Tk Source Code

Changes On Branch revised_text
Login

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

Changes In Branch revised_text Excluding Merge-Ins

This is equivalent to a diff from 32a9cba0 to 9b7c3afd

2024-04-17
20:40
Merge 9.0 Leaf check-in: 9b7c3afd user: jan.nijtmans tags: revised_text, tip-466
16:55
Merge 8.7 Leaf check-in: b42ce784 user: jan.nijtmans tags: trunk, main
2024-03-26
16:46
Merge 9.0 check-in: 7b5865b0 user: jan.nijtmans tags: revised_text, tip-466
2020-10-27
07:08
Rename "trunk" to "main". Add "trunk" propagating tag for backwards compatibility check-in: 0f77b70d user: jan.nijtmans tags: trunk, main
01:25
Merge 8.6 Closed-Leaf check-in: 32a9cba0 user: marc_culler tags: trunk
2020-10-26
08:58
Merge 8.6 check-in: 88e0ce57 user: jan.nijtmans tags: trunk
2020-10-25
20:11
Adjustment for Sierra. Closed-Leaf check-in: 77a51c32 user: culler tags: bug-5cc72e002c

Changes to .fossil-settings/ignore-glob.

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

28
29
30
31
32
33
34
35
36
37

*/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
unix/Tk-Info.plist
unix/Wish-Info.plist








|



|
>










>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tkConfig.sh
*/wish*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk*.zip
*/tkUuid.h
html
macosx/configure
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out
unix/tk.pc
unix/Tk-Info.plist
unix/Wish-Info.plist
unix/Credits.html

Added .github/ISSUE_TEMPLATE.md.







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

Added .github/PULL_REQUEST_TEMPLATE.md.







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

Added .github/workflows/linux-build.yml.













































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: Linux
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    - "revised_text"
    tags:
    - "core-**"
permissions:
  contents: read
defaults:
  run:
    shell: bash
    working-directory: tk/unix
env:
  ERROR_ON_FAILURES: 1
jobs:
  build:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
          - "clang"
        config:
          - ""
          - "CFLAGS=-DTK_NO_DEPRECATED=1"
          - "--disable-shared"
          - "--disable-xft"
          - "--disable-xss"
          - "--enable-symbols"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install libxss-dev libxft-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
          echo "TOOL_DIR=$(cd tcl/tools;pwd)" >> $GITHUB_ENV
          echo "BUILD_CONFIG_ID=$OPTS" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.config }}
          COMPILER: ${{ matrix.compiler }}
          OPTS: ${{ matrix.compiler }}${{ matrix.config }}
      - name: Configure and Build Tcl
        run: |
          ./configure $CFGOPT "--prefix=$HOME/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
        working-directory: tcl/unix
      - name: Configure (opts=${{ matrix.config }})
        run: |
          ./configure $CFGOPT --with-tcl=$TCL_CONFIG_PATH "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Build Test Harness
        run: |
          make tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Test-Drive Installation
        run: |
          make install || {
            echo "::error::Failure during Install"
            exit 1
          }
      - name: Create Distribution Package
        run: |
          make dist || {
            echo "::error::Failure during Distribute"
            exit 1
          }
      - name: Convert Documentation to HTML
        run: |
          make html-tk TOOL_DIR=$TOOL_DIR || {
            echo "::error::Failure during Distribute"
            exit 1
          }
      - name: Discover Version ID
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        run: |
          cd /tmp/dist
          echo "VERSION=`ls -d tk* | sed 's/tk//'`" >> $GITHUB_ENV
      - name: Upload Source Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v4
        with:
          name: Tk ${{ env.VERSION }} Source distribution (snapshot)
          path: |
            /tmp/dist/tk*
            !/tmp/dist/tk*/html/**
      - name: Upload Documentation Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v4
        with:
          name: Tk ${{ env.VERSION }} HTML documentation (snapshot)
          path: /tmp/dist/tk*/html
  test:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
        config:
          - ""
          - "--disable-xft"
          - "--enable-symbols"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install libxss-dev libxft-dev xvfb libicu-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.config }}
          COMPILER: ${{ matrix.compiler }}
      - name: Configure and Build Tcl
        run: |
          ./configure $CFGOPT "--prefix=$HOME/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
        working-directory: tcl/unix
      - name: Configure ${{ matrix.config }}
        run: |
          ./configure $CFGOPT --with-tcl=$TCL_CONFIG_PATH "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          xvfb-run --auto-servernum make test-classic | tee out-classic.txt
          xvfb-run --auto-servernum make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 10

Added .github/workflows/linux-with-tcl8-build.yml.





































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
name: Linux (with Tcl 8.7)
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
defaults:
  run:
    shell: bash
    working-directory: tk/unix
env:
  ERROR_ON_FAILURES: 1
jobs:
  build:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
          - "clang"
        cfgopt:
          - ""
          - "CFLAGS=-DTK_NO_DEPRECATED=1"
          - "--disable-shared"
          - "--disable-xft"
          - "--disable-xss"
          - "--enable-symbols"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-branch
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install libxss-dev libxft-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT" >> $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 and Build Tcl
        run: |
          ./configure $CFGOPT "--prefix=$HOME/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
        working-directory: tcl/unix
      - name: Configure (opts=${{ matrix.cfgopt }})
        run: |
          ./configure $CFGOPT --with-tcl=$TCL_CONFIG_PATH "--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
          }
  test:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
        cfgopt:
          - ""
          - "--disable-xft"
          - "--enable-symbols"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-branch
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install libxss-dev libxft-dev xvfb libicu-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.cfgopt }}
          COMPILER: ${{ matrix.compiler }}
      - name: Configure and Build Tcl
        run: |
          ./configure $CFGOPT "--prefix=$HOME/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
        working-directory: tcl/unix
      - name: Configure ${{ matrix.cfgopt }}
        run: |
          ./configure $CFGOPT --with-tcl=$TCL_CONFIG_PATH "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          xvfb-run --auto-servernum make test-classic | tee out-classic.txt
          xvfb-run --auto-servernum make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 15

Added .github/workflows/linux-with-tcl91-build.yml.





































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
name: Linux (with Tcl 9.1)
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
defaults:
  run:
    shell: bash
    working-directory: tk/unix
env:
  ERROR_ON_FAILURES: 1
jobs:
  build:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
          - "clang"
        cfgopt:
          - ""
          - "CFLAGS=-DTK_NO_DEPRECATED=1"
          - "--disable-shared"
          - "--disable-xft"
          - "--disable-xss"
          - "--enable-symbols"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: tip-626
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install libxss-dev libxft-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT" >> $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 and Build Tcl
        run: |
          ./configure $CFGOPT "--prefix=$HOME/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
        working-directory: tcl/unix
      - name: Configure (opts=${{ matrix.cfgopt }})
        run: |
          ./configure $CFGOPT --with-tcl=$TCL_CONFIG_PATH "--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
          }
  test:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
        cfgopt:
          - ""
          - "--disable-xft"
          - "--enable-symbols"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: tip-626
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install libxss-dev libxft-dev xvfb libicu-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.cfgopt }}
          COMPILER: ${{ matrix.compiler }}
      - name: Configure and Build Tcl
        run: |
          ./configure $CFGOPT "--prefix=$HOME/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
        working-directory: tcl/unix
      - name: Configure ${{ matrix.cfgopt }}
        run: |
          ./configure $CFGOPT --with-tcl=$TCL_CONFIG_PATH "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          xvfb-run --auto-servernum make test-classic | tee out-classic.txt
          xvfb-run --auto-servernum make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 15

Added .github/workflows/mac-build.yml.

























































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
name: macOS
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    - "revised_text"
    tags:
    - "core-**"
permissions:
  contents: read
env:
  ERROR_ON_FAILURES: 1
jobs:
  xcode:
    runs-on: macos-11
    defaults:
      run:
        shell: bash
        working-directory: tk/macosx
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Check out Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Prepare checked out repositories
        run: |
          touch tk/generic/tkStubInit.c
          mkdir build
          echo "BUILD_DIR=`cd build && pwd`" >> $GITHUB_ENV
          echo "DESTDIR=`cd build && pwd`" >> $GITHUB_ENV
        working-directory: .
      - name: Build Tcl
        run: |
          make all
        working-directory: tcl/macosx
      - name: Build
        run: |
          make all install || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          make test | tee out.txt
          nmatches=$( grep -c "Failed	0" out.txt )
          if [ $nmatches -lt 4 ]
          then
            echo "::error::Failure during Test"
            exit 1
          fi
        timeout-minutes: 30
  clang:
    runs-on: macos-11
    strategy:
      matrix:
        symbols:
          - 'no'
          - 'mem'
        options:
          - '--enable-aqua'
          - '--disable-aqua'
    defaults:
      run:
        shell: bash
        working-directory: tk/unix
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Check out Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Prepare checked out repositories
        env:
          SET_DISPLAY: ${{ contains(matrix.options, '--disable-aqua') }}
        run: |
          touch tkStubInit.c
          mkdir "$HOME/install dir"
          echo "USE_XVFB=$SET_DISPLAY" >> $GITHUB_ENV
        working-directory: tk/generic
      - name: Add X11 (if required)
        if: ${{ env.USE_XVFB == 'true' }}
        run: |
          brew install --cask xquartz
          sudo /opt/X11/libexec/privileged_startx || true
        working-directory: .
      - name: Build Tcl
        run: |
          ./configure $CFGOPT --disable-zipfs "--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 }})
        run: |
          ./configure $CFGOPT --disable-zipfs "--prefix=$HOME/install dir" --disable-xft || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
        env:
          CFGOPT: --enable-symbols=${{ matrix.symbols }} ${{matrix.options }}
      - name: Build
        run: |
          make 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 {
              echo Xvfb not used, this is a --enable-aqua build
            }
          fi
          ( runXvfb :0; make test-classic; exit $? ) | tee out-classic.txt || {
            echo "::error::Failure during Test (classic)"
            exit 1
          }
          ( runXvfb :0; make test-ttk; exit $? ) | tee out-ttk.txt || {
            echo "::error::Failure during Test (ttk)"
            exit 1
          }
          cat out-classic.txt | grep -q "Failed	0" || {
            echo "::error::Failure in classic test results"
            exit 1
          }
          cat out-ttk.txt | grep -q "Failed	0" || {
            echo "::error::Failure in ttk test results"
            exit 1
          }
        timeout-minutes: 20
      - name: Carry out trial installation
        run: |
          make install || {
            cat config.log
            echo "::error::Failure during Install"
            exit 1
          }

Added .github/workflows/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
name: Build Binaries
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
jobs:
  linux:
    name: Linux
    runs-on: ubuntu-20.04
    defaults:
      run:
        shell: bash
    env:
      CC: gcc
      CFGOPT: --disable-symbols --disable-shared
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Setup Environment
        run: |
          sudo apt-get install libxss-dev libxft-dev
          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 --prefix=$INST_DIR
        working-directory: tcl/unix
      - name: Build & Install Tcl
        run: |
          make binaries libraries 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: Package
        run: |
          cp bin/wish9.0 ${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 }}_snapshot
      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: Wish ${{ env.TCL_PATCHLEVEL }} Linux single-file build (snapshot)
          path: ${{ env.INST_DIR }}/*.tar
      - name: Describe Installation Zip Contents
        if: ${{ always() }}
        run: |
          unzip -l wish${{ env.TCL_PATCHLEVEL }}_snapshot || true
        working-directory: ${{ env.INST_DIR }}
  macos:
    name: macOS
    runs-on: macos-11
    defaults:
      run:
        shell: bash
    env:
      CC: gcc
      CFGOPT: --disable-symbols --disable-shared
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Checkout create-dmg
        uses: actions/checkout@v4
        with:
          repository: create-dmg/create-dmg
          ref: v1.0.8
          path: create-dmg
      - name: Setup Environment
        run: |
          mkdir -p 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
          echo "CFLAGS=-arch x86_64 -arch arm64" >> $GITHUB_ENV
        working-directory: "."
      - name: Configure Tcl
        run: |
          ./configure $CFGOPT --prefix=$INST_DIR
        working-directory: tcl/unix
      - name: Build & Install Tcl
        run: |
          make binaries libraries 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: Package
        run: |
          cp ../tk/unix/wish 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 (snapshot)" \
              --window-pos 200 120 \
              --window-size 800 400 \
              "TclTk-$TCL_PATCHLEVEL-(snapshot).dmg" \
              "contents/"
        working-directory: ${{ env.INST_DIR }}
        env:
          BUILD_NAME: wish${{ env.TCL_PATCHLEVEL }}_snapshot
      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: Wish ${{ env.TCL_PATCHLEVEL }} macOS single-file build (snapshot)
          path: ${{ env.INST_DIR }}/*.dmg
  win:
    name: Windows
    runs-on: windows-latest
    defaults:
      run:
        shell: msys2 {0}
    env:
      CC: gcc
      CFGOPT: --disable-symbols --disable-shared
    steps:
      - name: Install MSYS2
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          install: git mingw-w64-x86_64-toolchain make zip
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Setup Environment
        run: |
          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 --prefix=$INST_DIR
        working-directory: tcl/win
      - name: Build & Install Tcl
        run: |
          make binaries libraries install
          $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: Package
        run: |
          cp ${TK_BIN} combined/${BUILD_NAME}.exe
        working-directory: install
        env:
          BUILD_NAME: wish${{ env.TCL_PATCHLEVEL }}_snapshot
      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: Wish ${{ env.TCL_PATCHLEVEL }} Windows single-file build (snapshot)
          path: install/combined/wish${{ env.TCL_PATCHLEVEL }}_snapshot.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
name: Windows
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    - "revised_text"
    tags:
    - "core-**"
permissions:
  contents: read
env:
  ERROR_ON_FAILURES: 1
jobs:
  msvc:
    runs-on: windows-2022
    defaults:
      run:
        shell: powershell
        working-directory: tk/win
    # Using powershell means we need to explicitly stop on failure
    strategy:
      matrix:
        config:
          - ""
          - "OPTS=symbols"
          - "OPTS=static"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Init MSVC
        uses: ilammy/msvc-dev-cmd@v1
      - name: Make Install Location
        working-directory: tcl
        run: |
          echo "TCLDIR=`pwd`" >> $GITHUB_ENV
          cd ..
          mkdir install
          cd install
          echo "INSTALLDIR=`pwd`" >> $GITHUB_ENV
      - name: Build Tcl (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc release install ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
        working-directory: tcl/win
      - name: Build Tk (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc all ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Build Test Harness (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc tktest ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Run Tk Tests (${{ matrix.config }})
        run: |
          nmake -f makefile.vc test-classic ${{ matrix.config }} | tee out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          nmake -f makefile.vc test-ttk ${{ matrix.config }} | tee out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        env:
          CI_BUILD_WITH_MSVC: 1
        shell: bash
        timeout-minutes: 10
      - name: Build Help (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc htmlhelp ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Install (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc install ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
  gcc:
    runs-on: windows-2019
    defaults:
      run:
        shell: msys2 {0}
        working-directory: win
    strategy:
      matrix:
        config:
          - ""
          - "--enable-symbols=mem"
          - "--enable-symbols=all"
          - "--disable-shared"
    steps:
      - name: Install MSYS2
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          install: git mingw-w64-x86_64-toolchain make zip
      - name: Checkout Tk
        uses: actions/checkout@v4
      - name: Checkout Tcl 9.0
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: main
          path: tcl
      - name: Prepare
        run: |
          touch tkStubInit.c
          touch "${HOME}/forWinDialog-5.12.7"
          mkdir "${HOME}/install_dir"
          echo "INSTALL_DIR=${HOME}/install_dir" >> $GITHUB_ENV
        working-directory: generic
      - name: Configure and Build Tcl (${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$INSTALL_DIR" || {
            cat config.log
            echo "::warning::Failure during Tcl Configure"
            exit 1
          }
          make all install  || {
            echo "::warning::Failure during Tcl Build"
            exit 1
          }
          echo "TCL_CONFIG_PATH=`pwd`" >> $GITHUB_ENV
        env:
          CFGOPT: --enable-64bit ${{ matrix.config }}
        working-directory: tcl/win
      - name: Configure Tk (${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$HOME/INSTALL_DIR" "--with-tcl=$TCL_CONFIG_PATH" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
        env:
          CFGOPT: --enable-64bit ${{ matrix.config }}
      - name: Build Tk
        run: |
          make all tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tk Tests
        run: |
          make test-classic | tee out-classic.txt
          make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 10

Changes to .gitignore.

12
13
14
15
16
17
18

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

34
35
36
37
38
39
40
*.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
_FOSSIL_
*/tkConfig.sh
*/wish*
*/tktest*
*/versions.vc
*/version.vc
*/libtcl.vfs
*/libtcl_*.zip

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







>










|


|
|
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
*.res
*.sl
*.so
.fslckout
Makefile
Tk-Info.plist
Wish-Info.plist
Credits.html
autom4te.cache
config.cache
config.log
config.status
config.status.lineno
html
manifest.uuid
_FOSSIL_
*/tkConfig.sh
*/wish*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk*.zip
*/tkUuid.h
libtommath/bn.ilg
libtommath/bn.ind
libtommath/pretty.build
libtommath/tommath.src
libtommath/*.log
libtommath/*.pdf
libtommath/*.pl

Changes to .project.

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


|







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

Deleted .travis.yml.

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




















































































































































































































































































































































































































































































































































































































Deleted ChangeLog.

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

2013-08-30  Don Porter  <[email protected]>

	*** 8.6.1 TAGGED FOR RELEASE ***

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

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

2013-08-25   Kevin Walzer <[email protected]>

	* macosx/tkMacOSXButton.c:  Bug [3016181]: Crash after scrollbar
	* macosx/tkMacOSXMenu.c:	destroyed, Tk Cocoa.
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWm.c:

2012-08-15  Joe English  <[email protected]>

	* library/ttk/progress.tcl: Bug [c597acdab3]: Call [$pb step]
	in tail position in ttk::progressbar::Autoincrement, so that
	the widget is in a consistent state when any write traces on
	the linked -variable are fired.

2013-08-14  Jan Nijtmans  <[email protected]>

	* generic/tkConfig.c:  Bug [069c9e43c4]: FreeOptionInternalRep() breaks
	* tests/config.test:   Tk_CreateOptionTable()

2013-07-02  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:  Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4
	* unix/configure: (thanks to Brian Griffin)

2012-06-28  Jan Nijtmans  <[email protected]>

	* library/ttk/scale.tcl: [Bug 2501278]: ttk::scale keyboard binding
	problem.

2013-06-05  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkScroll.c: [Bug 3613759]: ttk::entry and symbolic
	index names.
	* generic/ttk/ttkEntry.c: [Bug 2100430]: ttk::entry widget index
	must be integer
	* generic/tkEntry.c: Don't set interp result when it will be
	overwritten later.

2013-06-04  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: Eliminate NO_VIZ macro as current
	zlib uses HAVE_HIDDEN in stead. One more last-moment
	fix for FreeBSD by Pietro Cerutti

2013-05-23  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:     [Bug 3613668]: XFilterEvent() hangs.
	* unix/configure:
	* unix/tkUnixEvent.c:

2013-05-19  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:     Fix for FreeBSD, and remove support for older
	* unix/configure:  FreeBSD versions. Patch by Pietro Cerutti.

2013-04-10  Jan Nijtmans  <[email protected]>

	* win/makefile.vc: [Bug 3568760]: Tk documentation fails to build

2013-04-01  Don Porter  <[email protected]>

	* tests/window.test: Bring back test window-2.9. No longer hangs.

	* generic/tkInt.h:	[Bug 3607830] Runtime checks that Xkb is
	* unix/tkUnixEvent.c:	available in the X server before trying to
	* unix/tkUnixKey.c:	use.  Adapted from patch from Brian Griffin.

2013-03-27  Jan Nijtmans  <[email protected]>

	* library/button.tcl:    [Bug 3608074]: Add <<Invoke>> bindings to
	* library/listbox.tcl:   Button's, Listbox and Menu.
	* library/menu.tcl:
	* doc/event.n:           Document <<Invoke>>, <<ThemeChanged>>,
	* doc/ttk_panedwindow.n: <<EnteredChild>> (ttk_pandedwindow only) and
	* doc/ttk_spinbox.n:     <<Increment/Decrement>> (ttk_spinbox only)

2013-03-13  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: Patch by Andrew Shadura, providing better support for
	three architectures they have in Debian.

2013-03-11  Don Porter  <[email protected]>

	* generic/tkListbox.c:	[Bug 3607326] Stop segfault from
	* tests/listbox.test:	[listbox .l -listvariable $array].

2013-02-28  Donal K. Fellows  <[email protected]>

	* unix/tkUnixKey.c (TkpGetKeySym): [Bug 3599312]: Put the
	initialization of the key mapping before the input method handling so
	that Alt key handling is correct on non-OSX Unix. Thanks to Colin
	McDonald for developing the fix.

2013-02-18  Jan Nijtmans  <[email protected]>

	* unix/tkUnixEvent.c: Call XInitThreads once before the first Xlib
	call. Suggested by Brian Griffin.

2013-01-14  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:	 More flexible search for win32 tclConfig.sh,
	* win/configure: backported from TEA.

2013-01-13  Jan Nijtmans  <[email protected]>

	* library/tk.tcl: [Bug 3600390]: tk_strictMotif not tested for. Now
	* library/ttk/entry.tcl: all key-bindings for Control-a,b,e,f,n,p and
	their shift variants respect tk_strictMotif.

2013-01-10  Jan Nijtmans  <[email protected]>

	* library/text.tcl: [Bug 3600251]: Inappropriate replacement of Mac
	binding.
	* library/tk.tcl: [Bug 3600260]: Errors in new virtual event
	definitions

2012-12-11  Don Porter  <[email protected]>

	*** 8.6.0 TAGGED FOR RELEASE ***

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

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

2012-12-04  François Vogel  <[email protected]>

	* generic/tkTextIndex.c: [Bug 3588824]: bug in image index handling
	* tests/textIndex.test:  for weird image names

2012-11-16  Joe Mistachkin  <[email protected]>

	* generic/tkBind.c: Add support for an 'M' binding substitution
	that is replaced with the number of script-based binding patterns
	matched so far for the event.

2012-11-14  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 3500545]: tk_getOpenFile -multiple 1 wrong
	on windows.
	[Bug 3416492]: Crash in open/save file dialog in Windows 7 libraries.
	[Bug 3095112]: crash when selecting file from Win7 Library.

2012-11-11  Jan Nijtmans  <[email protected]>

	* win/tkWinTest.c: [Bug 3585396]: winDialog.test requires user
	* tests/winDialog.test: interaction.

2012-11-07  Donal K. Fellows  <[email protected]>

	* generic/tkFocus.c (TkSetFocusWin): [Bug 3574708]: Move window
	liveness into this function from caller sites to ensure that there are
	no paths where things can trip up on setting the focus to a partially
	dead window.

2012-10-24  Don Porter  <[email protected]>

	* macosx/tkMacOSXWm.c:	[Bug 3574893] Add overlooked toplevel ref
	count maintenance in the [wm manage|forget] operations that could
	cause segfaults due to premature free of structs.

2012-09-19  Jan Nijtmans  <[email protected]>

	* win/Makefile.in:    Compile win32 binaries with -DTCL_NO_DEPRECATED
	* win/tkiWinWm.c:     Fix gcc compiler warning.

2012-09-17  Don Porter  <[email protected]>

	*** 8.6b3 TAGGED FOR RELEASE ***

	* macosx/tkMacOSXWm.c: [Bug 3567786] Stop segfault in [wm forget].

2012-09-15  Don Porter  <[email protected]>

	* macosx/tkMacOSXFont.c: [Bug 3567778] Make Tk_MeasureChars() honor
	the TK_AT_LEAST_ONE flag properly.

2012-09-13  Donal K. Fellows  <[email protected]>

	* generic/ttk/ttkEntry.c (EntryDisplay): [Bug 3567453]: Clip regions
	* generic/ttk/ttkLabel.c (TextDraw): must be cleared with XSetClipMask
	* xlib/xgc.c (TkSetRegion): and not TkSetRegion, or crashes will ensue
	on X11-based builds, which can't handle None for a region argument.
	Added a clean panic to the non-X11 TkSetRegion to catch this case and
	stop such confusion from happening again.

2012-09-13  Donal K. Fellows  <[email protected]>

	* win/tkWinWm.c (WmTransientCmd): [Bug 3567283]: Added missing cast.

2012-09-11  Donal K. Fellows  <[email protected]>

	* generic/ttk/ttkEntry.c (EntryDisplay): [Bug 3566594]: Must manually
	* generic/ttk/ttkLabel.c (TextDraw):     reset the clip region of GCs
	when not using the Xft font renderer (well, especially on classic X11)
	because the GC sharing code doesn't take into account clip handling.
	Thanks to Christian Nassau for identifying the problem.

2012-09-07  Donal K. Fellows  <[email protected]>

	* generic/tkCanvPs.c (TkCanvPostscriptCmd): [Bug 3565533]: Purge use
	of variable that was only ever checked once immediately afterwards,
	except for one (buggy) case where it was checked without assignment.

2012-09-07  Don Porter  <[email protected]>

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

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

2012-08-30  Andreas Kupries  <[email protected]>

	* generic/tkCanvWind.c (CanvasPsWindow): Unbreak AIX, replaced use
	of C99 comments in commit [961ae24a3f] (2012-08-27) with C89-style.
	* win/tkWinDialog.c: Unbreak windows problems with commit [961ae24a3f]
	* win/tkWinMenu.c: as well.
	* win/tkWinSend.c:

2012-08-28  Jan Nijtmans  <[email protected]>

	* generic/tkMenuDraw.c: [Bug 3562426]: Context menu goes out of edge of
	screen.

2012-08-27  Donal K. Fellows  <[email protected]>

	* (very many files): Reworked the generation of error messages and
	postscript so that they no longer made nearly as much use of the Tcl
	interpreter's string result code, in the process substantially
	reducing the amount of ad-hoc stack buffers used for message
	generation. There should be no observable changes from this except
	that Tk now causes the ::errorCode variable to be set meaningfully in
	virtually all places where errors are generated.

2012-08-24  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (GlobFiltered): [Bug 3558535]: Factor out the
	filtered-sorted globbing code into one procedure that knows how to
	avoid nasty problems when non-list filters are used. This allows the
	rest of the [tk_getOpenFile] implementation to be ignorant of the
	considerable complexities of globbing.

2012-08-23  Don Porter  <[email protected]>

	* unix/tkUnixWm.c: [Bugs 3554026,3561016]: Stop crash with tearoff
	menus.

2012-08-23  Jan Nijtmans  <[email protected]>

	* library/tk.tcl:        [Bug 3555644]: Better use of virtual events,
	* library/ttk/entry.tcl  Add <<ToggleSelection>> virtual event.
	* library/ttk/treeview.tcl

2012-08-22  Jan Nijtmans  <[email protected]>

	TIP #403 IMPLEMENTATION

	* xlib/xcolors.c:     Web Colors for Tk. New colors aqua, crimson,
	* xlib/rgb.txt:       fuchsia, indigo, lime, olive, silver and teal.
	* unix/tkUnixColor.c: Modified RGB values for gray/grey, green,
	* generic/tkInt.h:    maroon and purple.
	* generic/tkColor.c

2012-08-17  Jan Nijtmans  <[email protected]>

	* win/nmakehlp.c: Add "-V<num>" option, in order to be able to detect
	partial version numbers.

2012-08-15  Jan Nijtmans  <[email protected]>

	* win/buildall.vc.bat:	Only build the threaded builds by default
	* win/rules.vc:		For msvcrt static builds, allow to link
				against libraries where the 'x' is missing
				(generated by Makefile.in).
	* win/makefile.vc:	Always compile Tk with -DUSE_TCL_STUBS,
				formatting.
	* library/tk.tcl:	[FRQ 3555324]: On Windows, re-define Ctrl-A
				for Select-All., as most Windows applications
				do.

2012-08-11  Jan Nijtmans  <[email protected]>

	* library/*.tcl: [Bug 3555644]: Better use of virtual events.
	Pre-define 10 new Virtual events, and correct various bindings
	according to the Mac OSX documentation.
	*** POTENTIAL INCOMPATIBILITY *** for code that assumes that widget
	classes are bound to literal events or that was using one of the new
	virtual event names itself for other purposes.

	* win/rules.vc: Sync with tcl version of rules.vc

2012-08-11  François Vogel  <[email protected]>

	* generic/tkTextTag.c:  [Bug 3554273]: Test textDisp-32.2 failed

2012-08-09  Stuart Cassoff  <[email protected]>

	* generic/tkEvent.c:    Remove useless (void *) casts introduced in
	* unix/tkUnixEvent.c:   checkin [81e50c85ed]. The warnings were false
	* unix/tkUnixKey.c:     flags from a faulty OpenBSD C compiler.
	* unix/tkUnixRFont.c:

2012-07-31  Donal K. Fellows  <[email protected]>

	* unix/tkUnixKey.c (TkpSetKeycodeAndState, TkpInitKeymapInfo)
	(TkpGetKeySym): [Bug 3551802]: Convert from XKeycodeToKeysym to
	XkbKeycodeToKeysym to fix deprecation warning.

2012-07-31  Jan Nijtmans  <[email protected]>

	* win/nmakehlp.c: Backport from Tcl 8.6, but add -Q option from
	sampleextension.

2012-07-17  Jan Nijtmans  <[email protected]>

	* win/makefile.vc: [Bug 3544932]: Visual studio compiler check fails

2012-07-05  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c (GetFileNameW): [Bug 3540127]: Better solution,
	using Tcl_GetIndexFromObj in stead of Tcl_GetIndexFromObjStruct

2012-07-05  Donal K. Fellows  <[email protected]>

	* doc/wm.n (geometry): [Bug 3538401]: Better description of the key
	difference between [wm geometry] and [winfo geometry]; the former
	represents the window manager's understanding, not Tk's.

2012-07-04  Donal K. Fellows  <[email protected]>

	* win/tkWinDialog.c (GetFileNameW): [Bug 3540127]: Clean up the tables
	of options for the file dialogs so that options are listed in error
	messages in alphabetical order.

2012-07-02  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 3540127]: filebox.test fails on win32

2012-06-26  Jan Nijtmans  <[email protected]>

	* unix/configure.in:  Link cygwin wish.exe with win32 tk.dll, only
	* unix/Makefile.in:   in combination with --enable-shared.
	* unix/tcl.m4:
	* unix/configure:     autoconf-2.59

2012-06-24  Jan Nijtmans  <[email protected]>

	* doc/SetOptions.3:   [FRQ-3536507]: clientData field in Tk_OptionSpec
	* generic/tk.h:       should be "const void *"
	* generic/tk*.c:      Eliminate many unnessessary type casts

2012-06-22  Jan Nijtmans  <[email protected]>

	* win/Makefile.in:    [Bug 1844430]: cygwin make fails in 8.4.14-8.5b3
	* unix/tcl.m4:        Sync with Tcl version.
	* unix/configure:     autoconf-2.59

2012-06-20  Jan Nijtmans  <[email protected]>

	* generic/tk.decls:    [FRQ 2636558] simplification. Restore forwards
	* generic/tkBitmap.c:  compatibility with Tk 8.5.
	* generic/tkdecls.h:
	* generic/tkStubInit.c:

2012-06-15  Donal K. Fellows  <[email protected]>

	* generic/ttk/ttkTreeview.c (unshareObj): [Bug 3535362]: Changed name
	of 'unshare' internal function to avoid clash with some libc versions.

2012-06-12  Donal K. Fellows  <[email protected]>

	* unix/tkUnixRFont.c (Tk_DrawChars, TkUnixSetXftClipRegion): Add some
	* generic/ttk/ttkEntry.c (EntryDisplay): special magic to make the
	* generic/ttk/ttkLabel.c (TextDraw): text clipping work right with the
	Xft-based renderer (which doesn't use the standard Tk GC except to
	supply the color).

2012-06-11  Donal K. Fellows  <[email protected]>

	* generic/ttk/ttkLabel.c (TextDraw): [Bug 3294450]: Get the clipping
	* generic/ttk/ttkEntry.c (EntryDisplay): of text in Ttk various text
	elements (e.g., buttons, entries, etc.) correct. Stops a whole range
	of visual problems, including loss of the second and subsequent lines
	of a label when the first line doesn't entirely fit, and failing to
	draw the last character of an entry at all if it doesn't all exactly
	fit in the space available (a problem I've noticed in tkchat, and been
	very frustrated with).

2012-06-10  Jan Nijtmans  <[email protected]>

	* library/*.tcl:      [Bug 3534137]: $tcl_platform(platform) !=
	[tk windowingsystem]

2012-06-08  Jan Nijtmans  <[email protected]>

	* generic/tkMain.c:   Implement TkCygwinMainEx for loading
	* generic/tkWindow.c: Cygwin's Tk_MainEx from the Tk dll.
	* generic/tkInt.decls:   Change XChangeWindowAttributes signature and
	* generic/tkIntXlibDeclsDecls.h: many others to match Xorg, needed for
	Cygwin.

2012-06-06  Jan Nijtmans  <[email protected]>

	* unix/Makefile.in:      [Bug 3532186] pkgIndex.tcl file complexity
	* win/Makefile.in:

2012-05-31  Jan Nijtmans  <[email protected]>

	* generic/tkWindow.c:	Simplify determination whether we are running
	* generic/tkStubInit.c:	on cygwin.  Export Tk_GetHINSTANCE,
	* generic/tkInt.decls:	TkSetPixmapColormap and TkpPrintWindowId from
				the Cygwin dll, sync stub table with Tk 8.6
				win32 version.
	* generic/tk*Decls.h:   re-generated
	* win/Makefile.in:      "make genstubs" when cross-compiling on UNIX

	* win/stubs.c:		Implement XFlush and various others for win32
	* win/tkWinPort.h:	as stubs, so win32 extensions using those can
				run under CYGWIN as well.
	* generic/tkMain.c:     Allow tk86.dll to cooperate with the cygwin
				console.

2012-05-29  Donal K. Fellows  <[email protected]>

	* generic/tkInt.decls (TkMacOSXDrawable): Added OSX-specific mechanism
	to allow retrieval of the drawing surface. Allows Canvas3d to be
	adapted to 8.6.

2012-05-28  François Vogel  <[email protected]>

	* doc/text.n:  [Bug 1630251]: Doc for -endline option was wrong

2012-05-28  François Vogel  <[email protected]>

	* generic/tkTextDisp.c: [Bug 1630254]: missing scrolling of text widget
	when from a -startline == -endline initial state it is configured to
	display a non-empty part of it

2012-05-24  Jan Nijtmans  <[email protected]>

	* win/stubs.c:          Change XSetCommand signature to match Xorg,
	* win/tkWinWm.c:        needed for Cygwin.
	* generic/tkInt.decls
	* generic/tk*Decls.h:   re-generated

2012-05-09  Jan Nijtmans  <[email protected]>

	* win/tkWinWm.c:           Change TkpWmSetState signature to match Xorg,
	* generic/tkInt.decls:     needed for Cygwin. (not needed for Mac)
	* generic/tkIntPlatDeclsDecls.h:
	* generic/tkWindow.c:      Don't check for cygwin in win32 static build.
	* unix/tkUnixPort.h:       Some more useful #defines for Cygwin

2012-05-05  Jan Nijtmans  <[email protected]>

	* xlib/xcolors.c:      Single "const" addition
	* generic/tkWindow.c:  If tk.dll loaded in cygwin, don't use the
	win32 file dialogs

2012-05-04  Jan Nijtmans  <[email protected]>

	* library/menu.tcl: [Bug 2768586]: Menu posting on dual monitors

2012-04-29  Jan Nijtmans  <[email protected]>

	* library/tk.tcl: [Bug 533519]: Window placement with multiple screens
	* generic/tkBind.c:
	* generic/tkFocus.c:
	* generic/tkMenuDraw.c:
	* generic/tkWinWm.c:

2012-04-26  Donal K. Fellows  <[email protected]>

	* generic/tkStubInit.c (Tk_GetHINSTANCE): Ensure that this is defined
	for OSX.

2012-04-26  Jan Nijtmans  <[email protected]>

	* generic/tk.decls:	[Bug 3508771]: Implement TkClipBox, Tk*Region
	* generic/tkInt.decls:	and Tk_GetHINSTANCE for Cygwin
	* generic/tkPlatDecls.h:
	* generic/tkintDecls.h:
	* generic/tkStubInit.c:

2012-04-22  Donal K. Fellows  <[email protected]>

	* generic/tkBind.c (ExpandPercents): [Bug 3520202]: Ensure that the
	%k, %K and %N substitutions use dummy tokens with <MouseWheel> events
	and that the %D subsitution is a dummy with <Key>/<KeyRelease>. This
	was causing significant indigestion (and a read of goodness knows what
	memory) to Tkinter/Python because of the way they map events between
	languages.

2012-04-20  Donal K. Fellows  <[email protected]>

	* generic/tkWindow.c (commands): Ensure that all descriptions of
	commands created by Tk are correct.

2012-04-20  Jan Nijtmans  <[email protected]>

	* generic/tk.tcl: Use vroot size in stead of screen size for clipping
	window coordinates in ::tk::PlaceWindow.
	* generic/dialog.tcl: Use ::tk::PlaceWindow in dialog.tcl, instead of
	dumplicating the code there. (harmless part of [Bug 533519])

2012-04-13  Jan Nijtmans  <[email protected]>

	* win/rules.vc: [Bug 3517448]: TclKit build fails (unresolved
	__strtoi64)

2012-04-07  Jan Nijtmans  <[email protected]>

	* generic/tkBind.c: [Bug 3176239]: control-MouseWheel causes segv

2012-03-30  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:        [Bug 3511806]: Compiler checks too early
	* unix/configure.in:  This change allows to build the cygwin
	* unix/configure      and mingw32 ports of Tcl/Tk to build
	* win/tcl.m4:         out-of-the-box using a native or cross-
	* win/configure.in:   compiler.
	* win/configure

2012-03-21  Jan Nijtmans  <[email protected]>

	* generic/tkColor.c:  [Bug 2809525]: Abort on overlong color name.
	* unix/tkUnixColor.c:

2012-03-18  Jan Nijtmans  <[email protected]>

	* xlib/xcolors.c:   [FRQ 3503317]: XParseColor speedup
	* xlib/rgb.txt:     List of all colors accepted by Tk in Xorg format
	* tests/color.test: Added test case for all colors in rgb.txt

2012-03-13  Donal K. Fellows  <[email protected]>

	* doc/*.3, doc/*.n: Minor spelling fixes.

2012-03-07  Donal K. Fellows  <[email protected]>

	* generic/tkObj.c (GetPixelsFromObjEx): [Bug 3497848]: Better rounding
	of pixel values to integers.

2012-03-04  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:    Patch from the cygwin folks
	* unix/configure: (re-generated)

2012-02-28  François Vogel  <[email protected]>

	* generic/tkText.c:      [Bug 1630262, Bug 1615425]: segfault
	* generic/tkTextBTree.c  when deleting lines or tagging outside of
	* generic/tkTextDisp.c   the -startline/-endline range with peer
	* generic/tkTextMark.c   text widgets.
	* tests/text.test        [Bug 3487407]: Weird text indices.
	* tests/textMark.test

2012-02-28  Donal K. Fellows  <[email protected]>

	* doc/canvas.n: [Bug 3495198]: Corrected types of bitmap options.

2012-02-26  Jan Nijtmans  <[email protected]>

	* xlib/xcolors.c: Provide fallback for _strtoi64
	* win/configure.in: Detect whether _strtoi64 is available
	* win/configure: (regenerated)

2012-02-25  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 1913750]: tk_chooseDirectory -initialdir
	internationalization problem.

2012-02-15  Jan Nijtmans  <[email protected]>

	* xlib/xcolors.c: [Bug 3486474]: Inconsistent color scaling
	* generic/tkColor.c: new internal function TkParseColor
	* generic/tkInt.h:
	* generic/tk*.c:   Change XParseColor() to TkParseColor() everywhere.

2012-02-10  Donal K. Fellows  <[email protected]>

	* win/tkWinDialog.c (GetFileName): Ensure that we do not convert a
	result list to a string inadvertently, as this causes problems with
	Tkinter's handling of multiple filename results. Issue was reported
	via StackOverflow: http://stackoverflow.com/q/9227859/301832

2012-01-30  Joe English  <[email protected]>

	* library/ttk/combobox.tcl: [Bug 2925561] Don't take focus in
	disabled state.

2012-01-29  Jan Nijtmans  <[email protected]>

	* win/tkImgPhoto.c: [Bug 3480634]: PNG Images missing in menus on Mac

2012-01-27  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 3480471]: tk_getOpenFile crashes on Win64

2012-01-26  François Vogel  <[email protected]>

	* generic/tkTextDisp.c: [Bug-1754043] and [Bug-2321450]: When
	-blockcursor is true, the cursor appears as a blinking bar which
	expands to the right edge of the widget.

2012-01-25  Jan Nijtmans  <[email protected]>

	* generic/tkImgPhoto.c: [Bug 2433260]: non-critical error in
	Tk_PhotoPutBlock

2012-01-25  François Vogel  <[email protected]>

	* generic/tkText.c: Don't increase the epoch twice

2012-01-25  François Vogel  <[email protected]>

	* generic/tkText.c:      [Bug-1630271]: segfault/infinite loop
	* generic/tkTextMark.c:  when a mark is before -startline
	* tests/textMark.test:

2012-01-25  François Vogel  <[email protected]>

	* generic/tkText.c: [Bug-3475627]: Test text-31.11 fails

2012-01-22  François Vogel  <[email protected]>

	* generic/tkTextMark.c: [Bug-3288113,3288121]: Missing marks/endless
	* tests/textMark.test:  loop in text mark prev/next

2012-01-19  François Vogel  <[email protected]>

	* generic/tkText.c: [Bug-3021557]: Moving the cursor in
	* tests/text.test:  elided text freezes Tk

2011-12-22  Don Porter  <[email protected]>

	* win/tkWinMenu.c: [Bug 3235256] Keep menu entry IDs out of system
	values. Thanks Colin McDonald.

2011-12-13  Donal K. Fellows  <[email protected]>

	* doc/getOpenFile.n: Make example follow best practices. Issue spotted
	by Emiliano Gavilán.

2011-11-29  Donal K. Fellows  <[email protected]>

	* tests/safe.test: [Bug 1847925]: Update list of hidden commands.

2011-11-22  Jan Nijtmans  <[email protected]>

	* unix/Makefile.in: [Bug 1945073]: Demo square.tcl
	* win/Makefile.in: cannot run; need package tktest

2011-11-17  Jan Nijtmans  <[email protected]>

	* doc/menu.n: Fix the escaping of leading dots in lines that start with
	a widget name, so that nroff doesn't mistake it as a non-existing macro
	and skips the entire line.

2011-11-14  Alexandre Ferrieux  <[email protected]>

	* generic/tkCanvas.c: [Bug 3437816]: Missing TCL_ERROR return
	in [canvas lower].

2011-11-08  Reinhard Max  <[email protected]>

	* unix/Makefile.in: Add square to DEMOPROGS. It contains a shebang
	and hence should get installed with executable bits.

	* doc/label.n:         Fix the escaping of leading dots in lines that
	* doc/text.n:          start with a widget name, so that nroff
	* doc/ttk_notebook.n:  doesn't mistake it as a non-existing macro
	* doc/pack.n:          and skips the entire line.

2011-11-01  Donal K. Fellows  <[email protected]>

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

	* win/tkWinDialog.c: Internationalization of all Windows font
	* win/tkWinFont.c:   handling.

2011-10-10  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 3163893]: -initialdir option bug for
	tk_chooseDirectory under XP

2011-10-05  Jan Nijtmans  <[email protected]>

	* win/tkWinInt.h:   Remove tkWinProcs, as it is no longer
	* win/tkWinX.c:     being used.
	* win/tkWinTest.c:

2011-09-27  Donal K. Fellows  <[email protected]>

	* generic/tkImgPNG.c (WriteExtraChunks): [Bug 3405839]: Write the sDAT
	chunk with the correct length.

2011-09-08  Jan Nijtmans  <[email protected]>

	* generic/tkDecls.h: Don't let tkDecls.h depend on <tchar.h> on
	windows, not even in UNICODE mode.

2011-09-01  Donal K. Fellows  <[email protected]>

	* doc/photo.n: Correctly documented what the [$ph data] command
	produces without the -format option.

2011-08-16  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 3388350]: mingw64 compiler warnings
	* win/tkWinEmbed.c
	* win/tkWinMenu.c
	* win/tkWinTest.c
	* win/tkWinWm.c
	* win/tkWinX.c

2011-08-13  Jan Nijtmans  <[email protected]>

	* generic/tkBitmap.c: [Bug 3388350]: mingw64 compiler warnings
	* generic/tkConsole.c
	* win/tkWinDialog.c
	* win/tkWinEmbed.c
	* win/tkWinSend.c
	* win/tkWinSendCom.c

2011-08-05  Don Porter  <[email protected]>

	*** 8.6b2 TAGGED FOR RELEASE ***

	* changes:	Updates for 8.6b2 release.

2011-08-03  Don Porter  <[email protected]>

	* win/tkWinWm.c: [Bug 2891541]: Merge of 8.5.8 fix from Pat Thoyts.
	Permit normal behaviour on Windows for a grabbed toplevel when it
	is the main window.

2011-08-03  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: [Bug 3314770]: regression - Windows file
	dialogs not resizable

2011-07-28  Don Porter  <[email protected]>

	* changes:	Updates for 8.6b2 release.

2011-07-28  Jan Nijtmans  <[email protected]>

	* xlib/X11/Xutil.h: [Bug 3380684]: XEmptyRegion prototype doesn't
	match usage

2011-07-19  Donal K. Fellows  <[email protected]>

	* doc/*.3, doc/*.n: Many small fixes to documentation as part of
	project to improve quality of generated HTML docs.

2011-07-18  Don Porter  <[email protected]>

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

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

2011-06-29  Don Porter  <[email protected]>

	* generic/ttk/ttkTrace.c: [Bug 3341056]: Correct segfault due to flaw
	* tests/ttk/ttk.test:	in the 2011-06-17 commit.

2011-06-19  Donal K. Fellows  <[email protected]>

	* doc/wm.n: Added documentation of the -type attribute that was
	introduced in TIP#359, and moved documentation of -alpha to common
	section as it is supported on all platforms now.

2011-06-17  Don Porter  <[email protected]>

	* generic/ttk/ttkTrace.c:	Workaround Bug 3062331.
	* tests/ttk/ttk.test:
	* changes:	Updated

2011-06-16  Jan Nijtmans  <[email protected]>

	* win/tcl.m4: Sync with win/tcl.m4 from Tcl
	* win/configure: (regenerated)

2011-06-10  Don Porter  <[email protected]>

	* generic/tkEntry.c:	[Bug 3315731]: Fix [$entry -invcmd].

2011-06-10  Don Porter  <[email protected]>

	* README:	Correct some README bitrot.
	* macosx/README:

2011-06-07  Don Porter  <[email protected]>

	* generic/tkEntry.c:	[Bug 2358545]: Restore support for values "08"
	and "09" in a [spinbox] configured to use -from and -to values.

2011-06-06  Don Porter  <[email protected]>

	* generic/tkConsole.c:	[Bug 2546087]: Restore proper NUL output to
	* library/console.tcl:	the [console].

2011-04-22  Peter Spjuth  <[email protected]>

	* generic/tkCanvPoly.c: [Bug 3291543]: There was a crash if dchars
	* tests/canvas.test:    removed all coordinates of a polygon.

2011-04-21  Peter Spjuth  <[email protected]>

	* doc/checkbutton.n: Document all variable options as global.
	* doc/radiobutton.n:
	* doc/listbox.n:
	* doc/menu.n:
	* doc/options.n:
	* doc/ttk_combobox.n:
	* doc/ttk_entry.n:
	* doc/ttk_progressbar.n:
	* doc/ttk_widget.n:

2011-04-06  Jan Nijtmans  <[email protected]>

	* unix/tkAppInit.c:  Make symbols "main" and "Tcl_AppInit"
	MODULE_SCOPE: there is absolutely no reason for exporting them.
	* unix/tcl.m4:        Don't use -fvisibility=hidden with static
	* unix/configure      libraries (--disable-shared)

2011-04-04  Peter Spjuth  <[email protected]>

	* tests/grid.test:
	* generic/tkGrid.c: [Bug 723765]: When a slave was removed from grid,
	the -in option was not remembered.

2011-04-04  Joe Mistachkin  <[email protected]>

	* win/tkWinDialog.c (FontchooserShowCmd): Change the CHOOSEFONT and
	LOGFONT used with sizeof to CHOOSEFONTA and LOGFONTA to match their
	local variable declarations (i.e. mismatch with -DUNICODE).  This code
	is not present in 8.4 or 8.5.

2011-04-04  Peter Spjuth  <[email protected]>

	* doc/labelframe.n:
	* doc/frame.n:
	* generic/tkFrame.c: [Bug 2997657]: Removed -container from labelframe
	documentation since it does not work as expected and does not make
	sense as a container. Added note to frame about restrictions when used
	as a container.

2011-03-28  Donal K. Fellows  <[email protected]>

	* library/tk.tcl (::tk::FindAltKeyTarget): Make this handle the
	traversal of the logical window manager hierarchy correctly. Based on
	comments by Emiliano Gavilan.

2011-03-28  Jan Nijtmans  <[email protected]>

	* generic/tkTextBTree.c: [Bug 3129527]: Fix buffer overflow w/ GCC 4.5
	and -D_FORTIFY_SOURCE=2. One more place where this problem could
	appear.

2011-03-24  Jan Nijtmans  <[email protected]>

	* win/tkWinMenu.c: [Bug #3239768]: tk8.4.19 (and later) WIN32
	menu font support.

2011-03-16  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:    Make SHLIB_LD_LIBS='${LIBS}' the default and
	* unix/configure: set to "" on per-platform necessary basis.
	Backported from TEA, but kept all original platform code which was
	removed from TEA.

2011-03-14  Jan Nijtmans  <[email protected]>

	* generic/tkBind.c:      Eliminate some more unneeded write-only
	* generic/tkCanvUtil.c:  variables (discovered by gcc-4.6)
	* generic/tkFocus.c:

2011-03-12  Donal K. Fellows  <[email protected]>

	Remove casts from uses of ckalloc/ckfree/... now that Tcl declares
	them to be using useful casts internally.

2011-03-12  Jan Nijtmans  <[email protected]>

	* win/tkWin32Dll.c: Eliminate unneeded _TkFinalize wrapper.

2011-03-11  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkDefaultTheme.c: Eliminate some unneeded write-only
	* generic/ttk/ttkManager.c:      variables (discovered by gcc-4.6)
	* generic/ttk/ttkSquare.c:

2011-03-09  Reinhard Max  <[email protected]>

	* unix/configure.in: Use a symbol from libXft itself for the link
	test rather than one from libfreetype, because the latter doesn't
	work when the linker is called with --as-needed.

2011-03-03  Alexandre Ferrieux  <[email protected]>

	* generic/tkCanvLine.c: [Bug 3175610]: Incomplete refresh of line items.

2011-03-02  Donal K. Fellows  <[email protected]>

	* doc/tk_mac.n (new file): Description of OSX-specific functionality
	in Tk, contributed by Kevin Walzer.
	* doc/button.n, doc/font.n, doc/menu.n: Noted which parts of these
	commands are intentionally not fully supported on OSX.

2011-01-24  Joe English  <[email protected]>

	* generic/tkSelect.c: Fix for [Bug #3164879]: (memory allocation
	bug introduced by [Patch #3129527])

2011-01-22  Joe English  <[email protected]>

	* generic/ttk/ttkEntry.c(ttk::combobox): Add missing
	'validate' command (reported by schelte).

2011-01-13  Jan Nijtmans  <[email protected]>

	* library/msgbox.tcl: [Patch #3154705]: Close button has no effect

2011-01-12  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:         handle --enable-64bit=ia64 for gcc
	* win/configure.in    typo
	* win/configure:      (autoconf-2.59)

2011-01-06   Kevin Walzer <[email protected]>

	* macosx/README:	Added info on textured background windows.
	* macosx/tkMacOSXFont.c: Fix for 2857300, improves rounding up on text
	width [submitted by treectrl]
	* macosx/tkMacOSXMenu.c: Fix for radiobuttons and checkbuttons not
	displaying in popup menus, and disabled menu entries.
	* macosx/tkMacOSXWindowEvent.c:	Fix for 3086887, speeds up scrolling;
	also textured background windows
	* macosx/tkMacOSXWm.c: Textured background windows.

2011-01-06  Stuart Cassoff  <[email protected]>

	* generic/tkEvent.c:	Cast some NULLs to (void *) in order to quash
	* unix/tkUnixEvent.c:	"missing sentinel in function call"
	* unix/tkUnixKey.c:	compiler warnings.
	* unix/tkUnixRFont.c:

2010-12-17  Stuart Cassoff  <[email protected]>

	* unix/Makefile.in:	Clean up '.PHONY:' targets: Arrange those
				common to Tcl and Tk as in Tcl's Makefile.in,
				add any missing ones and remove duplicates.

2010-12-17  Stuart Cassoff  <[email protected]>

	* unix/Makefile.in:  [Bug 2446711]: Remove 'allpatch' target.

2010-12-17  Stuart Cassoff  <[email protected]>

	* unix/Makefile.in:  [Bug 2537626]: Use 'rpmbuild', not 'rpm'.

2010-12-17  Jan Nijtmans  <[email protected]>

	* generic/tkMain.c:  refactor isatty() function for Windows.
	* win/tkWinImage.c:  better warning message.
	* win/tkWinInit.c:   Let TkpDisplayWarning() send the message
	directly to the debugger, if available, otherwise do as before.

2010-12-16  Jan Nijtmans  <[email protected]>

	* generic/tk.h:       [Patch 3124554]: Move WishPanic from Tk to Tcl
	* win/winMain.c:      Remove special MessageBox'es here, since every
	panic-related thing is now handled correctly by Tcl.

2010-12-15  Stuart Cassoff  <[email protected]>

	* unix/Makefile.in:	Installer Improvements.
	* unix/install-sh:	Similar to Tcl [Patch 3101127].

2010-12-15  Jan Nijtmans  <[email protected]>

	* generic/tkMain.c:	[Patch #3124683]: platform specific stuff
	in (tcl|tk)Main.c

2010-12-13  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:		[Bug 3135271]: Link error due to hidden
	* unix/configure:	symbols (CentOS 4.2)  (autoconf-2.59)
	* generic/tkMain.c:	Change "Application initialization failed" to
	* tests/main.test:	"application-specific initialization failed",
	for consistency with Tcl.
	* win/tkWin32Dll.c:	See also: [Patch 1910041] and [Patch 3059922].
	SEH emulation on Win64 was not correct here: it sometimes results in
	a crash. Contrary to the other places, the code here is not meant to
	protect from OS bugs, but to protect Finalizing Tk when the application
	went in an invalid state.

2010-12-12  Stuart Cassoff  <[email protected]>

	* unix/tcl.m4: Better building on OpenBSD.
	* unix/configure: (autoconf-2.59)

2010-12-10  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:	Fix manifest-generation for 64-bit gcc (mingw-w64)
	* win/configure: (autoconf-2.59)

2010-12-06  Jan Nijtmans  <[email protected]>

	* generic/tkSelect.c:	[Bug 3129527]: Fix buffer overflow w/ GCC 4.5
	* generic/tkTextDisp.c: and -D_FORTIFY_SOURCE=2
	* unix/tkUnixWm.c:
	* win/tkWinWm.c:

2010-12-05  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:      [Patch 3116490]: cross-compile support for unix
	* unix/configure    (autoconf-2.59)

2010-12-03  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:	[Patch 3116490]: cross-compile Tcl mingw32 on unix
	* win/configure: This makes it possible to cross-compile Tcl/Tk for
	Windows (either 32-bit or 64-bit) out-of-the-box on UNIX, using
	mingw-w64 build tools.

2010-12-02  Donal K. Fellows  <[email protected]>

	* generic/tkInt.decls (TkDrawAngledTextLayout,TkDrawAngledChars,...):
	Expose angled text API for Emiliano Gavilán. Still only in internal
	stub table.

2010-11-29  Jan Nijtmans  <[email protected]>

	* generic/tkAtom.c:    Fix various 64-bit gcc(-4.5.2) warnings: cast
	* generic/tkSelect.c:  from pointer to integer of different size.
	* win/stubs.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinPixmap.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWindow.c:
	* win/tkWinWm.c:
	* win/ttkWinMonitor.c:
	* win/tkWin32Dll.c:   Make assembler code compile in Win64 with gcc.

2010-11-24  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c:  [Bug 3071836]: Crash/Tcl_Panic on WinXP saving
	* win/tkWinInit.c:    file to C:\, and rewrite TkpDisplayWarning not
	to use any Tcl functions any more. This allows TkpDisplayWarning to be
	used as panic proc.
	* win/winMain.c:      Use TkpDisplayWarning as panic proc on Windows.
	* generic/tkMain.c:   Remove unused strrchr, combine outChannel and
	errChannel variables to a single variable.

2010-11-19  Jan Nijtmans  <[email protected]>

	* generic/tkCanv*.c:         Revise Tcl_Panic() calls ending with a
	* generic/tkGeomerty.c:      newline removing the newline, because
	* generic/tkImgPhInstance.c: Tcl_Panic() outputs a final newline
	* generic/tkMenu.c:	     already.
	* generic/tkRectOval.c:
	* generic/tkTextBTree.c:
	* generic/tkWindow.c:
	* unix/tkUnixRFont.c:
	* win/tkWinColor.c:
	* win/tkWinDraw.c:
	* win/tkWinMenu.c:

2010-11-18  Jan Nijtmans  <[email protected]>

	* win/winMain.c:   [FRQ 491789]: "setargv() doesn't support a unicode
	cmdline" now implemented for cygwin and mingw32 too.
	* win/configure.in:	Allow cross-compilation by default.
	* win/configure    (regenerated)

2010-11-17  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:      [FRQ 491789]: "setargv() doesn't support a unicode
	cmdline" now implemented for mingw-w64
	* win/configure    (regenerated)
	* win/winMain.c    Workaround for bug in some versions of mingw-w64

2010-11-16  Jan Nijtmans  <[email protected]>

	* win/winMain.c    Bring compilation under mingw-w64 a bit closer
	* win/tcl.m4       to reality. See for what's missing:
	    https://sourceforge.net/apps/trac/mingw-w64/wiki/Unicode%20apps
	* win/configure:   (re-generated)
	* win/tkWinPort.h: [Bug 3110161]: Extensions using TCHAR don't compile
	on VS2005 SP1

2010-11-10  Andreas Kupries  <[email protected]>

	* changes:	Updates for 8.6b2 release.

2010-11-06  Jan Nijtmans  <[email protected]>

	* library/msgs/*.msg:	Update NL catalog. For other languages,
	sorting and fix some locations of "&".

2010-11-05  Jan Nijtmans  <[email protected]>

	* library/demos/widget: Use unicode copyright sign, instead of
	* library/demos/en.msg: depending on translation.
	* library/demos/nl.msg:
	* generic/tkMain.c:    Sync TK_ASCII_MAIN usage with tclMain.c

2010-11-04  Don Porter  <[email protected]>

	* changes:	Updates for 8.6b2 release.

2010-11-03  Jan Nijtmans  <[email protected]>

	* win/tkWinClipboard.c: [FRQ 2965056]: Windows build with
	* win/tkWinDialog.c:     -DUNICODE
	* win/tkWinMenu.c:

2010-10-11  Jan Nijtmans  <[email protected]>

	* generic/tkDecls.h:  [FRQ 491789]: "setargv() doesn't support a
	* doc/Tk_Main.3:      unicode cmdline" implemented for Tk on MSVC++
	* win/Makefile.in:
	* win/makefile.vc:
	* win/winMain.c:
	* win/rules.vc:       Update for VS10

2010-10-11  Joe English  <[email protected]>

	* generic/ttk/ttkTreeview.c: [Bug 3085489]: Fix crash in 'tag add' /
	'tag remove' commands when no -tags specified.

2010-10-11  Jan Nijtmans  <[email protected]>

	* win/tkWinMenu.c:    [FRQ 2965056]: Windows build with -DUNICODE
	* win/tkWinWm.c:
	* win/tcl.m4:         Add netapi32 to the link line, so we no longer
	* win/makefile.vc:    have to use LoadLibrary to access those
	* win/configure:      functions.

2010-10-06  Jan Nijtmans  <[email protected]>

	* win/tkWinClipboard.c: [FRQ 2965056]: Windows build with
	* win/tkWinColor.c:     -DUNICODE
	* win/tkWinCursor.c:
	* win/tkWinFont.c:
	* win/tkWinTest.c:
	* win/tkWinMenu.c:
	* win/tkWinPixmap.c:
	* win/tkWinX.c:         Eliminate isWinNT variable
	* win/Makefile.in (genstubs): Generate ttk files as well.

2010-10-06  Donal K. Fellows  <[email protected]>

	* win/Makefile.in (genstubs): [Tcl Bug 3082049]: Typo.

2010-10-05  Jan Nijtmans  <[email protected]>

	* generic/tkWinX.c: [Bug 3080953]: Malformed Unicode characters in %A
	substitution Problem was in the static function GetTranslatedKey().

2010-10-01  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock):
	[Bug 3078902]: Ensure that zero-dimensioned data blocks cause no
	changes at all instead of causing a hang.

2010-09-29  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:         Sync with Tcl version
	* unix/configure:      Re-generate with autoconf-2.59
	* win/configure:
	* generic/tkMain.c     Make compilable with -DUNICODE as well

2010-09-28  Jan Nijtmans  <[email protected]>

	* win/tkWinSend.c: [Bug 3076671]: CVS HEAD Tk build fails on win32
	with msys/mingw. Make it compile on older mingw as well.
	* generic/tk.decls:   Add explicit scspec "EXTERN", as in Tcl
	* generic/tkInt.decls:
	* generic/tkStubInit.c: Don't let Tk_MainEx macro disturb compilation

2010-09-23  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:            Add -Wdeclaration-after-statement
	* win/configure:         (regenerated)
	* win/tkWinX.c:          Make compilable with -DUNICODE.
	* win/winMain.c:
	* unix/tkAppInit.c:      Many clean-ups in comments, so all
	(tcl|tk)AppInit.c variants use the same style.
	* generic/ttk/ttkGenStubs.tcl: Dummy genStubs::export (from
	genStubs.tcl)

2010-09-20  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkGenStubs.tcl: Clean-up, port all genStubs.tcl changes
	* generic/ttk/ttk.decls:    from Tcl to ttkGenStubs.tcl as well (no
	* generic/tk.decls:         change in any output files). This brings
	* generic/tkInt.decls:      all *.decls in the same form as tcl.decls

2010-09-16  Jeff Hobbs  <[email protected]>

	* win/tkWinX.c (_WIN32_IE): update to IE5.5 base expectation

2010-09-14  Jan Nijtmans  <[email protected]>

	* win/rules.vc       [FRQ 2965056]: Windows build with -DUNICODE
	* win/Makefile.in

2010-09-13  Jan Nijtmans  <[email protected]>

	* win/tkWin.h          Move definitions of WINVER/_WIN32_WINNT
	* win/tkWinDialog.h    to one place, now that we only support
	* win/tkWinMenu.c      Win2000+
	* win/tkWinX.c

2010-09-10  Jan Nijtmans  <[email protected]>

	* win/tkWinEmbed.c:     Make compilable with -DUNICODE
	* win/tkWinClipboard.c: Mark those files as not compilable with
	* win/tkWinColor.c:     -DUNICODE, so add a TODO.
	* win/tkWinCursor.c:
	* win/tkWinDialog.c:
	* win/tkWinFont.c:
	* win/tkWinMenu.c:
	* win/tkWinPixmap.c:
	* win/tkWinTest.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
	* win/winMain.c:
	* win/tkWinPort.h:  mingw/cygwin fixes: <tchar.h> should always
	be included here.

2010-09-09  Jan Nijtmans  <[email protected]>

	* win/rules.vc:   (sync with tcl version)
	* win/makefile.vc: mingw should always link with -ladvapi32
	* win/tcl.m4:
	* win/configure:   (regenerated)
	* win/tkWinInt.h:  Remove ascii variant of tkWinPocs table,
	* win/tkWinX.c:    it is no longer necessary.
	* win/tkWinTest.c:

2010-09-08  Joe English  <[email protected]>

	* generic/ttk/ttkTreeview.c (TreeviewSeeCommand): [Bug 2829363]:
	Schedule redisplay if [$tv see] opens any items.

2010-09-05  Donal K. Fellows  <[email protected]>

	* library/bgerror.tcl: [Bugs 3046742,3046750]: Improve keybindings for
	the background error dialog, and allow the use of the window manager
	controls for closing it (where supported). The Escape key now causes
	all remaining background error messages in the queue to be dropped.

2010-09-02  Joe English  <[email protected]>

        * library/ttk/winTheme.tcl, library/ttk/xpTheme.tcl,
	* library/ttk/vistaTheme.tcl: [Bug 3057573]: Specify disabled combobox
	text foreground color.

2010-08-31  Andreas Kupries  <[email protected]>

	* win/tcl.m4: Applied patch by Jeff fixing issues with the manifest
	handling on Win64.
	* win/configure: Regenerated.

2010-08-26  Jeff Hobbs  <[email protected]>

	* unix/Makefile.in: Add valgrind target
	* unix/configure, unix/tcl.m4: [Bug 1230554]: SHLIB_LD_LIBS='${LIBS}'
	for OSF1-V*. Add /usr/lib64 to set of auto-search dirs.
	(SC_PATH_X): Correct syntax error when xincludes not found.

	* win/Makefile.in (VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE):
	* win/configure, win/configure.in, win/tcl.m4: SC_EMBED_MANIFEST macro
	and --enable-embedded-manifest configure arg added to support manifest
	embedding where we know the magic. Help prevents DLL hell with MSVC8+.

	* generic/tkText.c (DumpLine): [Bug 3053347]: Replace segPtr->size
	with currentSize throughout, but particularly in if lineChanged block
	where segPtr may no longer be valid.

2010-08-21  Jan Nijtmans  <[email protected]>

	* generic/tk*Decls.h:   (regenerated with modified genStubs.tcl)
	* generic/tk*StubInit.c

2010-08-18  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkGenStubs.tcl: [Patch 3034251]: partly: remove some
	more unneeded ifdeffery, as in tcl/tools/genStubs.tcl.
	* generic/tk.h:     Move USE_OLD_IMAGE support after tkDecls.h
	* generic/*Decls.h  (regenerated)
	* generic/ttk/ttkDecls.h

2010-08-11  Jeff Hobbs  <[email protected]>

	* win/Makefile.in (%.${OBJEXT}): Better implicit rules support

	* unix/configure: regen with ac-2.59
	* unix/configure.in, unix/Makefile.in:
	* unix/tcl.m4 (AIX): Remove the need for ldAIX, replace with
	-bexpall/-brtl.  Remove TK_EXP_FILE (export file) and other baggage
	that went with it.  Remove pre-4 AIX build support.

2010-08-11  Don Porter  <[email protected]>

	* changes:	Updates for 8.6b2 release.

2010-08-04  Jeff Hobbs  <[email protected]>

	* license.terms: fix DFARs note for number-adjusted rights clause

2010-08-03  Jeff Hobbs  <[email protected]>

	* library/button.tcl (::tk::CheckEnter): [AS Bug#87409]: Use uplevel
	set instead of set :: to work with other var resolvers (itcl).

2010-07-19  Donal K. Fellows  <[email protected]>

	* generic/tkImgGIF.c (StringWriteGIF): Added ability to write a GIF to
	a string (as a byte array, of course) following comments on c.l.t by
	Aric Bills. Also improved readability of some of the function and
	field names in this file.

2010-07-16  Jan Nijtmans  <[email protected]>

	* generic/tkDecls.h: [Tcl Bug 3029891]: Functions that don't belong in
	the stub table (Tk part, not really removed from the stub table, just
	disabled)
	* generic/tkMain.c:  [Bug 3027438]: Tk_Main calls Tcl_CreateInterp
	* generic/tk.h:      before Tcl_FindExecutable

2010-07-06  Andreas Kupries  <[email protected]>

	* doc/text.n: Fixed minor typo in the description of 'text delete', as
	reported by <[email protected]> on the chat.

2010-07-01  Jan Nijtmans  <[email protected]>

	* win/rules.vc:  [Bug 3020677]: wish can't link reg1.2

2010-06-22  Anton Kovalenko  <[email protected]>

	* generic/tkPlace.c: [Patch 3019624]: modify "place" command, making
	it get main window through ClientData (like grid or pack do), instead
	of calling Tk_MainWindow(interp).
	* generic/tkWindow.c: modify "place" entry in commands[], turn on
	passMainWindow flag.

2010-06-22  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkGenStubs.tcl: [Bug 3019363]: "make genstubs" failure
	* generic/ttk/ttkDecls.h:      (regenerated)
	* generic/ttk/ttkTheme.c:      Unnecessary type cast

2010-06-21  Jan Nijtmans  <[email protected]>

	* generic/tkInt.decls: [Patch 2999889]: TkCopyAndGlobalEval obsolete
	* generic/tkIntDecls.h
	* generic/tkBind.c
	* generic/tkStubInit.c

2010-06-19  Joe English  <[email protected]>

	* win/tkWinScrlbr.c, carbon/tkMacOSXScrlbr.c: Replace binding
	procedures with ordinary event handlers [Patch 3009998].
	* generic/tkBind.c, generic/tk.h, generic/tkInt.h,
	* generic/tkInt.decls: Simplifications enabled by previous change:
	TkCreateBindingProcedure() and associated machinery no longer needed;
	TkBindDeadWindow() no longer needed; TK_DEFER_MODAL_LOOP and
	associated machinery no longer needed.
	* generic/tkTest.c, tests/bind.test: Tests related to C binding
	procedures no longer needed.
	* generic/tkWindow.c: TkBindDeadWindow() no longer needed.
	* generic/tkIntDecls.h, generic/tkStubInit.c: Regenerated.

2010-06-15  Joe English  <[email protected]>

	* library/ttk/ttk.tcl: Bump dummy [package ifneeded tile] version to
	0.8.6; see [Bug 3016598].

2010-06-15  Donal K. Fellows  <[email protected]>

	* library/text.tcl (TextCursorInSelection): [Patch 2585265]: Make it
	so that pressing delete or backspace when the primary selection does
	not include the insertion cursor does not cause the deletion of the
	inserted text.

2010-06-15  Jan Nijtmans  <[email protected]>

	* generic/tkCanvArc.c:	Eliminate many unnecessary (ClientData) type
	* generic/tkCanvas.c:	casts.
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvTest.c:
	* generic/tkCanvWind.c:
	* generic/tkRectOval.c:
	* generic/tkScrollbar.c:
	* generic/tkStyle.c:
	* generic/tkTest.c:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixEvent.c:
	* unix/tkUnixScale.c:
	* unix/tkUnixScrlbr.c:
	* unix/tkUnixSelect.c:
	* unix/tkUnixWm.c:
	* carbon/tkMacOSXDialog.c: Terminate TkEnsemble definition with NULL
	* macosx/tkMacOSXDialog.c:

2010-05-31  Joe English <[email protected]>

	* generic/tkBind.c (Tk_CreateBinding): [Bug 3006842]: Silently ignore
	empty scripts.

2010-05-27  Joe English <[email protected]>

	* generic/ttk/ttkTreeview.c, tests/ttk/treeview.test:
	[$tv tag bind $tag <...> {}] now removes binding completely.
	Fixes [Bug 3006842] (although there's still a problem somewhere
	in Tk_CreateBinding()).

2010-05-26  Jan Nijtmans  <[email protected]>

	* tests/wm.test: Fix 3 tests on Ubuntu 10.4, two of them timing
	dependent, one wm-dependent.
	* generic/tkText.c:	Fix some gcc strict-aliasing warnings,
	* unix/tkUnixFont.c:	discovered with "-Wstrict-aliasing=2"
	* unix/tkUnixSelect.c:

2010-05-20  Donal K. Fellows  <[email protected]>

	* win/tkWinX.c (HandleIMEComposition): [Bug 2992129]: Ensure that all
	places that generate key events zero them out first; Tk relies on that
	being true for the generic parts of the fix for Bug 1924761.

2010-05-17  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: Fix [Bug 3002230]: tk_chooseDirectory returns
	garbage on cancel

2010-05-17  Joe English  <[email protected]>

	* generic/tkBind.c: Revert [Patch 2999920], as it entails an
	incompatible change to the C API is and is the cause of [Bug 3002768].

2010-05-17  Jan Nijtmans  <[email protected]>

	* generic/tkBind.c: [Patch 2999920]: Optimize Internal Virtual event
	string operations.
	* win/tkWinDialog.c: [Bug 2987995]: Tk_getOpenFile returns garbage
	under described circumstances

2010-05-11  Jan Nijtmans  <[email protected]>

	* doc/RestrictEv.3:  Consistent use of variable names in RestrictEvent
	* generic/tkGrab.c:  API documentation and implementation: Use 'prev'
	* unix/tkUnixDraw.c: instead of 'old', and 'arg' instead of
	* unix/tkUnixSend.c: 'clientData' everywhere, just as in tkEvent.c.
	* unix/tkUnixWm.c

2010-05-10  Jan Nijtmans  <[email protected]>

	* doc/BindTable.3:     Bring in line with actual implementation.
	* generic/tk.decls:    Change Tk_CreateBinding param name, as in doc
	* generic/tkInt.decls: CONSTify TkCopyAndGlobalEval,
	* generic/tkBind.c:    TkpSetMainMenubar, TkpMenuNotifyToplevelCreate,
	* generic/tkMenu.c:    and TkSetWindowMenuBar
	* generic/tkDecls.h:    (regenerated)
	* generic/tkIntDecls.h: (regenerated)
	* carbon/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenu.c:
	* unix/tkUnixMenu.c:
	* win/tkWinMenu.c:

2010-05-03  Don Porter  <[email protected]>

	* generic/tk.h:		Bump patchlevel to 8.6b1.2 to distinguish
	* library/tk.tcl:	CVS snapshots from earlier snapshots as well
	* unix/configure.in:	as the 8.6b1 and 8.6b2 releases.
	* win/configure.in:

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

2010-05-03  Donal K. Fellows  <[email protected]>

	* library/button.tcl (CheckInvoke, CheckEnter): [Patch 1530276 redux]:
	Apply a bit more care to ensure that things continue to work correctly
	even when there is no -selectcolor defined.

2010-04-29  Jan Nijtmans  <[email protected]>

	* win/tkWin.h:		Unnecessary TCL_STORAGE_CLASS re-definition
	* win/tkWinInt.h:	Make various functions MODULE_SCOPE
	* win/tkWinButton.c:	TCHAR-related fixes, making al those
	* win/tkWinFont.c:	files compile fine when TCHAR != char.
	* win/tkWinScrlbr.c:
	* win/tkWinWindow.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
	* win/ttkWinMonitor.c:
	* win/ttkWinXPTheme.c:

2010-04-25  Donal K. Fellows  <[email protected]>

	* generic/tkImgPNG.c (ReadIDAT, DecodePNG): Move the check for overall
	termination of the compressed stream until after the final IDAT has
	been read, so that multi-segment images will work right. Reported by
	Andy Goth on the Wiki.

2010-04-23  Jan Nijtmans  <[email protected]>

	* generic/tkImgGIF.c:  Formatting
	* generic/tkListbox.c: fix typo;
	* generic/tkTrig.c:    fix typo;
	* generic/tkInt.h:     fix typo; remove not existing tkDisplayList;
	* generic/*.h:         Useless re-definitions of TCL_STORAGE_CLASS

2010-04-20  Jan Nijtmans  <[email protected]>

	* generic/tkPort.h:         Make sure that tkWinPort.h is always
	* generic/tkIntXlibDecls.h: included before tcl.h, otherwise the
	* win/tkWinPort.h:          fallback for TCHAR might go off before the
				    inclusion of <tchar.h>
	* win/tkWinDialog.c:        Define OPENFILENAME_SIZE_VERSION_400 if
				    needed.
	* compat/stdlib.h:          Include <tcl.h> only when not already
	* compat/unistd.h:	    done.
	* generic/tkInt.h:          tkPort.h already includes tk.h, which
				    includes tcl.h.
	* generic/tk3d.h:           Always use #include "tkInt.h", not
	* generic/tkColor.h:	    <tkInt.h>
	* xlib/xcolors.c:
	* xlib/xgc.c:

2010-04-19  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: Fix [Bug 2987995]: Tk_GetOpenFile returns garbage
	under described circumstances.
	* win/tkWinDialog.c: [Patch 2898255]: Filenames limit with
	Tk_GetFileName().
	Assure modern style dialogs where available

2010-04-13  Jan Nijtmans  <[email protected]>

	* win/tkWinPort.h     Fix [Patch 2986105]: conditionally defining
	strcasecmp/strncasecmp

2010-04-12  Donal K. Fellows  <[email protected]>

	* generic/tkImgPNG.c (WriteIDAT): [Bug 2984787]: Use the correct
	flushing semantics when handling the last data from the image. Without
	this, many PNG readers (notably including Firefox) refuse to show the
	image and instead complain about errors.
	(ReadIDAT): Added sanity checks to ensure that when we've got bad data
	of the sorts of forms we were previously generating, we detect it and
	error out rather than silently failing.
	(WriteExtraChunks): New function to write in some basic metadata.

2010-04-09  Jan Nijtmans  <[email protected]>

	* doc/photo.n:    Follow-up to [Bug 2983824]: update doc.

2010-04-09  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoCmd): [Bug 2983824]: Use the file
	extension to guess the output format to use if one isn't specified.

2010-04-08  Jan Nijtmans  <[email protected]>

	* win/tkWinPort.h:    Add <wchar.h> to tkWinPort.h, and
	* win/tkWinSend.c:    remove some earlier CYGWIN-related
	* win/tkWinSendCom.c: hacks which are no longer necessary.

2010-04-06  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:         Sync with Tcl version
	* unix/tcl.m4:
	* win/configure:      (regenerate with autoconf-2.59)
	* unix/configure:     [Bug 2982540]: configure and install* script
			      files should always have LF

2010-03-29  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:            Only test for -visibility=hidden with gcc
	                          (Second remark in [Bug 2976508])
	* unix/configure:         regen

2010-03-29  Donal K. Fellows  <[email protected]>

	* unix/tkUnixRFont.c (GetFont): [Bug 2978410]: Do not use non-constant
	initializers for structures, since HP-UX cc doesn't like it.

2010-03-28  Joe English  <[email protected]>

	* generic/ttk/ttkTagSet.c, generic/ttk/ttkTheme.c,
	* generic/ttk/ttkTheme.h, generic/ttk/ttkTreeview.c,
	* generic/ttk/ttkWidget.h, doc/ttk_treeview.n,
	* tests/ttk/treetags.test: ttk::treeview widget: add 'tag names',
	'tag add', and 'tag remove' methods.

2010-03-23  Donal K. Fellows  <[email protected]>

	* unix/configure.in, unix/Makefile.in: [Bug 2965133]: Get rid of the
	spurious NONE and some pointless quotes that were causing problems
	with building Tk on OSX. Overall bug might not yet be solved.

2010-03-17  Donal K. Fellows  <[email protected]>

	* library/entry.tcl:	 [Bug 2971663]: Make the <Up> and <Down> keys
	* library/ttk/entry.tcl: explicitly do nothing, since Tk-on-Cocoa will
	generate (invisible zero-width) characters for them otherwise. The
	explicitly empty bindings are harmless on other platforms.

2010-03-16  Jan Nijtmans  <[email protected]>

	* unix/.cvsignore:	Ignore .a and .so

2010-03-12  Jan Nijtmans  <[email protected]>

	* win/rules.vc:		Fix [Tcl Bug 2967340]: Static build failure
	* win/makefile.vc:
	* win/.cvsignore:

2010-03-12  Donal K. Fellows  <[email protected]>

	* library/iconlist.tcl:		Factor out some of the machinery for
	* library/megawidget.tcl:	making a megawidget framework. Not a
					public API at the moment.

2010-03-11  Donal K. Fellows  <[email protected]>

	* generic/tkText.c (DumpLine): [Bug 2968379]: When peers are about,
	there can be unnamed marks present during a dump. Ignore them as they
	will just be for the peers' insert and current marks, which aren't
	very important.
	(DumpLine): Removed lame reliance on the leading letters of the names
	of segment types. Entailed expanding the scope of the declarations of
	the types of embedded images and windows.

2010-03-08  Don Porter  <[email protected]>

	* generic/tkPlatDecls.h: [Bug 2965600]: Correct broken 2886635 fix.

2010-03-06  Pat Thoyts  <[email protected]>

	* library/menu.tcl: [Bug 2949774]: When using the non-ClickToFocus
	menu mode cascade menus should popdown once the pointer moves to
	another entry to be compatible with current X desktop usage.

2010-03-04  Jan Nijtmans  <[email protected]>

	* unix/configure.in:    Don't use -fvisibility=hidden
	* unix/tcl.m4:          for cygwin.
	* win/tkWinTest.c:      Make tkTestWinProcs const

2010-03-04  Donal K. Fellows  <[email protected]>

	* doc/clipboard.n: Added note about STRING vs. UTF8_STRING types.

2010-03-02  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: [Tcl FRQ 2959069]: Support for -fvisibility=hidden
	* unix/configure:  (regenerated with autoconf-2.59)

2010-02-23  Jan Nijtmans  <[email protected]>

	* unix/configure.in:    Use @EXEEXT@ in stead of @EXT_SUFFIX@
	* unix/tcl.m4:
	* unix/Makefile.in:     Use -DBUILD_tk
	* unix/configure:       (regenerated)
	* generic/tkConfig.c:   Make internal Tk_ObjCustomOption const
	* generic/tkPanedWindow.c:
	* generic/tkTest.c:
	* generic/tkText.c:

2010-02-21  Donal K. Fellows  <[email protected]>

	* generic/tkText.c (TextEditCmd): [Bug 1799782]: Refix this, so that
	<<Modified>> events are issued when things change.

2010-02-20  Joe English  <[email protected]>

	* generic/ttk/ttkTreeview.c: Cache the result of the last call to
	EndPosition() to avoid quadratic-time behavior in the common cases
	where the treeview is populated in depth-first or breadth-first
	order.

2010-02-19  Jan Nijtmans  <[email protected]>

	* win/tkWinColor.c:	 remove unused "dataKey" variable

2010-02-19  Donal K. Fellows  <[email protected]>

	* unix/configure.in, unix/Makefile.in: [Bug 2415437]: Corrections to
	allow installation of Tcl and Tk to different directories, especially
	when neither is a system standard location. Also [Tcl Bug 2307398].

	* unix/installManPage: [Tcl Bug 2954638]: Correct behaviour of manual
	page installer. Also added armouring to check that assumptions about
	the initial state are actually valid (e.g., look for existing input
	file).

2010-02-19  Stuart Cassoff  <[email protected]>

	* tcl.m4: Correct compiler/linker flags for threaded builds on
	OpenBSD.
	* configure: (regenerated).

2010-02-18  Jan Nijtmans  <[email protected]>

	* generic/tkButton.h:	Put all Tk_OptionSpec for buttons and labels
	* generic/tkButton.c:	in const memory. With some changes to win32
	* win/tkWinButton.c:	and macosx, preventing direct writes to
	* unix/tkUnixPort.h:	read-only memory.
	* carbon/tkMacOSXPort.h:
	* macosx/tkMacOSXButton.c:

2010-02-17  Joe English  <[email protected]>

	* generic/tkMenu.c: [Bug 2952745]: Defer TkMenuOptionTables cleanup to
	CallWhenDeleted() time, to ensure that the record doesn't get freed
	until after all widget instance commands have been deleted.

2010-02-17  Jan Nijtmans  <[email protected]>

	* generic/tk.decls:	CONSTify everything related to Tk_ConfigSpec
	* generic/tk.h:
	* generic/tkCanvArc.c:	Many tables can now be put in const memory
	* generic/tkCanvas.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvPs.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkImgBmap.c:
	* generic/tkImgPhoto.c:
	* generic/tkOldConfig.c:
	* generic/tkRectOval.c:
	* generic/tkScrollbar.c:
	* generic/tkScrollbar.h:
	* generic/tkDecls.h:	(regenerated)
	* doc/CanvTkwin.3:
	* doc/ConfigWidg.3:
	* doc/CrtItemType.3:
	* win/tkWinScrlbr.c:
	* carbon/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXScrlbr.c:

2010-02-16  Jan Nijtmans  <[email protected]>

	* generic/tkWindow.c:	Reverted rename from tkStubs to tkConstStubs
	* generic/tkStubInit.c: (regenerated)
	* generic/tkArgv.c:	make defaultTable const
	* generic/tkScrollbar.c:Store default for "-with" in static non-const
				space
	* win/tkWinInt.h:	Make tkWinProcs const, and 5 procs
	* win/tkWinX.c:		MODULE_SCOPE.
	* win/tkWinColor.c:	Make sysColors const.
	* win/tkWinKey.c:	Make keymap const.
	* win/tkWinScrlbr.c:	Simplify copying of "-with" default value.
	* unix/tkUnixWm.c:	Make TkSetTransientFor static.
	* tests/textImage.test: textImage-1.13 depends on hash-order

2010-02-12  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:		Use -pipe for gcc on win32
	* win/configure:	(mingw/cygwin) (regenerated)
	* unix/tkUnixColor.c:	Make sure that TkpCmapStressed is exported
	* generic/tkImgPhoto.c:	Clean up unused Tk_CreatePhotoOption
	* generic/tkBind.c:	Make more internal arrays "const"
	* generic/tkBusy.c:
	* generic/tkButton.c:
	* generic/tkEvent.c:
	* generic/tkGrab.c:
	* generic/tkImgBmap.c:
	* generic/tkObj.c:
	* generic/tkOption.c:
	* generic/tkPanedWindow.c:
	* generic/tkPointer.c:
	* generic/tkWindow.c:
	* generic/tkImgPhoto.c:	Eliminate never used Tk_CreatePhotoOption()

2010-02-05  Jan Nijtmans  <[email protected]>

	* carbon/tkMacOSXDialog.c:  Make more internal tables "const"
	* macosx/tkMacOSXDialog.c:
	* unix/tkUnixButton.c:
	* unix/tkUnixWm.c:
	* win/tkWinDialog.c:
	* generic/tkWindow.c:
	* generic/tk*Decls.h:       (regenerated with new
	* generic/tkStubInit.c:     genStubs.tcl from Tcl)

2010-02-05  Joe English  <[email protected]>

	* generic/ttk/*.[ch]: Revert contravariant const qualifiers added by
	the previous commit to keep codebase in sync with the Tile extension,
	which must remain 8.4 compatible.

2010-02-05  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkGenStubs.tcl: Follow-up to [2010-01-29] commit:
	        prevent space within stub table function parameters if the
	        parameter type is a pointer. Make the various stub tables and
	        hook pointers const, just as Tcl and Tk.
	* generic/ttk/ttkDecls.h: (regenerated)
	* generic/ttk/ttkStubInit.c: (regenerated)
	* generic/ttk/ttk.decls:	Minor formatting
	* generic/ttk/ttkButton.c:	Make more internal tables "const"
	* generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkEntry.c:
	* generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c:
	* generic/ttk/ttkLayout.c:
	* generic/ttk/ttkNotebook.c:
	* generic/ttk/ttkPanedWindow.c:
	* generic/ttk/ttkProgress.c:
	* generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTheme.c:
	* generic/ttk/ttkTreeview.c:
	* generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h:

2010-01-31  Joe English  <[email protected]>

	* generic/ttk/ttkTheme.h, generic/ttk/ttkWidget.h, generic/ttk/*.c:
	Change signature of widget subcommand procedures to match
	Tcl_ObjCmdProc. Merge now-redundant ensemble dispatch code.

2010-01-29  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkGenStubs.tcl: No longer generate a space after "*"
	                        and immediately after a function name, so the
	                        format of function definitions in *Decls.h
	                        match all other *.h header files.
	* generic/ttk/ttkDecls.h: (re-generated)
	* generic/tk.decls:	Formatting
	* generic/tkDecls.h:	(re-generated)
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkBind.c:	Little simplification

2010-01-19  Jan Nijtmans  <[email protected]>

	* generic/tkInt.h:           Don't depend on <stdio.h> from tcl.h any
	* generic/tkOldConfig.c:     more.
	* generic/ttk/ttkClamTheme.c:	 Fix more gcc warnings: missing
	* generic/ttk/ttkClassicTheme.c: initializer.
	* generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c:
	* generic/ttk/ttkEntry.c:
	* generic/ttk/ttkInit.c:
	* generic/ttk/ttkLabel.c:
	* generic/ttk/ttkNotebook.c:
	* generic/ttk/ttkPanedwindow.c:
	* generic/ttk/ttkSquare.c:
	* generic/ttk/ttkTreeview.c:
	* win/ttkWinTheme.c:
	* win/tkWinMenu.c:     Add missing #include <string.h>
	* win/tkWinPort.h:     Fix include files for CYGWIN
	* win/tkWinSend.c:
	* win/tkWinSendCom.c:
	* win/tkWinTest.c:     Fix gcc warning
	* win/winMain.c:       Eliminate use of __argc and __argv for CYGWIN
	* win/tcl.m4:          Make cygwin configuration error into
	* win/configure.in:    a warning: CYGWIN compilation works
	* win/configure:       although there still are test failures.

2010-01-19  Donal K. Fellows  <[email protected]>

	* generic/tkCanvas.c (TagSearchScanExpr): [Bug 2931374]: Stop overflow
	of working buffer during construction of long tag expressions.

2010-01-19  Pat Thoyts  <[email protected]>

	TIP #359 IMPLEMENTATION

	* library/bgerror.tcl:  Extended Window Manager Hints following the
	* library/clrpick.tcl:  freedesktop.org specification are now
	* library/demos/widget: supported on X11 using a new [wm attribute]
	* library/dialog.tcl:   called '-type'. This feature is now used in
	* library/msgbox.tcl:   the Tk library functions where appropriate.
	* library/tkfbox.tcl:
	* library/ttk/combobox.tcl:
	* tests/unixWm.test:
	* tests/wm.test:
	* unix/tkUnixWm.c:

2010-01-18  Jan Nijtmans  <[email protected]>

	* generic/tkCanvArc.c:	Fix more gcc warnings: missing initializer
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvPs.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkCmds.c:
	* generic/tkImgBmap.c:
	* generic/tkImgGIF.c:
	* generic/tkImgPhoto.c:
	* generic/tkImgPNG.c:
	* generic/tkImgPPM.c:
	* generic/tkMenu.c:
	* generic/tkMenubutton.c:
	* generic/tkMessage.c:
	* generic/tkOldTest.c:
	* generic/tkPanedWindow.c:
	* generic/tkRectOval.c:
	* generic/tkScrollbar.c:
	* generic/tkSquare.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkTextImage.c:
	* generic/tkTextTag.c:
	* generic/tkTextWind.c:
	* generic/tkTrig.c:
	* generic/tkCanvas.c:      [Patch 2932808]: Canvas items not updating
				   on widget state change.

2010-01-13  Jan Nijtmans  <[email protected]>

	* generic/tkMenubutton.h:  Eliminate tkpMenubuttonClass
	* generic/tkButton.h       make tkpButtonProcs CONST
	* generic/tkBusy.c:        fix gcc warning: missing initializer
	* generic/tkButton.c
	* generic/tkCanvas.c
	* generic/tkConsole.c
	* generic/tkEntry.c
	* generic/tkFrame.c
	* generic/tkListbox.c
	* generic/tkMenu.c
	* generic/tkMenubutton.c
	* generic/tkMessage.c
	* generic/tkScale.c
	* generic/tkScrollbar.h
	* generic/tkText.c
	* generic/ttk/ttkWidget.c
	* carbon/tkMacOSXButton.c
	* carbon/tkMacOSXMenubutton.c
	* carbon/tkMacOSXScrlbr.c
	* macosx/tkMacOSXButton.c
	* macosx/tkMacOSXMenubutton.c
	* macosx/tkMacOSXScrlbr.c
	* unix/tkUnixButton.c
	* unix/tkUnixMenubu.c
	* unix/tkUnixScrolbr.c
	* win/tkWinButton.c
	* win/tkWinDialog.c
	* win/tkWinEmbed.c
	* win/tkWinFont.c
	* win/tkWinInit.c
	* win/tkWinKey.c
	* win/tkWinScrlbr.c
	* win/tkWinInt.h      Add SPI_SETKEYBOARDCUES definition, needed for
	                      original VC++ 6.0.

2010-01-10  Jan Nijtmans  <[email protected]>

	* doc/SetClassProcs.3:  CONSTify Tk_SetClassProcs
	* generic/tk.decls
	* generic/tkInt.h
	* generic/tkWindow.c
	* generic/tkDecls.h:    (regenerated)
	* unix/tcl.m4           Sync with Tcl version
	* unix/configure        (regenerated)

2010-01-09  Pat Thoyts  <[email protected]>

	TIP #360 IMPLEMENTATION

	* doc/menu.n:           Remove special handling of the .help menu on
	* library/obsolete.tcl: X11.
	* unix/tkUnixMenu.c:

	* library/menu.tcl:	Make Tk menu activation follow mouse
	* library/obsolete.tcl: movements.

2010-01-08  Pat Thoyts  <[email protected]>

	* doc/photo.n: [Bug 2927569]: Multiple edits have peverted the
	original meaning of the phrase 'image file data' to reference
	a filename option that does not exist.

2010-01-07  Donal K. Fellows  <[email protected]>

	* generic/tkTextDisp.c (AsyncUpdateLineMetrics): [Bug 2677890]: Fix
	odd text widget update problem that had scrollbars being unable to
	cover the whole widget. Fix is to reify the range to update sooner.

2010-01-06  Donal K. Fellows  <[email protected]>

	* library/tk.tcl:		Centralize the definition of keys that
	* library/entry.tcl:		do common movement in entry and text
	* library/spinbox.tcl:		widgets. This is because they are
	* library/text.tcl:		subtlely different on the different
	* library/ttk/entry.tcl:	platforms. Lets Tk code work more
	* doc/event.n (PREDEFINED VIRTUAL EVENTS): correctly with platform
					conventions "out of the box".

	* generic/tkBind.c (HandleEventGenerate, DoWarp): [Bug 2926819]:
	* generic/tkInt.h (TkDisplay):			Factor out the pointer
	* generic/tkWindow.c (GetScreen):		warping code a bit
	* carbon/tkMacOSXMouseEvent.c (TkpWarpPointer): better and extend it
	* macosx/tkMacOSXMouseEvent.c (TkpWarpPointer): to work on OSX too.
	* unix/tkUnixEvent.c (TkpWarpPointer):
	* win/tkWinPointer.c (TkpWarpPointer):

	* unix/tkUnixWm.c (TkWmMapWindow): [Bug 1163496]: Allow windows to be
	* tests/wm.test (wm-transient-8.1): set to be transients for withdrawn
	masters correctly.

2010-01-05  Pat Thoyts  <[email protected]>

	* win/tkWinDialog.c: [Patch 2898255]: Enable unlimited multiple file
	selection from the open files dialog. (pawlak,fellows,thoyts)

2010-01-05  Donal K. Fellows  <[email protected]>

	* generic/tkMenu.c (MenuWidgetObjCmd): [Bug 220950]: Do not delete
	menu entries if the first index to delete is explicitly after the last
	index of existing entries.

	* generic/tkFont.h (ROUND16): [Bug 2824916]: Use a correct rounding
	* unix/tkUnixFont.c (TkpDrawAngledChars):    macro for converting a
	* unix/tkUnixRFont.c (TkpDrawAngledChars):   double to a short. This
	* win/tkWinFont.c (GetScreenFont):	     stops a number of small
	visual artefacts from happening and reduces the effect of others. The
	ROUND16 macro is now shared across all the font code (though some
	platforms do not need it specially).

2010-01-04  Pat Thoyts  <[email protected]>

	* doc/TkInitStubs.3: [Bug 2192104]: Mention USE_TK_STUBS macro.
	* library/dialog.tcl: [Bug 2811266]: <Return> binding should invoke
	the button with the focus.
	* library/fontchooser.tcl: [Bug 2727476]: Fix default size of font
	chooser dialog and assigned minimum sizes for the lists.
	* library/console.tcl: [Bug 580361]: Fix console <<Cut>> binding.
	* library/console.tcl: Fix keyboard access to console menu.
	* library/demos/filebox.tcl: Make prettier using ttk.
	* library/demos/fontchoose.tcl: Fix display of demo code.
	* library/tk.tcl: Correctly handle quoted ampersands in AmpMenuArgs

2010-01-03  Donal K. Fellows  <[email protected]>

	* unix/tcl.m4 (SC_CONFIG_CFLAGS): [Bug 1636685]: Use the configuration
	for modern FreeBSD suggested by the FreeBSD porter.

2010-01-03  Pat Thoyts  <[email protected]>

	* generic/tkMenu.h: [Patch 2848897]: Support the system keyboard
	* win/tkWinMenu.c:  cues option on Windows. This system parameter
	hides the underlines on menu items unless the keyboard is used to
	open the menu. (kovalenko, thoyts)

2010-01-03  Donal K. Fellows  <[email protected]>

	* generic/tkFont.c (Tk_TextLayoutToPostscript):	Simplified the code to
	* generic/tkCanvPs.c (TkCanvPostscriptCmd):	generate the preamble
	* library/mkpsenc.tcl:				for PS generation and
	also simplify the code to output text following the observation that
	it effectively only produces ASCII anyway, even when it might have the
	option to do otherwise in theory.

2010-01-03  Pat Thoyts  <[email protected]>

	* library/tearoff.tcl: Tearoff menus should be transient and use the
	                       toolwindow style on Windows.
	* tests/menu.test: Menu tests using 'tkwait visibility' are unix only.

2010-01-02  Donal K. Fellows  <[email protected]>

	* unix/tkUnixEvent.c (TransferXEventsToTcl): [Bug 1924761]: Use the
	new cache mechanism to force the extraction of the string of a key
	event from XIM at the right time rather than after queueing when it
	can be quashed by a race condition centered on the limited amount of
	state in some XIM implementations.

	* unix/tkUnixKey.c (TkpGetString): [Bug 1373712]: Cache the value that
	* generic/tkInt.h (TkKeyEvent):		will be substituted via %A so
	* generic/tkEvent.c (CleanUpTkEvent):	that we do not need to make it
	* doc/HandleEvent.3 (ARGUMENTS):	fresh each time, which causes
	* doc/QWinEvent.3 (ARGUMENTS):		trouble with some input
	* carbon/tkMacOSXKeyEvent.c (InitKeyEvent): methods. Also includes the
	* macosx/tkMacOSXKeyEvent.c (tkProcessKeyEvent): factoring out of some
	* win/tkWinX.c (GenerateXEvent):	code and update of
	documentation to describe the slightly increased constraints on
	how Tk_HandleEvent can be used.

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

	* unix/tkUnixEvent.c (TransferXEventsToTcl): [Bug 1924761]: Move the
	* generic/tkEvent.c (Tk_HandleEvent):	     passing of key events to
	XFilterEvent to the low level point where all other events are
	handled, where it should have been all along. This makes more input
	methods work, stops [event generate] from interfering with input
	methods, and allows the simplification of tkEvent.c by removing half
	of InvokeInputMethods and allowing the rest - which was not full input
	method handling - to be rolled back into Tk_HandleEvent. Introduces a
	small potential bug when a focus change and input method handling are
	too close together in the Tk event queue, but that should be less
	deadly to usability than the previous problems where input methods
	could fail completely or reorder key presses...

2009-12-30  Pat Thoyts  <[email protected]>

	* generic/tkMenu.c: [Patch 2879789]: Torn off menu items are only
	* tests/menu.tcl:   activated over a limited region of the window.
	Fixed to make the whole width of a menu item activate the entry.

2009-12-27  Pat Thoyts  <[email protected]>

	* win/tkWinMenu.c: [Bug 2879927]: Highlight for cascade items in
	torn-off menus is incorrect on Windows.

2009-12-25  Joe English  <[email protected]>

	* library/ttk/utils.tcl, library/notebook.tcl: [Bugs 2917688,2546779]:
	Reworked ActivateTab focus selection logic.

2009-12-25  Donal K. Fellows  <[email protected]>

	* doc/option.n: [Bug 2914943]: Correct the first example.
	Also define what the format of option patterns is; that's a much less
	commonly known fact than it used to be.

2009-12-22  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:		Sync with current Tcl version.
	* unix/Makefile.in:	Use EXE_SUFFIX for Cygwin, and install
				libtk8.6.dll in bin directory.
	* unix/configure:	(regenerated)

2009-12-22  Joe English  <[email protected]>

	* library/ttk/sizegrip.tcl: [Bug 2912356]: Patch to avoid bizarro
	behavior under compiz.

2009-12-20  Donal K. Fellows  <[email protected]>

	* unix/tkUnixSend.c (ServerSecure): [Patch 2917663]: Better support
	for server-interpreted access control addreses.

2009-12-16  Jan Nijtmans  <[email protected]>

	* generic/tkListbox.c:	Fix gcc warning: ignoring return value of
				"strtol", declared with attribute
				warn_unused_result.
	* unix/tkUnixEvent.c:   Fix gcc warning: dereferencing pointer
				"xgePtr" does break strict-aliasing rules.
	* generic/tkInt.decls:  CONSTify return values of TkKeysymToString,
	* generic/tkBind.c      TkFindStateString, TkpGetString, TkpGetChar,
	* generic/tkIntDecls.h  which are all not supposed to be modified by
	* generic/tkUtil.c      the caller. In tkUtil.c this gets rid of a
	* carbon/tkMacOSXKeyboard.c   dangerous type cast.
	* macosx/tkMacOSXKeyboard.c
	* unix/tkUnixKey.c
	* win/tkWinKey.c

2009-12-15  Don Porter  <[email protected]>

	* generic/tkConfig.c:	Added another dimension of refCounting to the
	* generic/tkInt.c:	"option" Tcl_ObjType to improve memory troubles
	* generic/tkObj.c:	detailed in [Bug 2492179].  Also removed
	registration of the "option" Tcl_ObjType.
	*** POTENTIAL INCOMPATIBILITY *** for callers of
	Tcl_GetObjType("option") which must now handle a NULL return.

2009-12-15  Donal K. Fellows  <[email protected]>

	* library/demos/unicodeout.tcl (usePresentationFormsFor): Split out
	the code to decide whether to use presentation forms for clarity, and
	add some more languages (though only in natural uncomposed form for
	Devanagari script).

2009-12-14  Kevin B. Kenny  <[email protected]>

	* library/demos/unicodeout.tcl: Added code to check for right-to-left
	support on Windows and adjust Hebrew and Arabic character strings
	accordingly. Changed the Hebrew string to 'ktb ebryt' (ktav Ivrit,
	"Hebrew writing") to be consistent with at least the Greek and Russian
	strings. Thanks to Rodrigo Readi for calling the inconsistency to our
	attention.

2009-12-02  Jan Nijtmans  <[email protected]>

	* win/tkInt.decls: [Bugs 220600, 220690]: Comment that TkWinChildProc
	is exported through the stubs table since 8.5.9

2009-12-11  Jan Nijtmans  <[email protected]>

	* win/makefile.vc:	Fix dependancies on ${TKSTUBLIB} when
				TCL_USE_STATIC_PACKAGES is defined
	* generic/tkWindow.c:	Fix gcc warning, using gcc-4.3.4 on cygwin
				warning: array subscript has type 'char'

2009-12-11  Donal K. Fellows  <[email protected]>

	* library/tk.tcl (::tk::ScreenChanged): [Bug 2912473]: Stop problems
	caused by display names with a double colon in.

2009-12-10  Donal K. Fellows  <[email protected]>

	* library/demos/ttkscale.tcl: Added demo of [ttk::scale] widget.

2009-12-09  Donal K. Fellows  <[email protected]>

	* generic/tkColor.c (Tk_GetColorByValue): [Bug 2911570]: Ensure that
	hash keys of color values are zeroed first, so that they hash properly
	on 64-bit systems (where X structures are not tightly packed).

	* unix/tkUnixWm.c (TkpMakeMenuWindow):	Improve the determining of what
	* generic/tkMenu.c (ConfigureMenu):	EWMH hint to use so that we
	distinguish between dropdown menus (children of menubars) and what are
	presumably popup menus.

2009-12-08  Pat Thoyts  <[email protected]>

	* unix/tkUnixWm.c: [Bug 2864685]: Apply suitable extended window
	manager hints to the menus so that modern unix window managers can use
	the correct animation modes.

2009-12-02  Jan Nijtmans  <[email protected]>

	* win/configure:	(regenerated)
	* win/Makefile.in:	Use tktest86.dll for all tests.
	* win/tkWinInt.h:	Mark various functions MODULE_SCOPE
	* generic/tkInt.decls:	[Bugs 220600, 220690]: Make TkWinChildProc
				available in private stub table.
	* generic/tkIntPlatDecls.h: (regenerated)
	* generic/tkStubInit.c:	(regenerated)

2009-11-30  Jan Nijtmans  <[email protected]>

	* win/Makefile.in: Better dependancies in case of static build.
	Generate tktest86.dll and tktest86.lib.

2009-11-29  Jan Nijtmans  <[email protected]>

	* generic/tkInt.h:      Make all internal initialization
	* generic/tkTest.c:     routines MODULE_SCOPE
	* generic/tkOldTest.c:
	* generic/tkSquare.c:
	* carbon/tkMaxOSXTest.c:
	* macosx/tkMaxOSXTest.c:
	* win/tkWinTest.c:
	* win/tcl.m4:           (copied from Tcl 8.6)
	* win/configure:        (regenerated)

2009-11-25  Stuart Cassoff  <[email protected]>

	* unix/tcl.m4:		[Patch 2892871]: Remove unneeded
				AC_STRUCT_TIMEZONE.
	* unix/configure:	Regenerated with autoconf-2.59.

2009-11-24  Donal K. Fellows  <[email protected]>

	* unix/tkUnixWm.c (WmIconphotoCmd): [Bug 2902814]: Use the correct
	type for the array of data passed into X. It's wrong, but "right"
	because of a mistake in the X11 specification.

2009-11-23  Andreas Kupries  <[email protected]>

	* library/safetk.tcl (::safe::loadTk): [Bug 2902573]: Fixed access
	to the cleanupHook of the safe base. The code used the old
	internal commands which have been removed since 2009-11-05/06. See
	Tcl's ChangeLog.

2009-11-23  Donal K. Fellows  <[email protected]>

	* unix/Makefile.in: Added .PHONY lines to stop make from getting
	confused when someone makes an error in a rule.

2009-11-22  Pat Thoyts  <[email protected]>

	* tests/winWm.test: [Bug 2899949]: Make sure the window is still
	* win/tkWinWm.c:    present when handling delayed activation.

	* win/Makefile.vc: Include tk stubs in the tktest link

2009-11-21  Donal K. Fellows  <[email protected]>

	* generic/tkUtil.c: Remove some anachronistic techniques (pointless
	casts, mixed assignments and tests, etc.)

	* generic/tk3d.c, generic/tkBitmap.c, generic/tkColor.c:
	* generic/tkCursor.c, generic/tkFont.c, generic/tkTextIndex.c:
	[Tcl Bug 2857044]: Corrections following audit of Tcl_ObjType freeing
	practises; the typePtr field is now cleared when an object ceases to
	be of the type.

2009-11-19  Alexandre Ferrieux  <[email protected]>

	* generic/tkCanvas.c: [Bug 2899685]: Fix the redraw logic of [imove]

2009-11-19  Jan Nijtmans  <[email protected]>

	* doc/GetHINSTANCE.3:	Fix mentioned header file
	* generic/tkTest.c:	Compile with Stubs
	* generic/tkOldTest.c
	* generic/tkSquare.c
	* win/tcl.m4:		Should have been checked in together with the
				2009-08-09 check in of "win/configure"
	* win/tkWinTest.c:	Don't access tkWinProcs from Tk dll any more
	* unix/tcl.m4:		[Patch 2883533]: tcl.m4 support for Haiku OS
	* unix/configure	(regenerated)
	* unix/Makefile.in:	Fix library order in X11_LIB_SWITCHES

2009-11-19  Donal K. Fellows  <[email protected]>

	* generic/tkCanvLine.c (LineDeleteCoords): [Bug 2900121]: Get sense of
	test for drawing optimization correct.

2009-11-15  Donal K. Fellows  <[email protected]>

	* doc/ttk_treeview.n (detach): Added note that the 'move' operation
	restores detached nodes.

2009-11-12  Joe English  <[email protected]>

	* library/ttk/button.tcl, library/ttk/combobox.tcl,
	* library/ttk/notebook.tcl, library/ttk/treeview.tcl:
	[update] hygiene.

	+ Where possible, replace [a; update; b] with [a ; after 0 b].
	+ Where not possible, use [update idletasks] instead of full [update].
	+ Use [after 0] in favor of [after idle] for delayed work, to reduce
	likelihood of reentrancy issues in [update idletasks].

2009-11-11  Don Porter  <[email protected]>

	* generic/tkPlatDecls.h:	[Bug 2886635]: Restore C++
	friendliness to the tkPlatDecls.h header file, which we insist
	extensions #include to gain access to the Tk_*HWND*() routines.

2009-11-10  Andreas Kupries  <[email protected]>

	* unix/Makefile.in: Partially reverted Don Porter's 2009-10-20 commit.
	The OSX Cocoa code branch still needs tclInt.h and the internal
	headers, thus the TCL_PLATFORM directory. See tclMacOSXNotify.c for
	example.

2009-11-09  Donal K. Fellows  <[email protected]>

	* generic/tkFileFilter.c (TkFreeFileFilters): Simplify the code in
	this file by consolidating the deletion code together into a single
	function rather than scattering it over four.

2009-11-01  Joe Mistachkin  <[email protected]>

	* win/tkWinButton.c: [Bug 1739613]: The default width being stored
	in TSD cannot be put into the process-wide options table.  This fix
	allocates storage for the default width from the heap and frees it
	using an exit handler.

2009-11-01  Joe Mistachkin  <[email protected]>

	* doc/loadTk.n: Minor fix for htmlhelp target.

2009-11-01  Joe English  <[email protected]>

	* generic/ttk/ttkWidget.c, doc/ttk_widget.n: Uniform, extensible
	syntax for [$w identify] methods: [$w identify $component $x $y].  All
	ttk::* widgets support [$w identify element $x $y]; widgets with other
	identifiable parts may have additional subcommands.
	* generic/ttk/ttkNotebook.c, doc/ttk_notebook.n: Notebook widgets
	support [$nb identify tab].
	* generic/ttk/ttkPanedwindow.c, doc/ttk_panedwindow.n: Panedwindow
	widgets support [$w identify sash].  Older 2-argument form [$w
	identify $x $y] still supported, though it does different things
	depending on the widget.

2009-10-29  Pat Thoyts  <[email protected]>

	* win/tkWinFont.c: [Bug 1825353]: This patch reverts a previous
	attempt to fix tiny fonts on Russian Windows. It fixes the issue by
	requesting a suitable fixed font instead of decoding the system stock
	font.

2009-10-26  Don Porter  <[email protected]>

	* unix/Makefile.in:	Remove $(PACKAGE).* and prototype from the
	`make distclean` target.  Completes 2009-10-20 commit.

2009-10-25  Donal K. Fellows  <[email protected]>

	* unix/tkUnixColor.c (TkpGetColor): [Bug 2809525]: Impose a maximum
	X11 color name length so that it becomes impossible to blow things up
	that way.

	* library/text.tcl: [Bug 1854913]: Stop <Delete> actions from ever
	deleting backwards, even when the insertion cursor is "at the end" of
	the text widget.

2009-10-24  Donal K. Fellows  <[email protected]>

	* library/button.tcl, unix/tkUnixButton.c (TkpDisplayButton):
	[Patch 1530276]: Make -selectcolor handling work better for both
	checkbuttons and radiobuttons when they don't have indicators.

2009-10-22  Donal K. Fellows  <[email protected]>

	* generic/tkText.c (CreateWidget, TextEditUndo, TextEditRedo)
	(TextEditCmd, UpdateDirtyFlag):
	* generic/tkText.h: [Patch 1469210]: Corrected handling of marking as
	dirty when inserting after an undo from a non-dirty state.

	* win/tkWinDialog.c (GetFileNameA): Make the handling of the filter
	index the same as in GetFileNameW.

	* library/tkfbox.tcl (::tk::dialog::file::, Done):
	* library/xmfbox.tcl (MotifFDialog_FileTypes)
	(MotifFDialog_ActivateSEnt):
	* macosx/tkMacOSXDialog.c (Tk_GetOpenFileObjCmd):
	* win/tkWinDialog.c (GetFileNameW, GetFileNameA):
	* doc/getOpenFile.n: [Patch 2168768]: Corrected handling of the
	-typevariable option to be consistently global; it's the only way it
	can work even close to the same on all platforms.

	* macosx/ttkMacOSXTheme.c (RangeToFactor): [Bug 2883712]: Factor out
	some common code and make sure that it is 64-bit correct.

2009-10-21  Jan Nijtmans  <[email protected]>

	* win/Makefile.in:	[Bug 2875562]: Make sure that winMain.c and
	* win/winMain.c:	tkAppInit.c are never compiled with stubs.
	* unix/tkAppInit.c:

2009-10-20  Don Porter  <[email protected]>

	* unix/Makefile.in:	Compiling Tk no longer requires header files
	* win/Makefile.in:	from the TCL_PLATFORM DIR.  Baby step in
	pursuit of [Bug 1712098].  Also removed the long outdated and broken
	targets package-* that were for building Solaris packages.  Appears
	that the pieces needed for these targets to function have never been
	present in the current era of Tcl development and belong completely
	to Tcl pre-history.

2009-10-20  Andreas Kupries  <[email protected]>

	* library/msgs/pl.msg: Applied patch to Polish message catalog created
	and submitted by Pawel Pawlak <[email protected]> (via JeffH).

2009-10-18  Donal K. Fellows  <[email protected]>

	* doc/menu.n: Reorganized for readability, and added a note describing
	some subtleties of the -variable entry configuration option following
	some discussion with Joe Mistachkin.

2009-10-10  Donal K. Fellows  <[email protected]>

	* unix/tkUnixRFont.c (InitFont, TkpGetFontFromAttributes)
	(Tk_DrawChars, TkpDrawAngledChars): [Bug 1961455]: Draw underlines and
	overstrikes when using Xft for font rendering.

	* generic/tkFont.c (TkDrawAngledTextLayout): Optimize the zero-angle
	case better.

2009-10-08  Donal K. Fellows  <[email protected]>

	* library/iconlist.tcl (Create): [Patch 2870648]: Corrected cursor
	used in file/directory dialogs.

2009-10-07  Pat Thoyts  <[email protected]>

	* library/ttk/vistaTheme.tcl: [Bug 2787164]: Fix size of dropdown
	arrow on combobox and menubutton for Windows 7.

2009-10-07  Donal K. Fellows  <[email protected]>

	* unix/tkUnixScrlbr.c (TkpComputeScrollbarGeometry): [Patch 2088597]:
	Stop scrollbars from getting too small at the end.

2009-10-05  Pat Thoyts  <[email protected]>

	* win/tkWinButton.c: [Bug 2860827]: Avoid 3D effects with
	user-specified backgrounds. The default disabled text is embossed on
	Windows. But this looks poor when a non-default background color is in
	use. This patch disables the embossed effect for buttons and labels
	when the background is non- standard.

2009-09-30  Pat Thoyts  <[email protected]>

	* tests/winWm.test: [Bug 2799589]: Grab on deleted window.

2009-09-25  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (ImgGetPhoto): Correct generation of grayscale
	data from an image. Reported by Keith Vetter on comp.lang.tcl.

2009-09-19  Peter Spjuth  <[email protected]>

	* generic/tkGrid.c:	[Bug 2859912]: Bug fix in grid/pack collision
	* generic/tkPack.c:	detect. Faulty slave was not properly blocked
	* tests/packgrid.test:	from slave list.

2009-09-14  Jeff Hobbs  <[email protected]>

	* generic/tkMenuDraw.c (TkPostSubmenu): [Bug 873613]: Fix reposting of
	* win/tkWinMenu.c (TkWinHandleMenuEvent): submenu in torn off Windows
	menu.
	(DrawMenuEntryArrow): [Bug 873608]: Draw Win menu arrow after being
	torn off.

2009-09-09  Donal K. Fellows  <[email protected]>

	* unix/tkUnixRFont.c (InitFont): Move pattern disposal in error case
	to callers so they have more options when they come to recovering from
	the failure.
	(TkpGetFontFromAttributes): If the default attributes don't work, try
	adding a setting to turn off use of XRender. That seems to work for
	some people for unexplained reasons (possibly local misconfiguration).
	* generic/tkFont.c (Tk_AllocFontFromObj): Stop this function from
	keeling over in a heap when the low-level font allocation fails. An
	error beats a crash! (Issue reported on comp.lang.tcl by Denis
	Berezhnoy.)

2009-09-07  Daniel Steffen  <[email protected]>

	* generic/tkFocus.c:	Fix potential null dereference flagged by clang
	* generic/tkMenu.c:	static analyzer.
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextIndex.c:

	* generic/tkConsole.c:	Silence false positives from clang static
	* generic/tkTest.c:	analyzer about potential null dereference.
	* generic/tkText.c:
	* generic/tkTextBTree.c:
	* generic/tkTextTag.c:
	* generic/tkVisual.c:

2009-09-04  Donal K. Fellows  <[email protected]>

	* generic/tkInt.h (TkDisplay): Remove fields that are never read from.
	* generic/tkWindow.c (Tk_DestroyWindow): Remove code to write to
	write-only fields of TkDisplay. This follows on from [Bug 2039720].

2009-08-25  Donal K. Fellows  <[email protected]>

	* unix/tkUnixSend.c (ServerSecure): [Bug 1909931]: Added some support
	for server-interpreted access control addreses.

2009-08-24  Donal K. Fellows  <[email protected]>

	* library/msgbox.tcl (::tk::MessageBox): Correct bindings so that they
	work with ttk::buttons. Reported by Hans-Christoph Steiner.

2009-08-24  Daniel Steffen  <[email protected]>

	* generic/tkInt.h: Annotate Tcl_Panic as noreturn for clang static
	analyzer in PURIFY builds, replacing preprocessor/assert technique.

	* generic/tkBind.c (HandleEventGenerate): Don't generate events for
	windows that don't exist yet (fixes TkAqua testsuite crash).

	* macosx/tkMacOSXWindowEvent.c: [Bug 2821084]: Allow WM_DELETE_WINDOW
	handlers to prevent window closure by generating WM destroy event
	earlier (from window delegate's -windowShouldClose:).

	* macosx/tkMacOSXDraw.c (TkMacOSX{Setup,Restore}DrawingContext):
	Disable window flushing during Tk drawing to avoid immediate flush of
	NSView-based native widgets on draw. (fixes drawing performance issue
	reported by Youness Alaoui on tcl-mac)

	* macosx/tkMacOSXHLEvents.c (ScriptHandler):	Fix "do script" apple
	* carbon/tkMacOSXHLEvents.c (ScriptHandler):	event handler issues
	on recent OS X releases by using AE coercion to 'utf8' for text data
	and to 'fsrf' for alias data. (reported by Youness Alaoui on tcl-mac)

	* macosx/Wish.sdef (new file):		Install and enable sdef file
	* macosx/Wish-Info.plist.in:		into Wish application bundle,
	* macosx/Tk.xcode/project.pbxproj:	describing TkAqua apple event
	* macosx/Tk.xcodeproj/project.pbxproj:	support for use by AppleScript.
	* unix/Makefile.in:			(replaces functionality of
	* unix/configure.in:			'aete' resource removed with
						Cocoa port & fixes AppleScript
						issues reported on tcl-mac)
	* unix/configure: autoconf-2.59

	* carbon/Wish.xcode/project.pbxproj:	Remove references to obsolete
	* carbon/Wish.xcodeproj/project.pbxproj: prolog.ps file.

2009-08-19  Peter Spjuth  <[email protected]>

	* generic/tk.h
	* generic/tkGeometry.c
	* generic/tkGrid.c
	* generic/tkInt.h
	* generic/tkPack.c
	* generic/tkWindow.c
	* tests/grid.test
	* tests/packgrid.test
	* tests/textIndex.test:	[Patch 2475855]: Give an error if grid and
	pack are used in the same master.

2009-08-14  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDraw.c: Avoid exception in XCopyArea() when copying
	from toplevel that has never been mapped. (Reported by Youness Alaoui
	on tcl-mac)

	* macosx/tkMacOSXWm.c: Workaround for textured windows being draggable
	from opaque content areas. [Bug 2824538] (walzer)

2009-08-10  Jan Nijtmans  <[email protected]>

	* win/tkWinPixmap.c: Eliminate more gcc warnings
	* win/tkWinWm.c:
	* win/tkWinTest.c

2009-08-09  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkInit.c: Eliminate gcc warning
	* generic/tkBind.c
	* generic/tkText.c
	* generic/tkUtil.c
	* win/ttkWinXPTheme.c:	Include <vssym32.h> only when available
	* win/configure.in:	check for vssym32.h, available in newer SDK's
	* win/configure:	(regenerated)

2009-08-08  Donal K. Fellows  <[email protected]>

	* library/demos/pendulum.tcl: Make the display handle being resized
	more gracefully.

2009-08-04  Donal K. Fellows  <[email protected]>

	* generic/tkTextDisp.c (TkTextCharLayoutProc): Make the line breaking
	algorithm (in the word-wrap case) do the right thing with non-breaking
	spaces by restricting what we break on to ASCII spaces, which is good
	enough for most purposes.

2009-08-02  Jan Nijtmans  <[email protected]>

	* win/tkWinClipboard.c Correct check for winNT
	* win/tkWinDialog.c    Eliminate many gcc warnings
	* win/tkWinImage.c:
	* win/tkWinMenu.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
	* win/ttkWinXPTheme.c: Eliminate msvc warnings
	* win/tcl.m4:
	* win/configure
	* win/.cvsignore:      Prevent files from being checked in by accident

2009-08-01  Donal K. Fellows  <[email protected]>

	* unix/tkUnixWm.c (WmIconphotoCmd): [Bug 2830420]: Assemble the image
	for the window manager in a way that doesn't assume we're on a little-
	endian system.

2009-07-27  Donal K. Fellows  <[email protected]>

	* doc/GetScroll.3: Reworded and reordered so as to indicate that the
	Tcl_Obj forms are preferred.

2009-07-26  Donal K. Fellows  <[email protected]>

	* doc/canvas.n: Corrected description of acceptable join styles.
	Spotted by Emiliano Gavilán.

2009-07-23  Donal K. Fellows  <[email protected]>

	* generic/tkSelect.c (HandleTclCommand): [Bug 2441988]: Stop losing
	reports of errors in selection handlers; that's what the background
	error handling code is for.
	*** POTENTIAL INCOMPATIBILITY *** if your code was relying on erroring
	selection scripts being silent.
	(LostSelection, Tk_SelectionObjCmd): Stop using the vastly inefficient
	TkCopyAndGlobalEval; better to use Tcl_Obj refcount management.

2009-07-22  Donal K. Fellows  <[email protected]>

	* generic/tkFocus.c (TkFocusDeadWindow): [Bug 2496114]: Ensure that
	focus desynchronization doesn't cause a crash.

2009-07-21  Donal K. Fellows  <[email protected]>

	* generic/tkFont.c (TkUnderlineAngledTextLayout): [Bug 2356057]:
	Corrected drawing of rotated underlines.

2009-07-21  Alexandre Ferrieux  <[email protected]>

	* generic/tkFont.c: [Bug 2328657]: Explicitly exclude hacky zero-char
	chunks from intersection computation. Might deserve generalization to
	other tests.

2009-07-20  Donal K. Fellows  <[email protected]>

	* tests/clipboard.test (clipboard-6.2): [Bug 2824378]: Corrected
	result of test in light of changes to binary selection retrieval.

2009-07-18  Donal K. Fellows  <[email protected]>

	* unix/tkUnixSelect.c (SelCvtFromX32, SelCvtFromX8): Make the
	incremental transfer of binary selections work get deserialized
	correctly. Thanks to Emiliano Gavilán for detecting.

2009-07-18  Daniel Steffen  <[email protected]>

	* unix/Makefile.in:		Define NDEBUG in optimized (non-
					symbols) build to disable assert()s.

	* macosx/tkMacOSXBitmap.c:	[Bug 2821318]: Fix tk::mac::iconBitmap
					crash due to off-by-one ckalloc error.

2009-07-15  Daniel Steffen  <[email protected]>

	* macosx/ttkMacOSXTheme.c:	[Patch 2819620]: Update notebook tab
	* library/ttk/aquaTheme.tcl:	appearance to modern L&F; adjust tab &
					notebook padding and tabmargins;
					correct appearance of selected tree
					header; add support for native tree
					header sort arrows via user1 state.

	* library/demos/mclist.tcl:	Use native sort arrows with aqua theme

2009-07-15  Donal K. Fellows  <[email protected]>

	* unix/tkUnixSelect.c (TkSelEventProc, SelRcvIncrProc, SelCvtFromX8):
	[Bug 2821962]: Make byte sequence selection transfers possible.

2009-07-14  Donal K. Fellows  <[email protected]>

	* doc/canvas.n (WINDOW ITEMS): [Bug 2326602]: Corrected definition of
	the -height and -width options for these items.

	* unix/configure.in: [Bug 2496018]: Allow the disabling of the use of
	XScreenSaver at configuration time, so as to permit better control of
	dependencies in the embedded case.

2009-07-11  Donal K. Fellows  <[email protected]>

	* doc/grid.n: [Bug 2818455]: Corrected example.

2009-07-02  Pat Thoyts  <[email protected]>

	* generic/tkInt.h: Avoid using C++ reserved word in header.

2009-06-30  Daniel Steffen  <[email protected]>

	* generic/tkInt.h:		Add assert macros for clang static
					analyzer and redefine Tcl_Panic to
					assert after panic in clang PURIFY
					builds.

	* generic/tkImgPhInstance.c:	Small fixes to make clang static
	* generic/tkTextDisp.c:		analyzer happier.

	* generic/tkConfig.c:		Add clang assert for false positives
	* generic/tkUndo.c:		from static analyzer.

2009-06-29  Daniel Steffen  <[email protected]>

	Merge of TkAqua Cocoa port <http://github.com/das/tcltk/tree/de-carbon>
	*** POTENTIAL INCOMPATIBILITY ***

	* macosx/tkMacOSX.h:		Large-scale rewrite of TkAqua migrating
	* macosx/tkMacOSXBitmap.c:	all use of deprecated Carbon API to
	* macosx/tkMacOSXButton.c:	Cocoa API; now supports 64bit
	* macosx/tkMacOSXClipboard.c:	architecture and requires Mac OS X 10.5
	* macosx/tkMacOSXColor.c:	or later; with TkAqua enabled, all Tk
	* macosx/tkMacOSXConfig.c:	sources are now built with the
	* macosx/tkMacOSXCursor.c:	Objective-C compiler and running in
	* macosx/tkMacOSXDebug.c:	Objective-C garbage collection mode as
	* macosx/tkMacOSXDebug.h:	well as in retain-release mode is
	* macosx/tkMacOSXDefault.h:	supported; detailed development history
	* macosx/tkMacOSXDialog.c:	is available in github repository.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEmbed.c:	There should be no script-visible
	* macosx/tkMacOSXEntry.c:	changes to existing Tk functionality,
	* macosx/tkMacOSXEvent.c:	but there are a few aqua-specific
	* macosx/tkMacOSXEvent.h:	additions, see macosx/README for
	* macosx/tkMacOSXFont.c:	details; extensions using only public
	* macosx/tkMacOSXFont.h:	Tk API should continue to work
	* macosx/tkMacOSXHLEvents.c:	unchanged but extensions that rely on
	* macosx/tkMacOSXInit.c:	platform-specific internal Tk API or
	* macosx/tkMacOSXInt.h:		make assumptions about the inner
	* macosx/tkMacOSXKeyEvent.c:	workings of TkAqua (in particular
	* macosx/tkMacOSXKeyboard.c:	presence of QuickDraw) will require
	* macosx/tkMacOSXMenu.c:	porting.
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:	Configure Tk with --enable-aqua=carbon
	* macosx/tkMacOSXMouseEvent.c:	to fallback to now-deprecated previous
	* macosx/tkMacOSXNotify.c:	TkAqua implementation in tk/carbon.
	* macosx/tkMacOSXPort.h:
	* macosx/tkMacOSXPrivate.h:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXWm.h:
	* macosx/tkMacOSXXStubs.c:
	* macosx/ttkMacOSXTheme.c:
	* macosx/tkMacOSXCarbonEvents.c (removed):

	* macosx/tkMacOSXCursors.h (new):	Move cursor data from resources
	* macosx/tkMacOSXXCursors.h (new):	to compiled-in const array;
	* macosx/tkMacOSXCursors.r (removed):	remove obsolete Rez source
	* macosx/tkMacOSXXCursors.r (removed):	files for resource data.
	* macosx/tkAboutDlg.r (removed):
	* macosx/tkMacOSXAETE.r (removed):

	* macosx/Tk.tiff (new):		Rename and update icon to blue feather;
	* macosx/Tk.icns (new):		add tiff version for about dialog.
	* macosx/Wish.icns (removed):

	* macosx/Tk-Info.plist.in:	Update copyright; adjust minimum system
	* macosx/Wish-Info.plist.in:	version requirement.
	* generic/tkEntry.h:

	* license.terms:		Sync list of entities with those in the
					tcl license.terms, add Apple Inc.

	* generic/tk.h:			Update comment with list of source
					files containing tk version numbers.

	* generic/tkButton.c:		On aqua, recompute button geometry on
					secondary image change to enable cache
					of native img format in geom compute.

	* generic/tkGrab.c:		On aqua, make all grabs global, the
					Mac OS X windowserver forces all grabs
					to be application-local only anyway.

	* generic/tkSelect.c:		Enable utf8 atom on aqua.

	* generic/tk.decls:		Replace carbon types in public and
	* generic/tkInt.decls:		internal platform stubs interfaces with
					void* resp. generic Tk types.

	* xlib/xgc.c:			Add support for managing a platform-
					specific cache appended to a GC.

	* tests/dialog.test:		Change name of undefined bit to avoid
					match with OSType native bitmap name.

	* doc/cursors.n:		Update list of cursors mapped to native
					cursors and add new native cursors.

	* doc/menu.n:			Add documentation of new aqua-specific
					.window menu, document new constraints
					on .apple menu.

	* library/console.tcl:		Add aqua window and help menus.

	* unix/Makefile.in:		Add support for TkAqua-implementation-
					specific sources determined at
					configure-time. Update dist target for
					new/removed files.

	* unix/configure.in:		Add libraries & compiler flags for
					Cocoa and Objective-C; update build
					support for new/removed files; add
					support for configure-time choice of
					TkAqua implementation.

	* macosx/Tk-Common.xcconfig (new):	Rename Xcode projects and
	* macosx/Tk-Debug.xcconfig (new):	related files; update for Xcode
	* macosx/Tk-Release.xcconfig (new):	3.1 and 3.2; update for Cocoa,
	* macosx/Tk.xcode/* (new):		Objective-C & GC; update with
	* macosx/Tk.xcodeproj/* (new):		new/removed source files;
	* macosx/Wish.xcode/* (removed):	standardize on gcc 4.2; remove
	* macosx/Wish.xcodeproj/* (removed):	obsolete configurations and
	* macosx/Wish-Debug.xcconfig (removed):	pre-Xcode project.
	* macosx/Wish-Common.xcconfig (removed):
	* macosx/Wish-Release.xcconfig (removed):
	* macosx/Wish.pbproj/* (removed):

	* macosx/README:		Document new Cocoa-port features and
					constraints; update project docs;
					cleanup.

	* carbon/tkMacOSXInt.h:		Add dummy defines for empty GC cache.

	* carbon/tkMacOSXColor.c:	Update for type changes in platform
	* carbon/tkMacOSXDraw.c:	stubs interfaces.
	* carbon/tkMacOSXHLEvents.c:
	* carbon/tkMacOSXMouseEvent.c:
	* carbon/tkMacOSXSubwindows.c:
	* carbon/tkMacOSXWm.c:

	* carbon/tkMacOSXButton.c:	Fix warning.

	* generic/tkPlatDecls.h:	regen.
	* generic/tkIntPlatDecls.h:
	* unix/configure:		autoconf-2.59

2009-06-27  Jan Nijtmans  <[email protected]>

	* generic/tkInt.decls (added TkSmooth(Parse|Print)Proc,
	removed TkTile(Parse|Print)Proc which don't exist):
	Follow-up to [Bug 2804935]: Expose these functions through the
	internal stub table as they are useful to existing third-party code.

2009-06-26  Daniel Steffen  <[email protected]>

	* carbon/ (new directory):	Copy of current state of 'macosx'
	source directory, to preserve legacy TkAqua implementation based on
	Carbon API (with support for Mac OS X releases older than 10.5).

	* unix/Makefile.in:		Add support for --enable-aqua=carbon
	* unix/configure.in:		configure option (legacy fallback for
					pre-Mac OS X 10.5 releases).

	* unix/configure:		autoconf-2.59

2009-06-22  Jan Nijtmans  <[email protected]>

	* generic/tkCanvUtil.c: [Bug 220935]: canvas dash update problem

2009-06-12  Donal K. Fellows  <[email protected]>

	* generic/tkInt.decls (TkOrientParseProc, TkOrientPrintProc):
	[Bug 2804935]: Expose these functions through the internal stub table
	as they are useful to existing third-party code.

2009-06-02  Pat Thoyts  <[email protected]>

	* win/tkWinWm.c:    [Bug 2799589]: Avoid setting the focus on a
	* tests/winWm.test: deleted window during delayed activation.

2009-05-21  Pat Thoyts  <[email protected]>

	* win/tkWinMenu.c: [Bug 2794778]: Calls to CallWindowProc can lead to
	other functions overwriting the event strucure. Therefore preserve a
	local copy of the XKeyEvent while looping over the key events.

2009-05-17  Joe English  <[email protected]>

	* generic/ttkNotebook.c: [Bug 1470246]: More flexible tab placement.

2009-05-14  Pat Thoyts  <[email protected]>

	* generic/tkButton.c: [Bug 1923684]: If a checkbutton offvalue is the
	same as the tristate value we should use the off state in
	preference. (andrey gusev)

2009-05-13  Pat Thoyts  <[email protected]>

	* win/tkWinSend.c: FormatMessage should always use the ignore-inserts
	* win/tkWinTest.c: flag when processing system errors.

	* generic/tkFont.c: [Bug 2791352]: Handle parsing of type 5 font
	* tests/font.test: descriptions with hyphenated family name.

2009-05-06  Pat Thoyts  <[email protected]>

	* library/images/lamp.svg: Added an SVG version of the Tk lamp and
	* library/images/lamp.png: a pre-rendered PNG version.
	* win/rc/wish.ico: Wish gets a new icon using the SVG lamp and the tk
	* win/rc/tk.ico:   dll gets the tcl rendered feather. This provides
	improved icons for Vista/Windows 7.

2009-05-05  Donal K. Fellows  <[email protected]>

	* doc/MainWin.3 (Tk_GetNumMainWindows): [Bug 487220]: Clarified that
	this function works per-thread, not per-process.

	* doc/canvas.n (scale): [Bug 1832015]: Clarified that [$c scale] only
	affects item coordinates.

2009-05-04  Donal K. Fellows  <[email protected]>

	* doc/3DBorder.3, doc/BindTable.3, doc/CanvPsY.3, doc/Clipboard.3:
	* doc/ConfigWidg.3, doc/CrtWindow.3, doc/GetBitmap.3:
	* doc/GetCapStyl.3, doc/GetImage.3, doc/GetJoinStl.3, doc/GetScroll.3:
	* doc/GetSelect.3, doc/GetVisual.3, doc/MainWin.3, doc/Name.3:
	* doc/ParseArgv.3, doc/TextLayout.3, doc/Tk_Init.3: [Bug 2431507]:
	Purge all mention of the now-obsolete 'interp->result'.

2009-05-03  Donal K. Fellows  <[email protected]>

	* win/tkWinWm.c (UpdateWrapper): [Bug 2785744]: Manipulate flag bit
	correctly so that menubar updates can't smash other attributes.

2009-05-01  Donal K. Fellows  <[email protected]>

	* library/mkpsenc.tcl (DrawText): [Bug 2777019]: Corrected point of
	application of rotation transform so rotation is about the anchor
	point of the text.

	* generic/tkCanvPs.c (Tk_PostscriptPhoto):
	* library/mkpsenc.tcl: Factor out the postscript code for converting
	images into postscript so that the code bits are in the prolog and not
	emitted at runtime if a non-thread-safe static says to...

2009-04-30  Pat Thoyts  <[email protected]>

	* win/tkWinWm.c: [Patch 2504402]: Create icon bitmaps as device
	independent bitmaps. This ensures the icon can be drawn properly on
	various colour depth surfaces - in particular it fixes a problem with
	remote desktop and looks better in the vista task switching overlay.
	(cjmcdonald)

2009-04-30  Donal K. Fellows  <[email protected]>

	* win/tkWinPixmap.c (Tk_GetPixmap): [Bug 2080533]: Added patch that
	allows Tk to keep working even when the graphics card is stressed.

2009-04-28  Jeff Hobbs  <[email protected]>

	* unix/tcl.m4, unix/configure (SC_CONFIG_CFLAGS): Harden the check
	to add _r to CC on AIX with threads.

2009-04-27  Donal K. Fellows  <[email protected]>

	* generic/tkInt.decls: [Bug 2768945]: Expose (as "private") a set of
	functions needed for easily building canvas items that work like
	existing standard ones.

2009-04-24  Jeff Hobbs  <[email protected]>

	* win/tkWinDialog.c (ChooseDirectoryValidateProc): No need to set cwd
	on selchange. Prevents delete of selected folder in dialog.

2009-04-24  Stuart Cassoff <[email protected]>

	* unix/Makefile.in: Assorted issues:
	[Bug 2764263]: Removed stray @ from Makefile.in test target.
	[Bug 1945073]: Don't chmod+x square demo.
	[Patch 2764272]: Adjustable demo install location.

2009-04-24  Stuart Cassoff <[email protected]>

	* unix/Makefile.in: [Patch 2769530]: Don't chmod/exec installManPage.

2009-04-23  Jeff Hobbs  <[email protected]>

	* win/tkWinDialog.c (Tk_ChooseDirectoryObjCmd): [Bug 2779910]: Enable
	the new style choosedir that has a "New Folder" button, with
	::tk::winChooseDirFlags override for new behavior.

2009-04-14  Donal K. Fellows  <[email protected]>

	* library/xmfbox.tcl (MotifFDialog_ActivateSEnt): Ensure that the
	* library/tkfbox.tcl (Done):			  dialogs have the
	correct levels for [upvar] for accessing the -typevariable var.

2009-04-13  Donal K. Fellows  <[email protected]>

	* library/tk.tcl: Corrected another problem; can't determine the exact
	type of OS - needed for figuring out how to guess the correct binding
	in some circumstances - in a safe interpreter.

	* library/tkfbox.tcl: [Bug 2759119]: Corrected level handling for the
	* library/xmfbox.tcl: -typevariable option following updates to tk.tcl
	[Patch 2739360]: Use more modern images from Tango set for the non-
	Motif file dialog. Thanks to Emiliano for bring this to my attention.

2008-04-10  Joe English  <[email protected]

	* library/palette.tcl (tk_setPalette): Don't set *selectColor:
	#b03060; this makes radio- and checkbuttons look wrong post-TIP#109.

2009-04-10  Daniel Steffen  <[email protected]>

	* unix/configure.in (Darwin):	Use Darwin SUSv3 extensions if
					available.
	* unix/configure:		autoconf-2.59
	* unix/tkConfig.h.in:		autoheader-2.59

	* library/demos/filebox.tcl: Only show "Motif Style Dialog"
	checkbutton on X11 windowingsystem.

	* library/demos/widget: GOOBE: use ttk::cursor

	* library/demos/knightstour.tcl: Fix knightstour demo not running from
	interactive wish.

	* library/console.tcl (::tk::ConsoleInit): Remove redundant TkAqua
	Quit menu item.

	* generic/tkPointer.c (Tk_UpdatePointer): Use all 5 buttons.

	* generic/tkMenu.c (PostProcessEntry): Delay call to
	TkpConfigureMenuEntry() until all menu entry attributes are setup.

	* library/menu.tcl (::tk::MbPost): Fix error thrown in y position
	computation with indicatoron.

	* generic/tkMenubutton.c: s/DEF_BUTTON_JUSTIFY/DEF_MENUBUTTON_JUSTIFY/

	* generic/tkUtil.c (TkBackgroundEvalObjv): Use Tcl_BackgroundException

	* generic/tkTextBTree.c (TkBTreeDeleteIndexRange): Add bounds check
	to startEnd array access (fixes testsuite crash).

	* tests/unixFont.test: Only use xlsfonts with X11 windowingsystem.

2009-04-10  Donal K. Fellows  <[email protected]>

	* library/tk.tcl: [Bug 2116837]: Add event definitions to handle the
	standard virtual events when Caps Lock is on.

2009-04-08  Donal K. Fellows  <[email protected]>

	* library/demos/widget (addFormattedText): Stop marking demonstrations
	as new for 8.6; that label is for wholly new demos.

2009-04-04  Donal K. Fellows  <[email protected]>

	* doc/messageBox.n: [Bug 1881896]: Reworded to be clearer on what the
	platform restrictions really are.

2009-04-03  Joe English  <[email protected]>

	* unix/tkUnixWm.c: [Bug 1789819]: Don't panic when the window manager
	does something unexpected with the stacking order.

2009-04-03  Donal K. Fellows  <[email protected]>

	* doc/TextLayout.3: [Bug 974421]: Clarified description of how result
	of lookup of a point after end of layout relates to the underlying
	string's length.

2009-04-02  Pat Thoyts  <[email protected]>

	* tests/textTag.test: Ensure the pointer begins outside the window for
	all the tests checking Enter/Leave motion events.

	* library/demos/pendulum.tcl: Use unicode labels
	* library/demos/knightstour.tcl: Use polygon knight on x11.

2009-03-31  Donal K. Fellows  <[email protected]>

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

2009-03-25  Jan Nijtmans  <[email protected]>

	* doc/wish.1:		Bring doc and demos in line with
	* library/demos/hello:	http://wiki.tcl.tk/812
	* library/demos/rmt
	* library/demos/square
	* library/demos/tcolor
	* library/demos/timer
	* library/demos/widget
	* win/tkWinMenu.c:	Eliminate a few compiler warnings on mingw
	* win/ttkWinXPTheme.c:	Spacing

2009-03-25  Donal K. Fellows  <[email protected]>

	* generic/ttk/ttkTheme.c (BuildOptionMap, NewElementClass):
	[Bug 2178820]: Ensure that zero-size allocations don't happen; some
	malloc implementations don't like it at all.

	* win/wish.exe.manifest.in: [Bug 1871101]: Add magic to make Tk not be
	blurred on Vista with large fonts.

2009-03-14  Donal K. Fellows  <[email protected]>

	* unix/tk.pc.in (new file):		[Patch 2243962] (hat0)
	* unix/configure.in, unix/Makefile.in: Added support for reporting
	Tk's public build configuration via the pkg-config system. TEA is
	still the official mechanism though, in part because pkg-config is not
	universally supported across all Tk's supported platforms.

2009-03-10  Donal K. Fellows  <[email protected]>

	* doc/event.n: Tidy up and improve examples.

2009-03-09  Benjamin Riefenstahl  <[email protected]>

	* tkMacOSXFont.c (GetFontFamilyName): [Bug 2548661]: Handle NULL
	return from CFStringCreate.

2009-02-27  Jan Nijtmans  <[email protected]>

	* doc/GetBitmap.3:    [FRQ 2636558]: Tk_DefineBitmap and
	* generic/tk.decls:   Tk_GetBitmapFromData signature problem
	* generic/tkInt.decls:
	* generic/tkBitmap.c:
	* generic/tkInt.h:
	* generic/tkStubInit.c:
	* generic/tkDecls.h:    (regenerated)
	* generic/tkIntDecls.h: (regenerated)
	* macosx/tkMacOSXBitmap.c:

2009-02-27  Pat Thoyts  <[email protected]>

	* generic/tkWindow.c: [Bug 2645457]: Check for dead windows after
	calling Tk_MakeWindowExist to avoid a crash when mapping dead windows.

2009-02-23  Pat Thoyts  <[email protected]>

	* win/rc/*.cur: [Patch 2513104]: Fix cursor hotspots (cjmcdonald)

	* win/tkWinMenu.c: Applied patch for menu image display bug.
	[Bug 1329198, 456299] [Patch 2507419] (cjmcdonald)

2009-02-22  Pat Thoyts  <[email protected]>

	* win/tkWinCursor.c: Applied patch to support stock Win32 help arrow
	cursor when question_arrow requested [Patch 2542828] (danckaert)

2009-02-21  Pat Thoyts  <[email protected]>

	* library/ttk/vistaTheme.tcl: Correct the ttk::treeview border on
	* win/ttkWinXpTheme.c:        XP and vista.

	* library/console.tcl: [Bug 2546087]: In 2004 a fix to Tcl channels
	prevented the exposure of the internal UTF-8 representation of the
	ASCII NUL character (\uc080). Since then strings in the console have
	been truncated at NUL. This restores the older behaviour.

2009-02-17  Jeff Hobbs  <[email protected]>

	* win/tcl.m4, win/configure: Check if cl groks _WIN64 already to avoid
	CC manipulation that can screw up later configure checks. Use 'd'ebug
	runtime in 64-bit builds.

2009-02-16  Jeff Hobbs  <[email protected]>

	* win/configure.in, win/configure: Align better with tcl version.
	Ensures finding correct CPP for Win64.

2009-02-16  Donal K. Fellows  <[email protected]>

	* doc/ttk_intro.n: [Bug 2604420]: Improve wording so that this page
	feels less obviously incomplete.

2009-02-12  Donal K. Fellows  <[email protected]>

	* library/iconlist.tcl: Split out the IconList megawidget from
	tkfbox.tcl into its own file so as to make it easier to maintain. Also
	cleans up the API for the megawidget, making it more like a
	conventional Tk widget.

2009-02-11  Donal K. Fellows  <[email protected]>

	* library/demos/items.tcl, .../label.tcl, .../twind.tcl:
	* library/demos/images/ouster.png: [Bug 2588919]: Demo GOOBE. Added
	new image of John Ousterhout that does not look quite so massively out
	of date, and also showed off a bit of how we can adjust PNG images
	when loading them. Also labeled JO as the creator; it's the TCT who
	are the proprietors now.

2009-02-10  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: [Bug 2502365]: Building of head on HPUX was broken when
	using the native CC.
	* unix/configure (autoconf-2.59)

2009-02-08  Joe English  <[email protected]>

	* generic/ttk/*.[ch]: Renamed several internal data structures and
	functions: ElementImpl -> ElementClass, LayoutNode -> Element. Remove
	more unnecessary casts. Add function Ttk_ClientRegion, common factor
	of entry, scale, progress, and treeview widgets.
	* generic/ttk/ttkTrack.c: Fix [Bug 2431428].

2009-02-06  Daniel Steffen  <[email protected]>

	* generic/tkImgPhInstance.c:	Fix numerous leaks discovered with the
	* generic/tkMenu.c:		Mac OS X Instruments.app Leaks tool.
	* generic/tkText.c:
	* generic/tkTextImage.c:
	* generic/tkTextIndex.c:
	* generic/tkUndo.c:
	* generic/tkUtil.c:
	* generic/ttk/ttkFrame.c:
	* macosx/tkMacOSXWm.c:

2009-01-29  Jan Nijtmans  <[email protected]>

	* generic/tkCanvArc.c   - eliminate some unnessary type casts
	* generic/tkCanvBmap.c  - some internal const decorations
	* generic/tkCanvImg.c   - spacing
	* generic/tkCanvWind.c
	* generic/tkCmds.c
	* generic/tkConfig.c
	* generic/tkEntry.c
	* generic/tkFocus.c
	* generic/tkFont.c
	* generic/tkFrame.c
	* generic/tkGrab.c
	* generic/tkGrid.c
	* generic/tkImage.c
	* generic/tkListbox.c
	* generic/tkObj.c
	* generic/tkOption.c
	* generic/tkPack.c
	* generic/tkPanedWindow.c
	* generic/tkRectOval.c
	* generic/tkSelect.c
	* generic/tkText.c
	* generic/tkTextMark.c
	* generic/tkTextTag.c

2009-01-28  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkCache.c:  - eliminate some unnessary type casts
	* generic/ttk/ttkLayout.c  - some internal const decorations
	* generic/ttk/ttkState.c   - spacing
	* generic/ttk/ttkTheme.c
	* macosx/tkMacOSXMenu.c
	* macosx/tkMacOSXPrivate.h
	* unix/tkUnixFont.c
	* unix/tkUnixMenu.c
	* unix/tkUnixWm.c
	* win/tkWinColor.c
	* win/tkWinDialog.c
	* win/tkWinFont.c
	* win/tkWinMenu.c
	* win/tkWinSend.c
	* win/tkWinWindow.c
	* win/tkWinWM.c

2009-01-22  Kevin B. Kenny  <[email protected]>

	* unix/tcl.m4: Corrected a typo ($(SHLIB_VERSION) should be
	${SHLIB_VERSION}).
	* unix/configure: Autoconf 2.59

2009-01-19  Kevin B. Kenny  <[email protected]>

	* unix/Makefile.in: Added a CONFIG_INSTALL_DIR parameter so that
	* unix/tcl.m4:      distributors can control where tclConfig.sh goes.
	Made the installation of 'ldAix' conditional upon actually being on an
	AIX system. Allowed for downstream packagers to customize
	SHLIB_VERSION on BSD-derived systems.
	Thanks to Stuart Cassoff for [Patch 907924].
	* unix/configure: Autoconf 2.59

2009-01-16  Don Porter  <[email protected]>

	* generic/tk.h:		Bump patchlevel to 8.6b1.1 to distinguish
	* library/tk.tcl:	CVS snapshots from the 8.6b1 and 8.6b2
	* unix/configure.in:	releases.
	* win/configure.in:

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

2009-01-14  Jan Nijtmans  <[email protected]>

	* generic/tkImgPhoto.c: [Bug 2507326]: Fix for aMSN compatibility
	* generic/tkMenu.h: CONSTify Tk(Create|Find)MenuReferences
	* generic/tkMenu.c: various internal "const" decorations.

2009-01-13  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: [Bug 2502365]: Building of head on HPUX was broken when
	using the native CC
	* unix/configure (autoconf-2.59)

2009-01-13  Pat Thoyts  <[email protected]>

	* tests/constraints.tcl: Made the tests more independent of the
	* tests/*.test:          presence of images in the interpreter.

2009-01-11  Pat Thoyts  <[email protected]>

	* tests/bind.test: Fixed keysym bind tests for unix [Bug 2336454]

2009-01-11  George Peter Staplin <[email protected]>

	* generic/tkEvent.c: Fix a possible segv due to a NULL pointer
	dereference that occurs when XCreateIC fails.

2009-01-11  Pat Thoyts  <[email protected]>

	* library/bgerror.tcl: Pretty up the unix tk_messageBox icons with PNG
	* library/icons.tcl:   images and grouped all the stock icons in one
	* library/msgbox.tcl:  file.
	* library/tk.tcl:

2009-01-11  Joe English  <[email protected]>

	* generic/ttk/ttkNotebook.c (NotebookCleanup): [Bug 2496162]: Don't
	call Tk_DeleteOptionTable(), it's unnecessary and quite possibly
	harmful.

2009-01-08  Jan Nijtmans  <[email protected]>

	* generic/tk3d.c:     CONSTify TkDebugBorder
	* generic/tkBind.c:   CONSTify TkStringToKeysym
	* generic/tkBitmap.c: CONSTify TkDebugBitmap
	* generic/tkColor.c:  CONSTify TkDebugColor
	* generic/tkCursor.c: CONSTify TkDebugCursor
	* generic/tkFont.c:   CONSTify TkDebugFont
	* generic/tkInt.decls All those mods TIP #27 complient,
	                      no incompatibility risks.
	* generic/tkIntDecls.h (regenerated)

2009-01-08  Pat Thoyts  <[email protected]>

	* library/bgerror.tcl: Theme the bgerror dialog and make use of our
	PNG support to improve the icon.

2009-01-07  Pat Thoyts  <[email protected]>

	* library/tkfbox.tcl: [Bug 2473120]: Mis-ordered messagebox args.

	* win/tkWinWm.c: [Bug 1847002]: Prevent grabs being bypassed on
	Windows.

2009-01-06  Jan Nijtmans  <[email protected]>

	* generic/tk.h:		A few const -> CONST86 modifications,
	* generic/tkCanvas.c:	improving backwards compatibility. Change
	* generic/tkCanvLine.c:	Tk_ItemIndexProc and Tk_ItemInsertProc
	* generic/tkCanvPoly.c:	signature to have a Tcl_Obj parameter instead
	* generic/tkCanvText.c:	of a string parameter. This is binary and
	* doc/CrtItemType.3:	source compatible with previous API, it just
	* doc/Clipboard.3:	prevents the need for a type cast in the
	* doc/ConfigWidg.3:	Tk_ItemType table construction. Bring doc in
	* doc/ParseArgv.3:	line with API.

2009-01-06  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock): Optimize a common case for
	photo image building. [Patch 1539990] (jepler)

2009-01-06  Pat Thoyts  <[email protected]>

	* win/tkWinDialog.c: Use task modal for messagebox instead of system
	modal. [Bug 2484771] (ferrieux,thoyts,mjanssen)

2009-01-03  Donal K. Fellows  <[email protected]>

	* doc/canvas.n: [Bug 1836621]: Improve the documentation of the
	-offset and -outlineoffset item options.

2009-01-03  Jan Nijtmans  <[email protected]>

	* generic/tk.decls:       CONSTify Tk_ClipboardAppend
	* generic/tkClipboard.c:
	* generic/tkDecls.h: (regenerated)

2008-12-31  David Gravereaux <[email protected]>

	* win/rules.vc: Small bug not setting SYMBOLS macro fixed.

2008-12-31  Joe English  <[email protected]>

	* generic/ttk/ttkDefaultTheme.c: Fix color palette for radiobutton and
	checkbutton indicators. Fixes [Bug 2003310]; also makes "alt" theme
	check/radiobuttons look like Windows 98, as intended.
	* library/ttk/altTheme.tcl: Specify dark gray -bordercolor to soften
	edges.
	* tests/ttk/{checkbutton,radiobutton}.test: Split out of ttk.test.

2008-12-28  Donal K. Fellows  <[email protected]>

	TIP #171 IMPLEMENTATION

	* library/listbox.tcl, library/scrlbar.tcl, library/text.tcl: Adjust
	users of the <MouseWheel> event to do the right thing horizontally as
	well as vertically.
	* win/tkWinX.c (GenerateXEvent): Redirect <MouseWheel> to the window
	that contains the mouse.
	* generic/tkEvent.c (InvokeFocusHandlers): Do not direct <MouseWheel>
	through the focus mechanism.
	*** POTENTIAL INCOMPATIBILITY *** for anyone counting on shift-wheel
	to do something else (or nothing at all) or for the wheel events to be
	following the keyboard on Win.

	* generic/tkImgPNG.c (ReadIDAT): Corrected code to transfer blocks of
	compressed data into the Tcl_ZlibStream. Allows the reading of all
	images from PngSuite set. Thanks to Michael Kirkham for fix/testing.

	TIP #244 IMPLEMENTATION

	* generic/tkImgPNG.c, tests/imgPNG.test, doc/photo.n: Adaptation of
	tkpng to the Tk core, proving support for PNG image reading and
	writing, based on Tcl's zlib support.

2008-12-27  Joe English  <[email protected]>

	* generic/ttk/ttkTreeview.c: [Bug 2381555]: Fix inconsistent use of
	treeArea / headingArea. ([$tv identify] didn't work when horizontally
	scrolled).

2008-12-21  Donal K. Fellows  <[email protected]>

	* doc/canvas.n (postscript): Regularized documentation of -channel
	option.

2008-12-19  Don Porter  <[email protected]>

	*** 8.6b1 TAGGED FOR RELEASE ***

	* changes:	Updates for 8.6b1 release.

	* tests/clrpick.test:	Eliminate duplicate test names.
	* tests/embed.test:
	* tests/text.test:
	* tests/textMark.test:

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

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

2008-12-18  Don Porter  <[email protected]>

	* library/msgs/de.msg:	[Patch 2442309]: Updated German messages.
	Thanks to Ruediger Haertel.

2008-12-17  Jan Nijtmans  <[email protected]>

	* generic/tk.h:		VOID --> void
	* unix/tkUnixPort.h:
	* macosx/tkMacOSXPort.h:

2008-12-17  Donal K. Fellows  <[email protected]>

	* doc/selection.n: [Bugs 2441817,2441884]: Assorted small fixes.

2008-12-16  Jan Nijtmans  <[email protected]>

	* win/tkWinDialog.c: Remove unused variables

2008-12-15  Don Porter  <[email protected]>

	TIP #338 IMPLEMENTATION

	* doc/Tk_Main.c:	Removed the last two '#include "tclInt.h"'.
	* generic/tkMain.c:	Tk is now limited to Tcl's public interface.
	* macosx/tkMacOSXInit.c:

2008-12-12  Pat Thoyts  <[email protected]>

	* library/demos/fontchoose.tcl: Simple fontchooser demo.
	* library/demos/widget:

2008-12-11  Jan Nijtmans  <[email protected]>

	* generic/tk3d.c:	Make error message from Tk_GetRelief the same
				as for Tk_GetReliefFromObj.
	* tests/canvas.test:	Adapt test cases for changed error message.
	* tests/scrollbar.test
	* tests/textTag.test

2008-12-11  Joe English  <[email protected]>

	* library/demos/*.tcl: Omit contraindicated [package require Ttk].
	Remove logic that switches [ttk::scrollbar]s to [tk::scrollbar]s
	based on [tk windowingsystem]; this is already handled in
	library/ttk/scrollbar.tcl.

2008-12-10  Daniel Steffen  <[email protected]>

	TIP #324 IMPLEMENTATION

	* generic/tkCmds.c:		Implementation of [tk fontchooser] as
	* generic/tkInt.h:		a Ttk dialog for X11 and as a native
	* win/tkWinDialog.c:		platform dialog on Mac OS X & Windows.
	* win/tkWinInt.h:		(thoyts, vetter, robert, steffen)
	* win/tkWinTest.c:		[Patch 1477426]
	* win/tkWinX.c:
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXFont.h:
	* macosx/Wish.xcodeproj/project.pbxproj:
	* library/fontchooser.tcl (new):
	* library/tclIndex:
	* library/msgs/de.msg:
	* library/msgs/en.msg:
	* tests/fontchooser.test (new):
	* tests/winDialog.test:
	* doc/fontchooser.n (new):
	* doc/tk.n:

	* library/console.tcl:		Let user select console font via
					[tk fontchooser].
	* library/demos/text.tcl:	Add [tk fontchooser] demo.

	* generic/tkUtil.c:		Add TkBackgroundEvalObjv() and
					TkSendVirtualEvent() utility functions
					(used by TIP #324 code).

	* generic/tkInt.h:		Turn [tk] into an ensemble.
	* generic/tkBusy.c:		(thoyts, steffen)
	* generic/tkCmds.c:
	* generic/tkWindow.c:

	* macosx/tkMacOSXInit.c (TkpInit): Unconditionally show Tk console if
					   TK_CONSOLE env var is set.

2008-12-09  Don Porter  <[email protected]>

	TIP #337 IMPLEMENTATION

	* generic/tkBind.c:	Updated callers of Tcl_BackgroundError() to
	* generic/tkCanvas.c:	use the new routine
	* generic/tkEntry.c:	Tcl_BackgroundException() as appropriate.
	* generic/tkImgBmap.c:
	* generic/tkListbox.c:
	* generic/tkSelect.c:
	* generic/tkTextDisp.c:
	* generic/tkTextWind.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXWindowEvent.c:
	* unix/tkUnixScale.c:
	* unix/tkUnixWm.c:
	* win/tkWinButton.c:
	* win/tkWinMenu.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWm.c:

2008-12-07  Joe English  <[email protected]>

	* macosx/ttkMacOSXTheme.c: [Bug 2219588]: Add native aqua elements for
	ttk::spinbox
	* generic/ttk/ttkEntry.c, library/ttk/spinbox.tcl,
	* tests/ttk/spinbox.test: Moved most spinbox "business logic" out of
	ttkEntry.c into Tcl bindings.
	* library/ttk/clamTheme.tcl: Minor spinbox appearance improvements.
	* library/ttk/combobox.tcl, library/ttk/utils.tcl:
	Factor out ttk::bindMouseWheel procedure.
	* library/ttk/spinbox.tcl: Add cross-platform MouseWheel bindings.

2008-12-06  Donal K. Fellows  <[email protected]>

	TIP #197 IMPLEMENTATION

	* generic/tkText.c (insertUnfocussedStrings, optionSpecs):
	* generic/tkText.h (TkText, TkTextInsertUnfocussed):
	* doc/text.n, tests/text.test:
	Added definitions/tests/docs for "-insertunfocussed" field.
	* generic/tkTextMark.c (TkTextInsertDisplayProc):
	* generic/tkText.c (TextBlinkProc):
	Added user-controlledrendering of insertion cursor when focus is not
	in the text widget.

2008-12-05  Pat Thoyts  <[email protected]>

	* library/ttk/ttk.tcl:	      Added vista theme to iron out the visual
	* library/ttk/vistaTheme.tcl: differences between vista and XP.
	* library/ttk/xpTheme.tcl:
	* win/ttkWinXPTheme.c:

2008-12-05  Donal K. Fellows  <[email protected]>

	* generic/tkCanvPs.c (Tk_PostscriptFont): [Bug 2107938]: Ensure that
	font sizes can ever be negative; it triggers a really strange case
	that is definitely not what is wanted.
	* library/mkpsenc.tcl: Corrected and improved generation of postscript
	* library/prolog.ps:  prolog. Removed prolog.ps, which wasn't used and
	was misleading.

2008-12-04  Jan Nijtmans  <[email protected]>

	* generic/tkInt.decls:	[FRQ 220906]: Move 10 functions from tkText.h
	* generic/tkText.h:     to stub table.
	* generic/tkStubInit.c (regenerated)
	* generic/tkIntDecls.h (regenerated)

2008-12-04  Donal K. Fellows  <[email protected]>

	* doc/ttk_button.n, doc/ttk_checkbutton.n, doc/ttk_menubutton.n:
	* doc/ttk_radiobutton.n: Added mention of the Toolbutton style to all
	widgets that can sensibly make use of it.

2008-12-03  Joe English  <[email protected]>

	* generic/ttk/ttkState.c, generic/ttk/ttkTheme.h,
	* generic/ttk/ttkWidget.c, doc/ttk_widget.n:
	Add new "hover" state (patch from Pat Thoyts; needed to support proper
	visual feedback on Vista).

2008-11-29  Pat Thoyts  <[email protected]>

	* library/ttk/altTheme.tcl:     Use a styled frame around the popdown
	* library/ttk/clamTheme.tcl:    listbox so we can adjust the border
	* library/ttk/classicTheme.tcl: for each theme as needed.
	* library/ttk/combobox.tcl:
	* library/ttk/defaults.tcl:
	* library/ttk/winTheme.tcl:
	* library/ttk/xpTheme.tcl:
	* tests/ttk/combobox.test:

2008-11-28  Alexandre Ferrieux  <[email protected]>

	* generic/tkCanvUtil.c:	[Bug 1813597,2218964]: Millimeter patch.
	* generic/tkInt.h:	Eliminates the functional redundancy and
	* generic/tkObj.c:	unnecessary loss of precision of the
	* generic/tkText.c:	{pixel,mm}ObjType tandem.

2008-11-27  Jan Nijtmans  <[email protected]>

	* generic/tkCanvLine.c:	Replace Tcl_SetResult(interp, NULL, ....)
	* generic/tkEntry.c:	calls with Tcl_ResetResult(interp)
	* generic/tkMenu.c
	* generic/tkOldConfig.c
	* win/tkWinTest.c:	Eliminate warning: unused variable 'tkwin'

2008-11-23  Pat Thoyts  <[email protected]>

	* generic/tkBind.c:  [Bug 1389270]: event generate silently ignored
	* generic/tkFocus.c: focus events. These can now be generated.
	* generic/tkGrab.c:
	* generic/tkInt.h:
	* tests/bind.test: Fixed some locale dependencies in various
	tests to reduce the noise on non-English windows systems.

2008-11-22  Donal K. Fellows  <[email protected]>

	* library/demos/ctext.tcl: Extended to show off what you can do with
	angled text; there is now a pie selector to change the orientation.

2008-11-22  Pat Thoyts  <[email protected]>

	* library/ttk/combobox.tcl: [Bug 1939129,1991930]: combobox dropdown
				    was drawn behind topmost toplevels.
	* generic/tkCanvText.c:  Fixed up complaints from MSVC engendered
	* generic/tkFont.c:      by the last commit. In particular replaced
	* win/tkWinDraw.c:       round() which is a C99 function.
	* win/tkWinFont.c:

2008-11-22  Donal K. Fellows  <[email protected]>

	TIP #119 IMPLEMENTATION

	* generic/tkCanvText.c:  Added -angle configuration option to canvas
	* generic/tkFont.c:	 text items. This required reengineering the
	* library/prolog.ps:	 whole text rendering engine to be able to
	* macosx/tkMacOSXFont.c: handle an angle! No change to any external
	* unix/tkUnixFont.c:	 API. Note, this feature was originally
	* unix/tkUnixRFont.c:	 approved for Tk 8.5, but it has proved much
	* win/tkWinFont.c:	 harder to implement than originally
	* generic/tkInt.h:	 estimated. [Patch 1611359]
	* tests/canvText.test:

2008-11-22  Pat Thoyts  <[email protected]>

	* test/winDialog.test: [Bug 2307837]: Avoid some locale-dependent
	* win/tkWinTest.c:     failures by using id's or an english constraint

2008-11-19  Joe English  <[email protected]>

	* doc/ttk_panedwindow.n: [Bug 1824996]: Remove inoperative text
	stating that slave windows must be direct children of the master.

2008-11-19  Jan Nijtmans  <[email protected]>

	* generic/tkImgPhoto.c	 Minor simplification in fix for [Bug 2312027]
				 no need to malloc and copy photo type name
				 because it is a constant to begin with.
	* generic/tkOldConfig.c	 Convert Tcl_SetResult(......, TCL_DYNAMIC) to
	* mac/tkMacOSXWm.c	 Tcl_SetResult(......, TCL_VOLATILE), in
	* unix/tkUnixWm.c	 preparation for TIP #340
	* unix/tkUnixSend.c
	* win/tkWinWm.c

2008-11-16  Joe English  <[email protected]>

	* generic/ttk/ttkWidget.c: [Bug 2298720]: Widget self-destruction is
	not necessarily an error.

2008-11-16  Donal K. Fellows  <[email protected]>

	* doc/wm.n: Added note about [wm overrideredirect] so that users will
	avoid making unwarranted assumptions about how magical it is.
	Triggered by [Bug 2282861] discussion.

2008-11-14  Pat Thoyts  <[email protected]>

	* generic/tk.h:	       The TIP 125 implementation permits the
	* generic/tkFrame.c:   [wm manage] command to manage any widget but
	* macosx/tkMacOSXWm.c: only those with Frame instance data should be
	* unix/tkUnixWm.c:     permitted. We now check for the suitability and
	* win/tkWinWm.c:       raise an error for non-frame widgets. Updated
	* test/wm.test:	       the tests and documentation. See also [Bug
	* doc/wm.n:	       2239034]

2008-11-12  Joe English  <[email protected]>

	* generic/ttk/ttkWidget.c: Reworked widget construction and
	destruction sequence; fixes [Bug 2207435] and several other problems
	discovered during investigation of same.
	* generic/ttk/ttkButton.c (CheckbuttonInitialize): Account for
	initializeProc being called earlier in the construction sequence now.
	* tests/ttk/ttk.test: Updated test suite.

2008-11-12  Pat Thoyts  <[email protected]>

	* library/text.tcl: [Bug 1777362]: Handle windows with funky names by
	* test/text.test:   avoiding use of the window path for anchors.

2008-11-11  Jan Nijtmans  <[email protected]>

	* generic/tkImgPhoto.c	  Fix [Bug 2265860] new test failures

2008-11-11  Joe English  <[email protected]>

	* generic/ttk/ttkWidget.c (BeginDrawing): [Bug 2264732]: Don't crash
	when application uses nondefault visual.

2008-11-11  Jan Nijtmans  <[email protected]>

	* win/tcl.m4:	    Reverted change from 2008-11-06 (was under the
			    impression that "-Wno-implicit-int" added an extra
			    warning)
	* win/configure	    (regenerated)
	* unix/tcl.m4:	    Use -O2 as gcc optimization compiler flag, and get
			    rid of -Wno-implicit-int for UNIX
	* unix/configure    (regenerated)

	* generic/tk.decls     Modify Tk_Create(Old)ImageType signature,
	* generic/tk.h	       relaxing the constraint that every Tk_ImageType
	* generic/tkImage.c    can only be passed to this function once. This
	* generic/tkImgBmap.c  lets tkImg be loaded in multiple interpreters
	* generic/tkImgPhoto.c in a thread-enabled build of Tk. [Bug 2312027]
	* generic/tkTest.c     This CONSTification complies with TIP #27. It
	* doc/CrtImgType.3     is binary compatible with the old interface,
			       but not fully source compatible (although tkImg
			       does not suffer).
	* generic/tkDecls.h (regenerated)

	*** POTENTIAL INCOMPATIBILITY ***

2008-11-09  Joe English  <[email protected]>

	* generic/ttk/ttkWidget.c: Remove unnecessary casts.

	* generic/ttk/ttkWidget.h, generic/ttk/ttkWidget.c: Ttk widget
	initializeProc()s now return void instead of a status code, and are no
	longer allowed to fail. (Fix for [Bug 2207435] in progress).

	* generic/ttk/ttkButton.c, generic/ttk/ttkEntry.c,
	* generic/ttk/ttkFrame.c, generic/ttk/ttkNotebook.c,
	* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c,
	* generic/ttk/ttkScale.c, generic/ttk/ttkScrollbar.c,
	* generic/ttk/ttkTreeview.c: Adjustments for the above.

2008-11-09  Jan Nijtmans  <[email protected]>

	* generic/tkCanvas.c:	 Make all Tk_CustomOption tables const and
	* generic/tkCanvBmap.c:	 remove unnecessary type cast.
	* generic/tkCanvImg.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkRectOval.c:
	* generic/tkScrollbar.c:
	* generic/tk.decls:	Two more (hopefully the last) signature
	* generic/tkInt.h:	changes in Tk_CreateSmoothMethod and
	* generic/tkCanvLine.c: Tk_CreatePhotoImageFormat
	* generic/tkCanvUtil.c:
	* generic/tkImgPhoto.c:
	* generic/tkDecls.h: (regenerated)
	* doc/CrtImgType.3:  doc updates
	* doc/CrtPhImgFmt.3:

2008-11-06  Jan Nijtmans  <[email protected]>

	* win/tcl.m4: Add "-Wno-implicit-int" flag for gcc, as on UNIX
	* win/configure: (regenerated)
	* generic/default.h: Use tkUnixDefault.h under CygWin. With this
			     change, at least the X11 version of Tk can be
			     built with cygwin.

2008-11-06  Donal K. Fellows  <[email protected]>

	* unix/configure.in: [Bug 2229999]: Work around the fact that the
	HP-UX system compiler cannot handle 'inline'.

2008-11-05  Jan Nijtmans  <[email protected]>

	* unix/tkUnixFont.c:   [Bug 2226093]: Const changes not all correct
	* unix/tkUnixButton.c: More internal -Wwrite-strings warning fixes
	* unix/tkUnixCursor.c:
	* unix/tkUnixSend.c:
	* unix/tkUnixRFont.c:
	* generic/tkInt.h:     No need to use CONST in internal header files
	* generic/tkFont.h
	* generic/tkInt.decls: CONSTify string and fileName parameters of
	* generic/tkImgBmap.c: TkGetBitmapData
	* generic/tkBitmap.c:  Remove unneccessary type cast
	* generic/tkIntDecls.h: (regenerated)
	* doc/GetCursor.3:     Fix documentation about obsolete X10 bitmaps
	* doc/GetBitmap.3:     [Bug 1866774]: Remove X10 references from docs

2008-11-03  Jan Nijtmans  <[email protected]>

	* generic/ttk/ttkEntry.c: Fix warning: unused variable `currentValue'
	* generic/tkOldTest.c:	  Fix warning: assignment discards qualifiers
	* win/tkWinTest.c:	  from pointer target type

2008-11-03  Pat Thoyts  <[email protected]>

	* tests/winClipboard.test: testclipboard no longer returns strings
	with embedded \r but now returns Tcl strings
	* tests/winfo.test: Fixed embedding test broken during upgrade
	* tests/busy.test: Default wait cursor on windows is 'wait'
	* win/tkWinFont.c: const fixes for the windows code.

2008-11-02  Jan Nijtmans  <[email protected]>

	* generic/tkFont.h:	 More internal -Wwrite-strings warning fixes
	* generic/tkFont.c
	* generic/ttk/ttkTheme.h
	* generic/ttk/ttkDefaultTheme.c
	* generic/ttk/ttkState.c
	* macosx/tkMacOSXFont.c
	* unix/tkUnixFont.c
	* win/tkWinFont.c

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

	TIP #97 IMPLEMENTATION

	* generic/tkCanvas.c (CanvasWidgetCmd): Implementation of the 'imove'
	and 'rchars' subcommands.
	* generic/tk.h (TK_MOVABLE_POINTS): New flag to allow items to state
	whether they support finding and moving individual coordinates.
	* doc/canvas.n, tests/canvas.test: Docs 'n' tests.

2008-11-01  Pat Thoyts  <[email protected]>

	* generic/ttk/ttkEntry.c:      Implemented the themed spinbox
	* library/ttk/altTheme.tcl:    widget.
	* library/ttk/clamTheme.tcl:
	* library/ttk/classicTheme.tcl:
	* library/ttk/defaults.tcl:
	* library/ttk/entry.tcl:
	* library/ttk/ttk.tcl:
	* library/ttk/winTheme.tcl:
	* library/ttk/xpTheme.tcl:
	* library/ttk/spinbox.tcl:
	* win/ttkWinTheme.c:
	* win/ttkWinXPTheme.c:
	* doc/ttk_spinbox.n:
	* tests/ttk/spinbox.test:

2008-10-31  Joe English  <[email protected]>

	* generic/widget.c: Temporary workaround for [Bug 2207435]

2008-10-30  Jan Nijtmans  <[email protected]>

	* generic/tkAtom.c:	 more internal -Wwrite-strings warning fixes
	* generic/tkBusy.c
	* generic/tkButton.c
	* generic/tkCanvPoly.c
	* generic/tkCanvText.c
	* generic/tkCmds.c
	* generic/tkListbox.c
	* generic/tkMenu.c
	* generic/tkOldConfig.c
	* generic/tkOption.c
	* generic/tkPanedWindow.c
	* generic/tkPlace.c
	* generic/tkScale.c
	* generic/tkTest.c
	* generic/tkText.c
	* generic/tkTextImage.c

2008-10-30  Don Porter  <[email protected]>

	* tests/unixSelect.test:	Revise the unixSelect-1.* tests so that
	they test the ability of Tk's selection mechanism to faithfully pass
	valid Tcl values without corruption, and stop testing details of
	Tcl's internal encoding scheme.	 With this change, the Tk test suite
	no longer uses the identity encoding or [string bytelength].

2008-10-30  Jan Nijtmans  <[email protected]>

	* generic/tk.h:		      CONSTify return value of
	* generic/tkInt.h	      Tk_OptionPrintProc, and customPtr
	* generic/tk.decls	      field of Tk_ConfigSpec.
	* generic/tkCanvArc.c	      See [Bug 2190619]: Warnings due to
	* generic/tkCanvLine.c	      Tk_SmoothMethod name constness change
	* generic/tkCanvUtil.c
	* generic/tkUtil.c
	* generic/tkDecls.h:	      (regenerated)

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

	* generic/tkAtom.c(Tk_GetAtomName): Remove incorrect 'const' qualifier.
	Remove useless 'register' declarations too, while we're at it.

2008-10-28  Jan Nijtmans  <[email protected]>

	* generic/tk.h:		Add "const" to a few struct member fields.
	* generic/tkInt.h:	CONSTify TkPrintPadAmount
	* generic/tkSelect.h:	Move TkSelGetSelection to tkInt.decls
	* generic/tk.decls:	CONSTify Tk_ParseArgv
	* generic/tkInt.decls:	CONSTify TkCreateFrame and TkCreateMainWindow
	* generic/tkDecls.h:	(regenerated)
	* generic/tkIntDecls.h:	(regenerated)
	* generic/tkArgv.c:
	* generic/tkAtom.c:
	* generic/tkEntry.c:
	* generic/tkFrame.c:
	* generic/tkImgPhoto.c:
	* generic/tkPack.c:
	* generic/tkSelect.c:
	* generic/tkVisual.c:
	* generic/tkWindow.c:
	* win/tkWinTest.c:	Fix compilation under mingw32

2008-10-28  Joe English  <[email protected]>

	* library/ttk/cursors.tcl, library/ttk/combobox.tcl,
	library/ttk/entry.tcl, library/ttk/paned.tcl, library/ttk/sizegrip.tcl,
	library/treeview.tcl:
	[Bug 2054562]: Add correct platform-specific cursors for OSX
	[Bug 1534835]: Expanded set of symbolic cursors.  Use correct cursor
	for ttk::entry and ttk::combobox widgets

2008-10-28  Don Porter  <[email protected]>

	* win/tkWinTest.c:		[Bug 2191960]: Revise [testclipboard]
	* tests/winClipboard.test:	to form that handles encodings.
	* tests/constraints.tcl: [tcltest::bytestring] no longer used.

2008-10-24  Joe English  <[email protected]>

	* tests/ttk/ttk.test: [Bug 2175411]: Disable test ttk-6.3, it's not
	applicable.

	* generic/ttk/ttkTheme.c: Use different Tcl_AssocData key so the tile
	extension can be loaded into an 8.6 interp, in the off-chance that
	anyone wants to do this.

2008-10-24  Donal K. Fellows  <[email protected]>

	* generic/tkCanvUtil.c (TkSmoothPrintProc): [Bug 2190619]: Corrected
	'const'ness to quell warning.

2008-10-23  Don Porter  <[email protected]>

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

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

2008-10-22  Jan Nijtmans  <[email protected]>

	* generic/tk.h:		      CONST -> const and white-spacing
	* generic/tk.decls
	* generic/tkInt.decls
	* generic/tkDecls.h:	      (regenerated)
	* generic/tkIntDecls.h:	      (regenerated)
	* generic/tkIntPlatDecls.h:   (regenerated)
	* generic/tkIntXlibDecls.h:   (regenerated)
	* generic/tkPlatDecls.h:      (regenerated)
	* generic/ttk/tk.decls
	* generic/ttk/ttkDecls.h      (regenerated)
	* generic/ttk/ttkGenStubs.tcl

2008-10-20  Donal K. Fellows  <[email protected]>

	* generic/tkBusy.c, macosx/tkMacOSXEmbed.c, unix/tkUnixEmbed.c:
	* win/tkWinWindow.c: [Bug 2180919]: Factor out the platform-specific
	parts into the platform directories.

2008-10-18  Donal K. Fellows  <[email protected]>

	TIP #321 IMPLEMENTATION

	* generic/tkBusy.c, doc/busy.n, tests/busy.test: [Patch 1997907]:
	Implementation of the [tk busy] command.

2008-10-18  Pat Thoyts  <[email protected]>

	* win/tkWinFont.c: [Bug 1825353]: To fix a problem with tiny fonts on
	Russian versions of Windows we will avoid removing the internal
	leading for fixed width fonts.

2008-10-15  Jan Nijtmans  <[email protected]>

	* generic/tk.h:		 Add "const" to many internal const tables, so
	* generic/tkBind.c:	 those will be put by the C-compiler in the
	* generic/tkButton.c:	 TEXT segment instead of the DATA segment.
	* generic/tkCanvas.c:	 This makes those tables as being shareable in
	* generic/tkClipboard.c: shared libraries.
	* generic/tkCmds.c:
	* generic/tkConsole.c:
	* generic/tkEntry.c:
	* generic/tkFocus.c:
	* generic/tkFrame.c:
	* generic/tkGet.c:
	* generic/tkGrab.c:
	* generic/tkGrid.c:
	* generic/tkImage.c:
	* generic/tkImgBmap.c:
	* generic/tkImgGIF.c:
	* generic/tkImgPhoto.c:
	* generic/tkListbox.c:
	* generic/tkMenu.c:
	* generic/tkMenu.h:
	* generic/tkMenubutton.c:
	* generic/tkMessage.c:
	* generic/tkOption.c:
	* generic/tkPack.c:
	* generic/tkPanedWindow.c:
	* generic/tkPlace.c:
	* generic/tkScale.c:
	* generic/tkSelect.c:
	* generic/tkSquare.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkTextDisp.c:
	* generic/tkTextMark.c:
	* generic/tkTextTag.c:
	* generic/tkTextWind.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXWin.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixWm.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinDialog.c:
	* win/tkWinMenu.c:
	* win/tkWinSend.c:
	* win/tkWinWm.c:
	* xlib/xcolors.c:

2008-10-17  Pat Thoyts  <[email protected]>

	* library/ttk/scale.tcl: Implemented keyboard bindings for ttk::scale

2008-10-15  Jan Nijtmans  <[email protected]>

	* generic/tkInt.h:	 Add "const" to many internal const tables, so
	* generic/tk3d.c:	 those will be put by the C-compiler in the
	* generic/tkBitmap.c:	 TEXT segment instead of the DATA segment.
	* generic/tkColor.c:	 This makes those tables as being shareable in
	* generic/tkConfig.c:	 shared libraries.
	* generic/tkCursor.c:
	* generic/tkFont.c:
	* generic/tkObj.c:
	* generic/tkStyle.c:
	* generic/tkTextIndex.c:
	* generic/tkUtil.c:

2008-10-14  Donal K. Fellows  <[email protected]>

	* generic/tkObj.c (TkNewWindowObj): Added utility function for making
	a Tcl_Obj from a Tk_Window reference. Candidate for future exposure to
	third-party code I suppose, but useful internal to Tk for sure.

2008-10-11  Donal K. Fellows  <[email protected]>

	* generic/tkCanvas.c (CanvasWidgetCmd): Corrected result generation.

2008-10-10  Don Porter  <[email protected]>

	*** 8.6a3 TAGGED FOR RELEASE ***

	* changes:	Updates for 8.6a3 release.

2008-10-09  Don Porter  <[email protected]>

	* generic/tkListbox.c:	Make literal return values consistent with
	those generated by Tcl_PrintDouble().

	* tests/entry.test:	Restore test naming consistency with Tk 8.5.
	* tests/listbox.test:	Remove some more dependency on precision in
	* tests/spinbox.test:	test results.

2008-10-08  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4:		[Bug 2073255]: fix
	* unix/configure:	regenerated

2008-10-08  Don Porter  <[email protected]>

	* tests/textDisp.test (textDisp-16.34): Update test that tested string
	equality of double values based on an assumption of tcl_precision==12.
	Test now does its own formatting.

	* tests/scrollbar.test: Revised testing of the cget subcommand so that
	it tests consistency with the configure subcommand and not agreement
	with a hardcoded value that will change as tastes in GUIs evolve.

	* tests/canvText.test (canvText-17.1): Update expected result to match
	revised PostScript output due to more predictable formatting of
	floating point values.

	* unix/tkUnixWm.c:	[Bug 2021443]: Restored consistency of error
	* macosx/tkMacOSXWm.c:	messages from [wm iconphoto] with the test
	* tests/unixWm.test:	suite and across all platforms.

2008-10-07  Pat Thoyts  <[email protected]>

	* tests/canvImg.test:  Removed dependency on precision in results
	* tests/canvRect.test:
	* tests/canvText.test:
	* tests/entry.test:
	* tests/listbox.test:
	* tests/scrollbar.test:
	* tests/spinbox.test:
	* tests/winWm.test: Fixed incorrect error strings
	* tests/wm.test:

2008-10-06  Pat Thoyts  <[email protected]>

	* tests/winDialog.test: Fixed tests for Vista+
	* win/tkWinWm.c: corrected some errors from the previous commit

2008-10-05  Donal K. Fellows  <[email protected]>

	* win/tkWinWm.c (WmAttributesCmd, WmOverrideredirectCmd)
	(WmStackorderCmd):
	* win/tkWinSendCom.c (Async):
	* win/tkWinSend.c (Tk_SendObjCmd):
	* win/tkWinFont.c (TkpGetFontFamilies, TkpGetSubFonts):
	* unix/tkUnixWm.c (WmOverrideredirectCmd, WmStackorderCmd):
	* unix/tkUnixFont.c (TkpGetFontFamilies, TkpGetSubFonts):
	* macosx/tkMacOSXWm.c (WmOverrideredirectCmd, WmStackorderCmd):
	* generic/tkTextIndex.c (SetTextIndexFromAny):
	* generic/tkTest.c (TrivialConfigObjCmd):
	* generic/tkSelect.c (HandleTclCommand):
	* generic/tkPanedWindow.c (Tk_PanedWindowObjCmd)
	(PanedWindowSashCommand, PanedWindowProxyCommand):
	* generic/tkMenubutton.c (Tk_MenubuttonObjCmd):
	* generic/tkMenu.c (MenuWidgetObjCmd):
	* generic/tkListbox.c (ListboxWidgetObjCmd):
	* generic/tkImgPhoto.c (ImgPhotoCmd): (mostly)
	* generic/tkImage.c (Tk_ImageObjCmd):
	* generic/tkFont.c (Tk_FontObjCmd, GetAttributeInfoObj):
	* generic/tkEntry.c (EntryWidgetObjCmd, SpinboxWidgetObjCmd):
	* generic/tkConfig.c (SetOptionFromAny, Tk_SetOptions):
	* generic/tkCmds.c (Tk_TkObjCmd, Tk_WinfoObjCmd, TkGetDisplayOf):
	* generic/tkButton.c (ButtonCreate): Get rid of code that insists on
	non-idiomatically writing to the object in the interpreter result.

2008-10-03  Donal K. Fellows  <[email protected]>

	* generic/tkArgv.c, generic/tkCanvText.c, generic/tkEntry.c:
	* generic/tkListbox.c, generic/tkScrollbar.c, macosx/tkMacOSXScrlbr.c:
	* win/tkWinScrlbr.c: [Bug 2112563]: Convert use of %g to
	Tcl_PrintDouble to create string versions of floats so as to avoid
	trouble with some locales.

2008-10-02  Joe Mistachkin  <[email protected]>

	* doc/canvas.n: Fix unmatched font change.
	* win/buildall.vc.bat: Prefer the HtmlHelp target over the WinHelp
	target.

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

	TIP #236 IMPLEMENTATION

	* doc/canvas.n, generic/tkCanvas.c (CanvasWidgetCmd)
	* tests/canvMoveto.test: Added 'moveto' subcommand to canvases to
	allow items to be easily moved to a particular place.

2008-09-23  Donal K. Fellows  <[email protected]>

	* doc/listbox.n (SEE ALSO): [Bug 2123813]: Redirected this to
	ttk::treeview(n) which is far more useful (it does multicolumn listbox
	duties).

	* doc/*.n: [Bug 2118116]: Make sure that the initial line of the
	manpage includes nothing that chokes old versions of man.

2008-08-25  Todd M. Helfter  <[email protected]>

	* library/menu.tcl: [Bug 1023955]: Additional fix.

2008-09-08  Todd M. Helfter  <[email protected]>

	* doc/menu.n: [Bug 2098425]: Fix typo in docs.

2008-09-03  Don Porter  <[email protected]>

	* generic/tk.h:		Dropped use of _ANSI_ARGS_ macro to preserve
	* generic/tkSelect.h:	Tk's TCL_NO_DEPRECATED build.

2008-08-30  Ania Pawelczyk  <[email protected]>

	* tests/textWind.test: Update to tcltest2
	* tests/unixSelect.test:
	* tests/visual_bb.test:
	* tests/visual.test:
	* tests/window.test:
	* tests/winfo.test:
	* tests/xmfbox.test:
	* tests/winButton.test:
	* tests/winDialog.test:
	* tests/winFont.test:
	* tests/winMenu.test:
	* tests/winMsbox.test:
	* tests/winWm.test:

2008-08-28  Don Porter  <[email protected]>

	* unix/tkConfig.sh.in:	Added @XFT_LIBS@ to the definition of TK_LIBS
	to avoid link failures when a "big wish" program links against a
	--disable-shared build of libtk. (Discovered building expectTk.)

	* generic/tkImgPhoto.c:	Changed TclStack* calls to ck* calls so that
	we don't create new dependencies on Tcl internals.

	* unix/tkUnixPort.h:	Removed #include of tclInt.h that has been
	* win/tkWinPort.h:	disabled for three years. If we needed this
	we'd have noticed by now.

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

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

2008-08-28  Donal K. Fellows  <[email protected]>

	* tests/imgPhoto.test: [Bug 2080587]: Fix failures.

2008-08-28  Ania Pawelczyk  <[email protected]>

	* tests/option.test: Update to tcltest2
	* tests/place.test:
	* tests/scale.test:
	* tests/select.test:
	* tests/textBTree.test:
	* tests/textImage.test:
	* tests/textMark.test:
	* tests/textTag.test:
	* tests/unixMenu.test:

2008-08-25  Todd M. Helfter  <[email protected]>

	* library/menu.tcl: [Bug 1023955]: Fix typo.

2008-08-27  Peter Spjuth  <[email protected]>

	* tests/grid.test: [Bug 2075285]: Added a "knownBug"-marked test to
	show a problem identified in the grid implementation.

2008-08-26  Donal K. Fellows  <[email protected]>

	* tests/imgPhoto.test: More style improvements.

2008-08-25  Todd M. Helfter  <[email protected]>

	* library/menu.tcl: [Bug 1023955]: Do not flip to the arrow cursor on
	menus. This was a Motif convention. Current behavior is maintained iff
	tk_strictMotif is enabled.

2008-08-25  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoConfigureMaster): Ensure that uses of
	TclStackAlloc and TclStackFree balance.

2008-08-25  Todd M. Helfter  <[email protected]>

	* library/tkfbox.tcl: [Bug 1936220]: Fix the multiple selection error
	for tk_getOpenFile -multiple 1 which fails on all unix platforms since
	the adoption of ttk widgets.

2008-08-25  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c:	     Split the implementation of the core of
	* generic/tkImgPhoto.h:	     photo images into two pieces, the photo
	* generic/tkImgPhInstance.c: master (which manages the data model and
	the interaction with the script level) and the photo instances (which
	handle display).

2008-08-22  Don Porter  <[email protected]>

	*** 8.6a2 TAGGED FOR RELEASE ***

	* changes:	Updates for 8.6a2 release.

2008-08-21  Ania Pawelczyk  <[email protected]>

	* tests/menuDraw.test: Update to tcltest2
	* tests/msgbox.test:
	* tests/oldpack.test:
	* tests/pack.test:
	* tests/panedwindow.test:

2008-08-21  Donal K. Fellows  <[email protected]>

	* generic/tkOption.c (ExtendArray): Rework so that the code uses
	ckrealloc (idiomatically) rather than its home-brewed version.

2008-08-19  George Peter Staplin  <[email protected]>

	[Bug 2039720]: After some discussion with Joe English and subsequently
	the X.org developers (Keith Packard in particular), it was discovered
	that Tk is doing management of XIDs that it shouldn't need to do. The
	very common XC-MISC extension which has come with every version of X
	for the last 15 years is used with Xlib now, to retrieve the
	information about the used/unused XIDs. The public Tk_FreeXId is now a
	no-op.

	* generic/tkError.c: Remove the usage of TkpWindowWasRecentlyDeleted.
	* generic/tkInt.decls: Update the declarations for the now unused
	internal stubs.
	* generic/tkIntDecls.h: Regenerated based on tkInt.decls.
	* generic/tkIntPlatDecls.h: Regenerated based on tkInt.decls.
	* generic/tkStubInit.c
	* generic/tkWindow.c: Remove the calls to TkInitXId, and
	TkFreeWindowId.
	* macosx/tkMaxOSXPort.h: Remove TkFreeWindowId and TkInitXId macro
	definitions.
	* macosx/tkMacOSXXStubs.c: Remove the no-op
	TkpWindowWasRecentlyDeleted.
	* unix/tkUnixEvent.c: Remove call to TkFreeXId.
	* unix/tkUnixXId.c: Remove a lot of unnecessary code (see above).
	* win/tkWinPort.h: Remove TkFreeWindowId and TkInitXId.
	* win/tkWinWindow.c: Remove TkpWindowWasRecentlyDeleted.
	* tests/id.test: Remove this unnecessary test.

2008-08-19  Joe English  <[email protected]>

	* generic/ttk/ttkScroll.c: Don't use sprintf "%g" to format floating
	point numbers in -[xy]scrollcommand callbacks or [xy]view methods.
	Minor incompatibility: 0 and 1 now formatted as "0.0" resp "1.0".
	* tests/ttk/entry.test, tests/ttk/treeview.test: Updated to account
	for above change.

2008-08-19  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXFont.c (SetFontFeatures): Disable antialiasing of
						   fixed-width fonts with
						   size <= 10.

2008-08-18  Ania Pawelczyk  <[email protected]>

	* tests/canvWind.test: Update to tcltest2
	* tests/menubut.test:
	* tests/raise.test:
	* tests/unixButton.test:
	* tests/unixEmbed.test:
	* tests/winClipboard.test:

2008-08-17  Ania Pawelczyk  <[email protected]>

	* tests/focus.test: Update to tcltest2
	* tests/focusTcl.test:
	* tests/geometry.test:
	* tests/grab.test:
	* tests/grid.test:
	* tests/imgBmap.test:
	* tests/imgPhoto.test:
	* tests/imgPPM.test:
	* tests/listbox.test:
	* tests/safe.test:
	* tests/tk.test:
	* tests/util.test:

2008-08-15  Ania Pawelczyk  <[email protected]>

	* tests/clrpick.test: Update to tcltest2
	* tests/frame.test:
	* tests/font.test:
	* tests/image.test:

2008-08-14  Ania Pawelczyk  <[email protected]>

	* tests/event.test: Update to tcltest2
	* tests/id.test:
	* tests/menu.test:

2008-08-14  Daniel Steffen  <[email protected]>

	* unix/tcl.m4 (SC_PATH_X):	Check for libX11.dylib in addition to
					libX11.so et al.

	* unix/configure:		autoconf-2.59

2008-08-12  Ania Pawelczyk  <[email protected]>

	* tests/choosedir.test: Update to tcltest2
	* tests/clipboard.test:
	* tests/embed.test:
	* tests/main.test:

2008-08-12  Don Porter  <[email protected]>

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

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

	* changes:	Updates for 8.6a2 release.

2008-08-11  Ania Pawelczyk  <[email protected]>

	* tests/canvImg.test: Update to tcltest2
	* tests/canvRect.test:
	* tests/canvText.test:
	* tests/obj.test:

2008-08-07  Ania Pawelczyk  <[email protected]>

	* tests/canvPs.test: Update to tcltest2
	* tests/config.test:
	* tests/canvas.test:

2008-08-05  Joe English  <[email protected]>

	* generic/tk.h, generic/tkEvent.c: Fix for [Bug 2010422] "no event
	type or button # or keysym while executing "bind Listbox
	<MouseWheel> [...]".

2008-08-03  Ania Pawelczyk  <[email protected]>

	* tests/cmds.test: Update to tcltest2
	* tests/dialog.test:
	* tests/get.test:
	* tests/text.test: Update to tcltest2; report: 33.11 fails

2008-08-01  Pat Thoyts  <[email protected]>

	* win/tkWinWm.c: [Bug 2028703]: Check wmPtr is valid in
	* tests/wm.test: TopLevelReqProc.

2008-07-31  Don Porter  <[email protected]>

	* generic/tk.h: Added missing EXTERN for the Tcl_PkgInitStubsCheck
	declaration to fix inability to embed non-stub-enabled Tk on Windows.

2008-07-29  Ania Pawelczyk  <[email protected]>

	* tests/constraints.tcl: -highlightthickness entry's option (fonts
	constraint)

2008-07-28  Ania Pawelczyk  <[email protected]>

	* tests/cursor.test: Update to tcltest2
	* tests/message.test:

2008-07-26  Pat Thoyts  <[email protected]>

	* doc/options.n: [Bug 1686012]: Direct to the font manual for -font.

	* tests/constraints.tcl: Add a nonwin contraint.
	* tests/listbox.test:	 [Bug 2024753]: Conform to testing policy.

	* win/tkWinWm.c: [Bug 2009788]: Check that the parent has been mapped
	* tests/wm.test: before calling RemapWindows.

	* win/tkWinWindow.c: [Bug 2026405]: Check for 0x prefix in sprintf %p.

2008-07-25  Ania Pawelczyk  <[email protected]>

	* tests/bind.test: Update to tcltest2

2008-07-24  Jan Nijtmans  <[email protected]>

	* generic/*.c: [Bug 2021443]: Fix inconsistant "wrong # args" messages
	* macosx/tkMacOSXSend.c
	* macosx/tkMacOSXWm.c
	* unix/tkUnixSend.c
	* unix/tkUnixWm.c
	* tests/*.test

2008-07-22  Ania Pawelczyk  <[email protected]>

	* tests/bell.test:   Update to tcltest2
	* tests/bgerror.test:
	* tests/bitmap.test:
	* tests/border.test:
	* tests/button.test:
	* tests/entry.test:
	* tests/spinbox.test:

2008-07-22  Daniel Steffen  <[email protected]>

	* library/ttk/aquaTheme.tcl: Use system color names and TIP145 named
	font instead of hardcoded color values and deprecated native font name

	* macosx/tkMacOSXHLEvents.c: Factor out common code; formatting.

2008-07-08  Pat Thoyts  <[email protected]>

	* doc/*.n: Fixed broken line endings from last doc commit.

2008-07-04  Joe English  <[email protected]>

	* generic/ttk/ttkDefaultTheme.c, generic/ttk/ttkClamTheme.c,
	* generic/ttk/ttkClassicTheme.c, generic/ttk/ttkElements.c:
	[Bug 2009213]: Audit: ensure that output arguments to Tk_Get*FromObj()
	are initialized, in case of erroneous style specifications.

2008-07-02  Donal K. Fellows  <[email protected]>

	* macosx/tkMacOSXHLEvents.c: Some tidying up of this file. Make sure
	that failing handling callbacks get reported as background errors.

2008-06-30  Donal K. Fellows  <[email protected]>

	* doc/*.1, doc/*.3, doc/*.n: Remove out of date changebars, make
	formatting of typedefs consistent, other small changes.

2008-06-25  Don Porter  <[email protected]>

	*** 8.6a1 TAGGED FOR RELEASE ***

	* changes:		Updates for 8.6a1 release.

2008-06-24  Pat Thoyts  <[email protected]>

	* library/demos/ttkpane.tcl: Work around missing timezones
	* doc/text.n: [Bug 1997293]: Fix documentation of text tag options.

2008-06-19  Don Porter  <[email protected]>

	* changes:		Updates for 8.6a1 release.

	* generic/tk.h:		TIP 285 additions make Tk 8.6 call the new
	* library/tk.tcl:	Tcl_Canceled() routine, available only in Tcl
	8.6, so bump our Tcl dependencies to version 8.6. Tk 8.6a1 will no
	longer [load] into a Tcl 8.5 interp.

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

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

2008-06-18  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXCarbonEvents.c: Fix debug carbon event tracing.
	(InstallStandardApplicationEventHandler): Replace needless use of
	TkMacOSXInitNamedDebugSymbol() by standard TkMacOSXInitNamedSymbol().

	* macosx/tkMacOSXDebug.c:	Revert 2007-11-09 commit making
	* macosx/tkMacOSXDebug.h:	TkMacOSXInitNamedDebugSymbol()
					available outside of debug builds.

	* macosx/tkMacOSXEmbed.c (TkpMakeWindow):	Fix bug with missing
	* macosx/tkMacOSXSubwindows.c (XMapWindow):	focus on first map by
	only sending VisibilityNotify events once windows are mapped (rather
	than when they are created).

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessWindowEvent): Fix
	return value.

	* macosx/tkMacOSXInit.c:	Add helper to efficiently convert from
	* macosx/tkMacOSXPrivate.h:	CFString to Tcl_Obj.

	* macosx/tkMacOSXFont.c (TkpGetFontFromAttributes, InitFont):	Fix
	incorrect conversion to points of font sizes already in points; factor
	out retrieval of font family name from font family ID.

2008-06-13  Jeff Hobbs  <[email protected]>

	* win/configure, win/configure.in (TK_WIN_VERSION): Fix handling of
	interim a/b versioning for manifest usage.

2008-06-13  Joe Mistachkin  <[email protected]>

	TIP #285 IMPLEMENTATION

	* generic/tkCmds.c: During [tkwait] and [update], always cooperatively
	check for script cancellation.
	* win/makefile.vc: Added 'pdbs' option for Windows build rules to
	* win/rules.vc: allow for non-debug builds with full symbols.

2008-06-12  Daniel Steffen  <[email protected]>

	* generic/tkPointer.c (Tk_UpdatePointer): [Bug 1991932]: Fix failure
	to restore a global grab capture and to release the restrict window
	capture when releasing a button grab. Fixes segfault due to dangling
	reference to restrict window inside TkpSetCapture() implementation.

	* generic/ttk/ttkTreeview.c:	Fix warning.

	* unix/tcl.m4 (SunOS-5.11): Fix 64bit amd64 support with gcc & Sun cc.
	* unix/configure: autoconf-2.59

	* macosx/tkMacOSXXStubs.c (Tk_ResetUserInactiveTime): Use UsrActivity
	instead of OverallAct (which may be ignored in some circumstances).

	* macosx/Wish.xcodeproj/project.pbxproj: Add tclIORTrans.c; add tclOO
	* macosx/Wish.xcodeproj/default.pbxuser: files to tktest-X11 target;
	add debug configs for 64bit and with corefoundation disabled; updates
	and cleanup for Xcode 3.1 and for Leopard; sync with Tcl.xcodeproj.
	* macosx/Wish.xcode/project.pbxproj:	Sync Wish.xcodeproj changes.
	* macosx/Wish.xcode/default.pbxuser:
	* macosx/README:			Document new build configs.

2008-06-10  Joe English  <[email protected]>

	* unix/tkUnixKey.c: [Patch 1986818]: Use Xutf8LookupString if
	available. This should fix problems (like [Bug 1908443]) where Xlib's
	idea of the system encoding does not match Tcl's.

2008-06-01  Daniel Steffen  <[email protected]>

	* macosx/Wish.xcodeproj/project.pbxproj: Add new tclOO files; add
	* macosx/README:			 debug configs with gcov;
						 update to Xcode 3.1.

2008-05-27  Pat Thoyts  <[email protected]>

	* generic/ttk/ttkTheme.c: [ttk::style theme use] without an argument
	* doc/ttk_style.n: now returns the current theme.

2008-05-23  Joe English  <[email protected]>

	* doc/ttk_treeview.n, generic/ttk/ttkTreeview.c,
	* generic/ttk/ttkTagSet.c, generic/ttk/ttkLayout.c,
	* generic/ttk/ttkTheme.c, generic/ttk/ttkTheme.h,
	* generic/ttk/ttkThemeInt.h, generic/ttk/ttkWidget.h:
	Added [$tv identify region], [$tv identify element], and [$tv identify
	item] subcommands. Simplified bindings. Added [$tv tag has]
	subcommand. Tag-related display improvements; setting a tag
	-background or -foreground no longer overrides selection feedback.

	* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl,
	* library/ttk/clamTheme.tcl, library/ttk/classicTheme.tcl,
	* library/ttk/defaults.tcl, library/ttk/treeview.tcl,
	* library/ttk/winTheme.tcl, library/ttk/xpTheme.tcl:
	Don't need separate 'Item', 'Cell', and 'Row' style settings anymore,
	only the base "Treeview" style is used.

2008-05-23  Joe English  <[email protected]>

	* generic/ttk/ttkLabel.c: [Bug 1967576]: Avoid passing width or height
	<= 0 to Tk_RedrawImage, as this leads to a panic on Windows.

2008-05-16  Pat Thoyts  <[email protected]>

	* library/ttk/xpTheme.tcl: Add correct border to combobox on Vista

2008-05-15  Pat Thoyts  <[email protected]>

	* win/makefile.vc: We should use the thread allocator for threaded
	* win/rules.vc: builds. Added 'tclalloc' option to disable.

2008-05-14  Donal K. Fellows  <[email protected]>

	* generic/tkPanedWindow.c (PanedWindowProxyCommand)
	(DisplayPanedWindow): [Bug 1639824]: Ensure that a zero width never
	gets fed to the underlying window system.

2008-05-13  Pat Thoyts  <[email protected]>

	* library/console.tcl: Support pixel sized font in +/- keybinding.
	* tests/listbox.test: -activestyle default is underline on windows.
	* tests/winDialog.test: Fixed hanging tk_chooseColor tests.

2008-05-11  Pat Thoyts  <[email protected]>

	* library/tk.tcl: Support for ttk widgets in AmpWidget
	* doc/button.n: [Patch 1883418]: Note negative widths for button.

2008-05-09  Pat Thoyts  <[email protected]>

	* doc/ttk_*: 'identify' widget command is on all ttk widgets.

2008-05-04  Joe English  <[email protected]>

	* macosx/ttkMacOSAquaTheme.c: [Bug 1942785]: "default" and "focus"
	adornments should not be disjoint.

2008-04-27  Donal K. Fellows  <[email protected]>

	* */*.c: A large tranche of getting rid of pre-C89-isms; if your
	compiler doesn't support things like proper function declarations,
	'void' and 'const', borrow a proper one when building Tcl. (The header
	files allow building things that link against Tcl with really ancient
	compilers still; the requirement is just when building Tcl itself.)

2008-04-25  Joe English  <[email protected]>

	* library/ttk/treeview.tcl: [Bug 1951733]: [$tv selection] takes a
	list of items, not a single item.

2008-04-20  Pat Thoyts  <[email protected]>

	* win/makefile.vc: [Bug 1900872]: Include ws2_32 in the link list.
	* doc/menu.n: [Bug 1887169]: Minor change regarding the system menu.
	* doc/button.n: [Bug 1926223]: Minor clarification of button flash.

2008-04-17  Donal K. Fellows  <[email protected]>

	* doc/text.n: Correct description of when -relief option is ignored on
	a tag. Thanks to emiliano for spotting.

2008-04-17  Don Porter  <[email protected]>

	* generic/tkCanvas.c: [Bug 1327482]: Fix logic that determines when
	canvas item <Enter> event should fire. Thanks to Sebastian Wangnick.

2008-04-16  Daniel Steffen  <[email protected]>

	* generic/tkStubInit.c:			[Patch 1938497]: Make stubs
	* generic/tkWindow.c (Initialize):	tables static const and export
	only a module-scope pointer to to the main stubs table (for package
	init).

2008-04-14  Pat Thoyts  <[email protected]>

	* win/tkWinDialog.c:	[Bug 1941740]: Fix [tk_chooseColor -title].
	* win/tkWinTest.c:	Added parent to testgetwininfo
	* tests/winDialog.test:	Created some tk_chooseColor win tests.

2008-04-09  Jan Nijtmans  <[email protected]>

	* generic/tkImgGIF.c:	Let the GIF writer use a real LZW compressor.

2008-04-08  Pat Thoyts  <[email protected]>

	* win/ttkWinXpTheme.c:	Provide a visual-styles API element engine
	* tests/ttk/vsapi.test: to permit scripts to create any available
	* doc/ttk_vsapi.n:    windows xp/vista element. Plus basic tests.

2008-04-08  Daniel Steffen  <[email protected]>

	* generic/tkDecls.h:		make genstubs (genStubs.tcl changes).
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:

2008-04-08  Kevin Kenny  <[email protected]>

	* tkWinEmbed.c:	 Removed #if 0 code. Trust the revision control
	system, if you need it again, you can find it.

	* tkWinSend.c:	 Added conditional compilation to silence several
	compiler warnings.

2008-04-07  Jeff Hobbs  <[email protected]>

	* generic/tkWindow.c (Initialize): [Bug 1937135]: Fix double-free on
	* tests/main.test (main-3.*):	   Tk_ParseArgv error.

	* generic/tkArgv.c: Fix -help mem explosion. [Bug 1936238] (kenny)

2008-04-04  Pat Thoyts  <[email protected]>

	* library/ttk/sizegrip.tcl: Don't resize if the toplevel is not
	resizable or the sizegrip has been disabled.

2008-04-03  Pat Thoyts  <[email protected]>

	* win/makefile.vc:    Fixed stubs usage
	* library/ttk/xpTheme.tcl: fix the colour of labelframe in xp

2008-04-02  Daniel Steffen  <[email protected]>

	* generic/tk.decls:	Remove 'export' declarations of symbols now
				only in libtkstub and no longer in libtk.

	* generic/tkStubLib.c:	[Bug 1819422]: Make symbols in libtkstub.a
				MODULE_SCOPE to avoid exporting them from
				libraries that link with -ltkstub; constify
				tk*StubsPtr and stub table hook pointers.

	* generic/tkStubLib.c:	    Undef USE_TCL_STUBS before defining it
	* generic/ttk/ttkStubLib.c: unconditionally; remove needless #ifdef

	* generic/tkDecls.h:		make genstubs
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c:

	* unix/configure.in (Darwin):	Remove now unnecessary unexporting of
					libtclstub symbols from libtk.

	* unix/configure:		autoconf-2.59

2008-04-01  Don Porter  <[email protected]>

	* generic/tkStubLib.c (Tk_InitStubs):		Added missing error
	* generic/tkWindow.c (Tk_PkgInitStubsCheck):	message and removed
	needless #ifdef complexity.

	* generic/tkWindow.c:	[Tcl Bug 1819422]: Revised package init so
	* unix/Makefile.in:	that "tkStubsPtr" is not present in libtk.so,
	* win/Makefile.in:	but is present only in libtkstub.a. This
	* win/makefile.bc:	tightens up the rules for users of the stubs
	* win/makefile.vc:	interfaces.

	* README:		Bump version number to 8.6a0
	* generic/tk.h:
	* library/tk.tcl:
	* macosx/Wish-Common.xcconfig:
	* unix/configure.in:
	* unix/tk.spec:
	* win/README:
	* win/configure.in:
	* win/tcl.m4:

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

	* generic/tkConsole.c:	Relax Tcl_InitStubs() calls so that a Tk 8.6
	* generic/tkMain.c:	might [load] into a Tcl 8.5 interp.
	* generic/tkWindow.c:

	* generic/tkDecls.h:		make genstubs
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:

2008-03-28  Don Porter  <[email protected]>

	*** 8.5.2 TAGGED FOR RELEASE ***

	* README:		Bump to 8.5.2 for release.
	* generic/tk.h:
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

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

	* changes:	Updates for 8.5.2 release.

2008-03-27  Jeff Hobbs  <[email protected]>

	* library/safetk.tcl (::safe::tkInterpInit): Make sure tk_library and
	its subdirs (eg, ttk) are on the "safe" access path.

2008-03-27  Daniel Steffen  <[email protected]>

	* unix/tcl.m4 (SunOS-5.1x): [Bug 1921166]: Fix 64bit support for Sun
	cc.

	* unix/configure: autoconf-2.59

2008-03-27  Daniel Steffen  <[email protected]>

	* generic/ttk/ttkStubLib.c:	Ensure tcl stubs are used in libtkstub
					even in a static build of Tk.
	* generic/ttk/ttkDecls.h:	Fix incorrect number of arguments in
					Ttk_InitStubs macro definition.

2008-03-26  Don Porter  <[email protected]>

	* changes:	Updates for 8.5.2 release.

	* unix/tkUnixCursor.c:	[Bug 1922466]: Stop crash in [. configure
	-cursor] on X11. Thanks to Emiliano Gavilán.

2008-03-26  Joe English  <[email protected]>

	* generic/tkInt.h, generic/tkEvent.c, unix/tkUnixEvent.c,
	* unix/tkUnixKey.c: XIM reorganization and cleanup; see
	[Patch 1919791] for details.

2008-03-21  Joe English  <[email protected]>

	* generic/tk.decls, generic/ttk/ttkStubLib.c, unix/Makefile.in:
	[Bug 1920030]: Keep ttkStubLib.o in libtkstub instead of libtk.

2008-03-20  Donal K. Fellows  <[email protected]>

	* tests/wm.test: Rewrote so that tests clean up after themselves
	rather than leaving that to the following test. Makes it easier to
	catch problems where they originate. Inspired by [Bug 1852338]

2008-03-19  Donal K. Fellows  <[email protected]>

	* doc/GetClrmap.3: [Bug 220809]: Documented Tk_PreserveColormap.

2008-03-17  Joe English  <[email protected]>

	* unix/Makefile.in, win/Makefile.in, win/makefile.vc: [Bug 1863007]:
	Put ttkStubLib.o in libtkstub instead of libtk.

2008-03-16  Donal K. Fellows  <[email protected]>

	* library/demos/goldberg.tcl: [Bug 1899664]: Made work when run twice
	in the same session. Also made the control panel use Ttk widgets.

2008-03-13  Daniel Steffen  <[email protected]>

	* unix/configure.in: [Bug 1913622]: Use backslash-quoting instead of
	* unix/tcl.m4:	     double-quoting for lib paths in tkConfig.sh.
	* unix/configure:    autoconf-2.59

2008-03-13  Don Porter  <[email protected]>

	* changes:	Updates for 8.5.2 release.

2008-03-12  Daniel Steffen  <[email protected]>

	* macosx/Wish.xcodeproj/project.pbxproj: Add support for Xcode 3.1
	* macosx/Wish.xcodeproj/default.pbxuser: CODE_SIGN_IDENTITY and
	* macosx/Wish-Common.xcconfig:		 'xcodebuild install'.

2008-03-12  Joe English  <[email protected]>

	* unix/tkUnixRFont.c: Try a fallback font if XftFontOpenPattern()
	fails in GetFont (workaround for [Bug 1090382]).

2008-03-11  Daniel Steffen  <[email protected]>

	* library/demos/knightstour.tcl:	Aqua GOOBE.
	* library/demos/widget:

	* macosx/Wish.xcodeproj/project.pbxproj: Add support for Xcode 3.1 and
	* macosx/Wish.xcodeproj/default.pbxuser: configs for building with
	* macosx/Wish-Common.xcconfig:		 gcc-4.2 and llvm-gcc-4.2.

	* generic/tkCanvUtil.c:			Fix gcc-4.2 warnings.

	* macosx/GNUmakefile:			Fix quoting to allow paths to
	* macosx/Wish-Common.xcconfig:		${builddir}, ${INSTALL_ROOT}
	* unix/Makefile.in:			and ${TCL_BIN_DIR} to contain
	* unix/configure.in:			spaces.
	* unix/install-sh:
	* unix/tcl.m4:

	* unix/configure:			autoconf-2.59

	* unix/Makefile.in (install-strip):	Strip non-global symbols from
						dynamic library.

2008-03-10  Don Porter  <[email protected]>

	* changes:	Updates for 8.5.2 release.

2008-03-07  Donal K. Fellows  <[email protected]>

	* doc/colors.n: Reworked to produce nicer HTML output.

2008-03-06  Joe English  <[email protected]>

	* doc/ttk_notebook.n: [Bug 1882011]: Move "TAB IDENTIFIERS" section
	above "WIDGET COMMAND" section.

2008-02-29  Pat Thoyts  <[email protected]>

	* library/demos/widget:	 Added a Knight's tour canvas demo.
	* library/demos/knightstour.tcl:

2008-02-27  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDraw.c: Workaround leak in Carbon SetPortPenPixPat()
	API [Bug 1863346]; avoid repeated PixPat allocation/deallocation.

2008-02-23  Joe English  <[email protected]>

	* library/ttk/combobox.tcl, doc/ttk_combobox.n,
	* tests/ttk/combobox.test: Arrange to deliver <<ComboboxSelected>>
	event after listbox is unposted, as intended [Bug 1890211]. Clarified
	documentation.

2008-02-23  Joe English  <[email protected]>

	* generic/ttk/ttkPanedWindow.c: [FRQ 1898288]: Don't enforce minimum
	sash thickness of 5 pixels, just use 5 as a default.

2008-02-14  Donal K. Fellows  <[email protected]>

	* unix/README: Documented missing configure flags.

2008-02-06  Donal K. Fellows  <[email protected]>

	* doc/ttk_scale.n (new file): [Bug 1881925]: Added basic documentation

2008-02-04  Don Porter  <[email protected]>

	*** 8.5.1 TAGGED FOR RELEASE ***

	* generic/tk.h:		Bump to 8.5.1 for release.
	* library/tk.tcl:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

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

2008-02-04  Donal K. Fellows  <[email protected]>

	* doc/MeasureChar.3, doc/FontId.3: Minor improvements (formatting,
	keywords).

2008-02-02  Daniel Steffen  <[email protected]>

	* macosx/Wish-Info.plist.in:	Add CFBundleLocalizations key, listing
	* unix/configure.in (Darwin):	all library/msgs locales.

	* unix/configure.in (Darwin):	Correct Info.plist year substitution
					in non-framework builds.

	* unix/configure:		autoconf-2.59

2008-02-01  Don Porter  <[email protected]>

	* changes:	Updates for 8.5.1 release.

2008-02-01  Reinhard Max  <[email protected]>

	* generic/tkImgGIF.c: Fixed a buffer overflow (CVE-2008-0553).
	* tests/imgPhoto.test: Added a test for the above.

2008-01-31  Jeff Hobbs  <[email protected]>

	* library/msgbox.tcl (::tk::MessageBox): Don't use ttk::label in low
	depth/aqua fallback, as it doesn't support -bitmap.

	* win/tkWinDialog.c (Tk_MessageBoxObjCmd): [Bug 1881892]: Pass ""
	instead of NULL when -title isn't set.

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

	* doc/panedwindow.n: Added proper description of -height and -width
	options, which aren't "standard". Last of fallout from [Bug 1882495].

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

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

	* unix/tkUnixRFont.c: Re-fix strict-aliasing warnings reintroduced by
	last patch.

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

	* generic/ttk/ttkNotebook.c: [Bug 1878298]: Make sure to schedule a
	redisplay when adding and/or hiding tabs.

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

	* unix/tkUnixRFont.c: Merged common code from InitFont() and
	TkpGetFontAttrsForChar(), factored into GetTkFontAttributes() and
	GetTkFontMetrics(). Removed write-only struct UnixFtFont member
	'drawable'. Removed unneeded double-pointer indirections. Ensure that
	TkFontAttributes.family member is a Tk_Uid, as specified. Use
	FcTypeDouble for XFT_SIZE attribute. Finally: fix [Bug 1835848]

2008-01-25  Don Porter  <[email protected]>

	* changes:	Updates for 8.5.1 release.

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

	* generic/ttk/ttkFrame.c: [Bug 1867122]: fix crash in
	[ttk::labelframe] when -style option specified.

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

	* win/ttkWinTheme.c: [Bug 1865898]: Add tristate support to
	checkbuttons and radiobuttons.
	[Bug 1679067]: Fix check and radio indicator size.

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

	* generic/ttk/ttkWidget.c, generic/ttk/ttkWidget.h: Call
	Tk_MakeWindowExist() in widget constructor. Removed now-unnecessary
	initial ConfigureNotify processing.

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

	* library/ttk/treeview.tcl, library/ttk/utils.tcl:
	[Bugs 1442006, 1821939, 1862692]: Fix MouseWheel bindings for
	ttk::treeview widget.

2008-01-02  Don Porter  <[email protected]>

	* generic/tk.h:		Bump version number to 8.5.1b1 to distinguish
	* library/tk.tcl:	CVS development snapshots from the 8.5.0 and
	* unix/configure.in:	8.5.1 releases.
	* unix/tk.spec:
	* win/configure.in:

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

	******************************************************************
	*** CHANGELOG ENTRIES FOR 2005 TO 2007 IN "ChangeLog.2007"     ***
	*** CHANGELOG ENTRIES FOR 2004 AND 2003 IN "ChangeLog.2004"    ***
	*** CHANGELOG ENTRIES FOR 2002 AND EARLIER IN "ChangeLog.2002" ***
	******************************************************************
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted ChangeLog.2002.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
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
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
2002-12-27  David Gravereaux <[email protected]>

	* generic/tkText.h: ANSI unfriendly typedef for TkTextBTree
	repaired for C++ compilers.

2002-12-27  Joe English  <[email protected]>

	* unix/tkUnixWm.c (WaitForEvent): process Map and Unmap events
	as well as Configure events during WaitFor{Configure|Map}Notify.
	Fixes [Bug 578569] (WaitForMapNotify could process Map and Unmap
	events out of order, making Tk think a window was unmapped when
	it really wasn't).

2002-12-18  Todd M. Helfter  <[email protected]>

	* doc/label.n: Fixed documentation of the -compound option to
	the label widget.  The option was simply missing from the
	man page [Bug 577540]

2002-12-17  Donal K. Fellows  <[email protected]>

	* doc/photo.n: Fixed documentation of the put subcommand to no
	longer talk about files and to mention that you can use colour
	names for working with solid colours.  [Bug 640026]

2002-12-13  Don Porter <[email protected]>

	* generic/tkMain.c (Tk_Main):  Call on Tcl*StartupScript*() routines
	to store the startup script, if any.  [Bug 616245].

2002-12-10  David Gravereaux  <[email protected]>

	* win/makefile.vc: tclThreadTest.obj not required to link
	tktest.exe [Bug 651396]

2002-12-08  Jeff Hobbs  <[email protected]>

	* generic/tkEntry.c (ConfigureEntry): keep a flag to indicate when
	a var is traced to prevent double-traces caused by configuring the
	widget in traces with validation on. (dejong)

2002-12-07  Jeff Hobbs  <[email protected]>

	* generic/tkInt.decls: add TkWinSetHINSTANCE decl
	* generic/tkIntPlatDecls.h: regen
	* generic/tkStubInit.c: regen
	* win/tkWinInit.c (TkpInit):  While init and cleanup aren't correct
	* win/tkWinX.c (TkWinXInit):  in DllMain, we had to specify the
	* win/tkWin32Dll.c (DllMain): true HINSTANCE or the resources of a
	dynamic Tk weren't being loaded correctly.  Created a new function
	TkWinSetHINSTANCE for this purpose.

2002-12-06  Jeff Hobbs  <[email protected]>

	* win/tkWinX.c (TkWinXInit):      Move cleanup into an exit handler
	* win/tkWin32Dll.c (DllMain):     to ensure that it will be called
	* win/tkWinWm.c (TkWinWmCleanup): without having to unload the dll.
	Also reset the static int initialized on cleanup to allow reinit.

2002-12-01  Mo DeJong  <[email protected]>

	* tests/event.test (_keypress, _text_ind_to_x_y): Force focus to
	widget in _keypress method to avoid problems with window managers
	that use focus follows mouse. [Bug 526209]

2002-12-01  Mo DeJong  <[email protected]>

	* tests/wm.test: Add wm-transient-6.3 to check that a transient
	remains withdrawn when it is first withdrawn and then turned into
	a transient.
	* unix/tkUnixWm.c:
	* win/tkWinWm.c: Replace WM_TRANSIENT_WITHDRAWN with WM_WITHDRAWN
	and set this flag whenever a window is explicitly withdrawn. This
	fixes the test case added above. [Bug 644356]

2002-11-22  Jeff Hobbs  <[email protected]>

	* tests/textDisp.test:
	* generic/tkTextDisp.c (TkTextSeeCmd): handle see for unmapped
	text displays. [Bug #641778]

2002-11-19  Jim Ingham <[email protected]>

	* macosx/tkMacOSXScrlbr.c (TkpDisplayScrollbar): If the
	scrollbar width is set to 12 or less (but 12 is what you
	should use) use the small metric scrollbar.

	(UpdateControlValues): Fix thinko in setting off AUTO_ADJUST for
	the place geometry manager.

2002-11-19  Jeff Hobbs  <[email protected]>

	* unix/Makefile.in: add macosx/*.tcl (buildTkConfig.tcl in
	particular) to the dist target.

2002-11-14  Mo DeJong  <[email protected]>

	* generic/tkWindow.c (Tk_DestroyWindow, DeleteWindowsExitProc):
	Add TkHalfdeadWindow type and halfdeadWindowList to keep track of
	windows that were only partially deallocated before a call to
	exit. Finish cleaning up these windows in DeleteWindowsExitProc.
	Keep track of cleanup status in Tk_DestroyWindow so that a window
	with a Destroy binding which calls exit will get fully destroyed.
	* tests/window.test: Add Tk_DestroyWindow tests for an assortment
	of half dead window cases. [Bug 630533]

2002-11-10  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: fixed erroneous
	removal of libtkstub before Wish was built.

2002-11-07  Mo DeJong  <[email protected]>

	* tests/unixWm.test: Add short delay to test unixWm-51.7
	to account for raise/lower changes in TIP 107. This allows
	the test case to pass under Window Maker on Linux.

2002-11-07  Peter Spjuth  <[email protected]>

	* tests/place.test:
	* generic/tkPlace.c: place info did not return all settings,
	and didn't make sure the result was a proper list.
	Put '-in' first in result to be more consistent with how
	grid/pack info behaves. [Bug #635025][Bug #532022]

2002-11-07  Daniel Steffen  <[email protected]>

	* unix/Makefile.in: added macosx/README to dist target.
	* macosx/Wish.pbproj/project.pbxproj: fix to 'wish' script
	to allow it to work when not installed into '/'.

2002-11-06  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.
	* win/configure: Regen.
	* win/configure.in: Check that AR, RANLIB, and RC
	are found on the path when building with gcc.

2002-11-04  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: added Wish linker flag
	-headerpad_max_install_names to allow use of 'install_name_tool'.
	fixed tkConfig.sh generation and redo_prebinding in the case where
	Tk is not installed alongside Tcl.

2002-11-03  David Gravereaux <[email protected]>

	* win/winMain.c (Tcl_AppInit): Calls Registry_Init() and
	Dde_Init() when STATIC_BUILD and TCL_USE_STATIC_PACKAGES macros
	are set.

	* win/makefile.vc:  linkexten option now sets the
	TCL_USE_STATIC_PACKAGES	macro which also adds the registry and
	dde static lib files to the link of the shell. [Patch 479697]

	* win/rules.vc: Matches the one from Tcl.

	* win/buildall.vc.bat: More useful commentary.

2002-11-01  Andreas Kupries  <[email protected]>

	* win/makefile.vc (TCLREGLIBNAME): Updated to registry 1.1.

2002-10-29  Daniel Steffen  <[email protected]>

	* macosx/README: added info on new package searching in
	Frameworks directories.

2002-10-22  Jeff Hobbs  <[email protected]>

	*** 8.4.1 TAGGED FOR RELEASE ***

	* changes: updated for 8.4.1 release

2002-10-21  Daniel Steffen  <[email protected]>

	* macosx/README: revised according to Jim's suggestions
	* macosx/tkMacOSXAppInit.c: use standard PATH_MAX from <limits.h>

2002-10-18  Jeff Hobbs  <[email protected]>

	* win/winMain.c (WinMain, main): remove obsolete SetMessageQueue call

	* win/configure: Regen.
	* win/tcl.m4 (SC_CONFIG_CFLAGS): Check for bug in Cygwin version
	of windres and work around that case by passing a POSIX path
	instead of a Windows native path. One can't always pass a POSIX
	path because the mingw native toolchain accepts only Windows
	native paths. (dejong)

	* win/tkWinPort.h: define OPEN_MAX only if not defined.
	[Patch #625472] (howell)

2002-10-18  Daniel Steffen  <[email protected]>

	* mac/tkMacAppInit.c: removed tcltest dependency.
	[Bug #592639] (porter)

2002-10-17  Jeff Hobbs  <[email protected]>

	* tests/imgPhoto.test:
	* generic/tkImgPhoto.c (ImgPhotoConfigureMaster): fix arg handling
	for missing -format or -data options. [Bug #624974]

	* tests/text.test:		      properly return the number of
	* unix/tkUnixFont.c (ControlUtfProc): bytes consumed. [Bug #624732]

2002-10-17  Daniel Steffen  <[email protected]>

	* macosx/README: info specific to building and running
	TclTk on Mac OS X, answers to tcl-mac list FAQs.
	* macosx/Makefile: permission fix after embedded install.
	* macosx/Wish.pbproj/project.pbxproj: after install, fix
	permissions of uninstalled products.

2002-10-17  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: added TEXT document
	type to plist so that files can be dragged onto Wish Shell.

	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXFont.c: added private proc
	TkMacOSXUseAntialiasedText() to enable/disable quickdraw
	text antialiasing where available, default is enabled.
	Added a linked boolean ::tk::mac::antialiasedtext with
	write trace to allow control of antialiasing from tcl.

2002-10-16  Vince Darley  <[email protected]>

	* macosx/tkMacOSXMenu.c: fix to accelerators shown in menus
	with non-alphanumeric keys.
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c: applied first patch from [Patch
	#622582] to fix some of [Bug #616988].  Further work is needed
	in this area, but this will let foreign keyboards at least work
	reasonably with Tk.

2002-10-15  Jeff Hobbs  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: add AIX-5 ppc build support. Remove unused
	SC_ENABLE_MEMDEBUG.

	* win/configure:
	* win/tcl.m4: Add --enable-shared=mem support.

2002-10-10  Peter Spjuth  <[email protected]>

	* tests/grid.test:
	* generic/tkGrid.c: The grid size was not updated properly
	when removing a widget from a grid. [Bug #621241] (forssen)

2002-10-10  Jeff Hobbs  <[email protected]>

	* tests/canvPs.test: tests for canvas embedded window ps generation
	* generic/tkCanvWind.c (CanvasPsWindow): removed dead code loop.
	* generic/tkCanvas.h: moved TkColormapData struct to tkCanvPs.c
	* generic/tkCanvPs.c (TkImageGetColor): corrected bogus use of
	TkColormapData on Windows (Windows now requires RGB pixel data
	from image).
	* win/tkWinImage.c (XGetImage, XGetImageZPixmap): added support
	for generating ps for embedded widgets on canvases on Windows,
	tested for 8, 16, 24 and 32-bit depths (XGetImageZPixmap not used).

	* library/tk.tcl: simplified the adding of extra <ISO_Left_Tab>
	and <hpBackTab> events to <<PrevWindow>>.

2002-10-09  Jeff Hobbs  <[email protected]>

	* unix/README: doc'ed --enable-symbols options.
	* unix/Makefile.in: comment docs
	* unix/configure: regen
	* unix/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
	SC_ENABLE_SYMBOLS that takes yes|no|mem|all as options now.

2002-10-09  Don Porter <[email protected]>

	* generic/tk.h:  Added reminder comment to edit
	macosx/Wish.pbproj/project.pbxproj when version number changes.

2002-10-09  Daniel Steffen  <[email protected]>

	* macosx/Makefile: don't remove tclsh after building embedded.

	* macosx/Wish.pbproj/project.pbxproj: bumped version to 8.4.1;
	added missing library/mkpsenc.tcl to framework.

2002-10-09  Daniel Steffen  <[email protected]>

	* generic/tkInt.decls(tkIntXlib): added XQueryTree declaration for
	mac & aqua, since it's now called from ParentXId via Tk_HandleEvent.
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c: regen.
	* mac/tkMacXStubs.c: added XQueryTree stub

	* mac/tkMacEmbed.c (TkpUseWindow): check that container window
	has -container option set (sync with other platforms).

	* mac/tkMacBitmap.c:
	* mac/tkMacFont.c:
	* mac/tkMacSend.c:
	* mac/tkMacTest.c:
	* mac/tkMacWm.c: CONSTification.

	* mac/tkMacProjects.sea.hqx: added tkStyle.c and tkUndo.c to
	tk library projects.

2002-10-09  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoSetSize): Only error-out if we
	fail to allocate a non-empty buffer; getting a NULL when we
	allocate an empty buffer is no problem since nothing will look at
	the value anyway. [Bug 619544]
	Also tidied up file to take into account the fact that we're using
	32 bits per pixel in the master to accommodate the alpha channel
	as well as RGB.

2002-10-08  Jeff Hobbs  <[email protected]>

	* tests/winButton.test: add option clear to top to prevent option
	leakage from other tests causing problems. [Bug #582382]

	* generic/tkPanedWindow.c (Tk_PanedWindowObjCmd): leave the
	DestroyPanedWindow proc to free the pwPtr, add a Preserve
	reference to the pwPtr->tkwin.
	(DestroyPanedWindow): Release the pwPtr->tkwin.

	* generic/tkFocus.c (TkFocusFilterEvent): Ignore event if we are
	focusing into a dead window. [Bug #588831] (griffin)

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

	* macosx/tkMacOSXScrlbr.c (TkpDisplayScrollbar): Put the Tk scrollbar
	pointer into the control reference data for the Mac scrollbar, so we
	can get it out again in the ScrollbarActionProc.

2002-10-02  Jeff Hobbs  <[email protected]>

	* generic/tkText.c (TextBlinkProc): don't blink the cursor unless
	it is visible. [Bug #616791] [Patch #614474] (bonfield)

	* tests/entry.test: added entry-20.7
	* generic/tkEntry.c (EntryTextVarProc): check if the entry is
	being deleted before handling an associated textvariable.
	[Bug #607390 #617446]

2002-10-01  Donal K. Fellows  <[email protected]>

	* tests/unixSelect.test (unixSelect-1.1[89]): Altered these tests
	to work around [Bug #616923]
	* unix/tkUnixSelect.c (SelRcvIncrProc,TkSelPropProc): It turns out
	a much simpler and more robust solution is possible if we leverage
	Tcl's encoding engine by using the same code path as for the
	normal string selection.  It might be a bit slower, but it should
	be a lot more correct.  [Bug #614650]

2002-09-30  Jeff Hobbs  <[email protected]>

	* tests/panedwindow.test: added panedwindow-28.[12]
	* generic/tkPanedWindow.c (PanedWindowCmdDeletedProc):
	(Tk_PanedWindowObjCmd): when destroying the panedwindow, destroy
	the proxy before the parent to avoid dependency conflicts.
	[Bug #616589]

2002-09-30  Donal K. Fellows  <[email protected]>

	* tests/unixSelect.test: Test for various things that can fail to
	work in 8.4.0...
	* unix/tkUnixSelect.c (TkSelPropProc,SelRcvIncrProc): Incremental
	transfers of UTF8_STRING selections should now work; Tk will now
	tag them with the right size and only transfer complete UTF8
	characters.  Previously, things only worked when the transfer
	could only happen in one go, and even then not always. [Bug 614650]

	* doc/bind.n: Doc-fix to mention that %A substitutes UNICODE
	characters rather than ASCII ones.  Tk's done this ever since 8.1
	in any case; after all, it is the right thing to do.

2002-09-27  Don Porter <[email protected]>

	* README:		Bumped to version 8.4.1 to avoid confusion
	* generic/tk.h:		of CVS snapshots with release 8.4.0.
	* unix/README:
	* unix/configure.in:
	* unix/tk.spec
	* win/configure.in:

	* unix/configure:	autoconf
	* win/configure:

2002-09-26  Jeff Hobbs  <[email protected]>

	* unix/configure: regen.
	* unix/tcl.m4: improve AIX-4/5 64bit compilation support.

	* unix/Makefile.in: add macosx subdir to dist target.
	Do not generate .Z, only .gz and .zip in alldist target.

2002-09-18  Mumit Khan  <[email protected]>

	Added basic Cygwin support.

	* win/tcl.m4 (SC_PATH_TCLCONFIG): Support one-tree build.
	(SC_PATH_TKCONFIG): Likewise.
	(SC_PROG_TCLSH): Likewise.
	(SC_CONFIG_CFLAGS): Assume real Cygwin port and remove -mno-cygwin
	flags.  Add -mwin32 to extra_cflags and extra_ldflags.
	Remove ``-e _WinMain@16'' from LDFLAGS_WINDOW.
	* win/configure: Regenerate.

	* win/tkWinPort.h (tchar.h): Do not include on Cygwin.
	(_T): Define for Cygwin.
	* win/winMain.c (main): Conditionally define.

2002-09-26  Daniel Steffen  <[email protected]>

	* macosx/Makefile: preserve environment value of INSTALL_ROOT.
	When embedding only use deployment build. Force relink before
	embedded build to ensure new linker flags are picked up.

	* macosx/buildTkConfig.tcl (new):
	* macosx/Wish.pbproj/project.pbxproj: synthesize tkConfig.sh
	based on tclConfig.sh in Tcl.framework and tkConfig.sh.in.
	Add symbolic links to debug lib, stub libs and tkConfig.sh
	in framework toplevel. Made tkIntXlibDecls.h a public header
	since Headers/X11/Xlib.h includes it. Install wish8.4 script
	that runs "Wish Shell.app" and corresponding wish link.
	Use tcl headers from built Tcl.framework instead of from tcl
	source directory.

	* macosx/tkMacOSXPort.h: added missing standard unix includes
	and defines, similarly to tkUnixPort.h.
	* macosx/tkMacOSXNotify.c: removed dependency on internal tcl
	header "tclPort.h"

	* unix/Makefile.in:
	* unix/install-sh: copied support for 'install-strip' target
	over from tcl/unix/{Makefile.in,install-sh}

2002-09-22  Jim Ingham <[email protected]>

	* macosx/tkMacOSXScrlbr.c (UpdateControlValue): HiliteControl
	doesn't give the proper "nothing to scroll" look on Mac OS X.
	You have to set the min value greater than the max value to
	get this.

2002-09-15  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.
	* unix/tkUnixEvent.c (TkpCloseDisplay): Use PEEK_XCLOSEIM
	to examine the input context queue before invoking
	XCloseIM. Generate an assert if there is an input
	context that has not been freed.
	[Patch 570902]

2002-09-13  Andreas Kupries  <[email protected]>

	* generic/tk.h: Moved RC_INVOKED down so that tcl.h is still
	included when running the resource compiler. <tcl.h> excludes the
	unnecessary parts on its own. This reenables the Windows build. It
	failed because the non-inclusion of tcl.h caused the resource
	compiler to miss some vital macro definitions (TCL_FINAL_RELEASE,
	STRINGIFY, ...).

2002-09-12  Daniel Steffen  <[email protected]>

	* generic/tk.h:
	* mac/tkMacApplication.r:
	* mac/tkMacLibrary.r:
	* mac/tkMacResource.r:
	* macosx/tkAboutDlg.r:
	* macosx/tkMacOSXApplication.r:
	* macosx/tkMacOSXLibrary.r:
	* macosx/tkMacOSXResource.r: unified use of the two equivalent
	resource compiler header inclusion defines RC_INVOKED and
	RESOURCE_INCLUDED, now use RC_INVOKED throughout.

	* macosx/tkMacOSXAppInit.c: improved detection of Wish startup
	by the finder (by checking if stdin is /dev/null), in which
	case we want to bring up the Tk console window.

	* macosx/tkMacOSXHLEvents.c: added 'rapp' apple event handler.

2002-09-12  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: reference & install
	tk/generic/prolog.ps instead of tk/library/prolog.ps.

2002-09-10  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: added backwards
	compatibility for OSX 10.1 ProjectBuilder 2.0.

2002-09-10  Daniel Steffen  <[email protected]>

	* unix/Makefile.in: added DYLIB_INSTALL_DIR variable for Darwin
	and set it to default value ${LIB_RUNTIME_DIR}
	* unix/tcl.m4 (Darwin): use DYLIB_INSTALL_DIR instead of
	LIB_RUNTIME_DIR in the -install_name argument to ld.
	* unix/configure: regen.

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Makefile: added support for building Tcl as an embedded
	framework, i.e. using an dyld install_name containing
	@executable_path/../Frameworks via the new DYLIB_INSTALL_DIR
	unix/Makefile variable.

2002-09-10  Jeff Hobbs  <[email protected]>

	*** 8.4.0 TAGGED FOR RELEASE ***

2002-09-09  Jeff Hobbs  <[email protected]>

	* macosx/tkMacOSXNotify.c (Tk_MacOSXSetupTkNotifier): corrected
	Mac Jaguar event loop issue.

	* library/tk.tcl: use command instead of control on Aqua bindings.
	Force dialogs to appear below fixed native Mac menubar.
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c: Keypress/release events for pure
	modifier keys were not being passed to Tk.
	Deadkey presses were inserting null characters into text windows.
	Now they do nothing. (Still not ideal, but better than before!)
	* macosx/tkMacOSXMenu.c: Allow more than 200 menus to exist -
	increased to 2000.
	* macosx/tkMacOSXMouseEvent.c: Bad interactions between floating
	windows and ordinary ones.  Ensure that local<->global coordinate
	transformations are wrt to the correct window.
	* macosx/tkMacOSXWm.c: Better error msg for 'wm attributes'.
	Remove crash in 'wm transient'.
	Add 'noActivates' and 'noUpdates' flags to unsupported command.
	[Patch #606658] (darley)

	* library/xmfbox.tcl (::tk::MotifFDialog_ActivateSEnt): corrected
	msgcat code with XPG specifier. [Patch #606719] (miller)

2002-09-06  Don Porter <[email protected]>

	* tests/unixWm.test (unixWm-50.3):  Constrained test that hangs
	on Windows.

2002-09-05  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: added overlooked missing
	TK_PATCH_LEVEL version bump to 8.4.0.

2002-09-04  Andreas Kupries  <[email protected]>

	* win/Makefile.in (install-libraries): Added code section to
	install the message catalogs. Copied same section from
	unix/Makefile.in and adapted it to the slightly different
	environment.

2002-09-03  Jeff Hobbs  <[email protected]>

	* library/button.tcl: further restrict buttons to not resetting
	the "original" relief if it has changed in the interim.  This
	prevents code that simulated overrelief buttons from not working
	in 8.4.  [Bug #604270]

2002-09-03  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: Bumped version number to
	8.4.0 and updated copyright info.

2002-09-03  Vince Darley  <[email protected]>

	* macosx/tkMacOSXWm.c: fix to 'wm attributes' error-handling bug.

2002-09-03  Don Porter <[email protected]>

	* changes: Updated for 8.4.0 release

2002-09-02  Jeff Hobbs  <[email protected]>

	* tests/cursor.test: reverted 2002-08-31 change for OS X to use
	'heart' cursor because 'arrow' on windows has a pre-skewed use
	count. [Bug #602667]

	* tests/button.test: added button-14.1
	* win/tkWinButton.c (TkpComputeButtonGeometry): correct Win button
	sizing to be equal for one-line buttons with -height of 0 or 1, as
	well as -height 0 buttons with empty text and no image, which
	should be the same as single-line text buttons. [Bug #565485]

	* library/button.tcl (::tk::ButtonLeave): correctly restore state
	of button to normal for unix bindings. [Bug #597920]

	* doc/tk.n: added tk windowingsystem docs.

	* tests/wm.test:
	* unix/tkUnixWm.c: remove possible 2-second delay in 'raise'.
	[Patch #601518] (english) TIP #107

	* unix/tcl.m4: add support for 64-bit builds on HP-11 with gcc.
	* unix/configure.in: make sure to substitute LD_LIBRARY_PATH_VAR.
	* unix/configure: regend

	* README:		Bumped version number to 8.4.0
	* generic/tk.h:
	* unix/configure:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure:
	* win/configure.in:

	* generic/tkCmds.c:
	* generic/tkWindow.c: made 'tk' available in safe interpreters,
	but only the caret and windowingsystem subcommands may be called.
	* tests/safe.test (safe-1.2): noted that tk is now available in
	safe interps, but not the appname/scaling subcommands.

	* tests/tk.test (tk-1.2): noted new tk windowingsystem subcommand

2002-08-31  Daniel Steffen  <[email protected]>

	* unix/tcl.m4: update from Tcl

	* unix/Makefile.in: import of TK_SHLIB_LD_EXTRAS for Tk library
	specific linker settings. Added use of new LD_LIBRARY_PATH_VAR.

	* unix/configure: regen

2002-08-31  Daniel Steffen  <[email protected]>

	*** macosx-8-4-branch merged into the mainline [tcl patch #602770] ***

	* generic/tk.decls:
	* generic/tkInt.decls: added new "aqua" specific entries to the
	stubs tables. Changed all "unix" entries to "x11" to allow us to
	distinguish and build both "aqua" on MacOSX and "x11" on MacOSX.

	* generic/tk.h: added a #ifnded RESOURCE_INCLUDED so that tk.h can
	be passed to the resource compiler.

	* generic/tkCmds.c (Tk_TkObjCmd): added [tk windowingsystem]
	subcommand: returns "x11" when running on X11, "win32" on Windows,
	"classic" on MacOS9 and "aqua" on MacOSX Aqua (i.e. Carbon)

	* generic/tkFont.c (TkFontGetFirstTextLayout): new private function
	returning the first chunk of a Tk_TextLayout, i.e. until the first
	font change on the first line (or the whole first line if there is
	no such font change).

	* generic/tkMain.c: made Tcl_ThreadDataKey static

	* library/demos/puzzle.tcl: fixed button metrics for aqua

	* tests/cursor.test: check for presence of arrow cursor instead of
	heart cursor

	* xlib/xcolors.c: changed xColors static initialization to more
	standard C

	* macosx/Wish.pbproj/jingham.pbxuser (new):
	* macosx/Wish.pbproj/project.pbxproj (new): project for Apple's
	ProjectBuilder IDE.

	* macosx/Makefile (new): simple makefile for building the project
	from the command line via the ProjectBuilder tool 'pbxbuild'.

	* macosx/tkMacOSXAppInit.c (new): macosx specific AppInit looking
	for a AppMain.tcl file in its bundled Resources/Scripts folder. If
	present, argv[1] is set to that file and the Scripts folder is
	added to the auto_path. This allows tk apps to embed scripts within
	their bundle directory structure.

	* macosx/tkMacOSXInit.c (new): macosx adapted version of
	tkUnixInit.c: we initialize & cache the Carbon native encoding
	(e.g. 'macRoman') and try to find the tk script library files
	inside Tk packaged as a framework.

	* macosx/tkMacOSXNotify.c (new): new macosx specific merged
	Carbon/select-based notifier.

	* macosx/tkMacOSXEvent.c (new):
	* macosx/tkMacOSXEvent.h (new):
	* macosx/tkMacOSXKeyEvent.c (new):
	* macosx/tkMacOSXMouseEvent.c (new):
	* macosx/tkMacOSXWindowEvent.c (new): new macosx specific event
	handling functionality.

	* macosx/tkMacOSX.h (new):
	* macosx/tkMacOSXBitmap.c (new):
	* macosx/tkMacOSXButton.c (new):
	* macosx/tkMacOSXClipboard.c (new):
	* macosx/tkMacOSXColor.c (new):
	* macosx/tkMacOSXConfig.c (new):
	* macosx/tkMacOSXCursor.c (new):
	* macosx/tkMacOSXDefault.h (new):
	* macosx/tkMacOSXDialog.c (new):
	* macosx/tkMacOSXDraw.c (new):
	* macosx/tkMacOSXEmbed.c (new):
	* macosx/tkMacOSXFont.c (new):
	* macosx/tkMacOSXHLEvents.c (new):
	* macosx/tkMacOSXInt.h (new):
	* macosx/tkMacOSXKeyboard.c (new):
	* macosx/tkMacOSXMenu.c (new):
	* macosx/tkMacOSXMenubutton.c (new):
	* macosx/tkMacOSXMenus.c (new):
	* macosx/tkMacOSXPort.h (new):
	* macosx/tkMacOSXRegion.c (new):
	* macosx/tkMacOSXScale.c (new):
	* macosx/tkMacOSXScrlbr.c (new):
	* macosx/tkMacOSXSubwindows.c (new):
	* macosx/tkMacOSXTest.c (new):
	* macosx/tkMacOSXUtil.c (new):
	* macosx/tkMacOSXUtil.h (new):
	* macosx/tkMacOSXWm.c (new):
	* macosx/tkMacOSXWm.h (new):
	* macosx/tkMacOSXXStubs.c (new): macosx ports of classic mac Tk
	implementation in tk/mac.

	* macosx/tkMacOSXSend.c (new): only send to local interp
	implemented currently.

	* macosx/tkMacOSXDebug.h (new):
	* macosx/tkMacOSXDebug.c (new): new macosx specific functions for
	debugging MacOS events, regions, etc.

	* macosx/tkAboutDlg.r (new):
	* macosx/tkMacOSXApplication.r (new):
	* macosx/tkMacOSXCursors.r (new):
	* macosx/tkMacOSXLibrary.r (new):
	* macosx/tkMacOSXMenu.r (new):
	* macosx/tkMacOSXResource.r (new):
	* macosx/tkMacOSXXCursors.r (new):
	* macosx/tclets.r (new): sources for Rez resource compiler.

	* macosx/Wish.icns (new): Wish application icon.

	* generic/tk.h:
	* generic/default.h:
	* generic/tkBind.c:
	* generic/tkCmds.c:
	* generic/tkGrab.c:
	* generic/tkPointer.c:
	* generic/tkPort.h:
	* generic/tkSelect.c:
	* generic/tkStubLib.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkWindow.c:
	* unix/tkUnix3d.c:
	* xlib/xgc.c:
	* xlib/X11/X.h:
	* xlib/X11/Xlib.h:
	* xlib/X11/Xutil.h: added #includes and #ifdefs for macosx

	* library/bgerror.tcl:
	* library/button.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/scrlbar.tcl:
	* library/spinbox.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/demos/menu.tcl:
	* library/demos/menubu.tcl:
	* library/demos/widget: check [tk windowingsystem] instead of
	and/or in addition to $tcl_platform(platform).

	* generic/tkInt.h:
	* mac/tkMacBitmap.c:
	* mac/tkMacWm.c: added missing CONSTification

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c: regen

2002-08-27  D. Richard Hipp <[email protected]>

	* doc/checkbutton.n:      [Bug 582457] Fix the -offrelief option so
	* doc/radiobutton.n:      that when -offrelief is flat and -relief is
	* mac/tkMacButton.c:      sunken and -overrelief is raised, buttons
	* unix/tkUnixButton.c:    work look toolbar buttons under Windows.
	* win/tkWinButton.c:      See also: TIP #82.

2002-08-26  Don Porter <[email protected]>

	* win/Makefile.in:	Removed dependence on the (parts of) the
	* win/winMain.c:	tcltest executable on Windows.  It was not
	used, and the dependency complicated the Makefile.  [Bug 592638].

2002-08-20  Don Porter <[email protected]>

	* README:		Bumped version number to 8.4b3 to distinguish
	* generic/tk.h:		HEAD from the 8.4b2 release.
	* unix/configure.in:
	* win/configure.in:
	* unix/tk.spec:

	* unix/configure:	autoconf
	* win/configure:

	* generic/tk.h:	Added compile-time check that the tcl.h header file
	#included by Tk 8.4 is one from Tcl 8.4.  This is needed to be sure
	that new #defines like CONST84 are available. [Bug 597432].

2002-08-16  Jeff Hobbs  <[email protected]>

	* unix/Makefile.in (install-binaries): simplified pkgIndex.tcl
	file created on installation.
	* win/Makefile.in (install-binaries): corrected and simplified
	creation of pkgIndex.tcl file on installation.

2002-08-14  Vince Darley  <[email protected]>

	* win/tkWinDialog.c:
	* win/makefile.vc: broken compilation and link from changes
	Hobbs-08-07 fixed.
	* win/tkWinTest.c: CONST problem resolved.

2002-08-13  Jeff Hobbs  <[email protected]>

	* library/button.tcl: change the bindings to use Priv($w,relief)
	instead of just Priv(relief).  This ensures that neighboring
	buttons don't confuse (over)relief settings.

2002-08-13  Reinhard Max  <[email protected]>

	* unix/tkUnixSend.c (Tk_SetAppName): Fixed a compiler warning.

2002-08-12  Donal K. Fellows  <[email protected]>

	* library/demos/image2.tcl: Tweaked the behaviour of the directory
	box on resize, as resizing of the overall window tends to be
	common given the sample images.

2002-08-08  Mo DeJong  <[email protected]>

	* unix/tkUnixWm.c (WmTransientCmd): Apply fix for
	wm transient assertion error that was applied
	to tkWinWm.c for Tk Bug #592201.

2002-08-08  Mo DeJong  <[email protected]>

	* tests/wm.test: Add deleteWindows at start of
	new transient tests so they do not fail if the
	toplevels already exist.
	* unix/tkUnixWm.c: Revert patch for Tk Bug #592201
	which incorrectly removed numTransients member.

2002-08-08  Joe English  <[email protected]>

	* unix/tkUnixWm.c:
	* win/tkWinWm.c:
	* tests/wm.test: Fix for Tk Bug #592201 "wm transient fails with
	two masters"; fixes panic after a transient window is reassigned
	to new master and either master is subsequently destroyed.

2002-08-08  Don Porter <[email protected]>

	* tests/unixWm.test:  Corrected packaging of unixWm-50.3 so that
	[setupbg] and [cleanupbg] always balance, no matter what tests
	are skipped.

2002-08-08  Reinhard Max  <[email protected]>

	* unix/Makefile.in: Fixed typos in DISTNAME, and ZIPNAME.

2002-08-08  Jeff Hobbs  <[email protected]>

	*** 8.4b2 TAGGED FOR RELEASE ***

	* generic/tkButton.c (TkButtonWorldChanged): added GCFont handling
	to the disabledGc of buttons when compound != none.  The drawing
	appears to be incorrect across platforms still.  [Bug #477740]

	* generic/tkImgGIF.c (FileReadGIF): fixed -from handling for gifs
	[Bug #467524] (obermeier)

2002-08-07  Jeff Hobbs  <[email protected]>

	* generic/tkCanvUtil.c (TkSmoothParseProc): recognize the built-in
	bezier method by name. [Bug #578654]
	* doc/canvas.n: update to note that -smooth really doesn't take
	or return just booleans.

	* win/tkWinMenu.c (TkpSetWindowMenuBar): fixed logic bug in when
	to idle call ReconfigureWindowsMenu.

	* doc/GetBitmap.3: removed doc refs to deprecated
	Tk_GetBitmapFromData. [Bug #590379]

	* generic/tkPanedWindow.c (Tk_PanedWindowObjCmd):
	* library/panedwindow.tcl: changed class from PanedWindow to
	Panedwindow to not conflict with existing bwidgets, but also to be
	more regular with other names used in the core.

	* tests/panedwindow.test: added -text foobar to some test buttons
	to enable correct testing of panedwindow across platforms.
	[Bug #582370]

	* win/tkWinDialog.c: enabled use of the updated native Windows
	directory browser (tk_chooseDirectory).  This does require
	shell32.dll v4.71 or greater. [Patch #468139]

	* win/configure:
	* win/tcl.m4: added shell32 to libs for updated native Windows
	tk_chooseDirectory dialog.

2002-08-06  Donal K. Fellows  <[email protected]>

	* generic/tkPanedWindow.c (RESIZE_PENDING): Separated out flag for
	indicating that a resize needs to be issued.
	(PanedWindowReqProc): Do the old behaviour when the panedwindow is
	not mapped; easiest way of making the test suite pass while still
	preserving improved behaviour in the face of children whose size
	is not known immediately.

2002-08-06  Don Porter <[email protected]>

	* tests/defs.tcl: removed file.  No longer needed now that Tk is
	using the tcltest package to do its testing.

2002-08-05  Don Porter <[email protected]>

	* win/tkWinFont.c:	Additional changes to fix CONST warnings on
	* win/tkWinWM.c:	Windows due to latest patch.  Tks Vince Darley.

	* doc/3DBorder.3:	Applied companion patch for Tcl Patch 585105,
	* doc/BindTable.3:	updating Tk to use Tcl 8.4's fully CONST-ified
	* doc/ConfigWidg.3:	interface, and fully CONSTifying Tk at the
	* doc/CrtImgType.3:	same time.
	* doc/CrtWindow.3:
	* doc/DeleteImg.3:	This patch includes purging Tk of its last
	* doc/FindPhoto.3:	direct access to interp->result.  [Bug 589853]
	* doc/GetAnchor.3:
	* doc/GetBitmap.3:	The substantial changes include copying
	* doc/GetCapStyl.3:	event sequence strings into Tcl_DStrings
	* doc/GetClrmap.3:	in tkBind.c, and copying [text] indices into
	* doc/GetColor.3:	Tcl_DStrings because parsing them involved
	* doc/GetCursor.3:	overwriting them.  If this causes performance
	* doc/GetFont.3:	trouble, that can be resolved by further
	* doc/GetImage.3:	converting them to Tcl_Obj's.
	* doc/GetJoinStl.3:
	* doc/GetJustify.3:	The #defines USE_NON_CONST and USE_COMPAT_CONST
	* doc/GetOption.3:	have the same effect for Tk as they do for Tcl.
	* doc/GetRelief.3:	(They actually change tcl.h)
	* doc/GetScroll.3:
	* doc/GetVisual.3:
	* doc/InternAtom.3:
	* doc/NameOfImg.3:
	* doc/SetAppName.3:
	* doc/WindowId.3:
	* generic/tk.decls:
	* generic/tk.h:
	* generic/tk3d.c:
	* generic/tkAtom.c:
	* generic/tkBind.c:
	* generic/tkBitmap.c:
	* generic/tkButton.c:
	* generic/tkCanvArc.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvPs.c:
	* generic/tkCanvText.c:
	* generic/tkCanvUtil.c:
	* generic/tkCanvWind.c:
	* generic/tkCanvas.c:
	* generic/tkCanvas.h:
	* generic/tkClipboard.c:
	* generic/tkCmds.c:
	* generic/tkColor.c:
	* generic/tkConfig.c:
	* generic/tkConsole.c:
	* generic/tkCursor.c:
	* generic/tkDecls.h:
	* generic/tkEntry.c:
	* generic/tkFont.c:
	* generic/tkFrame.c:
	* generic/tkGet.c:
	* generic/tkGrid.c:
	* generic/tkImage.c:
	* generic/tkImgBmap.c:
	* generic/tkImgPhoto.c:
	* generic/tkInt.decls:
	* generic/tkInt.h:
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkListbox.c:
	* generic/tkMenu.c:
	* generic/tkMenubutton.c:
	* generic/tkMessage.c:
	* generic/tkOldConfig.c:
	* generic/tkOption.c:
	* generic/tkRectOval.c:
	* generic/tkScale.c:
	* generic/tkScrollbar.c:
	* generic/tkSelect.c:
	* generic/tkStyle.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextIndex.c:
	* generic/tkTextMark.c:
	* generic/tkTextTag.c:
	* generic/tkTextWind.c:
	* generic/tkUtil.c:
	* generic/tkVisual.c:
	* generic/tkWindow.c:
	* mac/tkMacConfig.c:
	* mac/tkMacCursor.c:
	* mac/tkMacEmbed.c:
	* mac/tkMacSend.c:
	* unix/tkUnixConfig.c:
	* unix/tkUnixCursor.c:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixSelect.c:
	* unix/tkUnixSend.c:
	* unix/tkUnixWm.c:
	* win/tkWinConfig.c:
	* win/tkWinCursor.c:
	* win/tkWinEmbed.c:
	* win/tkWinMenu.c:
	* win/tkWinSend.c:

2002-08-02  Donal K. Fellows  <[email protected]>

	* generic/tkPanedWindow.c (DestroyPanedWindow): Idle calls need to
	be deleted on destruction of the window, or things can *really* go
	pear-shaped.

2002-07-31  Donal K. Fellows  <[email protected]>

	* generic/tkPanedWindow.c (PanedWindowReqProc): Postpone pane
	arrangement until idle, as is done in other window managers, to
	fix problems with size calculations when the children don't
	already know their sizes anyway.

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2002-07-29  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Remove code that was setting
	CC_SEARCH_FLAGS and LD_SEARCH_FLAGS to try to
	account for cc vs ld linking. Tcl now handles this.
	* unix/tcl.m4: Update from Tcl.

2002-07-27  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Add MAJOR_VERSION, MINOR_VERSION,
	PATCH_LEVEL, INSTALL_LIBRARY, STUB_LIB_FILE, and LIB_FILE
	to support changes in tcl.m4 related to library builds.
	Use MAKE_LIB macro to avoid dealing with RANLIB issues.
	Rename TK_CC_SEARCH_FLAGS to CC_SEARCH_FLAGS and
	rename TK_LD_SEARCH_FLAGS to LD_SEARCH_FLAGS.
	Use new INSTALL_LIB and INSTALL_STUB_LIB substs to
	deal with ranlib issues when install libraries.
	* unix/configure: Regen.
	* unix/configure.in: Remove AC_PROG_RANLIB since
	this is done by tcl.m4 now. Define CC_SEARCH_FLAGS
	instead of TK_CC_SEARCH_FLAGS and so on.
	Use MAKE_LIB and MAKE_STUB_LIB from tcl.m4.
	Remove AC_SUBST calls that are no done in tcl.m4.
	* unix/tcl.m4: Update from Tcl.
	* unix/tkConfig.sh.in: Subst CC_SEARCH_FLAGS and
	LD_SEARCH_FLAGS.

2002-07-25  Peter Spjuth  <[email protected]>

	* generic/tkInt.h:
	* generic/tkWindow.c:
	* mac/tkMacWm.c:
	* unix/tkUnixWm.c:
	* win/tkWinWm.c:
	* tests/wm.test:
	* tests/winWm.test:
	* tests/unixWm.test: Objectifed wm. [Patch #564521]
	Note: At this point the Mac file is completely untested
	and may not even compile.

2002-07-25  Jeff Hobbs  <[email protected]>

	* tests/spinbox.test: added spinbox-22.[1-3]
	* generic/tkEntry.c (ConfigureEntry): made the textvariable value
	take precedence over changed -from/-to values, unless it must be
	constrained.  [Bug #559078]

	* library/spinbox.tcl (MouseSelect): when not in the entry, just
	return instead of invoking - ButtonUp handles invoking already.
	[Bug #499168]

	* library/tk.tcl (RestoreFocusGrab): handle the case where the
	FocusGrab info is not set. [Bug #553283]

2002-07-24  Jeff Hobbs  <[email protected]>

	* tests/canvas.test: added canvas-14.[1-6]
	* generic/tkCanvas.c (CanvasWidgetCmd): corrected handling of
	'scan' subcommand args.  Also removed early return cases to goto
	done instead where the canvasPtr would be Tcl_Release'd.  This may
	solve other problems with unreleased canvasPtr's. [Bug #581560]

	* win/tkWinButton.c (TkpDisplayButton): corrected display of focus
	ring around the actual text when the button is a compound button.
	[Bug #583691]

	* unix/README: Corrected notes about running user interactive Tk
	tests. [Bug #462320]

	* generic/tkText.c (TextEditUndo): set isDirtyIncrement to -1 when
	reverting to note proper "dirtiness". [Bug #580362] (callewaert)

	* generic/tkEntry.c (DisplayEntry): correct cursor position before
	calling Tk_SetCaretPos. (yamamoto)

2002-07-23  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2002-07-22  Mo DeJong  <[email protected]>

	* library/choosedir.tcl (tk::dialog::file::chooseDir):
	* library/clrpick.tcl (tk::dialog::file::chooseDir):
	* library/msgbox.tcl (tk::MessageBox):
	* library/tkfbox.tcl (tk::dialog::file):
	* library/xmfbox.tcl (tk::MotifFDialog):
	Revert [Tk patch 568278]. The transient window workaround
	is no longer needed since the fix for [Tk bug 570764]
	solved the problem for withdrawn transients.

2002-07-19  Mo DeJong  <[email protected]>

	* unix/configure:
	* unix/configure.in:
	* win/configure:
	* win/configure.in: Add AC_PREREQ(2.13) in an attempt
	to make it more clear that the configure scripts
	must be generated with autoconf version 2.13.
	[Tcl Bug 583573]

2002-07-19  D. Richard Hipp  <[email protected]>

	* library/mkpsec.tcl: Fix a bug that was causing postscript generation
	to fail under Win2K.

2002-07-18  Reinhard Max  <[email protected]>

	* unix/tkUnixSend.c: Using Tcl_GetTime instead of TclpGetTime.

2002-07-17  Reinhard Max  <[email protected]>

	* library/unsupported.tcl: Extended ExposePrivateVariable, and
	ExposePrivateCommand to accept patterns as well.

2002-07-17  Don Porter <[email protected]>

	* generic/tkFont.c: Corrected reversed logic in assert -> panic
	conversion.  [Bug 582799]

2002-07-16  Mo DeJong  <[email protected]>

	* generic/tkFont.c (TkFontPkgFree): Call panic instead
	of assert since assert is not used in the rest of Tk.
	[Tk bug 579651]

2002-07-16  Mo DeJong  <[email protected]>

	* unix/Makefile.in:
	* win/Makefile.in: Add a more descriptive warning
	in the event `make genstubs` needs to be rerun.

2002-07-16  Vince Darley  <[email protected]>

	* win/tkWinWm.c:
	* doc/wm.n: fix for part of [Bug 581627], and made iconbitmap
	code on Windows more flexible about reading in icons [Bug
	220800].

2002-07-15  David Gravereaux <[email protected]>

	* win/makefile.bc (new): re-add of the borland makefile.  Submitted
	by Helmut Giese <[email protected]>.  This needs testing, still.

2002-07-15  Don Porter <[email protected]>

	* Fixes for [Bug 581627, 581795].
	* generic/tkTest.c:		Test commands not supported on non-Unix
	platforms should not be defined there in the first place.
	* tests/constraints.tcl:	Fixed "secureserver" constraint.
	* tests/unixWm.test:		Some tests needed "unix" constraint.
	* win/tkWinWm.c:		Typo in error message.

2002-07-14  Don Porter <[email protected]>

	* tests/event.test:	Fixes to enable testing of only userInteraction
	* tests/visual_bb.test:	tests.

	* README:		Bumped HEAD to version 8.4b2 in order to
	* generic/tk.h:		distinguish it from the 8.4b1 release.
	* unix/configure*:	Also extended LOCALES to cover all message
	* unix/tk.spec:		catalogs.
	* win/configure*:

	* tests/focustTcl.test:	Conversion bug: Corrected backwards logic.
	* tests/imgPhoto.test:	Conversion bug: overwrote unix/README.

	* tests/all.tcl:		Completed conversion of Tk test suite
	* tests/constraints.tcl:	to use tcltest.
	* tests/[b-v]*.test:
	* unix/Makefile.in:

2002-07-12  Don Porter <[email protected]>

	* tests/constraints.tcl:	Converted more files to tcltest and
	* tests/[g-x]*.test:		factored out common code.

2002-07-11  Don Porter <[email protected]>

	* tests/canvPsImg.tcl:			Converted several files in the
	* tests/constraints.tcl (new file):	Tk test suite for testing by
	* tests/[r-x]*.test:			tcltest 2.1.
	* unix/Makefile.in:

2002-07-11  Jeff Hobbs  <[email protected]>

	* win/tkWinDialog.c (Tk_ChooseDirectoryObjCmd): initialize
	utfTitle to NULL, add a few more notes about limitations of
	possible new Tk_ChooseDirectoryObjCmd function.

2002-07-11  Donal K. Fellows  <[email protected]>

	* tests/imgPhoto.test (imgPhoto-15.1): Added test of mem-alloc
	failure, but this is non-portable.
	* generic/tkImgPhoto.c (ImgPhotoSetSize): Allowed this function to
	fail when it can't allocate enough memory.  Note that not all the
	places that call it can fail nicely without API changes; some
	still panic but at least some of the potential failures are now
	handled gracefully.

	* tests/visual_bb.test (lpr): Stopped this from relying on
	external files; direct piping is much more flexible for this
	application.

2002-07-09  Don Porter <[email protected]>

	* generic/tkTest.c:	Removed unused dependence on TclThread_Init()
	* tests/defs.tcl:	and [testthread].  [Bug 578165, Tcl Bug 531413]

2002-07-08  David Gravereaux <[email protected]>

	* unix/Makefile.in: Added missing win/lamp.bmp to the dist
	target.

2002-07-05  Jeff Hobbs  <[email protected]>

	*** 8.4b1 TAGGED FOR RELEASE ***

2002-07-04  Donal K. Fellows  <[email protected]>

	* library/bgerror.tcl (bgerror): Stopped the bgerror dialog from
	getting wider than the screen; in theory really long messages
	could make it become taller than the screen now, but that's much
	less likely to happen.  Also trimmed a little bit of internal
	space so that the icon-message gap is the same as the icon-frame
	and message-frame gaps.

2002-07-01  Don Porter <[email protected]>

	* unix/configure:
	* unix/tcl.m4: Updated to latest tcl.m4 from Tcl.

2002-06-28  Donal K. Fellows  <[email protected]>

	* library/msgbox.tcl (MessageBox): Force all non-button widgets to
	have the same background as the containing toplevel.  [Bug #552515]

2002-06-27  Andreas Kupries  <[email protected]>

	* win/Makefile.in (install-binaries): Fix of troubled Makefile
	quoting introduced by [Patch 521356] causing the installed to
	fail.

2002-06-25  Don Porter <[email protected]>

	* unix/tkUnixFont.c: (Tk_DrawChars) silence compiler warning.

2002-06-26  David Gravereaux <[email protected]>

	* generic/tkStyle.c: <eol> of the committing cvs client didn't
	match the <eol> of the file itself.  Windows users where getting
	\r\r\n.  Problem fixed.

2002-06-26  Anton Kovalenko <[email protected]>

	* generic/tkFont.c (TkTextLayoutToPostscript): fixed potential
	buffer overflow which could be intentionally triggered from
	within safe interpreter -- malicious applet could modify
	tk::psglyphs array.

2002-06-26  Anton Kovalenko <[email protected]>

	* tests/font.test (font-32.1): updated this test
	to expect the new behavior of canvas postscript.

2002-06-25  Don Porter <[email protected]>

	* unix/Makefile.in:	Expanded install-binaries target to create
	* win/Makefile.in:	and install a pkgIndex.tcl file to enable
	Tk as a loadable package [Patch 521356]

2002-06-25  Anton Kovalenko <[email protected]>

	* library/mkpsenc.tcl: (added) utilities to generate
	Postscript prolog for current system encoding.
	* generic/tkCanvPs.c (TkCanvPostscriptCmd): now
	uses mkpsenc.tcl to generate Postscript prolog.
	* generic/tkFont.c (TkTextLayoutToPostscript): modified
	according to patch #546910. Now outputs system-encoded
	characters (for unibyte) or Adobe glyph names (for
	multibyte or outside-locale).
	* tests/canvText.test (canvText-17.1): updated this test
	to expect the new behavior of canvas postscript.

2002-06-25  Reinhard Max  <[email protected]>

	* unix/tcl.m4:       New macro SC_CONFIG_MANPAGES.
	* unix/configure.in: Added support for symlinks and compression
	* unix/Makefile.in:  when installing the manpages. [Patch 518052]
	Default is still hardlinks and no compression.

	* unix/mkLinks:      generated
	* unix/configure:

	* unix/README:       Added documentation for the new features.

	* unix/configure:                  Replaced ${exec_prefix}/lib
	* unix/tcl.m4 (SC_PATH_TCLCONFIG): by ${libdir}.

2002-06-24  Mo DeJong  <[email protected]>

	* tests/winWm.test: Verify that both an unmapped
	and already mapped toplevel are raised and receive
	the focus when deiconified.
	* tests/wm.test: Add wm deiconify tests. Check that
	a toplevel that has never been mapped is not mapped
	by the deiconify command since it should be done
	at idle by MapFrame.
	* win/tkWinWm.c (Tk_WmCmd): Check the WM_NEVER_MAPPED
	flag while processing the wm deiconify command.
	The WM_UPDATE_PENDING flag should never be set when
	WM_NEVER_MAPPED is set, but double check so that
	the implementation is more explicit and matches
	the comment just above.
	Return without invoking TkWmRestackToplevel or
	TkSetFocusWin on a toplevel that has never been
	mapped. This fixes a bug where a toplevel is mapped
	with the wrong size and is then resized by the
	idle call to MapFrame. [Tk bug 233150]

2002-06-23  Jeff Hobbs  <[email protected]>

	* win/tkWinWm.c (UpdateGeometryInfo): remove the check for a null
	wrapper introduced in r1.41 on 2002-06-15 because it prevented
	geometry setting from taking effect if the window was not on the
	screen.  Another check may go in it's place as IsIconic and
	IsZoomed should not be passed NULL.

2002-06-22  Mo DeJong  <[email protected]>

	* tests/wm.test: Remove invalid minsize test. Add update
	calls to wm transient tests so that idle handlers get
	run. This is needed to get the tests to pass under Win32.
	* unix/tkUnixWm.c (WmWaitMapProc): Move the special
	transient withdrawn check into the if body to
	make it easier to set a breakpoint on this test
	inside a debugger. No functional changes.
	* win/tkWinWm.c (WmWaitVisibilityOrMapProc): Ditto.

2002-06-22  Jeff Hobbs  <[email protected]>

	* doc/wm.n:                   TIP #95 Windows implementation and
	* mac/tkMacWm.c (Tk_WmCmd):   docs with mac and unix stubs.
	* unix/tkUnixWm.c (Tk_WmCmd):
	* win/tkWinWm.c (Tk_WmCmd):
	* tests/unixWm.test:
	* tests/winWm.test: more wm attr tests will be needed.

	* generic/tkGrid.c (GridReqProc): check that gridPtr is not NULL
	(may be when embedded). [Bug #548791] (halliday)

	* generic/tkFont.c (TkFontPkgFree): changed panic on freeing fonts
	to an assert, and wrapped panic in #ifdef PURIFY. [Bug #568701]

	* library/menu.tcl: corrected menus from being posted offscreen
	on Windows. [Bug #464451] (darley)

	* library/console.tcl: corrected the defaultPrompt substitution
	[Bug #553207] and made Tab a default expansion key (like Escape).

	* win/tkWinEmbed.c (EmbedWindowDeleted): added a check for a null
	containerPtr.  The core of this bug is likely elsewhere. [Bug #476176]

	* doc/text.n:                             TIP #93 implementation that
	* generic/tkText.c (TextWidgetCmd):       enhances the text get and
	* generic/tkTextIndex.c (TkTextGetIndex): delete methods to accept
	* tests/text.test:                        multiple range pairs.
	This handles the delete case in an atomic, fixed-index fashion.

2002-06-21  Mo DeJong  <[email protected]>

	* tests/wm.test: Add tests to make sure a withdrawn
	transient does not get remapped by state changes
	in the master.
	* unix/tkUnixWm.c (Tk_WmCmd, WmWaitMapProc):
	* win/tkWinWm.c (Tk_WmCmd, WmWaitVisibilityOrMapProc):
	Add a WM_TRANSIENT_WITHDRAWN flag that gets set by the
	withdraw, deiconify, or state wm subcommands. Check
	this flag before mapping a transient when processing
	a MapNotify event. [Tk bug 570764]

2002-06-21  Donal K. Fellows  <[email protected]>

	* unix/tk.spec (version), README, win/configure.in, unix/configure.in:
	* generic/tk.h (TK_RELEASE_*, TK_PATCH_LEVEL): Bumped to beta1.

2002-06-21  Jeff Hobbs  <[email protected]>

	* doc/text.n:          TIP #104 implementation which generalizes the
	* generic/tkText.c:    undo/redo stack to not be tied solely to the
	* generic/tkText.h:    text widget.  The APIs are still private.
	* generic/tkUndo.c:    This also adds a stack limiting ability and
	* generic/tkUndo.h:    a -maxundo option to the text widget (in
	* library/text.tcl:    addition to the options from TIP #26) should
	* mac/tkMacDefault.h:  users want to limit the undo/redo stack
	* tests/text.test:     (should not be necessary in most cases).
	* unix/Makefile.in:    [Patch #554763] (callewart)
	* unix/tkUnixDefault.h:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/tkWinDefault.h:

2002-06-21  Don Porter <[email protected]>

	* unix/Makefile.in:	Removed unnecessary dependence of tktest
	* unix/tkAppInit.c:	executable on the tcltest executable on
	Unix.  If there are similar dependencies on other platforms, they
	can probably be removed as well.  [Bug 572134].

2002-06-20  Jeff Hobbs  <[email protected]>

	* doc/listbox.n:
	* generic/tkListbox.c (DisplayListbox):
	* mac/tkMacDefault.h:   TIP #94 implementation adding -activestyle
	* tests/listbox.test:   option to the listbox.  This adds the ability
	* unix/tkUnixDefault.h: to have listboxes look native on Windows, and
	* win/tkWinDefault.h:   "nicer" elsewhere using the 'dotbox' style.

2002-06-20  Peter Spjuth  <[email protected]>

	* generic/tkGrid.c: Corrected the test for grid propagate change.
	[Bug #571433]

2002-06-19  Jeff Hobbs  <[email protected]>

	* tests/panedwindow.test:
	* generic/tkPanedWindow.c: ensure that sash index is lower bounds
	checked. [Bug #548727]

2002-06-19  Mo DeJong  <[email protected]>

	* generic/tkClipboard.c (TkClipCleanup): Add code
	to set dispPtr->clipWindow to NULL, this was
	accidently removed by last commit. Fixes
	a crash while running the tests under win32.

2002-06-19  Mo DeJong  <[email protected]>

	* generic/tkBind.c (TkBindDeadWindow):
	Handle case where Tk_DestroyWindow is invoked
	on clipboard and send windows.
	* generic/tkClipboard.c (TkClipCleanup):
	Invoke Tk_DestroyWindow to cleanup the
	dispPtr->clipWindow. Call Tcl_Preserve
	and Tcl_Release on the window to avoid an
	invalid memory ref on shutdown.
	* generic/tkEvent.c (Tk_HandleEvent):
	Panic if XCreateIC is invoked twice for
	the same window. This should never happen,
	the check were just added to make sure it
	does not since this could lead to crashes
	in XCloseIM.
	* generic/tkFocus.c (TkFocusDeadWindow):
	Handle case where Tk_DestroyWindow is invoked
	on clipboard and send windows.
	* generic/tkOption.c (TkOptionDeadWindow): Ditto.
	* generic/tkWindow.c (TkCloseDisplay): Move
	deletion of dispPtr->winTable after TkpCloseDisplay
	call since Tk_DestroyWindow uses it and could
	be called by TkpCloseDisplay for clipboard/send windows.
	Also invoke ckfree for the dispPtr instead of
	doing it in TkpCloseDisplay.
	(Tk_DestroyWindow): Check for a null winPtr->mainPtr
	before doing certain cleanup tasks so the we can
	invoke Tk_DestroyWindow on clipboard and send windows.
	We need to do this so that XDestroyIC will get invoked
	for the input contexts of each window.
	* mac/tkMacXStubs.c (TkpCloseDisplay): Don't free
	the displayPtr since this is now done in TkCloseDisplay.
	* unix/tkUnixEvent.c (TkpCloseDisplay, OpenIM): Remove
	conditional compilation around calls to XCloseIM
	since I am confident that the crashes related to
	input contexts has been fixed. Don't free
	the displayPtr since this is now done in TkCloseDisplay.
	* unix/tkUnixSend.c (TkSendCleanup): Invoke the
	Tk_DestroyWindow method to cleanup the special
	send window. This will call XDestroyIC and thereby
	avoid a crash in XCloseIM. The send window needs
	to be Tcl_Preserve and Tcl_Release to avoid an
	invalid memory ref on shutdown.
	* win/tkWinX.c (TkpCloseDisplay): Don't free
	the displayPtr since this is now done in TkCloseDisplay.
	[Tk patch 570902]

2002-06-19  Donal K. Fellows  <[email protected]>

	* generic/tkStyle.c: TIP#48 style engine.
	See http://purl.org/tcl/tip/48.html for details.

	* generic/tkConfig.c (GetOptionFromObj): Split to allow for access
	to option tables via name as well as via object.
	(TkGetOptionSpec): Semi-public interface to GetOption functionality.
	(DoObjConfig, Tk_RestoreSavedOptions, FreeResources)
	(GetObjectForOption): Basic style support for configure.

	* generic/tkWindow.c (TkCreateMainWindow, Tk_DestroyWindow): Added
	calls to set up and tear down the style subsystem.

	* generic/tk.decls, generic/tk.h: Many declarations forming TIP#48
	public interface.

	* generic/tkInt.decls (TkStylePkgInit,TkStylePkgFree):
	* generic/tkInt.h (TkGetOptionSpec): Supporting declarations.

	* unix/Makefile.in, win/Makefile.in, win/makefile.vc: Added
	tkStyle.c to list of generic source files.

2002-06-18  Donal K. Fellows  <[email protected]>

	* tests/defs.tcl (makeFile): Defined the return value of this
	procedure to be the filename of the created file, as in the real
	tcltest package...

2002-06-17  Mo DeJong  <[email protected]>

	* generic/tkImage.c (Tk_ImageObjCmd, DeleteImage): Call
	Tcl_Preserve and Tcl_Release for the masterPtr->winPtr
	window to avoid accessing memory that had already
	been deallocated in DeleteImage.

2002-06-17  David Gravereaux <[email protected]>

	Trims to support the removal of RESOURCE_INCLUDED from rc
	scripts from Tcl's accepted FR #565088.

	* generic/tk.h: Changed RESOURCE_INCLUDED to be RC_INVOKED
	as the RC tool defines this already by default.

	* win/rc/tk.rc:
	* win/rc/wish.rc: removed the #define RESOURCE_INCLUDED lines.

2002-06-17  Jeff Hobbs  <[email protected]>

	* unix/Makefile.in (dist): correct installation of
	wish.exe.manifest to DISTDIR target directory.

	* generic/tkCmds.c (Tk_TkObjCmd):
	* generic/tkInt.h (struct TkCaret):
	* mac/tkMacXStubs.c (Tk_SetCaretPos):
	* unix/tkUnixKey.c (TkpGetString, Tk_SetCaretPos):
	* win/tkWinX.c (Tk_SetCaretPos):
	* tests/tk.test:        Added 'tk caret' implementation of TIP#96
	* doc/SetCaret.3 (new): which adds a TkCaret structure element to
	* doc/tk.n:             TkDisplay for maintaining state.

	* unix/tkUnixSend.c (TkSendCleanup): special cleanup of
	inputContext to avoid bug in XCloseIM. (dejong)

2002-06-17  Don Porter <[email protected]>

	* library/msgs/en_gb.msg:  Added catalog for UK English.
	Currently includes only Color -> Colour translation.

2002-06-17  D. Richard Hipp  <[email protected]>

	* doc/checkbutton.n:
	* doc/radiobutton.n:
	* generic/tkButton.c:
	* generic/tkButton.h:
	* mac/tkMacButton.c:
	* tests/button.test:
	* unix/tkUnixButton.c:
	* win/tkWinButton.c: Implementation of TIP#82 - Added the
	-offrelief option to checkbutton and radiobutton.

2002-06-14  Mo DeJong  <[email protected]>

	* generic/tkWindow.c (Tk_DestroyWindow): Set the pathName
	component of a window to NULL after its memory has been
	deallocated to avoid a possible illegal memory access
	as a result of a call to Tk_PathName() on a Tk_Window
	structure of a window that has already been destroyed.
	[Tk bug 521946]

2002-06-14  Mo DeJong  <[email protected]>

	* generic/tkOption.c (Tk_GetOption): Allocate
	memory with ckalloc not malloc. This keeps
	Tk from erroring out when built with
	TCL_MEM_DEBUG.

2002-06-14  Jeff Hobbs  <[email protected]>

	* generic/tkBind.c (HandleEventGenerate):
	* generic/tkInt.h: changed warpInProgress boolean from int to a
	bit in the flags variable (TK_DISPLAY_IN_WARP)

	* generic/tkCmds.c (Tk_TkObjCmd):
	* unix/tkUnixKey.c (TkpGetString):
	* generic/tkEvent.c (Tk_HandleEvent):
	* generic/tkInt.h: changed useInputMethods boolean from int to a
	bit in the flags variable (TK_DISPLAY_USE_IM)

	* generic/tkInt.h:
	* generic/tkCmds.c (Tk_WmObjCmd):
	* unix/tkUnixWm.c (Tk_WmCmd):
	* win/tkWinWm.c (Tk_WmCmd): changed wmTracing from being an int to
	just a bit in the flags variable (TK_DISPLAY_WM_TRACING)

	* generic/tkEvent.c (Tk_HandleEvent):
	* unix/tkUnixEvent.c (OpenIM):
	* unix/tkUnixKey.c (TkpGetString):
	* generic/tkInt.h: added TK_DISPLAY_XIM_SPOT flag bit for TkDisplay
	and used this to allow a runtime check to see if over-the-spot XIM
	is possible.  If not it will try and fallback to the old-style
	input context, which handles things like dead keys input.

	* generic/tk.decls:     added TIP #84 implementation that adds a
	* generic/tkDecls.h:    Tk_CollapseMotionEvents API which controls Tk's
	* generic/tkEvent.c:    collapsing of incoming motion events on its
	* generic/tkInt.h:      windows.  The default remains to do collapsing.
	* generic/tkStubInit.c: Added a flags parameter to the internal display
	* generic/tkWindow.c:   structure to support this and be used in the
	* doc/QWinEvent.3:      future for other bits. [Tk patch 564642]

	* unix/mkLinks: updated from current docs

2002-06-14  Mo DeJong  <[email protected]>

	* generic/tkEvent.c (TkXErrorHandler): Declare static
	function to avoid compiler error with VC++.
	* generic/tkBind.c (ExpandPercents): Cast argument to
	Tk_GetAtomName in order to avoid compiler warning.

2002-06-14  Joe English  <[email protected]>

	* doc/bind.n:
	* generic/tk.h:
	* generic/tkBind.c:
	* generic/tkCanvWind.c:
	* generic/tkCmds.c:
	* generic/tkEvent.c:
	* generic/tkFocus.c:
	* generic/tkGrab.c:
	* generic/tkGrid.c:
	* generic/tkImage.c:
	* generic/tkPack.c:
	* generic/tkPlace.c:
	* generic/tkPointer.c:
	* generic/tkTextWind.c:
	* generic/tkWindow.c:
	* mac/tkMacSubwindows.c:
	* mac/tkMacWindowMgr.c
	* mac/tkMacWm.c:
	* unix/Makefile.in:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixWm.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWindow.c:
	* win/tkWinWm.c: Implementation of TIP #47 by Neil McKay
	"Modifying Tk to Allow Writing X Window managers".
	Add CirculateRequest, Create, MapRequest, ResizeRequest,
	and ConfigureRequest event types;
	Split TK_TOPLEVEL flag into TK_TOPLEVEL, TK_HAS_WRAPPER,
	TK_WIN_MANAGED, and TK_TOP_HIERARCHY. [Tk patch 572978]

2002-06-14  Andreas Kupries  <[email protected]>

	* unix/tkAppInit.c: Removed now unneeded and erroneous reference
	to 'matherr'. See Tcl ChangeLog entry 2002-05-31 Don Porter.

2002-06-14  David Gravereaux <[email protected]>

	* win/rules.vc: The test for compiler optimizations was in error.
	Thanks goes to Roy Terry <[email protected]> for his
	assistance with this.

2002-06-14  Donal K. Fellows  <[email protected]>

	Implement TIP 98  [Tk patch 566765]

	* doc/FindPhoto.3, generic/tk.h, generic/tk.decls:
	* generic/tkImgPhoto.c: Changed *_Old to *_NoComposite and
	USE_OLD_PHOTO_PUT_BLOCK to USE_COMPOSITELESS_PHOTO_PUT_BLOCK
	following a suggestion from Don Porter.

	* tests/imgPhoto.test: Added tests of -compositingrule

	* doc/photo.n: Added documentation for "-compositingrule".
	* generic/tkImgPhoto.c (ImgPhotoCmd, ParseSubcommandOptions): New
	"-compositingrule" option for [$photo copy] subcommand, using
	OPT_COMPOSITE flag and compositingRule field in SubcommandOptions
	structure.

	* doc/FindPhoto.3: Documented the extra argument for the
	compositing rule and the action to take if anyone wants to
	maintain total backward-compatability.

	* generic/tk.h (TK_PHOTO_COMPOSITE_*): Defined values for use as
	compositing rules.
	(USE_OLD_PHOTO_PUT_BLOCK): Added a way for users to select the old
	interface to Tk_PhotoPutBlock to provide an easier upgrade path.

	* generic/tk.decls: Alter Tk_PhotoPut*Block to Tk_PhotoPut*Block_Old
	and introduce new slots for the old name of function with an extra
	argument at the end for the compositing rule.

	* generic/tkImgPhoto.c (ImgPhotoCmd): Updated "transparency set"
	subcommand to use TkSubtractRegion().

	* win/tkWinRegion.c (TkSubtractRegion):
	* mac/tkMacRegion.c (TkSubtractRegion):
	* generic/tkInt.decls (TkSubtractRegion):
	* unix/tkUnixPort.h (TkSubtractRegion): Added function to perform
	the set-difference operation on regions; it seems all platforms
	can support it, and it makes removing rectangular bits from
	regions much easier.

	* generic/tkImgPPM.c (FileReadPPM): Reading a PPM/PGM always uses
	the SET compositing rule because it is faster and the format does
	not have any transparency information.

	* generic/tkImgGIF.c (FileReadGIF): Reading a GIF always uses the
	SET compositing rule because GIF files model transparency as a
	single special colour.

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock):
	Added a compositing rule to allow better control over what happens
	to transparent pixels when inserting data into a photo image.

2002-06-13  Mo DeJong  <[email protected]>

	* tests/winfo.test: Add basic tests for winfo ismapped.

2002-06-13  Mo DeJong  <[email protected]>

	* tests/unixWm.test:
	* tests/wm.test: Move wm minsize and wm maxsize
	usage tests into the cross platform wm tests.

2002-06-13  Don Porter <[email protected]>

	* tests/cursor.test:  corrected error after cursor-2.2.
	* tests/defs.tcl: Added enhancements to Tk's fake version of
	tcltest required by recent cursor.test changes.

2002-06-13  Donal K. Fellows  <[email protected]>

	* tests/cursor.test (cursor-2.[34]): Tests added to ensure that
	cursor specs really are well-behaved lists.  Also some general
	clean-up...
	* win/tkWinCursor.c (TkGetCursorByName): Undone Jeff's back-off
	and fixed things so that they should work now.  Cursor specs are
	lists first and foremost.

2002-06-12  Mo DeJong  <[email protected]>

	* changes: Clearly label wm transient changes as
	a POTENTIAL INCOMPATIBILITY.
	* doc/wm.n: Remove "some window managers will" text
	and explicitly state what behavior a transient
	window will display. Also mention that it is an
	error to make a window a transient of itself.

2002-06-12  Mo DeJong  <[email protected]>

	* library/choosedir.tcl (tk::dialog::file::chooseDir):
	* library/clrpick.tcl (tk::dialog::file::chooseDir):
	* library/msgbox.tcl (tk::MessageBox):
	* library/tkfbox.tcl (tk::dialog::file):
	* library/xmfbox.tcl (tk::MotifFDialog): Remove the
	transient property on dialogs after they have been
	dismissed to insulate them from further state changes
	in the master. This keeps a withdrawn dialog from
	being mapped when the master is deiconified. [Tk patch 568278]

2002-06-12  Jeff Hobbs  <[email protected]>

	* win/tkWinCursor.c (TkGetCursorByName): reverted fix from
	2002-06-06 because it broke the ability to use built-in cursors
	like left_ptr.

2002-06-12  Mo DeJong  <[email protected]>

	* library/choosedir.tcl (tk::dialog::file::chooseDir):
	* library/clrpick.tcl (tk::dialog::color):
	* library/dialog.tcl (tk_dialog):
	* library/msgbox.tcl (tk::MessageBox):
	* library/tkfbox.tcl (tk::dialog::file):
	* library/xmfbox.tcl (tk::MotifFDialog_Create):
	Only make the dialog window a transient if
	the master is visible. This check already
	appeared in some of the dialogs. This patch
	just copies the check into those that were
	lacking. [Tk patch 568253]

2002-06-12  Mo DeJong  <[email protected]>

	* changes: Add note about new transient behavior.
	* tests/unixWm.test: Check that the WM_TRANSIENT_FOR
	property for a transient window is being cleared
	when the master is destroyed.
	* tests/wm.test: Source defs.tcl instead of using
	tcltest to match the rest of Tk's test files.
	Add new tests that ensure that a transient's state
	mirrors the state of the master.
	* unix/tkUnixWm.c (WmInfo, TkWmNewWindow, TkWmMapWindow)
	(TkWmDeadWindow, Tk_WmCmd, WmWaitMapProc): Add numTransients
	member to WmInfo structure. Keep state of master and
	transient in sync using a callback that tracks MapNotify
	and UnmapNotify events. When the master is mapped, map
	the transient. When the master is unmapped or iconified,
	withdraw the transient.
	* win/tkWinWm.c (TkWmMapWindow, TkpWmSetState)
	(TkWmDeadWindow, Tk_WmCmd, WmWaitVisibilityOrMapProc):
	Keep state of master and transient in sync using a
	callback that tracks MapNotify and UnmapNotify events.
	Move masterPtr check from TkpWmSetState into TkWmMapWindow
	to deal with WM_NEVER_MAPPED transients. Cleanup
	numTransients and the callback in TkWmDeadWindow.
	Cleanup numTransients and the callback only after
	deleting a master in wm transient command to avoid
	deleting the callback when an error is raised.
	Add support for MapNotify and UnmapNotify events
	to the master callback. [Tk patch 561708]

2002-06-11  Joe English  <[email protected]>

	* library/menu.tcl: fix for bug report #530212 "Bad Window Path
	Name in tkMenuFind"

2002-06-10  David Gravereaux <[email protected]>

	* win/makefile.vc: Fixed a win98 issue where the /exclude option
	for xcopy is unsupported.
	Reported by Roy Terry <[email protected]>.

2002-06-10  Anton Kovalenko <[email protected]>

	* library/tk.tcl: added utility functions to get "-underline" and
	"-text" for labels and buttons from translatable string containing
	"magic ampersand" [patch #566605]
	* library/clrpick.tcl:
	* library/msgbox.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl: some places where msgcat is used to get
	translated label are modified to handle labels with magic ampersand.
	* library/msgs/ru.msg: russian translations added
	* library/msgs/cs.msg:
	* library/msgs/de.msg:
	* library/msgs/el.msg:
	* library/msgs/es.msg:
	* library/msgs/fr.msg:
	* library/msgs/it.msg:
	* library/msgs/nl.msg: all translation files now have labels with
	'magic ampersand' where appropriate. In el.msg some ampersands are
	missing, as I don't know which underline positions seems natural
	to "el" users.

2002-06-09  Mo DeJong  <[email protected]>

	* library/bgerror.tcl (tk::dialog::error::bgerror):
	Don't set the bgerror dialog as a transient of
	itself since this operation is ill defined.

2002-06-06  Donal K. Fellows  <[email protected]>

	* win/tkWinCursor.c (TkGetCursorByName): Fixed so that the reading
	of cursors from a file with a cursor spec was built using [list]
	works when the file has a space in instead of requiring fiddling
	with backslashes.

2002-06-06  Anton Kovalenko <[email protected]>

	* library/msgbox.tcl (MessageBox): Add -default normal
	when creating non-default buttons for message box.
	They already get -default normal when they're
	unfocused, and dialog window size used to change suddenly
	in such cases.

2002-06-05  Anton Kovalenko <[email protected]>

	* unix/tkUnixFont.c (Tk_DrawChars): Don't assume that
	one char is always one byte, and that required
	subfont for the last character in any string is
	the same as for the previous character
	[Bug #559435] [Patch #559437]

2002-05-27  Mo DeJong  <[email protected]>

	* changes: Document [wm transient .t .t] error.
	* tests/wm.test: Check that setting a window
	as a transient of itself raises an error. Check
	that passing a non-toplevel window to the wm
	transient command uses the enclosing toplevel.
	* unix/tkUnixWm.c (Tk_WmCmd): Raise an error
	if the user tries to make a toplevel a
	transient of itself.
	* win/tkWinWm.c (Tk_WmCmd): Raise an error
	if the user tries to make a toplevel a
	transient of itself. Test for other error
	before checking for the transient self error.

2002-05-27  Mo DeJong  <[email protected]>

	* unix/tkUnixWm.c (WmInfo, TkWmCleanup, TkWmNewWindow)
	(TkWmMapWindow, TkWmDeadWindow, Tk_WmCmd): Replace
	WmInfo's master and masterWindowName members with
	a masterPtr member. This implementation is much
	simpler and mirrors the Win32 implementation. This
	change makes it easy to check the flags of the
	master window. No user visible changes.

2002-05-27  Mo DeJong  <[email protected]>

	* generic/tkInt.decls: Add unix decl for TkpWmSetState.
	* generic/tkIntPlatDecls.h: Regen.
	* generic/tkStubInit.c: Regen.
	* tests/wm.test: Test state changes between iconic,
	normal, and withdrawn both before and after initial
	mapping.
	* unix/tkUnixWm.c (Tk_WmCmd, TkpWmSetState): Move
	state change code into TkpWmSetState to more closely
	match the Win32 implementation. No user visible changes.

2002-05-27  Mo DeJong  <[email protected]>

	* tests/embed.test: Added cross platform embed tests.
	Check that window passed to -use has the -container
	option set.
	* tests/wm.test: Remove useless catch call. Deiconify
	. just in case, stackorder tests will not pass unless
	it is in the normal state. Add -container flag to
	embedded stackorder test.
	* unix/tkUnixEmbed.c (TkpUseWindow):
	* win/tkWinEmbed.c (TkpUseWindow): Lookup Tk window
	based on the id passed in as the value for -use.
	Generate an error if the Tk window did not have
	the -container option set.

2002-05-26  Peter Spjuth <[email protected]>

	* generic/tkButton.c (ConfigureButton): When creating
	a radiobutton with -value "" it was not drawn properly
	if the -variable was created by the radiobutton.
	[Bug #548765]

2002-05-26  Peter Spjuth <[email protected]>

	* generic/tkCanvText.c (ComputeTextBbox): Negative
	coordinates were rounded badly causing a 1 pixel
	displacement. [Bug #556526]

2002-05-24  Mo DeJong  <[email protected]>

	* mac/tkMacWm.c (Tk_WmCmd):
	* tests/unixWm.test: Move wm transient checks over
	to wm.test so they will be run on all systems.
	* tests/wm.test: Add tests to check for error when
	an iconwindow is passed to the wm transient command.
	* unix/tkUnixWm.c (Tk_WmCmd):
	* win/tkWinWm.c (Tk_WmCmd): Raise an error if one
	of the windows passed to the wm transient command
	is an iconwindow for another toplevel.

2002-05-23  Mo DeJong  <[email protected]>

	* mac/tkMacWm.c (TkWmStackorderToplevelWrapperMap):
	* tests/wm.test: Add embedded Window test case for
	the stackorder command.
	* unix/tkUnixWm.c (TkWmStackorderToplevelWrapperMap):
	* win/tkWinWm.c (TkWmStackorderToplevelWrapperMap):
	Ignore embedded windows during wm stackorder command.

2002-05-21  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Invoke SC_ENABLE_SHARED before
	calling SC_CONFIG_CFLAGS so that the SHARED_BUILD
	variable can be checked inside SC_CONFIG_CFLAGS.
	* unix/tcl.m4: Update from Tcl.

2002-05-20  Don Porter  <[email protected]>

	* library/tk.tcl:  A little namespace cleanup on Daniel Steffen's
	latest revisions to avoid defining new global commands.

2002-05-20  Daniel Steffen  <[email protected]>

	* mac/tkMacInit.c:
	* mac/tkMacTclCode.r: include msgcat package in resources
	as bgerror depends on it. Restores ability of mac static
	build to run standalone (except for encoding file issues).

	* mac/tkMacInit.c:
	* library/console.tcl:
	* library/tk.tcl: fix tk.tcl not sourcing library files
	that define bindings at startup on mac. (independent of
	tk library files being in resources or on auto_path)

2002-05-08  Don Porter  <[email protected]>

	* library/bgerror.tcl:
	* library/tclIndex:  Cleaned up namespace usage of the bgerror
	dialog.  Completes soft dependence on msgcat.  [FR 539309]

2002-05-07  David Gravereaux  <[email protected]>
	* win/makefile.vc: Problem with TCLDIR macro not accepting
	forward slash path seperators resolved.  Added the same logic
	to INSTALLDIR, too. [Bug #553208]

2002-04-26  Jeff Hobbs  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: change HP-11 SHLIB_LD_LIBS from "" to ${LIBS} so
	that the .sl knows its dependent libs.

2002-04-24  Daniel Steffen  <[email protected]>

	* mac/tkMacTclCode.r:
	* mac/tkMacResource.r: added check of
	TCLTK_NO_LIBRARY_TEXT_RESOURCES #define to allow disabling the
	inclusion of the tk library code in the resource fork of Tk
	executables and shared libraries.
	Moved tk library code inclusion to separate file like in tcl.
	Added 'panedwindow' resource.

2002-04-22  Jeff Hobbs  <[email protected]>

	* library/button.tcl (ButtonLeave): corrected the 3
	implementations of ButtonLeave to check for Priv(relief) existing
	before trying to use it. [Patch #541849]

	* generic/tkTextDisp.c (DisplayLineBackground):
	* unix/tkUnix3d.c (Tk_3DHorizontalBevel):
	* unix/tkUnixFont.c (Tk_DrawChars): applied fixes to not overrun
	the X window 16-bit size limit. [Patch #541999] (bonfield)

2002-04-22  Donal K. Fellows  <[email protected]>

	* generic/tkTextDisp.c (GetXView, GetYView): Comparison with
	previous values of scrollbar range are now done in a way that is
	sensitive to the bizarreness of floating-point on architectures
	where IEEE-FP is not used on the processor.  Also increased the
	size of the temporary buffer to take account of the fact that
	TCL_DOUBLE_SPACE is meant to only imply enough space to take a
	printed double and trailing '\0', and no more.  [Bug #223739]
	(FP_EQUAL_SCALE): New macro to help compare floating-point numbers
	for equality in a sane way, used in GetXView and GetYView.

2002-04-12  Jeff Hobbs  <[email protected]>

	* generic/tkWindow.c (TkCloseDisplay): Added to centralize where a
	display was closed.  This handles freeing memory associated with a
	display and closing it.
	(DeleteWindowsExitProc): actually close displays.  This would also
	ideally be done in Tk_DestroyWindow when the last window on the
	display has been closed, but that still has unresolved order of
	cleanup problems.
	(Tk_DestroyWindow): added TkFocusFree call.

	* generic/tkStubInit.c:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntDecls.h:
	* generic/tkInt.decls: added TkFocusFree, TkClipCleanup and
	TkGCCleanup generic private procs, and TkWmCleanup, TkSendCleanup
	and TkFreeXId unix private procs.

	* generic/tkInt.h:
	* unix/tkUnixXId.c (TkFreeXId): frees XID resources.
	Made idCleanupScheduled a Tcl_TimerToken (was int) in TkDisplay
	structure to allow us to delete the timer scheduled for it.

	* unix/tkUnixWm.c (TkWmStackorderToplevel): ensure children
	structure is freed.
	(ConfigureEvent, ComputeReparentGeometry): Add extra wm tracing info
	(TkWmRestackToplevel): initialize changes to 0 to prevent UMR.
	Use WaitForConfigureNotify on all windows.  This part still
	requires fixing as it is the root of the 2 second raise delay on
	some window managers (those that use extra wrapper windows of
	their own).

	* unix/tkUnixSend.c (TkSendCleanup): free send-related resources

	* unix/tkUnixEvent.c (TkpCloseDisplay): call TkSendCleanup and
	TkWmCleanup.

	* unix/tkUnixSelect.c (SelRcvIncrProc): added missing Tcl_Release
	of interp

	* generic/tkGet.c (FreeUidThreadExitProc): free thread-specific
	resources on thread exit

	* generic/tkFocus.c (TkFocusFree): frees TkMainInfo data
	* generic/tkClipboard.c (TkClipCleanup): frees TkDisplay data
	* generic/tkGC.c (TkGCCleanup): frees TkDisplay data

	* unix/tkUnixFont.c (FontPkgCleanup): cleanup thread specific font
	resources on thread exit.

	* mac/tkMacXStubs.c (TkpOpenDisplay): memset the initial display
	structures to 0.

	* generic/tkOption.c (OptionThreadExitProc): freed tsd option
	stacks on thread exit.
	(Tk_GetOption): free mem used to get Tk_Uid

	* generic/tkMenu.c (ConfigureMenu): freed saved options in all
	error cases.

	* win/tkWinInt.h: declaration for TkWinGetUnicodeEncoding
	* win/tkWinDialog.c (GetFileNameW): use TkWinGetUnicodeEncoding
	* win/tkWinInit.c (TkpDisplayWarning): use TkWinGetUnicodeEncoding
	* win/tkWinFont.c: use TkWinGetUnicodeEncoding instead of static
	unicodeEncoding.

	* win/tkWinX.c (Tk_SetCaretPos): remove WM_IME_STARTCOMPOSITION
	and place the IME position within Tk_SetCaretPos.  Cache results in
	Tk_SetCaretPos to reduce unnecessary repositioning.  Also call
	DestroyCaret if we receive WM_KILLFOCUS.
	(TkpOpenDisplay): ZeroMemory the initial display structures.
	(TkWinGetUnicodeEncoding): Added so that Windows only needs to
	cache this value one, and then free it in TkWinXCleanup.
	(HandleIMEComposition): add support for Win98 and ATOK13
	IME. (yamamoto)

	* generic/tkConsole.c (ConsoleCmd): correct return that should
	have just set result code.

	* generic/tkImgPhoto.c: Added PhotoFormatThreadExitProc to clean
	up on thread exit. (Tk_PhotoPutBlock) slight code updates

	* generic/tkPanedWindow.c (DestroyPanedWindow, ConfigureSlaves):
	fix mem leaks in not freeing slave info

	* win/configure:
	* win/tcl.m4: Enabled COFF as well as CV style debug info with
	--enable-symbols to allow Dr. Watson users to see function info.
	More info on debugging levels can be obtained at:
	http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp

2002-04-10  Mo DeJong  <[email protected]>

	* doc/wm.n:
	* mac/tkMacWm.c:
	* tests/wm.test:
	* unix/tkUnixWm.c:
	* win/tkWinWm.c: Update wm stackorder usage message
	to make it clear that either 1 or 3 arguments are
	required. [Bug 540013]

2002-04-08  Daniel Steffen  <[email protected]>

	* mac/tkMacProjects.sea.hqx: added tkPanedWindow.c to projects
	* mac/tkMacAppInit.c: fixes to MSL stdin/stdout hookup to the
	TkConsole when using shared MSL libraries; fix for crashing
	bug on exit: writing to stdin/sterr when console has already
	been destroyed. (both fixes need support in MSL, see
	'CW Pro6 changes' in tcl/mac/tcltkMacBuildSupport.sea.hqx)
	* mac/tkMacDialog.c: fixes to Navigation Services Dialog filter.
	* mac/tkMacDraw.c: add panic for overwide TkImages that would
	crash Tk on mac otherwise.

2002-04-05  Jeff Hobbs  <[email protected]>

	* mac/tkMacXStubs.c: added Tk_SetCaretPos stub (does nothing).
	* win/tkWinX.c: added Tk_SetCaretPos code to position IME windows
	correctly when WM_IME_STARTCOMPOSITION is received.
	* unix/tkUnixKey.c: added Tk_SetCaretPos and code for setting
	XIM caret in TkpGetString.

	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tk.decls: added Tk_SetCaretPos declaration.  This command
	allows users to indicate the cursor position and is used by XIM
	(Unix) or IME (Windows) to place the caret box correctly.  It is
	also part of correct Accessibility style on Windows to make the
	magnifier jump to the focus point.

	* win/tkWinButton.c (TkpDisplayButton):
	* generic/tkTextMark.c (TkTextInsertDisplayProc):
	* generic/tkCanvText.c (DisplayCanvText):
	* generic/tkEntry.c (DisplayEntry): added Tk_SetCaretPos calls

	* generic/tkInt.h: added TK_XIM_SPOT #define (default 1).
	Added XFontSet attribute to TkDisplay when TK_XIM_SPOT is true.
	* generic/tkEvent.c (Tk_HandleEvent): made sure inputContexts are
	not getting created on DestroyNotify events (for dead windows).
	Added over-the-spot support if TK_XIM_SPOT is defined (default).
	The is the nicer XIM behavior, but uses a bit more memory.

	* unix/tkUnixEvent.c:
	* generic/tkWindow.c: moved OpenIM over to tkUnixEvent.c.
	Removed setting inputContext to null in Tk_MakeWindowExist as it
	was redundant.

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

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

2002-03-28  David Gravereaux <[email protected]>

	* win/.cvsignore (new):
	* win/lamp.bmp (new):
	* win/makefile.vc:
	* win/nmakehlp.c (new):
	* win/rules.vc:  Brought the makefile up-to-date with Tcl's one.
	This now has support for Win9x issues and the winhelp target now
	exists.  Color scheme can be changed.  I'm just imparting a first
	suggestion using orange :)  I'll have to think about the install
	portion of the helpfile as I'll need to do some tricks to insert
	tk's contents file into Tcl's using some special winhlp32.exe
	switches.  [Bug 533862 527941]

	* win/makefile.vc:  Tk helpfile is now installing itself into Tcl's
	contents file as part of the install target and rebuilding the
	contents table as desired.  [Bug 527941]

	* doc/console.n:  Changed topic from "Tcl Built-In Commands" to
	"Tk Built-In Commands"

	* win/buildall.vc.bat:  Update to match Tcl.

2002-03-26  Andreas Kupries  <[email protected]>

	* unix/tkUnixFont.c: Added inclusion of <arpa/inet.h>. This fixes
	a GCC/HPUX problem with missing a "htons". See also
	"tclUnixPort.h" for equivalent code.

2002-03-21  David Gravereaux <[email protected]>

	* win/makefile.vc: Changed optimize flag to -0ti instead of -02.
	[Bug 528441]

2002-03-20  Don Porter  <[email protected]>

	* generic/tkButton.c (ButtonTextVarProc,ButtonVarProc):
	* generic/tkCmds.c (WaitVariableProc):
	* generic/tkEntry.c (EntryTextVarProc):
	* generic/tkListbox.c (ListboxListVarProc):
	* generic/tkMenu.c (MenuVarProc):
	* generic/tkMenubutton.c (MenuButtonTextVarProc):
	* generic/tkMessage.c (MessageTextVarProc):
	* generic/tkScale.c (ScaleVarProc): Updates to handle change in
	type of part2 argument of Tcl_VarTraceProc typedef. [TIP 27]
	[Patch 532644].

2002-03-19  Jeff Hobbs  <[email protected]>

	* generic/tkOldConfig.c (Tk_ConfigureValue): prevent leaving
	interp->result as NULL.

2002-03-07  Donal K. Fellows  <[email protected]>

	* library/text.tcl (TextPasteSelection): Renaming of TextPaste to
	prevent confusion with tk_textPaste.  Stopped code from inserting
	selections twice, which seems to have happened with TIP#26, and
	reorganized code to reduce amount of stuff protected by catch
	which is tricky to maintain.
	(tk_textPaste): Reduce amount of code protected by catch.

2002-03-06  Mo DeJong  <[email protected]>

	* win/tkWinX.c: Define _WIN32_IE as 0x0300
	before including commctrl.h so that we can
	access the InitCommonControlsEx API when
	building Tk with mingw.

2002-03-06  Donal K. Fellows  <[email protected]>

	* README, generic/tk.h, unix/configure.in, unix/tk.spec:
	* win/configure.in: Bumped patchlevel; this might need to change
	in the future, but it will help us distinguish between the CVS
	version and the most recent released version.

2002-03-05  Jeff Hobbs  <[email protected]>

	*** 8.4a4 TAGGED FOR RELEASE ***

	* unix/README: updated --* options docs.

	* unix/tk.spec: fixed URL refs to use www.tcl.tk or SF.

2002-03-04  Jeff Hobbs  <[email protected]>

	* README:
	* mac/README:
	* unix/README:
	* win/README: updated to use www.tcl.tk URL.

2002-03-03  Jeff Hobbs  <[email protected]>

	* library/entry.tcl: added catch around Triple-1 binding use of
	sel.last

2002-02-28  Don Porter  <[email protected]>

	* library/console.tcl (ConsoleBind): Corrected console <<Paste>>
	binding on Unix platforms.

2002-02-26  Jeff Hobbs  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

	* generic/tkWindow.c (Tk_MainWindow, Tk_GetNumMainWindows):
	protect against being called before Tcl stubs are init'ed.
	[Bug #220916] (porter)

2002-02-25  Jeff Hobbs  <[email protected]>

	* generic/tkText.c (ConfigureText): reenable the blinking cursor
	on state change where necessary. [Bug #503772]

	* tests/listbox.test:
	* generic/tkListbox.c: corrected error handling when setting to an
	invalid listvar value. [Bug #503613]

	* library/scale.tcl: mirror B2 bindings to B3 on Windows to better
	accomodate two button mice. [Patch #493145]

	* library/panedwindow.tcl: improved proxy sash handling. (boudaillier)

2002-02-25  Donal K. Fellows  <[email protected]>

	* tests/filebox.test: Reorganised and fixed so that tests are
	executed fewer times (!) and the automatic extension adding
	behaviour of tk_getSaveFile is tested.

2002-02-23  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2002-02-22  Jeff Hobbs  <[email protected]>

	* generic/tkPanedWindow.c (PanedWindowWidgetObjCmd): fixed returns
	that should have been breaks instead.  Corrected .pw configure
	handling for insufficient args.  [Patch #521436] (boudaillier)

	* mac/tkMacDefault.h:
	* unix/tkUnixDefault.h:
	* win/tkWinDefault.h: changed panedwindow default relief to flat,
	a more natural outer relief.

	* library/panedwindow.tcl (ReleaseSash): changed to not pass x and
	y args at all (they aren't used).
	Added proc comments.  Made configuring sash cursor more efficient.
	Added Cursor timer that restores the default cursor when pointer
	is no longer over the sash.  This is necessary because Leave
	events won't be seen when moving into a paned child.

2002-02-22  Donal K. Fellows  <[email protected]>

	* library/demos/widget: New section "Paned Windows"
	* library/demos/paned2.tcl, library/demos/paned1.tcl: New files.

	* library/panedwindow.tcl (ReleaseSash): Added missing arguments.
	* library/tk.tcl: Bindings for paned window were not being loaded
	by default.

	* unix/tkUnixMenu.c (GetMenuLabelGeometry,DrawMenuEntryLabel):
	Stop meaningless GCC warnings.

2002-02-21  Jeff Hobbs  <[email protected]>

	* doc/panedwindow.n (new):
	* generic/tkPanedWindow.c (new):
	* generic/tkInt.h:
	* generic/tkWindow.c:
	* library/panedwindow.tcl (new):
	* mac/tkMacDefault.h:
	* tests/panedwindow.test (new):
	* unix/Makefile.in:
	* unix/tkUnixDefault.h:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/tkWinDefault.h: added implementation of TIP #41, panedwindow
	widget. [Patch #512503] (melski)

	* generic/tkOption.c (ReadOptionFile): fixed Tcl_Seek casting to
	remove warnings (we expect no option files with be > 2GB).

	* unix/configure: regenerated
	* unix/tcl.m4: updated to sync with Tcl's tcl.m4
	Added --enable-64bit support for AIX-4 using IBM's xlc (-q64 flag).

2002-02-19  Don Porter  <[email protected]>

	* changes: First draft of updated changes for 8.4a4 release.

2002-02-19  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (MatchFileFormat):  Tcl_Seek takes
	Tcl_WideInt offset (three places.)
	* generic/tkImgPPM.c (FileReadPPM): Tcl_Seek takes Tcl_WideInt offset.
	* generic/tkFrame.c (ConfigureFrame): Stop GCC warning.

	* generic/tkImgGIF.c: Made file meet the formatting rules from the
	Tcl Engineering Manual better; mostly differences in whitespace.

2002-02-18  Jeff Hobbs  <[email protected]>

	* unix/configure: regen'd
	* unix/tcl.m4:
	* unix/configure.in: added macros and calls to SC_TCL_EARLY_FLAGS
	and SC_TCL_64BIT_FLAGS, part of TIP #72.

2002-02-14  Mo DeJong  <[email protected]>

	* library/entry.tcl:
	* library/text.tcl: Adjust <Double-1> and <Triple-1> bindings
	so that no anchor point is set and the insertion cursor is
	set to the last character in the selection. [Bug 220943]
	* tests/event.test: Add test cases for double click and
	drag as well as triple click and drag in the text and
	entry widgets.

2002-02-14  Mo DeJong  <[email protected]>

	* tests/event.test (_text_ind_to_x_y, _get_selection): Fix
	incorrect use of results from bbox invocation so that
	y center point for a give index is calculated correctly.
	Add new method to return the selection and use it in
	test cases. Always lappend to the result list to avoid
	case where initial result includes a space.

2002-02-07  Don Porter  <[email protected]>

	* generic/tkMain.c:
	* mac/tkMacInit.c:
	* mac/tkMacKeyboard.c:
	* win/tkWinDialog.c:
	* win/tkWinTest.c: modified some callers of Tcl routines that
	were restored to return (char *) pointing into Tcl_DStrings.

2002-02-03  eric melski  <[email protected]>

	* generic/tkImage.c (Tk_ImageObjCmd): Clean up bogus for loop in
	[image inuse] subcommand [Bug #485803].

2002-02-01  Jeff Hobbs  <[email protected]>

	* generic/tkCmds.c (Tk_TkObjCmd): don't use 'bool' as an arg as it
	conflicts with the C99 spec. [Bug #511956] (ingham)

2002-02-01  David Gravereaux <[email protected]>

	* win/makefile.vc: unset macro located in the tktest target
	caused a failure to build.  [Bug 511652]

2002-01-30  Don Porter  <[email protected]>

	* win/stubs.c (XSetCommand):  Overlooked CONSTification.

2002-02-01  Donal K. Fellows  <[email protected]>

	* doc/photo.n: Documented transparency subcommand.
	* tests/imgPhoto.test (imgPhoto-4.40...imgPhoto-4.68): Tests for
	the transparency subcommand.
	* generic/tkImgPhoto.c (ImgPhotoCmd): Added transparency
	subcommand (see TIP #14.)

2002-01-31  Todd Helfter <[email protected]>
	* generic/tkMenu.c (ConfigureMenuCloneEntries)
	* tests/menu.test (menu3.68)
	Correct and test for logic error when cloning menus. [Bug #508988]

2002-01-30  Don Porter  <[email protected]>

	* generic/tk.decls:  The POTENTIAL INCOMPATIBILITY in the changing
	interface of Tk_ParseArgv can now be removed by the -DUSE_NON_CONST
	compiler flag.
	* generic/tkDecls.h: make genstubs

2002-01-29  Andreas Kupries  <[email protected]>

	* win/tkWinInit.c (TkpGetAppName): TIP 27 fixup. The code now does
	not write into the CONST path returned by "argv0" and
	Tcl_SplitPath anymore.

2002-01-28  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Don't set TCL_LIB_SPEC and
	TCL_STUB_LIB_SPEC variables since this breaks
	the AIX build. This was used in the past to
	support linking with Tcl from the build dir
	or the install dir, but it is no longer needed.

2002-01-28  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Remove commented out vars.
	* unix/configure: Regen.
	* unix/configure.in: Don't subst vars that are already
	taken care of in SC_LOAD_TCLCONFIG.
	* unix/tcl.m4: Update from Tcl.
	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl.

2001-01-27  Daniel Steffen  <[email protected]>

	* generic/tkFileFilter.c:
	* mac/tkMacInit.c:
	* mac/tkMacKeyboard.c:
	* mac/tkMacMenus.c: TIP 27 CONSTification induced changes

2002-01-25  Don Porter  <[email protected]>

	* All changes below are Patch 505159

	* doc/AddOption.3:
	* doc/CanvTkWin.3:
	* doc/GetPixels.3:
	* doc/Name.3:
	* doc/ParseArgv.3:
	* generic/tk.decls (Tk_AddOption,Tk_CanvasGetCoord,Tk_GetPixels)
	(Tk_GetScreenMM,Tk_NameToWindow,Tk_ParseArgv):
	* generic/tkArgv.c (Tk_ParseArgv):
	* generic/tkCanvLine.c (ParseArrowShape):
	* generic/tkCanvUtil.c (Tk_CanvasGetCoord,Tk_CanvasTagsParseProc)
	(Tk_CanvasTagsPrintProc,Tk_GetDash):
	* generic/tkCanvas.c (ConfigureCanvas):
	* generic/tkGet.c (Tk_GetPixels,Tk_GetScreenMM):
	* generic/tkImgPhoto.c (ImgPhotoCmd):
	* generic/tkMain.c (Tk_MainEx):
	* generic/tkOldConfig.c (FormatConfigInfo):
	* generic/tkOption.c (Tk_AddOption):
	* generic/tkText.c (TextWidgetCmd,TkTextGetTabs,DumpSegment):
	* generic/tkText.h (TkTextCreateTag):
	* generic/tkTextTag.c (TkTextCreateTag):
	* generic/tkWindow.c (Tk_NameToWindow,Initialize):
	* mac/tkMacCursor.c (FindCursorByName,TkGetCursorByName):
	* mac/tkMacWm.c (Tk_WmCmd):
	* unix/tkUnixCursor.c (TkGetCursorByName):
	* unix/tkUnixSend.c (ValidateName):
	* unix/tkUnixWm.c (Tk_WmCmd):
	* win/tkWinCursor.c (TkGetCursorByName):
	* win/tkWinWm.c (Tk_WmCmd): Updated callers of Tcl_SplitList and
	Tcl_Merge.
	* generic/tkDecls.h: make genstubs
	***POTENTIAL INCOMPATIBILITY***
	Includes a source incompatibility in the argv argument of Tcl_ParseArgv.

	* generic/tkBind.c (DeleteVirtualEvent):
	* generic/tkCanvas.c (ScrollFractions, CanvasWidgetCmd)
	(CanvasUpdateScrollbars):
	* generic/tkTestTag.c (TkTextTagCmd): Updated callers of
	Tcl_GetStringResult.  Rewrote PrintScrollFractions to
	ScrollFractions to stop scribbling directly on interp->result.

	* generic/tkInt.decls (TkGetDefaultScreenName, TkpDisplayWarning)
	(TkpOpenDisplay):
	* generic/tkCanvPs.c (Tk_PostscriptColor, Tk_PostscriptFont):
	* generic/tkEntry.c (EntrySetValue, EntryValidateChange)
	(ExpandPercents, EntryValueChanged, Tk_EntryObjCmd, DestroyEntry)
	(ConfigureEntry, EntryComputeGeometry, InsertChars, DeleteChars)
	(EntryFetchSelection, EntryTextVarProc, Tk_SpinBoxObjCmd)
	(SpinboxWidgetObjCmd):
	* generic/tkMain.c (Prompt):
	* generic/tkMenu.c (MenuVarProc):
	* generic/tkMenubutton.c (ConfigureMenuButton, MenuButtonTextVarProc):
	* generic/tkMessage.c (ConfigureMessage, MessageTextVarProc):
	* generic/tkWindow.c (GetScreen, Initialize):
	* mac/tkMacInit.c (TkpInit, TkpDisplayWarning):
	* mac/tkMacXStubs.c (TkGetDefaultScreenName, TkpOpenDisplay):
	* unix/tkUnix.c (TkGetDefaultScreenName):
	* unix/tkUnixEvent.c (TkpOpenDisplay):
	* unix/tkUnixInit.c (TkpGetAppName, TkpDisplayWarning):
	* unix/tkUnixSend.c (SendEventProc):
	* win/tkWinInit.c (TkpGetAppName, TkpDisplayWarning):
	* win/tkWinX.c (TkGetDefaultScreenName,TkpOpenDisplay): Updated
	callers of Tcl_GetVar, Tcl_GetVar2
	* generic/tkIntDecls.h: make genstubs

	* generic/tkCanvPs.c (TkCanvPostscriptCmd):
	* generic/tkImgBmap.c (TkGetBitmapData):
	* generic/tkOption.c (ReadOptionFile):
	* mac/tkMacInit.c (TkpInit, TkpGetAppName):
	* win/tkWinInit.c (TkpGetAppName): Updated callers of
	Tcl_SplitPath, Tcl_JoinPath, and Tcl_TranslateFileName.

2002-01-18  Mo DeJong  <[email protected]>

	* tests/wm.test: Rewrite stackorder tests that
	deal with toplevels that have the overrideredirect
	flag set. [Tk bug 492259]

2002-01-18  Don Porter  <[email protected]>

	* win/tkWinDialog.c: Overlooked Tcl_GetIndexFromObj callers.

2001-01-18  Daniel Steffen  <[email protected]>

	* mac/tkMacDialog.c:
	* mac/tkMacSend.c: TIP 27 CONSTification broke the mac
	build in a few places.

2002-01-16  Jeff Hobbs  <[email protected]>

	* generic/tkListbox.c (ChangeListboxOffset): improved tracking
	when scrolling on x axis with entry/text.  [Bug #225025] (voskuil)

2002-01-16  Don Porter  <[email protected]>

	* generic/tk3d.c (Tk_GetReliefFromObj):
	* generic/tkBind.c (Tk_EventObjCmd, HandleEventGenerate):
	* generic/tkButton.c (ButtonWidgetObjCmd):
	* generic/tkCanvas.c (CanvasWidgetCmd, FindItems):
	* generic/tkClipboard.c (Tk_ClipboardObjCmd):
	* generic/tkCmds.c (Tk_BellObjCmd, Tk_TkObjCmd, Tk_TkwaitObjCmd)
	(Tk_UpdateObjCmd, Tk_WinfoObjCmd, Tk_WmObjCmd):
	* generic/tkConfig.c (DoObjConfig):
	* generic/tkEntry.c (EntryWidgetObjCmd, SpinboxWidgetObjCmd):
	* generic/tkFocus.c (Tk_FocusObjCmd):
	* generic/tkFont.c (Tk_FocusObjCmd, ConfigAttributesObj):
	* generic/tkFrame.c (Tk_FrameObjCmd):
	* generic/tkGet.c (Tk_GetAnchorFromObj, Tk_GetJustifyFromObj):
	* generic/tkGrab.c (Tk_GrabObjCmd):
	* generic/tkGrid.c (Tk_GridObjCmd, GridRowColumnConfigureCommand)
	(GridSlavesCommand, ConfigureSlaves):
	* generic/tkImage.c (Tk_ImageObjCmd):
	* generic/tkImgBmap.c (ImgBmapCmd):
	* generic/tkImgGIF.c (FileReadGIF):
	* generic/tkImgPhoto.c (ImgPhotoCmd):
	* generic/tkListbox.c (ListboxWidgetObjCmd, ListboxSelectionSubCmd)
	(GetListboxIndex):
	* generic/tkMenu.c (MenuWidgetObjCmd, MenuAddOrInsert, MenuCmd)
	(ConfigureMenu, CloneMenu):
	* generic/tkMenubutton.c (MenuButtonWidgetObjCmd):
	* generic/tkMessage.c (MessageWidgetObjCmd):
	* generic/tkOption.c (Tk_OptionObjCmd):
	* generic/tkPack.c (Tk_PackObjCmd, ConfigureSlaves):
	* generic/tkPlace.c (Tk_PlaceObjCmd):
	* generic/tkScale.c (ScaleWidgetObjCmd):
	* generic/tkSelect.c (Tk_SelectionObjCmd):
	* generic/tkSquare.c (SquareWidgetObjCmd):
	* generic/tkTest.c (TestobjconfigObjCmd, TrivialConfigObjCmd)
	(TestfontObjCmd): Updates to handle change in type of tablePtr
	argument of Tcl_GetIndexFromObj(Struct) from (char **) to
	(CONST char **).  [TIP 27] [Patch 504705]

	* generic/tkCanvText.c (GetSelText):
	* generic/tkEntry.c (Entry{FetchSelection,Setvalue},ExpandPercents):
	* generic/tkSelect.c (HandleTclCommand):
	* generic/tkText.c (TextSearchCmd):
	* generic/tkTextIndex.c (TkTextMakeByteIndex, TkTextIndexBackChars):
	* mac/tkMacFont.c (Tk_MeasureChars, BreakLine):
	* unix/tkUnixMenu.c (DrawMenuUnderline):
	* win/tkWinMenu.c (GetEntryText, DrawMenuUnderline):  Updated
	callers of Tcl_Utf* and Tcl_Regexp* APIs to reflect TIP 27 API
	changes (see Tcl Patch 471509). [Patch 471513]

2002-01-16  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.
	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl.

2002-01-04  Don Porter  <[email protected]>

	* generic/tkMain.c (Tk_MainEx):  Updated callers of CONSTified
	Tcl interfaces Tcl_EvalFile and TclGetStartupScriptFileName.

	* generic/tkConsole.c (ConsoleOutputProc, TkConsolePrint):
	* generic/tkInt.h (TkConsolePrint):
	* mac/tkMacAppInit.c (TkConsolePrint): Updated Tk's console to
	CONSTified channel driver interface.  [Tcl Patch 503565, Tk Patch
	503983]

2002-01-11  Mo DeJong  <[email protected]>

	Use ${libdir} instead of ${exec_prefix}/lib. [Tcl bug 489370]

	* unix/configure: Regen.
	* unix/configure.in: Define and use libdir.
	* win/configure: Regen.
	* win/configure.in: Define libdir.

2002-01-11  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Burn Tcl and Tk build
	directories into tktest executable to avoid crashes
	caused by ld loading a previously installed version
	of the tcl or tk shared libraries. Remove setting
	of LD_LIBRARY_PATH, LIBPATH, and SHLIB_PATH
	before running tktest since it should no
	longer be required.

2002-01-11  Mo DeJong  <[email protected]>

	Enable use of Tcl stubs when building Tk as
	a shared library. This should fix the build
	under AIX. [Bugs 220858, 220955, 220921]

	* unix/Makefile.in: Add TCL_STUB_LIB_SPEC and
	TCL_STUB_LIB_FLAG variables.
	* unix/configure: Regen.
	* unix/configure.in: Pass TCL_STUB_LIB_SPEC into
	Makefile and use it when linking the tk shared library.
	Define USE_TCL_STUBS when building shared. Subst
	TCL_STUB_LIB_SPEC and TCL_STUB_LIB_FLAG.

2002-01-08  D. Richard Hipp  <[email protected]>

	* win/tkWinMenu.c: Fix the following bug: If you select an entry
	on a cascade menu then the next time the parent menu is posted, the
	cascade entry was active.  Also, if you traverse to a disabled entry
	using keystrokes and press ENTER on the disabled entry, then that
	entry appears active the next time the menu is posted.  The same
	patch fixes both problems.

2002-01-04  Don Porter  <[email protected]>

	* generic/tkBind.c (TkBindFree):
	* generic/tkGrid.c (ResolveConstraints,CheckSlotData,DestroyGrid):
	* generic/tkSelect.c (Tk_DeleteSelHandler,TkSelDeadWindow): Replaced
	Tcl_Free calls with ckfree so that memory debugging is fully supported.

2001-12-28  Jeff Hobbs  <[email protected]>

	* test/winButton.test:
	* win/tkWinButton.c: added updated patch #463234 which returns the
	default sizing behavior (not so native), but enables native L&F
	with negative sizing (-11 for example).

	* library/text.tcl (tk::TextButton1): made text receive focus even
	in disabled state for Windows to show selection and allow
	mouse-wheel scrolling.

	* win/tkWinInit.c (TkpDisplayWarning): added Tcl_DStringFree's

	* win/tkWinInt.h:
	* win/tkWinX.c: added TkWinProcs that represent a function table
	to switch between unicode and ansi procs on Windows.  This is
	analogous to the TclWinProcs.  Using Tcl_WinUtfToTChar, we can
	easily take advantage of using unicode functions where available
	without having to switch on the platform id each time.

	* win/tkWinWm.c (InitWindowClass): corrected init routines to
	allow unicode in window titles on Windows (for Win2K/XP).
	(TkWmStackorderToplevel): Corrected casts to enable debug compile

	* win/configure: regen'ed
	* win/tcl.m4: added shell32.lib to link libs, as these are
	necessary for new directory chooser (when enabled).

	* win/tkWinDialog.c (Tk_MessageBoxObjCmd): use MessageBoxW for
	proper display of unicode errors.
	Added patch which uses new OLE based directory chooser.  This
	still has some issues, so is disabled by default. [Patch #468139]
	(ColorDlgHookProc) Corrected ability to use unicode chars in
	tk_chooseColor -title.

2001-12-27  Jeff Hobbs  <[email protected]>

	* win/tkWinInit.c (TkpDisplayWarning): Use MessageBoxW in case the
	error displayed has unicode chars. [Bug #485986]

2001-12-27  Daniel Steffen <[email protected]>

	* mac/tkMacInit.c:
	* mac/tkMacResource.r: synced up tkInit features to unix/win:
	use existing tkInit proc if defined. Added spinbox.tcl resource.
	Used TclGetEnv() instead of Tcl_GetVar2(interp, env)
	* mac/tkMacApplication.r:
	* mac/tkMacLibrary.r: minor version resources cleanup

2001-12-27  Jeff Hobbs  <[email protected]>

	* generic/tkButton.c (ButtonTextVarProc): guard against being
	called while the *button/label is being deleted. [Bug #490051]

	* library/entry.tcl:
	* library/spinbox.tcl:
	* library/text.tcl: added extra checks against bug #220269 and
	made spinbox reuse more of the entry procedure code.

2001-12-20  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2001-12-19  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2001-12-18  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Move EXP file changes over from
	Tcl configure script to fix AIX build with gcc. [Bug 220955]

2001-12-18  Mo DeJong  <[email protected]>

	* unix/Makefile.in:
	* win/Makefile.in: Use $(MAKE) instead of make
	in the tcltest rule.

2001-12-18  Don Porter  <[email protected]>

	* tests/event.test (event-click-drag-1.2): Corrected test that
	failed on Solaris/CDE due to text scrolling.  [Bug 413735]

2001-12-18  Jeff Hobbs  <[email protected]>

	* library/spinbox.tcl (ButtonDown): added catch to ignore
	possible error in after cancel when Priv(afterId) isn't defined.

	* doc/spinbox.n: corrected spin(up|down) -> button(up|down)

2001-12-14  Donal K. Fellows  <[email protected]>

	* doc/getOpenFile.n: Documented change.
	* library/tkfbox.tcl (SetFilter): Added code to guess the correct
	default extension from whatever value was selected in the
	filetypes option menu.  Adapted from code by Chris Nelson
	submitted in Patch #492220.

2001-12-12  Jeff Hobbs  <[email protected]>

	* unix/tkUnixWm.c (TkWmStackorderToplevelWrapperMap): added static

2001-12-05  Jeff Hobbs  <[email protected]>

	* generic/tkText.c:
	* generic/tkText.h: changed TkTextEditType enums to be prefaced
	with TK_EDIT_ to prevent name collision.

2001-12-05  Daniel Steffen <[email protected]>

	* mac/tkMacWm.c: mac implementation of wm stackorder
	(patch 481148, TIP 74)

2001-12-03  Mo DeJong  <[email protected]>

	Add TK patch 481148 to implement TIP 74, the
	wm stackorder command.

	* doc/winfo.n: Update documentation for the winfo
	children command to indicate that top-level windows
	are not returned in stacking order.
	* doc/wm.n: Add documentation for wm stackorder.
	* generic/tkInt.decls (TkWmStackorderToplevel):
	Add decl for new function.
	* generic/tkIntDecls.h: Regen.
	* generic/tkStubInit.c: Regen.
	* tests/unixWm.test: Add stackorder command to test
	for wm command usage message.
	* tests/wm.test: Add new set of tests for generic
	window manager methods.
	* unix/tkUnixWm.c (Tk_WmCmd, TkWmStackorderToplevelWrapperMap)
	(TkWmStackorderToplevel): Add unix implementation of
	new wm stackorder command.
	* win/tkWinWm.c (Tk_WmCmd, TkWmStackorderToplevelEnumProc)
	(TkWmStackorderToplevelWrapperMap, TkWmStackorderToplevel): Add
	windows implementation of new wm stackorder command.

2001-12-03  David Gravereaux <[email protected]>

	* win/makefile.vc: install target changes by request from
	Ryan Casey <[email protected]>.

2001-11-30  Donal K. Fellows  <[email protected]>

	* library/demos/widget: Further overhauling; shrank fonts, made
	better use of fonts, added an icon, fixed the About box.  Prompted
	by Bug #487442 from Vincent Wartelle.

2001-11-29  Donal K. Fellows  <[email protected]>

	* library/palette.tcl (tk_setPalette): Added heuristic to guess
	from the background whether to use black or white for the
	foreground when not told specifically.  Suggested by Chris Nelson,
	this makes the command fit the documentation better!

2001-11-27  David Gravereaux <[email protected]>

	* win/makefile.vc: Fixed CAT32 target.  cat.c is located in the Tcl
	source, not the Tk source.

2001-11-27  D. Richard Hipp <[email protected]>

	* library/menu.tcl: Do not allow keyboard traversal of torn-off
	menus to visit the (invisible) tearoff bar.

2001-11-26  D. Richard Hipp <[email protected]>

	* win/tkWinMenu.c: disabled menu items show the activebackground
	color in their background.  This change makes menu behavior
	consistent with what native windows does.

2001-11-24  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Add comments to better describe
	TCL_EXE and when it should be available. Add
	rule that prints message about running `make genstubs`
	when tkStubInit.c is out of date.
	* win/Makefile.in: Add TCL_TOOL_DIR and TCL_EXE
	variables to better match the Tcl Makefile. Add
	genstubs rule so tkSTubInit.c can be regenerated.

2001-11-24  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Don't AC_SUBST CFLAGS_DEBUG, CFLAGS_OPTIMIZE,
	or CFLAGS_WARNING since it is now done in SC_CONFIG_CFLAGS.
	* win/tcl.m4 (SC_CONFIG_CFLAGS): AC_SUBST DL_LIBS, CFLAGS_DEBUG,
	CFLAGS_OPTIMIZE, and CFLAGS_WARNING.

2001-11-23  Daniel Steffen <[email protected]>

	Up-port to 8.4 of mac code changes for 8.3.3 & various new
	changes for 8.4, some already backported to 8.3.4 (patch #435660)

	* library/tk.tcl: added <Key-F1> binding for <<Undo>> on the mac (TIP26)

	* library/button.tcl: fixed undefined $Priv(repeated) error for button
	without -repeatdelay support

	* generic/tkConsole.c:
	* library/console.tcl:
	* mac/tkMacInit.c:
	* mac/tkMacResource.r: corrected how mac deals with tcl library
	files present both in resources and in $tk_library directory.

	* generic/tkConsole.c: crashing bug fix when printing to console
	at program exit after the console has already been closed.
	Now setting gStdoutInterp=NULL in ConsoleClose().

	* mac/tkMacInit.c: correct use of Tcl_JoinPath in tk_library
	initialization

	* mac/tkMacMenu.c: special MDEF_PROC_OFFSET only needed for
	exactly one specific version of the MWERKS 68k compiler .

	* mac/tkMacShLib.exp: removed file

	* unix/Makefile.in: removed reference to .exp files

	* mac/MWTkBuildLibHeader.h:
	* mac/MW_TkBuildLibHeader.pch:
	* mac/MW_TkHeaderCommon.h:
	* mac/MW_TkOldImgStaticHeader.h:
	* mac/MW_TkStaticHeader.h:
	* mac/MW_TkStaticHeader.pch: new precompiled header files

	* mac/MW_TkHeader.pch:
	* mac/MW_TkOldImgHeader.h:
	* mac/MW_TkTestHeader.pch: revised precompiled header handling: now
	include a common header file 'MW_TkHeaderCommon.h' from all .pch files,
	the .pch files themselves now only setup #defines (e.g. BUILD_tk,
	STATIC_BUILD, TCL_DEBUG, TCL_THREADS) like in makefiles on other
	platforms.

	* mac/tkMac.h:
	* mac/tkMacPort.h:
	* mac/tkMacInt.h: use of BUILD_tk and TCL_STORAGE_CLASS like on other
	platforms, standardize #include'd files to what's done on other
	platforms, removed use of #pragma export, changed extern to EXTERN
	where appropriate to enable DLL export via the TCL_STORAGE_CLASS
	mechanism.

	* mac/tkMacAppearanceStubs.c: removed use of #pragma export

	* mac/widget.r: new resource file for 'Widget Demos'

	* mac/tkMacProjects.sea.hqx: updated mac build project files:
	build support for CodeWarrior Pro6, UnivIntf 3.4 & shared runtime
	libraries (see Tcl ChangeLog for details).
	changed weak linking so that CFM68k binaries now work on all OS
	versions from the free 7.5.5 onwards, with or without AppearanceMgr
	and/or NavigationMgr installed.
	added target to automatically build 'Widget Demos'
	included XML versions of the projects for CW Pro5 or Pro7 users.
	use compat/strtod.c instead of MSL's strtod()

	* generic/tkInt.decls:
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkStubInit.c:

	* mac/tkMacInt.h: MAC_TCL tk stub support was badly broken due to
	multiply defined (mac specific) names in tk.decls and tkInt.decls,
	removed the duplicates from the internal unsupported interfaces
	"interface tkInt" and "interface tkIntPlat"; moved declaration of
	TkpIsWindowFloating from tkMacInt.h to tkInt.decls: interface tkIntPlat.
	- these changes to the stub tables might require you to recompile your
	Tk extensions if they turn out to reference one of the removed routines
	in the wrong table (should be unlikely).

	* generic/tkMain.c: MAC_TCL: workaround for broken/non-standard isatty
	on MW Pro6, #include <unistd.h> instead of defining isatty

	* generic/tkPointer.c: MAC_TCL: #include tkMacInt.h

	* generic/tkStubLib.c: MAC_TCL: removed obsolete special casing of mac
	headers, standardize #include'd files to what's done on other platforms

	* mac/tclets.r:
	* mac/tkMacWindowMgr.c:
	* mac/tkMacScrlbr.c:
	* mac/tkMacMenu.c:
	* mac/tkMacMenus.c:
	* mac/tkMacFont.c:
	* mac/tkMacDialog.c:
	* mac/tkMacButton.c: renamed obsolete apple API names to modern
	equivalents; UH3.4 support: added #include <ControlDefinitions.h>;
	fixed munged non-ASCII chars in sources due to bungled latin1<->mac
	roman encoding in CVS repository.

	* mac/tkMacDialog.c: added support for -filetypes option (fix for bug
	tcl #221636); added update event handling for background windows while
	in a NavigationMgr dialog; fixed nasty bug when calling CustomGetFile
	(missing addr operator) (fix for bug tk #220911 & tcl #219367); renamed
	routines conflicting with standard MoreFiles headers (see Tcl ChangeLog
	for details)

	* mac/tkMacApplication.r:
	* mac/tkMacLibrary.r:
	* mac/tkMacResource.r: fixed obsolete copyrights/dates in version
	strings, updated version strings to standard usage, added support for
	'(Support Libraries)' subfolder for shared runtime libraries in
	unmerged binaries, commented out demo setting of "Tcl Environment
	Variables"; reorganized resources among these files to avoid
	multiple copies in applications and shared libraries, the script
	libraries/Xcursors etc are now no longer duplicated in Wish but are
	only included in the resources of Tk.shlb.

	* mac/tkMacMenu.c:
	* mac/tkMacMDEF.r: changes to support MW Pro 6 68k (vers 0x2400 only)
	compiler producing different offset to start of MDEF; fix to static 68k
	presence testing when calling the custom MDEF

	* mac/tkMacWm.c.c:
	* mac/tkMacWindowMgr.c: added/fixed AppearanceMgr checks; override
	AppearanceMgr version detection on static 68k to ensure static 68k Wish
	runs on PPCs with recent AppearanceMgr

	* mac/tkMacButton.c: fixed misplaced/missing variable initialization.

2001-11-20  Jeff Hobbs  <[email protected]>

	* generic/tkText.c (TextGetText): reworked to use DString for
	improved speed. (callewaert, darley)
	(DestroyText): plugged mem leak when not clearing stack (callewaert)
	(TextGetText): more efficient string size calculation (darley)

2001-11-19  Donal K. Fellows  <[email protected]>

	* library/demos/entry3.tcl: New demo showing off validation and
	password entry.

	* library/demos/widget: Some reorganization to make the code
	simpler, plus a new entry demo.

2001-11-17  Jeff Hobbs  <[email protected]>

	* win/tkWinButton.c (TkpComputeButtonGeometry): corrected the
	default size of Windows buttons to conform to the Windows style.
	This changes the default size of buttons on Windows.
	[Patch #463234] (nelson)
	**** POTENTIAL VISUAL INCOMPATABILITY ****

2001-11-16  Jeff Hobbs  <[email protected]>

	* library/menu.tcl: corrected menu traversal code on Unix to
	better handle entering cascades.  [Patch #481219] (oleinick)

2001-11-16  David Gravereaux <[email protected]>

	* win/makefile.vc:  Install target repaired.

2001-11-15  Donal K. Fellows  <[email protected]>

	* library/demos/image2.tcl: Many improvements to this
	image-viewing demo; now uses labelframes and tk_chooseDirectory

	* library/palette.tcl (::tk::RecolorTree): Made this work better
	with CDE, which does some extremely annoying things with the
	option database that interact badly with Tk's way of handling
	options.

	* doc/text.n: Overhauled the documentation of undo to make it
	easier to understand.
	* library/tk.tcl (::tk::EventMotifBindings): Added Emacs-like undo
	binding, but not behaviour (we separate undo and redo.)
	* library/demos/text.tcl: Show off our undo capability!

2001-11-12  David Gravereaux <[email protected]>

	* win/mkd.bat:
	* win/rmd.bat:  Removed -kb CVS attribute and added changes
	from Llyod Lim for better stability.  [Patch #456761]

	* win/rules.vc(new):
	* win/buildall.vc.bat(new):
	* win/makefile.vc:  large rewrite following Tcl's makefile.vc as
	a guide and Patch #456761.  Appears BugFree(tm).

2001-11-12  Jeff Hobbs  <[email protected]>

	* doc/text.n:
	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextTag.c:
	* library/text.tcl:
	* library/tk.tcl:
	* mac/tkMacDefault.h:
	* tests/text.test:
	* unix/tkUnixDefault.h:
	* win/tkWinDefault.h: added TIP #26 implementation of simple
	built-in undo/redo of text editing in the text widget.
	[Patch #458879] (callewaert)

2001-11-12  Donal K. Fellows  <[email protected]>

	* library/demos/menu.tcl: Show off -compound support in menus.

	* library/demos/radio.tcl: Added some code to both show off the
	extra capabilities of the buttons and also show what can be done
	with compound images on the sly.

2001-11-10  Mo DeJong  <[email protected]>

	* unix/Makefile.in:
	* win/Makefile.in: Add "make gdb" target. This target
	can run wish inside either gdb or insight.

2001-11-09  Jeff Hobbs  <[email protected]>

	* library/clrpick.tcl: changed a few parameters so that the full
	0..255 range could be accessed via the mouse. [Bug #478498]

	* unix/configure:
	* unix/tcl.m4: added -lc to AIX libs, fixed path to ldAix

	* win/configure:
	* win/tcl.m4:
	* win/makefile.vc: add comctl32.lib to build libs.
	* win/tkWinX.c (TkWinXInit): added InitCommonControlsEx call.
	* win/rc/tk.rc:
	* win/rc/wish.rc:
	* win/rc/wish.exe.manifest: added resources that specify using v6
	of the MS Common Controls library when available (WinXP+).  This
	enables use of the themeable widgets (like scrollbars) to be used
	in Tk. [Patch #478933]

2001-11-09  Mo DeJong  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: Update from Tcl.

2001-11-08  Mo DeJong  <[email protected]>

	* unix/Makefile.in:
	Avoid adding libc to the LIBS and WISH_LIBS
	variables since it is not needed when linking with CC.
	If required when linking with LD it should be done
	on a case by case basis in tcl.m4.

2001-11-05  Donal K. Fellows  <[email protected]>

	* library/demos/dialog2.tcl: Typo-fix.
	* library/demos/browse, library/demos/ixset, library/demos/rolodex:
	Installation does version number fixup, so we shouldn't.  Thanks
	to [email protected] for pointing these (thankfully minor) problems
	out.

2001-10-30  Donal K. Fellows  <[email protected]>

	* library/demos/widget: Integrated labelframe item into the labels
	section and added a spinbox demo to the (retitled) entry section.

	* library/demos/labelframe.tcl: Adjusted so as to show off the
	labelframe widget to better effect and have a better description.

	* library/demos/spin.tcl: New demo to show off spinbox capabilities.

	* library/demos/rolodex: Changes up-ported from core-8-3-1-branch
	to make the script use more 8.*-isms, but not menus due to the way
	the context help system works.

	* library/demos/ixset: Changed to use the labelframe widget and
	the grid geometry manager.

2001-10-29  Donal K. Fellows  <[email protected]>

	* library/demos/browse: Changes up-ported from core-8-3-1-branch
	to make the script much more robust, particularly when neither the
	current version of wish or the script are on the path.

	* library/demos/hello: Added emacs trailing tag-line.

	* library/demos/tcolor: Changes up-ported from core-8-3-1-branch
	to make the script compliant with current good practise, as well
	as extensive use of the new labelframe widget.

	* library/demos/timer: Changes up-ported from core-8-3-1-branch to
	make the script look and work better.

	* library/demos/rmt: Changes up-ported from core-8-3-1-branch to
	use more 8.* features and make the demo script more generally
	useful to people.

2001-10-23  Donal K. Fellows  <[email protected]>

	* generic/tkCursor.c (Tk_GetCursorFromData): Fixed uninit nextPtr
	field.  [adapted from Patch 473875]
	(GetCursor): Removed double-assignment to nextPtr field.

2001-10-19  Jeff Hobbs  <[email protected]>

	* library/console.tcl: removed transpose ability until the console
	can get a proper rewrite of tag handling.

2001-10-18  Jeff Hobbs  <[email protected]>

	* tests/defs.tcl: removed threaded build warning under X.

	* library/console.tcl (ConsoleOutput): fixed undefined widget
	argument.

2001-10-16  Jeff Hobbs  <[email protected]>

	* library/xmfbox.tcl: fixed filtering in motif file dialog.
	[Patch #469670] (nelson)

	* generic/tkWindow.c (OpenIM): Added simple XIM patch to enable
	basic XIM input on Unix. [Patch #412727] (fabian)

2001-10-15  Jeff Hobbs  <[email protected]>

	* unix/configure:
	* unix/configure.in:
	* win/configure:
	* win/configure.in:
	* win/tkConfig.sh.in: reworked to be a little cleaner in
	comparison to each other, and to AC_SUBST even empty vars for
	win/tkConfig.sh

2001-10-12  Todd M. Helfter <[email protected]>

	* ChangeLog:
	* doc/menu.n:
	* generic/tkMenu.c:
	* generic/tkMenu.h:
	* generic/tkMenubutton.c:
	* generic/tkMenubutton.h:
	* mac/tkMacDefault.h:
	* mac/tkMacMenu.c:
	* mac/tkMacMenubutton.c:
	* tests/menu.test:
	* unix/tkUnixDefault.h:
	* unix/tkUnixMenu.c:
	* win/makefile.vc:
	* win/tkWinDefault.h:
	* win/tkWinMenu.c:
	* win/tkWinWm.c: Implementation of TIP #63, the addition of
	a -compound option to menu entries allowing text and an image to
	be displayed at the same time.

2001-10-09  Jeff Hobbs  <[email protected]>

	* library/console.tcl: added more smarts extracted from tkcon to
	the default console.

2001-10-01  Jeff Hobbs  <[email protected]>

	* win/tkWinTest.c: better error reporting from testclipboard

	* win/tkWinDialog.c: minor cast changes to support Win64

	* win/tkWinWindow.c: made use of standard Tk_GetHWND instead of
	older, private TkWinGetHWND.

	* win/configure: regen'ed
	* win/tcl.m4:
	* win/makefile.vc: updated for Win64 SDK RC1 compilation support

2001-09-30  Peter Spjuth <[email protected]>

	* doc/grid.n:
	* generic/tkGrid.c:
	* tests/grid.test: Added -uniform option to grid's row/column-
	configure. [TIP 37] [Patch 459343]

2001-09-26  Peter Spjuth <[email protected]>

	* win/tkWinFont.c (Tk_DrawChars): Added support for clipping text.

	* doc/frame.n:
	* doc/labelframe.n:
	* doc/toplevel.n:
	* generic/tkFrame.c:
	* generic/tkInt.h:
	* generic/tkWindow.c:
	* library/demos/radio.tcl:
	* library/demos/labelframe.tcl:
	* library/demos/widget:
	* mac/tkMacDefault.h:
	* tests/frame.test:
	* unix/tkUnixDefault.h:
	* win/tkWinDefault.h: Added labelframe widget. Added -padx/y
	options to frame and toplevel.

	* tests/grid.test:
	* tests/pack.test:
	* tests/place.test: Used labelframe to test geometry manager changes.
	[TIP 18] [Patch 429164]

2001-09-26  Peter Spjuth <[email protected]>

	* doc/GeomReq.3:
	* doc/WindowId.3:
	* generic/tk.decls:
	* generic/tk.h:
	* generic/tkDecls.h:
	* generic/tkGeometry.c:
	* generic/tkGrid.c (ArrangeGrid):
	* generic/tkInt.h:
	* generic/tkPack.c (ArrangePacking):
	* generic/tkPlace.c (RecomputePlacement):
	* generic/tkStubInit.c:
	* generic/tkUtil.c (TkComputeAnchor):
	* generic/tkWindow.c (TkAllocWindow):
	* unix/mkLinks: Geometry manager changes to support TIP#18.
	Allows a widget to set different internal border widths on
	different sides, and to set a minimum requested size.
	POTENTIAL INCOMPATIBILITY.  [Patch 429164]

2001-09-25  Don Porter  <[email protected]>

	* generic/tkBind.c:
	* generic/tkInt.decls (TkpScanWindowId):
	* unix/tkUnixPort.h (Tkp{Print,Scan}WindowId):
	* unix/tkUnixXId.c (TkpScanWindowId):
	* win/tkWinWindow.c (TkpScanWindowId): Corrected definition of
	TkpScanWindowId to handle situation where types Window and int
	do not have the same number of bits.  CONST-ified too.

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

2001-09-24  Don Porter  <[email protected]>

	* generic/tkMain.c (StdinProc): Update to handle change in
	return type of Tcl_DStringAppend() from (char *) to (CONST char *).
	[TIP 27]

2001-09-23  Peter Spjuth  <[email protected]>
	* generic/tkPack.c (ConfigureSlaves):
	* tests/pack.test:
	* tests/grid.test:  Pack accepted asymmetric values for -ipadx/y.
	Only -padx/y supports asymmetry. [Bug #462348]

2001-09-21  Jeff Hobbs  <[email protected]>

	* win/tkWinWindow.c (TkpPrintWindowId, TkpScanWindowId): fixed to
	work on Win64 with 64bit XIDs.

	* generic/tkWindow.c (Tk_CreateAnonymousWindow):
	* generic/tkEntry.c (GetSpinboxElement): fixed unreachable returns.

	* win/tkWinX.c (TkGetServerInfo): added recognition of Win64.

	* xlib/X11/X.h: made XID __int64 type for Win64.

	* unix/tkUnixPort.h:
	* mac/tkMacPort.h: add (int*) cast to TkpScanWindowId.
	These may need to be changed to Window* (ulong).

	* generic/tkCmds.c (Tk_WinfoObjCmd):
	* generic/tkBind.c (NameToWindow):
	correct Window id's to be of type Window

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkInt.decls (TkpScanWindowId): changed decl to use
	Window* instead of int*.

	* xlib/xcolors.c:
	* generic/tkPack.c,tkWindow.c:
	* win/tkWinFont.c,tkWinMenu.c:
	* unix/tkUnixScale.c: minor cast fixes to prevent 64bit warnings.

	* tests/scrollbar.test (scrollbar-6.27): marked knownBug because
	it is skewed by bad dimensions returned by Windows.

	* tests/textDisp.test (textDisp-4.12): corrected test to work
	properly on Windows.

	* tests/id.test,macFont.test,macMenu.test,macscrollbar.test:
	* tests/send.test,winClipboard.test,winDialog.test,winFont.test:
	improved use of test constraints

	* win/tkWinWm.c (WinSetIcon): fixed SetClassLong for 64bit support.

2001-09-20  Jeff Hobbs  <[email protected]>

	* unix/configure: regen'ed
	* unix/tcl.m4: added --enable-64bit support for HP-11 with the
	64-bit kernel.

2001-09-17  Don Porter  <[email protected]>

	* generic/tkGrid.c (ConfigureSlaves):
	* generic/tkPack.c (PackAfter):  Corrected type definition of
	argument passed to Tcl_GetStringFromObj() from size_t to int.
	Incorrect type broke [pack] and [grid] on systems where
	sizeof(size_t) != sizeof(int).  [Bugs 462375, 462342, 462338]

2001-09-17  Donal K. Fellows  <[email protected]>

	* library/choosedir.tcl (DblClick):
	* library/tkfbox.tcl (OkCmd, ListInvoke): Rewrote so as to avoid
	the highly confusing string "text" and to be consistent about what
	is and what is not a list.  [Bug 459895, reported by fandom]

2001-09-14  Andreas Kupries  <[email protected]>

	* generic/tkImgGIF.c:
	* generic/tkImgPPM.c:
	* generic/tkImgPhoto.c:
	* generic/tkMenu.c: Applied patch [461578], provided by Vincent
	Darley. This fixes several memory leaks in the image code. They
	happen if there are errors during the initialization of the
	channel the image is supposed to be read from.

2001-09-12  Mo DeJong  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: Update from Tcl.

2001-09-12  D. Richard Hipp  <[email protected]>

	* library/tkfbox.tcl: fixed error that appeared when you would
	click on the canvas while viewing an empty directory.

2001-09-10  Mo DeJong  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: Update from Tcl.

2001-09-09  Mo DeJong  <[email protected]>

	* win/Makefile.in: Fix Windows Makefile so that
	tcltest will automatically be compiled if the
	user tries to build tktest.

2001-09-09  Mo DeJong  <[email protected]>

	* win/Makefile.in: Use TKTEST variable directly
	instead of depending on the tktest alias.

2001-09-08  Mo DeJong  <[email protected]>

	* win/mkd.bat:
	* win/rmd.bat:
	Apply binary property (cvs admin -kb) to files and convert
	to CRLF linefeed format to fix the VC++ build. [Tcl Bug #219409]

2001-08-29  Jeff Hobbs  <[email protected]>

	* tests/menu.test:
	* tests/send.test:
	* tests/select.test: corrected to use testConfig constraints in
	the TK_ALT_DISPLAY case

	* tests/unixSend.test: removed test file completely identical to
	send.test.  Removed platform specific named file in case somebody
	gets send working on Win/Mac in the future.

	* tests/config.test: added config-14.1 to test namespace import
	evaluation of widgets.
	* generic/tkButton.c (ButtonCreate):
	* generic/tkFrame.c (CreateFrame):
	* generic/tkMenubutton.c (Tk_MenubuttonObjCmd):
	* generic/tkPlace.c (Tk_PlaceObjCmd):
	* generic/tkScale.c (Tk_ScaleObjCmd):
	* generic/tkMessage.c (Tk_MessageObjCmd):
	* generic/tkEntry.c (Tk_EntryObjCmd, Tk_SpinboxObjCmd):
	* generic/tkSquare.c (SquareObjCmd): redid the handling of
	optionTables in widgets to allow them to be imported into other
	namespaces. [Bug #456632]

2001-08-28  Jeff Hobbs  <[email protected]>

	* win/tkWinDialog.c (ChooseDirectoryHookProc): work-around for MS
	bug that caused crashing in tk_chooseDirectory on Win95.
	[Bug #224936] (baker)

	* unix/tkUnixWm.c (TkWmRestackToplevel): reworked how
	ConfigureNotify requests were handled in relation to the parent to
	avoid the problem with potential 'raise' delays on some wms.
	[Bug #220260] (baker) wms that were affected should notice the
	difference in tests unixWm-51.* not failing that failed before.

2001-08-26  Don Porter  <[email protected]>

	* library/text.tcl (<Shift-Up> binding):  Corrected TIP 44 typo
	that broke binding.  Thanks to "Michal" for the fix.
	[Bug 455468]

2001-08-23  Jeff Hobbs  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: added QNX-6 build support. [Bug #219410] (loverso)

	* doc/CrtPhImgFmt.3: removed bogus note about including tkPhoto.h

2001-08-22  Peter Spjuth  <[email protected]>

	* generics/tkGrid.c (ConfigureSlaves):
	* tests/grid.test: Fixed a bug where adjacent 'x' and '^' where
	not handled properly. [Bug #452040]

2001-08-22  Jeff Hobbs  <[email protected]>

	* generic/tkPack.c (TkParsePadAmount): added lint init for sepChar.

	* tests/dialog.test (HitReturn): fixed failing dialog-2.1 test
	because it wasn't always getting focus properly.

2001-08-21  Jeff Hobbs  <[email protected]>

	* tests/unixFont.test (unixFont-2.[234]): fixed to be more
	sensitive on systems that have more installed fonts.

	* library/dialog.tcl (tk_dialog): changed dialog to show bar on
	Windows as well and added some y padding between the buttons and
	the bar. [Patch #442835] (harrismh)

2001-08-20  Peter Spjuth  <[email protected]>

	* generic/tkInt.h:
	* generic/tkWindow.c:
	* generic/tkGrid.c:
	* generic/tkPack.c:
	* tests/grid.test:
	* tests/oldpack.test:
	* tests/pack.test: Objectified grid and pack commands.

2001-08-20  Donal K. Fellows  <[email protected]>

	* generic/tkObj.c (TkGetWindowFromObj): Rewrote window code to
	reuse a previously worked-out set of window information exactly
	when the reference window is the same and no window deletions have
	occurred since the object was allocated (display has same epoch
	counter.)  Required changing the internal rep of the window quite
	a bit as now need to save three words-worth of information in the
	internal rep (this window, reference window, display epoch.)
	* generic/tkObj.c (SetWindowFromAny, DupWindowInternalRep)
	(FreeWindowInternalRep): Code to support new internal rep for
	window objects.
	* generic/tkInt.h: Added epoch counter to TkDisplay structure
	* generic/tkWindow.c (GetScreen, Tk_DestroyWindow): Epoch counter
	is incremented every time a window is deleted.

2001-08-18  Peter Spjuth <[email protected]>

	* doc/grid.n:
	* tests/grid.test:
	* generic/tkGrid.c: Grid configure rejected initial "x" and "^".
	[Bug #418664]

2001-08-17  Donal K. Fellows  <[email protected]>

	* generic/tkObj.c (TkGetWindowFromObj): Was failing to reuse
	cached window objects, forcing a call to Tcl_GetStringFromObj and
	Tk_NameToWindow every time.  This fault has been in there for
	nearly three years...

2001-08-15  Don Porter <[email protected]>

	* changes: Labelled the TIP 44 changes as "POTENTIAL INCOMPATIBILITY".
	Although technically internal changes are not incompatible, they'll
	be perceived as such by those who get bitten, and this will help
	them find the cause of their trouble.

2001-08-14  Donal K. Fellows  <[email protected]>

	* generic/tk{Util,Font,Cursor,Color,Bitmap,3d}.c: Modified
	objtype declarations so that they can be picked up in tkObj.c and
	the names are now prefixed with "tk" too.
	* generic/tkObj.c (TkRegisterObjTypes):
	* generic/tkWindow.c (Initialize):
	* generic/tkInt.h: Added code to register Tk's object types with
	the Tcl runtime.  [Tcl Bug 450545]

2001-08-12  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2001-08-10  Donal K. Fellows  <[email protected]>

	* library/demos/image2.tcl (loadDir): Converted non-portable
	[glob [file join $dirName *]] to [glob -directory $dirName *]
	which is both fully portable and more reliable when directory
	names contain glob-significant characters.  [Bug 223313]

2001-08-08  Don Porter <[email protected]>

	* tests/dialog.test:  New file testing [tk_dialog].

	* library/dialog.tcl:
	* library/tkfbox.tcl: Corrections to problems introduced by
	the TIP 44 changes.  [Bug 449261]

	* README:
	* generic/tk.h:
	* unix/configure:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure:
	* win/configure.in: Bumped up patchlevel to 8.4a4 to distinguish
	CVS snapshots from the 8.4a3 release.  This does not necessarily
	mean there will be an 8.4a4 release.  [Bug 448938].

2001-08-07  Jeff Hobbs  <[email protected]>

	* unix/Makefile.in (dist): added {unix,win}/tcl.m4 and
	library/msgs/*.msg to dist target.  [Bug: #448802]

2001-08-06  Jeff Hobbs  <[email protected]>

	8.4a3 RELEASE

	* changes:
	* README: updated for 8.4a3 release

	* unix/configure: regenerated
	* unix/tcl.m4: added GNU (HURD) configuration target. (brinkmann)
	[Patch: #442974]

2001-08-06  Don Porter  <[email protected]>

	* generic/tkConsole.c:
	* generic/tkWindow.c:
	* library/bgerror.tcl:
	* library/dialog.tcl:
	* library/msgbox.tcl:
	* library/unsupported.tcl:
	* mac/tclets.tcl:
	* mac/tkMacHLEvents.c:
	* mac/tkMacWm.c:  TIP 44 changes specific to the Mac and
	Windows platforms that were overlooked before: tkOpenDocument,
	tkConsoleExit, tkConsoleOutput, unsupported1 out of namespace :: .
	Thanks to Vince Darley for prompting another look.

2001-08-03  Jeff Hobbs  <[email protected]>

	* win/winMain.c (WishPanic): fixed CONST changes to go with
	CONST-ification in Tcl.

	* win/configure: regenerated
	* win/tcl.m4: fixed DLLSUFFIX definition to always be ${DBGX}.dll.
	This is necessary for TEA compliant builds that build shared
	against a static-built Tk.
	* win/Makefile.in ($(WISH)): added $(TK_STUB_LIB_FILE) to build
	target, otherwise it wouldn't get generated in a static build.

2001-08-01  Don Porter  <[email protected]>

	* doc/console.n:
	* doc/menu.n:
	* doc/text.n:
	* doc/tkvars.n:
	* generic/tkBind.c:
	* generic/tkMenu.c:
	* library/bgerror.tcl:
	* library/button.tcl:
	* library/choosedir.tcl:
	* library/clrpick.tcl:
	* library/comdlg.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/focus.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/optMenu.tcl:
	* library/palette.tcl:
	* library/scale.tcl:
	* library/scrlbar.tcl:
	* library/spinbox.tcl:
	* library/tclIndex:
	* library/tearoff.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/tkfbox.tcl:
	* library/unsupported.tcl:
	* library/xmfbox.tcl:
	* mac/tkMacMenu.c:
	* tests/clrpick.test:
	* tests/filebox.test:
	* tests/macMenu.test:
	* tests/menu.test:
	* tests/menuDraw.test:
	* tests/msgbox.test:
	* tests/text.test:
	* tests/unixMenu.test:
	* tests/winMenu.test:
	* tests/xmfbox.test:
	* unix/mkLinks:
	* unix/tkUnixDialog.c: Merged changes from feature branch
	dgp-privates-into-namespace, implementing TIP 44.  All
	Tk commands and variables matching tk[A-Z]* are now in the
	::tk namespace.  See "BRANCH: dgp-privates-into-namespace"
	entries below for details.  [FR 220936]

2001-07-24  Mo DeJong  <[email protected]>

	* generic/default.h: Include tkWinDefault.h
	when built with Cygwin or Mingw.

2001-07-18  Don Porter	<[email protected]>

	BRANCH dgp-privates-into-namespace:
	* doc/console.n:  Updated names of private console commands.

2001-07-16  Don Porter	<[email protected]>

	BRANCH dgp-privates-into-namespace:
	* library/console.tcl:
	* library/unsupported.tcl: Renamed tk::histNum to tk::HistNum
	as directed by the Tcl Style Guide.

2001-07-10  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Add AR and STLIB_LD variables.
	* unix/configure:
	* unix/configure.in: Use STLIB_LD when defining MAKE_LIB
	and MAKE_STUB_LIB. Subst STLIB_LD, RANLIB, and AR.
	* unix/tcl.m4: Update from Tcl.
	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl.

2001-07-06  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl.

2001-07-05  Mo DeJong  <[email protected]>

	* win/Makefile.in: Subst DEPARG directly instead
	of relying on a variable. This will make Cygwin
	build faster since an extra exec will be avoided.
	* win/configure: Regen.
	* win/configure.in: Subst DEPARG.
	* win/tcl.m4: Update from Tcl.

2001-07-04  Jeff Hobbs  <[email protected]>

	* README:
	* mac/README:
	* unix/README:
	* win/README: updated READMEs with purls

2001-07-03  Jeff Hobbs  <[email protected]>

	* tests/canvas.test:
	* generic/tkCanvPoly.c (PolygonToArea): Added patch that respects
	the polygon difference of including points in the polygon even
	when fill is empty.  [Bug #226357]

2001-07-03  Mo DeJong  <[email protected]>

	* win/Makefile.in: Remove PATHTYPE variable.
	* win/configure: Regen.
	* win/configure.in: Don't subst PATHTYPE.
	* win/tcl.m4: Update from Tcl.

2001-07-03  Mo DeJong  <[email protected]>

	* win/Makefile.in: Don't use VPSEP, instead just use :
	in the VPATH.
	* win/configure: Regen.
	* win/configure.in: Don't subst VPSEP.

2001-07-03  Donal K. Fellows  <[email protected]>

	* library/xmfbox.tcl (tkMotifFDialog_ActivateSEnt): Added missing
	backslash [Bug #438247]

2001-07-02  Jeff Hobbs  <[email protected]>

	* generic/tkWindow.c (Tk_DestroyWindow): changed to use
	Tcl_EventuallyFree instead of ckfree so that widgets that have
	references to a tkwin can use them.

	* generic/tkCanvArc.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkRectOval.c: corrected argument handling in
	Create<Item> functions that could lead to ABRs or FMRs and
	corrected names of argc/argv to objc/objv.

	* generic/tkImgGIF.c (Mgetc): corrected screwy use of ternary
	operator and possible FMR.

	* generic/tkEntry.c: corrected missing Tcl_Release that caused
	font not freed complaints when trying valid cleanup calls.
	* generic/tkListbox.c: made use of Tcl_Preserve/Tcl_Release to
	prevent FMR errors in Display functions.

	* unix/tkUnixScale.c (TkpDisplayScale): corrected FMR when scale
	was deleted while calling its command.

	* library/console.tcl:
	* library/entry.tcl:
	* library/spinbox.tcl:
	* library/text.tcl:
	* library/tk.tcl: added private ::tk::GetSelection command to
	handle requesting selection.  This is to support requesting
	UTF8_STRING before generic STRING on Unix.  Changed Text, Spinbox,
	Entry and Console to use this command.

	* tests/select.test:
	* generic/tkSelect.c (Tk_CreateSelHandler, Tk_DeleteSelHandler):
	on Unix, a UTF8_STRING handler will be created when the user
	requests a STRING handler (in addition to the STRING handler).
	This provides implicit support for the new UTF8_STRING selection
	target.
	* unix/tkUnixSelect.c (TkSelEventProc, ConvertSelection): Added
	support for UTF8_STRING target. [RFE #418653, Patch #433283]

	* generic/tkInt.h: added utf8Atom to TkDisplay structure.

	* tests/listbox.test: changed 'darkblue' to 'white' in a test
	because it isn't a portable color name.

	* generic/tkEntry.c (DestroyEntry): used Tcl_EventuallyFree
	instead of ckfree for entryPtr to prevent FMRs. [Bug #413904]

2001-06-26  Mo DeJong  <[email protected]>

	* unix/Makefile.in:
	* win/Makefile.in: Add `make shell` target. This target
	will set the proper env vars before invoking wish
	from the build directory.

2001-06-26  Mo DeJong  <[email protected]>

	* win/configure:
	* win/configure.in: Revert cross compiling change
	accidently added during last checkin.

2001-06-26  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Fix last checkin by removing
	export since that only works in bash.
	* win/configure: Regen.
	* win/configure.in: Ditto.

2001-06-26  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Set CFLAGS to "" if the user
	did not set CFLAGS in the env. This keeps AC_PROG_CC
	from adding "-g -O2" to the CFLAGS by default.
	* win/configure: Regen.
	* win/configure.in: Ditto.

2001-06-22  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Use RC_DEFINE flag from tcl.m4.
	* win/tcl.m4: Update from Tcl.

2001-06-22  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl.

2001-06-22  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/tcl.m4 (SC_CONFIG_CFLAGS): Link to the
	imm32 library when building with mingw gcc.
	* win/tkWinX.c: Include the imm.h header
	to fix compiling with mingw gcc.

2001-06-22  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Add resource compiler fix from
	8.3.3 to fix compiling with mingw.

2001-06-22  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/tcl.m4: Fix silly typo in last checkin.

2001-06-22  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@.
	Set LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@. Add LDFLAGS_DEBUG
	and LDFLAGS_OPTIMIZE to match the way CFLAGS_DEFAULT works. Use
	new LDFLAGS variable in the Makefile instead of @LDFLAGS@.
	* unix/configure: Regen.
	* unix/configure.in: Don't set CFLAGS to CFLAGS_DEFAULT, instead
	subst CFLAGS_DEFAULT into the Makefile. Add AC_SUBST for CFLAGS_DEBUG,
	CFLAGS_OPTIMIZE, LDFLAGS_DEFAULT, LDFLAGS_DEBUG, and LDFLAGS_OPTIMIZE.
	Remove unused LD_FLAGS subst.
	* unix/tcl.m4: Update from Tcl.
	* win/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@.
	Set LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@.
	* win/configure: Regen.
	* win/configure.in: Don't set CFLAGS or LDFLAGS, instead subst
	CFLAGS_DEFAULT and LDFLAGS_DEFAULT into the Makefile.
	* win/tcl.m4: Update from Tcl.

2001-06-22  Mo DeJong  <[email protected]>

	* win/configure:
	* win/tcl.m4: Update From Tcl.

2001-06-21  eric melski  <[email protected]>

	* doc/colors.n: Corrected bogus documentation with respect to
	several shades of blue, all of which were listed as RGB 0 0 0.
	[Bug #432104].

2001-06-14  Donal K. Fellows  <[email protected]>

	* library/demos/floor.tcl, library/demos/filebox.tcl,
	* library/demos/clrpick.tcl, library/demos/vscale.tcl,
	* library/demos/twind.tcl, library/demos/ruler.tcl,
	* library/demos/plot.tcl, library/demos/items.tcl,
	* library/demos/hscale.tcl, library/demos/ctext.tcl,
	* library/demos/cscroll.tcl, library/demos/arrow.tcl,
	* library/xmfbox.tcl, library/msgbox.tcl,
	* library/clrpick.tcl, library/bgerror.tcl: Braced expressions.

2001-06-06  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Handle the --prefix option correctly
	it should default to /usr/local like the unix version.

2001-06-03  Jeff Hobbs  <[email protected]>

	* doc/selection.n:
	* doc/clipboard.n: added SEE ALSOs to cross-reference selection
	and clipboard, with extra note for clipboard command in selection
	docs.  [Patch #422256]

	* unix/tkUnixFont.c: Corrected support for iso10646 (X11 Unicode)
	fonts on Unix. This adds a ucs-2be (UCS-2 Big Endian) encoding in
	Tk on Unix that is used for those fonts (X11 requires
	big-endianness). (welch) [Patch #406411; Bug #220890 #220899]
	This differs from the 8.3.3 patch by not adding ucs-2be in the
	preferred encodingList (seems works fine without).
	Added alias for jisx0201* fonts to jis0201 encoding. [Bug #414033]

2001-05-30  Jeff Hobbs  <[email protected]>

	* win/tkWinKey.c (TkpSetKeycodeAndState): removed old debug info

2001-05-29  Jeff Hobbs  <[email protected]>

	* win/tkWinX.c: moved the initialization of tkPlatformId from
	TkWinXInit to TkWinGetPlatformId because static builds could call
	it before it was initialized. [Bug #427278]

2001-05-28  Peter Spjuth  <[email protected]>

	* generic/tkFrame.c:
	* generic/tkWindow.c:
	* tests/frame.test: Upgraded frame to use the newer TK_OPTION
	style when processing configuration options. Some cleanup of
	bad comments and bad code. [part of patch #420861]

2001-05-23  Mo DeJong  <[email protected]>

	* unix/configure:
	* unix/tcl.m4:
	* win/configure:
	* win/tcl.m4: Sync from Tcl sources.

2001-05-21  Jeff Hobbs  <[email protected]>

	* unix/tcl.m4: sync'ed up wih Tcl tcl.m4. [Bug #419812]

	* doc/TkInitStubs.3:
	* generic/tk.h:
	* generic/tkStubLib.c: CONST'ified Tk_InitStubs to match CONST
	changes to Tcl_PkgRequireEx.

2001-05-21  Todd M. Helfter  <[email protected]>

	* doc/menubutton.n:
	* generic/tkMenubutton.c:
	* generic/tkMenubutton.h:
	* mac/tkMacMenubutton.c:
	* tests/menubut.test:
	* unix/tkUnixMenubu.c: Implementation of TIP #11, the addition of
	a -compound option to the menubutton allowing text and an image to
	be displayed at the same time.  This behavior is identical to the
	behavior of the button widget.

2001-05-16  Donal K. Fellows  <[email protected]>

	* doc/console.n: Added - was erroneously placed in Tcl before...

2001-04-25  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.
	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl.

2001-04-25  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/configure.in: Use $@ in MAKE_LIB and MAKE_STUB_LIB
	commands instead of using a delayed subst variable. Replace
	instances of STUB_LIB_FILE with TK_STUB_LIB_FILE.

2001-04-25  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Use TCL_STUB_LIB_FILE instead of STUB_LIB_FILE.
	* unix/configure: Regen.
	* unix/configure.in: Don't subst STUB_LIB_FILE, use TCL_STUB_LIB_FILE
	instead.

2001-04-12  Donal K. Fellows  <[email protected]>

	* generic/tkImage.c (Tk_ImageObjCmd,DeleteImage): Better detection
	of deletion when world is falling apart. [Bug #220819]

2001-04-04  Jeff Hobbs  <[email protected]>

	* win/tkWinMenu.c (TkWinHandleMenuEvent): corrected reseting of
	service mode to only occur when it was set. [Bug #220948]

2001-04-03  Jeff Hobbs  <[email protected]>

	* tests/winClipboard.test: improved results for understanding when
	tests fail.

	* tests/winDialog.test: string totitle'd some results that
	expected [pwd] to return a capital drive letter.

	* tests/cursor.test: changed tests to use 'heart' cursor because
	'arrow' on windows has a pre-skewed use count.

	* win/tkWinDialog.c (GetFileNameA): initialize multi to 0.

2001-04-02  Jeff Hobbs  <[email protected]>

	* win/configure:
	* win/tcl.m4 (SHLIB_LD): added -incremental:no. [Bug #219381]

	* generic/tkMenu.c (TkInvokeMenu): checked for menu deletion
	before calling associated menu entry command.  [Bug #220821]

	* doc/image.n: added warning about names chosen for images.

	* generic/tkImgPhoto.c (ImgPhotoCmd): corrected the src and dest
	values for $imageName put when -format and -to are used.
	[Bug #232741]

	* tests/listbox.test: added test listbox-27.1, delete during
	scrollbar update
	* generic/tkListbox.c (DestroyListbox, ListboxEventProc):
	corrected listbox to make proper use of Tcl_EventuallyFree and
	protect against unusual listbox deletion.

	* tests/entry.test: added tests entry-20.*, delete during widget
	activity
	* generic/tkEntry.c (DestroyEntry, EntryEventProc): fixed the
	entry widget to survive deletion while processing scrollbar
	updates and validation.

	* tests/canvas.test: test of canvas delete during event
	* generic/tkCanvas.c (DestroyCanvas, CanvasEventProc): fixed the
	canvas to survive deletion during event processing. [Bug #228024]

2001-04-01  Jeff Hobbs  <[email protected]>

	* README:
	* mac/README: updated patchlevel to 8.4a3 and corrected links and
	notes.

	* generic/tk.h:
	* unix/configure.in (TK_PATCH_LEVEL):
	* unix/configure:
	* unix/tk.spec:
	* win/configure.in (TK_PATCH_LEVEL):
	* win/configure: updated patchlevel to 8.4a3

2001-03-30  Jeff Hobbs  <[email protected]>

	* tests/safe.test: added note about correcting failures in
	safe.test.
	* library/tk.tcl: moved package require msgcat inside if case to
	not be used in safe interps.

	* win/makefile.vc:
	* win/configure:
	* win/tcl.m4: added imm32.lib to LIBS_GUI for Tk IME support.
	* win/tkWinInt.h:
	* win/tkWinKey.c:
	* win/tkWinX.c: added support for changing IME on the fly in
	Windows (2000).  (lam) [Patch #402993]

	* tests/bind.test (bind-22.18):
	* generic/tkBind.c (NameToWindow): handled the error case where a
	valid-looking but invalid identifier could be passed in certain
	event generate options causing a crash. [Bug #411307]

	* win/tkWinWm.c (UpdateWrapper): ensured that the passed in winPtr
	had an existent window to operate on. [Bug #409172]

	* win/Makefile.in (install-*): improved install-* targets to use
	their base build dependency.

	* generic/tkImage.c (Tk_ImageObjCmd, EventuallyDeleteImage):
	added casts to allow compiling on Windows with debbuging.

2001-03-29  Jeff Hobbs  <[email protected]>

	* library/msgs/de.msg: fixed translations. [Patch #403525]

	* doc/canvas.n: Noted ability to specify coords as a list in the
	docs. (techentin) [Patch #403660]

	* tests/canvas.test: added test case to check obj conversion
	* generic/tkObj.c (UpdateStringOfMM, SetMMFromAny): better
	obj-aware screen distances.  (pgbaum, hobbs) [Patch #403327]

	* library/bgerror.tcl (bgerror): allow focus into details window
	for Windows C&P to work. [Bug #220929]

	* library/tk.tcl: put a catch around adding <hpBackTab> to the
	<<PrevWindow>> virtual event as it doesn't seem to work on all HP
	systems. [Bug #411669]

	* library/tkfbox.tcl: fixed selecting directories and single files
	with spaces using tk_getOpenFile -multiple 1. [Bug #411640]

	* win/tkWinDialog.c (GetFileNameA): added support for -multiple to
	ascii-based tk_getOpenFile (Win9*). (haneef) [Patch #403047]
	(GetFileNameW): increased number of files that could be returned
	by tk_getOpenFile -multiple. [Patch #412042]

2001-03-29  Mo DeJong  <[email protected]>

	* library/entry.tcl (tkEntryMouseSelect):
	* library/text.tcl (tkTextSelectTo): When
	the mouse is dragged with the button down,
	move the insertion cursor to the current
	mouse position.
	* tests/event.test: Add a series of tests
	for event generation. Add tests for selection,
	check the position of the insertion cursor.

2001-03-28  Jeff Hobbs  <[email protected]>

	* unix/configure:
	* unix/tcl.m4: corrected IRIX-5.x config to not use -n32.
	(english) [Patch 403626]

2001-03-28  Don Porter  <[email protected]>

	* tests/focus.test (focus-6.1):
	* tests/macEmbed.test (unixEmbed-5.1):
	* tests/macMenu.test (macMenu-21.3):
	* tests/menu.test (menu-27.1):
	* tests/unixEmbed.test (unixEmbed-8.2):
	* tests/unixWm.test (unixWm-50.4):  Replaced all [load {} tk]
	in Tk test suite with [load {} Tk].  [Bug 220940, Patch 411952]

2001-03-12  Don Porter  <[email protected]>

	BRANCH dgp-privates-into-namespace:
	* doc/menu.n:
	* unix/mkLinks: Added documentation for [tk_menuSetFocus].

2001-03-12  Don Porter  <[email protected]>

	BRANCH dgp-privates-into-namespace:
	* doc/text.n:
	* doc/tkvars.n:
	* unix/mkLinks: Added documentation for commands and variables
	matching tk_text*.

2001-03-08  Don Porter  <[email protected]>

	BRANCH dgp-privates-into-namespace:
	* generic/tkTextDisp.c:
	* library/unsupported.tcl:
	* tests/textDisp.test: Restored the global variables tk_textRedraw
	and tk_textRelayout.  Since they match tk_*, they should remain
	publicly available until at least Tk 9.

2001-03-01  Don Porter  <[email protected]>

	BRANCH dgp-privates-into-namespace:
	* library/unsupported.tcl: New file for Tk's unsupported
	interfaces.  Contains [tk::unsupported::ExposePrivateCommand]
	and [tk::unsupported::ExposePrivateVariable] that restore the
	availability of an old public name of one of Tk's private
	commands and variables, respectively, for those applications
	and extensions that depend on the old names against advice.

2001-02-28  Don Porter  <[email protected]>

	BRANCH dgp-privates-into-namespace:  Feature branch to move all
	of Tk's private commands and variable into the ::tk namespace
	and its children.

	* doc/tkvars.n:  Documented private variable tkPriv renamed tk::Priv.

	* generic/tkBind.c:
	* generic/tkMenu.c:
	* generic/tkTextDisp.c:
	* library/bgerror.tcl:
	* library/button.tcl:
	* library/choosedir.tcl:
	* library/clrpick.tcl:
	* library/comdlg.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/focus.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/optMenu.tcl:
	* library/palette.tcl:
	* library/scale.tcl:
	* library/scrlbar.tcl:
	* library/spinbox.tcl:
	* library/tclIndex:
	* library/tearoff.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl:
	* mac/tkMacMenu.c:
	* tests/clrpick.test:
	* tests/filebox.test:
	* tests/macMenu.test:
	* tests/menu.test:
	* tests/menuDraw.test:
	* tests/msgbox.test:
	* tests/text.test:
	* tests/textDisp.test:
	* tests/unixMenu.test:
	* tests/winMenu.test:
	* tests/xmfbox.test:
	* unix/tkUnixDialog.c:  All Tk commands matching ::tk[A-Z]* and
	all Tk private variables in the global namespace were renamed to
	live in the namespace ::tk or one of its children.

2001-02-13  Eric Melski  <[email protected]>

	* doc/photo.n: [Bug 132213] Added clarification on interpretation
	of ranges for "photoName data -from" subcommand.

2001-02-12  D. Richard Hipp  <[email protected]>

	TIP #21: Asymmetric padding in the pack and grid geometry managers.
	With this changes, you can now say "-padx {10 20}" to put 10 pixels
	of padding on the left and 20 on the right.  Similar rules apply
	for vertical padding.  See the revised documentation for details.

2001-01-02  Andreas Kupries  <[email protected]>

	Everything below belongs together and implements TIP#8 (SF patch#102833)

	* win/tkWinWm.c (line 56f): Added icon structures.
	* win/tkWinWm.c (struct WmInfo, line 242): Added reference to
	optional icon for titlebar.
	* win/tkWinWm.c (struct ThreadSpecificData, line 335): Added
	reference to optional default icon for toplevel windows.
	* win/tkWinWm.c (line 387 ... 1169): All the new functions required
	to deal with icon specifications, 'InitWm' changed.
	* win/tkWinWm.c (TkWmNewWindow, UpdateWrapper, TkWmDeadWindow, Tk_WmCmd):
	Added initialization and handling of the new fields.
	* doc/wm.n: Documentation updated to explain the newly available
	functionality.

2000-12-13  jeff hobbs  <[email protected]>

	* generic/tkObj.c (SetMMFromAny): Added ability to recognize
	double type object to speed up canvas coord calculations.
	[Patch 403327]

2000-12-12  Donal K. Fellows  <[email protected]>

	* doc/entry.n: Improved documentation of interplay between the
	-state and -textvariable options.

2000-11-29  Donal K. Fellows  <[email protected]>

	* tests/image.test (image-1.10): Improved this test, which
	previously only worked if the command failed to delete the root
	window, and caused *major* trouble otherwise...
	* generic/tkImage.c (EventuallyDeleteImage): Created this function
	so that images that get deleted during the creation of an image
	won't cause a nasty core dump.  Properly fixes bug #120819.

2000-11-28  Donal K. Fellows  <[email protected]>

	* doc/image.n:
	* generic/tkImage.c (Tk_ImageObjCmd): Backed out previous change.
	Bug #120819 is back again in force.  Left the test in there
	though.

2000-11-23  Donal K. Fellows  <[email protected]>

	* doc/image.n:
	* tests/image.test (image-1.10):
	* generic/tkImage.c (Tk_ImageObjCmd): Prohibited image names that
	start with "." since they can cause some really obscure crashes.
	Fixes Bug #120819.

2000-11-21  Eric Melski  <[email protected]>

	Overall change:  Implemented TIP 5, which exports
	TkClassProcs/TkSetClassProcs as Tk_ClassProcs/Tk_SetClassProcs,
	adding a size field to Tk_ClassProcs to allow for future
	expansion, and renaming the geometryProc to worldChangedProc,
	which is more in keeping with the actual use of the callback.

	* unix/mkLinks: Added link for Tk_SetClassProcs.

	* doc/SetClassProcs.3: Documentation for
	Tk_ClassProcs/Tk_SetClassProcs.

	* generic/tkCanvas.c:
	* generic/tkEntry.c:
	* generic/tkFrame.c:
	* generic/tkListbox.c:
	* generic/tkMenu.c:
	* generic/tkMessage.c:
	* generic/tkScale.c:
	* generic/tkText.c: Updated to use Tk_ClassProcs/Tk_SetClassProcs
	instead of TkClassProcs/TkSetClassProcs.

	* generic/tkMenubutton.c:
	* generic/tkScrollbar.c:
	* generic/tkButton.c: Updated to use Tk_SetClassProcs instead of
	TkSetClassProcs.

	* generic/tkMenubutton.h:
	* generic/tkScrollbar.h:
	* generic/tkButton.h:
	* win/tkWinButton.c:
	* win/tkWinScrlbr.c:
	* mac/tkMacButton.c:
	* mac/tkMacMenubutton.c:
	* mac/tkMacScrlbr.c:
	* unix/tkUnixButton.c:
	* unix/tkUnixMenubu.c:
	* unix/tkUnixScrlbr.c: Updated to use Tk_ClassProcs instead of
	TkClassProcs.

	* generic/tkDecls.h:
	* generic/tkStubInit.c:
	* generic/tkIntDecls.h: Regenned from tk.decls, tkInt.decls.

	* generic/tk.h: Added declaration of Tk_ClassProcs, with size
	field.  Added typedef's for Tk_ClassCreateProc,
	Tk_ClassWorldChangedProc, Tk_ClassModalProc.  Added definition of
	Tk_GetClassProc macro, shorthand for extracting a member of the
	Tk_ClassProcs structure.

	* generic/tkInt.h: Removed declaration of TkClassProcs,
	TkClassGeometryProc, etc.

	* generic/tkBind.c (Tk_BindEvent): Updated to use Tk_GetClassProc
	macro to extract modalProc; added check that the modalProc is non-NULL.

	* generic/tkFont.c (RecomputeWidgets): Updated to use
	Tk_GetClassProc macro to extract worldChangedProc; added comment
	about the choice of a recursive versus iterative algorithm for
	propagating world changed messages.

	* generic/tkWindow.c (Tk_MakeWindowExist): Updated to use
	Tk_GetClassProc macro to extract createProc from Tk_ClassProcs.

	* generic/tk.decls: Added declaration for Tk_SetClassProcs.

	* generic/tkInt.decls: Commented out declaration for
	TkSetClassProcs, which is made public by this change.  The entry
	is left in place, but commented, so that future developers will
	know not to reuse it's stub number.

2000-11-21  Donal K. Fellows  <[email protected]>

	* doc/ConfigWidg.3: Added deprecation note from Bug #120944 - use
	Tk_SetOption() instead.

	* generic/tkImgPhoto.c (TkPhotoGetValidRegion): Applied patch to
	create this function and add it to tkInt stubs.  Should now be
	possible to write an extension that accesses the transparency data
	in a photo image.  Bug #120930

2000-11-03  Jeff Hobbs  <[email protected]>

	8.4a2 RELEASE

	* generic/tkWindow.c (Initialize): added call to Tcl_SetMainLoop.
	This only has effect when tclsh is run (not wish), and then Tk is
	loaded in interactively.

2000-11-02  Jeff Hobbs  <[email protected]>

	* win/tkWinButton.c:
	* win/tkWinDialog.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWm.c: fixed up code for Win64 support.  This mostly
	remains in _WIN64 #ifdef's, until updated compilers are standard.

	* win/tcl.m4:
	* win/makefile.vc: updated for Win64 compile support

	* unix/configure:
	* win/configure: checked in configure scripts so people doing
	CVS checkouts aren't required to have autoconf.  Changes to
	configure.in in the future will require the corresponding
	configure script to also be re-autoconf'ed and checked in.

	* doc/event.n: added note that key events require window focus.

2000-11-01  Jeff Hobbs  <[email protected]>

	* win/tkWinDialog.c (GetFileNameW, GetFileNameA)
	(Tk_ChooseDirectoryObjCmd): created
	work-around for change in NT5.0/98 that caused no initialdir
	setting to open the browser up in the user's documents dir.

	* tests/color.test: marked color-2.6 nonPortable as we can't
	reliably assume what 'red' maps to.

2000-11-01  Eric Melski  <[email protected]>

	* tests/winDialog.test: Corrected expected results for bad option
	tests (5.2, 5.5) to include -multiple option.

	* win/tkWinDialog.c: Added branch for 0 return from
	CommDlgExtendedError() switches; this was formerly treated as an
	error, but it actually is not, since it just means the user hit
	cancel or closed the dialog.  (GetFileNameW): Added better smarts
	such that -multiple is not considered a valid option for
	tk_getSaveFile.
	Removed CommDlgExtendedError() checks for color and choosedir
	dialogs, and removed all except the explicit invalid filename
	checks for the file dialogs.

2000-10-30  David Gravereaux  <[email protected]>

	* win/configure.in:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/rc/tk.rc:
	* win/rc/tk_base.rc (new):
	* win/rc/wish.rc: Added logic to derive filenames better in the
	resource scripts based on compile options along with better
	support for building a static wish shell with cursor resources.

2000-10-27  Jeff Hobbs  <[email protected]>

	* unix/tcl.m4: added support for AIX-5.

	* tests/tk.test:
	* doc/tk.n: updated to reflect default on status of useinputmethods.
	* library/tk.tcl: tk useinputmethods is set to 1 by default.  This
	enables Kanji and dead-char input by default.  Intro'd in
	1999-12-16 with default off to avoid some problems with older X
	servers that would slow down widget creation over time.

	* win/Makefile.in (test, winhelp, tktest): corrected the
	TCL_LIBRARY path specification.

2000-10-18  Eric Melski  <[email protected]>

	* win/tkWinDraw.c (RenderObject): Applied patch from [Bug: 6368],
	which corrects rendering of 1-pixel wide stippled lines on Windows.

	* generic/tkCanvLine.c (DisplayLine): Applied patch from
	[Bug: 6368], corrects bugs relating to use of active- and
	disabledwidth values for displaying lines (disabledwidth was never
	used, and activewidth/disablewidths would only possibly be used
	when greater than default width, rather than when simply not equal
	to default width).

	* library/tkfbox.tcl (OkCmd): Applied patch from [Bug: 6365],
	which adds safety for directory names containing spaces or which
	are non-lists.

	* win/tkWinDialog.c (GetFileNameW, GetFileNameA)
	(Tk_ChooseColorObjCmd, Tk_ChooseDirectoryObjCmd): Added error
	checking for the return value from the common dialog functions, so
	that the commands will not silently fail if the common dialog
	returns an error. [Bug: 6369].

2000-10-10  Eric Melski  <[email protected]>

	* generic/tkConfig.c (Tk_InitOptions): Added
	Tcl_IncrRefCount/Tcl_DecrRefCount calls on valuePtr, to prevent
	memory leaks when the value object comes from the option
	database.  [Bug: 6275].

2000-10-06  Jeff Hobbs  <[email protected]>

	* win/Makefile.in (cat32.${OBJEXT}): add win/ subdirectory to
	cat32 target to correctly find the source file.

2000-10-05  Eric Melski  <[email protected]>

	* generic/tkCmds.c (Tk_WinfoObjCmd): Added check for
	TK_ANONYMOUS_WINDOW flag in the [winfo children] subcommand; if
	set, the window will not be printed in the list of children.

	* doc/CrtWindow.3: Added entry for Tk_CreateAnonymousWindow.

	* generic/tkWindow.c
	(Tk_CreateAnonymousWindow): New API for creating anonymous
	windows.  These windows are manipulable from C, but not from Tcl,
	because they have no pathname associated with them.  They are used
	initially by widgets that do rubber-band resizing (panedwindow,
	multi-column listbox, etc.), and may be useful for other widgets
	as well (dropbox, combobox).
	(Tk_DestroyWindow): Added check for TK_ANONYMOUS_WINDOW flag when
	determining whether to generate a DestroyNotify event.

	* generic/tkStubInit.c:
	* generic/tkDecls.h: Regen'd from tk.decls.

	* generic/tk.decls: Added Tk_CreateAnonymousWindow declaration.

	* generic/tk.h: Added TK_ANONYMOUS_WINDOW flag for Tk_Window's.

2000-10-04  Eric Melski  <[email protected]>

	* doc/MaintGeom.3: Noted that Tk_MaintainGeometry handles direct
	descendants properly.

	* generic/tkGeometry.c (Tk_MaintainGeometry): Added a check for
	the case in which the slave window is a direct descendant of the
	master window.  In this case, we need not set up the additional
	infrastructure normally provide by Tk_MaintainGeometry, because we
	can rely on the parent/child relationship to handle it for us
	implicitly.  In this case, Tk_MaintainGeometry just calls directly
	to Tk_MoveResizeWindow.  This allows geometry managers to simply
	always use Tk_MaintainGeometry to maintain geometry for slaves,
	and avoid doing the direct descendant check themselves.
	(Tk_UnmaintainGeometry): Added a matching check for the direct
	descendant case; in this case, Tk_UnmaintainGeometry simply
	returns immediately.

2000-10-01  Eric Melski  <[email protected]>

	* generic/tkButton.c (ConfigureButton): Added tests for -compound
	option, so that when there is a textvariable and an image, and
	-compound is not none, the button will display both the
	textvariable and the image.

	* doc/SetOptions.3: Added note that restoreProc and freeProc may
	be NULL.

	* generic/tkConfig.c (Tk_RestoreSavedOptions): For custom options,
	added test that the restoreProc is not NULL, to allow for custom
	options that don't care about supporting Tk_RestoreSavedOptions.

2000-09-29  D. Richard Hipp <[email protected]>

	* generic/tkBitmap.c: Changes to prevent a BadMatch error from the
	Xserver when the same bitmap is used on two or more screens of the
	same display.

	* tests/menu.test: Print a warning if the TK_ALT_DISPLAY environment
	variable is not configured so as to test for the bug fix above.

	* library/tk.tcl (::tk::SetGrabFocus): "Catch" the grab in case
	another application already holds the grab and the "grab" command
	fails.

2000-09-29  Jeff Hobbs  <[email protected]>

	* win/Makefile.in: commented use of TESTFLAGS
	* unix/Makefile.in: added TESTFLAGS to test and testlang targets to
	conform with Windows makefile and TEA style.

2000-09-29  Eric Melski  <[email protected]>

	* generic/tkTest.c: Fixed tests to use updated API.

	* doc/SetOptions.3:
	* generic/tk.h:
	* generic/tkConfig.c: Changed interface for Tk_CustomOptionSetProc
	and Tk_CustomOptionGetProc; these now take a pointer to the start
	of the widget record, and an integer offset to the slot for the
	option value, instead of just a pointer to the slot.  This allows
	more sophisticated options to do interesting things based on other
	data in the widget record.

2000-09-17  Eric Melski  <[email protected]>

	* generic/tk.h: Added declaration of Tk_ObjCustomOption structure,
	used for TK_OPTION_CUSTOM, and typedef's of the functions
	Tk_CustomOptionSetProc, Tk_CustomOptionGetProc,
	Tk_CustomOptionRestoreProc, and Tk_CustomOptionFreeProc, used for
	TK_OPTION_CUSTOM.

	* doc/SetOptions.3: Added documentation of TK_OPTION_CUSTOM, and
	section "CUSTOM OPTION TYPES" explaining how to create and use
	custom options.

	* tests/config.test: Added tests for custom option type.

	* generic/tkTest.c: Added test support for TK_OPTION_CUSTOM to
	TestobjconfigObjCmd.  Added CustomOption* functions to implement a
	test custom option.

	* generic/tkConfig.c: Added new option type TK_OPTION_CUSTOM,
	which allows the definition of custom option types by creating
	parsing, printing, freeing, and restoring procedures for a custom
	option.  This is needed by the text and canvas widgets if they are
	to be fully objectified.

2000-09-07  Jeff Hobbs  <[email protected]>

	* doc/Tk_Init.3:
	* doc/bell.n:
	* doc/loadTk.n: minor doc cleanup

2000-09-06  Eric Melski  <[email protected]>

	* doc/HWNDToWindow.3:
	* doc/GetHWND.3: Changed synopsis to indicate the tkPlatDecls.h
	should be included, not tk.h.

	* generic/tkPlatDecls.h: Removed #include <windows.h> for Windows,
	a better solution for now is to update the docs and have extension
	authors #include <tkPlatDecls.h>.

	* generic/tk.h: Removed '#include "tkPlatDecls.h"', as the
	incorrect inclusion order between windows.h/tkPlatDecls.h causes
	build conflicts on Windows.

	* generic/tkPlatDecls.h: Added #include <windows.h> for Windows,
	so that HWND, etc., are defined properly.

2000-09-06  Jeff Hobbs  <[email protected]>

	* doc/canvas.n: fixed doc bug (ellson). [Bug: 6218]

	* README:
	* generic/tk.h:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in: updated to patchlevel 8.4a2

	* generic/tkMessage.c (MessageWidgetObjCmd): initialized result to
	avoid pedantic warning.

	* generic/tkGrab.c (Tk_GrabObjCmd): changed len arg from size_t to
	int to fix pedantic warning.

2000-09-01  Eric Melski  <[email protected]>

	* win/makefile.vc (install-libraries):
	* win/Makefile.in (install-libraries):
	* unix/Makefile.in (install-libraries): Added tkPlatDecls.h to
	list of header files to install.

	* generic/tk.h: Added #include "tkPlatDecls.h", which declares the
	platform specific component of the public Tk stubs API's.

2000-08-29  Eric Melski  <[email protected]>

	* win/tkWinMenu.c (DrawWindowsSystemBitmap): Use scratchDC
	for determining the source's logical coordinates.  Patch from
	[Bug: 6134 (Markus Oberhumer)].

	* win/tkWinMenu.c (SetDefaults): Compute the indicatorDimensions[]
	under Windows NT/2000 in the same way as under Windows 95/98.
	Patch from [Bug: 6134 (Markus Oberhumer)].

	* win/tkWinFont.c (GetScreenFont): Added a memset() to
	pacify memory checkers.  Patch from [Bug: 6134 (Markus Oberhumer)].

	* library/tkfbox.tcl (::tk::dialog::file::Update): Corrected
	handling of multi-pattern filters (eg, "* *.*"), which was broken
	by the getOpenFile performance patches applied earlier.

2000-08-24  Eric Melski  <[email protected]>

	* doc/toplevel.n:
	* doc/spinbox.n:
	* doc/scrollbar.n:
	* doc/scale.n:
	* doc/menubutton.n:
	* doc/menu.n:
	* doc/listbox.n:
	* doc/entry.n:
	* doc/frame.n:
	* doc/message.n:
	* doc/checkbutton.n:
	* doc/radiobutton.n:
	* doc/button.n:
	* doc/label.n:
	* doc/canvas.n:
	* doc/text.n: Fixed Standard Options section to make best use of
	new tab settings in man.macros.

2000-08-24  Mo DeJong  <[email protected]>

	* unix/README: Update to account for removal of --enable-gcc.
	* unix/configure.in:
	* unix/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option.
	* win/configure.in:
	* win/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option.
	Remove quick hack that provided cross compile support for
	windows builds.

2000-08-23  Jeff Hobbs  <[email protected]>

	* generic/tkButton.c (ButtonTextVarProc): reversed change below,
	it was not correct.

2000-08-22  Jeff Hobbs  <[email protected]>

	* generic/tkButton.c (ButtonTextVarProc): changed order of
	incr/decr of new value object, in case they are equal.

2000-08-18  Eric Melski  <[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoGet): Removed redundant call to
	DitherInstance; this call was formerly being made from
	ImgPhotoGet->ImgPhotoConfigureInstance->DitherInstance, and
	ImgPhotoGet->DitherInstance.  The second call was removed.

2000-08-10  Jeff Hobbs  <[email protected]>

	* doc/SetOptions.3: added missing ')'.

2000-08-09  Eric Melski  <[email protected]>

	* doc/SetOptions.3: Updated documentation to reflect support for
	TK_OPTION_NULL_OK for TK_OPTION_DOUBLE and TK_OPTION_PIXELS.

	* generic/tkConfig.c: Added for TK_OPTION_NULL_OK support for
	TK_OPTION_DOUBLE and TK_OPTION_PIXELS.

	* doc/place.n: Updated, reformatted manual entry.

	* tests/place.test: Added many tests.

	* generic/tkPlace.c (Tk_PlaceObjCmd): Updated to use Tk
	widget-option management facilities to manage place options (-x,
	-y, etc.), which simplifies the placer code.  Added support for
	[place configure pathName] and [place configure pathName -option],
	similar to the behavior of the configure subcommand supported by
	widgets.

2000-08-08  Eric Melski  <[email protected]>

	* tests/place.test: Extended test suite to test error returns from
	[place].

	* generic/tkInt.h: Replaced Tk_PlaceCmd prototype with
	Tk_PlaceObjCmd prototype.

	* generic/tkWindow.c: Updated [place] command entry to use new
	Tcl_Obj interface.

	* generic/tkPlace.c (Tk_PlaceObjCmd): Tcl_Obj'ified [place] command.

2000-08-07  Eric Melski  <[email protected]>

	* generic/tkWindow.c: Updated [selection] command entry to use
	new Tcl_Obj interface.

	* generic/tkInt.h: Replaced Tk_SelectionCmd prototype with
	Tk_SelectionObjCmd prototype.

	* tests/select.test: Updated test suite to recognize standardized
	error messages.

	* generic/tkSelect.c (Tk_SelectionObjCmd): Tcl_Obj'ified
	[selection] command.

2000-08-07  Jeff Hobbs  <[email protected]>

	* doc/cursors.n: changed .SS to more compatible macros.

2000-08-05  Jeff Hobbs  <[email protected]>

	* library/safetk.tcl: rationalized the setting of tk_library when
	initialized Tk in a safe interpreter.

2000-08-03  Eric Melski  <[email protected]>

	* generic/tkWindow.c: Updated "grab" command entry to use
	Tcl_Obj'ified command.

	* generic/tkInt.h: Replaced Tk_GrabCmd prototype with
	Tk_GrabObjCmd prototype.

	* tests/grab.test: Initial suite of tests for [grab] command.

	* generic/tkGrab.c (Tk_GrabObjCmd): Tcl_Obj'ified [grab] command.

	* generic/tkInt.h: Removed Tk_AfterCmd function prototype; the
	function does not exist (since 4.0p3).  Cleaned up some line
	wrapping.

	* generic/tk.h: Removed "#define Tk_AfterCmd Tcl_AfterCmd";
	nothing in the core uses Tk_AfterCmd, and Tcl_AfterCmd doesn't exist
	anymore anyway.

	* generic/tkInt.h: Replace Tk_BindCmd prototype with
	Tk_BindObjCmd prototype.

	* generic/tkWindow.c: Updated "bind" command entry to use
	Tcl_Obj'ified command.

	* generic/tkCmds.c (Tk_BindObjCmd): Tcl_Obj'ified [bind] command.

	* tests/bind.test: Tweaked expected error messages for [bindtags]
	to comply with updated error messages.

	* generic/tkMenu.c (CloneMenu): Replaced calls to Tk_BindtagsCmd
	with equivalent calls to Tk_BindtagsObjCmd.

	* generic/tkInt.h: Replace Tk_BindtagsCmd prototype with
	Tk_BindtagsObjCmd prototype.

	* generic/tkWindow.c: Updated "bindtags" command entry to use
	Tcl_Obj'ified command.

	* generic/tkCmds.c (Tk_BindtagsObjCmd): Tcl_Obj'ified [bindtags]
	command.

2000-08-02  Eric Melski  <[email protected]>

	* generic/tkCmds.c (Tk_TkwaitObjCmd): Tcl_Obj'ified [tkwait] command.

	* generic/tkWindow.c: Updated "tkwait" command entry to use
	Tcl_Obj'ified command.

	* generic/tkInt.h: Replace Tk_TkwaitCmd prototype with
	Tk_TkwaitObjCmd prototype.

	* generic/tkGrid.c (Tk_GridCmd): Split [grid] subcommands into
	separate functions instead of inlining them all in Tk_GridCmd.

2000-08-01  Eric Melski  <[email protected]>

	* generic/tkInt.h: Replaced prototype for Tk_MessageCmd with
	prototype for Tk_MessageObjCmd.

	* generic/tkWindow.c: Marked message command as using the new
	MessageObjCmd instead of the old MessageCmd.

	* tests/message.test: Added tests for the message widget.

	* generic/tkMessage.c: Obj'ified the message widget.

	* generic/tkInt.h: Removed prototype for Tk_ClipboardCmd, added
	prototype for Tk_ClipboardObjCmd.

	* generic/tkWindow.c: Updated function pointers for clipboard
	command to use Tcl_Obj version.

	* tests/clipboard.test: Updated tests to expect standard error
	messages.

	* generic/tkClipboard.c (Tk_ClipboardObjCmd): Obj'ified
	Tk_ClipboardCmd -> Tk_ClipboardObjCmd.

2000-07-28  Eric Melski  <[email protected]>

	* unix/tkUnixButton.c (TkpDisplayButton): Added bits to change
	the indicator color when radio-/check-buttons are disabled.  This
	reduces the visual incongruity when a group of these controls are
	disabled together.

	* win/tkWinMenu.c (ReconfigureWindowsMenu): Added MF_GRAYED bit
	for disabled menu entries, to ensure that those which are drawn by
	the system are shown grayed (such as entries on menubars) [Bug: 4372].

	* doc/label.n: Added -disabledforeground to list of options [Bug:
	6053].

	* mac/tkMacDefault.h:
	* unix/tkUnixDefault.h: Added default values for listbox
	disabledforeground and state.

	* win/tkWinDefault.h: Changed default listbox background color to
	white and listbox selection borderwidth to 0, in keeping with the
	"Microsoft Windows User Experience"; added default values for
	listbox disabledforeground and listbox state.

	* doc/listbox.n: Added documentation for -state option.

	* generic/tkListbox.c: Added support for -state to listbox. [RFE:
	6052].

	* tests/listbox.test: Tests for listbox disabled state.

2000-07-27  Mo DeJong  <[email protected]>

	* win/configure.in: TCL_STUB_LIB_FLAG and
	TK_STUB_LIB_FLAG should not include ${TCL_DBGX}
	in win/tkConfig.sh, fix that.

2000-07-25  Joe English  <[email protected]>

	* doc: CanvPsY.3, ConfigWidg.3, CrtImgType.3, CrtItemType.3,
	FontId.3, GetFont.3, canvas.n, font.n, options.n, text.n:
	Documentation fix: Replaced references to XFontStruct *
	and Tk_FontStruct with Tk_Font.

2000-07-24  Eric Melski  <[email protected]>

	* tests/text.test: Added tests for -regexp -nocase searches with
	backslash character classes.

	* generic/tkText.c (TextSearchCmd): Text search did not work
	properly when -regexp and -nocase were used, in combination with
	backslash character classes represented by capital letters (ie,
	\W, \M); altered implementation of -regexp -nocase searches to use
	new regexp interfaces to fix this problem.  [Bug: 5988].

2000-07-21  Eric Melski  <[email protected]>

	* tests/text.test: Added tests for searching when text is elided.

	* generic/tkText.c (TextSearchCmd): Text search was not returning
	the correct index when the search covered (but did not search)
	elided characters; corrected this by adjusting the match index by
	the number of elided characters preceeding the start of the match,
	just as is done with embedded windows, etc. [Bug: 5470].

2000-07-21  Mo DeJong  <[email protected]>

	* win/configure.in: Add TK_STUB_LIB_FLAG and
	TK_BUILD_STUB_LIB_SPEC. These are needed to build a stub enabled
	extension.

2000-07-20  Eric Melski  <[email protected]>

	* unix/tkUnixDraw.c (TkScrollWindow): Replaced a use of a trinary
	operator with an if/else, to avoid build problems on some
	platforms [Bug: 5819].

	* win/makefile.vc: Applied patch from Don Porter to enhance nmake
	support on NT/Alpha [RFE: 5939].

2000-07-19  Eric Melski  <[email protected]>

	* library/text.tcl: Enhanced <Tab> binding to behave like normal
	<Tab> bindings when the text widget is disabled (ie, it advances
	focus to the next widget).

	* generic/tkText.c (TextSearchCmd): Added a test for a NULL
	segment pointer when doing backwards searches for "" on an empty
	text widget. [Bug: 6007].

2000-07-18  Mo DeJong  <[email protected]>

	* unix/aclocal.m4: Use tcl.m4.

	* unix/configure.in: Properly quote LOCALES variable. Properly quote
	argument to m4 macro.

	* unix/tcl.m4: Add updated file from tcl.

	* win/tcl.m4: Updated file from tcl.

2000-07-18  Eric Melski  <[email protected]>

	* library/tkfbox.tcl: Fixed keyboard navigation in the iconlist.

	* unix/configure.in (MAKE_LIB): Corrected definition of MAKE_LIB
	for shared builds, with patch from Mike Hopkirk.

2000-07-18  Mo DeJong  <[email protected]>

	* win/Makefile.in: Fix TCL_GENERIC_DIR variable
	so that it uses the TK_SRC_DIR in the same way
	as the unix version.

2000-07-17  David Gravereaux  <[email protected]>

	* generic/tkConsole.c: Added comments for a Win2K OS bug with
	GetStdHandle(STD_OUTPUT_HANDLE).  No change was done to the code
	as the resulting behaviour of ShouldUseConsoleChannel() was
	correct, anyways. [BUG: 5971]

2000-07-17  Eric Melski  <[email protected]>

	* generic/tkStubImg.c (Tk_InitImageArgs): Applied patch from [Bug:
	5990], from Anselm Lingnau, which correctly sets the value of
	useNewImage to 0 when the new image system is not to be used,
	instead of leaving it at -1, which causes the check to be
	performed more times than is really necessary.

	* library/bgerror.tcl: Fixed a typo in one of the bgerror dialog
	label.

	* library/msgs/it.msg: Italian message catalog, from Paolo
	Brutti. [RFE: 6012].

2000-07-07  Eric Melski  <[email protected]>

	* library/msgs/el.msg: Greek message catalog, from George Petasis.

2000-07-07  Mo DeJong  <[email protected]>

	* win/configure.in: Fix subst of TK_SHARED_BUILD
	variable in tkConfig.sh.in. Fix definition of
	TK_SRC_DIR variable so that it matches the
	unix version.

2000-07-05  Mo DeJong  <[email protected]>

	* generic/tkFileFilter.c (AddClause): Cast to match function prototype.
	* win/stubs.c (_XInitImageFuncPtrs): Add return value for function.
	* win/tkWinButton.c (buttonStyles, ButtonBindProc, ComputeStyle):
	Remove unused declarations.
	* win/tkWinColor.c (GetColorByName, GetColorByValue): Remove unused
	function declarations.
	* win/tkWinDialog.c (TrySetDirectory): Remove unused function
	declaration.
	* win/tkWinEmbed.c (TkWinEmbeddedEventProc): Cast to match function
	prototype.
	* win/tkWinMenu.c (winMenuMutex, MenuExitProc): Remove unused
	declaration.
	* win/tkWinWindow.c (StackWindow): Remove unused declaration.
	* win/tkWinWm.c (ConfigureEvent): Remove unused declaration.
	* win/tkWinX.c (winXMutex): Remove unused declaration.
	* xlib/ximage.c (XCreateBitmapFromData): Cast to match function
	prototype.

2000-07-05  Eric Melski  <[email protected]>

	* tests/imgPhoto.test: Added test for GIF writing code [Bug: 5823].

	* generic/tkImgGIF.c: Applied patch from Jan Nijtmans to fix a
	problem with the GIF writing code [Bug:	5823].

	* generic/tkCursor.c: Added initialization for nextPtr field of
	TkCursor, patch from Nijtmans/Howlett.

2000-07-05  Eric Melski  <[email protected]>

	* library/msgs/nl.msg: Dutch message catalog for dialogs, from Jan
	Nijtmans.

2000-06-30  Eric Melski  <[email protected]>

	* doc/keysyms.n:
	* doc/colors.n: Added extra .CE/.CS pairs to break up the large
	text block, so that the generated Windows help file could
	accomodate the manual entry. [Bug: 5862]

	* tests/filebox.test: Adjusted tests to accomodate -multiple.

	* library/xmfbox.tcl: Adjusted arguments list construction such
	that -multiple is not presented as an option for tk_getSaveFile.

	* library/tk.tcl: Added test for safe interpreter status before
	attempting to load message catalogs (which is impossible in a
	standard safe interpreter).  This means that SafeTk will not have
	localized dialogs, unless a means is found for loading the message
	catalog files.

2000-06-29  Eric Melski  <[email protected]>

	* library/msgs/de.msg: German message catalog.

	* library/msgs/en.msg: English message catalog.

	* library/msgs/es.msg: Spanish message catalog.

	* library/msgs/fr.msg: French message catalog.

	* unix/Makefile.in:
	* unix/configure.in:
	* library/tk.tcl:
	* library/clrpick.tcl:
	* library/choosedir.tcl:
	* library/console.tcl:
	* library/msgbox.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl:
	* library/bgerror.tcl: Applied patches from Laurent Duperval to
	provide localization of Tk dialogs. [RFE: 2671].

2000-06-27  Eric Melski  <[email protected]>

	* generic/tkMenu.c (DeleteMenuCloneEntries): Applied fix from
	[Bug: 5275], which corrected a segfault-causing indexing problem
	when deleting entries from torn-off menus.

2000-06-22  Eric Melski  <[email protected]>

	* doc/getOpenFile.n: Updated with information about -multiple.

	* library/choosedir.tcl: Tweaked to handle modified tkIconList API's.

	* library/tkfbox.tcl: Preliminary implementation of multiple
	selection; based on patch from [RFE: 604].  Some of the tkIconList
	functions changed to support this and to make the dialog faster.

	* library/xmfbox.tcl: Added support for multiple selection, from
	patch in [RFE: 4999].

2000-06-21  Eric Melski  <[email protected]>

	* library/text.tcl: Corrected behavior of text widget with respect
	to this sequence of events:  click, shift-click.  Previously, the
	shift-click just moved the cursor and anchor; now, the shift-click
	will select the text between the click and the shift-click, which
	is the behavior most users expect. [Bug: 5929].

2000-06-19  Eric Melski  <[email protected]>

	* library/bgerror.tcl: Added auto-truncation for long error
	messages (more than 30 characters wide, or more than 4 lines
	long), so that the dialog remains a manageable size. [RFE: 5782]

2000-06-15  Eric Melski  <[email protected]>

	* win/tkWinDialog.c: Patched to support tk_getOpenFile
	-multiple. [RFE: 604].

2000-06-13  Eric Melski  <[email protected]>

	* win/aclocal.m4:
	* win/configure.in:
	* win/Makefile.in: Applied patch from [RFE: 5844], to provide
	support for the mingw compile environment for Windows.

2000-06-06  Jeff Hobbs  <[email protected]>

	8.4a1 RELEASE

2000-06-03  Jeff Hobbs  <[email protected]>

	* doc/CrtCmHdlr.3: new doc for ClientMessage handler procs
	* generic/tk.h: added typdef for Tk_ClientMessageProc
	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tk.decls: Added Tk_CreateClientMessageHandler and
	Tk_DeleteClientMessageHandler declarations.
	* generic/tkEvent.c (Tk_HandleEvent): Added
	Tk_CreateClientMessageHandler and Tk_DeleteClientMessageHandler to
	allow adding event handlers that invoke for ClientMessage events.
	This is necessary to support unix dnd protocols.

2000-06-02  Jeff Hobbs  <[email protected]>

	* canvas.test: added test for 5783.
	* generic/tkCanvPoly.c (DisplayPolygon): added checks for the
	polygon fillGC not being empty to prevent segfault. [Bug: 5783]

2000-05-31  Eric Melski  <[email protected]>

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

2000-05-30  Eric Melski  <[email protected]>

	* generic/tkImgGIF.c: Changed defines for GIF87a/GIF89a to be
	static char arrays with integer initialization, to address EBCIDIC
	vs. ASCII encoding issues and to handle compilers that don't deal
	with "\xAB" syntax for specifying hex values in strings.

2000-05-28  Jeff Hobbs  <[email protected]>

	* doc/spinbox.n: (new file) docs for spinbox widget
	* generic/tkInt.h: added Tk_SpinboxObjCmd declaration
	* generic/tkEntry.c: added 'spinbox' widget - an extension of the
	entry widget type.
	* generic/tkWindow.c: added 'spinbox' to core Tk commands
	* library/spinbox.tcl: (new file) binding and helper procs for spinbox
	* library/tk.tcl: added spinbox.tcl to list of files to source
	* tests/entry.test: updated changed error messages
	* tests/spinbox.test: (new file) test suite for spinbox

	* generic/tkPlace.c (Tk_PlaceCmd): reworked place master/slave
	table init'n to prevent seg fault when using place on multiple
	displays.

	* generic/tk.h: added comments ot Tk_FakeWin structure

2000-05-26  Eric Melski  <[email protected]>

	* generic/tkOption.c (Tk_GetOption): Extended Tk_GetOption to
	support a new syntax for option names in option tables.  If the
	option name has an embedded ".", it indicates that the name field
	contains both an option name and an overriding widget class, in
	the form "class.option".  The lookup for the option value will be
	performed as though the widget class is that specified, rather
	than the actual widget class.
	(SetupStacks): Replaced several lines of array element copying
	with a for loop for conciseness.

2000-05-25  Eric Melski  <[email protected]>

	* library/button.tcl: Tweaks for -overrelief handling on Windows.

	* doc/radiobutton.n: Added documentation for -overrelief option.

	* doc/checkbutton.n: Added documentation for -overrelief option.

	* doc/label.n: Added documentation for -state option.

	* generic/tkButton.c: Added -overrelief option for checkbuttons,
	and radiobuttons.

	* library/button.tcl (tkButtonDown, macintosh version): Added
	protection against querying the -repeatdelay option from a widget
	that doesn't support it (ie, checkbuttons, radiobuttons, etc).
	Other platforms use a different binding script for checkbuttons
	and radiobuttons, so they don't have this issue.
	(tkCheckRadioEnter, windows version):  Added code to handle
	-overrelief for check/radiobuttons on windows.

2000-05-22  Eric Melski  <[email protected]>

	* generic/tkButton.c: Added -activeforeground, -activebackground
	for labels, for the -state option.

	* doc/label.n: Added documentation for -state option,
	-activeforeground, -activebackground.

2000-05-22  Jeff Hobbs  <[email protected]>

	* win/Makefile.in (install-libraries): corrected to install X
	headers [Bug: 5516]

	* doc/bind.n:
	* doc/canvas.n:
	* doc/entry.n:
	* doc/listbox.n:
	* doc/photo.n: doc fix-ups [Bug: 5396]

2000-05-17  Jeff Hobbs  <[email protected]>

	* doc/bell.n:
	* tests/bell.test:
	* generic/tkCmds.c (Tk_BellObjCmd): added -nice option to
	optionally avoid resetting screen saver [Bug: 4279]

2000-05-15  Jeff Hobbs  <[email protected]>

	* win/tkWinWm.c (Tk_WmCmd): changed wm deiconify from using idle
	callback to calling restack and focus code immediately.

2000-05-17  Eric Melski  <[email protected]>

	Overall change:  Added "-readonlybackground" option for entries,
	to enable a visual change when state goes to readonly.

	* mac/tkMacDefault.h (DEF_ENTRY_READONLY_BG_COLOR)
	(DEF_ENTRY_READONLY_BG_COLOR):
	* win/tkWinDefault.h (DEF_ENTRY_READONLY_BG_COLOR)
	(DEF_ENTRY_READONLY_BG_COLOR):
	* unix/tkUnixDefault.h (DEF_ENTRY_READONLY_BG_COLOR)
	(DEF_ENTRY_READONLY_BG_COLOR): Added default values for entry
	-readonlybackground option.

	* generic/tkEntry.c: Added -readonlybackground option, cleaned up
	excessive use of graphics contexts.

	* tests/entry.test: Added configuration test for
	-readonlybackground option.

	* doc/entry.n: Added documentation for -readonlybackground option.

	Overall change:  changed implementation of "link" relief for
	buttons.  Instead of a new relief style (-relief link), there is a
	new option, -overrelief, which if set is used when the mouse is
	over the button.

	* doc/SetOptions.3: Added information about TK_OPTION_NULL_OK with
	TK_OPTION_RELIEF.

	* win/tkWinButton.c: Removed bits about TK_RELIEF_LINK.

	* tests/button.test: Added tests for -overrelief; removed tests
	for -relief link.

	* mac/tkMacButton.c: Removed bits about TK_RELIEF_LINK.

	* generic/tkOldConfig.c: Removed bits about TK_RELIEF_LINK.

	* generic/tkConfig.c: Removed bits about TK_RELIEF_LINK; added
	support for TK_OPTION_NULL_OK for TK_OPTION_RELIEF.

	* library/button.tcl: Added binding support for -overrelief.

	* generic/tk3d.c (Tk_GetRelief): Added branch for TK_RELIEF_NULL.

	* generic/tkButton.c: Added -overrelief option; removed
	Enter/Leave EventProc masks and handlers.

	* generic/tk.h: Added TK_RELIEF_NULL definition, removed
	TK_RELIEF_LINK.

	* mac/tkMacDefault.h (DEF_BUTTON_OVER_RELIEF):
	* win/tkWinDefault.h (DEF_BUTTON_OVER_RELIEF):
	* unix/tkUnixDefault.h (DEF_BUTTON_OVER_RELIEF): Added default
	value for the -overrelief option.

2000-05-16  Eric Melski  <[email protected]>

	* win/tkWinMenu.c (ReconfigureWindowsMenu): Added code to add the
	MF_SEPARATOR bit for SEPARATOR_ENTRY menu items.  This causes
	separator entries on the system menu to be drawn correctly [Bug: 5451].

2000-05-15  Eric Melski  <[email protected]>

	* doc/image.n: Added documentation for [image inuse] command.

	* tests/image.test: Added tests for [image inuse] command.

	* generic/tkImage.c (Tk_ImageObjCmd): Added [image inuse] command,
	which provides a means for programmers to determine if a given
	image is in use by any widgets. [RFE: 3327].

2000-05-14  Eric Melski  <[email protected]>

	* doc/clipboard.n: Added documentation for "clipboard get".

	* generic/tkClipboard.c (Tk_ClipboardCmd): Added "clipboard get"
	subcommand [RFE: 4628].

	* tests/clipboard.test: Updated to use "clipboard get" instead of
	"selection get -s CLIPBOARD".

	* library/entry.tcl: Adjusted Button-1 binding to set focus to the
	entry when it is readonly or normal.

	* doc/entry.n: Added documentation for readonly state,
	-disabledforeground, -disabledbackground.

	* tests/entry.test: Added tests for readonly state.

	* generic/tkEntry.c: Added support for "readonly" state, and
	redefined "disabled" state.  A disabled entry will display its
	text in a dimmed color and possibly with a different background,
	and will be completely unusable (no selection, no editing).  A
	readonly entry will look like a normal entry, but it will not be
	editable; selection is still allowed. [RFE: 4239].  To support the
	new disabled state properly, "-disabledforeground" and
	"-disabledbackground" options were added.
	*** THIS IS A BACKWARDS INCOMPATIBLE BEHAVIOR CHANGE ***

	* win/tkWinDefault.h:
	* mac/tkMacDefault.h:
	* unix/tkUnixDefault.h: Added DEF_ENTRY_DISABLED_FG,
	DEF_ENTRY_DISABLED_BG_COLOR, DEF_ENTRY_DISABLED_BG_MONO.

2000-05-12  Eric Melski  <[email protected]>

	* unix/tkUnixButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
	* mac/tkMacButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
	* win/tkWinButton.c (TkpDisplayButton, TkpComputeButtonGeometry):
	Added code for drawing compound buttons.

	* tests/button.test: Added configuration tests for -repeatdelay,
	-repeatinterval, -compound.

	* library/button.tcl: Added support for -repeatedelay,
	-repeatinterval options.

	* generic/tkOldConfig.c: Changed handling of link relief so that
	proper error messages are used.

	* generic/tkButton.h: Added -compound, -repeatdelay,
	-repeatinterval options.

	* generic/tkButton.c: Added event watchers for enter/leave events,
	for link relief support.

	* generic/tk3d.c: Changed handling of link relief so that proper
	error messages are used.

	* generic/tk.h: Changed values of
	TK_OPTION_LINK_OK/TK_CONFIG_LINK_OK for link relief support.

2000-05-12  Jeff Hobbs  <[email protected]>

	* win/tkWinFont.c (LoadFontRanges): improved support for all chars
	in 0-255 range for bitmap ANSI fonts.  May be improved to handle
	bitmap non-ANSI fonts in the future. [Bug: 2172]

	* win/tkWinWm.c (RaiseWinWhenIdle): added TK_DONT_DESTROY_WINDOW
	to flag check to prevent timing related core dump. [Bug: 5438]

2000-05-11  Jeff Hobbs  <[email protected]>

	* win/tkWinTest.c (TestclipboardObjCmd): ensured CloseClipboard
	would always get called for each OpenClipboard.

	* tests/focus.test (focusSetupAlt): removed wm withdraw from proc
	as it would cause a hang for tkwait visibility

	* tests/menu.test:
	* generic/tk3d.c:
	* generic/tkColor.c:
	* generic/tkCursor.c: corrected handling of 3DBorder, Cursor and
	Color objects on multiple screens. [Bug: 5454]

2000-05-09  Eric Melski  <[email protected]>

	* doc/button.n: Added documentation for link relief.

	* tests/button.test: Added tests for link relief for buttons.

	* generic/tk.h (TK_CONFIG_LINK_OK): Added definition of
	TK_RELIEF_LINK, TK_OPTION_LINK_OK and TK_CONFIG_LINK_OK. [RFE: 4348]

	* generic/tk3d.c: Added support for link relief. [RFE: 4348]

	* mac/tkMacButton.c (TkpDisplayButton):
	* unix/tkUnixButton.c (TkpDisplayButton): Added support for link
	relief. [RFE: 4348]

	* generic/tkOldConfig.c (Tk_ConfigureWidget):
	* generic/tkConfig.c (DoObjConfig): Added understanding of link
	relief, which is allowed only for widgets that have
	TK_OPTION_LINK_OK or TK_CONFIG_LINK_OK set for the "-relief"
	option. [RFE: 4348]

	* generic/tkButton.c: Added TK_OPTION_LINK_OK to "-relief" option
	for buttons. [RFE: 4348]

	* win/tkWinWm.c (EX_TRANSIENT_STYLE): Removed WS_EX_TOOLWINDOW
	style bit, so that transient windows have full-size titlebars
	(like the tk_getOpenFile dialog).

	* win/tkWinMenu.c (GetMenuSeparatorGeometry): Tweaked height
	requested for separator bars to be (linespace - (2*descent))
	instead of just (linespace); this makes the separator occupy a
	more correct amount of vertical space. [Bug: 5303].

2000-05-09  Jeff Hobbs  <[email protected]>

	* library/focus.tcl: fixed calling of takeFocus proc [Bug: 5372]

2000-05-02  Jeff Hobbs  <[email protected]>

	* README:
	* generic/tk.h:
	* library/tk.tcl:
	* mac/README:
	* unix/README:
	* unix/configure.in:
	* unix/tk.spec:
	* win/README:
	* win/aclocal.m4:
	* win/configure.in:
	* win/makefile.vc: updated patchlevel to 8.4a1

	* unix/Makefile.in: added tk.spec to dist target

2000-04-27  Eric Melski  <[email protected]>

	* doc/Tk_Init.3: Added Tk_SafeInit information [Bug: 1884].

	* doc/keysyms.n: Man page enumerating keysyms [RFE: 1645].

	* doc/colors.n: Man page enumerating valid color names [RFE: 1645].

	* doc/cursors.n: Man page enumerating valid cursor values [RFE: 1645].

	* library/msgbox.tcl: Corrected Unix tk_messageBox implementation
	to make the first button the default when no default is specified
	[Bug: 2218].

	* doc/messageBox.n: Updated documentation with regards to
	selection of default button when none is specified (now it will
	use the first button as the default in that case) [Bug: 2218].

2000-04-26  Jeff Hobbs  <[email protected]>

	8.3.1 RELEASE

	* README:
	* mac/README:
	* unix/README:
	* unix/tk.spec:
	* win/README: Updating URLs to reference dev.scriptics.com

2000-04-25  Jeff Hobbs  <[email protected]>

	* unix/Makefile.in:
	* win/Makefile.in: makefile cleanup

2000-04-25  Eric Melski  <[email protected]>

	* generic/tkMain.c: Fixed function header comment for Tk_MainEx.

	* unix/mkLinks:
	* doc/GetScroll.3: Added information about Tk_GetScrollInfoObj
	[Bug: 1866].

2000-04-24  Eric Melski  <[email protected]>

	* unix/mkLinks:
	* doc/Grab.3: Man page for Tk_Grab and Tk_Ungrab [Bug: 1868, 1889]

	* unix/mkLinks:
	* doc/MainWin.3: Added entry for Tk_GetNumMainWindows [Bug: 1865].

	* unix/mkLinks:
	* doc/GetHINSTANCE.3: Man page for Tk_GetHINSTANCE [Bug: 1862].

2000-04-24  Jeff Hobbs  <[email protected]>

	* generic/tkImage.c (Tk_PostscriptImage): added check to create
	necessary prolog for photos
	* generic/tkCanvPs.c: added Tk_PostscriptPhoto that outputs PS for
	photo images
	* generic/tkImgPhoto.c: new func ImgPhotoPostscript and added that
	in as ps proc in tkPhotoImageType.
	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tk.decls: added Tk_PostscriptPhoto

	* generic/tkConfig.c (DoObjConfig): removed direct setting of
	interp->result.

	* mac/tkMacWm.c (Tk_WmCmd): initialized gotToplevel in
	colormapwindows case (bug found by Reasoning, Inc's automated code
	testing).

2000-04-24  Eric Melski  <[email protected]>

	* unix/mkLinks:
	* doc/GetHWND.3: Man page for Tk_GetHWND [Bug: 1863].

	* unix/mkLinks:
	* doc/HWNDToWindow.3: Man page for Tk_HWNDToWindow [Bug: 1869].

	* unix/mkLinks:
	* doc/AddOption.3: Man page for Tk_AddOption [Bug: 1854]

2000-04-22  Jim Ingham	<[email protected]>

	* mac/tkMacDialog.c (Tk_MacGetOpenFile): Add empty bodies for the
	"-initialfile" and "-defaultextension" options.

	* mac/tkMacDialog.c (NavServicesGetFile): Only cons the result up
	into a list if multiple is true.

	* mac/tkMacMenus.c (SourceDialog): Use the "tk_getOpenFile"
	instead of hand-coding the dialog with StandardGetFile.  This way
	we get the Navigation dialogs for free.

	* doc/getOpenFile.n: Document the -multiple and -message flags
	which are only implemented on the Mac.  Also note that the -title
	works on the Mac with Nav Services installed.

2000-04-19  Eric Melski  <[email protected]>

	* doc/WinViewable.3:
	* unix/mkLinks: Removed docs for Tk_IsViewable.

	* win/tkWinDialog.c: Removed calls to Tk_IsViewable.

	* generic/tkUtil.c:
	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tkCmds.c:
	* generic/tk.decls: Removed Tk_IsViewable function (it was not
	actually needed).

2000-04-19  Jeff Hobbs  <[email protected]>

	* win/aclocal.m4: made SC_PROG_TCLSH search specifically for
	tclsh*.exe type files to find an executable.

	* win/Makefile.in: fixed up cleanup, winhelp, cat32 targets

	* library/console.tcl: made console use systemfixed font on Win

	* generic/tkEntry.c: removed unnecessary ENTRY_VALIDATE #define

2000-04-19  Eric Melski  <[email protected]>

	* generic/tkRectOval.c (ConfigureRectOval): Added checks for valid
	outline settings before creating of outline GC; this means that it
	is really possible now to have an oval or rectangle with no
	outline.  [Bug: 5029].

2000-04-19  Jeff Hobbs  <[email protected]>

	* library/choosedir.tcl (::tk::dialog::file::chooseDir::Config):
	* library/tkfbox.tcl (::tk::dialog::file::Config): removed the
	extraneous glob on -initialdir after file isdir already returned 1
	and moved cd trick into this case as the else already uses [pwd].
	[Bug: 5181]

	* win/winMain.c: moved extern call out of WinMain func

	* README:
	* generic/tk.h:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in: bumped to version 8.3.1

	* library/msgbox.tcl (tkMessageBox): changed to use grid in some
	places, realign icon to anchor nw.

	* mac/tkMacScale.c: reverted tkMacScale.c to 1.5 equivalent (it
	was accidentally bumped forward).

2000-04-18  Eric Melski  <[email protected]>

	* win/tkWinPointer.c: Changed Mod2Mask in TkWinGetModifierState to
	ALT_MASK, to fix some event problems [Bugs: 1160, 5088].

	* win/tkWinX.c: Changed Mod2Mask in GetState to ALT_MASK, to fix
	some event problems [Bugs: 1160, 5088].

	* generic/tkInt.h: Moved definition of ALT_MASK and META_MASK here
	so that it would be accessible from other modules than tkBind.c.

	* generic/tkBind.c: Added code in BindEvent to check for ALT_MASK
	and META_MASK in the event state field, as this field may not be
	set up with the correct display modifier mask bits if the XEvent
	structure was created by [event generate] or by the Windows X
	emulation. [Bugs: 1160, 5088].

2000-04-18  Scott Redman  <redman@HILO>

	* win/tk.rc:
	* win/wish.rc:
	* win/wish.ico:  Modified copyright dates in Windows resource
	files.  Updated the icon for wish.exe.

2000-04-17  Eric Melski  <[email protected]>

	* win/tkWinDialog.c: Added checks for visibility of parent window
	before creating MessageBox and ChooseColor dialogs; this prevents
	the application from locking when the parent is withdrawn and the
	message box is created.  In these cases, the window will be
	created without a parent.

	* unix/mkLinks: Added WinViewable.3.

	* tests/msgbox.test: Added tests for patch from [Bug: 4997].

	* library/msgbox.tcl:
	* library/dialog.tcl: Applied patch from [Bug: 4997]; detaches
	dialog window from parent if parent is not viewable.

	* library/bgerror.tcl: Removed workaround from [Bug: 4370]; this
	is superceeded by patches to dialog.tcl.

	* generic/tkCmds.c: Changed WinfoObjCmd to use Tk_IsViewable
	function to determine visibility of windows instead of inlining
	the code.

	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tk.decls: Added Tk_IsViewable declaration.

2000-04-17  Eric Melski  <[email protected]>

	* library/text.tcl: Tweaked double-/triple-click selection;
	previously, anchor and insert marks were placed in unexpected
	locations following a double or triple click.  Now they are placed
	logically.  Also tweaked the extension of selection via
	shift-double-clicks so that it no longer selects the contiguous
	whitespace on the side of the selection opposite the
	double-click. [RFE: 4253].

	* doc/menu.n: Added note regarding rendering of
	checkbuttons/radiobuttons in menubars on different platforms --
	some systems do not draw indicators for check/radiobuttons in
	menubars.

	* library/menu.tcl: Corrected behavior of
	checkbuttons/commands/radiobuttons in menubars [Bug: 630].

	* tests/grid.test: Added test for [grid propagate . 0] to not toggle.

	* generic/tkGrid.c: Fixed bogus logic in [grid propagate] that
	caused [grid propagate . 0] to act as a toggle instead of an
	absolute set. [Bug: 2286].

2000-04-16  Jeff Hobbs  <[email protected]>

	* win/tkWinColor.c (FindSystemColor): correct calculation of
	colors when shifting value. [Bug: 4919]

2000-04-16  Jim Ingham  <[email protected]>

	* mac/tkMacPort.h: protect against strncasecmp already defined -
	it is in the Pro5 version of MSL.

	* mac/tkMacWindowMgr.c (GenerateKeyEvent): Check for a null tkWin.
	If the hidden window we use for double-buffering controls manages
	to percolate to the top (should never happen, but...) this will
	keep us from crashing.

	* mac/tkMacButton.c (InitSampleControls): Hide the
	double-buffering window BEHIND the first "." window you can find.
	This will keep it from ever being the front window, and thus a
	black hole for events.  * mac/tkMacButton.c (ButtonEventProc):
	Disable the controls when the window is in the background.  This
	is required by the MacOS HIG. This doesn't always get called when
	it should, it still needs more work.

	* mac/tkMacDialog.c: Pretty substantial rewrite to include
	Navigation Services support for systems which have it.

2000-04-14  Eric Melski  <[email protected]>

	* win/tkWinKey.c: Added check for ASCII delete character in
	KeycodeToKeysym, to fix [Bug: 5090].  See comment in code for more
	information.

	* generic/ks_names.h: Added Scroll_Lock and Sys_Req definitions.

	* win/tkWinKey.c: Changed implementation of KeycodeToKeysym,
	et. al., to use a keycode table for lookups; this will result in
	faster keycode -> keysym translations for non-ASCII keys like
	Control, Alt, etc.

2000-04-14  Jeff Hobbs  <[email protected]>

	* win/tkWinWm.c (WmProc): added check in WM_MOUSEACTIVATE so we
	correctly activate native menus when clicking in when we didn't
	have focus [Bug: 2272]

	* generic/tkCanvas.c (CanvasEventProc:2451): corrected cast

	* generic/tkEntry.c (Tk_EntryObjCmd): adjusted finishing error
	cases and changed TK_CONFIG_NULL_OK to TK_OPTION_NULL_OK

	* tests/scale.test:
	* generic/tkScale.c:
	* generic/tkScale.h:
	* unix/tkUnixScale.c:
	* mac/tkMacScale.c: moved (PixelToValue|ValueToPixel|SetScaleValue)
	to tkScale.c.  Caused an associated variable to be immediately set
	[Bug: 4833]

	* library/scale.tcl (tkScaleActivate): reduced number of scale
	redisplays by checking current value of state before setting it
	again.  [Bug: 4191]

	* tests/winDialog.test: tk_chooseDirectory seems to get a noop
	from GetOpenFileName in the static build, hanging some tests.
	The tests were fixed to timeout (noop cause unknown).

	* unix/aclocal.m4 (SC_ENABLE_THREADS): enhanced the detection of
	pthread_mutex_init [Bug: 4359] and (SC_CONFIG_CFLAGS) added
	--enable-64bit-vis switch for Sparc VIS compilation [Bug: 4995]

2000-04-13  Eric Melski  <[email protected]>

	* win/tkWinKey.c: Added smarts to check whether the left or right
	Control, Shift, or Alt key was pressed.  [Bug: 870].

	* win/tkWinMenu.c: Corrected code that created separator items on
	menus; originally, it requested that the system be responsible for
	drawing those items, so it would ignore configuration items like
	the widget background.  Now, we draw the separators ourselves (as
	we do with every other kind of menu item already). [Bug: 1166].

	* win/tkWin3d.c:
	* unix/tkUnix3d.c: Applied patch from [RFE: 2501]: adds more
	sophisticated smarts to TkpGetShadows, so that the highlight of a
	very bright color is actually distinguishable from the color, and
	the shadow of a very dark color is similarly distinguishable from
	the color.

	* generic/tkCanvas.c: Applied patch from [Bug: 4202]; adds a check
	for NULL tkwin in Tk_CanvasEventuallyRedraw.

2000-04-12  Jeff Hobbs  <[email protected]>

	* test/winClipboard.test:
	* win/tkWinInt.h:
	* win/tkWinClipboard.c (UpdateClipboard):
	* win/tkWinX.c (GenerateXEvent): added updatingClipboard tsd and
	TkWinUpdatingClipboard accessor function to allow us to flag
	ourselves when we are the ones updating the clipboard.  This
	corrected inability to create our own clipboard types within a Tk
	application.  [Bug: 2338 4318]
	* win/tkWinTest.c (TestclipboardCmd): improved TestclipboardCmd
	with better error handling and obj'ification

2000-04-11  Eric Melski  <[email protected]>

	* msgcat.n: Added docs for new behavior from patch in [Bug: 4158].

	* msgcat.test: Added tests for new behavior from patch in [Bug:
	4158].

	* msgcat.tcl: Applied patch from [Bug: 4158], which enables
	msgcat::mc to search the entire namespace ancestry chain for
	message translations (ie, first it checks the current namespace,
	then the parent, then the parent's parent, etc).  Also allows the
	specification of additional args for msgcat::mc; if extra args are
	given, the [format] command is used to substitute the additional
	args in the translated message.

	* library/bgerror.tcl: Moved check for withdrawn state after check
	for tkerror; this was causing problems when tkerror was used.

2000-04-10  Eric Melski  <[email protected]>

	* library/bgerror.tcl: Added check for withdrawn state of . and
	unsetting of transient bit for .bgerrorDialog if . is not
	viewable; this protects against the application hanging on systems
	like Windows, where transient windows are withdrawn with their
	parents. [Bug: 4370].

	* tests/event.test: Added test for [event generate $widget
	<Alt-z>] [Bug: 4611].

	* tests/choosedir.test: Changed "namespace import ::tcltest" to
	"namespace import -force ::tcltest".

	* win/tkWinKey.c:
	* unix/tkUnixKey.c:
	* mac/tkMacKeyboard.c: Changed InitKeymapInfo to
	TkpInitKeymapInfo. [Bug: 4611].

	* generic/tkStubInit.c:
	* generic/tkIntDecls.h: Re-gen'd from tkInt.decls.

	* generic/tkInt.decls: Added TkpInitKeymapInfo to list of function
	decls.

	* generic/tkBind.c (HandleEventGenerate): Added code to initialize
	keymap info if necessary, and to correctly set modifier bits in
	XEvent structure create to handle [event generate] calls.
	Previously, the alt/meta bits were not set correctly, so [event
	generate $widget <Alt-z>] would always fail. [Bug: 4611]

2000-04-07  Jeff Hobbs  <[email protected]>

	* generic/tkGrid.c (InitMasterData): fixed uninit'd data in
	GridMaster struct [Bug: 4387]

	* library/safetk.tcl (disallowTk): made disallowTk work in the
	simple case.

	* library/comdlg.tcl (tkFocusGroup_In): fixed key navigation
	problems in dialogs under CDE [Bug: 2960]

	* tests/winDialog.test: removed knownBug constraint from 5.16

	* win/tkWinFont.c (GetScreenFont): corrected adjustment against
	LC_FACESIZE limitation for NT [Bug: 4931]

	* win/makefile.vc (TKTEST_OBJS):
	* win/Makefile.in (TKTEST_OBJS): moved tkWinTest.c from normal
	objs to TKTEST_OBJS where it belonged.

2000-04-03  Jeff Hobbs  <[email protected]>

	* generic/tkTest.c: fixed incorrect platform inclusion for
	TkplatformtestInit (it would never get called).

	* unix/Makefile.in (MAN_INSTALL_DIR): patch to accept --mandir
	correctly [Bug: 4085]

	* library/clrpick.tcl (tkColorDialog_Config): error now thrown
	when -initialcolor "" specified. [Bug: 4198]

2000-03-31  Jeff Hobbs  <[email protected]>

	* doc/DrawFocHlt.3: doc name correction

	* generic/tkEntry.c: set TK_OPTION_NULL_OK bit on -invcmd option
	and removed #ifdef ENTRY_VALIDATE expressions

	* library/menu.tcl (tkMenuInvoke): corrected naming of tearoffs
	[Bug: 4506]

	* library/tkfbox.tcl (tkIconList_Goto): caused browsecmd to be
	called in tkIconList_Select.  This causes the entry to be set
	properly when using the type-in-name-in-listbox bindings.

	* win/tkWinDialog.c: added unicode-aware open/save file dialogs

	* win/tkWinFont.c (TkpFontPkgInit): move private ref to platformId
	to TkWinGetPlatformId

	* win/tkWinMenu.c (SetDefaults): moved private use of versionInfo
	to TkWinGetPlatformId and removed all code for
	(versionInfo.dwMajorVersion < 4) (== Win32s)

	* win/tkWinX.c:
	* win/tkWin32Dll.c: moved TkWinGetPlatformId to tkWinX.c
	* win/tkWinInit.c: added TkWinXInit to TkpInit to ensure that its
	called for static Windows shells. [Bug: 3647]

	* win/tkWinInt.h:
	* win/tkWinX.c:
	* win/tkWinDraw.c (SetUpGraphicsPort):
	* win/tkWinScrlbr.c (UpdateScrollbar): removed use of tkpIsWin32s

	* win/tkWinInt.h (TkWinDCState struct): added bkmode value
	* win/tkWinDraw.c (TkWinGetDrawableDC, et al): added support for
	properly transparent dashed lines on Windows. [Bug: 4617]

2000-03-30  Eric Melski  <[email protected]>

	* generic/tkImgGIF.c: Fixed some ANSI specific bits to avoid
	compile problems with non-ANSI compilers (ie, replace const with
	CONST, etc).  [Bug: 4223].

	* unix/configure.in: Applied patch from [Bug: 4237]; ensures that
	srcdir is fully qualified.

	* unix/Makefile.in: Applied patch from [Bug: 4237]; if tcltest was
	not compiled, make test/tktest failed.  Now it has a rule to build
	tcltest if it has not been built.

2000-03-28  Eric Melski  <[email protected]>

	* library/tkfbox.tcl: Moved an overlooked tkFDialog* function in
	::tk::dialog::file namespace.

	* tests/unixWm.test: Added tests for memory leak conditions in
	tkUnixWm.c.

	* tests/canvas.test: Added test for bad configuration options on
	empty and non-empty canvas.

	* generic/tkCanvas.c: Removed bad code in CANV_CONFIGURE block of
	CanvasWidgetCmd; this was causing non-empty canvases to improperly
	handle bad configuration options [Bug: 4456].

2000-03-27  Eric Melski  <[email protected]>

	* unix/tkUnixWm.c: Applied patch from [Bug: 4405]; fixes memory
	leak in Unix wm command.

2000-03-24  Eric Melski  <[email protected]>

	* tests/filebox.test:
	* tests/choosedir.test: Updated tests.

	* library/xmfbox.tcl: Updated to stash data array in
	::tk::dialog::file namespace instead of in global namespace.

	* library/tkfbox.tcl: Extended some functions to support creation
	of a choosedir dialog, to allow greater code reuse between the two
	dialogs.  Moved tkFDialog* functions into a namespace
	(::tk::dialog::file).  Because these are private Tk functions (and
	should thus not be used directly by users), this should not impact
	anybody (the tk_getOpenFile and tk_getSaveFile commands still
	exist at the global scope).

	* library/tk.tcl:
	* library/tclIndex: Updated function names for tkFDialog*
	functions and choosedir functions.

	* library/choosedir.tcl: New and improved implementation of
	tk_chooseDirectory dialog.  Based on tk_getOpenFile dialog.

2000-03-23  Eric Melski  <[email protected]>

	* generic/tkWindow.c:
	* generic/tkInt.h: Updated Tcl_OptionCmd -> Tcl_OptionObjCmd

	* generic/tkOption.c: Tcl_Obj'ectified the "option" command.

2000-03-22  Eric Melski  <[email protected]>

	* library/listbox.tcl (tkListboxCancel): Added a check for empty
	string value for tkPriv(listboxPrev).  Without this check, it's
	possible to get a stack trace under certain conditions. [Bug: 4373].

2000-03-15  Sven Delmas  <[email protected]>

	* win/tkWinDialog.c: Changed the behavior for the
	tk_chooseDirectory dialog under Windows. Instead of trying to
	return the currently selected listbox entry (which didn't work in
	case the user selected the initial directory anyway), we now
	return the value shown in the entry. This seems to be in
	accordance with the expected behavior for this dialog.

2000-03-14  Eric Melski  <[email protected]>

	* tests/choosedir.test: Marked test 3.1 and 3.2 as bad until the
	issue with those tests on IRIX can be determined.

2000-03-10  Eric Melski  <[email protected]>

	* library/menu.tcl: Applied patch from [Bug: 4155]; protects
	against grabs on non-viewable windows.

2000-03-08  Eric Melski  <[email protected]>

	* tests/choosedir.test: Modified test 3.1 (-mustexist works) to be
	more careful about cleaning up its potentially troublesome after
	events.

2000-03-07  Eric Melski  <[email protected]>

	* tests/button.test:
	* generic/tkButton.c: Added -disabledforeground/-state to labels.

2000-03-07  Jeff Hobbs  <[email protected]>

	* tests/entry.test:
	* generic/tkEntry.c (EntrySetValue): malloc the value when
	validating because validation could cause the pointer to become
	invalid.  Also fixed configure to not trigger focus-based
	validation.  Improved use of Tcl_WrongNumArgs. [Bug: 4320]

2000-03-06  Eric Melski  <[email protected]>

	* library/menu.tcl: Added a check in tkMenuFirstEntry that changes
	menu behavior to only auto-post an immediate child cascade if we
	are currently on a menubar menu.  This prevents massive
	auto-cascading in cases where the first entry of the cascade is
	itself a cascade, and the first entry of that cascade is a
	cascade, and the first entry of that cascade is a cascade
	... [Bug: 676].

	* generic/tkOldConfig.c: Added check for NULL tkwin value in
	Tk_ConfigureWidget [Bug: 4079]

	* generic/tkWindow.c: Added check for NULL tkwin value in
	Tk_NameToWindow [Bug: 4079]

2000-03-02  Jeff Hobbs  <[email protected]>

	* tests/color.test:
	* xlib/xcolors.c (XParseColor FindColor):
	* win/tkWinColor.c (XAllocColor): Fixed bit fiddling for colors to
	return "correct" values for color mapping. [Bug: 4282]

	* unix/Makefile.in (SCRIPT_INSTALL_DIR): removed extraneous '/'
	* unix/aclocal.m4: corrected TCL_NEEDS_EXP_FILE to be 1 for AIX

	* win/tkWinInt.h: change extern to EXTERN for TkWinChildProc
	declaration with extra #defs. [Bug: 4240]

	* library/focus.tcl: fixed tkFocusOK to protect $w in
	uplevel with list. [Bug: 4208]

	* doc/CrtItemType.3: fixed docs for Tk_CreateItemType to reflect
	changes made in 8.3.0 (but old style would still work as well).
	[Bug: 4252]

	* tests/config.test: extra test to check object cleanup when
	destroying the widget
	* generic/tkListbox.c (DestroyListbox): fixed crash in
	DestroyListbox due to null tkwin.  [Bug: 4207]

	* tests/entry.test: added test suite for entry validation
	* doc/entry.n: improved docs discussing caveats and gotchas when
	mixing textvar with widget validation
	* generic/tkEntry.c (EntryValidateChange): improved handling of
	validation with relation to -textvariable.  Previously, it would
	turn off whenever the textvar was set.  Now it will it will turn
	off only when the textvar is set and validation returns 0.  Added
	%V (type of validation occuring) to %-subs to help work with
	trickier validation.

2000-03-01  Eric Melski  <[email protected]>

	* tests/clrpick.test:
	* library/clrpick.tcl: Added code to make color chooser dialog
	inherit screen setting from parent (bug #2334)

2000-02-25  Jeff Hobbs  <[email protected]>

	* win/tkWinWm.c (RaiseWinWhenIdle): Checked for the possibility
	that the window could be destroyed (can occur with
	wm deiconify .toplevel; destroy .toplevel).

2000-02-25  Eric Melski  <[email protected]>

	* generic/tkImgGIF.c: Applied "spirit of" the patch in 1605 (the
	submitted patch was more complicated than necessary and did not
	extend to writing GIF's, only reading), to allow reading/writing
	of GIF files on EBCDIC and other non-ASCII based systems.

2000-02-14  Eric Melski  <[email protected]>

	* unix/tk.spec: RPM specification for producing a binary Tk RPM
	for Linux.

	* unix/Makefile.in: Added rpm target to generate Tk
	binary RPM.

2000-02-10  Jeff Hobbs  <[email protected]>

	8.3.0 RELEASE

	* changes: updated for 8.3.0 release

	* generic/tkImgGIF.c (FileReadGIF): added cast for trashBuffer

	* generic/tkIntXlibDecls.h:
	* generic/tkInt.decls: declared some Xlib emulation calls for
	the Mac

	* generic/tkFrame.c (TkInstallFrameMenu): added extra panic to
	inform user of bad call when framePtr is NULL [Bug: 2530]

	* generic/tkMenu.c (DestroyMenuInstance): Placed checks around
	menu name objects before trying to incr the ref.  [Bug: 3402]

	* generic/tkTest.c: removed USE_OLD_IMAGE def for Mac

	* library/listbox.tcl:
	* library/text.tcl: added support for <4> and <5> for mousewheel
	style scrolling on Unix for mice that map to these buttons.

	* tests/scrollbar.test: fixed check of testmetrics command to
	allow unix tests to run (testmetrics is mac/pc only)

	* unix/tkUnixWm.c (Tk_CoordsToWindow): qualified delete of error
	handler as the goto label is reached from above and below.

	* unix/configure.in:
	* unix/aclocal.m4: cleaned up macros to coincide with tcl.m4,
	added -export-dynamic to LDFLAGS for FreeBSD-3+ [Bug: 2998]

	* unix/README:
	* unix/Makefile.in (dist): removed porting.notes and porting.old
	from distribution and CVS.  The information was very outdated.  Now
	refer to http://dev.scriptics.com/services/support/platforms.html

	* xlib/xgc.c: #def'd out XDrawSegments for the Mac, and added
	some extra include info for the Mac

2000-02-09  Jim Ingham  <[email protected]>

	* mac/tkMacButton.c: Stop removing the appearance window from the
	Window List.  It is not clear why Ray did this, and it causes the
	Appearance manager to crash at random times.

	* mac/tkMacWM.c: Add support in unsupported1 style for the Appearance
	specification of window styles, including floating window support.
	* mac/tkMacWindowMgr.c: Operate on the front non-floating window,
	unless the mouse is directly over the floating window.  Also,
	keystrokes go to the front non-floating window.
	* mac/tkMacAppInit.c: Initialize floating window support.
	* mac/tkMacScrlbr.c:
	* mac/tkMacmenu.c: Fixes for floating windows - operate on the
	FrontNonFloatingWindow.
	* mac/tkMacLibrary.r: Fix typo in File info string.
	* mac/tkMacApplication.r: Fix typo in file info string.  Add
	Finder balloon help for no apparent reason.

	* mac/tkMacSubwindows.c: Change panic in tkMacGetDrawablePort to
	Debugger.  This is only a temporary fix.  The panic is only
	triggered when a safeTk interpreter is torn down, and ignoring it
	does no harm.  I haven't figured out how to avoid it yet, however.
	Also use the Appearance MoveWindowStructure call when available.

	New Files:
	* MW_TkOldImageHeader.h: Handle #defining USE_OLD_IMAGE for tkImgPPM.c.
	* MW_TkTestHeader.h:
	* MW_TkTestHeader.pch:
	* MW_TkHeader.h: Add separate prefix files for test & release
	versions of Tk, so we can just have separate targets w/o having to
	edit files.

	* tclets.r: The D&D Tclets icon in rez form so we can have a
	target for this.

	The above are curtesy of Daniel Steffen ([email protected])

	* tkMacAppearanceStubs.c: Stubs of the Mac Appearance calls I use
	so I can link the static 68K Shell without putting ifdef's all
	over the code.

2000-02-08  Jeff Hobbs  <[email protected]>

	* generic/tk.decls:
	* generic/tkBind.c:
	* generic/tkInt.decls:
	* generic/tkIntDecls.h:
	* generic/tkStubInit.c:
	* mac/tkMacKeyboard.c:
	* unix/tkUnixKey.c:
	* win/tkWinKey.c: Fix for keyboard handling of "dead" keys and
	caps lock from Peter Spjuth. [Bug: 4105 3359 2493]
	Split functions into platform specific files:
	Static functions GetKeySym(), SetKeycodeAndState() and InitKeymapInfo()
	from tkBind.c moved into platform files tkWinKey.c tkUnixKey.c and
	tkMacKeyboard.c.  GetKeySym() and SetKeycodeAndState() renamed to
	Tkp* and made public (as private functions) in tkInt.decls.

	Step 2, fixes in tkWinKey.c
	New static function: KeycodeToKeysym(), based on XKeycodeToKeysym()
	but with different arguments, and a lot of improvements.
	TkpGetString() changed to use KeycodeToKeysym() + other fixes.
	TkpGetKeySym() changed to use KeycodeToKeysym() + other fixes.
	InitKeymapInfo() changed to use KeycodeToKeysym().
	TkpSetKeycodeAndState() rewritten, mostly by copying code from
	XKeysymToKeycode().
	XKeycodeToKeysym() rewritten. Preferably it should be removed.

	EXPLANATION: The main problem is ToAscii() which has a lot of side
	effects, and also that XKeycodeToKeysym() is not provided enough
	input to do a proper job.  The changes' main goal is to avoid
	calling ToAscii() if not necessary, and to provide it with as
	correct information as possible when called.  Also some attempts
	to clean up what ToAscii() did are done.  See the code for details.

	BUGS FIXED: Typing shifted (and AltGr) dead keys did not work.
	Keyboard lock lamps did not work on Win98.
	Events regarding AltGr-keys behaved badly.
	Example: On a Swedish keyboard, $ is typed with AltGr-4.
	That keyboard event would get the keysym '4' not 'dollar'.
	Also, doing [event generete . <Key-dollar>] would send keysym '4'.
	Translation to ascii in TkpGetString did not handle return and
	tab correctly. I.e. [event generate . <Key-Return>] gave wrong %A

	* generic/tkDecls.h:
	* generic/tk.decls:
	* generic/tk.h: moved new public functions created in dash patch
	to the stubs interface [Bug: 4062]

	* generic/tk.h:
	* doc/CrtImgType.3:
	* doc/CrtPhImgFmt.3:
	* generic/tk.h:
	* generic/tkImgGIF.c:
	* generic/tkImgPhoto.c:
	* generic/tkStubImg.c (new file):
	* generic/tkTest.c:
	* unix/Makefile.in:
	* win/Makefile.in:
	* win/makefile.vc: improved support for moving from the old style
	image C API to the new obj'ified one with new Tk_InitImageArgs
	command and stub'ing of image code.  See docs for how to make the
	transition. [Bug: 4060]

	* library/tk.tcl: wrapped check for tcl_platform(os) around info
	exists because it won't in safe interpreters

	* win/tkWinFont.c: corrected symbol font use to only work on 8-bit
	characters [Bug: 2406]

	* unix/aclocal.m4: changed all -fpic to -fPIC

	* README:
	* unix/configure.in:
	* win/configure.in:
	* generic/tk.h (TK_RELEASE_SERIAL): Moved to 8.3.0 patchlevel

2000-02-07  Eric Melski  <[email protected]>

	* library/tkfbox.tcl: Applied patch from bug #4117,
	tk_getOpenFile/getSaveFile doesn't do the right thing when user
	types a directory name in the entry and a default extension is
	specified.

2000-02-05  Jeff Hobbs  <[email protected]>

	* unix/tkUnixScale.c (TkpDestroyScale): changed ckfree to
	Tcl_EventuallyFree to behave with Tcl_Preserve in TkpDisplayScale
	(prevents possible segfault).

2000-02-03  Eric Melski  <[email protected]>

	* tests/canvText.test: test for fix for bug #2525.

	* generic/tkFont.c (Tk_ComputeTextLayout): Was erroneously setting
	the width of newline-only text display chunks to some arbitrary
	huge number, instead of 0; this was interfering with things like
	the canvas find enclosed feature. (bug #2525).

	* tests/text.test:
	* generic/tkText.c (DumpLine/DumpSegment): Changed DumpSegment to
	take a TkTextIndex instead of two integer offsets, so that it
	could use TkTextPrintIndex to format the offsets into an index,
	which makes it UTF smart (bug #2582).

2000-02-01  Eric Melski  <[email protected]>

	* library/tk.tcl:
	* library/tclIndex:
	* library/choosedir.tcl: Moved choosedir functions into the
	::tk::dialog::chooseDir namespace instead of a toplevel
	::tkChooseDirectory namespace.  Additional cleanup on the
	chooseDir dialog.

2000-02-01  Jeff Hobbs  <[email protected]>

	* doc/text.n: clarified docs on what happens during a search with
	-count when images/windows are embedded

	* win/Makefile.in (install-*): reduced verbosity of install

	* win/tkWinPixmap.c (XGetGeometry): added support for windows in
	XGetGeometry [Bug: 4069]

	* win/tkWinFont.c (GetScreenFont): fixed possible mem overrun with
	long font names [Bug: 4108]

	* win/tkWinDialog.c: added EnableWindow calls to dialogs to
	correct for possible loss of control in parent Tk toplevel
	[Bug: 1212 et al]

	* generic/tkRectOval.c (ConfigureRectOval):
	* generic/tkCanvLine.c (ConfigureLine):
	* generic/tkCanvPoly.c (ConfigurePoly):
	* generic/tkCanvArc.c (Configure/DisplayArc): fixed handling for
	negative dash values [Bug: 4104]

	* generic/tkScale.c (TkRoundToResolution): fixed incorrect
	assumption that (N+1)*delta = N*delta + delta with floating point
	math [Bug: 3689, 4099]
	(DestroyScale) Fixed check for cancelling TkpDisplayScale (was
	REDRAW_ALL, is now REDRAW_PENDING)

	* tests/listbox.test: corrected test case for listbox itemconfigure

	* unix/aclocal.m4: added *BSD ELF recognition for
	SHARED_LIB_SUFFIX determination (from Tcl's tcl.m4)

2000-01-27  Eric Melski  <[email protected]>

	* generic/tkImgPhoto.c: Removed unneccesary object translation in
	MatchStringFormat (bug #4103).

2000-01-27  Eric Melski  <[email protected]>

	* generic/tkImgGIF.c: Additional code cleanup (now we only have
	one decoder!  neat!)

2000-01-26  Eric Melski  <[email protected]>

	* doc/getOpenFile.n:
	* doc/chooseDirectory.n: Man page/cross links for
	tk_chooseDirectory (bug #1786).

	* library/tk.tcl:
	* library/tclIndex: Added hooks for tk_chooseDirectory. (bug #1786)

	* library/choosedir.tcl: tk_chooseDirectory implementation for
	Unix/Mac (bug #1786).

	* generic/tkImgPhoto.c: Added some comments regarding slow
	processing of transparent images.

	* generic/tkImgGIF.c: Improved GIF decoder for ~60% speed
	increase.  Added some comments on how to further improve the
	implementation, time permitting.

	* doc/photo.n: Added a description of what the -data string can
	contain (base64 or binary data).

	* generic/tkImgPhoto.c: Fixed bug with use of binary data for
	"-data" option to "image create" command.

2000-01-21  Eric Melski  <[email protected]>

	* library/tkfbox.tcl: Fixed bug relating to incorrect parent
	values for error message boxes displayed by the file dialog (bug
	#3616).

	* tests/text.test:
	* generic/tkText.c: Fixed bug relating to regexp searching for
	empty lines; previously, the starting line was ignored. (bug #1643).

2000-01-20  Jeff Hobbs  <[email protected]>

	* library/text.tcl: fixed double-click selection behavior where
	there were embedded windows/widgets in the same line. [Bug: 3989]

	* win/tkWinWm.c (TkWmProtocolEventProc): cached atom name as the
	window could get destroyed during eval [Bug: 2513]

	* generic/tkCanvLine.c (LineCoords): fixed segfault when too few
	coords were passed to a line with certain options set (it should
	always have thrown an error anyway). [Bug: 4042]

	* tests/text.test:
	* generic/tkText.c: fixed missing " in error case and missing
	'dump' in subcommand listing [Bug: 4036]

	* generic/tkListbox.c: adjusted use of basic string concatenation
	in (non-K&R behavior) [Bug: 4027]
	Swapped bg/fg class for -select(bg|fg) for listbox and their
	items [Bug: 4039]

	* unix/mkLinks:
	* doc/WindowId.3: added docs for Tk_IsContainer and Tk_IsEmbedded

	* doc/text.n: clarified mark gravity definition and usage of
	``word'' in binding definitions.  [Bug: 2004 2277 1388]

	* generic/tkInt.h: moved new TkDisplay useInputMethods structure
	element to end to not disturb position of previous elements in
	the structure (as compared to Tk <=8.2).

2000-01-20  Eric Melski  <[email protected]>

	* tests/grid.test: Added a test for the consecutive ^ and multiple
	widget case (bug #1386).

	* generic/tkGrid.c: Fixed interpretation of consecutive ^
	characters in grid command.  Previously, ^ ^ was interpreted as
	meaning that there must be a 2-column widget above to extend,
	neglecting the case where there was actually 2 1-column widgets
	above.  Now, ^ ^ is interpreted as a possible width; the gridder
	will consume as many ^'s as there are columns in the widget, and
	leave the rest for the extension of other widgets.  (bug #1386).

2000-01-19  Eric Melski  <[email protected]>

	* library/tk.tcl: Created a virtual event <<PrevWindow>> for
	reverse tab traversals, with one default binding <Shift-Tab>, and
	OS specific bindings for Linux, HP-UX, and IRIX. (bug #3163)

2000-01-13  Jeff Hobbs  <[email protected]>

	* changes: updated changes file to reflect 8.3b2 mods
	* README:
	* generic/tk.h:
	* unix/configure.in:
	* win/configure.in: updated to patchlevel 8.3b2

	* win/tkWinWm.c: added visibility event handler to make sure
	that transient window wrappers would be updated when the master
	was initially mapped.

2000-01-12  Jeff Hobbs  <[email protected]>

	* tests/text.test: changed test to reflect change of -hidden
	to -elide in search options.

	* win/tkWinScrlbr.c: added check for valid hwnd in ModalLoopProc
	to avoid crash when building statically

	* doc/event.n:
	* generic/tkBind.c: prevented core with event -warp on Windows
	when window wasn't mapped [Bug: 4004] and added docs stating
	the requirement for mapped windows.

	* generic/tkCanvas.c: fixed mem leak with TagSearchExprInit
	[Bug: 3977]

	* generic/tkStubInit.c:
	* generic/tkDecls.h: remove non-existent
	Tk_(Get|Create)CanvasVisitor prototypes

	* generic/tkText.c:
	* generic/tkEntry.c: fixed cursor to not blink when widget was
	disabled [Bug: 1807]

	* generic/tkRectOval.c: added note about change to bloat for
	RectOval bounds calculation for WIN32 only

	* library/dialog.tcl: improved handling of $default arg to allow
	for name of given button, as well as bounds checking

	* doc/wm.n:
	* tests/winWm.test:
	* tests/unixWm.test:
	* mac/tkMacWm.c:
	* unix/tkUnixWm.c: fixed possible X error being raised [Bug: 3377]
	* win/tkWinWm.c: wm deiconify in zoom state [Bug: 2077],
	fixed possible flashing of unmapped toplevel in deiconify [Bug: 3338]
	and fixed mapping of transient window [Bug: 572]
	Also, for all wm's, extended 'wm state' command to allow setting
	of the state, and added official support of 'zoomed' state on Win.

	* unix/aclocal.m4: strtod bug on Tru64 [Bug: 3378]

	* unix/Makefile.in: added tests to prevent unnecessary chmod +x
	in source dirs while installing [Bug: 3367]

	* unix/configure.in: properly sub'ed in TK_SHARED_BUILD [Bug: 3385]

2000-01-05  Jeff Hobbs  <[email protected]>

	* doc/text.n:
	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextTag.c: removed the -state option for text tags,
	and reoriented it around -elide, as -state disabled was never
	implemented, and -state hidden is better as -elide.

	* mac/tkMacClipboard.c: fixed i18n problems with clipboard [Bug: 3544]

	* library/entry.tcl:
	* library/focus.tcl:
	* library/listbox.tcl:
	* library/scale.tcl:
	* library/scrlbar.tcl:
	* library/tearoff.tcl:
	* library/text.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl: fixed unprotected arg parsing through eval/after
	[Bug: 3943]

	* unix/Makefile.in: added unix/aclocal.m4 to distribution [Bug: 3938]
	* unix/aclocal.m4: changed NetBSD SHLIB_CFLAGS from -fpic to -fPIC

	* win/tkWinImage.c: added static declaration to function

1999-12-22  Jeff Hobbs  <[email protected]>

	* changes: updated changes file

	* generic/tkScale.c:
	* generic/tkScale.h:
	* mac/tkMacScale.c:
	* unix/tkUnixScale.c: fixed potential segv from patch in 3897

	* tests/unixWm.test: nonPOrtable -> nonPortable

1999-12-21  Jeff Hobbs  <[email protected]>

	* generic/tk.h:
	* unix/configure.in:
	* win/configure.in:
	* win/aclocal.m4:
	* README: updated for patch level 8.3b1

	* unix/tkUnixWm.c: fixed panic in Tk_CoordsToWindow to print error
	and continue instead (for Tix) [Bug: 716 et al]

	* scale.test:
	* generic/tkScale.c:
	* generic/tkScale.h: fixed possible core when freeing options
	(cursor) associated with scale widget [Bug: 3897]

	* doc/MeasureChar.3: fixed docs for Tk_MeasureChars to reflect code
	* doc/listbox.n: fixed formatting problem

	* generic/tk3d.c: added extra calculations to ensure that thin
	frames get refreshed too [Bug: 3596]

	* unix/tkUnixMenu.c:
	* unix/tkUnixFont.c:
	* generic/tkCanvText.c:
	* generic/tkEntry.c:
	* generic/tkFont.c:
	* generic/tkImgPPM.c: removed extranneous vars that were set but
	never used.

	* mac/tclMacHLEvents.c: fixed applescript for I18N [Bug: 3644]

	* unix/aclocal.m4: removed -O flag for AIX when using the IBM
	compiler (several versions have a bug that crops up in the text
	widget). [Bug: 2316]

	* unix/Makefile.in: removed extra slash in SCRIPT_INSTALL_DIR
	[Bug: 3896]

	* library/listbox.tcl: added extra checks for existence of
	tkPriv(listboxSelection) before it was used. [Bug: 3892]

1999-12-16  Jeff Hobbs  <[email protected]>

	* doc/GetCursor.3:
	* win/tkWinCursor.c: added support for Windows cursors to
	TkGetCursorByName (.ani, .cur) using -cursor @<filename>
	(Ascher) [Bug: 1350]

	* win/tkWinWm.c: fixed 'wm deiconify' to update position of the
	toplevel if event is waiting before mapping. (Mao) [Bug: 3687]
	This removes the need for 'update idle' before 'wm deiconify' on
	Windows.

	* doc/listbox.n: added doc for <<ListboxSelect>> [Bug: 3500]

	* doc/getOpenFile.n: removed note that -initialfile didn't work
	for tk_getOpenFile
	* library/tkfbox.tcl: updated tk_get*File to better match the
	Windows file box it emulates, give proper support to -initialfile,
	and fixes lack of global tkPriv call.  [Bug: 3735 3882]

	* doc/tk.n: added doc for 'tk useinputmethods ...'
	* tests/tk.test:
	* unix/tkUnixKey.c:
	* generic/tkCmds.c:
	* generic/tkEvent.c:
	* generic/tkWindow.c:
	* generic/tkInt.h: add 'tk useinputmethods ?-display win? ?bool?'
	call to provide support for disabling/enabling the use of XIM on
	X.  This was previously all done at compile time, and always on.
	Now it is turned off by default, even when available, and the user
	must turn it on to use XIM (per display).

	* generic/tkCanvUtil.c: fixed bug in Tk_CanvasPsOutline that freed
	mem it shouldn't.

	* generic/tkFont.c: added "bitstream cyberbit" (popular Windows
	CJK font) to list of font fallbacks. (kenny) [Bug: 2407]

	* mac/tkMacMenu.c: finished bug 3075 by changing the char values of
	what was checked (verified correctness on Mac).

1999-12-13  Jeff Hobbs  <[email protected]>

	* doc/canvas.n: added docs for items added by dash patch (-*dash*,
	-state, -active*, -disabled*, -offset, essentially rewrote the
	man patch for completely updated 8.3 canvas widget.
	* doc/entry.n: added docs for entry widget validation
	* doc/event.n: added docs for -warp
	* doc/text.n: doc'ed new -state value 'hidden'
	* doc/GetDash.3: (new file) man page explaining Tk_GetDash
	* generic/tkStubInit.c:
	* generic/tkDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkInt.decls: added XSetDashes and XWarpPointer
	* generic/tk.decls: added Tk_CreateSmoothMethod, and reserved
	two spots
	* generic/tk.h: added Tk_SmoothMethod struct,
	state item to canvas record, #defines for item state,
	support for using old char*-based canvas item C creation
	procedures with -DUSE_OLD_CANVAS,
	Tk_Dash, Tk_TSOffset (-offsets) & Tk_Outline structs and #defs,
	decls for dash, outline and postscript routines
	* generic/tkBind.c: added support for Quadruple clicks, and added
	the -warp option to 'event' with pointer warping routines
	* xlib/xgc.c:
	* generic/tkRectOval.c:
	* generic/tkCanvArc.c:
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvPs.c:
	* generic/tkCanvText.c:
	* generic/tkCanvUtil.c:
	* generic/tkCanvWind.c:
	* generic/tkCanvas.c:
	* generic/tkCanvas.h: Canvas and items received overhaul to with
	the addition of the dash patch (Nijtmans, et al)  This includes
	objectification of the 'canvas' command, as well as support for
	(where appropriate) dashes in items, extended stipple support,
	state for all items, and postscript generation of images and
	windows.  See the new canvas man page for related docs.
	* generic/tkEntry.c: added entry widget validation, see entry.n
	* generic/tkEvent.c: on simulated events, ButtonPress should
	be matched with ButtonRelease to be correct
	* generic/tkFont.c: corrected possible null reference
	* generic/tkFrame.c: made frame a Tcl_Obj based command
	* generic/tkGet.c: added TkGetDoublePixels
	* generic/tkImage.c: bug fixes from Img patch and new
	Tk_PostscriptImage and Tk_SetTSOrigin functions
	* generic/tkImgBmap.c: new ImgBmapPostscript function
	* generic/tkImgPhoto.c: new Tk_CreatePhotoOption, Tk_DitherPhoto
	* generic/tkInt.h: declarations for some new functions
	* generic/tkMessage.c: reworked relief drawing
	* generic/tkOldConfig.c: added TK_CONFIG_OBJS so old style
	ConfigureWidget calls can pass in Tcl_Obj arrays
	* generic/tkScrollbar.c:
	* generic/tkScrollbar.h: made -orient use an option table
	* generic/tkText.c:
	* generic/tkText.h: made -wrap and -state use option tables
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextMark.c:
	* generic/tkTextTag.c:
	* generic/tkTextWind.c: added support for -elide and -state hidden
	* generic/tkTrig.c: changed TkMakeBezierCurve to support returning
	the upper limit of points needed for spline
	* generic/tkUtil.c: new option table parsing routines
	* generic/tkWindow.c: init'ing of warp stuff, mouseButtonState

	related bug ids for the fixes:
	[Bug: 648 1541 1540 1779 2168 2311 2297 2340 2348 2578 3386]

	* tests/bind.test:
	* tests/canvImg.test:
	* tests/canvPsArc.tcl:
	* tests/canvPsImg.tcl: (new file)
	* tests/canvRect.test:
	* tests/canvText.test:
	* tests/canvas.test:
	* tests/defs.tcl:
	* tests/entry.test:
	* tests/event.test:
	* tests/font.test:
	* tests/frame.test:
	* tests/imgPhoto.test:
	* tests/safe.test:
	* tests/scale.test:
	* tests/scrollbar.test:
	* tests/select.test:
	* tests/text.test:
	* tests/textDisp.test:
	* tests/textTag.test:
	* tests/unixFont.test:
	* tests/unixWm.test:
	* tests/visual_bb.test:
	* tests/winClipboard.test: tests for the dash patch changes

	* unix/mkLinks: added GetDash.3 into the mkLink step

	* mac/tkMacDraw.c: mac still needs pointer warping routine
	* mac/tkMacXStubs.c:
	* win/tkWinDraw.c:
	* win/tkWinPointer.c: added support for pointer warping and
	platform specific support for dash patch items

1999-12-12  Jeff Hobbs  <[email protected]>

	* generic/tkText.c: fixed bug in TextSearchCmd for multibyte chars
	(Darley) [Bug: 3839]

	* unix/aclocal.m4: added warning when configuring with
	--enable-threads that Tk may have problems

1999-12-09  Jeff Hobbs  <[email protected]>

	* generic/tkImgGIF.c: updated casting

	* win/makefile.vc: removed 16bit stuff, simplified makefile.

1999-12-06  Scott Redman  <[email protected]>

	* generic/tkMain.c: need to include tclInt.h for new hook
	functions that are internal-use-only.

1999-12-06  Jeff Hobbs  <[email protected]>

	* library/comdlg.tcl: removed tclVerifyInteger and tclSortNoCase,
	they weren't used, and were not actually correct

	* mac/tkMacFont.c:
	* mac/tkMacMenu.c:
	* mac/tkMacWindowMgr.c: fixed greyed out menu items, handling of
	... elipsis, font mapping problem, and enabled generated menu
	posting [Bug: 3705]

1999-12-02  Jeff Hobbs  <[email protected]>

	* generic/tkInt.h:
	* generic/tkWindow.c:
	* generic/tkCmds.c: converted Tk_DestroyCmd, Tk_LowerCmd and
	Tk_RaiseCmd to their ObjCmd equivalent.

	* library/msgbox.tcl: added color icons for tk_messageBox on Unix
	and Mac when tk_strictMotif isn't set. (Hipp)
	* library/tk.tcl: added window bounds checking to ::tk::PlaceWindow

	* tests/imgPPM.test: fixed test 2.2 to use -format ppm (since
	we know have GIF write capability)

1999-12-01  Scott Redman <[email protected]>

	* generic/tkMain.c :
	* unix/tkAppInit.c:
	* win/winMain.c: Added added hooks into the main() code for
	supporting TclPro and other "big" shells more easily without
	requiring a copy of the main() code.

1999-11-29  Jeff Hobbs  <[email protected]>

	* generic/tkImgGIF.c: added GIF writing that uses miGIF RLE
	[Bug: 2039, new patch]

	* library/entry.tcl: fixed up tkEntrySeeInsert (Nemthi)

	* generic/tkListbox.c: fixed 'get' of listbox to return a string
	when only one item is requested.

	* tests/clrpick.test:
	* tests/filebox.test: minor whitespace cleanup

	* library/tk.tcl: fixed missing $w in ::tk::PlaceWindow

1999-11-24  Jeff Hobbs  <[email protected]>

	* library/clrpick.tcl:
	* library/msgbox.tcl:
	* library/tk.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl: fixed dialogs to center over -parent,
	added utility functions ::tk::PlaceWindow, ::tk::SetFocusGrab,
	::tk::RestoreFocusGrab to tk.tcl to help

1999-11-23  Eric Melski  <[email protected]>

	* tests/listbox.test: Added a test to check that the topIndex is
	update when items are removed from the listvar variable.

	* generic/tkListbox.c: Added a check the updates the topIndex when
	items are removed from the listvar variable.

	* tests/listbox.test: Added a test to check that the vertical
	scrollbar is updated when the listvar changes.

	* generic/tkListbox.c (ListboxListVarProc): added a check that
	sets the UPDATE_V_SCROLLBAR flag if the length of the listvar has
	changed.

1999-11-23  Jeff Hobbs  <[email protected]>

	* generic/tk.h:
	* generic/tkConfig.c: added support for TK_OPTION_DONT_SET_DEFAULT
	as equiv for TK_CONFIG_DONT_SET_DEFAULT
	* generic/tkListbox.c: added TK_OPTION_DONT_SET_DEFAULT to the
	item specs

1999-11-19  Jeff Hobbs  <[email protected]>

	* generic/tkColor.c:
	* generic/tkColor.h: fixed Tk_NameOfColor to work correctly,
	with minor change to TkColor struct.

	* generic/tkConsole.c: added static declaration to
	ConsoleDeleteProc function (proto already had it)

	* win/tkWinInt.h: removed TkFontAttributes typedef (was
	redundant with tkFont.h).
	* win/tkWinPort.h: put #ifndef __GNUC__ around redefinition
	of str[n]casecmp, as cygwin uses the originals.
	* win/tkWinX.c: changed GetCurrentTime to GetTickCount (the
	former is deprecated).  [Bug: 2053]

1999-11-19  Eric Melski  <[email protected]>

	* tests/listbox.test: Added tests for itemcget and itemconfigure.

	* doc/listbox.n: Added documentation for -listvar option and for
	itemconfigure and itemcget commands.

	* generic/tkListbox.c: Added support for itemconfigure/itemcget
	listbox subcommands (addresses rfe #936)

1999-11-17  Eric Melski  <[email protected]>

	* tests/listbox.test: Updated tests for new error messages.

	* generic/tkListbox.c: Improved error messages for bad -listvar's.

	* tests/listbox.test: Added tests for bad -listvar's.

	* generic/tkListbox.c: Added handlers for bad -listvar's (ie, bad
	lists)

	* tests/listbox.test: Added tests for ListboxUpdateHScrollbar.

	* generic/tkListbox.c: Changed some old static buffers to base
	size on TCL_DOUBLLE_SPACE instead of (completely) hardcoding the size.

	* tests/listbox.test: New tests for -listvar functionality, and an
	odd extra case that wasn't covered before.

	* generic/tkListbox.c: Tests exposed some bugs, now fixed.

1999-11-16  Eric Melski  <[email protected]>

	* tests/listbox.test: Fixed tests to comply with new objectified
	error messages.  No -listvar specific tests yet.

	* win/tkWinDefault.h:
	* unix/tkUnixDefault.h:
	* mac/tkMacDefault.h: Added default value for -listvar option.

	* generic/tkWindow.c: Changed "listbox" mapping from old-school to
	new-school objectified command.

	* generic/tkListbox.c: Objectified listbox; added support for
	-listvar option.  Converted internal structure to use a Tcl list
	object to store the data.

	* generic/tkInt.h: Changed reference to Tk_ListboxCmd to
	Tk_ListboxObjCmd.

1999-11-09  Jeff Hobbs  <[email protected]>

	* generic/tkGrid.c: changed Tcl_Alloc to ckalloc

	* generic/tkEntry.c: fixed C expr error in destroy of entry
	that could lead to 'malformed bucket chain' error

	* win/winMain.c: corrected winMain to not do a DebugBreak when
	returning an error message from the top level

1999-10-30  Jeff Hobbs  <[email protected]>

	* win/tkWinKey.c: fixed XKeysymToKeycode to handle mapping of
	symbolic keysyms (Left, Home, ...) with event generate

	* library/entry.tcl: change tkEntrySeeInsert to avoid the use
	of a while loop that could eat CPU tremendously.  Behavior of
	moving the cursor at the right edge changes slightly (previously
	it tried to keep the cursor at the right edge, now it moves the
	cursor to a "central right" location - better IMHO).

1999-10-28  Jeff Hobbs  <[email protected]>

	* doc/CrtImgType.3:
	* doc/CrtPhImgFmt.3:
	* doc/FindPhoto.3:
	* doc/photo.n:
	* generic/tk.h:
	* generic/tkCmds.c:
	* generic/tkImage.c:
	* generic/tkImgBmap.c:
	* generic/tkImgGIF.c:
	* generic/tkImgPPM.c:
	* generic/tkImgPhoto.c:
	* generic/tkInt.h:
	* generic/tkTest.c:
	* generic/tkWindow.c:
	* tests/imgPhoto.test: added Img patch (Nijtmans) with docs,
	headers #def'd with USE_OLD_IMAGE.  Upgrades image stuff to
	Tcl_Obj API, adds alpha channel (images are now 32 bpp)

	* makefile.vc: changed 'c:/program files' to c:/progra~1

1999-10-19  Jeff Hobbs  <[email protected]>

	* library/scrlbar.tcl: changed tkScrollButtonUp to check for
	existence of tkPriv(relief) in order to avoid spurious release
	events

	* unix/Makefile.in: added ChangeLog to dist archive

1999-09-24  Jeff Hobbs  <[email protected]>

	* */README:
	* win/makefile.vc:
	* */configure.in:
	* generic/tk.h:
	* library/tk.tcl: up'd to 8.3a1

	* unix/Makefile.in: changed 'mkdir' to 'mkdir -p'

	* library/dialog.tcl: changed {Times 18} to {Times 12} for
	dialog font.

1999-09-16  Jeff Hobbs  <[email protected]>

	* generic/tkFont.c: fixed processing of font options and error
	returned [Bug: 2075]

	* win/tkWinWm.c: fixed bug in 'wm deiconify' that raised the
	wrong toplevel, and changed it to not set focus on overridden
	toplevels

1999-09-15  Jeff Hobbs  <[email protected]>

	* unix/aclocal.m4: added fix for FreeBSD-[1-2] recognition [Bug: 2070]
	and fix to AIX-* to get ldAix right [Bug: 2624], fixed AIX
	version check (readjust from 8-21 fix) and several other config
	fixes for AIX
	* mac/tkMacMenubutton.c:
	* unix/tkUnixMenubu.c: fixed permanently stippled menubutton image
	* win/tkWinButton.c: fixed possible pointer smash [Bug: 2733]

1999-09-14  Jeff Hobbs  <[email protected]>

	* win/tkWinMenu.c: fix for stack overrun in GetTextFace [Bug: 909]

1999-09-01  Jeff Hobbs  <[email protected]>

	* win/tkWinDraw.c:
	* unix/tkUnixDraw.c: fixed header style for TkpDrawHighlightBorder
	* generic/tkCanvas.c: fixed GC error (bg <> fg) in tkCanvas.c
	(from code added to support TkpDrawHighlightBorder) [Bug: 2676]
	* unix/aclocal.m4: added -bnoentry to the AIX-* flags
	* library/msgbox.tcl: changed the behavior of tk_messageBox on
	Unix to be more Windows like in handling of <Return> and the
	default button
	* library/button.tcl:
	* library/clrpick.tcl:
	* library/comdlg.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/focus.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/palette.tcl:
	* library/safetk.tcl:
	* library/scale.tcl:
	* library/scrlbar.tcl:
	* library/tearoff.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl: updated commands to use [string] ops
	instead of expr equality operators

1999-08-21  Jeff Hobbs  <[email protected]>

	* unix/aclocal.m4: Changed AIX-4.[2-9] check to AIX-4.[1-9]
	[Bug: 1909]

1999-08-20  Jeff Hobbs  <[email protected]>

	* generic/tkCursor.c: fixed bug in GetCursorFromObj that caused
	panic [Bug: 2562]

	* TK 8.2.0 RELEASED

1999-08-13  Jim Ingham  <[email protected]>

	* mac/tkMacMenu.c: Tk_DrawChars ends up setting the menu background
	wrong.	There is no clean way to stop it, so I use lower level routines
	here to draw the text.
	* mac/tkMacProjects.sea.hqx: Rearrange the projects so that the build
	directory is separate from the sources.  Much more convenient!

1999-08-10  Jeff Hobbs  <[email protected]>

	* win/tkWinWm.c: changed "wm deiconify" on Windows to raise and
	force the focus on the deiconified window (behavioral change from
	8.1 to comply better with Windows style) [Bug: 1609]
	* doc/wm.n: clarified behavior of "wm deiconify".
	* generic/tkInt.decls: added TkSetFocusWin
	* generic/tkFocus.c: changed static SetFocus to TkSetFocusWin

	* library/clrpick.tcl:
	* library/console.tcl:
	* library/tk.tcl: fixed code where abbreviations where used
	in calling widget methods (confuses iWidgets) [Bug: 2422]

1999-08-09  Jeff Hobbs  <[email protected]>

	* library/button.tcl: cleaned up programming (config -> configure)
	and fixed Windows relief bug [Bug: 664]
	* library/entry.tcl: changed Entry C/C/P to not use global data
	(now uses tkPriv(data)) [Bug: 1475]
	* library/listbox.tcl: fixed extended mode script error [Bug: 866]
	* doc/options.n: clarified that -troughcolor doesn't work on Windows
	* doc/wm.n: fixed wm positionfrom docs [Bug: 2284]

1999-08-01  Jeff Hobbs  <[email protected]>

	* mac/tkMacPort.h: wrapped panic in #ifndef panic to avoid
	compiler errors when used with stubs-#defines, from Vince Darley.
	[Bug: 2389]

1999-07-31  Scott Redman  <[email protected]>

	* xlib/X11/Xlib.h: Remove XFillRectangle since it is now in the
	stub tables.

1999-07-30  Jeff Hobbs  <[email protected]>

	* generic/tkInt.decls: Added stub entry for XFillRectangle [Bug: 2446]

1999-07-30  Scott Redman  <[email protected]>

	* win/makefile.vc: Corrected building threaded tktest.exe on
	Windows.  Needed to link in .obj files from Tcl, needs to change
	later so that code is in Tk and doesn't require a Tcl build.
	Also added runtest target.

1999-07-29  Scott Redman  <[email protected]>

	* generic/tkConsole.c: Allow tcl to open CON and NUL, even for std
	channels.  Checking for bad/unusable std channels was moved to Tk
	since its only purpose was to check whether to use the Tk Console
	Window for the std channels.  [Bug: 2393 2392 2209 2458]

	* win/Makefile.in: Corrected building threaded tktest.exe on
	Windows.  Needed to link in .obj files from Tcl, needs to change
	later so that code is in Tk and doesn't require a Tcl build.

1999-07-22  Scott Redman  <[email protected]>

	* Changed version to 8.2b2

	* win/tkWinPort.h: Block out include of sys/stat.h in order to
	build extensions with MetroWerks compiler for Win32. [Bug: 2385]

	* unix/Makefile.in: Need to make install-sh executable before
	calling (with chmod +x).  [Bug: 2413]

	* library/menu.tcl: Applied patch from Jeff Hobbs to fix typo.
	[Bug: 2425]

1999-07-21  Scott Redman  <[email protected]>

	* unix/Makefile.in: Add Windows configure script to distribution.

1999-07-16  Scott Redman  <[email protected]>

	* unix/Makefile.in:
	* win/Makefile.in:  Copy the prolog.ps from the generic directory
	for install-libraries.

	* unix/aclocal.m4: Check for Alpha/Linux to set the IEEE flag to
	the compiler to be -mieee.  Patch from Don Porter.

1999-07-08  Scott Stanton  <[email protected]>

	* tests/unixSelect.test: Fixed broken test.

	* win/makefile.vc: Added special case target to ensure that
	tkStubLib.obj is built with -DSTATIC_BUILD.

	* win/tkWinX.c (TkWinChildProc): Changed to pass
	WM_WINDOWPOSCHANGED through to DefWindowProc to make OpenGL
	sub-windows happy.  This allows Windows to generate the WM_SIZE
	and WM_MOVE messages.

1999-07-08  Scott Redman  <[email protected]>

	* unix/configure.in: Fix Tk stub lib file names and flags.

1999-06-30  Scott Redman  <[email protected]>

	* generic/tkGrid.c: removed deprecated functions (applied patch
	from Jan Nijtmans). [Bug: 2080]

	* generic/tkImgGIF.c:
	* generic/tkImgPPM.c:
	* generic/tkImgPhoto.c: Applied patch to allow Img extension to
	work with 8.2, from Jan Nijtmans. [Bug: 2068]

	* win/tkWinWm.c: Applied patch from Don Porter to prevent the
	windows code from calling the Tcl functions when the stub table
	has not been initialized in TkWinWmCleanup.  [Bug: 2269]

1999-06-16  Michael Thomas  <[email protected]>

	* unix/configure.in:
	* unix/Makefile.in:
	* unix/aclocal.m4: Numerous build changes to make Tk conform to
	the proposed TEA spec

	* tkConsole.c: changed some variable types from (int) to (size_t)
	to prevent compiler warnings.  Cast return value from strlen()
	to (int) in one place for the same reason.

1999-06-03  Scott Stanton  <[email protected]>

	* unix/tkUnixSelect.c:
	* tests/unixSelect.test:
	* generic/tkSelect.c: Fixed selection code to handle Unicode data
	in COMPOUND_TEXT and STRING selections. [Bug: 1791]

1999-06-02  Scott Stanton  <[email protected]>

	* generic/tkIntXlibDecls.h:
	* xlib/X11/Xlib.h: Added Mac specific defines to help with
	compilation.

	* generic/tkFont.c: lint

1999-06-01  Scott Stanton  <[email protected]>

	* unix/tkUnixSelect.c: Improved I18N selection support.
	COMPOUND_TEXT is converted to/from iso2022, and STRING is
	converted to/from iso8859-1.  There are still a few loose ends to
	tie up before this is completely done.

	* unix/tkUnixFont.c: Eliminated redundant case folding code.

	* generic/tkFont.c: Eliminated use of isupper/tolower in favor of
	Unicode variants.

1999-05-24  Scott Stanton  <[email protected]>

	* generic/tkStubLib.c:
	* generic/tkStubInit.c:
	* generic/tkIntXlibDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntDecls.h:
	* generic/tkInt.decls:
	* generic/tkConsole.c: Various changes to try to get the Mac
	builds working.

1999-05-21  Scott Stanton  <[email protected]>

	* win/tkWinClipboard.c: Fixed clipboard code to handle lack of
	CF_LOCALE information (e.g. from command.com).

1999-05-20  Scott Redman  <[email protected]>

	* library/console.tcl: Changed copyright string to read 1999
	Scriptics Corp. in wish console about box.

1999-05-19  Scott Redman  <[email protected]>

	* generic/tk.h: Add extern "C" block around entire header file for
	C++ compilers to fix linkage issues.  Submitted by Don Porter and
	Paul Duffin.

1999-05-18  Scott Stanton  <[email protected]>

	* tests/winClipboard.test:
	* win/tkWinClipboard.c: Fixed clipboard code so it handles Unicode
	data properly on Windows NT and 95. [Bug: 1791]

1999-05-07  Scott Stanton  <[email protected]>

	* library/menu.tcl: Fixed bug where tk_popup fails when called too
	quickly. [Bug: 2009]

1999-04-30  Scott Stanton  <[email protected]>

	* Changed version number to 8.1.1.

1999-04-30  Scott Stanton  <[email protected]>

	* Merged changes from 8.1.0 branch:

	* generic/tkDecls.h:
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c: Changed to avoid the need for forward
	declarations in stub initializers.  Added extern "C" blocks around
	stub table pointer declarations so the stubs can be used from C++
	code. [Bug: 1934]

	* generic/tkInt.decls: Added TkClipBox, XDrawSegments, and
	XForceScreenSaver to stubs.

	* generic/tkStubLib.c: Reordered declarations to avoid
	circularities and forward references.

	* generic/tkStubInit.c: Added includes for Mac.

	* generic/tkMenubutton.c: lint

	* generic/tkEntry.c: Fixed bad option table entry.

	* generic/tkImgBmap.c:
	* generic/tkImgPPM.c:
	* generic/tkImgPhoto.c: Set the -translation and -encoding options
	to binary for image files. (reported by Marco Gazzetta)

1999-04-23  Scott Stanton  <[email protected]>

	* generic/tkInt.decls: Added TkClipBox, XDrawSegments, and
	XForceScreenSaver to stubs.

	* generic/tkStubLib.c: Reordered declarations to avoid
	circularities and forward references.

	* generic/tkStubInit.c: Added includes for Mac.

	* generic/tkMenubutton.c: lint

	* generic/tkEntry.c: Fixed bad option table entry.

1999-04-22  Scott Redman  <[email protected]>

	* generic/tkImgBmap.c:
	* generic/tkImgPPM.c:
	* generic/tkImgPhoto.c: Set the -translation and -encoding options
	to binary for image files. (reported by Marco Gazzetta)

1999-04-20  Scott Redman  <[email protected]>

	* xlib/X11/Xlib.h: changed definition of Status type to use a
	typedef instead of a #define to avoid conflicting with the cygwin
	win32 headers [Bug 1804]

1999-04-15  Scott Stanton  <[email protected]>

	* Merged 8.1 branch into the main trunk

1999-04-09  Scott Redman  <[email protected]>

	* generic/tkWindow.c: Fixed deadlock situation when the Initialize()
	function returns without releasing the mutex.  Found while testing
	Bug 1700, during safe.test (tk).

1999-04-06  Scott Stanton  <[email protected]>

	* generic/tkMain.c (Tk_MainEx): Changed to reset result before
	calling Tcl_EvalFile.  The ensures that error messages will be
	generated cleanly.

	* tests/winfo.test: Enabled tests that previously failed.

1999-04-05  Scott Stanton  <[email protected]>

	* library/bgerror.tcl:
	* library/button.tcl:
	* library/clrpick.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/focus.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/palette.tcl:
	* library/scale.tcl:
	* library/scrlbar.tcl:
	* library/tearoff.tcl:
	* library/text.tcl:
	* library/tk.tcl: Lots of minor performance improvements
	contributed by Jeffrey Hobbs. [Bug: 1118]

	* win/tkWinWm.c (Tk_WmCmd): Fixed bad code in tracing
	suboption. [Bug: 1519]

	* library/tkfbox.tcl: Change to restore button text after an
	action to avoid the sticky "Open" button in a save dialog.
	[Bug: 1640]

	* library/entry.tcl: Fixed so selection is returned using the
	-show character during cut and paste operations. [Bug: 1687]

1999-04-5   Scott Redman  <[email protected]>

	* generic/tkInt.decls:
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c:
	* xlib/xgc.c:
	* xlib/X11/Xlib.h:
	* xlib/X11/Xutil.h: Added more X functions to the Win & Mac stubs
	tables.

1999-04-05  Scott Stanton  <[email protected]>

	* unix/configure.in:
	* generic/tkCanvPs.c: Added configure test for pw_gecos field in
	pwd to support OS/390. [Bug: 1724]

1999-04-02  Scott Stanton  <[email protected]>

	* tests/text.test:
	* generic/tkText.c: Fixed handling of Unicode in text searches.
	The -count option was returning byte counts instead of character
	counts. [Bug: 1056, 1148, 1666]

1999-04-01  Scott Redman  <[email protected]>

	* generic/tk.decls:
	* generic/tk.h:
	* generic/tkStubInit.c:
	* generic/tkWindow.c:
	* unix/Makefile.in:
	* win/makefile.vc: Tk now uses its own stub library to store
	pointers to its own stubs table.

	* doc/dde.n: (removed)
	* doc/send.n:
	* generic/tk.decls:
	* tests/winSend.test:
	* generic/tkPlatDecls.h:
	* win/tkWinSend.c:  Removed the DDE-based send and dde commands,
	they were causing Tk to lock up when any window on the system was
	not processing its message queue (more importantly, windows in Tcl
	and Tk).  The send command needs to be rewritten to prevent the
	deadlock situation (soon).  The dde command is being pushed into
	its own package and will provide almost all of the capabilities
	that send did before (using a "dde eval" command), not yet
	completed.

1999-03-31  Scott Redman  <[email protected]>

	* win/tkWinSend.c: Modified dde/send code to work properly on
	Win95/Win98. String lengths are not returned properly by DDE, so
	NULL terminate all strings going in and ignore the string length
	coming back out.  Do not destroy handles until all necessary work
	on those handles (and child handles) is done.

1999-03-30  Scott Stanton  <[email protected]>

	* generic/tkWindow.c (Tk_DestroyWindow): Image handlers are now
	finalized before the font subsystem since complex image handlers
	may contain references to fonts (e.g. Tix compound images).
	[Bug: 1603]

1999-03-29  Scott Stanton  <[email protected]>

	* doc/MeasureChar.3:
	* doc/TextLayout.3:
	* generic/tk.decls:
	* generic/tkCanvText.c:
	* generic/tkEntry.c:
	* generic/tkFont.c:
	* generic/tkListbox.c:
	* generic/tkMessage.c:
	* mac/tkMacFont.c:
	* unix/tkUnixButton.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixMenu.c:
	* win/tkWinFont.c:
	* win/tkWinMenu.c: Standardized text layout and font interfaces
	so they are consistent with respect to byte versus character
	oriented indices.  The layout functions all manipulate character
	oriented values while the lower level measurement functions all
	operate on byte oriented values.  This distinction was not clear
	and so the functions were being used improperly in a number of
	places.  [Bug: 1053, 747, 749, 1646]

	* generic/tk.decls: Eliminated uses of C++ STL types string and
	list from declarations.

	* generic/tkFont.c: Changes to named fonts were not being
	propagated in some cases. [Bug: 1144]

	* xlib/X11/Xlib.h:
	* generic/tkInt.decls: Added XParseColor to xlib stub
	tables. [Bug: 1574]

	* doc/GetBitmap.3:
	* generic/tkBitmap.c (BitmapInit): Eliminated use of Tk_Uid's in
	bitmaps.  Added a few CONST declarations.

1999-03-29  Scott Redman  <[email protected]>

	* unix/configure.in:
	* unix/Makefile.in:
	* win/makefile.vc:
	* generic/tkDecls.h:
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkIntXlibDecls.h: Removed stub functions. Always use the
	Tcl stubs when building with --enable-shared.

1999-03-26  Scott Redman  <[email protected]>

	* generic/tkTextIndex.c:
	* tests/testIndex.test: Avoid looking past the beginning of the
	array storing data for the text widget (.t index end-2c).  Added
	test case to check for the bug.  [Bug 991]

	* generic/tkConsole.c: Copy static strings into a Tcl_DString
	before passing to Tcl_Eval, in case the compiler puts static
	strings into read-only memory.

1999-03-26  Suresh Ankolekar  <[email protected]>

	* unix/configure.in:
	--nameble-shared is now the default and builds Tk as a shared
	library; specify --disable-shared to build a static Tk library
	and shell.

1999-03-26  Bryan Surles  <[email protected]>

	* library/menu.tcl: Fixed bug reported by Bryan Oakley in the
	menubutton bindings.  There was a false assumption that there was
	always a menu attached to the button.  [Bug 1116]

1999-03-26  Scott Redman  <[email protected]>

	* unix/configure.in: Removed --enable-tcl-stub.  Linking Tk to Tcl
	stubs is causing too many problems when linking executables like wish.
	Until the Tk is a fully loadable extension, linking against the Tcl
	stubs is not supported in Tk.

1999-03-19  Scott Redman  <[email protected]>

	* generic/tkBitmap.c:
	* generic/tkCursor.c:
	* generic/tkGC.c: When creating hash tables that key off of XID
	handles, make sure to pass TCL_ONE_WORD_KEYS.  XIDs are guaranteed
	to be 32bit numbers, although on some 64bit systems (including 64bit
	Solaris 7) they are packed into a 64bit value where the upper 32bits
	are zero. The normal method of sizeof(XID)/sizeof(int) causes the
	hash table code to assume that the XID is a pointer to an array of
	two ints, which it is not.  Tk now supports 64bit Solaris 7.

1999-03-17  Scott Stanton  <[email protected]>

	* win/makefile.vc:
	* generic/tk.h: Changed to use TCL_BETA_RELEASE macro, and fixed
	so this works in rc files.

	* win/makefile.vc:
	* win/makefile.bc:
	* win/README:
	* unix/configure.in:
	* generic/tk.h:
	* README: Updated version to 8.1b3.

1999-03-14  Scott Stanton  <stanton@GASPODE>

	* unix/configure.in: Added missing stub related definitions.

	* unix/Makefile.in: Install tkDecls.h in addition to tk.h.

	* generic/tkStubLib.c: Added flags to ensure we are using Tcl
	stub macros.

1999-03-11  Scott Stanton  <stanton@GASPODE>

	* generic/tkInt.decls: Added reserved slot for XSetDashes for use
	by the dash patch.

1999-03-10  Scott Redman  <[email protected]>

	* xlib/xdraw.c:
	* xlib/X11/Xlib.h:
	* mac/tkMac.h:
	* mac/tkMacInt.h:
	* mac/tkMacPort.h:
	* mac/tkMacXStubs.c:
	* mac/tkMacAppInit.c:
	* mac/tkMacCursor.c:
	* win/makefile.vc:
	* win/tkWin.h:
	* win/tkWinInt.h:
	* win/tkWinPort.h:
	* win/winMain.c:
	* generic/tk.h:
	* generic/tkInt.h:
	* generic/tk.decls:
	* generic/tkInt.decls:
	* generic/tkDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkStubs.c:
	* generic/tkPlatStubs.c:
	* generic/tkIntStubs.c:
	* generic/tkIntPlatStubs.c:
	* generic/tkIntXlibStubs.c:
	* generic/tkStubInit.c:
	* generic/tkStubLib.c:
	* generic/tkBind.c:
	* generic/tkCmds.c:
	* generic/tkConfig.c:
	* generic/tkConsole.c:
	* generic/tkCursor.c:
	* generic/tkGrab.c:
	* generic/tkImgPhoto.c:
	* generic/tkMain.c:
	* generic/tkMenu.c:
	* generic/tkPointer.c:
	* generic/tkTextDisp.c:
	* generic/tkWindow.c:
	* unix/tkUnixInt.h:
	* unix/tkUnixPort.h:
	* unix/Makefile.in:
	* unix/configure.in:
	* unix/tkConfig.sh.in:
	* unix/tkUnix.c:
	* unix/tkUnix3d.c:
	* unix/tkUnixDraw.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixMenubu.c: Stubs implementation for 8.1.  Tk_Main() is
	replaced with a macro which calls Tk_MainEx(). Tk can link to the Tcl
	stubs library, wish links directly to Tcl and Tk. Use
	--enable-tcl-stubs to link Tk to the Tcl stubs library (Unix), on
	by default on Windows. Exported all public functions through the
	stubs mechanism (see the *.decls files) and many of the internal
	functions. Most of the changes dealt with shifting around the
	function declarations in the header files.  Mac code may not
	compile, but it shouldn't take much work to fix this.

	* mac/tkMacMenu.c: Added dummy TkpMenuThreadInit for Mac to be
	consistent with Unix and Windows versions.

1999-03-08  Lee Bernhard  <[email protected]>

	* win/tkWinWm.c: Toplevel class no longer shared between
	threads.

	* win/tkWinX.c: Multiple threads no longer share the same
	TkDisplay structure.  Required because TkDisplay stores much
	thread-specific data for a given thread.

	* win/tkWinSend.c: Moved application instance handle out
	out thread-local storage.  DDE was failing to initialize
	when the instance handles were different between threads.

	* win/makefile.vc: Added THREADDEFINES for building with
	threads enabled.

	* generic/tkMenu.c:
	* win/tkWinMenu.c:
	* unix/tkUnixMenu.c: Added TkpMenuThreadInit for initializing
	thread-specific Menu state.

1999-03-01  Scott Redman  <[email protected]>

	* win/tkWinWm.c:
	* win/tkWinPointer.c:
	* win/tkWinInt.h: Fix "focus -force" for Windows.  The Win32 API
	function SetForegroundWindow() does not work unless the window
	handle is a toplevel window (a Windows toplevel).  The handle
	being passed was a Tk toplevel, which is a child of the Windows
	toplevel.

1999-02-26  Scott Redman  <[email protected]>

	* win/cat.c: Remove this file, use the one in the Tcl source directory.

	* win/makefile.vc: Remove the wishc.exe from the default targets.  Add
	a separate console-wish target to build it.  The need for a
	console-wish will go away soon, so we don't want to encourage its
	use.

1999-02-25  Scott Redman  <[email protected]>

	* win/tkWinWm.c: Properly initialize the tsdPtr->firstWindow field.

	* win/cat.c: Code for cat32.exe, copied from the Tcl sources. Required
	in order to run the test suite from the makefile

	* win/winMain.c: Add main() for a console-based wishc.exe, which meant
	adding code to disable the call to Tk_ConsoleInit().

	* generic/tkConsole.c: Check the standard handles before creating the
	new standard channels.	This allows a windows app that has stdin,
	stdout, or stderr to correctly connect to them.

	* generic/tkMain.c: Add a proper check for the interactive mode, since
	the standard channels may actually be connected in windows mode or
	even in the console-based wish.

	* win/makefile.vc: Add targets for wishc.exe (console-based wish) and
	cat32.exe (for testing). Fix the test suite target so it can be run
	from the makefile (which can happen since the standard handles have
	been fixed).

1999-02-12  Lee Bernhard  <[email protected]>

	* generic/tkMenuButton.h:
	* generic/tkMenuButton.c:
	* mac/tkMacMenubutton.c:
	* mac/tkMacDefault.h
	* unix/tkUnixMenubu.c: Eliminated Tk_Uids used by -state option.
	* unix/tkUnixDefault.h
	* win/tkWinDefault.h

	* generic/tk.h:
	* generic/tkScale.h:
	* generic/tkScale.c:
	* generic/tkWindow.c:
	* unix/tkUnixScale.c:
	* unix/tkUnixDefault.h:
	* unix/tkWinDefault.h:
	* mac/tkMacDefault.h:  Objectified scale widget.

	* win/tkWinX.c: Removed Thread-specific data from process
	initialization code that was stopping the Tk Dll from
	loading.

1999-02-11  Scott Stanton  <stanton@GASPODE>

	* README:
	* generic/tk.h:
	* unix/configure.in:
	* win/README:
	* win/makefile.bc:
	* win/makefile.vc: Updated version to 8.1b2.

	* unix/tkUnixSend.c: Fixed one more Tcl_*ObjVar instance.

1999-02-04  Scott Stanton  <stanton@GASPODE>

	* Various cleanup related to the Tcl_Eval and Tcl_ObjSetVar
	changes in Tcl.

	INTEGRATED PATCHES FROM 8.0.5b2:

	* win/tkWinMenu.c (TkpDestroyMenu): Changed so modalMenuPtr is
	cleared when it is being destroyed.

	* generic/tkImgPhoto.c: Changed so color tables are freed
	immediately instead of being delayed.  This ensures that color
	tables are properly disposed at process exit.

	* library/prolog.ps: Changed string that determines font height to
	include European character with an umlaut.

	* generic/tkImgBmap.c (ImgBmapConfigureInstance): If an image
	mask changed but ended up with the same XID, the GC failed to be
	updated and so the new mask was not used. [Bug: 970]

	* generic/tkFocus.c (SetFocus): Changed so focus window is always
	set if -force is specified.  This fixes the problem on Windows
	where Tk does not activate the window if it already has focus.

	* generic/tkConsole.c: Fixed so errors in console eval are
	reported properly.  Eliminated duplicate result messages. [Bug: 973]

	* win/tkWinWm.c: Changed so windows that aren't resizable don't
	have resize handles and the zoom box is disabled.

	* win/tkWinInt.h:
	* win/tkWinPointer.c: Changed to cancel the mouse timer when a
	user initiated move/resize loop begins.

	* unix/configure.in: TK_LD_SEARCH_FLAGS was set incorrectly if
	SHLIB_LD_LIBS='${LIBS}', and shared linking is performed through
	the C compiler. Systems affected are Linux, MP-RAS and NEXTSTEP,
	but also with gcc on many more systems. [Bug: 908]

	* win/makefile.vc: First stab at install target.  Fixed quoting so
	paths with spaces work.

	* tests/main.test:
	* tests/unixWm.test: Better cleanup of temporary files.

	* mac/tkMacAppInit.c:
	* generic/tkTest.c:
	* generic/tkAppInit.c:
	* win/winMain.c: Changed some EXTERN declarations to extern
	since they are not defining exported interfaces.  This avoids
	generating useless declspec() attributes and makes the windows
	makefile simpler.

	* library/menu.tcl (tkMenuFind): Changed so keyboard shortcuts
	will only be found in the current toplevel.  Previously, they
	might be found in menus attached to other toplevels that might not
	even be mapped. [Bug: 924]

	* generic/tkCanvLine.c: Changed to treat zero width lines like
	they have width 1 for purposes of selection. [Bug: 925]

	* win/tkWinFont.c (Tk_MeasureChars): Added a workaround for a bug
	in GetTextExtentExPoint on Win NT 4.0/Japanese. [Bug: 1006]

	* unix/tkUnixSend.c (Tk_SetAppName): Fixed uninitialized memory
	access bug. [Bug: 919]

1999-1-28  Scott Stanton  <stanton@GASPODE>

	* generic/tkGrid.c: Fixed bug in "grid forget" that failed to cancel
	pending idle handlers, resulting in a crash in a few odd cases.

1999-01-06  Lee Bernhard  <lfb@JUSTICE>

	* generic/tk.h, generic/tkGet.c, generic/tkConfig.c,
	* generic/tkOldConfig.c, generic/tkEntry.c, generic/tkMenubutton.c,
	* generic/tkMenubutton.h, generic/tkScale.c, generic/tkScale.h,
	* generic/tkTextDisplay.c, generic/tkText.c, unix/tkUnixMenubu.c,
	* unix/tkUnixScale.c, mac/tkMacMenu.c, mac/tkMacMenubutton.c,

	Removed global Tk_Uids dealing with "-state" configuration option
	and added new TK_CONFIG_STATE configSpec that doesn't use
	Tk_Uids.

1998-12-11    === Tk 8.1b1 Release ===

1998-12-11  Scott Stanton  <stanton@GASPODE>

	* generic/tkMain.c (Tk_Main): Fixed improper command line encoding
	handling.

1998-12-08  Scott Stanton  <stanton@GASPODE>

	* win/tkWinClipboard.c (TkSelGetSelection, TkWinClipboardRender):
	Changed to handle multibyte characters properly. [Bug: 935]

1998-12-07  Scott Stanton  <stanton@GASPODE>

	* library/xmfbox.tcl (tkMotifFDialog_Create): In the cached case,
	the data array was not being initialized with the correct set of
	widgets.

1998-12-4  Brent Welch  <welch@SAGE>

	* Changed patchLevel to 8.1b1

	* generic/tkMenu.c (ConfigureMenuCloneEntries): The -menu configuration
	option was being incorrectly specified as just "menu".

1998-11-30  Scott Stanton  <stanton@GASPODE>

	* generic/tkButton.c (ConfigureButton): The error result was
	getting lost when restoring configuration options. [Bug: 619]

1998-11-25  Scott Stanton  <stanton@GASPODE>

	* unix/tkUnixFont.c (GetFontAttributes): Initialize an unspecified
	family to an empty string.
	(FontMapLoadPage): if the font included characters below 32, the
	index computation was incorrect because the range was shifted up
	to 32.
	(CreateClosestFont): check for empty locale as well as NULL.

	* generic/tkFont.c (TkFontParseXLFD): initialize charset to
	iso8859-1 if no charset is specified.

	* mac/tkMacHLEvents.c (OdocHandler): added conversion from
	external string to UTF [Bug: 869]

	* integrated tk8.0.4 changes.

	* generic/tkBind.c: fixed deletion order bug where a crash would
	result if a binding deleted "."

	* generic/tkMenu.c (MenuWidgetObjCmd): disabled menu entries were
	getting reenabled whenever the mouse passed over the entry [Bug: 860]

	* unix/tkUnixMenu.c (TkpComputeStandardMenuGeometry): hidemargin
	option was not honored properly in menus [Bug: 859]

1998-11-24  Scott Stanton  <stanton@GASPODE>

	* tkMacMenu.c, tkUnixMenu.c, tkWinMenu.c, tkMenuDraw.c, tkMenu.h,
	* tkMenu.c: Backed out the previous fix for bug 620 and
	eliminated a bunch of code that created unnecessary objects.
	Changed back to using internal types instead of objects for many
	configuration options.	There are many more fixes like this that
	could be made, but some require a little restructuring of the
	code. In any case the leaks are fixed and there is a lot less
	allocation happening. [Bug: 620]

1998-11-19  Scott Stanton  <stanton@GASPODE>

	* tkMenu.c (DestroyMenuEntry): fixed memory leaks [Bug: 620]

	* tkWinX.c (GetTranslatedKey): fixed bad code merge

	* tkWinWm.c, tkWinMenu.c: fixed titles and menus so they properly
	display Unicode [Bug: 819]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted ChangeLog.2004.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
2004-12-29  Jeff Hobbs	<[email protected]>

	* win/tcl.m4, win/configure: update MSVC CFLAGS_OPT to -O2, remove -Gs
	(included in -O2) and -GD (outdated). Use "link -lib" instead of "lib"
	binary and remove -YX for MSVC7 portability. Add -fomit-frame-pointer
	for gcc OPT compiles. [Bug 1092952, 1091967]

2004-12-21  Donal K. Fellows  <[email protected]>

	* library/demos/*.tcl: Add [package require Tk] to all the widget demo
	scripts so they follow standard practice better. [FRQ 815118]

2004-12-20  Vince Darley  <[email protected]>

	* generic/tkFileFilter.c:
	* generic/tkFileFilter.h:
	* macosx/tkMacOSXDialog.c:
	* win/tkWinDialog.c:
	* tests/filebox.test:
	* tests/winDialog.test: Corrected handling of MacOS file types in
	tk_*file dialogs [Bug 1083878].

2004-12-20  Donal K. Fellows  <[email protected]>

	* doc/panedwindow.n: Fix silly typo. [Bug 1087842]

2004-12-19  Chengye Mao	 <[email protected]>

	* win/tkWin.h, win/tkWinEmbed.h: Make embedding work better on Windows.
	* win/tkWinWm.c, win/tkWinX.c:	 [Bugs 222677, 831627, 842945, 1024364]

2004-12-17  Chengye Mao	 <[email protected]>

	* generic/tkFrame.c:  Make container windows display their
	* generic/tkWindow.c: background when they don't have content.

2004-12-10  Donal K. Fellows  <[email protected]>

	* unix/tk.spec, macosx/Tk-Info.plist, macosx/Wish-Info.plist:
	* macosx/Wish.pbproj/project.pbxproj, README, win/configure.in:
	* unix/configure.in, generic/tk.h: Bump version to 8.5a3.

2004-12-09  Daniel Steffen  <[email protected]>

	* unix/tcl.m4: synced with tcl/unix/tcl.m4
	* unix/configure: regen

2004-12-09  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock):
	Added guards so that rescanning for the complex-alpha check is not done
	in the common case of creating a simple image a bit at a time, or any
	other time where the image was simple before and the input data has no
	alpha channel. [Bug 1081966]

2004-12-07  Don Porter	<[email protected]>

	* tests/canvPs.test:	Cleaned up the matching of [makeFile] and
	* tests/choosedir.test: [removeFile] commands as indicated by the
	* tests/filebox.test:	results of a -debug 1 run of the test suite.
	* tests/imgPPM.test:	Tk test suite is now -debug 1 clean. This
	* tests/imgPhoto.test:	completes fixing [1078648].
	* tests/listbox.test:
	* tests/main.test:

2004-12-07  Donal K. Fellows  <[email protected]>

	* tests/bind.test, tests/button.test, tests/canvas.test:
	* tests/cursor.test, tests/scrollbar.test: Eliminate all duplicate test
	names. [Bug 1078648 again]

2004-12-06  Jeff Hobbs	<[email protected]>

	*** 8.5a2 TAGGED FOR RELEASE ***

2004-12-06  Don Porter	<[email protected]>

	* tests/safe.test:	Trim auto_path to improve performance [1080039]

2004-12-05  Jeff Hobbs	<[email protected]>

	* changes: updated for 8.5a2 release

2004-12-04  Donal K. Fellows  <[email protected]>

	* tests/*.test: Resolve duplicate test names. [Bug 1078648]

2004-12-03  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Make
	overlay compositing where the target is empty no longer set the target
	to magical gray, and also make sure that the complex-alpha flag is
	toggled when necessary. [Patch 848161]

2004-12-01  Jeff Hobbs	<[email protected]>

	* unix/tkUnixButton.c (TkpDisplayButton): constrain coords to
	Tk_RedrawImage to display only portion that is valid.
	* generic/tkImgPhoto.c (ImgPhotoDisplay): add X error suppression
	around XGetImage to prevent app abort. [Bug 979239]

2004-11-28  Joe English	 <[email protected]>

	* unix/tkUnixRFont.c(Tk_DrawChars): Check for short integer overflow in
	x,y coordinates [Fixes: Bug 942320 "Tk, Xft, text and long lines"]

2004-11-26  David Gravereaux  <[email protected]>

	* win/makefile.vc: Shell targets needed more stack space. [Bug 1066755]

2004-11-20  Vince Darley  <[email protected]>

	* tests/text.test: fix to test's platform sensitivities [Bug 1025871]
	* tests/textDisp.test: made test less timing sensitive [Bug 1034171],
	and fixed a platform-sensitive test [Bug 966845]

2004-11-19  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: reverted earlier changes for
	tclConfig.h changes to tcl, since those have been reverted for now.

	Note that newly added macosx/Wish.xcode will not work without
	tclConfig.h, this project has not been removed again.

2004-11-18  Reinhard Max  <[email protected]>

	* unix/tcl.m4 (SC_CONFIG_MANPAGES): Applied an improved version of
	* unix/configure.in:		    [Patch 996085], that introduces
	* unix/Makefile.in:		    --enable-man-suffix.

	* unix/installManPage:		    added
	* unix/mkLinks.tcl:		    removed
	* unix/mkLinks:			    removed
	* unix/configure:		    generated

2004-11-17  Jeff Hobbs	<[email protected]>

	* generic/tkCanvWind.c (ConfigureWinItem): unmap windows immediately
	when state hidden is requested. [Bug 982248]

	* generic/tkCanvImg.c (ImageToPostscript): don't try ps generation of
	canvas image item without image specified. [Bug 1032300]

	* library/console.tcl (::tk::console::ExpandVariable): correct array
	keyname expansion. [Bug 1004508] (bold)

	* generic/tkPanedWindow.c (Tk_PanedWindowObjCmd): set save_under X attr
	to prevent expose events when moving sash. [Bug 1036963]

2004-11-16  Vince Darley  <[email protected]>

	* doc/text.n: clarified documentation on use of -tabs option.

2004-11-16  Don Porter	<[email protected]>

	* library/msgs/it.msg: Updated Italian message catalog. Thanks to
	Roberto Ugoccioni [Bug 1063675].

2004-11-16  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/buildTkConfig.tcl: fixes for tclConfig.h changes.

	* macosx/Wish.pbproj/project.pbxproj: fixed references to renamed
	bitmap files.

	* macosx/Wish.xcode/project.pbxproj (new):
	* macosx/Wish.xcode/default.pbxuser (new):
	* macosx/Wish-Info.plist (new):
	* macosx/Tk-Info.plist (new): added new Xcode 1.5 project using native
	targets, made possible by tclConfig.h changes.

	* generic/tk.h: added version number change comments for new files.

2004-11-15  Vince Darley  <[email protected]>

	* generic/tkText.c: fix to multi-line search problem and removed
	* tests/text.test:  'knownBug' from one test.

2004-11-15  Donal K. Fellows  <[email protected]>

	* unix/tcl.m4, unix/configure.in: Expanded all AC_DEFINE calls to the
	three-argument form and ported recent changes to the tcl.m4 from the
	Tcl distribution. *No* call to AC_CONFIG_HEADERS has been added; this
	change should be virtually entirely cosmetic.

2004-11-12  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXXStubs.c: implemented XGetGeometry().

2004-11-12  Jeff Hobbs	<[email protected]>

	* generic/tkCmds.c (Tk_TkObjCmd): use correct screen data when
	-displayof arg is passed to [tk scaling]. [Bug 800178]

2004-11-12  Daniel Steffen  <[email protected]>

	* doc/SetOptions.3:
	* doc/text.n: fixed *roff errors uncovered by running 'make html'.

	* macosx/tkMacOSXFont.c (Tk_MeasureChars,Tk_DrawChars,etc): Make sure
	that the lastSubFontPtr remains valid even when the subfont array is
	reallocated. [Bug 618872]

2004-11-11  Reinhard Max  <[email protected]>

	* generic/tkEvent.c (InvokeInputMethods): Call XSetICFocus whenever the
	window receives focus. This fixes [Bug 905830] but avoids [Bug 1000051]

2004-11-11  Daniel Steffen  <[email protected]>

	* generic/tkMain.c:
	* macosx/tkMacOSXAppInit.c (removed):
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h: changes to make TkAqua dynamically loadable,
	enabling [package require Tk] from tclsh. Startup code from
	tkMacOSXAppInit.c moved into tkMacOSXInit.c, added code that notifies
	the window server that an unbundled executable is a full GUI
	application after loading Tk. [Patch 1035348]

	* doc/wm.n: documented [wm attributes] on Mac OS X. [Bug 606665]
	* macosx/tkMacOSXWm.c: implemented TIP 222 [wm attributes -alpha] on
	Mac OS X. [Patch 892194]
	WmIconbitmapCmd: adopted FSRef changes from [wm atttrs -titlepath].

	* macosx/tkMacOSXSubwindows.c: synced spacing/formatting with
	core-8-4-branch.

	* generic/tkRectOval.c:
	* macosx/README:
	* macosx/tkMacOSXDefault.h:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXWm.c: forward port from core-8-4-branch of Jim's and
	my changes for CG drawing and [wm attributes] (corresponds to 8.4
	changes dating from 09-18, 07-27, 07-24).

	* macosx/tkMacOSXMouseEvent.c: endianness fixes.

	* macosx/Wish.pbproj/project.pbxproj: corrected path to html help
	inside framework.

	* macosx/Makefile: prevent parallel make from building several targets
	at the same time.

2004-11-09  Vince Darley  <[email protected]>

	* macosx/tkMacOSXButton.c: fix to dynamic reconfiguration of button
	'-compound' options (cosmetic problem), [Bug 1055023]

	* tests/text.test: added 'knownBug' 20.172.1 in text widget multiline
	search routines.

2004-11-08  Donal K. Fellows  <[email protected]>

	* library/demos/goldberg.tcl: Added slightly adapted version of Keith
	Vetter's tkGoldberg as the final animation demo. Many many thanks to
	Keith for giving his permission! [FRQ 627466]

2004-11-07  Peter Spjuth  <[email protected]>

	* doc/frame.n: Added some info for -width/-height options. [Bug
	1055423]

2004-11-07  Peter Spjuth  <[email protected]>

	* tests/grid.test:
	* generic/tkGrid.c: Made handling of ^ a bit more consistent in corner
	cases. This makes ^ work without any widgets in the same command. [Bug
	962589]

2004-11-07  Donal K. Fellows  <[email protected]>

	* library/demos/pendulum.tcl:	Added demonstrations of how to do
	* library/demos/aniwave.tcl:	animations using Tcl/Tk to the widget
	* library/demos/anilabel.tcl:	demo.

2004-11-03  Don Porter	<[email protected]>

	* tests/button.test: Update expected results to account for more
	verbose errorinfo from errors in variable traces [Tcl Bug 572164]

2004-11-01  Don Porter	<[email protected]>

	* tests/dialog.test (dialog-1.1): Update expected result to changes in
	the error messages produced by procs.

2004-10-29  Mo DeJong  <[email protected]>

	* tests/wm.test: Add Win32 test cases for attributes subcommand.
	* win/tkWinWm.c (WmAttributesCmd): Fixup broken option processing logic
	for attributes subcommand.

2004-10-28  Mo DeJong  <[email protected]>

	* win/tkWin32Dll.c (DllMain, _except_dllmain_detach_handler): Rework
	pushing of exception handler function pointer so that compiling with
	gcc -O3 works. Remove empty function call to avoid compiler warning.
	Mark the DllMain function as noinline to avoid compiler error from
	duplicated asm labels in generated code.

2004-10-28  Pat Thoyts	<[email protected]>

	* unix/tkUnixScale.c (DisplayHorizontalValue): Fix for [Bug 220927] by
	Michael Schlenker to keep the labels within the window.

2004-10-28  Donal K. Fellows  <[email protected]>

	* doc/*.n: Assorted minor documentation fixes.

2004-10-26  David Gravereaux <[email protected]>

	* win/tkWinX.c:		     Signature for tkWinXCleanup needed to be
	* generic/tkInt.decls:	     changed so it matches the Tcl_ExitProc
	* generic/tkIntPlatDecls.h:  typedef to avoid a bad-style cast.

	* win/makefile.vc: Force TCL_LIBRARY envar when calling tclsh

2004-10-26  Pat Thoyts	<[email protected]>

	* win/tkWinRegion.c (TkpBuildRegionFromAlphaData): Fixed syntax error
	* generic/tkImgPhoto.c (Tk_PhotoPutBlock): Removed unreferences vars.

2004-10-26  Donal K. Fellows  <[email protected]>

	* macosx/tkMacOSXRegion.c (TkpBuildRegionFromAlphaData):
	* win/tkWinRegion.c (TkpBuildRegionFromAlphaData): Factor out the
	* unix/tkUnix.c (TkpBuildRegionFromAlphaData):	   building of region
	* generic/tkImgPhoto.c (Tk_PhotoPutBlock):	   data to permit
	better implementations on particular platforms. [Bug 919066]

2004-10-24  Donal K. Fellows  <[email protected]>

	TIP#177 AND TIP#179 IMPLEMENTATIONS

	* doc/panedwindow.n: Docs for -hide and -stretch options.
	* tests/panedwindow.test: Basic tests of -hide and -stretch options.
	* generic/tkPanedWindow.c (Slave,slaveOptionSpecs,ComputeGeometry):
	(DisplayPanedWindow,ArrangePanes,MoveSash,PanedWindowIdentifyCoords):
	Add hide flag and stretch setting to list of options supported on a
	panedwindow's slaves. [Patch 983886] Much thanks to Brian Griffin for
	these options.

2004-10-20  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (UpdateWrapper): pass SWP_NOOWNERZORDER to SetWindowPos
	when maintaining win Z order, to prevent parent from flashing (when
	adjusting Z order).

2004-10-19  Joe English	 <[email protected]>

	TIP#204 IMPLEMENTATION

	* library/tk.tcl, library/entry.tcl, library/spinbox.tcl:
	TIP #204 "Virtual Events for Keyboard Traversal" [Patch 976928]

2004-10-19  Donal K. Fellows  <[email protected]>

	* tests/canvPsImg.tcl, tests/canvPsBmap.tcl:
	* generic/tkBitmap.c, bitmaps/*.bmp:
	* library/demos/icon.tcl, library/demos/items.tcl:
	* library/demos/label.tcl, library/demos/menu.tcl:
	* library/demos/ruler.tcl, library/demos/twind.tcl:
	* library/demos/images/*.bmp: Renamed all X bitmap files files to have
	an .xbm extension so Windows users won't get confused when wandering
	around the Tcl source tree. [Bug 733835]

2004-10-11  Miguel Bañon <[email protected]>

	* library/msgs/sv.msg: Swedish message catalog from Mats Bengtsson.

2004-10-09  Donal K. Fellows  <[email protected]>

	* doc/wm.n: Recorded what attribute values are supported on OSX though
	I don't know what they do.

2004-10-08  Joe English	 <[email protected]>

	TIP#205 IMPLEMENTATION

	* unix/tkUnixRFont.c: TIP #205 "Use pkgconfig Database to Register Xft
	Support".

2004-10-05  Jeff Hobbs	<[email protected]>

	TIP#159 IMPLEMENTATION

	* doc/wm.n (iconphoto):		  Added support for Tk photo images as
	* generic/tkInt.h (TkDisplay):	  title-bar icons. TIP #159
	* win/tkWinWm.c (WmIconphotoCmd): "wm iconphoto ?-default? image1 ..."
	* macosx/tkMacOSXWm.c (WmIconphotoCmd): Implemented for Win/Unix,
	* unix/tkUnixWm.c (WmIconphotoCmd):	stubbed out for OS X.
	* tests/wm.test, tests/unixWm.test, tests/winWm.test: [Bug 815751]

2004-10-04  Jeff Hobbs	<[email protected]>

	* generic/tkTextWind.c (EmbWinDelayedUnmap): Fix init warnings
	* generic/tkTextTag.c (TkTextCreateTag):
	* generic/tkTextMark.c (TkTextSetMark):
	* generic/tkTextIndex.c (GetIndex):
	* generic/tkUndo.c (EvaluateActionList):

2004-09-24  Don Porter	<[email protected]>

	* generic/tkCursor.c: Add missing initialization in debug routine.

2004-09-24  Vince Darley  <[email protected]>

	* library/text.tcl: corrected mousewheel scrolling [Bug 960190]

	* tests/textDisp.test: made some tests more robust to slowness in
	asynchronous height calculation callbacks [Bug 1025781]

2004-09-24  Pat Thoyts	<[email protected]>

	* win/tkWinX.c: Added declaration for advapi32 now that this file uses
	the Reg* functions (req'd for nmake build system).

2004-09-23  Vince Darley  <[email protected]>

	* generic/tkTest.c
	* tests/text.test: fix and tests for [Bug 1026485] - negative text
	search ranges should not lead to any matches.

2004-09-22  Jeff Hobbs	<[email protected]>

	* win/tkWinInt.h (TkWinDisplayChanged): added decl
	* win/tkWinX.c (TkWinDisplayChanged, TkpOpenDisplay): Correctly handle
	* win/tkWinWm.c (InvalidateSubTreeDepth, WmProc):     color and screen
	resolution changes. Tested for 16/24/32 bpp changes on XP. May need
	more fixes for 8bpp switch, use of special colormaps, or other special
	palette handling cases. [Bug 223689]

2004-09-21  Mo DeJong  <[email protected]>

	* generic/tkInt.decls: Add decl for TkWinGetPlatformTheme. It is only
	defined under Win32.
	* generic/tkIntPlatDecls.h: Regen.
	* generic/tkStubInit.c: Regen.
	* win/tkWinInt.h: Define TK_THEME_WIN_CLASSIC and TK_THEME_WIN_XP.
	* win/tkWinMenu.c (DrawMenuEntryAccelerator, DrawMenuEntryLabel): Draw
	a disabled 3D text highlight for the accelerator only with the Win95/98
	look. Same goes for the menu entry text.
	* win/tkWinX.c (TkWinGetPlatformId, TkWinGetPlatformTheme):
	Automatically detect the Windows theme in use and return either
	TK_THEME_WIN_CLASSIC or TK_THEME_WIN_XP when the TkWinGetPlatformTheme
	function is invoked. [Patch 866194]

2004-09-21  Mo DeJong  <[email protected]>

	* win/tkWinWm.c: Rework WS_EX_LAYERED and LWA_ALPHA defines so that
	compiling with mingw works again.

2004-09-20  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (UpdateWrapper, WmAttributesCmd): handle attribute
	settings prior to window mapping and resort to more forceful wrapper
	update again for -toolwindow (to remove it from taskbar).

2004-09-19  Donal K. Fellows  <[email protected]>

	* doc/*: Standardize style of references to manual sections and public
	Tcl symbols along the lines of what I set out in [Tcl Patch 1022527].

2004-09-18  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (WmAttributesCmd): correct -alpha 0.0/1.0 setting and
	round the value.
	(UpdateWrapper): don't adjust Z order of TOPMOST window.
	(WmAttributesCmd): don't call UpdateWrapper for -disabled or
	-toolwindow attr changes.

2004-09-17  Jeff Hobbs	<[email protected]>

	TIP#222 IMPLEMENTATION

	* doc/wm.n:
	* tests/winWm.test: Add 'wm attributes -alpha' to control toplevel
	* win/tkWinInt.h:   alpha transparency on Win2K/XP+.
	* win/tkWinWm.c:    TIP #222 [Patch 892194]

	* win/tkWinWm.c (UpdateWrapper): Ensure that we maintain Z order and
	* tests/winWm.test:		 focus of preexisting window when
	replacing the wrapper window.

2004-09-16  David Gravereaux <[email protected]>

	* win/makefile.vc : added VC7-safe environment check as used in the Tcl
	makefile.vc [Bug 1029349]

2004-09-16  Jeff Hobbs	<[email protected]>

	* generic/tkMenu.c (MenuWorldChanged): ensure that we recompute the
	menu geometry on WorldChanged to handle font size changes. [Bug 607649]

2004-09-16  Peter Spjuth  <[email protected]>

	* tests/place.test:
	* generic/tkPlace.c: Fixed a memory leak when a placed widget was
	forgotten. [Bug 1028888]

2004-09-14  Mo DeJong  <[email protected]>

	* win/tkWinWm.c (WmIconwindowCmd): Replace bogus call to
	XWithdrawWindow with proper code. This avoids a "couldn't send withdraw
	message to window manager" error when the iconwindow is already mapped.
	The wm iconwindow command does not seem to do much under Win32, but at
	least this avoids an error message.

2004-09-13  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (ReadIconFromFile): fix mem alloc to get the right size
	for both icons ('?:' order of precedence mistake).

2004-09-10  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (::tk::dialog::file::): Make sure that the state
	is reset properly when starting to run the dialog. [Bug 845189]

	* library/demos/filebox.tcl: Stop the use of tk_strictMotif from
	poisoning the rest of the widget demo. [Bug 1013942]

2004-09-10  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (ActivateWindow): SetFocus to grab window when clicking
	outside the grab window hierarchy. [Bug 220908]
	(UpdateWrapper): update to 2004-06-12 Kovalenko to account for whether
	the override window has a transient parent, and apply WS_POPUP in the
	correct case. The makes splash screens pop up as well as making
	dropdowns not grab focus away from the parent.

2004-09-10  Vince Darley  <[email protected]>

	TIP#169 IMPLEMENTATION

	* doc/text.n, generic/tkTest.c, generic/tkText.c, generic/tkText.h:
	* generic/tkTextBTree.c, generic/tkTextDisp.c, generic/tkTextImage.c:
	* generic/tkTextIndex.c, generic/tkTextMark.c, generic/tkTextTag.c:
	* generic/tkTextWind.c, generic/tkUndo.c, generic/tkUndo.h:
	* library/text.tcl, library/demos/twind.tcl, library/demos/widget:
	* tests/text.test, tests/textImage.test, tests/textIndex.test:
	* tests/textWind.test: implementation of TIP#169, which provides the
	new '$text peer' widget subcommand. This includes new documentation,
	tests, and an extension to the text widget demos to illustrate some of
	the new features. Many thanks also to Brian Griffin for the initial
	implementation.

2004-09-09  Jeff Hobbs	<[email protected]>

	* tests/panedwindow.test: bulletproof 23.2 result [Bug 1019100]

	* win/tkWinWm.c (ReadIconFromFile): when using SHGetFileInfo to
	retrieve icon, get regular icon as well for correct Alt-Tab icon.

2004-09-09  Donal K. Fellows  <[email protected]>

	* doc/wish.1: Added note that the -use option is linked to the frame's
	-container option to help with [Bug 1024364]

2004-09-06  Jeff Hobbs	<[email protected]>

	* library/tkfbox.tcl (::tk::dialog::file::Create): use label instead of
	button for "File of type", as it properly handles -state disabled now.

2004-09-06  Pat Thoyts	<[email protected]>

	* win/makefile.vc: Set TK_LIBRARY when execing Tk apps (test, runtest,
	rundemo).

2004-09-03  Donal K. Fellows  <[email protected]>

	* macosx/tkMacOSXMenus.c (GenerateEditEvent):
	* macosx/tkMacOSXMenu.c (MenuSelectEvent):
	* win/tkWinMenu.c (MenuSelectEvent): Make sure everywhere that needs to
	NULL-out the user_data field does actually do so. (Code that uses
	bzero() or memset() for the task just needs to be rebuilt to work).
	[Bug 1021812]

2004-09-01  Donal K. Fellows  <[email protected]>

	* tests/bind.test (bind-22.163): Fix inadvertent minor breakage from
	TIP#165. [Bug 1019085]

	* doc/toplevel.n, doc/loadTk.n: More spelling/abbreviation fixes from
	Mikhail Kolesnitchenko.

2004-08-29  Donal K. Fellows  <[email protected]>

	TIP#165 IMPLEMENTATION

	* generic/tk.h (XVirtualEvent): Added user_data field to structure.
	* generic/tkBind.c (ExpandPercents, HandleEventGenerate):
	* generic/tkEvent.c (Tk_HandleEvent): Handle putting data into the
	user_data field, passing it to scripts as %d substitution, and
	releasing the field's contents once the event has been processed.
	* doc/bind.n, doc/event.n, tests/bind.test: Docs + tests.

2004-08-26  Jeff Hobbs	<[email protected]>

	* library/text.tcl (::tk::TextTranspose): Ensure that Transpose is an
	atomic op to undo.

2004-08-25  Don Porter	<[email protected]>

	* macosx/tkMacOSXWm.c:	Made use of Tcl_WrongNumArgs in a few
	* win/tkWinMenu.c:	appropriate spots.

2004-08-22  Donal K. Fellows  <[email protected]>

	* doc/SetOptions.3, doc/SetClassProcs.3, doc/MeasureChar.3:
	* doc/GetVRoot.3, doc/GetHWND.3, doc/GetDash.3, doc/GetBitmap.3:
	* doc/FontId.3, doc/CrtItemType.3, doc/ConfigWidg.3, doc/GetCursor.3:
	More doc fixes from Mikhail Kolesnitchenko. [Patch 1013520]

2004-08-20  Donal K. Fellows  <[email protected]>

	* doc/TkInitStubs.3, doc/photo.n, doc/ParseArgv.3, doc/options.n:
	* doc/keysyms.n, doc/font.n: More doc fixes. [Patch 1012837]

	* doc/place.n, doc/pack.n, doc/grid.n, doc/getOpenFile.n:
	* doc/event.n, doc/chooseDirectory.n, doc/bind.n:
	Spelling and grammar fixes from Mikhail Kolesnitchenko. [Patch 1012083]

	* tests/canvas.test (canvas-17.1): Report the result of the test so
	that it can be compared. [Bug 1012331]

2004-08-19  Jeff Hobbs	<[email protected]>

	* win/tkWinDialog.c (Tk_MessageBoxObjCmd): Inherit the icon from the
	* win/tkWinInt.h:			   -parent window for the
	* win/tkWinWm.c (TkWinGetIcon):		   MessageBox.

2004-08-19  Joe English	 <[email protected]>

	* unix/tkUnixWm.c: Cast argument 7 of XChangeProperty to 'const
	unsigned char *' (from 'const char *') to satisfy Solaris 8 Forte C
	compiler [Bug 1012325]

2004-08-19  Don Porter	<[email protected]>

	* tests/safe.test (safe-1.3): Made test less sensitve to the full set
	of existing aliases in an interp, so the it only tests whether the
	tested ones are present.

	* unix/Makefile.in: Copied LD_LIBRARY_PATH machinery from `make shell`
	target to other similar targets so that just built libraries are
	tested, rather than previous installations.

2004-08-19  Donal K. Fellows  <[email protected]>

	TIP#168 IMPLEMENTATION

	* generic/tkTrig.c (TkMakeRawCurve, TkMakeRawCurvePostscript):
	* generic/tkInt.decls: New functions to handle the geometry for "raw"
	bezier curves.
	* generic/tkCanvUtil.c (tkRawSmoothMethod, InitSmoothMethods)
	(TkSmoothParseProc): Add new type of smoothing method, simplify the
	method initialization, and change the old smoothing method to be called
	"true" and just keep "bezier" as an alias.
	* tests/canvas.test (canvas-17.1): Basic test of built-in smoothing
	method support.
	* doc/canvas.n: Documentation updates.

2004-08-18  Donal K. Fellows  <[email protected]>

	* generic/tkPanedWindow.c (optionSpecs): Add missing GEOMETRY flag to
	-handlepad option. [Bug 1010938]

2004-08-17  Donal K. Fellows  <[email protected]>

	* doc/menu.n, doc/text.n: Assorted fixes, including spelling fixes from
	Mikhail Kolesnitschenko. [Patch 1010083]

	* doc/spinbox.n, doc/scrollbar.n, doc/scale.n, doc/panedwindow.n:
	* doc/message.n, doc/listbox.n, doc/entry.n, doc/button.n:
	More spelling fixes from Mikhail Kolesnitschenko. [Patch 1010607]

2004-08-16  Donal K. Fellows  <[email protected]>

	* doc/button.n, doc/checkbutton.n, doc/label.n, doc/menubutton.n:
	* doc/radiobutton.n: Added cross-reference to new standard option.
	* doc/options.n: Added standard documentation for the -compound
	option. [Bug 712588]

	* doc/canvas.n: Spelling and grammar fixes from Mikhail
	Kolesnitschenko. [Bug 1009636]

2004-08-11  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (ResolveFile): Added some environment variable
	handling; this isn't perfect, but should do what most people want most
	of the time. [FRQ 979101]
	* library/xmfbox.tcl (MotifFDialog_BuildUI): Fix [Bug 987169] in the
	Motif file dialogs as well.

2004-08-10  Joe English	 <[email protected]>

	* unix/tkUnixWm.c: Fix for [Bug 1006686] "wm resizable command not
	working on Solaris/CDE" (patch from Colin McDonald).

2004-08-09  Mo DeJong  <[email protected]>

	* tests/canvText.test:
	* win/tkWinFont.c (Tk_MeasureChars): Fix for text wrapping problem that
	appeared using canvas text under Win32. A long wrapping string that had
	leading spaces was being incorrectly wrapped. This change makes the
	Win32 implementation behave the same as the Unix implementation. [Patch
	1006286]

2004-08-05  Donal K. Fellows  <[email protected]>

	* library/clrpick.tcl (BuildDialog):
	* library/msgbox.tcl (MessageBox): Add scheme for cancelling dialog
	boxes with Escape and also handle what happens when the window gets
	nuked from outside. [Bug 987169]

2004-08-04  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoBlendComplexAlpha): Clean the code up a
	bit and add a few more comments.
	(Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Clarified the code,
	corrected the compositing rule now that I have looked up what the right
	thing to do is, and factorized out the compositing rule code into a few
	simpler macros.

2004-07-30  Daniel Steffen  <[email protected]>

	* unix/configure:
	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Darwin: instead of setting PLAT_OBJS
	to explict object files in tcl.m4, refer to MAC_OSX_OBJS makefile var.

2004-07-29  George Peter Staplin <[email protected]>

	* generic/tkEvent.c (TkQueueEventForAllChildren): Code from the
	core-8-4-branch to not queue events for unmapped windows was added.

2004-07-27  Daniel Steffen  <[email protected]>

	* generic/tkImgGIF.c (FileReadGIF): fix crash reported by Reinhard
	Max: in case of premature end of image data, return error instead of
	passing nil buffer to Tk_PhotoPutBlock().

2004-07-22  Jeff Hobbs	<[email protected]>

	* library/tkfbox.tcl (::tk::dialog::file::Update): use -directory [pwd]
	(instead of .) to get around some VFS edge case bugs. Correct args
	passes to tk_messageBox when failing to cd. Add -force back to
	namespace import of msgcat.

2004-07-20  Jeff Hobbs	<[email protected]>

	* generic/tkEvent.c (InvokeInputMethods): ensure IC focus is set after
	creation. [Bug 905830]

2004-07-20  Daniel Steffen  <[email protected]>

	* macosx/Makefile: added support to tk framework build to optionally
	install tk manpages in addition to html help, similarly to
	tcl/macosx/Makefile.

	* macosx/Wish.pbproj/project.pbxproj: fixes for building with
	non-default SYMROOT/OBJROOT/SRCROOT, added support for using a
	Tcl.framework in DYLIB_INSTALL_PATH != /Library/Frameworks, added
	optional support for building html help without tcl sources present by
	giving explicit location of tcltk-man2html script.

	* macosx/tkMacOSXMenu.c: fixed #include case sensitivity bug.

	* unix/Makefile.in:
	* win/Makefile.in: added 'install-private-headers' makefile target to
	allow optionally installing private tk headers. [Tcl FR 922727]

2004-07-16  Jeff Hobbs	<[email protected]>

	* unix/Makefile.in, unix/tcl.m4:     move (C|LD)FLAGS after their
	* unix/configure.in, unix/configure: _DEFAULT to allow for env setting
	to override m4 switches.
	Consolidate header checks to limit redundancy in configure.
	(CFLAGS_WARNING): Remove -Wconversion
	(SC_ENABLE_THREADS): Set m4 to force threaded build when built against
	a threaded Tcl core.
	Reorder configure.in for better 64-bit build configuration, replacing
	EXTRA_CFLAGS with CFLAGS. [Bug 874058]

2004-07-14  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXCursor.c (TkpSetCursor): The code to not reset the
	cursor more often than necessary was getting fooled when the current
	cursor was nulled out when the current cursor gets freed. So in the
	case where the input cursor was NULL, we have to just always set it.
	[Bug 894550]

2004-07-13  Don Porter	<[email protected]>

	* library/tkfbox.tcl: Corrected coding errors in most recent change.
	Use [bind $w], not [$w configure] to modify bindings.

2004-07-11  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (::tk::dialog::file::Create): Watch out for users
	destroying the dialog indirectly. [Bug 987169]

2004-07-07  Donal K. Fellows  <[email protected]>

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

2004-07-05  George Peter Staplin <[email protected]>

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

2004-07-05  Donal K. Fellows  <[email protected]>

	TIP#158 IMPLEMENTATION

	* tests/bind.test:		   Allow Win apps to distinguish keys
	* win/tkWinX.c (GetState):	   on the keypad using the Extended
	* generic/tkInt.h (EXTENDED_MASK): modifier. Thanks to Wolfgang
	* generic/tkBind.c:		   Grossbauer and Kevin Kenny for
	* doc/bind.n:			   developing this patch [Patch 797404]

2004-07-05  Joe English	 <[email protected]>

	* unix/tkUnixWm.c: Set _NET_WM_NAME and _NET_WM_ICON_NAME
	(freedesktop.org) in addition to WM_NAME and WM_ICON_NAME (ICCCM). This
	allows the full Unicode character set to be used in window manager
	strings (but only for newer WMs that support the EWMH spec). [Bug
	959973]

2004-07-02  George Peter Staplin <[email protected]>

	* generic/tkEvent.c: Tk_HandleEvent was refactored to be more readable,
	and during this process two bugs were found.
	1) Button 4 and 5 masks will now be synchronized with the TkDisplay.
	2) ClientMessage handlers will use the proper last pointer rather than
	writing to the last GenericHandler pointer.

	Thanks to Joe English for his help and encouragement, and DKF for
	review.

2004-07-01  Donal K. Fellows  <[email protected]>

	* doc/place.n, doc/pack.n: Doc fixes. [Tcl Bug 983146]

2004-06-30  Donal K. Fellows  <[email protected]>

	TIP#153 IMPLEMENTATION

	* generic/tkCmds.c (GetTopHierarchy): Modified from GetToplevel so
	* doc/winfo.n:			      that [winfo toplevel] does not
	assume that it is really working with toplevels. Occasionally this is
	important. Thanks to Neil McKay for this patch!

2004-06-29  Jeff Hobbs	<[email protected]>

	* generic/tkCmds.c (Tk_WinfoObjCmd): refetch interp result obj for
	'winfo id' as it can change when making the window exist.

2004-06-26  Joe Mistachkin  <[email protected]>

	* generic/tkConsole.c (ConsoleDeleteProc): Set tsdPtr->gStdoutInterp to
	NULL when the console command is deleted [Bug 756840]. Also, added
	Tcl_Preserve/Tcl_Release for consoleInterp in InterpreterCmd in case it
	gets deleted during the calls to Tcl_GlobalEval and Tcl_RecordAndEval.

2004-06-24  Donal K. Fellows  <[email protected]>

	* tests/canvPs.test, etc: Use standard tcltest constraint names.

2004-06-19  Daniel Steffen  <[email protected]>

	* unix/tcl.m4: autoconf 2.5 fixes in Darwin section.
	* unix/configure: autoconf-2.57

2004-06-17  Donal K. Fellows  <[email protected]>

	* tests/constraints.tcl, tests/*.test: Systematization of test
	constraints so many common and basic constraints are defined once with
	a single name.

2004-06-16  Joe English	 <[email protected]>

	* unix/tkUnixWm.c, win/tkWinWm.c, macosx/tkMacOSXWm.c, tests/wm.test
	* tests/unixWm.test: Fix for [Bug 742882] "Potential division by zero
	in gridded wm geometry"

2004-06-15  Anton Kovalenko <[email protected]>

	* win/tkWinButton.c: Add a 3D highlight to disabled *buttons and
	labels, the same way as it's now done for disabled menu entries.

2004-06-15  Donal K. Fellows  <[email protected]>

	* doc/image.n: Enhanced the documentation to take into account the
	concerns raised in [RFE 803060]

	* tests/canvas.test: Updated tests affected by the change to
	ScrollFractions, which is now clean about result generation.

	* generic/tkCanvas.c: Make tag search subsystem use symbolic names for
	type flags for easier maintenance.
	(FIRST_CANVAS_ITEM_MATCHING,FOR_EVERY_CANVAS_ITEM_MATCHING): Factorize
	out searching idioms into macros to reduce the #ifdef count and make
	braces match.
	(ScrollFractions): Really create a list Tcl_Obj.

2004-06-12  Anton Kovalenko <[email protected]>

	* win/tkWinWm.c (UpdateWrapper): Let overrideredirect'ed window's
	wrapper be the child of desktop window, thus making it to behave more
	similarly to X11 Override Redirect. Esp. useful for combobox-like
	megawidgets.

2004-06-09  Vince Darley  <[email protected]>

	* generic/tkText.c:
	* tests/text.test: fix to multi-line regexp search bugs in text widget
	(reported against Alphatk editor, not on sf). Addded 3 new tests.

2004-06-09  Donal K. Fellows  <[email protected]>

	* generic/tkUndo.c (TkUndoSetDepth): Delete the unlinked element and
	not the next element. Stops a crash in some situations and a memory
	leak in others. Thanks to Jiang Wu for spotting this. [Bug 969358]

2004-06-08  Mo DeJong  <[email protected]>

	* generic/tkCanvText.c (DisplayCanvText): Fix text rendering problem
	with canvas text items that have a selected region. The previous
	implementation would render the whole line and then redraw the
	selected text if it was a different color. This caused problems when
	the selected text foreground differs from the normal text foreground,
	the anti-aliasing alpha pixels for the two text strings would blend
	together resulting in strange looking text. The fix is to draw the
	normal text and the selected text separately. This problem has only
	been observed under Windows, with anti-aliased text. [Patch 968725]

2004-06-07  Vince Darley  <[email protected]>

	* generic/tkTextDisp.c:
	* generic/tkTextBTree.c: fix to (Bug 965186) in which the text widget's
	record of partial-line-height calculations (for very long wrapped
	lines) was being incorrectly reused. This resulted in confusing
	scrollbar-text interactions.

2004-06-06  Pat Thoyts	<[email protected]>

	* tests/frame.test:	Fix frame-2.8 for ![info exists env(DISPLAY)]

2004-06-04  Don Porter	<[email protected]>

	* tests/filebox.test:	A few typo corrections in dkf's recent style
	* tests/frame.test:	upgrade for the test suite.
	* tests/select.test:
	* tests/visual.test:

2004-06-04  Vince Darley  <[email protected]>

	* generic/tkTextIndex.c:
	* generic/tkText.c:
	* generic/tkTextDisp.c:
	* doc/text.n: fix to shimmering infinite loop scrolling problem in text
	widget under some rare circumstances (Bug 965398). Improved comments
	and documentation.

	* tests/textDisp.test: corrected rounding from float to int in test,
	fixing occasional failures

	* library/text.tcl: corrected mousewheel bindings for TkAqua

2004-05-29  Joe English	 <[email protected]>

	* doc/messageBox.n: Fix minor markup errors (backslash is \e, not \b).

2004-05-24  Donal K. Fellows  <[email protected]>

	* doc/messageBox.n: Added documentation for the -detail option.
	* tests/msgbox.test: Updated test suite with correct list of options.
	* win/tkWinDialog.c (Tk_MessageBoxObjCmd): Added "support" for the
	-detail option by concatenating it onto the end of the message.

2004-05-24  Jim Ingham	<[email protected]>

	* tkMacOSXDialog.c (Tk_MessageBoxObjCmd): Turn on the -detail option
	for Mac OS X.

2004-05-23  Donal K. Fellows  <[email protected]>

	* ChangeLog.2002: Split older ChangeLog entries off into a separate
	file.
	* doc/bindtags.n: Added example.

	* tests/*.test: Many minor fixes aiming towards making the Tk test
	suite have better style. (A very large fraction of test files were
	modified.)

	* generic/tkVisual.c (Tk_GetVisual): Minor fix for error message.

2004-05-14  Donal K. Fellows  <[email protected]>

	TIP#152 IMPLEMENTATION (Unix only)

	* library/msgbox.tcl (MessageBox): Added TIP#152's -detail option for
	Unix/X11 platforms. Also shrank the size of the main -message text
	which was grossly large.

2004-05-12  Chengye Mao <[email protected]>

	* generic/tkBind.c <HandleEventGenerate>: Modified to fix wish crash
	due to incorrectly generate <Destroy> event. This bug was reported in
	comp.lang.tcl but not logged.

2004-05-07  Chengye Mao <[email protected]>

	* win/tkWinWm.c <UpdateWrapper>: handle and destroy old wrapper
	correctly and fix crash problem in wish exiting [Bug 767176].

2004-05-05  Jeff Hobbs	<[email protected]>

	* win/tkWinFont.c (FindSubFontForChar): corrections to dkf patch to
	handle subFontPtrPtr in EnumFontFamilies callback.

2004-05-05  Donal K. Fellows  <[email protected]>

	* win/tkWinFont.c (Tk_MeasureChars,Tk_DrawChars,etc): Make sure that
	the lastSubFontPtr remains valid even when the subfont array is
	reallocated. [Bug 618872]

2004-05-03  Jeff Hobbs	<[email protected]>

	* unix/tkUnixButton.c (TkpDrawCheckIndicator): allow radiobuttons to be
	drawn when disabledforeground and/or selectcolor are NULL.
	[Bug 826850] (griffin)

	* win/tkWinMenu.c, unix/tkUnixMenu.c (DrawMenuEntryLabel): place images
	of compound menu entries in indicator space if not a radio of
	checkbutton. [Bug 756952] (eserte)

	* win/tkWinX.c:		       fix drawing of unicode chars in menu
	* win/tkWinInt.h (TkWinProcs): titles. [Bug 904371] (riefenstahl)
	* win/tkWinMenu.c (ReconfigureWindowsMenu):

	* generic/tkClipboard.c:   Move TkClipCleanup from tkClipboard.c to
	* macosx/tkMacOSXXStubs.c: being implemented in a platform-specific
	* unix/tkUnixEvent.c:	   manner. The cleanup order was bad at least
	* win/tkWinX.c:		   on Windows, where we reset/cleared display
	info that was still needed for the clipboard to render. [Bug 939389,
	822002, 732662]

	* library/panedwindow.tcl (MarkSash): call DragSash to stop sash jump
	when B1 is pressed and released without moving. [Bug 932155]

	* tests/panedwindow.test: panedwindow-25.1
	* generic/tkPanedWindow.c (Unlink): clean up -before/-after refs to a
	slave when removing it. [Bug 928413] (griffin)

	* generic/tkImgPhoto.c (ImgPhotoConfigureMaster): force -data into
	ByteArray and -format into String to correctly handle them if they
	have been shimmered or created as some other object type.

2004-04-24  Daniel Steffen  <[email protected]>

	* generic/tkPort.h:
	* unix/Makefile.in:
	* win/makefile.bc:
	* win/Makefile.in: followup on tcl header reform [FR 922727]: removed
	use of relative #include paths in tkPort.h to allow installation of
	private headers outside of tk source tree; added tcl plaform source dir
	to compiler header search path.

2004-04-23  Donal K. Fellows  <[email protected]>

	* doc/bind.n: Added examples (in line with the parallel programme for
	adding examples to Tcl manual pages) and made assorted minor
	alterations to improve the overall look.

2004-04-21  Donal K. Fellows  <[email protected]>

	* tests/textDisp.test: Get rid of windows that are no longer needed so
	single-proc tests don't have extra windows hanging around unexpectedly.

2004-04-21  Benjamin Riefenstahl  <[email protected]>

	Mac OS X: Fix several problems with Icelandic (and Faroese) keyboards
	reported by Jérôme Gagnon-Voyer <gagnonje5000<at>mac<dot>com> on
	tcl-mac on 2004-03-22.

	* macosx/tkMacOSXKeyEvent.c (KLSInit): Add.
	(GetKeyboardLayout): Add calls to Keyboard Layout Services, if present.
	Rework classic handling. Use GetKCHREncoding(). Add parameter
	encodingPtr.
	(GetKCHREncoding): Add.

2004-04-16  Jeff Hobbs	<[email protected]>

	* library/bgerror.tcl (bgerror): rework to only set -topmost bit on
	Windows if necessary. Also use existing ::tk functions for placing
	dialog and managing focus/grab.

2004-04-04  Joe English	 <[email protected]>

	* unix/tkUnixWm.c: Fix for [Bug 915350] "Tk sets min, max size in
	WM_HINTS when it shouldn't" and [Bug 922336] "Tk apps have no maximize
	window button under KDE-3.2.1"

2004-03-31  Jim Ingham	<[email protected]>

	* tkMacOSXCarbonEvents.c (AppEventHandlerProc): Handle the
	kEventAppHidden and kEventAppShown events.
	(TkMacOSXInitCarbonEvents): Register for the above events.
	* tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): Steal the
	Command-H menu key event and allow the Application handler to have it.
	This is currently the only way to get the Hide behavior to work. [Bug
	917557]

	* tkMacOSMenus.c (TkMacOSXHandleMenuSelect): Remove the Quit menu
	handler - this was for the Quit item in the File menu, but it doesn't
	belong there.
	(TkMacOSXInitMenus): Remove the Quit menu item from the File menu.

	* tkMacOSXMenu.c (EventuallyInvokeMenu): Report errors from invoking
	menu commands as background errors. [Bug 220871]

2004-03-31  Don Porter	<[email protected]>

	* generic/tkImgPhoto.c:	Removed outdated #include's of the tclMath.h
	* generic/tkScale.c:	header file. All tk*Port.h files have long had
	a #include <math.h>, and other parts of Tk routinely make use of
	libm-supplied math routines.

2004-03-30  Daniel Steffen  <[email protected]>

	* macosx/tclets.r (removed): obsolete holdover from mac classic.

2004-03-26  Donal K. Fellows  <[email protected]>

	* generic/tkImgPPM.c (ReadPPMStringHeader): Code to read PPM/PGM data
	(StringReadPPM, StringMatchPPM): from strings/bytearrays. [FRQ 540375]

2004-03-26  Don Porter	<[email protected]>

	* unix/tcl.m4:	Replaced -Wno-strict-alias with more portable
	-fno-strict-alias alternative.

	* README:		Bump version to 8.5a2.
	* generic/tk.h:
	* macosx/Wish.pbproj/project.pbxproj:
	* unix/configure.in:
	* unix/tk.spec:
	* win/configure.in:

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

2004-03-26  Donal K. Fellows  <[email protected]>

	* generic/tkImgPPM.c (StringWritePPM): New function to support
	converting of images to PPM strings. Other direction not yet done. Rest
	of file converted to use new image API.
	* generic/tkImgPhoto.c (ImgPhotoCmd): Restored support for the
	stringWriteProc of old photo formats. [Bug 923555]

2004-03-25  Donal K. Fellows  <[email protected]>

	* doc/winfo.n: Clarified the range of colour intensities returned by
	[winfo rgb]. [Bug 922610]

2004-03-22  Donal K. Fellows  <[email protected]>

	* doc/ConfigWidg.3: Converted malloc/free to Tcl_Alloc/Tcl_Free to help
	avoid confusion and crashes on Windows. [Bug 920695]

2004-03-20  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXSubwindows.c (GenerateConfigureNotify): New function.
	(XMoveWindow): Generate configure notify events for child widgets on
	move.
	(XMoveResizeWindow): Ditto.

2004-03-18  Daniel Steffen  <[email protected]>

	Removed support for Mac OS Classic platform [Patch 918139]

	* doc/console.n:
	* doc/tk.n:
	* generic/README:
	* generic/default.h:
	* generic/tk.decls:
	* generic/tk.h:
	* generic/tkBind.c:
	* generic/tkCmds.c:
	* generic/tkConsole.c:
	* generic/tkFileFilter.h:
	* generic/tkGrab.c:
	* generic/tkInitScript.h:
	* generic/tkInt.decls:
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkMain.c:
	* generic/tkPlatDecls.h:
	* generic/tkPointer.c:
	* generic/tkPort.h:
	* generic/tkSelect.c:
	* generic/tkStubInit.c:
	* generic/tkStubLib.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkWindow.c:
	* library/bgerror.tcl:
	* library/button.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/msgbox.tcl:
	* library/spinbox.tcl:
	* library/tearoff.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/demos/text.tcl:
	* library/demos/widget:
	* mac/MW_TkBuildLibHeader.h (removed):
	* mac/MW_TkBuildLibHeader.pch (removed):
	* mac/MW_TkHeader.h (removed):
	* mac/MW_TkHeader.pch (removed):
	* mac/MW_TkHeaderCommon.h (removed):
	* mac/MW_TkOldImgHeader.h (removed):
	* mac/MW_TkOldImgStaticHeader.h (removed):
	* mac/MW_TkStaticHeader.h (removed):
	* mac/MW_TkStaticHeader.pch (removed):
	* mac/MW_TkTestHeader.h (removed):
	* mac/MW_TkTestHeader.pch (removed):
	* mac/README (removed):
	* mac/bugs.doc (removed):
	* mac/tclets.r (removed):
	* mac/tclets.tcl (removed):
	* mac/tkMac.h (removed):
	* mac/tkMacAppInit.c (removed):
	* mac/tkMacAppearanceStubs.c (removed):
	* mac/tkMacApplication.r (removed):
	* mac/tkMacBitmap.c (removed):
	* mac/tkMacButton.c (removed):
	* mac/tkMacClipboard.c (removed):
	* mac/tkMacColor.c (removed):
	* mac/tkMacConfig.c (removed):
	* mac/tkMacCursor.c (removed):
	* mac/tkMacCursors.r (removed):
	* mac/tkMacDefault.h (removed):
	* mac/tkMacDialog.c (removed):
	* mac/tkMacDraw.c (removed):
	* mac/tkMacEmbed.c (removed):
	* mac/tkMacFont.c (removed):
	* mac/tkMacHLEvents.c (removed):
	* mac/tkMacInit.c (removed):
	* mac/tkMacInt.h (removed):
	* mac/tkMacKeyboard.c (removed):
	* mac/tkMacLibrary.r (removed):
	* mac/tkMacMDEF.c (removed):
	* mac/tkMacMDEF.r (removed):
	* mac/tkMacMenu.c (removed):
	* mac/tkMacMenu.r (removed):
	* mac/tkMacMenubutton.c (removed):
	* mac/tkMacMenus.c (removed):
	* mac/tkMacPort.h (removed):
	* mac/tkMacProjects.sea.hqx (removed):
	* mac/tkMacRegion.c (removed):
	* mac/tkMacResource.r (removed):
	* mac/tkMacScale.c (removed):
	* mac/tkMacScrlbr.c (removed):
	* mac/tkMacSend.c (removed):
	* mac/tkMacSubwindows.c (removed):
	* mac/tkMacTclCode.r (removed):
	* mac/tkMacTest.c (removed):
	* mac/tkMacWindowMgr.c (removed):
	* mac/tkMacWm.c (removed):
	* mac/tkMacXCursors.r (removed):
	* mac/tkMacXStubs.c (removed):
	* mac/widget.r (removed):
	* tests/clrpick.test:
	* tests/cursor.test:
	* tests/entry.test:
	* tests/font.test:
	* tests/macEmbed.test (removed):
	* tests/macFont.test (removed):
	* tests/macMenu.test (removed):
	* tests/macWinMenu.test (removed):
	* tests/macscrollbar.test (removed):
	* tests/menuDraw.test:
	* tests/safe.test:
	* tests/scrollbar.test:
	* tests/select.test:
	* tests/spinbox.test:
	* tests/text.test:
	* tests/tk.test:
	* tests/winfo.test:
	* tests/wm.test:
	* unix/Makefile.in:
	* unix/README:
	* unix/tk.spec:
	* unix/tkUnix3d.c:
	* unix/tkUnixDraw.c:
	* xlib/xgc.c:
	* xlib/xutil.c:
	* xlib/X11/X.h:
	* xlib/X11/Xlib.h:
	* xlib/X11/Xutil.h:
	* xlib/X11/keysym.h:

2004-03-16  Jeff Hobbs	<[email protected]>

	* unix/tkUnixButton.c (TkpDrawCheckIndicator): correct crash condition
	for new radio/checkbuttons when colors are exhausted.
	[Bug 915330] (griffin)

	* generic/tkGrid.c (GridRowColumnConfigureCommand): fix lint warning

	* generic/tkCanvUtil.c: fix cast warnings

	* generic/tkTextImage.c (EmbImageConfigure): fix casts

	* unix/tkUnixSelect.c (ConvertSelection, TkSelPropProc): fix casts

	* unix/configure, unix/tcl.m4: add -Wno-strict-aliasing for GCC to
	suppress useless type puning warnings.

2004-03-08  David Gravereaux <[email protected]>

	* win/makefile.vc:
	* win/buildall.vc.bat:	Checks MSDevDir, not MSVCDir envar.

2004-03-04  Mo DeJong  <[email protected]>

	* win/tkWin32Dll.c: Add variables needed when compiling with mem debug
	under Mingw. This fixes the checking from 2003-12-25.

2004-03-03  Jeff Hobbs	<[email protected]>

	*** 8.5a1 TAGGED FOR RELEASE ***

	* unix/Makefile.in (dist): don't require win/lamp.bmp copy in dist
	target (it's already handled by win/rc/*.bmp copy)

	* changes: updated for 8.5a1

2004-03-01  Jeff Hobbs	<[email protected]>

	* README:	update to patchlevel 8.5a1
	* generic/tk.h:
	* macosx/Wish.pbproj/project.pbxproj:
	* unix/configure, unix/configure.in, unix/tk.spec:
	* win/configure, win/configure.in:

	* unix/tcl.m4: update HP-11 build libs setup

2004-03-01  Don Porter	<[email protected]>

	* unix/tcl.m4 (SC_CONFIG_CFLAGS):	Allow 64-bit enabling on
	IRIX64-6.5* systems. [Bug 218561]
	* unix/configure:	autoconf-2.57

2004-02-28  Vince Darley  <[email protected]>

	* generic/tkTextIndex.c: remove use of internal Tcl interface
	'TclUtfToUniChar'

2004-02-25  Benjamin Riefenstahl  <[email protected]>

	* library/demos/widget (addFormattedText): Correct off-by-one error.

2004-02-23  Daniel Steffen  <[email protected]>

	* macosx/Makefile: ensure that xcodebuild will use the Wish.pbproj
	project even if a .xcode project is also present.

	* macosx/tkMacOSXMouseEvent.c: fixed modifiers for MouseWheel events.

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/tkAboutDlg.r: changed year in copyright strings to 2004.

2004-02-23  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXXStubs.c:
	* xlib/ximage.c: fixed MacOSX XGetImage/XPutImage and related functions
	to deal properly with XImages copied from screen.
	* generic/tkCanvPs.c (TkImageGetColor): MacOSX fix. [Bug 809157]

2004-02-18  Peter Spjuth  <[email protected]>

	* tests/grid.test:
	* generic/tkGrid.c: Fixed a bug in grid geometry calculations for a
	shrinking grid. [Bug 899246]

2004-02-17  Benjamin Riefenstahl  <[email protected]>

	* macosx/tkMacOSXKeyboard.c (TkpInitKeymapInfo): Don't make <Alt> and
	<Meta> synonyms for <Command> and <Option> for now.

2004-02-17  Jeff Hobbs	<[email protected]>

	* generic/tkBind.c (HandleEventGenerate): only modify root[xy] with
	[xy] when they haven't been otherwise set.

	TIP#110 IMPLEMENTATION

	* doc/checkbutton.n: Tristate Checkbutton and Radiobuttons
	* doc/radiobutton.n:
	* generic/tkButton.c:
	* generic/tkButton.h:
	* library/demos/check.tcl:
	* library/demos/radio.tcl:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDefault.h:
	* tests/button.test:
	* unix/tkUnixButton.c:
	* unix/tkUnixDefault.h:
	* win/tkWinButton.c:
	* win/tkWinDefault.h:

2004-02-17  Don Porter	<[email protected]>

	* tests/imgPhoto.test (imgPhoto-16.1): Corrected incorrect variable
	name [Bug 899010].

2004-02-15  Jim Ingham	<[email protected]>

	* tkMacOSXDialog.c (MatchOneType): If the Macintosh filetype is 0, then
	automatically pass the fileType check.

	* tkMacOSXCarbonEvents.c: New file - this doesn't do anything yet -
	just registers for a couple of App Events.

	* tkMacOSXInit.c (TkpInit.c): Call TkMacOSXInitCarbonEvents.c.

	* tkMacOSXAppInit.c: Formatting cleanups.
	* tkMacOSXButton.c: Ditto
	* tkMacOSXClipboard.c: Ditto
	* tkMacOSXDebug.c: Ditto
	* tkMacOSXDialog.c: Ditto
	* tkMacOSXDraw.c: Ditto
	* tkMacOSXEvent.c: Ditto
	* tkMacOSXFont.c: Ditto
	* tkMacOSXHLEvents.c: Ditto
	* tkMacOSXInit.c: Ditto
	* tkMacOSXInt.h
	* tkMacOSXKeyEvent.c: Ditto
	* tkMacOSXMenu.c: Ditto
	* tkMacOSXMenubutton.c: Ditto
	* tkMacOSXMouseEvent.c: Ditto
	* tkMacOSXNotify.c: Ditto
	* tkMacOSXScale.c: Ditto
	* tkMacOSXScrlbr.c: Ditto
	* tkMacOSXSubwindows.c: Ditto
	* tkMacOSXWindowEvent.c: Ditto
	* tkMacOSXWm.c: Ditto

2004-02-13  Jim Ingham	<[email protected]>

	* tkMacOSXDialog.c (Tk_GetOpenFileObjCmd): Use CFStringRef for title &
	message options, not pascal strings.
	(Tk_GetSaveFileObjCmd): Ditto
	(Tk_ChooseDirectoryObjCmd): Ditto
	(NavServicesGetFile): Now that we get CFStrings, we don't need to
	convert them here.

	* tkMacOSXMenu.c (TkMacOSXDispatchMenuEvent): Cleanup, we don't need to
	handle the Apple Menu picks any more, but the code didn't reflect that.

	* tkMacOSXWm.c (TkSetWMName): Use CFStrings for the Window Title name,
	not Pascal strings.

2004-02-12  Jeff Hobbs	<[email protected]>

	* win/tkWinDialog.c (ChooseDirectoryValidateProc): create a pidl for
	-initialdir if we have a UNC path because BFFM_SETSELECTION doesn't
	support UNC paths in strings.

2004-02-10  Donal K. Fellows  <[email protected]>

	* library/msgs/eo.msg:	Language support for Esperanto and Polish from
	* library/msgs/pl.msg:	Artur Trzewik <[email protected]> with thanks.

2004-02-09  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock):
	* tests/imgPhoto.test (imgPhoto-16.1): Better handling of the case when
	copying from one area of a photo to another triggers a resizing of the
	image. [Bug 877950]

2004-02-07  David Gravereaux <[email protected]>

	* win/makefile.vc:
	* win/rules.vc:
	* win/rc/tk.rc:
	* win/rc/wish.rc: Now supports the 'unchecked' option when building.

2004-02-03  Jeff Hobbs	<[email protected]>

	* doc/menubutton.n:
	* library/menu.tcl (::tk::MbPost): make menubuttons that post above or
	below reverse direction when not enough space is available.

2004-02-01  David Gravereaux <[email protected]>

	* win/lamp.bmp (deleted): using win/rc/lamp.bmp instead.

	* win/winMain.c: Removed our custom setargv() in favor of __argc and
	__argv exported by the C run-time.

	* win/makefile.vc:
	* win/rc/tk.rc:
	* win/rc/wish.rc: General clean-up.

	* win/rules.vc:
	* win/nmakehlp.c: sync'd to Tcl.

2004-01-31  Joe English	 <[email protected]>

	* unix/tkUnixWm.c, unix/tkUnixEvent.c: Replaced TclpGetTime() with
	Tcl_GetTime(), to remove dependency on tclInt.h [Bug 874745].

2004-01-27  Daniel Steffen  <[email protected]>

	* generic/tkTextIndex.c: added '#include <tclInt.h>' since the code
	uses the TclUtfToUniChar macro from that file. [Bug 874745]

	* macosx/Wish.pbproj/project.pbxproj: removed erroneous reference to
	mkpsenc.tcl in bundle resources phase (mkpsenc.tcl is already part of
	the copy files phase to Resources/Scripts).

	* macosx/Makefile: added support for 'xcodebuild' on Mac OS X 10.3.

2004-01-25  Benjamin Riefenstahl  <[email protected]>

	* macosx/tkMacOSXKeyboard.c: Fix regressions due to the last patches.

2004-01-25  Peter Spjuth  <[email protected]>

	* library/dialog.tcl:
	* library/msgbox.tcl: The dialogs were affected by the TIP#146
	implementation. Added grid anchor commands to restore original
	behaviour.

2004-01-15  David Gravereaux <[email protected]>

	* win/tkWinSendCom.c: Placed the requirement for the special COM
	libraries into the object file itself with #pragma comment (lib, ...)
	when built with VC++. This will simplify linking for users of the
	static library. uuid.lib is required for VC5.2, but is implicit with
	VC6.

	* win/makefile.vc: Removed 'ole32.lib oleaut32.lib uuid.lib' from
	$(baselibs).

2004-01-12  David Gravereaux <[email protected]>

	* generic/tk3d.c:	All uses of 'panic' (the macro) changed to
	* generic/tkBind.c:	'Tcl_Panic' (the function). The #define of
	* generic/tkBitmap.c:	panic in tcl.h clearly states it is deprecated
	* generic/tkCanvArc.c:	in the comments. [Tcl Patch 865264]
	* generic/tkCanvBmap.c:
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkColor.c:
	* generic/tkConfig.c:
	* generic/tkCursor.c:
	* generic/tkError.c:
	* generic/tkEvent.c:
	* generic/tkFocus.c:
	* generic/tkFont.c:
	* generic/tkFrame.c:
	* generic/tkGC.c:
	* generic/tkGrid.c:
	* generic/tkImgBmap.c:
	* generic/tkImgPhoto.c:
	* generic/tkImgUtil.c:
	* generic/tkMenu.c:
	* generic/tkObj.c:
	* generic/tkPack.c:
	* generic/tkPlace.c:
	* generic/tkRectOval.c:
	* generic/tkSelect.c:
	* generic/tkText.c:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextIndex.c:
	* generic/tkTextMark.c:
	* generic/tkTextWind.c:
	* generic/tkVisual.c:
	* generic/tkWindow.c:
	* mac/tkMacAppInit.c:
	* mac/tkMacAppearanceStubs.c:
	* mac/tkMacButton.c:
	* mac/tkMacDraw.c:
	* mac/tkMacEmbed.c:
	* mac/tkMacFont.c:
	* mac/tkMacInit.c:
	* mac/tkMacMenus.c:
	* mac/tkMacPort.h:
	* mac/tkMacSubwindows.c:
	* mac/tkMacWm.c:
	* mac/tkMacXStubs.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXPort.h:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnix3d.c:
	* unix/tkUnixColor.c:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixEvent.c:
	* unix/tkUnixFocus.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixSelect.c:
	* unix/tkUnixSend.c:
	* unix/tkUnixWm.c:
	* win/tkWin3d.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinDialog.c:
	* win/tkWinDraw.c:
	* win/tkWinEmbed.c:
	* win/tkWinFont.c:
	* win/tkWinPixmap.c:
	* win/tkWinPointer.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:

	* win/rc/tk.rc:
	* win/rc/tk_base.rc:
	* win/rc/wish.rc:
	* win/makefile.vc: Refreshed how the resource files are built. Should
	be a bit easier for people linking with a static Tk library.

	* win/lamp.bmp (deleted):
	* win/rc/lamp.bmp (new): Moved.

	* win/rules.vc:	 Sync'd to Tcl, respects the CHECKS=nodep command line
	macro and was used to verify the Tcl_Panic change above.

2004-01-09  Peter Spjuth  <[email protected]>

	TIP#146 IMPLEMENTATION

	* doc/grid.n:
	* tests/grid.test:
	* generic/tkGrid.c: Implementation of TIP#146, "Add Overall Anchoring
	to the Grid Geometry Manager", adding [grid anchor] subcommand.
	**** POTENTIAL VISUAL INCOMPATABILITY ****

2004-01-07  Vince Darley <[email protected]>

	* generic/tkTextDisp.c:
	* generic/tkTextBTree.c:
	* tests/text.test: fixed crashing [Bug 872299] in yview code, and added
	tests and better error checking in the B-tree.

2004-01-07  Vince Darley <[email protected]>

	* generic/tkTextIndex.c:
	* tests/textIndex.test: fixed bug in which 'wordstart' and 'wordend'
	were not utf-8 aware (they haven't been changed since Tk 8.0), and
	added tests.

2004-01-07  Vince Darley <[email protected]>

	* win/tkWinMenu.c: only provide a submenu handle when the MF_POPUP flag
	is given, fixing a recently-introduced crash when submenus are
	disabled. Also better error checking for this sort of situation in the
	future.

2003-12-31  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: added missing private headers to
	installed Tk.framework, so that tkInt.h can be included sucessfully
	from Tk.framework/PrivateHeaders.
	* generic/tkPort.h: corrected include of tkMacOSXPort.h

2003-12-28  Mo DeJong  <[email protected]>

	* win/tkWinMenu.c (ReconfigureWindowsMenu): Fix drawing of a disabled
	(TkWinHandleMenuEvent, DrawMenuEntryArrow): cascade menu arrow. Tk was
	displaying a disabled cascade menu arrow in black instead of gray. This
	was caused by a bug in the Win32 code for user drawn menu items. The
	fix is to avoid telling Windows that the menu item is a cascade type
	and then draw the gray arrow bitmap on our own. [Patch 865842]

2003-12-27  Mo DeJong  <[email protected]>

	* win/tkWinMenu.c (DrawWindowsSystemBitmap): Fix a strange Win32 bug
	where the logical coordinates returned by a call to DPtoLP are wrong
	the first time a menu is posted. This bug manifested itself by drawing
	the bitmap in the wrong place in a menu. The fix was to pass the newly
	created DC instead of the DC from the window.

2003-12-26  Mo DeJong  <[email protected]>

	* win/tkWinMenu.c (DrawMenuEntryAccelerator):
	(DrawMenuEntryLabel): When drawing the label text and accelerator text
	for a disabled menu entry be sure to draw a 3D highlight. The only
	exception to this is when a disabled menu entry is highlighted, in that
	case do not draw a 3D hightlight.

2003-12-26  Mo DeJong  <[email protected]>

	* win/tkWinMenu.c (DrawMenuEntryAccelerator, DrawMenuEntryArrow): Move
	the unused menu arrow drawing code in DrawMenuEntryAccelerator into a
	new function named DrawMenuEntryArrow. This makes no functional change
	but it will make it easier to fix things in the future.

2003-12-25  Mo DeJong  <[email protected]>

	* win/tkWin32Dll.c (DllMain): Add HAVE_NO_SEH blocks in place of __try
	and __except statements to support gcc builds. This is needed after
	David's changes on 2003-12-21. [Tcl patch 858493]

2003-12-22  David Gravereaux <[email protected]>

	* win/nmakehlp.c:
	* win/rules.vc: sync'd to Tcl.

	* win/makefile.vc: Uses new features of nmakehlp to get the version
	strings from header files without the use of hardcoded values.

	* generic/tk.h: removed the note about having to update makefile.vc
	when the version changes.

2003-12-22  Joe English	 <[email protected]>

	* doc/text.n: Fix markup errors (".t" at beginning of line).

2003-12-21  David Gravereaux <[email protected]>

	* generic/tkEvent.c:  Added three new functions: TkCreateExitHandler,
	* generic/tkInt.h:    TkDeleteExitHandler, and TkFinalize. This adds an
	* generic/tkMenu.c:   insertion point so Tk's exit handlers can be
	* generic/tkWindow.c: called on their own from tk85.dll's DllMain for
	* mac/tkMacButton.c:  DLL_PROCESS_DETACH. These are private to the
	* unix/tkUnixEvent.c: binary and not exported. It is possible the
	* win/tkWin32Dll.c:   Windows OS can unload Tk _prior_ to Tcl under
	* win/tkWinEmbed.c:   some conditions such as ExitProcess(). This
	* win/tkWinMenu.c:    avoids a dangling pointer problem when Tcl does
	* win/tkWinX.c:	      Tcl_Finalize after Tk has been unloaded.
	* win/winMain.c:      DllMain's DLL_PROCESS_DETACH now protected with
	SEH as DeleteWindowsExitProc is causing an exception of its own under
	some teardown conditions. AT&T assembly syntax has not been added for
	MinGW yet. [Tcl Patch 858493]

2003-12-20  Joe English	 <[email protected]>

	* library/bgerror.tcl: Truncate displayed error message if it's too
	long. [Bug 231251]

2003-12-16  Pat Thoyts	<[email protected]>

	* win/rc/wish.exe.manifest: It seems that Windows XP insists on a
	strict format for the version value. 8.5.a0 or 8.5.0 results in an
	unloadable executable -- must be 4 numbers.

	* win/tkWinSend.c: Removed some misleading comments [Bug 846134] and
	disabled the send package until [Bug 858822] is resolved.

2003-12-16  Anton Kovalenko <[email protected]>

	* win/tkWinWm.c (InstallColormaps): Check for TK_ALREADY_DEAD to avoid
	handling of dead windows.

2003-12-15  David Gravereaux <[email protected]>

	Some silent invalid handle issues discovered with NuMega's
	BoundsChecker [Patch 699022]

	* win/tkWinMenu.c (ReconfigureWindowsMenu): Only redraw the menubar
	when a menubar exists.

	* win/tkWinWm.c (UpdateGeometryInfo): wmPtr->wrapper might be NULL. No
	exception is thrown, but it isn't correct to ignore.

2003-12-15  Benjamin Riefenstahl  <[email protected]>

	* macosx/tkMacOSXKeyboard.c: General cleanup. Add support for [event
	generate]. [Bug 860454]

2003-12-15  Vince Darley <[email protected]>

	* generic/tkText.h:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextIndex.c: improved documentation in comments to explain
	how pixel heights are kept track of. Also ensured correct clean-up of
	elide-state calculation, even with very large numbers of tags. Also
	provided slightly better updating of cache for totally elided display
	lines.

2003-12-12  David Gravereaux <[email protected]>

	* win/tkWinEmbed.c (TkWinEmbeddedEventProc) : for loop dereferences
	containerPtr but can't get to the if (containerPtr == NULL) test due to
	the unhandled read memory exception for when it really is NULL.

	* win/tkWinX.c (TkWinXInit): Don't restrict InitCommonControlsEx. It's
	valid on all platforms given IE 3.0+ is installed. As tkWinX.c does set
	#define _WIN32_IE 0x0300, I guess we can accept IE3 as the lowest
	denominator and use the version 4.71 features of Comctl32.dll

	* win/rc/wish.exe.manifest: updated version string. This file isn't
	compiled.

2003-12-10  Vince Darley <[email protected]>

	* tests/textWind.test: fixed 2 tests so they run on Windows as well as
	unix, and so their results take account of -padx/-pady settings for the
	text widget.

2003-12-10  Donal K. Fellows  <[email protected]>

	* doc/CrtImgType.3: Fixed line-transposition error found by Eric
	Raymond. [Bug 857159]

2003-12-09  Jeff Hobbs	<[email protected]>

	* unix/configure:
	* unix/tcl.m4: updated OpenBSD build configuration based on [Patch
	775246] (cassoff)

2003-12-09  Vince Darley <[email protected]>

	* win/tkWinWm.c: fix to memory leak on certain error cases.

	* generic/tkTextTag.c: fix reading of freed tag memory, by removing all
	references to freed tags.

2003-12-08  Jeff Hobbs	<[email protected]>

	* doc/entry.n: clean up usage of 'edition' as a verb.

2003-12-05  Vince Darley <[email protected]>

	* tests/text.test:
	* generic/tkText.c: after debate on sf, allow decreasing tab-stops,
	hence removing any potential backwards incompatibility, even for buggy
	code. Added new test. [Bug 852949]

	* generic/tkText.h:
	* generic/tkTextDisp.c:
	* generic/tkTextTag.c: fix to performance problems in the text widget
	when inserting lines which wrap thousands of times [Bug 853003]. Note
	that the text widget must now perform additional calculations (pixel
	heights) compared to Tk <= 8.4, and so some actions will be slower, by
	necessity.

2003-12-05  Benjamin Riefenstahl  <[email protected]>

	* win/tkWinFont.c (Tk_MeasureChars): Fix indentation. Fix memory leak.
	Fix handling of TK_WHOLE_WORDS.

2003-12-04  Vince Darley <[email protected]>

	* generic/tkText.c: disallow negative or decreasing tab-stops, which
	fixes [Bug 852949], but is a

	*** POTENTIAL INCOMPATIBILITY ***

	with Tk 8.4.5 or earlier, but only for code which assumed (incorrectly)
	that tab stops are relative to each other instead of relative to the
	widget's left edge. Such code will now throw an error instead of doing
	the wrong thing.

	[[MAINTAINER NOTE: SEE TIP#256]]

	* generic/tkTextDisp.c: restore previous meaning of -[xy]scrollcommand
	[Bug 852954], and remove unused argument to 'MeasureChars'

	* generic/tkTextWind.c:
	* generic/tkTextImage.c: better border handling and fixed typos in
	comments.

	* tests/text.test: tests for negative and decreasing tab stops.

	* doc/text.n: documentation of '-tabs', to clarify Tk's longstanding
	interpretation of all distances as relative to the left edge of the
	widget.

	* library/demos/twind.tcl:
	* library/demos/widget: minor enhancements to text widget demo, showing
	embedded images, for example.

2003-12-04  Vince Darley <[email protected]>

	* win/tkWinFont.c: applied [Patch 852669] which fixes [Bug 478568] with
	certain bold or italic fonts on Windows.
	* tests/textDisp.test: added test for the font measurement problem.

2003-12-02  Jeff Hobbs	<[email protected]>

	* generic/tkMenu.c (MenuVarProc): prevent this from triggering while
	interp is being destroyed.

2003-11-25  Anton Kovalenko <[email protected]>

	* generic/tkPointer.c (Tk_UpdatePointer): corrected targetWinPtr check
	(line 369) so any pointer event with winPtr==0 is really redirected to
	the grab or restrict window (if any).

2003-11-21  Vince Darley <[email protected]>

	* generic/tkTextDisp.c:
	* generic/tkText.h:
	* generic/tkText.c:
	* tests/textDisp.test: ensure interpolated tabs are at the same
	location as the equivalent real tabs, by making use of fractional
	rather than integer pixel calculations.

2003-11-21  Vince Darley <[email protected]>

	* generic/tkTextDisp.c: prevent wrapped line height calculations until
	the widget has actually been given a geometry.

	* tests/textWind.test:
	* tests/textDisp.test: fix to [Bug 843752], allowing tests to complete
	cross-platform. Thanks to dgp for extensive testing.

2003-11-21  Donal K. Fellows  <[email protected]>

	* doc/FindPhoto.3: Removed reference to long-gone header file.

2003-11-20  Vince Darley <[email protected]>

	* win/tkWinSend.c:
	* win/tkWinSendCom.c: ensure object is not shared before lappend (fix
	for crash in Windows test suite), and clean up of files to bring them
	closer to Tcl standards.

2003-11-20  Benjamin Riefenstahl  <[email protected]>

	* macosx/tkMacOSXKeyboard.c: Add PowerBook keycode 0x34 as <Return>.

2003-11-18  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXScrlbr.c: Reworking Vince's fix to [Bug 842952]. This
	version is clearer, and works helps keep the mouse better pinned to the
	scrollbar. I also removed the glitch where the scrollbar would jump get
	its middle over the mouse when you first moved it.

2003-11-17  Don Porter	<[email protected]>

	* tests/constraints.tcl:When running the test suite in a process where
	* tests/image.test:	Tk has been [load]ed, there's no guarantee that
	* tests/select.test:	child processes created by [exec [interpreter]]
	* tests/unixWm.test:	will have Tk in them. Made modifications to
	* tests/window.test:	force a [load] of Tk in those situations.

2003-11-17  Jeff Hobbs	<[email protected]>

	* generic/tkMenubutton.h: fixed compound menubutton handling like
	* generic/tkMenubutton.c: *button corrections of 2003-04-25.
	* mac/tkMacMenubutton.c (TkpDisplayMenuButton):
	* unix/tkUnixMenubu.c (TkpDisplayMenuButton):

2003-11-16  Don Porter	<[email protected]>

	* win/makefile.vc: Restored consistency of pkgIndex.tcl file with that
	generated by Makefile.

2003-11-15  Vince Darley <[email protected]>

	* macosx/tkMacOSXScrlbr.c: [Bug 842952] correct scrollbar tracking with
	mouse. Also increased scrollbar resolution for better scrolling in very
	large text widgets.

	* generic/tkTextDisp.c: cleanup and clarify some comments
	* doc/text.n: cleanup some of the markup.

2003-11-15  David Gravereaux <[email protected]>

	* win/makefile.vc: Fixes pkgIndex.tcl generation so a symbols build is
	loaded when Tcl is symbols.

2003-11-15  Vince Darley <[email protected]>

	* generic/tkTextDisp.c:
	* tests/textDisp.test: fixes to one more old Tk [Bug 422411] this time
	concerning inconsistent tab interpretation. Also fixed an unreported
	new problem if a single logical line wraps to fill more than the
	entire display.

	* macosx/tkMacOSXScrlbr.c: fix to [Bug 840978] where the size of the
	proportional scrollbar was calculated wrongly.

2003-11-14  Joe English	 <[email protected]>

	* doc/text.n: Fix markup errors.

2003-11-15  Vince Darley <[email protected]>

	* generic/tkText.h:
	* generic/tkText.c:
	* generic/tkTextDisp.c:
	* generic/tkTextWind.c:
	* generic/tkTextTag.c:
	* tests/textDisp.test: fixes to another pair of old Tk bugs [Bug
	220816] (can't scroll horizontally to display all of last character),
	[Bug 842498] (xview confused on window creation), and more efficiency
	in tag creation. Added new tests.

2003-11-14  Donal K. Fellows  <[email protected]>

	* generic/tkTextDisp.c (TkTextRedrawTag): Get the correct number of
	lines in the region to be updated. This fix due to Vince Darley.
	(TkTextUpdateLineMetrics): Return the correct marker value when we know
	the update loop should terminate. [Bug 837300]

2003-11-13  Vince Darley <[email protected]>

	* tests/event.test:
	* library/text.tcl: fixed the text widget portion of [Bug 542199]

2003-11-13  Donal K. Fellows  <[email protected]>

	* generic/tkMenuDraw.c (TkPostSubmenu,AdjustMenuCoords): Rewrote to use
	Tcl_EvalObjv instead of Tcl_VarEval for greater robustness. A side
	benefit is that this should all be faster now too. [Bug 723856]

2003-11-12  Vince Darley <[email protected]>

	* generic/tkText.h:
	* generic/tkText.c:
	* generic/tkTextDisp.c:
	* generic/tkTextIndex.c:
	* generic/tkTextTag.c:
	* tests/textTag.test: fixes to two very old Tk bugs [Bug 583286]
	(focus handling with embedded windows), [Bug 220780] (tag bindings
	trigger on window borders), and made two more functions static in
	tkTextDisp.c.

	* library/text.tcl: fixed [Tcl Bug 699642] with double/triple-click
	insert positioning.

2003-11-11  Jeff Hobbs	<[email protected]>

	* unix/configure:
	* unix/configure.in: use xft-config instead of pkg-config to determine
	xft info.
	* unix/tcl.m4: improve AIX --enable-64bit handling remove
	-D__NO_STRING_INLINES -D__NO_MATH_INLINES from CFLAGS_OPTIMIZE on
	Linux. Make default opt -O2 (was -O).

	* generic/tkButton.c (ConfigureButton): abort option processing if the
	button was deleted. [Bug 824479]

	* generic/tkMenuDraw.c (TkPostSubmenu): add {} around menu name in case
	it has spaces when calling Tcl_VarEval. This is a hack until this is
	rewritten for proper Tcl_Obj handling. [Bug 723856]

	* library/tkfbox.tcl (::tk::dialog::file::Update): optimize the
	dir/files list separation by using the -tails, -directory and -type
	option of 'glob'. Also passes the glob the -filetypes filters instead
	of calling string match over each file. [Patch 833819]
	(::tk::dialog::file::ActivateEnt): allow typing filename into entry
	when tk_getOpenFile -multiple 1 is specified. [Bug 788069]

	* generic/tkListbox.c (ListboxDeleteSubCmd, ListboxListVarProc): free
	itemconfig data when removing it from table. [Bug 836483]

	* macosx/tkMacOSXClipboard.c (TkSuspendClipboard, TkSelGetSelection):
	add unicode clipboard support. [Patch 840107] (senn)

2003-11-10  Jeff Hobbs	<[email protected]>

	* win/configure:
	* win/tcl.m4: add necessary ole libs to VC LIBS_GUI line.

	* win/tkWinDraw.c (XFillRectangles): correctly handle the
	XGCValues.function parameter when filling rectangles. [Bug 820278]
	[Patch 820282]

	* win/configure:
	* win/configure.in: define TK_LIB_FLAG, TK_LIB_SPEC,
	TK_BUILD_LIB_SPEC, TK_STUB_LIB_SPEC, TK_STUB_LIB_PATH, and
	TK_BUILD_STUB_LIB_PATH for tkConfig.sh [Bug 826614]

	* unix/Makefile.in (SHLIB_LD_FLAGS): include in Makefile as it is used
	in MAKE_LIB sometimes (ie: AIX-64) [Bug 829686] (jimix)

2003-11-10  Vince Darley <[email protected]>

	* generic/tkTextDisp.c: correct yview handling of text widgets
	containing no vertical pixels at all.

2003-11-08  Pat Thoyts	<[email protected]>

	* win/tclWinSend.c: Fixed an error returning the registered name.

2003-11-08  Vince Darley <[email protected]>

	* tests/textDisp.test:
	* tests/text.test:
	* generic/tkText.h:
	* generic/tkTextIndex.c:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c: fix to another version of [Bug 833627] (crash
	in tkchat), adding more tests. I believe the handling of nested elide
	tags of all types is now correct!

2003-11-07  Vince Darley <[email protected]>

	* tests/textDisp.test:
	* generic/tkTextDisp.c: fix to another version of [Bug 833627] (crash
	in tkchat), adding two new tests.

	* generic/tkText.c
	* generic/tkTextIndex.c
	* generic/tkTextDisp.c
	* generic/tkTextWind.c
	* generic/tkTextImage.c
	* generic/tkTextTag.c
	* generic/tkTextMark.c
	* generic/tkTextBTree.c
	* generic/tkText.h
	* doc/text.n
	* tests/text.test
	* tests/textWind.test: better handling of 'elide' tags, especially
	during line layout, counting and forward/backward index movement. Added
	new tests to ensure correct behaviour with multiple tags of multiple
	priorities.

2003-11-05  Donal K. Fellows  <[email protected]>

	* library/demos/nl.msg: Dutch messages from Arjen Markus [Patch 836368]
	* library/demos/widget: Added mechanism to support some l10n of the
	actual hotkeys used.

2003-11-04  Vince Darley <[email protected]>

	* tests/textDisp.test:
	* tests/textWind.test: fix to rest of test suite problems reported in
	[Bug 833761]. This also has the nice effect that many more tests are
	now run on Windows.

2003-11-04  Donal K. Fellows  <[email protected]>

	* library/demos/widget (showCode,printCode): Added code to print the
	source code on Unix and Win, courtesy of Arjen Markus and the Wiki.
	[Patch 835644]

2003-11-03  Vince Darley <[email protected]>

	* generic/tkTextDisp.c
	* tests/textDisp.test: test and fix to a panic reported in [Bug
	833627], with tkchat, and an unused variable [Bug 835010]. Also fixes
	substantial parts of [Bug 833761]

2003-11-03  Donal K. Fellows  <[email protected]>

	* library/demos/widget, etc.: Made widget demos locate themselves
	independently of the main Tk library using the new global variable
	tk_demoDirectory. [Patch 832691, adapted]

	* generic/tkTextDisp.c (TextGetScrollInfoObj): Stop complaints about
	signed vs. unsigned for the length of strings.

2003-11-01  Donal K. Fellows  <[email protected]>

	* library/msgs/nl.msg: Updated messages from Arjen Markus and Pascal
	Scheffers. Thanks! [Patch 820519]

2003-10-31  Jeff Hobbs	<[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoBlendComplexAlpha): OS X uses 32bpp
	images internally always, so make use of the assumption.

2003-10-31  Vince Darley <[email protected]>

	TIP#155 IMPLEMENTATION

	* generic/tkText.c, generic/tkTextIndex.c, generic/tkTextDisp.c
	* generic/tkTextWind.c, generic/tkTextImage.c, generic/tkTextTag.c
	* generic/tkTextMark.c, generic/tkTextBTree.c, generic/tkText.h
	* doc/text.n, tests/text.test, tests/textDisp.test
	* tests/textImage.test, tests/textIndex.test, tests/textWind.test
	* library/text.tcl, generic/tkCanvas.c, unix/tkUnixDefault.h
	* win/tkWinDefault.h, mac/tkMacDefault.h, macosx/tkMacOSXDefault.h

	This adds the 'count' and 'replace' subcommands to the text widget, the
	'-blockcursor' option, and in particular provides correct, smooth
	pixel-based scrolling of the widget under all circumstances. See the
	text.n man page for the complete new documentation. This also fixes
	[Bugs 559450 778511 779174].

	* generic/tkTextDisp.c
	* tests/textDisp.test: tests and fix to the promptly reported [Bug
	833627]

2003-10-31  Vince Darley <[email protected]>

	* win/tkWinMenu.c: more correct placing of images in compound menu
	entries.

2003-10-30  Jeff Hobbs	<[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoBlendComplexAlpha): add alpha blending
	for images with partial transparency. Only operates for 15bpp+ display.
	[Bug 809157]

2003-10-29  Donal K. Fellows  <[email protected]>

	* unix/tkUnixRFont.c: Some cleaning up to get the file more in lines
	with the general style guidelines. [Bug 832091] Still many comments
	needed (from someone who knows the code!) for the style guide to be
	satisfied, so bug still open.

	* library/tkfbox.tcl (IconList_Create,IconList_Add): Added option
	munging to allow some control of foreground colours on Unix in the same
	way that you can influence the background. [Bug 795717]

2003-10-28  Jeff Hobbs	<[email protected]>

	* unix/tkUnixFont.c (GetFontAttributes): place extra check for NULL
	family against bad X servers.

	* win/tkWinImage.c (XGetImageZPixmap): add separate 16bpp XGetImage
	code to correctly handle 16bpp requests. This appears to never have
	worked correctly.

	* tests/focusTcl.test (setup1): expand frame size to allow for correct
	visibility of windows that use larger default fonts.

2003-10-28  Donal K. Fellows  <[email protected]>

	* library/tk.tcl (::tk::PlaceWindow): Added check for empty string
	first when determining placement strategy. [Bug 819284]

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

	* macosx/tkMacOSXDialog.c (NavServicesGetFile): Minor cleanups.
	(OpenFileFilterProc): Handle FSRef's as well as FSSpec's in the input
	file. Also convert the FSSpec filename to an C-string before passing to
	MatchOneFile. [Bug 517600]
	(MatchOneFile): Require the input filename to be a C-string, not a
	pascal string.

2003-10-22  Donal K. Fellows  <[email protected]>

	* library/dialog.tcl (tk_dialog): Constrain the dialog to be fairly
	sensibly sized and placed. [Bug 827535]

2003-10-15  Joe English	 <[email protected]>

	* unix/tkUnixWm.c, tests/unixWm.test: Delete WM_TRANSIENT_FOR property
	instead of setting it to None when making a window nontransient [Bug
	632816 "cannot remove transient"]

2003-10-14  Joe English	 <[email protected]>

	* unix/tkUnixPort.h(TkPutImage): changed macro argument names to match
	function argument names ('dest' and 'src' were swapped, which was
	confusing) [GPS]

2003-10-14  Pat Thoyts	<[email protected]>

	* win/makefile.vc:  Applied patches from tcl bug 801467 from
	* win/winMain.c:    Joe Mistachkin

2003-10-12  Jeff Hobbs	<[email protected]>

	* generic/tkInt.h:	move TkGetOptionSpec to stubs intDecls
	* generic/tkIntDecls.h:
	* generic/tkInt.decls:
	* generic/tkStubInit.c:
	* tkDecls.h:		updated with latest genstubs
	* tkIntPlatDecls.h:
	* tkIntXlibDecls.h:
	* tkPlatDecls.h:

	* tests/listbox.test (13.3): correct result size
	(4.7): correct test for possible window drift [Bug 701931] (dgp)

	* unix/mkLinks:
	* doc/GetHWND.3: add Tk_AttachHWND docs [Bug 220803]

2003-10-10  Jeff Hobbs	<[email protected]>

	* mac/tkMacButton.c (TkpDisplayButton):
	* macosx/tkMacOSXButton.c (TkpDisplayButton):
	* unix/tkUnixButton.c (TkpDisplayButton): correct imageYOffset for
	buttons with just images.

2003-10-10  Donal K. Fellows  <[email protected]>

	* generic/tkObj.c (TkRegisterObjTypes): Register the type of text
	indexes.

2003-10-09  Jeff Hobbs	<[email protected]>

	* win/tkWinButton.c (TkpDisplayButton): correct imageYOffset for
	buttons with just images.

2003-10-08  Pat Thoyts	<[email protected]>

	* win/tcl.m4:	      Add TIP #150 items to the TEA makefiles.
	* win/configure:
	* win/Makefile.in:

	* win/tkWinSend.c:    Clean up some warnings from gcc -Wall.
	* win/tkWinSendCom.c:

2003-10-06  Joe English	 <[email protected]>

	* library/text.tcl, doc/text.n: Text widget binding for Control-v is
	now Mac-only, since it conflicts with standard <<Paste>> binding on
	other platforms. [Bug 605277]

2003-10-06  Joe English	 <[email protected]>

	* generic/tkStyle.c: Fix double-free in style engine [Bug 798211]

2003-10-06  Jeff Hobbs	<[email protected]>

	* win/configure:
	* win/tcl.m4: removed incorrect checks for existence of optimization.
	TCL_CFG_OPTIMIZED is now defined whenever the user does not build with
	--enable-symbols.

2003-10-06  Don Porter	<[email protected]>

	* doc/ConfigWidg.3:	Removed reference to Tk_Offset from the NAME
	section to resolve mkLinks conflict with SetOptions.3 [Bug 404197]

	* unix/configure.in:	 Reconfigured to use $TCL_PREFIX as the default
	value of --prefix, and also added warning when a TK_PREFIX value
	different from TCL_PREFIX is selected, since [package require Tk] fails
	in that configuration. [Bugs 428627,765642]

	* unix/tcl.m4 (SC_PATH_TCLCONFIG):	Corrected search path so that
	alpha and beta releases of Tcl are not favored. [Bug 608698]

	* unix/configure.in:	Added check that version of Tcl header found by
	configure matches that of the Tk we wish to build. As long as the Tk
	sources insist on lockstep releases, Tk's configuration should verify
	that's what we have. [Bug 749088]

	* unix/configure:	autoconf (2.57)
	* unix/mkLinks:		make mklinks

2003-10-03  Pat Thoyts	<[email protected]>

	* library/scale.tcl: Clear bug with chording mouse buttons.

	* library/console.tcl: Avoid including the console in the list of
	interpreters exposed by [winfo interps].

2003-10-01  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Makefile: fixed redo prebinding bug when DESTDIR="". Added
	support for all applicable customizable makefile variables from
	tcl/macosx/Makefile.

	* macosx/README:
	* macosx/Wish.pbproj/project.pbxproj: ensure that the versioned wishX.X
	script works correctly when Tk.framework with multiple versions is
	present by referring to a copy of 'Wish Shell.app' located in
	Tk.framework/Versions/X.X/Resources.

2003-09-30  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXButton.c (TkpDisplayButton): Use the tk text drawing
	for checkbuttons & radiobuttons as well as for labels.
	* macosx/tkMacOSXEvent.c (XSync): New function, need to implement this
	so drawing will get flushed in "update idletasks".
	* tkMacOSXPort.h: convert #define of XSync to function def'n.

2003-09-30  Donal K. Fellows  <[email protected]>

	* library/demos/browse:		Added suitable [package require] lines
	* library/demos/hello:		to all the Tk demo scripts which are
	* library/demos/ixset:		not run as part of something larger.
	* library/demos/rmt:		[FRQ 815118]
	* library/demos/rolodex:
	* library/demos/square:
	* library/demos/tcolor:
	* library/demos/timer:
	* library/demos/widget:

2003-09-30  Pat Thoyts	<[email protected]>

	* tests/safe.test:    Accomodate TIP #150 in the results.
	* tests/textWind.test: Fix a dependancy on font size in 10.1

2003-09-30  Donal K. Fellows  <[email protected]>

	* generic/tkCanvas.c (TkGetStringsFromObjs):
	* generic/tkPanedWindow.c (PanedWindowWorldChanged): Private functions
	should be either static or prefixed with 'Tk' (thanks to George Staplin
	for spotting this.)

2003-09-27  Pat Thoyts	<[email protected]>

	TIP#150 IMPLEMENTATION

	* win/makefile.vc:    Implementation of TIP #150, "Provide 'send'
	* win/tkWinSend.c:    command for Windows"
	* win/tkWinSendCom.h:
	* win/tkWinSendCom.c:

2003-09-26  Benjamin Riefenstahl  <[email protected]>

	* macosx/tkMacOSXWm.c (TkWmStackorderToplevelWrapperMap): Add
	GetWindowFromPort() [Bug 812415]; make function static.

2003-09-25  Daniel Steffen  <[email protected]>

	* library/demos/widget: don't create iconwindow on aqua, but add about
	menu like on classic.
	* macosx/Makefile: pass MAKEOVERRIDES to pxbuild.
	* macosx/tkMacOSXButton.c: added -compound support for bevel buttons.

	* unix/configure:
	* unix/configure.in:
	* unix/tkConfig.sh.in: added TK_INCLUDE_SPEC to allow extensions to
	find installed Tk headers, parallel to TCL_INCLUDE_SPEC. [Bug 777203]

2003-09-18  Chengye Mao <[email protected]>

	* generic/tkConsole.c: Fixed memory leak [Bug 802435]

2003-09-18  Peter Spjuth  <[email protected]>

	TIP#147 IMPLEMENTATION

	* doc/grid.n:
	* tests/grid.test:
	* generic/tkGrid.c: Implementation of TIP#147, "Make Grid's Column/Row
	Configure Easier".

2003-09-17  Don Porter	<[email protected]>

	* generic/tkImage.c:	Stopped [image create] from generating an image
	* tests/image.test:	command name that would overwrite an existing
	command name. Thanks to Michael Schlenker. [Bug 808039].

2003-09-16  Peter Spjuth  <[email protected]>

	* tests/grid.test:
	* generic/tkGrid.c: Reworked a part of grid's geometry computations to
	handle some tricky cases better. [Bug 792387]

2003-09-05  Joe English	 <[email protected]>

	* doc/bind.n: Describe %P and %s substitution for Property events.
	[Bug 577906 "%P substitution not documented"]

2003-09-05  Don Porter	<[email protected]>

	* doc/wish.1:			Implementation of TIPs 137/151.
	* generic/tkMain.c (Tk_MainEx):	Added recognition of the -encoding
	* tests/main.test:		command line option by Tk_MainEx() and
	thus by wish and any other program built on Tk_MainEx(). [Patch 800139]
	This is a ***POTENTIAL INCOMPATIBILITY*** only for those C programs
	that embed Tcl and Tk, build on Tk_MainEx(), and make use of
	Tk_MainEx's former ability to pass a leading "-encoding" option to
	interactive shell operations.

2003-08-27  Donal K. Fellows  <[email protected]>

	* generic/tkListbox.c (ListboxSelect): Remove unused variable
	'increment'. [Bug 664783]

2003-08-25  David Gravereaux  <[email protected]>

	* win/makefile.vc: Don't do a string compare on the $(DBGX) variable,
	use the $(DEBUG) boolean directly. Also, don't try to regen the stubs
	table if $(TCLSH) doesn't exist.

2003-08-22  Donal K. Fellows  <[email protected]>

	* library/demos/msgbox.tcl: Brought into line with the newer
	look-and-feel for the demos.
	* library/demos/widget (addSeeDismiss): Added support for an extra
	button defined by the caller.

2003-08-21  Pat Thoyts	<[email protected]>

	* win/tkWin3d.c: Applied Tk patch 791273 from Jeremy Collins which
	improves the 3d lines for sunken widgets under windows.

2003-08-20  Jeff Hobbs	<[email protected]>

	* library/demos/widget:	     Redo code view dialog, use named fonts,
	* library/demos/arrow.tcl:   add basic see/dismiss routine with images
	* library/demos/bind.tcl:    for better look & feel
	* library/demos/bitmap.tcl:
	* library/demos/button.tcl:
	* library/demos/check.tcl:
	* library/demos/clrpick.tcl:
	* library/demos/colors.tcl:
	* library/demos/cscroll.tcl:
	* library/demos/ctext.tcl:
	* library/demos/entry1.tcl:
	* library/demos/entry2.tcl:
	* library/demos/entry3.tcl:
	* library/demos/filebox.tcl:
	* library/demos/floor.tcl:
	* library/demos/form.tcl:
	* library/demos/hscale.tcl:
	* library/demos/icon.tcl:
	* library/demos/image1.tcl:
	* library/demos/image2.tcl:
	* library/demos/items.tcl:
	* library/demos/label.tcl:
	* library/demos/labelframe.tcl:
	* library/demos/menu.tcl:
	* library/demos/menubu.tcl:
	* library/demos/paned1.tcl:
	* library/demos/paned2.tcl:
	* library/demos/plot.tcl:
	* library/demos/puzzle.tcl:
	* library/demos/radio.tcl:
	* library/demos/ruler.tcl:
	* library/demos/sayings.tcl:
	* library/demos/search.tcl:
	* library/demos/spin.tcl:
	* library/demos/states.tcl:
	* library/demos/style.tcl:
	* library/demos/text.tcl:
	* library/demos/twind.tcl:
	* library/demos/unicodeout.tcl:
	* library/demos/vscale.tcl:

2003-08-20  Donal K. Fellows  <[email protected]>

	* generic/tkCanvPs.c (Tk_PostscriptFont): Use Tcl_Obj-based interfaces
	for working with user-supplied font maps.

2003-08-19  Joe English	 <[email protected]>

	* generic/tkPanedWindow.c (PanedWindowWorldChanged): Set window
	background from the -background resource. Fixes [Bug 791500
	"PanedWindow refresh glitches on X"]

2003-08-19  Joe English	 <[email protected]>

	* doc/bind.n: Added more information on event types and details [FRQ
	523593 "bind(n) manpage needs more detail"]

2003-08-18  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl to fix Tcl bug 781109.

2003-08-15  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (ImgPhotoCmd): Faster color data parsing code
	for the [$photo put] subcommand. Now doesn't do everything through the
	pre-8.0 list handling routines!

2003-08-14  Donal K. Fellows  <[email protected]>

	* unix/tkUnixButton.c (TkpDisplayButton): Stopped accesses to NULL
	* unix/tkUnixMenu.c (TkpDrawMenuEntry):	  pointers that crashed tests.

	TIP #109 IMPLEMENTATION FROM Brian Griffin <[email protected]>
	* unix/tkUnixButton.c (TkpDrawCheckIndicator, TkpDisplayButton):
	* unix/tkUnixMenu.c (DrawMenuEntryIndicator, TkpDrawMenuEntry):
	Much improved display of checkbuttons and radiobuttons on UNIX/X.

2003-08-13  Pat Thoyts	<[email protected]>

	* library/scale.tcl: Fix for [Bug 787065] for Button-2 press.
	* tests/scale.test:  Added test for this bug.

2003-08-12  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXMenu.c: fixed C99'ism that breaks gcc 2.95.

2003-07-28  Pat Thoyts	<[email protected]>

	* win/tkWinDialog.c: Applied patch from [Bug 611615] which fixes a
	problem with double clicks in file dialogs falling through to the
	window underneath in win32.

	* library/panedwindow.tcl: Apply patch from [Bug 778893] to make the
	panedwindow -opaqueresize option work as per the docs.

	* library/tk.tcl: Apply fix for [Bug 778840] for window placement when
	using multiple desktops on windows.

2003-07-24  Pat Thoyts	<[email protected]>

	* win/tkWinCursor.c: Fix for [Bug 776646] for a native hand2 and fleur
	(move) cursor under win.
	* tests/cursor.test: Check that documented cursors are available.

2003-07-20  Daniel Steffen  <[email protected]>

	* macosx/buildTkConfig.tcl: fix to TK_BUILD_* ref generation broken by
	changes to tcl buildsystem.

2003-07-19  Pat Thoyts	<[email protected]>

	* win/tkWinCursor.c (TkGetCursorByName): Fix bug 420510 to provide
	consistency between unix and windows -cursor option.

	* library/scale.tcl: Fix for bug 706765 to correctly handle the
	-sliderrelief option while moving the thumb.

2003-07-18  Jeff Hobbs	<[email protected]>

	* unix/tkUnixFont.c (Tk_DrawChars): do not make XGetGeometry call that
	prevents overwidth lines as it requires a roundtrip call to the X
	server for every string drawn. Hard-code max width to 32768 until a
	better solution to get max width is made.

	* library/panedwindow.tcl: use widget-specific Priv slots for pwAfterId
	and panecursor items to correctly handle cursor changes with adjacant
	panedwindows.

	* generic/tkEvent.c (Tk_HandleEvent): correct XCreateIC call for
	TK_XIM_SPOT usage. [Bug 742660] (takahashi)

	* win/tkWinDialog.c: doubled the TK_MULTI_MAX_PATH value to ~10K. This
	is a short-term solution until the -multiple option is extended. [Bug
	641261]

2003-07-18  Vince Darley <[email protected]>

	* generic/tkWindow.c:
	* macosx/tkMacOSXDialog.c: added native tk_messageBox command,
	(Tk_MessageBoxObjCmd) for MacOS X platform.

	* macosx/tkMacOSXMenu.c: corrected encoding conversion for torn-off
	menu entries (but many other display problems still exist with these)

	* macosx/tkMacOSXMouseEvent.c: improved handling of events in the
	presence of grabs, particularly activation events.

2003-07-18  Donal K. Fellows  <[email protected]>

	* tests/panedwindow.test (panedwindow-30.2):
	* generic/tkPanedWindow.c (Tk_PanedWindowObjCmd): Ensure that we can
	share GCs between a panedwindow and its sash proxy, even if the
	panedwindow is in a toplevel with a different visual. [Bug 702230]

2003-07-17  Daniel Steffen  <[email protected]>

	* macosx/Makefile: Changes for new tcl buildsystem.

	* macosx/Wish.pbproj/jingham.pbxuser:
	* macosx/Wish.pbproj/project.pbxproj:
	Changes for new tcl buildsystem. Changed build to include tk specific
	html help in Tk.framework instead of Tcl.framework. Set default SYMROOT
	in target options to simplify setting up PB (manually setting common
	build folder for tcl & tk no longer needed).

	* macosx/README: Updated info for changes to buildsystem, html help
	location and PB setup.

2003-07-17  Donal K. Fellows  <[email protected]>

	* doc/photo.n: [$photo put] has been able to take rectangles of pixel
	colours, specified as lists of lists, for years. Now this is a
	documented feature. [Bug 728952]

	* doc/panedwindow.n: Removed warning invalidated by fix from Bug
	738143. [Bug 747814]

	* generic/tkImgPhoto.c (ImgPhotoCmd): Rewrote subcommand processing to
	never jump to the end of the switch. I find that confusing as I can't
	see whether there's processing still to be done from a quick glance at
	the code, unlike with a direct return. [Bug 771988]
	(ImgPhotoCmd, ImgPhotoSetSize, ImgPhotoInstanceSetSize): Try harder to
	avoid zero-length mallocs()... [Bug 404421]

2003-07-16  Don Porter	<[email protected]>

	* generic/tkPack.c (ConfigureSlaves): silence compiler warning
	[Bug 771982]

2003-07-16  Jeff Hobbs	<[email protected]>

	* win/tkWinImage.c (XGetImage): correct init of biSizeImage in bitmap
	header. [Bug 703697] (cap)

2003-07-17  Peter Spjuth  <[email protected]>

	* tests/frame.test:
	* generic/tkFrame.c (CreateFrame): Make sure all options can be set to
	their default value. [Bug 697652]

2003-07-16  Jeff Hobbs	<[email protected]>

	* generic/tkPanedWindow.c (ArrangePanes): Ensure that the last pane
	* tests/panedwindow.test: shrinks instead of being clipped when resized
	below the reqsize. [Bug 748277] (spjuth)

	* generic/tkWindow.c (Initialize): do not free uninit'ed dstring.
	[Bug 755906] (mistachkin)

2003-07-09  Donal K. Fellows  <[email protected]>

	* tests/send.test: Strengthened constraints to stop accidental smashing
	of Xserver access; some systems (*ahem* mine *ahem*) require
	xhost-style security for all use... :^/

2003-07-07  Jeff Hobbs	<[email protected]>

	* generic/tkTextDisp.c (DisplayText): correct use of textPtr data with
	respect to Tcl_Release time. [Bug 767009]

2003-07-07  Donal K. Fellows  <[email protected]>

	* generic/tkImage.c (TkDeleteAllImages,etc.): Stopped the deleting of
	hash entries from a table that has just been deleted by this function
	when some images are Tcl_Preserve()d... [Bug 749353]

2003-07-03  Jim Ingham <[email protected]>

	* macosx/tkMacOSXColor.c (GetControlPartColor): Use the ThemeBrushes to
	get the control text color for buttons.

2003-07-02  Mo DeJong  <[email protected]>

	* unix/tkUnixEvent.c (TkpCloseDisplay): Don't test for XCloseIM bug
	when the XFree86 version is newer than 4.0 since the layout of the XIM
	structure has changed. The check is not needed for newer XFree86
	releases since the bug we are checking for was fixed in the 4.2.99.2
	release. [Bug 755530]

2003-06-26  Vince Darley <[email protected]>

	* library/menu.tcl: workaround problem on some Windows systems by
	trying to avoid posting a menu offscreen.

2003-06-09  Joe English	 <[email protected]>

	* unix/tkUnixRFont.c: fix for [Bug 751553] "Xft: [font configure] does
	not update in-use fonts". Fixed TkpGetSubFonts() to return information
	about all subfonts, not just the first one.

2003-06-01  Joe English	 <[email protected]>

	* unix/configure.in: BUGFIX, --enable-xft test was broken.
	* unix/configure: regen

2003-05-31  Joe English	 <[email protected]>

	* unix/tkUnixRFont.c (InitFont): Fill in TkFontAttributes from pattern
	returned from GetFont (actual font) instead of the query pattern
	(requested font).

2003-05-31  Joe English	 <[email protected]>

	* unix/tkUnixRFont.c: New file
	* unix/tkUnixDefault.h: Use different default fonts if HAVE_XFT
	* unix/Makefile.in:
	* unix/configure.in: Add --enable-xft flag
	* unix/configure: regen
	Experimental support for antialiased text under X11 [Patch 535541]

2003-05-30  Vince Darley <[email protected]>

	* generic/tkMenu.c
	* generic/tkMenu.h
	* generic/tkMenuDraw.c:
	* tests/menu.test: fixed complex bug in menu clone cleanup [Bug 465324]
	and removed 'knownBug' from a test.

2003-05-29  Joe English	 <[email protected]>

	* doc/text.n: Fixed markup errors.

2003-05-28  Miguel Bañón <[email protected]>

	* library/msgs/cs.msg: Updated messages from [email protected]

2003-05-27  Vince Darley <[email protected]>

	* generic/tkText.c
	* generic/tkTextTag.c
	* generic/tkTextDisp.c
	* generic/tkText.h: refactoring of text widget cleanup code to ensure
	all resources are freed. [Bug 741179]

	* library/tearoff.tcl: ensure torn-off menus do not appear underneath
	the MacOS/MacOS X main menu bar.

2003-05-23  Mo DeJong  <[email protected]>

	* unix/mkLinks: Set the var S to "" at the top of the file to avoid
	error when user has set S to something. [Bug 739833]

2003-05-21  Donal K. Fellows  <[email protected]>

	* generic/tkPanedWindow.c (PanedWindowReqProc): Thanks very much to
	Eric Boudaillier for making panes resize correctly! [Bug 738143]

	* generic/tkText.c (TextSearchCmd): Forwards and backwards aren't the
	same. [Bug 740558] Also edited SearchCore to get it closer to the
	Engineering Manual style guidelines.

2003-05-19  Donal K. Fellows  <[email protected]>

	* tests/textImage.test:		Fixed faults in option parsing and made
	* tests/text.test:		tests conformant. [Bug 739965]
	* generic/tkText.c (TextSearchCmd):

	* library/demos/en.msg: Base catalog for the widget demo.
	* library/demos/widget: Added message-catalog support.
	* library/console.tcl: Reworked to use tk::AmpMenuArgs and be more "in
	style".
	* library/tk.tcl (tk::AmpMenuArgs): New procedure for doing
	tk::AmpWidget-like processing for menus.

	* generic/tkTextMark.c:		Removed complaints about signed vs.
	* generic/tkTextImage.c:	unsigned in arguments to strncmp() by
	* generic/tkText.c:		using Tcl_GetIndexFromObj() more.

2003-05-19  Vince Darley <[email protected]>

	TIP#113 IMPLEMENTATION

	* doc/text.n
	* generic/tkCanvas.c
	* generic/tkInt.h
	* generic/tkTest.c
	* generic/tkText.c
	* generic/tkText.h
	* generic/tkTextBTree.c
	* generic/tkTextDisp.c
	* generic/tkTextImage.c
	* generic/tkTextIndex.c
	* generic/tkTextMark.c
	* generic/tkTextTag.c
	* generic/tkTextWind.c
	* generic/tkUndo.c
	* generic/tkUndo.h
	* generic/tkWindow.c
	* library/text.tcl
	* tests/text.test
	* tests/textIndex.test
	* tests/textMark.test
	* tests/textTag.test
	* tests/textWind.test: This adds multi-line searching and '-all'
	searching to the text widget. In addition the changes contain a
	complete 'objectification' of the text widget. Includes documentation
	and new tests.

2003-05-19  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj: changed tkConfig.sh location in
	versioned framework subdirectories to be identical to location in
	framework toplevel; fixed stub library symbolic links to be tk version
	specific.

2003-05-15  Jeff Hobbs	<[email protected]>

	* unix/tkUnixFont.c: use gb2312-raw as the alias for gb2312* charset
	fonts. gb2312.enc was made to be euc-cn for Tcl because that is what
	is most often meant, but X really wants the original (-raw) gb2312
	encoding. [Bug 557030]

2003-05-14  Jeff Hobbs	<[email protected]>

	* library/msgs/fr.msg: updated msg catalog. [Bug 737790] (zolli)

2003-05-13  Vince Darley <[email protected]>

	* win/makefile.vc: fix to installation of winhelp into path containing
	a space (Bug 693512)

2003-05-13  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXInit.c (TkpInit): use new versioned bundle resource
	API to get tk runtime library for TK_VERSION. [Bug 736774]

2003-05-10  Jeff Hobbs	<[email protected]>

	* generic/tkCanvPoly.c (PolygonToPostscript):
	* tests/canvPs.test: correct crash when generating postscript for a
	single-line polygon (point) with no color. [Bug 734498] (wilm)

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

	* macosx/tkMacOSXClipboard.c (TkSelGetSelection): Convert '\r' to '\n'
	on the way into Tcl.

2003-05-08  Donal K. Fellows  <[email protected]>

	* tests/image.test (image-15.1): Test to ensure that widgets pick up
	image information even if the image is deleted and recreated.

	* generic/tkImage.c (Tk_ImageObjCmd): Use the ImageMaster's deleted
	flag to stop deleted images from showing up in the various [image *]
	operations. Can't delete directly from the table because that makes us
	lose the information about what widgets want to use the image. [Bug
	634864]

2003-04-30  Jeff Hobbs	<[email protected]>

	* macosx/tkMacOSXButton.c (TkpDisplayButton): correct typo for
	stippleGC [Bug 730124].

2003-04-25  Jeff Hobbs	<[email protected]>

	* generic/tkButton.h:			      Rewrote the handling of
	* generic/tkButton.c (TkButtonWorldChanged):  compound *buttons to
	* mac/tkMacButton.c (TkpDisplayButton):	      correctly display mixture
	* macosx/tkMacOSXButton.c (TkpDisplayButton): of disabledfg,
	* unix/tkUnixButton.c (TkpDisplayButton):     selectcolor, indicator,
	* win/tkWinButton.c (TkpDisplayButton):	      etc. *buttons will now
	only stipple the image, unless no disabledfg is given, in which case it
	will stipple the whole button.

	* library/bgerror.tcl: make bgerror dialog topmost on Windows to
	prevent it being covered by other windows.

	* unix/tkUnixButton.c (TkpDisplayButton): Use the normalTextGc when
	* win/tkWinButton.c (TkpDisplayButton):	  displaying disabled text that
	have images, as they get a gray50 stipple as well and the disabledGc is
	not set up correctly for font drawing. [Bug 477740]

2003-04-18  Jeff Hobbs	<[email protected]>

	* win/configure: regen
	* win/configure.in (SHELL): force it to /bin/sh as autoconf 2.5x uses
	/bin/bash, which can fail to find exes in the path (ie: lib).

	* generic/tkCanvBmap.c: s/CreateBitmap/TkcCreateBitmap as Windows has a
	CreateBitmap function already.

	* generic/tkCursor.c: s/GetCursor/TkcGetCursor as Windows has a
	GetCursor func already, which causes compiler warnings.

2003-04-14  Mo DeJong  <[email protected]>

	* win/tkWinMenu.c (TkpInitializeMenuBindings): Rename the private menu
	helper cmd from tk::tkWinMenuKey to tk::WinMenuKey. [Bug 721514]

2003-04-14  Mo DeJong  <[email protected]>

	* generic/tkBind.c (TkpGetBindingXEvent): Add helper method that can be
	used to query the XEvent* for the currently executing binding.
	* generic/tkInt.h: Declare TkpGetBindingXEvent.
	* win/tkWinMenu.c (MenuKeyBindProc, TkWinMenuKeyObjCmd)
	(TkpInitializeMenuBindings): Rename MenuKeyBindProc to
	TkWinMenuKeyObjCmd and convert it into a Tcl command named
	tk::tkWinMenuKey. Bind keyboard accelerator actions to this Tcl command
	instead of using a native C binding. This makes it possible to extend
	the existing binding with Tcl code and makes the Windows version work
	just like the unix version.

2003-04-04  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Subst TCL_LIBS instead of DL_LIBS and MATH_LIBS.
	* unix/configure: Regen.
	* unix/configure.in: Remove SC_ENABLE_THREADS invocation. Thread
	support in an extension should be automatic when Tcl is compiled with
	thread support. Add AC_DEFINE calls to set TCL_THREADS, _REENTRANT, and
	_THREAD_SAFE since this was done in SC_ENABLE_THREADS. Remove socket
	and math lib checks since these are already done in the Tcl configure
	script.
	* unix/tcl.m4: Update from Tcl to get TCL_LIBS fix. This fixes [Bug
	597847] which was caused by improper linking.
	* unix/tkConfig.sh.in: Subst TCL_LIBS instead of MATH_LIBS and DL_LIBS.
	[Bug 597847]

2003-04-02  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Set stub lib flag based on new LIBFLAGSUFFIX
	variable.
	* win/tcl.m4: Update from Tcl to get new LIBFLAGSUFFIX variable.

2003-04-02  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Don't set TCL_DLL_FILE, TCL_LIB_FILE,
	TCL_STUB_LIB_FILE, TCL_STUB_LIB_FLAG, and TCL_BUILD_STUB_LIB_SPEC.
	These variables are already set in tclConfig.sh. Don't subst vars that
	are either not used, or already covered by a subst in
	SC_LOAD_TCLCONFIG. [Bug 691908]

2003-04-01  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2003-04-01  Don Porter	<[email protected]>

	* tests/all.tcl:		Made better use of a common -loadfile
	* tests/constraints.tcl:	to hold definitions common to all test
	* tests/*.test:			files.

2003-03-27  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2003-03-26  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl to get BeOS changes.

2003-03-22  Kevin Kenny	 <[email protected]>

	* win/makefile.vc:
	* win/rules.vc: Corrected several problems that prevented OPTS=symbols
	from building properly. [Patch 707792] Thanks to Joe Mistachkin for the
	fixes.

2003-03-20  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXApplication.r (removed):
	* macosx/tkMacOSXLibrary.r (removed):
	* macosx/tkMacOSXResource.r (removed):
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/tkAboutDlg.r: updated copyrights, cleaned up about box,
	removed obsolete unused resource files.

	* macosx/buildTkConfig.tcl: TK_DEFS space fix.

2003-03-18  Mo DeJong  <[email protected]>

	* win/tkConfig.sh.in: Add TK_DLL_FILE entry to mirror the TCL_DLL_FILE
	entry in tclConfig.sh. [Patch 694271]

2003-03-18  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/configure.in: Don't run the AC_CYGWIN macro since it uses
	AC_CANONICAL_HOST under autoconf 2.5X. Just check to see if __CYGWIN__
	is defined by the compiler and set the ac_cv_cygwin variable based on
	that. [Tcl Bug 705912]

2003-03-18  Don Porter	<[email protected]>

	* tests/unixWm.test (unixWm-41.2): Corrected typo in 2003-03-13 commit.
	Thanks Larry Virden. [Bug 705567]

2003-03-18  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Makefile:
	* macosx/README: added support for giving 'make' the location of
	Tcl.framework and tclsh to build and link against.

	* macosx/tkMacOSXXStubs.c: fixed crash in [winfo server].

2003-03-13  Don Porter	<[email protected]>

	* tests/unixWm.test:  Constrained all tests older than revision 1.21 to
	run only on Unix. Alternative approach did not match maintainer habits.
	* tests/spinbox.test (spinbox-17.4): Avoid long failure message.

2003-03-13  Mo DeJong  <[email protected]>

	Require autoconf 2.57 or newer, see TIP 34 for a detailed explanation
	of why this is good. This will no doubt break the build on some
	platforms, let the flaming begin.

	* unix/configure: Regen with autoconf 2.57.
	* unix/configure.in: Require autoconf 2.57.
	* unix/tcl.m4: Update from Tcl.
	* win/configure: Regen with autoconf 2.57.
	* win/configure.in: Require autoconf 2.57.
	* win/tcl.m4: Update from Tcl.

2003-03-12  Donal K. Fellows  <[email protected]>

	* library/msgbox.tcl (tk::MessageBox): Stopped message box buttons from
	getting very wide, and added some compensatory space so that the
	smaller buttons still look nice (well, to me). [Bug 701812]

2003-03-11  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXMenu.c (EventuallyInvokeMenu): New function, used to
	invoke menu commands at idle time.
	(TkMacOSXDispatchMenuEvent): Don't immediately dispatch menu commands,
	wait till the idle loop to do so. This is more like what is done on
	Windows, and avoids the crash from destroying a menu in it's command.

	* macosx/tkMacOSXHLEvents.c (ReallyKillMe): Don't force the shell to
	exit. According to the OS X HI guidelines, it should be possible to
	cancel an attempt to quit, and if we force the kill, here, it would not
	be possible to implement this.

2003-03-11  Mo DeJong  <[email protected]>

	* tests/unixWm.test: Add the testwrapper constraint to tests that
	depend on the testwrapper command. These tests should not be run under
	Windows for example.

2003-03-11  Mo DeJong  <[email protected]>

	* doc/wm.n (minimize, maximize): Remove claim that the resizable
	command keeps scripts from changing the size of windows since it is not
	true. The resizable command only applies to user sizing via user
	interaction.
	* tests/unixWm.test: Replace broken tests with the nonPortable
	constraint with new tests for maxsize and minsize options. These tests
	verify that setting the minsize and maxsize will resize the window if
	needed, and that the wm hints will be updated with the new sizes.
	* tests/wm.test: Add an exhaustive set of tests for the wm maxsize and
	wm minsize commands. These tests verify that setting the minsize and
	maxsize will resize the window if needed. These tests have only been
	run under Win98 and Window Maker under Linux, so further tweaking may
	be needed for other systems.
	* unix/tkUnixWm.c (UpdateGeometryInfo, UpdateSizeHints): Fixup
	comments and initialization for the minWidth, minHeight, maxWidth,
	maxHeight, width, and height members of the WmInfo struct. Check to
	ensure that a new toplevel window size is not larger than the maxsize
	or smaller than the minsize when updating the geometry at idle time.
	Pass new width and height values to the UpdateSizeHints method so that
	it can properly set the window min and max sizes for a window that
	cannot be resized by the user. This fixes a bug where the window
	resizes back to the original size when the user clicks on the window
	border.
	* win/tkWinWm.c (UpdateGeometryInfo): Fixup comments and
	initialization for the minWidth, minHeight, maxWidth, maxHeight, width,
	and height members of the WmInfo struct. Check to ensure that a new
	toplevel window size is not larger than the maxsize or smaller than the
	minsize when updating the geometry at idle time. [Patch 568861]

2003-03-11  Mo DeJong  <[email protected]>

	* generic/tkGrid.c (GridStructureProc, ConfigureSlaves): Check for a
	NULL masterPtr and slavePtr in the GridStructureProc code to ensure
	that a Gridder created before some error condition is ignored when it
	comes to geometry calculations. This approach closely matches the pack
	implementation. Keep track of a -in argument to a grid command in order
	to detect the case of an already gridded widget that wants to change
	some options. The previous implementation could make repeated and
	unnecessary calls to Tk_ManageGeometry. Replace use of "parent" with
	"master" in comments throughout the file.
	* generic/tkPack.c (PackStructureProc): Check for a NULL masterPtr
	before other checks so that a slave created under certain error
	conditions is cleaned up properly. Replace use of "parent" with
	"master" in comments throughout the file.
	* generic/tkPlace.c (CreateSlave, ConfigureSlave, SlaveStructureProc):
	Don't call Tk_ManageGeometry in CreateSlave since this was causing
	incorrect results in some error cases. Rework the ConfigureSlave method
	so that slave setup is done in one place. The call to Tk_ManageGeometry
	was added to the one place where a slave is setup. When a slave is
	configured but the master is not changed, simply goto the
	scheduleLayout label. Check for a NULL master in SlaveStructureProc for
	the sake of readability.
	* tests/grid.test:
	* tests/pack.test:
	* tests/place.test: Add test to check that a winfo manager call does
	not return incorrect results after an error condition is hit. [Patch
	693063]

2003-03-11  Kevin Kenny	 <[email protected]>

	* win/makefile.vc: Backported the code that makes the makefile build
	pkgIndex.tcl as part of the install step.

2003-03-07  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXMenus.c (TkMacOSXInitMenus): No longer need to call
	TkMacOSXSetHelpMenuItemCount.
	* macosx/tkMacOSXMenu.c (TkMacOSXHelpMenuItemCount): Stub out since it
	is no longer need (but is in the stubs table...).
	(TkMacOSXDispatchMenuEvent): Get the number of system help menu items
	from HMGetHelpMenu.
	(ReconfigureMacintoshMenu): Ditto.
	(TkpDestroyMenu): Ditto.

2003-03-06  Donal K. Fellows  <[email protected]>

	TIP#116 IMPLEMENTATION

	* doc/FindPhoto.3: Documentation of the photo API changes due to
	TIP#116

	* generic/tkImgPhoto.c (Tk_PhotoExpand, Tk_PhotoPutBlock)
	(Tk_PhotoPutZoomedBlock, Tk_PhotoSetSize): Added interp argument to
	these functions and made them return a standard Tcl result, with error
	indicating memory allocation failure instead of panic()ing.
	[See TIP #116 at http://purl.org/tcl/tip/116.html for discussion.]
	Each of these functions has also acquired a backward-compatability
	variant as well, named with a _Panic suffix.
	* generic.tk.decls: New API in new slots, back-compat API in old ones.
	* generic/tk.h (USE_PANIC_ON_PHOTO_ALLOC_FAILURE): Allow users to
	define this symbol to get the old 8.4 photo image API, including
	panic() calls when things go wrong.

	* generic/tkImgPhoto.c (ImgPhotoCmd): Adjusted to use the new API
	* generic/tkImgGIF.c (FileReadGIF):   discussed above.
	* generic/tkImgPPM.c (FileReadPPM):

2003-03-05  David Gravereaux  <[email protected]>

	* win/rules.vc: updated default tcl version to 8.5.

2003-03-04  Don Porter <[email protected]>

	* README:				Bumped version number of Tk to
	* generic/tk.h:				8.5a0.
	* library/tk.tcl:
	* mac/README:
	* macosx/Wish.pbproj/project.pbxproj:
	* unix/README:
	* unix/configure.in:
	* unix/tk.spec:
	* win/README:
	* win/configure.in:
	* win/makefile.vc:
	* win/tcl.m4:

	* unix/configure:      autoconf
	* win/configure:

2003-03-03  Jeff Hobbs	<[email protected]>

	*** 8.4.2 TAGGED FOR RELEASE ***

2003-02-28  Donal K. Fellows  <[email protected]>

	* tests/bind.test (bind-16.44):
	* generic/tkBind.c (ExpandPercents): Only allow events to see those
	expansions that are actually valid for them, and force the substitution
	of the rest as "??". This stops some crashes on Windows and gets rid of
	bogus values everywhere. [Bug 612110]

2003-02-26  Jeff Hobbs	<[email protected]>

	* macosx/README: correct 8.4.3 refs to 8.4.2.

	* unix/README: replace version refs with version-agnostic wording.

2003-02-25  Jeff Hobbs	<[email protected]>

	* win/tkWinInt.h:
	* win/tkWinDraw.c:
	* win/tkWinFont.c (Tk_DrawChars): add support for simple XOR text
	drawing on Windows. [Patch 685388] (martin)

	* generic/tkMenu.c (TkMenuCleanup): make sure to reset static
	menusInitialized on finalize. [Bug 548729]

2003-02-25  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXHLEvents.c: fixed conversion of apple event parameters
	to posix style path names. [Bug 621672] (steffen, Benjamin Riefenstahl)

	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXWm.c:
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/tkMacOSXUtil.c (removed):
	* macosx/tkMacOSXUtil.h (removed): removed all references to
	tkMacOSXUtil.{c,h}, made obsolete by the patch above. [Bug 621672]

2003-02-24  Jeff Hobbs	<[email protected]>

	* unix/tkUnixFont.c (CreateClosestFont, CanUseFallback): use the first
	best font match in user font path. [Bug 647497] (dal zotto)

	* generic/tkListbox.c (ListboxSelectionSubCmd):
	* tests/listbox.test: Allow 'selection includes' to respond when
	disabled (but only 'includes'). [Bug 632514]

	* unix/tkUnixButton.c (TkpDisplayButton): Correct visual display of
	disabled check/radiobutton to be more distinctive on unix.
	* tests/unixButton.test: [Bug 669595] (hintermayer)

	* doc/panedwindow.n: clarified the need to use 'update idle' when
	adding unmapped windows. Needs further examination. [Bug 605105]

	* generic/tkEntry.c (SpinboxWidgetObjCmd, EntryWidgetObjCmd):
	* tests/entry.test:   return 1 if selection is present even if
	* tests/spinbox.test: entry/spinbox is disabled, as selection get will
	still return the selection (although selection still ignore modify
	requests when entry/spinbox is disabled). [Bug 637828]

2003-02-24  Benjamin Riefenstahl  <[email protected]>

	* tkMacOSXDialog.c (NavServicesGetFile): Fix bug with
	kNavCtlSetSelection - control data should be a pointer not a handle.

2003-02-21  Donal K. Fellows  <[email protected]>

	* library/clrpick.tcl (color::BuildDialog):
	* library/msgbox.tcl (MessageBox): Yet more places that did complex
	and fragile width calculations instead of using grid, though with these
	it is the -uniform option that saves the day.

	* library/tkfbox.tcl (file::Create): This procedure was really very
	crufty in how it went about creating the GUI. It is far easier and more
	robust to use the grid geometry manager than it is to tune the results
	of pack with tweaks to -width. [Bug 673722]

	* library/comdlg.tcl (FDGetFileTypes): Set an upper limit on how long a
	file type item description string can get due to appending of types.
	[Bug 617392]

	* tests/panedwindow.test (panedwindow-30.1):
	* generic/tkPanedWindow.c (DisplayPanedWindow, DisplayProxyWindow):
	Use the window's depth, not the screen's default depth. [Bug 671122]

2003-02-20  Daniel Steffen  <[email protected]>

	* library/console.tcl: (aqua & macintosh) added missing <Cmd-q> binding
	for corresponding Quit menu item shortcut.

	* macosx/README: updated instructions for embedded build, added various
	improvements by Russell Owen.

	* unix/tcl.m4: update from Tcl.
	* unix/configure: regen.

2003-02-20  Jeff Hobbs	<[email protected]>

	* win/tkWinScrlbr.c (UpdateScrollbar): use SIF_DISABLENOSCROLL to
	"disable" scrollbar when on Windows when there is nothing to scroll.
	This is Windows style, and fixes [Bug 624116].

	* tests/panedwindow.test:
	* generic/tkPanedWindow.c (ValidSashIndex): corrected to note that 2
	panes must exist before any one sash does. [tcllib Bug 689258]

2003-02-20  Peter Spjuth  <[email protected]>

	* tests/panedwindow.test:
	* generic/tkPanedWindow.c: Fixed calculation of the last slave's size
	when increasing the size of the panedwindow. [Bug 689099]

2003-02-20  Donal K. Fellows  <[email protected]>

	* generic/tkImgGIF.c (GetDataBlock): Removed pointless static variable
	ZeroDataBlock [Bug 664788]

	* unix/tkUnixFont.c (CanUseFallback): Added argument, passed through
	from callers to FindSubFontForChar(), so that pointers into the old
	subfont table to be updated when that table is reallocated, avoiding a
	(sometimes fatal) FMR. [Bugs 618872, 689357]

2003-02-19  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXKeyEvent.c: fix for uninitialized var warning.

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

	* macosx/tkMacOSXMouseEvents.c (GeneratePollingEvents): In the case
	where there was a capture window, we were sending the events to the
	capture window. But the capture window (return value or
	TkMacOSXGetCapture) is always a toplevel. So this is wrong in the case
	that the Event's toplevel IS the capture window - in which case the
	event should go to the subwindow most closely containing the event.

2003-02-19  Benjamin Riefenstahl <[email protected]>
	and Jim Ingham <[email protected]>

	This patch changes the default Tk behavior so that events are by
	default routed to the standard event handlers after Tk has looked at
	them.

	* macosx/tkMacOSXEvent.h: Rename "handledByTk" into "stopProcessing".

	* macosx/tkMacOSXEvent.c: Update erroneous comments and remove unused
	includes.
	(TkMacOSXProcessAppleEvent): Don't declare events handled that we did
	not even look at.
	(TkMacOSXProcessEvent): Add a comment on policy for "stopProcessing".
	(TkMacOSXProcessEvent): Remove "handling" of events that are not our
	business.
	(TkMacOSXProcessEvent): Rename "handledByTk" into "stopProcessing".
	(ReceiveAndProcessEvent): Ditto.
	(ReceiveAndProcessEvent): Tune error production of message.

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): Rename
	"handledByTk" into "stopProcessing".

	* macosx/tkMacOSXWindowEvent.c: Ditto.

	* macosx/tkMacOSXMouseEvent.c: Remove setting of "handledByTk".
	(TkMacOSXProcessMouseEvent): Handle clicks in the "traffic lights" in
	the window title when the window (or app) is in the background.

	This patch changes the key event handling to use the MacOS translation
	mechanisms. It also improves dead key handling.

	* macosx/tkMacOSXKeyEvent.c (InitKeyData): Add.
	(InitKeyEvent): Add.
	(DecodeViaUnicodeResource): Rename KeycodeToUnicodeViaUnicodeResource.
	(DecodeViaKCHRResource): Rename KeycodeToUnicodeViaKCHRResource.
	(GetKeyboardLayout): Use a boolean flag instead of a special layout id.
	(KeycodeToUnicodeViaUnicodeResource): Change interface and
	implementation to return a Unicode string instead of directly filling
	an XEvent.
	(KeycodeToUnicodeViaKCHRResource): Ditto.
	(KeycodeToUnicodeViaUnicodeResource): Add handling for callers that
	don't want deadkey processing (i.e. XKeycodeToKeysym).
	(KeycodeToUnicodeViaKCHRResource): Ditto.
	(KeycodeToUnicodeViaUnicodeResource): Clear deadKeyState if a character
	was produced.
	(KeycodeToUnicodeViaKCHRResource): Use CFString and current keyboard
	encoding instead of Tcl Tcl_ExternalToUtf() and fixed
	TkMacOSXCarbonEncoding.
	(TkMacOSXKeycodeToUnicode): Add.

	(TkMacOSXProcessKeyboardEvent): Add some heuristics to improve keyup
	events.
	(deadKeyState): Split into deadKeyStateUp and deadKeyStateDown.
	(GenerateKeyEvent): Change interface and implementation to accept a
	Unicode string instead of individual characters.
	(GenerateKeyEvent): Don't generate string representations for special
	characters.

	* macosx/tkMacOSXEvent.h (TkMacOSXKeycodeToUnicode): Add prototype.

	* macosx/tkMacOSXKeyboard.c (KCHRPtr): Remove.
	(XKeycodeToKeysym): Use TkMacOSXKeycodeToUnicode instead of
	KeyTranslate.
	(XKeycodeToKeysym): Support latin-1 keysyms.

	This patch reverts the hack to put icons in menus that Vince put in
	yesterday (but preserves the bug fix in that submission.)

	* macosx/tkMacOSXMenu.c (SetMenuTitle): revert treating "<bullet>
	number" as a request to put icon number <number> in the menu.

2003-02-18  Mo DeJong  <[email protected]>

	* doc/entry.n:
	* doc/text.n: Update double and triple click docs to match
	implementation changes made on 2002-02-14.

2003-02-19  Daniel Steffen  <[email protected]>

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Makefile: reworked embedded build to no longer require
	relinking but to use install_name_tool instead to change the
	install_names for embedded frameworks. [Bug 644510]

2003-02-19  Donal K. Fellows  <[email protected]>

	* library/demos/widget:		New part for the widget demo showing
	* library/demos/unicodeout.tcl: Tk's UNICODE output. [Patch 627453]

2003-02-18  Andreas Kupries  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl (HP xnet [Bug 651811]).

2003-02-18  Mo DeJong  <[email protected]>

	* unix/configure: Regen.
	* unix/tcl.m4: Update from Tcl.

2003-02-18  Jeff Hobbs	<[email protected]>

	* generic/tkText.c (TextWidgetCmd): remove unused lastEnd var. [Bug
	664790]

	* generic/tkCanvPs.c (TkPostscriptImage): remove unused depth var. [Bug
	664787]

	* generic/tkEntry.c (EntrySetValue): removed unused code var. [Bug
	664781]

	* library/tk.tcl (::tk::TabToWindow): auto-highlight spinboxes as well
	as entries when tabbing in. [Patch 683813] (bron)

	* library/xmfbox.tcl (::tk::MotifFDialog_ActivateSEnt): correct sub on
	embedded newlines. [Patch 688572] (bonfield)

	* doc/colors.n: corrected B values [Bug 682714].

	* win/tkWinInit.c (TkpDisplayWarning): truncate MessageBox string to
	1024 chars to prevent possible oversized window errors. May be
	necessary in other MB uses (ie Tcl_AppInit). [Tcl Bug 608559]

2003-02-18  Vince Darley <[email protected]>

	* macosx/tkMacOSXMenu.c: (SetMenuTitle) fix to utf encoding problem
	when setting menu titles, and provisional support for icons. [Tcl Bug
	625080]

2003-02-18  Donal K. Fellows  <[email protected]>

	* generic/tkImgGIF.c (FileReadGIF): Ensure that the trashBuffer is
	always deallocated on function exit to stop a potential memory leak.

2003-02-17  Mo DeJong  <[email protected]>

	* generic/tkEvent.c (Tk_HandleEvent): Fixup button press state saving
	code, it was incorrectly converting normal motion events into button
	press and motion events in some cases.
	* generic/tkInt.h: Add mouseButtonWindow member to the TkDisplay
	structure.
	* tests/event.test: Add test case for faulty button motion logic.

2003-02-14  Jeff Hobbs	<[email protected]>

	* README:	      Bumped to 8.4.2.
	* generic/tk.h:
	* macosx/Wish.pbproj/project.pbxproj:
	* unix/configure:
	* unix/configure.in:
	* unix/tcl.m4:
	* unix/tk.spec:
	* win/configure:
	* 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 \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.
	(TkpSetCursor): Don't reset the cursor if there is no change.
	* macosx/tkMacOSXMouseEvent.c (GeneratePollingEvents): Don't directly
	call TkMacOSXInstallCursor, it gets called by the call to
	Tk_UpdatePointer immediately above.

2003-02-05  Fred Fish  <[email protected]>

	* macosx/tkMacOSXWm.c (Tk_SetGrid): Fix precedence problem with
	* mac/tkMacWm.c (Tk_SetGrid):	    '==' and '|'.

2003-02-08  Jeff Hobbs	<[email protected]>

	* generic/tkCanvArc.c (CreateArc):	 Rework canvas create item type
	* generic/tkCanvBmap.c (CreateBitmap):	 coords handling to be
	* generic/tkCanvImg.c (CreateImage):	 consistent across types and
	* generic/tkCanvPoly.c (CreatePolygon):	 not pass empty coords to item
	* generic/tkCanvLine.c (CreateLine):	 creation procs.
	* generic/tkCanvText.c (CreateText):
	* generic/tkCanvWind.c (CreateWinItem):
	* generic/tkCanvas.c (CanvasWidgetCmd CANV_CREATE):
	* generic/tkRectOval.c (CreateRectOval):
	* tests/canvRect.test:
	* tests/canvText.test:
	* tests/canvas.test:

2003-01-28  Joe English	 <[email protected]>

	* generic/tkInt.h (TkDisplay,TkMainInfo):
	* generic/tkObj.c (windowObjType):
	* generic/tkWindow.c (Tk_DestroyWindow):
	* tests/wm.test (wm-deletion-epoch-1.1): Moved 'deletionEpoch' field
	from TkDisplay to TkMainInfo. Reworked windowObj type. Fixes [Bug
	671330] "segfault when e.g. deiconifying destroyed window"

2003-01-23  D. Richard Hipp  <[email protected]>

	* library/entry.tcl: Fix the KeyPress binding on the entry widget so
	that it enters text from left to right (not right to left) even if the
	mouse button is being held down. [Bug 673687]

2003-01-22  Donal K. Fellows  <[email protected]>

	* generic/tkFrame.c (TkToplevelWindowForCommand): Added way of mapping
	from command names to tkwins-for-toplevels.
	* generic/tkImage.c (Tk_ImageObjCmd): Added check to make sure that
	you're not creating an image named the same as .'s command, which
	refixes 220891, even when the name of the command has been changed with
	'rename'. The error message is better too.
	* tests/image.test (image-1.10,image-1.11): Updated to match new error
	message and added test for the rename case.

2003-01-19  Jeff Hobbs	<[email protected]>

	* generic/tkImage.c (DeleteImage): delete the image's entry in the
	image table correctly when there are no more instances. This reopens
	bug 220891. [Bug 669759]

2003-01-18  Jeff Hobbs	<[email protected]>

	* doc/loadTk.n: note that ::safe::loadTk has a prereq on
	::safe::interpCreate or ::safe::interpInit. [Bug 669159]

	* doc/photo.n: $image put only accepts -format and -to, and note
	extended use of -to.

2003-01-17  D. Richard Hipp <[email protected]>

	* generic/tkCanvUtil.c: The clipping algorithm introduced on 2003-01-08
	was unnecessarily aggressive in reducing the size of the clipping box.
	This did not cause a problem for normal display, but did create trouble
	for some extensions that attempt to render a canvas on a GDI printer
	under Windows. The patch here relaxes the constraints on the clipping
	box somewhat. [Bug 663981]

2003-01-14  Joe English	 <[email protected]>

	* generic/tkSelect.c (Tk_CreateSelHandler): Fix for [Bug 666346]
	"Selection handling crashes under KDE 3.0"
	* tests/unixSelect.test (unixSelect-1.20): Added test case.

2003-01-13  Mo DeJong  <[email protected]>

	* win/tkWinDialog.c (Tk_ChooseDirectoryObjCmd)
	(ChooseDirectoryValidateProc, Tk_MessageBoxObjCmd): Remove unused
	tsdPtr variable. Use TEXT macro instead of _T macro since _T does not
	work under Cygwin. Declare flags as UINT to avoid compiler warning when
	compiling with mingw.

2003-01-12  Mo DeJong  <[email protected]>

	* win/Makefile.in: Add TCL_DEFS to AC_FLAGS so that compiler flags
	defined by Tcl get passed to the compiler. Add empty rule for cat.c so
	that Tk compiles under msys.
	* win/configure: Regen.
	* win/tcl.m4: Update from Tcl, this pulls in a subst of TCL_DEFS, it
	also defines USE_THREAD_ALLOC when threads are used and it updates the
	SC_ENABLE_SYMBOLS and SC_PROG_TCLSH macros to match the ones used in
	Tcl.

2003-01-10  Joe English	 <[email protected]>

	* unix/tkUnixEvent.c (OpenIM): Remove unused variable (Fixes: [Bug
	664780] "SGI warning: OpenIM")

2003-01-08  D. Richard Hipp <[email protected]>

	* generic/tkCanvLine.c:
	* generic/tkCanvas.h:
	* generic/tkCanvUtil.c: Clip long lines so that they will display
	properly even on windowing systems where coordinates are expressed as
	16-bit numbers. [Bug 663981]

2003-01-03  Jeff Hobbs	<[email protected]>

	* generic/tkFrame.c (CreateFrame): throw a Tcl error instead of a panic
	when we cannot get a main window and appname is NULL. This can indicate
	that a user tried to create a frame/toplevel while Tk was dying. [Bug
	661792]

	******************************************************************
	*** CHANGELOG ENTRIES FOR 2002 AND EARLIER IN "ChangeLog.2002" ***
	******************************************************************
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted ChangeLog.2007.

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

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

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

2007-12-17  Donal K. Fellows  <[email protected]>

	*** 8.5.0 TAGGED FOR RELEASE ***

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

2007-12-14  Don Porter  <[email protected]>

	* changes:	More updates for 8.5.0 release.

2007-12-14  Joe English  <[email protected]>

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

2007-12-14  Pat Thoyts  <[email protected]>

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

2007-12-14  Pat Thoyts <[email protected]>

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

2007-12-13  Jeff Hobbs  <[email protected]>

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

2007-12-12  Jeff Hobbs  <[email protected]>

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

2007-12-12  Daniel Steffen  <[email protected]>

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

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

2007-12-12  Joe English  <[email protected]>

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

2007-12-12  Don Porter  <[email protected]>

	* changes:		Updated for 8.5.0 release.

2007-12-11  Joe English  <[email protected]>

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

2007-12-11  Donal K. Fellows  <[email protected]>

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

2007-12-10  Donal K. Fellows  <[email protected]>

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

2007-12-10  Joe English  <[email protected]>

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

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

2007-12-10  Daniel Steffen  <[email protected]>

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

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

2007-12-10  Donal K. Fellows  <[email protected]>

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

2007-12-10  Pat Thoyts  <[email protected]>

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

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

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

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

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

2007-12-09  Donal K. Fellows  <[email protected]>

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

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

2007-12-07  Joe English  <[email protected]>

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

2007-12-07  Don Porter  <[email protected]>

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

2007-12-05  Joe English  <[email protected]>

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

2007-12-05  Jeff Hobbs  <[email protected]>

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

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

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

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

2007-12-04  Joe English  <[email protected]>

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

2007-12-04  Donal K. Fellows  <[email protected]>

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

	* library/msgs/da.msg: Added Danish messages. [Patch 1844143]. Many
	thanks to Torsten Berg <[email protected]>.

2007-12-03  Jeff Hobbs  <[email protected]>

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

2007-12-01  Joe English  <[email protected]>

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

2007-11-28  Don Porter  <[email protected]>

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

2007-11-26  Kevin Kenny  <[email protected]>

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

2007-11-25  Joe English  <[email protected]>

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

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

2007-11-23  Donal K. Fellows  <[email protected]>

	* unix/README: General improvements.

2007-11-21  Donal K. Fellows  <[email protected]>

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

2007-11-19  Don Porter  <[email protected]>

	*** 8.5b3 TAGGED FOR RELEASE ***

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

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

	* changes:		Update changes for 8.5b3 release.

2007-11-19  Pat Thoyts  <[email protected]>

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

2007-11-18  Joe English  <[email protected]>

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

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

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

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

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

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

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

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

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

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

2007-11-18  Pat Thoyts  <[email protected]>

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

2007-11-17  Pat Thoyts  <[email protected]>

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

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

2007-11-17  Joe English  <[email protected]>

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

2007-11-16  Benjamin Riefenstahl  <[email protected]>

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

2007-11-15  Daniel Steffen  <[email protected]>

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

2007-11-14  Donal K. Fellows  <[email protected]>

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

2007-11-11  Benjamin Riefenstahl  <[email protected]>

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

2007-11-09  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

	* macosx/tkMacOSXPrivate.h:	correct Leopard HIToolboxVersionNumber.

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

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

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

2007-11-07  Joe English  <[email protected]>

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

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

2007-11-06  Andreas Kupries  <[email protected]>

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

2007-11-05  Joe English  <[email protected]>

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

2007-11-05  Andreas Kupries  <[email protected]>

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

2007-11-05  Joe English  <[email protected]>

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

2007-11-04  Joe English  <[email protected]>

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

2007-11-04  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

2007-11-03  Pat Thoyts  <[email protected]>

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

2007-11-02  Donal K. Fellows  <[email protected]>

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

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

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

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

2007-11-01  Donal K. Fellows  <[email protected]>

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

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

2007-11-01  Daniel Steffen  <[email protected]>

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

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

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

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

2007-11-01  Donal K. Fellows  <[email protected]>

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

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

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

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

2007-10-31  Donal K. Fellows  <[email protected]>

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

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

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

2007-10-30  Joe English  <[email protected]>

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

2007-10-31  Pat Thoyts  <[email protected]>

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

2007-10-30  Jeff Hobbs  <[email protected]>

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

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

2007-10-30  Don Porter  <[email protected]>

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

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

2007-10-30  Jeff Hobbs  <[email protected]>

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

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

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

2007-10-30  Donal K. Fellows  <[email protected]>

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

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

2007-10-30  Joe English  <[email protected]>

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

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

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

2007-10-30  Donal K. Fellows  <[email protected]>

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

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

2007-10-29  Jeff Hobbs  <[email protected]>

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

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

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

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

2007-10-29  Donal K. Fellows  <[email protected]>

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

2007-10-28  Joe English  <[email protected]>

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

2007-10-26  Don Porter  <[email protected]>

	*** 8.5b2 TAGGED FOR RELEASE ***

	* changes:		Update changes for 8.5b2 release.

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

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

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

2007-10-26  Daniel Steffen  <[email protected]>

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

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

2007-10-25  Joe English  <[email protected]>

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

2007-10-25  Jeff Hobbs  <[email protected]>

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

2007-10-25  Don Porter  <[email protected]>

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

2007-10-24  Joe English  <[email protected]>

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

2007-10-24  Donal K. Fellows  <[email protected]>

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

2007-10-24  Pat Thoyts  <[email protected]>

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

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

2007-10-23  Jeff Hobbs  <[email protected]>

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

2007-10-23  Joe English  <[email protected]>

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

2007-10-23  Don Porter  <[email protected]>

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

2007-10-23  Donal K. Fellows  <[email protected]>

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

2007-10-23  Pat Thoyts  <[email protected]>

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

2007-10-23  Daniel Steffen  <[email protected]>

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

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

2007-10-22  Donal K. Fellows  <[email protected]>

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

2007-10-22  Joe English  <[email protected]>

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

2007-10-22  Daniel Steffen  <[email protected]>

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

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

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

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

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

2007-10-18  Donal K. Fellows  <[email protected]>

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

2007-10-18  Pat Thoyts  <[email protected]>

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

2007-10-17  David Gravereaux <[email protected]>

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

2007-10-18  Daniel Steffen  <[email protected]>

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

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

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

	* macosx/tkMacOSXWm.c:		fix warnings.

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

2007-10-17  Donal K. Fellows  <[email protected]>

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

2007-10-16  David Gravereaux <[email protected]>

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

2007-10-16  Donal K. Fellows  <[email protected]>

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

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

2007-10-15  Donal K. Fellows  <[email protected]>

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

2007-10-15  Jeff Hobbs  <[email protected]>

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

2007-10-15  Joe English  <[email protected]>

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

2007-10-15  Daniel Steffen  <[email protected]>

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

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

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

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

2007-10-14  Jeff Hobbs  <[email protected]>

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

2007-10-12  Pat Thoyts  <[email protected]>

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

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

2007-10-12  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

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

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

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

2007-10-11  David Gravereaux <[email protected]>

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

2007-10-11  Daniel Steffen  <[email protected]>

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

2007-10-09  Pat Thoyts  <[email protected]>

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

2007-10-02  Don Porter  <[email protected]>

	[core-stabilizer-branch]

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

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

2007-09-30  Joe English  <[email protected]>

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

2007-09-26  Donal K. Fellows  <[email protected]>

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

2007-09-20  Donal K. Fellows  <[email protected]>

	*** 8.5b1 TAGGED FOR RELEASE ***

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

2007-09-20  Don Porter  <[email protected]>

	* changes: updates for 8.5b1 release.

2007-09-19  Don Porter  <[email protected]>

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

2007-09-19  Pat Thoyts  <[email protected]>

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

2007-09-18  Don Porter  <[email protected]>

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

2007-09-18  Donal K. Fellows  <[email protected]>

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

2007-09-18  Pat Thoyts  <[email protected]>

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

2007-09-17  Pat Thoyts  <[email protected]>

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

2007-09-17  Joe English  <[email protected]>

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

2007-09-17  Don Porter  <[email protected]>

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

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

2007-09-17  Joe English  <[email protected]>

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

2007-09-15  Daniel Steffen  <[email protected]>

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

2007-09-14  Daniel Steffen  <[email protected]>

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

2007-09-12  Andreas Kupries  <[email protected]>

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

2007-09-11  Reinhard Max  <[email protected]>

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

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

2007-09-11  Don Porter  <[email protected]>

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

2007-09-10  Jeff Hobbs  <[email protected]>

	* unix/README: typo corrections [Bug 1788682]

2007-09-10  Don Porter  <[email protected]>

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

2007-09-06  Don Porter  <[email protected]>

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

2007-09-06  Daniel Steffen  <[email protected]>

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

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

	* macosx/README: document project changes.

2007-09-04  Joe English  <[email protected]>

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

2007-09-04  Don Porter  <[email protected]>

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

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

2007-09-03  Daniel Steffen  <[email protected]>

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

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

2007-08-28  Donal K. Fellows  <[email protected]>

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

2007-08-27  Daniel Steffen  <[email protected]>

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

2007-08-21  Pat Thoyts  <[email protected]>

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

2007-08-07  Daniel Steffen  <[email protected]>

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

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

	* unix/configure: autoconf-2.59

2007-08-01  Pat Thoyts  <[email protected]>

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

2007-07-25  Daniel Steffen  <[email protected]>

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

2007-07-09  Jeff Hobbs  <[email protected]>

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

2007-07-09  Daniel Steffen  <[email protected]>

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

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

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

2007-07-06  Joe English  <[email protected]>

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

2007-07-04  Andreas Kupries  <[email protected]>

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

2007-07-02  Daniel Steffen  <[email protected]>

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

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

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

2007-06-29  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

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

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

	* macosx/README: Document Wish.xcodeproj changes.

2007-06-23  Daniel Steffen  <[email protected]>

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

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

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

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

2007-06-20  Jeff Hobbs  <[email protected]>

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

2007-06-09  Joe English  <[email protected]>

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

2007-06-09  Jeff Hobbs  <[email protected]>

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

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

2007-06-09  Joe English  <[email protected]>

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

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

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

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

2007-06-09  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

2007-06-06  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

2007-06-05  Donal K. Fellows  <[email protected]>

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

2007-06-03  Daniel Steffen  <[email protected]>

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

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

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

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

2007-06-02  Daniel Steffen  <[email protected]>

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

2007-05-31  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

2007-05-30  Don Porter  <[email protected]>

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

2007-05-30  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

2007-05-28  Benjamin Riefenstahl  <[email protected]>

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

2007-05-25  Joe English  <[email protected]>

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

2007-05-25  Donal K. Fellows  <[email protected]>

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

2007-05-22  Don Porter  <[email protected]>

	[core-stabilizer-branch]

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

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

2007-05-18  Joe English  <[email protected]>

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

2007-05-18  Don Porter  <[email protected]>

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

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

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

2007-05-17  Daniel Steffen  <[email protected]>

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

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

2007-05-16  Joe English  <[email protected]>

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

	Removed TCL_STORAGE_CLASS monkey business, as it had no effect.

2007-05-16  Don Porter  <[email protected]>

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

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

2007-05-16  Pat Thoyts  <[email protected]>

	* win/makefile.vc: Test ttk widgets.

2007-05-15  Joe English  <[email protected]>

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

2007-05-15  Don Porter  <[email protected]>

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

2007-05-15  Joe English  <[email protected]>

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

2007-05-14  Don Porter  <[email protected]>

	[Tk Bug 1712081]

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

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

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

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

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

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

2007-05-11  Pat Thoyts  <[email protected]>

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

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

2007-05-09  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

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

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

2007-05-07  Joe English  <[email protected]>

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

2007-05-04  Pat Thoyts  <[email protected]>

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

2007-05-04  Donal K. Fellows  <[email protected]>

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

2007-05-03  Donal K. Fellows  <[email protected]>

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

2007-04-29  Daniel Steffen  <[email protected]>

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

2007-04-27  Joe English  <[email protected]>

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

2007-04-26  Joe English  <[email protected]>

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

2007-04-26  Jeff Hobbs  <[email protected]>

	*** 8.5a6 TAGGED FOR RELEASE ***

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

2007-04-25  Jeff Hobbs  <[email protected]>

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

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

2007-04-25  Daniel Steffen  <[email protected]>

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

2007-04-24  Jeff Hobbs  <[email protected]>

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

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

2007-04-23  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2007-04-21  Jeff Hobbs  <[email protected]>

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

2007-04-17  Donal K. Fellows  <[email protected]>

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

2007-04-13  Donal K. Fellows  <[email protected]>

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

2007-04-12  Jeff Hobbs  <[email protected]>

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

2007-04-10  Joe English  <[email protected]>

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

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

2007-03-21  Joe English  <[email protected]>

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

2007-03-08  Joe English  <[email protected]>

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

2007-03-07  Daniel Steffen  <[email protected]>

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

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

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

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

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

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

2007-02-25  Peter Spjuth  <[email protected]>

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

2007-02-23  Jeff Hobbs  <[email protected]>

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

2007-02-19  Jeff Hobbs  <[email protected]>

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

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

2007-02-09  Joe Mistachkin  <[email protected]>

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

2007-02-06  Joe English  <[email protected]>

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

2007-02-04  Daniel Steffen  <[email protected]>

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

2007-02-03  Joe Mistachkin  <[email protected]>

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

2007-02-02  Pat Thoyts  <[email protected]>

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

2007-01-28  Daniel Steffen  <[email protected]>

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

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

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

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

2007-01-25  Daniel Steffen  <[email protected]>

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

	* unix/configure: autoconf-2.59

2007-01-19  Joe Mistachkin  <[email protected]>

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

2007-01-19  Daniel Steffen  <[email protected]>

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

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

	* unix/configure: autoconf-2.59

2007-01-11  Jeff Hobbs  <[email protected]>

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

2007-01-11  Joe English  <[email protected]>

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

2007-01-11  Joe English  <[email protected]>

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

2007-01-03  Jan Nijtmans  <[email protected]>

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

2007-01-02  Donal K. Fellows  <[email protected]>

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

2006-12-31  Benjamin Riefenstahl  <[email protected]>

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

2006-12-28  Mo DeJong  <[email protected]>

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

2006-12-26  Joe English  <[email protected]>

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

2006-12-22  Donal K. Fellows  <[email protected]>

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

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

2006-12-19  Jeff Hobbs  <[email protected]>

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

2006-12-19  Daniel Steffen  <[email protected]>

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

2006-12-18  Joe English  <[email protected]>

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

2006-12-17  Joe English  <[email protected]>

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

2006-12-16  Mo DeJong  <[email protected]>

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

2006-12-14  Joe English  <[email protected]>

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

2006-12-13  Jeff Hobbs  <[email protected]>

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

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

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

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

2006-12-13  Joe English  <[email protected]>

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

2006-12-12  Joe English  <[email protected]>

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

2006-12-12  Mo DeJong  <[email protected]>

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

2006-12-11  Donal K. Fellows  <[email protected]>

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

2006-12-10  Joe English  <[email protected]>

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

2006-12-09  Joe English  <[email protected]>

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

2006-12-06  Kevin Kenny  <[email protected]>

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

2006-12-04  Jeff Hobbs  <[email protected]>

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

2006-12-04  Donal K. Fellows  <[email protected]>

	TIP #286 IMPLEMENTATION

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

2006-12-01  Kevin Kenny  <[email protected]>

	TIP #300 IMPLEMENTATION

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

2006-12-01  Jeff Hobbs  <[email protected]>

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

2006-12-01  Joe English  <[email protected]>

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

2006-11-30  Daniel Steffen  <[email protected]>

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

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

2006-11-28  Joe English  <[email protected]>

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

2006-11-27  Kevin Kenny  <[email protected]>

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

2006-11-26  Joe English  <[email protected]>

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

2006-11-26  Daniel Steffen  <[email protected]>

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

2006-11-24  Jeff Hobbs  <[email protected]>

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

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

2006-11-24  Joe English  <[email protected]>

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

2006-11-23  Jeff Hobbs  <[email protected]>

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

2006-11-20  Joe English  <[email protected]>

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

2006-11-16  Donal K. Fellows  <[email protected]>

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

	* doc/labelframe.n: Added an example.

2006-11-15  Donal K. Fellows  <[email protected]>

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

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

2006-11-14  Joe English  <[email protected]>

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

2006-11-12  Joe English  <[email protected]>

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

2006-11-12  Joe English  <[email protected]>

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

2006-11-12  Joe English  <[email protected]>

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

2006-11-10  Daniel Steffen  <[email protected]>

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

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

2006-11-08  Kevin Kenny  <[email protected]>

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

2006-11-07  Kevin Kenny  <[email protected]>

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

2006-11-06  Joe English  <[email protected]>

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

2006-11-03  Pat Thoyts  <[email protected]>

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

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

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

2006-11-02  Daniel Steffen  <[email protected]>

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

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

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

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

2006-11-01  Daniel Steffen  <[email protected]>

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

2006-10-31  Pat Thoyts  <[email protected]>

	* win/makefile.vc: Added ttk files to msvc build and add manifest
	* win/rules.vc: files to binaries with MSVC8.

2006-10-31  Daniel Steffen  <[email protected]>

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

	* macosx/ttkMacOSXTheme.c: standardize header #includes.

	* unix/Makefile (checkstubs, checkexports): check ttk.decls, allow
	export of Ttk prefixed symbols.

	* generic/ttk/tkDefaultTheme.c: fix warnings.

2006-10-30  Jeff Hobbs  <[email protected]>

	* doc/ttk_Geometry.3, doc/ttk_Theme.3, doc/ttk_button.n:
	* doc/ttk_checkbutton.n, doc/ttk_combobox.n, doc/ttk_dialog.n:
	* doc/ttk_entry.n, doc/ttk_frame.n, doc/ttk_image.n:
	* doc/ttk_intro.n, doc/ttk_label.n, doc/ttk_labelframe.n:
	* doc/ttk_menubutton.n, doc/ttk_notebook.n, doc/ttk_panedwindow.n:
	* doc/ttk_progressbar.n, doc/ttk_radiobutton.n, doc/ttk_scrollbar.n:
	* doc/ttk_separator.n, doc/ttk_sizegrip.n, doc/ttk_style.n:
	* doc/ttk_treeview.n, doc/ttk_widget.n,:
	* generic/ttk/ttk.decls, generic/ttk/ttkBlink.c:
	* generic/ttk/ttkButton.c, generic/ttk/ttkCache.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.c:
	* generic/ttk/ttkManager.h, generic/ttk/ttkNotebook.c:
	* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c:
	* generic/ttk/ttkScale.c, generic/ttk/ttkScroll.c:
	* generic/ttk/ttkScrollbar.c, generic/ttk/ttkSeparator.c:
	* generic/ttk/ttkSquare.c, generic/ttk/ttkState.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTagSet.c, generic/ttk/ttkTheme.c:
	* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h:
	* generic/ttk/ttkTrace.c, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h:
	* library/demos/ttk_demo.tcl, library/demos/ttk_iconlib.tcl:
	* library/demos/ttk_repeater.tcl:
	* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl:
	* library/ttk/button.tcl, library/ttk/clamTheme.tcl:
	* library/ttk/classicTheme.tcl, library/ttk/combobox.tcl:
	* library/ttk/cursors.tcl, library/ttk/defaults.tcl:
	* library/ttk/dialog.tcl, library/ttk/entry.tcl:
	* library/ttk/fonts.tcl, library/ttk/icons.tcl:
	* library/ttk/keynav.tcl, library/ttk/menubutton.tcl:
	* library/ttk/notebook.tcl, library/ttk/panedwindow.tcl:
	* library/ttk/progress.tcl, library/ttk/scale.tcl:
	* library/ttk/scrollbar.tcl, library/ttk/sizegrip.tcl:
	* library/ttk/treeview.tcl, library/ttk/ttk.tcl:
	* library/ttk/utils.tcl, library/ttk/winTheme.tcl:
	* library/ttk/xpTheme.tcl:
	* macosx/ttkMacOSXTheme.c:
	* tests/ttk/all.tcl, tests/ttk/bwidget.test, tests/ttk/combobox.test:
	* tests/ttk/entry.test, tests/ttk/image.test:
	* tests/ttk/labelframe.test, tests/ttk/layout.test:
	* tests/ttk/misc.test, tests/ttk/notebook.test:
	* tests/ttk/panedwindow.test, tests/ttk/progressbar.test:
	* tests/ttk/scrollbar.test, tests/ttk/treetags.test:
	* tests/ttk/treeview.test, tests/ttk/ttk.test, tests/ttk/validate.test:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c:
	First import of Ttk themed Tk widgets as branched from tile 0.7.8

	* generic/tkInt.h, generic/tkWindow.c: add Ttk_Init call, copy tk
	classic widgets to ::tk namespace.
	* library/tk.tcl: add source of ttk/ttk.tcl, define $::ttk::library.
	* unix/Makefile.in, win/Makefile.in: add Ttk build bits
	* win/configure, win/configure.in: check for uxtheme.h (XP theme).

2006-10-23  Don Porter  <[email protected]>

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

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

2006-10-19  Pat Thoyts  <[email protected]>

	*** 8.5a5 TAGGED FOR RELEASE ***

	* generic/tkImgBmap.c: Fixed line endings.
	* win/makefile.vc:  Patched up build system to manage
	* win/rules.vc:  AMD64 with MSVC8
	* win/nmakehlp.c:   Ensure operation without Platform SDK.

2006-10-18  Don Porter  <[email protected]>

	* changes:		8.5a5 release date set.

2006-10-17  Jeff Hobbs  <[email protected]>

	* doc/text.n: fix docs to not correct -tabs usage case.

	* generic/tkTextDisp.c (SizeOfTab): fix -tabstyle wordprocessor tab
	alignment to correct tab edge case. [Bug 1578858]

2006-10-17  Pat Thoyts  <[email protected]>

	* generic/tkText.c: Applied suggested patch from [Bug 1536735]
	* tests/text.test:  Update test for above patch.
	* tests/textWind.test:  Corrected test to catch all messages
	* tests/safe.test: Silence spurious win32 failure awaiting TIP150
	* tests/winDialog.test: Updated test for file name length check.
	* test/winWm.test: Corrected test expectation for menu wrapping.

2006-10-16  Andreas Kupries  <[email protected]>

	* doc/WindowId.3: Pat's commit on 2006-10-08 broke the .SH NAME
	information across several lines, breaking the cross-linking of
	manpages during installation for this one. Put everything back on a
	single line, unbreaking it.

2006-10-16  Daniel Steffen  <[email protected]>

	* changes: updates for 8.5a5 release.

	* macosx/tkMacOSXDraw.c: fix numerous issues in CG and QD drawing
	procs so that they now match X11 drawing much more closely [Bug
	1558051]; use Tiger ellipse drawing API when available; fix comments &
	whitespace.

	* macosx/tkMacOSXInit.c: set default linewidth limit for CG
	antialiasing to 0 as thin horizontal/vertical lines look good now.
	* macosx/README: document CG antialiasing limit changes.

	* generic/tkCanvLine.c (ConfigureLine):  on TkAqua, pass outline
	* generic/tkCanvPoly.c (ConfigurePolygon):  linewidth in gc even for
	* generic/tkRectOval.c (ConfigureRectOval): fills (as it controls AA).

	* macosx/GNUmakefile: don't redo prebinding of non-prebound binaires.

	* library/demos/pendulum.tcl: fix incorrect setting of toplevel title.

2006-10-10  Don Porter  <[email protected]>

	* changes:	Updates for 8.5a5 release

2006-10-08  Pat Thoyts  <[email protected]>

	* generic/tkWindow.c:  Implemented TIP #264 - Tk_Interp function.
	* doc/WindowId.3:   Documented Tk_Interp.
	* generic/tk.decls: Added to the stubs interface and
	* generic/tkDecls.h:   regenerated.
	* generic/tkStubsInit.c:

2006-10-05  Jeff Hobbs  <[email protected]>

	* unix/tkUnixFont.c (Ucs2beToUtfProc, UtfToUcs2beProc):
	(TkpFontPkgInit, encodingAliases): Correct alignment issues in
	encoding conversion. Call ucs-2be "unicode" on big-endian systems.
	[Bug 1122671]

2006-09-27  Andreas Kupries  <[email protected]>

	* unix/Makefile.in (install-binaries): Added a second guard to the
	* win/Makefile.in: package index file to prevent older versions of Tcl
	* win/makefile.vc: from seeing version numbers which may contain a/b
	information, and then balking on them. This could otherwise happen
	when Tcl/Tk 8.4 and 8.5 are installed in the same directory, seeing
	each other. [Bug 1566418]

2006-09-22  Andreas Kupries  <[email protected]>

	* generic/tkConsole.c: TIP #268 update regarding registered package
	* generic/tkMain.c: version, now using full patchlevel instead of
	* generic/tkWindow.c:  major.minor
	* library/tk.tcl:
	* unix/configure:
	* unix/Makefile.in:
	* unix/tcl.m4:
	* win/configure:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/rules.vc:
	* win/tcl.m4:

2006-09-20  Jeff Hobbs  <[email protected]>

	* win/tkWinMenu.c (TkpPostMenu): disable menu animation in menus with
	images to avoid clipping bug. [Bug 1329198]

2006-09-21  Donal K. Fellows  <[email protected]>

	* generic/tkImgBmap.c (ImgBmapPostscript): Change 0 to NULL, since
	they are not interchangable on all platforms in all circumstances.
	[Tcl Bug 1562528]

2006-09-11  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWm.c (TkMacOSXMakeRealWindowExist): revert part of
	2006-05-16 change that had set overrideredirect windows to not become
	activated by the window manager, as this prevented interaction with
	native widgets in such windows [Bug 1472624]; apply changes to carbon
	window attributes even if native window has already been created.

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): fix app
	* macosx/tkMacOSXMenu.c (DrawMenuBarWhenIdle): menu item key shortcuts
	* macosx/tkMacOSXInt.h: when custom ".apple" menu is installed.

	* library/demos/widget: on TkAqua, don't install file menu with single
	quit menu item, as the application menu already has a quit item.

	* macosx/tkMacOSXColor.c: fix building on Mac OS X 10.2.

2006-09-10  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXColor.c (TkSetMacColor,TkpGetColor): use AppearanceMgr
	* macosx/tkMacOSXDefault.h: to retrieve platform std colors for text
	* macosx/tkMacOSXPort.h:    selections, add "systemHighlightSecondary"
	color name for standard color of inactive selections, use this color as
	default for text widget -inactiveselectbackground to implement platform
	standard look for inactive text selections.

	* library/text.tcl (aqua): remove focus bindings to set selection color

	* generic/tkTextBTree.c (TkTextIsElided): on TkAqua, don't show
	* generic/tkTextDisp.c (GetStyle):   inactive text selection when
						  text widget is disabled.

	* generic/tkEntry.c (DisplayEntry): change default TkAqua selection
	* macosx/tkMacOSXDefault.h:     relief to "flat" (platform std).

	* generic/tkText.c (CreateWidget): fix bug leading to default text
	selection relief string DEF_TEXT_SELECT_RELIEF being ignored.

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): allow mouse
	event delivery to background windows with kWindowNoActivatesAttribute
	(e.g. overrideredirect windows), as these never come to the foreground
	they would never receive any mouse events otherwise. [Bug 1472624]

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXGenerateFocusEvent): do not
	send focus events to any windows with kWindowNoActivatesAttribute.

	* macosx/tkMacOSXXStubs.c (XQueryColor, XQueryColors): implement basic
	XColor computation from pixel values, enough to make tkImg's window.c
	happy, fixes img::window failures reported on tcl-mac.

	* macosx/tkMacOSXMenu.c (DrawMenuEntryLabel): fix leak. [Bug 1554672]

	* macosx/GNUmakefile: workaround bug in 'cp -pRH' on Darwin 6 and
	earlier, fixes 'make embedded' failure reported on tcl-mac; fix error
	from 'make deploy' with same build tree as previous 'make embedded'.

	* macosx/Wish.xcodeproj/project.pbxproj: add new tclUnixCompat.c file.

	* macosx/tkMacOSXEntry.c (TkpDrawEntryBorderAndFocus): fix typo.

	* unix/tcl.m4: sync with tcl/unix/tcl.m4.
	* unix/configure: autoconf-2.59

2006-09-06  Jeff Hobbs  <[email protected]>

	* generic/tkEntry.c:   move hard-coded ALWAYS_SHOW_SELECTION control
	* generic/tkInt.h:   of entry/text selection display based on focus
	* generic/tkText.c: to the Tcl level, controlled by
	* generic/tkWindow.c:  ::tk::AlwaysShowSelection (boolean, private).
	* library/tk.tcl:   [Bug 1553691]
	* macosx/tkMacOSXDefault.h:
	* unix/tkUnixDefault.h:
	* unix/tkUnixPort.h:
	* win/tkWinDefault.h:

2006-08-30  Jeff Hobbs  <[email protected]>

	* win/tkWinKey.c: Add WM_UNICHAR window message support (used by
	* win/tkWinX.c:   virtual keyboard apps). [Bug 1518677] (petasis)

2006-08-24  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXScrlbr.c (UpdateControlValues): set native scrollbar
	control bounds only once all size adjustments have been computed.
	Fixes issue with grow icon obscuring scrollbar reported on tcl-mac.

2006-08-21  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXCarbonEvents.c (CarbonTimerProc): avoid starving main
	event loop: limit the number of tcl events processed per invocation.
	Fixes bug reported on tcl-mac by Kevan Hashemi.

2006-08-18  Donal K. Fellows  <[email protected]>

	* tests/text.test (text-25.15): Added test suggested by Sam
	<[email protected]> on comp.lang.tcl

	* generic/tk.h, generic/tkInt.h: Stylistic improvements. No API change.

2006-08-18  Daniel Steffen  <[email protected]>

	* unix/tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
	universal builds including x86_64, for 64-bit CoreFoundation on Leopard
	and for use of -mmacosx-version-min instead of MACOSX_DEPLOYMENT_TARGET
	* unix/configure.in (Darwin): remove 64-bit arch flags from CFLAGS for
	combined 32-bit and 64-bit universal builds, as neither TkAqua nor
	TkX11 can be built for 64-bit at present.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* macosx/Wish.xcodeproj/project.pbxproj: switch native release targets
	to use DWARF with dSYM, Xcode 3.0 changes.
	* macosx/README: updates for x86_64 support in Tcl.

	* macosx/tkMacOSXInit.c (TkpInit): when available, use public
	TransformProcessType() API instead of CPSEnableForegroundOperation()
	SPI to notify the window server that we are a GUI application.

	* macosx/tkMacOSXWm.c (WmAttrGetTitlePath): use HIWindow API on >=Tiger

	* macosx/tkMacOSXMouseEvent.c (GenerateToolbarButtonEvent):
	* macosx/tkMacOSXMenus.c (GenerateEditEvent):
	* macosx/tkMacOSXMenu.c (MenuSelectEvent): bzero() the XVirtualEvent
	structure before use to ensure all fields are initialized. [Bug
	1542205]

2006-08-16  Jeff Hobbs  <[email protected]>

	* macosx/tkMacOSXWm.c (WmAttributesCmd): correct OS X result for [wm
	attributes $top].

2006-07-25  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): handle key
	shortcut for kHICommandQuit in the same way as other application menu
	item key shortcuts. [Bug 1516950]

2006-07-24  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWm.c (TkWmMapWindow): fix incorrect values of wmInfo
	parentWidth/Height for toplevels by recalculating them once the window
	is mapped (i.e once the window&structure sizes are known). [Bug
	1358663]
	(ParseGeometry): sync with ParseGeometry in tkUnixWm.c/tkWinWm.c.

2006-07-21  Daniel Steffen  <[email protected]>

	* generic/tkBind.c (TkBindInit): for REDO_KEYSYM_LOOKUP, change
	keysym-to-string mapping hash to use first name in ks_names.h instead
	of last (if there are multiple possibilities), e.g. "F11" instead of
	"L1".

	* macosx/tkMacOSXKeyboard.c (TkpGetKeySym): correct keysyms for pure
	modifier key presses [Bugs 700311, 1525905]; correct keysym for Enter
	key; add keysyms for new NumLock and Fn modifiers (added 2005-08-09).

2006-07-20  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWm.c (WmAttributesCmd, WmIconbitmapCmd): add support
	* unix/tkUnixSend.c (Tk_GetUserInactiveTime):       for weakly
	importing symbols not available on OSX 10.2 or 10.3, enables binaires
	built on later OSX versions to run on earlier ones.
	* macosx/Wish.xcodeproj/project.pbxproj: enable weak-linking; turn on
	                 extra warnings.
	* macosx/README: document how to enable weak-linking; cleanup.
	* unix/configure.in: add check on Darwin-X11 for ld support of -weak-l
	* unix/tcl.m4:  flag and weak-link libXss if possible as it is not
	available before OSX 10.4; enforce requirement of OSX 10.2 for TkAqua;
	move Darwin specific checks & defines that are only relevant to the tcl
	build out of tcl.m4; restrict framework option to Darwin; clean up
	quoting and help messages.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* macosx/GNUmakefile: enable xft for TkX11 build.
	* macosx/tkMacOSXFont.c (TkMacOSXQuarzStartDraw, TkMacOSXQuarzEndDraw):
	verify validity of context returned from QDBeginCGContext() before use.
	* macosx/tkMacOSXKeyEvent.c: ifdef out diagnostic messages to stderr.

	* macosx/tkMacOSXEvent.h:   standardize MAC_OS_X_VERSION_MAX_ALLOWED
	* macosx/tkMacOSXMenu.c:    checks per QA1316, ensure define can be
	* macosx/tkMacOSXMenubutton.c: overridden on command line (from default
	* macosx/tkMacOSXMenus.c:   of current OS version).
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWm.c:

	* generic/tkImgGIF.c (ReadImage):
	* macosx/tkMacOSXCursor.c (TkMacOSXCursor):
	* macosx/tkMacOSXDebug.c (TkMacOSXGetNamedDebugSymbol):
	* macosx/tkMacOSXFont.c (TkpMeasureCharsInContext):
	* macosx/tkMacOSXInit.c (Map):
	* xlib/xgc.c (XCreateGC): fix signed-with-unsigned comparison and other
	warnings from gcc4 -Wextra.

2006-07-14  Andreas Kupries  <[email protected]>

	* generic/tkWindow.c (Initialize): Modify change of 2006-05-25 (jeffh).
	Release mutex a bit earlier, to prevent lock when OS X creates its
	console windows (recursively enters Tk_Init). Patch by JeffH.

2006-07-06  Jeff Hobbs  <[email protected]>

	* library/tkfbox.tcl: catch scrollbar use of highlightthickness

2006-06-21  Jeff Hobbs  <[email protected]>

	* library/bgerror.tcl (::tk::dialog::error::bgerror): remove a couple
	of unnecessary hardcoded options

2006-06-14  Don Porter  <[email protected]>

	* generic/tkScale.c: Revised variable writing logic to account for
	[scale]'s design that it deals with its value as a formatted string,
	and not as a double. [Bug 891141]

2006-06-14  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXSubwindows.c (TkMacOSXInvalidateWindow): ensure
	invalid clip regions are recreated via TkMacOSXUpdateClipRgn() before
	they are used; correct call order of TkMacOSXInvalidateWindow() and
	TkMacOSXInvalClipRgns() throughout. [Bug 1501922]

	* macosx/tkMacOSXDraw.c (TkPutImage): implement drawing of very wide
	images in slices of less than 4096 pixels to workaround CopyBits
	limitation. [Bug 950121]

2006-06-09  Don Porter  <[email protected]>

	* generic/tkMain.c:	Added Tcl_Preserve() call on the master interp
	as crash protection against any Tcl_DeleteInterp() call that might
	happen.

2006-06-01  Don Porter  <[email protected]>

	* generic/tkConsole.c:	Added Tcl_RegisterChannel() calls to bump the
	refcount of channels passed to Tcl_SetStdChannel(). This prevents early
	free-ing of the channels that leads to crashes. [Bug 912571]

2006-05-29  Jeff Hobbs  <[email protected]>

	* win/tkWinEmbed.c (TkpGetOtherWindow):   Do not panic if no window is
	* unix/tkUnixEmbed.c (TkpGetOtherWindow): found; caller handles. [Bug
	* unix/tkUnixWm.c (Tk_CoordsToWindow, UpdateGeometryInfo): 1212056]

	* tests/entry.test (entry-22.1):
	* tests/listbox.test (listbox-6.15):
	* generic/tkListbox.c (ListboxInsertSubCmd, ListboxDeleteSubCmd):
	Ignore Tcl_SetVar2Ex failure of listVarName, similar to entry widget
	handling. [Bug 1424513]

2006-05-26  Jeff Hobbs  <[email protected]>

	* macosx/tkMacOSXButton.c (TkMacOSXDrawControl): correct redraw for
	direct transition from disabled to active state. [Bug 706446]

2006-05-25  Jeff Hobbs  <[email protected]>

	* win/tkWinMenu.c (TkWinMenuKeyObjCmd): get eventPtr after we know the
	window is still alive. [AS bug 45987] [Bug 1236306]

	* generic/tkMenu.c (DeleteMenuCloneEntries): Modify entry index
	changes to work around VC6 optimization bug. [Bug 1224330]

	* generic/tkMessage.c (MessageWidgetObjCmd): Correct msgPtr
	preserve/release pairing. [Bug 1485750] (afredd)

	* generic/tkWindow.c (Initialize): Correct mutex (un)lock pairing.
	[Bug 1479587] (loewis)

	* generic/tkBind.c (Tk_BindEvent, TkCopyAndGlobalEval): use Tcl_EvalEx
	instead of Tcl_GlobalEval.

2006-05-16  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXGenerateFocusEvent): don't send
	focus events to windows of class help or to overrideredirect windows.
	[Bug 1472624]

	* macosx/tkMacOSXWm.c: set overrideredirect windows to not become
	activated by the window manager and to not receive OS activate events
	(should make them behave more like on other platforms); use modern
	window class API for overrideredirect and transient windows; set the
	default class of overrideredirect windows to 'simple' rather than
	'plain' (i.e. no window frame); add missing Panther and Tiger window
	attributes to [::tk::unsupported::MacWindowStyle].

2006-05-12  Jeff Hobbs  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Fix
	opt added 2006-03 that caused slowdown for some common cases. [Bug
	1409140]

2006-05-13  Daniel Steffen  <[email protected]>

	* generic/tkCanvWind.c (DisplayWinItem, WinItemRequestProc): ensure
	canvas window items are unmapped when canvas is unmapped. [Bug 940117]

	* macosx/tkMacOSXSubwindows.c (TkMacOSXUpdateClipRgn): empty clip
	region of unmapped windows to prevent any drawing into them or into
	their children from becoming visible. [Bug 940117]

	* macosx/tkMacOSXInt.h:     revert Jim's attempt of 2005-03-14 to
	* macosx/tkMacOSXSubwindows.c:  fix Bug 940117 as it disables Map/Unmap
	event propagation to children. [Bug 1480105]

	* macosx/tkMacOSXDraw.c (TkPutImage): handle tkPictureIsOpen flag,
	fixes incorrect positioning of images with complex alpha on native
	buttons; actual alpha blending is still broken in this situation. [Bug
	1155596]

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessCommandEvent):
	* macosx/tkMacOSXMenus.c (TkMacOSXInitMenus): workaround carbon bug
	with key shortcut for 'Preferences' app menu item. [Bug 1481503]

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): only check
	for HICommand menu item shortcuts in the application menu.

	* macosx/tkMacOSXInt.h:    initialize keyboard layout setup in
	* macosx/tkMacOSXInit.c:     TkpInit() rather than during handling of
	* macosx/tkMacOSXKeyEvent.c:  first key down event.

	* macosx/tkMacOSXDraw.c:     add optional debug code to flash clip
	* macosx/tkMacOSXSubwindows.c:  regions during update or draw.

2006-05-04  Don Porter  <[email protected]>

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

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

2006-04-28  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWm.c (TkWmMapWindow, InitialWindowBounds): fix use of
	potentially stale window position in initial configure event on first
	map of a window. [Bug 1476443]
	(TkMacOSXWindowOffset): use modern GetWindowStructureWidths API.

	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXMouseEvent.c (TkGenerateButtonEventForXPointer): new
	internal function to generate button events for current pointer
	directly, without requiring prior call to XQueryPointer().

	* macosx/tkMacOSXMouseEvent.c (XQueryPointer): implement return of
	window-local pointer position.

	* macosx/tkMacOSXInt.h:   use improvements above to avoid calls to
	* macosx/tkMacOSXKeyEvent.c: GlobalToLocal() when the current port
	* macosx/tkMacOSXMenu.c:    might not be set correctly. May fix [Bug
	* macosx/tkMacOSXMenus.c:   1243318]
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:

	* tkAboutDlg.r: update copyright.

	* macosx/tkMacOSXDebug.h: sync #includes with core-8-4-branch.
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.h:

2006-04-26  Don Porter  <[email protected]>

	*** 8.5a4 TAGGED FOR RELEASE ***

	* changes:	Updates for next RC

2006-04-25  Donal K. Fellows  <[email protected]>

	* unix/tkUnixFont.c (TkpGetFontFamilies): Fix crash caused when the
	XServer returns invalid font names. [Bug 1475865]

2006-04-23  Vince Darley  <[email protected]>

	* tests/scrollbar.test: fix to tkAqua test failures

2006-04-18  Vince Darley  <[email protected]>

	* macosx/tkMacOSXEmbed.c: fix to [Bug 1088814] test failures in
	embed.test

	* macosx/tkMacOSXWm.c:
	* tests/constraints.tcl:
	* tests/wm.test: fix to 'wm attributes' test for TkAqua

2006-04-11  Peter Spjuth  <[email protected]>

	* generic/tkWindow.c (Tk_NameToWindow): Allow NULL interp to
	Tk_NameToWindow. This fixes TkGetWindowFromObj which promises to handle
	NULL but didn't.

	* generic/tkGrid.c: Fixed handling of out of bounds row or column.
	* tests/grid.test:  [Bug 1432666]

2006-04-11  Don Porter  <[email protected]>

	* unix/Makefile.in:	Updated `make dist` target to be sure the
	message catalogs for the widget demo get packaged into the source code
	distribution. [Bug 1466509]

2006-04-11  Daniel Steffen  <[email protected]>

	* changes: added latest aqua bug fixes.

	* macosx/tkMacOSXDialog.c (Tk_MessageBoxObjCmd): added standard Escape
	key binding for msgbox cancel buttons [Patch 1193614], whitespace.

	* macosx/tkMacOSXCarbonEvents.c: handle kEventCommandUpdateStatus
	* macosx/tkMacOSXEvent.c:     carbon event to dynamically enable
	the 'Preferences' app menu item when proc [::tk::mac::ShowPreferences]
	is defined. [Bug 700316]

	* macosx/tkMacOSXHLEvents.c:    call ::tk::mac::* procs for all
	* macosx/tkMacOSXWindowEvent.c: registered appleevents [FR 1105284],
	implement print applevent handling, style/whitespace cleanup.

	* macosx/tkMacOSXDraw.c (TkMacOSXInitCGDrawing): prevent multiple init

	* macosx/tkMacOSXFont.c: remove #ifdef'd text measuring codepaths now
	* macosx/tkMacOSXInit.c: known to be incorrect, cleanup obsolete text
	* macosx/README:	 antialiasing control code, document ATSUI
				 text antialiasing changes.

	* macosx/tkMacOSXInt.h:     Implemented 'zoomed' window state
	* macosx/tkMacOSXWindowEvent.c: handling for TkAqua, via titlebar
	* macosx/tkMacOSXWm.c:     widget clicks as well as [wm state].
	* doc/wm.n:         [Bug 1073456]

2006-04-10  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (::tk::IconList_Goto): Fix prefix searching so
	that the start location is reasonable, and the prefix matching is
	using the correct Tcl command for this. [Bug 1467938]

2006-04-10  Benjamin Riefenstahl  <[email protected]>

	* macosx/tkMacOSXFont.c (MeasureStringWidth): Use implementation based
	on ATSUGetGlyphBounds (TK_MAC_USE_GETGLYPHBOUNDS), so we can use
	kATSUseFractionalOrigins. This in turn corrects [Bug 1461650].
	(InitFont): Use "." and "W" instead of "i" and "w" to determine the
	"-fixed" attribute. This prevents "Apple Chancery" from being
	classified as fixed.
	(InitFontFamilies): Only get the font families once.

2006-04-09  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWm.c (WmResizableCmd): propagate window attribute
	changes to Carbon window manager. [FR 1467004]
	(TkSetWMName, TkMacOSXMakeRealWindowExist): allow empty name for
	toplevels, remove bogus initial window name. [Bug 1450800]

2006-04-07  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): fix return
	values, implement window dragging & growing in background (with Command
	key down) and by fronting clicks [Bug 934524], use correct button &
	modifier state API when application is in background (also in
	TkMacOSXButtonKeyState).

	* macosx/tkMacOSXWm.c (TkMacOSXGrowToplevel): ensure QD port is set
	correctly before using API relying on it.

2006-04-06  Vince Darley  <[email protected]>

	* macosx/tkMacOSXMouseEvent.c: Now that [wm attributes -titlepath]
	works correctly, add OS support for dragging proxy icons and using the
	titlepath menu.

2006-04-06  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXWm.c (WmAttributesCmd, WmIconbitmapCmd): fix errors in
	setting/removing window proxy icons via [wm attributes -titlepath] and
	[wm iconbitmap], use HIWindow API on Tiger or later. [Bug 1455241]

	* unix/tcl.m4: remove TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
	define on Darwin. [Tcl Bug 1457515]
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

2006-04-05  Jeff Hobbs  <[email protected]>

	* generic/tkWindow.c (Initialize): remove impotent use of
	DeleteWindowsExitProc as a global exit handler.

	* generic/tkMenu.c (TkSetWindowMenuBar): remove extra TkMenuInit call
	that caused finalization panic. [Bug 1456851]
	* win/tkWinMenu.c (FreeID, TkpNewMenu, MenuExitHandler)
	(MenuThreadExitHandler, TkpMenuInit, TkpMenuThreadInit): rework Windows
	menu init/finalization to better respect per-process and per-thread
	boundaries. [Bug 1456851]
	(TkWinMenuKeyObjCmd): Do not error when unknown window is passed in.
	[Bug 1236306]

	* win/tkWinX.c (TkWinXInit): init default keyboard charset correctly.
	[Bug 1374119] (pajas)

	* win/tkWinWm.c (WmProc): pass WM_QUERYENDSESSION message to Tk as
	WM_SAVE_YOURSELF wm protocol callback.

	* tests/textWind.test (textWind-10.6.1): prevent infinite update loop
	in case of test failure.

	* tests/wm.test (wm-attributes-1.2.4): correct expected result.

	* tests/grid.test: fix segfault on empty or "all" index list
	* generic/tkGrid.c (GridRowColumnConfigureCommand): [Bug 1422430]

2006-04-05  Vince Darley  <[email protected]>

	* generic/tkText.c: fix to crash caused on some platforms by new tests
	introduced to check for [Bug 1414171], which destroy the text widget in
	the dump callback script.

2006-03-29  Jeff Hobbs  <[email protected]>

	* generic/tkOption.c (TkOptionDeadWindow): handle OptionThreadExitProc
	being called before DeleteWindowsExitProc.

	* win/Makefile.in: convert _NATIVE paths to use / to avoid ".\"
	path-as-escape issue.

2006-03-29  Don Porter  <[email protected]>

	* changes:	Updates for next RC

	* unix/tkUnixDefault.h: Changed "Black" to "#000000" and "White" to
	"#ffffff" to work around the (broken?) X servers that do not accept
	those color names. [Bug 917433]

2006-03-28  Jeff Hobbs  <[email protected]>

	* unix/tcl.m4, win/tcl.m4: []-quote AC_DEFUN functions.

2006-03-26  Vince Darley  <[email protected]>

	* generic/tkText.c:
	* tests/text.test: Fix for elaborations of [Bug 1414171] for '$text
	dump -command <script>' where script deletes large portions of the
	text widget, or even destroys the widget.

2006-03-28  Daniel Steffen  <[email protected]>

	* macosx/Wish.xcode/default.pbxuser:    add '-singleproc 1' cli arg to
	* macosx/Wish.xcodeproj/default.pbxuser: tktest to ease test debugging.

	* macosx/Wish.xcode/project.pbxproj:    removed $prefix/share from
	* macosx/Wish.xcodeproj/project.pbxproj: TCL_PACKAGE_PATH as per change
	to tcl/unix/configure.in of 2006-03-13.

	* macosx/tkMacOSXDraw.c:   sync whitespace & minor changes with
	* macosx/tkMacOSXEvent.h:  core-8-4-branch.
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXNotify.c:

2006-03-27  Don Porter  <[email protected]>

	* changes:	Updates for next RC

2006-03-27  Benjamin Riefenstahl  <[email protected]>

	* generic/tkTextDisp.c (MeasureChars): Fix calculations of start and
	end of string. [Bugs 1325998, 1456157]

2006-03-27  Donal K. Fellows  <[email protected]>

	* generic/tkImgGIF.c (FileReadGIF): Stop crashes when the first GIF
	frame does not define the overall size of the image. [Bug 1458234]

2006-03-26  Vince Darley  <[email protected]>

	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextBTree.c:
	* tests/text.test: Fix for [Bug 1414171] for '$text dump -command
	<script>' where 'script' actually modifies the widget during the
	process.

2006-03-25  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDraw.c (TkMacOSXSetUpCGContext):
	* macosx/tkMacOSXFont.c (TkMacOSXQuarzStartDraw, TkMacOSXQuarzEndDraw):
	performance improvements, sync similar code, formatting & whitespace.

2006-03-24  Daniel Steffen  <[email protected]>

	* generic/tkTextDisp.c:   Moved #ifdef MAC_OSX_TK code added by
	* macosx/tkMacOSXColor.c: [Patch 638966] into platform specific files.
	* macosx/tkMacOSXInt.h:

	* macosx/tkMacOSX.h:       Cleaned up & rationalized order of
	* macosx/tkMacOSXBitmap.c:  #includes of tk and carbon headers.
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXClipboard.c:
	* macosx/tkMacOSXColor.c:
	* macosx/tkMacOSXConfig.c:
	* macosx/tkMacOSXCursor.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXRegion.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXWm.h:
	* macosx/tkMacOSXXStubs.c:

2006-03-23  Reinhard Max  <[email protected]>

	* unix/tkUnixRFont.c (TkpMeasureCharsInContext): Copied over from
	tkUnixFont.c to fix compiling with --enable-xft .

	* unix/tk.spec: Cleaned up and completed. An RPM can now be built from
	the tk source distribution with "rpmbuild -tb <tarball>".

2006-03-23  Don Porter  <[email protected]>

	* tests/textDisp.test: Updated expected error messages to match the
	standardized formats established on 2005-11-17. [Bug 1370296]

2006-03-22  Don Porter  <[email protected]>

	* changes:	Updates for next RC

2006-03-21  Daniel Steffen  <[email protected]>

	* generic/tkFont.c:       implementation of ATSUI text rendering
	* generic/tkInt.h:      in TkAqua provided by Benjamin
	* generic/tkTextDisp.c:     Riefenstahl. [Patch 638966]
	* library/demos/unicodeout.tcl:
	* macosx/tkMacOSXFont.h (new file):
	* macosx/tkMacOSXFont.c:
	* tests/font.test:
	* unix/tkUnixFont.c:
	* win/tkWinFont.c:

	* generic/tkFont.c:       moved MODULE_SCOPE declarations of font
	* generic/tkFont.h:       helper procs into header files.
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXFont.h:
	* macosx/tkMacOSXMenubutton.c:

	* macosx/Wish.xcode/project.pbxproj:    add new tkMacOSXFont.h file,
	* macosx/Wish.xcodeproj/project.pbxproj: turn off dead code stripping
	as it interferes with -sectcreate (rdar://4486223).

	* macosx/Wish.xcode/default.pbxuser:    add TCLLIBPATH=/Library/Tcl
	* macosx/Wish.xcodeproj/default.pbxuser: env var setting to tktest.

	* unix/configure.in: fix detection of symbols build when enabling
	TkAqua debug code; filter nm output of libtclstub better to avoid
	error on intel macs. [Bug 1415789]
	* unix/configure: autoconf-2.59

2006-03-20  Don Porter  <[email protected]>

	* generic/tkConsole.c:	Added exit handler to clean up the interp where
	the console window lives. Also added code to handle multiple calls to
	Tk_CreateConsoleWindow so that the console channels connect to the last
	console window opened, in compatibility with the previous
	implementation.

2006-03-18  Vince Darley  <[email protected]>

	* generic/tkText.c: Fix for undo/modified status of text widgets when
	empty strings are inserted and undone.

2006-03-17  Pat Thoyts  <[email protected]>

	* library/clrpick.tcl:   Avoid using abbreviated sub-commands in core
	* library/palette.tcl:   scripts as this can cause problems with
	* library/scale.tcl:    mega-widget libraries like snit.
	* library/scrlbar.tcl:	 [Bug 1451587]
	* library/tkfbox.tcl:
	* library/xmfbox.tcl:

2006-03-16  Don Porter  <[email protected]>

	* generic/tkConsole.c:	Substantial rewrite of [console] support.
	* generic/tkInt.h:	Included Obj-ification of the [console] and
	[consoleinterp] commands, and reworking of all the supporting data
	structures for cleaner sharing and lifetime management especially in
	multi-threaded configurations.

2006-03-16  Donal K. Fellows  <[email protected]>

	* library/msgs/pt.msg: Messages for Portuguese (strictly just for
	Brazilian Portuguese, but they'll do until we get other Portuguese
	speakers localize) from Ricardo Jorge <[email protected]> and Silas
	Justiano <[email protected]>. Many thanks! [Bug 1405069]

	* generic/tkImgPhoto.c (ImgPhotoCmd, Tk_PhotoPutBlock)
	(Tk_PhotoPutZoomedBlock): Added hack to detect copying of a photo with
	a simple alpha channel and skip calling ToggleComplexAlphaIfNeeded.
	This should speed up many photo-to-photo copies, keeping the cost of
	the alpha channel down.

2006-03-15  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Try
	to squelch performance issue with code that writes to large images by
	single pixels. Masses of thanks to George Staplin for helping to trace
	this down to the COMPLEX_ALPHA flag handling code. [Bug 1409140]

2006-03-13  Don Porter  <[email protected]>

	* tests/scrollbar.test: Corrected several broken calls to [testmetrics]
	that were crashing the test suite.

	* tests/constraints.tcl:     Added notAqua constraint to canvPs-3.1
	* tests/canvPs.test:      to stop test suite crash on Mac OSX.
					[Bug 1088807]

	* generic/tkCmds.c:		Purged remaining references to errno,
	* macosx/tkMacOSXPort.h:	and errno.h. Standardized the logic
	* macosx/tkMacOSXWm.c:		for using header files from the compat
	* macosx/tkMacOSXWm.h:		directory. Thanks Joe English for the
	* unix/tkUnixPort.h:		patch. [Patch 1445404]

2006-03-08  Don Porter	<[email protected]>

	* unix/Makefile.in: Update `make dist` to copy the image files needed
	by the test suite into the source distro. This was overlooked in the
	2005-10-12 commit.

	* changes:	Update in prep. for 8.5a4 release.

2006-03-07  Joe English  <[email protected]>

	* unix/tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD, as per the other
	*BSD variants. [Bug 1334613]
	* unix/configure: Regenerated.

2006-03-07  Donal K. Fellows  <[email protected]>

	* doc/canvas.n: Added note that stipples are not well-supported on
	non-X11 platforms. [Bug 220787] It's not a great solution, but it does
	indicate the state of affairs that has existed for years anyway; not
	much modern software uses stipples anyway.

2006-03-02  Jeff Hobbs  <[email protected]>

	* macosx/tkMacOSXDraw.c (TkPutImage): Fix endian issue on OS X x86
	displaying images. Bitmap images still have a black/white reversal
	issue, appears to be a general OS X issue (as seen in frogger demo).

2006-02-27  Donal K. Fellows  <[email protected]>

	* generic/tkBitmap.c (Tk_GetBitmapFromData): Improve thread-safety.
	[Bug 470322]

	* generic/tkImgBmap.c (ImgBmapConfigureInstance): Force creation of new
	Pixmaps before deletion of old ones to prevent stupid caching problems.
	[Bug 480862]

2006-02-09  Daniel Steffen  <[email protected]>

	* generic/tk.decls:       fix signature of TkMacOSXInvalClipRgns
	* generic/tkPlatDecls.h:     to use Tk_Window instead of internal
	* macosx/tkMacOSXSubwindows.c:  type TkWindow (which led to any include
	* macosx/tkMacOSXWindowEvent.c: of public header tkMacOSX.h requiring
	* macosx/tkMacOSXWm.c:     prior include of tkInt.h).

	* generic/tk.h:      move TkAqua specific REDO_KEYSYM_LOOKUP define
	* macosx/tkMacOSXPort.h: out of tk.h into platform header.

2006-01-31  Donal K. Fellows  <[email protected]>

	* library/bgerror.tcl (::tk::dialog::error::bgerror): Finish the
	internationalization of the error dialog. [Bug 1409264]

2006-01-25  Don Porter	<[email protected]>

	* library/bgerror.tcl: Updates to use Tcl 8.4 features. [Patch 1237759]
	* library/choosedir.tcl:
	* library/comdlg.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/focus.tcl:
	* library/msgbox.tcl:
	* library/palette.tcl:
	* library/tk.tcl:
	* library/tkfbox.tcl:
	* library/xmfbox.tcl:

2006-01-23  Daniel Steffen  <[email protected]>

	* unix/configure:   minor fix to Darwin specific code removing
	* unix/configure.in: 64bit flags from CFLAGS for Tk build.

2006-01-20  Joe English  <[email protected]>

	* generic/tkEvent.c, unix/tkUnixEvent.c: XIM fixes [See 905830, patch
	tk84-xim-fixes.patch], and revert 2005-12-05 patch disabling XIM when
	SCIM in use, and make sure all X events get passed to XFilterEvent,
	including those without a corresponding Tk window.

2006-01-13  Anton Kovalenko  <[email protected]>

	* generic/tkUndo.c (TkUndoSetDepth): Don't free TkUndoSubAtoms for
	separator entries that are deleted: there is some unpredictable garbage
	instead of subatoms.

	Free both 'apply' and 'revert' action chains for non-separator entries.

2006-01-12  Donal K. Fellows  <[email protected]>

	TIP #260 IMPLEMENTATION

	* generic/tkCanvText.c (TextItem, CreateText, DisplayCanvText):
	* doc/canvas.n:		Code, docs and tests to implement an -underline
	* tests/canvText.test:	option for canvases' text items.

2006-01-11  Peter Spjuth  <[email protected]>

	* generic/tkGrid.c: Removed a lingering error message from TIP#147
	implementation.

2006-01-10  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDebug.c: add TkMacOSXGetNamedDebugSymbol() function
	* macosx/tkMacOSXDebug.h: that finds unexported symbols in loaded
	libraries by manually walking their symbol table; only to be used for
	debugging purposes, may break unexpectedly in the future. Needed to get
	access to private_extern internal debugging functions in HIToolbox.

	* macosx/tkMacOSXCarbonEvents.c: fix debug event tracing on Tiger.
	* macosx/tkMacOSXMenu.c: add debug menu printing during reconfigure.
	* macosx/tkMacOSXInit.c: conditionalize 64bit-unsafe dyld code.
	* macosx/GNUmakefile: add 'wish8.x' symlink to SYMROOT.

	* macosx/Wish.xcode/project.pbxproj:    fix copy to tktest resource
	* macosx/Wish.xcodeproj/project.pbxproj: fork when zerolinked.

	* macosx/Wish.xcode/default.pbxuser:    add widget demo as argument to
	* macosx/Wish.xcodeproj/default.pbxuser: executables (on by default).

	* unix/configure:   add caching, use AC_CACHE_CHECK instead of
	* unix/configure.in: AC_CACHE_VAL where possible, consistent message
	* unix/tcl.m4:  quoting, sync relevant tclconfig/tcl.m4 changes
	and gratuitous formatting differences, fix SC_CONFIG_MANPAGES with
	default argument, Darwin improvements to SC_LOAD_*CONFIG.

2005-12-28  Donal K. Fellows  <[email protected]>

	* generic/tkUndo.c (TkUndoSetDepth): Apply [Patch 1391939] from Ludwig
	Callewaert to fix [Bug 1380427].

2005-12-14  Daniel Steffen  <[email protected]>

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

2005-12-13  Daniel Steffen  <[email protected]>

	* library/demos/cscroll.tcl: add MouseWheel bindings for aqua.

	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent)
	(GenerateMouseWheelEvent): add support for kEventMouseScroll events
	(smooth mouse wheel scrolling from mighty mouse or scrolling trackpad)
	by handling kEventMouseWheelMoved on application target as well as on
	dispatcher, in order to pick up synthesized MouseWheel events from
	HIObject handler (c.f. QA1453); add support for horizontal scrolling
	events by generating MouseWheel XEvent with Shift modifier.

2005-12-12  Jeff Hobbs  <[email protected]>

	* unix/tcl.m4, unix/configure: Fix sh quoting error reported in
	bash-3.1+ [Bug 1377619] (schafer)

2005-12-09  Mo DeJong  <[email protected]>

	* win/tkWinWm.c (WinSetIcon): Don't check result of SetClassLong() or
	SetClassLongPtr() since it was generating an incorrect error and the
	MSDN docs indicate that the result need not be checked.

2005-12-09  Mo DeJong  <[email protected]>

	* win/configure: Regen.
	* win/tcl.m4 (SC_CONFIG_CFLAGS): Define MACHINE for gcc builds. The
	lack of a definition of this variable in the manifest file was causing
	a runtime error in wish built with gcc.

2005-12-09  Daniel Steffen  <[email protected]>

	* generic/tkInt.decls:  Move all platform test sources from tk lib into
	* generic/tkTest.c:  tktest directly, removes requirement to export
	* macosx/tkMacOSXTest.c:TkplatformtestInit from internal stubs table.
	* unix/Makefile.in:
	* win/Makefile.in:
	* win/makefile.vc:
	* win/tkWinTest.c:

	* generic/tkIntPlatDecls.h:
	* generic/tkStubInit.c: regen.

2005-12-08  Jeff Hobbs  <[email protected]>

	* win/tcl.m4:    Add build support for Windows-x64 builds.
	* win/configure:    --enable-64bit now accepts =amd64|ia64 for
	* win/Makefile.in:  Windows 64-bit build variants (default: amd64)
	* win/makefile.vc:  [Bug 1369597]
	(TKOBJS): add tkWinTest.obj to regular Tk obj for TkplatformtestInit

	* win/configure.in: Add CE build support (some C code fixes needed)
	* win/wish.exe.manifest.in (new):    manifest must map in MACHINE and
	* win/rc/wish.exe.manifest (removed): VERSION to be correct.
	* unix/Makefile.in: fix dist target for manifest dir change

	* generic/tkTextTag.c (TkTextTagCmd): use correct arraySize for peered
	text widgets in [$text tag names]. [Bugs 1375069, 1374935]

2005-12-08  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDraw.c:  Remove inclusion of tclInt.h and use of tcl
	* macosx/tkMacOSXFont.c:  internals wherever possible in tk/macosx, the
	* macosx/tkMacOSXInit.c:  only remaining tcl internals in TkAqua are
	* macosx/tkMacOSXNotify.c:TclServiceIdle() in tkMacOSXScrlbr.c and
	* macosx/tkMacOSXScrlbr.c:Tcl_Get/SetStartupScript() in tkMacOSXInit.c
				  [RFE 1336531]

	* macosx/tkMacOSXInt.h: sync comments with core-8-4-branch.

2005-12-07  Jeff Hobbs  <[email protected]>

	* unix/tkUnixEvent.c (OpenIM): remove extraneous const

2005-12-06  Donal K. Fellows  <[email protected]>

	* doc/ConfigWidg.3 (TK_CONFIG_OPTION_SPECIFIED): Mentioned that the
	flag is deprecated because it is not thread-safe.

2005-12-05  Reinhard Max  <[email protected]>

	* unix/tkUnixEvent.c (OpenIM): Added a workaround to allow at least
	ASCII and the Compose key when typing into text and entry widgets on a
	system that uses SCIM. This has to be taken out again once the SCIM
	problems have been fixed.

2005-12-01  Daniel Steffen  <[email protected]>

	* unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
	* unix/configure: regen.

2005-11-30  Jeff Hobbs  <[email protected]>

	* win/tkWinWm.c (WmAttributesCmd): set (no)topmost window aspect before
	rewrapping. [Bug 1086049]

	* macosx/tkMacOSXXStubs.c (TkpOpenDisplay, TkMacOSXDisplayChanged):
	* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessApplicationEvent):
	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXEvent.h: Trap kEventAppAvailableWindowBoundsChanged
	* macosx/tkMacOSXInt.h:   event to watch for change in display size and
	adjust internal state appropriately.

	* doc/checkbutton.n: fix -selectcolor docs. [Bug 1083838]

	* generic/tkImgGIF.c: cast calls to blockOut

	* win/Makefile.in: place TCL_BIN_DIR first in PATH for targets to get
	Tcl built dll first.
	Add tkWinTest.obj to tk84.dll to handle some needed test functions
	being defined in stubs (TkplatformtestInit).

	* tests/scrollbar.test (6.22): fix rounding-error sensitive test

2005-11-29  Jeff Hobbs  <[email protected]>

	* library/console.tcl (::tk::ConsoleInit): improve work-around to avoid
	'% ' from tclMain.c. [Bug 1252259]

2005-11-27  Daniel Steffen  <[email protected]>

	* unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
	add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
	configure (flag can't be present twice, so can't be in both CFLAGS and
	LDFLAGS during configure), don't use -prebind when deploying on 10.4,
	define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
	(SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
	autoconf macros. Sync with tcl/unix/tcl.m4.

	* unix/configure.in: fix obsolete autoconf macros, sync gratuitous
	formatting/ordering differences with tcl/unix/configure.in.

	* unix/Makefile.in: add CFLAGS to wish/tktest link to make executable
	linking the same as during configure (needed to avoid loosing any
	linker relevant flags in CFLAGS, in particular flags that can't be in
	LDFLAGS). Avoid concurrent linking of wish and compiling of
	tkTestInit.o during parallel make, fix dependencies and flags for
	building tkMacOSXInit.o
	(checkstubs, checkexports): dependency and Darwin fixes
	(dist): add new macosx files.

	* macosx/tkMacOSXEvent.c (TkMacOSXProcessEvent):
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent):
	* macosx/tkMacOSXCarbonEvents.c: install standard application event
	handler, add & call functions to start and stop carbon even timer that
	runs the tcl event loop periodically during a nested carbon event loop
	in the toolbox (e.g. during menutracking) to ensure tcl timers etc.
	continue to fire, register app event handler for menu tracking and HI
	command carbon events, move menu event handling to new handlers for
	those carbon events, no longer register for/handle appleevent carbon
	event (now dealt with by standard application event handler), event
	debugging code dynamically acquires carbon event debugging functions to
	allow use on Tiger where they are no longer exported from HIToolbox.

	* macosx/tkMacOSXFont.c (TkMacOSXUseAntialiasedText):
	* macosx/tkMacOSXKeyEvent.c (GetKeyboardLayout):
	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents):
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXInt.h: abstract common code to dynamically acquire
	address of a named symbol (from a loaded dynamic library) into new
	function TkMacOSXGetNamedSymbol() and macro TkMacOSXInitNamedSymbol.

	* macosx/tkMacOSXMenu.c (TkpNewMenu):
	* macosx/tkMacOSXMenubutton.c (MenuButtonInitControl):
	* macosx/tkMacOSXMenus.c (TkMacOSXHandleMenuSelect): switch to modern
	utf-8 aware menu manager API, remove obsolete code, add error handling.

	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c: define OSX 10.3 or later only constants
	if necessary to allow compilation on OSX 10.2

	* macosx/tkMacOSXWm.c (UpdateSizeHints): remove code that is never
	executed.

	* xlib/xgc.c (XCreateGC): sync with core-8-4-branch change.

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

	* generic/tkInt.h: clarify fat compile comment.

	* macosx/Wish.pbproj/default.pbxuser (new):
	* macosx/Wish.pbproj/jingham.pbxuser:
	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/default.pbxuser:
	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.xcodeproj/default.pbxuser (new):
	* macosx/Wish.xcodeproj/project.pbxproj (new): new/updated projects for
	Xcode 2.2 on 10.4, Xcode 1.5 on 10.3 & ProjectBuilder on 10.2, with
	native tktest targets and support for universal (fat) compiles.

	* macosx/Tk-Info.plist (removed):
	* macosx/Wish-Info.plist (removed):
	* macosx/buildTkConfig.tcl (removed): remove obsolete build files.

	* macosx/README: clarification/cleanup, document new Xcode projects and
	universal (fat) builds via CFLAGS (i.e. ppc and i386 at the same time).

	* unix/Makefile.in:
	* unix/aclocal.m4:
	* unix/configure.in:
	* macosx/configure.ac (new): add support for inclusion of
	unix/configure.in by macosx/configure.ac, allows generation of a
	config headers enabled configure script in macosx (required by Xcode
	projects).

	* macosx/GNUmakefile: rename from Makefile to avoid overwriting by
	configure run in tk/macosx, add support for reusing configure cache,
	build target fixes.

	* generic/tk3d.h:
	* generic/tkButton.h:
	* generic/tkCanvas.c:
	* generic/tkCanvas.h:
	* generic/tkColor.h:
	* generic/tkEntry.h:
	* generic/tkFileFilter.h:
	* generic/tkFont.c:
	* generic/tkFont.h:
	* generic/tkImage.c:
	* generic/tkImgPhoto.c:
	* generic/tkInt.h:
	* generic/tkMenu.c:
	* generic/tkMenu.h:
	* generic/tkMenubutton.h:
	* generic/tkScale.h:
	* generic/tkScrollbar.h:
	* generic/tkSelect.h:
	* generic/tkStubInit.c:
	* generic/tkStubLib.c:
	* generic/tkText.h:
	* generic/tkUndo.h:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXSend.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnixButton.c:
	* unix/tkUnixMenu.c:
	* xlib/xgc.c: ensure externally visible symbols not contained in stubs
	table are declared as MODULE_SCOPE (or as static if not used outside of
	own source file), #ifdef out a few Xlib and aqua functions that are
	never called. These changes allow 'make checkstubs' to complete without
	error on Darwin with gcc 4.

	* macosx/tkMacOSXTest.c:
	* macosx/tkMacOSXPort.h:
	* win/tkWinTest.c:
	* generic/tkInt.decls: add functions needed by tktest to internal stubs
	table, correct signature of TkMacOSXHandleMenuSelect, add XSync to aqua
	Xlib stubs.

	* unix/tkUnixSend.c:
	* generic/tkText.c:
	* generic/tkTest.c: #ifdef unix only declarations.
	(TestmetricsCmd): unify win and mac implementation.
	(TestsendCmd): move to tkUnixSend.c to avoid access to global var.
	(TesttextCmd): move to tkText.c to avoid having to put all the internal
	text functions it uses into the stubs table.

	* generic/tkTextDisp.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXXStubs.c: fix gcc 4 warnings.

	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXScrlbr.c: sync with core-8-4-branch.

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c:
	* unix/configure:
	* unix/tkConfig.h.in: regen.

2005-11-22  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl: Remove all references to data(curItem), as it is
	no longer used. [Bug 600313]
	(::tk::IconList_CurSelection): Renamed for clarity.

	* doc/GetFont.3: Revert previous fix; a NULL interp is now legal.
	* generic/tkFont.c (ParseFontNameObj, GetAttributeInfoObj): Allow these
	functions to work with a NULL interp by making them check when
	generating error messages. [Bug 1151523]

	* library/tkfbox.tcl (::tk::dialog::file::): Correct the quoting of the
	script used in variable traces so that widget names with spaces in will
	work. [Bug 1335485]

2005-11-16  Vince Darley  <[email protected]>

	* doc/text.n: clarify left to right interpretation of index modifiers,
	including the fact that validation occurs after each step. [Bug
	1357575]

2005-11-15  Joe English  <[email protected]>

	* unix/tkUnixWm.c, tests/unixWm.test, doc/wm.n: Support for [wm
	attributes] on X11. [TIP#231, Patch 1062022]

2005-11-14  Joe English  <[email protected]>

	* library/bgerror.tcl: Truncate error messages at 45 characters
	instead of 30. [Bug 1224235]

2005-11-14  Donal K. Fellows  <[email protected]>

	* generic/tkSelect.c (TkSelDefaultSelection): Test select-9.5
	highlighted further brokenness in this function.

2005-11-13  Donal K. Fellows  <[email protected]>

	* unix/tkUnixSelect.c (SelCvtToX): Arrange for the parsing code to use
	Tcl's list parsing code, another simplification that enables testing
	of the [Bug 1353414] fix.

	* unix/tkUnixSelect.c (SelCvtFromX): Generate string forms of the
	advanced selection types in a Tcl_DString. This makes fixing [Bug
	1353414] trivial, and simplifies the code at the same time.
	* tests/select.test (select-9.5): Added test for [Bug 1353414]

2005-11-10  Donal K. Fellows  <[email protected]>

	* generic/tkBind.c (ChangeScreen):		More DString fixes from
	* generic/tkTextWind.c (EmbWinLayoutProc):	[Bug 1353022]
	* win/tkWinMenu.c (SetDefaults):

	* win/tkWinDialog.c (ConvertExternalFilename): Factored out the
	encoding conversion and de-backslash-ing code that is used in many
	places in this file.
	(GetFileNameW, GetFileNameA, ChooseDirectoryValidateProc): Make sure
	that data is freed correctly and that certain (hopefully impossible)
	failure modes won't cause crashes. [Bug 1353022]

2005-11-06  Pat Thoyts  <[email protected]>

	* unix/tcl.m4:  Fix SHLIB_LD_LIBS for building tclkit on OpenBSD.
	* unix/configure: regenerated

2005-10-31  Vince Darley  <[email protected]>

	* generic/tkText.c
	* tests/textDisp.test: fix and test for [Bug 1333951] in '.text count
	-displaylines'.

2005-10-18  Don Porter	<[email protected]>

	* generic/tkMain.c: Rewrote code that sets the ::argv value to be sure
	conversion from the system encoding is complete before any processing
	sensitive to list-special characters is done. [Bug 1328926]

2005-10-17  Jeff Hobbs  <[email protected]>

	* macosx/tkMacOSXScrlbr.c (UpdateControlValues): check geomMgrPtr is
	valid before checking type

2005-10-15  Jeff Hobbs  <[email protected]>

	* library/menu.tcl (::tk::MenuUnpost): remove leftover ] from string
	equal mods of 2005-07-25. (sowadsky)

2005-10-14  Pat Thoyts  <[email protected]>

	* win/tkWinSend.c:  Avoid using tcl internal headers and fix to
	* win/tkWinSendCom.h: correctly link on all types of build (was
	* win/tkWinSendCom.c: broken in static,msvcrt builds).

2005-10-12  Donal K. Fellows  <[email protected]>

	* tests/canvPs.test, tests/canvPsBmap.tcl, tests/canvPsImg.tcl:
	* tests/imgPhoto.test, tests/menu.test: Arrange for the test suite to
	only ever refer to images in the same directory as the tests. This
	makes it possible to package the test suite itself as a starkit. Thanks
	to David Zolli for suggesting this.

2005-10-10  Jeff Hobbs  <[email protected]>

	* generic/tkConfig.c (Tk_DeleteOptionTable, Tk_CreateOptionTable):
	properly alloc/delete one more option. [Bug 1319720] (melbardis)

	* macosx/tkMacOSXInt.h: Move MODULE_SCOPE defn to tkInt.h and add
	* generic/tkInt.h:    WORDS_BIGENDIAN checks that will work with OS X
	universal binary compiles. (steffen)

	* generic/tkMenu.c (TkSetWindowMenuBar): do not call TkMenuInit if the
	winPtr indicates TK_ALREADY_DEAD. This prevents reinit that creates a
	Tk exit handler after all exit handlers should be called. [Bug 749908,
	1322294]

2005-10-10  Vince Darley  <[email protected]>

	TIP #256 IMPLEMENTATION

	* doc/text.n
	* generic/tkText.c
	* generic/tkText.h
	* generic/tkTextBTree.c
	* generic/tkTextDisp.c
	* generic/tkTextImage.c
	* generic/tkTextIndex.c
	* generic/tkTextMark.c
	* generic/tkTextTag.c
	* generic/tkTextWind.c
	* macosx/tkMacOSXDefault.h
	* tests/text.test
	* tests/textDisp.test
	* unix/tkUnixDefault.h
	* win/tkWinDefault.h: Implementation of TIP#256, adding a new text
	widget configuration option '-tabstyle', with new tests and
	documentation.

	Also a fix for [Bug 1281228] (documentation and full implementation of
	-strictlimits), and [Bug 1288677] (corrected elide behaviour), again
	with more tests.

2005-10-04  Jeff Hobbs  <[email protected]>

	* library/dialog.tcl (::tk_dialog): add tkwait visibility before grab.
	[Bug 1216775]

	* win/tkWinDialog.c (ChooseDirectoryValidateProc): reset stored path to
	"" if it doesn't exist and -mustexist is true. [Bug 1309218] Remove
	old-style dir chooser (no longer used).

	* macosx/tkMacOSXInt.h: add MODULE_SCOPE definition check for extension
	writers that access private headers on OS X and don't define it in
	configure.

2005-09-28  Don Porter	<[email protected]>

	* unix/tkUnixPort.h:	Disabled inclusion of the private Tcl header
	* win/tkWinPort.h:	file tclInt.h. Tk ought to have a tiny and
	shrinking number of calls of private Tcl routines. Each Tk source file
	doing this should follow the convention in the macosx port and have its
	own #include "tclInt.h".

	* generic/tkEvent.c:	Disabled calls to private Tcl routine
	TclInExit(). See comment in TkCreateExitHandler() for full rationale.

2005-09-21  Donal K. Fellows  <[email protected]>

	* generic/tkEvent.c (TkCreateThreadExitHandler, TkFinalizeThread)
	(TkDeleteThreadExitHandler): New internal API (from Joe Mistachkin) to
	allow Tk to finalize itself correctly in a multi-threaded
	environment. [Bug 749908]

2005-09-14  Donal K. Fellows  <[email protected]>

	* generic/tkOldConfig.c (GetCachedSpecs): Split out the code to
	manipulate the cached writable specs so that it can be reused from all
	the public Tk_Configure* functions.
	(Tk_ConfigureInfo, Tk_ConfigureWidget, Tk_ConfigureValue): Use the
	factored out code everywhere, so we always manipulate the cache
	correctly. [Bug 1288128]

2005-09-13  Don Porter	<[email protected]>

	* win/winMain.c (WishPanic): Replaced TCL_VARARGS* macros with direct
	use of stdarg.h conventions.

2005-09-11  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): check if
	process is in front on MouseDown, otherwise request process activation
	from BringWindowForward() via new isFrontProcess param.

	* macosx/tkMacOSXCarbonEvents.c (TkMacOSXInitCarbonEvents): register
	our event handler on the dispatcher target for all carbon events of
	interest to TkAqua; this replaces event processing directly from the
	event queue and thus allows to capture events that are syntesized by
	Carbon and sent directly to the dispatcher and not to the event queue.

	* macosx/tkMacOSXEvent.c: remove TkMacOSXCountAndProcessMacEvents(),
	rename ReceiveAndProcessEvent() to TkMacOSXReceiveAndProcessEvent().
	(TkMacOSXReceiveAndProcessEvent): remove tk event processing before
	sending events to the dispatcher, all events of interest are now
	processed in our dispatcher target event handler.

	* macosx/tkMacOSXNotify.c (CarbonEventsCheckProc): dispatch events
	directly via TkMacOSXReceiveAndProcessEvent(), but dispatch no more
	than four carbon events at one time to avoid starving other event
	sources.

	* macosx/tkMacOSXEvent.c: formatting cleanup, move XSync() to XStubs,
	* macosx/tkMacOSXEvent.h: removed obsolete kEventClassWish handling.
	* macosx/tkMacOSXXStubs.c

	* macosx/tkMacOSXEvent.h: declare macosx internal procs as MODULE_SCOPE
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWindowEvent.c:

	* macosx/tkMacOSXButton.c: conditionalize all debug message printing to
	* macosx/tkMacOSXCursor.c: stderr via TK_MAC_DEBUG define.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXEvent.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.c:

	* unix/configure.in: define TK_MAC_DEBUG on aqua when symbols enabled.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* library/listbox.tcl: synced aqua MouseWheel bindings with
	* library/scrlbar.tcl: core-8-4-branch.
	* library/text.tcl:

	* xlib/xcolors.c: fixed warning

2005-08-25  Daniel Steffen  <[email protected]>

	* unix/Makefile.in (html): reverted/amended changes of 2005-08-23 that
	broke TkAqua 'make install'; added BUILD_HTML_FLAGS optional var like
	in tcl/unix/Makefile.in.

2005-08-24  Donal K. Fellows  <[email protected]>

	* tests/text.test (text-8.18): Fix punctuation of error message to
	match good practice (actual message already fixed). [Bug 1267484]

2005-08-23  Jeff Hobbs  <[email protected]>

	* macosx/tkMacOSXDialog.c: make dialogs ignore -initialfile "" and
	-initialdir "" instead of error.

2005-08-23  Mo DeJong  <[email protected]>

	* win/tkWin32Dll.c (DllMain): Replace old asm SEH approach with Kenny's
	new SEH implementation. [Tcl Bug 1235544]

2005-08-23  Mo DeJong  <[email protected]>

	* unix/Makefile.in: Subst BUILD_TCLSH and TCL_EXE.
	* unix/configure: Regen.
	* unix/configure.in: Update minimum autoconf version to 2.59. Invoke
	SC_PROG_TCLSH and SC_BUILD_TCLSH.
	* unix/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH):
	* win/Makefile.in: Subst BUILD_TCLSH and TCL_EXE.
	* win/configure: Regen.
	* win/configure.in: Update minimum autoconf version to 2.59. Invoke
	SC_BUILD_TCLSH.
	* win/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH): Split confused search
	for tclsh on PATH and build and install locations into two macros.
	SC_PROG_TCLSH searches just the PATH. SC_BUILD_TCLSH determines the
	name of the tclsh executable in the Tcl build directory. [Tcl Bug
	1160114] [Tcl Patch 1244153]

2005-08-22  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c: fix warnings.

2005-08-20  Joe Mistachkin  <[email protected]>

	* win/tkWinX.c: Fixed bad cast. [Bug 1216006]

2005-08-18  Donal K. Fellows  <[email protected]>

	* doc/GetFont.3: Reworded to reflect the truth. [Bug 1151523]

2005-08-16 George Peter Staplin  <[email protected]>

	* doc/CrtItemType.3 prototypes were lacking [] after objv. Thus the man
	page was wrong about the actual prototypes. This was verified by
	studying tkCanvBmap.c.

2005-08-13 Chengye Mao  <[email protected]>

	* generic/tkOldConfig.c: Fixed [Bug 1258604]. This bug was introduced
	into the modfied Tk_ConfigureWidget. It failed to properly handle the
	specFlags' bit TK_CONFIG_OPTION_SPECIFIED.

2005-08-12  Donal K. Fellows  <[email protected]>

	* generic/tkOldConfig.c (Tk_ConfigureWidget): Stop storing per-thread
	data in global data structures. Store it in per-interpreter data (i.e.
	per-thread data) instead. [Bug 749908]

2005-08-10  Donal K. Fellows  <[email protected]>

	* generic/tkFrame.c (CreateFrame) and others: Don't use size_t when
	working with Tcl_GetStringFromObj because it is not 64-bit clean. [Bug
	1252702]

2005-08-04  Vince Darley  <[email protected]>

	* doc/text.n: Clarify behaviour of tab stops (as per [Bug 1247835])

2005-08-09  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXCarbonEvents.c (AppEventHandlerProc): handle carbon
	events sent directly to application event target via the general
	TkMacOSXProcessEvent() in the same way as events posted to the event
	loop. Moved existing app event handlers to tkMacOSXWindowEvent.c.
	(TkMacOSXInitCarbonEvents): register our application event handler for
	kEventWindowExpanded events to deal with uncollapsing from the dock.

	* macosx/tkMacOSXEvent.h: made TkMacOSXProcessEvent() non-static, added
	* macosx/tkMacOSXEvent.c: new interp field to TkMacOSXEvent struct for
				  use by app event handler.

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): retrieve
	current window, partCode, modifiers and local cursor position from
	carbon mouse event if possible. Use new static GenerateButtonEvent()
	taking a MouseEventData struct instead of TkGenerateButtonEvent() to
	avoid recomputing already known values. Move process activation on
	MouseDown into BringWindowForward() to allow clicking on window
	titlebar widgets without activating process. Move code dealing with
	clicks in window titelbar into separate function
	HandleWindowTitlebarMouseDown() to avoid code duplication. Avoid
	repeated calls to TkMacOSXGetXWindow() by storing result in
	MouseEventData struct.
	(TkMacOSXButtonKeyState, XQueryPointer): try to get button and modifier
	state from currently processed carbon event (to avoid unnecessary IPC
	with the window server), otherwise use modern carbon API to get this
	info instead of Button() and GetKeys(); only retrieve info caller asks
	for (via non-NULL ptr passed to XQueryPointer).
	(ButtonModifiers2State): new static function converting carbon button
	and modifier state into tk state, allows detection of more than 3 mouse
	buttons (tk supports up to 5) and of NumLock and Fn modifier keys
	(NumLock is mapped to Mod3 and Fn to Mod4).

	* macosx/tkMacOSXWindowEvent.c (TkMacOSXProcessApplicationEvent):
	handle kEventWindowExpanded event to deal with window uncollapsing from
	the dock by generating tk Map event, handle kEventAppHidden and
	kEventAppShown events (moved here from tkMacOSXCarbonEvents.c).

	* macosx/tkMacOSXSubwindows.c (XUnmapWindow): only hide window when it
	is not iconified to avoid window flashing on collapse.

	* macosx/tkMacOSXWm.c: replaced Tk_DoWhenIdle() by Tcl_DoWhenIdle().
	(TkMacOSXZoomToplevel): remove call to TrackBox(), now done in
	HandleWindowTitlebarMouseDown() in tkMacOSXMouseEvent.c.
	(TkpWmSetState): avoid window flashing on collapse by unmapping after
	calling CollapseWindow(); only uncollapse window if it is collapsed.

	* generic/tkInt.decls: changed TkMacOSXZoomToplevel() signature.
	* generic/tkIntPlatDecls.h:

	* macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): only call
	GetMenuItemCommandID() on KeyDown or KeyRepeat events.

	* macosx/tkMacOSXMenu.c (ReconfigureMacintoshMenu): remove call to
	obsolete AppendResMenu() API.

	* macosx/tkMacOSXKeyEvent.c: replaced all direct uses of expensive
	* macosx/tkMacOSXMenu.c:    GetMouse() and TkMacOSXButtonKeyState()
	* macosx/tkMacOSXMenus.c:   APIs by calls to XQueryPointer()
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXScale.c:
	* macosx/tkMacOSXScrlbr.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c:   replaced use of FrontNonFloatingWindow()
	* macosx/tkMacOSXKeyEvent.c: by ActiveNonFloatingWindow() as
	* macosx/tkMacOSXMenu.c:    recommended by Carbon docs.
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:

	* macosx/tkMacOSXDialog.c: fixed warnings
	* macosx/tkMacOSXTest.c:

	* macosx/tkMacOSXCarbonEvents.c: added CVS Id line to file header.
	* macosx/tkMacOSXDebug.c:
	* macosx/tkMacOSXDebug.h:
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXEvent.h:
	* macosx/tkMacOSXKeyEvent.c:
	* macosx/tkMacOSXMouseEvent.c:
	* macosx/tkMacOSXWindowEvent.c:
	* macosx/tkMacOSXWm.h:

	* macosx/tkMacOSXInt.h: declare macosx internal procs as MODULE_SCOPE.
	* macosx/tkMacOSXCarbonEvents.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXWindowEvent.c

	* library/bgerror.tcl: sync with core-8-4-branch changes of 2005-07-28.
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXMouseEvent.c:

	* generic/tkFrame.c:   sync with core-8-4-branch changes of 2005-07-27.
	* generic/tkIntDecls.h:
	* generic/tkStubInit.c:
	* generic/tkFrame.c:
	* win/tkWinDraw.c:
	* unix/tkUnixDraw.c:
	* macosx/tkMacOSXDraw.c:
	* macosx/tkMacOSXInt.h:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXSubwindows.c:

	* macosx/tkMacOSXButton.c: sync with core-8-4-branch.
	* macosx/tkMacOSXEntry.c:
	* macosx/tkMacOSXScale.c:

	* library/demos/menu.tcl: removed errant '}'.

2005-08-04  Donal K. Fellows  <[email protected]>

	* doc/clipboard.n: Add example demonstrating custom types of clipboard
	data.

2005-07-25  Donal K. Fellows  <[email protected]>

	* library/*.tcl: Updated to use more 8.4 and 8.5 features as part of
	resolving [Patch 1237759].

2005-07-22  Mo DeJong  <[email protected]>

	* win/tkWinX.c: Define _WIN32_WINNT with NT SP 3 data to fix compiler
	error because SendInput was not defined. The new msys_mingw7 release is
	now needed to compile the HEAD with mingw gcc. [Bug 1210712]

2005-07-21  Jeff Hobbs	<[email protected]>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): corrected if
	expression error (use of = instead of ==).

2005-07-18  Vince Darley  <[email protected]>

	* generic/tkTextMark.c: fix to segfault in "mark prev"
	* tests/textIndex.test: [Bug 1240221]

	* tests/textWind.test: make test more robust to avoid infinite loop

2005-07-06  Jeff Hobbs	<[email protected]>

	* doc/getOpenFile.n: correct -multiple docs (takes boolean)

2005-07-05  Don Porter	<[email protected]>

	* unix/Makefile.in:	Purged use of TCLTESTARGS. [RFE 1161550]

2005-06-23  Daniel Steffen  <[email protected]>

	* generic/tkConsole.c (TkConsolePrint): prevent potential NULL deref.

	* macosx/tkMacOSXDefault.h: change ENTRY_BORDER defaults to from 5 to 2
	to make default entry widgets in TkAqua look like in other aqua apps
	(and have same border dimensions as other platforms). [Bug 1176610]

2005-06-21  Donal K. Fellows  <[email protected]>

	* doc/GetBitmap.3: Fix silly error in SYNOPSIS. [Bug 1224983]

2005-06-19  Donal K. Fellows  <[email protected]>

	* generic/tkImgGIF.c: Cleanse all static (i.e. non-thread-safe) data
	at a miniscule performance hit.

2005-06-18  Daniel Steffen  <[email protected]>

	* macosx/Makefile: for X11 build, add -X11 suffix to unversioned wish
	symbolic link.

	* unix/tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
	ensure we can always relocate binaries with install_name_tool.

	* unix/configure: autoconf-2.59

2005-06-07  Donal K. Fellows  <[email protected]>

	Bump patchlevel to a4 to distinguish from a3 release.

2005-06-04  Jeff Hobbs	<[email protected]>

	*** 8.5a3 TAGGED FOR RELEASE ***

2005-06-02  Jim Ingham	<[email protected]>

	* generic/tkEvent.c (InvokeFocusHandlers): On Mac OS X the scrollwheel
	events are sent to the window under the mouse, not to the focus window

	Another patch from M. Kirkham.

	* macosx/tkMacOSXScrlbr.c (ThumbActionProc, ScrollBarBindProc): Record
	the first mouse down point, and compute differences from that, rather
	than getting the mouse down each time through the loop. The old method
	would get fooled if you moved the mouse less than a text line height in
	the text widget. [Bug 1083728]

2005-06-03  Daniel Steffen  <[email protected]>

	* macosx/Makefile: fixed 'embedded' target.

2005-06-02  Reinhard Max  <[email protected]>

	* unix/tkUnix.c (Tk_GetUserInactiveTime): Improvements to get it
	working on Solaris, and panic if we run out of memory.
	* unix/configure.in: Rework the searching for Xss, to make it work on
	Solaris and provide more useful output. Use AC_HELP_STRING where
	appropriate.
	* unix/tcl.m4: synced from Tcl.
	* unix/configure: regenerated with autoconf 2.59.

2005-06-01  Jeff Hobbs	<[email protected]>

	* win/tkWinInt.h: added private decls of Tk_GetEmbeddedMenuHWND,
	Tk_GetMenuHWND, TkWinCleanupContainerList, and TkpWmGetState to that
	are used across source files.

	* win/tkWinX.c (Tk_ResetUserInactiveTime): cast to squelch compiler
	warning.

2005-05-31  Reinhard Max  <[email protected]>

	* doc/Inactive.3 (new file): C level API documentationn for
	TIP#245 (Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime).
	* tests/tk.test: Added tests for the TIP#245 implementation.

2005-05-30  Jeff Hobbs	<[email protected]>

	* generic/tkPanedWindow.c, tests/panedwindow.test: batch of fixes to
	panedwindow from Daniel South. Improved auto-size to fit internal
	windows, fixed sash placement at edge of pane, fixed calculation of
	stretch amount for internal windows. [Bug 1124198, 1161543, 1054117,
	1010941, 795869, 690169, 1192323]

	* generic/tkMenu.c (MenuCmd): create event handler earlier to ensure
	proper destruction of menu through DestroyNotify. [Bug 1159367]

	* library/console.tcl (::tk::ConsoleInit): print out first prompt and
	swallow the extra "% " that comes once from Tcl on Windows.

2005-05-29  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXFont.c: use Tcl_Panic instead of panic.

	* unix/configure.in: added description of HAVE_XSS for autoheader.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in: autoheader-2.59

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/project.pbxproj: added missing FRAMEWORK defines
	introduced with configure/make based build.

	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXNotify.c: fixed warnings.

	* generic/tkDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c: ran missing 'make genstubs' for TIP245 changes
	to tk.decls

	* macosx/tkMacOSXXStubs.c (Tk_ResetUserInactiveTime): use symbolic
	constant argument in call to UpdateSystemActivity();

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Wish.xcode/project.pbxproj:
	* unix/configure.in: added/corrected linking to IOKit.framework for
	TIP245.

	* unix/configure.in: skip X11 configure checks when building tk_aqua.
	* unix/configure: autoconf-2.59

2005-05-28  Donal K. Fellows  <[email protected]>

	TIP #245 IMPLEMENTATION from Reinhard Max <[email protected]>

	* doc/tk.n: Documentation of [tk inactivity].
	* win/tkWinX.c (Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime):
	* unix/tkUnix.c (Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime):
	* macosx/tkMacOSXXStubs.c:	Implementations of the core API for
	(Tk_GetUserInactiveTime):	determining how long as user's left
	(Tk_ResetUserInactiveTime):	her machine alone.
	* unix/configure.in: Test for XScreenSaver support.
	* generic/tkCmds.c (Tk_TkObjCmd): Implementation of [tk inactivity].

2005-05-27  Todd Helfter  <[email protected]>

	* library/menu.tcl: correct the sticky behavior of menus posted by
	tk_popup so that they "stick" after the initial <ButtonRelease>
	following the post, that is not over an active menu entry.

2005-05-26  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXInit.c (TkpInit): fixed resource file extraction from
	__tk_rsrc section to work with non-prebound .dylib and .bundle.

	* macosx/Makefile: corrected EMBEDDED_BUILD check, use separate Tcl and
	Tk version vars to properly support tk/x11 framework version
	overriding, rewrite tkConfig.sh when overriding tk version, corrected
	Wish.app symlink in tk build dir.

	* unix/configure.in: corrected framework finalization to softlink stub
	library to Versions/8.x subdir instead of Versions/Current.
	* unix/configure: autoconf-2.59

2005-05-25  Jeff Hobbs	<[email protected]>

	* unix/Makefile.in (install-libraries): protect possible empty list in
	for with list= trick for older shells.

2005-05-23  Jeff Hobbs	<[email protected]>

	* generic/tkFileFilter.c (FreeGlobPatterns): s/null/NULL/

2005-05-24  Daniel Steffen  <[email protected]>

	* generic/tkTest.c: disable commands not available on TkAqua.

	* macosx/Makefile:
	* macosx/README:
	* macosx/Tk-Info.plist.in (new file):
	* macosx/Wish-Info.plist.in (new file):
	* unix/Makefile.in:
	* unix/configure.in:
	* unix/tcl.m4:
	* unix/tkUnixInit.c: moved all Darwin framework and TkAqua build
	support from macosx/Wish.pbproj and macosx/Makefile into the standard
	unix configure/make buildsystem, the project and macosx/Makefile are no
	longer required to build Tk.framework and/or TkAqua. TkAqua is now
	enabled by the --enable-aqua configure option, and static and
	non-framework builds of TkAqua are now available via the standard
	configure switches. Tk/X11 can also be built as a framework. The
	macosx/Makefile now wraps the unix buildsystem and no longer uses the
	projects, embedded builds are still only available via this Makefile,
	but for other builds it is not longer required (but its current
	functionality is still available for backwards compatibility). The
	projects currently do not call through to the Makefile to build (unlike
	Tcl.pbproj) so project builds may differ from makefile builds. Due to
	issues with spaces in pathnames, 'Wish Shell.app' has been renamed to
	'Wish.app', the macosx/Makefile installs backwards compatibility
	symlinks for the old name.
	* macosx/tkMacOSXInit.c (TkpInit): added support for Tk resource file
	in non-framework and static builds: the resource file is copied into a
	__tk_rsrc MachO section of the library or executable at link time and
	extracted into a temporary location at initialization.
	* unix/configure: autoconf-2.59
	* unix/tkConfig.h.in (new file): autoheader-2.59

	* macosx/Wish.pbproj/project.pbxproj:
	* macosx/Tk-Info.plist:
	* macosx/Wish-Info.plist:
	* macosx/tkAboutDlg.r: updated copyright years to 2005.

2005-05-22  Donal K. Fellows  <[email protected]>

	* generic/tkFileFilter.c (TkGetFileFilters): Add all filters, not just
	the first one. [Bug 1206133]

2005-05-15  Jim Ingham	<[email protected]>

	Fixes from Michael Kirkham:

	* macosx/tkMacOSXMenu.c (TkpConfigureMenuEntry): Thinko in clearing the
	ENTRY_ACCEL_MASK before re-parsing it. [Bug 1012852]

	* macosx/tkMacOSXScrlbr.c (UpdateControlValues): Don't set the control
	value BEFORE setting the min and max or the control manager will reset
	it for you. [Bug 1202181]

	* macosx/tkMacOSXXStubs.c (TkMacOSXXGetPixel, TkMacOSXXPutPixel):
	Restore the port to what it was before putting we were called. [Bug
	1202223]

2005-05-14  Jim Ingham  <[email protected]>

	* macosx/tkMacOSXScrlbr.c (ThumbActionProc): Missing Tcl_Release.

2005-05-14  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXNotify.c: introduction of new tcl notifier based on
	CFRunLoop allows replacement of the custom TkAqua notifier by a
	standard tcl event source. Removes requirement of threaded tcl core
	for TkAqua, allows to stub-link TkAqua against Tcl by removing use of
	the unstubbed TclInitNotifier & TclFinalizeNotifier. [Tcl Patch
	1202052]

	* macosx/Wish.xcode/project.pbxproj:
	* macosx/Wish.pbproj/project.pbxproj: stub-link TkAqua: build with
	USE_TCL_STUBS and link against libtclstub instead of Tcl.framework,
	unexport libtclstub symbols from Tk to avoid duplicate symbol warnings
	when linking with both Tcl and Tk, fixes for gcc4.0 warnings.

	* macosx/Wish.xcode/project.pbxproj: sync with Wish.pbproj changes
	since 2004-11-19.
	NOTE: to use this project, need to uncomment the tclConfig.h settings
	at the top of tcl/unix/configure.in, autoconf and rebuild tcl !

	* macosx/tkMacOSXBitmap.c:
	* macosx/tkMacOSXButton.c:
	* macosx/tkMacOSXDialog.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXHLEvents.c:
	* macosx/tkMacOSXInit.c:
	* macosx/tkMacOSXKeyboard.c:
	* macosx/tkMacOSXMenu.c:
	* macosx/tkMacOSXMenubutton.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c: fixed gcc 4.0 warnings.

	* unix/tcl.m4: sync with tcl
	* unix/configure: autoconf-2.59

2005-05-10  Vince Darley  <[email protected]>

	* library/text.tcl: test and fix to TextPrevPara to avoid infinite loop
	* tests/textIndex.test: at start of widget. [Bug 1191895]

	* generic/tkTextDisp.c: better synchronisation between explicit and
	implicit pixel line-height calculations. [Bug 1186558]

2005-05-10  Don Porter	<[email protected]>

	* generic/tkTextDisp.c (GetXView): Improved numerical precision of
	calculation of [.t xview] return values.
	* tests/textDisp.test: Match greater precisions of [.t xview] and
	[.t yview] values in tests.

2005-05-06  Jeff Hobbs	<[email protected]>

	* unix/configure: regen
	* unix/configure.in: Add AC_C_BIGENDIAN check and pkg-config xft checks
	to extend xft search.
	* unix/tcl.m4: Correct Solaris 10 (5.10) check and add support for
	x86_64 Solaris cc builds.

2005-04-28  Donal K. Fellows  <[email protected]>

	* macosx/tkMacOSXNotify.c (TkMacOSXWaitForEvent): Fix for typo in
	waitTime computation. [Bug 1191097]
	(AlertNotifier): Factor out the core of the notifier alerting code.

2005-04-25  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXNotify.c: sync with tclUnixNotfy.c changes since
	2004-06-22, added compile time check for threaded tcl core, removed
	unthreaded code paths as they are never used anyway, fixed
	TkMacOSXAlertNotifier() implementation.

	* unix/Makefile.in: added TCL_STUB_LIB_FILE, needed for unexporting of
	symbols from libtclstub to avoid duplicate symbol warnings.

	* unix/tcl.m4 (Darwin): added configure checks for recently added
	linker flags -single_module and -search_paths_first to allow building
	with older tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD
	and not just T{CL,K}_SHLIB_LD_EXTRAS, added unexporting from Tk of
	symbols from libtclstub to avoid duplicate symbol warnings, added
	PLAT_SRCS definition for Mac OS X, defined MODULE_SCOPE to
	__private_extern__.
	(SC_MISSING_POSIX_HEADERS): added caching of dirent.h check.

	* unix/configure: autoconf-2.59

2005-04-22  George Peter Staplin  <[email protected]>

	* doc/FontId.3: I fixed a typo. "linespace" was used instead of
	"ascent". I also added a .PP before the paragraph to make the
	formatting look better for the ascent paragraph.

2003-04-18  Joe English	 <[email protected]>

	* unix/tkUnixRFont.c(Tk_MeasureChars): Use Tcl_UtfToUnichar() for lax
	UTF-8 parsing instead of strict parsing with FcUtf8ToUcs4()
	[fix/workaround for Bug 1185640]

2003-04-18  Vince Darley  <[email protected]>

	* library/text.tcl
	* doc/text.n: corrected 'Home' and 'End' and Control-a/e handling to
	work with display lines. This was an ommission of the previous tip155
	patch. Clarified the documentation on this point.

2005-04-14  Jeff Hobbs	<[email protected]>

	* unix/tkUnixFont.c (FontMapLoadPage): reorder char[] decls to avoid
	possible segv. Minimal fix for [Bug 1122671]

2005-04-12  Jeff Hobbs	<[email protected]>

	* library/tkfbox.tcl (::tk::dialog::file::): fix typeMenuLab ref. Add
	undoc'd ::tk::dialog::file::showHiddenBtn var (default 0) that will add
	a "Show Hidden" checkbutton to tk_get*File and tk_chooseDirectory if
	set to true.
	* library/choosedir.tcl (::tk::dialog::file::chooseDir::): fix
	cancelBtn ref, add hiddenBtn ref for "Show Hidden" button.

2005-04-09  Daniel Steffen  <[email protected]>

	* macosx/README: updated requirements for OS & developer tool versions
	+ other small fixes/cleanup.

	* macosx/tkMacOSXEntry.c (ComputeIncDecParameters): manually define
	constants present only in 10.3 headers so that we can build on 10.2.

	* macosx/Wish.pbproj/project.pbxproj: fixed absolute path to tkEntry.h
	that confused 10.2 PBX.

	* unix/tcl.m4 (Darwin): added -single_module linker flag to
	TCL_SHLIB_LD_EXTRAS and TK_SHLIB_LD_EXTRAS.
	* unix/configure: autoconf-2.59

2005-04-07  Mo DeJong  <[email protected]>

	* macosx/tkMacOSXWm.c (TkWmStackorderToplevelWrapperMap,
	(TkWmStackorderToplevel):
	* unix/tkUnixWm.c (TkWmStackorderToplevelWrapperMap,
	(TkWmStackorderToplevel):
	* win/tkWinWm.c (TkWmStackorderToplevelWrapperMap,
	(TkWmStackorderToplevel):
	Fix panic in wm stackorder when a toplevel is created on another
	display. The code now ignores toplevels that have a display that does
	not match the display of the parent window. [Bug 1152809]

2005-04-06  Donal K. Fellows  <[email protected]>

	* doc/wm.n, doc/winfo.n, doc/tk.n, doc/send.n, doc/selection.n:
	* doc/radiobutton.n, doc/photo.n, doc/options.n, doc/menu.n:
	* doc/listbox.n, doc/getOpenFile.n, doc/font.n, doc/event.n:
	* doc/entry.n, doc/clipboard.n, doc/checkbutton.n, doc/canvas.n:
	* doc/button.n, doc/bind.n, doc/TextLayout.3, doc/MeasureChar.3:
	* doc/GetRelief.3, doc/GetPixels.3, doc/GetJustify.3, doc/GetFont.3:
	* doc/GetCursor.3, doc/GetColor.3, doc/GetBitmap.3, doc/GetAnchor.3:
	* doc/FontId.3, doc/CrtWindow.3, doc/CrtImgType.3, doc/ConfigWidg.3:
	* doc/3DBorder.3: Purge old .VS/.VE macro instances.

2005-04-04  Don Porter	<[email protected]>

	* library/comdlg.tcl: Added Macintosh file type validation to
	[::tk::FDGetFileTypes]. [Bug 1083878] (Thanks, Vince Darley)

2005-04-04  Vince Darley  <[email protected]>

	* generic/tkText.c:
	* tests/text.test: fix to elide searching problems [Bug 1174269] and
	disappearing cursor with insertofftime 0. [Bug 1169429]

2005-04-03  Peter Spjuth  <[email protected]>

	* tests/grid.test:
	* generic/tkGrid.c: Fixed bug in geometry calculations for widgets that
	span multiple columns/row. Bug was introduced in 8.5a1 when fixing
	792387. [Bug 1175092]

2005-03-29  Jeff Hobbs	<[email protected]>

	* win/tcl.m4, win/configure: do not require cygpath in macros to allow
	msys alone as an alternative.

2005-03-27  Vince Darley  <[email protected]>

	* tests/textDisp.test: added test for fix of 2005-03-15.

2005-03-24  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXEntry.c (TkpDrawEntryBorderAndFocus): Dopey bug - do
	not reset the width for entry widgets - we didn't change it for them.

2005-03-23  Jim Ingham	<[email protected]>

	These changes allow us to draw the Entry and Spinbox widget with a
	native look and feel on Mac OS X.

	* generic/tkEntry.h: New file, extracting the definitions of Entry and
	Spinbox.
	* generic/tkEntry.c (DisplayEntry): Call out to TkpDrawSpinboxButtons
	and TkpDrawEntryBorderAndFocus. Also provide default implementations
	for X11 & Win.
	* macosx/tkMacOSXEntry.c: New file, implements the entry & focus and
	spinbox button drawing.
	* tkMacOSXDefaults.h: Change the Mac OS X defaults so they fit the
	native widget shapes.

	This is cleanup thanks to Neil Madden <[email protected]>.

	* macosx/tkMacOSXWm.c (TkMacOSXWinStyle) New function.
	(TkUnsupported1ObjCmd): New function, replaces the un-objectified
	version of the command.
	* generic/tkInt.h: Swap TkUnsupported1Cmd for TkUnsupported1ObjCmd.
	* generic/tkWindow.c (): Ditto.

	This adds a "-notify" flag to "wm attributes" that will bounce the
	dock icon on Mac OS X.	This is from Revar Desmera <[email protected]>

	* macosx/tkMacOSXWm.c (WmAttrGetNotifyStatus, WmAttrSetNotifyStatus):
	New functions.
	(WmAttributesCmd): Add the -notify.
	* doc/wm.n: Document -notify.

2005-03-19  Donal K. Fellows  <[email protected]>

	* generic/tkConsole.c (Tk_CreateConsoleWindow,TkConsolePrint): Rewrite
	so that TkConsolePrint cannot become detached from the console when the
	[console] command is renamed. [Bug 1016385]

2005-03-15  Vince Darley  <[email protected]>

	* generic/tkTextDisp.c: fix for [Bug 1143776] in adjusting displayed
	lines when running into the bottom of the window.

2005-03-14  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXScrlbr.c (ThumbActionProc): No need to use "update
	idletasks" here, TclServiceIdle will do as well and it is simpler.

	These changes implement a change on the Mac OS X side. When we unmap a
	window we mark all its children as unmapped (not following toplevels.
	But we preserve whether they had been mapped before, and when the
	parent is remapped, we remap the children as well. [Bug 940117]

	* macosx/tkMacOSXInt.h: Added TK_MAPPED_IN_PARENT
	* macosx/tkMacOSXSubwindows.c (FixMappingFlags): New function.
	(XMapWindow): Call FixMappingFlags.
	(XUnMapWindow): Ditto.

	* macosx/tkMacOSXSubwindows.c (XMoveResizeWindow): Update the xOff &
	yOff data in the Macdrawable even if the native window hasn't been
	created yet. [Bug 700305]
	(XMoveWindow): Ditto.
	(XResizeWindow): Ditto.

2005-03-15  Pat Thoyts	<[email protected]>

	* unix/tcl.m4:	  Updated the OpenBSD configuration and regenerated the
	* unix/configure: configure script.

2005-03-14  Donal K. Fellows  <[email protected]>

	* generic/tkEvent.c (InvokeClientMessageHandlers): Ensure that client
	messages are handled correctly. Thanks to George Petasis for tracking
	this down. [Bug 1162356]

2005-03-11  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXButton.c (TkpDisplayButton): Set the port to the
	Button window's port BEFORE you set the clip, otherwise you are setting
	the clip on the wrong window!
	Also, a little cleanup - move x & y into the branches where they are
	used, and don't compute the TextAnchor if we are using the native
	button text, since we aren't going to use it.
	(TkMacOSXDrawControl): Call ShowControl & SetControlVisibility in a
	more logical order.

	* tkMacOSXInt.h: Add TkMacOSXGenerateFocusEvent.
	* tkMacOSXSubwindows.c (XDestroyWindow): We don't get Activate events
	for the remaining windows when a Floating window is destroyed. This can
	cause the focus to disappear. So catch this case when the window is
	being destroyed and move the focus here.

	* tkMacOSXWindowEvent.c (TkMacOSXGenerateFocusEvent): Make this public
	(used to be GenerateFocusEvent) since we need it here and in
	tkMacOSXSubwindows.c. Then change the name everywhere it is used. [Bug
	1124237]

2005-03-10  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): In the
	inDrag section, set the GrafPort to the drag window's GrafPort before
	doing LocalToGlobal. [Bug 1160025]

2005-03-09  Jim Ingham	<[email protected]>

	* macosx/tkMacOSXInit.c (TkpInit): Check to see if the environment
	variable XCNOSTDIN is set, and if so, close stdin & stdout. This is
	necessary to make remote debugging under Xcode work properly.

2005-03-08  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (WinSetIcon): fix GCLP_ICONSM -> GCLP_HICONSM.

	* win/makefile.vc: clarify necessary defined vars that can come from
	MSVC or the Platform SDK.

2005-02-28  Jeff Hobbs	<[email protected]>

	* win/tkWinX.c (GenerateXEvent): correct %A translation on MouseWheel.
	[Bug 1118340]

2005-02-24  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSX.h: fixed incorrect inclusion of internal header.
	* macosx/tkMacOSXNotify.c: corrected included headers.

2005-02-22  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXDialog.c (Tk_GetSaveFileObjCmd, NavServicesGetFile):
	fixed encoding problems with -initialfile & -filetypes and corrected
	potential buffer overrun with -initialdir/-initialfile. [Bug 1146057]

2005-02-16  Mo DeJong  <[email protected]>

	TIP#223 IMPLEMENTATION

	* doc/wm.n: Add documentation for -fullscreen attribute.
	* tests/winWm.test: Add -fullscreen to wm attribute usage message.
	* tests/wm.test: Add -fullscreen to wm attribute usage message. Add
	-fullscreen attribute test cases for Windows.
	* win/tkWinWm.c (WmInfo, UpdateWrapper, TkpWmSetFullScreen)
	(WmAttributesCmd, UpdateGeometryInfo):
	Implement TIP 223 [wm attributes -fullscreen].

2005-02-14  Vince Darley  <[email protected]>

	* generic/tkText.c:
	* generic/tkText.h:
	* generic/tkTextDisp.c:
	* generic/tkTextIndex.c:
	* generic/tkTextBTree.c:
	* doc/text.n:
	* tests/textDisp.test:
	* tests/textIndex.test: fix of longstanding elide problem when eliding
	a newline without eliding the entire logical line. [Bug 443848]

2005-02-14  Jeff Hobbs	<[email protected]>

	* doc/options.n: note -cursor {} behavior. [Bug 965618]

2005-02-14  Donal K. Fellows  <[email protected]>

	* tests/all.tcl: Add a [package require Tk] so that a missing display
	causes an early failure and keeps the error trace short. Issue observed
	in [FRQ 11122147], even though that's unrelated.

2005-02-11  Jeff Hobbs	<[email protected]>

	* library/panedwindow.tcl (::tk::panedwindow::Cursor): check window
	existence on delayed call. [Bug 949792]

	* doc/text.n: note 'image' key in 'dump' command. [Bug 1115907]

	* win/tkWinWm.c (TkWinGetIcon): fix toplevel retrieval for determining
	icon ref (potential crash). [Bug 1105738]

	* generic/tkCanvBmap.c (ConfigureBitmap, ComputeBitmapBbox): Fixed
	possible crash with disabled bmap and bbox handling [Bug 1119460]
	(BitmapToPostscript): made aware of various bitmap types

	* unix/Makefile.in: remove SHLIB_LD_FLAGS (only for AIX, inlined into
	* unix/tcl.m4:	    SHLIB_LD). Combine AIX-* and AIX-5 branches in
	* unix/configure:   SC_CONFIG_CFLAGS. Correct gcc builds for AIX-4+ and
	HP-UX-11. autoconf-2.59 gen'd.

2005-02-09  Donal K. Fellows  <[email protected]>

	* tests/wm.test: Convert to use more tcltest2 features.

2005-02-07  Donal K. Fellows  <[email protected]>

	* generic/tkCanvas.c (CanvasWidgetCmd): Fix stupid mistake in variable
	names, reported by Andreas Leitgeb.

2005-02-03  Donal K. Fellows  <[email protected]>

	* generic/tkCanvas.c (GetStaticUids): New function to manage the
	thread-specific data detailing the list of all uids in a thread.
	(typeList): Protect this (the other piece of global data) with a mutex.
	[Bug 1114977]

2005-01-31  Jeff Hobbs	<[email protected]>

	* unix/tcl.m4, unix/configure: add solaris-64 gcc build support. [Bug
	1021871]

2005-01-31  Donal K. Fellows  <[email protected]>

	* generic/tkImgPhoto.c (PhotoFormatThreadExitProc): Made the comments
	in the code more relevant to the function they were documenting! [Bug
	1110553]

	* library/msgs/es_ES.msg: Added more localization for Spanish Spanish.
	[Bug 1111213]

2005-01-25  Daniel Steffen  <[email protected]>

	* macosx/tkMacOSXInit.c (TkpInit): set tcl_interactive to 1 to show
	console at startup instead of directly calling [console show].

	* unix/tcl.m4 (Darwin): fixed bug with static build linking to dynamic
	library in /usr/lib etc instead of linking to static library earlier in
	search path. [Tcl Bug 956908]
	Removed obsolete references to Rhapsody.
	* unix/configure: autoconf-2.57

2005-01-18  Donal K. Fellows  <[email protected]>

	* library/demos/menu.tcl: Reworked to make dialogs children of the
	demo widget so that they are properly visible. Issue reported by Keith
	Nash <[email protected]>

2005-01-13  Donal K. Fellows  <[email protected]>

	* library/tkfbox.tcl (IconList_Selection, IconList_Create):
	(IconList_Arrange): Assorted tk_getOpenFile fixes. [part of Bug 600313]
	(IconList_ShiftMotion1): Also fix shift-drag.

2005-01-12  Don Porter	<[email protected]>

	* unix/tcl.m4:		Sync'ed to Tcl's copy.
	* unix/configure:	autoconf-2.57

2005-01-12  Donal K. Fellows  <[email protected]>

	* doc/event.n: Added section on predefined virtual events. [Bug 608115]

2005-01-11  Vince Darley  <[email protected]>

	* generic/tkTextDisp.c: fix to scrollbar height calculations of text
	widgets containing a single very long (wrapped) line. This fixes at
	least part of [Bug 1093631].

2005-01-11  Donal K. Fellows  <[email protected]>

	* generic/tkObj.c (TkParsePadAmount):
	* generic/tkPack.c: Moved function to tkObj.c and rewrote so that it
	takes advantage of Tcl_Objs properly and cannot leave objects in an
	inconsistent state. [Bug 1098779]

2005-01-10  Joe English	 <[email protected]>

	* unix/Makefile.in, unix/configure.in, unix/tkConfig.sh.in:
	Remove ${DBGX}, ${TK_DBGX} from Tk build system. [Patch 1081595]
	* unix/tcl.m4: re-synced with tcl/unix/tcl.m4
	* unix/configure: Regenerated.

2005-01-07  Donal K. Fellows  <[email protected]>

	* generic/tkWindow.c (GetScreen): Make sure the result is reset on all
	error paths to stop strange errors. [Bug 697915]

2005-01-05  Donal K. Fellows  <[email protected]>

	* doc/loadTk.n, doc/toplevel.n: Convert to other form of emacs mode
	control comment to prevent problems with old versions of man. [Bug
	1085127]

2005-01-03  Jeff Hobbs	<[email protected]>

	* win/tkWinWm.c (TkWinWmCleanup): clean up layered window class. This
	caused crash in reinit of Tk (as seen in plugin).

	******************************************************************
	*** CHANGELOG ENTRIES FOR 2004 AND 2003 IN "ChangeLog.2004"    ***
	*** CHANGELOG ENTRIES FOR 2002 AND EARLIER IN "ChangeLog.2002" ***
	******************************************************************
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to README.md.

1
2
3
4
5
6
7













8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# README:  Tk

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

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















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

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

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

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


|




>
>
>
>
>
>
>
>
>
>
>
>
>







|





|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# README:  Tk

This is the **Tk 9.0b2** 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=core-8-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Linux%22+branch%3Acore-8-branch)
[![Build Status](https://github.com/tcltk/tk/workflows/Windows/badge.svg?branch=core-8-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Windows%22+branch%3Acore-8-branch)
[![Build Status](https://github.com/tcltk/tk/workflows/macOS/badge.svg?branch=core-8-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22macOS%22+branch%3Acore-8-branch)
9.0 (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 9.0 Web page](https://www.tcl-lang.org/software/tcltk/9.0.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
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
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

Deleted changes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
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
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
This file summarizes all changes made to Tk since version 1.0 was
released on March 13, 1991.  Changes that aren't backward compatible
are marked specially.

3/16/91 (bug fix) Modified tkWindow.c to remove Tk's Tcl commands from
the interpreter when the main window is deleted (otherwise there will
be dangling pointers to the non-existent window).

3/16/91 (bug fix) Modified tkColor.c not to free black or white colors:
some X servers get upset at this.

3/18/91 (bug fix) Modified tkShare.c to fix bug causing "DeleteGroup
couldn't find group on shareList" panic.

3/18/91 (bug fix) Several changes to tkListbox.c and tkScrollbar.c to
handle listboxes (and scrollbars) with zero total entries in them.

3/22/91 (bug fix) Fixed a few ='s in tkListbox.c that should be ==.

3/22/91 (bug fix) Fixed error in main.c that caused BadWindow errors
in some cases where wish scripts invoke "destroy .".

3/23/91 (new feature) Added Tk_CancelIdleCall to remove Tk_DoWhenIdle
handler.

3/23/91 (bug fix and new feature) Added -name option to main.c, made
it more clever about choosing name (was always using the name "wish"
on most Unix systems).

3/23/91 (new feature) Added TK_CONFIG_STRING option to Tk_ConfigureWidget,
used it to malloc strings for various widget options that used to be
Tk_Uid's (e.g. button text, message strings, etc.).  Eliminates core
leaks when values change in continuous non-repeating fashion.

3/29/91 (new feature) Added Tk_Preserve, Tk_Release, and
Tk_EventuallyFree procedures to help manage widget records and avoid
premature memory free-ing.

4/4/91 (bug fix) Fixed problem in tkWm.c where top-level window geometry
wasn't tracking correctly when wm-induced size change also changed window
position (e.g. menus wouldn't be displayed at the right places).

4/5/91 (new feature) Added "invoke" option to widget command for buttons,
check buttons, and radio buttons.

4/5/91 (new feature) Added "unpack" option to "pack" command.

4/5/91 (bug fix) Changed tkPack.c to use new Tk_Preserve code and be
more careful about window deletions that occur while repacking is in
progress.

4/6/91 (bug fix) Major overhaul of deletion code in all widgets to use
Tk_Preserve and Tk_Release.  Should fix many problems.

4/6/91 (bug fix) Changed "winfo children" to generate correct lists
when child names have embedded spaces.

4/6/91 (new feature) Added "screenheight" and "screenwidth" options to
"winfo".

4/18/91 (bug fix) Binding mechanism didn't correctly handle very long
%-substitutions in commands (e.g. long path names) and caused memory
to be overwritten.  Modified tkBind.c to fix.

---------------------- Release 1.1, 4/18/91 -------------------------

4/19/91 (bug fix) Inconsistent ICCCM handling of coordinates of reparented
windows causes windows to gradually walk south when moved or resized.
Fixed tkWm.c to patch around the problem.

---------------------- Release 1.2, 4/24/91 -------------------------

4/26/91 (new feature) Added -geometry and -display switches to wish.
Also wrote wish manual entry.

5/3/91 (bug fix) Fixed bug in tkListbox.c that caused garbage to appear
at right edge of window when strings were to large to fit in window.

5/3/91 (bug fix) Fixed bug in tkListbox.c where topIndex wasn't getting
updated when elements were deleted:  tended to cause errors in
communication with scrollbars.

5/16/91 (bug fix) Fixed bug in tk3d.c, which caused core dumps when
consecutive points in a polygon were the same (happened with some
configurations of radio buttons, for example).

5/16/91 (bug fix) Fixed main.c to allow stdin to be redirected.

6/1/91 (bug fix) Make sure that pointers are never used after being
freed.

6/15/91 (bug fix) Fixed bug in tkBind.c that caused current binding
values to not always be printed correctly.

6/15/91 (bug fix) Make sure that interpreters are always unregistered
when their main windows are deleted, and make wish delete the main
window before exiting.

8/21/91 (misfeature correction)  Automatically set source of window
position to "user" in "wm geometry" command, unless it has been
explicitly set to "program".

9/5/91 (bug fix) Modified option code to accept '#' as a comment
character in .Xdefaults files, in addition to '!'.

9/10/91 (misfeature correction) Changed binding mechanism so that
numeric %-sequences are output in decimal instead of hex.

9/19/91 (bug fix) Fixed bug in Tk_DoOneEvent(1) where it wasn't
checking files and X connections properly so it missed events.

10/6/91 (new feature) Reorganized tkBind.c to provide generic "binding
table" structure, which can be used to create bindings on items in
canvases as well as windows.

10/6/91 (new feature) Upgraded buttons and menus to use new tracing
code in Tcl 6.0.  Allows radio buttons and check buttons to both set
and clear themselves when associated variable changes.

10/17/91 (bug fix) Fixed 2 bugs in listboxes: accidentally advanced the
selection when new entries were inserted in the listbox after the location
of the selected item(s), and goofed up on redisplay if selected item
was deleted and then selection was immediately lost.

10/27/91 (bug fix) "pack unpack" wasn't telling Tk that it no longer
manages window;  this led to core dumps in some situations.

10/31/91 (reorganization) Renamed manual entries so that they are no
more than 14 characters in length.

10/31/91 (reorganization) Changed tk.h and tkInt.h so that tkInt.h
doesn't needed to be included by tk.h.

11/3/91 (portability improvement) Eliminated use of "class" as a variable
name, since it's a reserved word in C++.

11/7/91 (reorganization) Many changes to upgrade for Tcl 6.1 including
use of Tcl hash tables instead of separate "Hash_" module.  The "lib"
subdirectory is no longer needed in Tk.

---------------------- Release 1.3, 11/7/91 -------------------------

11/24/91 (bug fix) Fixed bug causing occasional errors if existing bindings
are modified (FindSequence in tkBind.c forget to set *maskPtr).

11/24/91 (bug fix) Used wrong hash table in Tk_GetColorByValue.  Could
cause new entries to get created unnecessarily.

12/2/91 (bug fix) Changed "bind" code to put backslashes in front of
special characters (e.g. [ or \) that appear in %-replacements, so that
they can be parsed cleanly.

12/10/91 (bug fix) Manual entries had first lines that caused "man" program
to try weird preprocessor.  Added blank comment lines to fix problem.

1/2/92 (documentation cleanup) Changed manual entries for Tk_GetBitmap
and the like to make it more clear that the argument must be a Tk_Uid
and not a string.

1/2/92 (bug fix) Fixed problem where scrollbars that were very short or
very narrow (too small to hold both arrows) could cause negative values
in calls to XClearArea, which crashed some servers.

1/2/92 (bug fix) Fixed bug in TkMeasureChars occurring when maxChars
is 0.  Occasionally affected things like message window geometry.

1/3/92 (new feature) Added procedures Tk_GetJustify, Tk_GetAnchor,
Tk_GetCapStyle, and Tk_GetJoinStyle, plus support for these things
in Tk_ConfigureWidget.

---------------------- Release 1.4, 1/10/92 -------------------------

1/12/92 (bug fix) TkMenubutton.c wasn't cleaning up mbPtr->varName
properly during menubutton cleanup if an error occurred during
menubutton creation.

1/19/92 (bug fix) Fixed off-by-one bug in tkListbox.c that caused
scrollbars to display a slider that was too large.

2/10/92 (bug fix) Tk_CreateFileHandler didn't correctly handle case
where new mask was specified for existing handler.

2/13/92 (bug fix) Tk_DeleteAllBindings wasn't correctly removing
bindings from the pattern table:  only did the removal for the
first pattern in a pattern list.

2/15/92 (new feature) Added procedures Tk_DefineBitmap and
Tk_SizeOfBitmap.  Tk_GetBitmapFromData is now considered obsolete
and probably shouldn't be used anymore.  Tk_GetBitmapFromData
is now implemented by calling Tk_DefineBitmap and Tk_GetBitmap.

2/15/92 (new feature) Added "curselection" and "select clear" options
to widget command for listboxes.

2/15/92 (new feature) Added Tk_3DBorderColor procedure.

2/17/92 (relaxed limitations) Changed scrollbars so they no longer limit
the slider position to lie within the object's range:  can scroll off the
end of an object, if the object permits it.  Changed listboxes and
entries to explicitly prevent viewing off the ends.  Also relaxed
listbox index checks so that out-of-range indices are automatically
adjust to fit within the listbox range.

2/19/92 (bug fix) tkWindow.c tended to leave half-created windows around
if a new window's name was found to be in use already.  Fixed to clean
them up.

2/22/92 (new feature) Added -anchor, -bitmap, -height, -textvariable,
-width options to labels, buttons, check buttons, menu buttons, and radio
buttons.  This means that (a) size can be controlled better, (b) bitmaps
can be displayed in any buttons, (c) the position of the text within the
button can be controlled, and (d) a button can be made to display the value
of a variable, continuously updating itself.  Also changed -selector option
so that if it's specified as an empty string then no selector is drawn
for the button.

2/22/92 (new feature) Changed menus to support bitmaps in menu entries:
added new -bitmap option for entries.

2/26/92 (bug fix) "after" command, when invoked with just one argument,
called Tk_Sleep rather than registering a timer handler and looping on
Tk_DoOneEvent.  As a result, it caused the application to become non-
responsive to X events during the sleep.  Changed to use a Tk_DoOneEvent
loop so that it is responsive.

2/26/92 (bug fix) Tk's main program didn't map the main window until
after the startup script returned.  Changed to map the window as a
do-when-idle handler, so that scripts can cause the window to be
mapped immediately with a call to "update" or "after".

2/28/92 (bug fix) "wm withdraw" wasn't working if invoked before window
was originally mapped:  window got mapped anyway.  Fixed so that the
window doesn't get mapped as long as it's withdrawn.

2/29/92 (new feature) Can use "focus none" to clear input focus.

2/29/92 (bug fix) Fixed tkEvent.c to generate SubstructureNotify events
properly.  These weren't being generated previously.

2/29/92 (bug fix) Fixed entries so that newline characters can be properly
displayed (as `\x0a').  Had to change interface to TkDisplayChars in order
to do this (added flags argument).

2/29/92 (bug fix) Change Tk not to update size and position of top-level
windows directly during calls like Tk_ResizeWindow.  Instead, wait until
actual event is received.  This makes updates happen at same time as
callbacks.

3/6/92 (bug fix) TkMenubutton.c was dumping core when a menubutton was
pressed at a time when there was no associated menu for the button.

3/6/92 (new feature) Added Tk script library directory with official
Tk initialization file "tk.tcl".  Other procedures used by Tk are in
other files.  Tk procedures and variables all have names starting
with "tk_".  Also added Wish startup script "wish.tcl", which sources
both the Tk and Tcl startup scripts.  This means that things like
auto-loading and abbreviation expansion are now available in wish.
Added new variables tk_library, tk_priv, and tk_version.

3/6/92 (new feature) It's now possible to set bindings for whole
classes by using the class name in the bind command.  For example,
"bind Button <Enter> {puts stdout Hi!}" will cause a message to be
printed whenever any mouse button is entered.  Can also use "all"
to set bindings for all widgets.  Widget-specific bindings override
class bindings which override "all" bindings.

3/6/92 (reorganization) Changed buttons (all flavors) and listboxes to
eliminate all hard-wired behavior.  Instead, default behavior is set
by class bindings in tk.tcl.  Also set up class bindings for menus,
menubuttons, and entries, which previously had no default behavior at
all.  Scrollbars and scales still have hard-wired behavior that can't
be overridden.

3/7/92 (look-and-feel change) Changed listboxes and entries and menus
to use button 2 for scanning instead of button 3.  This is more consistent
with the official Motif use of button 2 for dragging.

3/10/92 (new features) Added more options to "winfo" command:  screencells,
screendepth, screenmmheight, screenmmwidth, and screenvisual.

3/13/92 (bug fix) Event sharing mechanism (tkShare.c) wasn't checking
to see whether window was mapped before sharing events with it.

3/16/92 (bug fix) Tk_SetInternalBorderWidth was passing wrong window to
geometry-management procedures, causing core-dumps when menu buttons
had their border widths changed.

3/16/92 (bug fix) Menus were setting their geometry directory rather
than using Tk_GeometryRequest mechanism.

3/17/92 (new feature) Added -cursor option to all widgets to set the
active cursor for the widget.  Also added TK_CONFIG_ACTIVE_CURSOR
configure type.

3/18/92 (new feature) Implemented generalized screen coordinates to
allow resolution-independent specification in many cases (but pixel-
based coordinates are still OK).  Added Tk_GetScreenMM(),
Tk_GetPixels(), new configure types TK_CONFIG_SCREEN_MM and
TK_CONFIG_PIXELS.  Changed widgets to use this new configure types
wherever possible (a few of the more complex cases still haven't
been taken care of yet).  Added "pixels" and "fpixels" options to
"winfo" command.

3/18/92 (new feature) First cut at canvas widgets is done and part of
the official Tk now.  Canvases display text and structured graphics,
and allow you to bind commands to events related to the text and
graphics.

3/21/92 (new feature) Added new "place" command.  It implements a
new geometry manager that provides fixed placement, rubber-sheet
placement, and combinations of the two.  Eliminated the commands
"move", "resize", and "map" that were provided by main.c but never
officially supported;  the placer provides all of this functionality.

3/23/92 (bug fix) Fixed bug in tkWm.c where top-level windows were
occasionally not being given the right size.  The problem occurred
when a string of resizes happened all in a row (such as deleting all
the windows in an application and then recreating them).

3/23/92 (new feature) Added Tk_CoordsToWindow procedure and
"winfo containing" command.  These may be used to locate the window
containing a given point.

3/28/92 (new feature) Added "-exportselection" option to listboxes,
so that listbox selection need not necessarily be the X selection.

4/12/92 (bug fix) Changed menu buttons to store name of menubutton
in the associated variable, rather than the name of the menu.  This
is necessary in order to allow several menu buttons to share the
same menu.
*** POTENTIAL INCOMPATIBILITY ***

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

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

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

4/18/92 (new feature) Major revision to listboxes.  Can now scroll and
scan in both x and y, plus -exportselection option allows selection not
to be exported.  The "view" widget command has been replaced by "xview"
and "yview", and the "scan" widget command has a new syntax.
*** POTENTIAL INCOMPATIBILITY ***

4/18/92 (new feature) Added -exportselection option to entries, so you
can select whether you want the entry selection to be the X selection
or not.

4/24/92 (new features) Added TK_CONFIG_CUSTOM type to Tk_ConfigureWidget,
plus added new flags TK_CONFIG_NULL_OK, TK_CONFIG_DONT_SET_DEFAULT,
and TK_CONFIG_OPTION_SPECIFIED.  Several other new types, such as
TK_CONFIG_CAP_STYLE, were also added as part of implementing canvases.

4/29/92 (bug fix) Changed "-selector" default for menus to have separate
values for mono and color.

4/30/92 (bug fix) Fixed bug in tkListbox.c where it occasionally generated
bogus scroll commands (last index less than first).

4/30/92 (reorganization) Moved demos directory to "library/demos".

---------------------- Release 2.0, 5/1/92 -------------------------

5/2/92 (bug fix) Fixed problem in tkListbox.c where it was doing too many
redisplays after repeated insertions.  Also reduced number of invocations
of scrollbar commands.

5/7/92 (portability improvement) Changed main.c not to use TK_EXCEPTION
flag;  it isn't needed and it causes problems on some systems.

5/9/92 (bug fix) Plugged core leaks in tkListbox.c and tkBind.c

5/9/92 (bug fix) TkBind.c was accidentally deleting bindings during
attempts to print non-existent bindings.

5/11/92 (bug fix) Maximum name length for applications (name used in
"send" commands) was too short (only 20);  increased to 1000.  Also
fixed bug related to over-long names that caused core dumps.

5/13/92 (bug fix) tkShare.c was using a dangling pointer if a share
group was deleted as a side-effect of a shared event.

5/13/92 (bug fix) Various initialization and core leak problems in
tkGC.c, tkSend.c, tkMenu.c, tkEvent.c, tkCanvas.c, tkCanvPoly.c,
tkCanvLine.c, tkListbox.c, tkEntry.c.

5/13/92 (bug fix) Empty entries could be scanned off the left edge,
displaying a garbage character.

5/13/92 (bug fix) Fixed a few problems with window manager interactions,
such as tendency for windows to spontaneously shrink in size.  By no
means are all of the problems fixed, though.

5/13/92 (performance optimization) Changed Tk_GeometryRequest not to
invoke geometry manager unless requested size has changed.

---------------------- Release 2.1, 5/14/92 -------------------------

5/1/92 (new features) Added flags like TK_IDLE_EVENTS to Tk_DoWhenIdle,
plus added "idletasks" option to "update" command.  Tk_DoWhenIdle arguments
look different now, but the change should be upward-compatible.

5/17/92 (new feature/bug fix) Added support for VisibilityNotify events
to the "bind" command.  For some reason they weren't supported previously.

5/17/92 (new feature) Added "tkwait" command.

5/17/92 (new feature) Added "grab" command.

5/17/92 (new feature) Added "-width" option to messages.  Also changed
messages to use the computed (i.e. desired) line length when displaying,
not the actual width of the window.

5/17/92 (bug fixes) Did some more fiddling with tkWm.c in the hopes
of improving window manager interactions.  Now there won't be more than
one configure request outstanding to the wm at a time.

5/17/92 (bug fix) Arrowheads on canvas lines weren't being translated
or scaled correctly.

5/20/92 (bug fix) Page-mode scrolling didn't work correctly for canvases
(wrong windowUnits was passed to scrollbars).

5/20/92 (bug fix) Changed scrollbars not to lose highlight when pointer
leaves window with button down.  Also changed redisplay to double-buffer
for smoother redraws.

5/21/92 (new feature) Added "gray50" and "gray25" as predefined bitmaps.

5/22/92 (new feature) Buttons can now be disabled using the "-state" and
"-disabledforeground configuration options.  The "activate" and "deactivate"
widget commands for buttons are now obsolete and will go away soon.
Please change Tcl scripts not to use them.

5/23/92 (new feature) Entries can now be disabled using the "-state"
config option.  Also improved class bindings for entries to keep the
cursor visible in the window when operations occur.  Also made slight
improvements in the way redisplay is done.

5/23/92 (new feature) Added "-textvariable" option to entries so that
the text in an entry can be tied to the value of a global variable in
a fashion similar to buttons.

5/27/92 (new feature) Added "-textvariable" and "-anchor" options to
messages.

5/28/92 (new feature) Added "-padx" and "-pady" and "-underline" options
to menubuttons.

5/28/92 (feature change) Changed "-width" and "-height" options on
all flavors of buttons and menubuttons so that they are orthogonal
to "-padx" and "-pady".  It used to be that -width overrode -padx
(no padding).  Now they accumulate.

5/29/92 (new feature) Added "-disabledforeground" option to menus and
all flavors of buttons (can specify color for disabled things rather
than just using stipple to gray out).

5/29/92 (new features) Added many new options to menu entries:
-activebackground, -background, -font, -state, -underline.  The
"disable" and "enable" widget commands for menus are now obsolete
and will go away soon.  Please change Tcl scripts not to use them.

5/29/92 (new features) Added "atom" and "atomname" options to "winfo"
command.

5/29/92 (new feature) Wrote tk_listboxSingleSelect procedure, which
can be used to change listbox behavior so that only a single item is
selected at once.

6/1/92 (new feature) Added new modifier names "Meta" and "Alt" for
"bind" command.

6/3/92 (new feature) Added "winfo toplevel" command.

6/3/92 (new feature) Made several changes for greater Motif compliance,
including:
    - menu retention if you click and release in the menu button,
    - keyboard traversal of menus (see traversal.man)
    - no widget flashing if you set $tk_strictMotif to 1

6/15/92 (bug fix) Fixed problem in tkBind.c where command string for a
binding could get reallocated while the command was being executed (e.g.
bindings that delete or change themselves).

6/15/92 (bug fix) Don't allow "tabWidth" field to become zero in tkFont.c:
can cause core dumps for fonts that don't enough information to compute
tab widths.

6/19/92 (bug fix) Fixed bug in binding mechanism that caused structure-
related events to be reported both to the correct window and its parent.

7/14/92 (bug fix) Changed tkColor.c not to free colors for visual types
StaticGray or StaticColor.

7/15/92 (new feature) Text widgets now exist.  They display any number of
lines of text with a variety of display formats, and include hypertext
facilities.  See the manual page for details.

7/20/92 (bug fix) If a top-level window was put in the iconic state to
begin with, it could be deiconified with "wm deiconify .foo" until it had
first been deiconified by hand from the window manager.  Tk was getting
confused and thought the window was mapped when it wasn't.

7/29/92 (bug fix) Don't permit rectangles or ovals to have zero-sized
dimensions.  Round up to at least one pixel.

7/29/92 (new features) Major upgrade to canvases:
    - new item types: arc, window, bitmap
    - added Bezier spline support for lines and polygons
    - rectangles and ovals now center their outlines on the shape,
      rather than drawing them entirely inside the shape
    - new "coords" and "bbox" widget commands
    - new "-tags" option for all item types.
    - new "-confine" option to prevent scrolling off edge of canvas.

8/6/92 (new feature) Added "-width" and "-height" options to frames.
The "-geometry" option is now obsolete and should be removed from Tcl
scripts:  it may go away in the future.

8/7/92 (bug fix) Error messages in Tk_ParseArgv were sometimes including
the option name where they should have included its value.

---------------------- Release 2.2, 8/7/92 -------------------------

8/7/92 (bug fix) Changed tkCanvas.c to be more conservative in the area
it passes to XCopyArea.

8/8/92 (bug fix) Fixed bug in tkTextDisp.c that sometimes caused core
dumps when text views changed (e.g. typing return on last line of screen).

8/8/92 (bug fix) Fixed bug in menu.tcl that caused errors when using
keyboard to traverse over separator menu entries.

8/10/92 (bug fix) Changed to use OPEN_MAX instead of MAX_FD to compute
maximum # of open files.

8/10/92 (bug fix) Canvases weren't updating scrollbars on window size
changes.  They also weren't recentering canvases on window size changes.

8/10/92 (bug fix) There were still a few places where commands were being
invoked at local level instead of global level (e.g. commands associated
with buttons and menu entries).

8/10/92 (bug fix) TkBind.c used to ignore explicit shift modifiers for
all keys (i.e. <Shift-Tab> was treated the same as <Tab>).  Modified to
allow explicit request for shift modifier, like <Shift-Tab>.

8/13/92 (feature change) Changed default fonts to request "Adobe" fonts
explicitly.

8/16/92 (bug fixes) Modified tkCanvArc.c and tkTrig.c to increase slightly
the bounding boxes for arcs, in order to make sure that proper redisplay
occurs when arcs are moved (little turds were getting left behind).

8/16/92 (bug fix) Modified tkCanvas.c not to redraw at all if the redisplay
area is off the screen.  Also, only do a background clear for the portion
of the redraw area that is on-screen.  Also, reduced size of off-screen
pixmaps used for redisplaying, which speeds up redisplay in some cases.

8/19/92 (bug fix) Canvases that were taller than wide were not being
redisplayed properly.

8/20/92 (new feature) Added Tk_CreateGenericHandler procedure for trapping
all X events (useful for tracing, watching non-Tk windows, etc.).

8/21/92 (bug fix) Widgets weren't always being notified when they got
the focus back again (the problem had to do with grabs and menus in
particular).

8/21/92 (new feature) Added "-state" option to scale widgets.

8/22/92 (new feature) Changed tkBitmap.c to allow tilde-substitution
to occur in bitmap file names.

---------------------- Release 2.3, 8/24/92 -------------------------

8/27/92 (bug fix) Changes to -activebackground and -activeforeground options
for menubuttons were being lost.

8/27/92 (bug fix) Entries were selecting last character when a B1-drag
occurred past the right edge of the text.

8/28/92 (bug fix) Fixed bug in canvases where a grab during a button
press caused the canvas state to lock up so that it didn't select a
new current item.

9/7/92 (bug fix) Changed tkMenu.c to accept numerical menu indices that
are out of range;  now it just rounds them off to the nearest existing
entry.

9/7/92 (bug fix) Fixed bug in tkTextDisp.c that caused core dumps when
invoking "yview -pickplace" widget command on texts that are too small
to hold any lines at all.

9/11/92 (bug fix) Fixed bug in tkTextDisp.c that caused core dumps
when adding tags to non-existent lines.

9/11/92 (bug fix) Line items in canvases didn't permit an empty fill
color (i.e. couldn't make them transparent).

9/14/92 (reorganization) Changed manual entries to use .1, .3, and .n
extensions.  Added "install" target to Makefile to suggest how Tk should
be installed.

9/16/92 (bug fix) Changed tkSend.c to always specify the root window of
screen 0 rather than using DefaultRootWindow.  DefaultRootWindow doesn't
always go to screen 0 on displays with multiple screens, which can result
in send's not being possible between the screens.

9/18/92 (new feature) Added three new options to "wm" command: "protocol",
"client", and "command".  These provide support for window manager protocols
such as WM_DELETE_WINDOW and WM_TAKE_FOCUS, plus support for the
WM_CLIENT_MACHINE and WM_COMMAND properties.

9/30/92 (new feature) Implemented color model support, including
"tk colormodel" command and Tk_GetColorModel and Tk_SetColorModel
procedures.  These allow you to force mono operation even on a color
display.  Also changed color allocation not to give errors when colors
run out, but just to switch to a mono color model.

10/1/92 (bug fixes) Fixed two bugs in tkTextBTree.c that caused core dumps
during text deletion.

10/5/92 (bug work-around) Changed tkColor.c to ignore errors when freeing
colors.  This is needed to work around improper reference count management
for colormap entries under X11/NeWS.

10/7/92 (new feature) Added support for different visual types, including
procedures Tk_SetWindowVisual and Tk_SetWindowColormap, plus macros
Tk_Visual, Tk_Depth, and Tk_Colormap.  The code for this was contributed
by Paul Mackerras.

10/7/92 (new feature) Added Tk_IsTopLevel macro.

10/12/92 (bug fix) Fixed bug in tk.tcl that caused torn-off menus with
cascaded children not to track mouse motion correctly (the cascade
switched in response to mouse motions within the cascaded child).

10/12/92 (new feature) Major changes to focus handling:
(a) Tk watches FocusIn and FocusOut events for focus changes, not Enter
    and Leave, so it will work better with explicit-focus-model window
    managers (e.g. mwm in default mode).
(b) Tk generates FocusIn and FocusOut events for the focus window now.
    The old procedural interface (via Tk_CreateFocusHandler) is obsolete
    and is no longer used inside Tk.  It is still supported for
    compatibility, but won't be for long.  You should change your code
    to use FocusIn and FocusOut events instead.
(c) The model for FocusIn and FocusOut events is different than the
    one described in Xlib documentation.  See the "focus" manual entry
    for details.
(d) If there is no input focus then keyboard events are discarded.  They
    used to be directed to the mouse pointer window, although this wasn't
    documented.  The focus now defaults to the root window.
*** POTENTIAL INCOMPATIBILITY ***

10/15/92 (bug fix) Fixed text items in canvases where they didn't
display the insertion cursor if the item had no characters in it.

10/26/92 (bug fix) Fixed bug in tkSelect.c that occasionally caused
BadWindow X protocol errors when retrieving the selection.  Tk wasn't
making sure that a window existed before using it to retrieve the
selection.

10/30/92 (feature change) Changed canvases so that if the scroll region
is smaller than the window and -confine is on, the scroll region isn't
forced to be centered in the window;  it can be anywhere that meets the
confinement restrictions.

11/2/92 (new feature) Added "winfo exists" command.

11/5/92 (new feature) Changed DoWhenIdle handlers so that if a new
when-idle handler is created as a side-effect of another when-idle
handler, the new handler isn't invoked until Tk has first checked
for other events to process.

11/6/92 (bug fixes, new features) Major overhaul of window manager
interface:
(a) Tk should now work with virtual-root window managers;
(b) windows will now place more accurately on the screen and stay where
    they're supposed to;
(c) size changes handled more reliably;
(d) code now works robustly in the face of withdrawals followed
    immediately by deiconifications.
(e) Added new procedure Tk_GetVRootInfo and new options to "winfo" command:
    vrootx, vrooty, vrootwidth, vrootheight.
(f) Added "overrideredirect" option to "wm".
(g) Fixed bug where change in width-only via "wm geom" didn't always work
   (min and max window sizes weren't being set properly for the wm).

11/6/92 (bug fixes) Modified menus so that they work correctly with
virtual root window managers.  Also fixed bug where menus didn't move
along with their associated windows, so that the menu popped up at
the old location of the window rather than its new location.

11/9/92 (new constraint) Made it illegal to give windows names that
start with upper-case letters, since such names will goof up the
option database by appearing to be classes rather than names.
*** POTENTIAL INCOMPATIBILITY ***

11/10/92 (new feature) Added Postscript output to canvases.

11/13/92 (bug fix) Changed default for maximum size passed to window
manager from 1000000 (which causes some wm's to make windows too large
when "maximized") to the size of the display.

11/14/92 (feature change) Major overhaul of menubuttons and pull-down
menus.  Removed event-sharing code, including Tk_ShareEvents and
Tk_UnshareEvents.  The -variable option for menubuttons has been
removed,and the "post" and "unpost" widget commands for menubuttons
no longer exist.  The "post" widget command for menus no longer
allows a group option.  The procedure tk_menus has been replaced
with a new procedure, tk_menuBar, which has a slightly different
interface.
*** POTENTIAL INCOMPATIBILITY ***

11/20/92 (new features, feature changes) Major overhaul of grab
mechanism to produce more correct event streams.  Also changed Tcl
commands to require explicit window for grab releases (makes it
possible for grabs to work on multiple displays simultaneously).
The old "grab none" command no longer exists, but new options
have been added: "current", "release", "set", and "status".
*** POTENTIAL INCOMPATIBILITY ***

11/20/92 (new feature) Use TK_LIBRARY environment variable to set library
directory location, if it is defined.  Otherwise fall back on usual
compiled-in value.

11/25/92 (bug fix) "wm grid" command was using wrong window.

11/29/92 (bug fix) Fixed core dump that occurred when trying to use
placer on top-level windows: return error instead.

11/29/92 (bug fix) Selection retrieval wasn't making sure that the window
on whose behalf selection is being retrieved actually exists.

12/3/92 (new feature) Added support for Mode_switch key to support the
full ISO character set.  Also added event handlers for MappingNotify
events so that Tk updates itself in response to keycode and modifier
changes.

12/6/92 (bug fix) Ignore recursive attempts to destroy window.

12/9/92 (new demos) Added "tcolor" and "rmt" demos.

12/10/92 (new features) Added "yposition" widget command for menus,
changed "delete" widget command to take an optional second index,
and changed -command option for cascade entries so that it is
invoked when the entry is activated rather than when it is invoked.
*** POTENTIAL INCOMPATIBILITY ***

12/12/92 (implementation change)  Changed the procedures Tk_FreeBitmap,
Tk_NameOfBitmap, Tk_SizeOfBitmap, Tk_FreeCursor, Tk_NameOfCursor, and
Tk_FreeGC to require an addition Display argument.  This is needed for
Tk to function correctly when an application has windows on multiple
displays.
*** POTENTIAL INCOMPATIBILITY ***

12/12/92 (new feature) Started creating a test suite.  Right now it
only has a few tests.

12/12/92 (new feature) Modified the packer so that a window can be
packed in descendants of its parent (used to be restricted to the
parent alone).  This makes it possible to hide extra windows used
for geometry management.  Also, can use generalized screen distances
in the "pack" command.

12/16/92 (feature change) Boolean options such as -exportselection now
print as 0/1 rather than true/false (both the default and current values
print this way).  This makes it easier to use these values in expressions.
*** POTENTIAL INCOMPATIBILITY ***

12/16/92 (name change) The classes "RadioButton" and "CheckButton" have
been renamed "Radiobutton" and "Checkbutton" for consistency.  From now
on widget class names will have exactly one capital letter.
*** POTENTIAL INCOMPATIBILITY ***

12/16/92 (new feature) Added -setgrid option to listboxes.

12/16/92 (new feature) The "destroy" command, and the "delete" widget
command for canvases, now accept any number of arguments, including
zero.

12/16/92 (new feature) Changed internal TkBindError procedure to
Tk_BackgroundError and exported it to Tk clients.

12/16/92 (option name change) Changed the place command's "dependents"
option to "slaves" for better consistency with documentation.
*** POTENTIAL INCOMPATIBILITY ***

12/16/92 (name changes) Renamed the "cursor*" options in entries and
canvases to "insert*".  Also renamed the "cursor" index to "insert" and
the "cursor" widget command to "icursor".  This was done to avoid
confusion between the mouse cursor and the insertion cursor.
*** POTENTIAL INCOMPATIBILITY ***

---------------------- Release 3.0, 12/17/92 -------------------------

12/17/92 (bug fix) Fixed dangling-pointer bug in canvases that occurred
if a <LeaveNotify> binding deleted the current item.

12/18/92 (bug fix) Core dump occurred if "wm" invoked with no arguments.
Also, tkWm.c wasn't properly setting WM_CLASS property on application
startup.

12/18/92 (incorrect documentation) Updated manual entries for Tk_FreeGC,
Tk_FreeCursor, and Tk_FreeBitmap to reflect new interface that requires
"display" argument.

12/18/92 (missing documentation) Added documentation for the canvas
"postscript" command, which was missing in the 3.0 release.

12/21/92 (bug fixes) There were lots of problems with the new installation
targets in the Makefiles, such as using "cp -f" and not installing
prolog.ps.  Made several other miscellaneous improvements to Makefile.

12/21/92 (bug fix) Arrowheads on canvas line items weren't moving properly
after coordinate changes made with the "coords" widget command.

12/21/92 (bug fix) If top-level window was initially withdrawn, couldn't
ever deiconify it again.

12/21/92 (bug fix) Double-button event sequences didn't always trigger
properly when grabs were in effect.

12/22/92 (bug fix) The packer didn't display any top or bottom windows
after a left or right expanded window, and vice versa.  Also made the
distribution of space among expanded windows more even.

12/28/92 (new features) Several improvements to selection:
(a) Added procedures Tk_ClearSelection and Tk_DeleteSelHandler.
(b) Added "clear" and "own" options to "selection" command, extended
    "handle" option to delete handlers.
(c) Error returns from "selection handle" scripts are now turned into
    selection retrieval errors ("no such selection") rather than an
    empty selection.
(d) Tk responds automatically for targets APPLICATION (name of application,
    so you can "send" to it) and WINDOW_NAME (name of window within
    application.
(e) Added test file "select.test" to test suite.

12/28/92 (bug fix) Fixed problem with flashing menus that occurred
because menu.tcl was willing to unpost and then immediately repost
the same menu.

1/6/93 (bug fix) Test for UnmapNotify events in tkPack.c used = instead
of ==.

1/21/93 (bug fix) Changed many widgets to eliminate use of
DefaultVisualofScreen, DefaultColormap, etc. and use the visuals
and colormaps for the actual windows instead.  Also changed to
inherit colormaps and windows from parent by default.

1/21/93 (new features) Added new winfo options "cells", "depth", and
"visual".

1/23/93 (bug fix) Fixed problem with text display that could result
in negative XCopyArea heights being sent to X server.  This causes some
servers (e.g. some versions of OpenWindows) to crash.

1/25/93 (new feature) Added -postcommand option to menus, so that menus
can be reconfigured before each posting.

1/29/93 (feature change) Changed %X and %Y in bindings so that they
refer to the virtual root rather than the true root.  Although
potentially incompatible, this change should almost always "do the
right thing".
*** POTENTIAL INCOMPATIBILITY ***

1/31/93 (bug fix) Changed "send" code to grab server while updating
the registry property (before this fix, two programs could allocate
the same interpreter name if they started up simultaneously).  In
order to make this fix I had to change the code for reclaiming
names of dead interpreters in a way that sometimes allows dead
interpreters to persist in the registry.

2/1/93 (feature change) Changed entries to allow leftmost "visible"
character to be the end of the text (i.e. no characters actually visible).
This is needed so that the cursor can be displayed even if the last
actual character is too wide to fit in the window.

2/3/93 (bug fix) Fixed two bugs in tkFocus.c:  (a) FocusIn events
were getting lost in some cases because the focus window hadn't been
created yet (e.g. new top-level window pops up underneath the mouse);
(b) Tk was accidentally triggering FocusOut events when the mouse
moved from a top-level window to one of its children.

2/4/93 (new feature) Added "visibility" option to "tkwait" command to make
it easier to wait for a new window to appear on the screen.

---------------------- Release 3.1, 2/5/93 -------------------------

2/10/93 (installation improvements) Makefile improvements:  added RANLIB
variable for easier Sys-V installation, changed to use INCLUDE_DIR
properly, and added SHELL variable for SGI systems.

---------------------- Release 3.2, 2/11/93 -------------------------

2/11/93 (new feature) Added "wm state" command, and improved wm so that
the right thing will happen if you invoke "wm iconify" when a window is
withdrawn.

2/14/93 (bug fix) When -colormap option was used in generating Postscript
for canvases, Tk didn't add an extra space after the color command.

2/14/93 (new feature) Changed "extern" declarations in tk.h to "EXTERN",
which will use the definition of EXTERN from tcl.h and work correctly
in C++ programs.

2/18/93 (bug fix) Item-specific bindings weren't getting deleted from
canvas items when the items were deleted.  As a result, they could
suddenly re-appear for new items if the new items were allocated a
record at the same addresses as the old ones.

2/18/93 (feature reversal) Changed "after" back again, so that it sleeps
*without* responding to events when it is invoked with just one argument;
can always use tkwait plus after with additional arguments to achieve
the effect of responding to events.
*** POTENTIAL INCOMPATIBILITY ***

2/20/93 (bug fix) Fixed bug in tkWindow.c where colormaps weren't being
set correctly for new top-level windows on different screens than their
parents (the bug results in X protocol errors: "invalid Colormap
parameter").

2/22/93 (bug fix) Changed "#!/usr/local/wish" in demo scripts to
"#!/usr/local/bin/wish" to reflect new location of binary.

2/22/93 (new feature) Added new reliefs "groove" and "ridge".

2/25/93 (new feature) Added new built-in bitmaps:  "error", "hourglass",
"info", "question", "questhead", and "warning".  Also added new demo in
"widget" to display all of these (under the Miscellaneous menu).

2/25/93 (improved implementation) Changed DrawText procedure in
prolog for outputting Postscript from canvases to use stringwidth
instead of charpath+pathbbox:  avoids limitcheck problems with long
strings, and also properly includes space characters in calculation.

2/25/93 (bug fix) Fixed several bugs in library/menu.tcl that caused
menu traversal to mis-behave when menu had no entries.

2/26/93 (new feature) Added "wm frame" command.

3/6/93 (bug fix) Mwm in click-to-focus mode was goofing up grabs so that
pull-down menus were sometimes unresponsive.  Modified tk.tcl to ignore
the spurious B1-Enter events generated by mwm, plus modified tkGrab.c to
release simulated button grabs correctly.

3/8/93 (bug fix) Tk had wrong interpretation of "lbearing" font metric,
which caused text to be displayed at the wrong horizontal position in
several places (labels/buttons, listboxes, canvas text, scales).  This
change will cause slight changes in the way certain widgets are
displayed.

3/12/93 (bug fix) Fixed core dumps that occurred in tkEntry.c because of
zero values in entryPtr->avgWidth.

3/12/93 (bug fix) Tk_CoordsToWindow was using root coordinates always.
Changed to use virtual-root coordinates when a virtual-root window
manager is being used.  Before this fix, "winfo containing" didn't
return the correct window under virtual-root window managers.

3/18/93 (bug fix) Modified tkWm.c so that Tk doesn't fight with window
manager over position of window;  it just takes what the window manager
gives it.

3/21/93 (new feature) Changed menus to display cascade entries with
standard Motif arrows at right side.a

3/22/93 (bug fix) Fixed bug in tkPack.c that was causing memory to
get trashed with the integer value 1.

3/22/93 (bug fix) Canvas text didn't print correctly if it contained
an open paren (or other special character) immediately followed by
an octal digit.

3/22/93 (bug fix) Text widgets didn't redisplay properly in cases
where two or more groups of lines both got taller at the same time
(e.g. from tag changes), causing two separate bit copies where the
first bit copy's target area overlapped the source area for
the second bit copy.

4/1/93 (bug fix) Changed canvases to use ISO Latin-1 font encoding
if that's supported by the Postscript interpreter.  Also added workaround
for bug in NeWSprint related to stipple fills.

4/1/93 (bug fixes) Made various changes to focusing and grabs to
eliminate extraneous focus events and generally improve behavior.

4/2/93 (bug fix) Modified tkWm.c not to wait indefinitely for the window
manager to map or reconfigure a window:  this led to deadlock in some
situations, such as creating a new top-level window with a grab held.

4/19/93 (bug fix) Fixed another bug in tkWm.c that caused windows to walk
across the screen in some situations.  Also fixed problem where rapid
posting and unposting of cascaded submenus (or menus?) could cause Tk
to become confused about whether or not a window is mapped (added
TkWmUnmapWindow procedure to make top-level unmaps synchronous).

4/24/93 (feature change) Changed the "after" command to allow times
less than or equal to 0, and to use 0 whenever they occur.

4/26/93 (new feature) Implemented security check for "send" as proposed
by Bennett Todd: incoming sends are now rejected unless (a) xhost-style
access control is enabled and (b) the list of authorized hosts is
empty.  In other words, you have to use xauth to use send.  This feature
can be disabled by setting the TK_NO_SECURITY flag at compile-time.

5/15/93 (improvement) Switched to use Tcl_PrintDouble whenever returning
real values as Tcl results.  This potentially allows higher precision.
Switched to use %.15g whenever printing reals in Postscript files.
However, the change Tcl_PrintDouble causes incompatibilities.  For
now, it's disabled with a macro in tclInt.h that redefines Tcl_PrintDouble.
Tk 4.0 will delete the macro, and you can also delete it now if you
want the better (but incompatible) behavior.

5/19/93 (bug fix) Fixed divide-by-zero problem that could occur in
closeness calculations for canvas oval items.

5/30/93 (bug fix) PROP and CONFIG were accidentally #defined to the same
value in tkBind.c, which could cause incorrect %-substitutions in event
bindings in a few exotic cases.

6/4/93 (improvement) Changed to use GNU autoconfig for configuration.
Makefile format changed, and Tcl is no longer automatically included
in Tk releases.

6/7/93 (bug fix) Fixed off-by-one error in rounding negative coordinates
during redisplay of canvases.

6/9/93 (feature improvement) Modified default bindings for entries to
keep one character visible to the left of the cursor during backspaces.

6/18/93 (feature improvement) Added patchlevel.h, for use in coordinating
future patch releases, and also added tk_patchLevel variable to make the
patch level available in scripts.

6/26/93 (bug fix) Fixed numeric problems in scales that occurred with
very large scale values.

6/26/93 (bug fix) Polygon items in canvases could cause core dumps if
the "coords" widget command was used to add one new coordinate.

6/26/93 (bug fix) Changed canvases to handle large stipple patterns
gracefully (stipples used to jump around during redisplay and lose
coherency).

7/1/93 (syntax change, new feature) Implemented the new packer syntax
as described in the book.  For now the old syntax will continue to be
supported too.  Converting over is straightforward except (a) use
"-anchor" instead of "frame", and (b) padding is different (separate
internal and external padding, plus pad amounts are *on each side*
instead of total).  Also added "pack propagate" command for keeping
the packer from setting the master's requested size.

7/1/93 Changed copyright notices.  The effect is the same as with the
old notices, but the new notices more clearly disclaim liability.

7/7/93 (new feature) Added support for window stacking order.  Windows
will now stack in the order created (most recent on top), plus "raise"
and "lower" commands may be used to restack (Tk_RestackWindow procedure
is available from C level).

7/7/93 (reorganization) Moved main.c to tkMain.c, reorganized it to
call Tcl_AppInit just like tclsh does, and added argv0 variable to contain
application name, and added default Tcl_AppInit procedure for wish.
Also added tkTest.c to hold C code for testing.

7/7/93 (new feature) Added new Tk-specific "exit" command, which cleans
up properly before exiting.  It replaces the Tcl "exit" command, and
can be used in place of "destroy .".

7/9/93 (new features) Added tk_dialog library procedure that creates
dialogs with a bitmap, message, and any number of buttons.  Also changed
default tkerror procedure to use tk_dialog plus offer the user a chance
to see a Tcl stack trace.

-------------------- Release 3.3 Beta 1, 7/9/93 -------------------------

7/12/93 (configuration changes) Eliminated leading blank line in
configure script;  provided separate targets in Makefile for installing
binary and non-binary information; fixed -lnsl and -lsocket handling
in configure; added autoconf support for fd_set type; check for various
typedefs like mode_t and size_t, and provide substitutes if they
don't exist; don't include tkAppInit.o in libtk.a; try to locate the
X includes and library in all of the standard places for various systems.

7/14/93 (new feature) Modified tkMain.c so that it stores the value
of the -display command-line option into the DISPLAY environment
variable, if it is specified.

7/15/93 (feature removal) Removed auto-initialization feature from
Tk_ConfigureWidget, so that you must once again initialize all fields
of a widget record before calling Tk_ConfigureWidget.  This restores
the behavior back to what it was in Tk 3.2.

7/16/93 (bug fix) Modified tkBind.c to ignore the Caps Lock modifier
unless it is explicitly requested in a binding.  Without this fix,
buttons and menus and other things didn't work if the Caps Lock key
was active.

-------------------- Release 3.3 Beta 2, 7/21/93 -------------------------

7/21/93 (new feature) Change "make install" so that it will modify the
#! lines on demo scripts to reflect the place where the wish binary
is installed.

7/23/93 (new feature) Added Tk_MainWindow procedure that returns the
main window associated with a Tcl interpreter.  This is intended for
use by Tcl_AppInit and other initialization procedures.

7/24/93 (configuration improvements) Changed configure script not to
omplain about "fd_set" missing if it's defined in <sys/select.h>.

7/28/93 (bug fix) "Bad Match - parameter mismatch" errors were
sometimes occurring when several top-level windows got created
at the same time, due to wrong choice of sibling when stacking
windows.

8/14/93 (new feature) Added support for tcl_prompt1 and tcl_prompt2
to wish main program:  makes prompts user-settable.

8/19/93 (bug fix) Bindings to event sequences like "aD" never matched
because the Shift key has to be pressed before D.  Modified Tk to
ignore extraneous keypresses if they are for modifier keys.

8/26/93 (configuration changes) Added Tk_Init, modified Tcl_AppInit
procedures to use it and Tcl_Init.  Added support for .wishrc file.

8/28/93 (new feature) The main window is now a legitimate toplevel
widget.

-------------------- Release 3.3 Beta 3, 8/30/93 -------------------------

9/2/93 (bug fix) The packer wasn't always relaying out a master after
changes to some of the configuration options of its slaves.

9/2/93 (bug fix) The binding mechanism made it impossible for patterns
like <Double-ButtonRelease-1> to ever match.

9/2/93 (bug fix) Fixed core dump that occurred for bitmap canvas items
if Postscript is generated but no -bitmap option has been specified.

9/4/93 (enhancement) Slight improvements to menu traversal:  set menu
traversal bindings for menubar window in tk_menuBar, plus trigger
traversal on <Any-Alt-Keypress> instead of <Alt-Keypress>.

9/9/93 (bug fix) Changed tkBind.c so that the Num_Lock key doesn't
prevent events from triggering bindings.

9/9/93 (bug fix) Changed tkOption.c to always fetch RESOURCE_MANAGER
property from root window of screen 0, rather than using default
screen.

9/9/93 (bug fix) Entry widgets weren't allocating quite enough width
for themselves.  Fixed this and changed the size computation to match
what's done for buttons and texts.

9/16/93 (bug fix) Changed tkMain.c not to call exit C procedure directly;
instead always invoke "exit" Tcl command so that application can redefine
the command to do additional cleanup.

-------------------- Release 3.3, 9/29/93 -------------------------

9/30/93 (bug fix) Packer wasn't unmapping slaves when master got deleted.

9/30/93 (bug fix) Binding event sequences such as <Right> were being
misprinted as ASCII characters such as "S".

10/6/93 (bug fix) Canvases weren't unmapping window items when the canvas
got unmapped, which caused problems for window items whose windows weren't
descendants of the canvas (they got left on the screen).

10/7/93 (feature change) NULL proc arguments to Tk_CreateFileHandler used
to have a special undocumented meaning (fd was display);  eliminated this
special interpretation.

10/7/93 (configuration change) Eliminated dependency of tkMain.c on
tkInt.h and tkConfig.h, so that it's easier for people to copy the file
out of the source directory to make modified versions.

10/8/93 (bug fix) 3.0 introduced a bug where the class of the application
wasn't being set properly, so options based on the application class
weren't triggering.  Fixed by adding new argument to Tk_CreateMainWindow.

10/11/93 (bug fix) Fixed bug in tkTextBTree.c where some deletions would
cause core dumps due to halfwayLinePtr not getting set correctly.

10/18/93 (bug fix) Fixed a couple of bugs that made it hard to actually
display N characters in an entry with "-width N" (tended to scroll the
entry so that only N-1 characters were visible at once).

10/22/93 (bug fix) During configuration, XINCLUDE_DIR and XLIBRARY_DIR
weren't overriding xmkmf like they were supposed to.

10/23/93 (new feature) Allow negative scale factors in canvas "scale"
widget command.

10/23/93 (bug fix) Grabs weren't being cleaned up right if the grab
window was deleted, causing core-dumps in some cases.

10/23/93 (bug fix) tk_TextSelectTo wasn't checking to be sure that
the "anchor" mark exists.

10/27/93 (bug fix) Fixed core dump that could occur in a text widget if
the scroll command modifies the text.

11/1/93 (bug fix) Change texts so that the -yscrollcommand option is
invoked at display time, not when the window is re-layed out.  This
eliminated various core dumps that could occur if -yscrollcommand modified
the text.

-------------------- Release 3.4, 11/04/93 -------------------------

Note: there is no 3.5 release.  It was flawed and was thus withdrawn
shortly after it was released.

11/12/93 (bug fix) TkMain.c didn't compile on some systems because of
R_OK in call to "access".  Changed to eliminate call to "access".

-------------------- Release 3.6, 11/26/93 -------------------------

11/10/93 (bug fix) Packer and placer didn't always reposition a window
correctly if it was managed inside a neice or lower descendant (using
"-in" option) and the neice's parent moved.

11/24/93 (bug fix) Fixed time problem in selection (retrievals could
fail if retriever hasn't received any X events since selection was
made, so that time of retrieval appears to be older than time of
selection).  Selection code is now much less picky about times, both
on retrieving and supplying sides.

12/2/93 (new feature) Changed arrow-head drawing code for canvas
lines to draw a 0-width outline in addition to filling the area:
this produces much nicer, more symmetrical displays.

12/2/93 (bug fix) When colors ran out, Tk was invoking "tkerror"
when its state was internally inconsistent, which could cause
core dumps in some situations (e.g. if tkerror used the same color
that caused colors to run out).  Changed notification to occur
as a when-idle handler.

12/3/93 (bug fix) During a global grab, Tk wasn't including PointerMotion
in the list of grabbed events, so pointer motion couldn't be tracked
outside the grabbing application.

12/3/93 (bug fix) Canvases didn't handle smoothed lines correctly
when they only contained two points.

12/3/93 (bug fix) Fixed bug in tkWindow.c where certain kinds of
errors during window creation could cause Destroy events to be generated
for a window that was never completely initialized.

12/13/93 (bug fix) Fixed bug in tkTextDisp.c that resulted in core
dumps at line 1467 under exmh.  The exact situation is that a text
widget was being redisplayed at a time when it had a -yscrollcommand
option but hadn't yet been mapped onto the screen.

12/17/93 (bug fix) Fixed bug in tkWindow.c whereby new top-level windows
with non-default visuals still inherited border pixmap from parent (root),
which could cause visual clash and X error.

12/17/93 (bug fix) Fixed bug in tkTextDisp.c that caused round-off
error in the information passed to scroll commands.

12/18/93 (bug fix) Fixed bug in tkPack.c that caused core dumps in
some situations if a master with siblings packed "-in" it was deleted.

12/18/93 (bug fix) Added "compat" directory to distribution, since it's
referenced by tkConfig.h on some systems.

12/18/93 (performance improvement) Improved performance of appending to
a listbox, so that inserting N items doesn't take N**2 time.

12/20/93 (bug fix) Fixed bug in canvas ovals that caused the fill color
for the oval to stick out past the outline.

1/2/94 (fixed Xlib bug) Added code to reuse X resource identifiers so
that they won't run out in long running applications.  There are three
new library procedures: Tk_FreeXId, Tk_GetPixmap, and Tk_FreePixmap.
Modified all Tk code to use these procedures, so wish applications should
now be able to run forever without running out of identifiers.

1/10/94 (bug fix) tkCursor wasn't freeing pixmaps used to create
cursors, which caused memory leaks in programs that changed cursors
frequently.

1/21/94 (bug fix) Fixed bug in scales that caused them to loop
infinitely drawing tick-marks when -from and -to were the same.

2/2/94 (bug fix) Fixed problem where messages that contained tabs
didn't always compute the correct size, so that text spilled off
the right edge.  The fix adds an extra "tabOrigin" parameter to
the internal procedures TkMeasureChars, TkDisplayChars, and
TkUnderlineChars.

2/4/94 (bug fix) Fixed off-by-one problem in tkBind.c that caused
it to read past the initialized part of dispPtr->modKeyCodes.

2/7/94 (bug fix) Text widgets didn't handle grabs correctly, such
that the "current" character got stuck if a grab occurred while a
mouse button was down.  It would get unstuck until after the
next button press and release.

2/19/94 (bug fix) Fixed prolog.ps (prolog for Postscript printing from
canvases) so that it correctly prints all of the characters in the
ISO Latin-1 character set.

2/19/94 (bug fix) Modified tkBind.c to save and restore the interpreter's
result across the execution of binding scripts.  Otherwise if an event
triggers in the middle of some other script (e.g. a destroy event during
window creation, because there was an error in the creation command),
the interpreter's result gets lost.

2/19/94 (bug fix) Fixed bug in dealing with results of sent command
that could cause them to get lost in some situations.

2/21/94 (bug fix) Don't let user close a dialog window created by
tk_dialog, since this would cause tk_dialog to hang:  force the user
to select one of the dialog's buttons.

2/21/94 (bug fix) Fixed bug in canvas polygons whereby they didn't
correctly handle changes in the number of points (via "coords"
widget command).

2/23/94 (bug fix) Large bitmaps in canvases didn't print correctly
because they overflowed the 64-KB limit on strings in Postscript.
Changed canvas printing to split up large bitmaps into mutliple
smaller ones for printing.

2/25/94 (bug fix) The "." window was being set up with -width
and -height options, which interfered with geometry management (any
configuration change on "." causes the window to change size to
200x200, then change back again).

2/26/94 (bug fix) Fixed several bugs that occurred when a Destroy
event handler for a window deleted the window's parent.

3/3/94 (new features) Changes to binding mechanism:
    - The modifiers for "Alt", "Meta", and "M" are now computed by
      examining the modifier map, rather than being hardwired to
      M2, M1, and M1.
    - When processing events, one script is invoked for each object
      in the list passed to Tk_BindEvent, rather than stopping as
      soon as a script is invoked for some object.  The "break" and
      "continue" commands can be used within a script to abort all
      scripts for the event or the current one.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added "bindtags" command so that new binding groups can be
      defined for widgets and the evaluation order can be changed.
    - When matching events to bindings, extra modifiers are now ignored,
      as if "Any" were specified for every event.  The "Any" modifier
      is still recognized, but it is ignored and is deprecated.
      *** POTENTIAL INCOMPATIBILITY ***
    - In % sequences that print window identifiers (e.g. %a and %S), print
      in hexadecimal rather than decimal, for consistence with "winfo id".
      *** POTENTIAL INCOMPATIBILITY ***
    - The "bind" command no longer supports the event types CirculateRequest,
      ConfigureRequest, MapRequest, or ResizeRequest.  These event types
      are somewhat dangerous, and they never worked anyway.

3/13/94 (bug fix) Fixed numerous problems with the "wm iconwindow" command.
It appears that this command never really worked at all, but it should
work OK now.

3/14/94 (feature changes) Removed several obsolete features:
    - Eliminated "enable" and "disable" widget commands for menus.
      *** POTENTIAL INCOMPATIBILITY ***
    - Eliminated "activate" and "deactivate" widget commands for buttons,
      checkbuttons, radiobuttons, and menubuttons.
      *** POTENTIAL INCOMPATIBILITY ***
    - Removed -geometry option for frames and toplevels:  it causes
      problems when .Xdefaults files contain entries like
      "*geometry: +0+0".  Must use -width and -height instead.
      *** POTENTIAL INCOMPATIBILITY ***
    - Desupported "tkVersion" variable: use "tk_version" instead.
      *** POTENTIAL INCOMPATIBILITY ***

3/16/94 (feature changes) Changes to listboxes:
    - Eliminated -geometry option (it causes problems when .Xdefaults
      files contain entries like "*geometry: +0+0").  Added -width
      and -height options to use instead.
      *** POTENTIAL INCOMPATIBILITY ***

3/21/94 (bug fix) Fixed bug in tkOption.c where the option cache wasn't
properly cleaned up after window deletion;  this could cause the wrong
value from the option database to be used under some conditions.

3/25/94 (new features) Changes to geometry management:
    - Added Tk_MaintainGeometry and Tk_UnmaintainGeometry procedures
      to solve problems with -in windows.  Modified the packer, the
      placer, and canvases to use them.
    - Changed 2nd argument to Tk_ManageGeometry from Tk_GeometryProc *
      to a pointer to a structure with additional information about
      the geometry manager, such as name and procedure to call when
      slaves are stolen.
      *** POTENTIAL INCOMPATIBILITY ***

3/28/94 (new feature) Overhauled event management:
    - Added "cancel" option to the "after" command so that you can
      cancel previously-scheduled commands.
    - Separated X-specific stuff from generic event management.  The
      file tkEvent.c can now be used stand-alone without the rest of Tk.
      See the manual entry for Tk_EventInit for information on which
      procedures are available this way.
    - Added Tk_CreateFileHandler2 procedure, which provides a lower-level
      and more powerful form of file event handler.
    - Fixed bug in Tk_DoOneEvent where an infinite loop could occur if
      the TK_FILE_EVENT and TK_DONT_WAIT flags were set simultaneously
      (there were bugs with several other combinations too;  all should
      be fixed now).

3/28/94 (new feature) Added "fileevent" command, which allows event-
driven I/O in the style of Mark Diekhans' "addinput" command.

4/11/94 (new feature) Better support for colormaps and visuals:
    - Added new -colormap and -visual options to toplevels and frames.
    - Added "winfo visualsavailable" command.
    - Added "wm colormapwindows" command, plus support for WM_COLORMAP_WINDOWS
      to Tk_SetWindowColormap.
    - Added new library procedures Tk_GetVisual, Tk_GetColormap,
      and Tk_FreeColormap.

4/11/94 (bug fix) Fixed core dump that used to occur when specifying
an iconwindow ("wm iconwindow") for a toplevel on a different screen
than the main window.

4/23/94 (new feature) Added support for images, including the following:
    - New "image" command for creating images.
    - Built-in image type: bitmap.
    - New "image" item type in canvases.
    - Labels, buttons, checkbuttons, radiobuttons, menubuttons, and
      menu entries now support a -image option for displaying images.
    - Tk_CreateImageType and Tk_ImageChanged procedures, for defining
      new types of images in C.
    - Tk_GetImage, Tk_FreeImage, Tk_RedrawImage, and Tk_SizeOfImage
      procedures, for using images in widgets.

5/1/94 (new features) Added new procedures Tk_3DVerticalBevel and
Tk_3DHorizontalBevel.

5/11/94 (new features) Major overhaul of text widgets:
    - Implemented embedded windows and "window" widget command.
    - Added new configuration options for tags: -justify, -lmargin1,
      -lmargin2, -rmargin, -offset, -spacing1, -spacing2, and -spacing3.
      See the "Display styles" widget demo for examples.
    - Added new configuration options for texts: -spacing1, -spacing2,
      and -spacing3.
    - Added "tagList" option to "insert" widget command to control
      tags on new text.  Made tagged regions so they aren't sticky on
      either side:  new characters get a tag only if the old chars. on
      both sides had it.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added gravity for marks, and "mark gravity" widget command.
    - Added horizontal scrolling, "xview" widget command, -xscrollcommand
      option.  Changed "scan" widget commands to support horizontal
      scrolling.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added "search" widget command for searching (either exact matches
      or regular expressions).
    - New widget commands: bbox, dlineinfo, and see.
    - Changed implementation of bindings so that Enter and Leave
      events are not generated unless the tag has just become present
      (or just ceased to be present) on the current character.  Also
      changed bindings to process separately for each tag, rather than
      having high-priority tags override low-priority ones.
    - The "end" index now refers to the character after the last newline
      rather than the newline itself.  You can now tag the final newline
      and set a mark after the final newline.
    - Deletions of the "sel" tag and the "insert" and "current" marks
      are now ignored silently, rather than generating errors.  This means
      you can do things like "eval .t tag delete [.t tag names]".

5/19/94 (bug fix) Canvases didn't generate proper Postscript for stippled
text.

5/20/94 (new feature) Added "bell" command to ring the display's bell.

5/20/94 (new feature) Incorporated "square" demonstration widget into
tktest application.

5/20/94 (new features) Changed wish application (tkMain.c):
    - wish no longer processes the -help option.
      *** POTENTIAL INCOMPATIBILITY ***
    - The wish main program is now called Tk_Main;  tkAppInit.c has a
      "main" procedure that calls Tk_Main.  This makes it easier to use
      Tk with C++ programs, which need their own main programs, and it
      also allows an application to prefilter the argument list before
      calling Tk_Main.
      *** POTENTIAL INCOMPATIBILITY ***
    - The application's class is now the same as its name (except the
      first letter is capitalized), instead of "Tk".
      *** POTENTIAL INCOMPATIBILITY ***
    - The -file keyword is no longer required:  the script file name can
      be provided as the first argument without being preceded by "-file",
      as in tclsh.  For backward compatibility the "-file" keyword is
      ignored if it is the first argument, but it is deprecated.

5/26/94 (feature removed) Removed support for "fill" justify mode from
Tk_GetJustify and from the TK_CONFIG_JUSTIFY configuration option.  None
of the built-in widgets ever supported this mode anyway.
*** POTENTIAL INCOMPATIBILITY ***

5/27/94 (feature change) Changed Tk to use Tk_PrintDouble everywhere
that it converts reals to strings.  This means that floating-point
values will be generated in some cases where integer-like values were
generated before.
*** POTENTIAL INCOMPATIBILITY ***

6/1/94 (feature change) Renamed "pack newinfo" command to "pack info".
The old "pack info" command is no longer available.
*** POTENTIAL INCOMPATIBILITY ***

6/20/94 (feature changes) Overhaul of entry widgets:
    - Added "-justify" option.
    - Added "-show" option to make entries easier to use for passwords.
    - Added "cget" widget command.
    - Added "selection range" and "selection present" widget commands.
    - Added "anchor" symbolic index.
    - Changed "-scrollcommand" option to "-xscrollcommand", "view"
      widget command to "xview", for compatibility with other widgets.
      *** POTENTIAL INCOMPATIBILITY ***
    - Changed sel.last to refer to character just *after* last one
      selected, again for compatibility with other widgets.
      *** POTENTIAL INCOMPATIBILITY ***
    - For "delete" widget command, second index now refers to character
      just *after* last one to delete.
      *** POTENTIAL INCOMPATIBILITY ***
    - Overhauled bindings to be more Motif-compatible and to include
      common Emacs bindings for editing.
    - Changed -width option:  if specified as 0, widget sizes to fit
      its current text.

6/11/94 (new features) Improved Motif compatibility:
    - Added "-highlightwidth" and "-highlightcolor" options to all widgets.

6/27/94 (bug fix) Postscript generation for text items in canvases was
not justifying the text properly when a -width was specified that was
longer than the longest line.

6/27/94 (bug fix) "winfo exists" used to report a window as existing
if it was in the process of being destroyed (i.e., a destroy handler
is in the middle of execution).  Changed to report it as non-existent
under these conditions.
*** POTENTIAL INCOMPATIBILITY ***

7/11/94 (bug fix) Selections claimed via "selection own" weren't always
being cleared properly when the selection was claimed away.  Also fixed
bug where Tk wasn't properly claiming the selection, if there haven't
been any recent X events at the time of the claim.

7/13/94 (feature changes) Overhaul of scrollbar widgets:
    - New widget commands: "activate", "cget", "fraction", and "identify".
    - New options: -activebackground, -activerelief, -highlightcolor,
      -jump, -highlightthickness, and -troughcolor.  What used to be
      -background is now -troughcolor, -foreground is now -background,
      and -activeforeground is now -activebackground.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added new syntax for "set" command, "get" result, and generated
      commands.  Changed other widgets to use the new syntax.
    - Moved the bindings out of C and into Tcl scripts, using the new
      options and widget commands.  Added support for all Motif
      bindings, plus jump scrolling and cancelling of slider drags.

7/16/94 (bug fix) Canvases assumed that the Leave event for one item
didn't modify or delete the next current item;  this could cause core
dumps under some conditions.

7/23/94 (feature change) Modified Tk_BackgroundError so that tkerror
is invoked as an idle handler.  If tkerror generates a break exception
then all other queued reports are aborted.

8/14/94 (bug fix) "cursorOffTime" and "cursorOnTime" were confused in
canvases, resulting in the same time being used for both.

8/16/94 (bug fix) "tkwait variable" command didn't detect errors in
variable name, such as trying to wait for an entire array.

9/2/94 (new features) Overhaul of scale widgets:
    - Floating-point values are supported now, following Paul Mackerras'
      "fscale" widget.  Added "-resolution" and "-digits" options.
    - Added "-variable" option to link scale to variable, following
      Henning Schulzrinne's implementation.
    - Added focus highlight (-highlightthickness and -highlightcolor
      options).
    - Added new widget commands "cget",  "coords", "identify", plus
      improved "get";  removed wired-in bindings, added complete set
      of Motif bindings via Tcl scripts.
    - Changed -sliderforeground option to -background, -background to
      -troughColor, -activeforeground to -activebackground.
      *** POTENTIAL INCOMPATIBILITY ***
    - Moved value label from below horizontal scales to above the scale,
      for Motif compliance.

9/9/94 (bug fix) Fixed bug in tkWm.c that caused long delays in "raise"
command under some conditions (window already at the top of the stack).

9/10/94 (new features) Overhaul of label/button/checkbutton/radiobutton
widgets:
    - Added focus highlight (-highlightthickness and -highlightcolor
      options).
    - Added new widget command "cget".
    - Changed -selector option to -selectcolor, and changed its meaning
      too: empty no longer means don't draw the indicator;  it means
      don't use a special color when selected.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added -indicatoron (controls whether indicator is displayed) and
      -selectimage (gives special image to display when selected) options.
    - Modified bindings to be more Motif-like, added binding for space
      key.
    - Changed padding defaults to give widgets correct Motif appearance
      by default.  Also, changed to ignore padding options when displaying
      an image or bitmap.
      *** POTENTIAL INCOMPATIBILITY ***
    - Can now display text on multiple lines:  newlines cause line breaks,
      and word wrapping can be requested with -wraplength option.  Also
      added -justify and -underline options.
    - The -value option for radiobuttons can now have an empty string as
      its value;  it no longer defaults to the name of the widget.
      *** POTENTIAL INCOMPATIBILITY ***

9/13/94 (new features) Modified both canvases and messages to support
-highlightthickness and -highlightcolor options plus "cget" widget
command.

9/19/94 (new features) Added Tk_UnsetGrid procedure, modified widgets
to use it.  Also changed Tk_SetGrid so that at most one window per
toplevel can have gridding enabled.

9/23/94 (new features) Major overhaul of listbox widgets:
    - Added focus highlight (-highlightthickness and -highlightcolor
      options).
    - Added new widget command "cget".
    - Revised selection commands to support single selections as well
      as multiple disjoint selections;  syntax of "selection" widget
      command has changed to support this.  Added new option -selectmode
      for specifying which mode to use.  Default is single selection;
      tk_listboxSingleSelect procedure no longer exists.  Selections
      now return as items separated by newlines instead of a list whose
      elements are the items.
      *** POTENTIAL INCOMPATIBILITY ***
    - Extended "get" widget command to allow many items to be retrieved
      at once.
    - Added "bbox" widget command for finding position of an element on
      screen.
    - Added "activate" command to mark element with traversal focus.
    - Extended index mechanism to support new types of indices:
      "active", "anchor", "@x,y".
    - Added "see" widget command.
    - Revised bindings to include all Motif features except for AddMode.
    - If -width or -height option is <= 0, the widget requests a size just
      large enough to hold all of its text.

10/6/94 (new features) Overhaul of menubuttons:
    - Added focus highlight (-highlightthickness and -highlightcolor
      options).
    - Added new widget command "cget".
    - Added -indicatoron option to display option menu indicator.
    - The -menu option must be a child of the menubutton.
      *** POTENTIAL INCOMPATIBILITY ***

10/6/94 (new features) Overhaul of menu widgets:
    - Added new widget commands "cget" and "entrycget".
    - Changed the implementation of tear-off menus to be more
      Motif-like;  added -tearoff option for specifying whether
      tearoff entry is displayed.
    - Changed interpretation of "@y" index:  it now returns the
      closest entry, rather than "none" if y is outside the menu's
      range.
      *** POTENTIAL INCOMPATIBILITY ***
    - The -menu option for a cascade entry must now be a child of
      the menu.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added "type" widget command, so that you can query the type of
      an entry.
    - Added -foreground, -activeforeground, -selectcolor, -indicatoron,
      -image, and -selectimage options to menu entries.
    - Changed "selector" menu option to "selectColor" for Motif compliance.
      *** POTENTIAL INCOMPATIBILITY ***
    - Added -relief option for menus, just for consistency with other
      widgets (it was implicitly "raised" before).

10/6/94 (feature change) Completely overhauled the bindings for menus
and menubuttons.  They now fit better with other Tk 4.0 facilities,
such as the new binding mechanism, and they provide better Motif
compliance (e.g. keyboard traversal of submenus).  Also, the bindings
now support option menus, popup menus, and proper Motif tear-off
menus.

10/6/94 (obsolete features) The procedures tk_menuBar and
tk_bindForTraversal are no longer needed in Tk 4.0.  They still exist
for compability, but they do nothing.

10/6/94 (new procedures) Added "tk_popup" procedure for posting a
popup menu, and "tk_optionMenu" for creating an option menubutton
and its associated menu.

10/6/94 (change in name) The variable "tk_priv" has been renamed
to "tkPriv" to reflect that fact that it is private to Tk now.
This shouldn't cause any problems, since no-one except Tk should
have been using it before anyway (right?).

10/6/94 (bug fix) Fixed bug in texts where sometimes the text would
stop tracking mouse motion (the "current" item wouldn't get updated)
because the text widget missed a ButtonRelease event.

10/20/94 (new features) Overhauled selection code to support multiple
selections (primary, secondary, etc.) and multiple displays:
    - Changed "selection" command to support new options such as
      "-displayof" and "-selection".  Old command formats are still
      supported for compatibility, but they are no longer documented
      and are deprecated.
    - Changed procedures Tk_GetSelection, Tk_CreateSelHandler, and
      Tk_ClearSelection to take additional "selection" argument.
      *** POTENTIAL INCOMPATIBILITY ***
    - Selection targets APPLICATION and WINDOW_NAME have been replaced
      by TK_APPLICATION and TK_WINDOW.
      *** POTENTIAL INCOMPATIBILITY ***

10/20/94 (new features) Added support for clipboard:
    - New "clipboard" command.
    - C procedures Tk_ClipboardClear and Tk_ClipboardAppend.
    - Bindings for "cut", "paste", and "copy" for text and entry widgets,
      plus "copy" binding for listboxes.

10/24/94 (bug fix) Button widgets weren't checking for errors when
setting the values of associated variables.

11/3/94 (bug fix) Fixed bug whereby Tk would hang if "exit" was invoked
from inside a <Destroy> binding.

11/15/94 (new features) Overhaul of focus mechanism:
    - Added support for multiple displays:  separate focus windows are
      kept for each display.
    - Added support for keyboard traversal.
    - Changed focus model so Tk keeps track of a focus window for each
      top-level window and automatically sets the focus on Enter to the
      top-level.  Tk no longer synthesizes FocusIn and FocusOut events,
      but just uses the standard X mechanisms.  There is no "default"
      focus window anymore; the focus reverts to top-levels by default.
      *** POTENTIAL INCOMPATIBILITY ***
    - Changed focus command:  eliminated "focus default" and "focus none",
      added "-displayof" and "-lastfor" options.  An empty string is now
      used to signify "no focus" instead of "none".
      *** POTENTIAL INCOMPATIBILITY ***
    - Added library procedures tk_focusNext, tk_focusPrev, and
      tk_focusFollowsMouse.
    - Removed obsolete Tk_CreateFocusHandler:  must use FocusIn and
      FocusOut events now.
      *** POTENTIAL INCOMPATIBILITY ***

11/23/94 (new features) Overhaul of "send" command:
    - Added support for multiple displays: -displayof option to "send".
    - Added asynchronous sends: -async option to "send".
    - Eliminated fixed timeouts on sends:  as long as the target
      application appears to exist, the send will wait for it.
    - Stale entries get removed from the application registry now,
      so "winfo interps" should never return non-existent applications.
    - Can change the name of an application with "tk appname" command.
      This is also the preferred way of querying the application name
      now.
    - The errorCode and errorInfo variables are now propagated back to
      the sender now, so a full stack trace is available.
    - Tk checks display security on each send now, instead of just during
      initialization, so changes in the security status are seen immediately
      by all applications.
    - The above changes required changes to the data formats used for
      communication between source and target applications, so Tk 4.0
      applications cannot send to, or be sent from, Tk 3.6 applications.
      *** POTENTIAL INCOMPATIBILITY ***
    - The procedure Tk_RegisterInterp has been replaced with Tk_SetAppName.
      *** POTENTIAL INCOMPATIBILITY ***

12/6/94 (cleanup) Eliminated "interp" argument to Tk_GetColorByValue,
since it is no longer needed.
*** POTENTIAL INCOMPATIBILITY ***

12/7/94 (feature change) Changed the "wm" command so that top-level
windows are now resizable by default.  You can no longer specify
empty arguments to "wm maxsize" and "wm minsize".
*** POTENTIAL INCOMPATIBILITY ***

12/8/94 (new feature) Added new "photo" image type using code provided
by Paul Mackerras:  currently supports only PPM "P6" format images.

12/14/94 (new features) Canvas modifications:
    - Modified the interfaces between generic canvas code and the item
      types so that it's easy for people to write new item types outside
      of Tk.
    - Added support for transparent bitmap items:  just specify an
      empty string as the background color.
    - Changed the "xview" and "yview" commands for canvases to use the
      new scrolling syntax.
    - Eliminated -scrollincrement option.
      *** POTENTIAL INCOMPATIBILITY ***

12/14/94 (bug fix) Fixed bug where the dimensions of canvas arrowheads
scaled during a "scale" widget command, but the scaling was only
temporary and got lost on the next re-configure of the item.  The
correct behavior is for the arrowheads not to scale.

-------------------- Release 4.0b1, 12/23/94 -------------------------

12/26/94 (bug fix) Removed obsolete demos from Makefile (color, dialog,
size), fixed "install" target.

1/3/95 (bug fix) Fixed all procedure calls to explicitly cast arguments:
implicit conversions from prototypes don't work when compiling under
non-ANSI compilers.  Tk is now clean under gcc -Wconversion.

1/4/95 (bug fix) Used "screenX" without ever setting it in DisplayText
in tkCanvText.c:  caused tabs in canvas text items to get messed up.

1/4/95 (bug fix) Canvases forgot to register the built-in types if
Tk_CreateItemType was called before a canvas widget was created.

1/4/95 (bug fixes) Fixed glitches in various text bindings:
    - Up used to do nothing if the cursor was at 2.0.
    - Right used to make the cursor invisible if it was just before
      the final newline of the text.
    - Control-t didn't conform to Emacs;  made it conform to GNU Emacs.
    - Deleted Control-x binding, since it doesn't conform to anything and
      is confusing for Emacs users.

1/4/95 (bug fixes) Changed Control-t for entries just as for texts (see
above) an deleted Control-x for entries (see above).

1/4/95 (bug fix) The packer didn't map slaves unless the master was mapped;
this could cause slaves to get "lost" so that they weren't mapped until the
master resized.

1/5/95 (bug fix) Scrollbars weren't executing the proper code the first time
the mouse entered the widget;  this caused problems if tk_strictMotif was
set.

1/6/95 (bug fix) Fixed label/button/checkbutton/radiobutton/menubutton
widgets to allow arbitrary screen distances when specifying -width and
-height for an image or bitmap (the manual pages already documented this
but the code didn't implement it).

1/6/95 (new feature) Added very primitive support for input methods,
as suggested by Martin Forssen.  This should be enough for European
character sets (Compose key) but it isn't near enough for Asian
character sets.

1/8/95 (bug fix) Fixed problem in canvas "xview" and "yview" commands
where divide-by-zero errors could sometimes occur.

1/8/95 (bug fix) New event handler didn't properly handle files for
which both TK_READABLE and TK_WRITABLE were specified.

1/11/95 (bug fix) Fixed bug with text selections:  was returning count
too high for data, causing bogus garbage to appear when selection was
copied.

-------------------- Release 4.0b2, 1/12/95 -------------------------

1/27/95 (feature removal) Removed %D substitution from binding scripts:
wasn't portable, shouldn't be used anyway.
*** POTENTIAL INCOMPATIBILITY ***

1/27/95 (new features) Added -displayof options to the commands
"winfo atom", "winfo atomname", "winfo containing", "winfo interps",
and "winfo pathname".

1/27/95 (new feature) Added "idle" option to "after" command to run
scripts as idle handlers.

1/28/95 (new feature) Modified placer to make -x and -relx additive
if you specify both.  Same for -y and -rely, -width and -relwidth,
and -height and -relheight.  This makes it easy to make request such
as "make .a 2 pixels larger than .b".
*** POTENTIAL INCOMPATIBILITY ***

1/28/95 (new feature) Improved auto-grab mechanism in canvases (which
prevents current item from changing while a button is down):  changed
to report Enter and Leave events for the current item while a button
is down.  However, as before, no Enter events are reported for other
items until the button goes up.

1/28/95 (new feature) Bitmap images are now transparent if the -background
is specified as an empty string (-maskdata and -maskfile are ignored in
this case).  This is also the default.

1/28/95 (bug fix) Tk didn't support manufacturer- or site-specific keysyms
such as SunAudioMute.  Modified tkBind.c so that it uses XStringToKeysym
in addition to its own hash table, so that all keysyms are now available.

1/30/95 (feature change) Modified "clipboard append" so that it reclaims
the clipboard selection if it had been previously lost, rather than just
generating an error.  This handles certain race conditions more cleanly,
and also allows the use of programs like "xclipboard".

1/30/95 (new feature) Added -xscrollincrement and -yscrollincrement
options to canvases.

1/31/95 (bug fix) Geometry management was broken if a particular geometry
manager claimed a slave away from itself.

1/31/95 (bug fix) Fixed bug in tkVisual.c where a visual with fewer bits
than requested was being selected in preference to one with just the right
number of bits.

1/31/95 (bug fix) Texts weren't redisplaying the padding region properly
after changes in -padx or -pady.

1/31/95 (new features) More text improvements:
    - Extended "insert" widget command for texts to allow multiple
      text-tagList pairs in the same command.
    - Added -nocase option to "search" widget command.
    - Added -overstrike option to tags.
    - Added tab stops, via -tabs option for widget and for tags.

2/10/95 (bug fix) Modified all widgets to allow renaming of widget
commands.  Deleting a widget command will delete the widget.

2/11/95 (new feature) Added -highlightbackground option to all widgets.

2/14/95 (new feature) Added "insert" widget command for menus.

2/15/95 (new feature) Modified text display code (for all widgets) to
display well-known control characters like newline and backspace as
\n or \b instead of \xa.

2/15/95 (bug fix) Modified bitmap and photo image managers to delete
the image command when the image is deleted.  Also modified them to
allow renaming of the image command, and to delete the image if the
image command is deleted.

2/15/95 (bug fix) Fixed text widgets to allow horizontal scrolling
even if wrapping was enabled, if a line isn't entirely visible due to
a large character or embedded window.

2/16/95 (feature change) Added "postcascade" widget command to menus,
changed "invoke" and "activate" not to post or unpost submenus.  Also
fixed bug in redisplay that tended to leave bits of garbage on menu
when submenu unposted.
*** POTENTIAL INCOMPATIBILITY ***

2/16/95 (feature removal) Removed "snap back" behavior (slider
snaps back to old position if you move the mouse outside the widet
before releasing the button) from scrollbars and scales.

2/16/95 (bug fix) The last line of a listbox wasn't being displayed if
it was only partially visible.

2/16/95 (new features) Added support for "-resolution 0" (no rounding
of values) to scale widgets, plus smarter computation of how many digits
to display.

2/17/95 (bug fix) Fixed bug in text bindings for things like Shift-Left:
didn't properly set the anchor position.

2/20/95 (bug fix) Changed management of COLORMAP_WINDOWS property to
add the toplevel implicitly to the end of the list if it wasn't already
on the list somewhere.  Without this, some window managers implicitly
put it at the front of the list, so that colormaps in internal windows
are never used.

2/20/95 (bug fix) Changed to use separate command procedures for
button, checkbutton, label, and radiobutton commands.  This allows the
class commands to be renamed without breaking their behavior.

2/20/95 (removed feature) The "bind" command no longer supports
"Keymap" events;  they never worked anyway.

2/20/95 (bug fix) The text "search" widget command looped infinitely
when searching an empty text.

2/20/95 (bug fix) Canvases weren't redrawing their borders after
configuration changes.

2/20/95 (upgrade) Changed to use autoconf version 2.2.

2/21/95 (bug fix) Fixed several bug fixes in menu bindings that occur
when menus have no entries.

2/21/95 (bug fix) Fixed bug in geometry management that caused windows
packed -in siblings to not always be mapped and unmapped properly
(particularly when the toplevel got unmapped and mapped).

2/22/95 (bug fix) Fixed resource leak problem in tkTextDisp.c that
caused embedded windows not to be unmapped when off-screen.

2/23/95 (bug fix) "After cancel" dumped core when the script for an
after event cancelled itself.

2/24/95 (bug fix) Text and entry widgets weren't properly ignoring
Alt-, Control-, and Meta- keystrokes, so a widget-specific binding
for one of these resulted in the character also being inserted.

2/24/95 (bug fix) Several widgets accidentally performed unsigned
division on negative numbers, thereby losing the sign bit.  This
mostly affected the display of images and bitmaps in buttons,
menubuttons, and messages.

2/24/95 (feature reversal) Restored old behavior of %A so that it
returns non-printing characters as well as printing ones now.
*** POTENTIAL INCOMPATIBILITY with Tk 4.0b2, but not with Tk 3.6 ***

2/24/95 (bug fix) Duplicate "leave" events could occur for canvas
items under some conditions, due to recursive calls to PickCurrentItem.
Added code to detect and skip the nested calls.

2/24/95 (bug fix) Fixed bug where an error could occur during the first
keystroke in an application if its binding invoked "break".

2/25/95 (new feature) Modified syntax of "search" widget command for
texts.  The -nowrap switch and the "variable" final argument are no
longer supported.  Instead, there is a -count switch to replace
the final argument;  if the final argument is specified, it is now
a stopping index for the search.  The features of -nowrap can be
achieved now with the stopping index.
*** POTENTIAL INCOMPATIBILITY with Tk 4.0b2, but not with Tk 3.6 ***

2/27/95 (bug fix) Fixed problem that appears to prevent keyboard
input for working under IRIX:  tkBind.c was ignoring XmbLookupString
calls that returned a status of XLookupBoth.

2/27/95 (new feature) Added Tk_GetItemTypes procedure to return
information about available canvas item types.

2/27/95 (feature change) Changed Makefile to always use install-sh
for installations:  there's just too much variation among "install"
system programs, which makes installation flakey.

2/27/95 (bug fix) Fixed bug in tkSend.c that caused core dumps if
the app's main window was destroyed by a destroy handler on a
child.

3/5/95 (feature change) Change separator character used in "bind +..."
bindings from semi-colon to newline (permits bindings that are
comments, for what that's worth).

3/7/95 (bug fix/feature change) Overhauled focus code, both in C
and in Tcl:
    - Tk won't move the X focus in response to the "focus" command
      unless either the application already has the focus or the
      -force switch is specified.
    - Tk no longer sets the X focus to anything other than top-levels;
      it synthesizes events for FocusIn and FocusOut to children.
    - A window no longer has to be viewable when focussed to;  Tk will
      set the X focus later, when the window becomes viewable.
    - Added -takefocus option to all widgets.
    - Rewrote tk_focusPrev and tk_focusNext to use the -takefocus option.
      These procedures no longer set the focus;  they just return the
      next window in focus order.
      *** POTENTIAL INCOMPATIBILITY with Tk 4.0b2, but not with Tk 3.6 ***
    - Eliminated tk_focusContinue.
      *** POTENTIAL INCOMPATIBILITY with Tk 4.0b2, but not with Tk 3.6 ***

3/8/95 (new feature, bug fix) Added support for tk_strictMotif variable
in C:  Tk_StrictMotif library procedure.  Modified buttons, menubuttons,
menus to use it.  This fixes the problem with menus not supporting
tk_strictMotif properly in Tk4.0b1 and b2.

3/16/95 (feature overhaul) Overhauled color management:
    - Changed Tk so it never denies a color request because a colormap
      filled up.  Instead, it allocates the closest available color.
    - Eliminated "color model" mechanism.  The "tk colormodel" command
      is gone, as are the procedures Tk_GetColorModel and Tk_SetColorModel.
      *** POTENTIAL INCOMPATIBILITY ***
    - Changed 3D border implementation to allocate colors for shadows
      lazily, so they're never allocated if they're never used.  Also
      added new feature whereby stippling is used for borders when
      the colormap has run out of entries.  Changed arguments to many
      of Tk_3D C procedures to take a Tk_Window as argument instead of
      a (Display *).  This is needed to do lazy color allocation.
      *** POTENTIAL INCOMPATIBILITY ***
    - Eliminated colormap argument to Tk_GetColor, Tk_GetColorByValue,
      and Tk_Get3DBorder.
      *** POTENTIAL INCOMPATIBILITY ***

3/16/95 (feature change) Event bindings created from Tcl will now ignore
Enter, Leave, FocusIn, and FocusOut events with detail NotifyInferior.
This is done in anticipation of mega-widgets, so that the user of a
mega-widget can create Enter/Leave bindings on the mega-widget without
seeing spurious events as the mouse moves among the windows in the
mega-widget.
*** POTENTIAL INCOMPATIBILITY ***

3/17/95 (feature change) Changed C interfaces throughout Tk to use ints
instead of unsigneds:  the unsigneds turn out to cause subtle problems
with arithmetic in some places, and using ints everywhere is just
simpler.
*** POTENTIAL INCOMPATIBILITY ***

3/23/95 (bug fix) Selections longer than 4000 bytes were being
truncated to 4000 bytes.

-------------------- Release 4.0b3, 3/24/95 -------------------------

3/25/95 (bug fix) Changed "install" to "./install" in Makefile so that
"make install" will work even when "." isn't in the search path.

3/25/95 (bug fix) Modified Tk's selection mechanism to prevent core
dumps in other applications during retrievals of large selections
(this is actually a bug in the other apps, but I've patched Tk to
keep it from getting triggered).

3/25/95 (bug fix) Fixed bug where X window for "." wasn't being
deleted.

3/27/95 (bug fix) Fixed many bugs associated with having more than
one application in a single process.

3/28/95 (bug fix) The "search" widget command for texts didn't
return the correct index and count if there were embedded widgets
on the same line as the returned range but before the end of
the range.

3/28/95 (bug fix) Changed pasting via button 2 in text and entries
so that it inserts at the pointer location, not the location of
the insertion cursor.

3/28/95 (bug fix) Fixed several bugs related to <Destroy> bindings
that delete ancestors in the window hierarchy.  Also eliminated
extraneous calls to XDestroyWindow, which speeds up window deletion
by about 3x.

3/28/95 (bug fix) Several widgets (buttons, menubuttons, menus) didn't
properly handle image deletions that occurred while the widget was
being deleted (caused core dumps).

3/29/95 (bug fix) When retrieving long selections from text widgets,
parts of lines were getting duplicated in the selection information.

4/1/95 (bug fix) Fixed bug that caused infinite loop in horizontal
scales with 0 range.

4/1/95 (bug fix) Fixed problem with -command option for scrollbars and
-takefocus option that caused commands to be evaluated in the wrong
context.

4/1/95 (bug fix) Fixed problem with option database that caused it to
sometimes use the wrong option (wasn't flushing the database properly
after a change in a window's class).

4/1/95 (bug fix) If a line in a text widget just barely fit in the window,
Tk was allocating a second screen line just for the newline character.

4/1/95 (new feature) When backspacing in an entry widget, when you reach
the left edge of the widget, the insertion cursor gets recentered.

4/1/95 (new features) Added "winfo pointerx" and "winfo pointery" commands
to fetch the current pointer position.

4/6/95 (bug fix) If the last line of a text widget was only partially
visible, it was counted as visible for purposes of the scrollbar.  Now
it is treated as if it were off-screen for scrolling purposes.

4/6/95 (new feature) Modified "bell" command to reset screen saver as well.

4/6/95 (feature change) Modified menu scanning (where menus pull down
as you drag across their menubuttons) so it only works among menus
in the same toplevel;  it used to work for any menubuttons in the
application.

4/6/95 (bug fix) Canvas text items weren't allowing real numbers in
"@x,y" notation for specifying indices.

4/7/95 (bug fix) Menus didn't display correctly when -activeborderwidth
was large.

4/7/95 (bug fix) Changed "clipboard append" command to support -- option
and to always treat the last argument as data, even if it starts with
"-".

4/17/95 (new feature) Added -wrap option to text tags.

4/18/95 (bug fix) Listboxes and texts weren't updating their grid information
when -width or -height changed.

4/18/95 (bug fix) "Down" didn't work right in text widgets if the last
line was only partially visible in the window.

4/19/95 (bug fix) Listboxes didn't handle partially visible last lines
right:  couldn't scroll it into full visibility, for example.

4/20/95 (bug fix) If a toplevel was positioned with a command like
"wm geometry . -0-0", the window didn't reposition itself to maintain
that geometry after a size change.

4/21/95 (feature change) Changed order of binding tags so widget bindings
fire before class bindings.  New order is: widget, class, toplevel, all.
*** POTENTIAL INCOMPATIBILITY with Tk 4.0b3, but not with Tk 3.6 ***

4/23/95 (new feature) Added "winfo colormapfull" command.

4/23/95 (new feature) Buttons and radiobuttons and checkbuttons now
treat Return the same as Space, unless tk_strictMotif is set.

4/23/95 (bug fix) Modified menu tear-off procedure to duplicate the
binding tags and bindings of the original in the copy.

4/25/95 (bug fix and feature change) Modified mechanism for choosing
"best" visual to fix a bug where depth wasn't really getting highest
priority in all situations.

4/28/95 (bug fix) Failed text searches starting at "end" could result
in an infinite loop in Tk.

4/30/95 (new feature) Added "wm resizable" command to enable and
disable interactive resizing.

4/30/95 (new feature) Added "window names" widget command to texts:
returns a list of all embedded windows.

5/2/95 (feature change) Changed text searches so that forward searches
start at the given index, rather than the character just after the
given index.
*** POTENTIAL INCOMPATIBILITY with Tk 4.0b3, but not with Tk 3.6 ***

5/4/95 (bug fix) Default bit gravity for windows was wrong (it was
ForgetGravity) causing unnecessary flashing when windows were resized.

5/4/95 (feature change) Modified Tk_DoOneEvent so that it doesn't
sleep if there's nothing that will wake it up again (e.g. no file
or timer handlers).  Returns 0 immediately.

5/5/95 (configuration change) Changed to use BSDgettimeofday instead
of gettimeofday on systems like IRIX where BSDgettimeofday is
available.  This avoids compilation problems due to the different
interface to gettimeofday provided by IRIX.

5/5/95 (feature change) Changed binding mechanism so that all bindings
are created immediately at initialization time, rather than waiting
until the first FocusIn or Enter event for a class.

5/6/95 (feature change) Changed default text for labels, buttons,
checkbuttons, radiobuttons, menubuttons, and messages from " " to
"".

5/6/95 (bug fix) If the application was destroyed in the middle of
an "update" command, Tk would dump core.

5/6/95 (bug fix) Changed manual entries to use the standard .TH
macro instead of a custom .HS macro;  the .HS macro confuses index
generators like makewhatis.

5/6/95 (bug fix) Change "wm iconwindow" command to disable button
presses for the icon window.  This is needed so that the window
manager can get those events (X only allows button presses to go
to one client for a given window).

5/9/95 (new feature) When specifying visuals, can now use "best"
with a depth, e.g. "-visual {best 8}" to get the best 8-bit visual.

5/18/95 (bug fix) Fixed bug with -spacing* options for text widget:
screen distances weren't allowed, only integers.

5/20/95 (bug fix) Eliminated memory leaks in tkTextDisp.c and elsewhere.

5/22/95 (color change) Changed the Tk color palette to a gray scheme.
Also added a library procedure tk_setPalette that makes it easy to
change colors on the fly, and a procedure tk_bisque that restores the
previous light brown scheme.

5/28/95 (bug fix) Modified canvases so that the -width and -height
options refer to the space inside the borders, not the total widget
space.  Also changed "xview" and "yview" commands and scroll-increment
rounding to use the pixel just inside the borders, rather than (0,0).

5/28/95 (bug fix) Several widgets (e.g. entries, buttons, and menus)
didn't properly handle unsets of variables they were tracing, if the
variables were reference through upvars in procedures.

6/4/95 (bug fix) The placer wasn't rounding window widths right when
both -relx and -relwidth were specified (or -rely and -relheight) so
that rounding errors accumulated.

6/4/95 (feature improvement) Change parsing of text indices to handle
weird mark and tag names better (e.g. any string ending with ".first"
will now be parsed as a tag name, even if it contains embedded spaces,
etc.).

6/4/95 (feature change) If a font defines glyphs for control characters,
they are now displayed, instead of translating the character to a
backslash sequence (however, tabs and newlines are still treated
specially;  glyphs are not displayed for these characters).

6/4/95 (bug fix) Modify the implementation of "raise" and "lower" for
toplevels so that it now works under olwm and olvwm.  It didn't use to
work, and the problem is really in the window manager, but Tk now
patches around it.  However, only "total" raises and lowers work:
raising and lowering relative to a sibling still don't work under
olvwm and olwm.

6/4/95 (feature change) Modified tab code in texts so that a tab always
occupies at least as much space as a space character.

6/4/95 (bug fix) The "%t" substitution wasn't being made properly in
Enter and Leave event bindings.

6/7/95 (new feature) Added support for GIF images.  Unfortunately it's
a bit fragile:  certain kinds of badly formed images can cause core
dumps;  I don't know enough about the GIF reader (taken from giftoppm)
to figure this out.

6/7/95 (bug fix and feature change) Fixed PPM image reader to be more
flexible about header formats, and added support for PGM images.

6/7/95 (feature change) Added -outlinestipple option to canvas arc
items, changed "-style arc" to use -outline as the color instead of
-fill (the old approach was pretty quirky).
*** POTENTIAL INCOMPATIBILITY ***

6/8/95 (feature change) Modified interface to Tk_Main to pass in the
address of the application-specific initialization procedure.
Tcl_AppInit is no longer hardwired into Tk_Main.  This is needed
in order to make Tcl a shared library.

6/8/95 (feature change) Modified Makefile so that the installed versions
of wish and libtk.a have version number in them (e.g. wish4.0 and
libtk4.0.a) and the library directory name also has an embedded version
number (e.g., /usr/local/lib/tk4.0).  This should make it easier for
Tk 4.0 to coexist with earlier versions.

6/9/95 (new feature) Added -outline and -width options to canvas polygon
items.

6/9/95 (feature changed) Renamed -decimate in photo widget to -subsample
(decimate wasn't technically correct).
*** POTENTIAL INCOMPATIBILITY with Tk 4.0b3, but not with Tk 3.6 ***

-------------------- Release 4.0b4, 6/16/95 -------------------------

6/19/95 (bug fix) Colors weren't being rounded correctly in canvas
Postscript generation: caused "white" to appear slightly gray when
the display of the canvas used only 8 bits per color.

6/20/95 (bug fix) "bbox" widget command for texts didn't return
proper width for tabs.

6/20/95 (bug fix) Scrollbars didn't always work right for texts:
couldn't scroll all the way to the bottom of the text in a single
drag of the slider.

6/20/95 (new feature) Added "delta" widget command for scrollbars
(needed for above bug fix).

6/23/95 (bug fix) Listboxes weren't properly redisplaying their
borders when the were configured to a smaller size.

6/23/95 (new feature) Added "winfo server" command.

6/23/95 (bug fix) If a menu was posted, couldn't switch to another
menu with an Alt- key.

6/24/95 (new feature) Added "winfo pointerxy" command.

6/25/95 (bug fix) Tk_ParseArgv referenced beyond the end of 0-length
option names.

6/25/95 (bug fix) Fixed problem in tkOption.c where "cachedWindow"
could get garbage in it if the main window's class was changed by
calling Tk_SetClass.

6/25/95 (bug fix) Fixed two bugs in menus, one where errors in
variable traces weren't propagated correctly and one where "invoke"
was invoked at the wrong stack level, with the result that variable
traces didn't have access to the right variables.

6/27/95 (bug fix) tk3d.c wasn't using all the right information
when deciding whether or not to stipple borders, so it stippled
borders even on 16-bit true-color displays.

6/28/95 (bug fix) Page up and down operations in texts could cause
insertion cursor to drift to the right.  Changed tkTextScrollPages
to use upper-left corner of current character, rather than center
of character.

6/28/95 (bug fix) Changed text widget so that you can't put the
insertion cursor after the last newline in the text.

6/28/95 (bug fix) Bitmap images didn't allow ~'s in file names.

6/28/95 (bug fix) Fixed problem that could cause core dumps in the
text widget when dealing with embedded windows (there were problems
if the act of redisplaying caused the window layout to change, which
can happen with embedded windows).

6/28/95 (bug fix) Texts didn't handle indices with double negatives,
such as ".t mark set insert {insert + -20 chars}".

6/28/95 (bug fix) Fixed problem where focus didn't always revert to
its prior window after a dialog box was dismissed.

6/28/95 (bug fix) Fixed problem with "search" widget command returning
incorrect length on some backwards regexp searches.

6/28/95 (bug fix) Successive "wm iconbitmap . {}" commands could cause
a core dump.

6/29/95 (new feature) Added -elementborderwidth option for scrollbars
so the -borderwidth can be set to 0 without flattening the arrows and
slider.

-------------------- Release 4.0, 7/1/95 -------------------------

7/18/95 (bug fix) %t in event bindings didn't work properly for some
events (e.g. PropertyNotify).

7/18/95 (bug fix) Changed "exec wish" lines in demo scripts to
"exec wish4.0" to avoid version conflicts.

7/18/95 (bug fix) Fixed round-off errors in scrolling for texts,
canvases, listboxes, and entries.  The error could cause the view
to shift up in a command like "$w yview moveto [lindex [$w yview] 0]".

7/19/95 (bug fix) Canvases weren't always redrawing borders correctly
when they became unobscured.  There were also some problems with
improper refresh after size changes.

7/19/95 (bug fix) Fixed bug in text index processing that causes
tests textIndex-11.1 and textIndex12.1 to fail on some platforms.

7/19/95 (bug fix) Fixed bug where 2-second delays were ocurring during
"raise" and "lower" commands for toplevel windows under some window
managers (such as fvwm).

7/20/95 (bug fix) Text searches were misbehaving when there were embedded
windows on the starting line of the search.  The most common symptom is
that Tk would fail to find a match at the starting position for the
search.

7/22/95 (bug fix) Fixed core dump that could occur in menus if a checkbutton
entry's -variable option referred to an array (or couldn't be read
by the menu C code for some other reason).

7/22/95 (bug fix) Text widgets didn't update their scrollbars when
changes were made to information that was off-screen.

7/25/95 (bug fix) Fixed core-dump in tkListbox.c that used to happen
in the command ".l bbox end" if the listbox was empty.

7/25/95 (bug fix) Page-up and page-down bindings for listboxes didn't
move active element to remain on the screen.

7/25/95 (bug fix) Patched around H-P compiler problem that results in
core-dumps in tkImgPhoto.c during image handling.

7/25/95 (bug fix) Fixed bug in tkImgPhoto.c that caused core dumps
(during Tk self-tests and other image uses) on AIX and other machines
where "schar" in tkImgPhoto.c was being defined as "short" instead of
"char".

7/26/95 (bug fix) The PPM image reader couldn't handle maximum intensity
values other than 255.

7/26/95 (bug fix) Canvases didn't redraw their borders when the relief
changed from raised to flat.

7/27/95 (bug fix) Canvases didn't set the scrolling values correctly
when no scroll region was specified.

7/28/95 (bug fix) Modified menu and tk_dialog scripts to restore any
old grab that might have been in effect before a menu or dialog was
posted.

----------------- Released patch 4.0p1, 7/29/95 ----------------------

8/4/95 (bug fix) Calls to toupper and tolower weren't using the UCHAR
macro, so they didn't always work in non-U.S. locales. (JO)

8/14/95 (new feature) Added -tearoffcommand option for menus.

8/16/95 (bug fix) Canvases didn't generate proper Enter and Leave
events if the Leave handler for an item reconfigured the canvas in
a way that made the old current item the new current item again. (JO)

8/21/95 (bug fix/feature change) When -takefocus was a script, Tk
was allowing window viewability to override it.  Changed so that
viewability is now ignored when -takefocus is a script. (JO)

8/21/95 (bug fixes) Fixed memory leaks in tkSend.c, tkSelect.c, and
tkUnixWm.c (JO).

8/21/95 (bug fix) Text widgets didn't handle commands like
".t search -backwards foo end 1.0" properly:  never found foo. (JO)

8/23/95 (new feature) Added Makefile and configure.in support for
dynamic loading. (JO)

8/25/95 (bug fix) The "frame" and "toplevel" commands couldn't safely
be renamed, due to a kludgy way that they shared a single command
procedure.  Split into separate procedures. (JO)

8/25/95 (bug fix) Fixed bug in libary/menu.tcl that caused "grab
window not visible" errors for popup menus (and perhaps elsewhere?). (JO)

8/25/95 (bug fix / new feature) The "gray25" bitmap was really only
12.5% on, not 25%.  Added new "gray12" bitmap that is the same as the
old "gray25".  "Gray25" is still supported for compatibility, but its
use is deprecated. (JO)

8/25/95 (bug fix) Scrollbar bindings didn't properly handle case where
B2 is clicked while B1 is already down. (JO)

8/26/95 (bug fix) Menus were ignoring -activebackground if tk_strictMotif
was set, but not -activeforeground.  Changed to ignore both. (JO)

8/26/95 (bug fix) Scales and scrollbars didn't properly handle a
-repeatdelay value of 0 (they shouldn't auto-repeat in this case). (JO)

8/28/95 (bug fix) Tcl errors were occurring for tkPriv(oldGrab) when
clicking on a disabled option menu. (JO)

8/28/95 (bug fix) Changed event-handling code to use FD_SETSIZE instead
of OPEN_MAX, since OPEN_MAX is incorrect on some systems (e.g., IRIX). (JO)

8/28/95 (bug fix) Fixed bug in photo images that caused garbling of
image data in the "put" and "copy" commands if the source data had
only one scan line but had a width less than the width of the target
image. (JO)

8/29/95 (bug fix) Tk used to refuse to post menus if they had no
entries.  This made it impossible for a menu to fill itself the first
time it is posted.  Changed to allow menus with no entries to be
posted. (JO)

8/30/95 (bug fix) If there was extra space at the bottom of a menu,
it wasn't being redisplayed properly.

8/30/95 (new feature) Added -transient option to menus.

8/30/95 (new features) Added proper button 2 support to both scrollbars
and scales (it sets the slider position from the mouse position). (JO)

8/30/95 (bug fix) Fixed potential core dump that could occur in
photo images (ReadPPMFileHeader could overflow buffer under some bad
inputs, such as certain GIF images). (JO)

8/30/95 (bug fix) Errors of the form `syntax error in expression "!"'
could occasionally happen in tkScaleDrag. (JO)

8/31/95 (new feature) Changed man page installation (with "mkLinks"
script) to create additional links for manual pages corresponding to
each of the procedure and command names described in the pages. (JO)

9/1/95 (new feature) Added "after info" command.  Also added checks
so that one interpreter can't cancel another's "after" events. (JO)

9/8/95 (bug fix) Fixed bug that could cause memory corruption and core
dumps if a "fileevent" handler was deleted while the handler was
active. (JO)

9/11/95 Reorganized Tk sources for Windows and Mac ports.  All sources
are now in subdirectories:  "generic" contains sources that work on all
platforms, "windows", "mac", and "unix" directories contain platform-
specific sources.  (SS)

9/11/95 (new feature) Added new  "notifier" mechanism to allow multiple
implementations of the mechanisms for finding out about events.  This
change was necessary to support Mac and PC platforms, but it may also
allow other goodies such as combining Xt and Tk widgets in a single
application.  See the new manual entry Notifier.3 for details. (SS)

9/11/95 (feature change) Changed interface to Tk_RestrictProc so that
(a) it takes a clientData argument instead of display and arg, and
(b) it returns a value that can ask for the event to be discarded as well
as deferred or processed. (SS)
*** POTENTIAL INCOMPATIBILITY ***

9/11/95 (new feature) Added TK_WINDOW_EVENTS #define, which is equivalent
to TK_X_EVENTS but is now preferred, since it applies to all platforms. (SS)

9/11/95 (feature change) Can't export variables anymore because this doesn't
work under Windows DLLs.  Eliminated tk_NumMainWindows variable and replaced
with procedure Tk_GetNumMainWindows. (SS)
*** POTENTIAL INCOMPATIBILITY ***

9/11/95 (new feature) Added procedure Tk_PreserveColormap to increment
the reference count on colormaps.  Used in photo widgets. (SS)

----------------- Released patch 4.0p2, 9/15/95 ----------------------

----------------- Released 4.1a1, 9/15/95 ----------------------

9/22/95 (renamed files) Changed the names of the bitmap images in the
$tk_library/demos/images directory to use the .bmap file extension.  (RJ)

9/22/95 (bug fix) Fixed bug where text widgets could occasionally
display the insertion cursor both at the end of one line and the
beginning of the next. (JO)

9/25/95 (bug fix) Fixed bug that could cause core dumps when an
application uses multiple screens and a binding destroys the main
window (bind code was using MainInfo structure after it had been
freed). (JO)

9/25/95 (bug fix) Text widgets sometimes scrolled backwards on
occasion if you dragged down past the bottom of the scrollbar. (JO)

9/25/95 (bug fix) Fixed bug in menus where a cascaded submenu posted
from a torn-off menu could be left posted if mouse was pulled off the
end of the cascade and released. (JO)

9/25/95 (new feature) Added "--" switch to wish, so that you can
pass arguments like -n through to a script without having wish
interpret them. (JO)

9/25/95 (bug fix) Fixed core dump that could occur for radiobuttons
and selectbuttons if -selectcolor was an empty string. (JO)

9/26/95 (bug fix) Entries didn't used to notice if a trace procedure
on the -textvariable overrode a new value set by the entry.  This
could cause the variable to get out of sync with the contents of the
entry. (JO)

9/26/95 (new feature) Added -sliderrelief option to scales, changed
default bindings to change the slider's relief to sunken while it's
being dragged with the mouse. (JO)

9/26/95 (bug fix) TkColor.c wasn't computing colormap size correctly;
could result in X Protocol error for QueryColors when colormaps run
out of colors. (JO)

9/26/95 (bug fix) Wish couldn't handle script files with spaces in
their names. (JO)

9/27/95 (cosmetic clean-up) Removed extraneous spaces to make error
messages consistent: ":  should be" is now ": should be". (JO)

9/27/95 (feature change)  Modified tk_dialog so that it uses the
option database for the -wraplength option on the message.  This
allows the option to be overridden by the caller. (JO)

9/28/95 (bug fix) Wish incorrectly parsed the command line under
Windows, causing backslashes to be substituted. (SS)

9/28/95 (bug fix) Wish now sources wishrc.tcl instead of .wishrc. (SS)

9/28/95 (bug fix) Tk_DoOneEvent returned 0 under some circumstances
when it was possible to find more work to do.  For example, if a
signal interrupted select(), but no event handlers were triggered, it
would return 0 even though it could still detect events by reentering
select().  (SS)

9/29/95 (bug fix) "winfo interps" caused a crash under Windows. (SS)

10/1/95 (feature change) Eliminated Tk_NotifyIdle interface in favor of
Tk_IdlePending. (SS)

10/1/95 (bug fix) Turned motion event collapsing into an idle handler
so it will be easier to move the event loop into Tcl. (SS)

10/1/95 (bug fix) Fixed several problems with negative coordinates
in canvases.  One example:  dragging a canvas rectangle with a wide
border and fractional coordinates could leave junk on the screen
if the rectangle was in negative coordinate space. (JO)

10/2/95 (bug fix) Tk was improperly handling Enter/Leave events
during a button grab. (SS)

10/2/95 (new feature) Added support for the Macintosh do script
('dosc') event.  Available only on the Macintosh.  (RJ)

10/4/95 (new feature) Added support for compiling with VC++.
Resulting binaries work under Win32s through NT.

----------------- Released 4.1a2, 10/6/95 ----------------------

10/10/95 (new feature) Macintosh Tk now supports the complete set
of X cursors that Unix Tk supports. (RJ)

10/11/95 (bug fix) Tk now supports all of the X11 cursors under
Windows.  (SS)

10/11/95 (bug fix) The "wm resizable" command was missing from the
Windows version of Tk. (SS)

10/12/95 (bug fix) Macintosh Tk had problems with clipping toplevel
windows that children of any frame other than another toplevel. (RJ)

10/13/95 (bug fix) Eliminated dependency on MKS toolkit for generating
the tk.def file from Borland object files. (SS)

10/16/95 (bug fix) Fixed clipping and update problems relating to
the raising and lowering of overlapping windows on Mac. (RJ)

10/30/95 (bug fix) When focus-follows-mode (invoked via tk_focusFollowsMouse),
was focussing on windows even in situations where keyboard traversal would
skip the window.  Changed to use the tkFocusOK procedure so that the
criteria for focussing are the same in both modes. (JO)

11/2/95 (bug fix) Changed listbox bindings to ignore double-clicks.
This avoids errors that used to occur if a user defined a binding
for double-click that deleted the listbox. (JO)

11/3/95 (feature change) Moved most of the Tk event loop to Tcl.  Many
Tk_ names have become Tcl names now:

TK_READABLE =>		TCL_READABLE
TK_WRITABLE =>		TCL_WRITABLE
TK_EXCEPTION =>		TCL_EXCEPTION
TK_DONT_WAIT =>		TCL_DONT_WAIT
TK_WINDOW_EVENTS =>	TCL_WINDOW_EVENTS
TK_FILE_EVENTS =>	TCL_FILE_EVENTS
TK_TIMER_EVENTS =>	TCL_TIMER_EVENTS
TK_IDLE_EVENTS =>	TCL_IDLE_EVENTS
TK_ALL_EVENTS =>	TCL_ALL_EVENTS
Tk_IdleProc =>		Tcl_IdleProc
Tk_FileProc =>		Tcl_FileProc
Tk_TimerProc =>		Tcl_TimerProc
Tk_TimerToken =>	Tcl_TimerToken
Tk_BackgroundError =>	Tcl_BackgroundError
Tk_CancelIdleCall =>	Tcl_CancelIdleCall
Tk_CreateFileHandler =>	Tcl_CreateFileHandler
Tk_CreateTimerHandler =>Tcl_CreateTimerHandler
Tk_DeleteFileHandler =>	Tcl_DeleteFileHandler
Tk_DeleteTimerHandler =>Tk_DeleteTimerHandler
Tk_DoOneEvent =>	Tcl_DoOneEvent
Tk_DoWhenIdle =>	Tcl_DoWhenIdle
Tk_Sleep =>		Tcl_Sleep
tkerror =>		bgerror

Other than the name changes, the functions are the same.  In addition,
there are #defines in tk.h so that the old Tk names will still work.
tkerror and bgerror are specially hacked as synonyms, so it should be
safe to use either one.  You should switch to the new Tcl names ASAP,
though, since the old Tk names will eventually be desupported. (JO)

11/7/95 (features removed) As part of moving the event loop to Tcl,
the following procedures were deleted:
    - Tk_EventInit (the presence of the event loop in Tcl should
      make this unneccessary).
    - Tk_CreatFileHandler2 (you can get the same effect by using event
      sources in Tcl, but you have to modify your code to use the new
      Tcl APIs).
    - All of the stuff in the manual entries Notifer.3 and QueueEvent.3;
      this has changed because the notifier got reworked when it was
      moved to Tcl.
*** POTENTIAL INCOMPATIBILITY ***

11/7/95 (feature change)  Changed to use exit handler to cleanup windows
in Tk, so Tk no longer needs to have a private copy of the "exit" command.
(JO)

11/7/95 (bug fix) If wish was invoked with a command-line geometry and
a script file (e.g. "wish foo.tcl -geometry 30x20"), and if one of
the windows created by the script used the -setgrid option, then the
width and height from the command line were lost. (JO)

11/8/95 (bug fix) The "see" command didn't work quite right for texts:
if the window was small and you try to "see" a line just offscreen,
Tk centered the line (actually, mis-centered it) when it should have
aligned it at the top or bottom. (JO)

11/9/95 (bug fix) The "send" command crashed if you tried to send to
a different display with "-displayof". (JO)

11/9/95 (bug fix) The Symbol font didn't print right in Postscript
output, because of changes made to re-encode fonts to get proper
ISO Latin1 behavior.  Changed the code not to re-encode the Symbol
font. (JO)

11/13/95 (bug fix) Fixed Makefile.in and configure.in for UNIX so that
configure can be run from a clean directory separate from the Tcl source
tree, and compilations can be performed there. (JO)

11/17/95 (bug fix) If a window was gridded, Tk still computed the
default maximum dimensions in pixel units, which resulted in windows
that could grow much larger than the screen. (JO)

11/17/95 (bug fix) If a menus entries were all disabled, posting
the menu and typing Up or Down caused an infinite loop, locking
up the screen (JO).

11/19/95 (bug fix) The focus wasn't being restored properly after a
menu selection in a cascaded menu. (JO)

11/19/95 (bug fix) Menubutton's didn't stipple display their images
differently when disabled.  Change to have the same behavior as buttons:
the image is stippled over in the background color when the menubutton
is disabled. (JO)

11/21/95 (bug fix) Changes in display attributes such as font could
cause core dumps in the text widget under some circumstances involving
line wrapping. (JO)

11/22/95 (bug fix/new feature)  Changed both the placer and the packer
to ensure that slaves are unmapped whenever the master is unmapped.
This saves time that slaves might otherwise spend trying to redisplay
themselves when they're unmapped. (JO)

11/22/95 (bug fix) Space and return keys didn't work for menus if
they were posted via Alt-x keystrokes. (JO)

11/24/95 (bug fix) tk_dialog procedure had binding for <Return> that
always activated default binding, even if input focus was in some
other binding.  Removed this feature, since existing focus support
will already "do the right thing".  (JO)

11/24/95 (bug fix) Both canvases and texts could dump core if a binding
(such as ButtonRelease on an internal item) deleted the widget. (JO)

11/24/95 (feature change) Replaced "configInfo" file with tkConfig.sh,
which is more complete and uses slightly different names.  Also
arranged for tkConfig.sh to be installed in the platform-specific
library directory. (JO)

11/24/95 (bug fix) It was possible for a slave to be placed or packed
-in itself, with unpleasant consequences.  It is now an error for the
slave to be its own master for geometry management. (JO)

11/25/95 (bug fix) The -command option of scales was sometimes being
invoked spuriously (e.g. when the mouse moved in the scale without a
button down).  This was because the scale wasn't rounding properly
when setting the scale value from its associated variable. (JO)

----------------- Released patch 4.0p3, 11/28/95 ----------------------

12/18/95 (feature change) Moved Tk_Preserve, Tk_Release, and
Tk_EventuallyFree to Tcl, renamed to Tcl_Preserve etc.  Added #defines
to tk.h so that the old names still work.  (JO)

12/23/95 (bug fix) If a single process had > 1 Tk application, Tk
didn't guarantee that the application names were unique, which could
cause all sorts of confusion with "send".  (JO)

12/23/95 (feature change) Eliminated Tk_CreateMainWindow and moved
all of its functionality to Tk_Init.  All that you need to do now
to get Tk in an application is to call Tk_Init.  Improved Tk_Init
so that -colormap and -visual command-line arguments are now passed
through to TkCreateFrame.  Tk_Main is much simpler now, since a lot
of its functionality has moved to Tk_Init. (JO)
*** POTENTIAL INCOMPATIBILITY ***

12/23/95 (new feature) Added support for Tcl_StaticPackage so
that Tk can now be loaded into slave interpreters with the "load"
command to create new applications. (JO)

12/23/95 (new features) Added support for -colormap and -visual command-
line options for wish. (JO)

1/4/95 (bug fix) Fixed keyboard code to properly handle alt-key
sequences for international keyboards and menu-accelerators. (SS)

1/5/96 (bug fix) Scrollbar code sometimes generated errors on accesses
to tkPriv(relief) during control-clicks. (JO)

1/9/96 (new feature) added the "grid" command to provide a table based
geometry manager. (SU)

1/12/96 (performance optimization) Changed the way tag information is kept
in the text's Btree so the cost of adding and removing tag ranges is no longer
proportional to the number of unique tags in the text.  In the old system
the cost of adding N unique tags was O(N-squared).  The new implementation is
optimized for tags that only cover a small amount of text, measuring from
their earliest tag range to the end of their last range.  In the best case the
cost of adding a tag range is unrelated to the number of unique tags, so the
cost of adding N tags is only O(N).  In the worst case, where all tags
cover all the text, the cost is still O(N-squared) to add N such tags.
Deleting tags still has an O(N) cost (so deleting N tags is O(N-squared),
but it is now a factor of 2 faster than the old system. (BW)

1/12/96 (new feature) added the text "dump" operation that returns information
about all elements in a text widget: text, tags, marks, and windows. (BW)

1/12/96 (new feature) added the text "mark next" and "mark previous" operations
to search forward and backwards for the next (previous) mark in the text. (BW)

1/12/96 (new feature) added the text "tag prevrange" operation to search
backwards for the current or previous range of a tag. (BW)

1/16/96 (new feature) Added support for relative widget placement on
the "grid" command. (SU)

1/17/96 (new feature) Modified the Makefile/configure setup to support
compiling Tk as a shared library.  Use the --enable-shared option to
the "configure" script. (JO)

----------------- Released 4.1b1, 1/26/96 -----------------------

2/2/96 (bug fix) Frames were getting a default size of 200x200, whereas
there should be no default. (JO)

2/2/96 (bug fix) Argc wasn't getting reset properly after Tk removed
the arguments it understood from those on the command line. (JO)

2/6/96 (bug fix) Fixed off by one error in argument parsing code under
Windows. (SS)

2/6/96 (bug fix) "wm transient" now works under Windows.  The resulting
toplevel is created with a modal dialog box frame and will not appear
in the taskbar under Windows '95. (SS)

2/9/96 (bug fix) Changed Makefile.in to use -L and -l for Tcl and Tk
libraries so that shared libraries are more likely to be found correctly
on more platforms. (JO)

2/14/96 (feature change) Eliminated tk_CanvasTagsOption variable because
it can't be exported safely across DLL boundaries.  Instead, exported
Tk_CanvasTagsParseProc and Tk_CanvasTagsPrintProc procedures for
use by canvas type managers in creating their own custom options. (JO)
*** POTENTIAL INCOMPATIBILITY ***

2/14/96 (bug fix) "winfo pointerxy" when applied to a non-toplevel window
crashed wish.  (SS)

2/14/96 (bug fix) "tkwait visibility" would hang under Windows. (SS)

2/14/96 (bug fix) Cursors were not being updated until an enter event.
In cases where the cursor left the toplevel and reentered before Tk
noticed, the cursor would get "stuck" until the next enter event.
Similarly, if the cursor attribute of a window was updated while the
mouse was in the window, the cursor would not change until the next
time the mouse entered the window. (SS)

2/15/96 (bug fix) If a top-level was resizable in one direction
(e.g. "wm resizable . 0 1"), once the user resized it any changes
in the internally requested size (by the widgets) were ignored,
even for the non-resizable dimension.  Fixed to handle the two
dimensions totally independently, so the widget's requests are
honored as long as that dimension hasn't been set by the user. (JO)

2/17/96 (bug fix) If a text widget had very long lines (e.g. more than
32K pixels), integer overflow could occur, resulting in parts of the
line not being visible. (JO)

2/20/96 (feature change) Changed the -minsize option of grid to take
screen units instead of pixels. (SU)

2/20/96 (bug fix) grid row and column weights are compared against
MINWEIGHT (0.001) instead of 0.0 to guard against divide by zero errors
during weight normalization. (SU)

2/20/96 (bug fix) Menu commands were not being invoked sometimes.
There was a race condition that caused events to be processed while a
menu was being unposted. (SS)

----------------- Released 4.1b2, 2/23/96 -----------------------

2/23/96 (bug fix) Alt-keys invoked in torn-off and popped up menus
caused menus to be posted in the parent toplevel. (JO)

2/23/96 (bug fix) Canvases weren't always updating their scrollbars
when they should. (JO)

2/23/96 (bug fix) Fixed core dump that could occur if a WM_DELETE_PROTOCOL
handler generated an error. (JO)

2/24/96 (bug fix) Removed dependencies on Makefile in the UNIX Makefile:
this caused problems on some platforms (like Linux?). (JO)

2/24/96 (feature change) Changed text and entry widgets so that they
set the insertion cursor before inserting during a button-2 click.
Also made optional bindings check for tk_strictMotif at the time of
the event, rather than at the time the bindings are created. (JO)

2/24/96 (bug fix) Tk tended to crash with an X error when unsetting
an icon window (e.g. "wm iconwindow . {}"). (JO)

2/25/96 (bug fix) Wasn't removing windows from the WM_COLORMAP_WINDOWS
property when they were deleted.  (JO)

3/1/96 (new feature) Added new "bbox" widget command for entries.
Also modified mouse bindings for entries and texts so that the
mouse position rounds to the nearest inter-character gap, rather
than the left edge of the character under the mouse.  This provides
more natural selection behavior. (JO)

3/1/96 (bug fix) Fixed core dump that could occur in image code if an
image was deleted while in use in a widet, then re-used in another
widget while "deleted". (JO)

3/1/96 (bug fix) Calling wish with a single argument caused a crash
under Windows due to an off-by-one error in the argument parsing code. (SS)

3/1/96 (bug fix) Palette management was broken and resulted in
incorrect palette realization and refresh behavior.  Also, images were
being drawn incorrectly if they were attached to widgets that had a
private colormap. (SS)

3/2/96 (bug fix) It was possible to press the mouse button over an
option menu, drag to a pulldown menu, and have the pulldown menu
popup in place of the option menu.  Fixed this so that option menus
are isolated from each other and from pulldowns. (JO)

3/2/96 (bug fix) Fixed yet another bug that caused long delays when
raising toplevel windows. (JO)

3/2/96 (bug fix) Fixed bug in canvases where zero-sized rectangles
and ovals didn't always redisplay right (could leave trailing
garbage on screen when moved). (JO)

3/2/96 (bug fix) Entry widgets reset their insertion cursor, selection,
and view whenever the text variable changed, plus whenever a "configure"
widget command was invoked and there was a text variable for the
widget.  Fixed to preserve this information as much as possible. (JO)

3/5/96 (new feature) Added version suffix to shared library names so that
Tk will compile under NetBSD and FreeBSD (I hope).  (JO)

3/6/96 (bug fix) Changed the way certain configure & motion events are
reported.  This fixes several bugs in menus & "winfo rootx". (RJ)

3/7/96 (bug fix) Fixed tag remove bug that showed up when draging out a
selection.  If you had dragged left, then tried to drag back right, the
left edge of the selection wasn't being updated because the tag remove
wasn't doing anything. (BW)

3/7/96 (bug fix) Fixed the boundary conditions of tag prevrange.  The second
index argument wasn't effecting in stopping the search if it fell within
a range.  The second index has to come at or before the start of a range
for the range to be found by tag prevrange. (BW)

3/7/96 (bug fix) "puts" to stdout or stderr when running from a script
caused wish41.exe to exit silently.  Now the output is silently
discarded without generating an error.  (SS)

3/7/96 (bug fix) Fixed bug where wish was treating empty lines in the input
as end of input, if the input came from stdin. This would cause it to
complain about missing closing braces etc. (JL)

----------------- Released 4.1b3, 3/8/96 -----------------------

3/9/96 (bug fix) Fixed bug in text.tcl that could cause errors in text
widgets of the form 'can't use non-numeric string as operand of "-"'. (JO)

3/12/96 (feature improvement) Modified startup script to look in several
different places for the Tcl library directory.  This should allow tk
to find the libraries under all but the weirdest conditions, even without
the TK_LIBRARY environment variable being set. (JO)

3/14/96 (bug fix) "wish bogus_file_name" didn't print an error message. (JO)

3/14/96 (bug fix) Button-2 wasn't claiming the focus during paste
operations. (JO)

3/14/96 (bug fix) "tkwait visibility" use to hang forever if its window
was deleted.  Now it detects this condition and returns an error. (JO)

3/16/96 (bug fix) Changed configuration stuff to get dynamic loading and
shared libraries working under AIX. (JO)

3/16/96 (bug fix) Fixed core dumps that could occur when a slave interpreter
was deleted in the middle of executin bindings. (JO)

3/18/96 (new feature) Added support for Activate/Deactivate events.
Currently, these new X events will generated only on the Macintosh. (RJ/CS)

3/21/96 (bug fix) The "tag prevrange" command would fail to return the current
range if it began at 1.0 and the starting point of the search was within
the range. (BW)

3/21/96 (configuration improvement) Changed configure script so it
doesn't use version numbers (as in -ltk4.1 and libtk4.1.so) under
SunOS 4.1, where they don't work anyway.  (JO)

3/22/96 (bug fix) Made Tk more robust against interpreter deletion. Now it
should be safe to delete an interpreter with a Tk application inside it,
without first deleting the Tk application. (JL)

3/26/96 (bug fix) Tk now returns results from a "send" to an interpreter
in which the Tk application is destroyed, if the interpreter continues
computing after the Tk application is destroyed. Previously any results
computed after '.' was destroyed in the target interpreter were discarded
by the "send". (JL)

3/26/96 (new feature) Tk now provides a static Tktest package which is
present only in test versions of Tk; this allows the testing commands to
be loaded into new interpreters besides the main one. (JL)

3/28/96 (bug fix) Changed the tk_dialog procedure *not* to make the
dialog a transient for its parent.  The old behavior meant that the
dialog did not get posted if the parent was iconified. (JO)

4/5/96 (bug fix) Tk would occasionally crash when destroying toplevels
under Windows. (SS)

4/5/96 (bug fix) Fonts were not being properly deallocated, causing
GDI resources to be consumed and never released under Windows. (SS)

4/11/96 (bug fix) Toplevel windows with no specified geometry were
always appearing in the upper left corner of the screen under
Windows. (SS)

4/11/96 (bug fix) "wm minsize" did not properly report the minimum
size imposed by the Windows window manager. (SS)

4/13/96 (bug fix) Text widgets could dump core in some cases where
text was inserted on the top visible line. (JO)

4/16/96 (bug fix) Changed menu code to ignore errors that occur when
restoring a grab:  the old grab window might not be visible anymore. (JO)

----------------- Released 4.1, 4/21/96 -----------------------

5/1/96 (bug fix) "option readfile" did not handle files with CRLF
line termination. (SS)

5/1/96 (bug fix) Changed to install tkConfig.sh under "make install-binaries",
not "make install-libraries". (JO)

5/7/96 (bug fix) Moved initScript in tkUnixInit.c to writable memory to
avoid potential core dumps. (JO)

5/7/96 (bug fix) Changed tk_dialog back so that the dialog box is a
transient window again.  This is needed to make sure that the dialog
box doesn't get obscured.  Also changed it to return -1 if the dialog
window is deleted before the user presses a button. (JO)

5/16/96 (bug fix) Fixed bug that caused core-dumps if a text widget
with -setgrid 1 was deleted by removing its command. (JO)

5/16/96 (bug fix) Fixed bug that caused Tk initialization to use improperly
initialized variables left over from previous invocation of Tk_Init on
another interpreter. (JL)

5/16/96 (new feature) Implemented application embedding on Windows
platforms (only Tk inside another application, not the other way yet). (JL)

5/16/96 (new feature) Added C API Tk_SafeInit that adds Tk to a safe
interpreter. (JL)

5/16/96 (bug fix) Fixed bug that caused Tk initialization to use improperly
initialized variables left over from previous invocation of Tk_Init on
another interpreter. (JL)

5/16/96 (new feature) Implemented application embedding on Windows
platforms (only Tk inside another application, not the other way yet). (JL)

5/16/96 (new feature) Added C API Tk_SafeInit that adds Tk to a safe
interpreter. (JL)

5/22/96 (bug fix) Listboxes weren't properly ignoring double clicks on
button 1. (JO)

6/12/96 (bug fix) Focus was automatically placed on new toplevels.
This caused the titlebar to flash during menubar traversal. (SS)

6/12/96 (bug fix) Iconification of a window with a specified geometry
by using the minimize button would leave the window in an inconsistent
state.  When the window was deiconified using "wm deiconify", the
window would continue to display as an icon with the deiconified
geometry. (SS)

6/12/96 (bug fix) Fixed a resource leak where the text widget was not
freeing all of the TkRegions it created.  This fix affects all
platforms, but is particularly important for Win32s. (SS)

6/21/96 (configuration change) Added --enable-gcc switch to configure
script to make Tk just like Tcl.  Now Tk will not use gcc unless you
request it explicitly. (JO)

7/18/96 (bug fix) Changed "configure" script to add an extra -R switch
(or whatever is appropriate to the platform) if the X library is in a
nonstandard place.  This guarantees that the shared library can be
found at runtime without having to set the LD_LIBRARY_PATH variable. (JO)

7/19/96 (bug fix) Fixed bug in tkImgGIF.c that cause core dumps if a
GIF file contained multiple images. (JO)

7/20/96 (bug fix) Deadlock could occur if a recursive series of send
operations involved multiple displays. (JO)

7/23/96 (bug fix) Fixed a resource leak where deallocated XIDs were
taking up memory on Windows and Macintosh platforms. (SS)

7/30/96 (bug fix) A core dump could occur if a <Destroy> handler for
a window tried to create a child in the half-dead window.  Fixed by
making the window's name disappear from the name table once it starts
to be deleted. (JO)

----------------- Released patch 4.1p1, 8/2/96 -----------------------

4/30/96 (new feature) Added support for named virtual events. New "event"
command to define/destroy named virtual events and to programmatically
send both real and virtual events to Tk. (CS)

8/6/96 (bug fix) Entry widgets were invoking scrollbar update functions
too often. (JO)

8/9/96 (bug fix) 7/30 change above for <Destroy> handlers broke many
things by making window available during Destroy handler.  Reworked
fix for core dump to simply disallow creating children of half-dead
parents. (JO)

8/12/96 (bug fix) Fixed bug where using the Copy menu item on the
Macintosh would append a NULL character at the end of the text. (RJ)

8/15/96 (bug fix) Fixed Mac code so garbage wouldn't be printed in
text and entry widgets when function & other non-printing keys were
pressed. (RJ)

8/15/96 (configuration improvement) Changed the file patchlevel.h
to be tkPatch.h.  This avoids conflict with the Tcl file and is now
in 8.3 format on the Windows platform. (RJ)

8/19/96 (bug fix) Fixed a bug under Windows where the initial window
position for a toplevel window was reported as +0+0, regardless of the
actual position. (SS)

8/21/96 (bug fix) If the last character on a line in a text widget was
a space character that didn't completely fit, the text widget would
sometimes add an extra wrap line. (JO)

8/22/96 (feature change) Complete rewrite of the grid geometry manager.
There is a new layout algorithm that produces better (but different)
layouts in many common cases. (SU)

8/22/96 (new feature) There are two new options for the grid geometry
manager, "grid update" which forces an immediate layout calculation,
and a "-pad" option to rowconfigure and columnconfigure that allows for
extra space around widgets. (SU)

8/22/96 (feature change) The order in which the grid geometry manager
reports slaves is now last-managed first. (SU)

8/22/96 (feature change) The column and row weights in the grid
geometry manager are kept internally as integers, instead of floating
point values.  Floating point values are still accepted on the command line,
but are truncated to integers. (SU)

8/22/96 (new feature) There are four new commands for opening common
dialog boxes: tk_chooseColor, tk_getOpenFile, tk_getSaveFile and
tk_messageBox. Native dialog boxes are used wherever available. (IL)

8/22/96 (new demos) Added "fsbox", "msgbox" and "clrpick" demos. (IL)

8/23/96 (feature change) Invoking the edit menu on the Macintosh now
generates the following virtual events <<Cut>>, <<Copy>>, <<Paste>>,
and <<Clear>> instead of faking key events. (RJ)
*** POTENTIAL INCOMPATIBILITY ***

8/25/96 (bug fix)  Fixed a bug that would cause "grid x" to dump core. (SU)

8/26/96 (new feature) Added the "unsupported1" command to the
Macintosh version of Tk.  This command will allow you to set the style
of a new toplevel Window (much like overrideredirect).  You can use
this to get access to all of the Native Mac window styles.  This is to
hold you over until we get a more general solution added to the
toplevel command. (RJ)

8/26/96 (new feature) Added support to handle the zoom box on a
Macintosh window.  (Currently, you can only get a Tk window with a
zoom box by using the "unsupported1" command. (RJ)

8/27/96 (documentation change) Removed old change bars (for changes in
Tk 4.1 and earlier releases) from manual entries. (JO)

----------------- Released 4.2b1, 8/30/96 -----------------------

9/5/96 (bug fixes) Fixed several bugs in file dialogs: individual files
could be listed twice, if a long list of files were shown, and the view
scrolled to the right, and then a different file file was shown, the
scrollregion on the canvas wasn't being reset, so the file dialog was
broken from then on, added an update idletasks so that the watch
cursor was shown when the dialog was thinking. For the motif file
dialog, fixed the weights for resizing.  On the clrpicker, fixed the
finalColor variable which caused problems when the OK button was
"clicked" before the dialog was mapped (in the test suite). Added Ioi's
last changes from before he left. For message boxes, if a single button
message box is shown (currently only 'ok'), it is set to be the default
even if not specified. (KC)

9/5/96 (bug fix) Fixed bug on Macintosh where menus would appear in a
seemingly random location.  (RJ)

9/5/96 (bug fix) Text widgets had rounding problems with the "yview"
command that caused them sometimes to round to the line before the
correct one. (JO)

9/5/96 (bug fix) Changed grab code to retry grabs after errors where
another application already has the grab.  This is needed to get
around race conditions with some window managers and will hopefully
solve the grab errors that people see occasionally. (JO)

9/6/96 (bug fix) Fixed x-y coordinate confusion problem with scaling
of window items in canvases. (JO)

9/11/96 (bug fix) The open and save file dialogs would change the
current working directory under Windows. (SS)

9/12/96 (bug fix) The Tk event system was delivering events to dead
windows, if the event handler got reentered during a Destroy event
handler.  This could cause core dumps and other problems. (JO)

9/20/96 (bug fix) In XFillRectangles under Windows, a brush was not
being deallocated. (SS)

9/20/96 (bug fix) The Mac window manager used to generate a mouseUp
event for a top level that was recently raised to the front/active
window which often caused a tk(priv) error.  The up event is no
longer generated with solves several problems. (RJ)

9/25/96 (bug fix) The font code under Windows was leaking memory
whenever a new font was referenced using the three part font names. (SS)

9/26/96 (bug fix) The tests for the common dialogs still used the 'testevent'
function.  I updated these calls in clrpick.test, msgbox.test, filebox.test
to use the new event gereating mechanism.

9/18/96 (bug fix) Long-standing bug in bind where <Button-1><Button-1> was
reported as <Double-Button-1>, but <Double-Key-a> was reported as "aa". (CS)

9/27/96 (bug fix) Bindings didn't work on 64-bit machines due to changes
made for virtual events. (CS)

9/30/96 (feature change) Binding for new virtual events included both
lower and upper-case, e.g., <<Copy>> was defined as <Control-c> and
<Control-C>.  Previously, widgets were directly bound to only lower-case
bindings.  The upper-case binding caused incompatibility with some existing
Tcl programs, so the upper case bindings for <<Cut>>, <<Copy>>, and <<Paste>>
were removed. (CS)

9/30/96 (bug fix) The postscript code in the canvas widget now uses
channels to get and write .ps files which fixed a bug on the Mac where
an output file would have mixed EOL characters.  In addition, I added
the ability for the prolog to come from the Tk shared library on the
Mac which makes it possible to have a standalone application. (RJ)

10/1/96 (feature change)  "grid forget" was renamed "grid remove".  A new
command "grid forget" was added whose semantics are the same as "pack forget"
(SAU)
*** POTENTIAL INCOMPATIBILITY ***

10/1/96 (feature change)  grid no longer accepts floating point values for
row or column weights, integers must be used.  (SAU)
*** POTENTIAL INCOMPATIBILITY ***

10/1/96 (feature change)  "grid {column,row}configure <master> <index>"
returns a list of option value pairs for all of the row or column
constraints. It used to return an error. (SAU)

10/1/96 (bug fix)  "The way grid handles '^' short-cuts was re-written
to eliminate core dumps. (SAU)

10/3/96 (feature change) A virtual event binding associated with a
given physical event is now considered less specific than a binding for
that same physical event, all other things being equal. (CS).

10/3/96 (bug fix) Under Windows text placed on the clipboard did not
undergo CRLF translation when delivered to other applications. (SS)

10/3/96 (bug fix) Copying an image onto itself with a zoom factor that
caused the image to grow was accessing freed memory. (SS)

10/3/96 (bug fix) Under Windows, the image blank subcommand did not
work. (SS)

10/10/96 (bug fix) Under Windows & Macintosh, XSetFont and XChangeGC
were not implemented, and XSetLineAttributes did not correctly update
the GC. (SS)

10/10/96 (bug fix) Under Windows, 8-bit non-palette displays were not
handled properly. (SS)

10/10/96 (bug fix) Under Windows, images of depth other than 8 or 24
bits were not being rendered properly. (SS)

10/10/96 (bug fix) Under Windows, bitmap subimages were not correctly
displayed. (SS)

10/14/96 (bug fix) Under Window, wm resizable would constrain both
programatic resizes as well as user resizes. (SS)

----------------- Released 4.2, 10/16/96 -----------------------

10/17/96 (bug fix) XCopyPlane was broken under Windows and would cause
a crash when used with a clipping bitmap. (SS)

10/21/96 (bug fix) Added missing resources needed by tk_getOpenDialog
on the Macintosh to the shared library for Tk. (RJ)

10/22/96 (bug fix) Invoking a menu with an Alt key sequence caused an
error due to a misplaced common in library/menu.tcl. (JO)

10/23/96 (bug fix) Errors in files sourced by the Macintosh
"Source..." menu are now correctly reported via the background
error mechanism. (RJ)

10/23/96 (bug fix) Fixed a bug in the Mac subwindow implementation
that caused refreshes to not occur for canvases with embedded
windows. (RJ)

10/24/96 (bug fix) Provided workaround for Apple bug that doesn't
handle zooming correctly for floating windows. (RJ)

10/24/96 (bug fix) Macintosh tearoff menus are now correctly
displayed as Mac floating windows. (RJ)

11/1/96 (bug fix) Restored manual page for procedures like
Tk_CreateWindowFromPath and Tk_DestroyWindow; was accidentally deleted
when Tk_CreateMainWindow procedure was decommissioned. (JO)

11/19/96 (bug fix) Fixed bugs in postscript code that would cause the
prefix to not be included and the output file to have the wrong
permissions. (RJ)

12/2/96 (bug fix) Fixed problem with canvas lines where it didn't
compute bounding boxes correctly for zero-width lines: this could
potentially leave garbage on the screen when items were deleted or
moved. (JO)

12/5/96 (bug fix) Fixed the Macintosh implementation of pointer x/y
which was returning garbage. (RJ)

12/6/96 (bug fix) Fixed grid bug where the positioning of slaves was
incorrect for non-zero values of ipadx and ipady (SU)

12/6/96 (bug fix) Fixed grid bug where slaves got "lost" when an
already managed slave is re-managed in a different master. (SAU)

----------------- Released 4.2p1, 12/8/96 (Mac only) --------------

1/17/97 (bug fix) Fixed bug where the Tk clipboard was not in sync
with the Macintosh clipboard on start-up.  (RJ)

----------------- Released 4.2p2, 1/31/97 --------------

----------------------------------------------------------
Changes for Tk 4.2 go above this line.
Changes for Tk 4.3 go below this line.
----------------------------------------------------------

9/19/96 (improvement) Implemented table driven mechanism for deciding
whether a command is safe. If it is added by Tk_Init and it appears in the
table then it is kept, otherwise it is removed in a safe interpreter. (JL)

10/18/96 (new feature) Added support for application embedding:
    - Frame and toplevel widgets now have a -container option, which
      turns the widget into a container.
    - Toplevel widgets have a -use option for requesting that the
      widget be embedded in another application.
    - Wish also supports a -use command-line option.
Embedding is fully supported under Unix, but the implementation is
not complete under Windows or the Macintosh (it works just well
enough to support the Tcl/Tk plugin). (JO)

10/22/96 (bug fix) The commands "winfo rootx" and "winfo rooty" didn't
work for non-toplevel windows in embedded applications: they returned
the coordinates of the nearest toplevel. (JO)

12/02/96 (new feature) Implemented Safe Tk. Tk can now be loaded into a
safe interpreter that has been created with tcl_safeCreateInterp, by
calling load {} Tk interpname. (JL)

12/02/96 (new feature) A safe Tk interpreter can no longer generate
postscript output from a canvas. (JL)

12/02/96 (new feature) Added -channel option to photo command to allow
image data to be read from a channel. This is useful in safe Tk
interpreters where the data cannot be read directly from a file. (JL)

----------------------------------------------------------
Changes for Tk 4.3 go above this line.
Changes for Tk 8.0 go below this line.
----------------------------------------------------------

9/1/96 (new features) The font mechanism in Tk has been completely
reworked:
    - Font names need not be nasty X LFDs: more intuitive names like
      {Times 12 Bold} can also be used.  See the manual entry font.n
      for details.
    - Font requests always succeed now.  If the requested font is not
      available, Tk finds the closest available font and uses that one.
    - Tk now supports named fonts whose precise attributes can be
      changed dynamically.  If a named font is changed, any widget
      using that font updates itself to reflect the change.
    - There is a new command "font" for creating named fonts and querying
      various information about fonts.
    - There are now officially supported C APIs for measuring and
      displaying text.  If you use these APIs now, your code will
      automatically handle international text when internationalization
      is added to Tk in a future release.  See the manual entries
      MeasureChar.3, TextLayout.3, and FontId.3.
    - The old C procedures Tk_GetFontStruct, Tk_NameOfFontStruct, and
      Tk_FreeFontStruct have been replaced with more portable procedures
      Tk_GetFont, Tk_NameOfFont, and Tk_FreeFont.
      *** POTENTIAL INCOMPATIBILITY ***
(CS)

9/24/96 (bug fix) Under Windows, transient windows would be destroyed
if their master was destroyed, even if the transient window was not a
child of the master. (SS)

10/18/96 (new features) A -menu option has been added to the toplevel
widget command, which allows a menu to operate as a menubar. On the
Macintosh, the menubar is displayed accross the top of the main monitor,
just like with other applications. Under Windows and Unix, the menu is
attached to the toplevel window. Also, changed some semantics.
Tearoff menus will now reflect changes to the menu it was
torn off from, and are deleted when the main menu is
deleted. Tearoffs also reflect more look-and-feel of the
platforms they are running on. (SRP)

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

11/7/96 (feature change) Under Unix, default borderwidth is now 1 to
more closely approximate CDE.  (SS)
Note: this change was undone on 6/12/97, restoring the default border
width to 2 again.  (JO)

11/7/96 (new feature) The button widget now supports a -default option
that draws a platform specific default ring around the widget. (SS)

11/7/96 (feature change) Under Windows, buttons and scrollbars now
have native look and feel.  This affects the default class bindings
and the way the some configuration options are interpreted.  Refer to
the widget manual pages for more details. (SS)
*** POTENTIAL INCOMPATIBILITY ***

11/19/96 (bug fix) Under Windows, images were incorrectly drawn on
16-bit displays. (SS)

11/19/96 (bug fix) Under Windows, the class name for the main window
(.) was not properly generated from argv0. (SS)

11/20/96 (bug fix) Fixed a couple of bugs in the Canvas widget.  The
postscript file is now created with the correct permissions.  Also,
the prolog is now properly included in all cases. (RJ)

11/22/96 (bug fix) Under Windows, the initial directory and file names
were not properly translated before being passed to the system
open/save file dialogs.  So forward slashes were not converted to
backslashes, and tilde substitution was not performed.  (SS)

11/25/96 (feature change) Under Windows and Macintosh, the selection
highlight is now hidden whenever an entry or text widget loses focus.
Also, the previous selection information is not lost when a new
selection is made in a different widget. (SS)

11/26/96 (new feature) Added support for images as primitive types in
text widgets. (SU)

11/30/96 (configuration improvement) Modified configure.in to handle the
case where Tcl and Tk are installed in different places by including both
their library directories in the library search path for Tk. (JO)

12/3/96 (bug fixes) Fixed two bugs related to canvas lines that caused
the screen to be incorrectly refreshed, leaving garbage on the screen.
One bug was related to lines with width zero, and the other was
related to lines with very long miters. (JO)

12/4/96 (bug fix) The "update" command was only syncing the display
for its main window.  Changed to sync all displays. (JO)

12/5/96 (bug fix) Color deallocation would occasionally cause a panic
under Windows. (SS)

12/5/96 (bug fix) Errors during startup were silently discarded under
Windows. (SS)

12/5/96 (bug fix) Errors during startup were silently discarded under
Windows. (SS)

12/11/96 (bug fix) Text widgets weren't considering the -spacing1
and -spacing2 options when computing their desired geometry. (JO)

12/12/96 (feature change) Option menus using tk_optionMenu were
created with command entries that set the option menu's variable in a
command string. This has been changed so that the option menu's
entries are now radiobutton entries so that the entries that matches
the variable is now checked when the menu is posted. (SRP)

12/12/96 (feature change) The destroy command no longer returns an
error when a window does not exist. (SRP)

12/13/96 (new feature) grid row/column-configure accepts a list of
indices in addition to a single index. (SU)

12/17/96 (bug fix) Under Windows, command line was not being parsed
correctly if it contained the literal characters \" (CS)

12/17/96 (feature change) Native Windows labels do not get a focus-ring
border.  (CS)

12/17/96 (bug fix) Under Windows, colors specified as "#XXYYZZ" where XX, YY,
or ZZ were not valid hex digits were getting a random color value instead of
being an error. (CS)

----------------- Released 8.0a1, 12/17/96 -----------------------

12/23/96 (bug fix) Fixed two menu bugs:
    - Menus could get stacked below other windows so that they weren't
      visible when posted (especially under olvwm and fvwm).
    - Under olvwm if you pressed button 1 over an entry in a new-style
      menubar, the menu didn't appear until you moved the mouse slightly.
(JO)

1/6/97 (bug fix) Focus could accidentally get grabbed by an application
away from the rightful focus owner if the focus recently changed from one
application to another. (JO)

1/6/97 (bug fix) Under Windows, the console was appearing even for
non-interactive applications.  This was a side effect of a general
problem with the wm state of windows that were being mapped for the
first time. (SS)

1/6/97 (bug fix) Under Windows, the initialization code was not
looking in the right directory for the Tk libraries when the program
being run was not in the Tcl installation heirarchy. (SS)

1/8/97 (bug fix) Under Windows, the windows were not being unmapped
properly, which led to strange packer behavior. (SS)

1/8/97 (bug fix) The "winfo containing" command (and the Tk_CoordsToWindow
procedure) didn't work properly on Unix in the presence of embedding or
menubars. (JO)

1/15/97 (bug fix) Invoking "destroy ." as the command from a menu would
cause Tk to crash because TkMainInfo was freed before menu released its
resources.  This bug had already been fixed for scrollbars and buttons. (CS)

1/15/97 (bug fix) Tk is now working under Win32s again, including Win32
version 1.25.  Fixed separate problems in fonts and dialogs. (CS)

1/15/97 (feature change) Under Windows, font sizes are now specified in
points, not pixels.  The mapping between pointsize and pixels depends on
Windows having accurate metrics for the monitor (plug&play helps).  Font
metrics are still reported in pixels. (CS)

1/21/97 (bug fix)  Grid no longer reports rows or columns "out of range"
when requesting their constraints. (SAU)

1/21/97 (bug fix)  Fixed some window manager related bugs on the
Macintosh.  Now better support global grabs. (RJ)

1/21/97 (bug fix) For Windows: Fixed problems with canvas items that
used end caps.  Fixed arc implementation to more closely approximate
X.  Stippling now works properly on fat lines. (SS)

1/21/97 (bug fix) Small interlaced GIF images were not properly
decoded. (SS)

1/21/97 (bug fix) More changes to image code to try to handle 16-bit
displays properly under Windows. (SS)

1/21/97 (bug fix) Numerous display bugs on Unix and Macintosh are now
fixed. Numerous binding problems for menubars under Unix are now
fixed. Deletion of menu separators under Windows is now fixed. (SRP)

----------------- Released 8.0a2, 1/24/97 -----------------------

1/29/97 (feature change) The -transient field for menus is no longer
supported.  There is now a -type field which is used to achieve the
same purpose that the -transient field accomplished. When a menu is
created, the -type field controls whether the menu is a normal
pull-down menu, a floating tearoff menu or a menubar. This option is
normally only used by the library code and internally by the menubar
code. (SRP)
*** POTENTIAL INCOMPATIBILITY ***

2/5/97 (feature change) Changed the photo image mechanism to use
Tcl_Channels instead of FILE * as an argument to image matching
functions.  The change will make it much easier to write cross
platform image types in Tk.  Note: FILE * is no longer used anywhere
in Tk. (RJ)
*** POTENTIAL INCOMPATIBILITY ***

2/7/97 (enhancement) Were not allowed to bind to virtual events inside of
canvas or text widget (e.g., "$canvas bind all <<foo>> {script}" or
"$text tag bind sel <<foo>> {script}"); it would return an error
disallowing that binding.  Now _can_ bind to a virtual event, but that
binding inside of the canvas or text widget will only fire if the
underlying virtual event definition is of type key, button, motion,
enter, or leave; all other physical event types get filtered out by the
widget before the virtual event mapping is done. (CS)

2/22/97 (bug fix) Under Unix, "wm geometry +-20+-30" didn't work. (JO)

2/24/97 (bug fix) The photo image didn't always zero out enough of its
pixel and dither correction arrays. (JO)

2/25/97 (bug fix) Fixed focus problem that could cause "BadMatch (invalid
parameter attributes)" in X_SetInputFocus requests on Unix. (JO)

2/25/97 (bug fix and new feature) Added new "gray75" bitmap, fixed
"gray25" bitmap to really be 25% on (due to an ancient mistake, it
had been only 12% on). (JO)

2/28/97 (bug fix) Windows: made embedding work again on Win32 platform.
Prevent iconification, deiconinification on embedded windows. (JL)

3/4/97 (new feature) Added the ability to manipulate the Apple and
Help menus on the Macintosh; the system menu on Windows; and to have a
right justified Help menu on Unix. See the documentation for menu.n
for more details. (SRP)

3/4/97 (bug fix) Prevented core dump at exit if a <Destroy> binding on "."
gets invoked from destroying a nested widget and the binding causes the
interpreter to be deleted. The core dump was being caused by the
interpreter not being Tcl_Preserve'd during the destroy of ".". (JL)

3/4/97 (bug fix) Under Unix, when embedded Tk is running in a separate
process, correctly handle a race condition: ignore cross-over messages from
the X server for windows that Tk thinks it had already deleted, when the
containing process deletes its container window. Some other race conditions
still remain, e.g. with pixmaps, colormaps and images. (JL)

3/10/97 (bug fix) Prevented core dump in generic console code due to
following a NULL pointer when the console interpreter was already deleted.
This may happen due to different orders of deletion possible at exit. (JL)

3/10/97 (bug fix) Fixed bug on Mac and Windows that caused time to be
ignored when considering if a single click was actually a double
click. (RJ)

3/11/97 (feature change) A major oversight has been that although it was
documented that the Tk programmer was asking for a font in points (1/72 of an
inch), under Unix and Mac Tk was actually asking for a font in pixels, while
only under Windows was it using points.  This caused applications to appear
much larger when run under Windows.  Now, on all platforms the (purportedly)
correct size in points is used when asking for fonts.  However, for
compatibility with existing tk4.2 applications that depend on fonts being of
specified pixel size, XLFDs retain their incorrect behavior of getting a
font in pixels.  (CCS)
*** POTENTIAL INCOMPATIBILITY ***

3/13/97 (new feature) "tk scaling" command to setup the mapping between
pixels and points.  This scaling factor is used by all widgets that accept
ruler distances, not just fonts. (CCS)

3/24/97 (new feature) Added "-columnbreak" option to menu
entries. When this value is "1", the entry will appear at the top of a
new column in a non-menubar menu. Also added "-hideMargin". Together
with "-columnBreak", menus with palettes are now possible. (SRP)

3/26/97 (new features and bug fix) Titles for tearoff menus were
broken on the Mac and Windows. Added the ability to set the title of a
menu when it gets torn off and override Tk's automatic generation of
the title.  On the Macintosh, whenever a menu
label contains three dots in a row "...", the menu will instead
display the elipses character '…'.  (SRP)

3/27/97 (bug fixes) When a menu had an error executing a postcommand,
the error information was getting lost. On Windows, a set of
menubuttons was not highligting properly when clicking between
windows. On Windows, post commands were getting executed twice for
popup menus.  On Macintosh, fixed problem where menubars were not
always current. (SRP)

4/11/97 (new feature) Menubuttons now have a direction flag which
controls where the menu popups up relative to the button. (SRP)

4/24/97 (bug fix) Transient windows did not obey the resizable setting
under Windows. (SS)

4/24/97 (bug fix) wm geometry did not correctly parse negative
coordinates. (SS)

4/29/97 (bug fix) Changed the canvas polygon implementation to only
report the coordinates specified by the end user not the automatically
generated end point of a self closing polygon. (RJ)
*** POTENTIAL INCOMPATIBILITY ***

4/23/97 (feature change) Loosened the rules on parsing font names so that
unix-centric fonts in scripts don't break when run on Windows or Mac.
(1) Previously, an XLFD had to specify font name, weight, slant, and size;
now, a minimal XLFD (such as "*-times-*") will be accepted, and all
unspecified attributes will be given default values.  (2) Previously, in the
{name size style ...} format, only the style was optional; now both the size
and the style are optional; this solves the problem of old scripts that
contain specifications of the form "-font fixed" or "-font times". (CCS)

5/7/97 (new feature) Menus now send a virtual event <<MenuSelect>>
when an item is highlighted in a menu. Applications can use this to
implement context-sensitive help. (SRP)

5/14/97 (bug fix) Fixed a race condition in the focus code where focus
could be taken away from a window incorrectly.  Scenario is that the main
window creates a toplevel and assigns focus to it.  When the user moves the
mouse from the main window into the toplevel there was a race between
two different kinds of focus events. (BW)

5/20/97 (bug fix) Fixed bug where the clipboard was not rendered before
the application exited. (SS)

5/22/97 (feature change) When a Tk8.0 menu is configured, all menus
derived from it (menubars, tearoff) mirror the changes. This was not
true for the "-tearoff" flag. In Tk4.6, tearoff menus had the
"-tearoff" flag turned off. Now, the "-tearoff" flag is tracked just
as the other options are. Tearoff menus and menubars with the
"-tearoff" option set will not display the tearoff item. This means
that a given menu entry for a menu and a tearoff of that menu will
match now. (SRP)
*** POTENTIAL INCOMPATIBILITY ***

----------------- Released 8.0b1, 5/27/97 -----------------------

5/30/97 (bug fix) Made the options to the grid command shortcut-able.
Ie. You can now use -stick, in addition to -sticky. (RJ)

6/2/97 (bug fix) Fixed bug in startup code that caused a problem in
finding the library files when they are installed in a directory
containing a space in the name. (SS)

6/2/97 (bug fix) Virtual events associated with <Enter>/<Leave> in text
widget tag caused panic. (CCS)

6/6/97 (bug fix) On some systems, struct timeval.tv_sec is unsigned. (SS)

6/6/97 (feature change) Changed -default option on buttons to take
three states: normal, active, disabled.  This allows apps to have a
row of buttons where the default ring moves between buttons without
changing the geometry of the buttons.  See the button.n manual page
for more details. (SS)
*** POTENTIAL INCOMPATIBILITY with Tk 8.0b1, but not with Tk 4.2 ***

6/9/97 (bug fix) Canvas postscript printing now works for bitmaps
under Windows. (SS)

6/10/97 (bug fix) Fixed bug in bindings for listboxes where state wasn't
being properly initialized on Shift-1 button presses. (JO)

6/11/97 (bug fix) Text widget display code did not include internal
padding in the damage calculation for borders leading to unrefreshed
sections on Windows and Mac. (SS)

6/12/97 (feature reversal) Changed default border widths under Unix
back to 2 again.  This reverses the change made on 11/7/96. (JO)

6/13/97 (bug fixes) In canvas text item: the insertion cursor wasn't shown
if insertion point was at end of text item, it was impossible to click to
position the insertion point after the last character, and @x,y indices were
computed incorrectly if -scrollregion had been specified and canvas was
scrolled. (CCS)

6/13/97 (bug fix) Hitting up/down arrows in a text widget packed in a
toplevel window created with the "-screen" option would cause an error dialog
to pop up. (CCS)

6/12/97 (bug fix) Fixed bug in canvas text items where multi-line
selections were not highlighted properly.  This bug existed only in
earlier releases of Tk 8.0.  (JO)

6/16/97 (bug fix) In some obscure cases, canvas window items could
accidentally specified a 0x0 size for the window, which caused a
BadValue error under X. (JO)

6/17/97 (bug fix) Tk buttons on the Macintosh will now correctly
draw under MacOS 8.0. (RJ)

6/18/97 (feature change) Changed the way highlights are drawn in text
widgets so that the empty space to the left of a line is highlighted
whenever the leftmost character of the line is highlighted (the empty
space didn't used to be highlighted).  This produces a neater left
edge when several lines are selected.  (JO)

6/18/97 (bug fix) Tk was using the wrong system colors to draw various
widgets under Windows. (SS)

6/19/97 (bug fix) Under Windows, the "wm transient" and "wm overrideredirect"
subcommands can now be applied to a toplevel to change its window
style at any time during the life of the window. (SS)

6/19/97 (feature change) All GIF and XBM images needed for the "TK"
file dialog box are included in-line in tkfbox.tcl. (IL)

6/27/97 (bug fix) Revamped focus code to eliminate most XSetInputFocus
calls from the FilterEvent procedure.  This moves the implementation back
towards the Tk 4.2 implementation, but adds embedding support.  There is
still a known bug with twm's NoTitleFocus and embedded windows.  However,
the races in a2 and the funny focus stealing in b1 are gone. (BW)

6/25/97 (bug fix) Error message was not properly reported when using
button 'toggle'. (DL)

6/25/97 (bug fix) Removed one source of memory corruption in tkGrid.c code
(fixes what was exercised by "grid col . 0 -w 1; grid col . 0 -w 25") (DL)

----------------- Released 8.0b2, 6/30/97 -----------------------

7/1/97 (bug fix) Menu shortcut and tearoff reported problem fixed. (DL)

7/1/97 (new feature) TK_BUILD_SHARED flag set in tkConfig.sh
when Tk has been built with --enable-shared. TK_SRC_DIR added.
A new tkLibObjs make target, echoing the list of the .o's needed
to build a tk library, is now provided. (DL)

7/9/97 (bug fix) Fixed Tk_CreateFileHandler and Tk_DeleteFileHandler
macros to directly call the Tcl equivalents. (JL)

7/10/97 (bug fix) On the Mac, if the binding for <<MenuSelect>> was
drawing, the drawing could bleed over into the menus. This is now
fixed. (SRP)

7/10/97 (bug fixes) Removed duplicate code related to Tk_SafeInit,
made a single init script handling both cases. (DL)

7/10/97 (feature change) On Unix, to be able to load Tk into a safe
interp you need to set the env(DISPLAY) var. Some API should be
added to allow master crontrol over Tk instantiation. (DL)

7/11/97 (new feature) On the Mac, menus that are too big for the
screen will now scroll. This is part of the interface on the Mac,
impossible under Windows, and is not done for Unix. (SRP)

7/21/97 (bug fix) After fixing the bug that in canvas text item the insertion
cursor wasn't shown if insertion point was at end of text item, introduced a
different bug in where clicking in entry widget with 0 characters would
crash or display garbage. (CCS)

7/22/97 (bug fix) If there were a whole bunch of returns or tabs in a row in
a canvas text item, then the temporary buffer used when outputting
postscript could overflow and overwrite the stack. (CCS)

7/23/97 (feature change) Reenabled "tkwait" in the Safe Tk base. (JL)

7/24/97 (bug fix) Single init script for both Win and Unix.
new library/safetk.tcl using features from new tcl safe.tcl (DL)

7/30/97 (feature change) As a result of native menus, you can no
longer drag through a frame of menubuttons on Macintosh and Windows
and have the menus pop down. You can still click on individual
menubuttons and their menus will pop down.  Applications needing to
present a menubar should consider using the new "-menu" configuration
of the toplevel widget to set up menubar which behaves correctly on
Macintosh, Windows and X Windows. (SRP)

7/31/97 (bug fix) Tk widget commands can now safely be hidden commands.
Previously destroying the widget would potentially leave dangling pointers
and destroy an exposed command instead of a hidden one if an exposed
command by that name existed. (JL)

7/31/97 (bug fix) On Windows, popup menus were not tracking the right mouse
button correctly if it was used to invoke the menu. On Unix, tearoff
menus were stealing focus when the mouse moving over them even when
focus following was turned off. (SRP)

8/4/97 (bug fix) Fixed problem under USENIX where raising a toplevel
window could cause an X error if the window had just been withdrawn.  (JO)

8/4/97 (feature change) tkerror and bgerror are not anymore hard links
maintained by the Tcl core. The implementation of bgerror provided by
Tk tries, for backward compatibility only, to to call "tkerror" and
if that fails, falls back to the usual dialog and stack trace option
posting. You can thus still use either "bgerror" or "tkerror" as your
application error handling proc, but using "bgerror" is strongly
recommended as support for "tkerror" will eventually vanish in upcoming
releases. (DL)
*** POTENTIAL INCOMPATIBILITY with scripts that were using
    the actual hardlink implementation 'features' and with
    scripts (if any) that would be calling the default "tkerror" to
    simulate error messages (use "bgerror" instead)                  ***

8/7/97 (feature change/addition) Removed the gif files used for the
Open dialog box on UNIX (they were previously made inline).  Added a
new images directory that includes several images of the Tcl and Tcl
Powered logos. (RJ)

8/7/97 (bug fix) Fixed focus to deal with embedding when there is
no window manager. (BW)

8/8/97 (bug fix) Fixed bug in photo image code where photo images from
different interpreters could get confused if they had the same name. (JO)

8/8/97 (new feature) Added new procedure Tk_GetImageMasterData for
mapping image names to master data.  (JO)

8/8/97 (feature change) Modified Tk_FindPhoto procedure to require
extra "interp" argument (needed for bug fix above).  (JO)
*** POTENTIAL INCOMPATIBILITY ***

8/8/97 (bug fix) Fixed problems under Windows renaming toplevels with
menubars. Fixed problems on all platforms renaming menu widgets and
using new menus of the same name as an old one as cascades. Fixed a
cosmetic problem with tearoff menus. (SRP)

8/13/97 (bug fixes) Fixed "-from" option for the "image create" and
"imageName read" commands for GIF images, which didn't used to work
correctly.  Also made transparency work correctly for GIF images
without the TRANSPARENT_GIF_COLOR hack; TRANSPARENT_GIF_COLOR is
now ignored.  These fixes were provided by Jan Nijtmans. (JO)

8/13/97 (new feature) added safe::loadTk command to load Tk in a
safe slave interpreter. See the loadTk.n manual page for more
details. (DL)

----------------- Released 8.0, 8/18/97 -----------------------

8/22/97 - (bug fix) Fixed syntax error in tk_popup; option menus now
popup over their selected items like they did in tk4.2. Fixed problem
where cascades sometimes did not work on X. On X, menubars with
checkbuttons and radiobuttons in them would infinite loop when
mappped. (SRP)

8/27/97 (new feature) Added support for new X11R6 colors under Windows
and Mac platforms. (SS)

8/29/97 (bug fix) Wish crashed if stdin was closed. (SS)

9/10/97 (bug fix) "font actual {helvetica 10} -displayof ." wasn't taking
into account the "-displayof" option.  This problem also existed for the
"font metrics" and "font measure" commands. (CCS)

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

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

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

9/19/97 (bug fix) Made Macintosh tearoff menus non-resizable. (RJ)

10/9/97 (bug fix) Default font for new canvas text items was hardcoded to
"Helvetica 12" instead of using DEF_CANVTEXT_FONT defined in
tk{platform}Default.h like all the other widget settings.  (CCS)

10/9/97 (bug fix) Image code could cause crashes during "exit" under
some conditions (such as an image named "place").  (JO)

10/9/97 (bug fix) Fixed bug that sometimes prevented listboxes from
scrolling far enough horizontally to see the rightmost character.  (JO)

10/10/97 (bug fix) In canvas text items, if the text ended with a \n, it
was not counted in the bbox height, as it did in tk4.2.  This caused
"hello\n" to be the same height as "hello" and you couldn't see the
cursor positioned on the next line. (CCS)

10/10/97 (bug fix) The grid geometry manager didn't always properly
forget about windows after a "grid forget" or "grid remove" command:
the windows could reappear on the screen later.  (JO)

10/13/97 (bug fix) Selection could not be restored to a text widget
after "selection clear" on Windows. (SS)

10/14/97 (bug fix) If a canvas had contained windows that were off-screen,
the windows could sometimes reappear (in the wrong place) if the canvas was
enlarged.  (JO)

10/20/97 (bug fix) Omitting the arguments to the text widget "mark
gravity" option caused a crash. (SS)

10/21/97 (bug fix) Tk did not reset the result after native dialog
modal loops on Window so background events could perturb the dialog
result. (SS)

10/23/97 (bug fix) Memory leak in unix's TkpGetFontFamilies.  Thanks
to James Bonfield for the fix. (DL)

10/27/97 (bug fix) Fixed event reporting for the Mac during a grab
when the pointer was out of the toplevel window. (RJ)

10/28/97 (bug fix) Under Unix, override-redirect was getting set
incorrectly for menus, so that "wm overrideredirect" returned 0. (JO)

10/28/97 (bug fix) Under Unix, focus code could sometimes cause the
display to deadlock (it wasn't flushing the output buffer after issuing
an ungrab command). (JO)

10/28/97 (bug fix) If a PPM image file wasn't complete (e.g. it
consisted of nothing but space characters) Tk entered an infinite loop
reading the header. (JO)

10/28/97 (bug fixes) On the Mac, menubars assigned to toplevels would
disappear after a menu item was invoked from them. On Windows,
clicking a system menu with added items and then again with a
different set of added items would crash. On all platforms, a command
menu entry that caused the entry to be deleted, another one created in
its place, and the replacement deleted would cause a panic. On Unix,
<<MenuSelect>> event bindings were firing every time the mouse moved,
instead of everytime the active menu item changed. (SRP)

10/27/97 (bug fix) If a particular race condition occurred under Windows,
Tk would crash complaining about trying to free a color that wasn't
allocated. (SS)

10/28/97 (bug fix) Under Windows, button grabs did not report motion
events that occurred outside of Tk windows. (SS)

10/28/97 (bug fix) Fixed incorrect display of transparent images on
the Macintosh. (JI)

10/29/97 (bug fix) Reworked the handling of out-of-range indices in
the widget command for listboxes: there were all sorts of quirks
before (e.g., ".l delete -1" actually deleted the first element
of the listbox). (JO)

10/29/97 (bug fix) Fixed crash on the Macintosh that could occur if a
window is moved before it is mapped where the X window was created but
the Macintosh port was not. (RJ)

10/29/97 (bug fix) Fixed several errors in how wm state was maintained
on the Macintosh.  Tk now also will iconify a toplevel window on the
Mac if the new Appearance Manager is present. (RJ)

10/28/97 (bug fixes) In canvas' postscript command: User name
information was leaked in safe interpreters on Unix (security fix).
Errors while reading prolog.ps were not propagated and the error
message was mixed with partial data. Note: postscript output does
not work in safe interpreters on unix and windows. (DL)

10/28/97 (bug fix) Safe Tk interps on unix were leaking env(DISPLAY). (DL)

10/31/97 (bug fix) Fixed problems related to the input focus when one
application had windows open simultaneously on several displays. (JO)

10/31/97 (bug fix) Fixed several problems with traversal of menus via
the keyboard under Unix. (SRP)

11/4/97 (bug fix) Fixed various word-size related problems for 64-bit
architectures. (SS)

11/5/97 (bug fix) Embedding on Windows was using freed data (crashing
in safe.test with TCL_MEM_DEBUG). NB: Embedding is still not fully
implemented on Windows ! (It works mostly when Tk is embeded into it's
own Tk frame (safe::loadTk case), but not well with respect to resizing
with a toplevel container or with an external process). (DL)

----------------- Released 8.0p1, 11/7/97 -----------------------

11/20/97 (bug fix) Fixed bug on the Mac where the "package require"
command caused menus to stop working. (JI)

11/20/97 (bug fix) Fixed bug in rendering transparent gifs on Text
widgets. (JI)

11/20/97 (enhancement) Made the changes required to work with the new
Apple Universal Headers V. 3.0 so we can compile with CW Pro 2.0 (JI)

----------------- Released 8.0p2, 11/25/97 -----------------------

11/25/97 (security bug fix + added feature) Tk Safe Init now asks
the master's safe::TkInit for the 'argv' to use. This is transparently
dealt with by the safe::loadTk API. New optional "-display displayName"
argument to safe::loadTk, and the "-use" argument accepts both window
Ids and Tk window names: see loadTk(n). Made the ":0.0" default display
work on the Mac as it works on Windows and Unix. (DL)

12/3/97 (bug fix/optimization) Removed unneeded and potentially dangerous
instances of double evaluations if "if" and "expr" statements from
the library files. It is recommended that unless you need a double
evaluation you always use "expr {...}" instead of "expr ..." and
"if {...} ..." instead of "if ... ...". It will also be faster
thanks to the byte compiler. (DL)

12/3/97 (new feature) Added support for browser/plugin style embedding,
and made various other fixes to get the plugin working on the Mac. (JI)

12/8/97 (bug fix) on Windows, using "winfo pathname" before "." was mapped
was crashing. (DL)

---- Shipped as part of the plugin2.0b5 as 8.0p2Plugin1, Dec 8th 97 ----

12/97 (bug fix) more Macintosh embeding fixes needed for the plugin. (JI)

Jan/9/98 (improvement) Allow applications to have custom init script
without  having to patch the Tk core: Tk_Init will use an existing
"tkInit" proc if one exists in the interp where one tries to install Tk
instead of defining it's own (tkInit is the transient proc defined in
generic/tkInitScript.h that searches and sources tk.tcl and defines
the 'correct' tk_library). (DL)

---- Shipped as part of the plugin2.0 as 8.0p2Plugin2, Jan 15th 98 ----

6/3/98 (bug fix) Fixed bugs in the tk_getOpenFile under Unix.
 1) If the -initialdir option was "." the result would be "././foo.tcl"
    instead of an absolute path, like the Windows interface.
 2) There is a traceVar on the data(selectPath) where the script was
    assumes the window exists. (BS)

6/12/98 (feature change) Focus -force now sets the foreground window
on Windows platforms in addition to moving the focus. (SS)

6/12/98 (bug fix) Fixed bug in Windows font measurement that did not
take kerning into account. (BS)

6/24/98 (bug fix) On Unix, fixed -initialdir switch to tk_getOpenFile
and tk_getSaveFile to convert the specified directory to an absolute
path and to use the current working directory if the specified
directory does not exist. (SS)

6/25/98 (bug fix) On Unix, both the Tk and the Motif file dialogs
would fail if the -parent flag changed between two parent windows that
had been previously used as file dialog parents. (SS)

6/29/98 (compatibility patch)  Added reserved fields to several Tk
structures to match additions made by Jan Nijtmans dash patch.  This
means that extensions can be compiled against the dash patch
and still work with unpatched Tk, and vice versa.

7/6/98 (bug fix) Added keysym definitions for the new keys on the
Microsoft keyboards.  You can bind to <App>, <Win_L>, and <Win_R>,
but you cannot use the Win keys as modifiers. (SS, BW)

7/6/98 (new feature) Added support for the Macintosh Appearance Manager. (JI)

7/24/98 (feature change) Eliminated the static variable that sets
tk_library and simplified search order for tk.tcl.  The tk_library
variable can now be set before calling Tk_Init to avoid doing any
searches.  If it isn't set, then Tk checks env(TK_LIBRARY), relative
to tcl_library, an install directory relative to the executable, a
source directory relative to the executable, and a tk directory
relative to the source heirarchy containing the executable.  See the
comment at the top of generic/tkInitScript.h for more details. (SS)

7/27/98 (bug fix) The bbox for coords in the canvas were incorrectly
including the center of the coord as part of the bound area.  (RJ)

8/4/98 (bug fix) Fixed memory leak in Windows menu code. (SS)

8/4/98 (bug fix) Fixed bug where bgerror's were not being generated
from menu callbacks on Windows. (SS)

8/4/98 (bug fix) Alt-key bindings were not being handled properly
under Windows, resulting in annoying beeps. (SS)

8/4/98 (bug fix) Fixed bug in Windows menubar handling that allowed
a shared menubar to be deleted when any window using it was deleted. (SS)

8/4/98 (feature change) Introduced TkReadBitmapFile to replace
XReadBitmapFile so that all Tk file opens go through the Tcl channel
mechanism.  This lets us wrap applications that define their own
bitmaps and cursors. Note that XReadBitmapFile is no longer
emulated for non-unix platforms platforms (RJ, BW)

8/5/98 (bug fix) <Insert> binding in entries was masking the virtual
event <<Paste>> binding to Shift-Insert on Windows. (SS)

8/5/98 (bug fix) wm frame would crash if the window had not been
mapped yet on Windows. (SS)

8/5/98 (bug fix) Local grabs did not exclude menus or the caption bar
under Windows. (SS)

8/5/98 (bug fix) Reduced message traffic by setting
WS_EX_NOPARENTNOTIFY on TkChild windows. (SS)

8/6/98 (feature change) Changed tkInitScript.h to use the new
tcl_findLibrary procedure to locate its script library. (BW)

8/10/98 (bug fix) Added special case to font code to limit the
length of displayed strings to avoid wrap-around bugs in some
PC X servers when the pixel length of the string exceeds 0x7fff. (SS)

8/12/98 (bug fix) Macintosh, lock down some of the resources
associated with menus to try and stabilise the menu system
on memory limited machines. (JI)

8/12/98 (windows build change) Moved the tkConsole.obj into the tk80.dll
on windows.  If you build your own Tk main program, you no longer
need to compile and link this yourself. (SKS)

-------- Released 8.0.3 to the Tcl Consortium CD-ROM project, 8/13/98 ------

10/5/98 (new feature) Added the event "MouseWheel" that will fire on
Windows applications in response to mouse wheel movement.  You can
bind to the MouseWheel event and use the %D substitution to get the
delta the wheel moved.  The "event generate" command has also been
enhanced with the -delta flag so you can generate these events from
Tcl.  See the bind and event man pages for more details.  The listbox
and text widgets' default bindings have been updated to understand
MouseWheel events. (RJ)

10/12/98 (performance improvement) Added hash table to canvas widget
that holds numeric ids for items.  The hash table makes item lookup
almost constant time which improves certain canvas operations
(exspecially for canvases with large number items).  Thanks to Mark
Weissman <[email protected]> and Jan Nijtmans <[email protected]>
for submitting this improvement.  (RJ)

10/15/98 (bug fix) The -fill option to text items in the canvas did
not allow the empty string as an argument (meaning transparent) even
though every other item type did.  Thanks to Sebastian Wangnick
<[email protected]> for supplying this patch. (RJ)

10/20/98 (feature change) The Makefile and configure scripts have been
changed for IRIX to build n32 binaries instead of the old 32 abi
format.  If you have extensions built with the o32 abi's you will need
to update them to n32 for them to work with Tcl.  (RJ)
*** POTENTIAL INCOMPATIBILITY ***

11/10/98 (feature change) The Macintosh menus will use the Appearance
Theme backgrounds, separators and menu shape, if Appearance version
1.0.1 or greater is installed.  The version of Appearance that shipped
with MacOS 8.0 so it will not work with a straight 8.0, but it will
with MacOS 8.1 or later. (JI)

----------------- Released 8.0.4, 11/20/98 -----------------------

11/24/98 (bug fix) On some X servers, XQueryLoadFont will always
return a font, even if the name is meaningless.  This prevents Tk from
parsing the font name, so now we perform a quick sanity check on the
name before letting X have it. (stanton)

12/30/98 (bug fix) Fixed bug in "grid forget" that failed to cancel
pending idle handlers, resulting in a crash in a few odd cases. (stanton)

1/28/99 (configure change) Now support -pipe option on gcc.  (RJ)

2/4/99 (bug fix) Changed so color tables in photo images are freed
immediately instead of being delayed.  This ensures that color tables
are properly disposed at process exit. (stanton)

2/4/99 (bug fix) Changed postscript template to	include a European
character with an umlaut when determining font height. (stanton)

2/4/99 (bug fix) If an image bitmap mask changed but ended up with the
same XID, the GC failed to be updated and so the new mask was
not used. (stanton)

2/4/99 (bug fix) Changed so focus window is always set if -force is
specified.  This fixes the problem on Windows where Tk does not
activate the window if it already has focus. (stanton)

2/4/99 (bug fix) Fixed so errors in console eval are reported
properly.  Eliminated duplicate result messages. (stanton)

2/4/99 (bug fix) Under Windows, changed so toplevels that aren't
resizable don't have resize handles and the zoom box is disabled. (stanton)

2/4/99 (bug fix) Changed to cancel the mouse timer when a user
initiated move/resize loop begins on Windows. (stanton)

2/4/99 (configure change) TK_LD_SEARCH_FLAGS was set incorrectly if
SHLIB_LD_LIBS='${LIBS}', and shared linking is performed through the C
compiler. Systems affected are Linux, MP-RAS and NEXTSTEP, but also
with gcc on many more systems.

2/4/99 (bug fix) Changed some EXTERN declarations to extern since they
are not defining exported interfaces.  This avoids generating useless
declspec() attributes and makes the Windows makefile simpler. (stanton)

2/4/99 (bug fix) Changed so keyboard shortcuts will only be found in
the current toplevel.  Previously, they might be found in menus
attached to other toplevels that might not even be mapped. (stanton)
*** POTENTIAL INCOMPATIBILITY ***

2/4/99 (bug fix) Changed to treat zero width lines in the canvas like
they have width 1 for purposes of selection. (stanton)

2/4/99 (bug fix) Added a workaround for a bug in GetTextExtentExPoint
on Win NT 4.0/Japanese that cause a crash in some cases. (stanton)

2/4/99 (bug fix) Fixed uninitialized memory access bug in Unix send
code. (stanton)

----------------------------------------------------------
Changes for Tk 8.0 go above this line.
Changes for Tk 8.1 go below this line.
----------------------------------------------------------

1/16/98 (new feature) Tk now supports international characters sets:
    - Font display mechanism overhauled to display Unicode strings
      containing full set of international characters.  You do not need
      Unicode fonts on your system in order to use tk or see international
      characters.  For those familiar with the Japanese or Chinese patches,
      there is no "-kanjifont" option.  Characters from any available fonts
      will automatically be used if the widget's originally selected font is
      not capable of displaying a given character.
    - Textual widgets are international aware.  For instance, cursor
      positioning commands would now move the cursor forwards/back by 1
      international character, not by 1 byte.
    - Input Method Editors (IMEs) work on Mac and Windows.  Unix is still in
      progress.

7/7/97 (new feature) The send command now works for Microsoft
Windows. It is implemented using Dynamic Data Exchange, and a new
command, dde, allows Tk to send more generic DDE commands to other
applications. (SRP)

11/3/97 (new feature) Major overhaul of code that manages configuration
options to use Tcl_Obj structures instead of strings:
    - There is a new set of procedures including Tk_CreateOptionTable,
      Tk_InitOptions, and Tk_SetOptions, which replace Tk_ConfigureWidget
      and related procedures.  The old procedures are still available.
      The new procedures use a new format for configuration tables.
      See SetOptions.3 for more information.
    - There are new procedures Tk_AllocColorFromObj, Tk_GetColorFromObj,
      and Tk_FreeColorFromObj to manage colors using objects to hold the
      name of the color and cache the corresponding XColor pointer.
      There are similar procedures Tk_Alloc3DBorderFromObj,
      Tk_AllocBitmapFromObj, Tk_AllocCursorFromObj, Tk_AllocFontFromObj,
      and so on to manage borders, bitmaps, cursors, and fonts.
    - The old-style procedures such as Tk_GetColor and Tk_GetBitmap no
      longer take Tk_Uids for arguments; they just take strings.
    - Menus, labels, buttons, checkbuttons, and radiobuttons have been
      converted to use the new object-based configuration library.
      (SRP & JO)

11/7/97 (improvement) Changed code referring to "interp->result" to call
accessor functions like Tcl_SetResult().

12/23/97 (fix) Fixed transparency and web optimized the palette of
the images/ Tcl powered logos. (DL)

12/16/97 (bug fix) Canvas and text "bind" subcommands generated an
error with no message if called to fetch a binding that didn't exist.
They now silently return without an error like the "bind" command. (SS)

1/13/98 (bug fix) Keysyms for international characters were not being
reported properly under Windows. (SS)

----------------- Released 8.1a1, 1/22/98 -----------------------

2/4/98 (bug fix) Calling XFreeFontNames() twice if couldn't allocate
font. (CCS)

2/10/98 (bug fix) Inlined prolog.ps in tkCanvPs.c to make it accessible
from safe interpreters: canvas postscript now works in safe interps
(like in tk8.0plugin). (DL)

2/11/98 (bug fix) Windows "send" to a remote interp wasn't propagating
$errorInfo correctly from the remote interp to the local invoking interp.
(CCS)

2/11/98 (bug fix) Windows "send" should have accepted "--" to mean "no more
arguments". (CCS)

2/11/98 (bug fix) Windows "send" was concatenating its arguments
incorrectly (not consistent with "eval", "uplevel", or Unix "send"). (CCS)

2/18/98 (bug fix) Macintosh radiobuttons and checkbuttons now color
their backgrounds correctly under Appearance.  The controls gadgets themselves
however, remain the Theme colors. (JI)

2/18/98 (improvement) The corner pixels that peek through around the
rounded corners of the Mac button widget are now controlled by the
-highlightbackground, rather than the -background option. (JI)

2/18/98 (improvement) Implemented the intra-application Send on the
Mac (RJ)

2/18/98 (bug fix) Under X, a problem mapping from a fontStructPtr to an
XLFD (no XA_FONT attribute) would lead to dereferencing NULL. (CCS)

----------------- Released 8.1a2, Feb 20 1998 -----------------------

10/21/98 (bug fix) Tk_UnderlineChars did not handle UTF strings properly
so underline indices were in bytes instead of characters. (stanton)

11/19/98 (bug fix) Fixed menus and titles so they properly display
Unicode characters under Windows. [Bug: 819] (stanton)

11/24/98 (bug fix) Fixed a bunch of memory leaks in the Windows menu
code. [Bug: 620] (stanton)

11/25/98 (bug fix) Various small bug fixes: (stanton)
	- hidemargin option was not honored properly in menus [Bug: 859]
	- disabled menu entries were getting reenabled whenever the
	mouse passed over the entry [Bug: 860]
	- fixed deletion order bug where a crash would result if a
	binding deleted "."

11/30/98 (bug fix) The error result was getting lost when restoring
configuration options in buttons. [Bug: 619] (stanton)

12/8/98 (bug fix) The Windows clipboard was not correctly traslating
multibyte characters. [Bug: 935] (stanton)

----------------- Released 8.1b1, Dec 11 1998 -----------------------

1/29/99 (bug fix) Fixed bug in "grid forget" that failed to cancel
pending idle handlers, resulting in a crash in a few odd
cases. (stanton)

2/4/99 (bug fix): Fixed uninitialized memory access in
Tk_SetAppName. [Bug: 919] (stanton)

2/4/99 (bug fix): Added a workaround for a bug in GetTextExtentExPoint
on Win NT 4.0/Japanese. [Bug: 1006] (stanton)

2/4/99 (bug fix): Changed so keyboard shortcuts for menus will only be
found in the current toplevel.  Previously, they might be found in
menus attached to other toplevels that might not even be mapped.
[Bug: 924] (stanton)

2/4/99 (bug fix): Changed to treat zero width lines in the canvas like
they have width 1 for purposes of selection. [Bug: 925] (stanton)

2/4/99 (bug fix): TK_LD_SEARCH_FLAGS was set incorrectly if
SHLIB_LD_LIBS='${LIBS}', and shared linking is performed through the C
compiler. Systems affected are Linux, MP-RAS and NEXTSTEP, but also
with gcc on many more systems. [Bug: 908] (stanton)

2/4/99 (feature enhancement): Changed so windows that aren't resizable
don't have resize handles and the zoom box is disabled on
Windows. (stanton)

2/4/99 (bug fix): Fixed so errors in console eval are reported
properly.  Eliminated duplicate result messages. [Bug: 973] (stanton)

2/4/99 (bug fix): Changed so focus window is always set if -force is
specified.  This fixes the problem on Windows where Tk does not
activate the window if it already has focus. (stanton)

2/4/99 (bug fix): If an image mask changed but ended up with the same
XID, the GC failed to be updated and so the new mask was not
used. [Bug: 970] (stanton)

2/12/99 (new feature): Tk is now thread safe.  You enable this by
configuring with --enable-threads.  Tcl must also be compiled with
--enable-threads.  See Tcl for more information about the threading
interfaces. (lfb)

2/25/99 (bug fix) Under Windows, wish can now inherit pipe handles on
stdio so it is possible to use the wish executable in a command
pipeline to capture the output of puts or read from the pipe with
gets.  (redman)

3/1/99 (bug fix) Under Windows, Tk was not properly handling focus and
activation changes in some cases. (redman)

3/10/99 (new feature) Tk now uses the new stub library feature in Tcl.
The Tk library now contains no direct references to any symbols in
Tcl.  In addition, there is a new Tk_MainEx() function that takes an
interpreter as an argument.  See the Tcl documentation for more
information about the stubs mechanism. (redman)

3/14/99 (feature change) Test suite now uses "test" namespace to
define the test procedure and other auxiliary procedures as well as
global variables.
    - Global array testConfige is now called ::test::testConfig.
    - Global variable VERBOSE is now called ::test::verbose, and
      ::test::verbose no longer works with numerical values.  We've
      switched to a bitwise character string.  You can set
      ::test::verbose by using the -verbose option on the Tk command
      line.
    - Global variable TESTS is now called ::test::matchingTests, and
      can be set on the Tk command line via the -match option.
    - There is now a ::test::skipTests variable (works similarly to
      ::test::matchTests) that can be set on the Tk command line via
      the -match option.
    - The test suite can now be run in any working directory.  When
      you run "make test", the working directory is nolonger switched
      to ../tests.
(hirschl)
*** POTENTIAL INCOMPATIBILITY ***

----------------- Released 8.1b2, March 16, 1999 ---------------------

3/23/99 (feature change) Test suite now uses "tcltest" namespace to
define the test procedure and other auxiliary procedures as well as
global variables.  The previously chosen "test" namespace was thought
to be too generic and likely to create conflits.
(hirschl)
*** POTENTIAL INCOMPATIBILITY ***

3/26/99 [bug fix]  Fixed bug reported by Bryan Oakley in the
menubutton bindings.  There was a false assumption that there was
always a menu attached to the button.  [Bug 1116] (surles)

3/26/99 (feature change) Removed --enable-tcl-stub from the configure
script. Linking Tk to Tcl stubs is causing too many problems when
linking executables like wish.  Until the Tk is a fully loadable
extension, linking against the Tcl stubs is not supported in Tk.
(redman)

3/26/99 (feature change) --nameble-shared is now the default and builds
Tk as a shared library; specify --disable-shared to build a static Tk
library and shell.
*** POTENTIAL INCOMPATIBILITY ***

3/29/99 (api change) Standardized text layout and font interfaces
so they are consistent with respect to byte versus character
oriented indices.  The layout functions all manipulate character
oriented values while the lower level measurement functions all
operate on byte oriented values. (stanton)

4/1/99 (bug fix) Image handlers are finalized before the font subsystem
to fix crashes during finalization of complex widgets. (stanton)

4/1/99 (feature change) Removed the send command on Windows.  Moved
the DDE basis of that command out to its own extension.  The send
implementation on top of DDE was causing Tk to lock up in some cases.
(redman)

4/5/99 (bug fix) Fixed handling of Unicode in text searches.  The
-count option was returning byte counts instead of character counts.

4/5/99 (feature change) Cut and paste to an entry widget returns the
selection instead of the widget contents, which can be different if the
-show option is used to hide the display. (stanton)

--------------- Released 8.1b3, April 6, 1999 ----------------------

4/20/99 (compiler fix) changed definition of Status type to use a
typedef instead of a #define to avoid conflicting with the cygwin win32
headers. (redman)

4/22/99 (bug fix) Set the -translation and -encoding options to binary
for image files. (redman)

4/27/99 (bug fix) Changed to avoid the need for forward declarations in
stub initializers.  Added extern "C" blocks around stub table pointer
declarations so the stubs can be used from C++ code. (stanton)

--------------- Released 8.1 final, April 29, 1999 ----------------------

5/7/99 (bug fix) Fixed bug wheretk_popup fails when called too
quickly. [Bug: 2009] (stanton)

5/18/99 (bug fix) Fixed clipboard code so it handles Unicode data
properly on Windows NT and 95. [Bug: 1791] (stanton)

5/19/99 (bug fix) Add extern "C" block around entire header file for
C++ compilers to fix linkage issues.  Submitted by Don Porter and Paul
Duffin. (redman)

--------------- Released 8.1.1, May 25, 1999 ----------------------

5/21/99 (bug fix) Fixed clipboard code to handle lack of CF_LOCALE
information (from command.com).  (stanton)

6/1/99  (bug fix) Improved I18N selection support.  COMPOUND_TEXT
is converted to/from iso2022, and STRING is converted to/from
iso8859-1.  More work is needed.  (stanton)

6/3/99  (bug fix) Fixed selection code to handle Unicode data in
COMPOUND_TEXT and STRING selections.  [Bug: 1791] (stanton)

6/16/99 (new feature) Changes to makefiles and configure scripts to
support TEA specification.  (wart)

6/30/99 (bug fix) Removed deprecated functions, patch from Jan
Nijtmans. [Bug 2080] (redman)

6/30/99 (bug fix) Applied patch to allow Img extension to work with
8.2, patch from Jan Nijtmans.  [Bug 2068] (redman)

6/30/99 (bug fix) Applied patch from Don Porter to prevent the Windows
shutdown code from calling Tcl functions when the stub table has not
been initialized in TkWinWmCleanup. [Bug: 2269] (redman)

7/8/99  (bug fix) Changed TkWinChildProc to pass WM_WINDOWSPOSCHANGED
through to DefWindowProc to make OpenGL sub-windows happpy.  This
allows Windows to generate the WM_SIZE and WM_MOVE messages. (stanton)

--------------- Released 8.2b1, July 14, 1999 ----------------------

7/16/99 (bug fix) Copy prolog.ps from the generic directory for
install-libraries make target. (redman)

7/22/99 (bug fix) Applied patch from Jeff Hobbs to fix
library/menu.tcl. [Bug: 2425] (redman)

7/22/99 (bug fix) Make install-sh have executable permissions before
calling from the Makefile. [Bug: 2413] (redman)

7/22/99 (bug fix) Block out sys/stat.h include with #if to allow
extension writers to use the MetroWerks compiler on Windows.
[Bug: 2385] (redman)

7/29/99 (bug fix) Allow tcl to opn CON and NUL on Windows, moved check
to Tk Console code instead.  [Bug: 2393 2392 2209 2458] (redman)

7/30/99 (bug fix) corrected the Windows build of threaded Tk from both
sets of makefiles (nmake and gmake). (redman)

7/30/99 (bug fix) Added XFillRectangle to stub table, patch from Jan
Njitmans.  [Bug: 2446] (hobbs)

8/1/99  (bug fix) Wrapped #define of panic() inside #ifndef blocks to
avoid compiler errors on Macintosh.  Patch from Vince Darley.
[Bug: 2389] (hobbs)

--------------- Released 8.2b2, August 5, 1999 ----------------------

8/13/99 (Mac) Rearranged the projects in the tkMacProjects.sea.hqx so
that the build directory is separate from the sources.  Fixed bug in
Tk_DrawChars(). (Jim Ingham)

--------------- Released 8.2.0, August 17, 1999 ----------------------

9/21/99 (bug fix) fixed 'wm deiconify' quirks on Windows. (hobbs)

9/21/99 (bug fix) fix fg<>bg GC swap bug for canvas. [Bug: 2676] (hobbs)

9/21/99 (config fix) fixed AIX config issues for Tk. (hobbs)

9/24/99 (feature change) tk_dialog now uses {Times 12} by default. (hobbs)

--- Released 8.2.1, October 04, 1999 --- See ChangeLog for details ---

10/30/99 (bug fix) fixed XKeysymToKeycode to handle mapping of symbolic
keysyms (Left, Home, ...) with event generate (hobbs)

10/30/99 (bug fix) change tkEntrySeeInsert to avoid the use of a while loop
that could eat CPU tremendously.  Behavior of moving the cursor at the
right edge changes slightly. [Bug: 3195] (hobbs)

10/30/99 (bug fix) changed tkScrollButtonUp to check for existence of
tkPriv(relief) in order to avoid spurious release events (hobbs)

--- Released 8.2.2, November 04, 1999 --- See ChangeLog for details ---

11/19/99 (bug fix) fixed expression error that could cause
'malformed bucket chain' error in tkEntry.c. (hobbs)

11/19/99 (bug fix) fixed Tk_NameOfColor (hobbs)

--- Released 8.2.3, December 16, 1999 --- See ChangeLog for details ---

1999-09-01 (feature enhancement) rewrote runtime libraries to use new
Tcl functions where appropriate

1999-10-28 (feature enhancement) added Img patch from Jan Nijtmans that
makes the image command Tcl_Obj-based, adds support for binary -data args,
adds alpha channel to images, adds GIF write capability (RLE).  Binary
compatability is maintained, and source level compatibility is retained
with -DUSE_OLD_IMAGE. (nijtmans)

1999-11-16 (feature enhancement) made listbox Tcl_Obj based, added
-listvariable option and itemconfigure command to allow coloring
individual items. (melski)

1999-11-23 (feature enhancement) added TK_OPTION_DONT_SET_DEFAULT as an
equivalent to TK_CONFIG_DONT_SET_DEFAULT (hobbs)

1999-11-24 (feature enhancement) updated dialogs to use color icons on
Unix, center properly over -parent. (hipp, hobbs)

1999-12-01 (feature enhancement) added hooks into main() code to support
"big" shells more easily. (redman)

1999-12-02 (feature enhancement) converted Tk_DestroyCmd, Tk_LowerCmd and
Tk_RaiseCmd to their ObjCmd equivalent.

1999-12-12 (bug fix) fixed bug in TextSearchCmd for multibyte chars

1999-12-13 (feature enhancement) added support for pointer warping via the
event -warp option, added some items from Dash patch: canvas widget now
Tcl_Obj-based, added Tk_CreateSmoothMethod, added support for <Quadruple>
clicks, entry widget validation routines, new -state hidden in text
widgets, new -state -active* -disabled* -offset options to canvas items
(see man page for full docs).  New features include dashed line support on
the canvas, -elide support for TkMan, postscript printing of images and
windows from the canvas.  Binary compatibility is maintained with 8.2, and
source level compatibility is kept by using -DUSE_OLD_CANVAS.
(hobbs, nijtmans, et al)

1999-12-16 (feature enhancement) added "bitstream cyberbit" to list of
font fallbacks. (hobbs)

1999-12-16 (feature enhancement) added new 'tk useinputmethods ...' command
to provide support for disabling/enabling the use of XIM on X.  This was
previously all done at compile time, and always on.  Now it is turned off
by default, even when available, and the user must turn it on to use XIM
(per display).
	*** POTENTIAL INCOMPATIBILITY ***
user must add 'tk useinputmethods 1' to retain old style. (hobbs)

1999-12-16 (feature enhancement) added proper support for -initialfile
to tk_get*File, and made Unix version better match Windows file box
that it was emulating. (hobbs)

1999-12-16 (bug fix) removed necessity of 'update idle' before 'wm
deiconify' on Windows. (mao)

1999-12-16 (feature enhancement) added support for Windows system cursors
to TkGetCursorByName (use -cursor @filename)

1999-12-21 (bug fix) fixed lack of refresh for thin frames (darley)

1999-12-21 (bug fix) fixed panic in Tk_CoordsToWindow to print error
to stderr instead (for Tix) (hobbs)

1999-12-21 (bug fix) fixed segv with scale widget when using -cursor (hobbs)

--- Released 8.3b1, December 22, 1999 --- See ChangeLog for details ---

2000-01-05 (bug fix) Applied fixes for unprotected arg passing through eval
and after in Tk runtime code [Bug: 3943] (hobbs)

2000-01-05 (bug fix) Applied fix for i18n problems with Mac clipboard
[Bug: 3544] (hobbs)

2000-01-05 (feature change) removed the 8.3b1 introduced -state option
for text tags, and documented -elide (-state hidden == -elide true) (hobbs)

2000-01-12 (bug fix) fix Windows 'wm deiconify' to zoomed state [Bug: 2077]
and fixed possible flashing of unmapped toplevel in deiconify [Bug: 3338]
and fixed unwanted mapping of transient window [Bug: 572] (hobbs)

2000-01-12 (feature enhancement) extended 'wm state' to accept a state
to set for the toplevel, and added support for zoomed (maximized) state
on Windows (hobbs)

2000-01-12 (bug fix) Applied fix for cursor to not blink when entry or
text widget was disabled [Bug: 1807] (hobbs)

--- Released 8.3b2, January 13, 2000 --- See ChangeLog for details ---

2000-01-20 (bug fix) fixed interpretation of consecutive ^ characters in
grid command (melski)

2000-01-20 (bug fix) fixed -select(bg|fg) class names in listbox (hobbs)

2000-01-20 (bug fix) fixed handling of too few coords for line item type in
canvas (hobbs)

2000-01-20 (bug fix) fixed dialog's association with parent (melski)

2000-01-26 (bug fix) fixed handling of binary data for -data option to
image create (melski)

2000-01-26 (feature enhancement) improved GIF decoding speed by ~60%
(melski)

2000-01-26 (feature enhancement) added tk_chooseDirectory implementation
for Unix and Mac (nelson, melski)

2000-02-01 (bug fix) fixed resolution rounding problem in scale (porter)
and fixed potential Unix seg fault due to use of ckfree instead of
Tcl_EventuallyFree (hobbs)

2000-02-01 (bug fix) fixed handling of negative dash values for canvas
items (nijtmans)

2000-02-01 (bug fix) fixed dialog lockup on Windows where once the native
dialog disappeared, the parent window could end up locked up (hobbs)

2000-02-03 (bug fix) fixed text dump to use char indices instead of byte
indices (melski)

2000-02-07 (bug fix) fixed handling of default extension in unix file
dialogs (dejong)

2000-02-08 (bug fix) corrected windows symbol font use to restrict itself
to 8-bit chars (kenny)

2000-02-08 (feature enhancement) improved support for moving from the old
style image C API to the new obj'ified one with new Tk_InitImageArgs
command and stub'ing of image code.  See docs for how to make the
transition. (nijtmans)

2000-02-08 (bug fix) fixed incorrect handling of CapsLock on Win9* and the
use of dead keys on international keyboards (spjuth)

2000-02-10 (bug fix) brought Mac back to building state, added support
for Appearance Manager (ingham)

2000-02-10 (feature enhancement) added support for buttons 4 && 5 as
mousewheel style scrolling in listbox and text widget for Unix.

--- Released 8.3.0, February 10, 2000 --- See ChangeLog for details ---

2000-03-02 (bug fix) fixed crash in listbox when cursor was configure and
then widget was destroyed (hobbs)

2000-03-02 (feature enhancement) added %V substitution to entry widget
validation to clarify type of validation occuring (hobbs)

2000-03-07 (feature enhancement) added -disabledforeground/-state to labels
(melski)

2000-03-29 (config enhancement) improved build support for gcc/mingw on
Windows (nijtmans, hobbs) and added RPM target (melski)

2000-03-24 (bug fixes) numerous corrections for more correct Unix dialog
behaviors (melski)

2000-03-27 (bug fix) fixed mem leak in wm commands (hu)

2000-03-31 (bug fix) correct initialization of Windows static builds and
added Unicode aware open/save file dialogs on Windows (hobbs)

2000-03 (bug fix) canvas: corrected support for transparency in dashed
lines on Windows (nijtmans); added support for postscript generation of
images on Windows, also fixing transparency printing (biancardi); corrected
handling of configure options in non-empty canvas (melski)

2000-04-07 (bug fix) correct font name length restriction that prevented
the use of long named (>16 char) fonts on NT/2000 (hobbs)

2000-04-07 (bug fix) fixed safe Tk to work in base cases (hobbs)

2000-04-10 (bug fix) corrected Alt-Key event generation and handling of
Alt-sequence Windows special char generation and (Control|Shift|Alt)_L/_R
determination (melski)

2000-04-10 (bug fix) correctly check state of parent when popping up
bgerror dialog. (melski)

2000-04-11 (feature enhancement) msgcat now searches up the namespace chain
for a match instead of just in the local namespace (hershey)

2000-04-12 (bug fix) corrected handling of Windows clipboard to allow for
use of user-defined types within the Tk app (hobbs)

2000-04-13 (feature enhancement) improved handling of shadow determination
for 3D borders in very light/dark cases (hipp, melski)

2000-04-13 (bug fix) correctly color separator bg in menus on Windows
(melski)

2000-04-14 (bug fix) improved handling of scale widget, reduced number of
redraws (hobbs)

2000-04-17 (feature enhancement) made shift-selection more Windows-like
(intuitive) in text widget (melski)

2000-04-22 (bug fix) mac bug fixes, nav services handling (ingham)

2000-04 more docs for public APIs (melski)

--- Released 8.3.1, April 26, 2000 --- See ChangeLog for details ---
2000-04 (doc updates) extended, updated docs (melski)

2000-05-09 (feature change) removed WS_EX_TOOLWINDOW style bit for
transient windows on Windows platforms, so that transients have
full-size titlebars (melski)

2000-05-09 (bug fix) fixed calling of takeFocus proc (nemethi)

2000-05-11 (bug fix) corrected handling of 3DBorder, Cursor and Color
objects on multiple screens (hobbs)

2000-05-12 (feature enhancement) improved support for chars in 0-255
range for bitmap ANSI fonts (spjuth, hobbs)

2000-05-12 (widget enhancement) added support for -repeatdelay,
-repeatinterval for command buttons; and -compound (image and text
simultaneously) for labels, check-, radio-, and command buttons (melski)

2000-05-14 (widget change) added "readonly" state for entries and
changed behavior of "disabled" entries; added -readonlybackground
option for entries (melski)
*** THIS IS A BACKWARDS INCOMPATIBLE BEHAVIOR CHANGE ***

2000-05-15 (feature enhancement) added [image inuse] command (melski)

2000-05-15 (feature enhancement) added -nice option to [bell] command (duncan)

2000-05-17 (widget enhancement) added -overrelief option for
check/radio/buttons (melski)

2000-05-26 (feature change) added support for new syntax in
Tk_OptionSpec tables; if the database name for an option contains an
embedded "." it indicates that the name contains an overriding window
class specifier in addition to the database name, which allows widgets
to perform queries for certain options as if they were options for a
different widget class (melski)

2000-05-28 (new widget) added spinbox widget (hobbs)

2000-05-31 (feature change) replaced bgerror dialog with a new and
improved one (fellows, melski)

--- Released 8.4a1, June 6, 2000 --- See ChangeLog for details ---

2000-05-15 (bug fix) changed wm deiconify from using idle callback to
calling restack and focus code immediately. (hobbs)

2000-07 (build cleanup) cleanup of defines in tkConfig.sh, and cleanup
in make and configure files to better handle .rc files across
builds. (welch)

2000-07 (build improvements) cleanup of the makefiles and configure scripts
to correct support for building under gcc for Windows. (dejong)

2000-08 (feature enhancements) for Windows, corrected drawing of separator
menu entries, disable menu entries and the height for separator
bars. (melski)

2000-08 (bug fix) fixed calling of takeFocus proc with arg bearing
functions. (nemethi)

2000-08 (bug fix) For text widgets, added a test for a NULL segment pointer
when doing backwards searches for "", correct searching over elided chars,
and corrected search combining -regexp and -nocase. (melski)

2000-08 (bug fix) Corrected code for using 'place', cursors, colors and 3D
borders on multiple screens simultaneously. (hobbs, hipp)

--- Released 8.3.2, August 9, 2000 --- See ChangeLog for details ---

2000-06-15 (new feature) [tk_getOpenFile ... -multiple] (melski)

2000-06-29 (new feature) localization support in Tk dialogs (duperval,
melski, et al)

200-07-28 (new feature) -state option for listbox, better native color
defaults (melski)

2000-08 (feature rewrites) Tcl_Obj'ified clipboard, message, tkwait,
bindtags, grab. place, selection commands (melski)

2000-08-24 (new feature) More correct GNU configure support (no more
--enable-gcc) (dejong)
	*** POTENTIAL INCOMPATIBILITY ***

2000-08-29 (bug fix) Corrected Windows menu indicator drawing (oberhumer)

2000-09-01 (bug fix) Added tkPlatDecls.h to default install (melski)

2000-09-17 (new feature) Added TK_OPTION_CUSTOM type, similar to
TK_CONFIG_CUSTOM (melski)

2000-09-29 (bug fix) Several fixes for multi-display uses of Tk (hipp, hobbs)

2000-10-05 (new feature) Tk_CreateAnonymousWindow API to create anonymous
Tk windows controllable from C (melski)

2000-10-27 (new default behavior) [tk useinputmethods 1] is the default
in tk.tcl, for users of XIM and "dead" keys (hobbs)

2000-10-30 Improved support for static builds on Windows (gravereaux)

 * Added support for mingw (gcc on Windows), AIX-5 and Win64 builds
   (dejong, hobbs)

 * Improved error checking in Windows native dialogs (melski, hobbs)

--- Released 8.4a2, November 3, 2000 --- See ChangeLog for details ---

2001-04-04 (build improvements) redid Mac build structure (steffen)
Corrected IRIX-5* configure (english).  Added support for AIX-5 (hobbs).
Added support for Win64 (hobbs).

2001-04-04 (doc fixes) numerous doc corrections and clarifications.
Update of READMEs.

2001-04-04 (bug fix) corrected reseting of service mode to only occur when
it was set (hedin, hobbs)

2001-04-02 (bug fix) Improved tests on Windows for correctness.
Checked for menu deletion before calling associated menu entry command.
Fixed listbox, canvas and entry destruction to be more aware of current
widget activity. (hobbs)

2001-03-30 (feature enhancement) added support for changing IME on the fly
in Windows (2000) (lam)
(bug fix) handled the error case where a valid-looking but invalid
identifier could be passed in certain event generate options causing a
crash (hobbs)

2001-03-29 (bug fix) corrected handling of drag-selection (dejong)

2001-01-02 (feature enhancement) added Windows icon support in wm
iconbitmap (darley)

2000-10-27 (feature enhancement) made [tk useinputmethods 1] the default
for Tk (hobbs)

2000-10-18 (bug fix) Corrected rendering of 1-pixel wide stippled lines on
Windows.  Correct use of active- and disabledwidth values for displaying
lines.  Enhanced error handling in Windows native dialogs (melski)

2000-09-29 (bug fix) corrected BadMatch errors when using Tk on multiple
screens (hipp)

2000-08-18 (feature enhancement) Removed redundant call to DitherInstance
(melski)

--- Released 8.3.3, April 6, 2001 --- See ChangeLog for details ---

2000-11-21 (new feature)[TIP 5] Tk_ClassProcs, Tk_SetClassProcs API (melski)

2000-12-13 (performance enhancement)[403327] Tcl_Objs of type "double"
are recognized in SetMMFromAny to speed up canvas coord calculations (hobbs)

2001-01-02 (new feature)[TIP 8] [wn iconbitmap -default] on Windows (darley)

2001-02-12 (new feature)[TIP #21] asymmetric padding in the pack and grid
geometry managers (hipp)

2001-05-21 (new feature)[TIP #11], -compound for [menubutton] widget (helfter)

2001-06-03 (bug fix) corrected support for is10646 fonts on Unix, added a
ucs-2be encoding (welch)

2001-07-02 (bug fix) allowed tkwin to be Tcl_EventuallyFree'd in
Tk_DestroyWindow so other widgets could register their use of it.  Updated
entry and listbox widgets to use this, correcting potential crashes. (hobbs)

2001-08-01 (interface rewrite)[TIP 44] moved all private tk[A-Z]* commands and
variables into the ::tk:: namespace (porter)
	*** POTENTIAL INCOMPATIBILITY ***

 * overhaul of configure scripts for cleaner standard support and support
   of mingw gcc on Windows. (mdejong)

 * improved tests to better handle results on variant systems (hobbs)

 * correct several minor Purify complaints (hobbs)

--- Released 8.4a3, August 6, 2000 --- See ChangeLog for details ---

2001-08-06 (new feature) added GNU (HURD) build support. (brinkman)

2001-08-23 (new feature) added QNX-6 build support. (loverso)

2001-08-24 (bug fix) correct several possible free memory reads and array
bounds read errors reported by purify. (hobbs)

2001-08-27 (new feature) added call to Tcl_SetMainLoop which enables Tk to
be loaded interactively into tclsh and have the event loop kick in
correctly. (hobbs)

2001-08-28 (bug fix) fixed tk_chooseDirectory crash on Win95. (baker)

2001-08-28 (bug fix) removed 2 second 'raise' delay seen by some Unix
window managers. (hobbs, baker)

2001-09-14 (bug fix) fixed memory leaks that occurred if errors were
thrown while initializing the channel for an image. (darley)

2001-09-20 (new feature) --enable-64bit support was added for HP 11 when
using the native compiler.

2001-10-03 (new feature) finalized Win64 support with latest RC1 release
and SDK. (hobbs, stacy)

2001-10-04 (new feature) added enhanced bgerror dialog from Hipp. (hobbs)

2001-10-09 (new feature) added brace/quote matching and file/path/var
expansion to the Win/Mac console. (hobbs)

2001-10-17 (bug fix) fixed file filtering in the motif file dialog (nelson)

2001-10-17 (bug fix) updated Mac build support. (steffen)

--- Released 8.3.4, October 19, 2001 --- See ChangeLog for details ---

2001-08-14 (bug fix)[450545] Tk's Tcl_ObjTypes now registered (fellows)

2001-08-20 (performance enhancement) internal use of a "window" Tcl_ObjType
(fellows)

2001-08-20 (performance enhancement) Obj-ified [grid] and [pack] (spjuth)

2001-09-26 (new feature)[TIP 18] add labels to frames, update geometry
managers (spjuth)

2001-09-30 (new feature)[TIP 37] [grid {row|column}configure -uniform] (spjuth)

2001-10-12 (new feature)[TIP 63] [$menu add ... -compound] (helfter)

2001-10-18 (build improvement) no more warnings about building with
thread-enabled Tcl (hobbs)

2001-11-10 (build improvement) new make target 'make gdb' (dejong)

2001-11-12 (new feature)[TIP 26] simple undo/redo in text widget (callewaert)

2001-11-12 (build improvement) revitalized makefile.vc (gravereaux)

2001-11-17 (visual change) default button size on Windows changed to
conform to Windows style (hobbs)
	**** POTENTIAL VISUAL INCOMPATABILITY ****

2001-12-03 (new feature)[TIP 74] [wm stackorder] (dejong, steffen)

2001-12 (new feature) more use of Unicode in native widgets on Windows (hobbs)

2001-12-18 (bug fix)[413735] event-click-drag-1.2 test failure (porter)

2001-12-28 (new feature) On Windows, buttons accept negative widths, meaning
minimum size, enabling native L&F (hobbs)

2002-01 (bug fix) updates for CONST-ification in Tcl API, notably
Tcl_ParseArgv.  Use -DUSE_NON_CONST to suppress source incompatibility
	**** POTENTIAL INCOMPATABILITY ****

2002-01-31 (bug fix)[508988] logic error in menu cloning (helfter)

2002-02-01 (new feature)[TIP 14] [$photo transparency] (fellows)

2002-02-01 (bug fix)[511956] C99 spec: avoid 'bool' as a variable name (hobbs)

2002-02-19 (bug fix) updates to image code calls of Tcl_Seek/Tcl_Tell to
address TIP 72 changes (64-bit) in Tcl (fellows)

2002-02-21 (new widget)[TIP 41] added [panedwindow] (hobbs)

2002-02-22 (new feature)  64-bit support for xlc compiler on AIX-4 (hobbs)

2002-02-25 (bug fix)[503772] blinking cursor fix in [text] (hobbs)

2002-02-25 (bug fix)[503613] [listbox] handling of invalid listvar (hobbs)

2002-02-25 (feature change)[493145] mirror B2 bindings to B3 on Windows (hobbs)

 * (updated demos) many updates to show new features (fellows)

--- Released 8.4a4, March 5, 2002 --- See ChangeLog for details ---

2002-03-20 (feature change)[TIP 27][532644] Constness changes (porter)

2002-03-21 (bug fix)[528441] Change in optimization flags for windows
(gravereaux)

2002-04-08 (bug fix) MSL stdin/out fixes prevent crash on exit  (steffen)

2002-04-12 (bug fix) Centralized closing of display, mem-leak fixes (hobbs)

2002-04-22 (bug fix)[223739] More robust FP comparisons for odd
architectures (fellows)

2002-04-22 (bug fix)[541999] Fixed posible overun of 16-bit size limit
of X windows in drawchars (hobbs,bonfield)

2002-04-22 (bug fix)[541849] ButtonLeave implementation corrected (hobbs)

2002-04-24 (new feature) TCLTK_NO_LIBRARY_TEXT_RESOURCES check added,
allowing disable of inclusion of tk lib into resources (steffen)

2002-05-07 (bug fix)[553208] Makefile/Win fix (TCLDIR, INSTALLDIR
forward slash trouble resolved) (gravereaux)

2002-05-20 (bug fix) msgcat added to resources, fixed setup of bindings
on startup (steffen, porter)

2002-05-21 (bug fix) Build system fix, SC_ENABLE_SHARED before
SC_CONFIG_CFLAGS for usage for SHARED_BUILD (dejong)

2002-05-26 (bug fix)[548765] Fixed -value "" redraw error for variable
created by radiobutton (spjuth)

2002-05-27 (feature change) [wm transient .t .t] now raises an error (dejong)
	*** POTENTIAL INCOMPATIBILITY ***

2002-06-10 (new feature)[566605] Utilities for -underline, ampersand magic
(kovalenko)

2002-06-12 (feature change) A transient toplevel now mirrors state changes
in the master. (dejong)
	*** POTENTIAL INCOMPATIBILITY ***

2002-06-13 (bug fix) Fixed handling of cursor specs across platforms to
be consistent. (fellows)

2002-06-14 (new feature) [TIP 98] Enhanced photo compositing (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

2002-06-14 (bug fix) Removed references to matherr (kupries)

2002-06-14 (new feature) [TIP 47] Reorganized Tk to allow usage in writing
an X wm (english)

2002-06-14 (new feature) [TIP 84] Full motion events upon request (hobbs)

2002-06-17 (new feature) [TIP 82] -offrelief option for check/radiobutton
(hipp)

2002-06-17 (enhancement) Added msg catalog for UK English. (porter)

2002-06-17 (new feature) [TIP 96] Added caret handling (hobbs)

2002-06-19 (new feature) [TIP 48] Added style engine (bonnet)

2002-06-19 (bug fix)[570902] Reorganized Tk shutdown to work around bugs in
X (dejong)

2002-06-20 (new feature) [TIP 94] Added -activestyle for [listbox] (hobbs)

2002-06-21 (new feature) [TIP 104] generalized text undo/redo (callewart,
hobbs)

2002-06-22 (new feature) [TIP 95] Added [wm attributes] command (hobbs)

2002-06-22 (new feature) [TIP 93] enhanced get/delete to accept accept
multiple range pairs (hobbs)

--- Released 8.4b1, July 5, 2002 --- See ChangeLog for details ---

2002-07-11 (bug fix) some memory allocation failures now result in
	error messages rather than panic (fellows)

2002-07-15 (platform support) Borland makefile on Windows (gravereaux,giese)

2002-07-16 (bug fix)[220800,581627] icon reading (darley)

2002-07-19 (bug fix) Postscript generation on Win2K (hipp)

2002-07-22 (bug fix)[570764,568278] transient windows (dejong)

2002-07-24 (bug fix)[581560] canvas memory management (hobbs)

2002-07-24 (bug fix)[584691] focus ring on compound button (hobbs)

2002-07-25 (feature enhancement)[564521] Obj-ified [wm] (spjuth)

2002-08-04 (new feature)[589853][TIP 27] Tk interfaces are now fully
	CONST-ified.  Use the symbols USE_NON_CONST or USE_COMPAT_CONST
	to select interfaces with fewer changes.
        *** POTENTIAL INCOMPATIBILITY ***

2002-08-07 (bug fix)[578654] bezier curves on canvas (hobbs)

2002-08-07 (platform support)[468139] native directory browser on Win (hobbs)

2002-08-07 (bug fix)[467524] fixed -from handling for gifs (obermeier)

2002-08-08 (bug fix)[592201] wm transient panic (english,dejong)

Rewrote Tk test suite to use tcltest package.

--- Released 8.4b2, August 9, 2002 --- See ChangeLog for details ---

2002-08-20 (bug fix) tk.h checks for matching tcl.h version (porter)

2002-08-27 (bug fix)[582457] toolbar button bindings (hipp)

2002-08-31 (platform support)[602770] Mac OS X / Aqua port (steffen)

2002-09-02 (bug fix)[565485] button height on windows (hobbs)

2002-09-02 (new feature)[TIP 108] new comand [tk windowingsystem] (steffen)

2002-09-02 (new feature)[TIP 107][601518] [raise] is non-blocking (english)

2002-09-02 (platfrom support) 64-bit compile on HP-11 (martin)

--- Released 8.4.0, September 10, 2002 --- See ChangeLog for details ---

2002-09-15 (bug fix)[570902] Use PEEK_XCLOSEIM to examine the input context
queue before invoking XCloseIM. Generate an assert if there is an input
context that has not been freed. (dejong)

2002-09-18 (platform support) Updated support for compiling with Cygwin and
either mingw or gcc. (khan, howell, dejong)

2002-09-30 (bug fix)[614650] Correct incremental transfers of UTF8_STRING
selections (fellows)

2002-10-02 (bug fix)[616791, 614474] don't blink the cursor unless it is
visible. (bonfield)

2002-10-02 (bug fix)[607390, 617446] check if the entry is being deleted
before handling an associated textvariable. (hobbs)

2002-10-08 (bug fix)[616589] leave the DestroyPanedWindow proc to free the
pwPtr. (hobbs)

2002-10-08 (bug fix)[588831] Ignore event if we are focusing into a dead
window (griffin)

2002-10-09 (bug fix)[619544] Only error-out creating an image if we fail to
allocate a non-empty buffer (fellows)

2002-10-09 (build support) all --enable-symbols to take the enhanced
options yes|no|mem|all. (hobbs)

2002-10-10 (feature enhancement) added support for generating ps for
embedded widgets on canvases on Windows (hobbs)

2002-10-10 (bug fix)[621241] The grid size was not updated properly when
removing a widget from a grid (forssen)

2002-10-16 (bug fix)[616988] macosx fix to accelerators shown in menus
with non-alphanumeric keys. (darley)

2002-10-15 (platform support) Correct AIX-5 ppc and 4/5 64-bit build flags.
Correct HP 11 64-bit gcc building. (martin, hobbs)

2002-10-17 (bug fix)[624974] fix arg handling for missing image create
photo -format or -data options (hobbs)

2002-10-17 (bug fix)[624732] In ControlUtfProc, properly return the number
of bytes consumed (hobbs)

2002-10-22 (platform support)[624509] On macosx, add embedded framework
dirs to tcl_pkgPath: @executable_path/../Frameworks and
@executable_path/../PrivateFrameworks (if they exist), as well as the dirs
in DYLD_FRAMEWORK_PATH (if set).  Added 'rapp' apple event handler.  Added
TEXT document type to plist so that files can be dragged onto Wish Shell.
Added private proc TkMacOSXUseAntialiasedText() to enable/disable quickdraw
text antialiasing where available, default is enabled.  Added a linked
boolean ::tk::mac::antialiasedtext with write trace to allow control of
antialiasing from tcl.  (steffen)

--- Released 8.4.1, October 22, 2002 --- See ChangeLog for details ---

2002-11-07 (bug fix)[635025,532022] Make [place info] complete and bring into
line with other geometry managers. (spjuth)

2002-11-14 (bug fix)[630533] Handle half-dead windows better. (dejong)

2002-11-19 (bug fix) Better handling of narrow scrollbars on OSX. (ingham)

2002-11-22 (bug fix)[641778] Make the [text see] work when the widget is
unmapped. (hobbs)

2002-12-01 (bug fix) Stopped [wm withdraw] and [wm transient] from interfering
with each other. (dejong)

2002-12-06 (bug fix) Improved DLL cleanup on Windows. (hobbs)

2002-12-06 (new feature) New function TkWinSetHINSTANCE() as part of enabling
dynamic Tk to load resources correctly. (hobbs)

2002-12-13 (bug fix)[616245] Use Tcl*StartupScript*() routines in Tk_Main.
(porter)

2002-12-27 (bug fix)[578569] Made sure that Tk always knows whether its windows
are mapped or not. (english)

2003-01-03 (bug fix)[661792] Stopped crash when trying to create a toplevel
when Tk is dying. (hobbs)

2003-01-08 (bug fix)[663981] Clip long lines so they show correctly even when
they hit windowing-system limits. (hipp)

2003-01-14 (bug fix)[666346] Stopped selection handling crashes under KDE3.0.
(english)

2003-01-22 (bug fix)[220891] Image creation cannot trigger Tk's death.
(fellows)

2003-01-23 (bug fix)[673687] Entry typein works as expected even when the mouse
button is pressed. (hipp)

2003-01-28 (bug fix)[671330] Stopped segfaults from unsynchonized window
deletion epochs. (english)

2003-02-08 (bug fix) Make canvas item coordinate list handling consistent to
stop segfaults.  Cannot now create items without coordinates. (hobbs)
	*** POTENTIAL INCOMPATIBILITY ***

2003-02-10 (bug fix) Better support for themed and animated cursors on OSX.
(ingham)

2003-02-17 (bug fix) Stopped motion events from morphing into button press
and motion events. (dejong)

2003-02-18 (bug fix) Removed memory leak in GIF image loader. (fellows)

2003-02-18 (bug fix) Made OSX menus support UTF8 text and icons. (darley)

2003-02-18 (bug fix)[608559] Stop message boxes from getting extremely wide.
(hobbs)

2003-02-18 (bug fix)[683813] Make focus behaviour of spinboxes more like
entries. (bron)

2003-02-19 (new demo)[627453] New demo showing off Tk's Unicode font handling.
(fellows,suchenwirth)

2003-02-19 (bug fix) Bring event handling more into line with the OSX standard.
Also improves "dead key" handling. (riefenstahl,ingham)

2003-02-20 (bug fix)[618872,689357] Stopped read of freed memory when working
with large composite fonts. (fellows)

2003-02-20 (bug fix)[689099,tcllib 689258] Improvements to [panedwindow] pane
size and sash handling. (spjuth,hobbs)

2003-02-20 (bug fix)[624116] Stopped semi-crash in Windows scrollbar handling.
(hobbs)

2003-02-21 (bug fix)[671122] Stopped panedwindow from crashing when embedded
in a window with a different visual to the root window. (fellows)

2003-02-21 (bug fix)[617392] Limit the screen-size of [tk_get*File] file type
selection menu. (fellows)

2003-02-21 (bug fix)[673722] Rework standard dialogs to use [grid]. (fellows)

2003-02-24 (bug fix)[637828] Report that entries can provide the selection,
even if they're not displaying it. (hobbs)

2003-02-24 (bug fix)[669595] Improved display of indicators in disabled
checkbuttons and radiobuttons. (hintermayer)

2003-02-24 (bug fix)[632514] Allow listbox 'selection includes' to respond
positively when disabled.

2003-02-24 (bug fix)[647497] Make Tk pick the first best matching font on
the font path. (dal zotto)
	*** POTENTIAL VISUAL INCOMPATIBILITY ***

2003-02-25 (bug fix)[621672] Fixed conversion of apple event parameters
to posix path names. (steffen,riefenstahl)

2003-02-25 (feature enhancement)[patch 685388] Support simple XOR text drawing
on Windows. (martin)

2003-02-28 (bug fix)[612110] Make %-substitutions for events only read data out
of the event structure when that field is valid for that event type. (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

--- Released 8.4.2, March 3, 2003 --- See ChangeLog for details ---

2003-03-14 (bug fix)[701812] Stop buttons from being very wide when a
tk_messageBox has a lot of content on Unix

2003-03-18 (bug fix) Fixed crash in [winfo server] on Mac OS X

2003-04-25 (bug fix)[477740] Correct compound button display in the
disabled state

2003-05-10 (bug fix)[734498] Correct crash when generating postscript for a
single-line polygon (point) with no color.

2003-05-13 (feature enhancement)[736774] Use new versioned bundle resource
API to get tk runtime library for TK_VERSION on Mac OS X

2003-05-14 (bug fix)[737790] Updated French message catalog

2003-05-15 (bug fix)[557030] Use gb2312-raw as the alias for gb2312*
charset fonts.  gb2312.enc was made to be euc-cn for Tcl because that is
what is most often meant, but X really wants the original (-raw) gb2312
encoding.

--- Released 8.4.3, May 20, 2003 --- See ChangeLog for details ---

2003-07-07 (bug fix)[749353] Improve deletion of images on exit.

2003-07-15 (bug fix)[465324] Fixed complex bug in menu clone cleanup.

2003-07-15 (bug fix)[755530] Don't test for XCloseIM bug when the XFree86
version is newer than 4.0 since the layout of the XIM structure has
changed.

2003-07-16 (bug fix)[748277, 702230, 738143] Numerous panedwindow fixes.
Ensure that the last pane shrinks instead of being clipped when resized
below the reqsize.  Ensure that we can share GCs between a panedwindow and
its sash proxy, even if the panedwindow is in a toplevel with a different
visual.  Ensure that panedwindows get their geometry right even when their
children don't know their initial size.  Use widget-specific Priv slots for
pwAfterId and panecursor items to correctly handle cursor changes with
adjacant panedwindows.

2003-07-17 (bug fix)[697652] Make sure all options of a frame can be set to
their default value.

2003-07-17 (bug fix)[404421] Try harder to avoid zero-length mallocs() when
creating images.

2003-07-17 (feature enhancement) MacOSX build system rewrite.

2003-07-18 (bug fix) Do not make XGetGeometry call that prevents overwidth
lines drawing on unix as it requires a roundtrip call to the X server for
every string drawn.  Hard-code max width to 32768 until a beter solution to
get max width is made.

2003-07-18 (bug fix)[742660] correct XCreateIC call for TK_XIM_SPOT usage
on unix.

2003-07-18 (bug fix)[420510] Provide consistency between unix and windows
-cursor option.

2003-07-19 (bug fix)[706765] Correctly handle the -sliderrelief option
while moving the thumb.

--- Released 8.4.4, July 22, 2003 --- See ChangeLog for details ---

2003-08-13 (bug fix)[787065] Fix Button-2 binding for scale widget.

2003-08-19 (bug fix)[791500] Fix panedwindow refresh glitches for bg.

2003-09-17 (bug fix)[808039] Prevent [image create] from generating an
image command name that overwrites an existing command.

2003-09-25 (enhancement) Added -compound support for OS X bevel buttons.

2003-10-10 (bug fix) Fix image offset stippling for disabled buttons.

2003-10-22 (enhancement)[827535] Constrain tk_dialog to be sensibly sized and
placed

2003-10-28 (bug fix) Add 16bpp XGetImage support on Windows

2003-10-29 (enhancement)[795717] Allow some control of foreground and
background colors on Tk's tk_getOpenFile/tk_chooseDirectory.

2003-11-01 (enhancement)[820519] Updated Dutch (nl) message catalog.

2003-11-10 (enhancement)[826614] Provide more Tk build info in tkConfig.sh.

2003-11-10 (enhancement)[809157] Add alpha blending for images with partial
transparency on Windows and Unix on 15bpp+ displays.

2003-11-10 (enhancement)[820282] Use the XGCValues.function parameter when
filling rectangles with XFillRectangles on Windows.

2003-11-11 (enhancement)[840107] Add OS X unicode clipboard support.

2003-11-11 (enhancement)[833819] Improve Tk's
tk_getOpenFile/tk_chooseDirectory directory glob'ing speed.

2003-11-11 (bug fix)[836483] Fix mem leak in '$listbox itemconfigure'.

2003-11-11 (bug fix)[723856] Correctly handle menu (un)posting on menus
with spaces in their names.

2003-11-11 (enhancement) Improve AIX-64 build configuration.

2003-11-17 (bug fix) Fix menubutton -compound state disabled drawing.

--- Released 8.4.5, November 20, 2003 --- See ChangeLog for details ---

2003-12-17 (platform support)[842952] Mac OS X: [scrollbar]

2004-02-13 (platform support)[776646] Win: native hand2/fleur cursors

2004-02-03 (enhancement) post menubuttons so they stay on screen.

2004-02-09 (bug fix)[877950] stop crash during intra-image copy/resize

2004-02-10 (enhancement) New msg catalogs for Esperanto and Polish (trzewik)

2004-02-13 (platform support)[478568] Win: bold/italic font handling

2004-02-15 (platform support)[860454] Mac OS X: [event generate]

2004-02-15 (platform support)[840107] Mac OS X: Unicode clipboard (senn)

2004-02-15 (platform support)[517600] Mac OS X: handle FSRef's

2004-02-15 (platform support) Mac OS X: native [tk_messageBox]

2004-02-15 (platform support) Mac OS X: PowerBook keycode 0x34 -> <Return>

2004-02-18 (platform support) Mac OS MouseWheel event handling

2004-02-18 (bug fix)[899246] fix shrinking grid geometry calculations

2003-02-23 (platform support)[809157] Mac OS X: Add alpha blending for
images with partial transparency.

2004-03-01 (platform support)[218561] Allow 64-bit configure on IRIX64-6.5*

--- Released 8.4.6, March 1, 2004 --- See ChangeLog for details ---

Changes to 8.5a1 include all changes to the 8.4 line through 8.4.6,
plus the following, which focuses on the high-level feature changes
in this changeset (new minor version) rather than bug fixes:

 * Tk is no longer guaranteed to work for Win95 (not tested 8.5+)

 * configure scripts now require autoconf 2.57 for regeneration

 * added support for anti-aliased test under X11 (already existed for
   Win/Mac) using --enable-xft

 * improved speed of 'photo put' handling

 * updated demos for consistency and improved look & feel

 * improve 3D line drawing for sunken widgets on Windows

 * [792387] reworked 'grid' to handle some tricky geometry computations
   better

 * [TIP #109] updated look of radiobuttons and checkbuttons on X11

 * [TIP #110] tristate value option for checkbuttons and radiobuttons

 * [TIP #113] add multi-line searching and -all searching to the text widget
   Full Tcl_Obj-ification of the text widget
 * [TIP #155] add 'count' and 'replace' subcommands and a '-blockcursor'
   option to text widgets and support smooth-scrolling of them
	*** POTENTIAL INCOMPATIBILITY ***
   Negative or decreasing tab-stops are explicitly disallowed

 * [TIP #116] more safety for large image creation through use of attempted
   allocation of large memory blocks

 * [TIP #137/151] add -encoding option to 'wish' executable (through
   Tk_MainEX())
	*** POTENTIAL INCOMPATIBILITY ***
   For Tk embedders that build on Tk_MainEx() and make use of Tk_MainEx's
   former ability to pass a leading "-encoding" option to interactive shell
   operations, this will now be consumed by Tk.

 * [TIP #146] added 'grid anchor' subcommand for overall grid anchoring

 * [TIP #147] recognize widget names and "all" as keywords in grid's
   'columnconfigure' and 'rowconfigure' subcommands

 * [TIP #150] make 'send' available on Windows

--- Released 8.5a1, March 3, 2004 --- See ChangeLog for details ---

2004-03-17 (platform support) Mac OS X: Grab the Command-H &
Command-Shift-H keys and use them for Hide and Hide Others before passing
keystrokes on to the generic keyboard event processing.
Stop putting a Quit menu item in the File menu. (ingham)

2004-03-26 (enhancement)[540375] Add code to read and write PPM/PGM data
from strings and/or bytearrays. (fellows)

2004-03-26 (bug fix)[923555] Restored support for the stringWriteProc of
old photo formats/ (fellows)

2004-03-31 (bug fix)[Bug 220871] Report errors from invoking menu commands
as background errors on OS X. (ingham)

2004-04-20 (bug fix)[915350, 922336] Do not set min, max size in WM_HINTS
when we shouldn't and correctly display maximize window button under
KDE-3.2.1. (english)

2004-05-03 (enhancement)[756952] Place images of compound menu entries in
indicator space if not a radio of checkbutton on Windows. (eserte)

2004-05-03 (bug fix)[904371] Fix drawing of unicode chars in menu titles.
(riefenstahl)

2004-05-03 (bug fix)[939389, 822002, 732662] Correctly post internal
clipboard data to the Windows clipboard on exit. (hobbs)

2004-05-03 (bug fix)[778893, 932155] Make the panedwindow -opaqueresize
option work as per the docs, and call DragSash to stop sash jump when B1 is
pressed and released without moving. (hobbs)

2004-05-05 (bug fix)[618872] Fix Tk_MeasureChars and Tk_DrawChars to handle
reallocation of subfonts when unicode chars require extra fonts.
(dkf, hobbs)

2004-05-14 (enhancement) reduce Tk tk_messageBox default font size to
14-point (was 18-point). (fellows)

2004-07-11 (enhancement)[987169] Handle users destroying the dialog
indirectly. (fellows)

2004-07-14 (bug fix)[894550] Correctly set the cursor to the platform
cursor on OS X when Tk asks for the "NULL" (empty) cursor.

2004-07-14 (bug fix)[969358] Prevent possible segfault in -maxundo. (jiangwu)

2004-07-19 (bug fix)[874058] improved build configuration on 64-bit systems.
Corrects Tcl_StatBuf definition issues.  (hobbs)

2004-07-23 (platform support) Mac OS X: Fix several problems with
Icelandic (and Faroese) keyboards (riefenstahl)

2004-07-24 (platform support) Mac OS X: Complete the implementation of
the CG version of the X drawing emulation layer. (tittle, ingham)

--- Released 8.4.7, July 26, 2004 --- See ChangeLog for details ---

2004-08-09 (bug fix)[1006286] test wrapping on canvas; Win (dejong)

2004-08-10 (bug fix)[1006686] [wm resizable] Solaris (mcdonald,english)

2004-08-17 (bug fix)[1010938] panedwindow -handlepad GEOMETRY (fellows)

2004-08-19 (bug fix)[611615] file dialog double clicks fell through (hobbs)

2004-09-10 (bug fix)[845189] file dialog state initialization (fellows)

2004-09-10 (bug fix)[1013942] widget demo robust against strict motif (fellows)

2004-09-16 (bug fix)[1028888] [place forget] memory leak (spjuth)

2004-09-16 (bug fix)[607649] font size change: recompute menu geometry (hobbs)

2004-09-17 (new feature)[TIP 222] [wm attributes -alpha] (hobbs)

2004-09-22 (bug fix)[865842] disabled cascade menu arrow draw (dejong)

2004-09-22 (bug fix)[866194] menu accelerator text highlights (dejong)

2004-09-22 (bug fix)[223689] handle color/screen resolution changes (hobbs)

2004-10-05 (new feature)[TIP 159] [wm iconphoto] (hobbs)

2004-10-26 (bug fix)[905830] set IC focus after creation (max)

2004-10-26 (bug fix) shutdown safety corrections for Win (gravereaux)

2004-10-28 (bug fix) HAVE_NO_SEH handler code, Win (dejong)

2004-10-29 (bug fix)[533519] multi-display window placement (thoyts)

2004-11-10 (bug fix)[1055023] compound buttons, MacOSX (kirkham,ingham)

2004-11-11 (bug fix)[1035348] [load]-able Tk on MacOSX/Aqua (steffen)

2004-11-12 (bug fix)[800178] use correct display for [tk scaling] (hobbs)

2004-11-16 (bug fix)[1063675] Italian msg catalog fixes (ugoccioni,welton)

2004-11-17 (bug fix)[1036963] panedwindow: set save_under X attr (hobbs)

2004-11-17 (bug fix)[1004508] console: array keyname expansion (bold,hobbs)

2004-11-17 (bug fix)[1032300] ps generation of unspecified canvas image (hobbs)

2004-11-17 (bug fix)[982248] immediate unmap of hidden canvas windows (hobbs)

2004-11-18 (new feature) configure options --enable-man-suffix (max)

--- Released 8.4.8, November 18, 2004 --- See ChangeLog for details ---

2004-12-01 (bug fix)[979239] Fix clipping of partially transparent images
on buttons on unix to avoid X error (hobbs, petasis)

2004-12-03 (bug fix)[848161] Fix Tk_PhotoPut(Zoomed)Block overlay
compositing of partially transparent areas.

--- Released 8.4.9, December 6, 2004 --- See ChangeLog for details ---

Changes to 8.5a2 include all changes to the 8.4 line through 8.4.9, plus
the following, which focuses on the 8.5-only changes since 8.5a1:

2004-03-16 (bug fix)[915330] correct crash condition for new
radio/checkbuttons when colors are exhausted (griffin)

2004-03-18 (platform removal)[918139] Removed support for Mac OS Classic
platform (steffen)
	*** POTENTIAL INCOMPATIBILITY ***

2004-03-26 (new feature)[FRQ 540375] support for
[image create photo -format PPM -data] (fellows)

2004-05-14 (bug fix)[TIP 152] -detail option for tk_messageBox (fellows)

2004-06-04 (bug fix)[965398] Fix to shimmering infinite loop scrolling in
text widget under rare circumstances (darley)

2004-06-04 (bug fix) Fixed mousewheel bindings for OS X/Aqua (darley)

2004-06-07 (bug fix)[965186] Fix text widget's record of
partial-line-height calculations for very long wrapped lines, correcting
scrollbar-text interactions (darley)

2004-06-08 (bug fix)[968725] Fix text rendering problem with canvas text
items that have a selected region. (dejong)

2004-06-09 (bug fix) Fix multi-line regexp search bugs in text widget
(darley)

2004-06-15 (feature enhancement) Add 3D highlight to disabled *buttons and
labels, as is done for disabled menu entries (kovalenko)

2004-06-16 (bug fix)[742882] Fix potential division by zero in gridded wm
geometry (english)

2004-06-26 (bug fix)[756840] Fix Tk console cleanup on exit/reinit
(mistachkin)

2004-06-30 (new feature)[TIP 153] enhanced 'winfo toplevel' to recognize
non-Tk windows (mckay)

2004-07-02 (bug fix) Button 4 and 5 masks synchronized with Tk display
(staplin)

2004-07-05 (bug fix)[959973] Set _NET_WM_NAME and _NET_WM_ICON_NAME
(freedesktop.org) in addition to WM_NAME and WM_ICON_NAME (ICCCM).  Allows
Unicode characters in wm titlebar on X11. (english)

2004-07-05 (new feature)[TIP 158][797404] Allow Win apps to distinguish
keys on the keypad using the Extended modifier (grossbauer, kenny)

2004-07-20 (feature enhancement)[922727] add install-private-headers target
(steffen)

2004-07-27 (bug fix) Fix segfault in case of premature end of GIF image
data (steffen)

2004-08-11 (feature)[979101] [tk_getOpenFile] consults env vars (fellows)

2004-08-19 (new feature)[TIP 168] Add -smooth method for alternative bezier
curve implementations on canvas items (hellstroem, fellows)

2004-08-29 (new feature)[TIP 165] Add %d binding substitution for
user-controlled data field (fellows)

2004-09-10 (new feature)[TIP 169] Allow for text peering with '$text peer'
widget subcommand (griffin, darley)

2004-10-08 (new feature)[TIP 205] Use pkgconfig Database to register Xft
support (english)

2004-10-11 (new language) Swedish message catalog from Mats Bengtsson

2004-10-19 (new feature)[TIP 204][976928] Virtual events for keyboard
traversal (english)

2004-10-24 (new feature)[TIP 177, 179][983886] Add -hide and -stretch
options to panedwindow widget (griffin)

2004-10-26 (bug fix)[919066] Improve region handling functions

2004-10-28 (bug fix)[220927] Fix scale labels to stay in window (schlenker,
thoyts)

2004-11-07 (bug fix)[962589] Made handling of ^ more consistent in grid
(spjuth)

2004-11-28 (bug fix)[942320] Fix short integer overflow in x,y coordinates
for long lines using unix AA fonts (english)

Updated test suite, documentation, and demos.

--- Released 8.5a2, December 7, 2004 --- See ChangeLog for details ---

2004-12-09 (performance)[1081966] BMP, JPG image load speed (fellows)

2004-12-17 (feature change) Modified DisplayFrame to draw a container's
background when the embedded window is NULL (chengyemao)

2004-12-17 (bug fix)[842945][831627] Fixed a bug in ContainerEventProc
to handle ConfigureNotify event properly; Changed CleanupContainList to
TkWinCleanupContainerList to be invoked in TkWinXCleanup; Changed Intialize
and CreateTopLevelWindow to create the DeleteWindowsExitProc after TkpInit
so that finalization will be done in a proper sequence (to avoid painics
and potential crashes in exit). (chengyemao)

2004-12-17 (platform support) Added TkWinClenupContainerList into stublib.
(chengyemao)

2004-12-18 (buf fix)[222677] Close the embedded window (of a different
process) when its container is destroyed. (chengyemao)

2004-12-19 (Windows feature implementation of embedded/embedding
Tk and bug fix) Implemented container identification, focus, raise, set
title of and move window so that an embedded widget is able to identify
a container, to get focus and to receive key press input. Fixed bugs include
[1024364][1096047] and an incorrect wm overrideredirect for an embedded
window. (chengyemao)

2004-12-20 (Windows feature implementation of embedded/embedding Tk)
Implemented overrideredirect for an embedded toplevel; correctly updated a
frame's upper left x and y of an embedded toplevel after its container
(of another process) moved. (chengyemao)

2004-12-28 (feature implementatoin of embedded/embedding Tk of Windows)
Implemented embedded/embedding toplevel menu. A menu may be embedded in
a container of either the same process or a different process. Working
fine with Windows 98. But having a problem when invoked with a mouse click
(Windows XP): if an embedded menu is in a different process, the menu items
may show as a blank window at the pull-down time and require the mouse
moves over the menu items to complete display. (chengyemao)

2004-12-29 (platform support)[1092952,1091967] MSVC7, gcc OPT compiles (hobbs)

2005-01-03 (feature implementation of embedded/embedding Tk of Windows) Added
a separated window handler for an embedded menu; solved the problem of
a blank menu display with a mouse click in XP. (chengyemao)

2005-01-07 (feature implementation of embedded/embedding Tk of Window) Added
TK_STATE message (Windows) to support {wm state} for embedded windows; forced
redraw of container after the embedded window detached; removed unnecessary
panic in using embedded window; embeded toplevel menu of an embedded window
automatically in wrapper updating.  Modified and added functions: WmStateCmd,
UpdateWrapper, TkpWmGetState (added) in tkWinWm.c; TkpUseWindow,
TkWinEmbeddedEventProc in tkWinEmbed.c; TkWinChildProc in tkWinX.c.
(chengyemao)

2005-01-08 (bug fix)[1098625] Wrong toplevel geometry when created with a menu;
[637653] Deleting a popup menu crashes wish (chengyemao)

2005-01-09 (feature implementation of embedded/embedding Tk of Windows)
Changed FrameWidgetObjCmd (tkFrame.c), TkpUseWindow (tkMacOSXEmbed.c,
tkUnixEmbed.c, tkWinEmbed.c) to make implementation ready for a
configurable toplevel -use option and completed the implementation for
Windows (tkWinWm.c, tkWinEmbed.c, tkWinInt.h). Embedding with a frame
container needs further debugging (chengyemao).

2005-01-10 (enhancement)[1081595] stopped use of TK_DBGX (english)

2005-01-11 (bug fix)[1098779] -pady accept all lists (fellows,kirkham)

2005-01-11 (bug fix)[1093631] [text] scroll long wrapped line (darley)

2005-01-18 (feature implementation of embedded/embedding Tk of Windows)
Simplified TkpUseWindow, added Tk_DetachEmbeddedWindow and got rid of code
for saving an embedded window object which is never used. Fixed a bug in
TkWinHandleMenuEvent for processing WM_MENUSELECT. Wish crashed due to an
invalid index in a case of MF_POPUP. The -use option of a toplevel can be
configured after the toplevel is created.

2005-01-18 (bug fix) dialog visibility in demos (nash,fellows)

2005-01-28 (platform support)[1021871] Solaris gcc 64-bit support (hobbs)

2005-01-31 (enhancement)[1111213] msg catalog for Spain's Spanish. (poser)

2005-02-03 (bug fix)[1114977] UID thread-safety in canvas (fellows)

2005-02-11 (bug fix)[949792] Fix error during panedwindow destroy (hobbs)

2005-02-11 (bug fix)[1105738] Fix [tk_messageBox -parent $nonToplevel]
segfault (hobbs)

2005-02-11 (bug fix)[1119460] Disabled canvas bmap/bbox segfault (hobbs)

2005-02-11 (platform support) Correct gcc builds for AIX-4+, HP-UX-11 (hobbs)

2005-02-14 (bug fix)[443848] [text] elide newline, but not line (darley)

2005-02-16 (new feature)[TIP 223] Windows: [wm attributes -fullscreen] (dejong)

2005-02-22 (bug fix)[1146057] Aqua: [tk_getOpenFile] encoding (steffen)

2005-02-28 (bug fix)[1118340] Fix Mousewheel %A translation (davis,hobbs)

2005-03-09 (bug fix) Mac OS X: remote debugging under Xcode (ingham)

2005-03-10 (bug fix)[1160025] Aqua: offset in mouse coords (davies,ingham)

2005-03-10 (bug fix)[1124237] Aqua: floating window focus (davies,ingham)

2005-03-14 (bug fix)[1162356] ClientMessageHandlers work now (petasis,fellows)

2005-03-14 (bug fix)[1124237] Aqua: (un)map of subwindows (ingham)

2005-03-14 (bug fix)[700305] Aqua: child window updates before creation
(ingham)

2005-03-15 (platform support) OpenBSD ports patch (thoyts)

2005-03-15 (bug fix)[1143776] [text] display panic (revar,darley)

2005-03-19 (bug fix)[1016385] allow [rename console] (fellows)

2005-03-23 (enhancment) Aqua: native L&F for entry and spinbox (ingham)

2005-03-23 (new feature) Aqua: [wm attributes -notify] (ingham)

2005-03-29 (platform support) Allow msys builds without cygwin (hobbs)

2005-04-03 (bug fix)[1175092] grid geometry calculations (spjuth)

2005-04-04 (bug fix)[1174269] [text] elide search (darley)

2005-04-04 (bug fix)[1169429] [text] invisible cursor (darley)

2005-04-04 (bug fix)[1083878] \0 char in [tk_getOpenFile -filetypes] (darley)

2005-04-07 (bug fix)[1152809] [wm stackorder] panic; multi-DISPLAY (dejong)

2005-04-14 (bug fix)[1122671] font encoding alignment issue (brubaker,hobbs)

2005-04-18 (bug fix) [text] <Home> and <End> bindings (darley)

2005-04-18 (bug fix)[1185640] [text] passed bogus utf-8 to Tk_MeasureChars
(petasis,english)

2005-04-25 (platform support) Fix builds on Mac OS X 10.1 (steffen)

2005-05-06 (platform support) Added x86_64 Solaris cc and Solaris 10 build
support (hobbs)

2005-05-10 (bug fix)[1191895] [text] hang on <Control-Key-Up> (vlasov,darley)

2005-05-14 (enhancement)[1202052] Aqua: CFRunLoop notifier allows
[load]able Tk (steffen)

2005-05-15 (bug fix)[1012852] Aqua: check/radiobutton accelerator (kirkham)

2005-05-15 (bug fix)[1202181] Aqua: scrollbar thumb position (kirkham)

2005-05-15 (bug fix)[1202223] Aqua: [text] window -> scroll lock (kirkham)

2005-05-22 (bug fix)[1206133] TkGetFileFilters: add all (dionizio,fellows)

2005-05-24 (platform support) Darwin/Aqua builds merged into unix (steffen)

2005-05-27 (behavior change) tk_popup menus now "sticky" (helfter)

2005-05-28 (new feature)[TIP 245] [tk inactive] (max,fellows)

2005-05-30 (bug fix)[1161543,1010941,795869,690169] panedwindow
display/resizing (south)

2005-05-30 (bug fix)[1159367] [menu] creation segfault (schofield,hobbs)

Documentation improvements [1087842,1081527,1115907,etc.]

--- Released 8.5a3, June 4, 2005 --- See ChangeLog for details ---

2005-06-23 (bug fix)[1176610] Aqua: default [entry] borderwidth (steffen)

2005-07-18 (bug fix)[1240221] [$text mark prev] crash (darley)

2005-07-22 (platform support) msys build now requires msys_mingw7.zip (dejong)

2005-08-09 (Aqua enhancement) Carbon events (steffen)

2005-08-10 (bug fix)[1252702] portable Tcl_GetStringFromObj() calls (fellows)

2005-08-12 (bug fix)[749908] per-thread Tk_ConfigSpec tables (fellows)

2005-08-23 (enhancement)[1244153] use SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)

2005-08-23 (bug fix)[1235544] adopt Tcl's SEH implementation (kenny,dejong)

2005-08-23 (Aqua bug fix) dialogs ignore -initial* options (hobbs)

2005-10-04 (bug fix)[1216775] [tk_dialog] failing [grab] (fontana,hobbs)

2005-10-04 (bug fix)[1309218] [tk_chooseDirectory -mustexist] (lemburg,hobbs)

2005-10-04 (bug fix)[1311734] Fixed the problems that an embedded windows failed
to respond to display changes (Windows platform) (chengyemao)

2005-10-10 (new feature)[TIP 256] [$text config -tabstyle] (darley)

2005-10-10 (bug fix)[1319720] Tk_DeleteOptionTable() mem leak (melbardis)

2005-10-12 (new feature) one directory test suite (starpackable) (zolli,fellows)

2005-10-18 (bug fix)[1328926] $argv encoding and list formatting (porter)

2005-11-06 (platform support) OpenBSD missing LIBS (thoyts)

2005-11-10 (bug fix)[1353022] minor potential memleaks (fellows)

2005-11-22 (bug fix)[1353414] [selection get] compat w/OpenOffice.org (fellows)

2005-11-14 (feature change) [bgerror] msg truncation at 45 chars (english)

2005-11-15 (new feature)[TIP 231] [wm attributes] on X11 (english)

2005-11-22 (bug fix)[1335485] dialog and space in widget name (taylor,fellows)

2005-11-27 (platform support) Darwin 64bit, Tiger copyfile(), and
Max OSX universal binaries support (steffen)

2005-11-29 (bug fix)[1252259] clear initial % from console (lawlor,hobbs)

2005-11-30 (bug fix)[1086049] [wm attributes -topmost] fix (courtney,hobbs)

2005-12-08 (enhancement)[1369597] Win 64: --enable-64bit=amd64|ia64 (hobbs)

2005-12-08 (bug fix)[1374935] [$text tag names] crash with peer (hobbs)

2005-12-12 (bug fix)[1377619] configure syntax error exposed in bash-3.1 (hobbs)

2005-12-13 (Aqua) MouseWheel bindings; kEventMouseScroll events (steffen)

2005-12-28 (bug fix)[1380427] text widget undo/redo crash (callewaert)

2006-01-12 (new feature)[TIP 260] canvas text item -underline option (fellows)

2006-01-20 (bug fix)[905830] all events to XFilterEvent (SCIM compat) (english)

2006-01-25 (feature enhance)[1237759] update script lib to 8.4 (fradin,porter)

2006-01-25 (feature enhance)[1409264] I10N of [bgerror] dialog (fellows)

2006-02-27 (bug fix)[480862] [$img configure -data] no display change (fellows)

2006-02-27 (bug fix)[470322] BitmapInit() thread safety (griffin,fellows)

2006-03-02 (Aqua bug fix) image endian issue on OS X/x86 (hobbs)

2006-03-15 (bug fix)[1409140] speed up photo image updates (fellows)

2006-03-16 (enhancement)[1405069] added Portuguese l10n. (ricardoj,silasj)

2006-03-17 (bug fix)[1451587] no abbreviations in script library (thoyts)

2006-03-21 (enhancement)[638966] Aqua: ATSUI text render (reifenstahl,steffen)

2006-03-23 (platform support) new tk.spec file (max)

2006-03-26 (bug fix)[1414171] crash in [$text dump -command] (macdonald,darley)

2006-03-27 (bug fix)[1458234] crash in animated GIFs (bron,fellows)

2006-03-29 (platform support)[917433] tolerate X servers that do not
accept the color names "Black" and "White" (porter)

2006-04-06 (bug fix)[1455241] Aqua: [wm attributes -titlepath] fix (steffen)

2006-04-07 (bug fix)[934524]  Aqua: background window dragging/growing (steffen)

2006-04-09 (bug fix)[1467004] Aqua: [wm resizable] fix (steffen)

2006-04-09 (bug fix)[1450800] Aqua: allow empty toplevel names (steffen)

2006-04-11 (bug fix)[1073456] Aqua: implement toplevel zoom (steffen)

2006-04-11 (bug fix)[700316]  Aqua: enable 'Preferences' app menu item (steffen)

2006-04-11 (bug fix)[1193614] Aqua: tk_messageBox escape key binding (steffen)

2006-04-11 (enhancement)[1105284] Aqua: call ::tk::mac::* procs for all
registered applevents (steffen)

2006-04-12 (bug fix)[1432666] grid row/col out of bounds crash (spjuth)

2006-04-25 (bug fix)[1475865] crash on invalid font name (fellows)

Documentation improvements [1224983,1247835,1151523,1357575,1083838]

--- Released 8.5a4, April 27, 2006 --- See ChangeLog for details ---

2006-04-28 (bug fix)[1243318] Aqua: incorrect cursor pos in bindings (steffen)

2006-04-28 (bug fix)[1476443] Aqua: incorrect toplevel pos on 1st map (steffen)

2006-05-12 (performance)[1409140] restore perf lost in 2006-03-15 change (hobbs)

2006-05-13 (bug fix)[1481503] Aqua: key shortcut for 'Preferences' (steffen)

2006-05-13 (bug fix)[1155596] Aqua: images with alpha on native btns (steffen)

2006-05-13 (bug fix)[1480105] Aqua: Map/Unmap propagation to children (steffen)

2006-05-13 (bug fix)[940117] Unmap canvas window items on canvas Unmap (steffen)

2006-05-16 (bug fix)[1472624] Aqua: balloon help don't steal focus (steffen)

2006-05-29 (bug fix)[706446] Aqua: active [button] highlight (hobbs)

2006-05-29 (bug fix)[1424513] [listbox] crash with namespace var (hobbs)

2006-06-01 (bug fix)[912571] [console] std chan refcount (mistachkin,hobbs)

2006-06-14 (bug fix)[950121] Aqua: crash in draw of very wide images (steffen)

2006-06-14 (bug fix)[1501922] Aqua: invalid clip regions on redraw (steffen)

2006-06-14 (bug fix)[891141] excess variable writes by [scale] (porter)

2006-07-20 (platform support) Mac OS X weak linking (steffen)

2006-07-21 (bug fix)[700311, 1525905] Aqua: pure modifier keysyms (steffen)

2006-07-24 (bug fix)[1358663] Aqua: [wm geometry -x-y] (steffen)

2006-07-25 (bug fix)[1516950] Aqua: cmd-Q app menu key shortcut (steffen)

2006-08-18 (bug fix)[1542205] Aqua: toplevel toolbar button crash (steffen)

2006-08-21 (bug fix) Aqua: recursively called event loop (steffen)

2006-08-24 (bug fix) Aqua: window grow icon obscuring scrollbar (steffen)

2006-08-30 (new feature)[1518677] WM_UNICHAR window message (hobbs,petasis)

2006-09-10 (bug fix) Aqua: active/inactive text selection color&relief (steffen)

2006-09-10 (bug fix)[1472624] Aqua: mouse events in overrideredir wins (steffen)

2006-09-11 (bug fix) Aqua: app menu shortcuts with custom .apple menu (steffen)

2006-09-22 (bug fix)[1562528] NULL terminates variadic calls (fellows,ryazanov)

2006-09-22 (new feature)[TIP 268] [package provide] full patchlevel (kupries)

2006-10-05 (bug fix)[1122671] alignment fixes in ucs-2be encoding routines
(hobbs,staplin)

2006-10-08 (new feature)[TIP 264] New public routine Tk_Interp() (thoyts)

2006-10-16 (bug fix)[1558051] Aqua: CG drawing matches X11 (steffen)

--- Released 8.5a5, October 20, 2006 --- See ChangeLog for details ---

2006-10-30 (new feature)[TIP 48] Addition of themed tk widgets to Tk as Ttk
(themed Tk).  Adds ttk::notebook, ttk::sizegrip, ttk::combobox,
ttk::panedwindow, ttk::progressbar, ttk::menubutton, ttk::button,
ttk::radiobutton, ttk::checkbutton, ttk::treeview, ttk::separator,
ttk::scrollbar, ttk::entry, ttk::frame and ttk::labelframe widgets.  Adds
ttk::style command.

2006-11-02 (enhancement) Improve OS X Carbon Update event handling (steffen)

2006-11-07 (configure change) Unix --enable-xft is enabled by default (kenny)

2006-11-23 (bug fix)[1599877] Fix unicode character underline in menus (hobbs)

2006-11-24 (bug fix)[1487701] Better handling of tcl_interactive on OS X to
control display of console (hobbs, steffen)

2006-11-26 (platform support)[1230558] --enable-64bit on more systems (steffen)

2006-11-30 (bug fix) Fix handling of Escape binding on OS X dialogs (steffen)

2006-12-01 (new feature) Add -transparentcolor wm attribute on Windows (hobbs)

2006-12-01 (new feature)[TIP 300] Added [font actual $font $char] (kenny)

2006-12-04 (new feature)[TIP 286] Added [$menu xposition] subcommand (bron)

2006-12-11 (enhancement) Improved EWMH support for _NET_WM_PID and
_NET_WM_PING (fellows)

2007-01-25 (configure change) ensure CPPFLAGS env var used when set (steffen)

2007-02-19 (configure change) Use SHLIB_SUFFIX=".so" on HP-UX IA64 (was
".sl") (hobbs)

2007-04-10 (platform support) Correctly handle theming on Vista/Aero (english)

2007-04-23 (enhancement) Allow empty value for -selectforeground opt (steffen)

2007-04-23 (platform support) Aqua: remove Tk-internal double buffering that is
wasteful on Aqua; allows direct-to-window CoreGraphics drawing (e.g. adding
support for colors with alpha) (steffen)

2007-04-23 (platform support) Aqua: add all OS theme colors/brushes (patterns)
as system colors (steffen)

2007-04-23 (platform support) Aqua: tk_dialog & bgerror use OS theme (steffen)

2007-04-23 (platform support) Aqua: add 'none' & missing theme cursors (steffen)

2007-04-23 (platform support) Aqua: [tk_getOpenFile -parent] et al use sheet
dialog (steffen)

2007-04-23 (bug fix) Aqua: fix custom MDEF and tearoff menu display (steffen)

2007-04-23 (bug fix)[1620826] Aqua: fix <<MenuSelect>> support (steffen)

2007-04-23 (platform support) Aqua: add support for live window resizing and
asynchronous window dragging; prevent window from becoming inacessible
offscreen or under Dock after dragging; use transparent grow box (steffen)

2007-04-23 (platform support) Aqua: improve event processing during nested
event loops (e.g. modal dialogs, menu tracking, window resizing etc) (steffen)

2007-04-23 (bug fix) Aqua: add support for all possible aqua scrollbar arrow
positions, scrollbar variants and for "jump to here" scrollbar behaviour;
correct scroll view size computation; enforce minimal scrollbar height (steffen)

2007-04-23 (platform support) Aqua: add [wm attributes] -topmost, -fullscreen
and -transparent (fully transparent win via -bg "systemTransparent") (steffen)

2007-04-23 (platform support) Aqua: determine win min/max sizes dynamically;
correct size handling of gridded windows; improve computation of initial
window bounds; correct window size handling on multi-headed systems (steffen)

2007-04-23 (platform support) Aqua: correct composite attribute handling in
[tk::unsupported::MacWindowStyle] and add new attributes; allow changing
window class of already existing windows (steffen)

2007-04-23 (platform support) Aqua: add tcl document extensions and mime type
to Wish.app's Info.plist (steffen)

--- Released 8.5a6, April 25, 2007 --- See ChangeLog for details ---

2007-05-04 (new feature)[TIP 145] Enhanced font handling (thoyts)

2007-05-14 (bug fix)[1712081] restored USE_OLD_IMAGE support (porter)

2007-05-15 (bug fix)[1717830,800149] memory leaks (jenglish)

2007-05-15 (bug fix)[1677608] [grid *configure] crash (porter)

2007-05-31 (platform support) Aqua: improve interaction of Expose events and
idle-time redraws (steffen)

2007-05-31 (bug fix) Aqua: gridded window max-size calculation (steffen)

2007-06-02 (bug fix)[1731734] Aqua: menu cascades outside menubar (steffen)

2007-06-06 (platform support) Aqua: enable MouseWheel events in background
windows (steffen)

2007-06-09 (bug fix)[1724223] Unicode menu entry crash (hobbs)

2007-06-09 (bug fix)[1467997] Blue/red reversal in icons (hobbs,janssen)

2007-06-23 (bug fix) Aqua: nav dialog sheet crash (steffen)

2007-06-29 (platform support) Aqua: remove private internal declarations from
installed tkMacOSXInt.h header (steffen)

2007-06-29 (bug fix) Aqua: scrollbar thumb size calculation (steffen)

2007-07-09 (bug fix) Aqua: app-is-frontmost detection (steffen)

2007-07-09 (bug fix) Aqua: window click activation & titlebar click handling
in presence of grabs or modal windows (steffen)

2007-07-25 (bug fix)[1743786] Aqua: [tk_getOpenFile] result (steffen)

2007-08-01 (bug fix)[1692927] [tk_messageBox -detail] buffer (davies,thoyts)

2007-08-27 (bug fix)[1782105] Aqua: tk_chooseColor result (steffen)

2007-09-06 (platform support) Aqua: drop support for Xcode 1.5 project, add
project for Xcode 3.0 (steffen)

2007-09-11 (bug fix) Animated GIF buffer overrun (max)

2007-09-15 (platform support) SunOS-5.1x link with cc, not ld (steffen)

2007-09-17 (enhancement)[1780286] Aqua: combobox appearance (english)

2007-09-17 (platform support)[1748251] Fix NetBSD link failures (english)

2007-09-20 (bug fix)[1791052] [text] DLine layout crash (khomoutov,fellows)

--- Released 8.5b1, September 26, 2007 --- See ChangeLog for details ---

2007-09-26 (enhancement)[1800742] msg catalog for Hungarian. (reszo)

2007-10-11 (bug fix)[1810818] Aqua: [wm resizeable] (steffen)

2007-10-12 (platform support) Aqua: replace RgnHandles by HIShapeRefs (steffen)
	*** POTENTIAL INCOMPATIBILITY for C code acessing MacDrawable Rgns ***

2007-10-15 (platform support) Mac OS X: 64-bit X11 support (steffen)

2007-10-15 (new feature)[TIP 125][998125] dockable frame support (hobbs)

2007-10-22 (bug fix)[1814778,1780286,1609168,1349586] combobox overhaul(english)

2007-10-22 (platform support) Aqua: TIP 145 and Aqua Theme fonts (steffen)

2007-10-23 (bug fix)[1818441] combobox & reparentable frames (hobbs)

2007-10-24 (bug fix)[1723362] Win: transparent bitmaps (mcdonald,thoyts)

2007-10-25 (bug fix)[1818491] crash in [place] manager (mcdonald)

2007-10-25 (new feature)[TIP 242][1156388] file dialog filter (hobbs)

2007-10-25 (bug fix)[1817596] ttk::notebook (english)

2007-10-26 (bug fix)[1816252] Aqua: [wm transient] (steffen)

Improvements to demo suite to make more use of Tk 8.5 features (fellows,steffen)

--- Released 8.5b2, October 26, 2007 --- See ChangeLog for details ---

2007-10-29 (appearance change) Default look and fonts on X11 (hobbs)
	*** POTENTIAL INCOMPATIBILITY; [::tk::classic::restore] to undo ***

2007-10-30 (bug fix)[1803723] Win: Arabic and Hebrew rendering (fellows)

2007-10-30 (bug fix)[1550528] [tk_chooseDirectory -mustexist true] disables
the "OK" until valid selection (hobbs)

2007-11-03 (new feature) adjustable [console] fonts (thoyts)

2007-11-04 (enhancement) Aqua: "Run Widget Demo" menu item (steffen)

2007-11-09 (bug fix) Aqua: activate event after window expansion (steffen)

2007-11-09 (bug fix)[1824521] Aqua: menubutton crash with -bitmap (steffen)

2007-11-09 (platform support) Aqua: (menu)button pressed/inactive/disabled
look&feel; menubutton size with -image/-bitmap (steffen)

2007-11-09 (bug fix) Aqua: [tk_getOpenFile] (et al.) and help menu crashes on
Mac OS X Leopard (steffen)

2007-11-11 (bug fix)[1824638] Aqua: small max-width text measuring (riefenstahl)

2007-11-14 (bug fix)[1831803] sv.msg catalog for "sv" locale (fellows)

Many significant improvements to the documentation and demos (fellows, hobbs,
steffen, kupries)

--- Released 8.5b3, Novemeber 19, 2007 --- See ChangeLog for details ---

2007-11-25 (bug fix)[1343984] ttk::notebook bugs (english,boudaillier)

2007-11-26 (bug fix)[1822391] [photo put] segfault w/ PPM data (kenny)

2007-11-26 (bug fix)[1822076] [tk_saveFile] and path w/spaces (bauer,kenny)

2007-12-04 (new feature)[1844143] Danish message catalog (berg)

2007-12-11 (bug fix)[1602537] crash in [$text replace] (goth,porter,fellows)

2007-12-12 (bug fix)[1845899] Aqua: [wm transient] (steffen)

2007-12-12 (bug fix)[1809538,1799782,1737288] fixes for the <<Modified>>
virtual event on [text] widgets (hobbs)

2007-12-13 (bug fix) correctly trace menubutton -textvariable for -compound
use (hobbs)

Several documentation and release notes improvements

--- Released 8.5.0, December 18, 2007 --- See ChangeLog for details ---

2007-12-30 (bug fix)[1860802] fixed Dutch message catalog (markus,fellows)

2008-01-06 (bug fix)[1442006,1821939,18862692] MouseWheel for treeview (english)

2008-01-08 (bug fix)[1865898,1679067] button size & state (english)

2008-01-08 (bug fix)[1867122] [labelframe -style] crash (english,rib)

2008-01-27 (bug fix)[1835848] size value returned by [font actual] (english)

2008-01-27 (bug fix)[1878298] [notebook] redraws on tab visibility (english)

2008-01-31 (bug fix)[1881892] messagebox default title (hobbs)

2008-02-01 (bug fix)[CVE-2008-0553] buffer overflow in GIF format (max)

--- Released 8.5.1, February 5, 2008 --- See ChangeLog for details ---

2008-02-27 (bug fix)[1863346] Aqua: memleak in QD drawing (steffen)

2008-02-29 (enhancement) Knight's tour demo (thoyts)

2008-03-12 (bug fix)[1090382] crash when GetFont() fails (jenglish)

2008-03-13 (enhancement) support space in INSTALL_ROOT or $builddir (steffen)

2008-03-21 (bug fix)[1863007,1920030] Export Ttk stubs table (english)

2008-03-26 (bug fix)[1922466] crash  in [. configure -cursor] (gavilán)

2008-03-27 (platform support)[1921166] Solaris 64bit build fixes (steffen)

2008-03-27 (bug fix) restored [::safe::loadTk] (hobbs)

--- Released 8.5.2, March 28, 2008 --- See ChangeLog for details ---

2008-04-01 (interface)[1819422] tkStubsPtr no longer in libtk (porter)
	*** POTENTIAL INCOMPATIBILITY ***

2008-04-02 (interface)[1819422] libtkstub symbols MODULE_SCOPE (steffen)

2008-04-07 (bug fix)[1937135] Tk_ParseArgv() double free crash (hobbs)

2008-04-07 (bug fix)[1936238] wish -h mem explosion (bachmann,kenny)

2008-04-08 (new feature) Win: visual-styles API element engine (thoyts)

2008-04-09 (enhancement) real LZW compression in GIF writer (nijtmans)

2008-04-14 (bug fix)[1941740] [tk_chooseColor -title] (thoyts)

2008-04-16 (interface)[1938497] make stubs tables 'static const' (steffen)

2008-04-17 (bug fix)[1327482] canvas item <Enter> events (wangnick)

2008-05-23 (bug fix)[1967576] ttk::label height or width 0 panic (lawlor)

2008-06-10 (enhancement)[1986818] Use Xutf8LookupString when possible (english)

2008-06-12 (bug fix)[1991932] global grab segfault (steffen)

2008-06-12 (platform support) Solaris/amd64 gcc 64bit support (steffen)

2008-06-13 (new feature)[TIP 285] [tkwait] and [update] are now
[interp cancel]able (mistachkin)

2008-06-18 (bug fix) Aqua: missing focus on first map (steffen)

--- Released 8.6a1, June 25, 2008 --- See ChangeLog for details ---

2008-07-04 (bug fix)[2009213] crash in [ttk::scale] (polo,english)

2008-07-24 (bug fix)[2021443] consistent "wrong # args" messages (nijtmans)

2008-07-26 (bug fix)[2026405] portability of [winfo id] (uchida,thoyts)

2008-07-31 (bug fix) export Tk_PkgInitStubsCheck; fixes Tk embed on Windows

2008-08-01 (bug fix)[2009788,2028703] unmapped toplevel crashes (thoyts)

2008-08-05 (bug fix)[2010422] Tk header files revised to accommodate
incompatible changes in recent X.org releases of X11 headers. (jenglish)

2008-08-19 (bug fix) revised number format in -[xy]scrollcommand callbacks
and [xy]view methods (jenglish)
        *** POTENTIAL INCOMPATIBILITY ***

2008-08-19 (enhancement) removed obsolete XID management code (staplin)

Test suite modernization by Ania Pawelczyk.

--- Released 8.6a2, August 25, 2008 --- See ChangeLog for details ---

2008-08-25 (bug fix)[1936220] fix [tk_getOpenFile -multiple 1] on unix (helfter)

2008-08-25 (bug fix)[1023955] default menu cursor: no more Motif (helfter)

2008-08-28 (bug fix) correct TK_LIBS value to include Xft (porter)

2008-09-03 (support) Dropped support for pre-ANSI compilers. (porter)

2008-10-01 (new feature)[TIP 236] [$canvas moveto] (mckay,fellows)

2008-10-05 (bug fix)[2112563] format double values explicitly in double
format, avoiding sensitivity to locale setting. (fellows)
        *** POTENTIAL INCOMPATIBILITY ***

--- Released 8.6a3, October 10, 2008 --- See ChangeLog for details ---

2008-10-17 (enhancement) keyboard bindings for ttk::scale (thoyts)

2008-10-18 (bug fix)[1825353] Russian Windows tiny fonts problem (thoyts)

2008-10-18 (new feature)[TIP 321] [tk busy] (decoster,fellows)

2008-10-28 (bug fix)[1534835,2054562] use of more correct cursors (english)

2008-11-01 (new feature) New [ttk::spinbox] widget (thoyts)

2008-11-01 (new feature)[TIP 97] [$canvas imove] [$canvas rchars] (fellows)

2008-11-09 (bug fix)[2207435] [ttk::entry .t -textvar ::noexist::x] (english)

2008-11-11 (bug fix)[2312027] Tk_Create*ImageType() thread safety (nijtmans)

2008-11-11 (bug fix)[2264732] crash using nondefault visual (english)

2008-11-12 (bug fix)[1777362] permit [text] names containing "-" (thoyts)

2008-11-14 (bug fix)[2239034] limit [wm manage] to Frames (thoyts)

2008-11-22 (new feature)[TIP 119] -angle option for canvas text items (fellows)

2008-11-22 (bug fix)[1939129,1991930] combobox behind other windows (thoyts)

2008-11-22 (new feature) Demo ctext.tcl now demos angled text (fellows)

2008-11-23 (bug fix)[1389270] made [event generate <Focus*>] work (thoyts)

2008-11-28 (bug fix)[1813597,2218964] eliminate unnecessary units conversion
in screen distances, reducing precision loss (ferrieux)

2008-12-03 (enhancement) new "hover" state for proper Vista visuals (thoyts)

2008-12-05 (bug fix)[2107938] no negative font size in PS (fellows)

2008-12-05 (enhancement) new "vista" theme (thoyts)

2008-12-06 (new feature)[TIP 197] [$text -insertunfocussed] (edwards,fellows)

2008-12-06 (new feature)[TIP 337] handle non-error bg exceptions (porter)

2008-12-10 (new feature)[TIP 324] [tk fontchooser](thoyts,vetter,robert,steffen)

2008-12-12 (new feature) Demo fontchoose.tcl demos [tk fontchooser] (thoyts)

2008-12-18 (enhancement)[24442309] Updated German messages (haertel)

--- Released 8.6b1, December 19, 2008 --- See ChangeLog for details ---

2008-12-27 (bug fix)[2381555] horiz. scroll [$treeview identify] (english)

2008-12-28 (new feature)[TIP 244] PNG photo format support (fellows)

2008-12-28 (new feature)[TIP 171] <MouseWheel> event handling (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

2008-12-31 (bug fix)[2003310] radio|check button indicator color (english)

2009-01-06 (bug fix)[2484771] messagebox: system to task modal (ferrieux,thoyts,mjanssen)

2009-01-06 (enhancement)[1539990] optimize photo building (jepler)

2009-01-07 (bug fix)[2473120] chooseDir syntax error (bron)

2009-01-07 (bug fix)[1847002] Win: prevent grab bypass (thoyts)

2009-01-11 (bug fix)[2496162] crash calling Tk_DeleteOptionTable() (english)

2009-01-11 (bug fix) crash on XCreateIC failure (staplin)

2009-01-14 (bug fix)[2507326] Restore aMSN compat (nijtmans)

2009-01-19 (new feature) CONFIG_INSTALL_DIR - where tkConfig.sh goes (cassoff)

2009-01-19 (platform support) better tools for BSD ports (cassoff)

2009-02-08 (bug fix)[2431428] panic computing layout on active widget (english)

2009-02-17 (platform support) MSVC and _WIN64 (hobbs)

2009-02-21 (bug fix)[2546087] [console] display of true UTF-8 \0 (thoyts)

2009-02-23 (bug fix)[1329198,456299,2507419] menu image display (mcdonald)

2009-02-23 (bug fix)[2513104] fix cursor hotspots (mcdonald)

2009-02-23 (bug fix)[2542828] Win: standard question_arrow cursor (danckaert)

2009-02-27 (bug fix)[2645457] crash in Tk_MakeWindowExist() (thoyts)

2009-03-09 (bug fix)[2548661] crash in GetFontFamilyName (riefenstahl)

2009-03-25 (bug fix)[2178820] stop zero-size allocs in ttk (fellows)

2009-03-25 (bug fix)[1871101] blurry large fonts on Vista (garvey,fellows)

2009-04-03 (bug fix)[1789819] stop panic on unexpected wm stack order (english)

2009-04-10 (bug fix)[2116837] std virtual events with Caps Lock (fellows)

2009-04-10 (platform) sse Darwin SUSv3 extensions if available (steffen)

2009-04-10 (bug fix) Motif checkbutton on X11 only (steffen)

2009-04-10 (bug fix) remove TkAqua Quit menu item on [console] (steffen)

2009-04-10 (bug fix) crash deleting char range from [text] (steffen)

2009-04-23 (bug fix)[2779910] updated Win chooseDir (hobbs)

2009-04-24 (bug fix) prevent delete of selected folder in Win dialog (hobbs)

2009-04-30 (bug fix)[2080533] panedwindow sash draw crash (fellows)

2009-04-30 (bug fix)[2504402] iconphoto on non-32-bit displays (mcdonald,thoyts)

2009-05-01 (bug fix)[2777019] anchor for text rotation (gavilán,fellows)

2009-05-03 (bug fix)[2785744] broken flag twiddling (baker,fellows)

2009-05-13 (bug fix)[2791352] XLFD parsing error (thoyts)

2009-05-14 (new feature) Vista theme support (thoyts)

2009-05-14 (bug fix)[1923684] confused checkbutton state (thoyts)

2009-05-17 (new feature)[1470246] notebook tab orientation control (english)

2009-05-21 (bug fix)[2794778] Win menu keyboard traversal (thoyts)

2009-06-02 (bug fix)[2799589] crash on delayed window activation (thoyts)

2009-06-23 (bug fix)[220935] canvas dash update problem (nijtmans)

2009-06-23 (platform) new subdir 'carbon' preserved for OSX 10.4-
use --enable-aqua=carbon option to unix/configure to enable (steffen)

2009-06-29 (new feature) source in `macosx` now built on Cocoa (steffen)
	*** POTENTIAL INCOMPATIBILITY ***

2009-06-30 (platform support) clang static analyzer macros (steffen)

2009-07-15 (bug fix)[2821962] photo image copy/paste (rib,fellows)

2009-07-21 (bug fix)[2356057] rotated underlined text (fellows)

2009-07-22 (bug fix)[2496114] focus in dead window crash (griffin,fellows)

2009-07-23 (bug fix)[2441988] report errors in selection handlers (fellows)
	*** POTENTIAL INCOMPATIBILITY ***

2009-08-01 (bug fix)[2830420] X iconphoto for big endian (misch,fellows)

2009-08-04 (bug fix) [text] word-wrap of non-breaking space (fellows)

2009-08-14 (bug fix) copy from unmapped toplevel crash (alaoui,steffen)

2009-08-19 (bug fix)[2475855] prevent grid & pack on same master (spjuth)

2009-08-24 (bug fix)[2821084] Cocoa: let WM_DELETE_WINDOW handler stop window
deletion (walzer,steffen)

2009-08-24 (bug fix) tk::MessageBox bindings for ttk::buttons (steiner,fellows)

2009-08-25 (bug fix)[1909931] [send] update for Fedora 8 (fellows)

2009-09-10 (bug fix) font allocation crash (berezhnoy,fellows)

2009-09-14 (bug fix)[873608] win tearoff menu, no submenu arrows (traum,hobbs)

2009-09-14 (bug fix)[873613] win tearoff menu repeat select (traum,hobbs)

2009-09-25 (bug fix) grayscale from images (vetter,fellows)

2009-10-07 (bug fix)[2088597] min scrollbar slider size (danckaert,fellows)

2009-10-07 (bug fix)[2787164] combobox/menubutton arrow size (thoyts)

2009-10-08 (bug fix)[2870648] file dialog cursor (danckaert,fellows)

2009-10-10 (feature)[1961455] underline, overstrike Xft fonts (caffin,fellows)

2009-10-20 (enhancement) Updates to Polish messages (pawlak)

2009-10-22 (bug fix)[2168768] file dialog -typevariable scope (danckaert)

2009-10-22 (bug fix)[1469210] [text] modified error (danckaert)

2009-10-22 (bug fix)[2883712] 64-bit Aqua progress bar (haffner)

2009-10-24 (bug fix)[1530276] X checkbutton -selectcolor (danckaert)

2009-10-25 (bug fix)[1854913] [.t delete] before -startindex (danckaert)

2009-10-25 (bug fix)[2809525] prevent X crash on overlong color name (goth)

2009-10-29 (bug fix)[1825353] Russian Windows tiny fonts problem (thoyts)

2009-11-01 (new feature) Ttk: [$w identify] now an ensemble (jenglish)

2009-11-19 (bug fix)[2899685] fix [imove] redraw logic (schekin,ferrieux)

2009-11-22 (bug fix)[2899949] crash on widget destroy (meier,thoyts)

2009-11-23 (bug fix)[2902573] Update Safe Tk to new Safe Base (kurpies)

2009-11-24 (bug fix)[2902814] fix [wm iconphoto] on LP64 systems (fellows)

2009-12-08 (bug fix)[2864685] Compiz menu item animation (gavilán,thoyts)

2009-12-11 (bug fix)[2912473] accept :: in DISPLAY name (fellows)

2009-12-15 (bug fix)[2492179] Tcl_ObjType "option" no longer registered (porter)
	*** POTENTIAL INCOMPATIBILITY for Tcl_GetObjType("option") ***

2009-12-20 (bug fix)[2917663] [send] accept SI:* on auth list (fellows)

2009-12-22 (bug fix)[2912356] [ttk::sizegrip] accommodate Compiz (english)

2009-12-25 (bug fix)[2977688,2546779] tab selection focus (english)

2009-12-27 (bug fix)[2879927] Win: cascade menu highlight (pawlak,thoyts)

2010-01-01 (bug fix)[1924761] stop [event generate] / XIM conflict (fellows)

2010-01-03 (bug fix)[2848897] ODS_NOACCEL flag support (kovalenko,thoyts)

2010-01-04 (bug fix)[2811266] <Return> binding in [tk_dialog] (thoyts)

2010-01-04 (bug fix)[2727476] font dialog appearance (thoyts)

2010-01-05 (bug fix)[220950] [$menu delete] bounds check (fellows)

2010-01-05 [2898255] unlimited multi-file select (pawlak,fellows,thoyts)

2010-01-06 (bug fix)[1163496] X: [wm transient] fix (bateman,fellows)

2010-01-09 (new feature)[TIP 360] Modernize X11 Menus (thoyts)

2010-01-18 (bug fix)[2932808] canvas update on state change (mcdonald,nijtmans)

2010-01-19 (new feature)[TIP 359] Extended Window Manager Hint Support (thoyts)

2010-01-19 (bug fix)[2931374] overflow in complex tag search (schmitz)

2010-02-17 (bug fix)[2952745] crash in menu deletion (english)

2010-02-20 (performance) treeview stop quadratic common case (english)

2010-03-02 (enhancement) -fvisibility-hidden build support (nijtmans)

2010-03-06 (bug fix)[2949774] cascade menu unpost (thoyts)

2010-03-11 (bug fix)[2968379] crash in peer text dump (fellows)

2010-03-17 (bug fix)[2971663] Cocoa entry <Up>, <Down> (goddard,fellows)

2010-03-28 (new feature) [$treeview tag names|add|remove] (english)

2010-04-09 (new feature)[2983824] [$image write -file] use extension of file
name to select image format (fellows)

2010-04-19 [2898255] unlimited multi-file select (pawlak,fellows,thoyts)

2010-05-31 (bug fix)[3006842] crash on empty bind scripts (english)

2010-06-15 (bug fix)[2585265] text <Delete>,<Backspace> note selection (fellows)

2010-06-15 (new package)[3016598] Tk now provides "tile 0.8.6" (english)

2010-07-19 (new feature) [$photo data -format GIF] (fellows)

2010-08-03 (bug fix) entry validation compat with Itcl scope (hobbs)

2010-08-11 (platform) Drop pre-aix 4.2 support, ldAix (hobbs)

2010-08-21 (patch)[3034251] genStubs steal features of ttkGenStubs (nijtmans)

2010-08-26 (bug fix)[1230554] configure, OSF-1 problems, windows manifest issues (hobbs)

2010-08-31 fixed manifest handling on windows (hobbs, kupries)

2010-09-02 (bug fix)[3057573] specify combobox text fg color (english)

2010-09-05 (enhancement)[3046742,3046750] Improved error dialog UI (fellows)

2010-09-08 (bug fix)[2829363] [$tv see] open item -> sched display (english)

2010-09-13 (platform) limit support to Win2000+ (nijtmans)

2010-10-01 (bug fix)[3078902] no hang operating on zero-size subimages (fellows)

2010-10-05 (bug fix)[3080953] corrupt multibyte char in %A subst (nijtmans)

2010-10-11 (bug fix)[3085489] crash in [tag add/remove] (english)

2010-10-11 (enhancement)[491789] Unicode command line support on Win (nijtmans)

2010-11-03 windows build with -UNICODE (nijtmans)

2010-11-05 Message catalogs reworked to use unicode copyright char (nijtmans)

2010-11-06 Message catalogs resorted, updates to NL (nijtmans)

2010-11-16 (platform) VS 2005 SP1 MSVC compiler (nijtmans)

2010-11-24 (bug fix)[3071836] crash in tk_getSaveFile (twylite)

2010-12-03 (enhancement)[3116490] mingw x-compile improvements (nijtmans)

2010-12-12 (platform) OpenBSD build improvements (cassoff)

2010-12-17 (platform) Revisions to support rpm 4.4.2 (cassoff)

2011-01-06 (bug fix)[2857300] Cocoa: correct text width rounding (walzer)

2011-01-06 (bug fix)[3086887] Cocoa: textured bg windows (walzer)

2011-01-13 (bug fix)[3154705] tk_messageBox close button disabled (skylera)

2011-01-22 (enhancement) add [ttk::entry validate] (schelte,english)

2011-01-24 (bug fix)[2907388] OSX: composite character entry crash (berg,walzer)

2011-03-02 (new doc) tk_mac.n: OS X specific functions (walzer)

2011-03-03 (bug fix)[3175610] incomplete line item refresh (ferrieux)

2011-03-10 (bug fix)[3205260] crash in [wm manage] (boudaillier, thoyts)

2011-03-16 (bug fix)[3181181] tearoff submenu fix (menez, thoyts)

2011-03-19 (bug fix)[3205464] [wm forget] loses window (boudaillier,thoyts)

2011-03-19 (bug fix)[3223850] ttk button state disabled during click (thoyts)

2011-03-22 (bug fix)[3000002] ttk scrollbar size Appearance (garvey,thoyts)

2011-03-24 (bug fix)[3239768] Win menu font support (wehle)

2011-03-28 (bug fix)[3129527] stop buffer overflows (dirtyepic,nijtmans)

2011-04-04 (feature change)[2997657] No -container for [labelframe] (spjuth)

2011-04-04 (bug fix)[723765] [grid remove] lost -in value (saye,spjuth)

2011-04-22 (bug fix)[3291543] mem corrupt when [$canvas dchars] removes all
coords of a polygon (rogers,spjuth)

2011-04-29 (platform support) [wm forget|manage] on OS X (walzer)

2011-06-06 (bug fix)[2546087] [console] treatment of '\0' (porter)

2011-06-07 (bug fix)[2358545] Restore "08" in spinbox configured with -from
and -to (porter)

2011-06-10 (bug fix)[3315731] fix [$entry -invcmd] (porter)

2011-06-17 (bug fix)[3062331] crash in unset traces (macdonald,porter)

2011-08-03 (bug fix)[2891541] fix grab behaviour for main window (thoyts)

--- Released 8.6b2, August 8, 2011 --- See ChangeLog for details ---

2011-09-22 (bug fix)[3404541] -takefocus option (dzach,english)

2011-10-24 (new feature)[TIP 382] -confirmoverwrite on save dialog (porter)

2011-10-25 (bug fix)[3410609] AltGr keysyms on Swiss keyboard (tasser,kenny)

2011-11-17 (bug fix)[3437816] return code of [canvas lower] (hirner,ferrieux)

2011-12-22 (bug fix)[3235256] correct menu failure on Windows (mcdonald)

2012-01-19 (bug fix)[3021557] cursor freeze in elided text (vogel)

2012-01-22 (bug fix)[3476698] hang in [text mark prev/next] (vogel)

2012-01-25 (bug fix)[3475627] Stop text-31.11 failure (vogel)

2012-01-25 (bug fix)[1630271] hang/crash on mark before -startline (vogel)

2012-01-26 (bug fix)[1754043,2321450] -blockcursor appearance (vogel)

2012-01-27 (bug fix)[3480471] crash in [tk_getOpenFile] (nijtmans)

2012-01-29 (bug fix)[3480634] PNG image in menus (nijtmans)

2012-01-30 (bug fix)[2925561] disabled combobox don't take focus (english)

2012-02-10 (bug fix) win dialog avoid shimmer that confuses Python (fellows)

2012-02-15 (bug fix)[3486474] Correct color scaling (goth,nijtmans)

2012-02-28 (bug fix)[1630262,1615425] [text] crash tags & -*line (vogel)

2012-03-07 (bug fix)[3497848] consistent pixel rounding (fassel,fellows)

2012-03-18 (enhancement)[3503317] XParseColor speedup (nijtmans)

2012-04-07 (bug fix)[3176239] control-Mousewheel crash (couch,nijtmans)

2012-04-22 (bug fix)[3520202] <MouseWheel> %k,%K,%N for Python (deily,fellows)

2012-05-02 (bug fix)[533519] multiscreen window placement (nijtmans)

2012-05-04 (bug fix)[2768586] multiscreen menu posting (nijtmans)

2012-05-28 (bug fix)[1630254] text peer update on -startline reset (baker,vogel)

2012-06-11 (bug fix)[3294450] ttk text element clipping (oehlmann,fellows)

2012-07-02 (bug fix) Make sure all index tables are static (kirkham,english)

2012-07-23 (bug fix)[3546073] DisplayString() -> DefaultDisplay() (english)

2012-08-11 (bug fix)[3554273] text elide and tags (vogel)

2012-08-15 (enhancement)[3555324] Win:Ctrl-A now means Select-All (nijtmans)
	*** POTENTIAL INCOMPATIBILITY ***

2012-08-22 (new feature)[TIP 403] Use Web color definitions (nijtmans)
	*** POTENTIAL INCOMPATIBILITY ***

2012-08-23 (enhancement)[3555644] better use of virtual events (nijtmans)
	*** POTENTIAL INCOMPATIBILITY ***

2012-08-24 (bug fix)[3558535] file dialog filtering (fellows)

2012-08-25 (bug fix)[3554026,3561016] crash with tearoff menus (gavilán)

2012-09-11 (bug fix)[3566594] stop clip region leaks (fellows)

2012-09-15 (bug fix)[3567778] stop hang in wrapped label (porter)

2012-09-17 (bug fix)[3567786] stop segfault in [wm forget] (porter)

Many revisions to better support a Cygwin environment (nijtmans)

--- Released 8.6b3, September 18, 2012 --- See ChangeLog for details ---

2012-10-02 (bug fix)[3572016] menu enable after modal dialog (berg,walzer)

2012-10-08 Remove Carbon support

2012-10-24 (bug fix)[3574893] crash in [wm forget] (porter)

2012-11-07 (bug fix)[3574708] crash in focus handling (fellows)

2012-11-14 (bug fix)[3500545] fix [tk_getOpenFile -multiple] (bruederlin)

2012-12-04 (bug fix)[3588824] Support weird image names in [text] (vogel)

2012-12-06 (bug fix)[3592736] stop pink greys from buggy mingw builds (fellows)

--- Released 8.6.0, December 20, 2012 --- See ChangeLog for details ---

2013-01-04 (bug fix) Tk_InitStubs("8.6") rejected in 8.60 interp (nijtmans)

2013-01-10 (bug fix)[3600251] Mac <Control-v> binding (kjnash,nijtmans)

2013-01-10 (bug fix)[3600260] <<SelectNextPara>> binding (kjnash,nijtmans)

2013-01-13 (bug fix)[3600290] restore $tk_strictMotif respect (kjnash,nijtmans)

2013-01-22 (bug fix)[3601782] Tcl_InitStubs failure message (nijtmans)

2013-01-31 (bug fix)[3599928] use XKeycodeToKeysym on old systems (cassoff)

2013-02-04 (bug fix)[3603077] treeview update on tag add/remove (english)

2013-02-28 (bug fix)[3599312] First Alt key event is lost (mcdonald)

2013-03-11 (bug fix)[3607326] Crash [listbox .l -listvariable $array] (porter)

2013-03-13 (enhancement) better build support for Debian arch (shadura)

2013-03-27 (bug fix)[3608074] button, listbox, menu <<Invoke>> (nijtmans)

2013-04-01 (bug fix)[3607830] Xkb runtime checks (griffin)

2013-05-19 (platform support) FreeBSD updates (cerutti)

2013-06-05 (bug fix)[3613759] [ttk::entry .e; .e xview end] (nijtmans)

2013-06-05 (bug fix)[2100430] [ttk::entry .e; .e xview insert] (nijtmans)

2013-06-28 (bug fix)[2501278] reverse ttk::scale key bindings {mcdonald)

2013-07-02 (bug fix)[32afa6] corrected dirent64 check (griffin)

2013-08-14 (bug fix)[069c9e] "option" value refcount crash (tim,nijtmans)

2013-08-15 (bug fix)[c597acd] [$pb step] work with traces (english)

2013-08-25 (bug fix)[3016181] Cocoa: [destroy $scrollbar] => crash (goddard)

--- Released 8.6.1, September 19, 2013 --- https://core.tcl-lang.org/tk/ for details

2013-10-27 (bug fix) OSX drawing lags (deily,steffen,walzer)

2013-10-28 (bug fix)[3603436] png wrong component indices (nijtmans)

2013-10-31 (bug fix) C++ friendly stubs struct declarations (nijtmans)

2013-10-31 (bug fix)[c0cc9fd] PNG parser accept uppercase -format (nijtmans)

2013-10-31 (bug fix) double free of a TkFont (nijtmans)

2013-11-03 (bug fix)[1632447] support PPM maxval up to 65535 (fellows)

2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans)

2013-11-11 (bug fix)[f214b8a] multi-interp font teardown double free (porter)

2013-11-11 (bug fix)[0aa5e85] option file \n syntax support (nijtmans)

2013-11-20 (platforms) Support for Windows 8.1 (nijtmans)

2014-01-23 (bug fix)[3606644] X: correct fontconfig dependence (venable)

2014-01-23 (bug fix) FreeBSD build fixes (cerutti)

2014-02-06 (bug fix)[3279221] [menu] event race (danckaert,kupries)

2014-02-07 (bug fix)[6867cc1] creative writing in [tk fontchooser] (nijtmans)

2014-02-11 (bug fix)[52ca3e7] XkbOpenDisplay macro correction (nijtmans)

2014-03-16 (bug fix) Xcode 5.1 update; Retina displays (walzer)

2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans)

2014-04-01 (bug fix)[5bcb502] @TK_LIBS@ in pkgconfig (badshah400,nijtmans)

2014-05-27 (bug fix)[a80f5d7] autoscroll initiation (crogers,english)

2014-07-07 (bug fix) OSX alpha channel rendering (culler,walzer)

2014-07-08 (workaround)[4955f5d] Ocaml trouble with tailcall splice (nijtmans)

2014-07-24 (bug fix) OSX [text] image display & scrolling (culler,walzer)

2014-08-01 (bug fix) OSX font config crash (rob@bitkeeper)

--- Released 8.6.2, August 27, 2014 --- https://core.tcl-lang.org/tk/ for details

2014-08-27 (bug) Cocoa: Crash after [$button destroy] (walzer)

2014-09-23 (bug) Cocoa: button and scroll display fixes (walzer)

2014-09-24 (bug) Cocoa: improved drawing performance (walzer)

2014-10-11 (bug)[9e487e] Phony button clicks from browsers to plugin (nijtmans)

2014-10-11 (bug)[810c43] [text] elide changes advance epoch (vogel)

2014-10-14 (bug)[fb35eb] fix PNG transparency appearance (walton,culler)

2014-10-18 (feature)[TIP 432] Win: updated file dialogs (nadkarni)

2014-10-26 Support for Windows 10 (nijtmans)

2014-10-28 (bug) OSX: Improved ttk notebook tab metrics for Yosemite (walzer)

2014-10-30 (bug)[3417012] [scale -digits $bigValue] segfault (vogel)

2014-11-07 (bug)[3529885] [scale] handling of negative resolution (vogel)

--- Released 8.6.3, November 12, 2014 --- https://core.tcl-lang.org/tk/ for details

2014-11-14 (bug)[d43a10] shimmer-related crash in [tk_getOpenFile] (nadkarni)

2014-11-23 (bug)[1c0d6e] Win build trouble with SIGDN (keene)

2014-12-03 (bug)[4a0451] [tk_getOpenFile] result (nadkarni)

2014-12-13 fix header files installation on OS X (houben)

2015-01-02 (bug) Stop bit loss in [winfo id] on 64-bit Cocoa (porter)

2015-02-06 (bug) several fixes to elided context in [text] (vogel)

2015-02-06 (new feature)[TIP 433] %M binding substitution (mistachkin)
        *** POTENTIAL INCOMPATIBILITY ***

2015-02-22 (bug)[ab6dab] corrupt dashed lines in postscript (porter)

Tk Cocoa 2.0: App Store enabled (walzer,culler,desmera,owen,nyberg,reincke)
        *** POTENTIAL INCOMPATIBILITY ***

--- Released 8.6.4, March 12, 2015 --- https://core.tcl-lang.org/tk/ for details

2015-03-10 (bug) Cocoa: premature image free crash (walzer)

2015-03-15 (bug) Cocoa: wish launches in front. [focus -force] works (culler)

2015-04-09 (bug)[e4ed00] [$text index "1.0 display wordstart"] crash (vogel)

2015-04-09 (bug)[562118] Unicode support of "wordstart" modifier (vogel)

2015-05-05 (bug)[06c3fc] PNG alpha error corrupted output file (gauthier,porter)

2015-05-20 (bug)[dece63] various mem corruptions in images (mic42,porter)

2015-05-24 (bug)[53f8fc] panedwindow geometry management (vogel)

2015-05-26 (bug)[1641721] tk_getOpenFile symlink display doubled (nijtmans)

2015-06-01 (bug)[d7bad5][2368195][3592454][1714535][1292219][3592454]
                panedwindow fixes (vogel)

2015-06-25 (bug)[805cff] Tk_ConfigureWidget() segfault (aspect,nijtmans)

2015-07-13 (bug)[3f179a] Text widget crash with elided text (vogel)

2015-07-16 (bug)[2886436] Stop [$text delete] acting before start index (vogel)

2015-07-28 (bug)[1236306] TraverseToMenu error bound to toplevel destroy (vogel)

2015-08-20 (bug)[00189c] MSVC 14: semi-static UCRT support (dower,nijtmans)

2015-09-13 (bug)[cc0ba3] PNG read buffer overflow (maxjarek,porter)

2015-09-29 (bug)[1501749] Crash embedded window delete bound to <Map> (vogel)

2015-10-04 (license) Replace icons that lacked clear free license (cowals)

2015-10-06 (bug)[46c83f] Win: tk_getOpenFile -initialdir (koend,nadkarni)

2015-10-08 (new feature)[TIP 437] New panedwindow options (vogel)

2015-10-09 (bug)[1669632] [text] autoseparator placement (nash,vogel)

2015-10-09 (bug)[2262711] [text] RE search Unicode+elided (kaitzschu,vogel)

2015-10-09 (bug)[1815161] [$text count -ypixels] needs management (vogel)

2015-10-22 (bug)[1520118] Document spinbox validate expectations (vogel)

2015-10-22 (bug)[1414025] $entry insertion cursor visibility (vogel)

2015-10-26 (bug) PNG rendering on El Capitan (meier,walzer)

2015-11-08 (bug)[2160206] menubutton panic (vogel)

2015-11-08 (bug)[220854] Display trailing TAB in entry (vogel)

2015-11-08 (bug)[542199] double click on lone char in entry (vogel)

2015-11-08 (bug)[297442d] strict motif binding on <Control-underscore> (vogel)

2015-11-08 (bug)[3601604] $listbox -takefocus (vogel)

2015-11-09 (bug)[5ee8af] X, Win: 64-bit enable embedded windows (vogel)

2015-11-29 (bug)[1997299] [text] tag borderwidth leak (vogel)

2015-12-12 (bug)[1739605] [text see] misbehavior (danckaert)

2015-12-13 (bug)[ff8a1e] Never-mapped [text] performance (danckaert)

2015-12-19 (bug)[1700065] Report errors from -textvariable write trace (vogel)

2015-12-19 (bug)[793909] -textvariable handle undefined namespace (vogel)

2015-12-26 (bug)[2f78c7] crash with [text] and [tablelist] (vogel)

2016-01-06 (bug)[1288433,3102228] <<ListboxSelect>> misfires (vogel)

2016-01-08 (bug)[1510538] initial scrollbar width (vogel,nijtmans)

2016-01-08 (bug)[1305128] event not received by scrollbar (vogel,nijtmans)

2016-01-09 (bug)[1927212] Mousewheel/scrollbar bindings (vogel)

2016-01-11 (bug)[63c354] Cocoa message boxes (culler)

2016-01-12 (bug)[2049429] get more $text options from database (vogel)

2016-01-22 (TIP 441) New option [listbox ... -justify] (vogel)

2016-01-25 (bug) OBOE in ttk::notebook options parsing (bromley,english)

2016-02-08 (enhance) [option readile] expects utf-8 file (oehlmann,nijtmans)

2016-02-08 (bug) crash in [$text delete] (griffin,vogel)

Tk Cocoa 2.0: More drawing internals refinements (culler,walzer)

--- Released 8.6.5, February 29, 2016 --- https://core.tcl-lang.org/tk/ for details

2016-03-07 (bug)[3137232] spinbox teardown hygiene (vogel)

2016-03-07 (bug)[2981253] spinbox rapid button action (vogel)

2016-03-07 (bug)[2262543] scale initialization callbacks (vogel)

2016-03-07 (bug)[e9112e] incomplete [wm forget] (vogel)

2016-03-11 (bug)[d95e5d] <Map> from hidden panes (vogel)

2016-03-20 (TIP 443) More configuration options for text tags (vogel)

2016-03-20 (bug)[487861] menu: cascade/accelerator appearance (vogel)

2016-03-27 (bug)[1192095] active index from toplevel menus (vogel)

2016-03-27 (bug)[18c08d] revised final newline behavior in [text] (vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2016-04-29 (bug)[fd3a4d] <<Modified>> delivery to text peers (vogel)

2016-05-03 (bug)[b36218,011706] event reentrancy / widget destruction (vogel)

2016-05-12 (bug)[64261b] mouse events after double click (nadmarki,nijtmans)

2016-05-18 (bug)[545f10] Xft color font speed (bonfield,davies,girffin,vogel)

2016-05-25 (bug)[109865] event reentrancy / widget destruction (vogel)

2016-05-30 (TIP 446)[1273358] [$text edit (canundo|canredo)] (vogel)

2016-05-30 (bug)[79549a] crash in mouse pointer warping (vogel)

2016-06-22 (bug)[787adc] Modernize Tk_Init() (porter)

2016-07-06 (bug) Aqua: excess lable padding (lanam,walzer)

2016-07-08 (bug) Aqua: bitmap distortion (culler,walzer)

2016-07-15 (bug) Aqua/Retina: fix alpha rendering of images (culler,walzer)

2016-07-17 (bug)[c84f66] Aqua: crash: overflow in geometry calc (culler,walzer)

2016-07-21 (bug)[450bb0] Aqua: memory corruption from [tk busy] (porter)

--- Released 8.6.6, July 27, 2016 --- https://core.tcl-lang.org/tk/ for details

2016-08-23 (bug)[a2abc4] Wrong warp cursor position on 2nd display (vogel)

2016-08-29 (bug)[fa3229] menu-38.1 (calvo,vogel)

2016-08-29 (bug)[2cf3d6] button-5.24 (vogel)

2016-09-04 (bug)[1534455,2945130] Key release events get _L vs _R right. (vogel)

2016-09-10 (bug)[8c4216] listbox-4.1 (vogel)

2016-09-10 (bug)[eb2681] listbox-13.1 (vogel)

2016-09-21 (bug)[3126428] ttk::button react to image change (thoyts)

2016-10-09 (bug)[1082213] wrapped text don't start lines with whitespace (vogel)

2016-10-12 (bug)[3217462] tri-state button on non-native theme (vogel)

2016-10-30 (bug)[3588460] Fix file dialog -typevariable (vogel)

2016-11-01 (bug)[e36963] event generate .e <diaeresis> (matthias,vogel)

2016-11-05 (bug)[6aea69] grid-23 (danckaert,vogel)

2016-11-18 (bug)[f60c54] combobox-3 (panza,vogel)

2017-01-03 (bug)[f32502] crash drawing many dashed objects (reithofer,werner)

2017-01-05 (bug)[dac92f] text-2.[89] (vogel)

2017-01-07 (bug)[3df559] OSX: Negative bbox width (vogel)

2017-01-07 (bug)[28a453] OSX: text widget index OBOE (vogel)

2017-01-07 (bug)[c12af7] OSX: text-21.1 (vogel)

2017-01-08 (bug)[7a838c] X11 ring buffer overflow (werner)

2017-01-11 (bug)[d4fb4e] imgPhoto-4.75 (nijtmans)

2017-01-18 (bug)[fab5fe] OSX: repair textDisp failures (vogel)

2017-01-23 (bug)[89a638] OSX: textDisp-15.8 (vogel)

2017-01-25 (bug)[1403ea] Limits on text line size on Windows (spjuth)

2017-02-05 (bug)[ae32eb] textDisp fails in text custom config (vogel)

2017-02-05 (bug)[7d967c] crash after IME restart (lanam,nijtmans)

2017-02-22 (bug)[c492c9] disabled combobox arrow appearance (danckaert)

2017-03-06 (bug)[6b3644] Fix -alpha for 16-bit color PNG (LemonMan)

2017-03-11 (bug)[775273] artifacts on Ubuntu 16.10+ (nemethi)

2017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel)

2017-03-29 (bug)[28a3c3] test BTree memleaks plugged (anonymous)

2017-04-06 (bug)[db8c54] Stop freed mem access in warp pointer callback (porter)

2017-04-07 (bugs) Fix calculation of ttk::notebook tab widths (vogel)

2017-04-07 (bug)[291296] notebook tab management (decoster)

2017-04-08 (bug)[f0188a] Win reject invalid hex color codes (bachmann)

2017-04-10 (bug)[3f323b] variable struct size on XCode 8.3.1 (auriocus)

2017-04-20 (bug)[061bf9] OSX scrollbar draw position (reincke,walzer,joye)

2017-05-01 (bug) restore -initialfile for OSX file dialogs (reincke,gollwitzer)

2017-05-06 (bug) OSX file dialog type filters (walzer)

2017-05-10 (bug)[a5ba1c] race condition on Win clipboard cleanup (donchenko)

2017-05-18 (bug)[2433781] center image on button (cramer)

2017-05-19 (bug)[434d29] type mismatch with recent Xft (nijtmans,werner)

2017-06-02 (bug)[bc43fd] paneconfigure get pane heights right (vogel)

2017-06-21 (bug)[adc028] menu avoid unreleasable global grab (nash)

2017-06-30 (bug)[92e028,c5eb90] User switch forced theme reset (lanam)

2017-06-30 (bug)[62c5b7] segfault in [text] replace (werner)

2017-07-03 (bug)[8afc6c] OSX crash in save/open dialogs (simpson,walzer)

2017-08-02 (bug)[b601ce] Resource exhaustion processing corrupt GIF (nash)

2017-08-03 (bug)[9eab54] Fix -initialdir for OSX file dialogs (gollwitzer)

2017-08-08 (bug)[28d0b8] Follow ICCCM advice on X selection protocol (donchenko)

2017-08-08 (bug)[4966ca] Scidb race in notebook tab selection (cramer)

--- Released 8.6.7, August 9, 2017 --- https://core.tcl-lang.org/tk/ for details

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

2016-03-07 (feature)[841280] spinbox autoswap -to/-from to get ordering (vogel)

2016-03-27 (feature)[38dc27] Support <Button-6> & <Button-7> (nijtmans)

2016-08-29 (TIP 449) [text] undo/redo return character range (vogel)

2016-11-02 (feature) Removed undocumented command [tk_getFileType] (vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2017-02-05 (bug)[c0dbdd] Compatibility fonts shadowed system fonts (vogel)

2017-03-21 (TIP 442) display text in a progressbar (zaumseil)

2017-04-13 \u escaped content in msg files converted to true utf-8 (nijtmans)

2017-08-28 (TIP 166) Extended color notation for alpha channel (bachmann)

--- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tk/ for details

2017-08-24 (bug)[f1a3ca] Memory leak in [text] B-tree (edhume3)

2017-08-24 (bug)[ee40fd] Report [console] init errors (the)

2017-08-24 (bug)[3295446] Improve history visibility in [console] (goth)

2017-08-24 (bug) canvas closed polylines fully honor -joinstyle (vogel)

2017-08-24 (bug)[cc42cc] out of mem crash in tests imgPhoto-18.* (vogel)

2017-09-16 (bug)[3406785] fix coords rounding when drawing canvas items (vogel)

2017-09-24 (bug)[8277e1] linux fontchooser sync with available fonts (vogel)

2017-09-24 (bug)[5239fd] Segfault copying a photo image to itself (bachmann)

2017-09-24 (bug)[514ff6] canvas rotated text overlap detection (vogel)

2017-09-24 (bug)[1e0db2] canvas rchars artifacts (bruchie,vogel)

2017-10-07 (bug)[d9fdfa] display of Long non-wrapped lines in text (cramer)

2017-10-07 (bug)[dd9667] text anchor not set (vogel)

2017-10-11 (bugs) memleaks and other changes for macOS 10.13 support (culler)

2017-10-11 (bug)[111de2] macOS colorspace improvement (walzer,culler)

2017-10-13 (bug) macOS scrolling issues (culler)

2017-10-15 (bug) clipping regions in scrolling and drawing on macOS (culler)

2017-10-15 (bug) macOS redraw artifacts (culler)

2017-10-22 (bug)[bb6b40] ::tk::AmpMenuArgs and 'entryconf' (vogel)

2017-10-22 (bug)[55b95f] Crash [scale] with a bignum value (vogel)

2017-10-28 (bug)[ce62c8] text-37.1 fails (vogel)

2017-11-03 (bug)[0ef1c5] OS X - tests menu-22.[345] hang (vogel)

2017-11-04 (bug)[c8c52b] repair OBOE in menu.test on macOS (vogel)

2017-11-11 (feature) Implement [wm_iconphoto] on macOS (walzer)

2017-11-11 (bug) display of embedded toplevels (culler)

2017-11-19 (bug)[73ba07] Correct property type for MULTIPLE conversion (dpb)

2017-11-20 (bug) Memory leak in tkImgPhoto.c. (werner)

2017-11-21 (bug) Defeat zombie toplevels (culler)

2017-11-25 (bug) macOS resposive menu bar for command line apps (culler)

2017-11-25 (bug)[1c659e] support png from mac screenshots (vogel)

2017-11-25 (bug)[de4af1] macOS file selector "all types" setting (culler)

2017-11-26 (bug) [wm withdraw] on Window and Dock menus (walzer)

2017-11-27 (feature) Drop support for macOS 10.5 (culler)

2017-11-30 (bug)[164c1b] Fixes [raise] on macOS (culler)

2017-11-30 (bug)[13d63d] macOS support of menu -postcommand (culler)

2017-12-05 (bug) enable custom icon display on macOS (walzer)

2017-12-05 (bug)[1088805,0feb63] macOS bind failures (culler)

2017-12-05 (bug)[3382424] Suppress noisy messages on macOS (culler)

2017-12-08 (new)[TIP 477] nmake build system reform (nadkarni)

2017-12-18 (bug)[b77626] Make [tk busy -cursor] silent no-op on macOS (vogel)

--- Released 8.6.8, December 22, 2017 --- https://core.tcl-lang.org/tk/ for details

2017-12-31 (bug)[aa7679] crash using window after master destroyed (vogel)

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

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

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

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

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

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

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

2018-01-28 (bug)[e20d5c] Stop failures of textTag-18.1 (vogel)

2018-02-04 (bug)[5d991b] Fortify var traces against deleted vars (vogel)

2018-02-10 (bug)[1821174] Stop RenderBadPicture X error (werner)

2018-02-11 (bug)[502e74] Stop X errors on untrusted connections (werner)

2018-03-07 (bug)[71b131] Regression in Tk_DrawChars() (werner,cramer)

2018-04-03 (bug)[59fccb] menu flaws when empty menubar clicked (vogel,mcdonald)

2018-04-28 (bug)[7423f9] improved legacy support for [tk_setPalette] (bll)

2018-04-30 (bug)[6d5042] enable [tk inactive] on Mac OSX (culler)

2018-05-03 (bug)[75d38f] fix touchpad scroll of listbox on win notebook (vogel)

2018-06-16 (bug)[de01e2] Crash in [$text replace] (vogel)

2018-07-04 (bug)[6ca257] Fix [wm resizable] on Mac OSX (culler)

2018-07-04 (bug)[135696] Crash in [wm transient] (culler)

2018-07-04 (bug)[309b42] Improve ttk high-contrast-mode support (lemburg,vogel)

2018-07-17 (bug)[1088825] fix frame-2.17,3.9,3.10 on Mac (vogel)

2018-07-27 (bug)[fbaed1] GIF photo support for "deferred clear code" (vogel)

2018-08-08 (feature) Modern full-screen support on Mac OSX (walzer)

2018-08-12 (bug)[1875c1] scrollbar on Mac OSX (walzer)

2018-08-14 (bug)[1ba71a] KeyRelease events on Mac OSX(walzer)

2018-09-02 (bug)[3441086] error message in layout-2 (vogel)

2018-09-07 (bug)[05bd7f] vista theme for combobox (vogel)

2018-09-08 (bug)[382712] crash in KeyPress event handling (vogel,werner)

2018-09-08 (bug)[6fcaaa] insertion cursor visibility in ttk::entry (nemethi)

2018-09-30 (bug)[822923] cascade menu indicator color (mcdonald)

2018-10-06 (bug)[9658bc] borderwidth calculations on menu items (vogel)

2018-10-17 (bug)[ca403f] treeview border drawing (vogel)

2018-10-17 (bug)[4b555a] hang in [$text search -all] (vogel,danckaert)

2018-10-30 (new platform) port to system changes in Mac OSX 10.14 (culler)

2018-11-04 (bug)[6b22d4] [treeview] binding fix (ohagan)

- Released 8.6.9, November 16, 2018 - https://core.tcl-lang.org/tk/ for details

2018-11-19 (bug)[0a9c91] crash in text-11a.22 (vogel)

2018-11-20 (bug)[9705d1] crash activating "Alt" theme (culler)

2018-11-24 (bug)[e3b954] cursor offset at full screen display (culler)

2019-01-04 (bug)[18a4ba] cross-platform [winfo containing] (culler)

2019-01-08 (feature) local grab on Mac OSX (culler)

2019-01-10 (build) 'None', 'ControlMask' symbol conflicts (nijtmans)

2019-01-20 (bug)[509caf] [treeview tag configure] regression (mcdonald,vogel)

2019-01-26 (bug)[3003895] [scale] res rounds and -from (tischler,pieper,vogel)

2019-02-02 (new)[TIP 533] [$mb post x y idx] (culler,vogel)

2019-02-08 (bug)[1529659] embed toplevel blocks outer menu (culler)

2019-02-10 (bug)[8814bd] crash in [NSMenu size] (culler)

2019-02-13 (bug)[b389df] Aqua: mouse position on dual screen (culler)

2019-02-23 (bug)[56a182] Aqua: [tk_getOpenFile] causes off-screen toplevels (culler,walzer)

2019-02-23 (bug)[9771ae] Aqua: workaround incompatible transient window models (culler,walzer)

2019-03-01 (bug)[1951ab] Prevent transient window cycles (crashed on Aqua) (culler,vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2019-03-04 (bug)[4da219] Incomplete read of multi-image GIF (oehlmann)

2019-03-14 (bug)[609e00] Aqua: wrong coords from MouseWheel binding (vogel,culler)

2019-03-25 (bug)[48c394] Aqua: recompute text layout for empty string (culler)

2019-03-31 (new)[TIP 535] Precision of ::scale widget tick mark values (vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2019-03-31 (bug)[da3914] [$treeview identify element] failure (ulfalizer,vogel)

2019-04-06 (bug)[897ffe] Prevent cross-manager loops of geom management (culler,vogel)

2019-04-11 (new) Apple Dark Mode support (culler)

2019-04-14 (new) Aqua: Use color names consistent with NSColor (culler)
        *** POTENTIAL INCOMPATIBILITY ***

2019-04-14 (new) Aqua: [tk::unsupported::MacWindowStyle isdark] (culler)

2019-04-19 (bug)[368fa4] Prevent toggle of hidden treeview indicators (ulfalizer,vogel)

2019-04-24 (bug)[4d2e8d] Aqua: notebook pane redraws (culler)

2019-04-24 (bug)[928652] Apply TIP 533 for ttk::menubutton (culler,vogel)

2019-04-24 (bug)[1001070] X-platform rework of label options -highlight* (seal,culler,vogel)

2019-04-28 (bug)[6286fd] checkbutton handling of -selectcolor (ralfixx)

2019-04-30 (bug)[4f9a99] Win: crash in [style element create] (oehlman,vogel)

2019-05-08 (bug) Ttk scrolling bugs, see tests treeview-9.1, entry-3.[3-6] (vogel)

2019-05-08 (bug)[51b4b1] Aqua: combobox use native ttk scrollbar (bll,vogel)
        *** POTENTIAL INCOMPATIBILITY ***

2019-05-18 (new)[eb2996] Win: support for horizontal scrolling (chavez,vogel)

2019-05-26 (new)[TIP 541] [combobox current] support "end" index (vogel)

2019-05-26 (bug)[2a6c62] <<TreeviewSelect>> trigger on item delete (vogel)

2019-06-05 (bug)[9ebc6f] Aqua: fix incorrect reports of mouse coords (chavez, culler)

2019-06-14 (bug)[436ad6] Corrected Aqua regressions in [wm manage] (walzer, culler)

2019-06-15 (bug)[75b8fb] Crash with some [event generate]d <ButtonRelease> (leunissen,vogel)

2019-06-15 (new)[TIP 536] New tk::mac::* commands for IPC on Mac OSX (walzer)

2019-07-13 (bug)[4566e2] Aqua: Make default background color of Tk and Ttk agree (walzer,culler)
        *** POTENTIAL INCOMPATIBILITY ***

2019-07-16 (bug)[5ddeca] Stop app switching exposing withdrawn windows as zombies (culler)

2019-07-25 (new)[1fb7af] Win support for buttons 4 and 5 (chavez,vogel,nijtmans)

2019-08-18 (new) Refactor all MouseWheel bindings (nijtmans)
        *** POTENTIAL INCOMPATIBILITY ***

2019-08-21 (bug)[c8ccd1] up array key in [text] takes to index 1.0 (ulfalizer,vogel)

2019-08-28 (new)[TIP 532] Tk event loop rewrite to prevent ring overflow (cramer)
        *** POTENTIAL INCOMPATIBILITY ***

2019-08-28 (bug)[943d5e] Win: embedded widget destruction cancels window resize (nemethi,vogel,nijtmans)

2019-09-12 (bug)[2834776] Stop disabled spinbox from generating <<Increment>> & <<Decrement>> (vogel)

2019-09-24 (bug)[96bce5] Aqua: Prevent crash drawing 1x1 rounded rectangles (bll,culler)

2019-10-03 (bug)[3ed5b6] Win: root window position with highlightthickness>0 (leunissem,vogel,nijtmans)

2019-10-09 (bug)[a01b6f7] Workaround XWayland bug reporting screen width (werner,nijtmans)

2019-10-10 (bug) Aqua: Prevent crash deactivating menu during menu deletion (culler)

2019-10-21 (bug)[aea00b] Aqua: Better handling of resolution changes (chavez, culler)

2019-10-25 (bug)[b82bd4] Fix [style configure -compound] (culler,vogel)

2019-10-27 (bug)[f7a4f7] Aqua: embedded toplevel, forced focus and mouse coords (naaus,culler)

2019-11-13 (new) Win: keycodes Mail, AudioMedia, Launch0, Launch1 (nijtmans)

2019-11-15 (bug)[69b48f] failing test textTag-18.1 (vogel)

2019-11-17 (bug)[c4abd2] panic in stackorder command (culler)

2019-11-17 (bug)[53d280] [wm iconphoto] crash on empty image (culler)

2019-11-17 [90d555] workaround NSFontManager bad selections (culler)

2019-11-19 (new) Partial Emoji support in text displays (nijtmans,culler)

- Released 8.6.10, Nov 21, 2019 - https://core.tcl-lang.org/tk/ for details

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

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

2017-12-07 [TIP 487] End support for pre-XP Windows (nijtmans)

2018-03-04 [TIP 489] New subcommand [$canvas image] (pitcher,vogel)

2018-05-13 [TIP 496] New options -placeholder* for entries (zaumseil,vogel)

2018-09-23 [TIP 517] New option -activerelief for menus (vogel)

2018-11-03 [TIP 512] Deprecate stub for Tk_MainEx() (nijtmans)

2018-11-06 [TIP 415] New option -height for [$canvas create arc] (geard)

2018-11-06 [TIP 518] New event <<NoMangedChild>> (oehlmann)

2019-04-14 [TIP 164] New subcommand [$canvas rotate] (fellows)

2019-04-14 [TIP 507] New photo image format 'svg' (zaumseil)

2019-04-14 [TIP 483] Record more configuration items (cassoff)

2019-04-14 [TIP 482] Record configured directory for demos (cassoff)

2019-05-25 [TIP 262] New frame options -backgroundimage, -tile (fellows)

2019-06-15 [TIP 528] Deprecate Tk_Offset() (nijtmans)

2019-08-19 [TIP 545] Revised options for photo image format 'svg' (oehlmann)

--- Released 8.7a3, November 25, 2019 --- http://core.tcl.tk/tk/ for details
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added changes.md.



>
1
TODO

Deleted compat/stdint.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
/*  A portable stdint.h
 ****************************************************************************
 *  BSD License:
 ****************************************************************************
 *
 *  Copyright (c) 2005-2016 Paul Hsieh
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************
 *
 *  Version 0.1.16.0
 *
 *  The ANSI C standard committee, for the C99 standard, specified the
 *  inclusion of a new standard include file called stdint.h.  This is
 *  a very useful and long desired include file which contains several
 *  very precise definitions for integer scalar types that is critically
 *  important for making several classes of applications portable
 *  including cryptography, hashing, variable length integer libraries
 *  and so on.  But for most developers its likely useful just for
 *  programming sanity.
 *
 *  The problem is that some compiler vendors chose to ignore the C99
 *  standard and some older compilers have no opportunity to be updated.
 *  Because of this situation, simply including stdint.h in your code
 *  makes it unportable.
 *
 *  So that's what this file is all about.  It's an attempt to build a
 *  single universal include file that works on as many platforms as
 *  possible to deliver what stdint.h is supposed to.  Even compilers
 *  that already come with stdint.h can use this file instead without
 *  any loss of functionality.  A few things that should be noted about
 *  this file:
 *
 *    1) It is not guaranteed to be portable and/or present an identical
 *       interface on all platforms.  The extreme variability of the
 *       ANSI C standard makes this an impossibility right from the
 *       very get go. Its really only meant to be useful for the vast
 *       majority of platforms that possess the capability of
 *       implementing usefully and precisely defined, standard sized
 *       integer scalars.  Systems which are not intrinsically 2s
 *       complement may produce invalid constants.
 *
 *    2) There is an unavoidable use of non-reserved symbols.
 *
 *    3) Other standard include files are invoked.
 *
 *    4) This file may come in conflict with future platforms that do
 *       include stdint.h.  The hope is that one or the other can be
 *       used with no real difference.
 *
 *    5) In the current version, if your platform can't represent
 *       int32_t, int16_t and int8_t, it just dumps out with a compiler
 *       error.
 *
 *    6) 64 bit integers may or may not be defined.  Test for their
 *       presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
 *       Note that this is different from the C99 specification which
 *       requires the existence of 64 bit support in the compiler.  If
 *       this is not defined for your platform, yet it is capable of
 *       dealing with 64 bits then it is because this file has not yet
 *       been extended to cover all of your system's capabilities.
 *
 *    7) (u)intptr_t may or may not be defined.  Test for its presence
 *       with the test: #ifdef PTRDIFF_MAX.  If this is not defined
 *       for your platform, then it is because this file has not yet
 *       been extended to cover all of your system's capabilities, not
 *       because its optional.
 *
 *    8) The following might not been defined even if your platform is
 *       capable of defining it:
 *
 *       WCHAR_MIN
 *       WCHAR_MAX
 *       (u)int64_t
 *       PTRDIFF_MIN
 *       PTRDIFF_MAX
 *       (u)intptr_t
 *
 *    9) The following have not been defined:
 *
 *       WINT_MIN
 *       WINT_MAX
 *
 *   10) The criteria for defining (u)int_least(*)_t isn't clear,
 *       except for systems which don't have a type that precisely
 *       defined 8, 16, or 32 bit types (which this include file does
 *       not support anyways). Default definitions have been given.
 *
 *   11) The criteria for defining (u)int_fast(*)_t isn't something I
 *       would trust to any particular compiler vendor or the ANSI C
 *       committee.  It is well known that "compatible systems" are
 *       commonly created that have very different performance
 *       characteristics from the systems they are compatible with,
 *       especially those whose vendors make both the compiler and the
 *       system.  Default definitions have been given, but its strongly
 *       recommended that users never use these definitions for any
 *       reason (they do *NOT* deliver any serious guarantee of
 *       improved performance -- not in this file, nor any vendor's
 *       stdint.h).
 *
 *   12) The following macros:
 *
 *       PRINTF_INTMAX_MODIFIER
 *       PRINTF_INT64_MODIFIER
 *       PRINTF_INT32_MODIFIER
 *       PRINTF_INT16_MODIFIER
 *       PRINTF_LEAST64_MODIFIER
 *       PRINTF_LEAST32_MODIFIER
 *       PRINTF_LEAST16_MODIFIER
 *       PRINTF_INTPTR_MODIFIER
 *
 *       are strings which have been defined as the modifiers required
 *       for the "d", "u" and "x" printf formats to correctly output
 *       (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
 *       (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
 *       PRINTF_INTPTR_MODIFIER is not defined for some systems which
 *       provide their own stdint.h.  PRINTF_INT64_MODIFIER is not
 *       defined if INT64_MAX is not defined.  These are an extension
 *       beyond what C99 specifies must be in stdint.h.
 *
 *       In addition, the following macros are defined:
 *
 *       PRINTF_INTMAX_HEX_WIDTH
 *       PRINTF_INT64_HEX_WIDTH
 *       PRINTF_INT32_HEX_WIDTH
 *       PRINTF_INT16_HEX_WIDTH
 *       PRINTF_INT8_HEX_WIDTH
 *       PRINTF_INTMAX_DEC_WIDTH
 *       PRINTF_INT64_DEC_WIDTH
 *       PRINTF_INT32_DEC_WIDTH
 *       PRINTF_INT16_DEC_WIDTH
 *       PRINTF_UINT8_DEC_WIDTH
 *       PRINTF_UINTMAX_DEC_WIDTH
 *       PRINTF_UINT64_DEC_WIDTH
 *       PRINTF_UINT32_DEC_WIDTH
 *       PRINTF_UINT16_DEC_WIDTH
 *       PRINTF_UINT8_DEC_WIDTH
 *
 *       Which specifies the maximum number of characters required to
 *       print the number of that type in either hexadecimal or decimal.
 *       These are an extension beyond what C99 specifies must be in
 *       stdint.h.
 *
 *  Compilers tested (all with 0 warnings at their highest respective
 *  settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
 *  bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
 *  .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
 *
 *  This file should be considered a work in progress.  Suggestions for
 *  improvements, especially those which increase coverage are strongly
 *  encouraged.
 *
 *  Acknowledgements
 *
 *  The following people have made significant contributions to the
 *  development and testing of this file:
 *
 *  Chris Howie
 *  John Steele Scott
 *  Dave Thorup
 *  John Dill
 *  Florian Wobbe
 *  Christopher Sean Morrison
 *  Mikkel Fahnoe Jorgensen
 *
 */

#include <stddef.h>
#include <limits.h>
#include <signal.h>

/*
 *  For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
 *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
 */

#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
#include <stdint.h>
#define _PSTDINT_H_INCLUDED
# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "l"
#  endif
#  ifndef PRINTF_INT32_MODIFIER
#   define PRINTF_INT32_MODIFIER ""
#  endif
# else
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
#  ifndef PRINTF_INT32_MODIFIER
#   if (UINT_MAX == UINT32_MAX)
#    define PRINTF_INT32_MODIFIER ""
#   else
#    define PRINTF_INT32_MODIFIER "l"
#   endif
#  endif
# endif
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
# ifndef PRINTF_INTMAX_MODIFIER
#  define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INT64_HEX_WIDTH
#  define PRINTF_INT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_UINT64_HEX_WIDTH
#  define PRINTF_UINT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_INT32_HEX_WIDTH
#  define PRINTF_INT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_UINT32_HEX_WIDTH
#  define PRINTF_UINT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_INT16_HEX_WIDTH
#  define PRINTF_INT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_UINT16_HEX_WIDTH
#  define PRINTF_UINT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_INT8_HEX_WIDTH
#  define PRINTF_INT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_UINT8_HEX_WIDTH
#  define PRINTF_UINT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_INT64_DEC_WIDTH
#  define PRINTF_INT64_DEC_WIDTH "19"
# endif
# ifndef PRINTF_UINT64_DEC_WIDTH
#  define PRINTF_UINT64_DEC_WIDTH "20"
# endif
# ifndef PRINTF_INT32_DEC_WIDTH
#  define PRINTF_INT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_UINT32_DEC_WIDTH
#  define PRINTF_UINT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_INT16_DEC_WIDTH
#  define PRINTF_INT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_UINT16_DEC_WIDTH
#  define PRINTF_UINT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_INT8_DEC_WIDTH
#  define PRINTF_INT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_UINT8_DEC_WIDTH
#  define PRINTF_UINT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
# endif
# ifndef PRINTF_UINTMAX_HEX_WIDTH
#  define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
# endif
# ifndef PRINTF_UINTMAX_DEC_WIDTH
#  define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
# endif

/*
 *  Something really weird is going on with Open Watcom.  Just pull some of
 *  these duplicated definitions from Open Watcom's stdint.h file for now.
 */

# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
#  if !defined (INT64_C)
#   define INT64_C(x)   (x + (INT64_MAX - INT64_MAX))
#  endif
#  if !defined (UINT64_C)
#   define UINT64_C(x)  (x + (UINT64_MAX - UINT64_MAX))
#  endif
#  if !defined (INT32_C)
#   define INT32_C(x)   (x + (INT32_MAX - INT32_MAX))
#  endif
#  if !defined (UINT32_C)
#   define UINT32_C(x)  (x + (UINT32_MAX - UINT32_MAX))
#  endif
#  if !defined (INT16_C)
#   define INT16_C(x)   (x)
#  endif
#  if !defined (UINT16_C)
#   define UINT16_C(x)  (x)
#  endif
#  if !defined (INT8_C)
#   define INT8_C(x)   (x)
#  endif
#  if !defined (UINT8_C)
#   define UINT8_C(x)  (x)
#  endif
#  if !defined (UINT64_MAX)
#   define UINT64_MAX  18446744073709551615ULL
#  endif
#  if !defined (INT64_MAX)
#   define INT64_MAX  9223372036854775807LL
#  endif
#  if !defined (UINT32_MAX)
#   define UINT32_MAX  4294967295UL
#  endif
#  if !defined (INT32_MAX)
#   define INT32_MAX  2147483647L
#  endif
#  if !defined (INTMAX_MAX)
#   define INTMAX_MAX INT64_MAX
#  endif
#  if !defined (INTMAX_MIN)
#   define INTMAX_MIN INT64_MIN
#  endif
# endif
#endif

/*
 *  I have no idea what is the truly correct thing to do on older Solaris.
 *  From some online discussions, this seems to be what is being
 *  recommended.  For people who actually are developing on older Solaris,
 *  what I would like to know is, does this define all of the relevant
 *  macros of a complete stdint.h?  Remember, in pstdint.h 64 bit is
 *  considered optional.
 */

#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
#include <sys/inttypes.h>
#define _PSTDINT_H_INCLUDED
#endif

#ifndef _PSTDINT_H_INCLUDED
#define _PSTDINT_H_INCLUDED

#ifndef SIZE_MAX
# define SIZE_MAX ((size_t)-1)
#endif

/*
 *  Deduce the type assignments from limits.h under the assumption that
 *  integer sizes in bits are powers of 2, and follow the ANSI
 *  definitions.
 */

#ifndef UINT8_MAX
# define UINT8_MAX 0xff
#endif
#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
    typedef unsigned char uint8_t;
#   define UINT8_C(v) ((uint8_t) v)
# else
#   error "Platform not supported"
# endif
#endif

#ifndef INT8_MAX
# define INT8_MAX 0x7f
#endif
#ifndef INT8_MIN
# define INT8_MIN INT8_C(0x80)
#endif
#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
    typedef signed char int8_t;
#   define INT8_C(v) ((int8_t) v)
# else
#   error "Platform not supported"
# endif
#endif

#ifndef UINT16_MAX
# define UINT16_MAX 0xffff
#endif
#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
  typedef unsigned int uint16_t;
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER ""
# endif
# define UINT16_C(v) ((uint16_t) (v))
#elif (USHRT_MAX == UINT16_MAX)
  typedef unsigned short uint16_t;
# define UINT16_C(v) ((uint16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef INT16_MAX
# define INT16_MAX 0x7fff
#endif
#ifndef INT16_MIN
# define INT16_MIN INT16_C(0x8000)
#endif
#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
  typedef signed int int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER ""
# endif
#elif (SHRT_MAX == INT16_MAX)
  typedef signed short int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef UINT32_MAX
# define UINT32_MAX (0xffffffffUL)
#endif
#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
  typedef unsigned long uint32_t;
# define UINT32_C(v) v ## UL
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER "l"
# endif
#elif (UINT_MAX == UINT32_MAX)
  typedef unsigned int uint32_t;
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
# define UINT32_C(v) v ## U
#elif (USHRT_MAX == UINT32_MAX)
  typedef unsigned short uint32_t;
# define UINT32_C(v) ((unsigned short) (v))
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef INT32_MAX
# define INT32_MAX (0x7fffffffL)
#endif
#ifndef INT32_MIN
# define INT32_MIN INT32_C(0x80000000)
#endif
#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
  typedef signed long int32_t;
# define INT32_C(v) v ## L
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER "l"
# endif
#elif (INT_MAX == INT32_MAX)
  typedef signed int int32_t;
# define INT32_C(v) v
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#elif (SHRT_MAX == INT32_MAX)
  typedef signed short int32_t;
# define INT32_C(v) ((short) (v))
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif

/*
 *  The macro stdint_int64_defined is temporarily used to record
 *  whether or not 64 integer support is available.  It must be
 *  defined for any 64 integer extensions for new platforms that are
 *  added.
 */

#undef stdint_int64_defined
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
#  define stdint_int64_defined
   typedef long long int64_t;
   typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# endif
#endif

#if !defined (stdint_int64_defined)
# if defined(__GNUC__) && !defined(vxWorks)
#  define stdint_int64_defined
   __extension__ typedef long long int64_t;
   __extension__ typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
#  define stdint_int64_defined
   typedef long long int64_t;
   typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
#  define stdint_int64_defined
   typedef __int64 int64_t;
   typedef unsigned __int64 uint64_t;
#  define UINT64_C(v) v ## UI64
#  define  INT64_C(v) v ## I64
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "I64"
#  endif
# endif
#endif

#if !defined (LONG_LONG_MAX) && defined (INT64_C)
# define LONG_LONG_MAX INT64_C (9223372036854775807)
#endif
#ifndef ULONG_LONG_MAX
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
#endif

#if !defined (INT64_MAX) && defined (INT64_C)
# define INT64_MAX INT64_C (9223372036854775807)
#endif
#if !defined (INT64_MIN) && defined (INT64_C)
# define INT64_MIN INT64_C (-9223372036854775808)
#endif
#if !defined (UINT64_MAX) && defined (INT64_C)
# define UINT64_MAX UINT64_C (18446744073709551615)
#endif

/*
 *  Width of hexadecimal for number field.
 */

#ifndef PRINTF_INT64_HEX_WIDTH
# define PRINTF_INT64_HEX_WIDTH "16"
#endif
#ifndef PRINTF_INT32_HEX_WIDTH
# define PRINTF_INT32_HEX_WIDTH "8"
#endif
#ifndef PRINTF_INT16_HEX_WIDTH
# define PRINTF_INT16_HEX_WIDTH "4"
#endif
#ifndef PRINTF_INT8_HEX_WIDTH
# define PRINTF_INT8_HEX_WIDTH "2"
#endif
#ifndef PRINTF_INT64_DEC_WIDTH
# define PRINTF_INT64_DEC_WIDTH "19"
#endif
#ifndef PRINTF_INT32_DEC_WIDTH
# define PRINTF_INT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_INT16_DEC_WIDTH
# define PRINTF_INT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_INT8_DEC_WIDTH
# define PRINTF_INT8_DEC_WIDTH "3"
#endif
#ifndef PRINTF_UINT64_DEC_WIDTH
# define PRINTF_UINT64_DEC_WIDTH "20"
#endif
#ifndef PRINTF_UINT32_DEC_WIDTH
# define PRINTF_UINT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_UINT16_DEC_WIDTH
# define PRINTF_UINT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_UINT8_DEC_WIDTH
# define PRINTF_UINT8_DEC_WIDTH "3"
#endif

/*
 *  Ok, lets not worry about 128 bit integers for now.  Moore's law says
 *  we don't need to worry about that until about 2040 at which point
 *  we'll have bigger things to worry about.
 */

#ifdef stdint_int64_defined
  typedef int64_t intmax_t;
  typedef uint64_t uintmax_t;
# define  INTMAX_MAX   INT64_MAX
# define  INTMAX_MIN   INT64_MIN
# define UINTMAX_MAX  UINT64_MAX
# define UINTMAX_C(v) UINT64_C(v)
# define  INTMAX_C(v)  INT64_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
#   define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
# endif
#else
  typedef int32_t intmax_t;
  typedef uint32_t uintmax_t;
# define  INTMAX_MAX   INT32_MAX
# define UINTMAX_MAX  UINT32_MAX
# define UINTMAX_C(v) UINT32_C(v)
# define  INTMAX_C(v)  INT32_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
#   define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
# endif
#endif

/*
 *  Because this file currently only supports platforms which have
 *  precise powers of 2 as bit sizes for the default integers, the
 *  least definitions are all trivial.  Its possible that a future
 *  version of this file could have different definitions.
 */

#ifndef stdint_least_defined
  typedef   int8_t   int_least8_t;
  typedef  uint8_t  uint_least8_t;
  typedef  int16_t  int_least16_t;
  typedef uint16_t uint_least16_t;
  typedef  int32_t  int_least32_t;
  typedef uint32_t uint_least32_t;
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
# define  UINT_LEAST8_MAX  UINT8_MAX
# define   INT_LEAST8_MAX   INT8_MAX
# define UINT_LEAST16_MAX UINT16_MAX
# define  INT_LEAST16_MAX  INT16_MAX
# define UINT_LEAST32_MAX UINT32_MAX
# define  INT_LEAST32_MAX  INT32_MAX
# define   INT_LEAST8_MIN   INT8_MIN
# define  INT_LEAST16_MIN  INT16_MIN
# define  INT_LEAST32_MIN  INT32_MIN
# ifdef stdint_int64_defined
    typedef  int64_t  int_least64_t;
    typedef uint64_t uint_least64_t;
#   define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
#   define UINT_LEAST64_MAX UINT64_MAX
#   define  INT_LEAST64_MAX  INT64_MAX
#   define  INT_LEAST64_MIN  INT64_MIN
# endif
#endif
#undef stdint_least_defined

/*
 *  The ANSI C committee has defined *int*_fast*_t types as well.  This,
 *  of course, defies rationality -- you can't know what will be fast
 *  just from the type itself.  Even for a given architecture, compatible
 *  implementations might have different performance characteristics.
 *  Developers are warned to stay away from these types when using this
 *  or any other stdint.h.
 */

typedef   int_least8_t   int_fast8_t;
typedef  uint_least8_t  uint_fast8_t;
typedef  int_least16_t  int_fast16_t;
typedef uint_least16_t uint_fast16_t;
typedef  int_least32_t  int_fast32_t;
typedef uint_least32_t uint_fast32_t;
#define  UINT_FAST8_MAX  UINT_LEAST8_MAX
#define   INT_FAST8_MAX   INT_LEAST8_MAX
#define UINT_FAST16_MAX UINT_LEAST16_MAX
#define  INT_FAST16_MAX  INT_LEAST16_MAX
#define UINT_FAST32_MAX UINT_LEAST32_MAX
#define  INT_FAST32_MAX  INT_LEAST32_MAX
#define   INT_FAST8_MIN   INT_LEAST8_MIN
#define  INT_FAST16_MIN  INT_LEAST16_MIN
#define  INT_FAST32_MIN  INT_LEAST32_MIN
#ifdef stdint_int64_defined
  typedef  int_least64_t  int_fast64_t;
  typedef uint_least64_t uint_fast64_t;
# define UINT_FAST64_MAX UINT_LEAST64_MAX
# define  INT_FAST64_MAX  INT_LEAST64_MAX
# define  INT_FAST64_MIN  INT_LEAST64_MIN
#endif

#undef stdint_int64_defined

/*
 *  Whatever piecemeal, per compiler thing we can do about the wchar_t
 *  type limits.
 */

#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
# include <wchar.h>
# ifndef WCHAR_MIN
#  define WCHAR_MIN 0
# endif
# ifndef WCHAR_MAX
#  define WCHAR_MAX ((wchar_t)-1)
# endif
#endif

/*
 *  Whatever piecemeal, per compiler/platform thing we can do about the
 *  (u)intptr_t types and limits.
 */

#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
# define STDINT_H_UINTPTR_T_DEFINED
#endif

#ifndef STDINT_H_UINTPTR_T_DEFINED
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
#  define stdint_intptr_bits 64
# elif defined (__WATCOMC__) || defined (__TURBOC__)
#  if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#    define stdint_intptr_bits 16
#  else
#    define stdint_intptr_bits 32
#  endif
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
#  define stdint_intptr_bits 32
# elif defined (__INTEL_COMPILER)
/* TODO -- what did Intel do about x86-64? */
# else
/* #error "This platform might not be supported yet" */
# endif

# ifdef stdint_intptr_bits
#  define stdint_intptr_glue3_i(a,b,c)  a##b##c
#  define stdint_intptr_glue3(a,b,c)    stdint_intptr_glue3_i(a,b,c)
#  ifndef PRINTF_INTPTR_MODIFIER
#    define PRINTF_INTPTR_MODIFIER      stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
#  endif
#  ifndef PTRDIFF_MAX
#    define PTRDIFF_MAX                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef PTRDIFF_MIN
#    define PTRDIFF_MIN                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
#  endif
#  ifndef UINTPTR_MAX
#    define UINTPTR_MAX                 stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef INTPTR_MAX
#    define INTPTR_MAX                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef INTPTR_MIN
#    define INTPTR_MIN                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
#  endif
#  ifndef INTPTR_C
#    define INTPTR_C(x)                 stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
#  endif
#  ifndef UINTPTR_C
#    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
#  endif
  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
# else
/* TODO -- This following is likely wrong for some platforms, and does
   nothing for the definition of uintptr_t. */
  typedef ptrdiff_t intptr_t;
# endif
# define STDINT_H_UINTPTR_T_DEFINED
#endif

/*
 *  Assumes sig_atomic_t is signed and we have a 2s complement machine.
 */

#ifndef SIG_ATOMIC_MAX
# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
#endif

#endif

#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)

/*
 *  Please compile with the maximum warning settings to make sure macros are
 *  not defined more than once.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define glue3_aux(x,y,z) x ## y ## z
#define glue3(x,y,z) glue3_aux(x,y,z)

#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);

#define DECL(us,bits) glue3(DECL,us,) (bits)

#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)

#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }

#define X_SIZE_MAX ((size_t)-1)

int main () {
	int err_n = 0;
	int err_first = 0;
	DECL(I,8)
	DECL(U,8)
	DECL(I,16)
	DECL(U,16)
	DECL(I,32)
	DECL(U,32)
#ifdef INT64_MAX
	DECL(I,64)
	DECL(U,64)
#endif
	intmax_t imax = INTMAX_C(0);
	uintmax_t umax = UINTMAX_C(0);
	char str0[256], str1[256];

	sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
	if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
	if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
	sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
	if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
	if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
#ifdef INT64_MAX
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
	if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
	if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
	if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
	if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
#endif

	sprintf (str0, "%d %x\n", 0, ~0);

	sprintf (str1, "%d %x\n",  i8, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
	sprintf (str1, "%u %x\n",  u8, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
	sprintf (str1, "%d %x\n",  i16, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
	sprintf (str1, "%u %x\n",  u16, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
	sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n",  i32, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
	sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n",  u32, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
#ifdef INT64_MAX
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n",  i64, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
#endif
	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n",  imax, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n",  umax, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));

	TESTUMAX(8);
	TESTUMAX(16);
	TESTUMAX(32);
#ifdef INT64_MAX
	TESTUMAX(64);
#endif

#define STR(v) #v
#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
	if (err_n) {
		printf ("pstdint.h is not correct.  Please use sizes below to correct it:\n");
	}

	Q(int)
	Q(unsigned)
	Q(long int)
	Q(short int)
	Q(int8_t)
	Q(int16_t)
	Q(int32_t)
#ifdef INT64_MAX
	Q(int64_t)
#endif

#if UINT_MAX < X_SIZE_MAX
	printf ("UINT_MAX < X_SIZE_MAX\n");
#else
	printf ("UINT_MAX >= X_SIZE_MAX\n");
#endif
	printf ("%" PRINTF_INT64_MODIFIER "u vs %" PRINTF_INT64_MODIFIER "u\n", UINT_MAX, X_SIZE_MAX);

	return EXIT_SUCCESS;
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to doc/3DBorder.3.

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




20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_Alloc3DBorderFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Alloc3DBorderFromObj, Tk_Get3DBorder, Tk_Get3DBorderFromObj, Tk_Draw3DRectangle, Tk_Fill3DRectangle, Tk_Draw3DPolygon, Tk_Fill3DPolygon, Tk_3DVerticalBevel, Tk_3DHorizontalBevel, Tk_SetBackgroundFromBorder, Tk_NameOf3DBorder, Tk_3DBorderColor, Tk_3DBorderGC, Tk_Free3DBorderFromObj, Tk_Free3DBorder \- draw borders with three-dimensional appearance
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_3DBorder
\fBTk_Alloc3DBorderFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp




Tk_3DBorder
\fBTk_Get3DBorder(\fIinterp, tkwin, colorName\fB)\fR
.sp


Tk_3DBorder
\fBTk_Get3DBorderFromObj(\fItkwin, objPtr\fB)\fR
.sp
void
\fBTk_Draw3DRectangle(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fB)\fR
.sp
void
\fBTk_Fill3DRectangle(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fB)\fR
.sp
void
\fBTk_Draw3DPolygon(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fB)\fR
.sp
void
\fBTk_Fill3DPolygon(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fB)\fR
.sp
void
\fBTk_3DVerticalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftBevel, relief\fB)\fR
.sp
void
\fBTk_3DHorizontalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief\fB)\fR
.sp
void
\fBTk_SetBackgroundFromBorder(\fItkwin, border\fB)\fR
.sp
const char *
\fBTk_NameOf3DBorder(\fIborder\fB)\fR
.sp
XColor *
\fBTk_3DBorderColor(\fIborder\fB)\fR
.sp
GC *
\fBTk_3DBorderGC(\fItkwin, border, which\fB)\fR
.sp
\fBTk_Free3DBorderFromObj(\fItkwin, objPtr\fB)\fR
.sp
\fBTk_Free3DBorder(\fIborder\fB)\fR

.SH ARGUMENTS
.AS "Tk_3DBorder" borderWidth
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window (for all procedures except \fBTk_Get3DBorder\fR,
must be the window for which the border was allocated).











|



|

|

>
>
>
>

|

>
>

|

<
|

<
|

<
|

<
|

<
|

<
|

<
|


|


|


|

|

|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33

34
35

36
37

38
39

40
41

42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_Alloc3DBorderFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Alloc3DBorderFromObj, Tk_ClipDrawableToRect, Tk_DrawHighlightBorder, Tk_Get3DBorder, Tk_Get3DBorderColors, Tk_Get3DBorderFromObj, Tk_Draw3DRectangle, Tk_Fill3DRectangle, Tk_Draw3DPolygon, Tk_Fill3DPolygon, Tk_3DVerticalBevel, Tk_3DHorizontalBevel, Tk_SetBackgroundFromBorder, Tk_NameOf3DBorder, Tk_3DBorderColor, Tk_3DBorderGC, Tk_Free3DBorderFromObj, Tk_Free3DBorder \- draw borders with three-dimensional appearance
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR

Tk_3DBorder
\fBTk_Alloc3DBorderFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
\fBTk_ClipDrawableToRect\fR(\fIdisplay, drawable, x, y, width, height\fR)
.sp
\fBTk_DrawHighlightBorder\fR(\fItkwin, fgGC, bgGC, highlightWidth, drawable\fR)
.sp
Tk_3DBorder
\fBTk_Get3DBorder\fR(\fIinterp, tkwin, colorName\fR)
.sp
\fBTk_Get3DBorderColors\fR(\fIborder, bgColorPtr, darkColorPtr, lightColorPtr\fR)
.sp
Tk_3DBorder
\fBTk_Get3DBorderFromObj\fR(\fItkwin, objPtr\fR)
.sp

\fBTk_Draw3DRectangle\fR(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fR)
.sp

\fBTk_Fill3DRectangle\fR(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fR)
.sp

\fBTk_Draw3DPolygon\fR(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fR)
.sp

\fBTk_Fill3DPolygon\fR(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fR)
.sp

\fBTk_3DVerticalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftBevel, relief\fR)
.sp

\fBTk_3DHorizontalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief\fR)
.sp

\fBTk_SetBackgroundFromBorder\fR(\fItkwin, border\fR)
.sp
const char *
\fBTk_NameOf3DBorder\fR(\fIborder\fR)
.sp
XColor *
\fBTk_3DBorderColor\fR(\fIborder\fR)
.sp
GC *
\fBTk_3DBorderGC\fR(\fItkwin, border, which\fR)
.sp
\fBTk_Free3DBorderFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_Free3DBorder\fR(\fIborder\fR)
.fi
.SH ARGUMENTS
.AS "Tk_3DBorder" borderWidth
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window (for all procedures except \fBTk_Get3DBorder\fR,
must be the window for which the border was allocated).
86
87
88
89
90
91
92



93
94
95
96
97
98
99
Width of rectangle describing border or bevel, in pixels.
.AP int height in
Height of rectangle describing border or bevel, in pixels.
.AP int borderWidth in
Width of border in pixels. Positive means border is inside rectangle
given by \fIx\fR, \fIy\fR, \fIwidth\fR, \fIheight\fR, negative means
border is outside rectangle.



.AP int relief in
Indicates 3-D position of interior of value relative to exterior;
should be \fBTK_RELIEF_RAISED\fR, \fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR,
\fBTK_RELIEF_SOLID\fR, or \fBTK_RELIEF_RIDGE\fR (may also be \fBTK_RELIEF_FLAT\fR
for \fBTk_Fill3DRectangle\fR).
.AP XPoint *pointPtr in
Pointer to array of points describing the set of vertices in a polygon.







>
>
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
Width of rectangle describing border or bevel, in pixels.
.AP int height in
Height of rectangle describing border or bevel, in pixels.
.AP int borderWidth in
Width of border in pixels. Positive means border is inside rectangle
given by \fIx\fR, \fIy\fR, \fIwidth\fR, \fIheight\fR, negative means
border is outside rectangle.
.AP int highlightWidth in
Width of ring around the outside of the widget if the widget has received the
input focus.
.AP int relief in
Indicates 3-D position of interior of value relative to exterior;
should be \fBTK_RELIEF_RAISED\fR, \fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR,
\fBTK_RELIEF_SOLID\fR, or \fBTK_RELIEF_RIDGE\fR (may also be \fBTK_RELIEF_FLAT\fR
for \fBTk_Fill3DRectangle\fR).
.AP XPoint *pointPtr in
Pointer to array of points describing the set of vertices in a polygon.
129
130
131
132
133
134
135












136
137
138
139
140
141
142
right than the top.
.AP int topBevel in
Non-zero means this bevel forms the top side of the value;  zero means
it forms the bottom side.
.AP int which in
Specifies which of the border's graphics contexts is desired.
Must be \fBTK_3D_FLAT_GC\fR, \fBTK_3D_LIGHT_GC\fR, or \fBTK_3D_DARK_GC\fR.












.BE
.SH DESCRIPTION
.PP
These procedures provide facilities for drawing window borders in a
way that produces a three-dimensional appearance.
\fBTk_Alloc3DBorderFromObj\fR
allocates colors and Pixmaps needed to draw a border in the window







>
>
>
>
>
>
>
>
>
>
>
>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
right than the top.
.AP int topBevel in
Non-zero means this bevel forms the top side of the value;  zero means
it forms the bottom side.
.AP int which in
Specifies which of the border's graphics contexts is desired.
Must be \fBTK_3D_FLAT_GC\fR, \fBTK_3D_LIGHT_GC\fR, or \fBTK_3D_DARK_GC\fR.
.AP XColor *bgColorPtr out
Pointer to location in which to store the background color of the given border.
.AP XColor *darkColorPtr out
Pointer to location in which to store the color for darker areas of the
given border.
.AP XColor *lightColorPtr out
Pointer to location in which to store the color for lighter areas of the
given border.
.AP GC fgGC in
Foreground X graphics context.
.AP GC fgGC in
Background X graphics context.
.BE
.SH DESCRIPTION
.PP
These procedures provide facilities for drawing window borders in a
way that produces a three-dimensional appearance.
\fBTk_Alloc3DBorderFromObj\fR
allocates colors and Pixmaps needed to draw a border in the window
154
155
156
157
158
159
160














161
162
163
164
165


166
167
168
169
170
171
172
for the border (e.g. a bogus color name was given)
then NULL is returned and an error message is left as the result of
interpreter \fIinterp\fR.
If it returns successfully, \fBTk_Alloc3DBorderFromObj\fR caches
information about the return value in \fIobjPtr\fR, which speeds up
future calls to \fBTk_Alloc3DBorderFromObj\fR with the same \fIobjPtr\fR
and \fItkwin\fR.














.PP
\fBTk_Get3DBorder\fR is identical to \fBTk_Alloc3DBorderFromObj\fR except
that the color is specified with a string instead of a value.  This
prevents \fBTk_Get3DBorder\fR from caching the return value, so
\fBTk_Get3DBorder\fR is less efficient than \fBTk_Alloc3DBorderFromObj\fR.


.PP
\fBTk_Get3DBorderFromObj\fR returns the token for an existing border, given
the window and color name used to create the border.
\fBTk_Get3DBorderFromObj\fR does not actually create the border; it must
already have been created with a previous call to
\fBTk_Alloc3DBorderFromObj\fR or \fBTk_Get3DBorder\fR.  The return
value is cached in \fIobjPtr\fR, which speeds up







>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
for the border (e.g. a bogus color name was given)
then NULL is returned and an error message is left as the result of
interpreter \fIinterp\fR.
If it returns successfully, \fBTk_Alloc3DBorderFromObj\fR caches
information about the return value in \fIobjPtr\fR, which speeds up
future calls to \fBTk_Alloc3DBorderFromObj\fR with the same \fIobjPtr\fR
and \fItkwin\fR.
.PP
\fBTk_ClipDrawableToRect\fR will clip all drawing into the drawable \fId\fR
to the given rectangle. If \fIwidth\fR or \fIheight\fR are negative, reset
to no clipping.
Subsequent drawing into \fId\fR is offset and clipped as specified.
The function is only used when \fBTK_NO_DOUBLE_BUFFERING\fR is specified at
compile time.
.PP
\fBTk_DrawHighlightBorder\fR draws a rectangular ring around the outside of
a widget to indicate that it has received the input focus.
On the Macintosh, this puts a 1 pixel border in the bgGC color between
the widget and the focus ring, except in the case where highlightWidth
is 1, in which case the border is left out.
For proper Mac L&F, use highlightWidth of 3.
.PP
\fBTk_Get3DBorder\fR is identical to \fBTk_Alloc3DBorderFromObj\fR except
that the color is specified with a string instead of a value.  This
prevents \fBTk_Get3DBorder\fR from caching the return value, so
\fBTk_Get3DBorder\fR is less efficient than \fBTk_Alloc3DBorderFromObj\fR.
.PP
\fBTk_Get3DBorderColors\fR returns the used colors of the given border.
.PP
\fBTk_Get3DBorderFromObj\fR returns the token for an existing border, given
the window and color name used to create the border.
\fBTk_Get3DBorderFromObj\fR does not actually create the border; it must
already have been created with a previous call to
\fBTk_Alloc3DBorderFromObj\fR or \fBTk_Get3DBorder\fR.  The return
value is cached in \fIobjPtr\fR, which speeds up
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
\fIwidth\fR and \fIheight\fR are the dimensions of the window), and
\fIborderWidth\fR specifies the number of pixels actually
occupied by the border.  The \fIrelief\fR argument indicates
which of several three-dimensional effects is desired:
\fBTK_RELIEF_RAISED\fR means that the interior of the rectangle should
appear raised relative to the exterior of the rectangle, and
\fBTK_RELIEF_SUNKEN\fR means that the interior should appear depressed.
\fBTK_RELIEF_GROOVE\fR and \fBTK_RELIEF_RIDGE\fR mean that there should appear to be
a groove or ridge around the exterior of the rectangle.
.PP
\fBTk_Fill3DRectangle\fR is somewhat like \fBTk_Draw3DRectangle\fR except
that it first fills the rectangular area with the background color
(one corresponding
to the color used to create \fIborder\fR).  Then it calls
\fBTk_Draw3DRectangle\fR to draw a border just inside the outer edge of
the rectangular area.  The argument \fIrelief\fR indicates the desired







|
|







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

with the window and color name used to create the
border; for \fBTk_Free3DBorder\fR the border to release is specified
with the Tk_3DBorder token for the border.
There should be exactly one call to \fBTk_Free3DBorderFromObj\fR or
\fBTk_Free3DBorder\fR for each call to \fBTk_Alloc3DBorderFromObj\fR
or \fBTk_Get3DBorder\fR.
.SH KEYWORDS
3D, background, border, color, depressed, illumination, value, polygon, raised, shadow, three-dimensional effect








|
>
318
319
320
321
322
323
324
325
326
with the window and color name used to create the
border; for \fBTk_Free3DBorder\fR the border to release is specified
with the Tk_3DBorder token for the border.
There should be exactly one call to \fBTk_Free3DBorderFromObj\fR or
\fBTk_Free3DBorder\fR for each call to \fBTk_Alloc3DBorderFromObj\fR
or \fBTk_Get3DBorder\fR.
.SH KEYWORDS
3D, background, border, color, depressed, illumination, value, polygon,
raised, shadow, three-dimensional effect

Changes to doc/AddOption.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
'\"
'\" Copyright (c) 1998-2000 by 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
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
void
\fBTk_AddOption\fR(\fItkwin, name, value, priority\fR)




.SH ARGUMENTS
.AP Tk_Window tkwin in
Token for window.
.AP "const char" *name in
Multi-element name of option.
.AP "const char" *value in
Value of option.




.AP int priority in
Overall priority level to use for option.
.BE
.SH DESCRIPTION
.PP
This procedure is invoked to add an option to the database
associated with \fItkwin\fR's main window.  \fIName\fR
contains the option being specified and consists of names and/or
classes separated by asterisks or dots, in the usual X format.
\fIValue\fR contains the text string to associate with \fIname\fR;
this value will be returned in calls to \fBTk_GetOption\fR.
\fIPriority\fR specifies the priority of the value; when options are
queried using \fBTk_GetOption\fR, the value with the highest priority
is returned.  \fIPriority\fR must be between 0 and \fBTK_MAX_PRIO\fR.  Some
common priority values are:
.IP 20
Used for default values hard-coded into widgets.
.IP 40
Used for options specified in application-specific startup files.
.IP 60
Used for options specified in user-specific defaults files, such as
\fB.Xdefaults\fR, resource databases loaded into the X server, or
user-specific startup files.
.IP 80
Used for options specified interactively after the application starts
running.




.SH KEYWORDS
class, name, option, add

|













>
>
>
>







>
>
>
>





|







|
|
|

|

|



|


>
>
>
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
'\"
'\" 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
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
void
\fBTk_AddOption\fR(\fItkwin, name, value, priority\fR)
.sp
Tcl_Obj *
\fBTk_GetSystemDefault\fR(\fItkwin, dbName, className\fR)
.fi
.SH ARGUMENTS
.AP Tk_Window tkwin in
Token for window.
.AP "const char" *name in
Multi-element name of option.
.AP "const char" *value in
Value of option.
.AP "const char" *dbName in
The option database name.
.AP "const char" *className in
The name of the option class.
.AP int priority in
Overall priority level to use for option.
.BE
.SH DESCRIPTION
.PP
\fBTk_AddOption\fR is invoked to add an option to the database
associated with \fItkwin\fR's main window.  \fIName\fR
contains the option being specified and consists of names and/or
classes separated by asterisks or dots, in the usual X format.
\fIValue\fR contains the text string to associate with \fIname\fR;
this value will be returned in calls to \fBTk_GetOption\fR.
\fIPriority\fR specifies the priority of the value; when options are
queried using \fBTk_GetOption\fR, the value with the highest priority
is returned.  \fIPriority\fR must be between 0 and \fBTK_MAX_PRIO\fR (100).
Some common priority values are:
.IP \fBTK_WIDGET_DEFAULT_PRIO\fR (20)
Used for default values hard-coded into widgets.
.IP \fBTK_STARTUP_FILE_PRIO\fR (40)
Used for options specified in application-specific startup files.
.IP \fBTK_USER_DEFAULT_PRIO\fR (60)
Used for options specified in user-specific defaults files, such as
\fB.Xdefaults\fR, resource databases loaded into the X server, or
user-specific startup files.
.IP \fBTK_INTERACTIVE_PRIO\fR (80)
Used for options specified interactively after the application starts
running.
.PP
\fBTk_GetSystemDefault\fR returns a Tcl_Obj* with the string identifying
a configuration option matching the given \fIdbname\fR and \fIclassName\fR.
Returns NULL if there are no system defaults that match this pair.
.SH KEYWORDS
class, name, option, add

Changes to doc/BindTable.3.

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

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.SH NAME
Tk_CreateBindingTable, Tk_DeleteBindingTable, Tk_CreateBinding, Tk_DeleteBinding, Tk_GetBinding, Tk_GetAllBindings, Tk_DeleteAllBindings, Tk_BindEvent \- invoke scripts in response to X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_BindingTable
\fBTk_CreateBindingTable(\fIinterp\fB)\fR
.sp
\fBTk_DeleteBindingTable(\fIbindingTable\fB)\fR
.sp
unsigned long
\fBTk_CreateBinding(\fIinterp, bindingTable, object, eventString, script, append\fB)\fR
.sp
int
\fBTk_DeleteBinding(\fIinterp, bindingTable, object, eventString\fB)\fR
.sp
const char *
\fBTk_GetBinding(\fIinterp, bindingTable, object, eventString\fB)\fR
.sp
\fBTk_GetAllBindings(\fIinterp, bindingTable, object\fB)\fR
.sp
\fBTk_DeleteAllBindings(\fIbindingTable, object\fB)\fR
.sp
\fBTk_BindEvent(\fIbindingTable, eventPtr, tkwin, numObjects, objectPtr\fB)\fR

.SH ARGUMENTS
.AS Tk_BindingTable bindingTable
.AP Tcl_Interp *interp in
Interpreter to use when invoking bindings in binding table.  Also
used for returning results and errors from binding procedures.
.AP Tk_BindingTable bindingTable in
Token for binding table;  must have been returned by some previous
call to \fBTk_CreateBindingTable\fR.
.AP ClientData object in
Identifies object with which binding is associated.
.AP "const char" *eventString in
String describing event sequence.
.AP "const char" *script in
Tcl script to invoke when binding triggers.
.AP int append in
Non-zero means append \fIscript\fR to existing script for binding,
if any; zero means replace existing script with new one.
.AP XEvent *eventPtr in
X event to match against bindings in \fIbindingTable\fR.
.AP Tk_Window tkwin in
Identifier for any window on the display where the event occurred.
Used to find display-related information such as key maps.
.AP int numObjects in
Number of object identifiers pointed to by \fIobjectPtr\fR.
.AP ClientData *objectPtr in
Points to an array of object identifiers:  bindings will be considered
for each of these objects in order from first to last.
.BE
.SH DESCRIPTION
.PP
These procedures provide a general-purpose mechanism for creating
and invoking bindings.







|

|


|


|


|

|

|

|
>








|













|

|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
.SH NAME
Tk_CreateBindingTable, Tk_DeleteBindingTable, Tk_CreateBinding, Tk_DeleteBinding, Tk_GetBinding, Tk_GetAllBindings, Tk_DeleteAllBindings, Tk_BindEvent \- invoke scripts in response to X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_BindingTable
\fBTk_CreateBindingTable\fR(\fIinterp\fR)
.sp
\fBTk_DeleteBindingTable\fR(\fIbindingTable\fR)
.sp
unsigned long
\fBTk_CreateBinding\fR(\fIinterp, bindingTable, object, eventString, script, append\fR)
.sp
int
\fBTk_DeleteBinding\fR(\fIinterp, bindingTable, object, eventString\fR)
.sp
const char *
\fBTk_GetBinding\fR(\fIinterp, bindingTable, object, eventString\fR)
.sp
\fBTk_GetAllBindings\fR(\fIinterp, bindingTable, object\fR)
.sp
\fBTk_DeleteAllBindings\fR(\fIbindingTable, object\fR)
.sp
\fBTk_BindEvent\fR(\fIbindingTable, eventPtr, tkwin, numObjects, objectPtr\fR)
.fi
.SH ARGUMENTS
.AS Tk_BindingTable bindingTable
.AP Tcl_Interp *interp in
Interpreter to use when invoking bindings in binding table.  Also
used for returning results and errors from binding procedures.
.AP Tk_BindingTable bindingTable in
Token for binding table;  must have been returned by some previous
call to \fBTk_CreateBindingTable\fR.
.AP "void *" object in
Identifies object with which binding is associated.
.AP "const char" *eventString in
String describing event sequence.
.AP "const char" *script in
Tcl script to invoke when binding triggers.
.AP int append in
Non-zero means append \fIscript\fR to existing script for binding,
if any; zero means replace existing script with new one.
.AP XEvent *eventPtr in
X event to match against bindings in \fIbindingTable\fR.
.AP Tk_Window tkwin in
Identifier for any window on the display where the event occurred.
Used to find display-related information such as key maps.
.AP Tcl_Size numObjects in
Number of object identifiers pointed to by \fIobjectPtr\fR.
.AP "void **" objectPtr in
Points to an array of object identifiers:  bindings will be considered
for each of these objects in order from first to last.
.BE
.SH DESCRIPTION
.PP
These procedures provide a general-purpose mechanism for creating
and invoking bindings.

Changes to doc/CanvPsY.3.

25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
int
\fBTk_CanvasPsFont\fR(\fIinterp, canvas, tkFont\fR)
.sp
\fBTk_CanvasPsPath\fR(\fIinterp, canvas, coordPtr, numPoints\fR)
.sp
int
\fBTk_CanvasPsStipple\fR(\fIinterp, canvas, bitmap\fR)

.SH ARGUMENTS
.AS "unsigned int" "numPoints"
.AP Tk_Canvas canvas in
A token that identifies a canvas widget for which Postscript is
being generated.
.AP double canvasY in
Y-coordinate in the space of the canvas.
.AP Tcl_Interp *interp in/out
A Tcl interpreter;  Postscript is appended to its result, or the







>

|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int
\fBTk_CanvasPsFont\fR(\fIinterp, canvas, tkFont\fR)
.sp
\fBTk_CanvasPsPath\fR(\fIinterp, canvas, coordPtr, numPoints\fR)
.sp
int
\fBTk_CanvasPsStipple\fR(\fIinterp, canvas, bitmap\fR)
.fi
.SH ARGUMENTS
.AS Tcl_Size "numPoints"
.AP Tk_Canvas canvas in
A token that identifies a canvas widget for which Postscript is
being generated.
.AP double canvasY in
Y-coordinate in the space of the canvas.
.AP Tcl_Interp *interp in/out
A Tcl interpreter;  Postscript is appended to its result, or the
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
.AP Tk_Font tkFont in
Font for which Postscript is to be generated.
.AP double *coordPtr in
Pointer to an array of coordinates for one or more
points specified in canvas coordinates.
The order of values in \fIcoordPtr\fR is x1, y1, x2, y2, x3, y3,
and so on.
.AP int numPoints in
Number of points at \fIcoordPtr\fR.
.BE
.SH DESCRIPTION
.PP
These procedures are called by canvas type managers to carry out
common functions related to generating Postscript.
Most of the procedures take a \fIcanvas\fR argument, which







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
.AP Tk_Font tkFont in
Font for which Postscript is to be generated.
.AP double *coordPtr in
Pointer to an array of coordinates for one or more
points specified in canvas coordinates.
The order of values in \fIcoordPtr\fR is x1, y1, x2, y2, x3, y3,
and so on.
.AP Tcl_Size numPoints in
Number of points at \fIcoordPtr\fR.
.BE
.SH DESCRIPTION
.PP
These procedures are called by canvas type managers to carry out
common functions related to generating Postscript.
Most of the procedures take a \fIcanvas\fR argument, which

Changes to doc/CanvTkwin.3.

26
27
28
29
30
31
32

33
34
35
36
37
38
39
\fBTk_CanvasWindowCoords\fR(\fIcanvas, x, y, screenXPtr, screenYPtr\fR)
.sp
\fBTk_CanvasEventuallyRedraw\fR(\fIcanvas, x1, y1, x2, y2\fR)
.sp
Tk_OptionParseProc *\fBTk_CanvasTagsParseProc\fR;
.sp
Tk_OptionPrintProc *\fBTk_CanvasTagsPrintProc\fR;

.SH ARGUMENTS
.AS Tk_ItemType *drawableXPtr
.AP Tk_Canvas canvas in
A token that identifies a canvas widget.
.AP Tcl_Interp *interp in/out
Interpreter to use for error reporting.
.AP "const char" *string in







>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
\fBTk_CanvasWindowCoords\fR(\fIcanvas, x, y, screenXPtr, screenYPtr\fR)
.sp
\fBTk_CanvasEventuallyRedraw\fR(\fIcanvas, x1, y1, x2, y2\fR)
.sp
Tk_OptionParseProc *\fBTk_CanvasTagsParseProc\fR;
.sp
Tk_OptionPrintProc *\fBTk_CanvasTagsPrintProc\fR;
.fi
.SH ARGUMENTS
.AS Tk_ItemType *drawableXPtr
.AP Tk_Canvas canvas in
A token that identifies a canvas widget.
.AP Tcl_Interp *interp in/out
Interpreter to use for error reporting.
.AP "const char" *string in
145
146
147
148
149
150
151
152
153
154
155
156
157
158
.CS
static const Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    ...
    {TK_CONFIG_CUSTOM, "\-tags", NULL, NULL,
        NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    ...
};
.CE
.SH KEYWORDS
canvas, focus, item type, redisplay, selection, type manager







|






146
147
148
149
150
151
152
153
154
155
156
157
158
159
.CS
static const Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
    Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    ...
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
        NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    ...
};
.CE
.SH KEYWORDS
canvas, focus, item type, redisplay, selection, type manager

Changes to doc/CanvTxtInfo.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Tk_CanvasTextInfo \- additional information for managing text items in canvases
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_CanvasTextInfo *
\fBTk_CanvasGetTextInfo\fR(\fIcanvas\fR)

.SH ARGUMENTS
.AS Tk_Canvas canvas
.AP Tk_Canvas canvas in
A token that identifies a particular canvas widget.
.BE
.SH DESCRIPTION
.PP
Textual canvas items are somewhat more complicated to manage than
other items, due to things like the selection and the input focus.
\fBTk_CanvasGetTextInfo\fR may be invoked by a type manager
to obtain additional information needed for items that display text.
The return value from \fBTk_CanvasGetTextInfo\fR is a pointer to
a structure that is shared between Tk and all the items that display
text.
The structure has the following form:
.CS
typedef struct Tk_CanvasTextInfo {
    Tk_3DBorder \fIselBorder\fR;
    int \fIselBorderWidth\fR;
    XColor *\fIselFgColorPtr\fR;
    Tk_Item *\fIselItemPtr\fR;
    int \fIselectFirst\fR;
    int \fIselectLast\fR;
    Tk_Item *\fIanchorItemPtr\fR;







>
















|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Tk_CanvasTextInfo \- additional information for managing text items in canvases
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_CanvasTextInfo *
\fBTk_CanvasGetTextInfo\fR(\fIcanvas\fR)
.fi
.SH ARGUMENTS
.AS Tk_Canvas canvas
.AP Tk_Canvas canvas in
A token that identifies a particular canvas widget.
.BE
.SH DESCRIPTION
.PP
Textual canvas items are somewhat more complicated to manage than
other items, due to things like the selection and the input focus.
\fBTk_CanvasGetTextInfo\fR may be invoked by a type manager
to obtain additional information needed for items that display text.
The return value from \fBTk_CanvasGetTextInfo\fR is a pointer to
a structure that is shared between Tk and all the items that display
text.
The structure has the following form:
.CS
typedef struct {
    Tk_3DBorder \fIselBorder\fR;
    int \fIselBorderWidth\fR;
    XColor *\fIselFgColorPtr\fR;
    Tk_Item *\fIselItemPtr\fR;
    int \fIselectFirst\fR;
    int \fIselectLast\fR;
    Tk_Item *\fIanchorItemPtr\fR;

Changes to doc/Clipboard.3.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
\fB#include <tk.h>\fR
.sp
int
\fBTk_ClipboardClear\fR(\fIinterp, tkwin\fR)
.sp
int
\fBTk_ClipboardAppend\fR(\fIinterp, tkwin, target, format, buffer\fR)

.SH ARGUMENTS
.AS Tk_ClipboardClear tkwin
.AP Tcl_Interp *interp in
Interpreter to use for reporting errors.
.AP Tk_Window tkwin in
Window that determines which display's clipboard to manipulate.
.AP Atom target in







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
\fB#include <tk.h>\fR
.sp
int
\fBTk_ClipboardClear\fR(\fIinterp, tkwin\fR)
.sp
int
\fBTk_ClipboardAppend\fR(\fIinterp, tkwin, target, format, buffer\fR)
.fi
.SH ARGUMENTS
.AS Tk_ClipboardClear tkwin
.AP Tcl_Interp *interp in
Interpreter to use for reporting errors.
.AP Tk_Window tkwin in
Window that determines which display's clipboard to manipulate.
.AP Atom target in

Changes to doc/ClrSelect.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
.SH NAME
Tk_ClearSelection \- Deselect a selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ClearSelection\fR(\fItkwin, selection\fR)

.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
The selection will be cleared from the display containing this
window.
.AP Atom selection in
The name of selection to be cleared.







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.SH NAME
Tk_ClearSelection \- Deselect a selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ClearSelection\fR(\fItkwin, selection\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
The selection will be cleared from the display containing this
window.
.AP Atom selection in
The name of selection to be cleared.

Changes to doc/ConfigWidg.3.

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

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.SH NAME
Tk_ConfigureWidget, Tk_ConfigureInfo, Tk_ConfigureValue, Tk_FreeOptions \- process configuration options for widgets
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ConfigureWidget(\fIinterp, tkwin, specs, argc, argv, widgRec, flags\fB)\fR
.sp
int
\fBTk_ConfigureInfo(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
.sp
int
\fBTk_ConfigureValue(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
.sp
\fBTk_FreeOptions(\fIspecs, widgRec, display, flags\fB)\fR

.SH ARGUMENTS
.AS char *widgRec in/out
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window used to represent widget (needed to set up X resources).
.AP "const Tk_ConfigSpec" *specs in
Pointer to table specifying legal configuration options for this
widget.
.AP int argc in
Number of arguments in \fIargv\fR.
.AP "const char" **argv in
Command-line options for configuring widget.
.AP char *widgRec in/out
Points to widget record structure.  Fields in this structure get
modified by \fBTk_ConfigureWidget\fR to hold configuration information.
.AP int flags in
If non-zero, then it specifies an OR-ed combination of flags that
control the processing of configuration information.







|


|


|

|
>

|







|
|
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.SH NAME
Tk_ConfigureWidget, Tk_ConfigureInfo, Tk_ConfigureValue, Tk_FreeOptions \- process configuration options for widgets
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ConfigureWidget\fR(\fIinterp, tkwin, specs, objc, objv, widgRec, flags\fR)
.sp
int
\fBTk_ConfigureInfo\fR(\fIinterp, tkwin, specs, widgRec, argvName, flags\fR)
.sp
int
\fBTk_ConfigureValue\fR(\fIinterp, tkwin, specs, widgRec, argvName, flags\fR)
.sp
\fBTk_FreeOptions\fR(\fIspecs, widgRec, display, flags\fR)
.fi
.SH ARGUMENTS
.AS void *widgRec in/out
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window used to represent widget (needed to set up X resources).
.AP "const Tk_ConfigSpec" *specs in
Pointer to table specifying legal configuration options for this
widget.
.AP Tcl_Size objc in
Number of arguments in \fIobjv\fR.
.AP "Tcl_Obj *const *" objv in
Command-line options for configuring widget.
.AP char *widgRec in/out
Points to widget record structure.  Fields in this structure get
modified by \fBTk_ConfigureWidget\fR to hold configuration information.
.AP int flags in
If non-zero, then it specifies an OR-ed combination of flags that
control the processing of configuration information.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
options.
.AP Display *display in
Display containing widget whose record is being freed;  needed in
order to free up resources.
.BE
.SH DESCRIPTION
.PP
Note: \fBTk_ConfigureWidget\fR should be replaced with the new
\fBTcl_Obj\fR based API \fBTk_SetOptions\fR.  The old interface is
retained for backward compatibility.
.PP
\fBTk_ConfigureWidget\fR is called to configure various aspects of a
widget, such as colors, fonts, border width, etc.
It is intended as a convenience procedure to reduce the amount
of code that must be written in individual widget managers to
handle configuration information.
It is typically
invoked when widgets are created, and again when the \fBconfigure\fR
command is invoked for a widget.
Although intended primarily for widgets, \fBTk_ConfigureWidget\fR
can be used in other situations where \fIargc-argv\fR information
is to be used to fill in a record structure, such as configuring
graphical elements for a canvas widget or entries of a menu.
.PP
\fBTk_ConfigureWidget\fR processes
a table specifying the configuration options that are supported
(\fIspecs\fR) and a collection of command-line arguments (\fIargc\fR and
\fIargv\fR) to fill in fields of a record (\fIwidgRec\fR).
It uses the option database and defaults specified in \fIspecs\fR
to fill in fields of \fIwidgRec\fR that are not specified in \fIargv\fR.
\fBTk_ConfigureWidget\fR normally returns the value \fBTCL_OK\fR; in this
case it does not modify \fIinterp\fR.
If an error
occurs then \fBTCL_ERROR\fR is returned and \fBTk_ConfigureWidget\fR will
leave an error message in interpreter \fIinterp\fR's result in the standard Tcl
fashion.
In the event of an error return, some of the fields of \fIwidgRec\fR







|
|











|





|
|

|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
options.
.AP Display *display in
Display containing widget whose record is being freed;  needed in
order to free up resources.
.BE
.SH DESCRIPTION
.PP
Note that \fBTk_ConfigureWidget\fR should be replaced with the new
\fBTcl_Obj\fR based API, \fBTk_SetOptions\fR.  The old interface is
retained for backward compatibility.
.PP
\fBTk_ConfigureWidget\fR is called to configure various aspects of a
widget, such as colors, fonts, border width, etc.
It is intended as a convenience procedure to reduce the amount
of code that must be written in individual widget managers to
handle configuration information.
It is typically
invoked when widgets are created, and again when the \fBconfigure\fR
command is invoked for a widget.
Although intended primarily for widgets, \fBTk_ConfigureWidget\fR
can be used in other situations where \fIobjc-objv\fR information
is to be used to fill in a record structure, such as configuring
graphical elements for a canvas widget or entries of a menu.
.PP
\fBTk_ConfigureWidget\fR processes
a table specifying the configuration options that are supported
(\fIspecs\fR) and a collection of command-line arguments (\fIobjc\fR and
\fIobjv\fR) to fill in fields of a record (\fIwidgRec\fR).
It uses the option database and defaults specified in \fIspecs\fR
to fill in fields of \fIwidgRec\fR that are not specified in \fIobjv\fR.
\fBTk_ConfigureWidget\fR normally returns the value \fBTCL_OK\fR; in this
case it does not modify \fIinterp\fR.
If an error
occurs then \fBTCL_ERROR\fR is returned and \fBTk_ConfigureWidget\fR will
leave an error message in interpreter \fIinterp\fR's result in the standard Tcl
fashion.
In the event of an error return, some of the fields of \fIwidgRec\fR
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
(e.g. \fBTK_CONFIG_COLOR\fR for a color value, or \fBTK_CONFIG_INT\fR for
an integer value).  The \fItype\fR field indicates how to use the
value of the option (more on this below).
The \fIargvName\fR field is a string such as
.QW \-font
or
.QW \-bg ,
which is compared with the values in \fIargv\fR (if \fIargvName\fR is
NULL it means this is a grouped entry;  see \fBGROUPED ENTRIES\fR below).  The
\fIdbName\fR and \fIdbClass\fR fields are used to look up a value
for this option in the option database.  The \fIdefValue\fR field
specifies a default value for this configuration option if no
value is specified in either \fIargv\fR or the option database.
\fIOffset\fR indicates where in \fIwidgRec\fR to store information
about this option, and \fIspecFlags\fR contains additional information
to control the processing of this configuration option (see FLAGS
below).
The last field, \fIcustomPtr\fR, is only used if \fItype\fR is
\fBTK_CONFIG_CUSTOM\fR;  see CUSTOM OPTION TYPES below.
.PP
\fBTk_ConfigureWidget\fR first processes \fIargv\fR to see which
(if any) configuration options are specified there.  \fIArgv\fR
must contain an even number of fields;  the first of each pair
of fields must match the \fIargvName\fR of some entry in \fIspecs\fR
(unique abbreviations are acceptable),
and the second field of the pair contains the value for that
configuration option.  If there are entries in \fIspec\fR for which
there were no matching entries in \fIargv\fR,
\fBTk_ConfigureWidget\fR uses the \fIdbName\fR and \fIdbClass\fR
fields of the \fIspecs\fR entry to probe the option database;  if
a value is found, then it is used as the value for the option.
Finally, if no entry is found in the option database, the
\fIdefValue\fR field of the \fIspecs\fR entry is used as the
value for the configuration option.  If the \fIdefValue\fR is
NULL, or if the \fBTK_CONFIG_DONT_SET_DEFAULT\fR bit is set in
\fIflags\fR, then there is no default value and this \fIspecs\fR entry
will be ignored if no value is specified in \fIargv\fR or the
option database.
.PP
Once a string value has been determined for a configuration option,
\fBTk_ConfigureWidget\fR translates the string value into a more useful
form, such as a color if \fItype\fR is \fBTK_CONFIG_COLOR\fR or an integer
if \fItype\fR is \fBTK_CONFIG_INT\fR.  This value is then stored in the
record pointed to by \fIwidgRec\fR.  This record is assumed to







|




|







|






|








|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
(e.g. \fBTK_CONFIG_COLOR\fR for a color value, or \fBTK_CONFIG_INT\fR for
an integer value).  The \fItype\fR field indicates how to use the
value of the option (more on this below).
The \fIargvName\fR field is a string such as
.QW \-font
or
.QW \-bg ,
which is compared with the values in \fIobjv\fR (if \fIargvName\fR is
NULL it means this is a grouped entry;  see \fBGROUPED ENTRIES\fR below).  The
\fIdbName\fR and \fIdbClass\fR fields are used to look up a value
for this option in the option database.  The \fIdefValue\fR field
specifies a default value for this configuration option if no
value is specified in either \fIobjv\fR or the option database.
\fIOffset\fR indicates where in \fIwidgRec\fR to store information
about this option, and \fIspecFlags\fR contains additional information
to control the processing of this configuration option (see FLAGS
below).
The last field, \fIcustomPtr\fR, is only used if \fItype\fR is
\fBTK_CONFIG_CUSTOM\fR;  see CUSTOM OPTION TYPES below.
.PP
\fBTk_ConfigureWidget\fR first processes \fIobjv\fR to see which
(if any) configuration options are specified there.  \fIArgv\fR
must contain an even number of fields;  the first of each pair
of fields must match the \fIargvName\fR of some entry in \fIspecs\fR
(unique abbreviations are acceptable),
and the second field of the pair contains the value for that
configuration option.  If there are entries in \fIspec\fR for which
there were no matching entries in \fIobjv\fR,
\fBTk_ConfigureWidget\fR uses the \fIdbName\fR and \fIdbClass\fR
fields of the \fIspecs\fR entry to probe the option database;  if
a value is found, then it is used as the value for the option.
Finally, if no entry is found in the option database, the
\fIdefValue\fR field of the \fIspecs\fR entry is used as the
value for the configuration option.  If the \fIdefValue\fR is
NULL, or if the \fBTK_CONFIG_DONT_SET_DEFAULT\fR bit is set in
\fIflags\fR, then there is no default value and this \fIspecs\fR entry
will be ignored if no value is specified in \fIobjv\fR or the
option database.
.PP
Once a string value has been determined for a configuration option,
\fBTk_ConfigureWidget\fR translates the string value into a more useful
form, such as a color if \fItype\fR is \fBTK_CONFIG_COLOR\fR or an integer
if \fItype\fR is \fBTK_CONFIG_INT\fR.  This value is then stored in the
record pointed to by \fIwidgRec\fR.  This record is assumed to
167
168
169
170
171
172
173

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

188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203

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

223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250

251
252
253
254

255
256
257
258
259
260

261
262
263
264
265
266

267
268
269
270
271

272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299

300
301
302
303
304
305
306

307
308
309
310
311
312

313
314
315
316
317
318

319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334

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

349
350
351
352
353
354
355

356
357
358
359
360
361
362
in the descriptions below.
.PP
The \fItype\fR field of each entry in \fIspecs\fR determines what
to do with the string value of that configuration option.  The
legal values for \fItype\fR, and the corresponding actions, are:
.TP
\fBTK_CONFIG_ACTIVE_CURSOR\fR

The value
must be an ASCII string identifying a cursor in a form
suitable for passing to \fBTk_GetCursor\fR.
The value is converted to a \fBTk_Cursor\fR by calling
\fBTk_GetCursor\fR and the result is stored in the target.
In addition, the resulting cursor is made the active cursor
for \fItkwin\fR by calling \fBXDefineCursor\fR.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target and \fItkwin\fR's
active cursor will be set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeCursor\fR.
.TP
\fBTK_CONFIG_ANCHOR\fR

The value must be an ASCII string identifying an anchor point in one of the ways
accepted by \fBTk_GetAnchor\fR.
The string is converted to a \fBTk_Anchor\fR by calling
\fBTk_GetAnchor\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_BITMAP\fR

The value must be an ASCII string identifying a bitmap in a form
suitable for passing to \fBTk_GetBitmap\fR.  The value is converted
to a \fBPixmap\fR by calling \fBTk_GetBitmap\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target is set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeBitmap\fR.
.TP
\fBTK_CONFIG_BOOLEAN\fR

The value must be an ASCII string specifying a boolean value.  Any
of the values
.QW true ,
.QW yes ,
.QW on ,
or
.QW 1 ,
or an abbreviation of one of these values, means true;
any of the values
.QW false ,
.QW no ,
.QW off ,
or
.QW 0 ,
or an abbreviation of one of these values, means false.
The target is expected to be an integer;  for true values it will
be set to 1 and for false values it will be set to 0.
.TP
\fBTK_CONFIG_BORDER\fR

The value must be an ASCII string identifying a border color in a form
suitable for passing to \fBTk_Get3DBorder\fR.  The value is converted
to a (\fBTk_3DBorder *\fR) by calling \fBTk_Get3DBorder\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_Free3DBorder\fR.
.TP
\fBTK_CONFIG_CAP_STYLE\fR

The value must be
an ASCII string identifying a cap style in one of the ways
accepted by \fBTk_GetCapStyle\fR.
The string is converted to an integer value corresponding
to the cap style by calling
\fBTk_GetCapStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_COLOR\fR

The value must be an ASCII string identifying a color in a form
suitable for passing to \fBTk_GetColor\fR.  The value is converted
to an (\fBXColor *\fR) by calling \fBTk_GetColor\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to \fBNone\fR.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeColor\fR.
.TP
\fBTK_CONFIG_CURSOR\fR

This option is identical to \fBTK_CONFIG_ACTIVE_CURSOR\fR except
that the new cursor is not made the active one for \fItkwin\fR.
.TP
\fBTK_CONFIG_CUSTOM\fR

This option allows applications to define new option types.
The \fIcustomPtr\fR field of the entry points to a structure
defining the new option type.
See the section \fBCUSTOM OPTION TYPES\fR below for details.
.TP
\fBTK_CONFIG_DOUBLE\fR

The value must be an ASCII floating-point number in
the format accepted by \fBstrtol\fR.  The string is converted
to a \fBdouble\fR value, and the value is stored in the
target.
.TP
\fBTK_CONFIG_END\fR

Marks the end of the table.  The last entry in \fIspecs\fR
must have this type;  all of its other fields are ignored and it
will never match any arguments.
.TP
\fBTK_CONFIG_FONT\fR

The value must be an ASCII string identifying a font in a form
suitable for passing to \fBTk_GetFont\fR.  The value is converted
to a \fBTk_Font\fR by calling \fBTk_GetFont\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeFont\fR.
.TP
\fBTK_CONFIG_INT\fR

The value must be an ASCII integer string
in the format accepted by \fBstrtol\fR (e.g.
.QW 0
and
.QW 0x
prefixes may be used to specify octal or hexadecimal
numbers, respectively).  The string is converted to an integer
value and the integer is stored in the target.
.TP
\fBTK_CONFIG_JOIN_STYLE\fR

The value must be
an ASCII string identifying a join style in one of the ways
accepted by \fBTk_GetJoinStyle\fR.
The string is converted to an integer value corresponding
to the join style by calling
\fBTk_GetJoinStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_JUSTIFY\fR

The value must be
an ASCII string identifying a justification method in one of the
ways accepted by \fBTk_GetJustify\fR.
The string is converted to a \fBTk_Justify\fR by calling
\fBTk_GetJustify\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_MM\fR

The value must specify a screen distance in one of the forms acceptable
to \fBTk_GetScreenMM\fR.
The string is converted to double-precision floating-point distance
in millimeters and the value is stored in the target.
.TP
\fBTK_CONFIG_PIXELS\fR

The value must specify screen units in one of the forms acceptable
to \fBTk_GetPixels\fR.
The string is converted to an integer distance in pixels and the
value is stored in the target.
.TP
\fBTK_CONFIG_RELIEF\fR

The value must be an ASCII string identifying a relief in a form
suitable for passing to \fBTk_GetRelief\fR.  The value is converted
to an integer relief value by calling \fBTk_GetRelief\fR and the result
is stored in the target.
.TP
\fBTK_CONFIG_STRING\fR
A copy

of the value is made by allocating memory space with
\fBTcl_Alloc\fR and copying the value into the dynamically-allocated
space.  A pointer to the new string is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target was not NULL, then it is
freed by passing it to \fBTcl_Free\fR.
.TP
\fBTK_CONFIG_SYNONYM\fR

This \fItype\fR value identifies special entries in \fIspecs\fR that
are synonyms for other entries.  If an \fIargv\fR value matches the
\fIargvName\fR of a \fBTK_CONFIG_SYNONYM\fR entry, the entry is not used
directly. Instead, \fBTk_ConfigureWidget\fR searches \fIspecs\fR
for another entry whose \fIargvName\fR is the same as the \fIdbName\fR
field in the \fBTK_CONFIG_SYNONYM\fR entry;  this new entry is used just
as if its \fIargvName\fR had matched the \fIargv\fR value.  The
synonym mechanism allows multiple \fIargv\fR values to be used for
a single configuration option, such as
.QW \-background
and
.QW \-bg .
.TP
\fBTK_CONFIG_UID\fR

The value is translated to a \fBTk_Uid\fR
(by passing it to \fBTk_GetUid\fR).  The resulting value
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR and the value
is an empty string then the target will be set to NULL.
.TP
\fBTK_CONFIG_WINDOW\fR

The value must be a window path name.  It is translated to a
\fBTk_Window\fR token and the token is stored in the target.
.SH "GROUPED ENTRIES"
.PP
In some cases it is useful to generate multiple resources from
a single configuration value.  For example, a color name might
be used both to generate the background color for a widget (using







>














>






>










>



















>










>








>










>




>






>






>





>










>










>








>







>






>






>






<
>
|








>

|




|
|






>







>







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

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
in the descriptions below.
.PP
The \fItype\fR field of each entry in \fIspecs\fR determines what
to do with the string value of that configuration option.  The
legal values for \fItype\fR, and the corresponding actions, are:
.TP
\fBTK_CONFIG_ACTIVE_CURSOR\fR
.
The value
must be an ASCII string identifying a cursor in a form
suitable for passing to \fBTk_GetCursor\fR.
The value is converted to a \fBTk_Cursor\fR by calling
\fBTk_GetCursor\fR and the result is stored in the target.
In addition, the resulting cursor is made the active cursor
for \fItkwin\fR by calling \fBXDefineCursor\fR.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target and \fItkwin\fR's
active cursor will be set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeCursor\fR.
.TP
\fBTK_CONFIG_ANCHOR\fR
.
The value must be an ASCII string identifying an anchor point in one of the ways
accepted by \fBTk_GetAnchor\fR.
The string is converted to a \fBTk_Anchor\fR by calling
\fBTk_GetAnchor\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_BITMAP\fR
.
The value must be an ASCII string identifying a bitmap in a form
suitable for passing to \fBTk_GetBitmap\fR.  The value is converted
to a \fBPixmap\fR by calling \fBTk_GetBitmap\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target is set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeBitmap\fR.
.TP
\fBTK_CONFIG_BOOLEAN\fR
.
The value must be an ASCII string specifying a boolean value.  Any
of the values
.QW true ,
.QW yes ,
.QW on ,
or
.QW 1 ,
or an abbreviation of one of these values, means true;
any of the values
.QW false ,
.QW no ,
.QW off ,
or
.QW 0 ,
or an abbreviation of one of these values, means false.
The target is expected to be an integer;  for true values it will
be set to 1 and for false values it will be set to 0.
.TP
\fBTK_CONFIG_BORDER\fR
.
The value must be an ASCII string identifying a border color in a form
suitable for passing to \fBTk_Get3DBorder\fR.  The value is converted
to a (\fBTk_3DBorder *\fR) by calling \fBTk_Get3DBorder\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_Free3DBorder\fR.
.TP
\fBTK_CONFIG_CAP_STYLE\fR
.
The value must be
an ASCII string identifying a cap style in one of the ways
accepted by \fBTk_GetCapStyle\fR.
The string is converted to an integer value corresponding
to the cap style by calling
\fBTk_GetCapStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_COLOR\fR
.
The value must be an ASCII string identifying a color in a form
suitable for passing to \fBTk_GetColor\fR.  The value is converted
to an (\fBXColor *\fR) by calling \fBTk_GetColor\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to \fBNone\fR.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeColor\fR.
.TP
\fBTK_CONFIG_CURSOR\fR
.
This option is identical to \fBTK_CONFIG_ACTIVE_CURSOR\fR except
that the new cursor is not made the active one for \fItkwin\fR.
.TP
\fBTK_CONFIG_CUSTOM\fR
.
This option allows applications to define new option types.
The \fIcustomPtr\fR field of the entry points to a structure
defining the new option type.
See the section \fBCUSTOM OPTION TYPES\fR below for details.
.TP
\fBTK_CONFIG_DOUBLE\fR
.
The value must be an ASCII floating-point number in
the format accepted by \fBstrtol\fR.  The string is converted
to a \fBdouble\fR value, and the value is stored in the
target.
.TP
\fBTK_CONFIG_END\fR
.
Marks the end of the table.  The last entry in \fIspecs\fR
must have this type;  all of its other fields are ignored and it
will never match any arguments.
.TP
\fBTK_CONFIG_FONT\fR
.
The value must be an ASCII string identifying a font in a form
suitable for passing to \fBTk_GetFont\fR.  The value is converted
to a \fBTk_Font\fR by calling \fBTk_GetFont\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeFont\fR.
.TP
\fBTK_CONFIG_INT\fR
.
The value must be an ASCII integer string
in the format accepted by \fBstrtol\fR (e.g.
.QW 0
and
.QW 0x
prefixes may be used to specify octal or hexadecimal
numbers, respectively).  The string is converted to an integer
value and the integer is stored in the target.
.TP
\fBTK_CONFIG_JOIN_STYLE\fR
.
The value must be
an ASCII string identifying a join style in one of the ways
accepted by \fBTk_GetJoinStyle\fR.
The string is converted to an integer value corresponding
to the join style by calling
\fBTk_GetJoinStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_JUSTIFY\fR
.
The value must be
an ASCII string identifying a justification method in one of the
ways accepted by \fBTk_GetJustify\fR.
The string is converted to a \fBTk_Justify\fR by calling
\fBTk_GetJustify\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_MM\fR
.
The value must specify a screen distance in one of the forms acceptable
to \fBTk_GetScreenMM\fR.
The string is converted to double-precision floating-point distance
in millimeters and the value is stored in the target.
.TP
\fBTK_CONFIG_PIXELS\fR
.
The value must specify screen units in one of the forms acceptable
to \fBTk_GetPixels\fR.
The string is converted to an integer distance in pixels and the
value is stored in the target.
.TP
\fBTK_CONFIG_RELIEF\fR
.
The value must be an ASCII string identifying a relief in a form
suitable for passing to \fBTk_GetRelief\fR.  The value is converted
to an integer relief value by calling \fBTk_GetRelief\fR and the result
is stored in the target.
.TP
\fBTK_CONFIG_STRING\fR

.
A copy of the value is made by allocating memory space with
\fBTcl_Alloc\fR and copying the value into the dynamically-allocated
space.  A pointer to the new string is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target was not NULL, then it is
freed by passing it to \fBTcl_Free\fR.
.TP
\fBTK_CONFIG_SYNONYM\fR
.
This \fItype\fR value identifies special entries in \fIspecs\fR that
are synonyms for other entries.  If an \fIobjv\fR value matches the
\fIargvName\fR of a \fBTK_CONFIG_SYNONYM\fR entry, the entry is not used
directly. Instead, \fBTk_ConfigureWidget\fR searches \fIspecs\fR
for another entry whose \fIargvName\fR is the same as the \fIdbName\fR
field in the \fBTK_CONFIG_SYNONYM\fR entry;  this new entry is used just
as if its \fIargvName\fR had matched the \fIobjv\fR value.  The
synonym mechanism allows multiple \fIobjv\fR values to be used for
a single configuration option, such as
.QW \-background
and
.QW \-bg .
.TP
\fBTK_CONFIG_UID\fR
.
The value is translated to a \fBTk_Uid\fR
(by passing it to \fBTk_GetUid\fR).  The resulting value
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR and the value
is an empty string then the target will be set to NULL.
.TP
\fBTK_CONFIG_WINDOW\fR
.
The value must be a window path name.  It is translated to a
\fBTk_Window\fR token and the token is stored in the target.
.SH "GROUPED ENTRIES"
.PP
In some cases it is useful to generate multiple resources from
a single configuration value.  For example, a color name might
be used both to generate the background color for a widget (using
377
378
379
380
381
382
383
384

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

398
399
400
401
402

403
404
405
406
407

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

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
The \fIflags\fR argument passed to \fBTk_ConfigureWidget\fR is used
in conjunction with the \fIspecFlags\fR fields in the entries of \fIspecs\fR
to provide additional control over the processing of configuration
options.  These values are used in three different ways as
described below.
.PP
First, if the \fIflags\fR argument to \fBTk_ConfigureWidget\fR has
the \fBTK_CONFIG_ARGV_ONLY\fR bit set (i.e., \fIflags\fR | \fBTK_CONFIG_ARGV_ONLY\fR != 0),

then the option database and
\fIdefValue\fR fields are not used.  In this case, if an entry in
\fIspecs\fR does not match a field in \fIargv\fR then nothing happens:
the corresponding target is not modified.  This feature is useful
when the goal is to modify certain configuration options while
leaving others in their current state, such as when a \fBconfigure\fR
widget command is being processed.
.PP
Second, the \fIspecFlags\fR field of an entry in \fIspecs\fR may be used
to control the processing of that entry.  Each \fIspecFlags\fR
field may consists of an OR-ed combination of the following values:
.TP
\fBTK_CONFIG_COLOR_ONLY\fR

If this bit is set then the entry will only be considered if the
display for \fItkwin\fR has more than one bit plane.  If the display
is monochromatic then this \fIspecs\fR entry will be ignored.
.TP
\fBTK_CONFIG_MONO_ONLY\fR

If this bit is set then the entry will only be considered if the
display for \fItkwin\fR has exactly one bit plane.  If the display
is not monochromatic then this \fIspecs\fR entry will be ignored.
.TP
\fBTK_CONFIG_NULL_OK\fR

This bit is only relevant for some types of entries (see the
descriptions of the various entry types above).
If this bit is set, it indicates that an empty string value
for the field is acceptable and if it occurs then the
target should be set to NULL or \fBNone\fR, depending
on the type of the target.
This flag is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
If this bit is not set then empty strings are processed as strings,
which generally results in an error.
.TP
\fBTK_CONFIG_DONT_SET_DEFAULT\fR

If this bit is one, it means that the \fIdefValue\fR field of the
entry should only be used for returning the default value in
\fBTk_ConfigureInfo\fR.
In calls to \fBTk_ConfigureWidget\fR no default will be supplied
for entries with this flag set;  it is assumed that the
caller has already supplied a default value in the target location.
This flag provides a performance optimization where it is expensive
to process the default string:  the client can compute the default
once, save the value, and provide it before calling
\fBTk_ConfigureWidget\fR.
.TP
\fBTK_CONFIG_OPTION_SPECIFIED\fR
This bit is
deprecated. It used to be set and cleared by \fBTk_ConfigureWidget\fR
so that callers could detect what entries were specified in
\fIargv\fR, but it was removed because it was inherently
thread-unsafe. Code that wishes to detect what options were specified
should use \fBTk_SetOptions\fR instead.
.PP
The \fBTK_CONFIG_MONO_ONLY\fR and \fBTK_CONFIG_COLOR_ONLY\fR flags are typically
used to specify different default values for
monochrome and color displays.  This is done by creating two
entries in \fIspecs\fR that are identical except for their
\fIdefValue\fR and \fIspecFlags\fR fields.  One entry should have
the value \fBTK_CONFIG_MONO_ONLY\fR in its \fIspecFlags\fR and the







|
>


|










>





>





>













>










<
<
<
<
<
<
<
<







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457








458
459
460
461
462
463
464
The \fIflags\fR argument passed to \fBTk_ConfigureWidget\fR is used
in conjunction with the \fIspecFlags\fR fields in the entries of \fIspecs\fR
to provide additional control over the processing of configuration
options.  These values are used in three different ways as
described below.
.PP
First, if the \fIflags\fR argument to \fBTk_ConfigureWidget\fR has
the \fBTK_CONFIG_ARGV_ONLY\fR bit set
(i.e., \fIflags\fR | \fBTK_CONFIG_ARGV_ONLY\fR != 0),
then the option database and
\fIdefValue\fR fields are not used.  In this case, if an entry in
\fIspecs\fR does not match a field in \fIobjv\fR then nothing happens:
the corresponding target is not modified.  This feature is useful
when the goal is to modify certain configuration options while
leaving others in their current state, such as when a \fBconfigure\fR
widget command is being processed.
.PP
Second, the \fIspecFlags\fR field of an entry in \fIspecs\fR may be used
to control the processing of that entry.  Each \fIspecFlags\fR
field may consists of an OR-ed combination of the following values:
.TP
\fBTK_CONFIG_COLOR_ONLY\fR
.
If this bit is set then the entry will only be considered if the
display for \fItkwin\fR has more than one bit plane.  If the display
is monochromatic then this \fIspecs\fR entry will be ignored.
.TP
\fBTK_CONFIG_MONO_ONLY\fR
.
If this bit is set then the entry will only be considered if the
display for \fItkwin\fR has exactly one bit plane.  If the display
is not monochromatic then this \fIspecs\fR entry will be ignored.
.TP
\fBTK_CONFIG_NULL_OK\fR
.
This bit is only relevant for some types of entries (see the
descriptions of the various entry types above).
If this bit is set, it indicates that an empty string value
for the field is acceptable and if it occurs then the
target should be set to NULL or \fBNone\fR, depending
on the type of the target.
This flag is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
If this bit is not set then empty strings are processed as strings,
which generally results in an error.
.TP
\fBTK_CONFIG_DONT_SET_DEFAULT\fR
.
If this bit is one, it means that the \fIdefValue\fR field of the
entry should only be used for returning the default value in
\fBTk_ConfigureInfo\fR.
In calls to \fBTk_ConfigureWidget\fR no default will be supplied
for entries with this flag set;  it is assumed that the
caller has already supplied a default value in the target location.
This flag provides a performance optimization where it is expensive
to process the default string:  the client can compute the default
once, save the value, and provide it before calling
\fBTk_ConfigureWidget\fR.








.PP
The \fBTK_CONFIG_MONO_ONLY\fR and \fBTK_CONFIG_COLOR_ONLY\fR flags are typically
used to specify different default values for
monochrome and color displays.  This is done by creating two
entries in \fIspecs\fR that are identical except for their
\fIdefValue\fR and \fIspecFlags\fR fields.  One entry should have
the value \fBTK_CONFIG_MONO_ONLY\fR in its \fIspecFlags\fR and the
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
corresponding field of the widget record to null.
.SH "CUSTOM OPTION TYPES"
.PP
Applications can extend the built-in configuration types with additional
configuration types by writing procedures to parse and print options
of the a type and creating a structure pointing to those procedures:
.CS
typedef struct Tk_CustomOption {
    Tk_OptionParseProc *\fIparseProc\fR;
    Tk_OptionPrintProc *\fIprintProc\fR;
    ClientData \fIclientData\fR;
} \fBTk_CustomOption\fR;

typedef int \fBTk_OptionParseProc\fR(
        ClientData \fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        Tk_Window \fItkwin\fR,
        char *\fIvalue\fR,
        char *\fIwidgRec\fR,
        int \fIoffset\fR);

typedef const char *\fBTk_OptionPrintProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR,
        char *\fIwidgRec\fR,
        int \fIoffset\fR,
        Tcl_FreeProc **\fIfreeProcPtr\fR);
.CE
The Tk_CustomOption structure contains three fields, which are pointers
to the two procedures and a \fIclientData\fR value to be passed to those
procedures when they are invoked.  The \fIclientData\fR value typically
points to a structure containing information that is needed by the
procedures when they are parsing and printing options.







|


|



|




|


|


|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
corresponding field of the widget record to null.
.SH "CUSTOM OPTION TYPES"
.PP
Applications can extend the built-in configuration types with additional
configuration types by writing procedures to parse and print options
of the a type and creating a structure pointing to those procedures:
.CS
typedef struct {
    Tk_OptionParseProc *\fIparseProc\fR;
    Tk_OptionPrintProc *\fIprintProc\fR;
    void *\fIclientData\fR;
} \fBTk_CustomOption\fR;

typedef int \fBTk_OptionParseProc\fR(
        void *\fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        Tk_Window \fItkwin\fR,
        char *\fIvalue\fR,
        char *\fIwidgRec\fR,
        Tcl_Size \fIoffset\fR);

typedef const char *\fBTk_OptionPrintProc\fR(
        void *\fIclientData\fR,
        Tk_Window \fItkwin\fR,
        char *\fIwidgRec\fR,
        Tcl_Size \fIoffset\fR,
        Tcl_FreeProc **\fIfreeProcPtr\fR);
.CE
The Tk_CustomOption structure contains three fields, which are pointers
to the two procedures and a \fIclientData\fR value to be passed to those
procedures when they are invoked.  The \fIclientData\fR value typically
points to a structure containing information that is needed by the
procedures when they are parsing and printing options.

Changes to doc/ConfigWind.3.

35
36
37
38
39
40
41

42
43
44
45
46
47
48
\fBTk_SetWindowBorderPixmap\fR(\fItkwin, pixmap\fR)
.sp
\fBTk_SetWindowColormap\fR(\fItkwin, colormap\fR)
.sp
\fBTk_DefineCursor\fR(\fItkwin, cursor\fR)
.sp
\fBTk_UndefineCursor\fR(\fItkwin\fR)

.SH ARGUMENTS
.AS XSetWindowAttributes borderWidth
.AP Tk_Window tkwin in
Token for window.
.AP "unsigned int" valueMask in
OR-ed mask of values like \fBCWX\fR or \fBCWBorderPixel\fR,
indicating which fields of \fI*valuePtr\fR or \fI*attsPtr\fR to use.







>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
\fBTk_SetWindowBorderPixmap\fR(\fItkwin, pixmap\fR)
.sp
\fBTk_SetWindowColormap\fR(\fItkwin, colormap\fR)
.sp
\fBTk_DefineCursor\fR(\fItkwin, cursor\fR)
.sp
\fBTk_UndefineCursor\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS XSetWindowAttributes borderWidth
.AP Tk_Window tkwin in
Token for window.
.AP "unsigned int" valueMask in
OR-ed mask of values like \fBCWX\fR or \fBCWBorderPixel\fR,
indicating which fields of \fI*valuePtr\fR or \fI*attsPtr\fR to use.

Changes to doc/CoordToWin.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_CoordsToWindow \- Find window containing a point
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_CoordsToWindow\fR(\fIrootX, rootY, tkwin\fR)

.SH ARGUMENTS
.AS Tk_Window tkwin
.AP int rootX in
X-coordinate (in root window coordinates).
.AP int rootY in
Y-coordinate (in root window coordinates).
.AP Tk_Window tkwin in







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_CoordsToWindow \- Find window containing a point
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_CoordsToWindow\fR(\fIrootX, rootY, tkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP int rootX in
X-coordinate (in root window coordinates).
.AP int rootY in
Y-coordinate (in root window coordinates).
.AP Tk_Window tkwin in

Changes to doc/CrtCmHdlr.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateClientMessageHandler\fR(\fIproc\fR)
.sp
\fBTk_DeleteClientMessageHandler\fR(\fIproc\fR)

.SH ARGUMENTS
.AP Tk_ClientMessageProc *proc in
Procedure to invoke whenever a ClientMessage X event occurs on any display.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateClientMessageHandler\fR arranges for \fIproc\fR to be invoked







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateClientMessageHandler\fR(\fIproc\fR)
.sp
\fBTk_DeleteClientMessageHandler\fR(\fIproc\fR)
.fi
.SH ARGUMENTS
.AP Tk_ClientMessageProc *proc in
Procedure to invoke whenever a ClientMessage X event occurs on any display.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateClientMessageHandler\fR arranges for \fIproc\fR to be invoked

Changes to doc/CrtConsoleChan.3.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
.SH NAME
Tk_InitConsoleChannels \- Install the console channels as standard channels
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_InitConsoleChannels\fR(\fIinterp\fR)

.SH ARGUMENTS
.AS Tcl_Interp *interp in
.AP Tcl_Interp *interp in
Interpreter in which the console channels are created.
.BE
.SH DESCRIPTION
.PP







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.SH NAME
Tk_InitConsoleChannels \- Install the console channels as standard channels
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_InitConsoleChannels\fR(\fIinterp\fR)
.fi
.SH ARGUMENTS
.AS Tcl_Interp *interp in
.AP Tcl_Interp *interp in
Interpreter in which the console channels are created.
.BE
.SH DESCRIPTION
.PP

Changes to doc/CrtErrHdlr.3.

14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.nf
\fB#include <tk.h>\fR
.sp
Tk_ErrorHandler
\fBTk_CreateErrorHandler\fR(\fIdisplay, error, request, minor, proc, clientData\fR)
.sp
\fBTk_DeleteErrorHandler\fR(\fIhandler\fR)

.SH ARGUMENTS
.AS "Tk_ErrorHandler" clientData
.AP Display *display in
Display whose errors are to be handled.
.AP int error in
Match only error events with this value in the \fIerror_code\fR
field.  If \-1, then match any \fIerror_code\fR value.
.AP int request in
Match only error events with this value in the \fIrequest_code\fR
field.  If \-1, then match any \fIrequest_code\fR value.
.AP int minor in
Match only error events with this value in the \fIminor_code\fR
field.  If \-1, then match any \fIminor_code\fR value.
.AP Tk_ErrorProc *proc in
Procedure to invoke whenever an error event is received for
\fIdisplay\fR and matches \fIerror\fR, \fIrequest\fR, and \fIminor\fR.
NULL means ignore any matching errors.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP Tk_ErrorHandler handler in
Token for error handler to delete (return value from a previous
call to \fBTk_CreateErrorHandler\fR).
.BE
.SH DESCRIPTION
.PP







>

















|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.nf
\fB#include <tk.h>\fR
.sp
Tk_ErrorHandler
\fBTk_CreateErrorHandler\fR(\fIdisplay, error, request, minor, proc, clientData\fR)
.sp
\fBTk_DeleteErrorHandler\fR(\fIhandler\fR)
.fi
.SH ARGUMENTS
.AS "Tk_ErrorHandler" clientData
.AP Display *display in
Display whose errors are to be handled.
.AP int error in
Match only error events with this value in the \fIerror_code\fR
field.  If \-1, then match any \fIerror_code\fR value.
.AP int request in
Match only error events with this value in the \fIrequest_code\fR
field.  If \-1, then match any \fIrequest_code\fR value.
.AP int minor in
Match only error events with this value in the \fIminor_code\fR
field.  If \-1, then match any \fIminor_code\fR value.
.AP Tk_ErrorProc *proc in
Procedure to invoke whenever an error event is received for
\fIdisplay\fR and matches \fIerror\fR, \fIrequest\fR, and \fIminor\fR.
NULL means ignore any matching errors.
.AP void *clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP Tk_ErrorHandler handler in
Token for error handler to delete (return value from a previous
call to \fBTk_CreateErrorHandler\fR).
.BE
.SH DESCRIPTION
.PP
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
The protocol request to which the error pertains must have been
made when the handler was active (see below for more information).
.PP
\fIProc\fR should have arguments and result that match the
following type:
.CS
typedef int \fBTk_ErrorProc\fR(
        ClientData \fIclientData\fR,
        XErrorEvent *\fIerrEventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTcl_CreateErrorHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to deal with the error.  \fIErrEventPtr\fR is







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
The protocol request to which the error pertains must have been
made when the handler was active (see below for more information).
.PP
\fIProc\fR should have arguments and result that match the
following type:
.CS
typedef int \fBTk_ErrorProc\fR(
        void *\fIclientData\fR,
        XErrorEvent *\fIerrEventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTcl_CreateErrorHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to deal with the error.  \fIErrEventPtr\fR is

Changes to doc/CrtGenHdlr.3.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateGenericHandler\fR(\fIproc, clientData\fR)
.sp
\fBTk_DeleteGenericHandler\fR(\fIproc, clientData\fR)

.SH ARGUMENTS
.AS "Tk_GenericProc" clientData
.AP Tk_GenericProc *proc in
Procedure to invoke whenever any X event occurs on any display.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateGenericHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever any X event occurs.  This mechanism is
\fInot\fR intended for dispatching X events on windows managed by Tk







>




|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateGenericHandler\fR(\fIproc, clientData\fR)
.sp
\fBTk_DeleteGenericHandler\fR(\fIproc, clientData\fR)
.fi
.SH ARGUMENTS
.AS "Tk_GenericProc" clientData
.AP Tk_GenericProc *proc in
Procedure to invoke whenever any X event occurs on any display.
.AP void *clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateGenericHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever any X event occurs.  This mechanism is
\fInot\fR intended for dispatching X events on windows managed by Tk
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_GenericProc\fR:
.CS
typedef int \fBTk_GenericProc\fR(
        ClientData \fIclientData\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateGenericHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
how to handle events.







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_GenericProc\fR:
.CS
typedef int \fBTk_GenericProc\fR(
        void *\fIclientData\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateGenericHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
how to handle events.

Changes to doc/CrtImgType.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateImageType, Tk_GetImageModelData, Tk_InitImageArgs \- define new kind of image
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateImageType\fR(\fItypePtr\fR)
.sp
ClientData
\fBTk_GetImageModelData\fR(\fIinterp, name, typePtrPtr\fR)
.sp
\fBTk_InitImageArgs\fR(\fIinterp, argc, argvPtr\fR)
.SH ARGUMENTS
.AS "const Tk_ImageType" *typePtrPtr
.AP "const Tk_ImageType" *typePtr in
Structure that defines the new type of image.
For Tk 8.4 and earlier this must be static: a
pointer to this structure is retained by the image code.
In Tk 8.5, this limitation was relaxed.
.AP Tcl_Interp *interp in
Interpreter in which image was created.
.AP "const char" *name in
Name of existing image.
.AP Tk_ImageType **typePtrPtr out
Points to word in which to store a pointer to type information for
the given image, if it exists.
.AP int argc in
Number of arguments
.AP char ***argvPtr in/out
Pointer to argument list
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateImageType\fR is invoked to define a new kind of image.
An image type corresponds to a particular value of the \fItype\fR











|






|

|
<














<
<







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

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


36
37
38
39
40
41
42
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateImageType, Tk_GetImageModelData \- define new kind of image
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateImageType\fR(\fItypePtr\fR)
.sp
void *
\fBTk_GetImageModelData\fR(\fIinterp, name, typePtrPtr\fR)
.fi

.SH ARGUMENTS
.AS "const Tk_ImageType" *typePtrPtr
.AP "const Tk_ImageType" *typePtr in
Structure that defines the new type of image.
For Tk 8.4 and earlier this must be static: a
pointer to this structure is retained by the image code.
In Tk 8.5, this limitation was relaxed.
.AP Tcl_Interp *interp in
Interpreter in which image was created.
.AP "const char" *name in
Name of existing image.
.AP Tk_ImageType **typePtrPtr out
Points to word in which to store a pointer to type information for
the given image, if it exists.


.AP char ***argvPtr in/out
Pointer to argument list
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateImageType\fR is invoked to define a new kind of image.
An image type corresponds to a particular value of the \fItype\fR
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
\fIimage manager\fR.
It consists of a collection of procedures plus three different
kinds of data structures.
The first data structure is a Tk_ImageType structure, which contains
the name of the image type and pointers to five procedures provided
by the image manager to deal with images of this type:
.CS
typedef struct Tk_ImageType {
    const char *\fIname\fR;
    Tk_ImageCreateProc *\fIcreateProc\fR;
    Tk_ImageGetProc *\fIgetProc\fR;
    Tk_ImageDisplayProc *\fIdisplayProc\fR;
    Tk_ImageFreeProc *\fIfreeProc\fR;
    Tk_ImageDeleteProc *\fIdeleteProc\fR;
} \fBTk_ImageType\fR;







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
\fIimage manager\fR.
It consists of a collection of procedures plus three different
kinds of data structures.
The first data structure is a Tk_ImageType structure, which contains
the name of the image type and pointers to five procedures provided
by the image manager to deal with images of this type:
.CS
typedef struct {
    const char *\fIname\fR;
    Tk_ImageCreateProc *\fIcreateProc\fR;
    Tk_ImageGetProc *\fIgetProc\fR;
    Tk_ImageDisplayProc *\fIdisplayProc\fR;
    Tk_ImageFreeProc *\fIfreeProc\fR;
    Tk_ImageDeleteProc *\fIdeleteProc\fR;
} \fBTk_ImageType\fR;
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIname\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[],
        const Tk_ImageType *\fItypePtr\fR,
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the \fBimage\fR
command was invoked, and \fIname\fR is the name for the new image,
which was either specified explicitly in the \fBimage\fR command
or generated automatically by the \fBimage\fR command.
The \fIobjc\fR and \fIobjv\fR arguments describe all the configuration
options for the new image (everything after the name argument to







|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIname\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[],
        const Tk_ImageType *\fItypePtr\fR,
        Tk_ImageModel \fImodel\fR,
        void **\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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
size of the image and request an initial redisplay.
.SS GETPROC
.PP
\fItypePtr->getProc\fR is invoked by Tk whenever a widget
calls \fBTk_GetImage\fR to use a particular image.
This procedure must match the following prototype:
.CS
typedef ClientData \fBTk_ImageGetProc\fR(
        Tk_Window \fItkwin\fR,
        ClientData \fImodelData\fR);
.CE
The \fItkwin\fR argument identifies the window in which the
image will be used and \fImodelData\fR is the value
returned by \fIcreateProc\fR when the image model was created.
\fIgetProc\fR will usually create a data structure for the new
instance, including such things as the resources needed to
display the image in the given window.
\fIgetProc\fR returns a one-word token for the instance, which
is typically the address of the instance data structure.
Tk will pass this value back to the image manager when invoking
its \fIdisplayProc\fR and \fIfreeProc\fR procedures.
.SS DISPLAYPROC
.PP
\fItypePtr->displayProc\fR is invoked by Tk whenever an image needs
to be displayed (i.e., whenever a widget calls \fBTk_RedrawImage\fR).
\fIdisplayProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDisplayProc\fR(
        ClientData \fIinstanceData\fR,
        Display *\fIdisplay\fR,
        Drawable \fIdrawable\fR,
        int \fIimageX\fR,
        int \fIimageY\fR,
        int \fIwidth\fR,
        int \fIheight\fR,
        int \fIdrawableX\fR,







|

|


















|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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 void *\fBTk_ImageGetProc\fR(
        Tk_Window \fItkwin\fR,
        void *\fImodelData\fR);
.CE
The \fItkwin\fR argument identifies the window in which the
image will be used and \fImodelData\fR is the value
returned by \fIcreateProc\fR when the image model was created.
\fIgetProc\fR will usually create a data structure for the new
instance, including such things as the resources needed to
display the image in the given window.
\fIgetProc\fR returns a one-word token for the instance, which
is typically the address of the instance data structure.
Tk will pass this value back to the image manager when invoking
its \fIdisplayProc\fR and \fIfreeProc\fR procedures.
.SS DISPLAYPROC
.PP
\fItypePtr->displayProc\fR is invoked by Tk whenever an image needs
to be displayed (i.e., whenever a widget calls \fBTk_RedrawImage\fR).
\fIdisplayProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDisplayProc\fR(
        void *\fIinstanceData\fR,
        Display *\fIdisplay\fR,
        Drawable \fIdrawable\fR,
        int \fIimageX\fR,
        int \fIimageY\fR,
        int \fIwidth\fR,
        int \fIheight\fR,
        int \fIdrawableX\fR,
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
\fBTk_FreeImage\fR is invoked).
This can happen, for example, when a widget is deleted or a image item
in a canvas is deleted, or when the image displayed in a widget or
canvas item is changed.
\fIfreeProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageFreeProc\fR(
        ClientData \fIinstanceData\fR,
        Display *\fIdisplay\fR);
.CE
The \fIinstanceData\fR will be the same as the value returned by
\fIgetProc\fR when the instance was created, and \fIdisplay\fR
is the display containing the window for the instance.
\fIfreeProc\fR should release any resources associated with the
image instance, since the instance will never be used again.
.SS DELETEPROC
.PP
\fItypePtr->deleteProc\fR is a procedure that Tk invokes when an
image is being deleted (i.e. when the \fBimage delete\fR command
is invoked).
Before invoking \fIdeleteProc\fR Tk will invoke \fIfreeProc\fR for
each of the image's instances.
\fIdeleteProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDeleteProc\fR(
        ClientData \fImodelData\fR);
.CE
The \fImodelData\fR argument will be the same as the value
stored in \fI*modelDataPtr\fR by \fIcreateProc\fR when the
image was created.
\fIdeleteProc\fR should release any resources associated with
the image.
.SH TK_GETIMAGEMODELDATA
.PP
The procedure \fBTk_GetImageModelData\fR may be invoked to retrieve
information about an image.  For example, an image manager can use this
procedure to locate its image model data for an image.
If there exists an image named \fIname\fR
in the interpreter given by \fIinterp\fR, then \fI*typePtrPtr\fR is
filled in with type information for the image (the \fItypePtr\fR value
passed to \fBTk_CreateImageType\fR when the image type was registered)
and the return value is the ClientData value returned by the
\fIcreateProc\fR when the image was created (this is typically a
pointer to the image model data structure).  If no such image exists
then NULL is returned and NULL is stored at \fI*typePtrPtr\fR.
.SH "LEGACY INTERFACE SUPPORT"
.PP
In Tk 8.2 and earlier, the definition of \fBTk_ImageCreateProc\fR
was incompatibly different, with the following prototype:
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        char *\fIname\fR,
        int \fIargc\fR,
        char **\fIargv\fR,
        Tk_ImageType *\fItypePtr\fR,
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
Legacy programs and libraries dating from those days may still
contain code that defines extended Tk image types using the old
interface.  The Tk header file will still support this legacy
interface if the code is compiled with the macro \fBUSE_OLD_IMAGE\fR
defined.
.PP
When the \fBUSE_OLD_IMAGE\fR legacy support is enabled, you may
see the routine \fBTk_InitImageArgs\fR in use.  This was a migration
tool used to create stub-enabled extensions that could be loaded
into interps containing all versions of Tk 8.1 and later.  Tk 8.5 no longer
provides this routine, but uses a macro to convert any attempted
calls of this routine into an empty comment.  Any stub-enabled
extension providing an extended image type via the legacy interface
that is compiled against Tk 8.5 headers and linked against the
Tk 8.5 stub library will produce a file that can be loaded only
into interps with Tk 8.5 or later; that is, the normal stub-compatibility
rules.  If a developer needs to generate from such code a file
that is loadable into interps with Tk 8.4 or earlier, they must
use Tk 8.4 headers and stub libraries to do so.
.PP
Any new code written today should not make use of the legacy
interfaces.  Expect their support to go away in Tk 9.
.SH "SEE ALSO"
Tk_ImageChanged, Tk_GetImage, Tk_FreeImage, Tk_RedrawImage, Tk_SizeOfImage
.SH KEYWORDS
image manager, image type, instance, model







|

















|















|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




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




































241
242
243
244
\fBTk_FreeImage\fR is invoked).
This can happen, for example, when a widget is deleted or a image item
in a canvas is deleted, or when the image displayed in a widget or
canvas item is changed.
\fIfreeProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageFreeProc\fR(
        void *\fIinstanceData\fR,
        Display *\fIdisplay\fR);
.CE
The \fIinstanceData\fR will be the same as the value returned by
\fIgetProc\fR when the instance was created, and \fIdisplay\fR
is the display containing the window for the instance.
\fIfreeProc\fR should release any resources associated with the
image instance, since the instance will never be used again.
.SS DELETEPROC
.PP
\fItypePtr->deleteProc\fR is a procedure that Tk invokes when an
image is being deleted (i.e. when the \fBimage delete\fR command
is invoked).
Before invoking \fIdeleteProc\fR Tk will invoke \fIfreeProc\fR for
each of the image's instances.
\fIdeleteProc\fR must match the following prototype:
.CS
typedef void \fBTk_ImageDeleteProc\fR(
        void *\fImodelData\fR);
.CE
The \fImodelData\fR argument will be the same as the value
stored in \fI*modelDataPtr\fR by \fIcreateProc\fR when the
image was created.
\fIdeleteProc\fR should release any resources associated with
the image.
.SH TK_GETIMAGEMODELDATA
.PP
The procedure \fBTk_GetImageModelData\fR may be invoked to retrieve
information about an image.  For example, an image manager can use this
procedure to locate its image model data for an image.
If there exists an image named \fIname\fR
in the interpreter given by \fIinterp\fR, then \fI*typePtrPtr\fR is
filled in with type information for the image (the \fItypePtr\fR value
passed to \fBTk_CreateImageType\fR when the image type was registered)
and the return value is the clientData value returned by the
\fIcreateProc\fR when the image was created (this is typically a
pointer to the image model data structure).  If no such image exists
then NULL is returned and NULL is stored at \fI*typePtrPtr\fR.




































.SH "SEE ALSO"
Tk_ImageChanged, Tk_GetImage, Tk_FreeImage, Tk_RedrawImage, Tk_SizeOfImage
.SH KEYWORDS
image manager, image type, instance, model

Changes to doc/CrtItemType.3.

13
14
15
16
17
18
19

20
21
22
23

24
25
26
27
28
29
30
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateItemType\fR(\fItypePtr\fR)
.sp
Tk_ItemType *
\fBTk_GetItemTypes\fR()

.SH ARGUMENTS
.AS Tk_ItemType *typePtr
.AP Tk_ItemType *typePtr in
Structure that defines the new type of canvas item.

.BE
.SH INTRODUCTION
.PP
\fBTk_CreateItemType\fR is invoked to define a new kind of canvas item
described by the \fItypePtr\fR argument.
An item type corresponds to a particular value of the \fItype\fR
argument to the \fBcreate\fR widget command for canvases, and







>




>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateItemType\fR(\fItypePtr\fR)
.sp
Tk_ItemType *
\fBTk_GetItemTypes\fR()
.fi
.SH ARGUMENTS
.AS Tk_ItemType *typePtr
.AP Tk_ItemType *typePtr in
Structure that defines the new type of canvas item.
Note that this is not \fIconst\fR; Tk may write to these structures.
.BE
.SH INTRODUCTION
.PP
\fBTk_CreateItemType\fR is invoked to define a new kind of canvas item
described by the \fItypePtr\fR argument.
An item type corresponds to a particular value of the \fItype\fR
argument to the \fBcreate\fR widget command for canvases, and
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    size_t \fIitemSize\fR;
    Tk_ItemCreateProc *\fIcreateProc\fR;
    const Tk_ConfigSpec *\fIconfigSpecs\fR;
    Tk_ItemConfigureProc *\fIconfigProc\fR;
    Tk_ItemCoordProc *\fIcoordProc\fR;
    Tk_ItemDeleteProc *\fIdeleteProc\fR;
    Tk_ItemDisplayProc *\fIdisplayProc\fR;
    int \fIalwaysRedraw\fR;
    Tk_ItemPointProc *\fIpointProc\fR;
    Tk_ItemAreaProc *\fIareaProc\fR;
    Tk_ItemPostscriptProc *\fIpostscriptProc\fR;
    Tk_ItemScaleProc *\fIscaleProc\fR;
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;
.VS "8.7, TIP164"
    Tk_ItemRotateProc *\fIrotateProc\fR;
.VE "8.7, TIP164"
} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail







|










|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    size_t \fIitemSize\fR;
    Tk_ItemCreateProc *\fIcreateProc\fR;
    const Tk_ConfigSpec *\fIconfigSpecs\fR;
    Tk_ItemConfigureProc *\fIconfigProc\fR;
    Tk_ItemCoordProc *\fIcoordProc\fR;
    Tk_ItemDeleteProc *\fIdeleteProc\fR;
    Tk_ItemDisplayProc *\fIdisplayProc\fR;
    int \fIflags\fR;
    Tk_ItemPointProc *\fIpointProc\fR;
    Tk_ItemAreaProc *\fIareaProc\fR;
    Tk_ItemPostscriptProc *\fIpostscriptProc\fR;
    Tk_ItemScaleProc *\fIscaleProc\fR;
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    struct Tk_ItemType *\fInextPtr\fR;
.VS "8.7, TIP164"
    Tk_ItemRotateProc *\fIrotateProc\fR;
.VE "8.7, TIP164"
} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
defined by Tk via the type Tk_Item; the rest of the item
record is defined by the type manager.
A type manager must define its item records with a Tk_Item as
the first field.
For example, the item record for bitmap items is defined as follows:
.PP
.CS
typedef struct BitmapItem {
    Tk_Item \fIheader\fR;
    double \fIx\fR, \fIy\fR;
    Tk_Anchor \fIanchor\fR;
    Pixmap \fIbitmap\fR;
    XColor *\fIfgColor\fR;
    XColor *\fIbgColor\fR;
    GC \fIgc\fR;







|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
defined by Tk via the type Tk_Item; the rest of the item
record is defined by the type manager.
A type manager must define its item records with a Tk_Item as
the first field.
For example, the item record for bitmap items is defined as follows:
.PP
.CS
typedef struct {
    Tk_Item \fIheader\fR;
    double \fIx\fR, \fIy\fR;
    Tk_Anchor \fIanchor\fR;
    Pixmap \fIbitmap\fR;
    XColor *\fIfgColor\fR;
    XColor *\fIbgColor\fR;
    GC \fIgc\fR;
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
Once \fBTk_CreateImageType\fR returns, this name may be used
in \fBcreate\fR widget commands to create items of the new
type.
If there already existed an item type by this name then
the new item type replaces the old one.
.SS "FLAGS (IN ALWAYSREDRAW)"
.PP
The \fItypePtr\->alwaysRedraw\fR field (so named for historic reasons)
contains a collection of flag bits that modify how the canvas core interacts
with the item. The following bits are defined:
.TP
\fB1\fR
.
Indicates that the item should always be redrawn when any part of the canvas
is redrawn, rather than only when the bounding box of the item overlaps the
area being redrawn. This is used by window items, for example, which need to
unmap subwindows that are not on the screen.
.TP
\fBTK_CONFIG_OBJS\fR
.
Indicates that operations which would otherwise take a string (or array of
strings) actually take a Tcl_Obj reference (or an array of such references).
The operations to which this applies are the \fIconfigProc\fR, the
\fIcoordProc\fR, the \fIcreateProc\fR, the \fIindexProc\fR and the
\fIinsertProc\fR.
.TP
\fBTK_MOVABLE_POINTS\fR
.VS 8.6
Indicates that the item supports the \fIdCharsProc\fR, \fIindexProc\fR and
\fIinsertProc\fR with the same semantics as Tk's built-in line and polygon
types, and that hence individual coordinate points can be moved. Must not be
set if any of the above methods is NULL.
.VE 8.6







|



|






<
<
<
<
<
<
<
<







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








185
186
187
188
189
190
191
Once \fBTk_CreateImageType\fR returns, this name may be used
in \fBcreate\fR widget commands to create items of the new
type.
If there already existed an item type by this name then
the new item type replaces the old one.
.SS "FLAGS (IN ALWAYSREDRAW)"
.PP
The \fItypePtr\->flags\fR field
contains a collection of flag bits that modify how the canvas core interacts
with the item. The following bits are defined:
.TP
\fBTK_ALWAYS_REDRAW\fR
.
Indicates that the item should always be redrawn when any part of the canvas
is redrawn, rather than only when the bounding box of the item overlaps the
area being redrawn. This is used by window items, for example, which need to
unmap subwindows that are not on the screen.
.TP








\fBTK_MOVABLE_POINTS\fR
.VS 8.6
Indicates that the item supports the \fIdCharsProc\fR, \fIindexProc\fR and
\fIinsertProc\fR with the same semantics as Tk's built-in line and polygon
types, and that hence individual coordinate points can be moved. Must not be
set if any of the above methods is NULL.
.VE 8.6
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
\fIitemPtr\fR is a pointer to a newly-allocated item of
size \fItypePtr\->itemSize\fR.
Tk has already initialized the item's header (the first
\fBsizeof(Tk_ItemType)\fR bytes).
The \fIobjc\fR and \fIobjv\fR arguments describe all of the
arguments to the \fBcreate\fR command after the \fItype\fR
argument.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobjv\fR parameter will actually
contain a pointer to an array of constant strings.
For example, in the widget command:
.PP
.CS
\fB\&.c create rectangle 10 20 50 50 \-fill black\fR
.CE
.PP
\fIobjc\fR will be \fB6\fR and \fIobjv\fR[0] will contain the







<
<
<







219
220
221
222
223
224
225



226
227
228
229
230
231
232
\fIitemPtr\fR is a pointer to a newly-allocated item of
size \fItypePtr\->itemSize\fR.
Tk has already initialized the item's header (the first
\fBsizeof(Tk_ItemType)\fR bytes).
The \fIobjc\fR and \fIobjv\fR arguments describe all of the
arguments to the \fBcreate\fR command after the \fItype\fR
argument.



For example, in the widget command:
.PP
.CS
\fB\&.c create rectangle 10 20 50 50 \-fill black\fR
.CE
.PP
\fIobjc\fR will be \fB6\fR and \fIobjv\fR[0] will contain the
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
\fBTk_ConfigureWidget\fR.
This table will normally be used by \fItypePtr\->createProc\fR
and \fItypePtr\->configProc\fR, but Tk also uses it directly
to retrieve option information in the \fBitemcget\fR and
\fBitemconfigure\fR widget commands.
\fItypePtr\->configSpecs\fR must point to the configuration table
for this type.

Note: Tk provides a custom option type \fBtk_CanvasTagsOption\fR
for implementing the \fB\-tags\fR option; see an existing type
manager for an example of how to use it in \fIconfigSpecs\fR.
.SS CONFIGPROC
.PP
\fItypePtr\->configProc\fR is called by Tk whenever the
\fBitemconfigure\fR widget command is invoked to change the
configuration options for a canvas item.







>
|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
\fBTk_ConfigureWidget\fR.
This table will normally be used by \fItypePtr\->createProc\fR
and \fItypePtr\->configProc\fR, but Tk also uses it directly
to retrieve option information in the \fBitemcget\fR and
\fBitemconfigure\fR widget commands.
\fItypePtr\->configSpecs\fR must point to the configuration table
for this type.
.PP
Note that Tk provides a custom option type \fBtk_CanvasTagsOption\fR
for implementing the \fB\-tags\fR option; see an existing type
manager for an example of how to use it in \fIconfigSpecs\fR.
.SS CONFIGPROC
.PP
\fItypePtr\->configProc\fR is called by Tk whenever the
\fBitemconfigure\fR widget command is invoked to change the
configuration options for a canvas item.
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
        int \fIflags\fR);
.CE
.PP
The \fIinterp\fR argument identifies the interpreter in which the
widget command was invoked, \fIcanvas\fR is a handle for the canvas
widget, and \fIitemPtr\fR is a pointer to the item being configured.
\fIobjc\fR and \fIobjv\fR contain the configuration options.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobjv\fR parameter will actually
contain a pointer to an array of constant strings.
For example, if the following command is invoked:
.PP
.CS
\fB\&.c itemconfigure 2 \-fill red \-outline black\fR
.CE
.PP
\fIobjc\fR is \fB4\fR and \fIobjv\fR contains the string objects \fB\-fill\fR







<
<
<







273
274
275
276
277
278
279



280
281
282
283
284
285
286
        int \fIflags\fR);
.CE
.PP
The \fIinterp\fR argument identifies the interpreter in which the
widget command was invoked, \fIcanvas\fR is a handle for the canvas
widget, and \fIitemPtr\fR is a pointer to the item being configured.
\fIobjc\fR and \fIobjv\fR contain the configuration options.



For example, if the following command is invoked:
.PP
.CS
\fB\&.c itemconfigure 2 \-fill red \-outline black\fR
.CE
.PP
\fIobjc\fR is \fB4\fR and \fIobjv\fR contains the string objects \fB\-fill\fR
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[]);
.CE
.PP
The arguments \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR
all have the standard meanings, and \fIobjc\fR and \fIobjv\fR
describe the coordinate arguments.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobjv\fR parameter will actually
contain a pointer to an array of constant strings.
For example, if the following widget command is invoked:
.PP
.CS
\fB\&.c coords 2 30 90\fR
.CE
.PP
\fIobjc\fR will be \fB2\fR and \fBobjv\fR will contain the integer objects







<
<
<







309
310
311
312
313
314
315



316
317
318
319
320
321
322
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[]);
.CE
.PP
The arguments \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR
all have the standard meanings, and \fIobjc\fR and \fIobjv\fR
describe the coordinate arguments.



For example, if the following widget command is invoked:
.PP
.CS
\fB\&.c coords 2 30 90\fR
.CE
.PP
\fIobjc\fR will be \fB2\fR and \fBobjv\fR will contain the integer objects
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
will not necessarily be the same as those in the canvas.
\fIdisplayProc\fR should call \fBTk_CanvasDrawableCoords\fR
to transform coordinates from those of the canvas to those
of \fIdst\fR.
.PP
Normally an item's \fIdisplayProc\fR is only invoked if the item
overlaps the area being displayed.
However, if bit zero of \fItypePtr\->alwaysRedraw\fR is 1,
(i.e.\|
.QW "\fItypePtr\->alwaysRedraw & 1 == 1\fR" )
then \fIdisplayProc\fR is invoked during every redisplay operation,
even if the item does not overlap the area of redisplay; this is useful for
cases such as window items, where the subwindow needs to be unmapped when it
is off the screen.
.SS POINTPROC
.PP
\fItypePtr\->pointProc\fR is invoked by Tk to find out how close







|

|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
will not necessarily be the same as those in the canvas.
\fIdisplayProc\fR should call \fBTk_CanvasDrawableCoords\fR
to transform coordinates from those of the canvas to those
of \fIdst\fR.
.PP
Normally an item's \fIdisplayProc\fR is only invoked if the item
overlaps the area being displayed.
However, if bit zero of \fItypePtr\->flags\fR is 1,
(i.e.\|
.QW "\fItypePtr\->flags & 1 == 1\fR" )
then \fIdisplayProc\fR is invoked during every redisplay operation,
even if the item does not overlap the area of redisplay; this is useful for
cases such as window items, where the subwindow needs to be unmapped when it
is off the screen.
.SS POINTPROC
.PP
\fItypePtr\->pointProc\fR is invoked by Tk to find out how close
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
the item is to be rotated, and \fIangleRad\fR gives the anticlockwise
rotation to be applied in radians.
The item should adjust the coordinates of its control points so that where
they used to have coordinates \fIx\fR and \fIy\fR, they will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where
.PP
.CS
\fIrelX\fR = \fIx\fR - \fIoriginX\fR
\fIrelY\fR = \fIy\fR - \fIoriginY\fR
\fIx\(fm\fR = \fIoriginX\fR + \fIrelX\fR \(mu cos(\fIangleRad\fR) + \fIrelY\fR \(mu sin(\fIangleRad\fR)
\fIy\(fm\fR = \fIoriginY\fR \(mi \fIrelX\fR \(mu sin(\fIangleRad\fR) + \fIrelY\fR \(mu cos(\fIangleRad\fR)
.CE
.PP
The control points for an item are not necessarily the coordinates provided to
the item when it is created (or via the \fItypePtr\->coordProc\fR), but could
instead be derived from them.







|
|







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
the item is to be rotated, and \fIangleRad\fR gives the anticlockwise
rotation to be applied in radians.
The item should adjust the coordinates of its control points so that where
they used to have coordinates \fIx\fR and \fIy\fR, they will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where
.PP
.CS
\fIrelX\fR = \fIx\fR \(mi \fIoriginX\fR
\fIrelY\fR = \fIy\fR \(mi \fIoriginY\fR
\fIx\(fm\fR = \fIoriginX\fR + \fIrelX\fR \(mu cos(\fIangleRad\fR) + \fIrelY\fR \(mu sin(\fIangleRad\fR)
\fIy\(fm\fR = \fIoriginY\fR \(mi \fIrelX\fR \(mu sin(\fIangleRad\fR) + \fIrelY\fR \(mu cos(\fIangleRad\fR)
.CE
.PP
The control points for an item are not necessarily the coordinates provided to
the item when it is created (or via the \fItypePtr\->coordProc\fR), but could
instead be derived from them.
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
.CE
.PP
The \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR arguments all
have the usual meaning.
\fIindexObj\fR contains a textual description of an index,
and \fIindexPtr\fR points to an integer value that should be
filled in with a numerical index.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIindexObj\fR parameter will
actually contain a pointer to a constant string.
It is up to the type manager to decide what forms of index
are supported (e.g., numbers, \fBinsert\fR, \fBsel.first\fR,
\fBend\fR, etc.).
\fIindexProc\fR should return a Tcl completion code and set
the interpreter result in the event of an error.
.SS ICURSORPROC
.PP







<
<
<







598
599
600
601
602
603
604



605
606
607
608
609
610
611
.CE
.PP
The \fIinterp\fR, \fIcanvas\fR, and \fIitemPtr\fR arguments all
have the usual meaning.
\fIindexObj\fR contains a textual description of an index,
and \fIindexPtr\fR points to an integer value that should be
filled in with a numerical index.



It is up to the type manager to decide what forms of index
are supported (e.g., numbers, \fBinsert\fR, \fBsel.first\fR,
\fBend\fR, etc.).
\fIindexProc\fR should return a Tcl completion code and set
the interpreter result in the event of an error.
.SS ICURSORPROC
.PP
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIindex\fR is an index into the item's text, as returned by a
previous call to \fItypePtr\->insertProc\fR, and \fIobj\fR
contains new text to insert just before the character given
by \fIindex\fR.
Note that if \fBTK_CONFIG_OBJS\fR is not set in the
\fItypePtr\->alwaysRedraw\fR field, the \fIobj\fR parameter will
actually contain a pointer to a constant string to be inserted.
If the item supports modification of the coordinates list by this
.PP
The type manager should insert the text and recompute the bounding
box in the item's header.
.SS DCHARSPROC
.PP
\fItypePtr\->dCharsProc\fR is invoked by Tk during the \fBdchars\fR







<
<
<







681
682
683
684
685
686
687



688
689
690
691
692
693
694
.CE
.PP
\fIcanvas\fR and \fIitemPtr\fR have the usual meanings.
\fIindex\fR is an index into the item's text, as returned by a
previous call to \fItypePtr\->insertProc\fR, and \fIobj\fR
contains new text to insert just before the character given
by \fIindex\fR.



If the item supports modification of the coordinates list by this
.PP
The type manager should insert the text and recompute the bounding
box in the item's header.
.SS DCHARSPROC
.PP
\fItypePtr\->dCharsProc\fR is invoked by Tk during the \fBdchars\fR

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
236
237
238
239
240
241
242


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

255
256
257
258
259
260
261
262
263

264
265

266



267
268
269
270
'\"
'\" 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"
.so man.macros
.BS
.SH NAME
Tk_CreatePhotoImageFormat \- define new file format for photo images
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR




.sp
\fBTk_CreatePhotoImageFormat\fR(\fIformatPtr\fR)
.SH ARGUMENTS
.AS "const Tk_PhotoImageFormat" *formatPtr




.AP "const Tk_PhotoImageFormat" *formatPtr in
Structure that defines the new file format.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreatePhotoImageFormat\fR is invoked to define a new file format
for image data for use with photo images.  The code that implements an
image file format is called an image file format handler, or
handler for short.  The photo image code
maintains a list of handlers that can be used to read and
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





An image file format handler consists of a collection of procedures
plus a Tk_PhotoImageFormat structure, which contains the name of the
image file format and pointers to six procedures provided by the
handler to deal with files and strings in this format.  The
Tk_PhotoImageFormat structure contains the following fields:

.CS
typedef struct Tk_PhotoImageFormat {
    const char *\fIname\fR;
    Tk_ImageFileMatchProc *\fIfileMatchProc\fR;
    Tk_ImageStringMatchProc *\fIstringMatchProc\fR;
    Tk_ImageFileReadProc *\fIfileReadProc\fR;
    Tk_ImageStringReadProc *\fIstringReadProc\fR;
    Tk_ImageFileWriteProc *\fIfileWriteProc\fR;
    Tk_ImageStringWriteProc *\fIstringWriteProc\fR;
} \fBTk_PhotoImageFormat\fR;
.CE

.PP
The handler need not provide implementations of all six procedures.
For example, the procedures that handle string data would not be
provided for a format in which the image data are stored in binary,
and could therefore contain null characters.  If any procedure is not
implemented, the corresponding pointer in the Tk_PhotoImageFormat
structure should be set to NULL.  The handler must provide the
\fIfileMatchProc\fR procedure if it provides the \fIfileReadProc\fR
procedure, and the \fIstringMatchProc\fR procedure if it provides the
\fIstringReadProc\fR procedure.
.SS NAME
.PP
\fIformatPtr->name\fR provides a name for the image type.
Once \fBTk_CreatePhotoImageFormat\fR returns, this name may be used
in the \fB\-format\fR photo image configuration and subcommand option.

The manual page for the photo image (photo(n)) describes how image
file formats are chosen based on their names and the value given to
the \fB\-format\fR option. The first character of \fIformatPtr->name\fR
must not be an uppercase character from the ASCII character set
(that is, one of the characters \fBA\fR-\fBZ\fR).  Such names are used
only for legacy interface support (see below).

.SS FILEMATCHPROC
.PP
\fIformatPtr->fileMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler
suitable for reading data in a given file.
\fIformatPtr->fileMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileMatchProc\fR(

        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,

        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
.CE
The \fIfileName\fR argument is the name of the file containing the
image data, which is open for reading as \fIchan\fR.  The
\fIformat\fR argument contains the value given for the
\fB\-format\fR option, or NULL if the option was not specified.


If the data in the file appears to be in the format supported by this
handler, the \fIformatPtr->fileMatchProc\fR procedure should store the
width and height of the image in *\fIwidthPtr\fR and *\fIheightPtr\fR
respectively, and return 1.  Otherwise it should return 0.
.SS STRINGMATCHPROC
.PP
\fIformatPtr->stringMatchProc\fR provides the address of a procedure for
Tk to call when it is searching for an image file format handler for
suitable for reading data from a given string.
\fIformatPtr->stringMatchProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringMatchProc\fR(

        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,

        int *\fIwidthPtr\fR,
        int *\fIheightPtr\fR,
        Tcl_Interp *\fIinterp\fR);
.CE
The \fIdata\fR argument points to the object containing the image
data.  The \fIformat\fR argument contains the value given for
the \fB\-format\fR option, or NULL if the option was not specified.


If the data in the string appears to be in the format supported by
this handler, the \fIformatPtr->stringMatchProc\fR procedure should
store the width and height of the image in *\fIwidthPtr\fR and
*\fIheightPtr\fR respectively, and return 1.  Otherwise it should
return 0.
.SS FILEREADPROC
.PP
\fIformatPtr->fileReadProc\fR provides the address of a procedure for
Tk to call to read data from an image file into a photo image.
\fIformatPtr->fileReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Channel \fIchan\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,

        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);

.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The image data is in the file named \fIfileName\fR, which is open for
reading as \fIchan\fR.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the file, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the file is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.


The return value is a standard Tcl return value.
.SS STRINGREADPROC
.PP
\fIformatPtr->stringReadProc\fR provides the address of a procedure for
Tk to call to read data from a string into a photo image.
\fIformatPtr->stringReadProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringReadProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIdata\fR,
        Tcl_Obj *\fIformat\fR,

        PhotoHandle \fIimageHandle\fR,
        int \fIdestX\fR, int \fIdestY\fR,
        int \fIwidth\fR, int \fIheight\fR,
        int \fIsrcX\fR, int \fIsrcY\fR);

.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to read the image; it should be used for reporting errors.
The \fIdata\fR argument points to the image data in object form.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The image data in the string, or a subimage of it, is to
be read into the photo image identified by the handle
\fIimageHandle\fR.  The subimage of the data in the string is of
dimensions \fIwidth\fR x \fIheight\fR and has its top-left corner at
coordinates (\fIsrcX\fR,\fIsrcY\fR).  It is to be stored in the photo
image with its top-left corner at coordinates
(\fIdestX\fR,\fIdestY\fR) using the \fBTk_PhotoPutBlock\fR procedure.


The return value is a standard Tcl return value.
.SS FILEWRITEPROC
.PP
\fIformatPtr->fileWriteProc\fR provides the address of a procedure for
Tk to call to write data from a photo image to a file.
\fIformatPtr->fileWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageFileWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIfileName\fR,
        Tcl_Obj *\fIformat\fR,

        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to write the image; it should be used for reporting errors.
The image data to be written are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The \fIfileName\fR argument
points to the string giving the name of the file in which to write the
image data.  The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->fileWriteProc\fR procedure may interpret these
characters to specify further details about the image file.


The return value is a standard Tcl return value.
.SS STRINGWRITEPROC
.PP
\fIformatPtr->stringWriteProc\fR provides the address of a procedure for
Tk to call to translate image data from a photo image into a string.

\fIformatPtr->stringWriteProc\fR must match the following prototype:
.CS
typedef int \fBTk_ImageStringWriteProc\fR(
        Tcl_Interp *\fIinterp\fR,
        Tcl_Obj *\fIformat\fR,

        Tk_PhotoImageBlock *\fIblockPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the command was
invoked to convert the image; it should be used for reporting errors.
The image data to be converted are in memory and are described by the
Tk_PhotoImageBlock structure pointed to by \fIblockPtr\fR; see the
manual page FindPhoto(3) for details.  The data for the string
should be put in the interpreter \fIinterp\fR result.
The \fIformat\fR argument contains the
value given for the \fB\-format\fR option, or NULL if the option was
not specified.  The format string can contain extra characters
after the name of the format.  If appropriate, the
\fIformatPtr->stringWriteProc\fR procedure may interpret these
characters to specify further details about the image file.


The return value is a standard Tcl return value.

.SH "LEGACY INTERFACE SUPPORT"













































































































































































.PP
In Tk 8.2 and earlier, the definition of all the function pointer
types stored in fields of a \fBTk_PhotoImageFormat\fR struct were
incompatibly different.  Legacy programs and libraries dating from
those days may still contain code that defines extended Tk photo image
formats using the old interface.  The Tk header file will still support
this legacy interface if the code is compiled with the
macro \fBUSE_OLD_IMAGE\fR defined.  Alternatively, the legacy interfaces
are used if the first character of \fIformatPtr->name\fR is an
uppercase ASCII character (\fBA\fR-\fBZ\fR), and explicit casts
are used to forgive the type mismatch.  For example,
.CS
static Tk_PhotoImageFormat myFormat = {


    "MyFormat",
    (Tk_ImageFileMatchProc *) FileMatch,
    NULL,
    (Tk_ImageFileReadProc *) FileRead,
    NULL,
    NULL,
    NULL
};
.CE
would define a minimal \fBTk_PhotoImageFormat\fR that operates provide
only file reading capability, where \fBFileMatch\fR and \fBFileRead\fR
are written according to the legacy interfaces of Tk 8.2 or earlier.

.PP
Any stub-enabled extension providing an extended photo image format
via the legacy interface enabled by the \fBUSE_OLD_IMAGE\fR macro
that is compiled against Tk 8.5 headers and linked against the
Tk 8.5 stub library will produce a file that can be loaded only
into interps with Tk 8.5 or later; that is, the normal stub-compatibility
rules.  If a developer needs to generate from such code a file
that is loadable into interps with Tk 8.4 or earlier, they must
use Tk 8.4 headers and stub libraries to do so.

.PP
Any new code written today should not make use of the legacy

interfaces.  Expect their support to go away in Tk 9.



.SH "SEE ALSO"
Tk_FindPhoto, Tk_PhotoPutBlock
.SH KEYWORDS
photo image, image file











|







>
>
>
>



|
>
>
>
>





|











>
>
>
>
>

|
|
|
|
>

|

|
|
|
|
|
|
|

>













|
|
>






>







|
>



>


|





>
>






|
|



|
>


>


|




>
>











|




>



|
>













>
>



|
|


|



>



|
>






|
|





>
>







|



>














>
>



|
|
>


|


>














>
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
<
<
<
<
<
<
|
<
<

|
>
>
|
|
<
<
<
<
<
<

<
<
<
>

<
<
<
<
<
<
<
<
>
|
<
>
|
>
>
>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444







445


446
447
448
449
450
451






452



453
454








455
456

457
458
459
460
461
462
463
464
465
'\"
'\" 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.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_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_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 \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 {
    const char *\fIname\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_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_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_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
suitable for reading data from a given string.
\fIformatPtr->stringMatchProc\fR must match the following prototype:
.CS
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_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_ImageFileReadProcVersion3\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,
        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 must match the following prototype:
.CS
typedef int \fBTk_ImageStringReadProcVersion3\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,
        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
\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_ImageFileWriteProcVersion3\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 must match the following prototype:
.CS
typedef int \fBTk_ImageStringWriteProcVersion3\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
.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:
.IP \(bu
Abbreviations are in upper case.
.IP \(bu
Words are in US English in small case (except proper nouns)
.IP \(bu
Vertical DPI is expressed as DPI/aspect. The reason is, that some
image formats may feature aspect and no resolution value.
.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));
    // use value reference in itemData
}
.CE
.PP
The \fB\-metadata\fR 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 \fB\-metadata\fR 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 \fB\-metadata\fR 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
metadata dict to return them.
Those functions get a Tcl object pointer \fImetadataOut\fR as
parameter.
\fImetadataOut\fR may be NULL to indicate, that no metadata return is
required (\fBput\fR, \fBread\fR subcommands). The variable pointed to
by \fImetadataOut\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)
.fi
.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 {
    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
.SH "SEE ALSO"
Tk_FindPhoto, Tk_PhotoPutBlock
.SH KEYWORDS
photo image, image file

Changes to doc/CrtSelHdlr.3.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateSelHandler\fR(\fItkwin, selection, target, proc, clientData, format\fR)
.sp
\fBTk_DeleteSelHandler\fR(\fItkwin, selection, target\fR)

.SH ARGUMENTS
.AS Tk_SelectionProc clientData
.AP Tk_Window tkwin in
Window for which \fIproc\fR will provide selection information.
.AP Atom selection in
The name of the selection for which \fIproc\fR will provide
selection information.
.AP Atom target in
Form in which \fIproc\fR can provide the selection (e.g. STRING
or FILE_NAME).  Corresponds to \fItype\fR arguments in \fBselection\fR
commands.
.AP Tk_SelectionProc *proc in
Procedure to invoke whenever the selection is owned by \fItkwin\fR
and the selection contents are requested in the format given by
\fItarget\fR.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP Atom format in
If the selection requestor is not in this process, \fIformat\fR determines
the representation used to transmit the selection to its
requestor.
.BE
.SH DESCRIPTION







>















|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateSelHandler\fR(\fItkwin, selection, target, proc, clientData, format\fR)
.sp
\fBTk_DeleteSelHandler\fR(\fItkwin, selection, target\fR)
.fi
.SH ARGUMENTS
.AS Tk_SelectionProc clientData
.AP Tk_Window tkwin in
Window for which \fIproc\fR will provide selection information.
.AP Atom selection in
The name of the selection for which \fIproc\fR will provide
selection information.
.AP Atom target in
Form in which \fIproc\fR can provide the selection (e.g. STRING
or FILE_NAME).  Corresponds to \fItype\fR arguments in \fBselection\fR
commands.
.AP Tk_SelectionProc *proc in
Procedure to invoke whenever the selection is owned by \fItkwin\fR
and the selection contents are requested in the format given by
\fItarget\fR.
.AP void *clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP Atom format in
If the selection requestor is not in this process, \fIformat\fR determines
the representation used to transmit the selection to its
requestor.
.BE
.SH DESCRIPTION
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
X Inter-Client Communication Conventions Manual (ICCCM) or
any other form in which an application is willing to present
the selection.  The most common form is STRING.
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_SelectionProc\fR:
.CS
typedef int \fBTk_SelectionProc\fR(
        ClientData \fIclientData\fR,
        int \fIoffset\fR,
        char *\fIbuffer\fR,
        int \fImaxBytes\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_CreateSelHandler\fR.
Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to retrieve the selection.  \fIOffset\fR specifies an
offset position into the selection, \fIbuffer\fR specifies a







|
|
|

|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
X Inter-Client Communication Conventions Manual (ICCCM) or
any other form in which an application is willing to present
the selection.  The most common form is STRING.
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_SelectionProc\fR:
.CS
typedef Tcl_Size \fBTk_SelectionProc\fR(
        void *\fIclientData\fR,
        Tcl_Size \fIoffset\fR,
        char *\fIbuffer\fR,
        Tcl_Size \fImaxBytes\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_CreateSelHandler\fR.
Typically, \fIclientData\fR points to a data
structure containing application-specific information that is
needed to retrieve the selection.  \fIOffset\fR specifies an
offset position into the selection, \fIbuffer\fR specifies a

Changes to doc/CrtWindow.3.

22
23
24
25
26
27
28

29
30
31
32
33
34
35
.sp
Tk_Window
\fBTk_CreateWindowFromPath\fR(\fIinterp, tkwin, pathName, topLevScreen\fR)
.sp
\fBTk_DestroyWindow\fR(\fItkwin\fR)
.sp
\fBTk_MakeWindowExist\fR(\fItkwin\fR)

.SH ARGUMENTS
.AS Tcl_Interp *topLevScreen
.AP Tcl_Interp *interp out
Tcl interpreter to use for error reporting.  If no error occurs,
then \fI*interp\fR is not modified.
.AP Tk_Window parent in
Token for the window that is to serve as the logical parent of







>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.sp
Tk_Window
\fBTk_CreateWindowFromPath\fR(\fIinterp, tkwin, pathName, topLevScreen\fR)
.sp
\fBTk_DestroyWindow\fR(\fItkwin\fR)
.sp
\fBTk_MakeWindowExist\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS Tcl_Interp *topLevScreen
.AP Tcl_Interp *interp out
Tcl interpreter to use for error reporting.  If no error occurs,
then \fI*interp\fR is not modified.
.AP Tk_Window parent in
Token for the window that is to serve as the logical parent of

Changes to doc/DeleteImg.3.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
.SH NAME
Tk_DeleteImage \- Destroy an image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_DeleteImage\fR(\fIinterp, name\fR)

.SH ARGUMENTS
.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Interpreter for which the image was created.
.AP "const char" *name in
Name of the image.
.BE







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.SH NAME
Tk_DeleteImage \- Destroy an image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_DeleteImage\fR(\fIinterp, name\fR)
.fi
.SH ARGUMENTS
.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Interpreter for which the image was created.
.AP "const char" *name in
Name of the image.
.BE

Changes to doc/DrawFocHlt.3.

9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
.BS
.SH NAME
Tk_DrawFocusHighlight \- draw the traversal highlight ring for a widget
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_DrawFocusHighlight(\fItkwin, gc, width, drawable\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tk_Window tkwin in
Window for which the highlight is being drawn.  Used to retrieve
the window's dimensions, among other things.
.AP GC gc in
Graphics context to use for drawing the highlight.







|
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.BS
.SH NAME
Tk_DrawFocusHighlight \- draw the traversal highlight ring for a widget
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_DrawFocusHighlight\fR(\fItkwin, gc, width, drawable\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tk_Window tkwin in
Window for which the highlight is being drawn.  Used to retrieve
the window's dimensions, among other things.
.AP GC gc in
Graphics context to use for drawing the highlight.

Changes to doc/EventHndlr.3.

17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
\fBTk_CreateEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_DeleteEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_GetButtonMask\fR(\fIbutton\fR)
.sp
\fBTk_SendVirtualEvent\fR(\fItkwin, eventName, detail\fR)

.SH ARGUMENTS
.AS "unsigned long" clientData
.AP unsigned button in
Button number.
.AP "const char" *eventName in
The name of the virtual event.
.AP Tcl_Obj *detail in
Detail information for the virtual event.
.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs
in the window given by \fItkwin\fR.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateEventHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever one of the event types specified
by \fImask\fR occurs in the window specified by \fItkwin\fR.
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_EventProc\fR:
.CS
typedef void \fBTk_EventProc\fR(
        ClientData \fIclientData\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateEventHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
the window in which the event occurred.  \fIEventPtr\fR is







>
















|

















|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
\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)
.fi
.SH ARGUMENTS
.AS "unsigned long" clientData
.AP unsigned button in
Button number.
.AP "const char" *eventName in
The name of the virtual event.
.AP Tcl_Obj *detail in
Detail information for the virtual event.
.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs
in the window given by \fItkwin\fR.
.AP void *clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_CreateEventHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever one of the event types specified
by \fImask\fR occurs in the window specified by \fItkwin\fR.
The callback to \fIproc\fR will be made by \fBTk_HandleEvent\fR;
this mechanism only works in programs that dispatch events
through \fBTk_HandleEvent\fR (or through other Tk procedures that
call \fBTk_HandleEvent\fR, such as \fBTcl_DoOneEvent\fR or
\fBTk_MainLoop\fR).
.PP
\fIProc\fR should have arguments and result that match the
type \fBTk_EventProc\fR:
.CS
typedef void \fBTk_EventProc\fR(
        void *\fIclientData\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
argument given to \fBTk_CreateEventHandler\fR when the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
the window in which the event occurred.  \fIEventPtr\fR is

Changes to doc/FindPhoto.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
int
\fBTk_PhotoPutZoomedBlock\fR(\fIinterp, handle, blockPtr, x, y, width, height,\
zoomX, zoomY, subsampleX, subsampleY, compRule\fR)
.sp
int
\fBTk_PhotoGetImage\fR(\fIhandle, blockPtr\fR)
.sp
void
\fBTk_PhotoBlank\fR(\fIhandle\fR)
.sp
int
\fBTk_PhotoExpand\fR(\fIinterp, handle, width, height\fR)
.sp
void
\fBTk_PhotoGetSize\fR(\fIhandle, widthPtr, heightPtr\fR)
.sp
int
\fBTk_PhotoSetSize\fR(\fIinterp. handle, width, height\fR)

.SH ARGUMENTS
.AS Tk_PhotoImageBlock window_path
.AP Tcl_Interp *interp in
Interpreter in which image was created and in which error reporting is
to be done.
.AP "const char" *imageName in
Name of the photo image.







<





<




>







28
29
30
31
32
33
34

35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
int
\fBTk_PhotoPutZoomedBlock\fR(\fIinterp, handle, blockPtr, x, y, width, height,\
zoomX, zoomY, subsampleX, subsampleY, compRule\fR)
.sp
int
\fBTk_PhotoGetImage\fR(\fIhandle, blockPtr\fR)
.sp

\fBTk_PhotoBlank\fR(\fIhandle\fR)
.sp
int
\fBTk_PhotoExpand\fR(\fIinterp, handle, width, height\fR)
.sp

\fBTk_PhotoGetSize\fR(\fIhandle, widthPtr, heightPtr\fR)
.sp
int
\fBTk_PhotoSetSize\fR(\fIinterp. handle, width, height\fR)
.fi
.SH ARGUMENTS
.AS Tk_PhotoImageBlock window_path
.AP Tcl_Interp *interp in
Interpreter in which image was created and in which error reporting is
to be done.
.AP "const char" *imageName in
Name of the photo image.
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
.SH BUGS
The \fBTk_PhotoImageBlock\fR structure used to provide image data to
\fBTk_PhotoPutBlock\fR promises great flexibility in the layout of the
data (e.g. separate planes for the red, green, blue and alpha
channels).  Unfortunately, the implementation fails to hold this
promise.  The problem is that the \fIpixelSize\fR field is
(incorrectly) used to determine whether the image has an alpha channel.
Currently, if the offset for the alpha channel is greater or equal than
\fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is
present and makes the image fully opaque.  This means that for layouts
where the channels are separate (or any other exotic layout where
\fIpixelSize\fR has to be smaller than the alpha offset), the alpha
channel will not be read correctly.  In order to be on the safe side
if this issue will be corrected in a future release, it is strongly
recommended you always provide alpha data - even if the image has no







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
.SH BUGS
The \fBTk_PhotoImageBlock\fR structure used to provide image data to
\fBTk_PhotoPutBlock\fR promises great flexibility in the layout of the
data (e.g. separate planes for the red, green, blue and alpha
channels).  Unfortunately, the implementation fails to hold this
promise.  The problem is that the \fIpixelSize\fR field is
(incorrectly) used to determine whether the image has an alpha channel.
Currently, if the offset for the alpha channel is greater than or equal to
\fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is
present and makes the image fully opaque.  This means that for layouts
where the channels are separate (or any other exotic layout where
\fIpixelSize\fR has to be smaller than the alpha offset), the alpha
channel will not be read correctly.  In order to be on the safe side
if this issue will be corrected in a future release, it is strongly
recommended you always provide alpha data - even if the image has no

Changes to doc/FontId.3.

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

24
25
26
27
28
29
30
Tk_FontId, Tk_GetFontMetrics, Tk_PostscriptFontName \- accessor functions for
fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Font
\fBTk_FontId(\fItkfont\fB)\fR
.sp
\fBTk_GetFontMetrics(\fItkfont, fmPtr\fB)\fR
.sp
int
\fBTk_PostscriptFontName(\fItkfont, dsPtr\fB)\fR

.SH ARGUMENTS
.AS Tk_FontMetrics *dsPtr
.AP Tk_Font tkfont in
Opaque font token being queried.  Must have been returned by a previous
call to \fBTk_GetFont\fR.
.AP Tk_FontMetrics *fmPtr out
Pointer to structure in which the font metrics for \fItkfont\fR will







|

|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Tk_FontId, Tk_GetFontMetrics, Tk_PostscriptFontName \- accessor functions for
fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Font
\fBTk_FontId\fR(\fItkfont\fR)
.sp
\fBTk_GetFontMetrics\fR(\fItkfont, fmPtr\fR)
.sp
int
\fBTk_PostscriptFontName\fR(\fItkfont, dsPtr\fR)
.fi
.SH ARGUMENTS
.AS Tk_FontMetrics *dsPtr
.AP Tk_Font tkfont in
Opaque font token being queried.  Must have been returned by a previous
call to \fBTk_GetFont\fR.
.AP Tk_FontMetrics *fmPtr out
Pointer to structure in which the font metrics for \fItkfont\fR will
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
Any other font families may not print correctly because the computed
Postscript font name may be incorrect or not exist on the printer.
.SH "DATA STRUCTURES"
.PP
The \fBTk_FontMetrics\fR data structure is used by \fBTk_GetFontMetrics\fR to
return information about a font and is defined as follows:
.CS
typedef struct Tk_FontMetrics {
    int \fIascent\fR;
    int \fIdescent\fR;
    int \fIlinespace\fR;
} \fBTk_FontMetrics\fR;
.CE
.PP
The \fIascent\fR field is the amount in pixels that the tallest







|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
Any other font families may not print correctly because the computed
Postscript font name may be incorrect or not exist on the printer.
.SH "DATA STRUCTURES"
.PP
The \fBTk_FontMetrics\fR data structure is used by \fBTk_GetFontMetrics\fR to
return information about a font and is defined as follows:
.CS
typedef struct {
    int \fIascent\fR;
    int \fIdescent\fR;
    int \fIlinespace\fR;
} \fBTk_FontMetrics\fR;
.CE
.PP
The \fIascent\fR field is the amount in pixels that the tallest

Deleted doc/FreeXId.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_FreeXId 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_FreeXId \- make X resource identifier available for reuse
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_FreeXId(\fIdisplay, id\fB)\fR
.SH ARGUMENTS
.AS Display *display out
.AP Display *display in
Display for which \fIid\fR was allocated.
.AP XID id in
Identifier of X resource (window, font, pixmap, cursor, graphics
context, or colormap) that is no longer in use.
.BE
.SH DESCRIPTION
.PP
This function is deprecated, it doesn't do anything since 2008-08-19.
.SH KEYWORDS
resource identifier
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































Changes to doc/GeomReq.3.

17
18
19
20
21
22
23

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

40
41

42
43

44
45

46
47
48
49
50
51
52
\fBTk_GeometryRequest\fR(\fItkwin, reqWidth, reqHeight\fR)
.sp
\fBTk_SetMinimumRequestSize\fR(\fItkwin, minWidth, minHeight\fR)
.sp
\fBTk_SetInternalBorder\fR(\fItkwin, width\fR)
.sp
\fBTk_SetInternalBorderEx\fR(\fItkwin, left, right, top, bottom\fR)

.SH ARGUMENTS
.AS baseHeight clientData
.AP Tk_Window tkwin in
Window for which geometry is being requested.
.AP int reqWidth in
Desired width for \fItkwin\fR, in pixel units.
.AP int reqHeight in
Desired height for \fItkwin\fR, in pixel units.
.AP int minWidth in
Desired minimum requested width for \fItkwin\fR, in pixel units.
.AP int minHeight in
Desired minimum requested height for \fItkwin\fR, in pixel units.
.AP int width in
Space to leave for internal border for \fItkwin\fR, in pixel units.
.AP int left in
Space to leave for left side of internal border for \fItkwin\fR, in pixel units.

.AP int right in
Space to leave for right side of internal border for \fItkwin\fR, in pixel units.

.AP int top in
Space to leave for top side of internal border for \fItkwin\fR, in pixel units.

.AP int bottom in
Space to leave for bottom side of internal border for \fItkwin\fR, in pixel units.

.BE
.SH DESCRIPTION
.PP
\fBTk_GeometryRequest\fR is called by widget code to indicate its
preference for the dimensions of a particular window.  The arguments
to \fBTk_GeometryRequest\fR are made available to the geometry
manager for the window, which then decides on the actual geometry







>















|
>

|
>

|
>

|
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
\fBTk_GeometryRequest\fR(\fItkwin, reqWidth, reqHeight\fR)
.sp
\fBTk_SetMinimumRequestSize\fR(\fItkwin, minWidth, minHeight\fR)
.sp
\fBTk_SetInternalBorder\fR(\fItkwin, width\fR)
.sp
\fBTk_SetInternalBorderEx\fR(\fItkwin, left, right, top, bottom\fR)
.fi
.SH ARGUMENTS
.AS baseHeight clientData
.AP Tk_Window tkwin in
Window for which geometry is being requested.
.AP int reqWidth in
Desired width for \fItkwin\fR, in pixel units.
.AP int reqHeight in
Desired height for \fItkwin\fR, in pixel units.
.AP int minWidth in
Desired minimum requested width for \fItkwin\fR, in pixel units.
.AP int minHeight in
Desired minimum requested height for \fItkwin\fR, in pixel units.
.AP int width in
Space to leave for internal border for \fItkwin\fR, in pixel units.
.AP int left in
Space to leave for left side of internal border for \fItkwin\fR,
in pixel units.
.AP int right in
Space to leave for right side of internal border for \fItkwin\fR,
in pixel units.
.AP int top in
Space to leave for top side of internal border for \fItkwin\fR,
in pixel units.
.AP int bottom in
Space to leave for bottom side of internal border for \fItkwin\fR,
in pixel units.
.BE
.SH DESCRIPTION
.PP
\fBTk_GeometryRequest\fR is called by widget code to indicate its
preference for the dimensions of a particular window.  The arguments
to \fBTk_GeometryRequest\fR are made available to the geometry
manager for the window, which then decides on the actual geometry

Changes to doc/GetAnchor.3.

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

25
26
27
28
29
30
31
.SH NAME
Tk_GetAnchorFromObj, Tk_GetAnchor, Tk_NameOfAnchor \- translate between strings and anchor positions
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetAnchorFromObj(\fIinterp, objPtr, anchorPtr\fB)\fR
.sp
int
\fBTk_GetAnchor(\fIinterp, string, anchorPtr\fB)\fR
.sp
const char *
\fBTk_NameOfAnchor(\fIanchor\fB)\fR

.SH ARGUMENTS
.AS "Tk_Anchor" *anchorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of anchor point:
.QW \fBn\fR  ,







|


|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.SH NAME
Tk_GetAnchorFromObj, Tk_GetAnchor, Tk_NameOfAnchor \- translate between strings and anchor positions
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetAnchorFromObj\fR(\fIinterp, objPtr, anchorPtr\fR)
.sp
int
\fBTk_GetAnchor\fR(\fIinterp, string, anchorPtr\fR)
.sp
const char *
\fBTk_NameOfAnchor\fR(\fIanchor\fR)
.fi
.SH ARGUMENTS
.AS "Tk_Anchor" *anchorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of anchor point:
.QW \fBn\fR  ,

Changes to doc/GetBitmap.3.

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

37
38
39
40
41
42
43
.SH NAME
Tk_AllocBitmapFromObj, Tk_GetBitmap, Tk_GetBitmapFromObj, Tk_DefineBitmap, Tk_NameOfBitmap, Tk_SizeOfBitmap, Tk_FreeBitmapFromObj, Tk_FreeBitmap \- maintain database of single-plane pixmaps
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Pixmap
\fBTk_AllocBitmapFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Pixmap
\fBTk_GetBitmap(\fIinterp, tkwin, info\fB)\fR
.sp
Pixmap
\fBTk_GetBitmapFromObj(\fItkwin, objPtr\fB)\fR
.sp
int
\fBTk_DefineBitmap(\fIinterp, name, source, width, height\fB)\fR
.sp
const char *
\fBTk_NameOfBitmap(\fIdisplay, bitmap\fB)\fR
.sp
\fBTk_SizeOfBitmap(\fIdisplay, bitmap, widthPtr, heightPtr\fB)\fR
.sp
\fBTk_FreeBitmapFromObj(\fItkwin, objPtr\fB)\fR
.sp
\fBTk_FreeBitmap(\fIdisplay, bitmap\fB)\fR

.SH ARGUMENTS
.AS "unsigned long" *pixelPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting; if NULL then no error message
is left after errors.
.AP Tk_Window tkwin in
Token for window in which the bitmap will be used.







|


|


|


|


|

|

|

|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
.SH NAME
Tk_AllocBitmapFromObj, Tk_GetBitmap, Tk_GetBitmapFromObj, Tk_DefineBitmap, Tk_NameOfBitmap, Tk_SizeOfBitmap, Tk_FreeBitmapFromObj, Tk_FreeBitmap \- maintain database of single-plane pixmaps
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Pixmap
\fBTk_AllocBitmapFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
Pixmap
\fBTk_GetBitmap\fR(\fIinterp, tkwin, info\fR)
.sp
Pixmap
\fBTk_GetBitmapFromObj\fR(\fItkwin, objPtr\fR)
.sp
int
\fBTk_DefineBitmap\fR(\fIinterp, name, source, width, height\fR)
.sp
const char *
\fBTk_NameOfBitmap\fR(\fIdisplay, bitmap\fR)
.sp
\fBTk_SizeOfBitmap\fR(\fIdisplay, bitmap, widthPtr, heightPtr\fR)
.sp
\fBTk_FreeBitmapFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_FreeBitmap\fR(\fIdisplay, bitmap\fR)
.fi
.SH ARGUMENTS
.AS "unsigned long" *pixelPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting; if NULL then no error message
is left after errors.
.AP Tk_Window tkwin in
Token for window in which the bitmap will be used.
76
77
78
79
80
81
82

83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
\fBTk_AllocBitmapFromObj\fR returns a Pixmap identifier for a bitmap
that matches the description in \fIobjPtr\fR and is suitable for use
in \fItkwin\fR.  It re-uses an existing bitmap, if possible, and
creates a new one otherwise.  \fIObjPtr\fR's value must have one
of the following forms:
.TP 20
\fB@\fIfileName\fR

\fIFileName\fR must be the name of a file containing a bitmap
description in the standard X11 format.
.TP 20
\fIname\fR

\fIName\fR must be the name of a bitmap defined previously with
a call to \fBTk_DefineBitmap\fR.  The following names are pre-defined
by Tk:
.RS
.TP 12
\fBerror\fR
The international
.QW don't
symbol:  a circle with a diagonal line across it.
.TP 12
\fBgray75\fR
75% gray: a checkerboard pattern where three out of four bits are on.
.TP 12
\fBgray50\fR
50% gray: a checkerboard pattern where every other bit is on.
.TP 12
\fBgray25\fR
25% gray: a checkerboard pattern where one out of every four bits is on.
.TP 12
\fBgray12\fR
12.5% gray: a pattern where one-eighth of the bits are on, consisting of
every fourth pixel in every other row.
.TP 12
\fBhourglass\fR
An hourglass symbol.
.TP 12
\fBinfo\fR
A large letter
.QW i .
.TP 12
\fBquesthead\fR
The silhouette of a human head, with a question mark in it.
.TP 12
\fBquestion\fR
A large question-mark.
.TP 12
\fBwarning\fR
A large exclamation point.
.PP
In addition, the following pre-defined names are available only on the
\fBMacintosh\fR platform:
.TP 12
\fBdocument\fR
A generic document.
.TP 12
\fBstationery\fR
Document stationery.
.TP 12
\fBedition\fR
The \fIedition\fR symbol.
.TP 12
\fBapplication\fR
Generic application icon.
.TP 12
\fBaccessory\fR
A desk accessory.
.TP 12
\fBfolder\fR
Generic folder icon.
.TP 12
\fBpfolder\fR
A locked folder.
.TP 12
\fBtrash\fR
A trash can.
.TP 12
\fBfloppy\fR
A floppy disk.
.TP 12
\fBramdisk\fR
A floppy disk with chip.
.TP 12
\fBcdrom\fR
A cd disk icon.
.TP 12
\fBpreferences\fR
A folder with prefs symbol.
.TP 12
\fBquerydoc\fR
A database document icon.
.TP 12
\fBstop\fR
A stop sign.
.TP 12
\fBnote\fR
A face with balloon words.
.TP 12
\fBcaution\fR
A triangle with an exclamation point.
.RE
.LP
Under normal conditions, \fBTk_AllocBitmapFromObj\fR
returns an identifier for the requested bitmap.  If an error
occurs in creating the bitmap, such as when \fIobjPtr\fR refers
to a non-existent file, then \fBNone\fR is returned and an error







>




>




<
|



<
|

<
|

<
|

<
|


<
|

<
|


<
|

<
|

<
|




<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|







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

94
95
96
97

98
99

100
101

102
103

104
105
106

107
108

109
110
111

112
113

114
115

116
117
118
119
120

121
122

123
124

125
126

127
128

129
130

131
132

133
134

135
136

137
138

139
140

141
142

143
144

145
146

147
148

149
150

151
152
153
154
155
156
157
158
\fBTk_AllocBitmapFromObj\fR returns a Pixmap identifier for a bitmap
that matches the description in \fIobjPtr\fR and is suitable for use
in \fItkwin\fR.  It re-uses an existing bitmap, if possible, and
creates a new one otherwise.  \fIObjPtr\fR's value must have one
of the following forms:
.TP 20
\fB@\fIfileName\fR
.
\fIFileName\fR must be the name of a file containing a bitmap
description in the standard X11 format.
.TP 20
\fIname\fR
.
\fIName\fR must be the name of a bitmap defined previously with
a call to \fBTk_DefineBitmap\fR.  The following names are pre-defined
by Tk:
.RS

.IP \fBerror\fR 12
The international
.QW don't
symbol:  a circle with a diagonal line across it.

.IP \fBgray75\fR 12
75% gray: a checkerboard pattern where three out of four bits are on.

.IP \fBgray50\fR 12
50% gray: a checkerboard pattern where every other bit is on.

.IP \fBgray25\fR 12
25% gray: a checkerboard pattern where one out of every four bits is on.

.IP \fBgray12\fR 12
12.5% gray: a pattern where one-eighth of the bits are on, consisting of
every fourth pixel in every other row.

.IP \fBhourglass\fR 12
An hourglass symbol.

.IP \fBinfo\fR 12
A large letter
.QW i .

.IP \fBquesthead\fR 12
The silhouette of a human head, with a question mark in it.

.IP \fBquestion\fR 12
A large question-mark.

.IP \fBwarning\fR 12
A large exclamation point.
.PP
In addition, the following pre-defined names are available only on the
\fBMacintosh\fR platform:

.IP \fBdocument\fR 12
A generic document.

.IP \fBstationery\fR 12
Document stationery.

.IP \fBedition\fR 12
The \fIedition\fR symbol.

.IP \fBapplication\fR 12
Generic application icon.

.IP \fBaccessory\fR 12
A desk accessory.

.IP \fBfolder\fR 12
Generic folder icon.

.IP \fBpfolder\fR 12
A locked folder.

.IP \fBtrash\fR 12
A trash can.

.IP \fBfloppy\fR 12
A floppy disk.

.IP \fBramdisk\fR 12
A floppy disk with chip.

.IP \fBcdrom\fR 12
A cd disk icon.

.IP \fBpreferences\fR 12
A folder with prefs symbol.

.IP \fBquerydoc\fR 12
A database document icon.

.IP \fBstop\fR 12
A stop sign.

.IP \fBnote\fR 12
A face with balloon words.

.IP \fBcaution\fR 12
A triangle with an exclamation point.
.RE
.LP
Under normal conditions, \fBTk_AllocBitmapFromObj\fR
returns an identifier for the requested bitmap.  If an error
occurs in creating the bitmap, such as when \fIobjPtr\fR refers
to a non-existent file, then \fBNone\fR is returned and an error
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
have been used in a call to \fBTk_DefineBitmap\fR.
The arguments \fIsource\fR, \fIwidth\fR, and \fIheight\fR
describe the bitmap.
\fBTk_DefineBitmap\fR normally returns \fBTCL_OK\fR; if an error occurs
(e.g. a bitmap named \fInameId\fR has already been defined) then
\fBTCL_ERROR\fR is returned and an error message is left in
interpreter \fIinterp\fR's result.
Note:  \fBTk_DefineBitmap\fR expects the memory pointed to by
\fIsource\fR to be static:  \fBTk_DefineBitmap\fR does not make
a private copy of this memory, but uses the bytes pointed to
by \fIsource\fR later in calls to \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.
.PP
Typically \fBTk_DefineBitmap\fR is used by \fB#include\fR-ing a
bitmap file directly into a C program and then referencing







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
have been used in a call to \fBTk_DefineBitmap\fR.
The arguments \fIsource\fR, \fIwidth\fR, and \fIheight\fR
describe the bitmap.
\fBTk_DefineBitmap\fR normally returns \fBTCL_OK\fR; if an error occurs
(e.g. a bitmap named \fInameId\fR has already been defined) then
\fBTCL_ERROR\fR is returned and an error message is left in
interpreter \fIinterp\fR's result.
Note that \fBTk_DefineBitmap\fR expects the memory pointed to by
\fIsource\fR to be static:  \fBTk_DefineBitmap\fR does not make
a private copy of this memory, but uses the bytes pointed to
by \fIsource\fR later in calls to \fBTk_AllocBitmapFromObj\fR or
\fBTk_GetBitmap\fR.
.PP
Typically \fBTk_DefineBitmap\fR is used by \fB#include\fR-ing a
bitmap file directly into a C program and then referencing

Changes to doc/GetCapStyl.3.

11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
.SH NAME
Tk_GetCapStyle, Tk_NameOfCapStyle \- translate between strings and cap styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetCapStyle(\fIinterp, string, capPtr\fB)\fR
.sp
const char *
\fBTk_NameOfCapStyle(\fIcap\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *capPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of cap style \- one of
.QW \fBbutt\fR ,







|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.SH NAME
Tk_GetCapStyle, Tk_NameOfCapStyle \- translate between strings and cap styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetCapStyle\fR(\fIinterp, string, capPtr\fR)
.sp
const char *
\fBTk_NameOfCapStyle\fR(\fIcap\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *capPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of cap style \- one of
.QW \fBbutt\fR ,

Changes to doc/GetClrmap.3.

11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
.SH NAME
Tk_GetColormap, Tk_PreserveColormap, Tk_FreeColormap \- allocate and free colormaps
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Colormap
\fBTk_GetColormap(\fIinterp, tkwin, string\fB)\fR
.sp
\fBTk_PreserveColormap(\fIdisplay, colormap\fB)\fR
.sp
\fBTk_FreeColormap(\fIdisplay, colormap\fB)\fR

.SH ARGUMENTS
.AS "Colormap" colormap
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which colormap will be used.
.AP "const char" *string in







|

|

|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.SH NAME
Tk_GetColormap, Tk_PreserveColormap, Tk_FreeColormap \- allocate and free colormaps
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Colormap
\fBTk_GetColormap\fR(\fIinterp, tkwin, string\fR)
.sp
\fBTk_PreserveColormap\fR(\fIdisplay, colormap\fR)
.sp
\fBTk_FreeColormap\fR(\fIdisplay, colormap\fR)
.fi
.SH ARGUMENTS
.AS "Colormap" colormap
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which colormap will be used.
.AP "const char" *string in

Changes to doc/GetColor.3.

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

38
39
40
41
42
43
44
.SH NAME
Tk_AllocColorFromObj, Tk_GetColor, Tk_GetColorFromObj, Tk_GetColorByValue, Tk_NameOfColor, Tk_FreeColorFromObj, Tk_FreeColor \- maintain database of colors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
XColor *
\fBTk_AllocColorFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
XColor *
\fBTk_GetColor(\fIinterp, tkwin, name\fB)\fR
.sp
XColor *
\fBTk_GetColorFromObj(\fItkwin, objPtr\fB)\fR
.sp
XColor *
\fBTk_GetColorByValue(\fItkwin, prefPtr\fB)\fR
.sp
const char *
\fBTk_NameOfColor(\fIcolorPtr\fB)\fR
.sp
GC
\fBTk_GCForColor(\fIcolorPtr, drawable\fB)\fR
.sp
\fBTk_FreeColorFromObj(\fItkwin, objPtr\fB)\fR
.sp
\fBTk_FreeColor(\fIcolorPtr\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *colorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which color will be used.
.AP Tcl_Obj *objPtr in/out







|


|


|


|


|


|

|

|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.SH NAME
Tk_AllocColorFromObj, Tk_GetColor, Tk_GetColorFromObj, Tk_GetColorByValue, Tk_NameOfColor, Tk_FreeColorFromObj, Tk_FreeColor \- maintain database of colors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
XColor *
\fBTk_AllocColorFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
XColor *
\fBTk_GetColor\fR(\fIinterp, tkwin, name\fR)
.sp
XColor *
\fBTk_GetColorFromObj\fR(\fItkwin, objPtr\fR)
.sp
XColor *
\fBTk_GetColorByValue\fR(\fItkwin, prefPtr\fR)
.sp
const char *
\fBTk_NameOfColor\fR(\fIcolorPtr\fR)
.sp
GC
\fBTk_GCForColor\fR(\fIcolorPtr, drawable\fR)
.sp
\fBTk_FreeColorFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_FreeColor\fR(\fIcolorPtr\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *colorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which color will be used.
.AP Tcl_Obj *objPtr in/out
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
.PP
Given a textual description of a color, \fBTk_AllocColorFromObj\fR
locates a pixel value that may be used to render the color
in a particular window.  The desired color is specified with a
value whose string value must have one of the following forms:
.TP 20
\fIcolorname\fR

Any of the valid textual names for a color defined in the
server's color database file, such as \fBred\fR or \fBPeachPuff\fR.
.TP 20
\fB#\fIRGB\fR
.TP 20
\fB#\fIRRGGBB\fR
.TP 20
\fB#\fIRRRGGGBBB\fR
.TP 20
\fB#\fIRRRRGGGGBBBB\fR

A numeric specification of the red, green, and blue intensities
to use to display the color.  Each \fIR\fR, \fIG\fR, or \fIB\fR
represents a single hexadecimal digit.  The four forms permit
colors to be specified with 4-bit, 8-bit, 12-bit or 16-bit values.
When fewer than 16 bits are provided for each color, they represent
the most significant bits of the color, while the lower unfilled
bits will be repeatedly replicated from the available higher bits.







>










>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
.PP
Given a textual description of a color, \fBTk_AllocColorFromObj\fR
locates a pixel value that may be used to render the color
in a particular window.  The desired color is specified with a
value whose string value must have one of the following forms:
.TP 20
\fIcolorname\fR
.
Any of the valid textual names for a color defined in the
server's color database file, such as \fBred\fR or \fBPeachPuff\fR.
.TP 20
\fB#\fIRGB\fR
.TP 20
\fB#\fIRRGGBB\fR
.TP 20
\fB#\fIRRRGGGBBB\fR
.TP 20
\fB#\fIRRRRGGGGBBBB\fR
.
A numeric specification of the red, green, and blue intensities
to use to display the color.  Each \fIR\fR, \fIG\fR, or \fIB\fR
represents a single hexadecimal digit.  The four forms permit
colors to be specified with 4-bit, 8-bit, 12-bit or 16-bit values.
When fewer than 16 bits are provided for each color, they represent
the most significant bits of the color, while the lower unfilled
bits will be repeatedly replicated from the available higher bits.

Changes to doc/GetCursor.3.

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

35
36
37
38
39
40
41
.SH NAME
Tk_AllocCursorFromObj, Tk_GetCursor, Tk_GetCursorFromObj, Tk_GetCursorFromData, Tk_NameOfCursor, Tk_FreeCursorFromObj, Tk_FreeCursor \- maintain database of cursors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Cursor
\fBTk_AllocCursorFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Tk_Cursor
\fBTk_GetCursor(\fIinterp, tkwin, name\fB)\fR
.sp
Tk_Cursor
\fBTk_GetCursorFromObj(\fItkwin, objPtr\fB)\fR
.sp
Tk_Cursor
\fBTk_GetCursorFromData(\fIinterp, tkwin, source, mask, width, height, xHot, yHot, fg, bg\fB)\fR
.sp
const char *
\fBTk_NameOfCursor(\fIdisplay, cursor\fB)\fR
.sp
\fBTk_FreeCursorFromObj(\fItkwin, objPtr\fB)\fR
.sp
\fBTk_FreeCursor(\fIdisplay, cursor\fB)\fR

.SH ARGUMENTS
.AS "unsigned long" *pixelPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which the cursor will be used.
.AP Tcl_Obj *objPtr in/out







|


|


|


|


|

|

|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.SH NAME
Tk_AllocCursorFromObj, Tk_GetCursor, Tk_GetCursorFromObj, Tk_GetCursorFromData, Tk_NameOfCursor, Tk_FreeCursorFromObj, Tk_FreeCursor \- maintain database of cursors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Cursor
\fBTk_AllocCursorFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
Tk_Cursor
\fBTk_GetCursor\fR(\fIinterp, tkwin, name\fR)
.sp
Tk_Cursor
\fBTk_GetCursorFromObj\fR(\fItkwin, objPtr\fR)
.sp
Tk_Cursor
\fBTk_GetCursorFromData\fR(\fIinterp, tkwin, source, mask, width, height, xHot, yHot, fg, bg\fR)
.sp
const char *
\fBTk_NameOfCursor\fR(\fIdisplay, cursor\fR)
.sp
\fBTk_FreeCursorFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_FreeCursor\fR(\fIdisplay, cursor\fR)
.fi
.SH ARGUMENTS
.AS "unsigned long" *pixelPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which the cursor will be used.
.AP Tcl_Obj *objPtr in/out
83
84
85
86
87
88
89

90
91
92
93
94
95
96
\fBTk_GetCursorFromObj\fR. If an error occurs in creating the cursor,
such as when \fIobjPtr\fR refers to a non-existent file, then \fBNone\fR
is returned and an error message will be stored in \fIinterp\fR's result
if \fIinterp\fR is not NULL.  \fIObjPtr\fR must contain a standard Tcl
list with one of the following forms:
.TP
\fIname\fR\0[\fIfgColor\fR\0[\fIbgColor\fR]]

\fIName\fR is the name of a cursor in the standard X cursor cursor,
i.e., any of the names defined in \fBcursorcursor.h\fR, without
the \fBXC_\fR.  Some example values are \fBX_cursor\fR, \fBhand2\fR,
or \fBleft_ptr\fR.  Appendix B of
.QW "The X Window System"
by Scheifler & Gettys has illustrations showing what each of these
cursors looks like.  If \fIfgColor\fR and \fIbgColor\fR are both







>







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

118
119
120
121
122
123
124
125
126

127
128
129
130
131
132

133
134
135
136
137
138
139
name of the resource.  The application and all its open
dynamic library's resource files will be searched for the named
cursor.  If there are conflicts color cursors will always be loaded
in preference to black and white cursors.
.RE
.TP
\fB@\fIsourceName\0maskName\0fgColor\0bgColor\fR

In this form, \fIsourceName\fR and \fImaskName\fR are the names of
files describing cursors for the cursor's source bits and mask.
Each file must be in standard X11 cursor format.
\fIFgColor\fR and \fIbgColor\fR
indicate the colors to use for the
cursor, in any of the forms acceptable to \fBTk_GetColor\fR.  This
form of the command will not work on Macintosh or Windows computers.
.TP
\fB@\fIsourceName\0fgColor\fR

This form is similar to the one above, except that the source is
used as mask also.  This means that the cursor's background is
transparent.  This form of the command will not work on Macintosh
or Windows computers.
.TP
\fB@\fIsourceName\fR

This form only works on Windows, and will load a Windows system
cursor (\fB.ani\fR or \fB.cur\fR) from the file specified in
\fIsourceName\fR.
.PP
\fBTk_GetCursor\fR is identical to \fBTk_AllocCursorFromObj\fR except
that the description of the cursor is specified with a string instead
of an object.  This prevents \fBTk_GetCursor\fR from caching the







>









>






>







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
name of the resource.  The application and all its open
dynamic library's resource files will be searched for the named
cursor.  If there are conflicts color cursors will always be loaded
in preference to black and white cursors.
.RE
.TP
\fB@\fIsourceName\0maskName\0fgColor\0bgColor\fR
.
In this form, \fIsourceName\fR and \fImaskName\fR are the names of
files describing cursors for the cursor's source bits and mask.
Each file must be in standard X11 cursor format.
\fIFgColor\fR and \fIbgColor\fR
indicate the colors to use for the
cursor, in any of the forms acceptable to \fBTk_GetColor\fR.  This
form of the command will not work on Macintosh or Windows computers.
.TP
\fB@\fIsourceName\0fgColor\fR
.
This form is similar to the one above, except that the source is
used as mask also.  This means that the cursor's background is
transparent.  This form of the command will not work on Macintosh
or Windows computers.
.TP
\fB@\fIsourceName\fR
.
This form only works on Windows, and will load a Windows system
cursor (\fB.ani\fR or \fB.cur\fR) from the file specified in
\fIsourceName\fR.
.PP
\fBTk_GetCursor\fR is identical to \fBTk_AllocCursorFromObj\fR except
that the description of the cursor is specified with a string instead
of an object.  This prevents \fBTk_GetCursor\fR from caching the
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
The procedure \fBTk_NameOfCursor\fR is roughly the inverse of
\fBTk_GetCursor\fR.  If its \fIcursor\fR argument was created
by \fBTk_GetCursor\fR, then the return value is the \fIname\fR
argument that was passed to \fBTk_GetCursor\fR to create the
cursor.  If \fIcursor\fR was created by a call to \fBTk_GetCursorFromData\fR,
or by any other mechanism, then the return value is a hexadecimal string
giving the X identifier for the cursor.
Note:  the string returned by \fBTk_NameOfCursor\fR is
only guaranteed to persist until the next call to
\fBTk_NameOfCursor\fR.  Also, this call is not portable except for
cursors returned by \fBTk_GetCursor\fR.
.PP
When a cursor returned by \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
or \fBTk_GetCursorFromData\fR
is no longer needed, \fBTk_FreeCursorFromObj\fR or







|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
The procedure \fBTk_NameOfCursor\fR is roughly the inverse of
\fBTk_GetCursor\fR.  If its \fIcursor\fR argument was created
by \fBTk_GetCursor\fR, then the return value is the \fIname\fR
argument that was passed to \fBTk_GetCursor\fR to create the
cursor.  If \fIcursor\fR was created by a call to \fBTk_GetCursorFromData\fR,
or by any other mechanism, then the return value is a hexadecimal string
giving the X identifier for the cursor.
Note that the string returned by \fBTk_NameOfCursor\fR is
only guaranteed to persist until the next call to
\fBTk_NameOfCursor\fR.  Also, this call is not portable except for
cursors returned by \fBTk_GetCursor\fR.
.PP
When a cursor returned by \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
or \fBTk_GetCursorFromData\fR
is no longer needed, \fBTk_FreeCursorFromObj\fR or

Changes to doc/GetFont.3.

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

37
38
39
40
41
42
43
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FontGetDescription, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Font
\fBTk_AllocFontFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Tk_Font
\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR
.sp
Tk_Font
\fBTk_GetFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
Tcl_Obj *
\fBTk_FontGetDescription(\fItkfont\fB)\fR
.sp
const char *
\fBTk_NameOfFont(\fItkfont\fB)\fR
.sp
Tk_Font
\fBTk_FreeFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
void
\fBTk_FreeFont(\fItkfont\fB)\fR

.SH ARGUMENTS
.AS "const char" *tkfont
.AP "Tcl_Interp" *interp in
Interpreter to use for error reporting.  If \fBNULL\fR, then no error
messages are left after errors.
.AP Tk_Window tkwin in
Token for window in which font will be used.







|


|


|


|


|


|

<
|
>







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

35
36
37
38
39
40
41
42
43
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FontGetDescription, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Font
\fBTk_AllocFontFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
Tk_Font
\fBTk_GetFont\fR(\fIinterp, tkwin, string\fR)
.sp
Tk_Font
\fBTk_GetFontFromObj\fR(\fItkwin, objPtr\fR)
.sp
Tcl_Obj *
\fBTk_FontGetDescription\fR(\fItkfont\fR)
.sp
const char *
\fBTk_NameOfFont\fR(\fItkfont\fR)
.sp
Tk_Font
\fBTk_FreeFontFromObj\fR(\fItkwin, objPtr\fR)
.sp

\fBTk_FreeFont\fR(\fItkfont\fR)
.fi
.SH ARGUMENTS
.AS "const char" *tkfont
.AP "Tcl_Interp" *interp in
Interpreter to use for error reporting.  If \fBNULL\fR, then no error
messages are left after errors.
.AP Tk_Window tkwin in
Token for window in which font will be used.
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
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







|
>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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
.QW "{{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

Changes to doc/GetGC.3.

13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
GC
\fBTk_GetGC\fR(\fItkwin, valueMask, valuePtr\fR)
.sp
\fBTk_FreeGC(\fIdisplay, gc\fR)

.SH ARGUMENTS
.AS "unsigned long" valueMask
.AP Tk_Window tkwin in
Token for window in which the graphics context will be used.
.AP "unsigned long" valueMask in
Mask of bits (such as \fBGCForeground\fR or \fBGCStipple\fR)
indicating which fields of \fI*valuePtr\fR are valid.







|
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
GC
\fBTk_GetGC\fR(\fItkwin, valueMask, valuePtr\fR)
.sp
\fBTk_FreeGC\fR(\fIdisplay, gc\fR)
.fi
.SH ARGUMENTS
.AS "unsigned long" valueMask
.AP Tk_Window tkwin in
Token for window in which the graphics context will be used.
.AP "unsigned long" valueMask in
Mask of bits (such as \fBGCForeground\fR or \fBGCStipple\fR)
indicating which fields of \fI*valuePtr\fR are valid.

Changes to doc/GetHINSTANCE.3.

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

16
17
18
19
20
21
22
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_GetHISTANCE 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHINSTANCE \- retrieve the global application instance handle
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
HINSTANCE
\fBTk_GetHINSTANCE\fR()

.BE
.SH DESCRIPTION
.PP
\fBTk_GetHINSTANCE\fR returns the Windows application instance handle
for the Tk application.  This function is only available on Windows platforms.
.SH KEYWORDS
identifier, instance

|













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'\"
'\" Copyright (c) 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
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
HINSTANCE
\fBTk_GetHINSTANCE\fR()
.fi
.BE
.SH DESCRIPTION
.PP
\fBTk_GetHINSTANCE\fR returns the Windows application instance handle
for the Tk application.  This function is only available on Windows platforms.
.SH KEYWORDS
identifier, instance

Changes to doc/GetHWND.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
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH HWND 3 8.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetHWND, Tk_AttachHWND \- manage interactions between the Windows handle and an X window
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
HWND
\fBTk_GetHWND\fR(\fIwindow\fR)
.sp
Window
\fBTk_AttachHWND\fR(\fItkwin, hwnd\fR)

.SH ARGUMENTS
.AP Window window in
X token for window.
.AP Tk_Window tkwin in
Tk window for window.
.AP HWND hwnd in
Windows HWND for window.

|
















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
'\"
'\" 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
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
HWND
\fBTk_GetHWND\fR(\fIwindow\fR)
.sp
Window
\fBTk_AttachHWND\fR(\fItkwin, hwnd\fR)
.fi
.SH ARGUMENTS
.AP Window window in
X token for window.
.AP Tk_Window tkwin in
Tk window for window.
.AP HWND hwnd in
Windows HWND for window.

Changes to doc/GetImage.3.

18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
\fBTk_GetImage\fR(\fIinterp, tkwin, name, changeProc, clientData\fR)
.sp
\fBTk_RedrawImage\fR(\fIimage, imageX, imageY, width, height, drawable, drawableX, drawableY\fR)
.sp
\fBTk_SizeOfImage\fR(\fIimage, widthPtr, heightPtr\fR)
.sp
\fBTk_FreeImage\fR(\fIimage\fR)

.SH ARGUMENTS
.AS Tk_ImageChangedProc *changeProc
.AP Tcl_Interp *interp in
Place to leave error message.
.AP Tk_Window tkwin in
Window in which image will be used.
.AP "const char" *name in
Name of image.
.AP Tk_ImageChangedProc *changeProc in
Procedure for Tk to invoke whenever image content or size changes.
.AP ClientData clientData in
One-word value for Tk to pass to \fIchangeProc\fR.
.AP Tk_Image image in
Token for image instance;  must have been returned by a previous
call to \fBTk_GetImage\fR.
.AP int imageX in
X-coordinate of upper-left corner of region of image to redisplay
(measured in pixels from the image's upper-left corner).







>










|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
\fBTk_GetImage\fR(\fIinterp, tkwin, name, changeProc, clientData\fR)
.sp
\fBTk_RedrawImage\fR(\fIimage, imageX, imageY, width, height, drawable, drawableX, drawableY\fR)
.sp
\fBTk_SizeOfImage\fR(\fIimage, widthPtr, heightPtr\fR)
.sp
\fBTk_FreeImage\fR(\fIimage\fR)
.fi
.SH ARGUMENTS
.AS Tk_ImageChangedProc *changeProc
.AP Tcl_Interp *interp in
Place to leave error message.
.AP Tk_Window tkwin in
Window in which image will be used.
.AP "const char" *name in
Name of image.
.AP Tk_ImageChangedProc *changeProc in
Procedure for Tk to invoke whenever image content or size changes.
.AP void *clientData in
One-word value for Tk to pass to \fIchangeProc\fR.
.AP Tk_Image image in
Token for image instance;  must have been returned by a previous
call to \fBTk_GetImage\fR.
.AP int imageX in
X-coordinate of upper-left corner of region of image to redisplay
(measured in pixels from the image's upper-left corner).
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
they can redisplay themselves.
The \fIchangeProc\fR and \fIclientData\fR arguments to
\fBTk_GetImage\fR are used for this purpose.
\fIchangeProc\fR will be called by Tk whenever a change occurs
in the image;  it must match the following prototype:
.CS
typedef void \fBTk_ImageChangedProc\fR(
        ClientData \fIclientData\fR,
        int \fIx\fR,
        int \fIy\fR,
        int \fIwidth\fR,
        int \fIheight\fR,
        int \fIimageWidth\fR,
        int \fIimageHeight\fR);
.CE







|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
they can redisplay themselves.
The \fIchangeProc\fR and \fIclientData\fR arguments to
\fBTk_GetImage\fR are used for this purpose.
\fIchangeProc\fR will be called by Tk whenever a change occurs
in the image;  it must match the following prototype:
.CS
typedef void \fBTk_ImageChangedProc\fR(
        void *\fIclientData\fR,
        int \fIx\fR,
        int \fIy\fR,
        int \fIwidth\fR,
        int \fIheight\fR,
        int \fIimageWidth\fR,
        int \fIimageHeight\fR);
.CE

Changes to doc/GetJoinStl.3.

11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
.SH NAME
Tk_GetJoinStyle, Tk_NameOfJoinStyle \- translate between strings and join styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetJoinStyle(\fIinterp, string, joinPtr\fB)\fR
.sp
const char *
\fBTk_NameOfJoinStyle(\fIjoin\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of join style \- one of
.QW \fBbevel\fR ,







|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.SH NAME
Tk_GetJoinStyle, Tk_NameOfJoinStyle \- translate between strings and join styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetJoinStyle\fR(\fIinterp, string, joinPtr\fR)
.sp
const char *
\fBTk_NameOfJoinStyle\fR(\fIjoin\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP "const char" *string in
String containing name of join style \- one of
.QW \fBbevel\fR ,

Changes to doc/GetJustify.3.

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

25
26
27
28
29
30
31
.SH NAME
Tk_GetJustifyFromObj, Tk_GetJustify, Tk_NameOfJustify \- translate between strings and justification styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetJustifyFromObj(\fIinterp, objPtr, justifyPtr\fB)\fR
.sp
int
\fBTk_GetJustify(\fIinterp, string, justifyPtr\fB)\fR
.sp
const char *
\fBTk_NameOfJustify(\fIjustify\fB)\fR

.SH ARGUMENTS
.AS "Tk_Justify" *justifyPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of justification style \- one of
.QW \fBleft\fR ,







|


|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.SH NAME
Tk_GetJustifyFromObj, Tk_GetJustify, Tk_NameOfJustify \- translate between strings and justification styles
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetJustifyFromObj\fR(\fIinterp, objPtr, justifyPtr\fR)
.sp
int
\fBTk_GetJustify\fR(\fIinterp, string, justifyPtr\fR)
.sp
const char *
\fBTk_NameOfJustify\fR(\fIjustify\fR)
.fi
.SH ARGUMENTS
.AS "Tk_Justify" *justifyPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL.
.AP Tcl_Obj *objPtr in/out
String value contains name of justification style \- one of
.QW \fBleft\fR ,
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Justification style (one of the values listed below).
.BE
.SH DESCRIPTION
.PP
\fBTk_GetJustifyFromObj\fR places in \fI*justifyPtr\fR the justify value
corresponding to \fIobjPtr\fR's value.
This value will be one of the following:
.TP
\fBTK_JUSTIFY_LEFT\fR
Means that the text on each line should start at the left edge of
the line;  as a result, the right edges of lines may be ragged.
.TP
\fBTK_JUSTIFY_RIGHT\fR
Means that the text on each line should end at the right edge of
the line;  as a result, the left edges of lines may be ragged.
.TP
\fBTK_JUSTIFY_CENTER\fR
Means that the text on each line should be centered;  as a result,
both the left and right edges of lines may be ragged.
.PP
Under normal circumstances the return value is \fBTCL_OK\fR and
\fIinterp\fR is unused.
If \fIobjPtr\fR does not contain a valid justification style
or an abbreviation of one of these names, \fBTCL_ERROR\fR is returned,







<
|


<
|


<
|







45
46
47
48
49
50
51

52
53
54

55
56
57

58
59
60
61
62
63
64
65
Justification style (one of the values listed below).
.BE
.SH DESCRIPTION
.PP
\fBTk_GetJustifyFromObj\fR places in \fI*justifyPtr\fR the justify value
corresponding to \fIobjPtr\fR's value.
This value will be one of the following:

.IP \fBTK_JUSTIFY_LEFT\fR
Means that the text on each line should start at the left edge of
the line;  as a result, the right edges of lines may be ragged.

.IP \fBTK_JUSTIFY_RIGHT\fR
Means that the text on each line should end at the right edge of
the line;  as a result, the left edges of lines may be ragged.

.IP \fBTK_JUSTIFY_CENTER\fR
Means that the text on each line should be centered;  as a result,
both the left and right edges of lines may be ragged.
.PP
Under normal circumstances the return value is \fBTCL_OK\fR and
\fIinterp\fR is unused.
If \fIobjPtr\fR does not contain a valid justification style
or an abbreviation of one of these names, \fBTCL_ERROR\fR is returned,

Changes to doc/GetOption.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_GetOption \- retrieve an option from the option database
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Uid
\fBTk_GetOption\fR(\fItkwin, name, class\fR)

.SH ARGUMENTS
.AS Tk_Window *class
.AP Tk_Window tkwin in
Token for window.
.AP "const char" *name in
Name of desired option.
.AP "const char" *class in







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_GetOption \- retrieve an option from the option database
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Uid
\fBTk_GetOption\fR(\fItkwin, name, class\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window *class
.AP Tk_Window tkwin in
Token for window.
.AP "const char" *name in
Name of desired option.
.AP "const char" *class in

Changes to doc/GetPixels.3.

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

31
32
33
34
35
36
37
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM, Tk_GetDoublePixelsFromObj \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj(\fIinterp, tkwin, objPtr, intPtr\fB)\fR
.sp
int
\fBTk_GetDoublePixelsFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
\fBTk_GetPixels(\fIinterp, tkwin, string, intPtr\fB)\fR
.sp
int
\fBTk_GetMMFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
\fBTk_GetScreenMM(\fIinterp, tkwin, string, doublePtr\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Window whose screen geometry determines the conversion between absolute
units and pixels.







|


|


|


|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM, Tk_GetDoublePixelsFromObj \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj\fR(\fIinterp, tkwin, objPtr, intPtr\fR)
.sp
int
\fBTk_GetDoublePixelsFromObj\fR(\fIinterp, tkwin, objPtr, doublePtr\fR)
.sp
int
\fBTk_GetPixels\fR(\fIinterp, tkwin, string, intPtr\fR)
.sp
int
\fBTk_GetMMFromObj\fR(\fIinterp, tkwin, objPtr, doublePtr\fR)
.sp
int
\fBTk_GetScreenMM\fR(\fIinterp, tkwin, string, doublePtr\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *joinPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Window whose screen geometry determines the conversion between absolute
units and pixels.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
the screen (\fIobjPtr\fR or \fIstring\fR) and compute the
corresponding distance either in integer pixels or floating-point millimeters.
In either case,
\fIobjPtr\fR or \fIstring\fR
specifies a screen distance as a
floating-point number followed by one of the following characters
that indicates units:
.TP
<none>
The number specifies a distance in pixels.
.TP
\fBc\fR
The number specifies a distance in centimeters on the screen.
.TP
\fBi\fR
The number specifies a distance in inches on the screen.
.TP
\fBm\fR
The number specifies a distance in millimeters on the screen.
.TP
\fBp\fR
The number specifies a distance in printer's points (1/72 inch)
on the screen.
.PP
\fBTk_GetPixelsFromObj\fR converts the value of \fIobjPtr\fR to the
nearest even number of pixels and stores that value at \fI*intPtr\fR.
It returns \fBTCL_OK\fR under normal circumstances.
If an error occurs (e.g. \fIobjPtr\fR contains a number followed







<
|

<
|

<
|

<
|

<
|







53
54
55
56
57
58
59

60
61

62
63

64
65

66
67

68
69
70
71
72
73
74
75
the screen (\fIobjPtr\fR or \fIstring\fR) and compute the
corresponding distance either in integer pixels or floating-point millimeters.
In either case,
\fIobjPtr\fR or \fIstring\fR
specifies a screen distance as a
floating-point number followed by one of the following characters
that indicates units:

.IP <none>
The number specifies a distance in pixels.

.IP \fBc\fR
The number specifies a distance in centimeters on the screen.

.IP \fBi\fR
The number specifies a distance in inches on the screen.

.IP \fBm\fR
The number specifies a distance in millimeters on the screen.

.IP \fBp\fR
The number specifies a distance in printer's points (1/72 inch)
on the screen.
.PP
\fBTk_GetPixelsFromObj\fR converts the value of \fIobjPtr\fR to the
nearest even number of pixels and stores that value at \fI*intPtr\fR.
It returns \fBTCL_OK\fR under normal circumstances.
If an error occurs (e.g. \fIobjPtr\fR contains a number followed

Changes to doc/GetPixmap.3.

11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
.SH NAME
Tk_GetPixmap, Tk_FreePixmap \- allocate and free pixmaps
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Pixmap
\fBTk_GetPixmap(\fIdisplay, d, width, height, depth\fB)\fR
.sp
\fBTk_FreePixmap(\fIdisplay, pixmap\fB)\fR

.SH ARGUMENTS
.AS "Drawable" *pixelPtr
.AP Display *display in
X display for the pixmap.
.AP Drawable d in
Pixmap or window where the new pixmap will be used for drawing.
.AP "int" width in







|

|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.SH NAME
Tk_GetPixmap, Tk_FreePixmap \- allocate and free pixmaps
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Pixmap
\fBTk_GetPixmap\fR(\fIdisplay, d, width, height, depth\fR)
.sp
\fBTk_FreePixmap\fR(\fIdisplay, pixmap\fR)
.fi
.SH ARGUMENTS
.AS "Drawable" *pixelPtr
.AP Display *display in
X display for the pixmap.
.AP Drawable d in
Pixmap or window where the new pixmap will be used for drawing.
.AP "int" width in

Changes to doc/GetRelief.3.

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

25
26
27
28
29
30
31
.SH NAME
Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetReliefFromObj(\fIinterp, objPtr, reliefPtr\fB)\fR
.sp
int
\fBTk_GetRelief(\fIinterp, name, reliefPtr\fB)\fR
.sp
const char *
\fBTk_NameOfRelief(\fIrelief\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *reliefPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Obj *objPtr in/out
String value contains name of relief, one of
.QW \fBflat\fR ,







|


|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.SH NAME
Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetReliefFromObj\fR(\fIinterp, objPtr, reliefPtr\fR)
.sp
int
\fBTk_GetRelief\fR(\fIinterp, name, reliefPtr\fR)
.sp
const char *
\fBTk_NameOfRelief\fR(\fIrelief\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *reliefPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Obj *objPtr in/out
String value contains name of relief, one of
.QW \fBflat\fR ,

Changes to doc/GetRootCrd.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
.SH NAME
Tk_GetRootCoords \- Compute root-window coordinates of window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_GetRootCoords\fR(\fItkwin, xPtr, yPtr\fR)

.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.AP int *xPtr out
Pointer to location in which to store root-window x-coordinate
corresponding to left edge of \fItkwin\fR's border.







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.SH NAME
Tk_GetRootCoords \- Compute root-window coordinates of window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_GetRootCoords\fR(\fItkwin, xPtr, yPtr\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.AP int *xPtr out
Pointer to location in which to store root-window x-coordinate
corresponding to left edge of \fItkwin\fR's border.

Changes to doc/GetScroll.3.

11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
.SH NAME
Tk_GetScrollInfoObj, Tk_GetScrollInfo \- parse arguments for scrolling commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetScrollInfoObj(\fIinterp, objc, objv, fractionPtr, stepsPtr\fB)\fR
.sp
int
\fBTk_GetScrollInfo(\fIinterp, argc, argv, fractionPtr, stepsPtr\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *fractionPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP int objc in
Number of Tcl_Obj's in \fIobjv\fR array.
.AP "Tcl_Obj *const *" objv in
Argument objects.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP int argc in
Number of strings in \fIargv\fR array.







|


|
>




|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.SH NAME
Tk_GetScrollInfoObj, Tk_GetScrollInfo \- parse arguments for scrolling commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetScrollInfoObj\fR(\fIinterp, objc, objv, fractionPtr, stepsPtr\fR)
.sp
int
\fBTk_GetScrollInfo\fR(\fIinterp, argc, argv, fractionPtr, stepsPtr\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *fractionPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Size objc in
Number of Tcl_Obj's in \fIobjv\fR array.
.AP "Tcl_Obj *const *" objv in
Argument objects.  These represent the entire widget command, of
which the first word is typically the widget name and the second
word is typically \fBxview\fR or \fByview\fR.
.AP int argc in
Number of strings in \fIargv\fR array.

Changes to doc/GetSelect.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Tk_GetSelection \- retrieve the contents of a selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetSelection\fR(\fIinterp, tkwin, selection, target, proc, clientData\fR)

.SH ARGUMENTS
.AS Tk_GetSelProc clientData
.AP Tcl_Interp *interp in
Interpreter to use for reporting errors.
.AP Tk_Window tkwin in
Window on whose behalf to retrieve the selection (determines
display from which to retrieve).
.AP Atom selection in
The name of the selection to be retrieved.
.AP Atom target in
Form in which to retrieve selection.
.AP Tk_GetSelProc *proc in
Procedure to invoke to process pieces of the selection as they
are retrieved.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_GetSelection\fR retrieves the selection specified by the atom
\fIselection\fR in the format specified by \fItarget\fR.  The
selection may actually be retrieved in several pieces; as each piece
is retrieved, \fIproc\fR is called to process the piece.  \fIProc\fR
should have arguments and result that match the type
\fBTk_GetSelProc\fR:
.PP
.CS
typedef int \fBTk_GetSelProc\fR(
        ClientData \fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        char *\fIportion\fR);
.CE
.PP
The \fIclientData\fR and \fIinterp\fR parameters to \fIproc\fR
will be copies of the corresponding arguments to
\fBTk_GetSelection\fR.  \fIPortion\fR will be a pointer to







>














|













|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Tk_GetSelection \- retrieve the contents of a selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetSelection\fR(\fIinterp, tkwin, selection, target, proc, clientData\fR)
.fi
.SH ARGUMENTS
.AS Tk_GetSelProc clientData
.AP Tcl_Interp *interp in
Interpreter to use for reporting errors.
.AP Tk_Window tkwin in
Window on whose behalf to retrieve the selection (determines
display from which to retrieve).
.AP Atom selection in
The name of the selection to be retrieved.
.AP Atom target in
Form in which to retrieve selection.
.AP Tk_GetSelProc *proc in
Procedure to invoke to process pieces of the selection as they
are retrieved.
.AP void *clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_GetSelection\fR retrieves the selection specified by the atom
\fIselection\fR in the format specified by \fItarget\fR.  The
selection may actually be retrieved in several pieces; as each piece
is retrieved, \fIproc\fR is called to process the piece.  \fIProc\fR
should have arguments and result that match the type
\fBTk_GetSelProc\fR:
.PP
.CS
typedef int \fBTk_GetSelProc\fR(
        void *\fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        char *\fIportion\fR);
.CE
.PP
The \fIclientData\fR and \fIinterp\fR parameters to \fIproc\fR
will be copies of the corresponding arguments to
\fBTk_GetSelection\fR.  \fIPortion\fR will be a pointer to

Changes to doc/GetUid.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_GetUid, Tk_Uid \- convert from string to unique identifier
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Uid
\fBTk_GetUid\fR(\fIstring\fR)

.SH ARGUMENTS
.AP char *string in
String for which the corresponding unique identifier is
desired.
.BE
.SH DESCRIPTION
.PP







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_GetUid, Tk_Uid \- convert from string to unique identifier
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Uid
\fBTk_GetUid\fR(\fIstring\fR)
.fi
.SH ARGUMENTS
.AP char *string in
String for which the corresponding unique identifier is
desired.
.BE
.SH DESCRIPTION
.PP

Changes to doc/GetVRoot.3.

10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
.BS
.SH NAME
Tk_GetVRootGeometry \- Get location and size of virtual root for window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_GetVRootGeometry(\fItkwin, xPtr, yPtr, widthPtr, heightPtr\fB)\fR

.SH ARGUMENTS
.AS Tk_Window heightPtr
.AP Tk_Window tkwin in
Token for window whose virtual root is to be queried.
.AP int xPtr out
Points to word in which to store x-offset of virtual root.
.AP int yPtr out







|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.BS
.SH NAME
Tk_GetVRootGeometry \- Get location and size of virtual root for window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_GetVRootGeometry\fR(\fItkwin, xPtr, yPtr, widthPtr, heightPtr\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window heightPtr
.AP Tk_Window tkwin in
Token for window whose virtual root is to be queried.
.AP int xPtr out
Points to word in which to store x-offset of virtual root.
.AP int yPtr out

Changes to doc/GetVisual.3.

11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
.SH NAME
Tk_GetVisual \- translate from string to visual
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Visual *
\fBTk_GetVisual(\fIinterp, tkwin, string, depthPtr, colormapPtr\fB)\fR

.SH ARGUMENTS
.AS "Tcl_Interp" *colormapPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which the visual will be used.
.AP "const char" *string in







|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.SH NAME
Tk_GetVisual \- translate from string to visual
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Visual *
\fBTk_GetVisual\fR(\fIinterp, tkwin, string, depthPtr, colormapPtr\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *colormapPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which the visual will be used.
.AP "const char" *string in
44
45
46
47
48
49
50

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

65
66
67

68
69
70
71
72

73
74
75

76
77
78
79
80
81
82
also locates an appropriate colormap for use with the result visual
and stores its X identifier at \fI*colormapPtr\fR.
.PP
The \fIstring\fR argument specifies the desired visual in one
of the following ways:
.TP 15
\fIclass depth\fR

The string consists of a class name followed by an integer depth,
with any amount of white space (including none) in between.
\fIclass\fR selects what sort of visual is desired and must be one of
\fBdirectcolor\fR, \fBgrayscale\fR, \fBgreyscale\fR, \fBpseudocolor\fR,
\fBstaticcolor\fR, \fBstaticgray\fR, \fBstaticgrey\fR, or
\fBtruecolor\fR, or a unique abbreviation.
\fIdepth\fR specifies how many bits per pixel are needed for the
visual.
If possible, \fBTk_GetVisual\fR will return a visual with this depth;
if there is no visual of the desired depth then \fBTk_GetVisual\fR
looks first for a visual with greater depth, then one with less
depth.
.TP 15
\fBdefault\fR

Use the default visual for \fItkwin\fR's screen.
.TP 15
\fIpathName\fR

Use the visual for the window given by \fIpathName\fR.
\fIpathName\fR must be the name of a window on the same screen
as \fItkwin\fR.
.TP 15
\fInumber\fR

Use the visual whose X identifier is \fInumber\fR.
.TP 15
\fBbest\fR ?\fIdepth\fR?

Choose the
.QW "best possible"
visual, using the following rules, in decreasing order of priority:
.RS
.IP (a)
a visual that has exactly the desired depth is best, followed
by a visual with greater depth than requested (but as little extra







>














>



>





>



>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
also locates an appropriate colormap for use with the result visual
and stores its X identifier at \fI*colormapPtr\fR.
.PP
The \fIstring\fR argument specifies the desired visual in one
of the following ways:
.TP 15
\fIclass depth\fR
.
The string consists of a class name followed by an integer depth,
with any amount of white space (including none) in between.
\fIclass\fR selects what sort of visual is desired and must be one of
\fBdirectcolor\fR, \fBgrayscale\fR, \fBgreyscale\fR, \fBpseudocolor\fR,
\fBstaticcolor\fR, \fBstaticgray\fR, \fBstaticgrey\fR, or
\fBtruecolor\fR, or a unique abbreviation.
\fIdepth\fR specifies how many bits per pixel are needed for the
visual.
If possible, \fBTk_GetVisual\fR will return a visual with this depth;
if there is no visual of the desired depth then \fBTk_GetVisual\fR
looks first for a visual with greater depth, then one with less
depth.
.TP 15
\fBdefault\fR
.
Use the default visual for \fItkwin\fR's screen.
.TP 15
\fIpathName\fR
.
Use the visual for the window given by \fIpathName\fR.
\fIpathName\fR must be the name of a window on the same screen
as \fItkwin\fR.
.TP 15
\fInumber\fR
.
Use the visual whose X identifier is \fInumber\fR.
.TP 15
\fBbest\fR ?\fIdepth\fR?
.
Choose the
.QW "best possible"
visual, using the following rules, in decreasing order of priority:
.RS
.IP (a)
a visual that has exactly the desired depth is best, followed
by a visual with greater depth than requested (but as little extra

Changes to doc/Grab.3.

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

19
20
21
22
23
24
25
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_Grab 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_Grab, Tk_Ungrab \- manipulate grab state in an application
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_Grab\fR(\fIinterp, tkwin, grabGlobal\fR)
.sp
void
\fBTk_Ungrab\fR(\fItkwin\fR)

.SH ARGUMENTS
.AP Tcl_Interp *interp in
Interpreter to use for error reporting
.AP Tk_Window tkwin in
Window on whose behalf the pointer is to be grabbed or released
.AP int grabGlobal in
Boolean indicating whether the grab is global or application local

|














<

>







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

17
18
19
20
21
22
23
24
25
'\"
'\" Copyright (c) 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
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_Grab\fR(\fIinterp, tkwin, grabGlobal\fR)
.sp

\fBTk_Ungrab\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AP Tcl_Interp *interp in
Interpreter to use for error reporting
.AP Tk_Window tkwin in
Window on whose behalf the pointer is to be grabbed or released
.AP int grabGlobal in
Boolean indicating whether the grab is global or application local

Changes to doc/HWNDToWindow.3.

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

16
17
18
19
20
21
22
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_HWNDToWindow 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_HWNDToWindow \- Find Tk's window information for a Windows window
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
Tk_Window
\fBTk_HWNDToWindow\fR(\fIhwnd\fR)

.SH ARGUMENTS
.AP HWND hwnd in
Windows handle for the window.
.BE
.SH DESCRIPTION
.PP
Given a Windows HWND window identifier, this procedure returns the

|













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'\"
'\" Copyright (c) 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
.SH SYNOPSIS
.nf
\fB#include <tkPlatDecls.h>\fR
.sp
Tk_Window
\fBTk_HWNDToWindow\fR(\fIhwnd\fR)
.fi
.SH ARGUMENTS
.AP HWND hwnd in
Windows handle for the window.
.BE
.SH DESCRIPTION
.PP
Given a Windows HWND window identifier, this procedure returns the

Changes to doc/HandleEvent.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
.SH NAME
Tk_HandleEvent \- invoke event handlers for window system events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_HandleEvent\fR(\fIeventPtr\fR)

.SH ARGUMENTS
.AS XEvent *eventPtr
.AP XEvent *eventPtr in
Pointer to X event to dispatch to relevant handler(s). It is important
that all unused fields of the structure be set to zero.
.BE
.SH DESCRIPTION







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.SH NAME
Tk_HandleEvent \- invoke event handlers for window system events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_HandleEvent\fR(\fIeventPtr\fR)
.fi
.SH ARGUMENTS
.AS XEvent *eventPtr
.AP XEvent *eventPtr in
Pointer to X event to dispatch to relevant handler(s). It is important
that all unused fields of the structure be set to zero.
.BE
.SH DESCRIPTION

Changes to doc/IdToWindow.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
Tk_IdToWindow \- Find Tk's window information for an X window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_IdToWindow\fR(\fIdisplay, window\fR)

.SH ARGUMENTS
.AS Tk_Window display
.AP Display *display in
X display containing the window.
.AP Window window in
X id for window.
.BE







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Tk_IdToWindow \- Find Tk's window information for an X window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_IdToWindow\fR(\fIdisplay, window\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window display
.AP Display *display in
X display containing the window.
.AP Window window in
X id for window.
.BE

Changes to doc/ImgChanged.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
.SH NAME
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fImodel, x, y, width, height, imageWidth, imageHeight\fR)

.SH ARGUMENTS
.AS Tk_ImageModel imageHeight
.AP Tk_ImageModel model in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.SH NAME
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fImodel, x, y, width, height, imageWidth, imageHeight\fR)
.fi
.SH ARGUMENTS
.AS Tk_ImageModel imageHeight
.AP Tk_ImageModel model in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured

Changes to doc/Inactive.3.

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

18
19
20
21
22
23
24
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH Tk_GetUserInactiveTime 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime \- discover user inactivity time
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
long
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.sp
\fBTk_ResetUserInactiveTime(\fIdisplay\fB)\fR

.SH ARGUMENTS
.AS Display *display
.AP Display *display in
The display on which the user inactivity timer is to be queried or
reset.
.BE
.SH DESCRIPTION

|












|

|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'\"
'\" Copyright (c) 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
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
long
\fBTk_GetUserInactiveTime\fR(\fIdisplay\fR)
.sp
\fBTk_ResetUserInactiveTime\fR(\fIdisplay\fR)
.fi
.SH ARGUMENTS
.AS Display *display
.AP Display *display in
The display on which the user inactivity timer is to be queried or
reset.
.BE
.SH DESCRIPTION

Changes to doc/InternAtom.3.

11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
.SH NAME
Tk_InternAtom, Tk_GetAtomName \- manage cache of X atoms
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Atom
\fBTk_InternAtom(\fItkwin, name\fR)
.sp
const char *
\fBTk_GetAtomName(\fItkwin, atom\fR)

.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.  Used to map atom or name relative to a particular display.
.AP "const char" *name in
String name for which atom is desired.
.AP Atom atom in







|


|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.SH NAME
Tk_InternAtom, Tk_GetAtomName \- manage cache of X atoms
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Atom
\fBTk_InternAtom\fR(\fItkwin, name\fR)
.sp
const char *
\fBTk_GetAtomName\fR(\fItkwin, atom\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.  Used to map atom or name relative to a particular display.
.AP "const char" *name in
String name for which atom is desired.
.AP Atom atom in

Changes to doc/MainLoop.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
.SH NAME
Tk_MainLoop \- loop for events until all windows are deleted
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MainLoop\fR()

.BE
.SH DESCRIPTION
.PP
\fBTk_MainLoop\fR is a procedure that loops repeatedly calling
\fBTcl_DoOneEvent\fR.  It returns only when there are no applications
left in this process (i.e. no main windows exist anymore).  Most
windowing applications will call \fBTk_MainLoop\fR after







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.SH NAME
Tk_MainLoop \- loop for events until all windows are deleted
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MainLoop\fR()
.fi
.BE
.SH DESCRIPTION
.PP
\fBTk_MainLoop\fR is a procedure that loops repeatedly calling
\fBTcl_DoOneEvent\fR.  It returns only when there are no applications
left in this process (i.e. no main windows exist anymore).  Most
windowing applications will call \fBTk_MainLoop\fR after

Changes to doc/MainWin.3.

13
14
15
16
17
18
19




20
21

22
23
24
25








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







39
40
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MainWindow\fR(\fIinterp\fR)
.sp




int
\fBTk_GetNumMainWindows\fR()

.SH ARGUMENTS
.AS Tcl_Interp *pathName
.AP Tcl_Interp *interp in/out
Interpreter associated with the application.








.BE
.SH DESCRIPTION
.PP
A main window is a special kind of toplevel window used as the
outermost window in an application.
.PP
If \fIinterp\fR is associated with a Tk application then \fBTk_MainWindow\fR
returns the application's main window. If there is no Tk application
associated with \fIinterp\fR then \fBTk_MainWindow\fR returns NULL and
leaves an error message in interpreter \fIinterp\fR's result.
.PP
\fBTk_GetNumMainWindows\fR returns a count of the number of main
windows currently open in the current thread.







.SH KEYWORDS
application, main window







>
>
>
>


>




>
>
>
>
>
>
>
>













>
>
>
>
>
>
>


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MainWindow\fR(\fIinterp\fR)
.sp
\fBTk_SetMainMenubar\fR(\fIinterp, tkwin, menuName\fR)
.sp
\fBTk_SetWindowMenubar\fR(\fIinterp, tkwin, oldMenuName, menuName\fR)
.sp
int
\fBTk_GetNumMainWindows\fR()
.fi
.SH ARGUMENTS
.AS Tcl_Interp *pathName
.AP Tcl_Interp *interp in/out
Interpreter associated with the application.
.AP Tk_Window tkwin in
Token for main window.
.AP const char *menuName in
The name of the new menubar that the toplevel needs to be set to.
NULL means that their is no menu now.
.AP const char *oldMenuName in
The name of the menubar previously set in this toplevel.
NULL means no menu was set previously.
.BE
.SH DESCRIPTION
.PP
A main window is a special kind of toplevel window used as the
outermost window in an application.
.PP
If \fIinterp\fR is associated with a Tk application then \fBTk_MainWindow\fR
returns the application's main window. If there is no Tk application
associated with \fIinterp\fR then \fBTk_MainWindow\fR returns NULL and
leaves an error message in interpreter \fIinterp\fR's result.
.PP
\fBTk_GetNumMainWindows\fR returns a count of the number of main
windows currently open in the current thread.
\fBTk_SetMainMenubar\fR
Called when a toplevel widget is brought to front. On the Macintosh,
sets up the menubar that goes across the top of the main monitor. On
other platforms, nothing is necessary.
\fBTk_SetWindowMenubar\fR associates a menu with a window.
The old menu clones for the menubar are thrown away, and a handler is
set up to allocate the new ones.
.SH KEYWORDS
application, main window

Changes to doc/MaintGeom.3.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MaintainGeometry\fR(\fIwindow, container, x, y, width, height\fR)
.sp
\fBTk_UnmaintainGeometry\fR(\fIwindow, container\fR)

.SH ARGUMENTS
.AS Tk_Window container
.AP Tk_Window window in
Window whose geometry is to be controlled.
.AP Tk_Window container in
Window relative to which \fIwindow\fR's geometry will be controlled.
.AP int x in







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MaintainGeometry\fR(\fIwindow, container, x, y, width, height\fR)
.sp
\fBTk_UnmaintainGeometry\fR(\fIwindow, container\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window container
.AP Tk_Window window in
Window whose geometry is to be controlled.
.AP Tk_Window container in
Window relative to which \fIwindow\fR's geometry will be controlled.
.AP int x in

Changes to doc/ManageGeom.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
.SH NAME
Tk_ManageGeometry \- arrange to handle geometry requests for a window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ManageGeometry\fR(\fItkwin, mgrPtr, clientData\fR)

.SH ARGUMENTS
.AS Tk_GeometryProc clientData
.AP Tk_Window tkwin in
Token for window to be managed.
.AP "const Tk_GeomMgr" *mgrPtr in
Pointer to data structure containing information about the
geometry manager, or NULL to indicate that \fItkwin\fR's geometry
should not be managed anymore.
The data structure pointed to by \fImgrPtr\fR must be static:
Tk keeps a reference to it as long as the window is managed.
.AP ClientData clientData in
Arbitrary one-word value to pass to geometry manager callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_ManageGeometry\fR arranges for a particular geometry manager,
described by the \fImgrPtr\fR argument, to control the geometry
of a particular content window, given by \fItkwin\fR.







>










|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.SH NAME
Tk_ManageGeometry \- arrange to handle geometry requests for a window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ManageGeometry\fR(\fItkwin, mgrPtr, clientData\fR)
.fi
.SH ARGUMENTS
.AS Tk_GeometryProc clientData
.AP Tk_Window tkwin in
Token for window to be managed.
.AP "const Tk_GeomMgr" *mgrPtr in
Pointer to data structure containing information about the
geometry manager, or NULL to indicate that \fItkwin\fR's geometry
should not be managed anymore.
The data structure pointed to by \fImgrPtr\fR must be static:
Tk keeps a reference to it as long as the window is managed.
.AP void *clientData in
Arbitrary one-word value to pass to geometry manager callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_ManageGeometry\fR arranges for a particular geometry manager,
described by the \fImgrPtr\fR argument, to control the geometry
of a particular content window, given by \fItkwin\fR.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
\fIrequestProc\fR is a procedure in the geometry manager that
will be invoked whenever \fBTk_GeometryRequest\fR is called by the
content window to change its desired geometry.
\fIrequestProc\fR should have arguments and results that match the
type \fBTk_GeomRequestProc\fR:
.CS
typedef void \fBTk_GeomRequestProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIrequestProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
\fIclientData\fR usually points to a data
structure containing application-specific information about
how to manage \fItkwin\fR's geometry.







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
\fIrequestProc\fR is a procedure in the geometry manager that
will be invoked whenever \fBTk_GeometryRequest\fR is called by the
content window to change its desired geometry.
\fIrequestProc\fR should have arguments and results that match the
type \fBTk_GeomRequestProc\fR:
.CS
typedef void \fBTk_GeomRequestProc\fR(
        void *\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.
77
78
79
80
81
82
83
84
85
86
87
88
89
90
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostContentProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostContentProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostContentProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
.SH KEYWORDS
callback, geometry, managed, request, unmanaged







|






78
79
80
81
82
83
84
85
86
87
88
89
90
91
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostContentProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostContentProc\fR(
        void *\fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostContentProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
.SH KEYWORDS
callback, geometry, managed, request, unmanaged

Changes to doc/MapWindow.3.

14
15
16
17
18
19
20

21
22
23
24
25
26
27
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MapWindow\fR(\fItkwin\fR)
.sp
\fBTk_UnmapWindow\fR(\fItkwin\fR)

.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_MapWindow\fR(\fItkwin\fR)
.sp
\fBTk_UnmapWindow\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP

Changes to doc/MeasureChar.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
.SH NAME
Tk_MeasureChars, Tk_TextWidth, Tk_DrawChars, Tk_UnderlineChars \- routines to measure and display simple single-line strings.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_MeasureChars(\fItkfont, string, numBytes, maxPixels, flags, lengthPtr\fB)\fR
.sp
int
\fBTk_TextWidth(\fItkfont, string, numBytes\fB)\fR
.sp
\fBTk_DrawChars(\fIdisplay, drawable, gc, tkfont, string, numBytes, x, y\fB)\fR
.sp
\fBTk_UnderlineChars(\fIdisplay, drawable, gc, tkfont, string, x, y, firstByte, lastByte\fB)\fR
.sp
.SH ARGUMENTS
.AS "const char" firstChar
.AP Tk_Font tkfont in
Token for font in which text is to be drawn or measured.  Must have been
returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
Text to be measured or displayed.  Need not be null terminated.  Any
non-printing meta-characters in the string (such as tabs, newlines, and
other control characters) will be measured or displayed in a
platform-dependent manner.
.AP int numBytes in
The maximum number of bytes to consider when measuring or drawing
\fIstring\fR.  Must be greater than or equal to 0.
.AP int maxPixels in
If \fImaxPixels\fR is >= 0, it specifies the longest permissible
line length in pixels.  Characters from \fIstring\fR are processed only
until this many pixels have been covered.  If \fImaxPixels\fR is < 0, then
the line length is unbounded and the \fIflags\fR argument is ignored.
.AP int flags in
Various flag bits OR-ed together: \fBTK_PARTIAL_OK\fR means include a character
as long as any part of it fits in the length given by \fImaxPixels\fR;
otherwise, a character must fit completely to be considered.
\fBTK_WHOLE_WORDS\fR means stop on a word boundary, if possible.  If
\fBTK_AT_LEAST_ONE\fR is set, it means return at least one character even if no
characters could fit in the length given by \fImaxPixels\fR.  If
\fBTK_AT_LEAST_ONE\fR is set and \fBTK_WHOLE_WORDS\fR is also set, it means that if
not even one word fits on the line, return the first few letters of the
word that did fit; if not even one letter of the word fit, then the first
letter will still be returned.
.AP int *lengthPtr out
Filled with the number of pixels occupied by the number of characters
returned as the result of \fBTk_MeasureChars\fR.
.AP Display *display in
Display on which to draw.







|


|

|

|
|










|














|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
.SH NAME
Tk_MeasureChars, Tk_TextWidth, Tk_DrawChars, Tk_UnderlineChars \- routines to measure and display simple single-line strings.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_MeasureChars\fR(\fItkfont, string, numBytes, maxPixels, flags, lengthPtr\fR)
.sp
int
\fBTk_TextWidth\fR(\fItkfont, string, numBytes\fR)
.sp
\fBTk_DrawChars\fR(\fIdisplay, drawable, gc, tkfont, string, numBytes, x, y\fR)
.sp
\fBTk_UnderlineChars\fR(\fIdisplay, drawable, gc, tkfont, string, x, y, firstByte, lastByte\fR)
.fi
.SH ARGUMENTS
.AS "const char" firstChar
.AP Tk_Font tkfont in
Token for font in which text is to be drawn or measured.  Must have been
returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
Text to be measured or displayed.  Need not be null terminated.  Any
non-printing meta-characters in the string (such as tabs, newlines, and
other control characters) will be measured or displayed in a
platform-dependent manner.
.AP Tcl_Size numBytes in
The maximum number of bytes to consider when measuring or drawing
\fIstring\fR.  Must be greater than or equal to 0.
.AP int maxPixels in
If \fImaxPixels\fR is >= 0, it specifies the longest permissible
line length in pixels.  Characters from \fIstring\fR are processed only
until this many pixels have been covered.  If \fImaxPixels\fR is < 0, then
the line length is unbounded and the \fIflags\fR argument is ignored.
.AP int flags in
Various flag bits OR-ed together: \fBTK_PARTIAL_OK\fR means include a character
as long as any part of it fits in the length given by \fImaxPixels\fR;
otherwise, a character must fit completely to be considered.
\fBTK_WHOLE_WORDS\fR means stop on a word boundary, if possible.  If
\fBTK_AT_LEAST_ONE\fR is set, it means return at least one character even if no
characters could fit in the length given by \fImaxPixels\fR.  If
\fBTK_AT_LEAST_ONE\fR is set and \fBTK_WHOLE_WORDS\fR is also set, it means
that if not even one word fits on the line, return the first few letters of the
word that did fit; if not even one letter of the word fit, then the first
letter will still be returned.
.AP int *lengthPtr out
Filled with the number of pixels occupied by the number of characters
returned as the result of \fBTk_MeasureChars\fR.
.AP Display *display in
Display on which to draw.

Changes to doc/MoveToplev.3.

10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
.BS
.SH NAME
Tk_MoveToplevelWindow \- Adjust the position of a top-level window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MoveToplevelWindow(\fItkwin, x, y\fB)\fR

.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for top-level window to move.
.AP int x in
New x-coordinate for the top-left pixel of \fItkwin\fR's border, or the
top-left pixel of the decorative border supplied for \fItkwin\fR by the







|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.BS
.SH NAME
Tk_MoveToplevelWindow \- Adjust the position of a top-level window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_MoveToplevelWindow\fR(\fItkwin, x, y\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for top-level window to move.
.AP int x in
New x-coordinate for the top-left pixel of \fItkwin\fR's border, or the
top-left pixel of the decorative border supplied for \fItkwin\fR by the

Changes to doc/Name.3.

18
19
20
21
22
23
24

25
26
27
28
29
30
31
\fBTk_Name\fR(\fItkwin\fR)
.sp
char *
\fBTk_PathName\fR(\fItkwin\fR)
.sp
Tk_Window
\fBTk_NameToWindow\fR(\fIinterp, pathName, tkwin\fR)

.SH ARGUMENTS
.AS Tcl_Interp *pathName
.AP Tk_Window tkwin in
Token for window.
.AP Tcl_Interp *interp out
Interpreter to use for error reporting.
.AP "const char" *pathName in







>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
\fBTk_Name\fR(\fItkwin\fR)
.sp
char *
\fBTk_PathName\fR(\fItkwin\fR)
.sp
Tk_Window
\fBTk_NameToWindow\fR(\fIinterp, pathName, tkwin\fR)
.fi
.SH ARGUMENTS
.AS Tcl_Interp *pathName
.AP Tk_Window tkwin in
Token for window.
.AP Tcl_Interp *interp out
Interpreter to use for error reporting.
.AP "const char" *pathName in

Changes to doc/NameOfImg.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageModel\fR)

.SH ARGUMENTS
.AS Tk_ImageModel imageModel
.AP Tk_ImageModel imageModel in
Token for image, which was passed to image manager's \fIcreateProc\fR when
the image was created.
.BE
.SH DESCRIPTION







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageModel\fR)
.fi
.SH ARGUMENTS
.AS Tk_ImageModel imageModel
.AP Tk_ImageModel imageModel in
Token for image, which was passed to image manager's \fIcreateProc\fR when
the image was created.
.BE
.SH DESCRIPTION

Changes to doc/OwnSelect.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
.SH NAME
Tk_OwnSelection \- make a window the owner of the primary selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_OwnSelection\fR(\fItkwin, selection, proc, clientData\fR)

.SH ARGUMENTS
.AS Tk_LostSelProc clientData
.AP Tk_Window tkwin in
Window that is to become new selection owner.
.AP Atom selection in
The name of the selection to be owned, such as XA_PRIMARY.
.AP Tk_LostSelProc *proc in
Procedure to invoke when \fItkwin\fR loses selection ownership later.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_OwnSelection\fR arranges for \fItkwin\fR to become the
new owner of the selection specified by the atom
\fIselection\fR.  After this call completes, future requests
for the selection will be directed to handlers created for
\fItkwin\fR using \fBTk_CreateSelHandler\fR.  When \fItkwin\fR
eventually loses the selection ownership, \fIproc\fR will be
invoked so that the window can clean itself up (e.g. by
unhighlighting the selection).  \fIProc\fR should have arguments and
result that match the type \fBTk_LostSelProc\fR:
.CS
typedef void \fBTk_LostSelProc\fR(
        ClientData \fIclientData\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_OwnSelection\fR, and is
usually a pointer to a data structure containing application-specific
information about \fItkwin\fR.
.SH KEYWORDS
own, selection owner







>








|















|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
.SH NAME
Tk_OwnSelection \- make a window the owner of the primary selection
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_OwnSelection\fR(\fItkwin, selection, proc, clientData\fR)
.fi
.SH ARGUMENTS
.AS Tk_LostSelProc clientData
.AP Tk_Window tkwin in
Window that is to become new selection owner.
.AP Atom selection in
The name of the selection to be owned, such as XA_PRIMARY.
.AP Tk_LostSelProc *proc in
Procedure to invoke when \fItkwin\fR loses selection ownership later.
.AP void *clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
.SH DESCRIPTION
.PP
\fBTk_OwnSelection\fR arranges for \fItkwin\fR to become the
new owner of the selection specified by the atom
\fIselection\fR.  After this call completes, future requests
for the selection will be directed to handlers created for
\fItkwin\fR using \fBTk_CreateSelHandler\fR.  When \fItkwin\fR
eventually loses the selection ownership, \fIproc\fR will be
invoked so that the window can clean itself up (e.g. by
unhighlighting the selection).  \fIProc\fR should have arguments and
result that match the type \fBTk_LostSelProc\fR:
.CS
typedef void \fBTk_LostSelProc\fR(
        void *\fIclientData\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy of the
\fIclientData\fR argument given to \fBTk_OwnSelection\fR, and is
usually a pointer to a data structure containing application-specific
information about \fItkwin\fR.
.SH KEYWORDS
own, selection owner

Changes to doc/ParseArgv.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_ParseArgv \- process command-line options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ParseArgv\fR(\fIinterp, tkwin, argcPtr, argv, argTable, flags\fR)

.SH ARGUMENTS
.AS Tk_ArgvInfo *argTable
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window to use when arguments specify Tk options.  If NULL, then
no Tk options will be processed.







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_ParseArgv \- process command-line options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ParseArgv\fR(\fIinterp, tkwin, argcPtr, argv, argTable, flags\fR)
.fi
.SH ARGUMENTS
.AS Tk_ArgvInfo *argTable
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window to use when arguments specify Tk options.  If NULL, then
no Tk options will be processed.
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
.QW "the matching argument"
in the descriptions below.  As part of the processing,
\fBTk_ParseArgv\fR may also use the next argument in \fIargv\fR
after the matching argument, which is called
.QW "the following argument" .
The legal values for \fItype\fR, and the processing
that they cause, are as follows:
.TP
\fBTK_ARGV_END\fR
Marks the end of the table.  The last entry in \fIargTable\fR
must have this type;  all of its other fields are ignored and it
will never match any arguments.
.TP
\fBTK_ARGV_CONSTANT\fR
\fISrc\fR is treated as an integer and \fIdst\fR is treated
as a pointer to an integer.  \fISrc\fR is stored at \fI*dst\fR.
The matching argument is discarded.
.TP
\fBTK_ARGV_INT\fR
The following argument must contain an
integer string in the format accepted by \fBstrtol\fR (e.g.
.QW 0
and
.QW 0x
prefixes may be used to specify octal or hexadecimal
numbers, respectively).  \fIDst\fR is treated as a pointer to an
integer;  the following argument is converted to an integer value
and stored at \fI*dst\fR.  \fISrc\fR is ignored.  The matching
and following arguments are discarded from \fIargv\fR.
.TP
\fBTK_ARGV_FLOAT\fR
The following argument must contain a floating-point number in
the format accepted by \fBstrtol\fR.
\fIDst\fR is treated as the address of a double-precision
floating point value;  the following argument is converted to a
double-precision value and stored at \fI*dst\fR.  The matching
and following arguments are discarded from \fIargv\fR.
.TP
\fBTK_ARGV_STRING\fR
In this form, \fIdst\fR is treated as a pointer to a (char *);
\fBTk_ParseArgv\fR stores at \fI*dst\fR a pointer to the following
argument, and discards the matching and following arguments from
\fIargv\fR.  \fISrc\fR is ignored.
.TP
\fBTK_ARGV_UID\fR
This form is similar to \fBTK_ARGV_STRING\fR, except that the argument
is turned into a Tk_Uid by calling \fBTk_GetUid\fR.
\fIDst\fR is treated as a pointer to a
Tk_Uid; \fBTk_ParseArgv\fR stores at \fI*dst\fR the Tk_Uid
corresponding to the following
argument, and discards the matching and following arguments from
\fIargv\fR.  \fISrc\fR is ignored.
.TP
\fBTK_ARGV_CONST_OPTION\fR
This form causes a Tk option to be set (as if the \fBoption\fR
command had been invoked).  The \fIsrc\fR field is treated as a
pointer to a string giving the value of an option, and \fIdst\fR
is treated as a pointer to the name of the option.  The matching
argument is discarded.  If \fItkwin\fR is NULL, then argument
specifiers of this type are ignored (as if they did not exist).
.TP
\fBTK_ARGV_OPTION_VALUE\fR
This form is similar to \fBTK_ARGV_CONST_OPTION\fR, except that the
value of the option is taken from the following argument instead
of from \fIsrc\fR.  \fIDst\fR is used as the name of the option.
\fISrc\fR is ignored.  The matching and following arguments
are discarded.  If \fItkwin\fR is NULL, then argument
specifiers of this type are ignored (as if they did not exist).
.TP
\fBTK_ARGV_OPTION_NAME_VALUE\fR
In this case the following argument is taken as the name of a Tk
option and the argument after that is taken as the value for that
option.  Both \fIsrc\fR and \fIdst\fR are ignored.  All three
arguments are discarded from \fIargv\fR.  If \fItkwin\fR is NULL,
then argument
specifiers of this type are ignored (as if they did not exist).
.TP
\fBTK_ARGV_HELP\fR
When this kind of option is encountered, \fBTk_ParseArgv\fR uses the
\fIhelp\fR fields of \fIargTable\fR to format a message describing
all the valid arguments.  The message is placed in interpreter
\fIinterp\fR's result
and \fBTk_ParseArgv\fR returns \fBTCL_ERROR\fR.  When this happens, the
caller normally prints the help message and aborts.  If the \fIkey\fR
field of a \fBTK_ARGV_HELP\fR specifier is NULL, then the specifier will
never match any arguments;  in this case the specifier simply provides
extra documentation, which will be included when some other
\fBTK_ARGV_HELP\fR entry causes help information to be returned.
.TP
\fBTK_ARGV_REST\fR
This option is used by programs or commands that allow the last
several of their options to be the name and/or options for some
other program.  If a \fBTK_ARGV_REST\fR argument is found, then
\fBTk_ParseArgv\fR does not process any
of the remaining arguments;  it returns them all at
the beginning of \fIargv\fR (along with any other unprocessed arguments).
In addition, \fBTk_ParseArgv\fR treats \fIdst\fR as the address of an
integer value, and stores at \fI*dst\fR the index of the first of the
\fBTK_ARGV_REST\fR options in the returned \fIargv\fR.  This allows the
program to distinguish the \fBTK_ARGV_REST\fR options from other
unprocessed options that preceded the \fBTK_ARGV_REST\fR.
.TP
\fBTK_ARGV_FUNC\fR
For this kind of argument, \fIsrc\fR is treated as the address of
a procedure, which is invoked to process the following argument.
The procedure should have the following structure:
.RS
.CS
int
\fIfunc\fR(\fIdst\fR, \fIkey\fR, \fInextArg\fR)







<
|



<
|



<
|










<
|






<
|




<
|







<
|






<
|






<
|






<
|










<
|











<
|







110
111
112
113
114
115
116

117
118
119
120

121
122
123
124

125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142

143
144
145
146
147

148
149
150
151
152
153
154
155

156
157
158
159
160
161
162

163
164
165
166
167
168
169

170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
.QW "the matching argument"
in the descriptions below.  As part of the processing,
\fBTk_ParseArgv\fR may also use the next argument in \fIargv\fR
after the matching argument, which is called
.QW "the following argument" .
The legal values for \fItype\fR, and the processing
that they cause, are as follows:

.IP \fBTK_ARGV_END\fR
Marks the end of the table.  The last entry in \fIargTable\fR
must have this type;  all of its other fields are ignored and it
will never match any arguments.

.IP \fBTK_ARGV_CONSTANT\fR
\fISrc\fR is treated as an integer and \fIdst\fR is treated
as a pointer to an integer.  \fISrc\fR is stored at \fI*dst\fR.
The matching argument is discarded.

.IP \fBTK_ARGV_INT\fR
The following argument must contain an
integer string in the format accepted by \fBstrtol\fR (e.g.
.QW 0
and
.QW 0x
prefixes may be used to specify octal or hexadecimal
numbers, respectively).  \fIDst\fR is treated as a pointer to an
integer;  the following argument is converted to an integer value
and stored at \fI*dst\fR.  \fISrc\fR is ignored.  The matching
and following arguments are discarded from \fIargv\fR.

.IP \fBTK_ARGV_FLOAT\fR
The following argument must contain a floating-point number in
the format accepted by \fBstrtol\fR.
\fIDst\fR is treated as the address of a double-precision
floating point value;  the following argument is converted to a
double-precision value and stored at \fI*dst\fR.  The matching
and following arguments are discarded from \fIargv\fR.

.IP \fBTK_ARGV_STRING\fR
In this form, \fIdst\fR is treated as a pointer to a (char *);
\fBTk_ParseArgv\fR stores at \fI*dst\fR a pointer to the following
argument, and discards the matching and following arguments from
\fIargv\fR.  \fISrc\fR is ignored.

.IP \fBTK_ARGV_UID\fR
This form is similar to \fBTK_ARGV_STRING\fR, except that the argument
is turned into a Tk_Uid by calling \fBTk_GetUid\fR.
\fIDst\fR is treated as a pointer to a
Tk_Uid; \fBTk_ParseArgv\fR stores at \fI*dst\fR the Tk_Uid
corresponding to the following
argument, and discards the matching and following arguments from
\fIargv\fR.  \fISrc\fR is ignored.

.IP \fBTK_ARGV_CONST_OPTION\fR
This form causes a Tk option to be set (as if the \fBoption\fR
command had been invoked).  The \fIsrc\fR field is treated as a
pointer to a string giving the value of an option, and \fIdst\fR
is treated as a pointer to the name of the option.  The matching
argument is discarded.  If \fItkwin\fR is NULL, then argument
specifiers of this type are ignored (as if they did not exist).

.IP \fBTK_ARGV_OPTION_VALUE\fR
This form is similar to \fBTK_ARGV_CONST_OPTION\fR, except that the
value of the option is taken from the following argument instead
of from \fIsrc\fR.  \fIDst\fR is used as the name of the option.
\fISrc\fR is ignored.  The matching and following arguments
are discarded.  If \fItkwin\fR is NULL, then argument
specifiers of this type are ignored (as if they did not exist).

.IP \fBTK_ARGV_OPTION_NAME_VALUE\fR
In this case the following argument is taken as the name of a Tk
option and the argument after that is taken as the value for that
option.  Both \fIsrc\fR and \fIdst\fR are ignored.  All three
arguments are discarded from \fIargv\fR.  If \fItkwin\fR is NULL,
then argument
specifiers of this type are ignored (as if they did not exist).

.IP \fBTK_ARGV_HELP\fR
When this kind of option is encountered, \fBTk_ParseArgv\fR uses the
\fIhelp\fR fields of \fIargTable\fR to format a message describing
all the valid arguments.  The message is placed in interpreter
\fIinterp\fR's result
and \fBTk_ParseArgv\fR returns \fBTCL_ERROR\fR.  When this happens, the
caller normally prints the help message and aborts.  If the \fIkey\fR
field of a \fBTK_ARGV_HELP\fR specifier is NULL, then the specifier will
never match any arguments;  in this case the specifier simply provides
extra documentation, which will be included when some other
\fBTK_ARGV_HELP\fR entry causes help information to be returned.

.IP \fBTK_ARGV_REST\fR
This option is used by programs or commands that allow the last
several of their options to be the name and/or options for some
other program.  If a \fBTK_ARGV_REST\fR argument is found, then
\fBTk_ParseArgv\fR does not process any
of the remaining arguments;  it returns them all at
the beginning of \fIargv\fR (along with any other unprocessed arguments).
In addition, \fBTk_ParseArgv\fR treats \fIdst\fR as the address of an
integer value, and stores at \fI*dst\fR the index of the first of the
\fBTK_ARGV_REST\fR options in the returned \fIargv\fR.  This allows the
program to distinguish the \fBTK_ARGV_REST\fR options from other
unprocessed options that preceded the \fBTK_ARGV_REST\fR.

.IP \fBTK_ARGV_FUNC\fR
For this kind of argument, \fIsrc\fR is treated as the address of
a procedure, which is invoked to process the following argument.
The procedure should have the following structure:
.RS
.CS
int
\fIfunc\fR(\fIdst\fR, \fIkey\fR, \fInextArg\fR)
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
(or NULL if there are not any more arguments left in \fIargv\fR).
If \fIfunc\fR uses \fInextArg\fR (so that
\fBTk_ParseArgv\fR should discard it), then it should return 1.  Otherwise it
should return 0 and \fBTkParseArgv\fR will process the following
argument in the normal fashion.  In either event the matching argument
is discarded.
.RE
.TP
\fBTK_ARGV_GENFUNC\fR
This form provides a more general procedural escape.  It treats
\fIsrc\fR as the address of a procedure, and passes that procedure
all of the remaining arguments.  The procedure should have the following
form:
.RS
.CS
int







<
|







217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
(or NULL if there are not any more arguments left in \fIargv\fR).
If \fIfunc\fR uses \fInextArg\fR (so that
\fBTk_ParseArgv\fR should discard it), then it should return 1.  Otherwise it
should return 0 and \fBTkParseArgv\fR will process the following
argument in the normal fashion.  In either event the matching argument
is discarded.
.RE

.IP \fBTK_ARGV_GENFUNC\fR
This form provides a more general procedural escape.  It treats
\fIsrc\fR as the address of a procedure, and passes that procedure
all of the remaining arguments.  The procedure should have the following
form:
.RS
.CS
int
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
\fBTk_ParseArgv\fR will process them.  If \fIgenfunc\fR encounters
an error then it should leave an error message in interpreter
\fIinterp\fR's result,
in the usual Tcl fashion, and return \-1;  when this happens
\fBTk_ParseArgv\fR will abort its processing and return \fBTCL_ERROR\fR.
.RE
.SS "FLAGS"
.TP
\fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR
\fBTk_ParseArgv\fR normally treats \fIargv[0]\fR as a program
or command name, and returns it to the caller just as if it
had not matched \fIargTable\fR.  If this flag is given, then
\fIargv[0]\fR is not given special treatment.
.TP
\fBTK_ARGV_NO_ABBREV\fR
Normally, \fBTk_ParseArgv\fR accepts unique abbreviations for
\fIkey\fR values in \fIargTable\fR.  If this flag is given then
only exact matches will be acceptable.
.TP
\fBTK_ARGV_NO_LEFTOVERS\fR
Normally, \fBTk_ParseArgv\fR returns unrecognized arguments to the
caller.  If this bit is set in \fIflags\fR then \fBTk_ParseArgv\fR
will return an error if it encounters any argument that does not
match \fIargTable\fR.  The only exception to this rule is \fIargv[0]\fR,
which will be returned to the caller with no errors as
long as \fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR is not specified.
.TP
\fBTK_ARGV_NO_DEFAULTS\fR
Normally, \fBTk_ParseArgv\fR searches an internal table of
standard argument specifiers in addition to \fIargTable\fR.  If
this bit is set in \fIflags\fR, then \fBTk_ParseArgv\fR will
use only \fIargTable\fR and not its default table.
.SH EXAMPLE
.PP
Here is an example definition of an \fIargTable\fR and







<
|




<
|



<
|






<
|







250
251
252
253
254
255
256

257
258
259
260
261

262
263
264
265

266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
\fBTk_ParseArgv\fR will process them.  If \fIgenfunc\fR encounters
an error then it should leave an error message in interpreter
\fIinterp\fR's result,
in the usual Tcl fashion, and return \-1;  when this happens
\fBTk_ParseArgv\fR will abort its processing and return \fBTCL_ERROR\fR.
.RE
.SS "FLAGS"

.IP \fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR
\fBTk_ParseArgv\fR normally treats \fIargv[0]\fR as a program
or command name, and returns it to the caller just as if it
had not matched \fIargTable\fR.  If this flag is given, then
\fIargv[0]\fR is not given special treatment.

.IP \fBTK_ARGV_NO_ABBREV\fR
Normally, \fBTk_ParseArgv\fR accepts unique abbreviations for
\fIkey\fR values in \fIargTable\fR.  If this flag is given then
only exact matches will be acceptable.

.IP \fBTK_ARGV_NO_LEFTOVERS\fR
Normally, \fBTk_ParseArgv\fR returns unrecognized arguments to the
caller.  If this bit is set in \fIflags\fR then \fBTk_ParseArgv\fR
will return an error if it encounters any argument that does not
match \fIargTable\fR.  The only exception to this rule is \fIargv[0]\fR,
which will be returned to the caller with no errors as
long as \fBTK_ARGV_DONT_SKIP_FIRST_ARG\fR is not specified.

.IP \fBTK_ARGV_NO_DEFAULTS\fR
Normally, \fBTk_ParseArgv\fR searches an internal table of
standard argument specifiers in addition to \fIargTable\fR.  If
this bit is set in \fIflags\fR, then \fBTk_ParseArgv\fR will
use only \fIargTable\fR and not its default table.
.SH EXAMPLE
.PP
Here is an example definition of an \fIargTable\fR and
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
char *fileName = defaultFileName;
Boolean exec = FALSE;

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

main(argc, argv)
    int argc;
    char *argv[];
{
    \&...

    if (Tk_ParseArgv(interp, tkwin, &argc, argv, argTable, 0) != TCL_OK) {
        fprintf(stderr, "%s\en", Tcl_GetString(Tcl_GetObjResult(interp)));
        exit(1);
    }

    /*
     * Remainder of the program.
     */
}
.CE
.PP
Note that default values can be assigned to variables named in
\fIargTable\fR:  the variables will only be overwritten if the
particular arguments are present in \fIargv\fR.
Here are some example command lines and their effects.
.CS
prog \-N 200 infile        # just sets the numReps variable to 200
prog \-of out200 infile    # sets fileName to reference "out200"
prog \-XN 10 infile        # sets the debug flag, also sets numReps
.CE
In all of the above examples, \fIargc\fR will be set by \fBTk_ParseArgv\fR to 2,
\fIargv\fR[0] will be
.QW prog ,
\fIargv\fR[1] will be
.QW infile ,
and \fIargv\fR[2] will be NULL.
.SH KEYWORDS
arguments, command line, options







|

|

|







<
<
|



















|
|
|









292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310


311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
char *fileName = defaultFileName;
Boolean exec = FALSE;

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



int main(int argc, char *argv[])
{
    \&...

    if (Tk_ParseArgv(interp, tkwin, &argc, argv, argTable, 0) != TCL_OK) {
        fprintf(stderr, "%s\en", Tcl_GetString(Tcl_GetObjResult(interp)));
        exit(1);
    }

    /*
     * Remainder of the program.
     */
}
.CE
.PP
Note that default values can be assigned to variables named in
\fIargTable\fR:  the variables will only be overwritten if the
particular arguments are present in \fIargv\fR.
Here are some example command lines and their effects.
.CS
prog -N 200 infile        # just sets the numReps variable to 200
prog -of out200 infile    # sets fileName to reference "out200"
prog -XN 10 infile        # sets the debug flag, also sets numReps
.CE
In all of the above examples, \fIargc\fR will be set by \fBTk_ParseArgv\fR to 2,
\fIargv\fR[0] will be
.QW prog ,
\fIargv\fR[1] will be
.QW infile ,
and \fIargv\fR[2] will be NULL.
.SH KEYWORDS
arguments, command line, options

Changes to doc/QWinEvent.3.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_CollapseMotionEvents\fR(\fIdisplay, collapse\fR)
.sp
\fBTk_QueueWindowEvent\fR(\fIeventPtr, position\fR)

.SH ARGUMENTS
.AS Tcl_QueuePosition position
.AP Display *display  in
Display for which to control motion event collapsing.
.AP int collapse in
Indicates whether motion events should be collapsed or not.
.AP XEvent *eventPtr  in







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_CollapseMotionEvents\fR(\fIdisplay, collapse\fR)
.sp
\fBTk_QueueWindowEvent\fR(\fIeventPtr, position\fR)
.fi
.SH ARGUMENTS
.AS Tcl_QueuePosition position
.AP Display *display  in
Display for which to control motion event collapsing.
.AP int collapse in
Indicates whether motion events should be collapsed or not.
.AP XEvent *eventPtr  in

Changes to doc/Restack.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_RestackWindow \- Change a window's position in the stacking order
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_RestackWindow\fR(\fItkwin, aboveBelow, other\fR)

.SH ARGUMENTS
.AS Tk_Window aboveBelow
.AP Tk_Window tkwin in
Token for window to restack.
.AP int aboveBelow in
Indicates new position of \fItkwin\fR relative to \fIother\fR;
must be \fBAbove\fR or \fBBelow\fR.







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_RestackWindow \- Change a window's position in the stacking order
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_RestackWindow\fR(\fItkwin, aboveBelow, other\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window aboveBelow
.AP Tk_Window tkwin in
Token for window to restack.
.AP int aboveBelow in
Indicates new position of \fItkwin\fR relative to \fIother\fR;
must be \fBAbove\fR or \fBBelow\fR.

Changes to doc/RestrictEv.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Tk_RestrictEvents \- filter and selectively delay X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_RestrictProc *
\fBTk_RestrictEvents\fR(\fIproc, arg, prevArgPtr\fR)

.SH ARGUMENTS
.AS Tk_RestrictProc **prevArgPtr
.AP Tk_RestrictProc *proc in
Predicate procedure to call to filter incoming X events.
NULL means do not restrict events at all.
.AP ClientData arg in
Arbitrary argument to pass to \fIproc\fR.
.AP ClientData *prevArgPtr out
Pointer to place to save argument to previous restrict procedure.
.BE
.SH DESCRIPTION
.PP
This procedure is useful in certain situations where applications
are only prepared to receive certain X events.  After
\fBTk_RestrictEvents\fR is called, \fBTcl_DoOneEvent\fR (and
hence \fBTk_MainLoop\fR) will filter X input events through
\fIproc\fR.  \fIProc\fR indicates whether a
given event is to be processed immediately, deferred until some
later time (e.g. when the event restriction is lifted), or discarded.
\fIProc\fR
is a procedure with arguments and result that match
the type \fBTk_RestrictProc\fR:
.CS
typedef Tk_RestrictAction \fBTk_RestrictProc\fR(
        ClientData \fIarg\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIarg\fR argument is a copy of the \fIarg\fR passed
to \fBTk_RestrictEvents\fR; it may be used to provide \fIproc\fR with
information it needs to filter events.  The \fIeventPtr\fR points to
an event under consideration.  \fIProc\fR returns a restrict action
(enumerated type \fBTk_RestrictAction\fR) that indicates what







>





|

|
















|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Tk_RestrictEvents \- filter and selectively delay X events
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_RestrictProc *
\fBTk_RestrictEvents\fR(\fIproc, arg, prevArgPtr\fR)
.fi
.SH ARGUMENTS
.AS Tk_RestrictProc **prevArgPtr
.AP Tk_RestrictProc *proc in
Predicate procedure to call to filter incoming X events.
NULL means do not restrict events at all.
.AP void *arg in
Arbitrary argument to pass to \fIproc\fR.
.AP void **prevArgPtr out
Pointer to place to save argument to previous restrict procedure.
.BE
.SH DESCRIPTION
.PP
This procedure is useful in certain situations where applications
are only prepared to receive certain X events.  After
\fBTk_RestrictEvents\fR is called, \fBTcl_DoOneEvent\fR (and
hence \fBTk_MainLoop\fR) will filter X input events through
\fIproc\fR.  \fIProc\fR indicates whether a
given event is to be processed immediately, deferred until some
later time (e.g. when the event restriction is lifted), or discarded.
\fIProc\fR
is a procedure with arguments and result that match
the type \fBTk_RestrictProc\fR:
.CS
typedef Tk_RestrictAction \fBTk_RestrictProc\fR(
        void *\fIarg\fR,
        XEvent *\fIeventPtr\fR);
.CE
The \fIarg\fR argument is a copy of the \fIarg\fR passed
to \fBTk_RestrictEvents\fR; it may be used to provide \fIproc\fR with
information it needs to filter events.  The \fIeventPtr\fR points to
an event under consideration.  \fIProc\fR returns a restrict action
(enumerated type \fBTk_RestrictAction\fR) that indicates what

Changes to doc/SetAppName.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_SetAppName \- Set the name of an application for 'send' commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_SetAppName\fR(\fItkwin, name\fR)

.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window in application.  Used only to select a particular
application.
.AP "const char" *name in
Name under which to register the application.







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_SetAppName \- Set the name of an application for 'send' commands
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_SetAppName\fR(\fItkwin, name\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window in application.  Used only to select a particular
application.
.AP "const char" *name in
Name under which to register the application.

Changes to doc/SetCaret.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
Tk_SetCaretPos \- set the display caret location
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_SetCaretPos\fR(\fItkwin, x, y, height\fR)

.SH ARGUMENTS
.AP Tk_Window tkwin in
Token for window.
.AP int x in
Window-relative x coordinate.
.AP int y in
Window-relative y coordinate.







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Tk_SetCaretPos \- set the display caret location
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_SetCaretPos\fR(\fItkwin, x, y, height\fR)
.fi
.SH ARGUMENTS
.AP Tk_Window tkwin in
Token for window.
.AP int x in
Window-relative x coordinate.
.AP int y in
Window-relative y coordinate.

Changes to doc/SetClass.3.

14
15
16
17
18
19
20

21
22
23
24
25
26
27
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClass\fR(\fItkwin, class\fR)
.sp
Tk_Uid
\fBTk_Class\fR(\fItkwin\fR)

.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.AP char *class in
New class name for window.
.BE







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClass\fR(\fItkwin, class\fR)
.sp
Tk_Uid
\fBTk_Class\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window parent
.AP Tk_Window tkwin in
Token for window.
.AP char *class in
New class name for window.
.BE

Changes to doc/SetClassProcs.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
.SH NAME
Tk_SetClassProcs \- register widget specific procedures
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClassProcs\fR(\fItkwin, procs, instanceData\fR)

.SH ARGUMENTS
.AS Tk_ClassProc instanceData
.AP Tk_Window tkwin in
Token for window to modify.
.AP "const Tk_ClassProcs" *procs in
Pointer to data structure containing widget specific procedures.
The data structure pointed to by \fIprocs\fR must be static:
Tk keeps a reference to it as long as the window exists.
.AP ClientData instanceData in
Arbitrary one-word value to pass to widget callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_SetClassProcs\fR is called to register a set of procedures that
are used as callbacks in different places.
.PP
The structure pointed to by \fIprocs\fR contains the following:
.CS
typedef struct Tk_ClassProcs {
    size_t \fIsize\fR;
    Tk_ClassWorldChangedProc *\fIworldChangedProc\fR;
    Tk_ClassCreateProc *\fIcreateProc\fR;
    Tk_ClassModalProc *\fImodalProc\fR;
} \fBTk_ClassProcs\fR;
.CE
The \fIsize\fR field is used to simplify future expansion of the
structure. It should always be set to (literally) \fBsizeof(Tk_ClassProcs)\fR.
.PP
\fIworldChangedProc\fR is invoked when the system has altered
in some way that requires some reaction from the widget.  For example,
when a font alias (see the \fBfont\fR manual entry) is reconfigured,
widgets configured to use that font alias must update their display
accordingly.  \fIworldChangedProc\fR should have arguments and results
that match the type \fBTk_ClassWorldChangedProc\fR:
.CS
typedef void \fBTk_ClassWorldChangedProc\fR(
        ClientData \fIinstanceData\fR);
.CE
The \fIinstanceData\fR parameter passed to the \fIworldChangedProc\fR
will be identical to the \fIinstanceData\fR parameter passed to
\fBTk_SetClassProcs\fR.
.PP
\fIcreateProc\fR is used to create platform-dependent windows.  It is
invoked by \fBTk_MakeWindowExist\fR.  \fIcreateProc\fR should have
arguments and results that match the type \fBTk_ClassCreateProc\fR:
.CS
typedef Window \fBTk_ClassCreateProc\fR(
        Tk_Window \fItkwin\fR,
        Window \fIparent\fR,
        ClientData \fIinstanceData\fR);
.CE
The \fItkwin\fR and \fIinstanceData\fR parameters will be identical to
the \fItkwin\fR and \fIinstanceData\fR parameters passed to
\fBTk_SetClassProcs\fR.  The \fIparent\fR parameter will be the parent
of the window to be created.  The \fIcreateProc\fR should return the
created window.
.PP







>








|









|

















|












|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
.SH NAME
Tk_SetClassProcs \- register widget specific procedures
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetClassProcs\fR(\fItkwin, procs, instanceData\fR)
.fi
.SH ARGUMENTS
.AS Tk_ClassProc instanceData
.AP Tk_Window tkwin in
Token for window to modify.
.AP "const Tk_ClassProcs" *procs in
Pointer to data structure containing widget specific procedures.
The data structure pointed to by \fIprocs\fR must be static:
Tk keeps a reference to it as long as the window exists.
.AP void *instanceData in
Arbitrary one-word value to pass to widget callbacks.
.BE
.SH DESCRIPTION
.PP
\fBTk_SetClassProcs\fR is called to register a set of procedures that
are used as callbacks in different places.
.PP
The structure pointed to by \fIprocs\fR contains the following:
.CS
typedef struct {
    size_t \fIsize\fR;
    Tk_ClassWorldChangedProc *\fIworldChangedProc\fR;
    Tk_ClassCreateProc *\fIcreateProc\fR;
    Tk_ClassModalProc *\fImodalProc\fR;
} \fBTk_ClassProcs\fR;
.CE
The \fIsize\fR field is used to simplify future expansion of the
structure. It should always be set to (literally) \fBsizeof(Tk_ClassProcs)\fR.
.PP
\fIworldChangedProc\fR is invoked when the system has altered
in some way that requires some reaction from the widget.  For example,
when a font alias (see the \fBfont\fR manual entry) is reconfigured,
widgets configured to use that font alias must update their display
accordingly.  \fIworldChangedProc\fR should have arguments and results
that match the type \fBTk_ClassWorldChangedProc\fR:
.CS
typedef void \fBTk_ClassWorldChangedProc\fR(
        void *\fIinstanceData\fR);
.CE
The \fIinstanceData\fR parameter passed to the \fIworldChangedProc\fR
will be identical to the \fIinstanceData\fR parameter passed to
\fBTk_SetClassProcs\fR.
.PP
\fIcreateProc\fR is used to create platform-dependent windows.  It is
invoked by \fBTk_MakeWindowExist\fR.  \fIcreateProc\fR should have
arguments and results that match the type \fBTk_ClassCreateProc\fR:
.CS
typedef Window \fBTk_ClassCreateProc\fR(
        Tk_Window \fItkwin\fR,
        Window \fIparent\fR,
        void *\fIinstanceData\fR);
.CE
The \fItkwin\fR and \fIinstanceData\fR parameters will be identical to
the \fItkwin\fR and \fIinstanceData\fR parameters passed to
\fBTk_SetClassProcs\fR.  The \fIparent\fR parameter will be the parent
of the window to be created.  The \fIcreateProc\fR should return the
created window.
.PP

Changes to doc/SetGrid.3.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetGrid\fR(\fItkwin, reqWidth, reqHeight, widthInc, heightInc\fR)
.sp
\fBTk_UnsetGrid\fR(\fItkwin\fR)

.SH ARGUMENTS
.AS Tk_Window heightInc
.AP Tk_Window tkwin in
Token for window.
.AP int reqWidth in
Width in grid units that corresponds to the pixel dimension \fItkwin\fR
has requested via \fBTk_GeometryRequest\fR.







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_SetGrid\fR(\fItkwin, reqWidth, reqHeight, widthInc, heightInc\fR)
.sp
\fBTk_UnsetGrid\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window heightInc
.AP Tk_Window tkwin in
Token for window.
.AP int reqWidth in
Width in grid units that corresponds to the pixel dimension \fItkwin\fR
has requested via \fBTk_GeometryRequest\fR.

Changes to doc/SetOptions.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
.SH NAME
Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue,  Tk_GetOptionInfo, Tk_FreeConfigOptions \- process configuration options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_OptionTable
\fBTk_CreateOptionTable(\fIinterp, templatePtr\fB)\fR
.sp
\fBTk_DeleteOptionTable(\fIoptionTable\fB)\fR
.sp
int
\fBTk_InitOptions(\fIinterp, recordPtr, optionTable, tkwin\fB)\fR
.sp
int
\fBTk_SetOptions(\fIinterp, recordPtr, optionTable, objc, objv, tkwin, savePtr, maskPtr\fB)\fR
.sp
\fBTk_FreeSavedOptions(\fIsavedPtr\fB)\fR
.sp
\fBTk_RestoreSavedOptions(\fIsavedPtr\fB)\fR
.sp
Tcl_Obj *
\fBTk_GetOptionValue(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
.sp
Tcl_Obj *
\fBTk_GetOptionInfo(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
.sp
\fBTk_FreeConfigOptions(\fIrecordPtr, optionTable, tkwin\fB)\fR

.SH ARGUMENTS
.AS Tk_SavedOptions "*const objv[]" in/out
.AP Tcl_Interp *interp in
A Tcl interpreter.  Most procedures use this only for returning error
messages; if it is NULL then no error messages are returned.  For
\fBTk_CreateOptionTable\fR the value cannot be NULL; it gives the
interpreter in which the option table will be used.







|

|


|


|

|

|


|


|

|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.SH NAME
Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue,  Tk_GetOptionInfo, Tk_FreeConfigOptions \- process configuration options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_OptionTable
\fBTk_CreateOptionTable\fR(\fIinterp, templatePtr\fR)
.sp
\fBTk_DeleteOptionTable\fR(\fIoptionTable\fR)
.sp
int
\fBTk_InitOptions\fR(\fIinterp, recordPtr, optionTable, tkwin\fR)
.sp
int
\fBTk_SetOptions\fR(\fIinterp, recordPtr, optionTable, objc, objv, tkwin, savePtr, maskPtr\fR)
.sp
\fBTk_FreeSavedOptions\fR(\fIsavedPtr\fR)
.sp
\fBTk_RestoreSavedOptions\fR(\fIsavedPtr\fR)
.sp
Tcl_Obj *
\fBTk_GetOptionValue\fR(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fR)
.sp
Tcl_Obj *
\fBTk_GetOptionInfo\fR(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fR)
.sp
\fBTk_FreeConfigOptions\fR(\fIrecordPtr, optionTable, tkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_SavedOptions "*const objv[]" in/out
.AP Tcl_Interp *interp in
A Tcl interpreter.  Most procedures use this only for returning error
messages; if it is NULL then no error messages are returned.  For
\fBTk_CreateOptionTable\fR the value cannot be NULL; it gives the
interpreter in which the option table will be used.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
fields of this record are modified by procedures such as \fBTk_SetOptions\fR
and read by procedures such as \fBTk_GetOptionValue\fR.
.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for
this argument.
.AP int objc in
Number of values in \fIobjv\fR.
.AP Tcl_Obj "*const *objv" in
Command-line arguments for setting configuring options.
.AP Tk_SavedOptions *savePtr out
If not NULL, the structure pointed to by this argument is filled
in with the old values of any options that were modified and old
values are restored automatically if an error occurs in \fBTk_SetOptions\fR.







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
fields of this record are modified by procedures such as \fBTk_SetOptions\fR
and read by procedures such as \fBTk_GetOptionValue\fR.
.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for
this argument.
.AP Tcl_Size objc in
Number of values in \fIobjv\fR.
.AP Tcl_Obj "*const *objv" in
Command-line arguments for setting configuring options.
.AP Tk_SavedOptions *savePtr out
If not NULL, the structure pointed to by this argument is filled
in with the old values of any options that were modified and old
values are restored automatically if an error occurs in \fBTk_SetOptions\fR.
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
.QW widget
will be used to refer to the object whose options are being managed; in
practice the object may not actually be a widget.  The term
.QW "widget record"
is used to refer to the C-level structure in
which information about a particular widget or object is stored.
.PP
Note: the easiest way to learn how to use these procedures is to
look at a working example.  In Tk, the simplest example is the code
that implements the button family of widgets, which is in \fBtkButton.c\fR.
Other examples are in \fBtkSquare.c\fR and \fBtkMenu.c\fR.
.PP
In order to use these procedures, the code that implements the widget
must contain a static array of Tk_OptionSpec structures. This is a
template that describes the various options supported by that class of







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
.QW widget
will be used to refer to the object whose options are being managed; in
practice the object may not actually be a widget.  The term
.QW "widget record"
is used to refer to the C-level structure in
which information about a particular widget or object is stored.
.PP
Note that the easiest way to learn how to use these procedures is to
look at a working example.  In Tk, the simplest example is the code
that implements the button family of widgets, which is in \fBtkButton.c\fR.
Other examples are in \fBtkSquare.c\fR and \fBtkMenu.c\fR.
.PP
In order to use these procedures, the code that implements the widget
must contain a static array of Tk_OptionSpec structures. This is a
template that describes the various options supported by that class of
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
class.  A Tk_OptionTable may be used only in a single interpreter, given
by the \fIinterp\fR argument to \fBTk_CreateOptionTable\fR.  When an
option table is no longer needed \fBTk_DeleteOptionTable\fR should be
called to free all of its resources.  All of the option tables
for a Tcl interpreter are freed automatically if the interpreter is deleted.
.PP
\fBTk_InitOptions\fR is invoked when a new widget is created to set the
default values for all of the widget's configuration options that do not
have \fBTK_OPTION_DONT_SET_DEFAULT\fR set in their \fIflags\fR field.
\fBTk_InitOptions\fR is passed a token for an option table
(\fIoptionTable\fR) and a pointer to a widget record (\fIrecordPtr\fR),
which is the C structure that holds information about this widget.
\fBTk_InitOptions\fR uses the information in the option table to choose an
appropriate default for each option, except those having
\fBTK_OPTION_DONT_SET_DEFAULT\fR set, then it stores the default value
directly into the widget record, overwriting any information that was
already present in the widget record.  \fBTk_InitOptions\fR normally
returns \fBTCL_OK\fR.  If an error occurred while setting the default
values (e.g., because a default value was erroneous) then \fBTCL_ERROR\fR
is returned and an error message is left in \fIinterp\fR's result if
\fIinterp\fR is not NULL.


.PP
\fBTk_SetOptions\fR is invoked to modify configuration options based
on information specified in a Tcl command.  The command might be one that
creates a new widget, or a command that modifies options on an existing
widget.  The \fIobjc\fR and \fIobjv\fR arguments describe the
values of the arguments from the Tcl command.  \fIObjv\fR must contain
an even number of objects: the first object of each pair gives the name of







|
<




|
<





|
>
>







124
125
126
127
128
129
130
131

132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
class.  A Tk_OptionTable may be used only in a single interpreter, given
by the \fIinterp\fR argument to \fBTk_CreateOptionTable\fR.  When an
option table is no longer needed \fBTk_DeleteOptionTable\fR should be
called to free all of its resources.  All of the option tables
for a Tcl interpreter are freed automatically if the interpreter is deleted.
.PP
\fBTk_InitOptions\fR is invoked when a new widget is created to set the
default values.

\fBTk_InitOptions\fR is passed a token for an option table
(\fIoptionTable\fR) and a pointer to a widget record (\fIrecordPtr\fR),
which is the C structure that holds information about this widget.
\fBTk_InitOptions\fR uses the information in the option table to choose an
appropriate default for each option, then it stores the default value

directly into the widget record, overwriting any information that was
already present in the widget record.  \fBTk_InitOptions\fR normally
returns \fBTCL_OK\fR.  If an error occurred while setting the default
values (e.g., because a default value was erroneous) then \fBTCL_ERROR\fR
is returned and an error message is left in \fIinterp\fR's result if
\fIinterp\fR is not NULL. For any widget's configuration option that
has \fBTK_OPTION_DONT_SET_DEFAULT\fR set in its \fIflags\fR field,
the above initialization is fully skipped, see below.
.PP
\fBTk_SetOptions\fR is invoked to modify configuration options based
on information specified in a Tcl command.  The command might be one that
creates a new widget, or a command that modifies options on an existing
widget.  The \fIobjc\fR and \fIobjv\fR arguments describe the
values of the arguments from the Tcl command.  \fIObjv\fR must contain
an even number of objects: the first object of each pair gives the name of
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322













323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346

347


348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401





402
403





404
405
406
407
408



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
\fBTK_OPTION_INT\fR then the internal form is an integer.  If the
\fIobjOffset\fR or \fIinternalOffset\fR field is negative then the
value is not stored in that form.  At least one of the offsets must be
greater than or equal to zero.
.PP
The \fIflags\fR field consists of one or more bits ORed together. The
following flags are supported:
.TP
\fBTK_OPTION_NULL_OK\fR
If this bit is set for an option then an empty string will be accepted as
the value for the option and the resulting internal form will be a NULL
pointer, a zero value, or \fBNone\fR, depending on the type of the option.
If the flag is not set then empty strings will result in errors.
\fBTK_OPTION_NULL_OK\fR is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
Not all option types support the \fBTK_OPTION_NULL_OK\fR
flag; for those that do, there is an explicit indication of that fact
in the descriptions below.
.TP
\fBTK_OPTION_DONT_SET_DEFAULT\fR
If this bit is set for an option then no default value will be set in
\fBTk_InitOptions\fR for this option. Neither the option database, nor any
system default value, nor \fIoptionTable\fR are used to give a default
value to this option. Instead it is assumed that the caller has already
supplied a default value in the widget code.













.PP
The \fItype\fR field of each Tk_OptionSpec structure determines
how to parse the value of that configuration option. The
legal value for \fItype\fR, and the corresponding actions, are
described below.  If the type requires a \fItkwin\fR value to be
passed into procedures like \fBTk_SetOptions\fR, or if it uses
the \fIclientData\fR field of the Tk_OptionSpec, then it is indicated
explicitly; if not mentioned, the type requires neither \fItkwin\fR
nor \fIclientData\fR.
.TP
\fBTK_OPTION_ANCHOR\fR
The value must be a standard anchor position such as \fBne\fR or
\fBcenter\fR.  The internal form is a Tk_Anchor value like the ones
returned by \fBTk_GetAnchorFromObj\fR.
.TP

\fBTK_OPTION_BITMAP\fR
The value must be a standard Tk bitmap name. The internal form is a
Pixmap token like the ones returned by \fBTk_AllocBitmapFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_BOOLEAN\fR
The value must be a standard boolean value such as \fBtrue\fR or
\fBno\fR.  The internal form is an integer with value 0 or 1.

.TP


\fBTK_OPTION_BORDER\fR
The value must be a standard color name such as \fBred\fR or \fB#ff8080\fR.
The internal form is a Tk_3DBorder token like the ones returned
by \fBTk_Alloc3DBorderFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_COLOR\fR
The value must be a standard color name such as \fBred\fR or \fB#ff8080\fR.
The internal form is an (XColor *) token like the ones returned by
\fBTk_AllocColorFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_CURSOR\fR
The value must be a standard cursor name such as \fBcross\fR or \fB@foo\fR.
The internal form is a Tk_Cursor token like the ones returned by
\fBTk_AllocCursorFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and when the option is set the cursor
for the window is changed by calling \fBXDefineCursor\fR.  This
option type also supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_CUSTOM\fR
This option allows applications to define new option types.  The
clientData field of the entry points to a structure defining the new
option type.  See the section \fBCUSTOM OPTION TYPES\fR below for details.
.TP
\fBTK_OPTION_DOUBLE\fR
The string value must be a floating-point number in
the format accepted by \fBstrtol\fR.  The internal form is a C
\fBdouble\fR value.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if a NULL value is set, the internal representation is set to zero.
.TP
\fBTK_OPTION_END\fR
Marks the end of the template.  There must be a Tk_OptionSpec structure
with \fItype\fR \fBTK_OPTION_END\fR at the end of each template.  If the
\fIclientData\fR field of this structure is not NULL, then it points to
an additional array of Tk_OptionSpec's, which is itself terminated by
another \fBTK_OPTION_END\fR entry.  Templates may be chained arbitrarily
deeply.  This feature allows common options to be shared by several
widget classes.
.TP
\fBTK_OPTION_FONT\fR
The value must be a standard font name such as \fBTimes 16\fR.
The internal form is a Tk_Font handle like the ones returned by
\fBTk_AllocFontFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_INT\fR
The string value must be an integer in the format accepted by
\fBstrtol\fR (e.g. \fB0\fR and \fB0x\fR prefixes may be used to
specify octal or hexadecimal numbers, respectively).  The internal





form is a C \fBint\fR value.
.TP





\fBTK_OPTION_JUSTIFY\fR
The value must be a standard justification value such as \fBleft\fR.
The internal form is a Tk_Justify like the values returned by
\fBTk_GetJustifyFromObj\fR.
.TP



\fBTK_OPTION_PIXELS\fR
The value must specify a screen distance such as \fB2i\fR or \fB6.4\fR.
The internal form is an integer value giving a
distance in pixels, like the values returned by
\fBTk_GetPixelsFromObj\fR.  Note: if the \fIobjOffset\fR field is not
used then information about the original value of this option will be lost.
See \fBOBJOFFSET VS. INTERNALOFFSET\fR below for details.  This option
type supports the \fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the
internal representation is set to zero.
.TP
\fBTK_OPTION_RELIEF\fR
The value must be standard relief such as \fBraised\fR.
The internal form is an integer relief value such as
\fBTK_RELIEF_RAISED\fR.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if the empty string is specified as the value for the option,
the integer relief value is set to \fBTK_RELIEF_NULL\fR.
.TP
\fBTK_OPTION_STRING\fR
The value may be any string.  The internal form is a (char *) pointer
that points to a dynamically allocated copy of the value.
This option type supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_STRING_TABLE\fR
For this type, \fIclientData\fR is a pointer to an array of strings
suitable for passing to \fBTcl_GetIndexFromObj\fR.  The value must
be one of the strings in the table, or a unique abbreviation of
one of the strings.  The internal form is an integer giving the index
into the table of the matching string, like the return value
from \fBTcl_GetStringFromObj\fR.  This option type supports the
\fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the internal
representation is set to -1.
.TP
\fBTK_OPTION_SYNONYM\fR
This type is used to provide alternative names for an option (for
example, \fB\-bg\fR is often used as a synonym for \fB\-background\fR).
The \fBclientData\fR field is a string that gives the name of another
option in the same table.  Whenever the synonym option is used, the
information from the other option will be used instead.
.TP
\fBTK_OPTION_WINDOW\fR
The value must be a window path name.  The internal form is a
\fBTk_Window\fR token for the window.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR (in order to identify the application),
and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.SH "STORAGE MANAGEMENT ISSUES"
.PP







<
|










<
|





>
>
>
>
>
>
>
>
>
>
>
>
>









|
|


|
|
>
|




<
|

|
>
|
>
>
|





<
|





<
|







<
|



<
|



|
<
|







<
|





<
|


|
>
>
>
>
>
|
<
>
>
>
>
>
|


|
<
>
>
>
|



|
|


|
<
|



|
|
<
|



<
|








<
|





<
|







298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

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

369
370
371
372
373
374

375
376
377
378
379
380
381
382

383
384
385
386

387
388
389
390
391

392
393
394
395
396
397
398
399

400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424

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

437
438
439
440
441
442

443
444
445
446

447
448
449
450
451
452
453
454
455

456
457
458
459
460
461

462
463
464
465
466
467
468
469
\fBTK_OPTION_INT\fR then the internal form is an integer.  If the
\fIobjOffset\fR or \fIinternalOffset\fR field is negative then the
value is not stored in that form.  At least one of the offsets must be
greater than or equal to zero.
.PP
The \fIflags\fR field consists of one or more bits ORed together. The
following flags are supported:

.IP \fBTK_OPTION_NULL_OK\fR
If this bit is set for an option then an empty string will be accepted as
the value for the option and the resulting internal form will be a NULL
pointer, a zero value, or \fBNone\fR, depending on the type of the option.
If the flag is not set then empty strings will result in errors.
\fBTK_OPTION_NULL_OK\fR is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
Not all option types support the \fBTK_OPTION_NULL_OK\fR
flag; for those that do, there is an explicit indication of that fact
in the descriptions below.

.IP \fBTK_OPTION_DONT_SET_DEFAULT\fR
If this bit is set for an option then no default value will be set in
\fBTk_InitOptions\fR for this option. Neither the option database, nor any
system default value, nor \fIoptionTable\fR are used to give a default
value to this option. Instead it is assumed that the caller has already
supplied a default value in the widget code.
.IP \fBTK_OPTION_ENUM_VAR\fR
If this value is set for an option, then it indicates the the
internalOffset points to an enum variable in stead of an int variable.
Only useful in combination with \fBTK_OPTION_STRING_TABLE\fR,
\fBTK_OPTION_BOOLEAN\fR, \fBTK_OPTION_ANCHOR\fR, \fBTK_OPTION_JUSTIFY\fR,
or \fBTK_OPTION_ANCHOR\fR.
.IP \fBTK_OPTION_VAR(\fItype\fB)\fR
If this value is set for an option, then it indicates the the
internalOffset points to a \fItype\fR variable in stead of an int variable.
Only useful in combination with \fBTK_OPTION_STRING_TABLE\fR or
\fBTK_OPTION_BOOLEAN\fR, or as \fBTK_OPTION_VAR(Tcl_Size)\fR
with \fBTK_OPTION_INT\fR
.RS
.PP
The \fItype\fR field of each Tk_OptionSpec structure determines
how to parse the value of that configuration option. The
legal value for \fItype\fR, and the corresponding actions, are
described below.  If the type requires a \fItkwin\fR value to be
passed into procedures like \fBTk_SetOptions\fR, or if it uses
the \fIclientData\fR field of the Tk_OptionSpec, then it is indicated
explicitly; if not mentioned, the type requires neither \fItkwin\fR
nor \fIclientData\fR.
.RE
.IP \fBTK_OPTION_ANCHOR\fR
The value must be a standard anchor position such as \fBne\fR or
\fBcenter\fR.  The internal form is a Tk_Anchor value like the ones
returned by \fBTk_GetAnchorFromObj\fR.  This option type supports the
\fBTK_OPTION_NULL_OK\fR flag; if the empty string is specified as the
value for the option, the integer relief value is set to \fBTK_ANCHOR_NULL\fR.
.IP \fBTK_OPTION_BITMAP\fR
The value must be a standard Tk bitmap name. The internal form is a
Pixmap token like the ones returned by \fBTk_AllocBitmapFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fBTK_OPTION_BOOLEAN\fR
The value must be a standard boolean value such as \fBtrue\fR or
\fBno\fR.  The internal form is an integer with value 0 or 1.  Note that if
the \fIobjOffset\fR field is not used, information about the original
value of this option will be lost.  This option type supports the
\fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the internal
representation is set to -1.
.IP \fBTK_OPTION_BORDER\fR
The value must be a standard color name such as \fBred\fR or \fB#ff8080\fR.
The internal form is a Tk_3DBorder token like the ones returned
by \fBTk_Alloc3DBorderFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fBTK_OPTION_COLOR\fR
The value must be a standard color name such as \fBred\fR or \fB#ff8080\fR.
The internal form is an (XColor *) token like the ones returned by
\fBTk_AllocColorFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fBTK_OPTION_CURSOR\fR
The value must be a standard cursor name such as \fBcross\fR or \fB@foo\fR.
The internal form is a Tk_Cursor token like the ones returned by
\fBTk_AllocCursorFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and when the option is set the cursor
for the window is changed by calling \fBXDefineCursor\fR.  This
option type also supports the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fBTK_OPTION_CUSTOM\fR
This option allows applications to define new option types.  The
clientData field of the entry points to a structure defining the new
option type.  See the section \fBCUSTOM OPTION TYPES\fR below for details.

.IP \fBTK_OPTION_DOUBLE\fR
The string value must be a floating-point number in
the format accepted by \fBstrtol\fR.  The internal form is a C
\fBdouble\fR value.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if a NULL value is set, the internal representation is set to NaN.

.IP \fBTK_OPTION_END\fR
Marks the end of the template.  There must be a Tk_OptionSpec structure
with \fItype\fR \fBTK_OPTION_END\fR at the end of each template.  If the
\fIclientData\fR field of this structure is not NULL, then it points to
an additional array of Tk_OptionSpec's, which is itself terminated by
another \fBTK_OPTION_END\fR entry.  Templates may be chained arbitrarily
deeply.  This feature allows common options to be shared by several
widget classes.

.IP \fBTK_OPTION_FONT\fR
The value must be a standard font name such as \fBTimes 16\fR.
The internal form is a Tk_Font handle like the ones returned by
\fBTk_AllocFontFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fBTK_OPTION_INT\fR
The string value must be an integer in the format accepted by
\fBstrtol\fR (e.g. \fB0\fR and \fB0x\fR prefixes may be used to
specify octal or hexadecimal numbers, respectively).  The internal form is
a C \fBint\fR value.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if a NULL value is set, the internal representation is set to INT_MIN.
.IP \fBTK_OPTION_INDEX\fR
The string value must be an index in the format accepted by
\fBTcl_GetIntForIndex()\fR
or the empty string.  The internal form is a C \fBint\fR value. If the string

starts with \fB\-\fR, the internal representation will be set to INT_MIN. If the
string has the form \fBend-???\fR, then the result will be a negative number:
\fB-1\fR stands for \fBend\fR, \fB-2\fR stands for \fBend-1\fR and so on.
This option type supports the \fBTK_OPTION_NULL_OK\fR flag;
if a NULL value is set, the internal representation is set to INT_MIN.
.IP \fBTK_OPTION_JUSTIFY\fR
The value must be a standard justification value such as \fBleft\fR.
The internal form is a Tk_Justify like the values returned by
\fBTk_GetJustifyFromObj\fR.  This option type supports the

\fBTK_OPTION_NULL_OK\fR
flag; if the empty string is specified as the value for the option,
the integer relief value is set to \fBTK_JUSTIFY_NULL\fR.
.IP \fBTK_OPTION_PIXELS\fR
The value must specify a screen distance such as \fB2i\fR or \fB6.4\fR.
The internal form is an integer value giving a
distance in pixels, like the values returned by
\fBTk_GetPixelsFromObj\fR.  Note that if the \fIobjOffset\fR field is not
used, information about the original value of this option will be lost.
See \fBOBJOFFSET VS. INTERNALOFFSET\fR below for details.  This option
type supports the \fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the
internal representation is set to INT_MIN.

.IP \fBTK_OPTION_RELIEF\fR
The value must be standard relief such as \fBraised\fR.
The internal form is an integer relief value such as
\fBTK_RELIEF_RAISED\fR.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if a NULL value is set, the internal representation is set to
\fBTK_RELIEF_NULL\fR.

.IP \fBTK_OPTION_STRING\fR
The value may be any string.  The internal form is a (char *) pointer
that points to a dynamically allocated copy of the value.
This option type supports the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fBTK_OPTION_STRING_TABLE\fR
For this type, \fIclientData\fR is a pointer to an array of strings
suitable for passing to \fBTcl_GetIndexFromObj\fR.  The value must
be one of the strings in the table, or a unique abbreviation of
one of the strings.  The internal form is an integer giving the index
into the table of the matching string, like the return value
from \fBTcl_GetStringFromObj\fR.  This option type supports the
\fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the internal
representation is set to -1.

.IP \fBTK_OPTION_SYNONYM\fR
This type is used to provide alternative names for an option (for
example, \fB\-bg\fR is often used as a synonym for \fB\-background\fR).
The \fBclientData\fR field is a string that gives the name of another
option in the same table.  Whenever the synonym option is used, the
information from the other option will be used instead.

.IP \fBTK_OPTION_WINDOW\fR
The value must be a window path name.  The internal form is a
\fBTk_Window\fR token for the window.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR (in order to identify the application),
and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.SH "STORAGE MANAGEMENT ISSUES"
.PP
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506




507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
the original screen-independent value. Thus for \fBTK_OPTION_PIXELS\fR options
it is better to use the \fIobjOffset\fR field.  In this case the original
value of the option is retained in the object and can be returned when
the option is retrieved.  In most cases it is convenient to use the
\fIinternalOffset\fR field as well, so that the integer value is
immediately available for use in the widget code (alternatively,
\fBTk_GetPixelsFromObj\fR can be used to extract the integer value from
the object whenever it is needed).  Note: the problem of losing information
on retrievals exists only for \fBTK_OPTION_PIXELS\fR options.
.PP
The second reason to use the \fIobjOffset\fR field is in order to
implement new types of options not supported by these procedures.
To implement a new type of option, you can use \fBTK_OPTION_STRING\fR as
the type in the Tk_OptionSpec structure and set the \fIobjOffset\fR field
but not the \fIinternalOffset\fR field.  Then, after calling
\fBTk_SetOptions\fR, convert the object to internal form yourself.




.SH "CUSTOM OPTION TYPES"
.PP
Applications can extend the built-in configuration types with
additional configuration types by writing procedures to parse, print,
free, and restore saved copies of the type and creating a structure
pointing to those procedures:
.CS
typedef struct Tk_ObjCustomOption {
    char *name;
    Tk_CustomOptionSetProc *\fIsetProc\fR;
    Tk_CustomOptionGetProc *\fIgetProc\fR;
    Tk_CustomOptionRestoreProc *\fIrestoreProc\fR;
    Tk_CustomOptionFreeProc *\fIfreeProc\fR;
    ClientData \fIclientData\fR;
} \fBTk_ObjCustomOption\fR;

typedef int \fBTk_CustomOptionSetProc\fR(
    ClientData \fIclientData\fR,
    Tcl_Interp *\fIinterp\fR,
    Tk_Window \fItkwin\fR,
    Tcl_Obj **\fIvaluePtr\fR,
    char *\fIrecordPtr\fR,
    int \fIinternalOffset\fR,
    char *\fIsaveInternalPtr\fR,
    int \fIflags\fR);

typedef Tcl_Obj *\fBTk_CustomOptionGetProc\fR(
    ClientData \fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIrecordPtr\fR,
    int \fIinternalOffset\fR);

typedef void \fBTk_CustomOptionRestoreProc\fR(
    ClientData \fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIinternalPtr\fR,
    char *\fIsaveInternalPtr\fR);

typedef void \fBTk_CustomOptionFreeProc\fR(
    ClientData \fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIinternalPtr\fR);
.CE
.PP
The Tk_ObjCustomOption structure contains six fields: a name
for the custom option type; pointers to the four procedures; and a
\fIclientData\fR value to be passed to those procedures when they are
invoked.  The \fIclientData\fR value typically points to a structure
containing information that is needed by the procedures when they are
parsing and printing options.  \fIRestoreProc\fR and \fIfreeProc\fR
may be NULL, indicating that no function should be called for those
operations.
.PP
The \fIsetProc\fR procedure is invoked by \fBTk_SetOptions\fR to
convert a Tcl_Obj into an internal representation and store the
resulting value in the widget record.  The arguments are:
.RS
.TP
\fIclientData\fR
A copy of the \fIclientData\fR field in the Tk_ObjCustomOption
structure.
.TP
\fIinterp\fR
A pointer to a Tcl interpreter, used for error reporting.
.TP
\fITkwin\fR
A copy of the \fItkwin\fR argument to \fBTk_SetOptions\fR
.TP
\fIvaluePtr\fR
A pointer to a reference to a Tcl_Obj describing the new value for the
option; it could have been specified explicitly in the call to
\fBTk_SetOptions\fR or it could come from the option database or a
default.  If the objOffset for the option is non-negative (the option
value is stored as a (Tcl_Obj *) in the widget record), the Tcl_Obj
pointer referenced by \fIvaluePtr\fR is the pointer that will be
stored at the objOffset for the option.  \fISetProc\fR may modify the
value if necessary; for example, \fIsetProc\fR may change the value to
NULL to support the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fIrecordPtr\fR
A pointer to the start of the widget record to modify.
.TP
\fIinternalOffset\fR
Offset in bytes from the start of the widget record to the location
where the internal representation of the option value is to be placed.
.TP
\fIsaveInternalPtr\fR
A pointer to storage allocated in a Tk_SavedOptions structure for the
internal representation of the original option value.  Before setting
the option to its new value, \fIsetProc\fR should set the value
referenced by \fIsaveInternalPtr\fR to the original value of the
option in order to support \fBTk_RestoreSavedOptions\fR.
.TP
\fIflags\fR
A copy of the \fIflags\fR field in the Tk_OptionSpec structure for the
option
.RE
.PP
\fISetProc\fR returns a standard Tcl result: \fBTCL_OK\fR to indicate successful
processing, or \fBTCL_ERROR\fR to indicate a failure of any kind.  An error
message may be left in the Tcl interpreter given by \fIinterp\fR in







|
|







>
>
>
>







|





|



|









|





|





|

















<
|


<
|

<
|

<
|









<
|

<
|


<
|





<
|







505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582
583
584

585
586

587
588

589
590
591
592
593
594
595
596
597
598

599
600

601
602
603

604
605
606
607
608
609

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

typedef int \fBTk_CustomOptionSetProc\fR(
    void *\fIclientData\fR,
    Tcl_Interp *\fIinterp\fR,
    Tk_Window \fItkwin\fR,
    Tcl_Obj **\fIvaluePtr\fR,
    char *\fIrecordPtr\fR,
    int \fIinternalOffset\fR,
    char *\fIsaveInternalPtr\fR,
    int \fIflags\fR);

typedef Tcl_Obj *\fBTk_CustomOptionGetProc\fR(
    void *\fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIrecordPtr\fR,
    int \fIinternalOffset\fR);

typedef void \fBTk_CustomOptionRestoreProc\fR(
    void *\fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIinternalPtr\fR,
    char *\fIsaveInternalPtr\fR);

typedef void \fBTk_CustomOptionFreeProc\fR(
    void *\fIclientData\fR,
    Tk_Window \fItkwin\fR,
    char *\fIinternalPtr\fR);
.CE
.PP
The Tk_ObjCustomOption structure contains six fields: a name
for the custom option type; pointers to the four procedures; and a
\fIclientData\fR value to be passed to those procedures when they are
invoked.  The \fIclientData\fR value typically points to a structure
containing information that is needed by the procedures when they are
parsing and printing options.  \fIRestoreProc\fR and \fIfreeProc\fR
may be NULL, indicating that no function should be called for those
operations.
.PP
The \fIsetProc\fR procedure is invoked by \fBTk_SetOptions\fR to
convert a Tcl_Obj into an internal representation and store the
resulting value in the widget record.  The arguments are:
.RS

.IP \fIclientData\fR
A copy of the \fIclientData\fR field in the Tk_ObjCustomOption
structure.

.IP \fIinterp\fR
A pointer to a Tcl interpreter, used for error reporting.

.IP \fITkwin\fR
A copy of the \fItkwin\fR argument to \fBTk_SetOptions\fR

.IP \fIvaluePtr\fR
A pointer to a reference to a Tcl_Obj describing the new value for the
option; it could have been specified explicitly in the call to
\fBTk_SetOptions\fR or it could come from the option database or a
default.  If the objOffset for the option is non-negative (the option
value is stored as a (Tcl_Obj *) in the widget record), the Tcl_Obj
pointer referenced by \fIvaluePtr\fR is the pointer that will be
stored at the objOffset for the option.  \fISetProc\fR may modify the
value if necessary; for example, \fIsetProc\fR may change the value to
NULL to support the \fBTK_OPTION_NULL_OK\fR flag.

.IP \fIrecordPtr\fR
A pointer to the start of the widget record to modify.

.IP \fIinternalOffset\fR
Offset in bytes from the start of the widget record to the location
where the internal representation of the option value is to be placed.

.IP \fIsaveInternalPtr\fR
A pointer to storage allocated in a Tk_SavedOptions structure for the
internal representation of the original option value.  Before setting
the option to its new value, \fIsetProc\fR should set the value
referenced by \fIsaveInternalPtr\fR to the original value of the
option in order to support \fBTk_RestoreSavedOptions\fR.

.IP \fIflags\fR
A copy of the \fIflags\fR field in the Tk_OptionSpec structure for the
option
.RE
.PP
\fISetProc\fR returns a standard Tcl result: \fBTCL_OK\fR to indicate successful
processing, or \fBTCL_ERROR\fR to indicate a failure of any kind.  An error
message may be left in the Tcl interpreter given by \fIinterp\fR in

Changes to doc/SetVisual.3.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
Tk_SetWindowVisual \- change visual characteristics of window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_SetWindowVisual\fR(\fItkwin, visual, depth, colormap\fR)

.SH ARGUMENTS
.AS "Tk_Window int" colormap
.AP Tk_Window tkwin in
Token for window.
.AP Visual *visual in
New visual type to use for \fItkwin\fR.
.AP "int" depth in







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tk_SetWindowVisual \- change visual characteristics of window
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_SetWindowVisual\fR(\fItkwin, visual, depth, colormap\fR)
.fi
.SH ARGUMENTS
.AS "Tk_Window int" colormap
.AP Tk_Window tkwin in
Token for window.
.AP Visual *visual in
New visual type to use for \fItkwin\fR.
.AP "int" depth in
39
40
41
42
43
44
45
46
47
48
49
50
The safest thing is to call \fBTk_SetWindowVisual\fR immediately
after calling \fBTk_CreateWindow\fR.
If \fItkwin\fR has already been created before \fBTk_SetWindowVisual\fR
is called then it returns 0 and does not make any changes;  otherwise
it returns 1 to signify that the operation
completed successfully.
.PP
Note:  \fBTk_SetWindowVisual\fR should not be called if you just want
to change a window's colormap without changing its visual or depth;
call \fBTk_SetWindowColormap\fR instead.
.SH KEYWORDS
colormap, depth, visual







|




40
41
42
43
44
45
46
47
48
49
50
51
The safest thing is to call \fBTk_SetWindowVisual\fR immediately
after calling \fBTk_CreateWindow\fR.
If \fItkwin\fR has already been created before \fBTk_SetWindowVisual\fR
is called then it returns 0 and does not make any changes;  otherwise
it returns 1 to signify that the operation
completed successfully.
.PP
Note that \fBTk_SetWindowVisual\fR should not be called if you just want
to change a window's colormap without changing its visual or depth;
call \fBTk_SetWindowColormap\fR instead.
.SH KEYWORDS
colormap, depth, visual

Changes to doc/StrictMotif.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
Tk_StrictMotif \- Return value of tk_strictMotif variable
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_StrictMotif\fR(\fItkwin\fR)

.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Tk_StrictMotif \- Return value of tk_strictMotif variable
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_StrictMotif\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP

Changes to doc/TextLayout.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
.SH NAME
Tk_ComputeTextLayout, Tk_FreeTextLayout, Tk_DrawTextLayout, Tk_UnderlineTextLayout, Tk_PointToChar, Tk_CharBbox, Tk_DistanceToTextLayout, Tk_IntersectTextLayout, Tk_TextLayoutToPostscript \- routines to measure and display single-font, multi-line, justified text.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_TextLayout
\fBTk_ComputeTextLayout(\fItkfont, string, numChars, wrapLength, justify, flags, widthPtr, heightPtr\fB)\fR
.sp
void
\fBTk_FreeTextLayout(\fIlayout\fB)\fR
.sp
void
\fBTk_DrawTextLayout(\fIdisplay, drawable, gc, layout, x, y, firstChar, lastChar\fB)\fR
.sp
void
\fBTk_UnderlineTextLayout(\fIdisplay, drawable, gc, layout, x, y, underline\fB)\fR
.sp
int
\fBTk_PointToChar(\fIlayout, x, y\fB)\fR
.sp
int
\fBTk_CharBbox(\fIlayout, index, xPtr, yPtr, widthPtr, heightPtr\fB)\fR
.sp
int
\fBTk_DistanceToTextLayout(\fIlayout, x, y\fB)\fR
.sp
int
\fBTk_IntersectTextLayout(\fIlayout, x, y, width, height\fB)\fR
.sp
void
\fBTk_TextLayoutToPostscript(\fIinterp, layout\fB)\fR

.SH ARGUMENTS
.AS Tk_TextLayout "*xPtr, *yPtr"
.AP Tk_Font tkfont in
Font to use when constructing and displaying a text layout.  The
\fItkfont\fR must remain valid for the lifetime of the text layout.  Must
have been returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in







|

<
|

<
|

<
|


|


|


|


|

<
|
>







10
11
12
13
14
15
16
17
18

19
20

21
22

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

37
38
39
40
41
42
43
44
45
.SH NAME
Tk_ComputeTextLayout, Tk_FreeTextLayout, Tk_DrawTextLayout, Tk_UnderlineTextLayout, Tk_PointToChar, Tk_CharBbox, Tk_DistanceToTextLayout, Tk_IntersectTextLayout, Tk_TextLayoutToPostscript \- routines to measure and display single-font, multi-line, justified text.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_TextLayout
\fBTk_ComputeTextLayout\fR(\fItkfont, string, numChars, wrapLength, justify, flags, widthPtr, heightPtr\fR)
.sp

\fBTk_FreeTextLayout\fR(\fIlayout\fR)
.sp

\fBTk_DrawTextLayout\fR(\fIdisplay, drawable, gc, layout, x, y, firstChar, lastChar\fR)
.sp

\fBTk_UnderlineTextLayout\fR(\fIdisplay, drawable, gc, layout, x, y, underline\fR)
.sp
int
\fBTk_PointToChar\fR(\fIlayout, x, y\fR)
.sp
int
\fBTk_CharBbox\fR(\fIlayout, index, xPtr, yPtr, widthPtr, heightPtr\fR)
.sp
int
\fBTk_DistanceToTextLayout\fR(\fIlayout, x, y\fR)
.sp
int
\fBTk_IntersectTextLayout\fR(\fIlayout, x, y, width, height\fR)
.sp

\fBTk_TextLayoutToPostscript\fR(\fIinterp, layout\fR)
.fi
.SH ARGUMENTS
.AS Tk_TextLayout "*xPtr, *yPtr"
.AP Tk_Font tkfont in
Font to use when constructing and displaying a text layout.  The
\fItkfont\fR must remain valid for the lifetime of the text layout.  Must
have been returned by a previous call to \fBTk_GetFont\fR.
.AP "const char" *string in
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
this GC must correspond to the \fItkfont\fR used when constructing the
text layout.
.AP int "x, y" in
Point, in pixels, at which to place the upper-left hand corner of the
text layout when it is being drawn, or the coordinates of a point (with
respect to the upper-left hand corner of the text layout) to check
against the text layout.
.AP int firstChar in
The index of the first character to draw from the given text layout.
The number 0 means to draw from the beginning.
.AP int lastChar in
The index of the last character up to which to draw.  The character
specified by \fIlastChar\fR itself will not be drawn.  A number less
than 0 means to draw all characters in the text layout.
.AP int underline in
Index of the single character to underline in the text layout, or a number

less than 0 for no underline.
.AP int index in
The index of the character whose bounding box is desired.  The bounding
box is computed with respect to the upper-left hand corner of the text layout.
.AP int "*xPtr, *yPtr" out
Filled with the upper-left hand corner, in pixels, of the bounding box
for the character specified by \fIindex\fR.  Either or both \fIxPtr\fR
and \fIyPtr\fR may be NULL, in which case the corresponding value
is not calculated.







|


|




|
>
|
|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
this GC must correspond to the \fItkfont\fR used when constructing the
text layout.
.AP int "x, y" in
Point, in pixels, at which to place the upper-left hand corner of the
text layout when it is being drawn, or the coordinates of a point (with
respect to the upper-left hand corner of the text layout) to check
against the text layout.
.AP Tcl_Size firstChar in
The index of the first character to draw from the given text layout.
The number 0 means to draw from the beginning.
.AP Tcl_Size lastChar in
The index of the last character up to which to draw.  The character
specified by \fIlastChar\fR itself will not be drawn.  A number less
than 0 means to draw all characters in the text layout.
.AP int underline in
Index of the single character to underline in the text layout, or a
negative number counting backwards from the end of the string. Any
out-of-range number (e.g. INT_MIN) means no underline.
.AP Tcl_Size index in
The index of the character whose bounding box is desired.  The bounding
box is computed with respect to the upper-left hand corner of the text layout.
.AP int "*xPtr, *yPtr" out
Filled with the upper-left hand corner, in pixels, of the bounding box
for the character specified by \fIindex\fR.  Either or both \fIxPtr\fR
and \fIyPtr\fR may be NULL, in which case the corresponding value
is not calculated.

Changes to doc/TkInitStubs.3.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
Tk_InitStubs \- initialize the Tk stubs mechanism
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_InitStubs\fR(\fIinterp, version, exact\fR)

.SH ARGUMENTS
.AS Tcl_Interp *interp in
.AP Tcl_Interp *interp in
Tcl interpreter handle.
.AP char *version in
A version string consisting of one or more decimal numbers
separated by dots.







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Tk_InitStubs \- initialize the Tk stubs mechanism
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_InitStubs\fR(\fIinterp, version, exact\fR)
.fi
.SH ARGUMENTS
.AS Tcl_Interp *interp in
.AP Tcl_Interp *interp in
Tcl interpreter handle.
.AP char *version in
A version string consisting of one or more decimal numbers
separated by dots.

Changes to doc/Tk_Init.3.

43
44
45
46
47
48
49

50
51
52

53
54
55
56
57
58

59
60
61

62
63
64
65

66
67
68

69
70
71

72
73
74

75
76
77

78
79
80
81

82
83
84
85
its command-line arguments).
.PP
\fBTk_SafeInit\fR is identical to \fBTk_Init\fR except that it removes
all Tk commands that are considered unsafe.  Those commands and the
reasons for their exclusion are:
.TP
\fBbell\fR

Continuous ringing of the bell is a nuisance.
.TP
\fBclipboard\fR

A malicious script could replace the contents of the clipboard with
the string
.QW "\fBrm \-r *\fR"
and lead to surprises when the contents of the clipboard are pasted.
.TP
\fBgrab\fR

Grab can be used to block the user from using any other applications.
.TP
\fBmenu\fR

Menus can be used to cover the entire screen and to steal input from
the user.
.TP
\fBselection\fR

See clipboard.
.TP
\fBsend\fR

Send can be used to cause unsafe interpreters to execute commands.
.TP
\fBtk\fR

The tk command recreates the send command, which is unsafe.
.TP
\fBtkwait\fR

Tkwait can block the containing process forever
.TP
\fBtoplevel\fR

Toplevels can be used to cover the entire screen and to steal input
from the user.
.TP
\fBwm\fR

If toplevels are ever allowed, wm can be used to remove decorations,
move windows around, etc.
.SH KEYWORDS
safe, application, initialization, load, main window







>



>






>



>




>



>



>



>



>




>




43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
its command-line arguments).
.PP
\fBTk_SafeInit\fR is identical to \fBTk_Init\fR except that it removes
all Tk commands that are considered unsafe.  Those commands and the
reasons for their exclusion are:
.TP
\fBbell\fR
.
Continuous ringing of the bell is a nuisance.
.TP
\fBclipboard\fR
.
A malicious script could replace the contents of the clipboard with
the string
.QW "\fBrm \-r *\fR"
and lead to surprises when the contents of the clipboard are pasted.
.TP
\fBgrab\fR
.
Grab can be used to block the user from using any other applications.
.TP
\fBmenu\fR
.
Menus can be used to cover the entire screen and to steal input from
the user.
.TP
\fBselection\fR
.
See clipboard.
.TP
\fBsend\fR
.
Send can be used to cause unsafe interpreters to execute commands.
.TP
\fBtk\fR
.
The tk command recreates the send command, which is unsafe.
.TP
\fBtkwait\fR
.
Tkwait can block the containing process forever
.TP
\fBtoplevel\fR
.
Toplevels can be used to cover the entire screen and to steal input
from the user.
.TP
\fBwm\fR
.
If toplevels are ever allowed, wm can be used to remove decorations,
move windows around, etc.
.SH KEYWORDS
safe, application, initialization, load, main window

Changes to doc/Tk_Main.3.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_Main\fR(\fIargc, argv, appInitProc\fR)
.SH ARGUMENTS
.AS Tcl_AppInitProc *appInitProc
.AP int argc in
Number of elements in \fIargv\fR.
.AP char *argv[] in
Array of strings containing command-line arguments. On Windows, when
using -DUNICODE, the parameter type changes to wchar_t *.
.AP Tcl_AppInitProc *appInitProc in
Address of an application-specific initialization procedure.
The value for this argument is usually \fBTcl_AppInit\fR.







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_Main\fR(\fIargc, argv, appInitProc\fR)
.SH ARGUMENTS
.AS Tcl_AppInitProc *appInitProc
.AP Tcl_Size argc in
Number of elements in \fIargv\fR.
.AP char *argv[] in
Array of strings containing command-line arguments. On Windows, when
using -DUNICODE, the parameter type changes to wchar_t *.
.AP Tcl_AppInitProc *appInitProc in
Address of an application-specific initialization procedure.
The value for this argument is usually \fBTcl_AppInit\fR.

Added doc/WinUtil.3.



































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_ConfigureWindow 3 4.0 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetOtherWindow, Tk_MakeContainer, Tk_MakeWindow, Tk_UseWindow \- window utility functions
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Window
\fBTk_GetOtherWindow\fR(\fItkwin\fR)
.sp
\fBTk_MakeContainer\fR(\fItkwin\fR)
.sp
\fBTk_MakeWindow\fR(\fItkwin, parent\fR)
.sp
int
\fBTk_UseWindow\fR(\fIinterp, tkwin, string\fR)
.fi
.SH ARGUMENTS
.AS XSetWindowAttributes borderWidth
.AP Tcl_Interp * interp in
Interpreter associated with the application.
.AP Tk_Window tkwin in
Token for window.
.AP Window parent in
Parent window.
.AP "const char" *string in
String identifying an X window to use for \fItkwin\fR; must be an integer value.
.BE
.SH DESCRIPTION
.PP
If both the container and embedded window are in the same process,
\fBTk_GetOtherWindow\fR will return either one, given the other.
If winPtr is a container, the return value is the token for the
embedded window, and vice versa. If the "other" window isn't in this
process, NULL is returned.
.PP
\fBTk_MakeContainer\fR is called to indicate that a particular window will be a
container for an embedded application. This changes certain aspects of
the window's behavior, such as whether it will receive events anymore.
.PP
\fBTk_MakeWindow\fR creates an actual window system window object based on the
current attributes of the specified TkWindow. It returns the handle to the new
window, or None on failure.
.PP
\fBTk_UseWindow\fR causes a Tk window to use a given X window as its
parent window, rather than the root window for the screen. It is
invoked by an embedded application to specify the window in which it
is embedded.
.PP
The return value is normally TCL_OK. If an error occurs (such as
string not being a valid window spec), then the return value is
TCL_ERROR and an error message is left in the interp's result if
interp is non-NULL.
.PP
.SH KEYWORDS
parent, window

Changes to doc/WindowId.3.

99
100
101
102
103
104
105

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







>







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
\fBTk_Colormap\fR(\fItkwin\fR)
.sp
Tcl_Interp *
\fBTk_Interp\fR(\fItkwin\fR)
.sp
Tcl_Obj *
\fBTk_NewWindowObj\fR(\fItkwin\fR)
.fi
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR
returns a pointer to a structure containing all of the above
information plus a few other fields.  \fBTk_Attributes\fR
returns a pointer to an XSetWindowAttributes structure describing
all of the attributes of the \fItkwin\fR's window, such as background
pixmap, event mask, and so on (Tk keeps track of all this information
as it is changed by the application).  Note: it is essential that
applications use Tk procedures like \fBTk_ResizeWindow\fR instead
of X procedures like \fBXResizeWindow\fR, so that Tk can keep its
data structures up-to-date.
.PP
\fBTk_IsContainer\fR returns a non-zero value if \fItkwin\fR
is a container, and that some other application may be embedding
itself inside \fItkwin\fR.







|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR
returns a pointer to a structure containing all of the above
information plus a few other fields.  \fBTk_Attributes\fR
returns a pointer to an XSetWindowAttributes structure describing
all of the attributes of the \fItkwin\fR's window, such as background
pixmap, event mask, and so on (Tk keeps track of all this information
as it is changed by the application).  Note that it is essential that
applications use Tk procedures like \fBTk_ResizeWindow\fR instead
of X procedures like \fBXResizeWindow\fR, so that Tk can keep its
data structures up-to-date.
.PP
\fBTk_IsContainer\fR returns a non-zero value if \fItkwin\fR
is a container, and that some other application may be embedding
itself inside \fItkwin\fR.

Changes to doc/bind.n.

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.
'\"
'\" 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



|







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 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
49
50
51
52
53
54
55



56
57
58
59
60
61
62
63
64
65
66
67
68
69
the window.
Although the \fBbindtags\fR command may be used to assign an
arbitrary set of binding tags to a window, the default binding
tags provide the following behavior:
.IP \(bu 3
If a tag is the name of an internal window the binding applies
to that window.



.IP \(bu 3
If the tag is the name of a toplevel window the binding applies
to the toplevel window and all its internal windows.
.IP \(bu 3
If the tag is the name of a class of widgets, such as \fBButton\fR,
the binding applies to all widgets in that class;
.IP \(bu 3
If \fItag\fR has the value \fBall\fR,
the binding applies to all windows in the application.
.SH "EVENT PATTERNS"
.PP
The \fIsequence\fR argument specifies a sequence of one or more
event patterns, with optional white space between the patterns.  Each
event pattern may







>
>
>




<
<
<







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



63
64
65
66
67
68
69
the window.
Although the \fBbindtags\fR command may be used to assign an
arbitrary set of binding tags to a window, the default binding
tags provide the following behavior:
.IP \(bu 3
If a tag is the name of an internal window the binding applies
to that window.
.IP \(bu 3
If the tag is the name of a class of widgets, such as \fBButton\fR,
the binding applies to all widgets in that class.
.IP \(bu 3
If the tag is the name of a toplevel window the binding applies
to the toplevel window and all its internal windows.
.IP \(bu 3



If \fItag\fR has the value \fBall\fR,
the binding applies to all windows in the application.
.SH "EVENT PATTERNS"
.PP
The \fIsequence\fR argument specifies a sequence of one or more
event patterns, with optional white space between the patterns.  Each
event pattern may
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
.SS "MODIFIERS"
.PP
Modifiers consist of any of the following values:
.DS
.ta 6c
\fBControl\fR	\fBMod1\fR, \fBM1\fR, \fBCommand\fR
\fBAlt\fR	\fBMod2\fR, \fBM2\fR, \fBOption\fR
\fBShift\fR	\fBMod3\fR, \fBM3\fR
\fBLock\fR	\fBMod4\fR, \fBM4\fR
\fBExtended\fR	\fBMod5\fR, \fBM5\fR
\fBButton1\fR, \fBB1\fR	\fBMeta\fR, \fBM\fR
\fBButton2\fR, \fBB2\fR	\fBDouble\fR
\fBButton3\fR, \fBB3\fR	\fBTriple\fR
\fBButton4\fR, \fBB4\fR	\fBQuadruple\fR
\fBButton5\fR, \fBB5\fR
.DE







|
|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
.SS "MODIFIERS"
.PP
Modifiers consist of any of the following values:
.DS
.ta 6c
\fBControl\fR	\fBMod1\fR, \fBM1\fR, \fBCommand\fR
\fBAlt\fR	\fBMod2\fR, \fBM2\fR, \fBOption\fR
\fBShift\fR	\fBMod3\fR, \fBM3\fR, \fBNum\fR
\fBLock\fR	\fBMod4\fR, \fBM4\fR, \fBFn\fR
\fBExtended\fR	\fBMod5\fR, \fBM5\fR
\fBButton1\fR, \fBB1\fR	\fBMeta\fR, \fBM\fR
\fBButton2\fR, \fBB2\fR	\fBDouble\fR
\fBButton3\fR, \fBB3\fR	\fBTriple\fR
\fBButton4\fR, \fBB4\fR	\fBQuadruple\fR
\fBButton5\fR, \fBB5\fR
.DE
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
times, and also place a time and space requirement on the sequence: for a
sequence of events to match a \fBDouble\fR, \fBTriple\fR or \fBQuadruple\fR
pattern, all of the events must occur close together in time and without
substantial mouse motion in between.  For example, \fB<Double\-Button\-1>\fR
is equivalent to \fB<Button\-1><Button\-1>\fR with the extra time and space
requirement.
.PP

The \fBCommand\fR and \fBOption\fR modifiers are equivalents of \fBMod1\fR
resp. \fBMod2\fR, they correspond to Macintosh-specific modifier keys.
.PP
The \fBExtended\fR modifier is, at present, specific to Windows.  It
appears on events that are associated with the keys on the
.QW "extended keyboard" .
On a US keyboard, the extended keys include the \fBAlt\fR
and \fBControl\fR keys at the right of the keyboard, the cursor keys
in the cluster to the left of the numeric pad, the \fBNumLock\fR key,







>
|
|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
times, and also place a time and space requirement on the sequence: for a
sequence of events to match a \fBDouble\fR, \fBTriple\fR or \fBQuadruple\fR
pattern, all of the events must occur close together in time and without
substantial mouse motion in between.  For example, \fB<Double\-Button\-1>\fR
is equivalent to \fB<Button\-1><Button\-1>\fR with the extra time and space
requirement.
.PP
The \fBCommand\fR, \fBOption\fR, \fBNum\fR and \fBFn\fRmodifiers are
equivalents of \fBMod1\fR up to \fBMod4\fR; they correspond to
Macintosh-specific modifier keys.
.PP
The \fBExtended\fR modifier is, at present, specific to Windows.  It
appears on events that are associated with the keys on the
.QW "extended keyboard" .
On a US keyboard, the extended keys include the \fBAlt\fR
and \fBControl\fR keys at the right of the keyboard, the cursor keys
in the cluster to the left of the numeric pad, the \fBNumLock\fR key,
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220















221
222
223
224
225
226
227
types; where two names appear together, they are synonyms.
.DS
.ta \w'\fBButton, ButtonPress\0\0\0\fR'u +\w'\fBKey, KeyPress\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButton\fR, \fBButtonPress\fR	\fBEnter\fR	\fBMapRequest\fR
\fBButtonRelease\fR	\fBExpose\fR	\fBMotion\fR
\fBCirculate\fR	\fBFocusIn\fR	\fBMouseWheel\fR
\fBCirculateRequest\fR	\fBFocusOut\fR	\fBProperty\fR
\fBColormap\fR	\fBGravity\fR	\fBReparent\fR
\fBConfigure\fR	\fBKey\fR, \fBKeyPress\fR	\fBResizeRequest\fR
\fBConfigureRequest\fR	\fBKeyRelease\fR	\fBUnmap\fR
\fBCreate\fR	\fBLeave\fR	\fBVisibility\fR
\fBDeactivate\fR
.DE
Most of the above events have the same fields and behaviors as events
in the X Windowing system.  You can find more detailed descriptions of
these events in any X window programming book.  A couple of the events
are extensions to the X event system to support features unique to the
Macintosh and Windows platforms.  We provide a little more detail on
these events here.  These include:
.IP "\fBActivate\fR, \fBDeactivate\fR" 5
These two events are sent to every sub-window of a toplevel when they
change state.  In addition to the focus Window, the Macintosh platform
and Windows platforms have a notion of an active window (which often
has but is not required to have the focus).  On the Macintosh, widgets
in the active window have a different appearance than widgets in
deactive windows.  The \fBActivate\fR event is sent to all the
sub-windows in a toplevel when it changes from being deactive to
active.  Likewise, the \fBDeactive\fR event is sent when the window's
state changes from active to deactive.  There are no useful percent
substitutions you would make when binding to these events.
.IP \fBMouseWheel\fR 5
Many contemporary mice support a mouse wheel, which is used
for scrolling documents without using the scrollbars.  By rolling the
wheel, the system will generate \fBMouseWheel\fR events that the
application can use to scroll.  The event is routed to the
window currently under the mouse pointer. When the event
is received you can use the \fB%D\fR substitution to get the
\fIdelta\fR field for the event, which is an integer value describing how
the mouse wheel has moved.  The smallest value for which the
system will report is defined by the OS.  The sign of the
value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.
.RS
.PP
Horizontal scrolling uses \fBShift-MouseWheel\fR events, with positive
\fB%D\fR \fIdelta\fR substitution indicating left scrolling and negative
right scrolling.
Horizontal scrolling events may fire from
many different hardware units such as tilt wheels or touchpads.  Horizontal
scrolling can also be emulated by holding Shift and scrolling vertically.
.RE















.IP "\fBKeyPress\fR, \fBKeyRelease\fR" 5
The \fBKeyPress\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKeyPress\fR and \fBKeyRelease\fR
.IP "\fBKey\fR, \fBKeyRelease\fR" 5
The \fBKey\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKey\fR and \fBKeyRelease\fR
events are sent to the window which currently has the keyboard focus.







|
|
|
|
|




















|













|
|
|
<
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
types; where two names appear together, they are synonyms.
.DS
.ta \w'\fBButton, ButtonPress\0\0\0\fR'u +\w'\fBKey, KeyPress\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButton\fR, \fBButtonPress\fR	\fBEnter\fR	\fBMapRequest\fR
\fBButtonRelease\fR	\fBExpose\fR	\fBMotion\fR
\fBCirculate\fR	\fBFocusIn\fR	\fBMouseWheel\fR
\fBTouchpadScroll\fR	\fBCirculateRequest\fR	\fBFocusOut\fR
\fBProperty\fR	\fBColormap\fR	\fBGravity\fR
\fBReparent\fR	\fBConfigure\fR	\fBKey\fR, \fBKeyPress\fR
\fBResizeRequest\fR	\fBConfigureRequest\fR	\fBKeyRelease\fR
\fBUnmap\fR   \fBCreate\fR	\fBLeave\fR	\fBVisibility\fR
\fBDeactivate\fR
.DE
Most of the above events have the same fields and behaviors as events
in the X Windowing system.  You can find more detailed descriptions of
these events in any X window programming book.  A couple of the events
are extensions to the X event system to support features unique to the
Macintosh and Windows platforms.  We provide a little more detail on
these events here.  These include:
.IP "\fBActivate\fR, \fBDeactivate\fR" 5
These two events are sent to every sub-window of a toplevel when they
change state.  In addition to the focus Window, the Macintosh platform
and Windows platforms have a notion of an active window (which often
has but is not required to have the focus).  On the Macintosh, widgets
in the active window have a different appearance than widgets in
deactive windows.  The \fBActivate\fR event is sent to all the
sub-windows in a toplevel when it changes from being deactive to
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 include a mouse wheel, which is used
for scrolling documents without using the scrollbars.  By rolling the
wheel, the system will generate \fBMouseWheel\fR events that the
application can use to scroll.  The event is routed to the
window currently under the mouse pointer. When the event
is received you can use the \fB%D\fR substitution to get the
\fIdelta\fR field for the event, which is an integer value describing how
the mouse wheel has moved.  The smallest value for which the
system will report is defined by the OS.  The sign of the
value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.
.RS
.PP
Horizontal scrolling uses \fBShift-MouseWheel\fR events, with positive
\fB%D\fR \fIdelta\fR substitution indicating left scrolling and
negative right scrolling. Horizontal scrolling events are generated
tilt wheels on some mice.  Horizontal scrolling can also be emulated

by holding Shift and scrolling vertically.
.RE
.IP "\fBTouchpadScroll\fR" 5
On some platforms (currently Windows and macOS) there is support for
high-resolution scrolling devices, such as touchpads.  This is
provided via \fBTouchpadScroll\fR events.  These events store two
16 bit delta values in the integer provided by the \fB%D\fR
substitution.  The \fIX\fR delta is in the high order 16 bits and the
\fIY\fR delta is in the low order 16 bits.  These values can be
unpacked by using the tk::PreciseScrollDeltas utility procedure.  For
example:
.CS
lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
.CE
The \fB$#\fR substitution is a counter for \fBTouchpadScroll\fR events
which can be used by widgets that only support scrolling by units to
ignore some portion of the events.
.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.
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
appended scripts, is terminated but Tk will continue processing
binding scripts associated with other \fItag\fR's.
If the \fBbreak\fR command is invoked within a binding script,
then that script terminates and no other scripts will be invoked
for the event.
.PP
Within a script called from the binding script, \fBreturn\fR
\fB-code ok\fR may be used to continue processing (including
.QW +
appended scripts), or \fBreturn\fR \fB-code break\fR may be used to
stop processing all other binding scripts.
.PP
If more than one binding matches a particular event and they
have the same \fItag\fR, then the most specific binding
is chosen and its script is evaluated.
The following tests are applied, in order, to determine which of
several matching sequences is more specific:







|

|







646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
appended scripts, is terminated but Tk will continue processing
binding scripts associated with other \fItag\fR's.
If the \fBbreak\fR command is invoked within a binding script,
then that script terminates and no other scripts will be invoked
for the event.
.PP
Within a script called from the binding script, \fBreturn\fR
\fB\-code ok\fR may be used to continue processing (including
.QW +
appended scripts), or \fBreturn\fR \fB\-code break\fR may be used to
stop processing all other binding scripts.
.PP
If more than one binding matches a particular event and they
have the same \fItag\fR, then the most specific binding
is chosen and its script is evaluated.
The following tests are applied, in order, to determine which of
several matching sequences is more specific:
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
The \fBbgerror\fR command will be executed at global level
(outside the context of any Tcl procedure).
.SH "EXAMPLES"
.PP
Arrange for a string describing the motion of the mouse to be printed
out when the mouse is double-clicked:
.CS
\fBbind\fR . <Double\-1> {
    puts "hi from (%x,%y)"
}
.CE
.PP
A little GUI that displays what the keysym name of the last key
pressed is:
.CS
set keysym "Press any key"
pack [label .l \-textvariable keysym \-padx 2m \-pady 1m]
\fBbind\fR . <Key> {
    set keysym "You pressed %K"
}
.CE
.SH "SEE ALSO"
bgerror(n), bindtags(n), event(n), focus(n), grab(n), keysyms(n)
.SH KEYWORDS
binding, event
'\" Local Variables:
'\" mode: nroff
'\" End:







|








|











736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
The \fBbgerror\fR command will be executed at global level
(outside the context of any Tcl procedure).
.SH "EXAMPLES"
.PP
Arrange for a string describing the motion of the mouse to be printed
out when the mouse is double-clicked:
.CS
\fBbind\fR . <Double-1> {
    puts "hi from (%x,%y)"
}
.CE
.PP
A little GUI that displays what the keysym name of the last key
pressed is:
.CS
set keysym "Press any key"
pack [label .l -textvariable keysym -padx 2m -pady 1m]
\fBbind\fR . <Key> {
    set keysym "You pressed %K"
}
.CE
.SH "SEE ALSO"
bgerror(n), bindtags(n), event(n), focus(n), grab(n), keysyms(n)
.SH KEYWORDS
binding, event
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/bitmap.n.

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
bitmap \- Images that display two colors
.SH SYNOPSIS
.nf
\fBimage create bitmap \fR?\fIname\fR? ?\fIoptions\fR?

\fIimageName \fBcget\fR \fIoption\fR
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
A bitmap is an image whose pixels can display either of two colors
or be transparent.







|







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
bitmap \- Images that display two colors
.SH SYNOPSIS
.nf
\fBimage create bitmap \fR?\fIname\fR? ?\fIoptions\fR?

\fIimageName \fBcget\fI option\fR
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
A bitmap is an image whose pixels can display either of two colors
or be transparent.
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64

65
66
67
68
69

70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104

105
106
107
108
109
110
111
the source data is one and the background color if the source
data is zero.
.SH "CREATING BITMAPS"
.PP
Like all images, bitmaps are created using the \fBimage create\fR
command.
Bitmaps support the following \fIoptions\fR:

.TP
\fB\-background \fIcolor\fR
.
Specifies a background color for the image in any of the standard
ways accepted by Tk.  If this option is set to an empty string
then the background pixels will be transparent.  This effect
is achieved by using the source bitmap as the mask bitmap, ignoring
any \fB\-maskdata\fR or \fB\-maskfile\fR options.

.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the source bitmap as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-data\fR and \fB\-file\fR options are specified,
the \fB\-data\fR option takes precedence.

.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file whose contents define the
source bitmap.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).

.TP
\fB\-foreground \fIcolor\fR
.
Specifies a foreground color for the image in any of the standard
ways accepted by Tk.

.TP
\fB\-maskdata \fIstring\fR
.
Specifies the contents of the mask as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-maskdata\fR and \fB\-maskfile\fR options are specified,
the \fB\-maskdata\fR option takes precedence.

.TP
\fB\-maskfile \fIname\fR
.
\fIname\fR gives the name of a file whose contents define the
mask.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
.SH "IMAGE COMMAND"
.PP
When a bitmap image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for bitmap images:

.TP
\fIimageName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBbitmap\fR command.

.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified







>








>








>







>





>








>




















>

|





>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
the source data is one and the background color if the source
data is zero.
.SH "CREATING BITMAPS"
.PP
Like all images, bitmaps are created using the \fBimage create\fR
command.
Bitmaps support the following \fIoptions\fR:
.\" OPTION: -background
.TP
\fB\-background \fIcolor\fR
.
Specifies a background color for the image in any of the standard
ways accepted by Tk.  If this option is set to an empty string
then the background pixels will be transparent.  This effect
is achieved by using the source bitmap as the mask bitmap, ignoring
any \fB\-maskdata\fR or \fB\-maskfile\fR options.
.\" OPTION: -data
.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the source bitmap as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-data\fR and \fB\-file\fR options are specified,
the \fB\-data\fR option takes precedence.
.\" OPTION: -file
.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file whose contents define the
source bitmap.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
.\" OPTION: -foreground
.TP
\fB\-foreground \fIcolor\fR
.
Specifies a foreground color for the image in any of the standard
ways accepted by Tk.
.\" OPTION: -maskdata
.TP
\fB\-maskdata \fIstring\fR
.
Specifies the contents of the mask as a string.
The string must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
If both the \fB\-maskdata\fR and \fB\-maskfile\fR options are specified,
the \fB\-maskdata\fR option takes precedence.
.\" OPTION: -maskfile
.TP
\fB\-maskfile \fIname\fR
.
\fIname\fR gives the name of a file whose contents define the
mask.
The file must adhere to X11 bitmap format (e.g., as generated
by the \fBbitmap\fR program).
.SH "IMAGE COMMAND"
.PP
When a bitmap image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for bitmap images:
.\" METHOD: cget
.TP
\fIimageName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBbitmap\fR command.
.\" METHOD: configure
.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified

Changes to doc/busy.n.

26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
.TH busy n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
busy \- Make Tk widgets busy, temporarily blocking user interactions
.SH SYNOPSIS

\fBtk busy\fR \fIwindow \fR?\fIoptions\fR?
.sp
\fBtk busy busywindow \fIwindow\fR
.sp
\fBtk busy hold\fR \fIwindow \fR?\fIoptions\fR?
.sp
\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
.sp
\fBtk busy forget\fR \fIwindow \fR?\fIwindow \fR?...
.sp
\fBtk busy current\fR ?\fIpattern\fR?
.sp
\fBtk busy status \fIwindow\fR

.BE
.SH DESCRIPTION
.PP
The \fBtk busy\fR command provides a simple means to block mouse pointer events
from Tk widgets, while overriding the widget's cursor with a configurable busy
cursor. Note this command does not prevent keyboard events from being sent to
the widgets made busy.







>
|
<

<
|
<

<
|
<

<

>







26
27
28
29
30
31
32
33
34

35

36

37

38

39

40
41
42
43
44
45
46
47
48
.TH busy n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
busy \- Make Tk widgets busy, temporarily blocking user interactions
.SH SYNOPSIS
.nf
\fBtk busy\fI window \fR?\fIoptions\fR?

\fBtk busy busywindow \fIwindow\fR

\fBtk busy hold\fI window \fR?\fIoptions\fR?

\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...

\fBtk busy forget\fI window \fR?\fIwindow \fR?...

\fBtk busy current\fR ?\fIpattern\fR?

\fBtk busy status \fIwindow\fR
.fi
.BE
.SH DESCRIPTION
.PP
The \fBtk busy\fR command provides a simple means to block mouse pointer events
from Tk widgets, while overriding the widget's cursor with a configurable busy
cursor. Note this command does not prevent keyboard events from being sent to
the widgets made busy.
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137

138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
\fBtk busy\fR forget .top
.CE
.PP
The busy window has a configurable cursor. You can change the busy cursor
using the \fBconfigure\fR operation.
.PP
.CS
\fBtk busy\fR configure .top \-cursor "watch"
.CE
.PP
Destroying the widget will also clean up any resources allocated by the \fBtk
busy\fR command.
.PP
.SH OPERATIONS
.PP
The following operations are available for the \fBtk busy\fR command:
.TP
\fBtk busy \fIwindow\fR ?\fIoption value\fR?...
.
Shortcut for \fBtk busy hold\fR command.

.TP
\fBtk busy busywindow \fIwindow\fR
.
Returns the pathname of the busy window (i.e. the transparent window
shielding the window appearing busy) created by the \fBtk busy hold\fR
command for \fIwindow\fR, or the empty string if \fIwindow\fR is not busy.

.TP
\fBtk busy cget \fIwindow\fR \fIoption\fR
.
Queries the \fBtk busy\fR command configuration options for \fIwindow\fR.
\fIWindow\fR must be the path name of a widget previously made busy by the
\fBhold\fR operation. The command returns the present value of the specified
\fIoption\fR. \fIOption\fR may have any of the values accepted by the
\fBhold\fR operation.

.TP
\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
.
Queries or modifies the \fBtk busy\fR command configuration options for
\fIwindow\fR. \fIWindow\fR must be the path name of a widget previously made
busy by the \fBhold\fR operation.  If no options are specified, a list
describing all of the available options for \fIwindow\fR (see







|












>






>

|






>







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
\fBtk busy\fR forget .top
.CE
.PP
The busy window has a configurable cursor. You can change the busy cursor
using the \fBconfigure\fR operation.
.PP
.CS
\fBtk busy\fR configure .top -cursor "watch"
.CE
.PP
Destroying the widget will also clean up any resources allocated by the \fBtk
busy\fR command.
.PP
.SH OPERATIONS
.PP
The following operations are available for the \fBtk busy\fR command:
.TP
\fBtk busy \fIwindow\fR ?\fIoption value\fR?...
.
Shortcut for \fBtk busy hold\fR command.
.\" METHOD: busywindow
.TP
\fBtk busy busywindow \fIwindow\fR
.
Returns the pathname of the busy window (i.e. the transparent window
shielding the window appearing busy) created by the \fBtk busy hold\fR
command for \fIwindow\fR, or the empty string if \fIwindow\fR is not busy.
.\" METHOD: cget
.TP
\fBtk busy cget \fIwindow option\fR
.
Queries the \fBtk busy\fR command configuration options for \fIwindow\fR.
\fIWindow\fR must be the path name of a widget previously made busy by the
\fBhold\fR operation. The command returns the present value of the specified
\fIoption\fR. \fIOption\fR may have any of the values accepted by the
\fBhold\fR operation.
.\" METHOD: configure
.TP
\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
.
Queries or modifies the \fBtk busy\fR command configuration options for
\fIwindow\fR. \fIWindow\fR must be the path name of a widget previously made
busy by the \fBhold\fR operation.  If no options are specified, a list
describing all of the available options for \fIwindow\fR (see
165
166
167
168
169
170
171

172
173
174
175
176
177

178
179
180
181
182
183
184
185

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

200
201
202
203
204
205
206

207
208
209
210
211
212
213
specified for it by either \fBoption\fR command:
.PP
.CS
option add *frame.busyCursor gumby
option add *Frame.BusyCursor gumby
.CE
.RE

.TP
\fBtk busy current \fR?\fIpattern\fR?
.
Returns the pathnames of all widgets that are currently busy. If a
\fIpattern\fR is given, only the path names of busy widgets matching
\fIpattern\fR are returned.

.TP
\fBtk busy forget \fIwindow\fR ?\fIwindow\fR?...
.
Releases resources allocated by the \fBtk busy\fR command for \fIwindow\fR,
including the transparent window. User events will again be received by
\fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed.
\fIWindow\fR must be the name of a widget specified in the \fBhold\fR
operation, otherwise an error is reported.

.TP
\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?...
.
Makes the specified \fIwindow\fR (and its descendants in the Tk window
hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget.
A transparent window is put in front of the specified window. This transparent
window is mapped the next time idle tasks are processed, and the specified
window and its descendants will be blocked from user interactions. Normally
\fBupdate\fR should be called immediately afterward to insure that the hold
operation is in effect before the application starts its processing. The
command returns the pathname of the busy window that was created (i.e. the
transparent window shielding the window appearing busy). The following
configuration options are valid:
.RS

.TP
\fB\-cursor \fIcursorName\fR
.
Specifies the cursor to be displayed when the widget is made busy.
\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The
default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms.
.RE

.TP
\fBtk busy status \fIwindow\fR
.
Returns the status of a widget \fIwindow\fR. If \fIwindow\fR presently can not
receive user interactions, \fB1\fR is returned, otherwise \fB0\fR.
.SH "EVENT HANDLING"
.SS BINDINGS







>






>








>














>







>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
specified for it by either \fBoption\fR command:
.PP
.CS
option add *frame.busyCursor gumby
option add *Frame.BusyCursor gumby
.CE
.RE
.\" METHOD: current
.TP
\fBtk busy current \fR?\fIpattern\fR?
.
Returns the pathnames of all widgets that are currently busy. If a
\fIpattern\fR is given, only the path names of busy widgets matching
\fIpattern\fR are returned.
.\" METHOD: forget
.TP
\fBtk busy forget \fIwindow\fR ?\fIwindow\fR?...
.
Releases resources allocated by the \fBtk busy\fR command for \fIwindow\fR,
including the transparent window. User events will again be received by
\fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed.
\fIWindow\fR must be the name of a widget specified in the \fBhold\fR
operation, otherwise an error is reported.
.\" METHOD: hold
.TP
\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?...
.
Makes the specified \fIwindow\fR (and its descendants in the Tk window
hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget.
A transparent window is put in front of the specified window. This transparent
window is mapped the next time idle tasks are processed, and the specified
window and its descendants will be blocked from user interactions. Normally
\fBupdate\fR should be called immediately afterward to insure that the hold
operation is in effect before the application starts its processing. The
command returns the pathname of the busy window that was created (i.e. the
transparent window shielding the window appearing busy). The following
configuration options are valid:
.RS
.\" OPTION: -cursor
.TP
\fB\-cursor \fIcursorName\fR
.
Specifies the cursor to be displayed when the widget is made busy.
\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The
default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms.
.RE
.\" METHOD: status
.TP
\fBtk busy status \fIwindow\fR
.
Returns the status of a widget \fIwindow\fR. If \fIwindow\fR presently can not
receive user interactions, \fB1\fR is returned, otherwise \fB0\fR.
.SH "EVENT HANDLING"
.SS BINDINGS

Changes to doc/button.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH button n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
button \- Create and manipulate 'button' action widgets
.SH SYNOPSIS
\fBbutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-font	\-relief
\-activeforeground	\-foreground	\-repeatdelay
\-anchor	\-highlightbackground	\-repeatinterval
\-background	\-highlightcolor	\-takefocus
\-bitmap	\-highlightthickness	\-text
\-borderwidth	\-image	\-textvariable







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH button n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
button \- Create and manipulate 'button' action widgets
.SH SYNOPSIS
\fBbutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-font	\-relief
\-activeforeground	\-foreground	\-repeatdelay
\-anchor	\-highlightbackground	\-repeatinterval
\-background	\-highlightcolor	\-takefocus
\-bitmap	\-highlightthickness	\-text
\-borderwidth	\-image	\-textvariable
110
111
112
113
114
115
116

117
118

119
120
121
122

123
124

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

137
138

139
140
141
142
143

144
145

146
147
148
149
150
151
152
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for button widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.

.TP
\fIpathName \fBflash\fR

Flash the button.  This is accomplished by redisplaying the button
several times, alternating between the configured activebackground
and background colors.  At the end of the flash the button is left
in the same normal/active state as when the command was invoked.
This command is ignored if the button's state is \fBdisabled\fR.

.TP
\fIpathName \fBinvoke\fR

Invoke the Tcl command associated with the button, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the button.
This command is ignored if the button's state is \fBdisabled\fR.
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for buttons that give them







>

|
>




>


>












>


>





>


>







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for button widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.
.\" METHOD: flash
.TP
\fIpathName \fBflash\fR
.
Flash the button.  This is accomplished by redisplaying the button
several times, alternating between the configured activebackground
and background colors.  At the end of the flash the button is left
in the same normal/active state as when the command was invoked.
This command is ignored if the button's state is \fBdisabled\fR.
.\" METHOD: invoke
.TP
\fIpathName \fBinvoke\fR
.
Invoke the Tcl command associated with the button, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the button.
This command is ignored if the button's state is \fBdisabled\fR.
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for buttons that give them
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
.SH EXAMPLES
.PP
This is the classic Tk
.QW "Hello, World!"
demonstration:
.PP
.CS
\fBbutton\fR .b \-text "Hello, World!" \-command exit
pack .b
.CE
.PP
This example demonstrates how to handle button accelerators:
.PP
.CS
\fBbutton\fR .b1 \-text Hello \-underline 0
\fBbutton\fR .b2 \-text World \-underline 0
bind . <Key\-h> {.b1 flash; .b1 invoke}
bind . <Key\-w> {.b2 flash; .b2 invoke}
pack .b1 .b2
.CE
.SH "SEE ALSO"
ttk::button(n)
.SH KEYWORDS
button, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|






|
|
|
|









192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
.SH EXAMPLES
.PP
This is the classic Tk
.QW "Hello, World!"
demonstration:
.PP
.CS
\fBbutton\fR .b -text "Hello, World!" -command exit
pack .b
.CE
.PP
This example demonstrates how to handle button accelerators:
.PP
.CS
\fBbutton\fR .b1 -text Hello -underline 0
\fBbutton\fR .b2 -text World -underline 0
bind . <Key-h> {.b1 flash; .b1 invoke}
bind . <Key-w> {.b2 flash; .b2 invoke}
pack .b1 .b2
.CE
.SH "SEE ALSO"
ttk::button(n)
.SH KEYWORDS
button, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/canvas.n.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.TH canvas n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
canvas \- Create and manipulate 'canvas' hypergraphics drawing surface widgets
.SH SYNOPSIS
\fBcanvas\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-insertbackground	\-insertborderwidth	\-insertofftime
\-insertontime	\-insertwidth	\-relief
\-selectbackground	\-selectborderwidth	\-selectforeground
\-takefocus	\-xscrollcommand	\-yscrollcommand







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.TH canvas n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
canvas \- Create and manipulate 'canvas' hypergraphics drawing surface widgets
.SH SYNOPSIS
\fBcanvas\fI pathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-insertbackground	\-insertborderwidth	\-insertofftime
\-insertontime	\-insertwidth	\-relief
\-selectbackground	\-selectborderwidth	\-selectforeground
\-takefocus	\-xscrollcommand	\-yscrollcommand
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
support as many of these forms as practical.
Note that it is possible to refer to the character just after
the last one in the text item; this is necessary for such
tasks as inserting new text at the end of the item.
Lines and Polygons do not support the insertion cursor
and the selection. Their indices are supposed to be even
always, because coordinates always appear in pairs.
.TP 10
\fInumber\fR
.
A decimal number giving the position of the desired character
within the text item.
0 refers to the first character, 1 to the next character, and
so on. If indexes are odd for lines and polygons, they will be
automatically decremented by one.
A number less than 0 is treated as if it were zero, and a
number greater than the length of the text item is treated
as if it were equal to the length of the text item. For
polygons, numbers less than 0 or greater than the length
of the coordinate list will be adjusted by adding or subtracting
the length until the result is between zero and the length,
inclusive.
.TP 10
\fBend\fR
.
Refers to the character or coordinate just after the last one
in the item (same as the number of characters or coordinates
in the item).
.TP 10
\fBinsert\fR
.
Refers to the character just before which the insertion cursor
is drawn in this item. Not valid for lines and polygons.
.TP 10
\fBsel.first\fR
.
Refers to the first selected character in the item.
If the selection is not in this item then this form is illegal.
.TP 10
\fBsel.last\fR
.
Refers to the last selected character in the item.
If the selection is not in this item then this form is illegal.
.TP 10
\fB@\fIx,y\fR
.
Refers to the character or coordinate at the point given by \fIx\fR and
\fIy\fR, where \fIx\fR and \fIy\fR are specified in the coordinate
system of the canvas.
If \fIx\fR and \fIy\fR lie outside the coordinates covered by the
text item, then they refer to the first or last character in the
line that is closest to the given point.
.SH "DASH PATTERNS"







<
|
<












<
|
<



<
|
<


<
|
<


<
|
<


<
|
<







252
253
254
255
256
257
258

259

260
261
262
263
264
265
266
267
268
269
270
271

272

273
274
275

276

277
278

279

280
281

282

283
284

285

286
287
288
289
290
291
292
support as many of these forms as practical.
Note that it is possible to refer to the character just after
the last one in the text item; this is necessary for such
tasks as inserting new text at the end of the item.
Lines and Polygons do not support the insertion cursor
and the selection. Their indices are supposed to be even
always, because coordinates always appear in pairs.

.IP \fInumber\fR 10

A decimal number giving the position of the desired character
within the text item.
0 refers to the first character, 1 to the next character, and
so on. If indexes are odd for lines and polygons, they will be
automatically decremented by one.
A number less than 0 is treated as if it were zero, and a
number greater than the length of the text item is treated
as if it were equal to the length of the text item. For
polygons, numbers less than 0 or greater than the length
of the coordinate list will be adjusted by adding or subtracting
the length until the result is between zero and the length,
inclusive.

.IP \fBend\fR 10

Refers to the character or coordinate just after the last one
in the item (same as the number of characters or coordinates
in the item).

.IP \fBinsert\fR 10

Refers to the character just before which the insertion cursor
is drawn in this item. Not valid for lines and polygons.

.IP \fBsel.first\fR 10

Refers to the first selected character in the item.
If the selection is not in this item then this form is illegal.

.IP \fBsel.last\fR 10

Refers to the last selected character in the item.
If the selection is not in this item then this form is illegal.

.IP \fB@\fIx,y\fR 10

Refers to the character or coordinate at the point given by \fIx\fR and
\fIy\fR, where \fIx\fR and \fIy\fR are specified in the coordinate
system of the canvas.
If \fIx\fR and \fIy\fR lie outside the coordinates covered by the
text item, then they refer to the first or last character in the
line that is closest to the given point.
.SH "DASH PATTERNS"
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

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

445
446
447
448
449
450
451
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:

.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg ...\fR?
.
For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the
command has no effect.
This command returns an empty string as result.
\fISearchSpec\fR and \fIarg\fR's may take any of the following
forms:
.RS
.TP
\fBabove \fItagOrId\fR
.
Selects the item just after (above) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the last (topmost)
of these items in the display list is used.
.TP
\fBall\fR
.
Selects all the items in the canvas.
.TP
\fBbelow \fItagOrId\fR
.
Selects the item just before (below) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the first (lowest)
of these items in the display list is used.
.TP
\fBclosest \fIx y \fR?\fIhalo\fR? ?\fIstart\fR?
.
Selects the item closest to the point given by \fIx\fR and \fIy\fR.
If more than one item is at the same closest distance (e.g. two
items overlap the point), then the top-most of these items (the
last one in the display list) is used.
If \fIhalo\fR is specified, then it must be a non-negative
value.
Any item closer than \fIhalo\fR to the point is considered to
overlap it.
The \fIstart\fR argument may be used to step circularly through
all the closest items.
If \fIstart\fR is specified, it names an item using a tag or id
(if by tag, it selects the first item in the display list with
the given tag).
Instead of selecting the topmost closest item, this form will
select the topmost closest item that is below \fIstart\fR in
the display list; if no such item exists, then the selection
behaves as if the \fIstart\fR argument had not been specified.
.TP
\fBenclosed\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR
.
Selects all the items completely enclosed within the rectangular
region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR.
\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.
.TP
\fBoverlapping\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR
.
Selects all the items that overlap or are enclosed within the
rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR,
and \fIy2\fR.
\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.
.TP
\fBwithtag \fItagOrId\fR
.
Selects all the items given by \fItagOrId\fR.
.RE

.TP
\fIpathName \fBbbox \fItagOrId\fR ?\fItagOrId tagOrId ...\fR?
.
Returns a list with four elements giving an approximate bounding box
for all the items named by the \fItagOrId\fR arguments.
The list has the form
.QW "\fIx1 y1 x2 y2\fR"
such that the drawn
areas of all the named elements are within the region bounded by
\fIx1\fR on the left, \fIx2\fR on the right, \fIy1\fR on the top,
and \fIy2\fR on the bottom.
The return value may overestimate the actual bounding box by
a few pixels.
If no items match any of the \fItagOrId\fR arguments or if the
matching items have empty bounding boxes (i.e. they have nothing
to display)
then an empty string is returned.

.TP
\fIpathName \fBbind \fItagOrId\fR ?\fIsequence\fR? ?\fIcommand\fR?
.
This command associates \fIcommand\fR with all the items given by
\fItagOrId\fR such that whenever the event sequence given by
\fIsequence\fR occurs for one of the items the command will
be invoked.







>














<
|
<




<
|
<

<
|
<




<
|
<

















<
|
<




<
|
<





<
|
<


>

















>







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

359

360
361
362
363

364

365

366

367
368
369
370

371

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

389

390
391
392
393

394

395
396
397
398
399

400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:
.\" METHOD: addtag
.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg ...\fR?
.
For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the
command has no effect.
This command returns an empty string as result.
\fISearchSpec\fR and \fIarg\fR's may take any of the following
forms:
.RS

.IP "\fBabove \fItagOrId\fR"

Selects the item just after (above) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the last (topmost)
of these items in the display list is used.

.IP \fBall\fR

Selects all the items in the canvas.

.IP "\fBbelow \fItagOrId\fR"

Selects the item just before (below) the one given by \fItagOrId\fR
in the display list.
If \fItagOrId\fR denotes more than one item, then the first (lowest)
of these items in the display list is used.

.IP "\fBclosest \fIx y \fR?\fIhalo\fR? ?\fIstart\fR?"

Selects the item closest to the point given by \fIx\fR and \fIy\fR.
If more than one item is at the same closest distance (e.g. two
items overlap the point), then the top-most of these items (the
last one in the display list) is used.
If \fIhalo\fR is specified, then it must be a non-negative
value.
Any item closer than \fIhalo\fR to the point is considered to
overlap it.
The \fIstart\fR argument may be used to step circularly through
all the closest items.
If \fIstart\fR is specified, it names an item using a tag or id
(if by tag, it selects the first item in the display list with
the given tag).
Instead of selecting the topmost closest item, this form will
select the topmost closest item that is below \fIstart\fR in
the display list; if no such item exists, then the selection
behaves as if the \fIstart\fR argument had not been specified.

.IP "\fBenclosed\fI x1 y1 x2 y2\fR"

Selects all the items completely enclosed within the rectangular
region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR.
\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.

.IP "\fBoverlapping\fI x1 y1 x2 y2\fR"

Selects all the items that overlap or are enclosed within the
rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR,
and \fIy2\fR.
\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be
no greater than \fIy2\fR.

.IP "\fBwithtag \fItagOrId\fR"

Selects all the items given by \fItagOrId\fR.
.RE
.\" METHOD: bbox
.TP
\fIpathName \fBbbox \fItagOrId\fR ?\fItagOrId tagOrId ...\fR?
.
Returns a list with four elements giving an approximate bounding box
for all the items named by the \fItagOrId\fR arguments.
The list has the form
.QW "\fIx1 y1 x2 y2\fR"
such that the drawn
areas of all the named elements are within the region bounded by
\fIx1\fR on the left, \fIx2\fR on the right, \fIy1\fR on the top,
and \fIy2\fR on the bottom.
The return value may overestimate the actual bounding box by
a few pixels.
If no items match any of the \fItagOrId\fR arguments or if the
matching items have empty bounding boxes (i.e. they have nothing
to display)
then an empty string is returned.
.\" METHOD: bind
.TP
\fIpathName \fBbind \fItagOrId\fR ?\fIsequence\fR? ?\fIcommand\fR?
.
This command associates \fIcommand\fR with all the items given by
\fItagOrId\fR such that whenever the event sequence given by
\fIsequence\fR occurs for one of the items the command will
be invoked.
499
500
501
502
503
504
505

506
507
508
509
510
511
512

513
514
515
516
517
518
519

520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572
573
574
575
576

577
578
579
580
581
582
583
584
585
586
587
588

589
590
591
592
593

594
595
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619
.PP
If bindings have been created for a canvas window using the \fBbind\fR
command, then they are invoked in addition to bindings created for
the canvas's items using the \fBbind\fR widget command.
The bindings for items will be invoked before any of the bindings
for the window as a whole.
.RE

.TP
\fIpathName \fBcanvasx \fIscreenx\fR ?\fIgridspacing\fR?
.
Given a window x-coordinate in the canvas \fIscreenx\fR, this command returns
the canvas x-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.

.TP
\fIpathName \fBcanvasy \fIscreeny\fR ?\fIgridspacing\fR?
.
Given a window y-coordinate in the canvas \fIscreeny\fR this command returns
the canvas y-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.

.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.

.TP
\fIpathName \fBconfigure ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list). If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified). If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.

.TP
\fIpathName\fR \fBcoords \fItagOrId \fR?\fIx0 y0 ...\fR?
.TP
\fIpathName\fR \fBcoords \fItagOrId \fR?\fIcoordList\fR?
.
Query or modify the coordinates that define an item.
If no coordinates are specified, this command returns a list
whose elements are the coordinates of the item named by
\fItagOrId\fR.
If coordinates are specified, then they replace the current
coordinates for the named item.
If \fItagOrId\fR refers to multiple items, then
the first one in the display list is used.
.RS
.PP
Note that for rectangles, ovals and arcs the returned list of coordinates
has a fixed order, namely the left, top, right and bottom coordinates,
which may not be the order originally given. Also the coordinates are always
returned in screen units with no units (that is, in pixels). So if the
original coordinates were specified for instance in centimeters or inches,
the returned values will nevertheless be in pixels.
.RE

.TP
\fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR?
.TP
\fIpathName \fBcreate \fItype coordList \fR?\fIoption value ...\fR?
.
Create a new item in \fIpathName\fR of type \fItype\fR.
The exact format of the arguments after \fItype\fR depends
on \fItype\fR, but usually they consist of the coordinates for
one or more points, followed by specifications for zero or
more item options.
See the subsections on individual item types below for more
on the syntax of this command.
This command returns the id for the new item.

.TP
\fIpathName \fBdchars \fItagOrId first \fR?\fIlast\fR?
.
For each item given by \fItagOrId\fR, delete the characters, or coordinates,
in the range given by \fIfirst\fR and \fIlast\fR, inclusive.
If some of the items given by \fItagOrId\fR do not support
indexing operations then they ignore this operation.
Text items interpret \fIfirst\fR and \fIlast\fR as indices to a character,
line and polygon items interpret them as indices to a coordinate (an x,y pair).
Indices are described in \fBINDICES\fR above.
If \fIlast\fR is omitted, it defaults to \fIfirst\fR.
This command returns an empty string.

.TP
\fIpathName \fBdelete \fR?\fItagOrId tagOrId ...\fR?
.
Delete each of the items given by each \fItagOrId\fR, and return
an empty string.

.TP
\fIpathName \fBdtag \fItagOrId \fR?\fItagToDelete\fR?
.
For each of the items given by \fItagOrId\fR, delete the
tag given by \fItagToDelete\fR from the list of those
associated with the item.
If an item does not have the tag \fItagToDelete\fR then
the item is unaffected by the command.
If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR.
This command returns an empty string.

.TP
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg ...\fR?
.
This command returns a list consisting of all the items that
meet the constraints specified by \fIsearchCommand\fR and
\fIarg\fR's.
\fISearchCommand\fR and \fIargs\fR have any of the forms
accepted by the \fBaddtag\fR command.
The items are returned in stacking order, with the lowest item first.

.TP
\fIpathName \fBfocus \fR?\fItagOrId\fR?
.
Set the keyboard focus for the canvas widget to the item given by
\fItagOrId\fR.
If \fItagOrId\fR refers to several items, then the focus is set
to the first such item in the display list that supports the







>







>







>

|





>















>

|

|


















>













>












>





>










>









>







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
.PP
If bindings have been created for a canvas window using the \fBbind\fR
command, then they are invoked in addition to bindings created for
the canvas's items using the \fBbind\fR widget command.
The bindings for items will be invoked before any of the bindings
for the window as a whole.
.RE
.\" METHOD: canvasx
.TP
\fIpathName \fBcanvasx \fIscreenx\fR ?\fIgridspacing\fR?
.
Given a window x-coordinate in the canvas \fIscreenx\fR, this command returns
the canvas x-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.
.\" METHOD: canvasy
.TP
\fIpathName \fBcanvasy \fIscreeny\fR ?\fIgridspacing\fR?
.
Given a window y-coordinate in the canvas \fIscreeny\fR this command returns
the canvas y-coordinate that is displayed at that location.
If \fIgridspacing\fR is specified, then the canvas coordinate is
rounded to the nearest multiple of \fIgridspacing\fR units.
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list). If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified). If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBcanvas\fR
command.
.\" METHOD: coords
.TP
\fIpathName \fBcoords \fItagOrId \fR?\fIx0 y0 ...\fR?
.TP
\fIpathName \fBcoords \fItagOrId \fR?\fIcoordList\fR?
.
Query or modify the coordinates that define an item.
If no coordinates are specified, this command returns a list
whose elements are the coordinates of the item named by
\fItagOrId\fR.
If coordinates are specified, then they replace the current
coordinates for the named item.
If \fItagOrId\fR refers to multiple items, then
the first one in the display list is used.
.RS
.PP
Note that for rectangles, ovals and arcs the returned list of coordinates
has a fixed order, namely the left, top, right and bottom coordinates,
which may not be the order originally given. Also the coordinates are always
returned in screen units with no units (that is, in pixels). So if the
original coordinates were specified for instance in centimeters or inches,
the returned values will nevertheless be in pixels.
.RE
.\" METHOD: create
.TP
\fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR?
.TP
\fIpathName \fBcreate \fItype coordList \fR?\fIoption value ...\fR?
.
Create a new item in \fIpathName\fR of type \fItype\fR.
The exact format of the arguments after \fItype\fR depends
on \fItype\fR, but usually they consist of the coordinates for
one or more points, followed by specifications for zero or
more item options.
See the subsections on individual item types below for more
on the syntax of this command.
This command returns the id for the new item.
.\" METHOD: dchars
.TP
\fIpathName \fBdchars \fItagOrId first \fR?\fIlast\fR?
.
For each item given by \fItagOrId\fR, delete the characters, or coordinates,
in the range given by \fIfirst\fR and \fIlast\fR, inclusive.
If some of the items given by \fItagOrId\fR do not support
indexing operations then they ignore this operation.
Text items interpret \fIfirst\fR and \fIlast\fR as indices to a character,
line and polygon items interpret them as indices to a coordinate (an x,y pair).
Indices are described in \fBINDICES\fR above.
If \fIlast\fR is omitted, it defaults to \fIfirst\fR.
This command returns an empty string.
.\" METHOD: delete
.TP
\fIpathName \fBdelete \fR?\fItagOrId tagOrId ...\fR?
.
Delete each of the items given by each \fItagOrId\fR, and return
an empty string.
.\" METHOD: dtag
.TP
\fIpathName \fBdtag \fItagOrId \fR?\fItagToDelete\fR?
.
For each of the items given by \fItagOrId\fR, delete the
tag given by \fItagToDelete\fR from the list of those
associated with the item.
If an item does not have the tag \fItagToDelete\fR then
the item is unaffected by the command.
If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR.
This command returns an empty string.
.\" METHOD: find
.TP
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg ...\fR?
.
This command returns a list consisting of all the items that
meet the constraints specified by \fIsearchCommand\fR and
\fIarg\fR's.
\fISearchCommand\fR and \fIargs\fR have any of the forms
accepted by the \fBaddtag\fR command.
The items are returned in stacking order, with the lowest item first.
.\" METHOD: focus
.TP
\fIpathName \fBfocus \fR?\fItagOrId\fR?
.
Set the keyboard focus for the canvas widget to the item given by
\fItagOrId\fR.
If \fItagOrId\fR refers to several items, then the focus is set
to the first such item in the display list that supports the
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
659


660
661
662
663

664


665
666
667
668
669

670
671
672



673
674
675
676
677

678


679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
708
709
710


711
712

713


714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
a given item does not actually have the input focus unless (a)
its canvas is the focus window and (b) the item is the focus item
within the canvas.
In most cases it is advisable to follow the \fBfocus\fR widget
command with the \fBfocus\fR command to set the focus window to
the canvas (if it was not there already).
.RE

.TP
\fIpathName \fBgettags\fR \fItagOrId\fR
.
Return a list whose elements are the tags associated with the
item given by \fItagOrId\fR.
If \fItagOrId\fR refers to more than one item, then the tags
are returned from the first such item in the display list.
If \fItagOrId\fR does not refer to any items, or if the item
contains no tags, then an empty string is returned.

.TP
\fIpathName \fBicursor \fItagOrId index\fR
.
Set the position of the insertion cursor for the item(s) given by \fItagOrId\fR
to just before the character whose position is given by \fIindex\fR.
If some or all of the items given by \fItagOrId\fR do not support
an insertion cursor then this command has no effect on them.
See \fBINDICES\fR above for a description of the
legal forms for \fIindex\fR.


Note: the insertion cursor is only displayed in an item if
that item currently has the keyboard focus (see the \fBfocus\fR widget
command, above), but the cursor position may
be set even when the item does not have the focus.

This command returns an empty string.


.TP
\fIpathName \fBimage \fIimagename\fR ?\fIsubsample\fR? ?\fIzoom\fR?
.
Draw the canvas into the Tk photo image named \fIimagename\fR. If a \fB-scrollregion\fR
has been defined then this will be the boundaries of the canvas region drawn and the

final size of the photo image. Otherwise the widget width and height with an origin
of 0,0 will be the size of the canvas region drawn and the final size of the photo
image. Optionally an integer \fIsubsample\fR factor may be given and the photo image



will be reduced in size. In addition to the \fIsubsample\fR an integer \fIzoom\fR
factor can also be given and the photo image will be enlarged. The image background
will be filled with the canvas background colour. The canvas widget does not need to
be mapped for this widget command to work, but at least one of it's ancestors must be
mapped.

This command returns an empty string.


.TP
\fIpathName \fBimove \fItagOrId index x y\fR
.
This command causes the \fIindex\fR'th coordinate of each of the items
indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
Each item interprets \fIindex\fR independently according to the rules
described in \fBINDICES\fR above. Out of the standard set of items, only line
and polygon items may have their coordinates relocated this way.

.TP
\fIpathName \fBindex \fItagOrId index\fR
.
This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.
Text items interpret \fIindex\fR as an index to a character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
The return value is guaranteed to lie between 0 and the number
of characters, or coordinates, within the item, inclusive.
If \fItagOrId\fR refers to multiple items, then the index
is processed in the first of these items that supports indexing
operations (in display list order).

.TP
\fIpathName \fBinsert \fItagOrId beforeThis string\fR
.
For each of the items given by \fItagOrId\fR, if the item supports
text or coordinate, insertion then \fIstring\fR is inserted into the item's
text just before the character, or coordinate, whose index is \fIbeforeThis\fR.
Text items interpret \fIbeforeThis\fR as an index to a character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
For lines and polygons the \fIstring\fR must be a valid coordinate
sequence.


See \fBINDICES\fR above for information about the forms allowed
for \fIbeforeThis\fR.

This command returns an empty string.


.TP
\fIpathName \fBitemcget\fR \fItagOrId\fR \fIoption\fR
.
Returns the current value of the configuration option for the
item given by \fItagOrId\fR whose name is \fIoption\fR.
This command is similar to the \fBcget\fR widget command except that
it applies to a particular item rather than the widget as a whole.
\fIOption\fR may have any of the values accepted by the \fBcreate\fR
widget command when the item was created.
If \fItagOrId\fR is a tag that refers to more than one item,
the first (lowest) such item is used.

.TP
\fIpathName \fBitemconfigure \fItagOrId\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
This command is similar to the \fBconfigure\fR widget command except
that it modifies item-specific options for the items given by
\fItagOrId\fR instead of modifying options for the overall
canvas widget.







>

|







>









>
>
|



>

>
>



|
|
>
|
|
|
>
>
>
|
|
|
|
|
>

>
>








>














>










>
>


>

>
>

|









>







623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
a given item does not actually have the input focus unless (a)
its canvas is the focus window and (b) the item is the focus item
within the canvas.
In most cases it is advisable to follow the \fBfocus\fR widget
command with the \fBfocus\fR command to set the focus window to
the canvas (if it was not there already).
.RE
.\" METHOD: gettags
.TP
\fIpathName \fBgettags\fI tagOrId\fR
.
Return a list whose elements are the tags associated with the
item given by \fItagOrId\fR.
If \fItagOrId\fR refers to more than one item, then the tags
are returned from the first such item in the display list.
If \fItagOrId\fR does not refer to any items, or if the item
contains no tags, then an empty string is returned.
.\" METHOD: icursor
.TP
\fIpathName \fBicursor \fItagOrId index\fR
.
Set the position of the insertion cursor for the item(s) given by \fItagOrId\fR
to just before the character whose position is given by \fIindex\fR.
If some or all of the items given by \fItagOrId\fR do not support
an insertion cursor then this command has no effect on them.
See \fBINDICES\fR above for a description of the
legal forms for \fIindex\fR.
.RS
.PP
Note that the insertion cursor is only displayed in an item if
that item currently has the keyboard focus (see the \fBfocus\fR widget
command, above), but the cursor position may
be set even when the item does not have the focus.
.PP
This command returns an empty string.
.RE
.\" METHOD: image
.TP
\fIpathName \fBimage \fIimagename\fR ?\fIsubsample\fR? ?\fIzoom\fR?
.
Draw the canvas into the Tk photo image named \fIimagename\fR.
If a \fB\-scrollregion\fR has been defined then this will be the boundaries
of the canvas region drawn and the final size of the photo image. Otherwise
the widget width and height with an origin of 0,0 will be the size of the
canvas region drawn and the final size of the photo image. Optionally an
integer \fIsubsample\fR factor may be given and the photo image
will be reduced in size.
.RS
.PP
In addition to the \fIsubsample\fR an integer \fIzoom\fR factor can also
be given and the photo image will be enlarged. The image background will
be filled with the canvas background colour. The canvas widget does not
need to be mapped for this widget command to work, but at least one of
it's ancestors must be mapped.
.PP
This command returns an empty string.
.RE
.\" METHOD: imove
.TP
\fIpathName \fBimove \fItagOrId index x y\fR
.
This command causes the \fIindex\fR'th coordinate of each of the items
indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
Each item interprets \fIindex\fR independently according to the rules
described in \fBINDICES\fR above. Out of the standard set of items, only line
and polygon items may have their coordinates relocated this way.
.\" METHOD: index
.TP
\fIpathName \fBindex \fItagOrId index\fR
.
This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.
Text items interpret \fIindex\fR as an index to a character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
The return value is guaranteed to lie between 0 and the number
of characters, or coordinates, within the item, inclusive.
If \fItagOrId\fR refers to multiple items, then the index
is processed in the first of these items that supports indexing
operations (in display list order).
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fItagOrId beforeThis string\fR
.
For each of the items given by \fItagOrId\fR, if the item supports
text or coordinate, insertion then \fIstring\fR is inserted into the item's
text just before the character, or coordinate, whose index is \fIbeforeThis\fR.
Text items interpret \fIbeforeThis\fR as an index to a character,
line and polygon items interpret it as an index to a coordinate (an x,y pair).
For lines and polygons the \fIstring\fR must be a valid coordinate
sequence.
.RS
.PP
See \fBINDICES\fR above for information about the forms allowed
for \fIbeforeThis\fR.
.PP
This command returns an empty string.
.RE
.\" METHOD: itemcget
.TP
\fIpathName \fBitemcget\fI tagOrId option\fR
.
Returns the current value of the configuration option for the
item given by \fItagOrId\fR whose name is \fIoption\fR.
This command is similar to the \fBcget\fR widget command except that
it applies to a particular item rather than the widget as a whole.
\fIOption\fR may have any of the values accepted by the \fBcreate\fR
widget command when the item was created.
If \fItagOrId\fR is a tag that refers to more than one item,
the first (lowest) such item is used.
.\" METHOD: itemconfigure
.TP
\fIpathName \fBitemconfigure \fItagOrId\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
This command is similar to the \fBconfigure\fR widget command except
that it modifies item-specific options for the items given by
\fItagOrId\fR instead of modifying options for the overall
canvas widget.
740
741
742
743
744
745
746

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768
769

770
771
772
773
774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
modifies the given widget option(s) to have the given value(s) in
each of the items given by \fItagOrId\fR; in
this case the command returns an empty string.
The \fIoption\fRs and \fIvalue\fRs are the same as those permissible
in the \fBcreate\fR widget command when the item(s) were created;
see the sections describing individual item types below for details
on the legal options.

.TP
\fIpathName \fBlower \fItagOrId \fR?\fIbelowThis\fR?
.
Move all of the items given by \fItagOrId\fR to a new position
in the display list just before the item given by \fIbelowThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIBelowThis\fR is a tag or id; if it refers to more than one
item then the first (lowest) of these items in the display list is used
as the destination location for the moved items.
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
This command returns an empty string.

.TP
\fIpathName \fBmove \fItagOrId xAmount yAmount\fR
.
Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.

.TP
\fIpathName \fBmoveto \fItagOrId xPos yPos\fR
.
Move the items given by \fItagOrId\fR in the canvas coordinate
space so that the first coordinate pair (the upper-left corner of the
bounding box) of the first item (the lowest in the display list) with
tag \fItagOrId\fR is located at
position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be
the empty string, in which case the corresponding coordinate
will be unchanged. All items matching
\fItagOrId\fR remain in the same positions relative to each other.
This command returns an empty string.

.TP
\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?
.
Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned; otherwise the Postscript
is returned as the result of the command.







>










|




>








>












>







750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
modifies the given widget option(s) to have the given value(s) in
each of the items given by \fItagOrId\fR; in
this case the command returns an empty string.
The \fIoption\fRs and \fIvalue\fRs are the same as those permissible
in the \fBcreate\fR widget command when the item(s) were created;
see the sections describing individual item types below for details
on the legal options.
.\" METHOD: lower
.TP
\fIpathName \fBlower \fItagOrId \fR?\fIbelowThis\fR?
.
Move all of the items given by \fItagOrId\fR to a new position
in the display list just before the item given by \fIbelowThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIBelowThis\fR is a tag or id; if it refers to more than one
item then the first (lowest) of these items in the display list is used
as the destination location for the moved items.
Note that this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
This command returns an empty string.
.\" METHOD: move
.TP
\fIpathName \fBmove \fItagOrId xAmount yAmount\fR
.
Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.
.\" METHOD: moveto
.TP
\fIpathName \fBmoveto \fItagOrId xPos yPos\fR
.
Move the items given by \fItagOrId\fR in the canvas coordinate
space so that the first coordinate pair (the upper-left corner of the
bounding box) of the first item (the lowest in the display list) with
tag \fItagOrId\fR is located at
position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be
the empty string, in which case the corresponding coordinate
will be unchanged. All items matching
\fItagOrId\fR remain in the same positions relative to each other.
This command returns an empty string.
.\" METHOD: postscript
.TP
\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?
.
Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned; otherwise the Postscript
is returned as the result of the command.
801
802
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
either invoke the \fBupdate\fR command to wait for the canvas window
to reach its final size, or else use the \fB\-width\fR and \fB\-height\fR
options to specify the area of the canvas to print.
The \fIoption\fR\-\fIvalue\fR argument pairs provide additional
information to control the generation of Postscript. The following
options are supported:
.RS

.TP
\fB\-channel \fIchannelName\fR
.
Specifies the name of the channel to which to write the Postscript.
If this option and the \fB\-file\fR option are
not specified then the Postscript is returned as the
result of the command.

.TP
\fB\-colormap \fIvarName\fR
.
\fIVarName\fR must be the name of an array variable
that specifies a color mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of Postscript
code to set a particular color value (e.g.
.QW "\fB1.0 1.0 0.0 setrgbcolor\fR" ).
When outputting color information in the Postscript, Tk checks
to see if there is an element of \fIvarName\fR with the same
name as the color.
If so, Tk uses the value of the element as the Postscript command
to set the color.


If this option has not been specified, or if there is no entry
in \fIvarName\fR for a given color, then Tk uses the red, green,
and blue intensities from the X color.


.TP
\fB\-colormode \fImode\fR
.
Specifies how to output color information. \fIMode\fR must be either
\fBcolor\fR (for full color output), \fBgray\fR (convert all colors
to their gray-scale equivalents) or \fBmono\fR (convert all colors
to black or white).

.TP
\fB\-file \fIfileName\fR
.
Specifies the name of the file in which to write the Postscript.
If this option and the \fB\-channel\fR option are
not specified then the Postscript is returned as the
result of the command.

.TP
\fB\-fontmap \fIvarName\fR
.
\fIVarName\fR must be the name of an array variable
that specifies a font mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of a Tcl list with
two elements, which are the name and point size of a Postscript font.
When outputting Postscript commands for a particular font, Tk
checks to see if \fIvarName\fR contains an element with the same
name as the font.
If there is such an element, then the font information contained in
that element is used in the Postscript.
Otherwise Tk attempts to guess what Postscript font to use.
Tk's guesses generally only work for well-known fonts such as
Times and Helvetica and Courier, and only if the X font name does not
omit any dashes up through the point size.


For example, \fB\-*\-Courier\-Bold\-R\-Normal\-\-*\-120\-*\fR will work but
\fB*Courier\-Bold\-R\-Normal*120*\fR will not; Tk needs the dashes to
parse the font name).


.TP
\fB\-height \fIsize\fR
.
Specifies the height of the area of the canvas to print.
Defaults to the height of the canvas window.

.TP
\fB\-pageanchor \fIanchor\fR
.
Specifies which point of the printed area of the canvas should appear over
the positioning point on the page (which is given by the \fB\-pagex\fR
and \fB\-pagey\fR options).


For example, \fB\-pageanchor n\fR means that the top center of the
area of the canvas being printed (as it appears in the canvas window)
should be over the positioning point. Defaults to \fBcenter\fR.


.TP
\fB\-pageheight \fIsize\fR
.
Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR high on the Postscript page.
\fISize\fR consists of a floating-point number followed by
\fBc\fR for centimeters, \fBi\fR for inches, \fBm\fR for millimeters,
or \fBp\fR or nothing for printer's points (1/72 inch).
Defaults to the height of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).

.TP
\fB\-pagewidth \fIsize\fR
.
Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR wide on the Postscript page.
\fISize\fR has the same form as for \fB\-pageheight\fR.
Defaults to the width of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).

.TP
\fB\-pagex \fIposition\fR
.
\fIPosition\fR gives the x-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagey\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.

.TP
\fB\-pagey \fIposition\fR
.
\fIPosition\fR gives the y-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagex\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.

.TP
\fB\-rotate \fIboolean\fR
.
\fIBoolean\fR specifies whether the printed area is to be rotated 90
degrees.
In non-rotated output the x-axis of the printed area runs along
the short dimension of the page
.PQ portrait " orientation" ;
in rotated output the x-axis runs along the long dimension of the page
.PQ landscape " orientation" .
Defaults to non-rotated.

.TP
\fB\-width \fIsize\fR
.
Specifies the width of the area of the canvas to print.
Defaults to the width of the canvas window.

.TP
\fB\-x \fIposition\fR
.
Specifies the x-coordinate of the left edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the left edge of the window.

.TP
\fB\-y \fIposition\fR
.
Specifies the y-coordinate of the top edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the top edge of the window.
.RE

.TP
\fIpathName \fBraise \fItagOrId \fR?\fIaboveThis\fR?
.
Move all of the items given by \fItagOrId\fR to a new position
in the display list just after the item given by \fIaboveThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIAboveThis\fR is a tag or id; if it refers to more than one
item then the last (topmost) of these items in the display list is used
as the destination location for the moved items.
This command returns an empty string.
.RS
.PP
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE

.TP
\fIpathName \fBrchars \fItagOrId first last string\fR
.
This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.

.TP
\fIpathName \fBrotate \fItagOrId xOrigin yOrigin angle\fR
.VS "8.7, TIP164"
Rotate the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
operation and \fIangle\fR identifies the amount to rotate the coordinates







>







>













>
>



>
>







>







>
















>
>



>
>





>






>
>



>
>












>










>








>








>











>





>







>








>













|




>











>







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
either invoke the \fBupdate\fR command to wait for the canvas window
to reach its final size, or else use the \fB\-width\fR and \fB\-height\fR
options to specify the area of the canvas to print.
The \fIoption\fR\-\fIvalue\fR argument pairs provide additional
information to control the generation of Postscript. The following
options are supported:
.RS
.\" OPTION: -channel
.TP
\fB\-channel \fIchannelName\fR
.
Specifies the name of the channel to which to write the Postscript.
If this option and the \fB\-file\fR option are
not specified then the Postscript is returned as the
result of the command.
.\" OPTION: -colormap
.TP
\fB\-colormap \fIvarName\fR
.
\fIVarName\fR must be the name of an array variable
that specifies a color mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of Postscript
code to set a particular color value (e.g.
.QW "\fB1.0 1.0 0.0 setrgbcolor\fR" ).
When outputting color information in the Postscript, Tk checks
to see if there is an element of \fIvarName\fR with the same
name as the color.
If so, Tk uses the value of the element as the Postscript command
to set the color.
.RS
.PP
If this option has not been specified, or if there is no entry
in \fIvarName\fR for a given color, then Tk uses the red, green,
and blue intensities from the X color.
.RE
.\" OPTION: -colormode
.TP
\fB\-colormode \fImode\fR
.
Specifies how to output color information. \fIMode\fR must be either
\fBcolor\fR (for full color output), \fBgray\fR (convert all colors
to their gray-scale equivalents) or \fBmono\fR (convert all colors
to black or white).
.\" OPTION: -file
.TP
\fB\-file \fIfileName\fR
.
Specifies the name of the file in which to write the Postscript.
If this option and the \fB\-channel\fR option are
not specified then the Postscript is returned as the
result of the command.
.\" OPTION: -fontmap
.TP
\fB\-fontmap \fIvarName\fR
.
\fIVarName\fR must be the name of an array variable
that specifies a font mapping to use in the Postscript.
Each element of \fIvarName\fR must consist of a Tcl list with
two elements, which are the name and point size of a Postscript font.
When outputting Postscript commands for a particular font, Tk
checks to see if \fIvarName\fR contains an element with the same
name as the font.
If there is such an element, then the font information contained in
that element is used in the Postscript.
Otherwise Tk attempts to guess what Postscript font to use.
Tk's guesses generally only work for well-known fonts such as
Times and Helvetica and Courier, and only if the X font name does not
omit any dashes up through the point size.
.RS
.PP
For example, \fB\-*\-Courier\-Bold\-R\-Normal\-\-*\-120\-*\fR will work but
\fB*Courier\-Bold\-R\-Normal*120*\fR will not; Tk needs the dashes to
parse the font name).
.RE
.\" OPTION: -height
.TP
\fB\-height \fIsize\fR
.
Specifies the height of the area of the canvas to print.
Defaults to the height of the canvas window.
.\" OPTION: -pageanchor
.TP
\fB\-pageanchor \fIanchor\fR
.
Specifies which point of the printed area of the canvas should appear over
the positioning point on the page (which is given by the \fB\-pagex\fR
and \fB\-pagey\fR options).
.RS
.PP
For example, \fB\-pageanchor n\fR means that the top center of the
area of the canvas being printed (as it appears in the canvas window)
should be over the positioning point. Defaults to \fBcenter\fR.
.RE
.\" OPTION: -pageheight
.TP
\fB\-pageheight \fIsize\fR
.
Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR high on the Postscript page.
\fISize\fR consists of a floating-point number followed by
\fBc\fR for centimeters, \fBi\fR for inches, \fBm\fR for millimeters,
or \fBp\fR or nothing for printer's points (1/72 inch).
Defaults to the height of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).
.\" OPTION: -pagewidth
.TP
\fB\-pagewidth \fIsize\fR
.
Specifies that the Postscript should be scaled in both x and y so
that the printed area is \fIsize\fR wide on the Postscript page.
\fISize\fR has the same form as for \fB\-pageheight\fR.
Defaults to the width of the printed area on the screen.
If both \fB\-pageheight\fR and \fB\-pagewidth\fR are specified then
the scale factor from \fB\-pagewidth\fR is used (non-uniform scaling
is not implemented).
.\" OPTION: -pagex
.TP
\fB\-pagex \fIposition\fR
.
\fIPosition\fR gives the x-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagey\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.
.\" OPTION: -pagey
.TP
\fB\-pagey \fIposition\fR
.
\fIPosition\fR gives the y-coordinate of the positioning point on
the Postscript page, using any of the forms allowed for \fB\-pageheight\fR.
Used in conjunction with the \fB\-pagex\fR and \fB\-pageanchor\fR options
to determine where the printed area appears on the Postscript page.
Defaults to the center of the page.
.\" OPTION: -rotate
.TP
\fB\-rotate \fIboolean\fR
.
\fIBoolean\fR specifies whether the printed area is to be rotated 90
degrees.
In non-rotated output the x-axis of the printed area runs along
the short dimension of the page
.PQ portrait " orientation" ;
in rotated output the x-axis runs along the long dimension of the page
.PQ landscape " orientation" .
Defaults to non-rotated.
.\" OPTION: -width
.TP
\fB\-width \fIsize\fR
.
Specifies the width of the area of the canvas to print.
Defaults to the width of the canvas window.
.\" OPTION: -x
.TP
\fB\-x \fIposition\fR
.
Specifies the x-coordinate of the left edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the left edge of the window.
.\" OPTION: -y
.TP
\fB\-y \fIposition\fR
.
Specifies the y-coordinate of the top edge of the area of the
canvas that is to be printed, in canvas coordinates, not window
coordinates.
Defaults to the coordinate of the top edge of the window.
.RE
.\" METHOD: raise
.TP
\fIpathName \fBraise \fItagOrId \fR?\fIaboveThis\fR?
.
Move all of the items given by \fItagOrId\fR to a new position
in the display list just after the item given by \fIaboveThis\fR.
If \fItagOrId\fR refers to more than one item then all are moved
but the relative order of the moved items will not be changed.
\fIAboveThis\fR is a tag or id; if it refers to more than one
item then the last (topmost) of these items in the display list is used
as the destination location for the moved items.
This command returns an empty string.
.RS
.PP
Note this this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE
.\" METHOD: rchars
.TP
\fIpathName \fBrchars \fItagOrId first last string\fR
.
This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.
.\" METHOD: rotate
.TP
\fIpathName \fBrotate \fItagOrId xOrigin yOrigin angle\fR
.VS "8.7, TIP164"
Rotate the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
operation and \fIangle\fR identifies the amount to rotate the coordinates
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
points, and the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types rotate about a
computed center point instead of moving the bounding box coordinates directly.
.PP
Some items (currently \fBarc\fR and\fB text\fR) have angles in their options;
this command \fIdoes not\fR affect those options.
.RE
.VE "8.7, TIP164"

.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale







>







1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
points, and the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types rotate about a
computed center point instead of moving the bounding box coordinates directly.
.PP
Some items (currently \fBarc\fR and\fB text\fR) have angles in their options;
this command \fIdoes not\fR affect those options.
.RE
.VE "8.7, TIP164"
.\" METHOD: scale
.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale
1011
1012
1013
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1025
1026
This command returns an empty string.
.RS
.PP
Note that some items have only a single pair of coordinates (e.g., text,
images and windows) and so scaling of them by this command can only move them
around.
.RE

.TP
\fIpathName \fBscan\fR \fIoption args\fR
.
This command is used to implement scanning on canvases. It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.







>

|







1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
This command returns an empty string.
.RS
.PP
Note that some items have only a single pair of coordinates (e.g., text,
images and windows) and so scaling of them by this command can only move them
around.
.RE
.\" METHOD: scan
.TP
\fIpathName \fBscan\fI option args\fR
.
This command is used to implement scanning on canvases. It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
It then adjusts the view by \fIgain\fR times the
difference in coordinates, where \fIgain\fR defaults to 10.
This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the canvas at high speed through its window. The return
value is an empty string.
.RE

.TP
\fIpathName \fBselect \fIoption\fR ?\fItagOrId arg\fR?
.
Manipulates the selection in one of several ways, depending on
\fIoption\fR.
The command may take any of the forms described below.
In all of the descriptions below, \fItagOrId\fR must refer to







>







1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
It then adjusts the view by \fIgain\fR times the
difference in coordinates, where \fIgain\fR defaults to 10.
This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the canvas at high speed through its window. The return
value is an empty string.
.RE
.\" METHOD: select
.TP
\fIpathName \fBselect \fIoption\fR ?\fItagOrId arg\fR?
.
Manipulates the selection in one of several ways, depending on
\fIoption\fR.
The command may take any of the forms described below.
In all of the descriptions below, \fItagOrId\fR must refer to
1104
1105
1106
1107
1108
1109
1110

1111
1112
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
The anchor point is determined by the most recent \fBselect adjust\fR
or \fBselect from\fR command for this widget.
If the selection anchor point for the widget is not currently in
\fItagOrId\fR, then it is set to the same character given
by \fIindex\fR.
Returns an empty string.
.RE

.TP
\fIpathName \fBtype\fI tagOrId\fR
.
Returns the type of the item given by \fItagOrId\fR, such as
\fBrectangle\fR or \fBtext\fR.
If \fItagOrId\fR refers to more than one item, then the type
of the first item in the display list is returned.
If \fItagOrId\fR does not refer to any items at all then
an empty string is returned.

.TP
\fIpathName \fBxview \fR?\fIargs\fR?
.
This command is used to query and change the horizontal position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS







>









>







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
The anchor point is determined by the most recent \fBselect adjust\fR
or \fBselect from\fR command for this widget.
If the selection anchor point for the widget is not currently in
\fItagOrId\fR, then it is set to the same character given
by \fIindex\fR.
Returns an empty string.
.RE
.\" METHOD: type
.TP
\fIpathName \fBtype\fI tagOrId\fR
.
Returns the type of the item given by \fItagOrId\fR, such as
\fBrectangle\fR or \fBtext\fR.
If \fItagOrId\fR refers to more than one item, then the type
of the first item in the display list is returned.
If \fItagOrId\fR does not refer to any items at all then
an empty string is returned.
.\" METHOD: xview
.TP
\fIpathName \fBxview \fR?\fIargs\fR?
.
This command is used to query and change the horizontal position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
If \fInumber\fR is negative then information farther to the left
becomes visible; if it is positive then information farther to the right
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right in units
of the \fBxScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's width otherwise.
.RE

.TP
\fIpathName \fByview ?\fIargs\fR?
.
This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS







>







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
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
.\" METHOD: yview
.TP
\fIpathName \fByview ?\fIargs\fR?
.
This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:
.RS
1185
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
area is off-screen to the top.
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
If \fIwhat\fR is \fBpages\fR then
the view adjusts in units of nine-tenths the window's height.
If \fInumber\fR is negative then higher information becomes
visible; if it is positive then lower information
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down in units







|
>







1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
area is off-screen to the top.
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer 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.
If \fIwhat\fR is \fBpages\fR then
the view adjusts in units of nine-tenths the window's height.
If \fInumber\fR is negative then higher information becomes
visible; if it is positive then lower information
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down in units
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
At present, text, line and polygon items provide this support.
For lines and polygons the indexing facility is used to manipulate
the coordinates of the item.
.SS "COMMON ITEM OPTIONS"
.PP
Many items share a common set of options. These options are
explained here, and then referred to be each widget type for brevity.

.TP
\fB\-anchor \fIanchorPos\fR
.
\fIAnchorPos\fR tells how to position the item relative to the
positioning point for the item; it may have any of the forms
accepted by \fBTk_GetAnchor\fR. For example, if \fIanchorPos\fR
is \fBcenter\fR then the item is centered on the point; if
\fIanchorPos\fR is \fBn\fR then the item will be drawn so that
its top center point is at the positioning point.
This option defaults to \fBcenter\fR.

.TP
\fB\-dash \fIpattern\fR

.TP
\fB\-activedash \fIpattern\fR

.TP
\fB\-disableddash \fIpattern\fR
.
This option specifies dash patterns for the normal, active
state, and disabled state of an item.
\fIpattern\fR may have any of the forms accepted by \fBTk_GetDash\fR.
If the dash options are omitted then the default is a solid outline.
See \fBDASH PATTERNS\fR for more information.

.TP
\fB\-dashoffset \fIoffset\fR
.
The starting \fIoffset\fR in pixels into the pattern provided by the
\fB\-dash\fR option. \fB\-dashoffset\fR is ignored if there is no
\fB\-dash\fR pattern. The \fIoffset\fR may have any of the forms described
in the \fBCOORDINATES\fR section above.

.TP
\fB\-fill \fIcolor\fR

.TP
\fB\-activefill \fIcolor\fR

.TP
\fB\-disabledfill \fIcolor\fR
.
Specifies the color to be used to fill item's area.
in its normal, active, and disabled states,

\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
For the line item, it specifies the color of the line drawn.
For the text item, it specifies the foreground color of the text.
If \fIcolor\fR is an empty string (the default for all canvas items
except line and text), then the item will not be filled.

.TP
\fB\-outline \fIcolor\fR

.TP
\fB\-activeoutline \fIcolor\fR

.TP
\fB\-disabledoutline \fIcolor\fR
.
This option specifies the color that should be used to draw the
outline of the item in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If \fIcolor\fR is specified as an empty string then no outline is drawn
for the item.

.TP
\fB\-offset \fIoffset\fR
.
Specifies the offset of stipples. The offset value can be of the form
\fBx,y\fR or \fIside\fR, where side can be \fBn\fR, \fBne\fR, \fBe\fR,
\fBse\fR, \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR. In the
first case the origin is the origin of the toplevel of the current window.
For the canvas itself and canvas objects the origin is the canvas origin,
but putting \fB#\fR in front of the coordinate pair indicates using the
toplevel origin instead. For canvas objects, the \fB\-offset\fR option is
used for stippling as well. For the line and polygon canvas items you can
also specify an index as argument, which connects the stipple origin to one
of the coordinate points of the line/polygon. Note that stipple offsets are
\fIonly supported on X11\fR; they are silently ignored on other platforms.

.TP
\fB\-outlinestipple \fIbitmap\fR

.TP
\fB\-activeoutlinestipple \fIbitmap\fR

.TP
\fB\-disabledoutlinestipple \fIbitmap\fR
.
This option specifies stipple patterns that should be used to draw the
outline of the item in its normal, active and disabled states.
Indicates that the outline for the item should be drawn with a stipple pattern;
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-outline\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then the outline is drawn
in a solid fashion.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR

.TP
\fB\-outlineoffset \fIoffset\fR
.
Specifies the offset of the stipple pattern used for outlines, in the same way
that the \fB\-outline\fR option controls fill stipples. (See the
\fB\-outline\fR option for a description of the syntax of \fIoffset\fR.)

.TP
\fB\-stipple \fIbitmap\fR

.TP
\fB\-activestipple \fIbitmap\fR

.TP
\fB\-disabledstipple \fIbitmap\fR
.
This option specifies stipple patterns that should be used to fill
the item in its normal, active and disabled states.
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-fill\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then filling is done
in a solid fashion.
For the text item, it affects the actual text.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR

.TP
\fB\-state \fIstate\fR
.
This allows an item to override the canvas widget's global \fIstate\fR
option. It takes the same values:
\fInormal\fR, \fIdisabled\fR or \fIhidden\fR.

.TP
\fB\-tags \fItagList\fR
.
Specifies a set of tags to apply to the item.
\fITagList\fR consists of a list of tag names, which replace any
existing tags for the item. \fITagList\fR may be an empty list.

.TP
\fB\-width \fIoutlineWidth\fR

.TP
\fB\-activewidth \fIoutlineWidth\fR

.TP
\fB\-disabledwidth \fIoutlineWidth\fR
.
Specifies the width of the outline to be drawn around
the item's region, in its normal, active and disabled states.
\fIoutlineWidth\fR may be in any of the forms described in the
\fBCOORDINATES\fR section above.
If the \fB\-outline\fR option has been specified as an empty string then
this option has no effect. This option defaults to 1.0.
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by either the \fB\-start\fR and \fB\-extent\fR options or the \fB\-height\fR option)
and displayed in one of several ways (specified by the \fB\-style\fR option).

Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a







>










>


>


>



|




>







>


>


>



|
|
>





>


>


>



|




>














>


>


>



|










>






>


>


>



|










>






>






>


>


>



|












|
|
>







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
At present, text, line and polygon items provide this support.
For lines and polygons the indexing facility is used to manipulate
the coordinates of the item.
.SS "COMMON ITEM OPTIONS"
.PP
Many items share a common set of options. These options are
explained here, and then referred to be each widget type for brevity.
.\" OPTION: -anchor
.TP
\fB\-anchor \fIanchorPos\fR
.
\fIAnchorPos\fR tells how to position the item relative to the
positioning point for the item; it may have any of the forms
accepted by \fBTk_GetAnchor\fR. For example, if \fIanchorPos\fR
is \fBcenter\fR then the item is centered on the point; if
\fIanchorPos\fR is \fBn\fR then the item will be drawn so that
its top center point is at the positioning point.
This option defaults to \fBcenter\fR.
.\" OPTION: -dash
.TP
\fB\-dash \fIpattern\fR
.\" OPTION: -activedash
.TP
\fB\-activedash \fIpattern\fR
.\" OPTION: -disableddash
.TP
\fB\-disableddash \fIpattern\fR
.
These options specify dash patterns for the normal, active
state, and disabled state of an item.
\fIpattern\fR may have any of the forms accepted by \fBTk_GetDash\fR.
If the dash options are omitted then the default is a solid outline.
See \fBDASH PATTERNS\fR for more information.
.\" OPTION: -dashoffset
.TP
\fB\-dashoffset \fIoffset\fR
.
The starting \fIoffset\fR in pixels into the pattern provided by the
\fB\-dash\fR option. \fB\-dashoffset\fR is ignored if there is no
\fB\-dash\fR pattern. The \fIoffset\fR may have any of the forms described
in the \fBCOORDINATES\fR section above.
.\" OPTION: -fill
.TP
\fB\-fill \fIcolor\fR
.\" OPTION: -activefill
.TP
\fB\-activefill \fIcolor\fR
.\" OPTION: -disabledfill
.TP
\fB\-disabledfill \fIcolor\fR
.
These options specify the color to be used to fill item's area.
in its normal, active, and disabled states.
The even-odd fill rule is used.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
For the line item, it specifies the color of the line drawn.
For the text item, it specifies the foreground color of the text.
If \fIcolor\fR is an empty string (the default for all canvas items
except line and text), then the item will not be filled.
.\" OPTION: -outline
.TP
\fB\-outline \fIcolor\fR
.\" OPTION: -activeoutline
.TP
\fB\-activeoutline \fIcolor\fR
.\" OPTION: -disabledoutline
.TP
\fB\-disabledoutline \fIcolor\fR
.
These options specify the color that should be used to draw the
outline of the item in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If \fIcolor\fR is specified as an empty string then no outline is drawn
for the item.
.\" OPTION: -offset
.TP
\fB\-offset \fIoffset\fR
.
Specifies the offset of stipples. The offset value can be of the form
\fBx,y\fR or \fIside\fR, where side can be \fBn\fR, \fBne\fR, \fBe\fR,
\fBse\fR, \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR. In the
first case the origin is the origin of the toplevel of the current window.
For the canvas itself and canvas objects the origin is the canvas origin,
but putting \fB#\fR in front of the coordinate pair indicates using the
toplevel origin instead. For canvas objects, the \fB\-offset\fR option is
used for stippling as well. For the line and polygon canvas items you can
also specify an index as argument, which connects the stipple origin to one
of the coordinate points of the line/polygon. Note that stipple offsets are
\fIonly supported on X11\fR; they are silently ignored on other platforms.
.\" OPTION: -outlinestipple
.TP
\fB\-outlinestipple \fIbitmap\fR
.\" OPTION: -activeoutlinestipple
.TP
\fB\-activeoutlinestipple \fIbitmap\fR
.\" OPTION: -disabledoutlinestipple
.TP
\fB\-disabledoutlinestipple \fIbitmap\fR
.
These options specify stipple patterns that should be used to draw the
outline of the item in its normal, active and disabled states.
Indicates that the outline for the item should be drawn with a stipple pattern;
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-outline\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then the outline is drawn
in a solid fashion.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR
.\" OPTION: -outlineoffset
.TP
\fB\-outlineoffset \fIoffset\fR
.
Specifies the offset of the stipple pattern used for outlines, in the same way
that the \fB\-outline\fR option controls fill stipples. (See the
\fB\-outline\fR option for a description of the syntax of \fIoffset\fR.)
.\" OPTION: -stipple
.TP
\fB\-stipple \fIbitmap\fR
.\" OPTION: -activestipple
.TP
\fB\-activestipple \fIbitmap\fR
.\" OPTION: -disabledstipple
.TP
\fB\-disabledstipple \fIbitmap\fR
.
These options specify stipple patterns that should be used to fill
the item in its normal, active and disabled states.
\fIbitmap\fR specifies the stipple pattern to use, in any of the
forms accepted by \fBTk_GetBitmap\fR.
If the \fB\-fill\fR option has not been specified then this option
has no effect.
If \fIbitmap\fR is an empty string (the default), then filling is done
in a solid fashion.
For the text item, it affects the actual text.
\fINote that stipples are not well supported on platforms that do not
use X11 as their drawing API.\fR
.\" OPTION: -state
.TP
\fB\-state \fIstate\fR
.
This allows an item to override the canvas widget's global \fIstate\fR
option. It takes the same values:
\fInormal\fR, \fIdisabled\fR or \fIhidden\fR.
.\" OPTION: -tags
.TP
\fB\-tags \fItagList\fR
.
Specifies a set of tags to apply to the item.
\fITagList\fR consists of a list of tag names, which replace any
existing tags for the item. \fITagList\fR may be an empty list.
.\" OPTION: -width
.TP
\fB\-width \fIoutlineWidth\fR
.\" OPTION: -activewidth
.TP
\fB\-activewidth \fIoutlineWidth\fR
.\" OPTION: -disabledwidth
.TP
\fB\-disabledwidth \fIoutlineWidth\fR
.
These options specify the width of the outline to be drawn around
the item's region, in its normal, active and disabled states.
\fIoutlineWidth\fR may be in any of the forms described in the
\fBCOORDINATES\fR section above.
If the \fB\-outline\fR option has been specified as an empty string then
this option has no effect. This option defaults to 1.0.
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by either the \fB\-start\fR and \fB\-extent\fR options or the \fB\-height\fR
option) and displayed in one of several ways (specified by the \fB\-style\fR
option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
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
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR
\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR
\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for arcs:

.TP
\fB\-extent \fIdegrees\fR

Specifies the size of the angular range occupied by the arc.
The arc's range extends for \fIdegrees\fR degrees counter-clockwise
from the starting angle given by the \fB\-start\fR option.
\fIDegrees\fR may be negative.
If it is greater than 360 or less than \-360, then \fIdegrees\fR
modulo 360 is used as the extent.

.TP
\fB\-start \fIdegrees\fR

Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.

.TP
\fB\-height \fIdistance\fR

Provides a shortcut for creating a circular arc segment by defining the
distance of the mid-point of the arc from its chord. When this option
is used the coordinates are interpreted as the start and end coordinates
of the chord, and the options \fB\-start\fR and \fB-extent\fR are ignored.
The value of \fIdistance\fR has the following meaning:
.RS
.PP
.RS
\fIdistance\fR > 0 creates a clockwise arc
.br
\fIdistance\fR < 0 creates an counter-clockwise arc







>


>






>


>




>


>



|







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
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR
\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR
\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for arcs:
.\" OPTION: -extent
.TP
\fB\-extent \fIdegrees\fR
.
Specifies the size of the angular range occupied by the arc.
The arc's range extends for \fIdegrees\fR degrees counter-clockwise
from the starting angle given by the \fB\-start\fR option.
\fIDegrees\fR may be negative.
If it is greater than 360 or less than \-360, then \fIdegrees\fR
modulo 360 is used as the extent.
.\" OPTION: -start
.TP
\fB\-start \fIdegrees\fR
.
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.
.\" OPTION: -height
.TP
\fB\-height \fIdistance\fR
.
Provides a shortcut for creating a circular arc segment by defining the
distance of the mid-point of the arc from its chord. When this option
is used the coordinates are interpreted as the start and end coordinates
of the chord, and the options \fB\-start\fR and \fB\-extent\fR are ignored.
The value of \fIdistance\fR has the following meaning:
.RS
.PP
.RS
\fIdistance\fR > 0 creates a clockwise arc
.br
\fIdistance\fR < 0 creates an counter-clockwise arc
1437
1438
1439
1440
1441
1442
1443

1444
1445

1446
1447
1448
1449
1450
1451
1452
.RE
.PP
choosing the minus sign for the minor arc and the plus sign for the major arc.
.PP
Note that \fBitemcget \-height\fR always returns 0 so that introspection code
can be kept simple.
.RE

.TP
\fB\-style \fItype\fR

Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined
by a section of the oval's perimeter plus a single line segment
connecting the two end points of the perimeter section.







>


>







1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
.RE
.PP
choosing the minus sign for the minor arc and the plus sign for the major arc.
.PP
Note that \fBitemcget \-height\fR always returns 0 so that introspection code
can be kept simple.
.RE
.\" OPTION: -style
.TP
\fB\-style \fItype\fR
.
Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined
by a section of the oval's perimeter plus a single line segment
connecting the two end points of the perimeter section.
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
The following standard options are supported by bitmaps:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for bitmaps:

.TP
\fB\-background \fIcolor\fR

.TP
\fB\-activebackground \fIcolor\fR

.TP
\fB\-disabledbackground \fIcolor\fR

Specifies the color to use for each of the bitmap's
.QW 0
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If this option is not specified, or if it is specified as an empty
string, then nothing is displayed where the bitmap pixels are 0; this
produces a transparent effect.

.TP
\fB\-bitmap \fIbitmap\fR

.TP
\fB\-activebitmap \fIbitmap\fR

.TP
\fB\-disabledbitmap \fIbitmap\fR

Specifies the bitmaps to display in the item in its normal, active and
disabled states.
\fIBitmap\fR may have any of the forms accepted by \fBTk_GetBitmap\fR.

.TP
\fB\-foreground \fIcolor\fR

.TP
\fB\-activeforeground \fIcolor\fR

.TP
\fB\-disabledforeground \fIcolor\fR

Specifies the color to use for each of the bitmap's
.QW 1
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
.SS "IMAGE ITEMS"
.PP
Items of type \fBimage\fR are used to display images on a
canvas.







>


>


>


>







>


>


>


>
|
|

>


>


>


>
|







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
The following standard options are supported by bitmaps:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for bitmaps:
.\" OPTION: -background
.TP
\fB\-background \fIcolor\fR
.\" OPTION: -activebackground
.TP
\fB\-activebackground \fIcolor\fR
.\" OPTION: -disabledbackground
.TP
\fB\-disabledbackground \fIcolor\fR
.
Specifies the color to use for each of the bitmap's
.QW 0
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
If this option is not specified, or if it is specified as an empty
string, then nothing is displayed where the bitmap pixels are 0; this
produces a transparent effect.
.\" OPTION: -bitmap
.TP
\fB\-bitmap \fIbitmap\fR
.\" OPTION: -activebitmap
.TP
\fB\-activebitmap \fIbitmap\fR
.\" OPTION: -disabledbitmap
.TP
\fB\-disabledbitmap \fIbitmap\fR
.
These options specify the bitmaps to display in the item in its normal,
active and disabled states.
\fIBitmap\fR may have any of the forms accepted by \fBTk_GetBitmap\fR.
.\" OPTION: -foreground
.TP
\fB\-foreground \fIcolor\fR
.\" OPTION: -activeforeground
.TP
\fB\-activeforeground \fIcolor\fR
.\" OPTION: -disabledforeground
.TP
\fB\-disabledforeground \fIcolor\fR
.
These options specify the color to use for each of the bitmap's
.QW 1
valued pixels in its normal, active and disabled states.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
.SS "IMAGE ITEMS"
.PP
Items of type \fBimage\fR are used to display images on a
canvas.
1534
1535
1536
1537
1538
1539
1540

1541
1542

1543
1544

1545
1546

1547
1548
1549
1550
1551
1552
1553
The following standard options are supported by images:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for images:

.TP
\fB\-image \fIname\fR

.TP
\fB\-activeimage \fIname\fR

.TP
\fB\-disabledimage \fIname\fR

Specifies the name of the images to display in the item in is normal,
active and disabled states.
This image must have been created previously with the
\fBimage create\fR command.
.SS "LINE ITEMS"
.PP
Items of type \fBline\fR appear on the display as one or more connected







>


>


>


>







1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
The following standard options are supported by images:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for images:
.\" OPTION: -image
.TP
\fB\-image \fIname\fR
.\" OPTION: -activeimage
.TP
\fB\-activeimage \fIname\fR
.\" OPTION: -disabledimage
.TP
\fB\-disabledimage \fIname\fR
.
Specifies the name of the images to display in the item in is normal,
active and disabled states.
This image must have been created previously with the
\fBimage create\fR command.
.SS "LINE ITEMS"
.PP
Items of type \fBline\fR appear on the display as one or more connected
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
\fB\-disabledfill\fR	\fB\-stipple\fR
\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR
\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for lines:

.TP
\fB\-arrow \fIwhere\fR

Indicates whether or not arrowheads are to be drawn at one or both
ends of the line.
\fIWhere\fR must have one of the values \fBnone\fR (for no arrowheads),
\fBfirst\fR (for an arrowhead at the first point of the line),
\fBlast\fR (for an arrowhead at the last point of the line), or
\fBboth\fR (for arrowheads at both ends).
This option defaults to \fBnone\fR.
When requested to draw an arrowhead, Tk internally adjusts the corresponding
line end point so that the rendered line ends at the neck of the arrowhead
rather than at its tip so that the line doesn't extend past the edge of the
arrowhead. This may trigger a \fBLeave\fR event if the mouse is hovering this
line end. Conversely, when removing an arrowhead Tk adjusts the corresponding
line point the other way round, which may trigger an \fBEnter\fR event.

.TP
\fB\-arrowshape \fIshape\fR

This option indicates how to draw arrowheads.
The \fIshape\fR argument must be a list with three elements, each
specifying a distance in any of the forms described in
the \fBCOORDINATES\fR section above.
The first element of the list gives the distance along the line
from the neck of the arrowhead to its tip.
The second element gives the distance along the line from the
trailing points of the arrowhead to the tip, and the third
element gives the distance from the outside edge of the line to the
trailing points.
If this option is not specified then Tk picks a
.QW reasonable
shape.

.TP
\fB\-capstyle \fIstyle\fR

Specifies the ways in which caps are to be drawn at the endpoints
of the line.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetCapStyle\fR
(\fBbutt\fR, \fBprojecting\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBbutt\fR.
Where arrowheads are drawn the cap style is ignored.

.TP
\fB\-joinstyle \fIstyle\fR

Specifies the ways in which joints are to be drawn at the vertices
of the line.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetJoinStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
If the line only contains two points then this option is
irrelevant.

.TP
\fB\-smooth \fIsmoothMethod\fR

\fIsmoothMethod\fR must have one of the forms accepted by
\fBTcl_GetBoolean\fR or a line smoothing method.
Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime. If a boolean

false value or empty string is given, no smoothing is applied. A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the line
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the line
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be generated within a curve by making control points
equal to their neighbouring knot points. If the last point is a
control point and not a knot point, the point is repeated (one or two
times) so that it also becomes a knot point.

.TP
\fB\-splinesteps \fInumber\fR

Specifies the degree of smoothness desired for curves: each spline
will be approximated with \fInumber\fR line segments. This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.SS "OVAL ITEMS"
.PP
Items of type \fBoval\fR appear as circular or oval regions on
the display. Each oval may have an outline, a fill, or







>


>













>


>













>


>






>


>







>


>



|
>
















>


>







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
\fB\-disabledfill\fR	\fB\-stipple\fR
\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR
\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for lines:
.\" OPTION: -arrow
.TP
\fB\-arrow \fIwhere\fR
.
Indicates whether or not arrowheads are to be drawn at one or both
ends of the line.
\fIWhere\fR must have one of the values \fBnone\fR (for no arrowheads),
\fBfirst\fR (for an arrowhead at the first point of the line),
\fBlast\fR (for an arrowhead at the last point of the line), or
\fBboth\fR (for arrowheads at both ends).
This option defaults to \fBnone\fR.
When requested to draw an arrowhead, Tk internally adjusts the corresponding
line end point so that the rendered line ends at the neck of the arrowhead
rather than at its tip so that the line doesn't extend past the edge of the
arrowhead. This may trigger a \fBLeave\fR event if the mouse is hovering this
line end. Conversely, when removing an arrowhead Tk adjusts the corresponding
line point the other way round, which may trigger an \fBEnter\fR event.
.\" OPTION: -arrowshape
.TP
\fB\-arrowshape \fIshape\fR
.
This option indicates how to draw arrowheads.
The \fIshape\fR argument must be a list with three elements, each
specifying a distance in any of the forms described in
the \fBCOORDINATES\fR section above.
The first element of the list gives the distance along the line
from the neck of the arrowhead to its tip.
The second element gives the distance along the line from the
trailing points of the arrowhead to the tip, and the third
element gives the distance from the outside edge of the line to the
trailing points.
If this option is not specified then Tk picks a
.QW reasonable
shape.
.\" OPTION: -capstyle
.TP
\fB\-capstyle \fIstyle\fR
.
Specifies the ways in which caps are to be drawn at the endpoints
of the line.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetCapStyle\fR
(\fBbutt\fR, \fBprojecting\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBbutt\fR.
Where arrowheads are drawn the cap style is ignored.
.\" OPTION: -joinstyle
.TP
\fB\-joinstyle \fIstyle\fR
.
Specifies the ways in which joints are to be drawn at the vertices
of the line.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetJoinStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
If the line only contains two points then this option is
irrelevant.
.\" OPTION: -smooth
.TP
\fB\-smooth \fIsmoothMethod\fR
.
\fIsmoothMethod\fR must have one of the forms accepted by
\fBTcl_GetBoolean\fR or a line smoothing method.
Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR),
but more can be added at runtime. If a boolean
false value or empty string is given, no smoothing is applied. A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the line
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the line
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be generated within a curve by making control points
equal to their neighbouring knot points. If the last point is a
control point and not a knot point, the point is repeated (one or two
times) so that it also becomes a knot point.
.\" OPTION: -splinesteps
.TP
\fB\-splinesteps \fInumber\fR
.
Specifies the degree of smoothness desired for curves: each spline
will be approximated with \fInumber\fR line segments. This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.SS "OVAL ITEMS"
.PP
Items of type \fBoval\fR appear as circular or oval regions on
the display. Each oval may have an outline, a fill, or
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
Polygon items support coordinate indexing operations using the \fBdchars\fR,
\fBindex\fR and \fBinsert\fR widget commands.
Polygons are created with widget commands of the following form:
.CS
\fIpathName \fBcreate polygon \fIx1 y1 ... xn yn \fR?\fIoption value ...\fR?
\fIpathName \fBcreate polygon \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR through \fIyn\fR or \fIcoordList\fR specify the coordinates for
three or more points that define a polygon.
The first point should not be repeated as the last to
close the shape; Tk will automatically close the periphery between
the first and last points.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's







|
|







1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
Polygon items support coordinate indexing operations using the \fBdchars\fR,
\fBindex\fR and \fBinsert\fR widget commands.
Polygons are created with widget commands of the following form:
.CS
\fIpathName \fBcreate polygon \fIx1 y1 ... xn yn \fR?\fIoption value ...\fR?
\fIpathName \fBcreate polygon \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR through \fIyn\fR or \fIcoordList\fR specify the
coordinates for three or more points that define a polygon.
The first point should not be repeated as the last to
close the shape; Tk will automatically close the periphery between
the first and last points.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
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
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR
\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR
\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for polygons:

.TP
\fB\-joinstyle \fIstyle\fR

Specifies the ways in which joints are to be drawn at the vertices
of the outline.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetJoinStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.

.TP
\fB\-smooth \fIboolean\fR

\fIBoolean\fR must have one of the forms accepted by \fBTcl_GetBoolean\fR
or a line smoothing method. Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime. If a boolean

false value or empty string is given, no smoothing is applied. A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the polygon
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the polygon
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be venerated within a curve by making control points
equal to their neighbouring knot points. If the last point is not the
second point of a pair of control points, the point is repeated (one or two
times) so that it also becomes the second point of a pair of control
points (the associated knot point will be the first control point).

.TP
\fB\-splinesteps \fInumber\fR

Specifies the degree of smoothness desired for curves: each spline
will be approximated with \fInumber\fR line segments. This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.PP
Polygon items are different from other items such as rectangles, ovals
and arcs in that interior points are considered to be
.QW inside







>


>





>


>


|
>












|




>


>







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
\fB\-disabledoutlinestipple\fR	\fB\-stipple\fR
\fB\-activestipple\fR	\fB\-disabledstipple\fR
\fB\-state\fR	\fB\-tags\fR
\fB\-width\fR	\fB\-activewidth\fR
\fB\-disabledwidth\fR
.DE
The following extra options are supported for polygons:
.\" OPTION: -joinstyle
.TP
\fB\-joinstyle \fIstyle\fR
.
Specifies the ways in which joints are to be drawn at the vertices
of the outline.
\fIStyle\fR may have any of the forms accepted by \fBTk_GetJoinStyle\fR
(\fBbevel\fR, \fBmiter\fR, or \fBround\fR).
If this option is not specified then it defaults to \fBround\fR.
.\" OPTION: -smooth
.TP
\fB\-smooth \fIboolean\fR
.
\fIBoolean\fR must have one of the forms accepted by \fBTcl_GetBoolean\fR
or a line smoothing method. Only \fBtrue\fR and \fBraw\fR are
supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR),
but more can be added at runtime. If a boolean
false value or empty string is given, no smoothing is applied. A boolean
truth value assumes \fBtrue\fR smoothing.
If the smoothing method is \fBtrue\fR, this indicates that the polygon
should be drawn as a curve, rendered as a set of quadratic splines: one spline
is drawn for the first and second line segments, one for the second
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the polygon
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be generated within a curve by making control points
equal to their neighbouring knot points. If the last point is not the
second point of a pair of control points, the point is repeated (one or two
times) so that it also becomes the second point of a pair of control
points (the associated knot point will be the first control point).
.\" OPTION: -splinesteps
.TP
\fB\-splinesteps \fInumber\fR
.
Specifies the degree of smoothness desired for curves: each spline
will be approximated with \fInumber\fR line segments. This
option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR.
.PP
Polygon items are different from other items such as rectangles, ovals
and arcs in that interior points are considered to be
.QW inside
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
\fB\-anchor\fR	\fB\-fill\fR
\fB\-activefill\fR	\fB\-disabledfill\fR
\fB\-stipple\fR	\fB\-activestipple\fR
\fB\-disabledstipple\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for text items:

.TP
\fB\-angle \fIrotationDegrees\fR
.
\fIRotationDegrees\fR tells how many degrees to rotate the text anticlockwise
about the positioning point for the text; it may have any floating-point value
from 0.0 to 360.0. For example, if \fIrotationDegrees\fR is \fB90\fR, then the
text will be drawn vertically from bottom to top.
This option defaults to \fB0.0\fR.

.TP
\fB\-font \fIfontName\fR

Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.

.TP
\fB\-justify \fIhow\fR

Specifies how to justify the text within its bounding region.
\fIHow\fR must be one of the values \fBleft\fR, \fBright\fR,
or \fBcenter\fR.
This option will only matter if the text is displayed as multiple
lines.
If the option is omitted, it defaults to \fBleft\fR.

.TP
\fB\-text \fIstring\fR

\fIString\fR specifies the characters to be displayed in the text item.
Newline characters cause line breaks.
The characters in the item may also be changed with the
\fBinsert\fR and \fBdelete\fR widget commands.
This option defaults to an empty string.

.TP
\fB\-underline \fI\fR

Specifies the integer index of a character within the text to be
underlined. 0 corresponds to the first character of the text
displayed, 1 to the next character, and so on. \-1 means that no
underline should be drawn (if the whole text item is to be underlined,
the appropriate font should be used instead).

.TP
\fB\-width \fIlineLength\fR

Specifies a maximum line length for the text, in any of the forms
described in the \fBCOORDINATES\fR section above.
If this option is zero (the default) the text is broken into
lines only at newline characters.
However, if this option is non-zero then any line that would
be longer than \fIlineLength\fR is broken just before a space
character to make the line shorter than \fIlineLength\fR; the







>








>


>




>


>






>


>





>

|
>





>


>







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
\fB\-anchor\fR	\fB\-fill\fR
\fB\-activefill\fR	\fB\-disabledfill\fR
\fB\-stipple\fR	\fB\-activestipple\fR
\fB\-disabledstipple\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for text items:
.\" OPTION: -angle
.TP
\fB\-angle \fIrotationDegrees\fR
.
\fIRotationDegrees\fR tells how many degrees to rotate the text anticlockwise
about the positioning point for the text; it may have any floating-point value
from 0.0 to 360.0. For example, if \fIrotationDegrees\fR is \fB90\fR, then the
text will be drawn vertically from bottom to top.
This option defaults to \fB0.0\fR.
.\" OPTION: -font
.TP
\fB\-font \fIfontName\fR
.
Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.
.\" OPTION: -justify
.TP
\fB\-justify \fIhow\fR
.
Specifies how to justify the text within its bounding region.
\fIHow\fR must be one of the values \fBleft\fR, \fBright\fR,
or \fBcenter\fR.
This option will only matter if the text is displayed as multiple
lines.
If the option is omitted, it defaults to \fBleft\fR.
.\" OPTION: -text
.TP
\fB\-text \fIstring\fR
.
\fIString\fR specifies the characters to be displayed in the text item.
Newline characters cause line breaks.
The characters in the item may also be changed with the
\fBinsert\fR and \fBdelete\fR widget commands.
This option defaults to an empty string.
.\" OPTION: -underline
.TP
\fB\-underline \fInumber\fR
.
Specifies the integer index of a character within the text to be
underlined. 0 corresponds to the first character of the text
displayed, 1 to the next character, and so on. \-1 means that no
underline should be drawn (if the whole text item is to be underlined,
the appropriate font should be used instead).
.\" OPTION: -width
.TP
\fB\-width \fIlineLength\fR
.
Specifies a maximum line length for the text, in any of the forms
described in the \fBCOORDINATES\fR section above.
If this option is zero (the default) the text is broken into
lines only at newline characters.
However, if this option is non-zero then any line that would
be longer than \fIlineLength\fR is broken just before a space
character to make the line shorter than \fIlineLength\fR; the
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
The following standard options are supported by window items:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for window items:

.TP
\fB\-height \fIpixels\fR
.
Specifies the height to assign to the item's window.
\fIPixels\fR may have any of the
forms described in the \fBCOORDINATES\fR section above.
If this option is not specified, or if it is specified as zero,
then the window is given whatever height it requests internally.

.TP
\fB\-width \fIpixels\fR
.
Specifies the width to assign to the item's window.
\fIPixels\fR may have any of the
forms described in the \fBCOORDINATES\fR section above.
If this option is not specified, or if it is specified as zero,
then the window is given whatever width it requests internally.

.TP
\fB\-window \fIpathName\fR
.
Specifies the window to associate with this item.
The window specified by \fIpathName\fR must either be a child of
the canvas widget or a child of some ancestor of the canvas widget.
\fIPathName\fR may not refer to a top-level window.
.PP
Note: due to restrictions in the ways that windows are managed, it is not
possible to draw other graphical items (such as lines and images) on top
of window items. A window item always obscures any graphics that
overlap it, regardless of their order in the display list. Also note that
window items, unlike other canvas items, are not clipped for display by their
containing canvas's border, and are instead clipped by the parent widget of
the window specified by the \fB\-window\fR option; when the parent widget is
the canvas, this means that the window item can overlap the canvas's border.







>








>








>








|







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
The following standard options are supported by window items:
.DS
.ta 3i
\fB\-anchor\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for window items:
.\" OPTION: -height
.TP
\fB\-height \fIpixels\fR
.
Specifies the height to assign to the item's window.
\fIPixels\fR may have any of the
forms described in the \fBCOORDINATES\fR section above.
If this option is not specified, or if it is specified as zero,
then the window is given whatever height it requests internally.
.\" OPTION: -width
.TP
\fB\-width \fIpixels\fR
.
Specifies the width to assign to the item's window.
\fIPixels\fR may have any of the
forms described in the \fBCOORDINATES\fR section above.
If this option is not specified, or if it is specified as zero,
then the window is given whatever width it requests internally.
.\" OPTION: -window
.TP
\fB\-window \fIpathName\fR
.
Specifies the window to associate with this item.
The window specified by \fIpathName\fR must either be a child of
the canvas widget or a child of some ancestor of the canvas widget.
\fIPathName\fR may not refer to a top-level window.
.PP
Note that, due to restrictions in the ways that windows are managed, it is not
possible to draw other graphical items (such as lines and images) on top
of window items. A window item always obscures any graphics that
overlap it, regardless of their order in the display list. Also note that
window items, unlike other canvas items, are not clipped for display by their
containing canvas's border, and are instead clipped by the parent widget of
the window specified by the \fB\-window\fR option; when the parent widget is
the canvas, this means that the window item can overlap the canvas's border.

Changes to doc/checkbutton.n.

193
194
195
196
197
198
199

200
201

202
203
204
205

206
207

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

220
221

222
223
224

225
226

227
228
229
230
231

232
233

234
235
236
237
238
239

240
241

242
243
244

245
246

247
248
249
250
251
252
253
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBcheckbutton\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBcheckbutton\fR
command.

.TP
\fIpathName \fBdeselect\fR

Deselects the checkbutton and sets the associated variable to its
.QW off
value.

.TP
\fIpathName \fBflash\fR

Flashes the checkbutton.  This is accomplished by redisplaying the checkbutton
several times, alternating between active and normal colors.  At
the end of the flash the checkbutton is left in the same normal/active
state as when the command was invoked.
This command is ignored if the checkbutton's state is \fBdisabled\fR.

.TP
\fIpathName \fBinvoke\fR

Does just what would have happened if the user invoked the checkbutton
with the mouse: toggle the selection state of the button and invoke
the Tcl command associated with the checkbutton, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the checkbutton.
This command is ignored if the checkbutton's state is \fBdisabled\fR.

.TP
\fIpathName \fBselect\fR

Selects the checkbutton and sets the associated variable to its
.QW on
value.

.TP
\fIpathName \fBtoggle\fR

Toggles the selection state of the button, redisplaying it and
modifying its associated variable to reflect the new state.
.SH BINDINGS
.PP
Tk automatically creates class bindings for checkbuttons that give them
the following default behavior:
.IP [1]







>

|
>




>


>












>


>



>


>





>


>






>


>



>


>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBcheckbutton\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBcheckbutton\fR
command.
.\" METHOD: deselect
.TP
\fIpathName \fBdeselect\fR
.
Deselects the checkbutton and sets the associated variable to its
.QW off
value.
.\" METHOD: flash
.TP
\fIpathName \fBflash\fR
.
Flashes the checkbutton.  This is accomplished by redisplaying the checkbutton
several times, alternating between active and normal colors.  At
the end of the flash the checkbutton is left in the same normal/active
state as when the command was invoked.
This command is ignored if the checkbutton's state is \fBdisabled\fR.
.\" METHOD: invoke
.TP
\fIpathName \fBinvoke\fR
.
Does just what would have happened if the user invoked the checkbutton
with the mouse: toggle the selection state of the button and invoke
the Tcl command associated with the checkbutton, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the checkbutton.
This command is ignored if the checkbutton's state is \fBdisabled\fR.
.\" METHOD: select
.TP
\fIpathName \fBselect\fR
.
Selects the checkbutton and sets the associated variable to its
.QW on
value.
.\" METHOD: toggle
.TP
\fIpathName \fBtoggle\fR
.
Toggles the selection state of the button, redisplaying it and
modifying its associated variable to reflect the new state.
.SH BINDINGS
.PP
Tk automatically creates class bindings for checkbuttons that give them
the following default behavior:
.IP [1]
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
The behavior of checkbuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH EXAMPLE
.PP
This example shows a group of uncoupled checkbuttons.
.PP
.CS
labelframe .lbl \-text "Steps:"
\fBcheckbutton\fR .c1 \-text Lights  \-variable lights
\fBcheckbutton\fR .c2 \-text Cameras \-variable cameras
\fBcheckbutton\fR .c3 \-text Action! \-variable action
pack .c1 .c2 .c3 \-in .lbl
pack .lbl
.CE
.SH "SEE ALSO"
button(n), options(n), radiobutton(n), ttk::checkbutton(n)
.SH KEYWORDS
checkbutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|
|
|









287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
The behavior of checkbuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH EXAMPLE
.PP
This example shows a group of uncoupled checkbuttons.
.PP
.CS
labelframe .lbl -text "Steps:"
\fBcheckbutton\fR .c1 -text Lights  -variable lights
\fBcheckbutton\fR .c2 -text Cameras -variable cameras
\fBcheckbutton\fR .c3 -text Action! -variable action
pack .c1 .c2 .c3 -in .lbl
pack .lbl
.CE
.SH "SEE ALSO"
button(n), options(n), radiobutton(n), ttk::checkbutton(n)
.SH KEYWORDS
checkbutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/chooseColor.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
48
\fBtk_chooseColor \fR?\fIoption value ...\fR?
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseColor\fR pops up a dialog box for the
user to select a color. The following \fIoption\-value\fR pairs are
possible as command line arguments:

.TP
\fB\-initialcolor\fR \fIcolor\fR

Specifies the color to display in the color dialog when it pops
up. \fIcolor\fR must be in a form acceptable to the \fBTk_GetColor\fR
function.

.TP
\fB\-parent\fR \fIwindow\fR

Makes \fIwindow\fR the logical parent of the color dialog. The color
dialog is displayed on top of its parent window.

.TP
\fB\-title\fR \fItitleString\fR

Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title will be displayed.
.LP
If the user selects a color, \fBtk_chooseColor\fR will return the
name of the color in a form acceptable to \fBTk_GetColor\fR.  If the
user cancels the operation, both commands will return the empty
string.
.SH EXAMPLE
.PP
.CS
button .b \-bg [tk_chooseColor \-initialcolor gray \-title "Choose color"]
.CE
.SH KEYWORDS
color, color selection, dialog
'\" Local Variables:
'\" mode: nroff
'\" End:







>

|
>



>

|
>


>

|
>










|






14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
\fBtk_chooseColor \fR?\fIoption value ...\fR?
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseColor\fR pops up a dialog box for the
user to select a color. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.\" OPTION: -initialcolor
.TP
\fB\-initialcolor\fI color\fR
.
Specifies the color to display in the color dialog when it pops
up. \fIcolor\fR must be in a form acceptable to the \fBTk_GetColor\fR
function.
.\" OPTION: -parent
.TP
\fB\-parent\fI window\fR
.
Makes \fIwindow\fR the logical parent of the color dialog. The color
dialog is displayed on top of its parent window.
.\" OPTION: -title
.TP
\fB\-title\fI titleString\fR
.
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title will be displayed.
.LP
If the user selects a color, \fBtk_chooseColor\fR will return the
name of the color in a form acceptable to \fBTk_GetColor\fR.  If the
user cancels the operation, both commands will return the empty
string.
.SH EXAMPLE
.PP
.CS
button .b -bg [tk_chooseColor -initialcolor gray -title "Choose color"]
.CE
.SH KEYWORDS
color, color selection, dialog
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/chooseDirectory.n.

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

19
20

21
22
23
24
25

26
27

28
29
30
31
32
33
34
35

36
37

38
39

40
41

42
43
44

45
46

47
48
49

50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH tk_chooseDirectory n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_chooseDirectory \- pops up a dialog box for the user to select a directory.
.SH SYNOPSIS
\fBtk_chooseDirectory \fR?\fIoption value ...\fR?
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseDirectory\fR pops up a dialog box for the
user to select a directory. The following \fIoption\-value\fR pairs are
possible as command line arguments:

.TP
\fB\-command\fR \fIstring\fR

Specifies the prefix of a Tcl command to invoke when the user closes the
dialog after having selected an item. This callback is not called if the
user cancelled the dialog. The actual command consists of \fIstring\fR
followed by a space and the value selected by the user in the dialog. This
is only available on Mac OS X.

.TP
\fB\-initialdir\fR \fIdirname\fR

Specifies that the directories in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
the initial directory defaults to the current working directory
on non-Windows systems and on Windows systems prior to Vista.
On Vista and later systems, the initial directory defaults to the last
user-selected directory for the application. If the
parameter specifies a relative path, the return value will convert the
relative path to an absolute path.

.TP
\fB\-message\fR \fIstring\fR

Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.

.TP
\fB\-mustexist\fR \fIboolean\fR

Specifies whether the user may specify non-existent directories.  If
this parameter is true, then the user may only select directories that
already exist.  The default value is \fIfalse\fR.

.TP
\fB\-parent\fR \fIwindow\fR

Makes \fIwindow\fR the logical parent of the dialog. The dialog
is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.

.TP
\fB\-title\fR \fItitleString\fR

Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title will be displayed.
.SH EXAMPLE
.PP
.CS
set dir [\fBtk_chooseDirectory\fR \e
        \-initialdir ~ \-title "Choose a directory"]
if {$dir eq ""} {
   label .l \-text "No directory selected"
} else {
   label .l \-text "Selected $dir"
}
.CE
.SH "SEE ALSO"
tk_getOpenFile(n), tk_getSaveFile(n)
.SH KEYWORDS
directory, selection, dialog, platform-specific
'\" Local Variables:
'\" mode: nroff
'\" End:

|
















>

|
>





>

|
>








>

|
>


>

|
>



>

|
>



>

|
>






|

|

|









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'\"
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\" All rights reserved.
'\"
.TH tk_chooseDirectory n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_chooseDirectory \- pops up a dialog box for the user to select a directory.
.SH SYNOPSIS
\fBtk_chooseDirectory \fR?\fIoption value ...\fR?
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseDirectory\fR pops up a dialog box for the
user to select a directory. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.\" OPTION: -command
.TP
\fB\-command\fI string\fR
.
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog after having selected an item. This callback is not called if the
user cancelled the dialog. The actual command consists of \fIstring\fR
followed by a space and the value selected by the user in the dialog. This
is only available on Mac OS X.
.\" OPTION: -initialdir
.TP
\fB\-initialdir\fI dirname\fR
.
Specifies that the directories in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
the initial directory defaults to the current working directory
on non-Windows systems and on Windows systems prior to Vista.
On Vista and later systems, the initial directory defaults to the last
user-selected directory for the application. If the
parameter specifies a relative path, the return value will convert the
relative path to an absolute path.
.\" OPTION: -message
.TP
\fB\-message\fI string\fR
.
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
.\" OPTION: -mustexist
.TP
\fB\-mustexist\fI boolean\fR
.
Specifies whether the user may specify non-existent directories.  If
this parameter is true, then the user may only select directories that
already exist.  The default value is \fIfalse\fR.
.\" OPTION: -parent
.TP
\fB\-parent\fI window\fR
.
Makes \fIwindow\fR the logical parent of the dialog. The dialog
is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.
.\" OPTION: -title
.TP
\fB\-title\fI titleString\fR
.
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title will be displayed.
.SH EXAMPLE
.PP
.CS
set dir [\fBtk_chooseDirectory\fR \e
        -initialdir ~ -title "Choose a directory"]
if {$dir eq ""} {
   label .l -text "No directory selected"
} else {
   label .l -text "Selected $dir"
}
.CE
.SH "SEE ALSO"
tk_getOpenFile(n), tk_getSaveFile(n)
.SH KEYWORDS
directory, selection, dialog, platform-specific
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/clipboard.n.

23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
be called, followed by a sequence of one or more calls to \fBclipboard
append\fR.  To ensure that the clipboard is updated atomically, all
appends should be completed before returning to the event loop.
.PP
The first argument to \fBclipboard\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:

.TP
\fBclipboard append\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-format\fR \fIformat\fR? ?\fB\-type\fR \fItype\fR? ?\fB\-\|\-\fR? \fIdata\fR
.
Appends \fIdata\fR to the clipboard on \fIwindow\fR's
display in the form given by \fItype\fR with the representation given
by \fIformat\fR and claims ownership of the clipboard on \fIwindow\fR's
display.
.RS
.PP







>

|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
be called, followed by a sequence of one or more calls to \fBclipboard
append\fR.  To ensure that the clipboard is updated atomically, all
appends should be completed before returning to the event loop.
.PP
The first argument to \fBclipboard\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:
.\" METHOD: append
.TP
\fBclipboard append\fR ?\fB\-displayof\fI window\fR? ?\fB\-format\fI format\fR? ?\fB\-type\fI type\fR? ?\fB\-\|\-\fR? \fIdata\fR
.
Appends \fIdata\fR to the clipboard on \fIwindow\fR's
display in the form given by \fItype\fR with the representation given
by \fIformat\fR and claims ownership of the clipboard on \fIwindow\fR's
display.
.RS
.PP
67
68
69
70
71
72
73

74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
irrelevant.
.PP
A \fB\-\|\-\fR argument may be specified to mark the end of options:  the
next argument will always be used as \fIdata\fR.
This feature may be convenient if, for example, \fIdata\fR starts
with a \fB\-\fR.
.RE

.TP
\fBclipboard clear\fR ?\fB\-displayof\fR \fIwindow\fR?
.
Claims ownership of the clipboard on \fIwindow\fR's display and removes
any previous contents.  \fIWindow\fR defaults to
.QW . .
Returns an empty string.

.TP
\fBclipboard get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-type\fR \fItype\fR?
.
Retrieve data from the clipboard on \fIwindow\fR's display.
\fIWindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which
the data is to be returned and should be an atom name such as \fBSTRING\fR
or \fBFILE_NAME\fR.  \fIType\fR defaults to \fBSTRING\fR.  This command is







>

|





>

|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
irrelevant.
.PP
A \fB\-\|\-\fR argument may be specified to mark the end of options:  the
next argument will always be used as \fIdata\fR.
This feature may be convenient if, for example, \fIdata\fR starts
with a \fB\-\fR.
.RE
.\" METHOD: clear
.TP
\fBclipboard clear\fR ?\fB\-displayof\fI window\fR?
.
Claims ownership of the clipboard on \fIwindow\fR's display and removes
any previous contents.  \fIWindow\fR defaults to
.QW . .
Returns an empty string.
.\" METHOD: get
.TP
\fBclipboard get\fR ?\fB\-displayof\fI window\fR? ?\fB\-type\fI type\fR?
.
Retrieve data from the clipboard on \fIwindow\fR's display.
\fIWindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which
the data is to be returned and should be an atom name such as \fBSTRING\fR
or \fBFILE_NAME\fR.  \fIType\fR defaults to \fBSTRING\fR.  This command is
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# it produces a script that recreates the item(s) when executed
proc getItemConfig {canvas tag} {
   set script {}
   foreach item [$canvas find withtag $tag] {
      append script {$canvas create } [$canvas type $item]
      append script { } [$canvas coords $item] { }
      foreach config [$canvas itemconf $item] {
         lassign $config name \- \- \- value
         append script [list $name $value] { }
      }
      append script \en
   }
   return [string trim $script]
}

# Set up a binding on a canvas to cut and paste an item
set c [canvas .c]
pack $c
$c create text 150 30 \-text "cut and paste me"
bind $c <<Cut>> {
   \fBclipboard clear\fR
   \fBclipboard append \-type\fR TkCanvasItem \e
         [getItemConfig %W current]
   # Delete because this is cut, not copy.
   %W delete current
}
bind $c <<Paste>> {
   catch {
      set canvas %W
      eval [\fBclipboard get \-type\fR TkCanvasItem]
   }
}
.CE
.SH "SEE ALSO"
interp(n), selection(n)
.SH KEYWORDS
clear, format, clipboard, append, selection, type
'\" Local Variables:
'\" mode: nroff
'\" End:







|










|


|







|










121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# it produces a script that recreates the item(s) when executed
proc getItemConfig {canvas tag} {
   set script {}
   foreach item [$canvas find withtag $tag] {
      append script {$canvas create } [$canvas type $item]
      append script { } [$canvas coords $item] { }
      foreach config [$canvas itemconf $item] {
         lassign $config name - - - value
         append script [list $name $value] { }
      }
      append script \en
   }
   return [string trim $script]
}

# Set up a binding on a canvas to cut and paste an item
set c [canvas .c]
pack $c
$c create text 150 30 -text "cut and paste me"
bind $c <<Cut>> {
   \fBclipboard clear\fR
   \fBclipboard append -type\fR TkCanvasItem \e
         [getItemConfig %W current]
   # Delete because this is cut, not copy.
   %W delete current
}
bind $c <<Paste>> {
   catch {
      set canvas %W
      eval [\fBclipboard get -type\fR TkCanvasItem]
   }
}
.CE
.SH "SEE ALSO"
interp(n), selection(n)
.SH KEYWORDS
clear, format, clipboard, append, selection, type
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/colors.n.

1
2
3
4
5
6
7
8
9
'\"
'\" Copyright (c) 1998-2000 by 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

|







1
2
3
4
5
6
7
8
9
'\"
'\" 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
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
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







|














<







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
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 contrasts
with its predecessor.
.RS
.DS
systemWindowBackgroundColor
systemWindowBackgroundColor1
systemWindowBackgroundColor2
systemWindowBackgroundColor3
systemWindowBackgroundColor4
systemWindowBackgroundColor5
systemWindowBackgroundColor6
systemWindowBackgroundColor7
.DE
.RE
.TP

\fBWindows\fR
.
On Windows, the following additional system colors are available
(note that the actual color values depend on the currently active OS theme):
.RS
.DS
.ta 6c

Changes to doc/console.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34

35
36

37
38
39

40
41

42
43

44
45

46
47

48
49

50
51
52
53
54
55
56
57
58
59
60

61
62

63
64

65
66

67
68
69
70
71
72
73
'\"
'\" Copyright (c) 2001 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH console n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
console \- Control the console on systems without a real console
.SH SYNOPSIS
\fBconsole\fR \fIsubcommand\fR ?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The console window is a replacement for a real console to allow input
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" ,
as a conventional terminal is expected to be present in that case.
In TkAqua, this command is disabled when there is a startup script
and stdin is \fB/dev/null\fR (as is the case e.g. when a bundled application
embedding Tk is started by the macOS Launcher).  To enable the command
in that case, define the environment variable \fBTK_CONSOLE\fR.  This can be
done by modifying the Info.plist file by adding the LSEnvironment key
to the main dict and setting its value to be a dict with the key \fBTK_CONSOLE\fR.

.PP

.TP
\fBconsole eval \fIscript\fR

Evaluate the \fIscript\fR argument as a Tcl script in the console
interpreter.  The normal interpreter is accessed through the
\fBconsoleinterp\fR command in the console interpreter.

.TP
\fBconsole hide\fR

Hide the console window from view.  Precisely equivalent to
withdrawing the \fB.\fR window in the console interpreter.

.TP
\fBconsole show\fR

Display the console window.  Precisely equivalent to deiconifying the
\fB.\fR window in the console interpreter.

.TP
\fBconsole title \fR?\fIstring\fR?

Query or modify the title of the console window.  If \fIstring\fR is
not specified, queries the title of the console window, and sets the
title of the console window to \fIstring\fR otherwise.  Precisely
equivalent to using the \fBwm title\fR command in the console
interpreter.
.SH "ACCESS TO THE MAIN INTERPRETER"
.PP
The \fBconsoleinterp\fR command in the console interpreter allows
scripts to be evaluated in the main interpreter.  It supports two
subcommands: \fBeval\fR and \fBrecord\fR.
.PP

.TP
\fBconsoleinterp eval \fIscript\fR

Evaluates \fIscript\fR as a Tcl script at the global level in the main
interpreter.

.TP
\fBconsoleinterp record \fIscript\fR

Records and evaluates \fIscript\fR as a Tcl script at the global level
in the main interpreter as if \fIscript\fR had been typed in at the
console.
.SH "ADDITIONAL TRAP CALLS"
.PP
There are several additional commands in the console interpreter that
are called in response to activity in the main interpreter.













|


















|
>

>


>



>


>


>


>


>


>











>


>


>


>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'\"
'\" Copyright (c) 2001 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH console n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
console \- Control the console on systems without a real console
.SH SYNOPSIS
\fBconsole\fI subcommand\fR ?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The console window is a replacement for a real console to allow input
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" ,
as a conventional terminal is expected to be present in that case.
In TkAqua, this command is disabled when there is a startup script
and stdin is \fB/dev/null\fR (as is the case e.g. when a bundled application
embedding Tk is started by the macOS Launcher).  To enable the command
in that case, define the environment variable \fBTK_CONSOLE\fR.  This can be
done by modifying the Info.plist file by adding the LSEnvironment key
to the main dict and setting its value to be a dict with the key
\fBTK_CONSOLE\fR.
.PP
.\" METHOD: eval
.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.
.\" METHOD: hide
.TP
\fBconsole hide\fR
.
Hide the console window from view.  Precisely equivalent to
withdrawing the \fB.\fR window in the console interpreter.
.\" METHOD: show
.TP
\fBconsole show\fR
.
Display the console window.  Precisely equivalent to deiconifying the
\fB.\fR window in the console interpreter.
.\" METHOD: title
.TP
\fBconsole title \fR?\fIstring\fR?
.
Query or modify the title of the console window.  If \fIstring\fR is
not specified, queries the title of the console window, and sets the
title of the console window to \fIstring\fR otherwise.  Precisely
equivalent to using the \fBwm title\fR command in the console
interpreter.
.SH "ACCESS TO THE MAIN INTERPRETER"
.PP
The \fBconsoleinterp\fR command in the console interpreter allows
scripts to be evaluated in the main interpreter.  It supports two
subcommands: \fBeval\fR and \fBrecord\fR.
.PP
.\" METHOD: eval
.TP
\fBconsoleinterp eval \fIscript\fR
.
Evaluates \fIscript\fR as a Tcl script at the global level in the main
interpreter.
.\" METHOD: record
.TP
\fBconsoleinterp record \fIscript\fR
.
Records and evaluates \fIscript\fR as a Tcl script at the global level
in the main interpreter as if \fIscript\fR had been typed in at the
console.
.SH "ADDITIONAL TRAP CALLS"
.PP
There are several additional commands in the console interpreter that
are called in response to activity in the main interpreter.

Changes to doc/cursors.n.

1
2
3
4
5
6
7
8
9
'\"
'\" Copyright (c) 1998-2000 by 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

|







1
2
3
4
5
6
7
8
9
'\"
'\" 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
97
98
99
100
101
102
103

104
105
106
107
108
109
110
xterm
.CE
.PP
The \fBnone\fR cursor can be specified to eliminate the cursor.
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR

On Windows systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
center_ptr
crosshair
fleur







>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
xterm
.CE
.PP
The \fBnone\fR cursor can be specified to eliminate the cursor.
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR
.
On Windows systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
center_ptr
crosshair
fleur
127
128
129
130
131
132
133

134
135
136
137
138
139
140
size_we
uparrow
wait
.CE
.RE
.TP
\fBMac OS X\fR

On Mac OS X systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
top_left_arrow
left_ptr
cross







>







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
size_we
uparrow
wait
.CE
.RE
.TP
\fBMac OS X\fR
.
On Mac OS X systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
top_left_arrow
left_ptr
cross

Changes to doc/dialog.n.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
\fBtk_dialog \fIwindow title text bitmap default string string ...\fR
.BE
.SH DESCRIPTION
.PP
This procedure is part of the Tk script library.
It is largely \fIdeprecated\fR by the \fBtk_messageBox\fR.
Its arguments describe a dialog box:
.TP
\fIwindow\fR
Name of top-level window to use for dialog.  Any existing window
by this name is destroyed.
.TP
\fItitle\fR
Text to appear in the window manager's title bar for the dialog.
.TP
\fItext\fR
Message to appear in the top portion of the dialog box.
.TP
\fIbitmap\fR
If non-empty, specifies a bitmap (in a form suitable for Tk_GetBitmap)
to display in the top portion of
the dialog, to the left of the text.
If this is an empty string then no bitmap is displayed in the dialog.
.TP
\fIdefault\fR
If this is an integer greater than or equal to zero, then it gives
the index of the button that is to be the default button for the dialog
(0 for the leftmost button, and so on).
If less than zero or an empty string then there will not be any default
button.
.TP
\fIstring\fR
There will be one button for each of these arguments.
Each \fIstring\fR specifies text to display in a button,
in order from left to right.
.PP
After creating a dialog box, \fBtk_dialog\fR waits for the user to
select one of the buttons either by clicking on the button with the
mouse or by typing return to invoke the default button (if any).







<
|


<
|

<
|

<
|




<
|





<
|







15
16
17
18
19
20
21

22
23
24

25
26

27
28

29
30
31
32
33

34
35
36
37
38
39

40
41
42
43
44
45
46
47
\fBtk_dialog \fIwindow title text bitmap default string string ...\fR
.BE
.SH DESCRIPTION
.PP
This procedure is part of the Tk script library.
It is largely \fIdeprecated\fR by the \fBtk_messageBox\fR.
Its arguments describe a dialog box:

.IP \fIwindow\fR
Name of top-level window to use for dialog.  Any existing window
by this name is destroyed.

.IP \fItitle\fR
Text to appear in the window manager's title bar for the dialog.

.IP \fItext\fR
Message to appear in the top portion of the dialog box.

.IP \fIbitmap\fR
If non-empty, specifies a bitmap (in a form suitable for Tk_GetBitmap)
to display in the top portion of
the dialog, to the left of the text.
If this is an empty string then no bitmap is displayed in the dialog.

.IP \fIdefault\fR
If this is an integer greater than or equal to zero, then it gives
the index of the button that is to be the default button for the dialog
(0 for the leftmost button, and so on).
If less than zero or an empty string then there will not be any default
button.

.IP \fIstring\fR
There will be one button for each of these arguments.
Each \fIstring\fR specifies text to display in a button,
in order from left to right.
.PP
After creating a dialog box, \fBtk_dialog\fR waits for the user to
select one of the buttons either by clicking on the button with the
mouse or by typing return to invoke the default button (if any).

Changes to doc/entry.n.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.TH entry n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
entry \- Create and manipulate 'entry' one-line text entry widgets
.SH SYNOPSIS
\fBentry\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-highlightthickness	\-selectbackground
\-borderwidth	\-insertbackground	\-selectborderwidth
\-cursor	\-insertborderwidth	\-selectforeground
\-exportselection	\-insertofftime	\-takefocus
\-font	\-insertontime	\-textvariable
\-foreground	\-insertwidth	\-xscrollcommand







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.TH entry n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
entry \- Create and manipulate 'entry' one-line text entry widgets
.SH SYNOPSIS
\fBentry\fI pathName \fR?\fIoptions\fR?
.SO
\-background	\-highlightthickness	\-selectbackground
\-borderwidth	\-insertbackground	\-selectborderwidth
\-cursor	\-insertborderwidth	\-selectforeground
\-exportselection	\-insertofftime	\-takefocus
\-font	\-insertontime	\-textvariable
\-foreground	\-insertwidth	\-xscrollcommand
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
\fB\-invalidcommand\fR encounters an error in its script while evaluating or
\fB\-validatecommand\fR does not return a valid Tcl boolean value.  The
\fB\-validate\fR option will also set itself to \fBnone\fR when you edit the
entry widget from within either the \fB\-validatecommand\fR or the
\fB\-invalidcommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the entry widget (for example set it to {})
during validation and still have the \fB\-validate\fR option set, you should
include the command
.CS
after idle {%W config \-validate %v}
.CE
in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you
were editing the entry widget from).  It is also recommended to not set an
associated \fB\-textvariable\fR during validation, as that can cause the
entry widget to become out of sync with the \fB\-textvariable\fR.
.SH "WIDGET COMMAND"
.PP







|

|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
\fB\-invalidcommand\fR encounters an error in its script while evaluating or
\fB\-validatecommand\fR does not return a valid Tcl boolean value.  The
\fB\-validate\fR option will also set itself to \fBnone\fR when you edit the
entry widget from within either the \fB\-validatecommand\fR or the
\fB\-invalidcommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the entry widget (for example set it to {})
during validation and still have the \fB\-validate\fR option set, you should
include the command:
.CS
after idle {%W config -validate %v}
.CE
in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you
were editing the entry widget from).  It is also recommended to not set an
associated \fB\-textvariable\fR during validation, as that can cause the
entry widget to become out of sync with the \fB\-textvariable\fR.
.SH "WIDGET COMMAND"
.PP
197
198
199
200
201
202
203

204
205
206
207

208
209
210
211

212
213
214
215
216

217
218
219
220

221
222
223
224

225
226
227
228
229

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



242
243
244

245
246

247
248
249
250
251
252
253
254

255
256

257
258
259
260

261
262

263
264
265
266
267
268
269
270
271
272
273
274

275
276

277
278
279
280
281
282
283

284
285

286

287
288

289
290

291
292

293

294
295

296
297

298
299

300
301
302
303
304

305
306
307
308
309
310

311
312
313
314
315
316
317
318

319
320

321
322
323
324
325

326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341

342
343
344
345
346

347
348
349
350

351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370

371
372

373
374
375
376

377
378

379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394

395
396
397
398

399
400
401
402
403

404
405
406
407
408
409
410
.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
string, in any of the following ways:
.TP 12
\fInumber\fR

Specifies the character as a numerical index, where 0 corresponds
to the first character in the string.
.TP 12
\fBanchor\fR

Indicates the anchor point for the selection, which is set with the
\fBselect from\fR and \fBselect adjust\fR widget commands.
.TP 12
\fBend\fR

Indicates the character just after the last one in the entry's string.
This is equivalent to specifying a numerical index equal to the length
of the entry's string.
.TP 12
\fBinsert\fR

Indicates the character adjacent to and immediately following the
insertion cursor.
.TP 12
\fBsel.first\fR

Indicates the first character in the selection.  It is an error to
use this form if the selection is not in the entry window.
.TP 12
\fBsel.last\fR

Indicates the character just after the last one in the selection.
It is an error to use this form if the selection is not in the
entry window.
.TP 12
\fB@\fInumber\fR

In this form, \fInumber\fR is treated as an x-coordinate in the
entry's window;  the character spanning that x-coordinate is used.
For example,
.QW \fB@0\fR
indicates the left-most character in the window.
.LP
Abbreviations may be used for any of the forms above, e.g.
.QW \fBe\fR
or
.QW \fBsel.f\fR .
In general, out-of-range indices are automatically rounded to the
nearest legal value.



.SS SUBCOMMANDS
.PP
The following commands are possible for entry widgets:

.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 configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBentry\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBentry\fR
command.

.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 an empty string.

.TP
\fIpathName \fBget\fR

Returns the entry's string.

.TP
\fIpathName \fBicursor \fIindex\fR

Arrange for the insertion cursor to be displayed just before the character
given by \fIindex\fR.  Returns an empty string.

.TP
\fIpathName \fBindex\fI index\fR

Returns the numerical index corresponding to \fIindex\fR.

.TP
\fIpathName \fBinsert \fIindex string\fR

Insert the characters of \fIstring\fR just before the character
indicated by \fIindex\fR.  Returns an empty string.

.TP
\fIpathName \fBscan\fR \fIoption args\fR

This command is used to implement scanning on entries.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx\fR

Records \fIx\fR and the current view in the entry window;  used in
conjunction with later \fBscan dragto\fR commands.  Typically this
command is associated with a mouse button press in the widget.  It
returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx\fR

This command computes the difference between its \fIx\fR argument
and the \fIx\fR argument to the last \fBscan mark\fR command for
the widget.  It then adjusts the view left or right by 10 times the
difference in x-coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the entry at high speed through the window.  The return
value is an empty string.
.RE

.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 adjust \fIindex\fR

Locate the end of the selection nearest to the character given by
\fIindex\fR, and adjust that end of the selection to be at \fIindex\fR
(i.e. including but not going beyond \fIindex\fR).  The other
end of the selection is made the anchor point for future
\fBselect to\fR commands.  If the selection
is not currently in the entry, then a new selection is created to
include the characters between \fIindex\fR and the most recent
selection anchor point, inclusive.
Returns an empty string.
.TP
\fIpathName \fBselection clear\fR

Clear the selection if it is currently in this widget.  If the
selection is not in this widget then the command has no effect.
Returns an empty string.
.TP
\fIpathName \fBselection from \fIindex\fR

Set the selection anchor point to just before the character
given by \fIindex\fR.  Does not change the selection.
Returns an empty string.
.TP
\fIpathName \fBselection present\fR

Returns 1 if there is are characters selected in the entry,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart\fR \fIend\fR

Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the entry's selection is cleared.
.TP
\fIpathName \fBselection to \fIindex\fR

If \fIindex\fR is before the anchor point, set the selection
to the characters from \fIindex\fR up to but not including
the anchor point.
If \fIindex\fR is the same as the anchor point, do nothing.
If \fIindex\fR is after the anchor point, set the selection
to the characters from the anchor point up to but not including
\fIindex\fR.
The anchor point is determined by the most recent \fBselect from\fR
or \fBselect adjust\fR command in this widget.
If the selection is not in this widget then a new selection is
created using the most recent anchor point specified for the widget.
Returns an empty string.
.RE

.TP
\fIpathName \fBvalidate\fR

This command is used to force an evaluation of the \fB\-validatecommand\fR
independent of the conditions specified by the \fB\-validate\fR option.
This is done by temporarily setting the \fB\-validate\fR option to \fBall\fR.
It returns 0 or 1.

.TP
\fIpathName \fBxview \fIargs\fR

This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the entry's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR

Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer 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.







>




>




>





>




>




>





>












>
>
>



>


>








>

|
>




>


>












>


>







>


>

>


>


>


>

>


>


>

|
>





>






>








>


>





>











>





>





>



|
>







>













>


>




>


>






>









|
>




>





>







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
.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
string, in any of the following ways:
.TP 12
\fInumber\fR
.
Specifies the character as a numerical index, where 0 corresponds
to the first character in the string.
.TP 12
\fBanchor\fR
.
Indicates the anchor point for the selection, which is set with the
\fBselect from\fR and \fBselect adjust\fR widget commands.
.TP 12
\fBend\fR
.
Indicates the character just after the last one in the entry's string.
This is equivalent to specifying a numerical index equal to the length
of the entry's string.
.TP 12
\fBinsert\fR
.
Indicates the character adjacent to and immediately following the
insertion cursor.
.TP 12
\fBsel.first\fR
.
Indicates the first character in the selection.  It is an error to
use this form if the selection is not in the entry window.
.TP 12
\fBsel.last\fR
.
Indicates the character just after the last one in the selection.
It is an error to use this form if the selection is not in the
entry window.
.TP 12
\fB@\fInumber\fR
.
In this form, \fInumber\fR is treated as an x-coordinate in the
entry's window;  the character spanning that x-coordinate is used.
For example,
.QW \fB@0\fR
indicates the left-most character in the window.
.LP
Abbreviations may be used for any of the forms above, e.g.
.QW \fBe\fR
or
.QW \fBsel.f\fR .
In general, out-of-range indices are automatically rounded to the
nearest legal value.
Indexes support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\fR.
.SS SUBCOMMANDS
.PP
The following commands are possible for entry widgets:
.\" METHOD: bbox
.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.
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBentry\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBentry\fR
command.
.\" METHOD: delete
.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 an empty string.
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the entry's string.
.\" METHOD: icursor
.TP
\fIpathName \fBicursor \fIindex\fR
.
Arrange for the insertion cursor to be displayed just before the character
given by \fIindex\fR.  Returns an empty string.
.\" METHOD: index
.TP
\fIpathName \fBindex\fI index\fR
.
Returns the numerical index corresponding to \fIindex\fR.
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fIindex string\fR
.
Insert the characters of \fIstring\fR just before the character
indicated by \fIindex\fR.  Returns an empty string.
.\" METHOD: scan
.TP
\fIpathName \fBscan\fI option args\fR
.
This command is used to implement scanning on entries.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx\fR
.
Records \fIx\fR and the current view in the entry window;  used in
conjunction with later \fBscan dragto\fR commands.  Typically this
command is associated with a mouse button press in the widget.  It
returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx\fR
.
This command computes the difference between its \fIx\fR argument
and the \fIx\fR argument to the last \fBscan mark\fR command for
the widget.  It then adjusts the view left or right by 10 times the
difference in x-coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the entry at high speed through the window.  The return
value is an empty string.
.RE
.\" METHOD: selection
.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 adjust \fIindex\fR
.
Locate the end of the selection nearest to the character given by
\fIindex\fR, and adjust that end of the selection to be at \fIindex\fR
(i.e. including but not going beyond \fIindex\fR).  The other
end of the selection is made the anchor point for future
\fBselect to\fR commands.  If the selection
is not currently in the entry, then a new selection is created to
include the characters between \fIindex\fR and the most recent
selection anchor point, inclusive.
Returns an empty string.
.TP
\fIpathName \fBselection clear\fR
.
Clear the selection if it is currently in this widget.  If the
selection is not in this widget then the command has no effect.
Returns an empty string.
.TP
\fIpathName \fBselection from \fIindex\fR
.
Set the selection anchor point to just before the character
given by \fIindex\fR.  Does not change the selection.
Returns an empty string.
.TP
\fIpathName \fBselection present\fR
.
Returns 1 if there is are characters selected in the entry,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart end\fR
.
Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the entry's selection is cleared.
.TP
\fIpathName \fBselection to \fIindex\fR
.
If \fIindex\fR is before the anchor point, set the selection
to the characters from \fIindex\fR up to but not including
the anchor point.
If \fIindex\fR is the same as the anchor point, do nothing.
If \fIindex\fR is after the anchor point, set the selection
to the characters from the anchor point up to but not including
\fIindex\fR.
The anchor point is determined by the most recent \fBselect from\fR
or \fBselect adjust\fR command in this widget.
If the selection is not in this widget then a new selection is
created using the most recent anchor point specified for the widget.
Returns an empty string.
.RE
.\" METHOD: validate
.TP
\fIpathName \fBvalidate\fR
.
This command is used to force an evaluation of the \fB\-validatecommand\fR
independent of the conditions specified by the \fB\-validate\fR option.
This is done by temporarily setting the \fB\-validate\fR option to \fBall\fR.
It returns 0 or 1.
.\" METHOD: xview
.TP
\fIpathName \fBxview \fIargs\fR
.
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the entry's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fI index\fR
.
Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
.
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls.

Changes to doc/event.n.

16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
32
33

34
35

36
37
38
39
40
41
42
43
44
45

46
47

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

68
69

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

88
89

90
91
92
93

94
95

96
97
98
99

100
101

102
103
104
105

106
107

108
109
110

111
112

113
114
115

116
117

118
119
120
121
122
123
124
125
126

127
128

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

143
144

145
146
147
148

149
150

151
152
153

154
155

156
157
158
159

160
161

162
163
164
165
166
167

168
169

170
171
172
173
174
175

176
177

178
179
180
181

182
183

184
185
186
187

188
189

190
191
192
193
194
195

196
197

198
199
200
201
202

203
204

205
206
207
208
209
210

211
212

213
214
215

216
217

218
219
220

221
222

223
224
225
226
227
228
229
230
231

232
233

234
235
236
237
238

239
240

241
242
243
244
245
246
247

248
249

250
251
252
253
254

255
256

257
258
259
260

261
262

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

281
282

283
284
285
286
287
288
289
290
291
292

293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321

322
323
324
325

326
327
328
329

330
331
332
333

334
335
336
337

338
339
340
341

342
343
344
345









346

347
348
349
350
351
352

353
354
355
356
357
358

359
360
361
362

363
364
365
366
367
368
369
370
371
372

373
374
375

376
377
378

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

.TP
\fBevent add <<\fIvirtual\fB>>\fI sequence \fR?\fIsequence ...\fR?

Associates the virtual event \fIvirtual\fR with the physical
event sequence(s) given by the \fIsequence\fR arguments, so that
the virtual event will trigger whenever any one of the \fIsequence\fRs
occurs.
\fIVirtual\fR may be any string value and \fIsequence\fR may have
any of the values allowed for the \fIsequence\fR argument to the
\fBbind\fR command.
If \fIvirtual\fR is already defined, the new physical event sequences
add to the existing sequences for the event.

.TP
\fBevent delete <<\fIvirtual\fB>> \fR?\fIsequence\fR \fIsequence ...\fR?

Deletes each of the \fIsequence\fRs from those associated with
the virtual event given by \fIvirtual\fR.
\fIVirtual\fR may be any string value and \fIsequence\fR may have
any of the values allowed for the \fIsequence\fR argument to the
\fBbind\fR command.
Any \fIsequence\fRs not currently associated with \fIvirtual\fR
are ignored.
If no \fIsequence\fR argument is provided, all physical event sequences
are removed for \fIvirtual\fR, so that the virtual event will not
trigger anymore.

.TP
\fBevent generate \fIwindow event \fR?\fIoption value option value ...\fR?

Generates a window event and arranges for it to be processed just as if
it had come from the window system.
\fIWindow\fR gives the path name of the window for which the event
will be generated; it may also be an identifier (such as returned by
\fBwinfo id\fR) as long as it is for a window in the current application.
\fIEvent\fR provides a basic description of
the event, such as \fB<Shift-Button-2>\fR or \fB<<Paste>>\fR.
If \fIWindow\fR is empty the whole screen is meant, and coordinates
are relative to the screen.
\fIEvent\fR may have any of the forms allowed for the \fIsequence\fR
argument of the \fBbind\fR command except that it must consist
of a single event pattern, not a sequence.
\fIOption-value\fR pairs may be used to specify additional
attributes of the event, such as the x and y mouse position;  see
\fBEVENT FIELDS\fR below.  If the \fB\-when\fR option is not specified, the
event is processed immediately:  all of the handlers for the event
will complete before the \fBevent generate\fR command returns.
If the \fB\-when\fR option is specified then it determines when the
event is processed.  Certain events, such as key events, require
that the window has focus to receive the event properly.

.TP
\fBevent info \fR?\fB<<\fIvirtual\fB>>\fR?

Returns information about virtual events.
If the \fB<<\fIvirtual\fB>>\fR argument is omitted, the return value
is a list of all the virtual events that are currently defined.
If \fB<<\fIvirtual\fB>>\fR is specified then the return value is
a list whose elements are the physical event sequences currently
defined for the given virtual event;  if the virtual event is
not defined then an empty string is returned.
.RS
.PP
Note that virtual events that are not bound to physical event
sequences are \fInot\fR returned by \fBevent info\fR.
.RE
.SH "EVENT FIELDS"
.PP
The following options are supported for the \fBevent generate\fR
command.  These correspond to the
.QW %
expansions allowed in binding scripts for the \fBbind\fR command.

.TP
\fB\-above\fI window\fR

\fIWindow\fR specifies the \fIabove\fR field for the event,
either as a window path name or as an integer window id.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%a\fR substitution for binding scripts.

.TP
\fB\-borderwidth\fI size\fR

\fISize\fR must be a screen distance;  it specifies the
\fIborder_width\fR field for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%B\fR substitution for binding scripts.

.TP
\fB\-button\fI number\fR

\fINumber\fR must be an integer;  it specifies the \fIdetail\fR field
for a \fBButton\fR or \fBButtonRelease\fR event, overriding
any button  number provided in the base \fIevent\fR argument.
Corresponds to the \fB%b\fR substitution for binding scripts.

.TP
\fB\-count\fI number\fR

\fINumber\fR must be an integer;  it specifies the \fIcount\fR field
for the event.  Valid for \fBExpose\fR events.
Corresponds to the \fB%c\fR substitution for binding scripts.

.TP
\fB\-data\fI string\fR

\fIString\fR may be any value; it specifies the \fIuser_data\fR field
for the event.  Only valid for virtual events.  Corresponds to the
\fB%d\fR substitution for virtual events in binding scripts.

.TP
\fB\-delta\fI number\fR

\fINumber\fR must be an integer;  it specifies the \fIdelta\fR field
for the \fBMouseWheel\fR event.  The \fIdelta\fR refers to the
direction and magnitude the mouse wheel was rotated.  Note the value
is not a screen distance but are units of motion in the mouse wheel.
Typically these values are multiples of 120.  For example, 120 should
scroll the text widget up 4 lines and \-240 would scroll the text
widget down 8 lines.  Of course, other widgets may define different
behaviors for mouse wheel motion.  This field corresponds to the
\fB%D\fR substitution for binding scripts.

.TP
\fB\-detail\fI detail\fR

\fIDetail\fR specifies the \fIdetail\fR field for the event
and must be one of the following:
.RS
.DS
.ta 6c
\fBNotifyAncestor\fR	\fBNotifyNonlinearVirtual\fR
\fBNotifyDetailNone\fR	\fBNotifyPointer\fR
\fBNotifyInferior\fR	\fBNotifyPointerRoot\fR
\fBNotifyNonlinear\fR	\fBNotifyVirtual\fR
.DE
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR and
\fBFocusOut\fR events.
Corresponds to the \fB%d\fR substitution for binding scripts.
.RE

.TP
\fB\-focus\fI boolean\fR

\fIBoolean\fR must be a boolean value;  it specifies the \fIfocus\fR
field for the event.
Valid for \fBEnter\fR and \fBLeave\fR events.
Corresponds to the \fB%f\fR substitution for binding scripts.

.TP
\fB\-height\fI size\fR

\fISize\fR must be a screen distance;  it specifies the \fIheight\fR
field for the event.  Valid for \fBConfigure\fR events.
Corresponds to the \fB%h\fR substitution for binding scripts.

.TP
\fB\-keycode\fI number\fR

\fINumber\fR  must be an integer;  it specifies the \fIkeycode\fR
field for the event.
Valid for \fBKey\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%k\fR substitution for binding scripts.

.TP
\fB\-keysym\fI name\fR

\fIName\fR must be the name of a valid keysym, such as \fBg\fR,
\fBspace\fR, or \fBReturn\fR;  its corresponding
keycode value is used as the \fIkeycode\fR field for event, overriding
any detail specified in the base \fIevent\fR argument.
Valid for \fBKey\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%K\fR substitution for binding scripts.

.TP
\fB\-mode\fI notify\fR

\fINotify\fR specifies the \fImode\fR field for the event and must be
one of \fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR, and
\fBFocusOut\fR events.
Corresponds to the \fB%m\fR substitution for binding scripts.

.TP
\fB\-override\fI boolean\fR

\fIBoolean\fR must be a boolean value;  it specifies the
\fIoverride_redirect\fR field for the event.
Valid for \fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
Corresponds to the \fB%o\fR substitution for binding scripts.

.TP
\fB\-place\fI where\fR

\fIWhere\fR specifies the \fIplace\fR field for the event;  it must be
either \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.
Valid for \fBCirculate\fR events.
Corresponds to the \fB%p\fR substitution for binding scripts.

.TP
\fB\-root\fI window\fR

\fIWindow\fR must be either a window path name or an integer window
identifier;  it specifies the \fIroot\fR field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%R\fR substitution for binding scripts.

.TP
\fB\-rootx\fI coord\fR

\fICoord\fR must be a screen distance;  it specifies the \fIx_root\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.  Corresponds to the \fB%X\fR substitution for binding scripts.

.TP
\fB\-rooty\fI coord\fR

\fICoord\fR must be a screen distance;  it specifies the \fIy_root\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%Y\fR substitution for binding scripts.

.TP
\fB\-sendevent\fI boolean\fR

\fIBoolean\fR must be a boolean value;  it specifies the \fIsend_event\fR
field for the event.  Valid for all events.  Corresponds to the
\fB%E\fR substitution for binding scripts.

.TP
\fB\-serial\fI number\fR

\fINumber\fR must be an integer;  it specifies the \fIserial\fR field
for the event.  Valid for all events.
Corresponds to the \fB%#\fR substitution for binding scripts.

.TP
\fB\-state\fI state\fR

\fIState\fR specifies the \fIstate\fR field for the event.
For \fBKey\fR, \fBKeyRelease\fR, \fBButtons\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events
it must be an integer value.
For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR,
\fBVisibilityPartiallyObscured\fR, or \fBVisibilityFullyObscured\fR.
This option overrides any modifiers such as \fBMeta\fR or \fBControl\fR
specified in the base \fIevent\fR.
Corresponds to the \fB%s\fR substitution for binding scripts.

.TP
\fB\-subwindow\fI window\fR

\fIWindow\fR specifies the \fIsubwindow\fR field for the event, either
as a path name for a Tk widget or as an integer window identifier.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events.
Similar to \fB%S\fR substitution for binding scripts.

.TP
\fB\-time\fI integer\fR

\fIInteger\fR must be an integer value;  it specifies the \fItime\fR field
for the event. Additonally the special value \fBcurrent\fR is allowed,
this value will be substituted by the current event time.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, \fBMotion\fR,
and \fBProperty\fR events.
Corresponds to the \fB%t\fR substitution for binding scripts.

.TP
\fB\-warp\fI boolean\fR

\fIboolean\fR must be a boolean value;  it specifies whether
the screen pointer should be warped as well.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, and \fBMotion\fR events.  The pointer will
only warp to a window if it is mapped.

.TP
\fB\-width\fI size\fR

\fISize\fR must be a screen distance;  it specifies the \fIwidth\fR field
for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%w\fR substitution for binding scripts.

.TP
\fB\-when\fI when\fR

\fIWhen\fR determines when the event will be processed;  it must have one
of the following values:
.RS
.IP \fBnow\fR 10
Process the event immediately, before the command returns.
This also happens if the \fB\-when\fR option is omitted.
.IP \fBtail\fR 10
Place the event on Tcl's event queue behind any events already
queued for this application.
.IP \fBhead\fR 10
Place the event at the front of Tcl's event queue, so that it
will be handled before any other events already queued.
.IP \fBmark\fR 10
Place the event at the front of Tcl's event queue but behind any
other events already queued with \fB\-when mark\fR.
This option is useful when generating a series of events that should
be processed in order but at the front of the queue.
.RE

.TP
\fB\-x\fI coord\fR

\fICoord\fR must be a screen distance;  it specifies the \fIx\fR field
for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%x\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%X\fR substitution
for binding scripts.

.TP
\fB\-y\fI coord\fR

\fICoord\fR must be a screen distance;  it specifies the \fIy\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%y\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%Y\fR substitution
for binding scripts.
.PP
Any options that are not specified when generating an event are filled
with the value 0, except for \fIserial\fR, which is filled with the
next X event serial number.
.SH "PREDEFINED VIRTUAL EVENTS"
.PP
Tk defines the following virtual events for the purposes of
notification:
.TP
\fB<<AltUnderlined>>\fR

This is sent to widget to notify it that the letter it has underlined
(as an accelerator indicator) with the \fB\-underline\fR option has
been pressed in combination with the Alt key. The usual response to
this is to either focus into the widget (or some related widget) or to
invoke the widget.
.TP
\fB<<Invoke>>\fR

This can be sent to some widgets (e.g. button, listbox, menu) as an
alternative to <space>.
.TP
\fB<<ListboxSelect>>\fR

This is sent to a listbox when the set of selected item(s) in the
listbox is updated.
.TP
\fB<<MenuSelect>>\fR

This is sent to a menu when the currently selected item in the menu
changes. It is intended for use with context-sensitive help systems.
.TP
\fB<<Modified>>\fR

This is sent to a text widget when the contents of the widget are
changed.
.TP
\fB<<Selection>>\fR

This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR

This is sent to all widgets when the ttk theme changed. The ttk
widgets listen to this event and redisplay themselves when it fires.
The legacy widgets ignore this event.
.TP









\fB<<TraverseIn>>\fR

This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<TraverseOut>>\fR

This is sent to a widget when the focus leaves the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<UndoStack>>\fR

This is sent to a text widget when its undo stack or redo stack becomes
empty or unempty.
.TP
\fB<<WidgetViewSync>>\fR

This is sent to a text widget when its internal data become obsolete,
and again when these internal data are back in sync with the widget
view. The detail field (%d substitution) is either true (when the
widget is in sync) or false (when it is not).
.PP
Tk defines the following virtual events for the purposes of unifying
bindings across multiple platforms. Users expect them to behave in the
following way:
.TP
\fB<<Clear>>\fR

Delete the currently selected widget contents.
.TP
\fB<<Copy>>\fR

Copy the currently selected widget contents to the clipboard.
.TP
\fB<<Cut>>\fR

Move the currently selected widget contents to the clipboard.
.TP
\fB<<LineEnd>>\fR
.
Move to the end of the line in the current widget while deselecting any
selected contents.
.TP







>


>









>

|
>










>


>




















>


>


















>


>




>


>




>


>




>


>



>


>



>


>









>


>














>


>




>


>



>


>




>


>






>


>






>


>




>


>




>


>






>


>





>


>






>


>



>


>



>


>









>


>





>


>

|





>


>





>


>




>


>


















>


>










>


>




















>







>




>




>




>




>




>




>
>
>
>
>
>
>
>
>

>






>






>




>










>



>



>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
.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:
.\" METHOD: add
.TP
\fBevent add <<\fIvirtual\fB>>\fI sequence \fR?\fIsequence ...\fR?
.
Associates the virtual event \fIvirtual\fR with the physical
event sequence(s) given by the \fIsequence\fR arguments, so that
the virtual event will trigger whenever any one of the \fIsequence\fRs
occurs.
\fIVirtual\fR may be any string value and \fIsequence\fR may have
any of the values allowed for the \fIsequence\fR argument to the
\fBbind\fR command.
If \fIvirtual\fR is already defined, the new physical event sequences
add to the existing sequences for the event.
.\" METHOD: delete
.TP
\fBevent delete <<\fIvirtual\fB>> \fR?\fIsequence sequence ...\fR?
.
Deletes each of the \fIsequence\fRs from those associated with
the virtual event given by \fIvirtual\fR.
\fIVirtual\fR may be any string value and \fIsequence\fR may have
any of the values allowed for the \fIsequence\fR argument to the
\fBbind\fR command.
Any \fIsequence\fRs not currently associated with \fIvirtual\fR
are ignored.
If no \fIsequence\fR argument is provided, all physical event sequences
are removed for \fIvirtual\fR, so that the virtual event will not
trigger anymore.
.\" METHOD: generate
.TP
\fBevent generate \fIwindow event \fR?\fIoption value option value ...\fR?
.
Generates a window event and arranges for it to be processed just as if
it had come from the window system.
\fIWindow\fR gives the path name of the window for which the event
will be generated; it may also be an identifier (such as returned by
\fBwinfo id\fR) as long as it is for a window in the current application.
\fIEvent\fR provides a basic description of
the event, such as \fB<Shift-Button-2>\fR or \fB<<Paste>>\fR.
If \fIWindow\fR is empty the whole screen is meant, and coordinates
are relative to the screen.
\fIEvent\fR may have any of the forms allowed for the \fIsequence\fR
argument of the \fBbind\fR command except that it must consist
of a single event pattern, not a sequence.
\fIOption-value\fR pairs may be used to specify additional
attributes of the event, such as the x and y mouse position;  see
\fBEVENT FIELDS\fR below.  If the \fB\-when\fR option is not specified, the
event is processed immediately:  all of the handlers for the event
will complete before the \fBevent generate\fR command returns.
If the \fB\-when\fR option is specified then it determines when the
event is processed.  Certain events, such as key events, require
that the window has focus to receive the event properly.
.\" METHOD: info
.TP
\fBevent info \fR?\fB<<\fIvirtual\fB>>\fR?
.
Returns information about virtual events.
If the \fB<<\fIvirtual\fB>>\fR argument is omitted, the return value
is a list of all the virtual events that are currently defined.
If \fB<<\fIvirtual\fB>>\fR is specified then the return value is
a list whose elements are the physical event sequences currently
defined for the given virtual event;  if the virtual event is
not defined then an empty string is returned.
.RS
.PP
Note that virtual events that are not bound to physical event
sequences are \fInot\fR returned by \fBevent info\fR.
.RE
.SH "EVENT FIELDS"
.PP
The following options are supported for the \fBevent generate\fR
command.  These correspond to the
.QW %
expansions allowed in binding scripts for the \fBbind\fR command.
.\" OPTION: -above
.TP
\fB\-above\fI window\fR
.
\fIWindow\fR specifies the \fIabove\fR field for the event,
either as a window path name or as an integer window id.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%a\fR substitution for binding scripts.
.\" OPTION: -borderwidth
.TP
\fB\-borderwidth\fI size\fR
.
\fISize\fR must be a screen distance;  it specifies the
\fIborder_width\fR field for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%B\fR substitution for binding scripts.
.\" OPTION: -button
.TP
\fB\-button\fI number\fR
.
\fINumber\fR must be an integer;  it specifies the \fIdetail\fR field
for a \fBButton\fR or \fBButtonRelease\fR event, overriding
any button  number provided in the base \fIevent\fR argument.
Corresponds to the \fB%b\fR substitution for binding scripts.
.\" OPTION: -count
.TP
\fB\-count\fI number\fR
.
\fINumber\fR must be an integer;  it specifies the \fIcount\fR field
for the event.  Valid for \fBExpose\fR events.
Corresponds to the \fB%c\fR substitution for binding scripts.
.\" OPTION: -data
.TP
\fB\-data\fI string\fR
.
\fIString\fR may be any value; it specifies the \fIuser_data\fR field
for the event.  Only valid for virtual events.  Corresponds to the
\fB%d\fR substitution for virtual events in binding scripts.
.\" OPTION: -delta
.TP
\fB\-delta\fI number\fR
.
\fINumber\fR must be an integer;  it specifies the \fIdelta\fR field
for the \fBMouseWheel\fR event.  The \fIdelta\fR refers to the
direction and magnitude the mouse wheel was rotated.  Note the value
is not a screen distance but are units of motion in the mouse wheel.
Typically these values are multiples of 120.  For example, 120 should
scroll the text widget up 4 lines and \-240 would scroll the text
widget down 8 lines.  Of course, other widgets may define different
behaviors for mouse wheel motion.  This field corresponds to the
\fB%D\fR substitution for binding scripts.
.\" OPTION: -detail
.TP
\fB\-detail\fI detail\fR
.
\fIDetail\fR specifies the \fIdetail\fR field for the event
and must be one of the following:
.RS
.DS
.ta 6c
\fBNotifyAncestor\fR	\fBNotifyNonlinearVirtual\fR
\fBNotifyDetailNone\fR	\fBNotifyPointer\fR
\fBNotifyInferior\fR	\fBNotifyPointerRoot\fR
\fBNotifyNonlinear\fR	\fBNotifyVirtual\fR
.DE
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR and
\fBFocusOut\fR events.
Corresponds to the \fB%d\fR substitution for binding scripts.
.RE
.\" OPTION: -focus
.TP
\fB\-focus\fI boolean\fR
.
\fIBoolean\fR must be a boolean value;  it specifies the \fIfocus\fR
field for the event.
Valid for \fBEnter\fR and \fBLeave\fR events.
Corresponds to the \fB%f\fR substitution for binding scripts.
.\" OPTION: -height
.TP
\fB\-height\fI size\fR
.
\fISize\fR must be a screen distance;  it specifies the \fIheight\fR
field for the event.  Valid for \fBConfigure\fR events.
Corresponds to the \fB%h\fR substitution for binding scripts.
.\" OPTION: -keycode
.TP
\fB\-keycode\fI number\fR
.
\fINumber\fR  must be an integer;  it specifies the \fIkeycode\fR
field for the event.
Valid for \fBKey\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%k\fR substitution for binding scripts.
.\" OPTION: -keysym
.TP
\fB\-keysym\fI name\fR
.
\fIName\fR must be the name of a valid keysym, such as \fBg\fR,
\fBspace\fR, or \fBReturn\fR;  its corresponding
keycode value is used as the \fIkeycode\fR field for event, overriding
any detail specified in the base \fIevent\fR argument.
Valid for \fBKey\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%K\fR substitution for binding scripts.
.\" OPTION: -mode
.TP
\fB\-mode\fI notify\fR
.
\fINotify\fR specifies the \fImode\fR field for the event and must be
one of \fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR, and
\fBFocusOut\fR events.
Corresponds to the \fB%m\fR substitution for binding scripts.
.\" OPTION: -override
.TP
\fB\-override\fI boolean\fR
.
\fIBoolean\fR must be a boolean value;  it specifies the
\fIoverride_redirect\fR field for the event.
Valid for \fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
Corresponds to the \fB%o\fR substitution for binding scripts.
.\" OPTION: -place
.TP
\fB\-place\fI where\fR
.
\fIWhere\fR specifies the \fIplace\fR field for the event;  it must be
either \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.
Valid for \fBCirculate\fR events.
Corresponds to the \fB%p\fR substitution for binding scripts.
.\" OPTION: -root
.TP
\fB\-root\fI window\fR
.
\fIWindow\fR must be either a window path name or an integer window
identifier;  it specifies the \fIroot\fR field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%R\fR substitution for binding scripts.
.\" OPTION: -rootx
.TP
\fB\-rootx\fI coord\fR
.
\fICoord\fR must be a screen distance;  it specifies the \fIx_root\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.  Corresponds to the \fB%X\fR substitution for binding scripts.
.\" OPTION: -rooty
.TP
\fB\-rooty\fI coord\fR
.
\fICoord\fR must be a screen distance;  it specifies the \fIy_root\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%Y\fR substitution for binding scripts.
.\" OPTION: -sendevent
.TP
\fB\-sendevent\fI boolean\fR
.
\fIBoolean\fR must be a boolean value;  it specifies the \fIsend_event\fR
field for the event.  Valid for all events.  Corresponds to the
\fB%E\fR substitution for binding scripts.
.\" OPTION: -serial
.TP
\fB\-serial\fI number\fR
.
\fINumber\fR must be an integer;  it specifies the \fIserial\fR field
for the event.  Valid for all events.
Corresponds to the \fB%#\fR substitution for binding scripts.
.\" OPTION: -state
.TP
\fB\-state\fI state\fR
.
\fIState\fR specifies the \fIstate\fR field for the event.
For \fBKey\fR, \fBKeyRelease\fR, \fBButtons\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events
it must be an integer value.
For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR,
\fBVisibilityPartiallyObscured\fR, or \fBVisibilityFullyObscured\fR.
This option overrides any modifiers such as \fBMeta\fR or \fBControl\fR
specified in the base \fIevent\fR.
Corresponds to the \fB%s\fR substitution for binding scripts.
.\" OPTION: -subwindow
.TP
\fB\-subwindow\fI window\fR
.
\fIWindow\fR specifies the \fIsubwindow\fR field for the event, either
as a path name for a Tk widget or as an integer window identifier.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events.
Similar to \fB%S\fR substitution for binding scripts.
.\" OPTION: -time
.TP
\fB\-time\fI integer\fR
.
\fIInteger\fR must be an integer value;  it specifies the \fItime\fR field
for the event. Additionally, the special value \fBcurrent\fR is allowed;
this value will be substituted by the current event time.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, \fBMotion\fR,
and \fBProperty\fR events.
Corresponds to the \fB%t\fR substitution for binding scripts.
.\" OPTION: -warp
.TP
\fB\-warp\fI boolean\fR
.
\fIboolean\fR must be a boolean value;  it specifies whether
the screen pointer should be warped as well.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, and \fBMotion\fR events.  The pointer will
only warp to a window if it is mapped.
.\" OPTION: -width
.TP
\fB\-width\fI size\fR
.
\fISize\fR must be a screen distance;  it specifies the \fIwidth\fR field
for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%w\fR substitution for binding scripts.
.\" OPTION: -when
.TP
\fB\-when\fI when\fR
.
\fIWhen\fR determines when the event will be processed;  it must have one
of the following values:
.RS
.IP \fBnow\fR 10
Process the event immediately, before the command returns.
This also happens if the \fB\-when\fR option is omitted.
.IP \fBtail\fR 10
Place the event on Tcl's event queue behind any events already
queued for this application.
.IP \fBhead\fR 10
Place the event at the front of Tcl's event queue, so that it
will be handled before any other events already queued.
.IP \fBmark\fR 10
Place the event at the front of Tcl's event queue but behind any
other events already queued with \fB\-when mark\fR.
This option is useful when generating a series of events that should
be processed in order but at the front of the queue.
.RE
.\" OPTION: -x
.TP
\fB\-x\fI coord\fR
.
\fICoord\fR must be a screen distance;  it specifies the \fIx\fR field
for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%x\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%X\fR substitution
for binding scripts.
.\" OPTION: -y
.TP
\fB\-y\fI coord\fR
.
\fICoord\fR must be a screen distance;  it specifies the \fIy\fR
field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%y\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%Y\fR substitution
for binding scripts.
.PP
Any options that are not specified when generating an event are filled
with the value 0, except for \fIserial\fR, which is filled with the
next X event serial number.
.SH "PREDEFINED VIRTUAL EVENTS"
.PP
Tk defines the following virtual events for the purposes of
notification:
.TP
\fB<<AltUnderlined>>\fR
.
This is sent to widget to notify it that the letter it has underlined
(as an accelerator indicator) with the \fB\-underline\fR option has
been pressed in combination with the Alt key. The usual response to
this is to either focus into the widget (or some related widget) or to
invoke the widget.
.TP
\fB<<Invoke>>\fR
.
This can be sent to some widgets (e.g. button, listbox, menu) as an
alternative to <space>.
.TP
\fB<<ListboxSelect>>\fR
.
This is sent to a listbox when the set of selected item(s) in the
listbox is updated.
.TP
\fB<<MenuSelect>>\fR
.
This is sent to a menu when the currently selected item in the menu
changes. It is intended for use with context-sensitive help systems.
.TP
\fB<<Modified>>\fR
.
This is sent to a text widget when the contents of the widget are
changed.
.TP
\fB<<Selection>>\fR
.
This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR
.
This is sent to all widgets when the ttk theme changed. The ttk
widgets listen to this event and redisplay themselves when it fires.
The legacy widgets ignore this event.
.TP
\fB<<TkWorldChanged>>\fR
.
This event is sent to all widgets when a font is changed, for example,
by the use of [font configure].  The user_data field (%d) will have the
value "FontChanged".  For other system wide changes, this event will
be sent to all widgets, and the user_data field will indicate the
cause of the change.  NOTE: all tk and ttk widgets already handle this
event internally.
.TP
\fB<<TraverseIn>>\fR
.
This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<TraverseOut>>\fR
.
This is sent to a widget when the focus leaves the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
\fB<<UndoStack>>\fR
.
This is sent to a text widget when its undo stack or redo stack becomes
empty or unempty.
.TP
\fB<<WidgetViewSync>>\fR
.
This is sent to a text widget when its internal data become obsolete,
and again when these internal data are back in sync with the widget
view. The detail field (%d substitution) is either true (when the
widget is in sync) or false (when it is not).
.PP
Tk defines the following virtual events for the purposes of unifying
bindings across multiple platforms. Users expect them to behave in the
following way:
.TP
\fB<<Clear>>\fR
.
Delete the currently selected widget contents.
.TP
\fB<<Copy>>\fR
.
Copy the currently selected widget contents to the clipboard.
.TP
\fB<<Cut>>\fR
.
Move the currently selected widget contents to the clipboard.
.TP
\fB<<LineEnd>>\fR
.
Move to the end of the line in the current widget while deselecting any
selected contents.
.TP
405
406
407
408
409
410
411

412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
.TP
\fB<<NextWord>>\fR
.
Move to the next group of items (i.e., visible word) in the current widget
while deselecting any selected contents.
.TP
\fB<<Paste>>\fR

Replace the currently selected widget contents with the contents of
the clipboard.
.TP
\fB<<PasteSelection>>\fR

Insert the contents of the selection at the mouse location. (This
event has meaningful \fB%x\fR and \fB%y\fR substitutions).
.TP
\fB<<PrevChar>>\fR
.
Move to the previous item (i.e., visible character) in the current widget
while deselecting any selected contents.
.TP
\fB<<PrevLine>>\fR
.
Move to the previous line in the current widget while deselecting any selected
contents.
.TP
\fB<<PrevPara>>\fR
.
Move to the previous paragraph in the current widget while deselecting any
selected contents.
.TP
\fB<<PrevWindow>>\fR

Traverse to the previous window.
.TP
\fB<<PrevWord>>\fR
.
Move to the previous group of items (i.e., visible word) in the current widget
while deselecting any selected contents.
.TP
\fB<<Redo>>\fR

Redo one undone action.
.TP
\fB<<SelectAll>>\fR
.
Set the range of selected contents to the complete widget.
.TP
\fB<<SelectLineEnd>>\fR







>




>



















>








>







490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
.TP
\fB<<NextWord>>\fR
.
Move to the next group of items (i.e., visible word) in the current widget
while deselecting any selected contents.
.TP
\fB<<Paste>>\fR
.
Replace the currently selected widget contents with the contents of
the clipboard.
.TP
\fB<<PasteSelection>>\fR
.
Insert the contents of the selection at the mouse location. (This
event has meaningful \fB%x\fR and \fB%y\fR substitutions).
.TP
\fB<<PrevChar>>\fR
.
Move to the previous item (i.e., visible character) in the current widget
while deselecting any selected contents.
.TP
\fB<<PrevLine>>\fR
.
Move to the previous line in the current widget while deselecting any selected
contents.
.TP
\fB<<PrevPara>>\fR
.
Move to the previous paragraph in the current widget while deselecting any
selected contents.
.TP
\fB<<PrevWindow>>\fR
.
Traverse to the previous window.
.TP
\fB<<PrevWord>>\fR
.
Move to the previous group of items (i.e., visible word) in the current widget
while deselecting any selected contents.
.TP
\fB<<Redo>>\fR
.
Redo one undone action.
.TP
\fB<<SelectAll>>\fR
.
Set the range of selected contents to the complete widget.
.TP
\fB<<SelectLineEnd>>\fR

Changes to doc/focus.n.

51
52
53
54
55
56
57

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75

76
77
78
79
80

81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
implement a focus order among the windows of a top-level;  they
are used in the default bindings for Tab and Shift-Tab, among other
things.
.PP
The \fBfocus\fR command can take any of the following forms:
.TP
\fBfocus\fR

Returns the path name of the focus window on the display containing
the application's main window,  or an empty string if no window in
this application has the focus on that display.   Note:  it is
better to specify the display explicitly using \fB\-displayof\fR
(see below) so that the code will work in applications using multiple
displays.
.TP
\fBfocus \fIwindow\fR

If the application currently has the input focus on \fIwindow\fR's
display, this command resets the input focus for \fIwindow\fR's display
to \fIwindow\fR and returns an empty string.
If the application does not currently have the input focus on
\fIwindow\fR's display, \fIwindow\fR will be remembered as the focus
for its top-level;  the next time the focus arrives at the top-level,
Tk will redirect it to \fIwindow\fR.
If \fIwindow\fR is an empty string then the command does nothing.
.TP
\fBfocus \-displayof\fR \fIwindow\fR

Returns the name of the focus window on the display containing \fIwindow\fR.
If the focus window for \fIwindow\fR's display is not in this
application, the return value is an empty string.
.TP
\fBfocus \-force \fIwindow\fR

Sets the focus of \fIwindow\fR's display to \fIwindow\fR, even if
the application does not currently have the input focus for the display.
This command should be used sparingly, if at all.
In normal usage, an application should not claim the focus for
itself;  instead, it should wait for the window manager to give it
the focus.
If \fIwindow\fR is an empty string then the command does nothing.
.TP
\fBfocus \-lastfor\fR \fIwindow\fR

Returns the name of the most recent window to have the input focus
among all the windows in the same top-level as \fIwindow\fR.
If no window in that top-level has ever had the input focus, or
if the most recent focus window has been deleted, then the name
of the top-level is returned.  The return value is the window that
will receive the input focus the next time the window manager gives
the focus to the top-level.







>








>









|
>





>








|
>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
implement a focus order among the windows of a top-level;  they
are used in the default bindings for Tab and Shift-Tab, among other
things.
.PP
The \fBfocus\fR command can take any of the following forms:
.TP
\fBfocus\fR
.
Returns the path name of the focus window on the display containing
the application's main window,  or an empty string if no window in
this application has the focus on that display.   Note:  it is
better to specify the display explicitly using \fB\-displayof\fR
(see below) so that the code will work in applications using multiple
displays.
.TP
\fBfocus \fIwindow\fR
.
If the application currently has the input focus on \fIwindow\fR's
display, this command resets the input focus for \fIwindow\fR's display
to \fIwindow\fR and returns an empty string.
If the application does not currently have the input focus on
\fIwindow\fR's display, \fIwindow\fR will be remembered as the focus
for its top-level;  the next time the focus arrives at the top-level,
Tk will redirect it to \fIwindow\fR.
If \fIwindow\fR is an empty string then the command does nothing.
.TP
\fBfocus \-displayof \fIwindow\fR
.
Returns the name of the focus window on the display containing \fIwindow\fR.
If the focus window for \fIwindow\fR's display is not in this
application, the return value is an empty string.
.TP
\fBfocus \-force \fIwindow\fR
.
Sets the focus of \fIwindow\fR's display to \fIwindow\fR, even if
the application does not currently have the input focus for the display.
This command should be used sparingly, if at all.
In normal usage, an application should not claim the focus for
itself;  instead, it should wait for the window manager to give it
the focus.
If \fIwindow\fR is an empty string then the command does nothing.
.TP
\fBfocus \-lastfor \fIwindow\fR
.
Returns the name of the most recent window to have the input focus
among all the windows in the same top-level as \fIwindow\fR.
If no window in that top-level has ever had the input focus, or
if the most recent focus window has been deleted, then the name
of the top-level is returned.  The return value is the window that
will receive the input focus the next time the window manager gives
the focus to the top-level.
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
the fact that the X focus is on the top-level is invisible unless
you use C code to query the X server directly.
.SH "EXAMPLE"
.PP
To make a window that only participates in the focus traversal ring
when a variable is set, add the following bindings to the widgets
\fIbefore\fR and \fIafter\fR it in that focus ring:

.CS
button .before \-text "Before"
button .middle \-text "Middle"
button .after  \-text "After"
checkbutton .flag \-variable traverseToMiddle \-takefocus 0
pack .flag \-side left
pack .before .middle .after
bind .before <Tab> {
   if {!$traverseToMiddle} {
      \fBfocus\fR .after
      break
   }
}
bind .after <Shift\-Tab> {
   if {!$traverseToMiddle} {
      \fBfocus\fR .before
      break
   }
}
\fBfocus\fR .before
.CE
.SH KEYWORDS
events, focus, keyboard, top-level, window manager
'\" Local Variables:
'\" mode: nroff
'\" End:







>

|
|
|
|
|







|












110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
the fact that the X focus is on the top-level is invisible unless
you use C code to query the X server directly.
.SH "EXAMPLE"
.PP
To make a window that only participates in the focus traversal ring
when a variable is set, add the following bindings to the widgets
\fIbefore\fR and \fIafter\fR it in that focus ring:
.PP
.CS
button .before -text "Before"
button .middle -text "Middle"
button .after  -text "After"
checkbutton .flag -variable traverseToMiddle -takefocus 0
pack .flag -side left
pack .before .middle .after
bind .before <Tab> {
   if {!$traverseToMiddle} {
      \fBfocus\fR .after
      break
   }
}
bind .after <Shift-Tab> {
   if {!$traverseToMiddle} {
      \fBfocus\fR .before
      break
   }
}
\fBfocus\fR .before
.CE
.SH KEYWORDS
events, focus, keyboard, top-level, window manager
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/focusNext.n.

8
9
10
11
12
13
14

15
16
17
18
19

20
21
22
23
24
25
26
.TH tk_focusNext n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_focusNext, tk_focusPrev, tk_focusFollowsMouse \- Utility procedures for managing the input focus.
.SH SYNOPSIS

\fBtk_focusNext \fIwindow\fR
.sp
\fBtk_focusPrev \fIwindow\fR
.sp
\fBtk_focusFollowsMouse\fR

.BE
.SH DESCRIPTION
.PP
\fBtk_focusNext\fR is a utility procedure used for keyboard traversal.
It returns the
.QW next
window after \fIwindow\fR in focus order. The focus order is determined by







>

<

<

>







8
9
10
11
12
13
14
15
16

17

18
19
20
21
22
23
24
25
26
.TH tk_focusNext n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_focusNext, tk_focusPrev, tk_focusFollowsMouse \- Utility procedures for managing the input focus.
.SH SYNOPSIS
.nf
\fBtk_focusNext \fIwindow\fR

\fBtk_focusPrev \fIwindow\fR

\fBtk_focusFollowsMouse\fR
.fi
.BE
.SH DESCRIPTION
.PP
\fBtk_focusNext\fR is a utility procedure used for keyboard traversal.
It returns the
.QW next
window after \fIwindow\fR in focus order. The focus order is determined by
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
\fBtk_focusFollowsMouse\fR changes the focus model for the application
to an implicit one where the window under the mouse gets the focus.
After this procedure is called, whenever the mouse enters a window
Tk will automatically give it the input focus.
The \fBfocus\fR command may be used to move the focus to a window
other than the one under the mouse, but as soon as the mouse moves
into a new window the focus will jump to that window.

Note: at present there is no built-in support for returning the
application to an explicit focus model;  to do this you will have
to write a script that deletes the bindings created by
\fBtk_focusFollowsMouse\fR.
.SH KEYWORDS
focus, keyboard traversal, top-level
'\" Local Variables:
'\" mode: nroff
'\" End:







>
|








45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
\fBtk_focusFollowsMouse\fR changes the focus model for the application
to an implicit one where the window under the mouse gets the focus.
After this procedure is called, whenever the mouse enters a window
Tk will automatically give it the input focus.
The \fBfocus\fR command may be used to move the focus to a window
other than the one under the mouse, but as soon as the mouse moves
into a new window the focus will jump to that window.
.PP
Note that at present there is no built-in support for returning the
application to an explicit focus model;  to do this you will have
to write a script that deletes the bindings created by
\fBtk_focusFollowsMouse\fR.
.SH KEYWORDS
focus, keyboard traversal, top-level
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/font.n.

16
17
18
19
20
21
22

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

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

61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78

79
80
81
82
83
84

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

99
100
101
102
103
104
105
106
107
108
109

110
111

112
113
114
115
116
117
118
.BE
.SH DESCRIPTION
.PP
The \fBfont\fR command provides several facilities for dealing with
fonts, such as defining named fonts and inspecting the actual attributes of
a font.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:

.TP
\fBfont actual \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR? ?\fB\-\|\-\fR? ?\fIchar\fR?
.
Returns information about the actual attributes that are obtained when
\fIfont\fR is used on \fIwindow\fR's display; the actual attributes obtained
may differ from the attributes requested due to platform-dependent
limitations, such as the availability of font families and point sizes.
\fIfont\fR is a font description; see \fBFONT DESCRIPTIONS\fR below.  If the
\fIwindow\fR argument is omitted, it defaults to the main window.  If
\fIoption\fR is specified, returns the value of that attribute; if it is
omitted, the return value is a list of all the attributes and their values.
See \fBFONT OPTIONS\fR below for a list of the possible attributes.  If the
\fIchar\fR argument is supplied, it must be a single character. The font
attributes returned will be those of the specific font used to render
that character, which will be different from the base font if the base
font does not contain the given character.  If \fIchar\fR may be a hyphen, it
should be preceded by \fB\-\|\-\fR to distinguish it from a misspelled
\fIoption\fR.

.TP
\fBfont configure \fIfontname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the desired attributes for the named font called
\fIfontname\fR.  If no \fIoption\fR is specified, returns a list describing
all the options and their values for \fIfontname\fR.  If a single \fIoption\fR
is specified with no \fIvalue\fR, then returns the current value of that
attribute.  If one or more \fIoption\fR\-\fIvalue\fR pairs are specified,
then the command modifies the given named font to have the given values; in
this case, all widgets using that font will redisplay themselves using the
new attributes for the font.  See \fBFONT OPTIONS\fR below for a list of the
possible attributes.
.RS
.PP
Note that on Aqua/Mac OS X, the system fonts (see
\fBPLATFORM SPECIFIC FONTS\fR below) may not be actually altered because they
are implemented by the system theme. To achieve the effect of modification,
use \fBfont actual\fR to get their configuration and \fBfont create\fR to
synthesize a copy of the font which can be modified.
.RE

.TP
\fBfont create\fR ?\fIfontname\fR? ?\fIoption value ...\fR?
.
Creates a new named font and returns its name.  \fIfontname\fR specifies the
name for the font; if it is omitted, then Tk generates a new name of the
form \fBfont\fIx\fR, where \fIx\fR is an integer.  There may be any number
of \fIoption\fR\-\fIvalue\fR pairs, which provide the desired attributes for
the new named font.  See \fBFONT OPTIONS\fR below for a list of the possible
attributes.

.TP
\fBfont delete\fR \fIfontname\fR ?\fIfontname ...\fR?
.
Delete the specified named fonts.  If there are widgets using the named font,
the named font will not actually be deleted until all the instances are
released.  Those widgets will continue to display using the last known values
for the named font.  If a deleted named font is subsequently recreated with
another call to \fBfont create\fR, the widgets will use the new named font
and redisplay themselves using the new attributes of that font.

.TP
\fBfont families\fR ?\fB\-displayof \fIwindow\fR?
.
The return value is a list of the case-insensitive names of all font families
that exist on \fIwindow\fR's display.  If the \fIwindow\fR argument is
omitted, it defaults to the main window.

.TP
\fBfont measure \fIfont\fR ?\fB\-displayof \fIwindow\fR? \fItext\fR
.
Measures the amount of space the string \fItext\fR would use in the given
\fIfont\fR when displayed in \fIwindow\fR.  \fIfont\fR is a font description;
see \fBFONT DESCRIPTIONS\fR below.  If the \fIwindow\fR argument is
omitted, it
defaults to the main window.  The return value is the total width in pixels
of \fItext\fR, not including the extra pixels used by highly exaggerated
characters such as cursive
.QW f .
If the string contains newlines or tabs,
those characters are not expanded or treated specially when measuring the
string.

.TP
\fBfont metrics \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR?
.
Returns information about the metrics (the font-specific data), for
\fIfont\fR when it is used on \fIwindow\fR's display.  \fIfont\fR is a font
description; see \fBFONT DESCRIPTIONS\fR below.  If the \fIwindow\fR
argument is
omitted, it defaults to the main window.  If \fIoption\fR is specified,
returns the value of that metric; if it is omitted, the return value is a
list of all the metrics and their values.  See \fBFONT METRICS\fR
below for a list of the possible metrics.

.TP
\fBfont names\fR

The return value is a list of all the named fonts that are currently defined.
.SH "FONT DESCRIPTIONS"
.PP
The following formats are accepted as a font description anywhere
\fIfont\fR is specified as an argument above; these same forms are also
permitted when specifying the \fB\-font\fR option for widgets.
.TP







>


















>




















>









>

|







>






>














>











>


>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
.BE
.SH DESCRIPTION
.PP
The \fBfont\fR command provides several facilities for dealing with
fonts, such as defining named fonts and inspecting the actual attributes of
a font.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:
.\" METHOD: actual
.TP
\fBfont actual \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR? ?\fB\-\|\-\fR? ?\fIchar\fR?
.
Returns information about the actual attributes that are obtained when
\fIfont\fR is used on \fIwindow\fR's display; the actual attributes obtained
may differ from the attributes requested due to platform-dependent
limitations, such as the availability of font families and point sizes.
\fIfont\fR is a font description; see \fBFONT DESCRIPTIONS\fR below.  If the
\fIwindow\fR argument is omitted, it defaults to the main window.  If
\fIoption\fR is specified, returns the value of that attribute; if it is
omitted, the return value is a list of all the attributes and their values.
See \fBFONT OPTIONS\fR below for a list of the possible attributes.  If the
\fIchar\fR argument is supplied, it must be a single character. The font
attributes returned will be those of the specific font used to render
that character, which will be different from the base font if the base
font does not contain the given character.  If \fIchar\fR may be a hyphen, it
should be preceded by \fB\-\|\-\fR to distinguish it from a misspelled
\fIoption\fR.
.\" METHOD: configure
.TP
\fBfont configure \fIfontname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the desired attributes for the named font called
\fIfontname\fR.  If no \fIoption\fR is specified, returns a list describing
all the options and their values for \fIfontname\fR.  If a single \fIoption\fR
is specified with no \fIvalue\fR, then returns the current value of that
attribute.  If one or more \fIoption\fR\-\fIvalue\fR pairs are specified,
then the command modifies the given named font to have the given values; in
this case, all widgets using that font will redisplay themselves using the
new attributes for the font.  See \fBFONT OPTIONS\fR below for a list of the
possible attributes.
.RS
.PP
Note that on Aqua/Mac OS X, the system fonts (see
\fBPLATFORM SPECIFIC FONTS\fR below) may not be actually altered because they
are implemented by the system theme. To achieve the effect of modification,
use \fBfont actual\fR to get their configuration and \fBfont create\fR to
synthesize a copy of the font which can be modified.
.RE
.\" METHOD: create
.TP
\fBfont create\fR ?\fIfontname\fR? ?\fIoption value ...\fR?
.
Creates a new named font and returns its name.  \fIfontname\fR specifies the
name for the font; if it is omitted, then Tk generates a new name of the
form \fBfont\fIx\fR, where \fIx\fR is an integer.  There may be any number
of \fIoption\fR\-\fIvalue\fR pairs, which provide the desired attributes for
the new named font.  See \fBFONT OPTIONS\fR below for a list of the possible
attributes.
.\" METHOD: delete
.TP
\fBfont delete\fI fontname\fR ?\fIfontname ...\fR?
.
Delete the specified named fonts.  If there are widgets using the named font,
the named font will not actually be deleted until all the instances are
released.  Those widgets will continue to display using the last known values
for the named font.  If a deleted named font is subsequently recreated with
another call to \fBfont create\fR, the widgets will use the new named font
and redisplay themselves using the new attributes of that font.
.\" METHOD: families
.TP
\fBfont families\fR ?\fB\-displayof \fIwindow\fR?
.
The return value is a list of the case-insensitive names of all font families
that exist on \fIwindow\fR's display.  If the \fIwindow\fR argument is
omitted, it defaults to the main window.
.\" METHOD: measure
.TP
\fBfont measure \fIfont\fR ?\fB\-displayof \fIwindow\fR? \fItext\fR
.
Measures the amount of space the string \fItext\fR would use in the given
\fIfont\fR when displayed in \fIwindow\fR.  \fIfont\fR is a font description;
see \fBFONT DESCRIPTIONS\fR below.  If the \fIwindow\fR argument is
omitted, it
defaults to the main window.  The return value is the total width in pixels
of \fItext\fR, not including the extra pixels used by highly exaggerated
characters such as cursive
.QW f .
If the string contains newlines or tabs,
those characters are not expanded or treated specially when measuring the
string.
.\" METHOD: metrics
.TP
\fBfont metrics \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR?
.
Returns information about the metrics (the font-specific data), for
\fIfont\fR when it is used on \fIwindow\fR's display.  \fIfont\fR is a font
description; see \fBFONT DESCRIPTIONS\fR below.  If the \fIwindow\fR
argument is
omitted, it defaults to the main window.  If \fIoption\fR is specified,
returns the value of that metric; if it is omitted, the return value is a
list of all the metrics and their values.  See \fBFONT METRICS\fR
below for a list of the possible metrics.
.\" METHOD: names
.TP
\fBfont names\fR
.
The return value is a list of all the named fonts that are currently defined.
.SH "FONT DESCRIPTIONS"
.PP
The following formats are accepted as a font description anywhere
\fIfont\fR is specified as an argument above; these same forms are also
permitted when specifying the \fB\-font\fR option for widgets.
.TP
196
197
198
199
200
201
202

203
204
205
206
207

208
209
210
211
212

213
214
215
216
217
218
219

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

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

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

273
274
275
276
277
278
279

280
281

282
283
284
285
286
287

288
289

290
291

292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348

349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
font.  In the following definitions, the
.QW baseline
of a font is the
horizontal line where the bottom of most letters line up; certain letters,
such as lower-case
.QW g
stick below the baseline.

.TP
\fB\-ascent        \0\fR
.
The amount in pixels that the tallest letter sticks up above the baseline of
the font, plus any extra blank space added by the designer of the font.

.TP
\fB\-descent       \0\fR
.
The largest amount in pixels that any letter sticks down below the baseline
of the font, plus any extra blank space added by the designer of the font.

.TP
\fB\-linespace\fR
.
Returns how far apart vertically in pixels two lines of text using the same
font should be placed so that none of the characters in one line overlap any
of the characters in the other line.  This is generally the sum of the ascent
above the baseline line plus the descent below the baseline.

.TP
\fB\-fixed          \0\fR
.
Returns a boolean flag that is
.QW \fB1\fR
if this is a fixed-width font,
where each normal character is the same width as all the other
characters, or is
.QW \fB0\fR
if this is a proportionally-spaced font, where
individual characters have different widths.  The widths of control
characters, tab characters, and other non-printing characters are not
included when calculating this value.
.SH "FONT OPTIONS"
.PP
The following options are supported on all platforms, and are used when
constructing a named font or when specifying a font using style [5] as
above:

.TP
\fB\-family \fIname\fR
.
The case-insensitive font family name.  Tk guarantees to support the font
families named \fBCourier\fR (a monospaced
.QW typewriter
font), \fBTimes\fR (a serifed
.QW newspaper
font), and \fBHelvetica\fR (a sans-serif
.QW European
font).  The most closely matching native font family will
automatically be substituted when one of the above font families is used.
The \fIname\fR may also be the name of a native, platform-specific font
family; in that case it will work as desired on one platform but may not
display correctly on other platforms.  If the family is unspecified or
unrecognized, a platform-specific default font will be chosen.

.TP
\fB\-size \fIsize\fR
.
The desired size of the font.  If the \fIsize\fR argument is a positive
number, it is interpreted as a size in points.  If \fIsize\fR is a negative
number, its absolute value is interpreted as a size in pixels.  If a
font cannot be displayed at the specified size, a nearby size will be
chosen.  If \fIsize\fR is unspecified or zero, a platform-dependent default
size will be chosen.
.RS
.PP
Sizes should normally be specified in points so the application will remain
the same ruler size on the screen, even when changing screen resolutions or
moving scripts across platforms.  However, specifying pixels is useful in
certain circumstances such as when a piece of text must line up with respect
to a fixed-size bitmap.  The mapping between points and pixels is set when
the application starts, based on properties of the installed monitor, but it
can be overridden by calling the \fBtk scaling\fR command.
.RE

.TP
\fB\-weight \fIweight\fR
.
The nominal thickness of the characters in the font.  The value
\fBnormal\fR specifies a normal weight font, while \fBbold\fR specifies a
bold font.  The closest available weight to the one specified will
be chosen.  The default weight is \fBnormal\fR.

.TP
\fB\-slant \fIslant\fR

The amount the characters in the font are slanted away from the
vertical.  Valid values for slant are \fBroman\fR and \fBitalic\fR.
A roman font is the normal, upright appearance of a font, while
an italic font is one that is tilted some number of degrees from upright.
The closest available slant to the one specified will be chosen.
The default slant is \fBroman\fR.

.TP
\fB\-underline \fIboolean\fR

The value is a boolean flag that specifies whether characters in this
font should be underlined.  The default value for underline is \fBfalse\fR.

.TP
\fB\-overstrike \fIboolean\fR

The value is a boolean flag that specifies whether a horizontal line should
be drawn through the middle of characters in this font.  The default value
for overstrike is \fBfalse\fR.
.SH "STANDARD FONTS"
.PP
The following named fonts are supported on all systems, and default to values
that match appropriate system defaults.
.TP
\fBTkDefaultFont\fR
.
This font is the default for all GUI items not otherwise specified.
.TP
\fBTkTextFont\fR
.
This font should be used for user text in entry widgets, listboxes etc.
.TP
\fBTkFixedFont\fR
.
This font is the standard fixed-width font.
.TP
\fBTkMenuFont\fR
.
This font is used for menu items.
.TP
\fBTkHeadingFont\fR
.
This font should be used for column headings in lists and tables.
.TP
\fBTkCaptionFont\fR
.
This font should be used for window and dialog caption bars.
.TP
\fBTkSmallCaptionFont\fR
.
This font should be used for captions on contained windows or tool dialogs.
.TP
\fBTkIconFont\fR
.
This font should be used for icon captions.
.TP
\fBTkTooltipFont\fR
.
This font should be used for tooltip windows (transient information windows).
.LP
It is \fInot\fR advised to change these fonts, as they may be modified by Tk
itself in response to system changes. Instead, make a copy of the font and
modify that.
.SH "PLATFORM SPECIFIC FONTS"
.PP
The following system fonts are supported:
.TP
\fBX Windows\fR

All valid X font names, including those listed by xlsfonts(1), are available.
.TP
\fBMS Windows\fR

The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBansi\fR	\fBdevice\fR
\fBsystemfixed\fR	\fBansifixed\fR	\fBoemfixed\fR
.DE
.RE
.TP
\fBMac OS X\fR

The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBapplication\fR	\fBmenu\fR
.DE







>

|



>

|



>







>

|
















>
















>



















>







>


>






>


>


>


>







<
|
<

<
|
<

<
|
<

<
|
<

<
|
<

<
|
<

<
|
<

<
|
<

<
|
<










>



>











>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
font.  In the following definitions, the
.QW baseline
of a font is the
horizontal line where the bottom of most letters line up; certain letters,
such as lower-case
.QW g
stick below the baseline.
.\" OPTION: -ascent
.TP
\fB\-ascent\fR
.
The amount in pixels that the tallest letter sticks up above the baseline of
the font, plus any extra blank space added by the designer of the font.
.\" OPTION: -descent
.TP
\fB\-descent\fR
.
The largest amount in pixels that any letter sticks down below the baseline
of the font, plus any extra blank space added by the designer of the font.
.\" OPTION: -linespace
.TP
\fB\-linespace\fR
.
Returns how far apart vertically in pixels two lines of text using the same
font should be placed so that none of the characters in one line overlap any
of the characters in the other line.  This is generally the sum of the ascent
above the baseline line plus the descent below the baseline.
.\" OPTION: -fixed
.TP
\fB\-fixed\fR
.
Returns a boolean flag that is
.QW \fB1\fR
if this is a fixed-width font,
where each normal character is the same width as all the other
characters, or is
.QW \fB0\fR
if this is a proportionally-spaced font, where
individual characters have different widths.  The widths of control
characters, tab characters, and other non-printing characters are not
included when calculating this value.
.SH "FONT OPTIONS"
.PP
The following options are supported on all platforms, and are used when
constructing a named font or when specifying a font using style [5] as
above:
.\" OPTION: -family
.TP
\fB\-family \fIname\fR
.
The case-insensitive font family name.  Tk guarantees to support the font
families named \fBCourier\fR (a monospaced
.QW typewriter
font), \fBTimes\fR (a serifed
.QW newspaper
font), and \fBHelvetica\fR (a sans-serif
.QW European
font).  The most closely matching native font family will
automatically be substituted when one of the above font families is used.
The \fIname\fR may also be the name of a native, platform-specific font
family; in that case it will work as desired on one platform but may not
display correctly on other platforms.  If the family is unspecified or
unrecognized, a platform-specific default font will be chosen.
.\" OPTION: -size
.TP
\fB\-size \fIsize\fR
.
The desired size of the font.  If the \fIsize\fR argument is a positive
number, it is interpreted as a size in points.  If \fIsize\fR is a negative
number, its absolute value is interpreted as a size in pixels.  If a
font cannot be displayed at the specified size, a nearby size will be
chosen.  If \fIsize\fR is unspecified or zero, a platform-dependent default
size will be chosen.
.RS
.PP
Sizes should normally be specified in points so the application will remain
the same ruler size on the screen, even when changing screen resolutions or
moving scripts across platforms.  However, specifying pixels is useful in
certain circumstances such as when a piece of text must line up with respect
to a fixed-size bitmap.  The mapping between points and pixels is set when
the application starts, based on properties of the installed monitor, but it
can be overridden by calling the \fBtk scaling\fR command.
.RE
.\" OPTION: -weight
.TP
\fB\-weight \fIweight\fR
.
The nominal thickness of the characters in the font.  The value
\fBnormal\fR specifies a normal weight font, while \fBbold\fR specifies a
bold font.  The closest available weight to the one specified will
be chosen.  The default weight is \fBnormal\fR.
.\" OPTION: -slant
.TP
\fB\-slant \fIslant\fR
.
The amount the characters in the font are slanted away from the
vertical.  Valid values for slant are \fBroman\fR and \fBitalic\fR.
A roman font is the normal, upright appearance of a font, while
an italic font is one that is tilted some number of degrees from upright.
The closest available slant to the one specified will be chosen.
The default slant is \fBroman\fR.
.\" OPTION: -underline
.TP
\fB\-underline \fIboolean\fR
.
The value is a boolean flag that specifies whether characters in this
font should be underlined.  The default value for underline is \fBfalse\fR.
.\" OPTION: -overstrike
.TP
\fB\-overstrike \fIboolean\fR
.
The value is a boolean flag that specifies whether a horizontal line should
be drawn through the middle of characters in this font.  The default value
for overstrike is \fBfalse\fR.
.SH "STANDARD FONTS"
.PP
The following named fonts are supported on all systems, and default to values
that match appropriate system defaults.

.IP \fBTkDefaultFont\fR

This font is the default for all GUI items not otherwise specified.

.IP \fBTkTextFont\fR

This font should be used for user text in entry widgets, listboxes etc.

.IP \fBTkFixedFont\fR

This font is the standard fixed-width font.

.IP \fBTkMenuFont\fR

This font is used for menu items.

.IP \fBTkHeadingFont\fR

This font should be used for column headings in lists and tables.

.IP \fBTkCaptionFont\fR

This font should be used for window and dialog caption bars.

.IP \fBTkSmallCaptionFont\fR

This font should be used for captions on contained windows or tool dialogs.

.IP \fBTkIconFont\fR

This font should be used for icon captions.

.IP \fBTkTooltipFont\fR

This font should be used for tooltip windows (transient information windows).
.LP
It is \fInot\fR advised to change these fonts, as they may be modified by Tk
itself in response to system changes. Instead, make a copy of the font and
modify that.
.SH "PLATFORM SPECIFIC FONTS"
.PP
The following system fonts are supported:
.TP
\fBX Windows\fR
.
All valid X font names, including those listed by xlsfonts(1), are available.
.TP
\fBMS Windows\fR
.
The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBansi\fR	\fBdevice\fR
\fBsystemfixed\fR	\fBansifixed\fR	\fBoemfixed\fR
.DE
.RE
.TP
\fBMac OS X\fR
.
The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBapplication\fR	\fBmenu\fR
.DE
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
.DE
.RE
.SH EXAMPLE
.PP
Fill a text widget with lots of font demonstrators, one for every font
family installed on your system:
.CS
pack [text .t \-wrap none] \-fill both \-expand 1
set count 0
set tabwidth 0
foreach family [lsort \-dictionary [\fBfont families\fR]] {
    .t tag configure f[incr count] \-font [list $family 10]
    .t insert end ${family}:\\t {} \e
            "This is a simple sampler\en" f$count
    set w [\fBfont measure\fR [.t cget \-font] ${family}:]
    if {$w+5 > $tabwidth} {
        set tabwidth [expr {$w+5}]
        .t configure \-tabs $tabwidth
    }
}
.CE
.SH "SEE ALSO"
options(n)
.SH KEYWORDS
font
'\" Local Variables:
'\" mode: nroff
'\" End:







|


|
|
|

|
|
|
|










389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
.DE
.RE
.SH EXAMPLE
.PP
Fill a text widget with lots of font demonstrators, one for every font
family installed on your system:
.CS
pack [text .t -wrap none] -fill both -expand 1
set count 0
set tabwidth 0
foreach family [lsort -dictionary [\fBfont families\fR]] {
    .t tag configure f[incr count] -font [list $family 10]
    .t insert end ${family}:\et {} \e
            "This is a simple sampler\en" f$count
    set w [\fBfont measure\fR [.t cget -font] ${family}:]
    if {$w + 5 > $tabwidth} {
        set tabwidth [expr {$w + 5}]
        .t configure -tabs $tabwidth
    }
}
.CE
.SH "SEE ALSO"
options(n)
.SH KEYWORDS
font
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/fontchooser.n.

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

14
15
16
17
18

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

33
34
35
36
37

38
39
40
41
42

43
44
45
46
47
48
49

50
51

52
53
54

55
56

57
58

59
60

61
62
63
64
65

66
67

68
69
70
71
72
73
74
75
76

77
78

79
80
81
82
83
84
85

86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
'\"
'\" 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 ...\fR?
.sp
\fBtk fontchooser\fR \fBshow\fR
.sp
\fBtk fontchooser\fR \fBhide\fR

.BE
.SH DESCRIPTION
.PP
The \fBtk fontchooser\fR command controls the Tk font selection dialog. It uses
the native platform font selection dialog where available, or a dialog
implemented in Tcl otherwise.
.PP
Unlike most of the other Tk dialog commands, \fBtk fontchooser\fR does not
return an immediate result, as on some platforms (Mac OS X) the standard font
dialog is modeless while on others (Windows) it is modal. To accommodate this
difference, all user interaction with the dialog will be communicated to the
caller via callbacks or virtual events.
.PP
The \fBtk fontchooser\fR command can have one of the following forms:

.TP
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value ...\fR?
.
Set or query one or more of the configurations options below (analogous to Tk
widget configuration).

.TP
\fBtk fontchooser\fR \fBshow\fR
.
Show the font selection dialog. Depending on the platform, may return
immediately or only once the dialog has been withdrawn.

.TP
\fBtk fontchooser\fR \fBhide\fR
.
Hide the font selection dialog if it is visible and cause any pending
\fBtk fontchooser\fR \fBshow\fR command to return.
.PP
.SH "CONFIGURATION OPTIONS"

.TP
\fB\-parent\fR

Specifies/returns the logical parent window of the font selection dialog
(similar to the \fB\-parent\fR option to other dialogs). The font selection
dialog is hidden if it is visible when the parent window is destroyed.

.TP
\fB\-title\fR

Specifies/returns the title of the dialog. Has no effect on platforms where the
font selection dialog does not support titles.

.TP
\fB\-font\fR

Specifies/returns the font that is currently selected in the dialog if it is
visible, or that will be initially selected when the dialog is shown (if
supported by the platform). Can be set to the empty string to indicate that no
font should be selected. Fonts can be specified in any form given by the "FONT
DESCRIPTION" section in the \fBfont\fR manual page.

.TP
\fB\-command\fR

Specifies/returns the command prefix to be called when a font selection has
been made by the user. The command prefix is evaluated at the global level
after having the specification of the selected font appended. On platforms
where the font selection dialog offers the user control of further font
attributes (such as color), additional key/value pairs may be appended before
evaluation. Can be set to the empty string to indicate that no callback should
be invoked. Fonts are specified by a list of form [3] of the "FONT DESCRIPTION"
section in the \fBfont\fR manual page (i.e. a list of the form
\fI{family size style ?style ...?}\fR).

.TP
\fB\-visible\fR

Read-only option that returns a boolean indicating whether the font selection
dialog is currently visible. Attempting to set this option results in an error.

.PP
.SH "VIRTUAL EVENTS"
.TP
\fB<<TkFontchooserVisibility>>\fR

Sent to the dialog parent whenever the visibility of the font selection dialog
changes, both as a result of user action (e.g. disposing of the dialog via
OK/Cancel button or close box) and of the \fBtk fontchooser\fR
\fBshow\fR/\fBhide\fR commands being called. Binding scripts can determine the
current visibility of the dialog by querying the \fB\-visible\fR configuration
option.
.TP
\fB<<TkFontchooserFontChanged>>\fR

Sent to the dialog parent whenever the font selection dialog is visible and the
selected font changes, both as a result of user action and of the \fB\-font\fR
configuration option being set. Binding scripts can determine the currently
selected font by querying the \fB\-font\fR configuration option.
.PP
.SH NOTES
.PP













>

<

<

>














>





>





>







>


>



>


>


>


>





>


>









>


>







>








>







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

16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
'\"
'\" 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
.nf
\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value ...\fR?

\fBtk fontchooser\fR \fBshow\fR

\fBtk fontchooser\fR \fBhide\fR
.fi
.BE
.SH DESCRIPTION
.PP
The \fBtk fontchooser\fR command controls the Tk font selection dialog. It uses
the native platform font selection dialog where available, or a dialog
implemented in Tcl otherwise.
.PP
Unlike most of the other Tk dialog commands, \fBtk fontchooser\fR does not
return an immediate result, as on some platforms (Mac OS X) the standard font
dialog is modeless while on others (Windows) it is modal. To accommodate this
difference, all user interaction with the dialog will be communicated to the
caller via callbacks or virtual events.
.PP
The \fBtk fontchooser\fR command can have one of the following forms:
.\" METHOD: configure
.TP
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value ...\fR?
.
Set or query one or more of the configurations options below (analogous to Tk
widget configuration).
.\" METHOD: show
.TP
\fBtk fontchooser\fR \fBshow\fR
.
Show the font selection dialog. Depending on the platform, may return
immediately or only once the dialog has been withdrawn.
.\" METHOD: hide
.TP
\fBtk fontchooser\fR \fBhide\fR
.
Hide the font selection dialog if it is visible and cause any pending
\fBtk fontchooser\fR \fBshow\fR command to return.
.PP
.SH "CONFIGURATION OPTIONS"
.\" OPTION: -parent
.TP
\fB\-parent\fR
.
Specifies/returns the logical parent window of the font selection dialog
(similar to the \fB\-parent\fR option to other dialogs). The font selection
dialog is hidden if it is visible when the parent window is destroyed.
.\" OPTION: -title
.TP
\fB\-title\fR
.
Specifies/returns the title of the dialog. Has no effect on platforms where the
font selection dialog does not support titles.
.\" OPTION: -font
.TP
\fB\-font\fR
.
Specifies/returns the font that is currently selected in the dialog if it is
visible, or that will be initially selected when the dialog is shown (if
supported by the platform). Can be set to the empty string to indicate that no
font should be selected. Fonts can be specified in any form given by the "FONT
DESCRIPTION" section in the \fBfont\fR manual page.
.\" OPTION: -command
.TP
\fB\-command\fR
.
Specifies/returns the command prefix to be called when a font selection has
been made by the user. The command prefix is evaluated at the global level
after having the specification of the selected font appended. On platforms
where the font selection dialog offers the user control of further font
attributes (such as color), additional key/value pairs may be appended before
evaluation. Can be set to the empty string to indicate that no callback should
be invoked. Fonts are specified by a list of form [3] of the "FONT DESCRIPTION"
section in the \fBfont\fR manual page (i.e. a list of the form
\fI{family size style ?style ...?}\fR).
.\" OPTION: -visible
.TP
\fB\-visible\fR
.
Read-only option that returns a boolean indicating whether the font selection
dialog is currently visible. Attempting to set this option results in an error.

.PP
.SH "VIRTUAL EVENTS"
.TP
\fB<<TkFontchooserVisibility>>\fR
.
Sent to the dialog parent whenever the visibility of the font selection dialog
changes, both as a result of user action (e.g. disposing of the dialog via
OK/Cancel button or close box) and of the \fBtk fontchooser\fR
\fBshow\fR/\fBhide\fR commands being called. Binding scripts can determine the
current visibility of the dialog by querying the \fB\-visible\fR configuration
option.
.TP
\fB<<TkFontchooserFontChanged>>\fR
.
Sent to the dialog parent whenever the font selection dialog is visible and the
selected font changes, both as a result of user action and of the \fB\-font\fR
configuration option being set. Binding scripts can determine the currently
selected font by querying the \fB\-font\fR configuration option.
.PP
.SH NOTES
.PP
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
to ensure its selected font matches the new value of the named font.
.PP
.SH EXAMPLE
.PP
.CS
proc fontchooserDemo {} {
    wm title . "Font Chooser Demo"
    \fBtk fontchooser\fR \fBconfigure\fR \-parent .
    button .b \-command fontchooserToggle \-takefocus 0
    fontchooserVisibility .b
    bind . \fB<<TkFontchooserVisibility>>\fR \\
            [list fontchooserVisibility .b]
    foreach w {.t1 .t2} {
        text $w \-width 20 \-height 4 \-borderwidth 1 \-relief solid
        bind $w <FocusIn> [list fontchooserFocus $w]
        $w insert end "Text Widget $w"
    }
    .t1 configure \-font {Courier 14}
    .t2 configure \-font {Times 16}
    pack .b .t1 .t2; focus .t1
}
proc fontchooserToggle {} {
    \fBtk fontchooser\fR [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR \-visible] ?
            "\fBhide\fR" : "\fBshow\fR"}]
}
proc fontchooserVisibility {w} {
    $w configure \-text [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR \-visible] ?
            "Hide Font Dialog" : "Show Font Dialog"}]
}
proc fontchooserFocus {w} {
    \fBtk fontchooser\fR \fBconfigure\fR \-font [$w cget \-font] \\
            \-command [list fontchooserFontSelection $w]
}
proc fontchooserFontSelection {w font args} {
    $w configure \-font [font actual $font]
}
fontchooserDemo
.CE
.SH "SEE ALSO"
font(n), tk(n)
.SH KEYWORDS
dialog, font, font selection, font chooser, font panel
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|

|


|



|
|




|



|
|



|
|


|










150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
to ensure its selected font matches the new value of the named font.
.PP
.SH EXAMPLE
.PP
.CS
proc fontchooserDemo {} {
    wm title . "Font Chooser Demo"
    \fBtk fontchooser\fR \fBconfigure\fR -parent .
    button .b -command fontchooserToggle -takefocus 0
    fontchooserVisibility .b
    bind . \fB<<TkFontchooserVisibility>>\fR \e
            [list fontchooserVisibility .b]
    foreach w {.t1 .t2} {
        text $w -width 20 -height 4 -borderwidth 1 -relief solid
        bind $w <FocusIn> [list fontchooserFocus $w]
        $w insert end "Text Widget $w"
    }
    .t1 configure -font {Courier 14}
    .t2 configure -font {Times 16}
    pack .b .t1 .t2; focus .t1
}
proc fontchooserToggle {} {
    \fBtk fontchooser\fR [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR -visible] ?
            "\fBhide\fR" : "\fBshow\fR"}]
}
proc fontchooserVisibility {w} {
    $w configure -text [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR -visible] ?
            "Hide Font Dialog" : "Show Font Dialog"}]
}
proc fontchooserFocus {w} {
    \fBtk fontchooser\fR \fBconfigure\fR -font [$w cget -font] \e
            -command [list fontchooserFontSelection $w]
}
proc fontchooserFontSelection {w font args} {
    $w configure -font [font actual $font]
}
fontchooserDemo
.CE
.SH "SEE ALSO"
font(n), tk(n)
.SH KEYWORDS
dialog, font, font selection, font chooser, font panel
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/frame.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH frame n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
frame \- Create and manipulate 'frame' simple container widgets
.SH SYNOPSIS
\fBframe\fR \fIpathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH frame n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
frame \- Create and manipulate 'frame' simple container widgets
.SH SYNOPSIS
\fBframe\fI pathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
123
124
125
126
127
128
129

130
131
132
133
134
135
136

137
138
139
140
141
142
143
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the frame widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified







>

|





>







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
\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:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBframe\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified

Changes to doc/getOpenFile.n.

30
31
32
33
34
35
36

37
38

39
40
41
42
43

44
45

46
47
48
49

50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81

82
83
84
85

86
87
88
89
90

91
92
93
94

95
96
97
98
99
100

101
102
103
104
105

106
107
108
109
110
111
112
113
114
The \fBtk_getSaveFile\fR command is usually associated with the \fBSave
as\fR command in the \fBFile\fR menu. If the user enters a file that
already exists, the dialog box prompts the user for confirmation
whether the existing file should be overwritten or not.
.PP
The following \fIoption\-value\fR pairs are possible as command line
arguments to these two commands:

.TP
\fB\-command\fR \fIstring\fR

Specifies the prefix of a Tcl command to invoke when the user closes the
dialog after having selected an item. This callback is not called if the
user cancelled the dialog. The actual command consists of \fIstring\fR
followed by a space and the value selected by the user in the dialog. This
is only available on Mac OS X.

.TP
\fB\-confirmoverwrite\fR \fIboolean\fR

Configures how the Save dialog reacts when the selected file already
exists, and saving would overwrite it.  A true value requests a
confirmation dialog be presented to the user.  A false value requests
that the overwrite take place without confirmation.  Default value is true.

.TP
\fB\-defaultextension\fR \fIextension\fR
.
Specifies a string that will be appended to the filename if the user
enters a filename without an extension. The default value is the empty
string, which means no extension will be appended to the filename in
any case. This option is ignored on Mac OS X, which
does not require extensions to filenames,
and the UNIX implementation guesses reasonable values for this from
the \fB\-filetypes\fR option when this is not supplied.

.TP
\fB\-filetypes\fR \fIfilePatternList\fR
.
If a \fBFile types\fR listbox exists in the file dialog on the particular
platform, this option gives the \fIfiletype\fRs in this listbox. When
the user choose a filetype in the listbox, only the files of that type
are listed. If this option is unspecified, or if it is set to the
empty list, or if the \fBFile types\fR listbox is not supported by the
particular platform then all files are listed regardless of their
types. See the section \fBSPECIFYING FILE PATTERNS\fR below for a
discussion on the contents of \fIfilePatternList\fR.

.TP
\fB\-initialdir\fR \fIdirectory\fR
.
Specifies that the files in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
the initial directory defaults to the current working directory
on non-Windows systems and on Windows systems prior to Vista.
On Vista and later systems, the initial directory defaults to the last
user-selected directory for the application. If the
parameter specifies a relative path, the return value will convert the
relative path to an absolute path.

.TP
\fB\-initialfile\fR \fIfilename\fR
.
Specifies a filename to be displayed in the dialog when it pops up.

.TP
\fB\-message\fR \fIstring\fR
.
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.

.TP
\fB\-multiple\fR \fIboolean\fR
.
Allows the user to choose multiple files from the Open dialog.

.TP
\fB\-parent\fR \fIwindow\fR
.
Makes \fIwindow\fR the logical parent of the file dialog. The file
dialog is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.

.TP
\fB\-title\fR \fItitleString\fR
.
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title is displayed.

.TP
\fB\-typevariable\fR \fIvariableName\fR
.
The global variable \fIvariableName\fR is used to preselect which filter is
used from \fIfilterList\fR when the dialog box is opened and is
updated when the dialog box is closed, to the last selected
filter. The variable is read once at the beginning to select the
appropriate filter. If the variable does not exist, or its value does
not match any filter typename, or is empty (\fB{}\fR), the dialog box







>

|
>





>

|
>




>

|








>

|









>

|









>

|


>

|



>

|


>

|




>

|



>

|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
The \fBtk_getSaveFile\fR command is usually associated with the \fBSave
as\fR command in the \fBFile\fR menu. If the user enters a file that
already exists, the dialog box prompts the user for confirmation
whether the existing file should be overwritten or not.
.PP
The following \fIoption\-value\fR pairs are possible as command line
arguments to these two commands:
.\" OPTION: -command
.TP
\fB\-command\fI string\fR
.
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog after having selected an item. This callback is not called if the
user cancelled the dialog. The actual command consists of \fIstring\fR
followed by a space and the value selected by the user in the dialog. This
is only available on Mac OS X.
.\" OPTION: -confirmoverwrite
.TP
\fB\-confirmoverwrite\fI boolean\fR
.
Configures how the Save dialog reacts when the selected file already
exists, and saving would overwrite it.  A true value requests a
confirmation dialog be presented to the user.  A false value requests
that the overwrite take place without confirmation.  Default value is true.
.\" OPTION: -defaultextension
.TP
\fB\-defaultextension\fI extension\fR
.
Specifies a string that will be appended to the filename if the user
enters a filename without an extension. The default value is the empty
string, which means no extension will be appended to the filename in
any case. This option is ignored on Mac OS X, which
does not require extensions to filenames,
and the UNIX implementation guesses reasonable values for this from
the \fB\-filetypes\fR option when this is not supplied.
.\" OPTION: -filetypes
.TP
\fB\-filetypes\fI filePatternList\fR
.
If a \fBFile types\fR listbox exists in the file dialog on the particular
platform, this option gives the \fIfiletype\fRs in this listbox. When
the user choose a filetype in the listbox, only the files of that type
are listed. If this option is unspecified, or if it is set to the
empty list, or if the \fBFile types\fR listbox is not supported by the
particular platform then all files are listed regardless of their
types. See the section \fBSPECIFYING FILE PATTERNS\fR below for a
discussion on the contents of \fIfilePatternList\fR.
.\" OPTION: -initialdir
.TP
\fB\-initialdir\fI directory\fR
.
Specifies that the files in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
the initial directory defaults to the current working directory
on non-Windows systems and on Windows systems prior to Vista.
On Vista and later systems, the initial directory defaults to the last
user-selected directory for the application. If the
parameter specifies a relative path, the return value will convert the
relative path to an absolute path.
.\" OPTION: -initialfile
.TP
\fB\-initialfile\fI filename\fR
.
Specifies a filename to be displayed in the dialog when it pops up.
.\" OPTION: -message
.TP
\fB\-message\fI string\fR
.
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
.\" OPTION: -multiple
.TP
\fB\-multiple\fI boolean\fR
.
Allows the user to choose multiple files from the Open dialog.
.\" OPTION: -parent
.TP
\fB\-parent\fI window\fR
.
Makes \fIwindow\fR the logical parent of the file dialog. The file
dialog is displayed on top of its parent window. On Mac OS X, this
turns the file dialog into a sheet attached to the parent window.
.\" OPTION: -title
.TP
\fB\-title\fI titleString\fR
.
Specifies a string to display as the title of the dialog box. If this
option is not specified, then a default title is displayed.
.\" OPTION: -typevariable
.TP
\fB\-typevariable\fI variableName\fR
.
The global variable \fIvariableName\fR is used to preselect which filter is
used from \fIfilterList\fR when the dialog box is opened and is
updated when the dialog box is closed, to the last selected
filter. The variable is read once at the beginning to select the
appropriate filter. If the variable does not exist, or its value does
not match any filter typename, or is empty (\fB{}\fR), the dialog box
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    {{Text Files}       {.txt}        }
    {{TCL Scripts}      {.tcl}        }
    {{C Source Files}   {.c}      TEXT}
    {{GIF Files}        {.gif}        }
    {{GIF Files}        {}        GIFF}
    {{All Files}        *             }
}
set filename [\fBtk_getOpenFile\fR \-filetypes $types]

if {$filename ne ""} {
    # Open the file ...
}
.CE
.SH "SEE ALSO"
tk_chooseDirectory
.SH KEYWORDS
file selection dialog
'\" Local Variables:
'\" mode: nroff
'\" End:







|












201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    {{Text Files}       {.txt}        }
    {{TCL Scripts}      {.tcl}        }
    {{C Source Files}   {.c}      TEXT}
    {{GIF Files}        {.gif}        }
    {{GIF Files}        {}        GIFF}
    {{All Files}        *             }
}
set filename [\fBtk_getOpenFile\fR -filetypes $types]

if {$filename ne ""} {
    # Open the file ...
}
.CE
.SH "SEE ALSO"
tk_chooseDirectory
.SH KEYWORDS
file selection dialog
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/grab.n.

8
9
10
11
12
13
14

15
16
17

18
19
20
21
22
23
24
.TH grab n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grab \- Confine pointer and keyboard events to a window sub-tree
.SH SYNOPSIS

\fBgrab \fR?\fB\-global\fR? \fIwindow\fR
.sp
\fBgrab \fIoption \fR?\fIarg \fR...?

.BE
.SH DESCRIPTION
.PP
This command implements simple pointer and keyboard grabs for Tk.
Tk's grabs are different than the grabs
described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer







>

<

>







8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
.TH grab n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grab \- Confine pointer and keyboard events to a window sub-tree
.SH SYNOPSIS
.nf
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR

\fBgrab \fIoption \fR?\fIarg \fR...?
.fi
.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
79
80
81
82
83
84
85

86

87
88

89
90
91
92
93
94

95
96

97
98

99
100

101
102
103
104
105
106
107

108
109

110
111
112
113
114
115
116
It is possible for different applications on a single display to have
simultaneous local grabs, but only one application can have a global
grab on a given display at once.
.PP
The \fBgrab\fR command can take any of the following forms:
.TP
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR

Same as \fBgrab set\fR, described below.

.TP
\fBgrab current \fR?\fIwindow\fR?

If \fIwindow\fR is specified, returns the name of the current grab
window in this application for \fIwindow\fR's display, or an empty
string if there is no such window.
If \fIwindow\fR is omitted, the command returns a list whose elements
are all of the windows grabbed by this application for all displays,
or an empty string if the application has no grabs.

.TP
\fBgrab release \fIwindow\fR

Releases the grab on \fIwindow\fR if there is one, otherwise does
nothing.  Returns an empty string.

.TP
\fBgrab set \fR?\fB\-global\fR? \fIwindow\fR

Sets a grab on \fIwindow\fR.  If \fB\-global\fR is specified then the
grab is global, otherwise it is local.
If a grab was already in effect for this application on
\fIwindow\fR's display then it is automatically released.
If there is already a grab on \fIwindow\fR and it has the same
global/local form as the requested grab, then the command
does nothing.  Returns an empty string.

.TP
\fBgrab status \fIwindow\fR

Returns \fBnone\fR if no grab is currently set on \fIwindow\fR,
\fBlocal\fR if a local grab is set on \fIwindow\fR, and
\fBglobal\fR if a global grab is set.
.SH WARNING
.PP
It is very easy to use global grabs to render a display completely
unusable (e.g. by setting a grab on a widget which does not respond to







>

>


>






>


>


>


>







>


>







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
It is possible for different applications on a single display to have
simultaneous local grabs, but only one application can have a global
grab on a given display at once.
.PP
The \fBgrab\fR command can take any of the following forms:
.TP
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR
.
Same as \fBgrab set\fR, described below.
.\" METHOD: current
.TP
\fBgrab current \fR?\fIwindow\fR?
.
If \fIwindow\fR is specified, returns the name of the current grab
window in this application for \fIwindow\fR's display, or an empty
string if there is no such window.
If \fIwindow\fR is omitted, the command returns a list whose elements
are all of the windows grabbed by this application for all displays,
or an empty string if the application has no grabs.
.\" METHOD: release
.TP
\fBgrab release \fIwindow\fR
.
Releases the grab on \fIwindow\fR if there is one, otherwise does
nothing.  Returns an empty string.
.\" METHOD: set
.TP
\fBgrab set \fR?\fB\-global\fR? \fIwindow\fR
.
Sets a grab on \fIwindow\fR.  If \fB\-global\fR is specified then the
grab is global, otherwise it is local.
If a grab was already in effect for this application on
\fIwindow\fR's display then it is automatically released.
If there is already a grab on \fIwindow\fR and it has the same
global/local form as the requested grab, then the command
does nothing.  Returns an empty string.
.\" METHOD: status
.TP
\fBgrab status \fIwindow\fR
.
Returns \fBnone\fR if no grab is currently set on \fIwindow\fR,
\fBlocal\fR if a local grab is set on \fIwindow\fR, and
\fBglobal\fR if a global grab is set.
.SH WARNING
.PP
It is very easy to use global grabs to render a display completely
unusable (e.g. by setting a grab on a widget which does not respond to
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
processes, this restriction does not exist.
.SH EXAMPLE
.PP
Set a grab so that only one button may be clicked out of a group.  The
other buttons are unresponsive to the mouse until the middle button is
clicked.
.CS
pack [button .b1 \-text "Click me! #1" \-command {destroy .b1}]
pack [button .b2 \-text "Click me! #2" \-command {destroy .b2}]
pack [button .b3 \-text "Click me! #3" \-command {destroy .b3}]
\fBgrab\fR .b2
.CE
.SH "SEE ALSO"
busy(n)
.SH KEYWORDS
grab, keyboard events, pointer events, window
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|









142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
processes, this restriction does not exist.
.SH EXAMPLE
.PP
Set a grab so that only one button may be clicked out of a group.  The
other buttons are unresponsive to the mouse until the middle button is
clicked.
.CS
pack [button .b1 -text "Click me! #1" -command {destroy .b1}]
pack [button .b2 -text "Click me! #2" -command {destroy .b2}]
pack [button .b3 -text "Click me! #3" -command {destroy .b3}]
\fBgrab\fR .b2
.CE
.SH "SEE ALSO"
busy(n)
.SH KEYWORDS
grab, keyboard events, pointer events, window
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/grid.n.

24
25
26
27
28
29
30

31
32
33
34
35
36

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

50
51
52
53
54
55
56
\fBgrid \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
If the first argument to \fBgrid\fR is suitable as the first window
argument to \fBgrid configure\fR, either a window name (any value
starting with \fB.\fR) or one of the characters \fBx\fR or \fB^\fR
(see the \fBRELATIVE PLACEMENT\fR section below), then the command is
processed in the same way as \fBgrid configure\fR.

.TP
\fBgrid anchor \fIwindow\fR ?\fIanchor\fR?
.
The anchor value controls how to place the grid within the container window
when no row/column has any weight.  See \fBTHE GRID ALGORITHM\fR below
for further details.  The default \fIanchor\fR is \fInw\fR.

.TP
\fBgrid bbox \fIwindow\fR ?\fIcolumn row\fR? ?\fIcolumn2 row2\fR?
.
With no arguments,
the bounding box (in pixels) of the grid is returned.
The return value consists of 4 integers.  The first two are the pixel
offset from the container window (x then y) of the top-left corner of the
grid, and the second two integers are the width and height of the grid,
also in pixels.  If a single \fIcolumn\fR and \fIrow\fR is specified on
the command line, then the bounding box for that cell is returned, where the
top left cell is numbered from zero.  If both \fIcolumn\fR and \fIrow\fR
arguments are specified, then the bounding box spanning the rows and columns
indicated is returned.

.TP
\fBgrid columnconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the column properties of the \fIindex\fR column of the
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.







>






>













>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
\fBgrid \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
If the first argument to \fBgrid\fR is suitable as the first window
argument to \fBgrid configure\fR, either a window name (any value
starting with \fB.\fR) or one of the characters \fBx\fR or \fB^\fR
(see the \fBRELATIVE PLACEMENT\fR section below), then the command is
processed in the same way as \fBgrid configure\fR.
.\" METHOD: anchor
.TP
\fBgrid anchor \fIwindow\fR ?\fIanchor\fR?
.
The anchor value controls how to place the grid within the container window
when no row/column has any weight.  See \fBTHE GRID ALGORITHM\fR below
for further details.  The default \fIanchor\fR is \fInw\fR.
.\" METHOD: bbox
.TP
\fBgrid bbox \fIwindow\fR ?\fIcolumn row\fR? ?\fIcolumn2 row2\fR?
.
With no arguments,
the bounding box (in pixels) of the grid is returned.
The return value consists of 4 integers.  The first two are the pixel
offset from the container window (x then y) of the top-left corner of the
grid, and the second two integers are the width and height of the grid,
also in pixels.  If a single \fIcolumn\fR and \fIrow\fR is specified on
the command line, then the bounding box for that cell is returned, where the
top left cell is numbered from zero.  If both \fIcolumn\fR and \fIrow\fR
arguments are specified, then the bounding box spanning the rows and columns
indicated is returned.
.\" METHOD: columnconfigure
.TP
\fBgrid columnconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the column properties of the \fIindex\fR column of the
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
78
79
80
81
82
83
84
85
86

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

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

111
112
113
114
115
116
117

118
119
120
121
122
123

124
125
126
127
128
129
130
131

132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that column when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "\-option value"
pairs.

.TP
\fBgrid configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the content.
The characters \fB\-\fR,  \fBx\fR and \fB^\fR,
can be specified instead of a window name to alter the default
location of a \fIwindow\fR, as described in the \fBRELATIVE PLACEMENT\fR
section, below.
The following options are supported:
.RS

.TP
\fB\-column \fIn\fR
.
Insert the window so that it occupies the \fIn\fRth column in the grid.
Column numbers start with 0.  If this option is not supplied, then the
window is arranged just to the right of previous window specified on this
call to \fBgrid\fR, or column
.QW 0
if it is the first window.  For each
\fBx\fR that immediately precedes the \fIwindow\fR, the column position
is incremented by one.  Thus the \fBx\fR represents a blank column
for this row in the grid.

.TP
\fB\-columnspan \fIn\fR
.
Insert the window so that it occupies \fIn\fR columns in the grid.
The default is one column, unless the window name is followed by a
\fB\-\fR, in which case the columnspan is incremented once for each immediately
following \fB\-\fR.

.TP
\fB\-in \fIcontainer\fR
.
Insert the window(s) in the container
window given by \fIcontainer\fR.  The default is the first window's
parent window.

.TP
\fB\-ipadx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal internal padding to
leave on each side of the content.  This is space is added
inside the content border.
The \fIamount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.

.TP
\fB\-ipady \fIamount\fR
.
The \fIamount\fR specifies how much vertical internal padding to
leave on the top and bottom of the content.
This space is added inside the content border.
The \fIamount\fR  defaults to 0.

.TP
\fB\-padx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal external padding to
leave on each side of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for left and right separately.
The \fIamount\fR defaults to 0.
This space is added outside the content border.

.TP
\fB\-pady \fIamount\fR
.
The \fIamount\fR specifies how much vertical external padding to
leave on the top and bottom of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
The \fIamount\fR defaults to 0.
This space is added outside the content border.

.TP
\fB\-row \fIn\fR
.
Insert the content so that it occupies the \fIn\fRth row in the grid.
Row numbers start with 0.  If this option is not supplied, then the
content is arranged on the same row as the previous content specified on this
call to \fBgrid\fR, or the next row after the highest occupied row
if this is the first content.

.TP
\fB\-rowspan \fIn\fR
.
Insert the content so that it occupies \fIn\fR rows in the grid.
The default is one row.  If the next \fBgrid\fR command contains
\fB^\fR characters instead of \fIcontent\fR that line up with the columns
of this \fIcontent\fR, then the \fBrowspan\fR of this \fIcontent\fR is
extended by one.

.TP
\fB\-sticky \fIstyle\fR
.
If a content's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the content within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.







|

>












>












>







>






>








>







>









>









>








>








>







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
The \fB\-pad\fR option specifies the number of screen units that will be
added to the largest window contained completely in that column when the
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "\fI\-option value\fR"
pairs.
.\" METHOD: configure
.TP
\fBgrid configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the content.
The characters \fB\-\fR,  \fBx\fR and \fB^\fR,
can be specified instead of a window name to alter the default
location of a \fIwindow\fR, as described in the \fBRELATIVE PLACEMENT\fR
section, below.
The following options are supported:
.RS
.\" OPTION: -column
.TP
\fB\-column \fIn\fR
.
Insert the window so that it occupies the \fIn\fRth column in the grid.
Column numbers start with 0.  If this option is not supplied, then the
window is arranged just to the right of previous window specified on this
call to \fBgrid\fR, or column
.QW 0
if it is the first window.  For each
\fBx\fR that immediately precedes the \fIwindow\fR, the column position
is incremented by one.  Thus the \fBx\fR represents a blank column
for this row in the grid.
.\" OPTION: -columnspan
.TP
\fB\-columnspan \fIn\fR
.
Insert the window so that it occupies \fIn\fR columns in the grid.
The default is one column, unless the window name is followed by a
\fB\-\fR, in which case the columnspan is incremented once for each immediately
following \fB\-\fR.
.\" OPTION: -in
.TP
\fB\-in \fIcontainer\fR
.
Insert the window(s) in the container
window given by \fIcontainer\fR.  The default is the first window's
parent window.
.\" OPTION: -ipadx
.TP
\fB\-ipadx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal internal padding to
leave on each side of the content.  This is space is added
inside the content border.
The \fIamount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.\" OPTION: -ipady
.TP
\fB\-ipady \fIamount\fR
.
The \fIamount\fR specifies how much vertical internal padding to
leave on the top and bottom of the content.
This space is added inside the content border.
The \fIamount\fR  defaults to 0.
.\" OPTION: -padx
.TP
\fB\-padx \fIamount\fR
.
The \fIamount\fR specifies how much horizontal external padding to
leave on each side of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for left and right separately.
The \fIamount\fR defaults to 0.
This space is added outside the content border.
.\" OPTION: -pady
.TP
\fB\-pady \fIamount\fR
.
The \fIamount\fR specifies how much vertical external padding to
leave on the top and bottom of the content, in screen units.
\fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
The \fIamount\fR defaults to 0.
This space is added outside the content border.
.\" OPTION: -row
.TP
\fB\-row \fIn\fR
.
Insert the content so that it occupies the \fIn\fRth row in the grid.
Row numbers start with 0.  If this option is not supplied, then the
content is arranged on the same row as the previous content specified on this
call to \fBgrid\fR, or the next row after the highest occupied row
if this is the first content.
.\" OPTION: -rowspan
.TP
\fB\-rowspan \fIn\fR
.
Insert the content so that it occupies \fIn\fR rows in the grid.
The default is one row.  If the next \fBgrid\fR command contains
\fB^\fR characters instead of \fIcontent\fR that line up with the columns
of this \fIcontent\fR, then the \fBrowspan\fR of this \fIcontent\fR is
extended by one.
.\" OPTION: -sticky
.TP
\fB\-sticky \fIstyle\fR
.
If a content's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the content within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.
189
190
191
192
193
194
195










196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228

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


241


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
.QW "" ,
which causes the content to be centered in its cavity, at its requested size.
.LP
If any of the content is already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE










.TP
\fBgrid forget \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
window is managed once more by the grid geometry manager, the initial
default settings are used.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE

.TP
\fBgrid info \fIwindow\fR
.
Returns a list whose elements are the current configuration state of
the content given by \fIwindow\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the windows's container window.

.TP
\fBgrid location \fIwindow x y\fR
.
Given  \fIx\fR and \fIy\fR values in screen units relative to the container window,
the column and row number at that \fIx\fR and \fIy\fR location is returned.
For locations that are above or to the left of the grid, \fB\-1\fR is
returned.

.TP
\fBgrid propagate \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fIwindow\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fIwindow\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIwindow\fR.


Propagation is enabled by default.


.TP
\fBgrid rowconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the row properties of the \fIindex\fR row of the
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of row indices to which the configuration options will operate on.
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all rows currently occupied by content windows. For
a window name, that window must be a content window of this container and the options
apply to all rows currently occupied by the container window.
The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this row.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
rows.
A weight of zero (0) indicates the row will not deviate from its requested







>
>
>
>
>
>
>
>
>
>












|
|



>









>



|
|
|
|
>












>
>

>
>










|
|
|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
.QW "" ,
which causes the content to be centered in its cavity, at its requested size.
.LP
If any of the content is already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.\" METHOD: content
.TP
\fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.
If no options are supplied, a list of all of the content in \fIwindow\fR
is returned, most recently managed first.
\fIOption\fR can be either \fB\-row\fR or \fB\-column\fR which
causes only the content in the row (or column) specified by \fIvalue\fR
to be returned.
.\" METHOD: forget
.TP
\fBgrid forget \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
window is managed once more by the grid geometry manager, the initial
default settings are used.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also
send the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE
.\" METHOD: info
.TP
\fBgrid info \fIwindow\fR
.
Returns a list whose elements are the current configuration state of
the content given by \fIwindow\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the windows's container window.
.\" METHOD: location
.TP
\fBgrid location \fIwindow x y\fR
.
Given  \fIx\fR and \fIy\fR values in screen units relative to the container
window, the column and row number at that \fIx\fR and \fIy\fR location is
returned. For locations that are above or to the left of the grid, \fB\-1\fR
is returned.
.\" METHOD: propagate
.TP
\fBgrid propagate \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fIwindow\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fIwindow\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIwindow\fR.
.RS
.PP
Propagation is enabled by default.
.RE
.\" METHOD: rowconfigure
.TP
\fBgrid rowconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the row properties of the \fIindex\fR row of the
geometry container, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of row indices to which the configuration options will operate on.
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all rows currently occupied by content windows. For a
window name, that window must be a content window of this container and the
options apply to all rows currently occupied by the container window.
The \fB\-minsize\fR option sets the minimum size, in screen units,
that will be permitted for this row.
The \fB\-weight\fR option (an integer value)
sets the relative weight for apportioning
any extra spaces among
rows.
A weight of zero (0) indicates the row will not deviate from its requested
272
273
274
275
276
277
278

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

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "-option value"
pairs.

.TP
\fBgrid remove \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the content window is managed once more by the grid
geometry manager, the previous values are retained.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE

.TP
\fBgrid size \fIcontainer\fR
.
Returns the size of the grid (in columns then rows) for \fIcontainer\fR.
The size is determined either by the \fIcontent\fR occupying the largest
row or column, or the largest column or row with a \fB\-minsize\fR,
\fB\-weight\fR, or \fB\-pad\fR that is non-zero.
.TP
\fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.
If no options are supplied, a list of all of the content in \fIwindow\fR
is returned, most recently managed first.
\fIOption\fR can be either \fB\-row\fR or \fB\-column\fR which
causes only the content in the row (or column) specified by \fIvalue\fR
to be returned.
.TP
\fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?
.
Synonym for . \fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.SH "RELATIVE PLACEMENT"
.PP
The \fBgrid\fR command contains a limited set of capabilities that
permit layouts to be created without specifying the row and column
information for each content.  This permits content to be rearranged,
added, or removed without the need to explicitly specify row and
column information.
When no column or row information is specified for a \fIcontent\fR,
default values are chosen for
\fB\-column\fR, \fB\-row\fR, \fB\-columnspan\fR and \fB\-rowspan\fR
at the time the \fIcontent\fR is managed. The values are chosen
based upon the current layout of the grid, the position of the \fIcontent\fR
relative to other \fIcontent\fRs in the same grid command, and the presence
of the characters \fB\-\fR, \fBx\fR, and \fB^\fR in \fBgrid\fR
command where \fIcontent\fR names are normally expected.
.RS
.TP
\fB\-\fR
.
This increases the \fB\-columnspan\fR of the \fIcontent\fR to the left.  Several
\fB\-\fR's in a row will successively increase the number of columns spanned. A \fB\-\fR
may not follow a \fB^\fR or a \fBx\fR, nor may it be the first \fIcontent\fR
argument to \fBgrid configure\fR.
.TP
\fBx\fR
.
This leaves an empty column between the \fIcontent\fR on the left and
the \fIcontent\fR on the right.
.TP
\fB^\fR
.
This extends the \fB\-rowspan\fR of the \fIcontent\fR above the \fB^\fR's
in the grid.  The number of \fB^\fR's in a row must match the number of
columns spanned by the \fIcontent\fR above it.
.RE
.SH "THE GRID ALGORITHM"
.PP
The grid geometry manager lays out its content in three steps.
In the first step, the minimum size needed to fit all of the content
is computed, then (if propagation is turned on), a request is made
of the container window to become that size.
In the second step, the requested size is compared against the actual size
of the container.  If the sizes are different, then spaces is added to or taken
away from the layout as needed.
For the final step, each content is positioned in its row(s) and column(s)
based on the setting of its \fIsticky\fR flag.
.PP
To compute the minimum size of a layout, the grid geometry manager
first looks at all content whose \fB\-columnspan\fR and \fB\-rowspan\fR values are one,
and computes the nominal size of each row or column to be either the
\fIminsize\fR for that row or column, or the sum of the \fIpad\fRding
plus the size of the largest content, whichever is greater.  After that
the rows or columns in each uniform group adapt to each other.  Then
the content whose row-spans or column-spans are greater than one are
examined.  If a group of rows or columns need to be increased in size
in order to accommodate these content, then extra space is added to each







>












|
|
|


>







<
<
|
<
<
<
<
<



|
















<
|
<

|
|
|
<
|
<


<
|
<
















|
|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335


336





337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357

358
359
360
361

362

363
364

365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
grid geometry manager requests a size from the containing window.
If only an option is specified, with no value,
the current value of that option is returned.
If only the container window and index is specified, all the current settings
are returned in a list of
.QW "-option value"
pairs.
.\" METHOD: remove
.TP
\fBgrid remove \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the content window is managed once more by the grid
geometry manager, the previous values are retained.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also
send the virtual event \fB<<NoManagedChild>>\fR to the container; the
container may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE
.\" METHOD: size
.TP
\fBgrid size \fIcontainer\fR
.
Returns the size of the grid (in columns then rows) for \fIcontainer\fR.
The size is determined either by the \fIcontent\fR occupying the largest
row or column, or the largest column or row with a \fB\-minsize\fR,
\fB\-weight\fR, or \fB\-pad\fR that is non-zero.


.\" METHOD: slaves





.TP
\fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?
.
Synonym for \fBgrid content \fIwindow\fR ?\fI\-option value\fR?.
.SH "RELATIVE PLACEMENT"
.PP
The \fBgrid\fR command contains a limited set of capabilities that
permit layouts to be created without specifying the row and column
information for each content.  This permits content to be rearranged,
added, or removed without the need to explicitly specify row and
column information.
When no column or row information is specified for a \fIcontent\fR,
default values are chosen for
\fB\-column\fR, \fB\-row\fR, \fB\-columnspan\fR and \fB\-rowspan\fR
at the time the \fIcontent\fR is managed. The values are chosen
based upon the current layout of the grid, the position of the \fIcontent\fR
relative to other \fIcontent\fRs in the same grid command, and the presence
of the characters \fB\-\fR, \fBx\fR, and \fB^\fR in \fBgrid\fR
command where \fIcontent\fR names are normally expected.
.RS

.IP \fB\-\fR

This increases the \fB\-columnspan\fR of the \fIcontent\fR to the left.  Several
\fB\-\fR's in a row will successively increase the number of columns spanned.
A \fB\-\fR may not follow a \fB^\fR or a \fBx\fR, nor may it be the first
\fIcontent\fR argument to \fBgrid configure\fR.

.IP \fBx\fR

This leaves an empty column between the \fIcontent\fR on the left and
the \fIcontent\fR on the right.

.IP \fB^\fR

This extends the \fB\-rowspan\fR of the \fIcontent\fR above the \fB^\fR's
in the grid.  The number of \fB^\fR's in a row must match the number of
columns spanned by the \fIcontent\fR above it.
.RE
.SH "THE GRID ALGORITHM"
.PP
The grid geometry manager lays out its content in three steps.
In the first step, the minimum size needed to fit all of the content
is computed, then (if propagation is turned on), a request is made
of the container window to become that size.
In the second step, the requested size is compared against the actual size
of the container.  If the sizes are different, then spaces is added to or taken
away from the layout as needed.
For the final step, each content is positioned in its row(s) and column(s)
based on the setting of its \fIsticky\fR flag.
.PP
To compute the minimum size of a layout, the grid geometry manager first looks
at all content whose \fB\-columnspan\fR and \fB\-rowspan\fR values are one,
and computes the nominal size of each row or column to be either the
\fIminsize\fR for that row or column, or the sum of the \fIpad\fRding
plus the size of the largest content, whichever is greater.  After that
the rows or columns in each uniform group adapt to each other.  Then
the content whose row-spans or column-spans are greater than one are
examined.  If a group of rows or columns need to be increased in size
in order to accommodate these content, then extra space is added to each
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
.SH EXAMPLES
.PP
A toplevel window containing a text widget and two scrollbars:
.PP
.CS
# Make the widgets
toplevel .t
text .t.txt \-wrap none \-xscroll {.t.h set} \-yscroll {.t.v set}
scrollbar .t.v \-orient vertical   \-command {.t.txt yview}
scrollbar .t.h \-orient horizontal \-command {.t.txt xview}

# Lay them out
\fBgrid\fR .t.txt .t.v \-sticky nsew
\fBgrid\fR .t.h        \-sticky nsew

# Tell the text widget to take all the extra room
\fBgrid rowconfigure\fR    .t .t.txt \-weight 1
\fBgrid columnconfigure\fR .t .t.txt \-weight 1
.CE
.PP
Three widgets of equal width, despite their different
.QW natural
widths:
.PP
.CS
button .b \-text "Foo"
entry .e \-textvariable foo ; set foo "Hello World!"
label .l \-text "This is a fairly long piece of text"

\fBgrid\fR .b .e .l \-sticky ew
\fBgrid columnconfigure\fR . "all" \-uniform allTheSame
.CE
.SH "SEE ALSO"
pack(n), place(n)
.SH KEYWORDS
geometry manager, location, grid, cell, propagation, size, pack
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|


|
|


|
|







|
|
|

|
|








457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
.SH EXAMPLES
.PP
A toplevel window containing a text widget and two scrollbars:
.PP
.CS
# Make the widgets
toplevel .t
text .t.txt -wrap none -xscroll {.t.h set} -yscroll {.t.v set}
scrollbar .t.v -orient vertical   -command {.t.txt yview}
scrollbar .t.h -orient horizontal -command {.t.txt xview}

# Lay them out
\fBgrid\fR .t.txt .t.v -sticky nsew
\fBgrid\fR .t.h        -sticky nsew

# Tell the text widget to take all the extra room
\fBgrid rowconfigure\fR    .t .t.txt -weight 1
\fBgrid columnconfigure\fR .t .t.txt -weight 1
.CE
.PP
Three widgets of equal width, despite their different
.QW natural
widths:
.PP
.CS
button .b -text "Foo"
entry .e -textvariable foo ; set foo "Hello World!"
label .l -text "This is a fairly long piece of text"

\fBgrid\fR .b .e .l -sticky ew
\fBgrid columnconfigure\fR . "all" -uniform allTheSame
.CE
.SH "SEE ALSO"
pack(n), place(n)
.SH KEYWORDS
geometry manager, location, grid, cell, propagation, size, pack
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/image.n.

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

22
23

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

41
42

43
44
45
46
47
48
49
50
51
52

53
54

55
56

57
58

59
60

61
62

63

64
65

66
67

68
69

70
71
72

73
74

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











96
97
98
99
100
101
102
.TH image n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
image \- Create and manipulate images
.SH SYNOPSIS
\fBimage\fR \fIoption \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBimage\fR command is used to create, delete, and query images.
It can take several different forms, depending on the
\fIoption\fR argument.  The legal forms are:

.TP
\fBimage create \fItype \fR?\fIname\fR? ?\fIoption value ...\fR?

Creates a new image and a command with the same name and returns its name.
\fItype\fR specifies the type of the image, which must be one of
the types currently defined (e.g., \fBbitmap\fR).
\fIname\fR specifies the name for the image;  if it is omitted then
Tk picks a name of the form \fBimage\fIx\fR, where \fIx\fR is
an integer.
There may be any number of \fIoption\fR\-\fIvalue\fR pairs,
which provide configuration options for the new image.
The legal set of options is defined separately for each image
type;  see below for details on the options for built-in image types.
If an image already exists by the given name then it is replaced
with the new image and any instances of that image will redisplay
with the new contents.
It is important to note that the image command will silently overwrite any
procedure that may currently be defined by the given name, so choose the
name wisely.  It is recommended to use a separate namespace for image names
(e.g., \fB::img::logo\fR, \fB::img::large\fR).

.TP
\fBimage delete \fR?\fIname name\fR ...?

Deletes each of the named images and returns an empty string.
If there are instances of the images displayed in widgets,
the images will not actually be deleted until all of the instances
are released.
However, the association between the instances and the image
manager will be dropped.
Existing instances will retain their sizes but redisplay as
empty areas.
If a deleted image is recreated with another call to \fBimage create\fR,
the existing instances will use the new image.

.TP
\fBimage height \fIname\fR

Returns a decimal string giving the height of image \fIname\fR
in pixels.

.TP
\fBimage inuse \fIname\fR

Returns a boolean value indicating whether or not the image given by
\fIname\fR is in use by any widgets.

.TP
\fBimage names\fR

Returns a list containing the names of all existing images.

.TP
\fBimage type \fIname\fR

Returns the type of image \fIname\fR (the value of the \fItype\fR
argument to \fBimage create\fR when the image was created).

.TP
\fBimage types\fR

Returns a list whose elements are all of the valid image types
(i.e., all of the values that may be supplied for the \fItype\fR
argument to \fBimage create\fR).

.TP
\fBimage width \fIname\fR

Returns a decimal string giving the width of image \fIname\fR
in pixels.
.PP
Additional operations (e.g. writing the image to a file) may be
available as subcommands of the image instance command. See the manual
page for the particular image type for details.
.SH "BUILT-IN IMAGE TYPES"
.PP
The following image types are defined by Tk so they will be available
in any Tk application.
Individual applications or extensions may define additional types.
.TP
\fBbitmap\fR
Each pixel in the image displays a foreground color, a background
color, or nothing.
See the \fBbitmap\fR manual entry for more information.
.TP
\fBphoto\fR
Displays a variety of full-color images, using dithering to
approximate colors on displays with limited color capabilities.
See the \fBphoto\fR manual entry for more information.











.SH "SEE ALSO"
bitmap(n), options(n), photo(n)
.SH KEYWORDS
height, image, types of images, width
'\" Local Variables:
'\" mode: nroff
'\" End:







|






>


>

















>


>










>


>


>


>


>


>

>


>


>


>



>


>











<
|



<
|



>
>
>
>
>
>
>
>
>
>
>

|





8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
.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\fI option \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:
.\" METHOD: create
.TP
\fBimage create \fItype \fR?\fIname\fR? ?\fIoption value ...\fR?
.
Creates a new image and a command with the same name and returns its name.
\fItype\fR specifies the type of the image, which must be one of
the types currently defined (e.g., \fBbitmap\fR).
\fIname\fR specifies the name for the image;  if it is omitted then
Tk picks a name of the form \fBimage\fIx\fR, where \fIx\fR is
an integer.
There may be any number of \fIoption\fR\-\fIvalue\fR pairs,
which provide configuration options for the new image.
The legal set of options is defined separately for each image
type;  see below for details on the options for built-in image types.
If an image already exists by the given name then it is replaced
with the new image and any instances of that image will redisplay
with the new contents.
It is important to note that the image command will silently overwrite any
procedure that may currently be defined by the given name, so choose the
name wisely.  It is recommended to use a separate namespace for image names
(e.g., \fB::img::logo\fR, \fB::img::large\fR).
.\" METHOD: delete
.TP
\fBimage delete \fR?\fIname name\fR ...?
.
Deletes each of the named images and returns an empty string.
If there are instances of the images displayed in widgets,
the images will not actually be deleted until all of the instances
are released.
However, the association between the instances and the image
manager will be dropped.
Existing instances will retain their sizes but redisplay as
empty areas.
If a deleted image is recreated with another call to \fBimage create\fR,
the existing instances will use the new image.
.\" METHOD: height
.TP
\fBimage height \fIname\fR
.
Returns a decimal string giving the height of image \fIname\fR
in pixels.
.\" METHOD: inuse
.TP
\fBimage inuse \fIname\fR
.
Returns a boolean value indicating whether or not the image given by
\fIname\fR is in use by any widgets.
.\" METHOD: names
.TP
\fBimage names\fR
.
Returns a list containing the names of all existing images.
.\" METHOD: type
.TP
\fBimage type \fIname\fR
.
Returns the type of image \fIname\fR (the value of the \fItype\fR
argument to \fBimage create\fR when the image was created).
.\" METHOD: types
.TP
\fBimage types\fR
.
Returns a list whose elements are all of the valid image types
(i.e., all of the values that may be supplied for the \fItype\fR
argument to \fBimage create\fR).
.\" METHOD: width
.TP
\fBimage width \fIname\fR
.
Returns a decimal string giving the width of image \fIname\fR
in pixels.
.PP
Additional operations (e.g. writing the image to a file) may be
available as subcommands of the image instance command. See the manual
page for the particular image type for details.
.SH "BUILT-IN IMAGE TYPES"
.PP
The following image types are defined by Tk so they will be available
in any Tk application.
Individual applications or extensions may define additional types.

.IP \fBbitmap\fR
Each pixel in the image displays a foreground color, a background
color, or nothing.
See the \fBbitmap\fR manual entry for more information.

.IP \fBphoto\fR
Displays a variety of full-color images, using dithering to
approximate colors on displays with limited color capabilities.
See the \fBphoto\fR manual entry for more information.
.IP \fBnsimage\fR
This type is only available in the Aqua platform.  It is a full-color
image which may be created from a named system image.  It has options
designed to facilitate the use of these images in buttons.  An
\fBnsimage\fR can be based on an a \fItemplate image\fR, which is an
anti-aliased 2-color image format that automatically interchanges
black and white in response to changes between the light and dark
modes on macOS.  An \fBnsimage\fR can also generate an alternate
\fIpressed\fR variant which is lighter in dark mode and darker in
light mode.  These are for use in image buttons. See the \fBnsimage\fR
manual entry for more information.
.SH "SEE ALSO"
bitmap(n), options(n), photo(n), nsimage(n)
.SH KEYWORDS
height, image, types of images, width
'\" Local Variables:
'\" mode: nroff
'\" End:

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
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" All rights reserved.
'\"
.TH keysyms n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
keysyms \- keysyms recognized by Tk
.BE
.SH DESCRIPTION
.PP
Tk recognizes many keysyms when specifying key bindings (e.g.,
.QW "\fBbind\fR \fB. <Key-\fR\fIkeysym\fR\fB>\fR" ).
The following list enumerates the
keysyms that will be recognized by Tk.  Note that not all keysyms will
be valid on all platforms, and some keysyms are also available on
platforms that have a different native name for that key.
For example, on Unix systems, the presence
of a particular keysym is dependent on the configuration of the
keyboard modifier map.  This list shows keysyms along with their
decimal and hexadecimal values.
.PP
.CS
space                               32     0x20
exclam                              33     0x21
quotedbl                            34     0x22
numbersign                          35     0x23
dollar                              36     0x24


percent                             37     0x25
ampersand                           38     0x26
apostrophe                          39     0x27
parenleft                           40     0x28
parenright                          41     0x29
asterisk                            42     0x2A
plus                                43     0x2B
comma                               44     0x2C
minus                               45     0x2D
period                              46     0x2E
slash                               47     0x2F
0                                   48     0x30
1                                   49     0x31
2                                   50     0x32
3                                   51     0x33
4                                   52     0x34
5                                   53     0x35
6                                   54     0x36
7                                   55     0x37
8                                   56     0x38
9                                   57     0x39
colon                               58     0x3A
semicolon                           59     0x3B
less                                60     0x3C
equal                               61     0x3D
greater                             62     0x3E

question                            63     0x3F
at                                  64     0x40
A                                   65     0x41
B                                   66     0x42
C                                   67     0x43
D                                   68     0x44
E                                   69     0x45
F                                   70     0x46
G                                   71     0x47

|












|











|



>
>
|
|
|
|
<
|
|
|
|
|
<










|


|

>
|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41

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 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. <\fR\fIkeysym\fR\fB>\fR" ).
The following list enumerates the
keysyms that will be recognized by Tk.  Note that not all keysyms will
be valid on all platforms, and some keysyms are also available on
platforms that have a different native name for that key.
For example, on Unix systems, the presence
of a particular keysym is dependent on the configuration of the
keyboard modifier map.  This list shows keysyms along with their
decimal and hexadecimal values.
.PP
.CS
space                               32     0x20
! (exclam)                          33     0x21
quotedbl                            34     0x22
numbersign                          35     0x23
dollar                              36     0x24
% (percent)                         37     0x25
& (ampersand)                       38     0x26
' (apostrophe)                      39     0x27
( (parenleft)                       40     0x28
) (parenright)                      41     0x29
* (asterisk)                        42     0x2A

+ (plus)                            43     0x2B
, (comma)                           44     0x2C
minus                               45     0x2D
. (period)                          46     0x2E
/ (slash)                           47     0x2F

0                                   48     0x30
1                                   49     0x31
2                                   50     0x32
3                                   51     0x33
4                                   52     0x34
5                                   53     0x35
6                                   54     0x36
7                                   55     0x37
8                                   56     0x38
9                                   57     0x39
: (colon)                           58     0x3A
semicolon                           59     0x3B
less                                60     0x3C
= (equal)                           61     0x3D
greater                             62     0x3E
? (question)                        63     0x3F
@ (at)                              64     0x40

A                                   65     0x41
B                                   66     0x42
C                                   67     0x43
D                                   68     0x44
E                                   69     0x45
F                                   70     0x46
G                                   71     0x47
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
grave                               96     0x60
a                                   97     0x61
b                                   98     0x62
c                                   99     0x63
d                                  100     0x64
e                                  101     0x65
f                                  102     0x66
g                                  103     0x67







|
>
|
<







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
` (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
u                                  117     0x75
v                                  118     0x76
w                                  119     0x77
x                                  120     0x78
y                                  121     0x79
z                                  122     0x7A
braceleft                          123     0x7B
bar                                124     0x7C
braceright                         125     0x7D
asciitilde                         126     0x7E
nobreakspace                       160     0xA0
exclamdown                         161     0xA1
cent                               162     0xA2
sterling                           163     0xA3
currency                           164     0xA4
yen                                165     0xA5
brokenbar                          166     0xA6
section                            167     0xA7
diaeresis                          168     0xA8
copyright                          169     0xA9
ordfeminine                        170     0xAA
guillemotleft                      171     0xAB

notsign                            172     0xAC


hyphen                             173     0xAD
registered                         174     0xAE
macron                             175     0xAF
degree                             176     0xB0
plusminus                          177     0xB1
twosuperior                        178     0xB2
threesuperior                      179     0xB3
acute                              180     0xB4
mu                                 181     0xB5
paragraph                          182     0xB6
periodcentered                     183     0xB7
cedilla                            184     0xB8
onesuperior                        185     0xB9
masculine                          186     0xBA
guillemotright                     187     0xBB
onequarter                         188     0xBC
onehalf                            189     0xBD

threequarters                      190     0xBE
questiondown                       191     0xBF
Agrave                             192     0xC0
Aacute                             193     0xC1


Acircumflex                        194     0xC2


Atilde                             195     0xC3
Adiaeresis                         196     0xC4
Aring                              197     0xC5
AE                                 198     0xC6
Ccedilla                           199     0xC7
Egrave                             200     0xC8
Eacute                             201     0xC9
Ecircumflex                        202     0xCA
Ediaeresis                         203     0xCB
Igrave                             204     0xCC
Iacute                             205     0xCD
Icircumflex                        206     0xCE
Idiaeresis                         207     0xCF
ETH                                208     0xD0
Ntilde                             209     0xD1
Ograve                             210     0xD2
Oacute                             211     0xD3
Ocircumflex                        212     0xD4
Otilde                             213     0xD5

Odiaeresis                         214     0xD6
multiply                           215     0xD7

Oslash                             216     0xD8
Ugrave                             217     0xD9
Uacute                             218     0xDA
Ucircumflex                        219     0xDB
Udiaeresis                         220     0xDC

Yacute                             221     0xDD
THORN                              222     0xDE
ssharp                             223     0xDF
agrave                             224     0xE0
aacute                             225     0xE1
acircumflex                        226     0xE2
atilde                             227     0xE3

adiaeresis                         228     0xE4
aring                              229     0xE5
ae                                 230     0xE6
ccedilla                           231     0xE7
egrave                             232     0xE8
eacute                             233     0xE9
ecircumflex                        234     0xEA
ediaeresis                         235     0xEB


igrave                             236     0xEC
iacute                             237     0xED
icircumflex                        238     0xEE
idiaeresis                         239     0xEF
eth                                240     0xF0
ntilde                             241     0xF1
ograve                             242     0xF2
oacute                             243     0xF3
ocircumflex                        244     0xF4
otilde                             245     0xF5
odiaeresis                         246     0xF6
division                           247     0xF7
oslash                             248     0xF8
ugrave                             249     0xF9
uacute                             250     0xFA
ucircumflex                        251     0xFB
udiaeresis                         252     0xFC

yacute                             253     0xFD
thorn                              254     0xFE
ydiaeresis                         255     0xFF



Aogonek                            417     0x1A1
breve                              418     0x1A2
Lstroke                            419     0x1A3
Lcaron                             421     0x1A5
Sacute                             422     0x1A6
Scaron                             425     0x1A9
Scedilla                           426     0x1AA
Tcaron                             427     0x1AB
Zacute                             428     0x1AC
.CE
.CS
Zcaron                             430     0x1AE
Zabovedot                          431     0x1AF
aogonek                            433     0x1B1
ogonek                             434     0x1B2
lstroke                            435     0x1B3
lcaron                             437     0x1B5
sacute                             438     0x1B6







|

|

<
|
|
|
<
<
|
|
|
|
|
>
|
>
>

<
|
|
<
|
|
|
|
|
<
|
|
|
<
|
<
>
|
|
|
|
>
>
|
>
>
<
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
>
<
|
<
|
|
>
|
|
|
|
<
|
|
>
|
|
|
|
|
<
|
|
>
>
|
|
<
|
|
|
|
<
|
|
|
|
|
|
|
|
|
>
|
|
|
>
>
>









<
<







111
112
113
114
115
116
117
118
119
120
121

122
123
124


125
126
127
128
129
130
131
132
133
134

135
136

137
138
139
140
141

142
143
144

145

146
147
148
149
150
151
152
153
154
155

156
157
158
159
160

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

177

178
179
180
181
182
183
184

185
186
187
188
189
190
191
192

193
194
195
196
197
198

199
200
201
202

203
204
205
206
207
208
209
210
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
braceright                         125     0x7D
~ (asciitilde)                     126     0x7E
nobreakspace                       160     0xA0

\(r! (exclamdown)                     161     0xA1
\(ct (cent)                           162     0xA2
\(Po (sterling)                       163     0xA3


\(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 (guillemetleft)                  171     0xAB
\(no (notsign)                        172     0xAC
hyphen                             173     0xAD

\(rg (registered)                     174     0xAE
\(a- (macron)                         175     0xAF

\(de (degree)                         176     0xB0
\(+- (plusminus)                      177     0xB1
\(S2 (twosuperior)                    178     0xB2
\(S3 (threesuperior)                  179     0xB3
\(aa (acute)                          180     0xB4

\(mc (mu)                             181     0xB5
\(ps (paragraph)                      182     0xB6
\(pc (periodcentered)                 183     0xB7

\(ac (cedilla)                        184     0xB8

\(S1 (onesuperior)                    185     0xB9
\(Om (ordmasculine)                   186     0xBA
\(Fc (guillemetright)                 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

\(~A (Atilde)                         195     0xC3
\(:A (Adiaeresis)                     196     0xC4
\(oA (Aring)                          197     0xC5
\(AE (AE)                             198     0xC6
\(,C (Ccedilla)                       199     0xC7

\(`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

\(/O (Oslash)                         216     0xD8

\(`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

\(`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

\(`e (egrave)                         232     0xE8
\('e (eacute)                         233     0xE9
\(^e (ecircumflex)                    234     0xEA
\(:e (ediaeresis)                     235     0xEB
\(`i (igrave)                         236     0xEC
\('i (iacute)                         237     0xED

\(^i (icircumflex)                    238     0xEE
\(:i (idiaeresis)                     239     0xEF
\(Sd (eth)                            240     0xF0
\(~n (ntilde)                         241     0xF1

\(`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


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
kana_RU                           1241     0x4D9
kana_RE                           1242     0x4DA
kana_RO                           1243     0x4DB
kana_WA                           1244     0x4DC
kana_N                            1245     0x4DD
voicedsound                       1246     0x4DE
semivoicedsound                   1247     0x4DF


Arabic_comma                      1452     0x5AC
Arabic_semicolon                  1467     0x5BB
Arabic_question_mark              1471     0x5BF
Arabic_hamza                      1473     0x5C1
Arabic_maddaonalef                1474     0x5C2
Arabic_hamzaonalef                1475     0x5C3
Arabic_hamzaonwaw                 1476     0x5C4







>
>







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







<
<







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


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
Cyrillic_CHE                      1790     0x6FE
Cyrillic_HARDSIGN                 1791     0x6FF
Greek_ALPHAaccent                 1953     0x7A1
Greek_EPSILONaccent               1954     0x7A2
Greek_ETAaccent                   1955     0x7A3
Greek_IOTAaccent                  1956     0x7A4
Greek_IOTAdieresis                1957     0x7A5

Greek_OMICRONaccent               1959     0x7A7
Greek_UPSILONaccent               1960     0x7A8
Greek_UPSILONdieresis             1961     0x7A9

Greek_OMEGAaccent                 1963     0x7AB
Greek_accentdieresis              1966     0x7AE
Greek_horizbar                    1967     0x7AF
Greek_alphaaccent                 1969     0x7B1
Greek_epsilonaccent               1970     0x7B2
Greek_etaaccent                   1971     0x7B3
Greek_iotaaccent                  1972     0x7B4







>



>







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
Greek_finalsmallsigma             2035     0x7F3
Greek_tau                         2036     0x7F4
Greek_upsilon                     2037     0x7F5
Greek_phi                         2038     0x7F6
Greek_chi                         2039     0x7F7
Greek_psi                         2040     0x7F8
Greek_omega                       2041     0x7F9


leftradical                       2209     0x8A1
topleftradical                    2210     0x8A2
horizconnector                    2211     0x8A3
topintegral                       2212     0x8A4
botintegral                       2213     0x8A5
vertconnector                     2214     0x8A6
topleftsqbracket                  2215     0x8A7







>
>







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







<
<







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


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
hebrew_pe                         3316     0xCF4
hebrew_finalzade                  3317     0xCF5
hebrew_zade                       3318     0xCF6
hebrew_qoph                       3319     0xCF7
hebrew_resh                       3320     0xCF8
hebrew_shin                       3321     0xCF9
hebrew_taw                        3322     0xCFA


Thai_kokai                        3489     0xDA1
Thai_khokhai                      3490     0xDA2
Thai_khokhuat                     3491     0xDA3
Thai_khokhwai                     3492     0xDA4
Thai_khokhon                      3493     0xDA5
Thai_khorakhang                   3494     0xDA6
Thai_ngongu                       3495     0xDA7







>
>







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
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
Hangul_J_PanSios                  3832     0xEF8
Hangul_J_KkogjiDalrinIeung        3833     0xEF9
Hangul_J_YeorinHieuh              3834     0xEFA
Korean_Won                        3839     0xEFF
OE                                5052     0x13BC
oe                                5053     0x13BD
Ydiaeresis                        5054     0x13BE
EuroSign                          8364     0x20AC
3270_Duplicate                   64769     0xFD01
3270_FieldMark                   64770     0xFD02
3270_Right2                      64771     0xFD03
3270_Left2                       64772     0xFD04
3270_BackTab                     64773     0xFD05
3270_EraseEOF                    64774     0xFD06
3270_EraseInput                  64775     0xFD07
3270_Reset                       64776     0xFD08
3270_Quit                        64777     0xFD09
3270_PA1                         64778     0xFD0A
3270_PA2                         64779     0xFD0B
3270_PA3                         64780     0xFD0C
3270_Test                        64781     0xFD0D
3270_Attn                        64782     0xFD0E
3270_CursorBlink                 64783     0xFD0F
3270_AltCursor                   64784     0xFD10
3270_KeyClick                    64785     0xFD11
3270_Jump                        64786     0xFD12
3270_Ident                       64787     0xFD13
3270_Rule                        64788     0xFD14
3270_Copy                        64789     0xFD15
3270_Play                        64790     0xFD16
3270_Setup                       64791     0xFD17
3270_Record                      64792     0xFD18
3270_ChangeScreen                64793     0xFD19
3270_DeleteWord                  64794     0xFD1A
3270_ExSelect                    64795     0xFD1B
3270_CursorSelect                64796     0xFD1C
3270_PrintScreen                 64797     0xFD1D
3270_Enter                       64798     0xFD1E


ISO_Lock                         65025     0xFE01
ISO_Level2_Latch                 65026     0xFE02
ISO_Level3_Shift                 65027     0xFE03
ISO_Level3_Latch                 65028     0xFE04
ISO_Level3_Lock                  65029     0xFE05
ISO_Group_Latch                  65030     0xFE06
ISO_Group_Lock                   65031     0xFE07







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>







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




\(eu (EuroSign)                      8364     0x20AC


























.CE
.CS
ISO_Lock                         65025     0xFE01
ISO_Level2_Latch                 65026     0xFE02
ISO_Level3_Shift                 65027     0xFE03
ISO_Level3_Latch                 65028     0xFE04
ISO_Level3_Lock                  65029     0xFE05
ISO_Group_Latch                  65030     0xFE06
ISO_Group_Lock                   65031     0xFE07
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
dead_E                           65155     0xFE83
dead_i                           65156     0xFE84
dead_I                           65157     0xFE85
dead_o                           65158     0xFE86
dead_O                           65159     0xFE87
dead_u                           65160     0xFE88
dead_U                           65161     0xFE89
dead_small_schwa                 65162     0xFE8A
dead_capital_schwa               65163     0xFE8B
dead_greek                       65164     0xFE8C
dead_lowline                     65168     0xFE90
dead_aboveverticalline           65169     0xFE91
dead_belowverticalline           65170     0xFE92
dead_longsolidusoverlay          65171     0xFE93
ch                               65184     0xFEA0
Ch                               65185     0xFEA1







|
|







1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
dead_E                           65155     0xFE83
dead_i                           65156     0xFE84
dead_I                           65157     0xFE85
dead_o                           65158     0xFE86
dead_O                           65159     0xFE87
dead_u                           65160     0xFE88
dead_U                           65161     0xFE89
dead_schwa                       65162     0xFE8A
dead_SCHWA                       65163     0xFE8B
dead_greek                       65164     0xFE8C
dead_lowline                     65168     0xFE90
dead_aboveverticalline           65169     0xFE91
dead_belowverticalline           65170     0xFE92
dead_longsolidusoverlay          65171     0xFE93
ch                               65184     0xFEA0
Ch                               65185     0xFEA1
1161
1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
Pointer_Drag3                    65271     0xFEF7
Pointer_Drag4                    65272     0xFEF8
Pointer_EnableKeys               65273     0xFEF9
Pointer_Accelerate               65274     0xFEFA
Pointer_DfltBtnNext              65275     0xFEFB
Pointer_DfltBtnPrev              65276     0xFEFC
Pointer_Drag5                    65277     0xFEFD


BackSpace                        65288     0xFF08
Tab                              65289     0xFF09
Linefeed                         65290     0xFF0A
Clear                            65291     0xFF0B
Return                           65293     0xFF0D
Pause                            65299     0xFF13
Scroll_Lock                      65300     0xFF14







>
>







1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
Pointer_Drag3                    65271     0xFEF7
Pointer_Drag4                    65272     0xFEF8
Pointer_EnableKeys               65273     0xFEF9
Pointer_Accelerate               65274     0xFEFA
Pointer_DfltBtnNext              65275     0xFEFB
Pointer_DfltBtnPrev              65276     0xFEFC
Pointer_Drag5                    65277     0xFEFD
.CE
.CS
BackSpace                        65288     0xFF08
Tab                              65289     0xFF09
Linefeed                         65290     0xFF0A
Clear                            65291     0xFF0B
Return                           65293     0xFF0D
Pause                            65299     0xFF13
Scroll_Lock                      65300     0xFF14
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
Up                               65362     0xFF52
Right                            65363     0xFF53
Down                             65364     0xFF54
Prior                            65365     0xFF55
Next                             65366     0xFF56
End                              65367     0xFF57
Begin                            65368     0xFF58
Win_L                            65371     0xFF5B
Win_R                            65372     0xFF5C
.CE
.CS
App                              65373     0xFF5D
Select                           65376     0xFF60
Print                            65377     0xFF61
Execute                          65378     0xFF62
Insert                           65379     0xFF63
Undo                             65381     0xFF65
Redo                             65382     0xFF66
Menu                             65383     0xFF67
Find                             65384     0xFF68
Cancel                           65385     0xFF69
Help                             65386     0xFF6A
Break                            65387     0xFF6B
Mode_switch                      65406     0xFF7E
Num_Lock                         65407     0xFF7F
KP_Space                         65408     0xFF80







<
<
<
<
<






|







1189
1190
1191
1192
1193
1194
1195





1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
Up                               65362     0xFF52
Right                            65363     0xFF53
Down                             65364     0xFF54
Prior                            65365     0xFF55
Next                             65366     0xFF56
End                              65367     0xFF57
Begin                            65368     0xFF58





Select                           65376     0xFF60
Print                            65377     0xFF61
Execute                          65378     0xFF62
Insert                           65379     0xFF63
Undo                             65381     0xFF65
Redo                             65382     0xFF66
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
Control_R                        65508     0xFFE4
Caps_Lock                        65509     0xFFE5
Shift_Lock                       65510     0xFFE6
Meta_L                           65511     0xFFE7
Meta_R                           65512     0xFFE8
Alt_L                            65513     0xFFE9
Alt_R                            65514     0xFFEA
Super_L                          65515     0xFFEB
Super_R                          65516     0xFFEC
Hyper_L                          65517     0xFFED
Hyper_R                          65518     0xFFEE
braille_dot_1                    65521     0xFFF1
braille_dot_2                    65522     0xFFF2
braille_dot_3                    65523     0xFFF3
braille_dot_4                    65524     0xFFF4
braille_dot_5                    65525     0xFFF5
braille_dot_6                    65526     0xFFF6
braille_dot_7                    65527     0xFFF7
braille_dot_8                    65528     0xFFF8
braille_dot_9                    65529     0xFFF9
braille_dot_10                   65530     0xFFFA
Delete                           65535     0xFFFF
Ibreve                        16777516     0x100012C
ibreve                        16777517     0x100012D
Wcircumflex                   16777588     0x1000174
wcircumflex                   16777589     0x1000175
Ycircumflex                   16777590     0x1000176
ycircumflex                   16777591     0x1000177
SCHWA                         16777615     0x100018F
Obarred                       16777631     0x100019F
Ohorn                         16777632     0x10001A0
ohorn                         16777633     0x10001A1
Uhorn                         16777647     0x10001AF
uhorn                         16777648     0x10001B0
Zstroke                       16777653     0x10001B5
zstroke                       16777654     0x10001B6
EZH                           16777655     0x10001B7
Ocaron                        16777681     0x10001D1
ocaron                        16777682     0x10001D2
Gcaron                        16777702     0x10001E6
gcaron                        16777703     0x10001E7
schwa                         16777817     0x1000259
obarred                       16777845     0x1000275
ezh                           16777874     0x1000292
Cyrillic_GHE_bar              16778386     0x1000492
Cyrillic_ghe_bar              16778387     0x1000493
Cyrillic_ZHE_descender        16778390     0x1000496
Cyrillic_zhe_descender        16778391     0x1000497
Cyrillic_KA_descender         16778394     0x100049A
Cyrillic_ka_descender         16778395     0x100049B
Cyrillic_KA_vertstroke        16778396     0x100049C
Cyrillic_ka_vertstroke        16778397     0x100049D
Cyrillic_EN_descender         16778402     0x10004A2
Cyrillic_en_descender         16778403     0x10004A3
Cyrillic_U_straight           16778414     0x10004AE
Cyrillic_u_straight           16778415     0x10004AF
Cyrillic_U_straight_bar       16778416     0x10004B0
Cyrillic_u_straight_bar       16778417     0x10004B1
Cyrillic_HA_descender         16778418     0x10004B2
Cyrillic_ha_descender         16778419     0x10004B3
Cyrillic_CHE_descender        16778422     0x10004B6
Cyrillic_che_descender        16778423     0x10004B7
Cyrillic_CHE_vertstroke       16778424     0x10004B8
Cyrillic_che_vertstroke       16778425     0x10004B9
Cyrillic_SHHA                 16778426     0x10004BA
Cyrillic_shha                 16778427     0x10004BB
Cyrillic_SCHWA                16778456     0x10004D8
Cyrillic_schwa                16778457     0x10004D9
Cyrillic_I_macron             16778466     0x10004E2
Cyrillic_i_macron             16778467     0x10004E3
Cyrillic_O_bar                16778472     0x10004E8
Cyrillic_o_bar                16778473     0x10004E9
Cyrillic_U_macron             16778478     0x10004EE
Cyrillic_u_macron             16778479     0x10004EF
Armenian_AYB                  16778545     0x1000531
Armenian_BEN                  16778546     0x1000532
Armenian_GIM                  16778547     0x1000533
Armenian_DA                   16778548     0x1000534
Armenian_YECH                 16778549     0x1000535
Armenian_ZA                   16778550     0x1000536
Armenian_E                    16778551     0x1000537
Armenian_AT                   16778552     0x1000538
Armenian_TO                   16778553     0x1000539
Armenian_ZHE                  16778554     0x100053A
Armenian_INI                  16778555     0x100053B
Armenian_LYUN                 16778556     0x100053C
Armenian_KHE                  16778557     0x100053D
Armenian_TSA                  16778558     0x100053E
Armenian_KEN                  16778559     0x100053F
Armenian_HO                   16778560     0x1000540
Armenian_DZA                  16778561     0x1000541
Armenian_GHAT                 16778562     0x1000542
Armenian_TCHE                 16778563     0x1000543
Armenian_MEN                  16778564     0x1000544
Armenian_HI                   16778565     0x1000545
Armenian_NU                   16778566     0x1000546
Armenian_SHA                  16778567     0x1000547
Armenian_VO                   16778568     0x1000548
Armenian_CHA                  16778569     0x1000549
Armenian_PE                   16778570     0x100054A
Armenian_JE                   16778571     0x100054B
Armenian_RA                   16778572     0x100054C
Armenian_SE                   16778573     0x100054D
Armenian_VEV                  16778574     0x100054E
Armenian_TYUN                 16778575     0x100054F
Armenian_RE                   16778576     0x1000550
Armenian_TSO                  16778577     0x1000551
Armenian_VYUN                 16778578     0x1000552
Armenian_PYUR                 16778579     0x1000553
Armenian_KE                   16778580     0x1000554
Armenian_O                    16778581     0x1000555
Armenian_FE                   16778582     0x1000556
Armenian_apostrophe           16778586     0x100055A
Armenian_accent               16778587     0x100055B
Armenian_exclam               16778588     0x100055C
Armenian_separation_mark      16778589     0x100055D
Armenian_question             16778590     0x100055E
Armenian_ayb                  16778593     0x1000561
Armenian_ben                  16778594     0x1000562
Armenian_gim                  16778595     0x1000563
Armenian_da                   16778596     0x1000564
Armenian_yech                 16778597     0x1000565
Armenian_za                   16778598     0x1000566
Armenian_e                    16778599     0x1000567
Armenian_at                   16778600     0x1000568
Armenian_to                   16778601     0x1000569
Armenian_zhe                  16778602     0x100056A
Armenian_ini                  16778603     0x100056B
Armenian_lyun                 16778604     0x100056C
Armenian_khe                  16778605     0x100056D
Armenian_tsa                  16778606     0x100056E
Armenian_ken                  16778607     0x100056F
Armenian_ho                   16778608     0x1000570
Armenian_dza                  16778609     0x1000571
Armenian_ghat                 16778610     0x1000572
Armenian_tche                 16778611     0x1000573
Armenian_men                  16778612     0x1000574
Armenian_hi                   16778613     0x1000575
Armenian_nu                   16778614     0x1000576
Armenian_sha                  16778615     0x1000577
Armenian_vo                   16778616     0x1000578
Armenian_cha                  16778617     0x1000579
Armenian_pe                   16778618     0x100057A
Armenian_je                   16778619     0x100057B
Armenian_ra                   16778620     0x100057C
Armenian_se                   16778621     0x100057D
Armenian_vev                  16778622     0x100057E
Armenian_tyun                 16778623     0x100057F
Armenian_re                   16778624     0x1000580
Armenian_tso                  16778625     0x1000581
Armenian_vyun                 16778626     0x1000582
Armenian_pyur                 16778627     0x1000583
Armenian_ke                   16778628     0x1000584
Armenian_o                    16778629     0x1000585
Armenian_fe                   16778630     0x1000586
Armenian_ligature_ew          16778631     0x1000587
Armenian_full_stop            16778633     0x1000589
Armenian_hyphen               16778634     0x100058A
Arabic_madda_above            16778835     0x1000653
Arabic_hamza_above            16778836     0x1000654
Arabic_hamza_below            16778837     0x1000655
Arabic_0                      16778848     0x1000660
Arabic_1                      16778849     0x1000661
Arabic_2                      16778850     0x1000662
Arabic_3                      16778851     0x1000663
Arabic_4                      16778852     0x1000664
Arabic_5                      16778853     0x1000665
Arabic_6                      16778854     0x1000666
Arabic_7                      16778855     0x1000667
Arabic_8                      16778856     0x1000668
Arabic_9                      16778857     0x1000669
Arabic_percent                16778858     0x100066A
Arabic_superscript_alef       16778864     0x1000670
Arabic_tteh                   16778873     0x1000679
Arabic_peh                    16778878     0x100067E
Arabic_tcheh                  16778886     0x1000686
Arabic_ddal                   16778888     0x1000688
Arabic_rreh                   16778897     0x1000691
Arabic_jeh                    16778904     0x1000698
Arabic_veh                    16778916     0x10006A4
Arabic_keheh                  16778921     0x10006A9
Arabic_gaf                    16778927     0x10006AF
Arabic_noon_ghunna            16778938     0x10006BA
Arabic_heh_doachashmee        16778942     0x10006BE
Arabic_heh_goal               16778945     0x10006C1
Farsi_yeh                     16778956     0x10006CC
Arabic_yeh_baree              16778962     0x10006D2
Arabic_fullstop               16778964     0x10006D4
Farsi_0                       16778992     0x10006F0
Farsi_1                       16778993     0x10006F1
Farsi_2                       16778994     0x10006F2
Farsi_3                       16778995     0x10006F3
Farsi_4                       16778996     0x10006F4
Farsi_5                       16778997     0x10006F5
Farsi_6                       16778998     0x10006F6
Farsi_7                       16778999     0x10006F7
Farsi_8                       16779000     0x10006F8
Farsi_9                       16779001     0x10006F9
Sinh_ng                       16780674     0x1000D82
Sinh_h2                       16780675     0x1000D83
Sinh_a                        16780677     0x1000D85
Sinh_aa                       16780678     0x1000D86
Sinh_ae                       16780679     0x1000D87
Sinh_aee                      16780680     0x1000D88
Sinh_i                        16780681     0x1000D89
Sinh_ii                       16780682     0x1000D8A
Sinh_u                        16780683     0x1000D8B
Sinh_uu                       16780684     0x1000D8C
Sinh_ri                       16780685     0x1000D8D
Sinh_rii                      16780686     0x1000D8E
Sinh_lu                       16780687     0x1000D8F
Sinh_luu                      16780688     0x1000D90
Sinh_e                        16780689     0x1000D91
Sinh_ee                       16780690     0x1000D92
Sinh_ai                       16780691     0x1000D93
Sinh_o                        16780692     0x1000D94
Sinh_oo                       16780693     0x1000D95
Sinh_au                       16780694     0x1000D96
Sinh_ka                       16780698     0x1000D9A
Sinh_kha                      16780699     0x1000D9B
Sinh_ga                       16780700     0x1000D9C
Sinh_gha                      16780701     0x1000D9D
Sinh_ng2                      16780702     0x1000D9E
Sinh_nga                      16780703     0x1000D9F
Sinh_ca                       16780704     0x1000DA0
Sinh_cha                      16780705     0x1000DA1
Sinh_ja                       16780706     0x1000DA2
Sinh_jha                      16780707     0x1000DA3
Sinh_nya                      16780708     0x1000DA4
Sinh_jnya                     16780709     0x1000DA5
Sinh_nja                      16780710     0x1000DA6
Sinh_tta                      16780711     0x1000DA7
Sinh_ttha                     16780712     0x1000DA8
Sinh_dda                      16780713     0x1000DA9
Sinh_ddha                     16780714     0x1000DAA
Sinh_nna                      16780715     0x1000DAB
Sinh_ndda                     16780716     0x1000DAC
Sinh_tha                      16780717     0x1000DAD
Sinh_thha                     16780718     0x1000DAE
Sinh_dha                      16780719     0x1000DAF
Sinh_dhha                     16780720     0x1000DB0
Sinh_na                       16780721     0x1000DB1
Sinh_ndha                     16780723     0x1000DB3
Sinh_pa                       16780724     0x1000DB4
Sinh_pha                      16780725     0x1000DB5
Sinh_ba                       16780726     0x1000DB6
Sinh_bha                      16780727     0x1000DB7
Sinh_ma                       16780728     0x1000DB8
Sinh_mba                      16780729     0x1000DB9
Sinh_ya                       16780730     0x1000DBA
Sinh_ra                       16780731     0x1000DBB
Sinh_la                       16780733     0x1000DBD
Sinh_va                       16780736     0x1000DC0
Sinh_sha                      16780737     0x1000DC1
Sinh_ssha                     16780738     0x1000DC2
Sinh_sa                       16780739     0x1000DC3
Sinh_ha                       16780740     0x1000DC4
Sinh_lla                      16780741     0x1000DC5
Sinh_fa                       16780742     0x1000DC6
Sinh_al                       16780746     0x1000DCA
Sinh_aa2                      16780751     0x1000DCF
Sinh_ae2                      16780752     0x1000DD0
Sinh_aee2                     16780753     0x1000DD1
Sinh_i2                       16780754     0x1000DD2
Sinh_ii2                      16780755     0x1000DD3
Sinh_u2                       16780756     0x1000DD4
Sinh_uu2                      16780758     0x1000DD6
Sinh_ru2                      16780760     0x1000DD8
Sinh_e2                       16780761     0x1000DD9
Sinh_ee2                      16780762     0x1000DDA
Sinh_ai2                      16780763     0x1000DDB
Sinh_o2                       16780764     0x1000DDC
Sinh_oo2                      16780765     0x1000DDD
Sinh_au2                      16780766     0x1000DDE
Sinh_lu2                      16780767     0x1000DDF
Sinh_ruu2                     16780786     0x1000DF2
Sinh_luu2                     16780787     0x1000DF3
Sinh_kunddaliya               16780788     0x1000DF4
Georgian_an                   16781520     0x10010D0
Georgian_ban                  16781521     0x10010D1
Georgian_gan                  16781522     0x10010D2
Georgian_don                  16781523     0x10010D3
Georgian_en                   16781524     0x10010D4
Georgian_vin                  16781525     0x10010D5
Georgian_zen                  16781526     0x10010D6
Georgian_tan                  16781527     0x10010D7
Georgian_in                   16781528     0x10010D8
Georgian_kan                  16781529     0x10010D9
Georgian_las                  16781530     0x10010DA
Georgian_man                  16781531     0x10010DB
Georgian_nar                  16781532     0x10010DC
Georgian_on                   16781533     0x10010DD
Georgian_par                  16781534     0x10010DE
Georgian_zhar                 16781535     0x10010DF
Georgian_rae                  16781536     0x10010E0
Georgian_san                  16781537     0x10010E1
Georgian_tar                  16781538     0x10010E2
Georgian_un                   16781539     0x10010E3
Georgian_phar                 16781540     0x10010E4
Georgian_khar                 16781541     0x10010E5
Georgian_ghan                 16781542     0x10010E6
Georgian_qar                  16781543     0x10010E7
Georgian_shin                 16781544     0x10010E8
Georgian_chin                 16781545     0x10010E9
Georgian_can                  16781546     0x10010EA
Georgian_jil                  16781547     0x10010EB
Georgian_cil                  16781548     0x10010EC
Georgian_char                 16781549     0x10010ED
Georgian_xan                  16781550     0x10010EE
Georgian_jhan                 16781551     0x10010EF
Georgian_hae                  16781552     0x10010F0
Georgian_he                   16781553     0x10010F1
Georgian_hie                  16781554     0x10010F2
Georgian_we                   16781555     0x10010F3
Georgian_har                  16781556     0x10010F4
Georgian_hoe                  16781557     0x10010F5
Georgian_fi                   16781558     0x10010F6
Babovedot                     16784898     0x1001E02
babovedot                     16784899     0x1001E03
Dabovedot                     16784906     0x1001E0A
dabovedot                     16784907     0x1001E0B
Fabovedot                     16784926     0x1001E1E
fabovedot                     16784927     0x1001E1F
Lbelowdot                     16784950     0x1001E36
lbelowdot                     16784951     0x1001E37
Mabovedot                     16784960     0x1001E40
mabovedot                     16784961     0x1001E41
Pabovedot                     16784982     0x1001E56
pabovedot                     16784983     0x1001E57
Sabovedot                     16784992     0x1001E60
sabovedot                     16784993     0x1001E61
Tabovedot                     16785002     0x1001E6A
tabovedot                     16785003     0x1001E6B
Wgrave                        16785024     0x1001E80
wgrave                        16785025     0x1001E81
Wacute                        16785026     0x1001E82
wacute                        16785027     0x1001E83
Wdiaeresis                    16785028     0x1001E84
wdiaeresis                    16785029     0x1001E85
Xabovedot                     16785034     0x1001E8A
xabovedot                     16785035     0x1001E8B
Abelowdot                     16785056     0x1001EA0
abelowdot                     16785057     0x1001EA1
Ahook                         16785058     0x1001EA2
ahook                         16785059     0x1001EA3
Acircumflexacute              16785060     0x1001EA4
acircumflexacute              16785061     0x1001EA5
Acircumflexgrave              16785062     0x1001EA6
acircumflexgrave              16785063     0x1001EA7
Acircumflexhook               16785064     0x1001EA8
acircumflexhook               16785065     0x1001EA9
Acircumflextilde              16785066     0x1001EAA
acircumflextilde              16785067     0x1001EAB
Acircumflexbelowdot           16785068     0x1001EAC
acircumflexbelowdot           16785069     0x1001EAD
Abreveacute                   16785070     0x1001EAE
abreveacute                   16785071     0x1001EAF
Abrevegrave                   16785072     0x1001EB0
abrevegrave                   16785073     0x1001EB1
Abrevehook                    16785074     0x1001EB2
abrevehook                    16785075     0x1001EB3
Abrevetilde                   16785076     0x1001EB4
abrevetilde                   16785077     0x1001EB5
Abrevebelowdot                16785078     0x1001EB6
abrevebelowdot                16785079     0x1001EB7
Ebelowdot                     16785080     0x1001EB8
ebelowdot                     16785081     0x1001EB9
Ehook                         16785082     0x1001EBA
ehook                         16785083     0x1001EBB
Etilde                        16785084     0x1001EBC
etilde                        16785085     0x1001EBD
Ecircumflexacute              16785086     0x1001EBE
ecircumflexacute              16785087     0x1001EBF
Ecircumflexgrave              16785088     0x1001EC0
ecircumflexgrave              16785089     0x1001EC1
Ecircumflexhook               16785090     0x1001EC2
ecircumflexhook               16785091     0x1001EC3
Ecircumflextilde              16785092     0x1001EC4
ecircumflextilde              16785093     0x1001EC5
Ecircumflexbelowdot           16785094     0x1001EC6
ecircumflexbelowdot           16785095     0x1001EC7
Ihook                         16785096     0x1001EC8
ihook                         16785097     0x1001EC9
Ibelowdot                     16785098     0x1001ECA
ibelowdot                     16785099     0x1001ECB
Obelowdot                     16785100     0x1001ECC
obelowdot                     16785101     0x1001ECD
Ohook                         16785102     0x1001ECE
ohook                         16785103     0x1001ECF
Ocircumflexacute              16785104     0x1001ED0
ocircumflexacute              16785105     0x1001ED1
Ocircumflexgrave              16785106     0x1001ED2
ocircumflexgrave              16785107     0x1001ED3
Ocircumflexhook               16785108     0x1001ED4
ocircumflexhook               16785109     0x1001ED5
Ocircumflextilde              16785110     0x1001ED6
ocircumflextilde              16785111     0x1001ED7
Ocircumflexbelowdot           16785112     0x1001ED8
ocircumflexbelowdot           16785113     0x1001ED9
Ohornacute                    16785114     0x1001EDA
ohornacute                    16785115     0x1001EDB
Ohorngrave                    16785116     0x1001EDC
ohorngrave                    16785117     0x1001EDD
Ohornhook                     16785118     0x1001EDE
ohornhook                     16785119     0x1001EDF
Ohorntilde                    16785120     0x1001EE0
ohorntilde                    16785121     0x1001EE1
Ohornbelowdot                 16785122     0x1001EE2
ohornbelowdot                 16785123     0x1001EE3
Ubelowdot                     16785124     0x1001EE4
ubelowdot                     16785125     0x1001EE5
Uhook                         16785126     0x1001EE6
uhook                         16785127     0x1001EE7
Uhornacute                    16785128     0x1001EE8
uhornacute                    16785129     0x1001EE9
Uhorngrave                    16785130     0x1001EEA
uhorngrave                    16785131     0x1001EEB
Uhornhook                     16785132     0x1001EEC
uhornhook                     16785133     0x1001EED
Uhorntilde                    16785134     0x1001EEE
uhorntilde                    16785135     0x1001EEF
Uhornbelowdot                 16785136     0x1001EF0
uhornbelowdot                 16785137     0x1001EF1
Ygrave                        16785138     0x1001EF2
ygrave                        16785139     0x1001EF3
Ybelowdot                     16785140     0x1001EF4
ybelowdot                     16785141     0x1001EF5
Yhook                         16785142     0x1001EF6
yhook                         16785143     0x1001EF7
Ytilde                        16785144     0x1001EF8
ytilde                        16785145     0x1001EF9
zerosuperior                  16785520     0x1002070
foursuperior                  16785524     0x1002074
fivesuperior                  16785525     0x1002075
sixsuperior                   16785526     0x1002076
sevensuperior                 16785527     0x1002077
eightsuperior                 16785528     0x1002078
ninesuperior                  16785529     0x1002079
zerosubscript                 16785536     0x1002080
onesubscript                  16785537     0x1002081
twosubscript                  16785538     0x1002082
threesubscript                16785539     0x1002083
foursubscript                 16785540     0x1002084
fivesubscript                 16785541     0x1002085
sixsubscript                  16785542     0x1002086
sevensubscript                16785543     0x1002087
eightsubscript                16785544     0x1002088
ninesubscript                 16785545     0x1002089
EcuSign                       16785568     0x10020A0
ColonSign                     16785569     0x10020A1
CruzeiroSign                  16785570     0x10020A2
FFrancSign                    16785571     0x10020A3
LiraSign                      16785572     0x10020A4
MillSign                      16785573     0x10020A5
NairaSign                     16785574     0x10020A6
PesetaSign                    16785575     0x10020A7
RupeeSign                     16785576     0x10020A8
WonSign                       16785577     0x10020A9
NewSheqelSign                 16785578     0x10020AA
DongSign                      16785579     0x10020AB
partdifferential              16785922     0x1002202
emptyset                      16785925     0x1002205
elementof                     16785928     0x1002208
notelementof                  16785929     0x1002209
containsas                    16785931     0x100220B
squareroot                    16785946     0x100221A
cuberoot                      16785947     0x100221B
fourthroot                    16785948     0x100221C
dintegral                     16785964     0x100222C
tintegral                     16785965     0x100222D
because                       16785973     0x1002235
notapproxeq                   16785991     0x1002247
approxeq                      16785992     0x1002248
notidentical                  16786018     0x1002262
stricteq                      16786019     0x1002263
braille_blank                 16787456     0x1002800
braille_dots_1                16787457     0x1002801
braille_dots_2                16787458     0x1002802
braille_dots_12               16787459     0x1002803
braille_dots_3                16787460     0x1002804
braille_dots_13               16787461     0x1002805
braille_dots_23               16787462     0x1002806
braille_dots_123              16787463     0x1002807
braille_dots_4                16787464     0x1002808
braille_dots_14               16787465     0x1002809
braille_dots_24               16787466     0x100280A
braille_dots_124              16787467     0x100280B
braille_dots_34               16787468     0x100280C
braille_dots_134              16787469     0x100280D
braille_dots_234              16787470     0x100280E
braille_dots_1234             16787471     0x100280F
braille_dots_5                16787472     0x1002810
braille_dots_15               16787473     0x1002811
braille_dots_25               16787474     0x1002812
braille_dots_125              16787475     0x1002813
braille_dots_35               16787476     0x1002814
braille_dots_135              16787477     0x1002815
braille_dots_235              16787478     0x1002816
braille_dots_1235             16787479     0x1002817
braille_dots_45               16787480     0x1002818
braille_dots_145              16787481     0x1002819
braille_dots_245              16787482     0x100281A
braille_dots_1245             16787483     0x100281B
braille_dots_345              16787484     0x100281C
braille_dots_1345             16787485     0x100281D
braille_dots_2345             16787486     0x100281E
braille_dots_12345            16787487     0x100281F
braille_dots_6                16787488     0x1002820
braille_dots_16               16787489     0x1002821
braille_dots_26               16787490     0x1002822
braille_dots_126              16787491     0x1002823
braille_dots_36               16787492     0x1002824
braille_dots_136              16787493     0x1002825
braille_dots_236              16787494     0x1002826
braille_dots_1236             16787495     0x1002827
braille_dots_46               16787496     0x1002828
braille_dots_146              16787497     0x1002829
braille_dots_246              16787498     0x100282A
braille_dots_1246             16787499     0x100282B
braille_dots_346              16787500     0x100282C
braille_dots_1346             16787501     0x100282D
braille_dots_2346             16787502     0x100282E
braille_dots_12346            16787503     0x100282F
braille_dots_56               16787504     0x1002830
braille_dots_156              16787505     0x1002831
braille_dots_256              16787506     0x1002832
braille_dots_1256             16787507     0x1002833
braille_dots_356              16787508     0x1002834
braille_dots_1356             16787509     0x1002835
braille_dots_2356             16787510     0x1002836
braille_dots_12356            16787511     0x1002837
braille_dots_456              16787512     0x1002838
braille_dots_1456             16787513     0x1002839
braille_dots_2456             16787514     0x100283A
braille_dots_12456            16787515     0x100283B
braille_dots_3456             16787516     0x100283C
braille_dots_13456            16787517     0x100283D
braille_dots_23456            16787518     0x100283E
braille_dots_123456           16787519     0x100283F
braille_dots_7                16787520     0x1002840
braille_dots_17               16787521     0x1002841
braille_dots_27               16787522     0x1002842
braille_dots_127              16787523     0x1002843
braille_dots_37               16787524     0x1002844
braille_dots_137              16787525     0x1002845
braille_dots_237              16787526     0x1002846
braille_dots_1237             16787527     0x1002847
braille_dots_47               16787528     0x1002848
braille_dots_147              16787529     0x1002849
braille_dots_247              16787530     0x100284A
braille_dots_1247             16787531     0x100284B
braille_dots_347              16787532     0x100284C
braille_dots_1347             16787533     0x100284D
braille_dots_2347             16787534     0x100284E
braille_dots_12347            16787535     0x100284F
braille_dots_57               16787536     0x1002850
braille_dots_157              16787537     0x1002851
braille_dots_257              16787538     0x1002852
braille_dots_1257             16787539     0x1002853
braille_dots_357              16787540     0x1002854
braille_dots_1357             16787541     0x1002855
braille_dots_2357             16787542     0x1002856
braille_dots_12357            16787543     0x1002857
braille_dots_457              16787544     0x1002858
braille_dots_1457             16787545     0x1002859
braille_dots_2457             16787546     0x100285A
braille_dots_12457            16787547     0x100285B
braille_dots_3457             16787548     0x100285C
braille_dots_13457            16787549     0x100285D
braille_dots_23457            16787550     0x100285E
braille_dots_123457           16787551     0x100285F
braille_dots_67               16787552     0x1002860
braille_dots_167              16787553     0x1002861
braille_dots_267              16787554     0x1002862
braille_dots_1267             16787555     0x1002863
braille_dots_367              16787556     0x1002864
braille_dots_1367             16787557     0x1002865
braille_dots_2367             16787558     0x1002866
braille_dots_12367            16787559     0x1002867
braille_dots_467              16787560     0x1002868
braille_dots_1467             16787561     0x1002869
braille_dots_2467             16787562     0x100286A
braille_dots_12467            16787563     0x100286B
braille_dots_3467             16787564     0x100286C
braille_dots_13467            16787565     0x100286D
braille_dots_23467            16787566     0x100286E
braille_dots_123467           16787567     0x100286F
braille_dots_567              16787568     0x1002870
braille_dots_1567             16787569     0x1002871
braille_dots_2567             16787570     0x1002872
braille_dots_12567            16787571     0x1002873
braille_dots_3567             16787572     0x1002874
braille_dots_13567            16787573     0x1002875
braille_dots_23567            16787574     0x1002876
braille_dots_123567           16787575     0x1002877
braille_dots_4567             16787576     0x1002878
braille_dots_14567            16787577     0x1002879
braille_dots_24567            16787578     0x100287A
braille_dots_124567           16787579     0x100287B
braille_dots_34567            16787580     0x100287C
braille_dots_134567           16787581     0x100287D
braille_dots_234567           16787582     0x100287E
braille_dots_1234567          16787583     0x100287F
braille_dots_8                16787584     0x1002880
braille_dots_18               16787585     0x1002881
braille_dots_28               16787586     0x1002882
braille_dots_128              16787587     0x1002883
braille_dots_38               16787588     0x1002884
braille_dots_138              16787589     0x1002885
braille_dots_238              16787590     0x1002886
braille_dots_1238             16787591     0x1002887
braille_dots_48               16787592     0x1002888
braille_dots_148              16787593     0x1002889
braille_dots_248              16787594     0x100288A
braille_dots_1248             16787595     0x100288B
braille_dots_348              16787596     0x100288C
braille_dots_1348             16787597     0x100288D
braille_dots_2348             16787598     0x100288E
braille_dots_12348            16787599     0x100288F
braille_dots_58               16787600     0x1002890
braille_dots_158              16787601     0x1002891
braille_dots_258              16787602     0x1002892
braille_dots_1258             16787603     0x1002893
braille_dots_358              16787604     0x1002894
braille_dots_1358             16787605     0x1002895
braille_dots_2358             16787606     0x1002896
braille_dots_12358            16787607     0x1002897
braille_dots_458              16787608     0x1002898
braille_dots_1458             16787609     0x1002899
braille_dots_2458             16787610     0x100289A
braille_dots_12458            16787611     0x100289B
braille_dots_3458             16787612     0x100289C
braille_dots_13458            16787613     0x100289D
braille_dots_23458            16787614     0x100289E
braille_dots_123458           16787615     0x100289F
braille_dots_68               16787616     0x10028A0
braille_dots_168              16787617     0x10028A1
braille_dots_268              16787618     0x10028A2
braille_dots_1268             16787619     0x10028A3
braille_dots_368              16787620     0x10028A4
braille_dots_1368             16787621     0x10028A5
braille_dots_2368             16787622     0x10028A6
braille_dots_12368            16787623     0x10028A7
braille_dots_468              16787624     0x10028A8
braille_dots_1468             16787625     0x10028A9
braille_dots_2468             16787626     0x10028AA
braille_dots_12468            16787627     0x10028AB
braille_dots_3468             16787628     0x10028AC
braille_dots_13468            16787629     0x10028AD
braille_dots_23468            16787630     0x10028AE
braille_dots_123468           16787631     0x10028AF
braille_dots_568              16787632     0x10028B0
braille_dots_1568             16787633     0x10028B1
braille_dots_2568             16787634     0x10028B2
braille_dots_12568            16787635     0x10028B3
braille_dots_3568             16787636     0x10028B4
braille_dots_13568            16787637     0x10028B5
braille_dots_23568            16787638     0x10028B6
braille_dots_123568           16787639     0x10028B7
braille_dots_4568             16787640     0x10028B8
braille_dots_14568            16787641     0x10028B9
braille_dots_24568            16787642     0x10028BA
braille_dots_124568           16787643     0x10028BB
braille_dots_34568            16787644     0x10028BC
braille_dots_134568           16787645     0x10028BD
braille_dots_234568           16787646     0x10028BE
braille_dots_1234568          16787647     0x10028BF
braille_dots_78               16787648     0x10028C0
braille_dots_178              16787649     0x10028C1
braille_dots_278              16787650     0x10028C2
braille_dots_1278             16787651     0x10028C3
braille_dots_378              16787652     0x10028C4
braille_dots_1378             16787653     0x10028C5
braille_dots_2378             16787654     0x10028C6
braille_dots_12378            16787655     0x10028C7
braille_dots_478              16787656     0x10028C8
braille_dots_1478             16787657     0x10028C9
braille_dots_2478             16787658     0x10028CA
braille_dots_12478            16787659     0x10028CB
braille_dots_3478             16787660     0x10028CC
braille_dots_13478            16787661     0x10028CD
braille_dots_23478            16787662     0x10028CE
braille_dots_123478           16787663     0x10028CF
braille_dots_578              16787664     0x10028D0
braille_dots_1578             16787665     0x10028D1
braille_dots_2578             16787666     0x10028D2
braille_dots_12578            16787667     0x10028D3
braille_dots_3578             16787668     0x10028D4
braille_dots_13578            16787669     0x10028D5
braille_dots_23578            16787670     0x10028D6
braille_dots_123578           16787671     0x10028D7
braille_dots_4578             16787672     0x10028D8
braille_dots_14578            16787673     0x10028D9
braille_dots_24578            16787674     0x10028DA
braille_dots_124578           16787675     0x10028DB
braille_dots_34578            16787676     0x10028DC
braille_dots_134578           16787677     0x10028DD
braille_dots_234578           16787678     0x10028DE
braille_dots_1234578          16787679     0x10028DF
braille_dots_678              16787680     0x10028E0
braille_dots_1678             16787681     0x10028E1
braille_dots_2678             16787682     0x10028E2
braille_dots_12678            16787683     0x10028E3
braille_dots_3678             16787684     0x10028E4
braille_dots_13678            16787685     0x10028E5
braille_dots_23678            16787686     0x10028E6
braille_dots_123678           16787687     0x10028E7
braille_dots_4678             16787688     0x10028E8
braille_dots_14678            16787689     0x10028E9
braille_dots_24678            16787690     0x10028EA
braille_dots_124678           16787691     0x10028EB
braille_dots_34678            16787692     0x10028EC
braille_dots_134678           16787693     0x10028ED
braille_dots_234678           16787694     0x10028EE
braille_dots_1234678          16787695     0x10028EF
braille_dots_5678             16787696     0x10028F0
braille_dots_15678            16787697     0x10028F1
braille_dots_25678            16787698     0x10028F2
braille_dots_125678           16787699     0x10028F3
braille_dots_35678            16787700     0x10028F4
braille_dots_135678           16787701     0x10028F5
braille_dots_235678           16787702     0x10028F6
braille_dots_1235678          16787703     0x10028F7
braille_dots_45678            16787704     0x10028F8
braille_dots_145678           16787705     0x10028F9
braille_dots_245678           16787706     0x10028FA
braille_dots_1245678          16787707     0x10028FB
braille_dots_345678           16787708     0x10028FC
braille_dots_1345678          16787709     0x10028FD
braille_dots_2345678          16787710     0x10028FE
braille_dots_12345678         16787711     0x10028FF
SunFA_Grave                  268828416     0x1005FF00
SunFA_Circum                 268828417     0x1005FF01
SunFA_Tilde                  268828418     0x1005FF02
SunFA_Acute                  268828419     0x1005FF03
SunFA_Diaeresis              268828420     0x1005FF04
SunFA_Cedilla                268828421     0x1005FF05
SunF36                       268828432     0x1005FF10







|
|













|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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

































































































































































































































































































































































.CS


































































































































































































































































































































































SunFA_Grave                  268828416     0x1005FF00
SunFA_Circum                 268828417     0x1005FF01
SunFA_Tilde                  268828418     0x1005FF02
SunFA_Acute                  268828419     0x1005FF03
SunFA_Diaeresis              268828420     0x1005FF04
SunFA_Cedilla                268828421     0x1005FF05
SunF36                       268828432     0x1005FF10
2056
2057
2058
2059
2060
2061
2062











































































































































2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074


2075
2076
2077
2078
2079
2080
2081
SunAudioLowerVolume          268828535     0x1005FF77
SunAudioMute                 268828536     0x1005FF78
SunAudioRaiseVolume          268828537     0x1005FF79
SunVideoDegauss              268828538     0x1005FF7A
SunVideoLowerBrightness      268828539     0x1005FF7B
SunVideoRaiseBrightness      268828540     0x1005FF7C
SunPowerSwitchShift          268828541     0x1005FF7D











































































































































XF86Switch_VT_1              269024769     0x1008FE01
XF86Switch_VT_2              269024770     0x1008FE02
XF86Switch_VT_3              269024771     0x1008FE03
XF86Switch_VT_4              269024772     0x1008FE04
XF86Switch_VT_5              269024773     0x1008FE05
XF86Switch_VT_6              269024774     0x1008FE06
XF86Switch_VT_7              269024775     0x1008FE07
XF86Switch_VT_8              269024776     0x1008FE08
XF86Switch_VT_9              269024777     0x1008FE09
XF86Switch_VT_10             269024778     0x1008FE0A
XF86Switch_VT_11             269024779     0x1008FE0B
XF86Switch_VT_12             269024780     0x1008FE0C


XF86Ungrab                   269024800     0x1008FE20
XF86ClearGrab                269024801     0x1008FE21
XF86Next_VMode               269024802     0x1008FE22
XF86Prev_VMode               269024803     0x1008FE23
XF86LogWindowTree            269024804     0x1008FE24
XF86LogGrabInfo              269024805     0x1008FE25
XF86ModeLock                 269025025     0x1008FF01







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>
>







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

2246
2247
2248
2249
2250
2251
2252
2253
XF86TouchpadOff              269025201     0x1008FFB1
XF86AudioMicMute             269025202     0x1008FFB2
XF86Keyboard                 269025203     0x1008FFB3
XF86WWAN                     269025204     0x1008FFB4
XF86RFKill                   269025205     0x1008FFB5
XF86AudioPreset              269025206     0x1008FFB6
XF86RotationLockToggle       269025207     0x1008FFB7

.CE
.SH "SEE ALSO"
bind(n), event(n)
.SH KEYWORDS
bind, binding, event, keysym
'\" Local Variables:
'\" mode: nroff
'\" End:







>








1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
XF86TouchpadOff              269025201     0x1008FFB1
XF86AudioMicMute             269025202     0x1008FFB2
XF86Keyboard                 269025203     0x1008FFB3
XF86WWAN                     269025204     0x1008FFB4
XF86RFKill                   269025205     0x1008FFB5
XF86AudioPreset              269025206     0x1008FFB6
XF86RotationLockToggle       269025207     0x1008FFB7
XF86FullScreen               269025208     0x1008FFB8
.CE
.SH "SEE ALSO"
bind(n), event(n)
.SH KEYWORDS
bind, binding, event, keysym
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/label.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH label n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
label \- Create and manipulate 'label' non-interactive text or image widgets
.SH SYNOPSIS
\fBlabel\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH label n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
label \- Create and manipulate 'label' non-interactive text or image widgets
.SH SYNOPSIS
\fBlabel\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable
76
77
78
79
80
81
82

83
84

85
86
87
88

89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabel\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlabel\fR
command.
.SH BINDINGS
.PP
When a new label is created, it has no default event bindings:
labels are not intended to be interactive.
.SH EXAMPLE
.PP
.CS
# Make the widgets
\fBlabel\fR .t \-text "This widget is at the top"    \-bg red
\fBlabel\fR .b \-text "This widget is at the bottom" \-bg green
\fBlabel\fR .l \-text "Left\enHand\enSide"
\fBlabel\fR .r \-text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
pack .t   \-side top    \-fill x
pack .b   \-side bottom \-fill x
pack .l   \-side left   \-fill y
pack .r   \-side right  \-fill y
pack .mid \-expand 1    \-fill both
.CE
.SH "SEE ALSO"
labelframe(n), button(n), ttk::label(n)
.SH KEYWORDS
label, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







>

|
>




>


>




















|
|
|
|



|
|
|
|
|








76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabel\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlabel\fR
command.
.SH BINDINGS
.PP
When a new label is created, it has no default event bindings:
labels are not intended to be interactive.
.SH EXAMPLE
.PP
.CS
# Make the widgets
\fBlabel\fR .t -text "This widget is at the top"    -bg red
\fBlabel\fR .b -text "This widget is at the bottom" -bg green
\fBlabel\fR .l -text "Left\enHand\enSide"
\fBlabel\fR .r -text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
pack .t   -side top    -fill x
pack .b   -side bottom -fill x
pack .l   -side left   -fill y
pack .r   -side right  -fill y
pack .mid -expand 1    -fill both
.CE
.SH "SEE ALSO"
labelframe(n), button(n), ttk::label(n)
.SH KEYWORDS
label, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/labelframe.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH labelframe n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
labelframe \- Create and manipulate 'labelframe' labelled container widgets
.SH SYNOPSIS
\fBlabelframe\fR \fIpathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightbackground	\-pady
\-cursor	\-highlightcolor	\-relief
\-font	\-highlightthickness	\-takefocus
\-foreground	\-padx	\-text
.SE
.SH "WIDGET-SPECIFIC OPTIONS"







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH labelframe n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
labelframe \- Create and manipulate 'labelframe' labelled container widgets
.SH SYNOPSIS
\fBlabelframe\fI pathName\fR ?\fIoptions\fR?
.SO
\-borderwidth	\-highlightbackground	\-pady
\-cursor	\-highlightcolor	\-relief
\-font	\-highlightthickness	\-takefocus
\-foreground	\-padx	\-text
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
97
98
99
100
101
102
103

104
105

106
107
108
109

110
111

112
113
114
115
116
117
118
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR

Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If







>

|
>




>


>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlabelframe\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
.SH EXAMPLE
.PP
This shows how to build part of a GUI for a hamburger vendor. The
\fBlabelframe\fR widgets are used to organize the available choices by
the kinds of things that the choices are being made over.
.PP
.CS
grid [\fBlabelframe\fR .burger \-text "Burger"] \e
     [\fBlabelframe\fR .bun    \-text "Bun"] \-sticky news
grid [\fBlabelframe\fR .cheese \-text "Cheese Option"] \e
     [\fBlabelframe\fR .pickle \-text "Pickle Option"] \-sticky news
foreach {type name val} {
    burger Beef    beef
    burger Lamb    lamb
    burger Vegetarian beans

    bun    Plain   white
    bun    Sesame  seeds







|
|
|
|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
.SH EXAMPLE
.PP
This shows how to build part of a GUI for a hamburger vendor. The
\fBlabelframe\fR widgets are used to organize the available choices by
the kinds of things that the choices are being made over.
.PP
.CS
grid [\fBlabelframe\fR .burger -text "Burger"] \e
     [\fBlabelframe\fR .bun    -text "Bun"] -sticky news
grid [\fBlabelframe\fR .cheese -text "Cheese Option"] \e
     [\fBlabelframe\fR .pickle -text "Pickle Option"] -sticky news
foreach {type name val} {
    burger Beef    beef
    burger Lamb    lamb
    burger Vegetarian beans

    bun    Plain   white
    bun    Sesame  seeds
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    cheese "Monterey Jack" jack

    pickle None    none
    pickle Gherkins gherkins
    pickle Onions  onion
    pickle Chili   chili
} {
    set w [radiobutton .$type.$val \-text $name \-anchor w \e
            \-variable $type \-value $val]
    pack $w \-side top \-fill x
}
set burger beef
set bun    white
set cheese none
set pickle none
.CE
.SH "SEE ALSO"
frame(n), label(n), ttk::labelframe(n)
.SH KEYWORDS
labelframe, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|













157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    cheese "Monterey Jack" jack

    pickle None    none
    pickle Gherkins gherkins
    pickle Onions  onion
    pickle Chili   chili
} {
    set w [radiobutton .$type.$val -text $name -anchor w \e
            -variable $type -value $val]
    pack $w -side top -fill x
}
set burger beef
set bun    white
set cheese none
set pickle none
.CE
.SH "SEE ALSO"
frame(n), label(n), ttk::labelframe(n)
.SH KEYWORDS
labelframe, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/listbox.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH listbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
listbox \- Create and manipulate 'listbox' item list widgets
.SH SYNOPSIS
\fBlistbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-disabledforeground	\-exportselection	\-font
\-foreground	\-highlightbackground	\-highlightcolor
\-highlightthickness	\-justify	\-relief
\-selectbackground	\-selectborderwidth	\-selectforeground
\-setgrid	\-takefocus	\-xscrollcommand







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH listbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
listbox \- Create and manipulate 'listbox' item list widgets
.SH SYNOPSIS
\fBlistbox\fI pathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-disabledforeground	\-exportselection	\-font
\-foreground	\-highlightbackground	\-highlightcolor
\-highlightthickness	\-justify	\-relief
\-selectbackground	\-selectborderwidth	\-selectforeground
\-setgrid	\-takefocus	\-xscrollcommand
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128



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

144
145
146
147
148
149
150
151
152

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

168
169
170
171
172
173
174

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

190
191
192
193
194
195
196

197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220

221
222
223
224
225
226
227

228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

249
250
251
252
253

254
255
256
257
258

259
260
261
262
263
264

265
266
267
268
269
270
271

272
273
274
275
276

277
278
279
280
281
282
283
284
285
They also support scanning, as described below.
.SH "INDICES"
.PP
Many of the widget commands for listboxes take one or more indices
as arguments.
An index specifies a particular element of the listbox, in any of
the following ways:
.TP 12
\fInumber\fR
.
Specifies the element as a numerical index, where 0 corresponds
to the first element in the listbox.
.TP 12
\fBactive\fR
.
Indicates the element that has the location cursor.  This element
will be displayed as specified by \fB\-activestyle\fR when the listbox
has the keyboard focus, and it is specified with the \fBactivate\fR
widget command.
.TP 12
\fBanchor\fR
.
Indicates the anchor point for the selection, which is set with the
\fBselection anchor\fR widget command.
.TP 12
\fBend\fR
.
Indicates the end of the listbox.
For most commands this refers to the last element in the listbox,
but for a few commands such as \fBindex\fR and \fBinsert\fR
it refers to the element just after the last one.
.TP 12
\fB@\fIx\fB,\fIy\fR
Indicates the element that covers the point in the listbox window
specified by \fIx\fR and \fIy\fR (in pixel coordinates).  If no
element covers that point, then the closest element to that
point is used.
.LP



In the widget command descriptions below, arguments named \fIindex\fR,
\fIfirst\fR, and \fIlast\fR always contain text indices in one of
the above forms.
.SH "WIDGET COMMAND"
.PP
The \fBlistbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for listbox widgets:

.TP
\fIpathName \fBactivate\fR \fIindex\fR
.
Sets the active element to the one indicated by \fIindex\fR.
If \fIindex\fR is outside the range of elements in the listbox
then the closest element is activated.
The active element is drawn as specified by \fB\-activestyle\fR when the
widget has the input focus, and its index may be retrieved with the
index \fBactive\fR.

.TP
\fIpathName \fBbbox\fR \fIindex\fR
.
Returns a list of four numbers describing the bounding box of
the text in the element given by \fIindex\fR.
The first two elements of the list give the x and y coordinates
of the upper-left corner of the screen area covered by the text
(specified in pixels relative to the widget) and the last two
elements give the width and height of the area, in pixels.
If no part of the element given by \fIindex\fR is visible on the
screen,
or if \fIindex\fR refers to a non-existent element,
then the result is an empty string;  if the element is
partially visible, the result gives the full area of the element,
including any parts that are not visible.

.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.

.TP
\fIpathName \fBcurselection\fR
.
Returns a list containing the numerical indices of
all of the elements in the listbox that are currently selected.
If there are no elements selected in the listbox then an empty
string is returned.

.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?
.
Deletes one or more elements of the listbox.  \fIFirst\fR and \fIlast\fR
are indices specifying the first and last elements in the range
to delete.  If \fIlast\fR is not specified it defaults to
\fIfirst\fR, i.e. a single element is deleted.

.TP
\fIpathName \fBget \fIfirst\fR ?\fIlast\fR?
.
If \fIlast\fR is omitted, returns the contents of the listbox
element indicated by \fIfirst\fR,
or an empty string if \fIfirst\fR refers to a non-existent element.
If \fIlast\fR is specified, the command returns a list whose elements
are all of the listbox elements between \fIfirst\fR and \fIlast\fR,
inclusive.
Both \fIfirst\fR and \fIlast\fR may have any of the standard
forms for indices.

.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the integer index value that corresponds to \fIindex\fR.
If \fIindex\fR is \fBend\fR the return value is a count of the number
of elements in the listbox (not the index of the last element).

.TP
\fIpathName \fBinsert \fIindex \fR?\fIelement element ...\fR?
.
Inserts zero or more new elements in the list just before the
element given by \fIindex\fR.  If \fIindex\fR is specified as
\fBend\fR then the new elements are added to the end of the
list.  Returns an empty string.

.TP
\fIpathName \fBitemcget \fIindex option\fR
.
Returns the current value of the item configuration option given
by \fIoption\fR. \fIOption\fR may have any of the values accepted
by the \fBitemconfigure\fR command.

.TP
\fIpathName \fBitemconfigure \fIindex\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
Query or modify the configuration options of an item in the listbox.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the item (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. The following options
are currently supported for items:
.RS

.TP
\fB\-background \fIcolor\fR
.
\fIColor\fR specifies the background color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.

.TP
\fB\-foreground \fIcolor\fR
.
\fIColor\fR specifies the foreground color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.

.TP
\fB\-selectbackground \fIcolor\fR
.
\fIcolor\fR specifies the background color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.

.TP
\fB\-selectforeground \fIcolor\fR
.
\fIcolor\fR specifies the foreground color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.RE

.TP
\fIpathName \fBnearest \fIy\fR
.
Given a y-coordinate within the listbox window, this command returns
the index of the (visible) listbox element nearest to that y-coordinate.

.TP
\fIpathName \fBscan\fR \fIoption args\fR
.
This command is used to implement scanning on listboxes.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.







<
|
<


<
|
<




<
|
<


<
|
<




<
|




|
>
>
>















>

|







>

|













>

|





>















>







>







>











>






>







>






>















>





>





>






>







>





>

|







91
92
93
94
95
96
97

98

99
100

101

102
103
104
105

106

107
108

109

110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
They also support scanning, as described below.
.SH "INDICES"
.PP
Many of the widget commands for listboxes take one or more indices
as arguments.
An index specifies a particular element of the listbox, in any of
the following ways:

.IP \fInumber\fR 12

Specifies the element as a numerical index, where 0 corresponds
to the first element in the listbox.

.IP \fBactive\fR 12

Indicates the element that has the location cursor.  This element
will be displayed as specified by \fB\-activestyle\fR when the listbox
has the keyboard focus, and it is specified with the \fBactivate\fR
widget command.

.IP \fBanchor\fR 12

Indicates the anchor point for the selection, which is set with the
\fBselection anchor\fR widget command.

.IP \fBend\fR 12

Indicates the end of the listbox.
For most commands this refers to the last element in the listbox,
but for a few commands such as \fBindex\fR and \fBinsert\fR
it refers to the element just after the last one.

.IP \fB@\fIx\fB,\fIy\fR 12
Indicates the element that covers the point in the listbox window
specified by \fIx\fR and \fIy\fR (in pixel coordinates).  If no
element covers that point, then the closest element to that
point is used.
.PP
Indexes support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\fR.
In the widget command descriptions below, arguments named \fIindex\fR,
\fIfirst\fR, and \fIlast\fR always contain text indices in one of
the above forms.
.SH "WIDGET COMMAND"
.PP
The \fBlistbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for listbox widgets:
.\" METHOD: activate
.TP
\fIpathName \fBactivate\fI index\fR
.
Sets the active element to the one indicated by \fIindex\fR.
If \fIindex\fR is outside the range of elements in the listbox
then the closest element is activated.
The active element is drawn as specified by \fB\-activestyle\fR when the
widget has the input focus, and its index may be retrieved with the
index \fBactive\fR.
.\" METHOD: bbox
.TP
\fIpathName \fBbbox\fI index\fR
.
Returns a list of four numbers describing the bounding box of
the text in the element given by \fIindex\fR.
The first two elements of the list give the x and y coordinates
of the upper-left corner of the screen area covered by the text
(specified in pixels relative to the widget) and the last two
elements give the width and height of the area, in pixels.
If no part of the element given by \fIindex\fR is visible on the
screen,
or if \fIindex\fR refers to a non-existent element,
then the result is an empty string;  if the element is
partially visible, the result gives the full area of the element,
including any parts that are not visible.
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBlistbox\fR
command.
.\" METHOD: curselection
.TP
\fIpathName \fBcurselection\fR
.
Returns a list containing the numerical indices of
all of the elements in the listbox that are currently selected.
If there are no elements selected in the listbox then an empty
string is returned.
.\" METHOD: delete
.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?
.
Deletes one or more elements of the listbox.  \fIFirst\fR and \fIlast\fR
are indices specifying the first and last elements in the range
to delete.  If \fIlast\fR is not specified it defaults to
\fIfirst\fR, i.e. a single element is deleted.
.\" METHOD: get
.TP
\fIpathName \fBget \fIfirst\fR ?\fIlast\fR?
.
If \fIlast\fR is omitted, returns the contents of the listbox
element indicated by \fIfirst\fR,
or an empty string if \fIfirst\fR refers to a non-existent element.
If \fIlast\fR is specified, the command returns a list whose elements
are all of the listbox elements between \fIfirst\fR and \fIlast\fR,
inclusive.
Both \fIfirst\fR and \fIlast\fR may have any of the standard
forms for indices.
.\" METHOD: index
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the integer index value that corresponds to \fIindex\fR.
If \fIindex\fR is \fBend\fR the return value is a count of the number
of elements in the listbox (not the index of the last element).
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fIindex \fR?\fIelement element ...\fR?
.
Inserts zero or more new elements in the list just before the
element given by \fIindex\fR.  If \fIindex\fR is specified as
\fBend\fR then the new elements are added to the end of the
list.  Returns an empty string.
.\" METHOD: itemcget
.TP
\fIpathName \fBitemcget \fIindex option\fR
.
Returns the current value of the item configuration option given
by \fIoption\fR. \fIOption\fR may have any of the values accepted
by the \fBitemconfigure\fR command.
.\" METHOD: itemconfigure
.TP
\fIpathName \fBitemconfigure \fIindex\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
Query or modify the configuration options of an item in the listbox.
If no \fIoption\fR is specified, returns a list describing all of
the available options for the item (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. The following options
are currently supported for items:
.RS
.\" OPTION: -background
.TP
\fB\-background \fIcolor\fR
.
\fIColor\fR specifies the background color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.
.\" OPTION: -foreground
.TP
\fB\-foreground \fIcolor\fR
.
\fIColor\fR specifies the foreground color to use when displaying the
item. It may have any of the forms accepted by \fBTk_GetColor\fR.
.\" OPTION: -selectbackground
.TP
\fB\-selectbackground \fIcolor\fR
.
\fIcolor\fR specifies the background color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.\" OPTION: -selectforeground
.TP
\fB\-selectforeground \fIcolor\fR
.
\fIcolor\fR specifies the foreground color to use when displaying the
item while it is selected. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.RE
.\" METHOD: nearest
.TP
\fIpathName \fBnearest \fIy\fR
.
Given a y-coordinate within the listbox window, this command returns
the index of the (visible) listbox element nearest to that y-coordinate.
.\" METHOD: scan
.TP
\fIpathName \fBscan\fI option args\fR
.
This command is used to implement scanning on listboxes.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx y\fR
.
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
\fBscan mark\fR command for the widget.
It then adjusts the view by 10 times the
difference in coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the list at high speed through the window.  The return
value is an empty string.
.RE

.TP
\fIpathName \fBsee \fIindex\fR
.
Adjust the view in the listbox so that the element given by \fIindex\fR
is visible.
If the element is already visible then the command has no effect;
if the element is near one edge of the window then the listbox
scrolls to bring the element into view at the edge;  otherwise
the listbox scrolls to center the element.

.TP
\fIpathName \fBselection \fIoption arg\fR
.
This command is used to adjust the selection within a listbox.  It
has several forms, depending on \fIoption\fR:
.RS
.TP







>









>







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
\fBscan mark\fR command for the widget.
It then adjusts the view by 10 times the
difference in coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the list at high speed through the window.  The return
value is an empty string.
.RE
.\" METHOD: see
.TP
\fIpathName \fBsee \fIindex\fR
.
Adjust the view in the listbox so that the element given by \fIindex\fR
is visible.
If the element is already visible then the command has no effect;
if the element is near one edge of the window then the listbox
scrolls to bring the element into view at the edge;  otherwise
the listbox scrolls to center the element.
.\" METHOD: selection
.TP
\fIpathName \fBselection \fIoption arg\fR
.
This command is used to adjust the selection within a listbox.  It
has several forms, depending on \fIoption\fR:
.RS
.TP
339
340
341
342
343
344
345

346
347
348
349
350

351
352
353
354
355
356
357
.TP
\fIpathName \fBselection set \fIfirst \fR?\fIlast\fR?
.
Selects all of the elements in the range between
\fIfirst\fR and \fIlast\fR, inclusive, without affecting
the selection state of elements outside that range.
.RE

.TP
\fIpathName \fBsize\fR
.
Returns a decimal string indicating the total number of elements
in the listbox.

.TP
\fIpathName \fBxview \fR?\fIargs\fR
.
This command is used to query and change the horizontal position of the
information in the widget's window.  It can take any of the following
forms:
.RS







>





>







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
.TP
\fIpathName \fBselection set \fIfirst \fR?\fIlast\fR?
.
Selects all of the elements in the range between
\fIfirst\fR and \fIlast\fR, inclusive, without affecting
the selection state of elements outside that range.
.RE
.\" METHOD: size
.TP
\fIpathName \fBsize\fR
.
Returns a decimal string indicating the total number of elements
in the listbox.
.\" METHOD: xview
.TP
\fIpathName \fBxview \fR?\fIargs\fR
.
This command is used to query and change the horizontal position of the
information in the widget's window.  It can take any of the following
forms:
.RS
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR character units (the width of the \fB0\fR character)
on the display.
.RE

.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR

Returns a list containing two elements, both of which are real fractions
between 0 and 1.
The first element gives the position of the listbox element at the
top of the window, relative to the listbox as a whole (0.5 means
it is halfway through the listbox, for example).
The second element gives the position of the listbox element just after
the last one in the window, relative to the listbox as a whole.







>









>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR character units (the width of the \fB0\fR character)
on the display.
.RE
.\" METHOD: yview
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:
.RS
.TP
\fIpathName \fByview\fR
.
Returns a list containing two elements, both of which are real fractions
between 0 and 1.
The first element gives the position of the listbox element at the
top of the window, relative to the listbox as a whole (0.5 means
it is halfway through the listbox, for example).
The second element gives the position of the listbox element just after
the last one in the window, relative to the listbox as a whole.
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
element in the listbox, 0.33 indicates the element one-third the
way through the listbox, and so on.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
If \fIwhat\fR is \fBpages\fR then
the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then earlier elements
become visible;  if it is positive then later elements
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by







|
>







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
element in the listbox, 0.33 indicates the element one-third the
way through the listbox, and so on.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer 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.
If \fIwhat\fR is \fBpages\fR then
the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then earlier elements
become visible;  if it is positive then later elements
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
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
\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







|







577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
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-/ 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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH "Safe Tk" n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
safe::loadTk \- Load Tk into a safe interpreter.
.SH SYNOPSIS
\fBsafe::loadTk \fIchild\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR?
.BE
.SH DESCRIPTION
.PP
Safe Tk is based on Safe Tcl, which provides a mechanism that allows
restricted and mediated access to auto-loading and packages for safe
interpreters.  Safe Tk adds the ability to configure the interpreter for safe
Tk operations and load Tk into safe interpreters.
.PP
The \fBsafe::loadTk\fR command initializes the required data structures in
the named safe interpreter and then loads Tk into it.  The interpreter must
have been created with \fBsafe::interpCreate\fR or have been initialized
with \fBsafe::interpInit\fR.  The command returns the name of the safe
interpreter.  If \fB\-use\fR is specified, the window identified by the
specified system dependent identifier \fIwindowId\fR is used to contain the
.QW .
window of the safe interpreter; it can be any valid id, eventually referencing
a window belonging to another application. As a convenience, if the window you
plan to use is a Tk Window of the application you can use the window name
(e.g.,
.QW \fB.x.y\fR )
instead of its window Id (e.g., from \fBwinfo id\fR \fB.x.y\fR).
When \fB\-use\fR is not specified, a new toplevel window is created for the
.QW .
window of the safe interpreter. On X11 if you want the embedded window to use
another display than the default one, specify it with \fB\-display\fR.  See
the \fBSECURITY ISSUES\fR section below for implementation details.
.SH "SECURITY ISSUES"
.PP
Please read the \fBsafe\fR manual page for Tcl to learn about the basic
security considerations for Safe Tcl.
.PP
\fBsafe::loadTk\fR adds the value of \fBtk_library\fR taken from the parent
interpreter to the virtual access path of the safe interpreter so that
auto-loading will work in the safe interpreter.
.PP
Tk initialization is now safe with respect to not trusting the child's state
for startup. \fBsafe::loadTk\fR registers the child's name so when the Tk
initialization (\fBTk_SafeInit\fR) is called and in turn calls the parent's
\fBsafe::InitTk\fR it will return the desired \fBargv\fR equivalent
(\fB\-use\fR \fIwindowId\fR, correct \fB\-display\fR, etc.)
.PP
When \fB\-use\fR is not used, the new toplevel created is specially decorated
so the user is always aware that the user interface presented comes from a
potentially unsafe code and can easily delete the corresponding interpreter.
.PP
On X11, conflicting \fB\-use\fR and \fB\-display\fR are likely to generate a
fatal X error.













|




















|


















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH "Safe Tk" n 8.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
safe::loadTk \- Load Tk into a safe interpreter.
.SH SYNOPSIS
\fBsafe::loadTk \fIchild\fR ?\fB\-use\fI windowId\fR? ?\fB\-display\fI displayName\fR?
.BE
.SH DESCRIPTION
.PP
Safe Tk is based on Safe Tcl, which provides a mechanism that allows
restricted and mediated access to auto-loading and packages for safe
interpreters.  Safe Tk adds the ability to configure the interpreter for safe
Tk operations and load Tk into safe interpreters.
.PP
The \fBsafe::loadTk\fR command initializes the required data structures in
the named safe interpreter and then loads Tk into it.  The interpreter must
have been created with \fBsafe::interpCreate\fR or have been initialized
with \fBsafe::interpInit\fR.  The command returns the name of the safe
interpreter.  If \fB\-use\fR is specified, the window identified by the
specified system dependent identifier \fIwindowId\fR is used to contain the
.QW .
window of the safe interpreter; it can be any valid id, eventually referencing
a window belonging to another application. As a convenience, if the window you
plan to use is a Tk Window of the application you can use the window name
(e.g.,
.QW \fB.x.y\fR )
instead of its window Id (e.g., from \fBwinfo id\fB .x.y\fR).
When \fB\-use\fR is not specified, a new toplevel window is created for the
.QW .
window of the safe interpreter. On X11 if you want the embedded window to use
another display than the default one, specify it with \fB\-display\fR.  See
the \fBSECURITY ISSUES\fR section below for implementation details.
.SH "SECURITY ISSUES"
.PP
Please read the \fBsafe\fR manual page for Tcl to learn about the basic
security considerations for Safe Tcl.
.PP
\fBsafe::loadTk\fR adds the value of \fBtk_library\fR taken from the parent
interpreter to the virtual access path of the safe interpreter so that
auto-loading will work in the safe interpreter.
.PP
Tk initialization is now safe with respect to not trusting the child's state
for startup. \fBsafe::loadTk\fR registers the child's name so when the Tk
initialization (\fBTk_SafeInit\fR) is called and in turn calls the parent's
\fBsafe::InitTk\fR it will return the desired \fBargv\fR equivalent
(\fB\-use\fI windowId\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.

Changes to doc/menu.n.

9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menu, tk_menuSetFocus \- Create and manipulate 'menu' widgets and menubars
.SH SYNOPSIS
.nf
\fBmenu\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fR \fIpathName\fR

.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font	\-activerelief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"







|
|
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menu, tk_menuSetFocus \- Create and manipulate 'menu' widgets and menubars
.SH SYNOPSIS
.nf
\fBmenu\fI pathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fI pathName\fR
.fi
.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font	\-activerelief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
36
37
38
39
40
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
be torn off.
.OP \-tearoffcommand tearOffCommand TearOffCommand
If this option has a non-empty value, then it specifies a Tcl command
to invoke whenever the menu is torn off.  The actual command will
consist of the value of this option, followed by a space, followed
by the name of the menu window, followed by a space, followed by
the name of the name of the torn off menu window.  For example, if
the option's value is
.QW "\fBa b\fR"
and menu \fB.x.y\fR is torn off to
create a new menu \fB.x.tearoff1\fR, then the command
.QW "\fBa b .x.y .x.tearoff1\fR"
will be invoked.
This option is ignored under Aqua/Mac OS X, where menus cannot
be torn off.
.OP \-title title Title
The string will be used to title the window created when this menu is
torn off. If the title is NULL, then the window will have the title
of the menubutton or the text of the cascade item from which this menu
was invoked.
.OP \-type type Type







|













|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
.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/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/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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355


356
357
358
359
360
361
362
363
364
365



366
367

368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383



384
385
386

387
388
389
390
391
392
393

394
395
396
397
398
399
400
401
402

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

418
419
420
421
422
423
424
425

426
427
428
429
430
431
432

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










446
447
448
449
450

451
452
453
454
455
456
457
458
459


460
461
462
463
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501

502
503
504
505
506
507
508

509
510
511
512
513

514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531
532

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

550
551
552
553
554

555
556
557

558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577

578
579
580
581
582

583
584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600

601
602
603
604
605

606
607
608

609
610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633

634
635
636
637
638

639
640
641
642
643
644

645
646
647
648
649
650

651
652
653
654
655

656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707

708
709
710
711
712
713
714
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
any of the following forms:
.TP 12
\fBactive\fR
.
Indicates the entry that is currently active.  If no entry is
active then this form is equivalent to \fBnone\fR.  This form may
not be abbreviated.
.TP 12
\fBend\fR
.
Indicates the bottommost entry in the menu.  If there are no
entries in the menu then this form is equivalent to \fBnone\fR.
This form may not be abbreviated.
.TP 12
\fBlast\fR
.
Same as \fBend\fR.
.TP 12
\fBnone\fR
.
Indicates
.QW "no entry at all" ;
this is used most commonly with
the \fBactivate\fR option to deactivate all the entries in the
menu.  In most cases the specification of \fBnone\fR causes
nothing to happen in the widget command.
This form may not be abbreviated.
.TP 12
\fB@\fInumber\fR
.
In this form, \fInumber\fR is treated as a y-coordinate in the
menu's window;  the entry closest to that y-coordinate is used.
For example,
.QW \fB@0\fR
indicates the top-most entry in the window.
.TP 12

\fInumber\fR
.
Specifies the entry numerically, where 0 corresponds
to the top-most entry of the menu, 1 to the entry below it, and
so on.
.TP 12


\fIpattern\fR
.
If the index does not satisfy one of the above forms then this
form is used.  \fIPattern\fR is pattern-matched against the label of
each entry in the menu, in order from the top down, until a
matching entry is found.  The rules of \fBstring match\fR
are used.
.PP
If the index could match more than one of the above forms, then
the form earlier in the above list takes precedence.



.PP
The following widget commands are possible for menu widgets:

.TP
\fIpathName \fBactivate \fIindex\fR
.
Change the state of the entry indicated by \fIindex\fR to \fBactive\fR
and redisplay it using its active colors.
Any previously-active entry is deactivated.  If \fIindex\fR
is specified as \fBnone\fR, or if the specified entry is
disabled, then the menu ends up with no active entry.
Returns an empty string.

.TP
\fIpathName \fBadd \fItype \fR?\fIoption value option value ...\fR?
.
Add a new entry to the bottom of the menu.  The new entry's type
is given by \fItype\fR and must be one of \fBcascade\fR,
\fBcheckbutton\fR, \fBcommand\fR, \fBradiobutton\fR, or \fBseparator\fR,
or a unique abbreviation of one of the above.  If additional arguments



are present, they specify the options listed in the \fBMENU ENTRY OPTIONS\fR
section below.
The \fBadd\fR widget command returns an empty string.

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.

.TP
\fIpathName \fBclone \fInewPathname\fR ?\fIcloneType\fR?
.
Makes a clone of the current menu named \fInewPathName\fR. This clone
is a menu in its own right, but any changes to the clone are
propagated to the original menu and vice versa. \fIcloneType\fR can be
\fBnormal\fR, \fBmenubar\fR, or \fBtearoff\fR. Should not normally be
called outside of the Tk library. See the \fBCLONES\fR section for
more information.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.

.TP
\fIpathName \fBdelete \fIindex1\fR ?\fIindex2\fR?
.
Delete all of the menu entries between \fIindex1\fR and
\fIindex2\fR inclusive.
If \fIindex2\fR is omitted then it defaults to \fIindex1\fR.
Attempts to delete a tear-off menu entry are ignored (instead, you
should change the \fB\-tearoff\fR option to remove the tear-off entry).

.TP
\fIpathName \fBentrycget \fIindex option\fR
.
Returns the current value of a configuration option for
the entry given by \fIindex\fR.
\fIOption\fR may have any of the names described in the
\fBMENU ENTRY OPTIONS\fR section below.

.TP
\fIpathName \fBentryconfigure \fIindex \fR?\fIoptions...\fR?
.
This command is similar to the \fBconfigure\fR command, except that
it applies to the options for an individual entry, whereas \fBconfigure\fR
applies to the options for the menu as a whole.
\fIOptions\fR may have any of the values described in the
\fBMENU ENTRY OPTIONS\fR
section below.  If \fIoptions\fR are specified, options are
modified as indicated in the command and the command returns an empty string.
If no \fIoptions\fR are specified, returns a list describing
the current options for entry \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).










.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the numerical index corresponding to \fIindex\fR, or
\fBnone\fR if \fIindex\fR was specified as \fBnone\fR.

.TP
\fIpathName \fBinsert \fIindex type \fR?\fIoption value option value ...\fR?
.
Same as the \fBadd\fR widget command except that it inserts the new
entry just before the entry given by \fIindex\fR, instead of appending
to the end of the menu.  The \fItype\fR, \fIoption\fR, and \fIvalue\fR
arguments have the same interpretation as for the \fBadd\fR widget
command.  It is not possible to insert new menu entries before the
tear-off entry, if the menu has one.


.TP
\fIpathName \fBinvoke \fIindex\fR
.
Invoke the action of the menu entry.  See the sections on the
individual entries above for details on what happens.  If the
menu entry is disabled then nothing happens.  If the
entry has a command associated with it then the result of that
command is returned as the result of the \fBinvoke\fR widget
command.  Otherwise the result is an empty string.  Note:  invoking
a menu entry does not automatically unpost the menu;  the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.

.TP
\fIpathName \fBpost \fIx y\fR ?\fIindex\fR?
.
Arrange for the menu to be displayed on the screen at the root-window
coordinates given by \fIx\fR and \fIy\fR.  If an index is specified
the menu will be located so that the entry with that index is
displayed at the point.  These coordinates are adjusted if necessary to
guarantee that the entire menu is visible on the screen.  This command
normally returns an empty string.  If the \fB\-postcommand\fR option
has been specified, then its value is executed as a Tcl script before
posting the menu and the result of that script is returned as the
result of the \fBpost\fR widget command.  If an error returns while
executing the command, then the error is returned without posting the
menu.

.TP
\fIpathName \fBpostcascade \fIindex\fR
.
Posts the submenu associated with the cascade entry given by
\fIindex\fR, and unposts any previously posted submenu.
If \fIindex\fR does not correspond to a cascade entry,
or if \fIpathName\fR is not posted,
the command has no effect except to unpost any currently posted
submenu.

.TP
\fIpathName \fBtype \fIindex\fR
.
Returns the type of the menu entry given by \fIindex\fR.
This is the \fItype\fR argument passed to the \fBadd\fR or \fBinsert\fR widget
command when the entry was created, such as \fBcommand\fR
or \fBseparator\fR, or \fBtearoff\fR for a tear-off entry.

.TP
\fIpathName \fBunpost\fR
.
Unmap the window so that it is no longer displayed.  If a
lower-level cascaded menu is posted, unpost that menu.  Returns an
empty string. This subcommand does not work on Windows and the
Macintosh, as those platforms have their own way of unposting menus.

.TP
\fIpathName \fBxposition \fIindex\fR
.
Returns a decimal string giving the x-coordinate within the menu
window of the leftmost pixel in the entry specified by \fIindex\fR.

.TP
\fIpathName \fByposition \fIindex\fR
.
Returns a decimal string giving the y-coordinate within the menu
window of the topmost pixel in the entry specified by \fIindex\fR.
.SH "MENU ENTRY OPTIONS"
The following options are allowed on menu entries. Most options are not
supported by all entry types.

.TP
\fB\-activebackground \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fB\-activebackground\fR option for the overall menu is used.
If the \fBtk_strictMotif\fR variable has been set to request strict
Motif compliance, then this option is ignored and the \fB\-background\fR
option is used in its place.
This option is not available for separator or tear-off entries.

.TP
\fB\-activeforeground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fB\-activeforeground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.TP
\fB\-accelerator \fIvalue\fR
.
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
used to invoke the same function as the menu entry. This is a display
option, it does not actually set the corresponding binding (which can
be achieved using the \fBbind\fR command). This option is not available
for separator or tear-off entries.

.TP
\fB\-background \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).

If this option is specified as an empty string (the default), then the
\fB\-background\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-bitmap \fIvalue\fR
.
Specifies a bitmap to display in the menu instead of a textual
label, in any of the forms accepted by \fBTk_GetBitmap\fR.
This option overrides the \fB\-label\fR option
(as controlled by the \fB\-compound\fR option)
but may be reset
to an empty string to enable a textual label to be displayed.
If a \fB\-image\fR option has been specified, it overrides
\fB\-bitmap\fR.
This option is not available for separator or tear-off entries.

.TP
\fB\-columnbreak \fIvalue\fR
.
When this option is zero, the entry appears below the previous entry. When
this option is one, the entry appears at the top of a new column in the
menu.
This option is ignored on Aqua/Mac OS X, where menus are always a single
column.

.TP
\fB\-command \fIvalue\fR
.
Specifies a Tcl command to execute when the menu entry is invoked.
Not available for separator or tear-off entries.

.TP
\fB\-compound \fIvalue\fR
.
Specifies whether the menu entry should display both an image and text,
and if so, where the image should be placed relative to the text.
Valid values for this option are \fBbottom\fR, \fBcenter\fR,
\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR.  The default value
is \fBnone\fR, meaning that the button will display either an image or
text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR
options.

.TP
\fB\-font \fIvalue\fR
.
Specifies the font to use when drawing the label or accelerator
string in this entry.
If this option is specified as an empty string (the default) then
the \fB\-font\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-foreground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is in the normal state (neither active nor disabled).

If this option is specified as an empty string (the default), then the
\fB\-foreground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-hidemargin \fIvalue\fR
.
Specifies whether the standard margins should be drawn for this menu
entry. This is useful when creating palette with images in them, i.e.,
color palettes, pattern palettes, etc. 1 indicates that the margin for
the entry is hidden; 0 means that the margin is used.

.TP
\fB\-image \fIvalue\fR
.
Specifies an image to display in the menu instead of a text string
or bitmap.
The image must have been created by some previous invocation of
\fBimage create\fR.
This option overrides the \fB\-label\fR and \fB\-bitmap\fR options
(as controlled by the \fB\-compound\fR option)
but may be reset to an empty string to enable a textual or
bitmap label to be displayed.
This option is not available for separator or tear-off entries.

.TP
\fB\-indicatoron \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
\fIValue\fR is a boolean that determines whether or not the
indicator should be displayed.

.TP
\fB\-label \fIvalue\fR
.
Specifies a string to display as an identifying label in the menu
entry.  Not available for separator or tear-off entries.

.TP
\fB\-menu \fIvalue\fR
.
Available only for cascade entries.  Specifies the path name of
the submenu associated with this entry.
The submenu must be a child of the menu.

.TP
\fB\-offvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is
deselected.

.TP
\fB\-onvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.

.TP
\fB\-selectcolor \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies the color to display in the indicator when the entry is
selected.
If the value is an empty string (the default) then the \fB\-selectcolor\fR
option for the menu determines the indicator color.

.TP
\fB\-selectimage \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies an image to display in the entry (in place of
the \fB\-image\fR option) when it is selected.
\fIValue\fR is the name of an image, which must have been created
by some previous invocation of \fBimage create\fR.
This option is ignored unless the \fB\-image\fR option has
been specified.

.TP
\fB\-state \fIvalue\fR
.
Specifies one of three states for the entry:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the entry is displayed using the
\fB\-foreground\fR option for the menu and the \fB\-background\fR
option from the entry or the menu.
The active state is typically used when the pointer is over the entry.
In active state the entry is displayed using the \fB\-activeforeground\fR
option for the menu along with the \fB\-activebackground\fR option from
the entry.  Disabled state means that the entry
should be insensitive:  the default bindings will refuse to activate
or invoke the entry.
In this state the entry is displayed according to the
\fB\-disabledforeground\fR option for the menu and the
\fB\-background\fR option from the entry.
This option is not available for separator entries.

.TP
\fB\-underline \fIvalue\fR
.
Specifies the integer index of a character to underline in the entry.
This option is also queried by the default bindings and used to
implement keyboard traversal.
0 corresponds to the first character of the text displayed in the entry,
1 to the next character, and so on.
If a bitmap or image is displayed in the entry then this option is ignored.
This option is not available for separator or tear-off entries.

.TP
\fB\-value \fIvalue\fR
.
Available only for radiobutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
If an empty string is specified, then the \fB\-label\fR option
for the entry as the value to store in the variable.

.TP
\fB\-variable \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.  Specifies
the name of a global variable to set when the entry is selected.
For checkbutton entries the variable is also set when the entry
is deselected.  For radiobutton entries, changing the variable







<
|
<

|

<
|
<

|

<
|
<

<
|
<




|

<
<
|
<
<
|
<
|
|
<
>
|
<



|
>
>
|
<
|







>
>
>


>






|


>

|




|
>
>
>
|
|
|
>







>









>















>








>







>













>
>
>
>
>
>
>
>
>
>




|
>

|



|
|
|

>
>












>














>









>







>







>





>








>




|
|





>




|


|









>





>
|


>












>






|

>





>










>








>





>
|


>







>












>






>





>






>






>





>








>










>

















>










>







>







309
310
311
312
313
314
315

316

317
318
319

320

321
322
323

324

325

326

327
328
329
330
331
332


333


334

335
336

337
338

339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
any of the following forms:

.IP \fBactive\fR 12

Indicates the entry that is currently active.  If no entry is
active then this form is equivalent to \fB{}\fR.  This form may
not be abbreviated.

.IP \fBend\fR 12

Indicates the bottommost entry in the menu.  If there are no
entries in the menu then this form is equivalent to \fB{}\fR.
This form may not be abbreviated.

.IP \fBlast\fR 12

Same as \fBend\fR.

.IP \fB{}\fR 12

Indicates
.QW "no entry at all" ;
this is used most commonly with
the \fBactivate\fR option to deactivate all the entries in the
menu.  In most cases the specification of \fB{}\fR causes
nothing to happen in the widget command.


.IP \fB@\fIx\fB,\fIy\fR 12


Indicates the entry that covers the point in the menu's window specified

by \fIx\fR and \fIy\fR (in pixel coordinates).
If no entry covers that point, then this form is equivalent to \fB{}\fR.

If only a single number is specified, it is treated as the y-coordinate.
.IP \fInumber\fR 12

Specifies the entry numerically, where 0 corresponds
to the top-most entry of the menu, 1 to the entry below it, and
so on.
.IP \fIid\fR 12
If the index does not satisfy one of the above forms then the menu is
searched for an entry with the specified id.
.IP \fIpattern\fR 12

If all of the above methods for finding an entry fail, this
form is used.  \fIPattern\fR is pattern-matched against the label of
each entry in the menu, in order from the top down, until a
matching entry is found.  The rules of \fBstring match\fR
are used.
.PP
If the index could match more than one of the above forms, then
the form earlier in the above list takes precedence.
Indexes support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\fR.
.PP
The following widget commands are possible for menu widgets:
.\" METHOD: activate
.TP
\fIpathName \fBactivate \fIindex\fR
.
Change the state of the entry indicated by \fIindex\fR to \fBactive\fR
and redisplay it using its active colors.
Any previously-active entry is deactivated.  If \fIindex\fR
is specified as \fB{}\fR, or if the specified entry is
disabled, then the menu ends up with no active entry.
Returns an empty string.
.\" METHOD: add
.TP
\fIpathName \fBadd \fItype \fR?\fIid\fR? ?\fIoption value option value ...\fR?
.
Add a new entry to the bottom of the menu.  The new entry's type
is given by \fItype\fR and must be one of \fBcascade\fR,
\fBcheckbutton\fR, \fBcommand\fR, \fBradiobutton\fR, or \fBseparator\fR,
or a unique abbreviation of one of the above.
If the \fIid\fR argument is specified, it is used as the entry identifier;
\fIid\fR must not already exist in the menu. Otherwise, a new unique
identifier is generated.
If additional arguments are present, they specify the options listed in the
\fBMENU ENTRY OPTIONS\fR section below.
The \fBadd\fR widget command returns the id of the new entry.
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.\" METHOD: clone
.TP
\fIpathName \fBclone \fInewPathname\fR ?\fIcloneType\fR?
.
Makes a clone of the current menu named \fInewPathName\fR. This clone
is a menu in its own right, but any changes to the clone are
propagated to the original menu and vice versa. \fIcloneType\fR can be
\fBnormal\fR, \fBmenubar\fR, or \fBtearoff\fR. Should not normally be
called outside of the Tk library. See the \fBCLONES\fR section for
more information.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.\" METHOD: delete
.TP
\fIpathName \fBdelete \fIindex1\fR ?\fIindex2\fR?
.
Delete all of the menu entries between \fIindex1\fR and
\fIindex2\fR inclusive.
If \fIindex2\fR is omitted then it defaults to \fIindex1\fR.
Attempts to delete a tear-off menu entry are ignored (instead, you
should change the \fB\-tearoff\fR option to remove the tear-off entry).
.\" METHOD: entrycget
.TP
\fIpathName \fBentrycget \fIindex option\fR
.
Returns the current value of a configuration option for
the entry given by \fIindex\fR.
\fIOption\fR may have any of the names described in the
\fBMENU ENTRY OPTIONS\fR section below.
.\" METHOD: entryconfigure
.TP
\fIpathName \fBentryconfigure \fIindex \fR?\fIoptions...\fR?
.
This command is similar to the \fBconfigure\fR command, except that
it applies to the options for an individual entry, whereas \fBconfigure\fR
applies to the options for the menu as a whole.
\fIOptions\fR may have any of the values described in the
\fBMENU ENTRY OPTIONS\fR
section below.  If \fIoptions\fR are specified, options are
modified as indicated in the command and the command returns an empty string.
If no \fIoptions\fR are specified, returns a list describing
the current options for entry \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).
.\" METHOD: id
.TP
\fIpathName \fBid \fIindex\fR
.
Returns the id of the menu entry given by \fIindex\fR.
This is the identifier that was assigned to the entry when it was created
using the \fBadd\fR or \fBinsert\fR widget command.
Returns an empty string for the tear-off entry, or if \fIindex\fR is
equivalent to \fB{}\fR.
.\" METHOD: index
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the numerical index corresponding to \fIindex\fR, or
\fB{}\fR if \fIindex\fR was specified as \fB{}\fR.
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fIindex type \fR?\fIid\fR? ?\fIoption value option value ...\fR?
.
Same as the \fBadd\fR widget command except that it inserts the new
entry just before the entry given by \fIindex\fR, instead of appending
to the end of the menu.  The \fItype\fR, \fIid\fR, \fIoption\fR, and
\fIvalue\fR arguments have the same interpretation as for the \fBadd\fR
widget command.  It is not possible to insert new menu entries before the
tear-off entry, if the menu has one.
The \fBinsert\fR widget command returns the id of the new entry.
.\" METHOD: invoke
.TP
\fIpathName \fBinvoke \fIindex\fR
.
Invoke the action of the menu entry.  See the sections on the
individual entries above for details on what happens.  If the
menu entry is disabled then nothing happens.  If the
entry has a command associated with it then the result of that
command is returned as the result of the \fBinvoke\fR widget
command.  Otherwise the result is an empty string.  Note:  invoking
a menu entry does not automatically unpost the menu;  the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.
.\" METHOD: post
.TP
\fIpathName \fBpost \fIx y\fR ?\fIindex\fR?
.
Arrange for the menu to be displayed on the screen at the root-window
coordinates given by \fIx\fR and \fIy\fR.  If an index is specified
the menu will be located so that the entry with that index is
displayed at the point.  These coordinates are adjusted if necessary to
guarantee that the entire menu is visible on the screen.  This command
normally returns an empty string.  If the \fB\-postcommand\fR option
has been specified, then its value is executed as a Tcl script before
posting the menu and the result of that script is returned as the
result of the \fBpost\fR widget command.  If an error returns while
executing the command, then the error is returned without posting the
menu.
.\" METHOD: postcascade
.TP
\fIpathName \fBpostcascade \fIindex\fR
.
Posts the submenu associated with the cascade entry given by
\fIindex\fR, and unposts any previously posted submenu.
If \fIindex\fR does not correspond to a cascade entry,
or if \fIpathName\fR is not posted,
the command has no effect except to unpost any currently posted
submenu.
.\" METHOD: type
.TP
\fIpathName \fBtype \fIindex\fR
.
Returns the type of the menu entry given by \fIindex\fR.
This is the \fItype\fR argument passed to the \fBadd\fR or \fBinsert\fR widget
command when the entry was created, such as \fBcommand\fR
or \fBseparator\fR, or \fBtearoff\fR for a tear-off entry.
.\" METHOD: unpost
.TP
\fIpathName \fBunpost\fR
.
Unmap the window so that it is no longer displayed.  If a
lower-level cascaded menu is posted, unpost that menu.  Returns an
empty string. This subcommand does not work on Windows and the
Macintosh, as those platforms have their own way of unposting menus.
.\" METHOD: xposition
.TP
\fIpathName \fBxposition \fIindex\fR
.
Returns a decimal string giving the x-coordinate within the menu
window of the leftmost pixel in the entry specified by \fIindex\fR.
.\" METHOD: yposition
.TP
\fIpathName \fByposition \fIindex\fR
.
Returns a decimal string giving the y-coordinate within the menu
window of the topmost pixel in the entry specified by \fIindex\fR.
.SH "MENU ENTRY OPTIONS"
The following options are allowed on menu entries. Most options are not
supported by all entry types.
.\" OPTION: -activebackground
.TP
\fB\-activebackground \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is active. This option is ignored on Aqua/MacOS.
If it is specified as an empty string (the default), then the
\fB\-activebackground\fR option for the overall menu is used.
If the \fBtk_strictMotif\fR variable has been set to request strict
Motif compliance, then this option is ignored and the \fB\-background\fR
option is used in its place.
This option is not available for separator or tear-off entries.
.\" OPTION: -activeforeground
.TP
\fB\-activeforeground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is active.   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.
.\" OPTION: -accelerator
.TP
\fB\-accelerator \fIvalue\fR
.
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
used to invoke the same function as the menu entry. This is a display
option, it does not actually set the corresponding binding (which can
be achieved using the \fBbind\fR command). This option is not available
for separator or tear-off entries.
.\" OPTION: -background
.TP
\fB\-background \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
This option is ignored on Aqua/macOS.
If it is specified as an empty string (the default), then the
\fB\-background\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.\" OPTION: -bitmap
.TP
\fB\-bitmap \fIvalue\fR
.
Specifies a bitmap to display in the menu instead of a textual
label, in any of the forms accepted by \fBTk_GetBitmap\fR.
This option overrides the \fB\-label\fR option
(as controlled by the \fB\-compound\fR option)
but may be reset
to an empty string to enable a textual label to be displayed.
If a \fB\-image\fR option has been specified, it overrides
\fB\-bitmap\fR.
This option is not available for separator or tear-off entries.
.\" OPTION: -columnbreak
.TP
\fB\-columnbreak \fIvalue\fR
.
When this option is zero, the entry appears below the previous entry. When
this option is one, the entry appears at the top of a new column in the
menu.
This option is ignored on Aqua/macOS, where menus are always a single
column.
.\" OPTION: -command
.TP
\fB\-command \fIvalue\fR
.
Specifies a Tcl command to execute when the menu entry is invoked.
Not available for separator or tear-off entries.
.\" OPTION: -compound
.TP
\fB\-compound \fIvalue\fR
.
Specifies whether the menu entry should display both an image and text,
and if so, where the image should be placed relative to the text.
Valid values for this option are \fBbottom\fR, \fBcenter\fR,
\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR.  The default value
is \fBnone\fR, meaning that the button will display either an image or
text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR
options.
.\" OPTION: -font
.TP
\fB\-font \fIvalue\fR
.
Specifies the font to use when drawing the label or accelerator
string in this entry.
If this option is specified as an empty string (the default) then
the \fB\-font\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.\" OPTION: -foreground
.TP
\fB\-foreground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
This option is ignored on Aqua/macOS.
If it is specified as an empty string (the default), then the
\fB\-foreground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.
.\" OPTION: -hidemargin
.TP
\fB\-hidemargin \fIvalue\fR
.
Specifies whether the standard margins should be drawn for this menu
entry. This is useful when creating palette with images in them, i.e.,
color palettes, pattern palettes, etc. 1 indicates that the margin for
the entry is hidden; 0 means that the margin is used.
.\" OPTION: -image
.TP
\fB\-image \fIvalue\fR
.
Specifies an image to display in the menu instead of a text string
or bitmap.
The image must have been created by some previous invocation of
\fBimage create\fR.
This option overrides the \fB\-label\fR and \fB\-bitmap\fR options
(as controlled by the \fB\-compound\fR option)
but may be reset to an empty string to enable a textual or
bitmap label to be displayed.
This option is not available for separator or tear-off entries.
.\" OPTION: -indicatoron
.TP
\fB\-indicatoron \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
\fIValue\fR is a boolean that determines whether or not the
indicator should be displayed.
.\" OPTION: -label
.TP
\fB\-label \fIvalue\fR
.
Specifies a string to display as an identifying label in the menu
entry.  Not available for separator or tear-off entries.
.\" OPTION: -menu
.TP
\fB\-menu \fIvalue\fR
.
Available only for cascade entries.  Specifies the path name of
the submenu associated with this entry.
The submenu must be a child of the menu.
.\" OPTION: -offvalue
.TP
\fB\-offvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is
deselected.
.\" OPTION: -onvalue
.TP
\fB\-onvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
.\" OPTION: -selectcolor
.TP
\fB\-selectcolor \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies the color to display in the indicator when the entry is
selected.
If the value is an empty string (the default) then the \fB\-selectcolor\fR
option for the menu determines the indicator color.
.\" OPTION: -selectimage
.TP
\fB\-selectimage \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies an image to display in the entry (in place of
the \fB\-image\fR option) when it is selected.
\fIValue\fR is the name of an image, which must have been created
by some previous invocation of \fBimage create\fR.
This option is ignored unless the \fB\-image\fR option has
been specified.
.\" OPTION: -state
.TP
\fB\-state \fIvalue\fR
.
Specifies one of three states for the entry:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the entry is displayed using the
\fB\-foreground\fR option for the menu and the \fB\-background\fR
option from the entry or the menu.
The active state is typically used when the pointer is over the entry.
In active state the entry is displayed using the \fB\-activeforeground\fR
option for the menu along with the \fB\-activebackground\fR option from
the entry.  Disabled state means that the entry
should be insensitive:  the default bindings will refuse to activate
or invoke the entry.
In this state the entry is displayed according to the
\fB\-disabledforeground\fR option for the menu and the
\fB\-background\fR option from the entry.
This option is not available for separator entries.
.\" OPTION: -underline
.TP
\fB\-underline \fIvalue\fR
.
Specifies the integer index of a character to underline in the entry.
This option is also queried by the default bindings and used to
implement keyboard traversal.
0 corresponds to the first character of the text displayed in the entry,
1 to the next character, and so on.
If a bitmap or image is displayed in the entry then this option is ignored.
This option is not available for separator or tear-off entries.
.\" OPTION: -value
.TP
\fB\-value \fIvalue\fR
.
Available only for radiobutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
If an empty string is specified, then the \fB\-label\fR option
for the entry as the value to store in the variable.
.\" OPTION: -variable
.TP
\fB\-variable \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.  Specifies
the name of a global variable to set when the entry is selected.
For checkbutton entries the variable is also set when the entry
is deselected.  For radiobutton entries, changing the variable

Deleted doc/menubar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tk_menuBar n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_menuBar, tk_bindForTraversal \- Obsolete support for menu bars
.SH SYNOPSIS
\fBtk_menuBar \fIframe \fR?\fImenu menu ...\fR?
.sp
\fBtk_bindForTraversal \fIarg ... \fR
.BE
.SH DESCRIPTION
.PP
These procedures were used in Tk 3.6 and earlier releases to help
manage pulldown menus and to implement keyboard traversal of menus.
In Tk 4.0 and later releases they are no
longer needed.  Stubs for these procedures have been retained for
backward compatibility, but they have no effect.  You should remove
calls to these procedures from your code, since eventually the
procedures will go away.
.PP
From Tk 8.0 onwards, you should instead construct your menubar as a
normal \fBmenu\fR and then attach it to the \fBtoplevel\fR of your
choice using the \fB\-menu\fR option of that widget.
.SH "SEE ALSO"
menu(n), toplevel(n)
.SH KEYWORDS
keyboard traversal, menu, menu bar, post
'\" Local Variables:
'\" mode: nroff
'\" End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































Changes to doc/menubutton.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.TH menubutton n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menubutton \- Create and manipulate 'menubutton' pop-up menu indicator widgets
.SH SYNOPSIS
\fBmenubutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable
\-cursor	\-image	\-underline
\-compound	\-justify	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-direction direction Height
Specifies where the menu is going to be popup up. \fBabove\fR tries to
pop the menu above the menubutton. \fBbelow\fR tries to pop the menu
below the menubutton. \fBleft\fR tries to pop the menu to the left of
the menubutton. \fBright\fR tries to pop the menu to the right of the
menu button. \fBflush\fR pops the menu directly over the menubutton.
In the case of \fBabove\fR or \fBbelow\fR, the direction will be
reversed if the menu would show offscreen.







|











|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.TH menubutton n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menubutton \- Create and manipulate 'menubutton' pop-up menu indicator widgets
.SH SYNOPSIS
\fBmenubutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable
\-cursor	\-image	\-underline
\-compound	\-justify	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-direction direction Direction
Specifies where the menu is going to be popup up. \fBabove\fR tries to
pop the menu above the menubutton. \fBbelow\fR tries to pop the menu
below the menubutton. \fBleft\fR tries to pop the menu to the left of
the menubutton. \fBright\fR tries to pop the menu to the right of the
menu button. \fBflush\fR pops the menu directly over the menubutton.
In the case of \fBabove\fR or \fBbelow\fR, the direction will be
reversed if the menu would show offscreen.
118
119
120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135
136
137
138
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for menubutton widgets:

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenubutton\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified







>







>







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for menubutton widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenubutton\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified

Changes to doc/message.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH message n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
message \- Create and manipulate 'message' non-interactive text widgets
.SH SYNOPSIS
\fBmessage\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-anchor	\-background	\-borderwidth
\-cursor	\-font	\-foreground
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-padx	\-pady	\-relief
\-takefocus	\-text	\-textvariable
.SE







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH message n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
message \- Create and manipulate 'message' non-interactive text widgets
.SH SYNOPSIS
\fBmessage\fI pathName \fR?\fIoptions\fR?
.SO
\-anchor	\-background	\-borderwidth
\-cursor	\-font	\-foreground
\-highlightbackground	\-highlightcolor	\-highlightthickness
\-padx	\-pady	\-relief
\-takefocus	\-text	\-textvariable
.SE
107
108
109
110
111
112
113

114
115
116
117
118
119
120

121
122
123
124
125
126
127
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for message widgets:

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmessage\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified







>







>







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for message widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmessage\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified

Changes to doc/messageBox.n.

19
20
21
22
23
24
25

26
27

28
29
30
31

32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48

49
50
51
52
53
54
55

56
57
58
59
60

61
62
63
64
65

66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
application-specified message, an icon and a set of buttons.  Each of
the buttons in the message window is identified by a unique symbolic
name (see the \fB\-type\fR options).  After the message window is
popped up, \fBtk_messageBox\fR waits for the user to select one of the
buttons. Then it returns the symbolic name of the selected button.
.PP
The following option-value pairs are supported:

.TP
\fB\-command\fR \fIstring\fR

Specifies the prefix of a Tcl command to invoke when the user closes the
dialog. The actual command consists of \fIstring\fR followed by a space
and the name of the button clicked by the user to close the dialog. This
is only available on Mac OS X.

.TP
\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
and so on). See \fB\-type\fR
for a list of the symbolic names.  If this option is not specified,
the first button in the dialog will be made the default.

.TP
\fB\-detail\fR \fIstring\fR
.
Specifies an auxiliary message to the main message given by the
\fB\-message\fR option. The message detail will be presented beneath the main
message and, where supported by the OS, in a less emphasized font than the
main message.

.TP
\fB\-icon\fR \fIiconImage\fR
.
Specifies an icon to display. \fIIconImage\fR must be one of the
following: \fBerror\fR, \fBinfo\fR, \fBquestion\fR or
\fBwarning\fR. If this option is not specified, then the info icon will be
displayed.

.TP
\fB\-message\fR \fIstring\fR
.
Specifies the message to display in this message box. The
default value is an empty string.

.TP
\fB\-parent\fR \fIwindow\fR
.
Makes \fIwindow\fR the logical parent of the message box. The message
box is displayed on top of its parent window.

.TP
\fB\-title\fR \fItitleString\fR
.
Specifies a string to display as the title of the message box. This option
is ignored on Mac OS X, where platform guidelines forbid the use of a title
on this kind of dialog.

.TP
\fB\-type\fR \fIpredefinedType\fR
.
Arranges for a predefined set of buttons to be displayed. The
following values are possible for \fIpredefinedType\fR:
.RS
.TP 18
\fBabortretryignore\fR
.
Displays three buttons whose symbolic names are \fBabort\fR,
\fBretry\fR and \fBignore\fR.
.TP 18
\fBok\fR
.
Displays one button whose symbolic name is \fBok\fR.
.TP 18
\fBokcancel\fR
.
Displays two buttons whose symbolic names are \fBok\fR and \fBcancel\fR.
.TP 18
\fBretrycancel\fR
.
Displays two buttons whose symbolic names are \fBretry\fR and \fBcancel\fR.
.TP 18
\fByesno\fR
.
Displays two buttons whose symbolic names are \fByes\fR and \fBno\fR.
.TP 18
\fByesnocancel\fR
.
Displays three buttons whose symbolic names are \fByes\fR, \fBno\fR
and \fBcancel\fR.
.RE
.PP
.SH EXAMPLE
.PP
.CS
set answer [\fBtk_messageBox\fR \-message "Really quit?" \e
        \-icon question \-type yesno \e
        \-detail "Select \e"Yes\e" to make the application exit"]
switch \-\- $answer {
    yes exit
    no {\fBtk_messageBox\fR \-message "I know you like this application!" \e
            \-type ok}
}
.CE
.SH KEYWORDS
message box
'\" Local Variables:
'\" mode: nroff
'\" End:







>

|
>




>

|








>

|





>

|





>

|



>

|



>

|

|
<
|
>

|




<
|
<


<
|
<

<
|
<

<
|
<

<
|
<

<
|
<







|
|
|
|

|
|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85

86

87
88

89

90

91

92

93

94

95

96

97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
application-specified message, an icon and a set of buttons.  Each of
the buttons in the message window is identified by a unique symbolic
name (see the \fB\-type\fR options).  After the message window is
popped up, \fBtk_messageBox\fR waits for the user to select one of the
buttons. Then it returns the symbolic name of the selected button.
.PP
The following option-value pairs are supported:
.\" OPTION: -command
.TP
\fB\-command\fI string\fR
.
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog. The actual command consists of \fIstring\fR followed by a space
and the name of the button clicked by the user to close the dialog. This
is only available on Mac OS X.
.\" OPTION: -default
.TP
\fB\-default\fI name\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
and so on). See \fB\-type\fR
for a list of the symbolic names.  If this option is not specified,
the first button in the dialog will be made the default.
.\" OPTION: -detail
.TP
\fB\-detail\fI string\fR
.
Specifies an auxiliary message to the main message given by the
\fB\-message\fR option. The message detail will be presented beneath the main
message and, where supported by the OS, in a less emphasized font than the
main message.
.\" OPTION: -icon
.TP
\fB\-icon\fI iconImage\fR
.
Specifies an icon to display. \fIIconImage\fR must be one of the
following: \fBerror\fR, \fBinfo\fR, \fBquestion\fR or
\fBwarning\fR. If this option is not specified, then the info icon will be
displayed.
.\" OPTION: -message
.TP
\fB\-message\fI string\fR
.
Specifies the message to display in this message box. The
default value is an empty string.
.\" OPTION: -parent
.TP
\fB\-parent\fI window\fR
.
Makes \fIwindow\fR the logical parent of the message box. The message
box is displayed on top of its parent window.
.\" OPTION: -title
.TP
\fB\-title\fI titleString\fR
.
Specifies a string to display as the title of the message box. The

default value is an empty string.
.\" OPTION: -type
.TP
\fB\-type\fI predefinedType\fR
.
Arranges for a predefined set of buttons to be displayed. The
following values are possible for \fIpredefinedType\fR:
.RS

.IP \fBabortretryignore\fR 18

Displays three buttons whose symbolic names are \fBabort\fR,
\fBretry\fR and \fBignore\fR.

.IP \fBok\fR 18

Displays one button whose symbolic name is \fBok\fR.

.IP \fBokcancel\fR 18

Displays two buttons whose symbolic names are \fBok\fR and \fBcancel\fR.

.IP \fBretrycancel\fR 18

Displays two buttons whose symbolic names are \fBretry\fR and \fBcancel\fR.

.IP \fByesno\fR 18

Displays two buttons whose symbolic names are \fByes\fR and \fBno\fR.

.IP \fByesnocancel\fR 18

Displays three buttons whose symbolic names are \fByes\fR, \fBno\fR
and \fBcancel\fR.
.RE
.PP
.SH EXAMPLE
.PP
.CS
set answer [\fBtk_messageBox\fR -message "Really quit?" \e
        -icon question -type yesno \e
        -detail "Select \e"Yes\e" to make the application exit"]
switch -- $answer {
    yes exit
    no {\fBtk_messageBox\fR -message "I know you like this application!" \e
            -type ok}
}
.CE
.SH KEYWORDS
message box
'\" Local Variables:
'\" mode: nroff
'\" End:

Added doc/nsimage.n.











































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'\"
'\" Copyright (c) 2022 Marc Culler
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH nsimage n 8.7 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
nsimage \- A Tk image type for macOS based on the NSImage class.
.BE
.SH DESCRIPTION
The nsimage is implemented as a Tk image type.  The \fBimage\fR
command is used to create, delete, and query all images, including
images of type \fBnsimage\fR.  The options that are available are
specific to the nsimage type and are described below.
.PP
The command to create an \fBnsimage\fR:
.TP
\fBimage create nsimage \fR?\fIname\fR? ?\fIoption value ...\fR?
.PP
creates a new nsimage and a command with the same name and returns its
name.
.SH OPTIONS
.PP
Valid \fIoptions\fR are:
.\" OPTION: -source
.TP
\fB\-source\fI string\fR
.PP
The value of the \fB\-source\fR option is a string describing an
NSimage.  There are several ways to interpret this string, and the
interpretation is determined by the value of the \fB\-as\fR option.
This option is required.
.PP
.\" OPTION: -as
.TP
\fB\-as\fI type\fR
.PP
There are four possible values for the \fB\-as\fR option which specify
how the source string should be interpreted.  The allowed values and
their meanings are:
.RS
.IP \fBname\fR
The source should be interpreted as the name of a named NSImage
provided by the system.
This is the default if the \fB\-as\fR option is not specified.
.IP \fBfile\fR
The source should be interpreted as a path to an image
file in one of the formats understood by the NSImage class.
.IP \fBpath\fR
The source should be interpreted as a path to an arbitrary
file. The type of the file will be examined and the resulting image
will be the system icon for files of that type.
.IP \fBfiletype\fR
The source is interpreted as a string identifying a
particular file type.  It may be a filename extension, an Apple Uniform Type
Identifier or a 4-character OSType value as used in the HFS filesystem.
.RE
.\" OPTION: -width
.TP
\fB\-width\fI pixels\fR
.PP
The value of the \fIwidth\fR option is an integer specifying the width
in pixels of the nsimage.  If the width is not specified it will be
computed from the height so as to preserve the aspect ration.  If
neither width nor height are specified then the width and height of
the underlying NSImage will be used.
.\" OPTION: -height
.TP
\fB\-height\fI pixels\fR
.PP
The value of the \fIheight\fR option is an integer specifying the
height in pixels of the nsimage. If the height is not specified it
will be computed from the height so as to preserve the aspect ration.
If neither width nor height are specified then the width and height of
the underlying NSImage will be used.
.\" OPTION: -radius
.TP
\fB\-radius\fI pixels\fR
.PP
The value of the \fIradius\fR option is an integer.  If non-zero the
image will be clipped to a rounded rectangle with the same width and
height as the image, but with circular arcs of the specified radius
cutting off the corners of the rectangle.
.\" OPTION: -ring
.TP
\fB\-ring\fI pixels\fR
.PP
The value of the \fIring\fR option is an integer.  If non-zero then it
specifies the thickness of a focus ring which will be drawn around the
image using the control accent color specified in the System
Preferences.  The image is resized to reduce its width and height by
twice the thickness of the ring.  Note that this may create a small
amount of distortion.  The aspect ration of a non-square image will
change slightly.
.\" OPTION: -alpha
.TP
\fB\-alpha\fI float\fR
.PP
The value of the \fIalpha\fR option should be a floating point number
between 0.0 and 1.0.  This alpha value will be applied to each pixel
of the nsimage, producing a partially transparent image.  The default value
is 1.0, which makes the image opaque.
.\" OPTION: -pressed
.TP
\fB\-pressed\fI boolean\fR
.PP
The \fIpressed\fR option takes a boolean value.  If the value is true
or 1 then the image will be algorithmically modified to become darker
in light mode or lighter in dark mode.  The default is false.  For an
image button, the primary image should use the value false while the
pressed image should be the same image but with the \fIpressed\fR
option set to true.
.\" OPTION: -template
.TP
\fB\-template\fI boolean\fR
.PP
The \fItemplate\fR option takes a boolean value.  If the value is true
or 1 then the image will be marked as being a template image.  This
means that the system will algorithmically convert the image to a
light colored image when in dark mode.  For the algorithm to work
correctly the image must consist only of black pixels with alpha
values.
.SH "SEE ALSO"
image(n), options(n), photo(n)
.SH KEYWORDS
height, image, types of images, width
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/option.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
\fBoption get \fIwindow name class\fR
\fBoption readfile \fIfileName \fR?\fIpriority\fR?
.fi
.BE
.SH DESCRIPTION
.PP
The \fBoption\fR command allows you to add entries to the Tk option
database or to retrieve options from the database.  The \fBadd\fR

form of the command adds a new option to the database.
\fIPattern\fR contains
the option being specified, and consists of names and/or classes
separated by asterisks or dots, in the usual X format (see
\fBPATTERN FORMAT\fR).  \fIValue\fR
contains a text string to associate with \fIpattern\fR;  this is the
value that will be returned in calls to \fBTk_GetOption\fR or by
invocations of the \fBoption get\fR command.  If \fIpriority\fR
is specified, it indicates the priority level for this option (see
below for legal values);  it defaults to \fBinteractive\fR.
This command always returns an empty string.
.PP

The \fBoption clear\fR command clears the option database.  Default
options (from the
\fBRESOURCE_MANAGER\fR property or the \fB.Xdefaults\fR
file) will be reloaded automatically the next time an
option is added to the database or removed from it.  This command
always returns an empty string.
.PP

The \fBoption get\fR command returns the value of the option
specified for \fIwindow\fR
under \fIname\fR and \fIclass\fR.  If several entries in the option
database match \fIwindow\fR, \fIname\fR, and \fIclass\fR, then
the command returns whichever was created with highest
\fIpriority\fR level.  If there are several matching
entries at the same priority level, then it returns whichever entry
was most recently entered into the option database.  If there are
no matching entries, then the empty string is returned.
.PP

The \fBreadfile\fR form of the command reads \fIfileName\fR,
which should have the standard format for an
X resource database such as \fB.Xdefaults\fR, and adds all the
options specified in that file to the option database.  If \fIpriority\fR
is specified, it indicates the priority level at which to enter the
options;  \fIpriority\fR defaults to \fBinteractive\fR.
.PP
The file is read through a channel which is in "utf-8" encoding,
invalid byte sequences are automatically converted to valid ones.
This means that encodings like ISO 8859-1 or cp1252 with high
probability will work as well, but this cannot be guaranteed.
This cannot be changed, setting the [encoding system] has no effect.
.PP
The \fIpriority\fR arguments to the \fBoption\fR command are
normally specified symbolically using one of the following values:
.TP
\fBwidgetDefault\fR
Level 20.  Used for default values hard-coded into widgets.
.TP
\fBstartupFile\fR
Level 40.  Used for options specified in application-specific
startup files.
.TP
\fBuserDefault\fR
Level 60.  Used for options specified in user-specific defaults
files, such as \fB.Xdefaults\fR, resource databases loaded into
the X server, or user-specific startup files.
.TP
\fBinteractive\fR
Level 80.  Used for options specified interactively after the application
starts running.  If \fIpriority\fR is not specified, it defaults to
this level.
.PP
Any of the above keywords may be abbreviated.  In addition, priorities
may be specified numerically using integers between 0 and 100,
inclusive.  The numeric form is probably a bad idea except for new priority







|
>
|











>







>










>















<
|

<
|


<
|



<
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75

76
77
78

79
80
81
82

83
84
85
86
87
88
89
90
\fBoption get \fIwindow name class\fR
\fBoption readfile \fIfileName \fR?\fIpriority\fR?
.fi
.BE
.SH DESCRIPTION
.PP
The \fBoption\fR command allows you to add entries to the Tk option
database or to retrieve options from the database.
.\" METHOD: add
The \fBadd\fR form of the command adds a new option to the database.
\fIPattern\fR contains
the option being specified, and consists of names and/or classes
separated by asterisks or dots, in the usual X format (see
\fBPATTERN FORMAT\fR).  \fIValue\fR
contains a text string to associate with \fIpattern\fR;  this is the
value that will be returned in calls to \fBTk_GetOption\fR or by
invocations of the \fBoption get\fR command.  If \fIpriority\fR
is specified, it indicates the priority level for this option (see
below for legal values);  it defaults to \fBinteractive\fR.
This command always returns an empty string.
.PP
.\" METHOD: clear
The \fBoption clear\fR command clears the option database.  Default
options (from the
\fBRESOURCE_MANAGER\fR property or the \fB.Xdefaults\fR
file) will be reloaded automatically the next time an
option is added to the database or removed from it.  This command
always returns an empty string.
.PP
.\" METHOD: get
The \fBoption get\fR command returns the value of the option
specified for \fIwindow\fR
under \fIname\fR and \fIclass\fR.  If several entries in the option
database match \fIwindow\fR, \fIname\fR, and \fIclass\fR, then
the command returns whichever was created with highest
\fIpriority\fR level.  If there are several matching
entries at the same priority level, then it returns whichever entry
was most recently entered into the option database.  If there are
no matching entries, then the empty string is returned.
.PP
.\" METHOD: readfile
The \fBreadfile\fR form of the command reads \fIfileName\fR,
which should have the standard format for an
X resource database such as \fB.Xdefaults\fR, and adds all the
options specified in that file to the option database.  If \fIpriority\fR
is specified, it indicates the priority level at which to enter the
options;  \fIpriority\fR defaults to \fBinteractive\fR.
.PP
The file is read through a channel which is in "utf-8" encoding,
invalid byte sequences are automatically converted to valid ones.
This means that encodings like ISO 8859-1 or cp1252 with high
probability will work as well, but this cannot be guaranteed.
This cannot be changed, setting the [encoding system] has no effect.
.PP
The \fIpriority\fR arguments to the \fBoption\fR command are
normally specified symbolically using one of the following values:

.IP \fBwidgetDefault\fR3
Level 20.  Used for default values hard-coded into widgets.

.IP \fBstartupFile\fR
Level 40.  Used for options specified in application-specific
startup files.

.IP \fBuserDefault\fR
Level 60.  Used for options specified in user-specific defaults
files, such as \fB.Xdefaults\fR, resource databases loaded into
the X server, or user-specific startup files.

.IP \fBinteractive\fR
Level 80.  Used for options specified interactively after the application
starts running.  If \fIpriority\fR is not specified, it defaults to
this level.
.PP
Any of the above keywords may be abbreviated.  In addition, priorities
may be specified numerically using integers between 0 and 100,
inclusive.  The numeric form is probably a bad idea except for new priority

Changes to doc/options.n.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
This option is typically only available in widgets displaying more
than one element at a time (e.g. menus but not buttons).
.OP \-activeforeground activeForeground Background
Specifies foreground color to use when drawing active elements.
See above for definition of active elements.
.OP \-activerelief activeRelief Relief
Specifies the 3-D effect desired for the active item of the widget.
See the \fB-relief\fR option for details.
.OP \-anchor anchor Anchor
Specifies how the information in a widget (e.g. text or a bitmap)
is to be displayed in the widget.
Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
For example, \fBnw\fR means display the information such that its
top-left corner is at the top-left corner of the widget.







|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
This option is typically only available in widgets displaying more
than one element at a time (e.g. menus but not buttons).
.OP \-activeforeground activeForeground Background
Specifies foreground color to use when drawing active elements.
See above for definition of active elements.
.OP \-activerelief activeRelief Relief
Specifies the 3-D effect desired for the active item of the widget.
See the \fB\-relief\fR option for details.
.OP \-anchor anchor Anchor
Specifies how the information in a widget (e.g. text or a bitmap)
is to be displayed in the widget.
Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
For example, \fBnw\fR means display the information such that its
top-left corner is at the top-left corner of the widget.
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
If the value has any other form, then the traversal scripts take
the value, append the name of the window to it (with a separator space),
and evaluate the resulting string as a Tcl script.
The script must return \fB0\fR, \fB1\fR, or an empty string:  a
\fB0\fR or \fB1\fR value specifies whether the window will receive
the input focus, and an empty string results in the default decision
described above.
Note: this interpretation of the option is defined entirely by
the Tcl scripts that implement traversal:  the widget implementations
ignore the option entirely, so you can change its meaning if you
redefine the keyboard traversal scripts.
.OP \-text text Text
Specifies a string to be displayed inside the widget.  The way in which
the string is displayed depends on the particular widget and may be
determined by other options, such as \fB\-anchor\fR or \fB\-justify\fR.







|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
If the value has any other form, then the traversal scripts take
the value, append the name of the window to it (with a separator space),
and evaluate the resulting string as a Tcl script.
The script must return \fB0\fR, \fB1\fR, or an empty string:  a
\fB0\fR or \fB1\fR value specifies whether the window will receive
the input focus, and an empty string results in the default decision
described above.
Note that this interpretation of the option is defined entirely by
the Tcl scripts that implement traversal:  the widget implementations
ignore the option entirely, so you can change its meaning if you
redefine the keyboard traversal scripts.
.OP \-text text Text
Specifies a string to be displayed inside the widget.  The way in which
the string is displayed depends on the particular widget and may be
determined by other options, such as \fB\-anchor\fR or \fB\-justify\fR.
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
in widgets such as scrollbars and scales.  This option is ignored for
scrollbars on Windows (native widget does not recognize this option).
.OP \-underline underline Underline
Specifies the integer index of a character to underline in the widget.
This option is used by the default bindings to implement keyboard
traversal for menu buttons and menu entries.
0 corresponds to the first character of the text displayed in the
widget, 1 to the next character, and so on.

.OP \-wraplength wrapLength WrapLength
For widgets that can perform word-wrapping, this option specifies
the maximum line length.
Lines that would exceed this length are wrapped onto the next line,
so that no line is longer than the specified length.
The value may be specified in any of the standard forms for
screen distances.







|
>







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
in widgets such as scrollbars and scales.  This option is ignored for
scrollbars on Windows (native widget does not recognize this option).
.OP \-underline underline Underline
Specifies the integer index of a character to underline in the widget.
This option is used by the default bindings to implement keyboard
traversal for menu buttons and menu entries.
0 corresponds to the first character of the text displayed in the
widget, 1 to the next character, and so on. \fBend\fR corresponds to the
last character, \fBend\fR-1 to the before last character, and so on.
.OP \-wraplength wrapLength WrapLength
For widgets that can perform word-wrapping, this option specifies
the maximum line length.
Lines that would exceed this length are wrapped onto the next line,
so that no line is longer than the specified length.
The value may be specified in any of the standard forms for
screen distances.

Deleted doc/pack-old.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH pack-old n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pack-old \- Obsolete syntax for packer geometry manager
.SH SYNOPSIS
\fBpack after \fIsibling \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack append \fIparent \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack before \fIsibling \fIwindow options\fR ?\fIwindow options \fR...?
.sp
\fBpack unpack \fIwindow\fR
.BE
.SH DESCRIPTION
.PP
\fINote: this manual entry describes the syntax for the \fBpack\fI
command as it existed before Tk version 3.3.
Although this syntax continues to be supported for backward
compatibility, it is obsolete and should not be used anymore.
At some point in the future it may cease to be supported.\fR
.PP
The packer is a geometry manager that arranges the
children of a parent by packing them in order around the edges of
the parent.  The first child is placed against one side of
the window, occupying the entire span of the window along that
side.  This reduces the space remaining for other children as
if the side had been moved in by the size of the first child.
Then the next child is placed against one side of the remaining
cavity, and so on until all children have been placed or there
is no space left in the cavity.
.PP
The \fBbefore\fR, \fBafter\fR, and \fBappend\fR forms of the \fBpack\fR
command are used to insert one or more children into the packing order
for their parent.  The \fBbefore\fR form inserts the children before
window \fIsibling\fR in the order;  all of the other windows must be
siblings of \fIsibling\fR.  The \fBafter\fR form inserts the windows
after \fIsibling\fR, and the \fBappend\fR form appends one or more
windows to the end of the packing order for \fIparent\fR.  If a
\fIwindow\fR named in any of these commands is already packed in
its parent, it is removed from its current position in the packing
order and repositioned as indicated by the command.  All of these
commands return an empty string as result.
.PP
The \fBunpack\fR form of the \fBpack\fR command removes \fIwindow\fR
from the packing order of its parent and unmaps it.  After the
execution of this command the packer will no longer manage
\fIwindow\fR's geometry.
.PP
The placement of each child is actually a four-step process;
the \fIoptions\fR argument following each \fIwindow\fR consists of
a list of one or more fields that govern the placement of that
window.  In the discussion below, the term \fIcavity\fR refers
to the space left in a parent when a particular child is placed
(i.e. all the space that was not claimed by earlier children in
the packing order).  The term \fIparcel\fR refers to the space
allocated to a particular child;  this is not necessarily the
same as the child window's final geometry.
.PP
The first step in placing a child is to determine which side of
the cavity it will lie against.  Any one of the following options
may be used to specify a side:
.TP
\fBtop\fR
Position the child's parcel against the top of the cavity,
occupying the full width of the cavity.
.TP
\fBbottom\fR
Position the child's parcel against the bottom of the cavity,
occupying the full width of the cavity.
.TP
\fBleft\fR
Position the child's parcel against the left side of the cavity,
occupying the full height of the cavity.
.TP
\fBright\fR
Position the child's parcel against the right side of the cavity,
occupying the full height of the cavity.
.LP
At most one of these options should be specified for any given window.
If no side is specified, then the default is \fBtop\fR.
.PP
The second step is to decide on a parcel for the child.  For \fBtop\fR
and \fBbottom\fR windows, the desired parcel width is normally the cavity
width and the desired parcel height is the window's requested height,
as passed to \fBTk_GeometryRequest\fR. For \fBleft\fR and \fBright\fR
windows, the desired parcel height is normally the cavity height and the
desired width is the window's requested width.  However, extra
space may be requested for the window using any of the following
options:
.TP 12
\fBpadx \fInum\fR
Add \fInum\fR pixels to the window's requested width before computing
the parcel size as described above.
.TP 12
\fBpady \fInum\fR
Add \fInum\fR pixels to the window's requested height before computing
the parcel size as described above.
.TP 12
\fBexpand\fR
This option requests that the window's parcel absorb any extra space left over
in the parent's cavity after packing all the children.
The amount of space left over depends on the sizes requested by the
other children, and may be zero.  If several windows have all specified
\fBexpand\fR then the extra width will be divided equally among all the
\fBleft\fR and \fBright\fR windows that specified \fBexpand\fR and
the extra height will be divided equally among all the \fBtop\fR and
\fBbottom\fR windows that specified \fBexpand\fR.
.LP
If the desired width or height for a parcel is larger than the corresponding
dimension of the cavity, then the cavity's dimension is used instead.
.PP
The third step in placing the window is to decide on the window's
width and height.  The default is for the window to receive either
its requested width and height or the those of the parcel, whichever
is smaller.  If the parcel is larger than the window's requested
size, then the following options may be used to expand the
window to partially or completely fill the parcel:
.TP
\fBfill\fR
Set the window's size to equal the parcel size.
.TP
\fBfillx\fR
Increase the window's width to equal the parcel's width, but retain
the window's requested height.
.TP
\fBfilly\fR
Increase the window's height to equal the parcel's height, but retain
the window's requested width.
.PP
The last step is to decide the window's location within its parcel.
If the window's size equals the parcel's size, then the window simply
fills the entire parcel.  If the parcel is larger than the window,
then one of
the following options may be used to specify where the window should
be positioned within its parcel:
.TP 15
\fBframe center\fR
Center the window in its parcel.  This is the default if no framing
option is specified.
.TP 15
\fBframe n\fR
Position the window with its top edge centered on the top edge of
the parcel.
.TP 15
\fBframe ne\fR
Position the window with its upper-right corner at the upper-right corner
of the parcel.
.TP 15
\fBframe e\fR
Position the window with its right edge centered on the right edge of
the parcel.
.TP 15
\fBframe se\fR
Position the window with its lower-right corner at the lower-right corner
of the parcel.
.TP 15
\fBframe s\fR
Position the window with its bottom edge centered on the bottom edge of
the parcel.
.TP 15
\fBframe sw\fR
Position the window with its lower-left corner at the lower-left corner
of the parcel.
.TP 15
\fBframe w\fR
Position the window with its left edge centered on the left edge of
the parcel.
.TP 15
\fBframe nw\fR
Position the window with its upper-left corner at the upper-left corner
of the parcel.
.PP
The packer manages the mapped/unmapped state of all the packed
children windows.  It automatically maps the windows when it packs
them, and it unmaps any windows for which there was no space left
in the cavity.
.PP
The packer makes geometry requests on behalf of the parent windows
it manages.  For each parent window it requests a size large enough
to accommodate all the options specified by all the packed children,
such that zero space would be leftover for \fBexpand\fR options.
.SH KEYWORDS
geometry manager, location, packer, parcel, size
'\" Local Variables:
'\" mode: nroff
'\" End:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































Changes to doc/pack.n.

19
20
21
22
23
24
25

26
27
28
29

30
31

32
33
34
35
36
37
38

39
40

41
42
43

44
45

46
47
48
49

50
51

52
53
54

55
56

57
58
59
60
61

62
63

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

84
85

86
87

88
89

90
91
92
93

94
95

96
97
98

99
100

101
102
103
104

105
106

107
108
109
110

111
112

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

127








128

129
130
131
132
133
134
135
136
137
138
139

140
141

142
143
144
145
146
147

148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
The \fBpack\fR command is used to communicate with the packer,
a geometry manager that arranges the children of a parent by
packing them in order around the edges of the parent.
The \fBpack\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBpack \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?

If the first argument to \fBpack\fR is a window name (any value
starting with
.QW . ),
then the command is processed in the same way as \fBpack configure\fR.

.TP
\fBpack configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?

The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the content.
See \fBTHE PACKER ALGORITHM\fR below for details on how the options
are used by the packer.
The following options are supported:
.RS

.TP
\fB\-after \fIother\fR

\fIOther\fR must the name of another window.
Use its container as the container for the content, and insert
the content just after \fIother\fR in the packing order.

.TP
\fB\-anchor \fIanchor\fR

\fIAnchor\fR must be a valid anchor position such as \fBn\fR
or \fBsw\fR; it specifies where to position each content in its
parcel.
Defaults to \fBcenter\fR.

.TP
\fB\-before \fIother\fR

\fIOther\fR must the name of another window.
Use its container as the container for the content, and insert
the content just before \fIother\fR in the packing order.

.TP
\fB\-expand \fIboolean\fR

Specifies whether the content should be expanded to consume
extra space in their container.
\fIBoolean\fR may have any proper boolean value, such as \fB1\fR
or \fBno\fR.
Defaults to 0.

.TP
\fB\-fill \fIstyle\fR

If a content's parcel is larger than its requested dimensions, this
option may be used to stretch the content.
\fIStyle\fR must have one of the following values:
.RS
.TP
\fBnone\fR
Give the content its requested dimensions plus any internal padding
requested with \fB\-ipadx\fR or \fB\-ipady\fR.  This is the default.
.TP
\fBx\fR
Stretch the content horizontally to fill the entire width of its
parcel (except leave external padding as specified by \fB\-padx\fR).
.TP
\fBy\fR
Stretch the content vertically to fill the entire height of its
parcel (except leave external padding as specified by \fB\-pady\fR).
.TP
\fBboth\fR
Stretch the content both horizontally and vertically.
.RE

.TP
\fB\-in \fIcontainer\fR

Insert the window at the end of the packing order for the container
window given by \fIcontainer\fR.

.TP
\fB\-ipadx \fIamount\fR

\fIAmount\fR specifies how much horizontal internal padding to
leave on each side of the content.
\fIAmount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.

.TP
\fB\-ipady \fIamount\fR

\fIAmount\fR specifies how much vertical internal padding to
leave on each side of the content.
\fIAmount\fR  defaults to 0.

.TP
\fB\-padx \fIamount\fR

\fIAmount\fR specifies how much horizontal external padding to
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for left and right separately.
\fIAmount\fR defaults to 0.

.TP
\fB\-pady \fIamount\fR

\fIAmount\fR specifies how much vertical external padding to
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
\fIAmount\fR defaults to 0.

.TP
\fB\-side \fIside\fR

Specifies which side of the container the content will be packed against.
Must be \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
Defaults to \fBtop\fR.
.LP
If no \fB\-in\fR, \fB\-after\fR or \fB\-before\fR option is specified
then each of the content will be inserted at the end of the packing list
for its parent unless it is already managed by the packer (in which
case it will be left where it is).
If one of these options is specified then all the content will be
inserted at the specified point.
If any of the content are already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE

.TP








\fBpack forget \fIwindow \fR?\fIwindow ...\fR?

Removes each of the \fIwindow\fRs from the packing order for its
container and unmaps their windows.
The content will no longer be managed by the packer.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will also send
the virtual event \fB<<NoManagedChild>>\fR to the container; the container
may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE

.TP
\fBpack info \fIwindow\fR

Returns a list whose elements are the current configuration state of
the window given by \fIwindow\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the window's container.

.TP
\fBpack propagate \fIcontainer\fR ?\fIboolean\fR?

If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fIcontainer\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fIcontainer\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIcontainer\fR.
Propagation is enabled by default.
.TP
\fBpack content \fIwindow\fR
Returns a list of all of the content windows in the packing order for \fIwindow\fR.
The order of the content windows in the list is the same as their order in
the packing order.
If \fIwindow\fR has no content then an empty string is returned.
.TP
\fBpack slaves \fIwindow\fR
.
Synonym for . \fBpack content \fIwindow\fR
.SH "THE PACKER ALGORITHM"
.PP
For each container the packer maintains an ordered list of content
windows called the \fIpacking list\fR.
The \fB\-in\fR, \fB\-after\fR, and \fB\-before\fR configuration
options are used to specify the container for each content and the content's
position in the packing list.







>




>


>







>


>



>


>




>


>



>


>





>


>




<
|


<
|


<
|


<
|


>


>


>


>




>


>



>


>




>


>




>


>














>

>
>
>
>
>
>
>
>

>






|
|
|


>


>






>


>










|
<
<
<
<
<



|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83

84
85
86

87
88
89

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





196
197
198
199
200
201
202
203
204
205
206
The \fBpack\fR command is used to communicate with the packer,
a geometry manager that arranges the children of a parent by
packing them in order around the edges of the parent.
The \fBpack\fR command can have any of several forms, depending
on the \fIoption\fR argument:
.TP
\fBpack \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
If the first argument to \fBpack\fR is a window name (any value
starting with
.QW . ),
then the command is processed in the same way as \fBpack configure\fR.
.\" METHOD: configure
.TP
\fBpack configure \fIwindow \fR?\fIwindow ...\fR? ?\fIoptions\fR?
.
The arguments consist of the names of one or more content windows
followed by pairs of arguments that specify how
to manage the content.
See \fBTHE PACKER ALGORITHM\fR below for details on how the options
are used by the packer.
The following options are supported:
.RS
.\" OPTION: -after
.TP
\fB\-after \fIother\fR
.
\fIOther\fR must the name of another window.
Use its container as the container for the content, and insert
the content just after \fIother\fR in the packing order.
.\" OPTION: -anchor
.TP
\fB\-anchor \fIanchor\fR
.
\fIAnchor\fR must be a valid anchor position such as \fBn\fR
or \fBsw\fR; it specifies where to position each content in its
parcel.
Defaults to \fBcenter\fR.
.\" OPTION: -before
.TP
\fB\-before \fIother\fR
.
\fIOther\fR must the name of another window.
Use its container as the container for the content, and insert
the content just before \fIother\fR in the packing order.
.\" OPTION: -expand
.TP
\fB\-expand \fIboolean\fR
.
Specifies whether the content should be expanded to consume
extra space in their container.
\fIBoolean\fR may have any proper boolean value, such as \fB1\fR
or \fBno\fR.
Defaults to 0.
.\" OPTION: -fill
.TP
\fB\-fill \fIstyle\fR
.
If a content's parcel is larger than its requested dimensions, this
option may be used to stretch the content.
\fIStyle\fR must have one of the following values:
.RS

.IP \fBnone\fR
Give the content its requested dimensions plus any internal padding
requested with \fB\-ipadx\fR or \fB\-ipady\fR.  This is the default.

.IP \fBx\fR
Stretch the content horizontally to fill the entire width of its
parcel (except leave external padding as specified by \fB\-padx\fR).

.IP \fBy\fR
Stretch the content vertically to fill the entire height of its
parcel (except leave external padding as specified by \fB\-pady\fR).

.IP \fBboth\fR
Stretch the content both horizontally and vertically.
.RE
.\" OPTION: -in
.TP
\fB\-in \fIcontainer\fR
.
Insert the window at the end of the packing order for the container
window given by \fIcontainer\fR.
.\" OPTION: -ipadx
.TP
\fB\-ipadx \fIamount\fR
.
\fIAmount\fR specifies how much horizontal internal padding to
leave on each side of the content.
\fIAmount\fR must be a valid screen distance, such as \fB2\fR or \fB.5c\fR.
It defaults to 0.
.\" OPTION: -ipady
.TP
\fB\-ipady \fIamount\fR
.
\fIAmount\fR specifies how much vertical internal padding to
leave on each side of the content.
\fIAmount\fR  defaults to 0.
.\" OPTION: -padx
.TP
\fB\-padx \fIamount\fR
.
\fIAmount\fR specifies how much horizontal external padding to
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for left and right separately.
\fIAmount\fR defaults to 0.
.\" OPTION: -pady
.TP
\fB\-pady \fIamount\fR
.
\fIAmount\fR specifies how much vertical external padding to
leave on each side of the content.  \fIAmount\fR may be a list
of two values to specify padding for top and bottom separately.
\fIAmount\fR defaults to 0.
.\" OPTION: -side
.TP
\fB\-side \fIside\fR
.
Specifies which side of the container the content will be packed against.
Must be \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
Defaults to \fBtop\fR.
.LP
If no \fB\-in\fR, \fB\-after\fR or \fB\-before\fR option is specified
then each of the content will be inserted at the end of the packing list
for its parent unless it is already managed by the packer (in which
case it will be left where it is).
If one of these options is specified then all the content will be
inserted at the specified point.
If any of the content are already managed by the geometry manager
then any unspecified options for them retain their previous values rather
than receiving default values.
.RE
.\" METHOD: content
.TP
\fBpack content \fIwindow\fR
.
Returns a list of all of the content windows in the packing order for
\fIwindow\fR. The order of the content windows in the list is the same as
their order in the packing order.
If \fIwindow\fR has no content then an empty string is returned.
.\" METHOD: forget
.TP
\fBpack forget \fIwindow \fR?\fIwindow ...\fR?
.
Removes each of the \fIwindow\fRs from the packing order for its
container and unmaps their windows.
The content will no longer be managed by the packer.
.RS
.PP
.VS "TIP 518"
If the last content window of the container becomes unmanaged, this will
also send the virtual event \fB<<NoManagedChild>>\fR to the container; the
container may choose to resize itself (or otherwise respond) to such a change.
.VE "TIP 518"
.RE
.\" METHOD: info
.TP
\fBpack info \fIwindow\fR
.
Returns a list whose elements are the current configuration state of
the window given by \fIwindow\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
where \fIcontainer\fR is the window's container.
.\" METHOD: propagate
.TP
\fBpack propagate \fIcontainer\fR ?\fIboolean\fR?
.
If \fIboolean\fR has a true boolean value such as \fB1\fR or \fBon\fR
then propagation is enabled for \fIcontainer\fR, which must be a window
name (see \fBGEOMETRY PROPAGATION\fR below).
If \fIboolean\fR has a false boolean value then propagation is
disabled for \fIcontainer\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIcontainer\fR.
Propagation is enabled by default.
.\" METHOD: slaves





.TP
\fBpack slaves \fIwindow\fR
.
Synonym for \fBpack content \fIwindow\fR.
.SH "THE PACKER ALGORITHM"
.PP
For each container the packer maintains an ordered list of content
windows called the \fIpacking list\fR.
The \fB\-in\fR, \fB\-after\fR, and \fB\-before\fR configuration
options are used to specify the container for each content and the content's
position in the packing list.
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
will be highest in the stacking order.
Or, you can use the \fBraise\fR and \fBlower\fR commands to change
the stacking order of either the container or the content.
.SH EXAMPLE
.PP
.CS
# Make the widgets
label .t \-text "This widget is at the top"    \-bg red
label .b \-text "This widget is at the bottom" \-bg green
label .l \-text "Left\enHand\enSide"
label .r \-text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
\fBpack\fR .t   \-side top    \-fill x
\fBpack\fR .b   \-side bottom \-fill x
\fBpack\fR .l   \-side left   \-fill y
\fBpack\fR .r   \-side right  \-fill y
\fBpack\fR .mid \-expand 1    \-fill both
.CE
.SH "SEE ALSO"
grid(n), place(n)
.SH KEYWORDS
geometry manager, location, packer, parcel, propagation, size
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|
|



|
|
|
|
|








299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
will be highest in the stacking order.
Or, you can use the \fBraise\fR and \fBlower\fR commands to change
the stacking order of either the container or the content.
.SH EXAMPLE
.PP
.CS
# Make the widgets
label .t -text "This widget is at the top"    -bg red
label .b -text "This widget is at the bottom" -bg green
label .l -text "Left\enHand\enSide"
label .r -text "Right\enHand\enSide"
text .mid
\&.mid insert end "This layout is like Java's BorderLayout"
# Lay them out
\fBpack\fR .t   -side top    -fill x
\fBpack\fR .b   -side bottom -fill x
\fBpack\fR .l   -side left   -fill y
\fBpack\fR .r   -side right  -fill y
\fBpack\fR .mid -expand 1    -fill both
.CE
.SH "SEE ALSO"
grid(n), place(n)
.SH KEYWORDS
geometry manager, location, packer, parcel, propagation, size
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/palette.n.

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

14
15
16
17
18

19
20
21
22
23
24
25
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tk_setPalette n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_setPalette, tk_bisque \- Modify the Tk color palette
.SH SYNOPSIS

\fBtk_setPalette \fIbackground\fR
.sp
\fBtk_setPalette \fIname value \fR?\fIname value ...\fR?
.sp
\fBtk_bisque\fR

.BE
.SH DESCRIPTION
.PP
The \fBtk_setPalette\fR procedure changes the color scheme for Tk.
It does this by modifying the colors of existing widgets and by changing
the option database so that future widgets will use the new color scheme.
If \fBtk_setPalette\fR is invoked with a single argument, the













>

<

<

>







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

16

17
18
19
20
21
22
23
24
25
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tk_setPalette n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_setPalette, tk_bisque \- Modify the Tk color palette
.SH SYNOPSIS
.nf
\fBtk_setPalette \fIbackground\fR

\fBtk_setPalette \fIname value \fR?\fIname value ...\fR?

\fBtk_bisque\fR
.fi
.BE
.SH DESCRIPTION
.PP
The \fBtk_setPalette\fR procedure changes the color scheme for Tk.
It does this by modifying the colors of existing widgets and by changing
the option database so that future widgets will use the new color scheme.
If \fBtk_setPalette\fR is invoked with a single argument, the

Changes to doc/panedwindow.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH panedwindow n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
panedwindow \- Create and manipulate 'panedwindow' split container widgets
.SH SYNOPSIS
\fBpanedwindow\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-orient	\-relief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-handlepad handlePad HandlePad
When sash handles are drawn, specifies the distance from the top or







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH panedwindow n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
panedwindow \- Create and manipulate 'panedwindow' split container widgets
.SH SYNOPSIS
\fBpanedwindow\fI pathName \fR?\fIoptions\fR?
.SO
\-background	\-borderwidth	\-cursor
\-orient	\-relief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-handlepad handlePad HandlePad
When sash handles are drawn, specifies the distance from the top or
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
or if resizing should be deferred until the sash is placed (false).
In the latter case, a
.QW ghost
version of the sash is displayed during the resizing to show where the
panes will be resized to when releasing the mouse button. This
.QW ghost
version of the sash is the proxy. It's rendering can be configured
using the \fB-proxybackground\fR, \fB-proxyborderwidth\fR and
\fB-proxyrelief\fR options.
.OP \-proxybackground proxyBackground ProxyBackground
Background color to use when drawing the proxy. If an empty string, the
value of the \fB-background\fR option will be used.
.OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth
Specifies the borderwidth of the proxy. May be any value accepted by
\fBTk_GetPixels\fR.
.OP \-proxyrelief proxyRelief ProxyRelief
Relief to use when drawing the proxy. May be any of the standard Tk
relief values. If an empty string, the value of the \fB-sashrelief\fR
option will be used.
.OP \-sashcursor sashCursor SashCursor
Mouse cursor to use when over a sash.  If null,
\fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and
\fBsb_v_double_arrow\fR will be used for vertical panedwindows.
.OP \-sashpad sashPad SashPad
Specifies the amount of padding to leave of each side of a sash.  May







|
|


|





|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
or if resizing should be deferred until the sash is placed (false).
In the latter case, a
.QW ghost
version of the sash is displayed during the resizing to show where the
panes will be resized to when releasing the mouse button. This
.QW ghost
version of the sash is the proxy. It's rendering can be configured
using the \fB\-proxybackground\fR, \fB\-proxyborderwidth\fR and
\fB\-proxyrelief\fR options.
.OP \-proxybackground proxyBackground ProxyBackground
Background color to use when drawing the proxy. If an empty string, the
value of the \fB\-background\fR option will be used.
.OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth
Specifies the borderwidth of the proxy. May be any value accepted by
\fBTk_GetPixels\fR.
.OP \-proxyrelief proxyRelief ProxyRelief
Relief to use when drawing the proxy. May be any of the standard Tk
relief values. If an empty string, the value of the \fB\-sashrelief\fR
option will be used.
.OP \-sashcursor sashCursor SashCursor
Mouse cursor to use when over a sash.  If null,
\fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and
\fBsb_v_double_arrow\fR will be used for vertical panedwindows.
.OP \-sashpad sashPad SashPad
Specifies the amount of padding to leave of each side of a sash.  May
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108

109
110
111
112
113
114

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

129
130
131
132
133

134
135
136
137
138
139
140
141
142

143
144
145
146
147

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

163
164
165
166
167

168
169
170
171
172

173
174
175
176
177
178
179
180
181

182
183
184
185
186
187

188
189
190
191
192
193
194
195

196
197
198
199
200
201

202
203
204
205
206
207

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

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266

267
268
269
270

271
272
273
274
275
276
277
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:

.TP
\fIpathName \fBadd \fIwindow \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?
.
Add one or more windows to the panedwindow, each in a separate pane.
The arguments consist of the names of one or more windows
followed by pairs of arguments that specify how to manage the windows.
\fIOption\fR may have any of the values accepted by the
\fBconfigure\fR subcommand.

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given by
\fIoption\fR.  \fIOption\fR may have any of the values accepted by the
\fBpanedwindow\fR command.

.TP
\fIpathName \fBconfigure \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. \fIOption\fR may have
any of the values accepted by the \fBpanedwindow\fR command.

.TP
\fIpathName \fBforget \fIwindow \fR?\fIwindow ...\fR?
.
Remove the pane containing \fIwindow\fR from the panedwindow.  All
geometry management options for \fIwindow\fR will be forgotten.

.TP
\fIpathName \fBidentify \fIx y\fR
.
Identify the panedwindow component underneath the point given by
\fIx\fR and \fIy\fR, in window coordinates.  If the point is over a
sash or a sash handle, the result is a two element list containing the
index of the sash or handle, and a word indicating whether it is over
a sash or a handle, such as {0 sash} or {2 handle}.  If the point is
over any other part of the panedwindow, the result is an empty list.

.TP
\fIpathName \fBpanecget \fIwindow option\fR
.
Query a management option for \fIwindow\fR.  \fIOption\fR may be any
value allowed by the \fBpaneconfigure\fR subcommand.

.TP
\fIpathName \fBpaneconfigure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the management options for \fIwindow\fR.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.  The following options
are supported:
.RS

.TP
\fB\-after \fIwindow\fR
.
Insert the window after the window specified.  \fIwindow\fR should be the
name of a window already managed by \fIpathName\fR.

.TP
\fB\-before \fIwindow\fR
.
Insert the window before the window specified.  \fIwindow\fR should be
the name of a window already managed by \fIpathName\fR.

.TP
\fB\-height \fIsize\fR
.
Specify a height for the window.  The height will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-height\fR is not specified, then the
height requested internally by the window will be used initially; the
height may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.

.TP
\fB\-hide \fIboolean\fR
.
Controls the visibility of a pane.  When the \fIboolean\fR is true
(according to \fBTcl_GetBoolean\fR) the pane will not be visible, but
it will still be maintained in the list of panes.

.TP
\fB\-minsize \fIn\fR
.
Specifies that the size of the window cannot be made less than
\fIn\fR.  This constraint only affects the size of the widget in the
paned dimension \(em the x dimension for horizontal panedwindows, the y
dimension for vertical panedwindows.  May be any value accepted by
\fBTk_GetPixels\fR.

.TP
\fB\-padx \fIn\fR
.
Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the X-direction.  The value may
have any of the forms accepted by \fBTk_GetPixels\fR.

.TP
\fB\-pady \fIn\fR
.
Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the Y-direction.  The value may
have any of the forms accepted by \fBTk_GetPixels\fR.

.TP
\fB\-sticky \fIstyle\fR
.
If a window's pane is larger than the requested dimensions of the
window, this option may be used to position (or stretch) the window
within its pane.  \fIStyle\fR  is a string that contains zero or more
of the characters \fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.  The string
can optionally contains spaces or commas, but they are ignored.  Each
letter refers to a side (north, south, east, or west) that the window
will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR)
are specified, the window will be stretched to fill the entire height
(or width) of its cavity.

.TP
\fB\-stretch \fIwhen\fR
.
Controls how extra space is allocated to each of the panes.
\fIWhen\fR is one of \fBalways\fR, \fBfirst\fR, \fBlast\fR,
\fBmiddle\fR, and \fBnever\fR.
The panedwindow will calculate the required size of all its panes. Any
remaining (or deficit) space will be distributed to those panes marked
for stretching. The space will be distributed based on each panes
current ratio of the whole.  The \fIwhen\fR values have the following
definition:
.RS
.TP
\fBalways\fR
.
This pane will always stretch.
.TP
\fBfirst\fR
.
Only if this pane is the first pane (left-most or top-most) will it
stretch.
.TP
\fBlast\fR
.
Only if this pane is the last pane (right-most or bottom-most) will it
stretch.  This is the default value.
.TP
\fBmiddle\fR
.
Only if this pane is not the first or last pane will it stretch.
.TP
\fBnever\fR
.
This pane will never stretch.
.RE

.TP
\fB\-width \fIsize\fR
.
Specify a width for the window.  The width will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-width\fR is not specified, then the
width requested internally by the window will be used initially; the
width may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.RE

.TP
\fIpathName \fBpanes\fR
.
Returns an ordered list of the widgets managed by \fIpathName\fR.

.TP
\fIpathName \fBproxy \fR?\fIargs\fR?
.
This command is used to query and change the position of the sash
proxy, used for rubberband-style pane resizing. It can take any of
the following forms:
.RS







>








>






>














>





>









>





>















>





>





>









>






>








>






>






>














>












<
|
<

<
|
<


<
|
<


<
|
<

<
|
<


>










>




>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250

251

252

253
254

255

256
257

258

259

260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:
.\" METHOD: add
.TP
\fIpathName \fBadd \fIwindow \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?
.
Add one or more windows to the panedwindow, each in a separate pane.
The arguments consist of the names of one or more windows
followed by pairs of arguments that specify how to manage the windows.
\fIOption\fR may have any of the values accepted by the
\fBconfigure\fR subcommand.
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given by
\fIoption\fR.  \fIOption\fR may have any of the values accepted by the
\fBpanedwindow\fR command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string. \fIOption\fR may have
any of the values accepted by the \fBpanedwindow\fR command.
.\" METHOD: forget
.TP
\fIpathName \fBforget \fIwindow \fR?\fIwindow ...\fR?
.
Remove the pane containing \fIwindow\fR from the panedwindow.  All
geometry management options for \fIwindow\fR will be forgotten.
.\" METHOD: identify
.TP
\fIpathName \fBidentify \fIx y\fR
.
Identify the panedwindow component underneath the point given by
\fIx\fR and \fIy\fR, in window coordinates.  If the point is over a
sash or a sash handle, the result is a two element list containing the
index of the sash or handle, and a word indicating whether it is over
a sash or a handle, such as {0 sash} or {2 handle}.  If the point is
over any other part of the panedwindow, the result is an empty list.
.\" METHOD: panecget
.TP
\fIpathName \fBpanecget \fIwindow option\fR
.
Query a management option for \fIwindow\fR.  \fIOption\fR may be any
value allowed by the \fBpaneconfigure\fR subcommand.
.\" METHOD: paneconfigure
.TP
\fIpathName \fBpaneconfigure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the management options for \fIwindow\fR.  If no
\fIoption\fR is specified, returns a list describing all of the
available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.  The following options
are supported:
.RS
.\" OPTION: -after
.TP
\fB\-after \fIwindow\fR
.
Insert the window after the window specified.  \fIwindow\fR should be the
name of a window already managed by \fIpathName\fR.
.\" OPTION: -before
.TP
\fB\-before \fIwindow\fR
.
Insert the window before the window specified.  \fIwindow\fR should be
the name of a window already managed by \fIpathName\fR.
.\" OPTION: -height
.TP
\fB\-height \fIsize\fR
.
Specify a height for the window.  The height will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-height\fR is not specified, then the
height requested internally by the window will be used initially; the
height may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.\" OPTION: -hide
.TP
\fB\-hide \fIboolean\fR
.
Controls the visibility of a pane.  When the \fIboolean\fR is true
(according to \fBTcl_GetBoolean\fR) the pane will not be visible, but
it will still be maintained in the list of panes.
.\" OPTION: -minsize
.TP
\fB\-minsize \fIn\fR
.
Specifies that the size of the window cannot be made less than
\fIn\fR.  This constraint only affects the size of the widget in the
paned dimension \(em the x dimension for horizontal panedwindows, the y
dimension for vertical panedwindows.  May be any value accepted by
\fBTk_GetPixels\fR.
.\" OPTION: -padx
.TP
\fB\-padx \fIn\fR
.
Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the X-direction.  The value may
have any of the forms accepted by \fBTk_GetPixels\fR.
.\" OPTION: -pady
.TP
\fB\-pady \fIn\fR
.
Specifies a non-negative value indicating how much extra space to
leave on each side of the window in the Y-direction.  The value may
have any of the forms accepted by \fBTk_GetPixels\fR.
.\" OPTION: -sticky
.TP
\fB\-sticky \fIstyle\fR
.
If a window's pane is larger than the requested dimensions of the
window, this option may be used to position (or stretch) the window
within its pane.  \fIStyle\fR  is a string that contains zero or more
of the characters \fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.  The string
can optionally contains spaces or commas, but they are ignored.  Each
letter refers to a side (north, south, east, or west) that the window
will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR)
are specified, the window will be stretched to fill the entire height
(or width) of its cavity.
.\" OPTION: -stretch
.TP
\fB\-stretch \fIwhen\fR
.
Controls how extra space is allocated to each of the panes.
\fIWhen\fR is one of \fBalways\fR, \fBfirst\fR, \fBlast\fR,
\fBmiddle\fR, and \fBnever\fR.
The panedwindow will calculate the required size of all its panes. Any
remaining (or deficit) space will be distributed to those panes marked
for stretching. The space will be distributed based on each panes
current ratio of the whole.  The \fIwhen\fR values have the following
definition:
.RS

.IP \fBalways\fR

This pane will always stretch.

.IP \fBfirst\fR

Only if this pane is the first pane (left-most or top-most) will it
stretch.

.IP \fBlast\fR

Only if this pane is the last pane (right-most or bottom-most) will it
stretch.  This is the default value.

.IP \fBmiddle\fR

Only if this pane is not the first or last pane will it stretch.

.IP \fBnever\fR

This pane will never stretch.
.RE
.\" OPTION: -width
.TP
\fB\-width \fIsize\fR
.
Specify a width for the window.  The width will be the outer
dimension of the window including its border, if any.  If \fIsize\fR
is an empty string, or if \fB\-width\fR is not specified, then the
width requested internally by the window will be used initially; the
width may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.RE
.\" METHOD: panes
.TP
\fIpathName \fBpanes\fR
.
Returns an ordered list of the widgets managed by \fIpathName\fR.
.\" METHOD: proxy
.TP
\fIpathName \fBproxy \fR?\fIargs\fR?
.
This command is used to query and change the position of the sash
proxy, used for rubberband-style pane resizing. It can take any of
the following forms:
.RS
285
286
287
288
289
290
291

292
293

294
295
296
297
298
299
300
.
Remove the proxy from the display.
.TP
\fIpathName \fBproxy place \fIx y\fR
.
Place the proxy at the given \fIx\fR and \fIy\fR coordinates.
.RE

.TP
\fIpathName \fBsash \fR?\fIargs\fR?

This command is used to query and change the position of sashes in the
panedwindow.  It can take any of the following forms:
.RS
.TP
\fIpathName \fBsash coord \fIindex\fR
.
Return the current x and y coordinate pair for the sash given by







>


>







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
.
Remove the proxy from the display.
.TP
\fIpathName \fBproxy place \fIx y\fR
.
Place the proxy at the given \fIx\fR and \fIy\fR coordinates.
.RE
.\" METHOD: sash
.TP
\fIpathName \fBsash \fR?\fIargs\fR?
.
This command is used to query and change the position of sashes in the
panedwindow.  It can take any of the following forms:
.RS
.TP
\fIpathName \fBsash coord \fIindex\fR
.
Return the current x and y coordinate pair for the sash given by

Changes to doc/photo.n.

39
40
41
42
43
44
45




46
47
48
49
50
51
52
53
54
55
56

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

71
72
73
74
75
76
77
78

79
80
81
82
83
84

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

97
98
99
100
101
102
103












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

116
117
118
119
120
121
122
internally in full color (32 bits per pixel), and is displayed using
dithering if necessary.  Image data for a photo image can be obtained
from a file or a string, or it can be supplied from C code through a
procedural interface.  At present, only
.VS 8.6
PNG,
.VE 8.6




GIF and PPM/PGM formats are supported, but an interface exists to
allow additional image file formats to be added easily.  A photo image
is (semi)transparent if the image data it was obtained from had
transparency informaton. In regions where no image data has been
supplied, it is fully transparent. Transparency may also be modified
with the \fBtransparency set\fR subcommand.
.SH "CREATING PHOTOS"
.PP
Like all images, photos are created using the \fBimage create\fR
command.
Photos support the following \fIoptions\fR:

.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the image as a string.
.VS 8.7
The string should
contain data in the default list-of-lists form,
.VE 8.7
binary data or, for some formats, base64-encoded data (this is
currently guaranteed to be supported for PNG and GIF images). The
format of the string must be one of those for which there is an image
file format handler that will accept string data.  If both the
\fB\-data\fR and \fB\-file\fR options are specified, the \fB\-file\fR
option takes precedence.

.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the file format for the data specified with the
\fB\-data\fR or \fB\-file\fR option and optional arguments passed to
the format handler. Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.

.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file that is to be read to supply data
for the photo image.  The file format must be one of those for which
there is an image file format handler that can read data.

.TP
\fB\-gamma \fIvalue\fR
.
Specifies that the colors allocated for displaying this image in a
window should be corrected for a non-linear display with the specified
gamma exponent value.  (The intensity produced by most
CRT displays is a power function of the input value, to a good
approximation; gamma is the exponent and is typically around 2).
The value specified must be greater than zero.  The default
value is one (no correction).  In general, values greater than one
will make the image lighter, and values less than one will make it
darker.

.TP
\fB\-height \fInumber\fR
.
Specifies the height of the image, in pixels.  This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink vertically to fit the data stored in it.












.TP
\fB\-palette \fIpalette-spec\fR
.
Specifies the resolution of the color cube to be allocated for
displaying this image, and thus the number of colors used from the
colormaps of the windows where it is displayed.  The
\fIpalette-spec\fR string may be either a single decimal number,
specifying the number of shades of gray to use, or three decimal
numbers separated by slashes (/), specifying the number of shades of
red, green and blue to use, respectively.  If the first form (a single
number) is used, the image will be displayed in monochrome (i.e.,
grayscale).

.TP
\fB\-width \fInumber\fR
.
Specifies the width of the image, in pixels.    This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink horizontally to fit the data stored in it.







>
>
>
>
|


|







>














>





|


>






>












>







>
>
>
>
>
>
>
>
>
>
>
>












>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
internally in full color (32 bits per pixel), and is displayed using
dithering if necessary.  Image data for a photo image can be obtained
from a file or a string, or it can be supplied from C code through a
procedural interface.  At present, only
.VS 8.6
PNG,
.VE 8.6
GIF, PPM/PGM,
.VS 8.7
and (read-only) SVG
.VE 8.7
formats are supported, but an interface exists to
allow additional image file formats to be added easily.  A photo image
is (semi)transparent if the image data it was obtained from had
transparency information. In regions where no image data has been
supplied, it is fully transparent. Transparency may also be modified
with the \fBtransparency set\fR subcommand.
.SH "CREATING PHOTOS"
.PP
Like all images, photos are created using the \fBimage create\fR
command.
Photos support the following \fIoptions\fR:
.\" OPTION: -data
.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the image as a string.
.VS 8.7
The string should
contain data in the default list-of-lists form,
.VE 8.7
binary data or, for some formats, base64-encoded data (this is
currently guaranteed to be supported for PNG and GIF images). The
format of the string must be one of those for which there is an image
file format handler that will accept string data.  If both the
\fB\-data\fR and \fB\-file\fR options are specified, the \fB\-file\fR
option takes precedence.
.\" OPTION: -format
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the file format for the data specified with the
\fB\-data\fR or \fB\-file\fR option and optional arguments passed to
the format handler. Note that 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.
.\" OPTION: -file
.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file that is to be read to supply data
for the photo image.  The file format must be one of those for which
there is an image file format handler that can read data.
.\" OPTION: -gamma
.TP
\fB\-gamma \fIvalue\fR
.
Specifies that the colors allocated for displaying this image in a
window should be corrected for a non-linear display with the specified
gamma exponent value.  (The intensity produced by most
CRT displays is a power function of the input value, to a good
approximation; gamma is the exponent and is typically around 2).
The value specified must be greater than zero.  The default
value is one (no correction).  In general, values greater than one
will make the image lighter, and values less than one will make it
darker.
.\" OPTION: -height
.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
.\" OPTION: -metadata
.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
.\" OPTION: -palette
.TP
\fB\-palette \fIpalette-spec\fR
.
Specifies the resolution of the color cube to be allocated for
displaying this image, and thus the number of colors used from the
colormaps of the windows where it is displayed.  The
\fIpalette-spec\fR string may be either a single decimal number,
specifying the number of shades of gray to use, or three decimal
numbers separated by slashes (/), specifying the number of shades of
red, green and blue to use, respectively.  If the first form (a single
number) is used, the image will be displayed in monochrome (i.e.,
grayscale).
.\" OPTION: -width
.TP
\fB\-width \fInumber\fR
.
Specifies the width of the image, in pixels.    This option is useful
primarily in situations where the user wishes to build up the contents
of the image piece by piece.  A value of zero (the default) allows the
image to expand or shrink horizontally to fit the data stored in it.
137
138
139
140
141
142
143

144
145
146
147
148
149


150
151
152
153
154
155
156

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





172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226

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

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

251
252
253
254
255
256

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

275
276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291

292












293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324











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

339
340
341
342
343
344
345
346
347
348

349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368
369











370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428

429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457

458
459
460
461
462











463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
of the image, if necessary, to accommodate the data written to the
image, unless the user has specified non-zero values for the
\fB\-width\fR and/or \fB\-height\fR configuration options, in which
case the width and/or height, respectively, of the image will not be
changed.
.PP
The following commands are possible for photo images:

.TP
\fIimageName \fBblank\fR
.
Blank the image; that is, set the entire image to have no data, so it
will be displayed as transparent, and the background of whatever
window it is displayed in will show through.


.TP
\fIimageName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.

.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.





.TP
\fIimageName \fBcopy\fR \fIsourceImage\fR ?\fIoption value(s) ...\fR?
.
Copies a region from the image called \fIsourceImage\fR (which must
be a photo image) to the image called \fIimageName\fR, possibly with
pixel zooming and/or subsampling.  If no options are specified, this
command copies the whole of \fIsourceImage\fR into \fIimageName\fR,
starting at coordinates (0,0) in \fIimageName\fR.  The following
options may be specified:
.RS

.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the source image to be copied.
(\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite corners of
the rectangle.  If \fIx2\fR and \fIy2\fR are not specified, the
default value is the bottom-right corner of the source image.  The
pixels copied will include the left and top edges of the specified
rectangle but not the bottom or right edges.  If the \fB\-from\fR
option is not given, the default is the whole source image.

.TP
\fB\-to \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the destination image to be
affected.  (\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite
corners of the rectangle.  If \fIx2\fR and \fIy2\fR are not specified,
the default value is (\fIx1,y1\fR) plus the size of the source
region (after subsampling and zooming, if specified).  If \fIx2\fR and
\fIy2\fR are specified, the source region will be replicated if
necessary to fill the destination region in a tiled fashion.

.TP
\fB\-shrink\fR
.
Specifies that the size of the destination image should be reduced, if
necessary, so that the region being copied into is at the bottom-right
corner of the image.  This option will not affect the width or height
of the image if the user has specified a non-zero value for the
\fB\-width\fR or \fB\-height\fR configuration option, respectively.

.TP
\fB\-zoom \fIx y\fR
.
Specifies that the source region should be magnified by a factor of
\fIx\fR in the X direction and \fIy\fR in the Y direction.  If \fIy\fR
is not given, the default value is the same as \fIx\fR.  With this
option, each pixel in the source image will be expanded into a block
of \fIx\fR x \fIy\fR pixels in the destination image, all the same
color.  \fIx\fR and \fIy\fR must be greater than 0.

.TP
\fB\-subsample \fIx y\fR
.
Specifies that the source image should be reduced in size by using
only every \fIx\fRth pixel in the X direction and \fIy\fRth pixel in
the Y direction.  Negative values will cause the image to be flipped
about the Y or X axes, respectively.  If \fIy\fR is not given, the
default value is the same as \fIx\fR.

.TP
\fB\-compositingrule \fIrule\fR
.
Specifies how transparent pixels in the source image are combined with
the destination image.  When a compositing rule of \fIoverlay\fR is
set, the old contents of the destination image are visible, as if the
source image were printed on a piece of transparent film and placed
over the top of the destination.  When a compositing rule of \fIset\fR
is set, the old contents of the destination image are discarded and
the source image is used as-is.  The default compositing rule is
\fIoverlay\fR.
.RE

.TP
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
.
Returns image data in the form of a string.
.VS 8.7
The format of the string depends on the format handler. By default, a
human readable format as a list of lists of pixel data is used, other
formats can be chosen with the \fB-format\fR option.
See \fBIMAGE FORMATS\fR below for details.
.VE 8.7
The following options may be specified:
.RS

.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.

.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the image file format handler to use and,
optionally, arguments to the format handler.  Specifically, this
subcommand searches for the first handler whose name matches an
initial substring of \fIformat-name\fR and which has the capability to
write a string containing this image data.
.VS 8.7
If this option is not given, this subcommand uses the default format
that consists of a list (one element per row) of lists (one element
per pixel/column) of colors in
.QW \fB#\fIrrggbb\fR
format (see \fBIMAGE FORMATS\fR below).
.VE 8.7
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.

.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be returned.
If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region, including x1,y1
and excluding x2,y2.  The default, if this option is not given, is the
whole image.

.TP
\fB\-grayscale\fR
.
If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.RE
.VS 8.7

.TP












\fIimageName \fBget\fR \fIx y\fR ?\fB-withalpha\fR?
.
Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the
image as a list of three integers between 0 and 255, representing the
red, green and blue components respectively. If the \fB-withalpha\fR
option is specified, the returned list will have a fourth element
representing the alpha value of the pixel as an integer between 0 and
255.
.VE 8.7
.TP
\fIimageName \fBput\fR \fIdata\fR ?\fIoption value(s) ...\fR?
.
Sets pixels in \fI imageName\fR to the data specified in \fIdata\fR.
.VS 8.7
This command searches the list of image file format handlers for
a handler that can interpret the data in \fIdata\fR, and then reads
the image encoded within into \fIimageName\fR (the destination image).
See \fBIMAGE FORMATS\fR below for details on formats for image data.
.VE 8.7
The following options may be specified:
.RS

.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ..\fR?}
.
Specifies the format of the image data in \fIdata\fR and, optionally,
arguments to be passed to the format handler.
Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.











.TP
\fB\-to \fIx1 y1\fR ?\fIx2 y2\fR?
.
Specifies the coordinates of the top-left corner (\fIx1\fR,\fIy1\fR)
of the region of \fIimageName\fR into which the image data will be
copied.  The default position is (0,0).  If \fIx2\fR,\fIy2\fR is given
and \fIdata\fR is not large enough to cover the rectangle specified by
this option, the image data extracted will be tiled so it covers the
entire destination rectangle. If the region specified with this opion
is smaller than the supplied \fIdata\fR, the exceeding data is silently
discarded. Note that if \fIdata\fR specifies a
single color value, then a region extending to the bottom-right corner
represented by (\fIx2\fR,\fIy2\fR) will be filled with that color.
.RE

.TP
\fIimageName \fBread\fR \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Reads image data from the file named \fIfilename\fR into the image.
This command first searches the list of
image file format handlers for a handler that can interpret the data
in \fIfilename\fR, and then reads the image in \fIfilename\fR into
\fIimageName\fR (the destination image).  The following options may be
specified:
.RS

.TP
\fB\-format {\fIformat-name\fR ?\fIoption value ..\fR?}
.
Specifies the format of the image data in \fIfilename\fR and,
optionally, additional options to the format handler.
Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.

.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the image file data to be copied
to the destination image.  If only \fIx1\fR and \fIy1\fR are
specified, the region extends from (\fIx1,y1\fR) to the bottom-right
corner of the image in the image file.  If all four coordinates are
specified, they specify diagonally opposite corners or the region.
The default, if this option is not specified, is the whole of the
image in the image file.











.TP
\fB\-shrink\fR
.
If this option, the size of \fIimageName\fR will be reduced, if
necessary, so that the region into which the image file data are read
is at the bottom-right corner of the \fIimageName\fR.  This option
will not affect the width or height of the image if the user has
specified a non-zero value for the \fB\-width\fR or \fB\-height\fR
configuration option, respectively.

.TP
\fB\-to \fIx y\fR
.
Specifies the coordinates of the top-left corner of the region of
\fIimageName\fR into which data from \fIfilename\fR are to be read.
The default is (0,0).
.RE

.TP
\fIimageName \fBredither\fR
.
The dithering algorithm used in displaying photo images propagates
quantization errors from one pixel to its neighbors.
If the image data for \fIimageName\fR is supplied in pieces, the
dithered image may not be exactly correct.  Normally the difference is
not noticeable, but if it is a problem, this command can be used to
recalculate the dithered image in each window where the image is
displayed.

.TP
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
.
Allows examination and manipulation of the transparency information in
the photo image.  Several subcommands are available:
.RS
.VS 8.7
.TP
\fIimageName \fBtransparency get \fIx y\fR ?\fB-alpha\fR?
.
Returns true if the pixel at (\fIx\fR,\fIy\fR) is fully transparent,
false otherwise.  If the option \fB-alpha\fR is passed, returns the
alpha value of the pixel instead, as an integer in the range 0 to 255.
.VE 8.7

.VS 8.7
.TP
\fIimageName \fBtransparency set \fIx y\fR \fInewVal\fR ?\fB-alpha\fR?
.
Change the transparency of the pixel at (\fIx\fR,\fIy\fR) to
\fInewVal.\fR If no additional option is passed, \fInewVal\fR is
interpreted as a boolean and the pixel is made fully transparent if
that value is true, fully opaque otherwise.  If the \fB-alpha\fR
option is passed, \fInewVal\fR is interpreted as an integral alpha
value for the pixel, which must be in the range 0 to 255.
.VE 8.7
.RE

.TP
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Writes image data from \fIimageName\fR to a file named \fIfilename\fR.
The following options may be specified:
.RS

.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.

.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the image file format handler to be used to
write the data to the file and, optionally, options to pass to the
format handler.  Specifically, this subcommand searches for the first
handler whose name matches an initial substring of \fIformat-name\fR
and which has the capability to write an image file.  If this option
is not given, the format is guessed from the file extension. If that
cannot be determined, this subcommand uses the first handler that has
the capability to write an image file.
Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.

.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be written to the
image file.  If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region.  The default,
if this option is not given, is the whole image.

.TP
\fB\-grayscale\fR
.
If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.











.RE
.SH "IMAGE FORMATS"
.PP
The photo image code is structured to allow handlers for additional
image file formats to be added easily.  The photo image code maintains
a list of these handlers.  Handlers are added to the list by
registering them with a call to \fBTk_CreatePhotoImageFormat\fR.  The
standard Tk distribution comes with handlers for PPM/PGM, PNG and GIF
formats,
.VS 8.7
as well as the \fBdefault\fR handler to encode/decode image
data in a human readable form.
.VE 8.7
These handlers are automatically registered on initialization.
.PP
When reading an image file or processing string data specified with







>





|
>
>

|





>















>
>
>
>
>

|








>










>










>








>









>








>












>







|




>






>















|


>










>





<

>

>
>
>
>
>
>
>
>
>
>
>
>
|



|



|

|










>








|


>
>
>
>
>
>
>
>
>
>
>








|





>

|








>








|


>










>
>
>
>
>
>
>
>
>
>
>









>







>










>






<

|
|

|


<
<

|
|



|




>






>






>











|


>









>





>
>
>
>
>
>
>
>
>
>
>







|
|







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

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491


492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
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:
.\" METHOD: blank
.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. The metadata dict of the
image is not changed.
.\" METHOD: cget
.TP
\fIimageName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.
.\" METHOD: configure
.TP
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options for the image.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIimageName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the
\fBimage create\fR \fBphoto\fR command.
.VS 8.7
Note that setting the \fB\-metadata\fR option without any other option
will not invoke the image format driver to recreate the bitmap.
.VE 8.7
.\" METHOD: copy
.TP
\fIimageName \fBcopy\fI sourceImage\fR ?\fIoption value(s) ...\fR?
.
Copies a region from the image called \fIsourceImage\fR (which must
be a photo image) to the image called \fIimageName\fR, possibly with
pixel zooming and/or subsampling.  If no options are specified, this
command copies the whole of \fIsourceImage\fR into \fIimageName\fR,
starting at coordinates (0,0) in \fIimageName\fR.  The following
options may be specified:
.RS
.\" OPTION: -from
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the source image to be copied.
(\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite corners of
the rectangle.  If \fIx2\fR and \fIy2\fR are not specified, the
default value is the bottom-right corner of the source image.  The
pixels copied will include the left and top edges of the specified
rectangle but not the bottom or right edges.  If the \fB\-from\fR
option is not given, the default is the whole source image.
.\" OPTION: -to
.TP
\fB\-to \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the destination image to be
affected.  (\fIx1,y1\fR) and (\fIx2,y2\fR) specify diagonally opposite
corners of the rectangle.  If \fIx2\fR and \fIy2\fR are not specified,
the default value is (\fIx1,y1\fR) plus the size of the source
region (after subsampling and zooming, if specified).  If \fIx2\fR and
\fIy2\fR are specified, the source region will be replicated if
necessary to fill the destination region in a tiled fashion.
.\" OPTION: -shrink
.TP
\fB\-shrink\fR
.
Specifies that the size of the destination image should be reduced, if
necessary, so that the region being copied into is at the bottom-right
corner of the image.  This option will not affect the width or height
of the image if the user has specified a non-zero value for the
\fB\-width\fR or \fB\-height\fR configuration option, respectively.
.\" OPTION: -zoom
.TP
\fB\-zoom \fIx y\fR
.
Specifies that the source region should be magnified by a factor of
\fIx\fR in the X direction and \fIy\fR in the Y direction.  If \fIy\fR
is not given, the default value is the same as \fIx\fR.  With this
option, each pixel in the source image will be expanded into a block
of \fIx\fR x \fIy\fR pixels in the destination image, all the same
color.  \fIx\fR and \fIy\fR must be greater than 0.
.\" OPTION: -subsample
.TP
\fB\-subsample \fIx y\fR
.
Specifies that the source image should be reduced in size by using
only every \fIx\fRth pixel in the X direction and \fIy\fRth pixel in
the Y direction.  Negative values will cause the image to be flipped
about the Y or X axes, respectively.  If \fIy\fR is not given, the
default value is the same as \fIx\fR.
.\" OPTION: -compositingrule
.TP
\fB\-compositingrule \fIrule\fR
.
Specifies how transparent pixels in the source image are combined with
the destination image.  When a compositing rule of \fIoverlay\fR is
set, the old contents of the destination image are visible, as if the
source image were printed on a piece of transparent film and placed
over the top of the destination.  When a compositing rule of \fIset\fR
is set, the old contents of the destination image are discarded and
the source image is used as-is.  The default compositing rule is
\fIoverlay\fR.
.RE
.\" METHOD: data
.TP
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
.
Returns image data in the form of a string.
.VS 8.7
The format of the string depends on the format handler. By default, a
human readable format as a list of lists of pixel data is used, other
formats can be chosen with the \fB\-format\fR option.
See \fBIMAGE FORMATS\fR below for details.
.VE 8.7
The following options may be specified:
.RS
.\" OPTION: -background
.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.\" OPTION: -format
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the image file format handler to use and,
optionally, arguments to the format handler.  Specifically, this
subcommand searches for the first handler whose name matches an
initial substring of \fIformat-name\fR and which has the capability to
write a string containing this image data.
.VS 8.7
If this option is not given, this subcommand uses the default format
that consists of a list (one element per row) of lists (one element
per pixel/column) of colors in
.QW \fB#\fIrrggbb\fR
format (see \fBIMAGE FORMATS\fR below).
.VE 8.7
Note that 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.
.\" OPTION: -from
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be returned.
If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region, including x1,y1
and excluding x2,y2.  The default, if this option is not given, is the
whole image.
.\" OPTION: -grayscale
.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
.\" OPTION: -metadata
.TP
\fB\-metadata\fI metadata\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
.\" METHOD: get
.TP
\fIimageName \fBget\fI x y\fR ?\fB\-withalpha\fR?
.
Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the
image as a list of three integers between 0 and 255, representing the
red, green and blue components respectively. If the \fB\-withalpha\fR
option is specified, the returned list will have a fourth element
representing the alpha value of the pixel as an integer between 0 and
255.
.\" METHOD: put
.TP
\fIimageName \fBput\fI data\fR ?\fIoption value(s) ...\fR?
.
Sets pixels in \fI imageName\fR to the data specified in \fIdata\fR.
.VS 8.7
This command searches the list of image file format handlers for
a handler that can interpret the data in \fIdata\fR, and then reads
the image encoded within into \fIimageName\fR (the destination image).
See \fBIMAGE FORMATS\fR below for details on formats for image data.
.VE 8.7
The following options may be specified:
.RS
.\" OPTION: -format
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ..\fR?}
.
Specifies the format of the image data in \fIdata\fR and, optionally,
arguments to be passed to the format handler.
Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.
Note that 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
.\" OPTION: -metadata
.TP
\fB\-metadata\fI metadata\fR
.
A specified \fImetadata\fR is passed to the image format driver when interpreting
the data.
Note that the current metadata of the image is not passed to the format driver
and is not changed by the command.
.VE 8.7
.\" OPTION: -to
.TP
\fB\-to \fIx1 y1\fR ?\fIx2 y2\fR?
.
Specifies the coordinates of the top-left corner (\fIx1\fR,\fIy1\fR)
of the region of \fIimageName\fR into which the image data will be
copied.  The default position is (0,0).  If \fIx2\fR,\fIy2\fR is given
and \fIdata\fR is not large enough to cover the rectangle specified by
this option, the image data extracted will be tiled so it covers the
entire destination rectangle. If the region specified with this option
is smaller than the supplied \fIdata\fR, the exceeding data is silently
discarded. Note that if \fIdata\fR specifies a
single color value, then a region extending to the bottom-right corner
represented by (\fIx2\fR,\fIy2\fR) will be filled with that color.
.RE
.\" METHOD: read
.TP
\fIimageName \fBread\fI filename\fR ?\fIoption value(s) ...\fR?
.
Reads image data from the file named \fIfilename\fR into the image.
This command first searches the list of
image file format handlers for a handler that can interpret the data
in \fIfilename\fR, and then reads the image in \fIfilename\fR into
\fIimageName\fR (the destination image).  The following options may be
specified:
.RS
.\" OPTION: -format
.TP
\fB\-format {\fIformat-name\fR ?\fIoption value ..\fR?}
.
Specifies the format of the image data in \fIfilename\fR and,
optionally, additional options to the format handler.
Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.
Note that 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.
.\" OPTION: -from
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the image file data to be copied
to the destination image.  If only \fIx1\fR and \fIy1\fR are
specified, the region extends from (\fIx1,y1\fR) to the bottom-right
corner of the image in the image file.  If all four coordinates are
specified, they specify diagonally opposite corners or the region.
The default, if this option is not specified, is the whole of the
image in the image file.
.VS 8.7
.\" OPTION: -metadata
.TP
\fB\-metadata\fI metadata\fR
.
A specified \fImetadata\fR is passed to the image format driver when interpreting
the data.
Note that the current metadata of the image is not passed to the format driver
and is not changed by the command.
.VE 8.7
.\" OPTION: -shrink
.TP
\fB\-shrink\fR
.
If this option, the size of \fIimageName\fR will be reduced, if
necessary, so that the region into which the image file data are read
is at the bottom-right corner of the \fIimageName\fR.  This option
will not affect the width or height of the image if the user has
specified a non-zero value for the \fB\-width\fR or \fB\-height\fR
configuration option, respectively.
.\" OPTION: -to
.TP
\fB\-to \fIx y\fR
.
Specifies the coordinates of the top-left corner of the region of
\fIimageName\fR into which data from \fIfilename\fR are to be read.
The default is (0,0).
.RE
.\" METHOD: redither
.TP
\fIimageName \fBredither\fR
.
The dithering algorithm used in displaying photo images propagates
quantization errors from one pixel to its neighbors.
If the image data for \fIimageName\fR is supplied in pieces, the
dithered image may not be exactly correct.  Normally the difference is
not noticeable, but if it is a problem, this command can be used to
recalculate the dithered image in each window where the image is
displayed.
.\" METHOD: transparency
.TP
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
.
Allows examination and manipulation of the transparency information in
the photo image.  Several subcommands are available:
.RS

.TP
\fIimageName \fBtransparency get \fIx y\fR ?\fB\-alpha\fR?
.VS 8.7
Returns true if the pixel at (\fIx\fR,\fIy\fR) is fully transparent,
false otherwise.  If the option \fB\-alpha\fR is passed, returns the
alpha value of the pixel instead, as an integer in the range 0 to 255.
.VE 8.7


.TP
\fIimageName \fBtransparency set \fIx y newVal\fR ?\fB\-alpha\fR?
.VS 8.7
Change the transparency of the pixel at (\fIx\fR,\fIy\fR) to
\fInewVal.\fR If no additional option is passed, \fInewVal\fR is
interpreted as a boolean and the pixel is made fully transparent if
that value is true, fully opaque otherwise.  If the \fB\-alpha\fR
option is passed, \fInewVal\fR is interpreted as an integral alpha
value for the pixel, which must be in the range 0 to 255.
.VE 8.7
.RE
.\" METHOD: write
.TP
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Writes image data from \fIimageName\fR to a file named \fIfilename\fR.
The following options may be specified:
.RS
.\" OPTION: -background
.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.\" OPTION: -format
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the image file format handler to be used to
write the data to the file and, optionally, options to pass to the
format handler.  Specifically, this subcommand searches for the first
handler whose name matches an initial substring of \fIformat-name\fR
and which has the capability to write an image file.  If this option
is not given, the format is guessed from the file extension. If that
cannot be determined, this subcommand uses the first handler that has
the capability to write an image file.
Note that 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.
.\" OPTION: -from
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be written to the
image file.  If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region.  The default,
if this option is not given, is the whole image.
.\" OPTION: -grayscale
.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
.\" OPTION: -metadata
.TP
\fB\-metadata\fI metadata\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
standard Tk distribution comes with handlers for PPM/PGM, PNG, GIF and
(read-only) SVG formats,
.VS 8.7
as well as the \fBdefault\fR handler to encode/decode image
data in a human readable form.
.VE 8.7
These handlers are automatically registered on initialization.
.PP
When reading an image file or processing string data specified with
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553




554
555
556
557
558
559


560
561
562
563
564
565
566
567
568
569


570
571
572
573
574


575
576
577


578
579
580
581
582
583


584


585
586
587


588
589


590


591
592


593
594


595
596
597
598
599
600
601
602
603
604
605
606
607

608
609
610
611
612
613
614
.SS "THE DEFAULT IMAGE HANDLER"
.PP
The \fBdefault\fR image handler cannot be used to read or write data
from/to a file. Its sole purpose is to encode and decode image data in
string form in a clear text, human readable, form. The \fIimageName\fR
\fBdata\fR subcommand uses this handler when no other format is
specified. When reading image data from a string with \fIimageName\fR
\fBput\fR or the \fB-data\fR option, the default handler is treated
as the other handlers.
.PP
Image data in the \fBdefault\fR string format is a (top-to-bottom)
list of scan-lines, with each scan-line being a (left-to-right) list
of pixel data. Every scan-line has the same length. The color
and, optionally, alpha value of each pixel is specified in any of
the forms described in the \fBCOLOR FORMATS\fR section below.
.VE 8.7

.SS "FORMAT SUBOPTIONS"
.PP
.VS 8.6
Image formats may support sub-options, wich ahre specified using
additional words in the value to the \fB\-format\fR option. These
suboptions can affect how image data is read or written to file or
string. The nature and values of these options is up to the format
handler.
The built-in handlers support these suboptions:

.VS 8.7
.TP
\fBdefault \-colorformat\fI formatType\fR
.
The option is allowed when writing image data to a string with
\fIimageName\fR \fBdata\fR. Specifies the format to use for the color
string of each pixel. \fIformatType\fR may be one of: \fBrgb\fR to
encode pixel data in the form \fB#\fIRRGGBB\fR, \fBrgba\fR to encode
pixel data in the form \fB#\fIRRGGBBAA\fR or \fBlist\fR to encode
pixel data as a list with four elements. See \fBCOLOR FORMATS\fR
below for details. The default is \fBrgb\fR.
.VE 8.7

.TP
\fBgif \-index\fI indexValue\fR
.
The option has effect when reading image data from a file. When
parsing a multi-part GIF image, Tk normally only accesses the first
image. By giving the \fB\-index\fR sub-option, the \fIindexValue\fR'th
value may be used instead. The \fIindexValue\fR must be an integer
from 0 up to the number of image parts in the GIF data.

.TP
\fBpng \-alpha\fI alphaValue\fR
.
The option has effect when reading image data from a file. Specifies
an additional alpha filtering for the overall image, which allows the
background on which the image is displayed to show through.  This
usually also has the effect of desaturating the image.  The
\fIalphaValue\fR must be between 0.0 and 1.0.




.TP
\fBsvg \-dpi\fI dpiValue\fB \-scale\fI scaleValue\fB \-scaletowidth \fI width\fB \-scaletoheight\fI height\fR
.
\fIdpiValue\fR is used in conversion between given coordinates and
screen resolution. The value must be greater than 0 and the default
value is 96.


\fIscaleValue\fR is used to scale the resulting image. The value must
be greater than 0 and the default value is 1.
\fIwidth\fR and \fIheight\fR are the width or height that the image
will be adjusted to. Only one parameter among \fB\-scale\fR,
\fB\-scaletowidth\fR and \fB\-scaletoheight\fR can be given at a time
and the aspect ratio of the original image is always preserved.
The svg format supports a wide range of SVG features, but the
full SVG standard is not available, for instance the 'text' feature
is missing and silently ignored when reading the SVG data.
The supported SVG features are:


.
.RS
\fB elements:\fR g, path, rect, circle, ellipse, line, polyline, polygon,
linearGradient, radialGradient, stop, defs, svg, style
.PP


\fB attributes:\fR width, height, viewBox,
preserveAspectRatio with none, xMin, xMid, xMax, yMin, yMid, yMax, slice
.PP


\fB gradient attributes:\fR gradientUnits with objectBoundingBox,
gradientTransform, cx, cy, r fx, fy x1, y1, x2, y2
spreadMethod with pad, reflect or repeat,
xlink:href
.PP
\fB poly attributes: \fR points


.PP


\fB line attributes: \fR x1, y1, x2, y2
.PP
\fB ellipse attributes: \fR cx, cy, rx, ry


.PP
\fB circle attributes: \fR cx, cy, r


.PP


\fB rectangle attributes: \fR x, y, width, height, rx, ry
.PP


\fB path attributes: \fR d with m, M, l, L, h, H, v, V, c, C, s, S, q, Q, t, T, a, A, z, Z
.PP


\fB style attributes: \fR display with none, visibility, hidden, visible,
fill with nonzero and evenodd, opacity, fill-opacity,
stroke, stroke-width, stroke-dasharray, stroke-dashoffset, stroke-opacity,
stroke-linecap with butt, round and square,
stroke-linejoin with miter, round and  bevel, stroke-miterlimit
fill-rule, font-size,
transform with matrix, translate, scale, rotate, skewX and  skewY,
stop-color, stop-opacity, offset, id, class
.RE
.
Currently only SVG images reading and conversion into (pixel-based
format) photos is supported: Tk does not (yet) support bundling photo
images in SVG vector graphics.

.VE 8.6
.VS 8.7
.SH "COLOR FORMATS"
.PP
The default image handler can represent/parse color and alpha values
of a pixel in one of the formats listed below. If a color format does
not contain transparency information, full opacity is assumed.  The







|












|





>





|






>








>








>
>
>
>

|




>
>






|



>
>

<
|

|
>
>
|

|
>
>
|



|
|
>
>
|
>
>
|
|
|
>
>
|
|
>
>
|
>
>
|
|
>
>
|
|
>
>
|








|



>







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
.SS "THE DEFAULT IMAGE HANDLER"
.PP
The \fBdefault\fR image handler cannot be used to read or write data
from/to a file. Its sole purpose is to encode and decode image data in
string form in a clear text, human readable, form. The \fIimageName\fR
\fBdata\fR subcommand uses this handler when no other format is
specified. When reading image data from a string with \fIimageName\fR
\fBput\fR or the \fB\-data\fR option, the default handler is treated
as the other handlers.
.PP
Image data in the \fBdefault\fR string format is a (top-to-bottom)
list of scan-lines, with each scan-line being a (left-to-right) list
of pixel data. Every scan-line has the same length. The color
and, optionally, alpha value of each pixel is specified in any of
the forms described in the \fBCOLOR FORMATS\fR section below.
.VE 8.7

.SS "FORMAT SUBOPTIONS"
.PP
.VS 8.6
Image formats may support sub-options, which are specified using
additional words in the value to the \fB\-format\fR option. These
suboptions can affect how image data is read or written to file or
string. The nature and values of these options is up to the format
handler.
The built-in handlers support these suboptions:
.\" OPTION -colorformat
.VS 8.7
.TP
\fBdefault \-colorformat\fI formatType\fR
.
The option is allowed when writing image data to a string with
\fIimageName \fBdata\fR. Specifies the format to use for the color
string of each pixel. \fIformatType\fR may be one of: \fBrgb\fR to
encode pixel data in the form \fB#\fIRRGGBB\fR, \fBrgba\fR to encode
pixel data in the form \fB#\fIRRGGBBAA\fR or \fBlist\fR to encode
pixel data as a list with four elements. See \fBCOLOR FORMATS\fR
below for details. The default is \fBrgb\fR.
.VE 8.7
.\" OPTION -index
.TP
\fBgif \-index\fI indexValue\fR
.
The option has effect when reading image data from a file. When
parsing a multi-part GIF image, Tk normally only accesses the first
image. By giving the \fB\-index\fR sub-option, the \fIindexValue\fR'th
value may be used instead. The \fIindexValue\fR must be an integer
from 0 up to the number of image parts in the GIF data.
.\" OPTION -alpha
.TP
\fBpng \-alpha\fI alphaValue\fR
.
The option has effect when reading image data from a file. Specifies
an additional alpha filtering for the overall image, which allows the
background on which the image is displayed to show through.  This
usually also has the effect of desaturating the image.  The
\fIalphaValue\fR must be between 0.0 and 1.0.
.\" OPTION -dpi
.\" OPTION -scale
.\" OPTION -scaletowidth
.\" OPTION -scaletoheight
.TP
\fBsvg \-dpi\fI dpiValue \fB\-scale\fI scaleValue \fB\-scaletowidth\fI width \fB\-scaletoheight\fI height\fR
.
\fIdpiValue\fR is used in conversion between given coordinates and
screen resolution. The value must be greater than 0 and the default
value is 96.
.RS
.PP
\fIscaleValue\fR is used to scale the resulting image. The value must
be greater than 0 and the default value is 1.
\fIwidth\fR and \fIheight\fR are the width or height that the image
will be adjusted to. Only one parameter among \fB\-scale\fR,
\fB\-scaletowidth\fR and \fB\-scaletoheight\fR can be given at a time
and the aspect ratio of the original image is always preserved.
The \fBsvg\fR format supports a wide range of SVG features, but the
full SVG standard is not available, for instance the 'text' feature
is missing and silently ignored when reading the SVG data.
The supported SVG features are:
.TP
\fBelements:\fR
.

g, path, rect, circle, ellipse, line, polyline, polygon,
linearGradient, radialGradient, stop, defs, svg, style
.TP
\fBattributes:\fR
.
width, height, viewBox,
preserveAspectRatio with none, xMin, xMid, xMax, yMin, yMid, yMax, slice
.TP
\fBgradient attributes:\fR
.
gradientUnits with objectBoundingBox,
gradientTransform, cx, cy, r fx, fy x1, y1, x2, y2
spreadMethod with pad, reflect or repeat,
xlink:href
.TP
\fBpoly attributes:\fR
.
points
.TP
\fBline attributes:\fR
.
x1, y1, x2, y2
.TP
\fBellipse attributes:\fR
.
cx, cy, rx, ry
.TP
\fBcircle attributes:\fR
.
cx, cy, r
.TP
\fBrectangle attributes:\fR
.
x, y, width, height, rx, ry
.TP
\fBpath attributes:\fR
.
d with m, M, l, L, h, H, v, V, c, C, s, S, q, Q, t, T, a, A, z, Z
.TP
\fBstyle attributes:\fR
.
display with none, visibility, hidden, visible,
fill with nonzero and evenodd, opacity, fill-opacity,
stroke, stroke-width, stroke-dasharray, stroke-dashoffset, stroke-opacity,
stroke-linecap with butt, round and square,
stroke-linejoin with miter, round and  bevel, stroke-miterlimit
fill-rule, font-size,
transform with matrix, translate, scale, rotate, skewX and  skewY,
stop-color, stop-opacity, offset, id, class
.RE
.PP
Currently only SVG images reading and conversion into (pixel-based
format) photos is supported: Tk does not (yet) support bundling photo
images in SVG vector graphics.
.RE
.VE 8.6
.VS 8.7
.SH "COLOR FORMATS"
.PP
The default image handler can represent/parse color and alpha values
of a pixel in one of the formats listed below. If a color format does
not contain transparency information, full opacity is assumed.  The
678
679
680
681
682
683
684






















































685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
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.






















































.SH CREDITS
.PP
The photo image type was designed and implemented by Paul Mackerras,
based on his earlier photo widget and some suggestions from
John Ousterhout.
.SH EXAMPLE
.PP
Load an image from a file and tile it to the size of a window, which
is useful for producing a tiled background:
.PP
.CS
# These lines should be called once
\fBimage create photo\fR untiled \-file "theFile.ppm"
\fBimage create photo\fR tiled

# These lines should be called whenever .someWidget changes
# size; a <Configure> binding is useful here
set width  [winfo width .someWidget]
set height [winfo height .someWidget]
tiled \fBcopy\fR untiled \-to 0 0 $width $height \-shrink
.CE
.PP
.VS 8.6
The PNG image loader allows the application of an additional alpha factor
during loading, which is useful for generating images suitable for disabled
buttons:
.PP
.CS
\fBimage create photo\fR icon \-file "icon.png"
\fBimage create photo\fR iconDisabled \-file "icon.png" \e
        \-format "png \-alpha 0.5"
button .b \-image icon \-disabledimage iconDisabled
.CE
.VE 8.6
.PP
.VS 8.7
Create a green box with a simple shadow effect
.PP
.CS







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|






|








|
|
|
|







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
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 (MULTIPLE FORMATS)"
.PP
Each image format driver supports an individual set of metadata dictionary
keys. Predefined keys are:
.IP \fBDPI\fR
Horizontal image resolution in DPI as a double value.
Supported by format \fBpng\fR.
.IP \fBaspect\fR
Aspect ratio horizontal divided by vertical as double value.
Supported by formats \fBgif\fR and \fBpng\fR.
.IP \fBcomment\fR
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 that it does not handle.
.SS "METADATA KEYS FOR ANIMATED GIF INFORMATION"
.PP
The following metadata keys are reported when reading a \fBgif\fR format file.
They are typically used in conjunction with the \fB\-index\fR option of an
animated \fBgif\fR file to properly display the subimage sequence.
The options are linked to each subimage selected by \fB\-index\fR.
.TP
\fBdelay time\fI time\fR
.
Update delay time in 10ms units.
This key is only present if the delay time is not 0.
.TP
\fBdisposal method\fI method\fR
.
Disposal method of the preceeding image, if given for the current image.
Possible values are: \fBdo not dispose\fR, \fBrestore to background color\fR,
\fBrestore to previous\fR.
.TP
\fBuser interaction\fI bool\fR
.
The key is present with a value of 1, if user interaction is specified.
Otherwise, the key is not present.
.TP
\fBupdate region\fI X0\fR, \fIY0\fR, \fIwidth\fR, \fIheight\fR
.
Update region of the current subimage, if subimage has not the same size as
the full image. The pixel outside of this box are all fully transparent.
.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
Load an image from a file and tile it to the size of a window, which
is useful for producing a tiled background:
.PP
.CS
# These lines should be called once
\fBimage create photo\fR untiled -file "theFile.ppm"
\fBimage create photo\fR tiled

# These lines should be called whenever .someWidget changes
# size; a <Configure> binding is useful here
set width  [winfo width .someWidget]
set height [winfo height .someWidget]
tiled \fBcopy\fR untiled -to 0 0 $width $height -shrink
.CE
.PP
.VS 8.6
The PNG image loader allows the application of an additional alpha factor
during loading, which is useful for generating images suitable for disabled
buttons:
.PP
.CS
\fBimage create photo\fR icon -file "icon.png"
\fBimage create photo\fR iconDisabled -file "icon.png" \e
        -format "png -alpha 0.5"
button .b -image icon -disabledimage iconDisabled
.CE
.VE 8.6
.PP
.VS 8.7
Create a green box with a simple shadow effect
.PP
.CS

Changes to doc/place.n.

26
27
28
29
30
31
32

33
34
35
36
37

38
39

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

53
54

55
56
57
58
59
60
61
62
63

64
65

66
67
68
69
70
71
72
in response to changes in the size of the container.
Lastly, the placer allows you to mix these styles of placement so
that, for example, the content has a fixed width and height but is
centered inside the container.
.PP
.TP
\fBplace \fIwindow option value \fR?\fIoption value ...\fR?

Arrange for the placer to manage the geometry of a content whose
pathName is \fIwindow\fR.  The remaining arguments consist of one or
more \fIoption\-value\fR pairs that specify the way in which
\fIwindow\fR's geometry is managed.  \fIOption\fR may have any of the
values accepted by the \fBplace configure\fR command.

.TP
\fBplace configure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the geometry options of the content given by
\fIwindow\fR.  If no \fIoption\fR is specified, this command returns a
list describing the available options (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s); in this case
the command returns an empty string.
.RS
.PP
The following \fIoption\-value\fR pairs are supported:

.TP
\fB\-anchor \fIwhere\fR

\fIWhere\fR specifies which point of \fIwindow\fR is to be positioned
at the (x,y) location selected by the \fB\-x\fR, \fB\-y\fR,
\fB\-relx\fR, and \fB\-rely\fR options.
The anchor point is in terms of the outer area of \fIwindow\fR
including its border, if any.
Thus if \fIwhere\fR is \fBse\fR then the lower-right corner of
\fIwindow\fR's border will appear at the given (x,y) location
in the container.
The anchor position defaults to \fBnw\fR.

.TP
\fB\-bordermode \fImode\fR

\fIMode\fR determines the degree to which borders within the
container are used in determining the placement of the content.
The default and most common value is \fBinside\fR.
In this case the placer considers the area of the container to
be the innermost area of the container, inside any border:
an option of \fB\-x 0\fR corresponds to an x-coordinate just
inside the border and an option of \fB\-relwidth 1.0\fR







>





>


>













>


>









>


>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
in response to changes in the size of the container.
Lastly, the placer allows you to mix these styles of placement so
that, for example, the content has a fixed width and height but is
centered inside the container.
.PP
.TP
\fBplace \fIwindow option value \fR?\fIoption value ...\fR?
.
Arrange for the placer to manage the geometry of a content whose
pathName is \fIwindow\fR.  The remaining arguments consist of one or
more \fIoption\-value\fR pairs that specify the way in which
\fIwindow\fR's geometry is managed.  \fIOption\fR may have any of the
values accepted by the \fBplace configure\fR command.
.\" METHOD: configure
.TP
\fBplace configure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the geometry options of the content given by
\fIwindow\fR.  If no \fIoption\fR is specified, this command returns a
list describing the available options (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given option(s) to have the given value(s); in this case
the command returns an empty string.
.RS
.PP
The following \fIoption\-value\fR pairs are supported:
.\" OPTION: -anchor
.TP
\fB\-anchor \fIwhere\fR
.
\fIWhere\fR specifies which point of \fIwindow\fR is to be positioned
at the (x,y) location selected by the \fB\-x\fR, \fB\-y\fR,
\fB\-relx\fR, and \fB\-rely\fR options.
The anchor point is in terms of the outer area of \fIwindow\fR
including its border, if any.
Thus if \fIwhere\fR is \fBse\fR then the lower-right corner of
\fIwindow\fR's border will appear at the given (x,y) location
in the container.
The anchor position defaults to \fBnw\fR.
.\" OPTION: -bordermode
.TP
\fB\-bordermode \fImode\fR
.
\fIMode\fR determines the degree to which borders within the
container are used in determining the placement of the content.
The default and most common value is \fBinside\fR.
In this case the placer considers the area of the container to
be the innermost area of the container, inside any border:
an option of \fB\-x 0\fR corresponds to an x-coordinate just
inside the border and an option of \fB\-relwidth 1.0\fR
80
81
82
83
84
85
86

87
88

89
90
91
92
93
94
95

96
97

98
99
100
101
102
103
104
105
106
107

108
109

110
111
112
113
114
115
116
117

118
119

120
121
122
123
124
125
126
127

128
129

130
131
132
133
134
135
136
137
138
139

140
141

142
143
144
145
146
147
148
149
150
151

152
153

154
155
156
157
158
159
160

161
162

163
164
165
166
167

168
169

170
171
172
173
174
175
176
177
178
179

180







181

182
183
184
185
186

187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
outside its container, as with the options \fB\-x 0 \-y 0 \-anchor ne\fR.
Lastly, \fImode\fR may be specified as \fBignore\fR, in which
case borders are ignored:  the area of the container is considered
to be its official X area, which includes any internal border but
no external border.  A bordermode of \fBignore\fR is probably
not very useful.
.RE

.TP
\fB\-height \fIsize\fR

\fISize\fR specifies the height for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The height will be the outer dimension of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-height\fR or
\fB\-relheight\fR option is specified, then the height requested
internally by the window will be used.

.TP
\fB\-in \fIcontainer\fR

\fIContainer\fR specifies the path name of the window relative
to which \fIwindow\fR is to be placed.
\fIContainer\fR must either be \fIwindow\fR's parent or a descendant
of \fIwindow\fR's parent.
In addition, \fIcontainer\fR and \fIwindow\fR must both be descendants
of the same top-level window.
These restrictions are necessary to guarantee
that \fIwindow\fR is visible whenever \fIcontainer\fR is visible.
If this option is not specified then the other window defaults to
\fIwindow\fR's parent.

.TP
\fB\-relheight \fIsize\fR

\fISize\fR specifies the height for \fIwindow\fR.
In this case the height is specified as a floating-point number
relative to the height of the container: 0.5 means \fIwindow\fR will
be half as high as the container, 1.0 means \fIwindow\fR will have
the same height as the container, and so on.
If both \fB\-height\fR and \fB\-relheight\fR are specified for a content,
their values are summed.  For example, \fB\-relheight 1.0 \-height \-2\fR
makes the content 2 pixels shorter than the container.

.TP
\fB\-relwidth \fIsize\fR

\fISize\fR specifies the width for \fIwindow\fR.
In this case the width is specified as a floating-point number
relative to the width of the container: 0.5 means \fIwindow\fR will
be half as wide as the container, 1.0 means \fIwindow\fR will have
the same width as the container, and so on.
If both \fB\-width\fR and \fB\-relwidth\fR are specified for a content,
their values are summed.  For example, \fB\-relwidth 1.0 \-width 5\fR
makes the content 5 pixels wider than the container.

.TP
\fB\-relx \fIlocation\fR

\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the location is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the left edge
of the container and 1.0 corresponds to the right edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-x\fR and \fB\-relx\fR are specified for a content
then their values are summed.  For example, \fB\-relx 0.5 \-x \-2\fR
positions the left edge of the content 2 pixels to the left of the
center of its container.

.TP
\fB\-rely \fIlocation\fR

\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the value is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the top edge
of the container and 1.0 corresponds to the bottom edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-y\fR and \fB\-rely\fR are specified for a content
then their values are summed.  For example, \fB\-rely 0.5 \-x 3\fR
positions the top edge of the content 3 pixels below the
center of its container.

.TP
\fB\-width \fIsize\fR

\fISize\fR specifies the width for \fIwindow\fR in screen units
(i.e. any of the forms accepted by \fBTk_GetPixels\fR).
The width will be the outer width of \fIwindow\fR including its
border, if any.
If \fIsize\fR is an empty string, or if no \fB\-width\fR
or \fB\-relwidth\fR option is specified, then the width requested
internally by the window will be used.

.TP
\fB\-x \fIlocation\fR

\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the container window.

.TP
\fB\-y \fIlocation\fR

\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the container window.
.PP
If the same value is specified separately with
two different options, such as \fB\-x\fR and \fB\-relx\fR, then
the most recent option is used and the older one is ignored.
.RE

.TP







\fBplace forget \fIwindow\fR

Causes the placer to stop managing the geometry of \fIwindow\fR.  As a
side effect of this command \fIwindow\fR will be unmapped so that it
does not appear on the screen.  If \fIwindow\fR is not currently managed
by the placer then the command has no effect.  This command returns an
empty string.

.TP
\fBplace info \fIwindow\fR

Returns a list giving the current configuration of \fIwindow\fR.
The list consists of \fIoption\-value\fR pairs in exactly the
same form as might be specified to the \fBplace configure\fR
command.
.TP
\fBplace content \fIwindow\fR
Returns a list of all the content windows for which \fIwindow\fR is the container.
If there is no content for \fIwindow\fR then an empty string is returned.
.TP
\fBplace slaves \fIwindow\fR
.
Synonym for . \fBplace content \fIwindow\fR
.PP
If the configuration of a window has been retrieved with
\fBplace info\fR, that configuration can be restored later by
first using \fBplace forget\fR to erase any existing information
for the window and then invoking \fBplace configure\fR with
the saved information.
.SH "FINE POINTS"







>


>







>


>










>


>








>


>








>


>










>


>










>


>







>


>





>


>










>

>
>
>
>
>
>
>

>





>


>




|
<
<
<



|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229



230
231
232
233
234
235
236
237
238
239
240
outside its container, as with the options \fB\-x 0 \-y 0 \-anchor ne\fR.
Lastly, \fImode\fR may be specified as \fBignore\fR, in which
case borders are ignored:  the area of the container is considered
to be its official X area, which includes any internal border but
no external border.  A bordermode of \fBignore\fR is probably
not very useful.
.RE
.\" OPTION: -height
.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.
.\" OPTION: -in
.TP
\fB\-in \fIcontainer\fR
.
\fIContainer\fR specifies the path name of the window relative
to which \fIwindow\fR is to be placed.
\fIContainer\fR must either be \fIwindow\fR's parent or a descendant
of \fIwindow\fR's parent.
In addition, \fIcontainer\fR and \fIwindow\fR must both be descendants
of the same top-level window.
These restrictions are necessary to guarantee
that \fIwindow\fR is visible whenever \fIcontainer\fR is visible.
If this option is not specified then the other window defaults to
\fIwindow\fR's parent.
.\" OPTION: -relheight
.TP
\fB\-relheight \fIsize\fR
.
\fISize\fR specifies the height for \fIwindow\fR.
In this case the height is specified as a floating-point number
relative to the height of the container: 0.5 means \fIwindow\fR will
be half as high as the container, 1.0 means \fIwindow\fR will have
the same height as the container, and so on.
If both \fB\-height\fR and \fB\-relheight\fR are specified for a content,
their values are summed.  For example, \fB\-relheight 1.0 \-height \-2\fR
makes the content 2 pixels shorter than the container.
.\" OPTION: -relwidth
.TP
\fB\-relwidth \fIsize\fR
.
\fISize\fR specifies the width for \fIwindow\fR.
In this case the width is specified as a floating-point number
relative to the width of the container: 0.5 means \fIwindow\fR will
be half as wide as the container, 1.0 means \fIwindow\fR will have
the same width as the container, and so on.
If both \fB\-width\fR and \fB\-relwidth\fR are specified for a content,
their values are summed.  For example, \fB\-relwidth 1.0 \-width 5\fR
makes the content 5 pixels wider than the container.
.\" OPTION: -relx
.TP
\fB\-relx \fIlocation\fR
.
\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the location is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the left edge
of the container and 1.0 corresponds to the right edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-x\fR and \fB\-relx\fR are specified for a content
then their values are summed.  For example, \fB\-relx 0.5 \-x \-2\fR
positions the left edge of the content 2 pixels to the left of the
center of its container.
.\" OPTION: -rely
.TP
\fB\-rely \fIlocation\fR
.
\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
In this case the value is specified in a relative fashion
as a floating-point number:  0.0 corresponds to the top edge
of the container and 1.0 corresponds to the bottom edge of the container.
\fILocation\fR need not be in the range 0.0\-1.0.
If both \fB\-y\fR and \fB\-rely\fR are specified for a content
then their values are summed.  For example, \fB\-rely 0.5 \-x 3\fR
positions the top edge of the content 3 pixels below the
center of its container.
.\" OPTION: -width
.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.
.\" OPTION: -x
.TP
\fB\-x \fIlocation\fR
.
\fILocation\fR specifies the x-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the container window.
.\" OPTION: -y
.TP
\fB\-y \fIlocation\fR
.
\fILocation\fR specifies the y-coordinate within the container window
of the anchor point for \fIwindow\fR.
The location is specified in screen units (i.e. any of the forms
accepted by \fBTk_GetPixels\fR) and need not lie within the bounds
of the container window.
.PP
If the same value is specified separately with
two different options, such as \fB\-x\fR and \fB\-relx\fR, then
the most recent option is used and the older one is ignored.
.RE
.\" METHOD: content
.TP
\fBplace content \fIwindow\fR
.
Returns a list of all the content windows for which \fIwindow\fR is the
container. If there is no content for \fIwindow\fR then an empty string
is returned.
.\" METHOD: forget
.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.
.\" METHOD: info
.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.
.\" METHOD: slaves



.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"
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
To control the sizes of these windows, make them windows like
frames and canvases that provide configuration options for this purpose.
.SH EXAMPLE
.PP
Make the label occupy the middle bit of the toplevel, no matter how it
is resized:
.CS
label .l \-text "In the\enMiddle!" \-bg black \-fg white
\fBplace\fR .l \-relwidth .3 \-relx .35 \-relheight .3 \-rely .35
.CE
.SH "SEE ALSO"
grid(n), pack(n)
.SH KEYWORDS
geometry manager, height, location, container, place, rubber sheet, content, width

'\" Local Variables:
'\" mode: nroff
'\" End:







|
|




|
>



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
To control the sizes of these windows, make them windows like
frames and canvases that provide configuration options for this purpose.
.SH EXAMPLE
.PP
Make the label occupy the middle bit of the toplevel, no matter how it
is resized:
.CS
label .l -text "In the\enMiddle!" -bg black -fg white
\fBplace\fR .l -relwidth .3 -relx .35 -relheight .3 -rely .35
.CE
.SH "SEE ALSO"
grid(n), pack(n)
.SH KEYWORDS
geometry manager, height, location, container, place, rubber sheet,
content, width
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/popup.n.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
the given point.
.SH EXAMPLE
.PP
How to attach a simple popup menu to a widget.
.CS
# Create a menu
set m [menu .popupMenu]
$m add command \-label "Example 1" \-command bell
$m add command \-label "Example 2" \-command bell

# Create something to attach it to
pack [label .l \-text "Click me!"]

# Arrange for the menu to pop up when the label is clicked
bind .l <Button-1> {\fBtk_popup\fR .popupMenu %X %Y}
.CE
.SH "SEE ALSO"
bind(n), menu(n), tk_optionMenu(n)
.SH KEYWORDS







|
|


|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
the given point.
.SH EXAMPLE
.PP
How to attach a simple popup menu to a widget.
.CS
# Create a menu
set m [menu .popupMenu]
$m add command -label "Example 1" -command bell
$m add command -label "Example 2" -command bell

# Create something to attach it to
pack [label .l -text "Click me!"]

# Arrange for the menu to pop up when the label is clicked
bind .l <Button-1> {\fBtk_popup\fR .popupMenu %X %Y}
.CE
.SH "SEE ALSO"
bind(n), menu(n), tk_optionMenu(n)
.SH KEYWORDS

Added doc/print.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
.\" Text automatically generated by txt2man
'\"
'\" Copyright (c) 2021 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 print n "" Tk "Tk Built-in Commands"
.so man.macros
.SH NAME
print \- Print canvas and text widgets using native dialogs and APIs.
.SH SYNOPSIS
\fBtk print \fIwindow\fR
.
.SH DESCRIPTION
.PP
The \fBtk print\fR command posts a dialog that allows users to print output
from the \fBcanvas\fR and \fBtext\fR widgets. The printing will be done using
platform-native APIs and dialogs where available.
.PP
The \fBcanvas\fR widget has long supported PostScript export and both
PostScript and text files can be sent directly to a printer on Unix-like
systems using the
.QW "lp"
and
.QW "lpr"
Unix commands, and the \fBtk print\fR command does not supersede that
functionality; it builds on it. The \fBtk print\fR command is a fuller
implementation that uses native dialogs on macOS and Windows, and a Tk-based
dialog that provides parallel functionality on X11.
.SH PLATFORM NOTES
.TP
\fBmacOS\fR
.
The Mac implementation uses native print dialogs and relies on the underlying
Common Unix Printing System (CUPS) to render text output from the text widget
and PDF conversion of the canvas data to the printer or to a PDF file.
.TP
\fBWindows\fR
.
The Windows implementation is based on the GDI (Graphics Device Interface)
API. Because there are slight differences in how GDI and Tk's \fBcanvas\fR
widget display graphics, printed output from the \fBcanvas\fR on Windows may
not be identical to screen rendering.
.TP
\fBX11\fR
.
The X11 implementation uses a Tk GUI to configure print jobs for sending to a
printer via the
.QW "lpr"
or
.QW "lp"
commands. While these commands have a large number of parameters for
configuring print jobs, printers vary widely in how they support these
parameters. As a result, only printer selection and number of copies are
configured as arguments to the print command; many aspects of print rendering,
such as grayscale or color for the canvas, are instead configured when
PostScript is generated.
.SH "SEE ALSO"
canvas(n), text(n), tk(n)
.SH KEYWORDS
print, output, graphics, text, canvas

Changes to doc/radiobutton.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH radiobutton n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
radiobutton \- Create and manipulate 'radiobutton' pick-one widgets
.SH SYNOPSIS
\fBradiobutton\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH radiobutton n 4.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
radiobutton \- Create and manipulate 'radiobutton' pick-one widgets
.SH SYNOPSIS
\fBradiobutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the radiobutton.
The empty string is the default value.
.OP \-selectcolor selectColor Background
Specifies a background color to use when the button is selected.
If \fBindicatorOn\fR is true then the color is used as the background for
the indicator regardless of the select state.
If \fB\-indicatoron\fR is false, this color is used as the background
for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fB\-image\fR option)
when the radiobutton is selected.
This option is ignored unless the \fB\-image\fR option has been







|
|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the radiobutton.
The empty string is the default value.
.OP \-selectcolor selectColor Background
Specifies a background color to use when the button is selected.
If \fBindicatorOn\fR is true then the color is used as the background for
the indicator regardless of the select state.
If \fB\-indicatoron\fR is false, this color is used as the background for the
entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fB\-image\fR option)
when the radiobutton is selected.
This option is ignored unless the \fB\-image\fR option has been
177
178
179
180
181
182
183

184
185
186
187
188
189
190

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

206
207
208
209
210
211
212

213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.

.TP
\fIpathName \fBdeselect\fR
.
Deselects the radiobutton and sets the associated variable to an
empty string.
If this radiobutton was not currently selected, the command has
no effect.

.TP
\fIpathName \fBflash\fR
.
Flashes the radiobutton.  This is accomplished by redisplaying the radiobutton
several times, alternating between active and normal colors.  At
the end of the flash the radiobutton is left in the same normal/active
state as when the command was invoked.
This command is ignored if the radiobutton's state is \fBdisabled\fR.

.TP
\fIpathName \fBinvoke\fR
.
Does just what would have happened if the user invoked the radiobutton
with the mouse: selects the button and invokes
its associated Tcl command, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the radiobutton.
This command is ignored if the radiobutton's state is \fBdisabled\fR.

.TP
\fIpathName \fBselect\fR
.
Selects the radiobutton and sets the associated variable to the
value corresponding to this widget.
.SH BINDINGS
.PP







>

|





>















>







>








>









>







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBradiobutton\fR
command.
.\" METHOD: deselect
.TP
\fIpathName \fBdeselect\fR
.
Deselects the radiobutton and sets the associated variable to an
empty string.
If this radiobutton was not currently selected, the command has
no effect.
.\" METHOD: flash
.TP
\fIpathName \fBflash\fR
.
Flashes the radiobutton.  This is accomplished by redisplaying the radiobutton
several times, alternating between active and normal colors.  At
the end of the flash the radiobutton is left in the same normal/active
state as when the command was invoked.
This command is ignored if the radiobutton's state is \fBdisabled\fR.
.\" METHOD: invoke
.TP
\fIpathName \fBinvoke\fR
.
Does just what would have happened if the user invoked the radiobutton
with the mouse: selects the button and invokes
its associated Tcl command, if there is one.
The return value is the return value from the Tcl command, or an
empty string if there is no command associated with the radiobutton.
This command is ignored if the radiobutton's state is \fBdisabled\fR.
.\" METHOD: select
.TP
\fIpathName \fBselect\fR
.
Selects the radiobutton and sets the associated variable to the
value corresponding to this widget.
.SH BINDINGS
.PP
253
254
255
256
257
258
259
260

261
262
263
264
265
.PP
If the radiobutton's state is \fBdisabled\fR then none of the above
actions occur:  the radiobutton is completely non-responsive.
.PP
The behavior of radiobuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
checkbutton(n), labelframe(n), listbox(n), options(n), scale(n), ttk::radiobutton(n)

.SH KEYWORDS
radiobutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|
>





259
260
261
262
263
264
265
266
267
268
269
270
271
272
.PP
If the radiobutton's state is \fBdisabled\fR then none of the above
actions occur:  the radiobutton is completely non-responsive.
.PP
The behavior of radiobuttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "SEE ALSO"
checkbutton(n), labelframe(n), listbox(n), options(n), scale(n),
ttk::radiobutton(n)
.SH KEYWORDS
radiobutton, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/raise.n.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.SH EXAMPLE
.PP
Make a button appear to be in a sibling frame that was created after
it. This is is often necessary when building GUIs in the style where
you create your activity widgets first before laying them out on the
display:
.CS
button .b \-text "Hi there!"
pack [frame .f \-background blue]
pack [label .f.l1 \-text "This is above"]
pack .b \-in .f
pack [label .f.l2 \-text "This is below"]
\fBraise\fR .b
.CE
.SH "SEE ALSO"
lower(n)
.SH KEYWORDS
obscure, raise, stacking order
'\" Local Variables:







|
|
|
|
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.SH EXAMPLE
.PP
Make a button appear to be in a sibling frame that was created after
it. This is is often necessary when building GUIs in the style where
you create your activity widgets first before laying them out on the
display:
.CS
button .b -text "Hi there!"
pack [frame .f -background blue]
pack [label .f.l1 -text "This is above"]
pack .b -in .f
pack [label .f.l2 -text "This is below"]
\fBraise\fR .b
.CE
.SH "SEE ALSO"
lower(n)
.SH KEYWORDS
obscure, raise, stacking order
'\" Local Variables:

Changes to doc/scale.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH scale n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scale \- Create and manipulate 'scale' value-controlled slider widgets
.SH SYNOPSIS
\fBscale\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-foreground	\-relief
\-background	\-highlightbackground	\-repeatdelay
\-borderwidth	\-highlightcolor	\-repeatinterval
\-cursor	\-highlightthickness	\-takefocus
\-font	\-orient	\-troughcolor
.SE







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH scale n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scale \- Create and manipulate 'scale' value-controlled slider widgets
.SH SYNOPSIS
\fBscale\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-foreground	\-relief
\-background	\-highlightbackground	\-repeatdelay
\-borderwidth	\-highlightcolor	\-repeatinterval
\-cursor	\-highlightthickness	\-takefocus
\-font	\-orient	\-troughcolor
.SE
74
75
76
77
78
79
80
81


82
83
84
85
86
87
88
If the scale is disabled then the value may not be changed and the scale
will not activate.
If the scale is active, the slider is displayed using the color
specified by the \fB\-activebackground\fR option.
.OP \-tickinterval tickInterval TickInterval
Must be a real value.
Determines the spacing between numerical
tick marks displayed below or to the left of the slider. The values will all be displayed with the same number of decimal places, which will be enough to ensure they are all accurate to within 20% of a tick interval.


If 0, no tick marks will be displayed.
.OP \-to to To
Specifies a real value corresponding
to the right or bottom end of the scale.
This value may be either less than or greater than the \fB\-from\fR option.
.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale.  Whenever the







|
>
>







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
If the scale is disabled then the value may not be changed and the scale
will not activate.
If the scale is active, the slider is displayed using the color
specified by the \fB\-activebackground\fR option.
.OP \-tickinterval tickInterval TickInterval
Must be a real value.
Determines the spacing between numerical
tick marks displayed below or to the left of the slider. The values will all
be displayed with the same number of decimal places, which will be enough to
ensure they are all accurate to within 20% of a tick interval.
If 0, no tick marks will be displayed.
.OP \-to to To
Specifies a real value corresponding
to the right or bottom end of the scale.
This value may be either less than or greater than the \fB\-from\fR option.
.OP \-variable variable Variable
Specifies the name of a global variable to link to the scale.  Whenever the
139
140
141
142
143
144
145

146
147
148
149
150
151
152

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

168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183

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

196
197
198
199
200
201
202
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:

.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.

.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Returns a list whose elements are the x and y coordinates of
the point along the centerline of the trough that corresponds
to \fIvalue\fR.
If \fIvalue\fR is omitted then the scale's current value is used.

.TP
\fIpathName \fBget\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are omitted, returns the current value
of the scale.  If \fIx\fR and \fIy\fR are specified, they give
pixel coordinates within the widget;  the command returns
the scale value corresponding to the given pixel.
Only one of \fIx\fR or \fIy\fR is used:  for horizontal scales
\fIy\fR is ignored, and for vertical scales \fIx\fR is ignored.

.TP
\fIpathName \fBidentify \fIx y\fR
.
Returns a string indicating what part of the scale lies under
the coordinates given by \fIx\fR and \fIy\fR.
A return value of \fBslider\fR means that the point is over
the slider;  \fBtrough1\fR means that the point is over the
portion of the slider above  or to the left of the slider;
and \fBtrough2\fR means that the point is over the portion
of the slider below or to the right of the slider.
If the point is not over one of these elements, an empty string
is returned.

.TP
\fIpathName \fBset \fIvalue\fR
.
This command is invoked to change the current value of the scale,
and hence the position at which the slider is displayed.  \fIValue\fR
gives the new value for the scale.
The command has no effect if the scale is disabled.







>

|





>















>







>









>












>







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscale\fR
command.
.\" METHOD: coords
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Returns a list whose elements are the x and y coordinates of
the point along the centerline of the trough that corresponds
to \fIvalue\fR.
If \fIvalue\fR is omitted then the scale's current value is used.
.\" METHOD: get
.TP
\fIpathName \fBget\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are omitted, returns the current value
of the scale.  If \fIx\fR and \fIy\fR are specified, they give
pixel coordinates within the widget;  the command returns
the scale value corresponding to the given pixel.
Only one of \fIx\fR or \fIy\fR is used:  for horizontal scales
\fIy\fR is ignored, and for vertical scales \fIx\fR is ignored.
.\" METHOD: identify
.TP
\fIpathName \fBidentify \fIx y\fR
.
Returns a string indicating what part of the scale lies under
the coordinates given by \fIx\fR and \fIy\fR.
A return value of \fBslider\fR means that the point is over
the slider;  \fBtrough1\fR means that the point is over the
portion of the slider above  or to the left of the slider;
and \fBtrough2\fR means that the point is over the portion
of the slider below or to the right of the slider.
If the point is not over one of these elements, an empty string
is returned.
.\" METHOD: set
.TP
\fIpathName \fBset \fIvalue\fR
.
This command is invoked to change the current value of the scale,
and hence the position at which the slider is displayed.  \fIValue\fR
gives the new value for the scale.
The command has no effect if the scale is disabled.

Changes to doc/scrollbar.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH scrollbar n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scrollbar \- Create and manipulate 'scrollbar' scrolling control and indicator widgets
.SH SYNOPSIS
\fBscrollbar\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightcolor	\-repeatdelay
\-background	\-highlightthickness	\-repeatinterval
\-borderwidth	\-jump	\-takefocus
\-cursor	\-orient	\-troughcolor
\-highlightbackground	\-relief
.SE







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH scrollbar n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scrollbar \- Create and manipulate 'scrollbar' scrolling control and indicator widgets
.SH SYNOPSIS
\fBscrollbar\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightcolor	\-repeatdelay
\-background	\-highlightthickness	\-repeatinterval
\-borderwidth	\-jump	\-takefocus
\-cursor	\-orient	\-troughcolor
\-highlightbackground	\-relief
.SE
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

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

124
125
126
127
128
129
130

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

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

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

170
171
172
173
174

175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
Scrollbars can be used to adjust the view in the associated window
by clicking or dragging with the mouse.  See the \fBBINDINGS\fR section
below for details.
.SH "ELEMENTS"
.PP
A scrollbar displays five elements, which are referred to in the
widget commands for the scrollbar:
.TP 10
\fBarrow1\fR
The top or left arrow in the scrollbar.
.TP 10
\fBtrough1\fR
The region between the slider and \fBarrow1\fR.
.TP 10
\fBslider\fR
The rectangle that indicates what is visible in the associated widget.
.TP 10
\fBtrough2\fR
The region between the slider and \fBarrow2\fR.
.TP 10
\fBarrow2\fR
The bottom or right arrow in the scrollbar.
.SH "WIDGET COMMAND"
.PP
The \fBscrollbar\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scrollbar widgets:

.TP
\fIpathName \fBactivate \fR?\fIelement\fR?
.
Marks the element indicated by \fIelement\fR as active, which
causes it to be displayed as specified by the \fB\-activebackground\fR
and \fB\-activerelief\fR options.
The only element values understood by this command are \fBarrow1\fR,
\fBslider\fR, or \fBarrow2\fR.
If any other value is specified then no element of the scrollbar
will be active.
If \fIelement\fR is not specified, the command returns
the name of the element that is currently active, or an empty string
if no element is active.

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.

.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
.
Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in slider position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the slider \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
ignored in this case).
If the scrollbar is vertical, the result indicates how much the
scrollbar setting must change to move the slider \fIdeltaY\fR pixels
down.  The arguments and the result may be zero or negative.

.TP
\fIpathName \fBfraction \fIx y\fR
.
Returns a real number between 0 and 1 indicating where the point
given by \fIx\fR and \fIy\fR lies in the trough area of the scrollbar.
The value 0 corresponds to the top or left of the trough, the
value 1 corresponds to the bottom or right, 0.5 corresponds to
the middle, and so on.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest
point in the trough is used.

.TP
\fIpathName \fBget\fR
.
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.

.TP
\fIpathName \fBidentify \fIx y\fR
.
Returns the name of the element under the point given by \fIx\fR and
\fIy\fR (such as \fBarrow1\fR), or an empty string if the point does
not lie in any element of the scrollbar.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.

.TP
\fIpathName \fBset \fIfirst last\fR
.
This command is invoked by the scrollbar's associated widget to
tell the scrollbar about the current view in the widget.
The command takes two arguments, each of which is a real fraction
between 0 and 1.







<
|

<
|

<
|

<
|

<
|













>













>







>















>












>












>





>








>







77
78
79
80
81
82
83

84
85

86
87

88
89

90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
Scrollbars can be used to adjust the view in the associated window
by clicking or dragging with the mouse.  See the \fBBINDINGS\fR section
below for details.
.SH "ELEMENTS"
.PP
A scrollbar displays five elements, which are referred to in the
widget commands for the scrollbar:

.IP \fBarrow1\fR 10
The top or left arrow in the scrollbar.

.IP \fBtrough1\fR 10
The region between the slider and \fBarrow1\fR.

.IP \fBslider\fR 10
The rectangle that indicates what is visible in the associated widget.

.IP \fBtrough2\fR 10
The region between the slider and \fBarrow2\fR.

.IP \fBarrow2\fR 10
The bottom or right arrow in the scrollbar.
.SH "WIDGET COMMAND"
.PP
The \fBscrollbar\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scrollbar widgets:
.\" METHOD: activate
.TP
\fIpathName \fBactivate \fR?\fIelement\fR?
.
Marks the element indicated by \fIelement\fR as active, which
causes it to be displayed as specified by the \fB\-activebackground\fR
and \fB\-activerelief\fR options.
The only element values understood by this command are \fBarrow1\fR,
\fBslider\fR, or \fBarrow2\fR.
If any other value is specified then no element of the scrollbar
will be active.
If \fIelement\fR is not specified, the command returns
the name of the element that is currently active, or an empty string
if no element is active.
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBscrollbar\fR
command.
.\" METHOD: delta
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
.
Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in slider position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the slider \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
ignored in this case).
If the scrollbar is vertical, the result indicates how much the
scrollbar setting must change to move the slider \fIdeltaY\fR pixels
down.  The arguments and the result may be zero or negative.
.\" METHOD: fraction
.TP
\fIpathName \fBfraction \fIx y\fR
.
Returns a real number between 0 and 1 indicating where the point
given by \fIx\fR and \fIy\fR lies in the trough area of the scrollbar.
The value 0 corresponds to the top or left of the trough, the
value 1 corresponds to the bottom or right, 0.5 corresponds to
the middle, and so on.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest
point in the trough is used.
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.\" METHOD: identify
.TP
\fIpathName \fBidentify \fIx y\fR
.
Returns the name of the element under the point given by \fIx\fR and
\fIy\fR (such as \fBarrow1\fR), or an empty string if the point does
not lie in any element of the scrollbar.
\fIX\fR and \fIy\fR must be pixel coordinates relative to the scrollbar
widget.
.\" METHOD: set
.TP
\fIpathName \fBset \fIfirst last\fR
.
This command is invoked by the scrollbar's associated widget to
tell the scrollbar about the current view in the widget.
The command takes two arguments, each of which is a real fraction
between 0 and 1.
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
the slider, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like
.QW \fB.t yview\fR .

.TP
\fIprefix \fBmoveto \fIfraction\fR
.
\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.

.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
.
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible. Fractional number are rounded away from 0, so
scrolling 0.001 pages has the same effect as scrolling 1 page.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
.
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window. Fractional
numbers are rounded away from 0, so scrolling 0.001 units has
the same effect as scrolling 1 unit.
.SH "OLD COMMAND SYNTAX"
.PP
In versions of Tk before 4.0, the \fBset\fR and \fBget\fR widget
commands used a different form.
This form is still supported for backward compatibility, but it
is deprecated.
In the old command syntax, the \fBset\fR widget command has the
following form:
.TP
\fIpathName \fBset \fItotalUnits windowUnits firstUnit lastUnit\fR
In this form the arguments are all integers.
\fITotalUnits\fR gives the total size of the object being displayed in the
associated widget.  The meaning of one unit depends on the associated
widget;  for example, in a text editor widget units might
correspond to lines of
text.  \fIWindowUnits\fR indicates the total number of units that
can fit in the associated window at one time.  \fIFirstUnit\fR
and \fIlastUnit\fR give the indices of the first and last units
currently visible in the associated window (zero corresponds to the
first unit of the object).
.LP
Under the old syntax the \fBget\fR widget command returns a list
of four integers, consisting of the \fItotalUnits\fR, \fIwindowUnits\fR,
\fIfirstUnit\fR, and \fIlastUnit\fR values from the last \fBset\fR
widget command.
.PP
The commands generated by scrollbars also have a different form
when the old syntax is being used:
.TP
\fIprefix\fR \fIunit\fR
\fIUnit\fR is an integer that indicates what should appear at
the top or left of the associated widget's window.
It has the same meaning as the \fIfirstUnit\fR and \fIlastUnit\fR
arguments to the \fBset\fR widget command.
.LP
The most recent \fBset\fR widget command determines whether or not
to use the old syntax.
If it is given two real arguments then the new syntax will be
used in the future, and if it is given four integer arguments then
the old syntax will be used.
.SH BINDINGS
.PP
Tk automatically creates class bindings for scrollbars that give them
the following default behavior.
If the behavior is different for vertical and horizontal scrollbars,
the horizontal behavior is described in parentheses.
.IP [1]







|
>










>









|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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








































244
245
246
247
248
249
250
the slider, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like
.QW "\fB.t yview\fR" .
.\" METHOD: moveto
.TP
\fIprefix \fBmoveto \fIfraction\fR
.
\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.\" METHOD: scroll
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
.
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible. Fractional numbers are rounded away from 0, so
scrolling 0.001 pages has the same effect as scrolling 1 page.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
.
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window. Fractional
numbers are rounded away from 0, so scrolling 0.001 units has
the same effect as scrolling 1 unit.








































.SH BINDINGS
.PP
Tk automatically creates class bindings for scrollbars that give them
the following default behavior.
If the behavior is different for vertical and horizontal scrollbars,
the horizontal behavior is described in parentheses.
.IP [1]
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
.IP [14]
The End key adjusts the view to the bottom (right edge) of the document.
.SH EXAMPLE
.PP
Create a window with a scrollable \fBtext\fR widget:
.CS
toplevel .tl
text .tl.t \-yscrollcommand {.tl.s set}
\fBscrollbar\fR .tl.s \-command {.tl.t yview}
grid .tl.t .tl.s \-sticky nsew
grid columnconfigure .tl 0 \-weight 1
grid rowconfigure .tl 0 \-weight 1
.CE
.SH "SEE ALSO"
ttk:scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|
|
|








309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
.IP [14]
The End key adjusts the view to the bottom (right edge) of the document.
.SH EXAMPLE
.PP
Create a window with a scrollable \fBtext\fR widget:
.CS
toplevel .tl
text .tl.t -yscrollcommand {.tl.s set}
\fBscrollbar\fR .tl.s -command {.tl.t yview}
grid .tl.t .tl.s -sticky nsew
grid columnconfigure .tl 0 -weight 1
grid rowconfigure .tl 0 -weight 1
.CE
.SH "SEE ALSO"
ttk:scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/selection.n.

22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
.PP
Note that for management of the \fBCLIPBOARD\fR selection (see below), the
\fBclipboard\fR command may also be used.
.PP
The first argument to \fBselection\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:

.TP
\fBselection clear\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR?
.
If \fIselection\fR exists anywhere on \fIwindow\fR's display, clear it
so that no window owns the selection anymore.  \fISelection\fR
specifies the X selection that should be cleared, and should be an
atom name such as \fBPRIMARY\fR or \fBCLIPBOARD\fR; see the Inter-Client
Communication Conventions Manual for complete details.
\fISelection\fR defaults to \fBPRIMARY\fR and \fIwindow\fR defaults to
.QW . .
Returns an empty string.

.TP
\fBselection get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR? ?\fB\-type\fR \fItype\fR?
.
Retrieves the value of \fIselection\fR from \fIwindow\fR's display and
returns it as a result.  \fISelection\fR defaults to \fBPRIMARY\fR and
\fIwindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which the selection is to be returned
(the desired







>

|









>

|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
.PP
Note that for management of the \fBCLIPBOARD\fR selection (see below), the
\fBclipboard\fR command may also be used.
.PP
The first argument to \fBselection\fR determines the format of the
rest of the arguments and the behavior of the command.  The following
forms are currently supported:
.\" METHOD: clear
.TP
\fBselection clear\fR ?\fB\-displayof\fI window\fR? ?\fB\-selection\fI selection\fR?
.
If \fIselection\fR exists anywhere on \fIwindow\fR's display, clear it
so that no window owns the selection anymore.  \fISelection\fR
specifies the X selection that should be cleared, and should be an
atom name such as \fBPRIMARY\fR or \fBCLIPBOARD\fR; see the Inter-Client
Communication Conventions Manual for complete details.
\fISelection\fR defaults to \fBPRIMARY\fR and \fIwindow\fR defaults to
.QW . .
Returns an empty string.
.\" METHOD: get
.TP
\fBselection get\fR ?\fB\-displayof\fI window\fR? ?\fB\-selection\fI selection\fR? ?\fB\-type\fI type\fR?
.
Retrieves the value of \fIselection\fR from \fIwindow\fR's display and
returns it as a result.  \fISelection\fR defaults to \fBPRIMARY\fR and
\fIwindow\fR defaults to
.QW . .
\fIType\fR specifies the form in which the selection is to be returned
(the desired
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
than the selection type; see the ICCCM for all the confusing details).
If the selection is returned in a non-string format, such as \fBINTEGER\fR
or \fBATOM\fR, the \fBselection\fR command converts it to string format as a
collection of fields separated by spaces: atoms are converted to their
textual names, and anything else is converted to hexadecimal integers.
Note that \fBselection get\fR does not retrieve the selection in the
\fBUTF8_STRING\fR format unless told to.

.TP
\fBselection handle\fR ?\fB\-selection\fR \fIs\fR? ?\fB\-type\fR \fIt\fR? ?\fB\-format\fR \fIf\fR? \fIwindow command\fR
.
Creates a handler for selection requests, such that \fIcommand\fR will
be executed whenever selection \fIs\fR is owned by \fIwindow\fR and
someone attempts to retrieve it in the form given by type \fIt\fR
(e.g. \fIt\fR is specified in the \fBselection get\fR command).
\fIS\fR defaults to \fBPRIMARY\fR, \fIt\fR defaults to \fBSTRING\fR, and
\fIf\fR defaults to \fBSTRING\fR.  If \fIcommand\fR is an empty string







>

|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
than the selection type; see the ICCCM for all the confusing details).
If the selection is returned in a non-string format, such as \fBINTEGER\fR
or \fBATOM\fR, the \fBselection\fR command converts it to string format as a
collection of fields separated by spaces: atoms are converted to their
textual names, and anything else is converted to hexadecimal integers.
Note that \fBselection get\fR does not retrieve the selection in the
\fBUTF8_STRING\fR format unless told to.
.\" METHOD: handle
.TP
\fBselection handle\fR ?\fB\-selection\fI s\fR? ?\fB\-type\fI t\fR? ?\fB\-format\fI f\fR? \fIwindow command\fR
.
Creates a handler for selection requests, such that \fIcommand\fR will
be executed whenever selection \fIs\fR is owned by \fIwindow\fR and
someone attempts to retrieve it in the form given by type \fIt\fR
(e.g. \fIt\fR is specified in the \fBselection get\fR command).
\fIS\fR defaults to \fBPRIMARY\fR, \fIt\fR defaults to \fBSTRING\fR, and
\fIf\fR defaults to \fBSTRING\fR.  If \fIcommand\fR is an empty string
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145




146
147



148
149
150
151

152
153





154
155
156
157


158
159


160
161


162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
.PP
The \fIformat\fR argument is needed only for compatibility with
selection requesters that do not use Tk.  If Tk is being
used to retrieve the selection then the value is converted back to
a string at the requesting end, so \fIformat\fR is
irrelevant.
.RE

.TP
\fBselection own\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR?
.TP
\fBselection own\fR ?\fB\-command\fR \fIcommand\fR? ?\fB\-selection\fR \fIselection\fR? \fIwindow\fR
.
The first form of \fBselection own\fR returns the path name of the
window in this application that owns \fIselection\fR on the display
containing \fIwindow\fR, or an empty string if no window in this
application owns the selection.  \fISelection\fR defaults to \fBPRIMARY\fR and
\fIwindow\fR defaults to
.QW . .
.RS
.PP
The second form of \fBselection own\fR causes \fIwindow\fR to become
the new owner of \fIselection\fR on \fIwindow\fR's display, returning
an empty string as result. The existing owner, if any, is notified
that it has lost the selection.
If \fIcommand\fR is specified, it is a Tcl script to execute when
some other window claims ownership of the selection away from
\fIwindow\fR.  \fISelection\fR defaults to PRIMARY.
.RE
.SH WIDGET FACILITIES
.PP
The \fBtext\fR, \fBentry\fR, \fBttk::entry\fR, \fBlistbox\fR, \fBspinbox\fR and \fBttk::spinbox\fR widgets have the option \fB\-exportselection\fR.  If a widget has this option set to boolean \fBtrue\fR, then (in an unsafe interpreter) a selection made in the widget is automatically written to the \fBPRIMARY\fR selection.




.PP
A GUI event, for example \fB<<PasteSelection>>\fR, can copy the \fBPRIMARY\fR selection to certain widgets.  This copy is implemented by a widget binding to the event.  The binding script makes appropriate calls to the \fBselection\fR command.



.PP
.SH PORTABILITY ISSUES
.PP
On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server, allowing communication between different processes that are X11 clients.

.PP
On Windows, the \fBPRIMARY\fR selection is not provided by the system, but only by Tk, and so it is shared only between windows of a parent interpreter and its child interpreters.  It is not shared between interpreters in different processes or different threads.  Each parent interpreter has a separate \fBPRIMARY\fR selection that is shared only with its child interpreters which are not safe interpreters.





.PP
.SH SECURITY
.PP
A safe interpreter cannot read from the \fBPRIMARY\fR selection because its \fBselection\fR command is hidden.  For this reason the \fBPRIMARY\fR selection cannot be written to the Tk widgets of a safe interpreter.


.PP
A Tk widget can have its option \fB\-exportselection\fR set to boolean \fBtrue\fR, but in a safe interpreter this option has no effect: writing from the widget to the \fBPRIMARY\fR selection is disabled.


.PP
These are security features.  A safe interpreter may run untrusted code, and it is a security risk if this untrusted code can read or write the \fBPRIMARY\fR selection used by other interpreters.


.PP
.SH EXAMPLES
.PP
On X11 platforms, one of the standard selections available is the
\fBSECONDARY\fR selection. Hardly anything uses it, but here is how to read
it using Tk:
.PP
.CS
set selContents [\fBselection get\fR \-selection SECONDARY]
.CE
.PP
Many different types of data may be available for a selection; the
special type \fBTARGETS\fR allows you to get a list of available types:
.PP
.CS
foreach type [\fBselection get\fR \-type TARGETS] {
   puts "Selection PRIMARY supports type $type"
}
.CE
.PP
To claim the selection, you must first set up a handler to supply the
data for the selection. Then you have to claim the selection...
.CS
# Set up the data handler ready for incoming requests
set foo "This is a string with some data in it... blah blah"
\fBselection handle\fR \-selection SECONDARY . getData
proc getData {offset maxChars} {
   puts "Retrieving selection starting at $offset"
   return [string range $::foo $offset [expr {$offset+$maxChars-1}]]
}

# Now we grab the selection itself
puts "Claiming selection"
\fBselection own\fR \-command lost \-selection SECONDARY .
proc lost {} {
   puts "Lost selection"
}
.CE
.SH "SEE ALSO"
clipboard(n)
.SH KEYWORDS
clear, format, handler, ICCCM, own, selection, target, type
'\" Local Variables:
'\" mode: nroff
'\" End:







>

|

|



















|
>
>
>
>

|
>
>
>



|
>

|
>
>
>
>
>



|
>
>

|
>
>

|
>
>








|






|









|







|











118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
.PP
The \fIformat\fR argument is needed only for compatibility with
selection requesters that do not use Tk.  If Tk is being
used to retrieve the selection then the value is converted back to
a string at the requesting end, so \fIformat\fR is
irrelevant.
.RE
.\" METHOD: own
.TP
\fBselection own\fR ?\fB\-displayof\fI window\fR? ?\fB\-selection\fI selection\fR?
.TP
\fBselection own\fR ?\fB\-command\fI command\fR? ?\fB\-selection\fI selection\fR? \fIwindow\fR
.
The first form of \fBselection own\fR returns the path name of the
window in this application that owns \fIselection\fR on the display
containing \fIwindow\fR, or an empty string if no window in this
application owns the selection.  \fISelection\fR defaults to \fBPRIMARY\fR and
\fIwindow\fR defaults to
.QW . .
.RS
.PP
The second form of \fBselection own\fR causes \fIwindow\fR to become
the new owner of \fIselection\fR on \fIwindow\fR's display, returning
an empty string as result. The existing owner, if any, is notified
that it has lost the selection.
If \fIcommand\fR is specified, it is a Tcl script to execute when
some other window claims ownership of the selection away from
\fIwindow\fR.  \fISelection\fR defaults to PRIMARY.
.RE
.SH WIDGET FACILITIES
.PP
The \fBtext\fR, \fBentry\fR, \fBttk::entry\fR, \fBlistbox\fR, \fBspinbox\fR
and \fBttk::spinbox\fR widgets have the option \fB\-exportselection\fR.  If a
widget has this option set to boolean \fBtrue\fR, then (in an unsafe
interpreter) a selection made in the widget is automatically written to the
\fBPRIMARY\fR selection.
.PP
A GUI event, for example \fB<<PasteSelection>>\fR, can copy the \fBPRIMARY\fR
selection to certain widgets.  This copy is implemented by a widget binding to
the event.  The binding script makes appropriate calls to the \fBselection\fR
command.
.PP
.SH PORTABILITY ISSUES
.PP
On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server,
allowing communication between different processes that are X11 clients.
.PP
On Windows, the \fBPRIMARY\fR selection is not provided by the system, but
only by Tk, and so it is shared only between windows of a parent interpreter
and its child interpreters.  It is not shared between interpreters in
different processes or different threads.  Each parent interpreter has a
separate \fBPRIMARY\fR selection that is shared only with its child
interpreters which are not safe interpreters.
.PP
.SH SECURITY
.PP
A safe interpreter cannot read from the \fBPRIMARY\fR selection because its
\fBselection\fR command is hidden.  For this reason the \fBPRIMARY\fR
selection cannot be written to the Tk widgets of a safe interpreter.
.PP
A Tk widget can have its option \fB\-exportselection\fR set to boolean
\fBtrue\fR, but in a safe interpreter this option has no effect: writing
from the widget to the \fBPRIMARY\fR selection is disabled.
.PP
These are security features.  A safe interpreter may run untrusted code, and
it is a security risk if this untrusted code can read or write the
\fBPRIMARY\fR selection used by other interpreters.
.PP
.SH EXAMPLES
.PP
On X11 platforms, one of the standard selections available is the
\fBSECONDARY\fR selection. Hardly anything uses it, but here is how to read
it using Tk:
.PP
.CS
set selContents [\fBselection get\fR -selection SECONDARY]
.CE
.PP
Many different types of data may be available for a selection; the
special type \fBTARGETS\fR allows you to get a list of available types:
.PP
.CS
foreach type [\fBselection get\fR -type TARGETS] {
   puts "Selection PRIMARY supports type $type"
}
.CE
.PP
To claim the selection, you must first set up a handler to supply the
data for the selection. Then you have to claim the selection...
.CS
# Set up the data handler ready for incoming requests
set foo "This is a string with some data in it... blah blah"
\fBselection handle\fR -selection SECONDARY . getData
proc getData {offset maxChars} {
   puts "Retrieving selection starting at $offset"
   return [string range $::foo $offset [expr {$offset+$maxChars-1}]]
}

# Now we grab the selection itself
puts "Claiming selection"
\fBselection own\fR -command lost -selection SECONDARY .
proc lost {} {
   puts "Lost selection"
}
.CE
.SH "SEE ALSO"
clipboard(n)
.SH KEYWORDS
clear, format, handler, ICCCM, own, selection, target, type
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/send.n.

26
27
28
29
30
31
32

33
34

35
36
37
38
39
40

41
42

43
44
45

46
47

48
49
50
51
52
53
54
contained entirely within the \fIcmd\fR argument.  If one or
more \fIarg\fRs are present, they are concatenated to form the
command to be executed, just as for the \fBeval\fR command.
.PP
If the initial arguments of the command begin with
.QW \-
they are treated as options.  The following options are currently defined:

.TP
\fB\-async\fR

Requests asynchronous invocation.  In this case the \fBsend\fR
command will complete immediately without waiting for \fIcmd\fR
to complete in the target application;  no result will be available
and errors in the sent command will be ignored.
If the target application is in the same process as the sending
application then the \fB\-async\fR option is ignored.

.TP
\fB\-displayof\fR \fIpathName\fR

Specifies that the target application's main window is on the display
of the window given by \fIpathName\fR, instead of the display containing
the application's main window.

.TP
\fB\-\|\-\fR

Serves no purpose except to terminate the list of options.  This
option is needed only if \fIapp\fR could contain a leading
.QW \-
character.
.SH "APPLICATION NAMES"
.PP
The name of an application is set initially from the name of the







>


>






>

|
>



>


>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
contained entirely within the \fIcmd\fR argument.  If one or
more \fIarg\fRs are present, they are concatenated to form the
command to be executed, just as for the \fBeval\fR command.
.PP
If the initial arguments of the command begin with
.QW \-
they are treated as options.  The following options are currently defined:
.\" OPTION: -async
.TP
\fB\-async\fR
.
Requests asynchronous invocation.  In this case the \fBsend\fR
command will complete immediately without waiting for \fIcmd\fR
to complete in the target application;  no result will be available
and errors in the sent command will be ignored.
If the target application is in the same process as the sending
application then the \fB\-async\fR option is ignored.
.\" OPTION: -displayof
.TP
\fB\-displayof\fI pathName\fR
.
Specifies that the target application's main window is on the display
of the window given by \fIpathName\fR, instead of the display containing
the application's main window.
.\" OPTION: --
.TP
\fB\-\|\-\fR
.
Serves no purpose except to terminate the list of options.  This
option is needed only if \fIapp\fR could contain a leading
.QW \-
character.
.SH "APPLICATION NAMES"
.PP
The name of an application is set initially from the name of the
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
functionality is provided by the \fBdde\fR command instead.
.SH EXAMPLE
.PP
This script fragment can be used to make an application that only runs
once on a particular display.
.CS
if {[tk appname FoobarApp] ne "FoobarApp"} {
    \fBsend\fR \-async FoobarApp RemoteStart $argv
    exit
}
# The command that will be called remotely, which raises
# the application main window and opens the requested files
proc RemoteStart args {
    raise .
    foreach filename $args {







|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
functionality is provided by the \fBdde\fR command instead.
.SH EXAMPLE
.PP
This script fragment can be used to make an application that only runs
once on a particular display.
.CS
if {[tk appname FoobarApp] ne "FoobarApp"} {
    \fBsend\fR -async FoobarApp RemoteStart $argv
    exit
}
# The command that will be called remotely, which raises
# the application main window and opens the requested files
proc RemoteStart args {
    raise .
    foreach filename $args {

Changes to doc/spinbox.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH spinbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
spinbox \- Create and manipulate 'spinbox' value spinner widgets
.SH SYNOPSIS
\fBspinbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightthickness	\-repeatinterval
\-background	\-insertbackground	\-selectbackground
\-borderwidth	\-insertborderwidth	\-selectborderwidth
\-cursor	\-insertontime	\-selectforeground
\-exportselection	\-insertwidth	\-takefocus
\-font	\-insertofftime	\-textvariable







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH spinbox n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
spinbox \- Create and manipulate 'spinbox' value spinner widgets
.SH SYNOPSIS
\fBspinbox\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightthickness	\-repeatinterval
\-background	\-insertbackground	\-selectbackground
\-borderwidth	\-insertborderwidth	\-selectborderwidth
\-cursor	\-insertontime	\-selectforeground
\-exportselection	\-insertwidth	\-takefocus
\-font	\-insertofftime	\-textvariable
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
The \fB\-validatecommand\fR will be called when the spinbox loses focus.
.IP \fBkey\fR 10
The \fB\-validatecommand\fR will be called when the spinbox is edited.
.IP \fBall\fR 10
The \fB\-validatecommand\fR will be called for all above conditions.
.PP
It is possible to perform percent substitutions on the \fB\-validatecommand\fR
and \fB\-invalidcommand\fR scripts, just as you would in a \fBbind\fR script.  The
following substitutions are recognized:
.PP
.IP \fB%d\fR 5
Type of action: 1 for \fBinsert\fR, 0 for \fBdelete\fR,
or \-1 for focus, forced or textvariable validation.
.IP \fB%i\fR 5
Index of char string to be inserted/deleted, if any, otherwise \-1.
.IP \fB%P\fR 5







|
|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
The \fB\-validatecommand\fR will be called when the spinbox loses focus.
.IP \fBkey\fR 10
The \fB\-validatecommand\fR will be called when the spinbox is edited.
.IP \fBall\fR 10
The \fB\-validatecommand\fR will be called for all above conditions.
.PP
It is possible to perform percent substitutions on the \fB\-validatecommand\fR
and \fB\-invalidcommand\fR scripts, just as you would in a \fBbind\fR script.
The following substitutions are recognized:
.PP
.IP \fB%d\fR 5
Type of action: 1 for \fBinsert\fR, 0 for \fBdelete\fR,
or \-1 for focus, forced or textvariable validation.
.IP \fB%i\fR 5
Index of char string to be inserted/deleted, if any, otherwise \-1.
.IP \fB%P\fR 5
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256

257
258
259
260

261
262
263
264
265

266
267
268
269

270
271
272
273

274
275
276
277
278

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



291
292
293

294
295

296
297
298
299
300
301
302
303

304
305

306
307
308
309

310
311

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

324
325

326
327
328
329
330
331
332

333
334

335

336
337

338
339

340
341

342
343
344

345
346

347

348
349

350
351

352
353

354
355

356
357

358
359
360
361
362

363
364
365
366
367
368

369
370
371
372
373
374
375
376

377
378

379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399

400
401
402
403

404
405
406
407
408

409
410
411
412

413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432

433
434

435
436
437

438
439

440
441
442
443

444
445

446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
461

462
463
464
465

466
467
468
469
470

471
472
473
474
475
476
477
\fB\-validate\fR option will also set itself to \fBnone\fR when you edit the
spinbox widget from within either the \fB\-validatecommand\fR or the
\fB\-invalidcommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the value of the widget
during validation and still have the \fB\-validate\fR option set, you should
include the command
.CS
     \fI%W config \-validate %v\fR
.CE
in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you
were editing the spinbox widget from).  It is also recommended to not set an
associated \fB\-textvariable\fR during validation, as that can cause the
spinbox widget to become out of sync with the \fB\-textvariable\fR.
.PP
Also, the \fB-validate\fR option will set itself to \fBnone\fR when the
spinbox value gets changed because of adjustment of \fB-from\fR or \fB-to\fR
and the \fB-validatecommand\fR returns false. For instance
.CS
     \fIspinbox pathName \-from 1 \-to 10 \-validate all \-vcmd {return 0}\fR
.CE
will in fact set the \fB-validate\fR option to \fBnone\fR because the default
value for the spinbox gets changed (due to the \fB-from\fR and \fB-to\fR
options) to a value not accepted by the validation script.
.PP
Moreover, forced validation is performed when invoking any spinbutton of
the spinbox. If the validation script returns false in this situation,
then the \fB-validate\fR option will be automatically set to \fBnone\fR.
.SH "WIDGET COMMAND"
.PP
The \fBspinbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for spinboxes take one or more indices as
arguments.  An index specifies a particular character in the spinbox's
string, in any of the following ways:
.TP 12
\fInumber\fR

Specifies the character as a numerical index, where 0 corresponds
to the first character in the string.
.TP 12
\fBanchor\fR

Indicates the anchor point for the selection, which is set with the
\fBselect from\fR and \fBselect adjust\fR widget commands.
.TP 12
\fBend\fR

Indicates the character just after the last one in the spinbox's string.
This is equivalent to specifying a numerical index equal to the length
of the spinbox's string.
.TP 12
\fBinsert\fR

Indicates the character adjacent to and immediately following the
insertion cursor.
.TP 12
\fBsel.first\fR

Indicates the first character in the selection.  It is an error to
use this form if the selection is not in the spinbox window.
.TP 12
\fBsel.last\fR

Indicates the character just after the last one in the selection.
It is an error to use this form if the selection is not in the
spinbox window.
.TP 12
\fB@\fInumber\fR

In this form, \fInumber\fR is treated as an x-coordinate in the
spinbox's window;  the character spanning that x-coordinate is used.
For example,
.QW \fB@0\fR
indicates the left-most character in the window.
.LP
Abbreviations may be used for any of the forms above, e.g.
.QW \fBe\fR
or
.QW \fBsel.f\fR .
In general, out-of-range indices are automatically rounded to the
nearest legal value.



.SS SUBCOMMANDS
.PP
The following commands are possible for spinbox widgets:

.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 configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBspinbox\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBspinbox\fR
command.

.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?

Delete one or more elements of the spinbox.
\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 an empty string.

.TP
\fIpathName \fBget\fR

Returns the spinbox's string.

.TP
\fIpathName \fBicursor \fIindex\fR

Arrange for the insertion cursor to be displayed just before the character
given by \fIindex\fR.  Returns an empty string.

.TP
\fIpathName \fBidentify\fI x y\fR

Returns the name of the window element corresponding to coordinates
\fIx\fR and \fIy\fR in the spinbox.  Return value is one of:
\fBnone\fR, \fBbuttondown\fR, \fBbuttonup\fR, \fBentry\fR.

.TP
\fIpathName \fBindex\fI index\fR

Returns the numerical index corresponding to \fIindex\fR.

.TP
\fIpathName \fBinsert \fIindex string\fR

Insert the characters of \fIstring\fR just before the character
indicated by \fIindex\fR.  Returns an empty string.

.TP
\fIpathName \fBinvoke\fI element\fR

Causes the specified element, either \fBbuttondown\fR or \fBbuttonup\fR,
to be invoked, triggering the action associated with it.

.TP
\fIpathName \fBscan\fR \fIoption args\fR

This command is used to implement scanning on spinboxes.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx\fR

Records \fIx\fR and the current view in the spinbox window;  used in
conjunction with later \fBscan dragto\fR commands.  Typically this
command is associated with a mouse button press in the widget.  It
returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx\fR

This command computes the difference between its \fIx\fR argument
and the \fIx\fR argument to the last \fBscan mark\fR command for
the widget.  It then adjusts the view left or right by 10 times the
difference in x-coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the spinbox at high speed through the window.  The return
value is an empty string.
.RE

.TP
\fIpathName \fBselection \fIoption arg\fR

This command is used to adjust the selection within a spinbox.  It
has several forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBselection adjust \fIindex\fR

Locate the end of the selection nearest to the character given by
\fIindex\fR, and adjust that end of the selection to be at \fIindex\fR
(i.e. including but not going beyond \fIindex\fR).  The other
end of the selection is made the anchor point for future
\fBselect to\fR commands.  If the selection
is not currently in the spinbox, then a new selection is created to
include the characters between \fIindex\fR and the most recent
selection anchor point, inclusive.
Returns an empty string.
.TP
\fIpathName \fBselection clear\fR

Clear the selection if it is currently in this widget.  If the
selection is not in this widget then the command has no effect.
Returns an empty string.
.TP
\fIpathName \fBselection element\fR ?\fIelement\fR?

Sets or gets the currently selected element.  If a spinbutton element
is specified, it will be displayed depressed.
.TP
\fIpathName \fBselection from \fIindex\fR

Set the selection anchor point to just before the character
given by \fIindex\fR.  Does not change the selection.
Returns an empty string.
.TP
\fIpathName \fBselection present\fR

Returns 1 if there is are characters selected in the spinbox,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart end\fR

Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the spinbox's selection is cleared.
.TP
\fIpathName \fBselection to \fIindex\fR

If \fIindex\fR is before the anchor point, set the selection
to the characters from \fIindex\fR up to but not including
the anchor point.
If \fIindex\fR is the same as the anchor point, do nothing.
If \fIindex\fR is after the anchor point, set the selection
to the characters from the anchor point up to but not including
\fIindex\fR.
The anchor point is determined by the most recent \fBselect from\fR
or \fBselect adjust\fR command in this widget.
If the selection is not in this widget then a new selection is
created using the most recent anchor point specified for the widget.
Returns an empty string.
.RE

.TP
\fIpathName \fBset\fR ?\fIstring\fR?

If \fIstring\fR is specified, the spinbox will try and set it to this
value, otherwise it just returns the spinbox's string.
If validation is on, it will occur when setting the string.

.TP
\fIpathName \fBvalidate\fR

This command is used to force an evaluation of the \fB\-validatecommand\fR
independent of the conditions specified by the \fB\-validate\fR option.
This is done by temporarily setting the \fB\-validate\fR option to \fBall\fR.
It returns 0 or 1.

.TP
\fIpathName \fBxview \fIargs\fR

This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the spinbox's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview \fIindex\fR

Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR







|






|
|
|

|

|
|




|

















>




>




>





>




>




>





>












>
>
>



>


>








>

|
>




>


>












>


>







>


>

>


>


>


>



>


>

>


>


>


>


>

|
>





>






>








>


>





>











>





>




>





>




>







>













>


>



>


>




>


>






>










>




>





>







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
\fB\-validate\fR option will also set itself to \fBnone\fR when you edit the
spinbox widget from within either the \fB\-validatecommand\fR or the
\fB\-invalidcommand\fR.  Such editions will override the one that was being
validated.  If you wish to edit the value of the widget
during validation and still have the \fB\-validate\fR option set, you should
include the command
.CS
     \fI%W config -validate %v\fR
.CE
in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you
were editing the spinbox widget from).  It is also recommended to not set an
associated \fB\-textvariable\fR during validation, as that can cause the
spinbox widget to become out of sync with the \fB\-textvariable\fR.
.PP
Also, the \fB\-validate\fR option will set itself to \fBnone\fR when the
spinbox value gets changed because of adjustment of \fB\-from\fR or \fB\-to\fR
and the \fB\-validatecommand\fR returns false. For instance
.CS
     \fIspinbox pathName -from 1 -to 10 -validate all -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 ...\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
string, in any of the following ways:
.TP 12
\fInumber\fR
.
Specifies the character as a numerical index, where 0 corresponds
to the first character in the string.
.TP 12
\fBanchor\fR
.
Indicates the anchor point for the selection, which is set with the
\fBselect from\fR and \fBselect adjust\fR widget commands.
.TP 12
\fBend\fR
.
Indicates the character just after the last one in the spinbox's string.
This is equivalent to specifying a numerical index equal to the length
of the spinbox's string.
.TP 12
\fBinsert\fR
.
Indicates the character adjacent to and immediately following the
insertion cursor.
.TP 12
\fBsel.first\fR
.
Indicates the first character in the selection.  It is an error to
use this form if the selection is not in the spinbox window.
.TP 12
\fBsel.last\fR
.
Indicates the character just after the last one in the selection.
It is an error to use this form if the selection is not in the
spinbox window.
.TP 12
\fB@\fInumber\fR
.
In this form, \fInumber\fR is treated as an x-coordinate in the
spinbox's window;  the character spanning that x-coordinate is used.
For example,
.QW \fB@0\fR
indicates the left-most character in the window.
.LP
Abbreviations may be used for any of the forms above, e.g.
.QW \fBe\fR
or
.QW \fBsel.f\fR .
In general, out-of-range indices are automatically rounded to the
nearest legal value.
Indexes support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\fR.
.SS SUBCOMMANDS
.PP
The following commands are possible for spinbox widgets:
.\" METHOD: bbox
.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.
.\" METHOD: cget
.TP
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBspinbox\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBspinbox\fR
command.
.\" METHOD: delete
.TP
\fIpathName \fBdelete \fIfirst \fR?\fIlast\fR?
.
Delete one or more elements of the spinbox.
\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 an empty string.
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the spinbox's string.
.\" METHOD: icursor
.TP
\fIpathName \fBicursor \fIindex\fR
.
Arrange for the insertion cursor to be displayed just before the character
given by \fIindex\fR.  Returns an empty string.
.\" METHOD: identify
.TP
\fIpathName \fBidentify\fI x y\fR
.
Returns the name of the window element corresponding to coordinates
\fIx\fR and \fIy\fR in the spinbox.  Return value is one of:
\fBnone\fR, \fBbuttondown\fR, \fBbuttonup\fR, \fBentry\fR.
.\" METHOD: index
.TP
\fIpathName \fBindex\fI index\fR
.
Returns the numerical index corresponding to \fIindex\fR.
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fIindex string\fR
.
Insert the characters of \fIstring\fR just before the character
indicated by \fIindex\fR.  Returns an empty string.
.\" METHOD: invoke
.TP
\fIpathName \fBinvoke\fI element\fR
.
Causes the specified element, either \fBbuttondown\fR or \fBbuttonup\fR,
to be invoked, triggering the action associated with it.
.\" METHOD: scan
.TP
\fIpathName \fBscan\fI option args\fR
.
This command is used to implement scanning on spinboxes.  It has
two forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBscan mark \fIx\fR
.
Records \fIx\fR and the current view in the spinbox window;  used in
conjunction with later \fBscan dragto\fR commands.  Typically this
command is associated with a mouse button press in the widget.  It
returns an empty string.
.TP
\fIpathName \fBscan dragto \fIx\fR
.
This command computes the difference between its \fIx\fR argument
and the \fIx\fR argument to the last \fBscan mark\fR command for
the widget.  It then adjusts the view left or right by 10 times the
difference in x-coordinates.  This command is typically associated
with mouse motion events in the widget, to produce the effect of
dragging the spinbox at high speed through the window.  The return
value is an empty string.
.RE
.\" METHOD: selection
.TP
\fIpathName \fBselection \fIoption arg\fR
.
This command is used to adjust the selection within a spinbox.  It
has several forms, depending on \fIoption\fR:
.RS
.TP
\fIpathName \fBselection adjust \fIindex\fR
.
Locate the end of the selection nearest to the character given by
\fIindex\fR, and adjust that end of the selection to be at \fIindex\fR
(i.e. including but not going beyond \fIindex\fR).  The other
end of the selection is made the anchor point for future
\fBselect to\fR commands.  If the selection
is not currently in the spinbox, then a new selection is created to
include the characters between \fIindex\fR and the most recent
selection anchor point, inclusive.
Returns an empty string.
.TP
\fIpathName \fBselection clear\fR
.
Clear the selection if it is currently in this widget.  If the
selection is not in this widget then the command has no effect.
Returns an empty string.
.TP
\fIpathName \fBselection element\fR ?\fIelement\fR?
.
Sets or gets the currently selected element.  If a spinbutton element
is specified, it will be displayed depressed.
.TP
\fIpathName \fBselection from \fIindex\fR
.
Set the selection anchor point to just before the character
given by \fIindex\fR.  Does not change the selection.
Returns an empty string.
.TP
\fIpathName \fBselection present\fR
.
Returns 1 if there is are characters selected in the spinbox,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart end\fR
.
Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the spinbox's selection is cleared.
.TP
\fIpathName \fBselection to \fIindex\fR
.
If \fIindex\fR is before the anchor point, set the selection
to the characters from \fIindex\fR up to but not including
the anchor point.
If \fIindex\fR is the same as the anchor point, do nothing.
If \fIindex\fR is after the anchor point, set the selection
to the characters from the anchor point up to but not including
\fIindex\fR.
The anchor point is determined by the most recent \fBselect from\fR
or \fBselect adjust\fR command in this widget.
If the selection is not in this widget then a new selection is
created using the most recent anchor point specified for the widget.
Returns an empty string.
.RE
.\" METHOD: set
.TP
\fIpathName \fBset\fR ?\fIstring\fR?
.
If \fIstring\fR is specified, the spinbox will try and set it to this
value, otherwise it just returns the spinbox's string.
If validation is on, it will occur when setting the string.
.\" METHOD: validate
.TP
\fIpathName \fBvalidate\fR
.
This command is used to force an evaluation of the \fB\-validatecommand\fR
independent of the conditions specified by the \fB\-validate\fR option.
This is done by temporarily setting the \fB\-validate\fR option to \fBall\fR.
It returns 0 or 1.
.\" METHOD: xview
.TP
\fIpathName \fBxview \fIargs\fR
.
This command is used to query and change the horizontal position of the
text in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1;  together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the spinbox's text is off-screen to the left, the middle 40% is visible
in the window, and 40% of the text is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview \fIindex\fR
.
Adjusts the view in the window so that the character given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
.
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR

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
.\" 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
.BS
.SH NAME
sysnotify \- Creates a notification window with a title and message.
.SH SYNOPSIS
\fBtk sysnotify\fI title message\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:
.PP
.CS
tk sysnotify "Alert" \e
      "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 will request permission from the user to authorize
notifications. This must be activated in Apple's System Preferences
Notifications section.
.RS
.PP
If deploying an application using the standalone version of Wish.app,
setting the bundle ID in the applications Info.plist file to begin with
.QW \fBcom\fR
seems necessary for notifications to work. Using a different prefix
for the bundle ID, such as something like
.QW \fBtk.tcl.tkchat\fR ,
will cause notifications to silently fail.
.RE
.TP
\fBWindows\fR
.
The image is taken from the system tray, i.e., \fBsysnotify\fR can only be
called when a \fBsystray\fR 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
.\" 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
.BS
.SH NAME
systray \- Creates an icon display in the platform-specific system tray.
.SH SYNOPSIS
.nf
\fBtk systray create \fB\-image \fIimage\fR ?\fB\-text \fItext\fR? ?\fB\-button1 \fIcallback\fR? ?\fB\-button3 \fIcallback\fR?
\fBtk systray configure \fI?option? ?value option value ...?\fR
\fBtk systray exists\fR
\fBtk systray destroy\fR
.fi
.BE
.SH DESCRIPTION
.PP
.\" METHOD: create
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
.\" METHOD: configure
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 value of this
option. When no option is given this command returns the list of all options and
their current value.
.PP
.\" METHOD: exists
The \fBtk systray exists\fR command checks whether a systray icon was created.
It returns a boolean.
.PP
.\" METHOD: destroy
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 \e
        R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
tk systray create -image book -text "tk systray sample" \e
        -button1 {puts "Here is the tk systray output"} \e
        -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 \e
        R0lGODlhCwAPAKIAAP//////AMDAwICAgAAA/wAAAAAAAAAAACwAAAAACwAPAAADMzi6CzAugiAgDGE68aB0RXgRJBFVX0SNpQlUWfahQOvSsgrX7eZJMlQMWBEYj8iQchlKAAA7
tk systray configure -image book_page -text "Updated sample" \e
        -button1 {puts "Different output from the tk systray"} \e
        -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 \fB\-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.

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

17
18

19


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




























38





39
40
41
42
43
44

45
46
47
48
49
50
51



































































































































52
53
54
55
56
57
58
59














































60
61
62















































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







79





80
81
82
83
84
85

86
87
88
89





















































90
91
92
93
94
95
96
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH text n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
text, tk_textCopy, tk_textCut, tk_textPaste \- Create and manipulate 'text' hypertext editing widgets
.SH SYNOPSIS
.nf
\fBtext\fR \fIpathName \fR?\fIoptions\fR?

\fBtk_textCopy\fR \fIpathName\fR
\fBtk_textCut\fR \fIpathName\fR

\fBtk_textPaste\fR \fIpathName\fR


.SO
\-background	\-highlightthickness	\-relief
\-borderwidth	\-insertbackground	\-selectbackground
\-cursor	\-insertborderwidth	\-selectborderwidth
\-exportselection	\-insertofftime	\-selectforeground
\-font	\-insertontime	\-setgrid
\-foreground	\-insertwidth	\-takefocus
\-highlightbackground	\-padx	\-xscrollcommand
\-highlightcolor	\-pady	\-yscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-autoseparators autoSeparators AutoSeparators
Specifies a boolean that says whether separators are automatically inserted in
the undo stack. Only meaningful when the \fB\-undo\fR option is true.
.OP \-blockcursor blockCursor BlockCursor
Specifies a boolean that says whether the blinking insertion cursor should be
drawn as a character-sized rectangular block. If false (the default) a thin
vertical line is used for the insertion cursor.




























.OP \-endline endLine EndLine





Specifies an integer line index representing the line of the underlying
textual data store that should be just after the last line contained in
the widget. This allows a text widget to reflect only a portion of a
larger piece of text. Instead of an integer, the empty string can be
provided to this configuration option, which will configure the widget
to end at the very last line in the textual data store.

.OP \-height height Height
Specifies the desired height for the window, in units of characters in the
font given by the \fB\-font\fR option. Must be at least one.
.OP \-inactiveselectbackground inactiveSelectBackground Foreground
Specifies the colour to use for the selection (the \fBsel\fR tag) when the
window does not have the input focus. If empty, \fB{}\fR, then no selection is
shown when the window does not have the focus.



































































































































.OP \-insertunfocussed insertUnfocussed InsertUnfocussed
.VS 8.6
Specifies how to display the insertion cursor when the widget does not have
the focus. Must be \fBnone\fR (the default) which means to not display the
cursor, \fBhollow\fR which means to display a hollow box, or \fBsolid\fR which
means to display a solid box. Note that \fBhollow\fR and \fBsolid\fR will
appear very similar when the \fB\-blockcursor\fR option is false.
.VE 8.6














































.OP \-maxundo maxUndo MaxUndo
Specifies the maximum number of compound undo actions on the undo stack. A
zero or a negative value imply an unlimited undo stack.















































.OP \-spacing1 spacing1 Spacing1
Requests additional space above each text line in the widget, using any of the
standard forms for screen distances. If a line wraps, this option only applies
to the first line on the display. This option may be overridden with
\fB\-spacing1\fR options in tags.
.OP \-spacing2 spacing2 Spacing2
For lines that wrap (so that they cover more than one line on the display)
this option specifies additional space to provide between the display lines
that represent a single line of text. The value may have any of the standard
forms for screen distances. This option may be overridden with
\fB\-spacing2\fR options in tags.
.OP \-spacing3 spacing3 Spacing3
Requests additional space below each text line in the widget, using any of the
standard forms for screen distances. If a line wraps, this option only applies
to the last line on the display. This option may be overridden with
\fB\-spacing3\fR options in tags.







.OP \-startline startLine StartLine





Specifies an integer line index representing the first line of the underlying
textual data store that should be contained in the widget. This allows a text
widget to reflect only a portion of a larger piece of text. Instead of an
integer, the empty string can be provided to this configuration option, which
will configure the widget to start at the very first line in the textual data
store.

.OP \-state state State
Specifies one of two states for the text: \fBnormal\fR or \fBdisabled\fR. If
the text is disabled then characters may not be inserted or deleted and no
insertion cursor will be displayed, even if the input focus is in the widget.





















































.OP \-tabs tabs Tabs
Specifies a set of tab stops for the window. The option's value consists of a
list of screen distances giving the positions of the tab stops, each of which
is a distance relative to the left edge of the widget (excluding borders,
padding, etc). Each position may optionally be followed in the next list
element by one of the keywords \fBleft\fR, \fBright\fR, \fBcenter\fR, or
\fBnumeric\fR, which specifies how to justify text relative to the tab stop.












|



>


>

>
>

















|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>






>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>
>
>
>
>
>
>

>
>
>
>
>






>

|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
'\"
'\" Copyright (c) 1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH text n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
text, \%tk_mergeRange, \%tk_textCopy, \%tk_textCut, \%tk_textInsert, \%tk_textPaste, \%tk_textRebindMouseWheel, \%tk_textReplace \- Create and manipulate 'text' hypertext editing widgets
.SH SYNOPSIS
.nf
\fBtext\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_mergeRange \fIvarName range\fR
\fBtk_textCopy\fR \fIpathName\fR
\fBtk_textCut\fR \fIpathName\fR
\fBtk_textInsert\fR \fIpathName\fR ?\fB\-hyphentags\fI tagList\fR? \fIindex chars\fR ?\fItagList chars tagList ...\fR?
\fBtk_textPaste\fR \fIpathName\fR
\fBtk_textRebindMouseWheel\fR \fIpathName\fR ?\fIpathName ...\fR?
\fBtk_textReplace\fR \fIpathName\fR ?\fB\-hyphentags\fR \fItagList\fR? \fIindex chars\fR ?\fItagList chars tagList ...\fR?
.SO
\-background	\-highlightthickness	\-relief
\-borderwidth	\-insertbackground	\-selectbackground
\-cursor	\-insertborderwidth	\-selectborderwidth
\-exportselection	\-insertofftime	\-selectforeground
\-font	\-insertontime	\-setgrid
\-foreground	\-insertwidth	\-takefocus
\-highlightbackground	\-padx	\-xscrollcommand
\-highlightcolor	\-pady	\-yscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-autoseparators autoSeparators AutoSeparators
Specifies a boolean that says whether separators are automatically inserted in
the undo stack. Only meaningful when the \fB\-undo\fR option is true.
.OP \-blockcursor blockCursor BlockCursor
Specifies a boolean that says whether the blinking insertion cursor should be
drawn as a character-sized rectangular block. If false (the default) a thin
vertical line is used for the insertion cursor. See section \fBTHE INSERTION CURSOR\fR
for more details.
.OP \-eolchar eolChar EolChar
Specifies the character to use when displaying the end of line symbol
(see option \fB\-showendofline\fR). An empty argument will force the use of
the default symbol (U+00B6 = PILCROW SIGN).
.OP \-eolcolor eolColor EolColor
Specifies the foreground color to use when displaying the end of line symbol
(see option \fB\-showendofline\fR). An empty argument will force the use of
the foreground color (set with \fB\-foreground\fR; this is the default).
.OP \-eotchar eotChar EotChar
Specifies the character to use when displaying the end of text symbol
(see option \fB\-showendoftext\fR). An empty argument will force the use of
the same symbol as used for showing the end of line symbol (see \fB\-eolchar\fR).
.OP \-eotcolor eotColor EotColor
Specifies the foreground color to use when displaying the end of text symbol
(see option \fB\-showendoftext\fR). An empty argument will force the use
of the same color as used for the end of line symbol (see \fB\-eolcolor\fR).
.OP \-hyphencolor hyphenColor HyphenColor
Specifies the foreground color to use when displaying the soft hyphen
character (U+00AD). An empty argument will force the use of the foreground
color (set with \fB\-foreground\fR; this is the default).
.OP \-endindex endIndex EndIndex
Specifies an index representing the end of the underlying textual data store
that should be contained in the widget. This allows a text widget to reflect
only a portion of a larger piece of text. Instead of an index, the empty string
can be provided to this configuration option, which will configure the widget
to the end index in the textual data store. Instead of an empty string the
special index specifier \fBend\fR can be used.
.OP \-endline endLine EndLine
Note that this option is deprecated, option \fB\-endindex\fR should be used
instead. For compatibility reasons this option still will be supported, but
may be removed in a future version.
.PP
.RS
Specifies an integer line index representing the line of the underlying
textual data store that should be just after the last line contained in
the widget. This allows a text widget to reflect only a portion of a
larger piece of text. Instead of an integer, the empty string can be
provided to this configuration option, which will configure the widget
to end at the very last line in the textual data store.
.RE
.OP \-height height Height
Specifies the desired height for the window, in units of characters in the
font given by the \fB\-font\fR option. Must be at least one.
.OP \-inactiveselectbackground inactiveSelectBackground Foreground
Specifies the colour to use for the selection (the \fBsel\fR tag) when the
window does not have the input focus. If empty, \fB{}\fR, then no selection is
shown when the window does not have the focus.
.OP \-inactiveselectforeground inactiveSelectForeground Foreground
Specifies the foreground colour to use for the selection (the \fBsel\fR tag)
when the window does not have the input focus. If empty, \fB{}\fR, then the
colour specified with widget option \fB\-selectforeground\fR will be used.
.OP \-hyphenrules hyphenRules HyphenRules
Specifies a list of spelling change rules for hyphenated words, given by the
identifier of the rules. Only the rules given with this set will be used for
spelling changes. Per default the set of rules is empty, this means that all
rules are allowed. The rules are important when command \%\fBtk_textInsert\fR
(or \%\fBtk_textReplace\fR) will be used with automatic spelling changes. An
exception will be thrown if one of the given rules is not defined. See
section for more details \fBHYPHENATION RULES\fR about the defined rules.
.RS
.PP
If also option \fB\-lang\fR is specified for a particular soft hyphen, then
only the rules belonging to this language will be applied to this soft
hyphen. This supports simpler hyphenators, not knowing spelling changes.
.PP
This is the way how the hyphen rules will be applied (
.QW "\e+"
denotes the soft hyphen character):
.IP "\fBck\fR"
If the soft hyphen is the right neighbor of character
.QW c ,
and the right neighbor is character
.QW k ,
then the \fBck\fR hyphenation rule will be
applied to this hyphen. Example: the German word
.QW Druc\e+ker
hyphenates into
.QW Druk-ker .
This rule belongs to language German (de).
.IP "\fBgemination\fR"
If the soft hyphen is the left neighbor of a geminated letter 'l' (or 'L'),
then the \fBgemination\fR hyphenation rule will be applied. Example: the
Catalan word
.QW para\e+l\N'183'lel
hyphenates into
.QW paral-lel .
This rule belongs to the Catalan language (ca).
.IP "\fBdoublevowel\fR"
If the soft hyphen is the right neighbor of any vowel, and the right
neighbor is the same vowel, then the \fBdoublevowel\fR hyphenation rule will
be applied to this hyphen. If this vowel is an
.QW e
then a conversion to e-acute will be done. Example: the Dutch word
.QW opaa\e+tje
hyphenates into
.QW opa-tje ,
and
.QW cafee\e+tje
becomes
.QW caf\['e]-tje .
This rule belongs to the Dutch language (nl).
.IP "\fBdoubledigraph\fR"
In Polish language the following spelling change will be applied with this
rule:
.QW c\e+cs
becomes
.QW cs-cs ,
.QW g\e+gy
becomes
.QW gy-gy ,
.QW l\e+ly
becomes
.QW ly-ly ,
.QW n\e+ny
becomes
.QW ny-ny ,
.QW t\e+ty
becomes
.QW ty-ty ,
.QW z\e+zs
becomes
.QW zs-zs ,
and
.QW s\e+sz
becomes
.QW sz-sz .
.IP "\fBrepeathyphen\fR"
In Polish the hyphen will be repeated after line break, this means for
example that
.QW tech\e+nik
becomes
.QW "tech- -nik" .
.IP "\fBtrema\fR"
If the soft hyphen is the right neighbor of any vowel, and the right neighbor
of any vowel with trema (umlaut), then the \fBtrema\fR hyphenation rule will
be applied to this hyphen. Example: the Dutch word
.QW re\e+\[:e]el
hyphenates into
.QW re-eel .
This rule belongs to the Dutch language (nl).
.IP "\fBtripleconsonant\fR"
If the soft hyphen is the right neighbor of a double consonant, and the
right neighbor is the same consonant, and this consonant is followed by a
vowel (or by letter
.QW j
\- Norwegian), then the \fBtripleconsonant\fR
hyphenation rule will be applied when \fBnot\fR hyphenating at this point.
Examples: the German word
.QW Schiff\e+fahrt
hyphenates into
.QW Schiff-fahrt ,
but will be written
.QW Schiffahrt
when no hyphenation will be done. The Swedish word
.QW tugg\e+gummi
becomes
.QW tuggummi ,
and the Norwegian word
.QW buss\e+sj\[oa]f\[/o]r
becomes
.QW "bussj\[oa]f\[/o]r" .
This rule belongs to languages German (de), Norwegian (no, nb, nn), and
Swedish (sv).
.RE
.OP \-hyphens hyphens Hyphens
Specifies a boolean indicating whether the hyphenation support will be
activated. If activated, then in state \fBnormal\fR or \fBreadonly\fR the
soft hyphen (Unicode point U+00AD) \- also called SHY \- will be invisible
unless it is used at line end for displaying a hyphen character in case of
dividing a word for line adjusting. If the widget is in state \fBnormal\fR
then the hyphen will be displayed like a normal character (with codepoint
U+2010), it will not be used for hyphenation (but may be used for line
wrapping, depending on the value of option \fB\-wrap\fR).
.OP \-insertforeground insertForeground InsertForeground
Specifies the color to use as foreground for the characters in the area
covered by the insertion cursor. This color will not be overridden with
tagging options. Note that this color will not be used unless option
\fB\-showinsertforeground\fR is enabled.
.OP \-insertunfocussed insertUnfocussed InsertUnfocussed
.VS 8.6
Specifies how to display the insertion cursor when the widget does not have
the focus. Must be \fBnone\fR (the default) which means to not display the
cursor, \fBhollow\fR which means to display a hollow box, or \fBsolid\fR which
means to display a solid box. Note that \fBhollow\fR and \fBsolid\fR will
appear very similar when the \fB\-blockcursor\fR option is false.
.VE 8.6
.OP \-justify justify Justify
Setting the style how lines will be justified. This style will be used for
the whole text, even for wrapped lines, but tags may override this style for
individual lines.
.RS
.PP
The following styles are possible:
.IP "\fBleft\fR"
The text is aligned along the left margin. This is the default.
.IP "\fBright\fR"
The text is aligned along the right margin.
.IP "\fBfull\fR"
The text is aligned along the left margin, and word-spacing is adjusted so
that the text flush with both margins.
.IP "\fBcenter\fR"
The text is aligned to neither the left nor the right margin, there is an
even gap on each side of each line.
.RE
.OP \-lang lang Lang
Setting the language code of the text content. The language code will be
used for line breaking (but only if option \fB\-useunibreak\fR is also set),
and it may be used to restrict the hyphenation rules (see
\fB\-hyphenrules\fR). An empty string is unsetting the language.
.RS
.PP
The language code will be specified as ISO 639-1 code. The language code
will not be verified, but it must be a string with two consecutive lowercase
letters (for example
.QW en
), or an empty string, otherwise an error will be thrown.
.RE
.OP \-maxredo maxRedo MaxRedo
Specifies the maximum number of redo actions on the undo stack. A zero value
will prevent any redo action, only undoes are possible. A negative value
imply an unlimited number of redo actions (this is the default; note that
the number of redo actions is always bound by the number of undo actions on
the stack). Setting a lower positive value (including zero) than the
previous (positive) number will reduce the redo stack immediately.
.RS
.PP
This option is especially useful for setting an undo stack without redo
capability; this means that in practice normally only the values -1 and 0
(zero) are useful (redo capability is on or off). When using a value greater
than zero, mind that as soon as the redo stack size exceeds, all the redo
items on the stack must expire (and will be deleted).
.RE
.OP \-maxundo maxUndo MaxUndo
Specifies the maximum number of compound undo actions on the undo stack. A
zero or a negative value imply an unlimited number of compound undo actions.
Setting a lower value (greater than zero) than the previous (positive)
number will reduce the stack immediately.
.OP \-maxundosize maxUndoSize MaxUndoSize
Specifies the maximal number of bytes stored on the undo stack, only
characters will be counted (the byte size of the characters), and also
embedded images and windows (each embedded item will be count with byte size
one). A zero or a negative value imply an unlimited number of bytes. If a
positive (non-zero) number of bytes is defined, option \fB\-maxundosize\fR
will have a higher priority than option \fB\-maxundo\fR. Setting a number of
bytes less than the number of bytes currently kept on the stack will not
immediately reduce the stack.
.OP \-responsiveness responsiveness Responsiveness
Specifies the delay before the widget will repick (sending
enter/leave/motion events when entering/leaving/hovering tagged regions)
after scroll operations. The default value is 50 milliseconds. When setting
the value to zero (or less than zero) the repick will be done immediately.
The higher the responsiveness, the less the display will flicker while the
widget is scrolling.
.OP \-showendofline showEndOfLine ShowEndOfLine
Specifies a boolean value determining whether manual line breaks (
.QW \en
) will be emphasized with an end of line symbol (default is U+00B6 =
PILCROW SIGN) at the end of the line, in this case that symbol does not
belong to the text content and cannot be edited or selected. Per default the
end of line symbol will not be shown.
.OP \-showendoftext showEndOfText ShowEndOfText
If this option is enabled the end of the text (after end of very last line)
will be emphasized with an end of text symbol (per default this is the end of
line symbol). This symbol does not belong to the text content and cannot
be edited or selected. Per default the end of text symbol will not be shown.
.OP \-showinsertforeground showInsertForeground ShowInsertForeground
Use color option \fB\-insertforeground\fR for the foreground of characters
covered by the insert cursor if this option is enabled, otherwise the color
of the characters will not change when coverd by the insertion cursor. Per
default this option is disabled.
.OP \-spacemode spaceMode SpaceMode
Specifies the mode how spaces (U+0020) will be displayed. Default is
\fBnone\fR, this means that spaces will be displayed like any character, but
when breaking lines at a space this space will be gobbled if option
\fB\-wrap\fR is set to \fBword\fR or \fBcodepoint\fR (this is the common
behavior of text editors). When setting to \fBexact\fR, no space character
will be gobbled at all, even when breaking lines. Mode \fBtrim\fR may be
used for trimming consecutive space characters, but a single space will
never be trimmed, instead it will be gobbled when a line break happens at
this space (if option \fB\-wrap\fR is set to \fBword\fR or \fBcodepoint\fR).
Normally mode \fBtrim\fR will not be used in conjunction with state
\fBnormal\fR (see option \fB\-state\fR).
.OP \-spacing1 spacing1 Spacing1
Requests additional space above each text line in the widget, using any of the
standard forms for screen distances. If a line wraps, this option only applies
to the first line on the display. This option may be overridden with
\fB\-spacing1\fR options in tags.
.OP \-spacing2 spacing2 Spacing2
For lines that wrap (so that they cover more than one line on the display)
this option specifies additional space to provide between the display lines
that represent a single line of text. The value may have any of the standard
forms for screen distances. This option may be overridden with
\fB\-spacing2\fR options in tags.
.OP \-spacing3 spacing3 Spacing3
Requests additional space below each text line in the widget, using any of the
standard forms for screen distances. If a line wraps, this option only applies
to the last line on the display. This option may be overridden with
\fB\-spacing3\fR options in tags.
.OP \-startindex startIndex StartIndex
Specifies an index representing the start of the underlying textual data store
that should be contained in the widget. This allows a text widget to reflect only
a portion of a larger piece of text. Instead of an index, the empty string can be
provided to this configuration option, which will configure the widget to the
start index in the textual data store. Instead of an empty string the special
index specifier \fBbegin\fR can be used.
.OP \-startline startLine StartLine
Note that this option is deprecated, option \fB\-startindex\fR should be used
instead. For compatibility reasons this option still will be supported, but
may be removed in a future version.
.PP
.RS
Specifies an integer line index representing the first line of the underlying
textual data store that should be contained in the widget. This allows a text
widget to reflect only a portion of a larger piece of text. Instead of an
integer, the empty string can be provided to this configuration option, which
will configure the widget to start at the very first line in the textual data
store.
.RE
.OP \-state state State
Specifies one of three states for the text: \fBnormal\fR, \fBdisabled\fR, or
\fBreadonly\fR. If the text is disabled then characters may not be inserted
or deleted and no insertion cursor will be displayed, even if the input
focus is in the widget. If the state is readonly then characters can be
inserted and deleted, but the widget does not receive any modifications from
GUI, the user cannot delete or insert, and no insertion cursor will be
displayed.
.RS
.PP
When hyphenation support is enabled (widget option \fB\-hyphens\fR)
switching the state to \fBnormal\fR is re-displaying the text content
without the use of soft hyphens for line break. Switching the state back to
\fBreadonly\fR, or \fBdisabled\fR, is re-displaying the content regarding
soft hyphens for possible line breaks.
.RE
.OP \-steadymarks steadyMarks SteadyMarks
This option, if activated, will change the behavior of marks. Every mark now
behaves simultaneously as an invisible character. One side effect is
that the gravity will also apply to the insertion of marks. Another side
effect is that every reference specified by a mark now will reference the
pseudo-character position of that mark. (But it is important to mention
that the real character position count will not be affected.)
.RS
.PP
The change of this behavior will apply to all peers of this widget, it's not
possible to have a different behavior in different peers.
.PP
This option cannot be set if the widget is not overall clean (see command
\fBisclean \-overall\fR), an error will be thrown if this is not satisified.
(It is not useful to switch this option, or setting this option, if the
widget is not overall clean, this may cause errors in the order of the
marks, therefore this is forbidden.)
.PP
This option is facilitating programmed editor control, because the shuffle
effect is eliminated, every mark now has a defined order relative to other
marks, this order is not changing as long as the mark will not be moved with
\fBmark set\fR. Note that the handling of marks, especially the change of
the gravity, will be performed more efficiently when this option is
activated.
.RE
.OP \-synctime syncTime SyncTime
Specifies the timeout in milliseconds of the asynchronous line metrics
calculation after any change which is affecting the geometry. Note that the
calculation will be splitted into short line ranges (except if timeout is
zero). The default value is 150 and will be changed only in seldom cases.
For most applications this value offers a good responsiveness, and gives the
impression of a better performance, compared to the behavior with a low
timeout.
.RS
.PP
When set to zero the line metrics update will be performed synchronous; this
means the whole update will be performed immediately; with most applications
this behavior would cause performance problems. When set to 1 the
computation is already asynchronous, but the computation starts with each
event loop cycle (this may also cause performance problems).
.RE
.OP \-tabs tabs Tabs
Specifies a set of tab stops for the window. The option's value consists of a
list of screen distances giving the positions of the tab stops, each of which
is a distance relative to the left edge of the widget (excluding borders,
padding, etc). Each position may optionally be followed in the next list
element by one of the keywords \fBleft\fR, \fBright\fR, \fBcenter\fR, or
\fBnumeric\fR, which specifies how to justify text relative to the tab stop.
129
130
131
132
133
134
135
























136
137





138
139
140
141
142
143















144
145
146
147
148

149
150
151
152











153
154
155
156
157
158
159
character in the line's text will be associated with the \fIn\fR'th tab stop
defined for that line. If the tab character's x coordinate falls to the right
of the \fIn\fR'th tab stop, then a gap of a single space will be inserted as a
fallback. If the tab style is \fBwordprocessor\fR then any tab character being
laid out will use (and be defined by) the first tab stop to the right of the
preceding characters already laid out on that line. The value of the
\fB\-tabstyle\fR option may be overridden by \fB\-tabstyle\fR options in tags.
























.OP \-undo undo Undo
Specifies a boolean that says whether the undo mechanism is active or not.





.OP \-width width Width
Specifies the desired width for the window in units of characters in the font
given by the \fB\-font\fR option. If the font does not have a uniform width
then the width of the character
.QW 0
is used in translating from character units to screen units.















.OP \-wrap wrap Wrap
Specifies how to handle lines in the text that are too long to be displayed in
a single line of the text's window. The value must be \fBnone\fR or \fBchar\fR
or \fBword\fR. A wrap mode of \fBnone\fR means that each line of text appears
as exactly one line on the screen; extra characters that do not fit on the

screen are not displayed. In the other modes each line of text will be broken
up into several screen lines if necessary to keep all the characters visible.
In \fBchar\fR mode a screen line break may occur after any character; in
\fBword\fR mode a line break will only be made at word boundaries.











.BE
.SH DESCRIPTION
.PP
The \fBtext\fR command creates a new window (given by the \fIpathName\fR
argument) and makes it into a text widget. Additional options, described
above, may be specified on the command line or in the option database to
configure aspects of the text such as its default background color and relief.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
|
|
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
character in the line's text will be associated with the \fIn\fR'th tab stop
defined for that line. If the tab character's x coordinate falls to the right
of the \fIn\fR'th tab stop, then a gap of a single space will be inserted as a
fallback. If the tab style is \fBwordprocessor\fR then any tab character being
laid out will use (and be defined by) the first tab stop to the right of the
preceding characters already laid out on that line. The value of the
\fB\-tabstyle\fR option may be overridden by \fB\-tabstyle\fR options in tags.
.OP \-tagging tagging Tagging
Setting the mode how characters will be tagged when inserting text without
explicit tagging information.
.RS
.PP
The following modes are defined:
.IP "\fBwithin\fR"
The new text will receive any tags that are present on both before and after
the insertion point, regardless whether it's a character (including the
invisible newline), a soft hyphen, an embedded window, or an embedded image;
if a tag is present on only one of these characters (windows, or images)
then it will not be applied to the new text. This is the default tagging
mode (and the way how the older versions of the text widget worked).
.IP "\fBgravity\fR"
The new text will receive any tags that are present at one side of the
insertion point: if the insert cursor has right gravity then the text will
receive the tags of the character after the insertion point (including the
invisible newline), otherwise, if the insertion cursor has left gravity, it
will receive the tags of the character before the insertion point (Arabian
mode), but only if a preceding character exists in this line. This mode is
commonly used in some text editors.
.IP "\fBnone\fR"
The new text will not receive any tags from surrounded text.
.RE
.OP \-undo undo Undo
Specifies a boolean that says whether the undo mechanism is active or not.
.OP \-undotagging undoTagging UndoTagging
This boolean value specifies the setup value for \fB-undo\fR option when
creating tags. Per default the setup value is \fItrue\fR. Note that this
value will not be used for the special tag \fBsel\fR. See description of
tag option \fB-undo\fR for more information.
.OP \-width width Width
Specifies the desired width for the window in units of characters in the font
given by the \fB\-font\fR option. If the font does not have a uniform width
then the width of the character
.QW 0
is used in translating from character units to screen units.
.OP \-useunibreak useUniBreak UseUniBreak
If this option is enabled then wrap mode \fBcodepoint\fR (see option
\fB\-wrap\fR) will use the external library \fIlibunibreak\fR (from Wu Yongwei)
for the computation of line breaks, but only if this library is available
(currently only UNIX). This library even supports language dependent line
breaking. Otherwise, if this option is not enabled, or if \fIlibunibreak\fR is not
available, a simpler algorithm (also based on the recommendations of the
Unicode consortium, but restricted to Latin-1 and most non-language
dependent characters, without regarding combined marks, and without language
support) will be used for the computation of the breaks. Per default this
option is not enabled.
.RS
.PP
For a simple test whether the unibreak libary is available see command \fBbrks\fR.
.RE
.OP \-wrap wrap Wrap
Specifies how to handle lines in the text that are too long to be displayed
in a single line of the text's window. The value must be \fBnone\fR,
\fBchar\fR, \fBword\fR, or \fBcodepoint\fR. A wrap mode of \fBnone\fR means
that each line of text appears as exactly one line on the screen; extra
characters that do not fit on the screen are not displayed. In the other
modes each line of text will be broken up into several screen lines if
necessary to keep all the characters visible. In \fBchar\fR mode a screen
line break may occur after any character; in \fBword\fR mode a line break
will only be made at word boundaries. The elaborated mode \fBcodepoint\fR is
based on Unicode code points, and conforms exactly (with \fIlibunibreak\fR) or
mostly (with internal algorithm) to the recommendations of the Unicode
consortium. If option \fB\-useunibreak\fR is set, then the unibreak library
(from Wu Yongwei) will be used for the line break computation. This library
even supports language dependent line breaking (see option \fB\-lang\fR for
language support). Otherwise, if \fB\-useunibreak\fR is not set, or if the
unibreak library is not available, a simpler algorithm \- also based on the
recommendations of the Unicode consortium, but restricted to Latin-1 and
most non-language dependent characters, without regarding combined marks,
and without language support \- will be used for the computation of the
breaks.
.BE
.SH DESCRIPTION
.PP
The \fBtext\fR command creates a new window (given by the \fIpathName\fR
argument) and makes it into a text widget. Additional options, described
above, may be specified on the command line or in the option database to
configure aspects of the text such as its default background color and relief.
186
187
188
189
190
191
192

193
194
195

196
197
198
199
200
201
202
See \fBPEER WIDGETS\fR below for more details.
.SH INDICES
.PP
Many of the widget commands for texts take one or more indices as arguments.
An index is a string used to indicate a particular place within a text, such
as a place to insert characters or one endpoint of a range of characters to
delete. Indices have the syntax

.CS
\fIbase modifier modifier modifier ...\fR
.CE

Where \fIbase\fR gives a starting point and the \fImodifier\fRs adjust the
index from the starting point (e.g. move forward or backward one character).
Every index must contain a \fIbase\fR, but the \fImodifier\fRs are optional.
Most modifiers (as documented below) allow an optional submodifier. Valid
submodifiers are \fBany\fR and \fBdisplay\fR. If the submodifier is
abbreviated, then it must be followed by whitespace, but otherwise there need
be no space between the submodifier and the following \fImodifier\fR.







>



>







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
See \fBPEER WIDGETS\fR below for more details.
.SH INDICES
.PP
Many of the widget commands for texts take one or more indices as arguments.
An index is a string used to indicate a particular place within a text, such
as a place to insert characters or one endpoint of a range of characters to
delete. Indices have the syntax
.PP
.CS
\fIbase modifier modifier modifier ...\fR
.CE
.PP
Where \fIbase\fR gives a starting point and the \fImodifier\fRs adjust the
index from the starting point (e.g. move forward or backward one character).
Every index must contain a \fIbase\fR, but the \fImodifier\fRs are optional.
Most modifiers (as documented below) allow an optional submodifier. Valid
submodifiers are \fBany\fR and \fBdisplay\fR. If the submodifier is
abbreviated, then it must be followed by whitespace, but otherwise there need
be no space between the submodifier and the following \fImodifier\fR.
212
213
214
215
216
217
218
219

220
221
222
223
224
225




226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
















245
246
247
248
249
250
251
The \fIbase\fR for an index must have one of the following forms:
.TP 12
\fIline\fB.\fIchar\fR
.
Indicates \fIchar\fR'th character on line \fIline\fR. Lines are numbered from
1 for consistency with other UNIX programs that use this numbering scheme.
Within a line, characters are numbered from 0. If \fIchar\fR is \fBend\fR then
it refers to the newline character that ends the line.

.TP 12
\fB@\fIx\fB,\fIy\fR
.
Indicates the character that covers the pixel whose x and y coordinates within
the text's window are \fIx\fR and \fIy\fR.
.TP 12




\fBend\fR
.
Indicates the end of the text (the character just after the last newline).
.TP 12
\fImark\fR
.
Indicates the character just after the mark whose name is \fImark\fR.

.TP 12
\fItag\fB.first\fR
.
Indicates the first character in the text that has been tagged with \fItag\fR.
This form generates an error if no characters are currently tagged with
\fItag\fR.
.TP 12
\fItag\fB.last\fR
.
Indicates the character just after the last one in the text that has been
tagged with \fItag\fR. This form generates an error if no characters are
currently tagged with \fItag\fR.
















.TP 12
\fIpathName\fR
.
Indicates the position of the embedded window whose name is \fIpathName\fR.
This form generates an error if there is no embedded window by the given name.
.TP 12
\fIimageName\fR







|
>






>
>
>
>






|
>












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
The \fIbase\fR for an index must have one of the following forms:
.TP 12
\fIline\fB.\fIchar\fR
.
Indicates \fIchar\fR'th character on line \fIline\fR. Lines are numbered from
1 for consistency with other UNIX programs that use this numbering scheme.
Within a line, characters are numbered from 0. If \fIchar\fR is \fBend\fR then
it refers to the newline character that ends the line, and if \fIchar\fR is \fBbegin\fR
then it refers the first character at start of the line.
.TP 12
\fB@\fIx\fB,\fIy\fR
.
Indicates the character that covers the pixel whose x and y coordinates within
the text's window are \fIx\fR and \fIy\fR.
.TP 12
\fBbegin\fR
.
Indicates the start of the text (the character just at the start of the first line).
.TP 12
\fBend\fR
.
Indicates the end of the text (the character just after the last newline).
.TP 12
\fImark\fR
.
Indicates the character just after the mark whose name is \fImark\fR (see
\fBMARKS\fR for details).
.TP 12
\fItag\fB.first\fR
.
Indicates the first character in the text that has been tagged with \fItag\fR.
This form generates an error if no characters are currently tagged with
\fItag\fR.
.TP 12
\fItag\fB.last\fR
.
Indicates the character just after the last one in the text that has been
tagged with \fItag\fR. This form generates an error if no characters are
currently tagged with \fItag\fR.
.TP 12
\fItag\fB.current.first\fR
.
Indicates the first character in the region (a connected span of text sharing
the same \fItag\fR) nearby the current mark (it is left from, right from,
or inside the tagged region) that has been tagged with \fItag\fR. This form
generates an error if no character is currently tagged with \fItag\fR
nearby the current mark.
.TP 12
\fItag\fB.current.last\fR
.
Indicates the character just after the last one in the region (a connected span
of text sharing the same \fItag\fR) nearby the current mark (it is left from,
right from, or inside the tagged region) that has been tagged with \fItag\fR.
This form generates an error if no character is currently tagged with \fItag\fR
nearby the current mark.
.TP 12
\fIpathName\fR
.
Indicates the position of the embedded window whose name is \fIpathName\fR.
This form generates an error if there is no embedded window by the given name.
.TP 12
\fIimageName\fR
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319


320



321
322
323

324
325
326
327
328
329
330
331
332
333
334


335



336
337
338
339


340
341
342
343
344
345
346
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.
Adjust the index forward by \fIcount\fR characters, moving to later lines in
the text if necessary. If there are fewer than \fIcount\fR characters in the
text after the current index, then set the index to the last index in the
text. Spaces on either side of \fIcount\fR are optional. If the \fBdisplay\fR
submodifier is given, elided characters are skipped over without being
counted. If \fBany\fR is given, then all characters are counted. For
historical reasons, if neither modifier is given then the count actually takes
place in units of index positions (see \fBINDICES\fR for details). This
behaviour may be changed in a future major release, so if you need an index
count, you are encouraged to use \fBindices\fR instead wherever possible.
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.
Adjust the index backward by \fIcount\fR characters, moving to earlier lines
in the text if necessary. If there are fewer than \fIcount\fR characters in
the text before the current index, then set the index to the first index in
the text (1.0). Spaces on either side of \fIcount\fR are optional. If the
\fBdisplay\fR submodifier is given, elided characters are skipped over without
being counted. If \fBany\fR is given, then all characters are counted. For
historical reasons, if neither modifier is given then the count actually takes
place in units of index positions (see \fBINDICES\fR for details). This
behavior may be changed in a future major release, so if you need an index
count, you are encouraged to use \fBindices\fR instead wherever possible.
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.
Adjust the index forward by \fIcount\fR index positions, moving to later lines
in the text if necessary. If there are fewer than \fIcount\fR index positions
in the text after the current index, then set the index to the last index
position in the text. Spaces on either side of \fIcount\fR are optional. Note
that an index position is either a single character or a single embedded image
or embedded window. If the \fBdisplay\fR submodifier is given, elided indices
are skipped over without being counted. If \fBany\fR is given, then all
indices are counted; this is also the default behaviour if no modifier is
given.
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.
Adjust the index backward by \fIcount\fR index positions, moving to earlier
lines in the text if necessary. If there are fewer than \fIcount\fR index
positions in the text before the current index, then set the index to the
first index position (1.0) in the text. Spaces on either side of \fIcount\fR
are optional. If the \fBdisplay\fR submodifier is given, elided indices are
skipped over without being counted. If \fBany\fR is given, then all indices
are counted; this is also the default behaviour if no modifier is given.
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.
Adjust the index forward by \fIcount\fR lines, retaining the same character
position within the line. If there are fewer than \fIcount\fR lines after the
line containing the current index, then set the index to refer to the same
character position on the last line of the text. Then, if the line is not long
enough to contain a character at the indicated character position, adjust the
character position to refer to the last character of the line (the newline).
Spaces on either side of \fIcount\fR are optional. If the \fBdisplay\fR


submodifier is given, then each visual display line is counted separately.



Otherwise, if \fBany\fR (or no modifier) is given, then each logical line (no
matter how many times it is visually wrapped) counts just once. If the
relevant lines are not wrapped, then these two methods of counting are

equivalent.
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.
Adjust the index backward by \fIcount\fR logical lines, retaining the same
character position within the line. If there are fewer than \fIcount\fR lines
before the line containing the current index, then set the index to refer to
the same character position on the first line of the text. Then, if the line
is not long enough to contain a character at the indicated character position,
adjust the character position to refer to the last character of the line (the
newline). Spaces on either side of \fIcount\fR are optional. If the


\fBdisplay\fR submodifier is given, then each visual display line is counted



separately. Otherwise, if \fBany\fR (or no modifier) is given, then each
logical line (no matter how many times it is visually wrapped) counts just
once. If the relevant lines are not wrapped, then these two methods of
counting are equivalent.


.TP
?\fIsubmodifier\fR? \fBlinestart\fR
.
Adjust the index to refer to the first index on the line. If the \fBdisplay\fR
submodifier is given, this is the first index on the display line, otherwise
on the logical line.
.TP







|
<
<
<
<








|
<
<
<
<










|










|



|
|

|
|
|
|
>
>
|
>
>
>
|
|
<
>
|




|
|
|
|
|
|
>
>
|
>
>
>
|
|
<
<
>
>







671
672
673
674
675
676
677
678




679
680
681
682
683
684
685
686
687




688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747


748
749
750
751
752
753
754
755
756
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.
Adjust the index forward by \fIcount\fR characters, moving to later lines in
the text if necessary. If there are fewer than \fIcount\fR characters in the
text after the current index, then set the index to the last index in the
text. Spaces on either side of \fIcount\fR are optional. If the \fBdisplay\fR
submodifier is given, elided characters are skipped over without being
counted. If \fBany\fR is given, then all characters are counted.




.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBchars\fR
.
Adjust the index backward by \fIcount\fR characters, moving to earlier lines
in the text if necessary. If there are fewer than \fIcount\fR characters in
the text before the current index, then set the index to the first index in
the text (1.0). Spaces on either side of \fIcount\fR are optional. If the
\fBdisplay\fR submodifier is given, elided characters are skipped over without
being counted. If \fBany\fR is given, then all characters are counted.




.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.
Adjust the index forward by \fIcount\fR index positions, moving to later lines
in the text if necessary. If there are fewer than \fIcount\fR index positions
in the text after the current index, then set the index to the last index
position in the text. Spaces on either side of \fIcount\fR are optional. Note
that an index position is either a single character or a single embedded image
or embedded window. If the \fBdisplay\fR submodifier is given, elided indices
are skipped over without being counted. If \fBany\fR is given, then all
indices are counted; this is also the default behavior if no modifier is
given.
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBindices\fR
.
Adjust the index backward by \fIcount\fR index positions, moving to earlier
lines in the text if necessary. If there are fewer than \fIcount\fR index
positions in the text before the current index, then set the index to the
first index position (1.0) in the text. Spaces on either side of \fIcount\fR
are optional. If the \fBdisplay\fR submodifier is given, elided indices are
skipped over without being counted. If \fBany\fR is given, then all indices
are counted; this is also the default behavior if no modifier is given.
.TP
\fB+ \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.
Adjust the index forward by \fIcount\fR lines, retaining the same position
within the line. If there are fewer than \fIcount\fR lines after the
line containing the current index, then set the index to refer to the same
position on the last line of the text. Then, if the line is not long enough
to contain a character at the indicated position, adjust the character position
to refer to the last character of the line (the newline). Spaces on either side
of \fIcount\fR are optional.
.RS
.PP
If the \fBdisplay\fR submodifier is given, then each visual display line is
counted separately, and in this case the position is determined by the
current pixel position.
.PP
Otherwise, if \fBany\fR (or no modifier) is given, then each logical line
(no matter how many times it is visually wrapped) counts just once, and the

position is determined by the character position.
.RE
.TP
\fB\- \fIcount\fR ?\fIsubmodifier\fR? \fBlines\fR
.
Adjust the index backward by \fIcount\fR logical lines, retaining the same
position within the line. If there are fewer than \fIcount\fR lines before
the line containing the current index, then set the index to refer to the
same position on the first line of the text. Then, if the line is not long
enough to contain a character at the indicated position, adjust the character
position to refer to the last character of the line (the newline). Spaces
on either side of \fIcount\fR are optional.
.RS
.PP
If the \fBdisplay\fR submodifier is given, then each visual display line is
counted separately, and in this case the character position is determined
by the current pixel position.
.PP
Otherwise, if \fBany\fR (or no modifier) is given, then each logical line
(no matter how many times it is visually wrapped) counts just once, and the


character position is determined by the index position.
.RE
.TP
?\fIsubmodifier\fR? \fBlinestart\fR
.
Adjust the index to refer to the first index on the line. If the \fBdisplay\fR
submodifier is given, this is the first index on the display line, otherwise
on the logical line.
.TP
386
387
388
389
390
391
392






393
394
395
396
397

398
399
400
401
402
403
404
.SH TAGS
.PP
The first form of annotation in text widgets is a tag. A tag is a textual
string that is associated with some of the characters in a text. Tags may
contain arbitrary characters, but it is probably best to avoid using the
characters
.QW " "






(space), \fB+\fR, or \fB\-\fR: these characters have special meaning in
indices, so tags containing them cannot be used as indices. There may be any
number of tags associated with characters in a text. Each tag may refer to a
single character, a range of characters, or several ranges of characters. An
individual character may have any number of tags associated with it.

.PP
A priority order is defined among tags, and this order is used in implementing
some of the tag-related functions described below. When a tag is defined (by
associating it with characters or setting its display options or binding
commands to it), it is given a priority higher than any existing tag. The
priority order of tags may be redefined using the
.QW "\fIpathName \fBtag raise\fR"







>
>
>
>
>
>
|
|
|
|
|
>







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
.SH TAGS
.PP
The first form of annotation in text widgets is a tag. A tag is a textual
string that is associated with some of the characters in a text. Tags may
contain arbitrary characters, but it is probably best to avoid using the
characters
.QW " "
(space),
.QW \fC@\fR ,
.QW \fC.\fR ,
.QW \fC+\fR ,
or
.QW \fC\-\fR :
these characters have special
meaning in indices, so tags containing them cannot be used as indices. There
may be any number of tags associated with characters in a text. Each tag may
refer to a single character, a range of characters, or several ranges of
characters. An individual character may have any number of tags associated
with it.
.PP
A priority order is defined among tags, and this order is used in implementing
some of the tag-related functions described below. When a tag is defined (by
associating it with characters or setting its display options or binding
commands to it), it is given a priority higher than any existing tag. The
priority order of tags may be redefined using the
.QW "\fIpathName \fBtag raise\fR"
432
433
434
435
436
437
438
439
440
441








442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461


































































462
463
464
465
466
467
468







469
470
471
472
473
474
475
.
\fIPixels\fR specifies the width of a border to draw around the tag using any
of the forms accepted by \fBTk_GetPixels\fR. This option should be used in
conjunction with the \fB\-relief\fR option to provide the desired border.
.TP
\fB\-elide \fIboolean\fR
.
\fIElide\fR specifies whether the data should be elided. Elided data
(characters, images, embedded windows, etc.) is not displayed and takes no
space on screen, but further on behaves just as normal data.








.TP
\fB\-fgstipple \fIbitmap\fR
.
\fIBitmap\fR specifies a bitmap that is used as a stipple pattern when drawing
text and other foreground information such as underlines. It may have any of
the forms accepted by \fBTk_GetBitmap\fR. If \fIbitmap\fR has not been
specified, or if it is specified as an empty string, then a solid fill will be
used.
.TP
\fB\-font \fIfontName\fR
.
\fIFontName\fR is the name of a font to use for drawing characters. It may
have any of the forms accepted by \fBTk_GetFont\fR.
.TP
\fB\-foreground \fIcolor\fR
.
\fIColor\fR specifies the color to use when drawing text and other foreground
information such as underlines. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.TP


































































\fB\-justify \fIjustify\fR
.
If the first non-elided character of a display line has a tag for which this
option has been specified, then \fIjustify\fR determines how to justify the
line. It must be one of \fBleft\fR, \fBright\fR, or \fBcenter\fR. If a line
wraps, then the justification for each line on the display is determined by
the first non-elided character of that display line.







.TP
\fB\-lmargin1 \fIpixels\fR
.
If the first non-elided character of a text line has a tag for which this
option has been specified, then \fIpixels\fR specifies how much the line
should be indented from the left edge of the window. \fIPixels\fR may have any
of the standard forms for screen distances. If a line of text wraps, this







|
|
|
>
>
>
>
>
>
>
>




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
|
|
|
>
>
>
>
>
>
>







849
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
.
\fIPixels\fR specifies the width of a border to draw around the tag using any
of the forms accepted by \fBTk_GetPixels\fR. This option should be used in
conjunction with the \fB\-relief\fR option to provide the desired border.
.TP
\fB\-elide \fIboolean\fR
.
\fIElide\fR specifies whether the data should be elided. Elided data (characters,
soft hyphens, images, embedded windows, etc) is not displayed and takes no
space on screen, but further on behaves just as normal data. An empty string
(instead of a boolean value) is clearing the elide option of this tag. It is
not allowed to set this option with the special selection tag \fBsel\fR.
.TP
\fB\-eolcolor \fIcolor\fR
.
Specifies the foreground color to use when displaying the end of line symbol
inside the tagged region. An empty argument will force the use of the
foreground color (set with \fB\-foreground\fR; this is the default).
.TP
\fB\-fgstipple \fIbitmap\fR
.
\fIBitmap\fR specifies a bitmap that is used as a stipple pattern when drawing
text and other foreground information such as underlines. It may have any of
the forms accepted by \fBTk_GetBitmap\fR. If \fIbitmap\fR has not been
specified, or if it is specified as an empty string, then a solid fill will be
used.
.TP
\fB\-font \fIfontName\fR
.
\fIFontName\fR is the name of a font to use for drawing characters. It may
have any of the forms accepted by \fBTk_GetFont\fR.
.TP
\fB\-foreground \fIcolor\fR
.
\fIColor\fR specifies the color to use when drawing text and other foreground
information such as underlines. It may have any of the forms accepted by
\fBTk_GetColor\fR.
.TP
\fB\-hyphencolor \fIcolor\fR
.
Specifies the foreground color to use when displaying the soft hyphen
character (U+00AD) inside the tagged region. An empty argument will force
the use of the foreground color (set with \fB\-foreground\fR; this is the
default).
.TP
\fB\-hyphenrules \fIrules\fR
.
Specifies a list of spelling change rules for hyphenated words, specified by
the identifier of the rules. Only the rules given with this set will be used
for spelling changes. The rules will be applied in the given order of this
list. Per default the set of rules is empty. An exception will be thrown if
one of the given rules is not defined.
.RS
.PP
This tag option overrules the global option \fB\-hyphenrules\fR, this means
that the global rules will be applied only to hyphens without tagged rules.
.PP
For the definition of hyphenation rules see widget option
\fB\-hyphenrules\fR.
.RE
.TP
\fB\-inactivebackground \fIcolor\fR
.
Color specifies the background color to use for characters associated with the
tag, when the window does not have the focus.
It may have any of the forms accepted by Tk_GetColor.
If specified then it will overrule the \fB\-background\fR option of the
\fBsel\fR tag, provided that the actual tag has a higher priority.
.TP
\fB\-inactiveforeground \fIcolor\fR
.
Color specifies the color to use when drawing text and other foreground
information such as underlines, when the window does not have the focus.
It may have any of the forms accepted by Tk_GetColor.
If specified then it will overrule the \fB\-foreground\fR option of the
\fBsel\fR tag, provided that the actual tag has a higher priority.
.TP
\fB\-inactiveselectbackground \fIcolor\fR
.
\fIColor\fR specifies the background color to use when displaying selected
items, when the window does not have the focus.
It may have any of the forms accepted by \fBTk_GetColor\fR.
If \fIcolor\fR has not been specified, or if it is specified as an empty string,
then the color specified by the \fB\-selectbackground\fR tag option is used.
If specified then it will overrule the \fB\-inactivebackground\fR option of the
\fBsel\fR tag, provided that the actual tag has a higher priority.
.TP
\fB\-inactiveselectforeground \fIcolor\fR
.
\fIColor\fR specifies the foreground color to use when displaying selected
items, when the window does not have the focus.
It may have any of the forms accepted by \fBTk_GetColor\fR.
If \fIcolor\fR has not been specified, or if it is specified as an empty string,
then the color specified by the \fB\-selectforeground\fR tag option is used.
If specified then it will overrule the \fB\-inactiveforeground\fR option of the
\fBsel\fR tag, provided that the actual tag has a higher priority.
.TP
\fB\-indentbackground \fIboolean\fR
.
If true then the background, set with \fB\-background\fR tag option, will be
indented according to the \fB\-lmargin1\fR, and \fB\-lmargin2\fR tag
options. This has the (intended) side effect that hovering the margin (left
from indented text) will not trigger events.
.TP
\fB\-justify \fIjustify\fR
.
If the first non-elided character of a display line has a tag for which this
option has been specified, then justify determines how to justify the line.
It must be one of \fBleft\fR, \fBright\fR, \fBfull\fR, or \fBcenter\fR. If a
line wraps, then the justification for each line on the display is
determined by the first non-elided character of that display line.
.TP
\fB\-lang \fIcode\fR
.
Setting the language code of the text content inside the tagged region. If
this tag option is specified, it overrides the \fB\-lang\fR option for the
text widget. For a detailed description of this option see widget option
\fB\-lang\fR.
.TP
\fB\-lmargin1 \fIpixels\fR
.
If the first non-elided character of a text line has a tag for which this
option has been specified, then \fIpixels\fR specifies how much the line
should be indented from the left edge of the window. \fIPixels\fR may have any
of the standard forms for screen distances. If a line of text wraps, this
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518







519
520
521
522
523
524
525
\fB\-lmargincolor \fIcolor\fR
.
\fIColor\fR specifies the background color to use in regions that do not
contain characters because they are indented by \fB\-lmargin1\fR or
\fB\-lmargin2\fR. It may have any of the forms accepted by
\fBTk_GetColor\fR. If \fIcolor\fR has not been specified, or if it is
specified as an empty string, then the color used is specified by the
\fB-background\fR tag option (or, if this is also unspecified, by the
\fB-background\fR widget option).
.TP
\fB\-offset \fIpixels\fR
.
\fIPixels\fR specifies an amount by which the text's baseline should be offset
vertically from the baseline of the overall line, in pixels. For example, a
positive offset can be used for superscripts and a negative offset can be used
for subscripts. \fIPixels\fR may have any of the standard forms for screen
distances.
.TP
\fB\-overstrike \fIboolean\fR
.
Specifies whether or not to draw a horizontal rule through the middle of
characters. \fIBoolean\fR may have any of the forms accepted by
\fBTcl_GetBoolean\fR.
.TP
\fB\-overstrikefg \fIcolor\fR
.
\fIColor\fR specifies the color to use when displaying the overstrike. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
specified by the \fB\-foreground\fR tag option is used.







.TP
\fB\-relief \fIrelief\fR
.
\fIRelief\fR specifies the relief style to use for drawing the border, in any
of the forms accepted by \fBTk_GetRelief\fR. This option is used in
conjunction with the \fB\-borderwidth\fR option to enable to the desired
border appearance.







|
|















|

|
|
|
|
>
>
>
>
>
>
>







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
\fB\-lmargincolor \fIcolor\fR
.
\fIColor\fR specifies the background color to use in regions that do not
contain characters because they are indented by \fB\-lmargin1\fR or
\fB\-lmargin2\fR. It may have any of the forms accepted by
\fBTk_GetColor\fR. If \fIcolor\fR has not been specified, or if it is
specified as an empty string, then the color used is specified by the
\fB\-background\fR tag option (or, if this is also unspecified, by the
\fB\-background\fR widget option).
.TP
\fB\-offset \fIpixels\fR
.
\fIPixels\fR specifies an amount by which the text's baseline should be offset
vertically from the baseline of the overall line, in pixels. For example, a
positive offset can be used for superscripts and a negative offset can be used
for subscripts. \fIPixels\fR may have any of the standard forms for screen
distances.
.TP
\fB\-overstrike \fIboolean\fR
.
Specifies whether or not to draw a horizontal rule through the middle of
characters. \fIBoolean\fR may have any of the forms accepted by
\fBTcl_GetBoolean\fR.
.TP
\fB\-overstrikecolor\fR \fIcolor\fR
.
\fIColor\fR specifies the color to use when displaying the overstrike. It may have
any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not been specified,
or if it is specified as an empty string, then the color specified by the
\fB\-foreground\fR tag option is used.
.TP
\fB\-overstrikefg \fIcolor\fR
.
Note that this option is deprecated, option \fB\-overstrikecolor\fR should be used
instead. For compatibility reasons this option still will be supported, but
may be removed in a future version.
See equivalent tag option \fB\-overstrikecolor\fR for a description.
.TP
\fB\-relief \fIrelief\fR
.
\fIRelief\fR specifies the relief style to use for drawing the border, in any
of the forms accepted by \fBTk_GetRelief\fR. This option is used in
conjunction with the \fB\-borderwidth\fR option to enable to the desired
border appearance.
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
.TP
\fB\-rmargincolor \fIcolor\fR
.
\fIColor\fR specifies the background color to use in regions that do not
contain characters because they are indented by \fB\-rmargin\fR. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
used is specified by the \fB-background\fR tag option (or, if this is also
unspecified, by the \fB-background\fR widget option).
.TP
\fB\-selectbackground \fIcolor\fR
\fIColor\fR specifies the background color to use when displaying selected
items. It may have any of the forms accepted by \fBTk_GetColor\fR. If
\fIcolor\fR has not been specified, or if it is specified as an empty
string, then the color specified by the \fB\-background\fR tag option is
used.







|
|







1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
.TP
\fB\-rmargincolor \fIcolor\fR
.
\fIColor\fR specifies the background color to use in regions that do not
contain characters because they are indented by \fB\-rmargin\fR. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
used is specified by the \fB\-background\fR tag option (or, if this is also
unspecified, by the \fB\-background\fR widget option).
.TP
\fB\-selectbackground \fIcolor\fR
\fIColor\fR specifies the background color to use when displaying selected
items. It may have any of the forms accepted by \fBTk_GetColor\fR. If
\fIcolor\fR has not been specified, or if it is specified as an empty
string, then the color specified by the \fB\-background\fR tag option is
used.
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607















608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
\fB\-tabs \fItabList\fR
.
\fITabList\fR specifies a set of tab stops in the same form as for the
\fB\-tabs\fR option for the text widget. This option only applies to a display
line if it applies to the first non-elided character on that display line. If
this option is specified as an empty string, it cancels the option, leaving it
unspecified for the tag (the default). If the option is specified as a
non-empty string that is an empty list, such as \fB\-tags\0{\0}\fR, then it
requests default 8-character tabs as described for the \fB\-tags\fR widget
option.
.TP
\fB\-tabstyle \fIstyle\fR
.
\fIStyle\fR specifies either the \fItabular\fR or \fIwordprocessor\fR style of
tabbing to use for the text widget. This option only applies to a display line
if it applies to the first non-elided character on that display line. If this
option is specified as an empty string, it cancels the option, leaving it
unspecified for the tag (the default).
.TP
\fB\-underline \fIboolean\fR
.
\fIBoolean\fR specifies whether or not to draw an underline underneath
characters. It may have any of the forms accepted by \fBTcl_GetBoolean\fR.
.TP
\fB\-underlinefg \fIcolor\fR
.
\fIColor\fR specifies the color to use when displaying the underline. It may
have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
been specified, or if it is specified as an empty string, then the color
specified by the \fB\-foreground\fR tag option is used.















.TP
\fB\-wrap \fImode\fR
.
\fIMode\fR specifies how to handle lines that are wider than the text's
window. This option only applies to a display line if it applies to the
first non-elided character on that display line. It has the same legal
values as the \fB\-wrap\fR option for the text widget: \fBnone\fR,
\fBchar\fR, or \fBword\fR. If this tag option is specified, it
overrides the \fB\-wrap\fR option for the text widget.
.PP
If a character has several tags associated with it, and if their display
options conflict, then the options of the highest priority tag are used. If a
particular display option has not been specified for a particular tag, or if
it is specified as an empty string, then that option will never be used; the
next-highest-priority tag's option will used instead. If no tag specifies a
particular display option, then the default style for the widget will be used.







|
|















|

|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
|







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
\fB\-tabs \fItabList\fR
.
\fITabList\fR specifies a set of tab stops in the same form as for the
\fB\-tabs\fR option for the text widget. This option only applies to a display
line if it applies to the first non-elided character on that display line. If
this option is specified as an empty string, it cancels the option, leaving it
unspecified for the tag (the default). If the option is specified as a
non-empty string that is an empty list, such as \fB\-tabs\0{\0}\fR, then it
requests default 8-character tabs as described for the \fB\-tabs\fR widget
option.
.TP
\fB\-tabstyle \fIstyle\fR
.
\fIStyle\fR specifies either the \fItabular\fR or \fIwordprocessor\fR style of
tabbing to use for the text widget. This option only applies to a display line
if it applies to the first non-elided character on that display line. If this
option is specified as an empty string, it cancels the option, leaving it
unspecified for the tag (the default).
.TP
\fB\-underline \fIboolean\fR
.
\fIBoolean\fR specifies whether or not to draw an underline underneath
characters. It may have any of the forms accepted by \fBTcl_GetBoolean\fR.
.TP
\fB\-underlinecolor\fR \fIcolor\fR
.
\fIColor\fR specifies the color to use when displaying the underline. It may have
any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not been specified,
or if it is specified as an empty string, then the color specified by the
\fB\-foreground\fR tag option is used.
.TP
\fB\-underlinefg \fIcolor\fR
.
Note that this option is deprecated, option \fB\-underlinecolor\fR should be used
instead. For compatibility reasons this option still will be supported, but
may be removed in a future version.
See equivalent tag option \fB\-underlinecolor\fR for a description.
.TP
\fB\-undo \fIboolean\fR
.
Specifies whether adding/removing this tag to/from text will be undone with
\fBundo\fR operation. If this flag is \fIfalse\fR, then changes of tag
associations will not be undone for this tag. The default is given with
text option \fB-undotagging\fR (normally \fItrue\fR), except for the special
selection flag \fBsel\fR, the default for this tag is always \fIfalse\fR.
.TP
\fB\-wrap \fImode\fR
.
\fIMode\fR specifies how to handle lines that are wider than the text's
window. This option only applies to a display line if it applies to the
first non-elided character on that display line. It has the same legal
values as the \fB\-wrap\fR option for the text widget: \fBnone\fR,
\fBchar\fR, \fBword\fR, or \fBcodepoint\fR. If this tag option is specified,
it overrides the \fB\-wrap\fR option for the text widget.
.PP
If a character has several tags associated with it, and if their display
options conflict, then the options of the highest priority tag are used. If a
particular display option has not been specified for a particular tag, or if
it is specified as an empty string, then that option will never be used; the
next-highest-priority tag's option will used instead. If no tag specifies a
particular display option, then the default style for the widget will be used.
635
636
637
638
639
640
641
642











643
644
645
646
647
648
649
The third use for tags is in managing the selection. See \fBTHE SELECTION\fR
below. With the exception of the special \fBsel\fR tag, all tags are shared
between peer text widgets, and may be manipulated on an equal basis from any
such widget. The \fBsel\fR tag exists separately and independently in each
peer text widget (but any tag bindings to \fBsel\fR are shared).
.SH MARKS
.PP
The second form of annotation in text widgets is a mark. Marks are used for











remembering particular places in a text. They are something like tags, in that
they have names and they refer to places in the file, but a mark is not
associated with particular characters. Instead, a mark is associated with the
gap between two characters. Only a single position may be associated with a
mark at any given time. If the characters around a mark are deleted the mark
will still remain; it will just have new neighbor characters. In contrast, if
the characters containing a tag are deleted then the tag will no longer have







|
>
>
>
>
>
>
>
>
>
>
>







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
The third use for tags is in managing the selection. See \fBTHE SELECTION\fR
below. With the exception of the special \fBsel\fR tag, all tags are shared
between peer text widgets, and may be manipulated on an equal basis from any
such widget. The \fBsel\fR tag exists separately and independently in each
peer text widget (but any tag bindings to \fBsel\fR are shared).
.SH MARKS
.PP
The second form of annotation in text widgets is a mark. The name of a mark
may contain arbitrary characters, but it is probably best to avoid using the
characters
.QW " "
(space),
.QW \fC@\fR ,
.QW \fC.\fR ,
.QW \fC+\fR ,
or
.QW \fC\-\fR :
these characters have special
meaning in indices. Marks are used for
remembering particular places in a text. They are something like tags, in that
they have names and they refer to places in the file, but a mark is not
associated with particular characters. Instead, a mark is associated with the
gap between two characters. Only a single position may be associated with a
mark at any given time. If the characters around a mark are deleted the mark
will still remain; it will just have new neighbor characters. In contrast, if
the characters containing a tag are deleted then the tag will no longer have
672
673
674
675
676
677
678









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


696
697
698
699
700
701
702
703
704
705
706
707
character closest to the mouse and is adjusted automatically to track the
mouse position and any changes to the text in the widget (one exception:
\fBcurrent\fR is not updated in response to mouse motions if a mouse button is
down; the update will be deferred until all mouse buttons have been released).
Neither of these special marks may be deleted. With the exception of these two
special marks, all marks are shared between peer text widgets, and may be
manipulated on an equal basis from any peer.









.SH "EMBEDDED WINDOWS"
.PP
The third form of annotation in text widgets is an embedded window. Each
embedded window annotation causes a window to be displayed at a particular
point in the text. There may be any number of embedded windows in a text
widget, and any widget may be used as an embedded window (subject to the usual
rules for geometry management, which require the text window to be the parent
of the embedded window or a descendant of its parent).
.PP
The embedded window's position on the screen will be updated as the text is
modified or scrolled, and it will be mapped and unmapped as it moves into and
out of the visible area of the text widget. Each embedded window occupies one
unit's worth of index space in the text widget, and it may be referred to
either by the name of its embedded window or by its position in the widget's
index space. If the range of text containing the embedded window is deleted
then the window is destroyed. Similarly if the text widget as a whole is
deleted, then the window is destroyed.


.PP
Eliding an embedded window immediately after scheduling it for creation via
\fIpathName \fBwindow create \fIindex \fB-create\fR will prevent it from being
effectively created. Uneliding an elided embedded window scheduled for creation
via \fIpathName \fBwindow create \fIindex \fB-create\fR will automatically
trigger the associated creation script. After destroying an elided embedded
window, the latter won't get automatically recreated.
.PP
When an embedded window is added to a text widget with the \fIpathName
\fBwindow create\fR widget command, several configuration options may be
associated with it. These options may be modified later with the \fIpathName
\fBwindow configure\fR widget command. The following options are currently







>
>
>
>
>
>
>
>
>














|
|
|
>
>


|

|







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
character closest to the mouse and is adjusted automatically to track the
mouse position and any changes to the text in the widget (one exception:
\fBcurrent\fR is not updated in response to mouse motions if a mouse button is
down; the update will be deferred until all mouse buttons have been released).
Neither of these special marks may be deleted. With the exception of these two
special marks, all marks are shared between peer text widgets, and may be
manipulated on an equal basis from any peer.
.PP
Generated marks (created with command \fBmark generate\fR) have a special meaning.
They will be discarded by the undo mechanism (relevant only if widget option
\fB\-steadymarks\fR is enabled). Furthermore these marks are
.QW invisible ,
only command \fBdump\fR is showing generated marks, the commands \fBmark names\fR,
\fBmark next\fR, and \fBmark previous\fR, cannot
.QW see
generated marks.
.SH "EMBEDDED WINDOWS"
.PP
The third form of annotation in text widgets is an embedded window. Each
embedded window annotation causes a window to be displayed at a particular
point in the text. There may be any number of embedded windows in a text
widget, and any widget may be used as an embedded window (subject to the usual
rules for geometry management, which require the text window to be the parent
of the embedded window or a descendant of its parent).
.PP
The embedded window's position on the screen will be updated as the text is
modified or scrolled, and it will be mapped and unmapped as it moves into and
out of the visible area of the text widget. Each embedded window occupies one
unit's worth of index space in the text widget, and it may be referred to
either by the name of its embedded window or by its position in the widget's
index space. If the range of text containing the embedded window is deleted,
and this range is not saved on undo stack, then the window is destroyed.
Similarly if the text widget as a whole is deleted, then the window is
destroyed. If this automatic destroy behavior is not wanted then option
\fB\-owner\fR should be set accordingly.
.PP
Eliding an embedded window immediately after scheduling it for creation via
\fIpathName \fBwindow create \fIindex \fB\-create\fR will prevent it from being
effectively created. Uneliding an elided embedded window scheduled for creation
via \fIpathName \fBwindow create \fIindex \fB\-create\fR will automatically
trigger the associated creation script. After destroying an elided embedded
window, the latter won't get automatically recreated.
.PP
When an embedded window is added to a text widget with the \fIpathName
\fBwindow create\fR widget command, several configuration options may be
associated with it. These options may be modified later with the \fIpathName
\fBwindow configure\fR widget command. The following options are currently
725
726
727
728
729
730
731









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








751
752
753
754
755
756
757
the screen. \fIScript\fR must create a window for the annotation and return
the name of that window as its result. Two substitutions will be performed in
\fIscript\fR before evaluation. \fI%W\fR will be substituted by the name of
the parent text widget, and \fI%%\fR will be substituted by a single \fI%\fR.
If the annotation's window should ever be deleted, \fIscript\fR will be
evaluated again the next time the annotation is displayed.
.TP









\fB\-padx \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on each side of the
embedded window. It may have any of the usual forms defined for a screen
distance.
.TP
\fB\-pady \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on the top and on
the bottom of the embedded window. It may have any of the usual forms defined
for a screen distance.
.TP
\fB\-stretch \fIboolean\fR
.
If the requested height of the embedded window is less than the height of the
line in which it is displayed, this option can be used to specify whether the
window should be stretched vertically to fill its line. If the \fB\-pady\fR
option has been specified as well, then the requested padding will be retained
even if the window is stretched.








.TP
\fB\-window \fIpathName\fR
.
Specifies the name of a window to display in the annotation. Note that if a
\fIpathName\fR has been set, then later configuring a window to the empty
string will not delete the widget corresponding to the old \fIpathName\fR.
Rather it will remove the association between the old \fIpathName\fR and the







>
>
>
>
>
>
>
>
>



















>
>
>
>
>
>
>
>







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
the screen. \fIScript\fR must create a window for the annotation and return
the name of that window as its result. Two substitutions will be performed in
\fIscript\fR before evaluation. \fI%W\fR will be substituted by the name of
the parent text widget, and \fI%%\fR will be substituted by a single \fI%\fR.
If the annotation's window should ever be deleted, \fIscript\fR will be
evaluated again the next time the annotation is displayed.
.TP
\fB\-owner \fIboolean\fR
.
If \fItrue\fR then the text widget is the owner of the embedded window. Only
if it is the owner the window will be destroyed if the range of text containing
the embedded window is deleted, and the deleted text is not saved on undo
stack. Per default this option is \fItrue\fR. Setting this option to
\fIfalse\fR should be done with care, because in this case the text widget
is not responsible for the lifetime of the embedded window.
.TP
\fB\-padx \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on each side of the
embedded window. It may have any of the usual forms defined for a screen
distance.
.TP
\fB\-pady \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on the top and on
the bottom of the embedded window. It may have any of the usual forms defined
for a screen distance.
.TP
\fB\-stretch \fIboolean\fR
.
If the requested height of the embedded window is less than the height of the
line in which it is displayed, this option can be used to specify whether the
window should be stretched vertically to fill its line. If the \fB\-pady\fR
option has been specified as well, then the requested padding will be retained
even if the window is stretched.
.TP
\fB\-tags \fItagList\fR
.
Specifies a set of tags to apply to the embedded window. \fITagList\fR consists
of a list of tag names, which replace any existing tags for the embedded window.
\fITagList\fR may be an empty list. Note that it is not possible to add or
remove the special selection tag \fBsel\fR, it will be left untouched with this
option.
.TP
\fB\-window \fIpathName\fR
.
Specifies the name of a window to display in the annotation. Note that if a
\fIpathName\fR has been set, then later configuring a window to the empty
string will not delete the widget corresponding to the old \fIpathName\fR.
Rather it will remove the association between the old \fIpathName\fR and the
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
space in the text widget, and it may be referred to either by its position in
the widget's index space, or the name it is assigned when the image is inserted
into the text widget with \fIpathName \fBimage create\fR. If the range of text
containing the embedded image is deleted then that copy of the image is removed
from the screen.
.PP
Eliding an embedded image immediately after scheduling it for creation via
\fIpathName \fBimage create \fIindex \fB-create\fR will prevent it from being
effectively created. Uneliding an elided embedded image scheduled for creation
via \fIpathName \fBimage create \fIindex \fB-create\fR will automatically
trigger the associated creation script. After destroying an elided embedded
image, the latter won't get automatically recreated.
.PP
When an embedded image is added to a text widget with the \fIpathName \fBimage
create\fR widget command, a name unique to this instance of the image is
returned. This name may then be used to refer to this image instance. The name
is taken to be the value of the \fB\-name\fR option (described below). If the







|

|







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
space in the text widget, and it may be referred to either by its position in
the widget's index space, or the name it is assigned when the image is inserted
into the text widget with \fIpathName \fBimage create\fR. If the range of text
containing the embedded image is deleted then that copy of the image is removed
from the screen.
.PP
Eliding an embedded image immediately after scheduling it for creation via
\fIpathName \fBimage create \fIindex \fB\-create\fR will prevent it from being
effectively created. Uneliding an elided embedded image scheduled for creation
via \fIpathName \fBimage create \fIindex \fB\-create\fR will automatically
trigger the associated creation script. After destroying an elided embedded
image, the latter won't get automatically recreated.
.PP
When an embedded image is added to a text widget with the \fIpathName \fBimage
create\fR widget command, a name unique to this instance of the image is
returned. This name may then be used to refer to this image instance. The name
is taken to be the value of the \fB\-name\fR option (described below). If the
825
826
827
828
829
830
831



















































































































































































































































































































































832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849



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
distance.
.TP
\fB\-pady \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on the top and on
the bottom of the embedded image. It may have any of the usual forms defined
for a screen distance.



















































































































































































































































































































































.SH "THE SELECTION"
.PP
Selection support is implemented via tags. If the \fB\-exportselection\fR option
for the text widget is true then the \fBsel\fR tag will be associated with the
selection:
.IP [1]
Whenever characters are tagged with \fBsel\fR the text widget will claim
ownership of the selection.
.IP [2]
Attempts to retrieve the selection will be serviced by the text widget,
returning all the characters with the \fBsel\fR tag.
.IP [3]
If the selection is claimed away by another application or by another window
within this application, then the \fBsel\fR tag will be removed from all
characters in the text.
.IP [4]
Whenever the \fBsel\fR tag range changes a virtual event \fB<<Selection>>\fR
is generated.



.PP
The \fBsel\fR tag is automatically defined when a text widget is created, and
it may not be deleted with the
.QW "\fIpathName \fBtag delete\fR"
widget command. Furthermore, the \fB\-selectbackground\fR,
\fB\-selectborderwidth\fR, and \fB\-selectforeground\fR options for the text


widget are tied to the \fB\-background\fR, \fB\-borderwidth\fR, and

\fB\-foreground\fR options for the \fBsel\fR tag: changes in either will
automatically be reflected in the other. Also the
\fB\-inactiveselectbackground\fR option for the text widget is used instead of
\fB\-selectbackground\fR when the text widget does not have the focus. This
allows programmatic control over the visualization of the \fBsel\fR tag for
foreground and background windows, or to have \fBsel\fR not shown at all (when
\fB\-inactiveselectbackground\fR is empty) for background windows. Each peer
text widget has its own \fBsel\fR tag which can be separately configured and
set.

















.SH "THE INSERTION CURSOR"
.PP
The mark named \fBinsert\fR has special significance in text widgets. It is
defined automatically when a text widget is created and it may not be unset
with the
.QW "\fIpathName \fBmark unset\fR"
widget command. The \fBinsert\fR mark represents the position of the insertion
cursor, and the insertion cursor will automatically be drawn at this point
whenever the text widget has the input focus.











.SH "THE MODIFIED FLAG"
.PP
The text widget can keep track of changes to the content of the widget by
means of the modified flag. Inserting or deleting text will set this flag. The
flag can be queried, set and cleared programmatically as well. Whenever the
flag changes state a \fB<<Modified>>\fR virtual event is generated. See the
\fIpathName \fBedit modified\fR widget command for more details.



















.SH "THE UNDO MECHANISM"
.PP
The text widget has an unlimited undo and redo mechanism (when the
\fB\-undo\fR widget option is true) which records every insert and delete
action on a stack.



.PP
Boundaries (called
.QW separators )
are inserted between edit actions. The purpose of these separators is to group
inserts, deletes and replaces into one compound edit action. When undoing a
change everything between two separators will be undone. The undone changes
are then moved to the redo stack, so that an undone edit can be redone again.
The redo stack is cleared whenever new edit actions are recorded on the undo
stack. The undo and redo stacks can be cleared to keep their depth under
control.
.PP
Separators are inserted automatically when the \fB\-autoseparators\fR widget
option is true. You can insert separators programmatically as well. If a
separator is already present at the top of the undo stack no other will be
inserted. That means that two separators on the undo stack are always
separated by at least one insert or delete action.
.PP
The \fB<<UndoStack>>\fR virtual event is generated every time the undo stack
or the redo stack becomes empty or unempty.
.PP
The undo mechanism is also linked to the modified flag. This means that



undoing or redoing changes can take a modified text widget back to the

unmodified state or vice versa. The modified flag will be set automatically to


the appropriate state. This automatic coupling does not work when the modified

flag has been set by the user, until the flag has been reset again.
.PP
See below for the \fIpathName \fBedit\fR widget command that controls the undo
mechanism.
.SH "PEER WIDGETS"
.PP
The text widget has a separate store of all its data concerning each line's







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|


|


|



|


>
>
>





|
>
>
|
>
|
|
<
<
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>
>
>
>
>
>
>
>
>
>
>


|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
>
>
>















|


|

|
>
>
>
|
>
|
>
>
|
>







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
distance.
.TP
\fB\-pady \fIpixels\fR
.
\fIPixels\fR specifies the amount of extra space to leave on the top and on
the bottom of the embedded image. It may have any of the usual forms defined
for a screen distance.
.TP
\fB\-tags \fItagList\fR
.
Specifies a set of tags to apply to the embedded image. \fITagList\fR consists
of a list of tag names, which replace any existing tags for the embedded image.
\fITagList\fR may be an empty list. Note that it is not possible to add or
remove the special selection tag \fBsel\fR, it will be left untouched with this
option.
.SH "EXTRA FUNCTIONS"
.SS "MERGE RANGE"
.TP
NAME
.
tk_mergeRange \- insert/merge a given range into a sorted list of ranges.
.TP
SYNOPSYS
.
\fBtk_mergeRange \fIvarName range\fR
.TP
DESCRIPTION
.
This procedure is inserting \fIrange\fR into a sorted list of ranges, given
with \fIvarName\fR. If given range is adjacent to, or intersecting a range in given list, then it will be amalgamated. This means that the result is a sorted list of disjoint ranges. This procedure return the new content of \fIvarName\fR.
.SS "INSERT TEXT"
.TP
NAME
.
tk_textInsert \- insert characters into a text widget regarding soft hyphen pattern.
.TP
SYNOPSYS
.
\fBtk_textInsert\fR \fIpathName\fR ?\fB\-hyphentags\fI tagList\fR? \fIindex chars\fR ?\fItagList chars tagList ...\fR?
.TP
DESCRIPTION
.
This procedure is especially supporting the predefined spelling changes
(see section \fBHYPHENATION RULES\fR).
.RS
.PP
The procedure \%\fBtk_textInsert\fR inserts all of the \fIchars\fR arguments just
before the character at \fIindex\fR in the specified text widget, see
command \fBinsert\fR of the text widget for a detailed description. This
procedure will pre-parse the \fIchars\fR arguments before it calls command
\fBinsert\fR of \fIpathName\fR for the execution of the insertion. The
parser is recognizing the following escape sequences:
.IP \(bu 3
The sequence
.QW \e-
will be replaced by the soft hyphen character. Example:
.QW Sen\e\e-tence
will hyphenate into
.QW Sen-tence .
.IP \(bu 3
The sequence
.QW \e+
will be replaced by the soft hyphen character, and, provided that no tagged
list of rules is given (in \fItagList\fR), a special tag with all known hyphen
rules (regarding option \fB\-lang\fR) will be attached to this hyphen (this
means that all known hyphenation rules will be applied to this hyphen \-
probably restricted by option \fB\-lang\fR).
.IP \(bu 3
The sequence
.QW \e:\fIRULE\fR:
\- \fIRULE\fR is the identifier for a defined hyphenation rule (see section
\fBHYPHENATION RULES\fR) \- will be replaced with a soft hyphen, and applies a tag with the specified hyphenation rule \fIRULE\fR to this soft hyphen character. An
error will be thrown if the specified rule is not defined, or if the
trailing colon is missing.
.IP \(bu 3
Any other escaped character (not
.QW \fC\-\fR ,
nor
.QW \fC+\fR ,
nor
.QW \fC:\fR
) will be replaced by this character; this means that the former escape
character will be removed.
.PP
The latter case is required to allow the escape character inside a string \- it
has to be doubled \- otherwise an unambiguous identification is not possible. Example: the character string
.QW \e\e-
will be interpreted as
.QW \e-
(a string), but the character string
.QW \e-
will be interpreted as soft hyphen character. (Please note that all the
statements about the escape character are related to the list notation,
inside the string notation every escape character has to be doubled.)
.PP
It is allowed to abbreviate all rules with a two-letter code:
.IP \(bu 3
:ck: is already an abbreviation
.IP \(bu 3
:dd: is :doubledigraph:
.IP \(bu 3
:dv: is :doublevowel:
.IP \(bu 3
:ge: is :gemination:
.IP \(bu 3
:tc: is :tripleconsonant:
.IP \(bu 3
:tr: is :trema:
.IP \(bu 3
:rh: is :repeathyphen:
.PP
If option \fB\-hyphentags\fR is specified then the associated \fItagList\fR
will additionally be associated with all soft hyphens in new text; combined
with the inherited tags, or the specified tags. This is especially useful
for hiding/showing soft hyphens (see tag option \fB\-elide\fR).
.RE
.SS "REBIND MOUSE WHEEL EVENT"
.TP
NAME
.
tk_textRebindMouseWheel \- rebind the mouse wheel event.
.TP
SYNOPSYS
.
\fBtk_textRebindMouseWheel\fR \fIpathName\fR ?\fIpathName ...\fR?
.TP
DESCRIPTION
.
This procedure provides a portable way to rebind the mouse wheel events of
embedded windows, so that the text widget will receive the events, as if
the embedded windows are transparent for mouse wheel events. Without rebinding
only the embedded window may receive the mouse wheel events, this might break
the expected scroll behavior of the text widget.
.RS
.PP
The first \fBpathName\fR is the receiver of the mouse wheel events, i.e. the
text widget which contains the embedded windows. If no further argument is
specified, then all currently embedded windows will be rebound. Otherwise only
the specified embedded windows, starting with the second provided argument,
will be rebound.
.RE
.SS "REPLACE TEXT"
.TP
NAME
.
tk_textReplace \- replace a range of characters inside a text widget regarding soft hyphen pattern.
.TP
SYNOPSYS
.
\fBtk_textReplace\fR \fIpathName\fR ?\fB\-hyphentags\fR \fItagList\fR? \fIindex chars\fR ?\fItagList chars tagList ...\fR?
.TP
DESCRIPTION
.
This procedure is especially supporting the predefined spelling changes (see
section \fBHYPHENATION RULES\fR).
.RS
.PP
The procedure \%\fBtk_textReplace\fR replaces the range of characters between
\fIindex1\fR and \fIindex2\fR, see command \fBreplace\fR for a detailed
description. This procedure will pre-parse the \fIchars\fR arguments before
it calls command \fBreplace\fR of \fIpathName\fR for the execution of the
replacement. The parser is recognizing the escape sequences
.QW \e- ,
.QW \e+ ,
and
.QW \e:RULE: ,
see procedure \%\fBtk_textInsert\fR which works in a similar way.
.PP
If option \fB\-hyphentags\fR is specified then the associated \fItagList\fR
will additionally be associated with all soft hyphens in new text; combined
with the inherited tags, or the specified tags. This is especially useful
for hiding/showing soft hyphens (see tag option \fB\-elide\fR).
.RE
.SH "HYPHENATION RULES"
.PP
The rules are:
.IP [1] 4
In natural (pre-reform) German orthography, a
.QW c
before the hyphenation point can change into a
.QW k :
.QW Drucker
hyphenates into
.QW Druk-ker .
This spelling change will be called \fBck\fR rule.
.IP [2] 4
In modern Dutch, an e-diaeresis after the hyphenation point can change into
a simple
.QW e
:
.QW re\[:e]el
hyphenates into
.QW re-eel .
This also applies for i-diaeresis, o-diaeresis, and u-diaeresis. This
spelling change will be called \fBtrema\fR rule.
.IP [3] 4
In German, Norwegian, and Swedish, a triple consonant can change into a
double consonant: Swedish
.QW tugg-gummi
becomes
.QW tuggummi
when not hyphenated, Norwegian
.QW buss-sj\[oa]f\[/o]r
becomes
.QW bussj\[oa]f\[/o]r ,
and German
.QW Schiff-fahrt
becomes
.QW Schiffahrt
(in pre-reform orthography). This spelling change will be called
\fBtripleconsonant\fR rule. (Note that is a reverse rule, applied when a
word will not be hyphenated at this point).
.IP [4] 4
In Dutch, a letter can disappear inside a doubled vowel:
.QW opaatje
hyphenates into
.QW opa-tje .
In case of an double
.QW e
it will change to the corresponding vowel with accute, for example
.QW cafeetje
becomes
.QW caf\['e]-tje .
This spelling change will be called \fBdoublevowel\fR rule.
.IP [5] 4
Hungarian has an unusual hyphenation case which involves reinsertion of a
root-letter, as in the following example:
.QW vissza
becomes
.QW visz-sza .
These special cases, occurring when the characters are in the middle of a
word are:
.QW ccs
becomes
.QW cs-cs ,
.QW ggy
becomes
.QW gy-gy ,
.QW lly
becomes
.QW ly-ly ,
.QW nny
becomes
.QW ny-ny ,
.QW tty
becomes
.QW ty-ty ,
.QW zzs
becomes
.QW zs-zs ,
.QW ssz
becomes
.QW sz-sz .
This rule is named \fBdoubledigraph\fR.
.IP [6] 4
In Catalan, a geminated consonant can be split: the word
.QW paral\N'183'lel
hyphenates into
.QW paral-lel .
The name for this rule is \fBgemination\fR.
.IP [7] 4
In Polish the hyphen will be repeated after line break, this means for
example that
.QW tech-nik
becomes
.QW "tech- -nik" .
The name of this rule is \fBrepeathyphen\fR.
.PP
Applying hyphenation rule \fIRULE\fR (which may result into spelling
changes) will be done automatically in the following cases:
.IP [1] 4
The hyphen is tagged with hyphenation rule \fIRULE\fR (tag option
\fB\-hyphenrules\fR includes \fIRULE\fR).
.IP [2] 4
The widget option \fB\-hyphenrules\fR contains rule \fIRULE\fR, and no tag
(attached to this hyphen) is overruling.
.SH "INSERTING TEXT WITH SOFT HYPHENS"
.PP
When spelling changes are involved it might be convenient to use the helper
functions \%\fBtk_textInsert\fR and \%\fBtk_textReplace\fR.
These functions are providing a simple way to insert hyphenated text
regarding the spelling changes based on rules. Example:
.PP
.CS
\fBtk_textInsert end .t "Nach dem Ein\\\\-le\\\\-gen des Pa\\\\-piers soll\\\\-ten\\\fR
    \fBdie Druc\\\\+ker\\\\-ein\\\\-stel\\\\-lun\\\\-gen \[:u]ber\\\\-pr\[:u]ft wer\\\\-den."\fR
.CE
.PP
This text in German may be hyphenated and displayed in the following way:
.PP
.CS
Nach dem Einlegen des Papiers sollten die Druk-
kereinstellungen \[:u]berpr\[:u]ft werden.
.CE
.PP
Second example:
.PP
.CS
\fBtk_textInsert end .t "Nach dem Ein\\\\-le\\\\-gen des Pa\\\\-piers soll\\\\-ten\\\fR
    \fBdie Druc\\\\:ck:ker\\\\-ein\\\\-stel\\\\-lun\\\\-gen \[:u]ber\\\\-pr\[:u]ft wer\\\\-den."\fR
.CE
.PP
This gives the same result, but here the \fBck\fR rule is explictly specified.
.PP
.CS
\fBtk_textInsert end .t "Nach dem Ein\\\\+le\\\\+gen des Pa\\\\+piers soll\\\\+ten\\\fR
    \fBdie Druc\\\\+ker\\\\+ein\\\\+stel\\\\+lun\\\\+gen \[:u]ber\\\\+pr\[:u]ft wer\\\\+den."\fR
.CE
.PP
This will also give the same result, because only the \fBck\fR rule will be detected
for spelling changes.
.PP
.CS
\fBtk_textInsert end .t "Nach dem Ein\\\\-le\\\\-gen des Pa\\\\-piers soll\\\\-ten\\\fR
    \fBdie Druc\\\\-ker\\\\-ein\\\\-stel\\\\-lun\\\\-gen \[:u]ber\\\\-pr\[:u]ft wer\\\\-den." ck\fR
\fB.t tag configure ck -hyphenrules {ck}\fR
.CE
.PP
The same result as before, because the \fBck\fR rule is applied explictly
(to all soft hyphens).
.PP
.CS
\fBtk_textInsert end .t {Nach dem Ein\\-le\\-gen des Pa\\-piers soll\\-ten\\\fR
    \fBdie Druc\\-ker\\-ein\\-stel\\-lun\\-gen \[:u]ber\\-pr\[:u]ft wer\\-den.} trema\fR
\fB.t tag configure trema -hyphenrules {trema}\fR
.CE
.PP
In this case only the \fBtrema\fR rule will be applied to the text - the \fBck\fR
rule is missing - thus we cannot get here the correct result, this text may be
(wrongly) hyphenated in the following way:
.PP
.CS
Nach dem Einlegen des Papiers sollten die Druc-
kereinstellungen \[:u]berpr\[:u]ft werden.
.CE
.PP
The explicit specification of the hyphenation rule is the preferred method (second
example), however it depends on the quality of the hyphenator which method will be
used. For instance, the TeX hyphenator does not know about spelling changes, and here
the method with the use of
.QW "\\\\+"
(for any hyphenation point like in the third example) may give fairly good results.
Of course, the use of
.QW "\\\\+"
is (currently) only useful for the languages Catalan, Dutch, German, Hungarian,
Norwegian, Polish, and Swedish.
.SH "THE SELECTION"
.PP
Selection support is implemented via tags. If the \fB\-exportselection\fR option
for the text widget is true then the \fBsel\fR tag will be associated with the
selection:
.IP [1] 4
Whenever characters are tagged with \fBsel\fR the text widget will claim
ownership of the selection.
.IP [2] 4
Attempts to retrieve the selection will be serviced by the text widget,
returning all the characters with the \fBsel\fR tag.
.IP [3] 4
If the selection is claimed away by another application or by another window
within this application, then the \fBsel\fR tag will be removed from all
characters in the text.
.IP [4] 4
Whenever the \fBsel\fR tag range changes a virtual event \fB<<Selection>>\fR
is generated.
It might also be generated when selection is affected but not actually changed.
Further, multiple selection changes could happen before events can be processed
leading to multiple events with the same visible selection.
.PP
The \fBsel\fR tag is automatically defined when a text widget is created, and
it may not be deleted with the
.QW "\fIpathName \fBtag delete\fR"
widget command. Furthermore, the \fB\-selectbackground\fR,
\fB\-selectborderwidth\fR, \fB\-selectforeground\fR,
\fB\-inactiveselectbackground\fR, \fB\-inactiveselectforeground\fR, and
\fB\-selectborderwidth\fR options for the text widget are tied to the
\fB\-background\fR, \fB\-borderwidth\fR, \fB\-foreground\fR,
\fB\-inactiveselectbackground\fR, \fB\-inactiveselectforeground\fR, and
\fB\-borderwidth\fR options for the \fBsel\fR tag: changes
in either will automatically be reflected in the other. This allows


programmatic control over the visualization of the \fBsel\fR tag for
foreground and background windows, or to have \fBsel\fR not shown at all
for background windows. Each peer text widget has its own \fBsel\fR tag
which can be separately configured and set.
.PP
The \fBsel\fR tag is overruling all other tags, except if a tag with higher
priority has explicitly defined the selection attributes
(\fB\-selectbackground\fR and \fB\-selectforeground\fR if the window is
active; \fB\-inactiveselectbackground\fR and \fB\-inactiveselectforeground\fR
if the window is inactive).
.PP
Note the specific behavior if \fB\-inactiveselectbackground\fR is not defined
(empty): if the window does not have the focus, then the selection attributes
of the text widget and all the attributes of the \fBsel\fR tag will not be
regarded; this means that in general no selection will be shown, this is the
default behavior on Windows.
.PP
Note the specific behavior on Mac: if the window does not have the focus, and
does not have state \fBnormal\fR (see widget option \fB\-state\fR),
then the selection attributes of the text widget and all the attributes of
the \fBsel\fR tag will not be regarded; this means that per default no selection
will be shown.
.SH "THE INSERTION CURSOR"
.PP
The mark named \fBinsert\fR has special significance in text widgets. It is
defined automatically when a text widget is created and it may not be unset
with the
.QW "\fIpathName \fBmark unset\fR"
widget command. The \fBinsert\fR mark represents the position of the insertion
cursor, and the insertion cursor will automatically be drawn at this point
whenever the text widget has the input focus.
.PP
The cursor shape (vertical line or rectangular block) can be specified with
option \fB\-blockcursor\fR. But note that in general the block cursor is
useful only if also the options \fB\-showendofline\fR and \fB\-showendoftext\fR
are enabled (otherwise the cursor handling is unsatisfying). With a block
cursor the optimal width (option \fB\-insertwidth\fR) is 2, and with a bar
cursor (vertical line) the optimal width is 2 as well, or even 1 if the cursor
is blinking. When disabling the blinking, or when setting a block cursor shape,
it is recommended to specify the cursor width (option \fB\-insertwidth\fR)
explicitly. Of course, in most cases the default settings for the cursor will
be preferred.
.SH "THE MODIFIED FLAG"
.PP
The text widget can keep track of changes to the textual content of the widget
by means of the modified flag. Inserting or deleting text will set this flag.
The flag can be queried, set and cleared programmatically as well. Whenever
the flag changes state a \fB<<Modified>>\fR virtual event is generated. See
the \fIpathName \fBedit modified\fR widget command for more details.
.SH "THE ALTERED FLAG"
.PP
It's possible to keep track of any change which has an affect on text content,
even if only the representation is affected. Also any change in tag associations
will be seen as a change in the representation. If option \fB\-steadymarks\fR is
enabled, also the mark operations may have effects on the text content (although
indirectly). Whenever the flag changes state a \fB<<Altered>>\fR virtual event
is generated. See the \fIpathName \fBedit altered\fR widget command for more
details.
.SH "THE IRREVERSIBLE FLAG"
.PP
As a supplement to the
.QW altered
flag also the
.QW irreversible
flag is provided. This flag informs whether the original content
(before any modification/operation has been performed) can be restored. Whenever
the state of this flag is changing, the virtual event \fB<<Irreversible>>\fR is
fired. For more details see the \fIpathName \fBedit irreversible\fR widget command.
.SH "THE UNDO MECHANISM"
.PP
The text widget has an unlimited undo and redo mechanism (when the
\fB\-undo\fR widget option is true) which records every insert and delete
action on a stack, including the insertion and deletion of embedded windows and
embedded images. Furthermore any change of tag associations will be recorded.
If option \fB\-steadymarks\fR is enabled even operations on marks will push
an undo operation on the stack.
.PP
Boundaries (called
.QW separators )
are inserted between edit actions. The purpose of these separators is to group
inserts, deletes and replaces into one compound edit action. When undoing a
change everything between two separators will be undone. The undone changes
are then moved to the redo stack, so that an undone edit can be redone again.
The redo stack is cleared whenever new edit actions are recorded on the undo
stack. The undo and redo stacks can be cleared to keep their depth under
control.
.PP
Separators are inserted automatically when the \fB\-autoseparators\fR widget
option is true. You can insert separators programmatically as well. If a
separator is already present at the top of the undo stack no other will be
inserted. That means that two separators on the undo stack are always
separated by at least one undoable action.
.PP
The \fB<<UndoStack>>\fR virtual event is generated every time the undo stack
or the redo stack is changing.
.PP
The undo mechanism is also linked to the
.QW modified
and
.QW altered
flag. This means that undoing or redoing changes can take a modified/altered
text widget back to the unmodified/unaltered state or vice versa. The
modified/altered flag will be set automatically to the appropriate state. The
automatic coupling of the
.QW modified
flag does not work when the
.QW modified
flag has been set by the user, until the flag has been reset again.
.PP
See below for the \fIpathName \fBedit\fR widget command that controls the undo
mechanism.
.SH "PEER WIDGETS"
.PP
The text widget has a separate store of all its data concerning each line's
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
positions (but all other marks are shared). Third, embedded windows, which are
arbitrary other widgets, cannot be shared between peers. This means the
\fB\-window\fR option of embedded windows is independently set for each peer
(it is advisable to use the \fB\-create\fR script capabilities to allow each
peer to create its own embedded windows as needed). Fourth, all of the
configuration options of each peer (e.g. \fB\-font\fR, etc) can be set
independently, with the exception of \fB\-undo\fR, \fB\-maxundo\fR,
\fB\-autoseparators\fR (i.e. all undo, redo and modified state issues are
shared).

.PP
Finally any single peer need not contain all lines from the underlying data
store. When creating a peer, a contiguous range of lines (e.g. only lines 52




through 125) may be specified. This allows a peer to contain just a small
portion of the overall text. The range of lines will expand and contract as
text is inserted or deleted. The peer will only ever display complete lines of
text (one cannot share just part of a line). If the peer's contents contracts
to nothing (i.e. all complete lines in the peer widget have been deleted from

another widget), then it is impossible for new lines to be inserted. The peer
will simply become an empty shell on which the background can be configured,
but which will never show any content (without manual reconfiguration of the
start and end lines). Note that a peer which does not contain all of the
underlying data store still has indices numbered from
.QW 1.0
to
.QW end .
It is simply that those indices reflect a subset of the total data, and data
outside the contained range is not accessible to the peer. This means that the
command \fIpeerName \fBindex end\fR may return quite different values in
different peers. Similarly, commands like \fIpeerName \fBtag ranges\fR will
not return index ranges outside that which is meaningful to the peer. The
configuration options \fB\-startline\fR and \fB\-endline\fR may be used to
control how much of the underlying data is contained in any given text widget.
.PP
Note that peers are really peers. Deleting the
.QW original
text widget will not cause any other peers to be deleted, or otherwise
affected.
.PP







|
|
>

|
|
>
>
>
>
|
|
<
|
<
>
|
|
|
|
|




|
|
|
|
|







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
positions (but all other marks are shared). Third, embedded windows, which are
arbitrary other widgets, cannot be shared between peers. This means the
\fB\-window\fR option of embedded windows is independently set for each peer
(it is advisable to use the \fB\-create\fR script capabilities to allow each
peer to create its own embedded windows as needed). Fourth, all of the
configuration options of each peer (e.g. \fB\-font\fR, etc) can be set
independently, with the exception of \fB\-undo\fR, \fB\-maxundo\fR,
\fB\-maxundosize\fR, \fB\-maxredo\fR, \fB\-autoseparators\fR (i.e. all undo,
redo and modified state issues are shared). Also option \fB\-steadymarks\fR
cannot be set independently.
.PP
Finally any single peer need not contain the whole content from the
underlying data store. When creating a peer, a contiguous range (e.g. only
range
.QW 52.begin
through
.QW 125.end
) may be specified. This allows a peer to contain just a small portion of
the overall text. The range will expand and contract as text is inserted or

deleted. If the peer's contents contracts to nothing (i.e. the start of the

content is after last newline, as a result of a deletion from another
widget), then it is impossible for new content to be inserted. The peer will
simply become an empty shell (dead peer) on which the background can be
configured, but which will never show any content (without manual
reconfiguration of the start and end range). Note that a peer which does not
contain all of the underlying data store still has indices numbered from
.QW 1.0
to
.QW end .
It is simply that those indices reflect a subset of the total data, and data
outside the contained range is not accessible to the peer. This means that
the command \fIpeerName \fBindex end\fR may return quite different values in
different peers. Similarly, commands like \fIpeerName \fBtag ranges\fR will not
return index ranges outside that which is meaningful to the peer. The
configuration options \fB\-startindex\fR and \fB\-endindex\fR may be used to
control how much of the underlying data is contained in any given text widget.
.PP
Note that peers are really peers. Deleting the
.QW original
text widget will not cause any other peers to be deleted, or otherwise
affected.
.PP
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
commands always wait for the end of the update calculation each time they are
called. In most use cases of these commands a more or less inaccurate result
does not really matter compared to execution speed.
.PP
In case accurate result is needed (and if the text widget is managed by a
geometry manager), one can resort to \fIpathName \fBsync\fR and \fIpathName
\fBpendingsync\fR to control the synchronization of the view of text widgets.



.PP
The \fB<<WidgetViewSync>>\fR virtual event fires when the line heights of the
text widget become obsolete (due to some editing command or configuration
change), and again when the internal data of the text widget are back in sync
with the widget view. The detail field (%d substitution) is either true (when
the widget is in sync) or false (when it is not).
.PP
\fIpathName \fBsync\fR, \fIpathName \fBpendingsync\fR and
\fB<<WidgetViewSync>>\fR apply to each text widget independently of its peers.

.PP
Examples of use:


.CS
## Example 1:
# immediately complete line metrics at any cost (GUI unresponsive)
$w sync
$w yview moveto $fraction

## Example 2:

# synchronously wait for up-to-date line metrics (GUI responsive)
# before executing the scheduled command, but don't block execution flow



$w sync -command [list $w yview moveto $fraction]

## Example 3:





# init
set yud($w) 0
proc updateaction w {
\&set ::yud($w) 1
\&# any other update action here...
}
# runtime, synchronously wait for up-to-date line metrics (GUI responsive)

$w sync -command [list updateaction $w]
vwait yud($w)
$w yview moveto $fraction






























## Example 4:
# init
set todo($w) {}
proc updateaction w {
\&foreach cmd $::todo($w) {uplevel #0 $cmd}
\&set todo($w) {}
}

# runtime



lappend todo($w) [list $w yview moveto $fraction]













$w sync -command [list updateaction $w]



















## Example 5:

# init
set todo($w) {}
bind $w <<WidgetViewSync>> {
\&if {%d} {
\&\&foreach cmd $todo(%W) {eval $cmd}
\&\&set todo(%W) {}


\&}

}
# runtime
if {![$w pendingsync]} {
\&$w yview moveto $fraction
} else {
\&lappend todo($w) [list $w yview moveto $fraction]
}
.CE






.SH "WIDGET COMMAND"
.PP
The \fBtext\fR command creates a new Tcl command whose name is the same as the
path name of the text's window. This command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as the text
widget's path name. \fIOption\fR and the \fIarg\fRs determine the exact
behavior of the command. The following commands are possible for text widgets:
.TP
\fIpathName \fBbbox \fIindex\fR
.
Returns a list of four elements describing the screen area of the character
given by \fIindex\fR. The first two elements of the list give the x and y
coordinates of the upper-left corner of the area occupied by the character,
and the last two elements give the width and height of the area. If the
character is only partially visible on the screen, then the return value
reflects just the visible part. If the character is not visible on the screen
then the return value is an empty list.












.TP
































\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtext\fR command.
.TP























































\fIpathName \fBcompare\fR \fIindex1 op index2\fR
.
Compares the indices given by \fIindex1\fR and \fIindex2\fR according to the
relational operator given by \fIop\fR, and returns 1 if the relationship is
satisfied and 0 if it is not. \fIOp\fR must be one of the operators <, <=, ==,
>=, >, or !=. If \fIop\fR is == then 1 is returned if the two indices refer to
the same character, if \fIop\fR is < then 1 is returned if \fIindex1\fR refers







>
>
>









>

|
>
>

<
<
|

|
<
>
|
|
>
>
>
|
|
<
>
>
>
>
>



|
|

|
>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
<
<
<

>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
<
|
|
|
|
>
>
|
>

|
|
|
<
<


>
>
>
>
>
>












|








>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
commands always wait for the end of the update calculation each time they are
called. In most use cases of these commands a more or less inaccurate result
does not really matter compared to execution speed.
.PP
In case accurate result is needed (and if the text widget is managed by a
geometry manager), one can resort to \fIpathName \fBsync\fR and \fIpathName
\fBpendingsync\fR to control the synchronization of the view of text widgets.
Alternatively, in very special cases (in general this would cause performance
problem), setting widget option \fB\-synctime\fR to zero provides accurate
results at any time.
.PP
The \fB<<WidgetViewSync>>\fR virtual event fires when the line heights of the
text widget become obsolete (due to some editing command or configuration
change), and again when the internal data of the text widget are back in sync
with the widget view. The detail field (%d substitution) is either true (when
the widget is in sync) or false (when it is not).
.PP
\fIpathName \fBsync\fR, \fIpathName \fBpendingsync\fR and
\fB<<WidgetViewSync>>\fR apply to each text widget independently of its peers.
.SS "EXAMPLES OF USE"
.PP
This immediately completes line metrics at any cost; the GUI
unresponsive while this is occurring:
.PP
.CS


\fB$w sync\fR
$w yview moveto $fraction
.CE

.PP
This synchronously waits for up-to-date line metrics (but with the GUI
responsive) before executing the scheduled command, but does not block
execution flow:
.PP
.CS
\fB$w sync\fR -command [list $w yview moveto $fraction]
.CE

.PP
This synchronously waits for up-to-date line metrics while keeping the
GUI responsive:
.PP
.CS
# init
set yud($w) 0
proc updateaction w {
    set ::yud($w) 1
    # any other update action here...
}

# runtime
\fB$w sync\fR -command [list updateaction $w]
vwait yud($w)
$w yview moveto $fraction
.CE
.PP
This is an extension of the previous example with a list of actions to
perform once the synchronization is completed.
.PP
.CS
# init
set todo($w) {}
proc updateaction w {
    foreach cmd $::todo($w) {uplevel #0 $cmd}
    set todo($w) {}
}

# runtime
lappend todo($w) [list $w yview moveto $fraction]
\fB$w sync\fR -command [list updateaction $w]
.CE
.PP
This detects whether a synchronization is pending, and if so just
postpones the code until that synchronization is done, detecting that
happening with a virtual event.
.PP
.CS
# init
set todo($w) {}
bind $w \fB<<WidgetViewSync>>\fR {
    if {%d} {
        foreach cmd $todo(%W) {eval $cmd}
        set todo(%W) {}
    }






}

# runtime
if {![\fB$w pendingsync\fR]} {
    $w yview moveto $fraction
} else {
    lappend todo($w) [list $w yview moveto $fraction]
}
.CE
.SH "IMPROVING THE PERFORMANCE WITH TAGS"
.PP
The use of thousands of different tags when inserting text is a bit slow.
Often such a large number of different tags can be avoided. Example:
.PP
.CS
set n 0
foreach i $items {
    $w insert insert $i [incr n] " "
    $w tag bind $n <Enter> [list Hilite $w $n yellow]
    $w tag bind $n <Leave> [list Hilite $w $n {}]
    $w tag bind $n <1> [list Action $w $n]
}
proc Hilite {w n bg} {
    $w tag configure $n -background $bg
}
proc Action {w n} {
    # do any action based on number $n
}
.CE
.PP
This piece of code assigns an unique tag to each item, used for
highlighting and identifying the item. But this can be solved in a
different way, with only two tags:
.PP
.CS
set n 0
foreach i $items {
    $w mark set [incr n] insert left
    $w insert end $i item " "
}

$w tag configure hilite -background yellow
$w tag bind item <Enter> {Enter %W}

$w tag bind item <Leave> {Leave %W}
$w tag bind item <1> {Action %W}

proc Enter {w} {
    $w tag add hilite item.current.first item.current.last
}
proc Leave {w} {
    $w tag remove hilite begin end
}
proc Action {w} {
    set n [$w mark previous item.current.last {[0-9]*}]
    # do any action based on number $n


}
.CE
.PP
The latter method may improve the performance of text insertion
significantly, because marks are very efficient, even if thousands
of marks are in usage. Also the number of bindings will be reduced,
so the overall consumption of resources is reduced.
.PP
.SH "WIDGET COMMAND"
.PP
The \fBtext\fR command creates a new Tcl command whose name is the same as the
path name of the text's window. This command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as the text
widget's path name. \fIOption\fR and the \fIarg\fRs determine the exact
behavior of the command. The following commands are possible for text widgets:
.TP
\fIpathName \fBbbox\fR ?\fB\-extents\fR? \fIindex\fR
.
Returns a list of four elements describing the screen area of the character
given by \fIindex\fR. The first two elements of the list give the x and y
coordinates of the upper-left corner of the area occupied by the character,
and the last two elements give the width and height of the area. If the
character is only partially visible on the screen, then the return value
reflects just the visible part. If the character is not visible on the screen
then the return value is an empty list.
.RS
.PP
If space mode \fBtrim\fR is set (see option \fB\-spacemode\fR) then the trimmed
spaces will be measured with a width of zero.
.PP
If option \fB\-extents\fR is specified then a list of four elements describing
the invisible extents of the bounding box will returned. If x/y (first/second
value) is not zero, then the first x/y pixels are not visible on screen. If
width/height (third/fourth value) is not zero, then the last width/height
pixels are not visible on screen. If the line which contains this character
is not visible on the screen, then the return value is an empty list.
.RE
.TP
\fIpathName \fBbrks\fR \fIstring\fR \fI?lang\fR?
.
This command expects a \fIstring\fR of characters, and the result is a list of
integers. This list has exactly the character length of the given string,
and integer value 1 in this list denotes a potential line break point at
this character position, value 2 denotes a mandatory line break point, and
value 0 (zero) denotes no line break at this character position. If the
optional language code is specified (see widget option \fB\-lang\fR for
language codes), then the external library \fIlibunibreak\fR (from Wu
Yongwei) will be used for the line break computation; an error will be
thrown if this library is not available. If no language code is specified,
then the internal wrap algorithm will be used: also based on the
recommendations of the Unicode consortium, but restricted to Latin-1 and
most non-language dependent characters, without regarding combined marks,
and without language support.
.RS
.PP
This command has three purposes:
.IP [1] 4
It provides a simple check whether \fIlibunibreak\fR is available or not
(even an empty string, and any language code, e.g.
.QW xx ,
works for this check). An error will be thrown if \fIlibunibreak\fR
is not available, but a language code has been specified (\fB\-lang\fR).
.IP [2] 4
For a proof of the line break algorithm, especially for testing the internal
algorithm.
.IP [3] 4
It is also conceivable to use this function for the computation of line
breaks inside other widgets.
.RE
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Returns the current value of the configuration option given by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtext\fR command.
.TP
\fIpathName \fBchecksum\fR
.
Computes a checksum over the whole widget content. The result is platform
independent.
.RS
.PP
One or more of the following switches (or abbreviations thereof) may be
specified to control the extraction:
.IP \fB\-all\fR
Computes the checksum over all these elements: chars (characters and soft
hyphens), tags, images, and windows. This is the default, and includes the
following switches: \fB\-chars\fR, \fB\-image\fR, \fB\-tag\fR,
\fB\-window\fR.
.IP \fB\-chars\fR
The computation considers all characters and soft hyphens.
.IP \fB\-displaychars\fR
If this option is given, then only those characters and soft hyphens which
are not elided will be considered in the computation of the checksum.
.IP \fB\-displaytext\fR
If this option is given, then only those characters which are not elided
will be considered in the computation of the checksum. Note that soft
hyphens (Unicode point U+00AD) do not belong to this result.
.IP \fB\-image\fR
The computation considers all embedded images. In case of an image the name
of the image will be used for the checksum computation.
.IP \fB\-mark\fR
The computation considers all marks. In case of a mark the name of the mark
and his gravity will be used for the checksum computation. Note that the
computation discards generated marks, and it discards the special marks
\fBcurrent\fR, and \fBinsert\fR.
.IP \fB\-tag\fR
Consider tag information in the checksum computation. The name of the tags
associated to this data (characters, soft hyphen, image, or window) will be
used for the checksum computation. But this computation also considers the
priority of the tags.
.IP \fB\-text\fR
The computation considers all characters. Note that soft hyphens (Unicode
point U+00AD) do not belong to this result.
.IP \fB\-window\fR
The computation considers all embedded windows. In case of a window the
pathname of the window will be used for the checksum computation.
.RE
.TP
\fIpathName \fBclear\fR
.
This command is clearing the overall widget, this affects all the
characters, soft hyphens, embedded images, embedded windows, tag
information, and marks. This is not bounded by restrictions, given with
option \fB\-startindex\fR/\fB\-endindex\fR. Also the undo stack will be cleared.
It's like a reset to the initial state, without resetting the options of the
widget, and without clearing widget bindings. Also the states
\fBedit modified\fR, \fBedit altered\fR, and \fBedit irreversible\fR will be
resetted to false. The widget now will be overall clean (see command
\fBisclean \-overall\fR). Note that this operation cannot be undone.
.TP
\fIpathName \fBcompare\fR \fIindex1 op index2\fR
.
Compares the indices given by \fIindex1\fR and \fIindex2\fR according to the
relational operator given by \fIop\fR, and returns 1 if the relationship is
satisfied and 0 if it is not. \fIOp\fR must be one of the operators <, <=, ==,
>=, >, or !=. If \fIop\fR is == then 1 is returned if the two indices refer to
the same character, if \fIop\fR is < then 1 is returned if \fIindex1\fR refers
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
specified). If one or more \fIoption\-value\fR pairs are specified, then the
command modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string. \fIOption\fR may have any of
the values accepted by the \fBtext\fR command.
.TP
\fIpathName \fBcount\fR ?\fIoptions\fR? \fIindex1 index2\fR
.
Counts the number of relevant things between the two indices. If \fIindex1\fR
is after \fIindex2\fR, the result will be a negative number (and this holds
for each of the possible options). The actual items which are counted depend
on the options given. The result is a list of integers, one for the result of
each counting option given. Valid counting options are \fB\-chars\fR,

\fB\-displaychars\fR, \fB\-displayindices\fR, \fB\-displaylines\fR,

\fB\-indices\fR, \fB\-lines\fR, \fB\-xpixels\fR and \fB\-ypixels\fR. The
default value, if no option is specified, is \fB\-indices\fR. There is an
additional possible option \fB\-update\fR which is a modifier. If given (and
if the text widget is managed by a geometry manager), then all subsequent
options ensure that any possible out of date information is recalculated.
This currently only has any effect for the \fB\-ypixels\fR count (which, if
\fB\-update\fR is not given, will use the text widget's current cached value
for each line). This \fB\-update\fR option is obsoleted by \fIpathName
\fBsync\fR, \fIpathName \fBpendingsync\fR and \fB<<WidgetViewSync>>\fR.  The
count options are interpreted as follows:
.RS
.IP \fB\-chars\fR
count all characters, whether elided or not. Do not count embedded windows or
images.
.IP \fB\-displaychars\fR
count all non-elided characters.


.IP \fB\-displayindices\fR
count all non-elided characters, windows and images.

.IP \fB\-displaylines\fR
count all display lines (i.e. counting one for each time a line wraps) from
the line of the first index up to, but not including the display line of the
second index. Therefore if they are both on the same display line, zero will
be returned. By definition displaylines are visible and therefore this only
counts portions of actual visible lines.





.IP \fB\-indices\fR
count all characters and embedded windows or images (i.e. everything which
counts in text-widget index space), whether they are elided or not.

.IP \fB\-lines\fR
count all logical lines (irrespective of wrapping) from the line of the first
index up to, but not including the line of the second index. Therefore if they
are both on the same line, zero will be returned. Logical lines are counted
whether they are currently visible (non-elided) or not.


.IP \fB\-xpixels\fR
count the number of horizontal pixels from the first pixel of the first index
to (but not including) the first pixel of the second index. To count the total
desired width of the text widget (assuming wrapping is not enabled), first

find the longest line and then use
.QW ".text count \-xpixels \N'34'${line}.0\N'34' \N'34'${line}.0 lineend\N'34'" .
.IP \fB\-ypixels\fR
count the number of vertical pixels from the first pixel of the first index to
(but not including) the first pixel of the second index. If both indices are
on the same display line, zero will be returned. To count the total number of
vertical pixels in the text widget, use
.QW ".text count \-ypixels 1.0 end" ,
and to ensure this is up to date, use
.QW ".text count \-update \-ypixels 1.0 end" .
.PP
The command returns a positive or negative integer corresponding to the number
of items counted between the two indices. One such integer is returned for
each counting option given, so a list is returned if more than one option was
supplied. For example
.QW ".text count \-xpixels \-ypixels 1.3 4.5"
is perfectly valid and will return a list of two elements.
.RE
.TP
\fIpathName \fBdebug \fR?\fIboolean\fR?
.
If \fIboolean\fR is specified, then it must have one of the true or false
values accepted by Tcl_GetBoolean. If the value is a true one then internal
consistency checks will be turned on in the B-tree code associated with text
widgets. If \fIboolean\fR has a false value then the debugging checks will be
turned off. In either case the command returns an empty string. If
\fIboolean\fR is not specified then the command returns \fBon\fR or \fBoff\fR
to indicate whether or not debugging is turned on. There is a single debugging
switch shared by all text widgets: turning debugging on or off in any widget
turns it on or off for all widgets. For widgets with large amounts of text,
the consistency checks may cause a noticeable slow-down.
.RS
.PP
When debugging is turned on, the drawing routines of the text widget set the
global variables \fBtk_textRedraw\fR and \fBtk_textRelayout\fR to the lists of
indices that are redrawn. The values of these variables are tested by Tk's
test suite.
.RE
.TP
\fIpathName \fBdelete \fIindex1 \fR?\fIindex2 ...\fR?
.
Delete a range of characters from the text.
If both \fIindex1\fR and \fIindex2\fR are specified, then delete
all the characters starting with the one given by \fIindex1\fR
and stopping just before \fIindex2\fR (i.e. the character at
\fIindex2\fR is not deleted).
If \fIindex2\fR does not specify a position later in the text
than \fIindex1\fR then no characters are deleted.
If \fIindex2\fR is not specified then the single character at
\fIindex1\fR is deleted.
Attempts to delete characters in a way that would leave
the text without a newline as the last character will be tweaked by the
text widget to avoid this. In particular, deletion of complete lines of
text up to the end of the text will also delete the newline character just



















before the deleted block so that it is replaced by the new final newline







of the text widget.

The command returns an empty string.


If more indices are given, multiple ranges of text will be deleted.
All indices are first checked for validity before any deletions are made.
They are sorted and the text is removed from the last range to the
first range so deleted text does not cause an undesired index shifting
side-effects.  If multiple ranges with the same start index are given,
then the longest range is used.  If overlapping ranges are given, then


they will be merged into spans that do not cause deletion of text
outside the given ranges due to text shifted during deletion.



.TP
\fIpathName \fBdlineinfo \fIindex\fR
.
Returns a list with five elements describing the area occupied by the display
line containing \fIindex\fR. The first two elements of the list give the x and
y coordinates of the upper-left corner of the area occupied by the line, the
third and fourth elements give the width and height of the area, and the fifth
element gives the position of the baseline for the line, measured down from
the top of the area. All of this information is measured in pixels. If the
current wrap mode is \fBnone\fR and the line extends beyond the boundaries of
the window, the area returned reflects the entire area of the line, including
the portions that are out of the window. If the line is shorter than the full
width of the window then the area returned reflects just the portion of the
line that is occupied by characters and embedded windows. If the display line



containing \fIindex\fR is not visible on the screen then the return value is
an empty list.










.TP
\fIpathName \fBdump \fR?\fIswitches\fR? \fIindex1 \fR?\fIindex2\fR?
.
Return the contents of the text widget from \fIindex1\fR up to, but not
including \fIindex2\fR, including the text and information about marks, tags,
and embedded windows. If \fIindex2\fR is not specified, then it defaults to
one character past \fIindex1\fR. The information is returned in the following
format:
.RS
.LP
\fIkey1 value1 index1 key2 value2 index2\fR ...
.LP
The possible \fIkey\fR values are \fBtext\fR, \fBmark\fR, \fBtagon\fR,
\fBtagoff\fR, \fBimage\fR, and \fBwindow\fR. The corresponding \fIvalue\fR is
the text, mark name, tag name, image name, or window name. The \fIindex\fR

information is the index of the start of the text, mark, tag transition, image

or window. One or more of the following switches (or abbreviations thereof)
may be specified to control the dump:
.TP
\fB\-all\fR
.
Return information about all elements: text, marks, tags, images and windows.
This is the default.









.TP
\fB\-command \fIcommand\fR
.
Instead of returning the information as the result of the dump operation,
invoke the \fIcommand\fR on each element of the text widget within the range.
The command has three arguments appended to it before it is evaluated: the
\fIkey\fR, \fIvalue\fR, and \fIindex\fR.
.TP
\fB\-image\fR
.
Include information about images in the dump results.
.TP
\fB\-mark\fR
.
Include information about marks in the dump results.
.TP




\fB\-tag\fR
.
Include information about tag transitions in the dump results. Tag information
is returned as \fBtagon\fR and \fBtagoff\fR elements that indicate the begin
and end of each range of each tag, respectively.
.TP
\fB\-text\fR
.
Include information about text in the dump results. The value is the text up
to the next element or the end of range indicated by \fIindex2\fR. A text
element does not span newlines. A multi-line block of text that contains no
marks or tag transitions will still be dumped as a set of text segments that
each end with a newline. The newline is part of the value.










.TP
\fB\-window\fR
.
Include information about embedded windows in the dump results. The value of a
window is its Tk pathname, unless the window has not been created yet. (It
must have a create script.) In this case an empty string is returned, and you
must query the window by its index position to get more information.





.RE
.TP
\fIpathName \fBedit \fIoption \fR?\fIarg ...\fR?
.
This command controls the undo mechanism and the modified flag. The exact
behavior of the command depends on the \fIoption\fR argument that follows the
\fBedit\fR argument. The following forms of the command are currently
supported:
.RS
.TP


































\fIpathName \fBedit canredo\fR
.





Returns a boolean true if redo is possible, i.e. when the redo stack is not
empty. Otherwise returns false.

.TP
\fIpathName \fBedit canundo\fR
.





Returns a boolean true if undo is possible, i.e. when the undo stack is not
empty. Otherwise returns false.
















































































































































































































































































































.TP
\fIpathName \fBedit modified \fR?\fIboolean\fR?
.
If \fIboolean\fR is not specified, returns the modified flag of the widget.

The insert, delete, edit undo and edit redo commands or the user can set or
clear the modified flag. If \fIboolean\fR is specified, sets the modified flag
of the widget to \fIboolean\fR.
.TP













\fIpathName \fBedit redo\fR
.
When the \fB\-undo\fR option is true, reapplies the last undone edits provided
no other edits were done since then, and returns a list of indices indicating
what ranges were changed by the redo operation. Generates an error when the
redo stack is empty. Does nothing when the \fB\-undo\fR option is false.
.TP
\fIpathName \fBedit reset\fR
.
Clears the undo and redo stacks.


.TP
\fIpathName \fBedit separator\fR
.
Inserts a separator (boundary) on the undo stack. Does nothing when the
\fB\-undo\fR option is false.





.TP
\fIpathName \fBedit undo\fR
.
Undoes the last edit action when the \fB\-undo\fR option is true, and returns a
list of indices indicating what ranges were changed by the undo operation. An
edit action is defined as all the insert and delete commands that are recorded

on the undo stack in between two separators. Generates an error when the undo


stack is empty. Does nothing when the \fB\-undo\fR option is false.










.RE

.TP
\fIpathName \fBget\fR ?\fB\-displaychars\fR? ?\fB\-\-\fR? \fIindex1\fR ?\fIindex2 ...\fR?
.
Return a range of characters from the text. The return value will be all the
characters in the text starting with the one whose index is \fIindex1\fR and
ending just before the one whose index is \fIindex2\fR (the character at
\fIindex2\fR will not be returned). If \fIindex2\fR is omitted then the single
character at \fIindex1\fR is returned. If there are no characters in the
specified range (e.g. \fIindex1\fR is past the end of the file or \fIindex2\fR
is less than or equal to \fIindex1\fR) then an empty string is returned. If
the specified range contains embedded windows, no information about them is
included in the returned string. If multiple index pairs are given, multiple
ranges of text will be returned in a list. Invalid ranges will not be
represented with empty strings in the list. The ranges are returned in the
order passed to \fIpathName \fBget\fR. If the \fB\-displaychars\fR option is















given, then, within each range, only those characters which are not elided






will be returned. This may have the effect that some of the returned ranges
are empty strings.

.TP
\fIpathName \fBimage \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded images. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBtag\fR
argument. The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBimage cget \fIindex option\fR
.
Returns the value of a configuration option for an embedded image. \fIIndex\fR
identifies the embedded image, and \fIoption\fR specifies a particular







|
|
|
|
|
>
|
>
|
|
|
|
|
|
|
<
<



|
|

|
>
>

|
>






>
>
>
>
>

|
|
>

|
|
|
|
>
>

|
|
|
>
|


|
|
|
|
|

|
<
<
<
<
<
<
<

















|




|

|
|
<
|
|
<
|
|
<
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
|
>
>
|
<
<
<
<
<
>
>
|
<
>
>
>

|











|
>
>
>


>
>
>
>
>
>
>
>
>
>





|
|
|




|
|
|
>
|
>
|
|



|
|
>
>
>
>
>
>
>
>
>
















>
>
>
>








|
|
|
|
|
>
>
>
>
>
>
>
>
>
>







>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>


>



>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
<


|

|
>
>

|


|
>
>
>
>
>



|
<
|
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>

>

|




|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
|
>




|







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
specified). If one or more \fIoption\-value\fR pairs are specified, then the
command modifies the given widget option(s) to have the given value(s); in
this case the command returns an empty string. \fIOption\fR may have any of
the values accepted by the \fBtext\fR command.
.TP
\fIpathName \fBcount\fR ?\fIoptions\fR? \fIindex1 index2\fR
.
Counts the number of relevant things between the two indices. If
\fIindex1\fR is after \fIindex2\fR, the result will be a negative number
(and this holds for each of the possible options). The actual items which
are counted depend on the options given. The result is a list of integers,
one for the result of each counting option given. Valid counting options are
\fB\-chars\fR, \fB\-displaychars\fR, \fB\-displayhyphens\fR,
\fB\-displayindices\fR, \fB\-displaylines\fR, \fB\-displaytext\fR,
\fB\-hyphens\fR, \fB\-indices\fR, \fB\-lines\fR, \fB\-text\fR,
\fB\-xpixels\fR and \fB\-ypixels\fR. The default value, if no option is
specified, is \fB\-indices\fR. There is an additional possible option
\fB\-update\fR which is a modifier. If given (and if the text widget is
managed by a geometry manager), then all subsequent options ensure that any
possible out of date information is recalculated. This currently only has
any effect for the \fB\-ypixels\fR count (which, if \fB\-update\fR is not
given, will use the text widget's current cached value for each line). The


count options are interpreted as follows:
.RS
.IP \fB\-chars\fR
count all characters, whether elided or not, this also includes soft
hyphens. Do not count embedded windows or images.
.IP \fB\-displaychars\fR
count all non-elided characters (see \fB\-chars\fR).
.IP \fB\-displayhyphens\fR
count all non-elided soft hyphens.
.IP \fB\-displayindices\fR
count all non-elided characters, soft hyphens, windows and images (see
\fB\-indices\fR).
.IP \fB\-displaylines\fR
count all display lines (i.e. counting one for each time a line wraps) from
the line of the first index up to, but not including the display line of the
second index. Therefore if they are both on the same display line, zero will
be returned. By definition displaylines are visible and therefore this only
counts portions of actual visible lines.
.IP \fB\-displaytext\fR
count all non-elided characters, but discard soft hyphens (see
\fB\-text\fR).
.IP \fB\-hyphens\fR
count all soft hyphens, whether elided or not.
.IP \fB\-indices\fR
count all characters, soft hyphens, and embedded windows or images (i.e.
everything which counts in text-widget index space), whether they are elided
or not.
.IP \fB\-lines\fR
count all logical lines (irrespective of wrapping) from the line of the
first index up to, but not including the line of the second index. Therefore
if they are both on the same line, zero will be returned. Logical lines are
counted whether they are currently visible (non-elided) or not.
.IP \fB\-text\fR
count all characters, whether elided or not, but discard soft hyphens.
.IP \fB\-xpixels\fR
count the number of horizontal pixels from the first pixel of the first
index to (but not including) the first pixel of the second index. To count
the total desired width of the text widget (assuming wrapping is not
enabled, and the used font is ideally monospaced), first find the longest
line and then use
.QW ".text count \-xpixels \N'34'${line}.0\N'34' \N'34'${line}.0 lineend\N'34'" .
.IP \fB\-ypixels\fR
count the number of vertical pixels from the first pixel of the first index
to (but not including) the first pixel of the second index. If both indices
are on the same display line, zero will be returned. To count the total
number of vertical pixels in the text widget, use
.QW ".text count \-ypixels begin end" ,
and to ensure this is up to date, use
.QW ".text count \-update \-ypixels begin end" .







.RE
.TP
\fIpathName \fBdebug \fR?\fIboolean\fR?
.
If \fIboolean\fR is specified, then it must have one of the true or false
values accepted by Tcl_GetBoolean. If the value is a true one then internal
consistency checks will be turned on in the B-tree code associated with text
widgets. If \fIboolean\fR has a false value then the debugging checks will be
turned off. In either case the command returns an empty string. If
\fIboolean\fR is not specified then the command returns \fBon\fR or \fBoff\fR
to indicate whether or not debugging is turned on. There is a single debugging
switch shared by all text widgets: turning debugging on or off in any widget
turns it on or off for all widgets. For widgets with large amounts of text,
the consistency checks may cause a noticeable slow-down.
.RS
.PP
When debugging is turned on, the drawing routines of the text widget set the
global variables \%\fBtk_textRedraw\fR and \%\fBtk_textRelayout\fR to the lists of
indices that are redrawn. The values of these variables are tested by Tk's
test suite.
.RE
.TP
\fIpathName \fBdelete \fI?options\fR? \fIindex1\fR ?\fIindex2 ...\fR?
.
Delete a range of characters from the text. If both \fIindex1\fR and
\fIindex2\fR are specified, then delete all the characters starting with the

one given by \fIindex1\fR and stopping just before \fIindex2\fR (i.e. the
character at \fIindex2\fR is not deleted). If \fIindex2\fR does not specify

a position later in the text than \fIindex1\fR then no characters are
deleted. If \fIindex2\fR is not specified then the single character at

\fIindex1\fR is deleted. Attempts to delete characters in a way that would
leave the text without a newline as the last character will be tweaked by
the text widget to avoid this. In particular, deletion of text up to the end
of the text (inclusively the last newline) will not delete the last newline,
but the tag associations of this newline will be cleared. The command
returns an empty string. If more indices are given, multiple ranges of text
will be deleted. All indices are first checked for validity before any
deletions are made. They are sorted and the text is removed from the last
range to the first range so deleted text does not cause an undesired index
shifting side-effects. If multiple ranges with the same start index are
given, then the longest range is used. If overlapping ranges are given, then
they will be merged into spans that do not cause deletion of text outside
the given ranges due to text shifted during deletion.
.RS
.PP
This command allows the following options:
.IP \fB\-marks\fR
Additionally all the marks belonging to the specified range will be deleted.
Here the indices will be interpreted differenty (but it's important to note
that this re-interpretation is not affecting the range of character
deletion). If \fIindex1\fR is specified in a numerical form the deletion of
the marks starts with the first mark at this position, otherwise it starts
with the next mark after that mark; provided that a mark at this position
exists, otherwise the deletion starts at first character position. If
\fIindex2\fR is specified in a numerical form the deletion ends with the
first mark at this position (not including this mark), otherwise it ends
immediately before that mark; provided that a mark at this position exists,
otherwise the deletion ends just before last character position (specified
with \fIindex2\fR). If \fIindex2\fR is unspecified then \fIindex2\fR will be
assumed as equal to "$index1+1c". This option is especially intended for
programmed editor control, if option \fB\-steadymarks\fR is activated. Note
that the special marks
.QW insert
and
.QW current ,
and also generated marks (see
\fBmark generate\fR), will not be deleted.





.IP \fB\-inclusive\fR
This option is useful only if combined with option \fB\-marks\fR. It causes
that also the marks referred to by \fIindex1\fR and \fIindex2\fR will be

deleted (provided that the concerned mark is neither a special mark \- \fBinsert\fR
or \fBcurrent\fR, \- nor a generated mark).
.RE
.TP
\fIpathName \fBdlineinfo\fR ?\fB\-extents\fR? \fIindex\fR
.
Returns a list with five elements describing the area occupied by the display
line containing \fIindex\fR. The first two elements of the list give the x and
y coordinates of the upper-left corner of the area occupied by the line, the
third and fourth elements give the width and height of the area, and the fifth
element gives the position of the baseline for the line, measured down from
the top of the area. All of this information is measured in pixels. If the
current wrap mode is \fBnone\fR and the line extends beyond the boundaries of
the window, the area returned reflects the entire area of the line, including
the portions that are out of the window. If the line is shorter than the full
width of the window then the area returned reflects just the portion of the
line that is occupied by characters and embedded windows. If the current wrap
mode is different from \fBnone\fR, the area returned reflects the area occupied
by all characters displayed on this line, which can be smaller than the widget
width. If the display line
containing \fIindex\fR is not visible on the screen then the return value is
an empty list.
.RS
.PP
If option \fB\-extents\fR is specified then a list of four elements describing
the invisible extents of the bounding box will returned, plus a fifth value
for the baseline position. If x/y (first/second value) is not zero, then the
first x/y pixels are not visible on screen. If width/height (third/fourth
value) is not zero, then the last width/height pixels are not visible on
screen. If the display line containing \fIindex\fR is not visible on the
screen then the return value is an empty list.
.RE
.TP
\fIpathName \fBdump \fR?\fIswitches\fR? \fIindex1 \fR?\fIindex2\fR?
.
Return the contents of the text widget from \fIindex1\fR up to, but not
including \fIindex2\fR, including the text and information about marks, tags,
and embedded windows, and images. If \fIindex2\fR is not specified, then it
defaults to one character past \fIindex1\fR. The information is returned in
the following format:
.RS
.LP
\fIkey1 value1 index1 key2 value2 index2\fR ...
.LP
The possible \fIkey\fR values are \fBtext\fR, \fBhyphen\fR, \fBmark\fR,
\fBtagon\fR, \fBtagoff\fR, \fBimage\fR, \fBwindow\fR and \fBnode\fR. The
corresponding \fIvalue\fR is the text, mark name, tag name, image name,
window name or node identifier, the hyphen has no value (this means the
value is empty). The \fIindex\fR information is the index of the start of
the text, hyphen, mark, tag transition, image, window or node. One or more
of the  following switches (or abbreviations thereof) may be specified to
control the dump:
.TP
\fB\-all\fR
.
Return information about all elements: text, hyphens, marks, tags, images
and windows (but not nodes). This is the default.
.TP
\fB\-chars\fR
.
Include information about text (characters and soft hyphens) in the dump
results. The value is the text up to the next element or the end of range
indicated by \fIindex2\fR. A text element does not span newlines. A
multi-line block of text that contains no marks or tag transitions will
still be dumped as a set of text segments that each end with a newline. The
newline is part of the value.
.TP
\fB\-command \fIcommand\fR
.
Instead of returning the information as the result of the dump operation,
invoke the \fIcommand\fR on each element of the text widget within the range.
The command has three arguments appended to it before it is evaluated: the
\fIkey\fR, \fIvalue\fR, and \fIindex\fR.
.TP
\fB\-image\fR
.
Include information about images in the dump results.
.TP
\fB\-mark\fR
.
Include information about marks in the dump results.
.TP
\fB\-node\fR
This information is for debugging only. It informs that the following
content will belong to this B-Tree node.
.TP
\fB\-tag\fR
.
Include information about tag transitions in the dump results. Tag information
is returned as \fBtagon\fR and \fBtagoff\fR elements that indicate the begin
and end of each range of each tag, respectively.
.TP
\fB\-text\fR
.
Include information about text (characters) in the dump results. The value
is the text up to the next element or the end of range indicated by
\fIindex2\fR. A text element does not span newlines. A multi-line block of
text that contains no marks or tag transitions will still be dumped as a set
of text segments that each end with a newline. The newline is part of the
value. Note that soft hyphens (Unicode point U+00AD) do not belong to this
result.
.TP
\fB\-tags \fItagList\fR
.
Specifies a set of tags to apply to the embedded window. \fITagList\fR consists
of a list of tag names, which replace any existing tags for the embedded window.
\fITagList\fR may be an empty list. Note that it is not possible to add or
remove the special selection tag \fBsel\fR, it will be left untouched with this
option.
.TP
\fB\-window\fR
.
Include information about embedded windows in the dump results. The value of a
window is its Tk pathname, unless the window has not been created yet. (It
must have a create script.) In this case an empty string is returned, and you
must query the window by its index position to get more information.
.TP
\fB\--\fR
.
This switch has no effect except to terminate the list of switches: the next
argument will be treated as pattern even if it starts with \-.
.RE
.TP
\fIpathName \fBedit \fIoption \fR?\fIarg ...\fR?
.
This command controls the undo mechanism and the modified flag. The exact
behavior of the command depends on the \fIoption\fR argument that follows the
\fBedit\fR argument. The following forms of the command are currently
supported:
.RS
.TP
\fIpathName \fBedit altered\fR
.
Returns whether changes have been done (eventual) affecting the text
content, or the representation of the text content. Any of the following
commands can set this flag to true:
.RS
.IP [1] 4
\fIpathName \fBdelete\fR
.IP [2] 4
\fIpathName \fBedit redo\fR
.IP [3] 4
\fIpathName \fBinsert\fR
.IP [4] 4
\fIpathName \fBmark gravity|set|unset\fR
(but only if \fB\-steadymarks\fR is enabled)
.IP [5] 4
\fIpathName \fBtag add|clear|lower|raise|remove\fR
(but not if \fB\-undo\fR of affected tag is false)
.IP [6] 4
\fIpathName \fBinsert\fR
.RE
.RS
.PP
This flag will be false before any of these operations have been done. It
can never be false if \fBedit irreversible\fR reports true. It will be true
after \fBclear\fR and \fBload\fR, and it will be true again if all changes
have been undone (with \fBedit undo\fR or \fBedit recover\fR). Also enabling
the undo stack (via widget option \fB\-undo\fR) will reset this state to false.
.PP
Any change of this state, if caused by an operation with (eventual) effects
on the (representation of the) text content, will trigger the virtual event
\fB<<Altered>>\fR.
.RE
.TP
\fIpathName \fBedit canredo\fR
.
Note that this command is deprecated, command \fIpathName\fR \fBedit info\fR
should be used instead. For compatibility reasons this command still will be
supported, but may be removed in a future version.
.RS
.PP
Returns a boolean true if redo is possible, i.e. when the redo stack is not
empty. Otherwise returns false.
.RE
.TP
\fIpathName \fBedit canundo\fR
.
Note that this command is deprecated, command \fIpathName\fR \fBedit info\fR
should be used instead. For compatibility reasons this command still will be
supported, but may be removed in a future version.
.RS
.PP
Returns a boolean true if undo is possible, i.e. when the undo stack is not
empty. Otherwise returns false.
.RE
.TP
\fIpathName \fBedit info\fR ??--? \fIarray\fR? | ?\fI-option\fR?
.
Returns information about edit states.
.RS
.TP
\fIpathName \fBedit info\fR ?--? ?\fIarray\fR?
.
Stores an array of some edit information in given variable \fIarray\fR, if
\fIarray\fR is not given then an unnamed variable will be used. The name of
the array must not start with a hyphen (\fB-\fR), unless it will be preceeded
with \fB--\fR, otherwise it will be treated as an option (see chapter below).
.RS
.PP
This command returns the array name \fIarray\fR, or an empty string (unnamed
variable) if \fIarray\fR is not specified.
.PP
This is the available information related to this widget:
.IP
\fBbytesize\fR
.
.RS
Current byte size, only characters have been counted (a character may have
more than one byte).
.RE
.IP
\fBlines\fR
.
.RS
Current number of lines.
.RE
.IP
\fBvisibleimages\fR
.
.RS
Number of visible embedded images.
.RE
.IP
\fBvisiblewindows\fR
.
.RS
Number of visible embedded windows.
.RE
.PP
This is the available information related to whole content:
.IP
\fBtotalbytesize\fR
.
.RS
Current byte size, only characters have been counted (a character may have
more than one byte).
.RE
.IP
\fBundodepth\fR
.
.RS
The depth (number of undoable actions) of the undo stack.
.RE
.IP
\fBredodepth\fR
.
.RS
The depth (number of redoable actions) of the redo stack.
.RE
.IP
\fBundostacksize\fR
.
.RS
Current number of items on undo stack.
.RE
.IP
\fBredostacksize\fR
.
.RS
Current number of items on redo stack.
.RE
.IP
\fBundobytesize\fR
.
.RS
Current number of bytes on the undo stack, only characters have been counted
(a character may have more than one byte).
.RE
.IP
\fBredobytesize\fR
.
.RS
Current number of bytes on the redo stack, only characters have been counted
(a character may have more than one byte).
.RE
.IP
\fBundocommands\fR
.
.RS
If the current undo stack action does not contain an undo atom, then this
information is empty. Otherwise it contains the list of commands that have
been pushed for undoing onto the stack since last inserted separator. A
command is one of: \fIdelete\fR, \fIimage\fR, \fIinsert\fR, \fImark\fR,
\fItag\fR, or \fIwindow\fR. Note that \fImark\fR can only occur when option
\fB\-steadymarks\fR is enabled. Also note that the \fBreplace\fR command is
pushing either \fIdelete\fR and \fIinsert\fR. Further note that this list
contains all edit operations of the current undo atom, this means that some
commands can occur repeatedly.
.RE
.IP
\fBredocommands\fR
.
.RS
If the current undo stack action does not contain an redo atom, then this
information is empty. Otherwise it contains the list of commands that have
been undone with current undo command, see \fBundocommands\fR for more
details.
.RE
.IP
\fBtotallines\fR
.
.RS
Current number of lines.
.RE
.IP
\fBimages\fR
.
.RS
Number of embedded images.
.RE
.IP
\fBwindows\fR
.
.RS
Number of embedded windows.
.RE
.IP
\fBtags\fR
.
.RS
Number of currently defined tags.
.RE
.IP
\fBusedtags\fR
.
.RS
Number of tags currently used.
.RE
.IP
\fBmarks\fR
.
.RS
Number of currently defined marks, this does not include the special marks
\fIinsert\fR and \fIcurrent\fR, nor the generated marks (see
\fBmark generate\fR).
.RE
.IP
\fBgeneratedmarks\fR
.
.RS
Number of generated marks currently defined (see \fBmark generate\fR).
.RE
.PP
This information is unrelated to the content:
.IP
\fBlinespernode\fR
.
.RS
Minimal number of lines per node in B-Tree, this information is only useful
for testing.
.RE
.PP
In the future the information might be extended. Note that embedded windows
and images will each be count with byte size one.
.RE
.TP
\fIpathName \fBedit info\fR -\fIoption\fR
.
This version will return only the specified value. \fIOption\fR is one of
\fBbytesize\fR, \fBgeneratedmarks\fR, \fBimages\fR, \fBlines\fR, \fBlinespernode\fR, \fBmarks\fR,
\fBredobytesize\fR, \fBredocommands\fR, \fBredodepth\fR, \fBredostacksize\fR, \fBtags\fR,
\fBtotalbytesize\fR, \fBtotallines\fR, \fBundobytesize\fR, \fBundocommands\fR, \fBundodepth\fR,
\fBundostacksize\fR, \fBusedtags\fR, \fBvisibleimages\fR, \fBvisiblewindows\fR, or \fBwindows\fR.
See chapter above about the meaning.
.RE
.TP
\fIpathName \fBedit inspect\fR ?\fIstack\fR?
.
Returns information about all undo, or redo, atoms. If \fIstack\fR is
specified (must be either \fBundo\fR or \fBredo\fR), then only the
information of this stack will be returned, otherwise the result contains
two lists, firstly all undo atoms, and secondly all redo atoms. Any atom
information contains at least one sub-atom. Each sub-atom is a list where the
first element of the list (at least) describes the nature of the sub-atom.
.RS
.PP
This is an informal description about the sub-atom content:
.PP
{\fBclear\fR}
.RS
Redo clearing tag associations (\fBtag clear\fR).
.RE
.PP
{\fBclear \fItag-list skip length\fR ...}
.RS
Undo clearing tag associations (\fBtag clear\fR).
.RE
.PP
{\fBdelete\fR}
.RS
Redo the deletion either of characters, hyphen, embedded image, or embedded
window (\fBdelete\fR).
.RE
.PP
{\fBdelete character \fIstring tag-list\fR}
.RS
Undo the deletion of characters (\fBdelete\fR), does not contain soft
hyphens.
.RE
.PP
{\fBdelete hyphen \fItag-list\fR}
.RS
Undo the deletion of a soft hyphen (\fBdelete\fR).
.RE
.PP
{\fBdelete image \fItag-list image-options\fR}
.RS
Undo the deletion of an embedded image (\fBdelete\fR).
.RE
.PP
{\fBdelete window \fItag-list window-options\fR}
.RS
Undo the deletion of an embedded window (\fBdelete\fR).
.RE
.PP
{\fBinsert\fR}
.RS
Undo an \fBinsert\fR operation; either characters, hyphen, embedded image,
or embedded window.
.RE
.PP
{\fBinsert character \fIstring tag-list\fR}
.RS
Redo an \fBinsert\fR operation of characters.
.RE
.PP
{\fBinsert hyphen \fItag-list\fR}
.RS
Redo an \fBinsert\fR operation of a soft hyphen.
.RE
.PP
{\fBinsert image \fItag-list image-options\fR}
.RS
Redo an \fBinsert\fR operation of an embedded image.
.RE
.PP
{\fBinsert window \fItag-list window-options\fR}
.RS
Redo an \fBinsert\fR operation of an embedded window.
.RE
.PP
{\fBmark gravity \fIname\fR}
.RS
Undo/redo toggling the gravity of a mark; either from \fIleft\fR to
\fIright\fR, or from \fIright\fR to \fIleft\fR (\fBtag gravity\fR).
.RE
.PP
{\fBmark set \fIname\fB left\fR}
.RS
Undo/redo setting a mark with left gravity (\fBmark set\fR).
.RE
.PP
{\fBmark set \fIname\fB right\fR}
.RS
Undo/redo setting a mark with right gravity (\fBmark set\fR).
.RE
.PP
{\fBmark unset \fIname\fR}
.RS
Undo/redo unsetting a mark (\fBmark unset\fR).
.RE
.PP
{\fBtag add \fItag\fR}
.RS
Undo/redo adding an association with tags (\fBtag add\fR).
.RE
.PP
{\fBtag remove \fItag\fR}
.RS
Undo/redo removing an association with tags (\fBtag delete\fR).
.RE
.RE
.TP
\fIpathName \fBedit irreversible\fR
.
Returns a flag whether the content of the text widget is irreversible. The
content is irreversible if the undo stack is not enabled when performing
undoable edit operations, or the undo stack is enabled, but incomplete due
to the limitation of stack depth and/or stack byte size. Also disabling
widget option \fB\-undo\fR will become an irreversible state if the undo
stack was not empty at this time. A change of this state, if caused by an
operation with (eventual) effects on the (representation of the) text
content (see \fBedit altered\fR for details), will trigger the virtual event
\fB<<Irreversible>>\fR. The state will be resetted to false if one of the
following commands will be performed: \fBclear\fR, \fBload\fR,
\fBedit reset\fR, or \fBedit reset undo\fR (but not \fBedit reset redo\fR).
The state will also be resetted to false when widget option \fB\-undo\fR
will be enabled.
.TP
\fIpathName \fBedit modified \fR?\fIboolean\fR?
.
If \fIboolean\fR is not specified, returns the modified flag of the widget.
The \fBinsert\fR, \fBdelete\fR, \fBedit undo\fR, \fBedit redo\fR and
\fBedit recover\fR commands or the user can set or clear the modified flag.
If \fIboolean\fR is specified, sets the modified flag of the widget to
\fIboolean\fR.
.TP
\fIpathName \fBedit recover\fR
.
Applies all undo items, without adding redo items. The initial text (before
any modification has been done since the undo stack is enabled) will be
recovered. The undo stack is empty afterwards.
.RS
.PP
Note: If \fBedit irreversible\fR returns true (before calling this function),
then it's not possible to recover the initial text, in this case it will be
recovered as much as possible. If \fBedit irreversible\fR returns false (before
calling this function), then the state \fBedit altered\fR will change to false.
.RE
.TP
\fIpathName \fBedit redo\fR
.
When the \fB\-undo\fR option is true, reapplies the last undone edits
provided no other edits were done since then. Generates an error when the

redo stack is empty. Does nothing when the \fB\-undo\fR option is false.
.TP
\fIpathName \fBedit reset\fR \fI?stack\fR?
.
If \fIstack\fR is not specified, then clear the undo and redo stacks.
Otherwise only clear the specified stack. The specified stack must be either
\fBundo\fR or \fBredo\fR, otherwise an error will be thrown.
.TP
\fIpathName \fBedit separator\fR ?\fB\-immediately\fR?
.
Inserts a separator (boundary) on the undo stack. Does nothing when the
\fB\-undo\fR option is false. Per default the insertion of the separator
will be postponed until the next
\fBinsert\fR/\fBdelete\fR/\fBreplace\fR/\fBedit undo\fR/\fBedit redo\fR/\fBedit recover\fR
command will be performed. If option \fB\-immediately\fR is specified then
the separator will be pushed immediately; this is required if mark or tag
operations should be separated.
.TP
\fIpathName \fBedit undo\fR
.
Undoes the last edit action when the \fB\-undo\fR option is true. An edit

action is defined as all the commands modifying any text, or tag
associations (but not the changes of tag options) that are recorded on the
undo stack in between two separators, furthermore this includes the
(dis-)embedding of images and windows, but not changes of the content or
options of images and windows. Generates an error when the undo stack is
empty. Does nothing when the \fB\-undo\fR option is false, or when
\fB\-maxredo\fR is set to zero.
.RS
.PP
The marks are not influencing the display, thus operations on marks will not
be recorded, except if option \fB\-steadymarks\fR is enabled: this is the
appropriate mode for programmed editor control, and here the recovery of the
marks (position and gravity) is essential. But operations on the special
marks \fBinsert\fR and \fBcurrent\fR, as well as operations on generated
marks, will never be recorded, these marks should in general not be used if
undoing the operation on a mark is essential.
.RE
.RE
.TP
\fIpathName \fBget\fR ?\fIswitch\fR? ?\fB\-\-\fR? \fIindex1\fR ?\fIindex2 ...\fR?
.
Return a range of characters from the text. The return value will be all the
characters in the text starting with the one whose index is \fIindex1\fR and
ending just before the one whose index is \fIindex2\fR (the character at
\fIindex2\fR will not be returned). If \fIindex2\fR is omitted then the
single character at \fIindex1\fR is returned. If there are no characters in
the specified range (e.g. \fIindex1\fR is past the end of the file or
\fIindex2\fR is less than or equal to \fIindex1\fR) then an empty string is
returned. If the specified range contains embedded windows, no information
about them is included in the returned string. If multiple index pairs are
given, multiple ranges of text will be returned in a list. Invalid ranges
will not be represented with empty strings in the list. The ranges are
returned in the order passed to \fIpathName \fBget\fR. The \fIswitch\fR will
be interpreted as follows:
.RS
.TP
\fB\-chars\fR
.
all characters within the ranges will be returned, whether elided or not,
this also includes soft hyphens. This is the default, if no switch is given.
.TP
\fB\-text\fR
.
all characters, which are not soft hyphens, within the ranges will be
returned, whether elided or not.
.TP
\fB\-displaychars\fR
.
only those characters which are not elided will be returned, this also
includes soft hyphens. This may have the effect that some of the returned
ranges are empty strings.
.TP
\fB\-displaytext\fR
.
only those characters, which are neither soft hyhens, nor elided, will be
returned. This may have the effect that some of the returned ranges are
empty strings.
.RE
.TP
\fIpathName \fBimage \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded images. The behavior of the
command depends on the \fIoption\fR argument that follows the \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
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
Returns the position corresponding to \fIindex\fR in the form \fIline.char\fR
where \fIline\fR is the line number and \fIchar\fR is the character number.
\fIIndex\fR may have any of the forms described under \fBINDICES\fR above.
.TP
\fIpathName \fBinsert \fIindex chars \fR?\fItagList chars tagList ...\fR?
.
Inserts all of the \fIchars\fR arguments just before the character at
\fIindex\fR. If \fIindex\fR refers to the end of the text (the character after
the last newline) then the new text is inserted just before the last newline
instead. If there is a single \fIchars\fR argument and no \fItagList\fR, then
the new text will receive any tags that are present on both the character
before and the character after the insertion point; if a tag is present on
only one of these characters then it will not be applied to the new text. If
\fItagList\fR is specified then it consists of a list of tag names; the new
characters will receive all of the tags in this list and no others, regardless
of the tags present around the insertion point. If multiple
\fIchars\fR\-\fItagList\fR argument pairs are present, they produce the same
effect as if a separate \fIpathName \fBinsert\fR widget command had been
issued for each pair, in order. The last \fItagList\fR argument may be
omitted.

































































































































































































































































































































.TP
\fIpathName \fBmark \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate marks. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBmark\fR argument. The
following forms of the command are currently supported:
.RS
.TP














































\fIpathName \fBmark gravity \fImarkName\fR ?\fIdirection\fR?
.
If \fIdirection\fR is not specified, returns \fBleft\fR or \fBright\fR to
indicate which of its adjacent characters \fImarkName\fR is attached to. If
\fIdirection\fR is specified, it must be \fBleft\fR or \fBright\fR; the
gravity of \fImarkName\fR is set to the given value.
.TP
\fIpathName \fBmark names\fR
.
Returns a list whose elements are the names of all the marks that are
currently set.





.TP
\fIpathName \fBmark next \fIindex\fR
.
Returns the name of the next mark at or after \fIindex\fR. If \fIindex\fR is
specified in numerical form, then the search for the next mark begins at that
index. If \fIindex\fR is the name of a mark, then the search for the next mark
begins immediately after that mark. This can still return a mark at the same
position if there are multiple marks at the same index. These semantics mean
that the \fBmark next\fR operation can be used to step through all the marks
in a text widget in the same order as the mark information returned by the
\fIpathName \fBdump\fR operation. If a mark has been set to the special
\fBend\fR index, then it appears to be \fIafter\fR \fBend\fR with respect to
the \fIpathName \fBmark next\fR operation. An empty string is returned if
there are no marks after \fIindex\fR.









.TP
\fIpathName \fBmark previous \fIindex\fR
.
Returns the name of the mark at or before \fIindex\fR. If \fIindex\fR is
specified in numerical form, then the search for the previous mark begins with
the character just before that index. If \fIindex\fR is the name of a mark,
then the search for the next mark begins immediately before that mark. This
can still return a mark at the same position if there are multiple marks at
the same index. These semantics mean that the \fIpathName \fBmark previous\fR
operation can be used to step through all the marks in a text widget in the
reverse order as the mark information returned by the \fIpathName \fBdump\fR
operation. An empty string is returned if there are no marks before
\fIindex\fR.









.TP
\fIpathName \fBmark set \fImarkName index\fR
.
Sets the mark named \fImarkName\fR to a position just before the character at
\fIindex\fR. If \fImarkName\fR already exists, it is moved from its old
position; if it does not exist, a new mark is created. This command returns an


empty string.







.TP
\fIpathName \fBmark unset \fImarkName \fR?\fImarkName markName ...\fR?
.
Remove the mark corresponding to each of the \fImarkName\fR arguments. The
removed marks will not be usable in indices and will not be returned by future
calls to
.QW "\fIpathName \fBmark names\fR" .





This command returns an empty string.
.RE
.TP
\fIpathName \fBpeer \fIoption args\fR
.
This command is used to create and query widget peers. It has two forms,
depending on \fIoption\fR:







|
|
|
|
|
<
|
|
<
|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|


|


|
>
>
>
>
>

|












>
>
>
>
>
>
>
>
>

|











>
>
>
>
>
>
>
>
>

|



|
>
>
|
>
>
>
>
>
>
>






|
>
>
>
>
>







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
Returns the position corresponding to \fIindex\fR in the form \fIline.char\fR
where \fIline\fR is the line number and \fIchar\fR is the character number.
\fIIndex\fR may have any of the forms described under \fBINDICES\fR above.
.TP
\fIpathName \fBinsert \fIindex chars \fR?\fItagList chars tagList ...\fR?
.
Inserts all of the \fIchars\fR arguments just before the character at
\fIindex\fR. If \fIindex\fR refers to the end of the text (the character
after the last newline) then the new text is inserted just before the last
newline instead. If there is a single \fIchars\fR argument and no
\fItagList\fR, then the new text will receive any tags depending on the
tagging mode (see option \fB\-tagging\fR). If \fItagList\fR is specified

then it consists of a list of tag names; the new characters will receive all
of the tags in this list and no others, regardless of the tagging mode. 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 \fBinspect\fR ?\fIswitches\fR?
.
Return the content of the text widget, including the text and optionally
information about tags, embedded windows, and embedded images. The information
is returned in the following format (notated in EBNF; BEG denotes the start of
a list, end END denotes the end of the list; white spaces will not be taken
into consideration):
.RS
.RS 3
.PP
.CS
\fIInspect\fR       = BEG, \fISetup\fR?, \fIConfigure\fR?, \fISegment\fR+, END;
\fISetup\fR         = BEG, "\fBsetup\fR", \fIPathName\fR, \fITextOptions\fR, END;
\fIConfigure\fR     = BEG, "\fBconfigure\fR", \fITagName\fR, (BEG, \fITagOptions\fR, END)?, END;
\fIBindings\fR      = BEG, "\fBbind\fR", \fITagName\fR, (BEG, \fIScript\fR, END), END;
\fISegment\fR       = BEG, ((\fIContent\fR, \fITagInfo\fR) | \fIMark\fR | \fIElide\fR | \fIBinding\fR), END;
\fIContent\fR       = \fIText\fR | \fIHyphen\fR | \fIBreak\fR | \fIEmbImage\fR | \fIEmbWindow\fR;
\fIText\fR          = "\fBtext\fR", BEG, \fICharacter\fR+, END;
\fIHyphen\fR        = "\fBhyphen\fR";
\fIEmbImage\fR      = "\fBimage\fR", \fIImageOptions\fR;
\fIEmbWindow\fR     = "\fBwindow\fR", \fIWindowOptions\fR;
\fIMark\fR          = \fIGravity\fR, \fIMarkName\fR;
\fIGravity\fR       = "\fBleft\fR" | "\fBright\fR";
\fIElide\fR         = "\fBelide\fR", ("\fBon\fR" | "\fBoff\fR");
\fITagInfo\fR       = (\fITags\fR, \fITags\fR?)?;
\fITags\fR          = BEG, \fITagName\fR*, END;
\fICharacter\fR     = ?Any character except newline?;
\fINewline\fR       = ?The newline character?;
\fITextOptions\fR   = ?See \fBSTANDARD OPTIONS\fR and \fBWIDGET-SPECIFIC OPTIONS\fR?;
\fITagOptions\fR    = ?See \fBTAGS\fR?;
\fIImageOptions\fR  = ?See \fBEMBEDDED IMAGES\fR?;
\fIWindowOptions\fR = ?See \fBEMBEDDED WINDOWS\fR?;
\fIPathName\fR      = ?Any valid widget pathname?;
\fITagName\fR       = ?Any tag name?;
\fIMarkName\fR      = ?Any mark name?;
.CE
.RE
.PP
We will also provide an informal description of the items; note that
the optional \fItagList\fR will be provided only if option \fB\-nested\fR is
specified:
.PP
{\fBsetup\fR \fIpathName configurationList\fR}
.RS
Provides the overall information about the inspected widget, notably its
\fIpathName\fR and configuration options.
.RE
.PP
{\fBconfigure\fR \fItagName\fR ?\fIconfigurationList\fR?}
.RS
Describes the configuration of a particular tag.
.RE
.PP
{\fBbind\fR \fItagName event script\fR}
.RS
Describes a binding applied to a tag
.RE
.PP
{\fBtext\fR \fIcontent ?tagList\fR ?\fItagList\fR??}
.RS
Describes a character sequence, optionally including what tags were applied to it.
.RE
.PP
{\fBbreak\fR \fItagList\fR ?\fItagList\fR?}
.RS
Describes a newline character, including what tags were applied to it.
.RE
.PP
{\fBhyphen\fR \fItagList\fR ?\fItagList\fR?}
.RS
Describes a soft hyphen, including what tags were applied to it.
.RE
.PP
{\fBimage\fR \fIimageOptions ?tagList\fR ?\fItagList\fR??}
.RS
Describes an image that was embedded, optionally including what tags were applied to it.
.RE
.PP
{\fBwindow\fR \fIwindowOptions ?tagList\fR ?\fItagList\fR??}
.RS
Describes a window that was embedded, optionally including what tags were applied to it.
.RE
.PP
{\fBleft\fR \fImarkName\fR}
.RS
Describes a mark with left gravity.
.RE
.PP
{\fBright\fR \fImarkName\fR}
.RS
Describes a mark with right gravity.
.RE
.PP
{\fBelide\fR \fBon\fR|\fBoff\fR}
.RS
Describes whether elision is turned on or off at the current handling point.
.RE
.PP
One or more of the following switches (or abbreviations thereof) may be
specified to control the extraction:
.RS
.TP
\fB\-all\fR
.
Return information about all elements: text (characters and soft hyphens),
marks, tags, images, and windows. This is the default, and includes the following
switches: \fB\-chars\fR, \fB\-mark\fR \fB\-tag\fR, \fB\-image\fR, and \fB\-window\fR.
.TP
\fB\-complete\fR
.
Return complete information, this includes the following switches:
\fB\-all\fR, \fB\-bindings\fR, \fB\-configurations\fR, \fB\-elide\fR,
\fB\-includedbconfig\fR, \fB\-includedefaultconfig\fR, \fB\-includeselection\fR,
\fB\-includesyscolors\fR, \fB\-includesysconfig\fR, \fB\-insertmark\fR, and
\fB\-setup\fR.
.TP
\fB\-bindings\fR
.
Include all tag bindings into the result.
.TP
\fB\-chars\fR
.
Include information about characters and soft hyphens in the dump results. The content of this segment is the text up to the next segment. The segmentation of text depends on the tagging information, any change in tagging is starting a new segment.
.TP
\fB\-configurations\fR
.
Include all the tag configurations.
.TP
\fB\-displaychars\fR
.
If this option is given, then only those characters and soft hyphens which
are not elided will be included into the result of the text element.
.TP
\fB\-displaytext\fR
.
If this option is given, then only those characters which are not elided
will be included into the result of the text element. Note that soft hyphens
(Unicode point U+00AD) do not belong to this result.
.TP
\fB\-dontresolvecolors\fR
.
Do not resolve system color names (this is affecting the content of \fB\-setup\fR,
and \fB\-configurations\fR). Resolving system color names is required for
portability, but in case of system dependent use (if all system color names will be
resolvable) it is not required. Per default system color names will be resolved.
.TP
\fB\-dontresolvefonts\fR
.
Do not resolve font names (this is affecting the content of \fB\-setup\fR,
and \fB\-configurations\fR). Resolving font names is required for
portability, but in case of private use (if all font names will be
resolvable) it is not required. Per default font names will be resolved.
.TP
\fB\-elide\fR
.
The result will also include information about elided regions. It is for
information only \- better visibility of elided text. The \fBload\fR command
will ignore these elements.
.TP
\fB\-image\fR
.
Include information about images in the result. The content of the image is
a list containing the image options.
.TP
\fB\-includedbconfig\fR
.
This option makes sense only if also option \fB\-setup\fR (or \fB\-all\fR) is
specified. With this option a configuration option will be included into the
list of configuration even if the value of this option is equal to the value
from option database (per default database values are excluded).
.TP
\fB\-includedefaultconfig\fR
.
This option makes sense only if also option \fB\-setup\fR (or \fB\-all\fR) is
specified. With this option a configuration option will be included into the
list of configuration even if the value of this option is equal to the default
value (per default the default values are excluded). Note that the options
\fB\-includedbconfig\fR and \fB\-includesysconfig\fR have higher priority.
.TP
\fB\-includeselection\fR
.
This option makes sense only if also option \fB\-tag\fR (or \fB\-all\fR) is
specified. With this option the selection tag \fBsel\fR will be included into the
result. Per default the selection will be discarded when inspecting the content.
.TP
\fB\-includesyscolors\fR
.
When inspecting widget or tag option values normally system colors (like
.QW SystemHighlight ,
or
.QW systemHighlight )
will be discarded, except if option \fB\-includesyscolors\fR is specified.
.TP
\fB\-includesysconfig\fR
.
This option makes sense only if also option \fB\-setup\fR (or \fB\-all\fR) is
specified. With this option a configuration option will be included into the
list of configuration even if the value of this option is equal to the system
value (per default the system values are excluded). Note that option
\fB\-includedbconfig\fR has a higher priority.
.TP
\fB\-insertmark\fR
.
Include information about the
.QW insert
mark in the dump results. Without this option, this mark will not be printed.
.TP
\fB\-mark\fR
.
Include information about marks in the dump results. Depending on the
gravity the type of this segment is either left or right. The segment
content is the name of the mark. The special marks \fBinsert\fR and
\fBcurrent\fR will be discarded (but see option \fB\-insertmark\fR), and
generated marks will also be discarded.
.TP
\fB\-nested\fR
.
This option will only be regarded in conjunction with switch \fB\-tag\fR,
see description of switch \fB\-tag\fR below.
.TP
\fB\-setup\fR
.
Include the pathname of the widget, and a list of configuration options. Per
default a configuration option will be included only if the value is neither
equal to the default value, nor equal to the system value, nor equal to the
value from option database. This can be modified with options
\fB\-includedefaultconfig\fR, \fB\-includesysconfig\fR, and
\fB\-includedbconfig\fR.
.TP
\fB\-tag\fR
.
Include information about tags in the result. If additionally option
\fB\-nested\fR is specified, then two tag sets will be provided: firstly all
the tags starting with this content, and secondly all the tags ending after
this content (similar to the \fItagon\fR and \fItagoff\fR ranges in the
\fBdump\fR format). Without the \fB\-nested\fR option (this is the default) only
one list will be provided, namely all the tags associated to this segment
content. The tag list will be sorted in order from lowest priority to highest
priority.
.TP
\fB\-text\fR
.
Include information about text (characters) in the dump result. The content
of this segment is the text up to the next segment. The segmentation of text
depends on the tagging information, any change in tagging is starting a new
segment. Note that soft hyphens (Unicode point U+00AD) do not belong to this
result.
.TP
\fB\-window\fR
.
Include information about embedded windows in the result. The content of a
window is a list containing the window options.
.RE
.PP
The result of this command can be used for loading a widget with a snapshot
(see command \fBload\fR).
.RE
.TP
\fIpathName \fBisclean\fR ?\fB\-overall\fR? ?\fB\-discardselection\fR?
.
Returns whether this widget does not contain any character, soft hyphen,
embedded window, or embedded image, except an untagged sole newline.
Furthermore a clean widget does not contain any marks, except the special
marks \fBcurrent\fR and \fBinsert\fR, and generated marks. If option
\fB\-overall\fR is specified, then this test will discard any restrictions
given with widget options \fB\-startindex\fR and \fB\-endindex\fR. If option
\fB\-discardselection\fR is given, the special selection tag \fBsel\fR
will be discarded when testing whether the sole newline is tagged.
.TP
\fIpathName \fBisdead\fR
.
A text widget is dead if it does not contain any line (in this case no
insertion is possible anymore). This only happens if one of the widget
options \fB\-startindex\fR/\fB\-endindex\fR is specified.
.TP
\fIpathName \fBisempty\fR ?\fB\-overall\fR?
.
Returns whether this widget does not contain any character, soft hyphen,
embedded window, or embedded image, except a sole newline. If the
\fB\-overall\fR option is specified, then this test will discard restrictions
given with widget options \fB\-startindex\fR and \fB\-endindex\fR.
.TP
\fIpathName \fBlineno\fR \fIindex\fR
.
Returns the line number corresponding to \fIindex\fR. \fIIndex\fR may have
any of the forms described under \fBINDICES\fR above.
.RS
.PP
If the widget is dead (i.e., does not contain lines, which is possible
only if option \fB\-startline\fR/\fB\-endline\fR is involved), then 0 (zero)
will be returned.
.RE
.TP
\fIpathName \fBload\fR ?\fB\-validconfig\fR? \fIserialContent\fR
.
Load the text widget with given content \fIserialContent\fR. The widget will
be cleared before the load will be done, this includes all marks, but not
the tag definitions. The format of \fIserialContent\fR is described in the
\fBinspect\fR subcommand, which produces it. Normally invalid configuaration
options will be skipped, except if option \fB\-validconfig\fR is specified,
in this case an error will be thrown if an invalid option value will be
encountered. Normally the latter only may happen if the given content is
produced under a different system.
.RS
.PP
For a complete recovery of the text widget content the following is
required:
.IP \(bu 3
The content contains the complete information (see flag \fB\-all\fR of
command \fBinspect\fR).
.IP \(bu 3
All embedded images have to exist.
.IP \(bu 3
Either the embedded windows have to exist, or the \fBwindow\fR item
contains an executable \fBcreate\fR option.
.PP
The states \fBedit modified\fR, \fBedit altered\fR, and
\fBedit irreversible\fR will be resetted to false. Note that this operation
cannot be undone.
.RE
.TP
\fIpathName \fBmark \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate marks. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBmark\fR argument. The
following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBmark compare\fR \fImarkName1 op markName2\fR
.
Compares the marks given by \fImarkName1\fR and \fImarkName2\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 marks
are the same, if \fIop\fR is < then 1 is returned if \fImarkName1\fR refers
to an earlier mark in the text than \fImarkName2\fR, and so on. If one of
the given operands is not an exisiting mark, then an error will be thrown.
This command is especially useful when option \fB\-steadymarks\fR is
enabled.
.TP
\fIpathName \fBmark exists\fR \fImarkName\fR
.
Returns whether the specified mark is already existing at any position.
.TP
\fIpathName \fBmark generate\fR
.
Creates a mark, either for temporary use, or for static use. This mark has
the following properties:
.RS
.IP [1] 4
Operations on this mark will not be stacked onto the undo stack (relevant
only if option \fB\-steadymarks\fR is enabled).
.IP [2] 4
It is not visible, this means that the commands \fBmark names\fR,
\fBmark next\fR, and \fBmark previous\fR will not return generated marks,
and command \fBinspect\fR will not print this mark (but command \fBdump\fR
will print it, it has the form
.QW "##ID##[:hexdigit:]+##[:hexdigit:]+##[:digit:]+##" ).
.IP [3] 4
This mark cannot be deleted except with command \fBmark unset\fR (this means
that \fBdelete \-marks\fR will not delete this kind of marks).
.IP [4] 4
Commands \fBclear\fR and \fBload\fR will not delete this mark, but the
relative order to other (generated) marks may change after clearing the text
content (command \fBload\fR is also clearing before loading).
.IP [5] 4
After deletion of a generated mark (with \fBmark unset\fR) this mark will
expire, which means that a subsequent call of \fBmark set\fR with this mark
will throw an error.
.PP
The initial position of this mark is at start of text. This command returns
the generated name of the mark.
.RE
.TP
\fIpathName \fBmark gravity \fImarkName\fR ?\fIdirection\fR?
.
If \fIdirection\fR is not specified, returns \fBleft\fR or \fBright\fR to
indicate which of its adjacent characters \fImarkName\fR is attached to. If
\fIdirection\fR is specified, it must be \fBleft\fR or \fBright\fR, the
gravity of \fImarkName\fR is set to the given value.
.TP
\fIpathName \fBmark names\fR ?\fB\-discardspecial\fR? ?\fIpattern\fR?
.
Returns a list whose elements are the names of all the marks that are
currently set. If an optional \fIpattern\fR is specified, then only
the names matching this pattern will be included in the result; see
\fBstring match\fR about the rules of pattern matching. If option
\fB\-discardspecial\fR is specified, then exclude the special marks
\fBinsert\fR and \fBcurrent\fR from result, even when matching the
given \fIpattern\fR.
.TP
\fIpathName \fBmark next\fR ?\fB-discardspecial\fR? \fIindex\fR ?\fIpattern\fR?
.
Returns the name of the next mark at or after \fIindex\fR. If \fIindex\fR is
specified in numerical form, then the search for the next mark begins at that
index. If \fIindex\fR is the name of a mark, then the search for the next mark
begins immediately after that mark. This can still return a mark at the same
position if there are multiple marks at the same index. These semantics mean
that the \fBmark next\fR operation can be used to step through all the marks
in a text widget in the same order as the mark information returned by the
\fIpathName \fBdump\fR operation. If a mark has been set to the special
\fBend\fR index, then it appears to be \fIafter\fR \fBend\fR with respect to
the \fIpathName \fBmark next\fR operation. An empty string is returned if
there are no marks after \fIindex\fR.
.RS
.PP
If an optional \fIpattern\fR is specified, then skip all the marks not matching
this pattern during the search; see \fBstring match\fR about the rules of pattern
matching.
.PP
If option \fB\-discardspecial\fR is specified, then skip the special marks
\fBinsert\fR and \fBcurrent\fR during the search.
.RE
.TP
\fIpathName \fBmark previous\fR ?\fB\-discardspecial\fR? \fIindex\fR ?\fIpattern\fR?
.
Returns the name of the mark at or before \fIindex\fR. If \fIindex\fR is
specified in numerical form, then the search for the previous mark begins with
the character just before that index. If \fIindex\fR is the name of a mark,
then the search for the next mark begins immediately before that mark. This
can still return a mark at the same position if there are multiple marks at
the same index. These semantics mean that the \fIpathName \fBmark previous\fR
operation can be used to step through all the marks in a text widget in the
reverse order as the mark information returned by the \fIpathName \fBdump\fR
operation. An empty string is returned if there are no marks before
\fIindex\fR.
.RS
.PP
If an optional \fIpattern\fR is specified, then skip all the marks not matching
this pattern during the search; see \fBstring match\fR about the rules of pattern
matching.
.PP
If option \fB\-discardspecial\fR is specified, then skip the special marks
\fBinsert\fR and \fBcurrent\fR during the search.
.RE
.TP
\fIpathName \fBmark set \fImarkName index\fR ?\fIdirection\fR?
.
Sets the mark named \fImarkName\fR to a position just before the character at
\fIindex\fR. If \fImarkName\fR already exists, it is moved from its old
position; if it does not exist, a new mark is created. If the third parameter
\fIdirection\fR is specified - it must be \fBleft\fR or \fBright\fR - the
gravity of \fImarkName\fR is set to the given value (the gravity for a mark
defaults to \fBright\fR). This command returns an empty string.
.RS
.PP
If widget option \fB\-steadymarks\fR is enabled, and \fIindex\fR is the name
of an existing mark, then \fImarkName\fR will be set left or right from
\fIindex\fR (but at the same numerical position), according to the gravity of
\fIindex\fR.
.RE
.TP
\fIpathName \fBmark unset \fImarkName \fR?\fImarkName markName ...\fR?
.
Remove the mark corresponding to each of the \fImarkName\fR arguments. The
removed marks will not be usable in indices and will not be returned by future
calls to
.QW "\fIpathName \fBmark names\fR" ,
.QW "\fIpathName \fBmark next\fR" ,
and
.QW "\fIpathName \fBmark previous\fR" .
When removing a generated mark (see \fBmark generate\fR) a future call of
\fBmark set\fR with this mark will throw an error (even after clearing the widget).
This command returns an empty string.
.RE
.TP
\fIpathName \fBpeer \fIoption args\fR
.
This command is used to create and query widget peers. It has two forms,
depending on \fIoption\fR:
1492
1493
1494
1495
1496
1497
1498

1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
\fIpathName \fBpeer names\fR
.
Returns a list of peers of this widget (this does not include the widget
itself). The order within this list is undefined.
.RE
.TP
\fIpathName \fBpendingsync\fR

Returns 1 if the line heights calculations are not up-to-date, 0 otherwise.
.TP
\fIpathName \fBreplace\fR \fIindex1 index2 chars\fR ?\fItagList chars tagList ...\fR?

Replaces the range of characters between \fIindex1\fR and \fIindex2\fR
with the given characters and tags.  See the section on \fIpathName
\fBinsert\fR for an explanation of the handling of the \fItagList...\fR
arguments, and the section on \fIpathName
\fBdelete\fR for an explanation of the handling of the indices.  If
\fIindex2\fR corresponds to an index earlier in the text than
\fIindex1\fR, an error will be generated.







>



>







3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
\fIpathName \fBpeer names\fR
.
Returns a list of peers of this widget (this does not include the widget
itself). The order within this list is undefined.
.RE
.TP
\fIpathName \fBpendingsync\fR
.
Returns 1 if the line heights calculations are not up-to-date, 0 otherwise.
.TP
\fIpathName \fBreplace\fR \fIindex1 index2 chars\fR ?\fItagList chars tagList ...\fR?
.
Replaces the range of characters between \fIindex1\fR and \fIindex2\fR
with the given characters and tags.  See the section on \fIpathName
\fBinsert\fR for an explanation of the handling of the \fItagList...\fR
arguments, and the section on \fIpathName
\fBdelete\fR for an explanation of the handling of the indices.  If
\fIindex2\fR corresponds to an index earlier in the text than
\fIindex1\fR, an error will be generated.
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
.QW "Z[a\-z]+Z"
against
.QW ZooZooZoo
will just match once.
.TP
\fB\-overlap\fR
.
When performing \fB\-all\fR searches, the normal behaviour is that matches
which overlap an already-found match will not be returned. This switch changes
that behaviour so that all matches which are not totally enclosed within
another match are returned. For example, applying an \fB\-overlap\fR search of
the pattern
.QW \ew+
against
.QW "hello there"
will just match twice (i.e. no different to just \fB\-all\fR), but matching
.QW Z[a\-z]+Z
against
.QW ZooZooZoo
will now match twice. An error will be thrown if this switch is used without
\fB\-all\fR.
.TP
\fB\-strictlimits\fR
.
When performing any search, the normal behaviour is that the start and stop
limits are checked with respect to the start of the matching text. With the
\fB\-strictlimits\fR flag, the entire matching range must lie inside the start
and stop limits specified for the match to be valid.
.TP
\fB\-elide\fR
.
Find elided (hidden) text as well. By default only displayed text is searched.
.TP






\fB\-\|\-\fR
.
This switch has no effect except to terminate the list of switches: the next
argument will be treated as \fIpattern\fR even if it starts with \fB\-\fR.
.PP
The matching range may be within a single line of text, or run across multiple
lines (if parts of the pattern can match a new-line). For regular expression







|

|














|








>
>
>
>
>
>







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
.QW "Z[a\-z]+Z"
against
.QW ZooZooZoo
will just match once.
.TP
\fB\-overlap\fR
.
When performing \fB\-all\fR searches, the normal behavior is that matches
which overlap an already-found match will not be returned. This switch changes
that behavior so that all matches which are not totally enclosed within
another match are returned. For example, applying an \fB\-overlap\fR search of
the pattern
.QW \ew+
against
.QW "hello there"
will just match twice (i.e. no different to just \fB\-all\fR), but matching
.QW Z[a\-z]+Z
against
.QW ZooZooZoo
will now match twice. An error will be thrown if this switch is used without
\fB\-all\fR.
.TP
\fB\-strictlimits\fR
.
When performing any search, the normal behavior is that the start and stop
limits are checked with respect to the start of the matching text. With the
\fB\-strictlimits\fR flag, the entire matching range must lie inside the start
and stop limits specified for the match to be valid.
.TP
\fB\-elide\fR
.
Find elided (hidden) text as well. By default only displayed text is searched.
.TP
\fB\-discardhyphens\fR
.
Do not match with soft hyphens, this means that soft hyphens inside widget
content will be discarded while performing the search operation. If the text
contains soft hyphen this option is often a must.
.TP
\fB\-\|\-\fR
.
This switch has no effect except to terminate the list of switches: the next
argument will be treated as \fIpattern\fR even if it starts with \fB\-\fR.
.PP
The matching range may be within a single line of text, or run across multiple
lines (if parts of the pattern can match a new-line). For regular expression
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
Adjusts the view in the window so that the character given by \fIindex\fR is
completely visible. If \fIindex\fR is already visible then the command does
nothing. If \fIindex\fR is a short distance out of view, the command adjusts
the view just enough to make \fIindex\fR visible at the edge of the window.
If \fIindex\fR is far out of view, then the command centers \fIindex\fR in the
window.
.TP
\fIpathName \fBsync\fR ?\fB-command \fIcommand\fR?

Controls the synchronization of the view of the text widget.
.RS
.TP
\fIpathName \fBsync\fR

Immediately brings the line metrics up-to-date by forcing computation of any
outdated line heights. The command returns immediately if there is no such
outdated line heights, otherwise it returns only at the end of the computation.


The command returns an empty string.
.TP
\fIpathName \fBsync -command \fIcommand\fR






Schedules \fIcommand\fR to be executed (by the event loop) exactly once as soon
as all line heights are up-to-date. If there are no pending line metrics



calculations, the scheduling is immediate. The command returns the empty
string. \fBbgerror\fR is called on \fIcommand\fR failure.






.RE
.TP
\fIpathName \fBtag \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate tags. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBtag\fR argument. The
following forms of the command are currently supported:







|
>




>



>
>
|

|
>
>
>
>
>
>

|
>
>
>
|
|
>
>
>
>
>
>







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
Adjusts the view in the window so that the character given by \fIindex\fR is
completely visible. If \fIindex\fR is already visible then the command does
nothing. If \fIindex\fR is a short distance out of view, the command adjusts
the view just enough to make \fIindex\fR visible at the edge of the window.
If \fIindex\fR is far out of view, then the command centers \fIindex\fR in the
window.
.TP
\fIpathName \fBsync\fR ?\fB\-command ?\fIcommand\fR??
.
Controls the synchronization of the view of the text widget.
.RS
.TP
\fIpathName \fBsync\fR
.
Immediately brings the line metrics up-to-date by forcing computation of any
outdated line heights. The command returns immediately if there is no such
outdated line heights, otherwise it returns only at the end of the computation.
It is guaranteed that the \fB<<WidgetViewSync>>\fR virtual event fires after
executing this command, even if no line was outdated. The command returns an
empty string.
.TP
\fIpathName \fBsync \-command\fR
.
Returns the command which will be scheduled as soon an the line metric
calculation is up-to-date, or an empty string if no command is available.
.TP
\fIpathName \fBsync \-command \fIcommand\fR
.
Schedules \fIcommand\fR to be executed (by the event loop) exactly once as soon
as all line heights are up-to-date. A new script will replace any existing
script, but if the first character is
.QW \fC+\fR
then the new script augments an existing script. If there is no pending line
metrics computation, the scheduling is immediate (as if the line metrics
computation will finish now). \fIbgerror\fR is called on \fIcommand\fR
failure. This command returns an empty string.
.PP
If a command is given (with \fB\-command\fR \fIcommand\fR) then it is ensured
that \fIcommand\fR will be called only when all line height values currently
are up-to-date. When waiting for event \fB<<WidgetViewSync>>\fR it is possible
that some race conditions will affect the received state.
.RE
.TP
\fIpathName \fBtag \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate tags. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBtag\fR argument. The
following forms of the command are currently supported:
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
is less than or equal to \fIindex1\fR) then the command has no effect.
.TP
\fIpathName \fBtag bind \fItagName\fR ?\fIsequence\fR? ?\fIscript\fR?
.
This command associates \fIscript\fR with the tag given by \fItagName\fR.
Whenever the event sequence given by \fIsequence\fR occurs for a character
that has been tagged with \fItagName\fR, the script will be invoked. This

widget command is similar to the \fBbind\fR command except that it operates on
characters in a text rather than entire widgets. See the \fBbind\fR manual
entry for complete details on the syntax of \fIsequence\fR and the
substitutions performed on \fIscript\fR before invoking it. If all arguments
are specified then a new binding is created, replacing any existing binding
for the same \fIsequence\fR and \fItagName\fR (if the first character of
\fIscript\fR is
.QW +
then \fIscript\fR augments an existing binding rather than replacing it). In
this case the return value is an empty string. If \fIscript\fR is omitted then
the command returns the \fIscript\fR associated with \fItagName\fR and
\fIsequence\fR (an error occurs if there is no such binding). If both
\fIscript\fR and \fIsequence\fR are omitted then the command returns a list of
all the sequences for which bindings have been defined for \fItagName\fR.
.RS
.PP
The only events for which bindings may be specified are those related to the
mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButton\fR,
\fBMotion\fR, and \fBKey\fR) or virtual events. Event bindings for a text

widget use the \fBcurrent\fR mark described under \fBMARKS\fR above. An
\fBEnter\fR event triggers for a tag when the tag first becomes present on the
current character, and a \fBLeave\fR event triggers for a tag when it ceases
to be present on the current character. \fBEnter\fR and \fBLeave\fR events can
happen either because the \fBcurrent\fR mark moved or because the character at
that position changed. Note that these events are different than \fBEnter\fR
and \fBLeave\fR events for windows. Mouse and keyboard events are directed to

the current character. If a virtual event is used in a binding, that binding
can trigger only if the virtual event is defined by an underlying
mouse-related or keyboard-related event.
.PP
It is possible for the current character to have multiple tags, and for each
of them to have a binding for a particular event sequence. When this occurs,
one binding is invoked for each tag, in order from lowest-priority to highest
priority. If there are multiple matching bindings for a single tag, then the







>







|










|
>
|





|
>
|







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
is less than or equal to \fIindex1\fR) then the command has no effect.
.TP
\fIpathName \fBtag bind \fItagName\fR ?\fIsequence\fR? ?\fIscript\fR?
.
This command associates \fIscript\fR with the tag given by \fItagName\fR.
Whenever the event sequence given by \fIsequence\fR occurs for a character
that has been tagged with \fItagName\fR, the script will be invoked. This
'\" TODO how can we include the "bind" ref explicitly?
widget command is similar to the \fBbind\fR command except that it operates on
characters in a text rather than entire widgets. See the \fBbind\fR manual
entry for complete details on the syntax of \fIsequence\fR and the
substitutions performed on \fIscript\fR before invoking it. If all arguments
are specified then a new binding is created, replacing any existing binding
for the same \fIsequence\fR and \fItagName\fR (if the first character of
\fIscript\fR is
.QW \fC+\fR
then \fIscript\fR augments an existing binding rather than replacing it). In
this case the return value is an empty string. If \fIscript\fR is omitted then
the command returns the \fIscript\fR associated with \fItagName\fR and
\fIsequence\fR (an error occurs if there is no such binding). If both
\fIscript\fR and \fIsequence\fR are omitted then the command returns a list of
all the sequences for which bindings have been defined for \fItagName\fR.
.RS
.PP
The only events for which bindings may be specified are those related to the
mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButton\fR,
\fBMotion\fR, and \fBKey\fR) or virtual events. Mouse and keyboard event
bindings for a text widget respectively use the \fBcurrent\fR and \fBinsert\fR
marks described under \fBMARKS\fR above. An
\fBEnter\fR event triggers for a tag when the tag first becomes present on the
current character, and a \fBLeave\fR event triggers for a tag when it ceases
to be present on the current character. \fBEnter\fR and \fBLeave\fR events can
happen either because the \fBcurrent\fR mark moved or because the character at
that position changed. Note that these events are different than \fBEnter\fR
and \fBLeave\fR events for windows. Mouse events are directed to the current
character, while keyboard events are directed to the insert character.
If a virtual event is used in a binding, that binding
can trigger only if the virtual event is defined by an underlying
mouse-related or keyboard-related event.
.PP
It is possible for the current character to have multiple tags, and for each
of them to have a binding for a particular event sequence. When this occurs,
one binding is invoked for each tag, in order from lowest-priority to highest
priority. If there are multiple matching bindings for a single tag, then the
1762
1763
1764
1765
1766
1767
1768














1769
1770
1771
1772
1773
1774
1775
.RE
.TP
\fIpathName \fBtag cget \fItagName option\fR
.
This command returns the current value of the option named \fIoption\fR
associated with the tag given by \fItagName\fR. \fIOption\fR may have any of
the values accepted by the \fIpathName \fBtag configure\fR widget command.














.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
This command is similar to the \fIpathName \fBconfigure\fR widget command
except that it modifies options associated with the tag given by \fItagName\fR
instead of modifying options for the overall text widget. If no \fIoption\fR
is specified, the command returns a list describing all of the available







>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
.RE
.TP
\fIpathName \fBtag cget \fItagName option\fR
.
This command returns the current value of the option named \fIoption\fR
associated with the tag given by \fItagName\fR. \fIOption\fR may have any of
the values accepted by the \fIpathName \fBtag configure\fR widget command.
.TP
\fIpathName \fBtag clear\fR ?\fB\-discardselection\fR? \fIindex1\fR \fI?index2 index1 index2 ...\fR?
.
Remove all tags from all of the characters starting at \fIindex1\fR and
ending just before \fIindex2\fR (the character at \fIindex2\fR is not
affected). A single command may contain any number of
\fIindex1\fR-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then
all tags will be 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 a list of all removed tags,
sorted in order from lowest priority to highest priority. If option
\fB\-discardselection\fR is given then the special selection tag \fBsel\fR
will not be removed.
.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR?
.
This command is similar to the \fIpathName \fBconfigure\fR widget command
except that it modifies options associated with the tag given by \fItagName\fR
instead of modifying options for the overall text widget. If no \fIoption\fR
is specified, the command returns a list describing all of the available
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
.TP
\fIpathName \fBtag delete \fItagName \fR?\fItagName ...\fR?
.
Deletes all tag information for each of the \fItagName\fR arguments. The
command removes the tags from all characters in the file and also deletes any
other information associated with the tags, such as bindings and display
information. The command returns an empty string.
























.TP
\fIpathName\fB tag lower \fItagName \fR?\fIbelowThis\fR?
.
Changes the priority of tag \fItagName\fR so that it is just lower in priority
than the tag whose name is \fIbelowThis\fR. If \fIbelowThis\fR is omitted,
then \fItagName\fR's priority is changed to make it lowest priority of all
tags.
.TP
\fIpathName \fBtag names \fR?\fIindex\fR?
.
Returns a list whose elements are the names of all the tags that are active at
the character position given by \fIindex\fR. If \fIindex\fR is omitted, then
the return value will describe all of the tags that exist for the text (this









includes all tags that have been named in a
.QW "\fIpathName \fBtag\fR"
widget command but have not been deleted by a
.QW "\fIpathName \fBtag delete\fR"

widget command, even if no characters are currently marked with the tag). The
list will be sorted in order from lowest priority to highest priority.









































































.TP
\fIpathName \fBtag nextrange \fItagName index1 \fR?\fIindex2\fR?
.
This command searches the text for a range of characters tagged with
\fItagName\fR where the first character of the range is no earlier than the
character at \fIindex1\fR and no later than the character just before
\fIindex2\fR (a range starting at \fIindex2\fR will not be considered). If







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|



|
>
>
>
>
>
>
>
>
>
|
|

|
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
.TP
\fIpathName \fBtag delete \fItagName \fR?\fItagName ...\fR?
.
Deletes all tag information for each of the \fItagName\fR arguments. The
command removes the tags from all characters in the file and also deletes any
other information associated with the tags, such as bindings and display
information. The command returns an empty string.
.TP
\fIpathName \fBtag findnext\fR ?\fB\-discardselection\fR? \fIindex\fR
.
Finds the first tagged character either at specified position \fIindex\fR,
or right from specified position \fIindex\fR, and returns the index of the
detected character. The value of the result will be empty if no character
can be found. If option \fB\-discardselection\fR is given then the special
selection tag \fBsel\fR will be discarded.
.TP
\fIpathName \fBtag findprev\fR ?\fB\-discardselection\fR? \fIindex\fR
.
Finds the first tagged character either at specified position \fIindex\fR,
or left from specified position \fIindex\fR, and returns the index of the
detected character. The value of the result will be empty if no character
can be found. If option \fB\-discardselection\fR is given then the special
selection tag \fBsel\fR will be discarded.
.TP
\fIpathName \fBtag getrange\fR \fItagName index\fR
.
Returns the range of text that have been tagged with \fItagName\fR, and
which includes the character at the specified position \fIindex\fR
(inclusive start of range, but exclusive end of range). If the character at
specified position \fIindex\fR is not tagged with \fItagName\fR, then the
returned value will be empty.
.TP
\fIpathName\fB tag lower \fItagName \fR?\fIbelowThis\fR?
.
Changes the priority of tag \fItagName\fR so that it is just lower in priority
than the tag whose name is \fIbelowThis\fR. If \fIbelowThis\fR is omitted,
then \fItagName\fR's priority is changed to make it lowest priority of all
tags.
.TP
\fIpathName \fBtag names\fR \fI?switches\fR? \fI?index\fR?
.
Returns a list whose elements are the names of all the tags that are active at
the character position given by \fIindex\fR. If \fIindex\fR is omitted, then
the return value will describe all of the tags that exist for the text. The
list will be sorted in order from lowest priority to highest priority.
.RS
.PP
One or more of the following switches (or abbreviations thereof) may be
specified to control the result:
.TP
\fB\-all\fR
.
Return all tags that exist for the text (this includes all tags that have
been named in a
.QW "pathName \fBtag\fR"
widget command but have not been deleted by a
.QW "pathName \fBtag delete\fR"
widget command, even if no characters/soft hyphens/embedded images/embedded
windows are currently marked with the tag). This is the default.

.TP
\fB\-discardselection\fR
.
Discard the special selection tag \fBsel\fR. (This option is identical to
option \fB\-noselection\fR, and only provided to be conform with other tag
sub-commands.)
.TP
\fB\-display\fR
.
Include all tags (eventually) influencing the display of text.
.TP
\fB\-nodisplay\fR
.
Discard all tags (eventually) influencing the display of text.
.TP
\fB\-elide\fR
.
Include all tags where option \fB\-elide\fR is enabled.
.TP
\fB\-noelide\fR
.
Discard all tags where option \fB\-elide\fR is enabled.
.TP
\fB\-geometry\fR
.
Include all tags (eventually) influencing the display geometry.
.TP
\fB\-nogeometry\fR
.
Discard all tags (eventually) influencing the display geometry.
.TP
\fB\-lineheight\fR
.
Include all tags (eventually) influencing the line height.
.TP
\fB\-nolineheight\fR
.
Discard all tags (eventually) influencing the line height.
.TP
\fB\-selection\fR
.
Include all tags affecting selected text. Currently this is only the
\fBsel\fR tag.
.TP
\fB\-noselection\fR
.
Discard all tags affecting selected text. Currently this is discarding only
the \fBsel\fR tag. (This option is identical to option
\fB\-discardselection\fR).
.TP
\fB\-undo\fR
.
Include all tags where option \fB\-undo\fR is enabled.
.TP
\fB\-noundo\fR
.
Discard all tags where option \fB\-undo\fR is enabled.
.TP
\fB\-used\fR
.
Include all tags which are currently used for associations with any
character, soft hyphen, embedded image, or embedded window.
.TP
\fB\-noused\fR
.
Discard all tags which are currently used for associations with any
character, soft hyphen, embedded image, or embedded window.
.TP
\fB\-unused\fR
.
This option is identical to option \fB\-noused\fR, and only provided for
convenience.
.RE
.TP
\fIpathName \fBtag nextrange \fItagName index1 \fR?\fIindex2\fR?
.
This command searches the text for a range of characters tagged with
\fItagName\fR where the first character of the range is no earlier than the
character at \fIindex1\fR and no later than the character just before
\fIindex2\fR (a range starting at \fIindex2\fR will not be considered). If
1828
1829
1830
1831
1832
1833
1834





1835
1836
1837
1838
1839
1840
1841
starting at \fIindex2\fR will be considered). If several matching ranges
exist, the one closest to \fIindex1\fR is chosen. The command's return value
is a list containing two elements, which are the index of the first character
of the range and the index of the character just after the last one in the
range. If no matching range is found then the return value is an empty string.
If \fIindex2\fR is not given then it defaults to the beginning of the text.
.TP





\fIpathName\fB tag raise \fItagName \fR?\fIaboveThis\fR?
.
Changes the priority of tag \fItagName\fR so that it is just higher in
priority than the tag whose name is \fIaboveThis\fR. If \fIaboveThis\fR is
omitted, then \fItagName\fR's priority is changed to make it highest priority
of all tags.
.TP







>
>
>
>
>







3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
starting at \fIindex2\fR will be considered). If several matching ranges
exist, the one closest to \fIindex1\fR is chosen. The command's return value
is a list containing two elements, which are the index of the first character
of the range and the index of the character just after the last one in the
range. If no matching range is found then the return value is an empty string.
If \fIindex2\fR is not given then it defaults to the beginning of the text.
.TP
\fIpathName \fBtag priority \fItagName\fR
.
Returns the priority (a positive integer value, or zero) of the specified tag.
This allows to compare the priority of tags.
.TP
\fIpathName\fB tag raise \fItagName \fR?\fIaboveThis\fR?
.
Changes the priority of tag \fItagName\fR so that it is just higher in
priority than the tag whose name is \fIaboveThis\fR. If \fIaboveThis\fR is
omitted, then \fItagName\fR's priority is changed to make it highest priority
of all tags.
.TP
1856
1857
1858
1859
1860
1861
1862




































































































































































































































1863
1864
1865
1866
1867
1868
1869
\fIindex2\fR is not affected). A single command may contain any number of
\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
tag is removed from the single character at \fIindex1\fR. If there are no
characters in the specified range (e.g. \fIindex1\fR is past the end of the
file or \fIindex2\fR is less than or equal to \fIindex1\fR) then the command
has no effect. This command returns an empty string.
.RE




































































































































































































































.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded windows. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBwindow\fR
argument. The following forms of the command are currently supported:
.RS







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
\fIindex2\fR is not affected). A single command may contain any number of
\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
tag is removed from the single character at \fIindex1\fR. If there are no
characters in the specified range (e.g. \fIindex1\fR is past the end of the
file or \fIindex2\fR is less than or equal to \fIindex1\fR) then the command
has no effect. This command returns an empty string.
.RE
.TP
\fIpathName\fR \fBwatch\fR ?\fB\-always\fR? ?\fIcommandPrefix\fR?
.
Monitors widget modifications, it causes a Tcl command to be executed
whenever certain widget modifications are done. In general only user (GUI)
modifications will be watched. But if option \fB\-always\fR is specified
then all modifications will be watched. In fact the triggering depends on
the way how a certain modification will be executed:
.RS
.IP \(bu 3
If option \fB\-always\fR is not specified then the \fBdelete\fR command
triggers only if the argument \fIindex1\fR (the starting point of the
deletion) is specified with
.QW insert
(the insertion cursor).
.IP \(bu 3
If option \fB\-always\fR is not specified then the \fBinsert\fR command
triggers only if the argument \fIindex\fR (the starting point of the
insertion) is specified with
.QW insert
(the insertion cursor).
.IP \(bu 3
If option \fB\-always\fR is not specified then the \fBmark set\fR command
triggers only if the argument \fImarkName\fR (the name of the mark) is
specified with
.QW insert
(the insertion cursor).
.IP \(bu 3
If option \fB\-always\fR is not specified then the \fBreplace\fR command
triggers only if the argument \fIindex1\fR (the starting point of the
replacement) is specified with
.QW insert
(the insertion cursor).
.IP \(bu 3
\fBedit undo\fR|\fBredo\fR|\fBrecover\fR will trigger the corresponding
\fBundo\fR|\fBredo\fR event.
.IP \(bu 3
A resize or content change of a displayed image will trigger event \fBimage\fR.
.IP \(bu 3
Any change of a displayed window (resize, map, or unmap) will trigger
event \fBwindow\fR.
.RE
.RS
.PP
Additionally any of the following commands may trigger because the view may
change:
.IP \(bu 3
\fIpathName \fBclear\fR|\fBload\fR
.IP \(bu 3
\fIpathName \fBconfigure\fR
.IP \(bu 3
\fIpathName \fBedit recover\fR|\fBredo\fR|\fBundo\fR
.IP \(bu 3
\fIpathName \fBimage\fR \fBconfigure\fR|\fBcreate\fR
.IP \(bu 3
\fIpathName \fBmark gravity\fR|\fBset\fR|\fBunset\fR
.IP \(bu 3
\fIpathName \fBsee\fR
.IP \(bu 3
\fIpathName \fBtag add\fR|\fBdelete\fR|\fBlower\fR|\fBraise\fR|\fBremove\fR
.IP \(bu 3
\fIpathName \fBwindow configure\fR|\fBcreate\fR
.IP \(bu 3
\fIpathName \fBxview\fR \fIarg\fR...
.IP \(bu 3
\fIpathName \fByview\fR \fIarg\fR...
.PP
Also destroying an embedded window may trigger due to a changed view.
.PP
Note that the \fBdelete\fR, and the \fBinsert\fR operation will be handled
in the same way as the \fBreplace\fR operation, this means that firstly the
deletion part triggers, and secondly the insertion part will be triggered.
In case of \fBdelete\fR the insertion part is empty (zero characters), and
in case of \fBinsert\fR the deletion range is empty.
.PP
\fICommandPrefix\fR will be resolved using the usual namespace resolution
rules used by commands. If the command does not exist, an error will be
thrown (except the command argument is empty). When a certain widget
modification triggers, a number of arguments are appended to
\fIcommandPrefix\fR so that the actual command is as follows:
.PP
.CS
\fIcommandPrefix... pathName op index1 index2 info userFlag\fR
.CE
.PP
\fIUserFlag\fR informs whether this is a user (GUI) modification. Note that
this flag is meaningful only if \fIop\fR is \fBdelete\fR, or \fBinsert\fR.
.PP
\fIOp\fR indicates which operation has been performed:
.TP
\fBinsert\fR
.
Zero or more characters have been inserted, this event will be triggered
after the insertion has been realized. \fIIndex1\fR and \fIindex2\fR are
specifying the range of the new characters after insertion, this range can
be empty. \fIInfo\fR will contain five items:
.RS
.IP [1] 4
The inserted characters.
.IP [2] 4
A list of tags applied to the character just before the inserted
characters.
.IP [3] 4
A list of tags applied to the character just after the inserted
characters.
.IP [4] 4
A list of tags applied to the newly inserted characters.
.IP [5] 4
A boolean flag indicating whether this is the final part of a
multi-insert/replace.
.PP
It should be avoided to call commands inside this event which will insert or
delete as long as \fIfinal\fR is false, the result can be unexpected. Such
commands should be postponed, either with the \fBafter\fR command, or until
\fIfinal\fR state is true.
.PP
This event will also be triggered for \fBdelete\fR, and \fBreplace\fR
operations, in these cases zero characters may be inserted, and \fIindex1\fR
refers to the start position of the deletion.
.RE
.TP
\fBdelete\fR
.
Zero or more characters will be deleted, this event will be triggered before
the deletion has been realized. \fIIndex1\fR and \fIindex2\fR are specifying
the range of the characters to be deleted, this range can be empty.
\fIInfo\fR will contain six items:
.RS
.IP [1] 4
The deleted characters.
.IP [2] 4
A list of tags applied to the character just before the deleted
characters.
.IP [3] 4
A list of tags applied to the character just after the deleted
characters.
.IP [4] 4
A list of tage applied to the first deleted character.
.IP [5] 4
A list of tage applied to the last deleted character.
.IP [6] 4
A boolean flag indicating whether this is the final part of a
multi-delete/replace.
.PP
This event will also be triggered for \fBinsert\fR, and \fBreplace\fR
operations, in these cases the deletion range may be empty, and \fIindex1\fR
refers to the start position of the insertion.
.PP
It should be avoided to call commands inside this event which will insert or
delete, the result can be unexpected. Such commands should be postponed,
either with the \fBafter\fR command, or until the corresponding \fBinsert\fR
event will be triggered.
.RE
.TP
\fBcursor\fR
.
The position of the insertion cursor has been moved. \fIIndex1\fR is the old
character position, and can be empty, \fIindex2\fR is the new character
position of the cursor. Here \fIinfo\fR contains a list of tags which would
be applied if the user (GUI) is inserting a character at the new cursor
position.
.TP
\fBview\fR
.
The view of the widget has changed (scrolling the widget, moving the cursor,
the see command has been executed, or any other modifying command has been
performed \- see the list of modifiying commands above). Here \fIindex1\fR
specifies the pixel position of the upper left corner in the form @x,y, and
\fIindex2\fR specifies the pixel position of the lower right corner.
\fIInfo\fR does not have a meaning here and will be empty.
.TP
\fBundo\fR
.
An undo action has been performed. \fIInfo\fR contains two elements. The
first is the performed undo command, one of: \fIdelete\fR, \fIimage\fR,
\fIinsert\fR, \fImark\fR, \fItag\fR, or \fIwindow\fR. The second is a
boolean flag indicating whether this is the final part of a multi-undo
action.
.RS
.PP
It is not allowed to perform any textual modification, nor is it allowed to
reset the undo/redo stack, an error will be thrown.
.RE
.TP
\fBredo\fR
.
A redo action has been performed. \fIInfo\fR contains two elements. The
first is the performed redo command, one of: \fIdelete\fR, \fIimage\fR,
\fIinsert\fR, \fImark\fR, \fItag\fR, or \fIwindow\fR. The second is a
boolean flag indicating whether this is the final part of a multi-redo
action.
.RS
.PP
It is not allowed to perform any textual modification, nor is it allowed to
reset the undo/redo stack, an error will be thrown.
.RE
.TP
\fBimage\fR
.
An image has been resized, or the content has changed. \fIInfo\fR contains
the name of the affected image as first element. In case of a change in
size the width and height of the image before resizing will be the second
and third element of \fIinfo\fR.
.TP
\fBwindow\fR
.
Either a window has changed the display state (mapped or unmapped), or the
size of the window has changed. \fIInfo\fR contains the name of the affected
window as first element. And if the size of the window has changed, then
\fIinfo\fR will provide the old width and height with a second and third
element.
.PP
\fIPathName\fR is the name of the widget where the modification has been
done. In case of \fBinsert\fR/\fBdelete\fR also the modifications in a
different peer will be triggered for this widget, provided that the range of
the modification is inside the displayed range. It is guaranteed that the
widget, where the \fBinsert\fR/\fBdelete\fR has been done, will be triggered
at first, but the order of triggering other peers is unspecified.
.PP
If \fIcommandPrefix\fR is not specified, then the watch of modifications
will be terminated. Otherwise it will replace any existing script, but if
the first character is
.QW \fC+\fR
then the new script augments an existing script.
.PP
This command returns the command prefix which has been set before this call,
this can be empty if a command prefix was not set.
.RE
.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded windows. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBwindow\fR
argument. The following forms of the command are currently supported:
.RS
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
Tk automatically creates class bindings for texts that give them the following
default behavior.
In the descriptions below,
.QW word
is dependent on the value of
the \fBtcl_wordchars\fR variable.  See \fBtclvars\fR(n).
.IP [1]
Clicking mouse button 1 positions the insertion cursor just before the
character underneath the mouse cursor, sets the input focus to this widget,
and clears any selection in the widget. Dragging with mouse button 1 strokes
out a selection between the insertion cursor and the character under the
mouse.
.IP [2]
Double-clicking with mouse button 1 selects the word under the mouse and
positions the insertion cursor at the start of the word. Dragging after a







|







4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
Tk automatically creates class bindings for texts that give them the following
default behavior.
In the descriptions below,
.QW word
is dependent on the value of
the \fBtcl_wordchars\fR variable.  See \fBtclvars\fR(n).
.IP [1]
Clicking mouse button 1 positions the insertion cursor at the closest edge of the
character underneath the mouse cursor, sets the input focus to this widget,
and clears any selection in the widget. Dragging with mouse button 1 strokes
out a selection between the insertion cursor and the character under the
mouse.
.IP [2]
Double-clicking with mouse button 1 selects the word under the mouse and
positions the insertion cursor at the start of the word. Dragging after a
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
.IP [18]
Control-/ selects the entire contents of the widget.
.IP [19]
Control-\e clears any selection in the widget.
.IP [20]
The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the
selection in the widget to the clipboard, if there is a selection. This
action is carried out by the command \fBtk_textCopy\fR.
.IP [21]
The F20 key (labelled Cut on many Sun workstations) or Control-w copies the
selection in the widget to the clipboard and deletes the selection. This
action is carried out by the command \fBtk_textCut\fR. If there is no
selection in the widget then these keys have no effect.
.IP [22]
The F18 key (labelled Paste on many Sun workstations) or Control-y inserts the
contents of the clipboard at the position of the insertion cursor. This action
is carried out by the command \fBtk_textPaste\fR.
.IP [23]
The Delete key deletes the selection, if there is one in the widget. If there
is no selection, it deletes the character to the right of the insertion
cursor.
.IP [24]
Backspace and Control-h delete the selection, if there is one in the widget.
If there is no selection, they delete the character to the left of the







|



|




|







4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
.IP [18]
Control-/ selects the entire contents of the widget.
.IP [19]
Control-\e clears any selection in the widget.
.IP [20]
The F16 key (labelled Copy on many Sun workstations) or Meta-w copies the
selection in the widget to the clipboard, if there is a selection. This
action is carried out by the command \%\fBtk_textCopy\fR.
.IP [21]
The F20 key (labelled Cut on many Sun workstations) or Control-w copies the
selection in the widget to the clipboard and deletes the selection. This
action is carried out by the command \%\fBtk_textCut\fR. If there is no
selection in the widget then these keys have no effect.
.IP [22]
The F18 key (labelled Paste on many Sun workstations) or Control-y inserts the
contents of the clipboard at the position of the insertion cursor. This action
is carried out by the command \%\fBtk_textPaste\fR.
.IP [23]
The Delete key deletes the selection, if there is one in the widget. If there
is no selection, it deletes the character to the right of the insertion
cursor.
.IP [24]
Backspace and Control-h delete the selection, if there is one in the widget.
If there is no selection, they delete the character to the left of the
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
.PP
If the widget is disabled using the \fB\-state\fR option, then its view can
still be adjusted and text can still be selected, but no insertion cursor will
be displayed and no text modifications will take place.
.PP
The behavior of texts can be changed by defining new bindings for individual
widgets or by redefining the class bindings.
.SH "KNOWN ISSUES"
.SS "ISSUES CONCERNING CHARS AND INDICES"
.PP

Before Tk 8.5, the widget used the string













.QW chars

to refer to index positions (which included characters, embedded windows and

embedded images). As of Tk 8.5 the text widget deals separately and correctly







































with
.QW chars
and


.QW indices .
For backwards compatibility, however, the index modifiers






.QW "+N chars"
and
.QW "\-N chars"
continue to refer to indices. One must use any of the full forms








.QW "+N any chars"
or
.QW "\-N any chars"

etc. to refer to actual character indices. This confusion may be fixed in a
future release by making the widget correctly interpret
.QW "+N chars"
as a synonym for
.QW "+N any chars" .
.SS "PERFORMANCE ISSUES"
.PP
Text widgets should run efficiently under a variety of conditions. The text
widget uses about 2-3 bytes of main memory for each byte of text, so texts
containing a megabyte or more should be practical on most workstations. Text
is represented internally with a modified B-tree structure that makes
operations relatively efficient even with large texts. Tags are included in







|
<

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<
>
>
|
<
>
>
>
>
>
>
|
<
|
|
>
>
>
>
>
>
>
>
|
<
<
>
|
|
|
<
<







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
.PP
If the widget is disabled using the \fB\-state\fR option, then its view can
still be adjusted and text can still be selected, but no insertion cursor will
be displayed and no text modifications will take place.
.PP
The behavior of texts can be changed by defining new bindings for individual
widgets or by redefining the class bindings.
.SH "DEPRECIATION WARNINGS"

.PP
Some functions/options now are marked as deprecated and will be removed in a
later version. Here is an overview about all possible depreciation warnings,
with possible solutions:
.PP
.IP \(bu 3
\fBtk::text: Option "-startline" is deprecated, please use option "-startindex".\fR
.PP
Replace all occurrences of
.QW "\fB$w -startline 4\fR"
with
.QW "\fB$w -startindex 4.0\fR".
.IP \(bu 3
\fBtk::text: Option "-endline" is deprecated, please use option "-endindex".\fR
.PP
Replace all occurrences of
.QW "\fB$w -endline 4\fR"
with
.QW "\fB$w -endindex 3.end\fR" .
.IP \(bu 3
\fBtk::text: Attempt to modify a disabled widget is deprecated.\fR
.PP
Remove this useless expression, a disabled widget cannot be
modified.
.IP \(bu 3
\fBtk::text: Attempt to modify a dead widget is deprecated.\fR
.PP
Remove this useless expression, a dead widget (does not contain
lines and does not show an insertion cursor) cannot be modified.
.IP \(bu 3
\fBtk::text: Command "edit canredo" is deprecated, please use "edit info".\fR
.PP
Replace all occurrences
.QW "\fB[$w edit canredo]\fR"
with
.QW "\fB[$w edit info -redodepth]\fR" .
.IP \(bu 3
\fBtk::text: Command "edit canundo" is deprecated, please use "edit info".\fR
.PP
Replace all occurrences
.QW "\fB[$w edit canundo]\fR"
with
.QW "\fB[$w edit info -undodepth]\fR" .
.IP \(bu 3
\fBtk::text: "begin" is a reserved index identifier and shouldn't be used for mark names anymore.\fR
.PP
Replace this mark name with a different mark name,
but do this at all places where \fBbegin\fR is used as a name for a mark.
.IP \(bu 3
\fBtk::text: Tag option "-overstrikefg" is deprecated, please use option "-overstrikecolor".\fR
.PP
Replace all occurrences
.QW "\fB$w tag configure -overstrikefg black\fR"
with
.QW "\fB$w tag configure -overstrikecolor black\fR" .
.IP \(bu 3
\fBtk::text: Tag option "-underlinefg" is deprecated, please use option "-underlinecolor".\fR
.PP
Replace all occurrences
.QW "\fB$w tag configure -underlinefg black\fR"
with
.QW "\fB$w tag configure -underlinecolor black\fR" .

.SH "KNOWN ISSUES"
.SS "ISSUES CONCERNING INDICES"
.PP

Currently the special index specifier \fBbegin\fR has the lowest precedence,
although it should have the same precedence as the special index special
\fBend\fR (see section \fBINDICES\fR). In a future release this will be
corrected. The current behavior is a workaround, avoiding that existing
applications will break with the introduction of \fBbegin\fR.
.SS "ISSUES CONCERNING WIDGET STATE"
.PP

Older versions of text widgets are ignoring textual changes
(insert/replace/delete) if the state of the widget is set to \fBdisabled\fR
(see widget option \fB\-state\fR). But it allows to insert/delete
embedded windows and images. Because of compatibility reasons this behavior
has not been changed. But in future versions also inserting/deleting
embedded windows and images should not be allowed. Furthermore in a future
version an error message should be thrown when attempting to make textual
changes (including embedded windows and images), because silently ignoring
changes (current behavior) can be quite confusing.
.SS "ISSUES CONCERNING DEAD PEERS"
.PP


See \fBisdead\fR about dead peers. Because of compatibility reasons
textual changes within a dead peer are still allowed, although it has
no effect, but in future versions of text widgets an error message
should be thrown when attempting to make changes within a dead peer.


.SS "PERFORMANCE ISSUES"
.PP
Text widgets should run efficiently under a variety of conditions. The text
widget uses about 2-3 bytes of main memory for each byte of text, so texts
containing a megabyte or more should be practical on most workstations. Text
is represented internally with a modified B-tree structure that makes
operations relatively efficient even with large texts. Tags are included in
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
ranges of each tag are near the beginning and end of the text, respectively,
or a single tag range covers most of the text widget. The cost of adding and
deleting tags like this is proportional to the number of other tags with the
same properties. In contrast, there is no problem with having thousands of
distinct tags if their overall ranges are localized and spread uniformly
throughout the text.
.PP
Very long text lines can be expensive, especially if they have many marks and
tags within them.
.PP
The display line with the insert cursor is redrawn each time the cursor
blinks, which causes a steady stream of graphics traffic. Set the
\fB\-insertofftime\fR attribute to 0 avoid this.
.SS "KNOWN BUGS"
.PP
The \fIpathName \fBsearch \-regexp\fR sub-command attempts to perform
sophisticated regexp matching across multiple lines in an efficient fashion
(since Tk 8.5), examining each line individually, and then in small groups of
lines, whether searching forwards or backwards. Under certain conditions the
search result might differ from that obtained by applying the same regexp to
the entire text from the widget in one go. For example, when searching with a
greedy regexp, the widget will continue to attempt to add extra lines to the
match as long as one of two conditions are true: either Tcl's regexp library
returns a code to indicate a longer match is possible (but there are known
bugs in Tcl which mean this code is not always correctly returned); or if each
extra line added results in at least a partial match with the pattern. This
means in the case where the first extra line added results in no match and
Tcl's regexp system returns the incorrect code and adding a second extra line
would actually match, the text widget will return the wrong result. In
practice this is a rare problem, but it can occur, for example:

.CS
pack [\fBtext\fR .t]
\&.t insert 1.0 "aaaa\enbbbb\encccc\enbbbb\enaaaa\en"
\&.t search \-regexp \-\- {(a+|b+\enc+\enb+)+\ena+} 1.0
.CE

will not find a match when one exists of 19 characters starting from the first
.QW b .
.PP
Whenever one possible match is fully enclosed in another, the search command
will attempt to ensure only the larger match is returned. When performing
backwards regexp searches it is possible that Tcl will not always achieve
this, in the case where a match is preceded by one or more short,
non-overlapping matches, all of which are preceded by a large match which
actually encompasses all of them. The search algorithm used by the widget does
not look back arbitrarily far for a possible match which might cover large
portions of the widget. For example:

.CS
pack [\fBtext\fR .t]
\&.t insert 1.0 "aaaa\enbbbb\enbbbb\enbbbb\enbbbb\\n"
\&.t search \-regexp \-backward \-\- {b+\en|a+\en(b+\en)+} end
.CE

matches at
.QW 5.0
when a true greedy match would match at
.QW 1.0 .
Similarly if we add \fB\-all\fR to this case, it matches at all of
.QW 5.0 ,
.QW 4.0 ,







<
<
<


|

















>


|
|

>











>


|
|

>







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
ranges of each tag are near the beginning and end of the text, respectively,
or a single tag range covers most of the text widget. The cost of adding and
deleting tags like this is proportional to the number of other tags with the
same properties. In contrast, there is no problem with having thousands of
distinct tags if their overall ranges are localized and spread uniformly
throughout the text.
.PP



The display line with the insert cursor is redrawn each time the cursor
blinks, which causes a steady stream of graphics traffic. Set the
\fB\-insertofftime\fR attribute to zero for avoiding this.
.SS "KNOWN BUGS"
.PP
The \fIpathName \fBsearch \-regexp\fR sub-command attempts to perform
sophisticated regexp matching across multiple lines in an efficient fashion
(since Tk 8.5), examining each line individually, and then in small groups of
lines, whether searching forwards or backwards. Under certain conditions the
search result might differ from that obtained by applying the same regexp to
the entire text from the widget in one go. For example, when searching with a
greedy regexp, the widget will continue to attempt to add extra lines to the
match as long as one of two conditions are true: either Tcl's regexp library
returns a code to indicate a longer match is possible (but there are known
bugs in Tcl which mean this code is not always correctly returned); or if each
extra line added results in at least a partial match with the pattern. This
means in the case where the first extra line added results in no match and
Tcl's regexp system returns the incorrect code and adding a second extra line
would actually match, the text widget will return the wrong result. In
practice this is a rare problem, but it can occur, for example:
.PP
.CS
pack [\fBtext\fR .t]
\%.t insert 1.0 "aaaa\enbbbb\encccc\enbbbb\enaaaa\en"
\%.t search \-regexp \-\- {(a+|b+\enc+\enb+)+\ena+} 1.0
.CE
.PP
will not find a match when one exists of 19 characters starting from the first
.QW b .
.PP
Whenever one possible match is fully enclosed in another, the search command
will attempt to ensure only the larger match is returned. When performing
backwards regexp searches it is possible that Tcl will not always achieve
this, in the case where a match is preceded by one or more short,
non-overlapping matches, all of which are preceded by a large match which
actually encompasses all of them. The search algorithm used by the widget does
not look back arbitrarily far for a possible match which might cover large
portions of the widget. For example:
.PP
.CS
pack [\fBtext\fR .t]
\%.t insert 1.0 "aaaa\enbbbb\enbbbb\enbbbb\enbbbb\\n"
\%.t search \-regexp \-backward \-\- {b+\en|a+\en(b+\en)+} end
.CE
.PP
matches at
.QW 5.0
when a true greedy match would match at
.QW 1.0 .
Similarly if we add \fB\-all\fR to this case, it matches at all of
.QW 5.0 ,
.QW 4.0 ,

Changes to doc/tk.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
.TH tk n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk \- Manipulate Tk internal state
.SH SYNOPSIS
\fBtk\fR \fIoption \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBtk\fR command provides access to miscellaneous
elements of Tk's internal state.
Most of the information manipulated by this command pertains to the
application as a whole, or to a screen or display, rather than to a
particular window.
The command can take any of a number of different forms
depending on the \fIoption\fR argument.  The legal forms are:

.TP
\fBtk appname \fR?\fInewName\fR?
.
If \fInewName\fR is not specified, this command returns the name
of the application (the name that may be used in \fBsend\fR
commands to communicate with the application).
If \fInewName\fR is specified, then the name of the application







|










>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
.TH tk n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk \- Manipulate Tk internal state
.SH SYNOPSIS
\fBtk\fI option \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBtk\fR command provides access to miscellaneous
elements of Tk's internal state.
Most of the information manipulated by this command pertains to the
application as a whole, or to a screen or display, rather than to a
particular window.
The command can take any of a number of different forms
depending on the \fIoption\fR argument.  The legal forms are:
.\" METHOD: appname
.TP
\fBtk appname \fR?\fInewName\fR?
.
If \fInewName\fR is not specified, this command returns the name
of the application (the name that may be used in \fBsend\fR
commands to communicate with the application).
If \fInewName\fR is specified, then the name of the application
40
41
42
43
44
45
46

47
48
49
50
51
52
53

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

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

84
85

86
87









88
89
90
91
92
93
94
\fInewName\fR should not start with a capital letter.
This will interfere with option processing, since names starting with
capitals are assumed to be classes;  as a result, Tk may not
be able to find some options for the application.
If sends have been disabled by deleting the \fBsend\fR command,
this command will reenable them and recreate the \fBsend\fR
command.

.TP
\fBtk busy \fIsubcommand\fR ...
.
This command controls the marking of window hierarchies as
.QW busy ,
rendering them non-interactive while some other operation is proceeding. For
more details see the \fBbusy\fR manual page.

.TP
\fBtk caret \fIwindow \fR?\fB\-x \fIx\fR? ?\fB\-y \fIy\fR? ?\fB\-height \fIheight\fR?
.
Sets and queries the caret location for the display of the specified
Tk window \fIwindow\fR.  The caret is the per-display cursor location
used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot
XIM (X Input Methods) or Windows IME windows.  If no options are specified,
the last values used for setting the caret are return in option-value pair
format.  \fB\-x\fR and \fB\-y\fR represent window-relative coordinates, and
\fB\-height\fR is the height of the current cursor location, or the height
of the specified \fIwindow\fR if none is given.

.TP
\fBtk inactive \fR?\fB\-displayof \fIwindow\fR? ?\fBreset\fR?
.
Returns a positive integer, the number of milliseconds since the last
time the user interacted with the system. If the \fB\-displayof\fR
option is given then the return value refers to the display of
\fIwindow\fR; otherwise it refers to the display of the application's
main window.
.RS
.PP
\fBtk inactive\fR will return \-1, if querying the user inactive time
is not supported by the system, and in safe interpreters.
.PP
If the literal string \fBreset\fR is given as an additional argument,
the timer is reset and an empty string is returned. Resetting the
inactivity time is forbidden in safe interpreters and will throw an
error if tried.
.RE

.TP
\fBtk fontchooser \fIsubcommand\fR ...

Controls the Tk font selection dialog. For more details see the
\fBfontchooser\fR manual page.









.TP
\fBtk scaling \fR?\fB\-displayof \fIwindow\fR? ?\fInumber\fR?
.
Sets and queries the current scaling factor used by Tk to convert between
physical units (for example, points, inches, or millimeters) and pixels.  The
\fInumber\fR argument is a floating point number that specifies the number of
pixels per point on \fIwindow\fR's display.  If the \fIwindow\fR argument is







>







>












>


















>


>


>
>
>
>
>
>
>
>
>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
\fInewName\fR should not start with a capital letter.
This will interfere with option processing, since names starting with
capitals are assumed to be classes;  as a result, Tk may not
be able to find some options for the application.
If sends have been disabled by deleting the \fBsend\fR command,
this command will reenable them and recreate the \fBsend\fR
command.
.\" METHOD: busy
.TP
\fBtk busy \fIsubcommand\fR ...
.
This command controls the marking of window hierarchies as
.QW busy ,
rendering them non-interactive while some other operation is proceeding. For
more details see the \fBbusy\fR manual page.
.\" METHOD: caret
.TP
\fBtk caret \fIwindow \fR?\fB\-x \fIx\fR? ?\fB\-y \fIy\fR? ?\fB\-height \fIheight\fR?
.
Sets and queries the caret location for the display of the specified
Tk window \fIwindow\fR.  The caret is the per-display cursor location
used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot
XIM (X Input Methods) or Windows IME windows.  If no options are specified,
the last values used for setting the caret are return in option-value pair
format.  \fB\-x\fR and \fB\-y\fR represent window-relative coordinates, and
\fB\-height\fR is the height of the current cursor location, or the height
of the specified \fIwindow\fR if none is given.
.\" METHOD: inactive
.TP
\fBtk inactive \fR?\fB\-displayof \fIwindow\fR? ?\fBreset\fR?
.
Returns a positive integer, the number of milliseconds since the last
time the user interacted with the system. If the \fB\-displayof\fR
option is given then the return value refers to the display of
\fIwindow\fR; otherwise it refers to the display of the application's
main window.
.RS
.PP
\fBtk inactive\fR will return \-1, if querying the user inactive time
is not supported by the system, and in safe interpreters.
.PP
If the literal string \fBreset\fR is given as an additional argument,
the timer is reset and an empty string is returned. Resetting the
inactivity time is forbidden in safe interpreters and will throw an
error if tried.
.RE
.\" METHOD: fontchooser
.TP
\fBtk fontchooser \fIsubcommand\fR ...
.
Controls the Tk font selection dialog. For more details see the
\fBfontchooser\fR manual page.
.\" METHOD: print
.TP
\fBtk print \fIwindow\fR
.
The \fBtk print\fR command posts a dialog that allows users to print output
from the \fBcanvas\fR and \fBtext\fR widgets. The printing will be done using
platform-native APIs and dialogs where available. For more details see the
\fBprint\fR manual page.
.\" METHOD: scaling
.TP
\fBtk scaling \fR?\fB\-displayof \fIwindow\fR? ?\fInumber\fR?
.
Sets and queries the current scaling factor used by Tk to convert between
physical units (for example, points, inches, or millimeters) and pixels.  The
\fInumber\fR argument is a floating point number that specifies the number of
pixels per point on \fIwindow\fR's display.  If the \fIwindow\fR argument is
106
107
108
109
110
111
112















113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
displayed 1.25 times as large as normal.  The initial value for the scaling
factor is set when the application starts, based on properties of the
installed monitor, but it can be changed at any time.  Measurements made
after the scaling factor is changed will use the new scaling factor, but it
is undefined whether existing widgets will resize themselves dynamically to
accommodate the new scaling factor.
.RE















.TP
\fBtk useinputmethods \fR?\fB\-displayof \fIwindow\fR? ?\fIboolean\fR?
.
Sets and queries the state of whether Tk should use XIM (X Input Methods)
for filtering events.  The resulting state is returned.  XIM is used in
some locales (i.e., Japanese, Korean), to handle special input devices. This
feature is only significant on X.  If XIM support is not available, this
will always return 0.  If the \fIwindow\fR argument is omitted, it defaults
to the main window.  If the \fIboolean\fR argument is omitted, the current
state is returned.  This is turned on by default for the main display.

.TP
\fBtk windowingsystem\fR
.
Returns the current Tk windowing system, one of
\fBx11\fR (X11-based), \fBwin32\fR (MS Windows),
or \fBaqua\fR (Mac OS X Aqua).
.SH "SEE ALSO"
busy(n), fontchooser(n), send(n), winfo(n)
.SH KEYWORDS
application name, send
'\" Local Variables:
'\" mode: nroff
'\" End:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>







|

|



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
displayed 1.25 times as large as normal.  The initial value for the scaling
factor is set when the application starts, based on properties of the
installed monitor, but it can be changed at any time.  Measurements made
after the scaling factor is changed will use the new scaling factor, but it
is undefined whether existing widgets will resize themselves dynamically to
accommodate the new scaling factor.
.RE
.\" METHOD: sysnotify
.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 \fBsysnotify\fR manual page.
.\" METHOD: systray
.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 \fBsystray\fR manual page.
.\" METHOD: useinputmethods
.TP
\fBtk useinputmethods \fR?\fB\-displayof \fIwindow\fR? ?\fIboolean\fR?
.
Sets and queries the state of whether Tk should use XIM (X Input Methods)
for filtering events.  The resulting state is returned.  XIM is used in
some locales (i.e., Japanese, Korean), to handle special input devices. This
feature is only significant on X.  If XIM support is not available, this
will always return 0.  If the \fIwindow\fR argument is omitted, it defaults
to the main window.  If the \fIboolean\fR argument is omitted, the current
state is returned.  This is turned on by default for the main display.
.\" METHOD: windowingsystem
.TP
\fBtk windowingsystem\fR
.
Returns the current Tk windowing system, one of
\fBx11\fR (X11-based), \fBwin32\fR (MS Windows),
or \fBaqua\fR (Mac OS X Aqua).
.SH "SEE ALSO"
busy(n), fontchooser(n), print(n), send(n), sysnotify(n), systray(n), winfo(n)
.SH KEYWORDS
application name, print, send, sysnotify, systray
'\" Local Variables:
'\" mode: nroff
'\" End:

Deleted doc/tk4.0.ps.

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

/FMPrintInColor { % once-thru loop gimmick
    % See if we're a NeWSprint printer
     /currentcanvas where {
        pop systemdict /separationdict known
	exit
     } if
% originally had the following, which should always be false:
%    /currentcanvas where {
%        pop currentcanvas /Color known {
%	    currentcanvas /Color get
%	    exit
%        } if
%    } if
    systemdict /colorimage known
    systemdict /currentcolortransfer known and
exit } loop def

% Uncomment the following line to force b&w on color printer
%   /FMPrintInColor false def
/FrameDict 195 dict def
systemdict /errordict known not {/errordict 10 dict def
		errordict /rangecheck {stop} put} if
% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
FrameDict /tmprangecheck errordict /rangecheck get put
errordict /rangecheck {FrameDict /bug true put} put
FrameDict /bug false put
mark
% Some PS machines read past the CR, so keep the following 3 lines together!
currentfile 5 string readline
00
0000000000
cleartomark
errordict /rangecheck FrameDict /tmprangecheck get put
FrameDict /bug get {
	/readline {
		/gstring exch def
		/gfile exch def
		/gindex 0 def
		{
			gfile read pop
			dup 10 eq {exit} if
			dup 13 eq {exit} if
			gstring exch gindex exch put
			/gindex gindex 1 add def
		} loop
		pop
		gstring 0 gindex getinterval true
		} def
	} if
/FMVERSION {
	FMversion ne {
		/Times-Roman findfont 18 scalefont setfont
		100 100 moveto
		(FrameMaker version does not match postscript_prolog!)
		dup =
		show showpage
		} if
	} def
/FMLOCAL {
	FrameDict begin
	0 def
	end
	} def
	/gstring FMLOCAL
	/gfile FMLOCAL
	/gindex FMLOCAL
	/orgxfer FMLOCAL
	/orgproc FMLOCAL
	/organgle FMLOCAL
	/orgfreq FMLOCAL
	/yscale FMLOCAL
	/xscale FMLOCAL
	/manualfeed FMLOCAL
	/paperheight FMLOCAL
	/paperwidth FMLOCAL
/FMDOCUMENT {
	array /FMfonts exch def
	/#copies exch def
	FrameDict begin
	0 ne dup {setmanualfeed} if
	/manualfeed exch def
	/paperheight exch def
	/paperwidth exch def
	/yscale exch def
	/xscale exch def
	currenttransfer cvlit /orgxfer exch def
	currentscreen cvlit /orgproc exch def
	/organgle exch def /orgfreq exch def
	setpapername
	manualfeed {true} {papersize} ifelse
	{manualpapersize} {false} ifelse
	{desperatepapersize} if
	end
	} def
	/pagesave FMLOCAL
	/orgmatrix FMLOCAL
	/landscape FMLOCAL
/FMBEGINPAGE {
	FrameDict begin
	/pagesave save def
	3.86 setmiterlimit
	/landscape exch 0 ne def
	landscape {
		90 rotate 0 exch neg translate pop
		}
		{pop pop}
		ifelse
	xscale yscale scale
	/orgmatrix matrix def
	gsave
	} def
/FMENDPAGE {
	grestore
	pagesave restore
	end
	showpage
	} def
/FMFONTDEFINE {
	FrameDict begin
	findfont
	ReEncode
	1 index exch
	definefont
	FMfonts 3 1 roll
	put
	end
	} def
/FMFILLS {
	FrameDict begin
	array /fillvals exch def
	end
	} def
/FMFILL {
	FrameDict begin
	 fillvals 3 1 roll put
	end
	} def
/FMNORMALIZEGRAPHICS {
	newpath
	0.0 0.0 moveto
	1 setlinewidth
	0 setlinecap
	0 0 0 sethsbcolor
	0 setgray
	} bind def
	/fx FMLOCAL
	/fy FMLOCAL
	/fh FMLOCAL
	/fw FMLOCAL
	/llx FMLOCAL
	/lly FMLOCAL
	/urx FMLOCAL
	/ury FMLOCAL
/FMBEGINEPSF {
	end
	/FMEPSF save def
	/showpage {} def
	FMNORMALIZEGRAPHICS
	[/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall
	fx fy translate
	rotate
	fw urx llx sub div fh ury lly sub div scale
	llx neg lly neg translate
	} bind def
/FMENDEPSF {
	FMEPSF restore
	FrameDict begin
	} bind def
FrameDict begin
/setmanualfeed {
%%BeginFeature *ManualFeed True
	 statusdict /manualfeed true put
%%EndFeature
	} def
/max {2 copy lt {exch} if pop} bind def
/min {2 copy gt {exch} if pop} bind def
/inch {72 mul} def
/pagedimen {
	paperheight sub abs 16 lt exch
	paperwidth sub abs 16 lt and
	{/papername exch def} {pop} ifelse
	} def
	/papersizedict FMLOCAL
/setpapername {
	/papersizedict 14 dict def
	papersizedict begin
	/papername /unknown def
		/Letter 8.5 inch 11.0 inch pagedimen
		/LetterSmall 7.68 inch 10.16 inch pagedimen
		/Tabloid 11.0 inch 17.0 inch pagedimen
		/Ledger 17.0 inch 11.0 inch pagedimen
		/Legal 8.5 inch 14.0 inch pagedimen
		/Statement 5.5 inch 8.5 inch pagedimen
		/Executive 7.5 inch 10.0 inch pagedimen
		/A3 11.69 inch 16.5 inch pagedimen
		/A4 8.26 inch 11.69 inch pagedimen
		/A4Small 7.47 inch 10.85 inch pagedimen
		/B4 10.125 inch 14.33 inch pagedimen
		/B5 7.16 inch 10.125 inch pagedimen
	end
	} def
/papersize {
	papersizedict begin
		/Letter {lettertray letter} def
		/LetterSmall {lettertray lettersmall} def
		/Tabloid {11x17tray 11x17} def
		/Ledger {ledgertray ledger} def
		/Legal {legaltray legal} def
		/Statement {statementtray statement} def
		/Executive {executivetray executive} def
		/A3 {a3tray a3} def
		/A4 {a4tray a4} def
		/A4Small {a4tray a4small} def
		/B4 {b4tray b4} def
		/B5 {b5tray b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	/FMdicttop countdictstack 1 add def
	statusdict begin stopped end
	countdictstack -1 FMdicttop {pop end} for
	} def
/manualpapersize {
	papersizedict begin
		/Letter {letter} def
		/LetterSmall {lettersmall} def
		/Tabloid {11x17} def
		/Ledger {ledger} def
		/Legal {legal} def
		/Statement {statement} def
		/Executive {executive} def
		/A3 {a3} def
		/A4 {a4} def
		/A4Small {a4small} def
		/B4 {b4} def
		/B5 {b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	stopped
	} def
/desperatepapersize {
	statusdict /setpageparams known
		{
		paperwidth paperheight 0 1
		statusdict begin
		{setpageparams} stopped pop
		end
		} if
	} def
/savematrix {
	orgmatrix currentmatrix pop
	} bind def
/restorematrix {
	orgmatrix setmatrix
	} bind def
/dmatrix matrix def
/dpi    72 0 dmatrix defaultmatrix dtransform
    dup mul exch   dup mul add   sqrt def
/freq dpi 18.75 div 8 div round dup 0 eq {pop 1} if 8 mul dpi exch div def
/sangle 1 0 dmatrix defaultmatrix dtransform exch atan def
/DiacriticEncoding [
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl
/numbersign /dollar /percent /ampersand /quotesingle /parenleft
/parenright /asterisk /plus /comma /hyphen /period /slash /zero /one
/two /three /four /five /six /seven /eight /nine /colon /semicolon
/less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K
/L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash
/bracketright /asciicircum /underscore /grave /a /b /c /d /e /f /g /h
/i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar
/braceright /asciitilde /.notdef /Adieresis /Aring /Ccedilla /Eacute
/Ntilde /Odieresis /Udieresis /aacute /agrave /acircumflex /adieresis
/atilde /aring /ccedilla /eacute /egrave /ecircumflex /edieresis
/iacute /igrave /icircumflex /idieresis /ntilde /oacute /ograve
/ocircumflex /odieresis /otilde /uacute /ugrave /ucircumflex
/udieresis /dagger /.notdef /cent /sterling /section /bullet
/paragraph /germandbls /registered /copyright /trademark /acute
/dieresis /.notdef /AE /Oslash /.notdef /.notdef /.notdef /.notdef
/yen /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/ordfeminine /ordmasculine /.notdef /ae /oslash /questiondown
/exclamdown /logicalnot /.notdef /florin /.notdef /.notdef
/guillemotleft /guillemotright /ellipsis /.notdef /Agrave /Atilde
/Otilde /OE /oe /endash /emdash /quotedblleft /quotedblright
/quoteleft /quoteright /.notdef /.notdef /ydieresis /Ydieresis
/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
/periodcentered /quotesinglbase /quotedblbase /perthousand
/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
] def
/ReEncode {
	dup
	length
	dict begin
	{
	1 index /FID ne
		{def}
		{pop pop} ifelse
	} forall
	0 eq {/Encoding DiacriticEncoding def} if
	currentdict
	end
	} bind def
/graymode true def
	/bwidth FMLOCAL
	/bpside FMLOCAL
	/bstring FMLOCAL
	/onbits FMLOCAL
	/offbits FMLOCAL
	/xindex FMLOCAL
	/yindex FMLOCAL
	/x FMLOCAL
	/y FMLOCAL
/setpattern {
	 /bwidth  exch def
	 /bpside  exch def
	 /bstring exch def
	 /onbits 0 def  /offbits 0 def
	 freq sangle landscape {90 add} if
		{/y exch def
		 /x exch def
		 /xindex x 1 add 2 div bpside mul cvi def
		 /yindex y 1 add 2 div bpside mul cvi def
		 bstring yindex bwidth mul xindex 8 idiv add get
		 1 7 xindex 8 mod sub bitshift and 0 ne
		 {/onbits  onbits  1 add def 1}
		 {/offbits offbits 1 add def 0}
		 ifelse
		}
		setscreen
	 {} settransfer
	 offbits offbits onbits add div FMsetgray
	/graymode false def
	} bind def
/grayness {
	FMsetgray
	graymode not {
		/graymode true def
		orgxfer cvx settransfer
		orgfreq organgle orgproc cvx setscreen
		} if
	} bind def
	/HUE FMLOCAL
	/SAT FMLOCAL
	/BRIGHT FMLOCAL
	/Colors FMLOCAL
FMPrintInColor

	{
	/HUE 0 def
	/SAT 0 def
	/BRIGHT 0 def
	% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
	/Colors
	[[0    0  ]    % black
	 [0    0  ]    % white
	 [0.00 1.0]    % red
	 [0.37 1.0]    % green
	 [0.60 1.0]    % blue
	 [0.50 1.0]    % cyan
	 [0.83 1.0]    % magenta
	 [0.16 1.0]    % comment / yellow
	 ] def

	/BEGINBITMAPCOLOR {
		BITMAPCOLOR} def
	/BEGINBITMAPCOLORc {
		BITMAPCOLORc} def
	/BEGINBITMAPTRUECOLOR {
		BITMAPTRUECOLOR } def
	/BEGINBITMAPTRUECOLORc {
		BITMAPTRUECOLORc } def
	/K {
		Colors exch get dup
		0 get /HUE exch store
		1 get /BRIGHT exch store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
		  ifelse
		} def
	/FMsetgray {
		/SAT exch 1.0 exch sub store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
		  ifelse
		} bind def
	}

	{
	/BEGINBITMAPCOLOR {
		BITMAPGRAY} def
	/BEGINBITMAPCOLORc {
		BITMAPGRAYc} def
	/BEGINBITMAPTRUECOLOR {
		BITMAPTRUEGRAY } def
	/BEGINBITMAPTRUECOLORc {
		BITMAPTRUEGRAYc } def
	/FMsetgray {setgray} bind def
	/K {
		pop
		} def
	}
ifelse
/normalize {
	transform round exch round exch itransform
	} bind def
/dnormalize {
	dtransform round exch round exch idtransform
	} bind def
/lnormalize {
	0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
	} bind def
/H {
	lnormalize setlinewidth
	} bind def
/Z {
	setlinecap
	} bind def
	/fillvals FMLOCAL
/X {
	fillvals exch get
	dup type /stringtype eq
	{8 1 setpattern}
	{grayness}
	ifelse
	} bind def
/V {
	gsave eofill grestore
	} bind def
/N {
	stroke
	} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
	/n FMLOCAL
/L {
 	/n exch def
	newpath
	normalize
	moveto
	2 1 n {pop normalize lineto} for
	} bind def
/Y {
	L
	closepath
	} bind def
	/x1 FMLOCAL
	/x2 FMLOCAL
	/y1 FMLOCAL
	/y2 FMLOCAL
	/rad FMLOCAL
/R {
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	x1 y1
	x2 y1
	x2 y2
	x1 y2
	4 Y
	} bind def
/RR {
	/rad exch def
	normalize
	/y2 exch def
	/x2 exch def
	normalize
	/y1 exch def
	/x1 exch def
	newpath
	x1 y1 rad add moveto
	x1 y2 x2 y2 rad arcto
	x2 y2 x2 y1 rad arcto
	x2 y1 x1 y1 rad arcto
	x1 y1 x1 y2 rad arcto
	closepath
	16 {pop} repeat
	} bind def
/C {
	grestore
	gsave
	R
	clip
	} bind def
	/FMpointsize FMLOCAL
/F {
	FMfonts exch get
	FMpointsize scalefont
	setfont
	} bind def
/Q {
	/FMpointsize exch def
	F
	} bind def
/T {
	moveto show
	} bind def
/RF {
	rotate
	0 ne {-1 1 scale} if
	} bind def
/TF {
	gsave
	moveto
	RF
	show
	grestore
	} bind def
/P {
	moveto
	0 32 3 2 roll widthshow
	} bind def
/PF {
	gsave
	moveto
	RF
	0 32 3 2 roll widthshow
	grestore
	} bind def
/S {
	moveto
	0 exch ashow
	} bind def
/SF {
	gsave
	moveto
	RF
	0 exch ashow
	grestore
	} bind def
/B {
	moveto
	0 32 4 2 roll 0 exch awidthshow
	} bind def
/BF {
	gsave
	moveto
	RF
	0 32 4 2 roll 0 exch awidthshow
	grestore
	} bind def
/G {
	gsave
	newpath
	normalize translate 0.0 0.0 moveto
	dnormalize scale
	0.0 0.0 1.0 5 3 roll arc
	closepath fill
	grestore
	} bind def
/A {
	gsave
	savematrix
	newpath
	2 index 2 div add exch 3 index 2 div sub exch
	normalize 2 index 2 div sub exch 3 index 2 div add exch
	translate
	scale
	0.0 0.0 1.0 5 3 roll arc
	restorematrix
	stroke
	grestore
	} bind def
	/x FMLOCAL
	/y FMLOCAL
	/w FMLOCAL
	/h FMLOCAL
	/xx FMLOCAL
	/yy FMLOCAL
	/ww FMLOCAL
	/hh FMLOCAL
	/FMsaveobject FMLOCAL
	/FMoptop FMLOCAL
	/FMdicttop FMLOCAL
/BEGINPRINTCODE {
	/FMdicttop countdictstack 1 add def
	/FMoptop count 4 sub def
	/FMsaveobject save def
	userdict begin
	/showpage {} def
	FMNORMALIZEGRAPHICS
	3 index neg 3 index neg translate
	} bind def
/ENDPRINTCODE {
	count -1 FMoptop {pop pop} for
	countdictstack -1 FMdicttop {pop end} for
	FMsaveobject restore
	} bind def
/gn {
	0
	{	46 mul
		cf read pop
		32 sub
		dup 46 lt {exit} if
		46 sub add
		} loop
	add
	} bind def
	/str FMLOCAL
/cfs {
	/str sl string def
	0 1 sl 1 sub {str exch val put} for
	str def
	} bind def
/ic [
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0
	{0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
	{10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
	{19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
	{13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}
	{4 wh} {5 wh} {6 wh} {7 wh} {8 wh} {9 wh} {10 wh} {11 wh} {12 wh}
	{13 wh} {14 wh} {gn wh} {0 bl} {1 bl} {2 bl} {3 bl} {4 bl} {5 bl} {6 bl}
	{7 bl} {8 bl} {9 bl} {10 bl} {11 bl} {12 bl} {13 bl} {14 bl} {gn bl}
	{0 fl} {1 fl} {2 fl} {3 fl} {4 fl} {5 fl} {6 fl} {7 fl} {8 fl} {9 fl}
	{10 fl} {11 fl} {12 fl} {13 fl} {14 fl} {gn fl}
	] def
	/sl FMLOCAL
	/val FMLOCAL
	/ws FMLOCAL
	/im FMLOCAL
	/bs FMLOCAL
	/cs FMLOCAL
	/len FMLOCAL
	/pos FMLOCAL
/ms {
	/sl exch def
	/val 255 def
	/ws cfs
	/im cfs
	/val 0 def
	/bs cfs
	/cs cfs
	} bind def
400 ms
/ip {
	is
	0
	cf cs readline pop
	{	ic exch get exec
		add
		} forall
	pop

	} bind def
/wh {
	/len exch def
	/pos exch def
	ws 0 len getinterval im pos len getinterval copy pop
	pos len
	} bind def
/bl {
	/len exch def
	/pos exch def
	bs 0 len getinterval im pos len getinterval copy pop
	pos len
	} bind def
/s1 1 string def
/fl {
	/len exch def
	/pos exch def
	/val cf s1 readhexstring pop 0 get def
	pos 1 pos len add 1 sub {im exch val put} for
	pos len
	} bind def
/hx {
	3 copy getinterval
	cf exch readhexstring pop pop
	} bind def
	/h FMLOCAL
	/w FMLOCAL
	/d FMLOCAL
	/lb FMLOCAL
	/bitmapsave FMLOCAL
	/is FMLOCAL
	/cf FMLOCAL
/wbytes {
	dup
	8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
	} bind def
/BEGINBITMAPBWc {
	1 {} COMMONBITMAPc
	} bind def
/BEGINBITMAPGRAYc {
	8 {} COMMONBITMAPc
	} bind def
/BEGINBITMAP2BITc {
	2 {} COMMONBITMAPc
	} bind def
/COMMONBITMAPc {
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def
	sl lb lt {lb ms} if
	/bitmapsave save def
	r
	/is im 0 lb getinterval def
	ws 0 lb getinterval is copy pop
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{ip} image
	bitmapsave restore
	grestore
	} bind def
/BEGINBITMAPBW {
	1 {} COMMONBITMAP
	} bind def
/BEGINBITMAPGRAY {
	8 {} COMMONBITMAP
	} bind def
/BEGINBITMAP2BIT {
	2 {} COMMONBITMAP
	} bind def
/COMMONBITMAP {
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	r
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{cf is readhexstring pop} image
	bitmapsave restore
	grestore
	} bind def
	/proc1 FMLOCAL
	/proc2 FMLOCAL
	/newproc FMLOCAL
/Fmcc {
    /proc2 exch cvlit def
    /proc1 exch cvlit def
    /newproc proc1 length proc2 length add array def
    newproc 0 proc1 putinterval
    newproc proc1 length proc2 putinterval
    newproc cvx
} bind def
/ngrayt 256 array def
/nredt 256 array def
/nbluet 256 array def
/ngreent 256 array def
	/gryt FMLOCAL
	/blut FMLOCAL
	/grnt FMLOCAL
	/redt FMLOCAL
	/indx FMLOCAL
	/cynu FMLOCAL
	/magu FMLOCAL
	/yelu FMLOCAL
	/k FMLOCAL
	/u FMLOCAL
/colorsetup {
	currentcolortransfer
	/gryt exch def
	/blut exch def
	/grnt exch def
	/redt exch def
	0 1 255 {
		/indx exch def
		/cynu 1 red indx get 255 div sub def
		/magu 1 green indx get 255 div sub def
		/yelu 1 blue indx get 255 div sub def
		/k cynu magu min yelu min def
		/u k currentundercolorremoval exec def
		nredt indx 1 0 cynu u sub max sub redt exec put
		ngreent indx 1 0 magu u sub max sub grnt exec put
		nbluet indx 1 0 yelu u sub max sub blut exec put
		ngrayt indx 1 k currentblackgeneration exec sub gryt exec put
	} for
	{255 mul cvi nredt exch get}
	{255 mul cvi ngreent exch get}
	{255 mul cvi nbluet exch get}
	{255 mul cvi ngrayt exch get}
	setcolortransfer
	{pop 0} setundercolorremoval
	{} setblackgeneration
	} bind def
	/tran FMLOCAL
/fakecolorsetup {
	/tran 256 string def
	0 1 255 {/indx exch def
		tran indx
		red indx get 77 mul
		green indx get 151 mul
		blue indx get 28 mul
		add add 256 idiv put} for
	currenttransfer
	{255 mul cvi tran exch get 255.0 div}
	exch Fmcc settransfer
} bind def
/BITMAPCOLOR {
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	colorsetup
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{cf is readhexstring pop} {is} {is} true 3 colorimage
	bitmapsave restore
	grestore
	} bind def
/BITMAPCOLORc {
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def
	sl lb lt {lb ms} if
	/bitmapsave save def
	colorsetup
	/is im 0 lb getinterval def
	ws 0 lb getinterval is copy pop
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{ip} {is} {is} true 3 colorimage
	bitmapsave restore
	grestore
	} bind def
/BITMAPTRUECOLORc {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def

        /is w string def

        ws 0 w getinterval is copy pop
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        {ip} {gip} {bip} true 3 colorimage
        bitmapsave restore
        grestore
        } bind def
/BITMAPTRUECOLOR {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        { cf is readhexstring pop }
        { cf gis readhexstring pop }
        { cf bis readhexstring pop }
        true 3 colorimage
        bitmapsave restore
        grestore
        } bind def
/BITMAPTRUEGRAYc {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def

        /is w string def

        ws 0 w getinterval is copy pop
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        {ip gip bip w gray} image
        bitmapsave restore
        grestore
        } bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray {
        /ww exch def
        /b exch def
        /g exch def
        /r exch def
        0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
			b i get .114 mul add add r i 3 -1 roll floor cvi put } for
        r
        } bind def
/BITMAPTRUEGRAY {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        { cf is readhexstring pop
          cf gis readhexstring pop
          cf bis readhexstring pop w gray}  image
        bitmapsave restore
        grestore
        } bind def
/BITMAPGRAY {
	8 {fakecolorsetup} COMMONBITMAP
	} bind def
/BITMAPGRAYc {
	8 {fakecolorsetup} COMMONBITMAPc
	} bind def
/ENDBITMAP {
	} bind def
end
	/ALDsave FMLOCAL
	/ALDmatrix matrix def ALDmatrix currentmatrix pop
/StartALD {
	/ALDsave save def
	 savematrix
	 ALDmatrix setmatrix
	} bind def
/InALD {
	 restorematrix
	} bind def
/DoneALD {
	 ALDsave restore
	} bind def
%%EndProlog
%%BeginSetup
(3.0) FMVERSION
1 1 612 792 0 1 13 FMDOCUMENT
0 0 /Helvetica-Bold FMFONTDEFINE
1 0 /Times-Bold FMFONTDEFINE
2 0 /Times-Italic FMFONTDEFINE
3 0 /Times-Roman FMFONTDEFINE
4 0 /Helvetica FMFONTDEFINE
5 0 /Courier FMFONTDEFINE
6 0 /Courier-Oblique FMFONTDEFINE
32 FMFILLS
0 0 FMFILL
1 0.1 FMFILL
2 0.3 FMFILL
3 0.5 FMFILL
4 0.7 FMFILL
5 0.9 FMFILL
6 0.97 FMFILL
7 1 FMFILL
8 <0f1e3c78f0e1c387> FMFILL
9 <0f87c3e1f0783c1e> FMFILL
10 <cccccccccccccccc> FMFILL
11 <ffff0000ffff0000> FMFILL
12 <8142241818244281> FMFILL
13 <03060c183060c081> FMFILL
14 <8040201008040201> FMFILL
16 1 FMFILL
17 0.9 FMFILL
18 0.7 FMFILL
19 0.5 FMFILL
20 0.3 FMFILL
21 0.1 FMFILL
22 0.03 FMFILL
23 0 FMFILL
24 <f0e1c3870f1e3c78> FMFILL
25 <f0783c1e0f87c3e1> FMFILL
26 <3333333333333333> FMFILL
27 <0000ffff0000ffff> FMFILL
28 <7ebddbe7e7dbbd7e> FMFILL
29 <fcf9f3e7cf9f3f7e> FMFILL
30 <7fbfdfeff7fbfdfe> FMFILL
%%EndSetup
%%Page: "1" 1
%%BeginPaperSize: Letter
%%EndPaperSize
612 792 0 FMBEGINPAGE
98.1 675 512.1 675 2 L
7 X
0 K
V
2 H
0 Z
0 X
N
98.1 450 512.1 450 2 L
7 X
V
2 Z
0 X
N
98.1 108 512.1 126 R
7 X
V
0 10 Q
0 X
(1) 506.54 119.33 T
1 24 Q
-0.48 (Tk4.0 Overview and Porting Guide) 152.1 605 S
2 12 Q
(John Ouster) 152.1 563 T
(hout) 210.84 563 T
98.1 135 512.1 423 R
7 X
V
3 10 Q
0 X
(Tk version 4.0 is a major new release with many improvements, new features, and bug) 152.1 416.33 T
(\336xes. This document provides an introduction to the new features and describes the most) 152.1 404.33 T
-0.18 (common problems you are likely to encounter when porting scripts from Tk 3.6, the previ-) 152.1 392.33 P
(ous release. This is) 152.1 380.33 T
2 F
(not) 230.66 380.33 T
3 F
( an introduction to Tk: I assume that you are already familiar with) 243.43 380.33 T
(Tk 3.6 as described in the book) 152.1 368.33 T
2 F
(T) 279.79 368.33 T
(cl and the Tk T) 284.43 368.33 T
(oolkit) 343.48 368.33 T
3 F
(.) 366.24 368.33 T
-0.26 (The good news about Tk 4.0 is that it has many improvements over Tk 3.6. Here are a) 170.1 356.33 P
(few of the most important new features:) 152.1 344.33 T
3 12 Q
(\245) 152.1 329.33 T
3 10 Q
(Tk 4.0 includes a general-purpose mechanism for manipulating color images \050Tk 3.6) 162.9 329.33 T
(supports only monochrome images\051.) 162.9 317.33 T
3 12 Q
(\245) 152.1 302.33 T
3 10 Q
-0.17 (The text widget in Tk 4.0 includes many new features such as tab stops, embedded win-) 162.9 302.33 P
(dows, horizontal scrolling, and many new formatting options.) 162.9 290.33 T
3 12 Q
(\245) 152.1 275.33 T
3 10 Q
(The binding mechanism in Tk 4.0 is much more powerful in Tk 3.6.) 162.9 275.33 T
3 12 Q
(\245) 152.1 260.33 T
3 10 Q
(Motif compliance is much better) 162.9 260.33 T
(. For example, there is now support for keyboard tra-) 292.82 260.33 T
(versal and focus highlights.) 162.9 248.33 T
3 12 Q
(\245) 152.1 233.33 T
3 10 Q
(Many widgets have been improved. For example, buttons and labels can display multi-) 162.9 233.33 T
(line justi\336ed text, and scales can handle real values.) 162.9 221.33 T
(The bad news about Tk 4.0 is that it contains several incompatibilities with Tk 3.6.) 170.1 206.33 T
(Ever since the \336rst release of Tk I have assumed that there would eventually be a major) 152.1 194.33 T
(new release of Tk with substantial incompatibilities. I knew that I wouldn\325) 152.1 182.33 T
(t be able to get) 450.06 182.33 T
(all of the features of Tk right the \336rst time; rather than live forever with all of my early) 152.1 170.33 T
(mistakes, I wanted to have a chance to correct them. Tk 4.0 is that correction. I apologize) 152.1 158.33 T
-0.05 (for the incompatibilities, but I hope they improve Tk enough to justify the dif) 152.1 146.33 P
-0.05 (\336culties you) 460.55 146.33 P
44.1 351 98.1 423 C
35.1 360 197.1 414 R
7 X
0 K
V
1 9 Q
0 X
(FIGURE  1) 35.1 408 T
(T) 35.1 387 T
(ABLE  1) 40.43 387 T
26.1 351 125.1 423 R
7 X
V
40.5 63 571.5 729 C
FMENDPAGE
%%EndPage: "1" 2
%%Page: "2" 2
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(2) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
(encounter during porting. Tk 4.0 is a one-time correction: we will try very hard to avoid) 152.1 632.33 T
(substantial incompatibilities \050especially in Tk\325) 152.1 620.3 T
(s T) 337 620.3 T
(cl-level interfaces\051 in future releases.) 348.79 620.3 T
-0.4 (Sections 1-1) 170.1 608.3 P
-0.4 (1 cover the major areas of change in Tk 4.0: bindings, focus, text widgets,) 219.02 608.3 P
-0 (Motif compliance, other widget changes, images, color management, event handling, sup-) 152.1 596.26 P
(port for multiple displays, the) 152.1 584.23 T
5 F
(send) 273.14 584.23 T
3 F
( command, and the selection. Section 12 summarizes) 297.13 584.23 T
(several smaller changes. Section 13 lists all of the incompatibilities that af) 152.1 572.19 T
(fect T) 448.4 572.19 T
(cl scripts,) 471.29 572.19 T
-0.02 (along with suggestions for how to deal with them. The explanations here are not intended) 152.1 560.16 P
(to be comprehensive, but rather to introduce you to the issues; for complete information) 152.1 548.12 T
(on new or modi\336ed commands, refer to the reference documentation that comes with the) 152.1 536.09 T
(distribution.) 152.1 524.05 T
98.1 480.7 512.1 483.72 C
152.1 481.92 512.1 481.92 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 482.21 143.1 482.21 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(1) 134.63 487.72 T
(Bindings) 152.1 487.72 T
3 10 Q
-0.35 (The changes for Tk 4.0 that are most likely to af) 152.1 464.03 P
-0.35 (fect existing T) 341.31 464.03 P
-0.35 (cl scripts are those related to) 397.64 464.03 P
(bindings. The new binding mechanism in Tk 4.0 is much more powerful than that of Tk) 152.1 452 T
(3.6, particularly in the way it allows behaviors to be combined, but several incompatible) 152.1 439.96 T
(changes were required to implement the new features. These changes are likely to break) 152.1 427.93 T
(most Tk 3.6 scripts. Fortunately) 152.1 415.89 T
(, it is relatively easy to upgrade your bindings to work) 279.16 415.89 T
(under Tk 4.0.) 152.1 403.86 T
-0.27 (The basic mechanism for bindings is the same as in Tk 3.6. A binding associates a T) 170.1 391.86 P
-0.27 (cl) 502.65 391.86 P
(script with a particular event \050or sequence of events\051 occurring in one or more windows;) 152.1 379.82 T
-0.11 (the script will be invoked automatically whenever the event sequence occurs in any of the) 152.1 367.79 P
-0.13 (speci\336ed windows. The Tk 4.0 binding mechanism has three major feature changes. First,) 152.1 355.75 P
(there is a more general mechanism for specifying the relationship between windows and) 152.1 343.72 T
(bindings, called) 152.1 331.68 T
2 F
(binding tags) 217.89 331.68 T
3 F
(. Second, the con\337ict resolution mechanism \050which is) 267.6 331.68 T
(invoked when more than one binding matches an event\051 has been changed to allow more) 152.1 319.65 T
(than one binding script to execute for a single event. Third, the) 152.1 307.61 T
5 F
(Any) 405.81 307.61 T
3 F
( modi\336er is now) 423.8 307.61 T
(implicit in all binding patterns. These changes are discussed separately in the subsections) 152.1 295.58 T
(that follow) 152.1 283.54 T
(.) 195.04 283.54 T
-0.16 (Overall, the main ef) 170.1 271.54 P
-0.16 (fect of Tk 4.0\325) 249.37 271.54 P
-0.16 (s binding changes is that it allows more bindings to) 306.06 271.54 P
(trigger than Tk 3.6 does. Feedback from the T) 152.1 259.51 T
(cl/Tk community about the Tk 3.6 binding) 335.71 259.51 T
(mechanism indicated that it was too conservative about triggering bindings. This caused) 152.1 247.47 T
(the system to lose behaviors relatively easily and made the binding structure fragile. It) 152.1 235.44 T
-0.35 (appears to be easier to deal with too many binding invocations than too few) 152.1 223.4 P
-0.35 (, so Tk 4.0 tries) 449.17 223.4 P
(to err in this direction.) 152.1 211.37 T
0 F
(1.1) 127.41 181.37 T
(Binding tags) 152.1 181.37 T
3 F
(In Tk 3.6 you specify the window\050s\051 for a binding in one of three ways:) 152.1 165.37 T
3 12 Q
(\245) 152.1 150.37 T
3 10 Q
(Y) 162.9 150.37 T
(ou give the name of a window) 169.12 150.37 T
(, such as) 289.49 150.37 T
5 F
(.a.b.c) 326.13 150.37 T
3 F
(, in which case the binding applies) 362.11 150.37 T
(only to that window) 162.9 138.33 T
(.) 242.49 138.33 T
FMENDPAGE
%%EndPage: "2" 3
%%Page: "3" 3
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(1 Bindings) 98.1 668.33 T
0 F
(3) 506.54 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 12 Q
0 X
(\245) 152.1 632.33 T
3 10 Q
-0.06 (Y) 162.9 632.33 P
-0.06 (ou give the name of a class, such as) 169.12 632.33 P
5 F
-0.15 (Button) 313.45 632.33 P
3 F
-0.06 (, in which case the binding applies to all) 349.43 632.33 P
(the windows of that class.) 162.9 620.33 T
3 12 Q
(\245) 152.1 605.33 T
3 10 Q
(Y) 162.9 605.33 T
(ou specify) 169.12 605.33 T
5 F
(all) 212.97 605.33 T
3 F
(, in which case the binding applies to all windows.) 230.96 605.33 T
-0.3 (In Tk4.0 you specify the window\050s\051 using a more general mechanism called a) 170.1 590.33 P
2 F
-0.3 (binding) 479.35 590.33 P
(tag) 152.1 578.33 T
3 F
(. A binding tag may be an arbitrary string, but if it starts with a \322.\323 then it must be the) 164.87 578.33 T
(name of a window) 152.1 566.33 T
(. If you specify a class name or) 225.56 566.33 T
5 F
(all) 352.4 566.33 T
3 F
( as a binding tag, it will usually) 370.39 566.33 T
-0.1 (have the same ef) 152.1 554.33 P
-0.1 (fect as in Tk 3.6, but you may also specify other strings that were not per-) 218.51 554.33 P
(mitted in Tk 3.6.) 152.1 542.33 T
-0.07 (Each window in Tk 4.0 has a list of binding tags. When an event occurs in a window) 170.1 530.33 P
-0.07 (,) 507.17 530.33 P
-0.19 (Tk fetches the window\325) 152.1 518.33 P
-0.19 (s binding tags and matches the event against all of the bindings for) 245.62 518.33 P
-0.09 (any of the tags. By default, the binding tags for a window consist of the window name, its) 152.1 506.33 P
-0.14 (class name, the name of its nearest toplevel ancestor) 152.1 494.33 P
-0.14 (, and) 359.61 494.33 P
5 F
-0.33 (all) 381.26 494.33 P
3 F
-0.14 (. For example, a button win-) 399.25 494.33 P
(dow named) 152.1 482.33 T
5 F
(.b) 200.95 482.33 T
3 F
( will have the tags) 212.95 482.33 T
5 9 Q
(.b Button . all) 179.1 468 T
3 10 Q
(by default and all of the following bindings will apply to the window:) 152.1 454.33 T
5 9 Q
(bind .b <Enter> {identify "press here to exit"}) 179.1 440 T
(bind Button <Button-Release-1> {%W invoke}) 179.1 430 T
(bind all <Help> {help %W}) 179.1 420 T
3 10 Q
(So far) 152.1 406.33 T
(, this mechanism produces the same behavior as in Tk 3.6 except that bindings cre-) 175.85 406.33 T
(ated for a toplevel also apply to its descendants \050see Section 1.5 for more on this issue\051.) 152.1 394.33 T
(Y) 170.1 382.33 T
(ou can use the) 176.32 382.33 T
5 F
(bindtags) 235.71 382.33 T
3 F
( command to change the binding tags for a window or) 283.69 382.33 T
(their order) 152.1 370.33 T
(. For example, the command) 193.46 370.33 T
5 9 Q
(bindtags .b {.b MyButton all}) 179.1 356 T
3 10 Q
(will change the binding tags for) 152.1 342.33 T
5 F
(.b) 281.46 342.33 T
3 F
( to the three values in the list. This provides a simple) 293.45 342.33 T
(way to make radical changes the behavior of a window) 152.1 330.33 T
(. After the above command is) 371.55 330.33 T
(invoked none of the) 152.1 318.33 T
5 F
(Button) 234.26 318.33 T
3 F
( class bindings will apply to) 270.24 318.33 T
5 F
(.b) 384.63 318.33 T
3 F
(. Instead, bindings for) 396.63 318.33 T
5 F
-0.81 (MyButton) 152.1 306.33 P
3 F
-0.34 ( will apply; this might give the button a totally dif) 200.07 306.33 P
-0.34 (ferent set of behaviors than a) 395.88 306.33 P
(normal button. In addition, the) 152.1 294.33 T
5 F
(bindtags) 276.75 294.33 T
3 F
( command removes the \322.\323 tag, so bindings on) 324.72 294.33 T
(\322.\323 will not apply to) 152.1 282.33 T
5 F
(.b) 234.27 282.33 T
3 F
(.) 246.27 282.33 T
(Y) 170.1 270.33 T
(ou can also place additional tags on a window with the) 176.32 270.33 T
5 F
(bindtags) 397.55 270.33 T
3 F
( command to) 445.53 270.33 T
(combine a number of behaviors. For example,) 152.1 258.33 T
5 9 Q
(bindtags .b {.b MyButton Button . all}) 179.1 244 T
3 10 Q
(gives) 152.1 230.33 T
5 F
(.b) 175.7 230.33 T
3 F
( the behaviors of) 187.69 230.33 T
5 F
(MyButton) 257.08 230.33 T
3 F
( bindings as well as those speci\336ed by) 305.06 230.33 T
5 F
(Button) 459.96 230.33 T
3 F
(bindings.) 152.1 218.33 T
(Overall, binding tags are similar to the tag mechanisms already used internally by) 170.1 206.33 T
(canvas and text widgets in Tk 3.6, except that binding tags apply to windows instead of) 152.1 194.33 T
(graphical objects or textual characters.) 152.1 182.33 T
FMENDPAGE
%%EndPage: "3" 4
%%Page: "4" 4
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(4) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
0 F
0 X
(1.2) 127.41 632.33 T
(Con\337ict resolution) 152.1 632.33 T
3 F
(It is possible for several bindings to match a particular event. In Tk 3.6 at most one event) 152.1 616.33 T
(is actually allowed to trigger: a set of con\337ict resolution rules determines the winner) 152.1 604.22 T
(. In) 488.27 604.22 T
(general, a more speci\336c binding takes precedence over a less speci\336c binding. For exam-) 152.1 592.11 T
-0.27 (ple, any binding for a speci\336c widget takes precedence over any class or) 152.1 580 P
5 F
-0.66 (all) 439.96 580 P
3 F
-0.27 ( binding, and) 457.95 580 P
(a binding on) 152.1 567.89 T
5 F
(<Control-a>) 204.57 567.89 T
3 F
( takes precedence over a binding on) 270.54 567.89 T
5 F
(<Key>.) 416.24 567.89 T
3 F
-0.26 (The mechanism for con\337ict resolution is similar in Tk 4.0 except that one binding can) 170.1 555.89 P
-0.35 (trigger for) 152.1 543.78 P
2 F
-0.35 (each) 194.7 543.78 P
3 F
-0.35 ( binding tag on the window where the event occurs. The bindings trigger in) 213.57 543.78 P
(the order of the tags. Thus if button) 152.1 531.67 T
5 F
(.b) 296.17 531.67 T
3 F
( has the default binding tags, one binding for) 308.16 531.67 T
5 F
(.b) 489.71 531.67 T
3 F
(can trigger) 152.1 519.56 T
(, followed by one for) 194.72 519.56 T
5 F
(Button) 281.32 519.56 T
3 F
(, followed by one for \322) 317.3 519.56 T
5 F
(.) 408.34 519.56 T
3 F
(\323, followed by one for) 414.34 519.56 T
5 F
(all) 152.1 507.44 T
3 F
(. If there are no matching bindings for a given tag then none will trigger) 170.09 507.44 T
(, and if there) 456.98 507.44 T
(are several matching bindings for a given tag then a single one is chosen using the same) 152.1 495.33 T
(rules as in Tk 3.6.) 152.1 483.22 T
(The philosophy behind binding tags in Tk 4.0 is that each binding tag corresponds to) 170.1 471.22 T
(an independent behavior) 152.1 459.11 T
(, so bindings with dif) 249.96 459.11 T
(ferent tags should usually be additive. Sup-) 334.46 459.11 T
(pose you de\336ned the following binding:) 152.1 447 T
5 9 Q
(bind .b <Enter> {puts "press here to exit"}) 179.1 432.67 T
3 10 Q
(This binding will add to the behavior de\336ned by the Button class binding for) 152.1 419 T
5 F
(<Enter>) 460.81 419 T
3 F
(.) 502.79 419 T
(In Tk 3.6, the widget-speci\336c binding will replace the class binding, which will break the) 152.1 406.89 T
(behavior of the button so that it no longer has normal button behavior) 152.1 394.78 T
(.) 429.71 394.78 T
(Sometimes there need to be interactions between binding tags. For example, you) 170.1 382.78 T
(might wish to keep most of the default button behavior for) 152.1 370.67 T
5 F
(.b) 388.34 370.67 T
3 F
( but replace the default) 400.33 370.67 T
(behavior for) 152.1 358.56 T
5 F
(<ButtonRelease>) 203.72 358.56 T
3 F
( with some other behavior) 293.67 358.56 T
(. T) 397.49 358.56 T
(o allow bindings to be) 407.9 358.56 T
-0.17 (overridden, Tk 4.0 allows the) 152.1 346.44 P
5 F
-0.41 (break) 271.44 346.44 P
3 F
-0.17 ( command to be invoked from inside a binding. This) 301.43 346.44 P
(causes all remaining binding tags for that binding to be skipped. Consider the following) 152.1 334.33 T
(binding:) 152.1 322.22 T
5 9 Q
(bind .b <ButtonRelease-1> {myRelease .b; break}) 179.1 307.89 T
3 10 Q
-0.21 (This will cause the) 152.1 294.22 P
5 F
-0.5 (myRelease) 228.99 294.22 P
3 F
-0.21 ( procedure to be invoked, then the) 282.96 294.22 P
5 F
-0.5 (break) 420.28 294.22 P
3 F
-0.21 ( command will) 450.26 294.22 P
-0.37 (cause the class binding for the event to be skipped \050assuming that the widget name appears) 152.1 282.11 P
(before its class in the binding tags for) 152.1 270 T
5 F
(.b) 304.78 270 T
3 F
(\051, along with any bindings for other tags.) 316.77 270 T
2 F
(Note:) 119.09 254 T
-0.07 (Y) 152.1 254 P
-0.07 (ou cannot invoke) 156.74 254 P
6 F
-0.17 (break) 227.31 254 P
2 F
-0.07 ( fr) 257.29 254 P
-0.07 (om within the) 266.02 254 P
6 F
-0.17 (myRelease) 322.73 254 P
2 F
-0.07 ( pr) 376.7 254 P
-0.07 (ocedur) 387.64 254 P
-0.07 (e in the above example:) 415.03 254 P
-0.02 (this will generate a T) 152.1 242.89 P
-0.02 (cl err) 236.05 242.89 P
-0.02 (or) 257.59 242.89 P
-0.02 (. However) 265.37 242.89 P
-0.02 (, you can invoke the command \322) 305.31 242.89 P
6 F
-0.05 (return -code) 434.25 242.89 P
(break) 152.1 231.78 T
2 F
(\323 in the pr) 182.08 231.78 T
(ocedur) 223.64 231.78 T
(e to achieve the same effect as the) 251.03 231.78 T
6 F
(break) 389.25 231.78 T
2 F
( in the binding script.) 419.23 231.78 T
0 F
(1.3) 127.41 202.78 T
(Implicit Any) 152.1 202.78 T
3 F
-0.13 (In Tk 3.6 extraneous modi\336ers prevent a binding from matching an event. For example, if) 152.1 186.78 P
(a binding is de\336ned for) 152.1 174.67 T
5 F
(<Button-1>) 247.32 174.67 T
3 F
( and the mouse button is pressed with the) 307.29 174.67 T
5 F
(Num-) 474.68 174.67 T
(Lock) 152.1 162.56 T
3 F
( key down, then the binding will not match. If you want a binding to trigger even) 176.09 162.56 T
(when extraneous modi\336ers are present, you must specify the) 152.1 150.45 T
5 F
(Any) 396.37 150.45 T
3 F
( modi\336er) 414.36 150.45 T
(, as in) 450.33 150.45 T
5 F
(<Any-) 476.42 150.45 T
(Button-1>) 152.1 138.33 T
3 F
(.) 206.07 138.33 T
FMENDPAGE
%%EndPage: "4" 5
%%Page: "5" 5
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(1 Bindings) 98.1 668.33 T
0 F
(5) 506.54 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
-0.06 (In Tk 4.0, all bindings have the) 170.1 632.33 P
5 F
-0.15 (Any) 297.08 632.33 P
3 F
-0.06 ( modi\336er present implicitly) 315.08 632.33 P
-0.06 (. The) 423.35 632.33 P
5 F
-0.15 (Any) 446.26 632.33 P
3 F
-0.06 ( modi\336er is) 464.25 632.33 P
(still allowed for compatibility) 152.1 620.33 T
(, but it has no meaning. Thus a binding for) 270.55 620.33 T
5 F
(<Button-1>) 443.23 620.33 T
3 F
(will match a button press event even if) 152.1 608.33 T
5 F
(NumLock) 309.21 608.33 T
3 F
(,) 351.19 608.33 T
5 F
(Shift) 356.19 608.33 T
3 F
(,) 386.17 608.33 T
5 F
(Control) 391.17 608.33 T
3 F
(, or any combina-) 433.15 608.33 T
(tion of them. If you wish for a binding not to trigger when a modi\336er is present, you can) 152.1 596.33 T
(just de\336ne an empty binding for that modi\336er combination. For example,) 152.1 584.33 T
5 9 Q
(bind .b <Control-Button-1> {# this script is a no-op}) 179.1 570 T
3 10 Q
(creates a binding that will trigger on mouse button presses when the) 152.1 556.33 T
5 F
(Control) 426.36 556.33 T
3 F
( key is) 468.34 556.33 T
-0.22 (down. If there is also a) 152.1 544.33 P
5 F
-0.52 (<Button-1>) 244.35 544.33 P
3 F
-0.22 ( binding for) 334.3 544.33 P
5 F
-0.52 (.b) 383.35 544.33 P
3 F
-0.22 (, it will no longer be invoked) 395.34 544.33 P
-0.02 (if the) 152.1 532.33 P
5 F
-0.05 (Control) 175.37 532.33 P
3 F
-0.02 ( key is down, due to the con\337ict resolution rules. The script for the above) 217.35 532.33 P
(binding is just a T) 152.1 520.33 T
(cl comment, so it has no ef) 223.59 520.33 T
(fect when it is invoked. Alternatively) 330.84 520.33 T
(, you) 478.98 520.33 T
(could use) 152.1 508.33 T
5 F
(%s) 192.63 508.33 T
3 F
( in the binding script to extract the modi\336er state, then test to see that only) 204.62 508.33 T
(desired modi\336ers are present.) 152.1 496.33 T
0 F
(1.4) 127.41 466.33 T
(Porting problems: widget bindings vs. class bindings) 152.1 466.33 T
3 F
-0.38 (Y) 152.1 450.33 P
-0.38 (ou are likely to encounter two problems with bindings when you port Tk 3.6 scripts to Tk) 158.32 450.33 P
-0.18 (4.0: widget bindings vs. class bindings, and events on top-level windows. This section dis-) 152.1 438.33 P
(cusses the \336rst problem and the following section discusses the second problem.) 152.1 426.33 T
(In Tk 3.6, if a widget-speci\336c binding matches an event then no class binding will) 170.1 414.33 T
-0.15 (trigger for the event; in Tk 4.0 both bindings will trigger) 152.1 402.33 P
-0.15 (. Because of this change, you will) 375.75 402.33 P
-0.09 (need to modify most of your widget-speci\336c bindings in one of two ways. If a widget-spe-) 152.1 390.33 P
(ci\336c binding in Tk 3.6 was intended to supplement the class binding, this could only be) 152.1 378.33 T
(done by duplicating the code of the class binding in the widget binding script. This dupli-) 152.1 366.33 T
-0.02 (cated code is no longer necessary in Tk 4.0 and will probably interfere with the new class) 152.1 354.33 P
(bindings in Tk 4.0; you should remove the duplicated class code, leaving only the widget-) 152.1 342.33 T
(speci\336c code in the binding script. If a widget-speci\336c binding in Tk 3.6 was intended to) 152.1 330.33 T
-0.17 (override the class binding, this will no longer occur by default in Tk 4.0; you should add a) 152.1 318.33 P
5 F
-0.54 (break) 152.1 306.33 P
3 F
-0.22 ( command at the end of the binding script to prevent the class binding from trigger-) 182.08 306.33 P
(ing. If a widget binding in Tk 3.6 didn\325) 152.1 294.33 T
(t con\337ict with a class binding, then you will not) 308.49 294.33 T
(need to modify it for Tk 4.0. For example, a widget binding for) 152.1 282.33 T
5 F
(<Help>) 407.49 282.33 T
3 F
( in a text widget) 443.47 282.33 T
(would not need to be modi\336ed, since it doesn\325) 152.1 270.33 T
(t con\337ict with a class binding.) 336.53 270.33 T
0 F
(1.5) 127.41 240.33 T
(Porting problems: events on top-levels) 152.1 240.33 T
3 F
-0.26 (The second binding problem you are likely to encounter in porting Tk 3.6 scripts to Tk 4.0) 152.1 224.33 P
(is that in Tk 4.0 a binding on a toplevel will match events on any of the internal windows) 152.1 212.33 T
(within that top-level. For example, suppose you have a binding created as follows:) 152.1 200.33 T
5 9 Q
(toplevel .t) 179.1 186 T
(button .t.b1 ...) 179.1 176 T
(button .t.b2 ...) 179.1 166 T
(bind .t <Enter> action) 179.1 156 T
FMENDPAGE
%%EndPage: "5" 6
%%Page: "6" 6
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(6) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
-0.27 (This binding will trigger not only when the mouse enters) 152.1 632.33 P
5 F
-0.64 (.t) 379.29 632.33 P
3 F
-0.27 (, but also when it enters either) 391.28 632.33 P
5 F
(.t.b1) 152.1 620.33 T
3 F
( or) 182.08 620.33 T
5 F
(.t.b2) 195.41 620.33 T
3 F
(. This is because the binding tags for a window include its nearest) 225.39 620.33 T
(ancestor toplevel by default. The toplevel is present in the binding tags to make it easy to) 152.1 608.33 T
(set up accelerator keys that apply in all the windows of a panel. For example,) 152.1 596.33 T
5 9 Q
(bind .t <Control-a> {controlAProc %W}) 179.1 582 T
3 10 Q
(will cause) 152.1 568.33 T
5 F
(controlAProc) 194.85 568.33 T
3 F
( to be invoked whenever) 266.81 568.33 T
5 F
(Control-a) 367.56 568.33 T
3 F
( is typed in any of the) 421.53 568.33 T
-0.12 (windows in) 152.1 556.33 P
5 F
-0.29 (.t) 200.72 556.33 P
3 F
-0.12 (. The procedure will receive the name of the focus window as its ar) 212.71 556.33 P
-0.12 (gument.) 479.62 556.33 P
(Unfortunately) 170.1 544.33 T
(, if you have created bindings on toplevel windows in your Tk 3.6) 225.52 544.33 T
-0.16 (scripts, they probably expect to trigger only for events in the toplevel, so the bindings will) 152.1 532.33 P
(misbehave under Tk 4.0. Fortunately you can reproduce the behavior of Tk 3.6 by using) 152.1 520.33 T
(the) 152.1 508.33 T
5 F
(%W) 166.81 508.33 T
3 F
( substitution in the binding script. For example, to ensure that) 178.8 508.33 T
5 F
(action) 427.28 508.33 T
3 F
( is invoked) 463.26 508.33 T
(only for) 152.1 496.33 T
5 F
(Enter) 186.52 496.33 T
3 F
( events in a toplevel window itself, create the following binding in place) 216.51 496.33 T
(of the one above:) 152.1 484.33 T
5 9 Q
(bind .t <Enter> {) 179.1 470 T
(if {"%W" == ".t"} {) 200.63 460 T
(action) 222.23 450 T
(}) 200.63 440 T
(}) 179.1 430 T
3 10 Q
-0.01 (When an) 152.1 416.33 P
5 F
-0.03 (Enter) 190.38 416.33 P
3 F
-0.01 ( event occurs in a descendant of) 220.36 416.33 P
5 F
-0.03 (.t) 350.45 416.33 P
3 F
-0.01 ( such as) 362.45 416.33 P
5 F
-0.03 (.t.x) 396.56 416.33 P
3 F
-0.01 (, a binding for) 420.54 416.33 P
5 F
-0.03 (Enter) 479.63 416.33 P
3 F
(in) 152.1 404.33 T
5 F
(.t.x) 162.37 404.33 T
3 F
( will trigger \336rst, if there is one. Then the above binding will trigger) 186.36 404.33 T
(. Since) 457.58 404.33 T
5 F
(%W) 487.29 404.33 T
3 F
(will be substituted with) 152.1 392.33 T
5 F
(.t.x) 248.17 392.33 T
3 F
(, the) 272.15 392.33 T
5 F
(if) 291.86 392.33 T
3 F
( condition will not be satis\336ed and the binding will) 303.86 392.33 T
(not do anything.) 152.1 380.33 T
-0.14 ( An alternative solution is to remove the toplevel window from the binding tags of all) 170.1 368.33 P
-0.12 (its internal windows. However) 152.1 356.33 P
-0.12 (, this means that you won\325) 274.03 356.33 P
-0.12 (t be able to take advantage of the) 378.73 356.33 P
(tag to create key bindings that apply everywhere within the toplevel.) 152.1 344.33 T
0 F
(1.6) 127.41 314.33 T
(Internal bindings in canvases and texts) 152.1 314.33 T
3 F
(The same changes in con\337ict resolution described in Section 1.2 also apply to bindings) 152.1 298.33 T
-0.05 (created internally for the items of a canvas or the tags of a text widget. If a canvas item or) 152.1 286.33 P
-0.29 (character of text has multiple tags, then one binding can trigger for each tag on each event.) 152.1 274.33 P
-0.32 (The bindings trigger in the priority order of the tags. Similar porting problems are likely to) 152.1 262.33 P
-0.19 (occur as described in Section 1.4; if a binding for one tag needs to override that of another) 152.1 250.33 P
(tag, you\325ll need to add a) 152.1 238.33 T
5 F
(break) 251.2 238.33 T
3 F
( command under Tk 4.0; if a binding for one tag dupli-) 281.18 238.33 T
-0.28 (cated the code from another tag\325) 152.1 226.33 P
-0.28 (s binding, so that they will compose in Tk 3.6, you\325ll have) 279.76 226.33 P
(to remove the duplicated code in Tk 4.0.) 152.1 214.33 T
FMENDPAGE
%%EndPage: "6" 7
%%Page: "7" 7
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(2 Focus management) 98.1 668.33 T
0 F
(7) 506.54 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
98.1 623.98 512.1 627 C
152.1 625.2 512.1 625.2 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 625.49 143.1 625.49 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(2) 134.63 631 T
(Focus management) 152.1 631 T
3 10 Q
(The input focus is another area where Tk 4.0 contains major changes. Fortunately) 152.1 607.31 T
(, the) 477.87 607.31 T
-0.09 (focus changes should not require as many modi\336cations to your Tk 3.6 scripts as the bind-) 152.1 595.31 P
(ing changes.) 152.1 583.31 T
0 F
(2.1) 127.41 553.31 T
(One focus window per toplevel) 152.1 553.31 T
3 F
(Tk 3.6 only keeps track of a single focus window for each application, and this results in) 152.1 537.31 T
(two problems. First, it doesn\325) 152.1 525.31 T
(t allow an application to use multiple displays since this) 269.64 525.31 T
-0.16 (could result in multiple simultaneous focus windows, one on each display) 152.1 513.31 P
-0.16 (. Second, the Tk) 444.99 513.31 P
(3.6 model doesn\325) 152.1 501.31 T
(t work very well for applications that have multiple toplevels: when the) 221.04 501.31 T
(mouse moves from one toplevel to another) 152.1 489.31 T
(, the focus window should switch to whatever) 322.7 489.31 T
-0.24 (window had the focus the last time the mouse was in the new toplevel, but Tk 3.6 does not) 152.1 477.31 P
(remember this information.) 152.1 465.31 T
(Tk 4.0 corrects both of these problems. It remembers one focus window for each) 170.1 453.31 T
(toplevel, which can be queried with the) 152.1 441.31 T
5 F
(focus -lastfor) 311.98 441.31 T
3 F
( command. When the win-) 395.94 441.31 T
(dow manager gives the focus to a toplevel window \050because the mouse entered the win-) 152.1 429.31 T
(dow or because you clicked on the window) 152.1 417.31 T
(, depending on the focus model being used by) 324.38 417.31 T
(the window manager\051, Tk passes the focus on to the remembered window) 152.1 405.31 T
(. Several win-) 446.23 405.31 T
(dows in an application can have the focus at the same time, one on each display the appli-) 152.1 393.31 T
(cation is using. When asking for the current focus window in the) 152.1 381.31 T
5 F
(focus) 413.31 381.31 T
3 F
( command, you) 443.29 381.31 T
(can use the) 152.1 369.31 T
5 F
(-displayof) 199 369.31 T
3 F
( switch to specify a particular display) 258.97 369.31 T
(.) 407.66 369.31 T
(When you set the focus to a window with the) 170.1 357.31 T
5 F
(focus) 353.31 357.31 T
3 F
( command, Tk remembers that) 383.29 357.31 T
(window as the most recent focus window for its toplevel. In addition, if the application) 152.1 345.31 T
(currently has the focus for the window\325) 152.1 333.31 T
(s display) 309.2 333.31 T
(, Tk moves the focus to the speci\336ed win-) 343.82 333.31 T
-0.35 (dow; this can be used, for example to move the focus to a dialog when the dialog is posted,) 152.1 321.31 P
(or to perform keyboard traversal among the toplevels of an application. If the application) 152.1 309.31 T
(doesn\325) 152.1 297.31 T
(t currently have the focus for the display) 178.57 297.31 T
(, then Tk will not normally take the focus) 339.74 297.31 T
(from its current owner) 152.1 285.31 T
(. However) 241.2 285.31 T
(, you can specify the) 282.43 285.31 T
5 F
(-force) 367.36 285.31 T
3 F
( ar) 403.34 285.31 T
(gument to) 413.43 285.31 T
5 F
(focus) 456.18 285.31 T
3 F
( to) 486.17 285.31 T
(insist that Tk grab the focus for this application \050in general this is probably not a good) 152.1 273.31 T
(idea, since it may clash with the window manager) 152.1 261.31 T
(\325) 352.05 261.31 T
(s focus policy\051.) 354.83 261.31 T
0 F
(2.2) 127.41 231.31 T
(Keyboard traversal) 152.1 231.31 T
3 F
-0.38 (Tk 4.0 has a much more complete implementation of keyboard traversal than Tk 3.6. In Tk) 152.1 215.31 P
(3.6 there is built-in support only for keyboard traversal of menus. In Tk 4.0 keyboard tra-) 152.1 203.31 T
(versal is implemented for all widgets. Y) 152.1 191.31 T
(ou can type) 311.27 191.31 T
5 F
(Tab) 359.85 191.31 T
3 F
( to move the focus among the) 377.84 191.31 T
-0.4 (windows within a toplevel and) 152.1 179.31 P
5 F
-0.95 (Shift+Tab) 275.31 179.31 P
3 F
-0.4 ( to move in the reverse direction. The order of) 329.28 179.31 P
-0.11 (traversal is de\336ned by the stacking order of widgets, with the lowest widget \336rst in the tra-) 152.1 167.31 P
(versal order) 152.1 155.31 T
(. All Tk widgets now provide a) 199 155.31 T
5 F
(-takefocus) 326.14 155.31 T
3 F
( option, which determines) 386.11 155.31 T
FMENDPAGE
%%EndPage: "7" 8
%%Page: "8" 8
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(8) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
(whether the window should accept the focus during traversal or be skipped. This option) 152.1 632.33 T
(has several features; see the) 152.1 620.33 T
5 F
(options.n) 265.61 620.33 T
3 F
( manual entry for details.) 319.58 620.33 T
(All of the Tk widgets provide a traversal highlight ring as required by Motif. The) 170.1 608.33 T
(highlight ring turns dark when the widget has the input focus. Its size and colors are con-) 152.1 596.33 T
(trolled by the) 152.1 584.33 T
5 F
(-highlightthickness) 207.9 584.33 T
3 F
(,) 321.84 584.33 T
5 F
(-highlightbackground) 326.83 584.33 T
3 F
(, and) 446.77 584.33 T
5 F
(-) 152.1 572.33 T
(highlightcolor) 158.1 572.33 T
3 F
( options. Y) 242.05 572.33 T
(ou may notice that widgets appear to have extra space) 285.2 572.33 T
(around them in Tk 4.0; this is due to the traversal highlight ring, which is normally the) 152.1 560.33 T
(same color as the background for widgets.) 152.1 548.33 T
0 F
(2.3) 127.41 518.33 T
(Support for focus-follows-mouse) 152.1 518.33 T
3 F
(Both Tk 3.6 and Tk 4.0 use an) 152.1 502.33 T
2 F
(explicit focus model) 275.91 502.33 T
3 F
( within a toplevel. This means that) 355.86 502.33 T
(moving the mouse among the windows of a toplevel does not normally move the focus;) 152.1 490.33 T
-0.06 (you have to click or perform some other action \050such as pressing) 152.1 478.33 P
5 F
-0.15 (Tab) 412.26 478.33 P
3 F
-0.06 (\051 to move the focus.) 430.25 478.33 P
(Tk 3.6 has no support for an) 152.1 466.33 T
2 F
(implicit focus model) 267.58 466.33 T
3 F
( where the window under the mouse) 348.64 466.33 T
(always has the focus. In Tk 4.0 you can invoke the library procedure) 152.1 454.33 T
5 F
(tk_focusFol-) 428.83 454.33 T
(lowsMouse) 152.1 442.33 T
3 F
( to switch to an implicit focus model; in this mode whenever the mouse) 206.07 442.33 T
(enters a new window the focus will switch to that window) 152.1 430.33 T
(.) 384.07 430.33 T
0 F
(2.4) 127.41 400.33 T
(No default focus window) 152.1 400.33 T
(, no \322none\323 focus.) 269.45 400.33 T
3 F
-0.16 (Tk 3.6 has the notion of a default focus window) 152.1 384.33 P
-0.16 (, which receives the focus if the focus win-) 341.56 384.33 P
(dow is deleted. It is also possible for an application to abandon the input focus by setting) 152.1 372.33 T
(the focus to) 152.1 360.33 T
5 F
(none) 201.23 360.33 T
3 F
(. In Tk 4.0 both of these features have been eliminated. There is no) 225.22 360.33 T
(default focus window) 152.1 348.33 T
(, and the focus can never be explicitly abandoned. If the focus win-) 238.05 348.33 T
(dow is destroyed, Tk resets the input focus to the toplevel containing the old focus win-) 152.1 336.33 T
(dow) 152.1 324.33 T
(. If the toplevel is destroyed, the window manager will reclaim the focus and move it) 168.66 324.33 T
(elsewhere.) 152.1 312.33 T
-0.18 (If you really want to abandon the focus in Tk 4.0 so that keyboard events are ignored,) 170.1 300.33 P
(you can create a dummy window with no key bindings \050set its binding tags to an empty) 152.1 288.33 T
(string to be sure\051, make sure that is never mapped, and give it the input focus.) 152.1 276.33 T
0 F
(2.5) 127.41 246.33 T
(Better focus events) 152.1 246.33 T
3 F
-0.13 (Tk 3.6 has a quirky event model for) 152.1 230.33 P
5 F
-0.32 (FocusIn) 296.77 230.33 P
3 F
-0.13 ( and) 338.75 230.33 P
5 F
-0.32 (FocusOut) 357.92 230.33 P
3 F
-0.13 ( events: when the window) 405.89 230.33 P
-0.23 (manager gives the focus to a toplevel, Tk generates a) 152.1 218.33 P
5 F
-0.55 (FocusIn) 364.36 218.33 P
3 F
-0.23 ( event for the toplevel and) 406.33 218.33 P
(another) 152.1 206.33 T
5 F
(FocusIn) 184.57 206.33 T
3 F
( event for the focus window) 226.55 206.33 T
(, but no events for any other windows.) 337.76 206.33 T
(When the window manager moves the focus somewhere else,) 152.1 194.33 T
5 F
(FocusOut) 400.79 194.33 T
3 F
( events are gen-) 448.77 194.33 T
-0 (erated for these same two windows. In Tk 4.0,) 152.1 182.33 P
5 F
-0 (FocusIn) 339.73 182.33 P
3 F
-0 ( and) 381.71 182.33 P
5 F
-0 (FocusOut) 401.13 182.33 P
3 F
-0 ( events are gen-) 449.11 182.33 P
-0.26 (erated in the same way as) 152.1 170.33 P
5 F
-0.63 (Enter) 255.43 170.33 P
3 F
-0.26 ( and) 285.41 170.33 P
5 F
-0.63 (Leave) 304.31 170.33 P
3 F
-0.26 ( events: when the focus arrives, a) 334.29 170.33 P
5 F
-0.63 (FocusIn) 467.89 170.33 P
3 F
-0.05 (event is generated for each window from the toplevel down to the focus window) 152.1 158.33 P
-0.05 (, with dif-) 472.5 158.33 P
FMENDPAGE
%%EndPage: "8" 9
%%Page: "9" 9
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(3 T) 98.1 668.33 T
(ext widgets) 111.43 668.33 T
0 F
(9) 506.54 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
-0.33 (ferent detail \336elds for dif) 152.1 632.33 P
-0.33 (ferent windows \050see Xlib documentation for information on these) 250.53 632.33 P
(values\051. The reverse happens when the focus leaves a window) 152.1 620.33 T
(.) 399.57 620.33 T
0 F
(2.6) 127.41 590.33 T
(Porting issues) 152.1 590.33 T
3 F
(If you didn\325) 152.1 574.33 T
(t have any special focus-related code in Tk 3.6, then you shouldn\325) 199.66 574.33 T
(t need to) 462.9 574.33 T
(make any changes for 4.0; things will just work better) 152.1 562.33 T
(. If you wrote code in Tk 3.6 to get) 366.96 562.33 T
(around the weaknesses with its focus mechanism, then you should remove most or all of) 152.1 550.33 T
(that code. For example, if you implemented keyboard traversal yourself, or if you built) 152.1 538.33 T
(your own mechanism to remember a separate focus window for each toplevel and give it) 152.1 526.33 T
(the input focus whenever the toplevel gets the focus, you can simply remove this code,) 152.1 514.33 T
-0.33 (since Tk 4.0 performs these functions for you. If you wrote code that depends on the weird) 152.1 502.33 P
-0.03 (event model in Tk 3.6, that code will need to be rewritten for Tk 4.0. The Tk 4.0 model is) 152.1 490.33 P
(general enough to duplicate any ef) 152.1 478.33 T
(fects that were possible in Tk 3.6.) 289.86 478.33 T
98.1 434.98 512.1 438 C
152.1 436.2 512.1 436.2 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 436.49 143.1 436.49 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(3) 134.63 442 T
(T) 152.1 442 T
(ext widgets) 158.54 442 T
3 10 Q
(T) 152.1 418.31 T
(ext widgets have under) 157.51 418.31 T
(gone a major overhaul for Tk 4.0 and they have improved in) 249.76 418.31 T
(many ways. The changes to text widgets are almost entirely upward-compatible from Tk) 152.1 406.31 T
(3.6.) 152.1 394.31 T
0 F
(3.1) 127.41 364.31 T
(Embedded windows.) 152.1 364.31 T
3 F
(Tk 3.6 supported two kinds of annotations in texts: marks and tags. In Tk 4.0 a third kind) 152.1 348.31 T
-0.04 (of annotation is available: an embedded window) 152.1 336.31 P
-0.04 (. This allows you to embed other widgets) 344.99 336.31 P
(inside a text widget, mixed in with the text. The text widget acts as a geometry manager) 152.1 324.31 T
(for these windows, laying them out and wrapping them just as if each embedded window) 152.1 312.31 T
(were a single character in the text. Y) 152.1 300.31 T
(ou can even have texts with nothing in them but) 297.64 300.31 T
(embedded windows. The) 152.1 288.31 T
5 F
(window) 254.8 288.31 T
3 F
( widget command for text widgets provides several) 290.78 288.31 T
(options to manage embedded windows.) 152.1 276.31 T
0 F
(3.2) 127.41 246.31 T
(More options for tags.) 152.1 246.31 T
3 F
(In Tk 4.0 tags support many new options providing additional control over how informa-) 152.1 230.31 T
(tion is displayed. Here is a summary of the new options:) 152.1 218.31 T
3 12 Q
(\245) 152.1 203.31 T
3 10 Q
(Y) 162.9 203.31 T
(ou can now specify tab stops with the) 169.12 203.31 T
5 F
(-tabs) 321.79 203.31 T
3 F
( option. Each tab stop can use left, cen-) 351.78 203.31 T
(ter) 162.9 191.31 T
(, right, or numeric justi\336cation. T) 173.04 191.31 T
(ab stops can also be speci\336ed for the widget as a) 305.6 191.31 T
(whole.) 162.9 179.31 T
3 12 Q
(\245) 152.1 164.31 T
3 10 Q
(Y) 162.9 164.31 T
(ou can specify justi\336cation \050left, center or right\051 with the) 169.12 164.31 T
5 F
(-justify) 398.12 164.31 T
3 F
( option.) 446.09 164.31 T
FMENDPAGE
%%EndPage: "9" 10
%%Page: "10" 10
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(10) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 12 Q
0 X
(\245) 152.1 632.33 T
3 10 Q
(Y) 162.9 632.33 T
(ou can now specify line spacing with three options,) 169.12 632.33 T
5 F
(-spacing1) 376.75 632.33 T
3 F
(,) 430.72 632.33 T
5 F
(-spacing2) 435.72 632.33 T
3 F
(, and) 489.69 632.33 T
5 F
(-) 162.9 620.2 T
(spacing3) 168.9 620.2 T
3 F
(, which control the spacing above a line, between wrapped lines, and) 216.87 620.2 T
(below a line.) 162.9 608.06 T
3 12 Q
(\245) 152.1 593.06 T
3 10 Q
(Y) 162.9 593.06 T
(ou can now specify mar) 169.12 593.06 T
(gins with the) 264.41 593.06 T
5 F
(-lmargin1) 318.55 593.06 T
3 F
(,) 372.52 593.06 T
5 F
(-lmargin2) 377.52 593.06 T
3 F
(, and) 431.49 593.06 T
5 F
(-rmargin) 453.42 593.06 T
3 F
(options.) 162.9 580.92 T
3 12 Q
(\245) 152.1 565.92 T
3 10 Q
-0.25 (Y) 162.9 565.92 P
-0.25 (ou can now adjust the vertical position of text \050e.g. for superscripts or subscripts\051 with) 169.12 565.92 P
(the) 162.9 553.79 T
5 F
(-offset) 177.61 553.79 T
3 F
( option.) 219.59 553.79 T
3 12 Q
(\245) 152.1 538.79 T
3 10 Q
-0.03 (Y) 162.9 538.79 P
-0.03 (ou can now specify the wrapping style \050word wrapping, character wrapping, or none\051) 169.12 538.79 P
(with the) 162.9 526.65 T
5 F
(-wrap) 197.88 526.65 T
3 F
( option.) 227.86 526.65 T
3 12 Q
(\245) 152.1 511.65 T
3 10 Q
(Y) 162.9 511.65 T
(ou can now request overstriking with the) 169.12 511.65 T
5 F
(-overstrike) 334.83 511.65 T
3 F
( option.) 400.8 511.65 T
0 F
(3.3) 127.41 481.65 T
(Bindings) 152.1 481.65 T
3 F
-0.19 (The default bindings for text widgets have been completely rewritten in Tk 4.0. They now) 152.1 465.65 P
(support almost all of the Motif behavior \050everything except add mode and secondary) 152.1 453.52 T
-0.36 (selections\051. They also include a substantial subset of the Emacs bindings for cursor motion) 152.1 441.38 P
(and basic editing. The) 152.1 429.24 T
5 F
(tk_strictMotif) 242.87 429.24 T
3 F
( variable disables the Emacs bindings.) 326.82 429.24 T
0 F
(3.4) 127.41 399.24 T
(Miscellaneous new features) 152.1 399.24 T
3 F
(In addition to the major changes described above, text widgets also include the following) 152.1 383.24 T
(new features:) 152.1 371.11 T
1 F
(Horizontal scr) 162.9 356.11 T
(olling) 224.07 356.11 T
3 F
(. T) 247.95 356.11 T
(ext widgets can now be scrolled horizontally as well as verti-) 258.36 356.11 T
(cally) 162.9 343.97 T
(, using the) 181.68 343.97 T
5 F
(-) 225.55 343.97 T
(xscrollcommand) 231.54 343.97 T
3 F
( option and the) 315.5 343.97 T
5 F
(xview) 377.68 343.97 T
3 F
( widget command.) 407.67 343.97 T
1 F
(Sear) 162.9 328.97 T
(ching) 182.15 328.97 T
3 F
(. T) 205.48 328.97 T
(ext widgets have a new) 215.88 328.97 T
5 F
(search) 311.64 328.97 T
3 F
( widget command, which provides ef) 347.62 328.97 T
(\336-) 495.67 328.97 T
-0.19 (cient searching of text widgets using either exact matching, glob-style matching, or reg-) 162.9 316.83 P
(ular expressions. Y) 162.9 304.7 T
(ou can search forwards or backwards.) 238.79 304.7 T
1 F
(Mark gravity) 162.9 289.7 T
3 F
(. In Tk 3.6 marks always had \322right gravity\323, which means they stick to) 219.71 289.7 T
(the character on the right side of the mark; if you insert at the position of a mark, the) 162.9 277.56 T
-0.1 (new character goes before the mark. In Tk 4.0 you can specify whether marks have left) 162.9 265.42 P
(or right gravity) 162.9 253.29 T
(.) 222.77 253.29 T
1 F
(Scr) 162.9 238.29 T
(een information) 177.15 238.29 T
3 F
(. In Tk 4.0 there are two new widget commands for text widgets) 245.16 238.29 T
(that return information about the screen layout. The) 162.9 226.15 T
5 F
(dlineinfo) 371.92 226.15 T
3 F
( widget command) 425.89 226.15 T
(returns the bounding box of a display line \050all the information displayed on one line of) 162.9 214.02 T
(the window) 162.9 201.88 T
(, which may be either a whole line of text or a partial line if wrapping has) 209.16 201.88 T
(occurred\051. The) 162.9 189.74 T
5 F
(bbox) 224.23 189.74 T
3 F
( widget command returns the screen area occupied by a single) 248.21 189.74 T
(character) 162.9 177.61 T
(.) 198.97 177.61 T
1 F
(Extended insert command) 162.9 162.61 T
3 F
(. The) 275.06 162.61 T
5 F
(insert) 298.1 162.61 T
3 F
( widget command now supports an addi-) 334.08 162.61 T
-0.32 (tional ar) 162.9 150.47 P
-0.32 (gument giving a list of tags to apply to the new characters. Y) 195.43 150.47 P
-0.32 (ou can also include) 434 150.47 P
(several text and tag ar) 162.9 138.33 T
(guments in a single) 250.42 138.33 T
5 F
(insert) 330.38 138.33 T
3 F
( command.) 366.36 138.33 T
FMENDPAGE
%%EndPage: "10" 11
%%Page: "11" 11
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(4 Better Motif compliance) 98.1 668.33 T
0 F
(1) 501.54 668.33 T
(1) 506.54 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
1 F
0 X
(See command) 162.9 632.33 T
3 F
(. There is a new) 222.03 632.33 T
5 F
(see) 288.08 632.33 T
3 F
( widget command, which adjusts the view in the) 306.07 632.33 T
(widget if needed to ensure that a particular character is visible in the window) 162.9 620.29 T
(.) 470.07 620.29 T
0 F
(3.5) 127.41 590.29 T
(Porting issues: tag stickiness, change in end) 152.1 590.29 T
3 F
(There are two changes in text widgets that may require modi\336cations to Tk 3.6 scripts.) 152.1 574.29 T
-0.06 (The \336rst change has to do with tag stickiness. In Tk 3.6, tags are sticky to the right: if you) 152.1 562.24 P
(insert new text just after a tagged range, the new text acquires the tags of the preceding) 152.1 550.19 T
(character) 152.1 538.14 T
(. If you insert text before a tagged range in Tk 3.6, the new characters do not) 188.17 538.14 T
-0.34 (acquire the tags of the range. In Tk 4.0, tags are not sticky on either side: new text acquires) 152.1 526.09 P
(a tag from surrounding characters only if the tag is present on both sides of the insertion) 152.1 514.05 T
(position. The sticky behavior in Tk 3.6 was rarely useful and special code was often) 152.1 502 T
(needed to work around it. Y) 152.1 489.95 T
(ou should be able to eliminate this code in Tk 4.0.) 263.24 489.95 T
(The second incompatible change in text widgets is that the index) 170.1 477.95 T
5 F
(end) 431.32 477.95 T
3 F
( now refers to) 449.31 477.95 T
-0.14 (the position just after the \336nal newline in the text, whereas in Tk 3.6 it referred to the posi-) 152.1 465.9 P
-0.1 (tion just before the \336nal newline. This makes it possible to apply tags to the \336nal newline,) 152.1 453.86 P
(which was not possible in Tk 3.6, but you may need to modify your scripts if you depend) 152.1 441.81 T
(on the old position of) 152.1 429.76 T
5 F
(end) 240.11 429.76 T
3 F
(.) 258.1 429.76 T
98.1 386.4 512.1 389.43 C
152.1 387.63 512.1 387.63 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 387.92 143.1 387.92 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(4) 134.63 393.43 T
(Better Motif compliance) 152.1 393.43 T
3 10 Q
(All of the widgets have been modi\336ed in Tk 4.0 to improve their Motif compliance. This) 152.1 369.74 T
-0.3 (was done by adding features that were missing and reworking the bindings to comply with) 152.1 357.69 P
(Motif conventions. I believe that the widgets are now completely Motif compliant except) 152.1 345.64 T
(for the following missing features:) 152.1 333.6 T
3 12 Q
(\245) 152.1 318.6 T
3 10 Q
(There is no support for secondary selections.) 162.9 318.6 T
3 12 Q
(\245) 152.1 303.6 T
3 10 Q
(There is no support for \322add mode\323 in widgets such as texts and listboxes.) 162.9 303.6 T
3 12 Q
(\245) 152.1 288.6 T
3 10 Q
(There is no support for drag and drop.) 162.9 288.6 T
-0.02 (Please let me know if you \336nd any other discrepancies between the Tk widgets and Motif) 152.1 273.59 P
(widgets. W) 152.1 261.55 T
(e plan to eliminate the remaining incompatibilities over the next year or two.) 196.82 261.55 T
98.1 218.19 512.1 221.21 C
152.1 219.41 512.1 219.41 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 219.7 143.1 219.7 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(5) 134.63 225.21 T
(W) 152.1 225.21 T
(idget changes) 163.31 225.21 T
3 10 Q
-0.07 (All of the Tk 4.0 widgets have been improved over their 3.6 counterparts, mostly in small) 152.1 201.52 P
-0.23 (and backwards compatible ways. Here is a summary of the widget improvements; see Sec-) 152.1 189.48 P
(tion 13 for information about incompatible changes.) 152.1 177.43 T
3 12 Q
(\245) 152.1 162.43 T
3 10 Q
(All widgets now have a) 162.9 162.43 T
5 F
(cget) 259.78 162.43 T
3 F
( command, which provides an easier way to retrieve the) 283.76 162.43 T
(value of a con\336guration option. In other situations where con\336guration options are) 162.9 150.38 T
(used, such as for menu entries or text tags, a) 162.9 138.33 T
5 F
(cget) 342.21 138.33 T
3 F
( command is also available.) 366.2 138.33 T
FMENDPAGE
%%EndPage: "11" 12
%%Page: "12" 12
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(12) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 12 Q
0 X
(\245) 152.1 632.33 T
3 10 Q
-0.22 (All widgets now have) 162.9 632.33 P
5 F
-0.53 (-highlightthickness) 251.96 632.33 P
3 F
-0.22 (,) 365.9 632.33 P
5 F
-0.53 (-highlightbackground) 370.68 632.33 P
3 F
-0.22 (, and) 490.61 632.33 P
5 F
(-) 162.9 620.33 T
(highlightcolor) 168.9 620.33 T
3 F
( options for displaying a highlight ring when the widget \050or one) 252.85 620.33 T
(of its descendants\051 has the input focus.) 162.9 608.33 T
3 12 Q
(\245) 152.1 593.33 T
3 10 Q
(Entry widgets now support justi\336cation and provide a) 162.9 593.33 T
5 F
(-show) 379.99 593.33 T
3 F
( option for \050not\051 display-) 409.97 593.33 T
(ing passwords. They will autosize to \336t their text if) 162.9 581.33 T
5 F
(-width 0) 369.17 581.33 T
3 F
( is speci\336ed.) 417.14 581.33 T
3 12 Q
(\245) 152.1 566.33 T
3 10 Q
-0.16 (The label/button family of widgets now supports multiline text and justi\336cation, includ-) 162.9 566.33 P
(ing new options) 162.9 554.33 T
5 F
(-wraplength) 229.25 554.33 T
3 F
( and) 295.22 554.33 T
5 F
(-justify) 314.65 554.33 T
3 F
(.  These features make the message) 361.97 554.33 T
-0.04 (widget obsolete. There is also a new) 162.9 542.33 P
5 F
-0.1 (-underline) 310.27 542.33 P
3 F
-0.04 ( option for highlighting a character) 370.23 542.33 P
(for keyboard traversal.) 162.9 530.33 T
3 12 Q
(\245) 152.1 515.33 T
3 10 Q
-0.23 (Listboxes now support all of the Motif selection modes, including single selection, mul-) 162.9 515.33 P
(tiple selection, and multiple disjoint selections, via the) 162.9 503.33 T
5 F
(-selectmode) 382.78 503.33 T
3 F
( option. They) 448.74 503.33 T
(will autosize to \336t their contents if) 162.9 491.33 T
5 F
(-width 0) 302.54 491.33 T
3 F
( or) 350.52 491.33 T
5 F
(-height 0) 363.84 491.33 T
3 F
( is speci\336ed. There are) 417.81 491.33 T
(new) 162.9 479.33 T
5 F
(see) 182.05 479.33 T
3 F
(,) 200.04 479.33 T
5 F
(bbox) 205.04 479.33 T
3 F
(, and) 229.02 479.33 T
5 F
(activate) 250.95 479.33 T
3 F
( widget commands.) 298.92 479.33 T
3 12 Q
(\245) 152.1 464.33 T
3 10 Q
(Canvas polygons now support) 162.9 464.33 T
5 F
(-outline) 286.16 464.33 T
3 F
( and) 334.14 464.33 T
5 F
(-width) 353.57 464.33 T
3 F
( options for drawing outlines.) 389.55 464.33 T
3 12 Q
(\245) 152.1 449.33 T
3 10 Q
-0.03 (Scale widgets now support real values as well as integers \050see the) 162.9 449.33 P
5 F
-0.08 (-resolution) 426.77 449.33 P
3 F
-0.03 ( and) 492.73 449.33 P
5 F
-0.54 (-digits) 162.9 437.33 P
3 F
-0.22 ( options\051, and they have a) 204.88 437.33 P
5 F
-0.54 (-variable) 308.73 437.33 P
3 F
-0.22 ( option to link to a T) 362.7 437.33 P
-0.22 (cl variable. They) 442.83 437.33 P
-0.28 (have two new widget commands,) 162.9 425.33 P
5 F
-0.67 (coords) 297.52 425.33 P
3 F
-0.28 ( and) 333.5 425.33 P
5 F
-0.67 (identify) 352.37 425.33 P
3 F
-0.28 (, and their bindings are now) 399.69 425.33 P
(de\336ned in T) 162.9 413.33 T
(cl rather than being hardwired in C code as in Tk 3.6.) 210.5 413.33 T
3 12 Q
(\245) 152.1 398.33 T
3 10 Q
(Scrollbar widgets now have a new interface to the controlling widget, which provides) 162.9 398.33 T
-0.04 (more \337exibility than the old style \050but the old style is still supported for compatibility\051.) 162.9 386.33 P
(There is a new option) 162.9 374.33 T
5 F
(-jump) 252 374.33 T
3 F
( to prevent continuous updates while dragging the slider) 281.98 374.33 T
(,) 505.88 374.33 T
-0.24 (and a new option) 162.9 362.33 P
5 F
-0.59 (-elementborderwidth) 232.98 362.33 P
3 F
-0.24 ( to control the border width of the arrows) 346.92 362.33 P
(and slider separately from the widget\325) 162.9 350.33 T
(s outer border) 314.18 350.33 T
(. There are four new widget com-) 369.14 350.33 T
(mands,) 162.9 338.33 T
5 F
(activate) 193.99 338.33 T
3 F
(,) 241.97 338.33 T
5 F
(delta) 246.96 338.33 T
3 F
(,) 276.95 338.33 T
5 F
(fraction) 281.95 338.33 T
3 F
(, and) 329.92 338.33 T
5 F
(identify) 351.85 338.33 T
3 F
(, and the default bindings) 399.17 338.33 T
(are now de\336ned in T) 162.9 326.33 T
(cl rather than being hardwired in C code as in Tk 3.6.) 244.91 326.33 T
3 12 Q
(\245) 152.1 311.33 T
3 10 Q
-0.13 (Menu entries now have several new con\336guration options such as) 162.9 311.33 P
5 F
-0.31 (-foreground) 426.97 311.33 P
3 F
-0.13 ( and) 492.93 311.33 P
5 F
-0.41 (-) 162.9 299.33 P
-0.41 (indicatoron) 168.9 299.33 P
3 F
-0.17 (, and tear) 234.86 299.33 P
-0.17 (-of) 271.23 299.33 P
-0.17 (f menus have been reimplemented to be more Motif-like.) 282.7 299.33 P
(New menu entries can be created in the middle of a menu using the) 162.9 287.33 T
5 F
(insert) 434.36 287.33 T
3 F
( widget) 470.34 287.33 T
(command, and there is a) 162.9 275.33 T
5 F
(type) 262.83 275.33 T
3 F
( widget command that returns the type of a menu entry) 286.81 275.33 T
(.) 505.45 275.33 T
3 12 Q
(\245) 152.1 260.33 T
3 10 Q
(Menubuttons now have a) 162.9 260.33 T
5 F
(-indicatoron) 266.16 260.33 T
3 F
( option for displaying an option menu indi-) 338.12 260.33 T
-0.38 (cator) 162.9 248.33 P
-0.38 (. There is now support for option menus via the) 182.33 248.33 P
5 F
-0.91 (tk_optionMenu) 370.9 248.33 P
3 F
-0.38 ( procedure, and) 448.86 248.33 P
(popups are simpli\336ed with the) 162.9 236.33 T
5 F
(tk_popup) 286.44 236.33 T
3 F
( procedure.) 334.42 236.33 T
3 12 Q
(\245) 152.1 221.33 T
3 10 Q
-0.03 (The variable) 162.9 221.33 P
5 F
-0.07 (tk_strictMotif) 215.57 221.33 P
3 F
-0.03 ( is used in more places to enforce even stricter Motif) 299.53 221.33 P
(compliance.) 162.9 209.33 T
FMENDPAGE
%%EndPage: "12" 13
%%Page: "13" 13
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(6 Images) 98.1 668.33 T
0 F
(13) 500.99 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
98.1 623.98 512.1 627 C
152.1 625.2 512.1 625.2 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 625.49 143.1 625.49 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(6) 134.63 631 T
(Images) 152.1 631 T
3 10 Q
(Tk 4.0 contains a general-purpose image mechanism for displaying color pictures and) 152.1 607.31 T
(other complex objects. There is a new command,) 152.1 595.26 T
5 F
(image) 350.84 595.26 T
3 F
(, which may be used to create) 380.82 595.26 T
(image objects. For example, the command) 152.1 583.21 T
5 9 Q
(image create photo myFace -f) 179.1 568.88 T
(ile picture.ppm) 330.09 568.88 T
3 10 Q
(creates a new image named) 152.1 555.21 T
5 F
(myFace) 264.5 555.21 T
3 F
(. The image is of type) 300.48 555.21 T
5 F
(photo) 390.14 555.21 T
3 F
( \050a full-color represen-) 420.12 555.21 T
(tation that dithers on monochrome or color) 152.1 543.17 T
(-mapped displays\051 and the source data for the) 323.46 543.17 T
(image is in the \336le named) 152.1 531.12 T
5 F
(picture.ppm) 257.59 531.12 T
3 F
(. Once an image has been created, it can be) 323.56 531.12 T
-0.15 (used in many dif) 152.1 519.07 P
-0.15 (ferent places by specifying a) 218.37 519.07 P
5 F
-0.36 (-image) 334.46 519.07 P
3 F
-0.15 ( option. For example, the command) 370.44 519.07 P
5 9 Q
(label .l -image myFace) 179.1 504.74 T
3 10 Q
(will create a label widget that displays the image, and if) 152.1 491.07 T
5 F
(.c) 377.5 491.07 T
3 F
( is a canvas widget the com-) 389.49 491.07 T
(mand) 152.1 479.02 T
5 9 Q
(.c create image 400 200 -image myFace) 179.1 464.69 T
3 10 Q
(will create an image item in the canvas that displays) 152.1 451.02 T
5 F
(myFace) 363.06 451.02 T
3 F
(.) 399.04 451.02 T
(The image mechanism provides a great deal of \337exibility:) 170.1 439.02 T
3 12 Q
(\245) 152.1 424.02 T
3 10 Q
-0.18 (Once an image has been de\336ned, it can be used in many dif) 162.9 424.02 P
-0.18 (ferent places, even on dif) 397.84 424.02 P
-0.18 (fer-) 497.68 424.02 P
(ent displays.) 162.9 411.98 T
3 12 Q
(\245) 152.1 396.98 T
3 10 Q
(Images provide image commands, analogous to widget commands, that can be used to) 162.9 396.98 T
(manipulate the image; any changes in an image are automatically re\337ected in all of its) 162.9 384.93 T
(instances.) 162.9 372.88 T
3 12 Q
(\245) 152.1 357.88 T
3 10 Q
-0.21 (There can be many dif) 162.9 357.88 P
-0.21 (ferent types of images. Tk 4.0 has two built-in types,) 251.78 357.88 P
5 F
-0.51 (photo) 463.11 357.88 P
3 F
-0.21 ( and) 493.1 357.88 P
5 F
(bitmap) 162.9 345.83 T
3 F
(. Other image types can be de\336ned in C as extensions \050see the documentation) 198.88 345.83 T
-0.16 (for the) 162.9 333.79 P
5 F
-0.39 (Tk_CreateImageType) 191.44 333.79 P
3 F
-0.16 ( library procedure\051. The photo image type was imple-) 299.38 333.79 P
(mented by Paul Mackerras, based on his earlier photo widget.) 162.9 321.74 T
3 12 Q
(\245) 152.1 306.74 T
3 10 Q
(W) 162.9 306.74 T
(ithin the photo image type, there can be many dif) 171.93 306.74 T
(ferent \336le formats. In Tk 4.0, only) 368.29 306.74 T
-0.11 (PPM, PGM, and GIF formats are built-in, but other formats can be added as extensions) 162.9 294.69 P
(\050see the documentation for the) 162.9 282.64 T
5 F
(Tk_CreatePhotoImageFormat) 286.97 282.64 T
3 F
( library proce-) 436.89 282.64 T
(dure\051. Readers for XPM, TIFF) 162.9 270.59 T
(, and others are available from the T) 284.23 270.59 T
(cl community) 428.41 270.59 T
(.) 483.01 270.59 T
98.1 227.24 512.1 230.26 C
152.1 228.46 512.1 228.46 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 228.75 143.1 228.75 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(7) 134.63 234.26 T
(Color management) 152.1 234.26 T
3 10 Q
(Tk 3.6 suf) 152.1 210.57 T
(fers from a relatively weak mechanism for managing colors. It uses only the) 192.73 210.57 T
(default colormap for a screen, and if all the entries in that colormap \336ll up then Tk) 152.1 198.52 T
(switches to monochrome mode and \322rounds\323 all future colors to black or white. This) 152.1 186.48 T
(approach is becoming increasingly unpleasant because of applications such as Frame and) 152.1 174.43 T
(W) 152.1 162.38 T
(eb browsers that use up all the entries in the default colormap.) 160.74 162.38 T
(Tk 4.0 has a much more powerful color management mechanism. If a colormap \336lls) 170.1 150.38 T
(up, Tk allocates future colors by picking the closest match from the available colors, so) 152.1 138.33 T
FMENDPAGE
%%EndPage: "13" 14
%%Page: "14" 14
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(14) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
(that it need not revert to monochrome mode. Tk also manages colors better by delaying) 152.1 632.33 T
-0.3 (color allocation until colors are actually needed; in many cases, such as 3D borders, colors) 152.1 620.33 P
(are never needed. When colors are scarce Tk changes the way it displays beveled borders) 152.1 608.33 T
-0.38 (so that it uses stippling instead of additional colors for the light and dark shadows. Y) 152.1 596.33 P
-0.38 (ou can) 484.01 596.33 P
(\336nd out whether a colormap has \336lled up using the new command) 152.1 584.33 T
5 F
(winfo colormap-) 418.59 584.33 T
(full) 152.1 572.33 T
3 F
(.) 176.09 572.33 T
-0.26 (Tk 4.0 also allows you to allocate new colormaps for toplevel and frame widgets with) 170.1 560.33 P
(the) 152.1 548.33 T
5 F
(-colormap) 166.81 548.33 T
3 F
( option, and you change the visual type in these widgets \050with the) 220.78 548.33 T
5 F
(-) 152.1 536.33 T
(visual) 158.1 536.33 T
3 F
( option\051 to take advantage of visuals other than the default visual for a screen.) 194.08 536.33 T
(New commands) 152.1 524.33 T
5 F
(winfo visualsavailable) 219.27 524.33 T
3 F
( and) 351.2 524.33 T
5 F
(wm colormapwindows) 370.63 524.33 T
3 F
( have) 478.57 524.33 T
(been added to help manage colormaps and visuals.) 152.1 512.33 T
(The default color scheme in Tk 4.0 has changed from a tan palette \050\322bisque\323\051 to a) 170.1 500.33 T
(gray palette, which seems to becoming standard for Motif. There is a new T) 152.1 488.33 T
(cl procedure) 454.78 488.33 T
5 F
-0.36 (tk_setPalette) 152.1 476.33 P
3 F
-0.15 ( that changes the palette of an application on the \337y) 230.06 476.33 P
-0.15 (, and there is also a) 433.89 476.33 P
(procedure) 152.1 464.33 T
5 F
(tk_bisque) 194.56 464.33 T
3 F
( to restore the palette to the old bisque colors.) 248.53 464.33 T
(The Tk 3.6 color model mechanism is no longer necessary so it has been removed in) 170.1 452.33 T
(Tk 4.0. If you want to \336nd out whether a screen is monochrome or color) 152.1 440.33 T
(, you cannot use) 440.38 440.33 T
(the) 152.1 428.33 T
5 F
(tk colormodel) 166.81 428.33 T
3 F
( command anymore; use) 244.77 428.33 T
5 F
(winfo depth) 345.25 428.33 T
3 F
( instead.) 411.22 428.33 T
98.1 384.98 512.1 388 C
152.1 386.2 512.1 386.2 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 386.49 143.1 386.49 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(8) 134.63 392 T
(Event handling: \336leevent and after) 152.1 392 T
3 10 Q
(Tk 4.0 contains several improvements in the area of event handling besides those already) 152.1 368.31 T
(mentioned for bindings:) 152.1 356.31 T
3 12 Q
(\245) 152.1 341.31 T
3 10 Q
(There is a new command) 162.9 341.31 T
5 F
(f) 265.87 341.31 T
(ileevent) 271.87 341.31 T
3 F
( for performing event-driven I/O to and from) 319.84 341.31 T
-0.12 (\336les. The) 162.9 329.31 P
5 F
-0.29 (f) 202.35 329.31 P
-0.29 (ileevent) 208.35 329.31 P
3 F
-0.12 ( command is modelled very closely after Mark Diekhans\325) 256.33 329.31 P
5 F
-0.29 (add-) 488.11 329.31 P
(input) 162.9 317.31 T
3 F
( extension, which has been used widely with Tk 3.6.) 192.88 317.31 T
3 12 Q
(\245) 152.1 302.31 T
3 10 Q
-0.34 (The) 162.9 302.31 P
5 F
-0.82 (after) 180.6 302.31 P
3 F
-0.34 ( command has two new options,) 210.58 302.31 P
5 F
-0.82 (idle) 339.82 302.31 P
3 F
-0.34 ( and) 363.81 302.31 P
5 F
-0.82 (cancel) 382.55 302.31 P
3 F
-0.34 (.) 418.53 302.31 P
5 F
-0.82 (After idle) 423.19 302.31 P
3 F
-0.34 ( can be) 482.33 302.31 P
-0.2 (used to schedule a script as an \322idle handler\323, which means it runs the next time that Tk) 162.9 290.31 P
(enters the event loop and \336nds no work to do.) 162.9 278.31 T
5 F
(After cancel) 348.06 278.31 T
3 F
( may be used to delete) 420.02 278.31 T
(a previously-scheduled) 162.9 266.31 T
5 F
(after) 257.83 266.31 T
3 F
( script, so that it will no longer be invoked.) 287.81 266.31 T
98.1 222.95 512.1 225.98 C
152.1 224.18 512.1 224.18 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 224.46 143.1 224.46 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(9) 134.63 229.98 T
(Multiple displays) 152.1 229.98 T
3 10 Q
(Although Tk has always allowed a single application to open windows on several dis-) 152.1 206.29 T
(plays, the support for multiple displays is weak in Tk 3.6. For example, many of the bind-) 152.1 194.29 T
(ings break if users work simultaneously in windows on dif) 152.1 182.29 T
(ferent displays, and) 385.94 182.29 T
(mechanisms like the selection and the input focus have insuf) 152.1 170.29 T
(\336cient support for multiple) 394.26 170.29 T
(displays.) 152.1 158.29 T
FMENDPAGE
%%EndPage: "14" 15
%%Page: "15" 15
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(10 The send command) 98.1 668.33 T
0 F
(15) 500.99 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
-0.33 (Tk 4.0 contains numerous modi\336cations to improve the handling of multiple displays.) 170.1 632.33 P
-0.18 (Several commands, such as) 152.1 620.24 P
5 F
-0.44 (selection) 263.78 620.24 P
3 F
-0.18 (,) 317.76 620.24 P
5 F
-0.44 (send) 322.57 620.24 P
3 F
-0.18 (, and) 346.55 620.24 P
5 F
-0.44 (focus) 368.12 620.24 P
3 F
-0.18 (, have a new) 398.1 620.24 P
5 F
-0.44 (-displayof) 449.82 620.24 P
3 F
(ar) 152.1 608.15 T
(gument so that you can select a particular display) 159.69 608.15 T
(. In addition, the bindings have been) 356.12 608.15 T
(reworked to handle interactions occurring simultaneously on dif) 152.1 596.05 T
(ferent displays. W) 408.13 596.05 T
(ith Tk) 480.73 596.05 T
(4.0 it should be possible to create applications that really use multiple displays gracefully) 152.1 583.96 T
(.) 508.44 583.96 T
98.1 540.6 512.1 543.63 C
152.1 541.83 512.1 541.83 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 542.12 143.1 542.12 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(10) 127.96 547.63 T
(The send command) 152.1 547.63 T
3 10 Q
-0.2 (The) 152.1 523.94 P
5 F
-0.48 (send) 169.94 523.94 P
3 F
-0.2 ( command has been completely overhauled for Tk 4.0 to eliminate several prob-) 193.93 523.94 P
(lems in Tk 3.6 and add a number of new features:) 152.1 511.85 T
3 12 Q
(\245) 152.1 496.85 T
3 10 Q
(Tk 3.6 aborts a) 162.9 496.85 T
5 F
(send) 225.36 496.85 T
3 F
( command if no response is received within 5 seconds; this made) 249.34 496.85 T
(it very dif) 162.9 484.75 T
(\336cult to invoke long-running commands. Tk 4.0 eliminates the timeout  and) 202.14 484.75 T
(uses a dif) 162.9 472.66 T
(ferent mechanism to tell if the tar) 200.47 472.66 T
(get application has crashed.) 333.53 472.66 T
3 12 Q
(\245) 152.1 457.66 T
3 10 Q
-0.36 (The) 162.9 457.66 P
5 F
-0.87 (winfo interps) 180.58 457.66 P
3 F
-0.36 ( command no longer returns the names of applications that have) 257.66 457.66 P
(exited or crashed.) 162.9 445.57 T
3 12 Q
(\245) 152.1 430.57 T
3 10 Q
(Asynchronous sends are possible using the) 162.9 430.57 T
5 F
(-async) 336.67 430.57 T
3 F
( switch.) 372.65 430.57 T
3 12 Q
(\245) 152.1 415.57 T
3 10 Q
(Commands can be sent to displays other than that of the root window) 162.9 415.57 T
(, using the) 439.3 415.57 T
5 F
(-) 162.9 403.47 T
(displayof) 168.9 403.47 T
3 F
( switch.) 222.87 403.47 T
3 12 Q
(\245) 152.1 388.47 T
3 10 Q
(W) 162.9 388.47 T
(indow server security is now checked on each) 171.93 388.47 T
5 F
(send) 357.89 388.47 T
3 F
(, so Tk 4.0 deals better with) 381.88 388.47 T
(changes in the security of the server) 162.9 376.38 T
(.) 306.12 376.38 T
3 12 Q
(\245) 152.1 361.38 T
3 10 Q
(More complete error information \050including the) 162.9 361.38 T
5 F
(errorCode) 356.09 361.38 T
3 F
( and) 410.06 361.38 T
5 F
(errorInfo) 429.49 361.38 T
3 F
( vari-) 483.46 361.38 T
(ables\051 is propagated back to the sender after errors.) 162.9 349.29 T
3 12 Q
(\245) 152.1 334.29 T
3 10 Q
(Y) 162.9 334.29 T
(ou can query and change the name of an application with the) 169.12 334.29 T
5 F
(tk appname) 414.48 334.29 T
3 F
( com-) 474.45 334.29 T
(mand.) 162.9 322.19 T
(Unfortunately the improvements to the Tk 4.0) 152.1 307.19 T
5 F
(send) 338.65 307.19 T
3 F
( mechanism required substantial) 362.63 307.19 T
(changes to the transport protocol for sends; this makes it impossible for Tk 4.0 applica-) 152.1 295.1 T
(tions to communicate with Tk 3.6 applications via) 152.1 283.01 T
5 F
(send) 355.04 283.01 T
3 F
(. The new transport protocol is) 379.02 283.01 T
(more \337exible than the old protocol, so it should be possible to make protocol improve-) 152.1 270.91 T
(ments in an upward-compatible way) 152.1 258.82 T
(.) 296.9 258.82 T
98.1 215.47 512.1 218.49 C
152.1 216.69 512.1 216.69 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 216.98 143.1 216.98 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(1) 128.62 222.49 T
(1) 134.63 222.49 T
(The selection and clipboard) 152.1 222.49 T
3 10 Q
(In Tk 3.6 the selection mechanism can deal only with the display of the root window and) 152.1 198.8 T
-0.13 (with the primary selection; there is no support for multiple displays, secondary selections,) 152.1 186.71 P
(or the clipboard. Tk 4.0 eliminates all of these shortcomings. The) 152.1 174.61 T
5 F
(-displayof) 415.82 174.61 T
3 F
( option) 475.78 174.61 T
-0.12 (can be used to specify a particular display in the selection command, and there is now full) 152.1 162.52 P
(access to all of the X selection types. Tk 4.0 also includes a new) 152.1 150.43 T
5 F
(clipboard) 411.36 150.43 T
3 F
( command) 465.33 150.43 T
(for manipulating the clipboard.) 152.1 138.33 T
FMENDPAGE
%%EndPage: "15" 16
%%Page: "16" 16
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(16) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
98.1 623.98 512.1 627 C
152.1 625.2 512.1 625.2 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 625.49 143.1 625.49 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(12) 127.96 631 T
(Miscellaneous changes) 152.1 631 T
3 10 Q
(Here is a quick summary of the remaining changes in Tk 4.0:) 152.1 607.31 T
3 12 Q
(\245) 152.1 592.31 T
3 10 Q
-0.17 (The) 162.9 592.31 P
5 F
-0.42 (wish) 180.76 592.31 P
3 F
-0.17 ( application has been modi\336ed so that the) 204.75 592.31 P
5 F
-0.42 (-f) 371.58 592.31 P
-0.42 (ile) 383.57 592.31 P
3 F
-0.17 ( switch is no longer needed) 401.56 592.31 P
(or recommended. This makes) 162.9 580.31 T
5 F
(wish) 283.64 580.31 T
3 F
( just like) 307.63 580.31 T
5 F
(tclsh) 344.56 580.31 T
3 F
(, where you specify the script \336le) 374.54 580.31 T
(as the \336rst ar) 162.9 568.31 T
(gument to the program, e.g.) 214.07 568.31 T
5 F
(wish foo.tcl) 327.33 568.31 T
3 F
(. The) 399.29 568.31 T
5 F
(-f) 422.33 568.31 T
(ile) 434.32 568.31 T
3 F
( switch is still) 452.31 568.31 T
(permitted for backward compatibility) 162.9 556.31 T
(, but its use is deprecated.) 311.87 556.31 T
3 12 Q
(\245) 152.1 541.31 T
5 10 Q
(Wish) 162.9 541.31 T
3 F
( now sets the application\325) 186.89 541.31 T
(s class from the application name \050what appears in the) 288.49 541.31 T
-0.37 (title bar of the window by default\051, rather than always using) 162.9 529.31 P
5 F
-0.88 (Tk) 400.9 529.31 P
3 F
-0.37 ( as the class as in Tk 3.6.) 412.89 529.31 P
(This makes application-speci\336c options easier to use.) 162.9 517.31 T
3 12 Q
(\245) 152.1 502.31 T
3 10 Q
(T) 162.9 502.31 T
(oplevel windows are now resizable by default, whereas in Tk 3.6 they were not. Y) 168.31 502.31 T
(ou) 496.22 502.31 T
(can use the) 162.9 490.31 T
5 F
(wm resizable) 209.8 490.31 T
3 F
( command to make windows non-reiszable.) 281.77 490.31 T
3 12 Q
(\245) 152.1 475.31 T
3 10 Q
(Tk 4.0 patches around an Xlib bug whereby long-running applications tended to reach) 162.9 475.31 T
(the end of the space of X resource ids, wrap around to 0 again, and then crash. Tk now) 162.9 463.31 T
(reuses resource identi\336ers so that wrap-around should never occur) 162.9 451.31 T
(.) 427.14 451.31 T
3 12 Q
(\245) 152.1 436.31 T
3 10 Q
-0.13 (There is a new) 162.9 436.31 P
5 F
-0.31 (winfo manager) 223.43 436.31 P
3 F
-0.13 ( command that tells which geometry manager is con-) 301.08 436.31 P
(trolling a particular widget.) 162.9 424.31 T
3 12 Q
(\245) 152.1 409.31 T
3 10 Q
(There is a new) 162.9 409.31 T
5 F
(bell) 223.96 409.31 T
3 F
( command that does what its name suggests.) 247.94 409.31 T
3 12 Q
(\245) 152.1 394.31 T
3 10 Q
(There are new) 162.9 394.31 T
5 F
(winfo pointerx) 222.56 394.31 T
3 F
(,) 306.51 394.31 T
5 F
(winfo pointery) 311.51 394.31 T
3 F
(, and) 394.81 394.31 T
5 F
(winfo pointerxy) 416.74 394.31 T
3 F
(commands that can be used to query the position of the mouse pointer) 162.9 382.31 T
(.) 442.17 382.31 T
98.1 338.95 512.1 341.98 C
152.1 340.18 512.1 340.18 2 L
0.5 H
2 Z
0 X
0 K
N
98.1 340.46 143.1 340.46 2 L
0 Z
N
40.5 63 571.5 729 C
0 12 Q
0 X
0 K
(13) 127.96 345.98 T
(Summary of Incompatibilites) 152.1 345.98 T
3 10 Q
-0.24 (This section lists all of the incompatible changes in Tk 4.0 that may require changes in T) 152.1 322.29 P
-0.24 (cl) 502.62 322.29 P
-0.22 (scripts written for T) 152.1 310.29 P
-0.22 (cl 3.6. Each incompatibility is described in terms of the problem it pro-) 230.42 310.29 P
(duces when you run your Tk 3.6 script under Tk 4.0 and a possible work-around. Only) 152.1 298.29 T
(T) 152.1 286.29 T
(cl-level incompatibilities are covered here. For incompatible changes at the C level, see) 157.51 286.29 T
(the) 152.1 274.29 T
5 F
(README) 166.81 274.29 T
3 F
( and) 202.79 274.29 T
5 F
(changes) 222.22 274.29 T
3 F
( \336les in the distribution. The problems and solutions are) 264.2 274.29 T
(roughly in order of importance, with the most important problems \336rst.) 152.1 262.29 T
1 F
(Pr) 152.1 247.29 T
(oblem #1:) 162.46 247.29 T
3 F
(When you change the background color of a widget, a small ring in the) 206.88 247.29 T
(default background color remains around the edge of the widget.) 152.1 235.29 T
2 F
(Solution:) 170.1 223.29 T
3 F
(This is the focus traversal highlight, whose color is speci\336ed separately) 209.25 223.29 T
(from) 170.1 211.29 T
5 F
(-background) 192.03 211.29 T
3 F
(; use the) 257.99 211.29 T
5 F
(-highlightbackground) 293.8 211.29 T
3 F
( option to change the) 413.74 211.29 T
(color of the highlight. Or) 170.1 199.29 T
(, you can set) 269.92 199.29 T
5 F
(-highlightthickness) 322.38 199.29 T
3 F
( to 0 to eliminate) 436.31 199.29 T
(the traversal highlight altogether) 170.1 187.29 T
(.) 299.74 187.29 T
1 F
(Pr) 152.1 172.29 T
(oblem #2:) 162.46 172.29 T
3 F
(Bindings de\336ned for a widget no longer replace the corresponding class) 206.88 172.29 T
(bindings, so unwanted class bindings get invoked in addition to the widget bindings.) 152.1 160.29 T
FMENDPAGE
%%EndPage: "16" 17
%%Page: "17" 17
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(13 Summary of Incompatibilites) 98.1 668.33 T
0 F
(17) 500.99 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
2 F
0 X
(Solution:) 170.1 632.33 T
3 F
(Add a) 209.25 632.33 T
5 F
(break) 235.89 632.33 T
3 F
( command at the end of the widget binding, or rework the) 265.88 632.33 T
(widget binding so that it\325) 170.1 620.33 T
(s OK for the class binding to execute.) 270.05 620.33 T
1 F
(Pr) 152.1 605.33 T
(oblem #3:) 162.46 605.33 T
3 F
(Bindings on toplevel windows are invoked when events occur for internal) 206.88 605.33 T
(windows inside the toplevels.) 152.1 593.33 T
2 F
(Solution:) 170.1 581.33 T
3 F
(Use the) 209.25 581.33 T
5 F
(%W) 242 581.33 T
3 F
( substitution to extract the name of the window where the event) 253.99 581.33 T
(actually occurred, and only execute the rest of the binding script if this matches the) 170.1 569.33 T
(name of the toplevel.) 170.1 557.33 T
1 F
-0.15 (Pr) 152.1 542.33 P
-0.15 (oblem #4:) 162.46 542.33 P
3 F
-0.15 (The) 206.58 542.33 P
5 F
-0.37 (-command) 224.46 542.33 P
3 F
-0.15 ( option for a cascade menu entry is no longer invoked when) 272.44 542.33 P
(the submenu is posted.) 152.1 530.33 T
2 F
(Solution:) 170.1 518.33 T
3 F
(Use the) 209.25 518.33 T
5 F
(-postcommand) 242 518.33 T
3 F
( option for the submenu instead.) 313.96 518.33 T
1 F
(Pr) 152.1 503.33 T
(oblem #5:) 162.46 503.33 T
3 F
(The) 206.88 503.33 T
5 F
(-geometry) 224.92 503.33 T
3 F
( option is no longer supported by listboxes, frames, and) 278.89 503.33 T
(toplevels.) 152.1 491.33 T
2 F
(Solution:) 170.1 479.33 T
3 F
(Use the) 209.25 479.33 T
5 F
(-width) 242 479.33 T
3 F
( and) 277.98 479.33 T
5 F
(-height) 297.41 479.33 T
3 F
( options instead.) 339.39 479.33 T
1 F
(Pr) 152.1 464.33 T
(oblem #6:) 162.46 464.33 T
3 F
(The procedure) 206.88 464.33 T
5 F
(tk_listboxSingleSelect) 267.38 464.33 T
3 F
( no longer exists.) 399.3 464.33 T
2 F
(Solution:) 170.1 452.33 T
3 F
(Use the) 209.25 452.33 T
5 F
(-selectmode) 242 452.33 T
3 F
( option on the listbox instead.) 307.96 452.33 T
1 F
(Pr) 152.1 437.33 T
(oblem #7:) 162.46 437.33 T
3 F
(Canvases no longer have a) 206.88 437.33 T
5 F
(-scrollincrement) 315.96 437.33 T
3 F
( option.) 411.91 437.33 T
2 F
(Solution:) 170.1 425.33 T
3 F
(Use the new) 209.25 425.33 T
5 F
(-xscrollincrement) 261.15 425.33 T
3 F
( and) 363.09 425.33 T
5 F
(-yscrollincrement) 382.52 425.33 T
3 F
(options instead.) 170.1 413.33 T
1 F
(Pr) 152.1 398.33 T
(oblem #8:) 162.46 398.33 T
3 F
(The) 206.88 398.33 T
5 F
(tk colormodel) 224.92 398.33 T
3 F
( command no longer exists.) 302.88 398.33 T
2 F
-0.28 (Solution:) 170.1 386.33 P
3 F
-0.28 (T) 208.97 386.33 P
-0.28 (o \336nd out whether a window is monochrome or color) 214.37 386.33 P
-0.28 (, use) 424.34 386.33 P
5 F
-0.68 (winfo depth) 444.6 386.33 P
3 F
(to extract the window\325) 170.1 374.33 T
(s depth; a depth of 1 means monochrome.) 259.76 374.33 T
1 F
-0.08 (Pr) 152.1 359.33 P
-0.08 (oblem #9:) 162.46 359.33 P
3 F
-0.08 (The class of Tk applications is no longer) 206.72 359.33 P
5 F
-0.19 (Tk) 370.97 359.33 P
3 F
-0.08 (, so options speci\336ed for the) 382.96 359.33 P
5 F
-0.19 (Tk) 497.69 359.33 P
3 F
(class in your) 152.1 347.33 T
5 F
(.Xdefaults) 205.12 347.33 T
3 F
( \336le are no longer used.) 265.09 347.33 T
2 F
(Solution:) 170.1 335.33 T
3 F
(Modify your) 209.25 335.33 T
5 F
(.Xdefaults) 262.55 335.33 T
3 F
( \336le \050and any T) 322.52 335.33 T
(cl code that sets options\051 to) 382.88 335.33 T
(specify the name of the application \050with the \336rst letter capitalized\051 as the class) 170.1 323.33 T
(instead of) 170.1 311.33 T
5 F
(Tk) 211.74 311.33 T
3 F
(.) 223.73 311.33 T
1 F
-0.15 (Pr) 152.1 296.33 P
-0.15 (oblem #10:) 162.46 296.33 P
3 F
-0.15 (When text is added to a text widget just after a tagged area, the new text no) 211.57 296.33 P
(longer receives the tag.) 152.1 284.33 T
2 F
-0.1 (Solution:) 170.1 272.33 P
3 F
-0.1 (Explicitly tag the new text with the desired tags. If you want the tags on the) 209.15 272.33 P
-0.08 (new text to be the same as those at some other point in the text, you can use the) 170.1 260.33 P
5 F
-0.2 (tag) 488.31 260.33 P
(names) 170.1 248.33 T
3 F
( widget command to query existing tags.) 200.08 248.33 T
1 F
(Pr) 152.1 233.33 T
(oblem #1) 162.46 233.33 T
(1:) 200.5 233.33 T
3 F
(W) 211.33 233.33 T
(idgets appear lar) 220.36 233.33 T
(ger than they did in Tk 3.6.) 286.24 233.33 T
2 F
(Solution:) 170.1 221.33 T
3 F
(There are two issues here. The \336rst is that all widgets now have a focus tra-) 209.25 221.33 T
-0.24 (versal highlight ring that turns dark when the widget has the focus; this is required for) 170.1 209.33 P
(Motif compliance but you can eliminate it by specifying a 0 value for the) 170.1 197.33 T
5 F
( -high-) 462.4 197.33 T
(lightthickness) 170.1 185.33 T
3 F
( option. The second issue is that the default padding for buttons) 254.05 185.33 T
-0.17 (and menubuttons has been increased to match the sizes of Motif widgets. If you don\325) 170.1 173.33 P
-0.17 (t) 506.99 173.33 P
(mind being dif) 170.1 161.33 T
(ferent from Motif, you can set the) 228.78 161.33 T
5 F
(-padx) 366.45 161.33 T
3 F
( and) 396.44 161.33 T
5 F
(-) 415.86 161.33 T
(pady) 421.86 161.33 T
3 F
( options back to) 445.85 161.33 T
FMENDPAGE
%%EndPage: "17" 18
%%Page: "18" 18
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(18) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
3 F
0 X
(their Tk 3.6 values \050use the) 170.1 632.33 T
5 F
(conf) 281.41 632.33 T
(igure) 305.4 632.33 T
3 F
( widget command in Tk 3.6 to see what the) 335.38 632.33 T
(old values were\051.) 170.1 620.33 T
1 F
(Pr) 152.1 605.33 T
(oblem #12:) 162.46 605.33 T
3 F
(Listboxes now return the selection as a string with newlines separating the) 211.88 605.33 T
(values, rather than a T) 152.1 593.33 T
(cl, list.) 240.49 593.33 T
2 F
(Solution:) 170.1 581.33 T
3 F
(Modify your code to handle the new format. Y) 209.25 581.33 T
(ou can convert the selection) 395.06 581.33 T
(back into the old list format with a script like the following:) 170.1 569.33 T
5 9 Q
(split [selection get] \134n) 179.1 555 T
1 10 Q
(Pr) 152.1 541.33 T
(oblem #13:) 162.46 541.33 T
3 F
(Tk 4.0 applications cannot) 211.88 541.33 T
5 F
(send) 320.42 541.33 T
3 F
( to or be sent from Tk 3.6 applications.) 344.4 541.33 T
2 F
(Solution:) 170.1 529.33 T
3 F
(The only solution is to upgrade all your applications to Tk 4.0.) 209.25 529.33 T
1 F
-0.17 (Pr) 152.1 514.33 P
-0.17 (oblem #14:) 162.46 514.33 P
3 F
-0.17 (In texts,) 211.54 514.33 P
5 F
-0.4 (end) 245.91 514.33 P
3 F
-0.17 ( now refers to a position just after the \336nal newline, instead of) 263.9 514.33 P
(the \336nal newline.) 152.1 502.33 T
2 F
-0.08 (Solution:) 170.1 490.33 P
3 F
-0.08 (If you wish to refer to the \336nal newline, use the index) 209.17 490.33 P
5 F
-0.19 (end-1char) 424.98 490.33 P
3 F
-0.08 ( instead) 478.95 490.33 P
(of) 170.1 478.33 T
5 F
(end) 180.92 478.33 T
3 F
(.) 198.91 478.33 T
1 F
(Pr) 152.1 463.33 T
(oblem #15:) 162.46 463.33 T
3 F
(In entry widgets,) 211.88 463.33 T
5 F
(sel.last) 281.83 463.33 T
3 F
( now refers to the character just after the last) 329.8 463.33 T
(selected one, rather than the last selected one. The second index for the) 152.1 451.33 T
5 F
(delete) 438.81 451.33 T
3 F
( widget) 474.79 451.33 T
(command has changed in the same way) 152.1 439.33 T
(.) 309.66 439.33 T
2 F
(Solution:) 170.1 427.33 T
3 F
(Add one to the values used in your scripts.) 209.25 427.33 T
1 F
(Pr) 152.1 412.33 T
(oblem #16:) 162.46 412.33 T
3 F
(Because) 211.88 412.33 T
5 F
(Any) 247.68 412.33 T
3 F
( is implicit in all bindings, bindings trigger when extra modi-) 265.67 412.33 T
(\336ers are present, whereas they didn\325) 152.1 400.33 T
(t trigger in Tk 3.6.) 296.24 400.33 T
2 F
(Solution:) 170.1 388.33 T
3 F
(In most cases it\325) 209.25 388.33 T
(s probably \336ne to ignore the extra modi\336ers. If you really) 273.93 388.33 T
-0.12 (don\325) 170.1 376.33 P
-0.12 (t want any actions to be taken when extra modi\336ers are present, create additional) 188.24 376.33 P
(bindings for the cases with extra modi\336ers, and specify a single blank character \050or) 170.1 364.33 T
(any script that does nothing\051 as the script for those bindings. Alternatively) 170.1 352.33 T
(, you can) 465.93 352.33 T
(use the) 170.1 340.33 T
5 F
(%s) 200.63 340.33 T
3 F
( substitution to extract the mouse and modi\336er state in the event binding,) 212.63 340.33 T
(then you can test this value for modi\336ers you do or don\325) 170.1 328.33 T
(t want.) 394.5 328.33 T
1 F
(Pr) 152.1 313.33 T
(oblem #17:) 162.46 313.33 T
3 F
(In scrollbars there is no longer a) 211.88 313.33 T
5 F
(-foreground) 343.17 313.33 T
3 F
( or) 409.13 313.33 T
5 F
(-activefore-) 422.45 313.33 T
(ground) 152.1 301.33 T
3 F
( option, and) 188.08 301.33 T
5 F
(-background) 238.05 301.33 T
3 F
( has a dif) 304.02 301.33 T
(ferent meaning.) 340.2 301.33 T
2 F
-0.4 (Solution:) 170.1 289.33 P
3 F
-0.4 (Use) 208.85 289.33 P
5 F
-0.96 (-troughcolor) 226.49 289.33 P
3 F
-0.4 ( everywhere that you used) 298.45 289.33 P
5 F
-0.96 (-background) 403.87 289.33 P
3 F
-0.4 ( in Tk 3.6,) 469.83 289.33 P
5 F
(-background) 170.1 277.33 T
3 F
( everywhere you used to use) 236.06 277.33 T
5 F
(-foreground) 352.08 277.33 T
3 F
(, and) 418.04 277.33 T
5 F
(-activeback-) 439.97 277.33 T
(ground) 170.1 265.33 T
3 F
( everywhere you used to use) 206.08 265.33 T
5 F
(-activeforeground) 322.1 265.33 T
3 F
(.) 424.04 265.33 T
1 F
(Pr) 152.1 250.33 T
(oblem #18:) 162.46 250.33 T
3 F
(Options for colors seem to have changed in scale widgets.) 211.88 250.33 T
2 F
(Solution:) 170.1 238.33 T
3 F
(Use) 209.25 238.33 T
5 F
(-background) 227.29 238.33 T
3 F
( where you used to use) 293.25 238.33 T
5 F
(-sliderforeground) 387.07 238.33 T
3 F
(,) 489.02 238.33 T
5 F
(-) 170.1 226.33 T
(troughcolor) 176.1 226.33 T
3 F
( where you used to use) 242.06 226.33 T
5 F
(-background) 335.88 226.33 T
3 F
(, and) 401.84 226.33 T
5 F
( -activeback-) 421.27 226.33 T
(ground) 170.1 214.33 T
3 F
( everywhere you used to use) 206.08 214.33 T
5 F
(-activeforeground) 322.1 214.33 T
3 F
(.) 424.04 214.33 T
1 F
(Pr) 152.1 199.33 T
(oblem #19:) 162.46 199.33 T
3 F
(Scale widgets no longer accept hexadecimal or octal numbers in the) 211.88 199.33 T
5 F
(set) 485.84 199.33 T
3 F
(command or the) 152.1 187.33 T
5 F
(-from) 219.55 187.33 T
3 F
( and) 249.54 187.33 T
5 F
(-to) 268.97 187.33 T
3 F
( options.) 286.96 187.33 T
2 F
(Solution:) 170.1 175.33 T
3 F
(Use) 209.25 175.33 T
5 F
(format) 227.29 175.33 T
3 F
( or) 263.27 175.33 T
5 F
(expr) 276.59 175.33 T
3 F
( to convert the values to decimal.) 300.58 175.33 T
1 F
(Pr) 152.1 160.33 T
(oblem #20:) 162.46 160.33 T
3 F
(In checkbuttons, radiobuttons, and menu entries, the) 211.88 160.33 T
5 F
(-selector) 423.4 160.33 T
3 F
( option) 477.37 160.33 T
(no longer exists.) 152.1 148.33 T
FMENDPAGE
%%EndPage: "18" 19
%%Page: "19" 19
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(13 Summary of Incompatibilites) 98.1 668.33 T
0 F
(19) 500.99 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
2 F
0 X
(Solution:) 170.1 632.33 T
3 F
(Use) 209.25 632.33 T
5 F
(-selectcolor) 227.29 632.33 T
3 F
( instead of) 299.25 632.33 T
5 F
(-select) 343.39 632.33 T
3 F
(. T) 385.36 632.33 T
(o specify that no indicator) 395.77 632.33 T
(should be drawn at all, use the) 170.1 620.33 T
5 F
(-indicatoron) 293.9 620.33 T
3 F
( option instead of setting) 365.86 620.33 T
5 F
(-select) 467.2 620.33 T
3 F
(to an empty string.) 170.1 608.33 T
1 F
-0.12 (Pr) 152.1 593.33 P
-0.12 (oblem #21:) 162.46 593.33 P
3 F
-0.12 (The indices of menu entries have changed, and operations on menu entry 0) 211.64 593.33 P
(no longer work.) 152.1 581.33 T
2 F
(Solution:) 170.1 569.33 T
3 F
(This is because menus now have a tearof) 209.25 569.33 T
(f entry at the top by default, and) 372.55 569.33 T
(this occupies entry 0, so your \336rst entry is now entry 1. Y) 170.1 557.33 T
(ou can either set the) 398.95 557.33 T
5 F
(-) 170.1 545.33 T
(tearoff) 176.1 545.33 T
3 F
( option to 0 to eliminate the tearof) 218.07 545.33 T
(f entry or add 1 to all the indices you) 354.2 545.33 T
(use in your scripts.) 170.1 533.33 T
1 F
-0.22 (Pr) 152.1 518.33 P
-0.22 (oblem #22:) 162.46 518.33 P
3 F
-0.22 (The) 211.44 518.33 P
5 F
-0.53 (enable) 229.26 518.33 P
3 F
-0.22 ( and) 265.24 518.33 P
5 F
-0.53 (disable) 284.23 518.33 P
3 F
-0.22 ( widget commands are no longer supported by) 326.21 518.33 P
(menus.) 152.1 506.33 T
2 F
(Solution:) 170.1 494.33 T
3 F
(Use the) 209.25 494.33 T
5 F
(-state) 242 494.33 T
3 F
( con\336guration option instead.) 277.98 494.33 T
1 F
(Pr) 152.1 479.33 T
(oblem #23:) 162.46 479.33 T
3 F
(The) 211.88 479.33 T
5 F
(activate) 229.92 479.33 T
3 F
( and) 277.89 479.33 T
5 F
(deactivate) 297.32 479.33 T
3 F
( widget commands are no longer sup-) 357.29 479.33 T
(ported by buttons, checkbuttons, radiobuttons, and menus.) 152.1 467.33 T
2 F
(Solution:) 170.1 455.33 T
3 F
(Use the) 209.25 455.33 T
5 F
(-state) 242 455.33 T
3 F
( con\336guration option instead.) 277.98 455.33 T
1 F
(Pr) 152.1 440.33 T
(oblem #24:) 162.46 440.33 T
3 F
(Canvas arc items no longer use the) 211.88 440.33 T
5 F
(-f) 353.72 440.33 T
(ill) 365.71 440.33 T
3 F
( and) 383.7 440.33 T
5 F
(-stipple) 403.13 440.33 T
3 F
( options for) 451.11 440.33 T
(drawing when the) 152.1 428.33 T
5 F
(-style) 226.21 428.33 T
3 F
( option is) 262.19 428.33 T
5 F
(arc) 301.9 428.33 T
3 F
(.) 319.89 428.33 T
2 F
(Solution:) 170.1 416.33 T
3 F
(Use the) 209.25 416.33 T
5 F
(-outline) 242 416.33 T
3 F
( and) 289.97 416.33 T
5 F
(-outlinestipple) 309.4 416.33 T
3 F
( options instead.) 399.35 416.33 T
1 F
-0.29 (Pr) 152.1 401.33 P
-0.29 (oblem #25:) 162.46 401.33 P
3 F
-0.29 (The variable) 211.29 401.33 P
5 F
-0.7 (tkVersion) 263.43 401.33 P
3 F
-0.29 ( no longer exists \050it has been obsolete for several) 317.4 401.33 P
(releases\051.) 152.1 389.33 T
2 F
(Solution:) 170.1 377.33 T
3 F
(Use) 209.25 377.33 T
5 F
(tk_version) 227.29 377.33 T
3 F
( instead.) 287.26 377.33 T
1 F
(Pr) 152.1 362.33 T
(oblem #26:) 162.46 362.33 T
3 F
(The syntax of the) 211.88 362.33 T
5 F
(scan) 284.05 362.33 T
3 F
( widget commands for texts has changed.) 308.03 362.33 T
2 F
(Solution:) 170.1 350.33 T
3 F
(Modify your code to use the new syntax.) 209.25 350.33 T
1 F
(Pr) 152.1 335.33 T
(oblem #27:) 162.46 335.33 T
5 F
(wish) 211.88 335.33 T
3 F
( no longer recognizes the) 235.86 335.33 T
5 F
(-help) 338.84 335.33 T
3 F
( option.) 368.82 335.33 T
2 F
(Solution:) 170.1 323.33 T
3 F
(Implement this option yourself in your) 209.25 323.33 T
5 F
(wish) 366.38 323.33 T
3 F
( scripts.) 390.37 323.33 T
1 F
(Pr) 152.1 308.33 T
(oblem #28:) 162.46 308.33 T
3 F
(Tk 4.0 always prints real numbers such as canvas coordinates with a deci-) 211.88 308.33 T
(mal point. This can cause syntax errors if you later use them in situations where integers) 152.1 296.33 T
(are expected.) 152.1 284.33 T
2 F
(Solution:) 170.1 272.33 T
3 F
(Change your code so that real numbers work OK, or use the) 209.25 272.33 T
5 F
(expr) 451.57 272.33 T
3 F
( com-) 475.55 272.33 T
(mand \050with the) 170.1 260.33 T
5 F
(round) 233.12 260.33 T
3 F
( function\051 to convert the numbers to integers.) 263.1 260.33 T
1 F
(Pr) 152.1 245.33 T
(oblem #29:) 162.46 245.33 T
3 F
(The) 211.88 245.33 T
5 F
(pack info) 229.92 245.33 T
3 F
( command returns dif) 283.89 245.33 T
(ferent information, and) 369.48 245.33 T
5 F
(pack) 464.41 245.33 T
(newinfo) 152.1 233.33 T
3 F
( no longer exists.) 194.08 233.33 T
2 F
(Solution:) 170.1 221.33 T
3 F
(Use) 209.25 221.33 T
5 F
(pack info) 227.29 221.33 T
3 F
( where you used to use) 281.26 221.33 T
5 F
(pack newinfo) 375.08 221.33 T
3 F
(.) 447.04 221.33 T
5 F
(Pack info) 452.04 221.33 T
3 F
(was obsolete, so it has been eliminated.) 170.1 209.33 T
1 F
(Pr) 152.1 194.33 T
(oblem #30:) 162.46 194.33 T
3 F
(The) 211.88 194.33 T
5 F
(view) 229.92 194.33 T
3 F
( widget command for entries no longer exists, nor does the) 253.9 194.33 T
5 F
(-) 152.1 182.33 T
(scrollcommand) 158.1 182.33 T
3 F
( option.) 236.05 182.33 T
2 F
-0.29 (Solution:) 170.1 170.33 P
3 F
-0.29 (Use) 208.96 170.33 P
5 F
-0.69 (xview) 226.71 170.33 P
3 F
-0.29 ( where you used to use) 256.7 170.33 P
5 F
-0.69 (view) 348.8 170.33 P
3 F
-0.29 (; use) 372.78 170.33 P
5 F
-0.69 (-xscrollcommand) 393.31 170.33 P
3 F
-0.29 ( where) 483.26 170.33 P
(you used to use) 170.1 158.33 T
5 F
(-scrollcommand) 234.51 158.33 T
3 F
(.) 318.46 158.33 T
FMENDPAGE
%%EndPage: "19" 20
%%Page: "20" 20
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(20) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
1 F
0 X
(Pr) 152.1 632.33 T
(oblem #31:) 162.46 632.33 T
3 F
(The) 211.88 632.33 T
5 F
(-padx) 229.92 632.33 T
3 F
( and) 259.9 632.33 T
5 F
(-pady) 279.33 632.33 T
3 F
( options are ignored for the button family of wid-) 309.31 632.33 T
(gets if a bitmap or image is being displayed: the padding is always 0.) 152.1 620.02 T
2 F
-0.27 (Solution:) 170.1 608.02 P
3 F
-0.27 (Pack the button inside a frame, with extra padding in the frame. Or) 208.98 608.02 P
-0.27 (, redo the) 472.94 608.02 P
(image or bitmap to incorporate padding into it.) 170.1 595.71 T
1 F
(Pr) 152.1 580.71 T
(oblem #32:) 162.46 580.71 T
3 F
(In radiobuttons, the) 211.88 580.71 T
5 F
(-value) 292.38 580.71 T
3 F
( option no longer defaults to the name of the) 328.36 580.71 T
(widget; it defaults to an empty string.) 152.1 568.4 T
2 F
(Solution:) 170.1 556.4 T
3 F
(Specify the widget\325) 209.25 556.4 T
(s name explicitly as the value of the option.) 286.98 556.4 T
1 F
(Pr) 152.1 541.4 T
(oblem #33:) 162.46 541.4 T
3 F
(The) 211.88 541.4 T
5 F
(-menu) 229.92 541.4 T
3 F
( option for menubuttons and cascade menu entries may refer) 259.9 541.4 T
(only to a child of the menubutton or menu.) 152.1 529.08 T
2 F
(Solution:) 170.1 517.08 T
3 F
(Rename menus to meet this requirement.) 209.25 517.08 T
1 F
(Pr) 152.1 502.08 T
(oblem #34:) 162.46 502.08 T
3 F
(The interpretation of) 211.88 502.08 T
5 F
(@y) 297.09 502.08 T
3 F
( in menus has changed: it never returns) 309.08 502.08 T
5 F
(none) 467.86 502.08 T
3 F
(,) 491.84 502.08 T
(even if the y-coordinate is outside the menu \050it returns the index of the closest entry\051.) 152.1 489.77 T
2 F
(Solution:) 170.1 477.77 T
3 F
(If you care about this distinction, check the y-coordinate explicitly to see if) 209.25 477.77 T
-0.17 (it is less than 0 or greater than or equal to the window\325) 170.1 465.46 P
-0.17 (s height \050use) 385.7 465.46 P
5 F
-0.41 (winfo height) 438.21 465.46 P
3 F
(to get the height\051.) 170.1 453.15 T
1 F
-0.13 (Pr) 152.1 438.15 P
-0.13 (oblem #35:) 162.46 438.15 P
3 F
-0.13 (The) 211.62 438.15 P
5 F
-0.3 (invoke) 229.54 438.15 P
3 F
-0.13 ( and) 265.52 438.15 P
5 F
-0.3 (activate) 284.7 438.15 P
3 F
-0.13 ( widget commands for menus no longer post) 332.67 438.15 P
(cascaded submenus.) 152.1 425.83 T
2 F
(Solution:) 170.1 413.83 T
3 F
(Use the) 209.25 413.83 T
5 F
(postcascade) 242 413.83 T
3 F
( widget command to post submenus.) 307.96 413.83 T
1 F
(Pr) 152.1 398.83 T
(oblem #36:) 162.46 398.83 T
3 F
(The selection tar) 211.88 398.83 T
(gets) 278.31 398.83 T
5 F
(APPLICATION) 296.91 398.83 T
3 F
( and) 362.87 398.83 T
5 F
(WINDOW_NAME) 382.3 398.83 T
3 F
( are no longer) 448.27 398.83 T
(supported.) 152.1 386.52 T
2 F
(Solution:) 170.1 374.52 T
3 F
(Use tar) 209.25 374.52 T
(gets) 237.65 374.52 T
5 F
(TK_APPLICATION) 256.25 374.52 T
3 F
( and) 340.21 374.52 T
5 F
(TK_WINDOW) 359.64 374.52 T
3 F
( instead.) 413.61 374.52 T
1 F
(Pr) 152.1 359.52 T
(oblem #37:) 162.46 359.52 T
3 F
(There is no longer a default focus.) 211.88 359.52 T
2 F
(Solution:) 170.1 347.52 T
3 F
(None: modify your code not to depend on this feature.) 209.25 347.52 T
1 F
(Pr) 152.1 332.52 T
(oblem #38:) 162.46 332.52 T
3 F
(The) 211.88 332.52 T
5 F
(focus) 229.92 332.52 T
3 F
( command now returns an empty string to indicate that the) 259.9 332.52 T
(application doesn\325) 152.1 320.21 T
(t have the input focus, instead of) 225.48 320.21 T
5 F
(none) 358.17 320.21 T
3 F
(.) 382.15 320.21 T
2 F
(Solution:) 170.1 308.21 T
3 F
(Modify your code to check for an empty string instead of) 209.25 308.21 T
5 F
(none) 440.47 308.21 T
3 F
(.) 464.46 308.21 T
1 F
(Pr) 152.1 293.21 T
(oblem #39:) 162.46 293.21 T
5 F
(FocusIn) 211.88 293.21 T
3 F
( and) 253.85 293.21 T
5 F
(FocusOut) 273.28 293.21 T
3 F
( events are delivered to more windows than) 321.26 293.21 T
(they used to be.) 152.1 280.9 T
2 F
-0.02 (Solution:) 170.1 268.9 P
3 F
-0.02 (Modify your code to use the new set of events. The old event set was some-) 209.23 268.9 P
(what bizarre, and the new set matches more closely what happens elsewhere, such as) 170.1 256.58 T
(with) 170.1 244.27 T
5 F
(Enter) 190.37 244.27 T
3 F
( and) 220.35 244.27 T
5 F
(Leave) 239.78 244.27 T
3 F
( events.) 269.77 244.27 T
1 F
-0.28 (Pr) 152.1 229.27 P
-0.28 (oblem #40:) 162.46 229.27 P
5 F
-0.67 (wm maxsize) 211.32 229.27 P
3 F
-0.28 ( and) 270.62 229.27 P
5 F
-0.67 (wm minsize) 289.49 229.27 P
3 F
-0.28 ( no longer accept empty ar) 348.79 229.27 P
-0.28 (guments. This) 453.52 229.27 P
(means that you cannot use these commands to make windows non-resizable.) 152.1 216.96 T
2 F
(Solution:) 170.1 204.96 T
3 F
(Use the) 209.25 204.96 T
5 F
(wm resizable) 242 204.96 T
3 F
( command to make windows resizable.) 313.96 204.96 T
1 F
(Pr) 152.1 189.96 T
(oblem #41:) 162.46 189.96 T
3 F
(In the placer) 211.88 189.96 T
(, if you specify both) 261.43 189.96 T
5 F
(-x) 344.15 189.96 T
3 F
( and) 356.15 189.96 T
5 F
(-relx) 375.58 189.96 T
3 F
( then they add, instead of) 405.56 189.96 T
(the most recent speci\336cation replacing the earlier one. Ditto for) 152.1 177.65 T
5 F
(-y) 407.74 177.65 T
3 F
( and) 419.73 177.65 T
5 F
(-rely) 439.16 177.65 T
3 F
(,) 468.5 177.65 T
5 F
(-width) 473.49 177.65 T
3 F
(and) 152.1 165.33 T
5 F
(-relwidth) 169.03 165.33 T
3 F
(, and) 223 165.33 T
5 F
(-height) 244.93 165.33 T
3 F
( and) 286.91 165.33 T
5 F
(-relheight) 306.33 165.33 T
3 F
(.) 366.3 165.33 T
2 F
(Solution:) 170.1 153.33 T
3 F
(If you no longer want one of these options to be used, set it to 0 explicitly) 209.25 153.33 T
(.) 503.14 153.33 T
1 F
(Pr) 152.1 138.33 T
(oblem #42:) 162.46 138.33 T
3 F
(The command \322) 211.88 138.33 T
5 F
(focus none) 276.27 138.33 T
3 F
(\323 doesn\325) 336.24 138.33 T
(t work in Tk 4.0.) 369.64 138.33 T
FMENDPAGE
%%EndPage: "20" 21
%%Page: "21" 21
612 792 0 FMBEGINPAGE
4 10 Q
0 X
0 K
(13 Summary of Incompatibilites) 98.1 668.33 T
0 F
(21) 500.99 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
2 F
0 X
(Solution:) 170.1 632.33 T
3 F
(Create a dummy widget that is never mapped and set the focus to that wid-) 209.25 632.33 T
(get.) 170.1 620.33 T
1 F
(Pr) 152.1 605.33 T
(oblem #43:) 162.46 605.33 T
5 F
(%D) 211.88 605.33 T
3 F
( substitutions are no longer supported in bindings, nor are the event) 223.87 605.33 T
(types) 152.1 593.33 T
5 F
(CirculateRequest) 175.7 593.33 T
3 F
(,) 271.64 593.33 T
5 F
(Conf) 276.64 593.33 T
(igureRequest) 300.63 593.33 T
3 F
(,) 372.59 593.33 T
5 F
(MapRequest) 377.59 593.33 T
3 F
(, and) 437.55 593.33 T
5 F
(Resiz-) 459.48 593.33 T
(eRequest) 152.1 581.33 T
3 F
(.) 200.07 581.33 T
2 F
-0.25 (Solution:) 170.1 569.33 P
3 F
-0.25 (Use the name of the display instead of %D to identify a display; you can get) 209 569.33 P
(the display name with the) 170.1 557.33 T
5 F
(winfo screen) 275.31 557.33 T
3 F
( command. The desupported event types) 347.27 557.33 T
(never really worked anyway) 170.1 545.33 T
(, so there should be no code that depends on them.) 282.96 545.33 T
1 F
(Pr) 152.1 530.33 T
(oblem #44:) 162.46 530.33 T
5 F
(%) 211.88 530.33 T
3 F
( binding substitutions that return window identi\336ers, such as) 217.87 530.33 T
5 F
(%a) 461.63 530.33 T
3 F
( and) 473.62 530.33 T
5 F
(%S) 493.05 530.33 T
3 F
(,) 505.05 530.33 T
(now produce hexadecimal results instead of decimal.) 152.1 518.33 T
2 F
(Solution:) 170.1 506.33 T
3 F
(Use the) 209.25 506.33 T
5 F
(format) 242 506.33 T
3 F
( command to turn them back to decimal.) 277.98 506.33 T
1 F
(Pr) 152.1 491.33 T
(oblem #45:) 162.46 491.33 T
5 F
(Enter) 211.88 491.33 T
3 F
(,) 241.46 491.33 T
5 F
(Leave) 246.46 491.33 T
3 F
(,) 276.44 491.33 T
5 F
(FocusIn) 281.44 491.33 T
3 F
(, and) 323.42 491.33 T
5 F
(FocusOut) 345.34 491.33 T
3 F
( events with detail) 393.32 491.33 T
5 F
(Notify-) 468.83 491.33 T
(Inferior) 152.1 479.33 T
3 F
( are now ignored by the binding mechanism, so they\325re not visible to T) 200.07 479.33 T
(cl) 483.08 479.33 T
(scripts.) 152.1 467.33 T
2 F
-0.13 (Solution:) 170.1 455.33 P
3 F
-0.13 (In most cases, T) 209.12 455.33 P
-0.13 (cl scripts work better if these bindings are ignored. Y) 273 455.33 P
-0.13 (ou can) 483.49 455.33 P
(still use C code to access these events if you really need them. Or) 170.1 443.33 T
(, create bindings on) 431.18 443.33 T
-0.33 (the inferior windows and use) 170.1 431.33 P
5 F
-0.8 (NotifyAncestor) 286.96 431.33 P
3 F
-0.33 ( bindings on the children instead of) 370.91 431.33 P
5 F
(NotifyInferior) 170.1 419.33 T
3 F
( bindings on the parent.) 254.05 419.33 T
FMENDPAGE
%%EndPage: "21" 22
%%Page: "22" 22
612 792 0 FMBEGINPAGE
0 10 Q
0 X
0 K
(22) 98.1 668.33 T
4 F
(Tk4.0 Overview and Porting Guide) 359.34 668.33 T
98.1 660.6 512.1 660.6 2 L
0.25 H
0 Z
N
98.1 135 512.1 639 R
7 X
V
FMENDPAGE
%%EndPage: "22" 23
%%Trailer
%%BoundingBox: 0 0 612 792
%%Pages: 22 1
%%DocumentFonts: Helvetica-Bold
%%+ Times-Bold
%%+ Times-Italic
%%+ Times-Roman
%%+ Helvetica
%%+ Courier
%%+ Courier-Oblique
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to doc/tk_mac.n.

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

48
49
50
51
52
53
54

55
56
57
58
59
60
61

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

80
81
82
83
84
85
86

87
88
89
90
91
92
93
\fB::tk::mac::standardAboutPanel\fR

\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
\fB::tk::mac::antialiasedtext \fInumber\fR
\fB::tk::mac::useThemedToplevel \fIboolean\fR


\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.fi
.BE
.SH "EVENT HANDLER CALLBACKS"
.PP
The Aqua/Mac OS X application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.

.TP
\fB::tk::mac::DoScriptFile\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes a Tcl file when an AppleScript sends a
.QW "do script"
command to Wish with a file path as a parameter.

.TP
\fB::tk::mac::DoScriptText\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes Tcl code when an AppleScript sends a
.QW "do script"
command to Wish with Tcl code or a Tcl procedure as a parameter.

.TP
\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is
used to wrap a specific own preferences command, which pops up a preferences
window. Something like:
.RS
.PP
.CS
proc ::tk::mac::ShowPreferences {} {
    setPref
}
.CE
.RE

.TP
\fB::tk::mac::OpenApplication\fR
.
If a proc of this name is defined, this proc fill fire when your application
is initially opened. It is the default Apple Event handler for
kAEOpenApplication,
.QW oapp .

.TP
\fB::tk::mac::ReopenApplication\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEReopenApplication,
.QW rapp ,
the Apple Event sent when your application is opened when it is already







<









>







>







>


















>







>







31
32
33
34
35
36
37

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

\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
\fB::tk::mac::antialiasedtext \fInumber\fR
\fB::tk::mac::useThemedToplevel \fIboolean\fR


\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.fi
.BE
.SH "EVENT HANDLER CALLBACKS"
.PP
The Aqua/Mac OS X application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.
.\" COMMAND: DoScriptFile
.TP
\fB::tk::mac::DoScriptFile\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes a Tcl file when an AppleScript sends a
.QW "do script"
command to Wish with a file path as a parameter.
.\" COMMAND: DoScriptText
.TP
\fB::tk::mac::DoScriptText\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes Tcl code when an AppleScript sends a
.QW "do script"
command to Wish with Tcl code or a Tcl procedure as a parameter.
.\" COMMAND: ShowPreferences
.TP
\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is
used to wrap a specific own preferences command, which pops up a preferences
window. Something like:
.RS
.PP
.CS
proc ::tk::mac::ShowPreferences {} {
    setPref
}
.CE
.RE
.\" COMMAND: OpenApplication
.TP
\fB::tk::mac::OpenApplication\fR
.
If a proc of this name is defined, this proc fill fire when your application
is initially opened. It is the default Apple Event handler for
kAEOpenApplication,
.QW oapp .
.\" COMMAND: ReopenApplication
.TP
\fB::tk::mac::ReopenApplication\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEReopenApplication,
.QW rapp ,
the Apple Event sent when your application is opened when it is already
102
103
104
105
106
107
108

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

127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144

145
146
147
148
149

150
151
152
153
154
155

156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
    } else {
        wm deiconify .
    }
    raise .
}
.CE
.RE

.TP
\fB::tk::mac::OpenDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEOpenDocuments,
.QW odoc ,
the Apple Event sent when your application is asked to open one or more
documents (e.g., by drag & drop onto the app or by opening a document of a
type associated to the app). The proc should take as arguments paths to the
files to be opened, like so:
.RS
.PP
.CS
proc ::tk::mac::OpenDocument {args} {
    foreach f $args {my_open_document $f}
}
.CE
.RE

.TP
\fB::tk::mac::PrintDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEPrintDocuments,
.QW pdoc ,
the Apple Event sent when your application is asked to print a
document.  It takes a single absolute file path as an argument.

.TP
\fB::tk::mac::Quit\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEQuitApplication,
.QW quit ,
the Apple Event sent when your application is asked to be quit, e.g. via the
quit menu item in the application menu, the quit menu item in the Dock menu,
or during a logout/restart/shutdown etc. If this is not defined, \fBexit\fR is
called instead.

.TP
\fB::tk::mac::OnHide\fR
.
If defined, this is called when your application receives a kEventAppHidden
event, e.g. via the hide menu item in the application or Dock menus.

.TP
\fB::tk::mac::OnShow\fR
.
If defined, this is called when your application receives a kEventAppShown
event, e.g. via the show all menu item in the application menu, or by clicking
the Dock icon of a hidden application.

.TP
\fB::tk::mac::ShowHelp\fR
.
Customizes behavior of Apple Help menu; if this procedure is not defined, the
platform-specific standard Help menu item
.QW "YourApp Help"
performs the default Cocoa action of showing the Help Book configured in the
application's Info.plist (or displaying an alert if no Help Book is
set).

.TP
\fB::tk::mac::PerformService\fR
.
Executes a Tcl procedure called from the macOS
.QW Services
menu in the Application menu item. The
.QW Services







>


















>








>










>





>






>









>







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    } else {
        wm deiconify .
    }
    raise .
}
.CE
.RE
.\" COMMAND: OpenDocument
.TP
\fB::tk::mac::OpenDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEOpenDocuments,
.QW odoc ,
the Apple Event sent when your application is asked to open one or more
documents (e.g., by drag & drop onto the app or by opening a document of a
type associated to the app). The proc should take as arguments paths to the
files to be opened, like so:
.RS
.PP
.CS
proc ::tk::mac::OpenDocument {args} {
    foreach f $args {my_open_document $f}
}
.CE
.RE
.\" COMMAND: PrintDocument
.TP
\fB::tk::mac::PrintDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEPrintDocuments,
.QW pdoc ,
the Apple Event sent when your application is asked to print a
document.  It takes a single absolute file path as an argument.
.\" COMMAND: Quit
.TP
\fB::tk::mac::Quit\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEQuitApplication,
.QW quit ,
the Apple Event sent when your application is asked to be quit, e.g. via the
quit menu item in the application menu, the quit menu item in the Dock menu,
or during a logout/restart/shutdown etc. If this is not defined, \fBexit\fR is
called instead.
.\" COMMAND: OnHide
.TP
\fB::tk::mac::OnHide\fR
.
If defined, this is called when your application receives a kEventAppHidden
event, e.g. via the hide menu item in the application or Dock menus.
.\" COMMAND: OnShow
.TP
\fB::tk::mac::OnShow\fR
.
If defined, this is called when your application receives a kEventAppShown
event, e.g. via the show all menu item in the application menu, or by clicking
the Dock icon of a hidden application.
.\" COMMAND: ShowHelp
.TP
\fB::tk::mac::ShowHelp\fR
.
Customizes behavior of Apple Help menu; if this procedure is not defined, the
platform-specific standard Help menu item
.QW "YourApp Help"
performs the default Cocoa action of showing the Help Book configured in the
application's Info.plist (or displaying an alert if no Help Book is
set).
.\" COMMAND: PerformService
.TP
\fB::tk::mac::PerformService\fR
.
Executes a Tcl procedure called from the macOS
.QW Services
menu in the Application menu item. The
.QW Services
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223




224
225



226
227
228
229

230
231
232
233
234

235
236
237
238
239

240
241
242
243
244
245

246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
the application's Info.plist file. The underlying code supporting this
command also allows the text, entry and ttk::entry widgets to access
services from other applications via the Services menu. The NSPortName
key in Wish's Info.plist file is currently set as
.QW "Wish"
; if a developer changes the name of the Wish executable to something
  else, this key should be modified with the same name.

.TP
\fB::tk::mac::LaunchURL \fIURL...\fR
.
If defined, launches a URL within Tk. This would be used if a Tk
application wants to handle a URL itself, such as displaying data from
an RSS feed, rather than launching a default application to handle the
URL, although it can defined as such. Wish includes a stub URL scheme
of
.QW foo://
in the CFBundleURLSchemes key of its Info.plist file; this should be customized for the specific URL
scheme the developer wants to support.
.TP
\fB::tk::mac::GetAppPath\fR
.
Returns the current applications's file path.
.TP


.SH "ADDITIONAL DIALOGS"
.PP
The Aqua/Mac OS X defines additional dialogs that applications should
support.

.TP
\fB::tk::mac::standardAboutPanel\fR
.
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
Info.plist keys and app bundle files used by the about panel.



.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
.
Preserves compatibility with older Tk/Aqua metrics; set to \fBfalse\fR for
more native spacing.

.TP
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
.
Sets the antialiasing limit; lines thinner that \fIlimit\fR pixels will not be
antialiased. Integer, set to 0 by default, making all lines be antialiased.

.TP
\fB::tk::mac::antialiasedtext \fInumber\fR
.
Sets anti-aliased text.  Controls text antialiasing, possible values for
\fInumber\fR are -1 (default, use system default for text AA), 0 (no text AA),
1 (use text AA).

.TP
\fB::tk::mac::useThemedToplevel \fIboolean\fR
.
Sets toplevel windows to draw with the modern grayish/ pinstripe Mac
background. Equivalent to configuring the toplevel with
.QW "\fB\-background systemWindowHeaderBackground\fR" ,
or to using a \fBttk::frame\fR.
.SH "SUPPORT COMMANDS"

.TP
\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.
Renders native icons and bitmaps in Tk applications (including any image file
readable by NSImage). A native bitmap name is interpreted as follows (in
order):
.RS







>









|
|





<
<




>



|
|
|
>
>
>
>
|
<
>
>
>




>





>





>






>








>







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223


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

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
the application's Info.plist file. The underlying code supporting this
command also allows the text, entry and ttk::entry widgets to access
services from other applications via the Services menu. The NSPortName
key in Wish's Info.plist file is currently set as
.QW "Wish"
; if a developer changes the name of the Wish executable to something
  else, this key should be modified with the same name.
.\" COMMAND: LaunchURL
.TP
\fB::tk::mac::LaunchURL \fIURL...\fR
.
If defined, launches a URL within Tk. This would be used if a Tk
application wants to handle a URL itself, such as displaying data from
an RSS feed, rather than launching a default application to handle the
URL, although it can defined as such. Wish includes a stub URL scheme
of
.QW foo://
in the CFBundleURLSchemes key of its Info.plist file; this should be
customized for the specific URL scheme the developer wants to support.
.TP
\fB::tk::mac::GetAppPath\fR
.
Returns the current applications's file path.
.TP


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

for more details. A hook is also provided for a custom About dialog.  If a Tcl
proc named tkAboutDialog is defined in the main interpreter then that
procedure will be called instead of opening the standardAboutPanel.
.SH "SYSTEM CONFIGURATION"
.PP
There are a number of additional global configuration options that control the
details of how Tk renders by default.
.\" COMMAND: useCompatibilityMetrics
.TP
\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
.
Preserves compatibility with older Tk/Aqua metrics; set to \fBfalse\fR for
more native spacing.
.\" COMMAND: CGAntialiasLimit
.TP
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
.
Sets the antialiasing limit; lines thinner that \fIlimit\fR pixels will not be
antialiased. Integer, set to 0 by default, making all lines be antialiased.
.\" COMMAND: antialiasedtext
.TP
\fB::tk::mac::antialiasedtext \fInumber\fR
.
Sets anti-aliased text.  Controls text antialiasing, possible values for
\fInumber\fR are -1 (default, use system default for text AA), 0 (no text AA),
1 (use text AA).
.\" COMMAND: useThemedToplevel
.TP
\fB::tk::mac::useThemedToplevel \fIboolean\fR
.
Sets toplevel windows to draw with the modern grayish/ pinstripe Mac
background. Equivalent to configuring the toplevel with
.QW "\fB\-background systemWindowHeaderBackground\fR" ,
or to using a \fBttk::frame\fR.
.SH "SUPPORT COMMANDS"
.\" COMMAND: iconBitmap
.TP
\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.
Renders native icons and bitmaps in Tk applications (including any image file
readable by NSImage). A native bitmap name is interpreted as follows (in
order):
.RS
268
269
270
271
272
273
274

275
276
277
278

279
280
281
282

283
284
285
286

287
288
289
290

291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
.IP \(bu 3
NSImage url string
.IP \(bu 3
4-char OSType of IconServices icon
.PP
The \fIwidth\fR and \fIheight\fR arguments to \fBtk::mac::iconBitmap\fR define
the dimensions of the image to create, and \fI\-kind\fR must be one of:

.TP
\fB\-file\fR
.
icon of file at given path

.TP
\fB\-fileType\fR
.
icon of given file type

.TP
\fB\-osType\fR
.
icon of given 4-char OSType file type

.TP
\fB\-systemType\fR
.
icon for given IconServices 4-char OSType

.TP
\fB\-namedImage\fR
.
named NSImage for given name

.TP
\fB\-imageFile\fR
.
image at given path
.RE
.SH "SEE ALSO"
bind(n), wm(n)
.SH KEYWORDS
about dialog, antialiasing, Apple event, icon, NSImage
'\" Local Variables:
'\" mode: nroff
'\" End:







>




>




>




>




>




>












290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
.IP \(bu 3
NSImage url string
.IP \(bu 3
4-char OSType of IconServices icon
.PP
The \fIwidth\fR and \fIheight\fR arguments to \fBtk::mac::iconBitmap\fR define
the dimensions of the image to create, and \fI\-kind\fR must be one of:
.\" OPTION: -file
.TP
\fB\-file\fR
.
icon of file at given path
.\" OPTION: -fileType
.TP
\fB\-fileType\fR
.
icon of given file type
.\" OPTION: -osType
.TP
\fB\-osType\fR
.
icon of given 4-char OSType file type
.\" OPTION: -systemType
.TP
\fB\-systemType\fR
.
icon for given IconServices 4-char OSType
.\" OPTION: -namedImage
.TP
\fB\-namedImage\fR
.
named NSImage for given name
.\" OPTION: -imageFile
.TP
\fB\-imageFile\fR
.
image at given path
.RE
.SH "SEE ALSO"
bind(n), wm(n)
.SH KEYWORDS
about dialog, antialiasing, Apple event, icon, NSImage
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/tkerror.n.

14
15
16
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31
32
33
34
.SH SYNOPSIS
\fBtkerror \fImessage\fR
.BE
.SH DESCRIPTION
.PP
Note: as of Tk 4.1 the \fBtkerror\fR command has been renamed to
\fBbgerror\fR because the event loop (which is what usually invokes


it) is now part of Tcl.  For backward compatibility
the \fBbgerror\fR provided by the current Tk version still
tries to call \fBtkerror\fR if there is one (or an auto loadable one),
so old script defining that error handler should still work, but you
should anyhow modify your scripts to use \fBbgerror\fR instead
of \fBtkerror\fR because that support for the old name might vanish
in the near future. If that call fails, \fBbgerror\fR
posts a dialog showing the error and offering to see the stack trace
to the user. If you want your own error management you should
directly override \fBbgerror\fR instead of \fBtkerror\fR.
Documentation for \fBbgerror\fR is available as part of Tcl's
documentation.
.SH KEYWORDS
background error, reporting







>
>
|





|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.SH SYNOPSIS
\fBtkerror \fImessage\fR
.BE
.SH DESCRIPTION
.PP
Note: as of Tk 4.1 the \fBtkerror\fR command has been renamed to
\fBbgerror\fR because the event loop (which is what usually invokes
it) is now part of Tcl.  Using the \fBtkerror\fR name is deprecated.
.PP
For backward compatibility
the \fBbgerror\fR provided by the current Tk version still
tries to call \fBtkerror\fR if there is one (or an auto loadable one),
so old script defining that error handler should still work, but you
should anyhow modify your scripts to use \fBbgerror\fR instead
of \fBtkerror\fR because that support for the old name might vanish
in the future. If that call fails, \fBbgerror\fR
posts a dialog showing the error and offering to see the stack trace
to the user. If you want your own error management you should
directly override \fBbgerror\fR instead of \fBtkerror\fR.
Documentation for \fBbgerror\fR is available as part of Tcl's
documentation.
.SH KEYWORDS
background error, reporting

Changes to doc/tkvars.n.

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

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

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





































55
56
57
58
59
60
61
62
63

64
























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

79
80
81
82
83
84
85


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

99
100
101
102
103
104
105
106
107
108
109
110
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tkvars n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
geometry, tk_library, tk_patchLevel, tk_strictMotif, tk_version \- Variables used or set by Tk
.BE
.SH DESCRIPTION
.PP
The following Tcl variables are either set or used by Tk at various times
in its execution:

.TP 15
\fBtk_library\fR
.
This variable holds the file name for a directory containing a library
of Tcl scripts related to Tk.  These scripts include an initialization
file that is normally processed whenever a Tk application starts up,
plus other files containing procedures that implement default behaviors
for widgets.
.RS
.PP
The initial value of \fBtcl_library\fR is set when Tk is added to
an interpreter;  this is done by searching several different directories
until one is found that contains an appropriate Tk startup script.
If the \fBTK_LIBRARY\fR environment variable exists, then
the directory it names is checked first.
If \fBTK_LIBRARY\fR is not set or does not refer to an appropriate
directory, then Tk checks several other directories based on a
compiled-in default location, the location of the Tcl library directory,
the location of the binary containing the application, and the current
working directory.
.PP
The variable can be modified by an application to switch to a different
library.
.RE

.TP
\fBtk_patchLevel\fR
.
Contains a dot-separated sequence of decimal integers giving the
current patch level for Tk.
The patch level is incremented for each new release or patch, and
it uniquely identifies an official version of Tk.
.RS
.PP
This value is normally the same as the result of
.QW "\fBpackage require\fR \fBTk\fR" .
.RE





































.TP
\fBtk_strictMotif\fR
.
This variable is set to zero by default.
If an application sets it to one, then Tk attempts to adhere as
closely as possible to Motif look-and-feel standards.
For example, active elements such as buttons and scrollbar
sliders will not change color when the pointer passes over them.
Modern applications should not normally set this variable.

.TP 15
























\fBtk_version\fR
.
Tk sets this variable in the interpreter for each application.
The variable holds the current version number of the Tk
library in the form \fImajor\fR.\fIminor\fR.  \fIMajor\fR and
\fIminor\fR are integers.  The major version number increases in
any Tk release that includes changes that are not backward compatible
(i.e. whenever existing Tk applications and scripts may have to change to
work with the new release).  The minor version number increases with
each new release of Tk, except that it resets to zero whenever the
major version number changes.
.SS "INTERNAL AND DEBUGGING VARIABLES"
.PP
These variables should not normally be set by user code.

.TP
\fBtk::Priv\fR
.
This variable is an array containing several pieces of information
that are private to Tk.  The elements of \fBtk::Priv\fR are used by
Tk library procedures and default bindings.
They should not be accessed by any code outside Tk.


.TP
\fBtk_textRedraw\fR
.TP
\fBtk_textRelayout\fR
.
These variables are set by text widgets when they have debugging
turned on.  The values written to these variables can be used to
test or debug text widget operations.  These variables are mostly
used by Tk's test suite.
.SH "OTHER GLOBAL VARIABLES"
The following variables are only guaranteed to exist in \fBwish\fR
executables; the Tk library does not define them itself but many Tk
environments do.

.TP 6
\fBgeometry\fR
.
If set, contains the user-supplied geometry specification to use for
the main Tk window.
.SH "SEE ALSO"
package(n), tclvars(n), wish(1)
.SH KEYWORDS
environment, text, variables, version
'\" Local Variables:
'\" mode: nroff
'\" End:












|





>










|













>










|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














>







>
>













>
|











1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tkvars n 4.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
geometry, tk_library, tk_patchLevel, tk::scalingPct, tk_strictMotif, tk::svgFmt, tk_version \- Variables used or set by Tk
.BE
.SH DESCRIPTION
.PP
The following Tcl variables are either set or used by Tk at various times
in its execution:
.\" VARIABLE: tk_library
.TP 15
\fBtk_library\fR
.
This variable holds the file name for a directory containing a library
of Tcl scripts related to Tk.  These scripts include an initialization
file that is normally processed whenever a Tk application starts up,
plus other files containing procedures that implement default behaviors
for widgets.
.RS
.PP
The initial value of \fBtk_library\fR is set when Tk is added to
an interpreter;  this is done by searching several different directories
until one is found that contains an appropriate Tk startup script.
If the \fBTK_LIBRARY\fR environment variable exists, then
the directory it names is checked first.
If \fBTK_LIBRARY\fR is not set or does not refer to an appropriate
directory, then Tk checks several other directories based on a
compiled-in default location, the location of the Tcl library directory,
the location of the binary containing the application, and the current
working directory.
.PP
The variable can be modified by an application to switch to a different
library.
.RE
.\" VARIABLE: tk_patchLevel
.TP
\fBtk_patchLevel\fR
.
Contains a dot-separated sequence of decimal integers giving the
current patch level for Tk.
The patch level is incremented for each new release or patch, and
it uniquely identifies an official version of Tk.
.RS
.PP
This value is normally the same as the result of
.QW "\fBpackage require\fR \fBtk\fR" .
.RE
.\" VARIABLE: scalingPct
.TP
\fBtk::scalingPct\fR
.
Tk sets this variable at initialization time to the scaling percentage
corresponding to the display's DPI scaling level.  This value is at least
100 and is restricted to multiples of 25 (100, 125, 150, 175, 200,
225, ...).  The sizes and various attributes of the Tk core and Ttk
widgets and their components, as well as the sizes of the images used by
Tk are chosen according to the scaling percentage, and this is
recommended for applications and library packages, too.
.RS
.PP
Note that any access to this variable is supposed to be strictly
read-only!  Note also that whenever the scaling factor used to convert
between physical units and pixels is changed via \fBtk scaling\fR, the
value of the variable \fBtk::scalingPct\fR is automatically updated.
.PP
On the windowing systems \fBwin32\fR and \fBaqua\fR the scaling
percentage is computed by rounding [\fBtk scaling\fR] * 75 to the
nearest multiple of 25 that is at least 100.  (On \fBaqua\fR the result
is always 100, and the desktop engine automatically scales everything as
needed.)  On \fBx11\fR, deriving the scaling percentage from
[\fBtk scaling\fR] is done as fallback method only, because the
implementation of display scaling is highly dependent on the desktop
environment and it mostly manipulates system resources that are resident
outside of Xlib, which Tk is based on.  Moreover, for technical reasons,
the value assigned to the variable \fBtk::scalingPct\fR can be different
from the one selected in the system settings (e.g., 200 rather than 125,
150, or 175 when running GNOME on Xorg or the Cinnamon desktop).  On
\fBx11\fR the scaling percentage is computed mostly (but not
exclusively) from the value of the X resource Xft.dpi, and, as an
additional step, Tk synchronizes the scaling factor used to convert
between physical units and pixels with the scaling percentage, with the
aid of the \fBtk scaling\fR command.
.RE
.\" VARIABLE: tk_strictMotif
.TP
\fBtk_strictMotif\fR
.
This variable is set to zero by default.
If an application sets it to one, then Tk attempts to adhere as
closely as possible to Motif look-and-feel standards.
For example, active elements such as buttons and scrollbar
sliders will not change color when the pointer passes over them.
Modern applications should not normally set this variable.
.\" VARIABLE: svgFmt
.TP
\fBtk::svgFmt\fR
.
This variable is set at Tk initialization time to
.RS
.RS 4
.PP
[\fBlist svg \-scale\fR [\fBexpr\fR {$\fBtk::scalingPct\fR / 100.0}]]
.RE
.PP
Typical values are {\fBsvg \-scale\fR 1.0}, {\fBsvg \-scale\fR 1.25},
{\fBsvg \-scale\fR 2.0}, etc.  It is recommended to pass the value of
this variable to the commands \fBimage create photo\fR, \fIimageName\fB
configure\fR, \fIimageName\fB put\fR, and \fIimageName\fB read\fR as the
value of their \fB\-format\fR option when creating or manipulating SVG
images, to make sure that their sizes will correspond to the display's
DPI scaling level.
.PP
Note that any access to this variable is supposed to be strictly
read-only!  Note also that whenever the scaling factor used to convert
between physical units and pixels is changed via \fBtk scaling\fR, the
value of the variable \fBtk::svgFmt\fR is automatically updated.
.RE
.\" VARIABLE: tk_version
.TP
\fBtk_version\fR
.
Tk sets this variable in the interpreter for each application.
The variable holds the current version number of the Tk
library in the form \fImajor\fR.\fIminor\fR.  \fIMajor\fR and
\fIminor\fR are integers.  The major version number increases in
any Tk release that includes changes that are not backward compatible
(i.e. whenever existing Tk applications and scripts may have to change to
work with the new release).  The minor version number increases with
each new release of Tk, except that it resets to zero whenever the
major version number changes.
.SS "INTERNAL AND DEBUGGING VARIABLES"
.PP
These variables should not normally be set by user code.
.\" VARIABLE: Priv
.TP
\fBtk::Priv\fR
.
This variable is an array containing several pieces of information
that are private to Tk.  The elements of \fBtk::Priv\fR are used by
Tk library procedures and default bindings.
They should not be accessed by any code outside Tk.
.\" VARIABLE: tk_textRedraw
.\" VARIABLE: tk_textRelayout
.TP
\fBtk_textRedraw\fR
.TP
\fBtk_textRelayout\fR
.
These variables are set by text widgets when they have debugging
turned on.  The values written to these variables can be used to
test or debug text widget operations.  These variables are mostly
used by Tk's test suite.
.SH "OTHER GLOBAL VARIABLES"
The following variables are only guaranteed to exist in \fBwish\fR
executables; the Tk library does not define them itself but many Tk
environments do.
.\" VARIABLE: geometry
.TP
\fBgeometry\fR
.
If set, contains the user-supplied geometry specification to use for
the main Tk window.
.SH "SEE ALSO"
package(n), tclvars(n), wish(1)
.SH KEYWORDS
environment, text, variables, version
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/tkwait.n.

8
9
10
11
12
13
14

15
16
17
18
19

20
21
22
23
24
25

26
27
28

29
30
31
32
33
34

35
36
37
38
39
40
41
.TH tkwait n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkwait \- Wait for variable to change or window to be destroyed
.SH SYNOPSIS

\fBtkwait variable \fIname\fR
.sp
\fBtkwait visibility \fIname\fR
.sp
\fBtkwait window \fIname\fR

.BE
.SH DESCRIPTION
.PP
The \fBtkwait\fR command waits for one of several things to happen,
then it returns without taking any other actions.
The return value is always an empty string.

If the first argument is \fBvariable\fR (or any abbreviation of
it) then the second argument is the name of a global variable and the
command waits for that variable to be modified.

If the first argument is \fBvisibility\fR (or any abbreviation
of it) then the second argument is the name of a window and the
\fBtkwait\fR command waits for a change in its
visibility state (as indicated by the arrival of a VisibilityNotify
event).  This form is typically used to wait for a newly-created
window to appear on the screen before taking some action.

If the first argument is \fBwindow\fR (or any abbreviation
of it) then the second argument is the name of a window and the
\fBtkwait\fR command waits for that window to be destroyed.
This form is typically used to wait for a user to finish interacting
with a dialog box before using the result of that interaction.
.PP
While the \fBtkwait\fR command is waiting it processes events in







>

<

<

>






>



>






>







8
9
10
11
12
13
14
15
16

17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
.TH tkwait n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tkwait \- Wait for variable to change or window to be destroyed
.SH SYNOPSIS
.nf
\fBtkwait variable \fIname\fR

\fBtkwait visibility \fIname\fR

\fBtkwait window \fIname\fR
.fi
.BE
.SH DESCRIPTION
.PP
The \fBtkwait\fR command waits for one of several things to happen,
then it returns without taking any other actions.
The return value is always an empty string.
.\" METHOD: variable
If the first argument is \fBvariable\fR (or any abbreviation of
it) then the second argument is the name of a global variable and the
command waits for that variable to be modified.
.\" METHOD: visibility
If the first argument is \fBvisibility\fR (or any abbreviation
of it) then the second argument is the name of a window and the
\fBtkwait\fR command waits for a change in its
visibility state (as indicated by the arrival of a VisibilityNotify
event).  This form is typically used to wait for a newly-created
window to appear on the screen before taking some action.
.\" METHOD: window
If the first argument is \fBwindow\fR (or any abbreviation
of it) then the second argument is the name of a window and the
\fBtkwait\fR command waits for that window to be destroyed.
This form is typically used to wait for a user to finish interacting
with a dialog box before using the result of that interaction.
.PP
While the \fBtkwait\fR command is waiting it processes events in

Changes to doc/toplevel.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH toplevel n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
toplevel \- Create and manipulate 'toplevel' main and popup window widgets
.SH SYNOPSIS
\fBtoplevel\fR \fIpathName \fR?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH toplevel n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
toplevel \- Create and manipulate 'toplevel' main and popup window widgets
.SH SYNOPSIS
\fBtoplevel\fI pathName \fR?\fIoptions\fR?
.SO
\-borderwidth	\-highlightcolor	\-pady
\-cursor	\-highlightthickness	\-relief
\-highlightbackground	\-padx	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
36
37
38
39
40
41
42
43


44
45
46
47
48
49
50
been created with the \fBimage create\fR command. If specified as the
empty string, no image will be displayed.
.VE "8.7, TIP262"
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.


The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual







|
>
>







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. 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
142
143
144
145
146
147
148

149
150
151
152
153
154
155

156
157
158
159
160
161
162
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the toplevel widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for toplevel widgets:

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtoplevel\fR
command.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified







>







>







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
\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:
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBtoplevel\fR
command.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified

Changes to doc/ttk_Geometry.3.

96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
\fBTTK_SIDE_RIGHT\fR, or \fBTTK_SIDE_BOTTOM\fR.
.AP unsigned sticky in
A bitmask containing one or more of the bits
\fBTTK_STICK_W\fR (west, or left),
\fBTTK_STICK_E\fR (east, or right),
\fBTTK_STICK_N\fR (north, or top), and
\fBTTK_STICK_S\fR (south, or bottom).
\fBTTK_FILL_X\fR is defined as a synonym for (\fBTTK_STICK_W\fR|\fBTTK_STICK_E\fR),

\fBTTK_FILL_Y\fR is a synonym for (\fBTTK_STICK_N\fR|\fBTTK_STICK_S\fR),
and  \fBTTK_FILL_BOTH\fR
is a synonym for (\fBTTK_FILL_X\fR|\fBTTK_FILL_Y\fR).
See also: \fIgrid(n)\fR.
.AP Tk_Window tkwin in
Window whose screen geometry determines
the conversion between absolute units and pixels.







|
>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
\fBTTK_SIDE_RIGHT\fR, or \fBTTK_SIDE_BOTTOM\fR.
.AP unsigned sticky in
A bitmask containing one or more of the bits
\fBTTK_STICK_W\fR (west, or left),
\fBTTK_STICK_E\fR (east, or right),
\fBTTK_STICK_N\fR (north, or top), and
\fBTTK_STICK_S\fR (south, or bottom).
\fBTTK_FILL_X\fR is defined as a synonym for
(\fBTTK_STICK_W\fR|\fBTTK_STICK_E\fR),
\fBTTK_FILL_Y\fR is a synonym for (\fBTTK_STICK_N\fR|\fBTTK_STICK_S\fR),
and  \fBTTK_FILL_BOTH\fR
is a synonym for (\fBTTK_FILL_X\fR|\fBTTK_FILL_Y\fR).
See also: \fIgrid(n)\fR.
.AP Tk_Window tkwin in
Window whose screen geometry determines
the conversion between absolute units and pixels.

Changes to doc/ttk_button.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::button n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::button \- Widget that issues a command when pressed
.SH SYNOPSIS
\fBttk::button\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::button\fR widget displays a textual label and/or image,
and evaluates a command when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-justify	\-state	\-style












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::button n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::button \- Widget that issues a command when pressed
.SH SYNOPSIS
\fBttk::button\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::button\fR widget displays a textual label and/or image,
and evaluates a command when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-justify	\-state	\-style
44
45
46
47
48
49
50
51


52

53
54

55
56
57
58
59







60
61
62
63
64
65
66
.\" .OP \-foreground foreground Foreground
.\" .OP \-font font Font
.\" .OP \-anchor anchor Anchor
.\" .OP \-relief relief Relief
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR


commands, buttons support the following additional widget commands:

.TP
\fIpathName \fBinvoke\fR

Invokes the command associated with the button.
.SH "STANDARD STYLES"
.PP
\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
themes, which is useful for creating widgets for toolbars.







.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::button\fP is \fBTButton\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBpressed\fP, \fBreadonly\fP.
.PP
\fBTButton\fP styling options configurable with \fBttk::style\fP







|
>
>
|
>


>





>
>
>
>
>
>
>







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
.\" .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 element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
button widgets support the following additional commands:
.\" METHOD: invoke
.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.
.PP
In the Aqua theme there are several other styles which can be used to
produce replicas of many of the different button types that are
discussed in Apple's Human Interface Guidelines.  These include
\fBDisclosureButton\fR, \fBDisclosureTriangle\fR, \fBHelpButton\fR,
\fBImageButton\fR, \fBInlineButton\fR, \fBGradientButton\fR,
\fBRoundedRectButton\fR, and \fBRecessedButton\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::button\fP is \fBTButton\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBpressed\fP, \fBreadonly\fP.
.PP
\fBTButton\fP styling options configurable with \fBttk::style\fP
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-shiftrelief\fP \fIamount\fP
.RS
\fB\-shiftrelief\fP specifies how far the button contents are
shifted down and right in the \fIpressed\fP state.
This action provides additional skeumorphic feedback.
.RE
\fB\-width\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-shiftrelief\fP \fIamount\fP
.RS
\fB\-shiftrelief\fP specifies how far the button contents are
shifted down and right in the \fIpressed\fP state.
This action provides additional skeuomorphic feedback.
.RE
\fB\-width\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.

Changes to doc/ttk_checkbutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::checkbutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::checkbutton \- On/off widget
.SH SYNOPSIS
\fBttk::checkbutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::checkbutton\fR widget is used to show or change a setting.
It has two states, selected and deselected.
The state of the checkbutton may be linked to a Tcl variable.
.SO ttk_widget
\-class	\-compound	\-cursor












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::checkbutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::checkbutton \- On/off widget
.SH SYNOPSIS
\fBttk::checkbutton\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::checkbutton\fR widget is used to show or change a setting.
It has two states, selected and deselected.
The state of the checkbutton may be linked to a Tcl variable.
.SO ttk_widget
\-class	\-compound	\-cursor
33
34
35
36
37
38
39
40


41
42

43
44

45
46
47
48
49
50
51
when the widget is selected.  Defaults to \fB1\fR.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Defaults to the widget pathname if not specified.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR


commands, checkbuttons support the following additional
widget commands:

.TP
\fIpathname\fB invoke\fR

Toggles between the selected and deselected states
and evaluates the associated \fB\-command\fR.
If the widget is currently selected, sets the \fB\-variable\fR
to the \fB\-offvalue\fR and deselects the widget;
otherwise, sets the \fB\-variable\fR to the \fB\-onvalue\fR
Returns the result of the \fB\-command\fR.
.\" Missing: select, deselect, toggle







|
>
>
|
<
>


>







33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
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 element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
checkbutton widgets support the following additional commands:

.\" METHOD: invoke
.TP
\fIpathname\fB invoke\fR
.
Toggles between the selected and deselected states
and evaluates the associated \fB\-command\fR.
If the widget is currently selected, sets the \fB\-variable\fR
to the \fB\-offvalue\fR and deselects the widget;
otherwise, sets the \fB\-variable\fR to the \fB\-onvalue\fR
Returns the result of the \fB\-command\fR.
.\" Missing: select, deselect, toggle

Changes to doc/ttk_combobox.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::combobox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::combobox \- text field with popdown selection list
.SH SYNOPSIS
\fBttk::combobox\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::combobox\fR combines a text field with a pop-down list of values;
the user may select the value of the text field from among the
values in the list.
.SO ttk_widget












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::combobox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::combobox \- text field with popdown selection list
.SH SYNOPSIS
\fBttk::combobox\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::combobox\fR combines a text field with a pop-down list of values;
the user may select the value of the text field from among the
values in the list.
.SO ttk_widget
51
52
53
54
55
56
57
58
59
60
61

62

63
64
65
66
67
68

69
70
71
72


73
74

75
76

77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
.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:
'\".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 \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):
.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"







|
<
|
<
>
|
>
|
<
<
<


>



|
>
>

|
>


>

|
<
<
<
<
<
<
<

|
>

<
<
<
<


|






<
<
<
<
<
<
<







51
52
53
54
55
56
57
58

59

60
61
62
63



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







81
82
83
84




85
86
87
88
89
90
91
92
93







94
95
96
97
98
99
100
.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
In addition to the standard

\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,

\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
combobox widgets support the following additional commands:
.\" METHOD: current



.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, moreover the same simple interpretation as
for the command \fBstring index\fR is supported, with simple integer index
arithmetic and indexing relative to \fBend\fR).
Otherwise, returns the index of the current value in the list of
\fB\-values\fR or \fB{}\fR if the current value does not appear in the list.
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the current value of the combobox.
.\" METHOD: set







.TP
\fIpathName \fBset\fI value\fR
.
Sets the value of the combobox to \fIvalue\fR.




.PP
The combobox widget also supports the following \fBttk::entry\fR
widget commands:
.DS
.ta 5.5c 11c
\fBbbox\fR	\fBdelete\fR	\fBicursor\fR
\fBindex\fR	\fBinsert\fR	\fBselection\fR
\fBxview\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"

Changes to doc/ttk_entry.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'\"
.TH ttk::entry n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::entry \- Editable text field widget
.SH SYNOPSIS
\fBttk::entry\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
An \fBttk::entry\fR widget displays a one-line text string and
allows that string to be edited by the user.
The value of the string may be linked to a Tcl variable
with the \fB\-textvariable\fR option.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'\"
.TH ttk::entry n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::entry \- Editable text field widget
.SH SYNOPSIS
\fBttk::entry\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
An \fBttk::entry\fR widget displays a one-line text string and
allows that string to be edited by the user.
The value of the string may be linked to a Tcl variable
with the \fB\-textvariable\fR option.
133
134
135
136
137
138
139



140
141




142

143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169

170
171

172

173
174

175
176
177
178
179
180
181
182

183

184
185

186
187
188
189
190
191
192
193

194
195
196
197
198

199
200
201
202
203

204
205
206
207

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

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
.LP
Abbreviations may be used for any of the forms above, e.g.\|
.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




The following subcommands are possible for entry widgets:

.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

Clear the selection if it is currently in this widget.
If the selection is not in this widget then the command has no effect.
Returns the empty string.
.TP
\fIpathName \fBselection present\fR

Returns 1 if there is are characters selected in the entry,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart\fR \fIend\fR

Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the 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,







>
>
>


>
>
>
>
|
>


>








|
<
<
<
<
<
<
<


>







>


>

>


>


|
<
<
<


>

>


>


|
<
<
<


>





>





>



|
>






|
<
<
<


>





<
<
<
<
<
<
<
<







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







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



185
186
187
188
189
190
191
192
193
194
195



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



223
224
225
226
227
228
229
230








231
232
233
234
235
236
237
.LP
Abbreviations may be used for any of the forms above, e.g.\|
.QW \fBe\fR
or
.QW \fBsel.l\fR .
In general, out-of-range indices are automatically rounded to the
nearest legal value.
Indexes support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\fR.
.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),
entry widgets support the following additional commands:
.\" METHOD: bbox
.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.
.\" METHOD: delete







.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.
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the entry's string.
.\" METHOD: icursor
.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.
.\" METHOD: index



.TP
\fIpathName \fBindex\fI index\fR
.
Returns the numerical index corresponding to \fIindex\fR.
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fIindex string\fR
.
Insert \fIstring\fR just before the character
indicated by \fIindex\fR.  Returns the empty string.
.\" METHOD: selection



.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
.
Clear the selection if it is currently in this widget.
If the selection is not in this widget then the command has no effect.
Returns the empty string.
.TP
\fIpathName \fBselection present\fR
.
Returns 1 if there is are characters selected in the entry,
0 if nothing is selected.
.TP
\fIpathName \fBselection range \fIstart end\fR
.
Sets the selection to include the characters starting with
the one indexed by \fIstart\fR and ending with the one just
before \fIend\fR.
If \fIend\fR refers to the same character as \fIstart\fR or an
earlier one, then the entry's selection is cleared.
.RE
.\" METHOD: validate



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








.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,
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
.RE
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Some themes use a graphical background and their field background colors cannot be changed.

.RE
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br







|
>







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
.RE
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Some themes use a graphical background and their field background colors
cannot be changed.
.RE
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-insertcolor\fP \fIcolor\fP
.br
\fB\-insertwidth\fP \fIamount\fP
.br

Changes to doc/ttk_frame.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::frame n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::frame \- Simple container widget
.SH SYNOPSIS
\fBttk::frame\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::frame\fR widget is a container, used to group other widgets
together.
.SO ttk_widget
\-class	\-cursor	\-padding	\-style
\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-borderwidth borderWidth BorderWidth
The desired width of the widget border.  Defaults to 0.
May be ignored depending on the theme used.
.OP \-relief relief Relief
One of the standard Tk border styles:
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
\fBsolid\fR, or \fBsunken\fR.
Defaults to \fBflat\fR.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;

see \fIttk::widget(n)\fR.
.SH "NOTES"
.PP
Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers
are used to manage the children of the \fBframe\fR,
by the GM's requested size will normally take precedence
over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options.
\fBpack propagate\fR and \fBgrid propagate\fR can be used












|






|
|
















|
|
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::frame n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::frame \- Simple container widget
.SH SYNOPSIS
\fBttk::frame\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::frame\fR widget is a container, used to group other widgets
together.
.SO ttk_widget
\-class	\-cursor	\-padding
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-borderwidth borderWidth BorderWidth
The desired width of the widget border.  Defaults to 0.
May be ignored depending on the theme used.
.OP \-relief relief Relief
One of the standard Tk border styles:
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
\fBsolid\fR, or \fBsunken\fR.
Defaults to \fBflat\fR.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
.SH "WIDGET COMMAND"
.PP
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_image.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29

30
31
32
33
34
35
36
37
38
39

40
41

42
43

44
45

46
47
48
49
50
51
52
53
54
55
56

57
58

59
60
61
62
63
64
65

66
67

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



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk_image n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_image \- Define an element based on an image
.SH SYNOPSIS
\fBttk::style element create \fIname\fR \fBimage\fR \fIimageSpec\fR ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fIimage\fR element factory creates a new element
in the current theme whose visual appearance is determined
by Tk images.
\fIimageSpec\fP is a list of one or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR
pairs specifying other images to use when the element is
in a particular state or combination of states.
.SH OPTIONS
.PP
Valid \fIoptions\fR are:

.TP
\fB\-border\fR \fIpadding\fR

\fIpadding\fR is a list of up to four integers, specifying
the left, top, right, and bottom borders, respectively.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right border;
a list of two numbers specify the horizontal and the vertical border;
a single number specifies the same border all the way around the element.
See \fBIMAGE STRETCHING\fR, below.

.TP
\fB\-height \fIheight\fR

Specifies a minimum height for the element.
If less than zero, the base image's height is used as a default.

.TP
\fB\-padding\fR \fIpadding\fR

Specifies the element's interior padding.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
Defaults to \fB\-border\fR if not specified.

.TP
\fB\-sticky\fR \fIspec\fR

Specifies how the image is placed within the final parcel.
\fIspec\fR contains zero or more characters
.QW n ,
.QW s ,
.QW w ,
or
.QW e .

.TP
\fB\-width \fIwidth\fR

Specifies a minimum width for the element.
If less than zero, the base image's width is used as a default.
.SH "IMAGE STRETCHING"
.PP
If the element's allocated parcel is larger than the image,
the image will be placed in the parcel based on the \fB\-sticky\fR option.
If the image needs to stretch horizontally (i.e., \fB\-sticky ew\fR)
or vertically (\fB\-sticky ns\fR),
subregions of the image are replicated to fill the parcel
based on the \fB\-border\fR option.
The \fB\-border\fR divides the image into 9 regions:
four fixed corners, top and left edges (which may be tiled horizontally),
left and right edges (which may be tiled vertically),
and the central area (which may be tiled in both directions).



.SH "EXAMPLE"
.PP
.CS
set img1 [image create photo \-file button.png]
set img2 [image create photo \-file button-pressed.png]
set img3 [image create photo \-file button-active.png]
style element create Button.button image \e
    [list $img1  pressed $img2  active $img3] \e
    \-border {2 4} \-sticky we
.CE
.SH "SEE ALSO"
ttk::intro(n), ttk::style(n), ttk_vsapi(n), image(n), photo(n)
.SH KEYWORDS
style, theme, appearance, pixmap theme, image
'\" Local Variables:
'\" mode: nroff
'\" End:












|














>

|
>






|
|


>


>


>

|
>







|
|


>

|
>







>


>














>
>
>



|
|
|
|

|








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk_image n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_image \- Define an element based on an image
.SH SYNOPSIS
\fBttk::style element create \fIname \fBimage\fI imageSpec\fR ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fIimage\fR element factory creates a new element
in the current theme whose visual appearance is determined
by Tk images.
\fIimageSpec\fP is a list of one or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR
pairs specifying other images to use when the element is
in a particular state or combination of states.
.SH OPTIONS
.PP
Valid \fIoptions\fR are:
.\" OPTION: -border
.TP
\fB\-border\fI padding\fR
.
\fIpadding\fR is a list of up to four integers, specifying
the left, top, right, and bottom borders, respectively.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right
border; a list of two numbers specify the horizontal and the vertical border;
a single number specifies the same border all the way around the element.
See \fBIMAGE STRETCHING\fR, below.
.\" OPTION: -height
.TP
\fB\-height \fIheight\fR
.
Specifies a minimum height for the element.
If less than zero, the base image's height is used as a default.
.\" OPTION: -padding
.TP
\fB\-padding\fI padding\fR
.
Specifies the element's interior padding.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right
padding; a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
Defaults to \fB\-border\fR if not specified.
.\" OPTION: -sticky
.TP
\fB\-sticky\fI spec\fR
.
Specifies how the image is placed within the final parcel.
\fIspec\fR contains zero or more characters
.QW n ,
.QW s ,
.QW w ,
or
.QW e .
.\" OPTION: -width
.TP
\fB\-width \fIwidth\fR
.
Specifies a minimum width for the element.
If less than zero, the base image's width is used as a default.
.SH "IMAGE STRETCHING"
.PP
If the element's allocated parcel is larger than the image,
the image will be placed in the parcel based on the \fB\-sticky\fR option.
If the image needs to stretch horizontally (i.e., \fB\-sticky ew\fR)
or vertically (\fB\-sticky ns\fR),
subregions of the image are replicated to fill the parcel
based on the \fB\-border\fR option.
The \fB\-border\fR divides the image into 9 regions:
four fixed corners, top and left edges (which may be tiled horizontally),
left and right edges (which may be tiled vertically),
and the central area (which may be tiled in both directions).
.PP
An image element that is not meant to claim any space (for example when used
as a background image) should use \fB\-width 0\fR and \fB\-height 0\fR.
.SH "EXAMPLE"
.PP
.CS
set img1 [image create photo -file button.png]
set img2 [image create photo -file button-pressed.png]
set img3 [image create photo -file button-active.png]
ttk::style element create Button.button image \e
    [list $img1  pressed $img2  active $img3] \e
    -border {2 4} -sticky we
.CE
.SH "SEE ALSO"
ttk::intro(n), ttk::style(n), ttk_vsapi(n), image(n), photo(n)
.SH KEYWORDS
style, theme, appearance, pixmap theme, image
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_intro.n.

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
the side specified by the \fB\-side\fR option,
and placed within the parcel according to the \fB\-sticky\fR
option.
For example, the layout for a horizontal scrollbar is:
.PP
.CS
ttk::\fBstyle layout\fR Horizontal.TScrollbar {
    Scrollbar.trough \-children {
	Scrollbar.leftarrow \-side left \-sticky w
	Scrollbar.rightarrow \-side right \-sticky e
	Scrollbar.thumb \-sticky ew
    }
}
.CE
.PP
By default, the layout for a widget is the same as its class name.
Some widgets may override this (for example, the \fBttk::scrollbar\fR
widget chooses different layouts based on the \fB\-orient\fR option).







|
|
|
|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
the side specified by the \fB\-side\fR option,
and placed within the parcel according to the \fB\-sticky\fR
option.
For example, the layout for a horizontal scrollbar is:
.PP
.CS
ttk::\fBstyle layout\fR Horizontal.TScrollbar {
    Scrollbar.trough -children {
	Scrollbar.leftarrow  -side left  -sticky w
	Scrollbar.rightarrow -side right -sticky e
	Scrollbar.thumb -sticky ew
    }
}
.CE
.PP
By default, the layout for a widget is the same as its class name.
Some widgets may override this (for example, the \fBttk::scrollbar\fR
widget chooses different layouts based on the \fB\-orient\fR option).
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
which specifies values for element options.
Style names use a recursive dotted notation like layouts and elements;
by default, widgets use the class name to look up a style in the current theme.
For example:
.PP
.CS
ttk::\fBstyle configure\fR TButton \e
	\-background #d9d9d9 \e
	\-foreground black \e
	\-relief raised \e
	;
.CE
.PP
Many elements are displayed differently depending on the widget state.
For example, buttons have a different background when they are active,
a different foreground when disabled, and a different relief when pressed.
The \fBstyle map\fR command specifies dynamic option settings
for a particular style:
.PP
.CS
ttk::\fBstyle map\fR TButton \e
	\-background [list disabled #d9d9d9  active #ececec] \e
	\-foreground [list disabled #a3a3a3] \e
	\-relief [list {pressed !disabled} sunken] \e
	;
.CE
.SH "SEE ALSO"
ttk::widget(n), ttk::style(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|











|
|
|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
which specifies values for element options.
Style names use a recursive dotted notation like layouts and elements;
by default, widgets use the class name to look up a style in the current theme.
For example:
.PP
.CS
ttk::\fBstyle configure\fR TButton \e
	-background #d9d9d9 \e
	-foreground black \e
	-relief raised \e
	;
.CE
.PP
Many elements are displayed differently depending on the widget state.
For example, buttons have a different background when they are active,
a different foreground when disabled, and a different relief when pressed.
The \fBstyle map\fR command specifies dynamic option settings
for a particular style:
.PP
.CS
ttk::\fBstyle map\fR TButton \e
	-background [list disabled #d9d9d9  active #ececec] \e
	-foreground [list disabled #a3a3a3] \e
	-relief [list {pressed !disabled} sunken] \e
	;
.CE
.SH "SEE ALSO"
ttk::widget(n), ttk::style(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_label.n.

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

24
25
26
27
28
29
30
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::label n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::label \- Display a text string and/or image
.SH SYNOPSIS
\fBttk::label\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::label\fR widget displays a textual label and/or image.
The label may be linked to a Tcl variable
to automatically change the displayed text.
.SO ttk_widget
\-anchor	\-class	\-compound	\-cursor
\-font	\-foreground
\-image	\-justify	\-padding	\-state	\-style	\-takefocus

\-text	\-textvariable	\-underline
\-width	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background frameColor FrameColor
The widget's background color.
If unspecified, the theme default is used.












|







|
|
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::label n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::label \- Display a text string and/or image
.SH SYNOPSIS
\fBttk::label\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::label\fR widget displays a textual label and/or image.
The label may be linked to a Tcl variable
to automatically change the displayed text.
.SO ttk_widget
\-anchor	\-class	\-compound
\-cursor	\-font	\-foreground
\-image	\-justify	\-padding
\-state	\-style	\-takefocus
\-text	\-textvariable	\-underline
\-width	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background frameColor FrameColor
The widget's background color.
If unspecified, the theme default is used.
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
Specifies the maximum line length (in pixels).
If this option is less than or equal to zero,
then automatic wrapping is not performed; otherwise
the text is split into lines such that no line is longer
than the specified value.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;

see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::label\fP is \fBTLabel\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTLabel\fP styling options configurable with \fBttk::style\fP







|
|
>
|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
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.

1
2
3
4
5
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) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::labelframe n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::labelframe \- Container widget with optional label
.SH SYNOPSIS
\fBttk::labelframe\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::labelframe\fR widget is a container used to group other widgets
together.  It has an optional label, which may be a plain text string or
another widget.
.SO ttk_widget
\-class	\-cursor	\-padding	\-style
\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.\" XXX: Currently included, but may go away:
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:












|







|
|







1
2
3
4
5
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) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::labelframe n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::labelframe \- Container widget with optional label
.SH SYNOPSIS
\fBttk::labelframe\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::labelframe\fR widget is a container used to group other widgets
together.  It has an optional label, which may be a plain text string or
another widget.
.SO ttk_widget
\-class	\-cursor	\-padding
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.\" XXX: Currently included, but may go away:
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
The underlined character is used for mnemonic activation.
Mnemonic activation for a \fBttk::labelframe\fR
sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;

see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::labelframe\fP is \fBTLabelframe\fP.
The text label
has a class of \fBTLabelframe.Label\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.







|
|
>
|







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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::menubutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::menubutton \- Widget that pops down a menu when pressed
.SH SYNOPSIS
\fBttk::menubutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::menubutton\fR widget displays a textual label and/or image,
and displays a menu when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::menubutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::menubutton \- Widget that pops down a menu when pressed
.SH SYNOPSIS
\fBttk::menubutton\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::menubutton\fR widget displays a textual label and/or image,
and displays a menu when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
To be on the safe side, the menu ought to be a direct child of the
menubutton.
.\" not documented: may go away:
.\" .OP \-anchor anchor Anchor
.\" .OP \-padding padding Pad
.SH "WIDGET COMMAND"
.PP
Menubutton widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR

methods.  No other widget methods are used.
.SH "STANDARD STYLES"
.PP
\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::menubutton\fP is \fBTMenubutton\fP.







|
|
>
|







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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::notebook n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::notebook \- Multi-paned container widget
.SH SYNOPSIS
.nf
\fBttk::notebook\fR \fIpathname \fR?\fIoptions...\fR?
.br
\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::notebook\fR widget manages a collection of windows
and displays a single one at a time.
Each content window is associated with a \fItab\fR,
which the user may select to change the currently-displayed window.













|

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::notebook n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::notebook \- Multi-paned container widget
.SH SYNOPSIS
.nf
\fBttk::notebook\fI pathname \fR?\fIoptions...\fR?
.br
\fIpathname \fBadd\fI window\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fI index window\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::notebook\fR widget manages a collection of windows
and displays a single one at a time.
Each content window is associated with a \fItab\fR,
which the user may select to change the currently-displayed window.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
of the notebook.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-width width Width
If present and greater than zero,
specifies the desired width of the pane area
(not including internal padding).
Otherwise, the maximum width of all panes is used.
.SH "TAB OPTIONS"







|
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
of the notebook.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right
padding; a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-width width Width
If present and greater than zero,
specifies the desired width of the pane area
(not including internal padding).
Otherwise, the maximum width of all panes is used.
.SH "TAB OPTIONS"
97
98
99
100
101
102
103




104







105
106

107
108
109
110
111
112
113
114
115
116
117
118

119
120

121
122

123
124
125
126

127
128

129
130
131
132
133
134

135
136
137

138
139

140
141

142
143
144

145
146

147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174

175
176

177
178
179
180
181
182
183
which identifies the currently-selected tab; or:
.IP \(bu
The literal string
.QW \fBend\fR ,
which returns the number of tabs
(only valid for
.QW "\fIpathname \fBindex\fR" ).




.SH "WIDGET COMMAND"







.TP
\fIpathname \fBadd \fIwindow\fR ?\fIoptions...\fR?

Adds a new tab to the notebook.
See \fBTAB OPTIONS\fR for the list of available \fIoptions\fR.
If \fIwindow\fR is currently managed by the notebook but hidden,
it is restored to its previous position.
.TP
\fIpathname \fBconfigure\fR ?\fIoptions\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBcget \fIoption\fR
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBforget \fItabid\fR

Removes the tab specified by \fItabid\fR,
unmaps and unmanages the associated window.

.TP
\fIpathname \fBhide \fItabid\fR

Hides the tab specified by \fItabid\fR.
The tab will not be displayed, but the associated window
remains managed by the notebook and its configuration remembered.
Hidden tabs may be restored with the \fBadd\fR command.

.TP
\fIpathname \fBidentify\fI component x y\fR

Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify element\fR \fIx y\fR

Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify tab\fR \fIx y\fR

Returns the index of the tab at the specified location.
.RE

.TP
\fIpathname \fBindex \fItabid\fR

Returns the numeric index of the tab specified by \fItabid\fR,
or the total number of tabs if \fItabid\fR is the string
.QW \fBend\fR .

.TP
\fIpathname \fBinsert \fIpos subwindow options...\fR

Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the notebook,
moves it to the specified position.
See \fBTAB OPTIONS\fR for the list of available options.
.TP
\fIpathname \fBinstate \fIstatespec \fR?\fIscript...\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBselect\fR ?\fItabid\fR?

Selects the specified tab.
The associated content window will be displayed,
and the previously-selected window (if different) is unmapped.
If \fItabid\fR is omitted, returns the widget name of the
currently selected pane.
.TP
\fIpathname \fBstate\fR ?\fIstatespec\fR?
See \fIttk::widget(n)\fR.
.TP
\fIpathname \fBtab \fItabid\fR ?\fI\-option \fR?\fIvalue ...\fR

Query or modify the options of the specific tab.
If no \fI\-option\fR is specified,
returns a dictionary of the tab option values.
If one \fI\-option\fR is specified,
returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
See \fBTAB OPTIONS\fR for the available options.

.TP
\fIpathname \fBtabs\fR

Returns the list of windows managed by the notebook, in the index order of
their associated tabs.
.SH "KEYBOARD TRAVERSAL"
To enable keyboard traversal for a toplevel window
containing a notebook widget \fI$nb\fR, call:
.CS
ttk::notebook::enableTraversal $nb







>
>
>
>

>
>
>
>
>
>
>


>




<
<
|

<
<
<

>


>


>




>


>





|
>


|
>


>


>



>


>






|
<
<


>





|
<
<


>







>


>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122


123
124



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171


172
173
174
175
176
177
178
179
180


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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" ).
.PP
Indexes support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\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:
.\" METHOD: add
.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.


.\" METHOD: forget
.TP



\fIpathname \fBforget \fItabid\fR
.
Removes the tab specified by \fItabid\fR,
unmaps and unmanages the associated window.
.\" METHOD: hide
.TP
\fIpathname \fBhide \fItabid\fR
.
Hides the tab specified by \fItabid\fR.
The tab will not be displayed, but the associated window
remains managed by the notebook and its configuration remembered.
Hidden tabs may be restored with the \fBadd\fR command.
.\" METHOD: identify
.TP
\fIpathname \fBidentify\fI component x y\fR
.
Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify element\fI x y\fR
.
Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify tab\fI x y\fR
.
Returns the index of the tab at the specified location.
.RE
.\" METHOD: index
.TP
\fIpathname \fBindex \fItabid\fR
.
Returns the numeric index of the tab specified by \fItabid\fR,
or the total number of tabs if \fItabid\fR is the string
.QW \fBend\fR .
.\" METHOD: insert
.TP
\fIpathname \fBinsert \fIpos subwindow options...\fR
.
Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the notebook,
moves it to the specified position.
See \fBTAB OPTIONS\fR for the list of available options.
.\" METHOD: select


.TP
\fIpathname \fBselect\fR ?\fItabid\fR?
.
Selects the specified tab.
The associated content window will be displayed,
and the previously-selected window (if different) is unmapped.
If \fItabid\fR is omitted, returns the widget name of the
currently selected pane.
.\" METHOD: tab


.TP
\fIpathname \fBtab \fItabid\fR ?\fI\-option \fR?\fIvalue ...\fR
.
Query or modify the options of the specific tab.
If no \fI\-option\fR is specified,
returns a dictionary of the tab option values.
If one \fI\-option\fR is specified,
returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
See \fBTAB OPTIONS\fR for the available options.
.\" METHOD: tabs
.TP
\fIpathname \fBtabs\fR
.
Returns the list of windows managed by the notebook, in the index order of
their associated tabs.
.SH "KEYBOARD TRAVERSAL"
To enable keyboard traversal for a toplevel window
containing a notebook widget \fI$nb\fR, call:
.CS
ttk::notebook::enableTraversal $nb
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
are direct children of the notebook.
.SH "VIRTUAL EVENTS"
The notebook widget generates a \fB<<NotebookTabChanged>>\fR
virtual event after a new tab is selected.
.SH "EXAMPLE"
.CS
pack [\fBttk::notebook\fR .nb]
\&.nb add [frame .nb.f1] \-text "First tab"
\&.nb add [frame .nb.f2] \-text "Second tab"
\&.nb select .nb.f2
ttk::notebook::enableTraversal .nb
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::notebook\fP is \fBTNotebook\fP.  The tab has
a class name of \fBTNotebook.Tab\fP







|
|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
are direct children of the notebook.
.SH "VIRTUAL EVENTS"
The notebook widget generates a \fB<<NotebookTabChanged>>\fR
virtual event after a new tab is selected.
.SH "EXAMPLE"
.CS
pack [\fBttk::notebook\fR .nb]
\&.nb add [frame .nb.f1] -text "First tab"
\&.nb add [frame .nb.f2] -text "Second tab"
\&.nb select .nb.f2
ttk::notebook::enableTraversal .nb
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::notebook\fP is \fBTNotebook\fP.  The tab has
a class name of \fBTNotebook.Tab\fP
228
229
230
231
232
233
234
235








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

















252
253
254
255
256
257














258
259
260
261
262
263
264
265
266
267
268
269
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-tabmargins\fP \fIpadding\fP
.br
\fB\-tabposition\fP \fIside\fP








.br
.PP
\fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-expand\fP \fIpadding\fP
.RS
Defines how much the tab grows in size.  Usually used with the
\fBselected\fP dynamic state.  \fB\-tabmargins\fP should be
set appropriately so that there is room for the tab growth.

















.RE
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP














.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), grid(n)
.SH "KEYWORDS"
pane, tab
'\" Local Variables:
'\" mode: nroff
'\" End:







|
>
>
>
>
>
>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>












246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-tabmargins\fP \fIpadding\fP
.br
\fB\-tabposition\fP \fIposition\fP
.RS
Specifies the position of the tab row or column as a string of length
1 or 2.  The first character indicates the side as \fBn\fP, \fBs\fP,
\fBw\fP, or \fBe\fP, while the second character (if present) is the
sticky bit (specified as \fBw\fP, \fBe\fP, \fBn\fP, or \fBs\fP) within
the tab position.  The default position is \fBn\fP for the \fBaqua\fP
theme and \fBnw\fP for all the other built-in themes.
.RE
.br
.PP
\fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-expand\fP \fIpadding\fP
.RS
Defines how much the tab grows in size.  Usually used with the
\fBselected\fP dynamic state.  \fB\-tabmargins\fP should be
set appropriately so that there is room for the tab growth.
For example, the Ttk library file \fBvistaTheme.tcl\fP contains
the lines
.CS
ttk::style configure TNotebook -tabmargins {2 2 2 0}
ttk::style map TNotebook.Tab -expand {selected {2 2 2 2}}
.CE
which are valid for the default value \fBnw\fP of the \fB\-tabposition\fP
style option.  For a \fBttk::notebook\fP style \fBnbStyle\fP defined by
.CS
set nbStyle SW.TNotebook
ttk::style configure $nbStyle -tabposition sw
.CE
you will have to adapt the above settings as follows:
.CS
ttk::style configure $nbStyle -tabmargins {2 0 2 2}
ttk::style map $nbStyle.Tab -expand {selected {2 2 2 2}}
.CE
.RE
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.RS
Some themes (e.g., \fBclam\fP) use a different \fIpadding\fP for the
selected tab.  For example, the Ttk library file \fBclamTheme.tcl\fP
contains the lines
.CS
ttk::style configure TNotebook.Tab \\
    -padding {4.5p 1.5p 4.5p 1.5p}
ttk::style map TNotebook.Tab \\
    -padding {selected {4.5p 3p 4.5p 1.5p}}
.CE
which are valid for the default value \fBnw\fP of the \fB\-tabposition\fP
style option.  Again, for a different tab position you will have to adapt
the above settings accordingly.
.RE
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), grid(n)
.SH "KEYWORDS"
pane, tab
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_panedwindow.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::panedwindow n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::panedwindow \- Multi-pane container window
.SH SYNOPSIS
.nf
\fBttk::panedwindow\fR \fIpathname \fR?\fIoptions\fR?
.br
\fIpathname \fBadd\fR \fIwindow\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fR \fIindex\fR \fIwindow\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::panedwindow\fR widget displays a number of subwindows,
stacked either vertically or horizontally.
The user may adjust the relative sizes of the subwindows
by dragging the sash between panes.













|

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::panedwindow n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::panedwindow \- Multi-pane container window
.SH SYNOPSIS
.nf
\fBttk::panedwindow\fI pathname \fR?\fIoptions\fR?
.br
\fIpathname \fBadd\fI window\fR ?\fIoptions...\fR?
\fIpathname \fBinsert\fI index window\fR ?\fIoptions...\fR?
.fi
.BE
.SH DESCRIPTION
A \fBttk::panedwindow\fR widget displays a number of subwindows,
stacked either vertically or horizontally.
The user may adjust the relative sizes of the subwindows
by dragging the sash between panes.
44
45
46
47
48
49
50


51

52
53

54
55

56
57

58
59

60
61

62
63

64
65
66
67
68
69
70

71
72
73

74
75

76
77

78
79
80
81
82
83

84
85

86
87
88
89
90
91

92
93

94
95

96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
.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"


Supports the standard \fBconfigure\fR, \fBcget\fR, \fBstate\fR,

and \fBinstate\fR commands; see \fIttk::widget(n)\fR for details.
Additional commands:

.TP
\fIpathname \fBadd \fIsubwindow options...\fR

Adds a new pane to the window.
See \fBPANE OPTIONS\fR for the list of available options.

.TP
\fIpathname \fBforget \fIpane\fR

Removes the specified subpane from the widget.
\fIpane\fR is either an integer index or the name of a managed subwindow.

.TP
\fIpathname \fBidentify \fIcomponent x y\fR

Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
If \fIcomponent\fR is omitted, it defaults to \fBsash\fR.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify element \fIx y\fR

Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify sash \fIx y\fR

Returns the index of the sash at the specified location.
.RE

.TP
\fIpathname \fBinsert \fIpos subwindow options...\fR

Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the paned window,
moves it to the specified position.
See \fBPANE OPTIONS\fR for the list of available options.

.TP
\fIpathname \fBpane \fIpane \-option \fR?\fIvalue \fR?\fI\-option value...\fR

Query or modify the options of the specified \fIpane\fR,
where \fIpane\fR is either an integer index or the name of a managed subwindow.
If no \fI\-option\fR is specified, returns a dictionary of the pane
option values.
If one \fI\-option\fR is specified, returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.

.TP
\fIpathname \fBpanes\fR

Returns the list of all windows managed by the widget, in the index order of
their associated panes.

.TP
\fIpathname \fBsashpos \fIindex\fR ?\fInewpos\fR?

If \fInewpos\fR is specified, sets the position
of sash number \fIindex\fR.
May adjust the positions of adjacent sashes
to ensure that positions are monotonically increasing.
Sash positions are further constrained to be between 0
and the total size of the widget.
.\" Full story: "total size" is either the -height (resp -width),
.\" or the actual window height (resp actual window width),
.\" depending on which changed most recently.
Returns the new position of sash number \fIindex\fR.
.\" Full story: new position may be different than the requested position.
.PP
The panedwindow widget also supports the following generic \fBttk::widget\fR
widget subcommands (see \fIttk::widget(n)\fR for details):
.DS
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR
\fBinstate\fR	\fBstate\fR
.DE
.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts
for <Leave> events when the pointer crosses from a parent to a child. The
panedwindow widget needs to know when that happens.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP.  The
sash has a class name of \fBSash\fP.
.PP
\fBTPanedwindow\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
\fBSash\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-gripcount\fP \fIcount\fP
.br
\fB\-handlepad\fP \fIamount\fP
.br
\fB\-handlesize\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br







>
>
|
>
|
|
>


>


>


>


>


>







>



>


>


>






>


>






>


>


>


>











<
<
<
<
<
<
<
<



|
<
<

















|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127








128
129
130
131


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
.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
\fBcget\fR, \fBconfigure\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
panedwindow widgets support the following additional commands:
.\" METHOD: add
.TP
\fIpathname \fBadd \fIsubwindow options...\fR
.
Adds a new pane to the window.
See \fBPANE OPTIONS\fR for the list of available options.
.\" METHOD: forget
.TP
\fIpathname \fBforget \fIpane\fR
.
Removes the specified subpane from the widget.
\fIpane\fR is either an integer index or the name of a managed subwindow.
.\" METHOD: identify
.TP
\fIpathname \fBidentify \fIcomponent x y\fR
.
Returns the name of the element under the point given by \fIx\fR and \fIy\fR,
or the empty string if no component is present at that location.
If \fIcomponent\fR is omitted, it defaults to \fBsash\fR.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify element \fIx y\fR
.
Returns the name of the element at the specified location.
.TP
\fIpathname \fBidentify sash \fIx y\fR
.
Returns the index of the sash at the specified location.
.RE
.\" METHOD: insert
.TP
\fIpathname \fBinsert \fIpos subwindow options...\fR
.
Inserts a pane at the specified position.
\fIpos\fR is either the string \fBend\fR, an integer index,
or the name of a managed subwindow.
If \fIsubwindow\fR is already managed by the paned window,
moves it to the specified position.
See \fBPANE OPTIONS\fR for the list of available options.
.\" METHOD: pane
.TP
\fIpathname \fBpane \fIpane \-option \fR?\fIvalue \fR?\fI\-option value...\fR
.
Query or modify the options of the specified \fIpane\fR,
where \fIpane\fR is either an integer index or the name of a managed subwindow.
If no \fI\-option\fR is specified, returns a dictionary of the pane
option values.
If one \fI\-option\fR is specified, returns the value of that \fIoption\fR.
Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs.
.\" METHOD: panes
.TP
\fIpathname \fBpanes\fR
.
Returns the list of all windows managed by the widget, in the index order of
their associated panes.
.\" METHOD: sashpos
.TP
\fIpathname \fBsashpos \fIindex\fR ?\fInewpos\fR?
.
If \fInewpos\fR is specified, sets the position
of sash number \fIindex\fR.
May adjust the positions of adjacent sashes
to ensure that positions are monotonically increasing.
Sash positions are further constrained to be between 0
and the total size of the widget.
.\" Full story: "total size" is either the -height (resp -width),
.\" or the actual window height (resp actual window width),
.\" depending on which changed most recently.
Returns the new position of sash number \fIindex\fR.
.\" Full story: new position may be different than the requested position.








.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events.


.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP.  The
sash has a class name of \fBSash\fP.
.PP
\fBTPanedwindow\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
\fBSash\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-gripsize\fP \fIsize\fP (number of screen units)
.br
\fB\-handlepad\fP \fIamount\fP
.br
\fB\-handlesize\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br

Changes to doc/ttk_progressbar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::progressbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::progressbar \- Provide progress feedback
.SH SYNOPSIS
\fBttk::progressbar\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::progressbar\fR widget shows the status of a long-running
operation.  They can operate in two modes: \fIdeterminate\fR mode shows the
amount completed relative to the total amount of work to be done, and
\fIindeterminate\fR mode provides an animated display to let the user know
that something is happening.
.PP
If the value of \fB-orient\fR is \fBhorizontal\fR a text string can be
displayed inside the progressbar. This string can be configured using
the \fB-anchor\fR, \fB-font\fR, \fB-foreground\fR, \fB-justify\fR,
\fB-text\fR and \fB-wraplength\fR options. If the value of \fB-orient\fR
is \fBvertical\fR then these options are ignored.
.SO ttk_widget
\-anchor	\-class	\-cursor
\-font	\-foreground	\-justify	\-style
\-takefocus	\-text	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"












|









|

|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
'\"
'\" Copyright (c) 2005 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::progressbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::progressbar \- Provide progress feedback
.SH SYNOPSIS
\fBttk::progressbar\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::progressbar\fR widget shows the status of a long-running
operation.  They can operate in two modes: \fIdeterminate\fR mode shows the
amount completed relative to the total amount of work to be done, and
\fIindeterminate\fR mode provides an animated display to let the user know
that something is happening.
.PP
If the value of \fB\-orient\fR is \fBhorizontal\fR a text string can be
displayed inside the progressbar. This string can be configured using
the \fB\-anchor\fR, \fB\-font\fR, \fB\-foreground\fR, \fB\-justify\fR,
\fB\-text\fR and \fB\-wraplength\fR options. If the value of \fB\-orient\fR
is \fBvertical\fR then these options are ignored.
.SO ttk_widget
\-anchor	\-class	\-cursor
\-font	\-foreground	\-justify	\-style
\-takefocus	\-text	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83

84
85
86
87
88
89
90
91
92

93
94

95
96

97
98
99
100
101
102
103
.OP \-variable variable Variable
The name of a global Tcl variable which is linked to the \fB\-value\fR.
If specified to an existing variable, the \fB\-value\fR of the progress bar is
automatically set to the value of the variable whenever
the latter is modified.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.

.TP
\fIpathName \fBstart\fR ?\fIinterval\fR?

Begin autoincrement mode:
schedules a recurring timer event that calls \fBstep\fR
every \fIinterval\fR milliseconds.
If omitted, \fIinterval\fR defaults to 50 milliseconds (20 steps/second).
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBstep\fR ?\fIamount\fR?

Increments the \fB\-value\fR by \fIamount\fR.
\fIamount\fR defaults to 1.0 if omitted.

.TP
\fIpathName \fBstop\fR

Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::progressbar\fP is \fBTProgressbar\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP







<
|
<
<
|
<
<
|
<
|
<
<
|
>


>




|
<
<


>


>


>







62
63
64
65
66
67
68

69


70


71

72


73
74
75
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
.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

In addition to the standard


\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,


\fBstate\fR and \fBstyle\fR

commands (see \fBttk::widget\fR),


progressbar widgets support the following additional commands:
.\" METHOD: start
.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).
.\" METHOD: step


.TP
\fIpathName \fBstep\fR ?\fIamount\fR?
.
Increments the \fB\-value\fR by \fIamount\fR.
\fIamount\fR defaults to 1.0 if omitted.
.\" METHOD: stop
.TP
\fIpathName \fBstop\fR
.
Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::progressbar\fP is \fBTProgressbar\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP

Changes to doc/ttk_radiobutton.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::radiobutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::radiobutton \- Mutually exclusive option widget
.SH SYNOPSIS
\fBttk::radiobutton\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
\fBttk::radiobutton\fR widgets are used in groups to show or change
a set of mutually-exclusive options.
Radiobuttons are linked to a Tcl variable,
and have an associated value; when a radiobutton is clicked,












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::radiobutton n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::radiobutton \- Mutually exclusive option widget
.SH SYNOPSIS
\fBttk::radiobutton\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
\fBttk::radiobutton\fR widgets are used in groups to show or change
a set of mutually-exclusive options.
Radiobuttons are linked to a Tcl variable,
and have an associated value; when a radiobutton is clicked,
33
34
35
36
37
38
39
40


41
42

43
44

45
46
47
48
49
50
51
when the widget is selected.
.OP \-variable variable Variable
The name of a global variable whose value is linked to the widget.
Default value is \fB::selectedButton\fR.
.SH "WIDGET COMMAND"
.PP
In addition to the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR


commands, radiobuttons support the following additional
widget commands:

.TP
\fIpathname\fB invoke\fR

Sets the \fB\-variable\fR to the \fB\-value\fR, selects the widget,
and evaluates the associated \fB\-command\fR.
Returns the result of the \fB\-command\fR, or the empty
string if no \fB\-command\fR is specified.
.\" Missing: select, deselect.  Useful?
.\" Missing: flash.  This is definitely not useful.
.SH "WIDGET STATES"







|
>
>
|
<
>


>







33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
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 element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),
radiobutton widgets support the following additional commands:

.\" METHOD: invoke
.TP
\fIpathname\fB invoke\fR
.
Sets the \fB\-variable\fR to the \fB\-value\fR, selects the widget,
and evaluates the associated \fB\-command\fR.
Returns the result of the \fB\-command\fR, or the empty
string if no \fB\-command\fR is specified.
.\" Missing: select, deselect.  Useful?
.\" Missing: flash.  This is definitely not useful.
.SH "WIDGET STATES"

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
100
101
102
103
104
105
106
107
108
109
.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
.
Returns the current value of the specified \fIoption\fR; see


\fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Modify or query widget options; see \fIttk::widget(n)\fR.

.TP
\fIpathName \fBget \fR?\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
Dynamic states: \fBactive\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP







<
|
<
<
>
>
|
<
<
<
|
>






<
<
<
<
<
<
|
<







<
<
<
<


>












|







47
48
49
50
51
52
53

54


55
56
57



58
59
60
61
62
63
64
65






66

67
68
69
70
71
72
73




74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
.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

In addition to the standard


\fBcget\fR, \fBconfigure\fR, \fBidentify element\fR, \fBinstate\fR,
\fBstate\fR and \fBstyle\fR
commands (see \fBttk::widget\fR),



scale widgets support the following additional commands:
.\" METHOD: get
.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.






.\" METHOD: see

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




.SH "INTERNAL COMMANDS"
.PP
.\" METHOD: coords
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Get the coordinates corresponding to \fIvalue\fR, or the coordinates
corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR
is omitted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scale\fP is \fBTScale\fP.
.PP
Dynamic states: \fBactive\fP.
.PP
\fBTScale\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP

Changes to doc/ttk_scrollbar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::scrollbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::scrollbar \- Control the viewport of a scrollable widget
.SH SYNOPSIS
\fBttk::scrollbar\fR \fIpathName \fR?\fIoptions...\fR?
.BE
.SH DESCRIPTION
.PP
\fBttk::scrollbar\fR widgets are typically linked to an associated window
that displays a document of some sort, such as a file being edited or a
drawing.
A scrollbar displays a \fIthumb\fR in the middle portion of the scrollbar,













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::scrollbar n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::scrollbar \- Control the viewport of a scrollable widget
.SH SYNOPSIS
\fBttk::scrollbar\fI pathName \fR?\fIoptions...\fR?
.BE
.SH DESCRIPTION
.PP
\fBttk::scrollbar\fR widgets are typically linked to an associated window
that displays a document of some sort, such as a file being edited or a
drawing.
A scrollbar displays a \fIthumb\fR in the middle portion of the scrollbar,
43
44
45
46
47
48
49
50
51
52
53
54

55


56
57

58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79

80
81

82
83
84
85
86
87
88
89
90

91
92

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

113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
or \fByview\fR (for vertical scrollbars).
.RE
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the scrollbar.
.SH "WIDGET COMMAND"
.PP
.TP
\fIpathName \fBcget \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Modify or query widget options; see \fIttk::widget(n)\fR.


.TP
\fIpathName \fBget\fR

Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.TP
\fIpathName \fBidentify \fIx y\fR
Returns the name of the element at position \fIx\fR, \fIy\fR.
See \fIttk::widget(n)\fR.
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBset \fIfirst last\fR

This command is normally invoked by the scrollbar's associated widget
from an \fB\-xscrollcommand\fR or \fB\-yscrollcommand\fR callback.
Specifies the visible range to be displayed.
\fIfirst\fR and \fIlast\fR are real fractions between 0 and 1.
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.SH "INTERNAL COMMANDS"
.PP
The following widget commands are used internally
by the \fBTScrollbar\fP widget class bindings.

.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR

Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in thumb position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the thumb \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
ignored in this case).
If the scrollbar is vertical, the result indicates how much the
scrollbar setting must change to move the thumb \fIdeltaY\fR pixels
down.  The arguments and the result may be zero or negative.

.TP
\fIpathName \fBfraction \fIx y\fR

Returns a real number between 0 and 1 indicating where the point
given by \fIx\fR and \fIy\fR lies in the trough area of the scrollbar,
where 0.0 corresponds to the top or left of the trough
and 1.0 corresponds to the bottom or right.
\fIX\fR and \fIy\fR are pixel coordinates relative to the scrollbar
widget.
If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest
point in the trough is used.
.SH "SCROLLING COMMANDS"
.PP
When the user interacts with the scrollbar, for example by dragging
the thumb, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like \fB.t yview\fR
.TP
\fIprefix \fBmoveto \fIfraction\fR

\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR

The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR

The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.SH "WIDGET STATES"
.PP
The scrollbar automatically sets the \fBdisabled\fR state bit.
when the entire range is visible (range is 0.0 to 1.0),
and clears it otherwise.
It also sets the \fBactive\fR and \fBpressed\fR state flags
of individual elements, based on the position and state of the mouse pointer.
.SH EXAMPLE
.PP
.CS
set f [frame .f]
ttk::scrollbar $f.hsb \-orient horizontal \-command [list $f.t xview]
ttk::scrollbar $f.vsb \-orient vertical \-command [list $f.t yview]
text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set]
grid $f.t \-row 0 \-column 0 \-sticky nsew
grid $f.vsb \-row 0 \-column 1 \-sticky nsew
grid $f.hsb \-row 1 \-column 0 \-sticky nsew
grid columnconfigure $f 0 \-weight 1
grid rowconfigure $f 0 \-weight 1
pack $f
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scrollbar\fP is \fBTScrollbar\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP.







<
|
<
<
|
>
|
>
>


>


|
<
<
<

<
<
<

>




<
<
<




>


>









>


>




















>









>









>

















|
|
|
|
|
|
|
|







43
44
45
46
47
48
49

50


51
52
53
54
55
56
57
58
59
60
61



62



63
64
65
66
67
68



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
or \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

In addition to the standard


\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:
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the scrollbar settings in the form of a list whose
elements are the arguments to the most recent \fBset\fR widget command.
.\" METHOD: set



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



.SH "INTERNAL COMMANDS"
.PP
The following widget commands are used internally
by the \fBTScrollbar\fP widget class bindings.
.\" METHOD: delta
.TP
\fIpathName \fBdelta \fIdeltaX deltaY\fR
.
Returns a real number indicating the fractional change in
the scrollbar setting that corresponds to a given change
in thumb position.  For example, if the scrollbar is horizontal,
the result indicates how much the scrollbar setting must change
to move the thumb \fIdeltaX\fR pixels to the right (\fIdeltaY\fR is
ignored in this case).
If the scrollbar is vertical, the result indicates how much the
scrollbar setting must change to move the thumb \fIdeltaY\fR pixels
down.  The arguments and the result may be zero or negative.
.\" METHOD: fraction
.TP
\fIpathName \fBfraction \fIx y\fR
.
Returns a real number between 0 and 1 indicating where the point
given by \fIx\fR and \fIy\fR lies in the trough area of the scrollbar,
where 0.0 corresponds to the top or left of the trough
and 1.0 corresponds to the bottom or right.
\fIX\fR and \fIy\fR are pixel coordinates relative to the scrollbar
widget.
If \fIx\fR and \fIy\fR refer to a point outside the trough, the closest
point in the trough is used.
.SH "SCROLLING COMMANDS"
.PP
When the user interacts with the scrollbar, for example by dragging
the thumb, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like \fB.t yview\fR
.TP
\fIprefix \fBmoveto \fIfraction\fR
.
\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
.
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
.
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.SH "WIDGET STATES"
.PP
The scrollbar automatically sets the \fBdisabled\fR state bit.
when the entire range is visible (range is 0.0 to 1.0),
and clears it otherwise.
It also sets the \fBactive\fR and \fBpressed\fR state flags
of individual elements, based on the position and state of the mouse pointer.
.SH EXAMPLE
.PP
.CS
set f [frame .f]
\fBttk::scrollbar\fR $f.hsb -orient horizontal -command [list $f.t xview]
\fBttk::scrollbar\fR $f.vsb -orient vertical -command [list $f.t yview]
text $f.t -xscrollcommand [list $f.hsb set] -yscrollcommand [list $f.vsb set]
grid $f.t -row 0 -column 0 -sticky nsew
grid $f.vsb -row 0 -column 1 -sticky nsew
grid $f.hsb -row 1 -column 0 -sticky nsew
grid columnconfigure $f 0 -weight 1
grid rowconfigure $f 0 -weight 1
pack $f
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scrollbar\fP is \fBTScrollbar\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP.
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP (color of the dark part of the 3D relief)
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-gripcount\fP \fIcount\fP (number of lines on the thumb)
.br
\fB\-lightcolor\fP \fIcolor\fP (color of the light part of the 3D relief)
.br
\fB\-troughcolor\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP







|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP (color of the dark part of the 3D relief)
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-gripsize\fP \fIsize\fP (number of screen units)
.br
\fB\-lightcolor\fP \fIcolor\fP (color of the light part of the 3D relief)
.br
\fB\-troughcolor\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP

Changes to doc/ttk_separator.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::separator n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::separator \- Separator bar
.SH SYNOPSIS
\fBttk::separator\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::separator\fR widget displays a horizontal or vertical separator
bar.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR

methods.  No other widget methods are used.
.PP
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::separator\fP is \fBTSeparator\fP.
.PP
\fBTSeparator\fP styling options configurable with \fBttk::style\fP
are:












|















|
|
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::separator n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::separator \- Separator bar
.SH SYNOPSIS
\fBttk::separator\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::separator\fR widget displays a horizontal or vertical separator
bar.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
'\"
'\" Copyright (c) 2006 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::sizegrip \- Bottom-right corner resize widget
.SH SYNOPSIS
\fBttk::sizegrip\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR)
allows the user to resize the containing toplevel window
by pressing and dragging the grip.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET COMMAND"
.PP
Sizegrip widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR

methods.  No other widget methods are used.
.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
.PP
Using pack:
.CS
pack [ttk::frame $top.statusbar] \-side bottom \-fill x
pack [\fBttk::sizegrip\fR $top.statusbar.grip] \-side right \-anchor se
.CE
.PP
Using grid:
.CS
grid [\fBttk::sizegrip\fR $top.statusbar.grip] \e
    \-row $lastRow \-column $lastColumn \-sticky se
# ... optional: add vertical scrollbar in $lastColumn,
# ... optional: add horizontal scrollbar in $lastRow
.CE
.SH "BUGS"
.PP
If the containing toplevel's position was specified
relative to the right or bottom of the screen












|












|
|
>
|










|
|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
'\"
'\" Copyright (c) 2006 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::sizegrip \- Bottom-right corner resize widget
.SH SYNOPSIS
\fBttk::sizegrip\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR)
allows the user to resize the containing toplevel window
by pressing and dragging the grip.
.SO ttk_widget
\-class	\-cursor
\-style	\-takefocus
.SE
.SH "WIDGET COMMAND"
.PP
Sizegrip widgets support the standard 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
.PP
Using pack:
.CS
pack [ttk::frame $top.statusbar] -side bottom -fill x
pack [\fBttk::sizegrip\fR $top.statusbar.grip] -side right -anchor se
.CE
.PP
Using grid:
.CS
grid [\fBttk::sizegrip\fR $top.statusbar.grip] \e
    -row $lastRow -column $lastColumn -sticky se
# ... optional: add vertical scrollbar in $lastColumn,
# ... optional: add horizontal scrollbar in $lastRow
.CE
.SH "BUGS"
.PP
If the containing toplevel's position was specified
relative to the right or bottom of the screen

Changes to doc/ttk_spinbox.n.

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

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::spinbox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::spinbox \- Selecting text field widget
.SH SYNOPSIS
\fBttk::spinbox\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in
up and down buttons that are used to either modify a numeric value or
to select among a set of values. The widget implements all the features
of the \fBttk::entry\fR widget including support of the
\fB\-textvariable\fR option to link the value displayed by the widget
to a Tcl variable.
.SO ttk_widget
\-class	\-cursor	\-state	\-style

\-takefocus	\-xscrollcommand	\-placeholder	\-placeholderforeground
.SE
.SO ttk_entry
\-validate	\-validatecommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
.OP \-format format Format
Specifies an alternate format to use when setting the string value
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating\-point value specifying the lowest value for the spinbox. This is
used in conjunction with \fB\-to\fR and \fB\-increment\fR to set a numerical
range.
.OP \-increment increment Increment
A floating\-point value specifying the change in value to be applied each
time one of the widget spin buttons is pressed. The up button applies a
positive increment, the down button applies a negative increment.
.OP \-to to To
A floating\-point value specifying the highest permissible value for the
widget. See also \fB\-from\fR and \fB\-increment\fR.
range.
.OP \-values values Values
This must be a Tcl list of values. If this option is set then this will
override any range set using the \fB\-from\fR, \fB\-to\fR and
\fB\-increment\fR options. The widget will instead use the values
specified beginning with the first value.












|










|
>
|













|



|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::spinbox n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::spinbox \- Selecting text field widget
.SH SYNOPSIS
\fBttk::spinbox\fI pathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in
up and down buttons that are used to either modify a numeric value or
to select among a set of values. The widget implements all the features
of the \fBttk::entry\fR widget including support of the
\fB\-textvariable\fR option to link the value displayed by the widget
to a Tcl variable.
.SO ttk_widget
\-class	\-cursor	\-state
\-style	\-takefocus	\-xscrollcommand
\-placeholder	\-placeholderforeground
.SE
.SO ttk_entry
\-validate	\-validatecommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
.OP \-format format Format
Specifies an alternate format to use when setting the string value
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating-point value specifying the lowest value for the spinbox. This is
used in conjunction with \fB\-to\fR and \fB\-increment\fR to set a numerical
range.
.OP \-increment increment Increment
A floating-point value specifying the change in value to be applied each
time one of the widget spin buttons is pressed. The up button applies a
positive increment, the down button applies a negative increment.
.OP \-to to To
A floating-point value specifying the highest permissible value for the
widget. See also \fB\-from\fR and \fB\-increment\fR.
range.
.OP \-values values Values
This must be a Tcl list of values. If this option is set then this will
override any range set using the \fB\-from\fR, \fB\-to\fR and
\fB\-increment\fR options. The widget will instead use the values
specified beginning with the first value.
62
63
64
65
66
67
68

69
70

71

72
73

74
75
76
77
78
79
80
.PP
See the \fBttk::entry\fR manual for information about using the
\fB\-validate\fR and \fB\-validatecommand\fR options.
.SH "WIDGET COMMAND"
.PP
The following subcommands are possible for spinbox widgets in addition to
the commands described for the \fBttk::entry\fR widget:

.TP
\fIpathName \fBget\fR

Returns the spinbox's current value.

.TP
\fIpathName \fBset \fIvalue\fR

Set the spinbox string to \fIvalue\fR. If a \fB\-format\fR option has
been configured then this format will be applied. If formatting fails
or is not set or the \fB\-values\fR option has been used then the value
is set directly.
.SH "VIRTUAL EVENTS"
.PP
The spinbox widget generates a \fB<<Increment>>\fR virtual event when







>


>

>


>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
.PP
See the \fBttk::entry\fR manual for information about using the
\fB\-validate\fR and \fB\-validatecommand\fR options.
.SH "WIDGET COMMAND"
.PP
The following subcommands are possible for spinbox widgets in addition to
the commands described for the \fBttk::entry\fR widget:
.\" METHOD: get
.TP
\fIpathName \fBget\fR
.
Returns the spinbox's current value.
.\" METHOD: set
.TP
\fIpathName \fBset \fIvalue\fR
.
Set the spinbox string to \fIvalue\fR. If a \fB\-format\fR option has
been configured then this format will be applied. If formatting fails
or is not set or the \fB\-values\fR option has been used then the value
is set directly.
.SH "VIRTUAL EVENTS"
.PP
The spinbox widget generates a \fB<<Increment>>\fR virtual event when

Changes to doc/ttk_style.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29



30
31
32

33
34

35






36
37
38
39
40

41
42
43
44
45
46
47
48

49
50
51

52
53

54
55

56
57
58
59

60
61

62
63
64
65
66
67
68
69
70


71
72

73
74
75
76






77
78
79
80
81

82
83
84
85
86
87
88

89
90
91

92
93
94
95
96





97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115

116
117

118

119
120

121
122
123

124
125

126
127
128
129
130
131
132

133
134

135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153



























154
155
156
157
158
159
160
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::style n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::style \- Manipulate style database
.SH SYNOPSIS
\fBttk::style\fR \fIoption\fR ?\fIargs\fR?
.BE
.SH NOTES
.PP
See also the Tcl'2004 conference presentation,
available at https://tktable.sourceforge.net/tile/tile-tcl2004.pdf
.SH DEFINITIONS
.PP
Each widget is assigned a \fIstyle\fR,
which specifies the set of elements making up the widget
and how they are arranged, along with dynamic and default
settings for element options.
By default, the style name is the same as the widget's class;
this may be overridden by the \fB\-style\fR option.
.PP
A \fItheme\fR is a collection of elements and styles
which controls the overall look and feel of an application.



.SH DESCRIPTION
.PP
The \fBttk::style\fR command takes the following arguments:

.TP
\fBttk::style configure \fIstyle\fR ?\fI\-option\fR ?\fIvalue option value...\fR? ?

Sets the default value of the specified option(s) in \fIstyle\fR.






.TP
\fBttk::style element\fR \fIargs\fR
.RS
.TP
\fBttk::style element create\fR \fIelementName\fR \fItype\fR ?\fIargs...\fR?

Creates a new element in the current theme of type \fItype\fR.
The only cross-platform built-in element type is \fIimage\fR
(see \fBttk_image\fR(n)) but themes may define other element types
(see \fBTtk_RegisterElementFactory\fR). On suitable versions of Windows
an element factory is registered to create Windows theme elements
(see \fBttk_vsapi\fR(n)).
.TP
\fBttk::style element names\fR

Returns the list of elements defined in the current theme.
.TP
\fBttk::style element options \fIelement\fR

Returns the list of \fIelement\fR's options.
.RE

.TP
\fBttk::style layout \fIstyle\fR ?\fIlayoutSpec\fR?

Define the widget layout for style \fIstyle\fR.
See \fBLAYOUTS\fR below for the format of \fIlayoutSpec\fR.
If \fIlayoutSpec\fR is omitted, return the layout specification
for style \fIstyle\fR.

.TP
\fBttk::style lookup \fIstyle\fR \fI\-option \fR?\fIstate \fR?\fIdefault\fR??

Returns the value specified for \fI\-option\fR in style \fIstyle\fR
in state \fIstate\fR, using the standard lookup rules for element options.
\fIstate\fR is a list of state names; if omitted,
it defaults to all bits off (the
.QW normal
state).
If the \fIdefault\fR argument is present, it is used as a fallback
value in case no specification for \fI\-option\fR is found.
.\" Otherwise -- signal error? return empty string? Leave unspecified for now.


.TP
\fBttk::style map \fIstyle\fR ?\fI\-option\fB { \fIstatespec value...\fB }\fR?

Sets dynamic values of the specified option(s) in \fIstyle\fR.
Each \fIstatespec / value\fR pair is examined in order;
the value corresponding to the first matching \fIstatespec\fR
is used.






.TP
\fBttk::style theme\fR \fIargs\fR
.RS
.TP
\fBttk::style theme create\fR \fIthemeName\fR ?\fB\-parent \fIbasedon\fR? ?\fB\-settings \fIscript...\fR ?

Creates a new theme.  It is an error if \fIthemeName\fR already exists.
If \fB\-parent\fR is specified, the new theme will inherit
styles, elements, and layouts from the parent theme \fIbasedon\fR.
If \fB\-settings\fR is present, \fIscript\fR is evaluated in the
context of the new theme as per \fBttk::style theme settings\fR.
.TP
\fBttk::style theme names\fR

Returns a list of all known themes.
.TP
\fBttk::style theme settings \fIthemeName\fR \fIscript\fR

Temporarily sets the current theme to \fIthemeName\fR,
evaluate \fIscript\fR, then restore the previous theme.
Typically \fIscript\fR simply defines styles and elements,
though arbitrary Tcl code may appear.
.TP





\fBttk::style theme use\fR ?\fIthemeName\fR?

Without an argument the result is the name of the current theme.
Otherwise this command sets the current theme to \fIthemeName\fR,
and refreshes all widgets.
.RE
.SH LAYOUTS
.PP
A \fIlayout\fR specifies a list of elements, each followed
by one or more options specifying how to arrange the element.
The layout mechanism uses a simplified version of the \fBpack\fR
geometry manager: given an initial cavity,
each element is allocated a parcel.
Then the parcel actually used by the element is adjusted within
the allocated parcel.
Valid options are:
.\" -border should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-border\fR \fIboolean\fR

.\" Specifies whether the element is drawn after its children. Defaults to 0.

.TP
\fB\-children { \fIsublayout...\fB }\fR

Specifies a list of elements to place inside the element.

.TP
\fB\-expand\fR \fIboolean\fR

Specifies whether the allocated parcel is the entire cavity. If so,
simultaneous specification of \fB\-side\fR is ignored.
Defaults to 0.

.TP
\fB\-side \fIside\fR

Specifies which side of the cavity to place the element;
one of \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
For instance, \fB\-side top\fR allocates the parcel along the top of
the cavity having width and height respectively the width of the cavity
and the height of the element.
If omitted, the allocated parcel is the entire cavity (same effect
as \fB\-expand\fR 1).

.TP
\fB\-sticky\fR \fB[\fInswe\fB]\fR

Specifies the actual parcel position and size inside the allocated parcel.
If specified as an empty string then the actual parcel is centered in
the allocated parcel. Default is \fBnswe\fR.
.\" -unit should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-unit\fR \fIboolean\fR

.\" Specifies whether the element propagates its state to its children.
.\" Defaults to 0.
.PP
For example:
.CS
ttk::style layout Horizontal.TScrollbar {
    Scrollbar.trough \-children {
        Scrollbar.leftarrow \-side left
        Scrollbar.rightarrow \-side right
        Horizontal.Scrollbar.thumb \-side left \-sticky ew
    }
}
.CE



























.SH "SEE ALSO"
ttk::intro(n), ttk::widget(n), photo(n), ttk_image(n)
.SH KEYWORDS
style, theme, appearance
'\" Local Variables:
'\" mode: nroff
'\" End:












|
















>
>
>



>


>

>
>
>
>
>
>

|


|
>








>



>


>


>




>

|
>









>
>


>
|



>
>
>
>
>
>

|


|
>







>


|
>





>
>
>
>
>

>
















|
>

>


>

>

|
>



>


>







>


>





|
>






|
|
|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
'\"
'\" Copyright (c) 2004 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::style n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::style \- Manipulate style database
.SH SYNOPSIS
\fBttk::style\fI option\fR ?\fIargs\fR?
.BE
.SH NOTES
.PP
See also the Tcl'2004 conference presentation,
available at https://tktable.sourceforge.net/tile/tile-tcl2004.pdf
.SH DEFINITIONS
.PP
Each widget is assigned a \fIstyle\fR,
which specifies the set of elements making up the widget
and how they are arranged, along with dynamic and default
settings for element options.
By default, the style name is the same as the widget's class;
this may be overridden by the \fB\-style\fR option.
.PP
A \fItheme\fR is a collection of elements and styles
which controls the overall look and feel of an application.
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:
.\" METHOD: configure
.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.
If \fIstyle\fR does not exist, it is created.
If only \fIstyle\fR and \fI\-option\fR are specified, get the default value
for option \fI\-option\fR of style \fIstyle\fR.
If only \fIstyle\fR is specified, get the default value for all options
of style \fIstyle\fR.
.\" METHOD: element
.TP
\fBttk::style element\fI args\fR
.RS
.TP
\fBttk::style element create\fI elementName type\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
.\" METHOD: layout
.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.
.\" METHOD: lookup
.TP
\fBttk::style lookup \fIstyle \-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.
.\" METHOD: map
.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.
.\" METHOD: theme
.TP
\fBttk::style theme\fI args\fR
.RS
.TP
\fBttk::style theme create\fI themeName\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 script\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 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\fI boolean\fR
.\" .
.\" Specifies whether the element is drawn after its children. Defaults to 0.
.\" OPTION: -children
.TP
\fB\-children { \fIsublayout...\fB }\fR
.
Specifies a list of elements to place inside the element.
.\" OPTION: -expand
.TP
\fB\-expand\fI boolean\fR
.
Specifies whether the allocated parcel is the entire cavity. If so,
simultaneous specification of \fB\-side\fR is ignored.
Defaults to 0.
.\" OPTION: -side
.TP
\fB\-side \fIside\fR
.
Specifies which side of the cavity to place the element;
one of \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR.
For instance, \fB\-side top\fR allocates the parcel along the top of
the cavity having width and height respectively the width of the cavity
and the height of the element.
If omitted, the allocated parcel is the entire cavity (same effect
as \fB\-expand\fR 1).
.\" OPTION: -sticky
.TP
\fB\-sticky\fR \fB[\fInswe\fB]\fR
.
Specifies the actual parcel position and size inside the allocated parcel.
If specified as an empty string then the actual parcel is centered in
the allocated parcel. Default is \fBnswe\fR.
.\" -unit should remain undocumented for now (dubious usefulness)
.\" .TP
.\" \fB\-unit\fI boolean\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
        Horizontal.Scrollbar.thumb -side left -sticky ew
    }
}
.CE
.SH ROOT STYLE
.PP
The
.QW .
theme root style can be configured like any other style, providing defaults
for its derived styles. In addition to the usual options,
.QW .
styling options configurable with \fBttk::style\fP are:
.PP
\fB\-insertofftime\fP \fIamount\fP
.RS
Specifies a non-negative integer value indicating the number of milliseconds
the insertion cursor should remain
.QW off
in each blink cycle. If this option is zero then the cursor does not blink:
it is on all the time. Defaults to 300 ms, unless overriden with a
\fBRESOURCE_MANAGER\fR property or \fB.Xdefaults\fR file.
.RE
.PP
\fB\-insertontime\fP \fIamount\fP
.RS
Specifies a non-negative integer value indicating the number of milliseconds
the insertion cursor should remain
.QW on
in each blink cycle. Defaults to 600 ms, unless overriden with a
\fBRESOURCE_MANAGER\fR property or \fB.Xdefaults\fR file.
.RE
.SH "SEE ALSO"
ttk::intro(n), ttk::widget(n), photo(n), ttk_image(n)
.SH KEYWORDS
style, theme, appearance
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_treeview.n.

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



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











93
94






95
96

97
98
99
100
101
102
103




104
105







106




































107
108

109
110
111
112
113
114
115
116
117
118
119

120
121

122
123
124
125
126
127
128
129

130
131

132
133
134


135
136

137
138
139
140

141
142

143
144
145
146

147






148

149
150
151
152

153
154

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

167
168
169

170
171

172
173
174
175
176
177
178

179








180

181
182

183
184

185
186
187


188
189

190
191
192

193
194

195

196
197

198

199
200

201
202

203
204

205
206
207
208

209
210

211
212
213
214
215
216
217
specifying which data columns are displayed
and the order in which they appear,
or the string \fB#all\fP.
If set to \fB#all\fP (the default),
all columns are shown in the order given.
.OP \-height height Height
Specifies the number of rows which should be visible.
Note:
the requested width is determined from the sum of the column widths.
.OP \-selectmode selectMode SelectMode
Controls how the built-in class bindings manage the selection.
One of \fBextended\fR, \fBbrowse\fR, or \fBnone\fR.
.RS
.PP
If set to \fBextended\fR (the default), multiple items may be selected.
If \fBbrowse\fR, only a single item will be selected at a time.
If \fBnone\fR, the selection will not be changed.
.PP
Note that application code and tag bindings can set the selection
however they wish, regardless of the value of \fB\-selectmode\fR.
.RE



.OP \-show show Show
A list containing zero or more of the following values, specifying
which elements of the tree to display.
.RS
.IP \fBtree\fR
Display tree labels in column #0.
.IP \fBheadings\fR
Display the heading row.
.PP
The default is \fBtree headings\fR, i.e., show all elements.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.RE











.SH "WIDGET COMMAND"
.PP






.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.
Items in the old child list not present in the new child list
are detached from the tree.
None of the items in \fInewchildren\fR may be an ancestor
of \fIitem\fR.
.RE

.TP
\fIpathname \fBcolumn \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?

Query or modify the options for the specified \fIcolumn\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the options are updated with the specified values.
The following options may be set on each column:
.RS

.TP
\fB\-id \fIname\fR

The column name.  This is a read-only option.
For example, [\fI$pathname \fBcolumn #\fIn \fB\-id\fR]
returns the data column associated with display column #\fIn\fR.


.TP
\fB\-anchor \fIanchor\fR

Specifies how the text in this column should be aligned
with respect to the cell. \fIAnchor\fR is one of
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.

.TP
\fB\-minwidth \fIminwidth\fR

The minimum width of the column in pixels.
The treeview widget will not make the column any smaller than
\fB\-minwidth\fR when the widget is resized or the user drags a
column separator.  Default is 20 pixels.

.TP






\fB\-stretch \fIboolean\fR

Specifies whether or not the column width should be adjusted
when the widget is resized or the user drags a column separator.
\fIBoolean\fR may have any of the forms accepted by \fBTcl_GetBoolean\fR.
By default columns are stretchable.

.TP
\fB\-width \fIwidth\fR

The width of the column in pixels.  Default is 200 pixels. The specified
column width may be changed by Tk in order to honor \fB\-stretch\fR
and/or \fB\-minwidth\fR, or when the widget is resized or the user drags a
column separator.
.PP
Use \fIpathname column #0\fR to configure the tree column.
.RE
.TP
\fIpathname \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
Modify or query widget options; see \fIttk::widget(n)\fR.
.TP
\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.
The items and all of their descendants are still present
and may be reinserted at another point in the tree
with the \fBmove\fR operation,
but will not be displayed until that is done.
The root item may not be detached.
See also: \fBdelete\fR.

.TP








\fIpathname \fBexists \fIitem\fR

Returns 1 if the specified \fIitem\fR is present in the tree,
0 otherwise.

.TP
\fIpathname \fBfocus \fR?\fIitem\fR?

If \fIitem\fR is specified, sets the focus item to \fIitem\fR.
Otherwise, returns the current focus item, or \fB{}\fR if there is none.
.\" Need: way to clear the focus item.  {} works for this...


.TP
\fIpathname \fBheading \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?

Query or modify the heading options for the specified \fIcolumn\fR.
Valid options are:
.RS

.TP
\fB\-text \fItext\fR

The text to display in the column heading.

.TP
\fB\-image \fIimageName\fR

Specifies an image to display to the right of the column heading.

.TP
\fB\-anchor \fIanchor\fR

Specifies how the heading text should be aligned.
One of the standard Tk anchor values.

.TP
\fB\-command \fIscript\fR

A script to evaluate when the heading label is pressed.
.PP
Use \fIpathname heading #0\fR to configure the tree column heading.
.RE

.TP
\fIpathname \fBidentify \fIcomponent x y\fR

Returns a description of the specified \fIcomponent\fR
under the point given by \fIx\fR and \fIy\fR,
or the empty string if no such \fIcomponent\fR is present at that position.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify region \fIx y\fR







|













>
>
>









|




>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>
>


>

|
<
<

|
|
>
>
>
>

|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>











>


>








>


>


|
>
>


>




>


>



|
>

>
>
>
>
>
>

>

|


>


>



|

|

|
<
<


>



>


>







>

>
>
>
>
>
>
>
>

>


>


>



>
>


>



>


>

>


>

>


>


>


>




>


>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
specifying which data columns are displayed
and the order in which they appear,
or the string \fB#all\fP.
If set to \fB#all\fP (the default),
all columns are shown in the order given.
.OP \-height height Height
Specifies the number of rows which should be visible.
Note that
the requested width is determined from the sum of the column widths.
.OP \-selectmode selectMode SelectMode
Controls how the built-in class bindings manage the selection.
One of \fBextended\fR, \fBbrowse\fR, or \fBnone\fR.
.RS
.PP
If set to \fBextended\fR (the default), multiple items may be selected.
If \fBbrowse\fR, only a single item will be selected at a time.
If \fBnone\fR, the selection will not be changed.
.PP
Note that application code and tag bindings can set the selection
however they wish, regardless of the value of \fB\-selectmode\fR.
.RE
.OP \-selecttype selectType SelectType
Controls how the built-in class bindings manage the selection.
One of \fBitem\fR or \fBcell\fR.
.OP \-show show Show
A list containing zero or more of the following values, specifying
which elements of the tree to display.
.RS
.IP \fBtree\fR
Display tree labels in column #0.
.IP \fBheadings\fR
Display the heading row.
.PP
The default is \fBtree headings\fR.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.RE
.OP \-striped striped Striped
Boolean specifying zebra striped item coloring.
Note that
striped items uses the \fB\-stripedbackground\fR option if set by the theme or
a tag. If not supported by the current theme, it will not show.
.OP \-titlecolumns titleColumns TitleColumns
Number of display columns at the left that should not be scrolled. The tree
column counts, even if \fB\-show tree\fR is not specified. Thus for value N of
this option, column #N is the first one that is scrollable. Default is 0.
.OP \-titleitems titleItems TitleItems
Number of items at the top that should not be vertically scrolled. Default is 0.
.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:
.\" METHOD: bbox
.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 the \fIitem\fR is not visible
(i.e., if it is a descendant of a closed item or is vertically scrolled
offscreen), returns the empty list.
If \fIcolumn\fR is specified and is not hidden (by the \fB\-displaycolumns\fR
option), returns the bounding box of that cell within \fIitem\fR
(even if the cell is horizontally scrolled offscreen).
.\" METHOD: cellselection
.TP
\fIpathname \fBcellselection\fR ?\fIselop arg ...\fR?
.
Manages cell selection. Cell selection is independent from item selection
handled by the \fBselection\fR command. A cell is given by a list of two
elements, item and column.
For the rectangle versions of commands, the cells must be in displayed columns.
Any change to \fB\-columns\fR clears the cell selection.
A \fIcellList\fR argument may be a single cell or a list of cells.
If \fIselop\fR is not specified, returns the list of selected cells.
Otherwise, \fIselop\fR is one of the following:
.RS
.TP
\fIpathname \fBcellselection set \fIcellList\fR
.
\fIcellList\fR becomes the new cell selection.
.TP
\fIpathname \fBcellselection set \fIfirstCell lastCell\fR
.
The rectangle defined becomes the new cell selection.
.TP
\fIpathname \fBcellselection add \fIcellList\fR
.
Add \fIcellList\fR to the cell selection.
.TP
\fIpathname \fBcellselection add \fIfirstCell lastCell\fR
.
The rectangle defined is added to the cell selection.
.TP
\fIpathname \fBcellselection remove \fIcellList\fR
.
Remove \fIcellList\fR from the cell selection.
.TP
\fIpathname \fBcellselection remove \fIfirstCell lastCell\fR
.
The rectangle defined is removed from the cell selection.
.TP
\fIpathname \fBcellselection toggle \fIcellList\fR
.
Toggle the cell selection state of each cell in \fIcellList\fR.
.TP
\fIpathname \fBcellselection toggle \fIfirstCell lastCell\fR
.
Toggle the cell selection state of each cell in the rectangle defined.
.RE
.\" METHOD: children
.TP
\fIpathname \fBchildren \fIitem\fR ?\fInewchildren\fR?
.
If \fInewchildren\fR is not specified,
returns the list of children belonging to \fIitem\fR.
.RS
.PP
If \fInewchildren\fR is specified, replaces \fIitem\fR's child list
with \fInewchildren\fR.
Items in the old child list not present in the new child list
are detached from the tree.
None of the items in \fInewchildren\fR may be an ancestor
of \fIitem\fR.
.RE
.\" METHOD: column
.TP
\fIpathname \fBcolumn \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
.
Query or modify the options for the specified \fIcolumn\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the options are updated with the specified values.
The following options may be set on each column:
.RS
.\" OPTION: -id
.TP
\fB\-id \fIname\fR
.
The column name.  This is a read-only option.
For example, [\fI$pathname \fBcolumn #\fIn \fB\-id\fR]
returns the data column associated with display column \fIn\fR.
The tree column has \fB\-id #0\fR.
.\" OPTION: -anchor
.TP
\fB\-anchor \fIanchor\fR
.
Specifies how the text in this column should be aligned
with respect to the cell. \fIAnchor\fR is one of
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
.\" OPTION: -minwidth
.TP
\fB\-minwidth \fIminwidth\fR
.
The minimum width of the column in pixels.
The treeview widget will not make the column any smaller than
\fB\-minwidth\fR when the widget is resized or the user drags a
heading column separator.  Default is 20 pixels.
.\" OPTION: -separator
.TP
\fB\-separator \fIboolean\fR
.
Specifies whether or not a column separator should be drawn to the right
of the column.  Default is false.
.\" OPTION: -stretch
.TP
\fB\-stretch \fIboolean\fR
.
Specifies whether or not the column width should be adjusted
when the widget is resized or the user drags a heading column separator.
\fIBoolean\fR may have any of the forms accepted by \fBTcl_GetBoolean\fR.
By default columns are stretchable.
.\" OPTION: -width
.TP
\fB\-width \fIwidth\fR
.
The width of the column in pixels.  Default is 200 pixels. The specified
column width may be changed by Tk in order to honor \fB\-stretch\fR
and/or \fB\-minwidth\fR, or when the widget is resized or the user drags a
heading column separator.
.PP
Use \fIpathname fBcolumn #0\fR to configure the tree column.
.RE
.\" METHOD: delete


.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.
.\" METHOD: detach
.TP
\fIpathname \fBdetach \fIitemList\fR
.
Unlinks all of the specified items in \fIitemList\fR from the tree.
The items and all of their descendants are still present
and may be reinserted at another point in the tree
with the \fBmove\fR operation,
but will not be displayed until that is done.
The root item may not be detached.
See also: \fBdelete\fR.
.\" METHOD: detached
.TP
\fIpathname \fBdetached \fR?\fIitem\fR?
.
If \fIitem\fR is provided, returns a boolean value indicating whether it is
the name of a detached item (see \fBdetach\fR). Otherwise, returns a list of
all the detached items (in an arbitrary order). The root item is never
detached.
.\" METHOD: exists
.TP
\fIpathname \fBexists \fIitem\fR
.
Returns 1 if the specified \fIitem\fR is present in the tree,
0 otherwise.
.\" METHOD: focus
.TP
\fIpathname \fBfocus \fR?\fIitem\fR?
.
If \fIitem\fR is specified, sets the focus item to \fIitem\fR.
Otherwise, returns the current focus item, or \fB{}\fR if there is none.
.\" Need: way to clear the focus item.  {} works for this...
.\"
.\" METHOD: heading
.TP
\fIpathname \fBheading \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
.
Query or modify the heading options for the specified \fIcolumn\fR.
Valid options are:
.RS
.\" OPTION: -text
.TP
\fB\-text \fItext\fR
.
The text to display in the column heading.
.\" OPTION: -image
.TP
\fB\-image \fIimageName\fR
.
Specifies an image to display to the right of the column heading.
.\" OPTION: -anchor
.TP
\fB\-anchor \fIanchor\fR
.
Specifies how the heading text should be aligned.
One of the standard Tk anchor values.
.\" OPTION: -command
.TP
\fB\-command \fIscript\fR
.
A script to evaluate when the heading label is pressed.
.PP
Use \fIpathname heading #0\fR to configure the tree column heading.
.RE
.\" METHOD: identify
.TP
\fIpathname \fBidentify \fIcomponent x y\fR
.
Returns a description of the specified \fIcomponent\fR
under the point given by \fIx\fR and \fIy\fR,
or the empty string if no such \fIcomponent\fR is present at that position.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify region \fIx y\fR
227
228
229
230
231
232
233

234

235
236
237

238
239
240





241

242
243
244

245
246
247
248
249

250
251

252

253
254

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

279
280
281
282
283
284
285

286
287

288
289
290
291
292
293
294
295

296
297

298
299

300
301

302
303

304
305

306
307

308
309

310
311
312
313

314
315



316
317
318
319
320

321
322
323

324
325
326

327
328
329

330
331

332
333

334
335
336
337
338
339
340
341
342
343
344







345
346
347

348
349
350
351
352

353
354
355
356


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

























369

370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386

387
388
389
390
391
392

393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413


414
415




416
417
418
419
420
421
422
423
424
425
426




427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442

443

444
445


446
447
448

449

450




451
452
453
454
455
456
457
458
459
460




461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480



481
482
483
484
485
486
487
will return the display column identifier
of the heading to left of the separator.
.IP tree
The tree area.
.IP cell
A data cell.
.RE

\fIpathname \fBidentify item \fIx y\fR

Returns the item ID of the item at position \fIy\fR.
.TP
\fIpathname \fBidentify column \fIx y\fR

Returns the display column identifier of the cell at position \fIx\fR.
The tree column has ID \fB#0\fR.
.TP





\fIpathname \fBidentify element \fIx y\fR

The element at position \fIx,y\fR.
.TP
\fIpathname \fBidentify row \fIx y\fR

Obsolescent synonym for \fIpathname \fBidentify item\fR.
.PP
See \fBCOLUMN IDENTIFIERS\fR for a discussion of display columns
and data columns.
.RE

.TP
\fIpathname \fBindex \fIitem\fR

Returns the integer index of \fIitem\fR within its parent's list of children.

.TP
\fIpathname \fBinsert \fIparent index\fR ?\fB\-id \fIid\fR? \fIoptions...\fR

Creates a new item.
\fIparent\fR is the item ID of the parent item,
or the empty string \fB{}\fR
to create a new top-level item.
\fIindex\fR is an integer, or the value \fBend\fR, specifying where in the
list of \fIparent\fR's children to insert the new item.
If \fIindex\fR is less than or equal to zero,
the new node is inserted at the beginning;
if \fIindex\fR is greater than or equal to the current number of children,
it is inserted at the end.
If \fB\-id\fR is specified, it is used as the item identifier;
\fIid\fR must not already exist in the tree.
Otherwise, a new unique identifier is generated.
.RS
.PP
\fIpathname \fBinsert\fR returns the item identifier of the
newly created item.
See \fBITEM OPTIONS\fR for the list of available options.
.RE
.TP
\fIpathname \fBinstate \fIstatespec\fR ?\fIscript\fR?
Test the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?

Query or modify the options for the specified \fIitem\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the item's options are updated with the specified values.
See \fBITEM OPTIONS\fR for the list of available options.

.TP
\fIpathname \fBmove \fIitem parent index\fR

Moves \fIitem\fR to position \fIindex\fR in \fIparent\fR's list of children.
It is illegal to move an item under one of its descendants.
.RS
.PP
If \fIindex\fR is less than or equal to zero, \fIitem\fR is moved
to the beginning; if greater than or equal to the number of children,
it is moved to the end.
.RE

.TP
\fIpathname \fBnext \fIitem\fR

Returns the identifier of \fIitem\fR's next sibling,
or \fB{}\fR if \fIitem\fR is the last child of its parent.

.TP
\fIpathname \fBparent \fIitem\fR

Returns the ID of the parent of \fIitem\fR,
or \fB{}\fR if \fIitem\fR is at the top level of the hierarchy.

.TP
\fIpathname \fBprev \fIitem\fR

Returns the identifier of \fIitem\fR's previous sibling,
or \fB{}\fR if \fIitem\fR is the first child of its parent.

.TP
\fIpathname \fBsee \fIitem\fR

Ensure that \fIitem\fR is visible:
sets all of \fIitem\fR's ancestors to \fB\-open true\fR,
and scrolls the widget if necessary so that \fIitem\fR is
within the visible portion of the tree.

.TP
\fIpathname \fBselection\fR ?\fIselop itemList\fR?



If \fIselop\fR is not specified, returns the list of selected items.
Otherwise, \fIselop\fR is one of the following:
.RS
.TP
\fIpathname \fBselection set \fIitemList\fR

\fIitemList\fR becomes the new selection.
.TP
\fIpathname \fBselection add \fIitemList\fR

Add \fIitemList\fR to the selection
.TP
\fIpathname \fBselection remove \fIitemList\fR

Remove \fIitemList\fR from the selection
.TP
\fIpathname \fBselection toggle \fIitemList\fR

Toggle the selection state of each item in \fIitemList\fR.
.RE

.TP
\fIpathname \fBset \fIitem\fR ?\fIcolumn\fR? ?\fIvalue\fR?

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.
.TP
\fIpathName \fBtag bind \fItagName \fR?\fIsequence\fR? ?\fIscript\fR?

Add a Tk binding script for the event sequence \fIsequence\fR
to the tag \fItagName\fR.  When an X event is delivered to an item,
binding scripts for each of the item's \fB\-tags\fR are evaluated
in order as per \fIbindtags(n)\fR.


.RS
.PP
\fB<Key>\fR, \fB<KeyRelease>\fR, and virtual events
are sent to the focus item.
\fB<Button>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events
are sent to the item under the mouse pointer.
No other event types are supported.
.PP
The binding \fIscript\fR undergoes \fB%\fR-substitutions before
evaluation; see \fBbind(n)\fR for details.
.RE
.TP

























\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR?

Query or modify the options for the specified \fItagName\fR.
If one or more \fIoption/value\fR pairs are specified,
sets the value of those options for the specified tag.
If a single \fIoption\fR is specified,
returns the value of that option
(or the empty string if the option has not been specified for \fItagName\fR).
With no additional arguments,
returns a dictionary of the option settings for \fItagName\fR.
See \fBTAG OPTIONS\fR for the list of available options.
.TP
\fIpathName \fBtag delete \fItagName\fR

Deletes all tag information for the \fItagName\fR argument. The
command removes the tag from all items in the widget and also deletes any
other information associated with the tag, such as bindings and display
information. The command returns an empty string.
.TP
\fIpathName \fBtag has \fItagName\fR ?\fIitem\fR?

If \fIitem\fR is specified, returns 1 or 0
depending on whether the specified item has the named tag.
Otherwise, returns a list of all items which have
the specified tag.
.TP
\fIpathName \fBtag names\fR

Returns a list of all tags used by the widget.
.TP
\fIpathName \fBtag remove \fItag\fR ?\fIitems\fR?

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


.OP \-image image Image
A Tk image, displayed to the left of the label.




.OP \-values values Values
The list of values associated with the item.
.RS
.PP
Each item should have the same number of values as
the \fB\-columns\fR widget option.
If there are fewer values than columns,
the remaining values are assumed empty.
If there are more values than columns,
the extra values are ignored.
.RE




.OP \-open open Open
A boolean value indicating whether the item's children
should be displayed (\fB\-open true\fR) or hidden (\fB\-open false\fR).
.OP \-tags tags Tags
A list of tags associated with this item.
.SH "TAG OPTIONS"
.PP
The following options may be specified on tags:
.IP \fB\-foreground\fR
Specifies the text foreground color.
.IP \fB\-background\fR
Specifies the cell or item background color.
.IP \fB\-font\fR
Specifies the font to use when drawing text.
.\" ??? Maybe: .IP \-anchor

.\" ??? Maybe: .IP \-padding

.\" ??? Maybe: .IP \-text

.IP \fB\-image\fR
Specifies the item image, in case the item's \fB\-image\fR option is empty.


.\" .PP
.\" \fI(@@@ TODO: sort out order of precedence for options)\fR
.PP

Tag priority is decided by the creation order: tags created first receive

higher priority.




.SH "COLUMN IDENTIFIERS"
.PP
Column identifiers take any of the following forms:
.IP \(bu
A symbolic name from the list of \fB\-columns\fR.
.IP \(bu
An integer \fIn\fR, specifying the \fIn\fRth data column.
.IP \(bu
A string of the form \fB#\fIn\fR, where \fIn\fR is an integer,
specifying the \fIn\fRth display column.




.PP
\fBNOTE:\fR
Item \fB\-values\fR may be displayed in a different order than
the order in which they are stored.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.PP
A \fIdata column number\fR is an index into an item's \fB\-values\fR list;
a \fIdisplay column number\fR is the column number in the tree
where the values are displayed.
Tree labels are displayed in column #0.
If \fB\-displaycolumns\fR is not set,
then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR.
Again, \fBcolumn #0 always refers to the tree column\fR.
.SH "VIRTUAL EVENTS"
.PP
The treeview widget generates the following virtual events.
.IP <<TreeviewSelect>>
Generated whenever the selection changes.



.IP <<TreeviewOpen>>
Generated just before setting the focus item to \fB\-open true\fR.
.IP <<TreeviewClose>>
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.







>

>



>



>
>
>
>
>

>



>





>


>

>


>



















|
<
<


>







>


>








>


>


>


>


>


>


>


>




>


>
>
>





>



>
|


>
|


>


>


>






|
<
<


>
>
>
>
>
>
>



>





>




>
>









|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>











>
|
|




>






>



>





<
<
<
<
<
<
<




|
|
>
>
|
|
>
>
>
>
|










>
>
>
>
|


|










|
>
|
>
|
>
|
|
>
>



>
|
>
|
>
>
>
>










>
>
>
>



















|
>
>
>







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400


401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485


486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
will return the display column identifier
of the heading to left of the separator.
.IP tree
The tree area.
.IP cell
A data cell.
.RE
.TP
\fIpathname \fBidentify item \fIx y\fR
.
Returns the item ID of the item at position \fIy\fR.
.TP
\fIpathname \fBidentify column \fIx y\fR
.
Returns the display column identifier of the cell at position \fIx\fR.
The tree column has ID \fB#0\fR.
.TP
\fIpathname \fBidentify cell \fIx y\fR
.
Returns the cell identifier of the cell at position \fIx y\fR.
A cell identifier is a list of item ID and column ID.
.TP
\fIpathname \fBidentify element \fIx y\fR
.
The element at position \fIx,y\fR.
.TP
\fIpathname \fBidentify row \fIx y\fR
.
Obsolescent synonym for \fIpathname \fBidentify item\fR.
.PP
See \fBCOLUMN IDENTIFIERS\fR for a discussion of display columns
and data columns.
.RE
.\" METHOD: index
.TP
\fIpathname \fBindex \fIitem\fR
.
Returns the integer index of \fIitem\fR within its parent's list of children.
.\" METHOD: insert
.TP
\fIpathname \fBinsert \fIparent index\fR ?\fB\-id \fIid\fR? \fIoptions...\fR
.
Creates a new item.
\fIparent\fR is the item ID of the parent item,
or the empty string \fB{}\fR
to create a new top-level item.
\fIindex\fR is an integer, or the value \fBend\fR, specifying where in the
list of \fIparent\fR's children to insert the new item.
If \fIindex\fR is less than or equal to zero,
the new node is inserted at the beginning;
if \fIindex\fR is greater than or equal to the current number of children,
it is inserted at the end.
If \fB\-id\fR is specified, it is used as the item identifier;
\fIid\fR must not already exist in the tree.
Otherwise, a new unique identifier is generated.
.RS
.PP
\fIpathname \fBinsert\fR returns the item identifier of the
newly created item.
See \fBITEM OPTIONS\fR for the list of available options.
.RE
.\" METHOD: item


.TP
\fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR?
.
Query or modify the options for the specified \fIitem\fR.
If no \fI\-option\fR is specified,
returns a dictionary of option/value pairs.
If a single \fI\-option\fR is specified,
returns the value of that option.
Otherwise, the item's options are updated with the specified values.
See \fBITEM OPTIONS\fR for the list of available options.
.\" METHOD: move
.TP
\fIpathname \fBmove \fIitem parent index\fR
.
Moves \fIitem\fR to position \fIindex\fR in \fIparent\fR's list of children.
It is illegal to move an item under one of its descendants.
.RS
.PP
If \fIindex\fR is less than or equal to zero, \fIitem\fR is moved
to the beginning; if greater than or equal to the number of children,
it is moved to the end.
.RE
.\" METHOD: next
.TP
\fIpathname \fBnext \fIitem\fR
.
Returns the identifier of \fIitem\fR's next sibling,
or \fB{}\fR if \fIitem\fR is the last child of its parent.
.\" METHOD: parent
.TP
\fIpathname \fBparent \fIitem\fR
.
Returns the ID of the parent of \fIitem\fR,
or \fB{}\fR if \fIitem\fR is at the top level of the hierarchy.
.\" METHOD: prev
.TP
\fIpathname \fBprev \fIitem\fR
.
Returns the identifier of \fIitem\fR's previous sibling,
or \fB{}\fR if \fIitem\fR is the first child of its parent.
.\" METHOD: see
.TP
\fIpathname \fBsee \fIitem\fR
.
Ensure that \fIitem\fR is visible:
sets all of \fIitem\fR's ancestors to \fB\-open true\fR,
and scrolls the widget if necessary so that \fIitem\fR is
within the visible portion of the tree.
.\" METHOD: selection
.TP
\fIpathname \fBselection\fR ?\fIselop itemList\fR?
.
Manages item selection. Item selection is independent from cell selection
handled by the \fBcellselection\fR command.
If \fIselop\fR is not specified, returns the list of selected items.
Otherwise, \fIselop\fR is one of the following:
.RS
.TP
\fIpathname \fBselection set \fIitemList\fR
.
\fIitemList\fR becomes the new selection.
.TP
\fIpathname \fBselection add \fIitemList\fR
.
Add \fIitemList\fR to the selection.
.TP
\fIpathname \fBselection remove \fIitemList\fR
.
Remove \fIitemList\fR from the selection.
.TP
\fIpathname \fBselection toggle \fIitemList\fR
.
Toggle the selection state of each item in \fIitemList\fR.
.RE
.\" METHOD: set
.TP
\fIpathname \fBset \fIitem\fR ?\fIcolumn\fR? ?\fIvalue\fR?
.
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.
.\" METHOD: tag


.TP
\fIpathName \fBtag \fIargs...\fR
.
Manages tags. Tags can be set on items as well as on cells.
The set of tags is shared between items and cells. However item tagging is
independent from cell tagging (for instance adding a tag on an item does
not also add this tag on the cells in that item). Cell tags take precedence
over item tags when drawing.
The following subcommands are supported:
.RS
.TP
\fIpathName \fBtag add \fItag items\fR
.
Adds the specified \fItag\fR to each of the listed \fIitems\fR.
If \fItag\fR is already present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.TP
\fIpathName \fBtag bind \fItagName \fR?\fIsequence\fR? ?\fIscript\fR?
.
Add a Tk binding script for the event sequence \fIsequence\fR
to the tag \fItagName\fR.  When an X event is delivered to an item,
binding scripts for each of the item's \fB\-tags\fR are evaluated
in order as per \fIbindtags(n)\fR.
If the event can be associated with a cell (i.e. mouse events) any
bindings for the cell's \fB\-tags\fR are evaluated as well.
.RS
.PP
\fB<Key>\fR, \fB<KeyRelease>\fR, and virtual events
are sent to the focus item.
\fB<Button>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events
are sent to the item under the mouse pointer.
No other event types are supported.
.PP
The binding \fIscript\fR undergoes \fB%\fR-substitutions before
evaluation; see \fBbind\fR(n) for details.
.RE
.TP
\fIpathName \fBtag cell \fIsubcommand...\fR
.
Manages tags on individual cells.
A \fIcellList\fR argument may be a single cell or a list of cells.
.RS
.TP
\fIpathName \fBtag cell add \fItag cellList\fR
.
Adds the specified \fItag\fR to each of the listed \fIcellList\fR.
If \fItag\fR is already present for a particular cell,
then the tag list for that cell is unchanged.
.TP
\fIpathName \fBtag cell has \fItagName\fR ?\fIcell\fR?
.
If \fIcell\fR is specified, returns 1 or 0
depending on whether the specified cell has the named tag.
Otherwise, returns a list of all cells which have
the specified tag.
.TP
\fIpathName \fBtag cell remove \fItag\fR ?\fIcellList\fR?
.
Removes the specified \fItag\fR from each of the listed \fIcellList\fR.
If \fIcellList\fR is omitted, removes \fItag\fR from each cell in the tree.
.RE
.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR?
.
Query or modify the options for the specified \fItagName\fR.
If one or more \fIoption/value\fR pairs are specified,
sets the value of those options for the specified tag.
If a single \fIoption\fR is specified,
returns the value of that option
(or the empty string if the option has not been specified for \fItagName\fR).
With no additional arguments,
returns a dictionary of the option settings for \fItagName\fR.
See \fBTAG OPTIONS\fR for the list of available options.
.TP
\fIpathName \fBtag delete \fItagName\fR
.
Deletes all tag information for the \fItagName\fR argument. The command
removes the tag from all items and cells in the widget and also deletes any
other information associated with the tag, such as bindings and display
information. The command returns an empty string.
.TP
\fIpathName \fBtag has \fItagName\fR ?\fIitem\fR?
.
If \fIitem\fR is specified, returns 1 or 0
depending on whether the specified item has the named tag.
Otherwise, returns a list of all items which have
the specified tag.
.TP
\fIpathName \fBtag names\fR
.
Returns a list of all tags used by the widget.
.TP
\fIpathName \fBtag remove \fItag\fR ?\fIitems\fR?
.
Removes the specified \fItag\fR from each of the listed \fIitems\fR.
If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree.
If \fItag\fR is not present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.RE







.SH "ITEM OPTIONS"
.PP
The following item options may be specified for items
in the \fBinsert\fR and \fBitem\fR widget commands.
.IP \fB\-text\fR
The textual label to display for the item in the tree column.
.IP \fB\-height\fR
The height for the item, in integer multiples of \fB\-rowheight\fP. Default is 1.
.IP \fB\-image\fR
A Tk image, displayed next to the label in the tree column, placed according
to \fB\-imageanchor\fR.
.IP \fB\-imageanchor\fR
Specifies how the \fB\-image\fR is displayed relative to the text.
Default is \fBw\fR. One of the standard Tk anchor values.
.IP \fB\-values\fR
The list of values associated with the item.
.RS
.PP
Each item should have the same number of values as
the \fB\-columns\fR widget option.
If there are fewer values than columns,
the remaining values are assumed empty.
If there are more values than columns,
the extra values are ignored.
.RE
.IP \fB\-hidden\fR
A boolean value indicating whether this item
should be displayed (\fB\-hidden false\fR) or hidden (\fB\-hidden true\fR).
If a parent is hidden, all its decendants are hidden too.
.IP \fB\-open\fR
A boolean value indicating whether the item's children
should be displayed (\fB\-open true\fR) or hidden (\fB\-open false\fR).
.IP \fB\-tags\fR
A list of tags associated with this item.
.SH "TAG OPTIONS"
.PP
The following options may be specified on tags:
.IP \fB\-foreground\fR
Specifies the text foreground color.
.IP \fB\-background\fR
Specifies the cell or item background color.
.IP \fB\-font\fR
Specifies the font to use when drawing text.
.IP \fB\-image\fR
Specifies the cell or item image.
.IP \fB\-imageanchor\fR
Specifies the cell or item image anchor.
.IP \fB\-padding\fR
Specifies the cell padding. A data cell will have a default padding of {4 0}
.IP \fB\-stripedbackground\fR
Specifies the cell or item background color for alternate lines,
if \fB\-striped\fR is true.
.PP
.\" .PP
.\" \fI(@@@ TODO: sort out order of precedence for options)\fR
.PP
Tags on cells have precedence over tags on items. Then, tag priority is
decided by the creation order: tags created first receive higher priority.
An item's options, like \fB\-image\fR and \fB\-imageanchor\fR, have priority
over tags.
.SH "IMAGES"
The -image option on an item, and on an item tag, controls the image next to
the label in the tree column.
Other cells can have images through the cell tag -image option.
.SH "COLUMN IDENTIFIERS"
.PP
Column identifiers take any of the following forms:
.IP \(bu
A symbolic name from the list of \fB\-columns\fR.
.IP \(bu
An integer \fIn\fR, specifying the \fIn\fRth data column.
.IP \(bu
A string of the form \fB#\fIn\fR, where \fIn\fR is an integer,
specifying the \fIn\fRth display column.
.PP
Column identifiers support the same simple interpretation as
for the command \fBstring index\fR, with simple integer index
arithmetic and indexing relative to \fBend\fR.
.PP
\fBNOTE:\fR
Item \fB\-values\fR may be displayed in a different order than
the order in which they are stored.
.PP
\fBNOTE:\fR Column #0 always refers to the tree column,
even if \fB\-show tree\fR is not specified.
.PP
A \fIdata column number\fR is an index into an item's \fB\-values\fR list;
a \fIdisplay column number\fR is the column number in the tree
where the values are displayed.
Tree labels are displayed in column #0.
If \fB\-displaycolumns\fR is not set,
then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR.
Again, \fBcolumn #0 always refers to the tree column\fR.
.SH "VIRTUAL EVENTS"
.PP
The treeview widget generates the following virtual events.
.IP <<TreeviewSelect>>
Generated whenever the selection or cellselection changes.
It might also be generated when selection is affected but not actually changed.
Further, multiple selection changes could happen before events can be processed
leading to multiple events with the same visible selection.
.IP <<TreeviewOpen>>
Generated just before setting the focus item to \fB\-open true\fR.
.IP <<TreeviewClose>>
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.
504
505
506
507
508
509
510







511
512

513

514


515
516
517
518
519
520

521
522
523
524
525
526


527
528
529
530
531
532
533
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br







\fB\-rowheight\fP \fIamount\fP
.RS

The \fB\-rowheight\fP value is not corrected by the \fBtk scaling\fP

value or by the configured font size and must always be set.  Also make


sure that the \fB\-rowheight\fP is large enough to contain any images.
.PP
To adjust the \fB\-rowheight\fP for the Treeview style, use the following code
after \fBtk scaling\fP has been applied.
Note that even if you do not support or change \fBtk scaling\fP
in your program, your users may have it set in their .wishrc.

.RE
.PP
.CS
ttk::style configure Treeview \\
     \-rowheight [expr {[font metrics \fIfont\fP \-linespace] + 2}]
.CE


.PP
\fBHeading\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP







>
>
>
>
>
>
>
|

>
|
>
|
>
>
|

|
<
<
<
>




|

>
>







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733



734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indent\fP \fIamount\fP
.RS
Specifies how many pixels items are indented from their parents. Defaults to 20.
.RE
.br
\fB\-columnseparatorwidth\fP \fIpixels\fP
.br
\fB\-rowheight\fP \fIpixels\fP
.RS
This is the standard height for an item.
If \fB\-rowheight\fP is not set by the style, it is set by measuring an
item and a cell layout with the style's settings.
This thus picks up the font and
any focus ring or padding from the theme's layout.
The \fB\-rowheight\fP may need to be set to make sure that a row
is large enough to contain any images.
.PP
Example of how to set \fB\-rowheight\fP, adapting to a font in a similar



way to how the default value is set:
.RE
.PP
.CS
ttk::style configure Treeview \\
     -rowheight [expr {[font metrics \fIfont\fP -linespace] + 2}]
.CE
.br
\fB\-stripedbackground\fP \fIcolor\fP
.PP
\fBHeading\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP

Changes to doc/ttk_vsapi.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51

52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk_vsapi n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_vsapi \- Define a Microsoft Visual Styles element
.SH SYNOPSIS
\fBttk::style element create \fIname\fR \fBvsapi\fR \fIclassName\fR \fIpartId\fR ?\fIstateMap\fR? ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fBvsapi\fR element factory creates a new element
in the current theme whose visual appearance is drawn using the
Microsoft Visual Styles API which is responsible for the themed styles
on Windows XP and Vista. This factory permits any of the Visual
Styles parts to be declared as Ttk elements that can then be
included in a style layout to modify the appearance of Ttk widgets.
.PP
\fIclassName\fR and \fIpartId\fR are required parameters and specify
the Visual Styles class and part as given in the Microsoft
documentation. The \fIstateMap\fR may be provided to map Ttk states to
Visual Styles API states (see \fBSTATE MAP\fR).
.SH "OPTIONS"
.PP
Valid \fIoptions\fR are:

.TP
\fB\-padding \fIpadding\fR
.
Specify the element's interior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
This option may not be mixed with any other options.

.TP
\fB\-margins \fIpadding\fR
.
Specifies the elements exterior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
This option may not be mixed with any other options.

.TP
\fB\-width \fIwidth\fR
.
Specifies the height for the element. If this option is set then
the Visual Styles API will not be queried for the recommended
size or the part. If this option is set then \fB\-height\fR should
also be set. The \fB\-width\fR and \fB\-height\fR options cannot
be mixed with the \fB\-padding\fR or \fB\-margins\fR options.

.TP
\fB\-height \fIheight\fR
.
Specifies the height of the element. See the comments for \fB\-width\fR.
.SH "STATE MAP"
.PP
The \fIstateMap\fR parameter is a list of ttk states and the












|










|






>










|
|


>







>








>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
'\"
'\" Copyright (c) 2008 Pat Thoyts
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk_vsapi n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk_vsapi \- Define a Microsoft Visual Styles element
.SH SYNOPSIS
\fBttk::style element create \fIname \fBvsapi\fI className partId\fR ?\fIstateMap\fR? ?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
The \fBvsapi\fR element factory creates a new element
in the current theme whose visual appearance is drawn using the
Microsoft Visual Styles API which is responsible for the themed styles
on Windows XP and Vista. This factory permits any of the Visual
Styles parts to be declared as Ttk elements that can then be
included in a style layout to modify the appearance of Ttk widgets.
.PP
The \fIclassName\fR and \fIpartId\fR are required parameters and specify
the Visual Styles class and part as given in the Microsoft
documentation. The \fIstateMap\fR may be provided to map Ttk states to
Visual Styles API states (see \fBSTATE MAP\fR).
.SH "OPTIONS"
.PP
Valid \fIoptions\fR are:
.\" OPTION: -padding
.TP
\fB\-padding \fIpadding\fR
.
Specify the element's interior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right
padding; a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
This option may not be mixed with any other options.
.\" OPTION: -margins
.TP
\fB\-margins \fIpadding\fR
.
Specifies the elements exterior padding.
\fIpadding\fR is a list of up to four integers specifying
the left, top, right and bottom padding quantities respectively.
This option may not be mixed with any other options.
.\" OPTION: -width
.TP
\fB\-width \fIwidth\fR
.
Specifies the height for the element. If this option is set then
the Visual Styles API will not be queried for the recommended
size or the part. If this option is set then \fB\-height\fR should
also be set. The \fB\-width\fR and \fB\-height\fR options cannot
be mixed with the \fB\-padding\fR or \fB\-margins\fR options.
.\" OPTION: -height
.TP
\fB\-height \fIheight\fR
.
Specifies the height of the element. See the comments for \fB\-width\fR.
.SH "STATE MAP"
.PP
The \fIstateMap\fR parameter is a list of ttk states and the

Changes to doc/ttk_widget.n.

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
See also \fB\-justify\fR (for widgets supporting this option).
.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.
If set to the empty string (the default), the rules described in the
"Elements" section of \fIttk::intro(n)\fR explain which value is actually
used.
Valid values are:
.RS
.IP text
Display text only.
.IP image
Display image only.
.IP center
Display text centered on top of image.







|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
See also \fB\-justify\fR (for widgets supporting this option).
.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.
If set to the empty string (the default), the rules described in the
"Elements" section of \fIttk::intro(n)\fR explain which value is actually
used.
The other valid values are:
.RS
.IP text
Display text only.
.IP image
Display image only.
.IP center
Display text centered on top of image.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
Specifies the internal padding for the widget.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-text text Text
Specifies a text string to be displayed inside the widget
(unless overridden by \fB\-textvariable\fR for the widgets supporting this option).
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value will be used
in place of the \fB\-text\fR resource.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to underline
in the text string.

The underlined character is used for mnemonic activation.
.OP \-width width Width
If greater than zero, specifies how much space, in character widths,
to allocate for the text label.
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.
Note that some themes may specify a non-zero \fB\-width\fR







|
|


|
|





|
>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Specifies the internal padding for the widget.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right
padding; a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-text text Text
Specifies a text string to be displayed inside the widget (unless overridden
by \fB\-textvariable\fR for the widgets supporting this option).
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value will be used
in place of the \fB\-text\fR resource.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to underline
in the text string. \fBend\fR corresponds to the last character,
\fBend\fR-1 to the before last character, and so on.
The underlined character is used for mnemonic activation.
.OP \-width width Width
If greater than zero, specifies how much space, in character widths,
to allocate for the text label.
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.
Note that some themes may specify a non-zero \fB\-width\fR
168
169
170
171
172
173
174

175
176
177
178
179

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

196
197
198
199
200
201
202
203


204
205
206
207
208
209
210
211
212
213

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

231





232

233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248

249
250
251
252

253
254
255
256
257

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

272
273

274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289

290
291
292
293

294
295
296
297
298

299
300
301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.

.TP
\fIpathName \fBidentify element \fIx y\fR
.
Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands.


.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE

.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE

.TP





\fIpathName \fBxview \fIargs\fR

This command is used to query and change the horizontal position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the left, the middle 40% is visible
in the window, and 40% of the content is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR

Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that the character \fIfraction\fR of the
way through the content appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE

.TP
\fIpathName \fByview \fIargs\fR

This command is used to query and change the vertical position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fByview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the vertical span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the top, the middle 40% is visible
in the window, and 40% of the content is off-screen to the bottom.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview\fR \fIindex\fR

Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the top edge of the window.
.TP
\fIpathName \fByview moveto\fI fraction\fR

Adjusts the view in the window so that the item \fIfraction\fR of the
way through the content appears at the top edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR

This command shifts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then items farther to the top
become visible;  if it is positive then items farther to the bottom
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR average-width characters on the display.
.RE
.SH "WIDGET STATES"
The widget state is a bitmap of independent state flags.
Widget state flags include:
.TP
\fBactive\fR
.
The mouse cursor is over the widget
and pressing a mouse button will cause some action to occur. (aka
.QW prelight
(Gnome),
.QW hot
(Windows),
.QW hover ).
.TP
\fBdisabled\fR
.
Widget is disabled under program control (aka
.QW unavailable ,
.QW inactive ).
.TP
\fBfocus\fR
.
Widget has keyboard focus.
.TP
\fBpressed\fR
.
Widget is being pressed (aka
.QW armed
in Motif).
.TP
\fBselected\fR
.
.QW On ,
.QW true ,
or
.QW current
for things like checkbuttons and radiobuttons.
.TP
\fBbackground\fR
.
Windows and the Mac have a notion of an
.QW active
or foreground window.
The \fBbackground\fR state is set for widgets in a background window,
and cleared for those in the foreground window.
.TP
\fBreadonly\fR
.
Widget should not allow user modification.
.TP
\fBalternate\fR
.
A widget-specific alternate display format.
For example, used for checkbuttons and radiobuttons in the
.QW tristate
or
.QW mixed
state, and for buttons with \fB\-default active\fR.
.TP
\fBinvalid\fR
.
The widget's value is invalid.
(Potential uses: scale widget value out of bounds,
entry widget value failed validation.)
.TP
\fBhover\fR
.
The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.
.PP







>





>
















>







|
>
>










>

















>

>
>
>
>
>

>






>









|
>




>





>














>


>






>









|
>




>





>


|
>













<
|
<







<
|
<



<
|
<

<
|
<



<
|
<





<
|
<





<
|
<

<
|
<






<
|
<



<
|
<







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

340

341
342
343
344
345
346
347

348

349
350
351

352

353

354

355
356
357

358

359
360
361
362
363

364

365
366
367
368
369

370

371

372

373
374
375
376
377
378

379

380
381
382

383

384
385
386
387
388
389
390
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.
.\" METHOD: identify
.TP
\fIpathName \fBidentify element \fIx y\fR
.
Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands described
in these widgets documentation.
.\" METHOD: instate
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE
.\" METHOD: state
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE
.\" METHOD: style
.TP
\fIpathName \fBstyle\fR
.
Return the style used by the widget.
.\" METHOD: xview
.TP
\fIpathName \fBxview \fIargs\fR
.
This command is used to query and change the horizontal position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the left, the middle 40% is visible
in the window, and 40% of the content is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fI index\fR
.
Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR
.
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the content appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE
.\" METHOD: yview
.TP
\fIpathName \fByview \fIargs\fR
.
This command is used to query and change the vertical position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fByview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the vertical span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the top, the middle 40% is visible
in the window, and 40% of the content is off-screen to the bottom.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview\fI index\fR
.
Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the top edge of the window.
.TP
\fIpathName \fByview moveto\fI fraction\fR
.
Adjusts the view in the window so that the item \fIfraction\fR of the
way through the content appears at the top edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command shifts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer 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 items farther to the top
become visible;  if it is positive then items farther to the bottom
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR average-width characters on the display.
.RE
.SH "WIDGET STATES"
The widget state is a bitmap of independent state flags.
Widget state flags include:

.IP \fBactive\fR

The mouse cursor is over the widget
and pressing a mouse button will cause some action to occur. (aka
.QW prelight
(Gnome),
.QW hot
(Windows),
.QW hover ).

.IP \fBdisabled\fR

Widget is disabled under program control (aka
.QW unavailable ,
.QW inactive ).

.IP \fBfocus\fR

Widget has keyboard focus.

.IP \fBpressed\fR

Widget is being pressed (aka
.QW armed
in Motif).

.IP \fBselected\fR

.QW On ,
.QW true ,
or
.QW current
for things like checkbuttons and radiobuttons.

.IP \fBbackground\fR

Windows and the Mac have a notion of an
.QW active
or foreground window.
The \fBbackground\fR state is set for widgets in a background window,
and cleared for those in the foreground window.

.IP \fBreadonly\fR

Widget should not allow user modification.

.IP \fBalternate\fR

A widget-specific alternate display format.
For example, used for checkbuttons and radiobuttons in the
.QW tristate
or
.QW mixed
state, and for buttons with \fB\-default active\fR.

.IP \fBinvalid\fR

The widget's value is invalid.
(Potential uses: scale widget value out of bounds,
entry widget value failed validation.)

.IP \fBhover\fR

The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.
.PP

Changes to doc/winfo.n.

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

22
23

24
25
26
27
28
29

30
31

32
33
34
35
36
37
38

39
40

41
42

43
44

45
46
47
48
49
50

51
52

53

54
55

56
57
58
59
60
61
62

63
64

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

82
83

84
85

86
87

88
89

90
91

92
93
94
95
96
97
98
99
100

101
102

103
104
105

106
107

108
109
110
111
112
113
114
115

116
117

118
119
120
121

122
123

124
125
126
127
128

129
130

131

132
133

134
135
136
137
138
139
140

141
142

143
144
145

146
147

148
149

150
151

152
153
154
155
156
157

158
159

160
161
162
163
164
165
166
167
168

169
170

171
172
173
174
175
176

177
178

179
180
181
182
183
184
185

186
187

188
189
190
191
192
193

194
195

196
197
198

199
200

201
202
203

204
205

206
207
208
209
210
211

212
213

214
215
216
217

218
219

220
221
222
223

224
225

226
227

228
229

230
231

232
233

234
235

236
237

238
239

240
241

242
243

244
245

246
247

248
249

250
251
252
253

254
255

256
257

258
259

260
261
262
263
264
265
266
267
268

269
270

271
272
273

274
275

276
277
278

279
280

281
282
283
284

285
286

287

288
289

290
291
292
293
294
295
296

297
298

299
300

301
302

303
304

305
306

307
308
309
310

311
312

313
314
315
316

317
318

319
320
321
322
323
324
325
326

327
328

329
330
331
332

333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
.TH winfo n 4.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
winfo \- Return window-related information
.SH SYNOPSIS
\fBwinfo\fR \fIoption \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBwinfo\fR command is used to retrieve information about windows
managed by Tk.  It can take any of a number of different forms,
depending on the \fIoption\fR argument.  The legal forms are:

.TP
\fBwinfo atom \fR?\fB\-displayof \fIwindow\fR? \fIname\fR

Returns a decimal string giving the integer identifier for the
atom whose name is \fIname\fR.  If no atom exists with the name
\fIname\fR then a new one is created.
If the \fB\-displayof\fR option is given then the atom is looked
up on the display of \fIwindow\fR;  otherwise it is looked up on
the display of the application's main window.

.TP
\fBwinfo atomname \fR?\fB\-displayof \fIwindow\fR? \fIid\fR

Returns the textual name for the atom whose integer identifier is
\fIid\fR.
If the \fB\-displayof\fR option is given then the identifier is looked
up on the display of \fIwindow\fR;  otherwise it is looked up on
the display of the application's main window.
This command is the inverse of the \fBwinfo atom\fR command.
It generates an error if no such atom exists.

.TP
\fBwinfo cells \fIwindow\fR

Returns a decimal string giving the number of cells in the
color map for \fIwindow\fR.

.TP
\fBwinfo children \fIwindow\fR

Returns a list containing the path names of all the children
of \fIwindow\fR. Top-level windows are returned as children
of their logical parents. The list is in stacking order, with
the lowest window first, except for Top-level windows which
are not returned in stacking order. Use the \fBwm stackorder\fR
command to query the stacking order of Top-level windows.

.TP
\fBwinfo class \fIwindow\fR

Returns the class name for \fIwindow\fR.

.TP
\fBwinfo colormapfull \fIwindow\fR

Returns 1 if the colormap for \fIwindow\fR is known to be full, 0
otherwise.  The colormap for a window is
.QW known
to be full if the last
attempt to allocate a new color on that window failed and this
application has not freed any colors in the colormap since the
failed allocation.

.TP
\fBwinfo containing \fR?\fB\-displayof \fIwindow\fR? \fIrootX rootY\fR

Returns the path name for the window containing the point given
by \fIrootX\fR and \fIrootY\fR.
\fIRootX\fR and \fIrootY\fR are specified in screen units (i.e.
any form acceptable to \fBTk_GetPixels\fR) in the coordinate
system of the root window (if a virtual-root window manager is in
use then the coordinate system of the virtual root window is used).
If the \fB\-displayof\fR option is given then the coordinates refer
to the screen containing \fIwindow\fR;  otherwise they refer to the
screen of the application's main window.
If no window in this application contains the point then an empty
string is returned.
An empty string is also returned if the point lies in the title bar
or border of its highest containing toplevel in this application.
(Note that with some window managers the borders may be invisible.)
In selecting the containing window, children are given higher priority
than parents and among siblings the highest one in the stacking order is
chosen.

.TP
\fBwinfo depth \fIwindow\fR

Returns a decimal string giving the depth of \fIwindow\fR (number
of bits per pixel).

.TP
\fBwinfo exists \fIwindow\fR

Returns 1 if there exists a window named \fIwindow\fR, 0 if no such
window exists.

.TP
\fBwinfo fpixels \fIwindow\fR \fInumber\fR

Returns a floating-point value giving the number of pixels
in \fIwindow\fR corresponding to the distance given by \fInumber\fR.
\fINumber\fR may be specified in any of the forms acceptable
to \fBTk_GetScreenMM\fR, such as
.QW 2.0c
or
.QW 1i .
The return value may be fractional;  for an integer value, use
\fBwinfo pixels\fR.

.TP
\fBwinfo geometry \fIwindow\fR

Returns the geometry for \fIwindow\fR, in the form
\fIwidth\fBx\fIheight\fB+\fIx\fB+\fIy\fR.  All dimensions are
in pixels.

.TP
\fBwinfo height \fIwindow\fR

Returns a decimal string giving \fIwindow\fR's height in pixels.
When a window is first created its height will be 1 pixel;  the
height will eventually be changed by a geometry manager to fulfil
the window's needs.
If you need the true height immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqheight\fR to get the window's requested height
instead of its actual height.

.TP
\fBwinfo id \fIwindow\fR

Returns a hexadecimal string giving a low-level platform-specific
identifier for \fIwindow\fR.  On Unix platforms, this is the X
window identifier.  Under Windows, this is the Windows
HWND.  On the Macintosh the value has no meaning outside Tk.

.TP
\fBwinfo interps \fR?\fB\-displayof \fIwindow\fR?

Returns a list whose members are the names of all Tcl interpreters
(e.g. all Tk-based applications) currently registered for a particular display.
If the \fB\-displayof\fR option is given then the return value refers
to the display of \fIwindow\fR;  otherwise it refers to
the display of the application's main window.

.TP
\fBwinfo ismapped \fIwindow\fR

Returns \fB1\fR if \fIwindow\fR is currently mapped, \fB0\fR otherwise.

.TP
\fBwinfo manager \fIwindow\fR

Returns the name of the geometry manager currently
responsible for \fIwindow\fR, or an empty string if \fIwindow\fR
is not managed by any geometry manager.
The name is usually the name of the Tcl command for the geometry
manager, such as \fBpack\fR or \fBplace\fR.
If the geometry manager is a widget, such as canvases or text, the
name is the widget's class command, such as \fBcanvas\fR.

.TP
\fBwinfo name \fIwindow\fR

Returns \fIwindow\fR's name (i.e. its name within its parent, as opposed
to its full path name).
The command \fBwinfo name .\fR will return the name of the application.

.TP
\fBwinfo parent \fIwindow\fR

Returns the path name of \fIwindow\fR's parent, or an empty string
if \fIwindow\fR is the main window of the application.

.TP
\fBwinfo pathname \fR?\fB\-displayof \fIwindow\fR? \fIid\fR

Returns the path name of the window whose X identifier is \fIid\fR.
\fIId\fR must be a decimal, hexadecimal, or octal integer and must
correspond to a window in the invoking application.
If the \fB\-displayof\fR option is given then the identifier is looked
up on the display of \fIwindow\fR;  otherwise it is looked up on
the display of the application's main window.

.TP
\fBwinfo pixels \fIwindow\fR \fInumber\fR

Returns the number of pixels in \fIwindow\fR corresponding
to the distance given by \fInumber\fR.
\fINumber\fR may be specified in any of the forms acceptable
to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i .
The result is rounded to the nearest integer value;  for a
fractional result, use \fBwinfo fpixels\fR.

.TP
\fBwinfo pointerx \fIwindow\fR

If the mouse pointer is on the same screen as \fIwindow\fR, returns the
pointer's x coordinate, measured in pixels in the screen's root window.
If a virtual root window is in use on the screen, the position is
measured in the virtual root.
If the mouse pointer is not on the same screen as \fIwindow\fR then
-1 is returned.

.TP
\fBwinfo pointerxy \fIwindow\fR

If the mouse pointer is on the same screen as \fIwindow\fR, returns a list
with two elements, which are the pointer's x and y coordinates measured
in pixels in the screen's root window.
If a virtual root window is in use on the screen, the position
is computed in the virtual root.
If the mouse pointer is not on the same screen as \fIwindow\fR then
both of the returned coordinates are \-1.

.TP
\fBwinfo pointery \fIwindow\fR

If the mouse pointer is on the same screen as \fIwindow\fR, returns the
pointer's y coordinate, measured in pixels in the screen's root window.
If a virtual root window is in use on the screen, the position
is computed in the virtual root.
If the mouse pointer is not on the same screen as \fIwindow\fR then
-1 is returned.

.TP
\fBwinfo reqheight \fIwindow\fR

Returns a decimal string giving \fIwindow\fR's requested height,
in pixels.  This is the value used by \fIwindow\fR's geometry
manager to compute its geometry.

.TP
\fBwinfo reqwidth \fIwindow\fR

Returns a decimal string giving \fIwindow\fR's requested width,
in pixels.  This is the value used by \fIwindow\fR's geometry
manager to compute its geometry.

.TP
\fBwinfo rgb \fIwindow color\fR

Returns a list containing three decimal values in the range 0 to
65535, which are the
red, green, and blue intensities that correspond to \fIcolor\fR in
the window given by \fIwindow\fR.  \fIColor\fR
may be specified in any of the forms acceptable for a color
option.

.TP
\fBwinfo rootx \fIwindow\fR

Returns a decimal string giving the x-coordinate, in the root
window of the screen, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).

.TP
\fBwinfo rooty \fIwindow\fR

Returns a decimal string giving the y-coordinate, in the root
window of the screen, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).

.TP
\fBwinfo screen \fIwindow\fR

Returns the name of the screen associated with \fIwindow\fR, in
the form \fIdisplayName\fR.\fIscreenIndex\fR.

.TP
\fBwinfo screencells \fIwindow\fR

Returns a decimal string giving the number of cells in the default
color map for \fIwindow\fR's screen.

.TP
\fBwinfo screendepth \fIwindow\fR

Returns a decimal string giving the depth of the root window
of \fIwindow\fR's screen (number of bits per pixel).

.TP
\fBwinfo screenheight \fIwindow\fR

Returns a decimal string giving the height of \fIwindow\fR's screen,
in pixels.

.TP
\fBwinfo screenmmheight \fIwindow\fR

Returns a decimal string giving the height of \fIwindow\fR's screen,
in millimeters.

.TP
\fBwinfo screenmmwidth \fIwindow\fR

Returns a decimal string giving the width of \fIwindow\fR's screen,
in millimeters.

.TP
\fBwinfo screenvisual \fIwindow\fR

Returns one of the following strings to indicate the default visual
class for \fIwindow\fR's screen: \fBdirectcolor\fR, \fBgrayscale\fR,
\fBpseudocolor\fR, \fBstaticcolor\fR, \fBstaticgray\fR, or
\fBtruecolor\fR.

.TP
\fBwinfo screenwidth \fIwindow\fR

Returns a decimal string giving the width of \fIwindow\fR's screen,
in pixels.

.TP
\fBwinfo server \fIwindow\fR

Returns a string containing information about the server for
\fIwindow\fR's display.  The exact format of this string may vary
from platform to platform.  For X servers the string
has the form
.QW "\fBX\fImajor\fBR\fIminor vendor vendorVersion\fR"
where \fImajor\fR and \fIminor\fR are the version and revision
numbers provided by the server (e.g., \fBX11R5\fR), \fIvendor\fR
is the name of the vendor for the server, and \fIvendorRelease\fR
is an integer release number provided by the server.

.TP
\fBwinfo toplevel \fIwindow\fR

Returns the path name of the top-of-hierarchy window containing \fIwindow\fR.
In standard Tk this will always be a \fBtoplevel\fR widget, but extensions may
create other kinds of top-of-hierarchy widgets.

.TP
\fBwinfo viewable \fIwindow\fR

Returns 1 if \fIwindow\fR and all of its ancestors up through the
nearest toplevel window are mapped.  Returns 0 if any of these
windows are not mapped.

.TP
\fBwinfo visual \fIwindow\fR

Returns one of the following strings to indicate the visual
class for \fIwindow\fR: \fBdirectcolor\fR, \fBgrayscale\fR,
\fBpseudocolor\fR, \fBstaticcolor\fR, \fBstaticgray\fR, or
\fBtruecolor\fR.

.TP
\fBwinfo visualid \fIwindow\fR

Returns the X identifier for the visual for \fIwindow\fR.

.TP
\fBwinfo visualsavailable \fIwindow\fR ?\fBincludeids\fR?

Returns a list whose elements describe the visuals available for
\fIwindow\fR's screen.
Each element consists of a visual class followed by an integer depth.
The class has the same form as returned by \fBwinfo visual\fR.
The depth gives the number of bits per pixel in the visual.
In addition, if the \fBincludeids\fR argument is provided, then the
depth is followed by the X identifier for the visual.

.TP
\fBwinfo vrootheight \fIwindow\fR

Returns the height of the virtual root window associated with \fIwindow\fR
if there is one;  otherwise returns the height of \fIwindow\fR's screen.

.TP
\fBwinfo vrootwidth \fIwindow\fR

Returns the width of the virtual root window associated with \fIwindow\fR
if there is one;  otherwise returns the width of \fIwindow\fR's screen.

.TP
\fBwinfo vrootx \fIwindow\fR

Returns the x-offset of the virtual root window associated with \fIwindow\fR,
relative to the root window of its screen.
This is normally either zero or negative.
Returns 0 if there is no virtual root window for \fIwindow\fR.

.TP
\fBwinfo vrooty \fIwindow\fR

Returns the y-offset of the virtual root window associated with \fIwindow\fR,
relative to the root window of its screen.
This is normally either zero or negative.
Returns 0 if there is no virtual root window for \fIwindow\fR.

.TP
\fBwinfo width \fIwindow\fR

Returns a decimal string giving \fIwindow\fR's width in pixels.
When a window is first created its width will be 1 pixel;  the
width will eventually be changed by a geometry manager to fulfil
the window's needs.
If you need the true width immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqwidth\fR to get the window's requested width
instead of its actual width.

.TP
\fBwinfo x \fIwindow\fR

Returns a decimal string giving the x-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).

.TP
\fBwinfo y \fIwindow\fR

Returns a decimal string giving the y-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.SH EXAMPLE
.PP
Print where the mouse pointer is and what window it is currently over:
.CS
lassign [\fBwinfo pointerxy\fR .] x y
puts \-nonewline "Mouse pointer at ($x,$y) which is "
set win [\fBwinfo containing\fR $x $y]
if {$win eq ""} {
    puts "over no window"
} else {
    puts "over $win"
}
.CE
.SH KEYWORDS
atom, children, class, geometry, height, identifier, information, interpreters,
mapped, parent, path name, screen, virtual root, width, window
'\" Local Variables:
'\" mode: nroff
'\" End:







|






>


>






>


>







>


>


>


>






>


>

>


>







>


>

















>


>


>


>


>

|
>









>


>



>


>








>


>




>


>





>


>

>


>







>


>



>


>


>


>






>

|
>









>


>






>


>







>


>






>


>



>


>



>


>






>


>




>


>




>


>


>


>


>


>


>


>


>


>


>


>


>


>




>


>


>


>









>


>



>


>



>


>




>


>

>


>







>


>


>


>


>


>




>


>




>


>








>


>




>


>









|













8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
.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\fI option \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:
.\" METHOD: atom
.TP
\fBwinfo atom \fR?\fB\-displayof \fIwindow\fR? \fIname\fR
.
Returns a decimal string giving the integer identifier for the
atom whose name is \fIname\fR.  If no atom exists with the name
\fIname\fR then a new one is created.
If the \fB\-displayof\fR option is given then the atom is looked
up on the display of \fIwindow\fR;  otherwise it is looked up on
the display of the application's main window.
.\" METHOD: atomname
.TP
\fBwinfo atomname \fR?\fB\-displayof \fIwindow\fR? \fIid\fR
.
Returns the textual name for the atom whose integer identifier is
\fIid\fR.
If the \fB\-displayof\fR option is given then the identifier is looked
up on the display of \fIwindow\fR;  otherwise it is looked up on
the display of the application's main window.
This command is the inverse of the \fBwinfo atom\fR command.
It generates an error if no such atom exists.
.\" METHOD: cells
.TP
\fBwinfo cells \fIwindow\fR
.
Returns a decimal string giving the number of cells in the
color map for \fIwindow\fR.
.\" METHOD: children
.TP
\fBwinfo children \fIwindow\fR
.
Returns a list containing the path names of all the children
of \fIwindow\fR. Top-level windows are returned as children
of their logical parents. The list is in stacking order, with
the lowest window first, except for Top-level windows which
are not returned in stacking order. Use the \fBwm stackorder\fR
command to query the stacking order of Top-level windows.
.\" METHOD: class
.TP
\fBwinfo class \fIwindow\fR
.
Returns the class name for \fIwindow\fR.
.\" METHOD: colormapfull
.TP
\fBwinfo colormapfull \fIwindow\fR
.
Returns 1 if the colormap for \fIwindow\fR is known to be full, 0
otherwise.  The colormap for a window is
.QW known
to be full if the last
attempt to allocate a new color on that window failed and this
application has not freed any colors in the colormap since the
failed allocation.
.\" METHOD: containing
.TP
\fBwinfo containing \fR?\fB\-displayof \fIwindow\fR? \fIrootX rootY\fR
.
Returns the path name for the window containing the point given
by \fIrootX\fR and \fIrootY\fR.
\fIRootX\fR and \fIrootY\fR are specified in screen units (i.e.
any form acceptable to \fBTk_GetPixels\fR) in the coordinate
system of the root window (if a virtual-root window manager is in
use then the coordinate system of the virtual root window is used).
If the \fB\-displayof\fR option is given then the coordinates refer
to the screen containing \fIwindow\fR;  otherwise they refer to the
screen of the application's main window.
If no window in this application contains the point then an empty
string is returned.
An empty string is also returned if the point lies in the title bar
or border of its highest containing toplevel in this application.
(Note that with some window managers the borders may be invisible.)
In selecting the containing window, children are given higher priority
than parents and among siblings the highest one in the stacking order is
chosen.
.\" METHOD: depth
.TP
\fBwinfo depth \fIwindow\fR
.
Returns a decimal string giving the depth of \fIwindow\fR (number
of bits per pixel).
.\" METHOD: exists
.TP
\fBwinfo exists \fIwindow\fR
.
Returns 1 if there exists a window named \fIwindow\fR, 0 if no such
window exists.
.\" METHOD: fpixels
.TP
\fBwinfo fpixels \fIwindow number\fR
.
Returns a floating-point value giving the number of pixels
in \fIwindow\fR corresponding to the distance given by \fInumber\fR.
\fINumber\fR may be specified in any of the forms acceptable
to \fBTk_GetScreenMM\fR, such as
.QW 2.0c
or
.QW 1i .
The return value may be fractional;  for an integer value, use
\fBwinfo pixels\fR.
.\" METHOD: geometry
.TP
\fBwinfo geometry \fIwindow\fR
.
Returns the geometry for \fIwindow\fR, in the form
\fIwidth\fBx\fIheight\fB+\fIx\fB+\fIy\fR.  All dimensions are
in pixels.
.\" METHOD: height
.TP
\fBwinfo height \fIwindow\fR
.
Returns a decimal string giving \fIwindow\fR's height in pixels.
When a window is first created its height will be 1 pixel;  the
height will eventually be changed by a geometry manager to fulfil
the window's needs.
If you need the true height immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqheight\fR to get the window's requested height
instead of its actual height.
.\" METHOD: id
.TP
\fBwinfo id \fIwindow\fR
.
Returns a hexadecimal string giving a low-level platform-specific
identifier for \fIwindow\fR.  On Unix platforms, this is the X
window identifier.  Under Windows, this is the Windows
HWND.  On the Macintosh the value has no meaning outside Tk.
.\" METHOD: interps
.TP
\fBwinfo interps \fR?\fB\-displayof \fIwindow\fR?
.
Returns a list whose members are the names of all Tcl interpreters
(e.g. all Tk-based applications) currently registered for a particular display.
If the \fB\-displayof\fR option is given then the return value refers
to the display of \fIwindow\fR;  otherwise it refers to
the display of the application's main window.
.\" METHOD: ismapped
.TP
\fBwinfo ismapped \fIwindow\fR
.
Returns \fB1\fR if \fIwindow\fR is currently mapped, \fB0\fR otherwise.
.\" METHOD: manager
.TP
\fBwinfo manager \fIwindow\fR
.
Returns the name of the geometry manager currently
responsible for \fIwindow\fR, or an empty string if \fIwindow\fR
is not managed by any geometry manager.
The name is usually the name of the Tcl command for the geometry
manager, such as \fBpack\fR or \fBplace\fR.
If the geometry manager is a widget, such as canvases or text, the
name is the widget's class command, such as \fBcanvas\fR.
.\" METHOD: name
.TP
\fBwinfo name \fIwindow\fR
.
Returns \fIwindow\fR's name (i.e. its name within its parent, as opposed
to its full path name).
The command \fBwinfo name .\fR will return the name of the application.
.\" METHOD: parent
.TP
\fBwinfo parent \fIwindow\fR
.
Returns the path name of \fIwindow\fR's parent, or an empty string
if \fIwindow\fR is the main window of the application.
.\" METHOD: pathname
.TP
\fBwinfo pathname \fR?\fB\-displayof \fIwindow\fR? \fIid\fR
.
Returns the path name of the window whose X identifier is \fIid\fR.
\fIId\fR must be a decimal, hexadecimal, or octal integer and must
correspond to a window in the invoking application.
If the \fB\-displayof\fR option is given then the identifier is looked
up on the display of \fIwindow\fR;  otherwise it is looked up on
the display of the application's main window.
.\" METHOD: pixels
.TP
\fBwinfo pixels \fIwindow number\fR
.
Returns the number of pixels in \fIwindow\fR corresponding
to the distance given by \fInumber\fR.
\fINumber\fR may be specified in any of the forms acceptable
to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i .
The result is rounded to the nearest integer value;  for a
fractional result, use \fBwinfo fpixels\fR.
.\" METHOD: pointerx
.TP
\fBwinfo pointerx \fIwindow\fR
.
If the mouse pointer is on the same screen as \fIwindow\fR, returns the
pointer's x coordinate, measured in pixels in the screen's root window.
If a virtual root window is in use on the screen, the position is
measured in the virtual root.
If the mouse pointer is not on the same screen as \fIwindow\fR then
-1 is returned.
.\" METHOD: pointerxy
.TP
\fBwinfo pointerxy \fIwindow\fR
.
If the mouse pointer is on the same screen as \fIwindow\fR, returns a list
with two elements, which are the pointer's x and y coordinates measured
in pixels in the screen's root window.
If a virtual root window is in use on the screen, the position
is computed in the virtual root.
If the mouse pointer is not on the same screen as \fIwindow\fR then
both of the returned coordinates are \-1.
.\" METHOD: pointery
.TP
\fBwinfo pointery \fIwindow\fR
.
If the mouse pointer is on the same screen as \fIwindow\fR, returns the
pointer's y coordinate, measured in pixels in the screen's root window.
If a virtual root window is in use on the screen, the position
is computed in the virtual root.
If the mouse pointer is not on the same screen as \fIwindow\fR then
-1 is returned.
.\" METHOD: reqheight
.TP
\fBwinfo reqheight \fIwindow\fR
.
Returns a decimal string giving \fIwindow\fR's requested height,
in pixels.  This is the value used by \fIwindow\fR's geometry
manager to compute its geometry.
.\" METHOD: reqwidth
.TP
\fBwinfo reqwidth \fIwindow\fR
.
Returns a decimal string giving \fIwindow\fR's requested width,
in pixels.  This is the value used by \fIwindow\fR's geometry
manager to compute its geometry.
.\" METHOD: rgb
.TP
\fBwinfo rgb \fIwindow color\fR
.
Returns a list containing three decimal values in the range 0 to
65535, which are the
red, green, and blue intensities that correspond to \fIcolor\fR in
the window given by \fIwindow\fR.  \fIColor\fR
may be specified in any of the forms acceptable for a color
option.
.\" METHOD: rootx
.TP
\fBwinfo rootx \fIwindow\fR
.
Returns a decimal string giving the x-coordinate, in the root
window of the screen, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.\" METHOD: rooty
.TP
\fBwinfo rooty \fIwindow\fR
.
Returns a decimal string giving the y-coordinate, in the root
window of the screen, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.\" METHOD: screen
.TP
\fBwinfo screen \fIwindow\fR
.
Returns the name of the screen associated with \fIwindow\fR, in
the form \fIdisplayName\fR.\fIscreenIndex\fR.
.\" METHOD: screencells
.TP
\fBwinfo screencells \fIwindow\fR
.
Returns a decimal string giving the number of cells in the default
color map for \fIwindow\fR's screen.
.\" METHOD: screendepth
.TP
\fBwinfo screendepth \fIwindow\fR
.
Returns a decimal string giving the depth of the root window
of \fIwindow\fR's screen (number of bits per pixel).
.\" METHOD: screenheight
.TP
\fBwinfo screenheight \fIwindow\fR
.
Returns a decimal string giving the height of \fIwindow\fR's screen,
in pixels.
.\" METHOD: screenmmheight
.TP
\fBwinfo screenmmheight \fIwindow\fR
.
Returns a decimal string giving the height of \fIwindow\fR's screen,
in millimeters.
.\" METHOD: screenmmwidth
.TP
\fBwinfo screenmmwidth \fIwindow\fR
.
Returns a decimal string giving the width of \fIwindow\fR's screen,
in millimeters.
.\" METHOD: screenvisual
.TP
\fBwinfo screenvisual \fIwindow\fR
.
Returns one of the following strings to indicate the default visual
class for \fIwindow\fR's screen: \fBdirectcolor\fR, \fBgrayscale\fR,
\fBpseudocolor\fR, \fBstaticcolor\fR, \fBstaticgray\fR, or
\fBtruecolor\fR.
.\" METHOD: screenwidth
.TP
\fBwinfo screenwidth \fIwindow\fR
.
Returns a decimal string giving the width of \fIwindow\fR's screen,
in pixels.
.\" METHOD: server
.TP
\fBwinfo server \fIwindow\fR
.
Returns a string containing information about the server for
\fIwindow\fR's display.  The exact format of this string may vary
from platform to platform.  For X servers the string
has the form
.QW "\fBX\fImajor\fBR\fIminor vendor vendorVersion\fR"
where \fImajor\fR and \fIminor\fR are the version and revision
numbers provided by the server (e.g., \fBX11R5\fR), \fIvendor\fR
is the name of the vendor for the server, and \fIvendorRelease\fR
is an integer release number provided by the server.
.\" METHOD: toplevel
.TP
\fBwinfo toplevel \fIwindow\fR
.
Returns the path name of the top-of-hierarchy window containing \fIwindow\fR.
In standard Tk this will always be a \fBtoplevel\fR widget, but extensions may
create other kinds of top-of-hierarchy widgets.
.\" METHOD: viewable
.TP
\fBwinfo viewable \fIwindow\fR
.
Returns 1 if \fIwindow\fR and all of its ancestors up through the
nearest toplevel window are mapped.  Returns 0 if any of these
windows are not mapped.
.\" METHOD: visual
.TP
\fBwinfo visual \fIwindow\fR
.
Returns one of the following strings to indicate the visual
class for \fIwindow\fR: \fBdirectcolor\fR, \fBgrayscale\fR,
\fBpseudocolor\fR, \fBstaticcolor\fR, \fBstaticgray\fR, or
\fBtruecolor\fR.
.\" METHOD: visualid
.TP
\fBwinfo visualid \fIwindow\fR
.
Returns the X identifier for the visual for \fIwindow\fR.
.\" METHOD: visualsavailable
.TP
\fBwinfo visualsavailable \fIwindow\fR ?\fBincludeids\fR?
.
Returns a list whose elements describe the visuals available for
\fIwindow\fR's screen.
Each element consists of a visual class followed by an integer depth.
The class has the same form as returned by \fBwinfo visual\fR.
The depth gives the number of bits per pixel in the visual.
In addition, if the \fBincludeids\fR argument is provided, then the
depth is followed by the X identifier for the visual.
.\" METHOD: vrootheight
.TP
\fBwinfo vrootheight \fIwindow\fR
.
Returns the height of the virtual root window associated with \fIwindow\fR
if there is one;  otherwise returns the height of \fIwindow\fR's screen.
.\" METHOD: vrootwidth
.TP
\fBwinfo vrootwidth \fIwindow\fR
.
Returns the width of the virtual root window associated with \fIwindow\fR
if there is one;  otherwise returns the width of \fIwindow\fR's screen.
.\" METHOD: vrootx
.TP
\fBwinfo vrootx \fIwindow\fR
.
Returns the x-offset of the virtual root window associated with \fIwindow\fR,
relative to the root window of its screen.
This is normally either zero or negative.
Returns 0 if there is no virtual root window for \fIwindow\fR.
.\" METHOD: vrooty
.TP
\fBwinfo vrooty \fIwindow\fR
.
Returns the y-offset of the virtual root window associated with \fIwindow\fR,
relative to the root window of its screen.
This is normally either zero or negative.
Returns 0 if there is no virtual root window for \fIwindow\fR.
.\" METHOD: width
.TP
\fBwinfo width \fIwindow\fR
.
Returns a decimal string giving \fIwindow\fR's width in pixels.
When a window is first created its width will be 1 pixel;  the
width will eventually be changed by a geometry manager to fulfil
the window's needs.
If you need the true width immediately after creating a widget,
invoke \fBupdate\fR to force the geometry manager to arrange it,
or use \fBwinfo reqwidth\fR to get the window's requested width
instead of its actual width.
.\" METHOD: x
.TP
\fBwinfo x \fIwindow\fR
.
Returns a decimal string giving the x-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.\" METHOD: y
.TP
\fBwinfo y \fIwindow\fR
.
Returns a decimal string giving the y-coordinate, in \fIwindow\fR's
parent, of the
upper-left corner of \fIwindow\fR's border (or \fIwindow\fR if it
has no border).
.SH EXAMPLE
.PP
Print where the mouse pointer is and what window it is currently over:
.CS
lassign [\fBwinfo pointerxy\fR .] x y
puts -nonewline "Mouse pointer at ($x,$y) which is "
set win [\fBwinfo containing\fR $x $y]
if {$win eq ""} {
    puts "over no window"
} else {
    puts "over $win"
}
.CE
.SH KEYWORDS
atom, children, class, geometry, height, identifier, information, interpreters,
mapped, parent, path name, screen, virtual root, width, window
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/wish.1.

10
11
12
13
14
15
16

17
18
19

20
21
22

23
24

25
26
27
28

29
30
31

32
33
34
35

36
37
38
39
40
41
42
43
44
45
46

47
48
49
50

51
52
53
54
55
56
57
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wish \- Simple windowing shell
.SH SYNOPSIS
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg ...\fR?
.SH OPTIONS

.IP "\fB\-encoding \fIname\fR" 20
Specifies the encoding of the text stored in \fIfileName\fR.
This option is only recognized prior to the \fIfileName\fR argument.

.IP "\fB\-colormap \fInew\fR" 20
Specifies that the window should have a new private colormap instead of
using the default colormap for the screen.

.IP "\fB\-display \fIdisplay\fR" 20
Display (and screen) on which to display window.

.IP "\fB\-geometry \fIgeometry\fR" 20
Initial geometry to use for window.  If this option is specified, its
value is stored in the \fBgeometry\fR global variable of the application's
Tcl interpreter.

.IP "\fB\-name \fIname\fR" 20
Use \fIname\fR as the title to be displayed in the window, and
as the name of the interpreter for \fBsend\fR commands.

.IP "\fB\-sync\fR" 20
Execute all X server commands synchronously, so that errors
are reported immediately.  This will result in much slower
execution, but it is useful for debugging.

.IP "\fB\-use\fR \fIid\fR" 20
Specifies that the main window for the application is to be embedded in
the window whose identifier is \fIid\fR, instead of being created as an
independent toplevel window.  \fIId\fR must be specified in the same
way as the value for the \fB\-use\fR option for toplevel widgets (i.e.
it has a form like that returned by the \fBwinfo id\fR command).
.RS
Note that on some platforms this will only work correctly if \fIid\fR
refers to a Tk \fBframe\fR or \fBtoplevel\fR that has its
\fB\-container\fR option enabled.
.RE

.IP "\fB\-visual \fIvisual\fR" 20
Specifies the visual to use for the window.
\fIVisual\fR may have any of the forms supported by the \fBTk_GetVisual\fR
procedure.

.IP "\fB\-\|\-\fR" 20
Pass all remaining arguments through to the script's \fBargv\fR
variable without interpreting them.
This provides a mechanism for passing arguments such as \fB\-name\fR
to a script instead of having \fBwish\fR interpret them.
.BE
.SH DESCRIPTION







>



>



>


>




>



>




>











>




>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wish \- Simple windowing shell
.SH SYNOPSIS
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg ...\fR?
.SH OPTIONS
.\" OPTION: -encoding
.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.
.\" OPTION: -colormap
.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.
.\" OPTION: -display
.IP "\fB\-display \fIdisplay\fR" 20
Display (and screen) on which to display window.
.\" OPTION: -geometry
.IP "\fB\-geometry \fIgeometry\fR" 20
Initial geometry to use for window.  If this option is specified, its
value is stored in the \fBgeometry\fR global variable of the application's
Tcl interpreter.
.\" OPTION: -name
.IP "\fB\-name \fIname\fR" 20
Use \fIname\fR as the title to be displayed in the window, and
as the name of the interpreter for \fBsend\fR commands.
.\" OPTION: -sync
.IP "\fB\-sync\fR" 20
Execute all X server commands synchronously, so that errors
are reported immediately.  This will result in much slower
execution, but it is useful for debugging.
.\" OPTION: -use
.IP "\fB\-use\fR \fIid\fR" 20
Specifies that the main window for the application is to be embedded in
the window whose identifier is \fIid\fR, instead of being created as an
independent toplevel window.  \fIId\fR must be specified in the same
way as the value for the \fB\-use\fR option for toplevel widgets (i.e.
it has a form like that returned by the \fBwinfo id\fR command).
.RS
Note that on some platforms this will only work correctly if \fIid\fR
refers to a Tk \fBframe\fR or \fBtoplevel\fR that has its
\fB\-container\fR option enabled.
.RE
.\" OPTION: -visual
.IP "\fB\-visual \fIvisual\fR" 20
Specifies the visual to use for the window.
\fIVisual\fR may have any of the forms supported by the \fBTk_GetVisual\fR
procedure.
.\" OPTION: --
.IP "\fB\-\|\-\fR" 20
Pass all remaining arguments through to the script's \fBargv\fR
variable without interpreting them.
This provides a mechanism for passing arguments such as \fB\-name\fR
to a script instead of having \fBwish\fR interpret them.
.BE
.SH DESCRIPTION
113
114
115
116
117
118
119
120

121
122

123
124

125
126

127
128
129
130

131
132

133
134

135
136

137
138
139
140
141

142
143

144
145
146
147
148
149
150
.PP
The class of the application, which is used for purposes such as
specifying options with a \fBRESOURCE_MANAGER\fR property or .Xdefaults
file, is the same as its name except that the first letter is
capitalized.
.SH "VARIABLES"
.PP
\fBWish\fR sets the following Tcl variables:

.TP 15
\fBargc\fR

Contains a count of the number of \fIarg\fR arguments (0 if none),
not including the options described above.

.TP 15
\fBargv\fR

Contains a Tcl list whose elements are the \fIarg\fR arguments
that follow a \fB\-\|\-\fR option or do not match any of the
options described in \fBOPTIONS\fR above, in order, or an empty string
if there are no such arguments.

.TP 15
\fBargv0\fR

Contains \fIfileName\fR if it was specified.
Otherwise, contains the name by which \fBwish\fR was invoked.

.TP 15
\fBgeometry\fR

If the \fB\-geometry\fR option is specified, \fBwish\fR copies its
value into this variable.  If the variable still exists after
\fIfileName\fR has been evaluated, \fBwish\fR uses the value of
the variable in a \fBwm geometry\fR command to set the main
window's geometry.

.TP 15
\fBtcl_interactive\fR

Contains 1 if \fBwish\fR is reading commands interactively (\fIfileName\fR
was not specified and standard input is a terminal-like
device), 0 otherwise.
.SH "SCRIPT FILES"
.PP
If you create a Tcl script in a file whose first line is
.CS







|
>


>


>


>




>


>


>


>





>


>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
.PP
The class of the application, which is used for purposes such as
specifying options with a \fBRESOURCE_MANAGER\fR property or .Xdefaults
file, is the same as its name except that the first letter is
capitalized.
.SH "VARIABLES"
.PP
\fBWish\fR sets the following global Tcl variables:
.\" VARIABLE: argc
.TP 15
\fBargc\fR
.
Contains a count of the number of \fIarg\fR arguments (0 if none),
not including the options described above.
.\" VARIABLE: argv
.TP 15
\fBargv\fR
.
Contains a Tcl list whose elements are the \fIarg\fR arguments
that follow a \fB\-\|\-\fR option or do not match any of the
options described in \fBOPTIONS\fR above, in order, or an empty string
if there are no such arguments.
.\" VARIABLE: argv0
.TP 15
\fBargv0\fR
.
Contains \fIfileName\fR if it was specified.
Otherwise, contains the name by which \fBwish\fR was invoked.
.\" VARIABLE: geometry
.TP 15
\fBgeometry\fR
.
If the \fB\-geometry\fR option is specified, \fBwish\fR copies its
value into this variable.  If the variable still exists after
\fIfileName\fR has been evaluated, \fBwish\fR uses the value of
the variable in a \fBwm geometry\fR command to set the main
window's geometry.
.\" VARIABLE: tcl_interactive
.TP 15
\fBtcl_interactive\fR
.
Contains 1 if \fBwish\fR is reading commands interactively (\fIfileName\fR
was not specified and standard input is a terminal-like
device), 0 otherwise.
.SH "SCRIPT FILES"
.PP
If you create a Tcl script in a file whose first line is
.CS

Changes to doc/wm.n.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

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

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

61
62
63
64
65
66
67

68
69
70
71
72
73

74
75
76
77
78
79

80
81
82
83

84
85
86
87

88
89
90
91
92
93
94
95
96
97





























98
99
100
101
102
103

104
105
106
107

108










































109
110
111
112

113
114
115
116
117
118
119
120
121
122
123

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

204
205
206
207
208
209
210
211
212
213
214

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

228
229
230
231
232
233
234
.TH wm n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wm \- Communicate with window manager
.SH SYNOPSIS
\fBwm\fR \fIoption window \fR?\fIargs\fR?
.BE
.SH DESCRIPTION
.PP
The \fBwm\fR command is used to interact with window managers in
order to control such things as the title for a window, its geometry,
or the increments in terms of which it may be resized.  The \fBwm\fR
command can take any of a number of different forms, depending on
the \fIoption\fR argument.  All of the forms expect at least one
additional argument, \fIwindow\fR, which must be the path name of a
top-level window.
.PP
The legal forms for the \fBwm\fR command are:

.TP
\fBwm aspect \fIwindow\fR ?\fIminNumer minDenom maxNumer maxDenom\fR?
.
If \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
are all specified, then they will be passed to the window manager
and the window manager should use them to enforce a range of
acceptable aspect ratios for \fIwindow\fR.  The aspect ratio of
\fIwindow\fR (width/length) will be constrained to lie
between \fIminNumer\fR/\fIminDenom\fR and \fImaxNumer\fR/\fImaxDenom\fR.
If \fIminNumer\fR etc. are all specified as empty strings, then
any existing aspect ratio restrictions are removed.
If \fIminNumer\fR etc. are specified, then the command returns an
empty string.  Otherwise, it returns
a Tcl list containing four elements, which are the current values
of \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
(if no aspect restrictions are in effect, then an empty string is
returned).

.TP
\fBwm attributes \fIwindow\fR
.TP
\fBwm attributes \fIwindow\fR ?\fBoption\fR?
.TP
\fBwm attributes \fIwindow\fR ?\fBoption value option value...\fR?
.
This subcommand returns or sets platform specific attributes associated
with a window. The first form returns a list of the platform specific
flags and their values. The second form returns the value for the
specific option. The third form sets one or more of the values. The
values are as follows:
.RS
.PP
All platforms support the following attributes (though X11 users
should see the notes below):

.TP
\fB\-alpha\fR
.
Specifies the alpha transparency level of the toplevel. It accepts a value
from \fB0.0\fR (fully transparent) to \fB1.0\fR (opaque).  Values outside that
range will be constrained.  Where not supported, the \fB\-alpha\fR value
remains at \fB1.0\fR.

.TP
\fB\-fullscreen\fR
.
Places the window in a mode that takes up the entire screen, has no
borders, and covers the general use area (i.e. Start menu and taskbar on
Windows, dock and menubar on OSX, general window decorations on X11).

.TP
\fB\-topmost\fR
.
Specifies whether this is a topmost window (displays above all other windows).
.PP
On Windows, the following attributes may be set.

.TP
\fB\-disabled\fR
.
Specifies whether the window is in a disabled state.

.TP
\fB\-toolwindow\fR
.
Specifies a toolwindow style window (as defined in the MSDN).

.TP
\fB\-transparentcolor\fR
.
Specifies the transparent color index of the toplevel.  It takes any color
value accepted by \fBTk_GetColor\fR.  If the empty string is specified
(default), no transparent color is used.  This is supported on Windows
2000/XP+.  Where not supported, the \fB\-transparentcolor\fR value remains
at \fB{}\fR.
.PP
On Mac OS X, the following attributes may be set.





























.TP
\fB\-modified\fR
.
Specifies the modification state of the window (determines whether the
window close widget contains the modification indicator and whether the
proxy icon is draggable).

.TP
\fB\-notify\fR
.
Specifies process notification state (bouncing of the application dock icon).

.TP










































\fB\-titlepath\fR
.
Specifies the path of the file referenced as the window proxy icon (which
can be dragged and dropped in lieu of the file's finder icon).

.TP
\fB\-transparent\fR
.
Makes the window content area transparent and turns off the window shadow. For
the transparency to be effective, the toplevel background needs to be set to a
color with some alpha, e.g.
.QW systemTransparent .
.PP
On X11, the following attributes may be set. These are not supported by all
window managers, and will have no effect under older WMs.
.\" See http://www.freedesktop.org/Standards/wm-spec

.TP
\fB\-type\fR
.VS 8.6
Requests that the window should be interpreted by the window manager as being
of the specified type(s). This may cause the window to be decorated in a
different way or otherwise managed differently, though exactly what happens is
entirely up to the window manager. A list of types may be used, in order of
preference. The following values are mapped to constants defined in the EWMH
specification (using others is possible, but not advised):
.RS
.TP
\fBdesktop\fR
.
indicates a desktop feature,
.TP
\fBdock\fR
.
indicates a dock/panel feature,
.TP
\fBtoolbar\fR
.
indicates a toolbar window that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,
.TP
\fBmenu\fR
.
indicates a torn-off menu that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,
.TP
\fButility\fR
.
indicates a utility window (e.g., palette or toolbox) that should be acting on
behalf of another window, as indicated with \fBwm transient\fR,
.TP
\fBsplash\fR
.
indicates a splash screen, displayed during application start up,
.TP
\fBdialog\fR
.
indicates a general dialog window, that should be acting on behalf of another
window, as indicated with \fBwm transient\fR,
.TP
\fBdropdown_menu\fR
.
indicates a menu summoned from a menu bar, which should usually also be set to
be override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBpopup_menu\fR
.
indicates a popup menu, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBtooltip\fR
.
indicates a tooltip window, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBnotification\fR
.
indicates a window that provides a background notification of some event,
which should usually also be set to be override-redirected (with \fBwm
overrideredirect\fR),
.TP
\fBcombo\fR
.
indicates the drop-down list of a combobox widget, which should usually also
be set to be override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBdnd\fR
.
indicates a window that represents something being dragged, which should
usually also be set to be override-redirected (with
\fBwm overrideredirect\fR),
.TP
\fBnormal\fR
.
indicates a window that has no special interpretation.
.RE
.VE 8.6

.TP
\fB\-zoomed\fR
.
Requests that the window should be maximized. This is the same as \fBwm state
zoomed\fR on Windows and Mac OS X.
.PP
On X11, changes to window attributes are performed asynchronously. Querying
the value of an attribute returns the current state, which will not be the
same as the value most recently set if the window manager has not yet
processed the request or if it does not support the attribute.
.RE

.TP
\fBwm client \fIwindow\fR ?\fIname\fR?
.
If \fIname\fR is specified, this command stores \fIname\fR (which
should be the name of
the host on which the application is executing) in \fIwindow\fR's
\fBWM_CLIENT_MACHINE\fR property for use by the window manager or
session manager.
The command returns an empty string in this case.
If \fIname\fR is not specified, the command returns the last name
set in a \fBwm client\fR command for \fIwindow\fR.
If \fIname\fR is specified as an empty string, the command deletes the
\fBWM_CLIENT_MACHINE\fR property from \fIwindow\fR.

.TP
\fBwm colormapwindows \fIwindow\fR ?\fIwindowList\fR?
.
This command is used to manipulate the \fBWM_COLORMAP_WINDOWS\fR
property, which provides information to the window managers about
windows that have private colormaps.
.RS







|












>

















>
















>







>






>






>




>




>









|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>




>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
>










|
>










<
|
<

<
|
<

<
|
<


<
|
<


<
|
<


<
|
<

<
|
<


<
|
<


<
|
<


<
|
<


<
|
<



<
|
<


<
|
<



<
|
<



>











>













>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

217

218

219

220

221

222
223

224

225
226

227

228
229

230

231

232

233
234

235

236
237

238

239
240

241

242
243

244

245
246
247

248

249
250

251

252
253
254

255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
.TH wm n 8.5 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wm \- Communicate with window manager
.SH SYNOPSIS
\fBwm\fI option window \fR?\fIargs\fR?
.BE
.SH DESCRIPTION
.PP
The \fBwm\fR command is used to interact with window managers in
order to control such things as the title for a window, its geometry,
or the increments in terms of which it may be resized.  The \fBwm\fR
command can take any of a number of different forms, depending on
the \fIoption\fR argument.  All of the forms expect at least one
additional argument, \fIwindow\fR, which must be the path name of a
top-level window.
.PP
The legal forms for the \fBwm\fR command are:
.\" METHOD: aspect
.TP
\fBwm aspect \fIwindow\fR ?\fIminNumer minDenom maxNumer maxDenom\fR?
.
If \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
are all specified, then they will be passed to the window manager
and the window manager should use them to enforce a range of
acceptable aspect ratios for \fIwindow\fR.  The aspect ratio of
\fIwindow\fR (width/length) will be constrained to lie
between \fIminNumer\fR/\fIminDenom\fR and \fImaxNumer\fR/\fImaxDenom\fR.
If \fIminNumer\fR etc. are all specified as empty strings, then
any existing aspect ratio restrictions are removed.
If \fIminNumer\fR etc. are specified, then the command returns an
empty string.  Otherwise, it returns
a Tcl list containing four elements, which are the current values
of \fIminNumer\fR, \fIminDenom\fR, \fImaxNumer\fR, and \fImaxDenom\fR
(if no aspect restrictions are in effect, then an empty string is
returned).
.\" METHOD: attributes
.TP
\fBwm attributes \fIwindow\fR
.TP
\fBwm attributes \fIwindow\fR ?\fBoption\fR?
.TP
\fBwm attributes \fIwindow\fR ?\fBoption value option value...\fR?
.
This subcommand returns or sets platform specific attributes associated
with a window. The first form returns a list of the platform specific
flags and their values. The second form returns the value for the
specific option. The third form sets one or more of the values. The
values are as follows:
.RS
.PP
All platforms support the following attributes (though X11 users
should see the notes below):
.\" OPTION: -alpha
.TP
\fB\-alpha\fR
.
Specifies the alpha transparency level of the toplevel. It accepts a value
from \fB0.0\fR (fully transparent) to \fB1.0\fR (opaque).  Values outside that
range will be constrained.  Where not supported, the \fB\-alpha\fR value
remains at \fB1.0\fR.
.\" OPTION: -fullscreen
.TP
\fB\-fullscreen\fR
.
Places the window in a mode that takes up the entire screen, has no
borders, and covers the general use area (i.e. Start menu and taskbar on
Windows, dock and menubar on OSX, general window decorations on X11).
.\" OPTION: -topmost
.TP
\fB\-topmost\fR
.
Specifies whether this is a topmost window (displays above all other windows).
.PP
On Windows, the following attributes may be set.
.\" OPTION: -disabled
.TP
\fB\-disabled\fR
.
Specifies whether the window is in a disabled state.
.\" OPTION: -toolwindow
.TP
\fB\-toolwindow\fR
.
Specifies a toolwindow style window (as defined in the MSDN).
.\" OPTION: -transparentcolor
.TP
\fB\-transparentcolor\fR
.
Specifies the transparent color index of the toplevel.  It takes any color
value accepted by \fBTk_GetColor\fR.  If the empty string is specified
(default), no transparent color is used.  This is supported on Windows
2000/XP+.  Where not supported, the \fB\-transparentcolor\fR value remains
at \fB{}\fR.
.PP
On MacOS, the following attributes may be set.
.\" OPTION: -appearance
.TP
\fB\-appearance\fR
.
Specifies whether the window is rendered in "dark mode".  Allowed
values are \fBauto\fR, \fBaqua\fR and \fBdarkaqua\fR.  If the setting
is auto then the appearance of the window is controlled by the
System Settings.
.\" OPTION: -class
.TP
\fB\-class\fR
.
Specifies whether the underlying Aqua window for a toplevel is an
object of the NSWindow class or the NSPanel class.  The two allowed
values for this option are \fBnswindow\fR and \fBnspanel\fR.  It is
not possible to change the class of the underlying Aqua window once
that window has been instantiated, and attempting to do that is an
error.  However it is allowed to set this option for a pathname that
does not correspond to an existing window.  Doing that causes the
class name to be cached for later use.  When a toplevel with that
pathname is eventually created, the cached class name will determine which
class is used for the underlying Aqua window.
.\" OPTION: -isdark
.TP
\fB\-isdark\fR
.
Returns a boolean value which is true if the window is currently in
dark mode.
.\" OPTION: -modified
.TP
\fB\-modified\fR
.
Specifies the modification state of the window (determines whether the
window close widget contains the modification indicator and whether the
proxy icon is draggable).
.\" OPTION: -notify
.TP
\fB\-notify\fR
.
Specifies process notification state (bouncing of the application dock icon).
.\" OPTION: -stylemask
.TP
\fB\-stylemask\fR
.
Specifies an integer to be assigned as the styleMask of the underlying
Aqua window.  (See the Apple documentation for styleMask property of
the NSWindow class.) The value of this option should be a list of
bitnames.  Each bit named in the list will be set to 1, and all other
bits will be set to 0.  The allowed bitnames are: \fBtitled\fR,
\fBclosable\fR, \fBminiaturizable\fR, \fBresizable\fR,
\fBfullsizecontentview\fR, \fBdocmodal\fR, \fButility\fR,
\fBnonactivatingpanel\fR, and \fBHUDwindow\fR.  Note that a side
effect of setting the fullsizecontentview bit is that the window title
bar becomes transparent.
.\" OPTION: -tabbingid
.TP
\fB\-tabbingid\fR
.
Controls how tabbed toplevel windows are grouped together.  Two tabs
in the same group must correspond to toplevels with the same
tabbingid, which can be an arbitrary UTF8 string.  In the Tk
implementation, changing the tabbingid of a toplevel in a tab group
will cause it to be moved into a different group, in which all tabs
have the new tabbingid or, if the new tabbingid is unique, to become
a normal non-tabbed toplevel.   It is allowed to set the tabbingid before the
toplevel is created.  If the pathname provided in the command does not
correspond to a toplevel, the value will be cached and used later when
the toplevel is actually created.
.\" OPTION: -tabbingmode
.TP
\fB\-tabbingmode\fR
.
Controls whether a toplevel can be opened as a tab within a tab group.
The allowed values are \fBauto\fR, \fBpreferred\fR or
\fBdisallowed\fR.  A toplevel can be opened as a tab in exactly two
situations: if its tabbingmode is \fBpreferred\fR; or if its
tabbingmode is \fBauto\fR and the user has selected "prefer tabs when
opening documents" in the Desktop and Dock panel of the System
Settings application.  It is allowed to set the tabbingmode before the
toplevel is created.  If the pathname provided in the command does not
correspond to a toplevel, the value will be cached and used later when
the toplevel is actually created.
.\" OPTION: -titlepath
.TP
\fB\-titlepath\fR
.
Specifies the path of the file referenced as the window proxy icon
(which can be dragged and dropped in lieu of the file's finder icon).
.\" OPTION: -transparent
.TP
\fB\-transparent\fR
.
Makes the window content area transparent and turns off the window shadow. For
the transparency to be effective, the toplevel background needs to be set to a
color with some alpha, e.g.
.QW systemTransparent .
.PP
On X11, the following attributes may be set. These are not supported by all
window managers, and will have no effect under older WMs.
.\" See https://www.freedesktop.org/wiki/Specifications/wm-spec/
.\" OPTION: -type
.TP
\fB\-type\fR
.VS 8.6
Requests that the window should be interpreted by the window manager as being
of the specified type(s). This may cause the window to be decorated in a
different way or otherwise managed differently, though exactly what happens is
entirely up to the window manager. A list of types may be used, in order of
preference. The following values are mapped to constants defined in the EWMH
specification (using others is possible, but not advised):
.RS

.IP \fBdesktop\fR

indicates a desktop feature,

.IP \fBdock\fR

indicates a dock/panel feature,

.IP \fBtoolbar\fR

indicates a toolbar window that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,

.IP \fBmenu\fR

indicates a torn-off menu that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,

.IP \fButility\fR

indicates a utility window (e.g., palette or toolbox) that should be acting on
behalf of another window, as indicated with \fBwm transient\fR,

.IP \fBsplash\fR

indicates a splash screen, displayed during application start up,

.IP \fBdialog\fR

indicates a general dialog window, that should be acting on behalf of another
window, as indicated with \fBwm transient\fR,

.IP \fBdropdown_menu\fR

indicates a menu summoned from a menu bar, which should usually also be set to
be override-redirected (with \fBwm overrideredirect\fR),

.IP \fBpopup_menu\fR

indicates a popup menu, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),

.IP \fBtooltip\fR

indicates a tooltip window, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),

.IP \fBnotification\fR

indicates a window that provides a background notification of some event,
which should usually also be set to be override-redirected (with \fBwm
overrideredirect\fR),

.IP \fBcombo\fR

indicates the drop-down list of a combobox widget, which should usually also
be set to be override-redirected (with \fBwm overrideredirect\fR),

.IP \fBdnd\fR

indicates a window that represents something being dragged, which should
usually also be set to be override-redirected (with
\fBwm overrideredirect\fR),

.IP \fBnormal\fR

indicates a window that has no special interpretation.
.RE
.VE 8.6
.\" OPTION: -zoomed
.TP
\fB\-zoomed\fR
.
Requests that the window should be maximized. This is the same as \fBwm state
zoomed\fR on Windows and Mac OS X.
.PP
On X11, changes to window attributes are performed asynchronously. Querying
the value of an attribute returns the current state, which will not be the
same as the value most recently set if the window manager has not yet
processed the request or if it does not support the attribute.
.RE
.\" METHOD: client
.TP
\fBwm client \fIwindow\fR ?\fIname\fR?
.
If \fIname\fR is specified, this command stores \fIname\fR (which
should be the name of
the host on which the application is executing) in \fIwindow\fR's
\fBWM_CLIENT_MACHINE\fR property for use by the window manager or
session manager.
The command returns an empty string in this case.
If \fIname\fR is not specified, the command returns the last name
set in a \fBwm client\fR command for \fIwindow\fR.
If \fIname\fR is specified as an empty string, the command deletes the
\fBWM_CLIENT_MACHINE\fR property from \fIwindow\fR.
.\" METHOD: colormapwindows
.TP
\fBwm colormapwindows \fIwindow\fR ?\fIwindowList\fR?
.
This command is used to manipulate the \fBWM_COLORMAP_WINDOWS\fR
property, which provides information to the window managers about
windows that have private colormaps.
.RS
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
If \fBwm colormapwindows\fR is not invoked, Tk will automatically set
the property for each top-level window to all the internal windows
whose colormaps differ from their parents, followed by the top-level
itself;  the order of the internal windows is undefined.
See the ICCCM documentation for more information on the
\fBWM_COLORMAP_WINDOWS\fR property.
.RE

.TP
\fBwm command \fIwindow\fR ?\fIvalue\fR?
.
If \fIvalue\fR is specified, this command stores \fIvalue\fR in \fIwindow\fR's
\fBWM_COMMAND\fR property for use by the window manager or
session manager and returns an empty string.
\fIValue\fR must have proper list structure;  the elements should
contain the words of the command used to invoke the application.
If \fIvalue\fR is not specified then the command returns the last value
set in a \fBwm command\fR command for \fIwindow\fR.
If \fIvalue\fR is specified as an empty string, the command
deletes the \fBWM_COMMAND\fR property from \fIwindow\fR.

.TP
\fBwm deiconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be displayed in normal (non-iconified) form.
This is done by mapping the window.  If the window has never been
mapped then this command will not map the window, but it will ensure
that when the window is first mapped it will be displayed
in de-iconified form.  On Windows, a deiconified window will also be
raised and be given the focus (made the active window).
Returns an empty string.

.TP
\fBwm focusmodel \fIwindow\fR ?\fBactive\fR|\fBpassive\fR?
.
If \fBactive\fR or \fBpassive\fR is supplied as an optional argument
to the command, then it specifies the focus model for \fIwindow\fR.
In this case the command returns an empty string.  If no additional
argument is supplied, then the command returns the current focus
model for \fIwindow\fR.
.RS
.PP
An \fBactive\fR focus model means that \fIwindow\fR will claim the
input focus for itself or its descendants, even at times when
the focus is currently in some other application.  \fBPassive\fR means that
\fIwindow\fR will never claim the focus for itself:  the window manager
should give the focus to \fIwindow\fR at appropriate times.  However,
once the focus has been given to \fIwindow\fR or one of its descendants,
the application may re-assign the focus among \fIwindow\fR's descendants.
The focus model defaults to \fBpassive\fR, and Tk's \fBfocus\fR command
assumes a passive model of focusing.
.RE

.TP
\fBwm forget \fIwindow\fR
.
The \fIwindow\fR will be unmapped from the screen and will no longer
be managed by \fBwm\fR.  Windows created with the \fBtoplevel\fR
command will be treated like \fBframe\fR windows once they are no
longer managed by \fBwm\fR, however, the \fB\-menu\fR configuration will be
remembered and the menus will return once the widget is managed again.

.TP
\fBwm frame \fIwindow\fR
.
If \fIwindow\fR has been reparented by the window manager into a
decorative frame, the command returns the platform specific window
identifier for the outermost frame that contains \fIwindow\fR (the
window whose parent is the root or virtual root).  If \fIwindow\fR
has not been reparented by the window manager then the command returns
the platform specific window identifier for \fIwindow\fR.

.TP
\fBwm geometry \fIwindow\fR ?\fInewGeometry\fR?
.
If \fInewGeometry\fR is specified, then the geometry of \fIwindow\fR
is changed and an empty string is returned.  Otherwise the current
geometry for \fIwindow\fR is returned (this is the most recent
geometry specified either by manual resizing or







>












>










>




















>








>









>







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
If \fBwm colormapwindows\fR is not invoked, Tk will automatically set
the property for each top-level window to all the internal windows
whose colormaps differ from their parents, followed by the top-level
itself;  the order of the internal windows is undefined.
See the ICCCM documentation for more information on the
\fBWM_COLORMAP_WINDOWS\fR property.
.RE
.\" METHOD: command
.TP
\fBwm command \fIwindow\fR ?\fIvalue\fR?
.
If \fIvalue\fR is specified, this command stores \fIvalue\fR in \fIwindow\fR's
\fBWM_COMMAND\fR property for use by the window manager or
session manager and returns an empty string.
\fIValue\fR must have proper list structure;  the elements should
contain the words of the command used to invoke the application.
If \fIvalue\fR is not specified then the command returns the last value
set in a \fBwm command\fR command for \fIwindow\fR.
If \fIvalue\fR is specified as an empty string, the command
deletes the \fBWM_COMMAND\fR property from \fIwindow\fR.
.\" METHOD: deiconify
.TP
\fBwm deiconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be displayed in normal (non-iconified) form.
This is done by mapping the window.  If the window has never been
mapped then this command will not map the window, but it will ensure
that when the window is first mapped it will be displayed
in de-iconified form.  On Windows, a deiconified window will also be
raised and be given the focus (made the active window).
Returns an empty string.
.\" METHOD: focusmodel
.TP
\fBwm focusmodel \fIwindow\fR ?\fBactive\fR|\fBpassive\fR?
.
If \fBactive\fR or \fBpassive\fR is supplied as an optional argument
to the command, then it specifies the focus model for \fIwindow\fR.
In this case the command returns an empty string.  If no additional
argument is supplied, then the command returns the current focus
model for \fIwindow\fR.
.RS
.PP
An \fBactive\fR focus model means that \fIwindow\fR will claim the
input focus for itself or its descendants, even at times when
the focus is currently in some other application.  \fBPassive\fR means that
\fIwindow\fR will never claim the focus for itself:  the window manager
should give the focus to \fIwindow\fR at appropriate times.  However,
once the focus has been given to \fIwindow\fR or one of its descendants,
the application may re-assign the focus among \fIwindow\fR's descendants.
The focus model defaults to \fBpassive\fR, and Tk's \fBfocus\fR command
assumes a passive model of focusing.
.RE
.\" METHOD: forget
.TP
\fBwm forget \fIwindow\fR
.
The \fIwindow\fR will be unmapped from the screen and will no longer
be managed by \fBwm\fR.  Windows created with the \fBtoplevel\fR
command will be treated like \fBframe\fR windows once they are no
longer managed by \fBwm\fR, however, the \fB\-menu\fR configuration will be
remembered and the menus will return once the widget is managed again.
.\" METHOD: frame
.TP
\fBwm frame \fIwindow\fR
.
If \fIwindow\fR has been reparented by the window manager into a
decorative frame, the command returns the platform specific window
identifier for the outermost frame that contains \fIwindow\fR (the
window whose parent is the root or virtual root).  If \fIwindow\fR
has not been reparented by the window manager then the command returns
the platform specific window identifier for \fIwindow\fR.
.\" METHOD: geometry
.TP
\fBwm geometry \fIwindow\fR ?\fInewGeometry\fR?
.
If \fInewGeometry\fR is specified, then the geometry of \fIwindow\fR
is changed and an empty string is returned.  Otherwise the current
geometry for \fIwindow\fR is returned (this is the most recent
geometry specified either by manual resizing or
355
356
357
358
359
360
361

362
363
364
365
366
367
368
actual size and location of \fIwindow\fR, whereas \fBwm geometry\fR allows
both setting and querying of the \fIwindow manager\fR's understanding of the
size and location of the window. This can vary significantly, for example to
reflect the addition of decorative elements to \fIwindow\fR such as title
bars, and window managers are not required to precisely follow the requests
made through this command.
.RE

.TP
\fBwm grid \fIwindow\fR ?\fIbaseWidth baseHeight widthInc heightInc\fR?
.
This command indicates that \fIwindow\fR is to be managed as a
gridded window.
It also specifies the relationship between grid units and pixel units.
\fIBaseWidth\fR and \fIbaseHeight\fR specify the number of grid







>







419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
actual size and location of \fIwindow\fR, whereas \fBwm geometry\fR allows
both setting and querying of the \fIwindow manager\fR's understanding of the
size and location of the window. This can vary significantly, for example to
reflect the addition of decorative elements to \fIwindow\fR such as title
bars, and window managers are not required to precisely follow the requests
made through this command.
.RE
.\" METHOD: grid
.TP
\fBwm grid \fIwindow\fR ?\fIbaseWidth baseHeight widthInc heightInc\fR?
.
This command indicates that \fIwindow\fR is to be managed as a
gridded window.
It also specifies the relationship between grid units and pixel units.
\fIBaseWidth\fR and \fIbaseHeight\fR specify the number of grid
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406
407
408

































409
410
411
412
413
414
415
.PP
Otherwise the return value is a Tcl list containing
four elements corresponding to the current \fIbaseWidth\fR,
\fIbaseHeight\fR, \fIwidthInc\fR, and \fIheightInc\fR;  if
\fIwindow\fR is not currently gridded, then an empty string
is returned.
.PP
Note: this command should not be needed very often, since the
\fBTk_SetGrid\fR library procedure and the \fBsetGrid\fR option
provide easier access to the same functionality.
.RE

.TP
\fBwm group \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it gives the path name for the leader of
a group of related windows.  The window manager may use this information,
for example, to unmap all of the windows in a group when the group's
leader is iconified.  \fIPathName\fR may be specified as an empty string to
remove \fIwindow\fR from any group association.  If \fIpathName\fR is
specified then the command returns an empty string;  otherwise it
returns the path name of \fIwindow\fR's current group leader, or an empty
string if \fIwindow\fR is not part of any group.

































.TP
\fBwm iconbitmap \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be displayed in
\fIwindow\fR's icon, and the command returns an empty string.  If







|



>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
.PP
Otherwise the return value is a Tcl list containing
four elements corresponding to the current \fIbaseWidth\fR,
\fIbaseHeight\fR, \fIwidthInc\fR, and \fIheightInc\fR;  if
\fIwindow\fR is not currently gridded, then an empty string
is returned.
.PP
Note that this command should not be needed very often, since the
\fBTk_SetGrid\fR library procedure and the \fBsetGrid\fR option
provide easier access to the same functionality.
.RE
.\" METHOD: group
.TP
\fBwm group \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it gives the path name for the leader of
a group of related windows.  The window manager may use this information,
for example, to unmap all of the windows in a group when the group's
leader is iconified.  \fIPathName\fR may be specified as an empty string to
remove \fIwindow\fR from any group association.  If \fIpathName\fR is
specified then the command returns an empty string;  otherwise it
returns the path name of \fIwindow\fR's current group leader, or an empty
string if \fIwindow\fR is not part of any group.
.\" METHOD: iconbadge
.TP
\fBwm iconbadge \fIwindow badge\fR
.
Sets a badge for the icon of the \fIwindow\fR. The badge can be a positive
integer number, for instance the number of new or unread messages, or
an exclamation point denoting attention needed. If the badge is an empty
string, the badge image is removed from the application icon. Managing
these changes through bindings, such as <FocusIn>, is the responsibility
of the developer.
.RS
.PP
On X11, for this command to work,
the variable \fB::tk::icons::base_icon($window)\fR must be set to the image
that is being used for the window icon of $window. On Windows and X11, the
iconphoto images work best at 32x32 or a similar dimension, as
the badge images are provided by Tk and drawn to overlay the icon images
using native (Windows) API's or Tk rendering. On macOS, the icon badge is
rendered by a system API and is not provided by Tk. The icon image itself
should be higher-resolution, preferably 512 pixels, to avoid being blurry.
.PP
The icon badge is intended for display in the Dock (macOS), taskbar
(Windows) or app panel (X11). On macOS, the last badge called will be
displayed in the Dock, regardless of how many different icon badges may be
assigned to different windows. On Windows, the taskbar display depends on
whether the taskbar buttons are combined or not (this is an OS setting
available to the user): if combined, the behavior is the same as on macOS,
otherwise each button in the taskbar shows the badge it was assigned.
Badge display on macOS is configured in the system preferences. App
panel display behavior on X11 will depend on the window manager and/or
desktop environment.
.RE
.\" METHOD: iconbitmap
.TP
\fBwm iconbitmap \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be displayed in
\fIwindow\fR's icon, and the command returns an empty string.  If
431
432
433
434
435
436
437

438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531
532
533
534
535

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

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
any file which contains a valid
Windows icon is also accepted (usually .ico or .icr files), or any
file for which the shell has assigned an icon.  Tcl will
first test if the file contains an icon, then if it has an assigned
icon, and finally, if that fails, test for
a bitmap.
.RE

.TP
\fBwm iconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be iconified.  It \fIwindow\fR has not
yet been mapped for the first time, this command will arrange for
it to appear in the iconified state when it is eventually mapped.

.TP
\fBwm iconmask \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be used as a mask
in conjunction with the \fBiconbitmap\fR option:  where the mask
has zeroes no icon will be displayed;  where it has ones, the bits
from the icon bitmap will be displayed.  If
an empty string is specified for \fIbitmap\fR then any current icon
mask is cancelled for \fIwindow\fR (this is equivalent to specifying
a bitmap of all ones).  If \fIbitmap\fR is specified
then the command returns an empty string.  Otherwise it
returns the name of the current icon mask associated with
\fIwindow\fR, or an empty string if no mask is in effect.

.TP
\fBwm iconname \fIwindow\fR ?\fInewName\fR?
.
If \fInewName\fR is specified, then it is passed to the window
manager;  the window manager should display \fInewName\fR inside
the icon associated with \fIwindow\fR.  In this case an empty
string is returned as result.  If \fInewName\fR is not specified
then the command returns the current icon name for \fIwindow\fR,
or an empty string if no icon name has been specified (in this
case the window manager will normally display the window's title,
as specified with the \fBwm title\fR command).

.TP
\fBwm iconphoto \fIwindow\fR ?\fB\-default\fR? \fIimage1\fR ?\fIimage2 ...\fR?
.
Sets the titlebar icon for \fIwindow\fR based on the named photo images.
If \fB\-default\fR is specified, this is applied to all future created
toplevels as well.  The data in the images is taken as a snapshot at the
time of invocation.  If the images are later changed, this is not
reflected to the titlebar icons.  Multiple images are accepted to allow
different images sizes (e.g., 16x16 and 32x32) to be provided. The window
manager may scale provided icons to an appropriate size.
.RS
.PP
On Windows, the images are packed into a Windows icon structure.
This will override an ico specified to \fBwm iconbitmap\fR, and
vice versa.
.PP
On X, the images are arranged into the _NET_WM_ICON X property, which
most modern window managers support.  A \fBwm iconbitmap\fR may exist
simultaneously.  It is recommended to use not more than 2 icons, placing
the larger icon first.

.PP
On Macintosh, the first image called is loaded into an OSX-native icon
format, and becomes the application icon in dialogs, the Dock, and
other contexts. At the
script level the command will accept only the first image passed in the
parameters as support for multiple sizes/resolutions on macOS is outside Tk's
scope. Developers should use the largest icon they can support
(preferably 512 pixels) to ensure smooth rendering on the Mac.
.RE

.TP
\fBwm iconposition \fIwindow\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are specified, they are passed to the window
manager as a hint about where to position the icon for \fIwindow\fR.
In this case an empty string is returned.  If \fIx\fR and \fIy\fR are
specified as empty strings then any existing icon position hint is cancelled.
If neither \fIx\fR nor \fIy\fR is specified, then the command returns
a Tcl list containing two values, which are the current icon position
hints (if no hints are in effect then an empty string is returned).

.TP
\fBwm iconwindow \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it is the path name for a window to
use as icon for \fIwindow\fR: when \fIwindow\fR is iconified then
\fIpathName\fR will be mapped to serve as icon, and when \fIwindow\fR
is de-iconified then \fIpathName\fR will be unmapped again.  If
\fIpathName\fR is specified as an empty string then any existing
icon window association for \fIwindow\fR will be cancelled.  If
the \fIpathName\fR argument is specified then an empty string is
returned.  Otherwise the command returns the path name of the
current icon window for \fIwindow\fR, or an empty string if there
is no icon window currently specified for \fIwindow\fR.
Button press events are disabled for \fIwindow\fR as long as it is
an icon window;  this is needed in order to allow window managers to
.QW own
those events.
Note: not all window managers support the notion of an icon window.


.TP
\fBwm manage \fIwidget\fR
.
The \fIwidget\fR specified will become a stand alone top-level window.  The
window will be decorated with the window managers title bar, etc. Only
\fIframe\fR, \fIlabelframe\fR and \fItoplevel\fR widgets can be used
with this command. Attempting to pass any other widget type will raise
an error. Attempting to manage a \fItoplevel\fR widget is benign and
achieves nothing. See also \fBGEOMETRY MANAGEMENT\fR.

.TP
\fBwm maxsize \fIwindow\fR ?\fIwidth height\fR?
.
If \fIwidth\fR and \fIheight\fR are specified, they give
the maximum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
less than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
maximum width and height currently in effect.
The maximum size defaults to the size of the screen.
See the sections on geometry management below for more information.

.TP
\fBwm minsize \fIwindow\fR ?\fIwidth height\fR?
.
If \fIwidth\fR and \fIheight\fR are specified, they give the
minimum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
greater than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
minimum width and height currently in effect.
The minimum size defaults to one pixel in each dimension.
See the sections on geometry management below for more information.

.TP
\fBwm overrideredirect \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR is specified, it must have a proper boolean form and
the override-redirect flag for \fIwindow\fR is set to that value.
If \fIboolean\fR is not specified then \fB1\fR or \fB0\fR is
returned to indicate whether or not the override-redirect flag
is currently set for \fIwindow\fR.
Setting the override-redirect flag for a window causes
it to be ignored by the window manager;  among other things, this means
that the window will not be reparented from the root window into a
decorative frame and the user will not be able to manipulate the
window using the normal window manager mechanisms.
.RS
.PP
Note that the override-redirect flag is only guaranteed to be taken notice of
when the window is first mapped or when mapped after the state is changed from
withdrawn to normal. Some, but not all, platforms will take notice at
additional times.
.RE

.TP
\fBwm positionfrom \fIwindow\fR ?\fIwho\fR?
.
If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current position was requested by the
program or by the user.  Many window managers ignore program-requested







>






>















>











>














|




|
>









>










>

















|
>
>









>















>















>




















>







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
any file which contains a valid
Windows icon is also accepted (usually .ico or .icr files), or any
file for which the shell has assigned an icon.  Tcl will
first test if the file contains an icon, then if it has an assigned
icon, and finally, if that fails, test for
a bitmap.
.RE
.\" METHOD: iconify
.TP
\fBwm iconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be iconified.  It \fIwindow\fR has not
yet been mapped for the first time, this command will arrange for
it to appear in the iconified state when it is eventually mapped.
.\" METHOD: iconmask
.TP
\fBwm iconmask \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be used as a mask
in conjunction with the \fBiconbitmap\fR option:  where the mask
has zeroes no icon will be displayed;  where it has ones, the bits
from the icon bitmap will be displayed.  If
an empty string is specified for \fIbitmap\fR then any current icon
mask is cancelled for \fIwindow\fR (this is equivalent to specifying
a bitmap of all ones).  If \fIbitmap\fR is specified
then the command returns an empty string.  Otherwise it
returns the name of the current icon mask associated with
\fIwindow\fR, or an empty string if no mask is in effect.
.\" METHOD: iconname
.TP
\fBwm iconname \fIwindow\fR ?\fInewName\fR?
.
If \fInewName\fR is specified, then it is passed to the window
manager;  the window manager should display \fInewName\fR inside
the icon associated with \fIwindow\fR.  In this case an empty
string is returned as result.  If \fInewName\fR is not specified
then the command returns the current icon name for \fIwindow\fR,
or an empty string if no icon name has been specified (in this
case the window manager will normally display the window's title,
as specified with the \fBwm title\fR command).
.\" METHOD: iconphoto
.TP
\fBwm iconphoto \fIwindow\fR ?\fB\-default\fR? \fIimage1\fR ?\fIimage2 ...\fR?
.
Sets the titlebar icon for \fIwindow\fR based on the named photo images.
If \fB\-default\fR is specified, this is applied to all future created
toplevels as well.  The data in the images is taken as a snapshot at the
time of invocation.  If the images are later changed, this is not
reflected to the titlebar icons.  Multiple images are accepted to allow
different images sizes (e.g., 16x16 and 32x32) to be provided. The window
manager may scale provided icons to an appropriate size.
.RS
.PP
On Windows, the images are packed into a Windows icon structure.
This will override an ico specified to \fBwm iconbitmap\fR, and
vice versa. This command sets the taskbar icon for the window.
.PP
On X, the images are arranged into the _NET_WM_ICON X property, which
most modern window managers support.  A \fBwm iconbitmap\fR may exist
simultaneously.  It is recommended to use not more than 2 icons, placing
the larger icon first. This command also sets the panel icon for the
application if the window manager or desktop environment supports it.
.PP
On Macintosh, the first image called is loaded into an OSX-native icon
format, and becomes the application icon in dialogs, the Dock, and
other contexts. At the
script level the command will accept only the first image passed in the
parameters as support for multiple sizes/resolutions on macOS is outside Tk's
scope. Developers should use the largest icon they can support
(preferably 512 pixels) to ensure smooth rendering on the Mac.
.RE
.\" METHOD: iconposition
.TP
\fBwm iconposition \fIwindow\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are specified, they are passed to the window
manager as a hint about where to position the icon for \fIwindow\fR.
In this case an empty string is returned.  If \fIx\fR and \fIy\fR are
specified as empty strings then any existing icon position hint is cancelled.
If neither \fIx\fR nor \fIy\fR is specified, then the command returns
a Tcl list containing two values, which are the current icon position
hints (if no hints are in effect then an empty string is returned).
.\" METHOD: iconwindow
.TP
\fBwm iconwindow \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it is the path name for a window to
use as icon for \fIwindow\fR: when \fIwindow\fR is iconified then
\fIpathName\fR will be mapped to serve as icon, and when \fIwindow\fR
is de-iconified then \fIpathName\fR will be unmapped again.  If
\fIpathName\fR is specified as an empty string then any existing
icon window association for \fIwindow\fR will be cancelled.  If
the \fIpathName\fR argument is specified then an empty string is
returned.  Otherwise the command returns the path name of the
current icon window for \fIwindow\fR, or an empty string if there
is no icon window currently specified for \fIwindow\fR.
Button press events are disabled for \fIwindow\fR as long as it is
an icon window;  this is needed in order to allow window managers to
.QW own
those events.
Note that not all window managers support the notion of an icon window, and
the concept is entirely meaningless on non-X11 platforms.
.\" METHOD: manage
.TP
\fBwm manage \fIwidget\fR
.
The \fIwidget\fR specified will become a stand alone top-level window.  The
window will be decorated with the window managers title bar, etc. Only
\fIframe\fR, \fIlabelframe\fR and \fItoplevel\fR widgets can be used
with this command. Attempting to pass any other widget type will raise
an error. Attempting to manage a \fItoplevel\fR widget is benign and
achieves nothing. See also \fBGEOMETRY MANAGEMENT\fR.
.\" METHOD: maxsize
.TP
\fBwm maxsize \fIwindow\fR ?\fIwidth height\fR?
.
If \fIwidth\fR and \fIheight\fR are specified, they give
the maximum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
less than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
maximum width and height currently in effect.
The maximum size defaults to the size of the screen.
See the sections on geometry management below for more information.
.\" METHOD: minsize
.TP
\fBwm minsize \fIwindow\fR ?\fIwidth height\fR?
.
If \fIwidth\fR and \fIheight\fR are specified, they give the
minimum permissible dimensions for \fIwindow\fR.
For gridded windows the dimensions are specified in
grid units;  otherwise they are specified in pixel units.
The window manager will restrict the window's dimensions to be
greater than or equal to \fIwidth\fR and \fIheight\fR.
If \fIwidth\fR and \fIheight\fR are
specified, then the command returns an empty string.  Otherwise
it returns a Tcl list with two elements, which are the
minimum width and height currently in effect.
The minimum size defaults to one pixel in each dimension.
See the sections on geometry management below for more information.
.\" METHOD: overrideredirect
.TP
\fBwm overrideredirect \fIwindow\fR ?\fIboolean\fR?
.
If \fIboolean\fR is specified, it must have a proper boolean form and
the override-redirect flag for \fIwindow\fR is set to that value.
If \fIboolean\fR is not specified then \fB1\fR or \fB0\fR is
returned to indicate whether or not the override-redirect flag
is currently set for \fIwindow\fR.
Setting the override-redirect flag for a window causes
it to be ignored by the window manager;  among other things, this means
that the window will not be reparented from the root window into a
decorative frame and the user will not be able to manipulate the
window using the normal window manager mechanisms.
.RS
.PP
Note that the override-redirect flag is only guaranteed to be taken notice of
when the window is first mapped or when mapped after the state is changed from
withdrawn to normal. Some, but not all, platforms will take notice at
additional times.
.RE
.\" METHOD: positionfrom
.TP
\fBwm positionfrom \fIwindow\fR ?\fIwho\fR?
.
If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current position was requested by the
program or by the user.  Many window managers ignore program-requested
600
601
602
603
604
605
606

607
608
609
610
611
612
613
614
615
616
617
618
619

620
621
622
623
624
625
626
627
628
629
630

631


632

633
634

635




636


637


638

639

640

641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
source of the window's current position, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
Tk will automatically set the position source to \fBuser\fR
when a \fBwm geometry\fR command is invoked, unless the source has
been set explicitly to \fBprogram\fR.

.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?
.
This command is used to manage window manager protocols such as
\fBWM_DELETE_WINDOW\fR.
\fIName\fR is the name of an atom corresponding to a window manager
protocol, such as \fBWM_DELETE_WINDOW\fR or \fBWM_SAVE_YOURSELF\fR
or \fBWM_TAKE_FOCUS\fR.
If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR
is associated with the protocol specified by \fIname\fR.
\fIName\fR will be added to \fIwindow\fR's \fBWM_PROTOCOLS\fR
property to tell the window manager that the application has a
protocol handler for \fIname\fR, and \fIcommand\fR will

be invoked in the future whenever the window manager sends a
message to the client for that protocol.
In this case the command returns an empty string.
If \fIname\fR is specified but \fIcommand\fR is not, then the current
command for \fIname\fR is returned, or an empty string if there
is no handler defined for \fIname\fR.
If \fIcommand\fR is specified as an empty string then the current
handler for \fIname\fR is deleted and it is removed from the
\fBWM_PROTOCOLS\fR property on \fIwindow\fR;  an empty string is
returned.
Lastly, if neither \fIname\fR nor \fIcommand\fR is specified, the

command returns a list of all the protocols for which handlers


are currently defined for \fIwindow\fR.

.RS
.PP

Tk always defines a protocol handler for \fBWM_DELETE_WINDOW\fR, even if




you have not asked for one with \fBwm protocol\fR.


If a \fBWM_DELETE_WINDOW\fR message arrives when you have not defined


a handler, then Tk handles the message by destroying the window for

which it was received.

.RE

.TP
\fBwm resizable \fIwindow\fR ?\fIwidth height\fR?
.
This command controls whether or not the user may interactively
resize a top-level window.  If \fIwidth\fR and \fIheight\fR are
specified, they are boolean values that determine whether the
width and height of \fIwindow\fR may be modified by the user.
In this case the command returns an empty string.
If \fIwidth\fR and \fIheight\fR are omitted then the command
returns a list with two 0/1 elements that indicate whether the
width and height of \fIwindow\fR are currently resizable.
By default, windows are resizable in both dimensions.
If resizing is disabled, then the window's size will be the size
from the most recent interactive resize or \fBwm geometry\fR
command.  If there has been no such operation then
the window's natural size will be used.

.TP
\fBwm sizefrom \fIwindow\fR ?\fIwho\fR?
.
If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current size was requested by the
program or by the user.  Some window managers ignore program-requested
sizes and ask the user to manually size the window;  if
\fBuser\fR is specified then the window manager should give the
window its specified size without asking the user for assistance.
If \fIwho\fR is specified as an empty string, then the current size
source is cancelled.
If \fIwho\fR is specified, then the command returns an empty string.
Otherwise it returns \fBuser\fR or \fBwindow\fR to indicate the
source of the window's current size, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.

.TP
\fBwm stackorder \fIwindow\fR ?\fBisabove\fR|\fBisbelow \fIwindow\fR?
.
The \fBstackorder\fR command returns a list of toplevel windows
in stacking order, from lowest to highest. When a single toplevel
window is passed, the returned list recursively includes all of the
window's children that are toplevels. Only those toplevels
that are currently mapped to the screen are returned.
The \fBstackorder\fR command can also be used to determine if one
toplevel is positioned above or below a second toplevel.
When two window arguments separated by either \fBisabove\fR or
\fBisbelow\fR are passed, a boolean result indicates whether
or not the first window is currently above or below the second
window in the stacking order.

.TP
\fBwm state \fIwindow\fR ?newstate?
.
If \fInewstate\fR is specified, the window will be set to the new state,
otherwise it returns the current state of \fIwindow\fR: either
\fBnormal\fR, \fBiconic\fR, \fBwithdrawn\fR, \fBicon\fR, or (Windows and Mac
OS X only) \fBzoomed\fR.
The difference between \fBiconic\fR and \fBicon\fR is that
\fBiconic\fR refers to a window that has been iconified (e.g., with the
\fBwm iconify\fR command) while \fBicon\fR refers to a window whose only
purpose is to serve as the icon for some other window (via the \fBwm
iconwindow\fR command).  The \fBicon\fR state cannot be set.

.TP
\fBwm title \fIwindow\fR ?\fIstring\fR?
.
If \fIstring\fR is specified, then it will be passed to the window
manager for use as the title for \fIwindow\fR (the window manager
should display this string in \fIwindow\fR's title bar).  In this
case the command returns an empty string.  If \fIstring\fR is not
specified then the command returns the current title for the
\fIwindow\fR.  The title for a window defaults to its name.

.TP
\fBwm transient \fIwindow\fR ?\fIcontainer\fR?
.
If \fIcontainer\fR is specified, then the window manager is informed that
\fIwindow\fR is a transient window (e.g. pull-down menu) working on
behalf of \fIcontainer\fR (where \fIcontainer\fR is the path name for a
top-level window).  If \fIcontainer\fR is specified as an empty string
then \fIwindow\fR is marked as not being a transient window any more.
Otherwise the command returns the path name of \fIwindow\fR's current
container, or an empty string if \fIwindow\fR is not currently a
transient window.  A transient window will mirror state changes in the
container and inherit the state of the container when initially mapped. The
directed graph with an edge from each transient to its container must be
acyclic.  In particular, it is an error to attempt to make a window a
transient of itself.  The window manager may also decorate a transient
window differently, removing some features normally present (e.g.,
minimize and maximize buttons) though this is entirely at the
discretion of the window manager.

.TP
\fBwm withdraw \fIwindow\fR
.
Arranges for \fIwindow\fR to be withdrawn from the screen.  This
causes the window to be unmapped and forgotten about by the window
manager.  If the window
has never been mapped, then this command
causes the window to be mapped in the withdrawn state.  Not all
window managers appear to know how to handle windows that are
mapped in the withdrawn state.
Note: it sometimes seems to be necessary to withdraw a
window and then re-map it (e.g. with \fBwm deiconify\fR) to get some
window managers to pay attention to changes in window attributes
such as group.
.SH "GEOMETRY MANAGEMENT"
.PP
By default a top-level window appears on the screen in its
\fInatural size\fR, which is the one determined internally by its







>



|
<
|
|
|
|
|
|
|
|
>
|
|
|
<
|
|
|
|
|
|
<
>
|
>
>
|
>


>
|
>
>
>
>
|
>
>
|
>
>
|
>
|
>

>
















>


















>














>












>









>


















>










|







712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
source of the window's current position, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
Tk will automatically set the position source to \fBuser\fR
when a \fBwm geometry\fR command is invoked, unless the source has
been set explicitly to \fBprogram\fR.
.\" METHOD: protocol
.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?
.
This command is used to manage window manager protocols. The \fIname\fR

argument in the \fBwm protocol\fR command is the name of an atom corresponding
to a window manager protocol.  Examples include \fBWM_DELETE_WINDOW\fR or
\fBWM_SAVE_YOURSELF\fR or \fBWM_TAKE_FOCUS\fR.
.RS
.PP
A \fIwindow manager protocol\fR is a class of messages sent from a window
manager to a Tk application outside of the normal event processing system. The
main example is the \fBWM_DELETE_WINDOW\fR protocol; these messages are sent
when the user clicks the close widget in the title bar of a window.  Handlers
for window manager protocols are installed with the \fBwm protocol\fR
command. As a rule, if no handler has been installed for a protocol by the
\fBwm protocol\fR command then all messages of that protocol are ignored. The

\fBWM_DELETE_WINDOW\fR protocol is an exception to this rule. At start-up Tk
installs a handler for this protocol, which responds by destroying the
window. The \fBwm protocol\fR command can be used to replace this default
handler by one which responds differently.
.RE
.RS

.PP
The list of available window manager protocols depends on the window manager,
but all window managers supported by Tk provide \fBWM_DELETE_WINDOW\fR. On the
Windows platform, a \fBWM_SAVE_YOURSELF\fR message is sent on user logout
or system restart.
.RE
.RS
.PP
If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR becomes
the handler for the protocol specified by \fIname\fR. The atom for \fIname\fR
will be added to \fIwindow\fR's \fBWM_PROTOCOLS\fR property to tell the window
manager that the application has a handler for the protocol specified by
\fIname\fR, and \fIcommand\fR will be invoked in the future whenever the
window manager sends a message of that protocol to the Tk application.  In
this case the \fBwm protocol\fR command returns an empty string.  If
\fIname\fR is specified but \fIcommand\fR is not, then the current handler for
\fIname\fR is returned, or an empty string if there is no handler defined for
\fIname\fR (as a special case, the default handler for \fBWM_DELETE_WINDOW\fR
is not returned).  If \fIcommand\fR is specified as an empty string then the
atom for \fIname\fR is removed from the \fBWM_PROTOCOLS\fR property of
\fIwindow\fR and the handler is destroyed; an empty string is returned.
Lastly, if neither \fIname\fR nor \fIcommand\fR is specified, the
\fBwm protocol\fR command returns a list of all of the protocols for which
handlers are currently defined for \fIwindow\fR.
.RE
.\" METHOD: resizable
.TP
\fBwm resizable \fIwindow\fR ?\fIwidth height\fR?
.
This command controls whether or not the user may interactively
resize a top-level window.  If \fIwidth\fR and \fIheight\fR are
specified, they are boolean values that determine whether the
width and height of \fIwindow\fR may be modified by the user.
In this case the command returns an empty string.
If \fIwidth\fR and \fIheight\fR are omitted then the command
returns a list with two 0/1 elements that indicate whether the
width and height of \fIwindow\fR are currently resizable.
By default, windows are resizable in both dimensions.
If resizing is disabled, then the window's size will be the size
from the most recent interactive resize or \fBwm geometry\fR
command.  If there has been no such operation then
the window's natural size will be used.
.\" METHOD: sizefrom
.TP
\fBwm sizefrom \fIwindow\fR ?\fIwho\fR?
.
If \fIwho\fR is specified, it must be either \fBprogram\fR or
\fBuser\fR, or an abbreviation of one of these two.  It indicates
whether \fIwindow\fR's current size was requested by the
program or by the user.  Some window managers ignore program-requested
sizes and ask the user to manually size the window;  if
\fBuser\fR is specified then the window manager should give the
window its specified size without asking the user for assistance.
If \fIwho\fR is specified as an empty string, then the current size
source is cancelled.
If \fIwho\fR is specified, then the command returns an empty string.
Otherwise it returns \fBuser\fR or \fBwindow\fR to indicate the
source of the window's current size, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
.\" METHOD: stackorder
.TP
\fBwm stackorder \fIwindow\fR ?\fBisabove\fR|\fBisbelow \fIwindow\fR?
.
The \fBstackorder\fR command returns a list of toplevel windows
in stacking order, from lowest to highest. When a single toplevel
window is passed, the returned list recursively includes all of the
window's children that are toplevels. Only those toplevels
that are currently mapped to the screen are returned.
The \fBstackorder\fR command can also be used to determine if one
toplevel is positioned above or below a second toplevel.
When two window arguments separated by either \fBisabove\fR or
\fBisbelow\fR are passed, a boolean result indicates whether
or not the first window is currently above or below the second
window in the stacking order.
.\" METHOD: state
.TP
\fBwm state \fIwindow\fR ?newstate?
.
If \fInewstate\fR is specified, the window will be set to the new state,
otherwise it returns the current state of \fIwindow\fR: either
\fBnormal\fR, \fBiconic\fR, \fBwithdrawn\fR, \fBicon\fR, or (Windows and Mac
OS X only) \fBzoomed\fR.
The difference between \fBiconic\fR and \fBicon\fR is that
\fBiconic\fR refers to a window that has been iconified (e.g., with the
\fBwm iconify\fR command) while \fBicon\fR refers to a window whose only
purpose is to serve as the icon for some other window (via the \fBwm
iconwindow\fR command).  The \fBicon\fR state cannot be set.
.\" METHOD: title
.TP
\fBwm title \fIwindow\fR ?\fIstring\fR?
.
If \fIstring\fR is specified, then it will be passed to the window
manager for use as the title for \fIwindow\fR (the window manager
should display this string in \fIwindow\fR's title bar).  In this
case the command returns an empty string.  If \fIstring\fR is not
specified then the command returns the current title for the
\fIwindow\fR.  The title for a window defaults to its name.
.\" METHOD: transient
.TP
\fBwm transient \fIwindow\fR ?\fIcontainer\fR?
.
If \fIcontainer\fR is specified, then the window manager is informed that
\fIwindow\fR is a transient window (e.g. pull-down menu) working on
behalf of \fIcontainer\fR (where \fIcontainer\fR is the path name for a
top-level window).  If \fIcontainer\fR is specified as an empty string
then \fIwindow\fR is marked as not being a transient window any more.
Otherwise the command returns the path name of \fIwindow\fR's current
container, or an empty string if \fIwindow\fR is not currently a
transient window.  A transient window will mirror state changes in the
container and inherit the state of the container when initially mapped. The
directed graph with an edge from each transient to its container must be
acyclic.  In particular, it is an error to attempt to make a window a
transient of itself.  The window manager may also decorate a transient
window differently, removing some features normally present (e.g.,
minimize and maximize buttons) though this is entirely at the
discretion of the window manager.
.\" METHOD: widthdraw
.TP
\fBwm withdraw \fIwindow\fR
.
Arranges for \fIwindow\fR to be withdrawn from the screen.  This
causes the window to be unmapped and forgotten about by the window
manager.  If the window
has never been mapped, then this command
causes the window to be mapped in the withdrawn state.  Not all
window managers appear to know how to handle windows that are
mapped in the withdrawn state.
Note that it sometimes seems to be necessary to withdraw a
window and then re-map it (e.g. with \fBwm deiconify\fR) to get some
window managers to pay attention to changes in window attributes
such as group.
.SH "GEOMETRY MANAGEMENT"
.PP
By default a top-level window appears on the screen in its
\fInatural size\fR, which is the one determined internally by its
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
.PP
Normally a top-level window can have any size from one pixel in each
dimension up to the size of its screen.
However, you can use the \fBwm minsize\fR and \fBwm maxsize\fR commands
to limit the range of allowable sizes.
The range set by \fBwm minsize\fR and \fBwm maxsize\fR applies to
all forms of resizing, including the window's natural size as
well as manual resizes and the \fBwm geometry\fR command.

You can also use the command \fBwm resizable\fR to completely
disable interactive resizing in one or both dimensions.
.PP
The \fBwm manage\fR and \fBwm forget\fR commands may be used to
perform undocking and docking of windows.  After a widget is managed
by \fBwm manage\fR command, all other \fBwm\fR subcommands may be used
with the widget.  Only widgets created using the toplevel command may







|
>







891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
.PP
Normally a top-level window can have any size from one pixel in each
dimension up to the size of its screen.
However, you can use the \fBwm minsize\fR and \fBwm maxsize\fR commands
to limit the range of allowable sizes.
The range set by \fBwm minsize\fR and \fBwm maxsize\fR applies to
all forms of resizing, including the window's natural size as
well as manual resizes and the \fBwm geometry\fR command.  You
can use any value accepted by \fBTk_GetPixels\fR.
You can also use the command \fBwm resizable\fR to completely
disable interactive resizing in one or both dimensions.
.PP
The \fBwm manage\fR and \fBwm forget\fR commands may be used to
perform undocking and docking of windows.  After a widget is managed
by \fBwm manage\fR command, all other \fBwm\fR subcommands may be used
with the widget.  Only widgets created using the toplevel command may
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857

858
859
860
\fBwm resizable\fR .fixed 0 0
.CE
.PP
A simple dialog-like window, centred on the screen:
.CS
# Create and arrange the dialog contents.
toplevel .msg
label  .msg.l  \-text "This is a very simple dialog demo."
button .msg.ok \-text OK \-default active \-command {destroy .msg}
pack .msg.ok \-side bottom \-fill x
pack .msg.l  \-expand 1    \-fill both

# Now set the widget up as a centred dialog.

# But first, we need the geometry managers to finish setting
# up the interior of the dialog, for which we need to run the
# event loop with the widget hidden completely...
\fBwm withdraw\fR .msg
update
set x [expr {([winfo screenwidth .]\-[winfo width .msg])/2}]
set y [expr {([winfo screenheight .]\-[winfo height .msg])/2}]
\fBwm geometry\fR  .msg +$x+$y
\fBwm transient\fR .msg .
\fBwm title\fR     .msg "Dialog demo"
\fBwm deiconify\fR .msg
.CE
.SH "SEE ALSO"
toplevel(n), winfo(n)
.SH KEYWORDS
aspect ratio, deiconify, focus model, geometry, grid, group, icon, iconify, increments, position, size, title, top-level window, units, window manager

'\" Local Variables:
'\" mode: nroff
'\" End:







|
|
|
|








|
|








|
>



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
\fBwm resizable\fR .fixed 0 0
.CE
.PP
A simple dialog-like window, centred on the screen:
.CS
# Create and arrange the dialog contents.
toplevel .msg
label  .msg.l  -text "This is a very simple dialog demo."
button .msg.ok -text OK -default active -command {destroy .msg}
pack .msg.ok -side bottom -fill x
pack .msg.l  -expand 1    -fill both

# Now set the widget up as a centred dialog.

# But first, we need the geometry managers to finish setting
# up the interior of the dialog, for which we need to run the
# event loop with the widget hidden completely...
\fBwm withdraw\fR .msg
update
set x [expr {([winfo screenwidth .] - [winfo width .msg]) / 2}]
set y [expr {([winfo screenheight .] - [winfo height .msg]) / 2}]
\fBwm geometry\fR  .msg +$x+$y
\fBwm transient\fR .msg .
\fBwm title\fR     .msg "Dialog demo"
\fBwm deiconify\fR .msg
.CE
.SH "SEE ALSO"
toplevel(n), winfo(n)
.SH KEYWORDS
aspect ratio, deiconify, focus model, geometry, grid, group, icon, iconify,
increments, position, size, title, top-level window, units, window manager
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to generic/ks_names.h.

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






46





47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69



70
71
72
73
74

75





76
77
78
79
80
81
82
{ "Linefeed", 0xFF0A },
{ "Clear", 0xFF0B },
{ "Return", 0xFF0D },
{ "Pause", 0xFF13 },
{ "Scroll_Lock", 0xFF14 },
{ "Sys_Req", 0xFF15 },
{ "Escape", 0xFF1B },
{ "Delete", 0xFFFF },
{ "Multi_key", 0xFF20 },
{ "Codeinput", 0xFF37 },
{ "SingleCandidate", 0xFF3C },
{ "MultipleCandidate", 0xFF3D },
{ "PreviousCandidate", 0xFF3E },
{ "Kanji", 0xFF21 },
{ "Muhenkan", 0xFF22 },
{ "Henkan_Mode", 0xFF23 },
{ "Henkan", 0xFF23 },
{ "Romaji", 0xFF24 },
{ "Hiragana", 0xFF25 },
{ "Katakana", 0xFF26 },
{ "Hiragana_Katakana", 0xFF27 },
{ "Zenkaku", 0xFF28 },
{ "Hankaku", 0xFF29 },
{ "Zenkaku_Hankaku", 0xFF2A },
{ "Touroku", 0xFF2B },
{ "Massyo", 0xFF2C },
{ "Kana_Lock", 0xFF2D },
{ "Kana_Shift", 0xFF2E },
{ "Eisu_Shift", 0xFF2F },
{ "Eisu_toggle", 0xFF30 },






{ "Kanji_Bangou", 0xFF37 },





{ "Zen_Koho", 0xFF3D },
{ "Mae_Koho", 0xFF3E },

{ "Home", 0xFF50 },
{ "Left", 0xFF51 },
{ "Up", 0xFF52 },
{ "Right", 0xFF53 },
{ "Down", 0xFF54 },
{ "Prior", 0xFF55 },
{ "Page_Up", 0xFF55 },
{ "Next", 0xFF56 },
{ "Page_Down", 0xFF56 },
{ "End", 0xFF57 },
{ "Begin", 0xFF58 },
{ "Win_L", 0xFF5B },
{ "Win_R", 0xFF5C },
{ "App", 0xFF5D },
{ "Select", 0xFF60 },
{ "Print", 0xFF61 },
{ "Execute", 0xFF62 },
{ "Insert", 0xFF63 },
{ "Undo", 0xFF65 },
{ "Redo", 0xFF66 },
{ "Menu", 0xFF67 },



{ "Find", 0xFF68 },
{ "Cancel", 0xFF69 },
{ "Help", 0xFF6A },
{ "Break", 0xFF6B },
{ "Mode_switch", 0xFF7E },

{ "script_switch", 0xFF7E },





{ "Num_Lock", 0xFF7F },
{ "KP_Space", 0xFF80 },
{ "KP_Tab", 0xFF89 },
{ "KP_Enter", 0xFF8D },
{ "KP_F1", 0xFF91 },
{ "KP_F2", 0xFF92 },
{ "KP_F3", 0xFF93 },







<

<
<
<
<

















>
>
>
>
>
>
|
>
>
>
>
>
|
|
>











<
<
<







>
>
>





>

>
>
>
>
>







16
17
18
19
20
21
22

23




24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66



67
68
69
70
71
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 },

{ "Multi_key", 0xFF20 },




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



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

{ "F1", 0xFFBE },
{ "F2", 0xFFBF },
{ "F3", 0xFFC0 },
{ "F4", 0xFFC1 },
{ "F5", 0xFFC2 },
{ "F6", 0xFFC3 },
{ "F7", 0xFFC4 },







<
















>







103
104
105
106
107
108
109

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_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
{ "Caps_Lock", 0xFFE5 },
{ "Shift_Lock", 0xFFE6 },
{ "Meta_L", 0xFFE7 },
{ "Meta_R", 0xFFE8 },
{ "Alt_L", 0xFFE9 },
{ "Alt_R", 0xFFEA },
{ "Super_L", 0xFFEB },



{ "Super_R", 0xFFEC },



{ "Hyper_L", 0xFFED },
{ "Hyper_R", 0xFFEE },











{ "ISO_Lock", 0xFE01 },
{ "ISO_Level2_Latch", 0xFE02 },
{ "ISO_Level3_Shift", 0xFE03 },
{ "ISO_Level3_Latch", 0xFE04 },
{ "ISO_Level3_Lock", 0xFE05 },
{ "ISO_Level5_Shift", 0xFE11 },
{ "ISO_Level5_Latch", 0xFE12 },
{ "ISO_Level5_Lock", 0xFE13 },
{ "ISO_Group_Shift", 0xFF7E },
{ "ISO_Group_Latch", 0xFE06 },
{ "ISO_Group_Lock", 0xFE07 },
{ "ISO_Next_Group", 0xFE08 },
{ "ISO_Next_Group_Lock", 0xFE09 },
{ "ISO_Prev_Group", 0xFE0A },
{ "ISO_Prev_Group_Lock", 0xFE0B },
{ "ISO_First_Group", 0xFE0C },
{ "ISO_First_Group_Lock", 0xFE0D },
{ "ISO_Last_Group", 0xFE0E },
{ "ISO_Last_Group_Lock", 0xFE0F },



{ "ISO_Left_Tab", 0xFE20 },
{ "ISO_Move_Line_Up", 0xFE21 },
{ "ISO_Move_Line_Down", 0xFE22 },
{ "ISO_Partial_Line_Up", 0xFE23 },
{ "ISO_Partial_Line_Down", 0xFE24 },
{ "ISO_Partial_Space_Left", 0xFE25 },
{ "ISO_Partial_Space_Right", 0xFE26 },







>
>
>

>
>
>


>
>
>
>
>
>
>
>
>
>
>





<
<
<
<










>
>
>







191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
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_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
{ "dead_belowcircumflex", 0xFE69 },
{ "dead_belowtilde", 0xFE6A },
{ "dead_belowbreve", 0xFE6B },
{ "dead_belowdiaeresis", 0xFE6C },
{ "dead_invertedbreve", 0xFE6D },
{ "dead_belowcomma", 0xFE6E },
{ "dead_currency", 0xFE6F },
{ "dead_lowline", 0xFE90 },
{ "dead_aboveverticalline", 0xFE91 },
{ "dead_belowverticalline", 0xFE92 },
{ "dead_longsolidusoverlay", 0xFE93 },
{ "dead_a", 0xFE80 },
{ "dead_A", 0xFE81 },
{ "dead_e", 0xFE82 },
{ "dead_E", 0xFE83 },
{ "dead_i", 0xFE84 },
{ "dead_I", 0xFE85 },
{ "dead_o", 0xFE86 },
{ "dead_O", 0xFE87 },
{ "dead_u", 0xFE88 },
{ "dead_U", 0xFE89 },
{ "dead_small_schwa", 0xFE8A },
{ "dead_capital_schwa", 0xFE8B },
{ "dead_greek", 0xFE8C },
{ "First_Virtual_Screen", 0xFED0 },
{ "Prev_Virtual_Screen", 0xFED1 },
{ "Next_Virtual_Screen", 0xFED2 },
{ "Last_Virtual_Screen", 0xFED4 },
{ "Terminate_Server", 0xFED5 },
{ "AccessX_Enable", 0xFE70 },
{ "AccessX_Feedback_Enable", 0xFE71 },
{ "RepeatKeys_Enable", 0xFE72 },
{ "SlowKeys_Enable", 0xFE73 },
{ "BounceKeys_Enable", 0xFE74 },
{ "StickyKeys_Enable", 0xFE75 },
{ "MouseKeys_Enable", 0xFE76 },
{ "MouseKeys_Accel_Enable", 0xFE77 },
{ "Overlay1_Enable", 0xFE78 },
{ "Overlay2_Enable", 0xFE79 },
{ "AudibleBell_Enable", 0xFE7A },






























{ "Pointer_Left", 0xFEE0 },
{ "Pointer_Right", 0xFEE1 },
{ "Pointer_Up", 0xFEE2 },
{ "Pointer_Down", 0xFEE3 },
{ "Pointer_UpLeft", 0xFEE4 },
{ "Pointer_UpRight", 0xFEE5 },
{ "Pointer_DownLeft", 0xFEE6 },







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







285
286
287
288
289
290
291






















292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
{ "dead_belowcircumflex", 0xFE69 },
{ "dead_belowtilde", 0xFE6A },
{ "dead_belowbreve", 0xFE6B },
{ "dead_belowdiaeresis", 0xFE6C },
{ "dead_invertedbreve", 0xFE6D },
{ "dead_belowcomma", 0xFE6E },
{ "dead_currency", 0xFE6F },






















{ "AccessX_Enable", 0xFE70 },
{ "AccessX_Feedback_Enable", 0xFE71 },
{ "RepeatKeys_Enable", 0xFE72 },
{ "SlowKeys_Enable", 0xFE73 },
{ "BounceKeys_Enable", 0xFE74 },
{ "StickyKeys_Enable", 0xFE75 },
{ "MouseKeys_Enable", 0xFE76 },
{ "MouseKeys_Accel_Enable", 0xFE77 },
{ "Overlay1_Enable", 0xFE78 },
{ "Overlay2_Enable", 0xFE79 },
{ "AudibleBell_Enable", 0xFE7A },
{ "dead_a", 0xFE80 },
{ "dead_A", 0xFE81 },
{ "dead_e", 0xFE82 },
{ "dead_E", 0xFE83 },
{ "dead_i", 0xFE84 },
{ "dead_I", 0xFE85 },
{ "dead_o", 0xFE86 },
{ "dead_O", 0xFE87 },
{ "dead_u", 0xFE88 },
{ "dead_U", 0xFE89 },
{ "dead_schwa", 0xFE8A },
{ "dead_small_schwa", 0xFE8A },
{ "dead_SCHWA", 0xFE8B },
{ "dead_capital_schwa", 0xFE8B },
{ "dead_greek", 0xFE8C },
{ "dead_lowline", 0xFE90 },
{ "dead_aboveverticalline", 0xFE91 },
{ "dead_belowverticalline", 0xFE92 },
{ "dead_longsolidusoverlay", 0xFE93 },
{ "ch", 0xFEA0 },
{ "Ch", 0xFEA1 },
{ "CH", 0xFEA2 },
{ "c_h", 0xFEA3 },
{ "C_h", 0xFEA4 },
{ "C_H", 0xFEA5 },
{ "First_Virtual_Screen", 0xFED0 },
{ "Prev_Virtual_Screen", 0xFED1 },
{ "Next_Virtual_Screen", 0xFED2 },
{ "Last_Virtual_Screen", 0xFED4 },
{ "Terminate_Server", 0xFED5 },
{ "Pointer_Left", 0xFEE0 },
{ "Pointer_Right", 0xFEE1 },
{ "Pointer_Up", 0xFEE2 },
{ "Pointer_Down", 0xFEE3 },
{ "Pointer_UpLeft", 0xFEE4 },
{ "Pointer_UpRight", 0xFEE5 },
{ "Pointer_DownLeft", 0xFEE6 },
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363

364
365
366

367
368
369
370
371
372
373
374
375

376

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

390
391

392

393

394
395
396
397
398
399
400
{ "Pointer_DblClick4", 0xFEF2 },
{ "Pointer_DblClick5", 0xFEF3 },
{ "Pointer_Drag_Dflt", 0xFEF4 },
{ "Pointer_Drag1", 0xFEF5 },
{ "Pointer_Drag2", 0xFEF6 },
{ "Pointer_Drag3", 0xFEF7 },
{ "Pointer_Drag4", 0xFEF8 },
{ "Pointer_Drag5", 0xFEFD },
{ "Pointer_EnableKeys", 0xFEF9 },
{ "Pointer_Accelerate", 0xFEFA },
{ "Pointer_DfltBtnNext", 0xFEFB },
{ "Pointer_DfltBtnPrev", 0xFEFC },
{ "ch", 0xFEA0 },
{ "Ch", 0xFEA1 },
{ "CH", 0xFEA2 },
{ "c_h", 0xFEA3 },
{ "C_h", 0xFEA4 },
{ "C_H", 0xFEA5 },
{ "3270_Duplicate", 0xFD01 },
{ "3270_FieldMark", 0xFD02 },
{ "3270_Right2", 0xFD03 },
{ "3270_Left2", 0xFD04 },
{ "3270_BackTab", 0xFD05 },
{ "3270_EraseEOF", 0xFD06 },
{ "3270_EraseInput", 0xFD07 },
{ "3270_Reset", 0xFD08 },
{ "3270_Quit", 0xFD09 },
{ "3270_PA1", 0xFD0A },
{ "3270_PA2", 0xFD0B },
{ "3270_PA3", 0xFD0C },
{ "3270_Test", 0xFD0D },
{ "3270_Attn", 0xFD0E },
{ "3270_CursorBlink", 0xFD0F },
{ "3270_AltCursor", 0xFD10 },
{ "3270_KeyClick", 0xFD11 },
{ "3270_Jump", 0xFD12 },
{ "3270_Ident", 0xFD13 },
{ "3270_Rule", 0xFD14 },
{ "3270_Copy", 0xFD15 },
{ "3270_Play", 0xFD16 },
{ "3270_Setup", 0xFD17 },
{ "3270_Record", 0xFD18 },
{ "3270_ChangeScreen", 0xFD19 },
{ "3270_DeleteWord", 0xFD1A },
{ "3270_ExSelect", 0xFD1B },
{ "3270_CursorSelect", 0xFD1C },
{ "3270_PrintScreen", 0xFD1D },
{ "3270_Enter", 0xFD1E },
{ "space", 0x20 },

{ "exclam", 0x21 },

{ "quotedbl", 0x22 },
{ "numbersign", 0x23 },
{ "dollar", 0x24 },

{ "percent", 0x25 },
{ "ampersand", 0x26 },
{ "apostrophe", 0x27 },
{ "quoteright", 0x27 },
{ "parenleft", 0x28 },
{ "parenright", 0x29 },
{ "asterisk", 0x2A },
{ "plus", 0x2B },
{ "comma", 0x2C },

{ "minus", 0x2D },

{ "period", 0x2E },
{ "slash", 0x2F },
{ "0", 0x30 },
{ "1", 0x31 },
{ "2", 0x32 },
{ "3", 0x33 },
{ "4", 0x34 },
{ "5", 0x35 },
{ "6", 0x36 },
{ "7", 0x37 },
{ "8", 0x38 },
{ "9", 0x39 },
{ "colon", 0x3A },

{ "semicolon", 0x3B },
{ "less", 0x3C },

{ "equal", 0x3D },

{ "greater", 0x3E },

{ "question", 0x3F },
{ "at", 0x40 },
{ "A", 0x41 },
{ "B", 0x42 },
{ "C", 0x43 },
{ "D", 0x44 },
{ "E", 0x45 },







<




|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>

>



>









>

>













>


>

>

>







351
352
353
354
355
356
357

358
359
360
361
362



































363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
{ "Pointer_DblClick4", 0xFEF2 },
{ "Pointer_DblClick5", 0xFEF3 },
{ "Pointer_Drag_Dflt", 0xFEF4 },
{ "Pointer_Drag1", 0xFEF5 },
{ "Pointer_Drag2", 0xFEF6 },
{ "Pointer_Drag3", 0xFEF7 },
{ "Pointer_Drag4", 0xFEF8 },

{ "Pointer_EnableKeys", 0xFEF9 },
{ "Pointer_Accelerate", 0xFEFA },
{ "Pointer_DfltBtnNext", 0xFEFB },
{ "Pointer_DfltBtnPrev", 0xFEFC },
{ "Pointer_Drag5", 0xFEFD },



































{ "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
{ "T", 0x54 },
{ "U", 0x55 },
{ "V", 0x56 },
{ "W", 0x57 },
{ "X", 0x58 },
{ "Y", 0x59 },
{ "Z", 0x5A },

{ "bracketleft", 0x5B },
{ "backslash", 0x5C },
{ "bracketright", 0x5D },

{ "asciicircum", 0x5E },
{ "underscore", 0x5F },
{ "grave", 0x60 },
{ "quoteleft", 0x60 },
{ "a", 0x61 },
{ "b", 0x62 },
{ "c", 0x63 },







>



>







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
{ "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
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485

486
487
488
489
490
491
492
{ "t", 0x74 },
{ "u", 0x75 },
{ "v", 0x76 },
{ "w", 0x77 },
{ "x", 0x78 },
{ "y", 0x79 },
{ "z", 0x7A },

{ "braceleft", 0x7B },

{ "bar", 0x7C },

{ "braceright", 0x7D },

{ "asciitilde", 0x7E },

{ "nobreakspace", 0xA0 },

{ "exclamdown", 0xA1 },
{ "cent", 0xA2 },
{ "sterling", 0xA3 },
{ "currency", 0xA4 },
{ "yen", 0xA5 },
{ "brokenbar", 0xA6 },
{ "section", 0xA7 },
{ "diaeresis", 0xA8 },
{ "copyright", 0xA9 },
{ "ordfeminine", 0xAA },

{ "guillemotleft", 0xAB },
{ "notsign", 0xAC },
{ "hyphen", 0xAD },
{ "registered", 0xAE },
{ "macron", 0xAF },
{ "degree", 0xB0 },
{ "plusminus", 0xB1 },
{ "twosuperior", 0xB2 },
{ "threesuperior", 0xB3 },
{ "acute", 0xB4 },
{ "mu", 0xB5 },
{ "paragraph", 0xB6 },
{ "periodcentered", 0xB7 },
{ "cedilla", 0xB8 },
{ "onesuperior", 0xB9 },

{ "masculine", 0xBA },

{ "guillemotright", 0xBB },
{ "onequarter", 0xBC },
{ "onehalf", 0xBD },
{ "threequarters", 0xBE },
{ "questiondown", 0xBF },
{ "Agrave", 0xC0 },
{ "Aacute", 0xC1 },







>

>

>

>

>

>










>















>

>







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
{ "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 },
{ "diaeresis", 0xA8 },
{ "copyright", 0xA9 },
{ "ordfeminine", 0xAA },
{ "guillemetleft", 0xAB },
{ "guillemotleft", 0xAB },
{ "notsign", 0xAC },
{ "hyphen", 0xAD },
{ "registered", 0xAE },
{ "macron", 0xAF },
{ "degree", 0xB0 },
{ "plusminus", 0xB1 },
{ "twosuperior", 0xB2 },
{ "threesuperior", 0xB3 },
{ "acute", 0xB4 },
{ "mu", 0xB5 },
{ "paragraph", 0xB6 },
{ "periodcentered", 0xB7 },
{ "cedilla", 0xB8 },
{ "onesuperior", 0xB9 },
{ "ordmasculine", 0xBA },
{ "masculine", 0xBA },
{ "guillemetright", 0xBB },
{ "guillemotright", 0xBB },
{ "onequarter", 0xBC },
{ "onehalf", 0xBD },
{ "threequarters", 0xBE },
{ "questiondown", 0xBF },
{ "Agrave", 0xC0 },
{ "Aacute", 0xC1 },
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
{ "Ograve", 0xD2 },
{ "Oacute", 0xD3 },
{ "Ocircumflex", 0xD4 },
{ "Otilde", 0xD5 },
{ "Odiaeresis", 0xD6 },
{ "multiply", 0xD7 },
{ "Oslash", 0xD8 },
#ifndef TK_NO_DEPRECATED
{ "Ooblique", 0xD8 },
#endif
{ "Ugrave", 0xD9 },
{ "Uacute", 0xDA },
{ "Ucircumflex", 0xDB },
{ "Udiaeresis", 0xDC },
{ "Yacute", 0xDD },
{ "THORN", 0xDE },
{ "Thorn", 0xDE },







<

<







531
532
533
534
535
536
537

538

539
540
541
542
543
544
545
{ "Ograve", 0xD2 },
{ "Oacute", 0xD3 },
{ "Ocircumflex", 0xD4 },
{ "Otilde", 0xD5 },
{ "Odiaeresis", 0xD6 },
{ "multiply", 0xD7 },
{ "Oslash", 0xD8 },

{ "Ooblique", 0xD8 },

{ "Ugrave", 0xD9 },
{ "Uacute", 0xDA },
{ "Ucircumflex", 0xDB },
{ "Udiaeresis", 0xDC },
{ "Yacute", 0xDD },
{ "THORN", 0xDE },
{ "Thorn", 0xDE },
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
{ "ograve", 0xF2 },
{ "oacute", 0xF3 },
{ "ocircumflex", 0xF4 },
{ "otilde", 0xF5 },
{ "odiaeresis", 0xF6 },
{ "division", 0xF7 },
{ "oslash", 0xF8 },
#ifndef TK_NO_DEPRECATED
{ "ooblique", 0xF8 },
#endif
{ "ugrave", 0xF9 },
{ "uacute", 0xFA },
{ "ucircumflex", 0xFB },
{ "udiaeresis", 0xFC },
{ "yacute", 0xFD },
{ "thorn", 0xFE },
{ "ydiaeresis", 0xFF },

{ "Aogonek", 0x1A1 },
{ "breve", 0x1A2 },
{ "Lstroke", 0x1A3 },
{ "Lcaron", 0x1A5 },
{ "Sacute", 0x1A6 },
{ "Scaron", 0x1A9 },
{ "Scedilla", 0x1AA },







<

<







>







565
566
567
568
569
570
571

572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
{ "ograve", 0xF2 },
{ "oacute", 0xF3 },
{ "ocircumflex", 0xF4 },
{ "otilde", 0xF5 },
{ "odiaeresis", 0xF6 },
{ "division", 0xF7 },
{ "oslash", 0xF8 },

{ "ooblique", 0xF8 },

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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







694
695
696
697
698
699
700


























701
702
703
704
705
706
707
{ "imacron", 0x3EF },
{ "ncedilla", 0x3F1 },
{ "omacron", 0x3F2 },
{ "kcedilla", 0x3F3 },
{ "uogonek", 0x3F9 },
{ "utilde", 0x3FD },
{ "umacron", 0x3FE },


























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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<







776
777
778
779
780
781
782


















783











784
785
786
787
788
789
790
{ "kana_RU", 0x4D9 },
{ "kana_RE", 0x4DA },
{ "kana_RO", 0x4DB },
{ "kana_WA", 0x4DC },
{ "kana_N", 0x4DD },
{ "voicedsound", 0x4DE },
{ "semivoicedsound", 0x4DF },


















{ "Arabic_comma", 0x5AC },











{ "Arabic_semicolon", 0x5BB },
{ "Arabic_question_mark", 0x5BF },
{ "Arabic_hamza", 0x5C1 },
{ "Arabic_maddaonalef", 0x5C2 },
{ "Arabic_hamzaonalef", 0x5C3 },
{ "Arabic_hamzaonwaw", 0x5C4 },
{ "Arabic_hamzaunderalef", 0x5C5 },
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
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
{ "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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







827
828
829
830
831
832
833












































834
835
836
837
838
839
840
{ "Arabic_dammatan", 0x5EC },
{ "Arabic_kasratan", 0x5ED },
{ "Arabic_fatha", 0x5EE },
{ "Arabic_damma", 0x5EF },
{ "Arabic_kasra", 0x5F0 },
{ "Arabic_shadda", 0x5F1 },
{ "Arabic_sukun", 0x5F2 },












































{ "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
{ "Cyrillic_CHE", 0x6FE },
{ "Cyrillic_HARDSIGN", 0x6FF },
{ "Greek_ALPHAaccent", 0x7A1 },
{ "Greek_EPSILONaccent", 0x7A2 },
{ "Greek_ETAaccent", 0x7A3 },
{ "Greek_IOTAaccent", 0x7A4 },
{ "Greek_IOTAdieresis", 0x7A5 },

{ "Greek_IOTAdiaeresis", 0x7A5 },

{ "Greek_IOTAaccentdiaeresis", 0x7A6 },
{ "Greek_OMICRONaccent", 0x7A7 },
{ "Greek_UPSILONaccent", 0x7A8 },
{ "Greek_UPSILONdieresis", 0x7A9 },
{ "Greek_UPSILONaccentdieresis", 0x7AA },
{ "Greek_OMEGAaccent", 0x7AB },
{ "Greek_accentdieresis", 0x7AE },







>

>







969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
{ "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
{ "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 },







<







1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
{ "Greek_finalsmallsigma", 0x7F3 },
{ "Greek_tau", 0x7F4 },
{ "Greek_upsilon", 0x7F5 },
{ "Greek_phi", 0x7F6 },
{ "Greek_chi", 0x7F7 },
{ "Greek_psi", 0x7F8 },
{ "Greek_omega", 0x7F9 },

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







<







1279
1280
1281
1282
1283
1284
1285

1286
1287
1288
1289
1290
1291
1292
#endif
{ "hebrew_resh", 0xCF8 },
{ "hebrew_shin", 0xCF9 },
{ "hebrew_taw", 0xCFA },
#ifndef TK_NO_DEPRECATED
{ "hebrew_taf", 0xCFA },
#endif

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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1363
1364
1365
1366
1367
1368
1369
















1370
1371
1372
1373
1374
1375
1376
{ "Thai_leksam", 0xDF3 },
{ "Thai_leksi", 0xDF4 },
{ "Thai_lekha", 0xDF5 },
{ "Thai_lekhok", 0xDF6 },
{ "Thai_lekchet", 0xDF7 },
{ "Thai_lekpaet", 0xDF8 },
{ "Thai_lekkao", 0xDF9 },
















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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1454
1455
1456
1457
1458
1459
1460






















































































































































































































































































































































































































































































































































































































































1461
1462
1463
1464
1465
1466
1467
{ "Hangul_YeorinHieuh", 0xEF5 },
{ "Hangul_AraeA", 0xEF6 },
{ "Hangul_AraeAE", 0xEF7 },
{ "Hangul_J_PanSios", 0xEF8 },
{ "Hangul_J_KkogjiDalrinIeung", 0xEF9 },
{ "Hangul_J_YeorinHieuh", 0xEFA },
{ "Korean_Won", 0xEFF },






















































































































































































































































































































































































































































































































































































































































{ "XF86ModeLock", 0x1008FF01 },
{ "XF86MonBrightnessUp", 0x1008FF02 },
{ "XF86MonBrightnessDown", 0x1008FF03 },
{ "XF86KbdLightOnOff", 0x1008FF04 },
{ "XF86KbdBrightnessUp", 0x1008FF05 },
{ "XF86KbdBrightnessDown", 0x1008FF06 },
{ "XF86MonBrightnessCycle", 0x1008FF07 },
2346
2347
2348
2349
2350
2351
2352

2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370











































































































































2371
2372
2373
2374
2375
2376
2377
{ "XF86TouchpadOff", 0x1008FFB1 },
{ "XF86AudioMicMute", 0x1008FFB2 },
{ "XF86Keyboard", 0x1008FFB3 },
{ "XF86WWAN", 0x1008FFB4 },
{ "XF86RFKill", 0x1008FFB5 },
{ "XF86AudioPreset", 0x1008FFB6 },
{ "XF86RotationLockToggle", 0x1008FFB7 },

{ "XF86Switch_VT_1", 0x1008FE01 },
{ "XF86Switch_VT_2", 0x1008FE02 },
{ "XF86Switch_VT_3", 0x1008FE03 },
{ "XF86Switch_VT_4", 0x1008FE04 },
{ "XF86Switch_VT_5", 0x1008FE05 },
{ "XF86Switch_VT_6", 0x1008FE06 },
{ "XF86Switch_VT_7", 0x1008FE07 },
{ "XF86Switch_VT_8", 0x1008FE08 },
{ "XF86Switch_VT_9", 0x1008FE09 },
{ "XF86Switch_VT_10", 0x1008FE0A },
{ "XF86Switch_VT_11", 0x1008FE0B },
{ "XF86Switch_VT_12", 0x1008FE0C },
{ "XF86Ungrab", 0x1008FE20 },
{ "XF86ClearGrab", 0x1008FE21 },
{ "XF86Next_VMode", 0x1008FE22 },
{ "XF86Prev_VMode", 0x1008FE23 },
{ "XF86LogWindowTree", 0x1008FE24 },
{ "XF86LogGrabInfo", 0x1008FE25 },











































































































































{ "SunFA_Grave", 0x1005FF00 },
{ "SunFA_Circum", 0x1005FF01 },
{ "SunFA_Tilde", 0x1005FF02 },
{ "SunFA_Acute", 0x1005FF03 },
{ "SunFA_Diaeresis", 0x1005FF04 },
{ "SunFA_Cedilla", 0x1005FF05 },
{ "SunF36", 0x1005FF10 },







>


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
{ "XF86TouchpadOff", 0x1008FFB1 },
{ "XF86AudioMicMute", 0x1008FFB2 },
{ "XF86Keyboard", 0x1008FFB3 },
{ "XF86WWAN", 0x1008FFB4 },
{ "XF86RFKill", 0x1008FFB5 },
{ "XF86AudioPreset", 0x1008FFB6 },
{ "XF86RotationLockToggle", 0x1008FFB7 },
{ "XF86FullScreen", 0x1008FFB8 },
{ "XF86Switch_VT_1", 0x1008FE01 },
{ "XF86Switch_VT_2", 0x1008FE02 },
{ "XF86Switch_VT_3", 0x1008FE03 },
{ "XF86Switch_VT_4", 0x1008FE04 },
{ "XF86Switch_VT_5", 0x1008FE05 },
{ "XF86Switch_VT_6", 0x1008FE06 },
{ "XF86Switch_VT_7", 0x1008FE07 },
{ "XF86Switch_VT_8", 0x1008FE08 },
{ "XF86Switch_VT_9", 0x1008FE09 },
{ "XF86Switch_VT_10", 0x1008FE0A },
{ "XF86Switch_VT_11", 0x1008FE0B },
{ "XF86Switch_VT_12", 0x1008FE0C },
{ "XF86Ungrab", 0x1008FE20 },
{ "XF86ClearGrab", 0x1008FE21 },
{ "XF86Next_VMode", 0x1008FE22 },
{ "XF86Prev_VMode", 0x1008FE23 },
{ "XF86LogWindowTree", 0x1008FE24 },
{ "XF86LogGrabInfo", 0x1008FE25 },
{ "XF86BrightnessAuto", 0x100810F4 },
{ "XF86DisplayOff", 0x100810F5 },
{ "XF86Info", 0x10081166 },
{ "XF86AspectRatio", 0x10081177 },
{ "XF86DVD", 0x10081185 },
{ "XF86Audio", 0x10081188 },
{ "XF86ChannelUp", 0x10081192 },
{ "XF86ChannelDown", 0x10081193 },
{ "XF86Break", 0x1008119B },
{ "XF86VideoPhone", 0x100811A0 },
{ "XF86ZoomReset", 0x100811A4 },
{ "XF86Editor", 0x100811A6 },
{ "XF86GraphicsEditor", 0x100811A8 },
{ "XF86Presentation", 0x100811A9 },
{ "XF86Database", 0x100811AA },
{ "XF86Voicemail", 0x100811AC },
{ "XF86Addressbook", 0x100811AD },
{ "XF86DisplayToggle", 0x100811AF },
{ "XF86SpellCheck", 0x100811B0 },
{ "XF86ContextMenu", 0x100811B6 },
{ "XF86MediaRepeat", 0x100811B7 },
{ "XF8610ChannelsUp", 0x100811B8 },
{ "XF8610ChannelsDown", 0x100811B9 },
{ "XF86Images", 0x100811BA },
{ "XF86NotificationCenter", 0x100811BC },
{ "XF86PickupPhone", 0x100811BD },
{ "XF86HangupPhone", 0x100811BE },
{ "XF86Fn", 0x100811D0 },
{ "XF86Fn_Esc", 0x100811D1 },
{ "XF86FnRightShift", 0x100811E5 },
{ "XF86Numeric0", 0x10081200 },
{ "XF86Numeric1", 0x10081201 },
{ "XF86Numeric2", 0x10081202 },
{ "XF86Numeric3", 0x10081203 },
{ "XF86Numeric4", 0x10081204 },
{ "XF86Numeric5", 0x10081205 },
{ "XF86Numeric6", 0x10081206 },
{ "XF86Numeric7", 0x10081207 },
{ "XF86Numeric8", 0x10081208 },
{ "XF86Numeric9", 0x10081209 },
{ "XF86NumericStar", 0x1008120A },
{ "XF86NumericPound", 0x1008120B },
{ "XF86NumericA", 0x1008120C },
{ "XF86NumericB", 0x1008120D },
{ "XF86NumericC", 0x1008120E },
{ "XF86NumericD", 0x1008120F },
{ "XF86CameraFocus", 0x10081210 },
{ "XF86WPSButton", 0x10081211 },
{ "XF86CameraZoomIn", 0x10081215 },
{ "XF86CameraZoomOut", 0x10081216 },
{ "XF86CameraUp", 0x10081217 },
{ "XF86CameraDown", 0x10081218 },
{ "XF86CameraLeft", 0x10081219 },
{ "XF86CameraRight", 0x1008121A },
{ "XF86AttendantOn", 0x1008121B },
{ "XF86AttendantOff", 0x1008121C },
{ "XF86AttendantToggle", 0x1008121D },
{ "XF86LightsToggle", 0x1008121E },
{ "XF86ALSToggle", 0x10081230 },
{ "XF86Buttonconfig", 0x10081240 },
{ "XF86Taskmanager", 0x10081241 },
{ "XF86Journal", 0x10081242 },
{ "XF86ControlPanel", 0x10081243 },
{ "XF86AppSelect", 0x10081244 },
{ "XF86Screensaver", 0x10081245 },
{ "XF86VoiceCommand", 0x10081246 },
{ "XF86Assistant", 0x10081247 },
{ "XF86EmojiPicker", 0x10081249 },
{ "XF86Dictate", 0x1008124A },
{ "XF86BrightnessMin", 0x10081250 },
{ "XF86BrightnessMax", 0x10081251 },
{ "XF86KbdInputAssistPrev", 0x10081260 },
{ "XF86KbdInputAssistNext", 0x10081261 },
{ "XF86KbdInputAssistPrevgroup", 0x10081262 },
{ "XF86KbdInputAssistNextgroup", 0x10081263 },
{ "XF86KbdInputAssistAccept", 0x10081264 },
{ "XF86KbdInputAssistCancel", 0x10081265 },
{ "XF86RightUp", 0x10081266 },
{ "XF86RightDown", 0x10081267 },
{ "XF86LeftUp", 0x10081268 },
{ "XF86LeftDown", 0x10081269 },
{ "XF86RootMenu", 0x1008126A },
{ "XF86MediaTopMenu", 0x1008126B },
{ "XF86Numeric11", 0x1008126C },
{ "XF86Numeric12", 0x1008126D },
{ "XF86AudioDesc", 0x1008126E },
{ "XF863DMode", 0x1008126F },
{ "XF86NextFavorite", 0x10081270 },
{ "XF86StopRecord", 0x10081271 },
{ "XF86PauseRecord", 0x10081272 },
{ "XF86VOD", 0x10081273 },
{ "XF86Unmute", 0x10081274 },
{ "XF86FastReverse", 0x10081275 },
{ "XF86SlowReverse", 0x10081276 },
{ "XF86Data", 0x10081277 },
{ "XF86OnScreenKeyboard", 0x10081278 },
{ "XF86PrivacyScreenToggle", 0x10081279 },
{ "XF86SelectiveScreenshot", 0x1008127A },
{ "XF86Macro1", 0x10081290 },
{ "XF86Macro2", 0x10081291 },
{ "XF86Macro3", 0x10081292 },
{ "XF86Macro4", 0x10081293 },
{ "XF86Macro5", 0x10081294 },
{ "XF86Macro6", 0x10081295 },
{ "XF86Macro7", 0x10081296 },
{ "XF86Macro8", 0x10081297 },
{ "XF86Macro9", 0x10081298 },
{ "XF86Macro10", 0x10081299 },
{ "XF86Macro11", 0x1008129A },
{ "XF86Macro12", 0x1008129B },
{ "XF86Macro13", 0x1008129C },
{ "XF86Macro14", 0x1008129D },
{ "XF86Macro15", 0x1008129E },
{ "XF86Macro16", 0x1008129F },
{ "XF86Macro17", 0x100812A0 },
{ "XF86Macro18", 0x100812A1 },
{ "XF86Macro19", 0x100812A2 },
{ "XF86Macro20", 0x100812A3 },
{ "XF86Macro21", 0x100812A4 },
{ "XF86Macro22", 0x100812A5 },
{ "XF86Macro23", 0x100812A6 },
{ "XF86Macro24", 0x100812A7 },
{ "XF86Macro25", 0x100812A8 },
{ "XF86Macro26", 0x100812A9 },
{ "XF86Macro27", 0x100812AA },
{ "XF86Macro28", 0x100812AB },
{ "XF86Macro29", 0x100812AC },
{ "XF86Macro30", 0x100812AD },
{ "XF86MacroRecordStart", 0x100812B0 },
{ "XF86MacroRecordStop", 0x100812B1 },
{ "XF86MacroPresetCycle", 0x100812B2 },
{ "XF86MacroPreset1", 0x100812B3 },
{ "XF86MacroPreset2", 0x100812B4 },
{ "XF86MacroPreset3", 0x100812B5 },
{ "XF86KbdLcdMenu1", 0x100812B8 },
{ "XF86KbdLcdMenu2", 0x100812B9 },
{ "XF86KbdLcdMenu3", 0x100812BA },
{ "XF86KbdLcdMenu4", 0x100812BB },
{ "XF86KbdLcdMenu5", 0x100812BC },
{ "SunFA_Grave", 0x1005FF00 },
{ "SunFA_Circum", 0x1005FF01 },
{ "SunFA_Tilde", 0x1005FF02 },
{ "SunFA_Acute", 0x1005FF03 },
{ "SunFA_Diaeresis", 0x1005FF04 },
{ "SunFA_Cedilla", 0x1005FF05 },
{ "SunF36", 0x1005FF10 },

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
#ifndef NANOSVG_H
#define NANOSVG_H

#ifdef __cplusplus
extern "C" {
#endif

// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes.
//

// The library suits well for anything from rendering scalable icons in your editor application to prototyping a game.
//

// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request!
//

// The shapes in the SVG images are transformed by the viewBox and converted to specified units.
// That is, you should get the same looking data as your designed in your favorite app.
//

// NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose
// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters.
//

// The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'.
// DPI (dots-per-inch) controls how the unit conversion is done.
//

// If you don't know or care about the units stuff, "px" and 96 should get you going.



/* Example Usage:
	// Load SVG
	NSVGimage* image;
	image = nsvgParseFromFile("test.svg", "px", 96);
	printf("size: %f x %f\n", image->width, image->height);







|
<
>
|
<
>
|
<
>
|
|
<
>
|
|
<
>
|
|
<
>
|
>







29
30
31
32
33
34
35
36

37
38

39
40

41
42
43

44
45
46

47
48
49

50
51
52
53
54
55
56
57
58
59
#ifndef NANOSVG_H
#define NANOSVG_H

#ifdef __cplusplus
extern "C" {
#endif

/* NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes.

 *
 * The library suits well for anything from rendering scalable icons in your editor application to prototyping a game.

 *
 * NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request!

 *
 * The shapes in the SVG images are transformed by the viewBox and converted to specified units.
 * That is, you should get the same looking data as your designed in your favorite app.

 *
 * NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose
 * to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters.

 *
 * The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'.
 * DPI (dots-per-inch) controls how the unit conversion is done.

 *
 * If you don't know or care about the units stuff, "px" and 96 should get you going.
 */


/* Example Usage:
	// Load SVG
	NSVGimage* image;
	image = nsvgParseFromFile("test.svg", "px", 96);
	printf("size: %f x %f\n", image->width, image->height);
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

// float emulation for MS VC6++ compiler
#if defined(_MSC_VER) && (_MSC_VER == 1200)
#define tanf(a) (float)tan(a)
#define cosf(a) (float)cos(a)
#define sinf(a) (float)sin(a)
#define sqrtf(a) (float)sqrt(a)
#define fabsf(a) (float)fabs(a)
#define acosf(a) (float)acos(a)
#define atan2f(a,b) (float)atan2(a,b)
#define ceilf(a) (float)ceil(a)
#define fmodf(a,b) (float)fmod(a,b)
#define floorf(a) (float)floor(a)
#endif
// float emulation for MS VC8++ compiler
#if defined(_MSC_VER) && (_MSC_VER == 1400)
#define fabsf(a) (float)fabs(a)
#endif

enum NSVGpaintType {

	NSVG_PAINT_NONE = 0,
	NSVG_PAINT_COLOR = 1,
	NSVG_PAINT_LINEAR_GRADIENT = 2,
	NSVG_PAINT_RADIAL_GRADIENT = 3
};

enum NSVGspreadType {







|












|





>







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

/* float emulation for MS VC6++ compiler */
#if defined(_MSC_VER) && (_MSC_VER == 1200)
#define tanf(a) (float)tan(a)
#define cosf(a) (float)cos(a)
#define sinf(a) (float)sin(a)
#define sqrtf(a) (float)sqrt(a)
#define fabsf(a) (float)fabs(a)
#define acosf(a) (float)acos(a)
#define atan2f(a,b) (float)atan2(a,b)
#define ceilf(a) (float)ceil(a)
#define fmodf(a,b) (float)fmod(a,b)
#define floorf(a) (float)floor(a)
#endif
/* float emulation for MS VC8++ compiler */
#if defined(_MSC_VER) && (_MSC_VER == 1400)
#define fabsf(a) (float)fabs(a)
#endif

enum NSVGpaintType {
	NSVG_PAINT_UNDEF = -1,
	NSVG_PAINT_NONE = 0,
	NSVG_PAINT_COLOR = 1,
	NSVG_PAINT_LINEAR_GRADIENT = 2,
	NSVG_PAINT_RADIAL_GRADIENT = 3
};

enum NSVGspreadType {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185



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

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
	char spread;
	float fx, fy;
	int nstops;
	NSVGgradientStop stops[1];
} NSVGgradient;

typedef struct NSVGpaint {
	char type;
	union {
		unsigned int color;
		NSVGgradient* gradient;
	};
} NSVGpaint;

typedef struct NSVGpath
{
	float* pts;					// Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
	int npts;					// Total number of bezier points.
	char closed;				// Flag indicating if shapes should be treated as closed.
	float bounds[4];			// Tight bounding box of the shape [minx,miny,maxx,maxy].
	struct NSVGpath* next;		// Pointer to next path, or NULL if last element.
} NSVGpath;

typedef struct NSVGshape
{
	char id[64];				// Optional 'id' attr of the shape or its group
	NSVGpaint fill;				// Fill paint
	NSVGpaint stroke;			// Stroke paint
	float opacity;				// Opacity of the shape.
	float strokeWidth;			// Stroke width (scaled).
	float strokeDashOffset;		// Stroke dash offset (scaled).
	float strokeDashArray[8];			// Stroke dash array (scaled).
	char strokeDashCount;				// Number of dash values in dash array.
	char strokeLineJoin;		// Stroke join type.
	char strokeLineCap;			// Stroke cap type.
	float miterLimit;			// Miter limit
	char fillRule;				// Fill rule, see NSVGfillRule.
	unsigned char flags;		// Logical or of NSVG_FLAGS_* flags
	float bounds[4];			// Tight bounding box of the shape [minx,miny,maxx,maxy].



	NSVGpath* paths;			// Linked list of paths in the image.
	struct NSVGshape* next;		// Pointer to next shape, or NULL if last element.
} NSVGshape;

typedef struct NSVGimage
{
	float width;				// Width of the image.
	float height;				// Height of the image.
	NSVGshape* shapes;			// Linked list of shapes in the image.
} NSVGimage;

// Parses SVG file from a file, returns SVG image as paths.
NANOSVG_SCOPE NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);

// Parses SVG file from a null terminated string, returns SVG image as paths.
// Important note: changes the string.
NANOSVG_SCOPE NSVGimage* nsvgParse(char* input, const char* units, float dpi);

// Deletes list of paths.
NANOSVG_SCOPE void nsvgDelete(NSVGimage* image);

#ifdef __cplusplus
}
#endif

#endif // NANOSVG_H

#ifdef NANOSVG_IMPLEMENTATION

#include <string.h>
#include <stdlib.h>

#include <math.h>

#define NSVG_PI (3.14159265358979323846264338327f)
#define NSVG_KAPPA90 (0.5522847493f)	// Length proportional to radius of a cubic bezier handle for 90deg arcs.

#define NSVG_ALIGN_MIN 0
#define NSVG_ALIGN_MID 1
#define NSVG_ALIGN_MAX 2
#define NSVG_ALIGN_NONE 0
#define NSVG_ALIGN_MEET 1
#define NSVG_ALIGN_SLICE 2

#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))

#ifdef _MSC_VER
	#pragma warning (disable: 4996) // Switch off security warnings
	#pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
	#ifdef __cplusplus
	#define NSVG_INLINE inline
	#else
	#define NSVG_INLINE
	#endif
	#if !defined(strtoll)           // old MSVC versions do not have strtoll()
		#define strtoll _strtoi64
	#endif
#else
	#define NSVG_INLINE inline
#endif









|








|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
|
|




|
|
|


|


|
|


|






<
<




>



|












|
|





|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215


216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
	char spread;
	float fx, fy;
	int nstops;
	NSVGgradientStop stops[1];
} NSVGgradient;

typedef struct NSVGpaint {
	signed char type;
	union {
		unsigned int color;
		NSVGgradient* gradient;
	};
} NSVGpaint;

typedef struct NSVGpath
{
	float* pts;					/* Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... */
	int npts;					/* Total number of bezier points. */
	char closed;				/* Flag indicating if shapes should be treated as closed. */
	float bounds[4];			/* Tight bounding box of the shape [minx,miny,maxx,maxy]. */
	struct NSVGpath* next;		/* Pointer to next path, or NULL if last element. */
} NSVGpath;

typedef struct NSVGshape
{
	char id[64];				/* Optional 'id' attr of the shape or its group */
	NSVGpaint fill;				/* Fill paint */
	NSVGpaint stroke;			/* Stroke paint */
	float opacity;				/* Opacity of the shape. */
	float strokeWidth;			/* Stroke width (scaled). */
	float strokeDashOffset;		/* Stroke dash offset (scaled). */
	float strokeDashArray[8];	/* Stroke dash array (scaled). */
	char strokeDashCount;		/* Number of dash values in dash array. */
	char strokeLineJoin;		/* Stroke join type. */
	char strokeLineCap;			/* Stroke cap type. */
	float miterLimit;			/* Miter limit */
	char fillRule;				/* Fill rule, see NSVGfillRule. */
	unsigned char flags;		/* Logical or of NSVG_FLAGS_* flags */
	float bounds[4];			/* Tight bounding box of the shape [minx,miny,maxx,maxy]. */
	char fillGradient[64];		// Optional 'id' of fill gradient
	char strokeGradient[64];	// Optional 'id' of stroke gradient
	float xform[6];				// Root transformation for fill/stroke gradient
	NSVGpath* paths;			/* Linked list of paths in the image. */
	struct NSVGshape* next;		/* Pointer to next shape, or NULL if last element. */
} NSVGshape;

typedef struct NSVGimage
{
	float width;				/* Width of the image. */
	float height;				/* Height of the image. */
	NSVGshape* shapes;			/* Linked list of shapes in the image. */
} NSVGimage;

/* Parses SVG file from a file, returns SVG image as paths. */
NANOSVG_SCOPE NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);

/* Parses SVG file from a null terminated string, returns SVG image as paths. */
/* Important note: changes the string. */
NANOSVG_SCOPE NSVGimage* nsvgParse(char* input, const char* units, float dpi);

/* Deletes list of paths. */
NANOSVG_SCOPE void nsvgDelete(NSVGimage* image);

#ifdef __cplusplus
}
#endif



#ifdef NANOSVG_IMPLEMENTATION

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define NSVG_PI (3.14159265358979323846264338327f)
#define NSVG_KAPPA90 (0.5522847493f)	/* Length proportional to radius of a cubic bezier handle for 90deg arcs. */

#define NSVG_ALIGN_MIN 0
#define NSVG_ALIGN_MID 1
#define NSVG_ALIGN_MAX 2
#define NSVG_ALIGN_NONE 0
#define NSVG_ALIGN_MEET 1
#define NSVG_ALIGN_SLICE 2

#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))

#ifdef _MSC_VER
	#pragma warning (disable: 4996) /* Switch off security warnings */
	#pragma warning (disable: 4100) /* Switch off unreferenced formal parameter warnings */
	#ifdef __cplusplus
	#define NSVG_INLINE inline
	#else
	#define NSVG_INLINE
	#endif
	#if !defined(strtoll)           /* old MSVC versions do not have strtoll() */
		#define strtoll _strtoi64
	#endif
#else
	#define NSVG_INLINE inline
#endif


255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
	return c >= '0' && c <= '9';
}

static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }


// Simple XML parser

#define NSVG_XML_TAG 1
#define NSVG_XML_CONTENT 2
#define NSVG_XML_MAX_ATTRIBS 256

static void nsvg__parseContent(char* s,
							   void (*contentCb)(void* ud, const char* s),
							   void* ud)
{
	// Trim start white spaces
	while (*s && nsvg__isspace(*s)) s++;
	if (!*s) return;

	if (contentCb)
		(*contentCb)(ud, s);
}

static void nsvg__parseElement(char* s,
							   void (*startelCb)(void* ud, const char* el, const char** attr),
							   void (*endelCb)(void* ud, const char* el),
							   void* ud)
{
	const char* attr[NSVG_XML_MAX_ATTRIBS];
	int nattr = 0;
	char* cbname;
	int start = 0;
	int end = 0;
	char quote;

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

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

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

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

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

		// Skip white space before the attrib name
		while (*s && nsvg__isspace(*s)) s++;
		if (!*s) break;
		if (*s == '/') {
			end = 1;
			break;
		}
		name = s;
		// Find end of the attrib name.
		while (*s && !nsvg__isspace(*s) && *s != '=') s++;
		if (*s) { *s++ = '\0'; }
		// Skip until the beginning of the value.
		while (*s && *s != '\"' && *s != '\'') s++;
		if (!*s) break;
		quote = *s;
		s++;
		// Store value and find the end of it.
		value = s;
		while (*s && *s != quote) s++;
		if (*s) { *s++ = '\0'; }

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

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

	// Call callbacks.
	if (start && startelCb)
		(*startelCb)(ud, cbname, attr);
	if (end && endelCb)
		(*endelCb)(ud, cbname);
}

NANOSVG_SCOPE
int nsvg__parseXML(char* input,
				   void (*startelCb)(void* ud, const char* el, const char** attr),
				   void (*endelCb)(void* ud, const char* el),
				   void (*contentCb)(void* ud, const char* s),
				   void* ud)
{
	char* s = input;
	char* mark = s;
	int state = NSVG_XML_CONTENT;
	while (*s) {
		if (*s == '<' && state == NSVG_XML_CONTENT) {
			// Start of a tag
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			mark = s;
			state = NSVG_XML_TAG;
		} else if (*s == '>' && state == NSVG_XML_TAG) {
			// Start of a content or new tag.
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			nsvg__parseElement(mark, startelCb, endelCb, ud);
			mark = s;
			state = NSVG_XML_CONTENT;
		} else {
			s++;







|









|



















|


|







|



|




|




|







|


|




|




|






|



|


















|





|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
	return c >= '0' && c <= '9';
}

static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }


/* Simple XML parser */

#define NSVG_XML_TAG 1
#define NSVG_XML_CONTENT 2
#define NSVG_XML_MAX_ATTRIBS 256

static void nsvg__parseContent(char* s,
							   void (*contentCb)(void* ud, const char* s),
							   void* ud)
{
	/* Trim start white spaces */
	while (*s && nsvg__isspace(*s)) s++;
	if (!*s) return;

	if (contentCb)
		(*contentCb)(ud, s);
}

static void nsvg__parseElement(char* s,
							   void (*startelCb)(void* ud, const char* el, const char** attr),
							   void (*endelCb)(void* ud, const char* el),
							   void* ud)
{
	const char* attr[NSVG_XML_MAX_ATTRIBS];
	int nattr = 0;
	char* cbname;
	int start = 0;
	int end = 0;
	char quote;

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

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

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

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

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

		/* Skip white space before the attrib name */
		while (*s && nsvg__isspace(*s)) s++;
		if (!*s) break;
		if (*s == '/') {
			end = 1;
			break;
		}
		name = s;
		/* Find end of the attrib name. */
		while (*s && !nsvg__isspace(*s) && *s != '=') s++;
		if (*s) { *s++ = '\0'; }
		/* Skip until the beginning of the value. */
		while (*s && *s != '\"' && *s != '\'') s++;
		if (!*s) break;
		quote = *s;
		s++;
		/* Store value and find the end of it. */
		value = s;
		while (*s && *s != quote) s++;
		if (*s) { *s++ = '\0'; }

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

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

	/* Call callbacks. */
	if (start && startelCb)
		(*startelCb)(ud, cbname, attr);
	if (end && endelCb)
		(*endelCb)(ud, cbname);
}

NANOSVG_SCOPE
int nsvg__parseXML(char* input,
				   void (*startelCb)(void* ud, const char* el, const char** attr),
				   void (*endelCb)(void* ud, const char* el),
				   void (*contentCb)(void* ud, const char* s),
				   void* ud)
{
	char* s = input;
	char* mark = s;
	int state = NSVG_XML_CONTENT;
	while (*s) {
		if (*s == '<' && state == NSVG_XML_CONTENT) {
			/* Start of a tag */
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			mark = s;
			state = NSVG_XML_TAG;
		} else if (*s == '>' && state == NSVG_XML_TAG) {
			/* Start of a content or new tag. */
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			nsvg__parseElement(mark, startelCb, endelCb, ud);
			mark = s;
			state = NSVG_XML_CONTENT;
		} else {
			s++;
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	NSVGcoordinate cx, cy, r, fx, fy;
} NSVGradialData;

typedef struct NSVGgradientData
{
	char id[64];
	char ref[64];
	char type;
	union {
		NSVGlinearData linear;
		NSVGradialData radial;
	};
	char spread;
	char units;
	float xform[6];







|







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
	NSVGcoordinate cx, cy, r, fx, fy;
} NSVGradialData;

typedef struct NSVGgradientData
{
	char id[64];
	char ref[64];
	signed char type;
	union {
		NSVGlinearData linear;
		NSVGradialData radial;
	};
	char spread;
	char units;
	float xform[6];
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	int i, j, count;
	double roots[2], a, b, c, b2ac, t, v;
	float* v0 = &curve[0];
	float* v1 = &curve[2];
	float* v2 = &curve[4];
	float* v3 = &curve[6];

	// Start the bounding box by end points
	bounds[0] = nsvg__minf(v0[0], v3[0]);
	bounds[1] = nsvg__minf(v0[1], v3[1]);
	bounds[2] = nsvg__maxf(v0[0], v3[0]);
	bounds[3] = nsvg__maxf(v0[1], v3[1]);

	// Bezier curve fits inside the convex hull of it's control points.
	// If control points are inside the bounds, we're done.
	if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
		return;

	// Add bezier curve inflection points in X and Y.
	for (i = 0; i < 2; i++) {
		a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
		b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
		c = 3.0 * v1[i] - 3.0 * v0[i];
		count = 0;
		if (fabs(a) < NSVG_EPSILON) {
			if (fabs(b) > NSVG_EPSILON) {







|





|
|



|







615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
	int i, j, count;
	double roots[2], a, b, c, b2ac, t, v;
	float* v0 = &curve[0];
	float* v1 = &curve[2];
	float* v2 = &curve[4];
	float* v3 = &curve[6];

	/* Start the bounding box by end points */
	bounds[0] = nsvg__minf(v0[0], v3[0]);
	bounds[1] = nsvg__minf(v0[1], v3[1]);
	bounds[2] = nsvg__maxf(v0[0], v3[0]);
	bounds[3] = nsvg__maxf(v0[1], v3[1]);

	/* Bezier curve fits inside the convex hull of it's control points. */
	/* If control points are inside the bounds, we're done. */
	if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
		return;

	/* Add bezier curve inflection points in X and Y. */
	for (i = 0; i < 2; i++) {
		a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
		b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
		c = 3.0 * v1[i] - 3.0 * v0[i];
		count = 0;
		if (fabs(a) < NSVG_EPSILON) {
			if (fabs(b) > NSVG_EPSILON) {
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
	if (p == NULL) goto error;
	memset(p, 0, sizeof(NSVGparser));

	p->image = (NSVGimage*)NANOSVG_malloc(sizeof(NSVGimage));
	if (p->image == NULL) goto error;
	memset(p->image, 0, sizeof(NSVGimage));

	// Init style
	nsvg__xformIdentity(p->attr[0].xform);
	memset(p->attr[0].id, 0, sizeof p->attr[0].id);
	p->attr[0].fillColor = NSVG_RGB(0,0,0);
	p->attr[0].strokeColor = NSVG_RGB(0,0,0);
	p->attr[0].opacity = 1;
	p->attr[0].fillOpacity = 1;
	p->attr[0].strokeOpacity = 1;







|







668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
	if (p == NULL) goto error;
	memset(p, 0, sizeof(NSVGparser));

	p->image = (NSVGimage*)NANOSVG_malloc(sizeof(NSVGimage));
	if (p->image == NULL) goto error;
	memset(p->image, 0, sizeof(NSVGimage));

	/* Init style */
	nsvg__xformIdentity(p->attr[0].xform);
	memset(p->attr[0].id, 0, sizeof p->attr[0].id);
	p->attr[0].fillColor = NSVG_RGB(0,0,0);
	p->attr[0].strokeColor = NSVG_RGB(0,0,0);
	p->attr[0].opacity = 1;
	p->attr[0].fillOpacity = 1;
	p->attr[0].strokeOpacity = 1;
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
		case NSVG_UNITS_PX:			return c.value;
		case NSVG_UNITS_PT:			return c.value / 72.0f * p->dpi;
		case NSVG_UNITS_PC:			return c.value / 6.0f * p->dpi;
		case NSVG_UNITS_MM:			return c.value / 25.4f * p->dpi;
		case NSVG_UNITS_CM:			return c.value / 2.54f * p->dpi;
		case NSVG_UNITS_IN:			return c.value * p->dpi;
		case NSVG_UNITS_EM:			return c.value * attr->fontSize;
		case NSVG_UNITS_EX:			return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
		case NSVG_UNITS_PERCENT:	return orig + c.value / 100.0f * length;
		default:					return c.value;
	}
	return c.value;
}

static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
{
	NSVGgradientData* grad = p->gradients;
	if (id == NULL || *id == '\0')
		return NULL;
	while (grad != NULL) {
		if (strcmp(grad->id, id) == 0)
			return grad;
		grad = grad->next;
	}
	return NULL;
}

static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	NSVGgradientData* data = NULL;
	NSVGgradientData* ref = NULL;
	NSVGgradientStop* stops = NULL;
	NSVGgradient* grad;
	float ox, oy, sw, sh, sl;
	int nstops = 0;
	int refIter;

	data = nsvg__findGradientData(p, id);
	if (data == NULL) return NULL;

	// TODO: use ref to fill in all unset values too.
	ref = data;
	refIter = 0;
	while (ref != NULL) {
		NSVGgradientData* nextRef = NULL;
		if (stops == NULL && ref->stops != NULL) {
			stops = ref->stops;
			nstops = ref->nstops;
			break;
		}
		nextRef = nsvg__findGradientData(p, ref->ref);
		if (nextRef == ref) break; // prevent infite loops on malformed data
		ref = nextRef;
		refIter++;
		if (refIter > 32) break; // prevent infite loops on malformed data
	}
	if (stops == NULL) return NULL;

	grad = (NSVGgradient*)NANOSVG_malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1));
	if (grad == NULL) return NULL;

	// The shape width and height.
	if (data->units == NSVG_OBJECT_SPACE) {
		ox = localBounds[0];
		oy = localBounds[1];
		sw = localBounds[2] - localBounds[0];
		sh = localBounds[3] - localBounds[1];
	} else {
		ox = nsvg__actualOrigX(p);
		oy = nsvg__actualOrigY(p);
		sw = nsvg__actualWidth(p);
		sh = nsvg__actualHeight(p);
	}
	sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f);

	if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
		float x1, y1, x2, y2, dx, dy;
		x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
		y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
		x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
		y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
		// Calculate transform aligned to the line
		dx = x2 - x1;
		dy = y2 - y1;
		grad->xform[0] = dy; grad->xform[1] = -dx;
		grad->xform[2] = dx; grad->xform[3] = dy;
		grad->xform[4] = x1; grad->xform[5] = y1;
	} else {
		float cx, cy, fx, fy, r;
		cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
		cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
		fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
		fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
		r = nsvg__convertToPixels(p, data->radial.r, 0, sl);
		// Calculate transform aligned to the circle
		grad->xform[0] = r; grad->xform[1] = 0;
		grad->xform[2] = 0; grad->xform[3] = r;
		grad->xform[4] = cx; grad->xform[5] = cy;
		grad->fx = fx / r;
		grad->fy = fy / r;
	}

	nsvg__xformMultiply(grad->xform, data->xform);
	nsvg__xformMultiply(grad->xform, attr->xform);

	grad->spread = data->spread;
	memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
	grad->nstops = nstops;

	*paintType = data->type;








|



















|

<











|










|


|






|



















|












|








|







854
855
856
857
858
859
860
861
862
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
		case NSVG_UNITS_PX:			return c.value;
		case NSVG_UNITS_PT:			return c.value / 72.0f * p->dpi;
		case NSVG_UNITS_PC:			return c.value / 6.0f * p->dpi;
		case NSVG_UNITS_MM:			return c.value / 25.4f * p->dpi;
		case NSVG_UNITS_CM:			return c.value / 2.54f * p->dpi;
		case NSVG_UNITS_IN:			return c.value * p->dpi;
		case NSVG_UNITS_EM:			return c.value * attr->fontSize;
		case NSVG_UNITS_EX:			return c.value * attr->fontSize * 0.52f; /* x-height of Helvetica. */
		case NSVG_UNITS_PERCENT:	return orig + c.value / 100.0f * length;
		default:					return c.value;
	}
	return c.value;
}

static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
{
	NSVGgradientData* grad = p->gradients;
	if (id == NULL || *id == '\0')
		return NULL;
	while (grad != NULL) {
		if (strcmp(grad->id, id) == 0)
			return grad;
		grad = grad->next;
	}
	return NULL;
}

static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, float *xform, signed char* paintType)
{

	NSVGgradientData* data = NULL;
	NSVGgradientData* ref = NULL;
	NSVGgradientStop* stops = NULL;
	NSVGgradient* grad;
	float ox, oy, sw, sh, sl;
	int nstops = 0;
	int refIter;

	data = nsvg__findGradientData(p, id);
	if (data == NULL) return NULL;

	/* TODO: use ref to fill in all unset values too. */
	ref = data;
	refIter = 0;
	while (ref != NULL) {
		NSVGgradientData* nextRef = NULL;
		if (stops == NULL && ref->stops != NULL) {
			stops = ref->stops;
			nstops = ref->nstops;
			break;
		}
		nextRef = nsvg__findGradientData(p, ref->ref);
		if (nextRef == ref) break; /* prevent infite loops on malformed data */
		ref = nextRef;
		refIter++;
		if (refIter > 32) break; /* prevent infite loops on malformed data */
	}
	if (stops == NULL) return NULL;

	grad = (NSVGgradient*)NANOSVG_malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1));
	if (grad == NULL) return NULL;

	/* The shape width and height. */
	if (data->units == NSVG_OBJECT_SPACE) {
		ox = localBounds[0];
		oy = localBounds[1];
		sw = localBounds[2] - localBounds[0];
		sh = localBounds[3] - localBounds[1];
	} else {
		ox = nsvg__actualOrigX(p);
		oy = nsvg__actualOrigY(p);
		sw = nsvg__actualWidth(p);
		sh = nsvg__actualHeight(p);
	}
	sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f);

	if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
		float x1, y1, x2, y2, dx, dy;
		x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
		y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
		x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
		y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
		/* Calculate transform aligned to the line */
		dx = x2 - x1;
		dy = y2 - y1;
		grad->xform[0] = dy; grad->xform[1] = -dx;
		grad->xform[2] = dx; grad->xform[3] = dy;
		grad->xform[4] = x1; grad->xform[5] = y1;
	} else {
		float cx, cy, fx, fy, r;
		cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
		cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
		fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
		fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
		r = nsvg__convertToPixels(p, data->radial.r, 0, sl);
		/* Calculate transform aligned to the circle */
		grad->xform[0] = r; grad->xform[1] = 0;
		grad->xform[2] = 0; grad->xform[3] = r;
		grad->xform[4] = cx; grad->xform[5] = cy;
		grad->fx = fx / r;
		grad->fy = fy / r;
	}

	nsvg__xformMultiply(grad->xform, data->xform);
	nsvg__xformMultiply(grad->xform, xform);

	grad->spread = data->spread;
	memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
	grad->nstops = nstops;

	*paintType = data->type;

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

	shape = (NSVGshape*)NANOSVG_malloc(sizeof(NSVGshape));
	if (shape == NULL) goto error;
	memset(shape, 0, sizeof(NSVGshape));

	memcpy(shape->id, attr->id, sizeof shape->id);



	scale = nsvg__getAverageScale(attr->xform);
	shape->strokeWidth = attr->strokeWidth * scale;
	shape->strokeDashOffset = attr->strokeDashOffset * scale;
	shape->strokeDashCount = (char)attr->strokeDashCount;
	for (i = 0; i < attr->strokeDashCount; i++)
		shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
	shape->strokeLineJoin = attr->strokeLineJoin;
	shape->strokeLineCap = attr->strokeLineCap;
	shape->miterLimit = attr->miterLimit;
	shape->fillRule = attr->fillRule;
	shape->opacity = attr->opacity;

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

	// Calculate shape bounds
	shape->bounds[0] = shape->paths->bounds[0];
	shape->bounds[1] = shape->paths->bounds[1];
	shape->bounds[2] = shape->paths->bounds[2];
	shape->bounds[3] = shape->paths->bounds[3];
	for (path = shape->paths->next; path != NULL; path = path->next) {
		shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
		shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
		shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
		shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
	}

	// Set fill
	if (attr->hasFill == 0) {
		shape->fill.type = NSVG_PAINT_NONE;
	} else if (attr->hasFill == 1) {
		shape->fill.type = NSVG_PAINT_COLOR;
		shape->fill.color = attr->fillColor;
		shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
	} else if (attr->hasFill == 2) {
		float inv[6], localBounds[4];
		nsvg__xformInverse(inv, attr->xform);
		nsvg__getLocalBounds(localBounds, shape, inv);
		shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
		if (shape->fill.gradient == NULL) {
			shape->fill.type = NSVG_PAINT_NONE;
		}
	}

	// Set stroke
	if (attr->hasStroke == 0) {
		shape->stroke.type = NSVG_PAINT_NONE;
	} else if (attr->hasStroke == 1) {
		shape->stroke.type = NSVG_PAINT_COLOR;
		shape->stroke.color = attr->strokeColor;
		shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24;
	} else if (attr->hasStroke == 2) {
		float inv[6], localBounds[4];
		nsvg__xformInverse(inv, attr->xform);
		nsvg__getLocalBounds(localBounds, shape, inv);
		shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
		if (shape->stroke.gradient == NULL)
			shape->stroke.type = NSVG_PAINT_NONE;
	}

	// Set flags
	shape->flags = ((attr->visible & NSVG_VIS_DISPLAY) && (attr->visible & NSVG_VIS_VISIBLE) ? NSVG_FLAGS_VISIBLE : 0x00);

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

	return;







>
>
>















|











|







<
<
<
<
<
|
|
|
<
|







<
<
<
<
<
|


|


|







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

	shape = (NSVGshape*)NANOSVG_malloc(sizeof(NSVGshape));
	if (shape == NULL) goto error;
	memset(shape, 0, sizeof(NSVGshape));

	memcpy(shape->id, attr->id, sizeof shape->id);
	memcpy(shape->fillGradient, attr->fillGradient, sizeof shape->fillGradient);
	memcpy(shape->strokeGradient, attr->strokeGradient, sizeof shape->strokeGradient);
	memcpy(shape->xform, attr->xform, sizeof shape->xform);
	scale = nsvg__getAverageScale(attr->xform);
	shape->strokeWidth = attr->strokeWidth * scale;
	shape->strokeDashOffset = attr->strokeDashOffset * scale;
	shape->strokeDashCount = (char)attr->strokeDashCount;
	for (i = 0; i < attr->strokeDashCount; i++)
		shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
	shape->strokeLineJoin = attr->strokeLineJoin;
	shape->strokeLineCap = attr->strokeLineCap;
	shape->miterLimit = attr->miterLimit;
	shape->fillRule = attr->fillRule;
	shape->opacity = attr->opacity;

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

	/* Calculate shape bounds */
	shape->bounds[0] = shape->paths->bounds[0];
	shape->bounds[1] = shape->paths->bounds[1];
	shape->bounds[2] = shape->paths->bounds[2];
	shape->bounds[3] = shape->paths->bounds[3];
	for (path = shape->paths->next; path != NULL; path = path->next) {
		shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
		shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
		shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
		shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
	}

	/* Set fill */
	if (attr->hasFill == 0) {
		shape->fill.type = NSVG_PAINT_NONE;
	} else if (attr->hasFill == 1) {
		shape->fill.type = NSVG_PAINT_COLOR;
		shape->fill.color = attr->fillColor;
		shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
	} else if (attr->hasFill == 2) {





		shape->fill.type = NSVG_PAINT_UNDEF;
	}


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





		shape->stroke.type = NSVG_PAINT_UNDEF;
	}

	/* Set flags */
	shape->flags = ((attr->visible & NSVG_VIS_DISPLAY) && (attr->visible & NSVG_VIS_VISIBLE) ? NSVG_FLAGS_VISIBLE : 0x00);

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

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

	if (p->npts < 4)
		return;

	if (closed)
		nsvg__lineTo(p, p->pts[0], p->pts[1]);

	// Expect 1 + N*3 points (N = number of cubic bezier segments).
	if ((p->npts % 3) != 1)
		return;

	path = (NSVGpath*)NANOSVG_malloc(sizeof(NSVGpath));
	if (path == NULL) goto error;
	memset(path, 0, sizeof(NSVGpath));

	path->pts = (float*)NANOSVG_malloc(p->npts*2*sizeof(float));
	if (path->pts == NULL) goto error;
	path->closed = closed;
	path->npts = p->npts;

	// Transform path.
	for (i = 0; i < p->npts; ++i)
		nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform);

	// Find bounds
	for (i = 0; i < path->npts-1; i += 3) {
		curve = &path->pts[i*2];
		nsvg__curveBounds(bounds, curve);
		if (i == 0) {
			path->bounds[0] = bounds[0];
			path->bounds[1] = bounds[1];
			path->bounds[2] = bounds[2];







|












|



|







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

	if (p->npts < 4)
		return;

	if (closed)
		nsvg__lineTo(p, p->pts[0], p->pts[1]);

	/* Expect 1 + N*3 points (N = number of cubic bezier segments). */
	if ((p->npts % 3) != 1)
		return;

	path = (NSVGpath*)NANOSVG_malloc(sizeof(NSVGpath));
	if (path == NULL) goto error;
	memset(path, 0, sizeof(NSVGpath));

	path->pts = (float*)NANOSVG_malloc(p->npts*2*sizeof(float));
	if (path->pts == NULL) goto error;
	path->closed = closed;
	path->npts = p->npts;

	/* Transform path. */
	for (i = 0; i < p->npts; ++i)
		nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform);

	/* Find bounds */
	for (i = 0; i < path->npts-1; i += 3) {
		curve = &path->pts[i*2];
		nsvg__curveBounds(bounds, curve);
		if (i == 0) {
			path->bounds[0] = bounds[0];
			path->bounds[1] = bounds[1];
			path->bounds[2] = bounds[2];
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
error:
	if (path != NULL) {
		if (path->pts != NULL) NANOSVG_free(path->pts);
		NANOSVG_free(path);
	}
}

// We roll our own string to float because the std library one uses locale and messes things up.
static double nsvg__atof(const char* s)
{
	char* cur = (char*)s;
	char* end = NULL;
	double res = 0.0, sign = 1.0;
#if defined(_MSC_VER) && (_MSC_VER == 1200)
	__int64 intPart = 0, fracPart = 0;
#else
	long long intPart = 0, fracPart = 0;
#endif
	char hasIntPart = 0, hasFracPart = 0;

	// Parse optional sign
	if (*cur == '+') {
		cur++;
	} else if (*cur == '-') {
		sign = -1;
		cur++;
	}

	// Parse integer part
	if (nsvg__isdigit(*cur)) {
		// Parse digit sequence
#if defined(_MSC_VER) && (_MSC_VER == 1200)
		intPart = strtol(cur, &end, 10);
#else
		intPart = strtoll(cur, &end, 10);
#endif
		if (cur != end) {
			res = (double)intPart;
			hasIntPart = 1;
			cur = end;
		}
	}

	// Parse fractional part.
	if (*cur == '.') {
		cur++; // Skip '.'
		if (nsvg__isdigit(*cur)) {
			// Parse digit sequence
#if defined(_MSC_VER) && (_MSC_VER == 1200)
			fracPart = strtol(cur, &end, 10);
#else
			fracPart = strtoll(cur, &end, 10);
#endif
			if (cur != end) {
				res += (double)fracPart / pow(10.0, (double)(end - cur));
				hasFracPart = 1;
				cur = end;
			}
		}
	}

	// A valid number should have integer or fractional part.
	if (!hasIntPart && !hasFracPart)
		return 0.0;

	// Parse optional exponent
	if (*cur == 'e' || *cur == 'E') {
		int expPart = 0;
		cur++; // skip 'E'
		expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
		if (cur != end) {
			res *= pow(10.0, (double)expPart);
		}
	}

	return res * sign;
}


static const char* nsvg__parseNumber(const char* s, char* it, const int size)
{
	const int last = size-1;
	int i = 0;

	// sign
	if (*s == '-' || *s == '+') {
		if (i < last) it[i++] = *s;
		s++;
	}
	// integer part
	while (*s && nsvg__isdigit(*s)) {
		if (i < last) it[i++] = *s;
		s++;
	}
	if (*s == '.') {
		// decimal point
		if (i < last) it[i++] = *s;
		s++;
		// fraction part
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	// exponent
	if (*s == 'e' || *s == 'E') {
		if (i < last) it[i++] = *s;
		s++;
		if (*s == '-' || *s == '+') {
			if (i < last) it[i++] = *s;
			s++;
		}
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	it[i] = '\0';

	return s;
}














static const char* nsvg__getNextPathItem(const char* s, char* it)
{
	it[0] = '\0';
	// Skip white spaces and commas
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	if (!*s) return s;
	if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
		s = nsvg__parseNumber(s, it, 64);
	} else {
		// Parse command
		it[0] = *s++;
		it[1] = '\0';
		return s;
	}

	return s;
}

static unsigned int nsvg__parseColorHex(const char* str)
{
	unsigned int c = 0, r = 0, g = 0, b = 0;
	int n = 0;
	str++; // skip #
	// Calculate number of characters.
	while(str[n] && !nsvg__isspace(str[n]))
		n++;
	if (n == 6) {
		sscanf(str, "%x", &c);
	} else if (n == 3) {

		sscanf(str, "%x", &c);
		c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8);
		c |= c<<4;


	}
	r = (c >> 16) & 0xff;
	g = (c >> 8) & 0xff;
	b = c & 0xff;
	return NSVG_RGB(r,g,b);
}






static unsigned int nsvg__parseColorRGB(const char* str)
{
	int r = -1, g = -1, b = -1;





	char s1[32]="", s2[32]="";
	sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);





	if (strchr(s1, '%')) {









		return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100);















	} else {
		return NSVG_RGB(r,g,b);

	}






}

typedef struct NSVGNamedColor {
	const char* name;
	unsigned int color;
} NSVGNamedColor;








|












|







|

|












|

|

|













|



|


|
|














|




|





|


|





|
















>
>
>
>
>
>
>
>
>
>
>
>
>




|





|










|
<
<
<
<
<
<
|
<
>
|
<
<
>
>
|
<
<
<
<
|
>
>
>
>
>



|
>
>
>
>
>
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
>
>
>
>
>
>







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
error:
	if (path != NULL) {
		if (path->pts != NULL) NANOSVG_free(path->pts);
		NANOSVG_free(path);
	}
}

/* We roll our own string to float because the std library one uses locale and messes things up. */
static double nsvg__atof(const char* s)
{
	char* cur = (char*)s;
	char* end = NULL;
	double res = 0.0, sign = 1.0;
#if defined(_MSC_VER) && (_MSC_VER == 1200)
	__int64 intPart = 0, fracPart = 0;
#else
	long long intPart = 0, fracPart = 0;
#endif
	char hasIntPart = 0, hasFracPart = 0;

	/* Parse optional sign */
	if (*cur == '+') {
		cur++;
	} else if (*cur == '-') {
		sign = -1;
		cur++;
	}

	/* Parse integer part */
	if (nsvg__isdigit(*cur)) {
		/* Parse digit sequence */
#if defined(_MSC_VER) && (_MSC_VER == 1200)
		intPart = strtol(cur, &end, 10);
#else
		intPart = strtoll(cur, &end, 10);
#endif
		if (cur != end) {
			res = (double)intPart;
			hasIntPart = 1;
			cur = end;
		}
	}

	/* Parse fractional part. */
	if (*cur == '.') {
		cur++; /* Skip '.' */
		if (nsvg__isdigit(*cur)) {
			/* Parse digit sequence */
#if defined(_MSC_VER) && (_MSC_VER == 1200)
			fracPart = strtol(cur, &end, 10);
#else
			fracPart = strtoll(cur, &end, 10);
#endif
			if (cur != end) {
				res += (double)fracPart / pow(10.0, (double)(end - cur));
				hasFracPart = 1;
				cur = end;
			}
		}
	}

	/* A valid number should have integer or fractional part. */
	if (!hasIntPart && !hasFracPart)
		return 0.0;

	/* Parse optional exponent */
	if (*cur == 'e' || *cur == 'E') {
		int expPart = 0;
		cur++; /* skip 'E' */
		expPart = strtol(cur, &end, 10); /* Parse digit sequence with sign */
		if (cur != end) {
			res *= pow(10.0, (double)expPart);
		}
	}

	return res * sign;
}


static const char* nsvg__parseNumber(const char* s, char* it, const int size)
{
	const int last = size-1;
	int i = 0;

	/* sign */
	if (*s == '-' || *s == '+') {
		if (i < last) it[i++] = *s;
		s++;
	}
	/* integer part */
	while (*s && nsvg__isdigit(*s)) {
		if (i < last) it[i++] = *s;
		s++;
	}
	if (*s == '.') {
		/* decimal point */
		if (i < last) it[i++] = *s;
		s++;
		/* fraction part */
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	/* exponent */
	if (*s == 'e' || *s == 'E') {
		if (i < last) it[i++] = *s;
		s++;
		if (*s == '-' || *s == '+') {
			if (i < last) it[i++] = *s;
			s++;
		}
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	it[i] = '\0';

	return s;
}

static const char* nsvg__getNextPathItemWhenArcFlag(const char* s, char* it)
{
	it[0] = '\0';
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	if (!*s) return s;
	if (*s == '0' || *s == '1') {
		it[0] = *s++;
		it[1] = '\0';
		return s;
	}
	return s;
}

static const char* nsvg__getNextPathItem(const char* s, char* it)
{
	it[0] = '\0';
	/* Skip white spaces and commas */
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	if (!*s) return s;
	if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
		s = nsvg__parseNumber(s, it, 64);
	} else {
		/* Parse command */
		it[0] = *s++;
		it[1] = '\0';
		return s;
	}

	return s;
}

static unsigned int nsvg__parseColorHex(const char* str)
{
	unsigned int r=0, g=0, b=0;






	if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 )		/* 2 digit hex */

		return NSVG_RGB(r, g, b);
	if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 )		/* 1 digit hex, e.g. #abc -> 0xccbbaa */


		return NSVG_RGB(r*17, g*17, b*17);			/* same effect as (r<<4|r), (g<<4|g), .. */
	return NSVG_RGB(128, 128, 128);
}





/*
 * Parse rgb color. The pointer 'str' must point at "rgb(" (4+ characters).
 * This function returns gray (rgb(128, 128, 128) == '#808080') on parse errors
 * for backwards compatibility. Note: other image viewers return black instead.
 */

static unsigned int nsvg__parseColorRGB(const char* str)
{
	int i;
	unsigned int rgbi[3];
	float rgbf[3];
	/* try decimal integers first */
	if (sscanf(str, "rgb(%u, %u, %u)", &rgbi[0], &rgbi[1], &rgbi[2]) != 3) {
		/* integers failed, try percent values (float, locale independent) */
		const char delimiter[3] = {',', ',', ')'};
		str += 4; /* skip "rgb(" */
		for (i = 0; i < 3; i++) {
			while (*str && (nsvg__isspace(*str))) str++; 	/* skip leading spaces */
			if (*str == '+') str++;				/* skip '+' (don't allow '-') */
			if (!*str) break;
			rgbf[i] = nsvg__atof(str);

			/*
			 * Note 1: it would be great if nsvg__atof() returned how many
			 * bytes it consumed but it doesn't. We need to skip the number,
			 * the '%' character, spaces, and the delimiter ',' or ')'.
			 *
			 * Note 2: The following code does not allow values like "33.%",
			 * i.e. a decimal point w/o fractional part, but this is consistent
			 * with other image viewers, e.g. firefox, chrome, eog, gimp.
			 */

			while (*str && nsvg__isdigit(*str)) str++;		/* skip integer part */
			if (*str == '.') {
				str++;
				if (!nsvg__isdigit(*str)) break;		/* error: no digit after '.' */
				while (*str && nsvg__isdigit(*str)) str++;	/* skip fractional part */
			}
			if (*str == '%') str++; else break;
			while (nsvg__isspace(*str)) str++;
			if (*str == delimiter[i]) str++;
			else break;
		}
		if (i == 3) {
			rgbi[0] = roundf(rgbf[0] * 2.55f);
			rgbi[1] = roundf(rgbf[1] * 2.55f);
			rgbi[2] = roundf(rgbf[2] * 2.55f);
		} else {

			rgbi[0] = rgbi[1] = rgbi[2] = 128;
		}
	}
	/* clip values as the CSS spec requires */
	for (i = 0; i < 3; i++) {
		if (rgbi[i] > 255) rgbi[i] = 255;
	}
	return NSVG_RGB(rgbi[0], rgbi[1], rgbi[2]);
}

typedef struct NSVGNamedColor {
	const char* name;
	unsigned int color;
} NSVGNamedColor;

1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
	else if (units[0] == 'e' && units[1] == 'x')
		return NSVG_UNITS_EX;
	return NSVG_UNITS_USER;
}

static int nsvg__isCoordinate(const char* s)
{
	// optional sign
	if (*s == '-' || *s == '+')
		s++;
	// must have at least one digit
	return nsvg__isdigit(*s);
}

static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
{
	NSVGcoordinate coord = {0, NSVG_UNITS_USER};
	char units[32]="";
	sscanf(str, "%f%s", &coord.value, units);







|


|
|







1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
	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);
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
		nsvg__xformPremultiply(xform, t);
	}
}

static void nsvg__parseUrl(char* id, const char* str)
{
	int i = 0;
	str += 4; // "url(";
	if (*str == '#')
		str++;
	while (i < 63 && *str != ')') {
		id[i] = *str++;
		i++;
	}
	id[i] = '\0';
}

static char nsvg__parseLineCap(const char* str)
{
	if (strcmp(str, "butt") == 0)
		return NSVG_CAP_BUTT;
	else if (strcmp(str, "round") == 0)
		return NSVG_CAP_ROUND;
	else if (strcmp(str, "square") == 0)
		return NSVG_CAP_SQUARE;
	// TODO: handle inherit.
	return NSVG_CAP_BUTT;
}

static char nsvg__parseLineJoin(const char* str)
{
	if (strcmp(str, "miter") == 0)
		return NSVG_JOIN_MITER;
	else if (strcmp(str, "round") == 0)
		return NSVG_JOIN_ROUND;
	else if (strcmp(str, "bevel") == 0)
		return NSVG_JOIN_BEVEL;
	// TODO: handle inherit.
	return NSVG_JOIN_MITER;
}

static char nsvg__parseFillRule(const char* str)
{
	if (strcmp(str, "nonzero") == 0)
		return NSVG_FILLRULE_NONZERO;
	else if (strcmp(str, "evenodd") == 0)
		return NSVG_FILLRULE_EVENODD;
	// TODO: handle inherit.
	return NSVG_FILLRULE_NONZERO;
}

static const char* nsvg__getNextDashItem(const char* s, char* it)
{
	int n = 0;
	it[0] = '\0';
	// Skip white spaces and commas
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	// Advance until whitespace, comma or end.
	while (*s && (!nsvg__isspace(*s) && *s != ',')) {
		if (n < 63)
			it[n++] = *s;
		s++;
	}
	it[n++] = '\0';
	return s;
}

static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray)
{
	char item[64];
	int count = 0, i;
	float sum = 0.0f;

	// Handle "none"
	if (str[0] == 'n')
		return 0;

	// Parse dashes
	while (*str) {
		str = nsvg__getNextDashItem(str, item);
		if (!*item) break;
		if (count < NSVG_MAX_DASHES)
			strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
	}








|
|

|














|











|









|







|

|















|



|







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
		nsvg__xformPremultiply(xform, t);
	}
}

static void nsvg__parseUrl(char* id, const char* str)
{
	int i = 0;
	str += 4; /* "url("; */
	if (*str && *str == '#')
		str++;
	while (i < 63 && *str && *str != ')') {
		id[i] = *str++;
		i++;
	}
	id[i] = '\0';
}

static char nsvg__parseLineCap(const char* str)
{
	if (strcmp(str, "butt") == 0)
		return NSVG_CAP_BUTT;
	else if (strcmp(str, "round") == 0)
		return NSVG_CAP_ROUND;
	else if (strcmp(str, "square") == 0)
		return NSVG_CAP_SQUARE;
	/* TODO: handle inherit. */
	return NSVG_CAP_BUTT;
}

static char nsvg__parseLineJoin(const char* str)
{
	if (strcmp(str, "miter") == 0)
		return NSVG_JOIN_MITER;
	else if (strcmp(str, "round") == 0)
		return NSVG_JOIN_ROUND;
	else if (strcmp(str, "bevel") == 0)
		return NSVG_JOIN_BEVEL;
	/* TODO: handle inherit. */
	return NSVG_JOIN_MITER;
}

static char nsvg__parseFillRule(const char* str)
{
	if (strcmp(str, "nonzero") == 0)
		return NSVG_FILLRULE_NONZERO;
	else if (strcmp(str, "evenodd") == 0)
		return NSVG_FILLRULE_EVENODD;
	/* TODO: handle inherit. */
	return NSVG_FILLRULE_NONZERO;
}

static const char* nsvg__getNextDashItem(const char* s, char* it)
{
	int n = 0;
	it[0] = '\0';
	/* Skip white spaces and commas */
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	/* Advance until whitespace, comma or end. */
	while (*s && (!nsvg__isspace(*s) && *s != ',')) {
		if (n < 63)
			it[n++] = *s;
		s++;
	}
	it[n++] = '\0';
	return s;
}

static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray)
{
	char item[64];
	int count = 0, i;
	float sum = 0.0f;

	/* Handle "none" */
	if (str[0] == 'n')
		return 0;

	/* Parse dashes */
	while (*str) {
		str = nsvg__getNextDashItem(str, item);
		if (!*item) break;
		if (count < NSVG_MAX_DASHES)
			strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
	}

1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
	if (!attr) return 0;

	if (strcmp(name, "style") == 0) {
		nsvg__parseStyle(p, value);
	} else if (strcmp(name, "display") == 0) {
		if (strcmp(value, "none") == 0)
			attr->visible &= ~NSVG_VIS_DISPLAY;
		// Don't reset ->visible on display:inline, one display:none hides the whole subtree

	} else if (strcmp(name, "visibility") == 0) {
		if (strcmp(value, "hidden") == 0) {
			attr->visible &= ~NSVG_VIS_VISIBLE;
		} else if (strcmp(value, "visible") == 0) {
			attr->visible |= NSVG_VIS_VISIBLE;
		}







|







1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
	if (!attr) return 0;

	if (strcmp(name, "style") == 0) {
		nsvg__parseStyle(p, value);
	} else if (strcmp(name, "display") == 0) {
		if (strcmp(value, "none") == 0)
			attr->visible &= ~NSVG_VIS_DISPLAY;
		/* Don't reset ->visible on display:inline, one display:none hides the whole subtree */

	} else if (strcmp(name, "visibility") == 0) {
		if (strcmp(value, "hidden") == 0) {
			attr->visible &= ~NSVG_VIS_VISIBLE;
		} else if (strcmp(value, "visible") == 0) {
			attr->visible |= NSVG_VIS_VISIBLE;
		}
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
	int n;

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

	val = str;

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

	n = (int)(str - start);
	if (n > 511) n = 511;
	if (n) memcpy(name, start, n);
	name[n] = 0;







|







1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
	int n;

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

	val = str;

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

	n = (int)(str - start);
	if (n > 511) n = 511;
	if (n) memcpy(name, start, n);
	name[n] = 0;
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955

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

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

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

		nsvg__parseNameValue(p, start, end);
		if (*str) ++str;
	}
}







|





|







1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998

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

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

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

		nsvg__parseNameValue(p, start, end);
		if (*str) ++str;
	}
}
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
	} else {
		cx = args[0];
		cy = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	// Convert to cubic bezier
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);








|







2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
	} else {
		cx = args[0];
		cy = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	/* Convert to cubic bezier */
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
		x2 = args[0];
		y2 = args[1];
	}

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

	// Convert to cubix bezier
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);








|







2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
		x2 = args[0];
		y2 = args[1];
	}

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

	/* Convert to cubix bezier */
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

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
	if (r < -1.0f) r = -1.0f;
	if (r > 1.0f) r = 1.0f;
	return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
}

static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	// Ported from canvg (https://code.google.com/p/canvg/)
	float rx, ry, rotx;
	float x1, y1, x2, y2, cx, cy, dx, dy, d;
	float x1p, y1p, cxp, cyp, s, sa, sb;
	float ux, uy, vx, vy, a1, da;
	float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
	float sinrx, cosrx;
	int fa, fs;
	int i, ndivs;
	float hda, kappa;

	rx = fabsf(args[0]);				// y radius
	ry = fabsf(args[1]);				// x radius
	rotx = args[2] / 180.0f * NSVG_PI;		// x rotation angle
	fa = fabsf(args[3]) > 1e-6 ? 1 : 0;	// Large arc
	fs = fabsf(args[4]) > 1e-6 ? 1 : 0;	// Sweep direction
	x1 = *cpx;							// start point
	y1 = *cpy;
	if (rel) {							// end point
		x2 = *cpx + args[5];
		y2 = *cpy + args[6];
	} else {
		x2 = args[5];
		y2 = args[6];
	}

	dx = x1 - x2;
	dy = y1 - y2;
	d = sqrtf(dx*dx + dy*dy);
	if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
		// The arc degenerates to a line
		nsvg__lineTo(p, x2, y2);
		*cpx = x2;
		*cpy = y2;
		return;
	}

	sinrx = sinf(rotx);
	cosrx = cosf(rotx);

	// Convert to center point parameterization.
	// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
	// 1) Compute x1', y1'
	x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
	y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
	d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry);
	if (d > 1) {
		d = sqrtf(d);
		rx *= d;
		ry *= d;
	}
	// 2) Compute cx', cy'
	s = 0.0f;
	sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p);
	sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p);
	if (sa < 0.0f) sa = 0.0f;
	if (sb > 0.0f)
		s = sqrtf(sa / sb);
	if (fa == fs)
		s = -s;
	cxp = s * rx * y1p / ry;
	cyp = s * -ry * x1p / rx;

	// 3) Compute cx,cy from cx',cy'
	cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp;
	cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp;

	// 4) Calculate theta1, and delta theta.
	ux = (x1p - cxp) / rx;
	uy = (y1p - cyp) / ry;
	vx = (-x1p - cxp) / rx;
	vy = (-y1p - cyp) / ry;
	a1 = nsvg__vecang(1.0f,0.0f, ux,uy);	// Initial angle
	da = nsvg__vecang(ux,uy, vx,vy);		// Delta angle

//	if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
//	if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;

	if (fs == 0 && da > 0)
		da -= 2 * NSVG_PI;
	else if (fs == 1 && da < 0)
		da += 2 * NSVG_PI;

	// Approximate the arc using cubic spline segments.
	t[0] = cosrx; t[1] = sinrx;
	t[2] = -sinrx; t[3] = cosrx;
	t[4] = cx; t[5] = cy;

	// Split arc into max 90 degree segments.
	// The loop assumes an iteration per end point (including start and end), this +1.
	ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
	hda = (da / (float)ndivs) / 2.0f;





	kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
	if (da < 0.0f)
		kappa = -kappa;

	for (i = 0; i <= ndivs; i++) {
		a = a1 + da * ((float)i/(float)ndivs);
		dx = cosf(a);
		dy = sinf(a);
		nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position
		nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent
		if (i > 0)
			nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y);
		px = x;
		py = y;
		ptanx = tanx;
		ptany = tany;
	}







|










|
|
|
|
|
|

|











|









|
|
|








|











|



|




|
|

|
|






|




|
|


>
>
>
>
>
|







|
|







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
	if (r < -1.0f) r = -1.0f;
	if (r > 1.0f) r = 1.0f;
	return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
}

static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	/* Ported from canvg (https://code.google.com/p/canvg/) */
	float rx, ry, rotx;
	float x1, y1, x2, y2, cx, cy, dx, dy, d;
	float x1p, y1p, cxp, cyp, s, sa, sb;
	float ux, uy, vx, vy, a1, da;
	float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
	float sinrx, cosrx;
	int fa, fs;
	int i, ndivs;
	float hda, kappa;

	rx = fabsf(args[0]);				/* y radius */
	ry = fabsf(args[1]);				/* x radius */
	rotx = args[2] / 180.0f * NSVG_PI;		/* x rotation angle */
	fa = fabsf(args[3]) > 1e-6 ? 1 : 0;	/* Large arc */
	fs = fabsf(args[4]) > 1e-6 ? 1 : 0;	/* Sweep direction */
	x1 = *cpx;							/* start point */
	y1 = *cpy;
	if (rel) {							/* end point */
		x2 = *cpx + args[5];
		y2 = *cpy + args[6];
	} else {
		x2 = args[5];
		y2 = args[6];
	}

	dx = x1 - x2;
	dy = y1 - y2;
	d = sqrtf(dx*dx + dy*dy);
	if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
		/* The arc degenerates to a line */
		nsvg__lineTo(p, x2, y2);
		*cpx = x2;
		*cpy = y2;
		return;
	}

	sinrx = sinf(rotx);
	cosrx = cosf(rotx);

	/* Convert to center point parameterization. */
	/* http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes */
	/* 1) Compute x1', y1' */
	x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
	y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
	d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry);
	if (d > 1) {
		d = sqrtf(d);
		rx *= d;
		ry *= d;
	}
	/* 2) Compute cx', cy' */
	s = 0.0f;
	sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p);
	sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p);
	if (sa < 0.0f) sa = 0.0f;
	if (sb > 0.0f)
		s = sqrtf(sa / sb);
	if (fa == fs)
		s = -s;
	cxp = s * rx * y1p / ry;
	cyp = s * -ry * x1p / rx;

	/* 3) Compute cx,cy from cx',cy' */
	cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp;
	cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp;

	/* 4) Calculate theta1, and delta theta. */
	ux = (x1p - cxp) / rx;
	uy = (y1p - cyp) / ry;
	vx = (-x1p - cxp) / rx;
	vy = (-y1p - cyp) / ry;
	a1 = nsvg__vecang(1.0f,0.0f, ux,uy);	/* Initial angle */
	da = nsvg__vecang(ux,uy, vx,vy);		/* Delta angle */

/*	if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI; */
/*	if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; */

	if (fs == 0 && da > 0)
		da -= 2 * NSVG_PI;
	else if (fs == 1 && da < 0)
		da += 2 * NSVG_PI;

	/* Approximate the arc using cubic spline segments. */
	t[0] = cosrx; t[1] = sinrx;
	t[2] = -sinrx; t[3] = cosrx;
	t[4] = cx; t[5] = cy;

	/* Split arc into max 90 degree segments. */
	/* The loop assumes an iteration per end point (including start and end), this +1. */
	ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
	hda = (da / (float)ndivs) / 2.0f;
	/* Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite) */
	if ((hda < 1e-3f) && (hda > -1e-3f))
		hda *= 0.5f;
	else
		hda = (1.0f - cosf(hda)) / sinf(hda);
	kappa = fabsf(4.0f / 3.0f * hda);
	if (da < 0.0f)
		kappa = -kappa;

	for (i = 0; i <= ndivs; i++) {
		a = a1 + da * ((float)i/(float)ndivs);
		dx = cosf(a);
		dy = sinf(a);
		nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); /* position */
		nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); /* tangent */
		if (i > 0)
			nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y);
		px = x;
		py = y;
		ptanx = tanx;
		ptany = tany;
	}
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
		cpx = 0; cpy = 0;
		cpx2 = 0; cpy2 = 0;
		initPoint = 0;
		closedFlag = 0;
		nargs = 0;

		while (*s) {




			s = nsvg__getNextPathItem(s, item);
			if (!*item) break;
			if (cmd != '\0' && nsvg__isCoordinate(item)) {
				if (nargs < 10)
					args[nargs++] = (float)nsvg__atof(item);
				if (nargs >= rargs) {
					switch (cmd) {
						case 'm':
						case 'M':
							nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
							// Moveto can be followed by multiple coordinate pairs,
							// which should be treated as linetos.
							cmd = (cmd == 'm') ? 'l' : 'L';
							rargs = nsvg__getArgsPerElement(cmd);
							cpx2 = cpx; cpy2 = cpy;
							initPoint = 1;
							break;
						case 'l':
						case 'L':







>
>
>
>
|









|
|







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
		cpx = 0; cpy = 0;
		cpx2 = 0; cpy2 = 0;
		initPoint = 0;
		closedFlag = 0;
		nargs = 0;

		while (*s) {
			item[0] = '\0';
			if ((cmd == 'A' || cmd == 'a') && (nargs == 3 || nargs == 4))
				s = nsvg__getNextPathItemWhenArcFlag(s, item);
			if (!*item)
				s = nsvg__getNextPathItem(s, item);
			if (!*item) break;
			if (cmd != '\0' && nsvg__isCoordinate(item)) {
				if (nargs < 10)
					args[nargs++] = (float)nsvg__atof(item);
				if (nargs >= rargs) {
					switch (cmd) {
						case 'm':
						case 'M':
							nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
							/* Moveto can be followed by multiple coordinate pairs, */
							/* which should be treated as linetos. */
							cmd = (cmd == 'm') ? 'l' : 'L';
							rargs = nsvg__getArgsPerElement(cmd);
							cpx2 = cpx; cpy2 = cpy;
							initPoint = 1;
							break;
						case 'l':
						case 'L':
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
							break;
					}
					nargs = 0;
				}
			} else {
				cmd = item[0];
				if (cmd == 'M' || cmd == 'm') {
					// Commit path.
					if (p->npts > 0)
						nsvg__addPath(p, closedFlag);
					// Start new subpath.
					nsvg__resetPath(p);
					closedFlag = 0;
					nargs = 0;
				} else if (initPoint == 0) {
					// Do not allow other commands until initial point has been set (moveTo called once).
					cmd = '\0';
				}
				if (cmd == 'Z' || cmd == 'z') {
					closedFlag = 1;
					// Commit path.
					if (p->npts > 0) {
						// Move current point to first point
						cpx = p->pts[0];
						cpy = p->pts[1];
						cpx2 = cpx; cpy2 = cpy;
						nsvg__addPath(p, closedFlag);
					}
					// Start new subpath.
					nsvg__resetPath(p);
					nsvg__moveTo(p, cpx, cpy);
					closedFlag = 0;
					nargs = 0;
				}
				rargs = nsvg__getArgsPerElement(cmd);
				if (rargs == -1) {
					// Command not recognized
					cmd = '\0';
					rargs = 0;
				}
			}
		}
		// Commit path.
		if (p->npts)
			nsvg__addPath(p, closedFlag);
	}

	nsvg__addShape(p);
}

static void nsvg__parseRect(NSVGparser* p, const char** attr)
{
	float x = 0.0f;
	float y = 0.0f;
	float w = 0.0f;
	float h = 0.0f;
	float rx = -1.0f; // marks not set
	float ry = -1.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));







|


|




|




|

|





|







|





|













|







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
							break;
					}
					nargs = 0;
				}
			} else {
				cmd = item[0];
				if (cmd == 'M' || cmd == 'm') {
					/* Commit path. */
					if (p->npts > 0)
						nsvg__addPath(p, closedFlag);
					/* Start new subpath. */
					nsvg__resetPath(p);
					closedFlag = 0;
					nargs = 0;
				} else if (initPoint == 0) {
					/* Do not allow other commands until initial point has been set (moveTo called once). */
					cmd = '\0';
				}
				if (cmd == 'Z' || cmd == 'z') {
					closedFlag = 1;
					/* Commit path. */
					if (p->npts > 0) {
						/* Move current point to first point */
						cpx = p->pts[0];
						cpy = p->pts[1];
						cpx2 = cpx; cpy2 = cpy;
						nsvg__addPath(p, closedFlag);
					}
					/* Start new subpath. */
					nsvg__resetPath(p);
					nsvg__moveTo(p, cpx, cpy);
					closedFlag = 0;
					nargs = 0;
				}
				rargs = nsvg__getArgsPerElement(cmd);
				if (rargs == -1) {
					/* Command not recognized */
					cmd = '\0';
					rargs = 0;
				}
			}
		}
		/* Commit path. */
		if (p->npts)
			nsvg__addPath(p, closedFlag);
	}

	nsvg__addShape(p);
}

static void nsvg__parseRect(NSVGparser* p, const char** attr)
{
	float x = 0.0f;
	float y = 0.0f;
	float w = 0.0f;
	float h = 0.0f;
	float rx = -1.0f; /* marks not set */
	float ry = -1.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490

		if (rx < 0.00001f || ry < 0.0001f) {
			nsvg__moveTo(p, x, y);
			nsvg__lineTo(p, x+w, y);
			nsvg__lineTo(p, x+w, y+h);
			nsvg__lineTo(p, x, y+h);
		} else {
			// Rounded rectangle
			nsvg__moveTo(p, x+rx, y);
			nsvg__lineTo(p, x+w-rx, y);
			nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry);
			nsvg__lineTo(p, x+w, y+h-ry);
			nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h);
			nsvg__lineTo(p, x+rx, y+h);
			nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry);







|







2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542

		if (rx < 0.00001f || ry < 0.0001f) {
			nsvg__moveTo(p, x, y);
			nsvg__lineTo(p, x+w, y);
			nsvg__lineTo(p, x+w, y+h);
			nsvg__lineTo(p, x, y+h);
		} else {
			/* Rounded rectangle */
			nsvg__moveTo(p, x+rx, y);
			nsvg__lineTo(p, x+w-rx, y);
			nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry);
			nsvg__lineTo(p, x+w, y+h-ry);
			nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h);
			nsvg__lineTo(p, x+rx, y+h);
			nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry);
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
				p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "height") == 0) {
				p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "viewBox") == 0) {
				sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight);
			} else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
				if (strstr(attr[i + 1], "none") != 0) {
					// No uniform scaling
					p->alignType = NSVG_ALIGN_NONE;
				} else {
					// Parse X align
					if (strstr(attr[i + 1], "xMin") != 0)
						p->alignX = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "xMid") != 0)
						p->alignX = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "xMax") != 0)
						p->alignX = NSVG_ALIGN_MAX;
					// Parse X align
					if (strstr(attr[i + 1], "yMin") != 0)
						p->alignY = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "yMid") != 0)
						p->alignY = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "yMax") != 0)
						p->alignY = NSVG_ALIGN_MAX;
					// Parse meet/slice
					p->alignType = NSVG_ALIGN_MEET;
					if (strstr(attr[i + 1], "slice") != 0)
						p->alignType = NSVG_ALIGN_SLICE;
				}
			}
		}
	}
}

static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type)
{
	int i;
	NSVGgradientData* grad = (NSVGgradientData*)NANOSVG_malloc(sizeof(NSVGgradientData));
	if (grad == NULL) return;
	memset(grad, 0, sizeof(NSVGgradientData));
	grad->units = NSVG_OBJECT_SPACE;
	grad->type = type;







|


|






|






|









|







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
				p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "height") == 0) {
				p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "viewBox") == 0) {
				sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight);
			} else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
				if (strstr(attr[i + 1], "none") != 0) {
					/* No uniform scaling */
					p->alignType = NSVG_ALIGN_NONE;
				} else {
					/* Parse X align */
					if (strstr(attr[i + 1], "xMin") != 0)
						p->alignX = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "xMid") != 0)
						p->alignX = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "xMax") != 0)
						p->alignX = NSVG_ALIGN_MAX;
					/* Parse X align */
					if (strstr(attr[i + 1], "yMin") != 0)
						p->alignY = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "yMid") != 0)
						p->alignY = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "yMax") != 0)
						p->alignY = NSVG_ALIGN_MAX;
					/* Parse meet/slice */
					p->alignType = NSVG_ALIGN_MEET;
					if (strstr(attr[i + 1], "slice") != 0)
						p->alignType = NSVG_ALIGN_SLICE;
				}
			}
		}
	}
}

static void nsvg__parseGradient(NSVGparser* p, const char** attr, signed char type)
{
	int i;
	NSVGgradientData* grad = (NSVGgradientData*)NANOSVG_malloc(sizeof(NSVGgradientData));
	if (grad == NULL) return;
	memset(grad, 0, sizeof(NSVGgradientData));
	grad->units = NSVG_OBJECT_SPACE;
	grad->type = type;
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
	curAttr->stopColor = 0;
	curAttr->stopOpacity = 1.0f;

	for (i = 0; attr[i]; i += 2) {
		nsvg__parseAttr(p, attr[i], attr[i + 1]);
	}

	// Add stop to the last gradient.
	grad = p->gradients;
	if (grad == NULL) return;

	grad->nstops++;
	grad->stops = (NSVGgradientStop*)NANOSVG_realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops);
	if (grad->stops == NULL) return;

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







|







|







2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
	curAttr->stopColor = 0;
	curAttr->stopOpacity = 1.0f;

	for (i = 0; attr[i]; i += 2) {
		nsvg__parseAttr(p, attr[i], attr[i + 1]);
	}

	/* Add stop to the last gradient. */
	grad = p->gradients;
	if (grad == NULL) return;

	grad->nstops++;
	grad->stops = (NSVGgradientStop*)NANOSVG_realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops);
	if (grad->stops == NULL) return;

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

static void nsvg__startElement(void* ud, const char* el, const char** attr)
{
	NSVGparser* p = (NSVGparser*)ud;

	if (p->defsFlag) {
		// Skip everything but gradients in defs
		if (strcmp(el, "linearGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
		} else if (strcmp(el, "radialGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
		} else if (strcmp(el, "stop") == 0) {
			nsvg__parseGradientStop(p, attr);
		}
		return;
	}

	if (strcmp(el, "g") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseAttribs(p, attr);
	} else if (strcmp(el, "path") == 0) {
		if (p->pathFlag)	// Do not allow nested paths.
			return;
		nsvg__pushAttr(p);
		nsvg__parsePath(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "rect") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseRect(p, attr);







|














|







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
}

static void nsvg__startElement(void* ud, const char* el, const char** attr)
{
	NSVGparser* p = (NSVGparser*)ud;

	if (p->defsFlag) {
		/* Skip everything but gradients in defs */
		if (strcmp(el, "linearGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
		} else if (strcmp(el, "radialGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
		} else if (strcmp(el, "stop") == 0) {
			nsvg__parseGradientStop(p, attr);
		}
		return;
	}

	if (strcmp(el, "g") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseAttribs(p, attr);
	} else if (strcmp(el, "path") == 0) {
		if (p->pathFlag)	/* Do not allow nested paths. */
			return;
		nsvg__pushAttr(p);
		nsvg__parsePath(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "rect") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseRect(p, attr);
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959

static float nsvg__viewAlign(float content, float container, int type)
{
	if (type == NSVG_ALIGN_MIN)
		return 0;
	else if (type == NSVG_ALIGN_MAX)
		return container - content;
	// mid
	return (container - content) * 0.5f;
}

static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy)
{
	float t[6];
	nsvg__xformSetTranslation(t, tx, ty);







|







2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011

static float nsvg__viewAlign(float content, float container, int type)
{
	if (type == NSVG_ALIGN_MIN)
		return 0;
	else if (type == NSVG_ALIGN_MAX)
		return container - content;
	/* mid */
	return (container - content) * 0.5f;
}

static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy)
{
	float t[6];
	nsvg__xformSetTranslation(t, tx, ty);
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
{
	NSVGshape* shape;
	NSVGpath* path;
	float tx, ty, sx, sy, us, bounds[4], t[6], avgs;
	int i;
	float* pt;

	// Guess image size if not set completely.
	nsvg__imageBounds(p, bounds);

	if (p->viewWidth == 0) {
		if (p->image->width > 0) {
			p->viewWidth = p->image->width;
		} else {
			p->viewMinx = bounds[0];







|







3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
{
	NSVGshape* shape;
	NSVGpath* path;
	float tx, ty, sx, sy, us, bounds[4], t[6], avgs;
	int i;
	float* pt;

	/* Guess image size if not set completely. */
	nsvg__imageBounds(p, bounds);

	if (p->viewWidth == 0) {
		if (p->image->width > 0) {
			p->viewWidth = p->image->width;
		} else {
			p->viewMinx = bounds[0];
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
	if (p->image->height == 0)
		p->image->height = p->viewHeight;

	tx = -p->viewMinx;
	ty = -p->viewMiny;
	sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
	sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
	// Unit scaling
	us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);

	// Fix aspect ratio
	if (p->alignType == NSVG_ALIGN_MEET) {
		// fit whole image into viewbox
		sx = sy = nsvg__minf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	} else if (p->alignType == NSVG_ALIGN_SLICE) {
		// fill whole viewbox with image
		sx = sy = nsvg__maxf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	}

	// Transform
	sx *= us;
	sy *= us;
	avgs = (sx+sy) / 2.0f;
	for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
		shape->bounds[0] = (shape->bounds[0] + tx) * sx;
		shape->bounds[1] = (shape->bounds[1] + ty) * sy;
		shape->bounds[2] = (shape->bounds[2] + tx) * sx;







|


|

|




|





|







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
	if (p->image->height == 0)
		p->image->height = p->viewHeight;

	tx = -p->viewMinx;
	ty = -p->viewMiny;
	sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
	sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
	/* Unit scaling */
	us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);

	/* Fix aspect ratio */
	if (p->alignType == NSVG_ALIGN_MEET) {
		/* fit whole image into viewbox */
		sx = sy = nsvg__minf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	} else if (p->alignType == NSVG_ALIGN_SLICE) {
		/* fill whole viewbox with image */
		sx = sy = nsvg__maxf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	}

	/* Transform */
	sx *= us;
	sy *= us;
	avgs = (sx+sy) / 2.0f;
	for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
		shape->bounds[0] = (shape->bounds[0] + tx) * sx;
		shape->bounds[1] = (shape->bounds[1] + ty) * sy;
		shape->bounds[2] = (shape->bounds[2] + tx) * sx;
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

		shape->strokeWidth *= avgs;
		shape->strokeDashOffset *= avgs;
		for (i = 0; i < shape->strokeDashCount; i++)
			shape->strokeDashArray[i] *= avgs;
	}
}































NANOSVG_SCOPE
NSVGimage* nsvgParse(char* input, const char* units, float dpi)
{
	NSVGparser* p;
	NSVGimage* ret = 0;

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

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




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

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

	nsvg__deleteParser(p);








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















>
>
>
|







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

		shape->strokeWidth *= avgs;
		shape->strokeDashOffset *= avgs;
		for (i = 0; i < shape->strokeDashCount; i++)
			shape->strokeDashArray[i] *= avgs;
	}
}

static void nsvg__createGradients(NSVGparser* p)
{
	NSVGshape* shape;

	for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
		if (shape->fill.type == NSVG_PAINT_UNDEF) {
			if (shape->fillGradient[0] != '\0') {
				float inv[6], localBounds[4];
				nsvg__xformInverse(inv, shape->xform);
				nsvg__getLocalBounds(localBounds, shape, inv);
				shape->fill.gradient = nsvg__createGradient(p, shape->fillGradient, localBounds, shape->xform, &shape->fill.type);
			}
			if (shape->fill.type == NSVG_PAINT_UNDEF) {
				shape->fill.type = NSVG_PAINT_NONE;
			}
		}
		if (shape->stroke.type == NSVG_PAINT_UNDEF) {
			if (shape->strokeGradient[0] != '\0') {
				float inv[6], localBounds[4];
				nsvg__xformInverse(inv, shape->xform);
				nsvg__getLocalBounds(localBounds, shape, inv);
				shape->stroke.gradient = nsvg__createGradient(p, shape->strokeGradient, localBounds, shape->xform, &shape->stroke.type);
			}
			if (shape->stroke.type == NSVG_PAINT_UNDEF) {
				shape->stroke.type = NSVG_PAINT_NONE;
			}
		}
	}
}

NANOSVG_SCOPE
NSVGimage* nsvgParse(char* input, const char* units, float dpi)
{
	NSVGparser* p;
	NSVGimage* ret = 0;

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

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

	// Create gradients after all definitions have been parsed
	nsvg__createGradients(p);

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

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

	nsvg__deleteParser(p);

3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
	if (!fp) goto error;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	data = (char*)NANOSVG_malloc(size+1);
	if (data == NULL) goto error;
	if (fread(data, 1, size, fp) != size) goto error;
	data[size] = '\0';	// Must be null terminated.
	fclose(fp);
	image = nsvgParse(data, units, dpi);
	NANOSVG_free(data);

	return image;

error:







|







3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
	if (!fp) goto error;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	data = (char*)NANOSVG_malloc(size+1);
	if (data == NULL) goto error;
	if (fread(data, 1, size, fp) != size) goto error;
	data[size] = '\0';	/* Must be null terminated. */
	fclose(fp);
	image = nsvgParse(data, units, dpi);
	NANOSVG_free(data);

	return image;

error:
3123
3124
3125
3126
3127
3128
3129


		NANOSVG_free(shape);
		shape = snext;
	}
	NANOSVG_free(image);
}

#endif









>
>
3208
3209
3210
3211
3212
3213
3214
3215
3216
		NANOSVG_free(shape);
		shape = snext;
	}
	NANOSVG_free(image);
}

#endif

#endif /* NANOSVG_H */

Changes to generic/nanosvgrast.h.

21
22
23
24
25
26
27


28
29
30
31
32
33
34
 * by Sean Barrett - http://nothings.org/
 *
 */

#ifndef NANOSVGRAST_H
#define NANOSVGRAST_H



#ifdef __cplusplus
extern "C" {
#endif

#ifndef NANOSVG_SCOPE
#define NANOSVG_SCOPE
#endif







>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 * by Sean Barrett - http://nothings.org/
 *
 */

#ifndef NANOSVGRAST_H
#define NANOSVGRAST_H

#include "nanosvg.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef NANOSVG_SCOPE
#define NANOSVG_SCOPE
#endif
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

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


91
92
93
94
95
96
97
	struct NSVGrasterizer* rast = nsvgCreateRasterizer();
	// Allocate memory for image
	unsigned char* img = malloc(w*h*4);
	// Rasterize
	nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4);
*/

// Allocated rasterizer context.
NANOSVG_SCOPE NSVGrasterizer* nsvgCreateRasterizer(void);

// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha)
//   r - pointer to rasterizer context
//   image - pointer to image to rasterize
//   tx,ty - image offset (applied after scaling)
//   scale - image scale
//   dst - pointer to destination image data, 4 bytes per pixel (RGBA)
//   w - width of the image to render
//   h - height of the image to render
//   stride - number of bytes per scaleline in the destination buffer

NANOSVG_SCOPE void nsvgRasterize(NSVGrasterizer* r,
				   NSVGimage* image, float tx, float ty, float scale,
				   unsigned char* dst, int w, int h, int stride);

// Deletes rasterizer context.
NANOSVG_SCOPE void nsvgDeleteRasterizer(NSVGrasterizer*);


#ifdef __cplusplus
}
#endif

#endif // NANOSVGRAST_H

#ifdef NANOSVGRAST_IMPLEMENTATION

#include <math.h>



#define NSVG__SUBSAMPLES	5
#define NSVG__FIXSHIFT		10
#define NSVG__FIX			(1 << NSVG__FIXSHIFT)
#define NSVG__FIXMASK		(NSVG__FIX-1)
#define NSVG__MEMPAGE_SIZE	1024








|


|
|
|
|
|
|
|
|
|
>




|







<
<



>
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97
98
99
100
	struct NSVGrasterizer* rast = nsvgCreateRasterizer();
	// Allocate memory for image
	unsigned char* img = malloc(w*h*4);
	// Rasterize
	nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4);
*/

/* Allocated rasterizer context. */
NANOSVG_SCOPE NSVGrasterizer* nsvgCreateRasterizer(void);

/* Rasterizes SVG image, returns RGBA image (non-premultiplied alpha)
 *   r - pointer to rasterizer context
 *   image - pointer to image to rasterize
 *   tx,ty - image offset (applied after scaling)
 *   scale - image scale
 *   dst - pointer to destination image data, 4 bytes per pixel (RGBA)
 *   w - width of the image to render
 *   h - height of the image to render
 *   stride - number of bytes per scaleline in the destination buffer
 */
NANOSVG_SCOPE void nsvgRasterize(NSVGrasterizer* r,
				   NSVGimage* image, float tx, float ty, float scale,
				   unsigned char* dst, int w, int h, int stride);

/* Deletes rasterizer context. */
NANOSVG_SCOPE void nsvgDeleteRasterizer(NSVGrasterizer*);


#ifdef __cplusplus
}
#endif



#ifdef NANOSVGRAST_IMPLEMENTATION

#include <math.h>
#include <stdlib.h>
#include <string.h>

#define NSVG__SUBSAMPLES	5
#define NSVG__FIXSHIFT		10
#define NSVG__FIX			(1 << NSVG__FIXSHIFT)
#define NSVG__FIXMASK		(NSVG__FIX-1)
#define NSVG__MEMPAGE_SIZE	1024

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
typedef struct NSVGmemPage {
	unsigned char mem[NSVG__MEMPAGE_SIZE];
	int size;
	struct NSVGmemPage* next;
} NSVGmemPage;

typedef struct NSVGcachedPaint {
	char type;
	char spread;
	float xform[6];
	unsigned int colors[256];
} NSVGcachedPaint;

struct NSVGrasterizer
{







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
typedef struct NSVGmemPage {
	unsigned char mem[NSVG__MEMPAGE_SIZE];
	int size;
	struct NSVGmemPage* next;
} NSVGmemPage;

typedef struct NSVGcachedPaint {
	signed char type;
	char spread;
	float xform[6];
	unsigned int colors[256];
} NSVGcachedPaint;

struct NSVGrasterizer
{
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	NANOSVG_free(r);
}

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

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

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

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

	return newp;
}







|




|




|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
	NANOSVG_free(r);
}

static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur)
{
	NSVGmemPage *newp;

	/* If using existing chain, return the next page in chain */
	if (cur != NULL && cur->next != NULL) {
		return cur->next;
	}

	/* Alloc new page */
	newp = (NSVGmemPage*)NANOSVG_malloc(sizeof(NSVGmemPage));
	if (newp == NULL) return NULL;
	memset(newp, 0, sizeof(NSVGmemPage));

	/* Add to linked list */
	if (cur != NULL)
		cur->next = newp;
	else
		r->pages = newp;

	return newp;
}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
	r->npoints2 = r->npoints;
}

static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1)
{
	NSVGedge* e;

	// Skip horizontal edges
	if (y0 == y1)
		return;

	if (r->nedges+1 > r->cedges) {
		r->cedges = r->cedges > 0 ? r->cedges * 2 : 64;
		r->edges = (NSVGedge*)NANOSVG_realloc(r->edges, sizeof(NSVGedge) * r->cedges);
		if (r->edges == NULL) return;







|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
	r->npoints2 = r->npoints;
}

static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1)
{
	NSVGedge* e;

	/* Skip horizontal edges */
	if (y0 == y1)
		return;

	if (r->nedges+1 > r->cedges) {
		r->cedges = r->cedges > 0 ? r->cedges * 2 : 64;
		r->edges = (NSVGedge*)NANOSVG_realloc(r->edges, sizeof(NSVGedge) * r->cedges);
		if (r->edges == NULL) return;
338
339
340
341
342
343
344

345
346
347
348
349
350
351
		*x *= id;
		*y *= id;
	}
	return d;
}

static float nsvg__absf(float x) { return x < 0 ? -x : x; }


static void nsvg__flattenCubicBez(NSVGrasterizer* r,
								  float x1, float y1, float x2, float y2,
								  float x3, float y3, float x4, float y4,
								  int level, int type)
{
	float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234;







>







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
		*x *= id;
		*y *= id;
	}
	return d;
}

static float nsvg__absf(float x) { return x < 0 ? -x : x; }
static float nsvg__roundf(float x) { return (x >= 0) ? floorf(x + 0.5) : ceilf(x - 0.5); }

static void nsvg__flattenCubicBez(NSVGrasterizer* r,
								  float x1, float y1, float x2, float y2,
								  float x3, float y3, float x4, float y4,
								  int level, int type)
{
	float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234;
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
	x34 = (x3+x4)*0.5f;
	y34 = (y3+y4)*0.5f;
	x123 = (x12+x23)*0.5f;
	y123 = (y12+y23)*0.5f;

	dx = x4 - x1;
	dy = y4 - y1;
	d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx));
	d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx));

	if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) {
		nsvg__addPathPoint(r, x4, y4, type);
		return;
	}

	x234 = (x23+x34)*0.5f;







|
|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
	x34 = (x3+x4)*0.5f;
	y34 = (y3+y4)*0.5f;
	x123 = (x12+x23)*0.5f;
	y123 = (y12+y23)*0.5f;

	dx = x4 - x1;
	dy = y4 - y1;
	d2 = nsvg__absf((x2 - x4) * dy - (y2 - y4) * dx);
	d3 = nsvg__absf((x3 - x4) * dy - (y3 - y4) * dx);

	if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) {
		nsvg__addPathPoint(r, x4, y4, type);
		return;
	}

	x234 = (x23+x34)*0.5f;
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
	int i, j;
	NSVGpath* path;

	for (path = shape->paths; path != NULL; path = path->next) {
		r->npoints = 0;
		// Flatten path
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
		}
		// Close path
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		// Build edges
		for (i = 0, j = r->npoints-1; i < r->npoints; j = i++)
			nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y);
	}
}

enum NSVGpointFlags
{







|





|

|







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
	int i, j;
	NSVGpath* path;

	for (path = shape->paths; path != NULL; path = path->next) {
		r->npoints = 0;
		/* Flatten path */
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
		}
		/* Close path */
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		/* Build edges */
		for (i = 0, j = r->npoints-1; i < r->npoints; j = i++)
			nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y);
	}
}

enum NSVGpointFlags
{
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
	int divs = (int)ceilf(arc / da);
	if (divs < 2) divs = 2;
	return divs;
}

static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth)
{
	int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol);	// Calculate divisions per half circle.
	NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0};
	NSVGpoint* p0, *p1;
	int j, s, e;

	// Build stroke edges
	if (closed) {
		// Looping
		p0 = &points[npoints-1];
		p1 = &points[0];
		s = 0;
		e = npoints;
	} else {
		// Add cap
		p0 = &points[0];
		p1 = &points[1];
		s = 1;
		e = npoints-1;
	}

	if (closed) {
		nsvg__initClosed(&left, &right, p0, p1, lineWidth);
		firstLeft = left;
		firstRight = right;
	} else {
		// Add cap
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0);







|




|

|





|











|







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
	int divs = (int)ceilf(arc / da);
	if (divs < 2) divs = 2;
	return divs;
}

static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth)
{
	int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol);	/* Calculate divisions per half circle. */
	NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0};
	NSVGpoint* p0, *p1;
	int j, s, e;

	/* Build stroke edges */
	if (closed) {
		/* Looping */
		p0 = &points[npoints-1];
		p1 = &points[0];
		s = 0;
		e = npoints;
	} else {
		/* Add cap */
		p0 = &points[0];
		p1 = &points[1];
		s = 1;
		e = npoints-1;
	}

	if (closed) {
		nsvg__initClosed(&left, &right, p0, p1, lineWidth);
		firstLeft = left;
		firstRight = right;
	} else {
		/* Add cap */
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
		} else {
			nsvg__straightJoin(r, &left, &right, p1, lineWidth);
		}
		p0 = p1++;
	}

	if (closed) {
		// Loop it
		nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y);
		nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y);
	} else {
		// Add cap
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_ROUND)
			nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1);
	}
}

static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin)
{
	int i, j;
	NSVGpoint* p0, *p1;

	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (i = 0; i < r->npoints; i++) {
		// Calculate segment direction and length
		p0->dx = p1->x - p0->x;
		p0->dy = p1->y - p0->y;
		p0->len = nsvg__normalize(&p0->dx, &p0->dy);
		// Advance
		p0 = p1++;
	}

	// calculate joins
	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (j = 0; j < r->npoints; j++) {
		float dlx0, dly0, dlx1, dly1, dmr2, cross;
		dlx0 = p0->dy;
		dly0 = -p0->dx;
		dlx1 = p1->dy;
		dly1 = -p1->dx;
		// Calculate extrusions
		p1->dmx = (dlx0 + dlx1) * 0.5f;
		p1->dmy = (dly0 + dly1) * 0.5f;
		dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy;
		if (dmr2 > 0.000001f) {
			float s2 = 1.0f / dmr2;
			if (s2 > 600.0f) {
				s2 = 600.0f;
			}
			p1->dmx *= s2;
			p1->dmy *= s2;
		}

		// Clear flags, but keep the corner.
		p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0;

		// Keep track of left turns.
		cross = p1->dx * p0->dy - p0->dx * p1->dy;
		if (cross > 0.0f)
			p1->flags |= NSVG_PT_LEFT;

		// Check to see if the corner needs to be beveled.
		if (p1->flags & NSVG_PT_CORNER) {
			if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) {
				p1->flags |= NSVG_PT_BEVEL;
			}
		}

		p0 = p1++;







|



|




















|



|



|








|












|


|




|







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
		} else {
			nsvg__straightJoin(r, &left, &right, p1, lineWidth);
		}
		p0 = p1++;
	}

	if (closed) {
		/* Loop it */
		nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y);
		nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y);
	} else {
		/* Add cap */
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_ROUND)
			nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1);
	}
}

static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin)
{
	int i, j;
	NSVGpoint* p0, *p1;

	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (i = 0; i < r->npoints; i++) {
		/* Calculate segment direction and length */
		p0->dx = p1->x - p0->x;
		p0->dy = p1->y - p0->y;
		p0->len = nsvg__normalize(&p0->dx, &p0->dy);
		/* Advance */
		p0 = p1++;
	}

	/* calculate joins */
	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (j = 0; j < r->npoints; j++) {
		float dlx0, dly0, dlx1, dly1, dmr2, cross;
		dlx0 = p0->dy;
		dly0 = -p0->dx;
		dlx1 = p1->dy;
		dly1 = -p1->dx;
		/* Calculate extrusions */
		p1->dmx = (dlx0 + dlx1) * 0.5f;
		p1->dmy = (dly0 + dly1) * 0.5f;
		dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy;
		if (dmr2 > 0.000001f) {
			float s2 = 1.0f / dmr2;
			if (s2 > 600.0f) {
				s2 = 600.0f;
			}
			p1->dmx *= s2;
			p1->dmy *= s2;
		}

		/* Clear flags, but keep the corner. */
		p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0;

		/* Keep track of left turns. */
		cross = p1->dx * p0->dy - p0->dx * p1->dy;
		if (cross > 0.0f)
			p1->flags |= NSVG_PT_LEFT;

		/* Check to see if the corner needs to be beveled. */
		if (p1->flags & NSVG_PT_CORNER) {
			if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) {
				p1->flags |= NSVG_PT_BEVEL;
			}
		}

		p0 = p1++;
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	NSVGpoint* p0, *p1;
	float miterLimit = shape->miterLimit;
	int lineJoin = shape->strokeLineJoin;
	int lineCap = shape->strokeLineCap;
	float lineWidth = shape->strokeWidth * scale;

	for (path = shape->paths; path != NULL; path = path->next) {
		// Flatten path
		r->npoints = 0;
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
		}
		if (r->npoints < 2)
			continue;

		closed = path->closed;

		// If the first and last points are the same, remove the last, mark as closed path.
		p0 = &r->points[r->npoints-1];
		p1 = &r->points[0];
		if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) {
			r->npoints--;
			p0 = &r->points[r->npoints-1];
			closed = 1;
		}

		if (shape->strokeDashCount > 0) {
			int idash = 0, dashState = 1;
			float totalDist = 0, dashLen, allDashLen, dashOffset;
			NSVGpoint cur;

			if (closed)
				nsvg__appendPathPoint(r, r->points[0]);

			// Duplicate points -> points2.
			nsvg__duplicatePoints(r);

			r->npoints = 0;
 			cur = r->points2[0];
			nsvg__appendPathPoint(r, cur);

			// Figure out dash offset.
			allDashLen = 0;
			for (j = 0; j < shape->strokeDashCount; j++)
				allDashLen += shape->strokeDashArray[j];
			if (shape->strokeDashCount & 1)
				allDashLen *= 2.0f;
			// Find location inside pattern
			dashOffset = fmodf(shape->strokeDashOffset, allDashLen);
			if (dashOffset < 0.0f)
				dashOffset += allDashLen;

			while (dashOffset > shape->strokeDashArray[idash]) {
				dashOffset -= shape->strokeDashArray[idash];
				idash = (idash + 1) % shape->strokeDashCount;
			}
			dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;

			for (j = 1; j < r->npoints2; ) {
				float dx = r->points2[j].x - cur.x;
				float dy = r->points2[j].y - cur.y;
				float dist = sqrtf(dx*dx + dy*dy);

				if ((totalDist + dist) > dashLen) {
					// Calculate intermediate point
					float d = (dashLen - totalDist) / dist;
					float x = cur.x + dx * d;
					float y = cur.y + dy * d;
					nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER);

					// Stroke
					if (r->npoints > 1 && dashState) {
						nsvg__prepareStroke(r, miterLimit, lineJoin);
						nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
					}
					// Advance dash pattern
					dashState = !dashState;
					idash = (idash+1) % shape->strokeDashCount;
					dashLen = shape->strokeDashArray[idash] * scale;
					// Restart
					cur.x = x;
					cur.y = y;
					cur.flags = NSVG_PT_CORNER;
					totalDist = 0.0f;
					r->npoints = 0;
					nsvg__appendPathPoint(r, cur);
				} else {
					totalDist += dist;
					cur = r->points2[j];
					nsvg__appendPathPoint(r, cur);
					j++;
				}
			}
			// Stroke any leftover path
			if (r->npoints > 1 && dashState)
				nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
		} else {
			nsvg__prepareStroke(r, miterLimit, lineJoin);
			nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth);
		}
	}







|











|
















|






|





|
















|





|




|



|













|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	NSVGpoint* p0, *p1;
	float miterLimit = shape->miterLimit;
	int lineJoin = shape->strokeLineJoin;
	int lineCap = shape->strokeLineCap;
	float lineWidth = shape->strokeWidth * scale;

	for (path = shape->paths; path != NULL; path = path->next) {
		/* Flatten path */
		r->npoints = 0;
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
		}
		if (r->npoints < 2)
			continue;

		closed = path->closed;

		/* If the first and last points are the same, remove the last, mark as closed path. */
		p0 = &r->points[r->npoints-1];
		p1 = &r->points[0];
		if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) {
			r->npoints--;
			p0 = &r->points[r->npoints-1];
			closed = 1;
		}

		if (shape->strokeDashCount > 0) {
			int idash = 0, dashState = 1;
			float totalDist = 0, dashLen, allDashLen, dashOffset;
			NSVGpoint cur;

			if (closed)
				nsvg__appendPathPoint(r, r->points[0]);

			/* Duplicate points -> points2. */
			nsvg__duplicatePoints(r);

			r->npoints = 0;
 			cur = r->points2[0];
			nsvg__appendPathPoint(r, cur);

			/* Figure out dash offset. */
			allDashLen = 0;
			for (j = 0; j < shape->strokeDashCount; j++)
				allDashLen += shape->strokeDashArray[j];
			if (shape->strokeDashCount & 1)
				allDashLen *= 2.0f;
			/* Find location inside pattern */
			dashOffset = fmodf(shape->strokeDashOffset, allDashLen);
			if (dashOffset < 0.0f)
				dashOffset += allDashLen;

			while (dashOffset > shape->strokeDashArray[idash]) {
				dashOffset -= shape->strokeDashArray[idash];
				idash = (idash + 1) % shape->strokeDashCount;
			}
			dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;

			for (j = 1; j < r->npoints2; ) {
				float dx = r->points2[j].x - cur.x;
				float dy = r->points2[j].y - cur.y;
				float dist = sqrtf(dx*dx + dy*dy);

				if ((totalDist + dist) > dashLen) {
					/* Calculate intermediate point */
					float d = (dashLen - totalDist) / dist;
					float x = cur.x + dx * d;
					float y = cur.y + dy * d;
					nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER);

					/* Stroke */
					if (r->npoints > 1 && dashState) {
						nsvg__prepareStroke(r, miterLimit, lineJoin);
						nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
					}
					/* Advance dash pattern */
					dashState = !dashState;
					idash = (idash+1) % shape->strokeDashCount;
					dashLen = shape->strokeDashArray[idash] * scale;
					/* Restart */
					cur.x = x;
					cur.y = y;
					cur.flags = NSVG_PT_CORNER;
					totalDist = 0.0f;
					r->npoints = 0;
					nsvg__appendPathPoint(r, cur);
				} else {
					totalDist += dist;
					cur = r->points2[j];
					nsvg__appendPathPoint(r, cur);
					j++;
				}
			}
			/* Stroke any leftover path */
			if (r->npoints > 1 && dashState)
				nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
		} else {
			nsvg__prepareStroke(r, miterLimit, lineJoin);
			nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth);
		}
	}
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898

static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint)
{
	 NSVGactiveEdge* z;
	float dxdy;

	if (r->freelist != NULL) {
		// Restore from freelist.
		z = r->freelist;
		r->freelist = z->next;
	} else {
		// Alloc new edge.
		z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge));
		if (z == NULL) return NULL;
	}

	dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
//	STBTT_assert(e->y0 <= start_point);
	// round dx down to avoid going too far
	if (dxdy < 0)
		z->dx = (int)(-floorf(NSVG__FIX * -dxdy));
	else
		z->dx = (int)floorf(NSVG__FIX * dxdy);
	z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0)));
//	z->x -= off_x * FIX;
	z->ey = e->y1;
	z->next = 0;
	z->dir = e->dir;

	return z;
}








|



|





|
|

|

|
|
|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint)
{
	 NSVGactiveEdge* z;
	float dxdy;

	if (r->freelist != NULL) {
		/* Restore from freelist. */
		z = r->freelist;
		r->freelist = z->next;
	} else {
		/* Alloc new edge. */
		z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge));
		if (z == NULL) return NULL;
	}

	dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
/*	STBTT_assert(e->y0 <= start_point); */
	/* round dx down to avoid going too far */
	if (dxdy < 0)
		z->dx = (int)(-nsvg__roundf(NSVG__FIX * -dxdy));
	else
		z->dx = (int)nsvg__roundf(NSVG__FIX * dxdy);
	z->x = (int)nsvg__roundf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0)));
/*	z->x -= off_x * FIX; */
	z->ey = e->y1;
	z->next = 0;
	z->dir = e->dir;

	return z;
}

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
{
	int i = x0 >> NSVG__FIXSHIFT;
	int j = x1 >> NSVG__FIXSHIFT;
	if (i < *xmin) *xmin = i;
	if (j > *xmax) *xmax = j;
	if (i < len && j >= 0) {
		if (i == j) {
			// x0,x1 are the same pixel, so compute combined coverage
			scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT));
		} else {
			if (i >= 0) // add antialiasing for x0
				scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT));
			else
				i = -1; // clip

			if (j < len) // add antialiasing for x1
				scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT));
			else
				j = len; // clip

			for (++i; i < j; ++i) // fill pixels between x0 and x1
				scanline[i] = (unsigned char)(scanline[i] + maxWeight);
		}
	}
}

// note: this routine clips fills that extend off the edges... ideally this
// wouldn't happen, but it could happen if the truetype glyph bounding boxes
// are wrong, or if the user supplies a too-small bitmap

static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule)
{
	// non-zero winding fill
	int x0 = 0, w = 0;

	if (fillRule == NSVG_FILLRULE_NONZERO) {
		// Non-zero
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				x0 = e->x; w += e->dir;
			} else {
				int x1 = e->x; w += e->dir;
				// if we went to zero, we need to draw
				if (w == 0)
					nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	} else if (fillRule == NSVG_FILLRULE_EVENODD) {
		// Even-odd
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				x0 = e->x; w = 1;
			} else {
				int x1 = e->x; w = 0;
				nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	}
}

static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); }

static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
	return (r) | (g << 8) | (b << 16) | (a << 24);
}

static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u)
{
	int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
	int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8;
	int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8;







|


|


|

|


|

|





|
|
|
>


|



|


|



|






|


|














|







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
{
	int i = x0 >> NSVG__FIXSHIFT;
	int j = x1 >> NSVG__FIXSHIFT;
	if (i < *xmin) *xmin = i;
	if (j > *xmax) *xmax = j;
	if (i < len && j >= 0) {
		if (i == j) {
			/* x0,x1 are the same pixel, so compute combined coverage */
			scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT));
		} else {
			if (i >= 0) /* add antialiasing for x0 */
				scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT));
			else
				i = -1; /* clip */

			if (j < len) /* add antialiasing for x1 */
				scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT));
			else
				j = len; /* clip */

			for (++i; i < j; ++i) /* fill pixels between x0 and x1 */
				scanline[i] = (unsigned char)(scanline[i] + maxWeight);
		}
	}
}

/* note: this routine clips fills that extend off the edges... ideally this
 * wouldn't happen, but it could happen if the truetype glyph bounding boxes
 * are wrong, or if the user supplies a too-small bitmap
 */
static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule)
{
	/* non-zero winding fill */
	int x0 = 0, w = 0;

	if (fillRule == NSVG_FILLRULE_NONZERO) {
		/* Non-zero */
		while (e != NULL) {
			if (w == 0) {
				/* if we're currently at zero, we need to record the edge start point */
				x0 = e->x; w += e->dir;
			} else {
				int x1 = e->x; w += e->dir;
				/* if we went to zero, we need to draw */
				if (w == 0)
					nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	} else if (fillRule == NSVG_FILLRULE_EVENODD) {
		/* Even-odd */
		while (e != NULL) {
			if (w == 0) {
				/* if we're currently at zero, we need to record the edge start point */
				x0 = e->x; w = 1;
			} else {
				int x1 = e->x; w = 0;
				nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	}
}

static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); }

static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
	return ((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24);
}

static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u)
{
	int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
	int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8;
	int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8;
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
		cb = (cache->colors[0] >> 16) & 0xff;
		ca = (cache->colors[0] >> 24) & 0xff;

		for (i = 0; i < count; i++) {
			int r,g,b;
			int a = nsvg__div255((int)cover[0] * ca);
			int ia = 255 - a;
			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
		}
	} else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) {
		// TODO: spread modes.
		// TODO: plenty of opportunities to optimize.
		float fx, fy, dx, gy;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;







|




|














|
|







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
		cb = (cache->colors[0] >> 16) & 0xff;
		ca = (cache->colors[0] >> 24) & 0xff;

		for (i = 0; i < count; i++) {
			int r,g,b;
			int a = nsvg__div255((int)cover[0] * ca);
			int ia = 255 - a;
			/* Premultiply */
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			/* Blend over */
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
		}
	} else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) {
		/* TODO: spread modes. */
		/* TODO: plenty of opportunities to optimize. */
		float fx, fy, dx, gy;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;
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
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
			fx += dx;
		}
	} else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) {
		// TODO: spread modes.
		// TODO: plenty of opportunities to optimize.
		// TODO: focus (fx,fy)
		float fx, fy, dx, gx, gy, gd;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;







|




|















|
|
|







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
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			/* Premultiply */
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			/* Blend over */
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
			fx += dx;
		}
	} else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) {
		/* TODO: spread modes. */
		/* TODO: plenty of opportunities to optimize. */
		/* TODO: focus (fx,fy) */
		float fx, fy, dx, gx, gy, gd;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;







|




|







1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

			a = nsvg__div255((int)cover[0] * ca);
			ia = 255 - a;

			/* Premultiply */
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			/* Blend over */
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
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
}

static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
{
	NSVGactiveEdge *active = NULL;
	int y, s;
	int e = 0;
	int maxWeight = (255 / NSVG__SUBSAMPLES);  // weight per vertical scanline
	int xmin, xmax;

	for (y = 0; y < r->height; y++) {
		memset(r->scanline, 0, r->width);
		xmin = r->width;
		xmax = 0;
		for (s = 0; s < NSVG__SUBSAMPLES; ++s) {
			// find center of pixel for this scanline
			float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f;
			NSVGactiveEdge **step = &active;

			// update all active edges;
			// remove all active edges that terminate before the center of this scanline
			while (*step) {
				NSVGactiveEdge *z = *step;
				if (z->ey <= scany) {
					*step = z->next; // delete from list
//					NSVG__assert(z->valid);
					nsvg__freeActive(r, z);
				} else {
					z->x += z->dx; // advance to position for current scanline
					step = &((*step)->next); // advance through list
				}
			}

			// resort the list if needed
			for (;;) {
				int changed = 0;
				step = &active;
				while (*step && (*step)->next) {
					if ((*step)->x > (*step)->next->x) {
						NSVGactiveEdge* t = *step;
						NSVGactiveEdge* q = t->next;
						t->next = q->next;
						q->next = t;
						*step = q;
						changed = 1;
					}
					step = &(*step)->next;
				}
				if (!changed) break;
			}

			// insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
			while (e < r->nedges && r->edges[e].y0 <= scany) {
				if (r->edges[e].y1 > scany) {
					NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany);
					if (z == NULL) break;
					// find insertion point
					if (active == NULL) {
						active = z;
					} else if (z->x < active->x) {
						// insert at front
						z->next = active;
						active = z;
					} else {
						// find thing to insert AFTER
						NSVGactiveEdge* p = active;
						while (p->next && p->next->x < z->x)
							p = p->next;
						// at this point, p->next->x is NOT < z->x
						z->next = p->next;
						p->next = z;
					}
				}
				e++;
			}

			// now process all active edges in non-zero fashion
			if (active != NULL)
				nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
		}
		// Blit
		if (xmin < 0) xmin = 0;
		if (xmax > r->width-1) xmax = r->width-1;
		if (xmin <= xmax) {
			nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
		}
	}

}

static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride)
{
	int x,y;

	// Unpremultiply
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = row[0], g = row[1], b = row[2], a = row[3];
			if (a != 0) {
				row[0] = (unsigned char)(r*255/a);
				row[1] = (unsigned char)(g*255/a);
				row[2] = (unsigned char)(b*255/a);
			}
			row += 4;
		}
	}

	// Defringe
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = 0, g = 0, b = 0, a = row[3], n = 0;
			if (a == 0) {
				if (x-1 > 0 && row[-1] != 0) {
					r += row[-4];







|







|



|
|



|
|


|
|



|

















|




|



|



|



|







|



|













|













|







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
}

static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
{
	NSVGactiveEdge *active = NULL;
	int y, s;
	int e = 0;
	int maxWeight = (255 / NSVG__SUBSAMPLES);  /* weight per vertical scanline */
	int xmin, xmax;

	for (y = 0; y < r->height; y++) {
		memset(r->scanline, 0, r->width);
		xmin = r->width;
		xmax = 0;
		for (s = 0; s < NSVG__SUBSAMPLES; ++s) {
			/* find center of pixel for this scanline */
			float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f;
			NSVGactiveEdge **step = &active;

			/* update all active edges; */
			/* remove all active edges that terminate before the center of this scanline */
			while (*step) {
				NSVGactiveEdge *z = *step;
				if (z->ey <= scany) {
					*step = z->next; /* delete from list */
/*					NSVG__assert(z->valid); */
					nsvg__freeActive(r, z);
				} else {
					z->x += z->dx; /* advance to position for current scanline */
					step = &((*step)->next); /* advance through list */
				}
			}

			/* resort the list if needed */
			for (;;) {
				int changed = 0;
				step = &active;
				while (*step && (*step)->next) {
					if ((*step)->x > (*step)->next->x) {
						NSVGactiveEdge* t = *step;
						NSVGactiveEdge* q = t->next;
						t->next = q->next;
						q->next = t;
						*step = q;
						changed = 1;
					}
					step = &(*step)->next;
				}
				if (!changed) break;
			}

			/* insert all edges that start before the center of this scanline -- omit ones that also end on this scanline */
			while (e < r->nedges && r->edges[e].y0 <= scany) {
				if (r->edges[e].y1 > scany) {
					NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany);
					if (z == NULL) break;
					/* find insertion point */
					if (active == NULL) {
						active = z;
					} else if (z->x < active->x) {
						/* insert at front */
						z->next = active;
						active = z;
					} else {
						/* find thing to insert AFTER */
						NSVGactiveEdge* p = active;
						while (p->next && p->next->x < z->x)
							p = p->next;
						/* at this point, p->next->x is NOT < z->x */
						z->next = p->next;
						p->next = z;
					}
				}
				e++;
			}

			/* now process all active edges in non-zero fashion */
			if (active != NULL)
				nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
		}
		/* Blit */
		if (xmin < 0) xmin = 0;
		if (xmax > r->width-1) xmax = r->width-1;
		if (xmin <= xmax) {
			nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
		}
	}

}

static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride)
{
	int x,y;

	/* Unpremultiply */
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = row[0], g = row[1], b = row[2], a = row[3];
			if (a != 0) {
				row[0] = (unsigned char)(r*255/a);
				row[1] = (unsigned char)(g*255/a);
				row[2] = (unsigned char)(b*255/a);
			}
			row += 4;
		}
	}

	/* Defringe */
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = 0, g = 0, b = 0, a = row[3], n = 0;
			if (a == 0) {
				if (x-1 > 0 && row[-1] != 0) {
					r += row[-4];
1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305
1306

	cache->spread = grad->spread;
	memcpy(cache->xform, grad->xform, sizeof(float)*6);

	if (grad->nstops == 0) {
		for (i = 0; i < 256; i++)
			cache->colors[i] = 0;
	} if (grad->nstops == 1) {

		for (i = 0; i < 256; i++)
			cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity);
	} else {
		unsigned int ca, cb = 0;
		float ua, ub, du, u;
		int ia, ib, count;

		ca = nsvg__applyOpacity(grad->stops[0].color, opacity);
		ua = nsvg__clampf(grad->stops[0].offset, 0, 1);







|
>

|







1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312

	cache->spread = grad->spread;
	memcpy(cache->xform, grad->xform, sizeof(float)*6);

	if (grad->nstops == 0) {
		for (i = 0; i < 256; i++)
			cache->colors[i] = 0;
	} else if (grad->nstops == 1) {
		unsigned int color = nsvg__applyOpacity(grad->stops[0].color, opacity);
		for (i = 0; i < 256; i++)
			cache->colors[i] = color;
	} else {
		unsigned int ca, cb = 0;
		float ua, ub, du, u;
		int ia, ib, count;

		ca = nsvg__applyOpacity(grad->stops[0].color, opacity);
		ua = nsvg__clampf(grad->stops[0].offset, 0, 1);
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


		if (shape->fill.type != NSVG_PAINT_NONE) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShape(r, shape, scale);

			// Scale and translate edges
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			// Rasterize edges

			qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
			nsvg__initPaint(&cache, &shape->fill, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
		}
		if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShapeStroke(r, shape, scale);

//			dumpEdges(r, "edge.svg");

			// Scale and translate edges
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			// Rasterize edges

			qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
			nsvg__initPaint(&cache, &shape->stroke, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
		}
	}

	nsvg__unpremultiplyAlpha(dst, w, h, stride);

	r->bitmap = NULL;
	r->width = 0;
	r->height = 0;
	r->stride = 0;
}

#endif









|








|
>
|

|











|

|








|
>
|

|















>
>
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
		if (shape->fill.type != NSVG_PAINT_NONE) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShape(r, shape, scale);

			/* Scale and translate edges */
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			/* Rasterize edges */
			if (r->nedges != 0)
				qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			/* now, traverse the scanlines and find the intersections on each scanline, use non-zero rule */
			nsvg__initPaint(&cache, &shape->fill, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
		}
		if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShapeStroke(r, shape, scale);

/*			dumpEdges(r, "edge.svg"); */

			/* Scale and translate edges */
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			/* Rasterize edges */
			if (r->nedges != 0)
				qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			/* now, traverse the scanlines and find the intersections on each scanline, use non-zero rule */
			nsvg__initPaint(&cache, &shape->stroke, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
		}
	}

	nsvg__unpremultiplyAlpha(dst, w, h, stride);

	r->bitmap = NULL;
	r->width = 0;
	r->height = 0;
	r->stride = 0;
}

#endif

#endif /* NANOSVGRAST_H */

Changes to generic/tk.decls.

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]>
#
# 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:







|
|







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 © 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:
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
}
declare 5 {
    void Tk_AddOption(Tk_Window tkwin, const char *name,
	    const char *value, int priority)
}
declare 6 {
    void Tk_BindEvent(Tk_BindingTable bindingTable,
	    XEvent *eventPtr, Tk_Window tkwin, int numObjects,
	    ClientData *objectPtr)
}
declare 7 {
    void Tk_CanvasDrawableCoords(Tk_Canvas canvas,
	    double x, double y, short *drawableXPtr,
	    short *drawableYPtr)
}
declare 8 {







|
|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
}
declare 5 {
    void Tk_AddOption(Tk_Window tkwin, const char *name,
	    const char *value, int priority)
}
declare 6 {
    void Tk_BindEvent(Tk_BindingTable bindingTable,
	    XEvent *eventPtr, Tk_Window tkwin, Tcl_Size numObjects,
	    void **objectPtr)
}
declare 7 {
    void Tk_CanvasDrawableCoords(Tk_Canvas canvas,
	    double x, double y, short *drawableXPtr,
	    short *drawableYPtr)
}
declare 8 {
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
}
declare 13 {
    int Tk_CanvasPsFont(Tcl_Interp *interp,
	    Tk_Canvas canvas, Tk_Font font)
}
declare 14 {
    void Tk_CanvasPsPath(Tcl_Interp *interp,
	    Tk_Canvas canvas, double *coordPtr, int numPoints)
}
declare 15 {
    int Tk_CanvasPsStipple(Tcl_Interp *interp,
	    Tk_Canvas canvas, Pixmap bitmap)
}
declare 16 {
    double Tk_CanvasPsY(Tk_Canvas canvas, double y)
}
declare 17 {
    void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc)
}
declare 18 {
    int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 19 {
    const char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 20 {
    Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas)
}
declare 21 {
    void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x, double y,
	    short *screenXPtr, short *screenYPtr)
}
declare 22 {
    void Tk_ChangeWindowAttributes(Tk_Window tkwin, unsigned long valueMask,
	    XSetWindowAttributes *attsPtr)
}
declare 23 {
    int Tk_CharBbox(Tk_TextLayout layout, int index, int *xPtr,
	    int *yPtr, int *widthPtr, int *heightPtr)
}
declare 24 {
    void Tk_ClearSelection(Tk_Window tkwin, Atom selection)
}
declare 25 {
    int Tk_ClipboardAppend(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom target, Atom format, const char *buffer)
}
declare 26 {
    int Tk_ClipboardClear(Tcl_Interp *interp, Tk_Window tkwin)
}
declare 27 {
    int Tk_ConfigureInfo(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 28 {
    int Tk_ConfigureValue(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 29 {
    int Tk_ConfigureWidget(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    int argc, const char **argv, char *widgRec,
	    int flags)
}
declare 30 {
    void Tk_ConfigureWindow(Tk_Window tkwin,
	    unsigned int valueMask, XWindowChanges *valuePtr)
}
declare 31 {
    Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font,
	    const char *str, int numChars, int wrapLength,
	    Tk_Justify justify, int flags, int *widthPtr,
	    int *heightPtr)
}
declare 32 {
    Tk_Window Tk_CoordsToWindow(int rootX, int rootY, Tk_Window tkwin)
}
declare 33 {
    unsigned long Tk_CreateBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr, const char *script, int append)
}
declare 34 {
    Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp)
}
declare 35 {
    Tk_ErrorHandler Tk_CreateErrorHandler(Display *display,
	    int errNum, int request, int minorCode,
	    Tk_ErrorProc *errorProc, ClientData clientData)
}
declare 36 {
    void Tk_CreateEventHandler(Tk_Window token,
	    unsigned long mask, Tk_EventProc *proc,
	    ClientData clientData)
}
declare 37 {
    void Tk_CreateGenericHandler(Tk_GenericProc *proc, ClientData clientData)
}
declare 38 {
    void Tk_CreateImageType(const Tk_ImageType *typePtr)
}
declare 39 {
    void Tk_CreateItemType(Tk_ItemType *typePtr)
}
declare 40 {
    void Tk_CreatePhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}
declare 41 {
    void Tk_CreateSelHandler(Tk_Window tkwin,
	    Atom selection, Atom target,
	    Tk_SelectionProc *proc, ClientData clientData,
	    Atom format)
}
declare 42 {
    Tk_Window Tk_CreateWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *name, const char *screenName)
}
declare 43 {
    Tk_Window Tk_CreateWindowFromPath(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *pathName, const char *screenName)
}
declare 44 {
    int Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
	    const void *source, int width, int height)
}
declare 45 {
    void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor)
}
declare 46 {
    void Tk_DeleteAllBindings(Tk_BindingTable bindingTable, ClientData object)
}
declare 47 {
    int Tk_DeleteBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr)
}
declare 48 {
    void Tk_DeleteBindingTable(Tk_BindingTable bindingTable)
}
declare 49 {
    void Tk_DeleteErrorHandler(Tk_ErrorHandler handler)
}
declare 50 {
    void Tk_DeleteEventHandler(Tk_Window token,
	    unsigned long mask, Tk_EventProc *proc,
	    ClientData clientData)
}
declare 51 {
    void Tk_DeleteGenericHandler(Tk_GenericProc *proc, ClientData clientData)
}
declare 52 {
    void Tk_DeleteImage(Tcl_Interp *interp, const char *name)
}
declare 53 {
    void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target)
}
declare 54 {
    void Tk_DestroyWindow(Tk_Window tkwin)
}
declare 55 {
    const char *Tk_DisplayName(Tk_Window tkwin)
}
declare 56 {
    int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y)
}
declare 57 {
    void Tk_Draw3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,
	    XPoint *pointPtr, int numPoints, int borderWidth,
	    int leftRelief)
}
declare 58 {
    void Tk_Draw3DRectangle(Tk_Window tkwin, Drawable drawable,
	    Tk_3DBorder border, int x, int y, int width, int height,
	    int borderWidth, int relief)
}
declare 59 {
    void Tk_DrawChars(Display *display, Drawable drawable, GC gc,
	    Tk_Font tkfont, const char *source, int numBytes, int x, int y)
}
declare 60 {
    void Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc, int width,
	    Drawable drawable)
}
declare 61 {
    void Tk_DrawTextLayout(Display *display,
	    Drawable drawable, GC gc, Tk_TextLayout layout,
	    int x, int y, int firstChar, int lastChar)
}
declare 62 {
    void Tk_Fill3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,
	    XPoint *pointPtr, int numPoints, int borderWidth,
	    int leftRelief)
}
declare 63 {
    void Tk_Fill3DRectangle(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border, int x,
	    int y, int width, int height, int borderWidth,
	    int relief)







|












|
|


|
|













|















|




|




|








|








|








|




|


|













|


















|



|











|


|



















|









|








|




|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
}
declare 13 {
    int Tk_CanvasPsFont(Tcl_Interp *interp,
	    Tk_Canvas canvas, Tk_Font font)
}
declare 14 {
    void Tk_CanvasPsPath(Tcl_Interp *interp,
	    Tk_Canvas canvas, double *coordPtr, Tcl_Size numPoints)
}
declare 15 {
    int Tk_CanvasPsStipple(Tcl_Interp *interp,
	    Tk_Canvas canvas, Pixmap bitmap)
}
declare 16 {
    double Tk_CanvasPsY(Tk_Canvas canvas, double y)
}
declare 17 {
    void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc)
}
declare 18 {
    int Tk_CanvasTagsParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 19 {
    const char *Tk_CanvasTagsPrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}
declare 20 {
    Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas)
}
declare 21 {
    void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x, double y,
	    short *screenXPtr, short *screenYPtr)
}
declare 22 {
    void Tk_ChangeWindowAttributes(Tk_Window tkwin, unsigned long valueMask,
	    XSetWindowAttributes *attsPtr)
}
declare 23 {
    int Tk_CharBbox(Tk_TextLayout layout, Tcl_Size index, int *xPtr,
	    int *yPtr, int *widthPtr, int *heightPtr)
}
declare 24 {
    void Tk_ClearSelection(Tk_Window tkwin, Atom selection)
}
declare 25 {
    int Tk_ClipboardAppend(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom target, Atom format, const char *buffer)
}
declare 26 {
    int Tk_ClipboardClear(Tcl_Interp *interp, Tk_Window tkwin)
}
declare 27 {
    int Tk_ConfigureInfo(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    void *widgRec, const char *argvName, int flags)
}
declare 28 {
    int Tk_ConfigureValue(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    void *widgRec, const char *argvName, int flags)
}
declare 29 {
    int Tk_ConfigureWidget(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    Tcl_Size objc, Tcl_Obj *const *objv, void *widgRec,
	    int flags)
}
declare 30 {
    void Tk_ConfigureWindow(Tk_Window tkwin,
	    unsigned int valueMask, XWindowChanges *valuePtr)
}
declare 31 {
    Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font,
	    const char *str, Tcl_Size numChars, int wrapLength,
	    Tk_Justify justify, int flags, int *widthPtr,
	    int *heightPtr)
}
declare 32 {
    Tk_Window Tk_CoordsToWindow(int rootX, int rootY, Tk_Window tkwin)
}
declare 33 {
    unsigned long Tk_CreateBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, void *object,
	    const char *eventStr, const char *script, int append)
}
declare 34 {
    Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp)
}
declare 35 {
    Tk_ErrorHandler Tk_CreateErrorHandler(Display *display,
	    int errNum, int request, int minorCode,
	    Tk_ErrorProc *errorProc, void *clientData)
}
declare 36 {
    void Tk_CreateEventHandler(Tk_Window token,
	    unsigned long mask, Tk_EventProc *proc,
	    void *clientData)
}
declare 37 {
    void Tk_CreateGenericHandler(Tk_GenericProc *proc, void *clientData)
}
declare 38 {
    void Tk_CreateImageType(const Tk_ImageType *typePtr)
}
declare 39 {
    void Tk_CreateItemType(Tk_ItemType *typePtr)
}
declare 40 {
    void Tk_CreatePhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}
declare 41 {
    void Tk_CreateSelHandler(Tk_Window tkwin,
	    Atom selection, Atom target,
	    Tk_SelectionProc *proc, void *clientData,
	    Atom format)
}
declare 42 {
    Tk_Window Tk_CreateWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *name, const char *screenName)
}
declare 43 {
    Tk_Window Tk_CreateWindowFromPath(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *pathName, const char *screenName)
}
declare 44 {
    int Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
	    const void *source, int width, int height)
}
declare 45 {
    void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor)
}
declare 46 {
    void Tk_DeleteAllBindings(Tk_BindingTable bindingTable, void *object)
}
declare 47 {
    int Tk_DeleteBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, void *object,
	    const char *eventStr)
}
declare 48 {
    void Tk_DeleteBindingTable(Tk_BindingTable bindingTable)
}
declare 49 {
    void Tk_DeleteErrorHandler(Tk_ErrorHandler handler)
}
declare 50 {
    void Tk_DeleteEventHandler(Tk_Window token,
	    unsigned long mask, Tk_EventProc *proc,
	    void *clientData)
}
declare 51 {
    void Tk_DeleteGenericHandler(Tk_GenericProc *proc, void *clientData)
}
declare 52 {
    void Tk_DeleteImage(Tcl_Interp *interp, const char *name)
}
declare 53 {
    void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target)
}
declare 54 {
    void Tk_DestroyWindow(Tk_Window tkwin)
}
declare 55 {
    const char *Tk_DisplayName(Tk_Window tkwin)
}
declare 56 {
    int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y)
}
declare 57 {
    void Tk_Draw3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,
	    XPoint *pointPtr, Tcl_Size numPoints, int borderWidth,
	    int leftRelief)
}
declare 58 {
    void Tk_Draw3DRectangle(Tk_Window tkwin, Drawable drawable,
	    Tk_3DBorder border, int x, int y, int width, int height,
	    int borderWidth, int relief)
}
declare 59 {
    void Tk_DrawChars(Display *display, Drawable drawable, GC gc,
	    Tk_Font tkfont, const char *source, Tcl_Size numBytes, int x, int y)
}
declare 60 {
    void Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc, int width,
	    Drawable drawable)
}
declare 61 {
    void Tk_DrawTextLayout(Display *display,
	    Drawable drawable, GC gc, Tk_TextLayout layout,
	    int x, int y, Tcl_Size firstChar, Tcl_Size lastChar)
}
declare 62 {
    void Tk_Fill3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,
	    XPoint *pointPtr, Tcl_Size numPoints, int borderWidth,
	    int leftRelief)
}
declare 63 {
    void Tk_Fill3DRectangle(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border, int x,
	    int y, int width, int height, int borderWidth,
	    int relief)
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
    void Tk_FreeGC(Display *display, GC gc)
}
declare 73 {
    void Tk_FreeImage(Tk_Image image)
}
declare 74 {
    void Tk_FreeOptions(const Tk_ConfigSpec *specs,
	    char *widgRec, Display *display, int needFlags)
}
declare 75 {
    void Tk_FreePixmap(Display *display, Pixmap pixmap)
}
declare 76 {
    void Tk_FreeTextLayout(Tk_TextLayout textLayout)
}
declare 77 {deprecated {function does nothing, call can be removed}} {
    void Tk_FreeXId(Display *display, XID xid)
}
declare 78 {
    GC Tk_GCForColor(XColor *colorPtr, Drawable drawable)
}
declare 79 {
    void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,  int reqHeight)
}
declare 80 {
    Tk_3DBorder	Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
	    Tk_Uid colorName)
}
declare 81 {
    void Tk_GetAllBindings(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object)
}
declare 82 {
    int Tk_GetAnchor(Tcl_Interp *interp,
	    const char *str, Tk_Anchor *anchorPtr)
}
declare 83 {
    const char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
    const char *Tk_GetBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr)
}
declare 85 {
    Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str)
}
declare 86 {
    Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp,







|







<
<
<












|










|







314
315
316
317
318
319
320
321
322
323
324
325
326
327
328



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
    void Tk_FreeGC(Display *display, GC gc)
}
declare 73 {
    void Tk_FreeImage(Tk_Image image)
}
declare 74 {
    void Tk_FreeOptions(const Tk_ConfigSpec *specs,
	    void *widgRec, Display *display, int needFlags)
}
declare 75 {
    void Tk_FreePixmap(Display *display, Pixmap pixmap)
}
declare 76 {
    void Tk_FreeTextLayout(Tk_TextLayout textLayout)
}



declare 78 {
    GC Tk_GCForColor(XColor *colorPtr, Drawable drawable)
}
declare 79 {
    void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,  int reqHeight)
}
declare 80 {
    Tk_3DBorder	Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
	    Tk_Uid colorName)
}
declare 81 {
    void Tk_GetAllBindings(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, void *object)
}
declare 82 {
    int Tk_GetAnchor(Tcl_Interp *interp,
	    const char *str, Tk_Anchor *anchorPtr)
}
declare 83 {
    const char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
    const char *Tk_GetBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, void *object,
	    const char *eventStr)
}
declare 85 {
    Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str)
}
declare 86 {
    Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp,
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
    void Tk_GetFontMetrics(Tk_Font font, Tk_FontMetrics *fmPtr)
}
declare 96 {
    GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr)
}
declare 97 {
    Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name,
	    Tk_ImageChangedProc *changeProc, ClientData clientData)
}
declare 98 {
    ClientData Tk_GetImageModelData(Tcl_Interp *interp,
	    const char *name, const Tk_ImageType **typePtrPtr)
}
declare 99 {
    Tk_ItemType *Tk_GetItemTypes(void)
}
declare 100 {
    int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr)







|


|







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    void Tk_GetFontMetrics(Tk_Font font, Tk_FontMetrics *fmPtr)
}
declare 96 {
    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, void *clientData)
}
declare 98 {
    void *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)
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
    int Tk_GetRelief(Tcl_Interp *interp, const char *name, int *reliefPtr)
}
declare 107 {
    void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr)
}
declare 108 {
    int Tk_GetScrollInfo(Tcl_Interp *interp,
	    int argc, const char **argv, double *dblPtr, int *intPtr)
}
declare 109 {
    int Tk_GetScreenMM(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, double *doublePtr)
}
declare 110 {
    int Tk_GetSelection(Tcl_Interp *interp,
	    Tk_Window tkwin, Atom selection, Atom target,
	    Tk_GetSelProc *proc, ClientData clientData)
}
declare 111 {
    Tk_Uid Tk_GetUid(const char *str)
}
declare 112 {
    Visual *Tk_GetVisual(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, int *depthPtr,







|








|







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    int Tk_GetRelief(Tcl_Interp *interp, const char *name, int *reliefPtr)
}
declare 107 {
    void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr)
}
declare 108 {
    int Tk_GetScrollInfo(Tcl_Interp *interp,
	    Tcl_Size argc, const char **argv, double *dblPtr, int *intPtr)
}
declare 109 {
    int Tk_GetScreenMM(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, double *doublePtr)
}
declare 110 {
    int Tk_GetSelection(Tcl_Interp *interp,
	    Tk_Window tkwin, Atom selection, Atom target,
	    Tk_GetSelProc *proc, void *clientData)
}
declare 111 {
    Tk_Uid Tk_GetUid(const char *str)
}
declare 112 {
    Visual *Tk_GetVisual(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, int *depthPtr,
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageModel model, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}
declare 118 {
    int Tk_Init(Tcl_Interp *interp)
}
declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)
}
declare 120 {
    int Tk_IntersectTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height)
}
declare 121 {
    void Tk_MaintainGeometry(Tk_Window window,
	    Tk_Window container, int x, int y, int width, int height)
}
declare 122 {
    Tk_Window Tk_MainWindow(Tcl_Interp *interp)
}
declare 123 {
    void Tk_MakeWindowExist(Tk_Window tkwin)
}
declare 124 {
    void Tk_ManageGeometry(Tk_Window tkwin,
	    const Tk_GeomMgr *mgrPtr, ClientData clientData)
}
declare 125 {
    void Tk_MapWindow(Tk_Window tkwin)
}
declare 126 {
    int Tk_MeasureChars(Tk_Font tkfont,
	    const char *source, int numBytes, int maxPixels,
	    int flags, int *lengthPtr)
}
declare 127 {
    void Tk_MoveResizeWindow(Tk_Window tkwin,
	    int x, int y, int width, int height)
}
declare 128 {







<
<
<



















|






|







468
469
470
471
472
473
474



475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageModel model, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}



declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)
}
declare 120 {
    int Tk_IntersectTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height)
}
declare 121 {
    void Tk_MaintainGeometry(Tk_Window window,
	    Tk_Window container, int x, int y, int width, int height)
}
declare 122 {
    Tk_Window Tk_MainWindow(Tcl_Interp *interp)
}
declare 123 {
    void Tk_MakeWindowExist(Tk_Window tkwin)
}
declare 124 {
    void Tk_ManageGeometry(Tk_Window tkwin,
	    const Tk_GeomMgr *mgrPtr, void *clientData)
}
declare 125 {
    void Tk_MapWindow(Tk_Window tkwin)
}
declare 126 {
    int Tk_MeasureChars(Tk_Font tkfont,
	    const char *source, Tcl_Size numBytes, int maxPixels,
	    int flags, int *lengthPtr)
}
declare 127 {
    void Tk_MoveResizeWindow(Tk_Window tkwin,
	    int x, int y, int width, int height)
}
declare 128 {
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
declare 141 {
    Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
	    const char *pathName, Tk_Window tkwin)
}
declare 142 {
    void Tk_OwnSelection(Tk_Window tkwin,
	    Atom selection, Tk_LostSelProc *proc,
	    ClientData clientData)
}
declare 143 {
    int Tk_ParseArgv(Tcl_Interp *interp,
	    Tk_Window tkwin, int *argcPtr, const char **argv,
	    const Tk_ArgvInfo *argTable, int flags)
}
declare 144 {deprecated {function signature changed}} {
    void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height)
}
declare 145 {deprecated {function signature changed}} {
    void Tk_PhotoPutZoomedBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int zoomX, int zoomY,
	    int subsampleX, int subsampleY)
}
declare 146 {
    int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)
}
declare 147 {
    void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
declare 148 {deprecated {function signature changed}} {
    void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height )
}
declare 149 {
    void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)
}
declare 150 {deprecated {function signature changed}} {
    void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
    int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
}
declare 152 {
    int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr)
}
declare 153 {







|






<
<
<
<
<
<
<
<
<
<
<






<
<
<



<
<
<







547
548
549
550
551
552
553
554
555
556
557
558
559
560











561
562
563
564
565
566



567
568
569



570
571
572
573
574
575
576
declare 141 {
    Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
	    const char *pathName, Tk_Window tkwin)
}
declare 142 {
    void Tk_OwnSelection(Tk_Window tkwin,
	    Atom selection, Tk_LostSelProc *proc,
	    void *clientData)
}
declare 143 {
    int Tk_ParseArgv(Tcl_Interp *interp,
	    Tk_Window tkwin, int *argcPtr, const char **argv,
	    const Tk_ArgvInfo *argTable, int flags)
}











declare 146 {
    int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)
}
declare 147 {
    void Tk_PhotoBlank(Tk_PhotoHandle handle)
}



declare 149 {
    void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)
}



declare 151 {
    int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
}
declare 152 {
    int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr)
}
declare 153 {
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
    void Tk_ResizeWindow(Tk_Window tkwin, int width, int height)
}
declare 157 {
    int Tk_RestackWindow(Tk_Window tkwin, int aboveBelow, Tk_Window other)
}
declare 158 {
    Tk_RestrictProc *Tk_RestrictEvents(Tk_RestrictProc *proc,
	    ClientData arg, ClientData *prevArgPtr)
}
declare 159 {
    int Tk_SafeInit(Tcl_Interp *interp)
}
declare 160 {
    const char *Tk_SetAppName(Tk_Window tkwin, const char *name)
}
declare 161 {
    void Tk_SetBackgroundFromBorder(Tk_Window tkwin, Tk_3DBorder border)
}







|
<
<
<







588
589
590
591
592
593
594
595



596
597
598
599
600
601
602
    void Tk_ResizeWindow(Tk_Window tkwin, int width, int height)
}
declare 157 {
    int Tk_RestackWindow(Tk_Window tkwin, int aboveBelow, Tk_Window other)
}
declare 158 {
    Tk_RestrictProc *Tk_RestrictEvents(Tk_RestrictProc *proc,
	    void *arg, void **prevArgPtr)



}
declare 160 {
    const char *Tk_SetAppName(Tk_Window tkwin, const char *name)
}
declare 161 {
    void Tk_SetBackgroundFromBorder(Tk_Window tkwin, Tk_3DBorder border)
}
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
declare 174 {
    int Tk_StrictMotif(Tk_Window tkwin)
}
declare 175 {
    void Tk_TextLayoutToPostscript(Tcl_Interp *interp, Tk_TextLayout layout)
}
declare 176 {
    int Tk_TextWidth(Tk_Font font, const char *str, int numBytes)
}
declare 177 {
    void Tk_UndefineCursor(Tk_Window window)
}
declare 178 {
    void Tk_UnderlineChars(Display *display,
	    Drawable drawable, GC gc, Tk_Font tkfont,
	    const char *source, int x, int y, int firstByte,
	    int lastByte)
}
declare 179 {
    void Tk_UnderlineTextLayout(Display *display, Drawable drawable, GC gc,
	    Tk_TextLayout layout, int x, int y,
	    int underline)
}
declare 180 {







|







|
|







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
declare 174 {
    int Tk_StrictMotif(Tk_Window tkwin)
}
declare 175 {
    void Tk_TextLayoutToPostscript(Tcl_Interp *interp, Tk_TextLayout layout)
}
declare 176 {
    int Tk_TextWidth(Tk_Font font, const char *str, Tcl_Size numBytes)
}
declare 177 {
    void Tk_UndefineCursor(Tk_Window window)
}
declare 178 {
    void Tk_UnderlineChars(Display *display,
	    Drawable drawable, GC gc, Tk_Font tkfont,
	    const char *source, int x, int y, Tcl_Size firstByte,
	    Tcl_Size lastByte)
}
declare 179 {
    void Tk_UnderlineTextLayout(Display *display, Drawable drawable, GC gc,
	    Tk_TextLayout layout, int x, int y,
	    int underline)
}
declare 180 {
795
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
}
declare 209 {
    int	 Tk_GetReliefFromObj(Tcl_Interp *interp,
	    Tcl_Obj *objPtr, int *resultPtr)
}
declare 210 {
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {nostub {Don't use this function in a stub-enabled extension}} {
    void  Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {
    int	 Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionTable, int objc,
	    Tcl_Obj *const objv[], Tk_Window tkwin,
	    Tk_SavedOptions *savePtr, int *maskPtr)
}
declare 215 {
    void Tk_InitConsoleChannels(Tcl_Interp *interp)
}
declare 216 {
    int Tk_CreateConsoleWindow(Tcl_Interp *interp)
}
declare 217 {
    void Tk_CreateSmoothMethod(Tcl_Interp *interp, const Tk_SmoothMethod *method)
}
#declare 218 {
#    void Tk_CreateCanvasVisitor(Tcl_Interp *interp, void *typePtr)
#}
#declare 219 {







|





<
<
<
<





|






<
<
<







769
770
771
772
773
774
775
776
777
778
779
780
781




782
783
784
785
786
787
788
789
790
791
792
793



794
795
796
797
798
799
800
}
declare 209 {
    int	 Tk_GetReliefFromObj(Tcl_Interp *interp,
	    Tcl_Obj *objPtr, int *resultPtr)
}
declare 210 {
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    Tcl_Size objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}




declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {
    int	 Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionTable, Tcl_Size objc,
	    Tcl_Obj *const objv[], Tk_Window tkwin,
	    Tk_SavedOptions *savePtr, int *maskPtr)
}
declare 215 {
    void Tk_InitConsoleChannels(Tcl_Interp *interp)
}



declare 217 {
    void Tk_CreateSmoothMethod(Tcl_Interp *interp, const Tk_SmoothMethod *method)
}
#declare 218 {
#    void Tk_CreateCanvasVisitor(Tcl_Interp *interp, void *typePtr)
#}
#declare 219 {
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
declare 234 {
    int Tk_PostscriptImage(Tk_Image image, Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y,
	    int width, int height, int prepass)
}
declare 235 {
    void Tk_PostscriptPath(Tcl_Interp *interp, Tk_PostscriptInfo psInfo,
	    double *coordPtr, int numPoints)
}
declare 236 {
    int Tk_PostscriptStipple(Tcl_Interp *interp, Tk_Window tkwin,
	    Tk_PostscriptInfo psInfo, Pixmap bitmap)
}
declare 237 {
    double Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo)







|







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
declare 234 {
    int Tk_PostscriptImage(Tk_Image image, Tcl_Interp *interp,
	    Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y,
	    int width, int height, int prepass)
}
declare 235 {
    void Tk_PostscriptPath(Tcl_Interp *interp, Tk_PostscriptInfo psInfo,
	    double *coordPtr, Tcl_Size numPoints)
}
declare 236 {
    int Tk_PostscriptStipple(Tcl_Interp *interp, Tk_Window tkwin,
	    Tk_PostscriptInfo psInfo, Pixmap bitmap)
}
declare 237 {
    double Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo)
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
#
declare 241 {
    Tk_Window Tk_CreateAnonymousWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *screenName)
}
declare 242 {
    void Tk_SetClassProcs(Tk_Window tkwin,
	    const Tk_ClassProcs *procs, ClientData instanceData)
}

# New in 8.4a4
#
declare 243 {
    void Tk_SetInternalBorderEx(Tk_Window tkwin, int left, int right,
	    int top, int bottom)
}
declare 244 {
    void Tk_SetMinimumRequestSize(Tk_Window tkwin,
	    int minWidth, int minHeight)
}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {deprecated {function signature changed}} {
    void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int compRule)
}
declare 247 {deprecated {function signature changed}} {
    void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int zoomX, int zoomY,
	    int subsampleX, int subsampleY, int compRule)
}
declare 248 {
    int Tk_CollapseMotionEvents(Display *display, int collapse)
}

# Style engine
declare 249 {
    Tk_StyleEngine Tk_RegisterStyleEngine(const char *name,







|


















<
<
<
<
<
<
<
<
<
<
<







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
#
declare 241 {
    Tk_Window Tk_CreateAnonymousWindow(Tcl_Interp *interp,
	    Tk_Window parent, const char *screenName)
}
declare 242 {
    void Tk_SetClassProcs(Tk_Window tkwin,
	    const Tk_ClassProcs *procs, void *instanceData)
}

# New in 8.4a4
#
declare 243 {
    void Tk_SetInternalBorderEx(Tk_Window tkwin, int left, int right,
	    int top, int bottom)
}
declare 244 {
    void Tk_SetMinimumRequestSize(Tk_Window tkwin,
	    int minWidth, int minHeight)
}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}











declare 248 {
    int Tk_CollapseMotionEvents(Display *display, int collapse)
}

# Style engine
declare 249 {
    Tk_StyleEngine Tk_RegisterStyleEngine(const char *name,
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
	    Tk_ElementSpec *templatePtr)
}
declare 252 {
    int Tk_GetElementId(const char *name)
}
declare 253 {
    Tk_Style Tk_CreateStyle(const char *name, Tk_StyleEngine engine,
	    ClientData clientData)
}
declare 254 {
    Tk_Style Tk_GetStyle(Tcl_Interp *interp, const char *name)
}
declare 255 {
    void Tk_FreeStyle(Tk_Style style)
}
declare 256 {
    const char *Tk_NameOfStyle(Tk_Style style)
}
declare 257 {
    Tk_Style  Tk_AllocStyleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
}
declare 258 {
    Tk_Style Tk_GetStyleFromObj(Tcl_Obj *objPtr)
}
declare 259 {
    void  Tk_FreeStyleFromObj(Tcl_Obj *objPtr)
}
declare 260 {
    Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
	Tk_OptionTable optionTable)
}
declare 261 {
    void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, int width, int height,
	    int inner, int *widthPtr, int *heightPtr)
}







|













<
<
<
<
<
<

|







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
	    Tk_ElementSpec *templatePtr)
}
declare 252 {
    int Tk_GetElementId(const char *name)
}
declare 253 {
    Tk_Style Tk_CreateStyle(const char *name, Tk_StyleEngine engine,
	    void *clientData)
}
declare 254 {
    Tk_Style Tk_GetStyle(Tcl_Interp *interp, const char *name)
}
declare 255 {
    void Tk_FreeStyle(Tk_Style style)
}
declare 256 {
    const char *Tk_NameOfStyle(Tk_Style style)
}
declare 257 {
    Tk_Style  Tk_AllocStyleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
}






declare 260 {
    Tk_StyledElement Tk_GetStyledElement(Tk_Style style, Tcl_Size elementId,
	Tk_OptionTable optionTable)
}
declare 261 {
    void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, int width, int height,
	    int inner, int *widthPtr, int *heightPtr)
}
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
}

# TIP #264
declare 271 {
    Tcl_Interp *Tk_Interp(Tk_Window tkwin)
}

# Now that the Tk 8.2 -> 8.3 transition is long past, use more conventional
# means to continue support for extensions using the USE_OLD_IMAGE to
# continue use of their string-based Tcl_ImageTypes and Tcl_PhotoImageFormats.
#
# Note that this restores the usual rules for stub compatibility.  Stub-enabled
# extensions compiled against 8.5 headers and linked to the 8.5 stub library
# will produce a file [load]able into an interp with Tk 8.X, for X >= 5.
# It will *not* be [load]able into interps with Tk 8.4 (or Tk 8.2!).
# Developers who need to produce a file [load]able into legacy interps must
# build against legacy sources.
declare 272 {
    void Tk_CreateOldImageType(const Tk_ImageType *typePtr)
}
declare 273 {
    void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}

# TIP#580
declare 274 {
    int Tk_AlwaysShowSelection(Tk_Window tkwin)
}
declare 275 {
    unsigned Tk_GetButtonMask(unsigned button)
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







998
999
1000
1001
1002
1003
1004

















1005
1006
1007
1008
1009
1010
1011
}

# TIP #264
declare 271 {
    Tcl_Interp *Tk_Interp(Tk_Window tkwin)
}


















# TIP#580
declare 274 {
    int Tk_AlwaysShowSelection(Tk_Window tkwin)
}
declare 275 {
    unsigned Tk_GetButtonMask(unsigned button)
}
1086
1087
1088
1089
1090
1091
1092












































1093
1094
1095
1096
1097
1098
1099
declare 278 {
    void Tk_SendVirtualEvent(Tk_Window tkwin, const char *eventName,
	    Tcl_Obj *detail)
}
declare 279 {
    Tcl_Obj *Tk_FontGetDescription(Tk_Font tkfont)
}













































# Define the platform specific public Tk interface.  These functions are
# only available on the designated platform.

interface tkPlat

################################







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
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)
}

# TIP#606
declare 281 {
    void Tk_DrawHighlightBorder(Tk_Window tkwin, GC fgGC, GC bgGC,
	    int highlightWidth, Drawable drawable)
}
declare 282 {
    void Tk_SetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, const char *menuName)
}
declare 283 {
    void Tk_SetWindowMenubar(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *oldMenuName, const char *menuName)
}
declare 284 {
    void Tk_ClipDrawableToRect(Display *display, Drawable d, int x,
	    int y, int width, int height)
}
declare 285 {
    Tcl_Obj *Tk_GetSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 286 {
    int Tk_UseWindow(Tcl_Interp *interp, Tk_Window tkwin, const char *string)
}
declare 287 {
    void Tk_MakeContainer(Tk_Window tkwin)
}
declare 288 {
    Tk_Window Tk_GetOtherWindow(Tk_Window tkwin)
}
declare 289 {
    void Tk_Get3DBorderColors(Tk_3DBorder border, XColor *bgColorPtr, XColor *darkColorPtr,
	    XColor *lightColorPtr)
}
declare 290 {
    Window Tk_MakeWindow(Tk_Window tkwin, Window parent)
}


# Define the platform specific public Tk interface.  These functions are
# only available on the designated platform.

interface tkPlat

################################
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
}
declare 2 win {
    HWND Tk_GetHWND(Window window)
}
declare 3 win {
    Tk_Window Tk_HWNDToWindow(HWND hwnd)
}
declare 4 win {
    void Tk_PointerEvent(HWND hwnd, int x, int y)
}
declare 5 win {
    int Tk_TranslateWinEvent(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
}

################################
# Aqua specific functions
# Stub removed because the function no longer exists.
#declare 3 aqua {
#    void TkMacOSXInitMenus(Tcl_Interp *interp)
#}
declare 4 aqua {
    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
}
declare 5 aqua {
    void TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}
declare 6 aqua {
    void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}
# Stub removed because it just returned NULL.
#declare 7 aqua {
#    void *TkMacOSXGetDrawablePort(Drawable drawable)
#}







<
<
<
<
<
<
<



<
<
<
<



<
<
<
<







1084
1085
1086
1087
1088
1089
1090







1091
1092
1093




1094
1095
1096




1097
1098
1099
1100
1101
1102
1103
}
declare 2 win {
    HWND Tk_GetHWND(Window window)
}
declare 3 win {
    Tk_Window Tk_HWNDToWindow(HWND hwnd)
}








################################
# Aqua specific functions




declare 4 aqua {
    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
}




declare 6 aqua {
    void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}
# Stub removed because it just returned NULL.
#declare 7 aqua {
#    void *TkMacOSXGetDrawablePort(Drawable drawable)
#}
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
# Public functions that are not accessible via the stubs table.

export {
    const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
	    int exact)
}
export {
    void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
export {
    void Tk_MainExW(int argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
}

# Local Variables:
# mode: tcl
# End:







|



|






1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
# Public functions that are not accessible via the stubs table.

export {
    const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
	    int exact)
}
export {
    void Tk_MainEx(Tcl_Size argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
export {
    void Tk_MainExW(Tcl_Size argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
}

# Local Variables:
# mode: tcl
# End:

Changes to generic/tk.h.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
#	error Tk 8.7 must be compiled with tcl.h from Tcl 8.6 or better
#endif

#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

/*







|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 7)
#	error Tk 9.0 must be compiled with tcl.h from Tcl 8.7 or better
#endif

#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

/*
61
62
63
64
65
66
67

68


69
70
71
72
73
74

75
76
77
78
79
80
81
 * unix/tk.spec		(1 LOC patch)
 * win/tcl.m4		(not patchlevel)
 *
 * You may also need to update some of these files when the numbers change for
 * the version of Tcl that this release of Tk is compiled against.
 */


#define TK_MAJOR_VERSION	8


#define TK_MINOR_VERSION	7
#define TK_RELEASE_LEVEL	TCL_ALPHA_RELEASE
#define TK_RELEASE_SERIAL	4

#define TK_VERSION		"8.7"
#define TK_PATCH_LEVEL		"8.7a4"


/*
 * A special definition used to allow this header file to be included from
 * windows or mac resource files so that they can obtain version information.
 * RC_INVOKED is defined by default by the windows RC tool and manually set
 * for macintosh.
 *







>
|
>
>
|
|
|

|
|
>







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 * unix/tk.spec		(1 LOC patch)
 * win/tcl.m4		(not patchlevel)
 *
 * You may also need to update some of these files when the numbers change for
 * the version of Tcl that this release of Tk is compiled against.
 */

#ifndef TK_MAJOR_VERSION
#   define TK_MAJOR_VERSION 9
#endif
#if TK_MAJOR_VERSION == 9
#   define TK_MINOR_VERSION	0
#   define TK_RELEASE_LEVEL	TCL_BETA_RELEASE
#   define TK_RELEASE_SERIAL	2

#   define TK_VERSION		"9.0"
#   define TK_PATCH_LEVEL		"9.0b2"
#endif /* TK_MAJOR_VERSION */

/*
 * A special definition used to allow this header file to be included from
 * windows or mac resource files so that they can obtain version information.
 * RC_INVOKED is defined by default by the windows RC tool and manually set
 * for macintosh.
 *
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#   include <X11/Xlib.h>
#   ifdef MAC_OSX_TK
#	include <X11/X.h>
#   endif
#endif
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
     || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#   include <stddef.h>
#endif

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS	DLLEXPORT
#else
# ifndef TCL_STORAGE_CLASS
#   define TCL_STORAGE_CLASS DLLIMPORT







<
<
|
<







94
95
96
97
98
99
100


101

102
103
104
105
106
107
108
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#   include <X11/Xlib.h>
#   ifdef MAC_OSX_TK
#	include <X11/X.h>
#   endif
#endif


#include <stddef.h>


#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS	DLLEXPORT
#else
# ifndef TCL_STORAGE_CLASS
#   define TCL_STORAGE_CLASS DLLIMPORT
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
    TK_OPTION_JUSTIFY,
    TK_OPTION_ANCHOR,
    TK_OPTION_SYNONYM,
    TK_OPTION_PIXELS,
    TK_OPTION_WINDOW,
    TK_OPTION_END,
    TK_OPTION_CUSTOM,
    TK_OPTION_STYLE

} Tk_OptionType;

/*
 * Structures of the following type are used by widgets to specify their
 * configuration options. Typically each widget has a static array of these
 * structures, where each element of the array describes a single
 * configuration option. The array is passed to Tk_CreateOptionTable.
 */

typedef struct Tk_OptionSpec {
    Tk_OptionType type;		/* Type of option, such as TK_OPTION_COLOR;
				 * see definitions above. Last option in table
				 * must have type TK_OPTION_END. */
    const char *optionName;	/* Name used to specify option in Tcl
				 * commands. */
    const char *dbName;		/* Name for option in option database. */
    const char *dbClass;	/* Class for option in database. */
    const char *defValue;	/* Default value for option if not specified
				 * in command line, the option database, or
				 * the system. */
#if TCL_MAJOR_VERSION > 8
    size_t objOffset;		/* Where in record to store a Tcl_Obj * that
				 * holds the value of this option, specified
				 * as an offset in bytes from the start of the
				 * record. Use the offsetof macro to generate
				 * values for this. TCL_INDEX_NONE means don't
				 * store the Tcl_Obj in the record. */
    size_t internalOffset;		/* Where in record to store the internal
				 * representation of the value of this option,
				 * such as an int or XColor *. This field is
				 * specified as an offset in bytes from the
				 * start of the record. Use the offsetof
				 * macro to generate values for it.
				 * TCL_INDEX_NONE means don't store the
				 * internal representation in the record. */
#else
    int objOffset;
    int internalOffset;
#endif
    int flags;			/* Any combination of the values defined
				 * below. */
    const void *clientData;	/* An alternate place to put option-specific
				 * data. Used for the monochrome default value
				 * for colors, etc. */
    int typeMask;		/* An arbitrary bit mask defined by the class
				 * manager; typically bits correspond to
				 * certain kinds of options such as all those
				 * that require a redisplay when they change.
				 * Tk_SetOptions returns the bit-wise OR of
				 * the typeMasks of all options that were
				 * changed. */
} Tk_OptionSpec;

/*
 * Flag values for Tk_OptionSpec structures. These flags are shared by
 * Tk_ConfigSpec structures, so be sure to coordinate any changes carefully.
 */

#define TK_OPTION_NULL_OK		(1 << 0)

#define TK_OPTION_DONT_SET_DEFAULT	(1 << 3)



/*
 * The following structure and function types are used by TK_OPTION_CUSTOM
 * options; the structure holds pointers to the functions needed by the Tk
 * option config code to handle a custom option.
 */

#if TCL_MAJOR_VERSION > 8
typedef int (Tk_CustomOptionSetProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec,
	size_t offset, char *saveInternalPtr, int flags);
typedef Tcl_Obj *(Tk_CustomOptionGetProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, size_t offset);
#else
typedef int (Tk_CustomOptionSetProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec,
	int offset, char *saveInternalPtr, int flags);
typedef Tcl_Obj *(Tk_CustomOptionGetProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset);
#endif
typedef void (Tk_CustomOptionRestoreProc) (ClientData clientData,
	Tk_Window tkwin, char *internalPtr, char *saveInternalPtr);
typedef void (Tk_CustomOptionFreeProc) (ClientData clientData, Tk_Window tkwin,
	char *internalPtr);

typedef struct Tk_ObjCustomOption {
    const char *name;		/* Name of the custom option. */
    Tk_CustomOptionSetProc *setProc;
				/* Function to use to set a record's option
				 * value from a Tcl_Obj */
    Tk_CustomOptionGetProc *getProc;
				/* Function to use to get a Tcl_Obj
				 * representation from an internal
				 * representation of an option. */
    Tk_CustomOptionRestoreProc *restoreProc;
				/* Function to use to restore a saved value
				 * for the internal representation. */
    Tk_CustomOptionFreeProc *freeProc;
				/* Function to use to free the internal
				 * representation of an option. */
    ClientData clientData;	/* Arbitrary one-word value passed to the
				 * handling procs. */
} Tk_ObjCustomOption;

/*
 * Macro to use to fill in "offset" fields of the Tk_OptionSpec structure.
 * Computes number of bytes from beginning of structure to a given field.
 */

#ifndef TK_NO_DEPRECATED
#   define Tk_Offset(type, field) ((int) offsetof(type, field))
#endif
/* Workaround for platforms missing offsetof(), e.g. VC++ 6.0 */
#ifndef offsetof
#   define offsetof(type, field) ((size_t) ((char *) &((type *) 0)->field))
#endif

/*
 * The following two structures are used for error handling. When config
 * options are being modified, the old values are saved in a Tk_SavedOptions
 * structure. If an error occurs, then the contents of the structure can be
 * used to restore all of the old values. The contents of this structure are
 * for the private use Tk. No-one outside Tk should ever read or write any of
 * the fields of these structures.
 */

typedef struct Tk_SavedOption {
    struct TkOption *optionPtr;	/* Points to information that describes the
				 * option. */
    Tcl_Obj *valuePtr;		/* The old value of the option, in the form of
				 * a Tcl object; may be NULL if the value was
				 * not saved as an object. */

    double internalForm;	/* The old value of the option, in some
				 * internal representation such as an int or
				 * (XColor *). Valid only if the field
				 * optionPtr->specPtr->objOffset is -1. The
				 * space must be large enough to accommodate a
				 * double, a long, or a pointer; right now it
				 * looks like a double (i.e., 8 bytes) is big
				 * enough. Also, using a double guarantees
				 * that the field is properly aligned for
				 * storing large values. */



} Tk_SavedOption;

#ifdef TCL_MEM_DEBUG
#   define TK_NUM_SAVED_OPTIONS 2
#else
#   define TK_NUM_SAVED_OPTIONS 20
#endif

typedef struct Tk_SavedOptions {
    void *recordPtr;		/* The data structure in which to restore
				 * configuration options. */
    Tk_Window tkwin;		/* Window associated with recordPtr; needed to
				 * restore certain options. */
#if TCL_MAJOR_VERSION > 8
    size_t numItems;		/* The number of valid items in items field. */
#else
    int numItems;
#endif
    Tk_SavedOption items[TK_NUM_SAVED_OPTIONS];
				/* Items used to hold old values. */
    struct Tk_SavedOptions *nextPtr;
				/* Points to next structure in list; needed if
				 * too many options changed to hold all the
				 * old values in a single structure. NULL
				 * means no more structures. */







|
>




















<
|





|







<
<
<
<




















>

>
>







<
|

<
<
<
<
<
<
|
|
|
<
|

|

















|



<
<
<
<
<
<
<
<
<
<
<
<
<















>
|




|
|
|
|
|
>
>
>













<
|
<
<
<







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210




211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243






244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270













271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

313



314
315
316
317
318
319
320
    TK_OPTION_JUSTIFY,
    TK_OPTION_ANCHOR,
    TK_OPTION_SYNONYM,
    TK_OPTION_PIXELS,
    TK_OPTION_WINDOW,
    TK_OPTION_END,
    TK_OPTION_CUSTOM,
    TK_OPTION_STYLE,
    TK_OPTION_INDEX
} Tk_OptionType;

/*
 * Structures of the following type are used by widgets to specify their
 * configuration options. Typically each widget has a static array of these
 * structures, where each element of the array describes a single
 * configuration option. The array is passed to Tk_CreateOptionTable.
 */

typedef struct Tk_OptionSpec {
    Tk_OptionType type;		/* Type of option, such as TK_OPTION_COLOR;
				 * see definitions above. Last option in table
				 * must have type TK_OPTION_END. */
    const char *optionName;	/* Name used to specify option in Tcl
				 * commands. */
    const char *dbName;		/* Name for option in option database. */
    const char *dbClass;	/* Class for option in database. */
    const char *defValue;	/* Default value for option if not specified
				 * in command line, the option database, or
				 * the system. */

    Tcl_Size objOffset;		/* Where in record to store a Tcl_Obj * that
				 * holds the value of this option, specified
				 * as an offset in bytes from the start of the
				 * record. Use the offsetof macro to generate
				 * values for this. TCL_INDEX_NONE means don't
				 * store the Tcl_Obj in the record. */
    Tcl_Size internalOffset;		/* Where in record to store the internal
				 * representation of the value of this option,
				 * such as an int or XColor *. This field is
				 * specified as an offset in bytes from the
				 * start of the record. Use the offsetof
				 * macro to generate values for it.
				 * TCL_INDEX_NONE means don't store the
				 * internal representation in the record. */




    int flags;			/* Any combination of the values defined
				 * below. */
    const void *clientData;	/* An alternate place to put option-specific
				 * data. Used for the monochrome default value
				 * for colors, etc. */
    int typeMask;		/* An arbitrary bit mask defined by the class
				 * manager; typically bits correspond to
				 * certain kinds of options such as all those
				 * that require a redisplay when they change.
				 * Tk_SetOptions returns the bit-wise OR of
				 * the typeMasks of all options that were
				 * changed. */
} Tk_OptionSpec;

/*
 * Flag values for Tk_OptionSpec structures. These flags are shared by
 * Tk_ConfigSpec structures, so be sure to coordinate any changes carefully.
 */

#define TK_OPTION_NULL_OK		(1 << 0)
#define TK_OPTION_JUSTIFY_FULL		(1 << 1)
#define TK_OPTION_DONT_SET_DEFAULT	(1 << 3)
#define TK_OPTION_VAR(type)		((sizeof(type) < 2 * sizeof(int)) ? ((int)(sizeof(type)&(sizeof(int)-1))<<6) : (3<<6))
#define TK_OPTION_ENUM_VAR		TK_OPTION_VAR(Tk_OptionType)

/*
 * The following structure and function types are used by TK_OPTION_CUSTOM
 * options; the structure holds pointers to the functions needed by the Tk
 * option config code to handle a custom option.
 */


typedef int (Tk_CustomOptionSetProc) (void *clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec,






	Tcl_Size offset, char *saveInternalPtr, int flags);
typedef Tcl_Obj *(Tk_CustomOptionGetProc) (void *clientData,
	Tk_Window tkwin, char *widgRec, Tcl_Size offset);

typedef void (Tk_CustomOptionRestoreProc) (void *clientData,
	Tk_Window tkwin, char *internalPtr, char *saveInternalPtr);
typedef void (Tk_CustomOptionFreeProc) (void *clientData, Tk_Window tkwin,
	char *internalPtr);

typedef struct Tk_ObjCustomOption {
    const char *name;		/* Name of the custom option. */
    Tk_CustomOptionSetProc *setProc;
				/* Function to use to set a record's option
				 * value from a Tcl_Obj */
    Tk_CustomOptionGetProc *getProc;
				/* Function to use to get a Tcl_Obj
				 * representation from an internal
				 * representation of an option. */
    Tk_CustomOptionRestoreProc *restoreProc;
				/* Function to use to restore a saved value
				 * for the internal representation. */
    Tk_CustomOptionFreeProc *freeProc;
				/* Function to use to free the internal
				 * representation of an option. */
    void *clientData;	/* Arbitrary one-word value passed to the
				 * handling procs. */
} Tk_ObjCustomOption;














/*
 * The following two structures are used for error handling. When config
 * options are being modified, the old values are saved in a Tk_SavedOptions
 * structure. If an error occurs, then the contents of the structure can be
 * used to restore all of the old values. The contents of this structure are
 * for the private use Tk. No-one outside Tk should ever read or write any of
 * the fields of these structures.
 */

typedef struct Tk_SavedOption {
    struct TkOption *optionPtr;	/* Points to information that describes the
				 * option. */
    Tcl_Obj *valuePtr;		/* The old value of the option, in the form of
				 * a Tcl object; may be NULL if the value was
				 * not saved as an object. */
#if TCL_MAJOR_VERSION > 8
    long double internalForm;	/* The old value of the option, in some
				 * internal representation such as an int or
				 * (XColor *). Valid only if the field
				 * optionPtr->specPtr->objOffset is -1. The
				 * space must be large enough to accommodate a
				 * long double, a double, a long, or a pointer;
				 * right now it looks like a long double (i.e., 16
				 * bytes) is big enough. Also, using a long double
				 * guarantees that the field is properly aligned
				 * for storing large values. */
#else
    double internalForm;
#endif
} Tk_SavedOption;

#ifdef TCL_MEM_DEBUG
#   define TK_NUM_SAVED_OPTIONS 2
#else
#   define TK_NUM_SAVED_OPTIONS 20
#endif

typedef struct Tk_SavedOptions {
    void *recordPtr;		/* The data structure in which to restore
				 * configuration options. */
    Tk_Window tkwin;		/* Window associated with recordPtr; needed to
				 * restore certain options. */

    Tcl_Size numItems;		/* The number of valid items in items field. */



    Tk_SavedOption items[TK_NUM_SAVED_OPTIONS];
				/* Items used to hold old values. */
    struct Tk_SavedOptions *nextPtr;
				/* Points to next structure in list; needed if
				 * too many options changed to hold all the
				 * old values in a single structure. NULL
				 * means no more structures. */
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
/*
 * This is a temporary flag used while tkObjConfig and new widgets are in
 * development.
 */

#ifndef __NO_OLD_CONFIG

#if TCL_MAJOR_VERSION > 8
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, size_t offset);
typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, size_t offset, Tcl_FreeProc **freeProcPtr);
#else
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, int offset);
typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);
#endif

typedef struct Tk_CustomOption {
    Tk_OptionParseProc *parseProc;
				/* Procedure to call to parse an option and
				 * store it in converted form. */
    Tk_OptionPrintProc *printProc;
				/* Procedure to return a printable string
				 * describing an existing option. */
    ClientData clientData;	/* Arbitrary one-word value used by option
				 * parser: passed to parseProc and
				 * printProc. */
} Tk_CustomOption;

/*
 * Structure used to specify information for Tk_ConfigureWidget. Each
 * structure gives complete information for one option, including how the







<
|
|
|
<
<
<
<
<
|
<








|







330
331
332
333
334
335
336

337
338
339





340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/*
 * This is a temporary flag used while tkObjConfig and new widgets are in
 * development.
 */

#ifndef __NO_OLD_CONFIG


typedef int (Tk_OptionParseProc) (void *clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset);
typedef const char *(Tk_OptionPrintProc) (void *clientData,





	Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr);


typedef struct Tk_CustomOption {
    Tk_OptionParseProc *parseProc;
				/* Procedure to call to parse an option and
				 * store it in converted form. */
    Tk_OptionPrintProc *printProc;
				/* Procedure to return a printable string
				 * describing an existing option. */
    void *clientData;	/* Arbitrary one-word value used by option
				 * parser: passed to parseProc and
				 * printProc. */
} Tk_CustomOption;

/*
 * Structure used to specify information for Tk_ConfigureWidget. Each
 * structure gives complete information for one option, including how the
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
				 * must have type TK_CONFIG_END. */
    const char *argvName;	/* Switch used to specify option in argv. NULL
				 * means this spec is part of a group. */
    Tk_Uid dbName;		/* Name for option in option database. */
    Tk_Uid dbClass;		/* Class for option in database. */
    Tk_Uid defValue;		/* Default value for option if not specified
				 * in command line or database. */
#if TCL_MAJOR_VERSION > 8
    size_t offset;			/* Where in widget record to store value; use
				 * offsetof macro to generate values for
				 * this. */
#else
    int offset;
#endif
    int specFlags;		/* Any combination of the values defined
				 * below; other bits are used internally by
				 * tkConfig.c. */
    const Tk_CustomOption *customPtr;
				/* If type is TK_CONFIG_CUSTOM then this is a
				 * pointer to info about how to parse and
				 * print the option. Otherwise it is







<
|


<
<
<







364
365
366
367
368
369
370

371
372
373



374
375
376
377
378
379
380
				 * must have type TK_CONFIG_END. */
    const char *argvName;	/* Switch used to specify option in argv. NULL
				 * means this spec is part of a group. */
    Tk_Uid dbName;		/* Name for option in option database. */
    Tk_Uid dbClass;		/* Class for option in database. */
    Tk_Uid defValue;		/* Default value for option if not specified
				 * in command line or database. */

    Tcl_Size offset;			/* Where in widget record to store value; use
				 * offsetof macro to generate values for
				 * this. */



    int specFlags;		/* Any combination of the values defined
				 * below; other bits are used internally by
				 * tkConfig.c. */
    const Tk_CustomOption *customPtr;
				/* If type is TK_CONFIG_CUSTOM then this is a
				 * pointer to info about how to parse and
				 * print the option. Otherwise it is
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
 * (internal-use-only flags are defined there).
 */

#define TK_CONFIG_NULL_OK		(1 << 0)
#define TK_CONFIG_COLOR_ONLY		(1 << 1)
#define TK_CONFIG_MONO_ONLY		(1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT	(1 << 3)
#ifndef TK_NO_DEPRECATED
#  define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)
#endif /* !TK_NO_DEPRECATED */
#define TK_CONFIG_USER_BIT		0x100
#endif /* __NO_OLD_CONFIG */

/*
 * Structure used to specify how to handle argv options.
 */








<
<
<







410
411
412
413
414
415
416



417
418
419
420
421
422
423
 * (internal-use-only flags are defined there).
 */

#define TK_CONFIG_NULL_OK		(1 << 0)
#define TK_CONFIG_COLOR_ONLY		(1 << 1)
#define TK_CONFIG_MONO_ONLY		(1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT	(1 << 3)



#define TK_CONFIG_USER_BIT		0x100
#endif /* __NO_OLD_CONFIG */

/*
 * Structure used to specify how to handle argv options.
 */

545
546
547
548
549
550
551

552
553
554
555
556
557
558
559
560
561

562




563
564
565
566
567
568
569
#define TK_NOTIFY_SHARE		20

/*
 * Enumerated type for describing a point by which to anchor something:
 */

typedef enum {

    TK_ANCHOR_N, TK_ANCHOR_NE, TK_ANCHOR_E, TK_ANCHOR_SE,
    TK_ANCHOR_S, TK_ANCHOR_SW, TK_ANCHOR_W, TK_ANCHOR_NW,
    TK_ANCHOR_CENTER
} Tk_Anchor;

/*
 * Enumerated type for describing a style of justification:
 */

typedef enum {

    TK_JUSTIFY_LEFT, TK_JUSTIFY_RIGHT, TK_JUSTIFY_CENTER




} Tk_Justify;

/*
 * The following structure is used by Tk_GetFontMetrics() to return
 * information about the properties of a Tk_Font.
 */








>










>
|
>
>
>
>







510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
#define TK_NOTIFY_SHARE		20

/*
 * Enumerated type for describing a point by which to anchor something:
 */

typedef enum {
    TK_ANCHOR_NULL = -1,
    TK_ANCHOR_N, TK_ANCHOR_NE, TK_ANCHOR_E, TK_ANCHOR_SE,
    TK_ANCHOR_S, TK_ANCHOR_SW, TK_ANCHOR_W, TK_ANCHOR_NW,
    TK_ANCHOR_CENTER
} Tk_Anchor;

/*
 * Enumerated type for describing a style of justification:
 */

typedef enum {
    TK_JUSTIFY_NULL = -1,
    TK_JUSTIFY_LEFT,
    TK_JUSTIFY_RIGHT,
    TK_JUSTIFY_CENTER,
    TK_JUSTIFY_FULL,
    TK_JUSTIFY_NUMERIC = TK_JUSTIFY_FULL
} Tk_Justify;

/*
 * The following structure is used by Tk_GetFontMetrics() to return
 * information about the properties of a Tk_Font.
 */

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623

/*
 * Widget class procedures used to implement platform specific widget
 * behavior.
 */

typedef Window (Tk_ClassCreateProc) (Tk_Window tkwin, Window parent,
	ClientData instanceData);
typedef void (Tk_ClassWorldChangedProc) (ClientData instanceData);
typedef void (Tk_ClassModalProc) (Tk_Window tkwin, XEvent *eventPtr);

typedef struct Tk_ClassProcs {
#if TCL_MAJOR_VERSION > 8
    size_t size;
#else
    unsigned int size;
#endif
    Tk_ClassWorldChangedProc *worldChangedProc;
				/* Procedure to invoke when the widget needs
				 * to respond in some way to a change in the
				 * world (font changes, etc.) */
    Tk_ClassCreateProc *createProc;
				/* Procedure to invoke when the platform-
				 * dependent window needs to be created. */







|
|



<
|
<
<
<







571
572
573
574
575
576
577
578
579
580
581
582

583



584
585
586
587
588
589
590

/*
 * Widget class procedures used to implement platform specific widget
 * behavior.
 */

typedef Window (Tk_ClassCreateProc) (Tk_Window tkwin, Window parent,
	void *instanceData);
typedef void (Tk_ClassWorldChangedProc) (void *instanceData);
typedef void (Tk_ClassModalProc) (Tk_Window tkwin, XEvent *eventPtr);

typedef struct Tk_ClassProcs {

    Tcl_Size size;



    Tk_ClassWorldChangedProc *worldChangedProc;
				/* Procedure to invoke when the widget needs
				 * to respond in some way to a change in the
				 * world (font changes, etc.) */
    Tk_ClassCreateProc *createProc;
				/* Procedure to invoke when the platform-
				 * dependent window needs to be created. */
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
 * (or NULL if the structure is NULL).
 *
 * A more general version of this function may be useful if other
 * size-versioned structure pop up in the future:
 *
 *	#define Tk_GetField(name, who, which) \
 *	    (((who) == NULL) ? NULL :
 *	    (((who)->size <= offsetof(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((procs)->size <= offsetof(Tk_ClassProcs, which)) ? NULL:(procs)->which))

/*
 * Each geometry manager (the packer, the placer, etc.) is represented by a
 * structure of the following form, which indicates procedures to invoke in
 * the geometry manager to carry out certain functions.
 */

#define Tk_GeomLostSlaveProc Tk_GeomLostContentProc
typedef void (Tk_GeomRequestProc) (ClientData clientData, Tk_Window tkwin);
typedef void (Tk_GeomLostContentProc) (ClientData clientData, Tk_Window tkwin);

typedef struct Tk_GeomMgr {
    const char *name;		/* Name of the geometry manager (command used
				 * to invoke it, or name of widget class that
				 * allows embedded widgets). */
    Tk_GeomRequestProc *requestProc;
				/* Procedure to invoke when a content's







|




|








|
|







601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
 * (or NULL if the structure is NULL).
 *
 * A more general version of this function may be useful if other
 * size-versioned structure pop up in the future:
 *
 *	#define Tk_GetField(name, who, which) \
 *	    (((who) == NULL) ? NULL :
 *	    (((size_t)(who)->size <= offsetof(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((size_t)(procs)->size <= offsetof(Tk_ClassProcs, which)) ? NULL:(procs)->which))

/*
 * Each geometry manager (the packer, the placer, etc.) is represented by a
 * structure of the following form, which indicates procedures to invoke in
 * the geometry manager to carry out certain functions.
 */

#define Tk_GeomLostSlaveProc Tk_GeomLostContentProc
typedef void (Tk_GeomRequestProc) (void *clientData, Tk_Window tkwin);
typedef void (Tk_GeomLostContentProc) (void *clientData, Tk_Window tkwin);

typedef struct Tk_GeomMgr {
    const char *name;		/* Name of the geometry manager (command used
				 * to invoke it, or name of widget class that
				 * allows embedded widgets). */
    Tk_GeomRequestProc *requestProc;
				/* Procedure to invoke when a content's
686
687
688
689
690
691
692

693
694

695
696
697
698
699
700
701
 *----------------------------------------------------------------------
 */

#define VirtualEvent	    (MappingNotify + 1)
#define ActivateNotify	    (MappingNotify + 2)
#define DeactivateNotify    (MappingNotify + 3)
#define MouseWheelEvent     (MappingNotify + 4)

#define TK_LASTEVENT	    (MappingNotify + 5)


#define MouseWheelMask	    (1L << 28)
#define ActivateMask	    (1L << 29)
#define VirtualEventMask    (1L << 30)

/*
 * A virtual event shares most of its fields with the XKeyEvent and
 * XButtonEvent structures. 99% of the time a virtual event will be an







>
|

>







653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
 *----------------------------------------------------------------------
 */

#define VirtualEvent	    (MappingNotify + 1)
#define ActivateNotify	    (MappingNotify + 2)
#define DeactivateNotify    (MappingNotify + 3)
#define MouseWheelEvent     (MappingNotify + 4)
#define TouchpadScroll      (MappingNotify + 5)
#define TK_LASTEVENT	    (MappingNotify + 6)

#define TouchpadScrollMask  (1L << 27)
#define MouseWheelMask	    (1L << 28)
#define ActivateMask	    (1L << 29)
#define VirtualEventMask    (1L << 30)

/*
 * A virtual event shares most of its fields with the XKeyEvent and
 * XButtonEvent structures. 99% of the time a virtual event will be an
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
    (((Tk_FakeWin *) (tkwin))->flags & TK_WIN_MANAGED)
#define Tk_TopWinHierarchy(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY)
#define Tk_IsManageable(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE)
#define Tk_ReqWidth(tkwin)	(((Tk_FakeWin *) (tkwin))->reqWidth)
#define Tk_ReqHeight(tkwin)	(((Tk_FakeWin *) (tkwin))->reqHeight)
#ifndef TK_NO_DEPRECATED
#define Tk_InternalBorderWidth(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#endif /* !TK_NO_DEPRECATED */
#define Tk_InternalBorderLeft(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#define Tk_InternalBorderRight(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderRight)
#define Tk_InternalBorderTop(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderTop)
#define Tk_InternalBorderBottom(tkwin) \







<
<
<
<







750
751
752
753
754
755
756




757
758
759
760
761
762
763
    (((Tk_FakeWin *) (tkwin))->flags & TK_WIN_MANAGED)
#define Tk_TopWinHierarchy(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY)
#define Tk_IsManageable(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE)
#define Tk_ReqWidth(tkwin)	(((Tk_FakeWin *) (tkwin))->reqWidth)
#define Tk_ReqHeight(tkwin)	(((Tk_FakeWin *) (tkwin))->reqHeight)




#define Tk_InternalBorderLeft(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#define Tk_InternalBorderRight(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderRight)
#define Tk_InternalBorderTop(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderTop)
#define Tk_InternalBorderBottom(tkwin) \
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
    XSetWindowAttributes atts;
    unsigned long dummy7;	/* dirtyAtts */
    unsigned int flags;
    char *dummy8;		/* handlerList */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIC dummy9;			/* inputContext */
#endif /* TK_USE_INPUT_METHODS */
    ClientData *dummy10;	/* tagPtr */
    int dummy11;		/* numTags */
    int dummy12;		/* optionLevel */
    char *dummy13;		/* selHandlerList */
    char *dummy14;		/* geomMgrPtr */
    ClientData dummy15;		/* geomData */
    int reqWidth, reqHeight;
    int internalBorderLeft;
    char *dummy16;		/* wmInfoPtr */
    char *dummy17;		/* classProcPtr */
    ClientData dummy18;		/* instanceData */
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)







|
|
|


|




|







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
    XSetWindowAttributes atts;
    unsigned long dummy7;	/* dirtyAtts */
    unsigned int flags;
    char *dummy8;		/* handlerList */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIC dummy9;			/* inputContext */
#endif /* TK_USE_INPUT_METHODS */
    void **dummy10;	/* tagPtr */
    Tcl_Size dummy11;		/* numTags */
    Tcl_Size dummy12;		/* optionLevel */
    char *dummy13;		/* selHandlerList */
    char *dummy14;		/* geomMgrPtr */
    void *dummy15;		/* geomData */
    int reqWidth, reqHeight;
    int internalBorderLeft;
    char *dummy16;		/* wmInfoPtr */
    char *dummy17;		/* classProcPtr */
    void *dummy18;		/* instanceData */
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
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
 * structure. Each actual item is represented by a record with the following
 * stuff at its beginning, plus additional type-specific stuff after that.
 */

#define TK_TAG_SPACE 3

typedef struct Tk_Item {
#if TCL_MAJOR_VERSION > 8
    size_t id;		/* Unique identifier for this item (also
				 * serves as first tag for item). */
#else
    int id;
#endif
    struct Tk_Item *nextPtr;	/* Next in display list of all items in this
				 * canvas. Later items in list are drawn on
				 * top of earlier ones. */
    Tk_Uid staticTagSpace[TK_TAG_SPACE];
				/* Built-in space for limited # of tags. */
    Tk_Uid *tagPtr;		/* Pointer to array of tags. Usually points to
				 * staticTagSpace, but may point to malloc-ed
				 * space if there are lots of tags. */
#if TCL_MAJOR_VERSION > 8
    size_t tagSpace;		/* Total amount of tag space available at
				 * tagPtr. */
    size_t numTags;		/* Number of tag slots actually used at
				 * *tagPtr. */
#else
    int tagSpace, numTags;
#endif
    struct Tk_ItemType *typePtr;/* Table of procedures that implement this
				 * type of item. */
    int x1, y1, x2, y2;		/* Bounding box for item, in integer canvas
				 * units. Set by item-specific code and
				 * guaranteed to contain every pixel drawn in
				 * item. Item area includes x1 and y1 but not
				 * x2 and y2. */







<
|

<
<
<








<
|

|

<
<
<







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
 * structure. Each actual item is represented by a record with the following
 * stuff at its beginning, plus additional type-specific stuff after that.
 */

#define TK_TAG_SPACE 3

typedef struct Tk_Item {

    Tcl_Size id;		/* Unique identifier for this item (also
				 * serves as first tag for item). */



    struct Tk_Item *nextPtr;	/* Next in display list of all items in this
				 * canvas. Later items in list are drawn on
				 * top of earlier ones. */
    Tk_Uid staticTagSpace[TK_TAG_SPACE];
				/* Built-in space for limited # of tags. */
    Tk_Uid *tagPtr;		/* Pointer to array of tags. Usually points to
				 * staticTagSpace, but may point to malloc-ed
				 * space if there are lots of tags. */

    Tcl_Size tagSpace;		/* Total amount of tag space available at
				 * tagPtr. */
    Tcl_Size numTags;		/* Number of tag slots actually used at
				 * *tagPtr. */



    struct Tk_ItemType *typePtr;/* Table of procedures that implement this
				 * type of item. */
    int x1, y1, x2, y2;		/* Bounding box for item, in integer canvas
				 * units. Set by item-specific code and
				 * guaranteed to contain every pixel drawn in
				 * item. Item area includes x1 and y1 but not
				 * x2 and y2. */
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
#define TK_ITEM_DONT_REDRAW		2

/*
 * Records of the following type are used to describe a type of item (e.g.
 * lines, circles, etc.) that can form part of a canvas widget.
 */

#if defined(USE_OLD_CANVAS) && TCL_MAJOR_VERSION < 9
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv, int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, char *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, char *indexString, int *indexPtr);
#else
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[]);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[],
		    int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const argv[]);
#if TCL_MAJOR_VERSION > 8
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, size_t *indexPtr);
#else
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, int *indexPtr);
#endif
#endif /* USE_OLD_CANVAS */
typedef void	(Tk_ItemDeleteProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display);
typedef void	(Tk_ItemDisplayProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display, Drawable dst, int x, int y, int width,
		    int height);
typedef double	(Tk_ItemPointProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *pointPtr);
typedef int	(Tk_ItemAreaProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *rectPtr);
typedef int	(Tk_ItemPostscriptProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int prepass);
typedef void	(Tk_ItemRotateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double angleRadians);
typedef void	(Tk_ItemScaleProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double scaleX,
		    double scaleY);
typedef void	(Tk_ItemTranslateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double deltaX, double deltaY);
#if TCL_MAJOR_VERSION > 8
typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t index);
typedef size_t	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t offset, char *buffer, size_t maxBytes);
typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t first, size_t last);
#else
typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int index);
typedef int	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int offset, char *buffer, int maxBytes);
typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int first, int last);
#endif

#ifndef __NO_OLD_CONFIG

typedef struct Tk_ItemType {
    const char *name;		/* The name of this type of item, such as
				 * "line". */
#if TCL_MAJOR_VERSION > 8
    size_t itemSize;		/* Total amount of space needed for item's
				 * record. */
#else
    int itemSize;
#endif
    Tk_ItemCreateProc *createProc;
				/* Procedure to create a new item of this
				 * type. */
    const Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
				 * this type. Used for returning configuration
				 * info. */
    Tk_ItemConfigureProc *configProc;
				/* Procedure to call to change configuration
				 * options. */
    Tk_ItemCoordProc *coordProc;/* Procedure to call to get and set the item's
				 * coordinates. */
    Tk_ItemDeleteProc *deleteProc;
				/* Procedure to delete existing item of this
				 * type. */
    Tk_ItemDisplayProc *displayProc;
				/* Procedure to display items of this type. */
    int alwaysRedraw;		/* Non-zero means displayProc should be called
				 * even when the item has been moved
				 * off-screen. */
    Tk_ItemPointProc *pointProc;/* Computes distance from item to a given
				 * point. */
    Tk_ItemAreaProc *areaProc;	/* Computes whether item is inside, outside,
				 * or overlapping an area. */
    Tk_ItemPostscriptProc *postscriptProc;
				/* Procedure to write a Postscript description
				 * for items of this type. */







<

|

<
<
|
<
<
<
<
<
<
<
<
<


<
<
<
<
<
|
<

|

|
<
<


















<

<
<
<
<
<
<
<
|
|
|

|
<






<
|

<
<
<
















|
<
<







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
#define TK_ITEM_DONT_REDRAW		2

/*
 * Records of the following type are used to describe a type of item (e.g.
 * lines, circles, etc.) that can form part of a canvas widget.
 */


typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,


		    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[],









		    int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,





		    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[]);

typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Tcl_Size beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, Tcl_Size *indexPtr);


typedef void	(Tk_ItemDeleteProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display);
typedef void	(Tk_ItemDisplayProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display, Drawable dst, int x, int y, int width,
		    int height);
typedef double	(Tk_ItemPointProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *pointPtr);
typedef int	(Tk_ItemAreaProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *rectPtr);
typedef int	(Tk_ItemPostscriptProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int prepass);
typedef void	(Tk_ItemRotateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double angleRadians);
typedef void	(Tk_ItemScaleProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double scaleX,
		    double scaleY);
typedef void	(Tk_ItemTranslateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double deltaX, double deltaY);

typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,







		    Tcl_Size index);
typedef Tcl_Size (Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Tcl_Size offset, char *buffer, Tcl_Size maxBytes);
typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Tcl_Size first, Tcl_Size last);


#ifndef __NO_OLD_CONFIG

typedef struct Tk_ItemType {
    const char *name;		/* The name of this type of item, such as
				 * "line". */

    Tcl_Size itemSize;		/* Total amount of space needed for item's
				 * record. */



    Tk_ItemCreateProc *createProc;
				/* Procedure to create a new item of this
				 * type. */
    const Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
				 * this type. Used for returning configuration
				 * info. */
    Tk_ItemConfigureProc *configProc;
				/* Procedure to call to change configuration
				 * options. */
    Tk_ItemCoordProc *coordProc;/* Procedure to call to get and set the item's
				 * coordinates. */
    Tk_ItemDeleteProc *deleteProc;
				/* Procedure to delete existing item of this
				 * type. */
    Tk_ItemDisplayProc *displayProc;
				/* Procedure to display items of this type. */
    int flags;		/* Combination of TK_ALWAYS_REDRAW/TK_MOVABLE_POINTS */


    Tk_ItemPointProc *pointProc;/* Computes distance from item to a given
				 * point. */
    Tk_ItemAreaProc *areaProc;	/* Computes whether item is inside, outside,
				 * or overlapping an area. */
    Tk_ItemPostscriptProc *postscriptProc;
				/* Procedure to write a Postscript description
				 * for items of this type. */
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1194
				 * about a point. */
    int reserved2;		/* Carefully compatible with */
    char *reserved3;		/* Jan Nijtmans dash patch */
    char *reserved4;
} Tk_ItemType;

/*
 * Flag (used in the alwaysRedraw field) to say whether an item supports
 * point-level manipulation like the line and polygon items.
 */


#define TK_MOVABLE_POINTS	2

#endif /* __NO_OLD_CONFIG */

/*
 * The following structure provides information about the selection and the
 * insertion cursor. It is needed by only a few items, such as those that
 * display text. It is shared by the generic canvas code and the item-specific







|
<


>
|







1098
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
				 * about a point. */
    int reserved2;		/* Carefully compatible with */
    char *reserved3;		/* Jan Nijtmans dash patch */
    char *reserved4;
} Tk_ItemType;

/*
 * Possible flags for 'flags' field.

 */

#define TK_ALWAYS_REDRAW	1	/* item should be redrawn always*/
#define TK_MOVABLE_POINTS	2	/* item supports point-level manipulation */

#endif /* __NO_OLD_CONFIG */

/*
 * The following structure provides information about the selection and the
 * insertion cursor. It is needed by only a few items, such as those that
 * display text. It is shared by the generic canvas code and the item-specific
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
    int selBorderWidth;		/* Width of border around selection. Read-only
				 * to items. */
    XColor *selFgColorPtr;	/* Foreground color for selected text.
				 * Read-only to items. */
    Tk_Item *selItemPtr;	/* Pointer to selected item. NULL means
				 * selection isn't in this canvas. Writable by
				 * items. */
#if TCL_MAJOR_VERSION > 8
    size_t selectFirst;		/* Character index of first selected
				 * character. Writable by items. */
    size_t selectLast;		/* Character index of last selected character.
				 * Writable by items. */
#else
    int selectFirst, selectLast;
#endif
    Tk_Item *anchorItemPtr;	/* Item corresponding to "selectAnchor": not
				 * necessarily selItemPtr. Read-only to
				 * items. */
#if TCL_MAJOR_VERSION > 8
    size_t selectAnchor;		/* Character index of fixed end of selection
				 * (i.e. "select to" operation will use this
				 * as one end of the selection). Writable by
				 * items. */
#else
    int selectAnchor;
#endif
    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. Read-only to items. */
    int insertWidth;		/* Total width of insertion cursor. Read-only
				 * to items. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor.
				 * Read-only to items. */
    Tk_Item *focusItemPtr;	/* Item that currently has the input focus, or







<
|

|

<
<
<



<
|



<
<
<







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
    int selBorderWidth;		/* Width of border around selection. Read-only
				 * to items. */
    XColor *selFgColorPtr;	/* Foreground color for selected text.
				 * Read-only to items. */
    Tk_Item *selItemPtr;	/* Pointer to selected item. NULL means
				 * selection isn't in this canvas. Writable by
				 * items. */

    Tcl_Size selectFirst;		/* Character index of first selected
				 * character. Writable by items. */
    Tcl_Size selectLast;		/* Character index of last selected character.
				 * Writable by items. */



    Tk_Item *anchorItemPtr;	/* Item corresponding to "selectAnchor": not
				 * necessarily selItemPtr. Read-only to
				 * items. */

    Tcl_Size selectAnchor;		/* Character index of fixed end of selection
				 * (i.e. "select to" operation will use this
				 * as one end of the selection). Writable by
				 * items. */



    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. Read-only to items. */
    int insertWidth;		/* Total width of insertion cursor. Read-only
				 * to items. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor.
				 * Read-only to items. */
    Tk_Item *focusItemPtr;	/* Item that currently has the input focus, or
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
 *
 * Procedure prototypes and structures used for managing images:
 *
 *----------------------------------------------------------------------
 */

typedef struct Tk_ImageType Tk_ImageType;
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && defined(USE_OLD_IMAGE)
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc,
	char **argv, Tk_ImageType *typePtr, Tk_ImageModel model,
	ClientData *clientDataPtr);
#else
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, const char *name, int objc,
	Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageModel model,
	ClientData *clientDataPtr);
#endif /* USE_OLD_IMAGE */
typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData clientData);
typedef void (Tk_ImageDisplayProc) (ClientData clientData, Display *display,
	Drawable drawable, int imageX, int imageY, int width, int height,
	int drawableX, int drawableY);
typedef void (Tk_ImageFreeProc) (ClientData clientData, Display *display);
typedef void (Tk_ImageDeleteProc) (ClientData clientData);
typedef void (Tk_ImageChangedProc) (ClientData clientData, int x, int y,
	int width, int height, int imageWidth, int imageHeight);
typedef int (Tk_ImagePostscriptProc) (ClientData clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo,
	int x, int y, int width, int height, int prepass);

/*
 * The following structure represents a particular type of image (bitmap, xpm
 * image, etc.). It provides information common to all images of that type,
 * such as the type name and a collection of procedures in the image manager







<
|
<
<
<
<

|
<
|
|


|
|
|

|







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
 *
 * Procedure prototypes and structures used for managing images:
 *
 *----------------------------------------------------------------------
 */

typedef struct Tk_ImageType Tk_ImageType;

typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, const char *name, Tcl_Size objc,




	Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageModel model,
	void **clientDataPtr);

typedef void *(Tk_ImageGetProc) (Tk_Window tkwin, void *clientData);
typedef void (Tk_ImageDisplayProc) (void *clientData, Display *display,
	Drawable drawable, int imageX, int imageY, int width, int height,
	int drawableX, int drawableY);
typedef void (Tk_ImageFreeProc) (void *clientData, Display *display);
typedef void (Tk_ImageDeleteProc) (void *clientData);
typedef void (Tk_ImageChangedProc) (void *clientData, int x, int y,
	int width, int height, int imageWidth, int imageHeight);
typedef int (Tk_ImagePostscriptProc) (void *clientData,
	Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo,
	int x, int y, int width, int height, int prepass);

/*
 * The following structure represents a particular type of image (bitmap, xpm
 * image, etc.). It provides information common to all images of that type,
 * such as the type name and a collection of procedures in the image manager
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

/*
 * Procedure prototypes and structures used in reading and writing photo
 * images:
 */

typedef struct Tk_PhotoImageFormat Tk_PhotoImageFormat;
#ifdef USE_OLD_IMAGE
typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, char *fileName,
	char *formatString, int *widthPtr, int *heightPtr);
typedef int (Tk_ImageStringMatchProc) (char *string, char *formatString,
	int *widthPtr, int *heightPtr);
typedef int (Tk_ImageFileReadProc) (Tcl_Interp *interp, Tcl_Channel chan,
	char *fileName, char *formatString, Tk_PhotoHandle imageHandle,
	int destX, int destY, int width, int height, int srcX, int srcY);
typedef int (Tk_ImageStringReadProc) (Tcl_Interp *interp, char *string,
	char *formatString, Tk_PhotoHandle imageHandle, int destX, int destY,
	int width, int height, int srcX, int srcY);
typedef int (Tk_ImageFileWriteProc) (Tcl_Interp *interp, char *fileName,
	char *formatString, Tk_PhotoImageBlock *blockPtr);
typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp,
	Tcl_DString *dataPtr, char *formatString, Tk_PhotoImageBlock *blockPtr);
#else
typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, const char *fileName,
	Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp);
typedef int (Tk_ImageStringMatchProc) (Tcl_Obj *dataObj, Tcl_Obj *format,
	int *widthPtr, int *heightPtr, Tcl_Interp *interp);
typedef int (Tk_ImageFileReadProc) (Tcl_Interp *interp, Tcl_Channel chan,
	const char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle,
	int destX, int destY, int width, int height, int srcX, int srcY);
typedef int (Tk_ImageStringReadProc) (Tcl_Interp *interp, Tcl_Obj *dataObj,
	Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY,
	int width, int height, int srcX, int srcY);
typedef int (Tk_ImageFileWriteProc) (Tcl_Interp *interp, const char *fileName,
	Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, Tcl_Obj *format,
	Tk_PhotoImageBlock *blockPtr);
#endif /* USE_OLD_IMAGE */






























/*
 * The following structure represents a particular file format for storing
 * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image
 * files of that format to be recognized and read into a photo image.
 */








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

/*
 * Procedure prototypes and structures used in reading and writing photo
 * images:
 */

typedef struct Tk_PhotoImageFormat Tk_PhotoImageFormat;
















typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, const char *fileName,
	Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp);
typedef int (Tk_ImageStringMatchProc) (Tcl_Obj *dataObj, Tcl_Obj *format,
	int *widthPtr, int *heightPtr, Tcl_Interp *interp);
typedef int (Tk_ImageFileReadProc) (Tcl_Interp *interp, Tcl_Channel chan,
	const char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle,
	int destX, int destY, int width, int height, int srcX, int srcY);
typedef int (Tk_ImageStringReadProc) (Tcl_Interp *interp, Tcl_Obj *dataObj,
	Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY,
	int width, int height, int srcX, int srcY);
typedef int (Tk_ImageFileWriteProc) (Tcl_Interp *interp, const char *fileName,
	Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, Tcl_Obj *format,
	Tk_PhotoImageBlock *blockPtr);

/*
 * The following alternate definitions are used with the Tk8.7 file format
 * supporting a metadata dict, internal dstring and close file flag
 */

typedef struct Tk_PhotoImageFormatVersion3 Tk_PhotoImageFormatVersion3;
typedef int (Tk_ImageFileMatchProcVersion3) (Tcl_Interp *interp,
	Tcl_Channel chan, const char *fileName, Tcl_Obj *format,
	Tcl_Obj *metadataIn, int *widthPtr, int *heightPtr,
	Tcl_Obj *metadataOut);
typedef int (Tk_ImageStringMatchProcVersion3) (Tcl_Interp *interp,
	Tcl_Obj *dataObj, Tcl_Obj *format, Tcl_Obj *metadataIn, int *widthPtr,
	int *heightPtr, Tcl_Obj *metadataOut);
typedef int (Tk_ImageFileReadProcVersion3) (Tcl_Interp *interp,
	Tcl_Channel chan,
	const char *fileName, Tcl_Obj *format, Tcl_Obj *metadataIn,
	Tk_PhotoHandle imageHandle,
	int destX, int destY, int width, int height, int srcX, int srcY,
	Tcl_Obj *metadataOut);
typedef int (Tk_ImageStringReadProcVersion3) (Tcl_Interp *interp,
	Tcl_Obj *dataObj, Tcl_Obj *format, Tcl_Obj *metadataIn,
	Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height,
	int srcX, int srcY, Tcl_Obj *metadataOut);
typedef int (Tk_ImageFileWriteProcVersion3) (Tcl_Interp *interp,
	const char *fileName, Tcl_Obj *format, Tcl_Obj *metadataIn,
	Tk_PhotoImageBlock *blockPtr);
typedef int (Tk_ImageStringWriteProcVersion3) (Tcl_Interp *interp,
	Tcl_Obj *format, Tcl_Obj *metadataIn, Tk_PhotoImageBlock *blockPtr);


/*
 * The following structure represents a particular file format for storing
 * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image
 * files of that format to be recognized and read into a photo image.
 */

1466
1467
1468
1469
1470
1471
1472
































1473
1474
1475
1476
1477
1478
1479
				 * representation of the data in a photo
				 * image.*/
    struct Tk_PhotoImageFormat *nextPtr;
				/* Next in list of all photo image formats
				 * currently known. Filled in by Tk, not by
				 * image format handler. */
};

































/*
 *----------------------------------------------------------------------
 *
 * Procedure prototypes and structures used for managing styles:
 *
 *----------------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
				 * representation of the data in a photo
				 * image.*/
    struct Tk_PhotoImageFormat *nextPtr;
				/* Next in list of all photo image formats
				 * currently known. Filled in by Tk, not by
				 * image format handler. */
};

/*
 * The following structure is the same plus added support for the metadata
 * structure.
 */

struct Tk_PhotoImageFormatVersion3 {
    const char *name;		/* Name of image file format */
    Tk_ImageFileMatchProcVersion3 *fileMatchProc;
				/* Procedure to call to determine whether an
				 * image file matches this format. */
    Tk_ImageStringMatchProcVersion3 *stringMatchProc;
				/* Procedure to call to determine whether the
				 * data in a string matches this format. */
    Tk_ImageFileReadProcVersion3 *fileReadProc;
				/* Procedure to call to read data from an
				 * image file into a photo image. */
    Tk_ImageStringReadProcVersion3 *stringReadProc;
				/* Procedure to call to read data from a
				 * string into a photo image. */
    Tk_ImageFileWriteProcVersion3 *fileWriteProc;
				/* Procedure to call to write data from a
				 * photo image to a file. */
    Tk_ImageStringWriteProcVersion3 *stringWriteProc;
				/* Procedure to call to obtain a string
				 * representation of the data in a photo
				 * image.*/
    struct Tk_PhotoImageFormatVersion3 *nextPtr;
				/* Next in list of all photo image formats
				 * currently known. Filled in by Tk, not by
				 * image format handler. */
};

/*
 *----------------------------------------------------------------------
 *
 * Procedure prototypes and structures used for managing styles:
 *
 *----------------------------------------------------------------------
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
#define TK_STYLE_VERSION        TK_STYLE_VERSION_1

/*
 * The following structures and prototypes are used as static templates to
 * declare widget elements.
 */

typedef void (Tk_GetElementSizeProc) (ClientData clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int width,
	int height, int inner, int *widthPtr, int *heightPtr);
typedef void (Tk_GetElementBoxProc) (ClientData clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int x, int y,
	int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr,
	int *heightPtr);
typedef int (Tk_GetElementBorderWidthProc) (ClientData clientData,
	char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin);
typedef void (Tk_DrawElementProc) (ClientData clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, Drawable d, int x,
	int y, int width, int height, int state);

typedef struct Tk_ElementOptionSpec {
    char *name;			/* Name of the required option. */
    Tk_OptionType type;		/* Accepted option type. TK_OPTION_END means
				 * any. */







|


|



|

|







1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
#define TK_STYLE_VERSION        TK_STYLE_VERSION_1

/*
 * The following structures and prototypes are used as static templates to
 * declare widget elements.
 */

typedef void (Tk_GetElementSizeProc) (void *clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int width,
	int height, int inner, int *widthPtr, int *heightPtr);
typedef void (Tk_GetElementBoxProc) (void *clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int x, int y,
	int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr,
	int *heightPtr);
typedef int (Tk_GetElementBorderWidthProc) (void *clientData,
	char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin);
typedef void (Tk_DrawElementProc) (void *clientData, char *recordPtr,
	const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, Drawable d, int x,
	int y, int width, int height, int state);

typedef struct Tk_ElementOptionSpec {
    char *name;			/* Name of the required option. */
    Tk_OptionType type;		/* Accepted option type. TK_OPTION_END means
				 * any. */
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
#define TK_ELEMENT_STATE_FOCUS          1<<2
#define TK_ELEMENT_STATE_PRESSED        1<<3

/*
 *----------------------------------------------------------------------
 *
 * The definitions below provide backward compatibility for functions and
 * types related to event handling that used to be in Tk but have moved to
 * Tcl.
 *
 *----------------------------------------------------------------------
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#define TK_READABLE		TCL_READABLE
#define TK_WRITABLE		TCL_WRITABLE
#define TK_EXCEPTION		TCL_EXCEPTION

#define TK_DONT_WAIT		TCL_DONT_WAIT
#define TK_X_EVENTS		TCL_WINDOW_EVENTS
#define TK_WINDOW_EVENTS	TCL_WINDOW_EVENTS
#define TK_FILE_EVENTS		TCL_FILE_EVENTS
#define TK_TIMER_EVENTS		TCL_TIMER_EVENTS
#define TK_IDLE_EVENTS		TCL_IDLE_EVENTS
#define TK_ALL_EVENTS		TCL_ALL_EVENTS

#define Tk_IdleProc		Tcl_IdleProc
#define Tk_FileProc		Tcl_FileProc
#define Tk_TimerProc		Tcl_TimerProc
#define Tk_TimerToken		Tcl_TimerToken

#define Tk_BackgroundError	Tcl_BackgroundError
#define Tk_CancelIdleCall	Tcl_CancelIdleCall
#define Tk_CreateFileHandler	Tcl_CreateFileHandler
#define Tk_CreateTimerHandler	Tcl_CreateTimerHandler
#define Tk_DeleteFileHandler	Tcl_DeleteFileHandler
#define Tk_DeleteTimerHandler	Tcl_DeleteTimerHandler
#define Tk_DoOneEvent		Tcl_DoOneEvent
#define Tk_DoWhenIdle		Tcl_DoWhenIdle
#define Tk_Sleep		Tcl_Sleep

/* Additional stuff that has moved to Tcl: */

#define Tk_EventuallyFree	Tcl_EventuallyFree
#define Tk_FreeProc		Tcl_FreeProc
#define Tk_Preserve		Tcl_Preserve
#define Tk_Release		Tcl_Release
#endif

/* Removed Tk_Main, use macro instead */
#if defined(_WIN32) || defined(__CYGWIN__)
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(0), (Tcl_CreateInterp)()))
#else
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)()))
#endif
const char *		Tk_InitStubs(Tcl_Interp *interp, const char *version,
				int exact);
EXTERN const char *	Tk_PkgInitStubsCheck(Tcl_Interp *interp,
				const char *version, int exact);

#ifndef USE_TK_STUBS
#define Tk_InitStubs(interp, version, exact) \
    Tk_PkgInitStubsCheck(interp, version, exact)
#endif /* USE_TK_STUBS */

#define Tk_InitImageArgs(interp, argc, argv) /**/

/*
 *----------------------------------------------------------------------
 *
 * Additional procedure types defined by Tk.
 *
 *----------------------------------------------------------------------
 */

typedef int (Tk_ErrorProc) (ClientData clientData, XErrorEvent *errEventPtr);
typedef void (Tk_EventProc) (ClientData clientData, XEvent *eventPtr);
typedef int (Tk_GenericProc) (ClientData clientData, XEvent *eventPtr);
typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr);
typedef int (Tk_GetSelProc) (ClientData clientData, Tcl_Interp *interp,
	const char *portion);
typedef void (Tk_LostSelProc) (ClientData clientData);
typedef Tk_RestrictAction (Tk_RestrictProc) (ClientData clientData,
	XEvent *eventPtr);
#if TCL_MAJOR_VERSION > 8
typedef size_t (Tk_SelectionProc) (ClientData clientData, size_t offset,
	char *buffer, size_t maxBytes);
#else
typedef int (Tk_SelectionProc) (ClientData clientData, int offset,
	char *buffer, int maxBytes);
#endif

/*
 *----------------------------------------------------------------------
 *
 * Platform independent exported procedures and variables.
 *
 *----------------------------------------------------------------------
 */

#include "tkDecls.h"

#ifdef USE_OLD_IMAGE
#undef Tk_CreateImageType
#define Tk_CreateImageType		Tk_CreateOldImageType
#undef Tk_CreatePhotoImageFormat
#define Tk_CreatePhotoImageFormat	Tk_CreateOldPhotoImageFormat
#endif /* USE_OLD_IMAGE */

/*
 *----------------------------------------------------------------------
 *
 * Allow users to say that they don't want to alter their source to add extra
 * arguments to Tk_PhotoPutBlock() et al.
 *
 * This goes after the inclusion of the stubbed-decls so that the declarations
 * of what is actually there can be correct.
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
#   ifdef Tk_PhotoPutBlock
#	undef Tk_PhotoPutBlock
#   endif
#   define Tk_PhotoPutBlock		Tk_PhotoPutBlock_NoComposite
#   ifdef Tk_PhotoPutZoomedBlock
#	undef Tk_PhotoPutZoomedBlock
#   endif
#   define Tk_PhotoPutZoomedBlock	Tk_PhotoPutZoomedBlock_NoComposite
#   define USE_PANIC_ON_PHOTO_ALLOC_FAILURE
#else /* !USE_COMPOSITELESS_PHOTO_PUT_BLOCK */
#   ifdef USE_PANIC_ON_PHOTO_ALLOC_FAILURE
#	ifdef Tk_PhotoPutBlock
#	    undef Tk_PhotoPutBlock
#	endif
#	define Tk_PhotoPutBlock		Tk_PhotoPutBlock_Panic
#	ifdef Tk_PhotoPutZoomedBlock
#	    undef Tk_PhotoPutZoomedBlock
#	endif
#	define Tk_PhotoPutZoomedBlock	Tk_PhotoPutZoomedBlock_Panic
#   endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */
#endif /* USE_COMPOSITELESS_PHOTO_PUT_BLOCK */
#ifdef USE_PANIC_ON_PHOTO_ALLOC_FAILURE
#   ifdef Tk_PhotoExpand
#	undef Tk_PhotoExpand
#   endif
#   define Tk_PhotoExpand		Tk_PhotoExpand_Panic
#   ifdef Tk_PhotoSetSize
#	undef Tk_PhotoSetSize
#   endif
#   define Tk_PhotoSetSize		Tk_PhotoSetSize_Panic
#endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */
#endif /* !TK_NO_DEPRECATED */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* RC_INVOKED */

/*
 * end block for C++







|
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<









|
|
|

|

|
|

<
<
<
<
|
|
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
#define TK_ELEMENT_STATE_FOCUS          1<<2
#define TK_ELEMENT_STATE_PRESSED        1<<3

/*
 *----------------------------------------------------------------------
 *
 * The definitions below provide backward compatibility for functions and
 * types that used to be in Tk but have moved to Tcl.

 *
 *----------------------------------------------------------------------
 */





































/* Removed Tk_Main, use macro instead */
#if defined(_WIN32) || defined(__CYGWIN__)
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(0), (Tcl_CreateInterp)()))
#else
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)()))
#endif
const char *		Tk_InitStubs(Tcl_Interp *interp, const char *version,
				int exact);
EXTERN const char *	Tk_PkgInitStubsCheck(Tcl_Interp *interp,
				const char *version, int exact);

#ifndef USE_TK_STUBS
#define Tk_InitStubs(interp, version, exact) \
    Tk_PkgInitStubsCheck(interp, version, exact)
#endif /* USE_TK_STUBS */



/*
 *----------------------------------------------------------------------
 *
 * Additional procedure types defined by Tk.
 *
 *----------------------------------------------------------------------
 */

typedef int (Tk_ErrorProc) (void *clientData, XErrorEvent *errEventPtr);
typedef void (Tk_EventProc) (void *clientData, XEvent *eventPtr);
typedef int (Tk_GenericProc) (void *clientData, XEvent *eventPtr);
typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr);
typedef int (Tk_GetSelProc) (void *clientData, Tcl_Interp *interp,
	const char *portion);
typedef void (Tk_LostSelProc) (void *clientData);
typedef Tk_RestrictAction (Tk_RestrictProc) (void *clientData,
	XEvent *eventPtr);




typedef Tcl_Size (Tk_SelectionProc) (void *clientData, Tcl_Size offset,
	char *buffer, Tcl_Size maxBytes);


/*
 *----------------------------------------------------------------------
 *
 * Platform independent exported procedures and variables.
 *
 *----------------------------------------------------------------------
 */

#include "tkDecls.h"





















































#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* RC_INVOKED */

/*
 * end block for C++

Changes to generic/tk3d.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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tk3d.h"

/*
 * The following table defines the string values for reliefs, which are used
 * by Tk_GetReliefFromObj.
 */

static const char *const reliefStrings[] = {
    "flat", "groove", "raised", "ridge", "solid", "sunken", NULL
};

/*
 * Forward declarations for functions defined in this file:
 */







|
|













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * tk3d.c --
 *
 *	This module provides procedures to draw borders in the
 *	three-dimensional Motif style.
 *
 * 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"

/*
 * The following table defines the string values for reliefs, which are used
 * by Tk_GetReliefFromObj.
 */

const char *const tkReliefStrings[] = {
    "flat", "groove", "raised", "ridge", "solid", "sunken", NULL
};

/*
 * Forward declarations for functions defined in this file:
 */

42
43
44
45
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
 * The following structure defines the implementation of the "border" Tcl
 * object, used for drawing. The border object remembers the hash table entry
 * associated with a border. The actual allocation and deallocation of the
 * border should be done by the configuration package when the border option
 * is set.
 */

const Tcl_ObjType tkBorderObjType = {
    "border",			/* name */
    FreeBorderObjProc,		/* freeIntRepProc */
    DupBorderObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *----------------------------------------------------------------------
 *
 * Tk_Alloc3DBorderFromObj --
 *







|
|



|
>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 * The following structure defines the implementation of the "border" Tcl
 * object, used for drawing. The border object remembers the hash table entry
 * associated with a border. The actual allocation and deallocation of the
 * border should be done by the configuration package when the border option
 * is set.
 */

const TkObjType tkBorderObjType = {
    {"border",			/* name */
    FreeBorderObjProc,		/* freeIntRepProc */
    DupBorderObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_Alloc3DBorderFromObj --
 *
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    Tcl_Interp *interp,		/* Interp for error results. */
    Tk_Window tkwin,		/* Need the screen the border is used on.*/
    Tcl_Obj *objPtr)		/* Object giving name of color for window
				 * background. */
{
    TkBorder *borderPtr;

    if (objPtr->typePtr != &tkBorderObjType) {
	InitBorderObj(objPtr);
    }
    borderPtr = (TkBorder *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBorder, see if it's the one we
     * want. If so, increment its reference count and return.







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    Tcl_Interp *interp,		/* Interp for error results. */
    Tk_Window tkwin,		/* Need the screen the border is used on.*/
    Tcl_Obj *objPtr)		/* Object giving name of color for window
				 * background. */
{
    TkBorder *borderPtr;

    if (objPtr->typePtr != &tkBorderObjType.objType) {
	InitBorderObj(objPtr);
    }
    borderPtr = (TkBorder *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBorder, see if it's the one we
     * want. If so, increment its reference count and return.
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665
666
667
668

669
670

671
672

673
674

675
676
677
678

679
680



681
682
683
684
685
686
687
int
Tk_GetReliefFromObj(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Obj *objPtr,		/* The object we are trying to get the value
				 * from. */
    int *resultPtr)		/* Where to place the answer. */
{
    return Tcl_GetIndexFromObjStruct(interp, objPtr, reliefStrings,
	    sizeof(char *), "relief", 0, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRelief --
 *
 *	Parse a relief description and return the corresponding relief value,
 *	or an error.
 *
 * Results:
 *	A standard Tcl return value. If all goes well then *reliefPtr is
 *	filled in with one of the values TK_RELIEF_RAISED, TK_RELIEF_FLAT, or
 *	TK_RELIEF_SUNKEN.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetRelief(
    Tcl_Interp *interp,		/* For error messages. */
    const char *name,		/* Name of a relief type. */
    int *reliefPtr)		/* Where to store converted relief. */
{
    char c;
    size_t length;


    c = name[0];
    length = strlen(name);
    if ((c == 'f') && (strncmp(name, "flat", length) == 0)) {
	*reliefPtr = TK_RELIEF_FLAT;
    } else if ((c == 'g') && (strncmp(name, "groove", length) == 0)
	    && (length >= 2)) {
	*reliefPtr = TK_RELIEF_GROOVE;
    } else if ((c == 'r') && (strncmp(name, "raised", length) == 0)
	    && (length >= 2)) {
	*reliefPtr = TK_RELIEF_RAISED;
    } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)) {

	*reliefPtr = TK_RELIEF_RIDGE;
    } else if ((c == 's') && (strncmp(name, "solid", length) == 0)) {

	*reliefPtr = TK_RELIEF_SOLID;
    } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)) {

	*reliefPtr = TK_RELIEF_SUNKEN;
    } else {

	Tcl_SetObjResult(interp,
		Tcl_ObjPrintf("bad relief \"%.50s\": must be %s",
		name, "flat, groove, raised, ridge, solid, or sunken"));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "RELIEF", NULL);

	return TCL_ERROR;
    }



    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfRelief --







|













|
<















>




|
|
<
|


|
|
>
|
|
>
|
|
>
|

>
|
|
|
|
>


>
>
>







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
int
Tk_GetReliefFromObj(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Obj *objPtr,		/* The object we are trying to get the value
				 * from. */
    int *resultPtr)		/* Where to place the answer. */
{
    return Tcl_GetIndexFromObjStruct(interp, objPtr, tkReliefStrings,
	    sizeof(char *), "relief", 0, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetRelief --
 *
 *	Parse a relief description and return the corresponding relief value,
 *	or an error.
 *
 * Results:
 *	A standard Tcl return value. If all goes well then *reliefPtr is
 *	filled in with one of the values TK_RELIEF_*

 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetRelief(
    Tcl_Interp *interp,		/* For error messages. */
    const char *name,		/* Name of a relief type. */
    int *reliefPtr)		/* Where to store converted relief. */
{
    char c;
    size_t length;
    int relief;

    c = name[0];
    length = strlen(name);
    if ((c == 'f') && (strncmp(name, "flat", length) == 0)) {
	relief = TK_RELIEF_FLAT;
    } else if ((c == 'g') && (strncmp(name, "groove", length) == 0)) {

	relief = TK_RELIEF_GROOVE;
    } else if ((c == 'r') && (strncmp(name, "raised", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_RAISED;
    } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_RIDGE;
    } else if ((c == 's') && (strncmp(name, "solid", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_SOLID;
    } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_SUNKEN;
    } else {
	if (interp) {
	    Tcl_SetObjResult(interp,
		    Tcl_ObjPrintf("bad relief \"%.50s\": must be %s",
		    name, "flat, groove, raised, ridge, solid, or sunken"));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "RELIEF", NULL);
	}
	return TCL_ERROR;
    }
    if (reliefPtr) {
	*reliefPtr = relief;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfRelief --
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771
Tk_Draw3DPolygon(
    Tk_Window tkwin,		/* Window for which border was allocated. */
    Drawable drawable,		/* X window or pixmap in which to draw. */
    Tk_3DBorder border,		/* Token for border to draw. */
    XPoint *pointPtr,		/* Array of points describing polygon. All
				 * points must be absolute
				 * (CoordModeOrigin). */
    int numPoints,		/* Number of points at *pointPtr. */
    int borderWidth,		/* Width of border, measured in pixels to the
				 * left of the polygon's trajectory. May be
				 * negative. */
    int leftRelief)		/* TK_RELIEF_RAISED or TK_RELIEF_SUNKEN:
				 * indicates how stuff to left of trajectory
				 * looks relative to stuff on right. */
{
    XPoint poly[4], b1, b2, newB1, newB2;
    XPoint perp, c, shift1, shift2;	/* Used for handling parallel lines. */
    XPoint *p1Ptr, *p2Ptr;
    TkBorder *borderPtr = (TkBorder *) border;
    GC gc;

    int i, lightOnLeft, dx, dy, parallel, pointsSeen;
    Display *display = Tk_Display(tkwin);

    if (borderPtr->lightGC == NULL) {
	TkpGetShadows(borderPtr, tkwin);
    }

    /*







|












>
|







753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
Tk_Draw3DPolygon(
    Tk_Window tkwin,		/* Window for which border was allocated. */
    Drawable drawable,		/* X window or pixmap in which to draw. */
    Tk_3DBorder border,		/* Token for border to draw. */
    XPoint *pointPtr,		/* Array of points describing polygon. All
				 * points must be absolute
				 * (CoordModeOrigin). */
    Tcl_Size numPoints,		/* Number of points at *pointPtr. */
    int borderWidth,		/* Width of border, measured in pixels to the
				 * left of the polygon's trajectory. May be
				 * negative. */
    int leftRelief)		/* TK_RELIEF_RAISED or TK_RELIEF_SUNKEN:
				 * indicates how stuff to left of trajectory
				 * looks relative to stuff on right. */
{
    XPoint poly[4], b1, b2, newB1, newB2;
    XPoint perp, c, shift1, shift2;	/* Used for handling parallel lines. */
    XPoint *p1Ptr, *p2Ptr;
    TkBorder *borderPtr = (TkBorder *) border;
    GC gc;
    Tcl_Size i;
    int lightOnLeft, dx, dy, parallel, pointsSeen;
    Display *display = Tk_Display(tkwin);

    if (borderPtr->lightGC == NULL) {
	TkpGetShadows(borderPtr, tkwin);
    }

    /*
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
     * so some parts of the processing are ommitted for these points. The
     * variable "pointsSeen" keeps track of the priming process; it has to be
     * separate from i in order to be able to ignore duplicate points in the
     * polygon.
     */

    pointsSeen = 0;
    for (i = -2, p1Ptr = &pointPtr[numPoints-2], p2Ptr = p1Ptr+1;
	    i < numPoints; i++, p1Ptr = p2Ptr, p2Ptr++) {
	if ((i == -1) || (i == numPoints-1)) {
	    p2Ptr = pointPtr;
	}
	if ((p2Ptr->x == p1Ptr->x) && (p2Ptr->y == p1Ptr->y)) {
	    /*
	     * Ignore duplicate points (they'd cause core dumps in ShiftLine
	     * calls below).
	     */







|
|
|







840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
     * so some parts of the processing are ommitted for these points. The
     * variable "pointsSeen" keeps track of the priming process; it has to be
     * separate from i in order to be able to ignore duplicate points in the
     * polygon.
     */

    pointsSeen = 0;
    for (i = 0, p1Ptr = &pointPtr[numPoints-2], p2Ptr = p1Ptr+1;
	    i < numPoints + 2; i++, p1Ptr = p2Ptr, p2Ptr++) {
	if ((i == 1) || (i == numPoints + 1)) {
	    p2Ptr = pointPtr;
	}
	if ((p2Ptr->x == p1Ptr->x) && (p2Ptr->y == p1Ptr->y)) {
	    /*
	     * Ignore duplicate points (they'd cause core dumps in ShiftLine
	     * calls below).
	     */
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
Tk_Fill3DPolygon(
    Tk_Window tkwin,		/* Window for which border was allocated. */
    Drawable drawable,		/* X window or pixmap in which to draw. */
    Tk_3DBorder border,		/* Token for border to draw. */
    XPoint *pointPtr,		/* Array of points describing polygon. All
				 * points must be absolute
				 * (CoordModeOrigin). */
    int numPoints,		/* Number of points at *pointPtr. */
    int borderWidth,		/* Width of border, measured in pixels to the
				 * left of the polygon's trajectory. May be
				 * negative. */
    int leftRelief)		/* Indicates 3D effect of left side of
				 * trajectory relative to right:
				 * TK_RELIEF_FLAT, TK_RELIEF_RAISED, or
				 * TK_RELIEF_SUNKEN. */
{
    TkBorder *borderPtr = (TkBorder *) border;

    XFillPolygon(Tk_Display(tkwin), drawable, borderPtr->bgGC,
	    pointPtr, numPoints, Complex, CoordModeOrigin);
    if (leftRelief != TK_RELIEF_FLAT) {
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		borderWidth, leftRelief);
    }
}

/*







|











|







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
Tk_Fill3DPolygon(
    Tk_Window tkwin,		/* Window for which border was allocated. */
    Drawable drawable,		/* X window or pixmap in which to draw. */
    Tk_3DBorder border,		/* Token for border to draw. */
    XPoint *pointPtr,		/* Array of points describing polygon. All
				 * points must be absolute
				 * (CoordModeOrigin). */
    Tcl_Size numPoints,		/* Number of points at *pointPtr. */
    int borderWidth,		/* Width of border, measured in pixels to the
				 * left of the polygon's trajectory. May be
				 * negative. */
    int leftRelief)		/* Indicates 3D effect of left side of
				 * trajectory relative to right:
				 * TK_RELIEF_FLAT, TK_RELIEF_RAISED, or
				 * TK_RELIEF_SUNKEN. */
{
    TkBorder *borderPtr = (TkBorder *) border;

    XFillPolygon(Tk_Display(tkwin), drawable, borderPtr->bgGC,
	    pointPtr, (int)numPoints, Complex, CoordModeOrigin);
    if (leftRelief != TK_RELIEF_FLAT) {
	Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
		borderWidth, leftRelief);
    }
}

/*
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
    Tcl_Obj *objPtr)		/* The object whose string value selects a
				 * border. */
{
    TkBorder *borderPtr = NULL;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkBorderObjType) {
	InitBorderObj(objPtr);
    }

    /*
     * If we are lucky (and the user doesn't use too many different displays,
     * screens, or colormaps...) then the TkBorder structure we need will be
     * cached in the internal representation of the Tcl_Obj. Check it out...







|







1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
    Tcl_Obj *objPtr)		/* The object whose string value selects a
				 * border. */
{
    TkBorder *borderPtr = NULL;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkBorderObjType.objType) {
	InitBorderObj(objPtr);
    }

    /*
     * If we are lucky (and the user doesn't use too many different displays,
     * screens, or colormaps...) then the TkBorder structure we need will be
     * cached in the internal representation of the Tcl_Obj. Check it out...
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkBorderObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkDebugBorder --







|







1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkBorderObjType.objType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkDebugBorder --
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389


































1390
1391
1392
1393
1394
1395
1396
1397
	if (borderPtr == NULL) {
	    Tcl_Panic("TkDebugBorder found empty hash table entry");
	}
	for ( ; (borderPtr != NULL); borderPtr = borderPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(borderPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(borderPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}



































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








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
	if (borderPtr == NULL) {
	    Tcl_Panic("TkDebugBorder found empty hash table entry");
	}
	for ( ; (borderPtr != NULL); borderPtr = borderPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj((Tcl_WideInt)borderPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj((Tcl_WideInt)borderPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_Get3BorderColors --
 *
 *	Given a Tk_3DBorder determine its 3 colors.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

void
Tk_Get3DBorderColors(
    Tk_3DBorder border,
    XColor *bgColorPtr,
    XColor *darkColorPtr,
    XColor *lightColorPtr)
{
    if (bgColorPtr) {
	*bgColorPtr = *((TkBorder *)border)->bgColorPtr;
    }
    if (darkColorPtr) {
	*darkColorPtr = *((TkBorder *) border)->darkColorPtr;
    }
    if (lightColorPtr) {
	*lightColorPtr = *((TkBorder *) border)->lightColorPtr;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tk3d.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tk3d.h --
 *
 *	Declarations of types and functions shared by the 3d border module.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK3D
#define _TK3D





|







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 © 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK3D
#define _TK3D
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    Screen *screen;		/* Screen on which the border will be used. */
    Visual *visual;		/* Visual for all windows and pixmaps using
				 * the border. */
    int depth;			/* Number of bits per pixel of drawables where
				 * the border will be used. */
    Colormap colormap;		/* Colormap out of which pixels are
				 * allocated. */
    TkSizeT resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_Alloc3DBorderFromObj or Tk_Get3DBorder).
				 * If this count is 0, then this structure is
				 * no longer valid and it isn't present in
				 * borderTable: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when objRefCount and
				 * resourceRefCount are both 0. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    XColor *bgColorPtr;		/* Background color (intensity between
				 * lightColorPtr and darkColorPtr). */
    XColor *darkColorPtr;	/* Color for darker areas (must free when
				 * deleting structure). NULL means shadows
				 * haven't been allocated yet.*/
    XColor *lightColorPtr;	/* Color used for lighter areas of border







|








|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    Screen *screen;		/* Screen on which the border will be used. */
    Visual *visual;		/* Visual for all windows and pixmaps using
				 * the border. */
    int depth;			/* Number of bits per pixel of drawables where
				 * the border will be used. */
    Colormap colormap;		/* Colormap out of which pixels are
				 * allocated. */
    Tcl_Size resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_Alloc3DBorderFromObj or Tk_Get3DBorder).
				 * If this count is 0, then this structure is
				 * no longer valid and it isn't present in
				 * borderTable: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when objRefCount and
				 * resourceRefCount are both 0. */
    Tcl_Size objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    XColor *bgColorPtr;		/* Background color (intensity between
				 * lightColorPtr and darkColorPtr). */
    XColor *darkColorPtr;	/* Color for darker areas (must free when
				 * deleting structure). NULL means shadows
				 * haven't been allocated yet.*/
    XColor *lightColorPtr;	/* Color used for lighter areas of border

Changes to generic/tkArgv.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|
|







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 © 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"

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    int srcIndex;		/* Location from which to read next argument
				 * from argv. */
    int dstIndex;		/* Index into argv to which next unused
				 * argument should be copied (never greater
				 * than srcIndex). */
    int argc;			/* # arguments in argv still to process. */
    size_t length;		/* Number of characters in current argument. */
    char *endPtr;		/* Used for identifying junk in arguments. */
    int i;

    if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) {
	srcIndex = dstIndex = 0;
	argc = *argcPtr;
    } else {
	srcIndex = dstIndex = 1;







<







79
80
81
82
83
84
85

86
87
88
89
90
91
92
    int srcIndex;		/* Location from which to read next argument
				 * from argv. */
    int dstIndex;		/* Index into argv to which next unused
				 * argument should be copied (never greater
				 * than srcIndex). */
    int argc;			/* # arguments in argv still to process. */
    size_t length;		/* Number of characters in current argument. */

    int i;

    if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) {
	srcIndex = dstIndex = 0;
	argc = *argcPtr;
    } else {
	srcIndex = dstIndex = 1;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
	if (length > 0) {
	    c = curArg[1];
	} else {
	    c = 0;
	}

	/*
	 * Loop throught the argument descriptors searching for one with the
	 * matching key string. If found, leave a pointer to it in matchPtr.
	 */

	matchPtr = NULL;
	for (i = 0; i < 2; i++) {
	    if (i == 0) {
		infoPtr = argTable;







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
	if (length > 0) {
	    c = curArg[1];
	} else {
	    c = 0;
	}

	/*
	 * Loop through the argument descriptors searching for one with the
	 * matching key string. If found, leave a pointer to it in matchPtr.
	 */

	matchPtr = NULL;
	for (i = 0; i < 2; i++) {
	    if (i == 0) {
		infoPtr = argTable;
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	 * Take the appropriate action based on the option type
	 */

    gotMatch:
	infoPtr = matchPtr;
	switch (infoPtr->type) {
	case TK_ARGV_CONSTANT:
	    *((int *) infoPtr->dst) = PTR2INT(infoPtr->src);
	    break;
	case TK_ARGV_INT:
	    if (argc == 0) {
		goto missingArg;
	    }
	    *((int *) infoPtr->dst) = strtol(argv[srcIndex], &endPtr, 0);
	    if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected %s argument for \"%s\" but got \"%s\"",
			"integer", infoPtr->key, argv[srcIndex]));
		Tcl_SetErrorCode(interp, "TK", "ARG", "INTEGER", curArg,NULL);
		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_STRING:
	    if (argc == 0) {







|





|
<
<
<
<
<







170
171
172
173
174
175
176
177
178
179
180
181
182
183





184
185
186
187
188
189
190
	 * Take the appropriate action based on the option type
	 */

    gotMatch:
	infoPtr = matchPtr;
	switch (infoPtr->type) {
	case TK_ARGV_CONSTANT:
	    *((int *) infoPtr->dst) = (int)PTR2INT(infoPtr->src);
	    break;
	case TK_ARGV_INT:
	    if (argc == 0) {
		goto missingArg;
	    }
	    if (Tcl_GetInt(interp, argv[srcIndex], (int *) infoPtr->dst) != TCL_OK) {





		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_STRING:
	    if (argc == 0) {
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	case TK_ARGV_REST:
	    *((int *) infoPtr->dst) = dstIndex;
	    goto argsDone;
	case TK_ARGV_FLOAT:
	    if (argc == 0) {
		goto missingArg;
	    }
	    *((double *) infoPtr->dst) = strtod(argv[srcIndex], &endPtr);
	    if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected %s argument for \"%s\" but got \"%s\"",
			"floating-point", infoPtr->key, argv[srcIndex]));
		Tcl_SetErrorCode(interp, "TK", "ARG", "FLOAT", curArg, NULL);
		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_FUNC: {
	    typedef int (ArgvFunc)(char *, const char *, const char *);







|
<
<
<
<
<







205
206
207
208
209
210
211
212





213
214
215
216
217
218
219
	case TK_ARGV_REST:
	    *((int *) infoPtr->dst) = dstIndex;
	    goto argsDone;
	case TK_ARGV_FLOAT:
	    if (argc == 0) {
		goto missingArg;
	    }
	    if (Tcl_GetDouble(interp, argv[srcIndex], ((double *) infoPtr->dst)) != TCL_OK) {





		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_FUNC: {
	    typedef int (ArgvFunc)(char *, const char *, const char *);
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
	    length = strlen(infoPtr->key);
	    if (length > width) {
		width = length;
	    }
	}
    }

    message = Tcl_NewStringObj("Command-specific options:", -1);
    for (i = 0; ; i++) {
	for (infoPtr = i ? defaultTable : argTable;
		infoPtr->type != TK_ARGV_END; infoPtr++) {
	    if ((infoPtr->type == TK_ARGV_HELP) && (infoPtr->key == NULL)) {
		Tcl_AppendPrintfToObj(message, "\n%s", infoPtr->help);
		continue;
	    }
	    Tcl_AppendPrintfToObj(message, "\n %s:", infoPtr->key);
	    numSpaces = width + 1 - strlen(infoPtr->key);
	    while (numSpaces-- > 0) {
		Tcl_AppendToObj(message, " ", 1);
	    }
	    Tcl_AppendToObj(message, infoPtr->help, -1);
	    switch (infoPtr->type) {
	    case TK_ARGV_INT:
		Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %d",
			*((int *) infoPtr->dst));
		break;
	    case TK_ARGV_FLOAT:
		Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %f",







|












|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
	    length = strlen(infoPtr->key);
	    if (length > width) {
		width = length;
	    }
	}
    }

    message = Tcl_NewStringObj("Command-specific options:", TCL_INDEX_NONE);
    for (i = 0; ; i++) {
	for (infoPtr = i ? defaultTable : argTable;
		infoPtr->type != TK_ARGV_END; infoPtr++) {
	    if ((infoPtr->type == TK_ARGV_HELP) && (infoPtr->key == NULL)) {
		Tcl_AppendPrintfToObj(message, "\n%s", infoPtr->help);
		continue;
	    }
	    Tcl_AppendPrintfToObj(message, "\n %s:", infoPtr->key);
	    numSpaces = width + 1 - strlen(infoPtr->key);
	    while (numSpaces-- > 0) {
		Tcl_AppendToObj(message, " ", 1);
	    }
	    Tcl_AppendToObj(message, infoPtr->help, TCL_INDEX_NONE);
	    switch (infoPtr->type) {
	    case TK_ARGV_INT:
		Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %d",
			*((int *) infoPtr->dst));
		break;
	    case TK_ARGV_FLOAT:
		Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %f",
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
		break;
	    }
	}

	if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) {
	    break;
	}
	Tcl_AppendToObj(message, "\nGeneric options for all commands:", -1);
    }
    Tcl_SetObjResult(interp, message);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|











388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
		break;
	    }
	}

	if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) {
	    break;
	}
	Tcl_AppendToObj(message, "\nGeneric options for all commands:", TCL_INDEX_NONE);
    }
    Tcl_SetObjResult(interp, message);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkArray.h.

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.
 *
 * 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







|







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 © 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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









|
|







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 © 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
/*
 * tkBind.c --
 *
 *	This file provides functions that associate Tcl commands with X events
 *	or sequences of X events.
 *
 * Copyright (c) 1989-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 by Scriptics Corporation.
 * Copyright (c) 2018-2019 by Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkDList.h"






|
|
|
|







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 © 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"
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

#ifdef _MSC_VER
/*
 * Earlier versions of MSVC don't know snprintf, but _snprintf is compatible.
 * Note that sprintf is deprecated.
 */
# define snprintf _snprintf
#endif

#define SIZE_OF_ARRAY(arr) (sizeof(arr)/sizeof(arr[0]))

/*
 * File structure:
 *
 * Structure definitions and static variables.
 *







<
<
<
<
<
<
<
<







27
28
29
30
31
32
33








34
35
36
37
38
39
40

#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif









#define SIZE_OF_ARRAY(arr) (sizeof(arr)/sizeof(arr[0]))

/*
 * File structure:
 *
 * Structure definitions and static variables.
 *
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

struct PatSeq; /* forward declaration */

/* We need this array for bookkeeping the last matching modifier mask per pattern. */
TK_ARRAY_DEFINE(PSModMaskArr, unsigned);

typedef struct PSEntry {
    TK_DLIST_LINKS(PSEntry);	/* Makes this struct a double linked list; must be first entry. */
    Window window;		/* Window of last match. */
    struct PatSeq* psPtr;	/* Pointer to pattern sequence. */
    PSModMaskArr *lastModMaskArr;
    				/* Last matching modifier mask per pattern (except last pattern).
    				 * Only needed if pattern sequence is not single (more than one
				 * pattern), and if one of these patterns contains a non-zero
				 * modifier mask. */







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

struct PatSeq; /* forward declaration */

/* We need this array for bookkeeping the last matching modifier mask per pattern. */
TK_ARRAY_DEFINE(PSModMaskArr, unsigned);

typedef struct PSEntry {
    TK_DLIST_LINKS(PSEntry);	/* Makes this struct a doubly linked list; must be first entry. */
    Window window;		/* Window of last match. */
    struct PatSeq* psPtr;	/* Pointer to pattern sequence. */
    PSModMaskArr *lastModMaskArr;
    				/* Last matching modifier mask per pattern (except last pattern).
    				 * Only needed if pattern sequence is not single (more than one
				 * pattern), and if one of these patterns contains a non-zero
				 * modifier mask. */
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
 * binding tables may exist at once, either because there are multiple
 * applications open, or because there are multiple domains within an
 * application with separate event bindings for each (for example, each canvas
 * widget has a separate binding table for associating events with the items
 * in the canvas).
 */

/* defining the whole Promotion_* stuff (array of PSList entries) */
TK_ARRAY_DEFINE(PromArr, PSList);

typedef struct Tk_BindingTable_ {
    Event eventInfo[TK_LASTEVENT];
    				/* Containing the most recent event for every event type. */
    PromArr *promArr;		/* Contains the promoted pattern sequences. */
    Event *curEvent;		/* Pointing to most recent event. */







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
 * binding tables may exist at once, either because there are multiple
 * applications open, or because there are multiple domains within an
 * application with separate event bindings for each (for example, each canvas
 * widget has a separate binding table for associating events with the items
 * in the canvas).
 */

/* Defining the whole PromArr_* stuff (array of PSList entries) */
TK_ARRAY_DEFINE(PromArr, PSList);

typedef struct Tk_BindingTable_ {
    Event eventInfo[TK_LASTEVENT];
    				/* Containing the most recent event for every event type. */
    PromArr *promArr;		/* Contains the promoted pattern sequences. */
    Event *curEvent;		/* Pointing to most recent event. */
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 *
 * The same key is used for both types of pattern tables so that the helper
 * functions that traverse and match patterns will work for both binding
 * tables and virtual event tables.
 */

typedef struct {
    ClientData object;		/* For binding table, identifies the binding tag of the object
    				 * (or class of objects) relative to which the event occurred.
				 * For virtual event table, always NULL. */
    unsigned type;		/* Type of event (from X). */
    Detail detail;		/* Additional information, such as keysym, button, Tk_Uid, or zero
    				 * if nothing additional. */
} PatternTableKey;








|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
 *
 * The same key is used for both types of pattern tables so that the helper
 * functions that traverse and match patterns will work for both binding
 * tables and virtual event tables.
 */

typedef struct {
    void *object;		/* For binding table, identifies the binding tag of the object
    				 * (or class of objects) relative to which the event occurred.
				 * For virtual event table, always NULL. */
    unsigned type;		/* Type of event (from X). */
    Detail detail;		/* Additional information, such as keysym, button, Tk_Uid, or zero
    				 * if nothing additional. */
} PatternTableKey;

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
 * Compute memory size of struct PatSeq with given pattern size.
 * The caller must be sure that pattern size is greater than zero.
 */
#define PATSEQ_MEMSIZE(numPats) (sizeof(PatSeq) + (numPats - 1)*sizeof(TkPattern))

/*
 * Constants that define how close together two events must be in milliseconds
 * or pixels to meet the PAT_NEARBY constraint:
 */

#define NEARBY_PIXELS	5
#define NEARBY_MS	500

/*
 * The following structure is used in the nameTable of a virtual event table







|







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
 * Compute memory size of struct PatSeq with given pattern size.
 * The caller must be sure that pattern size is greater than zero.
 */
#define PATSEQ_MEMSIZE(numPats) (sizeof(PatSeq) + (numPats - 1)*sizeof(TkPattern))

/*
 * Constants that define how close together two events must be in milliseconds
 * or pixels to be considered close in space or time.
 */

#define NEARBY_PIXELS	5
#define NEARBY_MS	500

/*
 * The following structure is used in the nameTable of a virtual event table
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434

435

436
437
438
439
440
441
442

/*
 * Flags for ModInfo structures:
 *
 * DOUBLE -		Non-zero means duplicate this event, e.g. for double-clicks.
 * TRIPLE -		Non-zero means triplicate this event, e.g. for triple-clicks.
 * QUADRUPLE -		Non-zero means quadruple this event, e.g. for 4-fold-clicks.
 * MULT_CLICKS -	Combination of all of above.
 */

#define DOUBLE		(1<<0)
#define TRIPLE		(1<<1)
#define QUADRUPLE	(1<<2)
#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)

static const ModInfo modArray[] = {
    {"Control",		ControlMask,	0},
    {"Shift",		ShiftMask,	0},
    {"Lock",		LockMask,	0},
    {"Meta",		META_MASK,	0},

    {"M",		META_MASK,	0},

    {"Alt",		ALT_MASK,	0},
    {"Extended",	EXTENDED_MASK,	0},
    {"B1",		Button1Mask,	0},
    {"Button1",		Button1Mask,	0},
    {"B2",		Button2Mask,	0},
    {"Button2",		Button2Mask,	0},
    {"B3",		Button3Mask,	0},







|












>

>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

/*
 * Flags for ModInfo structures:
 *
 * DOUBLE -		Non-zero means duplicate this event, e.g. for double-clicks.
 * TRIPLE -		Non-zero means triplicate this event, e.g. for triple-clicks.
 * QUADRUPLE -		Non-zero means quadruple this event, e.g. for 4-fold-clicks.
 * MULT_CLICKS -	Combination of all the above.
 */

#define DOUBLE		(1<<0)
#define TRIPLE		(1<<1)
#define QUADRUPLE	(1<<2)
#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)

static const ModInfo modArray[] = {
    {"Control",		ControlMask,	0},
    {"Shift",		ShiftMask,	0},
    {"Lock",		LockMask,	0},
    {"Meta",		META_MASK,	0},
#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},
451
452
453
454
455
456
457

458





459
460

461



462
463

464

465
466
467
468
469
470
471
    {"Button7",		Button7Mask,	0},
    {"B8",		Button8Mask,	0},
    {"Button8",		Button8Mask,	0},
    {"B9",		Button9Mask,	0},
    {"Button9",		Button9Mask,	0},
    {"Mod1",		Mod1Mask,	0},
    {"M1",		Mod1Mask,	0},

    {"Command",		Mod1Mask,	0},





    {"Mod2",		Mod2Mask,	0},
    {"M2",		Mod2Mask,	0},

    {"Option",		Mod2Mask,	0},



    {"Mod3",		Mod3Mask,	0},
    {"M3",		Mod3Mask,	0},

    {"Mod4",		Mod4Mask,	0},

    {"M4",		Mod4Mask,	0},
    {"Mod5",		Mod5Mask,	0},
    {"M5",		Mod5Mask,	0},
    {"Double",		0,		DOUBLE},
    {"Triple",		0,		TRIPLE},
    {"Quadruple",	0,		QUADRUPLE},
    {"Any",		0,		0},	/* Ignored: historical relic */







>

>
>
>
>
>


>

>
>
>


>

>







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    {"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},
    {"Num",		Mod3Mask,	0},
    {"Mod4",		Mod4Mask,	0},
    {"Fn",		Mod4Mask,	0},
    {"M4",		Mod4Mask,	0},
    {"Mod5",		Mod5Mask,	0},
    {"M5",		Mod5Mask,	0},
    {"Double",		0,		DOUBLE},
    {"Triple",		0,		TRIPLE},
    {"Quadruple",	0,		QUADRUPLE},
    {"Any",		0,		0},	/* Ignored: historical relic */
490
491
492
493
494
495
496

497

498
499

500

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527
 * This is necessary because X doesn't report up events unless you also ask
 * for down events. Also, X doesn't report button state in motion events
 * unless you've asked about button events.
 */

static const EventInfo eventArray[] = {
    {"Key",		KeyPress,		KeyPressMask},

    {"KeyPress",	KeyPress,		KeyPressMask},

    {"KeyRelease",	KeyRelease,		KeyPressMask|KeyReleaseMask},
    {"Button",		ButtonPress,		ButtonPressMask},

    {"ButtonPress",	ButtonPress,		ButtonPressMask},

    {"ButtonRelease",	ButtonRelease,		ButtonPressMask|ButtonReleaseMask},
    {"Motion",		MotionNotify,		ButtonPressMask|PointerMotionMask},
    {"Enter",		EnterNotify,		EnterWindowMask},
    {"Leave",		LeaveNotify,		LeaveWindowMask},
    {"FocusIn",		FocusIn,		FocusChangeMask},
    {"FocusOut",	FocusOut,		FocusChangeMask},
    {"Expose",		Expose,			ExposureMask},
    {"Visibility",	VisibilityNotify,	VisibilityChangeMask},
    {"Destroy",		DestroyNotify,		StructureNotifyMask},
    {"Unmap",		UnmapNotify,		StructureNotifyMask},
    {"Map",		MapNotify,		StructureNotifyMask},
    {"Reparent",	ReparentNotify,		StructureNotifyMask},
    {"Configure",	ConfigureNotify,	StructureNotifyMask},
    {"Gravity",		GravityNotify,		StructureNotifyMask},
    {"Circulate",	CirculateNotify,	StructureNotifyMask},
    {"Property",	PropertyNotify,		PropertyChangeMask},
    {"Colormap",	ColormapNotify,		ColormapChangeMask},
    {"Activate",	ActivateNotify,		ActivateMask},
    {"Deactivate",	DeactivateNotify,	ActivateMask},
    {"MouseWheel",	MouseWheelEvent,	MouseWheelMask},

    {"CirculateRequest", CirculateRequest,	SubstructureRedirectMask},
    {"ConfigureRequest", ConfigureRequest,	SubstructureRedirectMask},
    {"Create",		CreateNotify,		SubstructureNotifyMask},
    {"MapRequest",	MapRequest,		SubstructureRedirectMask},
    {"ResizeRequest",	ResizeRequest,		ResizeRedirectMask},
    {NULL,		0,			0}
};







>

>


>

>




















>







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
 * 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},
    {"Visibility",	VisibilityNotify,	VisibilityChangeMask},
    {"Destroy",		DestroyNotify,		StructureNotifyMask},
    {"Unmap",		UnmapNotify,		StructureNotifyMask},
    {"Map",		MapNotify,		StructureNotifyMask},
    {"Reparent",	ReparentNotify,		StructureNotifyMask},
    {"Configure",	ConfigureNotify,	StructureNotifyMask},
    {"Gravity",		GravityNotify,		StructureNotifyMask},
    {"Circulate",	CirculateNotify,	StructureNotifyMask},
    {"Property",	PropertyNotify,		PropertyChangeMask},
    {"Colormap",	ColormapNotify,		ColormapChangeMask},
    {"Activate",	ActivateNotify,		ActivateMask},
    {"Deactivate",	DeactivateNotify,	ActivateMask},
    {"MouseWheel",	MouseWheelEvent,	MouseWheelMask},
    {"TouchpadScroll",  TouchpadScroll,         TouchpadScrollMask},
    {"CirculateRequest", CirculateRequest,	SubstructureRedirectMask},
    {"ConfigureRequest", ConfigureRequest,	SubstructureRedirectMask},
    {"Create",		CreateNotify,		SubstructureNotifyMask},
    {"MapRequest",	MapRequest,		SubstructureRedirectMask},
    {"ResizeRequest",	ResizeRequest,		ResizeRedirectMask},
    {NULL,		0,			0}
};
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
#define	MAPREQ			(1<<20)
#define	CONFIGREQ		(1<<21)
#define	RESIZEREQ		(1<<22)
#define CIRCREQ			(1<<23)

/*
 * These structs agree with xkey for the fields type, serial, send_event, display,
 * window, root, subwindow, time, x, y, x_root, and y_root.  So when accessing
 * these fields we may pretend that we are using a struct xkey.
 */

#define HAS_XKEY_HEAD (KEY|BUTTON|MOTION|VIRTUAL|CROSSING|WHEEL)

/*
 * The xcrossing struct puts the state field in a different location, but the other







|







571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
#define	MAPREQ			(1<<20)
#define	CONFIGREQ		(1<<21)
#define	RESIZEREQ		(1<<22)
#define CIRCREQ			(1<<23)

/*
 * These structs agree with xkey for the fields type, serial, send_event, display,
 * window, root, subwindow, time, x, y, x_root, and y_root. So when accessing
 * these fields we may pretend that we are using a struct xkey.
 */

#define HAS_XKEY_HEAD (KEY|BUTTON|MOTION|VIRTUAL|CROSSING|WHEEL)

/*
 * The xcrossing struct puts the state field in a different location, but the other
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
   /* SelectionNotify */	0,
   /* ColormapNotify */		COLORMAP,
   /* ClientMessage */		0,
   /* MappingNotify */		0,
   /* VirtualEvent */		VIRTUAL,
   /* Activate */		ACTIVATE,
   /* Deactivate */		ACTIVATE,
   /* MouseWheel */		WHEEL

};

/*
 * The following table is used to map between the location where an generated
 * event should be queued and the string used to specify the location.
 */








|
>







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
   /* SelectionNotify */	0,
   /* ColormapNotify */		COLORMAP,
   /* ClientMessage */		0,
   /* MappingNotify */		0,
   /* VirtualEvent */		VIRTUAL,
   /* Activate */		ACTIVATE,
   /* Deactivate */		ACTIVATE,
   /* MouseWheel */		WHEEL,
   /* TouchpadScroll */		WHEEL
};

/*
 * The following table is used to map between the location where an generated
 * event should be queued and the string used to specify the location.
 */

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
			    char *virtString, const char *eventString);
static int		DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    char *virtString, const char *eventString);
static void		DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void		ExpandPercents(TkWindow *winPtr, const char *before, Event *eventPtr,
			    unsigned scriptCount, Tcl_DString *dsPtr);
static PatSeq *		FindSequence(Tcl_Interp *interp, LookupTables *lookupTables,
			    ClientData object, const char *eventString, int create,
			    int allowVirtual, unsigned *maskPtr);
static void		GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr);
static const char *	GetField(const char *p, char *copy, unsigned size);
static Tcl_Obj *	GetPatternObj(const PatSeq *psPtr);
static int		GetVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    Tcl_Obj *virtName);
static Tk_Uid		GetVirtualEventUid(Tcl_Interp *interp, char *virtString);
static int		HandleEventGenerate(Tcl_Interp *interp, Tk_Window main,
			    int objc, Tcl_Obj *const objv[]);
static void		InitVirtualEventTable(VirtualEventTable *vetPtr);
static PatSeq *		MatchPatterns(TkDisplay *dispPtr, Tk_BindingTable bindPtr, PSList *psList,
			    PSList *psSuccList, unsigned patIndex, const Event *eventPtr,
			    ClientData object, PatSeq **physPtrPtr);
static int		NameToWindow(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static unsigned		ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr,
			    TkPattern *patPtr, unsigned *eventMaskPtr);
static PSList *		GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr,
			    Tcl_Obj *object, int onlyConsiderDetailedEvents);
static void		ClearLookupTable(LookupTables *lookupTables, ClientData object);
static void		ClearPromotionLists(Tk_BindingTable bindPtr, ClientData object);
static PSEntry *	MakeListEntry(PSList *pool, PatSeq *psPtr, int needModMasks);
static void		RemovePatSeqFromLookup(LookupTables *lookupTables, PatSeq *psPtr);
static void		RemovePatSeqFromPromotionLists(Tk_BindingTable bindPtr, PatSeq *psPtr);
static PatSeq *		DeletePatSeq(PatSeq *psPtr);
static void		InsertPatSeq(LookupTables *lookupTables, PatSeq *psPtr);
#if SUPPORT_DEBUGGING
void			TkpDumpPS(const PatSeq *psPtr);
void			TkpDumpPSList(const PSList *psList);
#endif

/*
 * Some useful helper functions.
 */
#ifdef SUPPORT_DEBUGGING
static int BindCount = 0;
#endif

static unsigned Max(unsigned a, unsigned b) { return a < b ? b : a; }
static int Abs(int n) { return n < 0 ? -n : n; }
static int IsOdd(int n) { return n & 1; }

static int TestNearbyTime(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_MS; }
static int TestNearbyCoords(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_PIXELS; }

static int
IsSubsetOf(
    unsigned lhsMask,	/* this is a subset */
    unsigned rhsMask)	/* of this bit field? */
{
    return (lhsMask & rhsMask) == lhsMask;
}

static const char*
SkipSpaces(
    const char* s)







|








|



|






|
|













|
|


|








|
|







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
			    char *virtString, const char *eventString);
static int		DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    char *virtString, const char *eventString);
static void		DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void		ExpandPercents(TkWindow *winPtr, const char *before, Event *eventPtr,
			    unsigned scriptCount, Tcl_DString *dsPtr);
static PatSeq *		FindSequence(Tcl_Interp *interp, LookupTables *lookupTables,
			    void *object, const char *eventString, int create,
			    int allowVirtual, unsigned *maskPtr);
static void		GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr);
static const char *	GetField(const char *p, char *copy, unsigned size);
static Tcl_Obj *	GetPatternObj(const PatSeq *psPtr);
static int		GetVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    Tcl_Obj *virtName);
static Tk_Uid		GetVirtualEventUid(Tcl_Interp *interp, char *virtString);
static int		HandleEventGenerate(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Size 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,
			    void *object, PatSeq **physPtrPtr);
static int		NameToWindow(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static unsigned		ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr,
			    TkPattern *patPtr, unsigned *eventMaskPtr);
static PSList *		GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr,
			    Tcl_Obj *object, int onlyConsiderDetailedEvents);
static void		ClearLookupTable(LookupTables *lookupTables, void *object);
static void		ClearPromotionLists(Tk_BindingTable bindPtr, void *object);
static PSEntry *	MakeListEntry(PSList *pool, PatSeq *psPtr, int needModMasks);
static void		RemovePatSeqFromLookup(LookupTables *lookupTables, PatSeq *psPtr);
static void		RemovePatSeqFromPromotionLists(Tk_BindingTable bindPtr, PatSeq *psPtr);
static PatSeq *		DeletePatSeq(PatSeq *psPtr);
static void		InsertPatSeq(LookupTables *lookupTables, PatSeq *psPtr);
#if SUPPORT_DEBUGGING
void			TkpDumpPS(const PatSeq *psPtr);
void			TkpDumpPSList(const PSList *psList);
#endif

/*
 * Some useful helper functions.
 */
#if SUPPORT_DEBUGGING
static int BindCount = 0;  /* Can be set or queried from Tcl through 'event debug' subcommand. Otherwise not used. */
#endif

static Tcl_Size Max(Tcl_Size a, Tcl_Size b) { return a < b ? b : a; }
static int Abs(int n) { return n < 0 ? -n : n; }
static int IsOdd(int n) { return n & 1; }

static int TestNearbyTime(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_MS; }
static int TestNearbyCoords(int lhs, int rhs) { return Abs(lhs - rhs) <= NEARBY_PIXELS; }

static int
IsSubsetOf(
    unsigned lhsMask,	/* Is this a subset... */
    unsigned rhsMask)	/* ...of this bit field? */
{
    return (lhsMask & rhsMask) == lhsMask;
}

static const char*
SkipSpaces(
    const char* s)
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

805
806
807
808
809
810
811

static unsigned
GetButtonNumber(
    const char *field)
{
    unsigned button;
    assert(field);
    button = (field[0] >= '1' && field[0] <= '9' && field[1] == '\0') ? field[0] - '0' : 0;
    return (button > 3) ? (button + 4) : button;
}

static Time
CurrentTimeInMilliSecs(void)
{
    Tcl_Time now;

    Tcl_GetTime(&now);
    return ((Time) now.sec)*1000 + ((Time) now.usec)/1000;
}

static Info
GetInfo(
    const PatSeq *psPtr,







|







>







802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

static unsigned
GetButtonNumber(
    const char *field)
{
    unsigned button;
    assert(field);
    button = (field[0] >= '1' && field[0] <= '9' && field[1] == '\0') ? (unsigned)(field[0] - '0') : 0;
    return (button > 3) ? (button + 4) : button;
}

static Time
CurrentTimeInMilliSecs(void)
{
    Tcl_Time now;

    Tcl_GetTime(&now);
    return ((Time) now.sec)*1000 + ((Time) now.usec)/1000;
}

static Info
GetInfo(
    const PatSeq *psPtr,
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
    for (i = 0; i < sndMatchPtr->numPats; ++i) {
	if (GetInfo(sndMatchPtr, i)) { sndCount += GetCount(sndMatchPtr, i); }
    }

    return sndCount - fstCount;
}

int
IsKeyEventType(
    unsigned eventType)
{
    return eventType == KeyPress || eventType == KeyRelease;
}

int
IsButtonEventType(
    unsigned eventType)
{
    return eventType == ButtonPress || eventType == ButtonRelease;
}

static int
MatchEventNearby(
    const XEvent *lhs,	/* previous button event */
    const XEvent *rhs)	/* current button event */
{
    assert(lhs);
    assert(rhs);
    assert(IsButtonEventType(lhs->type));
    assert(lhs->type == rhs->type);

    /* assert: lhs->xbutton.time <= rhs->xbutton.time */

    return TestNearbyTime(rhs->xbutton.time, lhs->xbutton.time)
	    && TestNearbyCoords(rhs->xbutton.x_root, lhs->xbutton.x_root)
	    && TestNearbyCoords(rhs->xbutton.y_root, lhs->xbutton.y_root);
}

static int
MatchEventRepeat(
    const XKeyEvent *lhs,	/* previous key event */
    const XKeyEvent *rhs)	/* current key event */
{
    assert(lhs);
    assert(rhs);
    assert(IsKeyEventType(lhs->type));
    assert(lhs->type == rhs->type);

    /* assert: lhs->time <= rhs->time */







|

|




|








|
|















|
|







859
860
861
862
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
    for (i = 0; i < sndMatchPtr->numPats; ++i) {
	if (GetInfo(sndMatchPtr, i)) { sndCount += GetCount(sndMatchPtr, i); }
    }

    return sndCount - fstCount;
}

static int
IsKeyEventType(
    int eventType)
{
    return eventType == KeyPress || eventType == KeyRelease;
}

static int
IsButtonEventType(
    unsigned eventType)
{
    return eventType == ButtonPress || eventType == ButtonRelease;
}

static int
MatchEventNearby(
    const XEvent *lhs,	/* Previous button event */
    const XEvent *rhs)	/* Current button event */
{
    assert(lhs);
    assert(rhs);
    assert(IsButtonEventType(lhs->type));
    assert(lhs->type == rhs->type);

    /* assert: lhs->xbutton.time <= rhs->xbutton.time */

    return TestNearbyTime(rhs->xbutton.time, lhs->xbutton.time)
	    && TestNearbyCoords(rhs->xbutton.x_root, lhs->xbutton.x_root)
	    && TestNearbyCoords(rhs->xbutton.y_root, lhs->xbutton.y_root);
}

static int
MatchEventRepeat(
    const XKeyEvent *lhs,	/* Previous key event */
    const XKeyEvent *rhs)	/* Current key event */
{
    assert(lhs);
    assert(rhs);
    assert(IsKeyEventType(lhs->type));
    assert(lhs->type == rhs->type);

    /* assert: lhs->time <= rhs->time */
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
    PSList_Append(pool, psEntry);
}

static void
ClearList(
    PSList *psList,
    PSList *pool,
    ClientData object)
{
    assert(psList);
    assert(pool);

    if (object) {
	PSEntry *psEntry;
	PSEntry *psNext;







|







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
    PSList_Append(pool, psEntry);
}

static void
ClearList(
    PSList *psList,
    PSList *pool,
    void *object)
{
    assert(psList);
    assert(pool);

    if (object) {
	PSEntry *psEntry;
	PSEntry *psNext;
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
{
    PatternTableKey key;
    Tcl_HashEntry *hPtr;

    assert(lookupTables);
    assert(eventPtr);

    /* otherwise on some systems the key contains uninitialized bytes */
    memset(&key, 0, sizeof(PatternTableKey));

    if (onlyConsiderDetailedEvents) {
	switch (eventPtr->xev.type) {
	case ButtonPress:   /* fallthru */
	case ButtonRelease: key.detail.info = eventPtr->xev.xbutton.button; break;
	case MotionNotify:  key.detail.info = ButtonNumberFromState(eventPtr->xev.xmotion.state); break;







|







1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
{
    PatternTableKey key;
    Tcl_HashEntry *hPtr;

    assert(lookupTables);
    assert(eventPtr);

    /* Otherwise on some systems the key contains uninitialized bytes. */
    memset(&key, 0, sizeof(PatternTableKey));

    if (onlyConsiderDetailedEvents) {
	switch (eventPtr->xev.type) {
	case ButtonPress:   /* fallthru */
	case ButtonRelease: key.detail.info = eventPtr->xev.xbutton.button; break;
	case MotionNotify:  key.detail.info = ButtonNumberFromState(eventPtr->xev.xmotion.state); break;
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
 *	None.
 *
 *--------------------------------------------------------------
 */
static void
ClearLookupTable(
    LookupTables *lookupTables,
    ClientData object)
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_HashEntry *nextPtr;
    PSList *pool = &lookupTables->entryPool;

    assert(lookupTables);







|







1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
 *	None.
 *
 *--------------------------------------------------------------
 */
static void
ClearLookupTable(
    LookupTables *lookupTables,
    void *object)
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_HashEntry *nextPtr;
    PSList *pool = &lookupTables->entryPool;

    assert(lookupTables);
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
 *
 *--------------------------------------------------------------
 */

static void
ClearPromotionLists(
    Tk_BindingTable bindPtr,
    ClientData object)
{
    unsigned newArraySize = 0;
    unsigned i;

    assert(bindPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	ClearList(psList, &bindPtr->lookupTables.entryPool, object);
	if (!PSList_IsEmpty(psList)) {







|

|
<







1216
1217
1218
1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
 *
 *--------------------------------------------------------------
 */

static void
ClearPromotionLists(
    Tk_BindingTable bindPtr,
    void *object)
{
    size_t i, newArraySize = 0;


    assert(bindPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	ClearList(psList, &bindPtr->lookupTables.entryPool, object);
	if (!PSList_IsEmpty(psList)) {
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

/*
 * Windoze compiler does not allow the definition of these static variables inside a function,
 * otherwise this should belong to function TkBindInit().
 */
TCL_DECLARE_MUTEX(bindMutex);
static int initialized = 0;

void
TkBindInit(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;

    assert(mainPtr);

    /* otherwise virtual events can't be supported */
    assert(sizeof(XEvent) >= sizeof(XVirtualEvent));

    /* type of TkPattern.info is well defined? */
    assert(sizeof(Info) >= sizeof(KeySym));
    assert(sizeof(Info) >= sizeof(unsigned));

    /* ensure that our matching algorithm is working (when testing detail) */
    assert(sizeof(Detail) == sizeof(Tk_Uid));

    /* test expected indices of Button1..Button5, otherwise our button handling is not working */
    assert(Button1 == 1 && Button2 == 2 && Button3 == 3 && Button4 == 4 && Button5 == 5);
    assert(Button2Mask == (Button1Mask << 1));
    assert(Button3Mask == (Button1Mask << 2));
    assert(Button4Mask == (Button1Mask << 3));
    assert(Button5Mask == (Button1Mask << 4));

    /* test expected values of button motion masks, otherwise our button handling is not working */
    assert(Button1MotionMask == Button1Mask);
    assert(Button2MotionMask == Button2Mask);
    assert(Button3MotionMask == Button3Mask);
    assert(Button4MotionMask == Button4Mask);
    assert(Button5MotionMask == Button5Mask);

    /* because we expect zero if keySym is empty */
    assert(NoSymbol == 0L);

    /* this must be a union, not a struct, otherwise comparison with NULL will not work */
    assert(offsetof(Detail, name) == offsetof(Detail, info));

    /* we use some constraints about X*Event */
    assert(offsetof(XButtonEvent, time) == offsetof(XMotionEvent, time));
    assert(offsetof(XButtonEvent, x_root) == offsetof(XMotionEvent, x_root));
    assert(offsetof(XButtonEvent, y_root) == offsetof(XMotionEvent, y_root));
    assert(offsetof(XCreateWindowEvent, border_width) == offsetof(XConfigureEvent, border_width));
    assert(offsetof(XCreateWindowEvent, width) == offsetof(XConfigureEvent, width));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XCirculateRequestEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XConfigureEvent, window));







|













|


|



|


|






|






|


|


|







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
 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

/*
 * Windows compiler does not allow the definition of these static variables inside a function,
 * otherwise this should belong to function TkBindInit().
 */
TCL_DECLARE_MUTEX(bindMutex);
static int initialized = 0;

void
TkBindInit(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;

    assert(mainPtr);

    /* Otherwise virtual events can't be supported. */
    assert(sizeof(XEvent) >= sizeof(XVirtualEvent));

    /* Is type of TkPattern.info well defined? */
    assert(sizeof(Info) >= sizeof(KeySym));
    assert(sizeof(Info) >= sizeof(unsigned));

    /* Ensure that our matching algorithm is working (when testing detail). */
    assert(sizeof(Detail) == sizeof(Tk_Uid));

    /* Test expected indices of Button1..Button5, otherwise our button handling is not working. */
    assert(Button1 == 1 && Button2 == 2 && Button3 == 3 && Button4 == 4 && Button5 == 5);
    assert(Button2Mask == (Button1Mask << 1));
    assert(Button3Mask == (Button1Mask << 2));
    assert(Button4Mask == (Button1Mask << 3));
    assert(Button5Mask == (Button1Mask << 4));

    /* Test expected values of button motion masks, otherwise our button handling is not working. */
    assert(Button1MotionMask == Button1Mask);
    assert(Button2MotionMask == Button2Mask);
    assert(Button3MotionMask == Button3Mask);
    assert(Button4MotionMask == Button4Mask);
    assert(Button5MotionMask == Button5Mask);

    /* Because we expect zero if keySym is empty. */
    assert(NoSymbol == 0L);

    /* This must be a union, not a struct, otherwise comparison with NULL will not work. */
    assert(offsetof(Detail, name) == offsetof(Detail, info));

    /* We use some constraints about X*Event. */
    assert(offsetof(XButtonEvent, time) == offsetof(XMotionEvent, time));
    assert(offsetof(XButtonEvent, x_root) == offsetof(XMotionEvent, x_root));
    assert(offsetof(XButtonEvent, y_root) == offsetof(XMotionEvent, y_root));
    assert(offsetof(XCreateWindowEvent, border_width) == offsetof(XConfigureEvent, border_width));
    assert(offsetof(XCreateWindowEvent, width) == offsetof(XConfigureEvent, width));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XCirculateRequestEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XConfigureEvent, window));
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
 *--------------------------------------------------------------
 */

unsigned long
Tk_CreateBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to create binding. */
    ClientData object,		/* Token for object with which binding is associated. */
    const char *eventString,	/* String describing event sequence that triggers binding. */
    const char *script,		/* Contains Tcl script to execute when binding triggers. */
    int append)			/* 0 means replace any existing binding for eventString;
    				 * 1 means append to that binding. If the existing binding is
				 * for a callback function and not a Tcl command string, the
				 * existing binding will always be replaced. */
{







|







1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
 *--------------------------------------------------------------
 */

unsigned long
Tk_CreateBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to create binding. */
    void *object,		/* Token for object with which binding is associated. */
    const char *eventString,	/* String describing event sequence that triggers binding. */
    const char *script,		/* Contains Tcl script to execute when binding triggers. */
    int append)			/* 0 means replace any existing binding for eventString;
    				 * 1 means append to that binding. If the existing binding is
				 * for a callback function and not a Tcl command string, the
				 * existing binding will always be replaced. */
{
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
 *--------------------------------------------------------------
 */

int
Tk_DeleteBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to delete binding. */
    ClientData object,		/* Token for object with which binding is associated. */
    const char *eventString)	/* String describing event sequence that triggers binding. */
{
    PatSeq *psPtr;

    assert(bindPtr);
    assert(object);
    assert(eventString);







|







1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
 *--------------------------------------------------------------
 */

int
Tk_DeleteBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to delete binding. */
    void *object,		/* Token for object with which binding is associated. */
    const char *eventString)	/* String describing event sequence that triggers binding. */
{
    PatSeq *psPtr;

    assert(bindPtr);
    assert(object);
    assert(eventString);
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
 *--------------------------------------------------------------
 */

const char *
Tk_GetBinding(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to look for binding. */
    ClientData object,		/* Token for object with which binding is associated. */
    const char *eventString)	/* String describing event sequence that triggers binding. */
{
    const PatSeq *psPtr;

    assert(bindPtr);
    assert(object);
    assert(eventString);







|







1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
 *--------------------------------------------------------------
 */

const char *
Tk_GetBinding(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to look for binding. */
    void *object,		/* Token for object with which binding is associated. */
    const char *eventString)	/* String describing event sequence that triggers binding. */
{
    const PatSeq *psPtr;

    assert(bindPtr);
    assert(object);
    assert(eventString);
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
 *--------------------------------------------------------------
 */

void
Tk_GetAllBindings(
    Tcl_Interp *interp,		/* Interpreter returning result or error. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    ClientData object)		/* Token for object. */
{
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);

    if ((hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object))) {







|







1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
 *--------------------------------------------------------------
 */

void
Tk_GetAllBindings(
    Tcl_Interp *interp,		/* Interpreter returning result or error. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    void *object)		/* Token for object. */
{
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);

    if ((hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object))) {
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
 */

static void
RemovePatSeqFromPromotionLists(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr)		/* Remove this pattern sequence. */
{
    unsigned i;

    assert(bindPtr);
    assert(psPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;







|







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
 */

static void
RemovePatSeqFromPromotionLists(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr)		/* Remove this pattern sequence. */
{
    size_t i;

    assert(bindPtr);
    assert(psPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteAllBindings(
    Tk_BindingTable bindPtr,	/* Table in which to delete bindings. */
    ClientData object)		/* Token for object. */
{
    PatSeq *psPtr;
    PatSeq *nextPtr;
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);







|







2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteAllBindings(
    Tk_BindingTable bindPtr,	/* Table in which to delete bindings. */
    void *object)		/* Token for object. */
{
    PatSeq *psPtr;
    PatSeq *nextPtr;
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);
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

void
Tk_BindEvent(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    XEvent *eventPtr,		/* What actually happened. */
    Tk_Window tkwin,		/* Window on display where event occurred (needed in order to
    				 * locate display information). */
    int numObjects,		/* Number of objects at *objArr. */
    ClientData *objArr)		/* Array of one or more objects to check for a matching binding. */
{
    Tcl_Interp *interp;
    ScreenInfo *screenPtr;
    TkDisplay *dispPtr;
    TkDisplay *oldDispPtr;
    Event *curEvent;
    TkWindow *winPtr = (TkWindow *)tkwin;
    BindInfo *bindInfoPtr;
    Tcl_InterpState interpState;
    LookupTables *physTables;
    PatSeq *psPtr[2];
    PatSeq *matchPtrBuf[32];
    PatSeq **matchPtrArr = matchPtrBuf;
    PSList *psl[2];
    Tcl_DString scripts;
    const char *p;
    const char *end;
    unsigned scriptCount;
    int oldScreen;
    unsigned flags;
    unsigned arraySize;
    unsigned newArraySize;
    unsigned i, k;

    assert(bindPtr);
    assert(eventPtr);
    assert(tkwin);
    assert(numObjects >= 0);

    /*







|
|




















|

|







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

void
Tk_BindEvent(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    XEvent *eventPtr,		/* What actually happened. */
    Tk_Window tkwin,		/* Window on display where event occurred (needed in order to
    				 * locate display information). */
    Tcl_Size numObjects,		/* Number of objects at *objArr. */
    void **objArr)		/* Array of one or more objects to check for a matching binding. */
{
    Tcl_Interp *interp;
    ScreenInfo *screenPtr;
    TkDisplay *dispPtr;
    TkDisplay *oldDispPtr;
    Event *curEvent;
    TkWindow *winPtr = (TkWindow *)tkwin;
    BindInfo *bindInfoPtr;
    Tcl_InterpState interpState;
    LookupTables *physTables;
    PatSeq *psPtr[2];
    PatSeq *matchPtrBuf[32];
    PatSeq **matchPtrArr = matchPtrBuf;
    PSList *psl[2];
    Tcl_DString scripts;
    const char *p;
    const char *end;
    unsigned scriptCount;
    int oldScreen;
    unsigned flags;
    Tcl_Size arraySize;
    unsigned newArraySize;
    Tcl_Size i, k;

    assert(bindPtr);
    assert(eventPtr);
    assert(tkwin);
    assert(numObjects >= 0);

    /*
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
    }

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    bindInfoPtr = winPtr->mainPtr->bindInfo;
    curEvent = bindPtr->eventInfo + eventPtr->type;

    /*
     * Ignore the event completely if it is an Enter, Leave, FocusIn, or
     * FocusOut event with detail NotifyInferior. The reason for ignoring
     * these events is that we don't want transitions between a window and its
     * children to be visible to bindings on the parent: this would cause
     * problems for mega-widgets, since the internal structure of a
     * mega-widget isn't supposed to be visible to people watching the parent.
     *
     * Furthermore we have to compute current time, needed for "event generate".

     */

    switch (eventPtr->type) {
    case EnterNotify:
    case LeaveNotify:
	if (eventPtr->xcrossing.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xcrossing.time;
	}
	if (eventPtr->xcrossing.detail == NotifyInferior) {
	    return;
	}
	break;
    case FocusIn:
    case FocusOut:
	if (eventPtr->xfocus.detail == NotifyInferior) {
	    return;
	}
	break;
    case KeyPress:
    case KeyRelease: {
	int reset = 1;

	if (eventPtr->xkey.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xkey.time;
	}
	/* modifier keys should not influence button events */
	for (i = 0; i < (unsigned) dispPtr->numModKeyCodes; ++i) {
	    if (dispPtr->modKeyCodes[i] == eventPtr->xkey.keycode) {
		reset = 0;
	    }
	}
	if (reset) {
	    /* reset repetition count for button events */
	    bindPtr->eventInfo[ButtonPress].countAny = 0;
	    bindPtr->eventInfo[ButtonPress].countDetailed = 0;
	    bindPtr->eventInfo[ButtonRelease].countAny = 0;
	    bindPtr->eventInfo[ButtonRelease].countDetailed = 0;
	}
	break;
    }
    case ButtonPress:
    case ButtonRelease:
	/* reset repetition count for key events */
	bindPtr->eventInfo[KeyPress].countAny = 0;
	bindPtr->eventInfo[KeyPress].countDetailed = 0;
	bindPtr->eventInfo[KeyRelease].countAny = 0;
	bindPtr->eventInfo[KeyRelease].countDetailed = 0;
	/* fallthru */
    case MotionNotify:
	if (eventPtr->xmotion.time) {







<
<
<
<
<
<
<
|
>









<
<
<
<
<
<
<
<
<









|
|





|









|







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
    }

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    bindInfoPtr = winPtr->mainPtr->bindInfo;
    curEvent = bindPtr->eventInfo + eventPtr->type;

    /*







     * Compute current time needed for "event generate",
     * and reset counters for Key and Button events.
     */

    switch (eventPtr->type) {
    case EnterNotify:
    case LeaveNotify:
	if (eventPtr->xcrossing.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xcrossing.time;
	}









	break;
    case KeyPress:
    case KeyRelease: {
	int reset = 1;

	if (eventPtr->xkey.time) {
	    bindInfoPtr->lastCurrentTime = CurrentTimeInMilliSecs();
	    bindInfoPtr->lastEventTime = eventPtr->xkey.time;
	}
	/* Modifier keys should not influence button events. */
	for (i = 0; i < dispPtr->numModKeyCodes; ++i) {
	    if (dispPtr->modKeyCodes[i] == eventPtr->xkey.keycode) {
		reset = 0;
	    }
	}
	if (reset) {
	    /* Reset repetition count for button events. */
	    bindPtr->eventInfo[ButtonPress].countAny = 0;
	    bindPtr->eventInfo[ButtonPress].countDetailed = 0;
	    bindPtr->eventInfo[ButtonRelease].countAny = 0;
	    bindPtr->eventInfo[ButtonRelease].countDetailed = 0;
	}
	break;
    }
    case ButtonPress:
    case ButtonRelease:
	/* Reset repetition count for key events. */
	bindPtr->eventInfo[KeyPress].countAny = 0;
	bindPtr->eventInfo[KeyPress].countDetailed = 0;
	bindPtr->eventInfo[KeyRelease].countAny = 0;
	bindPtr->eventInfo[KeyRelease].countDetailed = 0;
	/* fallthru */
    case MotionNotify:
	if (eventPtr->xmotion.time) {
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
    bindPtr->curEvent = curEvent;
    physTables = &bindPtr->lookupTables;
    scriptCount = 0;
    arraySize = 0;
    Tcl_DStringInit(&scripts);

    if ((size_t) numObjects > SIZE_OF_ARRAY(matchPtrBuf)) {
	/* it's unrealistic that the buffer size is too small, but who knows? */
	matchPtrArr = (PatSeq **)ckalloc(numObjects*sizeof(matchPtrArr[0]));
    }
    memset(matchPtrArr, 0, numObjects*sizeof(matchPtrArr[0]));

    if (!PromArr_IsEmpty(bindPtr->promArr)) {
	for (k = 0; k < (unsigned) numObjects; ++k) {
	    psl[1] = PromArr_Last(bindPtr->promArr);
	    psl[0] = psl[1] - 1;

	    /*
	     * Loop over all promoted bindings, finding the longest matching one.
	     *
	     * Note that we must process all lists, because all matching patterns
	     * have to be promoted. Normally at most one list will be processed, and
	     * usually this list only contains one or two patterns.
	     */

	    for (i = PromArr_Size(bindPtr->promArr); i > 0; --i, --psl[0], --psl[1]) {
		psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psl[1], i, curEvent, objArr[k], NULL);

		if (IsBetterMatch(matchPtrArr[k], psPtr[0])) {
		    /* we will process it later, because we still may find a pattern with better match */
		    matchPtrArr[k] = psPtr[0];
		}
		if (!PSList_IsEmpty(psl[1])) {
		    /* we have promoted sequences, adjust array size */
		    arraySize = Max(i + 1, arraySize);
		}
	    }
	}
    }

    /*
     * 1. Look for bindings for the specific detail (button and key events).
     * 2. Look for bindings without detail.
     */

    for (k = 0; k < (unsigned) numObjects; ++k) {
	PSList *psSuccList = PromArr_First(bindPtr->promArr);
	PatSeq *bestPtr;

	psl[0] = GetLookupForEvent(physTables, curEvent, (Tcl_Obj *)objArr[k], 1);
	psl[1] = GetLookupForEvent(physTables, curEvent, (Tcl_Obj *)objArr[k], 0);

	assert(psl[0] == NULL || psl[0] != psl[1]);

	psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psSuccList, 0, curEvent, objArr[k], NULL);
	psPtr[1] = MatchPatterns(dispPtr, bindPtr, psl[1], psSuccList, 0, curEvent, objArr[k], NULL);

	if (!PSList_IsEmpty(psSuccList)) {
	    /* we have promoted sequences, adjust array size */
	    arraySize = Max(1u, arraySize);
	}

	bestPtr = psPtr[0] ? psPtr[0] : psPtr[1];

	if (matchPtrArr[k]) {
	    if (IsBetterMatch(matchPtrArr[k], bestPtr)) {
		matchPtrArr[k] = bestPtr;







|





|















|



|











|












|
|







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
    bindPtr->curEvent = curEvent;
    physTables = &bindPtr->lookupTables;
    scriptCount = 0;
    arraySize = 0;
    Tcl_DStringInit(&scripts);

    if ((size_t) numObjects > SIZE_OF_ARRAY(matchPtrBuf)) {
	/* It's unrealistic that the buffer size is too small, but who knows? */
	matchPtrArr = (PatSeq **)ckalloc(numObjects*sizeof(matchPtrArr[0]));
    }
    memset(matchPtrArr, 0, numObjects*sizeof(matchPtrArr[0]));

    if (!PromArr_IsEmpty(bindPtr->promArr)) {
	for (k = 0; k < numObjects; ++k) {
	    psl[1] = PromArr_Last(bindPtr->promArr);
	    psl[0] = psl[1] - 1;

	    /*
	     * Loop over all promoted bindings, finding the longest matching one.
	     *
	     * Note that we must process all lists, because all matching patterns
	     * have to be promoted. Normally at most one list will be processed, and
	     * usually this list only contains one or two patterns.
	     */

	    for (i = PromArr_Size(bindPtr->promArr); i > 0; --i, --psl[0], --psl[1]) {
		psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psl[1], i, curEvent, objArr[k], NULL);

		if (IsBetterMatch(matchPtrArr[k], psPtr[0])) {
		    /* We will process it later, because we still may find a pattern with better match. */
		    matchPtrArr[k] = psPtr[0];
		}
		if (!PSList_IsEmpty(psl[1])) {
		    /* We have promoted sequences, adjust array size. */
		    arraySize = Max(i + 1, arraySize);
		}
	    }
	}
    }

    /*
     * 1. Look for bindings for the specific detail (button and key events).
     * 2. Look for bindings without detail.
     */

    for (k = 0; k < numObjects; ++k) {
	PSList *psSuccList = PromArr_First(bindPtr->promArr);
	PatSeq *bestPtr;

	psl[0] = GetLookupForEvent(physTables, curEvent, (Tcl_Obj *)objArr[k], 1);
	psl[1] = GetLookupForEvent(physTables, curEvent, (Tcl_Obj *)objArr[k], 0);

	assert(psl[0] == NULL || psl[0] != psl[1]);

	psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psSuccList, 0, curEvent, objArr[k], NULL);
	psPtr[1] = MatchPatterns(dispPtr, bindPtr, psl[1], psSuccList, 0, curEvent, objArr[k], NULL);

	if (!PSList_IsEmpty(psSuccList)) {
	    /* We have promoted sequences, adjust array size. */
	    arraySize = Max(1, arraySize);
	}

	bestPtr = psPtr[0] ? psPtr[0] : psPtr[1];

	if (matchPtrArr[k]) {
	    if (IsBetterMatch(matchPtrArr[k], bestPtr)) {
		matchPtrArr[k] = bestPtr;
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
		    matchPtrArr[k] = matchPtr;
		}
	    }
	}

	if (matchPtrArr[k]) {
	    ExpandPercents(winPtr, matchPtrArr[k]->script, curEvent, scriptCount++, &scripts);
	    /* nul is added to the scripts string to separate the various scripts */
	    Tcl_DStringAppend(&scripts, "", 1);
	}
    }

    PromArr_SetSize(bindPtr->promArr, arraySize);

    /*
     * Remove expired pattern sequences.
     */

    for (i = 0, newArraySize = 0; i < arraySize; ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;
	PSEntry *psNext;

	for (psEntry = PSList_First(psList); psEntry; psEntry = psNext) {
	    const TkPattern *patPtr;

	    assert(i + 1 < psEntry->psPtr->numPats);

	    psNext = PSList_Next(psEntry);
	    patPtr = &psEntry->psPtr->pats[i + 1];

	    /*
	     * We have to remove the following entries from promotion list (but
	     * only if we don't want to keep it):







|


















|







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
		    matchPtrArr[k] = matchPtr;
		}
	    }
	}

	if (matchPtrArr[k]) {
	    ExpandPercents(winPtr, matchPtrArr[k]->script, curEvent, scriptCount++, &scripts);
	    /* Null is added to the scripts string to separate the various scripts. */
	    Tcl_DStringAppend(&scripts, "", 1);
	}
    }

    PromArr_SetSize(bindPtr->promArr, arraySize);

    /*
     * Remove expired pattern sequences.
     */

    for (i = 0, newArraySize = 0; i < arraySize; ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;
	PSEntry *psNext;

	for (psEntry = PSList_First(psList); psEntry; psEntry = psNext) {
	    const TkPattern *patPtr;

	    assert(i + 1 < (Tcl_Size)psEntry->psPtr->numPats);

	    psNext = PSList_Next(psEntry);
	    patPtr = &psEntry->psPtr->pats[i + 1];

	    /*
	     * We have to remove the following entries from promotion list (but
	     * only if we don't want to keep it):
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
		    }
		    break;
		}
	    }
	}

	if (!PSList_IsEmpty(psList)) {
	    /* we still have promoted sequences, adjust array size */
	    newArraySize = Max(i + 1, newArraySize);
	}
    }

    PromArr_SetSize(bindPtr->promArr, newArraySize);

    if (matchPtrArr != matchPtrBuf) {
	ckfree(matchPtrArr);
    }

    if (Tcl_DStringLength(&scripts) == 0) {
	return; /* nothing to do */
    }

    /*
     * Now go back through and evaluate the binding for each object, in order,
     * dealing with "break" and "continue" exceptions appropriately.
     *
     * There are two tricks here:







|











|







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
		    }
		    break;
		}
	    }
	}

	if (!PSList_IsEmpty(psList)) {
	    /* We still have promoted sequences, adjust array size. */
	    newArraySize = Max(i + 1, newArraySize);
	}
    }

    PromArr_SetSize(bindPtr->promArr, newArraySize);

    if (matchPtrArr != matchPtrBuf) {
	ckfree(matchPtrArr);
    }

    if (Tcl_DStringLength(&scripts) == 0) {
	return; /* Nothing to do. */
    }

    /*
     * Now go back through and evaluate the binding for each object, in order,
     * dealing with "break" and "continue" exceptions appropriately.
     *
     * There are two tricks here:
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
     * something that destroys ".", bindInfoPtr would have been freed, but we
     * can tell that by first checking to see if winPtr->mainPtr == NULL.
     */

    Tcl_Preserve(bindInfoPtr);

    for (p = Tcl_DStringValue(&scripts), end = p + Tcl_DStringLength(&scripts); p < end; ) {
	unsigned len = strlen(p);
	int code;

	if (!bindInfoPtr->deleted) {
	    ++screenPtr->bindingDepth;
	}
	Tcl_AllowExceptions(interp);








|







2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
     * something that destroys ".", bindInfoPtr would have been freed, but we
     * can tell that by first checking to see if winPtr->mainPtr == NULL.
     */

    Tcl_Preserve(bindInfoPtr);

    for (p = Tcl_DStringValue(&scripts), end = p + Tcl_DStringLength(&scripts); p < end; ) {
	Tcl_Size len = strlen(p);
	int code;

	if (!bindInfoPtr->deleted) {
	    ++screenPtr->bindingDepth;
	}
	Tcl_AllowExceptions(interp);

2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
 */

/* helper function */
static int
VirtPatIsBound(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr,		/* Test this pattern. */
    ClientData object,		/* Check for this binding tag. */
    PatSeq **physPtrPtr)	/* Input: the best physical event.
    				 * Output: the physical event associated with matching virtual event. */
{
    PatternTableKey key;
    const struct VirtOwners *owners;
    unsigned i;

    assert(bindPtr);
    assert(psPtr);
    assert(!psPtr->object);
    assert(physPtrPtr);

    if (*physPtrPtr) {
	const TkPattern *physPatPtr = (*physPtrPtr)->pats;
	const TkPattern *virtPatPtr = psPtr->pats;

	if (physPatPtr->info || !virtPatPtr->info) {
	    if (IsSubsetOf(virtPatPtr->modMask, physPatPtr->modMask)) {
		return 0; /* we cannot surpass this match */
	    }
	}
    }

    /* otherwise on some systems the key contains uninitialized bytes */
    memset(&key, 0, sizeof(key));

    key.object = object;
    key.type = VirtualEvent;
    owners = psPtr->ptr.owners;

    for (i = 0; i < VirtOwners_Size(owners); ++i) {







|


















|




|







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
 */

/* helper function */
static int
VirtPatIsBound(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr,		/* Test this pattern. */
    void *object,		/* Check for this binding tag. */
    PatSeq **physPtrPtr)	/* Input: the best physical event.
    				 * Output: the physical event associated with matching virtual event. */
{
    PatternTableKey key;
    const struct VirtOwners *owners;
    unsigned i;

    assert(bindPtr);
    assert(psPtr);
    assert(!psPtr->object);
    assert(physPtrPtr);

    if (*physPtrPtr) {
	const TkPattern *physPatPtr = (*physPtrPtr)->pats;
	const TkPattern *virtPatPtr = psPtr->pats;

	if (physPatPtr->info || !virtPatPtr->info) {
	    if (IsSubsetOf(virtPatPtr->modMask, physPatPtr->modMask)) {
		return 0; /* We cannot surpass this match. */
	    }
	}
    }

    /* Otherwise on some systems the key contains uninitialized bytes. */
    memset(&key, 0, sizeof(key));

    key.object = object;
    key.type = VirtualEvent;
    owners = psPtr->ptr.owners;

    for (i = 0; i < VirtOwners_Size(owners); ++i) {
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
    return 0;
}

/* helper function */
static int
Compare(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr) /* most recent match */
{
    int diff;

    if (!fstMatchPtr) { return +1; }
    assert(sndMatchPtr);
    diff = CountSpecialized(fstMatchPtr, sndMatchPtr);
    return diff ? diff : (int) sndMatchPtr->count - (int) fstMatchPtr->count;







|







2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
    return 0;
}

/* helper function */
static int
Compare(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr) /* Most recent match. */
{
    int diff;

    if (!fstMatchPtr) { return +1; }
    assert(sndMatchPtr);
    diff = CountSpecialized(fstMatchPtr, sndMatchPtr);
    return diff ? diff : (int) sndMatchPtr->count - (int) fstMatchPtr->count;
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
    /* Finally compare modifier masks of last pattern. */

    if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
    if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }

    return fstCount - sndCount;
}















static PatSeq *
MatchPatterns(
    TkDisplay *dispPtr,		/* Display from which the event came. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PSList *psList,		/* List of potentially matching patterns, can be NULL. */
    PSList *psSuccList,		/* Add all matching higher-level pattern sequences to this list.
    				 * Can be NULL. */
    unsigned patIndex,		/* Match only this tag in sequence. */
    const Event *curEvent,	/* Match this event. */
    ClientData object,		/* Check for this binding tag. */
    PatSeq **physPtrPtr)	/* Input: the best physical event; NULL if we test physical events.
    				 * Output: the associated physical event for the best matching virtual
				 * event; NULL when we match physical events. */
{
    Window window;
    PSEntry *psEntry;
    PatSeq *bestPtr;
    PatSeq *bestPhysPtr;
    unsigned bestModMask;
    const PSModMaskArr *bestModMaskArr = NULL;
    int i, isModKeyOnly = 0;


    assert(dispPtr);
    assert(bindPtr);
    assert(curEvent);

    if (!psList) {
	return NULL;







>
>
>
>
>
>
>
>
>
>
>
>
>
>










|










|
>







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
    /* Finally compare modifier masks of last pattern. */

    if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
    if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }

    return fstCount - sndCount;
}

/* helper function */
static int
IsPSInPSList(
    const PatSeq *psPtr,   /* Is this pattern sequence... */
    const PSList *psList)  /* ...an element of this list of patterns sequence? */
{
    PSEntry *psEntry;

    TK_DLIST_FOREACH(psEntry, psList) {
        if (psEntry->psPtr == psPtr) { return 1; }
    }
    return 0;
}

static PatSeq *
MatchPatterns(
    TkDisplay *dispPtr,		/* Display from which the event came. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PSList *psList,		/* List of potentially matching patterns, can be NULL. */
    PSList *psSuccList,		/* Add all matching higher-level pattern sequences to this list.
    				 * Can be NULL. */
    unsigned patIndex,		/* Match only this tag in sequence. */
    const Event *curEvent,	/* Match this event. */
    void *object,		/* Check for this binding tag. */
    PatSeq **physPtrPtr)	/* Input: the best physical event; NULL if we test physical events.
    				 * Output: the associated physical event for the best matching virtual
				 * event; NULL when we match physical events. */
{
    Window window;
    PSEntry *psEntry;
    PatSeq *bestPtr;
    PatSeq *bestPhysPtr;
    unsigned bestModMask;
    const PSModMaskArr *bestModMaskArr = NULL;
    int isModKeyOnly = 0;
    Tcl_Size i;

    assert(dispPtr);
    assert(bindPtr);
    assert(curEvent);

    if (!psList) {
	return NULL;
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
	    assert(psPtr->numPats > patIndex);

	    if (psPtr->object
		    ? psPtr->object == object
		    : VirtPatIsBound(bindPtr, psPtr, object, physPtrPtr)) {
		TkPattern *patPtr = psPtr->pats + patIndex;

                /* ignore modifier key events, and KeyRelease events if the current event
                 * is of a different type (e.g. a Button event)
                 */
                psEntry->keepIt = isModKeyOnly || \
                        ((patPtr->eventType != (unsigned) curEvent->xev.type) && curEvent->xev.type == KeyRelease);

		if (patPtr->eventType == (unsigned) curEvent->xev.type
			&& (curEvent->xev.type != CreateNotify
				|| curEvent->xev.xcreatewindow.parent == window)
			&& (!patPtr->name || patPtr->name == curEvent->detail.name)
			&& (!patPtr->info || patPtr->info == curEvent->detail.info)) {
		    /*
		     * Resolve the modifier mask for Alt and Mod keys. Unfortunately this
		     * cannot be done in ParseEventDescription, otherwise this function would
		     * be the better place.
		     */
		    unsigned modMask = ResolveModifiers(dispPtr, patPtr->modMask);
		    unsigned curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);

		    psEntry->expired = 1; /* remove it from promotion list */
                    psEntry->keepIt = 0; /* don't keep matching patterns */

		    if (IsSubsetOf(modMask, curModMask)) {
			unsigned count = patPtr->info ? curEvent->countDetailed : curEvent->countAny;

			if (patIndex < PSModMaskArr_Size(psEntry->lastModMaskArr)) {
			    PSModMaskArr_Set(psEntry->lastModMaskArr, patIndex, &modMask);
			}

			/*
			 * This pattern is finally matching.
			 */

			if (psPtr->numPats == patIndex + 1) {
			    if (patPtr->count <= count) {
				/*
				 * This is also a final pattern.
				 * We always prefer the pattern with better match.
				 * If completely equal than prefer most recently defined pattern.
				 */

				int cmp = Compare(bestPtr, psPtr);

				if (cmp == 0) {







|


















|
|















|







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
	    assert(psPtr->numPats > patIndex);

	    if (psPtr->object
		    ? psPtr->object == object
		    : VirtPatIsBound(bindPtr, psPtr, object, physPtrPtr)) {
		TkPattern *patPtr = psPtr->pats + patIndex;

                /* Ignore modifier key events, and KeyRelease events if the current event
                 * is of a different type (e.g. a Button event)
                 */
                psEntry->keepIt = isModKeyOnly || \
                        ((patPtr->eventType != (unsigned) curEvent->xev.type) && curEvent->xev.type == KeyRelease);

		if (patPtr->eventType == (unsigned) curEvent->xev.type
			&& (curEvent->xev.type != CreateNotify
				|| curEvent->xev.xcreatewindow.parent == window)
			&& (!patPtr->name || patPtr->name == curEvent->detail.name)
			&& (!patPtr->info || patPtr->info == curEvent->detail.info)) {
		    /*
		     * Resolve the modifier mask for Alt and Mod keys. Unfortunately this
		     * cannot be done in ParseEventDescription, otherwise this function would
		     * be the better place.
		     */
		    unsigned modMask = ResolveModifiers(dispPtr, patPtr->modMask);
		    unsigned curModMask = ResolveModifiers(dispPtr, bindPtr->curModMask);

		    psEntry->expired = 1; /* Remove it from promotion list. */
                    psEntry->keepIt = 0;  /* Don't keep matching patterns. */

		    if (IsSubsetOf(modMask, curModMask)) {
			unsigned count = patPtr->info ? curEvent->countDetailed : curEvent->countAny;

			if (patIndex < PSModMaskArr_Size(psEntry->lastModMaskArr)) {
			    PSModMaskArr_Set(psEntry->lastModMaskArr, patIndex, &modMask);
			}

			/*
			 * This pattern is finally matching.
			 */

			if (psPtr->numPats == patIndex + 1) {
			    if (patPtr->count <= count) {
				/*
				 * This is also a final pattern (i.e. the pattern sequence is complete).
				 * We always prefer the pattern with better match.
				 * If completely equal than prefer most recently defined pattern.
				 */

				int cmp = Compare(bestPtr, psPtr);

				if (cmp == 0) {
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908

2909
2910

2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928








2929
2930
2931
2932
2933
2934
2935
				    bestModMaskArr = psEntry->lastModMaskArr;
				    if (physPtrPtr) {
					bestPhysPtr = *physPtrPtr;
				    }
				}
			    } else {
				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* don't remove it from promotion list */
			    }
			} else if (psSuccList) {
			    /*
			     * Not a final pattern, but matching, so promote it to next level.

			     * But do not promote if count of current pattern is not yet reached.
			     */

			    if (patPtr->count == psEntry->count) {
				PSEntry *psNewEntry;

				assert(!patPtr->name);
				psNewEntry = MakeListEntry(
				    &bindPtr->lookupTables.entryPool, psPtr, psPtr->modMaskUsed);
				if (!PSModMaskArr_IsEmpty(psNewEntry->lastModMaskArr)) {
				    PSModMaskArr_Set(psNewEntry->lastModMaskArr, patIndex, &modMask);
				}
				assert(psNewEntry->keepIt);
				assert(psNewEntry->count == 1u);
				PSList_Append(psSuccList, psNewEntry);
				psNewEntry->window = window; /* bind to current window */
			    } else {
				assert(psEntry->count < patPtr->count);
				DEBUG(psEntry->expired = 0;)
				psEntry->count += 1;
				psEntry->keepIt = 1; /* don't remove it from promotion list */








			    }
			}
		    }
		}
	    }
	}
    }







|



|
>


>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>







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
				    bestModMaskArr = psEntry->lastModMaskArr;
				    if (physPtrPtr) {
					bestPhysPtr = *physPtrPtr;
				    }
				}
			    } else {
				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* Don't remove it from promotion list. */
			    }
			} else if (psSuccList) {
			    /*
			     * Not a final pattern, but matching (i.e. successive patterns match the pattern sequence so far),
			     * so promote the pattern sequence to next level if not already promoted in the success list.
			     * But do not promote if count of current pattern is not yet reached.
			     */
			    if (!IsPSInPSList(psPtr, psSuccList)) {
				if (patPtr->count == psEntry->count) {
				    PSEntry *psNewEntry;

				    assert(!patPtr->name);
				    psNewEntry = MakeListEntry(
					&bindPtr->lookupTables.entryPool, psPtr, psPtr->modMaskUsed);
				    if (!PSModMaskArr_IsEmpty(psNewEntry->lastModMaskArr)) {
					PSModMaskArr_Set(psNewEntry->lastModMaskArr, patIndex, &modMask);
				    }
				    assert(psNewEntry->keepIt);
				    assert(psNewEntry->count == 1u);
				    PSList_Append(psSuccList, psNewEntry);
				    psNewEntry->window = window; /* Bind to current window. */
				} else {
				    assert(psEntry->count < patPtr->count);
				    DEBUG(psEntry->expired = 0;)
				    psEntry->count += 1;
				    psEntry->keepIt = 1; /* Don't remove it from promotion list. */
				}
			    } else {
			        /*
				 * Pattern sequence is already present in the success list.
				 */

				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* Don't remove it from promotion list. */
			    }
			}
		    }
		}
	    }
	}
    }
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
	snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "u", unumber);	\
	string = numStorage;						\
    }

    while (1) {
	char numStorage[TCL_INTEGER_SPACE];
	const char *string;
	Tcl_WideInt number;     /* signed */
	Tcl_WideUInt unumber;   /* unsigned */

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */

	for (string = before; *string && *string != '%'; ++string)
	    ;
	if (string != before) {
	    Tcl_DStringAppend(dsPtr, before, string - before);
	    before = string;
	}
	if (!*before) {
	    break;
	}

	/*







|
|









|







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
	snprintf(numStorage, sizeof(numStorage), "%" TCL_LL_MODIFIER "u", unumber);	\
	string = numStorage;						\
    }

    while (1) {
	char numStorage[TCL_INTEGER_SPACE];
	const char *string;
	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)
	    ;
	if (string != before) {
	    Tcl_DStringAppend(dsPtr, before, (Tcl_Size)(string - before));
	    before = string;
	}
	if (!*before) {
	    break;
	}

	/*
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
	    numStorage[0] = before[1];
	    numStorage[1] = '\0';
	    string = numStorage;
	    break;
	}
	{   /* local scope */
	    int cvtFlags;
	    unsigned spaceNeeded = Tcl_ScanElement(string, &cvtFlags);
	    unsigned length = Tcl_DStringLength(dsPtr);

	    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	    spaceNeeded = Tcl_ConvertElement(
		    string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES);
	    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	    before += 2;
	}







|
|







3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
	    numStorage[0] = before[1];
	    numStorage[1] = '\0';
	    string = numStorage;
	    break;
	}
	{   /* local scope */
	    int cvtFlags;
	    Tcl_Size spaceNeeded = Tcl_ScanElement(string, &cvtFlags);
	    Tcl_Size length = Tcl_DStringLength(dsPtr);

	    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	    spaceNeeded = Tcl_ConvertElement(
		    string, Tcl_DStringValue(dsPtr) + length, cvtFlags | TCL_DONT_USE_BRACES);
	    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	    before += 2;
	}
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_EventObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index, i;
    char *name;
    const char *event;
    Tk_Window tkwin;
    TkBindInfo bindInfo;
    VirtualEventTable *vetPtr;

    static const char *const optionStrings[] = { "add", "delete", "generate", "info", NULL };





    enum options { EVENT_ADD, EVENT_DELETE, EVENT_GENERATE, EVENT_INFO };






    assert(clientData);

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(
	    interp, objv[1], optionStrings, sizeof(char *), "option", 0, &index) != TCL_OK) {
#ifdef SUPPORT_DEBUGGING
    	if (strcmp(Tcl_GetString(objv[1]), "debug") == 0) {
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "debug number");
		return TCL_ERROR;
	    }
	    Tcl_GetIntFromObj(interp, objv[2], &BindCount);
	    return TCL_OK;
	}
#endif
	return TCL_ERROR;
    }

    tkwin = (Tk_Window) clientData;
    bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo;
    vetPtr = &bindInfo->virtualEventTable;








|











|
>
>
>
>
>
|
>
>
>
>
>









<
<
<
<
<
<
<
<
<
<







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_EventObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index, i;
    char *name;
    const char *event;
    Tk_Window tkwin;
    TkBindInfo bindInfo;
    VirtualEventTable *vetPtr;

    static const char *const optionStrings[] = { "add",
#if SUPPORT_DEBUGGING
	"debug",
#endif
	"delete", "generate", "info", NULL
    };
    enum options { EVENT_ADD,
#if SUPPORT_DEBUGGING
	EVENT_DEBUG,
#endif
	EVENT_DELETE, EVENT_GENERATE, EVENT_INFO
    };

    assert(clientData);

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(
	    interp, objv[1], optionStrings, sizeof(char *), "option", 0, &index) != TCL_OK) {










	return TCL_ERROR;
    }

    tkwin = (Tk_Window) clientData;
    bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo;
    vetPtr = &bindInfo->virtualEventTable;

3381
3382
3383
3384
3385
3386
3387
















3388
3389
3390
3391
3392
3393
3394
	for (i = 3; i < objc; ++i) {
	    event = Tcl_GetString(objv[i]);
	    if (!CreateVirtualEvent(interp, vetPtr, name, event)) {
		return TCL_ERROR;
	    }
	}
	break;
















    case EVENT_DELETE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?");
	    return TCL_ERROR;
	}
	name = Tcl_GetString(objv[2]);
	if (objc == 3) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	for (i = 3; i < objc; ++i) {
	    event = Tcl_GetString(objv[i]);
	    if (!CreateVirtualEvent(interp, vetPtr, name, event)) {
		return TCL_ERROR;
	    }
	}
	break;
#if SUPPORT_DEBUGGING
    case EVENT_DEBUG:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "debug number");
	    return TCL_ERROR;
	}
	if (objc < 3) {
	    Tcl_SetObjResult(interp,
		Tcl_NewIntObj(BindCount));
	    return TCL_OK;
	}
	if (Tcl_GetIntFromObj(interp, objv[2], &BindCount) != TCL_OK) {
	    return TCL_ERROR;
	}
	return TCL_OK;
#endif
    case EVENT_DELETE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?");
	    return TCL_ERROR;
	}
	name = Tcl_GetString(objv[2]);
	if (objc == 3) {
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
    assert(eventString);

    if (!(virtUid = GetVirtualEventUid(interp, virtString))) {
	return 0;
    }

    /*
     * Find/create physical event
     */

    if (!(psPtr = FindSequence(interp, &vetPtr->lookupTables, NULL, eventString, 1, 0, NULL))) {
	return 0;
    }
    assert(TEST_PSENTRY(psPtr));








|







3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
    assert(eventString);

    if (!(virtUid = GetVirtualEventUid(interp, virtString))) {
	return 0;
    }

    /*
     * Find/create physical event.
     */

    if (!(psPtr = FindSequence(interp, &vetPtr->lookupTables, NULL, eventString, 1, 0, NULL))) {
	return 0;
    }
    assert(TEST_PSENTRY(psPtr));

3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663

	assert(TEST_PSENTRY(psPtr));

	if (!eventPSPtr || psPtr == eventPSPtr) {
	    VirtOwners *owners = psPtr->ptr.owners;
	    int iVirt = VirtOwners_Find(owners, vhPtr);

	    assert(iVirt != -1); /* otherwise we couldn't find owner, and this should not happen */

	    /*
	     * Remove association between this physical event and the given
	     * virtual event that it triggers.
	     */

	    if (VirtOwners_Size(owners) > 1) {







|







3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701

	assert(TEST_PSENTRY(psPtr));

	if (!eventPSPtr || psPtr == eventPSPtr) {
	    VirtOwners *owners = psPtr->ptr.owners;
	    int iVirt = VirtOwners_Find(owners, vhPtr);

	    assert(iVirt != -1); /* Otherwise we couldn't find owner, and this should not happen. */

	    /*
	     * Remove association between this physical event and the given
	     * virtual event that it triggers.
	     */

	    if (VirtOwners_Size(owners) > 1) {
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
 *---------------------------------------------------------------------------
 */

static int
HandleEventGenerate(
    Tcl_Interp *interp,		/* Interp for errors return and name lookup. */
    Tk_Window mainWin,		/* Main window associated with interp. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    union { XEvent general; XVirtualEvent virt; } event;

    const char *p;
    const char *name;
    const char *windowName;
    Tcl_QueuePosition pos;
    TkPattern pat;
    Tk_Window tkwin;
    Tk_Window tkwin2;
    TkWindow *mainPtr;
    unsigned eventMask;
    Tcl_Obj *userDataObj;
    int synch;
    int warp;
    unsigned count;
    unsigned flags;
    int number;
    unsigned i;

    static const char *const fieldStrings[] = {
	"-when",	"-above",	"-borderwidth",	"-button",
	"-count",	"-data",	"-delta",	"-detail",
	"-focus",	"-height",
	"-keycode",	"-keysym",	"-mode",	"-override",
	"-place",	"-root",	"-rootx",	"-rooty",







|



















|







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
 *---------------------------------------------------------------------------
 */

static int
HandleEventGenerate(
    Tcl_Interp *interp,		/* Interp for errors return and name lookup. */
    Tk_Window mainWin,		/* Main window associated with interp. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    union { XEvent general; XVirtualEvent virt; } event;

    const char *p;
    const char *name;
    const char *windowName;
    Tcl_QueuePosition pos;
    TkPattern pat;
    Tk_Window tkwin;
    Tk_Window tkwin2;
    TkWindow *mainPtr;
    unsigned eventMask;
    Tcl_Obj *userDataObj;
    int synch;
    int warp;
    unsigned count;
    unsigned flags;
    int number;
    Tcl_Size i;

    static const char *const fieldStrings[] = {
	"-when",	"-above",	"-borderwidth",	"-button",
	"-count",	"-data",	"-delta",	"-detail",
	"-focus",	"-height",
	"-keycode",	"-keysym",	"-mode",	"-override",
	"-place",	"-root",	"-rootx",	"-rooty",
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
    eventMask = 0;
    userDataObj = NULL;
    if ((count = ParseEventDescription(interp, &p, &pat, &eventMask)) == 0) {
	return TCL_ERROR;
    }
    if (count != 1u) {
	Tcl_SetObjResult(interp,
		Tcl_NewStringObj("Double, Triple, or Quadruple modifier not allowed", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_MODIFIER", NULL);
	return TCL_ERROR;
    }
    if (*p) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("only one event specification allowed", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "MULTIPLE", NULL);
	return TCL_ERROR;
    }

    memset(&event, 0, sizeof(event));
    event.general.xany.type = pat.eventType;
    event.general.xany.serial = NextRequest(Tk_Display(tkwin));







|




|







3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
    eventMask = 0;
    userDataObj = NULL;
    if ((count = ParseEventDescription(interp, &p, &pat, &eventMask)) == 0) {
	return TCL_ERROR;
    }
    if (count != 1u) {
	Tcl_SetObjResult(interp,
		Tcl_NewStringObj("Double, Triple, or Quadruple modifier not allowed", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_MODIFIER", NULL);
	return TCL_ERROR;
    }
    if (*p) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("only one event specification allowed", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "MULTIPLE", NULL);
	return TCL_ERROR;
    }

    memset(&event, 0, sizeof(event));
    event.general.xany.type = pat.eventType;
    event.general.xany.serial = NextRequest(Tk_Display(tkwin));
3969
3970
3971
3972
3973
3974
3975
3976
3977




3978

3979
3980
3981
3982
3983
3984
3985
     * Process the remaining arguments to fill in additional fields of the event.
     */

    synch = 1;
    warp = 0;
    pos = TCL_QUEUE_TAIL;

    for (i = 2; i < (unsigned) objc; i += 2) {
	Tcl_Obj *optionPtr, *valuePtr;




	int badOpt = 0;

	int index;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {







|

>
>
>
>

>







4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
     * Process the remaining arguments to fill in additional fields of the event.
     */

    synch = 1;
    warp = 0;
    pos = TCL_QUEUE_TAIL;

    for (i = 2; i < objc; i += 2) {
	Tcl_Obj *optionPtr, *valuePtr;
#if defined(_MSC_VER)
        /* Work around MSVC compiler optimization bug, see [d93c8175fd]. */
	volatile int badOpt = 0;
#else
	int badOpt = 0;
#endif
	int index;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
 *----------------------------------------------------------------------
 */

static PatSeq *
FindSequence(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    LookupTables *lookupTables,	/* Tables used for lookup. */
    ClientData object,		/* For binding table, token for object with which binding is
    				 * associated. For virtual event table, NULL. */
    const char *eventString,	/* String description of pattern to match on. See user
    				 * documentation for details. */
    int create,			/* 0 means don't create the entry if it doesn't already exist.
    				 * 1 means create. */
    int allowVirtual,		/* 0 means that virtual events are not allowed in the sequence.
    				 * 1 otherwise. */







|







4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
 *----------------------------------------------------------------------
 */

static PatSeq *
FindSequence(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    LookupTables *lookupTables,	/* Tables used for lookup. */
    void *object,		/* For binding table, token for object with which binding is
    				 * associated. For virtual event table, NULL. */
    const char *eventString,	/* String description of pattern to match on. See user
    				 * documentation for details. */
    int create,			/* 0 means don't create the entry if it doesn't already exist.
    				 * 1 means create. */
    int allowVirtual,		/* 0 means that virtual events are not allowed in the sequence.
    				 * 1 otherwise. */
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
	    ckfree(psPtr);
	    return NULL;
	}

	if (eventMask & VirtualEventMask) {
	    if (!allowVirtual) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"virtual event not allowed in definition of another virtual event", -1));
		Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "INNER", NULL);
		ckfree(psPtr);
		return NULL;
	    }
	    virtualFound = 1;
	}








|







4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
	    ckfree(psPtr);
	    return NULL;
	}

	if (eventMask & VirtualEventMask) {
	    if (!allowVirtual) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"virtual event not allowed in definition of another virtual event", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "INNER", NULL);
		ckfree(psPtr);
		return NULL;
	    }
	    virtualFound = 1;
	}

4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
     *------------------------------------------------------------------
     * Step 2: find the sequence in the binding table if it exists, and
     * add a new sequence to the table if it doesn't.
     *------------------------------------------------------------------
     */

    if (numPats == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("no events specified in binding", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "NO_EVENTS", NULL);
	ckfree(psPtr);
	return NULL;
    }
    if (numPats > 1u && virtualFound) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("virtual events may not be composed", -1));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "COMPOSITION", NULL);
	ckfree(psPtr);
	return NULL;
    }
    if (patsBufSize > numPats) {
	psPtr = (PatSeq *)ckrealloc(psPtr, PATSEQ_MEMSIZE(numPats));
    }







|





|







4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
     *------------------------------------------------------------------
     * Step 2: find the sequence in the binding table if it exists, and
     * add a new sequence to the table if it doesn't.
     *------------------------------------------------------------------
     */

    if (numPats == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("no events specified in binding", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "NO_EVENTS", NULL);
	ckfree(psPtr);
	return NULL;
    }
    if (numPats > 1u && virtualFound) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("virtual events may not be composed", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "COMPOSITION", NULL);
	ckfree(psPtr);
	return NULL;
    }
    if (patsBufSize > numPats) {
	psPtr = (PatSeq *)ckrealloc(psPtr, PATSEQ_MEMSIZE(numPats));
    }
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
    unsigned count = 1;

    assert(eventStringPtr);
    assert(patPtr);
    assert(eventMaskPtr);

    p = *eventStringPtr;
    memset(patPtr, 0, sizeof(TkPattern)); /* otherwise memcmp doesn't work */

    /*
     * Handle simple ASCII characters.
     */

    if (*p != '<') {
	char string[2];







|







4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
    unsigned count = 1;

    assert(eventStringPtr);
    assert(patPtr);
    assert(eventMaskPtr);

    p = *eventStringPtr;
    memset(patPtr, 0, sizeof(TkPattern)); /* Otherwise memcmp doesn't work. */

    /*
     * Handle simple ASCII characters.
     */

    if (*p != '<') {
	char string[2];
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
	    unsigned size;

	    p = strchr(field, '>');
	    if (p == field) {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("virtual event \"<<>>\" is badly formed", -1), "MALFORMED");
	    }
	    if (!p || p[1] != '>') {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("missing \">\" in virtual binding", -1), "MALFORMED");
	    }

	    size = p - field;
	    if (size >= sizeof(buf)) {
		bufPtr = (char *)ckalloc(size + 1);
	    }
	    strncpy(bufPtr, field, size);







|





|







4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
	    unsigned size;

	    p = strchr(field, '>');
	    if (p == field) {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("virtual event \"<<>>\" is badly formed", TCL_INDEX_NONE), "MALFORMED");
	    }
	    if (!p || p[1] != '>') {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("missing \">\" in virtual binding", TCL_INDEX_NONE), "MALFORMED");
	    }

	    size = p - field;
	    if (size >= sizeof(buf)) {
		bufPtr = (char *)ckalloc(size + 1);
	    }
	    strncpy(bufPtr, field, size);
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
		}
		p = SkipFieldDelims(p);
	    }

	    eventFlags = 0;
	    if ((hPtr = Tcl_FindHashEntry(&eventTable, field))) {
		const EventInfo *eiPtr = (const EventInfo *)Tcl_GetHashValue(hPtr);

		patPtr->eventType = eiPtr->type;
		eventFlags = flagArray[eiPtr->type];
		eventMask = eiPtr->eventMask;
		p = GetField(SkipFieldDelims(p), field, sizeof(field));
	    }
	    if (*field) {
		unsigned button = GetButtonNumber(field);

		if ((eventFlags & BUTTON)
			|| (button && eventFlags == 0)
			|| (SUPPORT_ADDITIONAL_MOTION_SYNTAX && (eventFlags & MOTION) && button == 0)) {
		    /* This must be a button (or bad motion) event */
		    if (button == 0) {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
		    }
		    patPtr->info = button;







<











|







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
		}
		p = SkipFieldDelims(p);
	    }

	    eventFlags = 0;
	    if ((hPtr = Tcl_FindHashEntry(&eventTable, field))) {
		const EventInfo *eiPtr = (const EventInfo *)Tcl_GetHashValue(hPtr);

		patPtr->eventType = eiPtr->type;
		eventFlags = flagArray[eiPtr->type];
		eventMask = eiPtr->eventMask;
		p = GetField(SkipFieldDelims(p), field, sizeof(field));
	    }
	    if (*field) {
		unsigned button = GetButtonNumber(field);

		if ((eventFlags & BUTTON)
			|| (button && eventFlags == 0)
			|| (SUPPORT_ADDITIONAL_MOTION_SYNTAX && (eventFlags & MOTION) && button == 0)) {
		    /* This must be a button (or bad motion) event. */
		    if (button == 0) {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
		    }
		    patPtr->info = button;
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
			    Tcl_ObjPrintf("specified keysym \"%s\" for non-key event", field),
			    "NON_KEY");
		}
	    } else if (eventFlags == 0) {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("no event type or button # or keysym", -1), "UNMODIFIABLE");
	    } else if (patPtr->eventType == MotionNotify) {
		patPtr->info = ButtonNumberFromState(patPtr->modMask);
	    }

	    p = SkipFieldDelims(p);

	    if (*p != '>') {
		while (*p) {
		    ++p;
		    if (*p == '>') {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_NewStringObj("extra characters after detail in binding", -1),
				"PAST_DETAIL");
		    }
		}
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("missing \">\" in binding", -1), "MALFORMED");
	    }
	    ++p;
	}
    }

    *eventStringPtr = p;
    *eventMaskPtr |= eventMask;







|



<









|






|







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
			    Tcl_ObjPrintf("specified keysym \"%s\" for non-key event", field),
			    "NON_KEY");
		}
	    } else if (eventFlags == 0) {
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("no event type or button # or keysym", TCL_INDEX_NONE), "UNMODIFIABLE");
	    } else if (patPtr->eventType == MotionNotify) {
		patPtr->info = ButtonNumberFromState(patPtr->modMask);
	    }

	    p = SkipFieldDelims(p);

	    if (*p != '>') {
		while (*p) {
		    ++p;
		    if (*p == '>') {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_NewStringObj("extra characters after detail in binding", TCL_INDEX_NONE),
				"PAST_DETAIL");
		    }
		}
		return FinalizeParseEventDescription(
			interp,
			patPtr, 0,
			Tcl_NewStringObj("missing \">\" in binding", TCL_INDEX_NONE), "MALFORMED");
	    }
	    ++p;
	}
    }

    *eventStringPtr = p;
    *eventMaskPtr |= eventMask;
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
		    modMask &= ~modPtr->mask;
		    Tcl_AppendPrintfToObj(patternObj, "%s-", modPtr->name);
		}
	    }

	    assert(patPtr->eventType < TK_LASTEVENT);
	    assert(((size_t) eventArrayIndex[patPtr->eventType]) < SIZE_OF_ARRAY(eventArray));
	    Tcl_AppendToObj(patternObj, eventArray[eventArrayIndex[patPtr->eventType]].name, -1);

	    if (patPtr->info) {
		switch (patPtr->eventType) {
		case KeyPress:
		case KeyRelease: {
		    const char *string = TkKeysymToString(patPtr->info);
		    if (string) {
			Tcl_AppendToObj(patternObj, "-", 1);
			Tcl_AppendToObj(patternObj, string, -1);
		    }
		    break;
		}
		case ButtonPress:
		case ButtonRelease:
		    assert(patPtr->info <= 13);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) ((patPtr->info > 7) ? (patPtr->info - 4) : patPtr->info));







|








|







5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
		    modMask &= ~modPtr->mask;
		    Tcl_AppendPrintfToObj(patternObj, "%s-", modPtr->name);
		}
	    }

	    assert(patPtr->eventType < TK_LASTEVENT);
	    assert(((size_t) eventArrayIndex[patPtr->eventType]) < SIZE_OF_ARRAY(eventArray));
	    Tcl_AppendToObj(patternObj, eventArray[eventArrayIndex[patPtr->eventType]].name, TCL_INDEX_NONE);

	    if (patPtr->info) {
		switch (patPtr->eventType) {
		case KeyPress:
		case KeyRelease: {
		    const char *string = TkKeysymToString(patPtr->info);
		    if (string) {
			Tcl_AppendToObj(patternObj, "-", 1);
			Tcl_AppendToObj(patternObj, string, TCL_INDEX_NONE);
		    }
		    break;
		}
		case ButtonPress:
		case ButtonRelease:
		    assert(patPtr->info <= 13);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) ((patPtr->info > 7) ? (patPtr->info - 4) : patPtr->info));
5236
5237
5238
5239
5240
5241
5242
5243


5244

































5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
 */

KeySym
TkStringToKeysym(
    const char *name)		/* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name);




































    if (hPtr) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }
    assert(name);
    if (strlen(name) == 1u) {
	KeySym keysym = (KeySym) (unsigned char) name[0];

	if (TkKeysymToString(keysym)) {
	    return keysym;
	}
    }
#endif /* REDO_KEYSYM_LOOKUP */
    assert(name);







|
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
<
|







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
 */

KeySym
TkStringToKeysym(
    const char *name)		/* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr;
#endif /* REDO_KEYSYM_LOOKUP */
    int keysym;

    size_t len = Tcl_UtfToUniChar(name, &keysym);
    if (name[len] == '\0') {
        if (!Tcl_UniCharIsPrint(keysym)) {
    	/* This form not supported */
        } else if ((unsigned)(keysym - 0x21) <= 0x5D) {
		return (KeySym)keysym;
	    } else if ((unsigned)(keysym - 0xA1) <= 0x5E) {
		return (KeySym)keysym;
	    } else if (keysym == 0x20AC) {
		return 0x20AC;
	    } else {
		return (KeySym)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);
    }
    if (((unsigned)(name[0]-1) < 0x7F) && !name[1]) {

	keysym = (unsigned char) name[0];

	if (TkKeysymToString(keysym)) {
	    return keysym;
	}
    }
#endif /* REDO_KEYSYM_LOOKUP */
    assert(name);
5276
5277
5278
5279
5280
5281
5282
5283
























5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
 */

const char *
TkKeysymToString(
    KeySym keysym)
{
#ifdef REDO_KEYSYM_LOOKUP
    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);

























    if (hPtr) {
	return (const char *)Tcl_GetHashValue(hPtr);
    }
#endif /* REDO_KEYSYM_LOOKUP */

    if (keysym > (KeySym)0x1008FFFF) {
	return NULL;
    }
    return XKeysymToString(keysym);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetBindingXEvent --







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






<
<
<







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
 */

const char *
TkKeysymToString(
    KeySym keysym)
{
#ifdef REDO_KEYSYM_LOOKUP
    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[Tcl_UniCharToUtf(keysym - 0x1000000, buf)] = '\0';
	} else if (keysym >= 0x1010000) {
	    snprintf(buf, sizeof(buf), "U%08X", (int)(keysym - 0x1000000));
	} else {
	    snprintf(buf, sizeof(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 */




    return XKeysymToString(keysym);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetBindingXEvent --

Added generic/tkBitField.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
/*
 * tkBitField.c --
 *
 *	This module implements bit field operations.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkBitField.h"
#include "tkIntSet.h"
#include <assert.h>

#ifndef MAX
# define MAX(a,b) (((int) a) < ((int) b) ? b : a)
#endif
#ifndef MIN
# define MIN(a,b) (((int) a) < ((int) b) ? a : b)
#endif

#ifdef TK_CHECK_ALLOCS
# define DEBUG_ALLOC(expr) expr
#else
# define DEBUG_ALLOC(expr)
#endif


#define NBITS		TK_BIT_NBITS
#define NWORDS(size)	TK_BIT_COUNT_WORDS(size)
#define BIT_INDEX(n)	TK_BIT_INDEX(n)
#define WORD_INDEX(n)	TK_BIT_WORD_INDEX(n)

#define NBYTES(words)	((words)*sizeof(size_t))
#define BYTE_SIZE(size)	NBYTES(NWORDS(size))
#define BF_SIZE(size)	(offsetof(TkBitField, bits) + BYTE_SIZE(size))
#define BIT_SPAN(f,t)	((~((size_t) 0) << (f)) & (~((size_t) 0) >> ((NBITS - 1) - (t))))


DEBUG_ALLOC(unsigned tkBitCountNew = 0);
DEBUG_ALLOC(unsigned tkBitCountDestroy = 0);


#ifdef TK_IS_64_BIT_ARCH

/* ****************************************************************************/
/*                 64 bit implementation                                      */
/* ****************************************************************************/

# if defined(__GNUC__) || defined(__clang__)

#  define LsbIndex(x) __builtin_ctzll(x)
#  define MsbIndex(x) ((sizeof(unsigned long long)*8 - 1) - __builtin_clzll(x))

# else /* !(defined(__GNUC__) || defined(__clang__)) */

static unsigned
LsbIndex(uint64_t x)
{
    /* Source: http://chessprogramming.wikispaces.com/BitScan (adapted for MSVC) */
    static const unsigned MultiplyDeBruijnBitPosition[64] = {
	 0,  1, 48,  2, 57, 49, 28,  3, 61, 58, 50, 42, 38, 29, 17,  4,
	62, 55, 59, 36, 53, 51, 43, 22, 45, 39, 33, 30, 24, 18, 12,  5,
	63, 47, 56, 27, 60, 41, 37, 16, 54, 35, 52, 21, 44, 32, 23, 11,
	46, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19,  9, 13,  8,  7,  6
    };
    uint64_t idx = ((uint64_t) ((x & -((int64_t) x))*UINT64_C(0x03f79d71b4cb0a89))) >> 58;
    return MultiplyDeBruijnBitPosition[idx];
}

static unsigned
MsbIndex(uint64_t x)
{
    /*
     * Source: http://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i
     * (extended to 64 bit by GC)
     */

   static const uint8_t Table[16] = { -1, 0, 1,1, 2,2,2,2, 3,3,3,3,3,3,3,3 };

   unsigned r = 0;
   uint64_t xk;

   if ((xk = x >> 32)) { r =  32; x = xk; }
   if ((xk = x >> 16)) { r += 16; x = xk; }
   if ((xk = x >>  8)) { r +=  8; x = xk; }
   if ((xk = x >>  4)) { r +=  4; x = xk; }

   return r + Table[x];
}

# endif /* defined(__GNUC__) || defined(__clang__) */

static unsigned
PopCount(uint64_t x)
{
    /* Source: http://chessprogramming.wikispaces.com/Population+Count */
    x -=  (x >> 1) & UINT64_C(0x5555555555555555);
    x  = ((x >> 2) & UINT64_C(0x3333333333333333)) + (x & UINT64_C(0x3333333333333333));
    x  = ((x >> 4) + x) & UINT64_C(0x0F0F0F0F0F0F0F0F);
    return (x * UINT64_C(0x0101010101010101)) >> 56;
}

#else /* TK_IS_64_BIT_ARCH */

/* ****************************************************************************/
/*                 32 bit implementation                                      */
/* ****************************************************************************/

# if defined(__GNUC__) || defined(__clang__)

#  define LsbIndex(x) __builtin_ctz(x)
#  define MsbIndex(x) ((sizeof(unsigned)*8 - 1) - __builtin_clz(x))

# else /* defined(__GNUC__) || defined(__clang__) */

#  if 1
/* On my system this is the fastest method, only about 5% slower than __builtin_ctz(). */
static unsigned
LsbIndex(uint32_t x)
{
    /*
     * Source: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
     * (adapted for MSVC)
     */
    static const unsigned MultiplyDeBruijnBitPosition[32] = {
	 0,  1, 28,  2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17,  4, 8,
	31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18,  6, 11,  5, 10, 9
    };
    return MultiplyDeBruijnBitPosition[((uint32_t) ((x & -((int32_t) x))*0x077cb531)) >> 27];
}
#  else
/* The "classical" method, but about 20% slower than the DeBruijn method on my system. */
static unsigned
LsbIndex(uint32_t x)
{
    unsigned ctz = 32;
    x &= -((int32_t ) x);
    if (x) --ctz;
    if (x & 0x0000ffff) ctz -= 16;
    if (x & 0x00ff00ff) ctz -= 8;
    if (x & 0x0f0f0f0f) ctz -= 4;
    if (x & 0x33333333) ctz -= 2;
    if (x & 0x55555555) ctz -= 1;
    return ctz;
}
#  endif

static unsigned
MsbIndex(uint32_t x)
{
    /* Source: http://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i */
   static const uint8_t Table[16] = { -1 ,0, 1,1, 2,2,2,2, 3,3,3,3,3,3,3,3 };

   unsigned r = 0;
   uint32_t xk;

   if ((xk = x >> 16)) { r = 16; x = xk; }
   if ((xk = x >>  8)) { r += 8; x = xk; }
   if ((xk = x >>  4)) { r += 4; x = xk; }

   return r + Table[x];
}

# endif /* defined(__GNUC__) || defined(__clang__) */

static unsigned
PopCount(uint32_t x)
{
    /* Source: http://graphics.stanford.edu/~seander/bithacks.html */
    /* NOTE: the GCC function __builtin_popcount() is slower on my system. */
    x -=  (x >> 1) & 0x55555555;
    x  = ((x >> 2) & 0x33333333) + (x & 0x33333333);
    x  = ((x >> 4) + x) & 0x0f0f0f0f;
    return (x*0x01010101) >> 24;
}

#endif /* !TK_IS_64_BIT_ARCH */


#ifdef TK_CHECK_ALLOCS
/*
 * Some useful functions for finding memory leaks.
 */

static TkBitField *Used = NULL;
static TkBitField *Last = NULL;


static void
Use(
    TkBitField *bf)
{
    static int N = 0;
    if (!Used) { Used = bf; }
    if (Last) { Last->next = bf; }
    bf->number = N++;
    bf->next = NULL;
    bf->prev = Last;
    Last = bf;
}


static void
Free(
    TkBitField *bf)
{
    assert(bf->prev || Used == bf);
    assert(bf->next || Last == bf);
    if (Last == bf) { Last = bf->prev; }
    if (Used == bf) { Used = bf->next; }
    if (bf->prev) { bf->prev->next = bf->next; }
    if (bf->next) { bf->next->prev = bf->prev; }
    bf->prev = NULL;
    bf->next = NULL;
}


void
TkBitCheckAllocs()
{
    for ( ; Used; Used = Used->next) {
	printf("TkBitField(number): %d\n", Used->number);
    }
}

#endif /* TK_CHECK_ALLOCS */


static int
IsEqual(
    const size_t *s,
    const size_t *t,
    unsigned numBytes)
{
    const size_t *e = s + numBytes;

    for ( ; s < e; ++s, ++t) {
	if (*s != *t) {
	    return 0;
	}
    }
    return 1;
}


static void
ResetUnused(
    TkBitField *bf)
{
    unsigned bitIndex = BIT_INDEX(bf->size);

    if (bitIndex) {
	bf->bits[NWORDS(bf->size) - 1] &= ~BIT_SPAN(bitIndex, NBITS - 1);
    }
}


void
TkBitDestroy(
    TkBitField **bfPtr)
{
    assert(bfPtr);

    if (*bfPtr) {
	DEBUG_ALLOC(Free(*bfPtr));
	ckfree(*bfPtr);
	*bfPtr = NULL;
	DEBUG_ALLOC(tkBitCountDestroy++);
    }
}


TkBitField *
TkBitResize(
    TkBitField *bf,
    unsigned newSize)
{
    if (!bf) {
	bf = (TkBitField *)ckalloc(BF_SIZE(newSize));
	DEBUG_ALLOC(Use(bf));
	bf->size = newSize;
	bf->refCount = 1;
	bf->isSetFlag = 0;
	memset(bf->bits, 0, BYTE_SIZE(newSize));
	DEBUG_ALLOC(tkBitCountNew++);
    } else {
	unsigned newWords;
	unsigned oldWords;

	newWords = NWORDS(newSize);
	oldWords = NWORDS(bf->size);

	if (newWords == oldWords) {
	    bf->size = newSize;
	    ResetUnused(bf);
	    return bf;
	}

	if (bf->refCount <= 1) {
	    DEBUG_ALLOC(Free(bf));
	    bf = (TkBitField *)ckrealloc((char *) bf, BF_SIZE(newSize));
	    DEBUG_ALLOC(Use(bf));
	} else {
	    TkBitField *newBF = (TkBitField *)ckalloc(BF_SIZE(newSize));
	    DEBUG_ALLOC(Use(newBF));
	    memcpy(newBF->bits, bf->bits, NBYTES(MIN(oldWords, newWords)));
	    newBF->refCount = 1;
	    newBF->isSetFlag = 0;
	    bf->refCount -= 1;
	    bf = newBF;
	    DEBUG_ALLOC(tkBitCountNew++);
	}

	bf->size = newSize;

	if (oldWords < newWords) {
	    memset(bf->bits + oldWords, 0, NBYTES(newWords - oldWords));
	} else {
	    ResetUnused(bf);
	}
    }

    return bf;
}


TkBitField *
TkBitFromSet(
    const TkIntSet *set,
    unsigned size)
{
    unsigned numEntries = TkIntSetSize(set);
    TkBitField *bf = TkBitResize(NULL, size);
    unsigned i;

    for (i = 0; i < numEntries; ++i) {
	TkIntSetType value = TkIntSetAccess(set, i);

	if (value >= size) {
	    break;
	}
	TkBitSet(bf, value);
    }

    return bf;
}


size_t
TkBitCount(
    const TkBitField *bf)
{
    size_t words, i;
    size_t count = 0;

    assert(bf);

    words = NWORDS(bf->size);

    for (i = 0; i < words; ++i) {
	count += PopCount(bf->bits[i]);
    }

    return count;
}


TkBitField *
TkBitCopy(
    const TkBitField *bf,
    int size)
{
    TkBitField *copy;
    unsigned oldWords, newWords;

    assert(bf);

    if (size < 0) {
	size = bf->size;
    }

    copy = (TkBitField *)ckalloc(BF_SIZE(size));
    DEBUG_ALLOC(Use(copy));
    oldWords = NWORDS(bf->size);
    newWords = NWORDS(size);
    memcpy(copy->bits, bf->bits, NBYTES(MIN(oldWords, newWords)));
    if (newWords > oldWords) {
	memset(copy->bits + oldWords, 0, NBYTES(newWords - oldWords));
    }
    copy->size = size;
    copy->refCount = 1;
    copy->isSetFlag = 0;
    ResetUnused(copy);
    DEBUG_ALLOC(tkBitCountNew++);
    return copy;
}


void
TkBitJoin(
    TkBitField *dst,
    const TkBitField *src)
{
    unsigned words, i;

    assert(dst);
    assert(src);
    assert(TkBitSize(src) <= TkBitSize(dst));

    if (src != dst && src->size > 0) {
	for (i = 0, words = NWORDS(src->size); i < words; ++i) {
	    dst->bits[i] |= src->bits[i];
	}
    }
}


void
TkBitJoin2(
    TkBitField *dst,
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned words1, words2, words, i;

    assert(dst);
    assert(bf1);
    assert(bf2);
    assert(TkBitSize(dst) >= TkBitSize(bf1));
    assert(TkBitSize(dst) >= TkBitSize(bf2));

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);
    words = MIN(words1, words2);

    for (i = 0; i < words; ++i) {
	dst->bits[i] |= bf1->bits[i] | bf2->bits[i];
    }
    for ( ; i < words1; ++i) {
	dst->bits[i] |= bf1->bits[i];
    }
    for ( ; i < words2; ++i) {
	dst->bits[i] |= bf2->bits[i];
    }
}


void
TkBitIntersect(
    TkBitField *dst,
    const TkBitField *src)
{
    unsigned srcWords, dstWords, i;

    assert(dst);
    assert(src);

    if (src == dst || dst->size == 0) {
	return;
    }

    srcWords = NWORDS(src->size);
    dstWords = NWORDS(dst->size);

    if (dstWords > srcWords) {
	memset(dst->bits + srcWords, 0, NBYTES(dstWords - srcWords));
	dstWords = srcWords;
    }

    for (i = 0; i < dstWords; ++i) {
	dst->bits[i] &= src->bits[i];
    }

    return;
}


void
TkBitRemove(
    TkBitField *dst,
    const TkBitField *src)
{
    unsigned dstWords;

    assert(dst);
    assert(src);

    if (dst->size == 0 || src->size == 0) {
	return;
    }

    dstWords = NWORDS(dst->size);

    if (src == dst) {
	memset(dst->bits, 0, NBYTES(dstWords));
    } else {
	unsigned words = MIN(NWORDS(src->size), dstWords);
	unsigned i;

	for (i = 0; i < words; ++i) {
	    dst->bits[i] &= ~src->bits[i];
	}
    }
}


void
TkBitComplementTo(
    TkBitField *dst,
    const TkBitField *src)
{
    unsigned srcWords, dstWords;

    assert(dst);
    assert(src);
    assert(TkBitSize(src) <= TkBitSize(dst));

    if (dst->size == 0) {
	return;
    }

    dstWords = NWORDS(dst->size);

    if (src == dst || src->size == 0) {
	srcWords = 0;
    } else {
	unsigned i;

	srcWords = NWORDS(src->size);

	for (i = 0; i < srcWords; ++i) {
	    dst->bits[i] = src->bits[i] & ~dst->bits[i];
	}
    }

    memset(dst->bits + srcWords, 0, NBYTES(dstWords - srcWords));
}


void
TkBitJoinComplementTo(
    TkBitField *dst,
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned i, words, words2;

    assert(dst);
    assert(bf1);
    assert(bf2);
    assert(TkBitSize(dst) >= TkBitSize(bf1));
    assert(TkBitSize(dst) >= TkBitSize(bf2));

    if (dst == bf2 || bf2->size == 0) {
	return;
    }

    assert(TkBitSize(bf2) >= TkBitSize(bf1));

    words2 = NWORDS(bf2->size);
    words = MIN(NWORDS(bf1->size), words2);

    for (i = 0; i < words; ++i) {
	dst->bits[i] |= bf2->bits[i] & ~bf1->bits[i];
    }
    for ( ; i < words2; ++i) {
	dst->bits[i] |= bf2->bits[i];
    }
}


void
TkBitJoinNonIntersection(
    TkBitField *dst,
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    assert(dst);
    assert(bf1);
    assert(bf2);
    assert(TkBitSize(dst) >= TkBitSize(bf1));
    assert(TkBitSize(dst) >= TkBitSize(bf2));

    if (bf1 == bf2) {
	return;
    }

    if (bf1->size == 0) {
	TkBitJoin(dst, bf2);
    } else if (bf2->size == 0) {
	TkBitJoin(dst, bf1);
    } else {
	unsigned i, words = MIN(NWORDS(bf1->size), NWORDS(bf2->size));

	for (i = 0; i < words; ++i) {
	    size_t bf1Bits = bf1->bits[i];
	    size_t bf2Bits = bf2->bits[i];

	    dst->bits[i] |= (bf1Bits & ~bf2Bits) | (bf2Bits & ~bf1Bits);
	}
    }
}


void
TkBitJoin2ComplementToIntersection(
    TkBitField *dst,
    const TkBitField *add,
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    assert(dst);
    assert(add);
    assert(bf1);
    assert(bf2);
    assert(TkBitSize(dst) >= TkBitSize(add));
    assert(TkBitSize(dst) >= TkBitSize(bf1));
    assert(TkBitSize(bf1) == TkBitSize(bf2));

    /* dst := dst + add + ((bf1 + bf2) - (bf1 & bf2)) */

    if (bf1 == bf2) {
	TkBitJoin(dst, add);
    } else {
	unsigned words1 = NWORDS(add->size);
	unsigned words2 = NWORDS(bf1->size);
	unsigned words = MIN(words1, words2);
	unsigned i;

	for (i = 0; i < words; ++i) {
	    size_t bf1Bits = bf1->bits[i];
	    size_t bf2Bits = bf2->bits[i];

	    dst->bits[i] |= add->bits[i] | ((bf1Bits | bf2Bits) & ~(bf1Bits & bf2Bits));
	}
	for ( ; i < words2; ++i) {
	    size_t bf1Bits = bf1->bits[i];
	    size_t bf2Bits = bf2->bits[i];

	    dst->bits[i] |= (bf1Bits | bf2Bits) & ~(bf1Bits & bf2Bits);
	}
	for ( ; i < words1; ++i) {
	    dst->bits[i] |= add->bits[i];
	}
    }
}


void
TkBitJoinOfDifferences(
    TkBitField *dst,
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned words, words1, words2, i;

    assert(dst);
    assert(bf1);
    assert(bf2);
    assert(TkBitSize(dst) >= TkBitSize(bf1));

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);

    words = MIN(words1, words2);

    for (i = 0; i < words; ++i) {
	size_t bf1Bits = bf1->bits[i];
	size_t bf2Bits = bf2->bits[i];

	/* dst := (dst - bf1) + (bf1 - bf2) */
	dst->bits[i] = (dst->bits[i] & ~bf1Bits) | (bf1Bits & ~bf2Bits);
    }

    for ( ; i < words1; ++i) {
	/* dst := dst + bf1 */
	dst->bits[i] |= bf1->bits[i];
    }
}


void
TkBitClear(
    TkBitField *bf)
{
    assert(bf);
    memset(bf->bits, 0, BYTE_SIZE(bf->size));
}


int
TkBitNone_(
    const size_t *bits,
    unsigned words)
{
    unsigned i;

    assert(bits);

    for (i = 0; i < words; ++i) {
	if (bits[i]) {
	    return 0;
	}
    }
    return 1;
}


int
TkBitAny(
    const TkBitField *bf)
{
    unsigned words, i;

    assert(bf);

    words = NWORDS(bf->size);

    for (i = 0; i < words; ++i) {
	if (bf->bits[i]) {
	    return 1;
	}
    }

    return 0;
}


int
TkBitComplete(
    const TkBitField *bf)
{
    unsigned words;

    assert(bf);

    words = NWORDS(bf->size);

    if (words)
    {
	unsigned i, n = words - 1;

	for (i = 0; i < n; ++i) {
	    if (bf->bits[i] != ~((size_t) 0)) {
		return 0;
	    }
	}

	if (bf->bits[words - 1] != BIT_SPAN(0, BIT_INDEX(bf->size - 1))) {
	    return 0;
	}
    }

    return 1;
}


int
TkBitIsEqual(
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned words1;

    assert(bf1);
    assert(bf2);

    if (bf1 == bf2) {
	return 1;
    }

    if (bf1->size > bf2->size) {
	const TkBitField *bf = bf1;
	bf1 = bf2;
	bf2 = bf;
    }

    words1 = NWORDS(bf1->size);

    if (!IsEqual(bf1->bits, bf2->bits, words1)) {
	return 0;
    }

    return TkBitNone_(bf2->bits + words1, NWORDS(bf2->size) - words1);
}


int
TkBitContains(
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned words1, words2, i;

    assert(bf1);
    assert(bf2);

    if (bf1 == bf2) {
	return 1;
    }

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);

    if (words1 < words2) {
	if (!TkBitNone_(bf2->bits + words1, words2 - words1)) {
	    return 0;
	}
	words2 = words1;
    }

    for (i = 0; i < words2; ++i) {
	size_t bits2 = bf2->bits[i];

	if (bits2 != (bf1->bits[i] & bits2)) {
	    return 0;
	}
    }

    return 1;
}


int
TkBitDisjunctive(
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned words, i;

    assert(bf1);
    assert(bf2);

    if (bf1 == bf2) {
	return TkBitNone(bf1);
    }

    words = MIN(NWORDS(bf1->size), NWORDS(bf2->size));

    for (i = 0; i < words; ++i) {
	if (bf1->bits[i] & bf2->bits[i]) {
	    return 0;
	}
    }

    return 1;
}


int
TkBitIntersectionIsEqual(
    const TkBitField *bf1,
    const TkBitField *bf2,
    const TkBitField *del)
{
    unsigned words, words1, words2, i;

    assert(bf1);
    assert(bf2);
    assert(del);
    assert(TkBitSize(bf1) <= TkBitSize(del));
    assert(TkBitSize(bf2) <= TkBitSize(del));

    if (bf1 == bf2) {
	return 1;
    }
    if (bf1->size == 0) {
	return TkBitNone(bf2);
    }
    if (bf2->size == 0) {
	return TkBitNone(bf1);
    }

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);
    words = MIN(words1, words2);

    for (i = 0; i < words; ++i) {
	size_t bits = del->bits[i];
	if ((bf1->bits[i] & bits) != (bf2->bits[i] & bits)) {
	    return 0;
	}
    }

    for (i = words; i < words1; ++i) {
	if (bf1->bits[i] & del->bits[i]) {
	    return 0;
	}
    }

    for (i = words; i < words2; ++i) {
	if (bf2->bits[i] & del->bits[i]) {
	    return 0;
	}
    }

    return 1;
}


unsigned
TkBitFindFirst(
    const TkBitField *bf)
{
    unsigned words, i;

    assert(bf);

    words = NWORDS(bf->size);

    for (i = 0; i < words; ++i) {
	size_t bits = bf->bits[i];

	if (bits) {
	    return NBITS*i + LsbIndex(bits);
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindLast(
    const TkBitField *bf)
{
    int i;

    assert(bf);

    for (i = NWORDS(bf->size) - 1; i >= 0; --i) {
	size_t bits = bf->bits[i];

	if (bits) {
	    return NBITS*i + MsbIndex(bits);
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindFirstNot(
    const TkBitField *bf)
{
    Tcl_Size words, mask, bits, i;

    assert(bf);

    if (bf->size > 0) {
	words = NWORDS(bf->size) - 1;

	for (i = 0; i < words; ++i) {
	    bits = bf->bits[i];

	    if (bits != ~((Tcl_Size) 0)) {
		return NBITS*i + LsbIndex(~bits);
	    }
	}

	mask = BIT_SPAN(0, BIT_INDEX(bf->size - 1));
	bits = bf->bits[words];

	if (bits != mask) {
	    return NBITS*words + LsbIndex(~bits & mask);
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindLastNot(
    const TkBitField *bf)
{
    assert(bf);

    if (bf->size > 0) {
	size_t bits,mask;
	unsigned words;
	int i;

	words = NWORDS(bf->size) - 1;
	mask = BIT_SPAN(0, BIT_INDEX(bf->size - 1));
	bits = bf->bits[words];

	if (bits != mask) {
	    return NBITS*words + MsbIndex(~bits & mask);
	}

	for (i = words - 1; i >= 0; --i) {
	    if ((bits = bf->bits[i]) != ~((size_t) 0)) {
		return NBITS*i + MsbIndex(~bits);
	    }
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindNext(
    const TkBitField *bf,
    unsigned prev)
{
    size_t bits;
    unsigned i, words;

    assert(bf);
    assert(prev < TkBitSize(bf));

    i = WORD_INDEX(prev);
    bits = bf->bits[i] & ~BIT_SPAN(0, BIT_INDEX(prev));

    if (bits) {
	return NBITS*i + LsbIndex(bits);
    }

    words = NWORDS(bf->size);

    for (++i; i < words; ++i) {
	if ((bits = bf->bits[i])) {
	    return NBITS*i + LsbIndex(bits);
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindNextNot(
    const TkBitField *bf,
    unsigned prev)
{
    size_t bits;
    unsigned i, words;

    assert(bf);
    assert(prev < TkBitSize(bf));

    i = WORD_INDEX(prev);
    bits = bf->bits[i] & ~BIT_SPAN(0, BIT_INDEX(prev));

    if (~bits != ~((size_t) 0)) {
	return NBITS*i + LsbIndex(bits);
    }

    words = NWORDS(bf->size);

    for (++i; i < words; ++i) {
	if (bits != ~((size_t) 0)) {
	    return NBITS*i + LsbIndex(~bits);
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindPrev(
    const TkBitField *bf,
    unsigned next)
{
    size_t bits;
    int i;

    assert(bf);
    assert(next < TkBitSize(bf));

    i = WORD_INDEX(next);
    bits = bf->bits[i] & ~BIT_SPAN(BIT_INDEX(next), NBITS - 1);

    if (bits) {
	return NBITS*i + MsbIndex(bits);
    }

    for (--i; i >= 0; --i) {
	if ((bits = bf->bits[i])) {
	    return NBITS*i + MsbIndex(bits);
	}
    }

    return TK_BIT_NPOS;
}


unsigned
TkBitFindFirstInIntersection(
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    unsigned words, i;

    assert(bf1);
    assert(bf2);

    words = NWORDS(MIN(bf1->size, bf2->size));

    for (i = 0; i < words; ++i) {
	size_t bits = bf1->bits[i] & bf2->bits[i];

	if (bits) {
	    return LsbIndex(bits);
	}
    }

    return TK_BIT_NPOS;
}


int
TkBitTestAndSet(
    TkBitField *bf,
    unsigned n)
{
    size_t *word;
    size_t mask;

    assert(bf);
    assert(n < TkBitSize(bf));

    word = bf->bits + WORD_INDEX(n);
    mask = TK_BIT_MASK(BIT_INDEX(n));

    if (*word & mask) {
	return 0;
    }
    *word |= mask;
    return 1;
}


int
TkBitTestAndUnset(
    TkBitField *bf,
    unsigned n)
{
    size_t *word;
    size_t mask;

    assert(bf);
    assert(n < TkBitSize(bf));

    word = bf->bits + WORD_INDEX(n);
    mask = TK_BIT_MASK(BIT_INDEX(n));

    if (!(*word & mask)) {
	return 0;
    }
    *word &= ~mask;
    return 1;
}


void
TkBitFill(
    TkBitField *bf)
{
    memset(bf->bits, 0xff, BYTE_SIZE(bf->size));
    ResetUnused(bf);
}


#ifndef NDEBUG

# include <stdio.h>

void
TkBitPrint(
    const TkBitField *bf)
{
    unsigned i;
    const char *comma = "";

    assert(bf);

    printf("%" TCL_Z_MODIFIER "d:{ ", TkBitCount(bf));
    for (i = TkBitFindFirst(bf); i != TK_BIT_NPOS; i = TkBitFindNext(bf, i)) {
	printf("%s%d", comma, i);
	comma = ", ";
    }
    printf(" }\n");
}

#endif /* NDEBUG */

#ifdef TK_UNUSED_BITFIELD_FUNCTIONS

/*
 * These functions are not needed anymore, but shouldn't be removed, because sometimes
 * any of these functions might be useful.
 */

void
TkBitInnerJoinDifference(
    TkBitField *dst,
    const TkBitField *add,
    const TkBitField *sub)
{
    unsigned words1, words2, i;

    assert(dst);
    assert(add);
    assert(sub);
    assert(TkBitSize(add) <= TkBitSize(dst));

    words2 = NWORDS(add->size);
    words1 = MIN(words2, NWORDS(sub->size));

    for (i = 0; i < words1; ++i) {
	size_t addBits = add->bits[i];
	dst->bits[i] = (dst->bits[i] & addBits) | (addBits & ~sub->bits[i]);
    }

    for ( ; i < words2; ++i) {
	size_t addBits = add->bits[i];
	dst->bits[i] = (dst->bits[i] & addBits) | addBits;
    }
}


int
TkBitInnerJoinDifferenceIsEmpty(
    const TkBitField *bf,
    const TkBitField *add,
    const TkBitField *sub)
{
    unsigned words, i;
    unsigned bfWords, addWords, subWords;

    assert(bf);
    assert(add);
    assert(sub);

    /* (bf & add) + (add - sub) == nil */

    if (add->size == 0) {
	/* nil */
	return 1;
    }

    if (add == bf) {
	/* add == nil */
	return TkBitNone(add);
    }

    bfWords = NWORDS(bf->size);
    addWords = NWORDS(add->size);
    subWords = NWORDS(sub->size);

    words = MIN(bfWords, MIN(addWords, subWords));

    for (i = 0; i < words; ++i) {
	size_t addBits = add->bits[i];
	if ((bf->bits[i] & addBits) | (addBits & ~sub->bits[i])) {
	    return 0;
	}
    }

    if (addWords == words) {
	/* nil */
	return 1;
    }

    if (bfWords > words) {
	assert(subWords == words);
	/* add == nil */

	for ( ; i < addWords; ++i) {
	    if (add->bits[i]) {
		return 0;
	    }
	}
    } else {
	assert(bfWords == words);
	words = MIN(addWords, subWords);

	/* (add - sub) == nil */

	for ( ; i < words; ++i) {
	    if (add->bits[i] & ~sub->bits[i]) {
		return 0;
	    }
	}
    }

    return 1;
}


int
TkBitIsEqualToDifference(
    const TkBitField *bf1,
    const TkBitField *bf2,
    const TkBitField *sub2)
{
    unsigned words0, words1, words2, i;

    assert(bf1);
    assert(bf2);
    assert(sub2);
    assert(TkBitSize(bf2) == TkBitSize(sub2));

    if (bf2->size == 0) {
	return TkBitNone(bf1);
    }
    if (bf1->size == 0) {
	return TkBitContains(sub2, bf2);
    }

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);
    words0 = MIN(words1, words2);

    /* bf1 == bf2 - sub2 */

    for (i = 0; i < words0; ++i) {
	if (bf1->bits[i] != (bf2->bits[i] & ~sub2->bits[i])) {
	    return 0;
	}
    }

    if (words1 > words2) {
	return TkBitNone_(bf1->bits + words2, words1 - words2);
    }

    for ( ; i < words2; ++i) {
	if (bf2->bits[i] & ~sub2->bits[i]) {
	    return 0;
	}
    }

    return 1;
}


int
TkBitIsEqualToInnerJoin(
    const TkBitField *bf1,
    const TkBitField *bf2,
    const TkBitField *add2)
{
    unsigned words0, words1, words2, i;

    assert(bf1);
    assert(bf2);
    assert(add2);
    assert(TkBitSize(bf2) == TkBitSize(add2));

    if (bf1 == bf2) {
	return 1;
    }
    if (bf2 == add2) {
	return TkBitIsEqual(bf1, bf2);
    }
    if (bf1->size == 0) {
	return TkBitNone(bf2);
    }
    if (bf2->size == 0) {
	return TkBitNone(bf1);
    }

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);
    words0 = MIN(words1, words2);

    for (i = 0; i < words0; ++i) {
	size_t bf2Bits = bf2->bits[i];
	if (bf1->bits[i] != (bf2Bits | (add2->bits[i] & bf2Bits))) {
	    return 0;
	}
    }

    if (words1 > words2) {
	return TkBitNone_(bf1->bits + words2, words1 - words2);
    }

    for ( ; i < words2; ++i) {
	size_t bf2Bits = bf2->bits[i];
	if (bf2Bits | (add2->bits[i] & bf2Bits)) {
	    return 0;
	}
    }

    return 1;
}


int
TkBitIsEqualToInnerJoinDifference(
    const TkBitField *bf1,
    const TkBitField *bf2,
    const TkBitField *add2,
    const TkBitField *sub2)
{
    unsigned words0, words1, words2, i;

    assert(bf1);
    assert(bf2);
    assert(add2);
    assert(sub2);
    assert(TkBitSize(bf2) == TkBitSize(add2));
    assert(TkBitSize(bf2) == TkBitSize(sub2));

    if (add2->size == 0) {
	return TkBitNone(bf1);
    }
    if (sub2->size == 0) {
	return TkBitIsEqual(bf1, add2);
    }

    words1 = NWORDS(bf1->size);
    words2 = NWORDS(bf2->size);
    words0 = MIN(words1, words2);

    for (i = 0; i < words0; ++i) {
	size_t addBits = add2->bits[i];
	if (bf1->bits[i] != ((bf2->bits[i] & addBits) | (addBits & ~sub2->bits[i]))) {
	    return 0;
	}
    }

    if (words1 > words2) {
	return TkBitNone_(bf1->bits + words2, words1 - words2);
    }

    for ( ; i < words2; ++i) {
	size_t addBits = add2->bits[i];
	if ((bf2->bits[i] & addBits) | (addBits & ~sub2->bits[i])) {
	    return 0;
	}
    }

    return 1;
}


static int
IntersectionIsDisjunctive(
    const TkBitField *bf1,
    const TkBitField *bf2,
    const TkBitField *del)
{
    unsigned words = NWORDS(bf1->size);

    assert(TkBitSize(bf1) == TkBitSize(bf2));
    assert(TkBitSize(bf1) == TkBitSize(del));

    for (i = 0; i < words; ++i) {
	size_t delBits = del->bits[i];

	if ((bf1->bits[i] & delBits) != (bf2->bits[i] & delBits)) {
	    return 0;
	}
    }

    return 1;
}


int
TkBitInnerJoinDifferenceIsEqual(
    const TkBitField *bf1,
    const TkBitField *bf2,
    const TkBitField *add,
    const TkBitField *sub)
{
    unsigned words, i;

    assert(bf1);
    assert(bf2);
    assert(add);
    assert(sub);
    assert(TkBitSize(bf1) == TkBitSize(bf2));
    assert(TkBitSize(bf1) == TkBitSize(add));
    assert(TkBitSize(bf1) == TkBitSize(sub));

    if (add->size == 0) {
	return 1;
    }

    if (bf1->size == 0) {
	 /*
	  * We have to show: sub & add == bf1 & add
	  * (see InnerJoinDifferenceIsEqual [tkIntSet.c]).
	  */
	 return IntersectionIsDisjunctive(bf1, sub, add);
    }

    if (bf2->size == 0) {
	 return IntersectionIsDisjunctive(bf2, sub, add);
    }

    words = NWORDS(bf1->size);

    for (i = 0; i < words; ++i) {
	size_t addBits = add->bits[i];
	size_t sumBits = addBits & ~sub->bits[i];

	if (((bf1->bits[i] & addBits) | sumBits) != ((bf2->bits[i] & addBits) | sumBits)) {
	    return 0;
	}
    }

    return 1;
}

#endif /* TK_UNUSED_BITFIELD_FUNCTIONS */


/* Additionally we need stand-alone object code. */
extern TkBitField *TkBitNew(unsigned size);
extern const unsigned char *TkBitData(const TkBitField *bf);
extern unsigned TkBitByteSize(const TkBitField *bf);
extern unsigned TkBitRefCount(const TkBitField *bf);
extern void TkBitIncrRefCount(TkBitField *bf);
extern unsigned TkBitDecrRefCount(TkBitField *bf);
extern int TkBitIsEmpty(const TkBitField *bf);
extern size_t TkBitSize(const TkBitField *bf);
extern int TkBitTest(const TkBitField *bf, unsigned n);
extern int TkBitNone(const TkBitField *bf);
extern int TkBitIntersects(const TkBitField *bf1, const TkBitField *bf2);
extern void TkBitSet(TkBitField *bf, unsigned n);
extern void TkBitUnset(TkBitField *bf, unsigned n);
extern void TkBitPut(TkBitField *bf, unsigned n, int value);
extern unsigned TkBitAdjustSize(unsigned size);

/* vi:set ts=8 sw=4: */

Added generic/tkBitField.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
/*
 * tkBitField.h --
 *
 *	This module implements bit field operations.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKBITFIELD
#define _TKBITFIELD

#include "tkInt.h" /* needed for inline support and 64 bit support */

#define TK_BIT_NBITS (sizeof(size_t)*8) /* Number of bits in one word. */

struct TkIntSet;


/*
 * The struct below will be shared with the struct TkIntSet, so the first two
 * members must exactly match the first two members in struct TkIntSet. In this
 * way we have a struct inheritance, based on the first two members. This
 * is portable due to C99 section 6.7.2.1 bullet point 13:
 *
 *	Within a structure object, the non-bit-field members and the units
 *	in which bit-fields reside have addresses that increase in the order
 *	in which they are declared. A pointer to a structure object, suitably
 *	converted, points to its initial member (or if that member is a
 *	bit-field, then to the unit in which it resides), and vice versa.
 *	There may be unnamed padding within a structure object, but not at
 *	beginning.
 *
 * This inheritance concept is also used in the portable GTK library.
 */

typedef struct TkBitField {
    uint32_t refCount:31;
    uint32_t isSetFlag:1;
    size_t size;
#ifdef TK_CHECK_ALLOCS
    struct TkBitField *next;
    struct TkBitField *prev;
    unsigned number;
#endif
    size_t bits[1];
} TkBitField;


/*
 * This value will be returned in case of end of iteration.
 */
#define TK_BIT_NPOS ((unsigned) -1)


inline TkBitField *TkBitNew(unsigned size);
TkBitField *TkBitResize(TkBitField *bf, unsigned newSize);
TkBitField *TkBitFromSet(const struct TkIntSet *set, unsigned size);
void TkBitDestroy(TkBitField **bfPtr);

inline const unsigned char *TkBitData(const TkBitField *bf);
inline unsigned TkBitByteSize(const TkBitField *bf);

inline unsigned TkBitRefCount(const TkBitField *bf);
inline void TkBitIncrRefCount(TkBitField *bf);
inline unsigned TkBitDecrRefCount(TkBitField *bf);

TkBitField *TkBitCopy(const TkBitField *bf, int size);

void TkBitJoin(TkBitField *dst, const TkBitField *src);
void TkBitIntersect(TkBitField *dst, const TkBitField *src);
void TkBitRemove(TkBitField *dst, const TkBitField *src);

/* dst := dst + bf1 + bf2 */
void TkBitJoin2(TkBitField *dst, const TkBitField *bf1, const TkBitField *bf2);
/* dst := src - dst */
void TkBitComplementTo(TkBitField *dst, const TkBitField *src);
/* dst := dst + (bf2 - bf1) */
void TkBitJoinComplementTo(TkBitField *dst, const TkBitField *bf1, const TkBitField *bf2);
/* dst := dst + (bf1 - bf2) + (bf2 - bf1) */
void TkBitJoinNonIntersection(TkBitField *dst, const TkBitField *bf1, const TkBitField *bf2);
/* dst := dst + add + ((bf1 + bf2) - (bf1 & bf2)) */
void TkBitJoin2ComplementToIntersection(TkBitField *dst,
    const TkBitField *add, const TkBitField *bf1, const TkBitField *bf2);
/* dst := (dst - bf1) + (bf1 - bf2) */
void TkBitJoinOfDifferences(TkBitField *dst, const TkBitField *bf1, const TkBitField *bf2);

inline int TkBitIsEmpty(const TkBitField *bf);
inline size_t TkBitSize(const TkBitField *bf);
size_t TkBitCount(const TkBitField *bf);

inline int TkBitTest(const TkBitField *bf, unsigned n);
inline int TkBitNone(const TkBitField *bf);
int TkBitAny(const TkBitField *bf);
int TkBitComplete(const TkBitField *bf);

int TkBitIsEqual(const TkBitField *bf1, const TkBitField *bf2);
int TkBitContains(const TkBitField *bf1, const TkBitField *bf2);
int TkBitDisjunctive(const TkBitField *bf1, const TkBitField *bf2);
inline int TkBitIntersects(const TkBitField *bf1, const TkBitField *bf2);
int TkBitIntersectionIsEqual(const TkBitField *bf1, const TkBitField *bf2, const TkBitField *del);

unsigned TkBitFindFirst(const TkBitField *bf);
unsigned TkBitFindLast(const TkBitField *bf);
unsigned TkBitFindFirstNot(const TkBitField *bf);
unsigned TkBitFindLastNot(const TkBitField *bf);
unsigned TkBitFindNext(const TkBitField *bf, unsigned prev);
unsigned TkBitFindNextNot(const TkBitField *bf, unsigned prev);
unsigned TkBitFindPrev(const TkBitField *bf, unsigned prev);
unsigned TkBitFindFirstInIntersection(const TkBitField *bf1, const TkBitField *bf2);

inline void TkBitSet(TkBitField *bf, unsigned n);
inline void TkBitUnset(TkBitField *bf, unsigned n);
inline void TkBitPut(TkBitField *bf, unsigned n, int value);
int TkBitTestAndSet(TkBitField *bf, unsigned n);
int TkBitTestAndUnset(TkBitField *bf, unsigned n);
void TkBitFill(TkBitField *bf);
void TkBitClear(TkBitField *bf);

/* Return nearest multiple of TK_BIT_NBITS which is greater or equal to given argument. */
inline unsigned TkBitAdjustSize(unsigned size);

#ifndef NDEBUG
void TkBitPrint(const TkBitField *bf);
#endif

#ifdef TK_CHECK_ALLOCS
void TkBitCheckAllocs();
#endif


#ifdef TK_UNUSED_BITFIELD_FUNCTIONS

/*
 * These functions are not needed anymore, but shouldn't be removed, because sometimes
 * any of these functions might be useful.
 */

/* dst := (dst + (add - sub)) & add */
void TkBitInnerJoinDifference(TkBitField *dst, const TkBitField *add, const TkBitField *sub);
/* ((bf + (add - sub)) & add) == nil */
int TkBitInnerJoinDifferenceIsEmpty(const TkBitField *bf, const TkBitField *add, const TkBitField *sub);
/* bf1 == bf2 - sub2 */
int TkBitIsEqualToDifference(const TkBitField *bf1, const TkBitField *bf2, const TkBitField *sub2);
/* bf1 == ((bf2 + add2) & bf2) */
int TkBitIsEqualToInnerJoin(const TkBitField *bf1, const TkBitField *bf2, const TkBitField *add2);
/* bf1 == ((bf2 + (add2 - sub2) & add) */
int TkBitIsEqualToInnerJoinDifference(const TkBitField *bf1, const TkBitField *bf2,
    const TkBitField *add2, const TkBitField *sub2);
/* ((bf1 + (add - sub)) & add) == ((bf2 + (add - sub)) & add) */
int TkBitInnerJoinDifferenceIsEqual(const TkBitField *bf1, const TkBitField *bf2,
    const TkBitField *add, const TkBitField *sub);

#endif /* TK_UNUSED_BITFIELD_FUNCTIONS */

#define _TK_NEED_IMPLEMENTATION
#include "tkBitFieldPriv.h"
#endif /* _TKBITFIELD */
/* vi:set ts=8 sw=4: */

Added generic/tkBitFieldPriv.h.





























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * tkBitFieldPriv.h --
 *
 *	Private implementation for bit field.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKBITFIELD
# error "do not include this private header file"
#endif


#ifndef _TKBITFIELDPRIV
#define _TKBITFIELDPRIV

MODULE_SCOPE int TkBitNone_(const size_t *buf, unsigned words);

#endif /* _TKBITFIELDPRIV */


#ifdef _TK_NEED_IMPLEMENTATION

#include <assert.h>


#define TK_BIT_WORD_INDEX(n)	((n) >> ((TK_BIT_NBITS + 128) >> 5))
#define TK_BIT_INDEX(n)		((n) & (TK_BIT_NBITS - 1))
#define TK_BIT_MASK(n)		(((size_t) 1) << (n))
#define TK_BIT_COUNT_WORDS(n)	((n + TK_BIT_NBITS - 1)/TK_BIT_NBITS)


inline
const unsigned char *
TkBitData(
    const TkBitField *bf)
{
    assert(bf);
    return (const unsigned char *) bf->bits;
}


inline
unsigned
TkBitByteSize(
    const TkBitField *bf)
{
    assert(bf);
    return TK_BIT_COUNT_WORDS(bf->size);
}


inline
unsigned
TkBitAdjustSize(
    unsigned size)
{
    return ((size + (TK_BIT_NBITS - 1))/TK_BIT_NBITS)*TK_BIT_NBITS;
}


inline
TkBitField *
TkBitNew(
    unsigned size)
{
    TkBitField *bf = TkBitResize(NULL, size);
    bf->refCount = 0;
    return bf;
}


inline
unsigned
TkBitRefCount(
    const TkBitField *bf)
{
    assert(bf);
    return bf->refCount;
}


inline
void
TkBitIncrRefCount(
    TkBitField *bf)
{
    assert(bf);
    bf->refCount += 1;
}


inline
unsigned
TkBitDecrRefCount(
    TkBitField *bf)
{
    unsigned refCount;

    assert(bf);
    assert(TkBitRefCount(bf) > 0);

    if ((refCount = --bf->refCount) == 0) {
	TkBitDestroy(&bf);
    }
    return refCount;
}


inline
size_t
TkBitSize(
    const TkBitField *bf)
{
    assert(bf);
    return bf->size;
}


inline
int
TkBitIsEmpty(
    const TkBitField *bf)
{
    assert(bf);
    return bf->size == 0;
}


inline
int
TkBitNone(
    const TkBitField *bf)
{
    assert(bf);
    return bf->size == 0 || TkBitNone_(bf->bits, TK_BIT_COUNT_WORDS(bf->size));
}


inline
int
TkBitIntersects(
    const TkBitField *bf1,
    const TkBitField *bf2)
{
    return !TkBitDisjunctive(bf1, bf2);
}


inline
int
TkBitTest(
    const TkBitField *bf,
    unsigned n)
{
    assert(bf);
    assert(n < TkBitSize(bf));
    return !!(bf->bits[TK_BIT_WORD_INDEX(n)] & TK_BIT_MASK(TK_BIT_INDEX(n)));
}


inline
void
TkBitSet(
    TkBitField *bf,
    unsigned n)
{
    assert(bf);
    assert(n < TkBitSize(bf));
    bf->bits[TK_BIT_WORD_INDEX(n)] |= TK_BIT_MASK(TK_BIT_INDEX(n));
}


inline
void
TkBitUnset(
    TkBitField *bf,
    unsigned n)
{
    assert(bf);
    assert(n < TkBitSize(bf));
    bf->bits[TK_BIT_WORD_INDEX(n)] &= ~TK_BIT_MASK(TK_BIT_INDEX(n));
}


inline
void
TkBitPut(
    TkBitField *bf,
    unsigned n,
    int value)
{
    if (value) {
	TkBitSet(bf, n);
    } else {
	TkBitUnset(bf, n);
    }
}


#undef _TK_NEED_IMPLEMENTATION
#endif /* _TK_NEED_IMPLEMENTATION */
/* vi:set ts=8 sw=4: */

Changes to generic/tkBitmap.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15




16
17
18
19
20
21
22
/*
 * 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.
 *
 * 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 includes below are for pre-defined bitmaps.
 *
 * Platform-specific issue: Windows complains when the bitmaps are included,
 * because an array of characters is being initialized with integers as
 * elements. For lint purposes, the following pragmas temporarily turn off







|
|






>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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 © 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The includes below are for pre-defined bitmaps.
 *
 * Platform-specific issue: Windows complains when the bitmaps are included,
 * because an array of characters is being initialized with integers as
 * elements. For lint purposes, the following pragmas temporarily turn off
117
118
119
120
121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136

/*
 * The following structure defines the implementation of the "bitmap" Tcl
 * object, which maps a string bitmap name to a TkBitmap object. The ptr1
 * field of the Tcl_Obj points to a TkBitmap object.
 */

const Tcl_ObjType tkBitmapObjType = {
    "bitmap",			/* name */
    FreeBitmapObjProc,		/* freeIntRepProc */
    DupBitmapObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocBitmapFromObj --
 *







|
|



|
>
>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

/*
 * The following structure defines the implementation of the "bitmap" Tcl
 * object, which maps a string bitmap name to a TkBitmap object. The ptr1
 * field of the Tcl_Obj points to a TkBitmap object.
 */

const TkObjType tkBitmapObjType = {
    {"bitmap",			/* name */
    FreeBitmapObjProc,		/* freeIntRepProc */
    DupBitmapObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocBitmapFromObj --
 *
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
				 * NULL. */
    Tk_Window tkwin,		/* Need the screen the bitmap is used on.*/
    Tcl_Obj *objPtr)		/* Object describing bitmap; see manual entry
				 * for legal syntax of string value. */
{
    TkBitmap *bitmapPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(objPtr);
    }
    bitmapPtr = (TkBitmap *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBitmap, see if it's the one we
     * want. If so, increment its reference count and return.







|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
				 * NULL. */
    Tk_Window tkwin,		/* Need the screen the bitmap is used on.*/
    Tcl_Obj *objPtr)		/* Object describing bitmap; see manual entry
				 * for legal syntax of string value. */
{
    TkBitmap *bitmapPtr;

    if (objPtr->typePtr != &tkBitmapObjType.objType) {
	InitBitmapObj(objPtr);
    }
    bitmapPtr = (TkBitmap *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkBitmap, see if it's the one we
     * want. If so, increment its reference count and return.
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    if (*string == '@') {	/* INTL: ISO char */
	Tcl_DString buffer;
	int result;

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify bitmap with '@' in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    goto error;
	}

	/*
	 * Note that we need to cast away the const from the string because
	 * Tcl_TranslateFileName is non-const, even though it doesn't modify







|







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
    if (*string == '@') {	/* INTL: ISO char */
	Tcl_DString buffer;
	int result;

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify bitmap with '@' in a safe interpreter",
		    TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    goto error;
	}

	/*
	 * Note that we need to cast away the const from the string because
	 * Tcl_TranslateFileName is non-const, even though it doesn't modify
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
    nameKey.height = height;
    dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
	    (char *) &nameKey, &isNew);
    if (!isNew) {
	name = (char *)Tcl_GetHashValue(dataHashPtr);
    } else {
	dispPtr->bitmapAutoNumber++;
	sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber);
	name = string;
	Tcl_SetHashValue(dataHashPtr, name);
	if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
	    Tcl_DeleteHashEntry(dataHashPtr);
	    return TCL_ERROR;
	}
    }







|







836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
    nameKey.height = height;
    dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
	    (char *) &nameKey, &isNew);
    if (!isNew) {
	name = (char *)Tcl_GetHashValue(dataHashPtr);
    } else {
	dispPtr->bitmapAutoNumber++;
	snprintf(string, sizeof(string), "_tk%d", dispPtr->bitmapAutoNumber);
	name = string;
	Tcl_SetHashValue(dataHashPtr, name);
	if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
	    Tcl_DeleteHashEntry(dataHashPtr);
	    return TCL_ERROR;
	}
    }
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
    Tcl_Obj *objPtr)		/* The object that describes the desired
				 * bitmap. */
{
    TkBitmap *bitmapPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkBitmapObjType) {
	InitBitmapObj(objPtr);
    }

    bitmapPtr = (TkBitmap *)objPtr->internalRep.twoPtrValue.ptr1;
    if (bitmapPtr != NULL) {
	if ((bitmapPtr->resourceRefCount > 0)
		&& (Tk_Display(tkwin) == bitmapPtr->display)) {







|







907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
    Tcl_Obj *objPtr)		/* The object that describes the desired
				 * bitmap. */
{
    TkBitmap *bitmapPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkBitmapObjType.objType) {
	InitBitmapObj(objPtr);
    }

    bitmapPtr = (TkBitmap *)objPtr->internalRep.twoPtrValue.ptr1;
    if (bitmapPtr != NULL) {
	if ((bitmapPtr->resourceRefCount > 0)
		&& (Tk_Display(tkwin) == bitmapPtr->display)) {
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkBitmapObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * BitmapInit --







|







982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkBitmapObjType.objType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * BitmapInit --
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
				 * or NULL if unavailable. */
{
    Tcl_Interp *dummy;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * First initialize the data in the ThreadSpecificData strucuture, if
     * needed.
     */

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	dummy = Tcl_CreateInterp();
	Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);







|







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
				 * or NULL if unavailable. */
{
    Tcl_Interp *dummy;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * First initialize the data in the ThreadSpecificData structure, if
     * needed.
     */

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	dummy = Tcl_CreateInterp();
	Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

/*
 *----------------------------------------------------------------------
 *
 * TkReadBitmapFile --
 *
 *	Loads a bitmap image in X bitmap format into the specified drawable.
 *	This is equivelent to the XReadBitmapFile in X.
 *
 * Results:
 *	Sets the size, hotspot, and bitmap on success.
 *
 * Side effects:
 *	Creates a new bitmap from the file data.
 *







|







1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094

/*
 *----------------------------------------------------------------------
 *
 * TkReadBitmapFile --
 *
 *	Loads a bitmap image in X bitmap format into the specified drawable.
 *	This is equivalent to the XReadBitmapFile in X.
 *
 * Results:
 *	Sets the size, hotspot, and bitmap on success.
 *
 * Side effects:
 *	Creates a new bitmap from the file data.
 *
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetBitmapPredefTable --
 *
 *	This function is used by tkMacBitmap.c to access the thread-specific
 *	predefBitmap table that maps from the names of the predefined bitmaps
 *	to data associated with those bitmaps. It is required because the
 *	table is allocated in thread-local storage and is not visible outside
 *	this file.

 * Results:
 *	Returns a pointer to the predefined bitmap hash table for the current







|







1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetBitmapPredefTable --
 *
 *	This function is used by tkMacOSXBitmap.c to access the thread-specific
 *	predefBitmap table that maps from the names of the predefined bitmaps
 *	to data associated with those bitmaps. It is required because the
 *	table is allocated in thread-local storage and is not visible outside
 *	this file.

 * Results:
 *	Returns a pointer to the predefined bitmap hash table for the current

Changes to generic/tkBusy.c.

12
13
14
15
16
17
18




19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkBusy.h"
#include "default.h"





/*
 * Things about the busy system that may be configured. Note that on some
 * platforms this may or may not have an effect.
 */

static const Tk_OptionSpec busyOptionSpecs[] = {
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUSY_CURSOR, TCL_INDEX_NONE, offsetof(Busy, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations of functions defined in this file.
 */

static void		BusyEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		BusyGeometryProc(ClientData clientData,
			    Tk_Window tkwin);
static void		BusyCustodyProc(ClientData clientData,
			    Tk_Window tkwin);
static int		ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr,
			    int objc, Tcl_Obj *const objv[]);
static Busy *		CreateBusy(Tcl_Interp *interp, Tk_Window tkRef);
static void		DestroyBusy(void *dataPtr);
static void		DoConfigureNotify(Tk_FakeWin *winPtr);
static inline Tk_Window	FirstChild(Tk_Window parent);
static Busy *		GetBusy(Tcl_Interp *interp,
			    Tcl_HashTable *busyTablePtr,
			    Tcl_Obj *const windowObj);
static int		HoldBusy(Tcl_HashTable *busyTablePtr,
			    Tcl_Interp *interp, Tcl_Obj *const windowObj,
			    int configObjc, Tcl_Obj *const configObjv[]);
static void		MakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
static inline Tk_Window	NextChild(Tk_Window tkwin);
static void		RefWinEventProc(ClientData clientData,
			    XEvent *eventPtr);
static inline void	SetWindowInstanceData(Tk_Window tkwin,
			    ClientData instanceData);

/*
 * The "busy" geometry manager definition.
 */

static Tk_GeomMgr busyMgrInfo = {
    "busy",			/* Name of geometry manager used by winfo */







>
>
>
>
















|

|

|


|

|







|



|


|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkBusy.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Things about the busy system that may be configured. Note that on some
 * platforms this may or may not have an effect.
 */

static const Tk_OptionSpec busyOptionSpecs[] = {
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUSY_CURSOR, TCL_INDEX_NONE, offsetof(Busy, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations of functions defined in this file.
 */

static void		BusyEventProc(void *clientData,
			    XEvent *eventPtr);
static void		BusyGeometryProc(void *clientData,
			    Tk_Window tkwin);
static void		BusyCustodyProc(void *clientData,
			    Tk_Window tkwin);
static int		ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static Busy *		CreateBusy(Tcl_Interp *interp, Tk_Window tkRef);
static Tcl_FreeProc	DestroyBusy;
static void		DoConfigureNotify(Tk_FakeWin *winPtr);
static inline Tk_Window	FirstChild(Tk_Window parent);
static Busy *		GetBusy(Tcl_Interp *interp,
			    Tcl_HashTable *busyTablePtr,
			    Tcl_Obj *const windowObj);
static int		HoldBusy(Tcl_HashTable *busyTablePtr,
			    Tcl_Interp *interp, Tcl_Obj *const windowObj,
			    Tcl_Size configObjc, Tcl_Obj *const configObjv[]);
static void		MakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
static inline Tk_Window	NextChild(Tk_Window tkwin);
static void		RefWinEventProc(void *clientData,
			    XEvent *eventPtr);
static inline void	SetWindowInstanceData(Tk_Window tkwin,
			    void *instanceData);

/*
 * The "busy" geometry manager definition.
 */

static Tk_GeomMgr busyMgrInfo = {
    "busy",			/* Name of geometry manager used by winfo */
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    }
    return (Tk_Window) winPtr->nextPtr;
}

static inline void
SetWindowInstanceData(
    Tk_Window tkwin,
    ClientData instanceData)
{
    struct TkWindow *winPtr = (struct TkWindow *) tkwin;

    winPtr->instanceData = instanceData;
}

/*







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    }
    return (Tk_Window) winPtr->nextPtr;
}

static inline void
SetWindowInstanceData(
    Tk_Window tkwin,
    void *instanceData)
{
    struct TkWindow *winPtr = (struct TkWindow *) tkwin;

    winPtr->instanceData = instanceData;
}

/*
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
 *	The Busy structure is freed at the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
BusyCustodyProc(
    ClientData clientData,	/* Information about the busy window. */
    TCL_UNUSED(Tk_Window))		/* Not used. */
{
    Busy *busyPtr = (Busy *)clientData;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyGeometryProc --
 *







|








|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
 *	The Busy structure is freed at the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
BusyCustodyProc(
    void *clientData,	/* Information about the busy window. */
    TCL_UNUSED(Tk_Window))		/* Not used. */
{
    Busy *busyPtr = (Busy *)clientData;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, DestroyBusy);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyGeometryProc --
 *
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
 *	it's hidden, the busy window is unmapped.
 *
 *----------------------------------------------------------------------
 */

static void
RefWinEventProc(
    ClientData clientData,	/* Busy window record */
    XEvent *eventPtr)	/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    switch (eventPtr->type) {
    case ReparentNotify:
    case DestroyNotify:
	/*
	 * Arrange for the busy structure to be removed at a proper time.
	 */

	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
	break;

    case ConfigureNotify:
	if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) ||
		(busyPtr->height != Tk_Height(busyPtr->tkRef)) ||
		(busyPtr->x != Tk_X(busyPtr->tkRef)) ||
		(busyPtr->y != Tk_Y(busyPtr->tkRef))) {







|











|







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
 *	it's hidden, the busy window is unmapped.
 *
 *----------------------------------------------------------------------
 */

static void
RefWinEventProc(
    void *clientData,	/* Busy window record */
    XEvent *eventPtr)	/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    switch (eventPtr->type) {
    case ReparentNotify:
    case DestroyNotify:
	/*
	 * Arrange for the busy structure to be removed at a proper time.
	 */

	Tcl_EventuallyFree(busyPtr, DestroyBusy);
	break;

    case ConfigureNotify:
	if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) ||
		(busyPtr->height != Tk_Height(busyPtr->tkRef)) ||
		(busyPtr->x != Tk_X(busyPtr->tkRef)) ||
		(busyPtr->y != Tk_Y(busyPtr->tkRef))) {
325
326
327
328
329
330
331

332



333
334
335
336
337
338
339
 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyBusy(

    void *data)			/* Busy window structure record */



{
    Busy *busyPtr = (Busy *)data;

    if (busyPtr->hashPtr != NULL) {
	Tcl_DeleteHashEntry(busyPtr->hashPtr);
    }
    Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask,







>

>
>
>







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyBusy(
#if TCL_MAJOR_VERSION > 8
    void *data)			/* Busy window structure record */
#else
    char *data)
#endif
{
    Busy *busyPtr = (Busy *)data;

    if (busyPtr->hashPtr != NULL) {
	Tcl_DeleteHashEntry(busyPtr->hashPtr);
    }
    Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask,
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
 *	with it released at the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
BusyEventProc(
    ClientData clientData,	/* Busy window record */
    XEvent *eventPtr)		/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    if (eventPtr->type == DestroyNotify) {
	busyPtr->tkBusy = NULL;
	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeTransparentWindowExist --







|






|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
 *	with it released at the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
BusyEventProc(
    void *clientData,	/* Busy window record */
    XEvent *eventPtr)		/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    if (eventPtr->type == DestroyNotify) {
	busyPtr->tkBusy = NULL;
	Tcl_EventuallyFree(busyPtr, DestroyBusy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeTransparentWindowExist --
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
	    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
	}
    }
    for (tkChild = FirstChild(tkParent); tkChild != NULL;
	    tkChild = NextChild(tkChild)) {
	Tk_MakeWindowExist(tkChild);
    }
    sprintf(name, fmt, Tk_Name(tkRef));
    tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL);
    ckfree(name);

    if (tkBusy == NULL) {
	return NULL;
    }
    Tk_MakeWindowExist(tkRef);







|







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
	    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
	}
    }
    for (tkChild = FirstChild(tkParent); tkChild != NULL;
	    tkChild = NextChild(tkChild)) {
	Tk_MakeWindowExist(tkChild);
    }
    snprintf(name, length + 6, fmt, Tk_Name(tkRef));
    tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL);
    ckfree(name);

    if (tkBusy == NULL) {
	return NULL;
    }
    Tk_MakeWindowExist(tkRef);
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
 *----------------------------------------------------------------------
 */

static int
ConfigureBusy(
    Tcl_Interp *interp,
    Busy *busyPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Cursor oldCursor = busyPtr->cursor;

    if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc,
	    objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;







|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
 *----------------------------------------------------------------------
 */

static int
ConfigureBusy(
    Tcl_Interp *interp,
    Busy *busyPtr,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Tk_Cursor oldCursor = busyPtr->cursor;

    if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc,
	    objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
    Tcl_Interp *interp,		/* Interpreter to look up main window of. */
    Tcl_HashTable *busyTablePtr,/* Busy hash table */
    Tcl_Obj *const windowObj)	/* Path name of parent window */
{
    Tcl_HashEntry *hPtr;
    Tk_Window tkwin;

    if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj,
	    &tkwin) != TCL_OK) {
	return NULL;
    }
    hPtr = Tcl_FindHashEntry(busyTablePtr, tkwin);
    if (hPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't find busy window \"%s\"", Tcl_GetString(windowObj)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY",







|
|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
    Tcl_Interp *interp,		/* Interpreter to look up main window of. */
    Tcl_HashTable *busyTablePtr,/* Busy hash table */
    Tcl_Obj *const windowObj)	/* Path name of parent window */
{
    Tcl_HashEntry *hPtr;
    Tk_Window tkwin;

    tkwin = Tk_MainWindow(interp);
    if (!tkwin || (TkGetWindowFromObj(interp, tkwin, windowObj, &tkwin) != TCL_OK)) {
	return NULL;
    }
    hPtr = Tcl_FindHashEntry(busyTablePtr, tkwin);
    if (hPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't find busy window \"%s\"", Tcl_GetString(windowObj)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY",
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
 */

static int
HoldBusy(
    Tcl_HashTable *busyTablePtr,/* Busy hash table. */
    Tcl_Interp *interp,		/* Interpreter to report errors to. */
    Tcl_Obj *const windowObj,	/* Window name. */
    int configObjc,		/* Option pairs. */
    Tcl_Obj *const configObjv[])
{
    Tk_Window tkwin;
    Tcl_HashEntry *hPtr;
    Busy *busyPtr;
    int isNew, result;

    if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj,
	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }
    hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew);
    if (isNew) {
	busyPtr = CreateBusy(interp, tkwin);
	if (busyPtr == NULL) {

	    return TCL_ERROR;
	}
	Tcl_SetHashValue(hPtr, busyPtr);
	busyPtr->hashPtr = hPtr;
    } else {
	busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
    }







|















>







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
 */

static int
HoldBusy(
    Tcl_HashTable *busyTablePtr,/* Busy hash table. */
    Tcl_Interp *interp,		/* Interpreter to report errors to. */
    Tcl_Obj *const windowObj,	/* Window name. */
    Tcl_Size configObjc,		/* Option pairs. */
    Tcl_Obj *const configObjv[])
{
    Tk_Window tkwin;
    Tcl_HashEntry *hPtr;
    Busy *busyPtr;
    int isNew, result;

    if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj,
	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }
    hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew);
    if (isNew) {
	busyPtr = CreateBusy(interp, tkwin);
	if (busyPtr == NULL) {
	    Tcl_DeleteHashEntry(hPtr);
	    return TCL_ERROR;
	}
	Tcl_SetHashValue(hPtr, busyPtr);
	busyPtr->hashPtr = hPtr;
    } else {
	busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
    }
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771

    if (Tk_IsMapped(busyPtr->tkRef)) {
	TkpShowBusyWindow(busyPtr);
    } else {
	TkpHideBusyWindow(busyPtr);
    }
    if (result == TCL_OK) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *







|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

    if (Tk_IsMapped(busyPtr->tkRef)) {
	TkpShowBusyWindow(busyPtr);
    } else {
	TkpHideBusyWindow(busyPtr);
    }
    if (result == TCL_OK) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), TCL_INDEX_NONE));
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BusyObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable;
    Busy *busyPtr;
    Tcl_Obj *objPtr;
    int index, result = TCL_OK;







|

|







790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BusyObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable;
    Busy *busyPtr;
    Tcl_Obj *objPtr;
    int index, result = TCL_OK;
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    Tcl_ResetResult(interp);
            return TCL_OK;
	}
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
        return TCL_OK;

    case BUSY_CGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window option");
	    return TCL_ERROR;
	}







|







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    Tcl_ResetResult(interp);
            return TCL_OK;
	}
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), TCL_INDEX_NONE));
        return TCL_OK;

    case BUSY_CGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window option");
	    return TCL_ERROR;
	}
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	TkpHideBusyWindow(busyPtr);
	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}







|







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	TkpHideBusyWindow(busyPtr);
	Tcl_EventuallyFree(busyPtr, DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}

Changes to generic/tkButton.c.

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.
 *
 * 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"







|
|







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 © 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"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 * Class names for buttons, indexed by one of the type values defined in
 * tkButton.h.
 */

static const char *const classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};

/*
 * The following table defines the legal values for the -default option. It is
 * used together with the "enum defaultValue" declaration in tkButton.h.
 */

static const char *const defaultStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -state option.
 * It is used together with the "enum state" declaration in tkButton.h.
 */

static const char *const stateStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -compound option.
 * It is used with the "enum compound" declaration in tkButton.h
 */

static const char *const compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

char tkDefButtonHighlightWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_HIGHLIGHT_WIDTH;
char tkDefButtonPadx[TCL_INTEGER_SPACE] = DEF_BUTTON_PADX;
char tkDefButtonPady[TCL_INTEGER_SPACE] = DEF_BUTTON_PADY;
char tkDefButtonBorderWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_BORDER_WIDTH;







|
<
<
<
<
<
<
<
<
<
|


|








|







25
26
27
28
29
30
31
32









33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 * Class names for buttons, indexed by one of the type values defined in
 * tkButton.h.
 */

static const char *const classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};

/*
 * The following table defines the legal values for the -default/-state options.









 * It is used together with the "enum defaultValue/state" declarations in tkButton.h.
 */

const char *const tkStateStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -compound option.
 * It is used with the "enum compound" declaration in tkButton.h
 */

const char *const tkCompoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

char tkDefButtonHighlightWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_HIGHLIGHT_WIDTH;
char tkDefButtonPadx[TCL_INTEGER_SPACE] = DEF_BUTTON_PADX;
char tkDefButtonPady[TCL_INTEGER_SPACE] = DEF_BUTTON_PADY;
char tkDefButtonBorderWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_BORDER_WIDTH;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec buttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
        DEF_BUTTON_DEFAULT, TCL_INDEX_NONE, offsetof(TkButton, defaultState),
	0, defaultStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefButtonPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, offsetof(TkButton, offValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_CHECKBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),







|














|
|






|





|





|











|










|








|
|
















|

















|
|




|
|



|











|











|




















|








|
|
















|

















|
|






|











|













|

|





|
|
















|













|
|



















|

















|
|






|











|














|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_LABEL_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TK_OPTION_UNDERLINE_DEF(TkButton, underline), 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec buttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
	DEF_BUTTON_DEFAULT, TCL_INDEX_NONE, offsetof(TkButton, defaultState),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefButtonPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TK_OPTION_UNDERLINE_DEF(TkButton, underline), 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, offsetof(TkButton, offValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TK_OPTION_UNDERLINE_DEF(TkButton, underline), 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_CHECKBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-value", "value", "Value",
	DEF_BUTTON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},







|













|
|







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TK_OPTION_UNDERLINE_DEF(TkButton, underline), 0},
    {TK_OPTION_STRING, "-value", "value", "Value",
	DEF_BUTTON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
	    COMMAND_INVOKE, COMMAND_SELECT}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ButtonCmdDeletedProc(ClientData clientData);
static int		ButtonCreate(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[], int type);
static void		ButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		ButtonImageProc(ClientData clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		ButtonSelectImageProc(ClientData clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		ButtonTristateImageProc(ClientData clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static char *		ButtonTextVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static char *		ButtonVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		ButtonWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		ConfigureButton(Tcl_Interp *interp, TkButton *butPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyButton(TkButton *butPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_ButtonCmd, Tk_CheckbuttonCmd, Tk_LabelCmd, Tk_RadiobuttonCmd --
 *







|
|
|

|

|


|


|


|


|


|
<
<

|







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536


537
538
539
540
541
542
543
544
545
	    COMMAND_INVOKE, COMMAND_SELECT}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ButtonCmdDeletedProc(void *clientData);
static int		ButtonCreate(void *clientData,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[], int type);
static void		ButtonEventProc(void *clientData,
			    XEvent *eventPtr);
static void		ButtonImageProc(void *clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		ButtonSelectImageProc(void *clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		ButtonTristateImageProc(void *clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static char *		ButtonTextVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static char *		ButtonVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static Tcl_ObjCmdProc ButtonWidgetObjCmd;


static int		ConfigureButton(Tcl_Interp *interp, TkButton *butPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DestroyButton(TkButton *butPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_ButtonCmd, Tk_CheckbuttonCmd, Tk_LabelCmd, Tk_RadiobuttonCmd --
 *
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
 *	call ButtonCreate to do all of the real work.
 *
 *--------------------------------------------------------------
 */

int
Tk_ButtonObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_BUTTON);
}

int
Tk_CheckbuttonObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_CHECK_BUTTON);
}

int
Tk_LabelObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_LABEL);
}

int
Tk_RadiobuttonObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_RADIO_BUTTON);
}








|









|









|









|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
 *	call ButtonCreate to do all of the real work.
 *
 *--------------------------------------------------------------
 */

int
Tk_ButtonObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_BUTTON);
}

int
Tk_CheckbuttonObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_CHECK_BUTTON);
}

int
Tk_LabelObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_LABEL);
}

int
Tk_RadiobuttonObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    return ButtonCreate(clientData, interp, objc, objv, TYPE_RADIO_BUTTON);
}

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonCreate(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument values. */
    int type)			/* Type of button to create: TYPE_LABEL,
				 * TYPE_BUTTON, TYPE_CHECK_BUTTON, or
				 * TYPE_RADIO_BUTTON. */
{
    TkButton *butPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    if (!tsdPtr->defaultsInitialized) {
	TkpButtonSetDefaults();
	tsdPtr->defaultsInitialized = 1;
    }

    if (objc < 2) {







|

|










<







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonCreate(
    TCL_UNUSED(void *),	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument values. */
    int type)			/* Type of button to create: TYPE_LABEL,
				 * TYPE_BUTTON, TYPE_CHECK_BUTTON, or
				 * TYPE_RADIO_BUTTON. */
{
    TkButton *butPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if (!tsdPtr->defaultsInitialized) {
	TkpButtonSetDefaults();
	tsdPtr->defaultsInitialized = 1;
    }

    if (objc < 2) {
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
    butPtr->display = Tk_Display(tkwin);
    butPtr->interp = interp;
    butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
	    ButtonWidgetObjCmd, butPtr, ButtonCmdDeletedProc);
    butPtr->type = type;
    butPtr->optionTable = optionTable;
    butPtr->textPtr = NULL;
    butPtr->underline = -1;
    butPtr->textVarNamePtr = NULL;
    butPtr->bitmap = None;
    butPtr->imagePtr = NULL;
    butPtr->image = NULL;
    butPtr->selectImagePtr = NULL;
    butPtr->selectImage = NULL;
    butPtr->tristateImagePtr = NULL;







|







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
    butPtr->display = Tk_Display(tkwin);
    butPtr->interp = interp;
    butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
	    ButtonWidgetObjCmd, butPtr, ButtonCmdDeletedProc);
    butPtr->type = type;
    butPtr->optionTable = optionTable;
    butPtr->textPtr = NULL;
    butPtr->underline = INT_MIN;
    butPtr->textVarNamePtr = NULL;
    butPtr->bitmap = None;
    butPtr->imagePtr = NULL;
    butPtr->image = NULL;
    butPtr->selectImagePtr = NULL;
    butPtr->selectImage = NULL;
    butPtr->tristateImagePtr = NULL;
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonWidgetObjCmd(
    ClientData clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    TkButton *butPtr = (TkButton *)clientData;
    int index;
    int result;







|







768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonWidgetObjCmd(
    void *clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    TkButton *butPtr = (TkButton *)clientData;
    int index;
    int result;
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
	Tk_FreeTextLayout(butPtr->textLayout);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, butPtr);
    }
    Tk_FreeConfigOptions((char *) butPtr, butPtr->optionTable,
	    butPtr->tkwin);
    butPtr->tkwin = NULL;
    Tcl_EventuallyFree(butPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------







|







992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
	Tk_FreeTextLayout(butPtr->textLayout);
    }
    if (butPtr->selVarNamePtr != NULL) {
	Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr),
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		ButtonVarProc, butPtr);
    }
    Tk_FreeConfigOptions(butPtr, butPtr->optionTable,
	    butPtr->tkwin);
    butPtr->tkwin = NULL;
    Tcl_EventuallyFree(butPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
 */

static int
ConfigureButton(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkButton *butPtr,	/* Information about widget;  may or may
				 * not already have values for some fields. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *errorResult = NULL;
    int error, haveImage;
    Tk_Image image;








|







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
 */

static int
ConfigureButton(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkButton *butPtr,	/* Information about widget;  may or may
				 * not already have values for some fields. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *errorResult = NULL;
    int error, haveImage;
    Tk_Image image;

1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
 *      Button will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

void
TkButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    TkButton *butPtr = (TkButton *)instanceData;

    /*







|







1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
 *      Button will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

void
TkButtonWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    TkButton *butPtr = (TkButton *)instanceData;

    /*
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *butPtr = (TkButton *)clientData;
    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	/*







|







1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *butPtr = (TkButton *)clientData;
    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	/*
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkButton *butPtr = (TkButton *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted or because the command was deleted,
     * and then this function destroys the widget. The BUTTON_DELETED flag







|







1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TkButton *butPtr = (TkButton *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted or because the command was deleted,
     * and then this function destroys the widget. The BUTTON_DELETED flag
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
 *	The button may become selected or deselected.
 *
 *--------------------------------------------------------------
 */

static char *
ButtonVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    const char *value;
    Tcl_Obj *valuePtr;
    (void)name1;
    (void)name2;

    /*
     * If the variable is being unset, then just re-establish the trace unless
     * the whole interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	butPtr->flags &= ~(SELECTED | TRISTATED);
	if (!Tcl_InterpDeleted(interp)) {
	    ClientData probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->selVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonVarProc, probe);
		if (probe == (ClientData)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * selVarNamePtr, which means it is not unset and not







|

|
|





<
<









|






|







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
 *	The button may become selected or deselected.
 *
 *--------------------------------------------------------------
 */

static char *
ButtonVarProc(
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),	/* Name of variable. */
    TCL_UNUSED(const char *),	/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    const char *value;
    Tcl_Obj *valuePtr;



    /*
     * If the variable is being unset, then just re-establish the trace unless
     * the whole interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	butPtr->flags &= ~(SELECTED | TRISTATED);
	if (!Tcl_InterpDeleted(interp)) {
	    void *probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->selVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonVarProc, probe);
		if (probe == (void *)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * selVarNamePtr, which means it is not unset and not
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
 *	The text displayed in the button will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
ButtonTextVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    Tcl_Obj *valuePtr;







|







1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
 *	The text displayed in the button will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
ButtonTextVarProc(
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    Tcl_Obj *valuePtr;
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
	if (!Tcl_InterpDeleted(interp) && butPtr->textVarNamePtr != NULL) {

	    /*
	     * An unset trace on some variable brought us here, but is it
	     * the variable we have stored in butPtr->textVarNamePtr ?
	     */

	    ClientData probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->textVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonTextVarProc, probe);
		if (probe == (ClientData)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * textVarNamePtr, which means it is not unset and not







|






|







1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
	if (!Tcl_InterpDeleted(interp) && butPtr->textVarNamePtr != NULL) {

	    /*
	     * An unset trace on some variable brought us here, but is it
	     * the variable we have stored in butPtr->textVarNamePtr ?
	     */

	    void *probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->textVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonTextVarProc, probe);
		if (probe == (void *)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * textVarNamePtr, which means it is not unset and not
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;







|







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonImageProc(
    void *clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
 *	May arrange for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonSelectImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;







|







1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
 *	May arrange for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonSelectImageProc(
    void *clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
 *	May arrange for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonTristateImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;







|







1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
 *	May arrange for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ButtonTristateImageProc(
    void *clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;

Changes to generic/tkButton.h.

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.
 *
 * 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






|







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 © 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    /*
     * Information about what's in the button.
     */

    Tcl_Obj *textPtr;		/* Value of -text option: specifies text to
				 * display in button. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline. < 0 means don't
				 * underline anything. */
    Tcl_Obj *textVarNamePtr;	/* Value of -textvariable option: specifies
				 * name of variable or NULL. If non-NULL,
				 * button displays the contents of this
				 * variable. */
    Pixmap bitmap;		/* Value of -bitmap option. If not None,
				 * specifies bitmap to display and text and







|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    /*
     * Information about what's in the button.
     */

    Tcl_Obj *textPtr;		/* Value of -text option: specifies text to
				 * display in button. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline. INT_MIN means don't
				 * underline anything. */
    Tcl_Obj *textVarNamePtr;	/* Value of -textvariable option: specifies
				 * name of variable or NULL. If non-NULL,
				 * button displays the contents of this
				 * variable. */
    Pixmap bitmap;		/* Value of -bitmap option. If not None,
				 * specifies bitmap to display and text and
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/*
 * Declaration of functions used in the implementation of the button widget.
 */

#ifndef TkpButtonSetDefaults
MODULE_SCOPE void	TkpButtonSetDefaults(void);
#endif
MODULE_SCOPE void	TkButtonWorldChanged(ClientData instanceData);
MODULE_SCOPE void	TkpComputeButtonGeometry(TkButton *butPtr);
MODULE_SCOPE TkButton	*TkpCreateButton(Tk_Window tkwin);
#ifndef TkpDestroyButton
MODULE_SCOPE void 	TkpDestroyButton(TkButton *butPtr);
#endif
#ifndef TkpDisplayButton
MODULE_SCOPE void	TkpDisplayButton(ClientData clientData);
#endif
MODULE_SCOPE int	TkInvokeButton(TkButton *butPtr);

#endif /* _TKBUTTON */







|






|




304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/*
 * Declaration of functions used in the implementation of the button widget.
 */

#ifndef TkpButtonSetDefaults
MODULE_SCOPE void	TkpButtonSetDefaults(void);
#endif
MODULE_SCOPE void	TkButtonWorldChanged(void *instanceData);
MODULE_SCOPE void	TkpComputeButtonGeometry(TkButton *butPtr);
MODULE_SCOPE TkButton	*TkpCreateButton(Tk_Window tkwin);
#ifndef TkpDestroyButton
MODULE_SCOPE void 	TkpDestroyButton(TkButton *butPtr);
#endif
#ifndef TkpDisplayButton
MODULE_SCOPE void	TkpDisplayButton(void *clientData);
#endif
MODULE_SCOPE int	TkInvokeButton(TkButton *butPtr);

#endif /* _TKBUTTON */

Changes to generic/tkCanvArc.c.

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.
 *
 * 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"





|
|







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 © 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"
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#define PIE_OUTLINE1_PTS	6
#define PIE_OUTLINE2_PTS	7

/*
 * Information used for parsing configuration specs:
 */

static int	StyleParseProc(ClientData clientData, Tcl_Interp *interp,
		    Tk_Window tkwin, const char *value,
		    char *widgRec, TkSizeT offset);
static const char * StylePrintProc(ClientData clientData, Tk_Window tkwin,
		    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr);

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption styleOption = {
    StyleParseProc, StylePrintProc, NULL
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};







|

|
|
|








|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#define PIE_OUTLINE1_PTS	6
#define PIE_OUTLINE2_PTS	7

/*
 * Information used for parsing configuration specs:
 */

static int	StyleParseProc(void *clientData, Tcl_Interp *interp,
		    Tk_Window tkwin, const char *value,
		    char *widgRec, Tcl_Size offset);
static const char * StylePrintProc(void *clientData, Tk_Window tkwin,
		    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr);

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption styleOption = {
    StyleParseProc, StylePrintProc, NULL
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
static int		ConfigureArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static void		ComputeArcParametersFromHeight(ArcItem *arcPtr);
static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		ArcCoords(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);
static int		ArcToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		ArcToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		ArcToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ScaleArc(Tk_Canvas canvas,







|




|






|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
static int		ConfigureArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static void		ComputeArcParametersFromHeight(ArcItem *arcPtr);
static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		ArcCoords(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static int		ArcToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		ArcToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		ArcToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ScaleArc(Tk_Canvas canvas,
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    sizeof(ArcItem),		/* itemSize */
    CreateArc,			/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureArc,		/* configureProc */
    ArcCoords,			/* coordProc */
    DeleteArc,			/* deleteProc */
    DisplayArc,			/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    ArcToPoint,			/* pointProc */
    ArcToArea,			/* areaProc */
    ArcToPostscript,		/* postscriptProc */
    ScaleArc,			/* scaleProc */
    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */







|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    sizeof(ArcItem),		/* itemSize */
    CreateArc,			/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureArc,		/* configureProc */
    ArcCoords,			/* coordProc */
    DeleteArc,			/* deleteProc */
    DisplayArc,			/* displayProc */
    0,				/* flags */
    ArcToPoint,			/* pointProc */
    ArcToArea,			/* areaProc */
    ArcToPostscript,		/* postscriptProc */
    ScaleArc,			/* scaleProc */
    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

static int
CreateArc(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing arc. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after







|



|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

static int
CreateArc(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing arc. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

static int
ArcCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *objs[4];

	objs[0] = Tcl_NewDoubleObj(arcPtr->bbox[0]);
	objs[1] = Tcl_NewDoubleObj(arcPtr->bbox[1]);
	objs[2] = Tcl_NewDoubleObj(arcPtr->bbox[2]);
	objs[3] = Tcl_NewDoubleObj(arcPtr->bbox[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
    } else if ((objc == 1) || (objc == 4)) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 4, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
 		    &arcPtr->bbox[0]) != TCL_OK)







|



















|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

static int
ArcCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *objs[4];

	objs[0] = Tcl_NewDoubleObj(arcPtr->bbox[0]);
	objs[1] = Tcl_NewDoubleObj(arcPtr->bbox[1]);
	objs[2] = Tcl_NewDoubleObj(arcPtr->bbox[2]);
	objs[3] = Tcl_NewDoubleObj(arcPtr->bbox[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
    } else if ((objc == 1) || (objc == 4)) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 4, got %" TCL_SIZE_MODIFIER "d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
 		    &arcPtr->bbox[0]) != TCL_OK)
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
	arcPtr->startPoint[1] = arcPtr->bbox[1];
	arcPtr->endPoint[0] = arcPtr->bbox[2];
	arcPtr->endPoint[1] = arcPtr->bbox[3];

	ComputeArcBbox(canvas, arcPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
	arcPtr->startPoint[1] = arcPtr->bbox[1];
	arcPtr->endPoint[0] = arcPtr->bbox[2];
	arcPtr->endPoint[1] = arcPtr->bbox[3];

	ComputeArcBbox(canvas, arcPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
 */

static int
ConfigureArc(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Arc item to reconfigure. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    int i;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) arcPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    state = itemPtr->state;

    /*
     * A few of the options require additional processing, such as style and







|
















|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
 */

static int
ConfigureArc(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Arc item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    int i;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, arcPtr, flags)) {
	return TCL_ERROR;
    }

    state = itemPtr->state;

    /*
     * A few of the options require additional processing, such as style and
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = NULL;
    }







|







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }

    mask = (unsigned long)Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
	newGC = NULL;
    }
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
	Tcl_AppendPrintfToObj(psObj,
		"matrix currentmatrix\n"
		"%.15g %.15g translate %.15g %.15g scale\n",
		(arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,
		(arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);

	if (arcPtr->style != CHORD_STYLE) {
	    Tcl_AppendToObj(psObj, "0 0 moveto ", -1);
	}
	Tcl_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
		ang1, ang2);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (arcPtr->outline.gc != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
    }

    /*
     * If there's an outline for the arc, draw it.
     */








|










|






|


|







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
	Tcl_AppendPrintfToObj(psObj,
		"matrix currentmatrix\n"
		"%.15g %.15g translate %.15g %.15g scale\n",
		(arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,
		(arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);

	if (arcPtr->style != CHORD_STYLE) {
	    Tcl_AppendToObj(psObj, "0 0 moveto ", TCL_INDEX_NONE);
	}
	Tcl_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
		ang1, ang2);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (arcPtr->outline.gc != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
	}
    }

    /*
     * If there's an outline for the arc, draw it.
     */

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
		ang1, ang2);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (arcPtr->style != ARC_STYLE) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

	    Tcl_ResetResult(interp);
	    if (arcPtr->style == CHORD_STYLE) {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			CHORD_OUTLINE_PTS);
	    } else {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			PIE_OUTLINE1_PTS);
		Tk_CanvasPsColor(interp, canvas, color);
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

		if (stipple != None) {
		    Tcl_AppendToObj(psObj, "clip ", -1);

		    Tcl_ResetResult(interp);
		    Tk_CanvasPsStipple(interp, canvas, stipple);
		    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
		} else {
		    Tcl_AppendToObj(psObj, "fill\n", -1);
		}
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsPath(interp, canvas,
			arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
			PIE_OUTLINE2_PTS);
	    }
	    Tk_CanvasPsColor(interp, canvas, color);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (stipple != None) {
		Tcl_AppendToObj(psObj, "clip ", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsStipple(interp, canvas, stipple);
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    } else {
		Tcl_AppendToObj(psObj, "fill\n", -1);
	    }
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */







|












|





|

|










|





|







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
		ang1, ang2);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (arcPtr->style != ARC_STYLE) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);

	    Tcl_ResetResult(interp);
	    if (arcPtr->style == CHORD_STYLE) {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			CHORD_OUTLINE_PTS);
	    } else {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			PIE_OUTLINE1_PTS);
		Tk_CanvasPsColor(interp, canvas, color);
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

		if (stipple != None) {
		    Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);

		    Tcl_ResetResult(interp);
		    Tk_CanvasPsStipple(interp, canvas, stipple);
		    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
		} else {
		    Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
		}
		Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);

		Tcl_ResetResult(interp);
		Tk_CanvasPsPath(interp, canvas,
			arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
			PIE_OUTLINE2_PTS);
	    }
	    Tk_CanvasPsColor(interp, canvas, color);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (stipple != None) {
		Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);

		Tcl_ResetResult(interp);
		Tk_CanvasPsStipple(interp, canvas, stipple);
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    } else {
		Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
	    }
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
static int
StyleParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Style *stylePtr = (Style *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*stylePtr = PIESLICE_STYLE;







|







2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
static int
StyleParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Style *stylePtr = (Style *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*stylePtr = PIESLICE_STYLE;
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
 */

static const char *
StylePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Ignored. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Style *stylePtr = (Style *) (widgRec + offset);

    if (*stylePtr == ARC_STYLE) {







|







2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
 */

static const char *
StylePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Ignored. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Style *stylePtr = (Style *) (widgRec + offset);

    if (*stylePtr == ARC_STYLE) {

Changes to generic/tkCanvBmap.c.

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.
 *
 * 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"





|
|







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 © 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"
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},







|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
};

/*
 * Prototypes for functions defined in this file:
 */

static int		BitmapCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[]);
static int		BitmapToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		BitmapToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		BitmapToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ComputeBitmapBbox(Tk_Canvas canvas,
			    BitmapItem *bmapPtr);
static int		ConfigureBitmap(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		TkcCreateBitmap(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);







|










|



|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
};

/*
 * Prototypes for functions defined in this file:
 */

static int		BitmapCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		BitmapToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		BitmapToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		BitmapToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ComputeBitmapBbox(Tk_Canvas canvas,
			    BitmapItem *bmapPtr);
static int		ConfigureBitmap(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static int		TkcCreateBitmap(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    sizeof(BitmapItem),		/* itemSize */
    TkcCreateBitmap,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureBitmap,		/* configureProc */
    BitmapCoords,		/* coordProc */
    DeleteBitmap,		/* deleteProc */
    DisplayBitmap,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    BitmapToPoint,		/* pointProc */
    BitmapToArea,		/* areaProc */
    BitmapToPostscript,		/* postscriptProc */
    ScaleBitmap,		/* scaleProc */
    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */







|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    sizeof(BitmapItem),		/* itemSize */
    TkcCreateBitmap,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureBitmap,		/* configureProc */
    BitmapCoords,		/* coordProc */
    DeleteBitmap,		/* deleteProc */
    DisplayBitmap,		/* displayProc */
    0,				/* flags */
    BitmapToPoint,		/* pointProc */
    BitmapToArea,		/* areaProc */
    BitmapToPostscript,		/* postscriptProc */
    ScaleBitmap,		/* scaleProc */
    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

static int
TkcCreateBitmap(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.







|



|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

static int
TkcCreateBitmap(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

static int
BitmapCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *obj = Tcl_NewObj();

	Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->x));
	Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->y));
	Tcl_SetObjResult(interp, obj);
    } else if (objc < 3) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&bmapPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
			&bmapPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeBitmapBbox(canvas, bmapPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|

















|














|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

static int
BitmapCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *obj = Tcl_NewObj();

	Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->x));
	Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->y));
	Tcl_SetObjResult(interp, obj);
    } else if (objc < 3) {
	if (objc == 1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %" TCL_SIZE_MODIFIER "d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&bmapPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
			&bmapPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeBitmapBbox(canvas, bmapPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
 */

static int
ConfigureBitmap(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Bitmap item to reconfigure. */
    int objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    Tk_Window tkwin;
    unsigned long mask;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) bmapPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as those that
     * determine the graphics context.
     */







|















|







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
 */

static int
ConfigureBitmap(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Bitmap item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    Tk_Window tkwin;
    unsigned long mask;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, bmapPtr, flags)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as those that
     * determine the graphics context.
     */
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteBitmap(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    (void)canvas;

    if (bmapPtr->bitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->bitmap);
    }
    if (bmapPtr->activeBitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->activeBitmap);
    }







|




<







413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteBitmap(
    TCL_UNUSED(Tk_Canvas),		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;


    if (bmapPtr->bitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->bitmap);
    }
    if (bmapPtr->activeBitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->activeBitmap);
    }
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
	y -= height;
	break;
    case TK_ANCHOR_W:
	y -= height/2;
	break;
    case TK_ANCHOR_NW:
	break;
    case TK_ANCHOR_CENTER:
	x -= width/2;
	y -= height/2;
	break;
    }

    /*
     * Store the information in the item header.







|







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
	y -= height;
	break;
    case TK_ANCHOR_W:
	y -= height/2;
	break;
    case TK_ANCHOR_NW:
	break;
    default:
	x -= width/2;
	y -= height/2;
	break;
    }

    /*
     * Store the information in the item header.
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
 *	None.
 *
 *--------------------------------------------------------------
 */

static double
BitmapToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;
    (void)canvas;

    x1 = bmapPtr->header.x1;
    y1 = bmapPtr->header.y1;
    x2 = bmapPtr->header.x2;
    y2 = bmapPtr->header.y2;

    /*







|





<







668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
 *	None.
 *
 *--------------------------------------------------------------
 */

static double
BitmapToPoint(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;


    x1 = bmapPtr->header.x1;
    y1 = bmapPtr->header.y1;
    x2 = bmapPtr->header.x2;
    y2 = bmapPtr->header.y2;

    /*
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
BitmapToArea(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    (void)canvas;

    if ((rectPtr[2] <= bmapPtr->header.x1)
	    || (rectPtr[0] >= bmapPtr->header.x2)
	    || (rectPtr[3] <= bmapPtr->header.y1)
	    || (rectPtr[1] >= bmapPtr->header.y2)) {
	return -1;
    }







|






<







724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
BitmapToArea(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;


    if ((rectPtr[2] <= bmapPtr->header.x1)
	    || (rectPtr[0] >= bmapPtr->header.x2)
	    || (rectPtr[3] <= bmapPtr->header.y1)
	    || (rectPtr[1] >= bmapPtr->header.y2)) {
	return -1;
    }
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
 */

static int
BitmapToPostscript(
    Tcl_Interp *interp,		/* Leave Postscript or error message here. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    int prepass)		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x, y;
    int width, height, rowsAtOnce, rowsThisTime;
    int curRow;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;
    (void)prepass;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;







|













<







872
873
874
875
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 int
BitmapToPostscript(
    Tcl_Interp *interp,		/* Leave Postscript or error message here. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    TCL_UNUSED(int))		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x, y;
    int width, height, rowsAtOnce, rowsThisTime;
    int curRow;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;


    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
    case TK_ANCHOR_N:	   x -= width/2.0; y -= height;		break;
    case TK_ANCHOR_NE:	   x -= width;	   y -= height;		break;
    case TK_ANCHOR_E:	   x -= width;	   y -= height/2.0;	break;
    case TK_ANCHOR_SE:	   x -= width;				break;
    case TK_ANCHOR_S:	   x -= width/2.0;			break;
    case TK_ANCHOR_SW:						break;
    case TK_ANCHOR_W:			   y -= height/2.0;	break;
    case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0;	break;
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();







|







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
    case TK_ANCHOR_N:	   x -= width/2.0; y -= height;		break;
    case TK_ANCHOR_NE:	   x -= width;	   y -= height;		break;
    case TK_ANCHOR_E:	   x -= width;	   y -= height/2.0;	break;
    case TK_ANCHOR_SE:	   x -= width;				break;
    case TK_ANCHOR_S:	   x -= width/2.0;			break;
    case TK_ANCHOR_SW:						break;
    case TK_ANCHOR_W:			   y -= height/2.0;	break;
    default: x -= width/2.0; y -= height/2.0;	break;
    }

    /*
     * Make our working space.
     */

    psObj = Tcl_NewObj();
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
		"%d 0 rlineto closepath\n",
		x, y, width, height, -width);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, bgColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	Tcl_AppendToObj(psObj, "fill\n", -1);
    }

    /*
     * Draw the bitmap, if there is a foreground color. If the bitmap is very
     * large, then chop it up into multiple bitmaps, each consisting of one or
     * more rows. This is needed because Postscript can't handle single
     * strings longer than 64 KBytes long.
     */

    if (fgColor != NULL) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fgColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (width > 60000) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't generate Postscript for bitmaps more than 60000"
		    " pixels wide", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	    goto error;
	}

	rowsAtOnce = 60000/width;
	if (rowsAtOnce < 1) {
	    rowsAtOnce = 1;







|

















|







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
		"%d 0 rlineto closepath\n",
		x, y, width, height, -width);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, bgColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
    }

    /*
     * Draw the bitmap, if there is a foreground color. If the bitmap is very
     * large, then chop it up into multiple bitmaps, each consisting of one or
     * more rows. This is needed because Postscript can't handle single
     * strings longer than 64 KBytes long.
     */

    if (fgColor != NULL) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fgColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (width > 60000) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't generate Postscript for bitmaps more than 60000"
		    " pixels wide", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	    goto error;
	}

	rowsAtOnce = 60000/width;
	if (rowsAtOnce < 1) {
	    rowsAtOnce = 1;
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
		    (double) rowsThisTime, width, rowsThisTime);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsBitmap(interp, canvas, bitmap, 0, curRow, width,
		    rowsThisTime);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    Tcl_AppendToObj(psObj, "\n} imagemask\n", -1);
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */








|







1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
		    (double) rowsThisTime, width, rowsThisTime);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsBitmap(interp, canvas, bitmap, 0, curRow, width,
		    rowsThisTime);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    Tcl_AppendToObj(psObj, "\n} imagemask\n", TCL_INDEX_NONE);
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

Changes to generic/tkCanvImg.c.

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.
 *
 * 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"





|
|







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 © 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"
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
	NULL, offsetof(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},







|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
	NULL, offsetof(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ImageChangedProc(ClientData clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static int		ImageCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const argv[]);
static int		ImageToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		ImageToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		ImageToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ComputeImageBbox(Tk_Canvas canvas, ImageItem *imgPtr);
static int		ConfigureImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const argv[], int flags);
static int		CreateImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const argv[]);
static void		DeleteImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateImage(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);







|



|
|








|
|


|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ImageChangedProc(void *clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static int		ImageCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		ImageToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		ImageToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		ImageToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ComputeImageBbox(Tk_Canvas canvas, ImageItem *imgPtr);
static int		ConfigureImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateImage(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    sizeof(ImageItem),		/* itemSize */
    CreateImage,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureImage,		/* configureProc */
    ImageCoords,		/* coordProc */
    DeleteImage,		/* deleteProc */
    DisplayImage,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    ImageToPoint,		/* pointProc */
    ImageToArea,		/* areaProc */
    ImageToPostscript,		/* postscriptProc */
    ScaleImage,			/* scaleProc */
    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */







|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    sizeof(ImageItem),		/* itemSize */
    CreateImage,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureImage,		/* configureProc */
    ImageCoords,		/* coordProc */
    DeleteImage,		/* deleteProc */
    DisplayImage,		/* displayProc */
    0,				/* flags */
    ImageToPoint,		/* pointProc */
    ImageToArea,		/* areaProc */
    ImageToPostscript,		/* postscriptProc */
    ScaleImage,			/* scaleProc */
    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

static int
CreateImage(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.







|



|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

static int
CreateImage(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

static int
ImageCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *objs[2];

	objs[0] = Tcl_NewDoubleObj(imgPtr->x);
	objs[1] = Tcl_NewDoubleObj(imgPtr->y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs));
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		    &imgPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
  		    &imgPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeImageBbox(canvas, imgPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|

















|














|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

static int
ImageCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *objs[2];

	objs[0] = Tcl_NewDoubleObj(imgPtr->x);
	objs[1] = Tcl_NewDoubleObj(imgPtr->y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs));
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %" TCL_SIZE_MODIFIER "d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		    &imgPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
  		    &imgPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeImageBbox(canvas, imgPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
 */

static int
ConfigureImage(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Image item to reconfigure. */
    int objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    Tk_Window tkwin;
    Tk_Image image;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) imgPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * Create the image. Save the old image around and don't free it until
     * after the new one is allocated. This keeps the reference count from
     * going to zero so the image doesn't have to be recreated if it hasn't







|









|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
 */

static int
ConfigureImage(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Image item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    Tk_Window tkwin;
    Tk_Image image;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, imgPtr, flags)) {
	return TCL_ERROR;
    }

    /*
     * Create the image. Save the old image around and don't free it until
     * after the new one is allocated. This keeps the reference count from
     * going to zero so the image doesn't have to be recreated if it hasn't
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteImage(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    (void)canvas;
    (void)display;

    if (imgPtr->imageString != NULL) {
	ckfree(imgPtr->imageString);
    }
    if (imgPtr->activeImageString != NULL) {
	ckfree(imgPtr->activeImageString);
    }







|

|


<
<







376
377
378
379
380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteImage(
    TCL_UNUSED(Tk_Canvas),	/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    TCL_UNUSED(Display *))	/* Display containing window for canvas. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;



    if (imgPtr->imageString != NULL) {
	ckfree(imgPtr->imageString);
    }
    if (imgPtr->activeImageString != NULL) {
	ckfree(imgPtr->activeImageString);
    }
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
	y -= height;
	break;
    case TK_ANCHOR_W:
	y -= height/2;
	break;
    case TK_ANCHOR_NW:
	break;
    case TK_ANCHOR_CENTER:
	x -= width/2;
	y -= height/2;
	break;
    }

    /*
     * Store the information in the item header.







|







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
	y -= height;
	break;
    case TK_ANCHOR_W:
	y -= height/2;
	break;
    case TK_ANCHOR_NW:
	break;
    default:
	x -= width/2;
	y -= height/2;
	break;
    }

    /*
     * Store the information in the item header.
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
 *	None.
 *
 *--------------------------------------------------------------
 */

static double
ImageToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;
    (void)canvas;

    x1 = imgPtr->header.x1;
    y1 = imgPtr->header.y1;
    x2 = imgPtr->header.x2;
    y2 = imgPtr->header.y2;

    /*







|





<







585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
 *	None.
 *
 *--------------------------------------------------------------
 */

static double
ImageToPoint(
    TCL_UNUSED(Tk_Canvas),	/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;


    x1 = imgPtr->header.x1;
    y1 = imgPtr->header.y1;
    x2 = imgPtr->header.x2;
    y2 = imgPtr->header.y2;

    /*
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImageToArea(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    (void)canvas;

    if ((rectPtr[2] <= imgPtr->header.x1)
	    || (rectPtr[0] >= imgPtr->header.x2)
	    || (rectPtr[3] <= imgPtr->header.y1)
	    || (rectPtr[1] >= imgPtr->header.y2)) {
	return -1;
    }







|






<







641
642
643
644
645
646
647
648
649
650
651
652
653
654

655
656
657
658
659
660
661
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImageToArea(
    TCL_UNUSED(Tk_Canvas),	/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;


    if ((rectPtr[2] <= imgPtr->header.x1)
	    || (rectPtr[0] >= imgPtr->header.x2)
	    || (rectPtr[3] <= imgPtr->header.y1)
	    || (rectPtr[1] >= imgPtr->header.y2)) {
	return -1;
    }
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
    case TK_ANCHOR_N:	   x -= width/2.0; y -= height;		break;
    case TK_ANCHOR_NE:	   x -= width;	   y -= height;		break;
    case TK_ANCHOR_E:	   x -= width;	   y -= height/2.0;	break;
    case TK_ANCHOR_SE:	   x -= width;				break;
    case TK_ANCHOR_S:	   x -= width/2.0;			break;
    case TK_ANCHOR_SW:						break;
    case TK_ANCHOR_W:			   y -= height/2.0;	break;
    case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0;	break;
    }

    if (!prepass) {
	Tcl_Obj *psObj = Tcl_GetObjResult(interp);

	if (Tcl_IsShared(psObj)) {
	    psObj = Tcl_DuplicateObj(psObj);







|







739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
    case TK_ANCHOR_N:	   x -= width/2.0; y -= height;		break;
    case TK_ANCHOR_NE:	   x -= width;	   y -= height;		break;
    case TK_ANCHOR_E:	   x -= width;	   y -= height/2.0;	break;
    case TK_ANCHOR_SE:	   x -= width;				break;
    case TK_ANCHOR_S:	   x -= width/2.0;			break;
    case TK_ANCHOR_SW:						break;
    case TK_ANCHOR_W:			   y -= height/2.0;	break;
    default: x -= width/2.0; y -= height/2.0;	break;
    }

    if (!prepass) {
	Tcl_Obj *psObj = Tcl_GetObjResult(interp);

	if (Tcl_IsShared(psObj)) {
	    psObj = Tcl_DuplicateObj(psObj);
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
 *	Arranges for the canvas to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ImageChangedProc(
    ClientData clientData,	/* Pointer to canvas item for image. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    ImageItem *imgPtr = (ImageItem *)clientData;







|







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
 *	Arranges for the canvas to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
ImageChangedProc(
    void *clientData,	/* Pointer to canvas item for image. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    ImageItem *imgPtr = (ImageItem *)clientData;

Changes to generic/tkCanvLine.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16




17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * tkCanvLine.c --
 *
 *	This file implements line items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"





/*
 * The structure below defines the record for each line item.
 */

typedef enum {
    ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
} Arrows;

typedef struct LineItem {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_Outline outline;		/* Outline structure */
    Tk_Canvas canvas;		/* Canvas containing item. Needed for parsing
				 * arrow shapes. */
    int numPoints;		/* Number of points in line (always >= 0). */
    double *coordPtr;		/* Pointer to malloc-ed array containing x-
				 * and y-coords of all points in line.
				 * X-coords are even-valued indices, y-coords
				 * are corresponding odd-valued indices. If
				 * the line has arrowheads then the first and
				 * last points have been adjusted to refer to
				 * the necks of the arrowheads rather than





|
|
|








>
>
>
>















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * tkCanvLine.c --
 *
 *	This file implements line items for canvas widgets.
 *
 * 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"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The structure below defines the record for each line item.
 */

typedef enum {
    ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
} Arrows;

typedef struct LineItem {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_Outline outline;		/* Outline structure */
    Tk_Canvas canvas;		/* Canvas containing item. Needed for parsing
				 * arrow shapes. */
    Tcl_Size numPoints;		/* Number of points in line (always >= 0). */
    double *coordPtr;		/* Pointer to malloc-ed array containing x-
				 * and y-coords of all points in line.
				 * X-coords are even-valued indices, y-coords
				 * are corresponding odd-valued indices. If
				 * the line has arrowheads then the first and
				 * last points have been adjusted to refer to
				 * the necks of the arrowheads rather than
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
 */

static int		ArrowheadPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, LineItem *linePtr,
			    double *arrowPtr, Tcl_Obj *psObj);
static void		ComputeLineBbox(Tk_Canvas canvas, LineItem *linePtr);
static int		ConfigureLine(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		ConfigureArrows(Tk_Canvas canvas, LineItem *linePtr);
static int		CreateLine(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetLineIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static int		LineCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		LineDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		LineInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
static int		LineToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		LineToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		LineToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static int		ArrowParseProc(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, TkSizeT offset);
static const char * ArrowPrintProc(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tcl_FreeProc **freeProcPtr);
static int		ParseArrowShape(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, TkSizeT offset);
static const char * PrintArrowShape(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tcl_FreeProc **freeProcPtr);
static void		RotateLine(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateLine(Tk_Canvas canvas,







|




|







|


|

|

|






|

|
|
|

|

|
|
|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 */

static int		ArrowheadPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, LineItem *linePtr,
			    double *arrowPtr, Tcl_Obj *psObj);
static void		ComputeLineBbox(Tk_Canvas canvas, LineItem *linePtr);
static int		ConfigureLine(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static int		ConfigureArrows(Tk_Canvas canvas, LineItem *linePtr);
static int		CreateLine(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetLineIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, Tcl_Size *indexPtr);
static int		LineCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		LineDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size first, Tcl_Size last);
static void		LineInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size beforeThis, Tcl_Obj *obj);
static int		LineToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		LineToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		LineToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static int		ArrowParseProc(void *clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, Tcl_Size offset);
static const char * ArrowPrintProc(void *clientData,
			    Tk_Window tkwin, char *recordPtr, Tcl_Size offset,
			    Tcl_FreeProc **freeProcPtr);
static int		ParseArrowShape(void *clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, Tcl_Size offset);
static const char * PrintArrowShape(void *clientData,
			    Tk_Window tkwin, char *recordPtr, Tcl_Size offset,
			    Tcl_FreeProc **freeProcPtr);
static void		RotateLine(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateLine(Tk_Canvas canvas,
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)







|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    sizeof(LineItem),			/* itemSize */
    CreateLine,				/* createProc */
    configSpecs,			/* configSpecs */
    ConfigureLine,			/* configureProc */
    LineCoords,				/* coordProc */
    DeleteLine,				/* deleteProc */
    DisplayLine,			/* displayProc */
    TK_CONFIG_OBJS | TK_MOVABLE_POINTS,	/* flags */
    LineToPoint,			/* pointProc */
    LineToArea,				/* areaProc */
    LineToPostscript,			/* postscriptProc */
    ScaleLine,				/* scaleProc */
    TranslateLine,			/* translateProc */
    GetLineIndex,			/* indexProc */
    NULL,				/* icursorProc */







|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    sizeof(LineItem),			/* itemSize */
    CreateLine,				/* createProc */
    configSpecs,			/* configSpecs */
    ConfigureLine,			/* configureProc */
    LineCoords,				/* coordProc */
    DeleteLine,				/* deleteProc */
    DisplayLine,			/* displayProc */
    TK_MOVABLE_POINTS,		/* flags */
    LineToPoint,			/* pointProc */
    LineToArea,				/* areaProc */
    LineToPostscript,			/* postscriptProc */
    ScaleLine,				/* scaleProc */
    TranslateLine,			/* translateProc */
    GetLineIndex,			/* indexProc */
    NULL,				/* icursorProc */
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

static int
CreateLine(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing line. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed to set defaults and to allow







|



|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

static int
CreateLine(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing line. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed to set defaults and to allow
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

static int
LineCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int i, numPoints;
    double *coordPtr;

    if (objc == 0) {
	int numCoords;
	Tcl_Obj *subobj, *obj = Tcl_NewObj();

	numCoords = 2*linePtr->numPoints;
	if (linePtr->firstArrowPtr != NULL) {
	    coordPtr = linePtr->firstArrowPtr;
	} else {
	    coordPtr = linePtr->coordPtr;







|



|



|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

static int
LineCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    Tcl_Size i, numPoints;
    double *coordPtr;

    if (objc == 0) {
	Tcl_Size numCoords;
	Tcl_Obj *subobj, *obj = Tcl_NewObj();

	numCoords = 2*linePtr->numPoints;
	if (linePtr->firstArrowPtr != NULL) {
	    coordPtr = linePtr->firstArrowPtr;
	} else {
	    coordPtr = linePtr->coordPtr;
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %d",
		objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL);
	return TCL_ERROR;
    } else if (objc < 4) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected at least 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL);
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (linePtr->numPoints != numPoints) {
	coordPtr = (double *)ckalloc(sizeof(double) * objc);







|





|







396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %" TCL_SIZE_MODIFIER "d",
		objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL);
	return TCL_ERROR;
    } else if (objc < 4) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected at least 4, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL);
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (linePtr->numPoints != numPoints) {
	coordPtr = (double *)ckalloc(sizeof(double) * objc);
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
 */

static int
ConfigureLine(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Line item to reconfigure. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    XGCValues gcValues;
    GC newGC, arrowGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) linePtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */







|












|







468
469
470
471
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
ConfigureLine(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Line item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    XGCValues gcValues;
    GC newGC, arrowGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, linePtr, flags)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659

static void
ComputeLineBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    LineItem *linePtr)		/* Item whose bbos is to be recomputed. */
{
    double *coordPtr;

    int i, intWidth;
    double width;
    Tk_State state = linePtr->header.state;
    Tk_TSOffset *tsoffset;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }







>
|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

static void
ComputeLineBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    LineItem *linePtr)		/* Item whose bbos is to be recomputed. */
{
    double *coordPtr;
    Tcl_Size i;
    int intWidth;
    double width;
    Tk_State state = linePtr->header.state;
    Tk_TSOffset *tsoffset;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
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
 *--------------------------------------------------------------
 */

static void
LineInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    TkSizeT beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int length, objc, i;
    double *newCoordPtr, *coordPtr;
    Tk_State state = itemPtr->state;
    Tcl_Obj **objv;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }

    length = 2*linePtr->numPoints;

    if (beforeThis == TCL_INDEX_NONE) {
	beforeThis = 0;
    }
    if (beforeThis + 1 > (TkSizeT)length + 1) {
	beforeThis = length;
    }






    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + objc));
    for (i=0; i<(int)beforeThis; i++) {
	newCoordPtr[i] = linePtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i + beforeThis]) != TCL_OK) {
	    Tcl_ResetResult(Canvas(canvas)->interp);
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = linePtr->coordPtr[i];
    }
    if (linePtr->coordPtr) {
        ckfree(linePtr->coordPtr);
    }
    linePtr->coordPtr = newCoordPtr;
    length += objc ;
    linePtr->numPoints = length / 2;

    if ((length > 3) && (state != TK_STATE_HIDDEN)) {
	/*
	 * This is some optimizing code that will result that only the part of
	 * the polygon that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.


	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;

	if ((int)beforeThis > 0) {

	    beforeThis -= 2;
	    objc += 2;

	}
	if ((int)beforeThis+objc < length) {
	    objc += 2;
	}
	if (linePtr->smooth) {





	    if ((int)beforeThis > 0) {
		beforeThis -= 2;








		objc += 2;
	    }

	    if ((int)beforeThis+objc+2 < length) {
		objc += 2;
	    }
	}


































	itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
	itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
	if ((linePtr->firstArrowPtr != NULL) && ((int)beforeThis < 1)) {
	    /*
	     * Include old first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc >= length)) {
	    /*
	     * Include old last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	coordPtr = linePtr->coordPtr + beforeThis + 2;
	for (i=2; i<objc; i+=2) {
	    TkIncludePoint(itemPtr, coordPtr);
	    coordPtr += 2;
	}
    }


    if (linePtr->firstArrowPtr != NULL) {
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }

    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && ((int)beforeThis > 2)) {
	    /*
	     * Include new first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc < length-2)) {
	    /*
	     * Include new right arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}







|




|












>

>
|


|


>
>
>
>
>
>









|











|












|




>
>




<
>
|
|
>
|
|
|
|

>
>
>
>
>
|

>
>
>
>
>
>
>
>
|
|
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
>
>
















|









|

|







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
 *--------------------------------------------------------------
 */

static void
LineInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    Tcl_Size beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    Tcl_Size length, oriNumPoints, objc, nbInsPoints, i;
    double *newCoordPtr, *coordPtr;
    Tk_State state = itemPtr->state;
    Tcl_Obj **objv;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    oriNumPoints = linePtr->numPoints;
    length = 2*linePtr->numPoints;
    nbInsPoints = objc / 2;
    if (beforeThis < 0) {
	beforeThis = 0;
    }
    if (beforeThis > length) {
	beforeThis = length;
    }

    /*
     * With arrows, the end points of the line are adjusted so that a thick
     * line doesn't stick out past the arrowheads (see ConfigureArrows).
     */

    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + objc));
    for (i=0; i<beforeThis; i++) {
	newCoordPtr[i] = linePtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i + beforeThis]) != TCL_OK) {
	    Tcl_ResetResult(Canvas(canvas)->interp);
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=(int)beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = linePtr->coordPtr[i];
    }
    if (linePtr->coordPtr) {
        ckfree(linePtr->coordPtr);
    }
    linePtr->coordPtr = newCoordPtr;
    length += objc ;
    linePtr->numPoints = length / 2;

    if ((length > 3) && (state != TK_STATE_HIDDEN)) {
	/*
	 * This is some optimizing code that will result that only the part of
	 * the line that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;


	/*
	 * Include one point at left of the left insert position, and one
	 * point at right of the right insert position.
	 */

	beforeThis -= 2;
	objc += 4;

	if (linePtr->smooth) {
	    if (!strcmp(linePtr->smooth->name, "true")) {
		/*
		 * Quadratic Bezier splines. A second point must be included at
		 * each side of the insert position.
		 */

		beforeThis -= 2;
		objc += 4;

		/*
		 * Moreover, if the insert position is the first or last point
		 * of the line, include a third point.
		 */

		if (beforeThis == (Tcl_Size)-4) {
		    objc += 2;
		}
		if (beforeThis + 4 == length - (objc - 8)) {
		    beforeThis -= 2;
		    objc += 2;
		}

	    } else if (!strcmp(linePtr->smooth->name, "raw")) {
		/*
		 * Cubic Bezier splines. See details in ticket [5fb8145997].
		 */

		if (((oriNumPoints - 1) % 3) || (nbInsPoints % 3)) {
		    /*
		     * No optimization for "degenerate" lines or when inserting
		     * something else than a multiple of 3 points.
		     */

		    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
		} else {
		    beforeThis -= (int)beforeThis % 6;
		    objc += 4;
		}

	    } else {
		/*
		 * Custom smoothing method. No optimization is possible.
		 */

		itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    }
	}

	if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	    if ((int)beforeThis < 0) {
		beforeThis = 0;
	    }
	    if ((int)beforeThis + objc > length) {
		objc = length - (int)beforeThis;
	    }

	    itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
	    itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
	    if ((linePtr->firstArrowPtr != NULL) && ((int)beforeThis < 2)) {
		/*
		 * Include old first arrow.
		 */

		for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
			i++, coordPtr += 2) {
		    TkIncludePoint(itemPtr, coordPtr);
		}
	    }
	    if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc >= length)) {
		/*
		 * Include old last arrow.
		 */

		for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
			i++, coordPtr += 2) {
		    TkIncludePoint(itemPtr, coordPtr);
		}
	    }
	    coordPtr = linePtr->coordPtr + beforeThis;
	    for (i=0; i<objc; i+=2) {
		TkIncludePoint(itemPtr, coordPtr);
		coordPtr += 2;
	    }
	}
    }

    if (linePtr->firstArrowPtr != NULL) {
	ckfree(linePtr->firstArrowPtr);
	linePtr->firstArrowPtr = NULL;
    }
    if (linePtr->lastArrowPtr != NULL) {
	ckfree(linePtr->lastArrowPtr);
	linePtr->lastArrowPtr = NULL;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }

    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && ((int)beforeThis < 2)) {
	    /*
	     * Include new first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc >= length)) {
	    /*
	     * Include new last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156


1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176






1177
1178
1179
1180
1181
1182
1183
1184
1185
1186

1187





1188

1189

1190







1191
1192




1193
1194



1195
1196
1197















1198
1199
1200




1201











1202
1203
1204
1205
1206
1207
1208
1209


1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
 *--------------------------------------------------------------
 */

static void
LineDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Index of first character to delete. */
    TkSizeT last)			/* Index of last character to delete. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int count, i, first1, last1;


    int length = 2*linePtr->numPoints;
    double *coordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    first &= -2;
    last &= -2;

    if ((int)first < 0) {
	first = 0;
    }
    if ((int)last >= length) {
	last = length-2;
    }
    if ((int)first > (int)last) {
	return;
    }






    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    first1 = first;
    last1 = last;

    if (first1 > 0) {





	first1 -= 2;

    }

    if (last1 < length-2) {







	last1 += 2;
    }




    if (linePtr->smooth) {
	if (first1 > 0) {



	    first1 -= 2;
	}
	if (last1 < length-2) {















	    last1 += 2;
	}
    }
















    if ((first1 >= 2) || (last1 < length-2)) {
	/*
	 * This is some optimizing code that will result that only the part of
	 * the line that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is set, the redrawing has to be done here, otherwise the
	 * general Canvas code will take care of it.


	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
	itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1];
	itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1];
	if ((linePtr->firstArrowPtr != NULL) && (first1 < 2)) {
	    /*
	     * Include old first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && (last1 >= length-2)) {
	    /*
	     * Include old last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);







|
|


|
>
>








|






|




>
>
>
>
>
>










>
|
>
>
>
>
>
|
>
|
>
|
>
>
>
>
>
>
>
|
|
>
>
>
>
|
|
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
|







>
>















|







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
 *--------------------------------------------------------------
 */

static void
LineDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    Tcl_Size first,			/* Index of first character to delete. */
    Tcl_Size last)			/* Index of last character to delete. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int count, i, first1, last1, nbDelPoints;
    int oriNumPoints = linePtr->numPoints;
    int canOptimize = 1;
    int length = 2*linePtr->numPoints;
    double *coordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    first &= -2;	/* If odd, make it even. */
    last &= -2;

    if ((int)first < 0) {
	first = 0;
    }
    if ((int)last >= length) {
	last = length - 2;
    }
    if ((int)first > (int)last) {
	return;
    }

    /*
     * With arrows, the end points of the line are adjusted so that a thick
     * line doesn't stick out past the arrowheads (see ConfigureArrows).
     */

    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    first1 = first;
    last1 = last;
    nbDelPoints = (last - first) / 2 + 1;

    /*
     * Include one point at left of the left delete position, and one
     * point at right of the right delete position.
     */

    first1 -= 2;
    last1 += 2;

    if (linePtr->smooth) {

	if (!strcmp(linePtr->smooth->name, "true")) {
	    /*
	     * Quadratic Bezier splines. A second point must be included at
	     * each side of the delete position.
	     */

	    first1 -= 2;
	    last1 += 2;

	    /*
	     * If the delete position is the first or last point of the line,
	     * include a third point.
	     */

	    if (first1 == -4) {
		last1 += 2;
	    }
	    if (last1 - 4 == length - 2) {
		first1 -= 2;
	    }

	} else if (!strcmp(linePtr->smooth->name, "raw")) {
	    /*
	     * Cubic Bezier splines. See details in ticket [5fb8145997].
	     */

	    if (((oriNumPoints - 1) % 3) || (nbDelPoints % 3)) {
		/*
		 * No optimization for "degenerate" lines or when deleting
		 * something else than a multiple of 3 points.
		 */

		canOptimize = 0;
	    }
	    else {
		first1 -= first1 % 6;
		last1 = last + 6 - last % 6;
	    }

	} else {
	    /*
	     * Custom smoothing method. No optimization is possible.
	     */

	    canOptimize = 0;
	}
    }

    if (first1 < 0) {
	first1 = 0;
    }
    if (last1 >= length) {
	last1 = length - 2;
    }

    if (canOptimize && ((first1 >= 2) || (last1 < length-2))) {
	/*
	 * This is some optimizing code that will result that only the part of
	 * the line that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is set, the redrawing has to be done here, otherwise the
	 * general Canvas code will take care of it.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
	itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1];
	itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1];
	if ((linePtr->firstArrowPtr != NULL) && (first1 < 2)) {
	    /*
	     * Include old first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && (last1 >= length - 2)) {
	    /*
	     * Include old last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && (first1 < 4)) {
	    /*
	     * Include new first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && (last1 > length-4)) {
	    /*
	     * Include new right arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}







|









|

|







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
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && (first1 < 2)) {
	    /*
	     * Include new first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && (last1 >= length - 2)) {
	    /*
	     * Include new last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
    double originX, double originY,
				/* Origin about which to scale rect. */
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;

    /*
     * Delete any arrowheads before scaling all the points (so that the
     * end-points of the line get restored).
     */

    if (linePtr->firstArrowPtr != NULL) {







|







1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
    double originX, double originY,
				/* Origin about which to scale rect. */
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    Tcl_Size i;

    /*
     * Delete any arrowheads before scaling all the points (so that the
     * end-points of the line get restored).
     */

    if (linePtr->firstArrowPtr != NULL) {
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
 *
 *--------------------------------------------------------------
 */

static int
GetLineIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    TkSizeT idx, length;
    LineItem *linePtr = (LineItem *) itemPtr;
    const char *string;
    (void)canvas;

    if (TCL_OK == TkGetIntForIndex(obj, 2*linePtr->numPoints - 1, 0, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > (2*(TkSizeT)linePtr->numPoints)) {
	    idx = 2*linePtr->numPoints;
	} else {
	    idx &= (TkSizeT)-2;	/* If index is odd, make it even. */
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}

	p = end+1;





	y = strtod(p, &end);

	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = linePtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<linePtr->numPoints; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {

	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */

    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "LINE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|




|

|

|
<

|
|

|


|





|


|

|
|


|
|


>
|
>
>
>
>
>
|
>
|














<
<
<
<
<
<







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
 *
 *--------------------------------------------------------------
 */

static int
GetLineIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    Tcl_Size *indexPtr)		/* Where to store converted index. */
{
    Tcl_Size idx, length;
    LineItem *linePtr = (LineItem *) itemPtr;
    char *string;


    if (TCL_OK == TkGetIntForIndex(obj, 2*linePtr->numPoints - 1, 1, &idx)) {
	if (idx < 0) {
	    idx = 0;
	} else if (idx > (2*(Tcl_Size)linePtr->numPoints)) {
	    idx = 2*linePtr->numPoints;
	} else {
	    idx &= (Tcl_Size)-2;	/* If index is odd, make it even. */
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = Tcl_GetStringFromObj(obj, &length);

    if (string[0] == '@') {
	Tcl_Size i;
	double x, y, bestDist, dist, *coordPtr;
	char savechar;
	char *p, *sep;

	p = string+1;
	sep = strchr(p, ',');
	if (!sep) {
	    goto badIndex;
	}
	savechar = *sep;
	*sep = '\0';
	i = Tcl_GetDouble(NULL, p, &x);
	*sep = savechar;
	if (i != TCL_OK) {
	    goto badIndex;
	}
	p = sep+1;
	i = Tcl_GetDouble(NULL, p, &y);
	if (i != TCL_OK) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = linePtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<linePtr->numPoints; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {






    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "LINE", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double deltaX, double deltaY)
				/* Amount by which item is to be moved. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	coordPtr[0] += deltaX;
	coordPtr[1] += deltaY;
    }
    if (linePtr->firstArrowPtr != NULL) {







|







1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double deltaX, double deltaY)
				/* Amount by which item is to be moved. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    Tcl_Size i;

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	coordPtr[0] += deltaX;
	coordPtr[1] += deltaY;
    }
    if (linePtr->firstArrowPtr != NULL) {
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    if (linePtr->firstArrowPtr != NULL) {







|







2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    Tcl_Size i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    if (linePtr->firstArrowPtr != NULL) {
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
ParseArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Not used. */
    const char *value,		/* Textual specification of arrow shape. */
    char *recordPtr,		/* Pointer to item record in which to store
				 * arrow information. */
    TkSizeT offset)			/* Offset of shape information in widget
				 * record. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    double a, b, c;
    int argc;
    const char **argv = NULL;

    if ((size_t)offset != offsetof(LineItem, arrowShapeA)) {
	Tcl_Panic("ParseArrowShape received bogus offset");
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {







|




|







2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
ParseArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Not used. */
    const char *value,		/* Textual specification of arrow shape. */
    char *recordPtr,		/* Pointer to item record in which to store
				 * arrow information. */
    Tcl_Size offset)			/* Offset of shape information in widget
				 * record. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    double a, b, c;
    Tcl_Size argc;
    const char **argv = NULL;

    if ((size_t)offset != offsetof(LineItem, arrowShapeA)) {
	Tcl_Panic("ParseArrowShape received bogus offset");
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014

static const char *
PrintArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(Tk_Window),		/* Window associated with linePtr's widget. */
    char *recordPtr,		/* Pointer to item record containing current
				 * shape information. */
    TCL_UNUSED(TkSizeT),			/* Offset of arrow information in record. */
    Tcl_FreeProc **freeProcPtr)	/* Store address of function to call to free
				 * string here. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    char *buffer = (char *)ckalloc(120);

    sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA,
	    linePtr->arrowShapeB, linePtr->arrowShapeC);
    *freeProcPtr = TCL_DYNAMIC;
    return buffer;
}

/*
 *--------------------------------------------------------------







|






|







2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142

static const char *
PrintArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(Tk_Window),		/* Window associated with linePtr's widget. */
    char *recordPtr,		/* Pointer to item record containing current
				 * shape information. */
    TCL_UNUSED(Tcl_Size),			/* 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);

    snprintf(buffer, 120, "%.5g %.5g %.5g", linePtr->arrowShapeA,
	    linePtr->arrowShapeB, linePtr->arrowShapeC);
    *freeProcPtr = TCL_DYNAMIC;
    return buffer;
}

/*
 *--------------------------------------------------------------
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
static int
ArrowParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;







|







2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
static int
ArrowParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
 */

static const char *
ArrowPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    switch (*arrowPtr) {







|







2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
 */

static const char *
ArrowPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    switch (*arrowPtr) {
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
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Check if we're just doing a "pixel".
     */

    if (linePtr->numPoints == 1) {
	Tcl_AppendToObj(psObj, "matrix currentmatrix\n", -1);
	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate %.15g %.15g",
		linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]),
		width/2.0, width/2.0);
	Tcl_AppendToObj(psObj,
		" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", -1);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);
	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;
    }

    /*
     * Generate a path for the line's center-line (do this differently for
     * straight lines and smoothed lines).







|




|






|




|







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
    interpState = Tcl_SaveInterpState(interp, TCL_OK);

    /*
     * Check if we're just doing a "pixel".
     */

    if (linePtr->numPoints == 1) {
	Tcl_AppendToObj(psObj, "matrix currentmatrix\n", TCL_INDEX_NONE);
	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate %.15g %.15g",
		linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]),
		width/2.0, width/2.0);
	Tcl_AppendToObj(psObj,
		" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", TCL_INDEX_NONE);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);
	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
	}
	goto done;
    }

    /*
     * Generate a path for the line's center-line (do this differently for
     * straight lines and smoothed lines).
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467

    /*
     * Output polygons for the arrowheads, if there are any.
     */

    if (linePtr->firstArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr, psObj);
    }
    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj);
    }

    /*
     * Plug the accumulated postscript back into the result.







|






|







2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595

    /*
     * Output polygons for the arrowheads, if there are any.
     */

    if (linePtr->firstArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr, psObj);
    }
    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj);
    }

    /*
     * Plug the accumulated postscript back into the result.
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
    }

    Tcl_ResetResult(interp);
    Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_AppendToObj(psObj, "clip ", -1);

	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    } else {
	Tcl_AppendToObj(psObj, "fill\n", -1);
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|





|











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
    }

    Tcl_ResetResult(interp);
    Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);

	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    } else {
	Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvPoly.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkCanvPoly.c --
 *
 *	This file implements polygon items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 Ajuba Solutions.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"





|
|
|







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 © 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"
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)







|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Prototypes for functions defined in this file:
 */

static void		ComputePolygonBbox(Tk_Canvas canvas,
			    PolygonItem *polyPtr);
static int		ConfigurePolygon(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreatePolygon(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeletePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr,  Display *display);
static void		DisplayPolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetPolygonIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static int		PolygonCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		PolygonDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
static int		PolygonToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		PolygonToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		PolygonToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		RotatePolygon(Tk_Canvas canvas, Tk_Item *itemPtr,







|



|







|


|

|

|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Prototypes for functions defined in this file:
 */

static void		ComputePolygonBbox(Tk_Canvas canvas,
			    PolygonItem *polyPtr);
static int		ConfigurePolygon(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreatePolygon(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeletePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr,  Display *display);
static void		DisplayPolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetPolygonIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, Tcl_Size *indexPtr);
static int		PolygonCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		PolygonDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size first, Tcl_Size last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size beforeThis, Tcl_Obj *obj);
static int		PolygonToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		PolygonToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		PolygonToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		RotatePolygon(Tk_Canvas canvas, Tk_Item *itemPtr,
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    sizeof(PolygonItem),		/* itemSize */
    CreatePolygon,			/* createProc */
    configSpecs,			/* configSpecs */
    ConfigurePolygon,			/* configureProc */
    PolygonCoords,			/* coordProc */
    DeletePolygon,			/* deleteProc */
    DisplayPolygon,			/* displayProc */
    TK_CONFIG_OBJS | TK_MOVABLE_POINTS,	/* flags */
    PolygonToPoint,			/* pointProc */
    PolygonToArea,			/* areaProc */
    PolygonToPostscript,		/* postscriptProc */
    ScalePolygon,			/* scaleProc */
    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */







|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    sizeof(PolygonItem),		/* itemSize */
    CreatePolygon,			/* createProc */
    configSpecs,			/* configSpecs */
    ConfigurePolygon,			/* configureProc */
    PolygonCoords,			/* coordProc */
    DeletePolygon,			/* deleteProc */
    DisplayPolygon,			/* displayProc */
    TK_MOVABLE_POINTS,		/* flags */
    PolygonToPoint,			/* pointProc */
    PolygonToArea,			/* areaProc */
    PolygonToPostscript,		/* postscriptProc */
    ScalePolygon,			/* scaleProc */
    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

static int
CreatePolygon(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing polygon. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after







|



|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

static int
CreatePolygon(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing polygon. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
328
329
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346

static int
PolygonCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;

    int i, numPoints;

    if (objc == 0) {
	/*
	 * Print the coords used to create the polygon. If we auto closed the
	 * polygon then we don't report the last point.
	 */








|



>
|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

static int
PolygonCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int i;
    int numPoints;

    if (objc == 0) {
	/*
	 * Print the coords used to create the polygon. If we auto closed the
	 * polygon then we don't report the last point.
	 */

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %d",
		objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "POLYGON", NULL);
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (polyPtr->pointsAllocated <= numPoints) {







|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (objc & 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected an even number, got %" TCL_SIZE_MODIFIER "d",
		objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "POLYGON", NULL);
	return TCL_ERROR;
    }

    numPoints = objc/2;
    if (polyPtr->pointsAllocated <= numPoints) {
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 */

static int
ConfigurePolygon(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Polygon item to reconfigure. */
    int objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */







|














|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
 */

static int
ConfigurePolygon(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Polygon item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, polyPtr, flags)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036

1037

1038
1039
1040
1041
1042
1043
1044
 *--------------------------------------------------------------
 */

static void
PolygonInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    TkSizeT beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length, objc, i;

    Tcl_Obj **objv;
    double *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }

    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while ((int)beforeThis > length) {
	beforeThis -= length;
    }
    while ((int)beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + 2 + objc));







|




|
>












>

>







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
 *--------------------------------------------------------------
 */

static void
PolygonInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    Tcl_Size beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length, oriNumPoints, nbInsPoints, i;
    Tcl_Size objc;
    Tcl_Obj **objv;
    double *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    oriNumPoints = polyPtr->numPoints - polyPtr->autoClosed;
    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    nbInsPoints = objc / 2;
    while ((int)beforeThis > length) {
	beforeThis -= length;
    }
    while ((int)beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + 2 + objc));
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
	/*
	 * This is some optimizing code that will result that only the part of
	 * the polygon that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.


	 */

    	double width;
	int j;

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;

	/*
	 * The header elements that normally are used for the bounding box,
	 * are now used to calculate the bounding box for only the part that
	 * has to be redrawn. That doesn't matter, because afterwards the
	 * bounding box has to be re-calculated anyway.
	 */

	itemPtr->x1 = itemPtr->x2 = (int) polyPtr->coordPtr[beforeThis];
	itemPtr->y1 = itemPtr->y2 = (int) polyPtr->coordPtr[beforeThis+1];

	beforeThis -= 2;
	objc += 4;

	if (polyPtr->smooth) {





	    beforeThis -= 2;
	    objc += 4;
	}






	/*





















	 * Be careful; beforeThis could now be negative
	 */

	for (i=beforeThis; i<(int)beforeThis+objc; i+=2) {
	    j = i;
	    if (j < 0) {
		j += length;
	    } else if (j >= length) {
		j -= length;
	    }
	    TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
	}
	width = polyPtr->outline.width;
	if (Canvas(canvas)->currentItemPtr == itemPtr) {
	    if (polyPtr->outline.activeWidth > width) {
		width = polyPtr->outline.activeWidth;
	    }
	} else if (state == TK_STATE_DISABLED) {
	    if (polyPtr->outline.disabledWidth > 0.0) {
		width = polyPtr->outline.disabledWidth;
	    }
	}
	itemPtr->x1 -= (int) width;
	itemPtr->y1 -= (int) width;
	itemPtr->x2 += (int) width;
	itemPtr->y2 += (int) width;
	Tk_CanvasEventuallyRedraw(canvas,
		itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2);

    }

    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------







>
>
















>


>

>
>
>
>
>
|
|
|
>
>
>
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







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
	/*
	 * This is some optimizing code that will result that only the part of
	 * the polygon that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

    	double width;
	int j;

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;

	/*
	 * The header elements that normally are used for the bounding box,
	 * are now used to calculate the bounding box for only the part that
	 * has to be redrawn. That doesn't matter, because afterwards the
	 * bounding box has to be re-calculated anyway.
	 */

	itemPtr->x1 = itemPtr->x2 = (int) polyPtr->coordPtr[beforeThis];
	itemPtr->y1 = itemPtr->y2 = (int) polyPtr->coordPtr[beforeThis+1];

	beforeThis -= 2;
	objc += 4;

	if (polyPtr->smooth) {
	    if (!strcmp(polyPtr->smooth->name, "true")) {
		/*
		 * Quadratic Bezier splines.
		 */

		beforeThis -= 2;
		objc += 4;

	    } else if (!strcmp(polyPtr->smooth->name, "raw")) {
		/*
		 * Cubic Bezier splines.
		 */

		if ((oriNumPoints % 3) || (nbInsPoints % 3)) {
		    /*
		     * No optimization for "degenerate" polygons or when inserting
		     * something else than a multiple of 3 points.
		     */

		    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
		} else {
		    beforeThis -= abs((int)beforeThis) % 6;
		    objc += 4;
		}

	    } else {
		/*
		 * Custom smoothing method. No optimization is possible.
		 */

		itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    }
	}

	if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	    /*
	     * Be careful; beforeThis could now be negative
	     */

	    for (i=(int)beforeThis; i<(int)beforeThis+objc; i+=2) {
		j = i;
		if (j < 0) {
		    j += length;
		} else if (j >= length) {
		    j -= length;
		}
		TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
	    }
	    width = polyPtr->outline.width;
	    if (Canvas(canvas)->currentItemPtr == itemPtr) {
		if (polyPtr->outline.activeWidth > width) {
		    width = polyPtr->outline.activeWidth;
		}
	    } else if (state == TK_STATE_DISABLED) {
		if (polyPtr->outline.disabledWidth > 0.0) {
		    width = polyPtr->outline.disabledWidth;
		}
	    }
	    itemPtr->x1 -= (int) width;
	    itemPtr->y1 -= (int) width;
	    itemPtr->x2 += (int) width;
	    itemPtr->y2 += (int) width;
	    Tk_CanvasEventuallyRedraw(canvas,
		    itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2);
	}
    }

    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
 *--------------------------------------------------------------
 */

static void
PolygonDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Index of first character to delete. */
    TkSizeT last)			/* Index of last character to delete. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int count, i;
    int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while ((int)first >= length) {
	first -= length;







|
|







1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
 *--------------------------------------------------------------
 */

static void
PolygonDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    Tcl_Size first,			/* Index of first character to delete. */
    Tcl_Size last)			/* Index of last character to delete. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int count, i;
    int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while ((int)first >= length) {
	first -= length;
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
GetPolygonIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    TkSizeT length, idx;
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    const char *string;
    TkSizeT count = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    if (TCL_OK == TkGetIntForIndex(obj,  (INT_MAX - 1) - ((INT_MAX) % count), 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;


	} else {
	    idx = (idx & (TkSizeT)-2) % count;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);


	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}
	p = end+1;
	y = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = polyPtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<polyPtr->numPoints-1; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */

    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|

|


|


|

>
>

|





|




|



|
>
>
|


|
|
|














<
<
<
<
<







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
GetPolygonIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    Tcl_Size *indexPtr)		/* Where to store converted index. */
{
    Tcl_Size length, idx;
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    const char *string;
    Tcl_Size count = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    if (TCL_OK == TkGetIntForIndex(obj,  (INT_MAX - 1) - ((INT_MAX) % count), 1, &idx)) {
	if (idx < 0) {
	    idx = 0;
	} else if (idx >= INT_MAX - ((INT_MAX) % count)) {
	    idx = count;
	} else {
	    idx = (idx & (Tcl_Size)-2) % count;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = Tcl_GetStringFromObj(obj, &length);

    if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *rest;
	const char *p;

	p = string+1;
	rest = strchr((char *)p, ',');
	*rest = '\0';
	if (Tcl_GetDouble(NULL, p, &x) != TCL_OK) {
	    *rest = ',';
	    goto badIndex;
	}
	*rest = ',';
	p = rest+1;
	if (Tcl_GetDouble(NULL, p, &y) != TCL_OK) {
	    goto badIndex;
	}
	bestDist = 1.0e36;
	coordPtr = polyPtr->coordPtr;
	*indexPtr = 0;
	for (i=0; i<polyPtr->numPoints-1; i++) {
	    dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {





    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
	 */

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;
    }

    /*
     * Fill the area of the polygon.
     */







|





|







1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
	 */

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
	}
	goto done;
    }

    /*
     * Fill the area of the polygon.
     */
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
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "eoclip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "eofill\n", -1);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */








|






|


|







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
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "eoclip ", TCL_INDEX_NONE);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "eofill\n", TCL_INDEX_NONE);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

Changes to generic/tkCanvPs.c.

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.
 *
 * 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"







|
|







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 © 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"
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
			    int startX, int startY, int width, int height,
			    Tcl_Obj *psObj);
static inline Tcl_Obj *	GetPostscriptBuffer(Tcl_Interp *interp);

/*
 *--------------------------------------------------------------
 *
 * TkCanvPostscriptCmd --
 *
 *	This function is invoked to process the "postscript" options of the
 *	widget command for canvas widgets. See the user documentation for
 *	details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkCanvPostscriptCmd(
    TkCanvas *canvasPtr,	/* Information about canvas widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char **argv)		/* Argument strings. Caller has already parsed
				 * this command enough to know that argv[1] is
				 * "postscript". */
{
    TkPostscriptInfo psInfo, *psInfoPtr = &psInfo;
    Tk_PostscriptInfo oldInfoPtr;
    int result;
    Tk_Item *itemPtr;
#define STRING_LENGTH 400







|















|


|
|
|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
			    int startX, int startY, int width, int height,
			    Tcl_Obj *psObj);
static inline Tcl_Obj *	GetPostscriptBuffer(Tcl_Interp *interp);

/*
 *--------------------------------------------------------------
 *
 * TkCanvPostscriptObjCmd --
 *
 *	This function is invoked to process the "postscript" options of the
 *	widget command for canvas widgets. See the user documentation for
 *	details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkCanvPostscriptObjCmd(
    TkCanvas *canvasPtr,	/* Information about canvas widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
	Tcl_Obj *const objv[])		/* Argument strings. Caller has already parsed
				 * this command enough to know that objv[1] is
				 * "postscript". */
{
    TkPostscriptInfo psInfo, *psInfoPtr = &psInfo;
    Tk_PostscriptInfo oldInfoPtr;
    int result;
    Tk_Item *itemPtr;
#define STRING_LENGTH 400
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

    /*
     * Get the generic preamble. We only ever bother with the ASCII encoding;
     * the others just make life too complicated and never actually worked as
     * such.
     */

    result = Tcl_EvalEx(interp, "::tk::ensure_psenc_is_loaded", -1, TCL_EVAL_GLOBAL);
    if (result != TCL_OK) {
	return result;
    }
    preambleObj = Tcl_GetVar2Ex(interp, "::tk::ps_preamble", NULL,
	    TCL_LEAVE_ERR_MSG);
    if (preambleObj == NULL) {
	return TCL_ERROR;







|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

    /*
     * Get the generic preamble. We only ever bother with the ASCII encoding;
     * the others just make life too complicated and never actually worked as
     * such.
     */

    result = Tcl_EvalEx(interp, "::tk::ensure_psenc_is_loaded", TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    if (result != TCL_OK) {
	return result;
    }
    preambleObj = Tcl_GetVar2Ex(interp, "::tk::ps_preamble", NULL,
	    TCL_LEAVE_ERR_MSG);
    if (preambleObj == NULL) {
	return TCL_ERROR;
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    psInfo.fileName = NULL;
    psInfo.channelName = NULL;
    psInfo.chan = NULL;
    psInfo.prepass = 0;
    psInfo.prolog = 1;
    psInfo.tkwin = tkwin;
    Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS);
    result = Tk_ConfigureWidget(interp, tkwin, configSpecs, argc-2, argv+2,
	    (char *) &psInfo, TK_CONFIG_ARGV_ONLY);
    if (result != TCL_OK) {
	goto cleanup;
    }

    if (psInfo.width == -1) {
	psInfo.width = Tk_Width(tkwin);
    }







|
|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    psInfo.fileName = NULL;
    psInfo.channelName = NULL;
    psInfo.chan = NULL;
    psInfo.prepass = 0;
    psInfo.prolog = 1;
    psInfo.tkwin = tkwin;
    Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS);
    result = Tk_ConfigureWidget(interp, tkwin, configSpecs, objc-2, objv+2,
	    &psInfo, TK_CONFIG_ARGV_ONLY);
    if (result != TCL_OK) {
	goto cleanup;
    }

    if (psInfo.width == -1) {
	psInfo.width = Tk_Width(tkwin);
    }
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314



315
316
317
318
319
320
321
    }
    switch (psInfo.pageAnchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_W:
    case TK_ANCHOR_SW:
	deltaX = 0;
	break;
    case TK_ANCHOR_N:
    case TK_ANCHOR_CENTER:
    case TK_ANCHOR_S:
	deltaX = -psInfo.width/2;
	break;
    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	deltaX = -psInfo.width;
	break;



    }
    switch (psInfo.pageAnchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_N:
    case TK_ANCHOR_NE:
	deltaY = - psInfo.height;
	break;
    case TK_ANCHOR_W:
    case TK_ANCHOR_CENTER:
    case TK_ANCHOR_E:
	deltaY = -psInfo.height/2;
	break;
    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:
	deltaY = 0;
	break;



    }

    if (psInfo.colorMode == NULL) {
	psInfo.colorLevel = 2;
    } else {
	length = strlen(psInfo.colorMode);
	if (strncmp(psInfo.colorMode, "monochrome", length) == 0) {







<
<
<
<
<





>
>
>







<
<
<
<
<





>
>
>







281
282
283
284
285
286
287





288
289
290
291
292
293
294
295
296
297
298
299
300
301
302





303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    }
    switch (psInfo.pageAnchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_W:
    case TK_ANCHOR_SW:
	deltaX = 0;
	break;





    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	deltaX = -psInfo.width;
	break;
    default:
	deltaX = -psInfo.width/2;
	break;
    }
    switch (psInfo.pageAnchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_N:
    case TK_ANCHOR_NE:
	deltaY = - psInfo.height;
	break;





    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:
	deltaY = 0;
	break;
    default:
	deltaY = -psInfo.height/2;
	break;
    }

    if (psInfo.colorMode == NULL) {
	psInfo.colorLevel = 2;
    } else {
	length = strlen(psInfo.colorMode);
	if (strncmp(psInfo.colorMode, "monochrome", length) == 0) {
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    if (psInfo.fileName != NULL) {
	/*
	 * Check that -file and -channel are not both specified.
	 */

	if (psInfo.channelName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify both -file and -channel", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "USAGE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}

	/*
	 * Check that we are not in a safe interpreter. If we are, disallow
	 * the -file specification.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify -file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PS_FILE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}

	p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer);
	if (p == NULL) {







|












|







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
    if (psInfo.fileName != NULL) {
	/*
	 * Check that -file and -channel are not both specified.
	 */

	if (psInfo.channelName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify both -file and -channel", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "USAGE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}

	/*
	 * Check that we are not in a safe interpreter. If we are, disallow
	 * the -file specification.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify -file in a safe interpreter", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PS_FILE", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}

	p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer);
	if (p == NULL) {
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
    /*
     * Generate the header and prolog for the Postscript.
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"%!PS-Adobe-3.0 EPSF-3.0\n"
		"%%Creator: Tk Canvas Widget\n", -1);

#ifdef HAVE_PW_GECOS
	if (!Tcl_IsSafe(interp)) {
	    struct passwd *pwPtr = getpwuid(getuid());	/* INTL: Native. */

	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%For: %s\n", (pwPtr ? pwPtr->pw_gecos : "Unknown"));







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    /*
     * Generate the header and prolog for the Postscript.
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"%!PS-Adobe-3.0 EPSF-3.0\n"
		"%%Creator: Tk Canvas Widget\n", TCL_INDEX_NONE);

#ifdef HAVE_PW_GECOS
	if (!Tcl_IsSafe(interp)) {
	    struct passwd *pwPtr = getpwuid(getuid());	/* INTL: Native. */

	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%For: %s\n", (pwPtr ? pwPtr->pw_gecos : "Unknown"));
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
	p = "%%%%DocumentNeededResources: font %s\n";
	for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendPrintfToObj(psObj, p,
		    Tcl_GetHashKey(&psInfo.fontTable, hPtr));
	    p = "%%%%+ font %s\n";
	}
	Tcl_AppendToObj(psObj, "%%EndComments\n\n", -1);

	/*
	 * Insert the prolog
	 */

	Tcl_AppendObjToObj(psObj, preambleObj);








|







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
	p = "%%%%DocumentNeededResources: font %s\n";
	for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendPrintfToObj(psObj, p,
		    Tcl_GetHashKey(&psInfo.fontTable, hPtr));
	    p = "%%%%+ font %s\n";
	}
	Tcl_AppendToObj(psObj, "%%EndComments\n\n", TCL_INDEX_NONE);

	/*
	 * Insert the prolog
	 */

	Tcl_AppendObjToObj(psObj, preambleObj);

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
		"%%%%BeginSetup\n/CL %d def\n", psInfo.colorLevel);
	for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%IncludeResource: font %s\n",
		    (char *) Tcl_GetHashKey(&psInfo.fontTable, hPtr));
	}
	Tcl_AppendToObj(psObj, "%%EndSetup\n\n", -1);

	/*
	 * Page setup: move to page positioning point, rotate if needed, set
	 * scale factor, offset for proper anchor position, and set clip
	 * region.
	 */

	Tcl_AppendToObj(psObj, "%%Page: 1 1\nsave\n", -1);
	Tcl_AppendPrintfToObj(psObj,
		"%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);
	if (psInfo.rotate) {
	    Tcl_AppendToObj(psObj, "90 rotate\n", -1);
	}
	Tcl_AppendPrintfToObj(psObj,
		"%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
	Tcl_AppendPrintfToObj(psObj,
		"%d %d translate\n", deltaX - psInfo.x, deltaY);
	Tcl_AppendPrintfToObj(psObj,
		"%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g "







|







|



|







506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
		"%%%%BeginSetup\n/CL %d def\n", psInfo.colorLevel);
	for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_AppendPrintfToObj(psObj,
		    "%%%%IncludeResource: font %s\n",
		    (char *) Tcl_GetHashKey(&psInfo.fontTable, hPtr));
	}
	Tcl_AppendToObj(psObj, "%%EndSetup\n\n", TCL_INDEX_NONE);

	/*
	 * Page setup: move to page positioning point, rotate if needed, set
	 * scale factor, offset for proper anchor position, and set clip
	 * region.
	 */

	Tcl_AppendToObj(psObj, "%%Page: 1 1\nsave\n", TCL_INDEX_NONE);
	Tcl_AppendPrintfToObj(psObj,
		"%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);
	if (psInfo.rotate) {
	    Tcl_AppendToObj(psObj, "90 rotate\n", TCL_INDEX_NONE);
	}
	Tcl_AppendPrintfToObj(psObj,
		"%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
	Tcl_AppendPrintfToObj(psObj,
		"%d %d translate\n", deltaX - psInfo.x, deltaY);
	Tcl_AppendPrintfToObj(psObj,
		"%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g "
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
	if (result != TCL_OK) {
	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (generating Postscript for item %d)",
		    (int)itemPtr->id));
	    goto cleanup;
	}

	Tcl_AppendToObj(psObj, "gsave\n", -1);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	Tcl_AppendToObj(psObj, "grestore\n", -1);
	Tcl_ResetResult(interp);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);







|

|







572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
	if (result != TCL_OK) {
	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (generating Postscript for item %d)",
		    (int)itemPtr->id));
	    goto cleanup;
	}

	Tcl_AppendToObj(psObj, "gsave\n", TCL_INDEX_NONE);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	Tcl_AppendToObj(psObj, "grestore\n", TCL_INDEX_NONE);
	Tcl_ResetResult(interp);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"restore showpage\n\n"
		"%%Trailer\n"
		"end\n"
		"%%EOF\n", -1);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	}
    }







|







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"restore showpage\n\n"
		"%%Trailer\n"
		"end\n"
		"%%EOF\n", TCL_INDEX_NONE);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	}
    }
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
     * there is an entry for this font, it consists of a list containing font
     * name and size. Use this information.
     */

    if (psInfoPtr->fontVar != NULL) {
	const char *name = Tk_NameOfFont(tkfont);
	Tcl_Obj **objv;
	int objc;
	double size;
	Tcl_Obj *list = Tcl_GetVar2Ex(interp, psInfoPtr->fontVar, name, 0);

	if (list != NULL) {
	    if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK
		    || objc != 2
		    || (fontname = Tcl_GetString(objv[0]))[0] == '\0'







|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
     * there is an entry for this font, it consists of a list containing font
     * name and size. Use this information.
     */

    if (psInfoPtr->fontVar != NULL) {
	const char *name = Tk_NameOfFont(tkfont);
	Tcl_Obj **objv;
	Tcl_Size objc;
	double size;
	Tcl_Obj *list = Tcl_GetVar2Ex(interp, psInfoPtr->fontVar, name, 0);

	if (list != NULL) {
	    if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK
		    || objc != 2
		    || (fontname = Tcl_GetString(objv[0]))[0] == '\0'
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

    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
    imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
	    totalWidth, totalHeight, 1, XYPixmap);









    Tcl_AppendToObj(psObj, "<", -1);




    mask = 0x80;
    value = 0;
    charsInLine = 0;
    lastX = startX + width - 1;
    lastY = startY + height - 1;
    for (y = lastY; y >= startY; y--) {
	for (x = startX; x <= lastX; x++) {
	    if (XGetPixel(imagePtr, x, y)) {
		value |= mask;
	    }
	    mask >>= 1;
	    if (mask == 0) {
		Tcl_AppendPrintfToObj(psObj, "%02x", value);
		mask = 0x80;
		value = 0;
		charsInLine += 2;
		if (charsInLine >= 60) {
		    Tcl_AppendToObj(psObj, "\n", -1);
		    charsInLine = 0;
		}
	    }
	}
	if (mask != 0x80) {
	    Tcl_AppendPrintfToObj(psObj, "%02x", value);
	    mask = 0x80;
	    value = 0;
	    charsInLine += 2;
	}
    }
    Tcl_AppendToObj(psObj, ">", -1);

    XDestroyImage(imagePtr);
}

/*
 *--------------------------------------------------------------
 *







>
>
>
>
>
>
>
>
|
>
>
>
>

















|











|







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

    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
    imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
	    totalWidth, totalHeight, 1, XYPixmap);


    if (!imagePtr) {
	/*
	 * The XGetImage() function is apparently not implemented on this
	 * system. Just skip the pixels, the Postscript will still be
	 * syntactically correct.
	 */

        Tcl_AppendToObj(psObj, "<>", TCL_INDEX_NONE);
	return;
    }

    Tcl_AppendToObj(psObj, "<", TCL_INDEX_NONE);
    mask = 0x80;
    value = 0;
    charsInLine = 0;
    lastX = startX + width - 1;
    lastY = startY + height - 1;
    for (y = lastY; y >= startY; y--) {
	for (x = startX; x <= lastX; x++) {
	    if (XGetPixel(imagePtr, x, y)) {
		value |= mask;
	    }
	    mask >>= 1;
	    if (mask == 0) {
		Tcl_AppendPrintfToObj(psObj, "%02x", value);
		mask = 0x80;
		value = 0;
		charsInLine += 2;
		if (charsInLine >= 60) {
		    Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		    charsInLine = 0;
		}
	    }
	}
	if (mask != 0x80) {
	    Tcl_AppendPrintfToObj(psObj, "%02x", value);
	    mask = 0x80;
	    value = 0;
	    charsInLine += 2;
	}
    }
    Tcl_AppendToObj(psObj, ">", TCL_INDEX_NONE);

    XDestroyImage(imagePtr);
}

/*
 *--------------------------------------------------------------
 *
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned *) &width,
	    (unsigned *) &height, &dummyBorderwidth, &dummyDepth);

    psObj = GetPostscriptBuffer(interp);
    Tcl_AppendPrintfToObj(psObj, "%d %d ", width, height);
    PostscriptBitmap(tkwin, bitmap, 0, 0, width, height, psObj);
    Tcl_AppendToObj(psObj, " StippleFill\n", -1);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptY --







|







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned *) &width,
	    (unsigned *) &height, &dummyBorderwidth, &dummyDepth);

    psObj = GetPostscriptBuffer(interp);
    Tcl_AppendPrintfToObj(psObj, "%d %d ", width, height);
    PostscriptBitmap(tkwin, bitmap, 0, 0, width, height, psObj);
    Tcl_AppendToObj(psObj, " StippleFill\n", TCL_INDEX_NONE);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_PostscriptY --
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
void
Tk_PostscriptPath(
    Tcl_Interp *interp,
    Tk_PostscriptInfo psInfo,	/* Canvas on whose behalf Postscript is being
				 * generated. */
    double *coordPtr,		/* Pointer to first in array of 2*numPoints
				 * coordinates giving points for path. */
    int numPoints)		/* Number of points at *coordPtr. */
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    Tcl_Obj *psObj;

    if (psInfoPtr->prepass) {
	return;
    }







|







1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
void
Tk_PostscriptPath(
    Tcl_Interp *interp,
    Tk_PostscriptInfo psInfo,	/* Canvas on whose behalf Postscript is being
				 * generated. */
    double *coordPtr,		/* Pointer to first in array of 2*numPoints
				 * coordinates giving points for path. */
    Tcl_Size numPoints)		/* Number of points at *coordPtr. */
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    Tcl_Obj *psObj;

    if (psInfoPtr->prepass) {
	return;
    }
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

static int
GetPostscriptPoints(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    char *string,		/* String describing a screen distance. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;


    d = strtod(string, &end);










    if (end == string) {
	goto error;




    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {



	end++;



    }

    switch (*end) {
    case 'c':
	d *= 72.0/2.54;
	end++;
	break;
    case 'i':
	d *= 72.0;
	end++;
	break;
    case 'm':
	d *= 72.0/25.4;
	end++;
	break;
    case 0:
	break;
    case 'p':
	end++;
	break;
    default:
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "POINTS", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * TkImageGetColor --
 *







|

>

|
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
|
<
>
>
>
|
>
>
>

>
|


<



<



<

<
<

<




<
<
<
<
<
<


<
<
<
<
<







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

static int
GetPostscriptPoints(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    char *string,		/* String describing a screen distance. */
    double *doublePtr)		/* Place to store converted result. */
{
    const char *rest;
    double d;
    Tcl_DString ds;

    if (Tcl_GetDouble(NULL, string, &d) == TCL_OK) {
	*doublePtr = d;
	return TCL_OK;
    }
    rest = string + strlen(string);
    while ((rest > string) && isspace(UCHAR(rest[-1]))) {
	--rest; /* skip all spaces at the end */
    }
    if (rest > string) {
	--rest; /* point to the character just before the last space */
    }
	if (rest == string) {
	error:
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad distance \"%s\"", string));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "POINTS", NULL);
	    }

	    return TCL_ERROR;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, string, rest-string);
    if (Tcl_GetDouble(NULL, Tcl_DStringValue(&ds), &d) != TCL_OK) {
	Tcl_DStringFree(&ds);
	goto error;
    }
    Tcl_DStringFree(&ds);
    switch (*rest) {
    case 'c':
	d *= 72.0/2.54;

	break;
    case 'i':
	d *= 72.0;

	break;
    case 'm':
	d *= 72.0/25.4;

	break;


    case 'p':

	break;
    default:
	goto error;
    }






    *doublePtr = d;
    return TCL_OK;





}

/*
 *--------------------------------------------------------------
 *
 * TkImageGetColor --
 *
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
#define GetBValue(rgb)	((rgb & cdata->blue_mask) >> cdata->blue_shift)

#endif /* _WIN32 */

#if defined(_WIN32) || defined(MAC_OSX_TK)
static void
TkImageGetColor(
    TkColormapData *cdata,	/* Colormap data */
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{
    (void)cdata;

    *red   = (double) GetRValue(pixel) / 255.0;
    *green = (double) GetGValue(pixel) / 255.0;
    *blue  = (double) GetBValue(pixel) / 255.0;
}
#else /* ! (_WIN32 || MAC_OSX_TK) */
static void







|




|







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
#define GetBValue(rgb)	((rgb & cdata->blue_mask) >> cdata->blue_shift)

#endif /* _WIN32 */

#if defined(_WIN32) || defined(MAC_OSX_TK)
static void
TkImageGetColor(
    TkColormapData *cdata,
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{
	(void)cdata;

    *red   = (double) GetRValue(pixel) / 255.0;
    *green = (double) GetGValue(pixel) / 255.0;
    *blue  = (double) GetBValue(pixel) / 255.0;
}
#else /* ! (_WIN32 || MAC_OSX_TK) */
static void
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

int
TkPostscriptImage(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psInfo,	/* postscript info */
    XImage *ximage,		/* Image to draw */
    int x, int y,		/* First pixel to output */
    int width, int height)	/* Width and height of area */
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    int xx, yy, band, maxRows;
    double red, green, blue;
    int bytesPerLine = 0, maxWidth = 0;
    int level = psInfoPtr->colorLevel;
    Colormap cmap;
    int i, ncolors;
    Visual *visual;
    TkColormapData cdata;
    Tcl_Obj *psObj;
    (void)y;

    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    cmap = Tk_Colormap(tkwin);
    visual = Tk_Visual(tkwin);







|












<







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

int
TkPostscriptImage(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psInfo,	/* postscript info */
    XImage *ximage,		/* Image to draw */
    int x, TCL_UNUSED(int),		/* First pixel to output */
    int width, int height)	/* Width and height of area */
{
    TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
    int xx, yy, band, maxRows;
    double red, green, blue;
    int bytesPerLine = 0, maxWidth = 0;
    int level = psInfoPtr->colorLevel;
    Colormap cmap;
    int i, ncolors;
    Visual *visual;
    TkColormapData cdata;
    Tcl_Obj *psObj;


    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    cmap = Tk_Colormap(tkwin);
    visual = Tk_Visual(tkwin);
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
		    }
		    mask >>= 1;
		    if (mask == 0) {
			Tcl_AppendPrintfToObj(psObj, "%02X", data);
			lineLen += 2;
			if (lineLen > 60) {
			    lineLen = 0;
			    Tcl_AppendToObj(psObj, "\n", -1);
			}
			mask = 0x80;
			data = 0x00;
		    }
		}
		if ((width % 8) != 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);







|







1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
		    }
		    mask >>= 1;
		    if (mask == 0) {
			Tcl_AppendPrintfToObj(psObj, "%02X", data);
			lineLen += 2;
			if (lineLen > 60) {
			    lineLen = 0;
			    Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
			}
			mask = 0x80;
			data = 0x00;
		    }
		}
		if ((width % 8) != 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);
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
			    &red, &green, &blue);
		    Tcl_AppendPrintfToObj(psObj, "%02X",
			    (int) floor(0.5 + 255.0 *
			    (0.30 * red + 0.59 * green + 0.11 * blue)));
		    lineLen += 2;
		    if (lineLen > 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		}
		break;
	    default:
		/*
		 * Finally, color mode. Here, just output the red, green, and
		 * blue values directly.
		 */

		for (xx = x; xx < x+width; xx++) {
		    TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
			    &red, &green, &blue);
		    Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X",
			    (int) floor(0.5 + 255.0 * red),
			    (int) floor(0.5 + 255.0 * green),
			    (int) floor(0.5 + 255.0 * blue));
		    lineLen += 6;
		    if (lineLen > 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		}
		break;
	    }
	}
	switch (level) {
	case 0: case 1:
	    Tcl_AppendToObj(psObj, ">\n} image\n", -1); break;
	default:
	    Tcl_AppendToObj(psObj, ">\n} false 3 colorimage\n", -1); break;
	}
	Tcl_AppendPrintfToObj(psObj, "0 %d translate\n", rows);
    }
    ckfree(cdata.colors);
    return TCL_OK;
}








|



















|







|

|







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
			    &red, &green, &blue);
		    Tcl_AppendPrintfToObj(psObj, "%02X",
			    (int) floor(0.5 + 255.0 *
			    (0.30 * red + 0.59 * green + 0.11 * blue)));
		    lineLen += 2;
		    if (lineLen > 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		    }
		}
		break;
	    default:
		/*
		 * Finally, color mode. Here, just output the red, green, and
		 * blue values directly.
		 */

		for (xx = x; xx < x+width; xx++) {
		    TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
			    &red, &green, &blue);
		    Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X",
			    (int) floor(0.5 + 255.0 * red),
			    (int) floor(0.5 + 255.0 * green),
			    (int) floor(0.5 + 255.0 * blue));
		    lineLen += 6;
		    if (lineLen > 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		    }
		}
		break;
	    }
	}
	switch (level) {
	case 0: case 1:
	    Tcl_AppendToObj(psObj, ">\n} image\n", TCL_INDEX_NONE); break;
	default:
	    Tcl_AppendToObj(psObj, ">\n} false 3 colorimage\n", TCL_INDEX_NONE); break;
	}
	Tcl_AppendPrintfToObj(psObj, "0 %d translate\n", rows);
    }
    ckfree(cdata.colors);
    return TCL_OK;
}

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
    /*
     * Set up the postscript code except for the image-data stream.
     */

    psObj = GetPostscriptBuffer(interp);
    switch (colorLevel) {
    case 0:
	Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", -1);
	decode = "1 0";
	bpc = 1;
	break;
    case 1:
	Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", -1);
	decode = "0 1";
	bpc = 8;
	break;
    default:
	Tcl_AppendToObj(psObj, "/DeviceRGB setcolorspace\n\n", -1);
	decode = "0 1 0 1 0 1";
	bpc = 8;
	break;
    }

    Tcl_AppendPrintfToObj(psObj,
	    "<<\n  /ImageType 1\n"







|




|




|







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
    /*
     * Set up the postscript code except for the image-data stream.
     */

    psObj = GetPostscriptBuffer(interp);
    switch (colorLevel) {
    case 0:
	Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", TCL_INDEX_NONE);
	decode = "1 0";
	bpc = 1;
	break;
    case 1:
	Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", TCL_INDEX_NONE);
	decode = "0 1";
	bpc = 8;
	break;
    default:
	Tcl_AppendToObj(psObj, "/DeviceRGB setcolorspace\n\n", TCL_INDEX_NONE);
	decode = "0 1 0 1 0 1";
	bpc = 8;
	break;
    }

    Tcl_AppendPrintfToObj(psObj,
	    "<<\n  /ImageType 1\n"
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
		}
		mask >>= 1;
		if (mask == 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);
		    lineLen += 2;
		    if (lineLen >= 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		    mask = 0x80;
		    data = 0x00;
		}
	    }
	    if ((width % 8) != 0) {
		Tcl_AppendPrintfToObj(psObj, "%02X", data);







|







1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
		}
		mask >>= 1;
		if (mask == 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);
		    lineLen += 2;
		    if (lineLen >= 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		    }
		    mask = 0x80;
		    data = 0x00;
		}
	    }
	    if ((width % 8) != 0) {
		Tcl_AppendPrintfToObj(psObj, "%02X", data);
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
		}
		mask >>= 1;
		if (mask == 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);
		    lineLen += 2;
		    if (lineLen >= 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", -1);
		    }
		    mask = 0x80;
		    data = 0x00;
		}
	    }
	    if ((width % 8) != 0) {
		Tcl_AppendPrintfToObj(psObj, "%02X", data);







|







1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
		}
		mask >>= 1;
		if (mask == 0) {
		    Tcl_AppendPrintfToObj(psObj, "%02X", data);
		    lineLen += 2;
		    if (lineLen >= 60) {
			lineLen = 0;
			Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		    }
		    mask = 0x80;
		    data = 0x00;
		}
	    }
	    if ((width % 8) != 0) {
		Tcl_AppendPrintfToObj(psObj, "%02X", data);
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
	    for (xx = 0; xx < width; xx ++) {
		alpha = *(alphaPtr + (yy * alphaPitch)
			+ (xx * alphaIncr) + alphaOffset);
		Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01);
		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }

	    /*
	     * Generate data in gray mode; in this case, take a weighted sum
	     * of the red, green, and blue values.
	     */







|







1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
	    for (xx = 0; xx < width; xx ++) {
		alpha = *(alphaPtr + (yy * alphaPitch)
			+ (xx * alphaIncr) + alphaOffset);
		Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01);
		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		}
	    }

	    /*
	     * Generate data in gray mode; in this case, take a weighted sum
	     * of the red, green, and blue values.
	     */
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
		blue = pixelPtr[blockPtr->offset[2]];

		Tcl_AppendPrintfToObj(psObj, "%02X", (int) floor(0.5 +
			( 0.3086 * red + 0.6094 * green + 0.0820 * blue)));
		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }
	    break;
	}
	default:
	    /*
	     * Generate transparency data. We must prevent a transparent value
	     * of 0 because of a bug in some HP printers.
	     */

	    for (xx = 0; xx < width; xx ++) {
		alpha = *(alphaPtr + (yy * alphaPitch)
			+ (xx * alphaIncr) + alphaOffset);
		Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01);
		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }

	    /*
	     * Finally, color mode. Here, just output the red, green, and blue
	     * values directly.
	     */

	    for (xx = 0; xx < width; xx ++) {
		pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch)
			+ (xx * blockPtr->pixelSize);

		Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X",
			pixelPtr[blockPtr->offset[0]],
			pixelPtr[blockPtr->offset[1]],
			pixelPtr[blockPtr->offset[2]]);
		lineLen += 6;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", -1);
		}
	    }
	    break;
	}
    }

    /*
     * The end-of-data marker.
     */

    Tcl_AppendToObj(psObj, ">\n", -1);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

















|



















|










|










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
		blue = pixelPtr[blockPtr->offset[2]];

		Tcl_AppendPrintfToObj(psObj, "%02X", (int) floor(0.5 +
			( 0.3086 * red + 0.6094 * green + 0.0820 * blue)));
		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		}
	    }
	    break;
	}
	default:
	    /*
	     * Generate transparency data. We must prevent a transparent value
	     * of 0 because of a bug in some HP printers.
	     */

	    for (xx = 0; xx < width; xx ++) {
		alpha = *(alphaPtr + (yy * alphaPitch)
			+ (xx * alphaIncr) + alphaOffset);
		Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01);
		lineLen += 2;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		}
	    }

	    /*
	     * Finally, color mode. Here, just output the red, green, and blue
	     * values directly.
	     */

	    for (xx = 0; xx < width; xx ++) {
		pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch)
			+ (xx * blockPtr->pixelSize);

		Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X",
			pixelPtr[blockPtr->offset[0]],
			pixelPtr[blockPtr->offset[1]],
			pixelPtr[blockPtr->offset[2]]);
		lineLen += 6;
		if (lineLen >= 60) {
		    lineLen = 0;
		    Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
		}
	    }
	    break;
	}
    }

    /*
     * The end-of-data marker.
     */

    Tcl_AppendToObj(psObj, ">\n", TCL_INDEX_NONE);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvText.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15




16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * tkCanvText.c --
 *
 *	This file implements text items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"





/*
 * The structure below defines the record for each text item.
 */

typedef struct TextItem {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_CanvasTextInfo *textInfoPtr;
				/* Pointer to a structure containing
				 * information about the selection and
				 * insertion cursor. The structure is owned by
				 * (and shared with) the generic canvas
				 * code. */
    /*
     * Fields that are set by widget commands other than "configure".
     */

    double x, y;		/* Positioning point for text. */
    TkSizeT insertPos;		/* Character index of character just before
				 * which the insertion cursor is displayed. */

    /*
     * Configuration settings that are updated by Tk_ConfigureWidget.
     */

    Tk_Anchor anchor;		/* Where to anchor text relative to (x,y). */
    Tk_TSOffset tsoffset;
    XColor *color;		/* Color for text. */
    XColor *activeColor;	/* Color for text. */
    XColor *disabledColor;	/* Color for text. */
    Tk_Font tkfont;		/* Font for drawing text. */
    Tk_Justify justify;		/* Justification mode for text. */
    Pixmap stipple;		/* Stipple bitmap for text, or None. */
    Pixmap activeStipple;	/* Stipple bitmap for text, or None. */
    Pixmap disabledStipple;	/* Stipple bitmap for text, or None. */
    char *text;			/* Text for item (malloc-ed). */
    int width;			/* Width of lines for word-wrap, pixels. Zero
				 * means no word-wrap. */
    int underline;		/* Index of character to put underline beneath
				 * or -1 for no underlining. */
    double angle;		/* What angle, in degrees, to draw the text
				 * at. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    TkSizeT numChars;		/* Length of text in characters. */
    TkSizeT numBytes;		/* Length of text in bytes. */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int actualWidth;		/* Width of text as computed. Used to make
				 * selections of wrapped text display
				 * right. */
    double drawOrigin[2];	/* Where we start drawing from. */
    GC gc;			/* Graphics context for drawing text. */
    GC selTextGC;		/* Graphics context for selected text. */





|
|








>
>
>
>



















|




















|








|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * tkCanvText.c --
 *
 *	This file implements text items for canvas widgets.
 *
 * 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"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The structure below defines the record for each text item.
 */

typedef struct TextItem {
    Tk_Item header;		/* Generic stuff that's the same for all
				 * types. MUST BE FIRST IN STRUCTURE. */
    Tk_CanvasTextInfo *textInfoPtr;
				/* Pointer to a structure containing
				 * information about the selection and
				 * insertion cursor. The structure is owned by
				 * (and shared with) the generic canvas
				 * code. */
    /*
     * Fields that are set by widget commands other than "configure".
     */

    double x, y;		/* Positioning point for text. */
    Tcl_Size insertPos;		/* Character index of character just before
				 * which the insertion cursor is displayed. */

    /*
     * Configuration settings that are updated by Tk_ConfigureWidget.
     */

    Tk_Anchor anchor;		/* Where to anchor text relative to (x,y). */
    Tk_TSOffset tsoffset;
    XColor *color;		/* Color for text. */
    XColor *activeColor;	/* Color for text. */
    XColor *disabledColor;	/* Color for text. */
    Tk_Font tkfont;		/* Font for drawing text. */
    Tk_Justify justify;		/* Justification mode for text. */
    Pixmap stipple;		/* Stipple bitmap for text, or None. */
    Pixmap activeStipple;	/* Stipple bitmap for text, or None. */
    Pixmap disabledStipple;	/* Stipple bitmap for text, or None. */
    char *text;			/* Text for item (malloc-ed). */
    int width;			/* Width of lines for word-wrap, pixels. Zero
				 * means no word-wrap. */
    int underline;		/* Index of character to put underline beneath
				 * or INT_MIN for no underlining. */
    double angle;		/* What angle, in degrees, to draw the text
				 * at. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    Tcl_Size numChars;		/* Length of text in characters. */
    Tcl_Size numBytes;		/* Length of text in bytes. */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int actualWidth;		/* Width of text as computed. Used to make
				 * selections of wrapped text display
				 * right. */
    double drawOrigin[2];	/* Where we start drawing from. */
    GC gc;			/* Graphics context for drawing text. */
    GC selTextGC;		/* Graphics context for selected text. */
83
84
85
86
87
88
89
90
91
92
93
94















































































95
96
97
98
99
100
101
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};
















































































static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,







|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};

static int
UnderlineParseProc(
    TCL_UNUSED(void *),	/* Not used.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item (ignored). */
{
    int *underlinePtr = (int *) (widgRec + offset);
    Tcl_Obj obj;
    int code;
    Tcl_Size underline;

    if (value == NULL || *value == 0) {
	*underlinePtr = INT_MIN; /* No underline */
	return TCL_OK;
    }

    obj.refCount = 1;
    obj.bytes = (char *)value;
    obj.length = strlen(value);
    obj.typePtr = NULL;
    code = TkGetIntForIndex(&obj, TCL_INDEX_NONE, 0, &underline);
    if (code == TCL_OK) {
	if (underline < INT_MIN) {
	    underline = INT_MIN;
	} else if (underline > INT_MAX) {
	    underline = INT_MAX;
	}
	*underlinePtr = (int)underline;

    } else {
	Tcl_AppendResult(interp, "bad index \"", value,
		"\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"", NULL);
    }
	return code;
}

static const char *
UnderlinePrintProc(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Pointer to record for item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    int underline = *(int *)(widgRec + offset);
    char *p;

    if (underline == INT_MIN) {
	p = (char *)"";
	*freeProcPtr = TCL_STATIC;
	return p;
    } else if (underline == INT_MAX) {
	p = (char *)"end+1";
	*freeProcPtr = TCL_STATIC;
	return p;
    } else if (underline == -1) {
	p = (char *)"end";
	*freeProcPtr = TCL_STATIC;
	return p;
    }
    p = (char *)ckalloc(32);
    if (underline < 0) {
	snprintf(p, 32, "end%d", 1 + underline);
    } else {
	snprintf(p, 32, "%d", underline);
    }
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}

static const Tk_CustomOption underlineOption = {
    UnderlineParseProc, UnderlinePrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(TextItem, stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_STRING, "-text", NULL, NULL,
	"", offsetof(TextItem, text), 0, NULL},
    {TK_CONFIG_INT, "-underline", NULL, NULL,
	"-1", offsetof(TextItem, underline), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", offsetof(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeTextBbox(Tk_Canvas canvas, TextItem *textPtr);
static int		ConfigureText(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateText(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const objv[]);
static void		DeleteText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayCanvText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static TkSizeT	GetSelText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT offset, char *buffer,
			    TkSizeT maxBytes);
static int		GetTextIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static void		ScaleText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		SetTextCursor(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT index);
static int		TextCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const objv[]);
static void		TextDeleteChars(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		TextInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
static int		TextToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		TextToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		TextToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		RotateText(Tk_Canvas canvas, Tk_Item *itemPtr,







|
|











|



|





|
|
|


|




|


|

|

|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(TextItem, stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_STRING, "-text", NULL, NULL,
	"", offsetof(TextItem, text), 0, NULL},
    {TK_CONFIG_CUSTOM, "-underline", NULL, NULL, NULL,
	offsetof(TextItem, underline), TK_CONFIG_NULL_OK, &underlineOption},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", offsetof(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeTextBbox(Tk_Canvas canvas, TextItem *textPtr);
static int		ConfigureText(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size argc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateText(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayCanvText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static Tcl_Size	GetSelText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size offset, char *buffer,
			    Tcl_Size maxBytes);
static int		GetTextIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, Tcl_Size *indexPtr);
static void		ScaleText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		SetTextCursor(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size index);
static int		TextCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		TextDeleteChars(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size first, Tcl_Size last);
static void		TextInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size beforeThis, Tcl_Obj *obj);
static int		TextToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		TextToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		TextToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		RotateText(Tk_Canvas canvas, Tk_Item *itemPtr,
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    sizeof(TextItem),		/* itemSize */
    CreateText,			/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureText,		/* configureProc */
    TextCoords,			/* coordProc */
    DeleteText,			/* deleteProc */
    DisplayCanvText,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    TextToPoint,		/* pointProc */
    TextToArea,			/* areaProc */
    TextToPostscript,		/* postscriptProc */
    ScaleText,			/* scaleProc */
    TranslateText,		/* translateProc */
    GetTextIndex,		/* indexProc */
    SetTextCursor,		/* icursorProc */







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    sizeof(TextItem),		/* itemSize */
    CreateText,			/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureText,		/* configureProc */
    TextCoords,			/* coordProc */
    DeleteText,			/* deleteProc */
    DisplayCanvText,		/* displayProc */
    0,				/* flags */
    TextToPoint,		/* pointProc */
    TextToArea,			/* areaProc */
    TextToPostscript,		/* postscriptProc */
    ScaleText,			/* scaleProc */
    TranslateText,		/* translateProc */
    GetTextIndex,		/* indexProc */
    SetTextCursor,		/* icursorProc */
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

static int
CreateText(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after







|



|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

static int
CreateText(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    textPtr->tkfont	= NULL;
    textPtr->justify	= TK_JUSTIFY_LEFT;
    textPtr->stipple	= None;
    textPtr->activeStipple = None;
    textPtr->disabledStipple = None;
    textPtr->text	= NULL;
    textPtr->width	= 0;
    textPtr->underline	= -1;
    textPtr->angle	= 0.0;

    textPtr->numChars	= 0;
    textPtr->numBytes	= 0;
    textPtr->textLayout = NULL;
    textPtr->actualWidth = 0;
    textPtr->drawOrigin[0] = textPtr->drawOrigin[1] = 0.0;







|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
    textPtr->tkfont	= NULL;
    textPtr->justify	= TK_JUSTIFY_LEFT;
    textPtr->stipple	= None;
    textPtr->activeStipple = None;
    textPtr->disabledStipple = None;
    textPtr->text	= NULL;
    textPtr->width	= 0;
    textPtr->underline	= INT_MIN;
    textPtr->angle	= 0.0;

    textPtr->numChars	= 0;
    textPtr->numBytes	= 0;
    textPtr->textLayout = NULL;
    textPtr->actualWidth = 0;
    textPtr->drawOrigin[0] = textPtr->drawOrigin[1] = 0.0;
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

static int
TextCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *obj = Tcl_NewObj();
	Tcl_Obj *subobj = Tcl_NewDoubleObj(textPtr->x);

	Tcl_ListObjAppendElement(interp, obj, subobj);
	subobj = Tcl_NewDoubleObj(textPtr->y);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);
	return TCL_OK;
    } else if (objc > 2) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL);
	return TCL_ERROR;
    }

    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	} else if (objc != 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # coordinates: expected 2, got %d", objc));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL);
	    return TCL_ERROR;
	}
    }
    if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&textPtr->x) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],







|















|










|







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

static int
TextCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *obj = Tcl_NewObj();
	Tcl_Obj *subobj = Tcl_NewDoubleObj(textPtr->x);

	Tcl_ListObjAppendElement(interp, obj, subobj);
	subobj = Tcl_NewDoubleObj(textPtr->y);
	Tcl_ListObjAppendElement(interp, obj, subobj);
	Tcl_SetObjResult(interp, obj);
	return TCL_OK;
    } else if (objc > 2) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL);
	return TCL_ERROR;
    }

    if (objc == 1) {
	if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		(Tcl_Obj ***) &objv) != TCL_OK) {
	    return TCL_ERROR;
	} else if (objc != 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # coordinates: expected 2, got %" TCL_SIZE_MODIFIER "d", objc));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL);
	    return TCL_ERROR;
	}
    }
    if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		&textPtr->x) != TCL_OK)
	    || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
 */

static int
ConfigureText(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Rectangle item to reconfigure. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    XGCValues gcValues;
    GC newGC, newSelGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    XColor *selBgColorPtr;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) textPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */







|
















|







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
 */

static int
ConfigureText(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Rectangle item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    XGCValues gcValues;
    GC newGC, newSelGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    XColor *selBgColorPtr;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, textPtr, flags)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
     * keep them inside the item.
     */

    textPtr->numBytes = strlen(textPtr->text);
    textPtr->numChars = Tcl_NumUtfChars(textPtr->text, textPtr->numBytes);
    if (textInfoPtr->selItemPtr == itemPtr) {

	if (textInfoPtr->selectFirst + 1 >= textPtr->numChars + 1) {
	    textInfoPtr->selItemPtr = NULL;
	} else {
	    if (textInfoPtr->selectLast + 1 >= textPtr->numChars + 1) {
		textInfoPtr->selectLast = textPtr->numChars - 1;
	    }
	    if ((textInfoPtr->anchorItemPtr == itemPtr)
		    && (textInfoPtr->selectAnchor + 1 >= textPtr->numChars + 1)) {
		textInfoPtr->selectAnchor = textPtr->numChars - 1;
	    }
	}
    }
    if (textPtr->insertPos + 1 >= textPtr->numChars + 1) {
	textPtr->insertPos = textPtr->numChars;
    }

    /*
     * Restrict so that 0.0 <= angle < 360.0, and then recompute the cached
     * sine and cosine of the angle. Note that fmod() can produce negative
     * results, and we try to avoid negative zero as well.







|


|



|




|







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
     * keep them inside the item.
     */

    textPtr->numBytes = strlen(textPtr->text);
    textPtr->numChars = Tcl_NumUtfChars(textPtr->text, textPtr->numBytes);
    if (textInfoPtr->selItemPtr == itemPtr) {

	if (textInfoPtr->selectFirst >= textPtr->numChars) {
	    textInfoPtr->selItemPtr = NULL;
	} else {
	    if (textInfoPtr->selectLast >= textPtr->numChars) {
		textInfoPtr->selectLast = textPtr->numChars - 1;
	    }
	    if ((textInfoPtr->anchorItemPtr == itemPtr)
		    && (textInfoPtr->selectAnchor >= textPtr->numChars)) {
		textInfoPtr->selectAnchor = textPtr->numChars - 1;
	    }
	}
    }
    if (textPtr->insertPos >= textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    }

    /*
     * Restrict so that 0.0 <= angle < 360.0, and then recompute the cached
     * sine and cosine of the angle. Note that fmod() can produce negative
     * results, and we try to avoid negative zero as well.
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteText(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    (void)canvas;

    if (textPtr->color != NULL) {
	Tk_FreeColor(textPtr->color);
    }
    if (textPtr->activeColor != NULL) {
	Tk_FreeColor(textPtr->activeColor);
    }







|




<







644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteText(
    TCL_UNUSED(Tk_Canvas),	/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    TextItem *textPtr = (TextItem *) itemPtr;


    if (textPtr->color != NULL) {
	Tk_FreeColor(textPtr->color);
    }
    if (textPtr->activeColor != NULL) {
	Tk_FreeColor(textPtr->activeColor);
    }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

static void
ComputeTextBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    TextItem *textPtr)		/* Item whose bbox is to be recomputed. */
{
    Tk_CanvasTextInfo *textInfoPtr;
    int leftX, topY, width, height, fudge, i;
    Tk_State state = textPtr->header.state;
    double x[4], y[4], dx[4], dy[4], sinA, cosA, tmp;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }








|







711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

static void
ComputeTextBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    TextItem *textPtr)		/* Item whose bbox is to be recomputed. */
{
    Tk_CanvasTextInfo *textInfoPtr;
    int width, height, fudge, i;
    Tk_State state = textPtr->header.state;
    double x[4], y[4], dx[4], dy[4], sinA, cosA, tmp;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
    }

    /*
     * Use overall geometry information to compute the top-left corner of the
     * bounding box for the text item.
     */

    leftX = ROUND(textPtr->x);
    topY = ROUND(textPtr->y);
    for (i=0 ; i<4 ; i++) {
	dx[i] = dy[i] = 0.0;
    }
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_N:
    case TK_ANCHOR_NE:
	break;

    case TK_ANCHOR_W:
    case TK_ANCHOR_CENTER:
    case TK_ANCHOR_E:
	topY -= height / 2;
	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height / 2;
	}
	break;

    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:
	topY -= height;
	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height;
	}
	break;
    }
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_W:
    case TK_ANCHOR_SW:
	break;

    case TK_ANCHOR_N:
    case TK_ANCHOR_CENTER:
    case TK_ANCHOR_S:
	leftX -= width / 2;
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width / 2;
	}
	break;

    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	leftX -= width;
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width;
	}
	break;
    }

    textPtr->actualWidth = width;

    sinA = textPtr->sine;







<
<









|
|
|
<

|



|
<
<
<

|









|
|
|
<

|



<
<
<
|

|







733
734
735
736
737
738
739


740
741
742
743
744
745
746
747
748
749
750
751

752
753
754
755
756
757



758
759
760
761
762
763
764
765
766
767
768
769
770
771

772
773
774
775
776



777
778
779
780
781
782
783
784
785
786
    }

    /*
     * Use overall geometry information to compute the top-left corner of the
     * bounding box for the text item.
     */



    for (i=0 ; i<4 ; i++) {
	dx[i] = dy[i] = 0.0;
    }
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_N:
    case TK_ANCHOR_NE:
	break;

    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:

	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height;
	}
	break;

    default:



	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height / 2;
	}
	break;
    }
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_W:
    case TK_ANCHOR_SW:
	break;

    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:

	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width;
	}
	break;




    default:
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width / 2;
	}
	break;
    }

    textPtr->actualWidth = width;

    sinA = textPtr->sine;
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y, int width, int height)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    TextItem *textPtr;
    Tk_CanvasTextInfo *textInfoPtr;
    TkSizeT selFirstChar, selLastChar;
    short drawableX, drawableY;
    Pixmap stipple;
    Tk_State state = itemPtr->state;

    textPtr = (TextItem *) itemPtr;
    textInfoPtr = textPtr->textInfoPtr;








|







870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y, int width, int height)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    TextItem *textPtr;
    Tk_CanvasTextInfo *textInfoPtr;
    Tcl_Size selFirstChar, selLastChar;
    short drawableX, drawableY;
    Pixmap stipple;
    Tk_State state = itemPtr->state;

    textPtr = (TextItem *) itemPtr;
    textInfoPtr = textPtr->textInfoPtr;

842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
    selLastChar = 0;
    Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0],
	    textPtr->drawOrigin[1], &drawableX, &drawableY);

    if (textInfoPtr->selItemPtr == itemPtr) {
	selFirstChar = textInfoPtr->selectFirst;
	selLastChar = textInfoPtr->selectLast;
	if (selLastChar + 1 > textPtr->numChars + 1 ) {
	    selLastChar = textPtr->numChars - 1;
	}
	if (((int)selFirstChar >= 0) && (selFirstChar + 1 <= selLastChar + 1 )) {
	    int xFirst, yFirst, hFirst;
	    int xLast, yLast, wLast;

	    /*
	     * Draw a special background under the selection.
	     */








|


|







914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
    selLastChar = 0;
    Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0],
	    textPtr->drawOrigin[1], &drawableX, &drawableY);

    if (textInfoPtr->selItemPtr == itemPtr) {
	selFirstChar = textInfoPtr->selectFirst;
	selLastChar = textInfoPtr->selectLast;
	if (selLastChar > textPtr->numChars) {
	    selLastChar = textPtr->numChars - 1;
	}
	if ((selFirstChar >= 0) && (selFirstChar <= selLastChar)) {
	    int xFirst, yFirst, hFirst;
	    int xLast, yLast, wLast;

	    /*
	     * Draw a special background under the selection.
	     */

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
 *----------------------------------------------------------------------
 */

static void
TextInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Text item to be modified. */
    TkSizeT index,			/* Character index before which string is to
				 * be inserted. */
    Tcl_Obj *obj)		/* New characters to be inserted. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, charsAdded;
    TkSizeT byteCount;
    char *newStr, *text;
    const char *string;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    string = TkGetStringFromObj(obj, &byteCount);

    text = textPtr->text;

    if (index == TCL_INDEX_NONE) {
	index = 0;
    }
    if (index + 1 > textPtr->numChars + 1) {
	index = textPtr->numChars;
    }
    byteIndex = Tcl_UtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }







|





|




|



|


|







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
 *----------------------------------------------------------------------
 */

static void
TextInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Text item to be modified. */
    Tcl_Size index,			/* Character index before which string is to
				 * be inserted. */
    Tcl_Obj *obj)		/* New characters to be inserted. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, charsAdded;
    Tcl_Size byteCount;
    char *newStr, *text;
    const char *string;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    string = Tcl_GetStringFromObj(obj, &byteCount);

    text = textPtr->text;

    if (index < 0) {
	index = 0;
    }
    if (index > textPtr->numChars) {
	index = textPtr->numChars;
    }
    byteIndex = Tcl_UtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }
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

    /*
     * Inserting characters invalidates indices such as those for the
     * selection and cursor. Update the indices appropriately.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst + 1 >= index + 1) {
	    textInfoPtr->selectFirst += charsAdded;
	}
	if (textInfoPtr->selectLast + 1 >= index + 1) {
	    textInfoPtr->selectLast += charsAdded;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 >= index + 1)) {
	    textInfoPtr->selectAnchor += charsAdded;
	}
    }
    if (textPtr->insertPos + 1 >= index + 1) {
	textPtr->insertPos += charsAdded;
    }
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------







|


|



|



|







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

    /*
     * Inserting characters invalidates indices such as those for the
     * selection and cursor. Update the indices appropriately.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst >= index) {
	    textInfoPtr->selectFirst += charsAdded;
	}
	if (textInfoPtr->selectLast >= index) {
	    textInfoPtr->selectLast += charsAdded;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor >= index)) {
	    textInfoPtr->selectAnchor += charsAdded;
	}
    }
    if (textPtr->insertPos >= index) {
	textPtr->insertPos += charsAdded;
    }
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
 *--------------------------------------------------------------
 */

static void
TextDeleteChars(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Character index of first character to
				 * delete. */
    TkSizeT last)			/* Character index of last character to delete
				 * (inclusive). */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, byteCount, charsRemoved;
    char *newStr, *text;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    text = textPtr->text;
    if ((int)first < 0) {
	first = 0;
    }
    if (last + 1 >= textPtr->numChars + 1) {
	last = textPtr->numChars - 1;
    }
    if (first + 1 > last + 1) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = Tcl_UtfAtIndex(text, first) - text;
    byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved)
	- (text + byteIndex);







|

|








|


|


|







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
 *--------------------------------------------------------------
 */

static void
TextDeleteChars(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    Tcl_Size first,			/* Character index of first character to
				 * delete. */
    Tcl_Size last)			/* Character index of last character to delete
				 * (inclusive). */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, byteCount, charsRemoved;
    char *newStr, *text;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    text = textPtr->text;
    if (first < 0) {
	first = 0;
    }
    if (last >= textPtr->numChars) {
	last = textPtr->numChars - 1;
    }
    if (first > last) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = Tcl_UtfAtIndex(text, first) - text;
    byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved)
	- (text + byteIndex);
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

    /*
     * Update indexes for the selection and cursor to reflect the renumbering
     * of the remaining characters.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst + 1 > first + 1) {
	    textInfoPtr->selectFirst -= charsRemoved;
	    if ((int)textInfoPtr->selectFirst + 1 < (int)first + 1) {
		textInfoPtr->selectFirst = first;
	    }
	}
	if (textInfoPtr->selectLast + 1 >= first + 1) {
	    textInfoPtr->selectLast -= charsRemoved;
	    if (textInfoPtr->selectLast + 1 < first) {
		textInfoPtr->selectLast = first - 1;
	    }
	}
	if ((int)textInfoPtr->selectFirst + 1 > (int)textInfoPtr->selectLast + 1) {
	    textInfoPtr->selItemPtr = NULL;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 > first + 1)) {
	    textInfoPtr->selectAnchor -= charsRemoved;
	    if (textInfoPtr->selectAnchor + 1 < first + 1) {
		textInfoPtr->selectAnchor = first;
	    }
	}
    }
    if (textPtr->insertPos + 1 > first + 1) {
	textPtr->insertPos -= charsRemoved;
	if ((int)textPtr->insertPos + 1 < (int)first + 1) {
	    textPtr->insertPos = first;
	}
    }
    ComputeTextBbox(canvas, textPtr);
    return;
}








|

|



|

|



|



|

|




|

|







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

    /*
     * Update indexes for the selection and cursor to reflect the renumbering
     * of the remaining characters.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst > first) {
	    textInfoPtr->selectFirst -= charsRemoved;
	    if (textInfoPtr->selectFirst < first) {
		textInfoPtr->selectFirst = first;
	    }
	}
	if (textInfoPtr->selectLast >= first) {
	    textInfoPtr->selectLast -= charsRemoved;
	    if (textInfoPtr->selectLast < first - 1) {
		textInfoPtr->selectLast = first - 1;
	    }
	}
	if (textInfoPtr->selectFirst > textInfoPtr->selectLast) {
	    textInfoPtr->selItemPtr = NULL;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor > first)) {
	    textInfoPtr->selectAnchor -= charsRemoved;
	    if (textInfoPtr->selectAnchor < first) {
		textInfoPtr->selectAnchor = first;
	    }
	}
    }
    if (textPtr->insertPos > first) {
	textPtr->insertPos -= charsRemoved;
	if (textPtr->insertPos < first) {
	    textPtr->insertPos = first;
	}
    }
    ComputeTextBbox(canvas, textPtr);
    return;
}

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
GetTextIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular character in
				 * itemPtr's text. */
    TkSizeT *indexPtr)		/* Where to store converted character
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT length, idx;
    int c;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars - 1, 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > textPtr->numChars) {
	    idx = textPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);
    c = string[0];

    if ((c == 'i')
	    && (strncmp(string, "insert", length) == 0)) {
	*indexPtr = textPtr->insertPos;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.first", length) == 0)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectFirst;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.last", length) == 0)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectLast;
    } else if (c == '@') {
	int x, y;
	double tmp, cs = textPtr->cosine, s = textPtr->sine;
	char *end;
	const char *p;

	p = string+1;
	tmp = strtod(p, &end);





	if ((end == p) || (*end != ',')) {
	    goto badIndex;
	}

	x = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	p = end+1;
	tmp = strtod(p, &end);
	if ((end == p) || (*end != 0)) {
	    goto badIndex;
	}
	y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	x -= (int) textPtr->drawOrigin[0];
	y -= (int) textPtr->drawOrigin[1];
	*indexPtr = Tk_PointToChar(textPtr->textLayout,
		(int) (x*cs - y*s), (int) (y*cs + x*s));
    } else {
	/*
	 * Some of the paths here leave messages in the interp's result, so we
	 * have to clear it out before storing our own message.
	 */

    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "TEXT", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|



|





|








|









|








|







|



|
>
>
>
>
>
|


>

|
|
<








<
<
<
<
<







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
GetTextIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular character in
				 * itemPtr's text. */
    Tcl_Size *indexPtr)		/* Where to store converted character
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    Tcl_Size length, idx;
    int c;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars - 1, 1, &idx)) {
	if (idx < 0) {
	    idx = 0;
	} else if (idx > textPtr->numChars) {
	    idx = textPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    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)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectFirst;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.last", length) == 0)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = textInfoPtr->selectLast;
    } else if (c == '@') {
	int x, y;
	double tmp, cs = textPtr->cosine, s = textPtr->sine;
	char *rest;
	const char *p;

	p = string+1;
	rest = strchr((char *)p, ',');
	if (!rest) {
	    goto badIndex;
	}
	*rest = '\0';
	if (Tcl_GetDouble(NULL, p, &tmp) != TCL_OK) {
	    *rest = ',';
	    goto badIndex;
	}
	*rest = ',';
	x = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	p = rest+1;
	if (Tcl_GetDouble(NULL, p, &tmp) != TCL_OK) {

	    goto badIndex;
	}
	y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	x -= (int) textPtr->drawOrigin[0];
	y -= (int) textPtr->drawOrigin[1];
	*indexPtr = Tk_PointToChar(textPtr->textLayout,
		(int) (x*cs - y*s), (int) (y*cs + x*s));
    } else {





    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "TEXT", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
 */

static void
SetTextCursor(
    TCL_UNUSED(Tk_Canvas),		/* Record describing canvas widget. */
    Tk_Item *itemPtr,		/* Text item in which cursor position is to be
				 * set. */
    TkSizeT index)			/* Character index of character just before
				 * which cursor is to be positioned. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (index == TCL_INDEX_NONE) {
	textPtr->insertPos = 0;
    } else if (index > textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    } else {
	textPtr->insertPos = index;
    }
}







|




|







1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
 */

static void
SetTextCursor(
    TCL_UNUSED(Tk_Canvas),		/* Record describing canvas widget. */
    Tk_Item *itemPtr,		/* Text item in which cursor position is to be
				 * set. */
    Tcl_Size index)			/* Character index of character just before
				 * which cursor is to be positioned. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (index < 0) {
	textPtr->insertPos = 0;
    } else if (index > textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    } else {
	textPtr->insertPos = index;
    }
}
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
GetSelText(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if (((int)textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst + 1 > textInfoPtr->selectLast + 1)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);
    if (selEnd  <= selStart + offset) {







|



|


|




|




|
|







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
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static Tcl_Size
GetSelText(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    Tcl_Size offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    Tcl_Size maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    Tcl_Size byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if ((textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst > textInfoPtr->selectLast)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);
    if (selEnd  <= selStart + offset) {
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
    if (stipple != None) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendPrintfToObj(psObj, "/StippleText {\n    %s} bind def\n",
		Tcl_GetString(Tcl_GetObjResult(interp)));
    }

    x = 0;  y = 0;  justify = NULL;
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:	   x = 0; y = 0; break;
    case TK_ANCHOR_N:	   x = 1; y = 0; break;
    case TK_ANCHOR_NE:	   x = 2; y = 0; break;
    case TK_ANCHOR_E:	   x = 2; y = 1; break;
    case TK_ANCHOR_SE:	   x = 2; y = 2; break;
    case TK_ANCHOR_S:	   x = 1; y = 2; break;
    case TK_ANCHOR_SW:	   x = 0; y = 2; break;
    case TK_ANCHOR_W:	   x = 0; y = 1; break;
    case TK_ANCHOR_CENTER: x = 1; y = 1; break;
    }
    switch (textPtr->justify) {
    case TK_JUSTIFY_LEFT:   justify = "0";   break;
    case TK_JUSTIFY_CENTER: justify = "0.5"; break;
    case TK_JUSTIFY_RIGHT:  justify = "1";   break;

    }

    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g %.15g [\n",
	    textPtr->angle, textPtr->x, Tk_CanvasPsY(canvas, textPtr->y));
    Tcl_ResetResult(interp);







<









|


<


>







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
    if (stipple != None) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendPrintfToObj(psObj, "/StippleText {\n    %s} bind def\n",
		Tcl_GetString(Tcl_GetObjResult(interp)));
    }


    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:	   x = 0; y = 0; break;
    case TK_ANCHOR_N:	   x = 1; y = 0; break;
    case TK_ANCHOR_NE:	   x = 2; y = 0; break;
    case TK_ANCHOR_E:	   x = 2; y = 1; break;
    case TK_ANCHOR_SE:	   x = 2; y = 2; break;
    case TK_ANCHOR_S:	   x = 1; y = 2; break;
    case TK_ANCHOR_SW:	   x = 0; y = 2; break;
    case TK_ANCHOR_W:	   x = 0; y = 1; break;
    default: x = 1; y = 1; break;
    }
    switch (textPtr->justify) {

    case TK_JUSTIFY_CENTER: justify = "0.5"; break;
    case TK_JUSTIFY_RIGHT:  justify = "1";   break;
    default:                justify = "0";   break;
    }

    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g %.15g [\n",
	    textPtr->angle, textPtr->x, Tk_CanvasPsY(canvas, textPtr->y));
    Tcl_ResetResult(interp);

Changes to generic/tkCanvUtil.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14




15
16
17
18
19
20
21
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"





/*
 * Structures defined only in this file.
 */

typedef struct SmoothAssocData {
    struct SmoothAssocData *nextPtr;






|







>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * tkCanvUtil.c --
 *
 *	This file contains a collection of utility functions used by the
 *	implementations of various canvas item types.
 *
 * 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Structures defined only in this file.
 */

typedef struct SmoothAssocData {
    struct SmoothAssocData *nextPtr;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
};


/*
 * Function forward-declarations.
 */

static void		SmoothMethodCleanupProc(ClientData clientData,
			    Tcl_Interp *interp);
static SmoothAssocData *InitSmoothMethods(Tcl_Interp *interp);
static int		DashConvert(char *l, const char *p, int n,
			    double width);
static void		TranslateAndAppendCoords(TkCanvas *canvPtr,
			    double x, double y, XPoint *outArr, int numOut);
static inline Tcl_Obj *	GetPostscriptBuffer(Tcl_Interp *interp);







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
};


/*
 * Function forward-declarations.
 */

static void		SmoothMethodCleanupProc(void *clientData,
			    Tcl_Interp *interp);
static SmoothAssocData *InitSmoothMethods(Tcl_Interp *interp);
static int		DashConvert(char *l, const char *p, int n,
			    double width);
static void		TranslateAndAppendCoords(TkCanvas *canvPtr,
			    double x, double y, XPoint *outArr, int numOut);
static inline Tcl_Obj *	GetPostscriptBuffer(Tcl_Interp *interp);
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoord(
    Tcl_Interp *dummy,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to which coordinate applies. */
    const char *string,		/* Describes coordinate (any screen coordinate
				 * form may be used here). */
    double *doublePtr)		/* Place to store converted coordinate. */
{
    (void)dummy;

    if (Tk_GetScreenMM(Canvas(canvas)->interp, Canvas(canvas)->tkwin, string,
	    doublePtr) != TCL_OK) {
	return TCL_ERROR;
    }
    *doublePtr *= Canvas(canvas)->pixelsPerMM;
    return TCL_OK;
}







|





<
<







231
232
233
234
235
236
237
238
239
240
241
242
243


244
245
246
247
248
249
250
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoord(
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to which coordinate applies. */
    const char *string,		/* Describes coordinate (any screen coordinate
				 * form may be used here). */
    double *doublePtr)		/* Place to store converted coordinate. */
{


    if (Tk_GetScreenMM(Canvas(canvas)->interp, Canvas(canvas)->tkwin, string,
	    doublePtr) != TCL_OK) {
	return TCL_ERROR;
    }
    *doublePtr *= Canvas(canvas)->pixelsPerMM;
    return TCL_OK;
}
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoordFromObj(
    Tcl_Interp *dummy,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to which coordinate applies. */
    Tcl_Obj *obj,		/* Describes coordinate (any screen coordinate
				 * form may be used here). */
    double *doublePtr)		/* Place to store converted coordinate. */
{
    (void)dummy;

    return Tk_GetDoublePixelsFromObj(Canvas(canvas)->interp, Canvas(canvas)->tkwin, obj, doublePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetStippleOrigin --







|





<
<







267
268
269
270
271
272
273
274
275
276
277
278
279


280
281
282
283
284
285
286
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoordFromObj(
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to which coordinate applies. */
    Tcl_Obj *obj,		/* Describes coordinate (any screen coordinate
				 * form may be used here). */
    double *doublePtr)		/* Place to store converted coordinate. */
{


    return Tk_GetDoublePixelsFromObj(Canvas(canvas)->interp, Canvas(canvas)->tkwin, obj, doublePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetStippleOrigin --
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
 *	The tags for a given item get replaced by those indicated in the value
 *	argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasTagsParseProc(
    ClientData dummy,	/* Not used.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    const char *value,		/* Value of option (list of tag names). */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item (ignored). */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;
    int argc, i;
    const char **argv;
    Tk_Uid *newPtr;
    (void)dummy;
    (void)tkwin;
    (void)offset;

    /*
     * Break the value up into the individual tag names.
     */

    if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Make sure that there's enough space in the item to hold the tag names.
     */

    if ((int)itemPtr->tagSpace < argc) {
	newPtr = (Tk_Uid *)ckalloc(argc * sizeof(Tk_Uid));
	for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	    newPtr[i] = itemPtr->tagPtr[i];
	}
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newPtr;
	itemPtr->tagSpace = argc;







|
|

|


|


|


<
<
<













|

|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416



417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
 *	The tags for a given item get replaced by those indicated in the value
 *	argument.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasTagsParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option (list of tag names). */
    char *widgRec,		/* Pointer to record for item. */
    TCL_UNUSED(Tcl_Size))			/* Offset into item (ignored). */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;
    Tcl_Size argc, i;
    const char **argv;
    Tk_Uid *newPtr;




    /*
     * Break the value up into the individual tag names.
     */

    if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Make sure that there's enough space in the item to hold the tag names.
     */

    if (itemPtr->tagSpace < argc) {
	newPtr = (Tk_Uid *)ckalloc(argc * sizeof(Tk_Uid));
	for (i = itemPtr->numTags - 1; i != TCL_INDEX_NONE; i--) {
	    newPtr[i] = itemPtr->tagPtr[i];
	}
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newPtr;
	itemPtr->tagSpace = argc;
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasTagsPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Ignored. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;
    (void)dummy;
    (void)tkwin;
    (void)offset;

    if (itemPtr->numTags == 0) {
	*freeProcPtr = NULL;
	return "";
    }
    if (itemPtr->numTags == 1) {
	*freeProcPtr = NULL;







|
|
|

|





<
<
<







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481



482
483
484
485
486
487
488
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
Tk_CanvasTagsPrintProc(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TCL_UNUSED(Tcl_Size),			/* Ignored. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;




    if (itemPtr->numTags == 0) {
	*freeProcPtr = NULL;
	return "";
    }
    if (itemPtr->numTags == 1) {
	*freeProcPtr = NULL;
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasDashParseProc(
    ClientData dummy,	/* Not used.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    (void)dummy;
    (void)tkwin;

    return Tk_GetDash(interp, value, (Tk_Dash *) (widgRec+offset));
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashPrintProc --







|

|


|

<
<
<







508
509
510
511
512
513
514
515
516
517
518
519
520
521



522
523
524
525
526
527
528
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasDashParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item. */
{



    return Tk_GetDash(interp, value, (Tk_Dash *) (widgRec+offset));
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashPrintProc --
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasDashPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset in record for item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_Dash *dash = (Tk_Dash *) (widgRec+offset);
    char *buffer, *p;
    int i = dash->number;
    (void)dummy;
    (void)tkwin;

    if (i < 0) {
	i = -i;
	*freeProcPtr = TCL_DYNAMIC;
	buffer = (char *)ckalloc(i + 1);
	p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
	memcpy(buffer, p, (unsigned int) i);
	buffer[i] = 0;
	return buffer;
    } else if (!i) {
	*freeProcPtr = NULL;
	return "";
    }
    buffer = (char *)ckalloc(4 * i);
    *freeProcPtr = TCL_DYNAMIC;

    p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
    sprintf(buffer, "%d", *p++ & 0xff);
    while (--i) {
	sprintf(buffer+strlen(buffer), " %d", *p++ & 0xff);
    }
    return buffer;
}

/*
 *--------------------------------------------------------------
 *







|
|

|







<
<




|








|



|

|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559


560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasDashPrintProc(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),	/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Offset in record for item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_Dash *dash = (Tk_Dash *) (widgRec+offset);
    char *buffer, *p;
    int i = dash->number;



    if (i < 0) {
	i = -i;
	*freeProcPtr = TCL_DYNAMIC;
	buffer = (char *)ckalloc((Tcl_Size)i + 1);
	p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
	memcpy(buffer, p, (unsigned int) i);
	buffer[i] = 0;
	return buffer;
    } else if (!i) {
	*freeProcPtr = NULL;
	return "";
    }
    buffer = (char *)ckalloc(4 * (Tcl_Size)i);
    *freeProcPtr = TCL_DYNAMIC;

    p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
    snprintf(buffer, 4 * (size_t)i, "%d", *p++ & 0xff);
    while (--i) {
	snprintf(buffer + strlen(buffer), 4 * (size_t)i - strlen(buffer), " %d", *p++ & 0xff);
    }
    return buffer;
}

/*
 *--------------------------------------------------------------
 *
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
 *	Smooth methods are removed.
 *
 *----------------------------------------------------------------------
 */

static void
SmoothMethodCleanupProc(
    ClientData clientData,	/* Points to "smoothMethod" AssocData for the
				 * interpreter. */
    Tcl_Interp *dummy)		/* Interpreter that is being deleted. */
{
    SmoothAssocData *ptr, *methods = (SmoothAssocData *)clientData;
    (void)dummy;

    while (methods != NULL) {
	ptr = methods;
	methods = methods->nextPtr;
	ckfree(ptr);
    }
}







|

|


<







694
695
696
697
698
699
700
701
702
703
704
705

706
707
708
709
710
711
712
 *	Smooth methods are removed.
 *
 *----------------------------------------------------------------------
 */

static void
SmoothMethodCleanupProc(
    void *clientData,	/* Points to "smoothMethod" AssocData for the
				 * interpreter. */
    TCL_UNUSED(Tcl_Interp *))		/* Interpreter that is being deleted. */
{
    SmoothAssocData *ptr, *methods = (SmoothAssocData *)clientData;


    while (methods != NULL) {
	ptr = methods;
	methods = methods->nextPtr;
	ckfree(ptr);
    }
}
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkSmoothParseProc(
    ClientData dummy,	/* Ignored. */
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    const Tk_SmoothMethod **smoothPtr =
	    (const Tk_SmoothMethod **) (widgRec + offset);
    const Tk_SmoothMethod *smooth = NULL;
    int b;
    size_t length;
    SmoothAssocData *methods;
    (void)dummy;
    (void)tkwin;

    if (value == NULL || *value == 0) {
	*smoothPtr = NULL;
	return TCL_OK;
    }
    length = strlen(value);
    methods = (SmoothAssocData *)Tcl_GetAssocData(interp, "smoothMethod", NULL);

    /*
     * Not initialized yet; fix that now.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
    }

    /*
     * Backward compatability hack.
     */

    if (strncmp(value, "bezier", length) == 0) {
	smooth = &tkBezierSmoothMethod;
    }

    /*







|

|


|







<
<

















|







726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745


746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkSmoothParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item. */
{
    const Tk_SmoothMethod **smoothPtr =
	    (const Tk_SmoothMethod **) (widgRec + offset);
    const Tk_SmoothMethod *smooth = NULL;
    int b;
    size_t length;
    SmoothAssocData *methods;



    if (value == NULL || *value == 0) {
	*smoothPtr = NULL;
	return TCL_OK;
    }
    length = strlen(value);
    methods = (SmoothAssocData *)Tcl_GetAssocData(interp, "smoothMethod", NULL);

    /*
     * Not initialized yet; fix that now.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
    }

    /*
     * Backward compatibility hack.
     */

    if (strncmp(value, "bezier", length) == 0) {
	smooth = &tkBezierSmoothMethod;
    }

    /*
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkSmoothPrintProc(
    ClientData dummy,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    const Tk_SmoothMethod *smoothPtr =
	    * (Tk_SmoothMethod **) (widgRec + offset);
    (void)dummy;
	(void)tkwin;
    (void)freeProcPtr;

    return smoothPtr ? smoothPtr->name : "0";
}
/*
 *--------------------------------------------------------------
 *
 * Tk_GetDash







|
|

|
|





<
<
<







818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834



835
836
837
838
839
840
841
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkSmoothPrintProc(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),	/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    const Tk_SmoothMethod *smoothPtr =
	    * (Tk_SmoothMethod **) (widgRec + offset);




    return smoothPtr ? smoothPtr->name : "0";
}
/*
 *--------------------------------------------------------------
 *
 * Tk_GetDash
873
874
875
876
877
878
879

880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
int
Tk_GetDash(
    Tcl_Interp *interp,		/* Used for error reporting. */
    const char *value,		/* Textual specification of dash list. */
    Tk_Dash *dash)		/* Pointer to record in which to store dash
				 * information. */
{

    int argc, i;
    const char **largv, **argv = NULL;
    char *pt;

    if ((value == NULL) || (*value == '\0')) {
	dash->number = 0;
	return TCL_OK;
    }

    /*
     * switch is usually compiled more efficiently than a chain of conditions.
     */

    switch (*value) {
    case '.': case ',': case '-': case '_':
	i = DashConvert(NULL, value, -1, 0.0);
	if (i <= 0) {
	    goto badDashList;
	}
	i = strlen(value);
	if (i > (int) sizeof(char *)) {
	    dash->pattern.pt = pt = (char *)ckalloc(strlen(value));
	} else {
	    pt = dash->pattern.array;
	}
	memcpy(pt, value, (unsigned) i);
	dash->number = -i;







>
|


















|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
int
Tk_GetDash(
    Tcl_Interp *interp,		/* Used for error reporting. */
    const char *value,		/* Textual specification of dash list. */
    Tk_Dash *dash)		/* Pointer to record in which to store dash
				 * information. */
{
    Tcl_Size argc;
    int i;
    const char **largv, **argv = NULL;
    char *pt;

    if ((value == NULL) || (*value == '\0')) {
	dash->number = 0;
	return TCL_OK;
    }

    /*
     * switch is usually compiled more efficiently than a chain of conditions.
     */

    switch (*value) {
    case '.': case ',': case '-': case '_':
	i = DashConvert(NULL, value, -1, 0.0);
	if (i <= 0) {
	    goto badDashList;
	}
	i = (int)strlen(value);
	if (i > (int) sizeof(char *)) {
	    dash->pattern.pt = pt = (char *)ckalloc(strlen(value));
	} else {
	    pt = dash->pattern.array;
	}
	memcpy(pt, value, (unsigned) i);
	dash->number = -i;
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
	}
    }

    Tcl_AppendPrintfToObj(psObj, "%.15g setlinewidth\n", width);

    ptr = ((unsigned) ABS(dash->number) > sizeof(char *)) ?
	    dash->pattern.pt : dash->pattern.array;
    Tcl_AppendToObj(psObj, "[", -1);
    if (dash->number > 0) {
	Tcl_Obj *converted;
	char *p = ptr;

	converted = Tcl_ObjPrintf("%d", *p++ & 0xff);
	for (i = dash->number-1 ; i>0 ; i--) {
	    Tcl_AppendPrintfToObj(converted, " %d", *p++ & 0xff);
	}
	Tcl_AppendObjToObj(psObj, converted);
	if (dash->number & 1) {
	    Tcl_AppendToObj(psObj, " ", -1);
	    Tcl_AppendObjToObj(psObj, converted);
	}
	Tcl_DecrRefCount(converted);
	Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);
    } else if (dash->number < 0) {
	if (dash->number < -5) {
	    lptr = (char *)ckalloc(1 - 2*dash->number);
	}
	i = DashConvert(lptr, ptr, -dash->number, width);
	if (i > 0) {
	    char *p = lptr;

	    Tcl_AppendPrintfToObj(psObj, "%d", *p++ & 0xff);
	    for (; --i>0 ;) {
		Tcl_AppendPrintfToObj(psObj, " %d", *p++ & 0xff);
	    }
	    Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);
	} else {
	    Tcl_AppendToObj(psObj, "] 0 setdash\n", -1);
	}
	if (lptr != pattern) {
	    ckfree(lptr);
	}
    } else {
	Tcl_AppendToObj(psObj, "] 0 setdash\n", -1);
    }

    Tk_CanvasPsColor(interp, canvas, color);

    if (stipple != None) {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "StrokeClip ", -1);
	Tk_CanvasPsStipple(interp, canvas, stipple);
    } else {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "stroke\n", -1);
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|










|


















|





|





|


|







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
	}
    }

    Tcl_AppendPrintfToObj(psObj, "%.15g setlinewidth\n", width);

    ptr = ((unsigned) ABS(dash->number) > sizeof(char *)) ?
	    dash->pattern.pt : dash->pattern.array;
    Tcl_AppendToObj(psObj, "[", TCL_INDEX_NONE);
    if (dash->number > 0) {
	Tcl_Obj *converted;
	char *p = ptr;

	converted = Tcl_ObjPrintf("%d", *p++ & 0xff);
	for (i = dash->number-1 ; i>0 ; i--) {
	    Tcl_AppendPrintfToObj(converted, " %d", *p++ & 0xff);
	}
	Tcl_AppendObjToObj(psObj, converted);
	if (dash->number & 1) {
	    Tcl_AppendToObj(psObj, " ", TCL_INDEX_NONE);
	    Tcl_AppendObjToObj(psObj, converted);
	}
	Tcl_DecrRefCount(converted);
	Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);
    } else if (dash->number < 0) {
	if (dash->number < -5) {
	    lptr = (char *)ckalloc(1 - 2*dash->number);
	}
	i = DashConvert(lptr, ptr, -dash->number, width);
	if (i > 0) {
	    char *p = lptr;

	    Tcl_AppendPrintfToObj(psObj, "%d", *p++ & 0xff);
	    for (; --i>0 ;) {
		Tcl_AppendPrintfToObj(psObj, " %d", *p++ & 0xff);
	    }
	    Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);
	} else {
	    Tcl_AppendToObj(psObj, "] 0 setdash\n", TCL_INDEX_NONE);
	}
	if (lptr != pattern) {
	    ckfree(lptr);
	}
    } else {
	Tcl_AppendToObj(psObj, "] 0 setdash\n", TCL_INDEX_NONE);
    }

    Tk_CanvasPsColor(interp, canvas, color);

    if (stipple != None) {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "StrokeClip ", TCL_INDEX_NONE);
	Tk_CanvasPsStipple(interp, canvas, stipple);
    } else {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "stroke\n", TCL_INDEX_NONE);
    }

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
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

int
TkCanvTranslatePath(
    TkCanvas *canvPtr,		/* The canvas */
    int numVertex,		/* Number of vertices specified by
				 * coordArr[] */
    double *coordArr,		/* X and Y coordinates for each vertex */
    int closedPath,		/* True if this is a closed polygon */
    XPoint *outArr)		/* Write results here, if not NULL */
{
    int numOutput = 0;		/* Number of output coordinates */
    double lft, rgh;		/* Left and right sides of the bounding box */
    double top, btm;		/* Top and bottom sizes of the bounding box */
    double *tempArr;		/* Temporary storage used by the clipper */
    double *a, *b, *t;		/* Pointers to parts of the temporary
				 * storage */
    int i, j;			/* Loop counters */
    double limit[4];		/* Boundries at which clipping occurs */
    double staticSpace[480];	/* Temp space from the stack */
    (void)closedPath;

    /*
     * Constrain all vertices of the path to be within a box that is no larger
     * than 32000 pixels wide or height. The top-left corner of this clipping
     * box is 1000 pixels above and to the left of the top left corner of the
     * window on which the canvas is displayed.
     *







|











<







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

int
TkCanvTranslatePath(
    TkCanvas *canvPtr,		/* The canvas */
    int numVertex,		/* Number of vertices specified by
				 * coordArr[] */
    double *coordArr,		/* X and Y coordinates for each vertex */
    TCL_UNUSED(int),		/* True if this is a closed polygon */
    XPoint *outArr)		/* Write results here, if not NULL */
{
    int numOutput = 0;		/* Number of output coordinates */
    double lft, rgh;		/* Left and right sides of the bounding box */
    double top, btm;		/* Top and bottom sizes of the bounding box */
    double *tempArr;		/* Temporary storage used by the clipper */
    double *a, *b, *t;		/* Pointers to parts of the temporary
				 * storage */
    int i, j;			/* Loop counters */
    double limit[4];		/* Boundries at which clipping occurs */
    double staticSpace[480];	/* Temp space from the stack */


    /*
     * Constrain all vertices of the path to be within a box that is no larger
     * than 32000 pixels wide or height. The top-left corner of this clipping
     * box is 1000 pixels above and to the left of the top left corner of the
     * window on which the canvas is displayed.
     *

Changes to generic/tkCanvWind.c.

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.
 *
 * 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"





|
|







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 © 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"
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", offsetof(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", offsetof(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeWindowBbox(Tk_Canvas canvas,
			    WindowItem *winItemPtr);
static int		ConfigureWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateWinItem(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);
static int		WinItemCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		WinItemLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		WinItemRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		WinItemStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		WinItemToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static int		WinItemToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static double		WinItemToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
#ifdef X_GetImage
static int		xerrorhandler(ClientData clientData, XErrorEvent *e);
#endif
static int		CanvasPsWindow(Tcl_Interp *interp,
			    Tk_Window tkwin, Tk_Canvas canvas, double x,
			    double y, int width, int height);

/*
 * The structure below defines the window item type by means of functions
 * that can be invoked by generic item code.
 */

Tk_ItemType tkWindowType = {
    "window",			/* name */
    sizeof(WindowItem),		/* itemSize */
    CreateWinItem,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureWinItem,		/* configureProc */
    WinItemCoords,		/* coordProc */
    DeleteWinItem,		/* deleteProc */
    DisplayWinItem,		/* displayProc */
    1|TK_CONFIG_OBJS,		/* flags */
    WinItemToPoint,		/* pointProc */
    WinItemToArea,		/* areaProc */
    WinItemToPostscript,	/* postscriptProc */
    ScaleWinItem,		/* scaleProc */
    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */







|



|













|

|

|

|








|



















|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeWindowBbox(Tk_Canvas canvas,
			    WindowItem *winItemPtr);
static int		ConfigureWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateWinItem(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);
static int		WinItemCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static void		WinItemLostContentProc(void *clientData,
			    Tk_Window tkwin);
static void		WinItemRequestProc(void *clientData,
			    Tk_Window tkwin);
static void		WinItemStructureProc(void *clientData,
			    XEvent *eventPtr);
static int		WinItemToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static int		WinItemToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static double		WinItemToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
#ifdef X_GetImage
static int		xerrorhandler(void *clientData, XErrorEvent *e);
#endif
static int		CanvasPsWindow(Tcl_Interp *interp,
			    Tk_Window tkwin, Tk_Canvas canvas, double x,
			    double y, int width, int height);

/*
 * The structure below defines the window item type by means of functions
 * that can be invoked by generic item code.
 */

Tk_ItemType tkWindowType = {
    "window",			/* name */
    sizeof(WindowItem),		/* itemSize */
    CreateWinItem,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureWinItem,		/* configureProc */
    WinItemCoords,		/* coordProc */
    DeleteWinItem,		/* deleteProc */
    DisplayWinItem,		/* displayProc */
    TK_ALWAYS_REDRAW,		/* flags */
    WinItemToPoint,		/* pointProc */
    WinItemToArea,		/* areaProc */
    WinItemToPostscript,	/* postscriptProc */
    ScaleWinItem,		/* scaleProc */
    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

static int
CreateWinItem(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing window. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.







|



|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

static int
CreateWinItem(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing window. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Initialize item's record.
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    i = 1;
	}
    }
    if (WinItemCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
    }
    if (ConfigureWinItem(interp, canvas, itemPtr, objc-i, objv+i, 0)
	    == TCL_OK) {
	return TCL_OK;
    }

  error:
    DeleteWinItem(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
    return TCL_ERROR;







|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
	    i = 1;
	}
    }
    if (WinItemCoords(interp, canvas, itemPtr, i, objv) != TCL_OK) {
	goto error;
    }
    if (ConfigureWinItem(interp, canvas, itemPtr, objc - i, objv + i, 0)
	    == TCL_OK) {
	return TCL_OK;
    }

  error:
    DeleteWinItem(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
    return TCL_ERROR;
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 int
WinItemCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *objs[2];

	objs[0] = Tcl_NewDoubleObj(winItemPtr->x);
	objs[1] = Tcl_NewDoubleObj(winItemPtr->y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs));
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &winItemPtr->x)
		!= TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		&winItemPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeWindowBbox(canvas, winItemPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|

















|













|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 int
WinItemCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1, y1, x2, y2, ... */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;

    if (objc == 0) {
	Tcl_Obj *objs[2];

	objs[0] = Tcl_NewDoubleObj(winItemPtr->x);
	objs[1] = Tcl_NewDoubleObj(winItemPtr->y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs));
    } else if (objc < 3) {
	if (objc==1) {
	    if (Tcl_ListObjGetElements(interp, objv[0], &objc,
		    (Tcl_Obj ***) &objv) != TCL_OK) {
		return TCL_ERROR;
	    } else if (objc != 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"wrong # coordinates: expected 2, got %" TCL_SIZE_MODIFIER "d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &winItemPtr->x)
		!= TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		&winItemPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeWindowBbox(canvas, winItemPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
 */

static int
ConfigureWinItem(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Window item to reconfigure. */
    int objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    Tk_Window oldWindow;
    Tk_Window canvasTkwin;

    oldWindow = winItemPtr->tkwin;
    canvasTkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, objc,
	    (const char **) objv, (char *) winItemPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing.
     */








|










|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
 */

static int
ConfigureWinItem(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Window item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv.  */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    Tk_Window oldWindow;
    Tk_Window canvasTkwin;

    oldWindow = winItemPtr->tkwin;
    canvasTkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, objc,
	    objv, winItemPtr, flags)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing.
     */

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
 *--------------------------------------------------------------
 */

static void
DeleteWinItem(
    Tk_Canvas canvas,		/* Overall info about widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    (void)display;

    if (winItemPtr->tkwin != NULL) {
	Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		WinItemStructureProc, winItemPtr);
	Tk_ManageGeometry(winItemPtr->tkwin, NULL, NULL);
	if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);







|



<







400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
 *--------------------------------------------------------------
 */

static void
DeleteWinItem(
    Tk_Canvas canvas,		/* Overall info about widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    TCL_UNUSED(Display *))	/* Display containing window for canvas. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);


    if (winItemPtr->tkwin != NULL) {
	Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		WinItemStructureProc, winItemPtr);
	Tk_ManageGeometry(winItemPtr->tkwin, NULL, NULL);
	if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
	y -= height;
	break;
    case TK_ANCHOR_W:
	y -= height/2;
	break;
    case TK_ANCHOR_NW:
	break;
    case TK_ANCHOR_CENTER:
	x -= width/2;
	y -= height/2;
	break;
    }

    /*
     * Store the information in the item header.







|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
	y -= height;
	break;
    case TK_ANCHOR_W:
	y -= height/2;
	break;
    case TK_ANCHOR_NW:
	break;
    default:
	x -= width/2;
	y -= height/2;
	break;
    }

    /*
     * Store the information in the item header.
556
557
558
559
560
561
562
563
564
565
566
567


568
569
570
571
572
573
574
575
576
577
578
579
580
581
582



583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
 *--------------------------------------------------------------
 */

static void
DisplayWinItem(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int regionX, int regionY, int regionWidth, int regionHeight)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */


{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int width, height;
    short x, y;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    Tk_State state = itemPtr->state;
    (void)display;
    (void)regionX;
    (void)regionY;
    (void)regionWidth;
    (void)regionHeight;

    if (winItemPtr->tkwin == NULL) {
	return;
    }



    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    /*
     * A drawable of None is used by the canvas UnmapNotify handler
     * to indicate that we should no longer display ourselves.
     */
    if (state == TK_STATE_HIDDEN || drawable == None) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}

	return;
    }
    Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,
	    (double) winItemPtr->header.y1, &x, &y);
    width = winItemPtr->header.x2 - winItemPtr->header.x1;
    height = winItemPtr->header.y2 - winItemPtr->header.y1;








|

<
|
|
>
>






<
<
<
<
<




>
>
>














>







555
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572
573





574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
 *--------------------------------------------------------------
 */

static void
DisplayWinItem(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    TCL_UNUSED(Display *),	/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */

    TCL_UNUSED(int), /* Describes region of canvas that must be */
    TCL_UNUSED(int), /* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int width, height;
    short x, y;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    Tk_State state = itemPtr->state;






    if (winItemPtr->tkwin == NULL) {
	return;
    }

    Tcl_Preserve(canvas);

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    /*
     * A drawable of None is used by the canvas UnmapNotify handler
     * to indicate that we should no longer display ourselves.
     */
    if (state == TK_STATE_HIDDEN || drawable == None) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tcl_Release(canvas);
	return;
    }
    Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,
	    (double) winItemPtr->header.y1, &x, &y);
    width = winItemPtr->header.x2 - winItemPtr->header.x1;
    height = winItemPtr->header.y2 - winItemPtr->header.y1;

611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631


632


633
634
635
636

637
638
639
640
641
642
643
    if (((x + width) <= 0) || ((y + height) <= 0)
	    || (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}

	return;
    }

    /*
     * Reposition and map the window (but in different ways depending on
     * whether the canvas is the window's parent).
     */

    if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
		|| (width != Tk_Width(winItemPtr->tkwin))
		|| (height != Tk_Height(winItemPtr->tkwin))) {
	    Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
	}


	Tk_MapWindow(winItemPtr->tkwin);


    } else {
	Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
		width, height);
    }

}

/*
 *--------------------------------------------------------------
 *
 * WinItemToPoint --
 *







>














>
>
|
>
>




>







610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
    if (((x + width) <= 0) || ((y + height) <= 0)
	    || (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tcl_Release(canvas);
	return;
    }

    /*
     * Reposition and map the window (but in different ways depending on
     * whether the canvas is the window's parent).
     */

    if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
		|| (width != Tk_Width(winItemPtr->tkwin))
		|| (height != Tk_Height(winItemPtr->tkwin))) {
	    Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
	}

	if (winItemPtr->tkwin) {
	    Tk_MapWindow(winItemPtr->tkwin);
	}

    } else {
	Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
		width, height);
    }
    Tcl_Release(canvas);
}

/*
 *--------------------------------------------------------------
 *
 * WinItemToPoint --
 *
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
 *	None.
 *
 *--------------------------------------------------------------
 */

static double
WinItemToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *pointPtr)		/* Pointer to x and y coordinates. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;
    (void)canvas;

    x1 = winItemPtr->header.x1;
    y1 = winItemPtr->header.y1;
    x2 = winItemPtr->header.x2;
    y2 = winItemPtr->header.y2;

    /*







|





<







659
660
661
662
663
664
665
666
667
668
669
670
671

672
673
674
675
676
677
678
 *	None.
 *
 *--------------------------------------------------------------
 */

static double
WinItemToPoint(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *pointPtr)		/* Pointer to x and y coordinates. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;


    x1 = winItemPtr->header.x1;
    y1 = winItemPtr->header.y1;
    x2 = winItemPtr->header.x2;
    y2 = winItemPtr->header.y2;

    /*
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
WinItemToArea(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area.  */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    (void)canvas;

    if ((rectPtr[2] <= winItemPtr->header.x1)
	    || (rectPtr[0] >= winItemPtr->header.x2)
	    || (rectPtr[3] <= winItemPtr->header.y1)
	    || (rectPtr[1] >= winItemPtr->header.y2)) {
	return -1;
    }







|






<







715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
WinItemToArea(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area.  */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;


    if ((rectPtr[2] <= winItemPtr->header.x1)
	    || (rectPtr[0] >= winItemPtr->header.x2)
	    || (rectPtr[3] <= winItemPtr->header.y1)
	    || (rectPtr[1] >= winItemPtr->header.y2)) {
	return -1;
    }
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
 *
 *--------------------------------------------------------------
 */

#ifdef X_GetImage
static int
xerrorhandler(
    ClientData dummy,
    XErrorEvent *e)
{
    (void)dummy;
    (void)e;

    return 0;
}
#endif /* X_GetImage */

/*
 *--------------------------------------------------------------
 *







|
|

<
<
<







758
759
760
761
762
763
764
765
766
767



768
769
770
771
772
773
774
 *
 *--------------------------------------------------------------
 */

#ifdef X_GetImage
static int
xerrorhandler(
    TCL_UNUSED(void *),
    TCL_UNUSED(XErrorEvent *))
{



    return 0;
}
#endif /* X_GetImage */

/*
 *--------------------------------------------------------------
 *
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
    case TK_ANCHOR_N:	    x -= width/2.0; y -= height;	    break;
    case TK_ANCHOR_NE:	    x -= width;	    y -= height;	    break;
    case TK_ANCHOR_E:	    x -= width;	    y -= height/2.0;	    break;
    case TK_ANCHOR_SE:	    x -= width;				    break;
    case TK_ANCHOR_S:	    x -= width/2.0;			    break;
    case TK_ANCHOR_SW:						    break;
    case TK_ANCHOR_W:			    y -= height/2.0;	    break;
    case TK_ANCHOR_CENTER:  x -= width/2.0; y -= height/2.0;	    break;
    }

    return CanvasPsWindow(interp, tkwin, canvas, x, y, width, height);
}

static int
CanvasPsWindow(







|







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
    case TK_ANCHOR_N:	    x -= width/2.0; y -= height;	    break;
    case TK_ANCHOR_NE:	    x -= width;	    y -= height;	    break;
    case TK_ANCHOR_E:	    x -= width;	    y -= height/2.0;	    break;
    case TK_ANCHOR_SE:	    x -= width;				    break;
    case TK_ANCHOR_S:	    x -= width/2.0;			    break;
    case TK_ANCHOR_SW:						    break;
    case TK_ANCHOR_W:			    y -= height/2.0;	    break;
    default:  x -= width/2.0; y -= height/2.0;	    break;
    }

    return CanvasPsWindow(interp, tkwin, canvas, x, y, width, height);
}

static int
CanvasPsWindow(
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
    if (result == TCL_OK) {
	Tcl_AppendPrintfToObj(psObj,
		"50 dict begin\nsave\ngsave\n"
		"0 %d moveto %d 0 rlineto 0 -%d rlineto -%d 0 rlineto closepath\n"
		"1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n",
		height, width, height, width);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	Tcl_AppendToObj(psObj, "\nrestore\nend\n\n\n", -1);
	goto done;
    }

    /*
     * If the window is off the screen it will generate a BadMatch/XError. We
     * catch any BadMatch errors here
     */







|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
    if (result == TCL_OK) {
	Tcl_AppendPrintfToObj(psObj,
		"50 dict begin\nsave\ngsave\n"
		"0 %d moveto %d 0 rlineto 0 -%d rlineto -%d 0 rlineto closepath\n"
		"1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n",
		height, width, height, width);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	Tcl_AppendToObj(psObj, "\nrestore\nend\n\n\n", TCL_INDEX_NONE);
	goto done;
    }

    /*
     * If the window is off the screen it will generate a BadMatch/XError. We
     * catch any BadMatch errors here
     */
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
 *	The window is disassociated from the window item when it is deleted.
 *
 *--------------------------------------------------------------
 */

static void
WinItemStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;

    if (eventPtr->type == DestroyNotify) {
	winItemPtr->tkwin = NULL;
    }







|







1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
 *	The window is disassociated from the window item when it is deleted.
 *
 *--------------------------------------------------------------
 */

static void
WinItemStructureProc(
    void *clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;

    if (eventPtr->type == DestroyNotify) {
	winItemPtr->tkwin = NULL;
    }
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
 *	depending on the options specified for the window item.
 *
 *--------------------------------------------------------------
 */

static void
WinItemRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    (void)tkwin;

    ComputeWindowBbox(winItemPtr->canvas, winItemPtr);

    /*
     * A drawable argument of None to DisplayWinItem is used by the canvas
     * UnmapNotify handler to indicate that we should no longer display
     * ourselves, so need to pass a (bogus) non-zero drawable value here.







|
|


<







1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
 *	depending on the options specified for the window item.
 *
 *--------------------------------------------------------------
 */

static void
WinItemRequestProc(
    void *clientData,	/* Pointer to record for window item. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;


    ComputeWindowBbox(winItemPtr->canvas, winItemPtr);

    /*
     * A drawable argument of None to DisplayWinItem is used by the canvas
     * UnmapNotify handler to indicate that we should no longer display
     * ourselves, so need to pass a (bogus) non-zero drawable value here.
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
WinItemLostContentProc(
    ClientData clientData,	/* WindowItem structure for content window window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
    (void)tkwin;

    Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
	    WinItemStructureProc, winItemPtr);
    if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
    }
    Tk_UnmapWindow(winItemPtr->tkwin);







|

|



<







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
WinItemLostContentProc(
    void *clientData,	/* WindowItem structure for content window window that
				 * was stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);


    Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
	    WinItemStructureProc, winItemPtr);
    if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
    }
    Tk_UnmapWindow(winItemPtr->tkwin);

Changes to generic/tkCanvas.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


23
24
25
26
27
28
29
30
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"
#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif


#endif /* TK_NO_DOUBLE_BUFFERING */

/*
 * See tkCanvas.h for key data structures used to implement canvases.
 */

/*
 * The structure defined below is used to keep track of a tag search in







|
|
|








|



>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * 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 © 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"
#include "default.h"
#include "tkPort.h"
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif
#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * See tkCanvas.h for key data structures used to implement canvases.
 */

/*
 * The structure defined below is used to keep track of a tag search in
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    Tk_Item *currentPtr;	/* Pointer to last item returned. */
    Tk_Item *lastPtr;		/* The item right before the currentPtr is
				 * tracked so if the currentPtr is deleted we
				 * don't have to start from the beginning. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
    int type;			/* Search type (see #defs below) */
    TkSizeT id;			/* Item id for searches by id */
    const char *string;		/* Tag expression string */
    int stringIndex;		/* Current position in string scan */
    int stringLength;		/* Length of tag expression string */
    char *rewritebuffer;	/* Tag string (after removing escapes) */
    unsigned int rewritebufferAllocated;
				/* Available space for rewrites. */
    TagSearchExpr *expr;	/* Compiled tag expression. */







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    Tk_Item *currentPtr;	/* Pointer to last item returned. */
    Tk_Item *lastPtr;		/* The item right before the currentPtr is
				 * tracked so if the currentPtr is deleted we
				 * don't have to start from the beginning. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
    int type;			/* Search type (see #defs below) */
    Tcl_Size id;			/* Item id for searches by id */
    const char *string;		/* Tag expression string */
    int stringIndex;		/* Current position in string scan */
    int stringLength;		/* Length of tag expression string */
    char *rewritebuffer;	/* Tag string (after removing escapes) */
    unsigned int rewritebufferAllocated;
				/* Available space for rewrites. */
    TagSearchExpr *expr;	/* Compiled tag expression. */
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
static Tcl_ThreadDataKey dataKey;
static SearchUids *	GetStaticUids(void);

/*
 * Prototypes for functions defined later in this file:
 */

static void		CanvasBindProc(ClientData clientData,
			    XEvent *eventPtr);
static void		CanvasBlinkProc(ClientData clientData);
static void		CanvasCmdDeletedProc(ClientData clientData);
static void		CanvasDoEvent(TkCanvas *canvasPtr, XEvent *eventPtr);
static void		CanvasEventProc(ClientData clientData,
			    XEvent *eventPtr);
static TkSizeT	CanvasFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT maxBytes);
static Tk_Item *	CanvasFindClosest(TkCanvas *canvasPtr,
			    double coords[2]);
static void		CanvasFocusProc(TkCanvas *canvasPtr, int gotFocus);
static void		CanvasLostSelection(ClientData clientData);
static void		CanvasSelectTo(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, TkSizeT index);
static void		CanvasSetOrigin(TkCanvas *canvasPtr,
			    int xOrigin, int yOrigin);
static void		CanvasUpdateScrollbars(TkCanvas *canvasPtr);
static int		CanvasWidgetCmd(ClientData clientData,
			    Tcl_Interp *interp, int argc,
			    Tcl_Obj *const *argv);
static void		CanvasWorldChanged(ClientData instanceData);
static int		ConfigureCanvas(Tcl_Interp *interp,
			    TkCanvas *canvasPtr, int argc,
			    Tcl_Obj *const *argv, int flags);
static void		DefaultRotateImplementation(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, double x, double y,
			    double angleRadians);
static void		DestroyCanvas(void *memPtr);
static int		DrawCanvas(Tcl_Interp *interp, ClientData clientData, Tk_PhotoHandle photohandle, int subsample, int zoom);
static void		DisplayCanvas(ClientData clientData);
static void		DoItem(Tcl_Obj *accumObj,
			    Tk_Item *itemPtr, Tk_Uid tag);
static void		EventuallyRedrawItem(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr);
static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int argc, Tcl_Obj *const *argv,
			    Tcl_Obj *newTagObj, int first,
			    TagSearch **searchPtrPtr);
static int		FindArea(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    Tcl_Obj *const *argv, Tk_Uid uid, int enclosed);
static double		GridAlign(double coord, double spacing);
static const char**	TkGetStringsFromObjs(int argc, Tcl_Obj *const *objv);
static void		InitCanvas(void);
static void		PickCurrentItem(TkCanvas *canvasPtr, XEvent *eventPtr);
static Tcl_Obj *	ScrollFractions(int screen1,
			    int screen2, int object1, int object2);
static int		RelinkItems(TkCanvas *canvasPtr, Tcl_Obj *tag,
			    Tk_Item *prevPtr, TagSearch **searchPtrPtr);
static void 		TagSearchExprInit(TagSearchExpr **exprPtrPtr);







|

|
|

|

|
|



|

|



|
|
|
|

|
|



|
|
|





|
|


|

<







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
static Tcl_ThreadDataKey dataKey;
static SearchUids *	GetStaticUids(void);

/*
 * Prototypes for functions defined later in this file:
 */

static void		CanvasBindProc(void *clientData,
			    XEvent *eventPtr);
static void		CanvasBlinkProc(void *clientData);
static void		CanvasCmdDeletedProc(void *clientData);
static void		CanvasDoEvent(TkCanvas *canvasPtr, XEvent *eventPtr);
static void		CanvasEventProc(void *clientData,
			    XEvent *eventPtr);
static Tcl_Size	CanvasFetchSelection(void *clientData, Tcl_Size offset,
			    char *buffer, Tcl_Size maxBytes);
static Tk_Item *	CanvasFindClosest(TkCanvas *canvasPtr,
			    double coords[2]);
static void		CanvasFocusProc(TkCanvas *canvasPtr, int gotFocus);
static void		CanvasLostSelection(void *clientData);
static void		CanvasSelectTo(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, Tcl_Size index);
static void		CanvasSetOrigin(TkCanvas *canvasPtr,
			    int xOrigin, int yOrigin);
static void		CanvasUpdateScrollbars(TkCanvas *canvasPtr);
static int		CanvasWidgetCmd(void *clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);
static void		CanvasWorldChanged(void *instanceData);
static int		ConfigureCanvas(Tcl_Interp *interp,
			    TkCanvas *canvasPtr, Tcl_Size objc,
			    Tcl_Obj *const *objv, int flags);
static void		DefaultRotateImplementation(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, double x, double y,
			    double angleRadians);
static Tcl_FreeProc	DestroyCanvas;
static int		DrawCanvas(Tcl_Interp *interp, void *clientData, Tk_PhotoHandle photohandle, int subsample, int zoom);
static void		DisplayCanvas(void *clientData);
static void		DoItem(Tcl_Obj *accumObj,
			    Tk_Item *itemPtr, Tk_Uid tag);
static void		EventuallyRedrawItem(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr);
static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    Tcl_Size objc, Tcl_Obj *const *objv,
			    Tcl_Obj *newTagObj, Tcl_Size first,
			    TagSearch **searchPtrPtr);
static int		FindArea(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    Tcl_Obj *const *objv, Tk_Uid uid, int enclosed);
static double		GridAlign(double coord, double spacing);

static void		InitCanvas(void);
static void		PickCurrentItem(TkCanvas *canvasPtr, XEvent *eventPtr);
static Tcl_Obj *	ScrollFractions(int screen1,
			    int screen2, int object1, int object2);
static int		RelinkItems(TkCanvas *canvasPtr, Tcl_Obj *tag,
			    Tk_Item *prevPtr, TagSearch **searchPtrPtr);
static void 		TagSearchExprInit(TagSearchExpr **exprPtrPtr);
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
 * ----------------------------------------------------------------------
 */

static inline int
AlwaysRedraw(
    Tk_Item *itemPtr)
{
    return itemPtr->typePtr->alwaysRedraw & 1;
}

static inline int
ItemConfigure(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, objv, TK_CONFIG_ARGV_ONLY);
    } else {
	const char **args = TkGetStringsFromObjs(objc, objv);

	result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY);
	if (args != NULL) {
	    ckfree(args);
	}
    }
    return result;
}

static inline int
ItemConfigInfo(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *fieldName)
{
    return Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin,
	    itemPtr->typePtr->configSpecs, (char *) itemPtr,
	    (fieldName ? Tcl_GetString(fieldName) : NULL), 0);
}

static inline int
ItemConfigValue(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *fieldName)
{
    return Tk_ConfigureValue(canvasPtr->interp, canvasPtr->tkwin,
	    itemPtr->typePtr->configSpecs, (char *) itemPtr,
	    Tcl_GetString(fieldName), 0);
}

static inline int
ItemCoords(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->coordProc == NULL) {
	result = TCL_OK;
    } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, objv);
    } else {
	const char **args = TkGetStringsFromObjs(objc, objv);

	result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, (Tcl_Obj **) args);
	if (args != NULL) {
	    ckfree(args);
	}
    }
    return result;
}

static inline int
ItemCreate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,		/* Warning: incomplete! typePtr field must be
				 * set by this point. */
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	result = itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc-3, objv+3);
    } else {
	const char **args = TkGetStringsFromObjs(objc-3, objv+3);

	result = itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc-3, (Tcl_Obj **) args);
	if (args != NULL) {
	    ckfree(args);
	}
    }
    return result;
}

static inline void
ItemCursor(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int index)







|






|



<

<
|
|
<
<
<
<
<
<
<
<
<
<









|










|







|







<
<
<

<
<

|
<
<
<









|



<

<
|

<
<
<
<
<
<
<
<
<
<







321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

339

340
341










342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377



378


379
380



381
382
383
384
385
386
387
388
389
390
391
392
393

394

395
396










397
398
399
400
401
402
403
 * ----------------------------------------------------------------------
 */

static inline int
AlwaysRedraw(
    Tk_Item *itemPtr)
{
    return itemPtr->typePtr->flags & TK_ALWAYS_REDRAW;
}

static inline int
ItemConfigure(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;



    return itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
	    itemPtr, objc, objv, TK_CONFIG_ARGV_ONLY);










}

static inline int
ItemConfigInfo(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *fieldName)
{
    return Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin,
	    itemPtr->typePtr->configSpecs, itemPtr,
	    (fieldName ? Tcl_GetString(fieldName) : NULL), 0);
}

static inline int
ItemConfigValue(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *fieldName)
{
    return Tk_ConfigureValue(canvasPtr->interp, canvasPtr->tkwin,
	    itemPtr->typePtr->configSpecs, itemPtr,
	    Tcl_GetString(fieldName), 0);
}

static inline int
ItemCoords(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;
    int result;

    if (itemPtr->typePtr->coordProc == NULL) {
	result = TCL_OK;



    } else {


	result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc, objv);



    }
    return result;
}

static inline int
ItemCreate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,		/* Warning: incomplete! typePtr field must be
				 * set by this point. */
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Tcl_Interp *interp = canvasPtr->interp;



	return itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objc-3, objv+3);










}

static inline void
ItemCursor(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int index)
468
469
470
471
472
473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
}

static int
ItemIndex(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *objPtr,
    TkSizeT *indexPtr)
{
    Tcl_Interp *interp = canvasPtr->interp;

    if (itemPtr->typePtr->indexProc == NULL) {
	return TCL_OK;
    } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {

	return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, objPtr, indexPtr);
    } else {
	return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
		itemPtr, (Tcl_Obj *) Tcl_GetString(objPtr), indexPtr);
    }
}

static inline void
ItemInsert(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int beforeThis,
    Tcl_Obj *toInsert)
{
    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
		beforeThis, toInsert);
    } else {
	itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
		beforeThis, (Tcl_Obj *) Tcl_GetString(toInsert));
    }
}

static inline int
ItemOverlap(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double rect[])







|





<
>
|
|
<
<
<
<









<
|
|
<
<
<
<







437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452




453
454
455
456
457
458
459
460
461

462
463




464
465
466
467
468
469
470
}

static int
ItemIndex(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *objPtr,
    Tcl_Size *indexPtr)
{
    Tcl_Interp *interp = canvasPtr->interp;

    if (itemPtr->typePtr->indexProc == NULL) {
	return TCL_OK;

    }
    return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
	    itemPtr, objPtr, indexPtr);




}

static inline void
ItemInsert(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int beforeThis,
    Tcl_Obj *toInsert)
{

    itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
	    beforeThis, toInsert);




}

static inline int
ItemOverlap(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double rect[])
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
    double xOrigin, double yOrigin,
    double xScale, double yScale)
{
    itemPtr->typePtr->scaleProc((Tk_Canvas) canvasPtr, itemPtr,
	    xOrigin, yOrigin, xScale, yScale);
}

static inline int
ItemSelection(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int offset,
    char *buffer,
    int maxBytes)
{
    if (itemPtr == NULL || itemPtr->typePtr->selectionProc == NULL) {
	return -1;
    }

    return itemPtr->typePtr->selectionProc((Tk_Canvas) canvasPtr, itemPtr,
	    offset, buffer, maxBytes);
}

static inline void
ItemTranslate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double xDelta,







|





|


|



|







493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
    double xOrigin, double yOrigin,
    double xScale, double yScale)
{
    itemPtr->typePtr->scaleProc((Tk_Canvas) canvasPtr, itemPtr,
	    xOrigin, yOrigin, xScale, yScale);
}

static inline Tcl_Size
ItemSelection(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    int offset,
    char *buffer,
    Tcl_Size maxBytes)
{
    if (itemPtr == NULL || itemPtr->typePtr->selectionProc == NULL) {
	return TCL_INDEX_NONE;
    }

    return itemPtr->typePtr->selectionProc((Tk_Canvas) canvasPtr, itemPtr,
	    offset, buffer, (int)maxBytes);
}

static inline void
ItemTranslate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double xDelta,
595
596
597
598
599
600
601

602
603
604
605
606
607
608
609
DefaultRotateImplementation(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double x,
    double y,
    double angleRadians)
{

    int objc, i, ok = 1;
    Tcl_Obj **objv, **newObjv;
    double *coordv;
    double s = sin(angleRadians);
    double c = cos(angleRadians);
    Tcl_Interp *interp = canvasPtr->interp;

    /*







>
|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
DefaultRotateImplementation(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double x,
    double y,
    double angleRadians)
{
    Tcl_Size i, objc;
    int ok = 1;
    Tcl_Obj **objv, **newObjv;
    double *coordv;
    double s = sin(angleRadians);
    double c = cos(angleRadians);
    Tcl_Interp *interp = canvasPtr->interp;

    /*
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
		newObjv[i] = Tcl_NewDoubleObj(coordv[i]);
		Tcl_IncrRefCount(newObjv[i]);
	    }
	    ItemCoords(canvasPtr, itemPtr, objc, newObjv);
	    for (i=0 ; i<objc ; i++) {
		Tcl_DecrRefCount(newObjv[i]);
	    }
	    ckfree((char *) newObjv);
	}
	ckfree((char *) coordv);
    }

    /*
     * The interpreter result was (probably) modified above; reset it.
     */

    Tcl_ResetResult(interp);







|

|







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
		newObjv[i] = Tcl_NewDoubleObj(coordv[i]);
		Tcl_IncrRefCount(newObjv[i]);
	    }
	    ItemCoords(canvasPtr, itemPtr, objc, newObjv);
	    for (i=0 ; i<objc ; i++) {
		Tcl_DecrRefCount(newObjv[i]);
	    }
	    ckfree(newObjv);
	}
	ckfree(coordv);
    }

    /*
     * The interpreter result was (probably) modified above; reset it.
     */

    Tcl_ResetResult(interp);
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    Tcl_Obj *const argv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkCanvas *canvasPtr;
    Tk_Window newWin;

    if (typeList == NULL) {
	InitCanvas();
    }

    if (argc < 2) {
	Tcl_WrongNumArgs(interp, 1, argv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    newWin = Tk_CreateWindowFromPath(interp,tkwin,Tcl_GetString(argv[1]),NULL);
    if (newWin == NULL) {
	return TCL_ERROR;
    }

    /*
     * Initialize fields that won't be initialized by ConfigureCanvas, or
     * which ConfigureCanvas expects to have reasonable values (e.g. resource







|

|
|









|
|



|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkCanvas *canvasPtr;
    Tk_Window newWin;

    if (typeList == NULL) {
	InitCanvas();
    }

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    newWin = Tk_CreateWindowFromPath(interp,tkwin,Tcl_GetString(objv[1]),NULL);
    if (newWin == NULL) {
	return TCL_ERROR;
    }

    /*
     * Initialize fields that won't be initialized by ConfigureCanvas, or
     * which ConfigureCanvas expects to have reasonable values (e.g. resource
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
	    CanvasEventProc, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    CanvasBindProc, canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:







|







752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
	    CanvasEventProc, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    CanvasBindProc, canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, objc-2, objv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
CanvasWidgetCmd(
    ClientData clientData,	/* Information about canvas widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    int c, result;
    Tk_Item *itemPtr = NULL;	/* Initialization needed only to prevent







|







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
CanvasWidgetCmd(
    void *clientData,	/* Information about canvas widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    int c, result;
    Tk_Item *itemPtr = NULL;	/* Initialization needed only to prevent
883
884
885
886
887
888
889
890

891
892
893
894
895
896
897
	    result = TCL_ERROR;
	    goto done;
	}
	result = FIND_ITEMS(objv[2], 3);
	break;

    case CANV_BBOX: {
	int i, gotAny;

	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;	/* Initializations needed only
						 * to prevent overcautious
						 * compiler warnings. */

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?tagOrId ...?");
	    result = TCL_ERROR;







|
>







844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
	    result = TCL_ERROR;
	    goto done;
	}
	result = FIND_ITEMS(objv[2], 3);
	break;

    case CANV_BBOX: {
	int gotAny;
	Tcl_Size i;
	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;	/* Initializations needed only
						 * to prevent overcautious
						 * compiler warnings. */

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?tagOrId ...?");
	    result = TCL_ERROR;
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"requested illegal events; only key, button, motion,"
			" enter, leave, and virtual events may be used", -1));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_EVENTS", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else if (objc == 4) {
	    const char *command;








|







1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"requested illegal events; only key, button, motion,"
			" enter, leave, and virtual events may be used", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_EVENTS", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else if (objc == 4) {
	    const char *command;

1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080

		if (string[0] != '\0') {
		    result = TCL_ERROR;
		    goto done;
		}
		Tcl_ResetResult(interp);
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
	    }
	} else {
	    Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
	}
	break;
    }
    case CANV_CANVASX: {







|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042

		if (string[0] != '\0') {
		    result = TCL_ERROR;
		    goto done;
		}
		Tcl_ResetResult(interp);
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(command, TCL_INDEX_NONE));
	    }
	} else {
	    Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
	}
	break;
    }
    case CANV_CANVASX: {
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
    case CANV_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	result = Tk_ConfigureValue(interp, canvasPtr->tkwin, configSpecs,
		(char *) canvasPtr, Tcl_GetString(objv[2]), 0);
	break;
    case CANV_CONFIGURE:
	if (objc == 2) {
	    result = Tk_ConfigureInfo(interp, canvasPtr->tkwin, configSpecs,
		    (char *) canvasPtr, NULL, 0);
	} else if (objc == 3) {
	    result = Tk_ConfigureInfo(interp, canvasPtr->tkwin, configSpecs,
		    (char *) canvasPtr, Tcl_GetString(objv[2]), 0);
	} else {
	    result = ConfigureCanvas(interp, canvasPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
	break;
    case CANV_COORDS:
	if (objc < 3) {







|




|


|







1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
    case CANV_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	result = Tk_ConfigureValue(interp, canvasPtr->tkwin, configSpecs,
		canvasPtr, Tcl_GetString(objv[2]), 0);
	break;
    case CANV_CONFIGURE:
	if (objc == 2) {
	    result = Tk_ConfigureInfo(interp, canvasPtr->tkwin, configSpecs,
		    canvasPtr, NULL, 0);
	} else if (objc == 3) {
	    result = Tk_ConfigureInfo(interp, canvasPtr->tkwin, configSpecs,
		    canvasPtr, Tcl_GetString(objv[2]), 0);
	} else {
	    result = ConfigureCanvas(interp, canvasPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
	break;
    case CANV_COORDS:
	if (objc < 3) {
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
	 * Make a temporary object here that we can reuse for all the
	 * modifications in the loop.
	 */

	tmpObj = Tcl_NewListObj(2, objv+4);

	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {
	    TkSizeT index;
	    int x1, x2, y1, y2;
	    int dontRedraw1, dontRedraw2;

	    /*
	     * The TK_MOVABLE_POINTS flag should only be set for types that
	     * support the same semantics of index, dChars and insert methods
	     * as lines and canvases.
	     */

	    if (itemPtr == NULL ||
		    !(itemPtr->typePtr->alwaysRedraw & TK_MOVABLE_POINTS)) {
		continue;
	    }

	    result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);
	    if (result != TCL_OK) {
		break;
	    }







|










|







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
	 * Make a temporary object here that we can reuse for all the
	 * modifications in the loop.
	 */

	tmpObj = Tcl_NewListObj(2, objv+4);

	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {
	    Tcl_Size index;
	    int x1, x2, y1, y2;
	    int dontRedraw1, dontRedraw2;

	    /*
	     * The TK_MOVABLE_POINTS flag should only be set for types that
	     * support the same semantics of index, dChars and insert methods
	     * as lines and canvases.
	     */

	    if (itemPtr == NULL ||
		    !(itemPtr->typePtr->flags & TK_MOVABLE_POINTS)) {
		continue;
	    }

	    result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);
	    if (result != TCL_OK) {
		break;
	    }
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
    }
    case CANV_CREATE: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;
	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	const char *arg;
	TkSizeT length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	c = arg[0];

	/*
	 * Lock because the list of types is a global resource that could be
	 * updated by another thread. That's fairly unlikely, but not
	 * impossible.
	 */







|






|







1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
    }
    case CANV_CREATE: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;
	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	const char *arg;
	Tcl_Size length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	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.
	 */
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
	itemPtr->redraw_flags |= FORCE_REDRAW;
	EventuallyRedrawItem(canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(itemPtr->id));
	break;
    }
    case CANV_DCHARS: {
	TkSizeT first, last;
	int x1, x2, y1, y2;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
	    result = TCL_ERROR;
	    goto done;
	}







|







1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
	itemPtr->redraw_flags |= FORCE_REDRAW;
	EventuallyRedrawItem(canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(itemPtr->id));
	break;
    }
    case CANV_DCHARS: {
	Tcl_Size first, last;
	int x1, x2, y1, y2;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
	    result = TCL_ERROR;
	    goto done;
	}
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_DELETE: {
	int i;
	Tcl_HashEntry *entryPtr;

	for (i = 2; i < objc; i++) {
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
		if (canvasPtr->bindingTable != NULL) {
		    Tk_DeleteAllBindings(canvasPtr->bindingTable, itemPtr);







|







1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_DELETE: {
	Tcl_Size i;
	Tcl_HashEntry *entryPtr;

	for (i = 2; i < objc; i++) {
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
		if (canvasPtr->bindingTable != NULL) {
		    Tk_DeleteAllBindings(canvasPtr->bindingTable, itemPtr);
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
		}
	    }
	}
	break;
    }
    case CANV_DTAG: {
	Tk_Uid tag;
	int i;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?tagToDelete?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc == 4) {
	    tag = Tk_GetUid(Tcl_GetString(objv[3]));
	} else {
	    tag = Tk_GetUid(Tcl_GetString(objv[2]));
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    for (i = (int)itemPtr->numTags-1; i >= 0; i--) {
		if (itemPtr->tagPtr[i] == tag) {

                    /*
                     * Don't shuffle the tags sequence: memmove the tags.
                     */

                    memmove((void *)(itemPtr->tagPtr + i),







|












|







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
		}
	    }
	}
	break;
    }
    case CANV_DTAG: {
	Tk_Uid tag;
	Tcl_Size i;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?tagToDelete?");
	    result = TCL_ERROR;
	    goto done;
	}
	if (objc == 4) {
	    tag = Tk_GetUid(Tcl_GetString(objv[3]));
	} else {
	    tag = Tk_GetUid(Tcl_GetString(objv[2]));
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    for (i = itemPtr->numTags-1; i != TCL_INDEX_NONE; i--) {
		if (itemPtr->tagPtr[i] == tag) {

                    /*
                     * Don't shuffle the tags sequence: memmove the tags.
                     */

                    memmove((void *)(itemPtr->tagPtr + i),
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    int i;
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (i = 0; i < (int)itemPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(itemPtr->tagPtr[i], -1));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    case CANV_ICURSOR: {
	TkSizeT index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {







|





|







1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    int i;
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (i = 0; i < (int)itemPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(itemPtr->tagPtr[i], TCL_INDEX_NONE));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    case CANV_ICURSOR: {
	Tcl_Size index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
		    && (canvasPtr->textInfo.cursorOn)) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	}
	break;
    }
    case CANV_INDEX: {
	TkSizeT index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {







|







1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
		    && (canvasPtr->textInfo.cursorOn)) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	}
	break;
    }
    case CANV_INDEX: {
	Tcl_Size index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
	if (result != TCL_OK) {
	    goto done;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	break;
    }
    case CANV_INSERT: {
	TkSizeT beforeThis;
	int x1, x2, y1, y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}







|







1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
	if (result != TCL_OK) {
	    goto done;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	break;
    }
    case CANV_INSERT: {
	Tcl_Size beforeThis;
	int x1, x2, y1, y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
		EventuallyRedrawItem(canvasPtr, itemPtr);
		canvasPtr->flags |= REPICK_NEEDED;
	    }
	}
	break;
    }
    case CANV_POSTSCRIPT: {
	const char **args = TkGetStringsFromObjs(objc, objv);

	result = TkCanvPostscriptCmd(canvasPtr, interp, objc, args);
	if (args != NULL) {
	    ckfree(args);
	}
	break;
    }
    case CANV_RAISE: {
	Tk_Item *prevPtr;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?aboveThis?");







<
<
|
<
<
<







1729
1730
1731
1732
1733
1734
1735


1736



1737
1738
1739
1740
1741
1742
1743
		EventuallyRedrawItem(canvasPtr, itemPtr);
		canvasPtr->flags |= REPICK_NEEDED;
	    }
	}
	break;
    }
    case CANV_POSTSCRIPT: {


	result = TkCanvPostscriptObjCmd(canvasPtr, interp, objc, objv);



	break;
    }
    case CANV_RAISE: {
	Tk_Item *prevPtr;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?aboveThis?");
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
		goto done;
	    }
	}
	RELINK_ITEMS(objv[2], prevPtr);
	break;
    }
    case CANV_RCHARS: {
	TkSizeT first, last;
	int x1, x2, y1, y2;
	int dontRedraw1, dontRedraw2;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
	    result = TCL_ERROR;
	    goto done;







|







1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
		goto done;
	    }
	}
	RELINK_ITEMS(objv[2], prevPtr);
	break;
    }
    case CANV_RCHARS: {
	Tcl_Size first, last;
	int x1, x2, y1, y2;
	int dontRedraw1, dontRedraw2;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
	    result = TCL_ERROR;
	    goto done;
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
		|| (Tcl_GetDoubleFromObj(interp, objv[5], &xScale)!=TCL_OK)
		|| (Tcl_GetDoubleFromObj(interp, objv[6], &yScale)!=TCL_OK)) {
	    result = TCL_ERROR;
	    goto done;
	}
	if ((xScale == 0.0) || (yScale == 0.0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "scale factor cannot be zero", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_SCALE", NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    ItemScale(canvasPtr, itemPtr, xOrigin, yOrigin, xScale, yScale);
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_SCAN: {
	int x, y, gain = 10;
	static const char *const optionStrings[] = {
	    "mark", "dragto", NULL
	};

	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?dragGain?");
	    result = TCL_ERROR;
	} else if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
		"scan option", 0, &idx) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc != 5+idx)) {
	    Tcl_WrongNumArgs(interp, 3, objv, idx?"x y ?gain?":"x y");
	    result = TCL_ERROR;
	} else if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    result = TCL_ERROR;
	} else if ((objc == 6) &&
		(Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
	    result = TCL_ERROR;
	} else if (!idx) {
	    canvasPtr->scanX = x;
	    canvasPtr->scanXOrigin = canvasPtr->xOrigin;
	    canvasPtr->scanY = y;
	    canvasPtr->scanYOrigin = canvasPtr->yOrigin;
	} else {
	    int newXOrigin, newYOrigin, tmp;








|















|








|
|







|







1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
		|| (Tcl_GetDoubleFromObj(interp, objv[5], &xScale)!=TCL_OK)
		|| (Tcl_GetDoubleFromObj(interp, objv[6], &yScale)!=TCL_OK)) {
	    result = TCL_ERROR;
	    goto done;
	}
	if ((xScale == 0.0) || (yScale == 0.0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "scale factor cannot be zero", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_SCALE", NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    ItemScale(canvasPtr, itemPtr, xOrigin, yOrigin, xScale, yScale);
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_SCAN: {
	int x, y, gain = 10;
	static const char *const optionStrings[] = {
	    "dragto", "mark", NULL
	};

	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?dragGain?");
	    result = TCL_ERROR;
	} else if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
		"scan option", 0, &idx) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc + idx != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, idx?"x y":"x y ?gain?");
	    result = TCL_ERROR;
	} else if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    result = TCL_ERROR;
	} else if ((objc == 6) &&
		(Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
	    result = TCL_ERROR;
	} else if (idx) {
	    canvasPtr->scanX = x;
	    canvasPtr->scanXOrigin = canvasPtr->xOrigin;
	    canvasPtr->scanY = y;
	    canvasPtr->scanYOrigin = canvasPtr->yOrigin;
	} else {
	    int newXOrigin, newYOrigin, tmp;

1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
		    - canvasPtr->scrollY1;
	    newYOrigin = canvasPtr->scrollY1 + tmp;
	    CanvasSetOrigin(canvasPtr, newXOrigin, newYOrigin);
	}
	break;
    }
    case CANV_SELECT: {
	TkSizeT index;
	int optionindex;
	static const char *const optionStrings[] = {
	    "adjust", "clear", "from", "item", "to", NULL
	};
	enum options {
	    CANV_ADJUST, CANV_CLEAR, CANV_FROM, CANV_ITEM, CANV_TO
	};







|







1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
		    - canvasPtr->scrollY1;
	    newYOrigin = canvasPtr->scrollY1 + tmp;
	    CanvasSetOrigin(canvasPtr, newXOrigin, newYOrigin);
	}
	break;
    }
    case CANV_SELECT: {
	Tcl_Size index;
	int optionindex;
	static const char *const optionStrings[] = {
	    "adjust", "clear", "from", "item", "to", NULL
	};
	enum options {
	    CANV_ADJUST, CANV_CLEAR, CANV_FROM, CANV_ITEM, CANV_TO
	};
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
	    Tcl_WrongNumArgs(interp, 2, objv, "tag");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(itemPtr->typePtr->name, -1));
	}
	break;
    case CANV_XVIEW: {
	int count, type;
	int newX = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;
	const char **args;

	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->xOrigin + canvasPtr->inset,
		    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)
		    - canvasPtr->inset, canvasPtr->scrollX1,
		    canvasPtr->scrollX2));
	    break;
	}

	args = TkGetStringsFromObjs(objc, objv);
	type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	if (args != NULL) {
	    ckfree(args);
	}
	switch (type) {
	case TK_SCROLL_ERROR:
	    result = TCL_ERROR;
	    goto done;
	case TK_SCROLL_MOVETO:
	    newX = canvasPtr->scrollX1 - canvasPtr->inset
		    + (int) (fraction * (canvasPtr->scrollX2
			    - canvasPtr->scrollX1) + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    newX = (int) (canvasPtr->xOrigin + count * .9
		    * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    break;
	case TK_SCROLL_UNITS:
	    if (canvasPtr->xScrollIncrement > 0) {
		newX = canvasPtr->xOrigin + count*canvasPtr->xScrollIncrement;
	    } else {
		newX = (int) (canvasPtr->xOrigin + count * .1
			* (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    }
	    break;



	}
	CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin);
	break;
    }
    case CANV_YVIEW: {
	int count, type;
	int newY = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;
	const char **args;

	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->yOrigin + canvasPtr->inset,
		    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
		    - canvasPtr->inset,
		    canvasPtr->scrollY1, canvasPtr->scrollY2));
	    break;
	}

	args = TkGetStringsFromObjs(objc, objv);
	type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	if (args != NULL) {
	    ckfree(args);
	}
	switch (type) {
	case TK_SCROLL_ERROR:
	    result = TCL_ERROR;
	    goto done;
	case TK_SCROLL_MOVETO:
	    newY = canvasPtr->scrollY1 - canvasPtr->inset + (int) (
		    fraction*(canvasPtr->scrollY2-canvasPtr->scrollY1) + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    newY = (int) (canvasPtr->yOrigin + count * .9
		    * (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    break;
	case TK_SCROLL_UNITS:
	    if (canvasPtr->yScrollIncrement > 0) {
		newY = canvasPtr->yOrigin + count*canvasPtr->yScrollIncrement;
	    } else {
		newY = (int) (canvasPtr->yOrigin + count * .1
			* (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    }
	    break;



	}
	CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
	break;
    }
    case CANV_IMAGE: {
        Tk_PhotoHandle photohandle;
        int subsample = 1, zoom = 1;







|







<










<
|
<
<
<

<
<
<

















>
>
>









<










<
|
<
<
<

<
<
<
















>
>
>







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
	    Tcl_WrongNumArgs(interp, 2, objv, "tag");
	    result = TCL_ERROR;
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(itemPtr->typePtr->name, TCL_INDEX_NONE));
	}
	break;
    case CANV_XVIEW: {
	int count, type;
	int newX = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;


	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->xOrigin + canvasPtr->inset,
		    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)
		    - canvasPtr->inset, canvasPtr->scrollX1,
		    canvasPtr->scrollX2));
	    break;
	}


	type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);



	switch (type) {



	case TK_SCROLL_MOVETO:
	    newX = canvasPtr->scrollX1 - canvasPtr->inset
		    + (int) (fraction * (canvasPtr->scrollX2
			    - canvasPtr->scrollX1) + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    newX = (int) (canvasPtr->xOrigin + count * .9
		    * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    break;
	case TK_SCROLL_UNITS:
	    if (canvasPtr->xScrollIncrement > 0) {
		newX = canvasPtr->xOrigin + count*canvasPtr->xScrollIncrement;
	    } else {
		newX = (int) (canvasPtr->xOrigin + count * .1
			* (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    }
	    break;
	default:
	    result = TCL_ERROR;
	    goto done;
	}
	CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin);
	break;
    }
    case CANV_YVIEW: {
	int count, type;
	int newY = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;


	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->yOrigin + canvasPtr->inset,
		    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
		    - canvasPtr->inset,
		    canvasPtr->scrollY1, canvasPtr->scrollY2));
	    break;
	}


	type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);



	switch (type) {



	case TK_SCROLL_MOVETO:
	    newY = canvasPtr->scrollY1 - canvasPtr->inset + (int) (
		    fraction*(canvasPtr->scrollY2-canvasPtr->scrollY1) + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    newY = (int) (canvasPtr->yOrigin + count * .9
		    * (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    break;
	case TK_SCROLL_UNITS:
	    if (canvasPtr->yScrollIncrement > 0) {
		newY = canvasPtr->yOrigin + count*canvasPtr->yScrollIncrement;
	    } else {
		newY = (int) (canvasPtr->yOrigin + count * .1
			* (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    }
	    break;
	default:
	    result = TCL_ERROR;
	    goto done;
	}
	CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
	break;
    }
    case CANV_IMAGE: {
        Tk_PhotoHandle photohandle;
        int subsample = 1, zoom = 1;
2228
2229
2230
2231
2232
2233
2234

2235



2236
2237
2238
2239
2240
2241
2242
 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(

    void *memPtr)		/* Info about canvas widget. */



{
    TkCanvas *canvasPtr = (TkCanvas *)memPtr;
    Tk_Item *itemPtr;
    TagSearchExpr *expr, *next;

    /*
     * Free up all of the items in the canvas.







>

>
>
>







2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Info about canvas widget. */
#else
    char *memPtr)
#endif
{
    TkCanvas *canvasPtr = (TkCanvas *)memPtr;
    Tk_Item *itemPtr;
    TagSearchExpr *expr, *next;

    /*
     * Free up all of the items in the canvas.
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
	TagSearchExprDestroy(expr);
	expr = next;
    }
    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (canvasPtr->bindingTable != NULL) {
	Tk_DeleteBindingTable(canvasPtr->bindingTable);
    }
    Tk_FreeOptions(configSpecs, (char *) canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree(canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *







|







2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
	TagSearchExprDestroy(expr);
	expr = next;
    }
    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (canvasPtr->bindingTable != NULL) {
	Tk_DeleteBindingTable(canvasPtr->bindingTable);
    }
    Tk_FreeOptions(configSpecs, canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree(canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *
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
ConfigureCanvas(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkCanvas *canvasPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    XGCValues gcValues;
    GC newGC;
    Tk_State old_canvas_state=canvasPtr->canvas_state;

    if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs,
	    objc, (const char **) objv, (char *) canvasPtr,
	    flags|TK_CONFIG_OBJS) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * A few options need special processing, such as setting the background
     * from a 3-D border and creating a GC for copying bits to the screen.
     */







|








|
|







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
 */

static int
ConfigureCanvas(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkCanvas *canvasPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    XGCValues gcValues;
    GC newGC;
    Tk_State old_canvas_state=canvasPtr->canvas_state;

    if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs,
	    objc, objv, canvasPtr,
	    flags) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * A few options need special processing, such as setting the background
     * from a 3-D border and creating a GC for copying bits to the screen.
     */
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
     */

    canvasPtr->scrollX1 = 0;
    canvasPtr->scrollY1 = 0;
    canvasPtr->scrollX2 = 0;
    canvasPtr->scrollY2 = 0;
    if (canvasPtr->regionString != NULL) {
	int argc2;
	const char **argv2;

	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,
		&argc2, &argv2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (argc2 != 4) {







|







2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
     */

    canvasPtr->scrollX1 = 0;
    canvasPtr->scrollY1 = 0;
    canvasPtr->scrollX2 = 0;
    canvasPtr->scrollY2 = 0;
    if (canvasPtr->regionString != NULL) {
	Tcl_Size argc2;
	const char **argv2;

	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,
		&argc2, &argv2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (argc2 != 4) {
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
 *	to be redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)instanceData;
    Tk_Item *itemPtr;

    itemPtr = canvasPtr->firstItemPtr;
    for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) {
	if (ItemConfigure(canvasPtr, itemPtr, 0, NULL) != TCL_OK) {







|







2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
 *	to be redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)instanceData;
    Tk_Item *itemPtr;

    itemPtr = canvasPtr->firstItemPtr;
    for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) {
	if (ItemConfigure(canvasPtr, itemPtr, 0, NULL) != TCL_OK) {
2562
2563
2564
2565
2566
2567
2568
2569
2570



2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
 *
 *----------------------------------------------------------------------
 */

#define OVERDRAW_PIXELS 32        /* How much larger we make the pixmap
                                   * that the canvas objects are drawn into */

/* From stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine */
#define IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100)




#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8))
#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000))

static int
DrawCanvas(
    Tcl_Interp *interp,           /* As passed to the widget command, and we will leave errors here */
    ClientData clientData,
    Tk_PhotoHandle photohandle,   /* The photo we are rendering into */
    int subsample,                /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */
    int zoom)
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin;
    Display *displayPtr;







|
|
>
>
>







|







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
 *
 *----------------------------------------------------------------------
 */

#define OVERDRAW_PIXELS 32        /* How much larger we make the pixmap
                                   * that the canvas objects are drawn into */

#ifdef WORDS_BIGENDIAN
#define IS_BIG_ENDIAN 1
#else
#define IS_BIG_ENDIAN 0
#endif

#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8))
#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000))

static int
DrawCanvas(
    Tcl_Interp *interp,           /* As passed to the widget command, and we will leave errors here */
    void *clientData,
    Tk_PhotoHandle photohandle,   /* The photo we are rendering into */
    int subsample,                /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */
    int zoom)
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin;
    Display *displayPtr;
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
        Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL);
        result = TCL_ERROR;
        goto done;
    }

#ifdef DEBUG_DRAWCANVAS
    Tcl_AppendResult(interp, "ximagePtr {", NULL);
    sprintf(buffer,"%d",ximagePtr->width);   Tcl_AppendResult(interp, " width ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->height);  Tcl_AppendResult(interp, " height ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->format);  Tcl_AppendResult(interp, " format ", buffer, NULL);
                                             Tcl_AppendResult(interp, " ximagePtr->data", NULL);
    if (ximagePtr->data != NULL) {
	int ix, iy;

        Tcl_AppendResult(interp, " {", NULL);
	for (iy = 0; iy < ximagePtr->height; ++ iy) {
	    Tcl_AppendResult(interp, " {", NULL);
	    for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) {
	        if (ix > 0) {
                    if (ix % 4 == 0)
                        Tcl_AppendResult(interp, "-", NULL);
                    else
                        Tcl_AppendResult(interp, " ", NULL);
                }
	        sprintf(buffer,"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF);
	        Tcl_AppendResult(interp, buffer, NULL);
	    }
	    Tcl_AppendResult(interp, " }", NULL);
	}
	Tcl_AppendResult(interp, " }", NULL);
    } else
	sprintf(buffer," NULL");
    sprintf(buffer,"%d",ximagePtr->byte_order);       Tcl_AppendResult(interp, " byte_order ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_unit);      Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_pad);       Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->depth);            Tcl_AppendResult(interp, " depth ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bytes_per_line);   Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bits_per_pixel);   Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

    Tcl_AppendResult(interp, "\nvisualPtr {", NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

#endif

    /*
     * Fill in the PhotoImageBlock structure abd allocate a block of memory
     * for the converted image data. Note we allocate an alpha channel even
     * though we don't use one, because this layout helps Tk_PhotoPutBlock()
     * use memcpy() instead of the slow pixel or line copy.
     */

    blockPtr.width = cWidth;
    blockPtr.height = cHeight;
    blockPtr.pixelSize = 4;
    blockPtr.pitch = blockPtr.pixelSize * blockPtr.width;







    blockPtr.offset[0] = 0;
    blockPtr.offset[1] = 1;
    blockPtr.offset[2] = 2;
    blockPtr.offset[3] = 3;


    blockPtr.pixelPtr = (unsigned char *)ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width);

    /*
     * Now convert the image data pixel by pixel from XImage to 32bit RGBA
     * format suitable for Tk_PhotoPutBlock().
     */

    DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits);
    DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits);
    DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits);

#ifdef DEBUG_DRAWCANVAS
    sprintf(buffer,"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL);
    sprintf(buffer,"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL);
    sprintf(buffer,"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL);
    sprintf(buffer,"%d",rbits);  Tcl_AppendResult(interp, " rbits ", buffer, NULL);
    sprintf(buffer,"%d",gbits);  Tcl_AppendResult(interp, " gbits ", buffer, NULL);
    sprintf(buffer,"%d",bbits);  Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL);
    Tcl_AppendResult(interp, "\nConverted_image {", NULL);
#endif

    /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...)
     * below to get this to work on Windows. X11 correctly sets the bitmap
     *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8
     * respectively!
     */

    bytesPerPixel = ximagePtr->bits_per_pixel/8;
    for (y = 0; y < blockPtr.height; ++y) {

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " {", NULL);
#endif

        for(x = 0; x < blockPtr.width; ++x) {
            unsigned int pixel = 0;

            switch (ximagePtr->bits_per_pixel) {

                /*
                 * Get an 8 bit pixel from the XImage.
                 */

                case 8 :







|
|
|
|














|






|
|
|
|
|
|
|
|
|
|
|



|
|
|















>
>
>
>
>
>
>




>
>












|
|
|
|
|
|


















|







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
        Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL);
        result = TCL_ERROR;
        goto done;
    }

#ifdef DEBUG_DRAWCANVAS
    Tcl_AppendResult(interp, "ximagePtr {", NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->width);   Tcl_AppendResult(interp, " width ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->height);  Tcl_AppendResult(interp, " height ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->format);  Tcl_AppendResult(interp, " format ", buffer, NULL);
                                             Tcl_AppendResult(interp, " ximagePtr->data", NULL);
    if (ximagePtr->data != NULL) {
	int ix, iy;

        Tcl_AppendResult(interp, " {", NULL);
	for (iy = 0; iy < ximagePtr->height; ++ iy) {
	    Tcl_AppendResult(interp, " {", NULL);
	    for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) {
	        if (ix > 0) {
                    if (ix % 4 == 0)
                        Tcl_AppendResult(interp, "-", NULL);
                    else
                        Tcl_AppendResult(interp, " ", NULL);
                }
	        snprintf(buffer,sizeof(buffer),"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF);
	        Tcl_AppendResult(interp, buffer, NULL);
	    }
	    Tcl_AppendResult(interp, " }", NULL);
	}
	Tcl_AppendResult(interp, " }", NULL);
    } else
	snprintf(buffer,sizeof(buffer)," NULL");
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->byte_order);       Tcl_AppendResult(interp, " byte_order ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->bitmap_unit);      Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->bitmap_pad);       Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->depth);            Tcl_AppendResult(interp, " depth ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->bytes_per_line);   Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",ximagePtr->bits_per_pixel);   Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"0x%8.8lx",ximagePtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"0x%8.8lx",ximagePtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

    Tcl_AppendResult(interp, "\nvisualPtr {", NULL);
    snprintf(buffer,sizeof(buffer),"0x%8.8lx",visualPtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"0x%8.8lx",visualPtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

#endif

    /*
     * Fill in the PhotoImageBlock structure abd allocate a block of memory
     * for the converted image data. Note we allocate an alpha channel even
     * though we don't use one, because this layout helps Tk_PhotoPutBlock()
     * use memcpy() instead of the slow pixel or line copy.
     */

    blockPtr.width = cWidth;
    blockPtr.height = cHeight;
    blockPtr.pixelSize = 4;
    blockPtr.pitch = blockPtr.pixelSize * blockPtr.width;

#ifdef TK_XGETIMAGE_USES_ABGR32
    blockPtr.offset[0] = 1;
    blockPtr.offset[1] = 2;
    blockPtr.offset[2] = 3;
    blockPtr.offset[3] = 0;
#else
    blockPtr.offset[0] = 0;
    blockPtr.offset[1] = 1;
    blockPtr.offset[2] = 2;
    blockPtr.offset[3] = 3;
#endif

    blockPtr.pixelPtr = (unsigned char *)ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width);

    /*
     * Now convert the image data pixel by pixel from XImage to 32bit RGBA
     * format suitable for Tk_PhotoPutBlock().
     */

    DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits);
    DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits);
    DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits);

#ifdef DEBUG_DRAWCANVAS
    snprintf(buffer,sizeof(buffer),"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",rbits);  Tcl_AppendResult(interp, " rbits ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",gbits);  Tcl_AppendResult(interp, " gbits ", buffer, NULL);
    snprintf(buffer,sizeof(buffer),"%d",bbits);  Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL);
    Tcl_AppendResult(interp, "\nConverted_image {", NULL);
#endif

    /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...)
     * below to get this to work on Windows. X11 correctly sets the bitmap
     *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8
     * respectively!
     */

    bytesPerPixel = ximagePtr->bits_per_pixel/8;
    for (y = 0; y < blockPtr.height; ++y) {

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " {", NULL);
#endif

        for(x = 0; x < blockPtr.width; ++x) {
            unsigned int pixel = 0;
	    int pixel_offset = blockPtr.pitch * y + blockPtr.pixelSize * x;
            switch (ximagePtr->bits_per_pixel) {

                /*
                 * Get an 8 bit pixel from the XImage.
                 */

                case 8 :
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
             * quad. However the visual mask is a 32bit ABGR quad. And
             * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
             * If the visual mask was correct there would be no need to
             * swap anything here.
             */

#ifdef _WIN32
#define   R_OFFSET 2

#define   B_OFFSET 0

#else
#define   R_OFFSET 0

#define   B_OFFSET 2

#endif





            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] =








                    (unsigned char)((pixel & visualPtr->red_mask) >> rshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] =
                    (unsigned char)((pixel & visualPtr->green_mask) >> gshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + B_OFFSET] =
                    (unsigned char)((pixel & visualPtr->blue_mask) >> bshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +3] = 0xFF;


#ifdef DEBUG_DRAWCANVAS






            {
		int ix;
                if (x > 0)
                    Tcl_AppendResult(interp, "-", NULL);
	        for (ix = 0; ix < 4; ++ix) {
                    if (ix > 0)
                        Tcl_AppendResult(interp, " ", NULL);

		    sprintf(buffer,"%2.2x",blockPtr.pixelPtr[blockPtr.pitch * y
                            + blockPtr.pixelSize * x + ix]&0xFF);
                    Tcl_AppendResult(interp, buffer, NULL);
                }
            }
#endif

        }







|
>
|
>

|
>
|
>

>
>
>
>
>
|
>
>
>
>
>
>
>
>

|

|

|
|
>

>
>
>
>
>
>







>
|







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
             * quad. However the visual mask is a 32bit ABGR quad. And
             * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
             * If the visual mask was correct there would be no need to
             * swap anything here.
             */

#ifdef _WIN32
#define   R_OFFSET blockPtr.offset[2]
#define   G_OFFSET blockPtr.offset[1]
#define   B_OFFSET blockPtr.offset[0]
#define   A_OFFSET blockPtr.offset[3]
#else
#define   R_OFFSET blockPtr.offset[0]
#define   G_OFFSET blockPtr.offset[1]
#define   B_OFFSET blockPtr.offset[2]
#define   A_OFFSET blockPtr.offset[3]
#endif
#ifdef TK_XGETIMAGE_USES_ABGR32
#define COPY_PIXEL (ximagePtr->bits_per_pixel == 32)
#else
#define COPY_PIXEL 0
#endif

	    if (COPY_PIXEL) {
		/*
		 * This platform packs pixels in RGBA byte order, as expected
		 * by Tk_PhotoPutBlock() so we can just copy the pixel as an int.
		 */
		*((unsigned int *) (blockPtr.pixelPtr + pixel_offset)) = pixel;
	    } else {
		blockPtr.pixelPtr[pixel_offset + R_OFFSET] =
                    (unsigned char)((pixel & visualPtr->red_mask) >> rshift);
		blockPtr.pixelPtr[pixel_offset + G_OFFSET] =
                    (unsigned char)((pixel & visualPtr->green_mask) >> gshift);
		blockPtr.pixelPtr[pixel_offset + B_OFFSET] =
                    (unsigned char)((pixel & visualPtr->blue_mask) >> bshift);
		blockPtr.pixelPtr[pixel_offset + A_OFFSET] = 0xFF;
	    }

#ifdef DEBUG_DRAWCANVAS
	    fprintf(stderr, "Converted pixel %x to %hhx %hhx %hhx %hhx \n",
		    pixel,
		    blockPtr.pixelPtr[pixel_offset + 0],
		    blockPtr.pixelPtr[pixel_offset + 1],
		    blockPtr.pixelPtr[pixel_offset + 2],
		    blockPtr.pixelPtr[pixel_offset + 3]);
            {
		int ix;
                if (x > 0)
                    Tcl_AppendResult(interp, "-", NULL);
	        for (ix = 0; ix < 4; ++ix) {
                    if (ix > 0)
                        Tcl_AppendResult(interp, " ", NULL);
		    snprintf(buffer,sizeof(buffer),"%2.2x",
		            blockPtr.pixelPtr[blockPtr.pitch * y
                            + blockPtr.pixelSize * x + ix]&0xFF);
                    Tcl_AppendResult(interp, buffer, NULL);
                }
            }
#endif

        }
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
 *	Information appears on the screen.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCanvas(
    ClientData clientData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tk_Item *itemPtr;
    Pixmap pixmap;
    int screenX1, screenX2, screenY1, screenY2, width, height;





    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if (!Tk_IsMapped(tkwin)) {
	goto done;
    }

#ifdef MAC_OSX_TK
    /*
     * If drawing is disabled, all we need to do is
     * clear the REDRAW_PENDING flag.
     */
    TkWindow *winPtr = (TkWindow *)(canvasPtr->tkwin);
    MacDrawable *macWin = winPtr->privatePtr;
    if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
	canvasPtr->flags &= ~REDRAW_PENDING;
	return;
    }
#endif

    /*







|






>
>
>
>














|
|







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
 *	Information appears on the screen.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCanvas(
    void *clientData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tk_Item *itemPtr;
    Pixmap pixmap;
    int screenX1, screenX2, screenY1, screenY2, width, height;
#ifdef MAC_OSX_TK
    TkWindow *winPtr;
    MacDrawable *macWin;
#endif

    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if (!Tk_IsMapped(tkwin)) {
	goto done;
    }

#ifdef MAC_OSX_TK
    /*
     * If drawing is disabled, all we need to do is
     * clear the REDRAW_PENDING flag.
     */
    winPtr = (TkWindow *)(canvasPtr->tkwin);
    macWin = winPtr->privatePtr;
    if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
	canvasPtr->flags &= ~REDRAW_PENDING;
	return;
    }
#endif

    /*
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
	    (screenX2 + 30 - canvasPtr->drawableXOrigin),
	    (screenY2 + 30 - canvasPtr->drawableYOrigin),
	    Tk_Depth(tkwin));
#else
	canvasPtr->drawableXOrigin = canvasPtr->xOrigin;
	canvasPtr->drawableYOrigin = canvasPtr->yOrigin;
	pixmap = Tk_WindowId(tkwin);
	TkpClipDrawableToRect(Tk_Display(tkwin), pixmap,
		screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin,
		width, height);
#endif /* TK_NO_DOUBLE_BUFFERING */

	/*
	 * Clear the area to be redrawn.
	 */







|







3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
	    (screenX2 + 30 - canvasPtr->drawableXOrigin),
	    (screenY2 + 30 - canvasPtr->drawableYOrigin),
	    Tk_Depth(tkwin));
#else
	canvasPtr->drawableXOrigin = canvasPtr->xOrigin;
	canvasPtr->drawableYOrigin = canvasPtr->yOrigin;
	pixmap = Tk_WindowId(tkwin);
	Tk_ClipDrawableToRect(Tk_Display(tkwin), pixmap,
		screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin,
		width, height);
#endif /* TK_NO_DOUBLE_BUFFERING */

	/*
	 * Clear the area to be redrawn.
	 */
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
		canvasPtr->pixmapGC,
		screenX1 - canvasPtr->drawableXOrigin,
		screenY1 - canvasPtr->drawableYOrigin,
		(unsigned int) width, (unsigned int) height,
		screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin);
	Tk_FreePixmap(Tk_Display(tkwin), pixmap);
#else
	TkpClipDrawableToRect(Tk_Display(tkwin), pixmap, 0, 0, -1, -1);
#endif /* TK_NO_DOUBLE_BUFFERING */
    }

    /*
     * Draw the window borders, if needed.
     */








|







3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
		canvasPtr->pixmapGC,
		screenX1 - canvasPtr->drawableXOrigin,
		screenY1 - canvasPtr->drawableYOrigin,
		(unsigned int) width, (unsigned int) height,
		screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin);
	Tk_FreePixmap(Tk_Display(tkwin), pixmap);
#else
	Tk_ClipDrawableToRect(Tk_Display(tkwin), pixmap, 0, 0, -1, -1);
#endif /* TK_NO_DOUBLE_BUFFERING */
    }

    /*
     * Draw the window borders, if needed.
     */

3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
	    GC fgGC, bgGC;

	    bgGC = Tk_GCForColor(canvasPtr->highlightBgColorPtr,
		    Tk_WindowId(tkwin));
	    if (canvasPtr->textInfo.gotFocus) {
		fgGC = Tk_GCForColor(canvasPtr->highlightColorPtr,
			Tk_WindowId(tkwin));
	    	TkpDrawHighlightBorder(tkwin, fgGC, bgGC,
			canvasPtr->highlightWidth, Tk_WindowId(tkwin));
	    } else {
	    	TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
			canvasPtr->highlightWidth, Tk_WindowId(tkwin));
	    }
	}
    }

  done:
    canvasPtr->flags &= ~(REDRAW_PENDING|BBOX_NOT_EMPTY);







|


|







3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
	    GC fgGC, bgGC;

	    bgGC = Tk_GCForColor(canvasPtr->highlightBgColorPtr,
		    Tk_WindowId(tkwin));
	    if (canvasPtr->textInfo.gotFocus) {
		fgGC = Tk_GCForColor(canvasPtr->highlightColorPtr,
			Tk_WindowId(tkwin));
	    	Tk_DrawHighlightBorder(tkwin, fgGC, bgGC,
			canvasPtr->highlightWidth, Tk_WindowId(tkwin));
	    } else {
	    	Tk_DrawHighlightBorder(tkwin, bgGC, bgGC,
			canvasPtr->highlightWidth, Tk_WindowId(tkwin));
	    }
	}
    }

  done:
    canvasPtr->flags &= ~(REDRAW_PENDING|BBOX_NOT_EMPTY);
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
 *	it gets exposed, it is redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    if (eventPtr->type == Expose) {
	int x, y;








|







3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
 *	it gets exposed, it is redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    if (eventPtr->type == Expose) {
	int x, y;

3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
	    canvasPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(canvasPtr->interp,
		    canvasPtr->widgetCmd);
	}
	if (canvasPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayCanvas, canvasPtr);
	}
	Tcl_EventuallyFree(canvasPtr, (Tcl_FreeProc *) DestroyCanvas);
    } else if (eventPtr->type == ConfigureNotify) {
	canvasPtr->flags |= UPDATE_SCROLLBARS;

	/*
	 * The call below is needed in order to recenter the canvas if it's
	 * confined and its scroll region is smaller than the window.
	 */







|







3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
	    canvasPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(canvasPtr->interp,
		    canvasPtr->widgetCmd);
	}
	if (canvasPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayCanvas, canvasPtr);
	}
	Tcl_EventuallyFree(canvasPtr, DestroyCanvas);
    } else if (eventPtr->type == ConfigureNotify) {
	canvasPtr->flags |= UPDATE_SCROLLBARS;

	/*
	 * The call below is needed in order to recenter the canvas if it's
	 * confined and its scroll region is smaller than the window.
	 */
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
	    CanvasFocusProc(canvasPtr, 0);
	}
    } else if (eventPtr->type == UnmapNotify) {
	Tk_Item *itemPtr;

	/*
	 * Special hack: if the canvas is unmapped, then must notify all items
	 * with "alwaysRedraw" set, so that they know that they are no longer
	 * displayed.
	 */

	for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    if (AlwaysRedraw(itemPtr)) {
		ItemDisplay(canvasPtr, itemPtr, None, 0, 0, 0, 0);
	    }







|
|







3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
	    CanvasFocusProc(canvasPtr, 0);
	}
    } else if (eventPtr->type == UnmapNotify) {
	Tk_Item *itemPtr;

	/*
	 * Special hack: if the canvas is unmapped, then must notify all items
	 * with flag TK_ALWAYS_REDRAW set, so that they know that they are no
	 * longer displayed.
	 */

	for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    if (AlwaysRedraw(itemPtr)) {
		ItemDisplay(canvasPtr, itemPtr, None, 0, 0, 0, 0);
	    }
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or







|







3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
	    case '\n':
	    case '\r':
		break;

	    case '!':		/* Negate next tag or subexpr */
		if (looking_for_tag > 1) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "too many '!' in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "COMPLEXITY", NULL);
		    return TCL_ERROR;
		}
		looking_for_tag++;
		negate_result = 1;
		break;







|







3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
	    case '\n':
	    case '\r':
		break;

	    case '!':		/* Negate next tag or subexpr */
		if (looking_for_tag > 1) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "too many '!' in tag search expression", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "COMPLEXITY", NULL);
		    return TCL_ERROR;
		}
		looking_for_tag++;
		negate_result = 1;
		break;
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
			found_endquote = 1;
			break;
		    }
		    *tag++ = c;
		}
		if (!found_endquote) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "missing endquote in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "ENDQUOTE", NULL);
		    return TCL_ERROR;
		}
		if (!(tag - searchPtr->rewritebuffer)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "null quoted tag string in tag search expression",
			    -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "EMPTY", NULL);
		    return TCL_ERROR;
		}
		*tag++ = '\0';
		expr->uids[expr->index++] =
			Tk_GetUid(searchPtr->rewritebuffer);
		looking_for_tag = 0;
		found_tag = 1;
		break;

	    case '&':		/* Illegal chars when looking for tag */
	    case '|':
	    case '^':
	    case ')':
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"unexpected operator in tag search expression", -1));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			"UNEXPECTED", NULL);
		return TCL_ERROR;

	    default:		/* Unquoted tag string */
		if (negate_result) {
		    expr->uids[expr->index++] = searchUids->negtagvalUid;







|







|
















|







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
			found_endquote = 1;
			break;
		    }
		    *tag++ = c;
		}
		if (!found_endquote) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "missing endquote in tag search expression", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "ENDQUOTE", NULL);
		    return TCL_ERROR;
		}
		if (!(tag - searchPtr->rewritebuffer)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "null quoted tag string in tag search expression",
			    TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "EMPTY", NULL);
		    return TCL_ERROR;
		}
		*tag++ = '\0';
		expr->uids[expr->index++] =
			Tk_GetUid(searchPtr->rewritebuffer);
		looking_for_tag = 0;
		found_tag = 1;
		break;

	    case '&':		/* Illegal chars when looking for tag */
	    case '|':
	    case '^':
	    case ')':
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"unexpected operator in tag search expression", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			"UNEXPECTED", NULL);
		return TCL_ERROR;

	    default:		/* Unquoted tag string */
		if (negate_result) {
		    expr->uids[expr->index++] = searchUids->negtagvalUid;
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
	    case '\r':
		break;

	    case '&':		/* AND operator */
		c = searchPtr->string[searchPtr->stringIndex++];
		if (c != '&') {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "singleton '&' in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "INCOMPLETE_OP", NULL);
		    return TCL_ERROR;
		}
		expr->uids[expr->index++] = searchUids->andUid;
		looking_for_tag = 1;
		break;

	    case '|':		/* OR operator */
		c = searchPtr->string[searchPtr->stringIndex++];
		if (c != '|') {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "singleton '|' in tag search expression", -1));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "INCOMPLETE_OP", NULL);
		    return TCL_ERROR;
		}
		expr->uids[expr->index++] = searchUids->orUid;
		looking_for_tag = 1;
		break;

	    case '^':		/* XOR operator */
		expr->uids[expr->index++] = searchUids->xorUid;
		looking_for_tag = 1;
		break;

	    case ')':		/* End subexpression */
		expr->uids[expr->index++] = searchUids->endparenUid;
		goto breakwhile;

	    default:		/* syntax error */
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"invalid boolean operator in tag search expression",
			-1));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "BAD_OP",
			NULL);
		return TCL_ERROR;
	    }
	}
    }

  breakwhile:
    if (found_tag && !looking_for_tag) {
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "missing tag in tag search expression", -1));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "NO_TAG", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *







|












|




















|












|







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
	    case '\r':
		break;

	    case '&':		/* AND operator */
		c = searchPtr->string[searchPtr->stringIndex++];
		if (c != '&') {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "singleton '&' in tag search expression", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "INCOMPLETE_OP", NULL);
		    return TCL_ERROR;
		}
		expr->uids[expr->index++] = searchUids->andUid;
		looking_for_tag = 1;
		break;

	    case '|':		/* OR operator */
		c = searchPtr->string[searchPtr->stringIndex++];
		if (c != '|') {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "singleton '|' in tag search expression", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH",
			    "INCOMPLETE_OP", NULL);
		    return TCL_ERROR;
		}
		expr->uids[expr->index++] = searchUids->orUid;
		looking_for_tag = 1;
		break;

	    case '^':		/* XOR operator */
		expr->uids[expr->index++] = searchUids->xorUid;
		looking_for_tag = 1;
		break;

	    case ')':		/* End subexpression */
		expr->uids[expr->index++] = searchUids->endparenUid;
		goto breakwhile;

	    default:		/* syntax error */
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"invalid boolean operator in tag search expression",
			TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "BAD_OP",
			NULL);
		return TCL_ERROR;
	    }
	}
    }

  breakwhile:
    if (found_tag && !looking_for_tag) {
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "missing tag in tag search expression", TCL_INDEX_NONE));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "NO_TAG", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
     */

    if (itemPtr->tagSpace == itemPtr->numTags) {
	Tk_Uid *newTagPtr;

	itemPtr->tagSpace += 5;
	newTagPtr = (Tk_Uid *)ckalloc(itemPtr->tagSpace * sizeof(Tk_Uid));
	memcpy((void *) newTagPtr, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
    }







|







4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
     */

    if (itemPtr->tagSpace == itemPtr->numTags) {
	Tk_Uid *newTagPtr;

	itemPtr->tagSpace += 5;
	newTagPtr = (Tk_Uid *)ckalloc(itemPtr->tagSpace * sizeof(Tk_Uid));
	memcpy(newTagPtr, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
    }
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
 *--------------------------------------------------------------
 */

static int
FindItems(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    TkCanvas *canvasPtr,	/* Canvas whose items are to be searched. */
    int objc,			/* Number of entries in argv. Must be greater
				 * than zero. */
    Tcl_Obj *const *objv,	/* Arguments that describe what items to
				 * search for (see user doc on "find" and
				 * "addtag" options). */
    Tcl_Obj *newTag,		/* If non-NULL, gives new tag to set on all
				 * found items; if NULL, then ids of found
				 * items are returned in the interp's
				 * result. */
    int first			/* For error messages: gives number of
				 * elements of objv which are already
				 * handled. */
    ,TagSearch **searchPtrPtr	/* From CanvasWidgetCmd local vars*/
    )
{
    Tk_Item *itemPtr;
    Tk_Uid uid;







|








|







4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
 *--------------------------------------------------------------
 */

static int
FindItems(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    TkCanvas *canvasPtr,	/* Canvas whose items are to be searched. */
    Tcl_Size objc,			/* Number of entries in argv. Must be greater
				 * than zero. */
    Tcl_Obj *const *objv,	/* Arguments that describe what items to
				 * search for (see user doc on "find" and
				 * "addtag" options). */
    Tcl_Obj *newTag,		/* If non-NULL, gives new tag to set on all
				 * found items; if NULL, then ids of found
				 * items are returned in the interp's
				 * result. */
    Tcl_Size first			/* For error messages: gives number of
				 * elements of objv which are already
				 * handled. */
    ,TagSearch **searchPtrPtr	/* From CanvasWidgetCmd local vars*/
    )
{
    Tk_Item *itemPtr;
    Tk_Uid uid;
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
 *	any).
 *
 *--------------------------------------------------------------
 */

static void
CanvasBindProc(
    ClientData clientData,	/* Pointer to canvas structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    unsigned mask;

    Tcl_Preserve(canvasPtr);








|







5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
 *	any).
 *
 *--------------------------------------------------------------
 */

static void
CanvasBindProc(
    void *clientData,	/* Pointer to canvas structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    unsigned mask;

    Tcl_Preserve(canvasPtr);

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
     */

    if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr)
	    && (canvasPtr->currentItemPtr != NULL)
	    && !(canvasPtr->flags & LEFT_GRABBED_ITEM)) {
	XEvent event;
	Tk_Item *itemPtr = canvasPtr->currentItemPtr;
	int i;

	event = canvasPtr->pickEvent;
	event.type = LeaveNotify;

	/*

	 * If the event's detail happens to be NotifyInferior the binding
	 * mechanism will discard the event. To be consistent, always use
	 * NotifyAncestor.







	 */

	event.xcrossing.detail = NotifyAncestor;
	canvasPtr->flags |= REPICK_IN_PROGRESS;
	CanvasDoEvent(canvasPtr, &event);
	canvasPtr->flags &= ~REPICK_IN_PROGRESS;

	/*
	 * The check below is needed because there could be an event handler
	 * for <LeaveNotify> that deletes the current item.
	 */

	if ((itemPtr == canvasPtr->currentItemPtr) && !buttonDown) {
	    for (i = (int)itemPtr->numTags-1; i >= 0; i--) {
		if (itemPtr->tagPtr[i] == searchUids->currentUid)
		    /* then */ {
                    memmove((void *)(itemPtr->tagPtr + i),
                            itemPtr->tagPtr + i + 1,
                            (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;
		    break;







|





>
|
|
|
>
>
>
>
>
>
>













|







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
     */

    if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr)
	    && (canvasPtr->currentItemPtr != NULL)
	    && !(canvasPtr->flags & LEFT_GRABBED_ITEM)) {
	XEvent event;
	Tk_Item *itemPtr = canvasPtr->currentItemPtr;
	Tcl_Size i;

	event = canvasPtr->pickEvent;
	event.type = LeaveNotify;

	/*
	 * Behaviour before ticket #47d4f29159:
	 *    If the event's detail happens to be NotifyInferior the binding
	 *    mechanism will discard the event. To be consistent, always use
	 *    NotifyAncestor.
	 *
	 * Behaviour after ticket #47d4f29159:
	 *    The binding mechanism doesn't discard events with detail field
	 *    NotifyInferior anymore. It would be best to base the detail
	 *    field on the ancestry relationship between the old and new
	 *    canvas items. For the time being, retain the choice from before
	 *    ticket #47d4f29159, which doesn't harm.
	 */

	event.xcrossing.detail = NotifyAncestor;
	canvasPtr->flags |= REPICK_IN_PROGRESS;
	CanvasDoEvent(canvasPtr, &event);
	canvasPtr->flags &= ~REPICK_IN_PROGRESS;

	/*
	 * The check below is needed because there could be an event handler
	 * for <LeaveNotify> that deletes the current item.
	 */

	if ((itemPtr == canvasPtr->currentItemPtr) && !buttonDown) {
	    for (i = itemPtr->numTags-1; i != TCL_INDEX_NONE; i--) {
		if (itemPtr->tagPtr[i] == searchUids->currentUid)
		    /* then */ {
                    memmove((void *)(itemPtr->tagPtr + i),
                            itemPtr->tagPtr + i + 1,
                            (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;
		    break;
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
    TkCanvas *canvasPtr,	/* Canvas widget in which event occurred. */
    XEvent *eventPtr)		/* Real or simulated X event that is to be
				 * processed. */
{
#define NUM_STATIC 3
    void *staticObjects[NUM_STATIC];
    void **objectPtr;
    int numObjects, i;
    Tk_Item *itemPtr;
    TagSearchExpr *expr;
    int numExprs;
    SearchUids *searchUids = GetStaticUids();

    if (canvasPtr->bindingTable == NULL) {
	return;
    }

    itemPtr = canvasPtr->currentItemPtr;







|


|







5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
    TkCanvas *canvasPtr,	/* Canvas widget in which event occurred. */
    XEvent *eventPtr)		/* Real or simulated X event that is to be
				 * processed. */
{
#define NUM_STATIC 3
    void *staticObjects[NUM_STATIC];
    void **objectPtr;
    Tcl_Size numObjects, i;
    Tk_Item *itemPtr;
    TagSearchExpr *expr;
    Tcl_Size numExprs;
    SearchUids *searchUids = GetStaticUids();

    if (canvasPtr->bindingTable == NULL) {
	return;
    }

    itemPtr = canvasPtr->currentItemPtr;
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
    numObjects = itemPtr->numTags + numExprs + 2;
    if (numObjects <= NUM_STATIC) {
	objectPtr = staticObjects;
    } else {
	objectPtr = (void **)ckalloc(numObjects * sizeof(void *));
    }
    objectPtr[0] = (char *)searchUids->allUid;
    for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	objectPtr[i+1] = (char *)itemPtr->tagPtr[i];
    }
    objectPtr[itemPtr->numTags + 1] = itemPtr;

    /*
     * Copy uids of matching expressions into object array
     */







|







5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
    numObjects = itemPtr->numTags + numExprs + 2;
    if (numObjects <= NUM_STATIC) {
	objectPtr = staticObjects;
    } else {
	objectPtr = (void **)ckalloc(numObjects * sizeof(void *));
    }
    objectPtr[0] = (char *)searchUids->allUid;
    for (i = itemPtr->numTags - 1; i != TCL_INDEX_NONE; i--) {
	objectPtr[i+1] = (char *)itemPtr->tagPtr[i];
    }
    objectPtr[itemPtr->numTags + 1] = itemPtr;

    /*
     * Copy uids of matching expressions into object array
     */
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
 *	function reschedules itself.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    if (!canvasPtr->textInfo.gotFocus || (canvasPtr->insertOffTime == 0)) {
	return;
    }
    if (canvasPtr->textInfo.cursorOn) {







|







5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
 *	function reschedules itself.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasBlinkProc(
    void *clientData)	/* Pointer to record describing entry. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    if (!canvasPtr->textInfo.gotFocus || (canvasPtr->insertOffTime == 0)) {
	return;
    }
    if (canvasPtr->textInfo.cursorOn) {
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
 *----------------------------------------------------------------------
 */

static void
CanvasSelectTo(
    TkCanvas *canvasPtr,	/* Information about widget. */
    Tk_Item *itemPtr,		/* Item that is to hold selection. */
    TkSizeT index)			/* Index of element that is to become the
				 * "other" end of the selection. */
{
    TkSizeT oldFirst, oldLast;
    Tk_Item *oldSelPtr;

    oldFirst = canvasPtr->textInfo.selectFirst;
    oldLast = canvasPtr->textInfo.selectLast;
    oldSelPtr = canvasPtr->textInfo.selItemPtr;

    /*







|


|







5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
 *----------------------------------------------------------------------
 */

static void
CanvasSelectTo(
    TkCanvas *canvasPtr,	/* Information about widget. */
    Tk_Item *itemPtr,		/* Item that is to hold selection. */
    Tcl_Size index)			/* Index of element that is to become the
				 * "other" end of the selection. */
{
    Tcl_Size oldFirst, oldLast;
    Tk_Item *oldSelPtr;

    oldFirst = canvasPtr->textInfo.selectFirst;
    oldLast = canvasPtr->textInfo.selectLast;
    oldSelPtr = canvasPtr->textInfo.selItemPtr;

    /*
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor + 1 <= index + 1) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = ((int)index < 0) ? TCL_INDEX_NONE : index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)







|







5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor <= index) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = ((int)index < 0) ? TCL_INDEX_NONE : index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
CanvasFetchSelection(
    ClientData clientData,	/* Information about canvas widget. */
    TkSizeT offset,			/* Offset within selection of first character
				 * to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    return ItemSelection(canvasPtr, canvasPtr->textInfo.selItemPtr, offset,
	    buffer, maxBytes);







|

|
|


|







5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static Tcl_Size
CanvasFetchSelection(
    void *clientData,	/* Information about canvas widget. */
    Tcl_Size offset,			/* Offset within selection of first character
				 * to be returned. */
    char *buffer,		/* Location in which to place selection. */
    Tcl_Size maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    return ItemSelection(canvasPtr, canvasPtr->textInfo.selItemPtr, offset,
	    buffer, maxBytes);
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasLostSelection(
    ClientData clientData)	/* Information about entry widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr);
    canvasPtr->textInfo.selItemPtr = NULL;
}








|







5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
CanvasLostSelection(
    void *clientData)	/* Information about entry widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr);
    canvasPtr->textInfo.selItemPtr = NULL;
}

5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
    scrollY2 = canvasPtr->scrollY2;
    canvasPtr->flags &= ~UPDATE_SCROLLBARS;
    if (canvasPtr->xScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(xOrigin + inset,
		xOrigin + width - inset, scrollX1, scrollX2);

	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, xScrollCmd, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	Tcl_DecrRefCount(fractions);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_ResetResult(interp);
	Tcl_Release(xScrollCmd);
    }

    if (yScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(yOrigin + inset,
		yOrigin + height - inset, scrollY1, scrollY2);

	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, yScrollCmd, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	Tcl_DecrRefCount(fractions);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_ResetResult(interp);
	Tcl_Release(yScrollCmd);







|
|
|
|














|
|
|
|







5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
    scrollY2 = canvasPtr->scrollY2;
    canvasPtr->flags &= ~UPDATE_SCROLLBARS;
    if (canvasPtr->xScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(xOrigin + inset,
		xOrigin + width - inset, scrollX1, scrollX2);

	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, xScrollCmd, TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, Tcl_GetString(fractions), TCL_INDEX_NONE);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	Tcl_DecrRefCount(fractions);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_ResetResult(interp);
	Tcl_Release(xScrollCmd);
    }

    if (yScrollCmd != NULL) {
	Tcl_Obj *fractions = ScrollFractions(yOrigin + inset,
		yOrigin + height - inset, scrollY1, scrollY2);

	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, yScrollCmd, TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, Tcl_GetString(fractions), TCL_INDEX_NONE);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	Tcl_DecrRefCount(fractions);
	if (result != TCL_OK) {
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_ResetResult(interp);
	Tcl_Release(yScrollCmd);
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
    canvasPtr->yOrigin = yOrigin;
    canvasPtr->flags |= UPDATE_SCROLLBARS;
    Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
	    canvasPtr->xOrigin, canvasPtr->yOrigin,
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetStringsFromObjs --
 *
 * Results:
 *	Converts object list into string list.
 *
 * Side effects:
 *	Memory is allocated for the objv array, which must be freed using
 *	ckfree() when no longer needed.
 *
 *----------------------------------------------------------------------
 */

static const char **
TkGetStringsFromObjs(
    int objc,
    Tcl_Obj *const objv[])
{
    int i;
    const char **argv;

    if (objc <= 0) {
	return NULL;
    }
    argv = (const char **)ckalloc((objc+1) * sizeof(char *));
    for (i = 0; i < objc; i++) {
	argv[i] = Tcl_GetString(objv[i]);
    }
    argv[objc] = 0;
    return argv;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsColor --
 *
 *	This function is called by individual canvas items when they want to
 *	set a color value for output. Given information about an X color, this







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







6034
6035
6036
6037
6038
6039
6040
6041


































6042
6043
6044
6045
6046
6047
6048
    canvasPtr->yOrigin = yOrigin;
    canvasPtr->flags |= UPDATE_SCROLLBARS;
    Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
	    canvasPtr->xOrigin, canvasPtr->yOrigin,
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}



































/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasPsColor --
 *
 *	This function is called by individual canvas items when they want to
 *	set a color value for output. Given information about an X color, this
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
Tk_CanvasPsPath(
    Tcl_Interp *interp,		/* Put generated Postscript in this
				 * interpreter's result field. */
    Tk_Canvas canvas,		/* Canvas on whose behalf Postscript is being
				 * generated. */
    double *coordPtr,		/* Pointer to first in array of 2*numPoints
				 * coordinates giving points for path. */
    int numPoints)		/* Number of points at *coordPtr. */
{
    Tk_PostscriptPath(interp, Canvas(canvas)->psInfo, coordPtr, numPoints);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|











6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
Tk_CanvasPsPath(
    Tcl_Interp *interp,		/* Put generated Postscript in this
				 * interpreter's result field. */
    Tk_Canvas canvas,		/* Canvas on whose behalf Postscript is being
				 * generated. */
    double *coordPtr,		/* Pointer to first in array of 2*numPoints
				 * coordinates giving points for path. */
    Tcl_Size numPoints)		/* Number of points at *coordPtr. */
{
    Tk_PostscriptPath(interp, Canvas(canvas)->psInfo, coordPtr, numPoints);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCanvas.h.

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.
 *
 * 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





|
|
|







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 © 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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    double pixelsPerMM;		/* Scale factor between MM and pixels; used
				 * when converting coordinates. */
    int flags;			/* Various flags; see below for
				 * definitions. */
    TkSizeT nextId;			/* Number to use as id for next item created
				 * in widget. */
    Tk_PostscriptInfo psInfo;	/* Pointer to information used for generating
				 * Postscript for the canvas. NULL means no
				 * Postscript is currently being generated. */
    Tcl_HashTable idTable;	/* Table of integer indices. */

    /*







|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    double pixelsPerMM;		/* Scale factor between MM and pixels; used
				 * when converting coordinates. */
    int flags;			/* Various flags; see below for
				 * definitions. */
    Tcl_Size nextId;			/* Number to use as id for next item created
				 * in widget. */
    Tk_PostscriptInfo psInfo;	/* Pointer to information used for generating
				 * Postscript for the canvas. NULL means no
				 * Postscript is currently being generated. */
    Tcl_HashTable idTable;	/* Table of integer indices. */

    /*
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#define FORCE_REDRAW		8

/*
 * Canvas-related functions that are shared among Tk modules but not exported
 * to the outside world:
 */

MODULE_SCOPE int	TkCanvPostscriptCmd(TkCanvas *canvasPtr,
			    Tcl_Interp *interp, int argc, const char **argv);
MODULE_SCOPE int 	TkCanvTranslatePath(TkCanvas *canvPtr,
			    int numVertex, double *coordPtr, int closed,
			    XPoint *outPtr);
/*
 * Standard item types provided by Tk:
 */








|
|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#define FORCE_REDRAW		8

/*
 * Canvas-related functions that are shared among Tk modules but not exported
 * to the outside world:
 */

MODULE_SCOPE int	TkCanvPostscriptObjCmd(TkCanvas *canvasPtr,
			    Tcl_Interp *interp, Tcl_Size argc, Tcl_Obj *const objv[]);
MODULE_SCOPE int 	TkCanvTranslatePath(TkCanvas *canvPtr,
			    int numVertex, double *coordPtr, int closed,
			    XPoint *outPtr);
/*
 * Standard item types provided by Tk:
 */

Changes to generic/tkClipboard.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
/*
 * 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.
 *
 * 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"

/*
 * Prototypes for functions used only in this file:
 */

static TkSizeT	ClipboardAppHandler(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static TkSizeT	ClipboardHandler(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static TkSizeT	ClipboardWindowHandler(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static void		ClipboardLostSel(ClientData clientData);
static int		ClipboardGetProc(ClientData clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *----------------------------------------------------------------------
 *
 * ClipboardHandler --
 *







|
|












|
|
|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
 * 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 © 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"

/*
 * Prototypes for functions used only in this file:
 */

static Tcl_Size	ClipboardAppHandler(void *clientData,
			    Tcl_Size offset, char *buffer, Tcl_Size maxBytes);
static Tcl_Size	ClipboardHandler(void *clientData,
			    Tcl_Size offset, char *buffer, Tcl_Size maxBytes);
static Tcl_Size	ClipboardWindowHandler(void *clientData,
			    Tcl_Size offset, char *buffer, Tcl_Size maxBytes);
static void		ClipboardLostSel(void *clientData);
static int		ClipboardGetProc(void *clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *----------------------------------------------------------------------
 *
 * ClipboardHandler --
 *
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardHandler(
    ClientData clientData,	/* Information about data to fetch. */
    TkSizeT offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkClipboardTarget *targetPtr = (TkClipboardTarget *)clientData;
    TkClipboardBuffer *cbPtr;
    char *srcPtr, *destPtr;
    TkSizeT count = 0;
    TkSizeT scanned = 0;
    TkSizeT length, freeCount;

    /*
     * Skip to buffer containing offset byte
     */

    for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {
	if (cbPtr == NULL) {







|

|
|


|




|
|
|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
ClipboardHandler(
    void *clientData,	/* Information about data to fetch. */
    Tcl_Size offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    Tcl_Size maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkClipboardTarget *targetPtr = (TkClipboardTarget *)clientData;
    TkClipboardBuffer *cbPtr;
    char *srcPtr, *destPtr;
    Tcl_Size count = 0;
    Tcl_Size scanned = 0;
    Tcl_Size length, freeCount;

    /*
     * Skip to buffer containing offset byte
     */

    for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {
	if (cbPtr == NULL) {
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardAppHandler(
    ClientData clientData,	/* Pointer to TkDisplay structure. */
    TkSizeT offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    TkSizeT length;
    const char *p;

    p = dispPtr->clipboardAppPtr->winPtr->nameUid;
    length = strlen(p);
    if (length <= offset) {
	return 0;
    }







|

|
|


|


|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
ClipboardAppHandler(
    void *clientData,	/* Pointer to TkDisplay structure. */
    Tcl_Size offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    Tcl_Size maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    Tcl_Size length;
    const char *p;

    p = dispPtr->clipboardAppPtr->winPtr->nameUid;
    length = strlen(p);
    if (length <= offset) {
	return 0;
    }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardWindowHandler(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(TkSizeT),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TCL_UNUSED(TkSizeT))		/* Maximum # of bytes to store at buffer. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*







|


|


|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
ClipboardWindowHandler(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(Tcl_Size),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TCL_UNUSED(Tcl_Size))		/* Maximum # of bytes to store at buffer. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
 *	The clipboard is marked as inactive.
 *
 *----------------------------------------------------------------------
 */

static void
ClipboardLostSel(
    ClientData clientData)	/* Pointer to TkDisplay structure. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;

    dispPtr->clipboardActive = 0;
}

/*







|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
 *	The clipboard is marked as inactive.
 *
 *----------------------------------------------------------------------
 */

static void
ClipboardLostSel(
    void *clientData)	/* Pointer to TkDisplay structure. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;

    dispPtr->clipboardActive = 0;
}

/*
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ClipboardObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *path = NULL;
    Atom selection;







|







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ClipboardObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *path = NULL;
    Atom selection;
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
	const char *formatName = NULL;
	const char *string;
	static const char *const appendOptionStrings[] = {
	    "-displayof", "-format", "-type", NULL
	};
	enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
	int subIndex;
	TkSizeT length;

	for (i = 2; i < objc - 1; i++) {
	    string = TkGetStringFromObj(objv[i], &length);
	    if (string[0] != '-') {
		break;
	    }

	    /*
	     * If the argument is "--", it signifies the end of arguments.
	     */







|


|







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
	const char *formatName = NULL;
	const char *string;
	static const char *const appendOptionStrings[] = {
	    "-displayof", "-format", "-type", NULL
	};
	enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
	int subIndex;
	Tcl_Size length;

	for (i = 2; i < objc - 1; i++) {
	    string = Tcl_GetStringFromObj(objv[i], &length);
	    if (string[0] != '-') {
		break;
	    }

	    /*
	     * If the argument is "--", it signifies the end of arguments.
	     */
699
700
701
702
703
704
705
706
707
708
709
710
711




712


713
714
715
716
717
718
719
720
721
722
 *	argument.
 *
 *--------------------------------------------------------------
 */

static int
ClipboardGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{




    Tcl_DStringAppend((Tcl_DString *)clientData, portion, -1);


    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|





>
>
>
>
|
>
>










699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
 *	argument.
 *
 *--------------------------------------------------------------
 */

static int
ClipboardGetProc(
    void *clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
    Tcl_DString ds;

    const char *str = Tcl_ExternalToUtfDString(utf8, portion, TCL_INDEX_NONE, &ds);
    Tcl_DStringAppend((Tcl_DString *) clientData, str, Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    Tcl_FreeEncoding(utf8);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkCmds.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if defined(_WIN32)
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static TkWindow *	GetTopHierarchy(Tk_Window tkwin);
static char *		WaitVariableProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		WaitVisibilityProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WaitWindowProc(ClientData clientData,
			    XEvent *eventPtr);
static int		AppnameCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		CaretCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		InactiveCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		ScalingCmd(ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv);
static int		UseinputmethodsCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);
static int		WindowingsystemCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);

#if defined(_WIN32) || defined(MAC_OSX_TK)
MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
#else
#define tkFontchooserEnsemble NULL
#endif

/*
 * Table of tk subcommand names and implementations.
 */

static const TkEnsemble tkCmdMap[] = {

    {"appname",		AppnameCmd, NULL },
    {"busy",		Tk_BusyObjCmd, NULL },
    {"caret",		CaretCmd, NULL },
    {"inactive",	InactiveCmd, NULL },
    {"scaling",		ScalingCmd, NULL },
    {"useinputmethods",	UseinputmethodsCmd, NULL },
    {"windowingsystem",	WindowingsystemCmd, NULL },
    {"fontchooser",	NULL, tkFontchooserEnsemble},
    {NULL, NULL, NULL}
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_BellObjCmd --






|
|
|




















|


|

|

|
|
|
|
|
|
|
|
|
|

|
|













>







<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
/*
 * tkCmds.c --
 *
 *	This file contains a collection of Tk-related Tcl commands that didn't
 *	fit in any particular file of the toolkit.
 *
 * 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"

#if defined(_WIN32)
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static TkWindow *	GetTopHierarchy(Tk_Window tkwin);
static char *		WaitVariableProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		WaitVisibilityProc(void *clientData,
			    XEvent *eventPtr);
static void		WaitWindowProc(void *clientData,
			    XEvent *eventPtr);
static int		AppnameCmd(void *dummy, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const *objv);
static int		CaretCmd(void *dummy, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const *objv);
static int		InactiveCmd(void *dummy, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const *objv);
static int		ScalingCmd(void *dummy, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const *objv);
static int		UseinputmethodsCmd(void *dummy,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const *objv);
static int		WindowingsystemCmd(void *dummy,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const *objv);

#if defined(_WIN32) || defined(MAC_OSX_TK)
MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
#else
#define tkFontchooserEnsemble NULL
#endif

/*
 * Table of tk subcommand names and implementations.
 */

static const TkEnsemble tkCmdMap[] = {
    {"fontchooser",	NULL, tkFontchooserEnsemble},
    {"appname",		AppnameCmd, NULL },
    {"busy",		Tk_BusyObjCmd, NULL },
    {"caret",		CaretCmd, NULL },
    {"inactive",	InactiveCmd, NULL },
    {"scaling",		ScalingCmd, NULL },
    {"useinputmethods",	UseinputmethodsCmd, NULL },
    {"windowingsystem",	WindowingsystemCmd, NULL },

    {NULL, NULL, NULL}
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_BellObjCmd --
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BellObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const bellOptions[] = {
	"-displayof", "-nice", NULL
    };
    enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
    Tk_Window tkwin = (Tk_Window)clientData;

    int i, index, nice = 0;
    Tk_ErrorHandler handler;

    if (objc > 4) {
    wrongArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
	return TCL_ERROR;
    }







|









>
|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BellObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const bellOptions[] = {
	"-displayof", "-nice", NULL
    };
    enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_Size i;
    int index, nice = 0;
    Tk_ErrorHandler handler;

    if (objc > 4) {
    wrongArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
	return TCL_ERROR;
    }
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BindObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr;
    ClientData object;
    const char *string;

    if ((objc < 2) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?pattern? ?command?");
	return TCL_ERROR;
    }
    string = Tcl_GetString(objv[1]);

    /*
     * Bind tags either a window name or a tag name for the first argument.
     * If the argument starts with ".", assume it is a window; otherwise, it
     * is a tag.
     */

    if (string[0] == '.') {
	winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
	if (winPtr == NULL) {
	    return TCL_ERROR;
	}
	object = (ClientData) winPtr->pathName;
    } else {
	winPtr = (TkWindow *)clientData;
	object = (ClientData) Tk_GetUid(string);
    }

    /*
     * If there are four arguments, the command is modifying a binding. If
     * there are three arguments, the command is querying a binding. If there
     * are only two arguments, the command is querying all the bindings for
     * the given tag/window.







|






|



















|


|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BindObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr;
    void *object;
    const char *string;

    if ((objc < 2) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?pattern? ?command?");
	return TCL_ERROR;
    }
    string = Tcl_GetString(objv[1]);

    /*
     * Bind tags either a window name or a tag name for the first argument.
     * If the argument starts with ".", assume it is a window; otherwise, it
     * is a tag.
     */

    if (string[0] == '.') {
	winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
	if (winPtr == NULL) {
	    return TCL_ERROR;
	}
	object = winPtr->pathName;
    } else {
	winPtr = (TkWindow *)clientData;
	object = (void *) Tk_GetUid(string);
    }

    /*
     * If there are four arguments, the command is modifying a binding. If
     * there are three arguments, the command is querying a binding. If there
     * are only two arguments, the command is querying all the bindings for
     * the given tag/window.
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

	command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
		object, Tcl_GetString(objv[2]));
	if (command == NULL) {
	    Tcl_ResetResult(interp);
	    return TCL_OK;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
    } else {
	Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
    }
    return TCL_OK;
}

/*







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

	command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
		object, Tcl_GetString(objv[2]));
	if (command == NULL) {
	    Tcl_ResetResult(interp);
	    return TCL_OK;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(command, TCL_INDEX_NONE));
    } else {
	Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object);
    }
    return TCL_OK;
}

/*
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

void
TkBindEventProc(
    TkWindow *winPtr,		/* Pointer to info about window. */
    XEvent *eventPtr)		/* Information about event. */
{
#define MAX_OBJS 20
    ClientData objects[MAX_OBJS], *objPtr;
    TkWindow *topLevPtr;
    int i, count;
    const char *p;
    Tcl_HashEntry *hPtr;

    if ((winPtr->mainPtr == NULL) || (winPtr->mainPtr->bindingTable == NULL)) {
	return;
    }

    objPtr = objects;
    if (winPtr->numTags != 0) {
	/*
	 * Make a copy of the tags for the window, replacing window names with
	 * pointers to the pathName from the appropriate window.
	 */

	if (winPtr->numTags > MAX_OBJS) {
	    objPtr = (void **)ckalloc(winPtr->numTags * sizeof(void *));
	}
	for (i = 0; i < winPtr->numTags; i++) {
	    p = (const char *)winPtr->tagPtr[i];
	    if (*p == '.') {
		hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
		if (hPtr != NULL) {
		    p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName;
		} else {
		    p = NULL;
		}
	    }
	    objPtr[i] = (ClientData) p;
	}
	count = winPtr->numTags;
    } else {
	objPtr[0] = (ClientData) winPtr->pathName;
	objPtr[1] = (ClientData) winPtr->classUid;
	for (topLevPtr = winPtr;
		(topLevPtr != NULL) && !(topLevPtr->flags & TK_TOP_HIERARCHY);
		topLevPtr = topLevPtr->parentPtr) {
	    /* Empty loop body. */
	}
	if ((winPtr != topLevPtr) && (topLevPtr != NULL)) {
	    count = 4;
	    objPtr[2] = (ClientData) topLevPtr->pathName;
	} else {
	    count = 3;
	}
	objPtr[count-1] = (ClientData) Tk_GetUid("all");
    }
    Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr,
	    count, objPtr);
    if (objPtr != objects) {
	ckfree(objPtr);
    }
}







|

|
|

















|








|



|
|







|



|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

void
TkBindEventProc(
    TkWindow *winPtr,		/* Pointer to info about window. */
    XEvent *eventPtr)		/* Information about event. */
{
#define MAX_OBJS 20
    void *objects[MAX_OBJS], **objPtr;
    TkWindow *topLevPtr;
    Tcl_Size i, count;
    char *p;
    Tcl_HashEntry *hPtr;

    if ((winPtr->mainPtr == NULL) || (winPtr->mainPtr->bindingTable == NULL)) {
	return;
    }

    objPtr = objects;
    if (winPtr->numTags != 0) {
	/*
	 * Make a copy of the tags for the window, replacing window names with
	 * pointers to the pathName from the appropriate window.
	 */

	if (winPtr->numTags > MAX_OBJS) {
	    objPtr = (void **)ckalloc(winPtr->numTags * sizeof(void *));
	}
	for (i = 0; i < winPtr->numTags; i++) {
	    p = (char *)winPtr->tagPtr[i];
	    if (*p == '.') {
		hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p);
		if (hPtr != NULL) {
		    p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName;
		} else {
		    p = NULL;
		}
	    }
	    objPtr[i] = p;
	}
	count = winPtr->numTags;
    } else {
	objPtr[0] = winPtr->pathName;
	objPtr[1] = (void *)winPtr->classUid;
	for (topLevPtr = winPtr;
		(topLevPtr != NULL) && !(topLevPtr->flags & TK_TOP_HIERARCHY);
		topLevPtr = topLevPtr->parentPtr) {
	    /* Empty loop body. */
	}
	if ((winPtr != topLevPtr) && (topLevPtr != NULL)) {
	    count = 4;
	    objPtr[2] = topLevPtr->pathName;
	} else {
	    count = 3;
	}
	objPtr[count-1] = (void *) Tk_GetUid("all");
    }
    Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr,
	    count, objPtr);
    if (objPtr != objects) {
	ckfree(objPtr);
    }
}
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BindtagsObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr, *winPtr2;
    int i, length;
    const char *p;
    Tcl_Obj *listPtr, **tags;

    if ((objc < 2) || (objc > 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?taglist?");
	return TCL_ERROR;
    }
    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
	    tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	listPtr = Tcl_NewObj();
	if (winPtr->numTags == 0) {
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj(winPtr->pathName, -1));
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj(winPtr->classUid, -1));
	    winPtr2 = winPtr;
	    while ((winPtr2 != NULL) && !(Tk_TopWinHierarchy(winPtr2))) {
		winPtr2 = winPtr2->parentPtr;
	    }
	    if ((winPtr != winPtr2) && (winPtr2 != NULL)) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tcl_NewStringObj(winPtr2->pathName, -1));
	    }
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj("all", -1));
	} else {
	    for (i = 0; i < winPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tcl_NewStringObj((char *) winPtr->tagPtr[i], -1));
	    }
	}
	Tcl_SetObjResult(interp, listPtr);
	return TCL_OK;
    }
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);







|






|
















|

|






|


|



|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_BindtagsObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr, *winPtr2;
    Tcl_Size i, length;
    const char *p;
    Tcl_Obj *listPtr, **tags;

    if ((objc < 2) || (objc > 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "window ?taglist?");
	return TCL_ERROR;
    }
    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
	    tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (objc == 2) {
	listPtr = Tcl_NewObj();
	if (winPtr->numTags == 0) {
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj(winPtr->pathName, TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj(winPtr->classUid, TCL_INDEX_NONE));
	    winPtr2 = winPtr;
	    while ((winPtr2 != NULL) && !(Tk_TopWinHierarchy(winPtr2))) {
		winPtr2 = winPtr2->parentPtr;
	    }
	    if ((winPtr != winPtr2) && (winPtr2 != NULL)) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tcl_NewStringObj(winPtr2->pathName, TCL_INDEX_NONE));
	    }
	    Tcl_ListObjAppendElement(NULL, listPtr,
		    Tcl_NewStringObj("all", TCL_INDEX_NONE));
	} else {
	    for (i = 0; i < winPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tcl_NewStringObj((const char *)winPtr->tagPtr[i], TCL_INDEX_NONE));
	    }
	}
	Tcl_SetObjResult(interp, listPtr);
	return TCL_OK;
    }
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
	     * string, rather than a Uid; at event time we'll look up the name
	     * in the window table and use the corresponding window, if there
	     * is one.
	     */

	    copy = (char *)ckalloc(strlen(p) + 1);
	    strcpy(copy, p);
	    winPtr->tagPtr[i] = (ClientData) copy;
	} else {
	    winPtr->tagPtr[i] = (ClientData) Tk_GetUid(p);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|

|







411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
	     * string, rather than a Uid; at event time we'll look up the name
	     * in the window table and use the corresponding window, if there
	     * is one.
	     */

	    copy = (char *)ckalloc(strlen(p) + 1);
	    strcpy(copy, p);
	    winPtr->tagPtr[i] = copy;
	} else {
	    winPtr->tagPtr[i] = (void *)Tk_GetUid(p);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
 *----------------------------------------------------------------------
 */

void
TkFreeBindingTags(
    TkWindow *winPtr)		/* Window whose tags are to be released. */
{
    int i;
    const char *p;

    for (i = 0; i < winPtr->numTags; i++) {
	p = (const char *)winPtr->tagPtr[i];
	if (*p == '.') {
	    /*
	     * Names starting with "." are malloced rather than Uids, so they
	     * have to be freed.
	     */

	    ckfree((char *)p);
	}
    }
    ckfree(winPtr->tagPtr);
    winPtr->numTags = 0;
    winPtr->tagPtr = NULL;
}








|










|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
 *----------------------------------------------------------------------
 */

void
TkFreeBindingTags(
    TkWindow *winPtr)		/* Window whose tags are to be released. */
{
    Tcl_Size i;
    const char *p;

    for (i = 0; i < winPtr->numTags; i++) {
	p = (const char *)winPtr->tagPtr[i];
	if (*p == '.') {
	    /*
	     * Names starting with "." are malloced rather than Uids, so they
	     * have to be freed.
	     */

	    ckfree((void *)p);
	}
    }
    ckfree(winPtr->tagPtr);
    winPtr->numTags = 0;
    winPtr->tagPtr = NULL;
}

478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_DestroyObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window window;
    Tk_Window tkwin = (Tk_Window)clientData;
    int i;

    for (i = 1; i < objc; i++) {
	window = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
	if (window == NULL) {
	    Tcl_ResetResult(interp);
	    continue;
	}







|






|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_DestroyObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window window;
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_Size i;

    for (i = 1; i < objc; i++) {
	window = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
	if (window == NULL) {
	    Tcl_ResetResult(interp);
	    continue;
	}
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_LowerObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window mainwin = (Tk_Window)clientData;
    Tk_Window tkwin, other;








|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_LowerObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window mainwin = (Tk_Window)clientData;
    Tk_Window tkwin, other;

584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_RaiseObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window mainwin = (Tk_Window)clientData;
    Tk_Window tkwin, other;








|







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_RaiseObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window mainwin = (Tk_Window)clientData;
    Tk_Window tkwin, other;

643
644
645
646
647
648
649
650
651


652
653

654

655
656
657
658
659
660
661
 *
 * ----------------------------------------------------------------------
 */

int
TkInitTkCmd(
    Tcl_Interp *interp,
    ClientData clientData)
{


    TkMakeEnsemble(interp, "::", "tk", clientData, tkCmdMap);
#if defined(_WIN32) || defined(MAC_OSX_TK)

    TkInitFontchooser(interp, clientData);

#endif
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|

>
>
|

>
|
>







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
 *
 * ----------------------------------------------------------------------
 */

int
TkInitTkCmd(
    Tcl_Interp *interp,
    void *clientData)
{
    /* If the interp is safe, leave out "fontchooser" */
    int isSafe = Tcl_IsSafe(interp);
    TkMakeEnsemble(interp, "::", "tk", clientData, tkCmdMap + isSafe);
#if defined(_WIN32) || defined(MAC_OSX_TK)
    if (!isSafe) {
	TkInitFontchooser(interp, clientData);
    }
#endif
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697



698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
AppnameCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr;
    const char *string;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"appname not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "APPLICATION", NULL);
	return TCL_ERROR;
    }

    winPtr = (TkWindow *) tkwin;

    if (objc > 2) {



	Tcl_WrongNumArgs(interp, 1, objv, "?newName?");
	return TCL_ERROR;
    }
    if (objc == 2) {
	string = Tcl_GetString(objv[1]);
	winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, -1));
    return TCL_OK;
}

int
CaretCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int index;
    Tcl_Obj *objPtr;
    TkCaret *caretPtr;
    Tk_Window window;







|

|








|






|
>
>
>



<
<
<
<
|





|

|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708




709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
AppnameCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr;
    const char *string;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"appname not accessible in a safe interpreter", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "APPLICATION", NULL);
	return TCL_ERROR;
    }

    winPtr = (TkWindow *) tkwin;

    if (objc == 2) {
	string = Tcl_GetString(objv[1]);
	winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
    } else if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, "?newName?");
	return TCL_ERROR;
    }




    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, TCL_INDEX_NONE));
    return TCL_OK;
}

int
CaretCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int index;
    Tcl_Obj *objPtr;
    TkCaret *caretPtr;
    Tk_Window window;
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
	} else if (index == TK_CARET_Y) {
	    value = caretPtr->y;
	} else /* if (index == TK_CARET_HEIGHT) -- last case */ {
	    value = caretPtr->height;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(value));
    } else {

	int i, value, x = 0, y = 0, height = -1;

	for (i = 2; i < objc; i += 2) {
	    if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings,
		    "caret option", 0, &index) != TCL_OK) ||
		    Tcl_GetIntFromObj(interp,objv[i+1],&value) != TCL_OK) {
		return TCL_ERROR;
	    }







>
|







774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
	} else if (index == TK_CARET_Y) {
	    value = caretPtr->y;
	} else /* if (index == TK_CARET_HEIGHT) -- last case */ {
	    value = caretPtr->height;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(value));
    } else {
	Tcl_Size i;
	int value, x = 0, y = 0, height = -1;

	for (i = 2; i < objc; i += 2) {
	    if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings,
		    "caret option", 0, &index) != TCL_OK) ||
		    Tcl_GetIntFromObj(interp,objv[i+1],&value) != TCL_OK) {
		return TCL_ERROR;
	    }
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
	Tk_SetCaretPos(window, x, y, height);
    }
    return TCL_OK;
}

int
ScalingCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Screen *screenPtr;

    int skip, width, height;
    double d;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"scaling not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "SCALING", NULL);
	return TCL_ERROR;
    }

    skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    screenPtr = Tk_Screen(tkwin);
    if (objc - skip == 1) {
	d = 25.4 / 72;
	d *= WidthOfScreen(screenPtr);
	d /= WidthMMOfScreen(screenPtr);
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d));





    } else if (objc - skip == 2) {
	if (Tcl_GetDoubleFromObj(interp, objv[1+skip], &d) != TCL_OK) {
	    return TCL_ERROR;
	}

	d = (25.4 / 72) / d;
	width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
	if (width <= 0) {
	    width = 1;
	}
	height = (int) (d * HeightOfScreen(screenPtr) + 0.5);
	if (height <= 0) {
	    height = 1;
	}
	WidthMMOfScreen(screenPtr) = width;
	HeightMMOfScreen(screenPtr) = height;






















    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?factor?");
	return TCL_ERROR;
    }
    return TCL_OK;
}

int
UseinputmethodsCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkDisplay *dispPtr;
    int skip;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"useinputmethods not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "INPUT_METHODS", NULL);
	return TCL_ERROR;
    }

    skip = TkGetDisplayOf(interp, objc-1, objv+1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if ((objc - skip) == 2) {

	int boolVal;

	if (Tcl_GetBooleanFromObj(interp, objv[1+skip],
		&boolVal) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolVal && (dispPtr->inputMethod != NULL)) {
	    dispPtr->flags |= TK_DISPLAY_USE_IM;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_USE_IM;
	}
    } else if ((objc - skip) != 1) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-displayof window? ?boolean?");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_USE_IM));
    return TCL_OK;
}

int
WindowingsystemCmd(
    TCL_UNUSED(void *),	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    const char *windowingsystem;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
#if defined(_WIN32)
    windowingsystem = "win32";
#elif defined(MAC_OSX_TK)
    windowingsystem = "aqua";
#else
    windowingsystem = "x11";
#endif
    Tcl_SetObjResult(interp, Tcl_NewStringObj(windowingsystem, -1));
    return TCL_OK;
}

int
InactiveCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);

    if (skip < 0) {
	return TCL_ERROR;
    }
    if (objc - skip == 1) {
	Tcl_WideInt inactive;

	inactive = (Tcl_IsSafe(interp) ? -1 :
		Tk_GetUserInactiveTime(Tk_Display(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(inactive));
    } else if (objc - skip == 2) {
	const char *string;

	string = Tcl_GetString(objv[objc-1]);
	if (strcmp(string, "reset") != 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad option \"%s\": must be reset", string));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
		    string, NULL);
	    return TCL_ERROR;
	}
	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "resetting the user inactivity timer "
		    "is not allowed in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "INACTIVITY_TIMER", NULL);
	    return TCL_ERROR;
	}
	Tk_ResetUserInactiveTime(Tk_Display(tkwin));
	Tcl_ResetResult(interp);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?reset?");







|

|




>
|
|
<
<
<
<
<
<
<






|




>
>
>
>
>
|



>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|

|




|



|




|




|












|











|

|















|





|

|



|




|





|













|







801
802
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
	Tk_SetCaretPos(window, x, y, height);
    }
    return TCL_OK;
}

int
ScalingCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Screen *screenPtr;
    Tcl_Size skip;
    int width, height, intPct;
    double d, dblPct;








    skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    screenPtr = Tk_Screen(tkwin);
    if (objc == 1 + skip) {
	d = 25.4 / 72;
	d *= WidthOfScreen(screenPtr);
	d /= WidthMMOfScreen(screenPtr);
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d));
    } else if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"setting the scaling not accessible in a safe interpreter", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "SCALING", NULL);
	return TCL_ERROR;
    } else if (objc == 2 + skip) {
	if (Tcl_GetDoubleFromObj(interp, objv[1+skip], &d) != TCL_OK) {
	    return TCL_ERROR;
	}
	dblPct = d * 75;
	d = (25.4 / 72) / d;
	width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
	if (width <= 0) {
	    width = 1;
	}
	height = (int) (d * HeightOfScreen(screenPtr) + 0.5);
	if (height <= 0) {
	    height = 1;
	}
	WidthMMOfScreen(screenPtr) = width;
	HeightMMOfScreen(screenPtr) = height;

	/*
	 * Keep the variables ::tk::scalingPct and ::tk::svgFmt
	 * in sync with the new value of the scaling factor
	 */

	for (intPct = 100; 1; intPct += 25) {
	    if (dblPct < intPct + 12.5) {
		break;
	    }
	}
	Tcl_SetVar2Ex(interp, "::tk::scalingPct", NULL, Tcl_NewIntObj(intPct),
		TCL_GLOBAL_ONLY);

	Tcl_SetVar2Ex(interp, "::tk::svgFmt", NULL,
		Tcl_NewStringObj("svg", TCL_INDEX_NONE), TCL_GLOBAL_ONLY);
	Tcl_SetVar2Ex(interp, "::tk::svgFmt", NULL,
		Tcl_NewStringObj("-scale", TCL_INDEX_NONE),
		TCL_GLOBAL_ONLY | TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
	Tcl_SetVar2Ex(interp, "::tk::svgFmt", NULL,
		Tcl_NewDoubleObj(intPct / 100.0),
		TCL_GLOBAL_ONLY | TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?factor?");
	return TCL_ERROR;
    }
    return TCL_OK;
}

int
UseinputmethodsCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkDisplay *dispPtr;
    Tcl_Size skip;

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"useinputmethods not accessible in a safe interpreter", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "INPUT_METHODS", NULL);
	return TCL_ERROR;
    }

    skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (objc == 2 + skip) {

	int boolVal;

	if (Tcl_GetBooleanFromObj(interp, objv[1+skip],
		&boolVal) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolVal && (dispPtr->inputMethod != NULL)) {
	    dispPtr->flags |= TK_DISPLAY_USE_IM;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_USE_IM;
	}
    } else if (objc != 1 + skip) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-displayof window? ?boolean?");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_USE_IM));
    return TCL_OK;
}

int
WindowingsystemCmd(
    TCL_UNUSED(void *),		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    const char *windowingsystem;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
#if defined(_WIN32)
    windowingsystem = "win32";
#elif defined(MAC_OSX_TK)
    windowingsystem = "aqua";
#else
    windowingsystem = "x11";
#endif
    Tcl_SetObjResult(interp, Tcl_NewStringObj(windowingsystem, TCL_INDEX_NONE));
    return TCL_OK;
}

int
InactiveCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_Size skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);

    if (skip < 0) {
	return TCL_ERROR;
    }
    if (objc == 1 + skip) {
	Tcl_WideInt inactive;

	inactive = (Tcl_IsSafe(interp) ? -1 :
		Tk_GetUserInactiveTime(Tk_Display(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(inactive));
    } else if (objc == 2 + skip) {
	const char *string;

	string = Tcl_GetString(objv[objc-1]);
	if (strcmp(string, "reset") != 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad option \"%s\": must be reset", string));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
		    string, NULL);
	    return TCL_ERROR;
	}
	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "resetting the user inactivity timer "
		    "is not allowed in a safe interpreter", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "INACTIVITY_TIMER", NULL);
	    return TCL_ERROR;
	}
	Tk_ResetUserInactiveTime(Tk_Display(tkwin));
	Tcl_ResetResult(interp);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?reset?");
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_TkwaitObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int done, index;
    int code = TCL_OK;







|







1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_TkwaitObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int done, index;
    int code = TCL_OK;
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
    Tcl_ResetResult(interp);

    return code;
}

static char *
WaitVariableProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),		/* Name of variable. */
    TCL_UNUSED(const char *),		/* Second part of variable name. */
    TCL_UNUSED(int))			/* Information about what happened. */
{
    int *donePtr = (int *)clientData;

    *donePtr = 1;


    return NULL;
}

static void
WaitVisibilityProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event (not used). */
{
    int *donePtr = (int *)clientData;

    if (eventPtr->type == VisibilityNotify) {
	*donePtr = 1;
    } else if (eventPtr->type == DestroyNotify) {
	*donePtr = 2;
    }
}

static void
WaitWindowProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event. */
{
    int *donePtr = (int *)clientData;

    if (eventPtr->type == DestroyNotify) {
	*donePtr = 1;
    }







|
|
|
|
|




>
>





|













|







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
    Tcl_ResetResult(interp);

    return code;
}

static char *
WaitVariableProc(
    void *clientData,		/* Pointer to integer to set to 1. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    TCL_UNUSED(const char *),	/* Second part of variable name. */
    TCL_UNUSED(int))		/* Information about what happened. */
{
    int *donePtr = (int *)clientData;

    *donePtr = 1;
    Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    WaitVariableProc, clientData);
    return NULL;
}

static void
WaitVisibilityProc(
    void *clientData,		/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event (not used). */
{
    int *donePtr = (int *)clientData;

    if (eventPtr->type == VisibilityNotify) {
	*donePtr = 1;
    } else if (eventPtr->type == DestroyNotify) {
	*donePtr = 2;
    }
}

static void
WaitWindowProc(
    void *clientData,		/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event. */
{
    int *donePtr = (int *)clientData;

    if (eventPtr->type == DestroyNotify) {
	*donePtr = 1;
    }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_UpdateObjCmd(
    TCL_UNUSED(void *),	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const updateOptions[] = {"idletasks", NULL};
    int flags, index;
    TkDisplay *dispPtr;







|







1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_UpdateObjCmd(
    TCL_UNUSED(void *),		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const updateOptions[] = {"idletasks", NULL};
    int flags, index;
    TkDisplay *dispPtr;
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275

1276
1277
1278
1279
1280
1281
1282
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WinfoObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index, x, y, width, height, useX, useY, c_class, skip;

    const char *string;
    TkWindow *winPtr;
    Tk_Window tkwin = (Tk_Window)clientData;

    static const TkStateMap visualMap[] = {
	{PseudoColor,	"pseudocolor"},
	{GrayScale,	"grayscale"},







|




|
>







1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WinfoObjCmd(
    void *clientData,		/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index, x, y, width, height, useX, useY, c_class;
    Tcl_Size skip;
    const char *string;
    TkWindow *winPtr;
    Tk_Window tkwin = (Tk_Window)clientData;

    static const TkStateMap visualMap[] = {
	{PseudoColor,	"pseudocolor"},
	{GrayScale,	"grayscale"},
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
	break;
    case WIN_CHILDREN: {
	Tcl_Obj *strPtr, *resultPtr = Tcl_NewObj();

	winPtr = winPtr->childList;
	for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
	    if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {
		strPtr = Tcl_NewStringObj(winPtr->pathName, -1);
		Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	    }
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case WIN_CLASS:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Class(tkwin), -1));
	break;
    case WIN_COLORMAPFULL:
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(TkpCmapStressed(tkwin,Tk_Colormap(tkwin))));
	break;
    case WIN_DEPTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Depth(tkwin)));
	break;
    case WIN_GEOMETRY:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d+%d+%d",
		Tk_Width(tkwin), Tk_Height(tkwin), Tk_X(tkwin), Tk_Y(tkwin)));
	break;
    case WIN_HEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Height(tkwin)));
	break;
    case WIN_ID: {
	char buf[TCL_INTEGER_SPACE];

	Tk_MakeWindowExist(tkwin);
	TkpPrintWindowId(buf, Tk_WindowId(tkwin));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
	break;
    }
    case WIN_ISMAPPED:
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tk_IsMapped(tkwin)));
	break;
    case WIN_MANAGER:
	if (winPtr->geomMgrPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(winPtr->geomMgrPtr->name, -1));
	}
	break;
    case WIN_NAME:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Name(tkwin), -1));
	break;
    case WIN_PARENT:
	if (winPtr->parentPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(winPtr->parentPtr->pathName, -1));
	}
	break;
    case WIN_POINTERX:
	useX = 1;
	useY = 0;
	goto pointerxy;
    case WIN_POINTERY:







|







|




















|








|



|




|







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
	break;
    case WIN_CHILDREN: {
	Tcl_Obj *strPtr, *resultPtr = Tcl_NewObj();

	winPtr = winPtr->childList;
	for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
	    if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {
		strPtr = Tcl_NewStringObj(winPtr->pathName, TCL_INDEX_NONE);
		Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	    }
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case WIN_CLASS:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Class(tkwin), TCL_INDEX_NONE));
	break;
    case WIN_COLORMAPFULL:
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(TkpCmapStressed(tkwin,Tk_Colormap(tkwin))));
	break;
    case WIN_DEPTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Depth(tkwin)));
	break;
    case WIN_GEOMETRY:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d+%d+%d",
		Tk_Width(tkwin), Tk_Height(tkwin), Tk_X(tkwin), Tk_Y(tkwin)));
	break;
    case WIN_HEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Height(tkwin)));
	break;
    case WIN_ID: {
	char buf[TCL_INTEGER_SPACE];

	Tk_MakeWindowExist(tkwin);
	TkpPrintWindowId(buf, Tk_WindowId(tkwin));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
	break;
    }
    case WIN_ISMAPPED:
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tk_IsMapped(tkwin)));
	break;
    case WIN_MANAGER:
	if (winPtr->geomMgrPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(winPtr->geomMgrPtr->name, TCL_INDEX_NONE));
	}
	break;
    case WIN_NAME:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Name(tkwin), TCL_INDEX_NONE));
	break;
    case WIN_PARENT:
	if (winPtr->parentPtr != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(winPtr->parentPtr->pathName, TCL_INDEX_NONE));
	}
	break;
    case WIN_POINTERX:
	useX = 1;
	useY = 0;
	goto pointerxy;
    case WIN_POINTERY:
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
	goto visual;
    case WIN_SERVER:
	TkGetServerInfo(interp, tkwin);
	break;
    case WIN_TOPLEVEL:
	winPtr = GetTopHierarchy(tkwin);
	if (winPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->pathName, -1));
	}
	break;
    case WIN_VIEWABLE: {
	int viewable = 0;

	for ( ; ; winPtr = winPtr->parentPtr) {
	    if ((winPtr == NULL) || !(winPtr->flags & TK_MAPPED)) {







|







1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
	goto visual;
    case WIN_SERVER:
	TkGetServerInfo(interp, tkwin);
	break;
    case WIN_TOPLEVEL:
	winPtr = GetTopHierarchy(tkwin);
	if (winPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->pathName, TCL_INDEX_NONE));
	}
	break;
    case WIN_VIEWABLE: {
	int viewable = 0;

	for ( ; ; winPtr = winPtr->parentPtr) {
	    if ((winPtr == NULL) || !(winPtr->flags & TK_MAPPED)) {
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
	c_class = Tk_Visual(tkwin)->c_class;

    visual:
	string = TkFindStateString(visualMap, c_class);
	if (string == NULL) {
	    string = "unknown";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(string, -1));
	break;
    case WIN_VISUALID:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned)
		XVisualIDFromVisual(Tk_Visual(tkwin))));
	break;
    case WIN_VROOTHEIGHT:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);







|







1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
	c_class = Tk_Visual(tkwin)->c_class;

    visual:
	string = TkFindStateString(visualMap, c_class);
	if (string == NULL) {
	    string = "unknown";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(string, TCL_INDEX_NONE));
	break;
    case WIN_VISUALID:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned)
		XVisualIDFromVisual(Tk_Visual(tkwin))));
	break;
    case WIN_VROOTHEIGHT:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
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
	 */

    case WIN_ATOM:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
	    return TCL_ERROR;
	}
	objv += skip;
	string = Tcl_GetString(objv[2]);
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(Tk_InternAtom(tkwin, string)));
	break;
    case WIN_ATOMNAME: {
	const char *name;
	Tcl_WideInt id;

	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
	    return TCL_ERROR;
	}
	objv += skip;
	if (Tcl_GetWideIntFromObj(interp, objv[2], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	name = Tk_GetAtomName(tkwin, (Atom) id);
	if (strcmp(name, "?bad atom?") == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no atom exists with id \"%s\"", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "ATOM",
		    Tcl_GetString(objv[2]), NULL);
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
	break;
    }
    case WIN_CONTAINING:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-displayof window? rootX rootY");
	    return TCL_ERROR;
	}
	objv += skip;
	string = Tcl_GetString(objv[2]);
	if (Tk_GetPixels(interp, tkwin, string, &x) != TCL_OK) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
	    return TCL_ERROR;
	}
	tkwin = Tk_CoordsToWindow(x, y, tkwin);
	if (tkwin != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin),-1));
	}
	break;
    case WIN_INTERPS:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
	    return TCL_ERROR;
	}
	return TkGetInterpNames(interp, tkwin);
    case WIN_PATHNAME: {
	Window id;

	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[2 + skip]);
	if (TkpScanWindowId(interp, string, &id) != TCL_OK) {
	    return TCL_ERROR;
	}







|
















|















|







|















|







|











|







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
	 */

    case WIN_ATOM:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc != 3 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
	    return TCL_ERROR;
	}
	objv += skip;
	string = Tcl_GetString(objv[2]);
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(Tk_InternAtom(tkwin, string)));
	break;
    case WIN_ATOMNAME: {
	const char *name;
	Tcl_WideInt id;

	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc != 3 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
	    return TCL_ERROR;
	}
	objv += skip;
	if (Tcl_GetWideIntFromObj(interp, objv[2], &id) != TCL_OK) {
	    return TCL_ERROR;
	}
	name = Tk_GetAtomName(tkwin, (Atom) id);
	if (strcmp(name, "?bad atom?") == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no atom exists with id \"%s\"", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "ATOM",
		    Tcl_GetString(objv[2]), NULL);
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, TCL_INDEX_NONE));
	break;
    }
    case WIN_CONTAINING:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc != 4 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-displayof window? rootX rootY");
	    return TCL_ERROR;
	}
	objv += skip;
	string = Tcl_GetString(objv[2]);
	if (Tk_GetPixels(interp, tkwin, string, &x) != TCL_OK) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
	    return TCL_ERROR;
	}
	tkwin = Tk_CoordsToWindow(x, y, tkwin);
	if (tkwin != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin), TCL_INDEX_NONE));
	}
	break;
    case WIN_INTERPS:
	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc != 2 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
	    return TCL_ERROR;
	}
	return TkGetInterpNames(interp, tkwin);
    case WIN_PATHNAME: {
	Window id;

	skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc != 3 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[2 + skip]);
	if (TkpScanWindowId(interp, string, &id) != TCL_OK) {
	    return TCL_ERROR;
	}
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
	 * If the window is a utility window with no associated path (such as
	 * a wrapper window or send communication window), just return an
	 * empty string.
	 */

	tkwin = (Tk_Window) winPtr;
	if (Tk_PathName(tkwin) != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin),-1));
	}
	break;
    }

	/*
	 * objv[3] is window.
	 */







|







1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
	 * If the window is a utility window with no associated path (such as
	 * a wrapper window or send communication window), just return an
	 * empty string.
	 */

	tkwin = (Tk_Window) winPtr;
	if (Tk_PathName(tkwin) != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin), TCL_INDEX_NONE));
	}
	break;
    }

	/*
	 * objv[3] is window.
	 */
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
	}

	templ.screen = Tk_ScreenNumber(tkwin);
	visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
		&templ, &count);
	if (visInfoPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find any visuals for screen", -1));
	    Tcl_SetErrorCode(interp, "TK", "VISUAL", "NONE", NULL);
	    return TCL_ERROR;
	}
	resultPtr = Tcl_NewObj();
	for (i = 0; i < count; i++) {
	    string = TkFindStateString(visualMap, visInfoPtr[i].c_class);
	    if (string == NULL) {
		strcpy(buf, "unknown");
	    } else {
		sprintf(buf, "%s %d", string, visInfoPtr[i].depth);
	    }
	    if (includeVisualId) {
		sprintf(visualIdString, " 0x%lx",
			(unsigned long) visInfoPtr[i].visualid);
		strcat(buf, visualIdString);
	    }
	    strPtr = Tcl_NewStringObj(buf, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
	Tcl_SetObjResult(interp, resultPtr);
	XFree((char *) visInfoPtr);
	break;
    }
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * TkGetDisplayOf --
 *
 *	Parses a "-displayof window" option for various commands. If present,
 *	the literal "-displayof" should be in objv[0] and the window name in
 *	objv[1].
 *
 * Results:
 *	The return value is 0 if the argument strings did not contain the
 *	"-displayof" option. The return value is 2 if the argument strings
 *	contained both the "-displayof" option and a valid window name.
 *	Otherwise, the return value is -1 if the window name was missing or
 *	did not specify a valid window.
 *
 *	If the return value was 2, *tkwinPtr is filled with the token for the
 *	window specified on the command line. If the return value was -1, an
 *	error message is left in interp's result object.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkGetDisplayOf(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. If it is present,
				 * "-displayof" should be in objv[0] and
				 * objv[1] the name of a window. */
    Tk_Window *tkwinPtr)	/* On input, contains main window of
				 * application associated with interp. On
				 * output, filled with window specified as
				 * option to "-displayof" argument, or
				 * unmodified if "-displayof" argument was not
				 * present. */
{
    const char *string;
    TkSizeT length;

    if (objc < 1) {
	return 0;
    }
    string = TkGetStringFromObj(objv[0], &length);
    if ((length >= 2) &&
	    (strncmp(string, "-displayof", length) == 0)) {
        if (objc < 2) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "value for \"-displayof\" missing", -1));
	    Tcl_SetErrorCode(interp, "TK", "NO_VALUE", "DISPLAYOF", NULL);
	    return -1;
	}
	*tkwinPtr = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), *tkwinPtr);
	if (*tkwinPtr == NULL) {
	    return -1;
	}
	return 2;
    }
    return 0;
}

/*







|









|


|



|



|




















|
|


|
|







|


|











|

|


|




|

|



|







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
	}

	templ.screen = Tk_ScreenNumber(tkwin);
	visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
		&templ, &count);
	if (visInfoPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find any visuals for screen", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VISUAL", "NONE", NULL);
	    return TCL_ERROR;
	}
	resultPtr = Tcl_NewObj();
	for (i = 0; i < count; i++) {
	    string = TkFindStateString(visualMap, visInfoPtr[i].c_class);
	    if (string == NULL) {
		strcpy(buf, "unknown");
	    } else {
		snprintf(buf, sizeof(buf), "%s %d", string, visInfoPtr[i].depth);
	    }
	    if (includeVisualId) {
		snprintf(visualIdString, sizeof(visualIdString), " 0x%lx",
			(unsigned long) visInfoPtr[i].visualid);
		strcat(buf, visualIdString);
	    }
	    strPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
	Tcl_SetObjResult(interp, resultPtr);
	XFree(visInfoPtr);
	break;
    }
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * TkGetDisplayOf --
 *
 *	Parses a "-displayof window" option for various commands. If present,
 *	the literal "-displayof" should be in objv[0] and the window name in
 *	objv[1].
 *
 * Results:
 *	The return value is 0 if the argument strings did not contain the
 *	"-displayof" option. The return value is 2 if the argument strings
 *	contained both the "-displayof" option and a valid window name.
 *	Otherwise, the return value is TCL_INDEX_NONE if the window name
 *	was missing or did not specify a valid window.
 *
 *	If the return value was 2, *tkwinPtr is filled with the token for the
 *	window specified on the command line. If the return value was
 *	TCL_INDEX_NONE, an error message is left in interp's result object.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Size
TkGetDisplayOf(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tcl_Size objc,		/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. If it is present,
				 * "-displayof" should be in objv[0] and
				 * objv[1] the name of a window. */
    Tk_Window *tkwinPtr)	/* On input, contains main window of
				 * application associated with interp. On
				 * output, filled with window specified as
				 * option to "-displayof" argument, or
				 * unmodified if "-displayof" argument was not
				 * present. */
{
    const char *string;
    Tcl_Size length;

    if (objc + 1 < 2) {
	return 0;
    }
    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", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "NO_VALUE", "DISPLAYOF", NULL);
	    return TCL_INDEX_NONE;
	}
	*tkwinPtr = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), *tkwinPtr);
	if (*tkwinPtr == NULL) {
	    return TCL_INDEX_NONE;
	}
	return 2;
    }
    return 0;
}

/*
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
 *----------------------------------------------------------------------
 */

int
TkDeadAppObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "can't invoke \"%s\" command: application has been destroyed",
	    Tcl_GetString(objv[0])));
    return TCL_ERROR;
}








|
|







1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
 *----------------------------------------------------------------------
 */

int
TkDeadAppObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),		/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "can't invoke \"%s\" command: application has been destroyed",
	    Tcl_GetString(objv[0])));
    return TCL_ERROR;
}

1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
 *
 *----------------------------------------------------------------------
 */

static TkWindow *
GetTopHierarchy(
    Tk_Window tkwin)		/* Window for which the top-of-hierarchy
				 * ancestor should be deterined. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    while ((winPtr != NULL) && !(winPtr->flags & TK_TOP_HIERARCHY)) {
	winPtr = winPtr->parentPtr;
    }
    return winPtr;







|







1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
 *
 *----------------------------------------------------------------------
 */

static TkWindow *
GetTopHierarchy(
    Tk_Window tkwin)		/* Window for which the top-of-hierarchy
				 * ancestor should be determined. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    while ((winPtr != NULL) && !(winPtr->flags & TK_TOP_HIERARCHY)) {
	winPtr = winPtr->parentPtr;
    }
    return winPtr;

Changes to generic/tkColor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16




17
18
19
20
21
22
23
/*
 * 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.
 *
 * 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"





/*
 * Structures of the following following type are used as keys for
 * colorValueTable (in TkDisplay).
 */

typedef struct {







|
|







>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * 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 © 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Structures of the following following type are used as keys for
 * colorValueTable (in TkDisplay).
 */

typedef struct {
48
49
50
51
52
53
54
55
56
57
58
59
60


61
62
63
64
65
66
67

/*
 * The following structure defines the implementation of the "color" Tcl
 * object, which maps a string color name to a TkColor object. The ptr1 field
 * of the Tcl_Obj points to a TkColor object.
 */

const Tcl_ObjType tkColorObjType = {
    "color",			/* name */
    FreeColorObjProc,		/* freeIntRepProc */
    DupColorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocColorFromObj --
 *







|
|



|
>
>







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

/*
 * The following structure defines the implementation of the "color" Tcl
 * object, which maps a string color name to a TkColor object. The ptr1 field
 * of the Tcl_Obj points to a TkColor object.
 */

const TkObjType tkColorObjType = {
    {"color",			/* name */
    FreeColorObjProc,		/* freeIntRepProc */
    DupColorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocColorFromObj --
 *
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    Tk_Window tkwin,		/* Window in which the color will be used.*/
    Tcl_Obj *objPtr)		/* Object that describes the color; string
				 * value is a color name such as "red" or
				 * "#ff0000".*/
{
    TkColor *tkColPtr;

    if (objPtr->typePtr != &tkColorObjType) {
	InitColorObj(objPtr);
    }
    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkColor, see if it's the one we
     * want. If so, increment its reference count and return.







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    Tk_Window tkwin,		/* Window in which the color will be used.*/
    Tcl_Obj *objPtr)		/* Object that describes the color; string
				 * value is a color name such as "red" or
				 * "#ff0000".*/
{
    TkColor *tkColPtr;

    if (objPtr->typePtr != &tkColorObjType.objType) {
	InitColorObj(objPtr);
    }
    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkColor, see if it's the one we
     * want. If so, increment its reference count and return.
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

    if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red,
		colorPtr->green, colorPtr->blue);

	/*
	 * If the string has the form #RSRSTUTUVWVW (where equal letters
	 * denote equal hexdigits) then this is equivalent to #RSTUVW. Then
	 * output the shorter form.
	 */







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

    if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	snprintf(tsdPtr->rgbString, sizeof(tsdPtr->rgbString), "#%04x%04x%04x", colorPtr->red,
		colorPtr->green, colorPtr->blue);

	/*
	 * If the string has the form #RSRSTUTUVWVW (where equal letters
	 * denote equal hexdigits) then this is equivalent to #RSTUVW. Then
	 * output the shorter form.
	 */
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
    Tcl_Obj *objPtr)		/* String value contains the name of the
				 * desired color. */
{
    TkColor *tkColPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkColorObjType) {
	InitColorObj(objPtr);
    }

    /*
     * First check to see if the internal representation of the object is
     * defined and is a color that is valid for the current screen and color
     * map. If it is, we are done.







|







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
    Tcl_Obj *objPtr)		/* String value contains the name of the
				 * desired color. */
{
    TkColor *tkColPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkColorObjType.objType) {
	InitColorObj(objPtr);
    }

    /*
     * First check to see if the internal representation of the object is
     * defined and is a color that is valid for the current screen and color
     * map. If it is, we are done.
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkColorObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * ColorInit --







|







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkColorObjType.objType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * ColorInit --
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
	if (tkColPtr == NULL) {
	    Tcl_Panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef _WIN32







|

|







820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
	if (tkColPtr == NULL) {
	    Tcl_Panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj((Tcl_WideInt)tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj((Tcl_WideInt)tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef _WIN32

Changes to generic/tkColor.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkColor.h --
 *
 *	Declarations of data types and functions used by the Tk color module.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCOLOR
#define _TKCOLOR





|







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 © 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCOLOR
#define _TKCOLOR
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
				 * color and all other fields defaulted. May
				 * be NULL. */
    Screen *screen;		/* Screen where this color is valid. Used to
				 * delete it, and to find its display. */
    Colormap colormap;		/* Colormap from which this entry was
				 * allocated. */
    Visual *visual;		/* Visual associated with colormap. */
    TkSizeT resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_AllocColorFromObj or Tk_GetColor). If
				 * this count is 0, then this TkColor
				 * structure is no longer valid and it isn't
				 * present in a hash table: it is being kept
				 * around only because there are objects
				 * referring to it. The structure is freed
				 * when resourceRefCount and objRefCount are
				 * both 0. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    int type;			/* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE. */
    Tcl_HashEntry *hashPtr;	/* Pointer to hash table entry for this
				 * structure. (for use in deleting entry). */
    struct TkColor *nextPtr;	/* Points to the next TkColor structure with
				 * the same color name. Colors with the same
				 * name but different screens or colormaps are







|









|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
				 * color and all other fields defaulted. May
				 * be NULL. */
    Screen *screen;		/* Screen where this color is valid. Used to
				 * delete it, and to find its display. */
    Colormap colormap;		/* Colormap from which this entry was
				 * allocated. */
    Visual *visual;		/* Visual associated with colormap. */
    Tcl_Size resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_AllocColorFromObj or Tk_GetColor). If
				 * this count is 0, then this TkColor
				 * structure is no longer valid and it isn't
				 * present in a hash table: it is being kept
				 * around only because there are objects
				 * referring to it. The structure is freed
				 * when resourceRefCount and objRefCount are
				 * both 0. */
    Tcl_Size objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    int type;			/* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE. */
    Tcl_HashEntry *hashPtr;	/* Pointer to hash table entry for this
				 * structure. (for use in deleting entry). */
    struct TkColor *nextPtr;	/* Points to the next TkColor structure with
				 * the same color name. Colors with the same
				 * name but different screens or colormaps are

Changes to generic/tkConfig.c.

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.
 *
 * 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.






|







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 © 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.
22
23
24
25
26
27
28














29
30
31
32
33
34
35

#define __NO_OLD_CONFIG
#endif

#include "tkInt.h"
#include "tkFont.h"















/*
 * The following definition keeps track of all of
 * the option tables that have been created for a thread.
 */

typedef struct {
    int initialized;		/* 0 means table below needs initializing. */







>
>
>
>
>
>
>
>
>
>
>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#define __NO_OLD_CONFIG
#endif

#include "tkInt.h"
#include "tkFont.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following encoding is used in TK_OPTION_VAR:
 *
 * if sizeof(type) == sizeof(int)        =>    TK_OPTION_VAR(type) = 0
 * if sizeof(type) == 1                  =>    TK_OPTION_VAR(type) = 64
 * if sizeof(type) == 2                  =>    TK_OPTION_VAR(type) = 128
 * if sizeof(type) == sizeof(long long)  =>    TK_OPTION_VAR(type) = 192
 */
#define TYPE_MASK        (((((int)sizeof(int)-1))|3)<<6)

/*
 * The following definition keeps track of all of
 * the option tables that have been created for a thread.
 */

typedef struct {
    int initialized;		/* 0 means table below needs initializing. */
134
135
136
137
138
139
140
141
142
143
144
145
146


147
148
149
150
151
152
153
/*
 * The structure below defines an object type that is used to cache the result
 * of looking up an option name. If an object has this type, then its
 * internalPtr1 field points to the OptionTable in which it was looked up, and
 * the internalPtr2 field points to the entry that matched.
 */

static const Tcl_ObjType optionObjType = {
    "option",			/* name */
    FreeOptionInternalRep,	/* freeIntRepProc */
    DupOptionInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateOptionTable --
 *







|
|



|
>
>







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * The structure below defines an object type that is used to cache the result
 * of looking up an option name. If an object has this type, then its
 * internalPtr1 field points to the OptionTable in which it was looked up, and
 * the internalPtr2 field points to the entry that matched.
 */

static const TkObjType optionObjType = {
    {"option",			/* name */
    FreeOptionInternalRep,	/* freeIntRepProc */
    DupOptionInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateOptionTable --
 *
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
	    if (specPtr->dbName != NULL) {
		optionPtr->dbNameUID = Tk_GetUid(specPtr->dbName);
	    }
	    if (specPtr->dbClass != NULL) {
		optionPtr->dbClassUID = Tk_GetUid(specPtr->dbClass);
	    }
	    if (specPtr->defValue != NULL) {
		optionPtr->defaultPtr = Tcl_NewStringObj(specPtr->defValue,-1);
		Tcl_IncrRefCount(optionPtr->defaultPtr);
	    }
	    if (((specPtr->type == TK_OPTION_COLOR)
		    || (specPtr->type == TK_OPTION_BORDER))
		    && (specPtr->clientData != NULL)) {
		optionPtr->extra.monoColorPtr =
			Tcl_NewStringObj((const char *)specPtr->clientData, -1);
		Tcl_IncrRefCount(optionPtr->extra.monoColorPtr);
	    }

	    if (specPtr->type == TK_OPTION_CUSTOM) {
		/*
		 * Get the custom parsing, etc., functions.
		 */







|






|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
	    if (specPtr->dbName != NULL) {
		optionPtr->dbNameUID = Tk_GetUid(specPtr->dbName);
	    }
	    if (specPtr->dbClass != NULL) {
		optionPtr->dbClassUID = Tk_GetUid(specPtr->dbClass);
	    }
	    if (specPtr->defValue != NULL) {
		optionPtr->defaultPtr = Tcl_NewStringObj(specPtr->defValue, TCL_INDEX_NONE);
		Tcl_IncrRefCount(optionPtr->defaultPtr);
	    }
	    if (((specPtr->type == TK_OPTION_COLOR)
		    || (specPtr->type == TK_OPTION_BORDER))
		    && (specPtr->clientData != NULL)) {
		optionPtr->extra.monoColorPtr =
			Tcl_NewStringObj((const char *)specPtr->clientData, TCL_INDEX_NONE);
		Tcl_IncrRefCount(optionPtr->extra.monoColorPtr);
	    }

	    if (specPtr->type == TK_OPTION_CUSTOM) {
		/*
		 * Get the custom parsing, etc., functions.
		 */
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
				 * window they are used in to be able to
				 * calculate their values. Not needed unless
				 * one of these options is in the configSpecs
				 * record. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    int count;
    Tk_Uid value;
    Tcl_Obj *valuePtr;
    enum {
	OPTION_DATABASE, SYSTEM_DEFAULT, TABLE_DEFAULT
    } source;

    /*







|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
				 * window they are used in to be able to
				 * calculate their values. Not needed unless
				 * one of these options is in the configSpecs
				 * record. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    size_t count;
    Tk_Uid value;
    Tcl_Obj *valuePtr;
    enum {
	OPTION_DATABASE, SYSTEM_DEFAULT, TABLE_DEFAULT
    } source;

    /*
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
	 */

	valuePtr = NULL;
	if (optionPtr->dbNameUID != NULL) {
	    value = Tk_GetOption(tkwin, optionPtr->dbNameUID,
		    optionPtr->dbClassUID);
	    if (value != NULL) {
		valuePtr = Tcl_NewStringObj(value, -1);
		source = OPTION_DATABASE;
	    }
	}

	/*
	 * Second, check for a system-specific default value.
	 */

	if ((valuePtr == NULL)
		&& (optionPtr->dbNameUID != NULL)) {
	    valuePtr = TkpGetSystemDefault(tkwin, optionPtr->dbNameUID,
		    optionPtr->dbClassUID);
	    if (valuePtr != NULL) {
		source = SYSTEM_DEFAULT;
	    }
	}

	/*







|










|







456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	 */

	valuePtr = NULL;
	if (optionPtr->dbNameUID != NULL) {
	    value = Tk_GetOption(tkwin, optionPtr->dbNameUID,
		    optionPtr->dbClassUID);
	    if (value != NULL) {
		valuePtr = Tcl_NewStringObj(value, TCL_INDEX_NONE);
		source = OPTION_DATABASE;
	    }
	}

	/*
	 * Second, check for a system-specific default value.
	 */

	if ((valuePtr == NULL)
		&& (optionPtr->dbNameUID != NULL)) {
	    valuePtr = Tk_GetSystemDefault(tkwin, optionPtr->dbNameUID,
		    optionPtr->dbClassUID);
	    if (valuePtr != NULL) {
		source = SYSTEM_DEFAULT;
	    }
	}

	/*
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
	if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin,
		NULL) != TCL_OK) {
	    if (interp != NULL) {
		char msg[200];

		switch (source) {
		case OPTION_DATABASE:
		    sprintf(msg, "\n    (database entry for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		    break;
		case SYSTEM_DEFAULT:
		    sprintf(msg, "\n    (system default for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		    break;
		case TABLE_DEFAULT:
		    sprintf(msg, "\n    (default value for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		}
		if (tkwin != NULL) {
		    sprintf(msg + strlen(msg) - 1, " in widget \"%.50s\")",
			    Tk_PathName(tkwin));
		}
		Tcl_AddErrorInfo(interp, msg);
	    }
	    Tcl_DecrRefCount(valuePtr);
	    return TCL_ERROR;
	}







|



|



|



|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
	if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin,
		NULL) != TCL_OK) {
	    if (interp != NULL) {
		char msg[200];

		switch (source) {
		case OPTION_DATABASE:
		    snprintf(msg, 200, "\n    (database entry for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		    break;
		case SYSTEM_DEFAULT:
		    snprintf(msg, 200, "\n    (system default for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		    break;
		case TABLE_DEFAULT:
		    snprintf(msg, 200, "\n    (default value for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		}
		if (tkwin != NULL) {
		    snprintf(msg + strlen(msg) - 1, 200 - (strlen(msg) - 1), " in widget \"%.50s\")",
			    Tk_PathName(tkwin));
		}
		Tcl_AddErrorInfo(interp, msg);
	    }
	    Tcl_DecrRefCount(valuePtr);
	    return TCL_ERROR;
	}
542
543
544
545
546
547
548




549
550
551
552
553
554
555
 * Side effects:
 *	RecordPtr gets modified to hold the new value in the form of a
 *	Tcl_Obj, an internal representation, or both. The old value is freed
 *	if oldValuePtrPtr is NULL.
 *
 *--------------------------------------------------------------
 */





static int
DoObjConfig(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no message is left if an error
				 * occurs. */
    void *recordPtr,		/* The record to modify to hold the new option







>
>
>
>







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
 * Side effects:
 *	RecordPtr gets modified to hold the new value in the form of a
 *	Tcl_Obj, an internal representation, or both. The old value is freed
 *	if oldValuePtrPtr is NULL.
 *
 *--------------------------------------------------------------
 */

static const char *const justifyFullStrings[] = {
    "left", "right", "center", "full", NULL
};

static int
DoObjConfig(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no message is left if an error
				 * occurs. */
    void *recordPtr,		/* The record to modify to hold the new option
605
606
607
608
609
610
611
612
613
614
615
616



617




618
619
620











621
622
623

624
625
626
627
628




629






630









































631
632
633
634
635
636
637
638
639
640
641
642

643



644
645








646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688



689

690











691
692

693
694
695
696
697
698
699
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;
    } else {
	oldInternalPtr = (char *) &internal.internalForm;
    }
    nullOK = (optionPtr->specPtr->flags & TK_OPTION_NULL_OK);
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_BOOLEAN: {
	int newBool;




	if (Tcl_GetBooleanFromObj(interp, valuePtr, &newBool) != TCL_OK) {




	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {











	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newBool;
	}

	break;
    }
    case TK_OPTION_INT: {
	int newInt;





	if (Tcl_GetIntFromObj(interp, valuePtr, &newInt) != TCL_OK) {






	    return TCL_ERROR;









































	}
	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newInt;
	}
	break;
    }
    case TK_OPTION_DOUBLE: {
	double newDbl;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;

	    newDbl = 0;



	} else {
	    if (Tcl_GetDoubleFromObj(interp, valuePtr, &newDbl) != TCL_OK) {








		return TCL_ERROR;
	    }
	}

	if (internalPtr != NULL) {
	    *((double *) oldInternalPtr) = *((double *) internalPtr);
	    *((double *) internalPtr) = newDbl;
	}
	break;
    }
    case TK_OPTION_STRING: {
	char *newStr;
	const char *value;
	TkSizeT length;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	}
	if (internalPtr != NULL) {
	    if (valuePtr != NULL) {
		value = TkGetStringFromObj(valuePtr, &length);
		newStr = (char *)ckalloc(length + 1);
		strcpy(newStr, value);
	    } else {
		newStr = NULL;
	    }
	    *((char **) oldInternalPtr) = *((char **) internalPtr);
	    *((char **) internalPtr) = newStr;
	}
	break;
    }
    case TK_OPTION_STRING_TABLE: {
	int newValue;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
            newValue = -1;
        } else {
	    if (Tcl_GetIndexFromObjStruct(interp, valuePtr,
		    optionPtr->specPtr->clientData, sizeof(char *),
		    optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
	        return TCL_ERROR;
	    }



        }

	if (internalPtr != NULL) {











	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newValue;

	}
	break;
    }
    case TK_OPTION_COLOR: {
	XColor *newPtr;

	if (nullOK && ObjectIsEmpty(valuePtr)) {







|




>
>
>
|
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
|
|
|
>





>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|








>
|
>
>
>

|
>
>
>
>
>
>
>
>













|






|















|
|


|
|

>
>
>
|
>

>
>
>
>
>
>
>
>
>
>
>
|
|
>







625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;
    } else {
	oldInternalPtr = (char *) &internal.internalForm;
    }
    nullOK = (optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|TCL_NULL_OK));
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_BOOLEAN: {
	int newBool;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newBool = -1;
	} else if (Tcl_GetBooleanFromObj(nullOK ? NULL : interp, valuePtr, &newBool) != TCL_OK) {
	    if (nullOK && interp) {
		Tcl_AppendResult(interp, "expected boolean value or \"\" but got \"",
			Tcl_GetString(valuePtr), "\"", NULL);
	    }
	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = (char)newBool;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = (short)newBool;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_BOOLEAN");
		}
	    } else {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newBool;
	    }
	}
	break;
    }
    case TK_OPTION_INT: {
	int newInt;

	if ((optionPtr->specPtr->flags & TYPE_MASK) == 0) {
	    if (nullOK && ObjectIsEmpty(valuePtr)) {
		valuePtr = NULL;
		newInt = INT_MIN;
	    } else if (Tcl_GetIntFromObj(nullOK ? NULL : interp, valuePtr, &newInt) != TCL_OK) {
	    invalidIntValue:
		if (nullOK && interp) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "expected integer or \"\" but got \"%.50s\"", Tcl_GetString(valuePtr)));
		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
		}
		return TCL_ERROR;
	    }
	    if (internalPtr != NULL) {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newInt;
	    }
	} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_MASK) {
	    Tcl_WideInt newWideInt;
	    if (nullOK && ObjectIsEmpty(valuePtr)) {
		valuePtr = NULL;
		newWideInt = (sizeof(long) > sizeof(int)) ? LONG_MIN : LLONG_MIN;
	    } else if (Tcl_GetWideIntFromObj(nullOK ? NULL : interp, valuePtr, &newWideInt) != TCL_OK) {
		goto invalidIntValue;
	    }
		if (internalPtr != NULL) {
			if (sizeof(long) > sizeof(int)) {
			    *((long *) oldInternalPtr) = *((long *) internalPtr);
			    *((long *) internalPtr) = (long)newWideInt;
			} else {
			    *((long long *) oldInternalPtr) = *((long long *) internalPtr);
			    *((long long *) internalPtr) = (long long)newWideInt;
			}
		}
	} else {
	    Tcl_Panic("Invalid flags for %s", "TK_OPTION_INT");
	}
	break;
    }
    case TK_OPTION_INDEX: {
	Tcl_Size newIndex;

	if (TkGetIntForIndex(valuePtr, TCL_INDEX_NONE, 0, &newIndex) != TCL_OK) {
	    if (interp) {
		Tcl_AppendResult(interp, "bad index \"", Tcl_GetString(valuePtr),
			"\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"", NULL);
	    }
	    return TCL_ERROR;
	}
	if (newIndex < INT_MIN) {
	    newIndex = INT_MIN;
	} else if (newIndex > INT_MAX) {
	    newIndex = INT_MAX;
	}
	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = (int)newIndex;
	}
	break;
    }
    case TK_OPTION_DOUBLE: {
	double newDbl;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
#if defined(NAN)
	    newDbl = NAN;
#else
	    newDbl = 0.0;
#endif
	} else {
	    if (Tcl_GetDoubleFromObj(nullOK ? NULL : interp, valuePtr, &newDbl) != TCL_OK) {
		if (nullOK && interp) {
		    Tcl_Obj *msg = Tcl_NewStringObj("expected floating-point number or \"\" but got \"", TCL_INDEX_NONE);

		    Tcl_AppendLimitedToObj(msg, Tcl_GetString(valuePtr), TCL_INDEX_NONE, 50, "");
		    Tcl_AppendToObj(msg, "\"", TCL_INDEX_NONE);
		    Tcl_SetObjResult(interp, msg);
		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
		}
		return TCL_ERROR;
	    }
	}

	if (internalPtr != NULL) {
	    *((double *) oldInternalPtr) = *((double *) internalPtr);
	    *((double *) internalPtr) = newDbl;
	}
	break;
    }
    case TK_OPTION_STRING: {
	char *newStr;
	const char *value;
	Tcl_Size length;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	}
	if (internalPtr != NULL) {
	    if (valuePtr != NULL) {
		value = Tcl_GetStringFromObj(valuePtr, &length);
		newStr = (char *)ckalloc(length + 1);
		strcpy(newStr, value);
	    } else {
		newStr = NULL;
	    }
	    *((char **) oldInternalPtr) = *((char **) internalPtr);
	    *((char **) internalPtr) = newStr;
	}
	break;
    }
    case TK_OPTION_STRING_TABLE: {
	int newValue;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newValue = -1;
	} else {
	    if (Tcl_GetIndexFromObjStruct(interp, valuePtr,
		    optionPtr->specPtr->clientData, sizeof(char *),
		    optionPtr->specPtr->optionName+1, (nullOK ? TCL_NULL_OK : 0), &newValue) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (slotPtrPtr != NULL && valuePtr != NULL) {
		valuePtr = Tcl_DuplicateObj(valuePtr);
		Tcl_InvalidateStringRep(valuePtr);
	    }
	}
	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = (char)newValue;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = (short)newValue;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		}
	    } else {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newValue;
	    }
	}
	break;
    }
    case TK_OPTION_COLOR: {
	XColor *newPtr;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
785
786
787
788
789
790
791
792
793
794
795
796
797











798
799





800
801
802
803
804
805
806
    }
    case TK_OPTION_RELIEF: {
	int newRelief;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newRelief = TK_RELIEF_NULL;
	} else {
	    if (Tk_GetReliefFromObj(interp, valuePtr, &newRelief) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	if (internalPtr != NULL) {











	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newRelief;





	}
	break;
    }
    case TK_OPTION_CURSOR: {
	Tk_Cursor newCursor;

	if (nullOK && ObjectIsEmpty(valuePtr)) {







|
|
|
|
<

>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>







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
    }
    case TK_OPTION_RELIEF: {
	int newRelief;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newRelief = TK_RELIEF_NULL;
	} else if (Tcl_GetIndexFromObj(interp, valuePtr, tkReliefStrings,
		"relief", (nullOK ? TCL_NULL_OK : 0), &newRelief) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = (char)newRelief;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = (short)newRelief;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_RELIEF");
		}
	    } else {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newRelief;
	    }
	}
	if (slotPtrPtr != NULL && valuePtr != NULL) {
	    valuePtr = Tcl_DuplicateObj(valuePtr);
	    Tcl_InvalidateStringRep(valuePtr);
	}
	break;
    }
    case TK_OPTION_CURSOR: {
	Tk_Cursor newCursor;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
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
	    *((Tk_Cursor *) oldInternalPtr) = *((Tk_Cursor *) internalPtr);
	    *((Tk_Cursor *) internalPtr) = newCursor;
	}
	Tk_DefineCursor(tkwin, newCursor);
	break;
    }
    case TK_OPTION_JUSTIFY: {
	Tk_Justify newJustify;








	if (Tk_GetJustifyFromObj(interp, valuePtr, &newJustify) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {


	    *((Tk_Justify *) oldInternalPtr) = *((Tk_Justify *) internalPtr);









	    *((Tk_Justify *) internalPtr) = newJustify;





	}
	break;
    }
    case TK_OPTION_ANCHOR: {
	Tk_Anchor newAnchor;




	if (Tk_GetAnchorFromObj(interp, valuePtr, &newAnchor) != TCL_OK) {

	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {


	    *((Tk_Anchor *) oldInternalPtr) = *((Tk_Anchor *) internalPtr);









	    *((Tk_Anchor *) internalPtr) = newAnchor;





	}
	break;
    }
    case TK_OPTION_PIXELS: {
	int newPixels;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newPixels = 0;
	} else {
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
		    &newPixels) != TCL_OK) {

		return TCL_ERROR;


	    }

	}
	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newPixels;
	}
	break;
    }
    case TK_OPTION_WINDOW: {
	Tk_Window newWin;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newWin = NULL;
	} else {
	    if (TkGetWindowFromObj(interp, tkwin, valuePtr,
		    &newWin) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	if (internalPtr != NULL) {
	    *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr);
	    *((Tk_Window *) internalPtr) = newWin;
	}
	break;
    }







|
>
>
>
|
>
>
>
>
|
>



>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>




|

>
>
>
|
>



>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>








|
<
|
|
>
|
>
>

>













<
|
|
|
<







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
	    *((Tk_Cursor *) oldInternalPtr) = *((Tk_Cursor *) internalPtr);
	    *((Tk_Cursor *) internalPtr) = newCursor;
	}
	Tk_DefineCursor(tkwin, newCursor);
	break;
    }
    case TK_OPTION_JUSTIFY: {
	int newJustify;
	const char *const *justifyTable = tkJustifyStrings;
	if (optionPtr->specPtr->flags & TK_OPTION_JUSTIFY_FULL) {
	    justifyTable = justifyFullStrings;
	}

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newJustify = -1;
	} else if (Tcl_GetIndexFromObj(interp, valuePtr, justifyTable,
		"justification", (nullOK ? TCL_NULL_OK : 0), &newJustify) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = (char)newJustify;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = (short)newJustify;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_JUSTIFY");
		}
	    } else {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newJustify;
	    }
	}
	if (slotPtrPtr != NULL && valuePtr != NULL) {
	    valuePtr = Tcl_DuplicateObj(valuePtr);
	    Tcl_InvalidateStringRep(valuePtr);
	}
	break;
    }
    case TK_OPTION_ANCHOR: {
	int newAnchor;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newAnchor = -1;
	} else if (Tcl_GetIndexFromObj(interp, valuePtr, tkAnchorStrings,
		"anchor", (nullOK ? TCL_NULL_OK : 0), &newAnchor) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = (char)newAnchor;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = (short)newAnchor;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_JUSTIFY");
		}
	    } else {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newAnchor;
	    }
	}
	if (slotPtrPtr != NULL && valuePtr != NULL) {
	    valuePtr = Tcl_DuplicateObj(valuePtr);
	    Tcl_InvalidateStringRep(valuePtr);
	}
	break;
    }
    case TK_OPTION_PIXELS: {
	int newPixels;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newPixels = INT_MIN;

	} else if (Tk_GetPixelsFromObj(nullOK ? NULL : interp, tkwin, valuePtr,
		&newPixels) != TCL_OK) {
	    if (nullOK && interp) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "expected screen distance or \"\" but got \"%.50s\"", Tcl_GetString(valuePtr)));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	    }
	    return TCL_ERROR;
	}
	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newPixels;
	}
	break;
    }
    case TK_OPTION_WINDOW: {
	Tk_Window newWin;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newWin = NULL;

	} else if (TkGetWindowFromObj(interp, tkwin, valuePtr,
		&newWin) != TCL_OK) {
	    return TCL_ERROR;

	}
	if (internalPtr != NULL) {
	    *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr);
	    *((Tk_Window *) internalPtr) = newWin;
	}
	break;
    }
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
    Option *bestPtr;
    const char *name;

    /*
     * First, check to see if the object already has the answer cached.
     */

    if (objPtr->typePtr == &optionObjType) {
	if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) {
	    return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
	}
    }

    /*
     * The answer isn't cached.







|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
    Option *bestPtr;
    const char *name;

    /*
     * First, check to see if the object already has the answer cached.
     */

    if (objPtr->typePtr == &optionObjType.objType) {
	if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) {
	    return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
	}
    }

    /*
     * The answer isn't cached.
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

    if ((objPtr->typePtr != NULL)
	    && (objPtr->typePtr->freeIntRepProc != NULL)) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
    objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
    objPtr->typePtr = &optionObjType;
    tablePtr->refCount++;
    return bestPtr;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown option \"%s\"", name));







|







1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

    if ((objPtr->typePtr != NULL)
	    && (objPtr->typePtr->freeIntRepProc != NULL)) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
    objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
    objPtr->typePtr = &optionObjType.objType;
    tablePtr->refCount++;
    return bestPtr;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown option \"%s\"", name));
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239

int
Tk_SetOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is returned.*/
    void *recordPtr,	    	/* The record to configure. */
    Tk_OptionTable optionTable,	/* Describes valid options. */
    int objc,			/* The number of elements in objv. */
    Tcl_Obj *const objv[],	/* Contains one or more name-value pairs. */
    Tk_Window tkwin,		/* Window associated with the thing being
				 * configured; needed for some options (such
				 * as colors). */
    Tk_SavedOptions *savePtr,	/* If non-NULL, the old values of modified
				 * options are saved here so that they can be
				 * restored after an error. */







|







1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

int
Tk_SetOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is returned.*/
    void *recordPtr,	    	/* The record to configure. */
    Tk_OptionTable optionTable,	/* Describes valid options. */
    Tcl_Size objc,			/* The number of elements in objv. */
    Tcl_Obj *const objv[],	/* Contains one or more name-value pairs. */
    Tk_Window tkwin,		/* Window associated with the thing being
				 * configured; needed for some options (such
				 * as colors). */
    Tk_SavedOptions *savePtr,	/* If non-NULL, the old values of modified
				 * options are saved here so that they can be
				 * restored after an error. */
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
 */

void
Tk_RestoreSavedOptions(
    Tk_SavedOptions *savePtr)	/* Holds saved option information; must have
				 * been passed to Tk_SetOptions. */
{
    size_t i;
    Option *optionPtr;
    Tcl_Obj *newPtr;		/* New object value of option, which we
				 * replace with old value and free. Taken from
				 * record. */
    void *internalPtr;		/* Points to internal value of option in
				 * record. */
    const Tk_OptionSpec *specPtr;

    /*
     * Be sure to restore the options in the opposite order they were set.
     * This is important because it's possible that the same option name was
     * used twice in a single call to Tk_SetOptions.
     */

    if (savePtr->nextPtr != NULL) {
	Tk_RestoreSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i != (size_t)-1; i--) {
	optionPtr = savePtr->items[i].optionPtr;
	specPtr = optionPtr->specPtr;

	/*
	 * First free the new value of the option, which is currently in the
	 * record.
	 */

	if (specPtr->objOffset != TCL_INDEX_NONE) {
	    newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset;
	} else {
	    internalPtr = NULL;
	}
	if (optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin);
	}







|



















|








|




|







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
 */

void
Tk_RestoreSavedOptions(
    Tk_SavedOptions *savePtr)	/* Holds saved option information; must have
				 * been passed to Tk_SetOptions. */
{
    Tcl_Size i;
    Option *optionPtr;
    Tcl_Obj *newPtr;		/* New object value of option, which we
				 * replace with old value and free. Taken from
				 * record. */
    void *internalPtr;		/* Points to internal value of option in
				 * record. */
    const Tk_OptionSpec *specPtr;

    /*
     * Be sure to restore the options in the opposite order they were set.
     * This is important because it's possible that the same option name was
     * used twice in a single call to Tk_SetOptions.
     */

    if (savePtr->nextPtr != NULL) {
	Tk_RestoreSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i >= 0; i--) {
	optionPtr = savePtr->items[i].optionPtr;
	specPtr = optionPtr->specPtr;

	/*
	 * First free the new value of the option, which is currently in the
	 * record.
	 */

	if (specPtr->objOffset >= 0) {
	    newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset >= 0) {
	    internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset;
	} else {
	    internalPtr = NULL;
	}
	if (optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin);
	}
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
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    char *ptr = (char *) &savePtr->items[i].internalForm;

	    CLANG_ASSERT(internalPtr);
	    switch (specPtr->type) {
	    case TK_OPTION_BOOLEAN:












	    case TK_OPTION_INT:















		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_DOUBLE:
		*((double *) internalPtr) = *((double *) ptr);
		break;
	    case TK_OPTION_STRING:
		*((char **) internalPtr) = *((char **) ptr);
		break;
	    case TK_OPTION_STRING_TABLE:









		*((int *) internalPtr) = *((int *) ptr);

		break;
	    case TK_OPTION_COLOR:
		*((XColor **) internalPtr) = *((XColor **) ptr);
		break;
	    case TK_OPTION_FONT:
		*((Tk_Font *) internalPtr) = *((Tk_Font *) ptr);
		break;
	    case TK_OPTION_STYLE:
		*((Tk_Style *) internalPtr) = *((Tk_Style *) ptr);
		break;
	    case TK_OPTION_BITMAP:
		*((Pixmap *) internalPtr) = *((Pixmap *) ptr);
		break;
	    case TK_OPTION_BORDER:
		*((Tk_3DBorder *) internalPtr) = *((Tk_3DBorder *) ptr);
		break;
	    case TK_OPTION_RELIEF:









		*((int *) internalPtr) = *((int *) ptr);

		break;
	    case TK_OPTION_CURSOR:
		*((Tk_Cursor *) internalPtr) = *((Tk_Cursor *) ptr);
		Tk_DefineCursor(savePtr->tkwin, *((Tk_Cursor *) internalPtr));
		break;
	    case TK_OPTION_JUSTIFY:









		*((Tk_Justify *) internalPtr) = *((Tk_Justify *) ptr);

		break;
	    case TK_OPTION_ANCHOR:


		*((Tk_Anchor *) internalPtr) = *((Tk_Anchor *) ptr);








		break;
	    case TK_OPTION_PIXELS:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_WINDOW:
		*((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
		break;







>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>
>
>
>
>
>
>
>
>
|
>

















>
>
>
>
>
>
>
>
>
|
>






>
>
>
>
>
>
>
>
>
|
>


>
>
|
>
>
>
>
>
>
>
>







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
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    char *ptr = (char *) &savePtr->items[i].internalForm;

	    CLANG_ASSERT(internalPtr);
	    switch (specPtr->type) {
	    case TK_OPTION_BOOLEAN:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_BOOLEAN");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_INT:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_MASK) {
			if (sizeof(long) > sizeof(int)) {
			    *((long *) internalPtr) = *((long *) ptr);
			} else {
			    *((long long *) internalPtr) = *((long long *) ptr);
			}
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_INT");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_INDEX:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_DOUBLE:
		*((double *) internalPtr) = *((double *) ptr);
		break;
	    case TK_OPTION_STRING:
		*((char **) internalPtr) = *((char **) ptr);
		break;
	    case TK_OPTION_STRING_TABLE:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_COLOR:
		*((XColor **) internalPtr) = *((XColor **) ptr);
		break;
	    case TK_OPTION_FONT:
		*((Tk_Font *) internalPtr) = *((Tk_Font *) ptr);
		break;
	    case TK_OPTION_STYLE:
		*((Tk_Style *) internalPtr) = *((Tk_Style *) ptr);
		break;
	    case TK_OPTION_BITMAP:
		*((Pixmap *) internalPtr) = *((Pixmap *) ptr);
		break;
	    case TK_OPTION_BORDER:
		*((Tk_3DBorder *) internalPtr) = *((Tk_3DBorder *) ptr);
		break;
	    case TK_OPTION_RELIEF:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_RELIEF");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_CURSOR:
		*((Tk_Cursor *) internalPtr) = *((Tk_Cursor *) ptr);
		Tk_DefineCursor(savePtr->tkwin, *((Tk_Cursor *) internalPtr));
		break;
	    case TK_OPTION_JUSTIFY:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_JUSTIFY");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_ANCHOR:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_ANCHOR");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_PIXELS:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_WINDOW:
		*((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
		break;
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
				 * particular option. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *listPtr, *elementPtr;

    listPtr = Tcl_NewListObj(0, NULL);
    Tcl_ListObjAppendElement(NULL, listPtr,
	    Tcl_NewStringObj(optionPtr->specPtr->optionName, -1));

    if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	elementPtr = Tcl_NewStringObj(
		optionPtr->extra.synonymPtr->specPtr->optionName, -1);
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
    } else {
	if (optionPtr->dbNameUID == NULL) {
	    elementPtr = Tcl_NewObj();
	} else {
	    elementPtr = Tcl_NewStringObj(optionPtr->dbNameUID, -1);
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if (optionPtr->dbClassUID == NULL) {
	    elementPtr = Tcl_NewObj();
	} else {
	    elementPtr = Tcl_NewStringObj(optionPtr->dbClassUID, -1);
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if ((tkwin != NULL) && ((optionPtr->specPtr->type == TK_OPTION_COLOR)
		|| (optionPtr->specPtr->type == TK_OPTION_BORDER))
		&& (Tk_Depth(tkwin) <= 1)
		&& (optionPtr->extra.monoColorPtr != NULL)) {







|



|





|






|







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
				 * particular option. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *listPtr, *elementPtr;

    listPtr = Tcl_NewListObj(0, NULL);
    Tcl_ListObjAppendElement(NULL, listPtr,
	    Tcl_NewStringObj(optionPtr->specPtr->optionName, TCL_INDEX_NONE));

    if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	elementPtr = Tcl_NewStringObj(
		optionPtr->extra.synonymPtr->specPtr->optionName, TCL_INDEX_NONE);
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
    } else {
	if (optionPtr->dbNameUID == NULL) {
	    elementPtr = Tcl_NewObj();
	} else {
	    elementPtr = Tcl_NewStringObj(optionPtr->dbNameUID, TCL_INDEX_NONE);
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if (optionPtr->dbClassUID == NULL) {
	    elementPtr = Tcl_NewObj();
	} else {
	    elementPtr = Tcl_NewStringObj(optionPtr->dbClassUID, TCL_INDEX_NONE);
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if ((tkwin != NULL) && ((optionPtr->specPtr->type == TK_OPTION_COLOR)
		|| (optionPtr->specPtr->type == TK_OPTION_BORDER))
		&& (Tk_Depth(tkwin) <= 1)
		&& (optionPtr->extra.monoColorPtr != NULL)) {
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
    void *recordPtr,		/* Pointer to record holding current values of
				 * configuration options. */
    Option *optionPtr,		/* Pointer to information describing an option
				 * whose internal value is stored in
				 * *recordPtr. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *objPtr;
    void *internalPtr;		/* Points to internal value of option in
				 * record. */

    objPtr = NULL;
    if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN:

















	case TK_OPTION_INT:


































	    objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));


	    break;
	case TK_OPTION_DOUBLE:

	    objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));

	    break;
	case TK_OPTION_STRING:
	    objPtr = Tcl_NewStringObj(*((char **)internalPtr), -1);
	    break;
	case TK_OPTION_STRING_TABLE:













	    objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
		    *((int *) internalPtr)], -1);

	    break;

	case TK_OPTION_COLOR: {
	    XColor *colorPtr = *((XColor **)internalPtr);

	    if (colorPtr != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
	    }
	    break;
	}
	case TK_OPTION_FONT: {
	    Tk_Font tkfont = *((Tk_Font *)internalPtr);

	    if (tkfont != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1);
	    }
	    break;
	}
	case TK_OPTION_STYLE: {
	    Tk_Style style = *((Tk_Style *)internalPtr);

	    if (style != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1);
	    }
	    break;
	}
	case TK_OPTION_BITMAP: {
	    Pixmap pixmap = *((Pixmap *)internalPtr);

	    if (pixmap != None) {
		objPtr = Tcl_NewStringObj(
		    Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), -1);
	    }
	    break;
	}
	case TK_OPTION_BORDER: {
	    Tk_3DBorder border = *((Tk_3DBorder *)internalPtr);

	    if (border != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1);
	    }
	    break;
	}
	case TK_OPTION_RELIEF:













	    objPtr = Tcl_NewStringObj(Tk_NameOfRelief(*((int *)internalPtr)), -1);

	    break;

	case TK_OPTION_CURSOR: {
	    Tk_Cursor cursor = *((Tk_Cursor *)internalPtr);

	    if (cursor != NULL) {
		objPtr = Tcl_NewStringObj(
		Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
	    }
	    break;
	}
	case TK_OPTION_JUSTIFY:













	    objPtr = Tcl_NewStringObj(Tk_NameOfJustify(
		    *((Tk_Justify *)internalPtr)), -1);

	    break;

	case TK_OPTION_ANCHOR:













	    objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(
		    *((Tk_Anchor *)internalPtr)), -1);

	    break;

	case TK_OPTION_PIXELS:

	    objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));

	    break;
	case TK_OPTION_WINDOW: {
	    tkwin = *((Tk_Window *) internalPtr);

	    if (tkwin != NULL) {
		objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
	    }
	    break;
	}
	case TK_OPTION_CUSTOM: {
	    const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	    objPtr = custom->getProc(custom->clientData, tkwin, (char *)recordPtr,
		    optionPtr->specPtr->internalOffset);
	    break;
        }
        default:
	    Tcl_Panic("bad option type in GetObjectForOption");
	}
    }
    if (objPtr == NULL) {
	objPtr = Tcl_NewObj();
    }
    return objPtr;







|
|
<

<



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>


>
|
>


|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>

>




|







|







|








|







|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>

>





|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>

>

>
|
>





|









|
|







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
    void *recordPtr,		/* Pointer to record holding current values of
				 * configuration options. */
    Option *optionPtr,		/* Pointer to information describing an option
				 * whose internal value is stored in
				 * *recordPtr. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *objPtr = NULL;
    void *internalPtr;		/* Points to internal value of option in record. */



    if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN: {
	    int value;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    value = *((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    value = *((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_BOOLEAN");
		}
	    } else {
		value = *((int *)internalPtr);
	    }
	    if (value != -1) {
		objPtr = Tcl_NewBooleanObj(value);
	    }
	    break;
	}
	case TK_OPTION_INT: {
	    Tcl_WideInt value;
	    int nullOK = (optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|TCL_NULL_OK));
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_MASK) {
		    if (sizeof(long) > sizeof(int)) {
			value = *((long *)internalPtr);
			if (nullOK && (value == LONG_MIN)) {break;}
		    } else {
			value = *((long long *)internalPtr);
			if (nullOK && (value == LLONG_MIN)) {break;}
		    }
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_INT");
		}
	    } else {
		value = *((int *)internalPtr);
		if (nullOK && (value == INT_MIN)) {break;}
	    }
		objPtr = Tcl_NewWideIntObj(value);
	    break;
	}
	case TK_OPTION_INDEX:
	    if (!(optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|TCL_NULL_OK)) || *((int *) internalPtr) != INT_MIN) {
		if (*((int *) internalPtr) == INT_MIN) {
		    objPtr = TkNewIndexObj(TCL_INDEX_NONE);
		} else if (*((int *) internalPtr) == INT_MAX) {
		    objPtr = Tcl_NewStringObj("end+1", TCL_INDEX_NONE);
		} else if (*((int *) internalPtr) == -1) {
		    objPtr = Tcl_NewStringObj("end", TCL_INDEX_NONE);
		} else if (*((int *) internalPtr) < 0) {
		    char buf[32];
		    snprintf(buf, 32, "end%d", 1 + *((int *) internalPtr));
		    objPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
		} else {
		    objPtr = Tcl_NewWideIntObj(*((int *) internalPtr));
		}
	    }
	    break;
	case TK_OPTION_DOUBLE:
	    if (!(optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|TCL_NULL_OK)) || !isnan(*((double *) internalPtr))) {
		objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
	    }
	    break;
	case TK_OPTION_STRING:
	    objPtr = Tcl_NewStringObj(*((char **)internalPtr), TCL_INDEX_NONE);
	    break;
	case TK_OPTION_STRING_TABLE: {
	    int value;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    value = *((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    value = *((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		}
	    } else {
		value = *((int *)internalPtr);
	    }
	    if (value >= 0) {
		objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
			value], TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_COLOR: {
	    XColor *colorPtr = *((XColor **)internalPtr);

	    if (colorPtr != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_FONT: {
	    Tk_Font tkfont = *((Tk_Font *)internalPtr);

	    if (tkfont != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_STYLE: {
	    Tk_Style style = *((Tk_Style *)internalPtr);

	    if (style != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_BITMAP: {
	    Pixmap pixmap = *((Pixmap *)internalPtr);

	    if (pixmap != None) {
		objPtr = Tcl_NewStringObj(
		    Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_BORDER: {
	    Tk_3DBorder border = *((Tk_3DBorder *)internalPtr);

	    if (border != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_RELIEF: {
	    int value;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    value = *((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    value = *((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_RELIEF");
		}
	    } else {
		value = *((int *)internalPtr);
	    }
	    if (value != TK_RELIEF_NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfRelief(value), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_CURSOR: {
	    Tk_Cursor cursor = *((Tk_Cursor *)internalPtr);

	    if (cursor != NULL) {
		objPtr = Tcl_NewStringObj(
		Tk_NameOfCursor(Tk_Display(tkwin), cursor), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_JUSTIFY: {
	    Tk_Justify value;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    value = (Tk_Justify)*((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    value = (Tk_Justify)*((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_JUSTIFY");
		}
	    } else {
		value = (Tk_Justify)*((int *)internalPtr);
	    }
	    if (value != TK_JUSTIFY_NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfJustify(value), TCL_INDEX_NONE);

	    }
	    break;
	}
	case TK_OPTION_ANCHOR: {
	    Tk_Anchor value;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(char)) {
		    value = (Tk_Anchor)*((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TK_OPTION_VAR(short)) {
		    value = (Tk_Anchor)*((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_ANCHOR");
		}
	    } else {
		value = (Tk_Anchor)*((int *)internalPtr);
	    }
	    if (value != TK_ANCHOR_NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(value), TCL_INDEX_NONE);

	    }
	    break;
	}
	case TK_OPTION_PIXELS:
	    if (!(optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|TCL_NULL_OK)) || *((int *) internalPtr) != INT_MIN) {
		objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));
	    }
	    break;
	case TK_OPTION_WINDOW: {
	    tkwin = *((Tk_Window *) internalPtr);

	    if (tkwin != NULL) {
		objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), TCL_INDEX_NONE);
	    }
	    break;
	}
	case TK_OPTION_CUSTOM: {
	    const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	    objPtr = custom->getProc(custom->clientData, tkwin, (char *)recordPtr,
		    optionPtr->specPtr->internalOffset);
	    break;
	}
	default:
	    Tcl_Panic("bad option type in GetObjectForOption");
	}
    }
    if (objPtr == NULL) {
	objPtr = Tcl_NewObj();
    }
    return objPtr;
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105

    for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
	    hashEntryPtr != NULL;
	    hashEntryPtr = Tcl_NextHashEntry(&search)) {
	if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
	    for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj(tablePtr->refCount));
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj(tablePtr->numOptions));
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
			tablePtr->options[0].specPtr->optionName, -1));
	    }
	    break;
	}
    }
    return objPtr;
}








|

|

|







2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463

    for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
	    hashEntryPtr != NULL;
	    hashEntryPtr = Tcl_NextHashEntry(&search)) {
	if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
	    for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj((Tcl_WideInt)tablePtr->refCount));
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj((Tcl_WideInt)tablePtr->numOptions));
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
			tablePtr->options[0].specPtr->optionName, TCL_INDEX_NONE));
	    }
	    break;
	}
    }
    return objPtr;
}


Changes to generic/tkConsole.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"








|







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 © 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"

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    int type;			/* TCL_STDOUT or TCL_STDERR */
} ChannelData;

/*
 * Prototypes for local procedures defined in this file:
 */

static int	ConsoleClose(ClientData instanceData, Tcl_Interp *interp);
static int	Console2Close(ClientData instanceData, Tcl_Interp *interp, int flags);
static void	ConsoleDeleteProc(ClientData clientData);
static void	ConsoleEventProc(ClientData clientData, XEvent *eventPtr);
static int	ConsoleHandle(ClientData instanceData, int direction,
		    ClientData *handlePtr);
static int	ConsoleInput(ClientData instanceData, char *buf, int toRead,
		    int *errorCode);
static int	ConsoleObjCmd(ClientData clientData, Tcl_Interp *interp,
		    int objc, Tcl_Obj *const objv[]);
static int	ConsoleOutput(ClientData instanceData, const char *buf,
		    int toWrite, int *errorCode);
static void	ConsoleWatch(ClientData instanceData, int mask);
static void	DeleteConsoleInterp(ClientData clientData);
static void	InterpDeleteProc(ClientData clientData, Tcl_Interp *interp);
static int	InterpreterObjCmd(ClientData clientData, Tcl_Interp *interp,
		    int objc, Tcl_Obj *const objv[]);

/*
 * This structure describes the channel type structure for file based IO:
 */

static const Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */







|
|
|
|
|
|
|

<
|
|

|
|
|
|
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60

61
62
63
64
65
66
67
    int type;			/* TCL_STDOUT or TCL_STDERR */
} ChannelData;

/*
 * Prototypes for local procedures defined in this file:
 */

static int	ConsoleClose(void *instanceData, Tcl_Interp *interp);
static int	Console2Close(void *instanceData, Tcl_Interp *interp, int flags);
static void	ConsoleDeleteProc(void *clientData);
static void	ConsoleEventProc(void *clientData, XEvent *eventPtr);
static int	ConsoleHandle(void *instanceData, int direction,
		    void **handlePtr);
static int	ConsoleInput(void *instanceData, char *buf, int toRead,
		    int *errorCode);

static Tcl_ObjCmdProc ConsoleObjCmd;
static int	ConsoleOutput(void *instanceData, const char *buf,
		    int toWrite, int *errorCode);
static void	ConsoleWatch(void *instanceData, int mask);
static void	DeleteConsoleInterp(void *clientData);
static void	InterpDeleteProc(void *clientData, Tcl_Interp *interp);
static Tcl_ObjCmdProc InterpreterObjCmd;


/*
 * This structure describes the channel type structure for file based IO:
 */

static const Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
    ConsoleInfo *info;
    Tcl_Channel consoleChannel;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
        return;
    }

    consoleInitPtr = (int *)Tcl_GetThreadData(&consoleInitKey, (int) sizeof(int));
    if (*consoleInitPtr) {
	/*
	 * We've already initialized console channels in this thread.







|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
    ConsoleInfo *info;
    Tcl_Channel consoleChannel;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
        return;
    }

    consoleInitPtr = (int *)Tcl_GetThreadData(&consoleInitKey, (int) sizeof(int));
    if (*consoleInitPtr) {
	/*
	 * We've already initialized console channels in this thread.
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, info);
	info->refCount++;
    }

    Tcl_Preserve(consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
	    -1, TCL_EVAL_GLOBAL);
    if (result == TCL_ERROR) {
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
    }
    Tcl_Release(consoleInterp);
    if (result == TCL_ERROR) {







|







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, info);
	info->refCount++;
    }

    Tcl_Preserve(consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
	    TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    if (result == TCL_ERROR) {
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
    }
    Tcl_Release(consoleInterp);
    if (result == TCL_ERROR) {
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
 *	Writes output on the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleOutput(
    ClientData instanceData,	/* Indicates which device to use. */
    const char *buf,		/* The data buffer. */
    int toWrite,		/* How many bytes to write? */
    int *errorCode)		/* Where to store error code. */
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;








|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
 *	Writes output on the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleOutput(
    void *instanceData,	/* Indicates which device to use. */
    const char *buf,		/* The data buffer. */
    int toWrite,		/* How many bytes to write? */
    int *errorCode)		/* Where to store error code. */
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;

513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

	    /*
	     * Not checking for utf8 == NULL.  Did not check for TCL_ERROR
	     * from Tcl_SetChannelOption() in Tk_InitConsoleChannels() either.
	     * Assumption is utf-8 Tcl_Encoding is reliably present.
	     */

	    const char *bytes
		    = Tcl_ExternalToUtfDString(utf8, buf, toWrite, &ds);
	    int numBytes = Tcl_DStringLength(&ds);
	    Tcl_Obj *cmd = Tcl_NewStringObj("tk::ConsoleOutput", -1);

	    Tcl_FreeEncoding(utf8);

	    if (data->type == TCL_STDERR) {
		Tcl_ListObjAppendElement(NULL, cmd,
			Tcl_NewStringObj("stderr", -1));
	    } else {
		Tcl_ListObjAppendElement(NULL, cmd,
			Tcl_NewStringObj("stdout", -1));
	    }
	    Tcl_ListObjAppendElement(NULL, cmd,
		    Tcl_NewStringObj(bytes, numBytes));

	    Tcl_DStringFree(&ds);
	    Tcl_IncrRefCount(cmd);
	    Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);







<
|
|
|





|


|







511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

	    /*
	     * Not checking for utf8 == NULL.  Did not check for TCL_ERROR
	     * from Tcl_SetChannelOption() in Tk_InitConsoleChannels() either.
	     * Assumption is utf-8 Tcl_Encoding is reliably present.
	     */


	    const char *bytes = Tcl_ExternalToUtfDString(utf8, buf, toWrite, &ds);
	    Tcl_Size numBytes = Tcl_DStringLength(&ds);
	    Tcl_Obj *cmd = Tcl_NewStringObj("tk::ConsoleOutput", TCL_INDEX_NONE);

	    Tcl_FreeEncoding(utf8);

	    if (data->type == TCL_STDERR) {
		Tcl_ListObjAppendElement(NULL, cmd,
			Tcl_NewStringObj("stderr", TCL_INDEX_NONE));
	    } else {
		Tcl_ListObjAppendElement(NULL, cmd,
			Tcl_NewStringObj("stdout", TCL_INDEX_NONE));
	    }
	    Tcl_ListObjAppendElement(NULL, cmd,
		    Tcl_NewStringObj(bytes, numBytes));

	    Tcl_DStringFree(&ds);
	    Tcl_IncrRefCount(cmd);
	    Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
 *	Frees the dummy file associated with the channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleClose(
    ClientData instanceData,
    TCL_UNUSED(Tcl_Interp *))
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;

    if (info) {
	if (info->refCount-- <= 1) {
	    /*
	     * Assuming the Tcl_Interp * fields must already be NULL.
	     */

	    ckfree(info);
	}
    }
    ckfree(data);
    return 0;
}

static int
Console2Close(
    ClientData instanceData,	/* Unused. */
    Tcl_Interp *interp,		/* Unused. */
    int flags)
{
    if ((flags&(TCL_CLOSE_READ|TCL_CLOSE_WRITE))==0) {
	return ConsoleClose(instanceData, interp);
    }
    return EINVAL;







|




















|







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
 *	Frees the dummy file associated with the channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleClose(
    void *instanceData,
    TCL_UNUSED(Tcl_Interp *))
{
    ChannelData *data = (ChannelData *)instanceData;
    ConsoleInfo *info = data->info;

    if (info) {
	if (info->refCount-- <= 1) {
	    /*
	     * Assuming the Tcl_Interp * fields must already be NULL.
	     */

	    ckfree(info);
	}
    }
    ckfree(data);
    return 0;
}

static int
Console2Close(
    void *instanceData,	/* Unused. */
    Tcl_Interp *interp,		/* Unused. */
    int flags)
{
    if ((flags&(TCL_CLOSE_READ|TCL_CLOSE_WRITE))==0) {
	return ConsoleClose(instanceData, interp);
    }
    return EINVAL;
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleObjCmd(
    ClientData clientData,	/* Access to the console interp */
    Tcl_Interp *interp,		/* Current interpreter */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* Argument objects */
{
    int index, result;
    static const char *const options[] = {
	"eval", "hide", "show", "title", NULL};







|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleObjCmd(
    void *clientData,	/* Access to the console interp */
    Tcl_Interp *interp,		/* Current interpreter */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* Argument objects */
{
    int index, result;
    static const char *const options[] = {
	"eval", "hide", "show", "title", NULL};
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
	cmd = objv[2];
	break;
    case CON_HIDE:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm withdraw .", -1);
	break;
    case CON_SHOW:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm deiconify .", -1);
	break;
    case CON_TITLE:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?title?");
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm title .", -1);
	if (objc == 3) {
	    Tcl_ListObjAppendElement(NULL, cmd, objv[2]);
	}
	break;
    default:
	CLANG_ASSERT(0);
    }

    Tcl_IncrRefCount(cmd);
    if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	Tcl_Preserve(consoleInterp);
	result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
	Tcl_Release(consoleInterp);
    } else {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no active console interp", -1));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NONE", NULL);
	result = TCL_ERROR;
    }
    Tcl_DecrRefCount(cmd);
    return result;
}








|






|






|


















|







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
	cmd = objv[2];
	break;
    case CON_HIDE:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm withdraw .", TCL_INDEX_NONE);
	break;
    case CON_SHOW:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm deiconify .", TCL_INDEX_NONE);
	break;
    case CON_TITLE:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?title?");
	    return TCL_ERROR;
	}
	cmd = Tcl_NewStringObj("wm title .", TCL_INDEX_NONE);
	if (objc == 3) {
	    Tcl_ListObjAppendElement(NULL, cmd, objv[2]);
	}
	break;
    default:
	CLANG_ASSERT(0);
    }

    Tcl_IncrRefCount(cmd);
    if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	Tcl_Preserve(consoleInterp);
	result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
	Tcl_Release(consoleInterp);
    } else {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no active console interp", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NONE", NULL);
	result = TCL_ERROR;
    }
    Tcl_DecrRefCount(cmd);
    return result;
}

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
 *	A standard Tcl result.
 *
 *----------------------------------------------------------------------
 */

static int
InterpreterObjCmd(
    ClientData clientData,	/* */
    Tcl_Interp *interp,		/* Current interpreter */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* Argument objects */
{
    int index, result = TCL_OK;
    static const char *const options[] = {"eval", "record", NULL};
    enum option {OTHER_EVAL, OTHER_RECORD};







|







778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
 *	A standard Tcl result.
 *
 *----------------------------------------------------------------------
 */

static int
InterpreterObjCmd(
    void *clientData,	/* */
    Tcl_Interp *interp,		/* Current interpreter */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* Argument objects */
{
    int index, result = TCL_OK;
    static const char *const options[] = {"eval", "record", NULL};
    enum option {OTHER_EVAL, OTHER_RECORD};
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 parent interp", -1));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NO_INTERP", NULL);
	return TCL_ERROR;
    }

    Tcl_Preserve(otherInterp);
    switch ((enum option) index) {
    case OTHER_EVAL:







|







805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "script");
	return TCL_ERROR;
    }

    if ((otherInterp == NULL) || Tcl_InterpDeleted(otherInterp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no active parent interp", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NO_INTERP", NULL);
	return TCL_ERROR;
    }

    Tcl_Preserve(otherInterp);
    switch ((enum option) index) {
    case OTHER_EVAL:
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
 *	lives in gets torn down.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteConsoleInterp(
    ClientData clientData)
{
    Tcl_Interp *interp = (Tcl_Interp *)clientData;

    Tcl_DeleteInterp(interp);
}

/*







|







852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
 *	lives in gets torn down.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteConsoleInterp(
    void *clientData)
{
    Tcl_Interp *interp = (Tcl_Interp *)clientData;

    Tcl_DeleteInterp(interp);
}

/*
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
 *	A new console it created.
 *
 *----------------------------------------------------------------------
 */

static void
InterpDeleteProc(
    ClientData clientData,
    Tcl_Interp *interp)
{
    ConsoleInfo *info = (ConsoleInfo *)clientData;

    if (info->consoleInterp == interp) {
	Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp);
	info->consoleInterp = NULL;







|







878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
 *	A new console it created.
 *
 *----------------------------------------------------------------------
 */

static void
InterpDeleteProc(
    void *clientData,
    Tcl_Interp *interp)
{
    ConsoleInfo *info = (ConsoleInfo *)clientData;

    if (info->consoleInterp == interp) {
	Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp);
	info->consoleInterp = NULL;
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
 *	A new console it created.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleDeleteProc(
    ClientData clientData)
{
    ConsoleInfo *info = (ConsoleInfo *)clientData;

    if (info->consoleInterp) {
	Tcl_DeleteInterp(info->consoleInterp);
    }
    if (info->refCount-- <= 1) {







|







911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
 *	A new console it created.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleDeleteProc(
    void *clientData)
{
    ConsoleInfo *info = (ConsoleInfo *)clientData;

    if (info->consoleInterp) {
	Tcl_DeleteInterp(info->consoleInterp);
    }
    if (info->refCount-- <= 1) {
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
 *	Invokes the "::tk::ConsoleExit" command in the console interp.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleEventProc(
    ClientData clientData,
    XEvent *eventPtr)
{
    if (eventPtr->type == DestroyNotify) {
	ConsoleInfo *info = (ConsoleInfo *)clientData;
	Tcl_Interp *consoleInterp = info->consoleInterp;

	if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	    Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL);
	}

	if (info->refCount-- <= 1) {
	    ckfree(info);
	}
    }
}







|







|







944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
 *	Invokes the "::tk::ConsoleExit" command in the console interp.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleEventProc(
    void *clientData,
    XEvent *eventPtr)
{
    if (eventPtr->type == DestroyNotify) {
	ConsoleInfo *info = (ConsoleInfo *)clientData;
	Tcl_Interp *consoleInterp = info->consoleInterp;

	if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
	    Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	}

	if (info->refCount-- <= 1) {
	    ckfree(info);
	}
    }
}

Changes to generic/tkCursor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15




16
17
18
19
20
21
22
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"





/*
 * A TkCursor structure exists for each cursor that is currently active. Each
 * structure is indexed with two hash tables defined below. One of the tables
 * is cursorIdTable, and the other is either cursorNameTable or
 * cursorDataTable, each of which are stored in the TkDisplay structure for
 * the current thread.







|
|






>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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 © 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * A TkCursor structure exists for each cursor that is currently active. Each
 * structure is indexed with two hash tables defined below. One of the tables
 * is cursorIdTable, and the other is either cursorNameTable or
 * cursorDataTable, each of which are stored in the TkDisplay structure for
 * the current thread.
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
 * The following structure defines the implementation of the "cursor" Tcl
 * object, used for drawing. The color object remembers the hash table
 * entry associated with a color. The actual allocation and deallocation
 * of the color should be done by the configuration package when the cursor
 * option is set.
 */

Tcl_ObjType const tkCursorObjType = {
    "cursor",			/* name */
    FreeCursorObjProc,		/* freeIntRepProc */
    DupCursorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocCursorFromObj --
 *







|
|



|
>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 * The following structure defines the implementation of the "cursor" Tcl
 * object, used for drawing. The color object remembers the hash table
 * entry associated with a color. The actual allocation and deallocation
 * of the color should be done by the configuration package when the cursor
 * option is set.
 */

const TkObjType tkCursorObjType = {
    {"cursor",			/* name */
    FreeCursorObjProc,		/* freeIntRepProc */
    DupCursorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocCursorFromObj --
 *
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    Tk_Window tkwin,		/* Window in which the cursor will be used.*/
    Tcl_Obj *objPtr)		/* Object describing cursor; see manual entry
				 * for description of legal syntax of this
				 * obj's string rep. */
{
    TkCursor *cursorPtr;

    if (objPtr->typePtr != &tkCursorObjType) {
	InitCursorObj(objPtr);
    }
    cursorPtr = (TkCursor *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkCursor, see if it's the one we
     * want. If so, increment its reference count and return.







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    Tk_Window tkwin,		/* Window in which the cursor will be used.*/
    Tcl_Obj *objPtr)		/* Object describing cursor; see manual entry
				 * for description of legal syntax of this
				 * obj's string rep. */
{
    TkCursor *cursorPtr;

    if (objPtr->typePtr != &tkCursorObjType.objType) {
	InitCursorObj(objPtr);
    }
    cursorPtr = (TkCursor *)objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkCursor, see if it's the one we
     * want. If so, increment its reference count and return.
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	sprintf(dispPtr->cursorString, "cursor id 0x%" TCL_Z_MODIFIER "x", (size_t)cursor);
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *)Tcl_GetHashValue(idHashPtr);







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	snprintf(dispPtr->cursorString, sizeof(dispPtr->cursorString), "cursor id 0x%" TCL_Z_MODIFIER "x", PTR2INT(cursor));
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *)Tcl_GetHashValue(idHashPtr);
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
    Tcl_Obj *objPtr)		/* The object that describes the desired
				 * cursor. */
{
    TkCursor *cursorPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkCursorObjType) {
	InitCursorObj(objPtr);
    }

    /*
     * The internal representation is a cache of the last cursor used with the
     * given name. But there can be lots different cursors for each cursor
     * name; one cursor for each display. Check to see if the cursor we have







|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
    Tcl_Obj *objPtr)		/* The object that describes the desired
				 * cursor. */
{
    TkCursor *cursorPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkCursorObjType.objType) {
	InitCursorObj(objPtr);
    }

    /*
     * The internal representation is a cache of the last cursor used with the
     * given name. But there can be lots different cursors for each cursor
     * name; one cursor for each display. Check to see if the cursor we have
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkCursorObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CursorInit --







|







773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkCursorObjType.objType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CursorInit --
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
	cursorPtr = (TkCursor *)Tcl_GetHashValue(hashPtr);
	if (cursorPtr == NULL) {
	    Tcl_Panic("TkDebugCursor found empty hash table entry");
	}
	for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(cursorPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(cursorPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|













864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
	cursorPtr = (TkCursor *)Tcl_GetHashValue(hashPtr);
	if (cursorPtr == NULL) {
	    Tcl_Panic("TkDebugCursor found empty hash table entry");
	}
	for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj((Tcl_WideInt)cursorPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj((Tcl_WideInt)cursorPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkDList.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * tkDList.h --
 *
 * A list is headed by pointers to first and last element. The elements
 * are doubly linked so that an arbitrary element can be removed without
 * a need to traverse the list. New elements can be added to the list
 * before or after an existing element or at the head/tail of the list.
 * A list may be traversed in the forward or backward direction.
 *
 * Copyright (c) 2018 by Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Note that this file will not be included in header files, it is the purpose









|







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 © 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
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Free(struct ElemType *elem)						\
{										\
    LT##_Remove(elem);								\
    ckfree((void *) elem);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_RemoveHead(LT *head)							\
{										\
    assert(!LT##_IsEmpty(head));						\







|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Free(struct ElemType *elem)						\
{										\
    LT##_Remove(elem);								\
    ckfree((void *)elem);							\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_RemoveHead(LT *head)							\
{										\
    assert(!LT##_IsEmpty(head));						\
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
LT##_Clear(LT *head)								\
{										\
    struct ElemType *p;								\
    struct ElemType *next;							\
    assert(head);								\
    for (p = head->first; p; p = next) {					\
	next = LT##_Next(p);							\
	ckfree((void *) p);							\
    }										\
    LT##_Init(head);								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Traverse(LT *head, LT##_Func func)						\







|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
LT##_Clear(LT *head)								\
{										\
    struct ElemType *p;								\
    struct ElemType *next;							\
    assert(head);								\
    for (p = head->first; p; p = next) {					\
	next = LT##_Next(p);							\
	ckfree((void *)p);							\
    }										\
    LT##_Init(head);								\
}										\
										\
__TK_DLIST_UNUSED								\
static void									\
LT##_Traverse(LT *head, LT##_Func func)						\

Changes to generic/tkDecls.h.

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.
 *
 * 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





|







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 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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
				int relief);
/* 5 */
EXTERN void		Tk_AddOption(Tk_Window tkwin, const char *name,
				const char *value, int priority);
/* 6 */
EXTERN void		Tk_BindEvent(Tk_BindingTable bindingTable,
				XEvent *eventPtr, Tk_Window tkwin,
				int numObjects, ClientData *objectPtr);
/* 7 */
EXTERN void		Tk_CanvasDrawableCoords(Tk_Canvas canvas, double x,
				double y, short *drawableXPtr,
				short *drawableYPtr);
/* 8 */
EXTERN void		Tk_CanvasEventuallyRedraw(Tk_Canvas canvas, int x1,
				int y1, int x2, int y2);







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
				int relief);
/* 5 */
EXTERN void		Tk_AddOption(Tk_Window tkwin, const char *name,
				const char *value, int priority);
/* 6 */
EXTERN void		Tk_BindEvent(Tk_BindingTable bindingTable,
				XEvent *eventPtr, Tk_Window tkwin,
				Tcl_Size numObjects, void **objectPtr);
/* 7 */
EXTERN void		Tk_CanvasDrawableCoords(Tk_Canvas canvas, double x,
				double y, short *drawableXPtr,
				short *drawableYPtr);
/* 8 */
EXTERN void		Tk_CanvasEventuallyRedraw(Tk_Canvas canvas, int x1,
				int y1, int x2, int y2);
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
EXTERN int		Tk_CanvasPsColor(Tcl_Interp *interp,
				Tk_Canvas canvas, XColor *colorPtr);
/* 13 */
EXTERN int		Tk_CanvasPsFont(Tcl_Interp *interp, Tk_Canvas canvas,
				Tk_Font font);
/* 14 */
EXTERN void		Tk_CanvasPsPath(Tcl_Interp *interp, Tk_Canvas canvas,
				double *coordPtr, int numPoints);
/* 15 */
EXTERN int		Tk_CanvasPsStipple(Tcl_Interp *interp,
				Tk_Canvas canvas, Pixmap bitmap);
/* 16 */
EXTERN double		Tk_CanvasPsY(Tk_Canvas canvas, double y);
/* 17 */
EXTERN void		Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc);
/* 18 */
EXTERN int		Tk_CanvasTagsParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 19 */
EXTERN const char *	Tk_CanvasTagsPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 20 */
EXTERN Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas);
/* 21 */
EXTERN void		Tk_CanvasWindowCoords(Tk_Canvas canvas, double x,
				double y, short *screenXPtr,
				short *screenYPtr);
/* 22 */
EXTERN void		Tk_ChangeWindowAttributes(Tk_Window tkwin,
				unsigned long valueMask,
				XSetWindowAttributes *attsPtr);
/* 23 */
EXTERN int		Tk_CharBbox(Tk_TextLayout layout, int index,
				int *xPtr, int *yPtr, int *widthPtr,
				int *heightPtr);
/* 24 */
EXTERN void		Tk_ClearSelection(Tk_Window tkwin, Atom selection);
/* 25 */
EXTERN int		Tk_ClipboardAppend(Tcl_Interp *interp,
				Tk_Window tkwin, Atom target, Atom format,
				const char *buffer);
/* 26 */
EXTERN int		Tk_ClipboardClear(Tcl_Interp *interp,
				Tk_Window tkwin);
/* 27 */
EXTERN int		Tk_ConfigureInfo(Tcl_Interp *interp, Tk_Window tkwin,
				const Tk_ConfigSpec *specs, char *widgRec,
				const char *argvName, int flags);
/* 28 */
EXTERN int		Tk_ConfigureValue(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				char *widgRec, const char *argvName,
				int flags);
/* 29 */
EXTERN int		Tk_ConfigureWidget(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				int argc, const char **argv, char *widgRec,
				int flags);
/* 30 */
EXTERN void		Tk_ConfigureWindow(Tk_Window tkwin,
				unsigned int valueMask,
				XWindowChanges *valuePtr);
/* 31 */
EXTERN Tk_TextLayout	Tk_ComputeTextLayout(Tk_Font font, const char *str,
				int numChars, int wrapLength,
				Tk_Justify justify, int flags, int *widthPtr,
				int *heightPtr);
/* 32 */
EXTERN Tk_Window	Tk_CoordsToWindow(int rootX, int rootY,
				Tk_Window tkwin);
/* 33 */
EXTERN unsigned long	Tk_CreateBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr,
				const char *script, int append);
/* 34 */
EXTERN Tk_BindingTable	Tk_CreateBindingTable(Tcl_Interp *interp);
/* 35 */
EXTERN Tk_ErrorHandler	Tk_CreateErrorHandler(Display *display, int errNum,
				int request, int minorCode,
				Tk_ErrorProc *errorProc,
				ClientData clientData);
/* 36 */
EXTERN void		Tk_CreateEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				ClientData clientData);
/* 37 */
EXTERN void		Tk_CreateGenericHandler(Tk_GenericProc *proc,
				ClientData clientData);
/* 38 */
EXTERN void		Tk_CreateImageType(const Tk_ImageType *typePtr);
/* 39 */
EXTERN void		Tk_CreateItemType(Tk_ItemType *typePtr);
/* 40 */
EXTERN void		Tk_CreatePhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);
/* 41 */
EXTERN void		Tk_CreateSelHandler(Tk_Window tkwin, Atom selection,
				Atom target, Tk_SelectionProc *proc,
				ClientData clientData, Atom format);
/* 42 */
EXTERN Tk_Window	Tk_CreateWindow(Tcl_Interp *interp, Tk_Window parent,
				const char *name, const char *screenName);
/* 43 */
EXTERN Tk_Window	Tk_CreateWindowFromPath(Tcl_Interp *interp,
				Tk_Window tkwin, const char *pathName,
				const char *screenName);
/* 44 */
EXTERN int		Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
				const void *source, int width, int height);
/* 45 */
EXTERN void		Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor);
/* 46 */
EXTERN void		Tk_DeleteAllBindings(Tk_BindingTable bindingTable,
				ClientData object);
/* 47 */
EXTERN int		Tk_DeleteBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr);
/* 48 */
EXTERN void		Tk_DeleteBindingTable(Tk_BindingTable bindingTable);
/* 49 */
EXTERN void		Tk_DeleteErrorHandler(Tk_ErrorHandler handler);
/* 50 */
EXTERN void		Tk_DeleteEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				ClientData clientData);
/* 51 */
EXTERN void		Tk_DeleteGenericHandler(Tk_GenericProc *proc,
				ClientData clientData);
/* 52 */
EXTERN void		Tk_DeleteImage(Tcl_Interp *interp, const char *name);
/* 53 */
EXTERN void		Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection,
				Atom target);
/* 54 */
EXTERN void		Tk_DestroyWindow(Tk_Window tkwin);
/* 55 */
EXTERN const char *	Tk_DisplayName(Tk_Window tkwin);
/* 56 */
EXTERN int		Tk_DistanceToTextLayout(Tk_TextLayout layout, int x,
				int y);
/* 57 */
EXTERN void		Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				int numPoints, int borderWidth,
				int leftRelief);
/* 58 */
EXTERN void		Tk_Draw3DRectangle(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);
/* 59 */
EXTERN void		Tk_DrawChars(Display *display, Drawable drawable,
				GC gc, Tk_Font tkfont, const char *source,
				int numBytes, int x, int y);
/* 60 */
EXTERN void		Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc,
				int width, Drawable drawable);
/* 61 */
EXTERN void		Tk_DrawTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int firstChar, int lastChar);
/* 62 */
EXTERN void		Tk_Fill3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				int numPoints, int borderWidth,
				int leftRelief);
/* 63 */
EXTERN void		Tk_Fill3DRectangle(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);
/* 64 */







|








|

|
>

|
|
|











|













|




|




|
|






|







|
|
|





|
<



|


|










|














|


|
|







|


|















|









|







|



|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
EXTERN int		Tk_CanvasPsColor(Tcl_Interp *interp,
				Tk_Canvas canvas, XColor *colorPtr);
/* 13 */
EXTERN int		Tk_CanvasPsFont(Tcl_Interp *interp, Tk_Canvas canvas,
				Tk_Font font);
/* 14 */
EXTERN void		Tk_CanvasPsPath(Tcl_Interp *interp, Tk_Canvas canvas,
				double *coordPtr, Tcl_Size numPoints);
/* 15 */
EXTERN int		Tk_CanvasPsStipple(Tcl_Interp *interp,
				Tk_Canvas canvas, Pixmap bitmap);
/* 16 */
EXTERN double		Tk_CanvasPsY(Tk_Canvas canvas, double y);
/* 17 */
EXTERN void		Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc);
/* 18 */
EXTERN int		Tk_CanvasTagsParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 19 */
EXTERN const char *	Tk_CanvasTagsPrintProc(void *clientData,
				Tk_Window tkwin, char *widgRec,
				Tcl_Size offset, Tcl_FreeProc **freeProcPtr);
/* 20 */
EXTERN Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas);
/* 21 */
EXTERN void		Tk_CanvasWindowCoords(Tk_Canvas canvas, double x,
				double y, short *screenXPtr,
				short *screenYPtr);
/* 22 */
EXTERN void		Tk_ChangeWindowAttributes(Tk_Window tkwin,
				unsigned long valueMask,
				XSetWindowAttributes *attsPtr);
/* 23 */
EXTERN int		Tk_CharBbox(Tk_TextLayout layout, Tcl_Size index,
				int *xPtr, int *yPtr, int *widthPtr,
				int *heightPtr);
/* 24 */
EXTERN void		Tk_ClearSelection(Tk_Window tkwin, Atom selection);
/* 25 */
EXTERN int		Tk_ClipboardAppend(Tcl_Interp *interp,
				Tk_Window tkwin, Atom target, Atom format,
				const char *buffer);
/* 26 */
EXTERN int		Tk_ClipboardClear(Tcl_Interp *interp,
				Tk_Window tkwin);
/* 27 */
EXTERN int		Tk_ConfigureInfo(Tcl_Interp *interp, Tk_Window tkwin,
				const Tk_ConfigSpec *specs, void *widgRec,
				const char *argvName, int flags);
/* 28 */
EXTERN int		Tk_ConfigureValue(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				void *widgRec, const char *argvName,
				int flags);
/* 29 */
EXTERN int		Tk_ConfigureWidget(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				Tcl_Size objc, Tcl_Obj *const *objv,
				void *widgRec, int flags);
/* 30 */
EXTERN void		Tk_ConfigureWindow(Tk_Window tkwin,
				unsigned int valueMask,
				XWindowChanges *valuePtr);
/* 31 */
EXTERN Tk_TextLayout	Tk_ComputeTextLayout(Tk_Font font, const char *str,
				Tcl_Size numChars, int wrapLength,
				Tk_Justify justify, int flags, int *widthPtr,
				int *heightPtr);
/* 32 */
EXTERN Tk_Window	Tk_CoordsToWindow(int rootX, int rootY,
				Tk_Window tkwin);
/* 33 */
EXTERN unsigned long	Tk_CreateBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable, void *object,
				const char *eventStr, const char *script,
				int append);
/* 34 */
EXTERN Tk_BindingTable	Tk_CreateBindingTable(Tcl_Interp *interp);
/* 35 */
EXTERN Tk_ErrorHandler	Tk_CreateErrorHandler(Display *display, int errNum,
				int request, int minorCode,
				Tk_ErrorProc *errorProc, void *clientData);

/* 36 */
EXTERN void		Tk_CreateEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				void *clientData);
/* 37 */
EXTERN void		Tk_CreateGenericHandler(Tk_GenericProc *proc,
				void *clientData);
/* 38 */
EXTERN void		Tk_CreateImageType(const Tk_ImageType *typePtr);
/* 39 */
EXTERN void		Tk_CreateItemType(Tk_ItemType *typePtr);
/* 40 */
EXTERN void		Tk_CreatePhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);
/* 41 */
EXTERN void		Tk_CreateSelHandler(Tk_Window tkwin, Atom selection,
				Atom target, Tk_SelectionProc *proc,
				void *clientData, Atom format);
/* 42 */
EXTERN Tk_Window	Tk_CreateWindow(Tcl_Interp *interp, Tk_Window parent,
				const char *name, const char *screenName);
/* 43 */
EXTERN Tk_Window	Tk_CreateWindowFromPath(Tcl_Interp *interp,
				Tk_Window tkwin, const char *pathName,
				const char *screenName);
/* 44 */
EXTERN int		Tk_DefineBitmap(Tcl_Interp *interp, const char *name,
				const void *source, int width, int height);
/* 45 */
EXTERN void		Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor);
/* 46 */
EXTERN void		Tk_DeleteAllBindings(Tk_BindingTable bindingTable,
				void *object);
/* 47 */
EXTERN int		Tk_DeleteBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable, void *object,
				const char *eventStr);
/* 48 */
EXTERN void		Tk_DeleteBindingTable(Tk_BindingTable bindingTable);
/* 49 */
EXTERN void		Tk_DeleteErrorHandler(Tk_ErrorHandler handler);
/* 50 */
EXTERN void		Tk_DeleteEventHandler(Tk_Window token,
				unsigned long mask, Tk_EventProc *proc,
				void *clientData);
/* 51 */
EXTERN void		Tk_DeleteGenericHandler(Tk_GenericProc *proc,
				void *clientData);
/* 52 */
EXTERN void		Tk_DeleteImage(Tcl_Interp *interp, const char *name);
/* 53 */
EXTERN void		Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection,
				Atom target);
/* 54 */
EXTERN void		Tk_DestroyWindow(Tk_Window tkwin);
/* 55 */
EXTERN const char *	Tk_DisplayName(Tk_Window tkwin);
/* 56 */
EXTERN int		Tk_DistanceToTextLayout(Tk_TextLayout layout, int x,
				int y);
/* 57 */
EXTERN void		Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				Tcl_Size numPoints, int borderWidth,
				int leftRelief);
/* 58 */
EXTERN void		Tk_Draw3DRectangle(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);
/* 59 */
EXTERN void		Tk_DrawChars(Display *display, Drawable drawable,
				GC gc, Tk_Font tkfont, const char *source,
				Tcl_Size numBytes, int x, int y);
/* 60 */
EXTERN void		Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc,
				int width, Drawable drawable);
/* 61 */
EXTERN void		Tk_DrawTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				Tcl_Size firstChar, Tcl_Size lastChar);
/* 62 */
EXTERN void		Tk_Fill3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				Tcl_Size numPoints, int borderWidth,
				int leftRelief);
/* 63 */
EXTERN void		Tk_Fill3DRectangle(Tk_Window tkwin,
				Drawable drawable, Tk_3DBorder border, int x,
				int y, int width, int height,
				int borderWidth, int relief);
/* 64 */
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
EXTERN void		Tk_FreeFont(Tk_Font f);
/* 72 */
EXTERN void		Tk_FreeGC(Display *display, GC gc);
/* 73 */
EXTERN void		Tk_FreeImage(Tk_Image image);
/* 74 */
EXTERN void		Tk_FreeOptions(const Tk_ConfigSpec *specs,
				char *widgRec, Display *display,
				int needFlags);
/* 75 */
EXTERN void		Tk_FreePixmap(Display *display, Pixmap pixmap);
/* 76 */
EXTERN void		Tk_FreeTextLayout(Tk_TextLayout textLayout);
/* 77 */
TK_DEPRECATED("function does nothing, call can be removed")
void			Tk_FreeXId(Display *display, XID xid);
/* 78 */
EXTERN GC		Tk_GCForColor(XColor *colorPtr, Drawable drawable);
/* 79 */
EXTERN void		Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,
				int reqHeight);
/* 80 */
EXTERN Tk_3DBorder	Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
				Tk_Uid colorName);
/* 81 */
EXTERN void		Tk_GetAllBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object);
/* 82 */
EXTERN int		Tk_GetAnchor(Tcl_Interp *interp, const char *str,
				Tk_Anchor *anchorPtr);
/* 83 */
EXTERN const char *	Tk_GetAtomName(Tk_Window tkwin, Atom atom);
/* 84 */
EXTERN const char *	Tk_GetBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr);
/* 85 */
EXTERN Pixmap		Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str);
/* 86 */
EXTERN Pixmap		Tk_GetBitmapFromData(Tcl_Interp *interp,
				Tk_Window tkwin, const void *source,
				int width, int height);







|





|
<
<










|
<







|
|







278
279
280
281
282
283
284
285
286
287
288
289
290
291


292
293
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
EXTERN void		Tk_FreeFont(Tk_Font f);
/* 72 */
EXTERN void		Tk_FreeGC(Display *display, GC gc);
/* 73 */
EXTERN void		Tk_FreeImage(Tk_Image image);
/* 74 */
EXTERN void		Tk_FreeOptions(const Tk_ConfigSpec *specs,
				void *widgRec, Display *display,
				int needFlags);
/* 75 */
EXTERN void		Tk_FreePixmap(Display *display, Pixmap pixmap);
/* 76 */
EXTERN void		Tk_FreeTextLayout(Tk_TextLayout textLayout);
/* Slot 77 is reserved */


/* 78 */
EXTERN GC		Tk_GCForColor(XColor *colorPtr, Drawable drawable);
/* 79 */
EXTERN void		Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,
				int reqHeight);
/* 80 */
EXTERN Tk_3DBorder	Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
				Tk_Uid colorName);
/* 81 */
EXTERN void		Tk_GetAllBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable, void *object);

/* 82 */
EXTERN int		Tk_GetAnchor(Tcl_Interp *interp, const char *str,
				Tk_Anchor *anchorPtr);
/* 83 */
EXTERN const char *	Tk_GetAtomName(Tk_Window tkwin, Atom atom);
/* 84 */
EXTERN const char *	Tk_GetBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable, void *object,
				const char *eventStr);
/* 85 */
EXTERN Pixmap		Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str);
/* 86 */
EXTERN Pixmap		Tk_GetBitmapFromData(Tcl_Interp *interp,
				Tk_Window tkwin, const void *source,
				int width, int height);
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/* 96 */
EXTERN GC		Tk_GetGC(Tk_Window tkwin, unsigned long valueMask,
				XGCValues *valuePtr);
/* 97 */
EXTERN Tk_Image		Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
				const char *name,
				Tk_ImageChangedProc *changeProc,
				ClientData clientData);
/* 98 */
EXTERN ClientData	Tk_GetImageModelData(Tcl_Interp *interp,
				const char *name,
				const Tk_ImageType **typePtrPtr);
/* 99 */
EXTERN Tk_ItemType *	Tk_GetItemTypes(void);
/* 100 */
EXTERN int		Tk_GetJoinStyle(Tcl_Interp *interp, const char *str,
				int *joinPtr);







|

|







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/* 96 */
EXTERN GC		Tk_GetGC(Tk_Window tkwin, unsigned long valueMask,
				XGCValues *valuePtr);
/* 97 */
EXTERN Tk_Image		Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
				const char *name,
				Tk_ImageChangedProc *changeProc,
				void *clientData);
/* 98 */
EXTERN void *		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);
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
/* 106 */
EXTERN int		Tk_GetRelief(Tcl_Interp *interp, const char *name,
				int *reliefPtr);
/* 107 */
EXTERN void		Tk_GetRootCoords(Tk_Window tkwin, int *xPtr,
				int *yPtr);
/* 108 */
EXTERN int		Tk_GetScrollInfo(Tcl_Interp *interp, int argc,
				const char **argv, double *dblPtr,
				int *intPtr);
/* 109 */
EXTERN int		Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, double *doublePtr);
/* 110 */
EXTERN int		Tk_GetSelection(Tcl_Interp *interp, Tk_Window tkwin,
				Atom selection, Atom target,
				Tk_GetSelProc *proc, ClientData clientData);
/* 111 */
EXTERN Tk_Uid		Tk_GetUid(const char *str);
/* 112 */
EXTERN Visual *		Tk_GetVisual(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, int *depthPtr,
				Colormap *colormapPtr);
/* 113 */
EXTERN void		Tk_GetVRootGeometry(Tk_Window tkwin, int *xPtr,
				int *yPtr, int *widthPtr, int *heightPtr);
/* 114 */
EXTERN int		Tk_Grab(Tcl_Interp *interp, Tk_Window tkwin,
				int grabGlobal);
/* 115 */
EXTERN void		Tk_HandleEvent(XEvent *eventPtr);
/* 116 */
EXTERN Tk_Window	Tk_IdToWindow(Display *display, Window window);
/* 117 */
EXTERN void		Tk_ImageChanged(Tk_ImageModel model, int x, int y,
				int width, int height, int imageWidth,
				int imageHeight);
/* 118 */
EXTERN int		Tk_Init(Tcl_Interp *interp);
/* 119 */
EXTERN Atom		Tk_InternAtom(Tk_Window tkwin, const char *name);
/* 120 */
EXTERN int		Tk_IntersectTextLayout(Tk_TextLayout layout, int x,
				int y, int width, int height);
/* 121 */
EXTERN void		Tk_MaintainGeometry(Tk_Window window,
				Tk_Window container, int x, int y, int width,
				int height);
/* 122 */
EXTERN Tk_Window	Tk_MainWindow(Tcl_Interp *interp);
/* 123 */
EXTERN void		Tk_MakeWindowExist(Tk_Window tkwin);
/* 124 */
EXTERN void		Tk_ManageGeometry(Tk_Window tkwin,
				const Tk_GeomMgr *mgrPtr,
				ClientData clientData);
/* 125 */
EXTERN void		Tk_MapWindow(Tk_Window tkwin);
/* 126 */
EXTERN int		Tk_MeasureChars(Tk_Font tkfont, const char *source,
				int numBytes, int maxPixels, int flags,
				int *lengthPtr);
/* 127 */
EXTERN void		Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y,
				int width, int height);
/* 128 */
EXTERN void		Tk_MoveWindow(Tk_Window tkwin, int x, int y);
/* 129 */







|








|




















|
<















|
<




|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
/* 106 */
EXTERN int		Tk_GetRelief(Tcl_Interp *interp, const char *name,
				int *reliefPtr);
/* 107 */
EXTERN void		Tk_GetRootCoords(Tk_Window tkwin, int *xPtr,
				int *yPtr);
/* 108 */
EXTERN int		Tk_GetScrollInfo(Tcl_Interp *interp, Tcl_Size argc,
				const char **argv, double *dblPtr,
				int *intPtr);
/* 109 */
EXTERN int		Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, double *doublePtr);
/* 110 */
EXTERN int		Tk_GetSelection(Tcl_Interp *interp, Tk_Window tkwin,
				Atom selection, Atom target,
				Tk_GetSelProc *proc, void *clientData);
/* 111 */
EXTERN Tk_Uid		Tk_GetUid(const char *str);
/* 112 */
EXTERN Visual *		Tk_GetVisual(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, int *depthPtr,
				Colormap *colormapPtr);
/* 113 */
EXTERN void		Tk_GetVRootGeometry(Tk_Window tkwin, int *xPtr,
				int *yPtr, int *widthPtr, int *heightPtr);
/* 114 */
EXTERN int		Tk_Grab(Tcl_Interp *interp, Tk_Window tkwin,
				int grabGlobal);
/* 115 */
EXTERN void		Tk_HandleEvent(XEvent *eventPtr);
/* 116 */
EXTERN Tk_Window	Tk_IdToWindow(Display *display, Window window);
/* 117 */
EXTERN void		Tk_ImageChanged(Tk_ImageModel model, int x, int y,
				int width, int height, int imageWidth,
				int imageHeight);
/* Slot 118 is reserved */

/* 119 */
EXTERN Atom		Tk_InternAtom(Tk_Window tkwin, const char *name);
/* 120 */
EXTERN int		Tk_IntersectTextLayout(Tk_TextLayout layout, int x,
				int y, int width, int height);
/* 121 */
EXTERN void		Tk_MaintainGeometry(Tk_Window window,
				Tk_Window container, int x, int y, int width,
				int height);
/* 122 */
EXTERN Tk_Window	Tk_MainWindow(Tcl_Interp *interp);
/* 123 */
EXTERN void		Tk_MakeWindowExist(Tk_Window tkwin);
/* 124 */
EXTERN void		Tk_ManageGeometry(Tk_Window tkwin,
				const Tk_GeomMgr *mgrPtr, void *clientData);

/* 125 */
EXTERN void		Tk_MapWindow(Tk_Window tkwin);
/* 126 */
EXTERN int		Tk_MeasureChars(Tk_Font tkfont, const char *source,
				Tcl_Size numBytes, int maxPixels, int flags,
				int *lengthPtr);
/* 127 */
EXTERN void		Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y,
				int width, int height);
/* 128 */
EXTERN void		Tk_MoveWindow(Tk_Window tkwin, int x, int y);
/* 129 */
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
/* 140 */
EXTERN const char *	Tk_NameOfRelief(int relief);
/* 141 */
EXTERN Tk_Window	Tk_NameToWindow(Tcl_Interp *interp,
				const char *pathName, Tk_Window tkwin);
/* 142 */
EXTERN void		Tk_OwnSelection(Tk_Window tkwin, Atom selection,
				Tk_LostSelProc *proc, ClientData clientData);
/* 143 */
EXTERN int		Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
				int *argcPtr, const char **argv,
				const Tk_ArgvInfo *argTable, int flags);
/* 144 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height);
/* 145 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutZoomedBlock_NoComposite(
				Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int zoomX, int zoomY,
				int subsampleX, int subsampleY);
/* 146 */
EXTERN int		Tk_PhotoGetImage(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr);
/* 147 */
EXTERN void		Tk_PhotoBlank(Tk_PhotoHandle handle);
/* 148 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
				int width, int height);
/* 149 */
EXTERN void		Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
				int *heightPtr);
/* 150 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
				int width, int height);
/* 151 */
EXTERN int		Tk_PointToChar(Tk_TextLayout layout, int x, int y);
/* 152 */
EXTERN int		Tk_PostscriptFontName(Tk_Font tkfont,
				Tcl_DString *dsPtr);
/* 153 */
EXTERN void		Tk_PreserveColormap(Display *display,







|




|
<
<
<
<
|
<
<
<
<
<
<





|
<
<
<



|
<
<
<







464
465
466
467
468
469
470
471
472
473
474
475
476




477






478
479
480
481
482
483



484
485
486
487



488
489
490
491
492
493
494
/* 140 */
EXTERN const char *	Tk_NameOfRelief(int relief);
/* 141 */
EXTERN Tk_Window	Tk_NameToWindow(Tcl_Interp *interp,
				const char *pathName, Tk_Window tkwin);
/* 142 */
EXTERN void		Tk_OwnSelection(Tk_Window tkwin, Atom selection,
				Tk_LostSelProc *proc, void *clientData);
/* 143 */
EXTERN int		Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
				int *argcPtr, const char **argv,
				const Tk_ArgvInfo *argTable, int flags);
/* Slot 144 is reserved */




/* Slot 145 is reserved */






/* 146 */
EXTERN int		Tk_PhotoGetImage(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr);
/* 147 */
EXTERN void		Tk_PhotoBlank(Tk_PhotoHandle handle);
/* Slot 148 is reserved */



/* 149 */
EXTERN void		Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
				int *heightPtr);
/* Slot 150 is reserved */



/* 151 */
EXTERN int		Tk_PointToChar(Tk_TextLayout layout, int x, int y);
/* 152 */
EXTERN int		Tk_PostscriptFontName(Tk_Font tkfont,
				Tcl_DString *dsPtr);
/* 153 */
EXTERN void		Tk_PreserveColormap(Display *display,
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
/* 156 */
EXTERN void		Tk_ResizeWindow(Tk_Window tkwin, int width,
				int height);
/* 157 */
EXTERN int		Tk_RestackWindow(Tk_Window tkwin, int aboveBelow,
				Tk_Window other);
/* 158 */
EXTERN Tk_RestrictProc * Tk_RestrictEvents(Tk_RestrictProc *proc,
				ClientData arg, ClientData *prevArgPtr);
/* 159 */
EXTERN int		Tk_SafeInit(Tcl_Interp *interp);
/* 160 */
EXTERN const char *	Tk_SetAppName(Tk_Window tkwin, const char *name);
/* 161 */
EXTERN void		Tk_SetBackgroundFromBorder(Tk_Window tkwin,
				Tk_3DBorder border);
/* 162 */
EXTERN void		Tk_SetClass(Tk_Window tkwin, const char *className);







|
|
|
<







504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
/* 156 */
EXTERN void		Tk_ResizeWindow(Tk_Window tkwin, int width,
				int height);
/* 157 */
EXTERN int		Tk_RestackWindow(Tk_Window tkwin, int aboveBelow,
				Tk_Window other);
/* 158 */
EXTERN Tk_RestrictProc * Tk_RestrictEvents(Tk_RestrictProc *proc, void *arg,
				void **prevArgPtr);
/* Slot 159 is reserved */

/* 160 */
EXTERN const char *	Tk_SetAppName(Tk_Window tkwin, const char *name);
/* 161 */
EXTERN void		Tk_SetBackgroundFromBorder(Tk_Window tkwin,
				Tk_3DBorder border);
/* 162 */
EXTERN void		Tk_SetClass(Tk_Window tkwin, const char *className);
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
/* 174 */
EXTERN int		Tk_StrictMotif(Tk_Window tkwin);
/* 175 */
EXTERN void		Tk_TextLayoutToPostscript(Tcl_Interp *interp,
				Tk_TextLayout layout);
/* 176 */
EXTERN int		Tk_TextWidth(Tk_Font font, const char *str,
				int numBytes);
/* 177 */
EXTERN void		Tk_UndefineCursor(Tk_Window window);
/* 178 */
EXTERN void		Tk_UnderlineChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, int x, int y,
				int firstByte, int lastByte);
/* 179 */
EXTERN void		Tk_UnderlineTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int underline);
/* 180 */
EXTERN void		Tk_Ungrab(Tk_Window tkwin);







|






|







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
/* 174 */
EXTERN int		Tk_StrictMotif(Tk_Window tkwin);
/* 175 */
EXTERN void		Tk_TextLayoutToPostscript(Tcl_Interp *interp,
				Tk_TextLayout layout);
/* 176 */
EXTERN int		Tk_TextWidth(Tk_Font font, const char *str,
				Tcl_Size numBytes);
/* 177 */
EXTERN void		Tk_UndefineCursor(Tk_Window window);
/* 178 */
EXTERN void		Tk_UnderlineChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, int x, int y,
				Tcl_Size firstByte, Tcl_Size lastByte);
/* 179 */
EXTERN void		Tk_UnderlineTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				int underline);
/* 180 */
EXTERN void		Tk_Ungrab(Tk_Window tkwin);
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
EXTERN int		Tk_GetPixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				int *intPtr);
/* 209 */
EXTERN int		Tk_GetReliefFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *resultPtr);
/* 210 */
EXTERN int		Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[], double *dblPtr,
				int *intPtr);
/* 211 */
EXTERN int		Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
/* 212 */
EXTERN void		Tk_MainEx(int argc, char **argv,
				Tcl_AppInitProc *appInitProc,
				Tcl_Interp *interp);
/* 213 */
EXTERN void		Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
/* 214 */
EXTERN int		Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionTable, int objc,
				Tcl_Obj *const objv[], Tk_Window tkwin,
				Tk_SavedOptions *savePtr, int *maskPtr);
/* 215 */
EXTERN void		Tk_InitConsoleChannels(Tcl_Interp *interp);
/* 216 */
EXTERN int		Tk_CreateConsoleWindow(Tcl_Interp *interp);
/* 217 */
EXTERN void		Tk_CreateSmoothMethod(Tcl_Interp *interp,
				const Tk_SmoothMethod *method);
/* Slot 218 is reserved */
/* Slot 219 is reserved */
/* 220 */
EXTERN int		Tk_GetDash(Tcl_Interp *interp, const char *value,







|
|
|



|
<
<
<




|




|
<







649
650
651
652
653
654
655
656
657
658
659
660
661
662



663
664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
EXTERN int		Tk_GetPixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				int *intPtr);
/* 209 */
EXTERN int		Tk_GetReliefFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *resultPtr);
/* 210 */
EXTERN int		Tk_GetScrollInfoObj(Tcl_Interp *interp,
				Tcl_Size objc, Tcl_Obj *const objv[],
				double *dblPtr, int *intPtr);
/* 211 */
EXTERN int		Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
/* Slot 212 is reserved */



/* 213 */
EXTERN void		Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
/* 214 */
EXTERN int		Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionTable, Tcl_Size objc,
				Tcl_Obj *const objv[], Tk_Window tkwin,
				Tk_SavedOptions *savePtr, int *maskPtr);
/* 215 */
EXTERN void		Tk_InitConsoleChannels(Tcl_Interp *interp);
/* Slot 216 is reserved */

/* 217 */
EXTERN void		Tk_CreateSmoothMethod(Tcl_Interp *interp,
				const Tk_SmoothMethod *method);
/* Slot 218 is reserved */
/* Slot 219 is reserved */
/* 220 */
EXTERN int		Tk_GetDash(Tcl_Interp *interp, const char *value,
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
EXTERN int		Tk_PostscriptImage(Tk_Image image,
				Tcl_Interp *interp, Tk_Window tkwin,
				Tk_PostscriptInfo psinfo, int x, int y,
				int width, int height, int prepass);
/* 235 */
EXTERN void		Tk_PostscriptPath(Tcl_Interp *interp,
				Tk_PostscriptInfo psInfo, double *coordPtr,
				int numPoints);
/* 236 */
EXTERN int		Tk_PostscriptStipple(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_PostscriptInfo psInfo,
				Pixmap bitmap);
/* 237 */
EXTERN double		Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo);
/* 238 */







|







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
EXTERN int		Tk_PostscriptImage(Tk_Image image,
				Tcl_Interp *interp, Tk_Window tkwin,
				Tk_PostscriptInfo psinfo, int x, int y,
				int width, int height, int prepass);
/* 235 */
EXTERN void		Tk_PostscriptPath(Tcl_Interp *interp,
				Tk_PostscriptInfo psInfo, double *coordPtr,
				Tcl_Size numPoints);
/* 236 */
EXTERN int		Tk_PostscriptStipple(Tcl_Interp *interp,
				Tk_Window tkwin, Tk_PostscriptInfo psInfo,
				Pixmap bitmap);
/* 237 */
EXTERN double		Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo);
/* 238 */
773
774
775
776
777
778
779
780
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
				Tk_ClientMessageProc *proc);
/* 241 */
EXTERN Tk_Window	Tk_CreateAnonymousWindow(Tcl_Interp *interp,
				Tk_Window parent, const char *screenName);
/* 242 */
EXTERN void		Tk_SetClassProcs(Tk_Window tkwin,
				const Tk_ClassProcs *procs,
				ClientData instanceData);
/* 243 */
EXTERN void		Tk_SetInternalBorderEx(Tk_Window tkwin, int left,
				int right, int top, int bottom);
/* 244 */
EXTERN void		Tk_SetMinimumRequestSize(Tk_Window tkwin,
				int minWidth, int minHeight);
/* 245 */
EXTERN void		Tk_SetCaretPos(Tk_Window tkwin, int x, int y,
				int height);
/* 246 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int compRule);
/* 247 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int zoomX, int zoomY,
				int subsampleX, int subsampleY, int compRule);
/* 248 */
EXTERN int		Tk_CollapseMotionEvents(Display *display,
				int collapse);
/* 249 */
EXTERN Tk_StyleEngine	Tk_RegisterStyleEngine(const char *name,
				Tk_StyleEngine parent);
/* 250 */
EXTERN Tk_StyleEngine	Tk_GetStyleEngine(const char *name);
/* 251 */
EXTERN int		Tk_RegisterStyledElement(Tk_StyleEngine engine,
				Tk_ElementSpec *templatePtr);
/* 252 */
EXTERN int		Tk_GetElementId(const char *name);
/* 253 */
EXTERN Tk_Style		Tk_CreateStyle(const char *name,
				Tk_StyleEngine engine, ClientData clientData);
/* 254 */
EXTERN Tk_Style		Tk_GetStyle(Tcl_Interp *interp, const char *name);
/* 255 */
EXTERN void		Tk_FreeStyle(Tk_Style style);
/* 256 */
EXTERN const char *	Tk_NameOfStyle(Tk_Style style);
/* 257 */
EXTERN Tk_Style		Tk_AllocStyleFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr);
/* 258 */
EXTERN Tk_Style		Tk_GetStyleFromObj(Tcl_Obj *objPtr);
/* 259 */
EXTERN void		Tk_FreeStyleFromObj(Tcl_Obj *objPtr);
/* 260 */
EXTERN Tk_StyledElement	 Tk_GetStyledElement(Tk_Style style, int elementId,

				Tk_OptionTable optionTable);
/* 261 */
EXTERN void		Tk_GetElementSize(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, int width, int height,
				int inner, int *widthPtr, int *heightPtr);
/* 262 */







|









|
<
<
<
<
|
<
<
<
<
<















|









|
<
|
<

|
>







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764




765





766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791

792

793
794
795
796
797
798
799
800
801
802
				Tk_ClientMessageProc *proc);
/* 241 */
EXTERN Tk_Window	Tk_CreateAnonymousWindow(Tcl_Interp *interp,
				Tk_Window parent, const char *screenName);
/* 242 */
EXTERN void		Tk_SetClassProcs(Tk_Window tkwin,
				const Tk_ClassProcs *procs,
				void *instanceData);
/* 243 */
EXTERN void		Tk_SetInternalBorderEx(Tk_Window tkwin, int left,
				int right, int top, int bottom);
/* 244 */
EXTERN void		Tk_SetMinimumRequestSize(Tk_Window tkwin,
				int minWidth, int minHeight);
/* 245 */
EXTERN void		Tk_SetCaretPos(Tk_Window tkwin, int x, int y,
				int height);
/* Slot 246 is reserved */




/* Slot 247 is reserved */





/* 248 */
EXTERN int		Tk_CollapseMotionEvents(Display *display,
				int collapse);
/* 249 */
EXTERN Tk_StyleEngine	Tk_RegisterStyleEngine(const char *name,
				Tk_StyleEngine parent);
/* 250 */
EXTERN Tk_StyleEngine	Tk_GetStyleEngine(const char *name);
/* 251 */
EXTERN int		Tk_RegisterStyledElement(Tk_StyleEngine engine,
				Tk_ElementSpec *templatePtr);
/* 252 */
EXTERN int		Tk_GetElementId(const char *name);
/* 253 */
EXTERN Tk_Style		Tk_CreateStyle(const char *name,
				Tk_StyleEngine engine, void *clientData);
/* 254 */
EXTERN Tk_Style		Tk_GetStyle(Tcl_Interp *interp, const char *name);
/* 255 */
EXTERN void		Tk_FreeStyle(Tk_Style style);
/* 256 */
EXTERN const char *	Tk_NameOfStyle(Tk_Style style);
/* 257 */
EXTERN Tk_Style		Tk_AllocStyleFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr);
/* Slot 258 is reserved */

/* Slot 259 is reserved */

/* 260 */
EXTERN Tk_StyledElement	 Tk_GetStyledElement(Tk_Style style,
				Tcl_Size elementId,
				Tk_OptionTable optionTable);
/* 261 */
EXTERN void		Tk_GetElementSize(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, int width, int height,
				int inner, int *widthPtr, int *heightPtr);
/* 262 */
869
870
871
872
873
874
875
876
877
878
879
880
881
882
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
				Tk_PhotoHandle handle, int width, int height);
/* 269 */
EXTERN long		Tk_GetUserInactiveTime(Display *dpy);
/* 270 */
EXTERN void		Tk_ResetUserInactiveTime(Display *dpy);
/* 271 */
EXTERN Tcl_Interp *	Tk_Interp(Tk_Window tkwin);
/* 272 */
EXTERN void		Tk_CreateOldImageType(const Tk_ImageType *typePtr);
/* 273 */
EXTERN void		Tk_CreateOldPhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);
/* 274 */
EXTERN int		Tk_AlwaysShowSelection(Tk_Window tkwin);
/* 275 */
EXTERN unsigned		Tk_GetButtonMask(unsigned button);
/* 276 */
EXTERN int		Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				double *doublePtr);
/* 277 */
EXTERN Tcl_Obj *	Tk_NewWindowObj(Tk_Window tkwin);
/* 278 */
EXTERN void		Tk_SendVirtualEvent(Tk_Window tkwin,
				const char *eventName, Tcl_Obj *detail);
/* 279 */
EXTERN Tcl_Obj *	Tk_FontGetDescription(Tk_Font tkfont);


































typedef struct {
    const struct TkPlatStubs *tkPlatStubs;
    const struct TkIntStubs *tkIntStubs;
    const struct TkIntPlatStubs *tkIntPlatStubs;
    const struct TkIntXlibStubs *tkIntXlibStubs;
} TkStubHooks;

typedef struct TkStubs {
    int magic;
    const TkStubHooks *hooks;

    void (*tk_MainLoop) (void); /* 0 */
    XColor * (*tk_3DBorderColor) (Tk_3DBorder border); /* 1 */
    GC (*tk_3DBorderGC) (Tk_Window tkwin, Tk_3DBorder border, int which); /* 2 */
    void (*tk_3DHorizontalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftIn, int rightIn, int topBevel, int relief); /* 3 */
    void (*tk_3DVerticalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftBevel, int relief); /* 4 */
    void (*tk_AddOption) (Tk_Window tkwin, const char *name, const char *value, int priority); /* 5 */
    void (*tk_BindEvent) (Tk_BindingTable bindingTable, XEvent *eventPtr, Tk_Window tkwin, int numObjects, ClientData *objectPtr); /* 6 */
    void (*tk_CanvasDrawableCoords) (Tk_Canvas canvas, double x, double y, short *drawableXPtr, short *drawableYPtr); /* 7 */
    void (*tk_CanvasEventuallyRedraw) (Tk_Canvas canvas, int x1, int y1, int x2, int y2); /* 8 */
    int (*tk_CanvasGetCoord) (Tcl_Interp *interp, Tk_Canvas canvas, const char *str, double *doublePtr); /* 9 */
    Tk_CanvasTextInfo * (*tk_CanvasGetTextInfo) (Tk_Canvas canvas); /* 10 */
    int (*tk_CanvasPsBitmap) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap, int x, int y, int width, int height); /* 11 */
    int (*tk_CanvasPsColor) (Tcl_Interp *interp, Tk_Canvas canvas, XColor *colorPtr); /* 12 */
    int (*tk_CanvasPsFont) (Tcl_Interp *interp, Tk_Canvas canvas, Tk_Font font); /* 13 */
    void (*tk_CanvasPsPath) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints); /* 14 */
    int (*tk_CanvasPsStipple) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); /* 15 */
    double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */
    void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */
    int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 18 */
    const char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */
    Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */
    void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */
    void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */
    int (*tk_CharBbox) (Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 23 */
    void (*tk_ClearSelection) (Tk_Window tkwin, Atom selection); /* 24 */
    int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, const char *buffer); /* 25 */
    int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */
    int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 27 */
    int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 28 */
    int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, const char **argv, char *widgRec, int flags); /* 29 */
    void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */
    Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, const char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */
    Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */
    unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr, const char *script, int append); /* 33 */
    Tk_BindingTable (*tk_CreateBindingTable) (Tcl_Interp *interp); /* 34 */
    Tk_ErrorHandler (*tk_CreateErrorHandler) (Display *display, int errNum, int request, int minorCode, Tk_ErrorProc *errorProc, ClientData clientData); /* 35 */
    void (*tk_CreateEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 36 */
    void (*tk_CreateGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 37 */
    void (*tk_CreateImageType) (const Tk_ImageType *typePtr); /* 38 */
    void (*tk_CreateItemType) (Tk_ItemType *typePtr); /* 39 */
    void (*tk_CreatePhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 40 */
    void (*tk_CreateSelHandler) (Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc *proc, ClientData clientData, Atom format); /* 41 */
    Tk_Window (*tk_CreateWindow) (Tcl_Interp *interp, Tk_Window parent, const char *name, const char *screenName); /* 42 */
    Tk_Window (*tk_CreateWindowFromPath) (Tcl_Interp *interp, Tk_Window tkwin, const char *pathName, const char *screenName); /* 43 */
    int (*tk_DefineBitmap) (Tcl_Interp *interp, const char *name, const void *source, int width, int height); /* 44 */
    void (*tk_DefineCursor) (Tk_Window window, Tk_Cursor cursor); /* 45 */
    void (*tk_DeleteAllBindings) (Tk_BindingTable bindingTable, ClientData object); /* 46 */
    int (*tk_DeleteBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 47 */
    void (*tk_DeleteBindingTable) (Tk_BindingTable bindingTable); /* 48 */
    void (*tk_DeleteErrorHandler) (Tk_ErrorHandler handler); /* 49 */
    void (*tk_DeleteEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 50 */
    void (*tk_DeleteGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 51 */
    void (*tk_DeleteImage) (Tcl_Interp *interp, const char *name); /* 52 */
    void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */
    void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */
    const char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */
    int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */
    void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 57 */
    void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */
    void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, int x, int y); /* 59 */
    void (*tk_DrawFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable); /* 60 */
    void (*tk_DrawTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar); /* 61 */
    void (*tk_Fill3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 62 */
    void (*tk_Fill3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 63 */
    Tk_PhotoHandle (*tk_FindPhoto) (Tcl_Interp *interp, const char *imageName); /* 64 */
    Font (*tk_FontId) (Tk_Font font); /* 65 */
    void (*tk_Free3DBorder) (Tk_3DBorder border); /* 66 */
    void (*tk_FreeBitmap) (Display *display, Pixmap bitmap); /* 67 */
    void (*tk_FreeColor) (XColor *colorPtr); /* 68 */
    void (*tk_FreeColormap) (Display *display, Colormap colormap); /* 69 */
    void (*tk_FreeCursor) (Display *display, Tk_Cursor cursor); /* 70 */
    void (*tk_FreeFont) (Tk_Font f); /* 71 */
    void (*tk_FreeGC) (Display *display, GC gc); /* 72 */
    void (*tk_FreeImage) (Tk_Image image); /* 73 */
    void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */
    void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */
    void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */
    TCL_DEPRECATED_API("function does nothing, call can be removed") void (*tk_FreeXId) (Display *display, XID xid); /* 77 */
    GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */
    void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */
    Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */
    void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); /* 81 */
    int (*tk_GetAnchor) (Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 82 */
    const char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
    const char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */
    Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 85 */
    Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, const void *source, int width, int height); /* 86 */
    int (*tk_GetCapStyle) (Tcl_Interp *interp, const char *str, int *capPtr); /* 87 */
    XColor * (*tk_GetColor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name); /* 88 */
    XColor * (*tk_GetColorByValue) (Tk_Window tkwin, XColor *colorPtr); /* 89 */
    Colormap (*tk_GetColormap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 90 */
    Tk_Cursor (*tk_GetCursor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid str); /* 91 */
    Tk_Cursor (*tk_GetCursorFromData) (Tcl_Interp *interp, Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); /* 92 */
    Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 93 */
    Tk_Font (*tk_GetFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 94 */
    void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */
    GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */
    Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */
    ClientData (*tk_GetImageModelData) (Tcl_Interp *interp, const char *name, const Tk_ImageType **typePtrPtr); /* 98 */
    Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */
    int (*tk_GetJoinStyle) (Tcl_Interp *interp, const char *str, int *joinPtr); /* 100 */
    int (*tk_GetJustify) (Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); /* 101 */
    int (*tk_GetNumMainWindows) (void); /* 102 */
    Tk_Uid (*tk_GetOption) (Tk_Window tkwin, const char *name, const char *className); /* 103 */
    int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *intPtr); /* 104 */
    Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */
    int (*tk_GetRelief) (Tcl_Interp *interp, const char *name, int *reliefPtr); /* 106 */
    void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */
    int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, const char **argv, double *dblPtr, int *intPtr); /* 108 */
    int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 109 */
    int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */
    Tk_Uid (*tk_GetUid) (const char *str); /* 111 */
    Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */
    void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */
    int (*tk_Grab) (Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); /* 114 */
    void (*tk_HandleEvent) (XEvent *eventPtr); /* 115 */
    Tk_Window (*tk_IdToWindow) (Display *display, Window window); /* 116 */
    void (*tk_ImageChanged) (Tk_ImageModel model, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */
    int (*tk_Init) (Tcl_Interp *interp); /* 118 */
    Atom (*tk_InternAtom) (Tk_Window tkwin, const char *name); /* 119 */
    int (*tk_IntersectTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height); /* 120 */
    void (*tk_MaintainGeometry) (Tk_Window window, Tk_Window container, int x, int y, int width, int height); /* 121 */
    Tk_Window (*tk_MainWindow) (Tcl_Interp *interp); /* 122 */
    void (*tk_MakeWindowExist) (Tk_Window tkwin); /* 123 */
    void (*tk_ManageGeometry) (Tk_Window tkwin, const Tk_GeomMgr *mgrPtr, ClientData clientData); /* 124 */
    void (*tk_MapWindow) (Tk_Window tkwin); /* 125 */
    int (*tk_MeasureChars) (Tk_Font tkfont, const char *source, int numBytes, int maxPixels, int flags, int *lengthPtr); /* 126 */
    void (*tk_MoveResizeWindow) (Tk_Window tkwin, int x, int y, int width, int height); /* 127 */
    void (*tk_MoveWindow) (Tk_Window tkwin, int x, int y); /* 128 */
    void (*tk_MoveToplevelWindow) (Tk_Window tkwin, int x, int y); /* 129 */
    const char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
    const char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
    const char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
    const char * (*tk_NameOfCapStyle) (int cap); /* 133 */
    const char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
    const char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
    const char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
    const char * (*tk_NameOfImage) (Tk_ImageModel model); /* 137 */
    const char * (*tk_NameOfJoinStyle) (int join); /* 138 */
    const char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
    const char * (*tk_NameOfRelief) (int relief); /* 140 */
    Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */
    void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */
    int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */
    int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */
    void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
    void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */
    int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */
    int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */
    void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */
    void (*tk_QueueWindowEvent) (XEvent *eventPtr, Tcl_QueuePosition position); /* 154 */
    void (*tk_RedrawImage) (Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY); /* 155 */
    void (*tk_ResizeWindow) (Tk_Window tkwin, int width, int height); /* 156 */
    int (*tk_RestackWindow) (Tk_Window tkwin, int aboveBelow, Tk_Window other); /* 157 */
    Tk_RestrictProc * (*tk_RestrictEvents) (Tk_RestrictProc *proc, ClientData arg, ClientData *prevArgPtr); /* 158 */
    int (*tk_SafeInit) (Tcl_Interp *interp); /* 159 */
    const char * (*tk_SetAppName) (Tk_Window tkwin, const char *name); /* 160 */
    void (*tk_SetBackgroundFromBorder) (Tk_Window tkwin, Tk_3DBorder border); /* 161 */
    void (*tk_SetClass) (Tk_Window tkwin, const char *className); /* 162 */
    void (*tk_SetGrid) (Tk_Window tkwin, int reqWidth, int reqHeight, int gridWidth, int gridHeight); /* 163 */
    void (*tk_SetInternalBorder) (Tk_Window tkwin, int width); /* 164 */
    void (*tk_SetWindowBackground) (Tk_Window tkwin, unsigned long pixel); /* 165 */
    void (*tk_SetWindowBackgroundPixmap) (Tk_Window tkwin, Pixmap pixmap); /* 166 */
    void (*tk_SetWindowBorder) (Tk_Window tkwin, unsigned long pixel); /* 167 */
    void (*tk_SetWindowBorderWidth) (Tk_Window tkwin, int width); /* 168 */
    void (*tk_SetWindowBorderPixmap) (Tk_Window tkwin, Pixmap pixmap); /* 169 */
    void (*tk_SetWindowColormap) (Tk_Window tkwin, Colormap colormap); /* 170 */
    int (*tk_SetWindowVisual) (Tk_Window tkwin, Visual *visual, int depth, Colormap colormap); /* 171 */
    void (*tk_SizeOfBitmap) (Display *display, Pixmap bitmap, int *widthPtr, int *heightPtr); /* 172 */
    void (*tk_SizeOfImage) (Tk_Image image, int *widthPtr, int *heightPtr); /* 173 */
    int (*tk_StrictMotif) (Tk_Window tkwin); /* 174 */
    void (*tk_TextLayoutToPostscript) (Tcl_Interp *interp, Tk_TextLayout layout); /* 175 */
    int (*tk_TextWidth) (Tk_Font font, const char *str, int numBytes); /* 176 */
    void (*tk_UndefineCursor) (Tk_Window window); /* 177 */
    void (*tk_UnderlineChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int x, int y, int firstByte, int lastByte); /* 178 */
    void (*tk_UnderlineTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); /* 179 */
    void (*tk_Ungrab) (Tk_Window tkwin); /* 180 */
    void (*tk_UnmaintainGeometry) (Tk_Window window, Tk_Window container); /* 181 */
    void (*tk_UnmapWindow) (Tk_Window tkwin); /* 182 */
    void (*tk_UnsetGrid) (Tk_Window tkwin); /* 183 */
    void (*tk_UpdatePointer) (Tk_Window tkwin, int x, int y, int state); /* 184 */
    Pixmap (*tk_AllocBitmapFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 185 */







|
<
|
<
<















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


















|







|



|
|



|



|
|
|

|

|

|
|
|



|




|
|


|
|





|

|

|
|











|


|



|


|












|
|









|

|







|





|

|















|

|
|


|

|







|
|
















|

|







833
834
835
836
837
838
839
840

841


842
843
844
845
846
847
848
849
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
				Tk_PhotoHandle handle, int width, int height);
/* 269 */
EXTERN long		Tk_GetUserInactiveTime(Display *dpy);
/* 270 */
EXTERN void		Tk_ResetUserInactiveTime(Display *dpy);
/* 271 */
EXTERN Tcl_Interp *	Tk_Interp(Tk_Window tkwin);
/* Slot 272 is reserved */

/* Slot 273 is reserved */


/* 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);
/* 281 */
EXTERN void		Tk_DrawHighlightBorder(Tk_Window tkwin, GC fgGC,
				GC bgGC, int highlightWidth,
				Drawable drawable);
/* 282 */
EXTERN void		Tk_SetMainMenubar(Tcl_Interp *interp,
				Tk_Window tkwin, const char *menuName);
/* 283 */
EXTERN void		Tk_SetWindowMenubar(Tcl_Interp *interp,
				Tk_Window tkwin, const char *oldMenuName,
				const char *menuName);
/* 284 */
EXTERN void		Tk_ClipDrawableToRect(Display *display, Drawable d,
				int x, int y, int width, int height);
/* 285 */
EXTERN Tcl_Obj *	Tk_GetSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);
/* 286 */
EXTERN int		Tk_UseWindow(Tcl_Interp *interp, Tk_Window tkwin,
				const char *string);
/* 287 */
EXTERN void		Tk_MakeContainer(Tk_Window tkwin);
/* 288 */
EXTERN Tk_Window	Tk_GetOtherWindow(Tk_Window tkwin);
/* 289 */
EXTERN void		Tk_Get3DBorderColors(Tk_3DBorder border,
				XColor *bgColorPtr, XColor *darkColorPtr,
				XColor *lightColorPtr);
/* 290 */
EXTERN Window		Tk_MakeWindow(Tk_Window tkwin, Window parent);

typedef struct {
    const struct TkPlatStubs *tkPlatStubs;
    const struct TkIntStubs *tkIntStubs;
    const struct TkIntPlatStubs *tkIntPlatStubs;
    const struct TkIntXlibStubs *tkIntXlibStubs;
} TkStubHooks;

typedef struct TkStubs {
    int magic;
    const TkStubHooks *hooks;

    void (*tk_MainLoop) (void); /* 0 */
    XColor * (*tk_3DBorderColor) (Tk_3DBorder border); /* 1 */
    GC (*tk_3DBorderGC) (Tk_Window tkwin, Tk_3DBorder border, int which); /* 2 */
    void (*tk_3DHorizontalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftIn, int rightIn, int topBevel, int relief); /* 3 */
    void (*tk_3DVerticalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftBevel, int relief); /* 4 */
    void (*tk_AddOption) (Tk_Window tkwin, const char *name, const char *value, int priority); /* 5 */
    void (*tk_BindEvent) (Tk_BindingTable bindingTable, XEvent *eventPtr, Tk_Window tkwin, Tcl_Size numObjects, void **objectPtr); /* 6 */
    void (*tk_CanvasDrawableCoords) (Tk_Canvas canvas, double x, double y, short *drawableXPtr, short *drawableYPtr); /* 7 */
    void (*tk_CanvasEventuallyRedraw) (Tk_Canvas canvas, int x1, int y1, int x2, int y2); /* 8 */
    int (*tk_CanvasGetCoord) (Tcl_Interp *interp, Tk_Canvas canvas, const char *str, double *doublePtr); /* 9 */
    Tk_CanvasTextInfo * (*tk_CanvasGetTextInfo) (Tk_Canvas canvas); /* 10 */
    int (*tk_CanvasPsBitmap) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap, int x, int y, int width, int height); /* 11 */
    int (*tk_CanvasPsColor) (Tcl_Interp *interp, Tk_Canvas canvas, XColor *colorPtr); /* 12 */
    int (*tk_CanvasPsFont) (Tcl_Interp *interp, Tk_Canvas canvas, Tk_Font font); /* 13 */
    void (*tk_CanvasPsPath) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, Tcl_Size numPoints); /* 14 */
    int (*tk_CanvasPsStipple) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); /* 15 */
    double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */
    void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */
    int (*tk_CanvasTagsParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 18 */
    const char * (*tk_CanvasTagsPrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 19 */
    Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */
    void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */
    void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */
    int (*tk_CharBbox) (Tk_TextLayout layout, Tcl_Size index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 23 */
    void (*tk_ClearSelection) (Tk_Window tkwin, Atom selection); /* 24 */
    int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, const char *buffer); /* 25 */
    int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */
    int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, void *widgRec, const char *argvName, int flags); /* 27 */
    int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, void *widgRec, const char *argvName, int flags); /* 28 */
    int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, Tcl_Size objc, Tcl_Obj *const *objv, void *widgRec, int flags); /* 29 */
    void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */
    Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, const char *str, Tcl_Size numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */
    Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */
    unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, void *object, const char *eventStr, const char *script, int append); /* 33 */
    Tk_BindingTable (*tk_CreateBindingTable) (Tcl_Interp *interp); /* 34 */
    Tk_ErrorHandler (*tk_CreateErrorHandler) (Display *display, int errNum, int request, int minorCode, Tk_ErrorProc *errorProc, void *clientData); /* 35 */
    void (*tk_CreateEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, void *clientData); /* 36 */
    void (*tk_CreateGenericHandler) (Tk_GenericProc *proc, void *clientData); /* 37 */
    void (*tk_CreateImageType) (const Tk_ImageType *typePtr); /* 38 */
    void (*tk_CreateItemType) (Tk_ItemType *typePtr); /* 39 */
    void (*tk_CreatePhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 40 */
    void (*tk_CreateSelHandler) (Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc *proc, void *clientData, Atom format); /* 41 */
    Tk_Window (*tk_CreateWindow) (Tcl_Interp *interp, Tk_Window parent, const char *name, const char *screenName); /* 42 */
    Tk_Window (*tk_CreateWindowFromPath) (Tcl_Interp *interp, Tk_Window tkwin, const char *pathName, const char *screenName); /* 43 */
    int (*tk_DefineBitmap) (Tcl_Interp *interp, const char *name, const void *source, int width, int height); /* 44 */
    void (*tk_DefineCursor) (Tk_Window window, Tk_Cursor cursor); /* 45 */
    void (*tk_DeleteAllBindings) (Tk_BindingTable bindingTable, void *object); /* 46 */
    int (*tk_DeleteBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, void *object, const char *eventStr); /* 47 */
    void (*tk_DeleteBindingTable) (Tk_BindingTable bindingTable); /* 48 */
    void (*tk_DeleteErrorHandler) (Tk_ErrorHandler handler); /* 49 */
    void (*tk_DeleteEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, void *clientData); /* 50 */
    void (*tk_DeleteGenericHandler) (Tk_GenericProc *proc, void *clientData); /* 51 */
    void (*tk_DeleteImage) (Tcl_Interp *interp, const char *name); /* 52 */
    void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */
    void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */
    const char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */
    int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */
    void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, Tcl_Size numPoints, int borderWidth, int leftRelief); /* 57 */
    void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */
    void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, Tcl_Size numBytes, int x, int y); /* 59 */
    void (*tk_DrawFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable); /* 60 */
    void (*tk_DrawTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, Tcl_Size firstChar, Tcl_Size lastChar); /* 61 */
    void (*tk_Fill3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, Tcl_Size numPoints, int borderWidth, int leftRelief); /* 62 */
    void (*tk_Fill3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 63 */
    Tk_PhotoHandle (*tk_FindPhoto) (Tcl_Interp *interp, const char *imageName); /* 64 */
    Font (*tk_FontId) (Tk_Font font); /* 65 */
    void (*tk_Free3DBorder) (Tk_3DBorder border); /* 66 */
    void (*tk_FreeBitmap) (Display *display, Pixmap bitmap); /* 67 */
    void (*tk_FreeColor) (XColor *colorPtr); /* 68 */
    void (*tk_FreeColormap) (Display *display, Colormap colormap); /* 69 */
    void (*tk_FreeCursor) (Display *display, Tk_Cursor cursor); /* 70 */
    void (*tk_FreeFont) (Tk_Font f); /* 71 */
    void (*tk_FreeGC) (Display *display, GC gc); /* 72 */
    void (*tk_FreeImage) (Tk_Image image); /* 73 */
    void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, void *widgRec, Display *display, int needFlags); /* 74 */
    void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */
    void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */
    void (*reserved77)(void);
    GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */
    void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */
    Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */
    void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, void *object); /* 81 */
    int (*tk_GetAnchor) (Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 82 */
    const char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
    const char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, void *object, const char *eventStr); /* 84 */
    Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 85 */
    Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, const void *source, int width, int height); /* 86 */
    int (*tk_GetCapStyle) (Tcl_Interp *interp, const char *str, int *capPtr); /* 87 */
    XColor * (*tk_GetColor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name); /* 88 */
    XColor * (*tk_GetColorByValue) (Tk_Window tkwin, XColor *colorPtr); /* 89 */
    Colormap (*tk_GetColormap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 90 */
    Tk_Cursor (*tk_GetCursor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid str); /* 91 */
    Tk_Cursor (*tk_GetCursorFromData) (Tcl_Interp *interp, Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); /* 92 */
    Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 93 */
    Tk_Font (*tk_GetFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 94 */
    void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */
    GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */
    Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, void *clientData); /* 97 */
    void * (*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, Tcl_Size 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, void *clientData); /* 110 */
    Tk_Uid (*tk_GetUid) (const char *str); /* 111 */
    Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */
    void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */
    int (*tk_Grab) (Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); /* 114 */
    void (*tk_HandleEvent) (XEvent *eventPtr); /* 115 */
    Tk_Window (*tk_IdToWindow) (Display *display, Window window); /* 116 */
    void (*tk_ImageChanged) (Tk_ImageModel model, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */
    void (*reserved118)(void);
    Atom (*tk_InternAtom) (Tk_Window tkwin, const char *name); /* 119 */
    int (*tk_IntersectTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height); /* 120 */
    void (*tk_MaintainGeometry) (Tk_Window window, Tk_Window container, int x, int y, int width, int height); /* 121 */
    Tk_Window (*tk_MainWindow) (Tcl_Interp *interp); /* 122 */
    void (*tk_MakeWindowExist) (Tk_Window tkwin); /* 123 */
    void (*tk_ManageGeometry) (Tk_Window tkwin, const Tk_GeomMgr *mgrPtr, void *clientData); /* 124 */
    void (*tk_MapWindow) (Tk_Window tkwin); /* 125 */
    int (*tk_MeasureChars) (Tk_Font tkfont, const char *source, Tcl_Size numBytes, int maxPixels, int flags, int *lengthPtr); /* 126 */
    void (*tk_MoveResizeWindow) (Tk_Window tkwin, int x, int y, int width, int height); /* 127 */
    void (*tk_MoveWindow) (Tk_Window tkwin, int x, int y); /* 128 */
    void (*tk_MoveToplevelWindow) (Tk_Window tkwin, int x, int y); /* 129 */
    const char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
    const char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
    const char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
    const char * (*tk_NameOfCapStyle) (int cap); /* 133 */
    const char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
    const char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
    const char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
    const char * (*tk_NameOfImage) (Tk_ImageModel model); /* 137 */
    const char * (*tk_NameOfJoinStyle) (int join); /* 138 */
    const char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
    const char * (*tk_NameOfRelief) (int relief); /* 140 */
    Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */
    void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, void *clientData); /* 142 */
    int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
    void (*reserved144)(void);
    void (*reserved145)(void);
    int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */
    void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */
    void (*reserved148)(void);
    void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */
    void (*reserved150)(void);
    int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */
    int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */
    void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */
    void (*tk_QueueWindowEvent) (XEvent *eventPtr, Tcl_QueuePosition position); /* 154 */
    void (*tk_RedrawImage) (Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY); /* 155 */
    void (*tk_ResizeWindow) (Tk_Window tkwin, int width, int height); /* 156 */
    int (*tk_RestackWindow) (Tk_Window tkwin, int aboveBelow, Tk_Window other); /* 157 */
    Tk_RestrictProc * (*tk_RestrictEvents) (Tk_RestrictProc *proc, void *arg, void **prevArgPtr); /* 158 */
    void (*reserved159)(void);
    const char * (*tk_SetAppName) (Tk_Window tkwin, const char *name); /* 160 */
    void (*tk_SetBackgroundFromBorder) (Tk_Window tkwin, Tk_3DBorder border); /* 161 */
    void (*tk_SetClass) (Tk_Window tkwin, const char *className); /* 162 */
    void (*tk_SetGrid) (Tk_Window tkwin, int reqWidth, int reqHeight, int gridWidth, int gridHeight); /* 163 */
    void (*tk_SetInternalBorder) (Tk_Window tkwin, int width); /* 164 */
    void (*tk_SetWindowBackground) (Tk_Window tkwin, unsigned long pixel); /* 165 */
    void (*tk_SetWindowBackgroundPixmap) (Tk_Window tkwin, Pixmap pixmap); /* 166 */
    void (*tk_SetWindowBorder) (Tk_Window tkwin, unsigned long pixel); /* 167 */
    void (*tk_SetWindowBorderWidth) (Tk_Window tkwin, int width); /* 168 */
    void (*tk_SetWindowBorderPixmap) (Tk_Window tkwin, Pixmap pixmap); /* 169 */
    void (*tk_SetWindowColormap) (Tk_Window tkwin, Colormap colormap); /* 170 */
    int (*tk_SetWindowVisual) (Tk_Window tkwin, Visual *visual, int depth, Colormap colormap); /* 171 */
    void (*tk_SizeOfBitmap) (Display *display, Pixmap bitmap, int *widthPtr, int *heightPtr); /* 172 */
    void (*tk_SizeOfImage) (Tk_Image image, int *widthPtr, int *heightPtr); /* 173 */
    int (*tk_StrictMotif) (Tk_Window tkwin); /* 174 */
    void (*tk_TextLayoutToPostscript) (Tcl_Interp *interp, Tk_TextLayout layout); /* 175 */
    int (*tk_TextWidth) (Tk_Font font, const char *str, Tcl_Size 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, Tcl_Size firstByte, Tcl_Size lastByte); /* 178 */
    void (*tk_UnderlineTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); /* 179 */
    void (*tk_Ungrab) (Tk_Window tkwin); /* 180 */
    void (*tk_UnmaintainGeometry) (Tk_Window window, Tk_Window container); /* 181 */
    void (*tk_UnmapWindow) (Tk_Window tkwin); /* 182 */
    void (*tk_UnsetGrid) (Tk_Window tkwin); /* 183 */
    void (*tk_UpdatePointer) (Tk_Window tkwin, int x, int y, int state); /* 184 */
    Pixmap (*tk_AllocBitmapFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 185 */
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
    Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */
    Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
    int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
    int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
    int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
    int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
    int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
    int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
    void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
    int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
    void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
    int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
    void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);
    int (*tk_GetDash) (Tcl_Interp *interp, const char *value, Tk_Dash *dash); /* 220 */
    void (*tk_CreateOutline) (Tk_Outline *outline); /* 221 */
    void (*tk_DeleteOutline) (Display *display, Tk_Outline *outline); /* 222 */
    int (*tk_ConfigOutlineGC) (XGCValues *gcValues, Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 223 */
    int (*tk_ChangeOutlineGC) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 224 */
    int (*tk_ResetOutlineGC) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 225 */
    int (*tk_CanvasPsOutline) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 226 */
    void (*tk_SetTSOrigin) (Tk_Window tkwin, GC gc, int x, int y); /* 227 */
    int (*tk_CanvasGetCoordFromObj) (Tcl_Interp *interp, Tk_Canvas canvas, Tcl_Obj *obj, double *doublePtr); /* 228 */
    void (*tk_CanvasSetOffset) (Tk_Canvas canvas, GC gc, Tk_TSOffset *offset); /* 229 */
    void (*tk_DitherPhoto) (Tk_PhotoHandle handle, int x, int y, int width, int height); /* 230 */
    int (*tk_PostscriptBitmap) (Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap, int startX, int startY, int width, int height); /* 231 */
    int (*tk_PostscriptColor) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, XColor *colorPtr); /* 232 */
    int (*tk_PostscriptFont) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, Tk_Font font); /* 233 */
    int (*tk_PostscriptImage) (Tk_Image image, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y, int width, int height, int prepass); /* 234 */
    void (*tk_PostscriptPath) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, double *coordPtr, int numPoints); /* 235 */
    int (*tk_PostscriptStipple) (Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap); /* 236 */
    double (*tk_PostscriptY) (double y, Tk_PostscriptInfo psInfo); /* 237 */
    int (*tk_PostscriptPhoto) (Tcl_Interp *interp, Tk_PhotoImageBlock *blockPtr, Tk_PostscriptInfo psInfo, int width, int height); /* 238 */
    void (*tk_CreateClientMessageHandler) (Tk_ClientMessageProc *proc); /* 239 */
    void (*tk_DeleteClientMessageHandler) (Tk_ClientMessageProc *proc); /* 240 */
    Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, const char *screenName); /* 241 */
    void (*tk_SetClassProcs) (Tk_Window tkwin, const Tk_ClassProcs *procs, ClientData instanceData); /* 242 */
    void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */
    void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */
    void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */
    int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */
    Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */
    Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */
    int (*tk_RegisterStyledElement) (Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); /* 251 */
    int (*tk_GetElementId) (const char *name); /* 252 */
    Tk_Style (*tk_CreateStyle) (const char *name, Tk_StyleEngine engine, ClientData clientData); /* 253 */
    Tk_Style (*tk_GetStyle) (Tcl_Interp *interp, const char *name); /* 254 */
    void (*tk_FreeStyle) (Tk_Style style); /* 255 */
    const char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */
    Tk_Style (*tk_AllocStyleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 257 */
    Tk_Style (*tk_GetStyleFromObj) (Tcl_Obj *objPtr); /* 258 */
    void (*tk_FreeStyleFromObj) (Tcl_Obj *objPtr); /* 259 */
    Tk_StyledElement (*tk_GetStyledElement) (Tk_Style style, int elementId, Tk_OptionTable optionTable); /* 260 */
    void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
    void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */
    int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin); /* 263 */
    void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */
    int (*tk_PhotoExpand) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 265 */
    int (*tk_PhotoPutBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 266 */
    int (*tk_PhotoPutZoomedBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 267 */
    int (*tk_PhotoSetSize) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 268 */
    long (*tk_GetUserInactiveTime) (Display *dpy); /* 269 */
    void (*tk_ResetUserInactiveTime) (Display *dpy); /* 270 */
    Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */
    void (*tk_CreateOldImageType) (const Tk_ImageType *typePtr); /* 272 */
    void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 273 */
    int (*tk_AlwaysShowSelection) (Tk_Window tkwin); /* 274 */
    unsigned (*tk_GetButtonMask) (unsigned button); /* 275 */
    int (*tk_GetDoublePixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 276 */
    Tcl_Obj * (*tk_NewWindowObj) (Tk_Window tkwin); /* 277 */
    void (*tk_SendVirtualEvent) (Tk_Window tkwin, const char *eventName, Tcl_Obj *detail); /* 278 */
    Tcl_Obj * (*tk_FontGetDescription) (Tk_Font tkfont); /* 279 */











} TkStubs;

extern const TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif







|

|

|

|


















|






|



|
|





|




|
|
|











|
|






>
>
>
>
>
>
>
>
>
>
>







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
    Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */
    Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
    int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
    int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
    int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
    int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
    int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
    int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    void (*reserved212)(void);
    void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
    int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Size objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
    void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
    void (*reserved216)(void);
    void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);
    int (*tk_GetDash) (Tcl_Interp *interp, const char *value, Tk_Dash *dash); /* 220 */
    void (*tk_CreateOutline) (Tk_Outline *outline); /* 221 */
    void (*tk_DeleteOutline) (Display *display, Tk_Outline *outline); /* 222 */
    int (*tk_ConfigOutlineGC) (XGCValues *gcValues, Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 223 */
    int (*tk_ChangeOutlineGC) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 224 */
    int (*tk_ResetOutlineGC) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 225 */
    int (*tk_CanvasPsOutline) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 226 */
    void (*tk_SetTSOrigin) (Tk_Window tkwin, GC gc, int x, int y); /* 227 */
    int (*tk_CanvasGetCoordFromObj) (Tcl_Interp *interp, Tk_Canvas canvas, Tcl_Obj *obj, double *doublePtr); /* 228 */
    void (*tk_CanvasSetOffset) (Tk_Canvas canvas, GC gc, Tk_TSOffset *offset); /* 229 */
    void (*tk_DitherPhoto) (Tk_PhotoHandle handle, int x, int y, int width, int height); /* 230 */
    int (*tk_PostscriptBitmap) (Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap, int startX, int startY, int width, int height); /* 231 */
    int (*tk_PostscriptColor) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, XColor *colorPtr); /* 232 */
    int (*tk_PostscriptFont) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, Tk_Font font); /* 233 */
    int (*tk_PostscriptImage) (Tk_Image image, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y, int width, int height, int prepass); /* 234 */
    void (*tk_PostscriptPath) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, double *coordPtr, Tcl_Size numPoints); /* 235 */
    int (*tk_PostscriptStipple) (Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap); /* 236 */
    double (*tk_PostscriptY) (double y, Tk_PostscriptInfo psInfo); /* 237 */
    int (*tk_PostscriptPhoto) (Tcl_Interp *interp, Tk_PhotoImageBlock *blockPtr, Tk_PostscriptInfo psInfo, int width, int height); /* 238 */
    void (*tk_CreateClientMessageHandler) (Tk_ClientMessageProc *proc); /* 239 */
    void (*tk_DeleteClientMessageHandler) (Tk_ClientMessageProc *proc); /* 240 */
    Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, const char *screenName); /* 241 */
    void (*tk_SetClassProcs) (Tk_Window tkwin, const Tk_ClassProcs *procs, void *instanceData); /* 242 */
    void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */
    void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */
    void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */
    void (*reserved246)(void);
    void (*reserved247)(void);
    int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */
    Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */
    Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */
    int (*tk_RegisterStyledElement) (Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); /* 251 */
    int (*tk_GetElementId) (const char *name); /* 252 */
    Tk_Style (*tk_CreateStyle) (const char *name, Tk_StyleEngine engine, void *clientData); /* 253 */
    Tk_Style (*tk_GetStyle) (Tcl_Interp *interp, const char *name); /* 254 */
    void (*tk_FreeStyle) (Tk_Style style); /* 255 */
    const char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */
    Tk_Style (*tk_AllocStyleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 257 */
    void (*reserved258)(void);
    void (*reserved259)(void);
    Tk_StyledElement (*tk_GetStyledElement) (Tk_Style style, Tcl_Size elementId, Tk_OptionTable optionTable); /* 260 */
    void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
    void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */
    int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin); /* 263 */
    void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */
    int (*tk_PhotoExpand) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 265 */
    int (*tk_PhotoPutBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 266 */
    int (*tk_PhotoPutZoomedBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 267 */
    int (*tk_PhotoSetSize) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 268 */
    long (*tk_GetUserInactiveTime) (Display *dpy); /* 269 */
    void (*tk_ResetUserInactiveTime) (Display *dpy); /* 270 */
    Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */
    void (*reserved272)(void);
    void (*reserved273)(void);
    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); /* 280 */
    void (*tk_DrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 281 */
    void (*tk_SetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, const char *menuName); /* 282 */
    void (*tk_SetWindowMenubar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 283 */
    void (*tk_ClipDrawableToRect) (Display *display, Drawable d, int x, int y, int width, int height); /* 284 */
    Tcl_Obj * (*tk_GetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 285 */
    int (*tk_UseWindow) (Tcl_Interp *interp, Tk_Window tkwin, const char *string); /* 286 */
    void (*tk_MakeContainer) (Tk_Window tkwin); /* 287 */
    Tk_Window (*tk_GetOtherWindow) (Tk_Window tkwin); /* 288 */
    void (*tk_Get3DBorderColors) (Tk_3DBorder border, XColor *bgColorPtr, XColor *darkColorPtr, XColor *lightColorPtr); /* 289 */
    Window (*tk_MakeWindow) (Tk_Window tkwin, Window parent); /* 290 */
} TkStubs;

extern const TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
	(tkStubsPtr->tk_FreeImage) /* 73 */
#define Tk_FreeOptions \
	(tkStubsPtr->tk_FreeOptions) /* 74 */
#define Tk_FreePixmap \
	(tkStubsPtr->tk_FreePixmap) /* 75 */
#define Tk_FreeTextLayout \
	(tkStubsPtr->tk_FreeTextLayout) /* 76 */
#define Tk_FreeXId \
	(tkStubsPtr->tk_FreeXId) /* 77 */
#define Tk_GCForColor \
	(tkStubsPtr->tk_GCForColor) /* 78 */
#define Tk_GeometryRequest \
	(tkStubsPtr->tk_GeometryRequest) /* 79 */
#define Tk_Get3DBorder \
	(tkStubsPtr->tk_Get3DBorder) /* 80 */
#define Tk_GetAllBindings \







<
|







1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1368
	(tkStubsPtr->tk_FreeImage) /* 73 */
#define Tk_FreeOptions \
	(tkStubsPtr->tk_FreeOptions) /* 74 */
#define Tk_FreePixmap \
	(tkStubsPtr->tk_FreePixmap) /* 75 */
#define Tk_FreeTextLayout \
	(tkStubsPtr->tk_FreeTextLayout) /* 76 */

/* Slot 77 is reserved */
#define Tk_GCForColor \
	(tkStubsPtr->tk_GCForColor) /* 78 */
#define Tk_GeometryRequest \
	(tkStubsPtr->tk_GeometryRequest) /* 79 */
#define Tk_Get3DBorder \
	(tkStubsPtr->tk_Get3DBorder) /* 80 */
#define Tk_GetAllBindings \
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
	(tkStubsPtr->tk_Grab) /* 114 */
#define Tk_HandleEvent \
	(tkStubsPtr->tk_HandleEvent) /* 115 */
#define Tk_IdToWindow \
	(tkStubsPtr->tk_IdToWindow) /* 116 */
#define Tk_ImageChanged \
	(tkStubsPtr->tk_ImageChanged) /* 117 */
#define Tk_Init \
	(tkStubsPtr->tk_Init) /* 118 */
#define Tk_InternAtom \
	(tkStubsPtr->tk_InternAtom) /* 119 */
#define Tk_IntersectTextLayout \
	(tkStubsPtr->tk_IntersectTextLayout) /* 120 */
#define Tk_MaintainGeometry \
	(tkStubsPtr->tk_MaintainGeometry) /* 121 */
#define Tk_MainWindow \







<
|







1435
1436
1437
1438
1439
1440
1441

1442
1443
1444
1445
1446
1447
1448
1449
	(tkStubsPtr->tk_Grab) /* 114 */
#define Tk_HandleEvent \
	(tkStubsPtr->tk_HandleEvent) /* 115 */
#define Tk_IdToWindow \
	(tkStubsPtr->tk_IdToWindow) /* 116 */
#define Tk_ImageChanged \
	(tkStubsPtr->tk_ImageChanged) /* 117 */

/* Slot 118 is reserved */
#define Tk_InternAtom \
	(tkStubsPtr->tk_InternAtom) /* 119 */
#define Tk_IntersectTextLayout \
	(tkStubsPtr->tk_IntersectTextLayout) /* 120 */
#define Tk_MaintainGeometry \
	(tkStubsPtr->tk_MaintainGeometry) /* 121 */
#define Tk_MainWindow \
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
	(tkStubsPtr->tk_NameOfRelief) /* 140 */
#define Tk_NameToWindow \
	(tkStubsPtr->tk_NameToWindow) /* 141 */
#define Tk_OwnSelection \
	(tkStubsPtr->tk_OwnSelection) /* 142 */
#define Tk_ParseArgv \
	(tkStubsPtr->tk_ParseArgv) /* 143 */
#define Tk_PhotoPutBlock_NoComposite \
	(tkStubsPtr->tk_PhotoPutBlock_NoComposite) /* 144 */
#define Tk_PhotoPutZoomedBlock_NoComposite \
	(tkStubsPtr->tk_PhotoPutZoomedBlock_NoComposite) /* 145 */
#define Tk_PhotoGetImage \
	(tkStubsPtr->tk_PhotoGetImage) /* 146 */
#define Tk_PhotoBlank \
	(tkStubsPtr->tk_PhotoBlank) /* 147 */
#define Tk_PhotoExpand_Panic \
	(tkStubsPtr->tk_PhotoExpand_Panic) /* 148 */
#define Tk_PhotoGetSize \
	(tkStubsPtr->tk_PhotoGetSize) /* 149 */
#define Tk_PhotoSetSize_Panic \
	(tkStubsPtr->tk_PhotoSetSize_Panic) /* 150 */
#define Tk_PointToChar \
	(tkStubsPtr->tk_PointToChar) /* 151 */
#define Tk_PostscriptFontName \
	(tkStubsPtr->tk_PostscriptFontName) /* 152 */
#define Tk_PreserveColormap \
	(tkStubsPtr->tk_PreserveColormap) /* 153 */
#define Tk_QueueWindowEvent \
	(tkStubsPtr->tk_QueueWindowEvent) /* 154 */
#define Tk_RedrawImage \
	(tkStubsPtr->tk_RedrawImage) /* 155 */
#define Tk_ResizeWindow \
	(tkStubsPtr->tk_ResizeWindow) /* 156 */
#define Tk_RestackWindow \
	(tkStubsPtr->tk_RestackWindow) /* 157 */
#define Tk_RestrictEvents \
	(tkStubsPtr->tk_RestrictEvents) /* 158 */
#define Tk_SafeInit \
	(tkStubsPtr->tk_SafeInit) /* 159 */
#define Tk_SetAppName \
	(tkStubsPtr->tk_SetAppName) /* 160 */
#define Tk_SetBackgroundFromBorder \
	(tkStubsPtr->tk_SetBackgroundFromBorder) /* 161 */
#define Tk_SetClass \
	(tkStubsPtr->tk_SetClass) /* 162 */
#define Tk_SetGrid \







<
|
<
|




<
|


<
|
















<
|







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
	(tkStubsPtr->tk_NameOfRelief) /* 140 */
#define Tk_NameToWindow \
	(tkStubsPtr->tk_NameToWindow) /* 141 */
#define Tk_OwnSelection \
	(tkStubsPtr->tk_OwnSelection) /* 142 */
#define Tk_ParseArgv \
	(tkStubsPtr->tk_ParseArgv) /* 143 */

/* Slot 144 is reserved */

/* Slot 145 is reserved */
#define Tk_PhotoGetImage \
	(tkStubsPtr->tk_PhotoGetImage) /* 146 */
#define Tk_PhotoBlank \
	(tkStubsPtr->tk_PhotoBlank) /* 147 */

/* Slot 148 is reserved */
#define Tk_PhotoGetSize \
	(tkStubsPtr->tk_PhotoGetSize) /* 149 */

/* Slot 150 is reserved */
#define Tk_PointToChar \
	(tkStubsPtr->tk_PointToChar) /* 151 */
#define Tk_PostscriptFontName \
	(tkStubsPtr->tk_PostscriptFontName) /* 152 */
#define Tk_PreserveColormap \
	(tkStubsPtr->tk_PreserveColormap) /* 153 */
#define Tk_QueueWindowEvent \
	(tkStubsPtr->tk_QueueWindowEvent) /* 154 */
#define Tk_RedrawImage \
	(tkStubsPtr->tk_RedrawImage) /* 155 */
#define Tk_ResizeWindow \
	(tkStubsPtr->tk_ResizeWindow) /* 156 */
#define Tk_RestackWindow \
	(tkStubsPtr->tk_RestackWindow) /* 157 */
#define Tk_RestrictEvents \
	(tkStubsPtr->tk_RestrictEvents) /* 158 */

/* Slot 159 is reserved */
#define Tk_SetAppName \
	(tkStubsPtr->tk_SetAppName) /* 160 */
#define Tk_SetBackgroundFromBorder \
	(tkStubsPtr->tk_SetBackgroundFromBorder) /* 161 */
#define Tk_SetClass \
	(tkStubsPtr->tk_SetClass) /* 162 */
#define Tk_SetGrid \
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
	(tkStubsPtr->tk_GetPixelsFromObj) /* 208 */
#define Tk_GetReliefFromObj \
	(tkStubsPtr->tk_GetReliefFromObj) /* 209 */
#define Tk_GetScrollInfoObj \
	(tkStubsPtr->tk_GetScrollInfoObj) /* 210 */
#define Tk_InitOptions \
	(tkStubsPtr->tk_InitOptions) /* 211 */
#define Tk_MainEx \
	(tkStubsPtr->tk_MainEx) /* 212 */
#define Tk_RestoreSavedOptions \
	(tkStubsPtr->tk_RestoreSavedOptions) /* 213 */
#define Tk_SetOptions \
	(tkStubsPtr->tk_SetOptions) /* 214 */
#define Tk_InitConsoleChannels \
	(tkStubsPtr->tk_InitConsoleChannels) /* 215 */
#define Tk_CreateConsoleWindow \
	(tkStubsPtr->tk_CreateConsoleWindow) /* 216 */
#define Tk_CreateSmoothMethod \
	(tkStubsPtr->tk_CreateSmoothMethod) /* 217 */
/* Slot 218 is reserved */
/* Slot 219 is reserved */
#define Tk_GetDash \
	(tkStubsPtr->tk_GetDash) /* 220 */
#define Tk_CreateOutline \







<
|






<
|







1617
1618
1619
1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630

1631
1632
1633
1634
1635
1636
1637
1638
	(tkStubsPtr->tk_GetPixelsFromObj) /* 208 */
#define Tk_GetReliefFromObj \
	(tkStubsPtr->tk_GetReliefFromObj) /* 209 */
#define Tk_GetScrollInfoObj \
	(tkStubsPtr->tk_GetScrollInfoObj) /* 210 */
#define Tk_InitOptions \
	(tkStubsPtr->tk_InitOptions) /* 211 */

/* Slot 212 is reserved */
#define Tk_RestoreSavedOptions \
	(tkStubsPtr->tk_RestoreSavedOptions) /* 213 */
#define Tk_SetOptions \
	(tkStubsPtr->tk_SetOptions) /* 214 */
#define Tk_InitConsoleChannels \
	(tkStubsPtr->tk_InitConsoleChannels) /* 215 */

/* Slot 216 is reserved */
#define Tk_CreateSmoothMethod \
	(tkStubsPtr->tk_CreateSmoothMethod) /* 217 */
/* Slot 218 is reserved */
/* Slot 219 is reserved */
#define Tk_GetDash \
	(tkStubsPtr->tk_GetDash) /* 220 */
#define Tk_CreateOutline \
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
	(tkStubsPtr->tk_SetClassProcs) /* 242 */
#define Tk_SetInternalBorderEx \
	(tkStubsPtr->tk_SetInternalBorderEx) /* 243 */
#define Tk_SetMinimumRequestSize \
	(tkStubsPtr->tk_SetMinimumRequestSize) /* 244 */
#define Tk_SetCaretPos \
	(tkStubsPtr->tk_SetCaretPos) /* 245 */
#define Tk_PhotoPutBlock_Panic \
	(tkStubsPtr->tk_PhotoPutBlock_Panic) /* 246 */
#define Tk_PhotoPutZoomedBlock_Panic \
	(tkStubsPtr->tk_PhotoPutZoomedBlock_Panic) /* 247 */
#define Tk_CollapseMotionEvents \
	(tkStubsPtr->tk_CollapseMotionEvents) /* 248 */
#define Tk_RegisterStyleEngine \
	(tkStubsPtr->tk_RegisterStyleEngine) /* 249 */
#define Tk_GetStyleEngine \
	(tkStubsPtr->tk_GetStyleEngine) /* 250 */
#define Tk_RegisterStyledElement \
	(tkStubsPtr->tk_RegisterStyledElement) /* 251 */
#define Tk_GetElementId \
	(tkStubsPtr->tk_GetElementId) /* 252 */
#define Tk_CreateStyle \
	(tkStubsPtr->tk_CreateStyle) /* 253 */
#define Tk_GetStyle \
	(tkStubsPtr->tk_GetStyle) /* 254 */
#define Tk_FreeStyle \
	(tkStubsPtr->tk_FreeStyle) /* 255 */
#define Tk_NameOfStyle \
	(tkStubsPtr->tk_NameOfStyle) /* 256 */
#define Tk_AllocStyleFromObj \
	(tkStubsPtr->tk_AllocStyleFromObj) /* 257 */
#define Tk_GetStyleFromObj \
	(tkStubsPtr->tk_GetStyleFromObj) /* 258 */
#define Tk_FreeStyleFromObj \
	(tkStubsPtr->tk_FreeStyleFromObj) /* 259 */
#define Tk_GetStyledElement \
	(tkStubsPtr->tk_GetStyledElement) /* 260 */
#define Tk_GetElementSize \
	(tkStubsPtr->tk_GetElementSize) /* 261 */
#define Tk_GetElementBox \
	(tkStubsPtr->tk_GetElementBox) /* 262 */
#define Tk_GetElementBorderWidth \







<
|
<
|




















<
|
<
|







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
	(tkStubsPtr->tk_SetClassProcs) /* 242 */
#define Tk_SetInternalBorderEx \
	(tkStubsPtr->tk_SetInternalBorderEx) /* 243 */
#define Tk_SetMinimumRequestSize \
	(tkStubsPtr->tk_SetMinimumRequestSize) /* 244 */
#define Tk_SetCaretPos \
	(tkStubsPtr->tk_SetCaretPos) /* 245 */

/* Slot 246 is reserved */

/* Slot 247 is reserved */
#define Tk_CollapseMotionEvents \
	(tkStubsPtr->tk_CollapseMotionEvents) /* 248 */
#define Tk_RegisterStyleEngine \
	(tkStubsPtr->tk_RegisterStyleEngine) /* 249 */
#define Tk_GetStyleEngine \
	(tkStubsPtr->tk_GetStyleEngine) /* 250 */
#define Tk_RegisterStyledElement \
	(tkStubsPtr->tk_RegisterStyledElement) /* 251 */
#define Tk_GetElementId \
	(tkStubsPtr->tk_GetElementId) /* 252 */
#define Tk_CreateStyle \
	(tkStubsPtr->tk_CreateStyle) /* 253 */
#define Tk_GetStyle \
	(tkStubsPtr->tk_GetStyle) /* 254 */
#define Tk_FreeStyle \
	(tkStubsPtr->tk_FreeStyle) /* 255 */
#define Tk_NameOfStyle \
	(tkStubsPtr->tk_NameOfStyle) /* 256 */
#define Tk_AllocStyleFromObj \
	(tkStubsPtr->tk_AllocStyleFromObj) /* 257 */

/* Slot 258 is reserved */

/* Slot 259 is reserved */
#define Tk_GetStyledElement \
	(tkStubsPtr->tk_GetStyledElement) /* 260 */
#define Tk_GetElementSize \
	(tkStubsPtr->tk_GetElementSize) /* 261 */
#define Tk_GetElementBox \
	(tkStubsPtr->tk_GetElementBox) /* 262 */
#define Tk_GetElementBorderWidth \
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
	(tkStubsPtr->tk_PhotoSetSize) /* 268 */
#define Tk_GetUserInactiveTime \
	(tkStubsPtr->tk_GetUserInactiveTime) /* 269 */
#define Tk_ResetUserInactiveTime \
	(tkStubsPtr->tk_ResetUserInactiveTime) /* 270 */
#define Tk_Interp \
	(tkStubsPtr->tk_Interp) /* 271 */
#define Tk_CreateOldImageType \
	(tkStubsPtr->tk_CreateOldImageType) /* 272 */
#define Tk_CreateOldPhotoImageFormat \
	(tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */
#define Tk_AlwaysShowSelection \
	(tkStubsPtr->tk_AlwaysShowSelection) /* 274 */
#define Tk_GetButtonMask \
	(tkStubsPtr->tk_GetButtonMask) /* 275 */
#define Tk_GetDoublePixelsFromObj \
	(tkStubsPtr->tk_GetDoublePixelsFromObj) /* 276 */
#define Tk_NewWindowObj \
	(tkStubsPtr->tk_NewWindowObj) /* 277 */
#define Tk_SendVirtualEvent \
	(tkStubsPtr->tk_SendVirtualEvent) /* 278 */
#define Tk_FontGetDescription \
	(tkStubsPtr->tk_FontGetDescription) /* 279 */























#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

/* Functions that don't belong in the stub table */
#undef Tk_MainEx
#undef Tk_Init
#undef Tk_SafeInit
#undef Tk_CreateConsoleWindow

#undef Tk_FreeXId
#define Tk_FreeXId(display,xid)
#undef Tk_GetStyleFromObj
#undef Tk_FreeStyleFromObj
#define Tk_GetStyleFromObj(obj) Tk_AllocStyleFromObj(NULL, obj)
#define Tk_FreeStyleFromObj(obj) /* no-op */
#define Tk_GetImageMasterData Tk_GetImageModelData



#if defined(_WIN32) && defined(UNICODE)
#   define Tk_MainEx Tk_MainExW
    EXTERN void Tk_MainExW(int argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif




#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8

#undef Tk_PhotoPutBlock_NoComposite



#undef Tk_PhotoPutZoomedBlock_NoComposite
#undef Tk_PhotoExpand_Panic
#undef Tk_PhotoPutBlock_Panic
#undef Tk_PhotoPutZoomedBlock_Panic
#undef Tk_PhotoSetSize_Panic
#undef Tk_CreateOldPhotoImageFormat
#endif /* TK_NO_DEPRECATED */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* _TKDECLS */







<
|
<
|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
|
<
<
<

|
<
|
|
<
<
<

>
>


|


|
>
>

|
>
|
>
>
>
|
|
<
<
<
<
|





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
	(tkStubsPtr->tk_PhotoSetSize) /* 268 */
#define Tk_GetUserInactiveTime \
	(tkStubsPtr->tk_GetUserInactiveTime) /* 269 */
#define Tk_ResetUserInactiveTime \
	(tkStubsPtr->tk_ResetUserInactiveTime) /* 270 */
#define Tk_Interp \
	(tkStubsPtr->tk_Interp) /* 271 */

/* Slot 272 is reserved */

/* Slot 273 is reserved */
#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) /* 280 */
#define Tk_DrawHighlightBorder \
	(tkStubsPtr->tk_DrawHighlightBorder) /* 281 */
#define Tk_SetMainMenubar \
	(tkStubsPtr->tk_SetMainMenubar) /* 282 */
#define Tk_SetWindowMenubar \
	(tkStubsPtr->tk_SetWindowMenubar) /* 283 */
#define Tk_ClipDrawableToRect \
	(tkStubsPtr->tk_ClipDrawableToRect) /* 284 */
#define Tk_GetSystemDefault \
	(tkStubsPtr->tk_GetSystemDefault) /* 285 */
#define Tk_UseWindow \
	(tkStubsPtr->tk_UseWindow) /* 286 */
#define Tk_MakeContainer \
	(tkStubsPtr->tk_MakeContainer) /* 287 */
#define Tk_GetOtherWindow \
	(tkStubsPtr->tk_GetOtherWindow) /* 288 */
#define Tk_Get3DBorderColors \
	(tkStubsPtr->tk_Get3DBorderColors) /* 289 */
#define Tk_MakeWindow \
	(tkStubsPtr->tk_MakeWindow) /* 290 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */


#define Tk_GetImageMasterData Tk_GetImageModelData




#ifndef MAC_OSX_TK

#   undef Tk_ClipDrawableToRect
#endif




EXTERN void  Tk_MainEx(Tcl_Size argc, char **argv,
	Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#if defined(_WIN32) && defined(UNICODE)
#   define Tk_MainEx Tk_MainExW
    EXTERN void Tk_MainExW(Tcl_Size argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif
EXTERN int Tk_Init(Tcl_Interp *interp);
EXTERN int Tk_SafeInit(Tcl_Interp *interp);
EXTERN int Tk_CreateConsoleWindow(Tcl_Interp *interp);

#if TK_MAJOR_VERSION < 9
/* Restore 8.x signature of Tk_ConfigureWidget, but panic if TK_CONFIG_OBJS flag is not set */
#undef Tk_ConfigureWidget
#define Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) \
	((int (*)(Tcl_Interp *, Tk_Window, const Tk_ConfigSpec *, \
	int, const char **, char *, int))(void *)(tkStubsPtr->tk_ConfigureWidget)) \
	(((flags & TK_CONFIG_OBJS) ? interp : (Tcl_Panic("Flag TK_CONFIG_OBJS is mandatory in Tk_ConfigureWidget"), \
	NULL)), tkwin, specs, argc, argv, widgRec, flags)




#endif

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#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
20




21
22
23
24
25
26
27
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkEntry.h"
#include "default.h"





/*
 * The following macro defines how many extra pixels to leave on each side of
 * the text in the entry.
 */

#define XPAD 1








|
|
|
|








>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
 * 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 © 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"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following macro defines how many extra pixels to leave on each side of
 * the text in the entry.
 */

#define XPAD 1
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, TCL_INDEX_NONE,







|













|




|
|



|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
	"PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
	offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, TCL_INDEX_NONE,
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 */

#define DEF_SPINBOX_REPEAT_DELAY	"400"
#define DEF_SPINBOX_REPEAT_INTERVAL	"100"

#define DEF_SPINBOX_CMD			""

#define DEF_SPINBOX_FROM		"0"
#define DEF_SPINBOX_TO			"0"
#define DEF_SPINBOX_INCREMENT		"1"
#define DEF_SPINBOX_FORMAT		""

#define DEF_SPINBOX_VALUES		""
#define DEF_SPINBOX_WRAP		"0"

static const Tk_OptionSpec sbOptSpec[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",







|
|
|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
 */

#define DEF_SPINBOX_REPEAT_DELAY	"400"
#define DEF_SPINBOX_REPEAT_INTERVAL	"100"

#define DEF_SPINBOX_CMD			""

#define DEF_SPINBOX_FROM		"0.0"
#define DEF_SPINBOX_TO			"0.0"
#define DEF_SPINBOX_INCREMENT		"1.0"
#define DEF_SPINBOX_FORMAT		""

#define DEF_SPINBOX_VALUES		""
#define DEF_SPINBOX_WRAP		"0"

static const Tk_OptionSpec sbOptSpec[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,







|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	DEF_SPINBOX_INCREMENT, TCL_INDEX_NONE, offsetof(Spinbox, increment), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SPINBOX_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(Spinbox, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SPINBOX_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(Spinbox, repeatInterval),
	0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",







|













|











|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	DEF_SPINBOX_INCREMENT, TCL_INDEX_NONE, offsetof(Spinbox, increment), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SPINBOX_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(Spinbox, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SPINBOX_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(Spinbox, repeatInterval),
	0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

/*
 * This is the string array corresponding to the enum in selelement. If you
 * modify them, you must modify the strings here.
 */

static const char *const selElementNames[] = {
    "none", "buttondown", "buttonup", NULL, "entry"
};

/*
 * Flags for GetEntryIndex function:
 */

#define ZERO_OK			1
#define LAST_PLUS_ONE_OK	2

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		DeleteChars(Entry *entryPtr, TkSizeT index, TkSizeT count);
static void		DestroyEntry(void *memPtr);
static void		DisplayEntry(ClientData clientData);
static void		EntryBlinkProc(ClientData clientData);
static void		EntryCmdDeletedProc(ClientData clientData);
static void		EntryComputeGeometry(Entry *entryPtr);
static void		EntryEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		EntryFocusProc(Entry *entryPtr, int gotFocus);
static TkSizeT	EntryFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT maxBytes);
static void		EntryLostSelection(ClientData clientData);
static void		EventuallyRedraw(Entry *entryPtr);
static void		EntryScanTo(Entry *entryPtr, int y);
static void		EntrySetValue(Entry *entryPtr, const char *value);
static void		EntrySelectTo(Entry *entryPtr, TkSizeT index);
static char *		EntryTextVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		EntryUpdateScrollbar(Entry *entryPtr);
static int		EntryValidate(Entry *entryPtr, char *cmd);
static int		EntryValidateChange(Entry *entryPtr, const char *change,
			    const char *newStr, TkSizeT index, int type);
static void		ExpandPercents(Entry *entryPtr, const char *before,
			    const char *change, const char *newStr, TkSizeT index,
			    int type, Tcl_DString *dsPtr);
static int		EntryValueChanged(Entry *entryPtr,
			    const char *newValue);
static void		EntryVisibleRange(Entry *entryPtr,
			    double *firstPtr, double *lastPtr);
static int		EntryWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		EntryWorldChanged(ClientData instanceData);
static int		GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr,
			    Tcl_Obj *indexObj, TkSizeT *indexPtr);
static int		InsertChars(Entry *entryPtr, TkSizeT index, const char *string);

/*
 * These forward declarations are the spinbox specific ones:
 */

static int		SpinboxWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GetSpinboxElement(Spinbox *sbPtr, int x, int y);
static int		SpinboxInvoke(Tcl_Interp *interp, Spinbox *sbPtr,
			    int element);
static int		ComputeFormat(Spinbox *sbPtr);

/*
 * The structure below defines widget class behavior by means of functions







|














|
|
|
|
|
|

|


|
|
|



|
|





|

|





|
<
<
|

|
|





|
<
<







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440


441
442
443
444
445
446
447
448
449
450


451
452
453
454
455
456
457

/*
 * This is the string array corresponding to the enum in selelement. If you
 * modify them, you must modify the strings here.
 */

static const char *const selElementNames[] = {
    "buttondown", "buttonup", "none", NULL, "entry"
};

/*
 * Flags for GetEntryIndex function:
 */

#define ZERO_OK			1
#define LAST_PLUS_ONE_OK	2

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		DeleteChars(Entry *entryPtr, Tcl_Size index, Tcl_Size count);
static Tcl_FreeProc	DestroyEntry;
static void		DisplayEntry(void *clientData);
static void		EntryBlinkProc(void *clientData);
static void		EntryCmdDeletedProc(void *clientData);
static void		EntryComputeGeometry(Entry *entryPtr);
static void		EntryEventProc(void *clientData,
			    XEvent *eventPtr);
static void		EntryFocusProc(Entry *entryPtr, int gotFocus);
static Tcl_Size	EntryFetchSelection(void *clientData, Tcl_Size offset,
			    char *buffer, Tcl_Size maxBytes);
static void		EntryLostSelection(void *clientData);
static void		EventuallyRedraw(Entry *entryPtr);
static void		EntryScanTo(Entry *entryPtr, int y);
static void		EntrySetValue(Entry *entryPtr, const char *value);
static void		EntrySelectTo(Entry *entryPtr, Tcl_Size index);
static char *		EntryTextVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		EntryUpdateScrollbar(Entry *entryPtr);
static int		EntryValidate(Entry *entryPtr, char *cmd);
static int		EntryValidateChange(Entry *entryPtr, const char *change,
			    const char *newStr, Tcl_Size index, int type);
static void		ExpandPercents(Entry *entryPtr, const char *before,
			    const char *change, const char *newStr, Tcl_Size index,
			    int type, Tcl_DString *dsPtr);
static int		EntryValueChanged(Entry *entryPtr,
			    const char *newValue);
static void		EntryVisibleRange(Entry *entryPtr,
			    double *firstPtr, double *lastPtr);
static Tcl_ObjCmdProc EntryWidgetObjCmd;


static void		EntryWorldChanged(void *instanceData);
static int		GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr,
			    Tcl_Obj *indexObj, Tcl_Size *indexPtr);
static int		InsertChars(Entry *entryPtr, Tcl_Size index, const char *string);

/*
 * These forward declarations are the spinbox specific ones:
 */

static Tcl_ObjCmdProc SpinboxWidgetObjCmd;


static int		GetSpinboxElement(Spinbox *sbPtr, int x, int y);
static int		SpinboxInvoke(Tcl_Interp *interp, Spinbox *sbPtr,
			    int element);
static int		ComputeFormat(Spinbox *sbPtr);

/*
 * The structure below defines widget class behavior by means of functions
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_EntryObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),







|








<







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_EntryObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
EntryWidgetObjCmd(
    ClientData clientData,	/* Information about entry widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr = (Entry *)clientData;
    int cmdIndex, selIndex, result;
    Tcl_Obj *objPtr;







|







593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
EntryWidgetObjCmd(
    void *clientData,	/* Information about entry widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr = (Entry *)clientData;
    int cmdIndex, selIndex, result;
    Tcl_Obj *objPtr;
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    case COMMAND_BBOX: {
	TkSizeT index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}







|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    case COMMAND_BBOX: {
	Tcl_Size index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DELETE: {
	TkSizeT first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else if (GetEntryIndex(interp, entryPtr, objv[3],
		&last) != TCL_OK) {
	    goto error;
	}
	if ((last + 1 >= first + 1 ) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }







|
















|







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DELETE: {
	Tcl_Size first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else if (GetEntryIndex(interp, entryPtr, objv[3],
		&last) != TCL_OK) {
	    goto error;
	}
	if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
		&entryPtr->insertPos) != TCL_OK) {
	    goto error;
	}
	EventuallyRedraw(entryPtr);
	break;

    case COMMAND_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case COMMAND_INSERT: {
	TkSizeT index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],







|














|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
		&entryPtr->insertPos) != TCL_OK) {
	    goto error;
	}
	EventuallyRedraw(entryPtr);
	break;

    case COMMAND_INDEX: {
	Tcl_Size index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case COMMAND_INSERT: {
	Tcl_Size index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
	    entryPtr->scanMarkX = x;
	    entryPtr->scanMarkIndex = entryPtr->leftIndex;
	} else if ((minorCmd[0] == 'd')
		&& (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) {
	    EntryScanTo(entryPtr, x);
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scan option \"%s\": must be mark or dragto",
		    minorCmd));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case COMMAND_SELECTION: {
	TkSizeT index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*







|









|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
	    entryPtr->scanMarkX = x;
	    entryPtr->scanMarkIndex = entryPtr->leftIndex;
	} else if ((minorCmd[0] == 'd')
		&& (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) {
	    EntryScanTo(entryPtr, x);
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scan option \"%s\": must be dragto or mark",
		    minorCmd));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case COMMAND_SELECTION: {
	Tcl_Size index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		TkSizeT half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1 ) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1 ) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}







|



|

|







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		Tcl_Size half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index < half1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index > half2) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
		    &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[4],
		    &index2) != TCL_OK) {
		goto error;
	    }
	    if (index + 1 >= index2 + 1 ) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)







|







892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
		    &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[4],
		    &index2) != TCL_OK) {
		goto error;
	    }
	    if (index >= index2) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
	    entryPtr->validate = selIndex;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case COMMAND_XVIEW: {
	TkSizeT index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);







|







943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
	    entryPtr->validate = selIndex;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case COMMAND_XVIEW: {
	Tcl_Size index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992


993
994
995
996
997
998
999
1000
1001
1002
	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {
	    case TK_SCROLL_ERROR:
		goto error;
	    case TK_SCROLL_MOVETO:
		index = (int) ((fraction * entryPtr->numChars) + 0.5);
		break;
	    case TK_SCROLL_PAGES: {
		int charsPerPage;

		charsPerPage = ((Tk_Width(entryPtr->tkwin)
			- 2 * entryPtr->inset) / entryPtr->avgWidth) - 2;
		if (charsPerPage < 1) {
		    charsPerPage = 1;
		}
		index += count * charsPerPage;
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;


	    }
	}
	if (index + 1 >= entryPtr->numChars + 1) {
	    index = entryPtr->numChars - 1;
	}
	if ((int)index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;







<
<

















>
>


|







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
	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {


	    case TK_SCROLL_MOVETO:
		index = (int) ((fraction * entryPtr->numChars) + 0.5);
		break;
	    case TK_SCROLL_PAGES: {
		int charsPerPage;

		charsPerPage = ((Tk_Width(entryPtr->tkwin)
			- 2 * entryPtr->inset) / entryPtr->avgWidth) - 2;
		if (charsPerPage < 1) {
		    charsPerPage = 1;
		}
		index += count * charsPerPage;
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;
	    default:
		goto error;
	    }
	}
	if (index >= entryPtr->numChars) {
	    index = entryPtr->numChars - 1;
	}
	if ((int)index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
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
 *	Everything associated with the entry is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyEntry(

    void *memPtr)		/* Info about entry widget. */



{
    Entry *entryPtr = (Entry *)memPtr;

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    ckfree((char *)entryPtr->string);
    if (entryPtr->textVarName != NULL) {
	Tcl_UntraceVar2(entryPtr->interp, entryPtr->textVarName,
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, entryPtr);
	entryPtr->flags &= ~ENTRY_VAR_TRACED;
    }
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
    }
    Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
    if (entryPtr->displayString != entryPtr->string) {
	ckfree((char *)entryPtr->displayString);
    }
    if (entryPtr->type == TK_SPINBOX) {
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	if (sbPtr->listObj != NULL) {
	    Tcl_DecrRefCount(sbPtr->listObj);
	    sbPtr->listObj = NULL;
	}
	if (sbPtr->formatBuf) {
	    ckfree(sbPtr->formatBuf);
	}
    }
    Tk_FreeTextLayout(entryPtr->textLayout);
    Tk_FreeConfigOptions((char *) entryPtr, entryPtr->optionTable,
	    entryPtr->tkwin);
    Tcl_Release(entryPtr->tkwin);
    entryPtr->tkwin = NULL;

    ckfree(entryPtr);
}








>

>
>
>








|














|













|







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
 *	Everything associated with the entry is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyEntry(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Info about entry widget. */
#else
    char *memPtr)
#endif
{
    Entry *entryPtr = (Entry *)memPtr;

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    ckfree((void *)entryPtr->string);
    if (entryPtr->textVarName != NULL) {
	Tcl_UntraceVar2(entryPtr->interp, entryPtr->textVarName,
		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		EntryTextVarProc, entryPtr);
	entryPtr->flags &= ~ENTRY_VAR_TRACED;
    }
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
    }
    Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
    if (entryPtr->displayString != entryPtr->string) {
	ckfree((void *)entryPtr->displayString);
    }
    if (entryPtr->type == TK_SPINBOX) {
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	if (sbPtr->listObj != NULL) {
	    Tcl_DecrRefCount(sbPtr->listObj);
	    sbPtr->listObj = NULL;
	}
	if (sbPtr->formatBuf) {
	    ckfree(sbPtr->formatBuf);
	}
    }
    Tk_FreeTextLayout(entryPtr->textLayout);
    Tk_FreeConfigOptions(entryPtr, entryPtr->optionTable,
	    entryPtr->tkwin);
    Tcl_Release(entryPtr->tkwin);
    entryPtr->tkwin = NULL;

    ckfree(entryPtr);
}

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
 */

static int
ConfigureEntry(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Entry *entryPtr,		/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_SavedOptions savedOptions;
    Tk_3DBorder border;
    Tcl_Obj *errorResult = NULL;
    Spinbox *sbPtr = (Spinbox *) entryPtr;
				/* Only used when this widget is of type
				 * TK_SPINBOX */
    char *oldValues = NULL;
    char *oldFormat = NULL;
    int error;
    int oldExport = 0;
    int valuesChanged = 0;
    double oldFrom = 0.0;
    double oldTo = 0.0;
    int code;


    /*
     * Eliminate any existing trace on a variable monitored by the entry.
     */

    if ((entryPtr->textVarName != NULL)
	    && (entryPtr->flags & ENTRY_VAR_TRACED)) {







|
















>







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
 */

static int
ConfigureEntry(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Entry *entryPtr,		/* Information about widget; may or may not
				 * already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_SavedOptions savedOptions;
    Tk_3DBorder border;
    Tcl_Obj *errorResult = NULL;
    Spinbox *sbPtr = (Spinbox *) entryPtr;
				/* Only used when this widget is of type
				 * TK_SPINBOX */
    char *oldValues = NULL;
    char *oldFormat = NULL;
    int error;
    int oldExport = 0;
    int valuesChanged = 0;
    double oldFrom = 0.0;
    double oldTo = 0.0;
    int code;
    size_t formatSpace = TCL_DOUBLE_SPACE;

    /*
     * Eliminate any existing trace on a variable monitored by the entry.
     */

    if ((entryPtr->textVarName != NULL)
	    && (entryPtr->flags & ENTRY_VAR_TRACED)) {
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
		/*
		 * Make sure that the given format is somewhat correct, and
		 * calculate the minimum space we'll need for the values as
		 * strings.
		 */

		int min, max;
		size_t formatLen, formatSpace = TCL_DOUBLE_SPACE;
		char fbuf[4], *fmt = sbPtr->reqFormat;

		formatLen = strlen(fmt);
		if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
		badFormatOpt:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad spinbox format specifier \"%s\"",







|







1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
		/*
		 * Make sure that the given format is somewhat correct, and
		 * calculate the minimum space we'll need for the values as
		 * strings.
		 */

		int min, max;
		size_t formatLen;
		char fbuf[4], *fmt = sbPtr->reqFormat;

		formatLen = strlen(fmt);
		if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
		badFormatOpt:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad spinbox format specifier \"%s\"",
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
	    if (oldValues != sbPtr->valueStr) {
		if (sbPtr->listObj != NULL) {
		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    int nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, TCL_INDEX_NONE);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }







|







1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
	    if (oldValues != sbPtr->valueStr) {
		if (sbPtr->listObj != NULL) {
		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    Tcl_Size nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, TCL_INDEX_NONE);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
		/* Scan failure */
		dvalue = sbPtr->fromValue;
	    } else if (dvalue > sbPtr->toValue) {
		dvalue = sbPtr->toValue;
	    } else if (dvalue < sbPtr->fromValue) {
		dvalue = sbPtr->fromValue;
	    }
	    sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);

            /*
	     * No check for error return here as well, because any possible
	     * error will be trapped below when attempting tracing.
	     */

	    EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }







|

|







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
		/* Scan failure */
		dvalue = sbPtr->fromValue;
	    } else if (dvalue > sbPtr->toValue) {
		dvalue = sbPtr->toValue;
	    } else if (dvalue < sbPtr->fromValue) {
		dvalue = sbPtr->fromValue;
	    }
	    snprintf(sbPtr->formatBuf, formatSpace, sbPtr->valueFormat, dvalue);

	    /*
	     * No check for error return here as well, because any possible
	     * error will be trapped below when attempting tracing.
	     */

	    EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
 *	Entry will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
EntryWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    unsigned long mask;
    Tk_3DBorder border;
    XColor *colorPtr;
    Entry *entryPtr = (Entry *)instanceData;







|







1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
 *	Entry will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
EntryWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    unsigned long mask;
    Tk_3DBorder border;
    XColor *colorPtr;
    Entry *entryPtr = (Entry *)instanceData;
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawEntryBorderAndFocus(
    Entry *entryPtr,
    Drawable pixmap,
    int isSpinbox)
{
    (void)entryPtr;
    (void)pixmap;
    (void)isSpinbox;

    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDrawSpinboxButtons --







|
|
|

<
<
<
<







1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570




1571
1572
1573
1574
1575
1576
1577
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawEntryBorderAndFocus(
    TCL_UNUSED(Entry *),
    TCL_UNUSED(Drawable),
    TCL_UNUSED(int))
{




    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDrawSpinboxButtons --
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Pixmap pixmap)
{
    (void)sbPtr;
    (void)pixmap;

    return 0;
}
#endif /* Not MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *







|
|

<
<
<







1587
1588
1589
1590
1591
1592
1593
1594
1595
1596



1597
1598
1599
1600
1601
1602
1603
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    TCL_UNUSED(Spinbox *),
    TCL_UNUSED(Pixmap))
{



    return 0;
}
#endif /* Not MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayEntry(
    ClientData clientData)	/* Information about window. */
{
    Entry *entryPtr = (Entry *)clientData;
    Tk_Window tkwin = entryPtr->tkwin;
    int baseY, selStartX, selEndX, cursorX;
    int showSelection, xBound;
    Tk_FontMetrics fm;
    Pixmap pixmap;







|







1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayEntry(
    void *clientData)	/* Information about window. */
{
    Entry *entryPtr = (Entry *)clientData;
    Tk_Window tkwin = entryPtr->tkwin;
    int baseY, selStartX, selEndX, cursorX;
    int showSelection, xBound;
    Tk_FontMetrics fm;
    Pixmap pixmap;
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
    } else {
	border = entryPtr->normalBorder;
    }
    Tk_Fill3DRectangle(tkwin, pixmap, border,
	    0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selectLast + 1  > entryPtr->leftIndex + 1)) {
	if (entryPtr->selectFirst <= entryPtr->leftIndex) {
	    selStartX = entryPtr->leftX;
	} else {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectFirst,
		    &selStartX, NULL, NULL, NULL);
	    selStartX += entryPtr->layoutX;
	}







|







1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
    } else {
	border = entryPtr->normalBorder;
    }
    Tk_Fill3DRectangle(tkwin, pixmap, border,
	    0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selectLast > entryPtr->leftIndex)) {
	if (entryPtr->selectFirst <= entryPtr->leftIndex) {
	    selStartX = entryPtr->leftX;
	} else {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectFirst,
		    &selStartX, NULL, NULL, NULL);
	    selStartX += entryPtr->layoutX;
	}
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
    if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
	Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
		NULL, NULL);
	cursorX += entryPtr->layoutX;
	cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
	Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
		fm.ascent + fm.descent);
	if ((entryPtr->insertPos + 1 >= entryPtr->leftIndex + 1) && cursorX < xBound) {
	    if (entryPtr->flags & CURSOR_ON) {
		Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder,
			cursorX, baseY - fm.ascent, entryPtr->insertWidth,
			fm.ascent + fm.descent, entryPtr->insertBorderWidth,
			TK_RELIEF_RAISED);
	    } else if (entryPtr->insertBorder == entryPtr->selBorder) {
		Tk_Fill3DRectangle(tkwin, pixmap, border, cursorX,







|







1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
    if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
	Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
		NULL, NULL);
	cursorX += entryPtr->layoutX;
	cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
	Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
		fm.ascent + fm.descent);
	if ((entryPtr->insertPos >= entryPtr->leftIndex) && cursorX < xBound) {
	    if (entryPtr->flags & CURSOR_ON) {
		Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder,
			cursorX, baseY - fm.ascent, entryPtr->insertWidth,
			fm.ascent + fm.descent, entryPtr->insertBorderWidth,
			TK_RELIEF_RAISED);
	    } else if (entryPtr->insertBorder == entryPtr->selBorder) {
		Tk_Fill3DRectangle(tkwin, pixmap, border, cursorX,
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
	    entryPtr->placeholderLayout, entryPtr->placeholderX, entryPtr->layoutY,
	    entryPtr->placeholderLeftIndex, entryPtr->placeholderChars);

    } else {

        if (showSelection && (entryPtr->state != STATE_DISABLED)
	        && (entryPtr->selTextGC != entryPtr->textGC)
	        && (entryPtr->selectFirst + 1 < entryPtr->selectLast + 1)) {

	    /*
	     * Draw the selected and unselected portions separately.
	     */

	    TkSizeT selFirst;

	    if (entryPtr->selectFirst + 1 < entryPtr->leftIndex + 1) {
	        selFirst = entryPtr->leftIndex;
	    } else {
	        selFirst = entryPtr->selectFirst;
	    }
	    if (entryPtr->leftIndex < selFirst) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,







|





|

|







1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
	    entryPtr->placeholderLayout, entryPtr->placeholderX, entryPtr->layoutY,
	    entryPtr->placeholderLeftIndex, entryPtr->placeholderChars);

    } else {

        if (showSelection && (entryPtr->state != STATE_DISABLED)
	        && (entryPtr->selTextGC != entryPtr->textGC)
	        && (entryPtr->selectFirst < entryPtr->selectLast)) {

	    /*
	     * Draw the selected and unselected portions separately.
	     */

	    Tcl_Size selFirst;

	    if (entryPtr->selectFirst < entryPtr->leftIndex) {
	        selFirst = entryPtr->leftIndex;
	    } else {
	        selFirst = entryPtr->selectFirst;
	    }
	    if (entryPtr->leftIndex < selFirst) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
	}
	if (xBound > 0) {
	    GC fgGC, bgGC;

	    bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, pixmap);
	    if (entryPtr->flags & GOT_FOCUS) {
		fgGC = Tk_GCForColor(entryPtr->highlightColorPtr, pixmap);
		TkpDrawHighlightBorder(tkwin, fgGC, bgGC, xBound, pixmap);
	    } else {
		TkpDrawHighlightBorder(tkwin, bgGC, bgGC, xBound, pixmap);
	    }
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * Everything's been redisplayed; now copy the pixmap onto the screen and







|

|







1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
	}
	if (xBound > 0) {
	    GC fgGC, bgGC;

	    bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, pixmap);
	    if (entryPtr->flags & GOT_FOCUS) {
		fgGC = Tk_GCForColor(entryPtr->highlightColorPtr, pixmap);
		Tk_DrawHighlightBorder(tkwin, fgGC, bgGC, xBound, pixmap);
	    } else {
		Tk_DrawHighlightBorder(tkwin, bgGC, bgGC, xBound, pixmap);
	    }
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * Everything's been redisplayed; now copy the pixmap onto the screen and
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
 */

static void
EntryComputeGeometry(
    Entry *entryPtr)		/* Widget record for entry. */
{
    int totalLength, overflow, rightX;
    TkSizeT maxOffScreen;
    int height, width, i;
    Tk_FontMetrics fm;
    char *p;

    if (entryPtr->displayString != entryPtr->string) {
	ckfree((char *)entryPtr->displayString);
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * If we're displaying a special character instead of the value of the
     * entry, recompute the displayString.







|





|







1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
 */

static void
EntryComputeGeometry(
    Entry *entryPtr)		/* Widget record for entry. */
{
    int totalLength, overflow, rightX;
    Tcl_Size maxOffScreen;
    int height, width, i;
    Tk_FontMetrics fm;
    char *p;

    if (entryPtr->displayString != entryPtr->string) {
	ckfree((void *)entryPtr->displayString);
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * If we're displaying a special character instead of the value of the
     * entry, recompute the displayString.
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
	/*
	 * Normalize the special character so we can safely duplicate it in
	 * the display string. If we didn't do this, then two malformed
	 * characters might end up looking like one valid UTF character in the
	 * resulting string.
	 */

	TkUtfToUniChar(entryPtr->showChar, &ch);
	size = TkUniCharToUtf(ch, buf);

	entryPtr->numDisplayBytes = entryPtr->numChars * size;
	p = (char *)ckalloc(entryPtr->numDisplayBytes + 1);
	entryPtr->displayString = p;

	for (i = entryPtr->numChars; i-- > 0; ) {
	    memcpy(p, buf, size);







|
|







1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
	/*
	 * Normalize the special character so we can safely duplicate it in
	 * the display string. If we didn't do this, then two malformed
	 * characters might end up looking like one valid UTF character in the
	 * resulting string.
	 */

	Tcl_UtfToUniChar(entryPtr->showChar, &ch);
	size = Tcl_UniCharToUtf(ch, buf);

	entryPtr->numDisplayBytes = entryPtr->numChars * size;
	p = (char *)ckalloc(entryPtr->numDisplayBytes + 1);
	entryPtr->displayString = p;

	for (i = entryPtr->numChars; i-- > 0; ) {
	    memcpy(p, buf, size);
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119

	maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0);
	Tk_CharBbox(entryPtr->textLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	if (rightX < overflow) {
	    maxOffScreen++;
	}
	if (entryPtr->leftIndex + 1 > maxOffScreen + 1) {
	    entryPtr->leftIndex = maxOffScreen;
	}
	Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, &rightX,
		NULL, NULL, NULL);
	entryPtr->leftX = entryPtr->inset;
	entryPtr->layoutX = entryPtr->leftX - rightX;
    }







|







2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116

	maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0);
	Tk_CharBbox(entryPtr->textLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	if (rightX < overflow) {
	    maxOffScreen++;
	}
	if (entryPtr->leftIndex > maxOffScreen) {
	    entryPtr->leftIndex = maxOffScreen;
	}
	Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, &rightX,
		NULL, NULL, NULL);
	entryPtr->leftX = entryPtr->inset;
	entryPtr->layoutX = entryPtr->leftX - rightX;
    }
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
 *
 *----------------------------------------------------------------------
 */

static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    TkSizeT index,			/* Add the new elements before this character
				 * index. */
    const char *value)		/* New characters to add (NULL-terminated
				 * string). */
{
    size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded;
    const char *string;
    char *newStr;







|







2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
 *
 *----------------------------------------------------------------------
 */

static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    Tcl_Size index,			/* Add the new elements before this character
				 * index. */
    const char *value)		/* New characters to add (NULL-terminated
				 * string). */
{
    size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded;
    const char *string;
    char *newStr;
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
	    entryPtr->validate == VALIDATE_ALL) &&
	    EntryValidateChange(entryPtr, value, newStr, index,
		    VALIDATE_INSERT) != TCL_OK) {
	ckfree(newStr);
	return TCL_OK;
    }

    ckfree((char *)string);
    entryPtr->string = newStr;

    /*
     * The following construction is used because inserting improperly formed
     * UTF-8 sequences between other improperly formed UTF-8 sequences could
     * result in actually forming valid UTF-8 sequences; the number of
     * characters added may not be Tcl_NumUtfChars(string, -1), because of
     * context. The actual number of characters added is how many characters
     * are in the string now minus the number that used to be there.
     */

    oldChars = entryPtr->numChars;
    entryPtr->numChars = Tcl_NumUtfChars(newStr, TCL_INDEX_NONE);
    charsAdded = entryPtr->numChars - oldChars;







|






|







2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
	    entryPtr->validate == VALIDATE_ALL) &&
	    EntryValidateChange(entryPtr, value, newStr, index,
		    VALIDATE_INSERT) != TCL_OK) {
	ckfree(newStr);
	return TCL_OK;
    }

    ckfree((void *)string);
    entryPtr->string = newStr;

    /*
     * The following construction is used because inserting improperly formed
     * UTF-8 sequences between other improperly formed UTF-8 sequences could
     * result in actually forming valid UTF-8 sequences; the number of
     * characters added may not be Tcl_NumUtfChars(string, TCL_INDEX_NONE), because of
     * context. The actual number of characters added is how many characters
     * are in the string now minus the number that used to be there.
     */

    oldChars = entryPtr->numChars;
    entryPtr->numChars = Tcl_NumUtfChars(newStr, TCL_INDEX_NONE);
    charsAdded = entryPtr->numChars - oldChars;
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
     * Inserting characters invalidates all indexes into the string. Touch up
     * the indexes so that they still refer to the same characters (at new
     * positions). When updating the selection end-points, don't include the
     * new text in the selection unless it was completely surrounded by the
     * selection.
     */

    if (entryPtr->selectFirst + 1 >= index + 1) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast + 1 > index + 1) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor + 1 > index + 1) || (entryPtr->selectFirst + 1 >= index + 1)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
	entryPtr->insertPos += charsAdded;
    }
    return EntryValueChanged(entryPtr, NULL);
}

/*
 *----------------------------------------------------------------------







|


|


|


|


|







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
     * Inserting characters invalidates all indexes into the string. Touch up
     * the indexes so that they still refer to the same characters (at new
     * positions). When updating the selection end-points, don't include the
     * new text in the selection unless it was completely surrounded by the
     * selection.
     */

    if (entryPtr->selectFirst >= index) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast > index) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex > index) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos >= index) {
	entryPtr->insertPos += charsAdded;
    }
    return EntryValueChanged(entryPtr, NULL);
}

/*
 *----------------------------------------------------------------------
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
 *
 *----------------------------------------------------------------------
 */

static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    TkSizeT index,			/* Index of first character to delete. */
    TkSizeT count)			/* How many characters to delete. */
{
    int byteIndex, byteCount, newByteCount;
    const char *string;
    char *newStr, *toDelete;

    if (index + count + 1 > entryPtr->numChars + 1) {
	count = entryPtr->numChars - index;
    }
    if ((int)count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;







|
|





|







2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
 *
 *----------------------------------------------------------------------
 */

static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    Tcl_Size index,			/* Index of first character to delete. */
    Tcl_Size count)			/* How many characters to delete. */
{
    int byteIndex, byteCount, newByteCount;
    const char *string;
    char *newStr, *toDelete;

    if (index + count > entryPtr->numChars) {
	count = entryPtr->numChars - index;
    }
    if ((int)count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;
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
		    VALIDATE_DELETE) != TCL_OK) {
	ckfree(newStr);
	ckfree(toDelete);
	return TCL_OK;
    }

    ckfree(toDelete);
    ckfree((char *)entryPtr->string);
    entryPtr->string = newStr;
    entryPtr->numChars -= count;
    entryPtr->numBytes -= byteCount;

    if (entryPtr->displayString == string) {
	entryPtr->displayString = newStr;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * Deleting characters results in the remaining characters being
     * renumbered. Update the various indexes into the string to reflect this
     * change.
     */

    if (entryPtr->selectFirst + 1 >= index + 1) {
	if (entryPtr->selectFirst + 1 >= index + count + 1) {
	    entryPtr->selectFirst -= count;
	} else {
	    entryPtr->selectFirst = index;
	}
    }
    if (entryPtr->selectLast + 1 >= index + 1) {
	if (entryPtr->selectLast + 1 >= index + count + 1) {
	    entryPtr->selectLast -= count;
	} else {
	    entryPtr->selectLast = index;
	}
    }
    if (entryPtr->selectLast + 1 <= entryPtr->selectFirst + 1) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
    }
    if (entryPtr->selectAnchor + 1 >= index + 1) {
	if (entryPtr->selectAnchor + 1 >= index + count + 1) {
	    entryPtr->selectAnchor -= count;
	} else {
	    entryPtr->selectAnchor = index;
	}
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
	if (entryPtr->leftIndex + 1 >= index + count + 1) {
	    entryPtr->leftIndex -= count;
	} else {
	    entryPtr->leftIndex = index;
	}
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
	if (entryPtr->insertPos + 1 >= index + count + 1) {
	    entryPtr->insertPos -= count;
	} else {
	    entryPtr->insertPos = index;
	}
    }
    return EntryValueChanged(entryPtr, NULL);
}







|















|
|





|
|





|



|
|





|
|





|
|







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
		    VALIDATE_DELETE) != TCL_OK) {
	ckfree(newStr);
	ckfree(toDelete);
	return TCL_OK;
    }

    ckfree(toDelete);
    ckfree((void *)entryPtr->string);
    entryPtr->string = newStr;
    entryPtr->numChars -= count;
    entryPtr->numBytes -= byteCount;

    if (entryPtr->displayString == string) {
	entryPtr->displayString = newStr;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * Deleting characters results in the remaining characters being
     * renumbered. Update the various indexes into the string to reflect this
     * change.
     */

    if (entryPtr->selectFirst >= index) {
	if (entryPtr->selectFirst >= index + count) {
	    entryPtr->selectFirst -= count;
	} else {
	    entryPtr->selectFirst = index;
	}
    }
    if (entryPtr->selectLast >= index) {
	if (entryPtr->selectLast >= index + count) {
	    entryPtr->selectLast -= count;
	} else {
	    entryPtr->selectLast = index;
	}
    }
    if (entryPtr->selectLast <= entryPtr->selectFirst) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
    }
    if (entryPtr->selectAnchor >= index) {
	if (entryPtr->selectAnchor >= index + count) {
	    entryPtr->selectAnchor -= count;
	} else {
	    entryPtr->selectAnchor = index;
	}
    }
    if (entryPtr->leftIndex > index) {
	if (entryPtr->leftIndex >= index + count) {
	    entryPtr->leftIndex -= count;
	} else {
	    entryPtr->leftIndex = index;
	}
    }
    if (entryPtr->insertPos >= index) {
	if (entryPtr->insertPos >= index + count) {
	    entryPtr->insertPos -= count;
	} else {
	    entryPtr->insertPos = index;
	}
    }
    return EntryValueChanged(entryPtr, NULL);
}
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
	char *tmp = (char *)ckalloc(valueLen + 1);

	strcpy(tmp, value);
	value = tmp;
	malloced = 1;

	entryPtr->flags |= VALIDATE_VAR;
	(void) EntryValidateChange(entryPtr, NULL, value, -1,
		VALIDATE_FORCED);
	entryPtr->flags &= ~VALIDATE_VAR;

	/*
	 * If VALIDATE_ABORT has been set, then this operation should be
	 * aborted because the validatecommand did something else instead
	 */

	if (entryPtr->flags & VALIDATE_ABORT) {
	    entryPtr->flags &= ~VALIDATE_ABORT;
	    ckfree((char *)value);
	    return;
	}
    }

    oldSource = entryPtr->string;
    ckfree((char *)entryPtr->string);

    if (malloced) {
	entryPtr->string = value;
    } else {
	char *tmp = (char *)ckalloc(valueLen + 1);

	strcpy(tmp, value);
	entryPtr->string = tmp;
    }
    entryPtr->numBytes = valueLen;
    entryPtr->numChars = Tcl_NumUtfChars(value, valueLen);

    if (entryPtr->displayString == oldSource) {
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
	if (entryPtr->selectFirst + 1 >= entryPtr->numChars + 1) {
	    entryPtr->selectFirst = TCL_INDEX_NONE;
	    entryPtr->selectLast = TCL_INDEX_NONE;
	} else if (entryPtr->selectLast + 1 > entryPtr->numChars + 1) {
	    entryPtr->selectLast = entryPtr->numChars;
	}
    }
    if (entryPtr->leftIndex + 1 >= entryPtr->numChars + 1) {
	if (entryPtr->numChars + 1 > 1) {
	    entryPtr->leftIndex = entryPtr->numChars - 1;
	} else {
	    entryPtr->leftIndex = 0;
	}
    }
    if (entryPtr->insertPos + 1 > entryPtr->numChars + 1) {
	entryPtr->insertPos = entryPtr->numChars;
    }

    entryPtr->flags |= UPDATE_SCROLLBAR;
    EntryComputeGeometry(entryPtr);
    EventuallyRedraw(entryPtr);
}







|










|





|


















|


|



|
|





|







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
	char *tmp = (char *)ckalloc(valueLen + 1);

	strcpy(tmp, value);
	value = tmp;
	malloced = 1;

	entryPtr->flags |= VALIDATE_VAR;
	(void) EntryValidateChange(entryPtr, NULL, value, TCL_INDEX_NONE,
		VALIDATE_FORCED);
	entryPtr->flags &= ~VALIDATE_VAR;

	/*
	 * If VALIDATE_ABORT has been set, then this operation should be
	 * aborted because the validatecommand did something else instead
	 */

	if (entryPtr->flags & VALIDATE_ABORT) {
	    entryPtr->flags &= ~VALIDATE_ABORT;
	    ckfree((void *)value);
	    return;
	}
    }

    oldSource = entryPtr->string;
    ckfree((void *)entryPtr->string);

    if (malloced) {
	entryPtr->string = value;
    } else {
	char *tmp = (char *)ckalloc(valueLen + 1);

	strcpy(tmp, value);
	entryPtr->string = tmp;
    }
    entryPtr->numBytes = valueLen;
    entryPtr->numChars = Tcl_NumUtfChars(value, valueLen);

    if (entryPtr->displayString == oldSource) {
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
	if (entryPtr->selectFirst >= entryPtr->numChars) {
	    entryPtr->selectFirst = TCL_INDEX_NONE;
	    entryPtr->selectLast = TCL_INDEX_NONE;
	} else if (entryPtr->selectLast > entryPtr->numChars) {
	    entryPtr->selectLast = entryPtr->numChars;
	}
    }
    if (entryPtr->leftIndex >= entryPtr->numChars) {
	if (entryPtr->numChars > 0) {
	    entryPtr->leftIndex = entryPtr->numChars - 1;
	} else {
	    entryPtr->leftIndex = 0;
	}
    }
    if (entryPtr->insertPos > entryPtr->numChars) {
	entryPtr->insertPos = entryPtr->numChars;
    }

    entryPtr->flags |= UPDATE_SCROLLBAR;
    EntryComputeGeometry(entryPtr);
    EventuallyRedraw(entryPtr);
}
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EntryEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Entry *entryPtr = (Entry *)clientData;

    if ((entryPtr->type == TK_SPINBOX) && (eventPtr->type == MotionNotify)) {
	Spinbox *sbPtr = (Spinbox *)clientData;
	int elem;







|







2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EntryEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Entry *entryPtr = (Entry *)clientData;

    if ((entryPtr->type == TK_SPINBOX) && (eventPtr->type == MotionNotify)) {
	Spinbox *sbPtr = (Spinbox *)clientData;
	int elem;
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
    case DestroyNotify:
	if (!(entryPtr->flags & ENTRY_DELETED)) {
	    entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT);
	    Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd);
	    if (entryPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayEntry, clientData);
	    }
	    Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyEntry);
	}
	break;
    case ConfigureNotify:
	Tcl_Preserve(entryPtr);
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);







|







2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
    case DestroyNotify:
	if (!(entryPtr->flags & ENTRY_DELETED)) {
	    entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT);
	    Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd);
	    if (entryPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayEntry, clientData);
	    }
	    Tcl_EventuallyFree(clientData, DestroyEntry);
	}
	break;
    case ConfigureNotify:
	Tcl_Preserve(entryPtr);
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EntryCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Entry *entryPtr = (Entry *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the







|







2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EntryCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    Entry *entryPtr = (Entry *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716

static int
GetEntryIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Entry *entryPtr,		/* Entry for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,	/* Specifies character in entryPtr. */
    TkSizeT *indexPtr)		/* Where to store converted character index */
{
    TkSizeT length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->numChars - 1, 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
	} else if (idx > entryPtr->numChars) {
	    idx = entryPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);

    switch (string[0]) {
    case 'a':
	if (strncmp(string, "anchor", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->selectAnchor;
	break;
    case 'i':
	if (strncmp(string, "insert", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->insertPos;
	break;
    case 's':
	if (entryPtr->selectFirst == TCL_INDEX_NONE) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK",
		    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
		    "NO_SELECTION", NULL);







|

|



|








|















|







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

static int
GetEntryIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Entry *entryPtr,		/* Entry for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,	/* Specifies character in entryPtr. */
    Tcl_Size *indexPtr)		/* Where to store converted character index */
{
    Tcl_Size length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->numChars - 1, 1, &idx)) {
	if (idx < 0) {
	    idx = 0;
	} else if (idx > entryPtr->numChars) {
	    idx = entryPtr->numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    string = Tcl_GetStringFromObj(indexObj, &length);

    switch (string[0]) {
    case 'a':
	if (strncmp(string, "anchor", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->selectAnchor;
	break;
    case 'i':
	if (strncmp(string, "insert", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->insertPos;
	break;
    case 's':
	if (entryPtr->selectFirst < 0) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK",
		    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
		    "NO_SELECTION", NULL);
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
	/*
	 * Special trick: if the x-position was off-screen to the right, round
	 * the index up to refer to the character just after the last visible
	 * one on the screen. This is needed to enable the last character to
	 * be selected, for example.
	 */

	if (roundUp && (*indexPtr + 1 < entryPtr->numChars + 1)) {
	    *indexPtr += 1;
	}
	break;
    }
    default:
	  badIndex:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad %s index \"%s\"",







|







2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
	/*
	 * Special trick: if the x-position was off-screen to the right, round
	 * the index up to refer to the character just after the last visible
	 * one on the screen. This is needed to enable the last character to
	 * be selected, for example.
	 */

	if (roundUp && (*indexPtr < entryPtr->numChars)) {
	    *indexPtr += 1;
	}
	break;
    }
    default:
	  badIndex:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad %s index \"%s\"",
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
 */

static void
EntryScanTo(
    Entry *entryPtr,		/* Information about widget. */
    int x)			/* X-coordinate to use for scan operation. */
{
    TkSizeT newLeftIndex;

    /*
     * Compute new leftIndex for entry by amplifying the difference between
     * the current position and the place where the scan started (the "mark"
     * position). If we run off the left or right side of the entry, then
     * reset the mark point so that the current position continues to
     * correspond to the edge of the window. This means that the picture will
     * start dragging as soon as the mouse reverses direction (without this
     * reset, might have to slide mouse a long ways back before the picture
     * starts moving again).
     */

    newLeftIndex = entryPtr->scanMarkIndex
	    - (10 * (x - entryPtr->scanMarkX)) / entryPtr->avgWidth;
    if (newLeftIndex + 1 >= entryPtr->numChars + 1) {
	newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1;
	entryPtr->scanMarkX = x;
    }
    if (newLeftIndex == TCL_INDEX_NONE) {
	newLeftIndex = entryPtr->scanMarkIndex = 0;
	entryPtr->scanMarkX = x;
    }

    if (newLeftIndex != entryPtr->leftIndex) {
	entryPtr->leftIndex = newLeftIndex;
	entryPtr->flags |= UPDATE_SCROLLBAR;







|














|



|







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
 */

static void
EntryScanTo(
    Entry *entryPtr,		/* Information about widget. */
    int x)			/* X-coordinate to use for scan operation. */
{
    Tcl_Size newLeftIndex;

    /*
     * Compute new leftIndex for entry by amplifying the difference between
     * the current position and the place where the scan started (the "mark"
     * position). If we run off the left or right side of the entry, then
     * reset the mark point so that the current position continues to
     * correspond to the edge of the window. This means that the picture will
     * start dragging as soon as the mouse reverses direction (without this
     * reset, might have to slide mouse a long ways back before the picture
     * starts moving again).
     */

    newLeftIndex = entryPtr->scanMarkIndex
	    - (10 * (x - entryPtr->scanMarkX)) / entryPtr->avgWidth;
    if (newLeftIndex >= entryPtr->numChars) {
	newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1;
	entryPtr->scanMarkX = x;
    }
    if (newLeftIndex < 0) {
	newLeftIndex = entryPtr->scanMarkIndex = 0;
	entryPtr->scanMarkX = x;
    }

    if (newLeftIndex != entryPtr->leftIndex) {
	entryPtr->leftIndex = newLeftIndex;
	entryPtr->flags |= UPDATE_SCROLLBAR;
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
 *
 *----------------------------------------------------------------------
 */

static void
EntrySelectTo(
    Entry *entryPtr,		/* Information about widget. */
    TkSizeT index)			/* Character index of element that is to
				 * become the "other" end of the selection. */
{
    TkSizeT newFirst, newLast;

    /*
     * Grab the selection if we don't own it already.
     */

    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		entryPtr);
	entryPtr->flags |= GOT_SELECTION;
    }

    /*
     * Pick new starting and ending points for the selection.
     */

    if (entryPtr->selectAnchor + 1 > entryPtr->numChars + 1) {
	entryPtr->selectAnchor = entryPtr->numChars;
    }
    if (entryPtr->selectAnchor + 1 <= index + 1) {
	newFirst = entryPtr->selectAnchor;
	newLast = index;
    } else {
	newFirst = index;
	newLast = entryPtr->selectAnchor;
	if (newLast == TCL_INDEX_NONE) {
	    newFirst = newLast = TCL_INDEX_NONE;
	}
    }
    if ((entryPtr->selectFirst == newFirst)
	    && (entryPtr->selectLast == newLast)) {
	return;
    }







|


|
















|


|





|







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
 *
 *----------------------------------------------------------------------
 */

static void
EntrySelectTo(
    Entry *entryPtr,		/* Information about widget. */
    Tcl_Size index)			/* Character index of element that is to
				 * become the "other" end of the selection. */
{
    Tcl_Size newFirst, newLast;

    /*
     * Grab the selection if we don't own it already.
     */

    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		entryPtr);
	entryPtr->flags |= GOT_SELECTION;
    }

    /*
     * Pick new starting and ending points for the selection.
     */

    if (entryPtr->selectAnchor > entryPtr->numChars) {
	entryPtr->selectAnchor = entryPtr->numChars;
    }
    if (entryPtr->selectAnchor <= index) {
	newFirst = entryPtr->selectAnchor;
	newLast = index;
    } else {
	newFirst = index;
	newLast = entryPtr->selectAnchor;
	if (newLast < 0) {
	    newFirst = newLast = TCL_INDEX_NONE;
	}
    }
    if ((entryPtr->selectFirst == newFirst)
	    && (entryPtr->selectLast == newLast)) {
	return;
    }
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
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
EntryFetchSelection(
    ClientData clientData,	/* Information about entry widget. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NUL character. */
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst == TCL_INDEX_NONE) || (!entryPtr->exportSelection)
	    || Tcl_IsSafe(entryPtr->interp)) {
	return -1;
    }
    string = entryPtr->displayString;
    selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);







|

|
|


|



|



|







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
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
EntryFetchSelection(
    void *clientData,	/* Information about entry widget. */
    Tcl_Size offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    Tcl_Size maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NUL character. */
{
    Entry *entryPtr = (Entry *)clientData;
    Tcl_Size byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection)
	    || Tcl_IsSafe(entryPtr->interp)) {
	return -1;
    }
    string = entryPtr->displayString;
    selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
EntryLostSelection(
    ClientData clientData)	/* Information about entry widget. */
{
    Entry *entryPtr = (Entry *)clientData;

    entryPtr->flags &= ~GOT_SELECTION;

    /*
     * On Windows and Mac systems, we want to remember the selection for the







|







2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
EntryLostSelection(
    void *clientData)	/* Information about entry widget. */
{
    Entry *entryPtr = (Entry *)clientData;

    entryPtr->flags &= ~GOT_SELECTION;

    /*
     * On Windows and Mac systems, we want to remember the selection for the
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
 *	function reschedules itself.
 *
 *----------------------------------------------------------------------
 */

static void
EntryBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
{
    Entry *entryPtr = (Entry *)clientData;

    if ((entryPtr->state == STATE_DISABLED) ||
	    (entryPtr->state == STATE_READONLY) ||
	    !(entryPtr->flags & GOT_FOCUS) || (entryPtr->insertOffTime == 0)) {
	return;







|







3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
 *	function reschedules itself.
 *
 *----------------------------------------------------------------------
 */

static void
EntryBlinkProc(
    void *clientData)	/* Pointer to record describing entry. */
{
    Entry *entryPtr = (Entry *)clientData;

    if ((entryPtr->state == STATE_DISABLED) ||
	    (entryPtr->state == STATE_READONLY) ||
	    !(entryPtr->flags & GOT_FOCUS) || (entryPtr->insertOffTime == 0)) {
	return;
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
	if (entryPtr->insertOffTime != 0) {
	    entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		    entryPtr->insertOnTime, EntryBlinkProc, entryPtr);
	}
	if (entryPtr->validate == VALIDATE_ALL ||
		entryPtr->validate == VALIDATE_FOCUS ||
		entryPtr->validate == VALIDATE_FOCUSIN) {
	    EntryValidateChange(entryPtr, NULL, entryPtr->string, -1,
		    VALIDATE_FOCUSIN);
	}
    } else {
	entryPtr->flags &= ~(GOT_FOCUS | CURSOR_ON);
	entryPtr->insertBlinkHandler = NULL;
	if (entryPtr->validate == VALIDATE_ALL ||
		entryPtr->validate == VALIDATE_FOCUS ||
		entryPtr->validate == VALIDATE_FOCUSOUT) {
	    EntryValidateChange(entryPtr, NULL, entryPtr->string, -1,
		    VALIDATE_FOCUSOUT);
	}
    }
    EventuallyRedraw(entryPtr);
}

/*







|








|







3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
	if (entryPtr->insertOffTime != 0) {
	    entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
		    entryPtr->insertOnTime, EntryBlinkProc, entryPtr);
	}
	if (entryPtr->validate == VALIDATE_ALL ||
		entryPtr->validate == VALIDATE_FOCUS ||
		entryPtr->validate == VALIDATE_FOCUSIN) {
	    EntryValidateChange(entryPtr, NULL, entryPtr->string, TCL_INDEX_NONE,
		    VALIDATE_FOCUSIN);
	}
    } else {
	entryPtr->flags &= ~(GOT_FOCUS | CURSOR_ON);
	entryPtr->insertBlinkHandler = NULL;
	if (entryPtr->validate == VALIDATE_ALL ||
		entryPtr->validate == VALIDATE_FOCUS ||
		entryPtr->validate == VALIDATE_FOCUSOUT) {
	    EntryValidateChange(entryPtr, NULL, entryPtr->string, TCL_INDEX_NONE,
		    VALIDATE_FOCUSOUT);
	}
    }
    EventuallyRedraw(entryPtr);
}

/*
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
 *	The text displayed in the entry will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
EntryTextVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    Entry *entryPtr = (Entry *)clientData;
    const char *value;
    (void)name1;
    (void)name2;

    if (entryPtr->flags & ENTRY_DELETED) {
	/*
	 * Just abort early if we entered here while being deleted.
	 */
	return NULL;
    }

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && entryPtr->textVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        entryPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        EntryTextVarProc, probe);
                if (probe == (ClientData)entryPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not







|

|
|




<
<















|






|







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
 *	The text displayed in the entry will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
EntryTextVarProc(
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),
    TCL_UNUSED(const char *),
    int flags)			/* Information about what happened. */
{
    Entry *entryPtr = (Entry *)clientData;
    const char *value;



    if (entryPtr->flags & ENTRY_DELETED) {
	/*
	 * Just abort early if we entered here while being deleted.
	 */
	return NULL;
    }

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && entryPtr->textVarName) {
            void *probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        entryPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        EntryTextVarProc, probe);
                if (probe == entryPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407

static int
EntryValidateChange(
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *change,	/* Characters to be added/deleted
				 * (NUL-terminated string). */
     const char *newValue,	/* Potential new value of entry string */
     TkSizeT index,			/* index of insert/delete, -1 otherwise */
     int type)			/* forced, delete, insert, focusin or
				 * focusout */
{
    int code, varValidate = (entryPtr->flags & VALIDATE_VAR);
    char *p;
    Tcl_DString script;








|







3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402

static int
EntryValidateChange(
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *change,	/* Characters to be added/deleted
				 * (NUL-terminated string). */
     const char *newValue,	/* Potential new value of entry string */
     Tcl_Size index,			/* index of insert/delete, TCL_INDEX_NONE otherwise */
     int type)			/* forced, delete, insert, focusin or
				 * focusout */
{
    int code, varValidate = (entryPtr->flags & VALIDATE_VAR);
    char *p;
    Tcl_DString script;

3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
	    int result;

	    Tcl_DStringInit(&script);
	    ExpandPercents(entryPtr, entryPtr->invalidCmd,
		    change, newValue, index, type, &script);
	    Tcl_DStringAppend(&script, "", 1);
	    p = Tcl_DStringValue(&script);
	    result = Tcl_EvalEx(entryPtr->interp, p, -1,
		    TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(entryPtr->interp,
			"\n    (in invalidcommand executed by entry)");
		Tcl_BackgroundException(entryPtr->interp, result);
		code = TCL_ERROR;
		entryPtr->validate = VALIDATE_NONE;







|







3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
	    int result;

	    Tcl_DStringInit(&script);
	    ExpandPercents(entryPtr, entryPtr->invalidCmd,
		    change, newValue, index, type, &script);
	    Tcl_DStringAppend(&script, "", 1);
	    p = Tcl_DStringValue(&script);
	    result = Tcl_EvalEx(entryPtr->interp, p, TCL_INDEX_NONE,
		    TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(entryPtr->interp,
			"\n    (in invalidcommand executed by entry)");
		Tcl_BackgroundException(entryPtr->interp, result);
		code = TCL_ERROR;
		entryPtr->validate = VALIDATE_NONE;
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *before,
				/* Command containing percent expressions to
				 * be replaced. */
     const char *change,	/* Characters to added/deleted (NUL-terminated
				 * string). */
     const char *newValue,	/* Potential new value of entry string */
     TkSizeT index,			/* index of insert/delete */
     int type,			/* INSERT or DELETE */
     Tcl_DString *dsPtr)	/* Dynamic string in which to append new
				 * command. */
{
    int spaceNeeded, cvtFlags;	/* Used to substitute string as proper Tcl
				 * list element. */
    int number, length;







|







3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *before,
				/* Command containing percent expressions to
				 * be replaced. */
     const char *change,	/* Characters to added/deleted (NUL-terminated
				 * string). */
     const char *newValue,	/* Potential new value of entry string */
     Tcl_Size index,			/* index of insert/delete */
     int type,			/* INSERT or DELETE */
     Tcl_DString *dsPtr)	/* Dynamic string in which to append new
				 * command. */
{
    int spaceNeeded, cvtFlags;	/* Used to substitute string as proper Tcl
				 * list element. */
    int number, length;
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

	/*
	 * No need to convert '%', as it is in ascii range.
	 */

	string = Tcl_UtfFindFirst(before, '%');
	if (string == NULL) {
	    Tcl_DStringAppend(dsPtr, before, -1);
	    break;
	} else if (string != before) {
	    Tcl_DStringAppend(dsPtr, before, string-before);
	    before = string;
	}

	/*
	 * There's a percent sequence here. Process it.
	 */

	before++; /* skip over % */
	if (*before != '\0') {
	    before += TkUtfToUniChar(before, &ch);
	} else {
	    ch = '%';
	}
	if (type == VALIDATE_BUTTON) {
	    /*
	     * -command %-substitution
	     */

	    switch (ch) {
	    case 's':		/* Current string value of spinbox */
		string = entryPtr->string;
		break;
	    case 'd':		/* direction, up or down */
		string = change;
		break;
	    case 'W':		/* widget name */
		string = Tk_PathName(entryPtr->tkwin);
		break;
	    default:
		length = TkUniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	} else {
	    /*
	     * -validatecommand / -invalidcommand %-substitution







|












|



















|







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

	/*
	 * No need to convert '%', as it is in ascii range.
	 */

	string = Tcl_UtfFindFirst(before, '%');
	if (string == NULL) {
	    Tcl_DStringAppend(dsPtr, before, TCL_INDEX_NONE);
	    break;
	} else if (string != before) {
	    Tcl_DStringAppend(dsPtr, before, string-before);
	    before = string;
	}

	/*
	 * There's a percent sequence here. Process it.
	 */

	before++; /* skip over % */
	if (*before != '\0') {
	    before += Tcl_UtfToUniChar(before, &ch);
	} else {
	    ch = '%';
	}
	if (type == VALIDATE_BUTTON) {
	    /*
	     * -command %-substitution
	     */

	    switch (ch) {
	    case 's':		/* Current string value of spinbox */
		string = entryPtr->string;
		break;
	    case 'd':		/* direction, up or down */
		string = change;
		break;
	    case 'W':		/* widget name */
		string = Tk_PathName(entryPtr->tkwin);
		break;
	    default:
		length = Tcl_UniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	} else {
	    /*
	     * -validatecommand / -invalidcommand %-substitution
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
		case VALIDATE_DELETE:
		    number = 0;
		    break;
		default:
		    number = -1;
		    break;
		}
		sprintf(numStorage, "%d", number);
		string = numStorage;
		break;
	    case 'i':		/* index of insert/delete */
		sprintf(numStorage, "%d", (int)index);
		string = numStorage;
		break;
	    case 'P':		/* 'Peeked' new value of the string */
		string = newValue;
		break;
	    case 's':		/* Current string value of spinbox */
		string = entryPtr->string;







|



|







3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
		case VALIDATE_DELETE:
		    number = 0;
		    break;
		default:
		    number = -1;
		    break;
		}
		snprintf(numStorage, sizeof(numStorage), "%d", number);
		string = numStorage;
		break;
	    case 'i':		/* index of insert/delete */
		snprintf(numStorage, sizeof(numStorage), "%d", (int)index);
		string = numStorage;
		break;
	    case 'P':		/* 'Peeked' new value of the string */
		string = newValue;
		break;
	    case 's':		/* Current string value of spinbox */
		string = entryPtr->string;
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
		    break;
		}
		break;
	    case 'W': /* widget name */
		string = Tk_PathName(entryPtr->tkwin);
		break;
	    default:
		length = TkUniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	}

	spaceNeeded = Tcl_ScanCountedElement(string, -1, &cvtFlags);
	length = Tcl_DStringLength(dsPtr);
	Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	spaceNeeded = Tcl_ConvertCountedElement(string, -1,
		Tcl_DStringValue(dsPtr) + length,
		cvtFlags | TCL_DONT_USE_BRACES);
	Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
    }
}

/*







|






|


|







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
		    break;
		}
		break;
	    case 'W': /* widget name */
		string = Tk_PathName(entryPtr->tkwin);
		break;
	    default:
		length = Tcl_UniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	    }
	}

	spaceNeeded = Tcl_ScanCountedElement(string, TCL_INDEX_NONE, &cvtFlags);
	length = Tcl_DStringLength(dsPtr);
	Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
	spaceNeeded = Tcl_ConvertCountedElement(string, TCL_INDEX_NONE,
		Tcl_DStringValue(dsPtr) + length,
		cvtFlags | TCL_DONT_USE_BRACES);
	Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
    }
}

/*
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
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SpinboxObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr;
    Spinbox *sbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),







|









<







3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708

3709
3710
3711
3712
3713
3714
3715
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SpinboxObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr;
    Spinbox *sbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    char *tmp;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
SpinboxWidgetObjCmd(
    ClientData clientData,	/* Information about spinbox widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr = (Entry *)clientData;
    Spinbox *sbPtr = (Spinbox *)clientData;
    int cmdIndex, selIndex, result;







|







3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
SpinboxWidgetObjCmd(
    void *clientData,	/* Information about spinbox widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Entry *entryPtr = (Entry *)clientData;
    Spinbox *sbPtr = (Spinbox *)clientData;
    int cmdIndex, selIndex, result;
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    case SB_CMD_BBOX: {
	TkSizeT index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index + 1 > 1)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewWideIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewWideIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewWideIntObj(width);
	bbox[3] = Tcl_NewWideIntObj(height);







|











|







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
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    case SB_CMD_BBOX: {
	Tcl_Size index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index > 0)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewWideIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewWideIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewWideIntObj(width);
	bbox[3] = Tcl_NewWideIntObj(height);
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
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case SB_CMD_DELETE: {
	TkSizeT first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else {
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &last) != TCL_OK) {
		goto error;
	    }
	}
	if ((last + 1 >= first + 1) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case SB_CMD_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1));
	break;

    case SB_CMD_ICURSOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pos");
	    goto error;
	}







|


















|













|







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
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case SB_CMD_DELETE: {
	Tcl_Size first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else {
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &last) != TCL_OK) {
		goto error;
	    }
	}
	if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case SB_CMD_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, TCL_INDEX_NONE));
	break;

    case SB_CMD_ICURSOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pos");
	    goto error;
	}
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 ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) ||
		(Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    goto error;
	}
	elem = GetSpinboxElement(sbPtr, x, y);
	if (elem != SEL_NONE) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(selElementNames[elem], -1));
	}
	break;
    }

    case SB_CMD_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case SB_CMD_INSERT: {
	TkSizeT index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],







|





|














|







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
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) ||
		(Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    goto error;
	}
	elem = GetSpinboxElement(sbPtr, x, y);
	if (elem != SEL_NONE) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(selElementNames[elem], TCL_INDEX_NONE));
	}
	break;
    }

    case SB_CMD_INDEX: {
	Tcl_Size index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case SB_CMD_INSERT: {
	Tcl_Size index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
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
	    entryPtr->scanMarkX = x;
	    entryPtr->scanMarkIndex = entryPtr->leftIndex;
	} else if ((minorCmd[0] == 'd')
		&& (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) {
	    EntryScanTo(entryPtr, x);
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scan option \"%s\": must be mark or dragto",
		    minorCmd));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case SB_CMD_SELECTION: {
	TkSizeT index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*







|









|







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
	    entryPtr->scanMarkX = x;
	    entryPtr->scanMarkIndex = entryPtr->leftIndex;
	} else if ((minorCmd[0] == 'd')
		&& (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) {
	    EntryScanTo(entryPtr, x);
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scan option \"%s\": must be dragto or mark",
		    minorCmd));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option",
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case SB_CMD_SELECTION: {
	Tcl_Size index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		TkSizeT half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}







|



|

|







4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		Tcl_Size half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index < half1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index > half2) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[4],& index2) != TCL_OK) {
		goto error;
	    }
	    if (index + 1 >= index2 + 1) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)







|







4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[4],& index2) != TCL_OK) {
		goto error;
	    }
	    if (index >= index2) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
	case SB_SEL_ELEMENT:
	    if ((objc < 3) || (objc > 4)) {
		Tcl_WrongNumArgs(interp, 3, objv, "?elemName?");
		goto error;
	    }
	    if (objc == 3) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			selElementNames[sbPtr->selElement], -1));
	    } else {
		int lastElement = sbPtr->selElement;

		result = Tcl_GetIndexFromObj(interp, objv[3], selElementNames,
			"selection element", 0, &(sbPtr->selElement));
		if (result != TCL_OK) {
		    goto error;







|







4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
	case SB_SEL_ELEMENT:
	    if ((objc < 3) || (objc > 4)) {
		Tcl_WrongNumArgs(interp, 3, objv, "?elemName?");
		goto error;
	    }
	    if (objc == 3) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			selElementNames[sbPtr->selElement], TCL_INDEX_NONE));
	    } else {
		int lastElement = sbPtr->selElement;

		result = Tcl_GetIndexFromObj(interp, objv[3], selElementNames,
			"selection element", 0, &(sbPtr->selElement));
		if (result != TCL_OK) {
		    goto error;
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
	}
	if (objc == 3) {
	    code = EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
            if (code != TCL_OK) {
                goto error;
            }
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1));
	break;
    }

    case SB_CMD_VALIDATE: {
	int code;

	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	selIndex = entryPtr->validate;
	entryPtr->validate = VALIDATE_ALL;
	code = EntryValidateChange(entryPtr, NULL, entryPtr->string,
		-1, VALIDATE_FORCED);
	if (entryPtr->validate != VALIDATE_NONE) {
	    entryPtr->validate = selIndex;
	}

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case SB_CMD_XVIEW: {
	TkSizeT index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);







|













|









|







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
	}
	if (objc == 3) {
	    code = EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
            if (code != TCL_OK) {
                goto error;
            }
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, TCL_INDEX_NONE));
	break;
    }

    case SB_CMD_VALIDATE: {
	int code;

	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	selIndex = entryPtr->validate;
	entryPtr->validate = VALIDATE_ALL;
	code = EntryValidateChange(entryPtr, NULL, entryPtr->string,
		TCL_INDEX_NONE, VALIDATE_FORCED);
	if (entryPtr->validate != VALIDATE_NONE) {
	    entryPtr->validate = selIndex;
	}

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case SB_CMD_XVIEW: {
	Tcl_Size index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308


4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {
	    case TK_SCROLL_ERROR:
		goto error;
	    case TK_SCROLL_MOVETO:
		index = ((fraction * entryPtr->numChars) + 0.5);
		break;
	    case TK_SCROLL_PAGES: {
		int charsPerPage;

		charsPerPage = ((Tk_Width(entryPtr->tkwin)
			- 2 * entryPtr->inset - entryPtr->xWidth)
			/ entryPtr->avgWidth) - 2;
		if (charsPerPage < 1) {
		    charsPerPage = 1;
		}
		index += count * charsPerPage;
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;


	    }
	}
	if (index + 1 >= entryPtr->numChars + 1) {
	    index = entryPtr->numChars - 1;
	}
	if (index == TCL_INDEX_NONE) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;







<
<


















>
>


|


|







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
	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {


	    case TK_SCROLL_MOVETO:
		index = ((fraction * entryPtr->numChars) + 0.5);
		break;
	    case TK_SCROLL_PAGES: {
		int charsPerPage;

		charsPerPage = ((Tk_Width(entryPtr->tkwin)
			- 2 * entryPtr->inset - entryPtr->xWidth)
			/ entryPtr->avgWidth) - 2;
		if (charsPerPage < 1) {
		    charsPerPage = 1;
		}
		index += count * charsPerPage;
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;
	    default:
		goto error;
	    }
	}
	if (index >= entryPtr->numChars) {
	    index = entryPtr->numChars - 1;
	}
	if (index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
	    if (strcmp(Tcl_GetString(objPtr), entryPtr->string)) {
		/*
		 * Somehow the string changed from what we expected, so let's
		 * do a search on the list to see if the current value is
		 * there. If not, move to the first element of the list.
		 */

		int i, listc;
		TkSizeT elemLen, length = entryPtr->numChars;
		const char *bytes;
		Tcl_Obj **listv;

		Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
		for (i = 0; i < listc; i++) {
		    bytes = TkGetStringFromObj(listv[i], &elemLen);
		    if ((length == elemLen) &&
			    (memcmp(bytes, entryPtr->string,
				    length) == 0)) {
			sbPtr->eIndex = i;
			break;
		    }
		}







|
|





|







4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
	    if (strcmp(Tcl_GetString(objPtr), entryPtr->string)) {
		/*
		 * Somehow the string changed from what we expected, so let's
		 * do a search on the list to see if the current value is
		 * there. If not, move to the first element of the list.
		 */

		Tcl_Size i, listc;
		Tcl_Size elemLen, length = entryPtr->numChars;
		const char *bytes;
		Tcl_Obj **listv;

		Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
		for (i = 0; i < listc; i++) {
		    bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
		    if ((length == elemLen) &&
			    (memcmp(bytes, entryPtr->string,
				    length) == 0)) {
			sbPtr->eIndex = i;
			break;
		    }
		}
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
		     * greater than the toValue, because the user may have
		     * manipulated the value by hand.
		     */

		    dvalue = sbPtr->toValue;
		}
	    }
	    sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
	    code = EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }
    if (code != TCL_OK) {
        return TCL_ERROR;
    }

    if (sbPtr->command != NULL) {
	Tcl_DStringInit(&script);
	ExpandPercents(entryPtr, sbPtr->command, type, "", 0,
		VALIDATE_BUTTON, &script);
	Tcl_DStringAppend(&script, "", 1);

	code = Tcl_EvalEx(interp, Tcl_DStringValue(&script), -1,
		TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	Tcl_DStringFree(&script);

	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (in command executed by spinbox)");
	    Tcl_BackgroundException(interp, code);







|













|







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
		     * greater than the toValue, because the user may have
		     * manipulated the value by hand.
		     */

		    dvalue = sbPtr->toValue;
		}
	    }
	    snprintf(sbPtr->formatBuf, TCL_DOUBLE_SPACE, sbPtr->valueFormat, dvalue);
	    code = EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }
    if (code != TCL_OK) {
        return TCL_ERROR;
    }

    if (sbPtr->command != NULL) {
	Tcl_DStringInit(&script);
	ExpandPercents(entryPtr, sbPtr->command, type, "", 0,
		VALIDATE_BUTTON, &script);
	Tcl_DStringAppend(&script, "", 1);

	code = Tcl_EvalEx(interp, Tcl_DStringValue(&script), TCL_INDEX_NONE,
		TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
	Tcl_DStringFree(&script);

	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (in command executed by spinbox)");
	    Tcl_BackgroundException(interp, code);
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
    if (afterDecimal > 0) {
	fDigits++;		/* Decimal point. */
    }
    if (mostSigDigit < 0) {
	fDigits++;		/* Zero to left of decimal point. */
    }
    if (fDigits <= eDigits) {
	sprintf(sbPtr->digitFormat, "%%.%df", afterDecimal);
    } else {
	sprintf(sbPtr->digitFormat, "%%.%de", numDigits-1);
    }
    sbPtr->valueFormat = sbPtr->digitFormat;
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|












4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
    if (afterDecimal > 0) {
	fDigits++;		/* Decimal point. */
    }
    if (mostSigDigit < 0) {
	fDigits++;		/* Zero to left of decimal point. */
    }
    if (fDigits <= eDigits) {
	snprintf(sbPtr->digitFormat, sizeof(sbPtr->digitFormat), "%%.%df", afterDecimal);
    } else {
	snprintf(sbPtr->digitFormat, sizeof(sbPtr->digitFormat), "%%.%de", numDigits-1);
    }
    sbPtr->valueFormat = sbPtr->digitFormat;
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkEntry.h.

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.
 */

#ifndef _TKENTRY
#define _TKENTRY

#ifndef _TKINT
#include "tkInt.h"








|







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 © 2002 Apple Inc.
 */

#ifndef _TKENTRY
#define _TKENTRY

#ifndef _TKINT
#include "tkInt.h"
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

    /*
     * Fields that are set by widget commands other than "configure".
     */

    const char *string;		/* Pointer to storage for string;
				 * NULL-terminated; malloc-ed. */
    TkSizeT insertPos;		/* Character index before which next typed
				 * character will be inserted. */

    /*
     * Information about what's selected, if any.
     */

    TkSizeT selectFirst;		/* Character index of first selected character
				 * (-1 means nothing selected. */
    TkSizeT selectLast;		/* Character index just after last selected
				 * character (-1 means nothing selected. */
    TkSizeT selectAnchor;		/* Fixed end of selection (i.e. "select to"
				 * operation will use this as one end of the
				 * selection). */

    /*
     * Information for scanning:
     */








|






|

|

|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

    /*
     * Fields that are set by widget commands other than "configure".
     */

    const char *string;		/* Pointer to storage for string;
				 * NULL-terminated; malloc-ed. */
    Tcl_Size insertPos;		/* Character index before which next typed
				 * character will be inserted. */

    /*
     * Information about what's selected, if any.
     */

    Tcl_Size selectFirst;		/* Character index of first selected character
				 * (-1 means nothing selected. */
    Tcl_Size selectLast;		/* Character index just after last selected
				 * character (-1 means nothing selected. */
    Tcl_Size selectAnchor;		/* Fixed end of selection (i.e. "select to"
				 * operation will use this as one end of the
				 * selection). */

    /*
     * Information for scanning:
     */

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

    /*
     * Fields used in displaying help text if entry value is empty
     */

    Tk_TextLayout placeholderLayout;/* Cached placeholder text layout information. */
    char *placeholderString;	/* String value of placeholder. */
    TkSizeT placeholderChars;	/* Number of chars in placeholder. */
    XColor *placeholderColorPtr;/* Color value of placeholder foreground. */
    GC placeholderGC;		/* For drawing placeholder text. */
    int placeholderX;		/* Origin for layout. */
    int placeholderLeftIndex;	/* Character index of left-most character
				 * visible in window. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    const char *displayString;	/* String to use when displaying. This may be
				 * a pointer to string, or a pointer to
				 * malloced memory with the same character
				 * length as string but whose characters are
				 * all equal to showChar. */
    TkSizeT numBytes;		/* Length of string in bytes. */
    TkSizeT numChars;		/* Length of string in characters. Both string
				 * and displayString have the same character
				 * length, but may have different byte lengths
				 * due to being made from different UTF-8
				 * characters. */
    TkSizeT numDisplayBytes;	/* Length of displayString in bytes. */
    int inset;			/* Number of pixels on the left and right
				 * sides that are taken up by XPAD,
				 * borderWidth (if any), and highlightWidth
				 * (if any). */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int layoutX, layoutY;	/* Origin for layout. */
    int leftX;			/* X position at which character at leftIndex
				 * is drawn (varies depending on justify). */
    TkSizeT leftIndex;		/* Character index of left-most character
				 * visible in window. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    GC textGC;			/* For drawing normal text. */
    GC selTextGC;		/* For drawing selected text. */
    GC highlightGC;		/* For drawing traversal highlight. */







|
















|
|




|








|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

    /*
     * Fields used in displaying help text if entry value is empty
     */

    Tk_TextLayout placeholderLayout;/* Cached placeholder text layout information. */
    char *placeholderString;	/* String value of placeholder. */
    Tcl_Size placeholderChars;	/* Number of chars in placeholder. */
    XColor *placeholderColorPtr;/* Color value of placeholder foreground. */
    GC placeholderGC;		/* For drawing placeholder text. */
    int placeholderX;		/* Origin for layout. */
    int placeholderLeftIndex;	/* Character index of left-most character
				 * visible in window. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    const char *displayString;	/* String to use when displaying. This may be
				 * a pointer to string, or a pointer to
				 * malloced memory with the same character
				 * length as string but whose characters are
				 * all equal to showChar. */
    Tcl_Size numBytes;		/* Length of string in bytes. */
    Tcl_Size numChars;		/* Length of string in characters. Both string
				 * and displayString have the same character
				 * length, but may have different byte lengths
				 * due to being made from different UTF-8
				 * characters. */
    Tcl_Size numDisplayBytes;	/* Length of displayString in bytes. */
    int inset;			/* Number of pixels on the left and right
				 * sides that are taken up by XPAD,
				 * borderWidth (if any), and highlightWidth
				 * (if any). */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int layoutX, layoutY;	/* Origin for layout. */
    int leftX;			/* X position at which character at leftIndex
				 * is drawn (varies depending on justify). */
    Tcl_Size leftIndex;		/* Character index of left-most character
				 * visible in window. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    GC textGC;			/* For drawing normal text. */
    GC selTextGC;		/* For drawing selected text. */
    GC highlightGC;		/* For drawing traversal highlight. */
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    double fromValue;		/* Value corresponding to left/top of dial */
    double toValue;		/* Value corresponding to right/bottom of
				 * dial */
    double increment;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    char *formatBuf;		/* string into which to format value.
				 * Malloc'ed. */
    char *reqFormat;		/* Sprintf conversion specifier used for the
				 * value that the users requests. Malloc'ed */
    char *valueFormat;		/* Sprintf conversion specifier used for the
				 * value. */
    char digitFormat[16];	/* Sprintf conversion specifier computed from
				 * digits and other information; used for the
				 * value. */

    char *valueStr;		/* Values List. Malloc'ed. */
    Tcl_Obj *listObj;		/* Pointer to the list object being used */
    int eIndex;			/* Holds the current index into elements */
    int nElements;		/* Holds the current count of elements */







|

|

|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    double fromValue;		/* Value corresponding to left/top of dial */
    double toValue;		/* Value corresponding to right/bottom of
				 * dial */
    double increment;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    char *formatBuf;		/* string into which to format value.
				 * Malloc'ed. */
    char *reqFormat;		/* Snprintf conversion specifier used for the
				 * value that the users requests. Malloc'ed */
    char *valueFormat;		/* Snprintf conversion specifier used for the
				 * value. */
    char digitFormat[16];	/* Snprintf conversion specifier computed from
				 * digits and other information; used for the
				 * value. */

    char *valueStr;		/* Values List. Malloc'ed. */
    Tcl_Obj *listObj;		/* Pointer to the list object being used */
    int eIndex;			/* Holds the current index into elements */
    int nElements;		/* Holds the current count of elements */
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

/*
 * This is the element index corresponding to the strings in selElementNames.
 * If you modify them, you must modify the numbers here.
 */

enum selelement {
    SEL_NONE, SEL_BUTTONDOWN, SEL_BUTTONUP, SEL_NULL, SEL_ENTRY
};

/*
 * Declaration of functions used in the implementation of the native side of
 * the Entry widget.
 */

MODULE_SCOPE int	TkpDrawEntryBorderAndFocus(Entry *entryPtr,
			    Drawable d, int isSpinbox);
MODULE_SCOPE int	TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d);

#endif /* _TKENTRY */







|












292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

/*
 * This is the element index corresponding to the strings in selElementNames.
 * If you modify them, you must modify the numbers here.
 */

enum selelement {
    SEL_BUTTONDOWN, SEL_BUTTONUP, SEL_NONE, SEL_NULL, SEL_ENTRY
};

/*
 * Declaration of functions used in the implementation of the native side of
 * the Entry widget.
 */

MODULE_SCOPE int	TkpDrawEntryBorderAndFocus(Entry *entryPtr,
			    Drawable d, int isSpinbox);
MODULE_SCOPE int	TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d);

#endif /* _TKENTRY */

Changes to generic/tkError.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









|
|







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 © 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"

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
				 * codes). */
    int minorCode,		/* Consider only errors with this minor
				 * request code (-1 means consider all minor
				 * codes). */
    Tk_ErrorProc *errorProc,	/* Procedure to invoke when a matching error
				 * occurs. NULL means just ignore matching
				 * errors. */
    ClientData clientData)	/* Arbitrary value to pass to errorProc. */
{
    TkErrorHandler *errorPtr;
    TkDisplay *dispPtr;

    /*
     * Find the display. If Tk doesn't know about this display then it's an
     * error: panic.







|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
				 * codes). */
    int minorCode,		/* Consider only errors with this minor
				 * request code (-1 means consider all minor
				 * codes). */
    Tk_ErrorProc *errorProc,	/* Procedure to invoke when a matching error
				 * occurs. NULL means just ignore matching
				 * errors. */
    void *clientData)	/* Arbitrary value to pass to errorProc. */
{
    TkErrorHandler *errorPtr;
    TkDisplay *dispPtr;

    /*
     * Find the display. If Tk doesn't know about this display then it's an
     * error: panic.

Changes to generic/tkEvent.c.

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
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|
|
|
|







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 © 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"

119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
    0,					/* SelectionNotify */
    ColormapChangeMask,			/* ColormapNotify */
    0,					/* ClientMessage */
    0,					/* Mapping Notify */
    VirtualEventMask,			/* VirtualEvents */
    ActivateMask,			/* ActivateNotify */
    ActivateMask,			/* DeactivateNotify */
    MouseWheelMask			/* MouseWheelEvent */

};

/*
 * For each exit handler created with a call to TkCreateExitHandler or
 * TkCreateThreadExitHandler there is a structure of the following type:
 */








|
>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    0,					/* SelectionNotify */
    ColormapChangeMask,			/* ColormapNotify */
    0,					/* ClientMessage */
    0,					/* Mapping Notify */
    VirtualEventMask,			/* VirtualEvents */
    ActivateMask,			/* ActivateNotify */
    ActivateMask,			/* DeactivateNotify */
    MouseWheelMask,			/* MouseWheelEvent */
    TouchpadScrollMask			/* TouchpadScroll */
};

/*
 * For each exit handler created with a call to TkCreateExitHandler or
 * TkCreateThreadExitHandler there is a structure of the following type:
 */

1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
    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.







>
|
|
|
|
|
|
|
|
|
|
>







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
    InProgress ip;
    Tcl_Interp *interp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


#if !defined(_WIN32) && !defined(MAC_OSX_TK)
    if ((eventPtr->type == ButtonRelease) || (eventPtr->type == ButtonPress)) {
	if ((eventPtr->xbutton.button >= Button4) && (eventPtr->xbutton.button < Button8)) {
	    if (eventPtr->type == ButtonRelease) {
		return;
	    } else { /* 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.
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
 *
 *----------------------------------------------------------------------
 */

void
TkCreateExitHandler(
    Tcl_ExitProc *proc,		/* Function to invoke. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;

    exitPtr = (ExitHandler *)ckalloc(sizeof(ExitHandler));
    exitPtr->proc = proc;
    exitPtr->clientData = clientData;
    Tcl_MutexLock(&exitMutex);







|







1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
 *
 *----------------------------------------------------------------------
 */

void
TkCreateExitHandler(
    Tcl_ExitProc *proc,		/* Function to invoke. */
    void *clientData)	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;

    exitPtr = (ExitHandler *)ckalloc(sizeof(ExitHandler));
    exitPtr->proc = proc;
    exitPtr->clientData = clientData;
    Tcl_MutexLock(&exitMutex);
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017

/*
 *----------------------------------------------------------------------
 *
 * TkFinalize --
 *
 *	Runs our private exit handlers and removes itself from Tcl. This is
 *	benificial should we want to protect from dangling pointers should the
 *	Tk shared library be unloaded prior to Tcl which can happen on windows
 *	should the process be forcefully exiting from an exception handler.
 *
 * Results:
 *	None.
 *
 * Side effects.







|







2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020

/*
 *----------------------------------------------------------------------
 *
 * TkFinalize --
 *
 *	Runs our private exit handlers and removes itself from Tcl. This is
 *	beneficial should we want to protect from dangling pointers should the
 *	Tk shared library be unloaded prior to Tcl which can happen on windows
 *	should the process be forcefully exiting from an exception handler.
 *
 * Results:
 *	None.
 *
 * Side effects.

Changes to generic/tkFileFilter.c.

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.
 *
 * 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"






|







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 © 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"
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
int
TkGetFileFilters(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    FileFilterList *flistPtr,	/* Stores the list of file filters. */
    Tcl_Obj *types,		/* Value of the -filetypes option. */
    int isWindows)		/* True if we are running on Windows. */
{
    int listObjc;
    Tcl_Obj ** listObjv = NULL;
    int i;

    if (types == NULL) {
	return TCL_OK;
    }

    if (Tcl_ListObjGetElements(interp, types, &listObjc,
	    &listObjv) != TCL_OK) {







|

<







75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
int
TkGetFileFilters(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    FileFilterList *flistPtr,	/* Stores the list of file filters. */
    Tcl_Obj *types,		/* Value of the -filetypes option. */
    int isWindows)		/* True if we are running on Windows. */
{
    Tcl_Size i, listObjc;
    Tcl_Obj ** listObjv = NULL;


    if (types == NULL) {
	return TCL_OK;
    }

    if (Tcl_ListObjGetElements(interp, types, &listObjc,
	    &listObjv) != TCL_OK) {
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    for (i = 0; i<listObjc; i++) {
	/*
	 * Each file type should have two or three elements: the first one is
	 * the name of the type and the second is the filter of the type. The
	 * third is the Mac OSType ID, but we don't care about them here.
	 */

	int count;
	FileFilter *filterPtr;
	Tcl_Obj **typeInfo;

	if (Tcl_ListObjGetElements(interp, listObjv[i], &count,
		&typeInfo) != TCL_OK) {
	    return TCL_ERROR;
	}







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    for (i = 0; i<listObjc; i++) {
	/*
	 * Each file type should have two or three elements: the first one is
	 * the name of the type and the second is the filter of the type. The
	 * third is the Mac OSType ID, but we don't care about them here.
	 */

	Tcl_Size count;
	FileFilter *filterPtr;
	Tcl_Obj **typeInfo;

	if (Tcl_ListObjGetElements(interp, listObjv[i], &count,
		&typeInfo) != TCL_OK) {
	    return TCL_ERROR;
	}
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
    Tcl_Obj *ostypesObj,	/* A Tcl list of Mac OSType strings. */
    int isWindows)		/* True if we are running on Windows; False if
				 * we are running on the Mac; Glob patterns
				 * need to be processed differently on these
				 * two platforms */
{
    Tcl_Obj **globList = NULL, **ostypeList = NULL;
    int globCount, ostypeCount, i, code = TCL_OK;

    FileFilterClause *clausePtr;
    Tcl_Encoding macRoman = NULL;

    if (Tcl_ListObjGetElements(interp, patternsObj,
	    &globCount, &globList) != TCL_OK) {
	code = TCL_ERROR;
	goto done;







|
>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    Tcl_Obj *ostypesObj,	/* A Tcl list of Mac OSType strings. */
    int isWindows)		/* True if we are running on Windows; False if
				 * we are running on the Mac; Glob patterns
				 * need to be processed differently on these
				 * two platforms */
{
    Tcl_Obj **globList = NULL, **ostypeList = NULL;
    Tcl_Size globCount, ostypeCount, i;
    int code = TCL_OK;
    FileFilterClause *clausePtr;
    Tcl_Encoding macRoman = NULL;

    if (Tcl_ListObjGetElements(interp, patternsObj,
	    &globCount, &globList) != TCL_OK) {
	code = TCL_ERROR;
	goto done;
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	/*
	 * Might be cleaner to use 'Tcl_GetOSTypeFromObj' but that is actually
	 * static to the MacOS X/Darwin version of Tcl, and would therefore
	 * require further code refactoring.
	 */

	for (i=0; i<ostypeCount; i++) {
	    TkSizeT len;
	    const char *strType = TkGetStringFromObj(ostypeList[i], &len);

	    /*
	     * If len is < 4, it is definitely an error. If equal or longer,
	     * we need to use the macRoman encoding to determine the correct
	     * length (assuming there may be non-ascii characters, e.g.,
	     * embedded nulls or accented characters in the string, the
	     * macRoman length will be different).







|
|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	/*
	 * Might be cleaner to use 'Tcl_GetOSTypeFromObj' but that is actually
	 * static to the MacOS X/Darwin version of Tcl, and would therefore
	 * require further code refactoring.
	 */

	for (i=0; i<ostypeCount; i++) {
	    Tcl_Size 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).
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
		Tcl_DString osTypeDS;

		/*
		 * Convert utf to macRoman, since MacOS types are defined to
		 * be 4 macRoman characters long
		 */

		Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
		len = Tcl_DStringLength(&osTypeDS);
		Tcl_DStringFree(&osTypeDS);
	    }
	    if (len != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad Macintosh file type \"%s\"",
			Tcl_GetString(ostypeList[i])));







|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
		Tcl_DString osTypeDS;

		/*
		 * Convert utf to macRoman, since MacOS types are defined to
		 * be 4 macRoman characters long
		 */

		(void)Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
		len = Tcl_DStringLength(&osTypeDS);
		Tcl_DStringFree(&osTypeDS);
	    }
	    if (len != 4) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad Macintosh file type \"%s\"",
			Tcl_GetString(ostypeList[i])));
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
	filterPtr->clausesTail = clausePtr;
    }
    clausePtr->next = NULL;

    if (globCount > 0 && globList != NULL) {
	for (i=0; i<globCount; i++) {
	    GlobPattern *globPtr = (GlobPattern *)ckalloc(sizeof(GlobPattern));
	    TkSizeT len;
	    const char *str = TkGetStringFromObj(globList[i], &len);

	    len = (len + 1) * sizeof(char);
	    if (str[0] && str[0] != '*') {
		/*
		 * Prepend a "*" to patterns that do not have a leading "*"
		 */








|
|







318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
	filterPtr->clausesTail = clausePtr;
    }
    clausePtr->next = NULL;

    if (globCount > 0 && globList != NULL) {
	for (i=0; i<globCount; i++) {
	    GlobPattern *globPtr = (GlobPattern *)ckalloc(sizeof(GlobPattern));
	    Tcl_Size 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 "*"
		 */

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
    }
    if (ostypeList != NULL && ostypeCount > 0) {
	if (macRoman == NULL) {
	    macRoman = Tcl_GetEncoding(NULL, "macRoman");
	}
	for (i=0; i<ostypeCount; i++) {
	    Tcl_DString osTypeDS;
	    TkSizeT len;
	    MacFileType *mfPtr = (MacFileType *)ckalloc(sizeof(MacFileType));
	    const char *strType = TkGetStringFromObj(ostypeList[i], &len);
	    char *string;

	    /*
	     * Convert utf to macRoman, since MacOS types are defined to be 4
	     * macRoman characters long
	     */

	    Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
	    string = Tcl_DStringValue(&osTypeDS);
	    mfPtr->type = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
		    (OSType) string[2] <<  8 | (OSType) string[3];
	    Tcl_DStringFree(&osTypeDS);

	    /*
	     * Add the Mac type pattern into the list of Mac types
	     */







|

|







|
<







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
    }
    if (ostypeList != NULL && ostypeCount > 0) {
	if (macRoman == NULL) {
	    macRoman = Tcl_GetEncoding(NULL, "macRoman");
	}
	for (i=0; i<ostypeCount; i++) {
	    Tcl_DString osTypeDS;
	    Tcl_Size len;
	    MacFileType *mfPtr = (MacFileType *)ckalloc(sizeof(MacFileType));
	    const char *strType = Tcl_GetStringFromObj(ostypeList[i], &len);
	    char *string;

	    /*
	     * Convert utf to macRoman, since MacOS types are defined to be 4
	     * macRoman characters long
	     */

	    string = Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);

	    mfPtr->type = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
		    (OSType) string[2] <<  8 | (OSType) string[3];
	    Tcl_DStringFree(&osTypeDS);

	    /*
	     * Add the Mac type pattern into the list of Mac types
	     */

Changes to generic/tkFileFilter.h.

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.
 *
 * 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






|







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 © 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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|
|







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 © 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"

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

/*
 * Debugging support...
 */

#define DEBUG(dispPtr, arguments) \
    if ((dispPtr)->focusDebug) { \
	printf arguments; \
    }

/*
 * Forward declarations for functions defined in this file:
 */

static DisplayFocusInfo*FindDisplayFocusInfo(TkMainInfo *mainPtr,







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

/*
 * Debugging support...
 */

#define DEBUG(dispPtr, arguments) \
    if ((dispPtr)->focusDebug) { \
	printf arguments; fflush(stdout); \
    }

/*
 * Forward declarations for functions defined in this file:
 */

static DisplayFocusInfo*FindDisplayFocusInfo(TkMainInfo *mainPtr,
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
	 * Skip FocusIn events that cause confusion
	 * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur on
	 *	windows in between the origin and destination of the focus
	 *	change. For FocusIn we may see this when focus goes into an
	 *	embedded child. We don't care about this, although we may end
	 *	up getting a NotifyPointer later.
	 * NotifyInferior - focus is coming to us from an embedded child. When
	 *	focus is on an embeded focus, we still think we have the
	 *	focus, too, so this message doesn't change our state.
	 * NotifyPointerRoot - should never happen because this is sent to the
	 *	root window.
	 *
	 * Interesting FocusIn events are
	 * NotifyAncestor - focus is coming from our parent, probably the root.
	 * NotifyNonlinear - focus is coming from a different branch, probably







|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
	 * Skip FocusIn events that cause confusion
	 * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur on
	 *	windows in between the origin and destination of the focus
	 *	change. For FocusIn we may see this when focus goes into an
	 *	embedded child. We don't care about this, although we may end
	 *	up getting a NotifyPointer later.
	 * NotifyInferior - focus is coming to us from an embedded child. When
	 *	focus is on an embedded focus, we still think we have the
	 *	focus, too, so this message doesn't change our state.
	 * NotifyPointerRoot - should never happen because this is sent to the
	 *	root window.
	 *
	 * Interesting FocusIn events are
	 * NotifyAncestor - focus is coming from our parent, probably the root.
	 * NotifyNonlinear - focus is coming from a different branch, probably
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
	retValue = 1;
	if (eventPtr->xcrossing.detail == NotifyInferior) {
	    return retValue;
	}
    }

    /*
     * If winPtr isn't a top-level window than just ignore the event.
     */

    winPtr = TkWmFocusToplevel(winPtr);
    if (winPtr == NULL) {
	return retValue;
    }








|







365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
	retValue = 1;
	if (eventPtr->xcrossing.detail == NotifyInferior) {
	    return retValue;
	}
    }

    /*
     * If winPtr isn't a top-level window then just ignore the event.
     */

    winPtr = TkWmFocusToplevel(winPtr);
    if (winPtr == NULL) {
	return retValue;
    }

497
498
499
500
501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
	 * dispPtr->implicitWinPtr)!! In addition, we generate events because
	 * the window manager won't give us a FocusOut event when we focus on
	 * the root.
	 */

	if ((dispPtr->implicitWinPtr != NULL)
		&& !(winPtr->flags & TK_EMBEDDED)) {
	    DEBUG(dispPtr, ("Defocussed implicit Async\n"));
	    GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
	    XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot,
		    CurrentTime);
	    displayFocusPtr->focusWinPtr = NULL;
	    dispPtr->implicitWinPtr = NULL;

	}
    }
    return retValue;
}

/*
 *----------------------------------------------------------------------







|





>







497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
	 * dispPtr->implicitWinPtr)!! In addition, we generate events because
	 * the window manager won't give us a FocusOut event when we focus on
	 * the root.
	 */

	if ((dispPtr->implicitWinPtr != NULL)
		&& !(winPtr->flags & TK_EMBEDDED)) {
	    DEBUG(dispPtr, ("Defocussed implicit Async from %s\n", displayFocusPtr->focusWinPtr->pathName));
	    GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
	    XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot,
		    CurrentTime);
	    displayFocusPtr->focusWinPtr = NULL;
	    dispPtr->implicitWinPtr = NULL;
	    dispPtr->focusPtr = NULL;
	}
    }
    return retValue;
}

/*
 *----------------------------------------------------------------------
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
    if (topLevelPtr->flags & TK_EMBEDDED &&
        (displayFocusPtr->focusWinPtr == NULL)) {

	/*
	 * We are assigning focus to an embedded toplevel.  The platform
	 * specific function TkpClaimFocus needs to handle the job of
	 * assigning focus to the container, since we have no way to find the
	 * contaiuner.
	 */

	TkpClaimFocus(topLevelPtr, force);
    } else if ((displayFocusPtr->focusWinPtr != NULL) || force) {

	/*
	 * If we are forcing removal of focus from a container hosting a







|







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
    if (topLevelPtr->flags & TK_EMBEDDED &&
        (displayFocusPtr->focusWinPtr == NULL)) {

	/*
	 * We are assigning focus to an embedded toplevel.  The platform
	 * specific function TkpClaimFocus needs to handle the job of
	 * assigning focus to the container, since we have no way to find the
	 * container.
	 */

	TkpClaimFocus(topLevelPtr, force);
    } else if ((displayFocusPtr->focusWinPtr != NULL) || force) {

	/*
	 * If we are forcing removal of focus from a container hosting a
809
810
811
812
813
814
815

816
817
818
819
820
821
822
TkFocusDeadWindow(
    TkWindow *winPtr)	/* Information about the window that is being
				 * deleted. */
{
    ToplevelFocusInfo *tlFocusPtr, *prevPtr;
    DisplayFocusInfo *displayFocusPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;


    /*
     * Certain special windows like those used for send and clipboard have no
     * mainPtr.
     */

    if (winPtr->mainPtr == NULL) {







>







810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
TkFocusDeadWindow(
    TkWindow *winPtr)	/* Information about the window that is being
				 * deleted. */
{
    ToplevelFocusInfo *tlFocusPtr, *prevPtr;
    DisplayFocusInfo *displayFocusPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;
    int noMatch = 1;

    /*
     * Certain special windows like those used for send and clipboard have no
     * mainPtr.
     */

    if (winPtr->mainPtr == NULL) {
852
853
854
855
856
857
858

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892









893
894
895
896
897
898
899
	    }
	    if (prevPtr == NULL) {
		winPtr->mainPtr->tlFocusPtr = tlFocusPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = tlFocusPtr->nextPtr;
	    }
	    ckfree(tlFocusPtr);

	    break;
	} else if (winPtr == tlFocusPtr->focusWinPtr) {
	    /*
	     * The deleted window had the focus for its top-level: move the
	     * focus to the top-level itself.
	     */

	    tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
	    if ((displayFocusPtr->focusWinPtr == winPtr)
		    && !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) {
		DEBUG(dispPtr, ("forwarding focus to %s after %s died\n",
			tlFocusPtr->topLevelPtr->pathName, winPtr->pathName));
		GenerateFocusEvents(displayFocusPtr->focusWinPtr,
			tlFocusPtr->topLevelPtr);
		displayFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
		dispPtr->focusPtr = tlFocusPtr->topLevelPtr;
	    }

	    break;
	}
    }

    /*
     * Occasionally, things can become unsynchronized. Move them back into
     * synch now. [Bug 2496114]
     */

    if (displayFocusPtr->focusWinPtr == winPtr) {
	DEBUG(dispPtr, ("focus cleared after %s died\n", winPtr->pathName));
	displayFocusPtr->focusWinPtr = NULL;
    }

    if (displayFocusPtr->focusOnMapPtr == winPtr) {
	displayFocusPtr->focusOnMapPtr = NULL;
    }









}

/*
 *----------------------------------------------------------------------
 *
 * GenerateFocusEvents --
 *







>

















>

















>
>
>
>
>
>
>
>
>







854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
	    }
	    if (prevPtr == NULL) {
		winPtr->mainPtr->tlFocusPtr = tlFocusPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = tlFocusPtr->nextPtr;
	    }
	    ckfree(tlFocusPtr);
	    noMatch = 0;
	    break;
	} else if (winPtr == tlFocusPtr->focusWinPtr) {
	    /*
	     * The deleted window had the focus for its top-level: move the
	     * focus to the top-level itself.
	     */

	    tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
	    if ((displayFocusPtr->focusWinPtr == winPtr)
		    && !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) {
		DEBUG(dispPtr, ("forwarding focus to %s after %s died\n",
			tlFocusPtr->topLevelPtr->pathName, winPtr->pathName));
		GenerateFocusEvents(displayFocusPtr->focusWinPtr,
			tlFocusPtr->topLevelPtr);
		displayFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
		dispPtr->focusPtr = tlFocusPtr->topLevelPtr;
	    }
	    noMatch = 0;
	    break;
	}
    }

    /*
     * Occasionally, things can become unsynchronized. Move them back into
     * synch now. [Bug 2496114]
     */

    if (displayFocusPtr->focusWinPtr == winPtr) {
	DEBUG(dispPtr, ("focus cleared after %s died\n", winPtr->pathName));
	displayFocusPtr->focusWinPtr = NULL;
    }

    if (displayFocusPtr->focusOnMapPtr == winPtr) {
	displayFocusPtr->focusOnMapPtr = NULL;
    }

    /*
     * It may happen that the search above for focus records that refer
     * to this window did not find any match. In such a case, when the
     * dead window had the focus, release it.
     */
    if (noMatch && (dispPtr->focusPtr == winPtr)) {
	dispPtr->focusPtr = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateFocusEvents --
 *
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
 *
 *	Free resources associated with maintaining the focus.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This mainPtr should no long access focus information.
 *
 *----------------------------------------------------------------------
 */

void
TkFocusFree(
    TkMainInfo *mainPtr)	/* Record that identifies a particular







|







1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
 *
 *	Free resources associated with maintaining the focus.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This mainPtr should no longer access focus information.
 *
 *----------------------------------------------------------------------
 */

void
TkFocusFree(
    TkMainInfo *mainPtr)	/* Record that identifies a particular
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
}

/*
 *----------------------------------------------------------------------
 *
 * TkFocusJoin --
 *
 *	Remove the focus record for this window that is nolonger managed
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A tlFocusPtr record is removed
 *







|







1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
}

/*
 *----------------------------------------------------------------------
 *
 * TkFocusJoin --
 *
 *	Remove the focus record for this window that is no longer managed
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A tlFocusPtr record is removed
 *

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
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.
 *
 * 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.
 */







|
|










>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * 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 © 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

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following structure is used to keep track of all the fonts that exist
 * in the current application. It must be stored in the TkMainInfo for the
 * application.
 */

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 * token.
 */

typedef struct LayoutChunk {
    const char *start;		/* Pointer to simple string to be displayed.
				 * This is a pointer into the TkTextLayout's
				 * string. */
    int numBytes;		/* The number of bytes in this chunk. */
    int numChars;		/* The number of characters in this chunk. */
    int numDisplayChars;	/* The number of characters to display when
				 * this chunk is displayed. Can be less than
				 * numChars if extra space characters were
				 * absorbed by the end of the chunk. This will
				 * be < 0 if this is a chunk that is holding a
				 * tab or newline. */
    int x, y;			/* The origin of the first character in this
				 * chunk with respect to the upper-left hand







|
|
|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 * token.
 */

typedef struct LayoutChunk {
    const char *start;		/* Pointer to simple string to be displayed.
				 * This is a pointer into the TkTextLayout's
				 * string. */
    Tcl_Size numBytes;		/* The number of bytes in this chunk. */
    Tcl_Size numChars;		/* The number of characters in this chunk. */
    Tcl_Size numDisplayChars;	/* The number of characters to display when
				 * this chunk is displayed. Can be less than
				 * numChars if extra space characters were
				 * absorbed by the end of the chunk. This will
				 * be < 0 if this is a chunk that is holding a
				 * tab or newline. */
    int x, y;			/* The origin of the first character in this
				 * chunk with respect to the upper-left hand
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
} LayoutChunk;

typedef struct TextLayout {
    Tk_Font tkfont;		/* The font used when laying out the text. */
    const char *string;		/* The string that was layed out. */
    int width;			/* The maximum width of all lines in the text
				 * layout. */
    int numChunks;		/* Number of chunks actually used in following
				 * array. */
    LayoutChunk chunks[TKFLEXARRAY];/* Array of chunks. The actual size will be
				 * maxChunks. THIS FIELD MUST BE THE LAST IN
				 * THE STRUCTURE. */
} TextLayout;

/*







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
} LayoutChunk;

typedef struct TextLayout {
    Tk_Font tkfont;		/* The font used when laying out the text. */
    const char *string;		/* The string that was layed out. */
    int width;			/* The maximum width of all lines in the text
				 * layout. */
    Tcl_Size numChunks;		/* Number of chunks actually used in following
				 * array. */
    LayoutChunk chunks[TKFLEXARRAY];/* Array of chunks. The actual size will be
				 * maxChunks. THIS FIELD MUST BE THE LAST IN
				 * THE STRUCTURE. */
} TextLayout;

/*
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357


358
359
360
361
362
363
364
	((const TkFontAttributes *) &((TkFont *) (tkfont))->fa)

#define GetFontMetrics(tkfont)    \
	((const TkFontMetrics *) &((TkFont *) (tkfont))->fm)


static int		ConfigAttributesObj(Tcl_Interp *interp,
			    Tk_Window tkwin, int objc, Tcl_Obj *const objv[],
			    TkFontAttributes *faPtr);
static void		DupFontObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr);
static int		FieldSpecified(const char *field);
static void		FreeFontObj(Tcl_Obj *objPtr);
static void		FreeFontObjProc(Tcl_Obj *objPtr);
static int		GetAttributeInfoObj(Tcl_Interp *interp,
			    const TkFontAttributes *faPtr, Tcl_Obj *objPtr);
static LayoutChunk *	NewChunk(TextLayout **layoutPtrPtr, int *maxPtr,
			    const char *start, int numChars, int curX,
			    int newX, int y);
static int		ParseFontNameObj(Tcl_Interp *interp, Tk_Window tkwin,
			    Tcl_Obj *objPtr, TkFontAttributes *faPtr);
static void		RecomputeWidgets(TkWindow *winPtr);
static int		SetFontFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void		TheWorldHasChanged(ClientData clientData);
static void		UpdateDependentFonts(TkFontInfo *fiPtr,
			    Tk_Window tkwin, Tcl_HashEntry *namedHashPtr);

/*
 * The following structure defines the implementation of the "font" Tcl
 * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
 * font object points to the TkFont structure for the font, or NULL.
 */

const Tcl_ObjType tkFontObjType = {
    "font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *---------------------------------------------------------------------------
 *
 * TkFontPkgInit --
 *







|








|





|









|
|



|
>
>







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
	((const TkFontAttributes *) &((TkFont *) (tkfont))->fa)

#define GetFontMetrics(tkfont)    \
	((const TkFontMetrics *) &((TkFont *) (tkfont))->fm)


static int		ConfigAttributesObj(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Size objc, Tcl_Obj *const objv[],
			    TkFontAttributes *faPtr);
static void		DupFontObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr);
static int		FieldSpecified(const char *field);
static void		FreeFontObj(Tcl_Obj *objPtr);
static void		FreeFontObjProc(Tcl_Obj *objPtr);
static int		GetAttributeInfoObj(Tcl_Interp *interp,
			    const TkFontAttributes *faPtr, Tcl_Obj *objPtr);
static LayoutChunk *	NewChunk(TextLayout **layoutPtrPtr, int *maxPtr,
			    const char *start, Tcl_Size numChars, int curX,
			    int newX, int y);
static int		ParseFontNameObj(Tcl_Interp *interp, Tk_Window tkwin,
			    Tcl_Obj *objPtr, TkFontAttributes *faPtr);
static void		RecomputeWidgets(TkWindow *winPtr);
static int		SetFontFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void		TheWorldHasChanged(void *clientData);
static void		UpdateDependentFonts(TkFontInfo *fiPtr,
			    Tk_Window tkwin, Tcl_HashEntry *namedHashPtr);

/*
 * The following structure defines the implementation of the "font" Tcl
 * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
 * font object points to the TkFont structure for the font, or NULL.
 */

const TkObjType tkFontObjType = {
    {"font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *---------------------------------------------------------------------------
 *
 * TkFontPkgInit --
 *
412
413
414
415
416
417
418

419

420
421
422
423

424

425
426
427
428
429
430
431
void
TkFontPkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    TkFontInfo *fiPtr = mainPtr->fontInfoPtr;
    Tcl_HashEntry *hPtr, *searchPtr;
    Tcl_HashSearch search;

    int fontsLeft = 0;


    for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
	    searchPtr != NULL;
	    searchPtr = Tcl_NextHashEntry(&search)) {

	fontsLeft++;

#ifdef DEBUG_FONTS
	fprintf(stderr, "Font %s still in cache.\n",
		(char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
    }

#ifdef PURIFY







>

>




>

>







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
void
TkFontPkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    TkFontInfo *fiPtr = mainPtr->fontInfoPtr;
    Tcl_HashEntry *hPtr, *searchPtr;
    Tcl_HashSearch search;
#ifdef PURIFY
    int fontsLeft = 0;
#endif

    for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
	    searchPtr != NULL;
	    searchPtr = Tcl_NextHashEntry(&search)) {
#ifdef PURIFY
	fontsLeft++;
#endif
#ifdef DEBUG_FONTS
	fprintf(stderr, "Font %s still in cache.\n",
		(char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
    }

#ifdef PURIFY
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_FontObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index;
    Tk_Window tkwin = (Tk_Window)clientData;
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;







|







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_FontObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index;
    Tk_Window tkwin = (Tk_Window)clientData;
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
	    return TCL_ERROR;
	}

	/*
	 * Next parameter may be an option.
	 */

	n = skip + 3;
	optPtr = NULL;
	charPtr = NULL;
	if (n < objc) {
	    s = Tcl_GetString(objv[n]);
	    if (s[0] == '-' && s[1] != '-') {
		optPtr = objv[n];
		n++;







|







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
	    return TCL_ERROR;
	}

	/*
	 * Next parameter may be an option.
	 */

	n = 3 + skip;
	optPtr = NULL;
	charPtr = NULL;
	if (n < objc) {
	    s = Tcl_GetString(objv[n]);
	    if (s[0] == '-' && s[1] != '-') {
		optPtr = objv[n];
		n++;
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583

	/*
	 * The 'charPtr' arg must be a single Unicode.
	 */

	if (charPtr != NULL) {
	    const char *string = Tcl_GetString(charPtr);
	    size_t len = TkUtfToUniChar(string, &uniChar);

	    if (len != (size_t)charPtr->length) {
		resultPtr = Tcl_NewStringObj(
			"expected a single character but got \"", -1);
		Tcl_AppendLimitedToObj(resultPtr, string,
			-1, 40, "...");
		Tcl_AppendToObj(resultPtr, "\"", -1);
		Tcl_SetObjResult(interp, resultPtr);
		Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL);
		return TCL_ERROR;
	    }
	}

	/*







|



|

|
|







572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

	/*
	 * The 'charPtr' arg must be a single Unicode.
	 */

	if (charPtr != NULL) {
	    const char *string = Tcl_GetString(charPtr);
	    size_t len = Tcl_UtfToUniChar(string, &uniChar);

	    if (len != (size_t)charPtr->length) {
		resultPtr = Tcl_NewStringObj(
			"expected a single character but got \"", TCL_INDEX_NONE);
		Tcl_AppendLimitedToObj(resultPtr, string,
			TCL_INDEX_NONE, 40, "...");
		Tcl_AppendToObj(resultPtr, "\"", TCL_INDEX_NONE);
		Tcl_SetObjResult(interp, resultPtr);
		Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL);
		return TCL_ERROR;
	    }
	}

	/*
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
	}
	if (name == NULL) {
	    /*
	     * No font name specified. Generate one of the form "fontX".
	     */

	    for (i = 1; ; i++) {
		sprintf(buf, "font%d", i);
		namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf);
		if (namedHashPtr == NULL) {
		    break;
		}
	    }
	    name = buf;
	    skip = 2;
	}
	TkInitFontAttributes(&fa);
	if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip,
		&fa) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
	break;
    }
    case FONT_DELETE: {
	int i, result = TCL_OK;
	const char *string;

	/*







|
















|







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
	}
	if (name == NULL) {
	    /*
	     * No font name specified. Generate one of the form "fontX".
	     */

	    for (i = 1; ; i++) {
		snprintf(buf, sizeof(buf), "font%d", i);
		namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf);
		if (namedHashPtr == NULL) {
		    break;
		}
	    }
	    name = buf;
	    skip = 2;
	}
	TkInitFontAttributes(&fa);
	if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip,
		&fa) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, TCL_INDEX_NONE));
	break;
    }
    case FONT_DELETE: {
	int i, result = TCL_OK;
	const char *string;

	/*
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
    }
    case FONT_FAMILIES: {
	int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);

	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
	    return TCL_ERROR;
	}
	TkpGetFontFamilies(interp, tkwin);
	break;
    }
    case FONT_MEASURE: {
	const char *string;
	Tk_Font tkfont;
	TkSizeT length = 0;
	int skip = 0;

	if (objc > 4) {
	    skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	    if (skip < 0) {
		return TCL_ERROR;
	    }
	}
	if (objc - skip != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? text");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
	}
	string = TkGetStringFromObj(objv[3 + skip], &length);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		Tk_TextWidth(tkfont, string, length)));
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_METRICS: {
	Tk_Font tkfont;
	int skip, i;
	const TkFontMetrics *fmPtr;
	static const char *const switches[] = {
	    "-ascent", "-descent", "-linespace", "-fixed", NULL
	};

	skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if ((objc < 3) || ((objc - skip) > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?-option?");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;







|









|








|








|










|






|







711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
    }
    case FONT_FAMILIES: {
	int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);

	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc != 2 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
	    return TCL_ERROR;
	}
	TkpGetFontFamilies(interp, tkwin);
	break;
    }
    case FONT_MEASURE: {
	const char *string;
	Tk_Font tkfont;
	Tcl_Size length = 0;
	int skip = 0;

	if (objc > 4) {
	    skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	    if (skip < 0) {
		return TCL_ERROR;
	    }
	}
	if (objc != 4 + skip) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? text");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
	}
	string = 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, i;
	const TkFontMetrics *fmPtr;
	static const char *const switches[] = {
	    "-ascent", "-descent", "-fixed", "-linespace", NULL
	};

	skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 4 + skip)) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?-option?");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
		Tk_FreeFont(tkfont);
		return TCL_ERROR;
	    }
	    i = 0;		/* Needed only to prevent compiler warning. */
	    switch (index) {
	    case 0: i = fmPtr->ascent;			break;
	    case 1: i = fmPtr->descent;			break;
	    case 2: i = fmPtr->ascent + fmPtr->descent;	break;
	    case 3: i = fmPtr->fixed;			break;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(i));
	}
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_NAMES: {







|
|







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
		Tk_FreeFont(tkfont);
		return TCL_ERROR;
	    }
	    i = 0;		/* Needed only to prevent compiler warning. */
	    switch (index) {
	    case 0: i = fmPtr->ascent;			break;
	    case 1: i = fmPtr->descent;			break;
	    case 2: i = fmPtr->fixed;			break;
	    case 3: i = fmPtr->ascent + fmPtr->descent;	break;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(i));
	}
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_NAMES: {
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
	    NamedFont *nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);

	    if (!nfPtr->deletePending) {
		char *string = (char *)Tcl_GetHashKey(&fiPtr->namedTable,
			namedHashPtr);

		Tcl_ListObjAppendElement(NULL, resultPtr,
			Tcl_NewStringObj(string, -1));
	    }
	    namedHashPtr = Tcl_NextHashEntry(&search);
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    }







|







811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
	    NamedFont *nfPtr = (NamedFont *)Tcl_GetHashValue(namedHashPtr);

	    if (!nfPtr->deletePending) {
		char *string = (char *)Tcl_GetHashKey(&fiPtr->namedTable,
			namedHashPtr);

		Tcl_ListObjAppendElement(NULL, resultPtr,
			Tcl_NewStringObj(string, TCL_INDEX_NONE));
	    }
	    namedHashPtr = Tcl_NextHashEntry(&search);
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    }
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
	}
	cacheHashPtr = Tcl_NextHashEntry(&search);
    }
}

static void
TheWorldHasChanged(
    ClientData clientData)	/* Info about application's fonts. */
{
    TkFontInfo *fiPtr = (TkFontInfo *)clientData;

    /*
     * On macOS it is catastrophic to recompute all widgets while the
     * [NSView drawRect] method is drawing. The best that we can do in
     * that situation is to abort the recomputation and hope for the best.







|







879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
	}
	cacheHashPtr = Tcl_NextHashEntry(&search);
    }
}

static void
TheWorldHasChanged(
    void *clientData)	/* Info about application's fonts. */
{
    TkFontInfo *fiPtr = (TkFontInfo *)clientData;

    /*
     * On macOS it is catastrophic to recompute all widgets while the
     * [NSView drawRect] method is drawing. The best that we can do in
     * that situation is to abort the recomputation and hope for the best.
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927







928
929
930
931
932
933
934

static void
RecomputeWidgets(
    TkWindow *winPtr)		/* Window to which command is sent. */
{
    Tk_ClassWorldChangedProc *proc =
	    Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);


    if (proc != NULL) {
	proc(winPtr->instanceData);
    }

    /*
     * Notify all the descendants of this window that the world has changed.
     *
     * This could be done recursively or iteratively. The recursive version is
     * easier to implement and understand, and typically, windows with a -font
     * option will be leaf nodes in the widget heirarchy (buttons, labels,
     * etc.), so the recursion depth will be shallow.
     *
     * However, the additional overhead of the recursive calls may become a
     * performance problem if typical usage alters such that -font'ed widgets
     * appear high in the heirarchy, causing deep recursion. This could happen
     * with text widgets, or more likely with the (not yet existant) labeled
     * frame widget. With these widgets it is possible, even likely, that a
     * -font'ed widget (text or labeled frame) will not be a leaf node, but
     * will instead have many descendants. If this is ever found to cause a
     * performance problem, it may be worth investigating an iterative version
     * of the code below.
     */

    for (winPtr=winPtr->childList ; winPtr!=NULL ; winPtr=winPtr->nextPtr) {
	RecomputeWidgets(winPtr);
    }







}

/*
 *---------------------------------------------------------------------------
 *
 * TkCreateNamedFont --
 *







>










|




|
|
|
|





|
|

>
>
>
>
>
>
>







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

static void
RecomputeWidgets(
    TkWindow *winPtr)		/* Window to which command is sent. */
{
    Tk_ClassWorldChangedProc *proc =
	    Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);
    TkWindow *tkwinPtr;

    if (proc != NULL) {
	proc(winPtr->instanceData);
    }

    /*
     * Notify all the descendants of this window that the world has changed.
     *
     * This could be done recursively or iteratively. The recursive version is
     * easier to implement and understand, and typically, windows with a -font
     * option will be leaf nodes in the widget hierarchy (buttons, labels,
     * etc.), so the recursion depth will be shallow.
     *
     * However, the additional overhead of the recursive calls may become a
     * performance problem if typical usage alters such that -font'ed widgets
     * appear high in the hierarchy, causing deep recursion. This could happen
     * with text widgets, or more likely with the labelframe
     * widget. With these widgets it is possible, even likely, that a
     * -font'ed widget (text or labelframe) will not be a leaf node, but
     * will instead have many descendants. If this is ever found to cause a
     * performance problem, it may be worth investigating an iterative version
     * of the code below.
     */

    for (tkwinPtr=winPtr->childList ; tkwinPtr!=NULL ; tkwinPtr=tkwinPtr->nextPtr) {
	RecomputeWidgets(tkwinPtr);
    }

    /*
     * Broadcast font change virtually for mega-widget layout managers.
     * Do this after the font change has been propagated to core widgets.
    */
    Tk_SendVirtualEvent((Tk_Window)winPtr, "TkWorldChanged",
			Tcl_NewStringObj("FontChanged",-1));
}

/*
 *---------------------------------------------------------------------------
 *
 * TkCreateNamedFont --
 *
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
    Tk_Window tkwin,		/* For display on which font will be used. */
    const char *string)		/* String describing font, as: named font,
				 * native format, or parseable string. */
{
    Tk_Font tkfont;
    Tcl_Obj *strPtr;

    strPtr = Tcl_NewStringObj(string, -1);
    Tcl_IncrRefCount(strPtr);
    tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr);
    Tcl_DecrRefCount(strPtr);
    return tkfont;
}

/*







|







1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
    Tk_Window tkwin,		/* For display on which font will be used. */
    const char *string)		/* String describing font, as: named font,
				 * native format, or parseable string. */
{
    Tk_Font tkfont;
    Tcl_Obj *strPtr;

    strPtr = Tcl_NewStringObj(string, TCL_INDEX_NONE);
    Tcl_IncrRefCount(strPtr);
    tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr);
    Tcl_DecrRefCount(strPtr);
    return tkfont;
}

/*
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
{
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    Tcl_HashEntry *cacheHashPtr, *namedHashPtr;
    TkFont *fontPtr, *firstFontPtr, *oldFontPtr;
    int isNew, descent;
    NamedFont *nfPtr;

    if (objPtr->typePtr != &tkFontObjType
	    || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
	SetFontFromAny(interp, objPtr);
    }

    oldFontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;
    if (oldFontPtr != NULL) {
	if (oldFontPtr->resourceRefCount == 0) {







|







1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
{
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    Tcl_HashEntry *cacheHashPtr, *namedHashPtr;
    TkFont *fontPtr, *firstFontPtr, *oldFontPtr;
    int isNew, descent;
    NamedFont *nfPtr;

    if (objPtr->typePtr != &tkFontObjType.objType
	    || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
	SetFontFromAny(interp, objPtr);
    }

    oldFontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;
    if (oldFontPtr != NULL) {
	if (oldFontPtr->resourceRefCount == 0) {
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218

    if (fontPtr == NULL) {
	if (isNew) {
	    Tcl_DeleteHashEntry(cacheHashPtr);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"failed to allocate font due to internal system font engine"
		" problem", -1));
	Tcl_SetErrorCode(interp, "TK", "FONT", "INTERNAL_PROBLEM", NULL);
	return NULL;
    }

    fontPtr->resourceRefCount = 1;
    fontPtr->objRefCount = 1;
    fontPtr->cacheHashPtr = cacheHashPtr;







|







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236

    if (fontPtr == NULL) {
	if (isNew) {
	    Tcl_DeleteHashEntry(cacheHashPtr);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"failed to allocate font due to internal system font engine"
		" problem", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "FONT", "INTERNAL_PROBLEM", NULL);
	return NULL;
    }

    fontPtr->resourceRefCount = 1;
    fontPtr->objRefCount = 1;
    fontPtr->cacheHashPtr = cacheHashPtr;
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
				 * in. */
    Tcl_Obj *objPtr)		/* The object from which to get the font. */
{
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    TkFont *fontPtr;
    Tcl_HashEntry *hashPtr;

    if (objPtr->typePtr != &tkFontObjType
	    || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
	SetFontFromAny(NULL, objPtr);
    }

    fontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;
    if (fontPtr != NULL) {
	if (fontPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkFont that's no
	     * longer in use. Clear the reference.
	     */

	    FreeFontObj(objPtr);
	    fontPtr = NULL;
	} else if (Tk_Screen(tkwin) == fontPtr->screen) {

	    return (Tk_Font) fontPtr;
	}
    }

    /*
     * Next, search the list of fonts that have the name we want, to see if
     * one of them is for the right screen.







|















>







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
				 * in. */
    Tcl_Obj *objPtr)		/* The object from which to get the font. */
{
    TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
    TkFont *fontPtr;
    Tcl_HashEntry *hashPtr;

    if (objPtr->typePtr != &tkFontObjType.objType
	    || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
	SetFontFromAny(NULL, objPtr);
    }

    fontPtr = (TkFont *)objPtr->internalRep.twoPtrValue.ptr1;
    if (fontPtr != NULL) {
	if (fontPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkFont that's no
	     * longer in use. Clear the reference.
	     */

	    FreeFontObj(objPtr);
	    fontPtr = NULL;
	} else if (Tk_Screen(tkwin) == fontPtr->screen) {
	    fontPtr->resourceRefCount++;
	    return (Tk_Font) fontPtr;
	}
    }

    /*
     * Next, search the list of fonts that have the name we want, to see if
     * one of them is for the right screen.
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkFontObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;

    return TCL_OK;
}

/*







|







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    objPtr->typePtr = &tkFontObjType.objType;
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;

    return TCL_OK;
}

/*
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
	/*
	 * Inline, capitalize the first letter of each word, lowercase the
	 * rest of the letters in each word, and then take out the spaces
	 * between the words. This may make the DString shorter, which is safe
	 * to do.
	 */

	Tcl_DStringAppend(dsPtr, family, -1);

	src = dest = Tcl_DStringValue(dsPtr) + len;
	upper = 1;
	for (; *src != '\0'; ) {
	    while (isspace(UCHAR(*src))) { /* INTL: ISO space */
		src++;
		upper = 1;
	    }
	    src += TkUtfToUniChar(src, &ch);
	    if (upper) {
		ch = Tcl_UniCharToUpper(ch);
		upper = 0;
	    } else {
		ch = Tcl_UniCharToLower(ch);
	    }
	    dest += TkUniCharToUtf(ch, dest);
	}
	*dest = '\0';
	Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
	family = Tcl_DStringValue(dsPtr) + len;
    }
    if (family != Tcl_DStringValue(dsPtr) + len) {
	Tcl_DStringAppend(dsPtr, family, -1);
	family = Tcl_DStringValue(dsPtr) + len;
    }

    if (strcasecmp(family, "NewCenturySchoolbook") == 0) {
	Tcl_DStringSetLength(dsPtr, len);
	Tcl_DStringAppend(dsPtr, "NewCenturySchlbk", -1);
	family = Tcl_DStringValue(dsPtr) + len;
    }

    /*
     * Get the string to use for the weight.
     */








|








|






|






|





|







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
	/*
	 * Inline, capitalize the first letter of each word, lowercase the
	 * rest of the letters in each word, and then take out the spaces
	 * between the words. This may make the DString shorter, which is safe
	 * to do.
	 */

	Tcl_DStringAppend(dsPtr, family, TCL_INDEX_NONE);

	src = dest = Tcl_DStringValue(dsPtr) + len;
	upper = 1;
	for (; *src != '\0'; ) {
	    while (isspace(UCHAR(*src))) { /* INTL: ISO space */
		src++;
		upper = 1;
	    }
	    src += Tcl_UtfToUniChar(src, &ch);
	    if (upper) {
		ch = Tcl_UniCharToUpper(ch);
		upper = 0;
	    } else {
		ch = Tcl_UniCharToLower(ch);
	    }
	    dest += Tcl_UniCharToUtf(ch, dest);
	}
	*dest = '\0';
	Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
	family = Tcl_DStringValue(dsPtr) + len;
    }
    if (family != Tcl_DStringValue(dsPtr) + len) {
	Tcl_DStringAppend(dsPtr, family, TCL_INDEX_NONE);
	family = Tcl_DStringValue(dsPtr) + len;
    }

    if (strcasecmp(family, "NewCenturySchoolbook") == 0) {
	Tcl_DStringSetLength(dsPtr, len);
	Tcl_DStringAppend(dsPtr, "NewCenturySchlbk", TCL_INDEX_NONE);
	family = Tcl_DStringValue(dsPtr) + len;
    }

    /*
     * Get the string to use for the weight.
     */

1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
     * and not italic.
     */

    if ((slantString == NULL) && (weightString == NULL)) {
	if ((strcmp(family, "Times") == 0)
		|| (strcmp(family, "NewCenturySchlbk") == 0)
		|| (strcmp(family, "Palatino") == 0)) {
	    Tcl_DStringAppend(dsPtr, "-Roman", -1);
	}
    } else {
	Tcl_DStringAppend(dsPtr, "-", -1);
	if (weightString != NULL) {
	    Tcl_DStringAppend(dsPtr, weightString, -1);
	}
	if (slantString != NULL) {
	    Tcl_DStringAppend(dsPtr, slantString, -1);
	}
    }

    return (int)(fontPtr->fa.size + 0.5);
}

/*







|


|

|


|







1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
     * and not italic.
     */

    if ((slantString == NULL) && (weightString == NULL)) {
	if ((strcmp(family, "Times") == 0)
		|| (strcmp(family, "NewCenturySchlbk") == 0)
		|| (strcmp(family, "Palatino") == 0)) {
	    Tcl_DStringAppend(dsPtr, "-Roman", TCL_INDEX_NONE);
	}
    } else {
	Tcl_DStringAppend(dsPtr, "-", TCL_INDEX_NONE);
	if (weightString != NULL) {
	    Tcl_DStringAppend(dsPtr, weightString, TCL_INDEX_NONE);
	}
	if (slantString != NULL) {
	    Tcl_DStringAppend(dsPtr, slantString, TCL_INDEX_NONE);
	}
    }

    return (int)(fontPtr->fa.size + 0.5);
}

/*
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
 *---------------------------------------------------------------------------
 */

int
Tk_TextWidth(
    Tk_Font tkfont,		/* Font in which text will be measured. */
    const char *string,		/* String whose width will be computed. */
    int numBytes)		/* Number of bytes to consider from string, or
				 * < 0 for strlen(). */
{
    int width;

    if (numBytes < 0) {
	numBytes = strlen(string);
    }
    Tk_MeasureChars(tkfont, string, numBytes, -1, 0, &width);







|
|







1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
 *---------------------------------------------------------------------------
 */

int
Tk_TextWidth(
    Tk_Font tkfont,		/* Font in which text will be measured. */
    const char *string,		/* String whose width will be computed. */
    Tcl_Size numBytes)		/* Number of bytes to consider from string, or
				 * TCL_INDEX_NONE for strlen(). */
{
    int width;

    if (numBytes < 0) {
	numBytes = strlen(string);
    }
    Tk_MeasureChars(tkfont, string, numBytes, -1, 0, &width);
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
    Tk_Font tkfont,		/* Font used in GC; must have been allocated
				 * by Tk_GetFont(). Used for character
				 * dimensions, etc. */
    const char *string,		/* String containing characters to be
				 * underlined or overstruck. */
    int x, int y,		/* Coordinates at which first character of
				 * string is drawn. */
    int firstByte,		/* Index of first byte of first character. */
    int lastByte)		/* Index of first byte after the last
				 * character. */
{
    TkUnderlineCharsInContext(display, drawable, gc, tkfont, string,
	    lastByte, x, y, firstByte, lastByte);
}

void
TkUnderlineCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for actually drawing
				 * line. */
    Tk_Font tkfont,		/* Font used in GC; must have been allocated
				 * by Tk_GetFont(). Used for character
				 * dimensions, etc. */
    const char *string,		/* String containing characters to be
				 * underlined or overstruck. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y,		/* Coordinates at which the first character of
				 * the whole string would be drawn. */
    int firstByte,		/* Index of first byte of first character. */
    int lastByte)		/* Index of first byte after the last
				 * character. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    int startX, endX;

    TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0,
	    &startX);







|
|

















|


|
|







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
    Tk_Font tkfont,		/* Font used in GC; must have been allocated
				 * by Tk_GetFont(). Used for character
				 * dimensions, etc. */
    const char *string,		/* String containing characters to be
				 * underlined or overstruck. */
    int x, int y,		/* Coordinates at which first character of
				 * string is drawn. */
    Tcl_Size firstByte,		/* Index of first byte of first character. */
    Tcl_Size lastByte)		/* Index of first byte after the last
				 * character. */
{
    TkUnderlineCharsInContext(display, drawable, gc, tkfont, string,
	    lastByte, x, y, firstByte, lastByte);
}

void
TkUnderlineCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for actually drawing
				 * line. */
    Tk_Font tkfont,		/* Font used in GC; must have been allocated
				 * by Tk_GetFont(). Used for character
				 * dimensions, etc. */
    const char *string,		/* String containing characters to be
				 * underlined or overstruck. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    int x, int y,		/* Coordinates at which the first character of
				 * the whole string would be drawn. */
    Tcl_Size firstByte,		/* Index of first byte of first character. */
    Tcl_Size lastByte)		/* Index of first byte after the last
				 * character. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    int startX, endX;

    TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0,
	    &startX);
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
 */

Tk_TextLayout
Tk_ComputeTextLayout(
    Tk_Font tkfont,		/* Font that will be used to display text. */
    const char *string,		/* String whose dimensions are to be
				 * computed. */
    int numChars,		/* Number of characters to consider from
				 * string, or < 0 for strlen(). */
    int wrapLength,		/* Longest permissible line length, in pixels.
				 * <= 0 means no automatic wrapping: just let
				 * lines get as long as needed. */
    Tk_Justify justify,		/* How to justify lines. */
    int flags,			/* Flag bits OR-ed together. TK_IGNORE_TABS
				 * means that tab characters should not be
				 * expanded. TK_IGNORE_NEWLINES means that
				 * newline characters should not cause a line
				 * break. */
    int *widthPtr,		/* Filled with width of string. */
    int *heightPtr)		/* Filled with height of string. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    const char *start, *endp, *special;

    int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight;
    int baseline, height, curX, newX, maxWidth, *lineLengths;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    const TkFontMetrics *fmPtr;
    Tcl_DString lineBuffer;

    Tcl_DStringInit(&lineBuffer);







|
|














>
|







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
 */

Tk_TextLayout
Tk_ComputeTextLayout(
    Tk_Font tkfont,		/* Font that will be used to display text. */
    const char *string,		/* String whose dimensions are to be
				 * computed. */
    Tcl_Size numChars,		/* Number of characters to consider from
				 * string, or TCL_INDEX_NONE for strlen(). */
    int wrapLength,		/* Longest permissible line length, in pixels.
				 * <= 0 means no automatic wrapping: just let
				 * lines get as long as needed. */
    Tk_Justify justify,		/* How to justify lines. */
    int flags,			/* Flag bits OR-ed together. TK_IGNORE_TABS
				 * means that tab characters should not be
				 * expanded. TK_IGNORE_NEWLINES means that
				 * newline characters should not cause a line
				 * break. */
    int *widthPtr,		/* Filled with width of string. */
    int *heightPtr)		/* Filled with height of string. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    const char *start, *endp, *special;
    Tcl_Size n;
    int y, bytesThisChunk, maxChunks, curLine, layoutHeight;
    int baseline, height, curX, newX, maxWidth, *lineLengths;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    const TkFontMetrics *fmPtr;
    Tcl_DString lineBuffer;

    Tcl_DStringInit(&lineBuffer);
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
    }

    fmPtr = &fontPtr->fm;

    height = fmPtr->ascent + fmPtr->descent;

    if (numChars < 0) {
	numChars = Tcl_NumUtfChars(string, -1);
    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;








|







2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
    }

    fmPtr = &fontPtr->fm;

    height = fmPtr->ascent + fmPtr->descent;

    if (numChars < 0) {
	numChars = Tcl_NumUtfChars(string, TCL_INDEX_NONE);
    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

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
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context to use for drawing
				 * text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    int firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specifies the
				 * beginning. */
    int lastChar)		/* The index just after the last character to
				 * draw from the given text item. A number < 0
				 * means to draw all characters. */
{
#if 0
    /* Use TkDrawAngledTextLayout() implementation - testing purposes at this point */
    TkDrawAngledTextLayout(display, drawable, gc, layout, x, y, 0.0, firstChar, lastChar);
#else
    TextLayout *layoutPtr = (TextLayout *) layout;

    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;

    if (layoutPtr == NULL) {
	return;
    }








|


|








>
|







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
    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). */
    Tcl_Size firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specifies the
				 * beginning. */
    Tcl_Size 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, drawX;
    Tcl_Size numDisplayChars;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;

    if (layoutPtr == NULL) {
	return;
    }

2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
    GC gc,			/* Graphics context to use for drawing
				 * text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    double angle,
    int firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specifies the
				 * beginning. */
    int lastChar)		/* The index just after the last character to
				 * draw from the given text item. A number < 0
				 * means to draw all characters. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;







|


|







2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
    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,
    Tcl_Size firstChar,		/* The index of the first character to draw
				 * from the given text item. 0 specifies the
				 * beginning. */
    Tcl_Size lastChar)		/* The index just after the last character to
				 * draw from the given text item. A number < 0
				 * means to draw all characters. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context to use for drawing text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    int underline)		/* Index of the single character to underline,
				 * or -1 for no underline. */
{
    int xx, yy, width, height;

    if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0)
	    && (width != 0)) {
	TextLayout *layoutPtr = (TextLayout *) layout;
	TkFont *fontPtr = (TkFont *) layoutPtr->tkfont;







|







2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context to use for drawing text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    int underline)		/* Index of the single character to underline,
				 * or INT_MIN for no underline. */
{
    int xx, yy, width, height;

    if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0)
	    && (width != 0)) {
	TextLayout *layoutPtr = (TextLayout *) layout;
	TkFont *fontPtr = (TkFont *) layoutPtr->tkfont;
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
				 * text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    double angle,
    int underline)		/* Index of the single character to underline,
				 * or -1 for no underline. */
{
    int xx, yy, width, height;

    if (angle == 0.0) {
	Tk_UnderlineTextLayout(display, drawable, gc, layout, x,y, underline);
	return;
    }







|







2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
				 * text. */
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int x, int y,		/* Upper-left hand corner of rectangle in
				 * which to draw (pixels). */
    double angle,
    int underline)		/* Index of the single character to underline,
				 * or INT_MIN for no underline. */
{
    int xx, yy, width, height;

    if (angle == 0.0) {
	Tk_UnderlineTextLayout(display, drawable, gc, layout, x,y, underline);
	return;
    }
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
 *---------------------------------------------------------------------------
 */

int
Tk_CharBbox(
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    int index,			/* The index of the character whose bbox is
				 * desired. */
    int *xPtr, int *yPtr,	/* Filled with the upper-left hand corner, in
				 * pixels, of the bounding box for the
				 * character specified by index, if
				 * non-NULL. */
    int *widthPtr, int *heightPtr)
				/* Filled with the width and height of the
				 * bounding box for the character specified by
				 * index, if non-NULL. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int i, x = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {




	return 0;

    }

    tkfont = layoutPtr->tkfont;
    fontPtr = (TkFont *) tkfont;

    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->numDisplayChars < 0) {







|
|

















>
>
>
>
|
>







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
 *---------------------------------------------------------------------------
 */

int
Tk_CharBbox(
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    Tcl_Size index,			/* The index of the character whose bbox is
				 * desired. Negative means count backwards. */
    int *xPtr, int *yPtr,	/* Filled with the upper-left hand corner, in
				 * pixels, of the bounding box for the
				 * character specified by index, if
				 * non-NULL. */
    int *widthPtr, int *heightPtr)
				/* Filled with the width and height of the
				 * bounding box for the character specified by
				 * index, if non-NULL. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int i, x = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {
	for (i = 0; i < layoutPtr->numChunks; i++) {
	    index += (chunkPtr + i)->numChars;
	}
	if (index < 0) {
	    return 0;
	}
    }

    tkfont = layoutPtr->tkfont;
    fontPtr = (TkFont *) tkfont;

    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->numDisplayChars < 0) {
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
	    if (xPtr != NULL) {
		Tk_MeasureChars(tkfont, chunkPtr->start,
			end - chunkPtr->start, -1, 0, &x);
		x += chunkPtr->x;
	    }
	    if (widthPtr != NULL) {
		int ch;
		Tk_MeasureChars(tkfont, end, TkUtfToUniChar(end, &ch), -1, 0, &w);
	    }
	    goto check;
	}
	index -= chunkPtr->numChars;
	chunkPtr++;
    }
    if (index != 0) {







|







2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
	    if (xPtr != NULL) {
		Tk_MeasureChars(tkfont, chunkPtr->start,
			end - chunkPtr->start, -1, 0, &x);
		x += chunkPtr->x;
	    }
	    if (widthPtr != NULL) {
		int ch;
		Tk_MeasureChars(tkfont, end, Tcl_UtfToUniChar(end, &ch), -1, 0, &w);
	    }
	    goto check;
	}
	index -= chunkPtr->numChars;
	chunkPtr++;
    }
    if (index != 0) {
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
    Tk_TextLayout layout)	/* The layout to be rendered. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int baseline = chunkPtr->y;
    Tcl_Obj *psObj = Tcl_NewObj();
    int i, j;
    TkSizeT len;
    const char *p, *glyphname;
    char uindex[5], c, *ps;
    int ch;

    Tcl_AppendToObj(psObj, "[(", -1);
    for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) {
	if (baseline != chunkPtr->y) {
	    Tcl_AppendToObj(psObj, ")]\n[(", -1);
	    baseline = chunkPtr->y;
	}
	if (chunkPtr->numDisplayChars <= 0) {
	    if (chunkPtr->start[0] == '\t') {
		Tcl_AppendToObj(psObj, "\\t", -1);
	    }
	    continue;
	}

	for (p=chunkPtr->start, j=0; j<chunkPtr->numDisplayChars; j++) {
	    /*
	     * INTL: We only handle symbols that have an encoding as a glyph
	     * from the standard set defined by Adobe. The rest get punted.
	     * Eventually this should be revised to handle more sophsticiated
	     * international postscript fonts.
	     */

	    p += TkUtfToUniChar(p, &ch);
	    if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) {
		/*
		 * Tricky point: the "03" is necessary in the sprintf below,
		 * so that a full three digits of octal are always generated.
		 * Without the "03", a number following this sequence could be
		 * interpreted by Postscript as part of this sequence.
		 */

		Tcl_AppendPrintfToObj(psObj, "\\%03o", ch);
		continue;







|




|


|




|












|


|







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
    Tk_TextLayout layout)	/* The layout to be rendered. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int baseline = chunkPtr->y;
    Tcl_Obj *psObj = Tcl_NewObj();
    int i, j;
    Tcl_Size len;
    const char *p, *glyphname;
    char uindex[5], c, *ps;
    int ch;

    Tcl_AppendToObj(psObj, "[(", TCL_INDEX_NONE);
    for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) {
	if (baseline != chunkPtr->y) {
	    Tcl_AppendToObj(psObj, ")]\n[(", TCL_INDEX_NONE);
	    baseline = chunkPtr->y;
	}
	if (chunkPtr->numDisplayChars <= 0) {
	    if (chunkPtr->start[0] == '\t') {
		Tcl_AppendToObj(psObj, "\\t", TCL_INDEX_NONE);
	    }
	    continue;
	}

	for (p=chunkPtr->start, j=0; j<chunkPtr->numDisplayChars; j++) {
	    /*
	     * INTL: We only handle symbols that have an encoding as a glyph
	     * from the standard set defined by Adobe. The rest get punted.
	     * Eventually this should be revised to handle more sophsticiated
	     * international postscript fonts.
	     */

	    p += Tcl_UtfToUniChar(p, &ch);
	    if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) {
		/*
		 * Tricky point: the "03" is necessary in the snprintf below,
		 * so that a full three digits of octal are always generated.
		 * Without the "03", a number following this sequence could be
		 * interpreted by Postscript as part of this sequence.
		 */

		Tcl_AppendPrintfToObj(psObj, "\\%03o", ch);
		continue;
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
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
	     * This character doesn't belong to the ASCII character set, so we
	     * use the full glyph name.
	     */

	    if (ch > 0xffff) {
		goto noMapping;
	    }
	    sprintf(uindex, "%04X", ch);		/* endianness? */
	    glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0);
	    if (glyphname) {
		ps = TkGetStringFromObj(psObj, &len);
		if (ps[len-1] == '(') {
		    /*
		     * In-place edit. Ewww!
		     */

		    ps[len-1] = '/';
		} else {
		    Tcl_AppendToObj(psObj, ")/", -1);
		}
		Tcl_AppendToObj(psObj, glyphname, -1);
		Tcl_AppendToObj(psObj, "(", -1);
	    } else {
		/*
		 * No known mapping for the character into the space of
		 * PostScript glyphs. Ignore it. :-(
		 */
noMapping:	;

#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT
		fprintf(stderr, "Warning: no mapping to PostScript "
			"glyphs for \\u%04x\n", ch);
#endif
	    }
	}
    }
    Tcl_AppendToObj(psObj, ")]\n", -1);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
}

/*
 *---------------------------------------------------------------------------
 *







|


|







|

|
|














|







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
	     * This character doesn't belong to the ASCII character set, so we
	     * use the full glyph name.
	     */

	    if (ch > 0xffff) {
		goto noMapping;
	    }
	    snprintf(uindex, sizeof(uindex), "%04X", ch);		/* endianness? */
	    glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0);
	    if (glyphname) {
		ps = Tcl_GetStringFromObj(psObj, &len);
		if (ps[len-1] == '(') {
		    /*
		     * In-place edit. Ewww!
		     */

		    ps[len-1] = '/';
		} else {
		    Tcl_AppendToObj(psObj, ")/", TCL_INDEX_NONE);
		}
		Tcl_AppendToObj(psObj, glyphname, TCL_INDEX_NONE);
		Tcl_AppendToObj(psObj, "(", TCL_INDEX_NONE);
	    } else {
		/*
		 * No known mapping for the character into the space of
		 * PostScript glyphs. Ignore it. :-(
		 */
noMapping:	;

#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT
		fprintf(stderr, "Warning: no mapping to PostScript "
			"glyphs for \\u%04x\n", ch);
#endif
	    }
	}
    }
    Tcl_AppendToObj(psObj, ")]\n", TCL_INDEX_NONE);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
}

/*
 *---------------------------------------------------------------------------
 *
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408

3409
3410
3411
3412
3413
3414
3415
3416
 *---------------------------------------------------------------------------
 */

static int
ConfigAttributesObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    TCL_UNUSED(Tk_Window),	/* For display on which font will be used. */
    int objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[],	/* Command line options. */
    TkFontAttributes *faPtr)	/* Font attributes structure whose fields are
				 * to be modified. Structure must already be
				 * properly initialized. */
{

    int i, n, index;
    Tcl_Obj *optionPtr, *valuePtr;
    const char *value;

    for (i = 0; i < objc; i += 2) {
	optionPtr = objv[i];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,







|





>
|







3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
 *---------------------------------------------------------------------------
 */

static int
ConfigAttributesObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    TCL_UNUSED(Tk_Window),	/* For display on which font will be used. */
    Tcl_Size 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. */
{
    Tcl_Size i;
    int n, index;
    Tcl_Obj *optionPtr, *valuePtr;
    const char *value;

    for (i = 0; i < objc; i += 2) {
	optionPtr = objv[i];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,
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
	    } else {
		valuePtr = Tcl_NewWideIntObj(-(Tcl_WideInt)(-faPtr->size + 0.5));
	    }
	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;

	case FONT_SLANT:
	    str = TkFindStateString(slantMap, faPtr->slant);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;

	case FONT_UNDERLINE:
	    valuePtr = Tcl_NewBooleanObj(faPtr->underline);
	    break;

	case FONT_OVERSTRIKE:
	    valuePtr = Tcl_NewBooleanObj(faPtr->overstrike);
	    break;
	}
	if (objPtr != NULL) {
	    Tcl_SetObjResult(interp, valuePtr);
	    return TCL_OK;
	}
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj(fontOpt[i], -1));
	Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*







|




|















|







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
	    } else {
		valuePtr = Tcl_NewWideIntObj(-(Tcl_WideInt)(-faPtr->size + 0.5));
	    }
	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, TCL_INDEX_NONE);
	    break;

	case FONT_SLANT:
	    str = TkFindStateString(slantMap, faPtr->slant);
	    valuePtr = Tcl_NewStringObj(str, TCL_INDEX_NONE);
	    break;

	case FONT_UNDERLINE:
	    valuePtr = Tcl_NewBooleanObj(faPtr->underline);
	    break;

	case FONT_OVERSTRIKE:
	    valuePtr = Tcl_NewBooleanObj(faPtr->overstrike);
	    break;
	}
	if (objPtr != NULL) {
	    Tcl_SetObjResult(interp, valuePtr);
	    return TCL_OK;
	}
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj(fontOpt[i], TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*
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
    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;
}

/*
 *---------------------------------------------------------------------------
 *







|



|



|



|







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
    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, TCL_INDEX_NONE));
    }
    if (faPtr->slant != TK_FS_ROMAN) {
	str = TkFindStateString(slantMap, faPtr->slant);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, TCL_INDEX_NONE));
    }
    if (faPtr->underline) {
	str = TkFindStateString(underlineMap, faPtr->underline);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, TCL_INDEX_NONE));
    }
    if (faPtr->overstrike) {
	str = TkFindStateString(overstrikeMap, faPtr->overstrike);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, TCL_INDEX_NONE));
    }
    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *
3654
3655
3656
3657
3658
3659
3660
3661

3662
3663
3664
3665
3666
3667
3668
    Tcl_Obj *objPtr,		/* Parseable font description object. */
    TkFontAttributes *faPtr)	/* Filled with attributes parsed from font
				 * name. Any attributes that were not
				 * specified in font name are filled with
				 * default values. */
{
    const char *dash;
    int objc, result, i, n;

    Tcl_Obj **objv;
    const char *string;

    TkInitFontAttributes(faPtr);

    string = Tcl_GetString(objPtr);
    if (*string == '-') {







|
>







3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
    Tcl_Obj *objPtr,		/* Parseable font description object. */
    TkFontAttributes *faPtr)	/* Filled with attributes parsed from font
				 * name. Any attributes that were not
				 * specified in font name are filled with
				 * default values. */
{
    const char *dash;
    int result, n;
    Tcl_Size objc, i;
    Tcl_Obj **objv;
    const char *string;

    TkInitFontAttributes(faPtr);

    string = Tcl_GetString(objPtr);
    if (*string == '-') {
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
 */

static LayoutChunk *
NewChunk(
    TextLayout **layoutPtrPtr,
    int *maxPtr,
    const char *start,
    int numBytes,
    int curX,
    int newX,
    int y)
{
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    int maxChunks, numChars;







|







3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
 */

static LayoutChunk *
NewChunk(
    TextLayout **layoutPtrPtr,
    int *maxPtr,
    const char *start,
    Tcl_Size numBytes,
    int curX,
    int newX,
    int y)
{
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    int maxChunks, numChars;
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908

    str = string;
    if (*str == '-') {
	str++;
    }

    Tcl_DStringInit(&ds);
    Tcl_DStringAppend(&ds, str, -1);
    src = Tcl_DStringValue(&ds);

    field[0] = src;
    for (i = 0; *src != '\0'; src++) {
	if (!(*src & 0x80)
		&& Tcl_UniCharIsUpper(UCHAR(*src))) {
	    *src = (char) Tcl_UniCharToLower(UCHAR(*src));







|







3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936

    str = string;
    if (*str == '-') {
	str++;
    }

    Tcl_DStringInit(&ds);
    Tcl_DStringAppend(&ds, str, TCL_INDEX_NONE);
    src = Tcl_DStringValue(&ds);

    field[0] = src;
    for (i = 0; *src != '\0'; src++) {
	if (!(*src & 0x80)
		&& Tcl_UniCharIsUpper(UCHAR(*src))) {
	    *src = (char) Tcl_UniCharToLower(UCHAR(*src));
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    Tk_Font *font,
    char *dst)
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr;
    int numBytesInChunk;

    if ((layoutPtr == NULL) || (layoutPtr->numChunks == 0)
	    || (layoutPtr->chunks->numDisplayChars <= 0)) {
	dst[0] = '\0';
	return 0;
    }
    chunkPtr = layoutPtr->chunks;







|







4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
    Tk_TextLayout layout,	/* Layout information, from a previous call to
				 * Tk_ComputeTextLayout(). */
    Tk_Font *font,
    char *dst)
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr;
    Tcl_Size numBytesInChunk;

    if ((layoutPtr == NULL) || (layoutPtr->numChunks == 0)
	    || (layoutPtr->chunks->numDisplayChars <= 0)) {
	dst[0] = '\0';
	return 0;
    }
    chunkPtr = layoutPtr->chunks;

Changes to generic/tkFont.h.

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.
 *
 * 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







|







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 © 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 */

typedef struct TkFont {
    /*
     * Fields used and maintained exclusively by generic code.
     */

    TkSizeT resourceRefCount;	/* Number of active uses of this font (each
				 * active use corresponds to a call to
				 * Tk_AllocFontFromTable or Tk_GetFont). If
				 * this count is 0, then this TkFont structure
				 * is no longer valid and it isn't present in
				 * a hash table: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when
				 * resourceRefCount and objRefCount are both
				 * 0. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure,
				 * used when deleting it. */
    Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that
				 * corresponds to the named font that the
				 * tkfont was based on, or NULL if the tkfont
				 * was not based on a named font. */







|









|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 */

typedef struct TkFont {
    /*
     * Fields used and maintained exclusively by generic code.
     */

    Tcl_Size resourceRefCount;	/* Number of active uses of this font (each
				 * active use corresponds to a call to
				 * Tk_AllocFontFromTable or Tk_GetFont). If
				 * this count is 0, then this TkFont structure
				 * is no longer valid and it isn't present in
				 * a hash table: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when
				 * resourceRefCount and objRefCount are both
				 * 0. */
    Tcl_Size objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure,
				 * used when deleting it. */
    Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that
				 * corresponds to the named font that the
				 * tkfont was based on, or NULL if the tkfont
				 * was not based on a named font. */

Changes to generic/tkFrame.c.

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.
 *
 * 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"







|
|







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 © 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"
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    Tcl_Interp *interp;		/* Interpreter associated with widget. Used to
				 * delete widget command. */
    Tcl_Command widgetCmd;	/* Token for frame's widget command. */
    Tk_OptionTable optionTable;	/* Table that defines configuration options
				 * available for this widget. */
    char *className;		/* Class name for widget (from configuration
				 * option). Malloc-ed. */
    enum FrameType type;	/* Type of widget, such as TYPE_FRAME. */
    char *screenName;		/* Screen on which widget is created. Non-null
				 * only for top-levels. Malloc-ed, may be
				 * NULL. */
    char *visualName;		/* Textual description of visual for window,
				 * from -visual option. Malloc-ed, may be
				 * NULL. */
    char *colormapName;		/* Textual description of colormap for window,







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    Tcl_Interp *interp;		/* Interpreter associated with widget. Used to
				 * delete widget command. */
    Tcl_Command widgetCmd;	/* Token for frame's widget command. */
    Tk_OptionTable optionTable;	/* Table that defines configuration options
				 * available for this widget. */
    char *className;		/* Class name for widget (from configuration
				 * option). Malloc-ed. */
    int type;			/* Type of widget, such as TYPE_FRAME. */
    char *screenName;		/* Screen on which widget is created. Non-null
				 * only for top-levels. Malloc-ed, may be
				 * NULL. */
    char *visualName;		/* Textual description of visual for window,
				 * from -visual option. Malloc-ed, may be
				 * NULL. */
    char *colormapName;		/* Textual description of colormap for window,
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ComputeFrameGeometry(Frame *framePtr);
static int		ConfigureFrame(Tcl_Interp *interp, Frame *framePtr,
			    int objc, Tcl_Obj *const objv[]);
static int		CreateFrame(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const argv[],
			    enum FrameType type, const char *appName);
static void		DestroyFrame(void *memPtr);
static void		DestroyFramePartly(Frame *framePtr);
static void		DisplayFrame(ClientData clientData);
static void		DrawFrameBackground(Tk_Window tkwin, Pixmap pixmap,
			    int highlightWidth, int borderWidth,
			    Tk_Image bgimg, int bgtile);
static void		FrameBgImageProc(ClientData clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		FrameCmdDeletedProc(ClientData clientData);
static void		FrameEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		FrameLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		FrameRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		FrameStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		FrameWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		FrameWorldChanged(ClientData instanceData);
static void		MapFrame(ClientData clientData);

/*
 * The structure below defines frame class behavior by means of functions that
 * can be invoked from generic window code.
 */

static const Tk_ClassProcs frameClass = {







|
<
<
<
|

|



|


|
|

|

|

|

|
<
<
|
|







324
325
326
327
328
329
330
331



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350


351
352
353
354
355
356
357
358
359

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ComputeFrameGeometry(Frame *framePtr);
static int		ConfigureFrame(Tcl_Interp *interp, Frame *framePtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);



static Tcl_FreeProc	DestroyFrame;
static void		DestroyFramePartly(Frame *framePtr);
static void		DisplayFrame(void *clientData);
static void		DrawFrameBackground(Tk_Window tkwin, Pixmap pixmap,
			    int highlightWidth, int borderWidth,
			    Tk_Image bgimg, int bgtile);
static void		FrameBgImageProc(void *clientData,
			    int x, int y, int width, int height,
			    int imgWidth, int imgHeight);
static void		FrameCmdDeletedProc(void *clientData);
static void		FrameEventProc(void *clientData,
			    XEvent *eventPtr);
static void		FrameLostContentProc(void *clientData,
			    Tk_Window tkwin);
static void		FrameRequestProc(void *clientData,
			    Tk_Window tkwin);
static void		FrameStructureProc(void *clientData,
			    XEvent *eventPtr);
static Tcl_ObjCmdProc FrameWidgetObjCmd;


static void		FrameWorldChanged(void *instanceData);
static void		MapFrame(void *clientData);

/*
 * The structure below defines frame class behavior by means of functions that
 * can be invoked from generic window code.
 */

static const Tk_ClassProcs frameClass = {
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
 *	call CreateFrame to do all of the real work.
 *
 *--------------------------------------------------------------
 */

int
Tk_FrameObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME, NULL);
}

int
Tk_ToplevelObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, NULL);
}

int
Tk_LabelframeObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return CreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME, NULL);
}

/*
 *--------------------------------------------------------------
 *
 * TkCreateFrame --
 *
 *	This function is the old command function for the "frame" and
 *	"toplevel" commands. Now it is used directly by Tk_Init to create a
 *	new main window. See the user documentation for the "frame" and
 *	"toplevel" commands for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkCreateFrame(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char *const *argv,	/* Argument strings. */
    int toplevel,		/* Non-zero means create a toplevel window,
				 * zero means create a frame. */
    const char *appName)	/* Should only be non-NULL if there is no main
				 * window associated with the interpreter.
				 * Gives the base name to use for the new
				 * application. */
{
    int result, i;
    Tcl_Obj **objv = (Tcl_Obj **)ckalloc((argc+1) * sizeof(Tcl_Obj **));

    for (i=0; i<argc; i++) {
	objv[i] = Tcl_NewStringObj(argv[i], -1);
	Tcl_IncrRefCount(objv[i]);
    }
    objv[argc] = NULL;
    result = CreateFrame(clientData, interp, argc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, appName);
    for (i=0; i<argc; i++) {
	Tcl_DecrRefCount(objv[i]);
    }
    ckfree(objv);
    return result;
}

int
TkListCreateFrame(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *listObj,		/* List of arguments. */
    int toplevel,		/* Non-zero means create a toplevel window,
				 * zero means create a frame. */
    Tcl_Obj *nameObj)		/* Should only be non-NULL if there is no main
				 * window associated with the interpreter.
				 * Gives the base name to use for the new
				 * application. */
{
    int objc;
    Tcl_Obj **objv;

    if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) {
	return TCL_ERROR;
    }
    return CreateFrame(clientData, interp, objc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME,
	    nameObj ? Tcl_GetString(nameObj) : NULL);
}

static int
CreateFrame(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum FrameType type,	/* What widget type to create. */
    const char *appName)	/* Should only be non-NULL if there are no
				 * Main window associated with the
				 * interpreter. Gives the base name to use for
				 * the new application. */
{
    Tk_Window tkwin;
    Frame *framePtr;
    Tk_OptionTable optionTable;
    Tk_Window newWin;
    const char *className, *screenName, *visualName, *colormapName;
    const char *arg, *useOption;
    int i, depth;
    TkSizeT length;
    unsigned int mask;
    Colormap colormap;
    Visual *visual;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*







|




|




|




|




|




|




















<


<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|











|
|



<







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445













446

















447























448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
 *	call CreateFrame to do all of the real work.
 *
 *--------------------------------------------------------------
 */

int
Tk_FrameObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return TkCreateFrame(clientData, interp, objc, objv, TYPE_FRAME, NULL);
}

int
Tk_ToplevelObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return TkCreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, NULL);
}

int
Tk_LabelframeObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return TkCreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME, NULL);
}

/*
 *--------------------------------------------------------------
 *
 * TkCreateFrame --
 *
 *	This function is the old command function for the "frame" and
 *	"toplevel" commands. Now it is used directly by Tk_Init to create a
 *	new main window. See the user documentation for the "frame" and
 *	"toplevel" commands for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkCreateFrame(













    TCL_UNUSED(void *),

















    Tcl_Interp *interp,		/* Current interpreter. */























    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    int type,	/* What widget type to create. */
    const char *appName)	/* Should only be non-NULL if there are no
				 * Main window associated with the
				 * interpreter. Gives the base name to use for
				 * the new application. */
{
    Tk_Window tkwin;
    Frame *framePtr;
    Tk_OptionTable optionTable;
    Tk_Window newWin;
    const char *className, *screenName, *visualName, *colormapName;
    const char *arg, *useOption;
    int depth;
    Tcl_Size i, length;
    unsigned int mask;
    Colormap colormap;
    Visual *visual;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
     * be processed specially, before the window is configured using the usual
     * Tk mechanisms.
     */

    className = colormapName = screenName = visualName = useOption = NULL;
    colormap = None;
    for (i = 2; i < objc; i += 2) {
	arg = TkGetStringFromObj(objv[i], &length);
	if (length < 2) {
	    continue;
	}
	if ((arg[1] == 'c') && (length >= 3)
		&& (strncmp(arg, "-class", length) == 0)) {
	    className = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 'c') && (length >= 3)







|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
     * be processed specially, before the window is configured using the usual
     * Tk mechanisms.
     */

    className = colormapName = screenName = visualName = useOption = NULL;
    colormap = None;
    for (i = 2; i < objc; i += 2) {
	arg = Tcl_GetStringFromObj(objv[i], &length);
	if (length < 2) {
	    continue;
	}
	if ((arg[1] == 'c') && (length >= 3)
		&& (strncmp(arg, "-class", length) == 0)) {
	    className = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 'c') && (length >= 3)
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
     * before calling ConfigureFrame below, and they must also be processed in
     * a particular order, for the following reasons:
     * 1. Must set the window's class before calling ConfigureFrame, so that
     *	  unspecified options are looked up in the option database using the
     *	  correct class.
     * 2. Must set visual information before calling ConfigureFrame so that
     *	  colors are allocated in a proper colormap.
     * 3. Must call TkpUseWindow before setting non-default visual
     *	  information, since TkpUseWindow changes the defaults.
     */

    if (screenName == NULL) {
	screenName = (type == TYPE_TOPLEVEL) ? "" : NULL;
    }

    /*







|
|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
     * before calling ConfigureFrame below, and they must also be processed in
     * a particular order, for the following reasons:
     * 1. Must set the window's class before calling ConfigureFrame, so that
     *	  unspecified options are looked up in the option database using the
     *	  correct class.
     * 2. Must set visual information before calling ConfigureFrame so that
     *	  colors are allocated in a proper colormap.
     * 3. Must call Tk_UseWindow before setting non-default visual
     *	  information, since Tk_UseWindow changes the defaults.
     */

    if (screenName == NULL) {
	screenName = (type == TYPE_TOPLEVEL) ? "" : NULL;
    }

    /*
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
	}
    }
    Tk_SetClass(newWin, className);
    if (useOption == NULL) {
	useOption = Tk_GetOption(newWin, "use", "Use");
    }
    if ((useOption != NULL) && (*useOption != 0)
	    && (TkpUseWindow(interp, newWin, useOption) != TCL_OK)) {
	goto error;
    }
    if (visualName == NULL) {
	visualName = Tk_GetOption(newWin, "visual", "Visual");
    }
    if (colormapName == NULL) {
	colormapName = Tk_GetOption(newWin, "colormap", "Colormap");







|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
	}
    }
    Tk_SetClass(newWin, className);
    if (useOption == NULL) {
	useOption = Tk_GetOption(newWin, "use", "Use");
    }
    if ((useOption != NULL) && (*useOption != 0)
	    && (Tk_UseWindow(interp, newWin, useOption) != TCL_OK)) {
	goto error;
    }
    if (visualName == NULL) {
	visualName = Tk_GetOption(newWin, "visual", "Visual");
    }
    if (colormapName == NULL) {
	colormapName = Tk_GetOption(newWin, "colormap", "Colormap");
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
	    (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
	goto error;
    }
    if (framePtr->isContainer) {
	if (framePtr->useThis != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "windows cannot have both the -use and the -container"
		    " option set", -1));
	    Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL);
	    goto error;
	}
	TkpMakeContainer(framePtr->tkwin);
    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, framePtr);
    }
    Tcl_SetObjResult(interp, Tk_NewWindowObj(newWin));
    return TCL_OK;








|



|







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
	    (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
	goto error;
    }
    if (framePtr->isContainer) {
	if (framePtr->useThis != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "windows cannot have both the -use and the -container"
		    " option set", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL);
	    goto error;
	}
	Tk_MakeContainer(framePtr->tkwin);
    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, framePtr);
    }
    Tcl_SetObjResult(interp, Tk_NewWindowObj(newWin));
    return TCL_OK;

758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
FrameWidgetObjCmd(
    ClientData clientData,	/* Information about frame widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const frameOptions[] = {
	"cget", "configure", NULL
    };
    enum options {
	FRAME_CGET, FRAME_CONFIGURE
    };
    Frame *framePtr = (Frame *)clientData;
    int result = TCL_OK, index;
    int c, i;
    TkSizeT length;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions,







|












|
|







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
FrameWidgetObjCmd(
    void *clientData,	/* Information about frame widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const frameOptions[] = {
	"cget", "configure", NULL
    };
    enum options {
	FRAME_CGET, FRAME_CONFIGURE
    };
    Frame *framePtr = (Frame *)clientData;
    int result = TCL_OK, index;
    int c;
    Tcl_Size i, length;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions,
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
	} else {
	    /*
	     * Don't allow the options -class, -colormap, -container, -screen,
	     * -use, or -visual to be changed.
	     */

	    for (i = 2; i < objc; i++) {
		const char *arg = TkGetStringFromObj(objv[i], &length);

		if (length < 2) {
		    continue;
		}
		c = arg[1];
		if (((c == 'c') && (length >= 2)
			&& (strncmp(arg, "-class", length) == 0))
		    || ((c == 'c') && (length >= 3)
			&& (strncmp(arg, "-colormap", length) == 0))
		    || ((c == 'c') && (length >= 3)
			&& (strncmp(arg, "-container", length) == 0))
		    || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL)
			&& (strncmp(arg, "-screen", length) == 0))
		    || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL)
			&& (strncmp(arg, "-use", length) == 0))
		    || ((c == 'v')
			&& (strncmp(arg, "-visual", length) == 0))) {

#ifdef SUPPORT_CONFIG_EMBEDDED
		    if (c == 'u') {
			const char *string = Tcl_GetString(objv[i+1]);

			if (TkpUseWindow(interp, framePtr->tkwin,
				string) != TCL_OK) {
			    result = TCL_ERROR;
			    goto done;
			}
			continue;
		    }
#endif







|


















|



|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
	} 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 = 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 _WIN32
		    if (c == 'u') {
			const char *string = Tcl_GetString(objv[i+1]);

			if (Tk_UseWindow(interp, framePtr->tkwin,
				string) != TCL_OK) {
			    result = TCL_ERROR;
			    goto done;
			}
			continue;
		    }
#endif
886
887
888
889
890
891
892

893



894
895
896
897
898
899
900
 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(

    void *memPtr)		/* Info about frame widget. */



{
    Frame *framePtr = (Frame *)memPtr;
    Labelframe *labelframePtr = (Labelframe *)memPtr;

    if (framePtr->type == TYPE_LABELFRAME) {
	Tk_FreeTextLayout(labelframePtr->textLayout);
	if (labelframePtr->textGC != NULL) {







>

>
>
>







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Info about frame widget. */
#else
    char *memPtr)
#endif
{
    Frame *framePtr = (Frame *)memPtr;
    Labelframe *labelframePtr = (Labelframe *)memPtr;

    if (framePtr->type == TYPE_LABELFRAME) {
	Tk_FreeTextLayout(labelframePtr->textLayout);
	if (labelframePtr->textGC != NULL) {
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
	if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
	    Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
	}
	Tk_UnmapWindow(labelframePtr->labelWin);
	labelframePtr->labelWin = NULL;
    }

    Tk_FreeConfigOptions((char *) framePtr, framePtr->optionTable,
	    framePtr->tkwin);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureFrame --







|







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
	if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
	    Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
	}
	Tk_UnmapWindow(labelframePtr->labelWin);
	labelframePtr->labelWin = NULL;
    }

    Tk_FreeConfigOptions(framePtr, framePtr->optionTable,
	    framePtr->tkwin);
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureFrame --
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
 */

static int
ConfigureFrame(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Frame *framePtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    char *oldMenuName;
    Tk_Window oldWindow = NULL;
    Labelframe *labelframePtr = (Labelframe *) framePtr;
    Tk_Image image = NULL;







|







919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
 */

static int
ConfigureFrame(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Frame *framePtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    char *oldMenuName;
    Tk_Window oldWindow = NULL;
    Labelframe *labelframePtr = (Labelframe *) framePtr;
    Tk_Image image = NULL;
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
     */

    if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName == NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName != NULL)
	    && strcmp(oldMenuName, framePtr->menuName) != 0))
	    && framePtr->type == TYPE_TOPLEVEL) {
	TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName,
		framePtr->menuName);
    }

    if (oldMenuName != NULL) {
    	ckfree(oldMenuName);
    }








|







975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
     */

    if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName == NULL))
	    || ((oldMenuName != NULL) && (framePtr->menuName != NULL)
	    && strcmp(oldMenuName, framePtr->menuName) != 0))
	    && framePtr->type == TYPE_TOPLEVEL) {
	Tk_SetWindowMenubar(interp, framePtr->tkwin, oldMenuName,
		framePtr->menuName);
    }

    if (oldMenuName != NULL) {
    	ckfree(oldMenuName);
    }

1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
 *	Frame will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
FrameWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)instanceData;
    Labelframe *labelframePtr = (Labelframe *)instanceData;
    Tk_Window tkwin = framePtr->tkwin;
    XGCValues gcValues;
    GC gc;
    int anyTextLabel, anyWindowLabel;







|







1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
 *	Frame will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
FrameWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)instanceData;
    Labelframe *labelframePtr = (Labelframe *)instanceData;
    Tk_Window tkwin = framePtr->tkwin;
    XGCValues gcValues;
    GC gc;
    int anyTextLabel, anyWindowLabel;
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
	labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0;

	if (anyTextLabel) {
	    labelText = Tcl_GetString(labelframePtr->textPtr);
	    Tk_FreeTextLayout(labelframePtr->textLayout);
	    labelframePtr->textLayout =
		    Tk_ComputeTextLayout(labelframePtr->tkfont,
		    labelText, -1, 0, TK_JUSTIFY_CENTER, 0,
		    &labelframePtr->labelReqWidth,
		    &labelframePtr->labelReqHeight);
	    labelframePtr->labelReqWidth += 2 * LABELSPACING;
	    labelframePtr->labelReqHeight += 2 * LABELSPACING;
	} else if (anyWindowLabel) {
	    labelframePtr->labelReqWidth = Tk_ReqWidth(labelframePtr->labelWin);
	    labelframePtr->labelReqHeight =







|







1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
	labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0;

	if (anyTextLabel) {
	    labelText = Tcl_GetString(labelframePtr->textPtr);
	    Tk_FreeTextLayout(labelframePtr->textLayout);
	    labelframePtr->textLayout =
		    Tk_ComputeTextLayout(labelframePtr->tkfont,
		    labelText, TCL_INDEX_NONE, 0, TK_JUSTIFY_CENTER, 0,
		    &labelframePtr->labelReqWidth,
		    &labelframePtr->labelReqHeight);
	    labelframePtr->labelReqWidth += 2 * LABELSPACING;
	    labelframePtr->labelReqHeight += 2 * LABELSPACING;
	} else if (anyWindowLabel) {
	    labelframePtr->labelReqWidth = Tk_ReqWidth(labelframePtr->labelWin);
	    labelframePtr->labelReqHeight =
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
 *	Commands are output to X to display the frame in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayFrame(
    ClientData clientData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;
    int bdX1, bdY1, bdX2, bdY2, hlWidth;
    Pixmap pixmap;
    TkRegion clipRegion = NULL;

    framePtr->flags &= ~REDRAW_PENDING;
    if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    /*
     * Highlight shall always be drawn if it exists, so do that first.
     */

    hlWidth = framePtr->highlightWidth;

    if (hlWidth != 0) {
	GC fgGC, bgGC;

	bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr,
		Tk_WindowId(tkwin));
	if (framePtr->flags & GOT_FOCUS) {
	    fgGC = Tk_GCForColor(framePtr->highlightColorPtr,
		    Tk_WindowId(tkwin));
	    TkpDrawHighlightBorder(tkwin, fgGC, bgGC, hlWidth,
		    Tk_WindowId(tkwin));
	} else {
	    TkpDrawHighlightBorder(tkwin, bgGC, bgGC, hlWidth,
		    Tk_WindowId(tkwin));
	}
    }

    /*
     * If -background is set to "", no interior is drawn.
     */







|





|




















|


|







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
 *	Commands are output to X to display the frame in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayFrame(
    void *clientData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;
    int bdX1, bdY1, bdX2, bdY2, hlWidth;
    Pixmap pixmap;
    Bool useClipping = False;

    framePtr->flags &= ~REDRAW_PENDING;
    if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    /*
     * Highlight shall always be drawn if it exists, so do that first.
     */

    hlWidth = framePtr->highlightWidth;

    if (hlWidth != 0) {
	GC fgGC, bgGC;

	bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr,
		Tk_WindowId(tkwin));
	if (framePtr->flags & GOT_FOCUS) {
	    fgGC = Tk_GCForColor(framePtr->highlightColorPtr,
		    Tk_WindowId(tkwin));
	    Tk_DrawHighlightBorder(tkwin, fgGC, bgGC, hlWidth,
		    Tk_WindowId(tkwin));
	} else {
	    Tk_DrawHighlightBorder(tkwin, bgGC, bgGC, hlWidth,
		    Tk_WindowId(tkwin));
	}
    }

    /*
     * If -background is set to "", no interior is drawn.
     */
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
	     * Draw label. If there is not room for the entire label, use
	     * clipping to get a nice appearance.
	     */

	    if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth)
		    || (labelframePtr->labelBox.height <
			    labelframePtr->labelReqHeight)) {
		clipRegion = TkCreateRegion();
		TkUnionRectWithRegion(&labelframePtr->labelBox, clipRegion,
			clipRegion);
		TkSetRegion(framePtr->display, labelframePtr->textGC,
			clipRegion);

	    }

	    Tk_DrawTextLayout(framePtr->display, pixmap,
		    labelframePtr->textGC, labelframePtr->textLayout,
		    labelframePtr->labelTextX + LABELSPACING,
		    labelframePtr->labelTextY + LABELSPACING, 0, -1);

	    if (clipRegion != NULL) {
		XSetClipMask(framePtr->display, labelframePtr->textGC, None);
		TkDestroyRegion(clipRegion);
	    }
	} else {
	    /*
	     * Reposition and map the window (but in different ways depending
	     * on whether the frame is the window's parent).
	     */








<
<
|
|
<
>







|

<







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
	     * Draw label. If there is not room for the entire label, use
	     * clipping to get a nice appearance.
	     */

	    if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth)
		    || (labelframePtr->labelBox.height <
			    labelframePtr->labelReqHeight)) {


		useClipping = True;
		XSetClipRectangles(framePtr->display, labelframePtr->textGC, 0, 0,

			&labelframePtr->labelBox, 1, Unsorted);
	    }

	    Tk_DrawTextLayout(framePtr->display, pixmap,
		    labelframePtr->textGC, labelframePtr->textLayout,
		    labelframePtr->labelTextX + LABELSPACING,
		    labelframePtr->labelTextY + LABELSPACING, 0, -1);

	    if (useClipping) {
		XSetClipMask(framePtr->display, labelframePtr->textGC, None);

	    }
	} else {
	    /*
	     * Reposition and map the window (but in different ways depending
	     * on whether the frame is the window's parent).
	     */

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
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
FrameEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)	/* Information about event. */
{
    Frame *framePtr = (Frame *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	ComputeFrameGeometry(framePtr);
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	if (framePtr->menuName != NULL) {
	    TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
		    framePtr->menuName, NULL);
	    ckfree(framePtr->menuName);
	    framePtr->menuName = NULL;
	}
	if (framePtr->tkwin != NULL) {
	    /*
	     * If this window is a container, then this event could be coming







|











|







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
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
FrameEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)	/* Information about event. */
{
    Frame *framePtr = (Frame *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	ComputeFrameGeometry(framePtr);
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	if (framePtr->menuName != NULL) {
	    Tk_SetWindowMenubar(framePtr->interp, framePtr->tkwin,
		    framePtr->menuName, NULL);
	    ckfree(framePtr->menuName);
	    framePtr->menuName = NULL;
	}
	if (framePtr->tkwin != NULL) {
	    /*
	     * If this window is a container, then this event could be coming
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
	    framePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
	}
	if (framePtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayFrame, framePtr);
	}
	Tcl_CancelIdleCall(MapFrame, framePtr);
	Tcl_EventuallyFree(framePtr, (Tcl_FreeProc *) DestroyFrame);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags |= GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    } else if (eventPtr->type == FocusOut) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags &= ~GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    } else if (eventPtr->type == ActivateNotify) {
    	TkpSetMainMenubar(framePtr->interp, framePtr->tkwin,
    		framePtr->menuName);
    }
    return;

  redraw:
    if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayFrame, framePtr);







|















|







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
	    framePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
	}
	if (framePtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayFrame, framePtr);
	}
	Tcl_CancelIdleCall(MapFrame, framePtr);
	Tcl_EventuallyFree(framePtr, DestroyFrame);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags |= GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    } else if (eventPtr->type == FocusOut) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags &= ~GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
    } else if (eventPtr->type == ActivateNotify) {
    	Tk_SetMainMenubar(framePtr->interp, framePtr->tkwin,
    		framePtr->menuName);
    }
    return;

  redraw:
    if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayFrame, framePtr);
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;

    if (framePtr->menuName != NULL) {
	TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
		framePtr->menuName, NULL);
	ckfree(framePtr->menuName);
	framePtr->menuName = NULL;
    }

    /*
     * This function could be invoked either because the window was destroyed







|





|







1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;

    if (framePtr->menuName != NULL) {
	Tk_SetWindowMenubar(framePtr->interp, framePtr->tkwin,
		framePtr->menuName, NULL);
	ckfree(framePtr->menuName);
	framePtr->menuName = NULL;
    }

    /*
     * This function could be invoked either because the window was destroyed
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
 *	The frame given by the clientData argument is mapped.
 *
 *----------------------------------------------------------------------
 */

static void
MapFrame(
    ClientData clientData)		/* Pointer to frame structure. */
{
    Frame *framePtr = (Frame *)clientData;

    /*
     * Wait for all other background events to be processed before mapping
     * window. This ensures that the window's correct geometry will have been
     * determined before it is first mapped, so that the window manager







|







1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
 *	The frame given by the clientData argument is mapped.
 *
 *----------------------------------------------------------------------
 */

static void
MapFrame(
    void *clientData)		/* Pointer to frame structure. */
{
    Frame *framePtr = (Frame *)clientData;

    /*
     * Wait for all other background events to be processed before mapping
     * window. This ensures that the window's correct geometry will have been
     * determined before it is first mapped, so that the window manager
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
 *	The window is disassociated from the frame when it is deleted.
 *
 *--------------------------------------------------------------
 */

static void
FrameStructureProc(
    ClientData clientData,	/* Pointer to record describing frame. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Labelframe *labelframePtr = (Labelframe *)clientData;

    if (eventPtr->type == DestroyNotify) {
	/*
	 * This should only happen in a labelframe but it doesn't hurt to be







|







1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
 *	The window is disassociated from the frame when it is deleted.
 *
 *--------------------------------------------------------------
 */

static void
FrameStructureProc(
    void *clientData,	/* Pointer to record describing frame. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Labelframe *labelframePtr = (Labelframe *)clientData;

    if (eventPtr->type == DestroyNotify) {
	/*
	 * This should only happen in a labelframe but it doesn't hurt to be
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
 *	on the options specified for the frame.
 *
 *--------------------------------------------------------------
 */

static void
FrameRequestProc(
    ClientData clientData,	/* Pointer to record for frame. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    Frame *framePtr = (Frame *)clientData;
    (void)tkwin;

    FrameWorldChanged(framePtr);
}

/*
 *--------------------------------------------------------------
 *







|
|


<







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951

1952
1953
1954
1955
1956
1957
1958
 *	on the options specified for the frame.
 *
 *--------------------------------------------------------------
 */

static void
FrameRequestProc(
    void *clientData,	/* Pointer to record for frame. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    Frame *framePtr = (Frame *)clientData;


    FrameWorldChanged(framePtr);
}

/*
 *--------------------------------------------------------------
 *
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
 *	Forgets all frame-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
FrameLostContentProc(
    ClientData clientData,	/* Frame structure for content window window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window window. */
{
    Frame *framePtr = (Frame *)clientData;
    Labelframe *labelframePtr = (Labelframe *)clientData;
    (void)tkwin;

    /*
     * This should only happen in a labelframe but it doesn't hurt to be
     * careful.
     */

    if (labelframePtr->frame.type == TYPE_LABELFRAME) {







|

|



<







1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980

1981
1982
1983
1984
1985
1986
1987
 *	Forgets all frame-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
FrameLostContentProc(
    void *clientData,	/* Frame structure for content window window that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window window. */
{
    Frame *framePtr = (Frame *)clientData;
    Labelframe *labelframePtr = (Labelframe *)clientData;


    /*
     * This should only happen in a labelframe but it doesn't hurt to be
     * careful.
     */

    if (labelframePtr->frame.type == TYPE_LABELFRAME) {
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
    Frame *framePtr = (Frame *)((TkWindow *) tkwin)->instanceData;
    Tk_OptionTable optionTable;

    if (Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_FRAME) {
	framePtr->type = TYPE_TOPLEVEL;
	Tcl_DoWhenIdle(MapFrame, framePtr);
	if (framePtr->menuName != NULL) {
	    TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, NULL,
		    framePtr->menuName);
	}
    } else if (!Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_TOPLEVEL) {
	framePtr->type = TYPE_FRAME;
    } else {
	/*
	 * Not a frame or toplevel, skip it.







|







2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
    Frame *framePtr = (Frame *)((TkWindow *) tkwin)->instanceData;
    Tk_OptionTable optionTable;

    if (Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_FRAME) {
	framePtr->type = TYPE_TOPLEVEL;
	Tcl_DoWhenIdle(MapFrame, framePtr);
	if (framePtr->menuName != NULL) {
	    Tk_SetWindowMenubar(framePtr->interp, framePtr->tkwin, NULL,
		    framePtr->menuName);
	}
    } else if (!Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_TOPLEVEL) {
	framePtr->type = TYPE_FRAME;
    } else {
	/*
	 * Not a frame or toplevel, skip it.
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
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameBgImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */

{
    Frame *framePtr = (Frame *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;


    /*
     * Changing the background image never alters the dimensions of the frame.
     */

    if (framePtr->tkwin && Tk_IsMapped(framePtr->tkwin) &&
	    !(framePtr->flags & REDRAW_PENDING)) {







|
|
|
|
|
|
>


<
<
<
<
<
<
<







2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102







2103
2104
2105
2106
2107
2108
2109
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameBgImageProc(
    void *clientData,	/* Pointer to widget record. */
    TCL_UNUSED(int), /* Upper left pixel (within image) that must */
    TCL_UNUSED(int), /* be redisplayed. */
    TCL_UNUSED(int),	/* Dimensions of area to redisplay (might be */
    TCL_UNUSED(int), /* <= 0). */
    TCL_UNUSED(int), /* New dimensions of image. */
    TCL_UNUSED(int))
{
    Frame *framePtr = (Frame *)clientData;








    /*
     * Changing the background image never alters the dimensions of the frame.
     */

    if (framePtr->tkwin && Tk_IsMapped(framePtr->tkwin) &&
	    !(framePtr->flags & REDRAW_PENDING)) {

Changes to generic/tkGC.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|
|







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 © 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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkGeometry.c --
 *
 *	This file contains generic Tk code for geometry management (stuff
 *	that's used by all geometry managers).
 *
 * 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"

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
 *	container, then this procedure has no effect.
 *
 *----------------------------------------------------------------------
 */

void
Tk_UnmaintainGeometry(
    Tk_Window window,		/* WIndow for geometry management. */
    Tk_Window container)		/* Container for window; must be a descendant of
				 * window's parent. */
{
    Tcl_HashEntry *hPtr;
    MaintainContainer *containerPtr;
    MaintainContent *contentPtr, *prevPtr;
    Tk_Window ancestor;







|







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
 *	container, then this procedure has no effect.
 *
 *----------------------------------------------------------------------
 */

void
Tk_UnmaintainGeometry(
    Tk_Window window,		/* Window for geometry management. */
    Tk_Window container)		/* Container for window; must be a descendant of
				 * window's parent. */
{
    Tcl_HashEntry *hPtr;
    MaintainContainer *containerPtr;
    MaintainContent *contentPtr, *prevPtr;
    Tk_Window ancestor;

Changes to generic/tkGet.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









|
|







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 © 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"

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
static void		FreeUidThreadExitProc(ClientData clientData);

/*
 * The following tables defines the string values for reliefs, which are
 * used by Tk_GetAnchorFromObj and Tk_GetJustifyFromObj.
 */

static const char *const anchorStrings[] = {
    "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", NULL
};
static const char *const justifyStrings[] = {
    "left", "right", "center", NULL
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetAnchorFromObj --







|


|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
static void		FreeUidThreadExitProc(ClientData clientData);

/*
 * The following tables defines the string values for reliefs, which are
 * used by Tk_GetAnchorFromObj and Tk_GetJustifyFromObj.
 */

const char *const tkAnchorStrings[] = {
    "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", NULL
};
const char *const tkJustifyStrings[] = {
    "left", "right", "center", NULL
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetAnchorFromObj --
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
				 * from. */
    Tk_Anchor *anchorPtr)	/* Where to place the Tk_Anchor that
				 * corresponds to the string value of
				 * objPtr. */
{
    int index, code;

    code = Tcl_GetIndexFromObj(interp, objPtr, anchorStrings, "anchor", 0,
	    &index);
    if (code == TCL_OK) {
	*anchorPtr = (Tk_Anchor) index;
    }
    return code;
}








|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
				 * from. */
    Tk_Anchor *anchorPtr)	/* Where to place the Tk_Anchor that
				 * corresponds to the string value of
				 * objPtr. */
{
    int index, code;

    code = Tcl_GetIndexFromObj(interp, objPtr, tkAnchorStrings, "anchor", 0,
	    &index);
    if (code == TCL_OK) {
	*anchorPtr = (Tk_Anchor) index;
    }
    return code;
}

186
187
188
189
190
191
192

193
194
195
196
197
198
199
    case TK_ANCHOR_E: return "e";
    case TK_ANCHOR_SE: return "se";
    case TK_ANCHOR_S: return "s";
    case TK_ANCHOR_SW: return "sw";
    case TK_ANCHOR_W: return "w";
    case TK_ANCHOR_NW: return "nw";
    case TK_ANCHOR_CENTER: return "center";

    }
    return "unknown anchor position";
}

/*
 *--------------------------------------------------------------
 *







>







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    case TK_ANCHOR_E: return "e";
    case TK_ANCHOR_SE: return "se";
    case TK_ANCHOR_S: return "s";
    case TK_ANCHOR_SW: return "sw";
    case TK_ANCHOR_W: return "w";
    case TK_ANCHOR_NW: return "nw";
    case TK_ANCHOR_CENTER: return "center";
    case TK_ANCHOR_NULL: return "";
    }
    return "unknown anchor position";
}

/*
 *--------------------------------------------------------------
 *
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
				 * from. */
    Tk_Justify *justifyPtr)	/* Where to place the Tk_Justify that
				 * corresponds to the string value of
				 * objPtr. */
{
    int index, code;

    code = Tcl_GetIndexFromObj(interp, objPtr, justifyStrings,
	    "justification", 0, &index);
    if (code == TCL_OK) {
	*justifyPtr = (Tk_Justify) index;
    }
    return code;
}








|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
				 * from. */
    Tk_Justify *justifyPtr)	/* Where to place the Tk_Justify that
				 * corresponds to the string value of
				 * objPtr. */
{
    int index, code;

    code = Tcl_GetIndexFromObj(interp, objPtr, tkJustifyStrings,
	    "justification", 0, &index);
    if (code == TCL_OK) {
	*justifyPtr = (Tk_Justify) index;
    }
    return code;
}

467
468
469
470
471
472
473


474
475
476
477
478
479
480
    Tk_Justify justify)		/* Justification style for which identifying
				 * string is desired. */
{
    switch (justify) {
    case TK_JUSTIFY_LEFT: return "left";
    case TK_JUSTIFY_RIGHT: return "right";
    case TK_JUSTIFY_CENTER: return "center";


    }
    return "unknown justification style";
}

/*
 *----------------------------------------------------------------------
 *







>
>







468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    Tk_Justify justify)		/* Justification style for which identifying
				 * string is desired. */
{
    switch (justify) {
    case TK_JUSTIFY_LEFT: return "left";
    case TK_JUSTIFY_RIGHT: return "right";
    case TK_JUSTIFY_CENTER: return "center";
    case TK_JUSTIFY_FULL: return "full";
    case TK_JUSTIFY_NULL: return "";
    }
    return "unknown justification style";
}

/*
 *----------------------------------------------------------------------
 *
567
568
569
570
571
572
573
574
575

576
577
578
579


580
581
582

583
584
585
586
587

588

























589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
    Tcl_Interp *interp,		/* Use this for error reporting. */
    Tk_Window tkwin,		/* Window whose screen determines conversion
				 * from centimeters and other absolute
				 * units. */
    const char *string,		/* String describing a screen distance. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;


    d = strtod(string, &end);
    if (end == string) {
	goto error;


    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;

    }
    switch (*end) {
    case 0:
	d /= WidthOfScreen(Tk_Screen(tkwin));
	d *= WidthMMOfScreen(Tk_Screen(tkwin));

	break;

























    case 'c':
	d *= 10;
	end++;
	break;
    case 'i':
	d *= 25.4;
	end++;
	break;
    case 'm':
	end++;
	break;
    case 'p':
	d *= 25.4/72.0;
	end++;
	break;
    default:
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad screen distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "SCREEN_DISTANCE", NULL);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetPixels --
 *







|

>

|
|
|
>
>
|
<
<
>
|
<
<


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<



<


<



<




<
<
<
<
<
<


<
<
<
<
<
<







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586


587
588


589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

620
621
622

623
624

625
626
627

628
629
630
631






632
633






634
635
636
637
638
639
640
    Tcl_Interp *interp,		/* Use this for error reporting. */
    Tk_Window tkwin,		/* Window whose screen determines conversion
				 * from centimeters and other absolute
				 * units. */
    const char *string,		/* String describing a screen distance. */
    double *doublePtr)		/* Place to store converted result. */
{
    const char *rest;
    double d;
    Tcl_DString ds;

    if (Tcl_GetDouble(NULL, string, &d) == TCL_OK) {
	if (!tkwin) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj("bad screen", -1));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "SCREEN_DISTANCE", NULL);
	    }


	    return TCL_ERROR;
	}


	d /= WidthOfScreen(Tk_Screen(tkwin));
	d *= WidthMMOfScreen(Tk_Screen(tkwin));
	*doublePtr = d;
	return TCL_OK;
    }
    rest = string + strlen(string);
    while ((rest > string) && isspace(UCHAR(rest[-1]))) {
	--rest; /* skip all spaces at the end */
    }
    if (rest > string) {
	--rest; /* point to the character just before the last space */
    }
	if (rest == string) {
	error:
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected screen distance or \"\" but got \"%.50s\"", string));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	    }
	    return TCL_ERROR;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, string, rest-string);
    if (Tcl_GetDouble(NULL, Tcl_DStringValue(&ds), &d) != TCL_OK) {
	Tcl_DStringFree(&ds);
	goto error;
    }
    Tcl_DStringFree(&ds);
    switch (*rest) {
    case 'c':
	d *= 10;

	break;
    case 'i':
	d *= 25.4;

	break;
    case 'm':

	break;
    case 'p':
	d *= 25.4/72.0;

	break;
    default:
	goto error;
    }






    *doublePtr = d;
    return TCL_OK;






}

/*
 *--------------------------------------------------------------
 *
 * Tk_GetPixels --
 *
687
688
689
690
691
692
693
694
695

696
697

















698
699




700
701



702



703

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
    Tcl_Interp *interp,		/* Use this for error reporting. */
    Tk_Window tkwin,		/* Window whose screen determines conversion
				 * from centimeters and other absolute
				 * units. */
    const char *string,		/* String describing a number of pixels. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;


    d = strtod((char *) string, &end);

















    if (end == string) {
	goto error;




    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {



	end++;



    }

    switch (*end) {
    case 0:
	break;
    case 'c':
	d *= 10*WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));
	end++;
	break;
    case 'i':
	d *= 25.4*WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));
	end++;
	break;
    case 'm':
	d *= WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));
	end++;
	break;
    case 'p':
	d *= (25.4/72.0)*WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));
	end++;
	break;
    default:
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad screen distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "FRACTIONAL_PIXELS", NULL);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
|
<
>
>
>
|
>
>
>

>
|
<
<



<




<




<




<




<
<
<
<
<
<


<
<
<
<
<
<









700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745


746
747
748

749
750
751
752

753
754
755
756

757
758
759
760

761
762
763
764






765
766






767
768
769
770
771
772
773
774
775
    Tcl_Interp *interp,		/* Use this for error reporting. */
    Tk_Window tkwin,		/* Window whose screen determines conversion
				 * from centimeters and other absolute
				 * units. */
    const char *string,		/* String describing a number of pixels. */
    double *doublePtr)		/* Place to store converted result. */
{
    const char *rest;
    double d;
    Tcl_DString ds;

    if (Tcl_GetDouble(NULL, string, &d) == TCL_OK) {
	*doublePtr = d;
	return TCL_OK;
    }
    if (!tkwin) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("bad screen", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "FRACTIONAL_PIXELS", NULL);
	}
	return TCL_ERROR;
    }
    rest = string + strlen(string);
    while ((rest > string) && isspace(UCHAR(rest[-1]))) {
	--rest; /* skip all spaces at the end */
    }
    if (rest > string) {
	--rest; /* point to the character just before the last space */
    }
	if (rest == string) {
	error:
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected screen distance but got \"%.50s\"", string));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	    }

	    return TCL_ERROR;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, string, rest-string);
    if (Tcl_GetDouble(NULL, Tcl_DStringValue(&ds), &d) != TCL_OK) {
	Tcl_DStringFree(&ds);
	goto error;
    }
    Tcl_DStringFree(&ds);
    switch (*rest) {


    case 'c':
	d *= 10*WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));

	break;
    case 'i':
	d *= 25.4*WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));

	break;
    case 'm':
	d *= WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));

	break;
    case 'p':
	d *= (25.4/72.0)*WidthOfScreen(Tk_Screen(tkwin));
	d /= WidthMMOfScreen(Tk_Screen(tkwin));

	break;
    default:
	goto error;
    }






    *doublePtr = d;
    return TCL_OK;






}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkGrab.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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"


#endif

/*
 * The grab state machine has four states: ungrabbed, button pressed, grabbed,
 * and button pressed while grabbed. In addition, there are three pieces of
 * grab state information: the current grab window, the current restrict
 * window, and whether the mouse is captured.
 *
 * The current grab window specifies the point in the Tk window heirarchy
 * above which pointer events will not be reported. Any window within the
 * subtree below the grab window will continue to receive events as normal.
 * Events outside of the grab tree will be reported to the grab window.
 *
 * If the current restrict window is set, then all pointer events will be
 * reported only to the restrict window. The restrict window is normally set
 * during an automatic button grab.





|
|











>
>








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
 * tkGrab.c --
 *
 *	This file provides functions that implement grabs for Tk.
 *
 * 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"

#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#else
#include "tkMacOSXInt.h"
#endif

/*
 * The grab state machine has four states: ungrabbed, button pressed, grabbed,
 * and button pressed while grabbed. In addition, there are three pieces of
 * grab state information: the current grab window, the current restrict
 * window, and whether the mouse is captured.
 *
 * The current grab window specifies the point in the Tk window hierarchy
 * above which pointer events will not be reported. Any window within the
 * subtree below the grab window will continue to receive events as normal.
 * Events outside of the grab tree will be reported to the grab window.
 *
 * If the current restrict window is set, then all pointer events will be
 * reported only to the restrict window. The restrict window is normally set
 * during an automatic button grab.
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GrabObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int globalGrab;
    Tk_Window tkwin;
    TkDisplay *dispPtr;
    const char *arg;
    int index;
    TkSizeT len;
    static const char *const optionStrings[] = {
	"current", "release", "set", "status", NULL
    };
    static const char *const flagStrings[] = {
	"-global", NULL
    };
    enum options {







|









|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GrabObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int globalGrab;
    Tk_Window tkwin;
    TkDisplay *dispPtr;
    const char *arg;
    int index;
    Tcl_Size len;
    static const char *const optionStrings[] = {
	"current", "release", "set", "status", NULL
    };
    static const char *const flagStrings[] = {
	"-global", NULL
    };
    enum options {
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
	return TCL_ERROR;
    }

    /*
     * First check for a window name or "-global" as the first argument.
     */

    arg = TkGetStringFromObj(objv[1], &len);
    if (arg[0] == '.') {
	/* [grab window] */
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "?-global? window");
	    return TCL_ERROR;
	}
	tkwin = Tk_NameToWindow(interp, arg, (Tk_Window)clientData);







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
	return TCL_ERROR;
    }

    /*
     * First check for a window name or "-global" as the first argument.
     */

    arg = 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);
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
	if (dispPtr->eventualGrabWinPtr != winPtr) {
	    statusString = "none";
	} else if (dispPtr->grabFlags & GRAB_GLOBAL) {
	    statusString = "global";
	} else {
	    statusString = "local";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(statusString, -1));
	break;
    }
    }

    return TCL_OK;
}








|







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
	if (dispPtr->eventualGrabWinPtr != winPtr) {
	    statusString = "none";
	} else if (dispPtr->grabFlags & GRAB_GLOBAL) {
	    statusString = "global";
	} else {
	    statusString = "local";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(statusString, TCL_INDEX_NONE));
	break;
    }
    }

    return TCL_OK;
}

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
    }
    QueueGrabWindowChange(dispPtr, winPtr);
    return TCL_OK;

  grabError:
    if (grabResult == GrabNotViewable) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: window not viewable", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "UNVIEWABLE", NULL);
    } else if (grabResult == AlreadyGrabbed) {
    alreadyGrabbed:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: another application has grab", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "GRABBED", NULL);
    } else if (grabResult == GrabFrozen) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: keyboard or pointer frozen", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "FROZEN", NULL);
    } else if (grabResult == GrabInvalidTime) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: invalid time", -1));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "BAD_TIME", NULL);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"grab failed for unknown reason (code %d)", grabResult));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "UNKNOWN", NULL);
    }
    return TCL_ERROR;







|




|



|



|







519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    }
    QueueGrabWindowChange(dispPtr, winPtr);
    return TCL_OK;

  grabError:
    if (grabResult == GrabNotViewable) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: window not viewable", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "UNVIEWABLE", NULL);
    } else if (grabResult == AlreadyGrabbed) {
    alreadyGrabbed:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: another application has grab", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "GRABBED", NULL);
    } else if (grabResult == GrabFrozen) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: keyboard or pointer frozen", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "FROZEN", NULL);
    } else if (grabResult == GrabInvalidTime) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"grab failed: invalid time", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "BAD_TIME", NULL);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"grab failed for unknown reason (code %d)", grabResult));
	Tcl_SetErrorCode(interp, "TK", "GRAB", "UNKNOWN", NULL);
    }
    return TCL_ERROR;
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
EatGrabEvents(
    TkDisplay *dispPtr,		/* Display from which to consume events. */
    unsigned int serial)	/* Only discard events that have a serial
				 * number at least this great. */
{
    Tk_RestrictProc *prevProc;
    GrabInfo info;
    ClientData prevArg;

    info.display = dispPtr->display;
    info.serial = serial;
    TkpSync(info.display);
    prevProc = Tk_RestrictEvents(GrabRestrictProc, &info, &prevArg);
    while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	/* EMPTY */







|







1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
EatGrabEvents(
    TkDisplay *dispPtr,		/* Display from which to consume events. */
    unsigned int serial)	/* Only discard events that have a serial
				 * number at least this great. */
{
    Tk_RestrictProc *prevProc;
    GrabInfo info;
    void *prevArg;

    info.display = dispPtr->display;
    info.serial = serial;
    TkpSync(info.display);
    prevProc = Tk_RestrictEvents(GrabRestrictProc, &info, &prevArg);
    while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
	/* EMPTY */
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
GrabRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    GrabInfo *info = (GrabInfo *)arg;
    int mode, diff;

    /*
     * The diff caculation is trickier than it may seem. Don't forget that







|







1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
GrabRestrictProc(
    void *arg,
    XEvent *eventPtr)
{
    GrabInfo *info = (GrabInfo *)arg;
    int mode, diff;

    /*
     * The diff caculation is trickier than it may seem. Don't forget that

Changes to generic/tkGrid.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkGrid.c --
 *
 *	Grid based geometry manager.
 *
 * 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"

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

/*
 * Prototypes for procedures used only in this file:
 */

static void		AdjustForSticky(Gridder *contentPtr, int *xPtr,
			    int *yPtr, int *widthPtr, int *heightPtr);
static int		AdjustOffsets(int width, int elements,
			    SlotInfo *slotPtr);
static void		ArrangeGrid(ClientData clientData);
static int		CheckSlotData(Gridder *containerPtr, int slot,
			    int slotType, int checkOnly);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyGrid(void *memPtr);
static Gridder *	GetGrid(Tk_Window tkwin);
static int		GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridForgetRemoveCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GridInfoCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridLocationCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GridPropagateCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GridRowColumnConfigureCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GridSizeCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridContentCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static void		GridStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		GridLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		GridReqProc(ClientData clientData, Tk_Window tkwin);
static void		InitContainerData(Gridder *containerPtr);
static Tcl_Obj *	NewPairObj(Tcl_WideInt, Tcl_WideInt);
static Tcl_Obj *	NewQuadObj(Tcl_WideInt, Tcl_WideInt, Tcl_WideInt, Tcl_WideInt);
static int		ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
			    int maxOffset);
static void		SetGridSize(Gridder *gridPtr);
static int		SetContentColumn(Tcl_Interp *interp, Gridder *contentPtr,







|

|
|


|
|


|

|

|


|

|


|


|


|

|
|

|

|







251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

/*
 * Prototypes for procedures used only in this file:
 */

static void		AdjustForSticky(Gridder *contentPtr, int *xPtr,
			    int *yPtr, int *widthPtr, int *heightPtr);
static int		AdjustOffsets(int width, Tcl_Size elements,
			    SlotInfo *slotPtr);
static void		ArrangeGrid(void *clientData);
static int		CheckSlotData(Gridder *containerPtr, Tcl_Size slot,
			    int slotType, int checkOnly);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static Tcl_FreeProc	DestroyGrid;
static Gridder *	GetGrid(Tk_Window tkwin);
static int		GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		GridForgetRemoveCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		GridInfoCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		GridLocationCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		GridPropagateCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		GridRowColumnConfigureCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		GridSizeCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		GridContentCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		GridStructureProc(void *clientData,
			    XEvent *eventPtr);
static void		GridLostContentProc(void *clientData,
			    Tk_Window tkwin);
static void		GridReqProc(void *clientData, Tk_Window tkwin);
static void		InitContainerData(Gridder *containerPtr);
static Tcl_Obj *	NewPairObj(Tcl_WideInt, Tcl_WideInt);
static Tcl_Obj *	NewQuadObj(Tcl_WideInt, Tcl_WideInt, Tcl_WideInt, Tcl_WideInt);
static int		ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
			    int maxOffset);
static void		SetGridSize(Gridder *gridPtr);
static int		SetContentColumn(Tcl_Interp *interp, Gridder *contentPtr,
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GridObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"anchor", "bbox", "columnconfigure", "configure",







|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GridObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"anchor", "bbox", "columnconfigure", "configure",
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

    case GRID_COLUMNCONFIGURE:
    case GRID_ROWCONFIGURE:
	return GridRowColumnConfigureCommand(tkwin, interp, objc, objv);
    }

    /* This should not happen */
    Tcl_SetObjResult(interp, Tcl_NewStringObj("internal error in grid", -1));
    Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







|







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

    case GRID_COLUMNCONFIGURE:
    case GRID_ROWCONFIGURE:
	return GridRowColumnConfigureCommand(tkwin, interp, objc, objv);
    }

    /* This should not happen */
    Tcl_SetObjResult(interp, Tcl_NewStringObj("internal error in grid", TCL_INDEX_NONE));
    Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
 *----------------------------------------------------------------------
 */

static int
GridAnchorCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;
    GridContainer *gridPtr;
    Tk_Anchor old;








|







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
 *----------------------------------------------------------------------
 */

static int
GridAnchorCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;
    GridContainer *gridPtr;
    Tk_Anchor old;

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
 *----------------------------------------------------------------------
 */

static int
GridBboxCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;		/* container grid record */
    GridContainer *gridPtr;	/* pointer to grid data */
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */







|







507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
 *----------------------------------------------------------------------
 */

static int
GridBboxCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;		/* container grid record */
    GridContainer *gridPtr;	/* pointer to grid data */
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
 *----------------------------------------------------------------------
 */

static int
GridForgetRemoveCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window content;
    Gridder *contentPtr;
    int i;
    const char *string = Tcl_GetString(objv[1]);
    char c = string[0];

    for (i = 2; i < objc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
	    return TCL_ERROR;
	}







|




|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
 *----------------------------------------------------------------------
 */

static int
GridForgetRemoveCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window content;
    Gridder *contentPtr;
    Tcl_Size i;
    const char *string = Tcl_GetString(objv[1]);
    char c = string[0];

    for (i = 2; i < objc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

		if (contentPtr->in != NULL) {
		    Tcl_DecrRefCount(contentPtr->in);
		    contentPtr->in = NULL;
		}
		if (contentPtr->containerPtr != NULL) {
		    contentPtr->in = Tcl_NewStringObj(
			    Tk_PathName(contentPtr->containerPtr->tkwin), -1);
		    Tcl_IncrRefCount(contentPtr->in);
		}
	    }
	    Tk_ManageGeometry(content, NULL, NULL);
	    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		Tk_UnmaintainGeometry(contentPtr->tkwin,
			contentPtr->containerPtr->tkwin);







|







690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

		if (contentPtr->in != NULL) {
		    Tcl_DecrRefCount(contentPtr->in);
		    contentPtr->in = NULL;
		}
		if (contentPtr->containerPtr != NULL) {
		    contentPtr->in = Tcl_NewStringObj(
			    Tk_PathName(contentPtr->containerPtr->tkwin), TCL_INDEX_NONE);
		    Tcl_IncrRefCount(contentPtr->in);
		}
	    }
	    Tk_ManageGeometry(content, NULL, NULL);
	    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		Tk_UnmaintainGeometry(contentPtr->tkwin,
			contentPtr->containerPtr->tkwin);
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
 *----------------------------------------------------------------------
 */

static int
GridInfoCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Gridder *contentPtr;
    Tk_Window content;
    Tcl_Obj *infoObj;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	return TCL_ERROR;
    }
    contentPtr = GetGrid(content);
    if (contentPtr->containerPtr == NULL) {
	Tcl_ResetResult(interp);
	return TCL_OK;
    }

    infoObj = Tcl_NewObj();
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
	    Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", -1),
	    Tcl_NewWideIntObj(contentPtr->column));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", -1),
	    Tcl_NewWideIntObj(contentPtr->row));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", -1),
	    Tcl_NewWideIntObj(contentPtr->numCols));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", -1),
	    Tcl_NewWideIntObj(contentPtr->numRows));
    TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
    TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
    TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft, contentPtr->padX);
    TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-sticky", -1),
	    StickyToObj(contentPtr->sticky));
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|




















|

|

|

|

|





|







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
 *----------------------------------------------------------------------
 */

static int
GridInfoCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Gridder *contentPtr;
    Tk_Window content;
    Tcl_Obj *infoObj;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	return TCL_ERROR;
    }
    contentPtr = GetGrid(content);
    if (contentPtr->containerPtr == NULL) {
	Tcl_ResetResult(interp);
	return TCL_OK;
    }

    infoObj = Tcl_NewObj();
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", TCL_INDEX_NONE),
	    Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", TCL_INDEX_NONE),
	    Tcl_NewWideIntObj(contentPtr->column));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", TCL_INDEX_NONE),
	    Tcl_NewWideIntObj(contentPtr->row));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", TCL_INDEX_NONE),
	    Tcl_NewWideIntObj(contentPtr->numCols));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", TCL_INDEX_NONE),
	    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", TCL_INDEX_NONE),
	    StickyToObj(contentPtr->sticky));
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
 *----------------------------------------------------------------------
 */

static int
GridLocationCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;		/* Container grid record. */
    GridContainer *gridPtr;	/* Pointer to grid data. */
    SlotInfo *slotPtr;
    int x, y;			/* Offset in pixels, from edge of container. */







|







789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
 *----------------------------------------------------------------------
 */

static int
GridLocationCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;		/* Container grid record. */
    GridContainer *gridPtr;	/* Pointer to grid data. */
    SlotInfo *slotPtr;
    int x, y;			/* Offset in pixels, from edge of container. */
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
    }
    if (Tk_GetPixelsFromObj(interp, container, objv[4], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    containerPtr = GetGrid(container);
    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, -1));
	return TCL_OK;
    }
    gridPtr = containerPtr->containerDataPtr;

    /*
     * Update any pending requests. This is not always the steady state value,
     * as more configure events could be in the pipeline, but its as close as







|







818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
    }
    if (Tk_GetPixelsFromObj(interp, container, objv[4], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    containerPtr = GetGrid(container);
    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, TCL_INDEX_NONE));
	return TCL_OK;
    }
    gridPtr = containerPtr->containerDataPtr;

    /*
     * Update any pending requests. This is not always the steady state value,
     * as more configure events could be in the pipeline, but its as close as
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
 *----------------------------------------------------------------------
 */

static int
GridPropagateCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;
    int propagate, old;

    if (objc > 4) {







|







882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
 *----------------------------------------------------------------------
 */

static int
GridPropagateCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;
    int propagate, old;

    if (objc > 4) {
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 int
GridRowColumnConfigureCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container, content;
    Gridder *containerPtr, *contentPtr;
    SlotInfo *slotPtr = NULL;
    int slot;			/* the column or row number */
    int slotType;		/* COLUMN or ROW */
    int size;			/* the configuration value */
    int lObjc;			/* Number of items in index list */
    Tcl_Obj **lObjv;		/* array of indices */
    int ok;			/* temporary TCL result code */
    int i, j, first, last;
    const char *string;
    static const char *const optionStrings[] = {
	"-minsize", "-pad", "-uniform", "-weight", NULL
    };
    enum options {
	ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
    };







|








|


|







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 int
GridRowColumnConfigureCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container, content;
    Gridder *containerPtr, *contentPtr;
    SlotInfo *slotPtr = NULL;
    int slot;			/* the column or row number */
    int slotType;		/* COLUMN or ROW */
    int size;			/* the configuration value */
    Tcl_Size lObjc;		/* Number of items in index list */
    Tcl_Obj **lObjv;		/* array of indices */
    int ok;			/* temporary TCL result code */
    Tcl_Size 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
    };
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
    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 "







|







1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
    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", TCL_INDEX_NONE));
	    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 "
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
		minsize = slotPtr[slot].minSize;
		pad     = slotPtr[slot].pad;
		weight  = slotPtr[slot].weight;
		uniform = slotPtr[slot].uniform;
	    }

	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-minsize", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(pad));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-uniform", -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj(uniform == NULL ? "" : uniform, -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-weight", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(weight));
	    Tcl_SetObjResult(interp, res);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_OK;
	}

	/*







|


|


|

|

|







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
		minsize = slotPtr[slot].minSize;
		pad     = slotPtr[slot].pad;
		weight  = slotPtr[slot].weight;
		uniform = slotPtr[slot].uniform;
	    }

	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-minsize", TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(pad));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-uniform", TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj(uniform == NULL ? "" : uniform, TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-weight", TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(weight));
	    Tcl_SetObjResult(interp, res);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_OK;
	}

	/*
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
	} else if (index == ROWCOL_WEIGHT) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].weight : 0));
	} else if (index == ROWCOL_UNIFORM) {
	    Tk_Uid value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (value == NULL) ? "" : value, -1));
	} else if (index == ROWCOL_PAD) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }







|







1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
	} else if (index == ROWCOL_WEIGHT) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].weight : 0));
	} else if (index == ROWCOL_UNIFORM) {
	    Tk_Uid value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (value == NULL) ? "" : value, TCL_INDEX_NONE));
	} else if (index == ROWCOL_PAD) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
 *----------------------------------------------------------------------
 */

static int
GridSizeCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;
    GridContainer *gridPtr;	/* pointer to grid data */

    if (objc != 3) {







|







1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
 *----------------------------------------------------------------------
 */

static int
GridSizeCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;
    GridContainer *gridPtr;	/* pointer to grid data */

    if (objc != 3) {
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
 *----------------------------------------------------------------------
 */

static int
GridContentCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;		/* container grid record */
    Gridder *contentPtr;
    int i, value, index;
    int row = -1, column = -1;







|







1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
 *----------------------------------------------------------------------
 */

static int
GridContentCommand(
    Tk_Window tkwin,		/* Main window of the application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window container;
    Gridder *containerPtr;		/* container grid record */
    Gridder *contentPtr;
    int i, value, index;
    int row = -1, column = -1;
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
 *	the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
GridReqProc(
    ClientData clientData,	/* Grid's information about window that got
				 * new preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Gridder *gridPtr = (Gridder *)clientData;

    gridPtr = gridPtr->containerPtr;







|







1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
 *	the next idle point.
 *
 *----------------------------------------------------------------------
 */

static void
GridReqProc(
    void *clientData,	/* Grid's information about window that got
				 * new preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Gridder *gridPtr = (Gridder *)clientData;

    gridPtr = gridPtr->containerPtr;
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
 *	Forgets all grid-related information about the content.
 *
 *----------------------------------------------------------------------
 */

static void
GridLostContentProc(
    ClientData clientData,	/* Grid structure for content window that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    Gridder *contentPtr = (Gridder *)clientData;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);







|







1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
 *	Forgets all grid-related information about the content.
 *
 *----------------------------------------------------------------------
 */

static void
GridLostContentProc(
    void *clientData,	/* Grid structure for content window that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the content window. */
{
    Gridder *contentPtr = (Gridder *)clientData;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
 *
 *----------------------------------------------------------------------
 */

static int
AdjustOffsets(
    int size,			/* The total layout size (in pixels). */
    int slots,			/* Number of slots. */
    SlotInfo *slotPtr)	/* Pointer to slot array. */
{
    int slot;		/* Current slot. */
    int diff;			/* Extra pixels needed to add to the layout. */
    int totalWeight;		/* Sum of the weights for all the slots. */
    int weight;			/* Sum of the weights so far. */
    int minSize;		/* Minimum possible layout size. */
    int newDiff;		/* The most pixels that can be added on the
    				 * current pass. */








|


|







1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
 *
 *----------------------------------------------------------------------
 */

static int
AdjustOffsets(
    int size,			/* The total layout size (in pixels). */
    Tcl_Size slots,			/* Number of slots. */
    SlotInfo *slotPtr)	/* Pointer to slot array. */
{
    Tcl_Size slot;		/* Current slot. */
    int diff;			/* Extra pixels needed to add to the layout. */
    int totalWeight;		/* Sum of the weights for all the slots. */
    int weight;			/* Sum of the weights so far. */
    int minSize;		/* Minimum possible layout size. */
    int newDiff;		/* The most pixels that can be added on the
    				 * current pass. */

1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
 *	The content of containerPtr may get resized or moved.
 *
 *----------------------------------------------------------------------
 */

static void
ArrangeGrid(
    ClientData clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Gridder *containerPtr = (Gridder *)clientData;
    Gridder *contentPtr;
    GridContainer *slotPtr = containerPtr->containerDataPtr;
    int abort;
    int width, height;		/* Requested size of layout, in pixels. */







|







1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
 *	The content of containerPtr may get resized or moved.
 *
 *----------------------------------------------------------------------
 */

static void
ArrangeGrid(
    void *clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Gridder *containerPtr = (Gridder *)clientData;
    Gridder *contentPtr;
    GridContainer *slotPtr = containerPtr->containerDataPtr;
    int abort;
    int width, height;		/* Requested size of layout, in pixels. */
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
    int newRow, newNumRows, lastRow;

    newRow = (row >= 0) ? row : contentPtr->row;
    newNumRows = (numRows >= 1) ? numRows : contentPtr->numRows;

    lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
    if (lastRow >= MAX_ELEMENT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("row out of bounds", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_ROW", NULL);
	return TCL_ERROR;
    }

    contentPtr->row = newRow;
    contentPtr->numRows = newNumRows;
    return TCL_OK;







|







2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
    int newRow, newNumRows, lastRow;

    newRow = (row >= 0) ? row : contentPtr->row;
    newNumRows = (numRows >= 1) ? numRows : contentPtr->numRows;

    lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
    if (lastRow >= MAX_ELEMENT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("row out of bounds", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_ROW", NULL);
	return TCL_ERROR;
    }

    contentPtr->row = newRow;
    contentPtr->numRows = newNumRows;
    return TCL_OK;
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
 *
 *----------------------------------------------------------------------
 */

static int
CheckSlotData(
    Gridder *containerPtr,		/* The geometry container for this grid. */
    int slot,			/* Which slot to look at. */
    int slotType,		/* ROW or COLUMN. */
    int checkOnly)		/* Don't allocate new space if true. */
{
    int numSlot;		/* Number of slots already allocated (Space) */
    int end;			/* Last used constraint. */

    /*
     * If slot is out of bounds, return immediately.
     */

    if (slot < 0 || slot >= MAX_ELEMENT) {







|



|







2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
 *
 *----------------------------------------------------------------------
 */

static int
CheckSlotData(
    Gridder *containerPtr,		/* The geometry container for this grid. */
    Tcl_Size slot,			/* Which slot to look at. */
    int slotType,		/* ROW or COLUMN. */
    int checkOnly)		/* Don't allocate new space if true. */
{
    Tcl_Size 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) {
2820
2821
2822
2823
2824
2825
2826

2827



2828
2829
2830



2831
2832
2833
2834
2835
2836
2837
 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(

    void *memPtr)		/* Info about window that is now dead. */



{
    Gridder *gridPtr = (Gridder *)memPtr;




    if (gridPtr->containerDataPtr != NULL) {
	if (gridPtr->containerDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> rowPtr);
	}
	if (gridPtr->containerDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> columnPtr);
	}







>

>
>
>



>
>
>







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
 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Info about window that is now dead. */
#else
    char *memPtr)
#endif
{
    Gridder *gridPtr = (Gridder *)memPtr;

    if (gridPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
    }
    if (gridPtr->containerDataPtr != NULL) {
	if (gridPtr->containerDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> rowPtr);
	}
	if (gridPtr->containerDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> columnPtr);
	}
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
 *	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) {







|







2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
 *	information. If it was just resized, re-configure its content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
GridStructureProc(
    void *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) {
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid);
    } else if (eventPtr->type == MapNotify) {
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {







|







2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree(gridPtr, DestroyGrid);
    } else if (eventPtr->type == MapNotify) {
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
 */

static int
ConfigureContent(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Any window in application containing
				 * content. Used to look up content names. */
    int objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[])	/* Argument objects: contains one or more
				 * window names followed by any number of
				 * "option value" pairs. Caller must make sure
				 * that there is at least one window name. */
{
    Gridder *containerPtr = NULL;
    Gridder *contentPtr;







|







2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
 */

static int
ConfigureContent(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Any window in application containing
				 * content. Used to look up content names. */
    Tcl_Size objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[])	/* Argument objects: contains one or more
				 * window names followed by any number of
				 * "option value" pairs. Caller must make sure
				 * that there is at least one window name. */
{
    Gridder *containerPtr = NULL;
    Gridder *contentPtr;
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996

    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	TkSizeT length;
	char prevChar = firstChar;

	string = TkGetStringFromObj(objv[i], &length);
    	firstChar = string[0];

	if (firstChar == '.') {
	    /*
	     * Check that windows are valid, and locate the first content's
	     * parent window (default for -in).
	     */







|


|







2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003

    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	Tcl_Size length;
	char prevChar = firstChar;

	string = Tcl_GetStringFromObj(objv[i], &length);
    	firstChar = string[0];

	if (firstChar == '.') {
	    /*
	     * Check that windows are valid, and locate the first content's
	     * parent window (default for -in).
	     */
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
	    Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	    return TCL_ERROR;
	}

	if ((firstChar == REL_HORIZ) && ((numWindows == 0) ||
		(prevChar == REL_SKIP) || (prevChar == REL_VERT))) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "must specify window before shortcut '-'", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)
		|| (firstChar == REL_HORIZ)) {
	    continue;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid window shortcut, \"%s\" should be '-', 'x', or '^'",
		string));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    numWindows = i;

    if ((objc - numWindows) & 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"extra option or option with no value", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	return TCL_ERROR;
    }

    /*
     * Go through all options looking for -in and -row, which are needed to be
     * found first to handle the special case where ^ is used on a row without







|



















|







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
	    Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	    return TCL_ERROR;
	}

	if ((firstChar == REL_HORIZ) && ((numWindows == 0) ||
		(prevChar == REL_SKIP) || (prevChar == REL_VERT))) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "must specify window before shortcut '-'", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)
		|| (firstChar == REL_HORIZ)) {
	    continue;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid window shortcut, \"%s\" should be '-', 'x', or '^'",
		string));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    numWindows = i;

    if ((objc - numWindows) & 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"extra option or option with no value", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL);
	return TCL_ERROR;
    }

    /*
     * Go through all options looking for -in and -row, which are needed to be
     * found first to handle the special case where ^ is used on a row without
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
	    case CONF_IN:
		if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
			&other) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (other == content) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "window can't be managed in itself", -1));
		    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
		    return TCL_ERROR;
		}
		positionGiven = 1;
		containerPtr = GetGrid(other);
		InitContainerData(containerPtr);
		break;







|







3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
	    case CONF_IN:
		if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
			&other) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (other == content) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "window can't be managed in itself", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
		    return TCL_ERROR;
		}
		positionGiven = 1;
		containerPtr = GetGrid(other);
		InitContainerData(containerPtr);
		break;
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't use '^', can't find container window", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Count the number of consecutive ^'s starting from this position.
	 */







|







3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't use '^', can't find container window", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Count the number of consecutive ^'s starting from this position.
	 */
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find content to extend with \"^\"", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}
    }

    if (containerPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't determine container window", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    SetGridSize(containerPtr);

    /*
     * If we have emptied this container from content it means we are no longer







|







|







3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find content to extend with \"^\"", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}
    }

    if (containerPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't determine container window", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    SetGridSize(containerPtr);

    /*
     * If we have emptied this container from content it means we are no longer

Added generic/tkIcu.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
/*
 * tkIcu.c --
 *
 * 	tkIcu.c implements various Tk commands which can find
 * 	grapheme cluster and workchar bounderies in Unicode strings.
 *
 * Copyright © 2021 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"

/*
 * Runtime linking of libicu.
 */
typedef enum UBreakIteratorTypex {
	  UBRK_CHARACTERX = 0,
	  UBRK_WORDX = 1
} UBreakIteratorTypex;

typedef enum UErrorCodex {
    U_ZERO_ERRORZ              =  0     /**< No error, no warning. */
} UErrorCodex;

typedef void *(*fn_icu_open)(UBreakIteratorTypex, const char *,
	const uint16_t *, int32_t, UErrorCodex *);
typedef void	(*fn_icu_close)(void *);
typedef int32_t	(*fn_icu_preceding)(void *, int32_t);
typedef int32_t	(*fn_icu_following)(void *, int32_t);
typedef int32_t	(*fn_icu_previous)(void *);
typedef int32_t	(*fn_icu_next)(void *);
typedef void	(*fn_icu_setText)(void *, const void *, int32_t, UErrorCodex *);

static struct {
    size_t				nopen;
    Tcl_LoadHandle		lib;
    fn_icu_open			open;
    fn_icu_close		close;
    fn_icu_preceding	preceding;
    fn_icu_following	following;
    fn_icu_previous	previous;
    fn_icu_next	next;
    fn_icu_setText	setText;
} icu_fns = {
    0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

#define FLAG_WORD 1
#define FLAG_FOLLOWING 4
#define FLAG_SPACE 8

#define icu_open			icu_fns.open
#define icu_close			icu_fns.close
#define icu_preceding		icu_fns.preceding
#define icu_following		icu_fns.following
#define icu_previous		icu_fns.previous
#define icu_next		icu_fns.next
#define icu_setText		icu_fns.setText

TCL_DECLARE_MUTEX(icu_mutex);

static int
startEndOfCmd(
    void *clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_DString ds;
    Tcl_Size len;
    const char *str;
    UErrorCodex errorCode = U_ZERO_ERRORZ;
    void *it;
    Tcl_Size idx;
    int flags = PTR2INT(clientData);
    const uint16_t *ustr;
    const char *locale = NULL;

    if ((unsigned)(objc - 3) > 1) {
	Tcl_WrongNumArgs(interp, 1 , objv, "str start ?locale?");
	return TCL_ERROR;
    }
    if (objc > 3) {
	locale = Tcl_GetString(objv[3]);
	if (!*locale) {
	    locale = NULL;
	}
    }
    Tcl_DStringInit(&ds);
    str = Tcl_GetStringFromObj(objv[1], &len);
    Tcl_UtfToChar16DString(str, len, &ds);
    len = Tcl_DStringLength(&ds)/2;
    Tcl_Size ulen = Tcl_GetCharLength(objv[1]);
    if (TkGetIntForIndex(objv[2], ulen-1, 0, &idx) != TCL_OK) {
	Tcl_DStringFree(&ds);
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"", Tcl_GetString(objv[2])));
	Tcl_SetErrorCode(interp, "TK", "ICU", "INDEX", NULL);
	return TCL_ERROR;
    }
    it = icu_open((UBreakIteratorTypex)(flags&3), locale,
    		NULL, -1, &errorCode);
    if (it != NULL) {
	errorCode = U_ZERO_ERRORZ;
	ustr = (const uint16_t *)Tcl_DStringValue(&ds);
	icu_setText(it, ustr, len, &errorCode);
    }
    if (it == NULL || errorCode != U_ZERO_ERRORZ) {
    	Tcl_DStringFree(&ds);
    	Tcl_SetObjResult(interp, Tcl_ObjPrintf("cannot open ICU iterator, errorcode: %d", (int)errorCode));
    	Tcl_SetErrorCode(interp, "TK", "ICU", "CANNOTOPEN", NULL);
    	return TCL_ERROR;
    }
    if (idx > 0 && len != ulen) {
	/* The string contains codepoints > \uFFFF. Determine UTF-16 index */
	Tcl_Size newIdx = 0;
	for (Tcl_Size i = 0; i < idx; i++) {
	    newIdx += 1 + (((newIdx < (Tcl_Size)len-1) && (ustr[newIdx]&0xFC00) == 0xD800) && ((ustr[newIdx+1]&0xFC00) == 0xDC00));
	}
	idx = newIdx;
    }
    if (flags & FLAG_FOLLOWING) {
	if ((idx < 0) && (flags & FLAG_WORD)) {
	    idx = 0;
	}
	idx = icu_following(it, idx);
	if ((flags & FLAG_WORD) && idx >= len) {
	    idx = -1;
	}
    } else if (idx > 0) {
	if (!(flags & FLAG_WORD)) {
	    idx += 1 + (((ustr[idx]&0xFC00) == 0xD800) && ((ustr[idx+1]&0xFC00) == 0xDC00));
	}
	idx = icu_preceding(it, idx);
	if (idx == 0 && (flags & FLAG_WORD)) {
	    flags &= ~FLAG_WORD; /* If 0 is reached here, don't do a further search */
	}
    }
    if ((flags & FLAG_WORD) && (idx != TCL_INDEX_NONE)) {
	if (!(flags & FLAG_SPACE) == ((idx >= len) || Tcl_UniCharIsSpace(ustr[idx]))) {
	    if (flags & FLAG_FOLLOWING) {
		idx = icu_next(it);
		if (idx >= len) {
		    idx = TCL_INDEX_NONE;
		}
	    } else {
		idx = icu_previous(it);
	    }
	} else if (idx == 0 && !(flags & FLAG_FOLLOWING)) {
	    idx = TCL_INDEX_NONE;
	}
    }
    icu_close(it);
    Tcl_DStringFree(&ds);
    if (idx != TCL_INDEX_NONE) {
	if (idx > 0 && len != ulen) {
	    /* The string contains codepoints > \uFFFF. Determine UTF-32 index */
	    Tcl_Size newIdx = 1;
	    for (Tcl_Size i = 1; i < idx; i++) {
    	if (((ustr[i-1]&0xFC00) != 0xD800) || ((ustr[i]&0xFC00) != 0xDC00)) newIdx++;
	    }
	    idx = newIdx;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(idx));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SysNotifyDeleteCmd --
 *
 *      Delete notification and clean up.
 *
 * Results:
 *	Window destroyed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
icuCleanup(
    TCL_UNUSED(void *))
{
    Tcl_MutexLock(&icu_mutex);
    if (icu_fns.nopen-- <= 1) {
	if (icu_fns.lib != NULL) {
	    Tcl_FSUnloadFile(NULL, icu_fns.lib);
	}
	memset(&icu_fns, 0, sizeof(icu_fns));
    }
    Tcl_MutexUnlock(&icu_mutex);
}

void
Icu_Init(
    Tcl_Interp *interp)
{
    Tcl_MutexLock(&icu_mutex);
    char symbol[24];
    char icuversion[4] = "_80"; /* Highest ICU version + 1 */

    if (icu_fns.nopen == 0) {
	int i = 0;
	Tcl_Obj *nameobj;
	static const char *iculibs[] = {
#if defined(_WIN32)
	    "icuuc??.dll", /* When running under Windows, user-provided */
	    NULL,
	    "cygicuuc??.dll", /* When running under Cygwin */
#elif defined(__CYGWIN__)
	    "cygicuuc??.dll",
#elif defined(MAC_OSX_TCL)
	    "libicuuc.??.dylib",
#else
	    "libicuuc.so.??",
#endif
	    NULL
	};

	/* Going back down to ICU version 60 */
	while ((icu_fns.lib == NULL) && (icuversion[1] >= '6')) {
	    if (--icuversion[2] < '0') {
		icuversion[1]--; icuversion[2] = '9';
	    }
#if defined(_WIN32) && !defined(STATIC_BUILD)
	    if (tclStubsPtr->tcl_CreateFileHandler) {
		/* Running on Cygwin, so try to load the cygwin icu dll */
		i = 2;
	    } else
#endif
	    i = 0;
	    while (iculibs[i] != NULL) {
		Tcl_ResetResult(interp);
		nameobj = Tcl_NewStringObj(iculibs[i], TCL_INDEX_NONE);
		char *nameStr = Tcl_GetString(nameobj);
		char *p = strchr(nameStr, '?');
		if (p != NULL) {
		    memcpy(p, icuversion+1, 2);
		}
		Tcl_IncrRefCount(nameobj);
		if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.lib)
			== TCL_OK) {
		    if (p == NULL) {
			icuversion[0] = '\0';
		    }
		    Tcl_DecrRefCount(nameobj);
		    break;
		}
		Tcl_DecrRefCount(nameobj);
		++i;
	    }
	}
#if defined(_WIN32)
	if (icu_fns.lib == NULL) {
	    Tcl_ResetResult(interp);
		nameobj = Tcl_NewStringObj("icu.dll", TCL_INDEX_NONE);
		Tcl_IncrRefCount(nameobj);
		if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.lib)
			== TCL_OK) {
		    icuversion[0] = '\0';
		}
		Tcl_DecrRefCount(nameobj);
	}
	if (icu_fns.lib == NULL) {
	    Tcl_ResetResult(interp);
		nameobj = Tcl_NewStringObj("icuuc.dll", TCL_INDEX_NONE);
		Tcl_IncrRefCount(nameobj);
		if (Tcl_LoadFile(interp, nameobj, NULL, 0, NULL, &icu_fns.lib)
			== TCL_OK) {
		    icuversion[0] = '\0';
		}
		Tcl_DecrRefCount(nameobj);
	}
#endif
	if (icu_fns.lib != NULL) {
#define ICU_SYM(name)							\
	    strcpy(symbol, "ubrk_" #name ); \
	    strcat(symbol, icuversion); \
	    icu_fns.name = (fn_icu_ ## name)				\
		Tcl_FindSymbol(NULL, icu_fns.lib, symbol)
	    ICU_SYM(open);
	    ICU_SYM(close);
	    ICU_SYM(preceding);
	    ICU_SYM(following);
	    ICU_SYM(previous);
	    ICU_SYM(next);
	    ICU_SYM(setText);
#undef ICU_SYM
	}
    }
    Tcl_MutexUnlock(&icu_mutex);

    if (icu_fns.lib != NULL) {
	Tcl_CreateObjCommand(interp, "::tk::startOfCluster", startEndOfCmd,
		INT2PTR(0), icuCleanup);
	Tcl_CreateObjCommand(interp, "::tk::startOfNextWord", startEndOfCmd,
		INT2PTR(FLAG_WORD|FLAG_FOLLOWING), icuCleanup);
	Tcl_CreateObjCommand(interp, "::tk::startOfPreviousWord", startEndOfCmd,
		INT2PTR(FLAG_WORD), icuCleanup);
	Tcl_CreateObjCommand(interp, "::tk::endOfCluster", startEndOfCmd,
		INT2PTR(FLAG_FOLLOWING), icuCleanup);
	Tcl_CreateObjCommand(interp, "::tk::endOfWord", startEndOfCmd,
		INT2PTR(FLAG_WORD|FLAG_FOLLOWING|FLAG_SPACE), icuCleanup);
    icu_fns.nopen += 5;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * coding: utf-8
 * End:
 */

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
/*
 * 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.
 *
 * 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 ImageModel *modelPtr;
				/* Model for this image (identifiers image
				 * manager, for example). */
    ClientData instanceData;	/* One word argument to pass to image manager
				 * when dealing with this image instance. */
    Tk_ImageChangedProc *changeProc;
				/* Code in widget to call when image changes
				 * in a way that affects redisplay. */
    ClientData widgetClientData;/* Argument to pass to changeProc. */
    struct Image *nextPtr;	/* Next in list of all image instances


				 * associated with the same name. */
} Image;

/*
 * For each image model there is one of the following structures, which
 * represents a name in the image table and all of the images instantiated
 * from it. Entries in mainPtr->imageTable point to these structures.
 */

typedef struct ImageModel {
    Tk_ImageType *typePtr;	/* Information about image type. NULL means
				 * that no image manager owns this image: the
				 * image was deleted. */
    ClientData modelData;	/* One-word argument to pass to image mgr when
				 * dealing with the model, as opposed to
				 * instances. */
    int width, height;		/* Last known dimensions for image. */
    Tcl_HashTable *tablePtr;	/* Pointer to hash table containing image (the
				 * imageTable field in some TkMainInfo
				 * structure). */
    Tcl_HashEntry *hPtr;	/* Hash entry in mainPtr->imageTable for this






|
|






>
>
>
>

















|




|

>
>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * 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 © 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Each call to Tk_GetImage returns a pointer to one of the following
 * structures, which is used as a token by clients (widgets) that display
 * images.
 */

typedef struct Image {
    Tk_Window tkwin;		/* Window passed to Tk_GetImage (needed to
				 * "re-get" the image later if the manager
				 * changes). */
    Display *display;		/* Display for tkwin. Needed because when the
				 * image is eventually freed tkwin may not
				 * exist anymore. */
    struct ImageModel *modelPtr;
				/* Model for this image (identifiers image
				 * manager, for example). */
    void *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. */
    void *widgetClientData;/* Argument to pass to changeProc. */
    struct Image *nextPtr;	/* Next in list of all image instances
				 * associated with the same name. */
    struct Image *prevPtr;	/* Previous in list of all image instances
				 * associated with the same name. */
} Image;

/*
 * For each image model there is one of the following structures, which
 * represents a name in the image table and all of the images instantiated
 * from it. Entries in mainPtr->imageTable point to these structures.
 */

typedef struct ImageModel {
    Tk_ImageType *typePtr;	/* Information about image type. NULL means
				 * that no image manager owns this image: the
				 * image was deleted. */
    void *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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
 */

static void		ImageTypeThreadExitProc(ClientData clientData);
static void		DeleteImage(ImageModel *modelPtr);
static void		EventuallyDeleteImage(ImageModel *modelPtr,
			    int forgetImageHashNow);

/*
 *----------------------------------------------------------------------
 *
 * ImageTypeThreadExitProc --







|
|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
 */

static void		ImageTypeThreadExitProc(void *clientData);
static Tcl_FreeProc	DeleteImage;
static void		EventuallyDeleteImage(ImageModel *modelPtr,
			    int forgetImageHashNow);

/*
 *----------------------------------------------------------------------
 *
 * ImageTypeThreadExitProc --
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
	ckfree(freePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateOldImageType, Tk_CreateImageType --
 *
 *	This function is invoked by an image manager to tell Tk about a new
 *	kind of image and the functions that manage the new type. The function
 *	is typically invoked during Tcl_AppInit.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The new image type is entered into a table used in the "image create"
 *	command.
 *
 *----------------------------------------------------------------------
 */

void
Tk_CreateOldImageType(
    const Tk_ImageType *typePtr)
				/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_ImageType *copyPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL);
    }
    copyPtr = (Tk_ImageType *)ckalloc(sizeof(Tk_ImageType));
    *copyPtr = *typePtr;
    copyPtr->nextPtr = tsdPtr->oldImageTypeList;
    tsdPtr->oldImageTypeList = copyPtr;
}

void
Tk_CreateImageType(
    const Tk_ImageType *typePtr)
				/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{







|















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149





















150
151
152
153
154
155
156
	ckfree(freePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateImageType --
 *
 *	This function is invoked by an image manager to tell Tk about a new
 *	kind of image and the functions that manage the new type. The function
 *	is typically invoked during Tcl_AppInit.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The new image type is entered into a table used in the "image create"
 *	command.
 *
 *----------------------------------------------------------------------
 */






















void
Tk_CreateImageType(
    const Tk_ImageType *typePtr)
				/* Structure describing the type. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ImageObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    static const char *const imageOptions[] = {
	"create", "delete", "height", "inuse", "names", "type", "types",
	"width", NULL







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ImageObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    static const char *const imageOptions[] = {
	"create", "delete", "height", "inuse", "names", "type", "types",
	"width", NULL
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	/*
	 * Figure out a name to use for the new image.
	 */

	if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
	    do {
		dispPtr->imageId++;
		sprintf(idString, "image%d", dispPtr->imageId);
		name = idString;
	    } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL);
	    firstOption = 3;
	} else {
	    TkWindow *topWin;

	    name = arg;







|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
	/*
	 * Figure out a name to use for the new image.
	 */

	if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
	    do {
		dispPtr->imageId++;
		snprintf(idString, sizeof(idString), "image%d", dispPtr->imageId);
		name = idString;
	    } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL);
	    firstOption = 3;
	} else {
	    TkWindow *topWin;

	    name = arg;
364
365
366
367
368
369
370







371
372


373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
	    args = (Tcl_Obj **)ckalloc((objc+1) * sizeof(Tcl_Obj *));
	    for (i = 0; i < objc; i++) {
		args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
	    }
	    args[objc] = NULL;
	}
	Tcl_Preserve(modelPtr);







	if (typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData) != TCL_OK){


	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
	Tcl_Release(modelPtr);
	if (oldimage) {
	    ckfree(args);
	}
	modelPtr->typePtr = typePtr;
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin,
		    modelPtr->modelData);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
	break;
    }
    case IMAGE_DELETE:
	for (i = 2; i < objc; i++) {
	    arg = Tcl_GetString(objv[i]);
	    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
	    if (hPtr == NULL) {
		goto alreadyDeleted;
	    }
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage(modelPtr);
	}
	break;
    case IMAGE_NAMES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
	resultObj = Tcl_NewObj();
	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		continue;
	    }
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    case IMAGE_TYPES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, -1));
	}
	for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case IMAGE_HEIGHT:
    case IMAGE_INUSE:
    case IMAGE_TYPE:







>
>
>
>
>
>
>
|
|
>
>


















|













|















|












|




|







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
	    args = (Tcl_Obj **)ckalloc((objc+1) * sizeof(Tcl_Obj *));
	    for (i = 0; i < objc; i++) {
		args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
	    }
	    args[objc] = NULL;
	}
	Tcl_Preserve(modelPtr);
	if (oldimage) {
	    typedef int (OldCreateProc)(Tcl_Interp*, char*, Tcl_Size, char**,
		Tk_ImageType*, Tk_ImageModel, ClientData*);
	    i = ((OldCreateProc*)typePtr->createProc)(interp,
		(char*)name, objc, (char**)args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	} else {
	    i = typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	}
	if (i != TCL_OK){
	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
	Tcl_Release(modelPtr);
	if (oldimage) {
	    ckfree(args);
	}
	modelPtr->typePtr = typePtr;
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin,
		    modelPtr->modelData);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), TCL_INDEX_NONE));
	break;
    }
    case IMAGE_DELETE:
	for (i = 2; i < objc; i++) {
	    arg = Tcl_GetString(objv[i]);
	    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
	    if (hPtr == NULL) {
		goto alreadyDeleted;
	    }
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage((char *)modelPtr);
	}
	break;
    case IMAGE_NAMES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
	resultObj = Tcl_NewObj();
	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		continue;
	    }
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), TCL_INDEX_NONE));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    case IMAGE_TYPES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, TCL_INDEX_NONE));
	}
	for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, TCL_INDEX_NONE));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case IMAGE_HEIGHT:
    case IMAGE_INUSE:
    case IMAGE_TYPE:
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
	case IMAGE_INUSE:
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    modelPtr->typePtr && modelPtr->instancePtr));
	    break;
	case IMAGE_TYPE:
	    if (modelPtr->typePtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(modelPtr->typePtr->name, -1));
	    }
	    break;
	case IMAGE_WIDTH:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
	case IMAGE_INUSE:
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    modelPtr->typePtr && modelPtr->instancePtr));
	    break;
	case IMAGE_TYPE:
	    if (modelPtr->typePtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(modelPtr->typePtr->name, TCL_INDEX_NONE));
	    }
	    break;
	case IMAGE_WIDTH:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
				 * be found. */
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    const char *name,		/* Name of desired image. */
    Tk_ImageChangedProc *changeProc,
				/* Function to invoke when redisplay is needed
				 * because image's pixels or size changed. */
    ClientData clientData)	/* One-word argument to pass to damageProc. */
{
    Tcl_HashEntry *hPtr;
    ImageModel *modelPtr;
    Image *imagePtr;

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
    if (hPtr == NULL) {







|







595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
				 * be found. */
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    const char *name,		/* Name of desired image. */
    Tk_ImageChangedProc *changeProc,
				/* Function to invoke when redisplay is needed
				 * because image's pixels or size changed. */
    void *clientData)	/* One-word argument to pass to damageProc. */
{
    Tcl_HashEntry *hPtr;
    ImageModel *modelPtr;
    Image *imagePtr;

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
    if (hPtr == NULL) {
627
628
629
630
631
632
633




634
635
636
637
638
639
640
    imagePtr->display = Tk_Display(tkwin);
    imagePtr->modelPtr = modelPtr;
    imagePtr->instanceData =
	    modelPtr->typePtr->getProc(tkwin, modelPtr->modelData);
    imagePtr->changeProc = changeProc;
    imagePtr->widgetClientData = clientData;
    imagePtr->nextPtr = modelPtr->instancePtr;




    modelPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image \"%s\" doesn't exist", name));







>
>
>
>







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
    imagePtr->display = Tk_Display(tkwin);
    imagePtr->modelPtr = modelPtr;
    imagePtr->instanceData =
	    modelPtr->typePtr->getProc(tkwin, modelPtr->modelData);
    imagePtr->changeProc = changeProc;
    imagePtr->widgetClientData = clientData;
    imagePtr->nextPtr = modelPtr->instancePtr;
    if (imagePtr->nextPtr) {
	imagePtr->nextPtr->prevPtr = imagePtr;
    }
    imagePtr->prevPtr = NULL;
    modelPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image \"%s\" doesn't exist", name));
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683


684
685

686
687
688
689
690
691
692
693
694
695
void
Tk_FreeImage(
    Tk_Image image)		/* Token for image that is no longer needed by
				 * a widget. */
{
    Image *imagePtr = (Image *) image;
    ImageModel *modelPtr = imagePtr->modelPtr;
    Image *prevPtr;

    /*
     * Clean up the particular instance.
     */

    if (modelPtr->typePtr != NULL) {
	modelPtr->typePtr->freeProc(imagePtr->instanceData,
		imagePtr->display);
    }
    prevPtr = modelPtr->instancePtr;
    if (prevPtr == imagePtr) {
	modelPtr->instancePtr = imagePtr->nextPtr;


    } else {
	while (prevPtr->nextPtr != imagePtr) {

	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = imagePtr->nextPtr;
    }
    ckfree(imagePtr);

    /*
     * If there are no more instances left for the model, and if the model
     * image has been deleted, then delete the model too.
     */







<









|
|
|
>
>

|
>
|

<







662
663
664
665
666
667
668

669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690
691
692
693
694
void
Tk_FreeImage(
    Tk_Image image)		/* Token for image that is no longer needed by
				 * a widget. */
{
    Image *imagePtr = (Image *) image;
    ImageModel *modelPtr = imagePtr->modelPtr;


    /*
     * Clean up the particular instance.
     */

    if (modelPtr->typePtr != NULL) {
	modelPtr->typePtr->freeProc(imagePtr->instanceData,
		imagePtr->display);
    }
    if (imagePtr->prevPtr) {
	imagePtr->prevPtr->nextPtr = imagePtr->nextPtr;
	if (imagePtr->nextPtr) {
	    imagePtr->nextPtr->prevPtr = imagePtr->prevPtr;
	}
    } else {
	modelPtr->instancePtr = imagePtr->nextPtr;
	if (modelPtr->instancePtr) {
	    modelPtr->instancePtr->prevPtr = NULL;
	}

    }
    ckfree(imagePtr);

    /*
     * If there are no more instances left for the model, and if the model
     * image has been deleted, then delete the model too.
     */
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((ImageModel *)Tcl_GetHashValue(hPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteImage --
 *







|







926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((char *)Tcl_GetHashValue(hPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteImage --
 *
950
951
952
953
954
955
956

957



958
959
960

961
962
963
964
965
966
967
 *	existing instances will not be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(

    ImageModel *modelPtr)	/* Pointer to main data structure for image. */



{
    Image *imagePtr;
    Tk_ImageType *typePtr;


    typePtr = modelPtr->typePtr;
    modelPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    typePtr->freeProc(imagePtr->instanceData, imagePtr->display);







>
|
>
>
>



>







949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
 *	existing instances will not be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(
#if TCL_MAJOR_VERSION > 8
    void *blockPtr)	/* Pointer to main data structure for image. */
#else
    char *blockPtr)
#endif
{
    Image *imagePtr;
    Tk_ImageType *typePtr;
    ImageModel *modelPtr = (ImageModel *)blockPtr;

    typePtr = modelPtr->typePtr;
    modelPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    typePtr->freeProc(imagePtr->instanceData, imagePtr->display);
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
				 * to vanish. */
{
    if (forgetImageHashNow) {
	modelPtr->hPtr = NULL;
    }
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, (Tcl_FreeProc *) DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --







|







1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
				 * to vanish. */
{
    if (forgetImageHashNow) {
	modelPtr->hPtr = NULL;
    }
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tk_GetImageModelData(
    Tcl_Interp *interp,		/* Interpreter in which the image was
				 * created. */
    const char *name,		/* Name of image. */
    const Tk_ImageType **typePtrPtr)
				/* Points to location to fill in with pointer
				 * to type information for image. */







|







1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
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. */

Changes to generic/tkImgBmap.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkImgBmap.c --
 *
 *	This procedure implements images of type "bitmap" for Tk.
 *
 * 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"

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

/*
 * The type record for bitmap images:
 */

static int		GetByte(Tcl_Channel chan);
static int		ImgBmapCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const 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);
static void		ImgBmapDelete(ClientData clientData);
static int		ImgBmapPostscript(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psinfo, int x, int y,
			    int width, int height, int prepass);

Tk_ImageType tkBitmapImageType = {
    "bitmap",			/* name */
    ImgBmapCreate,		/* createProc */







|

|
|
|



|
|
|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

/*
 * The type record for bitmap images:
 */

static int		GetByte(Tcl_Channel chan);
static int		ImgBmapCreate(Tcl_Interp *interp,
			    const char *name, Tcl_Size objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    void **clientDataPtr);
static void	*ImgBmapGet(Tk_Window tkwin, void *clientData);
static void		ImgBmapDisplay(void *clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width, int height,
			    int drawableX, int drawableY);
static void		ImgBmapFree(void *clientData, Display *display);
static void		ImgBmapDelete(void *clientData);
static int		ImgBmapPostscript(void *clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psinfo, int x, int y,
			    int width, int height, int prepass);

Tk_ImageType tkBitmapImageType = {
    "bitmap",			/* name */
    ImgBmapCreate,		/* createProc */
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    int wordLength;		/* Number of non-NULL bytes in word. */
} ParseInfo;

/*
 * Prototypes for procedures used only locally in this file:
 */

static int		ImgBmapCmd(ClientData clientData, Tcl_Interp *interp,
			    int argc, Tcl_Obj *const objv[]);
static void		ImgBmapCmdDeletedProc(ClientData clientData);
static void		ImgBmapConfigureInstance(BitmapInstance *instancePtr);
static int		ImgBmapConfigureModel(BitmapModel *modelPtr,
			    int argc, Tcl_Obj *const objv[], int flags);
static int		NextBitmapWord(ParseInfo *parseInfoPtr);

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCreate --
 *







|
|
|


|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    int wordLength;		/* Number of non-NULL bytes in word. */
} ParseInfo;

/*
 * Prototypes for procedures used only locally in this file:
 */

static int		ImgBmapCmd(void *clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static void		ImgBmapCmdDeletedProc(void *clientData);
static void		ImgBmapConfigureInstance(BitmapInstance *instancePtr);
static int		ImgBmapConfigureModel(BitmapModel *modelPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[], int flags);
static int		NextBitmapWord(ParseInfo *parseInfoPtr);

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCreate --
 *
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
 */

static int
ImgBmapCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,			/* Name to use for image. */
    int argc,			/* Number of arguments. */
    Tcl_Obj *const argv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    const Tk_ImageType *typePtr,/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    ClientData *clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    BitmapModel *modelPtr = (BitmapModel *)ckalloc(sizeof(BitmapModel));
    (void)typePtr;

    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgBmapCmd,
	    modelPtr, ImgBmapCmdDeletedProc);
    modelPtr->width = modelPtr->height = 0;
    modelPtr->data = NULL;
    modelPtr->maskData = NULL;
    modelPtr->fgUid = NULL;
    modelPtr->bgUid = NULL;
    modelPtr->fileString = NULL;
    modelPtr->dataString = NULL;
    modelPtr->maskFileString = NULL;
    modelPtr->maskDataString = NULL;
    modelPtr->instancePtr = NULL;
    if (ImgBmapConfigureModel(modelPtr, argc, argv, 0) != TCL_OK) {
	ImgBmapDelete(modelPtr);
	return TCL_ERROR;
    }
    *clientDataPtr = modelPtr;
    return TCL_OK;
}








|
|

|


|



<















|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
 */

static int
ImgBmapCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,			/* Name to use for image. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    void **clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    BitmapModel *modelPtr = (BitmapModel *)ckalloc(sizeof(BitmapModel));


    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, objc, objv, 0) != TCL_OK) {
	ImgBmapDelete(modelPtr);
	return TCL_ERROR;
    }
    *clientDataPtr = modelPtr;
    return TCL_OK;
}

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
 *----------------------------------------------------------------------
 */

static int
ImgBmapConfigureModel(
    BitmapModel *modelPtr,	/* Pointer to data structure describing
				 * overall bitmap image to (reconfigure). */
    int objc,			/* Number of entries in objv. */
    Tcl_Obj *const objv[],	/* Pairs of configuration options for image. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    BitmapInstance *instancePtr;
    int maskWidth, maskHeight, dummy1, dummy2;
    const char **argv = (const char **)ckalloc((objc+1) * sizeof(char *));

    for (dummy1 = 0; dummy1 < objc; dummy1++) {
	argv[dummy1] = Tcl_GetString(objv[dummy1]);
    }
    argv[objc] = NULL;

    if (Tk_ConfigureWidget(modelPtr->interp, Tk_MainWindow(modelPtr->interp),
	    configSpecs, objc, argv, (char *) modelPtr, flags) != TCL_OK) {
	ckfree(argv);
	return TCL_ERROR;
    }
    ckfree(argv);

    /*
     * Parse the bitmap and/or mask to create binary data. Make sure that the
     * bitmap and mask have the same dimensions.
     */

    if (modelPtr->data != NULL) {







|






<

<
<
<
<
<

|
<


<







227
228
229
230
231
232
233
234
235
236
237
238
239
240

241





242
243

244
245

246
247
248
249
250
251
252
 *----------------------------------------------------------------------
 */

static int
ImgBmapConfigureModel(
    BitmapModel *modelPtr,	/* Pointer to data structure describing
				 * overall bitmap image to (reconfigure). */
    Tcl_Size 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;







    if (Tk_ConfigureWidget(modelPtr->interp, Tk_MainWindow(modelPtr->interp),
	    configSpecs, objc, objv, modelPtr, flags) != TCL_OK) {

	return TCL_ERROR;
    }


    /*
     * Parse the bitmap and/or mask to create binary data. Make sure that the
     * bitmap and mask have the same dimensions.
     */

    if (modelPtr->data != NULL) {
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	ckfree(modelPtr->maskData);
	modelPtr->maskData = NULL;
    }
    if ((modelPtr->maskFileString != NULL)
	    || (modelPtr->maskDataString != NULL)) {
	if (modelPtr->data == NULL) {
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "can't have mask without bitmap", -1));
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "NO_BITMAP", NULL);
	    return TCL_ERROR;
	}
	modelPtr->maskData = TkGetBitmapData(modelPtr->interp,
		modelPtr->maskDataString, modelPtr->maskFileString,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (modelPtr->maskData == NULL) {
	    return TCL_ERROR;
	}
	if ((maskWidth != modelPtr->width)
		|| (maskHeight != modelPtr->height)) {
	    ckfree(modelPtr->maskData);
	    modelPtr->maskData = NULL;
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "bitmap and mask have different sizes", -1));
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "MASK_SIZE", NULL);
	    return TCL_ERROR;
	}
    }

    /*







|















|







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	ckfree(modelPtr->maskData);
	modelPtr->maskData = NULL;
    }
    if ((modelPtr->maskFileString != NULL)
	    || (modelPtr->maskDataString != NULL)) {
	if (modelPtr->data == NULL) {
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "can't have mask without bitmap", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "NO_BITMAP", NULL);
	    return TCL_ERROR;
	}
	modelPtr->maskData = TkGetBitmapData(modelPtr->interp,
		modelPtr->maskDataString, modelPtr->maskFileString,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (modelPtr->maskData == NULL) {
	    return TCL_ERROR;
	}
	if ((maskWidth != modelPtr->width)
		|| (maskHeight != modelPtr->height)) {
	    ckfree(modelPtr->maskData);
	    modelPtr->maskData = NULL;
	    Tcl_SetObjResult(modelPtr->interp, Tcl_NewStringObj(
		    "bitmap and mask have different sizes", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(modelPtr->interp, "TK", "IMAGE", "BITMAP",
		    "MASK_SIZE", NULL);
	    return TCL_ERROR;
	}
    }

    /*
496
497
498
499
500
501
502
503
504
505

506
507
508
509

510
511
512
513
514
515
516
	if ((interp != NULL) && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get bitmap data from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    return NULL;
	}
	expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer);
	if (expandedFileName == NULL) {
	    return NULL;

	}
	pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0);
	Tcl_DStringFree(&buffer);
	if (pi.chan == NULL) {

	    if (interp != NULL) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't read bitmap file \"%s\": %s",
			fileName, Tcl_PosixError(interp)));
	    }
	    return NULL;







|

|
>




>







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
	if ((interp != NULL) && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get bitmap data from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    return NULL;
	}
	expandedFileName = Tcl_TranslateFileName(NULL, fileName, &buffer);
	if (expandedFileName == NULL) {
	    Tcl_SetErrno(ENOENT);
	    goto cannotRead;
	}
	pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0);
	Tcl_DStringFree(&buffer);
	if (pi.chan == NULL) {
	cannotRead:
	    if (interp != NULL) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't read bitmap file \"%s\": %s",
			fileName, Tcl_PosixError(interp)));
	    }
	    return NULL;
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
		    goto getData;
		}
	    }
	} else if ((pi.word[0] == '{') && (pi.word[1] == 0)) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"format error in bitmap data; looks like it's an"
			" obsolete X10 bitmap file", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "OBSOLETE",
			NULL);
	    }
	    goto errorCleanup;
	}
    }








|







591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
		    goto getData;
		}
	    }
	} else if ((pi.word[0] == '{') && (pi.word[1] == 0)) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"format error in bitmap data; looks like it's an"
			" obsolete X10 bitmap file", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "OBSOLETE",
			NULL);
	    }
	    goto errorCleanup;
	}
    }

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    *hotXPtr = hotX;
    *hotYPtr = hotY;
    return data;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"format error in bitmap data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "FORMAT", NULL);
    }

  errorCleanup:
    if (data != NULL) {
	ckfree(data);
    }







|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
    *hotXPtr = hotX;
    *hotYPtr = hotY;
    return data;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"format error in bitmap data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "FORMAT", NULL);
    }

  errorCleanup:
    if (data != NULL) {
	ckfree(data);
    }
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ImgBmapCmd(
    ClientData clientData,	/* Information about the image model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const bmapOptions[] = {"cget", "configure", NULL};
    BitmapModel *modelPtr = (BitmapModel *)clientData;
    int index;







|







740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ImgBmapCmd(
    void *clientData,	/* Information about the image model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const bmapOptions[] = {"cget", "configure", NULL};
    BitmapModel *modelPtr = (BitmapModel *)clientData;
    int index;
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    switch (index) {
    case 0: /* cget */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		(char *) modelPtr, Tcl_GetString(objv[2]), 0);
    case 1: /* configure */
	if (objc == 2) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr, NULL, 0);
	} else if (objc == 3) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr,
		    Tcl_GetString(objv[2]), 0);
	} else {
	    return ImgBmapConfigureModel(modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
    default:
	Tcl_Panic("bad const entries to bmapOptions in ImgBmapCmd");







|



|


|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
    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,
		modelPtr, Tcl_GetString(objv[2]), 0);
    case 1: /* configure */
	if (objc == 2) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, modelPtr, NULL, 0);
	} else if (objc == 3) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, modelPtr,
		    Tcl_GetString(objv[2]), 0);
	} else {
	    return ImgBmapConfigureModel(modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}
    default:
	Tcl_Panic("bad const entries to bmapOptions in ImgBmapCmd");
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
 * Side effects:
 *	A data structure is set up for the instance (or, an existing instance
 *	is re-used for the new one).
 *
 *----------------------------------------------------------------------
 */

static ClientData
ImgBmapGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData modelData)	/* Pointer to our model structure for the
				 * image. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;
    BitmapInstance *instancePtr;

    /*
     * See if there is already an instance for this window. If so then just







|



|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
 * Side effects:
 *	A data structure is set up for the instance (or, an existing instance
 *	is re-used for the new one).
 *
 *----------------------------------------------------------------------
 */

static void *
ImgBmapGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    void *modelData)	/* Pointer to our model structure for the
				 * image. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;
    BitmapInstance *instancePtr;

    /*
     * See if there is already an instance for this window. If so then just
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDisplay(
    ClientData clientData,	/* Pointer to BitmapInstance structure for
				 * instance to be displayed. */
    Display *display,		/* Display on which to draw image. */
    Drawable drawable,		/* Pixmap or window in which to draw image. */
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to draw. */
    int drawableX, int drawableY)







|







872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDisplay(
    void *clientData,	/* Pointer to BitmapInstance structure for
				 * instance to be displayed. */
    Display *display,		/* Display on which to draw image. */
    Drawable drawable,		/* Pixmap or window in which to draw image. */
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to draw. */
    int drawableX, int drawableY)
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
 *	Internal data structures get cleaned up.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapFree(
    ClientData clientData,	/* Pointer to BitmapInstance structure for
				 * instance to be displayed. */
    Display *display)		/* Display containing window that used image. */
{
    BitmapInstance *instancePtr = (BitmapInstance *)clientData;
    BitmapInstance *prevPtr;

    if (instancePtr->refCount-- > 1) {







|







933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
 *	Internal data structures get cleaned up.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapFree(
    void *clientData,	/* Pointer to BitmapInstance structure for
				 * instance to be displayed. */
    Display *display)		/* Display containing window that used image. */
{
    BitmapInstance *instancePtr = (BitmapInstance *)clientData;
    BitmapInstance *prevPtr;

    if (instancePtr->refCount-- > 1) {
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    ClientData modelData)	/* Pointer to BitmapModel structure for
				 * image. Must not have any more instances. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;

    if (modelPtr->instancePtr != NULL) {
	Tcl_Panic("tried to delete bitmap image when instances still exist");
    }
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
    }
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
    }
    Tk_FreeOptions(configSpecs, (char *) modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCmdDeletedProc --







|

















|







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
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    void *modelData)	/* Pointer to BitmapModel structure for
				 * image. Must not have any more instances. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;

    if (modelPtr->instancePtr != NULL) {
	Tcl_Panic("tried to delete bitmap image when instances still exist");
    }
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
    }
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
    }
    Tk_FreeOptions(configSpecs, modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCmdDeletedProc --
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapCmdDeletedProc(
    ClientData clientData)	/* Pointer to BitmapModel structure for
				 * image. */
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));







|







1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapCmdDeletedProc(
    void *clientData)	/* Pointer to BitmapModel structure for
				 * image. */
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
 */

static int
GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;
    size_t size;

    size = Tcl_Read(chan, &buffer, 1);
    if (size != 1) {
	return EOF;
    } else {
	return buffer;
    }
}

/*







<

|
<







1068
1069
1070
1071
1072
1073
1074

1075
1076

1077
1078
1079
1080
1081
1082
1083
 */

static int
GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;


    if (Tcl_Read(chan, &buffer, 1) != 1) {

	return EOF;
    } else {
	return buffer;
    }
}

/*
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177

    nBytePerRow = (width + 7) / 8;
    for (i=0; i<height; i++) {
	for (j=0; j<nBytePerRow; j++) {
	    Tcl_AppendPrintfToObj(psObj, " %02x",
		    bit_reverse[0xff & data[i*nBytePerRow + j]]);
	}
	Tcl_AppendToObj(psObj, "\n", -1);
    }

    Tcl_AppendToObj(psObj, ">} imagemask \n", -1);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapPostscript --
 *







|


|







1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168

    nBytePerRow = (width + 7) / 8;
    for (i=0; i<height; i++) {
	for (j=0; j<nBytePerRow; j++) {
	    Tcl_AppendPrintfToObj(psObj, " %02x",
		    bit_reverse[0xff & data[i*nBytePerRow + j]]);
	}
	Tcl_AppendToObj(psObj, "\n", TCL_INDEX_NONE);
    }

    Tcl_AppendToObj(psObj, ">} imagemask \n", TCL_INDEX_NONE);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapPostscript --
 *
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ImgBmapPostscript(
    ClientData clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psinfo,
    int x, int y, int width, int height,
    int prepass)
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;







|







1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ImgBmapPostscript(
    void *clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psinfo,
    int x, int y, int width, int height,
    int prepass)
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
     * than about 60k characters. If the bitmap data is that big or bigger,
     * we bail out.
     */

    if (modelPtr->width*modelPtr->height > 60000) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unable to generate postscript for bitmaps larger than 60000"
		" pixels", -1));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	return TCL_ERROR;
    }

    /*
     * Make our working space.
     */







|







1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
     * than about 60k characters. If the bitmap data is that big or bigger,
     * we bail out.
     */

    if (modelPtr->width*modelPtr->height > 60000) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unable to generate postscript for bitmaps larger than 60000"
		" pixels", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
	return TCL_ERROR;
    }

    /*
     * Make our working space.
     */
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (modelPtr->maskData == NULL) {
	    Tcl_AppendToObj(psObj,
		    "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto "
		    "closepath fill\n", -1);
	} else {
	    ImgBmapPsImagemask(psObj, modelPtr->width, modelPtr->height,
		    modelPtr->maskData);
	}
    }

    /*







|







1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (modelPtr->maskData == NULL) {
	    Tcl_AppendToObj(psObj,
		    "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto "
		    "closepath fill\n", TCL_INDEX_NONE);
	} else {
	    ImgBmapPsImagemask(psObj, modelPtr->width, modelPtr->height,
		    modelPtr->maskData);
	}
    }

    /*

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
/*
 * 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
 *
 * 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:
 *










|
|
|
|







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 © 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:
 *
42
43
44
45
46
47
48












49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

#define GIF_SPECIAL	(256)
#define GIF_PAD		(GIF_SPECIAL+1)
#define GIF_SPACE	(GIF_SPECIAL+2)
#define GIF_BAD		(GIF_SPECIAL+3)
#define GIF_DONE	(GIF_SPECIAL+4)













/*
 * structure to "mimic" FILE for Mread, so we can look like fread. The decoder
 * state keeps track of which byte we are about to read, or EOF.
 */

typedef struct mFile {
    unsigned char *data;	/* mmencoded source string */
    int c;			/* bits left over from previous character */
    int state;			/* decoder state (0-4 or GIF_DONE) */
    size_t length;			/* Total amount of bytes in data */
} MFile;

/*
 * Non-ASCII encoding support:
 * Most data in a GIF image is binary and is treated as such. However, a few
 * key bits are stashed in ASCII. If we try to compare those pieces to the
 * char they represent, it will fail on any non-ASCII (eg, EBCDIC) system. To







>
>
>
>
>
>
>
>
>
>
>
>









|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

#define GIF_SPECIAL	(256)
#define GIF_PAD		(GIF_SPECIAL+1)
#define GIF_SPACE	(GIF_SPECIAL+2)
#define GIF_BAD		(GIF_SPECIAL+3)
#define GIF_DONE	(GIF_SPECIAL+4)

/*
 * structure to hold the data of a Graphic Control Extension block.
 */

typedef struct {
    int blockPresent;		/* if 1, the block was read and is in scope */
    int transparent;		/* Transparency index */
    int delayTime;		/* update delay time in 10ms */
    int disposalMethod;		/* disposal method 0-3 */
    int userInteraction;	/* user interaction 0/1 */
} GIFGraphicControlExtensionBlock;

/*
 * structure to "mimic" FILE for Mread, so we can look like fread. The decoder
 * state keeps track of which byte we are about to read, or EOF.
 */

typedef struct mFile {
    unsigned char *data;	/* mmencoded source string */
    int c;			/* bits left over from previous character */
    int state;			/* decoder state (0-4 or GIF_DONE) */
    Tcl_Size length;			/* Total amount of bytes in data */
} MFile;

/*
 * Non-ASCII encoding support:
 * Most data in a GIF image is binary and is treated as such. However, a few
 * key bits are stashed in ASCII. If we try to compare those pieces to the
 * char they represent, it will fail on any non-ASCII (eg, EBCDIC) system. To
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127

128

129

130

131
132
133
134

135
136

137
138

139

140
141
142
143
144
145
146
147
148
149
} GIFImageConfig;

/*
 * Type of a function used to do the writing to a file or buffer when
 * serializing in the GIF format.
 */

typedef size_t (WriteBytesFunc) (ClientData clientData, const char *bytes,
			    size_t byteCount);

/*
 * The format record for the GIF file format:
 */

static int		FileMatchGIF(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *format, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);

static int		FileReadGIF(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *format,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);

static int		StringMatchGIF(Tcl_Obj *dataObj, Tcl_Obj *format,

			    int *widthPtr, int *heightPtr, Tcl_Interp *interp);

static int		StringReadGIF(Tcl_Interp *interp, Tcl_Obj *dataObj,

			    Tcl_Obj *format, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static int		FileWriteGIF(Tcl_Interp *interp, const char *filename,

			    Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
static int		StringWriteGIF(Tcl_Interp *interp, Tcl_Obj *format,

			    Tk_PhotoImageBlock *blockPtr);
static int		CommonWriteGIF(Tcl_Interp *interp, ClientData clientData,

			    WriteBytesFunc *writeProc, Tcl_Obj *format,

			    Tk_PhotoImageBlock *blockPtr);

Tk_PhotoImageFormat tkImgFmtGIF = {
    "gif",		/* name */
    FileMatchGIF,	/* fileMatchProc */
    StringMatchGIF,	/* stringMatchProc */
    FileReadGIF,	/* fileReadProc */
    StringReadGIF,	/* stringReadProc */
    FileWriteGIF,	/* fileWriteProc */
    StringWriteGIF,	/* stringWriteProc */







|
|





|
|
|
>


|
|
>
|
>
|
>

>
|

|

>
|

>

|
>

>


|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
} GIFImageConfig;

/*
 * Type of a function used to do the writing to a file or buffer when
 * serializing in the GIF format.
 */

typedef Tcl_Size (WriteBytesFunc) (void *clientData, const char *bytes,
			    Tcl_Size byteCount);

/*
 * The format record for the GIF file format:
 */

static int		FileMatchGIF(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *format,
			    Tcl_Obj *metadataInObj, int *widthPtr,
			    int *heightPtr, Tcl_Obj *metadataOutObj);
static int		FileReadGIF(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *format,
			    Tcl_Obj *metadataInObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, Tcl_Obj *metadataOutObj);
static int		StringMatchGIF(Tcl_Interp *interp, Tcl_Obj *dataObj,
			    Tcl_Obj *format, Tcl_Obj *metadataInObj,
			    int *widthPtr, int *heightPtr,
			    Tcl_Obj *metadataOutObj);
static int		StringReadGIF(Tcl_Interp *interp, Tcl_Obj *dataObj,
			    Tcl_Obj *format, Tcl_Obj *metadataInObj,
			    Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, Tcl_Obj *metadataOutObj);
static int		FileWriteGIF(Tcl_Interp *interp, const char *filename,
			    Tcl_Obj *format, Tcl_Obj *metadataInObj,
			    Tk_PhotoImageBlock *blockPtr);
static int		StringWriteGIF(Tcl_Interp *interp, Tcl_Obj *format,
			    Tcl_Obj *metadataInObj,
			    Tk_PhotoImageBlock *blockPtr);
static int		CommonWriteGIF(Tcl_Interp *interp,
			    void *clientData,
			    WriteBytesFunc *writeProc, Tcl_Obj *format,
			    Tcl_Obj *metadataInObj,
			    Tk_PhotoImageBlock *blockPtr);

Tk_PhotoImageFormatVersion3 tkImgFmtGIF = {
    "gif",		/* name */
    FileMatchGIF,	/* fileMatchProc */
    StringMatchGIF,	/* stringMatchProc */
    FileReadGIF,	/* fileReadProc */
    StringReadGIF,	/* stringReadProc */
    FileWriteGIF,	/* fileWriteProc */
    StringWriteGIF,	/* stringWriteProc */
161
162
163
164
165
166
167


168
169


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#define MAX_LWZ_BITS		12
#define LM_to_uint(a,b)		(((b)<<8)|(a))

/*
 * Prototypes for local functions defined in this file:
 */



static int		DoExtension(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, int label, unsigned char *buffer,


			    int *transparent);
static int		GetCode(Tcl_Channel chan, int code_size, int flag,
			    GIFImageConfig *gifConfPtr);
static int		GetDataBlock(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, unsigned char *buf);
static int		ReadColorMap(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, int number,
			    unsigned char buffer[MAXCOLORMAPSIZE][4]);
static int		ReadGIFHeader(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, int *widthPtr, int *heightPtr);
static int		ReadImage(GIFImageConfig *gifConfPtr,
			    Tcl_Interp *interp, unsigned char *imagePtr,
			    Tcl_Channel chan, int len, int rows,
			    unsigned char cmap[MAXCOLORMAPSIZE][4], int srcX,
			    int srcY, int interlace, int transparent);

/*
 * these are for the BASE64 image reader code only
 */

static size_t		Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
			    size_t size, size_t count, Tcl_Channel chan);
static size_t		Mread(unsigned char *dst, size_t size, size_t count,
			    MFile *handle);
static int		Mgetc(MFile *handle);
static int		char64(int c);
static void		mInit(unsigned char *string, MFile *handle,
			    size_t length);

/*
 * Types, defines and variables needed to write and compress a GIF.
 */

#define LSB(a)		((unsigned char) (((short)(a)) & 0x00FF))
#define MSB(a)		((unsigned char) (((short)(a)) >> 8))







>
>


>
>
|



















|
|
|




|







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#define MAX_LWZ_BITS		12
#define LM_to_uint(a,b)		(((b)<<8)|(a))

/*
 * Prototypes for local functions defined in this file:
 */

static int		ReadOneByte(Tcl_Interp *interp,
			    GIFImageConfig *gifConfPtr, Tcl_Channel chan);
static int		DoExtension(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, int label, unsigned char *buffer,
			    GIFGraphicControlExtensionBlock
			    *gifGraphicControlExtensionBlock,
			    Tcl_Obj *metadataOutObj);
static int		GetCode(Tcl_Channel chan, int code_size, int flag,
			    GIFImageConfig *gifConfPtr);
static int		GetDataBlock(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, unsigned char *buf);
static int		ReadColorMap(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, int number,
			    unsigned char buffer[MAXCOLORMAPSIZE][4]);
static int		ReadGIFHeader(GIFImageConfig *gifConfPtr,
			    Tcl_Channel chan, int *widthPtr, int *heightPtr);
static int		ReadImage(GIFImageConfig *gifConfPtr,
			    Tcl_Interp *interp, unsigned char *imagePtr,
			    Tcl_Channel chan, int len, int rows,
			    unsigned char cmap[MAXCOLORMAPSIZE][4], int srcX,
			    int srcY, int interlace, int transparent);

/*
 * these are for the BASE64 image reader code only
 */

static Tcl_Size		Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
			    Tcl_Size size, Tcl_Size count, Tcl_Channel chan);
static Tcl_Size		Mread(unsigned char *dst, Tcl_Size size, Tcl_Size count,
			    MFile *handle);
static int		Mgetc(MFile *handle);
static int		char64(int c);
static void		mInit(unsigned char *string, MFile *handle,
			    Tcl_Size length);

/*
 * Types, defines and variables needed to write and compress a GIF.
 */

#define LSB(a)		((unsigned char) (((short)(a)) & 0x00FF))
#define MSB(a)		((unsigned char) (((short)(a)) >> 8))
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
     * codes are re-sized at this point, and a special CLEAR code is generated
     * for the decompressor. Late addition: construct the table according to
     * file size for noticeable speed improvement on small files. Please
     * direct questions about this implementation to ames!jaw.
     */

    int initialBits;
    ClientData destination;
    WriteBytesFunc *writeProc;

    int clearCode;
    int eofCode;

    unsigned long currentAccumulated;
    int currentBits;







|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
     * codes are re-sized at this point, and a special CLEAR code is generated
     * for the decompressor. Late addition: construct the table according to
     * file size for noticeable speed improvement on small files. Please
     * direct questions about this implementation to ames!jaw.
     */

    int initialBits;
    void *destination;
    WriteBytesFunc *writeProc;

    int clearCode;
    int eofCode;

    unsigned long currentAccumulated;
    int currentBits;
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318

/*
 * Definition of new functions to write GIFs
 */

static int		ColorNumber(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		Compress(int initBits, ClientData handle,
			    WriteBytesFunc *writeProc, ifunptr readValue,
			    GifWriterState *statePtr);
static int		IsNewColor(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		SaveMap(GifWriterState *statePtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		ReadValue(GifWriterState *statePtr);







|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

/*
 * Definition of new functions to write GIFs
 */

static int		ColorNumber(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		Compress(int initBits, void *handle,
			    WriteBytesFunc *writeProc, ifunptr readValue,
			    GifWriterState *statePtr);
static int		IsNewColor(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		SaveMap(GifWriterState *statePtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		ReadValue(GifWriterState *statePtr);
341
342
343
344
345
346
347

348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchGIF(

    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *format,		/* User-specified format object, or NULL. */

    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here if the file is a valid raw GIF file. */
    Tcl_Interp *dummy)		/* not used */
{
    GIFImageConfig gifConf;
    (void)fileName;
    (void)format;
    (void)dummy;

    memset(&gifConf, 0, sizeof(GIFImageConfig));
    return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}

/*
 *----------------------------------------------------------------------







>

|
|
>



|


<
<
<







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383



384
385
386
387
388
389
390
 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchGIF(
    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 *),	/* 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;




    memset(&gifConf, 0, sizeof(GIFImageConfig));
    return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}

/*
 *----------------------------------------------------------------------
383
384
385
386
387
388
389

390
391
392
393
394
395
396

397
398
399
400

401
402
403
404

405
406

407
408
409
410
411

412
413
414
415
416
417
418

static int
FileReadGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *format,		/* User-specified format object, or NULL. */

    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */

{
    int fileWidth, fileHeight, imageWidth, imageHeight;
    unsigned int nBytes;
    int index = 0, argc = 0, i, result = TCL_ERROR;

    Tcl_Obj **objv;
    unsigned char buf[100];
    unsigned char *trashBuffer = NULL;
    int bitPixel;

    unsigned char colorMap[MAXCOLORMAPSIZE][4];
    int transparent = -1;

    static const char *const optionStrings[] = {
	"-index", NULL
    };
    GIFImageConfig gifConf, *gifConfPtr = &gifConf;


    /*
     * Decode the magic used to convey when we're sourcing data from a string
     * source and not a file.
     */

    memset(colorMap, 0, MAXCOLORMAPSIZE*4);
    memset(gifConfPtr, 0, sizeof(GIFImageConfig));







>





|

>



|
>




>

<
>





>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447

static int
FileReadGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *format,		/* User-specified format object, or NULL. */
    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. */
    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. */
    Tcl_Obj *metadataOutObj)	/* metadata return dict, may be NULL */
{
    int fileWidth, fileHeight, imageWidth, imageHeight;
    unsigned int nBytes;
    int index = 0, result = TCL_ERROR;
    Tcl_Size argc = 0, i;
    Tcl_Obj **objv;
    unsigned char buf[100];
    unsigned char *trashBuffer = NULL;
    int bitPixel;
    int gifLabel;
    unsigned char colorMap[MAXCOLORMAPSIZE][4];

    GIFGraphicControlExtensionBlock gifGraphicControlExtensionBlock;
    static const char *const optionStrings[] = {
	"-index", NULL
    };
    GIFImageConfig gifConf, *gifConfPtr = &gifConf;

    gifGraphicControlExtensionBlock.blockPresent = 0;
    /*
     * Decode the magic used to convey when we're sourcing data from a string
     * source and not a file.
     */

    memset(colorMap, 0, MAXCOLORMAPSIZE*4);
    memset(gifConfPtr, 0, sizeof(GIFImageConfig));
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
	return TCL_OK;
    }
    bitPixel = 2 << (buf[0] & 0x07);

    if (BitSet(buf[0], LOCALCOLORMAP)) {	/* Global Colormap */
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);
	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;







|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
	return TCL_OK;
    }
    bitPixel = 2 << (buf[0] & 0x07);

    if (BitSet(buf[0], LOCALCOLORMAP)) {	/* Global Colormap */
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);
	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
499
500
501
502
503
504
505






506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544


545
546
547
548
549
550
551
552
553
     */

    if (Tk_PhotoExpand(interp, imageHandle,
	    destX + width, destY + height) != TCL_OK) {
	return TCL_ERROR;
    }







    /*
     * Search for the frame from the GIF to display.
     */

    while (1) {
	if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
	    /*
	     * Premature end of image.
	     */

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "premature end of image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END",
		    NULL);
	    goto error;
	}

	switch (buf[0]) {
	case GIF_TERMINATOR:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA", NULL);
	    goto error;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension function code in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    if (DoExtension(gifConfPtr, chan, buf[0],
		    gifConfPtr->workingBuffer, &transparent) < 0) {


		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension in GIF image", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    continue;
	case GIF_START:
	    if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) {







>
>
>
>
>
>





<
<
<
<
|
<
<
<
<



|


|








|
<
<
<
<
<


|
|
>
>

|







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545




546




547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562





563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
     */

    if (Tk_PhotoExpand(interp, imageHandle,
	    destX + width, destY + height) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * -------------------------------------------------------------------------
     * From here on, go to error to not leave memory leaks
     * -------------------------------------------------------------------------
     */

    /*
     * Search for the frame from the GIF to display.
     */

    while (1) {




	if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {




	    goto error;
	}

	switch (gifLabel) {
	case GIF_TERMINATOR:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no image data for this index", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA", NULL);
	    goto error;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {





		goto error;
	    }
	    if (DoExtension(gifConfPtr, chan, gifLabel,
		    gifConfPtr->workingBuffer, &gifGraphicControlExtensionBlock,
		    metadataOutObj)
		    < 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension in GIF image", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    continue;
	case GIF_START:
	    if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) {
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
	    /*
	     * This is not the GIF frame we want to read: skip it.
	     */

	    if (BitSet(buf[8], LOCALCOLORMAP)) {
		if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "error reading color map", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF",
			    "COLOR_MAP", NULL);
		    goto error;
		}
	    }

	    /*







|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
	    /*
	     * This is not the GIF frame we want to read: skip it.
	     */

	    if (BitSet(buf[8], LOCALCOLORMAP)) {
		if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "error reading color map", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF",
			    "COLOR_MAP", NULL);
		    goto error;
		}
	    }

	    /*
623
624
625
626
627
628
629







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
	     * common case.
	     */

	    if (ReadImage(gifConfPtr, interp, trashBuffer, chan, imageWidth,
		    imageHeight, colorMap, 0, 0, 0, -1) != TCL_OK) {
		goto error;
	    }







	    continue;
	}
	break;
    }

    /*
     * Found the frame we want to read. Next, check for a local color map for
     * this frame.
     */

    if (BitSet(buf[8], LOCALCOLORMAP)) {
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);
	    goto error;
	}
    }

    /*
     * Extract the location within the overall visible image to put the data







>
>
>
>
>
>
>













|







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
	     * common case.
	     */

	    if (ReadImage(gifConfPtr, interp, trashBuffer, chan, imageWidth,
		    imageHeight, colorMap, 0, 0, 0, -1) != TCL_OK) {
		goto error;
	    }

	    /*
	     * This extension starts a new scope, so Graphic control Extension
	     * data should be cleared
	     */
	    gifGraphicControlExtensionBlock.blockPresent = 0;

	    continue;
	}
	break;
    }

    /*
     * Found the frame we want to read. Next, check for a local color map for
     * this frame.
     */

    if (BitSet(buf[8], LOCALCOLORMAP)) {
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);
	    goto error;
	}
    }

    /*
     * Extract the location within the overall visible image to put the data
670
671
672
673
674
675
676



677
678
679
680
681
682
683
684
    }
    if (height > imageHeight) {
	height = imageHeight;
    }

    if ((width > 0) && (height > 0)) {
	Tk_PhotoImageBlock block;




	/*
	 * Read the data and put it into the photo buffer for display by the
	 * general image machinery.
	 */

	block.width = width;
	block.height = height;







>
>
>
|







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
    }
    if (height > imageHeight) {
	height = imageHeight;
    }

    if ((width > 0) && (height > 0)) {
	Tk_PhotoImageBlock block;
	int transparent = -1;
	if (gifGraphicControlExtensionBlock.blockPresent) {
	    transparent = gifGraphicControlExtensionBlock.transparent;
	}
	/*
	 * Read the data and put it into the photo buffer for display by the
	 * general image machinery.
	 */

	block.width = width;
	block.height = height;
709
710
711
712
713
714
715
716
717












































































718
719
720
721










































722
723
724
725

726
727
728
729
730
731
732
733
734
735







































736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

753
754
755

756
757

758
759
760

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    goto error;
	}
	ckfree(block.pixelPtr);
    }

    /*












































































     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */











































    Tcl_SetObjResult(interp, Tcl_NewStringObj(tkImgFmtGIF.name, -1));
    result = TCL_OK;

  error:

    /*
     * If a trash buffer has been allocated, free it now.
     */

    if (trashBuffer != NULL) {
	ckfree(trashBuffer);
    }
    return result;
}








































/*
 *----------------------------------------------------------------------
 *
 * StringMatchGIF --
 *
 *	This function is invoked by the photo image type to see if an object
 *	contains image data in GIF format.
 *
 * Results:
 *	The return value is 1 if the first characters in the data are like GIF
 *	data, and 0 otherwise.
 *
 * Side effects:
 *	The size of the image is placed in widthPtr and heightPtr.
 *
 *----------------------------------------------------------------------
 */


static int
StringMatchGIF(

    Tcl_Obj *dataObj,		/* the object containing the image data */
    Tcl_Obj *format,		/* the image format object, or NULL */

    int *widthPtr,		/* where to put the string width */
    int *heightPtr,		/* where to put the string height */
    Tcl_Interp *dummy)		/* not used */

{
    unsigned char *data, header[10];
    TkSizeT got, length;
    MFile handle;
    (void)format;
    (void)dummy;

    data = TkGetByteArrayFromObj(dataObj, &length);

    /*
     * Header is a minimum of 10 bytes.
     */

    if (length < 10) {
	return 0;









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


|
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















>



>

|
>


<
>


|

<
<

|







743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    goto error;
	}
	ckfree(block.pixelPtr);
    }

    /*
     * Update the metadata dictionary with current image data
     */

    if (NULL != metadataOutObj) {

	/*
	 * Save the update box, if not the whole image
	 */

	if ( width != fileWidth || height != fileHeight) {
	    Tcl_Obj *itemList[4];
	    itemList[0] = Tcl_NewIntObj(destX);
	    itemList[1] = Tcl_NewIntObj(destY);
	    itemList[2] = Tcl_NewIntObj(width);
	    itemList[3] = Tcl_NewIntObj(height);
	    if ( TCL_OK != Tcl_DictObjPut(interp, metadataOutObj,
		    Tcl_NewStringObj("update region",-1),
		    Tcl_NewListObj(4, itemList) )) {
		result = TCL_ERROR;
		goto error;
	    }
	}

	/*
	 * Copy the Graphic Control Extension Block data to the metadata
	 * dictionary
	 */

	if (gifGraphicControlExtensionBlock.blockPresent) {
	    if ( gifGraphicControlExtensionBlock.delayTime != 0) {
		if ( TCL_OK != Tcl_DictObjPut(interp, metadataOutObj,
			Tcl_NewStringObj("delay time",-1),
			Tcl_NewIntObj(gifGraphicControlExtensionBlock.delayTime)
			)) {
		    result = TCL_ERROR;
		    goto error;
		}
	    }
	    switch ( gifGraphicControlExtensionBlock.disposalMethod ) {
	    case 1: /* Do not dispose */
		if ( TCL_OK != Tcl_DictObjPut(interp, metadataOutObj,
			Tcl_NewStringObj("disposal method",-1),
			Tcl_NewStringObj("do not dispose",-1))) {
		    result = TCL_ERROR;
		    goto error;
		}
		break;
	    case 2: /* Restore to background color */
		if ( TCL_OK != Tcl_DictObjPut(interp, metadataOutObj,
			Tcl_NewStringObj("disposal method",-1),
			Tcl_NewStringObj("restore to background color",-1))) {
		    result = TCL_ERROR;
		    goto error;
		}
		break;
	    case 3: /* Restore to previous */
		if ( TCL_OK != Tcl_DictObjPut(interp, metadataOutObj,
			Tcl_NewStringObj("disposal method",-1),
			Tcl_NewStringObj("restore to previous",-1))) {
		    result = TCL_ERROR;
		    goto error;
		}
		break;
	    }
	    if ( gifGraphicControlExtensionBlock.userInteraction != 0) {
		if ( TCL_OK != Tcl_DictObjPut(interp, metadataOutObj,
			Tcl_NewStringObj("user interaction",-1),
			Tcl_NewBooleanObj(1))) {
		    result = TCL_ERROR;
		    goto error;
		}
	    }
	}
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */

    while (1) {
	if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {
	    goto error;
	}
	switch (gifLabel) {
	case GIF_TERMINATOR:
	    break;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    if (-1 == (gifLabel = ReadOneByte( interp, gifConfPtr, chan ) ) ) {
		goto error;
	    }
	    if (DoExtension(gifConfPtr, chan, gifLabel,
		    gifConfPtr->workingBuffer, &gifGraphicControlExtensionBlock,
		    metadataOutObj)
		    < 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension in GIF image", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    continue;
	case GIF_START:
	    /*
	     * There should not be a second image block - bail out without error
	     */
	    break;
	default:
	    /*
	     * Not a valid start character; ignore it.
	     */

	    continue;
	}
	break;
    }

    Tcl_SetObjResult(interp, Tcl_NewStringObj(tkImgFmtGIF.name, TCL_INDEX_NONE));
    result = TCL_OK;

error:

    /*
     * If a trash buffer has been allocated, free it now.
     */

    if (trashBuffer != NULL) {
	ckfree(trashBuffer);
    }
    return result;
}


/*
 *----------------------------------------------------------------------
 *
 * Read one Byte --
 *
 *	Read one byte (label byte) from the image stream.
 *
 * Results:
 *	The return value is 1 if the first characters in the data are like GIF
 *	data, and 0 otherwise.
 *
 * Side effects:
 *	The access position in the source is incremented.
 *
 *----------------------------------------------------------------------
 */

static int
ReadOneByte(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan		/* The image file, open for reading. */
    )
{
    unsigned char buf[2];
    if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
        /*
         * Premature end of image.
         */

        Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"premature end of image data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END", NULL);
	return -1;
    }
    return buf[0];
}

/*
 *----------------------------------------------------------------------
 *
 * StringMatchGIF --
 *
 *	This function is invoked by the photo image type to see if an object
 *	contains image data in GIF format.
 *
 * Results:
 *	The return value is 1 if the first characters in the data are like GIF
 *	data, and 0 otherwise.
 *
 * Side effects:
 *	The size of the image is placed in widthPtr and heightPtr.
 *
 *----------------------------------------------------------------------
 */


static int
StringMatchGIF(
    TCL_UNUSED(Tcl_Interp *),		/* not used */
    Tcl_Obj *dataObj,		/* the object containing the image data */
    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 */
{
    unsigned char *data, header[10];
    Tcl_Size got, length;
    MFile handle;



    data = Tcl_GetByteArrayFromObj(dataObj, &length);

    /*
     * Header is a minimum of 10 bytes.
     */

    if (length < 10) {
	return 0;
821
822
823
824
825
826
827

828
829
830
831

832
833
834
835
836
837
838
839
840
841
842
843
 */

static int
StringReadGIF(
    Tcl_Interp *interp,		/* interpreter for reporting errors in */
    Tcl_Obj *dataObj,		/* object containing the image */
    Tcl_Obj *format,		/* format object, or NULL */

    Tk_PhotoHandle imageHandle,	/* the image to write this data into */
    int destX, int destY,	/* The rectangular region of the */
    int width, int height,	/* image to copy */
    int srcX, int srcY)

{
    MFile handle, *hdlPtr = &handle;
    TkSizeT length;
    const char *xferFormat;
    unsigned char *data = TkGetByteArrayFromObj(dataObj, &length);

    mInit(data, hdlPtr, length);

    /*
     * Check whether the data is Base64 encoded by doing a character-by-
     * charcter comparison with the binary-format headers; BASE64-encoded
     * never matches (matching the other way is harder because of potential







>



|
>


|

|







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
 */

static int
StringReadGIF(
    Tcl_Interp *interp,		/* interpreter for reporting errors in */
    Tcl_Obj *dataObj,		/* object containing the image */
    Tcl_Obj *format,		/* format object, or NULL */
    Tcl_Obj *metadataInObj,	/* metadata input, may be NULL */
    Tk_PhotoHandle imageHandle,	/* the image to write this data into */
    int destX, int destY,	/* The rectangular region of the */
    int width, int height,	/* image to copy */
    int srcX, int srcY,
    Tcl_Obj *metadataOutObj)	/* metadata return dict, may be NULL */
{
    MFile handle, *hdlPtr = &handle;
    Tcl_Size length;
    const char *xferFormat;
    unsigned char *data = Tcl_GetByteArrayFromObj(dataObj, &length);

    mInit(data, hdlPtr, length);

    /*
     * Check whether the data is Base64 encoded by doing a character-by-
     * charcter comparison with the binary-format headers; BASE64-encoded
     * never matches (matching the other way is harder because of potential
853
854
855
856
857
858
859
860

861
862
863
864
865
866
867

    /*
     * Fall through to the file reader now that we have a correctly-configured
     * pseudo-channel to pull the data from.
     */

    return FileReadGIF(interp, (Tcl_Channel) hdlPtr, xferFormat, format,
	    imageHandle, destX, destY, width, height, srcX, srcY);

}

/*
 *----------------------------------------------------------------------
 *
 * ReadGIFHeader --
 *







|
>







1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063

    /*
     * Fall through to the file reader now that we have a correctly-configured
     * pseudo-channel to pull the data from.
     */

    return FileReadGIF(interp, (Tcl_Channel) hdlPtr, xferFormat, format,
	    metadataInObj, imageHandle, destX, destY, width, height, srcX, srcY,
	    metadataOutObj);
}

/*
 *----------------------------------------------------------------------
 *
 * ReadGIFHeader --
 *
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
    int number,
    unsigned char buffer[MAXCOLORMAPSIZE][4])
{
    int i;
    unsigned char rgb[3];

    for (i = 0; i < number; ++i) {
	if (((size_t)Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) + 1) < 2) {
	    return 0;
	}

	if (buffer) {
	    buffer[i][CM_RED] = rgb[0];
	    buffer[i][CM_GREEN] = rgb[1];
	    buffer[i][CM_BLUE] = rgb[2];
	    buffer[i][CM_ALPHA] = 255;
	}
    }
    return 1;
}























static int
DoExtension(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    int label,
    unsigned char *buf,

    int *transparent)
{
    int count;






    switch (label) {
    case 0x01:			/* Plain Text Extension */


	break;


    case 0xff:			/* Application Extension */
	break;

    case 0xfe:			/* Comment Extension */
	do {
	    count = GetDataBlock(gifConfPtr, chan, buf);
	} while (count > 0);
	return count;

    case 0xf9:			/* Graphic Control Extension */
	count = GetDataBlock(gifConfPtr, chan, buf);
	if (count < 0) {
	    return 1;
	}










	if ((buf[0] & 0x1) != 0) {


	    *transparent = buf[3];
	}











	do {
	    count = GetDataBlock(gifConfPtr, chan, buf);
	} while (count > 0);

	return count;







    }




















    do {
	count = GetDataBlock(gifConfPtr, chan, buf);
    } while (count > 0);
    return count;
}

static int
GetDataBlock(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    unsigned char *buf)
{
    unsigned char count;

    if (((size_t)Fread(gifConfPtr, &count, 1, 1, chan) + 1) < 2) {
	return -1;
    }

    if ((count != 0) && (((size_t)Fread(gifConfPtr, buf, count, 1, chan) + 1) < 2)) {
	return -1;
    }

    return count;
}

/*







|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
>
|


>
>
>
>
>



>
>
|
|
>
|

<
<
<
<
<
<
<



|

>
>
>
>
>
>
>
>
>
>
|
>
>
|

>
>
>
>
>
|
>
>
>
>
>
|

|
>
|
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|










|



|







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
    int number,
    unsigned char buffer[MAXCOLORMAPSIZE][4])
{
    int i;
    unsigned char rgb[3];

    for (i = 0; i < number; ++i) {
	if (Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) <= 0) {
	    return 0;
	}

	if (buffer) {
	    buffer[i][CM_RED] = rgb[0];
	    buffer[i][CM_GREEN] = rgb[1];
	    buffer[i][CM_BLUE] = rgb[2];
	    buffer[i][CM_ALPHA] = 255;
	}
    }
    return 1;
}

/*
*----------------------------------------------------------------------
*
* DoExtension --
*
*	Process a GIF extension block
*
* Results:
*	-1 to trigger an extension read error
*       >= 0 ok
*
* Side effects:
*       The gifGraphicControlExtensionBlock is set if present in current
*       extensions
*       The data of the following extensions are saved to the metadata dict:
*       - Application extension
*         - Comment extension in key "comment"
*       Plain text extensions are currently ignored.
*
*----------------------------------------------------------------------
*/

static int
DoExtension(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    int label,
    unsigned char *buf, /* defined as 280 byte working buffer */
    GIFGraphicControlExtensionBlock *gifGraphicControlExtensionBlock,
    Tcl_Obj *metadataOutObj)
{
    int count;
    /* Prepare extension name
     * Maximum string size: "comment" + Code(3) + trailing zero
     */
    char extensionStreamName[8];
    extensionStreamName[0] = '\0';

    switch (label) {
    case 0x01:			/* Plain Text Extension */
	/*
	 * This extension starts a new scope, so Graphic control Extension
	 * data should be cleared
	 */
	gifGraphicControlExtensionBlock->blockPresent = 0;
	/* this extension is ignored, skip below */
	break;







    case 0xf9:			/* Graphic Control Extension */
	count = GetDataBlock(gifConfPtr, chan, buf);
	if (count < 0) {
	    return -1;
	}
	gifGraphicControlExtensionBlock->blockPresent=1;
	/* save disposal method */
	gifGraphicControlExtensionBlock->disposalMethod
		= ((buf[0] & 0x1C) >> 2);
	/* save disposal method */
	gifGraphicControlExtensionBlock->userInteraction = ((buf[0] & 2) >> 1);
	/* save delay time */
	gifGraphicControlExtensionBlock->delayTime
		= LM_to_uint(buf[1], buf[2]);
	/* save transparent index if given */
	if ((buf[0] & 0x1) == 0) {
	    gifGraphicControlExtensionBlock->transparent = -1;
	} else {
	    gifGraphicControlExtensionBlock->transparent = buf[3];
	}
	break;
    case 0xfe:			/* Comment Extension */
	strcpy(extensionStreamName,"comment");
        /* copy the extension data below */
	break;
    }
    /* Add extension to dict */
    if (NULL != metadataOutObj
	    && extensionStreamName[0] != '\0' ) {
	Tcl_Obj *ValueObj = NULL;
	int length = 0;
	for (;;) {
	    count = GetDataBlock(gifConfPtr, chan, buf);
	    switch (count) {
	    case -1: /* error */
		return -1;
	    case 0: /* end of data */
		if (length > 0) {
		    if ( TCL_OK != Tcl_DictObjPut(NULL, metadataOutObj,
			    Tcl_NewByteArrayObj(
				(unsigned char *)extensionStreamName,
			    strlen(extensionStreamName)), ValueObj)) {
			return -1;
		    }
		}
		/* return success */
		return 0;
	    default: /* block received */
		if (length == 0) {
		    /* first block */
		    ValueObj = Tcl_NewByteArrayObj(buf, count);
		    length = count;
		} else {
		    /* consecutive block */
		    unsigned char *bytePtr;
		    bytePtr = Tcl_SetByteArrayLength(ValueObj, length+count);
		    memcpy(bytePtr+length,buf,count);
		    length += count;
		}
		break;
	    }
	} /* for */
    }
    /* skip eventual remaining data block bytes */
    do {
	count = GetDataBlock(gifConfPtr, chan, buf);
    } while (count > 0);
    return count; /* this may be -1 for error or 0 */
}

static int
GetDataBlock(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    unsigned char *buf)
{
    unsigned char count;

    if (Fread(gifConfPtr, &count, 1, 1, chan) <= 0) {
	return -1;
    }

    if ((count != 0) && (Fread(gifConfPtr, buf, count, 1, chan) <= 0)) {
	return -1;
    }

    return count;
}

/*
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
ReadImage(
    GIFImageConfig *gifConfPtr,
    Tcl_Interp *interp,
    unsigned char *imagePtr,
    Tcl_Channel chan,
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    int srcX, int srcY,

    int interlace,
    int transparent)
{
    unsigned char initialCodeSize;
    int xpos = 0, ypos = 0, pass = 0, i, count;
    unsigned char *pixelPtr;
    static const int interlaceStep[] = { 8, 8, 4, 2 };
    static const int interlaceStart[] = { 0, 4, 2, 1 };
    unsigned short prefix[(1 << MAX_LWZ_BITS)];
    unsigned char append[(1 << MAX_LWZ_BITS)];
    unsigned char stack[(1 << MAX_LWZ_BITS)*2];
    unsigned char *top;
    int codeSize, clearCode, inCode, endCode, oldCode, maxCode;
    int code, firstCode, v;
    (void)srcX;
    (void)srcY;

    /*
     * Initialize the decoder
     */

    if (((size_t)Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) + 1) < 2) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading GIF image: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    if (initialCodeSize > MAX_LWZ_BITS) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("malformed image", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "MALFORMED", NULL);
	return TCL_ERROR;
    }

    if (transparent != -1) {
	cmap[transparent][CM_RED] = 0;
	cmap[transparent][CM_GREEN] = 0;







|
>














<
<





|






|







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
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),
    int interlace,
    int transparent)
{
    unsigned char initialCodeSize;
    int xpos = 0, ypos = 0, pass = 0, i, count;
    unsigned char *pixelPtr;
    static const int interlaceStep[] = { 8, 8, 4, 2 };
    static const int interlaceStart[] = { 0, 4, 2, 1 };
    unsigned short prefix[(1 << MAX_LWZ_BITS)];
    unsigned char append[(1 << MAX_LWZ_BITS)];
    unsigned char stack[(1 << MAX_LWZ_BITS)*2];
    unsigned char *top;
    int codeSize, clearCode, inCode, endCode, oldCode, maxCode;
    int code, firstCode, v;



    /*
     * Initialize the decoder
     */

    if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading GIF image: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    if (initialCodeSize > MAX_LWZ_BITS) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("malformed image", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "MALFORMED", NULL);
	return TCL_ERROR;
    }

    if (transparent != -1) {
	cmap[transparent][CM_RED] = 0;
	cmap[transparent][CM_GREEN] = 0;
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
 *----------------------------------------------------------------------
 */

static void
mInit(
    unsigned char *string,	/* string containing initial mmencoded data */
    MFile *handle,		/* mmdecode "file" handle */
    size_t length)			/* Number of bytes in string */
{
    handle->data = string;
    handle->state = 0;
    handle->c = 0;
    handle->length = length;
}








|







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
 *----------------------------------------------------------------------
 */

static void
mInit(
    unsigned char *string,	/* string containing initial mmencoded data */
    MFile *handle,		/* mmdecode "file" handle */
    Tcl_Size length)			/* Number of bytes in string */
{
    handle->data = string;
    handle->state = 0;
    handle->c = 0;
    handle->length = length;
}

1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static size_t
Mread(
    unsigned char *dst,		/* where to put the result */
    size_t chunkSize,		/* size of each transfer */
    size_t numChunks,		/* number of chunks */
    MFile *handle)		/* mmdecode "file" handle */
{
    int c;
    size_t i, count = chunkSize * numChunks;

    for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
	*dst++ = c;
    }
    return i;
}








|


|
|



|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
Mread(
    unsigned char *dst,		/* where to put the result */
    Tcl_Size chunkSize,		/* size of each transfer */
    Tcl_Size numChunks,		/* number of chunks */
    MFile *handle)		/* mmdecode "file" handle */
{
    int c;
    Tcl_Size i, count = chunkSize * numChunks;

    for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
	*dst++ = c;
    }
    return i;
}

1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583




1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
 *	a base64 encoded string.
 *
 * Results: - same as POSIX fread() or Tcl Tcl_Read()
 *
 *----------------------------------------------------------------------
 */

static size_t
Fread(
    GIFImageConfig *gifConfPtr,
    unsigned char *dst,		/* where to put the result */
    size_t hunk, size_t count,	/* how many */
    Tcl_Channel chan)
{




    if (gifConfPtr->fromData == INLINE_DATA_BASE64) {
	return Mread(dst, hunk, count, (MFile *) chan);
    }

    if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
	MFile *handle = (MFile *) chan;

	if ((handle->length + 1 < 2) || (handle->length < hunk*count)) {
	    return (size_t)-1;
	}
	memcpy(dst, handle->data, hunk * count);
	handle->data += hunk * count;
	handle->length -= hunk * count;
	return hunk * count;
    }








|



|


>
>
>
>







|
|







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
 *	a base64 encoded string.
 *
 * Results: - same as POSIX fread() or Tcl Tcl_Read()
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
Fread(
    GIFImageConfig *gifConfPtr,
    unsigned char *dst,		/* where to put the result */
    Tcl_Size hunk, Tcl_Size count,	/* how many */
    Tcl_Channel chan)
{
    if (hunk < 0 || count < 0) {
        return -1;
    }

    if (gifConfPtr->fromData == INLINE_DATA_BASE64) {
	return Mread(dst, hunk, count, (MFile *) chan);
    }

    if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
	MFile *handle = (MFile *) chan;

	if ((handle->length <= 0) || (handle->length < hunk*count)) {
	    return -1;
	}
	memcpy(dst, handle->data, hunk * count);
	handle->data += hunk * count;
	handle->length -= hunk * count;
	return hunk * count;
    }

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


static int
FileWriteGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    const char *filename,
    Tcl_Obj *format,

    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan = NULL;
    int result;

    chan = Tcl_OpenFileChannel(interp, (char *) filename, "w", 0644);
    if (!chan) {
	return TCL_ERROR;
    }
    if (Tcl_SetChannelOption(interp, chan, "-translation",
	    "binary") != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr);


    if (Tcl_Close(interp, chan) == TCL_ERROR) {
	return TCL_ERROR;
    }
    return result;
}

static int
StringWriteGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors and
				 * returning the GIF data. */
    Tcl_Obj *format,

    Tk_PhotoImageBlock *blockPtr)
{
    int result;
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_IncrRefCount(objPtr);
    result = CommonWriteGIF(interp, objPtr, WriteToByteArray, format,
	    blockPtr);
    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objPtr);
    }
    Tcl_DecrRefCount(objPtr);
    return result;
}

static size_t
WriteToChannel(
    ClientData clientData,
    const char *bytes,
    size_t byteCount)
{
    Tcl_Channel handle = (Tcl_Channel)clientData;

    return Tcl_Write(handle, bytes, byteCount);
}

static size_t
WriteToByteArray(
    ClientData clientData,
    const char *bytes,
    size_t byteCount)
{
    Tcl_Obj *objPtr = (Tcl_Obj *)clientData;
    Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount);

    Tcl_IncrRefCount(tmpObj);
    Tcl_AppendObjToObj(objPtr, tmpObj);
    Tcl_DecrRefCount(tmpObj);
    return byteCount;
}

static int
CommonWriteGIF(
    Tcl_Interp *interp,
    ClientData handle,
    WriteBytesFunc *writeProc,

    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    GifWriterState state;
    int resolution;
    long width, height, x;
    unsigned char c;
    unsigned int top, left;
    (void)format;

    top = 0;
    left = 0;

    memset(&state, 0, sizeof(state));

    state.pixelSize = blockPtr->pixelSize;







>















|
>












>







|







|

|

|






|

|

|













|

>
|







<







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


static int
FileWriteGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    const char *filename,
    Tcl_Obj *format,
    Tcl_Obj *metadataInObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan = NULL;
    int result;

    chan = Tcl_OpenFileChannel(interp, (char *) filename, "w", 0644);
    if (!chan) {
	return TCL_ERROR;
    }
    if (Tcl_SetChannelOption(interp, chan, "-translation",
	    "binary") != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    result = CommonWriteGIF(interp, chan, WriteToChannel, format, metadataInObj,
	    blockPtr);

    if (Tcl_Close(interp, chan) == TCL_ERROR) {
	return TCL_ERROR;
    }
    return result;
}

static int
StringWriteGIF(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors and
				 * returning the GIF data. */
    Tcl_Obj *format,
    Tcl_Obj *metadataInObj,
    Tk_PhotoImageBlock *blockPtr)
{
    int result;
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_IncrRefCount(objPtr);
    result = CommonWriteGIF(interp, objPtr, WriteToByteArray, format,
	    metadataInObj, blockPtr);
    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objPtr);
    }
    Tcl_DecrRefCount(objPtr);
    return result;
}

static Tcl_Size
WriteToChannel(
    void *clientData,
    const char *bytes,
    Tcl_Size byteCount)
{
    Tcl_Channel handle = (Tcl_Channel)clientData;

    return Tcl_Write(handle, bytes, byteCount);
}

static Tcl_Size
WriteToByteArray(
    void *clientData,
    const char *bytes,
    Tcl_Size byteCount)
{
    Tcl_Obj *objPtr = (Tcl_Obj *)clientData;
    Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount);

    Tcl_IncrRefCount(tmpObj);
    Tcl_AppendObjToObj(objPtr, tmpObj);
    Tcl_DecrRefCount(tmpObj);
    return byteCount;
}

static int
CommonWriteGIF(
    Tcl_Interp *interp,
    void *handle,
    WriteBytesFunc *writeProc,
    TCL_UNUSED(Tcl_Obj *),
    Tcl_Obj *metadataInObj,
    Tk_PhotoImageBlock *blockPtr)
{
    GifWriterState state;
    int resolution;
    long width, height, x;
    unsigned char c;
    unsigned int top, left;


    top = 0;
    left = 0;

    memset(&state, 0, sizeof(state));

    state.pixelSize = blockPtr->pixelSize;
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763

    width = blockPtr->width;
    height = blockPtr->height;
    state.pixelOffset = blockPtr->pixelPtr + blockPtr->offset[0];
    state.pixelPitch = blockPtr->pitch;
    SaveMap(&state, blockPtr);
    if (state.num >= MAXCOLORMAPSIZE) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("too many colors", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL", NULL);
	return TCL_ERROR;
    }
    if (state.num<2) {
	state.num = 2;
    }
    c = LSB(width);







|







2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038

    width = blockPtr->width;
    height = blockPtr->height;
    state.pixelOffset = blockPtr->pixelPtr + blockPtr->offset[0];
    state.pixelPitch = blockPtr->pitch;
    SaveMap(&state, blockPtr);
    if (state.num >= MAXCOLORMAPSIZE) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("too many colors", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL", NULL);
	return TCL_ERROR;
    }
    if (state.num<2) {
	state.num = 2;
    }
    c = LSB(width);
1838
1839
1840
1841
1842
1843
1844












































1845
1846
1847
1848
1849
1850
1851

    state.ssize = state.rsize = blockPtr->width;
    state.csize = blockPtr->height;
    Compress(resolution+1, handle, writeProc, ReadValue, &state);

    c = 0;
    writeProc(handle, (char *) &c, 1);












































    c = GIF_TERMINATOR;
    writeProc(handle, (char *) &c, 1);

    return TCL_OK;
}

static int







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

    state.ssize = state.rsize = blockPtr->width;
    state.csize = blockPtr->height;
    Compress(resolution+1, handle, writeProc, ReadValue, &state);

    c = 0;
    writeProc(handle, (char *) &c, 1);
    /*
     * Check for metadata keys to add to file
     */
    if (NULL != metadataInObj) {
	Tcl_Obj *itemData;

	/*
	 * Check and code comment block
	 */

	if (TCL_ERROR == Tcl_DictObjGet(interp, metadataInObj,
		Tcl_NewStringObj("comment",-1),
		&itemData)) {
	    return TCL_ERROR;
	}
	if (itemData != NULL) {
	    Tcl_Size length;
	    unsigned char *comment;
	    comment = Tcl_GetByteArrayFromObj(itemData, &length);
	    if (length > 0) {
		/* write comment header */
		writeProc(handle, (char *) "\x21\xfe", 2);
		/* write comment blocks */
		for (;length > 0;) {
		    int blockLength;
		    unsigned char blockLengthChar;
		    if (length > 255) {
			length -=255;
			blockLength = 255;
		    } else {
			blockLength = length;
			length = 0;
		    }
		    blockLengthChar = (unsigned char) blockLength;
		    writeProc(handle, (char *) &blockLengthChar, 1);
		    writeProc(handle, (char *) comment, blockLength);
		    comment += blockLength;
		}
		/* Block terminator */
		c = 0;
		writeProc(handle, (char *) &c, 1);
	    }
	}
    }
    c = GIF_TERMINATOR;
    writeProc(handle, (char *) &c, 1);

    return TCL_OK;
}

static int
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
 *              James A. Woods          (decvax!ihnp4!ames!jaw)
 *              Joe Orost               (decvax!vax135!petsd!joe)
 */

static void
Compress(
    int initialBits,
    ClientData handle,
    WriteBytesFunc *writeProc,
    ifunptr readValue,
    GifWriterState *statePtr)
{
    long fcode, ent, disp, hSize, i = 0;
    int c, hshift;
    GIFState_t state;







|







2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
 *              James A. Woods          (decvax!ihnp4!ames!jaw)
 *              Joe Orost               (decvax!vax135!petsd!joe)
 */

static void
Compress(
    int initialBits,
    void *handle,
    WriteBytesFunc *writeProc,
    ifunptr readValue,
    GifWriterState *statePtr)
{
    long fcode, ent, disp, hSize, i = 0;
    int c, hshift;
    GIFState_t state;

Changes to generic/tkImgListFormat.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33




34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 *      list element being itself a list of pixels (or columns). For details,
 *      see the manpage photo.n
 *
 *      This image format cannot read/write files, it is meant for string
 *      data only.
 *
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2003 Donal K. Fellows
 * Copyright (c) 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Authors:
 *      Paul Mackerras ([email protected]),
 *              Department of Computer Science,
 *              Australian National University.
 *
 *      Simon Bachmann ([email protected])
 */


#include "tkImgPhoto.h"





/*
 * Message to generate when an attempt to allocate memory for an image fails.
 */

#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
        "not enough free memory for image buffer"


/*
 * Color name length limit: do not attempt to parse as color strings that are
 * longer than this limit
 */

#define TK_PHOTO_MAX_COLOR_CHARS 99

/*
 * Symbols for the different formats of a color string.
 */

enum ColorFormatType {
    COLORFORMAT_TKCOLOR,







|
|
|
|















>
>
>
>













|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 *      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 © 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,
 *              Australian National University.
 *
 *      Simon Bachmann ([email protected])
 */


#include "tkImgPhoto.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Message to generate when an attempt to allocate memory for an image fails.
 */

#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
        "not enough free memory for image buffer"


/*
 * Color name length limit: do not attempt to parse as color strings that are
 * longer than this limit
 */

#define TK_PHOTO_MAX_COLOR_LENGTH 99

/*
 * Symbols for the different formats of a color string.
 */

enum ColorFormatType {
    COLORFORMAT_TKCOLOR,
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
};

/*
 * Forward declarations
 */

static int      ParseFormatOptions(Tcl_Interp *interp, int allowedOptions,
                    int objc, Tcl_Obj *const objv[], int *indexPtr,
                    struct FormatOptions *optPtr);
static Tcl_Obj  *GetBadOptMsg(const char *badValue, int allowedOpts);
static int      StringMatchDef(Tcl_Obj *data, Tcl_Obj *formatString,
                    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int      StringReadDef(Tcl_Interp *interp, Tcl_Obj *data,
                    Tcl_Obj *formatString, Tk_PhotoHandle imageHandle,
                    int destX, int destY, int width, int height,
                    int srcX, int srcY);
static int      StringWriteDef(Tcl_Interp *interp,
                    Tcl_Obj *formatString,
                    Tk_PhotoImageBlock *blockPtr);
static int      ParseColor(Tcl_Interp *interp, Tcl_Obj *specObj,
                    Display *display, Colormap colormap, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsList(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsHex(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, Display *display, Colormap colormap,
                    unsigned char *redPtr, unsigned char *greenPtr,
                    unsigned char *bluePtr, unsigned char *alphaPtr);
static int      ParseColorAsStandard(Tcl_Interp *interp,







|















|
<







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
};

/*
 * Forward declarations
 */

static int      ParseFormatOptions(Tcl_Interp *interp, int allowedOptions,
                    Tcl_Size objc, Tcl_Obj *const objv[], Tcl_Size *indexPtr,
                    struct FormatOptions *optPtr);
static Tcl_Obj  *GetBadOptMsg(const char *badValue, int allowedOpts);
static int      StringMatchDef(Tcl_Obj *data, Tcl_Obj *formatString,
                    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int      StringReadDef(Tcl_Interp *interp, Tcl_Obj *data,
                    Tcl_Obj *formatString, Tk_PhotoHandle imageHandle,
                    int destX, int destY, int width, int height,
                    int srcX, int srcY);
static int      StringWriteDef(Tcl_Interp *interp,
                    Tcl_Obj *formatString,
                    Tk_PhotoImageBlock *blockPtr);
static int      ParseColor(Tcl_Interp *interp, Tcl_Obj *specObj,
                    Display *display, Colormap colormap, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsList(const char *colorString, unsigned char *redPtr,

                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsHex(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, Display *display, Colormap colormap,
                    unsigned char *redPtr, unsigned char *greenPtr,
                    unsigned char *bluePtr, unsigned char *alphaPtr);
static int      ParseColorAsStandard(Tcl_Interp *interp,
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
 *----------------------------------------------------------------------
 */
static int
ParseFormatOptions(
    Tcl_Interp *interp,               /* For error messages */
    int allowedOptions,               /* Bitfield specifying which options are
                                       * to be considered allowed */
    int objc,                         /* Number of elements in argv[] */
    Tcl_Obj *const objv[],            /* The arguments to parse */
    int *indexPtr,                    /* Index giving the first element to
                                       * parse. The value is updated to the
                                       * index where parsing ended */
    struct FormatOptions *optPtr)     /* Parsed option values are written to
                                       * this struct */

{
    int index, optIndex, first;
    enum ColorFormatType typeIndex;
    const char *option;

    first = 1;

    /*
     * Fill in default values
     */







|

|






|
|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
 *----------------------------------------------------------------------
 */
static int
ParseFormatOptions(
    Tcl_Interp *interp,               /* For error messages */
    int allowedOptions,               /* Bitfield specifying which options are
                                       * to be considered allowed */
    Tcl_Size objc,                         /* Number of elements in argv[] */
    Tcl_Obj *const objv[],            /* The arguments to parse */
    Tcl_Size *indexPtr,                    /* Index giving the first element to
                                       * parse. The value is updated to the
                                       * index where parsing ended */
    struct FormatOptions *optPtr)     /* Parsed option values are written to
                                       * this struct */

{
    Tcl_Size optIndex, index;
    int first, typeIndex;
    const char *option;

    first = 1;

    /*
     * Fill in default values
     */
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("the \"%s\" option "
                        "requires a value", Tcl_GetString(objv[index - 1])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "MISSING_VALUE", NULL);
                return TCL_ERROR;
            }
            if (Tcl_GetIndexFromObj(NULL, objv[index], colorFormatNames, "",
                    TCL_EXACT, (int *)&typeIndex) != TCL_OK
                    || (typeIndex != COLORFORMAT_LIST
                    && typeIndex != COLORFORMAT_RGB2
                    && typeIndex != COLORFORMAT_RGBA2) ) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad color format "
                        "\"%s\": must be rgb, rgba, or list",
                        Tcl_GetString(objv[index])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "BAD_COLOR_FORMAT", NULL);
                return TCL_ERROR;
            }
            optPtr->colorFormat = typeIndex;
            break;
        default:
            Tcl_Panic("ParseFormatOptions: unexpected switch fallthrough");
        }

        /*
         * Add option to bitfield in optPtr







|










|







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("the \"%s\" option "
                        "requires a value", Tcl_GetString(objv[index - 1])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "MISSING_VALUE", NULL);
                return TCL_ERROR;
            }
            if (Tcl_GetIndexFromObj(NULL, objv[index], colorFormatNames, "",
                    TCL_EXACT, &typeIndex) != TCL_OK
                    || (typeIndex != COLORFORMAT_LIST
                    && typeIndex != COLORFORMAT_RGB2
                    && typeIndex != COLORFORMAT_RGBA2) ) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad color format "
                        "\"%s\": must be rgb, rgba, or list",
                        Tcl_GetString(objv[index])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "BAD_COLOR_FORMAT", NULL);
                return TCL_ERROR;
            }
            optPtr->colorFormat = (enum ColorFormatType)typeIndex;
            break;
        default:
            Tcl_Panic("ParseFormatOptions: unexpected switch fallthrough");
        }

        /*
         * Add option to bitfield in optPtr
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
    const char *badValue,   /* the erroneous option */
    int allowedOpts)        /* bitfield specifying the allowed options */
{
    int i, bit;
    Tcl_Obj *resObj = Tcl_ObjPrintf("bad format option \"%s\": ", badValue);

    if (allowedOpts == 0) {
        Tcl_AppendToObj(resObj, "no options allowed", -1);
    } else {
        Tcl_AppendToObj(resObj, "must be ", -1);
        bit = 1;
        for (i = 0; formatOptionNames[i] != NULL; i++) {
            if (allowedOpts & bit) {
                if (allowedOpts & (bit -1)) {
                    /*
                     * not the first option
                     */
                    if (allowedOpts & ~((bit << 1) - 1)) {
                        /*
                         * not the last option
                         */
                        Tcl_AppendToObj(resObj, ", ", -1);
                    } else {
                        Tcl_AppendToObj(resObj, ", or ", -1);
                    }
                }
                Tcl_AppendToObj(resObj, formatOptionNames[i], -1);
            }
            bit <<=1;
        }
    }
    return resObj;
}








|

|











|

|


|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
    const char *badValue,   /* the erroneous option */
    int allowedOpts)        /* bitfield specifying the allowed options */
{
    int i, bit;
    Tcl_Obj *resObj = Tcl_ObjPrintf("bad format option \"%s\": ", badValue);

    if (allowedOpts == 0) {
        Tcl_AppendToObj(resObj, "no options allowed", TCL_INDEX_NONE);
    } else {
        Tcl_AppendToObj(resObj, "must be ", TCL_INDEX_NONE);
        bit = 1;
        for (i = 0; formatOptionNames[i] != NULL; i++) {
            if (allowedOpts & bit) {
                if (allowedOpts & (bit -1)) {
                    /*
                     * not the first option
                     */
                    if (allowedOpts & ~((bit << 1) - 1)) {
                        /*
                         * not the last option
                         */
                        Tcl_AppendToObj(resObj, ", ", TCL_INDEX_NONE);
                    } else {
                        Tcl_AppendToObj(resObj, ", or ", TCL_INDEX_NONE);
                    }
                }
                Tcl_AppendToObj(resObj, formatOptionNames[i], TCL_INDEX_NONE);
            }
            bit <<=1;
        }
    }
    return resObj;
}

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
static int
StringMatchDef(
    Tcl_Obj *data,          /* The data to check */
    Tcl_Obj *formatString,  /* Value of the -format option, not used here */
    int *widthPtr,          /* Width of image is written to this location */
    int *heightPtr,         /* Height of image is written to this location */
    Tcl_Interp *interp)     /* Error messages are left in this interpreter */
{
    int y, rowCount, colCount, curColCount;
    unsigned char dummy;
    Tcl_Obj **rowListPtr, *pixelData;
    (void)formatString;

    /*
     * See if data can be parsed as a list, if every element is itself a valid
     * list and all sublists have the same length.
     */

    if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)







|




|


<







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
static int
StringMatchDef(
    Tcl_Obj *data,          /* The data to check */
    TCL_UNUSED(Tcl_Obj *),  /* Value of the -format option, not used here */
    int *widthPtr,          /* Width of image is written to this location */
    int *heightPtr,         /* Height of image is written to this location */
    Tcl_Interp *interp)     /* Error messages are left in this interpreter */
{
    Tcl_Size y, rowCount, colCount, curColCount;
    unsigned char dummy;
    Tcl_Obj **rowListPtr, *pixelData;


    /*
     * See if data can be parsed as a list, if every element is itself a valid
     * list and all sublists have the same length.
     */

    if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
        if (Tcl_ListObjLength(interp, rowListPtr[y], &curColCount) != TCL_OK) {
            return 0;
        }
        if (colCount < 0) {
            colCount = curColCount;
        } else if (curColCount != colCount) {
            if (interp != NULL) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid row # %d: "
                        "all rows must have the same number of elements", y));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "INVALID_DATA", NULL);
            }
            return 0;
        }
    }

    /*
     * Data in base64 encoding (or even binary data), might actually pass
     * these tests. To avoid parsing it as list of lists format, check one
     * pixel for validity.
     */
    if (Tcl_ListObjIndex(interp, rowListPtr[0], 0, &pixelData) != TCL_OK) {
        return 0;
    }

    if (Tcl_GetCharLength(pixelData) > TK_PHOTO_MAX_COLOR_CHARS) {
        return 0;
    }
    if (ParseColor(interp, pixelData, Tk_Display(Tk_MainWindow(interp)),
            Tk_Colormap(Tk_MainWindow(interp)), &dummy, &dummy, &dummy, &dummy)
            != TCL_OK) {
        return 0;
    }







|
















>
|







394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
        if (Tcl_ListObjLength(interp, rowListPtr[y], &curColCount) != TCL_OK) {
            return 0;
        }
        if (colCount < 0) {
            colCount = curColCount;
        } else if (curColCount != colCount) {
            if (interp != NULL) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid row # %" TCL_SIZE_MODIFIER "d: "
                        "all rows must have the same number of elements", y));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "INVALID_DATA", NULL);
            }
            return 0;
        }
    }

    /*
     * Data in base64 encoding (or even binary data), might actually pass
     * these tests. To avoid parsing it as list of lists format, check one
     * pixel for validity.
     */
    if (Tcl_ListObjIndex(interp, rowListPtr[0], 0, &pixelData) != TCL_OK) {
        return 0;
    }
    (void)Tcl_GetString(pixelData);
    if (pixelData->length > TK_PHOTO_MAX_COLOR_LENGTH) {
        return 0;
    }
    if (ParseColor(interp, pixelData, Tk_Display(Tk_MainWindow(interp)),
            Tk_Colormap(Tk_MainWindow(interp)), &dummy, &dummy, &dummy, &dummy)
            != TCL_OK) {
        return 0;
    }
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
                                 * in destination image*/
    int width, int height,      /* dimensions of area to write to */
    int srcX, int srcY)         /* start reading source data at these
                                 * coordinates */
{
    Tcl_Obj **rowListPtr, **colListPtr;
    Tcl_Obj **objv;
    int objc;
    unsigned char *curPixelPtr;
    int x, y, rowCount, colCount, curColCount;
    Tk_PhotoImageBlock srcBlock;
    Display *display;
    Colormap colormap;
    struct FormatOptions opts;
    int optIndex;

    /*
     * Parse format suboptions
     * We don't use any format suboptions, but we still need to provide useful
     * error messages if suboptions were specified.
     */








|

|




|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
                                 * in destination image*/
    int width, int height,      /* dimensions of area to write to */
    int srcX, int srcY)         /* start reading source data at these
                                 * coordinates */
{
    Tcl_Obj **rowListPtr, **colListPtr;
    Tcl_Obj **objv;
    Tcl_Size objc, rowCount, colCount, curColCount;
    unsigned char *curPixelPtr;
    int x, y;
    Tk_PhotoImageBlock srcBlock;
    Display *display;
    Colormap colormap;
    struct FormatOptions opts;
    Tcl_Size optIndex;

    /*
     * Parse format suboptions
     * We don't use any format suboptions, but we still need to provide useful
     * error messages if suboptions were specified.
     */

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
StringWriteDef(
    Tcl_Interp *interp,                 /* For the result and errors */
    Tcl_Obj *formatString,              /* The value of the -format option */
    Tk_PhotoImageBlock *blockPtr)       /* The image data to convert */
{
    int greenOffset, blueOffset, alphaOffset, hasAlpha;
    Tcl_Obj *result, **objv = NULL;
    int objc, allowedOpts, optIndex;
    struct FormatOptions opts;

    /*
     * Parse format suboptions
     */
    if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
            != TCL_OK) {







|







624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
StringWriteDef(
    Tcl_Interp *interp,                 /* For the result and errors */
    Tcl_Obj *formatString,              /* The value of the -format option */
    Tk_PhotoImageBlock *blockPtr)       /* The image data to convert */
{
    int greenOffset, blueOffset, alphaOffset, hasAlpha;
    Tcl_Obj *result, **objv = NULL;
    Tcl_Size objc, allowedOpts, optIndex;
    struct FormatOptions opts;

    /*
     * Parse format suboptions
     */
    if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
            != TCL_OK) {
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
                 * While this is not a problem if the data is used as
                 * a list, it would cause problems if someone decides to parse
                 * it as a string (and it looks kinda strange)
                 */

                switch (opts.colorFormat) {
                case COLORFORMAT_RGB2:
                    sprintf(colorBuf, "#%02x%02x%02x ",  pixelPtr[0],
                            pixelPtr[greenOffset], pixelPtr[blueOffset]);
                    Tcl_DStringAppend(&line, colorBuf, -1);
                    break;
                case COLORFORMAT_RGBA2:
                    sprintf(colorBuf, "#%02x%02x%02x%02x ",
                            pixelPtr[0], pixelPtr[greenOffset],
                            pixelPtr[blueOffset], alphaVal);
                    Tcl_DStringAppend(&line, colorBuf, -1);
                    break;
                case COLORFORMAT_LIST:
                    Tcl_DStringStartSublist(&line);
                    sprintf(colorBuf, "%d", pixelPtr[0]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", pixelPtr[greenOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", pixelPtr[blueOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", alphaVal);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    Tcl_DStringEndSublist(&line);
                    break;
                default:
                    Tcl_Panic("unexpected switch fallthrough");
                }
                pixelPtr += blockPtr->pixelSize;
            }
            if (opts.colorFormat != COLORFORMAT_LIST) {
                /*
                 * For the #XXX formats, we need to remove the last
                 * whitespace.
                 */

                *(Tcl_DStringValue(&line) + Tcl_DStringLength(&line) - 1)
                        = '\0';
            }
            Tcl_DStringAppendElement(&data, Tcl_DStringValue(&line));
            Tcl_DStringFree(&line);
        }
        result = Tcl_NewStringObj(Tcl_DStringValue(&data), -1);
        Tcl_DStringFree(&data);
    } else {
        result = Tcl_NewObj();
    }

    Tcl_SetObjResult(interp, result);
    return TCL_OK;







|

|


|


|



|

|

|

|




















|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
                 * While this is not a problem if the data is used as
                 * a list, it would cause problems if someone decides to parse
                 * it as a string (and it looks kinda strange)
                 */

                switch (opts.colorFormat) {
                case COLORFORMAT_RGB2:
                    snprintf(colorBuf, sizeof(colorBuf), "#%02x%02x%02x ",  pixelPtr[0],
                            pixelPtr[greenOffset], pixelPtr[blueOffset]);
                    Tcl_DStringAppend(&line, colorBuf, TCL_INDEX_NONE);
                    break;
                case COLORFORMAT_RGBA2:
                    snprintf(colorBuf, sizeof(colorBuf), "#%02x%02x%02x%02x ",
                            pixelPtr[0], pixelPtr[greenOffset],
                            pixelPtr[blueOffset], alphaVal);
                    Tcl_DStringAppend(&line, colorBuf, TCL_INDEX_NONE);
                    break;
                case COLORFORMAT_LIST:
                    Tcl_DStringStartSublist(&line);
                    snprintf(colorBuf, sizeof(colorBuf), "%d", pixelPtr[0]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    snprintf(colorBuf, sizeof(colorBuf), "%d", pixelPtr[greenOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    snprintf(colorBuf, sizeof(colorBuf), "%d", pixelPtr[blueOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    snprintf(colorBuf, sizeof(colorBuf), "%d", alphaVal);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    Tcl_DStringEndSublist(&line);
                    break;
                default:
                    Tcl_Panic("unexpected switch fallthrough");
                }
                pixelPtr += blockPtr->pixelSize;
            }
            if (opts.colorFormat != COLORFORMAT_LIST) {
                /*
                 * For the #XXX formats, we need to remove the last
                 * whitespace.
                 */

                *(Tcl_DStringValue(&line) + Tcl_DStringLength(&line) - 1)
                        = '\0';
            }
            Tcl_DStringAppendElement(&data, Tcl_DStringValue(&line));
            Tcl_DStringFree(&line);
        }
        result = Tcl_NewStringObj(Tcl_DStringValue(&data), TCL_INDEX_NONE);
        Tcl_DStringFree(&data);
    } else {
        result = Tcl_NewObj();
    }

    Tcl_SetObjResult(interp, result);
    return TCL_OK;
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
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
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    const char *specString;
    TkSizeT charCount;

    /*
     * Find out which color format we have
     */

    specString = TkGetStringFromObj(specObj, &charCount);

    if (charCount == 0) {
        /* Empty string */
        *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0;
        return TCL_OK;
    }
    if (charCount > TK_PHOTO_MAX_COLOR_CHARS) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid color"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                "INVALID_COLOR", NULL);
        return TCL_ERROR;
    }
    if (specString[0] == '#') {
        return ParseColorAsHex(interp, specString, charCount, display,
                colormap, redPtr, greenPtr, bluePtr, alphaPtr);
    }
    if (ParseColorAsList(interp, specString, charCount,
            redPtr, greenPtr, bluePtr, alphaPtr) == TCL_OK) {
        return TCL_OK;
    }

    /*
     * Parsing the color as standard Tk color always is the last option tried
     * because TkParseColor() is very slow with values it cannot parse.
     */

    Tcl_ResetResult(interp);
    return ParseColorAsStandard(interp, specString, charCount, display,
            colormap, redPtr, greenPtr, bluePtr, alphaPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsList --
 *
 *      This function extracts color and alpha values from a list of 3 or 4
 *      integers (the list color format).
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      Does *not* leave error messages in interp. The reason is that
 *      it is not always possible to tell if the list format was even
 *      intended and thus it is hard to return meaningful messages.
 *      A general error message from the caller is probably the best
 *      alternative.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsList(
    Tcl_Interp *dummy,         /* not used */
    const char *colorString,    /* the color data to parse */
    int colorStrLen,            /* length of the color string */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    /*
     * This is kinda ugly. The code would be certainly nicer if it
     * used Tcl_ListObjGetElements() and Tcl_GetIntFromObj(). But with
     * strtol() it's *much* faster.
     */

    const char *curPos;
    int values[4];
    int i;
    (void)dummy;
    (void)colorStrLen;

    curPos = colorString;
    i = 0;

    /*
     * strtol can give false positives with a sequence of space chars.
     * To avoid that, avance the pointer to the next non-blank char.
     */

    while(isspace(UCHAR(*curPos))) {
        ++curPos;
    }
    while (i < 4 && *curPos != '\0') {
        values[i] = strtol(curPos, (char **)&curPos, 0);







|





|

|




|






|


|










|



















<
<
<
<
|





<

<














<
<






|







774
775
776
777
778
779
780
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
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    const char *specString;
    Tcl_Size length;

    /*
     * Find out which color format we have
     */

    specString = Tcl_GetStringFromObj(specObj, &length);

    if (length == 0) {
        /* Empty string */
        *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0;
        return TCL_OK;
    }
    if (length > TK_PHOTO_MAX_COLOR_LENGTH) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid color"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                "INVALID_COLOR", NULL);
        return TCL_ERROR;
    }
    if (specString[0] == '#') {
        return ParseColorAsHex(interp, specString, length, display,
                colormap, redPtr, greenPtr, bluePtr, alphaPtr);
    }
    if (ParseColorAsList(specString,
            redPtr, greenPtr, bluePtr, alphaPtr) == TCL_OK) {
        return TCL_OK;
    }

    /*
     * Parsing the color as standard Tk color always is the last option tried
     * because TkParseColor() is very slow with values it cannot parse.
     */

    Tcl_ResetResult(interp);
    return ParseColorAsStandard(interp, specString, length, display,
            colormap, redPtr, greenPtr, bluePtr, alphaPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsList --
 *
 *      This function extracts color and alpha values from a list of 3 or 4
 *      integers (the list color format).
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:




 *      None
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsList(

    const char *colorString,    /* the color data to parse */

    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    /*
     * This is kinda ugly. The code would be certainly nicer if it
     * used Tcl_ListObjGetElements() and Tcl_GetIntFromObj(). But with
     * strtol() it's *much* faster.
     */

    const char *curPos;
    int values[4];
    int i;



    curPos = colorString;
    i = 0;

    /*
     * strtol can give false positives with a sequence of space chars.
     * To avoid that, advance the pointer to the next non-blank char.
     */

    while(isspace(UCHAR(*curPos))) {
        ++curPos;
    }
    while (i < 4 && *curPos != '\0') {
        values[i] = strtol(curPos, (char **)&curPos, 0);
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    XColor parsedColor;
    const char *suffixString, *colorString;
    char colorBuffer[TK_PHOTO_MAX_COLOR_CHARS + 1];
    char *tmpString;
    double fracAlpha;
    unsigned int suffixAlpha;
    int i;

    /*
     * Split color data string in color and suffix parts
     */







|
<







996
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    XColor parsedColor;
    const char *suffixString, *colorString;
    char colorBuffer[TK_PHOTO_MAX_COLOR_LENGTH + 1];

    double fracAlpha;
    unsigned int suffixAlpha;
    int i;

    /*
     * Split color data string in color and suffix parts
     */
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
     */

    switch (suffixString[0]) {
    case '\0':
        suffixAlpha = 255;
        break;
    case '@':
        fracAlpha = strtod(suffixString + 1, &tmpString);
        if (*tmpString != '\0') {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha "
                    "suffix \"%s\": expected floating-point value",
                    suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID COLOR", NULL);
            return TCL_ERROR;
        }







|
<







1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
     */

    switch (suffixString[0]) {
    case '\0':
        suffixAlpha = 255;
        break;
    case '@':
        if (Tcl_GetDouble(NULL, suffixString + 1, &fracAlpha) != TCL_OK) {

            Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha "
                    "suffix \"%s\": expected floating-point value",
                    suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID COLOR", NULL);
            return TCL_ERROR;
        }

Changes to generic/tkImgPNG.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkImgPNG.c --
 *
 *	A Tk photo image file handler for PNG files.
 *
 * Copyright (c) 2006-2008 Muonics, Inc.
 * Copyright (c) 2008 Donal K. Fellows
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#define	PNG_INT32(a,b,c,d)	\
	(((long)(a) << 24) | ((long)(b) << 16) | ((long)(c) << 8) | (long)(d))
#define	PNG_BLOCK_SZ	1024		/* Process up to 1k at a time. */
#define PNG_MIN(a, b) (((a) < (b)) ? (a) : (b))

/*
 * Every PNG image starts with the following 8-byte signature.
 */






|
|







|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkImgPNG.c --
 *
 *	A Tk photo image file handler for PNG files.
 *
 * 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"

#define	PNG_UINT32(a,b,c,d)	\
	(((unsigned long)(a) << 24) | ((unsigned long)(b) << 16) | ((unsigned long)(c) << 8) | (unsigned long)(d))
#define	PNG_BLOCK_SZ	1024		/* Process up to 1k at a time. */
#define PNG_MIN(a, b) (((a) < (b)) ? (a) : (b))

/*
 * Every PNG image starts with the following 8-byte signature.
 */

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

/*
 * Chunk types, not all of which have support implemented. Note that there are
 * others in the official extension set which we will never support (as they
 * are officially deprecated).
 */

#define CHUNK_IDAT	PNG_INT32('I','D','A','T')	/* Pixel data. */
#define CHUNK_IEND	PNG_INT32('I','E','N','D')	/* End of Image. */
#define CHUNK_IHDR	PNG_INT32('I','H','D','R')	/* Header. */
#define CHUNK_PLTE	PNG_INT32('P','L','T','E')	/* Palette. */

#define CHUNK_bKGD	PNG_INT32('b','K','G','D')	/* Background Color */
#define CHUNK_cHRM	PNG_INT32('c','H','R','M')	/* Chroma values. */
#define CHUNK_gAMA	PNG_INT32('g','A','M','A')	/* Gamma. */
#define CHUNK_hIST	PNG_INT32('h','I','S','T')	/* Histogram. */
#define CHUNK_iCCP	PNG_INT32('i','C','C','P')	/* Color profile. */
#define CHUNK_iTXt	PNG_INT32('i','T','X','t')	/* Internationalized
							 * text (comments,
							 * etc.) */
#define CHUNK_oFFs	PNG_INT32('o','F','F','s')	/* Image offset. */
#define CHUNK_pCAL	PNG_INT32('p','C','A','L')	/* Pixel calibration
							 * data. */
#define CHUNK_pHYs	PNG_INT32('p','H','Y','s')	/* Physical pixel
							 * dimensions. */
#define CHUNK_sBIT	PNG_INT32('s','B','I','T')	/* Significant bits */
#define CHUNK_sCAL	PNG_INT32('s','C','A','L')	/* Physical scale. */
#define CHUNK_sPLT	PNG_INT32('s','P','L','T')	/* Suggested
							 * palette. */
#define CHUNK_sRGB	PNG_INT32('s','R','G','B')	/* Standard RGB space
							 * declaration. */
#define CHUNK_tEXt	PNG_INT32('t','E','X','t')	/* Plain Latin-1
							 * text. */
#define CHUNK_tIME	PNG_INT32('t','I','M','E')	/* Time stamp. */
#define CHUNK_tRNS	PNG_INT32('t','R','N','S')	/* Transparency. */
#define CHUNK_zTXt	PNG_INT32('z','T','X','t')	/* Compressed Latin-1
							 * text. */

/*
 * Color flags.
 */

#define PNG_COLOR_INDEXED	1







|
|
|
|

|
|
|
|
|
|


|
|

|

|
|
|

|

|

|
|
|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

/*
 * Chunk types, not all of which have support implemented. Note that there are
 * others in the official extension set which we will never support (as they
 * are officially deprecated).
 */

#define CHUNK_IDAT	PNG_UINT32('I','D','A','T')	/* Pixel data. */
#define CHUNK_IEND	PNG_UINT32('I','E','N','D')	/* End of Image. */
#define CHUNK_IHDR	PNG_UINT32('I','H','D','R')	/* Header. */
#define CHUNK_PLTE	PNG_UINT32('P','L','T','E')	/* Palette. */

#define CHUNK_bKGD	PNG_UINT32('b','K','G','D')	/* Background Color */
#define CHUNK_cHRM	PNG_UINT32('c','H','R','M')	/* Chroma values. */
#define CHUNK_gAMA	PNG_UINT32('g','A','M','A')	/* Gamma. */
#define CHUNK_hIST	PNG_UINT32('h','I','S','T')	/* Histogram. */
#define CHUNK_iCCP	PNG_UINT32('i','C','C','P')	/* Color profile. */
#define CHUNK_iTXt	PNG_UINT32('i','T','X','t')	/* Internationalized
							 * text (comments,
							 * etc.) */
#define CHUNK_oFFs	PNG_UINT32('o','F','F','s')	/* Image offset. */
#define CHUNK_pCAL	PNG_UINT32('p','C','A','L')	/* Pixel calibration
							 * data. */
#define CHUNK_pHYs	PNG_UINT32('p','H','Y','s')	/* Physical pixel
							 * dimensions. */
#define CHUNK_sBIT	PNG_UINT32('s','B','I','T')	/* Significant bits */
#define CHUNK_sCAL	PNG_UINT32('s','C','A','L')	/* Physical scale. */
#define CHUNK_sPLT	PNG_UINT32('s','P','L','T')	/* Suggested
							 * palette. */
#define CHUNK_sRGB	PNG_UINT32('s','R','G','B')	/* Standard RGB space
							 * declaration. */
#define CHUNK_tEXt	PNG_UINT32('t','E','X','t')	/* Plain Latin-1
							 * text. */
#define CHUNK_tIME	PNG_UINT32('t','I','M','E')	/* Time stamp. */
#define CHUNK_tRNS	PNG_UINT32('t','R','N','S')	/* Transparency. */
#define CHUNK_zTXt	PNG_UINT32('z','T','X','t')	/* Compressed Latin-1
							 * text. */

/*
 * Color flags.
 */

#define PNG_COLOR_INDEXED	1
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    /*
     * PNG data source/destination channel/object/byte array.
     */

    Tcl_Channel channel;	/* Channel for from-file reads. */
    Tcl_Obj *objDataPtr;
    unsigned char *strDataBuf;	/* Raw source data for from-string reads. */
    TkSizeT strDataLen;		/* Length of source data. */
    unsigned char *base64Data;	/* base64 encoded string data. */
    unsigned char base64Bits;	/* Remaining bits from last base64 read. */
    unsigned char base64State;	/* Current state of base64 decoder. */
    double alpha;		/* Alpha from -format option. */

    /*
     * Image header information.







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    /*
     * PNG data source/destination channel/object/byte array.
     */

    Tcl_Channel channel;	/* Channel for from-file reads. */
    Tcl_Obj *objDataPtr;
    unsigned char *strDataBuf;	/* Raw source data for from-string reads. */
    Tcl_Size strDataLen;		/* Length of source data. */
    unsigned char *base64Data;	/* base64 encoded string data. */
    unsigned char base64Bits;	/* Remaining bits from last base64 read. */
    unsigned char base64State;	/* Current state of base64 decoder. */
    double alpha;		/* Alpha from -format option. */

    /*
     * Image header information.
171
172
173
174
175
176
177









178
179
180
181
182
183
184

    Tcl_ZlibStream stream;	/* Inflating or deflating stream; this one is
				 * not bound to a Tcl command. */
    Tcl_Obj *lastLineObj;	/* Last line of pixels, for unfiltering. */
    Tcl_Obj *thisLineObj;	/* Current line of pixels to process. */
    int lineSize;		/* Number of bytes in a PNG line. */
    int phaseSize;		/* Number of bytes/line in current phase. */









} PNGImage;

/*
 * Maximum size of various chunks.
 */

#define	PNG_PLTE_MAXSZ 768	/* 3 bytes/RGB entry, 256 entries max */







>
>
>
>
>
>
>
>
>







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

    Tcl_ZlibStream stream;	/* Inflating or deflating stream; this one is
				 * not bound to a Tcl command. */
    Tcl_Obj *lastLineObj;	/* Last line of pixels, for unfiltering. */
    Tcl_Obj *thisLineObj;	/* Current line of pixels to process. */
    int lineSize;		/* Number of bytes in a PNG line. */
    int phaseSize;		/* Number of bytes/line in current phase. */


    /*
     * Physical size: pHYS chunks.
     */

    double DPI;
    double aspect;

} PNGImage;

/*
 * Maximum size of various chunks.
 */

#define	PNG_PLTE_MAXSZ 768	/* 3 bytes/RGB entry, 256 entries max */
194
195
196
197
198
199
200
201

202
203
204

205
206
207
208

209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240
241
242

243
244
245

246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
			    unsigned long calculated);
static void		CleanupPNGImage(PNGImage *pngPtr);
static int		DecodeLine(Tcl_Interp *interp, PNGImage *pngPtr);
static int		DecodePNG(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY);
static int		EncodePNG(Tcl_Interp *interp,
			    Tk_PhotoImageBlock *blockPtr, PNGImage *pngPtr);

static int		FileMatchPNG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *fmtObj, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);

static int		FileReadPNG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *fmtObj,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);

static int		FileWritePNG(Tcl_Interp *interp, const char *filename,

			    Tcl_Obj *fmtObj, Tk_PhotoImageBlock *blockPtr);
static int		InitPNGImage(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Channel chan, Tcl_Obj *objPtr, int dir);
static inline unsigned char Paeth(int a, int b, int c);
static int		ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    PNGImage *pngPtr);
static int		ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
			    size_t *sizePtr, unsigned long *typePtr,
			    unsigned long *crcPtr);
static int		ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long *resultPtr, unsigned long *crcPtr);
static int		ReadPLTE(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadTRNS(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		SkipChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		StringMatchPNG(Tcl_Obj *dataObj, Tcl_Obj *fmtObj,

			    int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		StringReadPNG(Tcl_Interp *interp, Tcl_Obj *dataObj,

			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);

static int		StringWritePNG(Tcl_Interp *interp, Tcl_Obj *fmtObj,

			    Tk_PhotoImageBlock *blockPtr);
static int		UnfilterLine(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	WriteByte(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char c, unsigned long *crcPtr);
static inline int	WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long chunkType,
			    const unsigned char *dataPtr, size_t dataSize);
static int		WriteData(Tcl_Interp *interp, PNGImage *pngPtr,
			    const unsigned char *srcPtr, size_t srcSz,
			    unsigned long *crcPtr);
static int		WriteExtraChunks(Tcl_Interp *interp,
			    PNGImage *pngPtr);
static int		WriteIHDR(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		WriteIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static inline int	WriteInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long l, unsigned long *crcPtr);

/*
 * The format record for the PNG file format:
 */

Tk_PhotoImageFormat tkImgFmtPNG = {
    "png",			/* name */
    FileMatchPNG,		/* fileMatchProc */
    StringMatchPNG,		/* stringMatchProc */
    FileReadPNG,		/* fileReadProc */
    StringReadPNG,		/* stringReadProc */
    FileWritePNG,		/* fileWriteProc */
    StringWritePNG,		/* stringWriteProc */







|
>
|
|
|
>


|
|
>

>
|






|


|


|


|












|
>

|
|
>
|

|
>

>






|

|


|











|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
			    unsigned long calculated);
static void		CleanupPNGImage(PNGImage *pngPtr);
static int		DecodeLine(Tcl_Interp *interp, PNGImage *pngPtr);
static int		DecodePNG(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY);
static int		EncodePNG(Tcl_Interp *interp,
			    Tk_PhotoImageBlock *blockPtr, PNGImage *pngPtr,
			    Tcl_Obj *metadataInObj);
static int		FileMatchPNG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *fmtObj,
			    Tcl_Obj *metadataInObj, int *widthPtr,
			    int *heightPtr, Tcl_Obj *metadataOut);
static int		FileReadPNG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *fmtObj,
			    Tcl_Obj *metadataInObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, Tcl_Obj *metadataOutPtr);
static int		FileWritePNG(Tcl_Interp *interp, const char *filename,
			    Tcl_Obj *fmtObj, Tcl_Obj *metadataInObj,
			    Tk_PhotoImageBlock *blockPtr);
static int		InitPNGImage(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Channel chan, Tcl_Obj *objPtr, int dir);
static inline unsigned char Paeth(int a, int b, int c);
static int		ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    PNGImage *pngPtr);
static int		ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, Tcl_Size destSz,
			    unsigned long *crcPtr);
static int		ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, Tcl_Size destSz,
			    unsigned long *crcPtr);
static int		ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, Tcl_Size destSz,
			    unsigned long *crcPtr);
static int		ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Size *sizePtr, unsigned long *typePtr,
			    unsigned long *crcPtr);
static int		ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long *resultPtr, unsigned long *crcPtr);
static int		ReadPLTE(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadTRNS(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		SkipChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		StringMatchPNG(Tcl_Interp *interp, Tcl_Obj *pObjData,
			    Tcl_Obj *fmtObj, Tcl_Obj *metadataInObj,
			    int *widthPtr, int *heightPtr,
			    Tcl_Obj *metadataOutObj);
static int		StringReadPNG(Tcl_Interp *interp, Tcl_Obj *pObjData,
			    Tcl_Obj *fmtObj, Tcl_Obj *metadataInObj,
			    Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, Tcl_Obj *metadataOutObj);

static int		StringWritePNG(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    Tcl_Obj *metadataInObj,
			    Tk_PhotoImageBlock *blockPtr);
static int		UnfilterLine(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	WriteByte(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char c, unsigned long *crcPtr);
static inline int	WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long chunkType,
			    const unsigned char *dataPtr, Tcl_Size dataSize);
static int		WriteData(Tcl_Interp *interp, PNGImage *pngPtr,
			    const unsigned char *srcPtr, Tcl_Size srcSz,
			    unsigned long *crcPtr);
static int		WriteExtraChunks(Tcl_Interp *interp,
			    PNGImage *pngPtr, Tcl_Obj *metadataInObj);
static int		WriteIHDR(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		WriteIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static inline int	WriteInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long l, unsigned long *crcPtr);

/*
 * The format record for the PNG file format:
 */

Tk_PhotoImageFormatVersion3 tkImgFmtPNG = {
    "png",			/* name */
    FileMatchPNG,		/* fileMatchProc */
    StringMatchPNG,		/* stringMatchProc */
    FileReadPNG,		/* fileReadProc */
    StringReadPNG,		/* stringReadProc */
    FileWritePNG,		/* fileWriteProc */
    StringWritePNG,		/* stringWriteProc */
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347







348
349
350
351
352
353
354
     * reading with ReadData().
     */

    if (objPtr) {
	Tcl_IncrRefCount(objPtr);
	pngPtr->objDataPtr = objPtr;
	pngPtr->strDataBuf =
		TkGetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
    }

    /*
     * Initialize the palette transparency table to fully opaque.
     */

    memset(pngPtr->palette, 255, sizeof(pngPtr->palette));

    /*
     * Initialize Zlib inflate/deflate stream.
     */

    if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB,
	    TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "zlib initialization failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL);
	}
	if (objPtr) {
	    Tcl_DecrRefCount(objPtr);
	}
	return TCL_ERROR;
    }








    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupPNGImage --







|
















|








>
>
>
>
>
>
>







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
     * reading with ReadData().
     */

    if (objPtr) {
	Tcl_IncrRefCount(objPtr);
	pngPtr->objDataPtr = objPtr;
	pngPtr->strDataBuf =
		Tcl_GetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
    }

    /*
     * Initialize the palette transparency table to fully opaque.
     */

    memset(pngPtr->palette, 255, sizeof(pngPtr->palette));

    /*
     * Initialize Zlib inflate/deflate stream.
     */

    if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB,
	    TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "zlib initialization failed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL);
	}
	if (objPtr) {
	    Tcl_DecrRefCount(objPtr);
	}
	return TCL_ERROR;
    }

    /*
     * Initialize physical size pHYS values
     */

    pngPtr->DPI = -1;
    pngPtr->aspect = -1;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupPNGImage --
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
 */

static int
ReadBase64(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    unsigned long *crcPtr)
{
    static const unsigned char from64[] = {
	0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x80,
	0x83, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x3e,







|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
 */

static int
ReadBase64(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    Tcl_Size destSz,
    unsigned long *crcPtr)
{
    static const unsigned char from64[] = {
	0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x80,
	0x83, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x3e,
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83
    };

    /*
     * Definitions for the base-64 decoder.
     */

#define PNG64_SPECIAL	0x80	/* Flag bit */







|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83
    };

    /*
     * Definitions for the base-64 decoder.
     */

#define PNG64_SPECIAL	0x80	/* Flag bit */
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
	if (c64 & PNG64_SPECIAL) {
	    break;
	}
    }

    if (destSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unexpected end of image data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}








|







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
	if (c64 & PNG64_SPECIAL) {
	    break;
	}
    }

    if (destSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unexpected end of image data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
 */

static int
ReadByteArray(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    unsigned long *crcPtr)
{
    /*
     * Check to make sure the number of requested bytes are available.
     */

    if ((size_t)pngPtr->strDataLen < destSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unexpected end of image data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    while (destSz) {
	size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	memcpy(destPtr, pngPtr->strDataBuf, blockSz);

	pngPtr->strDataBuf += blockSz;
	pngPtr->strDataLen -= blockSz;

	if (crcPtr) {







|






|

|





|







575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
 */

static int
ReadByteArray(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    Tcl_Size destSz,
    unsigned long *crcPtr)
{
    /*
     * Check to make sure the number of requested bytes are available.
     */

    if (pngPtr->strDataLen < destSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unexpected end of image data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    while (destSz) {
	Tcl_Size blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	memcpy(destPtr, pngPtr->strDataBuf, blockSz);

	pngPtr->strDataBuf += blockSz;
	pngPtr->strDataLen -= blockSz;

	if (crcPtr) {
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
 */

static int
ReadData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    unsigned long *crcPtr)
{
    if (pngPtr->base64Data) {
	return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr);
    } else if (pngPtr->strDataBuf) {
	return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr);
    }

    while (destSz) {
	TkSizeT blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == TCL_IO_FAILURE) {
	    /* TODO: failure info... */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel read failed: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;







|









|







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
 */

static int
ReadData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    Tcl_Size destSz,
    unsigned long *crcPtr)
{
    if (pngPtr->base64Data) {
	return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr);
    } else if (pngPtr->strDataBuf) {
	return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr);
    }

    while (destSz) {
	Tcl_Size blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == TCL_IO_FAILURE) {
	    /* TODO: failure info... */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel read failed: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

	/*
	 * Check for EOF before all desired data was read.
	 */

	if (destSz && Tcl_Eof(pngPtr->channel)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "unexpected end of file", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EOF", NULL);
	    return TCL_ERROR;
	}
    }

    return TCL_OK;
}







|







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

	/*
	 * Check for EOF before all desired data was read.
	 */

	if (destSz && Tcl_Eof(pngPtr->channel)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "unexpected end of file", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EOF", NULL);
	    return TCL_ERROR;
	}
    }

    return TCL_OK;
}
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
{
    unsigned char p[4];

    if (ReadData(interp, pngPtr, p, 4, crcPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    *resultPtr = PNG_INT32(p[0], p[1], p[2], p[3]);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
{
    unsigned char p[4];

    if (ReadData(interp, pngPtr, p, 4, crcPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    *resultPtr = PNG_UINT32(p[0], p[1], p[2], p[3]);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
    }

    /*
     * Compare the read CRC to what we calculate to make sure they match.
     */

    if (calculated != chunked) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("CRC check failed", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "CRC", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}








|







758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
    }

    /*
     * Compare the read CRC to what we calculate to make sure they match.
     */

    if (calculated != chunked) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("CRC check failed", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "CRC", NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
 *----------------------------------------------------------------------
 */

static int
ReadChunkHeader(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    size_t *sizePtr,
    unsigned long *typePtr,
    unsigned long *crcPtr)
{
    unsigned long chunkType = 0;
    int chunkSz = 0;
    unsigned long crc = 0;








|







878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
 *----------------------------------------------------------------------
 */

static int
ReadChunkHeader(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tcl_Size *sizePtr,
    unsigned long *typePtr,
    unsigned long *crcPtr)
{
    unsigned long chunkType = 0;
    int chunkSz = 0;
    unsigned long crc = 0;

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
	 * maximum size for Tcl_Read, Tcl_GetByteArrayFromObj, etc.
	 */

	if (ReadData(interp, pngPtr, pc, 4, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	temp = PNG_INT32(pc[0], pc[1], pc[2], pc[3]);

	if (temp > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "chunk size is out of supported range on this architecture",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "OUTSIZE", NULL);
	    return TCL_ERROR;







|







906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
	 * maximum size for Tcl_Read, Tcl_GetByteArrayFromObj, etc.
	 */

	if (ReadData(interp, pngPtr, pc, 4, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	temp = PNG_UINT32(pc[0], pc[1], pc[2], pc[3]);

	if (temp > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "chunk size is out of supported range on this architecture",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "OUTSIZE", NULL);
	    return TCL_ERROR;
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
	    return TCL_ERROR;
	}

	/*
	 * Convert it to a host-order integer for simple comparison.
	 */

	chunkType = PNG_INT32(pc[0], pc[1], pc[2], pc[3]);

	/*
	 * Check to see if this is a known/supported chunk type. Note that the
	 * PNG specs require non-critical (i.e., ancillary) chunk types that
	 * are not recognized to be ignored, rather than be treated as an
	 * error. It does, however, recommend that an unknown critical chunk
	 * type be treated as a failure.







|







931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
	    return TCL_ERROR;
	}

	/*
	 * Convert it to a host-order integer for simple comparison.
	 */

	chunkType = PNG_UINT32(pc[0], pc[1], pc[2], pc[3]);

	/*
	 * Check to see if this is a known/supported chunk type. Note that the
	 * PNG specs require non-critical (i.e., ancillary) chunk types that
	 * are not recognized to be ignored, rather than be treated as an
	 * error. It does, however, recommend that an unknown critical chunk
	 * type be treated as a failure.
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
	    /*
	     * These chunk types are required and/or supported.
	     */

	case CHUNK_IDAT:
	case CHUNK_IEND:
	case CHUNK_IHDR:

	case CHUNK_PLTE:
	case CHUNK_tRNS:
	    break;

	    /*
	     * These chunk types are part of the standard, but are not used by
	     * this implementation (at least not yet). Note that these are all
	     * ancillary chunks (lowercase first letter).
	     */

	case CHUNK_bKGD:
	case CHUNK_cHRM:
	case CHUNK_gAMA:
	case CHUNK_hIST:
	case CHUNK_iCCP:
	case CHUNK_iTXt:
	case CHUNK_oFFs:
	case CHUNK_pCAL:
	case CHUNK_pHYs:
	case CHUNK_sBIT:
	case CHUNK_sCAL:
	case CHUNK_sPLT:
	case CHUNK_sRGB:
	case CHUNK_tEXt:
	case CHUNK_tIME:
	case CHUNK_zTXt:







>


















<







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
	    /*
	     * These chunk types are required and/or supported.
	     */

	case CHUNK_IDAT:
	case CHUNK_IEND:
	case CHUNK_IHDR:
	case CHUNK_pHYs:
	case CHUNK_PLTE:
	case CHUNK_tRNS:
	    break;

	    /*
	     * These chunk types are part of the standard, but are not used by
	     * this implementation (at least not yet). Note that these are all
	     * ancillary chunks (lowercase first letter).
	     */

	case CHUNK_bKGD:
	case CHUNK_cHRM:
	case CHUNK_gAMA:
	case CHUNK_hIST:
	case CHUNK_iCCP:
	case CHUNK_iTXt:
	case CHUNK_oFFs:
	case CHUNK_pCAL:

	case CHUNK_sBIT:
	case CHUNK_sCAL:
	case CHUNK_sPLT:
	case CHUNK_sRGB:
	case CHUNK_tEXt:
	case CHUNK_tIME:
	case CHUNK_zTXt:
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986

	default:
	    /*
	     * Unknown chunk type. If it's critical, we can't continue.
	     */

	    if (!(chunkType & PNG_CF_ANCILLARY)) {
		if (chunkType & PNG_INT32(128,128,128,128)) {
		    /*
		     * No nice ASCII conversion; shouldn't happen either, but
		     * we'll be doubly careful.
		     */

		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "encountered an unsupported critical chunk type",







|







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

	default:
	    /*
	     * Unknown chunk type. If it's critical, we can't continue.
	     */

	    if (!(chunkType & PNG_CF_ANCILLARY)) {
		if (chunkType & PNG_UINT32(128,128,128,128)) {
		    /*
		     * No nice ASCII conversion; shouldn't happen either, but
		     * we'll be doubly careful.
		     */

		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "encountered an unsupported critical chunk type",
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
	     * Check to see if the chunk type has legal bytes.
	     */

	    for (i=0 ; i<4 ; i++) {
		if ((pc[i] < 65) || (pc[i] > 122) ||
			((pc[i] > 90) && (pc[i] < 97))) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "invalid chunk type", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG",
			    "INVALID_CHUNK", NULL);
		    return TCL_ERROR;
		}
	    }

	    /*







|







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
	     * Check to see if the chunk type has legal bytes.
	     */

	    for (i=0 ; i<4 ; i++) {
		if ((pc[i] < 65) || (pc[i] > 122) ||
			((pc[i] > 90) && (pc[i] < 97))) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "invalid chunk type", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG",
			    "INVALID_CHUNK", NULL);
		    return TCL_ERROR;
		}
	    }

	    /*
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
	break;

    case PNG_COLOR_RGBA:
	pngPtr->numChannels = 4;
	if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) {
	unsupportedDepth:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "bit depth is not allowed for given color type", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_DEPTH", NULL);
	    return TCL_ERROR;
	}
	break;

    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|







1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
	break;

    case PNG_COLOR_RGBA:
	pngPtr->numChannels = 4;
	if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) {
	unsupportedDepth:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "bit depth is not allowed for given color type", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_DEPTH", NULL);
	    return TCL_ERROR;
	}
	break;

    default:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
static int
ReadIHDR(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char sigBuf[PNG_SIG_SZ];
    unsigned long chunkType;
    size_t chunkSz;
    unsigned long crc;
    unsigned long width, height;
    int mismatch;

    /*
     * Read the appropriate number of bytes for the PNG signature.
     */







|







1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
static int
ReadIHDR(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char sigBuf[PNG_SIG_SZ];
    unsigned long chunkType;
    Tcl_Size chunkSz;
    unsigned long crc;
    unsigned long width, height;
    int mismatch;

    /*
     * Read the appropriate number of bytes for the PNG signature.
     */
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
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
    mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);

    /*
     * If reading from string, reset position and try base64 decode.
     */

    if (mismatch && pngPtr->strDataBuf) {
	pngPtr->strDataBuf = TkGetByteArrayFromObj(pngPtr->objDataPtr,
		&pngPtr->strDataLen);
	pngPtr->base64Data = pngPtr->strDataBuf;

	if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);
    }

    if (mismatch) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"data stream does not have a PNG signature", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_SIG", NULL);
	return TCL_ERROR;
    }

    if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
	    &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Read in the IHDR (header) chunk for width, height, etc.
     *
     * The first chunk in the file must be the IHDR (headr) chunk.
     */

    if (chunkType != CHUNK_IHDR) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"expected IHDR chunk type", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_IHDR", NULL);
	return TCL_ERROR;
    }

    if (chunkSz != 13) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid IHDR chunk size", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IHDR", NULL);
	return TCL_ERROR;
    }

    /*
     * Read and verify the image width and height to be sure Tk can handle its
     * dimensions. The PNG specification does not permit zero-width or







|












|

















|






|







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
    mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);

    /*
     * If reading from string, reset position and try base64 decode.
     */

    if (mismatch && pngPtr->strDataBuf) {
	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;
	}

	mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);
    }

    if (mismatch) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"data stream does not have a PNG signature", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_SIG", NULL);
	return TCL_ERROR;
    }

    if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
	    &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Read in the IHDR (header) chunk for width, height, etc.
     *
     * The first chunk in the file must be the IHDR (headr) chunk.
     */

    if (chunkType != CHUNK_IHDR) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"expected IHDR chunk type", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_IHDR", NULL);
	return TCL_ERROR;
    }

    if (chunkSz != 13) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid IHDR chunk size", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IHDR", NULL);
	return TCL_ERROR;
    }

    /*
     * Read and verify the image width and height to be sure Tk can handle its
     * dimensions. The PNG specification does not permit zero-width or
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
     * This chunk is mandatory for color type 3 and forbidden for 2 and 6.
     */

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAY:
    case PNG_COLOR_GRAYALPHA:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PLTE chunk type forbidden for grayscale", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PLTE_UNEXPECTED",
		NULL);
	return TCL_ERROR;

    default:
	break;
    }

    /*
     * The palette chunk contains from 1 to 256 palette entries. Each entry
     * consists of a 3-byte RGB value. It must therefore contain a non-zero
     * multiple of 3 bytes, up to 768.
     */

    if (!chunkSz || (chunkSz > PNG_PLTE_MAXSZ) || (chunkSz % 3)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid palette chunk size", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_PLTE", NULL);
	return TCL_ERROR;
    }

    /*
     * Read the palette contents and stash them for later, possibly.
     */







|
















|







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
     * This chunk is mandatory for color type 3 and forbidden for 2 and 6.
     */

    switch (pngPtr->colorType) {
    case PNG_COLOR_GRAY:
    case PNG_COLOR_GRAYALPHA:
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PLTE chunk type forbidden for grayscale", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PLTE_UNEXPECTED",
		NULL);
	return TCL_ERROR;

    default:
	break;
    }

    /*
     * The palette chunk contains from 1 to 256 palette entries. Each entry
     * consists of a 3-byte RGB value. It must therefore contain a non-zero
     * multiple of 3 bytes, up to 768.
     */

    if (!chunkSz || (chunkSz > PNG_PLTE_MAXSZ) || (chunkSz % 3)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid palette chunk size", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_PLTE", NULL);
	return TCL_ERROR;
    }

    /*
     * Read the palette contents and stash them for later, possibly.
     */
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
    /*
     * For indexed color, there is up to one single-byte transparency value
     * per palette entry (thus a max of 256).
     */

    if (chunkSz > PNG_TRNS_MAXSZ) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid tRNS chunk size", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	return TCL_ERROR;
    }

    /*
     * Read in the raw transparency information.
     */







|







1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
    /*
     * For indexed color, there is up to one single-byte transparency value
     * per palette entry (thus a max of 256).
     */

    if (chunkSz > PNG_TRNS_MAXSZ) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid tRNS chunk size", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	return TCL_ERROR;
    }

    /*
     * Read in the raw transparency information.
     */
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
	 * The number of tRNS entries must be less than or equal to the number
	 * of PLTE entries, and consists of a single-byte alpha level for the
	 * corresponding PLTE entry.
	 */

	if (chunkSz > pngPtr->paletteLen) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "size of tRNS chunk is too large for the palette", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TRNS_SIZE", NULL);
	    return TCL_ERROR;
	}

	for (i=0 ; i<chunkSz ; i++) {
	    pngPtr->palette[i].alpha = buffer[i];
	}







|







1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
	 * The number of tRNS entries must be less than or equal to the number
	 * of PLTE entries, and consists of a single-byte alpha level for the
	 * corresponding PLTE entry.
	 */

	if (chunkSz > pngPtr->paletteLen) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "size of tRNS chunk is too large for the palette", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TRNS_SIZE", NULL);
	    return TCL_ERROR;
	}

	for (i=0 ; i<chunkSz ; i++) {
	    pngPtr->palette[i].alpha = buffer[i];
	}
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
    case PNG_COLOR_RGB:
	/*
	 * TrueColor uses a single RRGGBB triplet.
	 */

	if (chunkSz != 6) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid tRNS chunk size - must 6 bytes for RGB", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	    return TCL_ERROR;
	}

	/*
	 * According to the PNG specs, if the bit depth is less than 16, then
	 * only the lower byte is used. But the tRNS chunk still contains two







|







1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
    case PNG_COLOR_RGB:
	/*
	 * TrueColor uses a single RRGGBB triplet.
	 */

	if (chunkSz != 6) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid tRNS chunk size - must 6 bytes for RGB", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL);
	    return TCL_ERROR;
	}

	/*
	 * According to the PNG specs, if the bit depth is less than 16, then
	 * only the lower byte is used. But the tRNS chunk still contains two
1636
1637
1638
1639
1640
1641
1642














































































1643
1644
1645
1646
1647
1648
1649
	pngPtr->useTRNS = 1;
	break;
    }

    return TCL_OK;
}















































































/*
 *----------------------------------------------------------------------
 *
 * Paeth --
 *
 *	Utility function for applying the Paeth filter to a pixel. The Paeth
 *	filter is a linear function of the pixel to be filtered and the pixels







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	pngPtr->useTRNS = 1;
	break;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ReadPHYS --
 *
 *	This function reads the PHYS (physical size) chunk data from
 *	the PNG file and populates the fields in the PNGImage
 *	structure.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if an I/O error occurs or the PHYS chunk is
 *	invalid.
 *
 * Side effects:
 *	The access position in f advances.
 *
 *----------------------------------------------------------------------
 */

static int
ReadPHYS(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    int chunkSz,
    unsigned long crc)
{
    unsigned long PPUx, PPUy;
    char unitSpecifier;

    /*
     * Check chunk size equal 9 bytes
     */

    if (chunkSz != 9) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid physical chunk size", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_PHYS", NULL);
	return TCL_ERROR;
    }

    /*
     * Read the chunk data
     * 4 bytes: Pixels per unit, x axis
     * 4 bytes: Pixels per unit, y axis
     * 1 byte: unit specifier
     */

    if (ReadInt32(interp, pngPtr, &PPUx, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (ReadInt32(interp, pngPtr, &PPUy, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (ReadData(interp, pngPtr, (unsigned char *)&unitSpecifier, 1, &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if ( PPUx > 2147483647 || PPUy > 2147483647
	    || unitSpecifier > 1 ) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"invalid physical size value", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_PHYS", NULL);
	return TCL_ERROR;
    }

    if (PPUx > 0) {
	pngPtr->aspect = ((double) PPUy) / ((double) PPUx);
    }
    if (1 == unitSpecifier) {
	pngPtr->DPI = ((double) PPUx) * 0.0254;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Paeth --
 *
 *	Utility function for applying the Paeth filter to a pixel. The Paeth
 *	filter is a linear function of the pixel to be filtered and the pixels
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720

static int
UnfilterLine(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char *thisLine =
	    Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL);
    unsigned char *lastLine =
	    Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, NULL);

#define	PNG_FILTER_NONE		0
#define	PNG_FILTER_SUB		1
#define	PNG_FILTER_UP		2
#define	PNG_FILTER_AVG		3
#define	PNG_FILTER_PAETH	4








|

|







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, (Tcl_Size *)NULL);
    unsigned char *lastLine =
	    Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, (Tcl_Size *)NULL);

#define	PNG_FILTER_NONE		0
#define	PNG_FILTER_SUB		1
#define	PNG_FILTER_UP		2
#define	PNG_FILTER_AVG		3
#define	PNG_FILTER_PAETH	4

1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
    int haveBits = 0;		/* Number of bits remaining in current byte */
    unsigned char pixBits = 0;	/* Extracted bits for current channel */
    int shifts = 0;		/* Number of channels extracted from byte */
    int offset = 0;		/* Current offset into pixelPtr */
    int colStep = 1;		/* Column increment each pass */
    int pixStep = 0;		/* extra pixelPtr increment each pass */
    unsigned char lastPixel[6];
    unsigned char *p = Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL);

    p++;
    if (UnfilterLine(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (pngPtr->currentLine >= pngPtr->block.height) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|







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, (Tcl_Size *)NULL);

    p++;
    if (UnfilterLine(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (pngPtr->currentLine >= pngPtr->block.height) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
    unsigned long crc)
{
    /*
     * Process IDAT contents until there is no more in this chunk.
     */

    while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) {
	TkSizeT len1, len2;

	/*
	 * Read another block of input into the zlib stream if data remains.
	 */

	if (chunkSz) {
	    Tcl_Obj *inputObj = NULL;
	    int blockSz = PNG_MIN(chunkSz, PNG_BLOCK_SZ);
	    unsigned char *inputPtr = NULL;

	    /*
	     * Check for end of zlib stream.
	     */

	    if (Tcl_ZlibStreamEof(pngPtr->stream)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after end of zlib stream", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;
	    }

	    inputObj = Tcl_NewObj();
	    Tcl_IncrRefCount(inputObj);







|
















|







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
    unsigned long crc)
{
    /*
     * Process IDAT contents until there is no more in this chunk.
     */

    while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) {
	Tcl_Size len1, len2;

	/*
	 * Read another block of input into the zlib stream if data remains.
	 */

	if (chunkSz) {
	    Tcl_Obj *inputObj = NULL;
	    int blockSz = PNG_MIN(chunkSz, PNG_BLOCK_SZ);
	    unsigned char *inputPtr = NULL;

	    /*
	     * Check for end of zlib stream.
	     */

	    if (Tcl_ZlibStreamEof(pngPtr->stream)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after end of zlib stream", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;
	    }

	    inputObj = Tcl_NewObj();
	    Tcl_IncrRefCount(inputObj);
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163

	/*
	 * Inflate, processing each output buffer's worth as a line of pixels,
	 * until we cannot fill the buffer any more.
	 */

    getNextLine:
	TkGetByteArrayFromObj(pngPtr->thisLineObj, &len1);
	if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj,
		pngPtr->phaseSize - len1) == TCL_ERROR) {
	    return TCL_ERROR;
	}
	TkGetByteArrayFromObj(pngPtr->thisLineObj, &len2);

	if (len2 == (TkSizeT)pngPtr->phaseSize) {
	    if (pngPtr->phase > 7) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after final scan line of final phase",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;







|




|

|







2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265

	/*
	 * Inflate, processing each output buffer's worth as a line of pixels,
	 * until we cannot fill the buffer any more.
	 */

    getNextLine:
	Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len1);
	if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj,
		pngPtr->phaseSize - len1) == TCL_ERROR) {
	    return TCL_ERROR;
	}
	Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len2);

	if (len2 == (Tcl_Size)pngPtr->phaseSize) {
	    if (pngPtr->phase > 7) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after final scan line of final phase",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
     * Ensure that if we've got to the end of the compressed data, we've
     * also got to the end of the compressed stream. This sanity check is
     * enforced by most PNG readers.
     */

    if (chunkSz != 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"compressed data after stream finalize in PNG data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL);
	return TCL_ERROR;
    }

    return CheckCRC(interp, pngPtr, crc);
}








|







2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
     * Ensure that if we've got to the end of the compressed data, we've
     * also got to the end of the compressed stream. This sanity check is
     * enforced by most PNG readers.
     */

    if (chunkSz != 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"compressed data after stream finalize in PNG data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL);
	return TCL_ERROR;
    }

    return CheckCRC(interp, pngPtr, crc);
}

2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
static int
ParseFormat(
    Tcl_Interp *interp,
    Tcl_Obj *fmtObj,
    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptionsEnum {
	OPT_ALPHA
    };








|







2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
static int
ParseFormat(
    Tcl_Interp *interp,
    Tcl_Obj *fmtObj,
    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    Tcl_Size objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptionsEnum {
	OPT_ALPHA
    };

2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
	    if (Tcl_GetDoubleFromObj(interp, objv[0],
		    &pngPtr->alpha) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-alpha value must be between 0.0 and 1.0", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_ALPHA",
			NULL);
		return TCL_ERROR;
	    }
	    break;
	}
    }







|







2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
	    if (Tcl_GetDoubleFromObj(interp, objv[0],
		    &pngPtr->alpha) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-alpha value must be between 0.0 and 1.0", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_ALPHA",
			NULL);
		return TCL_ERROR;
	    }
	    break;
	}
    }
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
    PNGImage *pngPtr,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY)
{
    unsigned long chunkType;
    size_t chunkSz;
    unsigned long crc;

    /*
     * Parse the PNG signature and IHDR (header) chunk.
     */

    if (ReadIHDR(interp, pngPtr) == TCL_ERROR) {







|







2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
    PNGImage *pngPtr,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY)
{
    unsigned long chunkType;
    Tcl_Size chunkSz;
    unsigned long crc;

    /*
     * Parse the PNG signature and IHDR (header) chunk.
     */

    if (ReadIHDR(interp, pngPtr) == TCL_ERROR) {
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
     * PLTE is mandatory for color type 3 and forbidden for 2 and 6
     */

    if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
	    &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }
























    if (CHUNK_PLTE == chunkType) {
	/*
	 * Finish parsing the PLTE chunk.
	 */

	if (ReadPLTE(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Begin the next chunk.
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    } else if (PNG_COLOR_PLTE == pngPtr->colorType) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PLTE chunk required for indexed color", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_PLTE", NULL);
	return TCL_ERROR;
    }

    /*
     * The next chunk may be a tRNS (palette transparency) chunk, depending on
     * the color type. It must come after the PLTE chunk and before the IDAT







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|







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
     * PLTE is mandatory for color type 3 and forbidden for 2 and 6
     */

    if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
	    &crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Physical header may be present here so try to parse it
     */

    if (CHUNK_pHYs == chunkType) {
	/*
	 * Finish parsing the PHYS chunk.
	 */

	if (ReadPHYS(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Begin the next chunk.
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }

    if (CHUNK_PLTE == chunkType) {
	/*
	 * Finish parsing the PLTE chunk.
	 */

	if (ReadPLTE(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Begin the next chunk.
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    } else if (PNG_COLOR_PLTE == pngPtr->colorType) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PLTE chunk required for indexed color", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_PLTE", NULL);
	return TCL_ERROR;
    }

    /*
     * The next chunk may be a tRNS (palette transparency) chunk, depending on
     * the color type. It must come after the PLTE chunk and before the IDAT
2460
2461
2462
2463
2464
2465
2466























2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }
























    /*
     * Other ancillary chunk types could appear here, but for now we're only
     * interested in IDAT. The others should have been skipped.
     */

    if (chunkType != CHUNK_IDAT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"at least one IDAT chunk is required", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_IDAT", NULL);
	return TCL_ERROR;
    }

    /*
     * Expand the photo size (if not set by the user) to provide enough space
     * for the image being parsed. It does not matter if width or height wrap







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|







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
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }

    /*
     * Physical header may be present here so try to parse it
     */

    if (CHUNK_pHYs == chunkType) {
	/*
	 * Finish parsing the PHYS chunk.
	 */

	if (ReadPHYS(interp, pngPtr, chunkSz, crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	/*
	 * Begin the next chunk.
	 */

	if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType,
		&crc) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }

    /*
     * Other ancillary chunk types could appear here, but for now we're only
     * interested in IDAT. The others should have been skipped.
     */

    if (chunkType != CHUNK_IDAT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"at least one IDAT chunk is required", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_IDAT", NULL);
	return TCL_ERROR;
    }

    /*
     * Expand the photo size (if not set by the user) to provide enough space
     * for the image being parsed. It does not matter if width or height wrap
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
    Tcl_IncrRefCount(pngPtr->lastLineObj);
    pngPtr->thisLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->thisLineObj);

    pngPtr->block.pixelPtr = (unsigned char *)attemptckalloc(pngPtr->blockLen);
    if (!pngPtr->block.pixelPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"memory allocation failed", -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	return TCL_ERROR;
    }

    /*
     * Determine size of the first phase if interlaced. Phase size should
     * always be <= line size, so probably not necessary to check for







|







2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
    Tcl_IncrRefCount(pngPtr->lastLineObj);
    pngPtr->thisLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->thisLineObj);

    pngPtr->block.pixelPtr = (unsigned char *)attemptckalloc(pngPtr->blockLen);
    if (!pngPtr->block.pixelPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"memory allocation failed", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	return TCL_ERROR;
    }

    /*
     * Determine size of the first phase if interlaced. Phase size should
     * always be <= line size, so probably not necessary to check for
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
     * Ensure that we've got to the end of the compressed stream now that
     * there are no more IDAT segments. This sanity check is enforced by most
     * PNG readers.
     */

    if (!Tcl_ZlibStreamEof(pngPtr->stream)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unfinalized data stream in PNG data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL);
	return TCL_ERROR;
    }

    /*
     * Now skip the remaining chunks which we're also not interested in.
     */







|







2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
     * Ensure that we've got to the end of the compressed stream now that
     * there are no more IDAT segments. This sanity check is enforced by most
     * PNG readers.
     */

    if (!Tcl_ZlibStreamEof(pngPtr->stream)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unfinalized data stream in PNG data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL);
	return TCL_ERROR;
    }

    /*
     * Now skip the remaining chunks which we're also not interested in.
     */
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

    /*
     * Got the IEND (end of image) chunk. Do some final checks...
     */

    if (chunkSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"IEND chunk contents must be empty", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL);
	return TCL_ERROR;
    }

    /*
     * Check the CRC on the IEND chunk.
     */

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * TODO: verify that nothing else comes after the IEND chunk, or do we
     * really care?
     */

#if 0
    if (ReadData(interp, pngPtr, &c, 1, NULL) != TCL_ERROR) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"extra data following IEND chunk", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL);
	return TCL_ERROR;
    }
#endif

    /*
     * Apply overall image alpha if specified.







|




















|







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

    /*
     * Got the IEND (end of image) chunk. Do some final checks...
     */

    if (chunkSz) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"IEND chunk contents must be empty", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL);
	return TCL_ERROR;
    }

    /*
     * Check the CRC on the IEND chunk.
     */

    if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * TODO: verify that nothing else comes after the IEND chunk, or do we
     * really care?
     */

#if 0
    if (ReadData(interp, pngPtr, &c, 1, NULL) != TCL_ERROR) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"extra data following IEND chunk", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL);
	return TCL_ERROR;
    }
#endif

    /*
     * Apply overall image alpha if specified.
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
 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchPNG(

    Tcl_Channel chan,
    const char *fileName,

    Tcl_Obj *fmtObj,
    int *widthPtr,
    int *heightPtr,


    Tcl_Interp *interp)
{
    PNGImage png;
    int match = 0;
    (void)fileName;
    (void)fmtObj;

    InitPNGImage(NULL, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;







>
|
|
>
|
|
<
>
>
|



<
<







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
 *	The access position in f may change.
 *
 *----------------------------------------------------------------------
 */

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 *),	/* 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;
    int match = 0;



    InitPNGImage(NULL, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719

2720
2721
2722


2723
2724

2725
2726

2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740












2741
2742
2743
2744
2745
2746
2747
 *	image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
FileReadPNG(
    Tcl_Interp *interp,
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *fmtObj,

    Tk_PhotoHandle imageHandle,
    int destX,
    int destY,


    int width,
    int height,

    int srcX,
    int srcY)

{
    PNGImage png;
    int result = TCL_ERROR;
    (void)fileName;
    (void)width;
    (void)height;
    (void)srcX;
    (void)srcY;

    result = InitPNGImage(interp, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY);
    }













    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------







|
|
|
|
>
|
|
<
>
>
|
|
>
|
|
>



<
<
<
<
<






>
>
>
>
>
>
>
>
>
>
>
>







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
 *	image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
FileReadPNG(
    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_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
				 * 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 */
{
    PNGImage png;
    int result = TCL_ERROR;






    result = InitPNGImage(interp, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY);
    }

    if (TCL_OK == result && metadataOutObj != NULL && png.DPI != -1) {
	result = Tcl_DictObjPut(NULL, metadataOutObj,
		Tcl_NewStringObj("DPI",-1),
		Tcl_NewDoubleObj(png.DPI));
    }

    if (TCL_OK == result && metadataOutObj != NULL && png.aspect != -1) {
	result = Tcl_DictObjPut(NULL, metadataOutObj,
		Tcl_NewStringObj("aspect",-1),
		Tcl_NewDoubleObj(png.aspect));
    }

    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------
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
 *	The size of the image is placed in widthPre and heightPtr.
 *
 *----------------------------------------------------------------------
 */

static int
StringMatchPNG(

    Tcl_Obj *pObjData,

    Tcl_Obj *fmtObj,
    int *widthPtr,
    int *heightPtr,
    Tcl_Interp *interp)
{
    PNGImage png;
    int match = 0;
    (void)fmtObj;

    InitPNGImage(NULL, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE);

    png.strDataBuf = TkGetByteArrayFromObj(pObjData, &png.strDataLen);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;
    }








>
|
>
|
|
|
|



<



|







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
 *	The size of the image is placed in widthPre and heightPtr.
 *
 *----------------------------------------------------------------------
 */

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 *),	/* 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 = Tcl_GetByteArrayFromObj(pObjData, &png.strDataLen);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;
    }

2803
2804
2805
2806
2807
2808
2809
2810
2811
2812

2813
2814
2815
2816
2817
2818
2819

2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833












2834
2835
2836
2837
2838
2839
2840
 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
StringReadPNG(
    Tcl_Interp *interp,
    Tcl_Obj *pObjData,
    Tcl_Obj *fmtObj,

    Tk_PhotoHandle imageHandle,
    int destX,
    int destY,
    int width,
    int height,
    int srcX,
    int srcY)

{
    PNGImage png;
    int result = TCL_ERROR;
    (void)width;
    (void)height;
    (void)srcX;
    (void)srcY;

    result = InitPNGImage(interp, &png, NULL, pObjData,
	    TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY);
    }













    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------







|
|
|
>
|
|
|
|
<
|
|
>



<
<
<
<







>
>
>
>
>
>
>
>
>
>
>
>







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
 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
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),

    TCL_UNUSED(int),
    TCL_UNUSED(int),
    Tcl_Obj *metadataOutObj)	/* metadata return dict, may be NULL */
{
    PNGImage png;
    int result = TCL_ERROR;





    result = InitPNGImage(interp, &png, NULL, pObjData,
	    TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY);
    }

    if (TCL_OK == result && metadataOutObj != NULL && png.DPI != -1) {
	result = Tcl_DictObjPut(NULL, metadataOutObj,
		Tcl_NewStringObj("DPI",-1),
		Tcl_NewDoubleObj(png.DPI));
    }

    if (TCL_OK == result && metadataOutObj != NULL && png.aspect != -1) {
	result = Tcl_DictObjPut(NULL, metadataOutObj,
		Tcl_NewStringObj("aspect",-1),
		Tcl_NewDoubleObj(png.aspect));
    }

    CleanupPNGImage(&png);
    return result;
}

/*
 *----------------------------------------------------------------------
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
 */

static int
WriteData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    const unsigned char *srcPtr,
    size_t srcSz,
    unsigned long *crcPtr)
{
    if (!srcPtr || !srcSz) {
	return TCL_OK;
    }

    if (crcPtr) {
	*crcPtr = Tcl_ZlibCRC32(*crcPtr, srcPtr, srcSz);
    }

    /*
     * TODO: is Tcl_AppendObjToObj faster here? i.e., does Tcl join the
     * objects immediately or store them in a multi-object rep?
     */

    if (pngPtr->objDataPtr) {
	TkSizeT objSz;
	unsigned char *destPtr;

	TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz + srcSz > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "image too large to store completely in byte array", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	    return TCL_ERROR;
	}

	destPtr = Tcl_SetByteArrayLength(pngPtr->objDataPtr, objSz + srcSz);

	if (!destPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "memory allocation failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    return TCL_ERROR;
	}

	memcpy(destPtr+objSz, srcPtr, srcSz);
    } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|


|













|


|



|








|







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
 */

static int
WriteData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    const unsigned char *srcPtr,
    Tcl_Size srcSz,
    unsigned long *crcPtr)
{
    if (!srcPtr || srcSz <= 0) {
	return TCL_OK;
    }

    if (crcPtr) {
	*crcPtr = Tcl_ZlibCRC32(*crcPtr, srcPtr, srcSz);
    }

    /*
     * TODO: is Tcl_AppendObjToObj faster here? i.e., does Tcl join the
     * objects immediately or store them in a multi-object rep?
     */

    if (pngPtr->objDataPtr) {
	Tcl_Size objSz;
	unsigned char *destPtr;

	Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz + srcSz > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "image too large to store completely in byte array", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	    return TCL_ERROR;
	}

	destPtr = Tcl_SetByteArrayLength(pngPtr->objDataPtr, objSz + srcSz);

	if (!destPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "memory allocation failed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    return TCL_ERROR;
	}

	memcpy(destPtr+objSz, srcPtr, srcSz);
    } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
2914
2915
2916
2917
2918
2919
2920




























2921
2922
2923
2924
2925
2926
2927
{
    return WriteData(interp, pngPtr, &c, 1, crcPtr);
}

/*
 *----------------------------------------------------------------------
 *




























 * WriteInt32 --
 *
 *	This function writes a 32-bit integer value out to the PNG image as
 *	four bytes in network byte order.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
{
    return WriteData(interp, pngPtr, &c, 1, crcPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * LongToInt32 --
 *
 *	This function transforms to a 32-bit integer value as
 *	four bytes in network byte order.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Buffer will be modified.
 *
 *----------------------------------------------------------------------
 */

static inline void
LongToInt32(
    unsigned long l,
    unsigned char *pc)
{
    pc[0] = (unsigned char) ((l & 0xff000000) >> 24);
    pc[1] = (unsigned char) ((l & 0x00ff0000) >> 16);
    pc[2] = (unsigned char) ((l & 0x0000ff00) >> 8);
    pc[3] = (unsigned char) ((l & 0x000000ff) >> 0);
}

/*
 *----------------------------------------------------------------------
 *
 * WriteInt32 --
 *
 *	This function writes a 32-bit integer value out to the PNG image as
 *	four bytes in network byte order.
 *
 * Results:
 *	TCL_OK, or TCL_ERROR if the write fails.
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
WriteInt32(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long l,
    unsigned long *crcPtr)
{
    unsigned char pc[4];

    pc[0] = (unsigned char) ((l & 0xff000000) >> 24);
    pc[1] = (unsigned char) ((l & 0x00ff0000) >> 16);
    pc[2] = (unsigned char) ((l & 0x0000ff00) >> 8);
    pc[3] = (unsigned char) ((l & 0x000000ff) >> 0);

    return WriteData(interp, pngPtr, pc, 4, crcPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * WriteChunk --







|
<
<
<
<
<







3134
3135
3136
3137
3138
3139
3140
3141





3142
3143
3144
3145
3146
3147
3148
WriteInt32(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long l,
    unsigned long *crcPtr)
{
    unsigned char pc[4];
    LongToInt32(l,pc);





    return WriteData(interp, pngPtr, pc, 4, crcPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * WriteChunk --
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982

static inline int
WriteChunk(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long chunkType,
    const unsigned char *dataPtr,
    size_t dataSize)
{
    unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
    int result = TCL_OK;

    /*
     * Write the length field for the chunk.
     */







|







3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175

static inline int
WriteChunk(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long chunkType,
    const unsigned char *dataPtr,
    Tcl_Size dataSize)
{
    unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
    int result = TCL_OK;

    /*
     * Write the length field for the chunk.
     */
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tk_PhotoImageBlock *blockPtr)
{
    int rowNum, flush = TCL_ZLIB_NO_FLUSH, result;
    Tcl_Obj *outputObj;
    unsigned char *outputBytes;
    TkSizeT outputSize;

    /*
     * Filter and compress each row one at a time.
     */

    for (rowNum=0 ; rowNum < blockPtr->height ; rowNum++) {
	int colNum;







|







3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tk_PhotoImageBlock *blockPtr)
{
    int rowNum, flush = TCL_ZLIB_NO_FLUSH, result;
    Tcl_Obj *outputObj;
    unsigned char *outputBytes;
    Tcl_Size outputSize;

    /*
     * Filter and compress each row one at a time.
     */

    for (rowNum=0 ; rowNum < blockPtr->height ; rowNum++) {
	int colNum;
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225

	if (rowNum + 1 == blockPtr->height) {
	    flush = TCL_ZLIB_FINALIZE;
	}
	if (Tcl_ZlibStreamPut(pngPtr->stream, pngPtr->thisLineObj,
		flush) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "deflate() returned error", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DEFLATE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Swap line buffers to keep the last around for filtering next.
	 */







|







3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418

	if (rowNum + 1 == blockPtr->height) {
	    flush = TCL_ZLIB_FINALIZE;
	}
	if (Tcl_ZlibStreamPut(pngPtr->stream, pngPtr->thisLineObj,
		flush) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "deflate() returned error", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DEFLATE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Swap line buffers to keep the last around for filtering next.
	 */
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
    }

    /*
     * Now get the compressed data and write it as one big IDAT chunk.
     */

    outputObj = Tcl_NewObj();
    (void) Tcl_ZlibStreamGet(pngPtr->stream, outputObj, -1);
    outputBytes = TkGetByteArrayFromObj(outputObj, &outputSize);
    result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize);
    Tcl_DecrRefCount(outputObj);
    return result;
}

/*
 *----------------------------------------------------------------------







|
|







3426
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, TCL_INDEX_NONE);
    outputBytes = Tcl_GetByteArrayFromObj(outputObj, &outputSize);
    result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize);
    Tcl_DecrRefCount(outputObj);
    return result;
}

/*
 *----------------------------------------------------------------------
3260
3261
3262
3263
3264
3265
3266
3267

3268
3269
3270
3271
3272
3273
3274
 *
 *----------------------------------------------------------------------
 */

static int
WriteExtraChunks(
    Tcl_Interp *interp,
    PNGImage *pngPtr)

{
    static const unsigned char sBIT_contents[] = {
	8, 8, 8, 8
    };
    int sBIT_length = 4;
    Tcl_DString buf;








|
>







3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
 *
 *----------------------------------------------------------------------
 */

static int
WriteExtraChunks(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tcl_Obj *metadataInObj)
{
    static const unsigned char sBIT_contents[] = {
	8, 8, 8, 8
    };
    int sBIT_length = 4;
    Tcl_DString buf;

3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318









































































3319
3320
3321
3322
3323
3324
3325
     * Say that it is Tk that made the PNG. Note that we *need* the NUL at the
     * end of "Software" to be transferred; do *not* change the length
     * parameter to -1 there!
     */

    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, "Software", 9);
    Tcl_DStringAppend(&buf, "Tk Toolkit v", -1);
    Tcl_DStringAppend(&buf, TK_PATCH_LEVEL, -1);
    if (WriteChunk(interp, pngPtr, CHUNK_tEXt,
	    (unsigned char *) Tcl_DStringValue(&buf),
	    Tcl_DStringLength(&buf)) != TCL_OK) {
	Tcl_DStringFree(&buf);
	return TCL_ERROR;
    }
    Tcl_DStringFree(&buf);










































































    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * EncodePNG --







|
|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
     * Say that it is Tk that made the PNG. Note that we *need* the NUL at the
     * end of "Software" to be transferred; do *not* change the length
     * parameter to -1 there!
     */

    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, "Software", 9);
    Tcl_DStringAppend(&buf, "Tk Toolkit v", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, TK_PATCH_LEVEL, TCL_INDEX_NONE);
    if (WriteChunk(interp, pngPtr, CHUNK_tEXt,
	    (unsigned char *) Tcl_DStringValue(&buf),
	    Tcl_DStringLength(&buf)) != TCL_OK) {
	Tcl_DStringFree(&buf);
	return TCL_ERROR;
    }
    Tcl_DStringFree(&buf);

    /*
     * Add a pHYs chunk if there is metadata for DPI and/or aspect
     * aspect = PPUy / PPUx
     * DPI = PPUx * 0.0254
     * 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) {

	Tcl_Obj *aspectObj, *DPIObj;
	double aspectValue=-1, DPIValue=-1;
	unsigned long PPUx = 65536, PPUy = 65536;
	char unitSpecifier;

	if (TCL_ERROR == Tcl_DictObjGet(interp, metadataInObj,
		Tcl_NewStringObj("aspect",-1),
		&aspectObj) ||
	    TCL_ERROR == Tcl_DictObjGet(interp, metadataInObj,
		Tcl_NewStringObj("DPI",-1),
		&DPIObj) ) {
	    return TCL_ERROR;
	}
	if (DPIObj != NULL) {
	    if (TCL_ERROR == Tcl_GetDoubleFromObj(interp, DPIObj, &DPIValue))
	    {
		return TCL_ERROR;
	    }
	    PPUx = (unsigned long)floor(DPIValue / 0.0254+0.5);
	    if (aspectObj == NULL) {
		PPUy = PPUx;
	    }
	    unitSpecifier = 1;
	}
	if (aspectObj != NULL) {
	    if (TCL_ERROR == Tcl_GetDoubleFromObj(interp, aspectObj,
		    &aspectValue)) {
		return TCL_ERROR;
	    }

	    /*
	     * aspect = PPUy / PPUx
	     */

	    if (DPIObj == NULL) {
		unitSpecifier = 0;
		PPUx = 65536;
		PPUy = (unsigned long)floor(65536.0 * aspectValue+0.5);
	    } else {
		PPUy = (unsigned long)floor(DPIValue * aspectValue / 0.0254+0.5);
	    }
	}
	if (DPIObj != NULL || aspectObj != NULL) {
	    unsigned char buffer[9];

	    if ( PPUx > 2147483647 || PPUy > 2147483647 ) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"DPI or aspect out of range", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PHYS", NULL);
		return TCL_ERROR;
	    }

	    LongToInt32(PPUx, buffer);
	    LongToInt32(PPUy, buffer+4);
	    buffer[8] = unitSpecifier;
	    if (WriteChunk(interp, pngPtr, CHUNK_pHYs, buffer, 9)
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * EncodePNG --
3337
3338
3339
3340
3341
3342
3343
3344

3345
3346
3347
3348
3349
3350
3351
 *----------------------------------------------------------------------
 */

static int
EncodePNG(
    Tcl_Interp *interp,
    Tk_PhotoImageBlock *blockPtr,
    PNGImage *pngPtr)

{
    int greenOffset, blueOffset, alphaOffset;

    /*
     * Determine appropriate color type based on color usage (e.g., only red
     * and maybe alpha channel = grayscale).
     *







|
>







3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
 *----------------------------------------------------------------------
 */

static int
EncodePNG(
    Tcl_Interp *interp,
    Tk_PhotoImageBlock *blockPtr,
    PNGImage *pngPtr,
    Tcl_Obj *metadataInObj)
{
    int greenOffset, blueOffset, alphaOffset;

    /*
     * Determine appropriate color type based on color usage (e.g., only red
     * and maybe alpha channel = grayscale).
     *
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401

    pngPtr->lineSize = 1 + (pngPtr->bytesPerPixel * blockPtr->width);
    pngPtr->blockLen = pngPtr->lineSize * blockPtr->height;

    if ((blockPtr->width > (INT_MAX - 1) / (pngPtr->bytesPerPixel)) ||
	    (blockPtr->height > INT_MAX / pngPtr->lineSize)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image is too large to encode pixel data", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	return TCL_ERROR;
    }

    pngPtr->lastLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->lastLineObj);
    pngPtr->thisLineObj = Tcl_NewObj();







|







3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669

    pngPtr->lineSize = 1 + (pngPtr->bytesPerPixel * blockPtr->width);
    pngPtr->blockLen = pngPtr->lineSize * blockPtr->height;

    if ((blockPtr->width > (INT_MAX - 1) / (pngPtr->bytesPerPixel)) ||
	    (blockPtr->height > INT_MAX / pngPtr->lineSize)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"image is too large to encode pixel data", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	return TCL_ERROR;
    }

    pngPtr->lastLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->lastLineObj);
    pngPtr->thisLineObj = Tcl_NewObj();
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
    }

    /*
     * Write out the extra chunks containing metadata that is of interest to
     * other programs more than us.
     */

    if (WriteExtraChunks(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Write out the image pixels in the IDAT (data) chunk.
     */








|







3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
    }

    /*
     * Write out the extra chunks containing metadata that is of interest to
     * other programs more than us.
     */

    if (WriteExtraChunks(interp, pngPtr, metadataInObj) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Write out the image pixels in the IDAT (data) chunk.
     */

3461
3462
3463
3464
3465
3466
3467

3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
 *----------------------------------------------------------------------
 */

static int
FileWritePNG(
    Tcl_Interp *interp,
    const char *filename,

    Tcl_Obj *fmtObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    PNGImage png;
    int result = TCL_ERROR;
    (void)fmtObj;

    /*
     * Open a Tcl file channel where the image data will be stored. Tk ought
     * to take care of this, and just provide a channel, but it doesn't.
     */

    chan = Tcl_OpenFileChannel(interp, filename, "w", 0644);







>
|





<







3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742

3743
3744
3745
3746
3747
3748
3749
 *----------------------------------------------------------------------
 */

static int
FileWritePNG(
    Tcl_Interp *interp,
    const char *filename,
    TCL_UNUSED(Tcl_Obj *),
    Tcl_Obj *metadataInObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    PNGImage png;
    int result = TCL_ERROR;


    /*
     * Open a Tcl file channel where the image data will be stored. Tk ought
     * to take care of this, and just provide a channel, but it doesn't.
     */

    chan = Tcl_OpenFileChannel(interp, filename, "w", 0644);
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
	goto cleanup;
    }

    /*
     * Write the raw PNG data out to the file.
     */

    result = EncodePNG(interp, blockPtr, &png);

  cleanup:
    Tcl_Close(interp, chan);
    CleanupPNGImage(&png);
    return result;
}








|







3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
	goto cleanup;
    }

    /*
     * Write the raw PNG data out to the file.
     */

    result = EncodePNG(interp, blockPtr, &png, metadataInObj);

  cleanup:
    Tcl_Close(interp, chan);
    CleanupPNGImage(&png);
    return result;
}

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
 *
 *----------------------------------------------------------------------
 */

static int
StringWritePNG(
    Tcl_Interp *interp,

    Tcl_Obj *fmtObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Obj *resultObj = Tcl_NewObj();
    PNGImage png;
    int result = TCL_ERROR;
    (void)fmtObj;

    /*
     * Initalize PNGImage instance for encoding.
     */

    if (InitPNGImage(interp, &png, NULL, resultObj,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data into the prepared Tcl_Obj buffer. Set the result
     * back to the interpreter if successful.
     */

    result = EncodePNG(interp, blockPtr, &png);

    if (TCL_OK == result) {
	Tcl_SetObjResult(interp, png.objDataPtr);
    }

  cleanup:
    CleanupPNGImage(&png);







>
|





<















|







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
 *
 *----------------------------------------------------------------------
 */

static int
StringWritePNG(
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Obj *),
    Tcl_Obj *metadataInObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Obj *resultObj = Tcl_NewObj();
    PNGImage png;
    int result = TCL_ERROR;


    /*
     * Initalize PNGImage instance for encoding.
     */

    if (InitPNGImage(interp, &png, NULL, resultObj,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data into the prepared Tcl_Obj buffer. Set the result
     * back to the interpreter if successful.
     */

    result = EncodePNG(interp, blockPtr, &png, metadataInObj);

    if (TCL_OK == result) {
	Tcl_SetObjResult(interp, png.objDataPtr);
    }

  cleanup:
    CleanupPNGImage(&png);

Changes to generic/tkImgPPM.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
/*
 * 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.
 *
 * 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"





/*
 * The maximum amount of memory to allocate for data read from the file. If we
 * need more than this, we do it in pieces.
 */

#define MAX_MEMORY	10000		/* don't allocate > 10KB */





|
|










>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 * tkImgPPM.c --
 *
 *	A photo image file handler for PPM (Portable PixMap) files.
 *
 * 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.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The maximum amount of memory to allocate for data read from the file. If we
 * need more than this, we do it in pieces.
 */

#define MAX_MEMORY	10000		/* don't allocate > 10KB */
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);
    }

    nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch;
    if (nLines > height) {
	nLines = height;
    }
    if (nLines <= 0) {







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

    if (Tk_PhotoExpand(interp, imageHandle,
	    destX + width, destY + height) != TCL_OK) {
	return TCL_ERROR;
    }

    if (srcY > 0) {
	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) {
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
	    for (p = pixelPtr; count > 0; count--, p++) {
		*p = (((int) *p) * 255)/maxIntensity;
	    }
	} else if (maxIntensity > 0x00ff) {
	    unsigned char *p;
	    unsigned int value;

	    for (p = pixelPtr; count > 0; count--, p += 2) {
		value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
	    for (p = pixelPtr; count > 0; count--, p++) {
		*p = (((int) *p) * 255)/maxIntensity;
	    }
	} else if (maxIntensity > 0x00ff) {
	    unsigned char *p;
	    unsigned int value;

	    for (p = pixelPtr; count > 0; count -= 2, p += 2) {
		value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
    }
    if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    Tcl_Write(chan, header, -1);

    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {







|
|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    }
    if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    snprintf(header, sizeof(header), "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    Tcl_Write(chan, header, TCL_INDEX_NONE);

    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;

    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);

    /*
     * Construct a byte array of the right size with the header and
     * get a pointer to the data part of it.
     */

    size = strlen(header);







|







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;

    snprintf(header, sizeof(header), "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);

    /*
     * Construct a byte array of the right size with the header and
     * get a pointer to the data part of it.
     */

    size = strlen(header);
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
    unsigned char *pixelPtr, *dataBuffer;
    Tk_PhotoImageBlock block;

    type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight,
	    &maxIntensity, &dataBuffer, &dataSize);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't read raw PPM header from string", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PPM image data has dimension(s) <= 0", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
	return TCL_ERROR;
    }
    if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"PPM image data has bad maximum intensity value %d",
		maxIntensity));







|





|







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    unsigned char *pixelPtr, *dataBuffer;
    Tk_PhotoImageBlock block;

    type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight,
	    &maxIntensity, &dataBuffer, &dataSize);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't read raw PPM header from string", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"PPM image data has dimension(s) <= 0", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
	return TCL_ERROR;
    }
    if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"PPM image data has bad maximum intensity value %d",
		maxIntensity));
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
    if (maxIntensity == 0x00ff) {
	/*
	 * We have all the data in memory, so write everything in one go.
	 */

	if (block.pitch*height > dataSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "truncated PPM data", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
	    return TCL_ERROR;
	}
	block.pixelPtr = dataBuffer + srcX * block.pixelSize;
	block.height = height;
	return Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET);







|







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
    if (maxIntensity == 0x00ff) {
	/*
	 * We have all the data in memory, so write everything in one go.
	 */

	if (block.pitch*height > dataSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "truncated PPM data", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
	    return TCL_ERROR;
	}
	block.pixelPtr = dataBuffer + srcX * block.pixelSize;
	block.height = height;
	return Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET);
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
	if (nLines > h) {
	    nLines = h;
	    nBytes = nLines * block.pitch;
	}
	if (dataSize < nBytes) {
	    ckfree(pixelPtr);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "truncated PPM data", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
		*p = (((int) *dataBuffer) * 255)/maxIntensity;
	    }
	} else {
	    unsigned int value;

	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2) {
		value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	dataSize -= nBytes;
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,







|










|
|







593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
	if (nLines > h) {
	    nLines = h;
	    nBytes = nLines * block.pitch;
	}
	if (dataSize < nBytes) {
	    ckfree(pixelPtr);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "truncated PPM data", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
	    return TCL_ERROR;
	}
	if (maxIntensity < 0x00ff) {
	    for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
		*p = (((int) *dataBuffer) * 255)/maxIntensity;
	    }
	} else {
	    unsigned int value;

	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2, dataBuffer += 2) {
		value = ((unsigned int)dataBuffer[0]) * 256 + ((unsigned int)dataBuffer[1]);
		value = value * 255 / maxIntensity;
		p[0] = p[1] = (unsigned char) value;
	    }
	}
	dataSize -= nBytes;
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
				 * is stored here. */
    unsigned char **dataBufferPtr,
    int *dataSizePtr)
{
#define BUFFER_SIZE 1000
    char buffer[BUFFER_SIZE], c;
    int i, numFields, type = 0;
    TkSizeT dataSize;
    unsigned char *dataBuffer;

    dataBuffer = TkGetByteArrayFromObj(dataPtr, &dataSize);

    /*
     * Read 4 space-separated fields from the string, ignoring comments (any
     * line that starts with "#").
     */

    if (dataSize-- < 1) {







|


|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
				 * is stored here. */
    unsigned char **dataBufferPtr,
    int *dataSizePtr)
{
#define BUFFER_SIZE 1000
    char buffer[BUFFER_SIZE], c;
    int i, numFields, type = 0;
    Tcl_Size dataSize;
    unsigned char *dataBuffer;

    dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize);

    /*
     * Read 4 space-separated fields from the string, ignoring comments (any
     * line that starts with "#").
     */

    if (dataSize-- < 1) {

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * tkImgPhInstance.c --
 *
 *	Implements the rendering of images of type "photo" for Tk. Photo
 *	images are stored in full color (32 bits per pixel including alpha
 *	channel) and displayed using dithering if necessary.
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2008 Donal K. Fellows
 * Copyright (c) 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"
#include "tkPort.h"





/*
 * Declaration for internal Xlib function used here:
 */
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
#ifdef __cplusplus
extern "C" {
#endif
extern int		_XInitImageFuncPtrs(XImage *image);
#ifdef __cplusplus
}
#endif
#endif

/*
 * Forward declarations
 */

#ifndef TKPUTIMAGE_CAN_BLEND
static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);
#endif
static int		IsValidPalette(PhotoInstance *instancePtr,
			    const char *palette);
static int		CountBits(unsigned mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(ClientData clientData);
static int		ReclaimColors(ColorTableId *id, int numColors);

/*
 * Hash table used to hash from (display, colormap, palette, gamma) to
 * ColorTable address.
 */








|
|
|
|











>
>
>
>


















|









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * 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 © 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"
#include "tkPort.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Declaration for internal Xlib function used here:
 */
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
#ifdef __cplusplus
extern "C" {
#endif
extern int		_XInitImageFuncPtrs(XImage *image);
#ifdef __cplusplus
}
#endif
#endif

/*
 * Forward declarations
 */

#ifndef TK_CAN_RENDER_RGBA
static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);
#endif
static int		IsValidPalette(PhotoInstance *instancePtr,
			    const char *palette);
static int		CountBits(unsigned mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(void *clientData);
static int		ReclaimColors(ColorTableId *id, int numColors);

/*
 * Hash table used to hash from (display, colormap, palette, gamma) to
 * ColorTable address.
 */

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227



228
229
230
231
232
233
234
 *----------------------------------------------------------------------
 */

ClientData
TkImgPhotoGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData modelData)	/* Pointer to our model structure for the
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;
    Colormap colormap;
    int mono, nRed, nGreen, nBlue, numVisuals;
    XVisualInfo visualInfo, *visInfoPtr;
    char buf[TCL_INTEGER_SPACE * 3];
    XColor *white, *black;
    XGCValues gcValues;




    /*
     * Table of "best" choices for palette for PseudoColor displays with
     * between 3 and 15 bits/pixel.
     */

    static const int paletteChoice[13][3] = {







|










>
>
>







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
 *----------------------------------------------------------------------
 */

ClientData
TkImgPhotoGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    void *modelData)	/* Pointer to our model structure for the
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;
    Colormap colormap;
    int mono, nRed, nGreen, nBlue, numVisuals;
    XVisualInfo visualInfo, *visInfoPtr;
    char buf[TCL_INTEGER_SPACE * 3];
    XColor *white, *black;
    XGCValues gcValues;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    int gcmask;
#endif

    /*
     * Table of "best" choices for palette for PseudoColor displays with
     * between 3 and 15 bits/pixel.
     */

    static const int paletteChoice[13][3] = {
253
254
255
256
257
258
259
260




261
262
263
264
265
266
267
     * colormap. If so then just re-use it.
     */

    colormap = Tk_Colormap(tkwin);
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if ((colormap == instancePtr->colormap)
		&& (Tk_Display(tkwin) == instancePtr->display)) {




	    /*
	     * Re-use this instance.
	     */

	    if (instancePtr->refCount == 0) {
		/*
		 * We are resurrecting this instance.







|
>
>
>
>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
     * colormap. If so then just re-use it.
     */

    colormap = Tk_Colormap(tkwin);
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if ((colormap == instancePtr->colormap)
	    && (Tk_Display(tkwin) == instancePtr->display)
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
	    && (Tk_Visual(tkwin) == instancePtr->visualInfo.visual)
#endif
	    ) {
	    /*
	     * Re-use this instance.
	     */

	    if (instancePtr->refCount == 0) {
		/*
		 * We are resurrecting this instance.
310
311
312
313
314
315
316




317
318
319
320
321
322
323








324
325
326
327
328
329
330
	Tcl_Panic("TkImgPhotoGet couldn't find visual for window");
    }

    nRed = 2;
    nGreen = nBlue = 0;
    mono = 1;
    instancePtr->visualInfo = *visInfoPtr;




    switch (visInfoPtr->c_class) {
    case DirectColor:
    case TrueColor:
	nRed = 1 << CountBits(visInfoPtr->red_mask);
	nGreen = 1 << CountBits(visInfoPtr->green_mask);
	nBlue = 1 << CountBits(visInfoPtr->blue_mask);
	mono = 0;








	break;
    case PseudoColor:
    case StaticColor:
	if (visInfoPtr->depth > 15) {
	    nRed = 32;
	    nGreen = 32;
	    nBlue = 32;







>
>
>
>







>
>
>
>
>
>
>
>







321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
	Tcl_Panic("TkImgPhotoGet couldn't find visual for window");
    }

    nRed = 2;
    nGreen = nBlue = 0;
    mono = 1;
    instancePtr->visualInfo = *visInfoPtr;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    gcmask = 0;
    instancePtr->visualInfo.visual = Tk_Visual(tkwin);
#endif
    switch (visInfoPtr->c_class) {
    case DirectColor:
    case TrueColor:
	nRed = 1 << CountBits(visInfoPtr->red_mask);
	nGreen = 1 << CountBits(visInfoPtr->green_mask);
	nBlue = 1 << CountBits(visInfoPtr->blue_mask);
	mono = 0;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
	if (visInfoPtr->depth > 24) {
	    gcValues.plane_mask = visInfoPtr->red_mask
		    | visInfoPtr->green_mask
		    | visInfoPtr->blue_mask;
	    gcmask = GCPlaneMask;
	}
#endif
	break;
    case PseudoColor:
    case StaticColor:
	if (visInfoPtr->depth > 15) {
	    nRed = 32;
	    nGreen = 32;
	    nBlue = 32;
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368



369

370
371
372
373
374
375
376
	}
	break;
    case GrayScale:
    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree((char *) visInfoPtr);

    if (mono) {
	sprintf(buf, "%d", nRed);
    } else {
	sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(modelPtr->interp, tkwin, "white");
    black = Tk_GetColor(modelPtr->interp, tkwin, "black");
    gcValues.foreground = (white != NULL)? white->pixel:
	    WhitePixelOfScreen(Tk_Screen(tkwin));
    gcValues.background = (black != NULL)? black->pixel:
	    BlackPixelOfScreen(Tk_Screen(tkwin));
    Tk_FreeColor(white);
    Tk_FreeColor(black);
    gcValues.graphics_exposures = False;

    instancePtr->gc = Tk_GetGC(tkwin,



	    GCForeground|GCBackground|GCGraphicsExposures, &gcValues);


    /*
     * Set configuration options and finish the initialization of the
     * instance. This will also dither the image if necessary.
     */

    TkImgPhotoConfigureInstance(instancePtr);







|


|

|
















>

>
>
>
|
>







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
	}
	break;
    case GrayScale:
    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree(visInfoPtr);

    if (mono) {
	snprintf(buf, sizeof(buf), "%d", nRed);
    } else {
	snprintf(buf, sizeof(buf), "%d/%d/%d", nRed, nGreen, nBlue);
    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(modelPtr->interp, tkwin, "white");
    black = Tk_GetColor(modelPtr->interp, tkwin, "black");
    gcValues.foreground = (white != NULL)? white->pixel:
	    WhitePixelOfScreen(Tk_Screen(tkwin));
    gcValues.background = (black != NULL)? black->pixel:
	    BlackPixelOfScreen(Tk_Screen(tkwin));
    Tk_FreeColor(white);
    Tk_FreeColor(black);
    gcValues.graphics_exposures = False;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    instancePtr->gc = Tk_GetGC(tkwin,
	gcmask|GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
#else
    instancePtr->gc = Tk_GetGC(tkwin,
	GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
#endif

    /*
     * Set configuration options and finish the initialization of the
     * instance. This will also dither the image if necessary.
     */

    TkImgPhotoConfigureInstance(instancePtr);
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
 *	whereas RGB15 is the correct version and works for 15bpp+, but it
 *	slower, so it's only used for 15bpp+.
 *
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *----------------------------------------------------------------------
 */
#ifndef TKPUTIMAGE_CAN_BLEND
#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \







|







440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
 *	whereas RGB15 is the correct version and works for 15bpp+, but it
 *	slower, so it's only used for 15bpp+.
 *
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *----------------------------------------------------------------------
 */
#ifndef TK_CAN_RENDER_RGBA
#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647
648
649
650
651
652
		}
		XPutPixel(bgImg, x, y, RGB(r, g, b));
	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* TKPUTIMAGE_CAN_BLEND */

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoDisplay(
    ClientData clientData,	/* Pointer to PhotoInstance structure for
				 * instance to be displayed. */
    Display *display,		/* Display on which to draw image. */
    Drawable drawable,		/* Pixmap or window in which to draw image. */
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to
				 * draw. */
    int drawableX,int drawableY)/* Coordinates within drawable that correspond
				 * to imageX and imageY. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
#ifndef TKPUTIMAGE_CAN_BLEND
    XVisualInfo visInfo = instancePtr->visualInfo;
#endif

    /*
     * If there's no pixmap, it means that an error occurred while creating
     * the image instance so it can't be displayed.
     */

    if (instancePtr->pixels == None) {
	return;
    }

#ifdef TKPUTIMAGE_CAN_BLEND

    /*
     * If TkPutImage can handle RGBA Ximages directly there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->modelPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);

#else

    if ((instancePtr->modelPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;







|



















|











|












|
>

|








|




>







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
		}
		XPutPixel(bgImg, x, y, RGB(r, g, b));
	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* TK_CAN_RENDER_RGBA */

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoDisplay(
    void *clientData,	/* Pointer to PhotoInstance structure for
				 * instance to be displayed. */
    Display *display,		/* Display on which to draw image. */
    Drawable drawable,		/* Pixmap or window in which to draw image. */
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to
				 * draw. */
    int drawableX,int drawableY)/* Coordinates within drawable that correspond
				 * to imageX and imageY. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
#ifndef TK_CAN_RENDER_RGBA
    XVisualInfo visInfo = instancePtr->visualInfo;
#endif

    /*
     * If there's no pixmap, it means that an error occurred while creating
     * the image instance so it can't be displayed.
     */

    if (instancePtr->pixels == None) {
	return;
    }

#ifdef TK_CAN_RENDER_RGBA

    /*
     * We can use TkpPutRGBAImage to render RGBA Ximages directly so there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->modelPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkpPutRGBAImage(display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);

#else

    if ((instancePtr->modelPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
	TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
		bgImg, 0, 0, drawableX, drawableY,
		(unsigned int) width, (unsigned int) height);
	XDestroyImage(bgImg);
	Tk_DeleteErrorHandler(handler);
    } else {
	/*
	 * modelPtr->region describes which parts of the image contain valid
	 * data. We set this region as the clip mask for the gc, setting its
	 * origin appropriately, and use it when drawing the image.
	 */

    fallBack:
	TkSetRegion(display, instancePtr->gc,
		instancePtr->modelPtr->validRegion);







|







712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
	TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
		bgImg, 0, 0, drawableX, drawableY,
		(unsigned int) width, (unsigned int) height);
	XDestroyImage(bgImg);
	Tk_DeleteErrorHandler(handler);
    } else {
	/*
	 * modelPtr->validRegion describes which parts of the image contain valid
	 * data. We set this region as the clip mask for the gc, setting its
	 * origin appropriately, and use it when drawing the image.
	 */

    fallBack:
	TkSetRegion(display, instancePtr->gc,
		instancePtr->modelPtr->validRegion);
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
 *	Internal data structures get cleaned up, later.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoFree(
    ClientData clientData,	/* Pointer to PhotoInstance structure for
				 * instance to be displayed. */
    Display *display)		/* Display containing window that used
				 * image. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    ColorTable *colorPtr;
    (void)display;

    if (instancePtr->refCount-- > 1) {
	return;
    }

    /*
     * There are no more uses of the image within this widget. Decrement the







|

|




<







752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
 *	Internal data structures get cleaned up, later.
 *
 *----------------------------------------------------------------------
 */

void
TkImgPhotoFree(
    void *clientData,	/* Pointer to PhotoInstance structure for
				 * instance to be displayed. */
    TCL_UNUSED(Display *))	/* Display containing window that used
				 * image. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    ColorTable *colorPtr;


    if (instancePtr->refCount-- > 1) {
	return;
    }

    /*
     * There are no more uses of the image within this widget. Decrement the
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
 *	which is used to locate color tables.
 *
 *----------------------------------------------------------------------
 */

static void
DisposeColorTable(
    ClientData clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = (ColorTable *)clientData;
    Tcl_HashEntry *entry;

    if (colorPtr->pixelMap != NULL) {
	if (colorPtr->numColors > 0) {







|







1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
 *	which is used to locate color tables.
 *
 *----------------------------------------------------------------------
 */

static void
DisposeColorTable(
    void *clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = (ColorTable *)clientData;
    Tcl_HashEntry *entry;

    if (colorPtr->pixelMap != NULL) {
	if (colorPtr->numColors > 0) {
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
 *	The instance data structure and the resources it references are freed.
 *
 *----------------------------------------------------------------------
 */

void
TkImgDisposeInstance(
    ClientData clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    PhotoInstance *prevPtr;

    if (instancePtr->pixels != None) {
	Tk_FreePixmap(instancePtr->display, instancePtr->pixels);







|







1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
 *	The instance data structure and the resources it references are freed.
 *
 *----------------------------------------------------------------------
 */

void
TkImgDisposeInstance(
    void *clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    PhotoInstance *prevPtr;

    if (instancePtr->pixels != None) {
	Tk_FreePixmap(instancePtr->display, instancePtr->pixels);

Changes to generic/tkImgPhoto.c.

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.
 *
 * 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.







|
|
|
|







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 © 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.
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
    int toX2, toY2;		/* Second coordinate pair for -to option. */
    int zoomX, zoomY;		/* Values specified for -zoom option. */
    int subsampleX, subsampleY;	/* Values specified for -subsample option. */
    Tcl_Obj *format;		/* Value specified for -format option. */
    XColor *background;		/* Value specified for -background option. */
    int compositingRule;	/* Value specified for -compositingrule
				 * option. */

};

/*
 * Bit definitions for use with ParseSubcommandOptions: each bit is set in the
 * allowedOptions parameter on a call to ParseSubcommandOptions if that option
 * is allowed for the current photo image subcommand. On return, the bit is
 * set in the options field of the SubcommandOptions structure if that option
 * was specified.
 *
 * OPT_ALPHA:			Set if -alpha option allowed/specified.
 * OPT_BACKGROUND:		Set if -format option allowed/specified.
 * OPT_COMPOSITE:		Set if -compositingrule option allowed/spec'd.
 * OPT_FORMAT:			Set if -format option allowed/specified.
 * OPT_FROM:			Set if -from option allowed/specified.
 * OPT_GRAYSCALE:		Set if -grayscale option allowed/specified.

 * OPT_SHRINK:			Set if -shrink option allowed/specified.
 * OPT_SUBSAMPLE:		Set if -subsample option allowed/spec'd.
 * OPT_TO:			Set if -to option allowed/specified.
 * OPT_WITHALPHA:		Set if -withalpha option allowed/specified.
 * OPT_ZOOM:			Set if -zoom option allowed/specified.
 */

#define OPT_ALPHA	1
#define OPT_BACKGROUND	2
#define OPT_COMPOSITE	4
#define OPT_FORMAT	8
#define OPT_FROM	0x10
#define OPT_GRAYSCALE	0x20

#define OPT_SHRINK	0x40
#define OPT_SUBSAMPLE	0x80
#define OPT_TO		0x100
#define OPT_WITHALPHA	0x200
#define OPT_ZOOM	0x400

/*
 * List of option names. The order here must match the order of declarations
 * of the OPT_* constants above.
 */

static const char *const optionNames[] = {
    "-alpha",
    "-background",
    "-compositingrule",
    "-format",
    "-from",
    "-grayscale",

    "-shrink",
    "-subsample",
    "-to",
    "-withalpha",
    "-zoom",
    NULL
};







>















>













>
|
|
|
|
|













>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    int toX2, toY2;		/* Second coordinate pair for -to option. */
    int zoomX, zoomY;		/* Values specified for -zoom option. */
    int subsampleX, subsampleY;	/* Values specified for -subsample option. */
    Tcl_Obj *format;		/* Value specified for -format option. */
    XColor *background;		/* Value specified for -background option. */
    int compositingRule;	/* Value specified for -compositingrule
				 * option. */
    Tcl_Obj *metadata;		/* Value specified for -metadata option. */
};

/*
 * Bit definitions for use with ParseSubcommandOptions: each bit is set in the
 * allowedOptions parameter on a call to ParseSubcommandOptions if that option
 * is allowed for the current photo image subcommand. On return, the bit is
 * set in the options field of the SubcommandOptions structure if that option
 * was specified.
 *
 * OPT_ALPHA:			Set if -alpha option allowed/specified.
 * OPT_BACKGROUND:		Set if -format option allowed/specified.
 * OPT_COMPOSITE:		Set if -compositingrule option allowed/spec'd.
 * OPT_FORMAT:			Set if -format option allowed/specified.
 * OPT_FROM:			Set if -from option allowed/specified.
 * OPT_GRAYSCALE:		Set if -grayscale option allowed/specified.
 * OPT_METADATA:		Set if -metadata option allowed/specified.
 * OPT_SHRINK:			Set if -shrink option allowed/specified.
 * OPT_SUBSAMPLE:		Set if -subsample option allowed/spec'd.
 * OPT_TO:			Set if -to option allowed/specified.
 * OPT_WITHALPHA:		Set if -withalpha option allowed/specified.
 * OPT_ZOOM:			Set if -zoom option allowed/specified.
 */

#define OPT_ALPHA	1
#define OPT_BACKGROUND	2
#define OPT_COMPOSITE	4
#define OPT_FORMAT	8
#define OPT_FROM	0x10
#define OPT_GRAYSCALE	0x20
#define OPT_METADATA	0x40
#define OPT_SHRINK	0x80
#define OPT_SUBSAMPLE	0x100
#define OPT_TO		0x200
#define OPT_WITHALPHA	0x400
#define OPT_ZOOM	0x800

/*
 * List of option names. The order here must match the order of declarations
 * of the OPT_* constants above.
 */

static const char *const optionNames[] = {
    "-alpha",
    "-background",
    "-compositingrule",
    "-format",
    "-from",
    "-grayscale",
    "-metadata",
    "-shrink",
    "-subsample",
    "-to",
    "-withalpha",
    "-zoom",
    NULL
};
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
	"not enough free memory for image buffer"

/*
 * Functions used in the type record for photo images.
 */

static int		ImgPhotoCreate(Tcl_Interp *interp, const char *name,
			    int objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static void		ImgPhotoDelete(ClientData clientData);
static int		ImgPhotoPostscript(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, int x, int y, int width,
			    int height, int prepass);

/*
 * The type record itself for photo images:
 */







|

|
|
|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
	"not enough free memory for image buffer"

/*
 * Functions used in the type record for photo images.
 */

static int		ImgPhotoCreate(Tcl_Interp *interp, const char *name,
			    Tcl_Size objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    void **clientDataPtr);
static void		ImgPhotoDelete(void *clientData);
static int		ImgPhotoPostscript(void *clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, int x, int y, int width,
			    int height, int prepass);

/*
 * The type record itself for photo images:
 */
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


162
163


164
165
166
167


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197


198

199
200
201


202

203
204
205
206
207
208
209
    NULL
};

typedef struct {
    Tk_PhotoImageFormat *formatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    Tk_PhotoImageFormat *oldFormatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/
#endif
    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Default configuration
 */

#define DEF_PHOTO_GAMMA		"1"
#define DEF_PHOTO_HEIGHT	"0"
#define DEF_PHOTO_PALETTE	""
#define DEF_PHOTO_WIDTH		"0"

/*
 * Information used for parsing configuration specifications:
 */

static const Tk_ConfigSpec configSpecs[] = {


    {TK_CONFIG_STRING, "-file", NULL, NULL,
	 NULL, offsetof(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},


    {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
	 DEF_PHOTO_GAMMA, offsetof(PhotoModel, gamma), 0, NULL},
    {TK_CONFIG_INT, "-height", NULL, NULL,
	 DEF_PHOTO_HEIGHT, offsetof(PhotoModel, userHeight), 0, NULL},


    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, offsetof(PhotoModel, palette), 0, NULL},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, offsetof(PhotoModel, userWidth), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations
 */

static void		PhotoFormatThreadExitProc(ClientData clientData);
static int		ImgPhotoCmd(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		ParseSubcommandOptions(
			    struct SubcommandOptions *optPtr,
			    Tcl_Interp *interp, int allowedOptions,
			    int *indexPtr, int objc, Tcl_Obj *const objv[]);
static void		ImgPhotoCmdDeletedProc(ClientData clientData);
static int		ImgPhotoConfigureModel(Tcl_Interp *interp,
			    PhotoModel *modelPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		ToggleComplexAlphaIfNeeded(PhotoModel *mPtr);
static int		ImgPhotoSetSize(PhotoModel *modelPtr, int width,
			    int height);
static char *		ImgGetPhoto(PhotoModel *modelPtr,
			    Tk_PhotoImageBlock *blockPtr,
			    struct SubcommandOptions *optPtr);
static int		MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *formatString,


			    Tk_PhotoImageFormat **imageFormatPtr,

			    int *widthPtr, int *heightPtr, int *oldformat);
static int		MatchStringFormat(Tcl_Interp *interp, Tcl_Obj *data,
			    Tcl_Obj *formatString,


			    Tk_PhotoImageFormat **imageFormatPtr,

			    int *widthPtr, int *heightPtr, int *oldformat);
static const char *	GetExtension(const char *path);

/*
 *----------------------------------------------------------------------
 *
 * PhotoFormatThreadExitProc --







<
|

|
<



















>
>


>
>




>
>











|
|




|
|

|









>
>

>



>
>

>







135
136
137
138
139
140
141

142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    NULL
};

typedef struct {
    Tk_PhotoImageFormat *formatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/

    Tk_PhotoImageFormatVersion3 *formatListVersion3;
				/* Pointer to the first in the list of known
				 * photo image formats in Version3 format.*/

    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Default configuration
 */

#define DEF_PHOTO_GAMMA		"1"
#define DEF_PHOTO_HEIGHT	"0"
#define DEF_PHOTO_PALETTE	""
#define DEF_PHOTO_WIDTH		"0"

/*
 * Information used for parsing configuration specifications:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	 NULL, TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	 NULL, offsetof(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-format", NULL, NULL,
	 NULL, TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
	 DEF_PHOTO_GAMMA, offsetof(PhotoModel, gamma), 0, NULL},
    {TK_CONFIG_INT, "-height", NULL, NULL,
	 DEF_PHOTO_HEIGHT, offsetof(PhotoModel, userHeight), 0, NULL},
    {TK_CONFIG_STRING, "-metadata", NULL, NULL,
	 NULL, TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, offsetof(PhotoModel, palette), 0, NULL},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, offsetof(PhotoModel, userWidth), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations
 */

static void		PhotoFormatThreadExitProc(void *clientData);
static int		ImgPhotoCmd(void *clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		ParseSubcommandOptions(
			    struct SubcommandOptions *optPtr,
			    Tcl_Interp *interp, int allowedOptions,
			    Tcl_Size *indexPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static void		ImgPhotoCmdDeletedProc(void *clientData);
static int		ImgPhotoConfigureModel(Tcl_Interp *interp,
			    PhotoModel *modelPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static int		ToggleComplexAlphaIfNeeded(PhotoModel *mPtr);
static int		ImgPhotoSetSize(PhotoModel *modelPtr, int width,
			    int height);
static char *		ImgGetPhoto(PhotoModel *modelPtr,
			    Tk_PhotoImageBlock *blockPtr,
			    struct SubcommandOptions *optPtr);
static int		MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *formatString,
			    Tcl_Obj *metadataInObj,
			    Tcl_Obj *metadataOutObj,
			    Tk_PhotoImageFormat **imageFormatPtr,
			    Tk_PhotoImageFormatVersion3 **imageFormatVersion3Ptr,
			    int *widthPtr, int *heightPtr, int *oldformat);
static int		MatchStringFormat(Tcl_Interp *interp, Tcl_Obj *data,
			    Tcl_Obj *formatString,
			    Tcl_Obj *metadataInObj,
			    Tcl_Obj *metadataOutObj,
			    Tk_PhotoImageFormat **imageFormatPtr,
			    Tk_PhotoImageFormatVersion3 **imageFormatVersion3Ptr,
			    int *widthPtr, int *heightPtr, int *oldformat);
static const char *	GetExtension(const char *path);

/*
 *----------------------------------------------------------------------
 *
 * PhotoFormatThreadExitProc --
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242






243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318


























319
320
321
322
323
324
325
 */

static void
PhotoFormatThreadExitProc(
    TCL_UNUSED(void *))	/* not used */
{
    Tk_PhotoImageFormat *freePtr;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    while (tsdPtr->oldFormatList != NULL) {
	freePtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr;
	ckfree(freePtr);
    }
#endif
    while (tsdPtr->formatList != NULL) {
	freePtr = tsdPtr->formatList;
	tsdPtr->formatList = tsdPtr->formatList->nextPtr;
	ckfree((char *)freePtr->name);
	ckfree(freePtr);
    }






}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat --

 *
 *	This function is invoked by an image file handler to register a new
 *	photo image format and the functions that handle the new format. The
 *	function is typically invoked during Tcl_AppInit.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The new image file format is entered into a table used in the photo
 *	image "read" and "write" subcommands.
 *
 *----------------------------------------------------------------------
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
void
Tk_CreateOldPhotoImageFormat(
    const Tk_PhotoImageFormat *formatPtr)
				/* Structure describing the format. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_PhotoImageFormat *copyPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *)ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;
    copyPtr->nextPtr = tsdPtr->oldFormatList;
    tsdPtr->oldFormatList = copyPtr;
}
#endif

void
Tk_CreatePhotoImageFormat(
    const Tk_PhotoImageFormat *formatPtr)
				/* Structure describing the format. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_PhotoImageFormat *copyPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *)ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    if (isupper((unsigned char) *formatPtr->name)) {
	copyPtr->nextPtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = copyPtr;
    } else
#endif
    {
	/* for compatibility with aMSN: make a copy of formatPtr->name */
	char *name = (char *)ckalloc(strlen(formatPtr->name) + 1);
	strcpy(name, formatPtr->name);
	copyPtr->name = name;
	copyPtr->nextPtr = tsdPtr->formatList;
	tsdPtr->formatList = copyPtr;
    }
}



























/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCreate --
 *
 *	This function is called by the Tk image code to create a new photo







>



<
<
<
<
<
<
<



|


>
>
>
>
>
>





|
>















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<
<
<
<
<









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







234
235
236
237
238
239
240
241
242
243
244







245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278























279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295






296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
 */

static void
PhotoFormatThreadExitProc(
    TCL_UNUSED(void *))	/* not used */
{
    Tk_PhotoImageFormat *freePtr;
    Tk_PhotoImageFormatVersion3 *freePtrVersion3;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));








    while (tsdPtr->formatList != NULL) {
	freePtr = tsdPtr->formatList;
	tsdPtr->formatList = tsdPtr->formatList->nextPtr;
	ckfree((void *)freePtr->name);
	ckfree(freePtr);
    }
    while (tsdPtr->formatListVersion3 != NULL) {
	freePtrVersion3 = tsdPtr->formatListVersion3;
	tsdPtr->formatListVersion3 = tsdPtr->formatListVersion3->nextPtr;
	ckfree((void *)freePtrVersion3->name);
	ckfree(freePtrVersion3);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CreatePhotoImageFormat,
 * Tk_CreatePhotoImageFormatVersion3 --
 *
 *	This function is invoked by an image file handler to register a new
 *	photo image format and the functions that handle the new format. The
 *	function is typically invoked during Tcl_AppInit.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The new image file format is entered into a table used in the photo
 *	image "read" and "write" subcommands.
 *
 *----------------------------------------------------------------------
 */
























void
Tk_CreatePhotoImageFormat(
    const Tk_PhotoImageFormat *formatPtr)
				/* Structure describing the format. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_PhotoImageFormat *copyPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormat *)ckalloc(sizeof(Tk_PhotoImageFormat));
    *copyPtr = *formatPtr;






    {
	/* for compatibility with aMSN: make a copy of formatPtr->name */
	char *name = (char *)ckalloc(strlen(formatPtr->name) + 1);
	strcpy(name, formatPtr->name);
	copyPtr->name = name;
	copyPtr->nextPtr = tsdPtr->formatList;
	tsdPtr->formatList = copyPtr;
    }
}
void
Tk_CreatePhotoImageFormatVersion3(
    const Tk_PhotoImageFormatVersion3 *formatPtr)
				/* Structure describing the format. All of the
				 * fields except "nextPtr" must be filled in
				 * by caller. */
{
    Tk_PhotoImageFormatVersion3 *copyPtr;
    char *name;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL);
    }
    copyPtr = (Tk_PhotoImageFormatVersion3 *)
	    ckalloc(sizeof(Tk_PhotoImageFormatVersion3));
    *copyPtr = *formatPtr;
    /* for compatibility with aMSN: make a copy of formatPtr->name */
    name = (char *)ckalloc(strlen(formatPtr->name) + 1);
    strcpy(name, formatPtr->name);
    copyPtr->name = name;
    copyPtr->nextPtr = tsdPtr->formatListVersion3;
    tsdPtr->formatListVersion3 = copyPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCreate --
 *
 *	This function is called by the Tk image code to create a new photo
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
 */

static int
ImgPhotoCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,		/* Name to use for image. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    ClientData *clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    PhotoModel *modelPtr;

    /*
     * Allocate and initialize the photo image model record.
     */







|





|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
 */

static int
ImgPhotoCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,		/* Name to use for image. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    void **clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    PhotoModel *modelPtr;

    /*
     * Allocate and initialize the photo image model record.
     */
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421

422
423
424
425
426
427
428
429
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    ClientData clientData,	/* Information about photo model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const photoOptions[] = {
	"blank", "cget", "configure", "copy", "data", "get", "put",
	"read", "redither", "transparency", "write", NULL
    };
    enum PhotoOptions {
	PHOTO_BLANK, PHOTO_CGET, PHOTO_CONFIGURE, PHOTO_COPY, PHOTO_DATA,
	PHOTO_GET, PHOTO_PUT, PHOTO_READ, PHOTO_REDITHER, PHOTO_TRANS,
	PHOTO_WRITE
    };

    PhotoModel *modelPtr = (PhotoModel *)clientData;
    int result, index, x, y, width, height;

    struct SubcommandOptions options;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    Tk_PhotoImageFormat *imageFormat;

    TkSizeT length;
    int imageWidth, imageHeight, matched, oldformat = 0;
    Tcl_Channel chan;
    Tk_PhotoHandle srcHandle;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {







|















|
>




>
|







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    void *clientData,	/* Information about photo model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const photoOptions[] = {
	"blank", "cget", "configure", "copy", "data", "get", "put",
	"read", "redither", "transparency", "write", NULL
    };
    enum PhotoOptions {
	PHOTO_BLANK, PHOTO_CGET, PHOTO_CONFIGURE, PHOTO_COPY, PHOTO_DATA,
	PHOTO_GET, PHOTO_PUT, PHOTO_READ, PHOTO_REDITHER, PHOTO_TRANS,
	PHOTO_WRITE
    };

    PhotoModel *modelPtr = (PhotoModel *)clientData;
    int result, x, y, width, height;
    Tcl_Size index;
    struct SubcommandOptions options;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    Tk_PhotoImageFormat *imageFormat;
    Tk_PhotoImageFormatVersion3 *imageFormatVersion3;
    Tcl_Size length;
    int imageWidth, imageHeight, matched, oldformat = 0;
    Tcl_Channel chan;
    Tk_PhotoHandle srcHandle;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468




469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535














536
537
538
539
540
541
542
543
544
545
546
547
    case PHOTO_CGET: {
	const char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	if (strncmp(arg,"-data", length) == 0) {
	    if (modelPtr->dataString) {
		Tcl_SetObjResult(interp, modelPtr->dataString);
	    }
	} else if (strncmp(arg,"-format", length) == 0) {
	    if (modelPtr->format) {
		Tcl_SetObjResult(interp, modelPtr->format);
	    }




	} else {
	    Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		    (char *) modelPtr, Tcl_GetString(objv[2]), 0);
	}
	return TCL_OK;
    }

    case PHOTO_CONFIGURE:
	/*
	 * photo configure command - handle this in the standard way.
	 */

	if (objc == 2) {
	    Tcl_Obj *obj, *subobj;

	    result = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr, NULL, 0);
	    if (result != TCL_OK) {
		return result;
	    }
	    obj = Tcl_NewObj();
	    subobj = Tcl_NewStringObj("-data {} {} {}", 14);
	    if (modelPtr->dataString) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->dataString);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-format {} {} {}", 16);
	    if (modelPtr->format) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->format);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", NULL);







	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
	    Tcl_SetObjResult(interp, obj);
	    return TCL_OK;

	} else if (objc == 3) {
	    const char *arg = TkGetStringFromObj(objv[2], &length);

	    if (length > 1 && !strncmp(arg, "-data", length)) {
		Tcl_AppendResult(interp, "-data {} {} {}", NULL);
		if (modelPtr->dataString) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->dataString);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		    !strncmp(arg, "-format", length)) {
		Tcl_AppendResult(interp, "-format {} {} {}", NULL);
		if (modelPtr->format) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->format);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);














		}
		return TCL_OK;
	    } else {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, (char *) modelPtr, arg, 0);
	    }
	} else {
	    return ImgPhotoConfigureModel(interp, modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}

    case PHOTO_COPY:







|








>
>
>
>


|













|








|






|
>
>
>
>
>
>
>







|


|








|




|








|
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
    case PHOTO_CGET: {
	const char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = Tcl_GetStringFromObj(objv[2], &length);
	if (strncmp(arg,"-data", length) == 0) {
	    if (modelPtr->dataString) {
		Tcl_SetObjResult(interp, modelPtr->dataString);
	    }
	} else if (strncmp(arg,"-format", length) == 0) {
	    if (modelPtr->format) {
		Tcl_SetObjResult(interp, modelPtr->format);
	    }
	} else if (strncmp(arg, "-metadata", length) == 0) {
	    if (modelPtr->metadata) {
		Tcl_SetObjResult(interp, modelPtr->metadata);
	    }
	} else {
	    Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		    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, modelPtr, NULL, 0);
	    if (result != TCL_OK) {
		return result;
	    }
	    obj = Tcl_NewObj();
	    subobj = Tcl_NewStringObj("-data {} {} {}", 14);
	    if (modelPtr->dataString) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->dataString);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", (char *)NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-format {} {} {}", 16);
	    if (modelPtr->format) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->format);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", (char *)NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    subobj = Tcl_NewStringObj("-metadata {} {} {}", 18);
	    if (modelPtr->metadata) {
		Tcl_ListObjAppendElement(NULL, subobj, modelPtr->metadata);
	    } else {
		Tcl_AppendStringsToObj(subobj, " {}", (char *)NULL);
	    }
	    Tcl_ListObjAppendElement(interp, obj, subobj);
	    Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
	    Tcl_SetObjResult(interp, obj);
	    return TCL_OK;

	} else if (objc == 3) {
	    const char *arg = Tcl_GetStringFromObj(objv[2], &length);

	    if (length > 1 && !strncmp(arg, "-data", length)) {
		Tcl_AppendResult(interp, "-data {} {} {}", (char *)NULL);
		if (modelPtr->dataString) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->dataString);
		} else {
		    Tcl_AppendResult(interp, " {}", (char *)NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		    !strncmp(arg, "-format", length)) {
		Tcl_AppendResult(interp, "-format {} {} {}", (char *)NULL);
		if (modelPtr->format) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->format);
		} else {
		    Tcl_AppendResult(interp, " {}", (char *)NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		!strncmp(arg, "-metadata", length)) {
		Tcl_AppendResult(interp, "-metadata {} {} {}", (char *)NULL);
		if (modelPtr->metadata) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			modelPtr->metadata);
		} else {
		    Tcl_AppendResult(interp, " {}", (char *)NULL);
		}
		return TCL_OK;
	    } else {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, modelPtr, arg, 0);
	    }
	} else {
	    return ImgPhotoConfigureModel(interp, modelPtr, objc-2, objv+2,
		    TK_CONFIG_ARGV_ONLY);
	}

    case PHOTO_COPY:
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

	srcHandle = Tk_FindPhoto(interp, Tcl_GetString(options.name));
	if (srcHandle == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image \"%s\" doesn't exist or is not a photo image",
		    Tcl_GetString(options.name)));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO",
		    Tcl_GetString(options.name), NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetImage(srcHandle, &block);
	if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
		|| (options.fromX2 > block.width)
		|| (options.fromY2 > block.height)) {
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Hack to pass through the message that the place we're coming from
	 * has a simple alpha channel.
	 */







|






<
<
<



|







612
613
614
615
616
617
618
619
620
621
622
623
624
625



626
627
628
629
630
631
632
633
634
635
636

	srcHandle = Tk_FindPhoto(interp, Tcl_GetString(options.name));
	if (srcHandle == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image \"%s\" doesn't exist or is not a photo image",
		    Tcl_GetString(options.name)));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO",
		    Tcl_GetString(options.name), (char *)NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetImage(srcHandle, &block);
	if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
		|| (options.fromX2 > block.width)
		|| (options.fromY2 > block.height)) {



	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * Hack to pass through the message that the place we're coming from
	 * has a simple alpha channel.
	 */
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650



651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686

687
688
689
690
691

692
693
694
695

696
697
698
699
700



701
702
703
704
705
706
707
708
709



710
711
712
713
714
715
716
717
718
719
720
721
722
723










724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

747
748
749
750
751
752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774



775
776
777
778
779
780
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
	    options.toY2 = options.toY + height * options.zoomY;
	}

	/*
	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */


	block.pixelPtr += options.fromX * block.pixelSize
		+ options.fromY * block.pitch;
	block.width = options.fromX2 - options.fromX;
	block.height = options.fromY2 - options.fromY;
	result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
		&block, options.toX, options.toY, options.toX2 - options.toX,
		options.toY2 - options.toY, options.zoomX, options.zoomY,
		options.subsampleX, options.subsampleY,
		options.compositingRule);




	/*
	 * Set the destination image size if the -shrink option was specified.
	 * This has to be done _after_ copying the data. Otherwise, if source
	 * and destination are the same image, block.pixelPtr would point to
	 * an invalid memory block (bug [5239fd749b]).
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX2,
		    options.toY2) != TCL_OK) {
		if (options.background) {
		    Tk_FreeColor(options.background);
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
		return TCL_ERROR;
	    }
	}

	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	return result;

    case PHOTO_DATA: {
        char *data = NULL;
        Tcl_Obj *freeObj = NULL;


	/*
	 * photo data command - first parse and check any options given.
	 */

	Tk_ImageStringWriteProc *stringWriteProc = NULL;


	index = 1;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;

	options.fromX = 0;
	options.fromY = 0;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,

		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");



	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);



	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = modelPtr->width;
	    options.fromY2 = modelPtr->height;
	}
	if (!(options.options & OPT_FORMAT)) {
            options.format = Tcl_NewStringObj("default", -1);
            freeObj = options.format;










	}

	/*
	 * Search for an appropriate image string format handler.
	 */

	matched = 0;
	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
                imageFormat = imageFormat->nextPtr) {
	    if ((strncasecmp(Tcl_GetString(options.format),
                    imageFormat->name, strlen(imageFormat->name)) == 0)) {
                matched = 1;
                if (imageFormat->stringWriteProc != NULL) {
                    stringWriteProc = imageFormat->stringWriteProc;
                    break;
                }
	    }
	}
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
	if (stringWriteProc == NULL) {
	    oldformat = 1;
	    for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
                    imageFormat = imageFormat->nextPtr) {

                if ((strncasecmp(Tcl_GetString(options.format),
                        imageFormat->name,
                        strlen(imageFormat->name)) == 0)) {
                    matched = 1;
                    if (imageFormat->stringWriteProc != NULL) {
                        stringWriteProc = imageFormat->stringWriteProc;

                        break;
                    }
                }
	    }
	}
#endif
	if (stringWriteProc == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                    "image string format \"%s\" is %s",
                    Tcl_GetString(options.format),
                    (matched ? "not supported" : "unknown")));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
                    Tcl_GetString(options.format), NULL);
	    goto dataErrorExit;
	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);




	if (oldformat) {
	    Tcl_DString buffer;
	    typedef int (*OldStringWriteProc)(Tcl_Interp *interp,
		    Tcl_DString *dataPtr, const char *formatString,
		    Tk_PhotoImageBlock *blockPtr);

	    Tcl_DStringInit(&buffer);
	    result = ((OldStringWriteProc)(void *)stringWriteProc)(interp, &buffer,
		    Tcl_GetString(options.format), &block);
	    if (result == TCL_OK) {
		Tcl_DStringResult(interp, &buffer);
	    } else {
		Tcl_DStringFree(&buffer);
	    }
	} else {
	    typedef int (*NewStringWriteProc)(Tcl_Interp *interp,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr,
		    void *dummy);

	    result = ((NewStringWriteProc)(void *)stringWriteProc)(interp,
		    options.format, &block, NULL);
	}












	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
        if (freeObj != NULL) {
            Tcl_DecrRefCount(freeObj);
        }
	return result;

      dataErrorExit:
        if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
        if (freeObj != NULL) {
            Tcl_DecrRefCount(freeObj);
        }
	return TCL_ERROR;
    }

    case PHOTO_GET: {
	/*
	 * photo get command - first parse and check parameters.
	 */

	Tcl_Obj *channels[4];
	int channelCount = 3;

        index = 3;
        memset(&options, 0, sizeof(options));
        options.name = NULL;
        if (ParseSubcommandOptions(&options, interp, OPT_WITHALPHA,
                &index, objc, objv) != TCL_OK) {
            return TCL_ERROR;
        }
        if (options.name == NULL || index < objc) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?-withalpha?");
	    return TCL_ERROR;
	}
        if (options.options & OPT_WITHALPHA) {
            channelCount = 4;
        }

	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s get: coordinates out of range",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
		    NULL);
	    return TCL_ERROR;
	}

	/*
	 * Extract the value of the desired pixel and format it as a list.
	 */

	pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	channels[0] = Tcl_NewWideIntObj(pixelPtr[0]);
	channels[1] = Tcl_NewWideIntObj(pixelPtr[1]);
	channels[2] = Tcl_NewWideIntObj(pixelPtr[2]);
	channels[3] = Tcl_NewWideIntObj(pixelPtr[3]);

	Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
	return TCL_OK;
    }

    case PHOTO_PUT: {
	Tcl_Obj *format, *data;

	/*
	 * photo put command - first parse the options.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;

	if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,

		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * See if there's a format that can read the data
	 */

	if (MatchStringFormat(interp, objv[2], options.format, &imageFormat,

		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {

	    return TCL_ERROR;
	}

	if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
	    options.toX2 = options.toX + imageWidth;
	    options.toY2 = options.toY + imageHeight;
	}







>
|
|
|
|
|
|
|
|
|
>
>
>











<
<
<

|
|



>
|
|
<
<




|
|
>






>





>



|
>





>
>
>







|
|
>
>
>












|
|
>
>
>
>
>
>
>
>
>
>








|

|
|
|
|
|
|


<

|
|
|
>
|
|
|
|
|
|
>
|
|
|


<
|

|
|
|

|









>
>
>
|















|
<


|

>
>
>
>
>
>
>
>
>
>
>
>






|
|
|
<
<
<
<
<
<
<
<
<
<
<
<









|

|
|
|
|
|
|
|
|



|
|
|











|








|
|
<
<
>















>
|
>












|
>
|
>







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701



702
703
704
705
706
707
708
709
710


711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	    options.toY2 = options.toY + height * options.zoomY;
	}

	/*
	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */

	if (block.pixelPtr) {
	    block.pixelPtr += options.fromX * block.pixelSize
		    + options.fromY * block.pitch;
	    block.width = options.fromX2 - options.fromX;
	    block.height = options.fromY2 - options.fromY;
	    result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
		    &block, options.toX, options.toY, options.toX2 - options.toX,
		    options.toY2 - options.toY, options.zoomX, options.zoomY,
		    options.subsampleX, options.subsampleY,
		    options.compositingRule);
	} else {
	    result = TCL_OK;
	}

	/*
	 * Set the destination image size if the -shrink option was specified.
	 * This has to be done _after_ copying the data. Otherwise, if source
	 * and destination are the same image, block.pixelPtr would point to
	 * an invalid memory block (bug [5239fd749b]).
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX2,
		    options.toY2) != TCL_OK) {



		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (block.pixelPtr || (options.options & OPT_SHRINK)) {
	    Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		    modelPtr->width, modelPtr->height);


	}
	return result;

    case PHOTO_DATA: {
	char *data = NULL;
	Tcl_Obj *freeObj = NULL;
	Tcl_Obj *metadataIn;

	/*
	 * photo data command - first parse and check any options given.
	 */

	Tk_ImageStringWriteProc *stringWriteProc = NULL;
	Tk_ImageStringWriteProcVersion3 *stringWriteProcVersion3 = NULL;

	index = 1;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.metadata = NULL;
	options.fromX = 0;
	options.fromY = 0;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND
		| OPT_METADATA,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters.
	 */

	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    options.fromX2 = modelPtr->width;
	    options.fromY2 = modelPtr->height;
	}
	if (!(options.options & OPT_FORMAT)) {
	    options.format = Tcl_NewStringObj("default", TCL_INDEX_NONE);
	    freeObj = options.format;
	}

	/*
	 * Use argument metadata if specified, otherwise the master metadata
	 */

	if (NULL != options.metadata) {
	    metadataIn = options.metadata;
	} else {
	    metadataIn = modelPtr->metadata;
	}

	/*
	 * Search for an appropriate image string format handler.
	 */

	matched = 0;
	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
		imageFormat = imageFormat->nextPtr) {
	    if ((strncasecmp(Tcl_GetString(options.format),
		    imageFormat->name, strlen(imageFormat->name)) == 0)) {
		matched = 1;
		if (imageFormat->stringWriteProc != NULL) {
		    stringWriteProc = imageFormat->stringWriteProc;
		    break;
		}
	    }
	}

	if (stringWriteProc == NULL) {
	    oldformat = 0;
	    for (imageFormatVersion3 = tsdPtr->formatListVersion3;
		    imageFormatVersion3 != NULL;
		    imageFormatVersion3 = imageFormatVersion3->nextPtr) {
		if ((strncasecmp(Tcl_GetString(options.format),
			imageFormatVersion3->name,
			strlen(imageFormatVersion3->name)) == 0)) {
		    matched = 1;
		    if (imageFormatVersion3->stringWriteProc != NULL) {
			stringWriteProcVersion3 =
				imageFormatVersion3->stringWriteProc;
			break;
		    }
		}
	    }
	}

	if (stringWriteProc == NULL && stringWriteProcVersion3 == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image string format \"%s\" is %s",
		    Tcl_GetString(options.format),
		    (matched ? "not supported" : "unknown")));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    Tcl_GetString(options.format), (char *)NULL);
	    goto dataErrorExit;
	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	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,
		    Tcl_DString *dataPtr, const char *formatString,
		    Tk_PhotoImageBlock *blockPtr);

	    Tcl_DStringInit(&buffer);
	    result = ((OldStringWriteProc)(void *)stringWriteProc)(interp, &buffer,
		    Tcl_GetString(options.format), &block);
	    if (result == TCL_OK) {
		Tcl_DStringResult(interp, &buffer);
	    } else {
		Tcl_DStringFree(&buffer);
	    }
	} else {
	    typedef int (*NewStringWriteProc)(Tcl_Interp *interp,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr);


	    result = ((NewStringWriteProc)(void *)stringWriteProc)(interp,
		    options.format, &block);
	}
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
	if (freeObj != NULL) {
	    Tcl_DecrRefCount(freeObj);
	}
	return result;

      dataErrorExit:
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
	if (freeObj != NULL) {
	    Tcl_DecrRefCount(freeObj);
	}












	return TCL_ERROR;
    }

    case PHOTO_GET: {
	/*
	 * photo get command - first parse and check parameters.
	 */

	Tcl_Obj *channels[4];
	int i, channelCount = 3;

	index = 3;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	if (ParseSubcommandOptions(&options, interp, OPT_WITHALPHA,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (options.name == NULL || index < objc) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?-withalpha?");
	    return TCL_ERROR;
	}
	if (options.options & OPT_WITHALPHA) {
	    channelCount = 4;
	}

	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s get: coordinates out of range",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
		    (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * Extract the value of the desired pixel and format it as a list.
	 */

	pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	for (i = 0; i < channelCount; i++) {
	    channels[i] = Tcl_NewWideIntObj(pixelPtr[i]);


	}
	Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
	return TCL_OK;
    }

    case PHOTO_PUT: {
	Tcl_Obj *format, *data;

	/*
	 * photo put command - first parse the options.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.metadata = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_TO|OPT_FORMAT|OPT_METADATA,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * See if there's a format that can read the data
	 */

	if (MatchStringFormat(interp, objv[2], options.format,
		options.metadata, NULL, &imageFormat,
		&imageFormatVersion3, &imageWidth, &imageHeight, &oldformat)
		!= TCL_OK) {
	    return TCL_ERROR;
	}

	if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
	    options.toX2 = options.toX + imageWidth;
	    options.toY2 = options.toY + imageHeight;
	}
912
913
914
915
916
917
918

919
920
921
922
923
924












925
926
927
928
929
930
931
	if (oldformat) {
	    if (format) {
		format = (Tcl_Obj *) Tcl_GetString(format);
	    }
	    data = (Tcl_Obj *) Tcl_GetString(data);
	}


	if (imageFormat->stringReadProc(interp, data, format,
		(Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		options.toX2 - options.toX,
		options.toY2 - options.toY, 0, 0) != TCL_OK) {
	    return TCL_ERROR;
	}












	/*
	 * SB: is the next line really needed? The stringReadProc
	 * writes image data with Tk_PhotoPutBlock(), which in turn
	 * takes care to notify the changed image and to set/unset the
	 * IMAGE_CHANGED bit.
	 */
	modelPtr->flags |= IMAGE_CHANGED;







>
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>







973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
	if (oldformat) {
	    if (format) {
		format = (Tcl_Obj *) Tcl_GetString(format);
	    }
	    data = (Tcl_Obj *) Tcl_GetString(data);
	}

	if (imageFormat != NULL) {
	    if (imageFormat->stringReadProc(interp, data, format,
		    (Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		    options.toX2 - options.toX,
		    options.toY2 - options.toY, 0, 0) != TCL_OK) {
		return TCL_ERROR;
	    }
	} else {
	    if (imageFormatVersion3->stringReadProc(interp, data, format,
		    options.metadata,
		    (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.
	 */
	modelPtr->flags |= IMAGE_CHANGED;
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
	 * photo read command - first parse the options specified.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;

	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_TO | OPT_SHRINK,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Open the image file and look for a handler for it.
	 */








>

|














|
|







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
	 * photo read command - first parse the options specified.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.metadata = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_TO | OPT_SHRINK | OPT_METADATA,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * Open the image file and look for a handler for it.
	 */

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
	if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
		!= TCL_OK) {
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}

	if (MatchFileFormat(interp, chan,
		Tcl_GetString(options.name), options.format, &imageFormat,

		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {
	    Tcl_Close(NULL, chan);

	    return TCL_ERROR;

	}

	/*
	 * Check the values given for the -from option.
	 */

	if ((options.fromX > imageWidth) || (options.fromY > imageHeight)
		|| (options.fromX2 > imageWidth)
		|| (options.fromY2 > imageHeight)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;

	}
	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    width = imageWidth - options.fromX;
	    height = imageHeight - options.fromY;
	} else {
	    width = options.fromX2 - options.fromX;
	    height = options.fromY2 - options.fromY;
	}

	/*
	 * If the -shrink option was specified, set the size of the image.
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX + width,
		    options.toY + height) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
		Tcl_Close(NULL, chan);
		return TCL_ERROR;

	    }
	}

	/*
	 * Call the handler's file read function to read the data into the
	 * image.
	 */

	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(format);
	}

	result = imageFormat->fileReadProc(interp, chan,
		Tcl_GetString(options.name),
		format, (Tk_PhotoHandle) modelPtr, options.toX,
		options.toY, width, height, options.fromX, options.fromY);








	if (chan != NULL) {
	    Tcl_Close(NULL, chan);
	}
	return result;
    }

    case PHOTO_REDITHER:







|
>
|
<
>
|
>












|
<
|
>


















|
|
<
|
>












>
|
|
|
|
>
>
>
>
>
>
>
>







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
	if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
		!= TCL_OK) {
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}

	if (MatchFileFormat(interp, chan,
		Tcl_GetString(options.name), options.format,
		options.metadata, NULL, &imageFormat,
		&imageFormatVersion3, &imageWidth, &imageHeight, &oldformat)

		!= TCL_OK) {
	    result = TCL_ERROR;
	    goto readCleanup;
	}

	/*
	 * Check the values given for the -from option.
	 */

	if ((options.fromX > imageWidth) || (options.fromY > imageHeight)
		|| (options.fromX2 > imageWidth)
		|| (options.fromY2 > imageHeight)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);

	    result = TCL_ERROR;
	    goto readCleanup;
	}
	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    width = imageWidth - options.fromX;
	    height = imageHeight - options.fromY;
	} else {
	    width = options.fromX2 - options.fromX;
	    height = options.fromY2 - options.fromY;
	}

	/*
	 * If the -shrink option was specified, set the size of the image.
	 */

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX + width,
		    options.toY + height) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);

		result = TCL_ERROR;
		goto readCleanup;
	    }
	}

	/*
	 * Call the handler's file read function to read the data into the
	 * image.
	 */

	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(format);
	}
	if (imageFormat != NULL) {
	    result = imageFormat->fileReadProc(interp, chan,
		    Tcl_GetString(options.name),
		    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) modelPtr,
		    options.toX, options.toY, width, height, options.fromX,
		    options.fromY, NULL);
	}
readCleanup:
	if (chan != NULL) {
	    Tcl_Close(NULL, chan);
	}
	return result;
    }

    case PHOTO_REDITHER:
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
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		    || (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency get: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Extract and return the desired value
	     */
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		Tcl_SetObjResult(interp, Tcl_NewBooleanObj( ! pixelPtr[3]));
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixelPtr[3]));
	    }
	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {







|













|








|







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
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			(char *)NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		    || (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency get: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			(char *)NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Extract and return the desired value
	     */
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pixelPtr[3] == 0));
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixelPtr[3]));
	    }
	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {
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
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency set: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    if (boolMode) {
		if (Tcl_GetBooleanFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
	    } else {
		if (Tcl_GetIntFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (newVal < 0 || newVal > 255) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "invalid alpha value \"%d\": "
			    "must be integer between 0 and 255", newVal));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "BAD_VALUE", NULL);
		    return TCL_ERROR;
		}
	    }

	    /*
	     * Set new alpha value for the pixel
	     */







|













|
















|







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
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			(char *)NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency set: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			(char *)NULL);
		return TCL_ERROR;
	    }

	    if (boolMode) {
		if (Tcl_GetBooleanFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
	    } else {
		if (Tcl_GetIntFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (newVal < 0 || newVal > 255) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "invalid alpha value \"%d\": "
			    "must be integer between 0 and 255", newVal));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "BAD_VALUE", (char *)NULL);
		    return TCL_ERROR;
		}
	    }

	    /*
	     * Set new alpha value for the pixel
	     */
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
	}
	Tcl_Panic("unexpected fallthrough");
    }

    case PHOTO_WRITE: {
	char *data;
	const char *fmtString;
	Tcl_Obj *format;
	int usedExt;

	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't write image to a file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * photo write command - first parse and check any options given.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;

	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,

		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");



	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);



	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters. Note that a
	 * missing -format flag results in us having a guess from the file
	 * extension. [Bug 2983824]







|








|
|











>

|
>





>
>
>







|
|
>
>
>







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
	}
	Tcl_Panic("unexpected fallthrough");
    }

    case PHOTO_WRITE: {
	char *data;
	const char *fmtString;
	Tcl_Obj *format, *metadataIn;
	int usedExt;

	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't write image to a file in a safe interpreter", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * photo write command - first parse and check any options given.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.metadata = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND
		| OPT_METADATA,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters. Note that a
	 * missing -format flag results in us having a guess from the file
	 * extension. [Bug 2983824]
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
	    fmtString = GetExtension(Tcl_GetString(options.name));
	    usedExt = (fmtString != NULL);
	} else {
	    fmtString = Tcl_GetString(options.format);
	    usedExt = 0;
	}












	/*
	 * Search for an appropriate image file format handler, and give an
	 * error if none is found.
	 */

	matched = 0;
    redoFormatLookup:

	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
		imageFormat = imageFormat->nextPtr) {
	    if ((fmtString == NULL)
		    || (strncasecmp(fmtString, imageFormat->name,
			    strlen(imageFormat->name)) == 0)) {
		matched = 1;
		if (imageFormat->fileWriteProc != NULL) {
		    break;
		}
	    }
	}
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
	if (imageFormat == NULL) {
	    oldformat = 1;
	    for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
		    imageFormat = imageFormat->nextPtr) {

		if ((fmtString == NULL)
			|| (strncasecmp(fmtString, imageFormat->name,
				strlen(imageFormat->name)) == 0)) {
		    matched = 1;
		    if (imageFormat->fileWriteProc != NULL) {
			break;
		    }
		}
	    }
	}
#endif
	if (usedExt && !matched) {
	    /*
	     * If we didn't find one and we're using file extensions as the
	     * basis for the guessing, go back and look again without
	     * prejudice. Supports old broken code.
	     */

	    usedExt = 0;
	    fmtString = NULL;
	    goto redoFormatLookup;
	}
	if (imageFormat == NULL) {
	    if (fmtString == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no available image file format has file writing"
			" capability", -1));
	    } else if (!matched) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"image file format \"%s\" is unknown", fmtString));
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"image file format \"%s\" has no file writing capability",
			fmtString));
	    }
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    fmtString, NULL);



	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);
	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(options.format);
	}

	result = imageFormat->fileWriteProc(interp,
		Tcl_GetString(options.name), format, &block);





	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
	return result;







>
>
>
>
>
>
>
>
>
>
>







>











<

|
|
|
>

|
|

|





<











|



|









|
>
>
>












>
|
|
>
>
>
>
>







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
	    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 = modelPtr->metadata;
	}

	/*
	 * Search for an appropriate image file format handler, and give an
	 * error if none is found.
	 */

	matched = 0;
    redoFormatLookup:
	imageFormatVersion3 = NULL;
	for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
		imageFormat = imageFormat->nextPtr) {
	    if ((fmtString == NULL)
		    || (strncasecmp(fmtString, imageFormat->name,
			    strlen(imageFormat->name)) == 0)) {
		matched = 1;
		if (imageFormat->fileWriteProc != NULL) {
		    break;
		}
	    }
	}

	if (imageFormat == NULL) {
	    oldformat = 0;
	    for (imageFormatVersion3 = tsdPtr->formatListVersion3;
		    imageFormatVersion3 != NULL;
		    imageFormatVersion3 = imageFormatVersion3->nextPtr) {
		if ((fmtString == NULL)
			|| (strncasecmp(fmtString, imageFormatVersion3->name,
				strlen(imageFormatVersion3->name)) == 0)) {
		    matched = 1;
		    if (imageFormatVersion3->fileWriteProc != NULL) {
			break;
		    }
		}
	    }
	}

	if (usedExt && !matched) {
	    /*
	     * If we didn't find one and we're using file extensions as the
	     * basis for the guessing, go back and look again without
	     * prejudice. Supports old broken code.
	     */

	    usedExt = 0;
	    fmtString = NULL;
	    goto redoFormatLookup;
	}
	if (imageFormat == NULL && imageFormatVersion3 == NULL) {
	    if (fmtString == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no available image file format has file writing"
			" capability", TCL_INDEX_NONE));
	    } else if (!matched) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"image file format \"%s\" is unknown", fmtString));
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"image file format \"%s\" has no file writing capability",
			fmtString));
	    }
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    fmtString, (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);
	format = options.format;
	if (oldformat && format) {
	    format = (Tcl_Obj *) Tcl_GetString(options.format);
	}
	if (imageFormat != NULL) {
	    result = imageFormat->fileWriteProc(interp,
		    Tcl_GetString(options.name), format, &block);
	} else {
	    result = imageFormatVersion3->fileWriteProc(interp,
		    Tcl_GetString(options.name), format, metadataIn,
		    &block);
	}
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
	return result;
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
/*
 *----------------------------------------------------------------------
 *
 * ParseSubcommandOptions --
 *
 *	This function is invoked to process one of the options which may be
 *	specified for the photo image subcommands, namely, -from, -to, -zoom,
 *	-subsample, -format, -shrink, -compositingrule, -alpha, -boolean and
 *	-withalpha.
 *	Parsing starts at the index in *optIndexPtr and stops at the end of
 *	objv[] or at the first value that does not belong to an option.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:







|
|







1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
/*
 *----------------------------------------------------------------------
 *
 * ParseSubcommandOptions --
 *
 *	This function is invoked to process one of the options which may be
 *	specified for the photo image subcommands, namely, -from, -to, -zoom,
 *	-subsample, -format, -shrink, -compositingrule, -alpha, -boolean,
 *	-withalpha and -metadata.
 *	Parsing starts at the index in *optIndexPtr and stops at the end of
 *	objv[] or at the first value that does not belong to an option.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
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
ParseSubcommandOptions(
    struct SubcommandOptions *optPtr,
				/* Information about the options specified and
				 * the values given is returned here. */
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    int allowedOptions,		/* Indicates which options are valid for the
				 * current command. */
    int *optIndexPtr,		/* Points to a variable containing the current
				 * index in objv; this variable is updated by
				 * this function. */
    int objc,			/* Number of arguments in objv[]. */
    Tcl_Obj *const objv[])	/* Arguments to be parsed. */
{
    static const char *const compositingRules[] = {
	"overlay", "set",	/* Note that these must match the
				 * TK_PHOTO_COMPOSITE_* constants. */
	NULL
    };
    TkSizeT length;
    int index, c, bit, currentBit;
    int values[4], numValues, maxValues, argIndex;
    const char *option, *expandedOption, *needed;
    const char *const *listPtr;
    Tcl_Obj *msgObj;

    for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) {
	/*
	 * We can have one value specified without an option; it goes into
	 * optPtr->name.
	 */

	expandedOption = option = TkGetStringFromObj(objv[index], &length);
	if (option[0] != '-') {
	    if (optPtr->name == NULL) {
		optPtr->name = objv[index];
		continue;
	    }
	    break;
	}







|


|







|
|
|










|







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
ParseSubcommandOptions(
    struct SubcommandOptions *optPtr,
				/* Information about the options specified and
				 * the values given is returned here. */
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    int allowedOptions,		/* Indicates which options are valid for the
				 * current command. */
    Tcl_Size *optIndexPtr,		/* Points to a variable containing the current
				 * index in objv; this variable is updated by
				 * this function. */
    Tcl_Size objc,			/* Number of arguments in objv[]. */
    Tcl_Obj *const objv[])	/* Arguments to be parsed. */
{
    static const char *const compositingRules[] = {
	"overlay", "set",	/* Note that these must match the
				 * TK_PHOTO_COMPOSITE_* constants. */
	NULL
    };
    Tcl_Size index, length, argIndex;
    int c, bit, currentBit;
    int values[4], numValues, maxValues;
    const char *option, *expandedOption, *needed;
    const char *const *listPtr;
    Tcl_Obj *msgObj;

    for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) {
	/*
	 * We can have one value specified without an option; it goes into
	 * optPtr->name.
	 */

	expandedOption = option = Tcl_GetStringFromObj(objv[index], &length);
	if (option[0] != '-') {
	    if (optPtr->name == NULL) {
		optPtr->name = objv[index];
		continue;
	    }
	    break;
	}
1570
1571
1572
1573
1574
1575
1576











1577
1578
1579
1580
1581
1582
1583
	     */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->format = objv[index];











	} else if (bit == OPT_COMPOSITE) {
	    /*
	     * The -compositingrule option takes a single value from a
	     * well-known set.
	     */

	    if (index + 1 >= objc) {







>
>
>
>
>
>
>
>
>
>
>







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
	     */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->format = objv[index];
	} else if (bit == OPT_METADATA) {
	    /*
	    * The -metadata option takes a single dict value. Note that
	    * parsing this is outside the scope of this function.
	    */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->metadata = objv[index];
	} else if (bit == OPT_COMPOSITE) {
	    /*
	     * The -compositingrule option takes a single value from a
	     * well-known set.
	     */

	    if (index + 1 >= objc) {
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
    /*
     * Exception generation.
     */

  oneValueRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires a value", expandedOption));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL);
    return TCL_ERROR;

  manyValuesRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires one %s integer values",
	    expandedOption, (maxValues == 2) ? "or two": "to four"));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL);
    return TCL_ERROR;

  numberOutOfRange:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "value(s) for the %s option must be %s", expandedOption, needed));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_VALUE", NULL);
    return TCL_ERROR;

  unknownOrAmbiguousOption:
    msgObj = Tcl_ObjPrintf("unrecognized option \"%s\": must be ", option);
    bit = 1;
    for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
	if (allowedOptions & bit) {
	    if (allowedOptions & (bit - 1)) {
		if (allowedOptions & ~((bit << 1) - 1)) {
		    Tcl_AppendToObj(msgObj, ", ", -1);
		} else {
		    Tcl_AppendToObj(msgObj, ", or ", -1);
		}
	    }
	    Tcl_AppendToObj(msgObj, *listPtr, -1);
	}
	bit <<= 1;
    }
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureModel --







|






|





|









|

|


|




|







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
    /*
     * Exception generation.
     */

  oneValueRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires a value", expandedOption));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", (char *)NULL);
    return TCL_ERROR;

  manyValuesRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires one %s integer values",
	    expandedOption, (maxValues == 2) ? "or two": "to four"));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", (char *)NULL);
    return TCL_ERROR;

  numberOutOfRange:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "value(s) for the %s option must be %s", expandedOption, needed));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_VALUE", (char *)NULL);
    return TCL_ERROR;

  unknownOrAmbiguousOption:
    msgObj = Tcl_ObjPrintf("unrecognized option \"%s\": must be ", option);
    bit = 1;
    for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
	if (allowedOptions & bit) {
	    if (allowedOptions & (bit - 1)) {
		if (allowedOptions & ~((bit << 1) - 1)) {
		    Tcl_AppendToObj(msgObj, ", ", TCL_INDEX_NONE);
		} else {
		    Tcl_AppendToObj(msgObj, ", or ", TCL_INDEX_NONE);
		}
	    }
	    Tcl_AppendToObj(msgObj, *listPtr, TCL_INDEX_NONE);
	}
	bit <<= 1;
    }
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", (char *)NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureModel --
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
 */

static int
ImgPhotoConfigureModel(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    PhotoModel *modelPtr,	/* Pointer to data structure describing
				 * overall photo image to (re)configure. */
    int objc,			/* Number of entries in objv. */
    Tcl_Obj *const objv[],	/* Pairs of configuration options for image. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    PhotoInstance *instancePtr;
    const char *oldFileString, *oldPaletteString;
    Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL;

    Tcl_Obj *tempdata, *tempformat;
    TkSizeT length;
    int i, j, result, imageWidth, imageHeight, oldformat;
    double oldGamma;
    Tcl_Channel chan;
    Tk_PhotoImageFormat *imageFormat;
    const char **args;

    args = (const char **)ckalloc((objc + 1) * sizeof(char *));
    for (i = 0, j = 0; i < objc; i++,j++) {
	args[j] = TkGetStringFromObj(objv[i], &length);
	if ((length > 1) && (args[j][0] == '-')) {
	    if ((args[j][1] == 'd') &&
		    !strncmp(args[j], "-data", length)) {
		if (++i < objc) {
		    data = objv[i];
		    j--;
		} else {
		    ckfree(args);
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "value for \"-data\" missing", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "MISSING_VALUE", NULL);
		    return TCL_ERROR;
		}
	    } else if ((args[j][1] == 'f') &&
		    !strncmp(args[j], "-format", length)) {
		if (++i < objc) {
		    format = objv[i];
		    j--;
		} else {
		    ckfree(args);
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "value for \"-format\" missing", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "MISSING_VALUE", NULL);











		    return TCL_ERROR;
		}
	    }
	}
    }

    /*







|






|
>

|
|



|

<
|
|
|
|
|


<

<

|

|


|
|


<

<

|

|
>
>
>
>
>
>
>
>
>
>
>







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
 */

static int
ImgPhotoConfigureModel(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    PhotoModel *modelPtr,	/* Pointer to data structure describing
				 * overall photo image to (re)configure. */
    Tcl_Size objc,			/* Number of entries in objv. */
    Tcl_Obj *const objv[],	/* Pairs of configuration options for image. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    PhotoInstance *instancePtr;
    const char *oldFileString, *oldPaletteString;
    Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL,
	    *metadataInObj = NULL, *metadataOutObj = NULL;
    Tcl_Obj *tempdata, *tempformat;
    Tcl_Size i, length;
    int result, imageWidth, imageHeight, oldformat;
    double oldGamma;
    Tcl_Channel chan;
    Tk_PhotoImageFormat *imageFormat;
    Tk_PhotoImageFormatVersion3 *imageFormatVersion3;


    for (i = 0; i < objc; i++) {
	const char *arg = Tcl_GetStringFromObj(objv[i], &length);
	if ((length > 1) && (arg[0] == '-')) {
	    if ((arg[1] == 'd') &&
		    !strncmp(arg, "-data", length)) {
		if (++i < objc) {
		    data = objv[i];

		} else {

		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "value for \"-data\" missing", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "MISSING_VALUE", (char *)NULL);
		    return TCL_ERROR;
		}
	    } else if ((arg[1] == 'f') &&
		    !strncmp(arg, "-format", length)) {
		if (++i < objc) {
		    format = objv[i];

		} else {

		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "value for \"-format\" missing", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "MISSING_VALUE", (char *)NULL);
		    return TCL_ERROR;
		}
	    } else if ((arg[1] == 'm') &&
		!strncmp(arg, "-metadata", length)) {
		if (++i < objc) {
		    metadataInObj = objv[i];
		} else {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"value for \"-metadata\" missing", TCL_INDEX_NONE));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"MISSING_VALUE", (char *)NULL);
		    return TCL_ERROR;
		}
	    }
	}
    }

    /*
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
    oldGamma = modelPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    j, args, (char *) modelPtr, flags) != TCL_OK) {
	ckfree(args);
	goto errorExit;
    }
    ckfree(args);

    /*
     * Regard the empty string for -file, -data or -format as the null value.
     */

    if ((modelPtr->fileString != NULL) && (modelPtr->fileString[0] == 0)) {
	ckfree(modelPtr->fileString);
	modelPtr->fileString = NULL;
    }
    if (data) {
	/*
	 * Force into ByteArray format, which most (all) image handlers will
	 * use anyway. Empty length means ignore the -data option.
	 */
	TkSizeT bytesize;

	(void) TkGetByteArrayFromObj(data, &bytesize);
	if (bytesize) {
	    Tcl_IncrRefCount(data);
	} else {
	    data = NULL;
	}
	if (modelPtr->dataString) {
	    Tcl_DecrRefCount(modelPtr->dataString);







|
<


<


|











|

|







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
    oldGamma = modelPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    objc, objv, modelPtr, flags) != TCL_OK) {

	goto errorExit;
    }


    /*
     * Regard the empty string for -file, -data, -format or -metadata as the null value.
     */

    if ((modelPtr->fileString != NULL) && (modelPtr->fileString[0] == 0)) {
	ckfree(modelPtr->fileString);
	modelPtr->fileString = NULL;
    }
    if (data) {
	/*
	 * Force into ByteArray format, which most (all) image handlers will
	 * use anyway. Empty length means ignore the -data option.
	 */
	Tcl_Size bytesize;

	(void) Tcl_GetByteArrayFromObj(data, &bytesize);
	if (bytesize) {
	    Tcl_IncrRefCount(data);
	} else {
	    data = NULL;
	}
	if (modelPtr->dataString) {
	    Tcl_DecrRefCount(modelPtr->dataString);
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
	    format = NULL;
	}
	if (modelPtr->format) {
	    Tcl_DecrRefCount(modelPtr->format);
	}
	modelPtr->format = format;
    }


























    /*
     * Set the image to the user-requested size, if any, and make sure storage
     * is correctly allocated for this image.
     */

    if (ImgPhotoSetSize(modelPtr, modelPtr->width,
	    modelPtr->height) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	goto errorExit;
    }

    /*
     * Read in the image from the file or string if the user has specified the
     * -file or -data option.
     */

    if ((modelPtr->fileString != NULL)
	    && ((modelPtr->fileString != oldFileString)
	    || (modelPtr->format != oldFormat))) {
	/*
	 * Prevent file system access in a safe interpreter.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL);
	    goto errorExit;
	}

	chan = Tcl_OpenFileChannel(interp, modelPtr->fileString, "r", 0);
	if (chan == NULL) {
	    goto errorExit;
	}








	/*
	 * -translation binary also sets -encoding binary
	 */

	if ((Tcl_SetChannelOption(interp, chan,
		"-translation", "binary") != TCL_OK) ||
		(MatchFileFormat(interp, chan, modelPtr->fileString,

			modelPtr->format, &imageFormat, &imageWidth,
			&imageHeight, &oldformat) != TCL_OK)) {
	    Tcl_Close(NULL, chan);
	    goto errorExit;
	}
	result = ImgPhotoSetSize(modelPtr, imageWidth, imageHeight);
	if (result != TCL_OK) {
	    Tcl_Close(NULL, chan);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}

	result = imageFormat->fileReadProc(interp, chan,
		modelPtr->fileString, tempformat, (Tk_PhotoHandle) modelPtr,

		0, 0, imageWidth, imageHeight, 0, 0);








	Tcl_Close(NULL, chan);
	if (result != TCL_OK) {
	    goto errorExit;
	}

	Tcl_ResetResult(interp);
	modelPtr->flags |= IMAGE_CHANGED;
    }

    if ((modelPtr->fileString == NULL) && (modelPtr->dataString != NULL)
	    && ((modelPtr->dataString != oldData)
		    || (modelPtr->format != oldFormat))) {








	if (MatchStringFormat(interp, modelPtr->dataString,

		modelPtr->format, &imageFormat, &imageWidth,
		&imageHeight, &oldformat) != TCL_OK) {
	    goto errorExit;
	}
	if (ImgPhotoSetSize(modelPtr, imageWidth, imageHeight) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	tempdata = modelPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	    }
	    tempdata = (Tcl_Obj *) Tcl_GetString(tempdata);
	}

	if (imageFormat->stringReadProc(interp, tempdata, tempformat,
		(Tk_PhotoHandle) modelPtr, 0, 0, imageWidth, imageHeight,
		0, 0) != TCL_OK) {
	    goto errorExit;
	}








	Tcl_ResetResult(interp);
	modelPtr->flags |= IMAGE_CHANGED;
    }












































    /*
     * Enforce a reasonable value for gamma.
     */

    if (modelPtr->gamma <= 0) {
	modelPtr->gamma = 1.0;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
|




















|








>
>
>
>
>
>
>







>
|
|







|
|






>
|
|
>
|
>
>
>
>
>
>
>
>













>
>
>
>
>
>
>

>
|





|
|










>
|
|
|
|
|
>
>
>
>
>
|
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	    format = NULL;
	}
	if (modelPtr->format) {
	    Tcl_DecrRefCount(modelPtr->format);
	}
	modelPtr->format = format;
    }
    if (metadataInObj) {
	/*
	 * Make -metadata a dict.
	 * Take also empty metadatas as this may be a sign to replace
	 * existing metadata.
	 */
	Tcl_Size dictSize;

	if (TCL_OK != Tcl_DictObjSize(interp,metadataInObj, &dictSize)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "value for \"-metadata\" not a dict", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		    "UNRECOGNIZED_DATA", (char *)NULL);
	    return TCL_ERROR;
	}

	if (dictSize > 0) {
	    Tcl_IncrRefCount(metadataInObj);
	} else {
	    metadataInObj = NULL;
	}
	if (modelPtr->metadata) {
	    Tcl_DecrRefCount(modelPtr->metadata);
	}
	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(modelPtr, modelPtr->width,
	    modelPtr->height) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	goto errorExit;
    }

    /*
     * Read in the image from the file or string if the user has specified the
     * -file or -data option.
     */

    if ((modelPtr->fileString != NULL)
	    && ((modelPtr->fileString != oldFileString)
	    || (modelPtr->format != oldFormat))) {
	/*
	 * Prevent file system access in a safe interpreter.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)NULL);
	    goto errorExit;
	}

	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, modelPtr->fileString,
			modelPtr->format, modelPtr->metadata, metadataOutObj,
			&imageFormat, &imageFormatVersion3,
			&imageWidth, &imageHeight, &oldformat) != TCL_OK)) {
	    Tcl_Close(NULL, chan);
	    goto errorExit;
	}
	result = ImgPhotoSetSize(modelPtr, imageWidth, imageHeight);
	if (result != TCL_OK) {
	    Tcl_Close(NULL, chan);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}
	if (imageFormat != NULL) {
	    result = imageFormat->fileReadProc(interp, chan,
		    modelPtr->fileString, tempformat,
		    (Tk_PhotoHandle) modelPtr,
		    0, 0, imageWidth, imageHeight, 0, 0);
	} else {
	    result = imageFormatVersion3->fileReadProc(interp, chan,
		    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);
	modelPtr->flags |= IMAGE_CHANGED;
    }

    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, modelPtr->dataString,
		modelPtr->format, modelPtr->metadata, metadataOutObj,
		&imageFormat, &imageFormatVersion3, &imageWidth,
		&imageHeight, &oldformat) != TCL_OK) {
	    goto errorExit;
	}
	if (ImgPhotoSetSize(modelPtr, imageWidth, imageHeight) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	tempdata = modelPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	    }
	    tempdata = (Tcl_Obj *) Tcl_GetString(tempdata);
	}
	if (imageFormat != NULL) {
	    if (imageFormat->stringReadProc(interp, tempdata, tempformat,
		    (Tk_PhotoHandle) modelPtr, 0, 0, imageWidth, imageHeight,
		    0, 0) != TCL_OK) {
		goto errorExit;
	    }
	} else {
	    if (imageFormatVersion3->stringReadProc(interp, tempdata, tempformat,
		    modelPtr->metadata, (Tk_PhotoHandle) modelPtr, 0, 0,
		    imageWidth, imageHeight, 0, 0, metadataOutObj) != TCL_OK) {
		goto errorExit;
	    }
	}

	Tcl_ResetResult(interp);
	modelPtr->flags |= IMAGE_CHANGED;
    }

    /*
     * Merge driver returned metadata and master metadata
     */
    if (metadataOutObj != NULL) {
	Tcl_Size dictSize;
	if (TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "driver metadata not a dict", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		    "UNRECOGNIZED_DATA", (char *)NULL);
	    goto errorExit;
	}
	if (dictSize > 0) {

	    /*
	     * We have driver return metadata
	     */

	    if (modelPtr->metadata == NULL) {
		modelPtr->metadata = metadataOutObj;
		metadataOutObj = NULL;
	    } else {
		Tcl_DictSearch search;
		Tcl_Obj *key, *value;
		int done;

		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, modelPtr->metadata, key, value);
		}
	    }
	}
    }

    /*
     * Enforce a reasonable value for gamma.
     */

    if (modelPtr->gamma <= 0) {
	modelPtr->gamma = 1.0;
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

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }




    ToggleComplexAlphaIfNeeded(modelPtr);

    return TCL_OK;

  errorExit:
    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }



    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ToggleComplexAlphaIfNeeded --







>
>
>












>
>
>







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

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }
    if (metadataOutObj != NULL) {
	Tcl_DecrRefCount(metadataOutObj);
    }

    ToggleComplexAlphaIfNeeded(modelPtr);

    return TCL_OK;

  errorExit:
    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
	Tcl_DecrRefCount(oldFormat);
    }
    if (metadataOutObj != NULL) {
	Tcl_DecrRefCount(metadataOutObj);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ToggleComplexAlphaIfNeeded --
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
static int
ToggleComplexAlphaIfNeeded(
    PhotoModel *mPtr)
{
    size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
	    (size_t)MAX(mPtr->userHeight, mPtr->height) * 4;
    unsigned char *c = mPtr->pix32;
    unsigned char *end = c + len;

    /*
     * Set the COMPLEX_ALPHA flag if we have an image with partially
     * transparent bits.
     */

    mPtr->flags &= ~COMPLEX_ALPHA;
    if (c == NULL) {
	return 0;
    }

    c += 3;			/* Start at first alpha byte. */
    for (; c < end; c += 4) {
	if (*c && *c != 255) {
     	    mPtr->flags |= COMPLEX_ALPHA;
	    break;
	}
    }







|










>







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
static int
ToggleComplexAlphaIfNeeded(
    PhotoModel *mPtr)
{
    size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
	    (size_t)MAX(mPtr->userHeight, mPtr->height) * 4;
    unsigned char *c = mPtr->pix32;
    unsigned char *end;

    /*
     * Set the COMPLEX_ALPHA flag if we have an image with partially
     * transparent bits.
     */

    mPtr->flags &= ~COMPLEX_ALPHA;
    if (c == NULL) {
	return 0;
    }
    end = c + len;
    c += 3;			/* Start at first alpha byte. */
    for (; c < end; c += 4) {
	if (*c && *c != 255) {
     	    mPtr->flags |= COMPLEX_ALPHA;
	    break;
	}
    }
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    ClientData modelData)	/* Pointer to PhotoModel structure for image.
				 * Must not have any more instances. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;

    while ((instancePtr = modelPtr->instancePtr) != NULL) {
	if (instancePtr->refCount > 0) {







|







2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    void *modelData)	/* Pointer to PhotoModel structure for image.
				 * Must not have any more instances. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;

    while ((instancePtr = modelPtr->instancePtr) != NULL) {
	if (instancePtr->refCount > 0) {
2141
2142
2143
2144
2145
2146
2147



2148
2149
2150
2151
2152
2153
2154
2155
    }
    if (modelPtr->dataString != NULL) {
	Tcl_DecrRefCount(modelPtr->dataString);
    }
    if (modelPtr->format != NULL) {
	Tcl_DecrRefCount(modelPtr->format);
    }



    Tk_FreeOptions(configSpecs, (char *) modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmdDeletedProc --







>
>
>
|







2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
    }
    if (modelPtr->dataString != NULL) {
	Tcl_DecrRefCount(modelPtr->dataString);
    }
    if (modelPtr->format != NULL) {
	Tcl_DecrRefCount(modelPtr->format);
    }
    if (modelPtr->metadata != NULL) {
	Tcl_DecrRefCount(modelPtr->metadata);
    }
    Tk_FreeOptions(configSpecs, modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoCmdDeletedProc --
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    ClientData clientData)	/* Pointer to PhotoModel structure for
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));







|







2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    void *clientData)	/* Pointer to PhotoModel structure for
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
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
 *	This function is called to find a photo image file format handler
 *	which can parse the image data in the given file. If a user-specified
 *	format string is provided, only handlers whose names match a prefix of
 *	the format string are tried.
 *
 * Results:
 *	A standard TCL return value. If the return value is TCL_OK, a pointer
 *	to the image format record is returned in *imageFormatPtr, and the
 *	width and height of the image are returned in *widthPtr and
 *	*heightPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MatchFileFormat(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *formatObj,		/* User-specified format string, or NULL. */


    Tk_PhotoImageFormat **imageFormatPtr,
				/* A pointer to the photo image format record
				 * is returned here. */





    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here. */
    int *oldformat)		/* Returns 1 if the old image API is used. */
{
    int matched = 0;
    int useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *formatString = NULL;

    if (formatObj) {
	formatString = Tcl_GetString(formatObj);
    }







|
|
|













>
>


|
>
>
>
>
>








>







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
 *	This function is called to find a photo image file format handler
 *	which can parse the image data in the given file. If a user-specified
 *	format string is provided, only handlers whose names match a prefix of
 *	the format string are tried.
 *
 * Results:
 *	A standard TCL return value. If the return value is TCL_OK, a pointer
 *	to the image format record is returned in *imageFormatPtr or
 *	*imageFormatVersion3Ptr, and the width and height of the image are
 *	returned in *widthPtr and *heightPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MatchFileFormat(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *formatObj,		/* User-specified format string, or NULL. */
    Tcl_Obj *metadataInObj,	/* User-specified metadata, may be NULL */
    Tcl_Obj *metadataOutObj,	/* metadata to return, may be NULL */
    Tk_PhotoImageFormat **imageFormatPtr,
				/* A pointer to the photo image format record
				 * is returned here. For formatVersion3, this is
				 * set to NULL */
    Tk_PhotoImageFormatVersion3 **imageFormatVersion3Ptr,
				/* A pointer to the photo image formatVersion3
				 * record is returned here. For non
				 * formatVersion3, this is set to NULL*/
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here. */
    int *oldformat)		/* Returns 1 if the old image API is used. */
{
    int matched = 0;
    int useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr;
    Tk_PhotoImageFormatVersion3 *formatVersion3Ptr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *formatString = NULL;

    if (formatObj) {
	formatString = Tcl_GetString(formatObj);
    }
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
	    }
	    matched = 1;
	    if (formatPtr->fileMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-file option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_FILE_FORMAT", NULL);
		return TCL_ERROR;
	    }
	}
	if (formatPtr->fileMatchProc != NULL) {
	    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);

	    if (formatPtr->fileMatchProc(chan, fileName, formatObj,
		    widthPtr, heightPtr, interp)) {
		if (*widthPtr < 1) {
		    *widthPtr = 1;
		}
		if (*heightPtr < 1) {
		    *heightPtr = 1;
		}
		break;
	    }
	}
    }
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9




if (formatPtr == NULL) {


	useoldformat = 1;



	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;




		formatPtr = formatPtr->nextPtr) {



	    if (formatString != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {

		    continue;
		}
		matched = 1;
		if (formatPtr->fileMatchProc == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "-file option isn't supported for %s images",
			    formatString));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "NOT_FILE_FORMAT", NULL);
		    return TCL_ERROR;
		}
	    }
	    if (formatPtr->fileMatchProc != NULL) {
		(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
		if (formatPtr->fileMatchProc(chan, fileName, (Tcl_Obj *)

			formatString, widthPtr, heightPtr, interp)) {

		    if (*widthPtr < 1) {
			*widthPtr = 1;
		    }
		    if (*heightPtr < 1) {
			*heightPtr = 1;
		    }






		    break;




		}








	    }
	}
    }
#endif

    if (formatPtr == NULL) {




	if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image file format \"%s\" is not supported",
		    formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, NULL);
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "couldn't recognize data in image file \"%s\"",
		    fileName));
	    Tcl_SetErrorCode(interp, "TK", "PHOTO", "IMAGE",
		    "UNRECOGNIZED_DATA", NULL);
	}
	return TCL_ERROR;
    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;
    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * MatchStringFormat --
 *
 *	This function is called to find a photo image file format handler
 *	which can parse the image data in the given string. If a
 *	user-specified format string is provided, only handlers whose names
 *	match a prefix of the format string are tried.
 *
 * Results:
 *	A standard TCL return value. If the return value is TCL_OK, a pointer
 *	to the image format record is returned in *imageFormatPtr, and the
 *	width and height of the image are returned in *widthPtr and
 *	*heightPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MatchStringFormat(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *data,		/* Object containing the image data. */
    Tcl_Obj *formatObj,		/* User-specified format string, or NULL. */


    Tk_PhotoImageFormat **imageFormatPtr,
				/* A pointer to the photo image format record
				 * is returned here. */





    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here. */
    int *oldformat)		/* Returns 1 if the old image API is used. */
{
    int matched = 0, useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *formatString = NULL;

    if (formatObj) {
	formatString = Tcl_GetString(formatObj);
    }







|


















|
>
>
>
>
|
>
>
|
>
>
>
|
>
>
>
>
|
>
>
>
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
|
|
|
|
|
|
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
|
|
|
<
|
|
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<














|
|
|












>
>


|
>
>
>
>
>







>







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
	    }
	    matched = 1;
	    if (formatPtr->fileMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-file option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_FILE_FORMAT", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (formatPtr->fileMatchProc != NULL) {
	    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);

	    if (formatPtr->fileMatchProc(chan, fileName, formatObj,
		    widthPtr, heightPtr, interp)) {
		if (*widthPtr < 1) {
		    *widthPtr = 1;
		}
		if (*heightPtr < 1) {
		    *heightPtr = 1;
		}
		break;
	    }
	}
    }

    /*
     * For old and not version 3 format, exit now with success
     */

    if (formatPtr != NULL) {
	*imageFormatPtr = formatPtr;
	*imageFormatVersion3Ptr = NULL;
	*oldformat = useoldformat;
	(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
	return TCL_OK;
    }

    /*
     * Scan through the table of file format version 3 handlers to find one
     * which can handle the image.
     */

    for (formatVersion3Ptr = tsdPtr->formatListVersion3;
	    formatVersion3Ptr != NULL;
	    formatVersion3Ptr = formatVersion3Ptr->nextPtr) {
	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatVersion3Ptr->name, strlen(formatVersion3Ptr->name))
		    != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatVersion3Ptr->fileMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-file option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_FILE_FORMAT", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (formatVersion3Ptr->fileMatchProc != NULL) {
	    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);

	    if (formatVersion3Ptr->fileMatchProc(interp, chan, fileName,
		    formatObj, metadataInObj, widthPtr, heightPtr,
		    metadataOutObj)) {
		if (*widthPtr < 1) {
		    *widthPtr = 1;
		}
		if (*heightPtr < 1) {
		    *heightPtr = 1;
		}
		*imageFormatVersion3Ptr = formatVersion3Ptr;
		*imageFormatPtr = NULL;
		*oldformat = 0;
		(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
		return TCL_OK;
	    }

	    /*
	     * Check if driver has shared or changed the metadata Tcl object.
	     * In this case, release and recreate it.
	     */

	    if (metadataOutObj != NULL) {
		Tcl_Size dictSize;
		if (Tcl_IsShared(metadataOutObj)
			|| TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)
			|| dictSize > 0) {
		    Tcl_DecrRefCount(metadataOutObj);
		    metadataOutObj = Tcl_NewDictObj();
		    Tcl_IncrRefCount(metadataOutObj);
		}
	    }
	}

    }

    /*
     * No matching format found
     */

    if ((formatObj != NULL) && !matched) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image file format \"%s\" is not supported",
		formatString));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		formatString, (char *)NULL);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't recognize data in image file \"%s\"",
		fileName));
	Tcl_SetErrorCode(interp, "TK", "PHOTO", "IMAGE",
		"UNRECOGNIZED_DATA", (char *)NULL);
    }
    return TCL_ERROR;






}

/*
 *----------------------------------------------------------------------
 *
 * MatchStringFormat --
 *
 *	This function is called to find a photo image file format handler
 *	which can parse the image data in the given string. If a
 *	user-specified format string is provided, only handlers whose names
 *	match a prefix of the format string are tried.
 *
 * Results:
 *	A standard TCL return value. If the return value is TCL_OK, a pointer
 *	to the image format record is returned in *imageFormatPtr or
 *	*imageFormatVersion3Ptr, and the width and height of the image are
 *	returned in *widthPtr and *heightPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MatchStringFormat(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *data,		/* Object containing the image data. */
    Tcl_Obj *formatObj,		/* User-specified format string, or NULL. */
    Tcl_Obj *metadataInObj,	/* User-specified metadata, may be NULL */
    Tcl_Obj *metadataOutObj,	/* metadata output dict, may be NULL */
    Tk_PhotoImageFormat **imageFormatPtr,
				/* A pointer to the photo image format record
				 * is returned here. For formatVersion3, this is
				 * set to NULL*/
    Tk_PhotoImageFormatVersion3 **imageFormatVersion3Ptr,
				/* A pointer to the photo image formatVersion3
				 * record is returned here. For non
				 * formatVersion3, this is set to NULL*/
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here. */
    int *oldformat)		/* Returns 1 if the old image API is used. */
{
    int matched = 0, useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL;
    Tk_PhotoImageFormatVersion3 *formatVersion3Ptr = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *formatString = NULL;

    if (formatObj) {
	formatString = Tcl_GetString(formatObj);
    }
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
	    }
	    matched = 1;
	    if (formatPtr->stringMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-data option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_DATA_FORMAT", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * If this is the default format, and it was not passed as -format
	 * option, skip the stringMatchProc test. It'll be done later







|







2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
	    }
	    matched = 1;
	    if (formatPtr->stringMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-data option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_DATA_FORMAT", (char *)NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * If this is the default format, and it was not passed as -format
	 * option, skip the stringMatchProc test. It'll be done later
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
		&& (formatPtr->stringReadProc != NULL)
		&& formatPtr->stringMatchProc(data, formatObj,
			widthPtr, heightPtr, interp)) {
	    break;
	}
    }

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    if (formatPtr == NULL) {
	useoldformat = 1;

	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatObj != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {

		    continue;
		}
		matched = 1;
		if (formatPtr->stringMatchProc == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "-data option isn't supported for %s images",
			    formatString));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "NOT_DATA_FORMAT", NULL);
		    return TCL_ERROR;
		}
	    }
	    if ((formatPtr->stringMatchProc != NULL)
		    && (formatPtr->stringReadProc != NULL)
		    && formatPtr->stringMatchProc(
			    (Tcl_Obj *) Tcl_GetString(data),
			    (Tcl_Obj *) formatString,
			    widthPtr, heightPtr, interp)) {

		break;
	    }
	}




    }

#endif











    if (formatPtr == NULL) {
	/*
	 * Try the default format as last resort (only if no -format option
	 * was passed).
	 */

	if ( formatObj == NULL && defaultFormatPtr == NULL) {
	    Tcl_Panic("default image format handler not registered");
	}
	if ( formatObj == NULL
		&& defaultFormatPtr->stringMatchProc != NULL
		&& defaultFormatPtr->stringReadProc != NULL
		&& defaultFormatPtr->stringMatchProc(data, formatObj,
		widthPtr, heightPtr, interp) != 0) {
	    useoldformat = 0;
	    formatPtr = defaultFormatPtr;
	} else if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image format \"%s\" is not supported", formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, NULL);
	    return TCL_ERROR;
	} else {

            /*
             * Some lower level routine (stringMatchProc) may have already set
             * a specific error message, so just return this. Otherwise return
             * a generic image data error.
             */

            if (Tcl_GetString(Tcl_GetObjResult(interp))[0] == '\0') {
                Tcl_SetObjResult(interp, Tcl_NewStringObj(
                        "couldn't recognize image data", -1));
	        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		        "UNRECOGNIZED_DATA", NULL);
            }
	    return TCL_ERROR;
	}
    }

    *imageFormatPtr = formatPtr;

    *oldformat = useoldformat;

    /*
     * Some stringMatchProc might have left error messages and error codes in
     * interp.	Clear them before return.
     */
    Tcl_ResetResult(interp);







<

|
>
|
|


|
>



|




|



|
|
|
<
<
|
>


|
>
>
>
>
|
>
|
>
>
>
>
>
>
|
>
>
>
>
|



















|



|
|
|
|
|

|
|
|
|
|
|





>







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
		&& (formatPtr->stringReadProc != NULL)
		&& formatPtr->stringMatchProc(data, formatObj,
			widthPtr, heightPtr, interp)) {
	    break;
	}
    }


    if (formatPtr == NULL) {
	useoldformat = 0;
	for (formatVersion3Ptr = tsdPtr->formatListVersion3;
		formatVersion3Ptr != NULL;
		formatVersion3Ptr = formatVersion3Ptr->nextPtr) {
	    if (formatObj != NULL) {
		if (strncasecmp(formatString,
			formatVersion3Ptr->name, strlen(formatVersion3Ptr->name)
			) != 0) {
		    continue;
		}
		matched = 1;
		if (formatVersion3Ptr->stringMatchProc == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "-data option isn't supported for %s images",
			    formatString));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "NOT_DATA_FORMAT", (char *)NULL);
		    return TCL_ERROR;
		}
	    }
	    if ((formatVersion3Ptr->stringMatchProc != NULL)
		    && (formatVersion3Ptr->stringReadProc != NULL)
		    && formatVersion3Ptr->stringMatchProc(interp, data,


			    formatObj, metadataInObj, widthPtr, heightPtr,
			    metadataOutObj)) {
		break;
	    }

	    /*
	     * Check if driver has shared or changed the metadata tcl object.
	     * In this case, release and recreate it.
	     */

	    if (metadataOutObj != NULL) {
		Tcl_Size dictSize;
		if (Tcl_IsShared(metadataOutObj)
			|| TCL_OK != Tcl_DictObjSize(interp,metadataOutObj, &dictSize)
			|| dictSize > 0) {
		    Tcl_DecrRefCount(metadataOutObj);
		    metadataOutObj = Tcl_NewDictObj();
		    Tcl_IncrRefCount(metadataOutObj);
		}
	    }
	}
    }

    if (formatPtr == NULL && formatVersion3Ptr == NULL) {
	/*
	 * Try the default format as last resort (only if no -format option
	 * was passed).
	 */

	if ( formatObj == NULL && defaultFormatPtr == NULL) {
	    Tcl_Panic("default image format handler not registered");
	}
	if ( formatObj == NULL
		&& defaultFormatPtr->stringMatchProc != NULL
		&& defaultFormatPtr->stringReadProc != NULL
		&& defaultFormatPtr->stringMatchProc(data, formatObj,
		widthPtr, heightPtr, interp) != 0) {
	    useoldformat = 0;
	    formatPtr = defaultFormatPtr;
	} else if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image format \"%s\" is not supported", formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, (char *)NULL);
	    return TCL_ERROR;
	} else {

	    /*
	     * Some lower level routine (stringMatchProc) may have already set
	     * a specific error message, so just return this. Otherwise return
	     * a generic image data error.
	     */

	    if (Tcl_GetString(Tcl_GetObjResult(interp))[0] == '\0') {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't recognize image data", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"UNRECOGNIZED_DATA", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
    }

    *imageFormatPtr = formatPtr;
    *imageFormatVersion3Ptr = formatVersion3Ptr;
    *oldformat = useoldformat;

    /*
     * Some stringMatchProc might have left error messages and error codes in
     * interp.	Clear them before return.
     */
    Tcl_ResetResult(interp);
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
Tk_PhotoHandle
Tk_FindPhoto(
    Tcl_Interp *interp,		/* Interpreter (application) in which image
				 * exists. */
    const char *imageName)	/* Name of the desired photo image. */
{
    const Tk_ImageType *typePtr;
    ClientData clientData =
	    Tk_GetImageModelData(interp, imageName, &typePtr);

    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return clientData;
}







|







3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
Tk_PhotoHandle
Tk_FindPhoto(
    Tcl_Interp *interp,		/* Interpreter (application) in which image
				 * exists. */
    const char *imageName)	/* Name of the desired photo image. */
{
    const Tk_ImageType *typePtr;
    void *clientData =
	    Tk_GetImageModelData(interp, imageName, &typePtr);

    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return clientData;
}
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (sourceBlock.pixelPtr >= modelPtr->pix32
	    && sourceBlock.pixelPtr <= modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }


    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {







|
|
|


















|
|















|
|







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
     *
     * 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 (modelPtr->pix32 && (sourceBlock.pixelPtr >= modelPtr->pix32)
	    && (sourceBlock.pixelPtr < modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4)) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }


    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
    /*
     * Add this new block to the region which specifies which data is valid.
     */

    if (alphaOffset) {
	/*
	 * This block is grossly inefficient. For each row in the image, it
	 * finds each continguous string of nontransparent pixels, then marks
	 * those areas as valid in the validRegion mask. This makes drawing
	 * very efficient, because of the way we use X: we just say, here's
	 * your mask, and here's your data. We need not worry about the
	 * current background color, etc. But this costs us a lot on the image
	 * setup. Still, image setup only happens once, whereas the drawing
	 * happens many times, so this might be the best way to go.
	 *







|







3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
    /*
     * Add this new block to the region which specifies which data is valid.
     */

    if (alphaOffset) {
	/*
	 * This block is grossly inefficient. For each row in the image, it
	 * finds each contiguous string of nontransparent pixels, then marks
	 * those areas as valid in the validRegion mask. This makes drawing
	 * very efficient, because of the way we use X: we just say, here's
	 * your mask, and here's your data. We need not worry about the
	 * current background color, etc. But this costs us a lot on the image
	 * setup. Still, image setup only happens once, whereas the drawing
	 * happens many times, so this might be the best way to go.
	 *
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
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (sourceBlock.pixelPtr >= modelPtr->pix32
	    && sourceBlock.pixelPtr <= modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }

    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {







|
|
|


















|
|














|
|







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
     *
     * 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 (modelPtr->pix32 && (sourceBlock.pixelPtr >= modelPtr->pix32)
	    && (sourceBlock.pixelPtr < modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4)) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }

    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
3634
3635
3636
3637
3638
3639
3640

3641
3642

3643
3644
3645
3646
3647
3648
3649
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */


    memset(modelPtr->pix32, 0,
	    ((size_t)modelPtr->width * modelPtr->height * 4));

    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgResetDither(instancePtr);
    }

    /*
     * Tell the core image code that this image has changed.







>
|
|
>







3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */

    if (modelPtr->pix32) {
	memset(modelPtr->pix32, 0,
		((size_t)modelPtr->width * modelPtr->height * 4));
    }
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgResetDither(instancePtr);
    }

    /*
     * Tell the core image code that this image has changed.
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
	height = modelPtr->height;
    }
    if ((width != modelPtr->width) || (height != modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(width, modelPtr->width),
		MAX(height, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    }
	    return TCL_ERROR;
	}
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }
    return TCL_OK;







|
|







4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
	height = modelPtr->height;
    }
    if ((width != modelPtr->width) || (height != modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(width, modelPtr->width),
		MAX(height, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }
    return TCL_OK;
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779

    modelPtr->userWidth = width;
    modelPtr->userHeight = height;
    if (ImgPhotoSetSize(modelPtr, ((width > 0) ? width: modelPtr->width),
	    ((height > 0) ? height: modelPtr->height)) == TCL_ERROR) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	}
	return TCL_ERROR;
    }
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
	    modelPtr->width, modelPtr->height);
    return TCL_OK;
}







|
|







4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090

    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, TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	}
	return TCL_ERROR;
    }
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
	    modelPtr->width, modelPtr->height);
    return TCL_OK;
}
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
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImgPhotoPostscript(
    ClientData clientData,	/* Handle for the photo image. */
    Tcl_Interp *interp,		/* Interpreter. */
    TCL_UNUSED(Tk_Window),		/* (unused) */
    Tk_PostscriptInfo psInfo,	/* Postscript info. */
    int x, int y,		/* First pixel to output. */
    int width, int height,	/* Width and height of area. */
    TCL_UNUSED(int))		/* (unused) */
{
    Tk_PhotoImageBlock block;

    Tk_PhotoGetImage(clientData, &block);
    block.pixelPtr += y * block.pitch + x * block.pixelSize;

    return Tk_PostscriptPhoto(interp, &block, psInfo, width, height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutBlock_NoComposite, Tk_PhotoPutZoomedBlock_NoComposite --
 *
 * These backward-compatability functions just exist to fill slots in stubs
 * table. For the behaviour of *_NoComposite, refer to the corresponding
 * function without the extra suffix, except that the compositing rule is
 * always "overlay" and the function always panics on memory-allocation
 * failure.
 *
 *----------------------------------------------------------------------
 */
#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
void
Tk_PhotoPutBlock_NoComposite(
    Tk_PhotoHandle handle,
    Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height)
{
    if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,
	    TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}

void
Tk_PhotoPutZoomedBlock_NoComposite(
    Tk_PhotoHandle handle,
    Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height,
    int zoomX, int zoomY, int subsampleX, int subsampleY)
{
    if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height,
	    zoomX, zoomY, subsampleX, subsampleY,
	    TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic,
 * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic
 *
 * Backward compatability functions for preserving the old behaviour (i.e.
 * panic on memory allocation failure) so that extensions do not need to be
 * significantly updated to take account of TIP #116. These call the new
 * interface (i.e. the interface without the extra suffix), but panic if an
 * error condition is returned.
 *
 *----------------------------------------------------------------------
 */

void
Tk_PhotoExpand_Panic(
    Tk_PhotoHandle handle,
    int width, int height)
{
    if (Tk_PhotoExpand(NULL, handle, width, height) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}

void
Tk_PhotoPutBlock_Panic(
    Tk_PhotoHandle handle,
    Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height, int compRule)
{
    if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,
	    compRule) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}

void
Tk_PhotoPutZoomedBlock_Panic(
    Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height,
    int zoomX, int zoomY, int subsampleX, int subsampleY,
    int compRule)
{
    if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height,
	    zoomX, zoomY, subsampleX, subsampleY, compRule) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}

void
Tk_PhotoSetSize_Panic(
    Tk_PhotoHandle handle,
    int width, int height)
{
    if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}
#endif /* TK_NO_DEPRECATED */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * tab-width: 8
 * End:
 */







|
















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImgPhotoPostscript(
    void *clientData,	/* Handle for the photo image. */
    Tcl_Interp *interp,		/* Interpreter. */
    TCL_UNUSED(Tk_Window),		/* (unused) */
    Tk_PostscriptInfo psInfo,	/* Postscript info. */
    int x, int y,		/* First pixel to output. */
    int width, int height,	/* Width and height of area. */
    TCL_UNUSED(int))		/* (unused) */
{
    Tk_PhotoImageBlock block;

    Tk_PhotoGetImage(clientData, &block);
    block.pixelPtr += y * block.pitch + x * block.pixelSize;

    return Tk_PostscriptPhoto(interp, &block, psInfo, width, height);
}

/*





































































































 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * tab-width: 8
 * End:
 */

Changes to generic/tkImgPhoto.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * tkImgPhoto.h --
 *
 *	Declarations for images of type "photo" for Tk.
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2008 Donal K. Fellows
 * Copyright (c) 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Author: Paul Mackerras ([email protected]),
 *	   Department of Computer Science,
 *	   Australian National University.





|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * tkImgPhoto.h --
 *
 *	Declarations for images of type "photo" for Tk.
 *
 * 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.
155
156
157
158
159
160
161


162
163
164
165
166
167
168
    Tk_Uid palette;		/* User-specified default palette for
				 * instances of this image. */
    double gamma;		/* Display gamma value to correct for. */
    char *fileString;		/* Name of file to read into image. */
    Tcl_Obj *dataString;	/* Object to use as contents of image. */
    Tcl_Obj *format;		/* User-specified format of data in image file
				 * or string value. */


    unsigned char *pix32;	/* Local storage for 32-bit image. */
    int ditherX, ditherY;	/* Location of first incorrectly dithered
				 * pixel in image. */
    TkRegion validRegion;	/* Tk region indicating which parts of the
				 * image have valid image data. */
    PhotoInstance *instancePtr;	/* First in the list of instances associated
				 * with this model. */







>
>







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    Tk_Uid palette;		/* User-specified default palette for
				 * instances of this image. */
    double gamma;		/* Display gamma value to correct for. */
    char *fileString;		/* Name of file to read into image. */
    Tcl_Obj *dataString;	/* Object to use as contents of image. */
    Tcl_Obj *format;		/* User-specified format of data in image file
				 * or string value. */
    Tcl_Obj *metadata;		/* User-specified metadata dict or read from
				 * 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 model. */
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
 * Declarations of functions shared between the different parts of the
 * photo image implementation.
 */

MODULE_SCOPE void	TkImgPhotoConfigureInstance(
			    PhotoInstance *instancePtr);
MODULE_SCOPE void	TkImgDisposeInstance(ClientData clientData);
MODULE_SCOPE void	TkImgPhotoInstanceSetSize(PhotoInstance *instancePtr);
MODULE_SCOPE ClientData	TkImgPhotoGet(Tk_Window tkwin, ClientData clientData);
MODULE_SCOPE void	TkImgDitherInstance(PhotoInstance *instancePtr, int x,
			    int y, int width, int height);
MODULE_SCOPE void	TkImgPhotoDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width, int height,
			    int drawableX, int drawableY);
MODULE_SCOPE void	TkImgPhotoFree(ClientData clientData,
			    Display *display);
MODULE_SCOPE void	TkImgResetDither(PhotoInstance *instancePtr);

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

|


|



|










243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
 * Declarations of functions shared between the different parts of the
 * photo image implementation.
 */

MODULE_SCOPE void	TkImgPhotoConfigureInstance(
			    PhotoInstance *instancePtr);
MODULE_SCOPE void	TkImgDisposeInstance(void *clientData);
MODULE_SCOPE void	TkImgPhotoInstanceSetSize(PhotoInstance *instancePtr);
MODULE_SCOPE void *TkImgPhotoGet(Tk_Window tkwin, void *clientData);
MODULE_SCOPE void	TkImgDitherInstance(PhotoInstance *instancePtr, int x,
			    int y, int width, int height);
MODULE_SCOPE void	TkImgPhotoDisplay(void *clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width, int height,
			    int drawableX, int drawableY);
MODULE_SCOPE void	TkImgPhotoFree(void *clientData,
			    Display *display);
MODULE_SCOPE void	TkImgResetDither(PhotoInstance *instancePtr);

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkImgSVGnano.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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 Christian Werner https://www.androwish.org/
 * Copyright (c) 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
 *





|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * tkImgSVGnano.c
 *
 *	A photo file handler for SVG files.
 *
 * 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
 *
42
43
44
45
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99








































100
101
102
103
104
105
106
 */

typedef struct {
    /* A poiner to remember if it is the same svn image (data)
     * It is a Tcl_Channel if image created by -file option
     * or a Tcl_Obj, if image is created with the -data option
     */
    ClientData dataOrChan;
    Tcl_DString formatString;
    NSVGimage *nsvgImage;
    RastOpts ropts;
} NSVGcache;



static int		FileMatchSVG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *format, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		FileReadSVG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *format,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);
static int		StringMatchSVG(Tcl_Obj *dataObj, Tcl_Obj *format,
			    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int		StringReadSVG(Tcl_Interp *interp, Tcl_Obj *dataObj,
			    Tcl_Obj *format, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static NSVGimage *	ParseSVGWithOptions(Tcl_Interp *interp,
			    const char *input, TkSizeT length, Tcl_Obj *format,
			    RastOpts *ropts);
static int		RasterizeSVG(Tcl_Interp *interp,
			    Tk_PhotoHandle imageHandle, NSVGimage *nsvgImage,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, RastOpts *ropts);
static double		GetScaleFromParameters(NSVGimage *nsvgImage,
			    RastOpts *ropts, int *widthPtr, int *heightPtr);
static NSVGcache *	GetCachePtr(Tcl_Interp *interp);
static int		CacheSVG(Tcl_Interp *interp, ClientData dataOrChan,
			    Tcl_Obj *formatObj, NSVGimage *nsvgImage,
			    RastOpts *ropts);
static NSVGimage *	GetCachedSVG(Tcl_Interp *interp, ClientData dataOrChan,
			    Tcl_Obj *formatObj, RastOpts *ropts);
static void		CleanCache(Tcl_Interp *interp);
static void		FreeCache(ClientData clientData, Tcl_Interp *interp);

/*
 * The format record for the SVG nano file format:
 */

Tk_PhotoImageFormat tkImgFmtSVGnano = {
    "svg",			/* name */
    FileMatchSVG,		/* fileMatchProc */
    StringMatchSVG,		/* stringMatchProc */
    FileReadSVG,		/* fileReadProc */
    StringReadSVG,		/* stringReadProc */
    NULL,			/* fileWriteProc */
    NULL,			/* stringWriteProc */
    NULL
};









































/*
 *----------------------------------------------------------------------
 *
 * FileMatchSVG --
 *
 *	This function is invoked by the photo image type to see if a file







|





>
>














|








|


|


|















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
 */

typedef struct {
    /* A poiner to remember if it is the same svn image (data)
     * It is a Tcl_Channel if image created by -file option
     * or a Tcl_Obj, if image is created with the -data option
     */
    void *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);
static int		StringMatchSVG(Tcl_Obj *dataObj, Tcl_Obj *format,
			    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int		StringReadSVG(Tcl_Interp *interp, Tcl_Obj *dataObj,
			    Tcl_Obj *format, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static NSVGimage *	ParseSVGWithOptions(Tcl_Interp *interp,
			    const char *input, Tcl_Size length, Tcl_Obj *format,
			    RastOpts *ropts);
static int		RasterizeSVG(Tcl_Interp *interp,
			    Tk_PhotoHandle imageHandle, NSVGimage *nsvgImage,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, RastOpts *ropts);
static double		GetScaleFromParameters(NSVGimage *nsvgImage,
			    RastOpts *ropts, int *widthPtr, int *heightPtr);
static NSVGcache *	GetCachePtr(Tcl_Interp *interp);
static int		CacheSVG(Tcl_Interp *interp, void *dataOrChan,
			    Tcl_Obj *formatObj, NSVGimage *nsvgImage,
			    RastOpts *ropts);
static NSVGimage *	GetCachedSVG(Tcl_Interp *interp, void *dataOrChan,
			    Tcl_Obj *formatObj, RastOpts *ropts);
static void		CleanCache(Tcl_Interp *interp);
static void		FreeCache(void *clientData, Tcl_Interp *interp);

/*
 * The format record for the SVG nano file format:
 */

Tk_PhotoImageFormat tkImgFmtSVGnano = {
    "svg",			/* name */
    FileMatchSVG,		/* fileMatchProc */
    StringMatchSVG,		/* stringMatchProc */
    FileReadSVG,		/* fileReadProc */
    StringReadSVG,		/* stringReadProc */
    NULL,			/* fileWriteProc */
    NULL,			/* stringWriteProc */
    NULL
};

/*
 *----------------------------------------------------------------------
 *
 * 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135












136
137
138
139
140
141
142
143
144
145
146
147
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchSVG(
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    Tcl_Obj *dataObj = Tcl_NewObj();
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;
    (void)fileName;

    CleanCache(interp);
    if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) {












	/* in case of an error reading the file */
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    data = TkGetStringFromObj(dataObj, &length);
    nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts);
    Tcl_DecrRefCount(dataObj);
    if (nsvgImage != NULL) {
        GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr);
        if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) {
	    nsvgDelete(nsvgImage);
	    return 0;







|




|




<


|
>
>
>
>
>
>
>
>
>
>
>
>




|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchSVG(
    Tcl_Channel chan,
    TCL_UNUSED(const char *),
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    Tcl_Size length;
    Tcl_Obj *dataObj = Tcl_NewObj();
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;


    CleanCache(interp);
    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, TCL_INDEX_NONE, 1) == TCL_IO_FAILURE)) {
	/* in case of an error reading the file */
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    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;
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
 *----------------------------------------------------------------------
 */

static int
FileReadSVG(
    Tcl_Interp *interp,
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, chan, formatObj, &ropts);
    (void)fileName;

    if (nsvgImage == NULL) {
        Tcl_Obj *dataObj = Tcl_NewObj();

	if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) {
	    /* in case of an error reading the file */
	    Tcl_DecrRefCount(dataObj);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("read error", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "READ_ERROR", NULL);
	    return TCL_ERROR;
	}
	data = TkGetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
	Tcl_DecrRefCount(dataObj);
	if (nsvgImage == NULL) {
	    return TCL_ERROR;
	}
    }







|






|



<




|


|



|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
 *----------------------------------------------------------------------
 */

static int
FileReadSVG(
    Tcl_Interp *interp,
    Tcl_Channel chan,
    TCL_UNUSED(const char *),
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    Tcl_Size length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, chan, formatObj, &ropts);


    if (nsvgImage == NULL) {
        Tcl_Obj *dataObj = Tcl_NewObj();

	if (Tcl_ReadChars(chan, dataObj, TCL_INDEX_NONE, 0) == TCL_IO_FAILURE) {
	    /* in case of an error reading the file */
	    Tcl_DecrRefCount(dataObj);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("read error", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "READ_ERROR", NULL);
	    return TCL_ERROR;
	}
	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
static int
StringMatchSVG(
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;

    CleanCache(interp);
    data = TkGetStringFromObj(dataObj, &length);






    nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts);
    if (nsvgImage != NULL) {
        GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr);
        if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) {
	    nsvgDelete(nsvgImage);
	    return 0;
        }







|





|
>
>
>
>
>
>







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
static int
StringMatchSVG(
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    Tcl_Size length, testLength;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;

    CleanCache(interp);
    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;
        }
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, dataObj, formatObj, &ropts);

    if (nsvgImage == NULL) {
        data = TkGetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
    }
    if (nsvgImage == NULL) {
	return TCL_ERROR;
    }
    return RasterizeSVG(interp, imageHandle, nsvgImage, destX, destY,







|





|







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    Tcl_Size length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, dataObj, formatObj, &ropts);

    if (nsvgImage == NULL) {
	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,
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
 *----------------------------------------------------------------------
 */

static NSVGimage *
ParseSVGWithOptions(
    Tcl_Interp *interp,
    const char *input,
    TkSizeT length,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    double dpi = 96.0;
    char *inputCopy = NULL;
    NSVGimage *nsvgImage;
    int parameterScaleSeen = 0;
    static const char *const fmtOptions[] = {
        "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL
    };
    enum fmtOptionsEnum {
	OPT_DPI, OPT_SCALE, OPT_SCALE_TO_HEIGHT, OPT_SCALE_TO_WIDTH
    };

    /*
     * The parser destroys the original input string,
     * therefore first duplicate.
     */

    inputCopy = (char *)attemptckalloc(length+1);
    if (inputCopy == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc data buffer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto error;
    }
    memcpy(inputCopy, input, length);
    inputCopy[length] = '\0';

    /*







|




|


















|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
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 NSVGimage *
ParseSVGWithOptions(
    Tcl_Interp *interp,
    const char *input,
    Tcl_Size length,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    Tcl_Obj **objv = NULL;
    Tcl_Size objc = 0;
    double dpi = 96.0;
    char *inputCopy = NULL;
    NSVGimage *nsvgImage;
    int parameterScaleSeen = 0;
    static const char *const fmtOptions[] = {
        "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL
    };
    enum fmtOptionsEnum {
	OPT_DPI, OPT_SCALE, OPT_SCALE_TO_HEIGHT, OPT_SCALE_TO_WIDTH
    };

    /*
     * The parser destroys the original input string,
     * therefore first duplicate.
     */

    inputCopy = (char *)attemptckalloc(length+1);
    if (inputCopy == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc data buffer", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto error;
    }
    memcpy(inputCopy, input, length);
    inputCopy[length] = '\0';

    /*
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	 */
	switch ((enum fmtOptionsEnum)optIndex) {
	case OPT_SCALE:
	case OPT_SCALE_TO_HEIGHT:
	case OPT_SCALE_TO_WIDTH:
	    if ( parameterScaleSeen ) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"only one of -scale, -scaletoheight, -scaletowidth may be given", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    parameterScaleSeen = 1;
	    break;
	default:
	    break;
	}

	/*
	 * Decode parameters
	 */
	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_DPI:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) {
	        goto error;
	    }
	    if (dpi < 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-dpi value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_DPI",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scale <= 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scale value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_HEIGHT:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToHeight) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToHeight <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletoheight value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_WIDTH:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToWidth) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToWidth <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletowidth value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	}
    }

    nsvgImage = nsvgParse(inputCopy, "px", (float) dpi);
    if (nsvgImage == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot parse SVG image", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "PARSE_ERROR", NULL);
	goto error;
    }
    ckfree(inputCopy);
    return nsvgImage;

error:







|




















|












|












|












|










|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
	 */
	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", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    parameterScaleSeen = 1;
	    break;
	default:
	    break;
	}

	/*
	 * Decode parameters
	 */
	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_DPI:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) {
	        goto error;
	    }
	    if (dpi < 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-dpi value must be positive", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_DPI",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scale <= 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scale value must be positive", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_HEIGHT:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToHeight) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToHeight <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletoheight value must be positive", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_WIDTH:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToWidth) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToWidth <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletowidth value must be positive", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	}
    }

    nsvgImage = nsvgParse(inputCopy, "px", (float) dpi);
    if (nsvgImage == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot parse SVG image", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "PARSE_ERROR", NULL);
	goto error;
    }
    ckfree(inputCopy);
    return nsvgImage;

error:
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533









534
535
536
537
538
539
540
541
542
543
static int
RasterizeSVG(
    Tcl_Interp *interp,
    Tk_PhotoHandle imageHandle,
    NSVGimage *nsvgImage,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY,

    RastOpts *ropts)
{
    int w, h, c;
    NSVGrasterizer *rast;
    unsigned char *imgData;
    Tk_PhotoImageBlock svgblock;
    double scale;
    (void)srcX;
    (void)srcY;

    scale = GetScaleFromParameters(nsvgImage, ropts, &w, &h);

    rast = nsvgCreateRasterizer();
    if (rast == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot initialize rasterizer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "RASTERIZER_ERROR",
		NULL);
	goto cleanAST;
    }









    imgData = (unsigned char *)attemptckalloc(w * h *4);
    if (imgData == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc image buffer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto cleanRAST;
    }
    nsvgRasterize(rast, nsvgImage, 0, 0,
	    (float) scale, imgData, w, h, w * 4);
    /* transfer the data to a photo block */
    svgblock.pixelPtr = imgData;







|
>







|
<





|




>
>
>
>
>
>
>
>
>
|

|







565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
static int
RasterizeSVG(
    Tcl_Interp *interp,
    Tk_PhotoHandle imageHandle,
    NSVGimage *nsvgImage,
    int destX, int destY,
    int width, int height,
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    RastOpts *ropts)
{
    int w, h, c;
    NSVGrasterizer *rast;
    unsigned char *imgData;
    Tk_PhotoImageBlock svgblock;
    double scale;
    Tcl_WideUInt wh;


    scale = GetScaleFromParameters(nsvgImage, ropts, &w, &h);

    rast = nsvgCreateRasterizer();
    if (rast == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot initialize rasterizer", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "RASTERIZER_ERROR",
		NULL);
	goto cleanAST;
    }

    /* Tk Ticket [822330269b] Check potential int overflow in following ckalloc */
    wh = (Tcl_WideUInt)w * (Tcl_WideUInt)h;
    if ( w < 0 || h < 0 || wh > INT_MAX / 4) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("image size overflow", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "IMAGE_SIZE_OVERFLOW", NULL);
	goto cleanRAST;
    }

    imgData = (unsigned char *)attemptckalloc(wh * 4);
    if (imgData == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc image buffer", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto cleanRAST;
    }
    nsvgRasterize(rast, nsvgImage, 0, 0,
	    (float) scale, imgData, w, h, w * 4);
    /* transfer the data to a photo block */
    svgblock.pixelPtr = imgData;
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
 *
 *----------------------------------------------------------------------
 */

static int
CacheSVG(
    Tcl_Interp *interp,
    ClientData dataOrChan,
    Tcl_Obj *formatObj,
    NSVGimage *nsvgImage,
    RastOpts *ropts)
{
    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = dataOrChan;
	if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    Tcl_DStringAppend(&cachePtr->formatString, data, length);
	}
	cachePtr->nsvgImage = nsvgImage;
	cachePtr->ropts = *ropts;
	return 1;
    }
    return 0;







|




|






|







745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
 *
 *----------------------------------------------------------------------
 */

static int
CacheSVG(
    Tcl_Interp *interp,
    void *dataOrChan,
    Tcl_Obj *formatObj,
    NSVGimage *nsvgImage,
    RastOpts *ropts)
{
    Tcl_Size length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = dataOrChan;
	if (formatObj != NULL) {
	    data = Tcl_GetStringFromObj(formatObj, &length);
	    Tcl_DStringAppend(&cachePtr->formatString, data, length);
	}
	cachePtr->nsvgImage = nsvgImage;
	cachePtr->ropts = *ropts;
	return 1;
    }
    return 0;
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
 *
 *----------------------------------------------------------------------
 */

static NSVGimage *
GetCachedSVG(
    Tcl_Interp *interp,
    ClientData dataOrChan,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);
    NSVGimage *nsvgImage = NULL;

    if ((cachePtr != NULL) && (cachePtr->nsvgImage != NULL) &&
	(cachePtr->dataOrChan == dataOrChan)) {
        if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    if (strcmp(data, Tcl_DStringValue(&cachePtr->formatString)) == 0) {
	        nsvgImage = cachePtr->nsvgImage;
		*ropts = cachePtr->ropts;
		cachePtr->nsvgImage = NULL;
	    }
	} else if (Tcl_DStringLength(&cachePtr->formatString) == 0) {
	    nsvgImage = cachePtr->nsvgImage;







|



|







|







786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
 *
 *----------------------------------------------------------------------
 */

static NSVGimage *
GetCachedSVG(
    Tcl_Interp *interp,
    void *dataOrChan,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    Tcl_Size length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);
    NSVGimage *nsvgImage = NULL;

    if ((cachePtr != NULL) && (cachePtr->nsvgImage != NULL) &&
	(cachePtr->dataOrChan == dataOrChan)) {
        if (formatObj != NULL) {
	    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;
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
 * Side effects:
 *	Existing image data in the cache and the cache will be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeCache(ClientData clientData, Tcl_Interp *interp)
{
    NSVGcache *cachePtr = (NSVGcache *)clientData;
    (void)interp;

    Tcl_DStringFree(&cachePtr->formatString);
    if (cachePtr->nsvgImage != NULL) {
        nsvgDelete(cachePtr->nsvgImage);
    }
    ckfree(cachePtr);
}








|


<








859
860
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875
876
 * Side effects:
 *	Existing image data in the cache and the cache will be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeCache(void *clientData, TCL_UNUSED(Tcl_Interp *))
{
    NSVGcache *cachePtr = (NSVGcache *)clientData;


    Tcl_DStringFree(&cachePtr->formatString);
    if (cachePtr->nsvgImage != NULL) {
        nsvgDelete(cachePtr->nsvgImage);
    }
    ckfree(cachePtr);
}

Changes to generic/tkImgUtil.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21
/*
 * tkImgUtil.c --
 *
 *	This file contains image related utility functions.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "xbytes.h"




/*
 *----------------------------------------------------------------------
 *
 * TkAlignImageData --
 *
 *	This function takes an image and copies the data into an aligned





|







|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkImgUtil.c --
 *
 *	This file contains image related utility functions.
 *
 * 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"
#ifdef _WIN32
#   include "tkWinInt.h"
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkAlignImageData --
 *
 *	This function takes an image and copies the data into an aligned

Changes to generic/tkInt.decls.

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]>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

library tk

##############################################################################






|
|







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 © 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

##############################################################################
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#
declare 12 {
    TkCursor *TkCreateCursorFromData(Tk_Window tkwin,
	    const char *source, const char *mask, int width, int height,
	    int xHot, int yHot, XColor fg, XColor bg)
}
declare 13 {
    int TkCreateFrame(ClientData clientData, Tcl_Interp *interp,
	    int argc, const char *const *argv, int toplevel, const char *appName)
}
declare 14 {
    Tk_Window TkCreateMainWindow(Tcl_Interp *interp,
	    const char *screenName, const char *baseName)
}
declare 15 {
    Time TkCurrentTime(TkDisplay *dispPtr)







|
|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#
declare 12 {
    TkCursor *TkCreateCursorFromData(Tk_Window tkwin,
	    const char *source, const char *mask, int width, int height,
	    int xHot, int yHot, XColor fg, XColor bg)
}
declare 13 {
    int TkCreateFrame(void *clientData, Tcl_Interp *interp,
	    Tcl_Size objc, Tcl_Obj *const objv[], int type, const char *appName)
}
declare 14 {
    Tk_Window TkCreateMainWindow(Tcl_Interp *interp,
	    const char *screenName, const char *baseName)
}
declare 15 {
    Time TkCurrentTime(TkDisplay *dispPtr)
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    const char *TkGetDefaultScreenName(Tcl_Interp *interp,
	    const char *screenName)
}
declare 34 {
    TkDisplay *TkGetDisplay(Display *display)
}
declare 35 {
    int TkGetDisplayOf(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
	    Tk_Window *tkwinPtr)
}
declare 36 {
    TkWindow *TkGetFocusWin(TkWindow *winPtr)
}
declare 37 {
    int TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin)







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    const char *TkGetDefaultScreenName(Tcl_Interp *interp,
	    const char *screenName)
}
declare 34 {
    TkDisplay *TkGetDisplay(Display *display)
}
declare 35 {
    Tcl_Size TkGetDisplayOf(Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[],
	    Tk_Window *tkwinPtr)
}
declare 36 {
    TkWindow *TkGetFocusWin(TkWindow *winPtr)
}
declare 37 {
    int TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin)
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
}
declare 58 {
    void TkpDisplayWarning(const char *msg, const char *title)
}
declare 59 {
    void TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name)
}
declare 60 {
    TkWindow *TkpGetOtherWindow(TkWindow *winPtr)
}
declare 61 {
    TkWindow *TkpGetWrapperWindow(TkWindow *winPtr)
}
declare 62 {
    int TkpInit(Tcl_Interp *interp)
}
declare 63 {
    void TkpInitializeMenuBindings(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable)
}
declare 64 {
    void TkpMakeContainer(Tk_Window tkwin)
}
declare 65 {
    void TkpMakeMenuWindow(Tk_Window tkwin, int transient)
}
declare 66 {
    Window TkpMakeWindow(TkWindow *winPtr, Window parent)
}
declare 67 {
    void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, const char *menuName)
}
declare 68 {
    TkDisplay *TkpOpenDisplay(const char *display_name)
}
declare 69 {







<
<
<










<
<
<



<
<
<







222
223
224
225
226
227
228



229
230
231
232
233
234
235
236
237
238



239
240
241



242
243
244
245
246
247
248
}
declare 58 {
    void TkpDisplayWarning(const char *msg, const char *title)
}
declare 59 {
    void TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name)
}



declare 61 {
    TkWindow *TkpGetWrapperWindow(TkWindow *winPtr)
}
declare 62 {
    int TkpInit(Tcl_Interp *interp)
}
declare 63 {
    void TkpInitializeMenuBindings(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable)
}



declare 65 {
    void TkpMakeMenuWindow(Tk_Window tkwin, int transient)
}



declare 67 {
    void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, const char *menuName)
}
declare 68 {
    TkDisplay *TkpOpenDisplay(const char *display_name)
}
declare 69 {
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
}
declare 72 {
    int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr)
}
declare 73 {
    void TkpRedirectKeyEvent(TkWindow *winPtr, XEvent *eventPtr)
}
declare 74 {
    void TkpSetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, const char *menuName)
}
declare 75 {
    int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, const char *string)
}
#
# Slot 76 unused (WAS: TkpWindowWasRecentlyDeleted)
#
declare 77 {
    void TkQueueEventForAllChildren(TkWindow *winPtr, XEvent *eventPtr)
}
declare 78 {
    int TkReadBitmapFile(Display *display, Drawable d, const char *filename,
	    unsigned int *width_return, unsigned int *height_return,
	    Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return)







<
<
<
<
<
<
<
<
<







256
257
258
259
260
261
262









263
264
265
266
267
268
269
}
declare 72 {
    int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr)
}
declare 73 {
    void TkpRedirectKeyEvent(TkWindow *winPtr, XEvent *eventPtr)
}









declare 77 {
    void TkQueueEventForAllChildren(TkWindow *winPtr, XEvent *eventPtr)
}
declare 78 {
    int TkReadBitmapFile(Display *display, Drawable d, const char *filename,
	    unsigned int *width_return, unsigned int *height_return,
	    Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return)
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
}
declare 82 {
    void TkSelInit(Tk_Window tkwin)
}
declare 83 {
    void TkSelPropProc(XEvent *eventPtr)
}

# Exported publically as Tk_SetClassProcs in 8.4a2
#declare 84 {
#    void TkSetClassProcs(Tk_Window tkwin,
#	    TkClassProcs *procs, ClientData instanceData)
#}
declare 85 {
    void TkSetWindowMenuBar(Tcl_Interp *interp, Tk_Window tkwin,
	    const char *oldMenuName, const char *menuName)
}
declare 86 {
    KeySym TkStringToKeysym(const char *name)
}
declare 87 {
    int TkThickPolyLineToArea(double *coordPtr, int numPoints,
	    double width, int capStyle, int joinStyle, double *rectPtr)
}







<
<
<
<
<
<
<
<
<
<







280
281
282
283
284
285
286










287
288
289
290
291
292
293
}
declare 82 {
    void TkSelInit(Tk_Window tkwin)
}
declare 83 {
    void TkSelPropProc(XEvent *eventPtr)
}










declare 86 {
    KeySym TkStringToKeysym(const char *name)
}
declare 87 {
    int TkThickPolyLineToArea(double *coordPtr, int numPoints,
	    double width, int capStyle, int joinStyle, double *rectPtr)
}
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
}
declare 109 {
    const char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
    void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
}
declare 111 {
    Tcl_Obj *TkpGetSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 112 {
    void TkpMenuThreadInit(void)
}
declare 113 {
    int XClipBox(Region rgn, XRectangle *rect_return)
}
declare 114 {







<
<
<
<







362
363
364
365
366
367
368




369
370
371
372
373
374
375
}
declare 109 {
    const char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
    void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
}




declare 112 {
    void TkpMenuThreadInit(void)
}
declare 113 {
    int XClipBox(Region rgn, XRectangle *rect_return)
}
declare 114 {
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
declare 118 {
    int XSetRegion(Display *display, GC gc, Region rgn)
}
declare 119 {
    int XUnionRectWithRegion(XRectangle *rect,
	    Region src, Region dr_return)
}
declare 121 aqua {
    Pixmap TkpCreateNativeBitmap(Display *display, const void *source)
}
declare 122 aqua {
    void TkpDefineNativeBitmaps(void)
}
declare 124 aqua {
    Pixmap TkpGetNativeAppBitmap(Display *display,
	    const char *name, int *width, int *height)
}
declare 135 {
    void TkpDrawHighlightBorder(Tk_Window tkwin, GC fgGC, GC bgGC,
        int highlightWidth, Drawable drawable)
}
declare 136 {
    void TkSetFocusWin(TkWindow *winPtr, int force)
}
declare 137 {
    void TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
            XEvent *eventPtr)
}







|


|


|



<
<
<
<







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404




405
406
407
408
409
410
411
declare 118 {
    int XSetRegion(Display *display, GC gc, Region rgn)
}
declare 119 {
    int XUnionRectWithRegion(XRectangle *rect,
	    Region src, Region dr_return)
}
declare 121 {
    Pixmap TkpCreateNativeBitmap(Display *display, const void *source)
}
declare 122 {
    void TkpDefineNativeBitmaps(void)
}
declare 124 {
    Pixmap TkpGetNativeAppBitmap(Display *display,
	    const char *name, int *width, int *height)
}




declare 136 {
    void TkSetFocusWin(TkWindow *winPtr, int force)
}
declare 137 {
    void TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
            XEvent *eventPtr)
}
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
	    Tk_Canvas canvas, double *pointPtr, int numPoints)
}
declare 152 {
    void TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
	    int highlightWidth, int borderWidth, int relief)
}
declare 153 {
    void TkCreateThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}
declare 154 {
    void TkDeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}

# entries needed only by tktest:
declare 156 {
    int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 157 {
    int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 158 {
    int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom selection, Atom target, Tk_GetSelProc *proc,
	    ClientData clientData)
}
declare 159 {
    int TkTextGetIndex(Tcl_Interp *interp, struct TkText *textPtr,
	    const char *string, struct TkTextIndex *indexPtr)
}
declare 160 {
    int TkTextIndexBackBytes(const struct TkText *textPtr,
	    const struct TkTextIndex *srcPtr, int count,
	    struct TkTextIndex *dstPtr)
}
declare 161 {
    int TkTextIndexForwBytes(const struct TkText *textPtr,
	    const struct TkTextIndex *srcPtr, int count,
	    struct TkTextIndex *dstPtr)
}
declare 162 {
    struct TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree,
	    const struct TkText *textPtr, int lineIndex,
	    int byteIndex, struct TkTextIndex *indexPtr)
}
declare 163 {
    TkSizeT TkTextPrintIndex(const struct TkText *textPtr,
	    const struct TkTextIndex *indexPtr, char *string)
}
declare 164 {
    struct TkTextSegment *TkTextSetMark(struct TkText *textPtr,
	    const char *name, struct TkTextIndex *indexPtr)
}
declare 165 {
    int TkTextXviewCmd(struct TkText *textPtr, Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[])
}
declare 166 {
    void TkTextChanged(struct TkSharedText *sharedTextPtr,
	    struct TkText *textPtr, const struct TkTextIndex *index1Ptr,
	    const struct TkTextIndex *index2Ptr)
}
declare 167 {
    int	TkBTreeNumLines(TkTextBTree tree,
	    const struct TkText *textPtr)
}
declare 168 {
    void TkTextInsertDisplayProc(struct TkText *textPtr,
	    struct TkTextDispChunk *chunkPtr, int x, int y,
	    int height, int baseline, Display *display,
	    Drawable dst, int screenY)
}
# Next group of functions exposed due to [Bug 2768945].
declare 169 {
    int TkStateParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 170 {
    const char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 171 {
    int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 172 {
    const char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 173 {
    int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 174 {
    const char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 175 {
    int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 176 {
    const char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 177 {
    int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 178 {
    const char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}
declare 179 {
    int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset)
}
declare 180 {
    const char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
}

# Angled text API, exposed for Emiliano Gavilán's RBC work.
declare 181 {
    void TkDrawAngledTextLayout(Display *display, Drawable drawable, GC gc,
	    Tk_TextLayout layout, int x, int y, double angle, int firstChar,
	    int lastChar)
}
declare 182 {
    void TkUnderlineAngledTextLayout(Display *display, Drawable drawable,
	    GC gc, Tk_TextLayout layout, int x, int y, double angle,
	    int underline)
}
declare 183 {
    int TkIntersectAngledTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height, double angle)
}
declare 184 {
    void TkDrawAngledChars(Display *display,Drawable drawable, GC gc,
	    Tk_Font tkfont, const char *source, int numBytes, double x,
	    double y, double angle)
}

# Support for aqua's inability to draw outside [NSView drawRect:]
declare 185 macosx {
    void TkpRedrawWidget(Tk_Window tkwin)
}
declare 186 macosx {
    int TkpWillDrawWidget(Tk_Window tkwin)
}

# Debugging / testing functions for photo images
declare 187 {
    int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data,
            Tcl_Obj *formatString, int *widthPtr, int *heightPtr)







|


|




|



|





|







|




|





|


|








|


















|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|


|
|





|
|












|




|


|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
	    Tk_Canvas canvas, double *pointPtr, int numPoints)
}
declare 152 {
    void TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
	    int highlightWidth, int borderWidth, int relief)
}
declare 153 {
    void TkCreateThreadExitHandler(Tcl_ExitProc *proc, void *clientData)
}
declare 154 {
    void TkDeleteThreadExitHandler(Tcl_ExitProc *proc, void *clientData)
}

# entries needed only by tktest:
declare 156 {
    int TkpTestembedCmd(void *clientData, Tcl_Interp *interp, Tcl_Size objc,
	    Tcl_Obj *const objv[])
}
declare 157 {
    int TkpTesttextCmd(void *dummy, Tcl_Interp *interp, Tcl_Size objc,
	    Tcl_Obj *const objv[])
}
declare 158 {
    int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin,
	    Atom selection, Atom target, Tk_GetSelProc *proc,
	    void *clientData)
}
declare 159 {
    int TkTextGetIndex(Tcl_Interp *interp, struct TkText *textPtr,
	    const char *string, struct TkTextIndex *indexPtr)
}
declare 160 {
    int TkTextIndexBackBytes(const struct TkText *textPtr,
	    const struct TkTextIndex *srcPtr, Tcl_Size count,
	    struct TkTextIndex *dstPtr)
}
declare 161 {
    int TkTextIndexForwBytes(const struct TkText *textPtr,
	    const struct TkTextIndex *srcPtr, Tcl_Size count,
	    struct TkTextIndex *dstPtr)
}
declare 162 {
    struct TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree,
	    const struct TkText *textPtr, int lineIndex,
	    Tcl_Size byteIndex, struct TkTextIndex *indexPtr)
}
declare 163 {
    Tcl_Size TkTextPrintIndex(const struct TkText *textPtr,
	    const struct TkTextIndex *indexPtr, char *string)
}
declare 164 {
    struct TkTextSegment *TkTextSetMark(struct TkText *textPtr,
	    const char *name, struct TkTextIndex *indexPtr)
}
declare 165 {
    int TkTextXviewCmd(struct TkText *textPtr, Tcl_Interp *interp,
	    Tcl_Size objc, Tcl_Obj *const objv[])
}
declare 166 {
    void TkTextChanged(struct TkSharedText *sharedTextPtr,
	    struct TkText *textPtr, const struct TkTextIndex *index1Ptr,
	    const struct TkTextIndex *index2Ptr)
}
declare 167 {
    int	TkBTreeNumLines(TkTextBTree tree,
	    const struct TkText *textPtr)
}
declare 168 {
    void TkTextInsertDisplayProc(struct TkText *textPtr,
	    struct TkTextDispChunk *chunkPtr, int x, int y,
	    int height, int baseline, Display *display,
	    Drawable dst, int screenY)
}
# Next group of functions exposed due to [Bug 2768945].
declare 169 {
    int TkStateParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 170 {
    const char *TkStatePrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}
declare 171 {
    int TkCanvasDashParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 172 {
    const char *TkCanvasDashPrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}
declare 173 {
    int TkOffsetParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 174 {
    const char *TkOffsetPrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}
declare 175 {
    int TkPixelParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 176 {
    const char *TkPixelPrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}
declare 177 {
    int TkOrientParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 178 {
    const char *TkOrientPrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}
declare 179 {
    int TkSmoothParseProc(void *clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset)
}
declare 180 {
    const char *TkSmoothPrintProc(void *clientData, Tk_Window tkwin,
	    char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr)
}

# Angled text API, exposed for Emiliano Gavilán's RBC work.
declare 181 {
    void TkDrawAngledTextLayout(Display *display, Drawable drawable, GC gc,
	    Tk_TextLayout layout, int x, int y, double angle, Tcl_Size firstChar,
	    Tcl_Size lastChar)
}
declare 182 {
    void TkUnderlineAngledTextLayout(Display *display, Drawable drawable,
	    GC gc, Tk_TextLayout layout, int x, int y, double angle,
	    int underline)
}
declare 183 {
    int TkIntersectAngledTextLayout(Tk_TextLayout layout, int x, int y,
	    int width, int height, double angle)
}
declare 184 {
    void TkDrawAngledChars(Display *display,Drawable drawable, GC gc,
	    Tk_Font tkfont, const char *source, Tcl_Size numBytes, double x,
	    double y, double angle)
}

# Support for aqua's inability to draw outside [NSView drawRect:]
declare 185 {
    void TkpRedrawWidget(Tk_Window tkwin)
}
declare 186 {
    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)
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739

declare 0 x11 {
    void TkCreateXEventSource(void)
}
declare 2 x11 {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}
declare 3 x11 {
    int TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
}
declare 4 x11 {
    void TkpSync(Display *display)
}
declare 5 x11 {
    Window TkUnixContainerId(TkWindow *winPtr)
}
declare 6 x11 {
    int TkUnixDoOneXEvent(Tcl_Time *timePtr)
}
declare 7 x11 {
    void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar)
}
declare 8 x11 {
    int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
}
declare 9 x11 {
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 10 x11 {
    void TkSendCleanup(TkDisplay *dispPtr)
}
declare 12 x11 {
    int TkpWmSetState(TkWindow *winPtr, int state)
}
# only needed by tktest:
declare 13 x11 {
    int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 38 x11 {
    int TkpCmapStressed_(Tk_Window tkwin, Colormap colormap)
}
declare 39 x11 {
    void TkpSync_(Display *display)
}
declare 40 x11 {
    Window TkUnixContainerId_(TkWindow *winPtr)
}
declare 41 x11 {
    int TkUnixDoOneXEvent_(Tcl_Time *timePtr)
}
declare 42 x11 {
    void TkUnixSetMenubar_(Tk_Window tkwin, Tk_Window menubar)
}
declare 43 x11 {
    void TkWmCleanup_(TkDisplay *dispPtr)
}
declare 44 x11 {
    void TkSendCleanup_(TkDisplay *dispPtr)
}
# only needed by tktest:
declare 45 x11 {
    int TkpTestsendCmd_(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}

################################
# Windows specific functions

declare 0 win {
    char *TkAlignImageData(XImage *image, int alignment, int bitOrder)
}
declare 2 win {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}
declare 3 win {
    unsigned long TkpGetMS(void)
}







<
<
<
<
<
<
<
<
<

<
<
<
<
<
<



<
<
<
<
<
<



<
<
<
<

|


|


|


|


|


|


|



|







|







626
627
628
629
630
631
632









633






634
635
636






637
638
639




640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

declare 0 x11 {
    void TkCreateXEventSource(void)
}
declare 2 x11 {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}









declare 6 x11 {






    int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
}
declare 9 x11 {






    int TkpWmSetState(TkWindow *winPtr, int state)
}
# only needed by tktest:




declare 38 x11 {
    int TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
}
declare 39 x11 {
    void TkpSync(Display *display)
}
declare 40 x11 {
    Window TkUnixContainerId(TkWindow *winPtr)
}
declare 41 x11 {
    int TkUnixDoOneXEvent(Tcl_Time *timePtr)
}
declare 42 x11 {
    void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar)
}
declare 43 x11 {
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 44 x11 {
    void TkSendCleanup(TkDisplay *dispPtr)
}
# only needed by tktest:
declare 45 x11 {
    int TkpTestsendCmd(void *clientData, Tcl_Interp *interp, Tcl_Size objc,
	    Tcl_Obj *const objv[])
}

################################
# Windows specific functions

declare 0 win {
    void TkCreateXEventSource(void)
}
declare 2 win {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}
declare 3 win {
    unsigned long TkpGetMS(void)
}
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
declare 26 win {
    void TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd, int pos)
}
declare 27 win {
    void TkWinWmCleanup(HINSTANCE hInstance)
}
declare 28 win {
    void TkWinXCleanup(ClientData clientData)
}
declare 29 win {
    void TkWinXInit(HINSTANCE hInstance)
}

# new for 8.1

declare 30 win {
    void TkWinSetForegroundWindow(TkWindow *winPtr)
}
declare 31 win {
    void TkWinDialogDebug(int debug)
}
declare 32 win {
    Tcl_Obj *TkWinGetMenuSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 33 win {
    int TkWinGetPlatformId(void)
}

# new for 8.4.1

declare 34 win {
    void TkWinSetHINSTANCE(HINSTANCE hInstance)
}
declare 35 win {
    int TkWinGetPlatformTheme(void)
}

# Exported through stub table since Tk 8.4.20/8.5.9

declare 36 win {
    LRESULT __stdcall TkWinChildProc(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam)
}

# new for 8.4.20+/8.5.12+, Cygwin only
declare 37 win {
    void TkCreateXEventSource(void)
}
declare 38 win {
    int TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
}
declare 39 win {
    void TkpSync(Display *display)
}
declare 40 win {







|


















|


















<
<
<
<







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792




793
794
795
796
797
798
799
declare 26 win {
    void TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd, int pos)
}
declare 27 win {
    void TkWinWmCleanup(HINSTANCE hInstance)
}
declare 28 win {
    void TkWinXCleanup(void *clientData)
}
declare 29 win {
    void TkWinXInit(HINSTANCE hInstance)
}

# new for 8.1

declare 30 win {
    void TkWinSetForegroundWindow(TkWindow *winPtr)
}
declare 31 win {
    void TkWinDialogDebug(int debug)
}
declare 32 win {
    Tcl_Obj *TkWinGetMenuSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 33 win {
    char *TkAlignImageData(XImage *image, int alignment, int bitOrder)
}

# new for 8.4.1

declare 34 win {
    void TkWinSetHINSTANCE(HINSTANCE hInstance)
}
declare 35 win {
    int TkWinGetPlatformTheme(void)
}

# Exported through stub table since Tk 8.4.20/8.5.9

declare 36 win {
    LRESULT __stdcall TkWinChildProc(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam)
}





declare 38 win {
    int TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
}
declare 39 win {
    void TkpSync(Display *display)
}
declare 40 win {
874
875
876
877
878
879
880
881
882
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
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 44 win {
    void TkSendCleanup(TkDisplay *dispPtr)
}
# only needed by tktest:
declare 45 win {
    int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc,
	    Tcl_Obj *const objv[])
}
declare 47 win {
    Tk_Window TkpGetCapture(void)
}

################################
# Aqua specific functions

declare 0 aqua {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}
declare 2 aqua {
    void TkGenerateActivateEvents_(TkWindow *winPtr, int active)
}
declare 3 aqua {
    void TkPointerDeadWindow(TkWindow *winPtr)
}
declare 4 aqua {
    void TkpSetCapture(TkWindow *winPtr)
}
declare 5 aqua {
    void TkpSetCursor(TkpCursor cursor)
}
declare 6 aqua {
    void TkpWmSetState(TkWindow *winPtr, int state)
}
declare 7 aqua {
    void TkAboutDlg(void)
}
declare 8 aqua {
    unsigned int TkMacOSXButtonKeyState(void)
}
declare 9 aqua {
    void TkMacOSXClearMenubarActive(void)
}
declare 10 aqua {
    int TkMacOSXDispatchMenuEvent(int menuID, int index)
}
# Now a static function
# declare 11 aqua {
#     void TkMacOSXInstallCursor(int resizeOverride)
# }

declare 12 aqua {
    void TkMacOSXHandleTearoffMenu(void)
}
declare 14 aqua {
    int TkMacOSXDoHLEvent(void *theEvent)
}
declare 16 aqua {
    Window TkMacOSXGetXWindow(void *macWinPtr)
}
declare 17 aqua {
    int TkMacOSXGrowToplevel(void *whichWindow, XPoint start)
}
declare 18 aqua {
    void TkMacOSXHandleMenuSelect(short theMenu, unsigned short theItem,
	    int optionKeyPressed)
}

# removed duplicates from tkPlat table(tk.decls)
#declare 19 aqua {
#    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
#}
#
#declare 20 aqua {
#    void TkMacOSXInitMenus(Tcl_Interp *interp)
#}

declare 21 aqua {
    void TkMacOSXInvalidateWindow(MacDrawable *macWin, int flag)
}
declare 22 aqua {
    int TkMacOSXIsCharacterMissing(Tk_Font tkfont, unsigned int searchChar)
}
declare 23 aqua {
    void TkMacOSXMakeRealWindowExist(TkWindow *winPtr)
}
declare 24 aqua {
    void *TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
}
declare 25 aqua {
    void TkMacOSXMenuClick(void)
}
# The corresponding Unregister was not a stub, and this should be static.
#declare 26 aqua {
#    void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
#}
declare 27 aqua {
    int TkMacOSXResizable(TkWindow *winPtr)
}
declare 28 aqua {
    void TkMacOSXSetHelpMenuItemCount(void)
}
declare 29 aqua {
    void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag)
}
declare 30 aqua {
    void TkMacOSXSetUpClippingRgn(Drawable drawable)
}
declare 31 aqua {
    void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort)
}
declare 32 aqua {
    void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}
# This was not implemented.  Perhaps meant to be OffScreen ?
#declare 33 aqua {
#    void TkMacOSXUnregisterMacWindow(void *portPtr)
#}
declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    Region TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {







|









|
|


|


|


|





|


|










<
|
|
<
>
















<
<
<
<
<
<
<
<
<
<



<
<
<









<
<
<
<









<
<
<






<
<
<
<







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
    void TkWmCleanup(TkDisplay *dispPtr)
}
declare 44 win {
    void TkSendCleanup(TkDisplay *dispPtr)
}
# only needed by tktest:
declare 45 win {
    int TkpTestsendCmd(void *clientData, Tcl_Interp *interp, Tcl_Size objc,
	    Tcl_Obj *const objv[])
}
declare 47 win {
    Tk_Window TkpGetCapture(void)
}

################################
# Aqua specific functions

declare 1 aqua {
    void TkAboutDlg(void)
}
declare 2 aqua {
    void TkGenerateActivateEvents(TkWindow *winPtr, int active)
}
declare 3 aqua {
    unsigned long TkpGetMS(void)
}
declare 4 aqua {
    void TkPointerDeadWindow(TkWindow *winPtr)
}
declare 5 aqua {
    void TkpSetCursor(TkpCursor cursor)
}
declare 6 aqua {
    int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
}
declare 7 aqua {
    int TkpWmSetState(TkWindow *winPtr, int state)
}
declare 8 aqua {
    unsigned int TkMacOSXButtonKeyState(void)
}
declare 9 aqua {
    void TkMacOSXClearMenubarActive(void)
}
declare 10 aqua {
    int TkMacOSXDispatchMenuEvent(int menuID, int index)
}

declare 11 aqua {
    void TkpSetCapture(TkWindow *winPtr)

}
declare 12 aqua {
    void TkMacOSXHandleTearoffMenu(void)
}
declare 14 aqua {
    int TkMacOSXDoHLEvent(void *theEvent)
}
declare 16 aqua {
    Window TkMacOSXGetXWindow(void *macWinPtr)
}
declare 17 aqua {
    int TkMacOSXGrowToplevel(void *whichWindow, XPoint start)
}
declare 18 aqua {
    void TkMacOSXHandleMenuSelect(short theMenu, unsigned short theItem,
	    int optionKeyPressed)
}










declare 21 aqua {
    void TkMacOSXInvalidateWindow(MacDrawable *macWin, int flag)
}



declare 23 aqua {
    void TkMacOSXMakeRealWindowExist(TkWindow *winPtr)
}
declare 24 aqua {
    void *TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
}
declare 25 aqua {
    void TkMacOSXMenuClick(void)
}




declare 27 aqua {
    int TkMacOSXResizable(TkWindow *winPtr)
}
declare 28 aqua {
    void TkMacOSXSetHelpMenuItemCount(void)
}
declare 29 aqua {
    void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag)
}



declare 31 aqua {
    void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort)
}
declare 32 aqua {
    void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}




declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    Region TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053

1054
1055
1056
1057
1058
1059
1060
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}
declare 52 aqua {
    void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag)
}
declare 53 aqua {
    unsigned long TkpGetMS(void)
}
# For Canvas3d, requested by Sean Woods
declare 54 aqua {
    void *TkMacOSXDrawable(Drawable drawable)
}
declare 55 aqua {
    int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
}


##############################################################################

# Define the platform specific internal Xlib interfaces. These functions are
# only available on the designated platform.

interface tkIntXlib







|
<
<
<
|
|
<
<
<
<
>







947
948
949
950
951
952
953
954



955
956




957
958
959
960
961
962
963
964
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}
declare 52 aqua {
    void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag)
}
# Made public as Tk_MacOSXGetNSWindowForDrawable



#declare 54 aqua {
#    void *TkMacOSXDrawable(Drawable drawable)




#}

##############################################################################

# Define the platform specific internal Xlib interfaces. These functions are
# only available on the designated platform.

interface tkIntXlib
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
	    KeySym *k, Status *s)
}
declare 80 win {
    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}
# This slot is reserved for use by the clipping rectangle patch:
#  declare 81 win {
#      XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
#  	    int clip_y_origin, XRectangle rectangles[], int n, int ordering)
#  }

declare 82 win {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 83 win {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)







<
|
|
|
<
|







1239
1240
1241
1242
1243
1244
1245

1246
1247
1248

1249
1250
1251
1252
1253
1254
1255
1256
	    KeySym *k, Status *s)
}
declare 80 win {
    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}

declare 81 win {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
	    int clip_y_origin, XRectangle rectangles[], int n, int ordering)

}
declare 82 win {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 83 win {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
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
declare 5 macosx {
    char *XKeysymToString(KeySym k)
}
declare 6 macosx {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 macosx {









    GContext XGContextFromGC(GC g)
}



# second parameter was of type KeyCode
declare 8 macosx {
    KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i)
}
declare 9 macosx {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 10 macosx {
    Window XRootWindow(Display *d, int i)
}
declare 11 macosx {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 12 macosx {









    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 13 macosx {
    int XBell(Display *d, int i)
}
declare 14 macosx {
    int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 15 macosx {
    int XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 16 macosx {



    int XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 17 macosx {
    int XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 18 macosx {
    int XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1,
	    unsigned int ui2, int i3, int i4, unsigned long ul)
}
declare 19 macosx {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 20 macosx {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 21 macosx {



    int XDestroyWindow(Display *d, Window w)
}
declare 22 macosx {
    int XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 23 macosx {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 24 macosx {
    int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 25 macosx {
    int XFillArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 26 macosx {
    int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 27 macosx {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 28 macosx {



    int XFreeColormap(Display *d, Colormap c)
}
declare 29 macosx {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}



declare 30 macosx {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 31 macosx {
    Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1,
	    int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3,
	    unsigned int *ui4)
}
declare 32 macosx {



    int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2,
	    Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1,
	    unsigned long *ulp2, unsigned char **cpp)
}
declare 33 macosx {



    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 34 macosx {
    int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui,
	    int i1, int i2, Window w2, Cursor c, Time t)
}
declare 35 macosx {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 36 macosx {




    int XMapWindow(Display *d, Window w)
}
declare 37 macosx {
    int XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 38 macosx {
    int XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 39 macosx {









    Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3,
	    int *i1, int *i2, int *i3, int *i4, unsigned int *ui)
}
declare 40 macosx {




    int XRaiseWindow(Display *d, Window w)
}
declare 41 macosx {
    int XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 42 macosx {
    int XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 43 macosx {
    int XSelectInput(Display *d, Window w, long l)
}
declare 44 macosx {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 45 macosx {



    int XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 46 macosx {
    int XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 47 macosx {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 48 macosx {
    int XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 49 macosx {
    int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 50 macosx {
    int XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 51 macosx {
    int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 52 macosx {
    int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 53 macosx {
    int XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 54 macosx {




    int XUngrabKeyboard(Display *d, Time t)
}
declare 55 macosx {
    int XUngrabPointer(Display *d, Time t)
}
declare 56 macosx {
    int XUnmapWindow(Display *d, Window w)
}
declare 57 macosx {













    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}
declare 58 macosx {




    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 59 macosx {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 60 macosx {
    int XFreeGC(Display *display, GC gc)
}
declare 61 macosx {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 62 macosx {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 63 macosx {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 64 macosx {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 65 macosx {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 66 macosx {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 67 macosx {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 68 macosx {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 69 macosx {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 70 macosx {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 71 macosx {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 72 macosx {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 73 macosx {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 74 macosx {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 75 macosx {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 76 macosx {
    XIC XCreateIC(XIM xim, ...)
}
declare 77 macosx {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 78 macosx {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 79 macosx {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 80 macosx {
    int XDrawSegments(Display *display, Drawable d, GC gc,
	    XSegment *segments, int nsegments)
}
declare 81 macosx {
    int XForceScreenSaver(Display *display, int mode)
}
declare 82 macosx {
    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 83 macosx {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}
declare 84 macosx {
    int XClearWindow(Display *d, Window w)
}
declare 85 macosx {
    int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 macosx {
    int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
	    int npoints, int mode)
}
declare 87 macosx {
    int XWarpPointer(Display *display, Window src_w, Window dest_w,
	    int src_x, int src_y, unsigned int src_width,
	    unsigned int src_height, int dest_x, int dest_y)
}
declare 88 macosx {
    int XQueryColor(Display *display, Colormap colormap, XColor *def_in_out)
}
declare 89 macosx {
    int XQueryColors(Display *display, Colormap colormap,
	    XColor *defs_in_out, int ncolors)
}
declare 90 macosx {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 91 macosx {
    int XSync(Display *display, Bool discard)
}
declare 92 macosx {
    Bool XTranslateCoordinates(Display *d, Window w1, Window w2, int i1,
	    int i2, int *i3, int *i4, Window *w3)
}
declare 93 macosx {
    int XDeleteProperty(Display *d, Window w, Atom a)
}
declare 94 macosx {
    int XFreeCursor(Display *d, Cursor c)
}
declare 95 macosx {
    int XGetInputFocus(Display *d, Window *w, int *i)
}
declare 96 macosx {
    int XmbLookupString(XIC xi, XKeyPressedEvent *xk, char *c, int i,
	    KeySym *k, Status *s)
}
declare 97 macosx {
    int XNextEvent(Display *d, XEvent *x)
}
declare 98 macosx {
    int XPutBackEvent(Display *d, XEvent *x)
}
declare 99 macosx {
    int XSetCommand(Display *d, Window w, char **c, int i)
}
declare 100 macosx {
    int XWindowEvent(Display *d, Window w, long l, XEvent *x)
}
declare 101 macosx {
    Status XGetWindowAttributes(Display *d, Window w, XWindowAttributes *x)
}
declare 102 macosx {
    Status XGetWMColormapWindows(Display *d, Window w, Window **wpp, int *ip)
}
declare 103 macosx {
    Status XIconifyWindow(Display *d, Window w, int i)
}
declare 104 macosx {
    Status XWithdrawWindow(Display *d, Window w, int i)
}
declare 105 macosx {
    XHostAddress *XListHosts(Display *d, int *i, Bool *b)
}
declare 106 macosx {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
       int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 107 macosx {
    int XFlush(Display *display)
}
declare 108 macosx {
    int XGrabServer(Display *display)
}
declare 109 macosx {
    int XUngrabServer(Display *display)
}
declare 110 macosx {
    int XFree(void *data)
}
declare 111 macosx {
    int XNoOp(Display *display)
}
declare 112 macosx {
    XAfterFunction XSynchronize(Display *display, Bool onoff)
}
declare 113 macosx {
    Status XLookupColor(Display *d, Colormap c1, _Xconst char *c2,
	    XColor *x1, XColor *x2)
}
declare 114 macosx {
    VisualID XVisualIDFromVisual(Visual *visual)
}


declare 120 macosx {
    int XOffsetRegion(Region rgn, int dx, int dy)
}
declare 121 macosx {
    int XUnionRegion(Region srca, Region srcb, Region dr_return)
}


declare 122 macosx {
    Window XCreateWindow(Display *display, Window parent, int x, int y,
	    unsigned int width, unsigned int height,
	    unsigned int border_width, int depth, unsigned int clazz,
	    Visual *visual, unsigned long value_mask,
	    XSetWindowAttributes *attributes)
}


declare 129 macosx {
    int XLowerWindow(Display *d, Window w)
}
declare 130 macosx {
    int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 131 macosx {
    int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 132 macosx {
    int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n)
}









declare 136 macosx {
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 macosx {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
declare 138 macosx {
    Region XPolygonRegion(XPoint *pts, int n, int rule)
}
declare 139 macosx {
    int XPointInRegion(Region rgn, int x, int y)
}

declare 140 macosx {
    XVaNestedList XVaCreateNestedList(int dummy, ...)
}
declare 141 macosx {
    char *XSetICValues(XIC xic, ...)
}
declare 142 macosx {
    char *XGetICValues(XIC xic, ...)
}
declare 143 macosx {
    void XSetICFocus(XIC xic)
}
declare 144 macosx {
    void XDestroyIC(XIC xic)
}
declare 145 macosx {
    Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
	    XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)
}
declare 146 macosx {
    Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2,
	    unsigned int ui1, unsigned int ui2, XColor _Xconst *x1,
	    XColor _Xconst *x2)
}
declare 147 macosx {
    void XFreeFontSet(Display *display, XFontSet fontset)
}
declare 148 macosx {
    int XCloseIM(XIM im)
}
declare 149 macosx {







>
>
>
>
>
>
>
>
>


>
>
>

|


|


|


|


|
>
>
>
>
>
>
>
>
>


|


|



|



|
>
>
>



|



|

|
|

|



|


|
>
>
>


|



|


|



|



|



|


|
>
>
>


|



>
>
>
|


|




|
>
>
>




|
>
>
>


|



|


|
>
>
>
>


|



|


|
>
>
>
>
>
>
>
>
>



|
>
>
>
>


|


|



|


|


|
>
>
>


|


|


|


|


|


|


|


|


|
>
>
>
>


|


|


|
>
>
>
>
>
>
>
>
>
>
>
>
>




|
>
>
>
>



|



|


|



|


|


|


|



|



|


|


|


|


|


|


|


|



|


|


|



|



|



|
<
<
<
<
<
<
<



|
<
<
<
<
|
<
<
|

|
|
<
<
<
<
|
<

<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















|
<




>
>






>
>







>
>












>
>
>
>
>
>
>
>
>














>












<
<
<
<
<
<
<
<
<
<
<
<







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
declare 5 macosx {
    char *XKeysymToString(KeySym k)
}
declare 6 macosx {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 macosx {
    Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
	    XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)
}
declare 8 macosx {
    Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2,
	    unsigned int ui1, unsigned int ui2, XColor _Xconst *x1,
	    XColor _Xconst *x2)
}
declare 9 macosx {
    GContext XGContextFromGC(GC g)
}
declare 10 macosx {
    XHostAddress *XListHosts(Display *d, int *i, Bool *b)
}
# second parameter was of type KeyCode
declare 11 macosx {
    KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i)
}
declare 12 macosx {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 13 macosx {
    Window XRootWindow(Display *d, int i)
}
declare 14 macosx {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 15 macosx {
    Status XIconifyWindow(Display *d, Window w, int i)
}
declare 16 macosx {
    Status XWithdrawWindow(Display *d, Window w, int i)
}
declare 17 macosx {
    Status XGetWMColormapWindows(Display *d, Window w, Window **wpp, int *ip)
}
declare 18 macosx {
    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 19 macosx {
    int XBell(Display *d, int i)
}
declare 20 macosx {
    int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 21 macosx {
    int XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 22 macosx {
    int XClearWindow(Display *d, Window w)
}
declare 23 macosx {
    int XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 24 macosx {
    int XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 25 macosx {
    int XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2,
	    int i3, int i4, unsigned long ul)
}
declare 26 macosx {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 27 macosx {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 28 macosx {
    int XDeleteProperty(Display *d, Window w, Atom a)
}
declare 29 macosx {
    int XDestroyWindow(Display *d, Window w)
}
declare 30 macosx {
    int XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 31 macosx {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 32 macosx {
    int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 33 macosx {
    int XFillArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 34 macosx {
    int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 35 macosx {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 36 macosx {
    int XForceScreenSaver(Display *d, int i)
}
declare 37 macosx {
    int XFreeColormap(Display *d, Colormap c)
}
declare 38 macosx {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}
declare 39 macosx {
    int XFreeCursor(Display *d, Cursor c)
}
declare 40 macosx {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 41 macosx {
    Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1,
	    int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3,
	    unsigned int *ui4)
}
declare 42 macosx {
    int XGetInputFocus(Display *d, Window *w, int *i)
}
declare 43 macosx {
    int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2,
	    Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1,
	    unsigned long *ulp2, unsigned char **cpp)
}
declare 44 macosx {
    Status XGetWindowAttributes(Display *d, Window w, XWindowAttributes *x)
}
declare 45 macosx {
    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 46 macosx {
    int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui,
	    int i1, int i2, Window w2, Cursor c, Time t)
}
declare 47 macosx {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 48 macosx {
    Status XLookupColor(Display *d, Colormap c1, _Xconst char *c2,
	    XColor *x1, XColor *x2)
}
declare 49 macosx {
    int XMapWindow(Display *d, Window w)
}
declare 50 macosx {
    int XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 51 macosx {
    int XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 52 macosx {
    int XNextEvent(Display *d, XEvent *x)
}
declare 53 macosx {
    int XPutBackEvent(Display *d, XEvent *x)
}
declare 54 macosx {
    int XQueryColors(Display *d, Colormap c, XColor *x, int i)
}
declare 55 macosx {
    Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3,
	    int *i1, int *i2, int *i3, int *i4, unsigned int *ui)
}
declare 56 macosx {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 57 macosx {
    int XRaiseWindow(Display *d, Window w)
}
declare 58 macosx {
    int XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 59 macosx {
    int XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 60 macosx {
    int XSelectInput(Display *d, Window w, long l)
}
declare 61 macosx {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 62 macosx {
    int XSetCommand(Display *d, Window w, char **c, int i)
}
declare 63 macosx {
    int XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 64 macosx {
    int XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 65 macosx {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 66 macosx {
    int XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 67 macosx {
    int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 68 macosx {
    int XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 69 macosx {
    int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 70 macosx {
    int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 71 macosx {
    int XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 72 macosx {
    Bool XTranslateCoordinates(Display *d, Window w1, Window w2, int i1,
	    int i2, int *i3, int *i4, Window *w3)
}
declare 73 macosx {
    int XUngrabKeyboard(Display *d, Time t)
}
declare 74 macosx {
    int XUngrabPointer(Display *d, Time t)
}
declare 75 macosx {
    int XUnmapWindow(Display *d, Window w)
}
declare 76 macosx {
    int XWindowEvent(Display *d, Window w, long l, XEvent *x)
}
declare 77 macosx {
    void XDestroyIC(XIC x)
}
declare 78 macosx {
    Bool XFilterEvent(XEvent *x, Window w)
}
declare 79 macosx {
    int XmbLookupString(XIC xi, XKeyPressedEvent *xk, char *c, int i,
	    KeySym *k, Status *s)
}
declare 80 macosx {
    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}
declare 81 macosx {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
	    int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 82 macosx {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 83 macosx {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 84 macosx {
    int XFreeGC(Display *display, GC gc)
}
declare 85 macosx {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 86 macosx {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 87 macosx {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 88 macosx {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 89 macosx {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 90 macosx {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 91 macosx {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 92 macosx {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 93 macosx {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 94 macosx {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 95 macosx {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 96 macosx {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 97 macosx {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 98 macosx {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 99 macosx {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 100 macosx {
    XIC XCreateIC(XIM xim, ...)
}
declare 101 macosx {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 102 macosx {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 103 macosx {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 104 macosx {







    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 105 macosx {




    int XWarpPointer(Display *d, Window s, Window dw, int sx, int sy,


	    unsigned int sw, unsigned int sh, int dx, int dy)
}
declare 106 macosx {
    int XFillRectangle(Display *display, Drawable d, GC gc,




	    int x, int y, unsigned int width, unsigned int height)

}



# New in Tk 8.6


























































declare 107 macosx {
    int XFlush(Display *display)
}
declare 108 macosx {
    int XGrabServer(Display *display)
}
declare 109 macosx {
    int XUngrabServer(Display *display)
}
declare 110 macosx {
    int XFree(void *data)
}
declare 111 macosx {
    int XNoOp(Display *display)
}
declare 112 macosx {
    XAfterFunction XSynchronize(Display *display, Bool onoff)
}
declare 113 macosx {
    int XSync(Display *display, Bool discard)

}
declare 114 macosx {
    VisualID XVisualIDFromVisual(Visual *visual)
}

# For tktreectrl
declare 120 macosx {
    int XOffsetRegion(Region rgn, int dx, int dy)
}
declare 121 macosx {
    int XUnionRegion(Region srca, Region srcb, Region dr_return)
}

# For 3dcanvas
declare 122 macosx {
    Window XCreateWindow(Display *display, Window parent, int x, int y,
	    unsigned int width, unsigned int height,
	    unsigned int border_width, int depth, unsigned int clazz,
	    Visual *visual, unsigned long value_mask,
	    XSetWindowAttributes *attributes)
}

# Various, e.g. for stub-enabled BLT
declare 129 macosx {
    int XLowerWindow(Display *d, Window w)
}
declare 130 macosx {
    int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 131 macosx {
    int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 132 macosx {
    int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n)
}
declare 133 macosx {
    int XDrawSegments(Display *d, Drawable dr, GC gc, XSegment *s, int n)
}
declare 134 macosx {
    int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y)
}
declare 135 macosx {
    int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m)
}
declare 136 macosx {
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 macosx {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
declare 138 macosx {
    Region XPolygonRegion(XPoint *pts, int n, int rule)
}
declare 139 macosx {
    int XPointInRegion(Region rgn, int x, int y)
}
# For XIM
declare 140 macosx {
    XVaNestedList XVaCreateNestedList(int dummy, ...)
}
declare 141 macosx {
    char *XSetICValues(XIC xic, ...)
}
declare 142 macosx {
    char *XGetICValues(XIC xic, ...)
}
declare 143 macosx {
    void XSetICFocus(XIC xic)
}












declare 147 macosx {
    void XFreeFontSet(Display *display, XFontSet fontset)
}
declare 148 macosx {
    int XCloseIM(XIM im)
}
declare 149 macosx {

Changes to generic/tkInt.h.

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.
 *
 * 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








|







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 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
27
28
29
30
31
32
33


34
35
36
37
38
39
40

#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#    include <sys/param.h>
#endif


#ifdef BYTE_ORDER
#    ifdef BIG_ENDIAN
#	 if BYTE_ORDER == BIG_ENDIAN
#	     undef WORDS_BIGENDIAN
#	     define WORDS_BIGENDIAN 1
#	 endif
#    endif







>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#    include <sys/param.h>
#endif
#include <stdint.h>
#include <stdlib.h>
#ifdef BYTE_ORDER
#    ifdef BIG_ENDIAN
#	 if BYTE_ORDER == BIG_ENDIAN
#	     undef WORDS_BIGENDIAN
#	     define WORDS_BIGENDIAN 1
#	 endif
#    endif
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118


119

120




121

122
123







124
125
126
127
128
129
130
131
132
133
134










135
136
137
138
139
140
141
#   elif defined(__GNUC__) && (__GNUC__ > 2)
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__) __attribute__((unused))
#   else
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__)
#   endif
#endif

#ifndef TkSizeT
#   if TCL_MAJOR_VERSION > 8
#	define TkSizeT size_t
#   else
#	define TkSizeT int
#   endif
#endif

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 7)
# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int len, Tcl_DString *))Tcl_UniCharToUtfDString)
# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int len, Tcl_DString *))Tcl_UtfToUniCharDString)
# define Tcl_Char16ToUtfDString Tcl_UniCharToUtfDString
# define Tcl_UtfToChar16DString Tcl_UtfToUniCharDString
#endif

#if defined(__GNUC__) && (__GNUC__ > 2)
#   define TKFLEXARRAY 0
#else
#   define TKFLEXARRAY 1
#endif

#if !defined(Tcl_GetParent) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
#   define Tcl_GetParent Tcl_GetMaster
#endif

/*
 * Macros used to cast between pointers and integers (e.g. when storing an int
 * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
 * to/from pointer from/to integer of different size".
 */

#if !defined(INT2PTR) && !defined(PTR2INT)
#   if defined(HAVE_INTPTR_T) || defined(intptr_t)
#	define INT2PTR(p) ((void*)(intptr_t)(p))
#	define PTR2INT(p) ((intptr_t)(p))
#   else
#	define INT2PTR(p) ((void*)(p))
#	define PTR2INT(p) ((long)(p))
#   endif
#endif
#if !defined(UINT2PTR) && !defined(PTR2UINT)
#   if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
#	define UINT2PTR(p) ((void*)(uintptr_t)(p))


#	define PTR2UINT(p) ((uintptr_t)(p))

#   else




#	define UINT2PTR(p) ((void*)(p))

#	define PTR2UINT(p) ((unsigned long)(p))
#   endif







#endif

#ifndef TCL_Z_MODIFIER
#   if defined(_WIN64)
#	define TCL_Z_MODIFIER	"I"
#   elif defined(__GNUC__) && !defined(_WIN32)
#	define TCL_Z_MODIFIER	"z"
#   else
#	define TCL_Z_MODIFIER	""
#   endif
#endif /* !TCL_Z_MODIFIER */











/*
 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;







<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|





<
<
<
<






|
<
|
<
|
|
|
<

|
<
|
>
>
|
>
|
>
>
>
>
|
>
|
|
>
>
>
>
>
>
>











>
>
>
>
>
>
>
>
>
>







71
72
73
74
75
76
77







78






79
80
81
82
83
84
85




86
87
88
89
90
91
92

93

94
95
96

97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#   elif defined(__GNUC__) && (__GNUC__ > 2)
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__) __attribute__((unused))
#   else
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__)
#   endif
#endif








#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)






#   define TKFLEXARRAY
#elif defined(__GNUC__) && (__GNUC__ > 2)
#   define TKFLEXARRAY 0
#else
#   define TKFLEXARRAY 1
#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)

#   define INT2PTR(p) ((void *)(ptrdiff_t)(p))

#endif
#if !defined(PTR2INT)
#   define PTR2INT(p) ((ptrdiff_t)(p))

#endif
#if !defined(UINT2PTR)

#   define UINT2PTR(p) ((void *)(size_t)(p))
#endif
#if !defined(PTR2UINT)
#   define PTR2UINT(p) ((size_t)(p))
#endif

/*
 * Fallback in case Tk is linked against a Tcl version not having TIP #585
 * (TCL_INDEX_TEMP_TABLE) or TIP #613/#618 (TCL_NULL_OK)
 */

#ifndef TCL_NULL_OK
#   define TCL_NULL_OK 32
#endif
#if !defined(TCL_INDEX_TEMP_TABLE)
#   define TCL_INDEX_TEMP_TABLE 64
#endif

#if (UINTPTR_MAX >= 0xffffffffffffffffu)
    /* This is a real 64 bit architecture. */
#   define TK_IS_64_BIT_ARCH
#endif

#ifndef TCL_Z_MODIFIER
#   if defined(_WIN64)
#	define TCL_Z_MODIFIER	"I"
#   elif defined(__GNUC__) && !defined(_WIN32)
#	define TCL_Z_MODIFIER	"z"
#   else
#	define TCL_Z_MODIFIER	""
#   endif
#endif /* !TCL_Z_MODIFIER */
#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

#if !defined(TCL_SIZE_MODIFIER)
#   define TCL_SIZE_MODIFIER ""
#endif

/*
 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 * specific cursor files.
 */

typedef struct TkCursor {
    Tk_Cursor cursor;		/* System specific identifier for cursor. */
    Display *display;		/* Display containing cursor. Needed for
				 * disposal and retrieval of cursors. */
    TkSizeT resourceRefCount;	/* Number of active uses of this cursor (each
				 * active use corresponds to a call to
				 * Tk_AllocPreserveFromObj or Tk_Preserve). If
				 * this count is 0, then this structure is no
				 * longer valid and it isn't present in a hash
				 * table: it is being kept around only because
				 * there are objects referring to it. The
				 * structure is freed when resourceRefCount
				 * and objRefCount are both 0. */
    TkSizeT objRefCount;		/* Number of Tcl objects that reference this
				 * structure.. */
    Tcl_HashTable *otherTable;	/* Second table (other than idTable) used to
				 * index this entry. */
    Tcl_HashEntry *hashPtr;	/* Entry in otherTable for this structure
				 * (needed when deleting). */
    Tcl_HashEntry *idHashPtr;	/* Entry in idTable for this structure (needed
				 * when deleting). */







|








|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
 * specific cursor files.
 */

typedef struct TkCursor {
    Tk_Cursor cursor;		/* System specific identifier for cursor. */
    Display *display;		/* Display containing cursor. Needed for
				 * disposal and retrieval of cursors. */
    Tcl_Size resourceRefCount;	/* Number of active uses of this cursor (each
				 * active use corresponds to a call to
				 * Tk_AllocPreserveFromObj or Tk_Preserve). If
				 * this count is 0, then this structure is no
				 * longer valid and it isn't present in a hash
				 * table: it is being kept around only because
				 * there are objects referring to it. The
				 * structure is freed when resourceRefCount
				 * and objRefCount are both 0. */
    Tcl_Size objRefCount;		/* Number of Tcl objects that reference this
				 * structure.. */
    Tcl_HashTable *otherTable;	/* Second table (other than idTable) used to
				 * index this entry. */
    Tcl_HashEntry *hashPtr;	/* Entry in otherTable for this structure
				 * (needed when deleting). */
    Tcl_HashEntry *idHashPtr;	/* Entry in idTable for this structure (needed
				 * when deleting). */
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
				 * modifier, then this is zero. */
    unsigned int altModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    TkLockUsage lockUsage;
				/* Indicates how to interpret lock
				 * modifier. */
    int numModKeyCodes;		/* Number of entries in modKeyCodes array
				 * below. */
    KeyCode *modKeyCodes;	/* Pointer to an array giving keycodes for all
				 * of the keys that have modifiers associated
				 * with them. Malloc'ed, but may be NULL. */

    /*
     * Information used by tkBitmap.c only:







|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
				 * modifier, then this is zero. */
    unsigned int altModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    TkLockUsage lockUsage;
				/* Indicates how to interpret lock
				 * modifier. */
    Tcl_Size numModKeyCodes;		/* Number of entries in modKeyCodes array
				 * below. */
    KeyCode *modKeyCodes;	/* Pointer to an array giving keycodes for all
				 * of the keys that have modifiers associated
				 * with them. Malloc'ed, but may be NULL. */

    /*
     * Information used by tkBitmap.c only:
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
     * Information used by tkError.c only:
     */

    struct TkErrorHandler *errorPtr;
				/* First in list of error handlers for this
				 * display. NULL means no handlers exist at
				 * present. */
    TkSizeT deleteCount;		/* Counts # of handlers deleted since last
				 * time inactive handlers were garbage-
				 * collected. When this number gets big,
				 * handlers get cleaned up. */

    /*
     * Used by tkEvent.c only:
     */







|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
     * Information used by tkError.c only:
     */

    struct TkErrorHandler *errorPtr;
				/* First in list of error handlers for this
				 * display. NULL means no handlers exist at
				 * present. */
    Tcl_Size deleteCount;		/* Counts # of handlers deleted since last
				 * time inactive handlers were garbage-
				 * collected. When this number gets big,
				 * handlers get cleaned up. */

    /*
     * Used by tkEvent.c only:
     */
370
371
372
373
374
375
376






377
378
379
380
381
382
383
384
385

    Tcl_HashTable maintainHashTable;
				/* Hash table that maps from a container's
				 * Tk_Window token to a list of windows managed
				 * by that container. */
    int geomInit;







#define TkGetContainer(tkwin) (((TkWindow *)tkwin)->maintainerPtr != NULL ? \
    ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr)

    /*
     * Information used by tkGet.c only:
     */

    Tcl_HashTable uidTable;	/* Stores all Tk_Uid used in a thread. */
    int uidInit;		/* 0 means uidTable needs initializing. */







>
>
>
>
>
>
|
|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

    Tcl_HashTable maintainHashTable;
				/* Hash table that maps from a container's
				 * Tk_Window token to a list of windows managed
				 * by that container. */
    int geomInit;

    /*
     * Information used by tkGrid.c, tkPack.c, tkPlace.c, tkPointer.c,
     * and ttkMacOSXTheme.c:
     */

#define TkGetContainer(tkwin) (Tk_TopWinHierarchy((TkWindow *)tkwin) ? NULL : \
	(((TkWindow *)tkwin)->maintainerPtr != NULL ? \
	 ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr))

    /*
     * Information used by tkGet.c only:
     */

    Tcl_HashTable uidTable;	/* Stores all Tk_Uid used in a thread. */
    int uidInit;		/* 0 means uidTable needs initializing. */
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    TkSizeT refCount;		/* Reference count of how many Tk applications
				 * are using this display. Used to clean up
				 * the display when we no longer have any Tk
				 * applications using it. */

    /*
     * The following field were all added for Tk8.3
     */

#if TCL_MAJOR_VERSION < 9
#if !defined(TK_NO_DEPRECATED)
    int mouseButtonState;	/* Current mouse button state for this
				 * display. NOT USED as of 8.6.10 */
    Window mouseButtonWindow;	/* Window the button state was set in, added
				 * in Tk 8.4. */
#else
    int notused1;
    XID notused2;
#endif /* !TK_NO_DEPRECATED */
#endif
    Tk_Window warpWindow;
    Tk_Window warpMainwin;	/* For finding the root window for warping
				 * purposes. */
    int warpX;
    int warpY;

    /*







|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







541
542
543
544
545
546
547
548
549
550
551
552















553
554
555
556
557
558
559
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    Tcl_Size refCount;		/* Reference count of how many Tk applications
				 * are using this display. Used to clean up
				 * the display when we no longer have any Tk
				 * applications using it. */
















    Tk_Window warpWindow;
    Tk_Window warpMainwin;	/* For finding the root window for warping
				 * purposes. */
    int warpX;
    int warpY;

    /*
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
				 * request code (-1 means consider all major
				 * codes). */
    int minorCode;		/* Consider only errors with this minor
				 * request code (-1 means consider all minor
				 * codes). */
    Tk_ErrorProc *errorProc;	/* Function to invoke when a matching error
				 * occurs. NULL means just ignore errors. */
    ClientData clientData;	/* Arbitrary value to pass to errorProc. */
    struct TkErrorHandler *nextPtr;
				/* Pointer to next older handler for this
				 * display, or NULL for end of list. */
} TkErrorHandler;

/*
 * One of the following structures exists for each event handler created by
 * calling Tk_CreateEventHandler. This information is used by tkEvent.c only.
 */

typedef struct TkEventHandler {
    unsigned long mask;		/* Events for which to invoke proc. */
    Tk_EventProc *proc;		/* Function to invoke when an event in mask
				 * occurs. */
    ClientData clientData;	/* Argument to pass to proc. */
    struct TkEventHandler *nextPtr;
				/* Next in list of handlers associated with
				 * window (NULL means end of list). */
} TkEventHandler;

/*
 * Tk keeps one of the following data structures for each main window (created
 * by a call to TkCreateMainWindow). It stores information that is shared by
 * all of the windows associated with a particular main window.
 */

typedef struct TkMainInfo {
    TkSizeT refCount;		/* Number of windows whose "mainPtr" fields
				 * point here. When this becomes zero, can
				 * free up the structure (the reference count
				 * is zero because windows can get deleted in
				 * almost any order; the main window isn't
				 * necessarily the last one deleted). */
    struct TkWindow *winPtr;	/* Pointer to main window. */
    Tcl_Interp *interp;		/* Interpreter associated with application. */







|














|












|







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
				 * request code (-1 means consider all major
				 * codes). */
    int minorCode;		/* Consider only errors with this minor
				 * request code (-1 means consider all minor
				 * codes). */
    Tk_ErrorProc *errorProc;	/* Function to invoke when a matching error
				 * occurs. NULL means just ignore errors. */
    void *clientData;	/* Arbitrary value to pass to errorProc. */
    struct TkErrorHandler *nextPtr;
				/* Pointer to next older handler for this
				 * display, or NULL for end of list. */
} TkErrorHandler;

/*
 * One of the following structures exists for each event handler created by
 * calling Tk_CreateEventHandler. This information is used by tkEvent.c only.
 */

typedef struct TkEventHandler {
    unsigned long mask;		/* Events for which to invoke proc. */
    Tk_EventProc *proc;		/* Function to invoke when an event in mask
				 * occurs. */
    void *clientData;	/* Argument to pass to proc. */
    struct TkEventHandler *nextPtr;
				/* Next in list of handlers associated with
				 * window (NULL means end of list). */
} TkEventHandler;

/*
 * Tk keeps one of the following data structures for each main window (created
 * by a call to TkCreateMainWindow). It stores information that is shared by
 * all of the windows associated with a particular main window.
 */

typedef struct TkMainInfo {
    Tcl_Size refCount;		/* Number of windows whose "mainPtr" fields
				 * point here. When this becomes zero, can
				 * free up the structure (the reference count
				 * is zero because windows can get deleted in
				 * almost any order; the main window isn't
				 * necessarily the last one deleted). */
    struct TkWindow *winPtr;	/* Pointer to main window. */
    Tcl_Interp *interp;		/* Interpreter associated with application. */
691
692
693
694
695
696
697












698
699
700
701
702
703
704
    int strictMotif;		/* This is linked to the tk_strictMotif global
				 * variable. */
    int alwaysShowSelection;	/* This is linked to the
				 * ::tk::AlwaysShowSelection variable. */
    struct TkMainInfo *nextPtr;	/* Next in list of all main windows managed by
				 * this process. */
    Tcl_HashTable busyTable;	/* Information used by [tk busy] command. */












} TkMainInfo;

/*
 * Tk keeps the following data structure for each of it's builtin bitmaps.
 * This structure is only used by tkBitmap.c and other platform specific
 * bitmap files.
 */







>
>
>
>
>
>
>
>
>
>
>
>







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
    int strictMotif;		/* This is linked to the tk_strictMotif global
				 * variable. */
    int alwaysShowSelection;	/* This is linked to the
				 * ::tk::AlwaysShowSelection variable. */
    struct TkMainInfo *nextPtr;	/* Next in list of all main windows managed by
				 * this process. */
    Tcl_HashTable busyTable;	/* Information used by [tk busy] command. */
    Tcl_ObjCmdProc *tclUpdateObjProc;
				/* Saved Tcl [update] command, used to restore
				 * Tcl's version of [update] after Tk is shut
				 * down */
#if TCL_MAJOR_VERSION > 8
    Tcl_ObjCmdProc2 *tclUpdateObjProc2;
				/* Saved Tcl [update] command, used to restore
				 * Tcl's version of [update] after Tk is shut
				 * down, in case it's a Tcl_ObjCmdProc2 */
#endif
    unsigned int ttkNbTabsStickBit;
    				/* Information used by ttk::notebook. */
} TkMainInfo;

/*
 * Tk keeps the following data structure for each of it's builtin bitmaps.
 * This structure is only used by tkBitmap.c and other platform specific
 * bitmap files.
 */
800
801
802
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
#endif /* TK_USE_INPUT_METHODS */

    /*
     * Information used for event bindings (see "bind" and "bindtags" commands
     * in tkCmds.c):
     */

    ClientData *tagPtr;		/* Points to array of tags used for bindings
				 * on this window. Each tag is a Tk_Uid.
				 * Malloc'ed. NULL means no tags. */
    int numTags;		/* Number of tags at *tagPtr. */

    /*
     * Information used by tkOption.c to manage options for the window.
     */

    int optionLevel;		/* -1 means no option information is currently
				 * cached for this window. Otherwise this
				 * gives the level in the option stack at
				 * which info is cached. */
    /*
     * Information used by tkSelect.c to manage the selection.
     */

    struct TkSelHandler *selHandlerList;
				/* First in list of handlers for returning the
				 * selection in various forms. */

    /*
     * Information used by tkGeometry.c for geometry management.
     */

    const Tk_GeomMgr *geomMgrPtr;
				/* Information about geometry manager for this
				 * window. */
    ClientData geomData;	/* Argument for geometry manager functions. */
    int reqWidth, reqHeight;	/* Arguments from last call to
				 * Tk_GeometryRequest, or 0's if
				 * Tk_GeometryRequest hasn't been called. */
    int internalBorderLeft;	/* Width of internal border of window (0 means
				 * no internal border). Geometry managers
				 * should not normally place children on top
				 * of the border. Fields for the other three







|


|





|


















|







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
#endif /* TK_USE_INPUT_METHODS */

    /*
     * Information used for event bindings (see "bind" and "bindtags" commands
     * in tkCmds.c):
     */

    void **tagPtr;		/* Points to array of tags used for bindings
				 * on this window. Each tag is a Tk_Uid.
				 * Malloc'ed. NULL means no tags. */
    Tcl_Size numTags;		/* Number of tags at *tagPtr. */

    /*
     * Information used by tkOption.c to manage options for the window.
     */

    Tcl_Size optionLevel;		/* TCL_INDEX_NONE means no option information is currently
				 * cached for this window. Otherwise this
				 * gives the level in the option stack at
				 * which info is cached. */
    /*
     * Information used by tkSelect.c to manage the selection.
     */

    struct TkSelHandler *selHandlerList;
				/* First in list of handlers for returning the
				 * selection in various forms. */

    /*
     * Information used by tkGeometry.c for geometry management.
     */

    const Tk_GeomMgr *geomMgrPtr;
				/* Information about geometry manager for this
				 * window. */
    void *geomData;	/* Argument for geometry manager functions. */
    int reqWidth, reqHeight;	/* Arguments from last call to
				 * Tk_GeometryRequest, or 0's if
				 * Tk_GeometryRequest hasn't been called. */
    int internalBorderLeft;	/* Width of internal border of window (0 means
				 * no internal border). Geometry managers
				 * should not normally place children on top
				 * of the border. Fields for the other three
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
				 * NULL. */

    /*
     * Information used by widget classes.
     */

    const Tk_ClassProcs *classProcsPtr;
    ClientData instanceData;

    /*
     * Platform specific information private to each port.
     */

    struct TkWindowPrivate *privatePtr;








|







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
				 * NULL. */

    /*
     * Information used by widget classes.
     */

    const Tk_ClassProcs *classProcsPtr;
    void *instanceData;

    /*
     * Platform specific information private to each port.
     */

    struct TkWindowPrivate *privatePtr;

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
				 * if its container is its parent. */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC inputContext;		/* XIM input context. */
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkWindow;











/*
 * Real definition of some events. Note that these events come from outside
 * but have internally generated pieces added to them.
 */

typedef struct {
    XKeyEvent keyEvent;		/* The real event from X11. */
#ifdef _WIN32



    char trans_chars[XMaxTransChars];
                            /* translated characters */
    unsigned char nbytes;
#elif !defined(MAC_OSC_TK)
    char *charValuePtr;		/* A pointer to a string that holds the key's
				 * %A substitution text (before backslash
				 * adding), or NULL if that has not been
				 * computed yet. If non-NULL, this string was
				 * allocated with ckalloc(). */
    TkSizeT charValueLen;	/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
#endif
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
 */

#define TK_MAKE_MENU_TEAROFF	0	/* Only non-transient case. */
#define TK_MAKE_MENU_POPUP	1
#define TK_MAKE_MENU_DROPDOWN	2

/* See TIP #494 */
#ifndef TCL_IO_FAILURE
#   define TCL_IO_FAILURE (-1)
#endif
/* See TIP #537 */
#ifndef TCL_INDEX_NONE
#   define TCL_INDEX_NONE (-1)
#endif

/*
 * The following structure is used with TkMakeEnsemble to create ensemble
 * commands and optionally to create sub-ensembles.
 */





typedef struct TkEnsemble {
    const char *name;
    Tcl_ObjCmdProc *proc;
    const struct TkEnsemble *subensemble;
} TkEnsemble;

/*
 * The following structure is used as a two way map between integers and
 * strings, usually to map between an internal C representation and the
 * strings used in Tcl.







>
>
>
>
>
>
>
>
>
>








>
>
>



|





|














<
<
<
<
<
<
<
<
<




>
>
>
>



|







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
				 * if its container is its parent. */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC inputContext;		/* XIM input context. */
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkWindow;

/*
 * String tables:
 */

MODULE_SCOPE const char *const tkStateStrings[];
MODULE_SCOPE const char *const tkCompoundStrings[];
MODULE_SCOPE const char *const tkAnchorStrings[];
MODULE_SCOPE const char *const tkReliefStrings[];
MODULE_SCOPE const char *const tkJustifyStrings[];

/*
 * 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
#   ifndef XMaxTransChars
#	define XMaxTransChars 7
#   endif
    char trans_chars[XMaxTransChars];
                            /* translated characters */
    unsigned char nbytes;
#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(). */
    Tcl_Size charValueLen;	/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
#endif
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
 */

#define TK_MAKE_MENU_TEAROFF	0	/* Only non-transient case. */
#define TK_MAKE_MENU_POPUP	1
#define TK_MAKE_MENU_DROPDOWN	2










/*
 * The following structure is used with TkMakeEnsemble to create ensemble
 * commands and optionally to create sub-ensembles.
 */

#if (TCL_MAJOR_VERSION < 9) && !defined(Tcl_ObjCmdProc2)
#define Tcl_ObjCmdProc2 Tcl_ObjCmdProc
#endif

typedef struct TkEnsemble {
    const char *name;
    Tcl_ObjCmdProc2 *proc;
    const struct TkEnsemble *subensemble;
} TkEnsemble;

/*
 * The following structure is used as a two way map between integers and
 * strings, usually to map between an internal C representation and the
 * strings used in Tcl.
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


/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */


MODULE_SCOPE const Tcl_ObjType tkBorderObjType;







MODULE_SCOPE const Tcl_ObjType tkBitmapObjType;
MODULE_SCOPE const Tcl_ObjType tkColorObjType;
MODULE_SCOPE const Tcl_ObjType tkCursorObjType;
MODULE_SCOPE const Tcl_ObjType tkFontObjType;
MODULE_SCOPE const Tcl_ObjType tkStateKeyObjType;
MODULE_SCOPE const Tcl_ObjType tkTextIndexType;

/*
 * Miscellaneous variables shared among Tk modules but not exported to the
 * outside world:
 */

MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod;
MODULE_SCOPE Tk_ImageType	tkBitmapImageType;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF;
MODULE_SCOPE void		(*tkHandleEventProc) (XEvent* eventPtr);
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtSVGnano;
MODULE_SCOPE TkMainInfo		*tkMainWindowList;
MODULE_SCOPE Tk_ImageType	tkPhotoImageType;
MODULE_SCOPE Tcl_HashTable	tkPredefBitmapTable;

MODULE_SCOPE const char *const tkWebColors[20];







>
|
>
>
>
>
>
>
>
|
|
|
|
|
|








|


|







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


/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

typedef struct {
    Tcl_ObjType objType;
    size_t version;
} TkObjType;

#ifndef TCL_OBJTYPE_V0
#   define TCL_OBJTYPE_V0 /* just empty */
#endif

MODULE_SCOPE const TkObjType tkBorderObjType;
MODULE_SCOPE const TkObjType tkBitmapObjType;
MODULE_SCOPE const TkObjType tkColorObjType;
MODULE_SCOPE const TkObjType tkCursorObjType;
MODULE_SCOPE const TkObjType tkFontObjType;
MODULE_SCOPE const TkObjType tkStateKeyObjType;

/*
 * Miscellaneous variables shared among Tk modules but not exported to the
 * outside world:
 */

MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod;
MODULE_SCOPE Tk_ImageType	tkBitmapImageType;
MODULE_SCOPE Tk_PhotoImageFormatVersion3 tkImgFmtGIF;
MODULE_SCOPE void		(*tkHandleEventProc) (XEvent* eventPtr);
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault;
MODULE_SCOPE Tk_PhotoImageFormatVersion3 tkImgFmtPNG;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtSVGnano;
MODULE_SCOPE TkMainInfo		*tkMainWindowList;
MODULE_SCOPE Tk_ImageType	tkPhotoImageType;
MODULE_SCOPE Tcl_HashTable	tkPredefBitmapTable;

MODULE_SCOPE const char *const tkWebColors[20];
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
#define PI	M_PI
#else
#define PI	3.14159265358979323846
#endif
#endif

/*
 * Support for Clang Static Analyzer <http://clang-analyzer.llvm.org>
 */

#if defined(PURIFY) && defined(__clang__)
#if __has_feature(attribute_analyzer_noreturn) && \
	!defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED)
void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn));
#endif







|







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
#define PI	M_PI
#else
#define PI	3.14159265358979323846
#endif
#endif

/*
 * Support for Clang Static Analyzer <https://clang-analyzer.llvm.org/>
 */

#if defined(PURIFY) && defined(__clang__)
#if __has_feature(attribute_analyzer_noreturn) && \
	!defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED)
void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn));
#endif
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
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
#include "tkIntDecls.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Themed widget set init function:
 */

MODULE_SCOPE int	Ttk_Init(Tcl_Interp *interp);


/*
 * Internal functions shared among Tk modules but not exported to the outside
 * world:
 */

MODULE_SCOPE int	Tk_BellObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BindObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BindtagsObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_BusyObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ButtonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_CanvasObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int argc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_CheckbuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ClipboardObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseColorObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ChooseDirectoryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_DestroyObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_EntryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_EventObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_FrameObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_FocusObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_FontObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_GetOpenFileObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_GetSaveFileObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_GrabObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_GridObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ImageObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_LabelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_LabelframeObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ListboxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_LowerObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MenuObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MenubuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MessageBoxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_MessageObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_PanedWindowObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_OptionObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_PackObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_PlaceObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_RadiobuttonObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_RaiseObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ScaleObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ScrollbarObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SelectionObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SendObjCmd(ClientData clientData,
			    Tcl_Interp *interp,int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SendObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SpinboxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_TextObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_TkwaitObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_ToplevelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_UpdateObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);

MODULE_SCOPE int	TkSetGeometryContainer(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name);
MODULE_SCOPE void	TkFreeGeometryContainer(Tk_Window tkwin,
			    const char *name);

MODULE_SCOPE void	TkEventInit(void);
MODULE_SCOPE void	TkRegisterObjTypes(void);
MODULE_SCOPE int	TkDeadAppObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const argv[]);
MODULE_SCOPE int	TkCanvasGetCoordObj(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tcl_Obj *obj,
			    double *doublePtr);
MODULE_SCOPE int	TkGetDoublePixels(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *string, double *doublePtr);
MODULE_SCOPE int	TkPostscriptImage(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, XImage *ximage,
			    int x, int y, int width, int height);
#if TCL_MAJOR_VERSION > 8
MODULE_SCOPE int TkCanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
    Tk_Window tkwin, const char *value, char *widgRec, size_t offset);
MODULE_SCOPE const char *TkCanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
    char *widgRec, size_t offset, Tcl_FreeProc **freeProcPtr);
#else
#define TkCanvasTagsParseProc Tk_CanvasTagsParseProc
#define TkCanvasTagsPrintProc Tk_CanvasTagsPrintProc
#endif
MODULE_SCOPE void       TkMapTopFrame(Tk_Window tkwin);
MODULE_SCOPE XEvent *	TkpGetBindingXEvent(Tcl_Interp *interp);
MODULE_SCOPE void	TkCreateExitHandler(Tcl_ExitProc *proc,
			    ClientData clientData);
MODULE_SCOPE void	TkDeleteExitHandler(Tcl_ExitProc *proc,
			    ClientData clientData);
MODULE_SCOPE Tcl_ExitProc	TkFinalize;
MODULE_SCOPE Tcl_ExitProc	TkFinalizeThread;
MODULE_SCOPE void	TkpBuildRegionFromAlphaData(Region region,
			    unsigned x, unsigned y, unsigned width,
			    unsigned height, unsigned char *dataPtr,
			    unsigned pixelStride, unsigned lineStride);
MODULE_SCOPE void	TkAppendPadAmount(Tcl_Obj *bufferObj,
			    const char *buffer, int pad1, int pad2);
MODULE_SCOPE int	TkParsePadAmount(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    int *pad1Ptr, int *pad2Ptr);
MODULE_SCOPE void       TkFocusSplit(TkWindow *winPtr);
MODULE_SCOPE void       TkFocusJoin(TkWindow *winPtr);





MODULE_SCOPE void	TkpDrawCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, int x, int y);
MODULE_SCOPE void	TkpDrawAngledCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, double x, double y, double angle);
MODULE_SCOPE int	TkpMeasureCharsInContext(Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, int maxLength, int flags,
			    int *lengthPtr);
MODULE_SCOPE void	TkUnderlineCharsInContext(Display *display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *string, int numBytes, int x, int y,
			    int firstByte, int lastByte);
MODULE_SCOPE void	TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
			    int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE void	TkpDrawFrameEx(Tk_Window tkwin, Drawable drawable,
			    Tk_3DBorder border, int highlightWidth,
			    int borderWidth, int relief);
MODULE_SCOPE void	TkpShowBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpHideBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpMakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
MODULE_SCOPE void	TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef,
			    Window *parentPtr, Tk_Window tkParent,
			    TkBusy busy);
MODULE_SCOPE int	TkBackgroundEvalObjv(Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv, int flags);
MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp,
			    const char *nsname, const char *name,
			    ClientData clientData, const TkEnsemble *map);

MODULE_SCOPE int	TkInitTkCmd(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE void	TkInitEmbeddedConfigurationInformation(
			    Tcl_Interp *interp);
MODULE_SCOPE void	TkDoWarpWrtWin(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);
MODULE_SCOPE int	TkListCreateFrame(ClientData clientData,
			    Tcl_Interp *interp, Tcl_Obj *listObj,
			    int toplevel, Tcl_Obj *nameObj);
MODULE_SCOPE void	TkRotatePoint(double originX, double originY,
			    double sine, double cosine, double *xPtr,
			    double *yPtr);
MODULE_SCOPE int TkGetIntForIndex(Tcl_Obj *, TkSizeT, int lastOK, TkSizeT*);



#define TkNewIndexObj(value) Tcl_NewWideIntObj((Tcl_WideInt)(value + 1) - 1)

#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);







|



>






|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
<
<
|
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
<
<
<
|
<
|
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
<
<
<
|
<
|
|
<
<
|
<
<
|
<
<
<
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<








|
<








<
<
<
<
<
<
<
<
<



|

|













>
>
>
>
>


|
|


|
|

|
|



|
|













|


|
>

|

|




<
<
<



|

>
>
|







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
#include "tkIntDecls.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Themed widget set init function, and handler called when Tk is destroyed.
 */

MODULE_SCOPE int	Ttk_Init(Tcl_Interp *interp);
MODULE_SCOPE void	Ttk_TkDestroyedHandler(Tcl_Interp *interp);

/*
 * Internal functions shared among Tk modules but not exported to the outside
 * world:
 */

MODULE_SCOPE Tcl_ObjCmdProc Tk_BellObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_BindObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_BindtagsObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc2 Tk_BusyObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_ButtonObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_CanvasObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_CheckbuttonObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_ClipboardObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_ChooseColorObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_ChooseDirectoryObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_DestroyObjCmd;




MODULE_SCOPE Tcl_ObjCmdProc Tk_EntryObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc Tk_EventObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_FrameObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_FocusObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_FontObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_GetOpenFileObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_GetSaveFileObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_GrabObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_GridObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_ImageObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_LabelObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_LabelframeObjCmd;





MODULE_SCOPE Tcl_ObjCmdProc Tk_ListboxObjCmd;

MODULE_SCOPE Tcl_ObjCmdProc Tk_LowerObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc Tk_MenuObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_MenubuttonObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_MessageBoxObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_MessageObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_PanedWindowObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_OptionObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_PackObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_PlaceObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_RadiobuttonObjCmd;





MODULE_SCOPE Tcl_ObjCmdProc Tk_RaiseObjCmd;

MODULE_SCOPE Tcl_ObjCmdProc Tk_ScaleObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc Tk_ScrollbarObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_SelectionObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_SendObjCmd;





MODULE_SCOPE Tcl_ObjCmdProc Tk_SpinboxObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_TextObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_TkwaitObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_ToplevelObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_UpdateObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_WinfoObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc Tk_WmObjCmd;


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 Tcl_ObjCmdProc TkDeadAppObjCmd;

MODULE_SCOPE int	TkCanvasGetCoordObj(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tcl_Obj *obj,
			    double *doublePtr);
MODULE_SCOPE int	TkGetDoublePixels(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *string, double *doublePtr);
MODULE_SCOPE int	TkPostscriptImage(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, XImage *ximage,
			    int x, int y, int width, int height);









MODULE_SCOPE void       TkMapTopFrame(Tk_Window tkwin);
MODULE_SCOPE XEvent *	TkpGetBindingXEvent(Tcl_Interp *interp);
MODULE_SCOPE void	TkCreateExitHandler(Tcl_ExitProc *proc,
			    void *clientData);
MODULE_SCOPE void	TkDeleteExitHandler(Tcl_ExitProc *proc,
			    void *clientData);
MODULE_SCOPE Tcl_ExitProc	TkFinalize;
MODULE_SCOPE Tcl_ExitProc	TkFinalizeThread;
MODULE_SCOPE void	TkpBuildRegionFromAlphaData(Region region,
			    unsigned x, unsigned y, unsigned width,
			    unsigned height, unsigned char *dataPtr,
			    unsigned pixelStride, unsigned lineStride);
MODULE_SCOPE void	TkAppendPadAmount(Tcl_Obj *bufferObj,
			    const char *buffer, int pad1, int pad2);
MODULE_SCOPE int	TkParsePadAmount(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    int *pad1Ptr, int *pad2Ptr);
MODULE_SCOPE void       TkFocusSplit(TkWindow *winPtr);
MODULE_SCOPE void       TkFocusJoin(TkWindow *winPtr);
#ifdef MAC_OSX_TK
MODULE_SCOPE int	TkpDrawingIsDisabled(Tk_Window tkwin);
#else
# define TkpDrawingIsDisabled(tkwin) 0
#endif
MODULE_SCOPE void	TkpDrawCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, Tcl_Size numBytes, Tcl_Size rangeStart,
			    Tcl_Size rangeLength, int x, int y);
MODULE_SCOPE void	TkpDrawAngledCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, Tcl_Size numBytes, Tcl_Size rangeStart,
			    Tcl_Size rangeLength, double x, double y, double angle);
MODULE_SCOPE int	TkpMeasureCharsInContext(Tk_Font tkfont,
			    const char *source, Tcl_Size numBytes, Tcl_Size rangeStart,
			    Tcl_Size rangeLength, int maxLength, int flags,
			    int *lengthPtr);
MODULE_SCOPE void	TkUnderlineCharsInContext(Display *display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *string, Tcl_Size numBytes, int x, int y,
			    Tcl_Size firstByte, Tcl_Size lastByte);
MODULE_SCOPE void	TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
			    int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE void	TkpDrawFrameEx(Tk_Window tkwin, Drawable drawable,
			    Tk_3DBorder border, int highlightWidth,
			    int borderWidth, int relief);
MODULE_SCOPE void	TkpShowBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpHideBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpMakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
MODULE_SCOPE void	TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef,
			    Window *parentPtr, Tk_Window tkParent,
			    TkBusy busy);
MODULE_SCOPE int	TkBackgroundEvalObjv(Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const *objv, int flags);
MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp,
			    const char *nsname, const char *name,
			    void *clientData, const TkEnsemble *map);
MODULE_SCOPE double	TkScalingLevel(Tk_Window tkwin);
MODULE_SCOPE int	TkInitTkCmd(Tcl_Interp *interp,
			    void *clientData);
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    void *clientData);
MODULE_SCOPE void	TkInitEmbeddedConfigurationInformation(
			    Tcl_Interp *interp);
MODULE_SCOPE void	TkDoWarpWrtWin(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);



MODULE_SCOPE void	TkRotatePoint(double originX, double originY,
			    double sine, double cosine, double *xPtr,
			    double *yPtr);
MODULE_SCOPE int TkGetIntForIndex(Tcl_Obj *, Tcl_Size, int lastOK, Tcl_Size*);

#define TkNewIndexObj(value) (((Tcl_Size)(value) == TCL_INDEX_NONE) ? Tcl_NewObj() : Tcl_NewWideIntObj((Tcl_WideInt)(value)))
#define TK_OPTION_UNDERLINE_DEF(type, field) NULL, TCL_INDEX_NONE, offsetof(type, field), TK_OPTION_NULL_OK, NULL


#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);
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
#define TkSubtractRegion XSubtractRegion
#define TkUnionRectWithRegion XUnionRectWithRegion

#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(Region clipRegion);
#endif



#if !defined(__cplusplus) && !defined(c_plusplus)
# define c_class class
#endif

#if TCL_UTF_MAX > 4
#   define TkUtfToUniChar(src, ch) (size_t)(((int (*)(const char *, int *))Tcl_UtfToUniChar)(src, ch))
#   define TkUniCharToUtf(ch, src) (size_t)(((int (*)(int, char *))Tcl_UniCharToUtf)(ch, src))
#   define TkUtfPrev Tcl_UtfPrev
#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
    MODULE_SCOPE const char *TkUtfPrev(const char *, const char *);
#endif

#if TCL_MAJOR_VERSION > 8
#define TkGetStringFromObj(objPtr, lenPtr) \
	(((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \
	*(lenPtr) = (objPtr)->length, (objPtr)->bytes)
MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr,
	size_t *lengthPtr);
#else
#define TkGetStringFromObj Tcl_GetStringFromObj
#define TkGetByteArrayFromObj Tcl_GetByteArrayFromObj
#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);

/*
 * For Tktest.
 */
MODULE_SCOPE int SquareObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
MODULE_SCOPE int	TkOldTestInit(Tcl_Interp *interp);
#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#define TkplatformtestInit(x) TCL_OK
#else
MODULE_SCOPE int	TkplatformtestInit(Tcl_Interp *interp);
#endif

#ifdef __cplusplus







>
>




|
<
<
|
<
<
<
<


<
<
<
<
|
<
<
<
<
<





|
<
<




|
<
<
<







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
#define TkSubtractRegion XSubtractRegion
#define TkUnionRectWithRegion XUnionRectWithRegion

#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(Region clipRegion);
#endif

MODULE_SCOPE void	TkpCopyRegion(TkRegion dst, TkRegion src);

#if !defined(__cplusplus) && !defined(c_plusplus)
# define c_class class
#endif

#if defined(_WIN32) && !defined(STATIC_BUILD) && TCL_MAJOR_VERSION < 9


#   define tcl_CreateFileHandler reserved9




#endif





MODULE_SCOPE  void       Icu_Init(Tcl_Interp* interp);






/*
 * Unsupported commands.
 */

MODULE_SCOPE Tcl_ObjCmdProc TkUnsupported1ObjCmd;



/*
 * For Tktest.
 */
MODULE_SCOPE Tcl_ObjCmdProc SquareObjCmd;



#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#define TkplatformtestInit(x) TCL_OK
#else
MODULE_SCOPE int	TkplatformtestInit(Tcl_Interp *interp);
#endif

#ifdef __cplusplus

Changes to generic/tkIntDecls.h.

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.
 *
 * 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








|







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 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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/* Slot 11 is reserved */
/* 12 */
EXTERN TkCursor *	TkCreateCursorFromData(Tk_Window tkwin,
				const char *source, const char *mask,
				int width, int height, int xHot, int yHot,
				XColor fg, XColor bg);
/* 13 */
EXTERN int		TkCreateFrame(ClientData clientData,
				Tcl_Interp *interp, int argc,
				const char *const *argv, int toplevel,
				const char *appName);
/* 14 */
EXTERN Tk_Window	TkCreateMainWindow(Tcl_Interp *interp,
				const char *screenName, const char *baseName);
/* 15 */
EXTERN Time		TkCurrentTime(TkDisplay *dispPtr);
/* 16 */
EXTERN void		TkDeleteAllImages(TkMainInfo *mainPtr);







|
<
|
|







75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
/* Slot 11 is reserved */
/* 12 */
EXTERN TkCursor *	TkCreateCursorFromData(Tk_Window tkwin,
				const char *source, const char *mask,
				int width, int height, int xHot, int yHot,
				XColor fg, XColor bg);
/* 13 */
EXTERN int		TkCreateFrame(void *clientData, Tcl_Interp *interp,

				Tcl_Size objc, Tcl_Obj *const objv[],
				int type, const char *appName);
/* 14 */
EXTERN Tk_Window	TkCreateMainWindow(Tcl_Interp *interp,
				const char *screenName, const char *baseName);
/* 15 */
EXTERN Time		TkCurrentTime(TkDisplay *dispPtr);
/* 16 */
EXTERN void		TkDeleteAllImages(TkMainInfo *mainPtr);
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
				Tk_Window tkwin, Tk_Uid string);
/* 33 */
EXTERN const char *	TkGetDefaultScreenName(Tcl_Interp *interp,
				const char *screenName);
/* 34 */
EXTERN TkDisplay *	TkGetDisplay(Display *display);
/* 35 */
EXTERN int		TkGetDisplayOf(Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[], Tk_Window *tkwinPtr);
/* 36 */
EXTERN TkWindow *	TkGetFocusWin(TkWindow *winPtr);
/* 37 */
EXTERN int		TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin);
/* 38 */
EXTERN int		TkGetMiterPoints(double p1[], double p2[],







|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
				Tk_Window tkwin, Tk_Uid string);
/* 33 */
EXTERN const char *	TkGetDefaultScreenName(Tcl_Interp *interp,
				const char *screenName);
/* 34 */
EXTERN TkDisplay *	TkGetDisplay(Display *display);
/* 35 */
EXTERN Tcl_Size		TkGetDisplayOf(Tcl_Interp *interp, Tcl_Size objc,
				Tcl_Obj *const objv[], Tk_Window *tkwinPtr);
/* 36 */
EXTERN TkWindow *	TkGetFocusWin(TkWindow *winPtr);
/* 37 */
EXTERN int		TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin);
/* 38 */
EXTERN int		TkGetMiterPoints(double p1[], double p2[],
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
EXTERN void		TkpCloseDisplay(TkDisplay *dispPtr);
/* 57 */
EXTERN void		TkpClaimFocus(TkWindow *topLevelPtr, int force);
/* 58 */
EXTERN void		TkpDisplayWarning(const char *msg, const char *title);
/* 59 */
EXTERN void		TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name);
/* 60 */
EXTERN TkWindow *	TkpGetOtherWindow(TkWindow *winPtr);
/* 61 */
EXTERN TkWindow *	TkpGetWrapperWindow(TkWindow *winPtr);
/* 62 */
EXTERN int		TkpInit(Tcl_Interp *interp);
/* 63 */
EXTERN void		TkpInitializeMenuBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable);
/* 64 */
EXTERN void		TkpMakeContainer(Tk_Window tkwin);
/* 65 */
EXTERN void		TkpMakeMenuWindow(Tk_Window tkwin, int transient);
/* 66 */
EXTERN Window		TkpMakeWindow(TkWindow *winPtr, Window parent);
/* 67 */
EXTERN void		TkpMenuNotifyToplevelCreate(Tcl_Interp *interp,
				const char *menuName);
/* 68 */
EXTERN TkDisplay *	TkpOpenDisplay(const char *display_name);
/* 69 */
EXTERN int		TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr);
/* 70 */
EXTERN int		TkPolygonToArea(double *polyPtr, int numPoints,
				double *rectPtr);
/* 71 */
EXTERN double		TkPolygonToPoint(double *polyPtr, int numPoints,
				double *pointPtr);
/* 72 */
EXTERN int		TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr);
/* 73 */
EXTERN void		TkpRedirectKeyEvent(TkWindow *winPtr,
				XEvent *eventPtr);
/* 74 */
EXTERN void		TkpSetMainMenubar(Tcl_Interp *interp,
				Tk_Window tkwin, const char *menuName);
/* 75 */
EXTERN int		TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin,
				const char *string);
/* Slot 76 is reserved */
/* 77 */
EXTERN void		TkQueueEventForAllChildren(TkWindow *winPtr,
				XEvent *eventPtr);
/* 78 */
EXTERN int		TkReadBitmapFile(Display *display, Drawable d,
				const char *filename,







|
<







|
<


|
<


















|
<
<
|
<
<







198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213

214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235


236


237
238
239
240
241
242
243
EXTERN void		TkpCloseDisplay(TkDisplay *dispPtr);
/* 57 */
EXTERN void		TkpClaimFocus(TkWindow *topLevelPtr, int force);
/* 58 */
EXTERN void		TkpDisplayWarning(const char *msg, const char *title);
/* 59 */
EXTERN void		TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name);
/* Slot 60 is reserved */

/* 61 */
EXTERN TkWindow *	TkpGetWrapperWindow(TkWindow *winPtr);
/* 62 */
EXTERN int		TkpInit(Tcl_Interp *interp);
/* 63 */
EXTERN void		TkpInitializeMenuBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable);
/* Slot 64 is reserved */

/* 65 */
EXTERN void		TkpMakeMenuWindow(Tk_Window tkwin, int transient);
/* Slot 66 is reserved */

/* 67 */
EXTERN void		TkpMenuNotifyToplevelCreate(Tcl_Interp *interp,
				const char *menuName);
/* 68 */
EXTERN TkDisplay *	TkpOpenDisplay(const char *display_name);
/* 69 */
EXTERN int		TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr);
/* 70 */
EXTERN int		TkPolygonToArea(double *polyPtr, int numPoints,
				double *rectPtr);
/* 71 */
EXTERN double		TkPolygonToPoint(double *polyPtr, int numPoints,
				double *pointPtr);
/* 72 */
EXTERN int		TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr);
/* 73 */
EXTERN void		TkpRedirectKeyEvent(TkWindow *winPtr,
				XEvent *eventPtr);
/* Slot 74 is reserved */


/* Slot 75 is reserved */


/* Slot 76 is reserved */
/* 77 */
EXTERN void		TkQueueEventForAllChildren(TkWindow *winPtr,
				XEvent *eventPtr);
/* 78 */
EXTERN int		TkReadBitmapFile(Display *display, Drawable d,
				const char *filename,
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);
/* 83 */
EXTERN void		TkSelPropProc(XEvent *eventPtr);
/* Slot 84 is reserved */
/* 85 */
EXTERN void		TkSetWindowMenuBar(Tcl_Interp *interp,
				Tk_Window tkwin, const char *oldMenuName,
				const char *menuName);
/* 86 */
EXTERN KeySym		TkStringToKeysym(const char *name);
/* 87 */
EXTERN int		TkThickPolyLineToArea(double *coordPtr,
				int numPoints, double width, int capStyle,
				int joinStyle, double *rectPtr);
/* 88 */







|
<
<
<







254
255
256
257
258
259
260
261



262
263
264
265
266
267
268
/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);
/* 83 */
EXTERN void		TkSelPropProc(XEvent *eventPtr);
/* Slot 84 is reserved */
/* Slot 85 is reserved */



/* 86 */
EXTERN KeySym		TkStringToKeysym(const char *name);
/* 87 */
EXTERN int		TkThickPolyLineToArea(double *coordPtr,
				int numPoints, double width, int capStyle,
				int joinStyle, double *rectPtr);
/* 88 */
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
				Tk_Window tkwin, Tcl_Obj *objPtr,
				Tk_Window *windowPtr);
/* 109 */
EXTERN const char *	TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
				Tcl_DString *dsPtr);
/* 110 */
EXTERN void		TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
/* 111 */
EXTERN Tcl_Obj *	TkpGetSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);
/* 112 */
EXTERN void		TkpMenuThreadInit(void);
/* 113 */
EXTERN int		XClipBox(Region rgn, XRectangle *rect_return);
/* 114 */
EXTERN Region		XCreateRegion(void);
/* 115 */
EXTERN int		XDestroyRegion(Region rgn);
/* 116 */
EXTERN int		XIntersectRegion(Region sra, Region srcb,
				Region dr_return);
/* 117 */
EXTERN int		XRectInRegion(Region rgn, int x, int y,
				unsigned int width, unsigned int height);
/* 118 */
EXTERN int		XSetRegion(Display *display, GC gc, Region rgn);
/* 119 */
EXTERN int		XUnionRectWithRegion(XRectangle *rect, Region src,
				Region dr_return);
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
/* 121 */
EXTERN Pixmap		TkpCreateNativeBitmap(Display *display,
				const void *source);
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
/* 122 */
EXTERN void		TkpDefineNativeBitmaps(void);
#endif /* AQUA */
/* Slot 123 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
/* 124 */
EXTERN Pixmap		TkpGetNativeAppBitmap(Display *display,
				const char *name, int *width, int *height);
#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* 135 */
EXTERN void		TkpDrawHighlightBorder(Tk_Window tkwin, GC fgGC,
				GC bgGC, int highlightWidth,
				Drawable drawable);
/* 136 */
EXTERN void		TkSetFocusWin(TkWindow *winPtr, int force);
/* 137 */
EXTERN void		TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
				XEvent *eventPtr);
/* 138 */
EXTERN KeySym		TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);







|
<
<




















<



<
<


<

<



<










|
<
<
<







315
316
317
318
319
320
321
322


323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

343
344
345


346
347

348

349
350
351

352
353
354
355
356
357
358
359
360
361
362



363
364
365
366
367
368
369
				Tk_Window tkwin, Tcl_Obj *objPtr,
				Tk_Window *windowPtr);
/* 109 */
EXTERN const char *	TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
				Tcl_DString *dsPtr);
/* 110 */
EXTERN void		TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
/* Slot 111 is reserved */


/* 112 */
EXTERN void		TkpMenuThreadInit(void);
/* 113 */
EXTERN int		XClipBox(Region rgn, XRectangle *rect_return);
/* 114 */
EXTERN Region		XCreateRegion(void);
/* 115 */
EXTERN int		XDestroyRegion(Region rgn);
/* 116 */
EXTERN int		XIntersectRegion(Region sra, Region srcb,
				Region dr_return);
/* 117 */
EXTERN int		XRectInRegion(Region rgn, int x, int y,
				unsigned int width, unsigned int height);
/* 118 */
EXTERN int		XSetRegion(Display *display, GC gc, Region rgn);
/* 119 */
EXTERN int		XUnionRectWithRegion(XRectangle *rect, Region src,
				Region dr_return);
/* Slot 120 is reserved */

/* 121 */
EXTERN Pixmap		TkpCreateNativeBitmap(Display *display,
				const void *source);


/* 122 */
EXTERN void		TkpDefineNativeBitmaps(void);

/* Slot 123 is reserved */

/* 124 */
EXTERN Pixmap		TkpGetNativeAppBitmap(Display *display,
				const char *name, int *width, int *height);

/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */



/* 136 */
EXTERN void		TkSetFocusWin(TkWindow *winPtr, int force);
/* 137 */
EXTERN void		TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
				XEvent *eventPtr);
/* 138 */
EXTERN KeySym		TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
				int numPoints);
/* 152 */
EXTERN void		TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
				int highlightWidth, int borderWidth,
				int relief);
/* 153 */
EXTERN void		TkCreateThreadExitHandler(Tcl_ExitProc *proc,
				ClientData clientData);
/* 154 */
EXTERN void		TkDeleteThreadExitHandler(Tcl_ExitProc *proc,
				ClientData clientData);
/* Slot 155 is reserved */
/* 156 */
EXTERN int		TkpTestembedCmd(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* 157 */
EXTERN int		TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp,
				int objc, Tcl_Obj *const objv[]);
/* 158 */
EXTERN int		TkSelGetSelection(Tcl_Interp *interp,
				Tk_Window tkwin, Atom selection, Atom target,
				Tk_GetSelProc *proc, ClientData clientData);
/* 159 */
EXTERN int		TkTextGetIndex(Tcl_Interp *interp,
				struct TkText *textPtr, const char *string,
				struct TkTextIndex *indexPtr);
/* 160 */
EXTERN int		TkTextIndexBackBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr, int count,
				struct TkTextIndex *dstPtr);
/* 161 */
EXTERN int		TkTextIndexForwBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr, int count,
				struct TkTextIndex *dstPtr);
/* 162 */
EXTERN struct TkTextIndex * TkTextMakeByteIndex(TkTextBTree tree,
				const struct TkText *textPtr, int lineIndex,

				int byteIndex, struct TkTextIndex *indexPtr);
/* 163 */
EXTERN TkSizeT		TkTextPrintIndex(const struct TkText *textPtr,
				const struct TkTextIndex *indexPtr,
				char *string);
/* 164 */
EXTERN struct TkTextSegment * TkTextSetMark(struct TkText *textPtr,
				const char *name,
				struct TkTextIndex *indexPtr);
/* 165 */
EXTERN int		TkTextXviewCmd(struct TkText *textPtr,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* 166 */
EXTERN void		TkTextChanged(struct TkSharedText *sharedTextPtr,
				struct TkText *textPtr,
				const struct TkTextIndex *index1Ptr,
				const struct TkTextIndex *index2Ptr);
/* 167 */
EXTERN int		TkBTreeNumLines(TkTextBTree tree,
				const struct TkText *textPtr);
/* 168 */
EXTERN void		TkTextInsertDisplayProc(struct TkText *textPtr,
				struct TkTextDispChunk *chunkPtr, int x,
				int y, int height, int baseline,
				Display *display, Drawable dst, int screenY);
/* 169 */
EXTERN int		TkStateParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);
/* 170 */
EXTERN const char *	TkStatePrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
/* 171 */
EXTERN int		TkCanvasDashParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);
/* 172 */
EXTERN const char *	TkCanvasDashPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
/* 173 */
EXTERN int		TkOffsetParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);
/* 174 */
EXTERN const char *	TkOffsetPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
/* 175 */
EXTERN int		TkPixelParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);
/* 176 */
EXTERN const char *	TkPixelPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
/* 177 */
EXTERN int		TkOrientParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);
/* 178 */
EXTERN const char *	TkOrientPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
/* 179 */
EXTERN int		TkSmoothParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				TkSizeT offset);
/* 180 */
EXTERN const char *	TkSmoothPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
/* 181 */
EXTERN void		TkDrawAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, int firstChar, int lastChar);

/* 182 */
EXTERN void		TkUnderlineAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, int underline);
/* 183 */
EXTERN int		TkIntersectAngledTextLayout(Tk_TextLayout layout,
				int x, int y, int width, int height,
				double angle);
/* 184 */
EXTERN void		TkDrawAngledChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, int numBytes, double x,
				double y, double angle);
#ifdef MAC_OSX_TCL /* MACOSX */
/* 185 */
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 186 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
/* 187 */
EXTERN int		TkDebugPhotoStringMatchDef(Tcl_Interp *inter,
				Tcl_Obj *data, Tcl_Obj *formatString,
				int *widthPtr, int *heightPtr);

typedef struct TkIntStubs {
    int magic;







|


|


|
<
|

|
|



|






|
|


|
|



>
|

|








|















|


|

|
|
|

|


|

|

|

|


|

|
|
|

|


|

|
|
|

|


|

|
|
|

|


|

|
|
|




|
>












|
|
<


<
<


<







402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

540
541


542
543

544
545
546
547
548
549
550
				int numPoints);
/* 152 */
EXTERN void		TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
				int highlightWidth, int borderWidth,
				int relief);
/* 153 */
EXTERN void		TkCreateThreadExitHandler(Tcl_ExitProc *proc,
				void *clientData);
/* 154 */
EXTERN void		TkDeleteThreadExitHandler(Tcl_ExitProc *proc,
				void *clientData);
/* Slot 155 is reserved */
/* 156 */
EXTERN int		TkpTestembedCmd(void *clientData, Tcl_Interp *interp,

				Tcl_Size objc, Tcl_Obj *const objv[]);
/* 157 */
EXTERN int		TkpTesttextCmd(void *dummy, Tcl_Interp *interp,
				Tcl_Size objc, Tcl_Obj *const objv[]);
/* 158 */
EXTERN int		TkSelGetSelection(Tcl_Interp *interp,
				Tk_Window tkwin, Atom selection, Atom target,
				Tk_GetSelProc *proc, void *clientData);
/* 159 */
EXTERN int		TkTextGetIndex(Tcl_Interp *interp,
				struct TkText *textPtr, const char *string,
				struct TkTextIndex *indexPtr);
/* 160 */
EXTERN int		TkTextIndexBackBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr,
				Tcl_Size count, struct TkTextIndex *dstPtr);
/* 161 */
EXTERN int		TkTextIndexForwBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr,
				Tcl_Size count, struct TkTextIndex *dstPtr);
/* 162 */
EXTERN struct TkTextIndex * TkTextMakeByteIndex(TkTextBTree tree,
				const struct TkText *textPtr, int lineIndex,
				Tcl_Size byteIndex,
				struct TkTextIndex *indexPtr);
/* 163 */
EXTERN Tcl_Size		TkTextPrintIndex(const struct TkText *textPtr,
				const struct TkTextIndex *indexPtr,
				char *string);
/* 164 */
EXTERN struct TkTextSegment * TkTextSetMark(struct TkText *textPtr,
				const char *name,
				struct TkTextIndex *indexPtr);
/* 165 */
EXTERN int		TkTextXviewCmd(struct TkText *textPtr,
				Tcl_Interp *interp, Tcl_Size objc,
				Tcl_Obj *const objv[]);
/* 166 */
EXTERN void		TkTextChanged(struct TkSharedText *sharedTextPtr,
				struct TkText *textPtr,
				const struct TkTextIndex *index1Ptr,
				const struct TkTextIndex *index2Ptr);
/* 167 */
EXTERN int		TkBTreeNumLines(TkTextBTree tree,
				const struct TkText *textPtr);
/* 168 */
EXTERN void		TkTextInsertDisplayProc(struct TkText *textPtr,
				struct TkTextDispChunk *chunkPtr, int x,
				int y, int height, int baseline,
				Display *display, Drawable dst, int screenY);
/* 169 */
EXTERN int		TkStateParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 170 */
EXTERN const char *	TkStatePrintProc(void *clientData, Tk_Window tkwin,
				char *widgRec, Tcl_Size offset,
				Tcl_FreeProc **freeProcPtr);
/* 171 */
EXTERN int		TkCanvasDashParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 172 */
EXTERN const char *	TkCanvasDashPrintProc(void *clientData,
				Tk_Window tkwin, char *widgRec,
				Tcl_Size offset, Tcl_FreeProc **freeProcPtr);
/* 173 */
EXTERN int		TkOffsetParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 174 */
EXTERN const char *	TkOffsetPrintProc(void *clientData, Tk_Window tkwin,
				char *widgRec, Tcl_Size offset,
				Tcl_FreeProc **freeProcPtr);
/* 175 */
EXTERN int		TkPixelParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 176 */
EXTERN const char *	TkPixelPrintProc(void *clientData, Tk_Window tkwin,
				char *widgRec, Tcl_Size offset,
				Tcl_FreeProc **freeProcPtr);
/* 177 */
EXTERN int		TkOrientParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 178 */
EXTERN const char *	TkOrientPrintProc(void *clientData, Tk_Window tkwin,
				char *widgRec, Tcl_Size offset,
				Tcl_FreeProc **freeProcPtr);
/* 179 */
EXTERN int		TkSmoothParseProc(void *clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				Tcl_Size offset);
/* 180 */
EXTERN const char *	TkSmoothPrintProc(void *clientData, Tk_Window tkwin,
				char *widgRec, Tcl_Size offset,
				Tcl_FreeProc **freeProcPtr);
/* 181 */
EXTERN void		TkDrawAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, Tcl_Size firstChar,
				Tcl_Size lastChar);
/* 182 */
EXTERN void		TkUnderlineAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, int underline);
/* 183 */
EXTERN int		TkIntersectAngledTextLayout(Tk_TextLayout layout,
				int x, int y, int width, int height,
				double angle);
/* 184 */
EXTERN void		TkDrawAngledChars(Display *display,
				Drawable drawable, GC gc, Tk_Font tkfont,
				const char *source, Tcl_Size numBytes,
				double x, double y, double angle);

/* 185 */
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);


/* 186 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);

/* 187 */
EXTERN int		TkDebugPhotoStringMatchDef(Tcl_Interp *inter,
				Tcl_Obj *data, Tcl_Obj *formatString,
				int *widthPtr, int *heightPtr);

typedef struct TkIntStubs {
    int magic;
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
    void (*tkBindInit) (TkMainInfo *mainPtr); /* 6 */
    void (*tkChangeEventWindow) (XEvent *eventPtr, TkWindow *winPtr); /* 7 */
    int (*tkClipInit) (Tcl_Interp *interp, TkDisplay *dispPtr); /* 8 */
    void (*tkComputeAnchor) (Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 9 */
    void (*reserved10)(void);
    void (*reserved11)(void);
    TkCursor * (*tkCreateCursorFromData) (Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); /* 12 */
    int (*tkCreateFrame) (ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv, int toplevel, const char *appName); /* 13 */
    Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, const char *screenName, const char *baseName); /* 14 */
    Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */
    void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */
    void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */
    void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */
    void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */
    void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */







|







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
    void (*tkBindInit) (TkMainInfo *mainPtr); /* 6 */
    void (*tkChangeEventWindow) (XEvent *eventPtr, TkWindow *winPtr); /* 7 */
    int (*tkClipInit) (Tcl_Interp *interp, TkDisplay *dispPtr); /* 8 */
    void (*tkComputeAnchor) (Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 9 */
    void (*reserved10)(void);
    void (*reserved11)(void);
    TkCursor * (*tkCreateCursorFromData) (Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); /* 12 */
    int (*tkCreateFrame) (void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], int type, const char *appName); /* 13 */
    Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, const char *screenName, const char *baseName); /* 14 */
    Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */
    void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */
    void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */
    void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */
    void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */
    void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
    void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */
    void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */
    char * (*tkGetBitmapData) (Tcl_Interp *interp, const char *string, const char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr); /* 30 */
    void (*tkGetButtPoints) (double p1[], double p2[], double width, int project, double m1[], double m2[]); /* 31 */
    TkCursor * (*tkGetCursorByName) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string); /* 32 */
    const char * (*tkGetDefaultScreenName) (Tcl_Interp *interp, const char *screenName); /* 33 */
    TkDisplay * (*tkGetDisplay) (Display *display); /* 34 */
    int (*tkGetDisplayOf) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tk_Window *tkwinPtr); /* 35 */
    TkWindow * (*tkGetFocusWin) (TkWindow *winPtr); /* 36 */
    int (*tkGetInterpNames) (Tcl_Interp *interp, Tk_Window tkwin); /* 37 */
    int (*tkGetMiterPoints) (double p1[], double p2[], double p3[], double width, double m1[], double m2[]); /* 38 */
    void (*tkGetPointerCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 39 */
    void (*tkGetServerInfo) (Tcl_Interp *interp, Tk_Window tkwin); /* 40 */
    void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */
    int (*tkGrabState) (TkWindow *winPtr); /* 42 */







|







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
    void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */
    void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */
    char * (*tkGetBitmapData) (Tcl_Interp *interp, const char *string, const char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr); /* 30 */
    void (*tkGetButtPoints) (double p1[], double p2[], double width, int project, double m1[], double m2[]); /* 31 */
    TkCursor * (*tkGetCursorByName) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string); /* 32 */
    const char * (*tkGetDefaultScreenName) (Tcl_Interp *interp, const char *screenName); /* 33 */
    TkDisplay * (*tkGetDisplay) (Display *display); /* 34 */
    Tcl_Size (*tkGetDisplayOf) (Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], Tk_Window *tkwinPtr); /* 35 */
    TkWindow * (*tkGetFocusWin) (TkWindow *winPtr); /* 36 */
    int (*tkGetInterpNames) (Tcl_Interp *interp, Tk_Window tkwin); /* 37 */
    int (*tkGetMiterPoints) (double p1[], double p2[], double p3[], double width, double m1[], double m2[]); /* 38 */
    void (*tkGetPointerCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 39 */
    void (*tkGetServerInfo) (Tcl_Interp *interp, Tk_Window tkwin); /* 40 */
    void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */
    int (*tkGrabState) (TkWindow *winPtr); /* 42 */
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
    int (*tkOvalToArea) (double *ovalPtr, double *rectPtr); /* 53 */
    double (*tkOvalToPoint) (double ovalPtr[], double width, int filled, double pointPtr[]); /* 54 */
    int (*tkpChangeFocus) (TkWindow *winPtr, int force); /* 55 */
    void (*tkpCloseDisplay) (TkDisplay *dispPtr); /* 56 */
    void (*tkpClaimFocus) (TkWindow *topLevelPtr, int force); /* 57 */
    void (*tkpDisplayWarning) (const char *msg, const char *title); /* 58 */
    void (*tkpGetAppName) (Tcl_Interp *interp, Tcl_DString *name); /* 59 */
    TkWindow * (*tkpGetOtherWindow) (TkWindow *winPtr); /* 60 */
    TkWindow * (*tkpGetWrapperWindow) (TkWindow *winPtr); /* 61 */
    int (*tkpInit) (Tcl_Interp *interp); /* 62 */
    void (*tkpInitializeMenuBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable); /* 63 */
    void (*tkpMakeContainer) (Tk_Window tkwin); /* 64 */
    void (*tkpMakeMenuWindow) (Tk_Window tkwin, int transient); /* 65 */
    Window (*tkpMakeWindow) (TkWindow *winPtr, Window parent); /* 66 */
    void (*tkpMenuNotifyToplevelCreate) (Tcl_Interp *interp, const char *menuName); /* 67 */
    TkDisplay * (*tkpOpenDisplay) (const char *display_name); /* 68 */
    int (*tkPointerEvent) (XEvent *eventPtr, TkWindow *winPtr); /* 69 */
    int (*tkPolygonToArea) (double *polyPtr, int numPoints, double *rectPtr); /* 70 */
    double (*tkPolygonToPoint) (double *polyPtr, int numPoints, double *pointPtr); /* 71 */
    int (*tkPositionInTree) (TkWindow *winPtr, TkWindow *treePtr); /* 72 */
    void (*tkpRedirectKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 73 */
    void (*tkpSetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, const char *menuName); /* 74 */
    int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, const char *string); /* 75 */
    void (*reserved76)(void);
    void (*tkQueueEventForAllChildren) (TkWindow *winPtr, XEvent *eventPtr); /* 77 */
    int (*tkReadBitmapFile) (Display *display, Drawable d, const char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); /* 78 */
    int (*tkScrollWindow) (Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, Region damageRgn); /* 79 */
    void (*tkSelDeadWindow) (TkWindow *winPtr); /* 80 */
    void (*tkSelEventProc) (Tk_Window tkwin, XEvent *eventPtr); /* 81 */
    void (*tkSelInit) (Tk_Window tkwin); /* 82 */
    void (*tkSelPropProc) (XEvent *eventPtr); /* 83 */
    void (*reserved84)(void);
    void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 85 */
    KeySym (*tkStringToKeysym) (const char *name); /* 86 */
    int (*tkThickPolyLineToArea) (double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr); /* 87 */
    void (*tkWmAddToColormapWindows) (TkWindow *winPtr); /* 88 */
    void (*tkWmDeadWindow) (TkWindow *winPtr); /* 89 */
    TkWindow * (*tkWmFocusToplevel) (TkWindow *winPtr); /* 90 */
    void (*tkWmMapWindow) (TkWindow *winPtr); /* 91 */
    void (*tkWmNewWindow) (TkWindow *winPtr); /* 92 */







|



|

|







|
|









|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
    int (*tkOvalToArea) (double *ovalPtr, double *rectPtr); /* 53 */
    double (*tkOvalToPoint) (double ovalPtr[], double width, int filled, double pointPtr[]); /* 54 */
    int (*tkpChangeFocus) (TkWindow *winPtr, int force); /* 55 */
    void (*tkpCloseDisplay) (TkDisplay *dispPtr); /* 56 */
    void (*tkpClaimFocus) (TkWindow *topLevelPtr, int force); /* 57 */
    void (*tkpDisplayWarning) (const char *msg, const char *title); /* 58 */
    void (*tkpGetAppName) (Tcl_Interp *interp, Tcl_DString *name); /* 59 */
    void (*reserved60)(void);
    TkWindow * (*tkpGetWrapperWindow) (TkWindow *winPtr); /* 61 */
    int (*tkpInit) (Tcl_Interp *interp); /* 62 */
    void (*tkpInitializeMenuBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable); /* 63 */
    void (*reserved64)(void);
    void (*tkpMakeMenuWindow) (Tk_Window tkwin, int transient); /* 65 */
    void (*reserved66)(void);
    void (*tkpMenuNotifyToplevelCreate) (Tcl_Interp *interp, const char *menuName); /* 67 */
    TkDisplay * (*tkpOpenDisplay) (const char *display_name); /* 68 */
    int (*tkPointerEvent) (XEvent *eventPtr, TkWindow *winPtr); /* 69 */
    int (*tkPolygonToArea) (double *polyPtr, int numPoints, double *rectPtr); /* 70 */
    double (*tkPolygonToPoint) (double *polyPtr, int numPoints, double *pointPtr); /* 71 */
    int (*tkPositionInTree) (TkWindow *winPtr, TkWindow *treePtr); /* 72 */
    void (*tkpRedirectKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 73 */
    void (*reserved74)(void);
    void (*reserved75)(void);
    void (*reserved76)(void);
    void (*tkQueueEventForAllChildren) (TkWindow *winPtr, XEvent *eventPtr); /* 77 */
    int (*tkReadBitmapFile) (Display *display, Drawable d, const char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); /* 78 */
    int (*tkScrollWindow) (Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, Region damageRgn); /* 79 */
    void (*tkSelDeadWindow) (TkWindow *winPtr); /* 80 */
    void (*tkSelEventProc) (Tk_Window tkwin, XEvent *eventPtr); /* 81 */
    void (*tkSelInit) (Tk_Window tkwin); /* 82 */
    void (*tkSelPropProc) (XEvent *eventPtr); /* 83 */
    void (*reserved84)(void);
    void (*reserved85)(void);
    KeySym (*tkStringToKeysym) (const char *name); /* 86 */
    int (*tkThickPolyLineToArea) (double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr); /* 87 */
    void (*tkWmAddToColormapWindows) (TkWindow *winPtr); /* 88 */
    void (*tkWmDeadWindow) (TkWindow *winPtr); /* 89 */
    TkWindow * (*tkWmFocusToplevel) (TkWindow *winPtr); /* 90 */
    void (*tkWmMapWindow) (TkWindow *winPtr); /* 91 */
    void (*tkWmNewWindow) (TkWindow *winPtr); /* 92 */
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */
    Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */
    TkDisplay * (*tkGetDisplayList) (void); /* 106 */
    TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */
    int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */
    const char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
    void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */
    Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */
    void (*tkpMenuThreadInit) (void); /* 112 */
    int (*xClipBox) (Region rgn, XRectangle *rect_return); /* 113 */
    Region (*xCreateRegion) (void); /* 114 */
    int (*xDestroyRegion) (Region rgn); /* 115 */
    int (*xIntersectRegion) (Region sra, Region srcb, Region dr_return); /* 116 */
    int (*xRectInRegion) (Region rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
    int (*xSetRegion) (Display *display, GC gc, Region rgn); /* 118 */
    int (*xUnionRectWithRegion) (XRectangle *rect, Region src, Region dr_return); /* 119 */
    void (*reserved120)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved121)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved121)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */
    Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved122)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved122)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */
    void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
    void (*reserved123)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved124)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved124)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */
    Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */
#endif /* AQUA */
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    void (*reserved129)(void);
    void (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*tkpDrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 135 */
    void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */
    void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */
    KeySym (*tkpGetKeySym) (TkDisplay *dispPtr, XEvent *eventPtr); /* 138 */
    void (*tkpInitKeymapInfo) (TkDisplay *dispPtr); /* 139 */
    Region (*tkPhotoGetValidRegion) (Tk_PhotoHandle handle); /* 140 */
    TkWindow ** (*tkWmStackorderToplevel) (TkWindow *parentPtr); /* 141 */
    void (*tkFocusFree) (TkMainInfo *mainPtr); /* 142 */
    void (*tkClipCleanup) (TkDisplay *dispPtr); /* 143 */
    void (*tkGCCleanup) (TkDisplay *dispPtr); /* 144 */
    int (*xSubtractRegion) (Region sra, Region srcb, Region dr_return); /* 145 */
    void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */
    void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */
    Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, const char *cmdName); /* 148 */
    const Tk_OptionSpec * (*tkGetOptionSpec) (const char *name, Tk_OptionTable optionTable); /* 149 */
    int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */
    void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */
    void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */
    void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */
    void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */
    void (*reserved155)(void);
    int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */
    int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */
    int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */
    int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */
    int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */
    int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 161 */
    struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, int byteIndex, struct TkTextIndex *indexPtr); /* 162 */
    TkSizeT (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */
    struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */
    int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */
    void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */
    int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */
    void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */
    int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 169 */
    const char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 170 */
    int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 171 */
    const char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 172 */
    int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 173 */
    const char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 174 */
    int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 175 */
    const char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 176 */
    int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 177 */
    const char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 178 */
    int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 179 */
    const char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 180 */
    void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */
    void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */
    int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */
    void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved185)(void);
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved185)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    void (*tkpRedrawWidget) (Tk_Window tkwin); /* 185 */
#endif /* MACOSX */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved186)(void);
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved186)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
    int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}







|









<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<

<

<
<
<
<
<
<
<
<

<










|

















|
|

|
|
|

|
|
|
|

|



|
|
|
|
|
|
|
|
|
|
|
|
|


|
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<

<







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673








674









675

676








677

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737







738








739

740
741
742
743
744
745
746
    int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */
    Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */
    TkDisplay * (*tkGetDisplayList) (void); /* 106 */
    TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */
    int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */
    const char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
    void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */
    void (*reserved111)(void);
    void (*tkpMenuThreadInit) (void); /* 112 */
    int (*xClipBox) (Region rgn, XRectangle *rect_return); /* 113 */
    Region (*xCreateRegion) (void); /* 114 */
    int (*xDestroyRegion) (Region rgn); /* 115 */
    int (*xIntersectRegion) (Region sra, Region srcb, Region dr_return); /* 116 */
    int (*xRectInRegion) (Region rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
    int (*xSetRegion) (Display *display, GC gc, Region rgn); /* 118 */
    int (*xUnionRectWithRegion) (XRectangle *rect, Region src, Region dr_return); /* 119 */
    void (*reserved120)(void);








    Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */









    void (*tkpDefineNativeBitmaps) (void); /* 122 */

    void (*reserved123)(void);








    Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */

    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    void (*reserved129)(void);
    void (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*reserved135)(void);
    void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */
    void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */
    KeySym (*tkpGetKeySym) (TkDisplay *dispPtr, XEvent *eventPtr); /* 138 */
    void (*tkpInitKeymapInfo) (TkDisplay *dispPtr); /* 139 */
    Region (*tkPhotoGetValidRegion) (Tk_PhotoHandle handle); /* 140 */
    TkWindow ** (*tkWmStackorderToplevel) (TkWindow *parentPtr); /* 141 */
    void (*tkFocusFree) (TkMainInfo *mainPtr); /* 142 */
    void (*tkClipCleanup) (TkDisplay *dispPtr); /* 143 */
    void (*tkGCCleanup) (TkDisplay *dispPtr); /* 144 */
    int (*xSubtractRegion) (Region sra, Region srcb, Region dr_return); /* 145 */
    void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */
    void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */
    Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, const char *cmdName); /* 148 */
    const Tk_OptionSpec * (*tkGetOptionSpec) (const char *name, Tk_OptionTable optionTable); /* 149 */
    int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */
    void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */
    void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */
    void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, void *clientData); /* 153 */
    void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, void *clientData); /* 154 */
    void (*reserved155)(void);
    int (*tkpTestembedCmd) (void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); /* 156 */
    int (*tkpTesttextCmd) (void *dummy, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); /* 157 */
    int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, void *clientData); /* 158 */
    int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */
    int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, Tcl_Size count, struct TkTextIndex *dstPtr); /* 160 */
    int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, Tcl_Size count, struct TkTextIndex *dstPtr); /* 161 */
    struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, Tcl_Size byteIndex, struct TkTextIndex *indexPtr); /* 162 */
    Tcl_Size (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */
    struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */
    int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); /* 165 */
    void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */
    int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */
    void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */
    int (*tkStateParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 169 */
    const char * (*tkStatePrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 170 */
    int (*tkCanvasDashParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 171 */
    const char * (*tkCanvasDashPrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 172 */
    int (*tkOffsetParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 173 */
    const char * (*tkOffsetPrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 174 */
    int (*tkPixelParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 175 */
    const char * (*tkPixelPrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 176 */
    int (*tkOrientParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 177 */
    const char * (*tkOrientPrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 178 */
    int (*tkSmoothParseProc) (void *clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, Tcl_Size offset); /* 179 */
    const char * (*tkSmoothPrintProc) (void *clientData, Tk_Window tkwin, char *widgRec, Tcl_Size offset, Tcl_FreeProc **freeProcPtr); /* 180 */
    void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, Tcl_Size firstChar, Tcl_Size 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, Tcl_Size numBytes, double x, double y, double angle); /* 184 */







    void (*tkpRedrawWidget) (Tk_Window tkwin); /* 185 */








    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */

    int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
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
	(tkIntStubsPtr->tkpCloseDisplay) /* 56 */
#define TkpClaimFocus \
	(tkIntStubsPtr->tkpClaimFocus) /* 57 */
#define TkpDisplayWarning \
	(tkIntStubsPtr->tkpDisplayWarning) /* 58 */
#define TkpGetAppName \
	(tkIntStubsPtr->tkpGetAppName) /* 59 */
#define TkpGetOtherWindow \
	(tkIntStubsPtr->tkpGetOtherWindow) /* 60 */
#define TkpGetWrapperWindow \
	(tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */
#define TkpInit \
	(tkIntStubsPtr->tkpInit) /* 62 */
#define TkpInitializeMenuBindings \
	(tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */
#define TkpMakeContainer \
	(tkIntStubsPtr->tkpMakeContainer) /* 64 */
#define TkpMakeMenuWindow \
	(tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */
#define TkpMakeWindow \
	(tkIntStubsPtr->tkpMakeWindow) /* 66 */

#define TkpMenuNotifyToplevelCreate \
	(tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */
#define TkpOpenDisplay \
	(tkIntStubsPtr->tkpOpenDisplay) /* 68 */
#define TkPointerEvent \
	(tkIntStubsPtr->tkPointerEvent) /* 69 */
#define TkPolygonToArea \
	(tkIntStubsPtr->tkPolygonToArea) /* 70 */
#define TkPolygonToPoint \
	(tkIntStubsPtr->tkPolygonToPoint) /* 71 */
#define TkPositionInTree \
	(tkIntStubsPtr->tkPositionInTree) /* 72 */
#define TkpRedirectKeyEvent \
	(tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */
#define TkpSetMainMenubar \
	(tkIntStubsPtr->tkpSetMainMenubar) /* 74 */
#define TkpUseWindow \
	(tkIntStubsPtr->tkpUseWindow) /* 75 */
/* Slot 76 is reserved */
#define TkQueueEventForAllChildren \
	(tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */
#define TkReadBitmapFile \
	(tkIntStubsPtr->tkReadBitmapFile) /* 78 */
#define TkScrollWindow \
	(tkIntStubsPtr->tkScrollWindow) /* 79 */
#define TkSelDeadWindow \
	(tkIntStubsPtr->tkSelDeadWindow) /* 80 */
#define TkSelEventProc \
	(tkIntStubsPtr->tkSelEventProc) /* 81 */
#define TkSelInit \
	(tkIntStubsPtr->tkSelInit) /* 82 */
#define TkSelPropProc \
	(tkIntStubsPtr->tkSelPropProc) /* 83 */
/* Slot 84 is reserved */
#define TkSetWindowMenuBar \
	(tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */
#define TkStringToKeysym \
	(tkIntStubsPtr->tkStringToKeysym) /* 86 */
#define TkThickPolyLineToArea \
	(tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */
#define TkWmAddToColormapWindows \
	(tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */
#define TkWmDeadWindow \







|
<






|
<


<
<
>














|
<
<
|
















|
<







865
866
867
868
869
870
871
872

873
874
875
876
877
878
879

880
881


882
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
	(tkIntStubsPtr->tkpCloseDisplay) /* 56 */
#define TkpClaimFocus \
	(tkIntStubsPtr->tkpClaimFocus) /* 57 */
#define TkpDisplayWarning \
	(tkIntStubsPtr->tkpDisplayWarning) /* 58 */
#define TkpGetAppName \
	(tkIntStubsPtr->tkpGetAppName) /* 59 */
/* Slot 60 is reserved */

#define TkpGetWrapperWindow \
	(tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */
#define TkpInit \
	(tkIntStubsPtr->tkpInit) /* 62 */
#define TkpInitializeMenuBindings \
	(tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */
/* Slot 64 is reserved */

#define TkpMakeMenuWindow \
	(tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */


/* Slot 66 is reserved */
#define TkpMenuNotifyToplevelCreate \
	(tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */
#define TkpOpenDisplay \
	(tkIntStubsPtr->tkpOpenDisplay) /* 68 */
#define TkPointerEvent \
	(tkIntStubsPtr->tkPointerEvent) /* 69 */
#define TkPolygonToArea \
	(tkIntStubsPtr->tkPolygonToArea) /* 70 */
#define TkPolygonToPoint \
	(tkIntStubsPtr->tkPolygonToPoint) /* 71 */
#define TkPositionInTree \
	(tkIntStubsPtr->tkPositionInTree) /* 72 */
#define TkpRedirectKeyEvent \
	(tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */
/* Slot 74 is reserved */


/* Slot 75 is reserved */
/* Slot 76 is reserved */
#define TkQueueEventForAllChildren \
	(tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */
#define TkReadBitmapFile \
	(tkIntStubsPtr->tkReadBitmapFile) /* 78 */
#define TkScrollWindow \
	(tkIntStubsPtr->tkScrollWindow) /* 79 */
#define TkSelDeadWindow \
	(tkIntStubsPtr->tkSelDeadWindow) /* 80 */
#define TkSelEventProc \
	(tkIntStubsPtr->tkSelEventProc) /* 81 */
#define TkSelInit \
	(tkIntStubsPtr->tkSelInit) /* 82 */
#define TkSelPropProc \
	(tkIntStubsPtr->tkSelPropProc) /* 83 */
/* Slot 84 is reserved */
/* Slot 85 is reserved */

#define TkStringToKeysym \
	(tkIntStubsPtr->tkStringToKeysym) /* 86 */
#define TkThickPolyLineToArea \
	(tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */
#define TkWmAddToColormapWindows \
	(tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */
#define TkWmDeadWindow \
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
	(tkIntStubsPtr->tkGetMainInfoList) /* 107 */
#define TkGetWindowFromObj \
	(tkIntStubsPtr->tkGetWindowFromObj) /* 108 */
#define TkpGetString \
	(tkIntStubsPtr->tkpGetString) /* 109 */
#define TkpGetSubFonts \
	(tkIntStubsPtr->tkpGetSubFonts) /* 110 */
#define TkpGetSystemDefault \
	(tkIntStubsPtr->tkpGetSystemDefault) /* 111 */
#define TkpMenuThreadInit \
	(tkIntStubsPtr->tkpMenuThreadInit) /* 112 */
#define XClipBox \
	(tkIntStubsPtr->xClipBox) /* 113 */
#define XCreateRegion \
	(tkIntStubsPtr->xCreateRegion) /* 114 */
#define XDestroyRegion \
	(tkIntStubsPtr->xDestroyRegion) /* 115 */
#define XIntersectRegion \
	(tkIntStubsPtr->xIntersectRegion) /* 116 */
#define XRectInRegion \
	(tkIntStubsPtr->xRectInRegion) /* 117 */
#define XSetRegion \
	(tkIntStubsPtr->xSetRegion) /* 118 */
#define XUnionRectWithRegion \
	(tkIntStubsPtr->xUnionRectWithRegion) /* 119 */
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpCreateNativeBitmap \
	(tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpDefineNativeBitmaps \
	(tkIntStubsPtr->tkpDefineNativeBitmaps) /* 122 */
#endif /* AQUA */
/* Slot 123 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpGetNativeAppBitmap \
	(tkIntStubsPtr->tkpGetNativeAppBitmap) /* 124 */
#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
#define TkpDrawHighlightBorder \
	(tkIntStubsPtr->tkpDrawHighlightBorder) /* 135 */
#define TkSetFocusWin \
	(tkIntStubsPtr->tkSetFocusWin) /* 136 */
#define TkpSetKeycodeAndState \
	(tkIntStubsPtr->tkpSetKeycodeAndState) /* 137 */
#define TkpGetKeySym \
	(tkIntStubsPtr->tkpGetKeySym) /* 138 */
#define TkpInitKeymapInfo \







<
|

















<


<
<


<

<


<










<
|







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
	(tkIntStubsPtr->tkGetMainInfoList) /* 107 */
#define TkGetWindowFromObj \
	(tkIntStubsPtr->tkGetWindowFromObj) /* 108 */
#define TkpGetString \
	(tkIntStubsPtr->tkpGetString) /* 109 */
#define TkpGetSubFonts \
	(tkIntStubsPtr->tkpGetSubFonts) /* 110 */

/* Slot 111 is reserved */
#define TkpMenuThreadInit \
	(tkIntStubsPtr->tkpMenuThreadInit) /* 112 */
#define XClipBox \
	(tkIntStubsPtr->xClipBox) /* 113 */
#define XCreateRegion \
	(tkIntStubsPtr->xCreateRegion) /* 114 */
#define XDestroyRegion \
	(tkIntStubsPtr->xDestroyRegion) /* 115 */
#define XIntersectRegion \
	(tkIntStubsPtr->xIntersectRegion) /* 116 */
#define XRectInRegion \
	(tkIntStubsPtr->xRectInRegion) /* 117 */
#define XSetRegion \
	(tkIntStubsPtr->xSetRegion) /* 118 */
#define XUnionRectWithRegion \
	(tkIntStubsPtr->xUnionRectWithRegion) /* 119 */
/* Slot 120 is reserved */

#define TkpCreateNativeBitmap \
	(tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */


#define TkpDefineNativeBitmaps \
	(tkIntStubsPtr->tkpDefineNativeBitmaps) /* 122 */

/* Slot 123 is reserved */

#define TkpGetNativeAppBitmap \
	(tkIntStubsPtr->tkpGetNativeAppBitmap) /* 124 */

/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* Slot 129 is reserved */
/* Slot 130 is reserved */
/* Slot 131 is reserved */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */

/* Slot 135 is reserved */
#define TkSetFocusWin \
	(tkIntStubsPtr->tkSetFocusWin) /* 136 */
#define TkpSetKeycodeAndState \
	(tkIntStubsPtr->tkpSetKeycodeAndState) /* 137 */
#define TkpGetKeySym \
	(tkIntStubsPtr->tkpGetKeySym) /* 138 */
#define TkpInitKeymapInfo \
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 */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpRedrawWidget \
	(tkIntStubsPtr->tkpRedrawWidget) /* 185 */
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpWillDrawWidget \
	(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
#define TkDebugPhotoStringMatchDef \
	(tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 187 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkpCmapStressed_
#undef TkpSync_
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_

#if !defined(MAC_OSX_TK)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget



#   define TkpWillDrawWidget(w) 0
#   define TkpRedrawWidget(w)



#endif

#endif /* _TKINTDECLS */







<


<
<


<










<
<
<
<
<
<
<
<
<
|


>
>
>


>
>
>



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
	(tkIntStubsPtr->tkDrawAngledTextLayout) /* 181 */
#define TkUnderlineAngledTextLayout \
	(tkIntStubsPtr->tkUnderlineAngledTextLayout) /* 182 */
#define TkIntersectAngledTextLayout \
	(tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */
#define TkDrawAngledChars \
	(tkIntStubsPtr->tkDrawAngledChars) /* 184 */

#define TkpRedrawWidget \
	(tkIntStubsPtr->tkpRedrawWidget) /* 185 */


#define TkpWillDrawWidget \
	(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */

#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










#if !defined(MAC_OSX_TK) && !defined(USE_TK_STUBS)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   undef TkpDefineNativeBitmaps
#   undef TkpCreateNativeBitmap
#   undef TkpGetNativeAppBitmap
#   define TkpWillDrawWidget(w) 0
#   define TkpRedrawWidget(w)
#   define TkpDefineNativeBitmaps()
#   define TkpCreateNativeBitmap(display, source) None
#   define TkpGetNativeAppBitmap(display, name, w, h) None
#endif

#endif /* _TKINTDECLS */

Changes to generic/tkIntPlatDecls.h.

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.
 * All rights reserved.
 */

#ifndef _TKINTPLATDECLS
#define _TKINTPLATDECLS

#ifdef BUILD_tk








|







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 Scriptics Corporation.
 * All rights reserved.
 */

#ifndef _TKINTPLATDECLS
#define _TKINTPLATDECLS

#ifdef BUILD_tk
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

/*
 * Exported function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN char *		TkAlignImageData(XImage *image, int alignment,
				int bitOrder);
/* Slot 1 is reserved */
/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);
/* 3 */
EXTERN unsigned long	TkpGetMS(void);
/* 4 */







|
<







32
33
34
35
36
37
38
39

40
41
42
43
44
45
46

/*
 * Exported function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN void		TkCreateXEventSource(void);

/* Slot 1 is reserved */
/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);
/* 3 */
EXTERN unsigned long	TkpGetMS(void);
/* 4 */
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
EXTERN void		TkWinSetMenu(Tk_Window tkwin, HMENU hMenu);
/* 26 */
EXTERN void		TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd,
				int pos);
/* 27 */
EXTERN void		TkWinWmCleanup(HINSTANCE hInstance);
/* 28 */
EXTERN void		TkWinXCleanup(ClientData clientData);
/* 29 */
EXTERN void		TkWinXInit(HINSTANCE hInstance);
/* 30 */
EXTERN void		TkWinSetForegroundWindow(TkWindow *winPtr);
/* 31 */
EXTERN void		TkWinDialogDebug(int debug);
/* 32 */
EXTERN Tcl_Obj *	TkWinGetMenuSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);
/* 33 */
EXTERN int		TkWinGetPlatformId(void);

/* 34 */
EXTERN void		TkWinSetHINSTANCE(HINSTANCE hInstance);
/* 35 */
EXTERN int		TkWinGetPlatformTheme(void);
/* 36 */
EXTERN LRESULT __stdcall TkWinChildProc(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam);
/* 37 */
EXTERN void		TkCreateXEventSource(void);
/* 38 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
/* 39 */
EXTERN void		TkpSync(Display *display);
/* 40 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);
/* 41 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);
/* 42 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
/* 43 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
/* 44 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);
/* 45 */
EXTERN int		TkpTestsendCmd(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* Slot 46 is reserved */
/* 47 */
EXTERN Tk_Window	TkpGetCapture(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */

/* 0 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);
/* Slot 1 is reserved */
/* 2 */
EXTERN void		TkGenerateActivateEvents_(TkWindow *winPtr,
				int active);
/* 3 */
EXTERN void		TkPointerDeadWindow(TkWindow *winPtr);
/* 4 */
EXTERN void		TkpSetCapture(TkWindow *winPtr);
/* 5 */
EXTERN void		TkpSetCursor(TkpCursor cursor);
/* 6 */

EXTERN void		TkpWmSetState(TkWindow *winPtr, int state);
/* 7 */
EXTERN void		TkAboutDlg(void);
/* 8 */
EXTERN unsigned int	TkMacOSXButtonKeyState(void);
/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);
/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);
/* Slot 11 is reserved */

/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);
/* Slot 13 is reserved */
/* 14 */
EXTERN int		TkMacOSXDoHLEvent(void *theEvent);
/* Slot 15 is reserved */
/* 16 */
EXTERN Window		TkMacOSXGetXWindow(void *macWinPtr);
/* 17 */
EXTERN int		TkMacOSXGrowToplevel(void *whichWindow, XPoint start);
/* 18 */
EXTERN void		TkMacOSXHandleMenuSelect(short theMenu,
				unsigned short theItem, int optionKeyPressed);
/* Slot 19 is reserved */
/* Slot 20 is reserved */
/* 21 */
EXTERN void		TkMacOSXInvalidateWindow(MacDrawable *macWin,
				int flag);
/* 22 */
EXTERN int		TkMacOSXIsCharacterMissing(Tk_Font tkfont,
				unsigned int searchChar);
/* 23 */
EXTERN void		TkMacOSXMakeRealWindowExist(TkWindow *winPtr);
/* 24 */
EXTERN void *		TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);
/* 25 */
EXTERN void		TkMacOSXMenuClick(void);
/* Slot 26 is reserved */
/* 27 */
EXTERN int		TkMacOSXResizable(TkWindow *winPtr);
/* 28 */
EXTERN void		TkMacOSXSetHelpMenuItemCount(void);
/* 29 */
EXTERN void		TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag);
/* 30 */
EXTERN void		TkMacOSXSetUpClippingRgn(Drawable drawable);
/* 31 */
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
/* Slot 33 is reserved */
/* 34 */
EXTERN int		TkMacOSXUseMenuID(short macID);







|










|
>







|
<















|
<
|





>
|
|
<
<

|


|

|



>
|

|






|
>


















|
<
<













|
<







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191


192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
EXTERN void		TkWinSetMenu(Tk_Window tkwin, HMENU hMenu);
/* 26 */
EXTERN void		TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd,
				int pos);
/* 27 */
EXTERN void		TkWinWmCleanup(HINSTANCE hInstance);
/* 28 */
EXTERN void		TkWinXCleanup(void *clientData);
/* 29 */
EXTERN void		TkWinXInit(HINSTANCE hInstance);
/* 30 */
EXTERN void		TkWinSetForegroundWindow(TkWindow *winPtr);
/* 31 */
EXTERN void		TkWinDialogDebug(int debug);
/* 32 */
EXTERN Tcl_Obj *	TkWinGetMenuSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);
/* 33 */
EXTERN char *		TkAlignImageData(XImage *image, int alignment,
				int bitOrder);
/* 34 */
EXTERN void		TkWinSetHINSTANCE(HINSTANCE hInstance);
/* 35 */
EXTERN int		TkWinGetPlatformTheme(void);
/* 36 */
EXTERN LRESULT __stdcall TkWinChildProc(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam);
/* Slot 37 is reserved */

/* 38 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
/* 39 */
EXTERN void		TkpSync(Display *display);
/* 40 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);
/* 41 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);
/* 42 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
/* 43 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
/* 44 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);
/* 45 */
EXTERN int		TkpTestsendCmd(void *clientData, Tcl_Interp *interp,

				Tcl_Size objc, Tcl_Obj *const objv[]);
/* Slot 46 is reserved */
/* 47 */
EXTERN Tk_Window	TkpGetCapture(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* 1 */
EXTERN void		TkAboutDlg(void);


/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);
/* 3 */
EXTERN unsigned long	TkpGetMS(void);
/* 4 */
EXTERN void		TkPointerDeadWindow(TkWindow *winPtr);
/* 5 */
EXTERN void		TkpSetCursor(TkpCursor cursor);
/* 6 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				const char *string, Window *idPtr);
/* 7 */
EXTERN int		TkpWmSetState(TkWindow *winPtr, int state);
/* 8 */
EXTERN unsigned int	TkMacOSXButtonKeyState(void);
/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);
/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);
/* 11 */
EXTERN void		TkpSetCapture(TkWindow *winPtr);
/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);
/* Slot 13 is reserved */
/* 14 */
EXTERN int		TkMacOSXDoHLEvent(void *theEvent);
/* Slot 15 is reserved */
/* 16 */
EXTERN Window		TkMacOSXGetXWindow(void *macWinPtr);
/* 17 */
EXTERN int		TkMacOSXGrowToplevel(void *whichWindow, XPoint start);
/* 18 */
EXTERN void		TkMacOSXHandleMenuSelect(short theMenu,
				unsigned short theItem, int optionKeyPressed);
/* Slot 19 is reserved */
/* Slot 20 is reserved */
/* 21 */
EXTERN void		TkMacOSXInvalidateWindow(MacDrawable *macWin,
				int flag);
/* Slot 22 is reserved */


/* 23 */
EXTERN void		TkMacOSXMakeRealWindowExist(TkWindow *winPtr);
/* 24 */
EXTERN void *		TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);
/* 25 */
EXTERN void		TkMacOSXMenuClick(void);
/* Slot 26 is reserved */
/* 27 */
EXTERN int		TkMacOSXResizable(TkWindow *winPtr);
/* 28 */
EXTERN void		TkMacOSXSetHelpMenuItemCount(void);
/* 29 */
EXTERN void		TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag);
/* Slot 30 is reserved */

/* 31 */
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
/* Slot 33 is reserved */
/* 34 */
EXTERN int		TkMacOSXUseMenuID(short macID);
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282


283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/* 50 */
EXTERN int		TkGenerateButtonEvent(int x, int y, Window window,
				unsigned int state);
/* 51 */
EXTERN void		TkGenWMDestroyEvent(Tk_Window tkwin);
/* 52 */
EXTERN void		TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);
/* 53 */
EXTERN unsigned long	TkpGetMS(void);
/* 54 */
EXTERN void *		TkMacOSXDrawable(Drawable drawable);
/* 55 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				const char *string, Window *idPtr);
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
/* 0 */
EXTERN void		TkCreateXEventSource(void);
/* Slot 1 is reserved */
/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);
/* 3 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
/* 4 */
EXTERN void		TkpSync(Display *display);
/* 5 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);
/* 6 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);
/* 7 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
/* 8 */
EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				const char *string, Window *idPtr);


/* 9 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
/* 10 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);
/* Slot 11 is reserved */
/* 12 */
EXTERN int		TkpWmSetState(TkWindow *winPtr, int state);
/* 13 */
EXTERN int		TkpTestsendCmd(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */







<
<
<
<
<
<
<








|
<
|
<
|
<

<
<
<
<


>
>

|
|
<

|
<
|
<
<
<







244
245
246
247
248
249
250







251
252
253
254
255
256
257
258
259

260

261

262




263
264
265
266
267
268
269

270
271

272



273
274
275
276
277
278
279
/* 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);







#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
/* 0 */
EXTERN void		TkCreateXEventSource(void);
/* Slot 1 is reserved */
/* 2 */
EXTERN void		TkGenerateActivateEvents(TkWindow *winPtr,
				int active);
/* Slot 3 is reserved */

/* Slot 4 is reserved */

/* Slot 5 is reserved */

/* 6 */




EXTERN int		TkpScanWindowId(Tcl_Interp *interp,
				const char *string, Window *idPtr);
/* Slot 7 is reserved */
/* Slot 8 is reserved */
/* 9 */
EXTERN int		TkpWmSetState(TkWindow *winPtr, int state);
/* Slot 10 is reserved */

/* Slot 11 is reserved */
/* Slot 12 is reserved */

/* Slot 13 is reserved */



/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
/* Slot 32 is reserved */
/* Slot 33 is reserved */
/* Slot 34 is reserved */
/* Slot 35 is reserved */
/* Slot 36 is reserved */
/* Slot 37 is reserved */
/* 38 */
EXTERN int		TkpCmapStressed_(Tk_Window tkwin, Colormap colormap);
/* 39 */
EXTERN void		TkpSync_(Display *display);
/* 40 */
EXTERN Window		TkUnixContainerId_(TkWindow *winPtr);
/* 41 */
EXTERN int		TkUnixDoOneXEvent_(Tcl_Time *timePtr);
/* 42 */
EXTERN void		TkUnixSetMenubar_(Tk_Window tkwin, Tk_Window menubar);
/* 43 */
EXTERN void		TkWmCleanup_(TkDisplay *dispPtr);
/* 44 */
EXTERN void		TkSendCleanup_(TkDisplay *dispPtr);
/* 45 */
EXTERN int		TkpTestsendCmd_(ClientData clientData,
				Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[]);
#endif /* X11 */

typedef struct TkIntPlatStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */
    void (*reserved1)(void);
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
    unsigned long (*tkpGetMS) (void); /* 3 */
    void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 4 */
    void (*tkpPrintWindowId) (char *buf, Window window); /* 5 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 6 */
    void (*tkpSetCapture) (TkWindow *winPtr); /* 7 */







|

|

|

|

|

|

|

|
<
|







|







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
/* Slot 32 is reserved */
/* Slot 33 is reserved */
/* Slot 34 is reserved */
/* Slot 35 is reserved */
/* Slot 36 is reserved */
/* Slot 37 is reserved */
/* 38 */
EXTERN int		TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
/* 39 */
EXTERN void		TkpSync(Display *display);
/* 40 */
EXTERN Window		TkUnixContainerId(TkWindow *winPtr);
/* 41 */
EXTERN int		TkUnixDoOneXEvent(Tcl_Time *timePtr);
/* 42 */
EXTERN void		TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
/* 43 */
EXTERN void		TkWmCleanup(TkDisplay *dispPtr);
/* 44 */
EXTERN void		TkSendCleanup(TkDisplay *dispPtr);
/* 45 */
EXTERN int		TkpTestsendCmd(void *clientData, Tcl_Interp *interp,

				Tcl_Size objc, Tcl_Obj *const objv[]);
#endif /* X11 */

typedef struct TkIntPlatStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    void (*tkCreateXEventSource) (void); /* 0 */
    void (*reserved1)(void);
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
    unsigned long (*tkpGetMS) (void); /* 3 */
    void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 4 */
    void (*tkpPrintWindowId) (char *buf, Window window); /* 5 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 6 */
    void (*tkpSetCapture) (TkWindow *winPtr); /* 7 */
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

395

396
397
398

399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
    int (*tkWinIndexOfColor) (XColor *colorPtr); /* 21 */
    void (*tkWinReleaseDrawableDC) (Drawable d, HDC hdc, TkWinDCState *state); /* 22 */
    LRESULT (*tkWinResendEvent) (WNDPROC wndproc, HWND hwnd, XEvent *eventPtr); /* 23 */
    HPALETTE (*tkWinSelectPalette) (HDC dc, Colormap colormap); /* 24 */
    void (*tkWinSetMenu) (Tk_Window tkwin, HMENU hMenu); /* 25 */
    void (*tkWinSetWindowPos) (HWND hwnd, HWND siblingHwnd, int pos); /* 26 */
    void (*tkWinWmCleanup) (HINSTANCE hInstance); /* 27 */
    void (*tkWinXCleanup) (ClientData clientData); /* 28 */
    void (*tkWinXInit) (HINSTANCE hInstance); /* 29 */
    void (*tkWinSetForegroundWindow) (TkWindow *winPtr); /* 30 */
    void (*tkWinDialogDebug) (int debug); /* 31 */
    Tcl_Obj * (*tkWinGetMenuSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 32 */
    int (*tkWinGetPlatformId) (void); /* 33 */
    void (*tkWinSetHINSTANCE) (HINSTANCE hInstance); /* 34 */
    int (*tkWinGetPlatformTheme) (void); /* 35 */
    LRESULT (__stdcall *tkWinChildProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* 36 */
    void (*tkCreateXEventSource) (void); /* 37 */
    int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 38 */
    void (*tkpSync) (Display *display); /* 39 */
    Window (*tkUnixContainerId) (TkWindow *winPtr); /* 40 */
    int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 41 */
    void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */
    void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */
    void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */
    int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 45 */
    void (*reserved46)(void);
    Tk_Window (*tkpGetCapture) (void); /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 0 */
    void (*reserved1)(void);

    void (*tkGenerateActivateEvents_) (TkWindow *winPtr, int active); /* 2 */

    void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 3 */
    void (*tkpSetCapture) (TkWindow *winPtr); /* 4 */
    void (*tkpSetCursor) (TkpCursor cursor); /* 5 */

    void (*tkpWmSetState) (TkWindow *winPtr, int state); /* 6 */
    void (*tkAboutDlg) (void); /* 7 */
    unsigned int (*tkMacOSXButtonKeyState) (void); /* 8 */
    void (*tkMacOSXClearMenubarActive) (void); /* 9 */
    int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */
    void (*reserved11)(void);
    void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */
    void (*reserved13)(void);
    int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */
    void (*reserved15)(void);
    Window (*tkMacOSXGetXWindow) (void *macWinPtr); /* 16 */
    int (*tkMacOSXGrowToplevel) (void *whichWindow, XPoint start); /* 17 */
    void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */
    void (*reserved19)(void);
    void (*reserved20)(void);
    void (*tkMacOSXInvalidateWindow) (MacDrawable *macWin, int flag); /* 21 */
    int (*tkMacOSXIsCharacterMissing) (Tk_Font tkfont, unsigned int searchChar); /* 22 */
    void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */
    void * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */
    void (*tkMacOSXMenuClick) (void); /* 25 */
    void (*reserved26)(void);
    int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */
    void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
    void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
    void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */
    void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */
    void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
    void (*reserved33)(void);
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    Region (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */







|




|



|







|




<
|
>
|
>
|
<

>
|
<



|










|







|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

371
372
373
374
375

376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
    int (*tkWinIndexOfColor) (XColor *colorPtr); /* 21 */
    void (*tkWinReleaseDrawableDC) (Drawable d, HDC hdc, TkWinDCState *state); /* 22 */
    LRESULT (*tkWinResendEvent) (WNDPROC wndproc, HWND hwnd, XEvent *eventPtr); /* 23 */
    HPALETTE (*tkWinSelectPalette) (HDC dc, Colormap colormap); /* 24 */
    void (*tkWinSetMenu) (Tk_Window tkwin, HMENU hMenu); /* 25 */
    void (*tkWinSetWindowPos) (HWND hwnd, HWND siblingHwnd, int pos); /* 26 */
    void (*tkWinWmCleanup) (HINSTANCE hInstance); /* 27 */
    void (*tkWinXCleanup) (void *clientData); /* 28 */
    void (*tkWinXInit) (HINSTANCE hInstance); /* 29 */
    void (*tkWinSetForegroundWindow) (TkWindow *winPtr); /* 30 */
    void (*tkWinDialogDebug) (int debug); /* 31 */
    Tcl_Obj * (*tkWinGetMenuSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 32 */
    char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 33 */
    void (*tkWinSetHINSTANCE) (HINSTANCE hInstance); /* 34 */
    int (*tkWinGetPlatformTheme) (void); /* 35 */
    LRESULT (__stdcall *tkWinChildProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* 36 */
    void (*reserved37)(void);
    int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 38 */
    void (*tkpSync) (Display *display); /* 39 */
    Window (*tkUnixContainerId) (TkWindow *winPtr); /* 40 */
    int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 41 */
    void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */
    void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */
    void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */
    int (*tkpTestsendCmd) (void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); /* 45 */
    void (*reserved46)(void);
    Tk_Window (*tkpGetCapture) (void); /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */

    void (*reserved0)(void);
    void (*tkAboutDlg) (void); /* 1 */
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
    unsigned long (*tkpGetMS) (void); /* 3 */
    void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 4 */

    void (*tkpSetCursor) (TkpCursor cursor); /* 5 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 6 */
    int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 7 */

    unsigned int (*tkMacOSXButtonKeyState) (void); /* 8 */
    void (*tkMacOSXClearMenubarActive) (void); /* 9 */
    int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */
    void (*tkpSetCapture) (TkWindow *winPtr); /* 11 */
    void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */
    void (*reserved13)(void);
    int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */
    void (*reserved15)(void);
    Window (*tkMacOSXGetXWindow) (void *macWinPtr); /* 16 */
    int (*tkMacOSXGrowToplevel) (void *whichWindow, XPoint start); /* 17 */
    void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */
    void (*reserved19)(void);
    void (*reserved20)(void);
    void (*tkMacOSXInvalidateWindow) (MacDrawable *macWin, int flag); /* 21 */
    void (*reserved22)(void);
    void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */
    void * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */
    void (*tkMacOSXMenuClick) (void); /* 25 */
    void (*reserved26)(void);
    int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */
    void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
    void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
    void (*reserved30)(void);
    void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */
    void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
    void (*reserved33)(void);
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    Region (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463



464
465
466
467
468
469
470
471
    int (*tkpIsWindowFloating) (void *window); /* 46 */
    Tk_Window (*tkpGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkMacOSXGetContainer) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
    unsigned long (*tkpGetMS) (void); /* 53 */
    void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    void (*tkCreateXEventSource) (void); /* 0 */
    void (*reserved1)(void);
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
    int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 3 */
    void (*tkpSync) (Display *display); /* 4 */
    Window (*tkUnixContainerId) (TkWindow *winPtr); /* 5 */
    int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 6 */
    void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 7 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 8 */
    void (*tkWmCleanup) (TkDisplay *dispPtr); /* 9 */
    void (*tkSendCleanup) (TkDisplay *dispPtr); /* 10 */
    void (*reserved11)(void);
    int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 12 */



    int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 13 */
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*reserved16)(void);
    void (*reserved17)(void);
    void (*reserved18)(void);
    void (*reserved19)(void);
    void (*reserved20)(void);







<
<
<





|
|
<
<
|
|
|
<
|
|
>
>
>
|







417
418
419
420
421
422
423



424
425
426
427
428
429
430


431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
    int (*tkpIsWindowFloating) (void *window); /* 46 */
    Tk_Window (*tkpGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkMacOSXGetContainer) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */



#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    void (*tkCreateXEventSource) (void); /* 0 */
    void (*reserved1)(void);
    void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
    void (*reserved3)(void);
    void (*reserved4)(void);


    void (*reserved5)(void);
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 6 */
    void (*reserved7)(void);

    void (*reserved8)(void);
    int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 9 */
    void (*reserved10)(void);
    void (*reserved11)(void);
    void (*reserved12)(void);
    void (*reserved13)(void);
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*reserved16)(void);
    void (*reserved17)(void);
    void (*reserved18)(void);
    void (*reserved19)(void);
    void (*reserved20)(void);
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
    void (*reserved31)(void);
    void (*reserved32)(void);
    void (*reserved33)(void);
    void (*reserved34)(void);
    void (*reserved35)(void);
    void (*reserved36)(void);
    void (*reserved37)(void);
    int (*tkpCmapStressed_) (Tk_Window tkwin, Colormap colormap); /* 38 */
    void (*tkpSync_) (Display *display); /* 39 */
    Window (*tkUnixContainerId_) (TkWindow *winPtr); /* 40 */
    int (*tkUnixDoOneXEvent_) (Tcl_Time *timePtr); /* 41 */
    void (*tkUnixSetMenubar_) (Tk_Window tkwin, Tk_Window menubar); /* 42 */
    void (*tkWmCleanup_) (TkDisplay *dispPtr); /* 43 */
    void (*tkSendCleanup_) (TkDisplay *dispPtr); /* 44 */
    int (*tkpTestsendCmd_) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 45 */
#endif /* X11 */
} TkIntPlatStubs;

extern const TkIntPlatStubs *tkIntPlatStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define TkAlignImageData \
	(tkIntPlatStubsPtr->tkAlignImageData) /* 0 */
/* Slot 1 is reserved */
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */
#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 3 */
#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */







|
|
|
|
|
|
|
|
















|
|







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
    void (*reserved31)(void);
    void (*reserved32)(void);
    void (*reserved33)(void);
    void (*reserved34)(void);
    void (*reserved35)(void);
    void (*reserved36)(void);
    void (*reserved37)(void);
    int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 38 */
    void (*tkpSync) (Display *display); /* 39 */
    Window (*tkUnixContainerId) (TkWindow *winPtr); /* 40 */
    int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 41 */
    void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */
    void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */
    void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */
    int (*tkpTestsendCmd) (void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); /* 45 */
#endif /* X11 */
} TkIntPlatStubs;

extern const TkIntPlatStubs *tkIntPlatStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TK_STUBS)

/*
 * Inline function declarations:
 */

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */
/* Slot 1 is reserved */
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */
#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 3 */
#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
	(tkIntPlatStubsPtr->tkWinXInit) /* 29 */
#define TkWinSetForegroundWindow \
	(tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 30 */
#define TkWinDialogDebug \
	(tkIntPlatStubsPtr->tkWinDialogDebug) /* 31 */
#define TkWinGetMenuSystemDefault \
	(tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 32 */
#define TkWinGetPlatformId \
	(tkIntPlatStubsPtr->tkWinGetPlatformId) /* 33 */
#define TkWinSetHINSTANCE \
	(tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */
#define TkWinGetPlatformTheme \
	(tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */
#define TkWinChildProc \
	(tkIntPlatStubsPtr->tkWinChildProc) /* 36 */
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 37 */
#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */
#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 39 */
#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */
#define TkUnixDoOneXEvent \







|
|






|
<







546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
	(tkIntPlatStubsPtr->tkWinXInit) /* 29 */
#define TkWinSetForegroundWindow \
	(tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 30 */
#define TkWinDialogDebug \
	(tkIntPlatStubsPtr->tkWinDialogDebug) /* 31 */
#define TkWinGetMenuSystemDefault \
	(tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 32 */
#define TkAlignImageData \
	(tkIntPlatStubsPtr->tkAlignImageData) /* 33 */
#define TkWinSetHINSTANCE \
	(tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */
#define TkWinGetPlatformTheme \
	(tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */
#define TkWinChildProc \
	(tkIntPlatStubsPtr->tkWinChildProc) /* 36 */
/* Slot 37 is reserved */

#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */
#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 39 */
#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */
#define TkUnixDoOneXEvent \
602
603
604
605
606
607
608



609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */
/* Slot 46 is reserved */
#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */



#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 0 */
/* Slot 1 is reserved */
#define TkGenerateActivateEvents_ \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents_) /* 2 */
#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 3 */
#define TkpSetCapture \
	(tkIntPlatStubsPtr->tkpSetCapture) /* 4 */
#define TkpSetCursor \
	(tkIntPlatStubsPtr->tkpSetCursor) /* 5 */
#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 6 */
#define TkAboutDlg \
	(tkIntPlatStubsPtr->tkAboutDlg) /* 7 */
#define TkMacOSXButtonKeyState \
	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */
#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */
/* Slot 11 is reserved */

#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
/* Slot 13 is reserved */
#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
/* Slot 15 is reserved */
#define TkMacOSXGetXWindow \
	(tkIntPlatStubsPtr->tkMacOSXGetXWindow) /* 16 */
#define TkMacOSXGrowToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGrowToplevel) /* 17 */
#define TkMacOSXHandleMenuSelect \
	(tkIntPlatStubsPtr->tkMacOSXHandleMenuSelect) /* 18 */
/* Slot 19 is reserved */
/* Slot 20 is reserved */
#define TkMacOSXInvalidateWindow \
	(tkIntPlatStubsPtr->tkMacOSXInvalidateWindow) /* 21 */
#define TkMacOSXIsCharacterMissing \
	(tkIntPlatStubsPtr->tkMacOSXIsCharacterMissing) /* 22 */
#define TkMacOSXMakeRealWindowExist \
	(tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */
#define TkMacOSXMakeStippleMap \
	(tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */
#define TkMacOSXMenuClick \
	(tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */
/* Slot 26 is reserved */
#define TkMacOSXResizable \
	(tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */
#define TkMacOSXSetHelpMenuItemCount \
	(tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */
#define TkMacOSXSetScrollbarGrow \
	(tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */
#define TkMacOSXSetUpClippingRgn \
	(tkIntPlatStubsPtr->tkMacOSXSetUpClippingRgn) /* 30 */
#define TkMacOSXSetUpGraphicsPort \
	(tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */
#define TkMacOSXUpdateClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */
/* Slot 33 is reserved */
#define TkMacOSXUseMenuID \
	(tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */







>
>
>

|
<
|
|

|
|
|
|
|

|
<
<






|
>
















|
<













|
<







576
577
578
579
580
581
582
583
584
585
586
587

588
589
590
591
592
593
594
595
596
597


598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */
/* Slot 46 is reserved */
#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
#define TkAboutDlg \
	(tkIntPlatStubsPtr->tkAboutDlg) /* 1 */
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */

#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 3 */
#define TkPointerDeadWindow \
	(tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */
#define TkpSetCursor \
	(tkIntPlatStubsPtr->tkpSetCursor) /* 5 */
#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 6 */
#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 7 */


#define TkMacOSXButtonKeyState \
	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */
#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */
#define TkpSetCapture \
	(tkIntPlatStubsPtr->tkpSetCapture) /* 11 */
#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
/* Slot 13 is reserved */
#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
/* Slot 15 is reserved */
#define TkMacOSXGetXWindow \
	(tkIntPlatStubsPtr->tkMacOSXGetXWindow) /* 16 */
#define TkMacOSXGrowToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGrowToplevel) /* 17 */
#define TkMacOSXHandleMenuSelect \
	(tkIntPlatStubsPtr->tkMacOSXHandleMenuSelect) /* 18 */
/* Slot 19 is reserved */
/* Slot 20 is reserved */
#define TkMacOSXInvalidateWindow \
	(tkIntPlatStubsPtr->tkMacOSXInvalidateWindow) /* 21 */
/* Slot 22 is reserved */

#define TkMacOSXMakeRealWindowExist \
	(tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */
#define TkMacOSXMakeStippleMap \
	(tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */
#define TkMacOSXMenuClick \
	(tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */
/* Slot 26 is reserved */
#define TkMacOSXResizable \
	(tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */
#define TkMacOSXSetHelpMenuItemCount \
	(tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */
#define TkMacOSXSetScrollbarGrow \
	(tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */
/* Slot 30 is reserved */

#define TkMacOSXSetUpGraphicsPort \
	(tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */
#define TkMacOSXUpdateClipRgn \
	(tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */
/* Slot 33 is reserved */
#define TkMacOSXUseMenuID \
	(tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734

735
736
737
738




739
740
741
742
743
744
745
	(tkIntPlatStubsPtr->tkMacOSXGetContainer) /* 49 */
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#define TkpGetMS \
	(tkIntPlatStubsPtr->tkpGetMS) /* 53 */
#define TkMacOSXDrawable \
	(tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */
#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 55 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */
/* Slot 1 is reserved */
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */
#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 3 */
#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 4 */
#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 5 */
#define TkUnixDoOneXEvent \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 6 */
#define TkUnixSetMenubar \
	(tkIntPlatStubsPtr->tkUnixSetMenubar) /* 7 */
#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 8 */
#define TkWmCleanup \
	(tkIntPlatStubsPtr->tkWmCleanup) /* 9 */
#define TkSendCleanup \
	(tkIntPlatStubsPtr->tkSendCleanup) /* 10 */
/* Slot 11 is reserved */

#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 12 */
#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 13 */




/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */







<
<
<
<
<
<







|
|
<
|
<
<
<
<
<
<

|
<
<
<
<
|
>

|
<
<
>
>
>
>







671
672
673
674
675
676
677






678
679
680
681
682
683
684
685
686

687






688
689




690
691
692
693


694
695
696
697
698
699
700
701
702
703
704
	(tkIntPlatStubsPtr->tkMacOSXGetContainer) /* 49 */
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */






#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#define TkCreateXEventSource \
	(tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */
/* Slot 1 is reserved */
#define TkGenerateActivateEvents \
	(tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */
/* Slot 3 is reserved */
/* Slot 4 is reserved */

/* Slot 5 is reserved */






#define TkpScanWindowId \
	(tkIntPlatStubsPtr->tkpScanWindowId) /* 6 */




/* Slot 7 is reserved */
/* Slot 8 is reserved */
#define TkpWmSetState \
	(tkIntPlatStubsPtr->tkpWmSetState) /* 9 */


/* Slot 10 is reserved */
/* Slot 11 is reserved */
/* Slot 12 is reserved */
/* Slot 13 is reserved */
/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* Slot 20 is reserved */
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
/* Slot 31 is reserved */
/* Slot 32 is reserved */
/* Slot 33 is reserved */
/* Slot 34 is reserved */
/* Slot 35 is reserved */
/* Slot 36 is reserved */
/* Slot 37 is reserved */
#define TkpCmapStressed_ \
	(tkIntPlatStubsPtr->tkpCmapStressed_) /* 38 */
#define TkpSync_ \
	(tkIntPlatStubsPtr->tkpSync_) /* 39 */
#define TkUnixContainerId_ \
	(tkIntPlatStubsPtr->tkUnixContainerId_) /* 40 */
#define TkUnixDoOneXEvent_ \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent_) /* 41 */
#define TkUnixSetMenubar_ \
	(tkIntPlatStubsPtr->tkUnixSetMenubar_) /* 42 */
#define TkWmCleanup_ \
	(tkIntPlatStubsPtr->tkWmCleanup_) /* 43 */
#define TkSendCleanup_ \
	(tkIntPlatStubsPtr->tkSendCleanup_) /* 44 */
#define TkpTestsendCmd_ \
	(tkIntPlatStubsPtr->tkpTestsendCmd_) /* 45 */
#endif /* X11 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TkpCmapStressed_
#undef TkpSync_
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_
#undef TkGenerateActivateEvents_
#undef TkMacOSXSetUpClippingRgn

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkWinGetPlatformId
#define TkWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */

#endif /* _TKINTPLATDECLS */







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






|
|
<
<
<
<
|
<
<
<




<
<
<

715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745




746



747
748
749
750



751
/* Slot 31 is reserved */
/* Slot 32 is reserved */
/* Slot 33 is reserved */
/* Slot 34 is reserved */
/* Slot 35 is reserved */
/* Slot 36 is reserved */
/* Slot 37 is reserved */
#define TkpCmapStressed \
	(tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */
#define TkpSync \
	(tkIntPlatStubsPtr->tkpSync) /* 39 */
#define TkUnixContainerId \
	(tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */
#define TkUnixDoOneXEvent \
	(tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 41 */
#define TkUnixSetMenubar \
	(tkIntPlatStubsPtr->tkUnixSetMenubar) /* 42 */
#define TkWmCleanup \
	(tkIntPlatStubsPtr->tkWmCleanup) /* 43 */
#define TkSendCleanup \
	(tkIntPlatStubsPtr->tkSendCleanup) /* 44 */
#define TkpTestsendCmd \
	(tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */
#endif /* X11 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#ifndef TK_NO_DEPRECATED
#   define TkMacOSXDrawable Tk_MacOSXGetNSWindowForDrawable




#endif




#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT




#endif /* _TKINTPLATDECLS */

Added generic/tkIntSet.c.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
/*
 * tkIntSet.c --
 *
 *	This module implements an integer set.
 *
 *	NOTE: the current implementation is for TkTextTagSet, so in general these
 *	functions are not modifying the arguments, except if this is expected.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkIntSet.h"
#include "tkBitField.h"

#include <assert.h>

#ifndef MIN
# define MIN(a,b) (((int) a) < ((int) b) ? a : b)
#endif
#ifndef MAX
# define MAX(a,b) (((int) a) < ((int) b) ? b : a)
#endif

#ifdef TK_CHECK_ALLOCS
# define DEBUG_ALLOC(expr) expr
#else
# define DEBUG_ALLOC(expr)
#endif


#define TestIfEqual TkIntSetIsEqual__

#define SET_SIZE(size) (offsetof(TkIntSet, buf) + (size)*sizeof(TkIntSetType))


DEBUG_ALLOC(unsigned tkIntSetCountNew = 0);
DEBUG_ALLOC(unsigned tkIntSetCountDestroy = 0);


static int IsPowerOf2(unsigned n) { return !(n & (n - 1)); }


static unsigned
NextPowerOf2(
    unsigned n)
{
    --n;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;

#if !(UINT_MAX <= 4294967295u)
    /* unsigned is 64 bit wide, this is unusual, but possible */
    n |= n >> 32;
#endif

    return ++n;
}


int
TkIntSetIsEqual__(
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2)
{
    if (end1 - set1 != end2 - set2) {
	return 0;
    }
    for ( ; set1 < end1; ++set1, ++set2) {
	if (*set1 != *set2) {
	    return 0;
	}
    }
    return 1;
}


unsigned
TkIntSetFindFirstInIntersection(
    const TkIntSet *set,
    const TkBitField *bf)
{
    unsigned size, i;

    assert(set);
    assert(bf);

    if (!TkBitNone(bf)) {
	size = TkIntSetSize(set);

	for (i = 0; i < size; ++i) {
	    TkIntSetType value = TkIntSetAccess(set, i);

	    if (TkBitTest(bf, value)) {
		return value;
	    }
	}
    }

    return TK_SET_NPOS;
}


TkIntSetType *
TkIntSetLowerBound(
    TkIntSetType *first,
    TkIntSetType *last,
    TkIntSetType value)
{
    while (first != last) {
	TkIntSetType *mid = first + (last - first)/2;

	if (*mid < value) {
	    first = mid + 1;
	} else {
	    last = mid;
	}
    }

    return first;
}


TkIntSet *
TkIntSetNew()
{
    TkIntSet *set = (TkIntSet *)ckalloc(SET_SIZE(0));
    set->end = set->buf;
    set->refCount = 0;
    set->isSetFlag = 1;
    DEBUG_ALLOC(tkIntSetCountNew++);
    return set;
}


TkIntSet *
TkIntSetFromBits(
    const TkBitField *bf)
{
    unsigned size;
    TkIntSet *set;
    unsigned index = 0, i;

    size = TkBitCount(bf);
    set = (TkIntSet *)ckalloc(SET_SIZE(NextPowerOf2(size)));
    set->end = set->buf + size;
    set->refCount = 1;
    set->isSetFlag = 1;
    DEBUG_ALLOC(tkIntSetCountNew++);

    for (i = TkBitFindFirst(bf); i != TK_BIT_NPOS; i = TkBitFindNext(bf, i)) {
	set->buf[index++] = i;
    }

    return set;
}


void
TkIntSetDestroy(
    TkIntSet **setPtr)
{
    assert(setPtr);

    if (*setPtr) {
	ckfree(*setPtr);
	*setPtr = NULL;
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }
}


TkIntSet *
TkIntSetCopy(
    const TkIntSet *set)
{
    TkIntSet *newSet;
    unsigned size;

    assert(set);

    size = TkIntSetSize(set);
    newSet = (TkIntSet *)ckalloc(SET_SIZE(NextPowerOf2(size)));
    newSet->end = newSet->buf + size;
    newSet->refCount = 1;
    newSet->isSetFlag = 1;
    memcpy(newSet->buf, set->buf, size*sizeof(TkIntSetType));
    DEBUG_ALLOC(tkIntSetCountNew++);
    return newSet;
}


static TkIntSetType *
Join(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *add, const TkIntSetType *addEnd)
{
    unsigned size;

    while (src < srcEnd && add < addEnd) {
	if (*src < *add) {
	    *dst++ = *src++;
	} else {
	    if (*src == *add) {
		++src;
	    }
	    *dst++ = *add++;
	}
    }

    if ((size = srcEnd - src) > 0) {
	memcpy(dst, src, size*sizeof(TkIntSetType));
	dst += size;
    } else if ((size = addEnd - add) > 0) {
	memcpy(dst, add, size*sizeof(TkIntSetType));
	dst += size;
    }

    return dst;
}


TkIntSet *
TkIntSetJoin(
    TkIntSet *dst,
    const TkIntSet *src)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkIntSetSize(src));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = Join(set->buf, dst->buf, dst->end, src->buf, src->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
JoinBits(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkBitField *bf)
{
    unsigned size, i;

    i = TkBitFindFirst(bf);

    while (src < srcEnd && i != TK_BIT_NPOS) {
	if (*src < i) {
	    *dst++ = *src++;
	} else {
	    if (*src == i) {
		++src;
	    }
	    *dst++ = i;
	    i = TkBitFindNext(bf, i);
	}
    }

    if ((size = srcEnd - src) > 0) {
	memcpy(dst, src, size*sizeof(TkIntSetType));
	dst += size;
    } else {
	for ( ; i != TK_BIT_NPOS; i = TkBitFindNext(bf, i)) {
	    *dst++ = i;
	}
    }

    return dst;
}


TkIntSet *
TkIntSetJoinBits(
    TkIntSet *dst,
    const TkBitField *src)
{
    TkIntSet *set;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    if (dst->buf == dst->end) {
	set = TkIntSetNew();
    } else {
	unsigned capacity1, capacity2, size;

	capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkBitSize(src));
	set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
	set->end = JoinBits(set->buf, dst->buf, dst->end, src);
	size = set->end - set->buf;
	capacity2 = NextPowerOf2(size);
	assert(capacity2 <= capacity1);
	DEBUG_ALLOC(tkIntSetCountNew++);

	if (capacity2 < capacity1) {
	    set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	    set->end = set->buf + size;
	}
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
Join2(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *set1, const TkIntSetType *set1End,
    const TkIntSetType *set2, const TkIntSetType *set2End)
{
    unsigned size;

    while (src < srcEnd && set1 < set1End && set2 < set2End) {
	if (*set1 < *set2) {
	    if (*src < *set1) {
		*dst++ = *src++;
	    } else {
		if (*src == *set1) {
		    src++;
		}
		*dst++ = *set1++;
	    }
	} else {
	    if (*src < *set2) {
		*dst++ = *src++;
	    } else {
		if (*src == *set2) {
		    src++;
		}
		if (*set1 == *set2)
		    set1++;
		*dst++ = *set2++;
	    }
	}
    }

    if (src == srcEnd) {
	dst = Join(dst, set1, set1End, set2, set2End);
    } else if (set1 < set1End) {
	dst = Join(dst, src, srcEnd, set1, set1End);
    } else if (set2 < set2End) {
	dst = Join(dst, src, srcEnd, set2, set2End);
    } else if ((size = srcEnd - src) > 0) {
	memcpy(dst, src, size*sizeof(TkIntSetType));
	dst += size;
    }

    return dst;
}


TkIntSet *
TkIntSetJoin2(
    TkIntSet *dst,
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(dst);
    assert(set1);
    assert(set2);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkIntSetSize(set1) + TkIntSetSize(set2));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = Join2(set->buf, dst->buf, dst->end, set1->buf, set1->end, set2->buf, set2->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
Intersect(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *isc, const TkIntSetType *iscEnd)
{
    while (src < srcEnd && isc < iscEnd) {
	if (*src < *isc) {
	    ++src;
	} else {
	    if (*src == *isc) {
		*dst++ = *src++;
	    }
	    ++isc;
	}
    }

    return dst;
}


TkIntSet *
TkIntSetIntersect(
    TkIntSet *dst,
    const TkIntSet *src)
{
    TkIntSet *set;
    unsigned size;
    unsigned capacity1, capacity2;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    size = MIN(TkIntSetSize(src), TkIntSetSize(dst));
    capacity1 = NextPowerOf2(size);
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = Intersect(set->buf, dst->buf, dst->end, src->buf, src->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
IntersectBits(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkBitField *isc)
{
    unsigned size = TkBitSize(isc);

    for ( ; src < srcEnd; ++src) {
	if (*src >= size) {
	    break;
	}
	if (TkBitTest(isc, *src)) {
	    *dst++ = *src;
	}
    }

    return dst;
}


TkIntSet *
TkIntSetIntersectBits(
    TkIntSet *dst,
    const TkBitField *src)
{
    TkIntSet *set;
    unsigned size;
    unsigned capacity1, capacity2;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    size = TkBitCount(src);

    size = MIN(TkIntSetSize(dst), TkBitCount(src));
    capacity1 = NextPowerOf2(size);
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = IntersectBits(set->buf, dst->buf, dst->end, src);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
Remove(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *sub, const TkIntSetType *subEnd)
{
    while (src < srcEnd && sub < subEnd) {
	if (*src < *sub) {
	    *dst++ = *src++;
	} else {
	    if (*src == *sub) {
		++src;
	    }
	    ++sub;
	}
    }

    if (src < srcEnd) {
	unsigned size = srcEnd - src;
	memcpy(dst, src, size*sizeof(TkIntSetType));
	dst += size;
    }

    return dst;
}


TkIntSet *
TkIntSetRemove(
    TkIntSet *dst,
    const TkIntSet *src)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = Remove(set->buf, dst->buf, dst->end, src->buf, src->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
RemoveBits(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkBitField *sub)
{
    unsigned size = TkBitSize(sub);

    for ( ; src < srcEnd; ++src) {
	if (*src >= size) {
	    break;
	}
	if (!TkBitTest(sub, *src)) {
	    *dst++ = *src;
	}
    }

    if ((size = srcEnd - src) > 0) {
	memcpy(dst, src, size*sizeof(TkIntSetType));
	dst += size;
    }

    return dst;
}


TkIntSet *
TkIntSetRemoveBits(
    TkIntSet *dst,
    const TkBitField *src)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = RemoveBits(set->buf, dst->buf, dst->end, src);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
ComplementTo(
    TkIntSetType *dst,
    const TkIntSetType *sub, const TkIntSetType *subEnd,
    const TkIntSetType *src, const TkIntSetType *srcEnd)
{
    return Remove(dst, src, srcEnd, sub, subEnd);
}


TkIntSet *
TkIntSetComplementTo(
    TkIntSet *dst,
    const TkIntSet *src)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(src));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = ComplementTo(set->buf, dst->buf, dst->end, src->buf, src->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
ComplementToBits(
    TkIntSetType *dst,
    const TkIntSetType *sub, const TkIntSetType *subEnd,
    const TkBitField *src)
{
    unsigned i = TkBitFindFirst(src);

    /* dst := src - sub */

    while (sub < subEnd && i != TK_BIT_NPOS) {
	if (*sub < i) {
	    ++sub;
	} else {
	    if (i < *sub) {
		*dst++ = i;
	    } else {
		++sub;
	    }
	    i = TkBitFindNext(src, i);
	}
    }
    for ( ; i != TK_BIT_NPOS; i = TkBitFindNext(src, i)) {
	*dst++ = i;
    }

    return dst;
}


TkIntSet *
TkIntSetComplementToBits(
    TkIntSet *dst,
    const TkBitField *src)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(src);
    assert(dst);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkBitSize(src));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = ComplementToBits(set->buf, dst->buf, dst->end, src);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
JoinComplementTo(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *set1, const TkIntSetType *set1End,
    const TkIntSetType *set2, const TkIntSetType *set2End)
{
    /* dst = src + (set2 - set1) */

    while (src < srcEnd && set1 < set1End && set2 < set2End) {
	if (*set2 < *set1) {
	    if (*src < *set2) {
		*dst++ = *src++;
	    } else if (*src == *set2) {
		*dst++ = *src++;
		set2++;
	    } else {
		if (*src == *set2) {
		    ++src;
		}
		*dst++ = *set2++;
	    }
	} else if (*src < *set1) {
	    *dst++ = *src++;
	} else {
	    if (*set2 == *set1) {
		set2++;
	    }
	    if (*src == *set1) {
		*dst++ = *src++;
	    }
	    set1++;
	}
    }

    if (src == srcEnd) {
	dst = ComplementTo(dst, set1, set1End, set2, set2End);
    } else if (set2 < set2End) {
	dst = Join(dst, src, srcEnd, set2, set2End);
    } else {
	unsigned size = srcEnd - src;
	memcpy(dst, src, size*sizeof(TkIntSetType));
	dst += size;
    }

    return dst;
}


TkIntSet *
TkIntSetJoinComplementTo(
    TkIntSet *dst,
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(dst);
    assert(set1);
    assert(set2);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkIntSetSize(set1));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = JoinComplementTo(
	    set->buf, dst->buf, dst->end, set1->buf, set1->end, set2->buf, set2->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


static TkIntSetType *
JoinNonIntersection(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *set1, const TkIntSetType *set1End,
    const TkIntSetType *set2, const TkIntSetType *set2End)
{
    unsigned size;

    /* dst += src + (set1 - set2) + (set2 - set1) */

    while (src != srcEnd && set1 != set1End && set2 != set2End) {
	if (*set1 < *set2) {
	    /* dst += src + set1 */
	    if (*set1 < *src) {
		*dst++ = *set1++;
	    } else {
		if (*src == *set1) {
		    ++set1;
		}
		*dst++ = *src++;
	    }
	} else if (*set2 < *set1) {
	    /* dst += src + set2 */
	    if (*set2 < *src) {
		*dst++ = *set2++;
	    } else {
		if (*src == *set2) {
		    ++set2;
		}
		*dst++ = *src++;
	    }
	} else {
	    ++set1;
	    ++set2;
	}
    }

    if (src == srcEnd) {
	/* dst += (set1 - set2) + (set2 - set1) */

	while (set1 != set1End && set2 != set2End) {
	    if (*set1 < *set2) {
		*dst++ = *set1++;
	    } else if (*set2 < *set1) {
		*dst++ = *set2++;
	    } else {
		++set1;
		++set2;
	    }
	}
	if (set1 == set1End) {
	    set1 = set2;
	    set1End = set2End;
	}

	/* dst += set1 */

	if ((size = set1End - set1)) {
	    memcpy(dst, set1, size*sizeof(TkIntSetType));
	    dst += size;
	}
    } else {
	if (set1 == set1End) {
	    set1 = set2;
	    set1End = set2End;
	}

	/* dst += src + set1 */

	dst = Join(dst, src, srcEnd, set1, set1End);
    }

    return dst;
}


TkIntSet *
TkIntSetJoinNonIntersection(
    TkIntSet *dst,
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(dst);
    assert(set1);
    assert(set2);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkIntSetSize(set1) + TkIntSetSize(set2));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = JoinNonIntersection(
	    set->buf, dst->buf, dst->end, set1->buf, set1->end, set2->buf, set2->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


TkIntSet *
TkIntSetJoin2ComplementToIntersection(
    TkIntSet *dst,
    const TkIntSet *add,
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    TkIntSet *set;
    const TkIntSetType *set1P;
    const TkIntSetType *set2P;
    const TkIntSetType *set1End;
    const TkIntSetType *set2End;
    TkIntSetType *res1, *res2, *res3, *res1End, *res2End, *res3End;
    TkIntSetType buffer[512];
    unsigned capacity1, capacity2;
    unsigned size, size1, size2;

    assert(dst);
    assert(add);
    assert(set1);
    assert(set2);
    assert(TkIntSetRefCount(dst) > 0);

    set1P = set1->buf;
    set2P = set2->buf;
    set1End = set1->end;
    set2End = set2->end;

    size1 = TkIntSetSize(set1) + TkIntSetSize(set2);
    size2 = MIN(TkIntSetSize(set1), TkIntSetSize(set2));
    size = size1 + 2*size2;
    res1 = size <= sizeof(buffer)/sizeof(buffer[0]) ? buffer : (TkIntSetType *)ckalloc(size*sizeof(TkIntSetType));
    res2 = res1 + size1;
    res3 = res2 + size2;

    res1End = Join(res1, set1P, set1End, set2P, set2End);
    res2End = Intersect(res2, set1P, set1End, set2P, set2End);
    res3End = ComplementTo(res3, res1, res1End, res2, res2End);

    capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkIntSetSize(add) + (res3End - res3));
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    set->end = Join2(set->buf, dst->buf, dst->end, add->buf, add->end, res3, res3End);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    if (res1 != buffer) {
	ckfree(res1);
    }
    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


TkIntSet *
TkIntSetJoinOfDifferences(
    TkIntSet *dst,
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    TkIntSet *set;
    TkIntSetType *buf1, *buf2, *end1, *end2;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(dst);
    assert(set1);
    assert(set2);
    assert(TkIntSetRefCount(dst) > 0);

    capacity2 = TkIntSetSize(dst) + TkIntSetSize(set1);
    capacity1 = NextPowerOf2(2*capacity2);
    set = (TkIntSet *)ckalloc(SET_SIZE(capacity1));
    buf1 = set->buf + capacity2;
    buf2 = buf1 + TkIntSetSize(dst);
    end1 = Remove(buf1, dst->buf, dst->end, set1->buf, set1->end);
    end2 = Remove(buf2, set1->buf, set1->end, set2->buf, set2->end);
    set->end = Join(set->buf, buf1, end1, buf2, end2);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = (TkIntSet *)ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


int
TkIntSetDisjunctive__(
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2)
{
    while (set1 != end1 && set2 != end2) {
	if (*set1 == *set2) {
	    return 0;
	}
	if (*set1 < *set2) {
	    ++set1;
	} else {
	    ++set2;
	}
    }

    return 1;
}


int
TkIntSetContains__(
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2)
{
    /*
     * a in set1, not in set2 -> skip
     * a in set1, and in set2 -> skip
     * a in set2, not in set1 -> 0
     */

    if (end1 - set1 < end2 - set2) {
	return 0;
    }

    while (set1 != end1 && set2 != end2) {
	if (*set2 < *set1) {
	    return 0;
	} else if (*set1 == *set2) {
	    ++set2;
	}
	++set1;
    }

    return set2 == end2;
}


int
TkIntSetIsContainedBits(
    const TkIntSet *set,
    const TkBitField *bf)
{
    size_t setSize, bitSize, i;

    assert(bf);
    assert(set);

    setSize = TkIntSetSize(set);
    bitSize = TkBitSize(bf);

    for (i = 0; i < setSize; ++i) {
	TkIntSetType value = set->buf[i];
	if (value >= bitSize || !TkBitTest(bf, value)) {
	    return 0;
	}
    }

    return 1;
}


int
TkIntSetIntersectionIsEqual(
    const TkIntSet *set1,
    const TkIntSet *set2,
    const TkBitField *del)
{
    const TkIntSetType *s1;
    const TkIntSetType *e1;
    const TkIntSetType *s2;
    const TkIntSetType *e2;

    assert(set1);
    assert(set2);
    assert(del);
    assert(TkIntSetMax(set1) < TkBitSize(del));
    assert(TkIntSetMax(set2) < TkBitSize(del));

    if (set1 == set2) {
	return 1;
    }

    s1 = set1->buf; e1 = set1->end;
    s2 = set2->buf; e2 = set2->end;

    while (s1 != e1 && s2 != e2) {
	if (*s1 == *s2) {
	    ++s1;
	    ++s2;
	} else if (*s1 < *s2) {
	    if (!TkBitTest(del, *s1)) {
		return 0;
	    }
	    ++s1;
	} else { /* if (*s2 < *s1) */
	    if (!TkBitTest(del, *s2)) {
		return 0;
	    }
	    ++s2;
	}
    }
    for ( ; s1 != e1; ++s1) {
	if (!TkBitTest(del, *s1)) {
	    return 0;
	}
    }
    for ( ; s2 != e2; ++s2) {
	if (!TkBitTest(del, *s2)) {
	    return 0;
	}
    }

    return 1;
}


int
TkIntSetIntersectionIsEqualBits(
    const TkIntSet *set,
    const TkBitField *bf,
    const TkBitField *del)
{
    TkBitField *cp = TkBitCopy(del, -1);
    int test;

    assert(set);
    assert(bf);
    assert(del);
    assert(TkIntSetMax(set) < TkBitSize(del));
    assert(TkBitSize(bf) <= TkBitSize(del));

    TkBitIntersect(cp, bf);
    test = TkIntSetIsEqualBits(set, cp);
    TkBitDestroy(&cp);
    return test;
}


static TkIntSet *
Add(
    TkIntSet *set,
    TkIntSetType *pos,
    unsigned n)
{
    unsigned size = set->end - set->buf;

    if (IsPowerOf2(size)) {
	TkIntSet *newSet = (TkIntSet *)ckalloc(SET_SIZE(MAX(2*size, 1)));
	unsigned offs = pos - set->buf;

	assert(offs <= size);
	memcpy(newSet->buf, set->buf, offs*sizeof(TkIntSetType));
	memcpy(newSet->buf + offs + 1, pos, (size - offs)*sizeof(TkIntSetType));
	newSet->end = newSet->buf + size + 1;
	newSet->refCount = 1;
	newSet->isSetFlag = 1;
	DEBUG_ALLOC(tkIntSetCountNew++);

	if (--set->refCount == 0) {
	    ckfree(set);
	    DEBUG_ALLOC(tkIntSetCountDestroy++);
	}

	set = newSet;
	pos = set->buf + offs;
    } else {
	memmove(pos + 1, pos, (set->end - pos)*sizeof(TkIntSetType));
	set->end += 1;
    }

    *pos = n;
    return set;
}


TkIntSet *
TkIntSetAdd(
    TkIntSet *set,
    unsigned n)
{
    TkIntSetType *pos;

    assert(set);
    assert(TkIntSetRefCount(set) > 0);

    pos = TkIntSetLowerBound(set->buf, set->end, n);

    if (pos < set->end && *pos == n) {
	return set;
    }

    return Add(set, pos, n);
}


static TkIntSet *
Erase(
    TkIntSet *set,
    TkIntSetType *pos,
    unsigned n)
{
    unsigned size = set->end - set->buf - 1;
    (void)n;

    if (IsPowerOf2(size)) {
	TkIntSet *newSet = (TkIntSet *)ckalloc(SET_SIZE(size));
	unsigned offs = pos - set->buf;

	memcpy(newSet->buf, set->buf, offs*sizeof(TkIntSetType));
	memcpy(newSet->buf + offs, pos + 1, (size - offs)*sizeof(TkIntSetType));
	newSet->end = newSet->buf + size;
	newSet->refCount = 1;
	newSet->isSetFlag = 1;
	DEBUG_ALLOC(tkIntSetCountNew++);

	if (--set->refCount == 0) {
	    ckfree(set);
	    DEBUG_ALLOC(tkIntSetCountDestroy++);
	}

	set = newSet;
    } else {
	memmove(pos, pos + 1, (set->end - pos - 1)*sizeof(TkIntSetType));
	set->end -= 1;
    }

    return set;
}


TkIntSet *
TkIntSetErase(
    TkIntSet *set,
    unsigned n)
{
    TkIntSetType *pos;

    assert(set);
    assert(TkIntSetRefCount(set) > 0);

    pos = TkIntSetLowerBound(set->buf, set->end, n);

    if (pos == set->end || *pos != n) {
	return set;
    }

    return Erase(set, pos, n);
}


TkIntSet *
TkIntSetTestAndSet(
    TkIntSet *set,
    unsigned n)
{
    TkIntSetType *pos;

    assert(set);
    assert(TkIntSetRefCount(set) > 0);

    pos = TkIntSetLowerBound(set->buf, set->end, n);

    if (pos < set->end && *pos == n) {
	return NULL;
    }

    return Add(set, pos, n);
}


TkIntSet *
TkIntSetTestAndUnset(
    TkIntSet *set,
    unsigned n)
{
    TkIntSetType *pos;

    assert(set);
    assert(TkIntSetRefCount(set) > 0);

    pos = TkIntSetLowerBound(set->buf, set->end, n);

    if (pos == set->end || *pos != n) {
	return NULL;
    }

    return Erase(set, pos, n);
}


TkIntSet *
TkIntSetClear(
    TkIntSet *set)
{
    TkIntSet *newSet;

    assert(set);
    assert(TkIntSetRefCount(set) > 0);

    if (set->buf == set->end) {
	return set;
    }

    newSet = (TkIntSet *)ckalloc(SET_SIZE(0));
    newSet->end = newSet->buf;
    newSet->refCount = 1;
    newSet->isSetFlag = 1;
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (--set->refCount == 0) {
	ckfree(set);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    return newSet;
}


int
TkIntSetIsEqualBits(
    const TkIntSet *set,
    const TkBitField *bf)
{
    unsigned sizeSet, sizeBf, i;

    assert(set);
    assert(bf);

    sizeSet = TkIntSetSize(set);

    if (sizeSet != TkBitCount(bf)) {
	return 0;
    }

    sizeBf = TkBitSize(bf);

    for (i = 0; i < sizeSet; ++i) {
	TkIntSetType value = set->buf[i];

	if (value >= sizeBf || !TkBitTest(bf, value)) {
	    return 0;
	}
    }

    return 1;
}


int
TkIntSetContainsBits(
    const TkIntSet *set,
    const TkBitField *bf)
{
    unsigned sizeSet, sizeBf, i;
    unsigned count = 0;

    assert(set);
    assert(bf);

    sizeSet = TkIntSetSize(set);
    sizeBf = TkBitSize(bf);

    for (i = 0; i < sizeSet; ++i) {
	TkIntSetType value = set->buf[i];

	if (value >= sizeBf) {
	    break;
	}

	if (TkBitTest(bf, value)) {
	    count += 1;
	}
    }

    return count == TkBitCount(bf);
}


int
TkIntSetDisjunctiveBits(
    const TkIntSet *set,
    const TkBitField *bf)
{
    unsigned sizeSet, sizeBf, i;

    assert(set);
    assert(bf);

    sizeSet = TkIntSetSize(set);
    sizeBf = TkBitSize(bf);

    for (i = 0; i < sizeSet; ++i) {
	TkIntSetType value = set->buf[i];

	if (value >= sizeBf) {
	    return 1;
	}
	if (TkBitTest(bf, value)) {
	    return 0;
	}
    }

    return 1;
}


#ifndef NDEBUG

# include <stdio.h>

void
TkIntSetPrint(
    const TkIntSet *set)
{
    unsigned i, n;
    const char *comma = "";

    assert(set);

    n = TkIntSetSize(set);
    printf("%d:{ ", n);
    for (i = 0; i < n; ++i) {
	printf("%s%d", comma, set->buf[i]);
	comma = ", ";
    }
    printf(" }\n");
}

#endif /* NDEBUG */

#ifdef TK_UNUSED_INTSET_FUNCTIONS

/*
 * These functions are not needed anymore, but shouldn't be removed, because sometimes
 * any of these functions might be useful.
 */

static TkIntSetType *
InnerJoinDifference(
    TkIntSetType *dst,
    const TkIntSetType *src, const TkIntSetType *srcEnd,
    const TkIntSetType *add, const TkIntSetType *addEnd,
    const TkIntSetType *sub, const TkIntSetType *subEnd)
{
    /* dst = (src & add) + (add - sub) */

    while (src != srcEnd && add != addEnd) {
	if (*src < *add) {
	    ++src;
	} else {
	    if (*src == *add) {
		*dst++ = *add;
		++src;
	    } else {
		for ( ; sub != subEnd && *sub < *add; ++sub) {
		    /* empty loop body */
		}
		if (sub == subEnd) {
		    break;
		}
		if (*add != *sub) {
		    *dst++ = *add;
		}
	    }
	    ++add;
	}
    }

    if (sub == subEnd) {
	/* dst += add */
	unsigned size = addEnd - add;
	memcpy(dst, add, size*sizeof(TkIntSetType));
	dst += size;
    } else if (src == srcEnd) {
	/* dst += add - sub */
	dst = Remove(dst, add, addEnd, sub, subEnd);
    } else { /* if (add == addEnd) */
	/* dst += nil */
    }

    return dst;
}


TkIntSet *
TkIntSetInnerJoinDifference(
    TkIntSet *dst,
    const TkIntSet *add,
    const TkIntSet *sub)
{
    TkIntSet *set;
    unsigned capacity1, capacity2;
    unsigned size;

    assert(dst);
    assert(add);
    assert(sub);
    assert(TkIntSetRefCount(dst) > 0);

    capacity1 = NextPowerOf2(TkIntSetSize(dst) + TkIntSetSize(add));
    set = ckalloc(SET_SIZE(capacity1));
    set->end = InnerJoinDifference(set->buf, dst->buf, dst->end, add->buf, add->end, sub->buf, sub->end);
    size = set->end - set->buf;
    capacity2 = NextPowerOf2(size);
    assert(capacity2 <= capacity1);
    DEBUG_ALLOC(tkIntSetCountNew++);

    if (capacity2 < capacity1) {
	set = ckrealloc(set, SET_SIZE(capacity2));
	set->end = set->buf + size;
    }

    if (--dst->refCount == 0) {
	ckfree(dst);
	DEBUG_ALLOC(tkIntSetCountDestroy++);
    }

    set->refCount = 1;
    set->isSetFlag = 1;
    return set;
}


int
TkIntSetInnerJoinDifferenceIsEmpty(
    const TkIntSet *set,
    const TkIntSet *add,
    const TkIntSet *sub)
{
    const TkIntSetType *setP, *setEnd;
    const TkIntSetType *addP, *addEnd;
    const TkIntSetType *subP, *subEnd;

    assert(set);
    assert(add);
    assert(sub);

    /* (set & add) + (add - sub) == nil */

    if (add->buf == add->end) {
	/* nil */
	return 1;
    }

    if (add == set) {
	/* add == nil */
	return TkIntSetIsEmpty(add);
    }

    setP = set->buf; setEnd = set->end;
    addP = add->buf; addEnd = add->end;

    /* (set & add) == nil */

    while (setP != setEnd && addP < addEnd) {
	if (*setP == *addP) {
	    return 0;
	} else if (*setP < *addP) {
	    ++setP;
	} else {
	    ++addP;
	}
    }

    /* (add - sub) == nil */

    addP = add->buf; addEnd = add->end;
    subP = sub->buf; subEnd = sub->end;

    while (addP != addEnd && subP != subEnd) {
	if (*addP < *subP) {
	    return 0;
	} else if (*addP == *subP) {
	    ++addP;
	}
	++subP;
    }

    return addP == addEnd;
}


static int
DifferenceIsEmpty(
    const TkIntSetType *set, const TkIntSetType *setEnd,
    const TkIntSetType *sub, const TkIntSetType *subEnd)
{
    while (set != setEnd && sub != subEnd) {
	if (*set < *sub) {
	    return 0;
	} else {
	    if (*set == *sub) {
		++set;
	    }
	    ++sub;
	}
    }

    return set == setEnd;
}


int
TkIntSetIsEqualToDifference(
    const TkIntSet *set1,
    const TkIntSet *set2,
    const TkIntSet *sub2)
{
    const TkIntSetType *set1P, *set1End;
    const TkIntSetType *set2P, *set2End;
    const TkIntSetType *sub2P, *sub2End;

    assert(set1);
    assert(set2);
    assert(sub2);

    if (set2->buf == set2->end) {
	return set1->buf == set1->end;
    }

    set1P = set1->buf; set1End = set1->end;
    set2P = set2->buf; set2End = set2->end;
    sub2P = sub2->buf; sub2End = sub2->end;

    if (set1P == set1End) {
	return DifferenceIsEmpty(set2P, set2End, sub2P, sub2End);
    }

    /* set1 == set2 - sub2 */

    while (set1P != set1End && set2P != set2End) {
	if (*set1P < *set2P) {
	    return 0;
	}
	for ( ; sub2P != sub2End && *sub2P < *set2P; ++sub2P) {
	    /* empty loop body */
	}
	if (sub2P == sub2End) {
	    break;
	}
	if (*set1P == *set2P) {
	    if (*set2P == *sub2P) {
		return 0;
	    }
	    ++set1P;
	} else {
	    if (*set2P != *sub2P) {
		return 0;
	    }
	}
	++set2P;
    }

    if (set2P == set2End) {
	/* set1 == nil */
	return set1P == set1End;
    }

    if (sub2P == sub2End) {
	/* set1 == set2 */
	return TestIfEqual(set1P, set1End, set2P, set2End);
    }

    assert(set1P == set1End);
    /* set2 - sub2 == nil */

    return DifferenceIsEmpty(set2P, set2End, sub2P, sub2End);
}


int
TkIntSetIsEqualToInnerJoin(
    const TkIntSet *set1,
    const TkIntSet *set2,
    const TkIntSet *add2)
{
    const TkIntSetType *set1P, *set1End;
    const TkIntSetType *set2P, *set2End;
    const TkIntSetType *add2P, *add2End;

    assert(set1);
    assert(set2);
    assert(add2);

    if (set1 == set2) {
	/* set1 == (set1 + (add2 & set1)) */
	return 1;
    }

    set1P = set1->buf; set1End = set1->end;
    set2P = set2->buf; set2End = set2->end;

    if (set2P == set2End) {
	/* set1 == nil */
	return set1P == set1End;
    }

    if (set2 == add2) {
	/* set1 == set2 */
	return TestIfEqual(set1P, set1End, set2P, set2End);
    }

    add2P = add2->buf; add2End = add2->end;

    /* set1 == (set2 + (add2 & set2)) */

    while (set1P != set1End && set2P != set2End && add2P != add2End) {
	if (*set2P < *set1P) {
	    return 0;
	} else if (*set1P == *set2P) {
	    ++set1P;
	    ++set2P;
	/* now: *set1P < *set2P */
	} else if (*add2P < *set2P) {
	    ++add2P;
	} else if (*set2P < *add2P) {
	    ++set2P;
	} else {
	    return 0;
	}
    }

    if (add2P == add2End) {
	/* set1 == set2 */
	return TestIfEqual(set1P, set1End, set2P, set2End);
    }

    if (set1P == set1End) {
	/* set2 == nil */
	return set2P == set2End;
    }

    /* set2P == set2End: set1 == nil */
    return set1P == set1End;
}


static int
EqualToJoin(
    const TkIntSetType *src, const TkIntSetType *send,
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2)
{
    /* src == set1 + set2 */

    assert(src != send);

    while (set1 != end1 && set2 != end2) {
	if (*src == *set1) {
	    if (*src == *set2) {
		++set2;
	    }
	    ++set1;
	} else if (*src == *set2) {
	    ++set2;
	} else {
	    return 0;
	}
	if (++src == send) {
	    return set1 == end1 && set2 == end2;
	}
    }

    if (set1 == end1) {
	set1 = set2;
	end1 = end2;
    }

    return TestIfEqual(src, send, set1, end1);
}


int
TkIntSetIsEqualToInnerJoinDifference(
    const TkIntSet *set1,
    const TkIntSet *set2,
    const TkIntSet *add2,
    const TkIntSet *sub2)
{
    TkIntSetType buf1[100];
    TkIntSetType buf2[100];
    TkIntSetType *inscBuf; /* set2 & add2 */
    TkIntSetType *diffBuf; /* add2 - sub2 */
    TkIntSetType *inscP, *inscEnd;
    TkIntSetType *diffP, *diffEnd;
    unsigned inscSize;
    unsigned diffSize;
    int isEqual;

    assert(set1);
    assert(set2);
    assert(add2);
    assert(sub2);

    /* set1 == (set2 & add2) + (add2 - sub2) */

    if (add2->buf == add2->end) {
	/* set1 == nil */
	return TkIntSetIsEmpty(set1);
    }

    if (sub2->buf == sub2->end) {
	/* set1 == (set2 & add2) + add2 */
	return TkIntSetIsEqualToInnerJoin(set1, add2, set2);
    }

    if (set1->buf == set1->end) {
	/* (set2 & add2) + (add2 - sub2) == nil */
	return TkIntSetDisjunctive(set2, add2)
		&& DifferenceIsEmpty(add2->buf, add2->end, sub2->buf, sub2->end);
    }

    diffSize = TkIntSetSize(add2);
    inscSize = MIN(TkIntSetSize(set2), diffSize);
    inscBuf = inscSize <= sizeof(buf1)/sizeof(buf1[0]) ? buf1 : ckalloc(inscSize*sizeof(buf1[0]));
    inscEnd = Intersect(inscP = inscBuf, set2->buf, set2->end, add2->buf, add2->end);

    if (inscP == inscEnd) {
	/* set1 == (add2 - sub2) */
	isEqual = TkIntSetIsEqualToDifference(set1, add2, sub2);
    } else {
	diffBuf = diffSize <= sizeof(buf2)/sizeof(buf2[0]) ? buf2 : ckalloc(diffSize*sizeof(buf2[0]));
	diffEnd = Remove(diffP = diffBuf, add2->buf, add2->end, sub2->buf, sub2->end);

	if (diffP == diffEnd) {
	    /* set1 == inscP */
	    isEqual = TestIfEqual(set1->buf, set1->end, inscP, inscEnd);
	} else {
	    /* set1 == inscP + diffP */
	    isEqual = EqualToJoin(set1->buf, set1->end, inscP, inscEnd, diffP, diffEnd);
	}

	if (diffBuf != buf2) { ckfree(diffBuf); }
    }

    if (inscBuf != buf1) { ckfree(inscBuf); }

    return isEqual;
}


static int
InnerJoinDifferenceIsEqual(
    const TkIntSetType *set, const TkIntSetType *setEnd,
    const TkIntSetType *add, const TkIntSetType *addEnd,
    const TkIntSetType *sub, const TkIntSetType *subEnd)
{
    /*
     * (add - sub) == (set & add) + (add - sub)
     *
     * This is equivalent to:
     * (add - sub) & add == (set + (add - sub)) & add
     *
     * This means we have to show:
     * For any x in add: x in (add - sub) <=> x in (set + (add - sub))
     *
     * So it's sufficient to show:
     * For any x in add: x in sub => x not in set
     * For any x in add: x in set => x not in sub
     *
     * But this is equivalent to:
     * (sub & add) & (set & add) == nil
     */

    if (add != addEnd) {
	while (set != setEnd && sub != subEnd) {
	    if (*set == *sub) {
		while (*add < *set) {
		    if (++add == addEnd) {
			return 1;
		    }
		}
		if (*add == *set) {
		    return 0;
		}
		++set;
		++sub;
	    } else if (*set < *sub) {
		++set;
	    } else {
		++sub;
	    }
	}
    }

    return 1;
}


int
TkIntSetInnerJoinDifferenceIsEqual(
    const TkIntSet *set1,
    const TkIntSet *set2,
    const TkIntSet *add,
    const TkIntSet *sub)
{
    const TkIntSetType *set1P, *set1End;
    const TkIntSetType *set2P, *set2End;
    const TkIntSetType *addP, *addEnd;
    const TkIntSetType *subP, *subEnd;

    if (add->buf == add->end) {
	return 1;
    }

    set1P = set1->buf; set1End = set1->end;
    set2P = set2->buf; set2End = set2->end;
    addP = add->buf; addEnd = add->end;
    subP = sub->buf; subEnd = sub->end;

    if (set1P == set1End) {
	return InnerJoinDifferenceIsEqual(set2P, set2End, addP, addEnd, subP, subEnd);
    }
    if (set2P == set2End) {
	return InnerJoinDifferenceIsEqual(set1P, set1End, addP, addEnd, subP, subEnd);
    }

    /*
     * (set1 & add) + (add - sub) == (set2 & add) + (add - sub)
     *
     * This is equivalent to:
     * (set1 + (add - sub)) & add == (set2 + (add - sub)) & add
     *
     * This means we have to show:
     * For any x in add: x in (set1 + (add - sub)) <=> x in (set2 + (add - sub))
     *
     * x in (add & sub): Proof: x in set1 <=> x in set2.
     * x in (add - sub): Nothing to proof.
     */

    while (addP != addEnd && subP != subEnd) {
	if (*addP < *subP) {
	    ++addP;
	} else {
	    if (*addP == *subP) {
		/* x in (add & sub): Proof: x in set1 <=> x in set2. */
		for ( ; set1P != set1End && *set1P < *addP; ++set1P) {
		    /* empty loop body */
		}
		if (set1P == set1End) {
		    /* (add - sub) == (set2 & add) + (add - sub) */
		    return InnerJoinDifferenceIsEqual(set2P, set2End, addP, addEnd, subP, subEnd);
		}
		for ( ; set2P != set2End && *set2P < *addP; ++set2P) {
		    /* empty loop body */
		}
		if (set2P == set2End) {
		    /* (add - sub) == (set1 & add) + (add - sub) */
		    return InnerJoinDifferenceIsEqual(set1P, set1End, addP, addEnd, subP, subEnd);
		}
		if (*addP == *set1P) {
		    if (*addP != *set2P) {
			return 0;
		    }
		    ++set1P;
		    ++set2P;
		} else if (*addP == *set2P) {
		    return 0;
		}
		++addP;
	    }
	    ++subP;
	}
    }

    return 1;
}

#endif /* TK_UNUSED_INTSET_FUNCTIONS */


/* Additionally we need stand-alone object code. */
extern unsigned TkIntSetByteSize(const TkIntSet *set);
extern const unsigned char *TkIntSetData(const TkIntSet *set);
extern int TkIntSetIsEmpty(const TkIntSet *set);
extern unsigned TkIntSetSize(const TkIntSet *set);
extern unsigned TkIntSetMax(const TkIntSet *set);
extern unsigned TkIntSetRefCount(const TkIntSet *set);
extern void TkIntSetIncrRefCount(TkIntSet *set);
extern unsigned TkIntSetDecrRefCount(TkIntSet *set);
extern TkIntSetType TkIntSetAccess(const TkIntSet *set, unsigned index);
extern int TkIntSetTest(const TkIntSet *set, unsigned n);
extern int TkIntSetNone(const TkIntSet *set);
extern int TkIntSetAny(const TkIntSet *set);
extern int TkIntSetIsEqual(const TkIntSet *set1, const TkIntSet *set2);
extern int TkIntSetContains(const TkIntSet *set1, const TkIntSet *set2);
extern int TkIntSetDisjunctive(const TkIntSet *set1, const TkIntSet *set2);
extern int TkIntSetIntersects(const TkIntSet *set1, const TkIntSet *set2);
extern unsigned TkIntSetFindFirst(const TkIntSet *set);
extern unsigned TkIntSetFindNext(const TkIntSet *set);
extern TkIntSet *TkIntSetAddOrErase(TkIntSet *set, unsigned n, int add);

/* vi:set ts=8 sw=4: */

Added generic/tkIntSet.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
/*
 * tkSet.h --
 *
 *	This module implements an integer set.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINTSET
#define _TKINTSET

#include "tkInt.h" /* required for inline support */

#if defined(__GNUC__) || defined(__clang__)
# define __warn_unused__ __attribute__((warn_unused_result))
#else
# define __warn_unused__
#endif

struct TkBitField;


typedef uint32_t TkIntSetType;

/*
 * The struct below will be shared with the struct TkBitField, so the first two
 * members must exactly match the first two members in struct TkBitField. In this
 * way we have a struct inheritance, based on the first two members. This
 * is portable due to C99 section 6.7.2.1 bullet point 13:
 *
 *	Within a structure object, the non-bit-field members and the units
 *	in which bit-fields reside have addresses that increase in the order
 *	in which they are declared. A pointer to a structure object, suitably
 *	converted, points to its initial member (or if that member is a
 *	bit-field, then to the unit in which it resides), and vice versa.
 *	There may be unnamed padding within a structure object, but not at
 *	beginning.
 *
 * This inheritance concept is also used in the portable GTK library.
 */

typedef struct TkIntSet {
    uint32_t refCount:31;
    uint32_t isSetFlag:1;
    TkIntSetType *end;
    TkIntSetType *curr; /* mutable */
    TkIntSetType buf[1];
} TkIntSet;


#define TK_SET_NPOS ((unsigned) -1)


TkIntSet *TkIntSetNew();
TkIntSet *TkIntSetFromBits(const struct TkBitField *bf);
void TkIntSetDestroy(TkIntSet **setPtr);

inline unsigned TkIntSetByteSize(const TkIntSet *set);
inline const unsigned char *TkIntSetData(const TkIntSet *set);

TkIntSet *TkIntSetCopy(const TkIntSet *set) __warn_unused__;

TkIntSet *TkIntSetJoin(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
TkIntSet *TkIntSetIntersect(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
TkIntSet *TkIntSetRemove(TkIntSet *dst, const TkIntSet *src) __warn_unused__;

TkIntSet *TkIntSetJoinBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
TkIntSet *TkIntSetIntersectBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
TkIntSet *TkIntSetRemoveBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;
/* dst := src - dst */
TkIntSet *TkIntSetComplementToBits(TkIntSet *dst, const struct TkBitField *src) __warn_unused__;

/* dst := dst + set1 + set2 */
TkIntSet *TkIntSetJoin2(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2) __warn_unused__;
/* dst := src - dst */
TkIntSet *TkIntSetComplementTo(TkIntSet *dst, const TkIntSet *src) __warn_unused__;
/* dst := dst + (set2 - set1) */
TkIntSet *TkIntSetJoinComplementTo(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2)
    __warn_unused__;
/* dst := dst + (set1 - set2) + (set2 - set1) */
TkIntSet *TkIntSetJoinNonIntersection(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2)
    __warn_unused__;
/* dst := dst + add + ((set1 + set2) - (set1 & set2)) */
TkIntSet *TkIntSetJoin2ComplementToIntersection(TkIntSet *dst,
    const TkIntSet *add, const TkIntSet *set1, const TkIntSet *set2) __warn_unused__;
/* dst := (dst - set1) + (set1 - set2) */
TkIntSet *TkIntSetJoinOfDifferences(TkIntSet *dst, const TkIntSet *set1, const TkIntSet *set2)
    __warn_unused__;

inline int TkIntSetIsEmpty(const TkIntSet *set);
inline unsigned TkIntSetSize(const TkIntSet *set);
inline unsigned TkIntSetMax(const TkIntSet *set);

inline unsigned TkIntSetRefCount(const TkIntSet *set);
inline void TkIntSetIncrRefCount(TkIntSet *set);
inline unsigned TkIntSetDecrRefCount(TkIntSet *set);

inline TkIntSetType TkIntSetAccess(const TkIntSet *set, unsigned index);

inline int TkIntSetTest(const TkIntSet *set, unsigned n);
inline int TkIntSetNone(const TkIntSet *set);
inline int TkIntSetAny(const TkIntSet *set);

inline int TkIntSetIsEqual(const TkIntSet *set1, const TkIntSet *set2);
inline int TkIntSetContains(const TkIntSet *set1, const TkIntSet *set2);
inline int TkIntSetDisjunctive(const TkIntSet *set1, const TkIntSet *set2);
inline int TkIntSetIntersects(const TkIntSet *set1, const TkIntSet *set2);

int TkIntSetIntersectionIsEqual(const TkIntSet *set1, const TkIntSet *set2,
    const struct TkBitField *del);
int TkIntSetIsEqualBits(const TkIntSet *set, const struct TkBitField *bf);
int TkIntSetContainsBits(const TkIntSet *set, const struct TkBitField *bf);
int TkIntSetDisjunctiveBits(const TkIntSet *set, const struct TkBitField *bf);
int TkIntSetIntersectionIsEqualBits(const TkIntSet *set, const struct TkBitField *bf,
    const struct TkBitField *del);
int TkIntSetIsContainedBits(const TkIntSet *set, const struct TkBitField *bf);

inline unsigned TkIntSetFindFirst(const TkIntSet *set);
inline unsigned TkIntSetFindNext(const TkIntSet *set);

unsigned TkIntSetFindFirstInIntersection(const TkIntSet *set, const struct TkBitField *bf);

TkIntSet *TkIntSetAdd(TkIntSet *set, unsigned n) __warn_unused__;
TkIntSet *TkIntSetErase(TkIntSet *set, unsigned n) __warn_unused__;
TkIntSet *TkIntSetTestAndSet(TkIntSet *set, unsigned n) __warn_unused__;
TkIntSet *TkIntSetTestAndUnset(TkIntSet *set, unsigned n) __warn_unused__;
inline TkIntSet *TkIntSetAddOrErase(TkIntSet *set, unsigned n, int add) __warn_unused__;
TkIntSet *TkIntSetClear(TkIntSet *set) __warn_unused__;

#ifndef NDEBUG
void TkIntSetPrint(const TkIntSet *set);
#endif


#ifdef TK_UNUSED_INTSET_FUNCTIONS

/*
 * These functions are not needed anymore, but shouldn't be removed, because sometimes
 * any of these functions might be useful.
 */

/* dst := (dst + (set - sub)) & set */
TkIntSet *TkIntSetInnerJoinDifference(TkIntSet *dst, const TkIntSet *set, const TkIntSet *sub)
    __warn_unused__;
/* ((set + (add - sub)) & add) == nil */
int TkIntSetInnerJoinDifferenceIsEmpty(const TkIntSet *set, const TkIntSet *add, const TkIntSet *sub);
/* set1 == set2 - sub2 */
int TkIntSetIsEqualToDifference(const TkIntSet *set1, const TkIntSet *set2, const TkIntSet *sub2);
/* set1 == set2 + (add2 & set2) */
int TkIntSetIsEqualToInnerJoin(const TkIntSet *set1, const TkIntSet *set2, const TkIntSet *add2);
/* set1 == ((set2 + (add2 - sub2)) & add2) */
int TkIntSetIsEqualToInnerJoinDifference(const TkIntSet *set1, const TkIntSet *set2,
    const TkIntSet *add2, const TkIntSet *sub2);
/* ((set1 + (add - sub)) & add) == ((set2 + (add - sub)) & add) */
int TkIntSetInnerJoinDifferenceIsEqual(const TkIntSet *set1, const TkIntSet *set2,
    const TkIntSet *add, const TkIntSet *sub);

#endif /* TK_UNUSED_INTSET_FUNCTIONS */


#undef __warn_unused__

#define _TK_NEED_IMPLEMENTATION
#include "tkIntSetPriv.h"
#endif /* _TKINTSET */
/* vi:set ts=8 sw=4: */

Added generic/tkIntSetPriv.h.











































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
 * tkIntSetPriv.h --
 *
 *	Private implementation for integer set.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINTSET
# error "do not include this private header file"
#endif


#ifndef _TKINTSETPRIV
#define _TKINTSETPRIV

MODULE_SCOPE int TkIntSetContains__(
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2);
MODULE_SCOPE int TkIntSetDisjunctive__(
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2);
MODULE_SCOPE int TkIntSetIsEqual__(
    const TkIntSetType *set1, const TkIntSetType *end1,
    const TkIntSetType *set2, const TkIntSetType *end2);

#endif /* _TKINTSETPRIV */


#ifdef _TK_NEED_IMPLEMENTATION

#include <assert.h>


extern TkIntSetType *
TkIntSetLowerBound(
    TkIntSetType *first,
    TkIntSetType *last,
    TkIntSetType value);


inline
const unsigned char *
TkIntSetData(
    const TkIntSet *set)
{
    assert(set);
    return (const unsigned char *) set->buf;
}


inline
unsigned
TkIntSetByteSize(
    const TkIntSet *set)
{
    assert(set);
    return (set->end - set->buf)*sizeof(TkIntSetType);
}


inline
int
TkIntSetIsEmpty(
    const TkIntSet *set)
{
    assert(set);
    return set->end == set->buf;
}


inline
int
TkIntSetIsEqual(
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    assert(set1);
    assert(set2);

    return set1 == set2 || TkIntSetIsEqual__(set1->buf, set1->end, set2->buf, set2->end);
}


inline
int
TkIntSetContains(
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    assert(set1);
    assert(set2);

    return set1 == set2 || TkIntSetContains__(set1->buf, set1->end, set2->buf, set2->end);
}


inline
int
TkIntSetDisjunctive(
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    assert(set1);
    assert(set2);

    if (set1 == set2) {
	return TkIntSetIsEmpty(set1);
    }
    return TkIntSetDisjunctive__(set1->buf, set1->end, set2->buf, set2->end);
}


inline
unsigned
TkIntSetSize(
    const TkIntSet *set)
{
    assert(set);
    return set->end - set->buf;
}


inline
unsigned
TkIntSetMax(
    const TkIntSet *set)
{
    assert(!TkIntSetIsEmpty(set));
    return set->end[-1];
}


inline
unsigned
TkIntSetRefCount(
    const TkIntSet *set)
{
    assert(set);
    return set->refCount;
}


inline
void
TkIntSetIncrRefCount(TkIntSet *set)
{
    assert(set);
    set->refCount += 1;
}


inline
unsigned
TkIntSetDecrRefCount(TkIntSet *set)
{
    unsigned refCount;

    assert(set);
    assert(set->refCount > 0);

    if ((refCount = --set->refCount) == 0) {
	TkIntSetDestroy(&set);
    }
    return refCount;
}


inline
TkIntSetType
TkIntSetAccess(
    const TkIntSet *set,
    unsigned index)
{
    assert(set);
    assert(index < TkIntSetSize(set));
    return set->buf[index];
}


inline
void
TkIntSetChange(
    TkIntSet *set,
    unsigned index,
    unsigned n)
{
    assert(set);
    assert(index < TkIntSetSize(set));
    set->buf[index] = n;
}


inline
int
TkIntSetTest(
    const TkIntSet *set,
    unsigned n)
{
    const TkIntSetType *pos;

    assert(set);

    pos = TkIntSetLowerBound(((TkIntSet *) set)->buf, ((TkIntSet *) set)->end, n);
    return pos < set->end && *pos == n;
}


inline
int
TkIntSetNone(
    const TkIntSet *set)
{
    assert(set);
    return set->buf == set->end;
}


inline
int
TkIntSetAny(
    const TkIntSet *set)
{
    assert(set);
    return set->buf < set->end;
}


inline
int
TkIntSetIntersects(
    const TkIntSet *set1,
    const TkIntSet *set2)
{
    return !TkIntSetDisjunctive(set1, set2);
}


inline
unsigned
TkIntSetFindNext(
    const TkIntSet *set)
{
    assert(set);
    return set->curr == set->end ? TK_SET_NPOS : *(((TkIntSet *) set)->curr++); /* 'curr' is mutable */
}


inline
unsigned
TkIntSetFindFirst(
    const TkIntSet *set)
{
    assert(set);
    ((TkIntSet *) set)->curr = ((TkIntSet *) set)->buf; /* 'curr' is mutable */
    return TkIntSetFindNext(set);
}


inline
TkIntSet *
TkIntSetAddOrErase(
    TkIntSet *set,
    unsigned n,
    int add)
{
    assert(set);
    return add ? TkIntSetAdd(set, n) : TkIntSetErase(set, n);
}


#undef _TK_NEED_IMPLEMENTATION
#endif /* _TK_NEED_IMPLEMENTATION */
/* vi:set ts=8 sw=4: */

Changes to generic/tkIntXlibDecls.h.

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.
 * All rights reserved.
 */

#ifndef _TKINTXLIBDECLS
#define _TKINTXLIBDECLS

/*








|







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 Scriptics Corporation.
 * All rights reserved.
 */

#ifndef _TKINTXLIBDECLS
#define _TKINTXLIBDECLS

/*
277
278
279
280
281
282
283
284



285
286
287
288
289
290
291
				char *c, int i, KeySym *k, Status *s);
/* 80 */
EXTERN int		TkPutImage(unsigned long *colors, int ncolors,
				Display *display, Drawable d, GC gc,
				XImage *image, int src_x, int src_y,
				int dest_x, int dest_y, unsigned int width,
				unsigned int height);
/* Slot 81 is reserved */



/* 82 */
EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);
/* 83 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
/* 84 */







|
>
>
>







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
				char *c, int i, KeySym *k, Status *s);
/* 80 */
EXTERN int		TkPutImage(unsigned long *colors, int ncolors,
				Display *display, Drawable d, GC gc,
				XImage *image, int src_x, int src_y,
				int dest_x, int dest_y, unsigned int width,
				unsigned int height);
/* 81 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 82 */
EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);
/* 83 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
/* 84 */
491
492
493
494
495
496
497








498
499


500
501
502
503
504
505
506
507







508
509
510
511
512
513
514
515
516
517
518


519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536


537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558


559
560
561
562
563


564
565
566
567
568
569
570


571
572
573
574
575



576
577
578
579
580
581
582
583
584



585
586
587
588
589
590
591







592
593
594
595



596
597
598
599
600
601
602
603
604
605
606
607


608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631




632
633
634
635
636
637









638
639
640
641
642
643




644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710




711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
EXTERN char *		XGetAtomName(Display *d, Atom a);
/* 5 */
EXTERN char *		XKeysymToString(KeySym k);
/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);
/* 7 */








EXTERN GContext		XGContextFromGC(GC g);
/* 8 */


EXTERN KeySym		XKeycodeToKeysym(Display *d, unsigned int k, int i);
/* 9 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);
/* 10 */
EXTERN Window		XRootWindow(Display *d, int i);
/* 11 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);
/* 12 */







EXTERN Status		XAllocColor(Display *d, Colormap c, XColor *xp);
/* 13 */
EXTERN int		XBell(Display *d, int i);
/* 14 */
EXTERN int		XChangeProperty(Display *d, Window w, Atom a1,
				Atom a2, int i1, int i2,
				_Xconst unsigned char *c, int i3);
/* 15 */
EXTERN int		XChangeWindowAttributes(Display *d, Window w,
				unsigned long ul, XSetWindowAttributes *x);
/* 16 */


EXTERN int		XConfigureWindow(Display *d, Window w,
				unsigned int i, XWindowChanges *x);
/* 17 */
EXTERN int		XCopyArea(Display *d, Drawable dr1, Drawable dr2,
				GC g, int i1, int i2, unsigned int ui1,
				unsigned int ui2, int i3, int i4);
/* 18 */
EXTERN int		XCopyPlane(Display *d, Drawable dr1, Drawable dr2,
				GC g, int i1, int i2, unsigned int ui1,
				unsigned int ui2, int i3, int i4,
				unsigned long ul);
/* 19 */
EXTERN Pixmap		XCreateBitmapFromData(Display *display, Drawable d,
				_Xconst char *data, unsigned int width,
				unsigned int height);
/* 20 */
EXTERN int		XDefineCursor(Display *d, Window w, Cursor c);
/* 21 */


EXTERN int		XDestroyWindow(Display *d, Window w);
/* 22 */
EXTERN int		XDrawArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);
/* 23 */
EXTERN int		XDrawLines(Display *d, Drawable dr, GC g, XPoint *x,
				int i1, int i2);
/* 24 */
EXTERN int		XDrawRectangle(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2);
/* 25 */
EXTERN int		XFillArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);
/* 26 */
EXTERN int		XFillPolygon(Display *d, Drawable dr, GC g,
				XPoint *x, int i1, int i2, int i3);
/* 27 */
EXTERN int		XFillRectangles(Display *d, Drawable dr, GC g,
				XRectangle *x, int i);
/* 28 */


EXTERN int		XFreeColormap(Display *d, Colormap c);
/* 29 */
EXTERN int		XFreeColors(Display *d, Colormap c,
				unsigned long *ulp, int i, unsigned long ul);
/* 30 */


EXTERN int		XFreeModifiermap(XModifierKeymap *x);
/* 31 */
EXTERN Status		XGetGeometry(Display *d, Drawable dr, Window *w,
				int *i1, int *i2, unsigned int *ui1,
				unsigned int *ui2, unsigned int *ui3,
				unsigned int *ui4);
/* 32 */


EXTERN int		XGetWindowProperty(Display *d, Window w, Atom a1,
				long l1, long l2, Bool b, Atom a2, Atom *ap,
				int *ip, unsigned long *ulp1,
				unsigned long *ulp2, unsigned char **cpp);
/* 33 */



EXTERN int		XGrabKeyboard(Display *d, Window w, Bool b, int i1,
				int i2, Time t);
/* 34 */
EXTERN int		XGrabPointer(Display *d, Window w1, Bool b,
				unsigned int ui, int i1, int i2, Window w2,
				Cursor c, Time t);
/* 35 */
EXTERN KeyCode		XKeysymToKeycode(Display *d, KeySym k);
/* 36 */



EXTERN int		XMapWindow(Display *d, Window w);
/* 37 */
EXTERN int		XMoveResizeWindow(Display *d, Window w, int i1,
				int i2, unsigned int ui1, unsigned int ui2);
/* 38 */
EXTERN int		XMoveWindow(Display *d, Window w, int i1, int i2);
/* 39 */







EXTERN Bool		XQueryPointer(Display *d, Window w1, Window *w2,
				Window *w3, int *i1, int *i2, int *i3,
				int *i4, unsigned int *ui);
/* 40 */



EXTERN int		XRaiseWindow(Display *d, Window w);
/* 41 */
EXTERN int		XRefreshKeyboardMapping(XMappingEvent *x);
/* 42 */
EXTERN int		XResizeWindow(Display *d, Window w, unsigned int ui1,
				unsigned int ui2);
/* 43 */
EXTERN int		XSelectInput(Display *d, Window w, long l);
/* 44 */
EXTERN Status		XSendEvent(Display *d, Window w, Bool b, long l,
				XEvent *x);
/* 45 */


EXTERN int		XSetIconName(Display *d, Window w, _Xconst char *c);
/* 46 */
EXTERN int		XSetInputFocus(Display *d, Window w, int i, Time t);
/* 47 */
EXTERN int		XSetSelectionOwner(Display *d, Atom a, Window w,
				Time t);
/* 48 */
EXTERN int		XSetWindowBackground(Display *d, Window w,
				unsigned long ul);
/* 49 */
EXTERN int		XSetWindowBackgroundPixmap(Display *d, Window w,
				Pixmap p);
/* 50 */
EXTERN int		XSetWindowBorder(Display *d, Window w,
				unsigned long ul);
/* 51 */
EXTERN int		XSetWindowBorderPixmap(Display *d, Window w,
				Pixmap p);
/* 52 */
EXTERN int		XSetWindowBorderWidth(Display *d, Window w,
				unsigned int ui);
/* 53 */
EXTERN int		XSetWindowColormap(Display *d, Window w, Colormap c);
/* 54 */




EXTERN int		XUngrabKeyboard(Display *d, Time t);
/* 55 */
EXTERN int		XUngrabPointer(Display *d, Time t);
/* 56 */
EXTERN int		XUnmapWindow(Display *d, Window w);
/* 57 */









EXTERN int		TkPutImage(unsigned long *colors, int ncolors,
				Display *display, Drawable d, GC gc,
				XImage *image, int src_x, int src_y,
				int dest_x, int dest_y, unsigned int width,
				unsigned int height);
/* 58 */




EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);
/* 59 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
/* 60 */
EXTERN int		XFreeGC(Display *display, GC gc);
/* 61 */
EXTERN Atom		XInternAtom(Display *display,
				_Xconst char *atom_name, Bool only_if_exists);
/* 62 */
EXTERN int		XSetBackground(Display *display, GC gc,
				unsigned long foreground);
/* 63 */
EXTERN int		XSetForeground(Display *display, GC gc,
				unsigned long foreground);
/* 64 */
EXTERN int		XSetClipMask(Display *display, GC gc, Pixmap pixmap);
/* 65 */
EXTERN int		XSetClipOrigin(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin);
/* 66 */
EXTERN int		XSetTSOrigin(Display *display, GC gc,
				int ts_x_origin, int ts_y_origin);
/* 67 */
EXTERN int		XChangeGC(Display *d, GC gc, unsigned long mask,
				XGCValues *values);
/* 68 */
EXTERN int		XSetFont(Display *display, GC gc, Font font);
/* 69 */
EXTERN int		XSetArcMode(Display *display, GC gc, int arc_mode);
/* 70 */
EXTERN int		XSetStipple(Display *display, GC gc, Pixmap stipple);
/* 71 */
EXTERN int		XSetFillRule(Display *display, GC gc, int fill_rule);
/* 72 */
EXTERN int		XSetFillStyle(Display *display, GC gc,
				int fill_style);
/* 73 */
EXTERN int		XSetFunction(Display *display, GC gc, int function);
/* 74 */
EXTERN int		XSetLineAttributes(Display *display, GC gc,
				unsigned int line_width, int line_style,
				int cap_style, int join_style);
/* 75 */
EXTERN int		_XInitImageFuncPtrs(XImage *image);
/* 76 */
EXTERN XIC		XCreateIC(XIM xim, ...);
/* 77 */
EXTERN XVisualInfo *	XGetVisualInfo(Display *display, long vinfo_mask,
				XVisualInfo *vinfo_template,
				int *nitems_return);
/* 78 */
EXTERN void		XSetWMClientMachine(Display *display, Window w,
				XTextProperty *text_prop);
/* 79 */
EXTERN Status		XStringListToTextProperty(char **list, int count,
				XTextProperty *text_prop_return);
/* 80 */
EXTERN int		XDrawSegments(Display *display, Drawable d, GC gc,
				XSegment *segments, int nsegments);
/* 81 */
EXTERN int		XForceScreenSaver(Display *display, int mode);
/* 82 */
EXTERN int		XDrawLine(Display *d, Drawable dr, GC g, int x1,
				int y1, int x2, int y2);
/* 83 */




EXTERN int		XFillRectangle(Display *display, Drawable d, GC gc,
				int x, int y, unsigned int width,
				unsigned int height);
/* 84 */
EXTERN int		XClearWindow(Display *d, Window w);
/* 85 */
EXTERN int		XDrawPoint(Display *display, Drawable d, GC gc,
				int x, int y);
/* 86 */
EXTERN int		XDrawPoints(Display *display, Drawable d, GC gc,
				XPoint *points, int npoints, int mode);
/* 87 */
EXTERN int		XWarpPointer(Display *display, Window src_w,
				Window dest_w, int src_x, int src_y,
				unsigned int src_width,
				unsigned int src_height, int dest_x,
				int dest_y);
/* 88 */
EXTERN int		XQueryColor(Display *display, Colormap colormap,
				XColor *def_in_out);
/* 89 */
EXTERN int		XQueryColors(Display *display, Colormap colormap,
				XColor *defs_in_out, int ncolors);
/* 90 */
EXTERN Status		XQueryTree(Display *d, Window w1, Window *w2,
				Window *w3, Window **w4, unsigned int *ui);
/* 91 */
EXTERN int		XSync(Display *display, Bool discard);
/* 92 */
EXTERN Bool		XTranslateCoordinates(Display *d, Window w1,
				Window w2, int i1, int i2, int *i3, int *i4,
				Window *w3);
/* 93 */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);
/* 94 */
EXTERN int		XFreeCursor(Display *d, Cursor c);
/* 95 */
EXTERN int		XGetInputFocus(Display *d, Window *w, int *i);
/* 96 */
EXTERN int		XmbLookupString(XIC xi, XKeyPressedEvent *xk,
				char *c, int i, KeySym *k, Status *s);
/* 97 */
EXTERN int		XNextEvent(Display *d, XEvent *x);
/* 98 */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);
/* 99 */
EXTERN int		XSetCommand(Display *d, Window w, char **c, int i);
/* 100 */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);
/* 101 */
EXTERN Status		XGetWindowAttributes(Display *d, Window w,
				XWindowAttributes *x);
/* 102 */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);
/* 103 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
/* 104 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
/* 105 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);
/* 106 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 107 */
EXTERN int		XFlush(Display *display);
/* 108 */
EXTERN int		XGrabServer(Display *display);
/* 109 */
EXTERN int		XUngrabServer(Display *display);
/* 110 */
EXTERN int		XFree(void *data);
/* 111 */
EXTERN int		XNoOp(Display *display);
/* 112 */
EXTERN XAfterFunction	XSynchronize(Display *display, Bool onoff);
/* 113 */
EXTERN Status		XLookupColor(Display *d, Colormap c1,
				_Xconst char *c2, XColor *x1, XColor *x2);
/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */







>
>
>
>
>
>
>
>

|
>
>

|

|

|

|
>
>
>
>
>
>
>

|

|



|


|
>
>


|



|




|



|

|
>
>

|



|


|


|



|


|


|
>
>

|


|
>
>

|




|
>
>




|
>
>
>


|



|

|
>
>
>

|


|

|
>
>
>
>
>
>
>



|
>
>
>

|

|


|

|


|
>
>

|

|


|


|


|


|


|


|

|
>
>
>
>

|

|

|
>
>
>
>
>
>
>
>
>





|
>
>
>
>


|


|

|


|


|


|

|


|


|


|

|

|

|

|


|

|



|

|

|



|


|


|
<
<
<
<
<


|
>
>
>
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|
<







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767





768
769
770
771
772
773
774
775
776
777






























































778
779
780
781
782
783
784
785
786
787
788
789
790
791

792
793
794
795
796
797
798
EXTERN char *		XGetAtomName(Display *d, Atom a);
/* 5 */
EXTERN char *		XKeysymToString(KeySym k);
/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);
/* 7 */
EXTERN Cursor		XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
				XColor *x1, XColor *x2, unsigned int ui1,
				unsigned int ui2);
/* 8 */
EXTERN Cursor		XCreateGlyphCursor(Display *d, Font f1, Font f2,
				unsigned int ui1, unsigned int ui2,
				XColor _Xconst *x1, XColor _Xconst *x2);
/* 9 */
EXTERN GContext		XGContextFromGC(GC g);
/* 10 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);
/* 11 */
EXTERN KeySym		XKeycodeToKeysym(Display *d, unsigned int k, int i);
/* 12 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);
/* 13 */
EXTERN Window		XRootWindow(Display *d, int i);
/* 14 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);
/* 15 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
/* 16 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
/* 17 */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);
/* 18 */
EXTERN Status		XAllocColor(Display *d, Colormap c, XColor *xp);
/* 19 */
EXTERN int		XBell(Display *d, int i);
/* 20 */
EXTERN int		XChangeProperty(Display *d, Window w, Atom a1,
				Atom a2, int i1, int i2,
				_Xconst unsigned char *c, int i3);
/* 21 */
EXTERN int		XChangeWindowAttributes(Display *d, Window w,
				unsigned long ul, XSetWindowAttributes *x);
/* 22 */
EXTERN int		XClearWindow(Display *d, Window w);
/* 23 */
EXTERN int		XConfigureWindow(Display *d, Window w,
				unsigned int i, XWindowChanges *x);
/* 24 */
EXTERN int		XCopyArea(Display *d, Drawable dr1, Drawable dr2,
				GC g, int i1, int i2, unsigned int ui1,
				unsigned int ui2, int i3, int i4);
/* 25 */
EXTERN int		XCopyPlane(Display *d, Drawable dr1, Drawable dr2,
				GC g, int i1, int i2, unsigned int ui1,
				unsigned int ui2, int i3, int i4,
				unsigned long ul);
/* 26 */
EXTERN Pixmap		XCreateBitmapFromData(Display *display, Drawable d,
				_Xconst char *data, unsigned int width,
				unsigned int height);
/* 27 */
EXTERN int		XDefineCursor(Display *d, Window w, Cursor c);
/* 28 */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);
/* 29 */
EXTERN int		XDestroyWindow(Display *d, Window w);
/* 30 */
EXTERN int		XDrawArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);
/* 31 */
EXTERN int		XDrawLines(Display *d, Drawable dr, GC g, XPoint *x,
				int i1, int i2);
/* 32 */
EXTERN int		XDrawRectangle(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2);
/* 33 */
EXTERN int		XFillArc(Display *d, Drawable dr, GC g, int i1,
				int i2, unsigned int ui1, unsigned int ui2,
				int i3, int i4);
/* 34 */
EXTERN int		XFillPolygon(Display *d, Drawable dr, GC g,
				XPoint *x, int i1, int i2, int i3);
/* 35 */
EXTERN int		XFillRectangles(Display *d, Drawable dr, GC g,
				XRectangle *x, int i);
/* 36 */
EXTERN int		XForceScreenSaver(Display *d, int i);
/* 37 */
EXTERN int		XFreeColormap(Display *d, Colormap c);
/* 38 */
EXTERN int		XFreeColors(Display *d, Colormap c,
				unsigned long *ulp, int i, unsigned long ul);
/* 39 */
EXTERN int		XFreeCursor(Display *d, Cursor c);
/* 40 */
EXTERN int		XFreeModifiermap(XModifierKeymap *x);
/* 41 */
EXTERN Status		XGetGeometry(Display *d, Drawable dr, Window *w,
				int *i1, int *i2, unsigned int *ui1,
				unsigned int *ui2, unsigned int *ui3,
				unsigned int *ui4);
/* 42 */
EXTERN int		XGetInputFocus(Display *d, Window *w, int *i);
/* 43 */
EXTERN int		XGetWindowProperty(Display *d, Window w, Atom a1,
				long l1, long l2, Bool b, Atom a2, Atom *ap,
				int *ip, unsigned long *ulp1,
				unsigned long *ulp2, unsigned char **cpp);
/* 44 */
EXTERN Status		XGetWindowAttributes(Display *d, Window w,
				XWindowAttributes *x);
/* 45 */
EXTERN int		XGrabKeyboard(Display *d, Window w, Bool b, int i1,
				int i2, Time t);
/* 46 */
EXTERN int		XGrabPointer(Display *d, Window w1, Bool b,
				unsigned int ui, int i1, int i2, Window w2,
				Cursor c, Time t);
/* 47 */
EXTERN KeyCode		XKeysymToKeycode(Display *d, KeySym k);
/* 48 */
EXTERN Status		XLookupColor(Display *d, Colormap c1,
				_Xconst char *c2, XColor *x1, XColor *x2);
/* 49 */
EXTERN int		XMapWindow(Display *d, Window w);
/* 50 */
EXTERN int		XMoveResizeWindow(Display *d, Window w, int i1,
				int i2, unsigned int ui1, unsigned int ui2);
/* 51 */
EXTERN int		XMoveWindow(Display *d, Window w, int i1, int i2);
/* 52 */
EXTERN int		XNextEvent(Display *d, XEvent *x);
/* 53 */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);
/* 54 */
EXTERN int		XQueryColors(Display *d, Colormap c, XColor *x,
				int i);
/* 55 */
EXTERN Bool		XQueryPointer(Display *d, Window w1, Window *w2,
				Window *w3, int *i1, int *i2, int *i3,
				int *i4, unsigned int *ui);
/* 56 */
EXTERN Status		XQueryTree(Display *d, Window w1, Window *w2,
				Window *w3, Window **w4, unsigned int *ui);
/* 57 */
EXTERN int		XRaiseWindow(Display *d, Window w);
/* 58 */
EXTERN int		XRefreshKeyboardMapping(XMappingEvent *x);
/* 59 */
EXTERN int		XResizeWindow(Display *d, Window w, unsigned int ui1,
				unsigned int ui2);
/* 60 */
EXTERN int		XSelectInput(Display *d, Window w, long l);
/* 61 */
EXTERN Status		XSendEvent(Display *d, Window w, Bool b, long l,
				XEvent *x);
/* 62 */
EXTERN int		XSetCommand(Display *d, Window w, char **c, int i);
/* 63 */
EXTERN int		XSetIconName(Display *d, Window w, _Xconst char *c);
/* 64 */
EXTERN int		XSetInputFocus(Display *d, Window w, int i, Time t);
/* 65 */
EXTERN int		XSetSelectionOwner(Display *d, Atom a, Window w,
				Time t);
/* 66 */
EXTERN int		XSetWindowBackground(Display *d, Window w,
				unsigned long ul);
/* 67 */
EXTERN int		XSetWindowBackgroundPixmap(Display *d, Window w,
				Pixmap p);
/* 68 */
EXTERN int		XSetWindowBorder(Display *d, Window w,
				unsigned long ul);
/* 69 */
EXTERN int		XSetWindowBorderPixmap(Display *d, Window w,
				Pixmap p);
/* 70 */
EXTERN int		XSetWindowBorderWidth(Display *d, Window w,
				unsigned int ui);
/* 71 */
EXTERN int		XSetWindowColormap(Display *d, Window w, Colormap c);
/* 72 */
EXTERN Bool		XTranslateCoordinates(Display *d, Window w1,
				Window w2, int i1, int i2, int *i3, int *i4,
				Window *w3);
/* 73 */
EXTERN int		XUngrabKeyboard(Display *d, Time t);
/* 74 */
EXTERN int		XUngrabPointer(Display *d, Time t);
/* 75 */
EXTERN int		XUnmapWindow(Display *d, Window w);
/* 76 */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);
/* 77 */
EXTERN void		XDestroyIC(XIC x);
/* 78 */
EXTERN Bool		XFilterEvent(XEvent *x, Window w);
/* 79 */
EXTERN int		XmbLookupString(XIC xi, XKeyPressedEvent *xk,
				char *c, int i, KeySym *k, Status *s);
/* 80 */
EXTERN int		TkPutImage(unsigned long *colors, int ncolors,
				Display *display, Drawable d, GC gc,
				XImage *image, int src_x, int src_y,
				int dest_x, int dest_y, unsigned int width,
				unsigned int height);
/* 81 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 82 */
EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);
/* 83 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
/* 84 */
EXTERN int		XFreeGC(Display *display, GC gc);
/* 85 */
EXTERN Atom		XInternAtom(Display *display,
				_Xconst char *atom_name, Bool only_if_exists);
/* 86 */
EXTERN int		XSetBackground(Display *display, GC gc,
				unsigned long foreground);
/* 87 */
EXTERN int		XSetForeground(Display *display, GC gc,
				unsigned long foreground);
/* 88 */
EXTERN int		XSetClipMask(Display *display, GC gc, Pixmap pixmap);
/* 89 */
EXTERN int		XSetClipOrigin(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin);
/* 90 */
EXTERN int		XSetTSOrigin(Display *display, GC gc,
				int ts_x_origin, int ts_y_origin);
/* 91 */
EXTERN int		XChangeGC(Display *d, GC gc, unsigned long mask,
				XGCValues *values);
/* 92 */
EXTERN int		XSetFont(Display *display, GC gc, Font font);
/* 93 */
EXTERN int		XSetArcMode(Display *display, GC gc, int arc_mode);
/* 94 */
EXTERN int		XSetStipple(Display *display, GC gc, Pixmap stipple);
/* 95 */
EXTERN int		XSetFillRule(Display *display, GC gc, int fill_rule);
/* 96 */
EXTERN int		XSetFillStyle(Display *display, GC gc,
				int fill_style);
/* 97 */
EXTERN int		XSetFunction(Display *display, GC gc, int function);
/* 98 */
EXTERN int		XSetLineAttributes(Display *display, GC gc,
				unsigned int line_width, int line_style,
				int cap_style, int join_style);
/* 99 */
EXTERN int		_XInitImageFuncPtrs(XImage *image);
/* 100 */
EXTERN XIC		XCreateIC(XIM xim, ...);
/* 101 */
EXTERN XVisualInfo *	XGetVisualInfo(Display *display, long vinfo_mask,
				XVisualInfo *vinfo_template,
				int *nitems_return);
/* 102 */
EXTERN void		XSetWMClientMachine(Display *display, Window w,
				XTextProperty *text_prop);
/* 103 */
EXTERN Status		XStringListToTextProperty(char **list, int count,
				XTextProperty *text_prop_return);
/* 104 */





EXTERN int		XDrawLine(Display *d, Drawable dr, GC g, int x1,
				int y1, int x2, int y2);
/* 105 */
EXTERN int		XWarpPointer(Display *d, Window s, Window dw, int sx,
				int sy, unsigned int sw, unsigned int sh,
				int dx, int dy);
/* 106 */
EXTERN int		XFillRectangle(Display *display, Drawable d, GC gc,
				int x, int y, unsigned int width,
				unsigned int height);






























































/* 107 */
EXTERN int		XFlush(Display *display);
/* 108 */
EXTERN int		XGrabServer(Display *display);
/* 109 */
EXTERN int		XUngrabServer(Display *display);
/* 110 */
EXTERN int		XFree(void *data);
/* 111 */
EXTERN int		XNoOp(Display *display);
/* 112 */
EXTERN XAfterFunction	XSynchronize(Display *display, Bool onoff);
/* 113 */
EXTERN int		XSync(Display *display, Bool discard);

/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
821
822
823
824
825
826
827
828


829


830


831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
				int n);
/* 131 */
EXTERN int		XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 132 */
EXTERN int		XDrawRectangles(Display *d, Drawable dr, GC gc,
				XRectangle *r, int n);
/* Slot 133 is reserved */


/* Slot 134 is reserved */


/* Slot 135 is reserved */


/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* 138 */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
EXTERN void		XSetICFocus(XIC xic);
/* 144 */
EXTERN void		XDestroyIC(XIC xic);
/* 145 */
EXTERN Cursor		XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
				XColor *x1, XColor *x2, unsigned int ui1,
				unsigned int ui2);
/* 146 */
EXTERN Cursor		XCreateGlyphCursor(Display *d, Font f1, Font f2,
				unsigned int ui1, unsigned int ui2,
				XColor _Xconst *x1, XColor _Xconst *x2);
/* 147 */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
EXTERN int		XCloseIM(XIM im);
/* 149 */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,







|
>
>
|
>
>
|
>
>



















|
<
|
<
<
<
|
<
<
<







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857

858



859



860
861
862
863
864
865
866
				int n);
/* 131 */
EXTERN int		XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 132 */
EXTERN int		XDrawRectangles(Display *d, Drawable dr, GC gc,
				XRectangle *r, int n);
/* 133 */
EXTERN int		XDrawSegments(Display *d, Drawable dr, GC gc,
				XSegment *s, int n);
/* 134 */
EXTERN int		XDrawPoint(Display *d, Drawable dr, GC gc, int x,
				int y);
/* 135 */
EXTERN int		XDrawPoints(Display *d, Drawable dr, GC gc,
				XPoint *p, int n, int m);
/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* 138 */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
EXTERN void		XSetICFocus(XIC xic);
/* Slot 144 is reserved */

/* Slot 145 is reserved */



/* Slot 146 is reserved */



/* 147 */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
EXTERN int		XCloseIM(XIM im);
/* 149 */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
    int (*xUngrabPointer) (Display *d, Time t); /* 74 */
    int (*xUnmapWindow) (Display *d, Window w); /* 75 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 76 */
    void (*xDestroyIC) (XIC x); /* 77 */
    Bool (*xFilterEvent) (XEvent *x, Window w); /* 78 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 79 */
    int (*tkPutImage) (unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); /* 80 */
    void (*reserved81)(void);
    Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 82 */
    GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 83 */
    int (*xFreeGC) (Display *display, GC gc); /* 84 */
    Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 85 */
    int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 86 */
    int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 87 */
    int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 88 */







|







979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
    int (*xUngrabPointer) (Display *d, Time t); /* 74 */
    int (*xUnmapWindow) (Display *d, Window w); /* 75 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 76 */
    void (*xDestroyIC) (XIC x); /* 77 */
    Bool (*xFilterEvent) (XEvent *x, Window w); /* 78 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 79 */
    int (*tkPutImage) (unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); /* 80 */
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 81 */
    Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 82 */
    GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 83 */
    int (*xFreeGC) (Display *display, GC gc); /* 84 */
    Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 85 */
    int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 86 */
    int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 87 */
    int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 88 */
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
    int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
    XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
    XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
    XImage * (*xGetImage) (Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); /* 3 */
    char * (*xGetAtomName) (Display *d, Atom a); /* 4 */
    char * (*xKeysymToString) (KeySym k); /* 5 */
    Colormap (*xCreateColormap) (Display *d, Window w, Visual *v, int i); /* 6 */


    GContext (*xGContextFromGC) (GC g); /* 7 */

    KeySym (*xKeycodeToKeysym) (Display *d, unsigned int k, int i); /* 8 */
    KeySym (*xStringToKeysym) (_Xconst char *c); /* 9 */
    Window (*xRootWindow) (Display *d, int i); /* 10 */
    XErrorHandler (*xSetErrorHandler) (XErrorHandler x); /* 11 */



    Status (*xAllocColor) (Display *d, Colormap c, XColor *xp); /* 12 */
    int (*xBell) (Display *d, int i); /* 13 */
    int (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 14 */
    int (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 15 */

    int (*xConfigureWindow) (Display *d, Window w, unsigned int i, XWindowChanges *x); /* 16 */
    int (*xCopyArea) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 17 */
    int (*xCopyPlane) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4, unsigned long ul); /* 18 */
    Pixmap (*xCreateBitmapFromData) (Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height); /* 19 */
    int (*xDefineCursor) (Display *d, Window w, Cursor c); /* 20 */

    int (*xDestroyWindow) (Display *d, Window w); /* 21 */
    int (*xDrawArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 22 */
    int (*xDrawLines) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2); /* 23 */
    int (*xDrawRectangle) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 24 */
    int (*xFillArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 25 */
    int (*xFillPolygon) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3); /* 26 */
    int (*xFillRectangles) (Display *d, Drawable dr, GC g, XRectangle *x, int i); /* 27 */

    int (*xFreeColormap) (Display *d, Colormap c); /* 28 */
    int (*xFreeColors) (Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul); /* 29 */

    int (*xFreeModifiermap) (XModifierKeymap *x); /* 30 */
    Status (*xGetGeometry) (Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4); /* 31 */

    int (*xGetWindowProperty) (Display *d, Window w, Atom a1, long l1, long l2, Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1, unsigned long *ulp2, unsigned char **cpp); /* 32 */

    int (*xGrabKeyboard) (Display *d, Window w, Bool b, int i1, int i2, Time t); /* 33 */
    int (*xGrabPointer) (Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); /* 34 */
    KeyCode (*xKeysymToKeycode) (Display *d, KeySym k); /* 35 */

    int (*xMapWindow) (Display *d, Window w); /* 36 */
    int (*xMoveResizeWindow) (Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 37 */
    int (*xMoveWindow) (Display *d, Window w, int i1, int i2); /* 38 */
    Bool (*xQueryPointer) (Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui); /* 39 */
    int (*xRaiseWindow) (Display *d, Window w); /* 40 */
    int (*xRefreshKeyboardMapping) (XMappingEvent *x); /* 41 */
    int (*xResizeWindow) (Display *d, Window w, unsigned int ui1, unsigned int ui2); /* 42 */
    int (*xSelectInput) (Display *d, Window w, long l); /* 43 */
    Status (*xSendEvent) (Display *d, Window w, Bool b, long l, XEvent *x); /* 44 */
    int (*xSetIconName) (Display *d, Window w, _Xconst char *c); /* 45 */
    int (*xSetInputFocus) (Display *d, Window w, int i, Time t); /* 46 */
    int (*xSetSelectionOwner) (Display *d, Atom a, Window w, Time t); /* 47 */
    int (*xSetWindowBackground) (Display *d, Window w, unsigned long ul); /* 48 */
    int (*xSetWindowBackgroundPixmap) (Display *d, Window w, Pixmap p); /* 49 */
    int (*xSetWindowBorder) (Display *d, Window w, unsigned long ul); /* 50 */
    int (*xSetWindowBorderPixmap) (Display *d, Window w, Pixmap p); /* 51 */
    int (*xSetWindowBorderWidth) (Display *d, Window w, unsigned int ui); /* 52 */
    int (*xSetWindowColormap) (Display *d, Window w, Colormap c); /* 53 */
    int (*xUngrabKeyboard) (Display *d, Time t); /* 54 */
    int (*xUngrabPointer) (Display *d, Time t); /* 55 */
    int (*xUnmapWindow) (Display *d, Window w); /* 56 */
    int (*tkPutImage) (unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); /* 57 */
    Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 58 */
    GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 59 */
    int (*xFreeGC) (Display *display, GC gc); /* 60 */
    Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 61 */
    int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 62 */
    int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 63 */
    int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 64 */
    int (*xSetClipOrigin) (Display *display, GC gc, int clip_x_origin, int clip_y_origin); /* 65 */
    int (*xSetTSOrigin) (Display *display, GC gc, int ts_x_origin, int ts_y_origin); /* 66 */
    int (*xChangeGC) (Display *d, GC gc, unsigned long mask, XGCValues *values); /* 67 */
    int (*xSetFont) (Display *display, GC gc, Font font); /* 68 */
    int (*xSetArcMode) (Display *display, GC gc, int arc_mode); /* 69 */
    int (*xSetStipple) (Display *display, GC gc, Pixmap stipple); /* 70 */

    int (*xSetFillRule) (Display *display, GC gc, int fill_rule); /* 71 */
    int (*xSetFillStyle) (Display *display, GC gc, int fill_style); /* 72 */
    int (*xSetFunction) (Display *display, GC gc, int function); /* 73 */
    int (*xSetLineAttributes) (Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); /* 74 */
    int (*_XInitImageFuncPtrs) (XImage *image); /* 75 */
    XIC (*xCreateIC) (XIM xim, ...); /* 76 */

    XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 77 */
    void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 78 */
    Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 79 */
    int (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */
    int (*xForceScreenSaver) (Display *display, int mode); /* 81 */
    int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 82 */
    int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 83 */
    int (*xClearWindow) (Display *d, Window w); /* 84 */
    int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
    int (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */
    int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */
    int (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */
    int (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */
    Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 90 */
    int (*xSync) (Display *display, Bool discard); /* 91 */
    Bool (*xTranslateCoordinates) (Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3); /* 92 */
    int (*xDeleteProperty) (Display *d, Window w, Atom a); /* 93 */
    int (*xFreeCursor) (Display *d, Cursor c); /* 94 */
    int (*xGetInputFocus) (Display *d, Window *w, int *i); /* 95 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 96 */
    int (*xNextEvent) (Display *d, XEvent *x); /* 97 */
    int (*xPutBackEvent) (Display *d, XEvent *x); /* 98 */
    int (*xSetCommand) (Display *d, Window w, char **c, int i); /* 99 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 100 */
    Status (*xGetWindowAttributes) (Display *d, Window w, XWindowAttributes *x); /* 101 */
    Status (*xGetWMColormapWindows) (Display *d, Window w, Window **wpp, int *ip); /* 102 */
    Status (*xIconifyWindow) (Display *d, Window w, int i); /* 103 */
    Status (*xWithdrawWindow) (Display *d, Window w, int i); /* 104 */
    XHostAddress * (*xListHosts) (Display *d, int *i, Bool *b); /* 105 */
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 106 */
    int (*xFlush) (Display *display); /* 107 */
    int (*xGrabServer) (Display *display); /* 108 */
    int (*xUngrabServer) (Display *display); /* 109 */
    int (*xFree) (void *data); /* 110 */
    int (*xNoOp) (Display *display); /* 111 */
    XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */
    Status (*xLookupColor) (Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2); /* 113 */
    VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
    void (*reserved115)(void);
    void (*reserved116)(void);
    void (*reserved117)(void);
    void (*reserved118)(void);
    void (*reserved119)(void);
    int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */
    int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */
    Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */
    void (*reserved123)(void);
    void (*reserved124)(void);
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    int (*xLowerWindow) (Display *d, Window w); /* 129 */
    int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*reserved135)(void);
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
    int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
    XVaNestedList (*xVaCreateNestedList) (int dummy, ...); /* 140 */
    char * (*xSetICValues) (XIC xic, ...); /* 141 */
    char * (*xGetICValues) (XIC xic, ...); /* 142 */
    void (*xSetICFocus) (XIC xic); /* 143 */
    void (*xDestroyIC) (XIC xic); /* 144 */
    Cursor (*xCreatePixmapCursor) (Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); /* 145 */
    Cursor (*xCreateGlyphCursor) (Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); /* 146 */
    void (*xFreeFontSet) (Display *display, XFontSet fontset); /* 147 */
    int (*xCloseIM) (XIM im); /* 148 */
    Bool (*xRegisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 149 */
    Bool (*xUnregisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 150 */
    char * (*xSetLocaleModifiers) (const char *modifier_list); /* 151 */
    XIM (*xOpenIM) (Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name, char *res_class); /* 152 */
    char * (*xGetIMValues) (XIM im, ...); /* 153 */







>
>
|
>
|
|
|
|
>
>
>
|
|
|
|
>
|
|
|
|
|
>
|
|
|
|
|
|
|
>
|
|
>
|
|
>
|
>
|
|
|
>
|
|
|
<
|
<
<
<
|
<
|
<
<
|
|
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
>
|
|
|
|
|
<
|
|
|
|
<
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|






|



















|
|
|








|
|
|







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
    int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
    XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
    XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
    XImage * (*xGetImage) (Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); /* 3 */
    char * (*xGetAtomName) (Display *d, Atom a); /* 4 */
    char * (*xKeysymToString) (KeySym k); /* 5 */
    Colormap (*xCreateColormap) (Display *d, Window w, Visual *v, int i); /* 6 */
    Cursor (*xCreatePixmapCursor) (Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); /* 7 */
    Cursor (*xCreateGlyphCursor) (Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); /* 8 */
    GContext (*xGContextFromGC) (GC g); /* 9 */
    XHostAddress * (*xListHosts) (Display *d, int *i, Bool *b); /* 10 */
    KeySym (*xKeycodeToKeysym) (Display *d, unsigned int k, int i); /* 11 */
    KeySym (*xStringToKeysym) (_Xconst char *c); /* 12 */
    Window (*xRootWindow) (Display *d, int i); /* 13 */
    XErrorHandler (*xSetErrorHandler) (XErrorHandler x); /* 14 */
    Status (*xIconifyWindow) (Display *d, Window w, int i); /* 15 */
    Status (*xWithdrawWindow) (Display *d, Window w, int i); /* 16 */
    Status (*xGetWMColormapWindows) (Display *d, Window w, Window **wpp, int *ip); /* 17 */
    Status (*xAllocColor) (Display *d, Colormap c, XColor *xp); /* 18 */
    int (*xBell) (Display *d, int i); /* 19 */
    int (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 20 */
    int (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 21 */
    int (*xClearWindow) (Display *d, Window w); /* 22 */
    int (*xConfigureWindow) (Display *d, Window w, unsigned int i, XWindowChanges *x); /* 23 */
    int (*xCopyArea) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 24 */
    int (*xCopyPlane) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4, unsigned long ul); /* 25 */
    Pixmap (*xCreateBitmapFromData) (Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height); /* 26 */
    int (*xDefineCursor) (Display *d, Window w, Cursor c); /* 27 */
    int (*xDeleteProperty) (Display *d, Window w, Atom a); /* 28 */
    int (*xDestroyWindow) (Display *d, Window w); /* 29 */
    int (*xDrawArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 30 */
    int (*xDrawLines) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2); /* 31 */
    int (*xDrawRectangle) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 32 */
    int (*xFillArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 33 */
    int (*xFillPolygon) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3); /* 34 */
    int (*xFillRectangles) (Display *d, Drawable dr, GC g, XRectangle *x, int i); /* 35 */
    int (*xForceScreenSaver) (Display *d, int i); /* 36 */
    int (*xFreeColormap) (Display *d, Colormap c); /* 37 */
    int (*xFreeColors) (Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul); /* 38 */
    int (*xFreeCursor) (Display *d, Cursor c); /* 39 */
    int (*xFreeModifiermap) (XModifierKeymap *x); /* 40 */
    Status (*xGetGeometry) (Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4); /* 41 */
    int (*xGetInputFocus) (Display *d, Window *w, int *i); /* 42 */
    int (*xGetWindowProperty) (Display *d, Window w, Atom a1, long l1, long l2, Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1, unsigned long *ulp2, unsigned char **cpp); /* 43 */
    Status (*xGetWindowAttributes) (Display *d, Window w, XWindowAttributes *x); /* 44 */
    int (*xGrabKeyboard) (Display *d, Window w, Bool b, int i1, int i2, Time t); /* 45 */
    int (*xGrabPointer) (Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); /* 46 */
    KeyCode (*xKeysymToKeycode) (Display *d, KeySym k); /* 47 */
    Status (*xLookupColor) (Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2); /* 48 */
    int (*xMapWindow) (Display *d, Window w); /* 49 */
    int (*xMoveResizeWindow) (Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 50 */
    int (*xMoveWindow) (Display *d, Window w, int i1, int i2); /* 51 */

    int (*xNextEvent) (Display *d, XEvent *x); /* 52 */



    int (*xPutBackEvent) (Display *d, XEvent *x); /* 53 */

    int (*xQueryColors) (Display *d, Colormap c, XColor *x, int i); /* 54 */


    Bool (*xQueryPointer) (Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui); /* 55 */
    Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 56 */





    int (*xRaiseWindow) (Display *d, Window w); /* 57 */
    int (*xRefreshKeyboardMapping) (XMappingEvent *x); /* 58 */
    int (*xResizeWindow) (Display *d, Window w, unsigned int ui1, unsigned int ui2); /* 59 */
    int (*xSelectInput) (Display *d, Window w, long l); /* 60 */
    Status (*xSendEvent) (Display *d, Window w, Bool b, long l, XEvent *x); /* 61 */
    int (*xSetCommand) (Display *d, Window w, char **c, int i); /* 62 */
    int (*xSetIconName) (Display *d, Window w, _Xconst char *c); /* 63 */
    int (*xSetInputFocus) (Display *d, Window w, int i, Time t); /* 64 */
    int (*xSetSelectionOwner) (Display *d, Atom a, Window w, Time t); /* 65 */
    int (*xSetWindowBackground) (Display *d, Window w, unsigned long ul); /* 66 */
    int (*xSetWindowBackgroundPixmap) (Display *d, Window w, Pixmap p); /* 67 */
    int (*xSetWindowBorder) (Display *d, Window w, unsigned long ul); /* 68 */
    int (*xSetWindowBorderPixmap) (Display *d, Window w, Pixmap p); /* 69 */
    int (*xSetWindowBorderWidth) (Display *d, Window w, unsigned int ui); /* 70 */
    int (*xSetWindowColormap) (Display *d, Window w, Colormap c); /* 71 */
    Bool (*xTranslateCoordinates) (Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3); /* 72 */
    int (*xUngrabKeyboard) (Display *d, Time t); /* 73 */
    int (*xUngrabPointer) (Display *d, Time t); /* 74 */
    int (*xUnmapWindow) (Display *d, Window w); /* 75 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 76 */
    void (*xDestroyIC) (XIC x); /* 77 */
    Bool (*xFilterEvent) (XEvent *x, Window w); /* 78 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 79 */
    int (*tkPutImage) (unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); /* 80 */
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 81 */
    Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 82 */
    GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 83 */
    int (*xFreeGC) (Display *display, GC gc); /* 84 */

    Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 85 */
    int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 86 */
    int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 87 */
    int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 88 */

    int (*xSetClipOrigin) (Display *display, GC gc, int clip_x_origin, int clip_y_origin); /* 89 */
    int (*xSetTSOrigin) (Display *display, GC gc, int ts_x_origin, int ts_y_origin); /* 90 */
    int (*xChangeGC) (Display *d, GC gc, unsigned long mask, XGCValues *values); /* 91 */
    int (*xSetFont) (Display *display, GC gc, Font font); /* 92 */
    int (*xSetArcMode) (Display *display, GC gc, int arc_mode); /* 93 */
    int (*xSetStipple) (Display *display, GC gc, Pixmap stipple); /* 94 */
    int (*xSetFillRule) (Display *display, GC gc, int fill_rule); /* 95 */
    int (*xSetFillStyle) (Display *display, GC gc, int fill_style); /* 96 */

    int (*xSetFunction) (Display *display, GC gc, int function); /* 97 */
    int (*xSetLineAttributes) (Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); /* 98 */
    int (*_XInitImageFuncPtrs) (XImage *image); /* 99 */
    XIC (*xCreateIC) (XIM xim, ...); /* 100 */
    XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 101 */
    void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 102 */
    Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 103 */
    int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 104 */
    int (*xWarpPointer) (Display *d, Window s, Window dw, int sx, int sy, unsigned int sw, unsigned int sh, int dx, int dy); /* 105 */
    int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 106 */
    int (*xFlush) (Display *display); /* 107 */
    int (*xGrabServer) (Display *display); /* 108 */
    int (*xUngrabServer) (Display *display); /* 109 */
    int (*xFree) (void *data); /* 110 */
    int (*xNoOp) (Display *display); /* 111 */
    XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */
    int (*xSync) (Display *display, Bool discard); /* 113 */
    VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
    void (*reserved115)(void);
    void (*reserved116)(void);
    void (*reserved117)(void);
    void (*reserved118)(void);
    void (*reserved119)(void);
    int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */
    int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */
    Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */
    void (*reserved123)(void);
    void (*reserved124)(void);
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    int (*xLowerWindow) (Display *d, Window w); /* 129 */
    int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */
    int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */
    int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
    int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
    XVaNestedList (*xVaCreateNestedList) (int dummy, ...); /* 140 */
    char * (*xSetICValues) (XIC xic, ...); /* 141 */
    char * (*xGetICValues) (XIC xic, ...); /* 142 */
    void (*xSetICFocus) (XIC xic); /* 143 */
    void (*reserved144)(void);
    void (*reserved145)(void);
    void (*reserved146)(void);
    void (*xFreeFontSet) (Display *display, XFontSet fontset); /* 147 */
    int (*xCloseIM) (XIM im); /* 148 */
    Bool (*xRegisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 149 */
    Bool (*xUnregisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 150 */
    char * (*xSetLocaleModifiers) (const char *modifier_list); /* 151 */
    XIM (*xOpenIM) (Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name, char *res_class); /* 152 */
    char * (*xGetIMValues) (XIM im, ...); /* 153 */
1396
1397
1398
1399
1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410
	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */
#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */
/* Slot 81 is reserved */

#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */
#define XInternAtom \







|
>







1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */
#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 81 */
#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */
#define XInternAtom \
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
	(tkIntXlibStubsPtr->xGetImage) /* 3 */
#define XGetAtomName \
	(tkIntXlibStubsPtr->xGetAtomName) /* 4 */
#define XKeysymToString \
	(tkIntXlibStubsPtr->xKeysymToString) /* 5 */
#define XCreateColormap \
	(tkIntXlibStubsPtr->xCreateColormap) /* 6 */




#define XGContextFromGC \
	(tkIntXlibStubsPtr->xGContextFromGC) /* 7 */


#define XKeycodeToKeysym \
	(tkIntXlibStubsPtr->xKeycodeToKeysym) /* 8 */
#define XStringToKeysym \
	(tkIntXlibStubsPtr->xStringToKeysym) /* 9 */
#define XRootWindow \
	(tkIntXlibStubsPtr->xRootWindow) /* 10 */
#define XSetErrorHandler \
	(tkIntXlibStubsPtr->xSetErrorHandler) /* 11 */






#define XAllocColor \
	(tkIntXlibStubsPtr->xAllocColor) /* 12 */
#define XBell \
	(tkIntXlibStubsPtr->xBell) /* 13 */
#define XChangeProperty \
	(tkIntXlibStubsPtr->xChangeProperty) /* 14 */
#define XChangeWindowAttributes \
	(tkIntXlibStubsPtr->xChangeWindowAttributes) /* 15 */


#define XConfigureWindow \
	(tkIntXlibStubsPtr->xConfigureWindow) /* 16 */
#define XCopyArea \
	(tkIntXlibStubsPtr->xCopyArea) /* 17 */
#define XCopyPlane \
	(tkIntXlibStubsPtr->xCopyPlane) /* 18 */
#define XCreateBitmapFromData \
	(tkIntXlibStubsPtr->xCreateBitmapFromData) /* 19 */
#define XDefineCursor \
	(tkIntXlibStubsPtr->xDefineCursor) /* 20 */


#define XDestroyWindow \
	(tkIntXlibStubsPtr->xDestroyWindow) /* 21 */
#define XDrawArc \
	(tkIntXlibStubsPtr->xDrawArc) /* 22 */
#define XDrawLines \
	(tkIntXlibStubsPtr->xDrawLines) /* 23 */
#define XDrawRectangle \
	(tkIntXlibStubsPtr->xDrawRectangle) /* 24 */
#define XFillArc \
	(tkIntXlibStubsPtr->xFillArc) /* 25 */
#define XFillPolygon \
	(tkIntXlibStubsPtr->xFillPolygon) /* 26 */
#define XFillRectangles \
	(tkIntXlibStubsPtr->xFillRectangles) /* 27 */


#define XFreeColormap \
	(tkIntXlibStubsPtr->xFreeColormap) /* 28 */
#define XFreeColors \
	(tkIntXlibStubsPtr->xFreeColors) /* 29 */


#define XFreeModifiermap \
	(tkIntXlibStubsPtr->xFreeModifiermap) /* 30 */
#define XGetGeometry \
	(tkIntXlibStubsPtr->xGetGeometry) /* 31 */


#define XGetWindowProperty \
	(tkIntXlibStubsPtr->xGetWindowProperty) /* 32 */


#define XGrabKeyboard \
	(tkIntXlibStubsPtr->xGrabKeyboard) /* 33 */
#define XGrabPointer \
	(tkIntXlibStubsPtr->xGrabPointer) /* 34 */
#define XKeysymToKeycode \
	(tkIntXlibStubsPtr->xKeysymToKeycode) /* 35 */


#define XMapWindow \
	(tkIntXlibStubsPtr->xMapWindow) /* 36 */
#define XMoveResizeWindow \
	(tkIntXlibStubsPtr->xMoveResizeWindow) /* 37 */
#define XMoveWindow \
	(tkIntXlibStubsPtr->xMoveWindow) /* 38 */






#define XQueryPointer \
	(tkIntXlibStubsPtr->xQueryPointer) /* 39 */


#define XRaiseWindow \
	(tkIntXlibStubsPtr->xRaiseWindow) /* 40 */
#define XRefreshKeyboardMapping \
	(tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 41 */
#define XResizeWindow \
	(tkIntXlibStubsPtr->xResizeWindow) /* 42 */
#define XSelectInput \
	(tkIntXlibStubsPtr->xSelectInput) /* 43 */
#define XSendEvent \
	(tkIntXlibStubsPtr->xSendEvent) /* 44 */


#define XSetIconName \
	(tkIntXlibStubsPtr->xSetIconName) /* 45 */
#define XSetInputFocus \
	(tkIntXlibStubsPtr->xSetInputFocus) /* 46 */
#define XSetSelectionOwner \
	(tkIntXlibStubsPtr->xSetSelectionOwner) /* 47 */
#define XSetWindowBackground \
	(tkIntXlibStubsPtr->xSetWindowBackground) /* 48 */
#define XSetWindowBackgroundPixmap \
	(tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 49 */
#define XSetWindowBorder \
	(tkIntXlibStubsPtr->xSetWindowBorder) /* 50 */
#define XSetWindowBorderPixmap \
	(tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 51 */
#define XSetWindowBorderWidth \
	(tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 52 */
#define XSetWindowColormap \
	(tkIntXlibStubsPtr->xSetWindowColormap) /* 53 */


#define XUngrabKeyboard \
	(tkIntXlibStubsPtr->xUngrabKeyboard) /* 54 */
#define XUngrabPointer \
	(tkIntXlibStubsPtr->xUngrabPointer) /* 55 */
#define XUnmapWindow \
	(tkIntXlibStubsPtr->xUnmapWindow) /* 56 */








#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 57 */


#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 58 */
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 59 */
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 60 */
#define XInternAtom \
	(tkIntXlibStubsPtr->xInternAtom) /* 61 */
#define XSetBackground \
	(tkIntXlibStubsPtr->xSetBackground) /* 62 */
#define XSetForeground \
	(tkIntXlibStubsPtr->xSetForeground) /* 63 */
#define XSetClipMask \
	(tkIntXlibStubsPtr->xSetClipMask) /* 64 */
#define XSetClipOrigin \
	(tkIntXlibStubsPtr->xSetClipOrigin) /* 65 */
#define XSetTSOrigin \
	(tkIntXlibStubsPtr->xSetTSOrigin) /* 66 */
#define XChangeGC \
	(tkIntXlibStubsPtr->xChangeGC) /* 67 */
#define XSetFont \
	(tkIntXlibStubsPtr->xSetFont) /* 68 */
#define XSetArcMode \
	(tkIntXlibStubsPtr->xSetArcMode) /* 69 */
#define XSetStipple \
	(tkIntXlibStubsPtr->xSetStipple) /* 70 */
#define XSetFillRule \
	(tkIntXlibStubsPtr->xSetFillRule) /* 71 */
#define XSetFillStyle \
	(tkIntXlibStubsPtr->xSetFillStyle) /* 72 */
#define XSetFunction \
	(tkIntXlibStubsPtr->xSetFunction) /* 73 */
#define XSetLineAttributes \
	(tkIntXlibStubsPtr->xSetLineAttributes) /* 74 */
#define _XInitImageFuncPtrs \
	(tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 75 */
#define XCreateIC \
	(tkIntXlibStubsPtr->xCreateIC) /* 76 */
#define XGetVisualInfo \
	(tkIntXlibStubsPtr->xGetVisualInfo) /* 77 */
#define XSetWMClientMachine \
	(tkIntXlibStubsPtr->xSetWMClientMachine) /* 78 */
#define XStringListToTextProperty \
	(tkIntXlibStubsPtr->xStringListToTextProperty) /* 79 */
#define XDrawSegments \
	(tkIntXlibStubsPtr->xDrawSegments) /* 80 */
#define XForceScreenSaver \
	(tkIntXlibStubsPtr->xForceScreenSaver) /* 81 */
#define XDrawLine \
	(tkIntXlibStubsPtr->xDrawLine) /* 82 */
#define XFillRectangle \
	(tkIntXlibStubsPtr->xFillRectangle) /* 83 */
#define XClearWindow \
	(tkIntXlibStubsPtr->xClearWindow) /* 84 */
#define XDrawPoint \
	(tkIntXlibStubsPtr->xDrawPoint) /* 85 */
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 86 */
#define XWarpPointer \
	(tkIntXlibStubsPtr->xWarpPointer) /* 87 */
#define XQueryColor \
	(tkIntXlibStubsPtr->xQueryColor) /* 88 */
#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 89 */
#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 90 */
#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 91 */
#define XTranslateCoordinates \
	(tkIntXlibStubsPtr->xTranslateCoordinates) /* 92 */
#define XDeleteProperty \
	(tkIntXlibStubsPtr->xDeleteProperty) /* 93 */
#define XFreeCursor \
	(tkIntXlibStubsPtr->xFreeCursor) /* 94 */
#define XGetInputFocus \
	(tkIntXlibStubsPtr->xGetInputFocus) /* 95 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 96 */
#define XNextEvent \
	(tkIntXlibStubsPtr->xNextEvent) /* 97 */
#define XPutBackEvent \
	(tkIntXlibStubsPtr->xPutBackEvent) /* 98 */
#define XSetCommand \
	(tkIntXlibStubsPtr->xSetCommand) /* 99 */
#define XWindowEvent \
	(tkIntXlibStubsPtr->xWindowEvent) /* 100 */
#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 101 */
#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 102 */
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 103 */
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 104 */
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 105 */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 106 */
#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */
#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */
#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */
#define XFree \
	(tkIntXlibStubsPtr->xFree) /* 110 */
#define XNoOp \
	(tkIntXlibStubsPtr->xNoOp) /* 111 */
#define XSynchronize \
	(tkIntXlibStubsPtr->xSynchronize) /* 112 */
#define XLookupColor \
	(tkIntXlibStubsPtr->xLookupColor) /* 113 */
#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */







>
>
>
>

|
>
>

|

|

|

|
>
>
>
>
>
>

|

|

|

|
>
>

|

|

|

|

|
>
>

|

|

|

|

|

|

|
>
>

|

|
>
>

|

|
>
>

|
>
>

|

|

|
>
>

|

|

|
>
>
>
>
>
>

|
>
>

|

|

|

|

|
>
>

|

|

|

|

|

|

|

|

|
>
>

|

|

|
>
>
>
>
>
>
>
>

|
>
>

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|
<
<
<
<

|
<
<
<
<
<
<
<
<

|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












|
|







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
	(tkIntXlibStubsPtr->xGetImage) /* 3 */
#define XGetAtomName \
	(tkIntXlibStubsPtr->xGetAtomName) /* 4 */
#define XKeysymToString \
	(tkIntXlibStubsPtr->xKeysymToString) /* 5 */
#define XCreateColormap \
	(tkIntXlibStubsPtr->xCreateColormap) /* 6 */
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 7 */
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 8 */
#define XGContextFromGC \
	(tkIntXlibStubsPtr->xGContextFromGC) /* 9 */
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 10 */
#define XKeycodeToKeysym \
	(tkIntXlibStubsPtr->xKeycodeToKeysym) /* 11 */
#define XStringToKeysym \
	(tkIntXlibStubsPtr->xStringToKeysym) /* 12 */
#define XRootWindow \
	(tkIntXlibStubsPtr->xRootWindow) /* 13 */
#define XSetErrorHandler \
	(tkIntXlibStubsPtr->xSetErrorHandler) /* 14 */
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 15 */
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 16 */
#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 17 */
#define XAllocColor \
	(tkIntXlibStubsPtr->xAllocColor) /* 18 */
#define XBell \
	(tkIntXlibStubsPtr->xBell) /* 19 */
#define XChangeProperty \
	(tkIntXlibStubsPtr->xChangeProperty) /* 20 */
#define XChangeWindowAttributes \
	(tkIntXlibStubsPtr->xChangeWindowAttributes) /* 21 */
#define XClearWindow \
	(tkIntXlibStubsPtr->xClearWindow) /* 22 */
#define XConfigureWindow \
	(tkIntXlibStubsPtr->xConfigureWindow) /* 23 */
#define XCopyArea \
	(tkIntXlibStubsPtr->xCopyArea) /* 24 */
#define XCopyPlane \
	(tkIntXlibStubsPtr->xCopyPlane) /* 25 */
#define XCreateBitmapFromData \
	(tkIntXlibStubsPtr->xCreateBitmapFromData) /* 26 */
#define XDefineCursor \
	(tkIntXlibStubsPtr->xDefineCursor) /* 27 */
#define XDeleteProperty \
	(tkIntXlibStubsPtr->xDeleteProperty) /* 28 */
#define XDestroyWindow \
	(tkIntXlibStubsPtr->xDestroyWindow) /* 29 */
#define XDrawArc \
	(tkIntXlibStubsPtr->xDrawArc) /* 30 */
#define XDrawLines \
	(tkIntXlibStubsPtr->xDrawLines) /* 31 */
#define XDrawRectangle \
	(tkIntXlibStubsPtr->xDrawRectangle) /* 32 */
#define XFillArc \
	(tkIntXlibStubsPtr->xFillArc) /* 33 */
#define XFillPolygon \
	(tkIntXlibStubsPtr->xFillPolygon) /* 34 */
#define XFillRectangles \
	(tkIntXlibStubsPtr->xFillRectangles) /* 35 */
#define XForceScreenSaver \
	(tkIntXlibStubsPtr->xForceScreenSaver) /* 36 */
#define XFreeColormap \
	(tkIntXlibStubsPtr->xFreeColormap) /* 37 */
#define XFreeColors \
	(tkIntXlibStubsPtr->xFreeColors) /* 38 */
#define XFreeCursor \
	(tkIntXlibStubsPtr->xFreeCursor) /* 39 */
#define XFreeModifiermap \
	(tkIntXlibStubsPtr->xFreeModifiermap) /* 40 */
#define XGetGeometry \
	(tkIntXlibStubsPtr->xGetGeometry) /* 41 */
#define XGetInputFocus \
	(tkIntXlibStubsPtr->xGetInputFocus) /* 42 */
#define XGetWindowProperty \
	(tkIntXlibStubsPtr->xGetWindowProperty) /* 43 */
#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 44 */
#define XGrabKeyboard \
	(tkIntXlibStubsPtr->xGrabKeyboard) /* 45 */
#define XGrabPointer \
	(tkIntXlibStubsPtr->xGrabPointer) /* 46 */
#define XKeysymToKeycode \
	(tkIntXlibStubsPtr->xKeysymToKeycode) /* 47 */
#define XLookupColor \
	(tkIntXlibStubsPtr->xLookupColor) /* 48 */
#define XMapWindow \
	(tkIntXlibStubsPtr->xMapWindow) /* 49 */
#define XMoveResizeWindow \
	(tkIntXlibStubsPtr->xMoveResizeWindow) /* 50 */
#define XMoveWindow \
	(tkIntXlibStubsPtr->xMoveWindow) /* 51 */
#define XNextEvent \
	(tkIntXlibStubsPtr->xNextEvent) /* 52 */
#define XPutBackEvent \
	(tkIntXlibStubsPtr->xPutBackEvent) /* 53 */
#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 54 */
#define XQueryPointer \
	(tkIntXlibStubsPtr->xQueryPointer) /* 55 */
#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 56 */
#define XRaiseWindow \
	(tkIntXlibStubsPtr->xRaiseWindow) /* 57 */
#define XRefreshKeyboardMapping \
	(tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 58 */
#define XResizeWindow \
	(tkIntXlibStubsPtr->xResizeWindow) /* 59 */
#define XSelectInput \
	(tkIntXlibStubsPtr->xSelectInput) /* 60 */
#define XSendEvent \
	(tkIntXlibStubsPtr->xSendEvent) /* 61 */
#define XSetCommand \
	(tkIntXlibStubsPtr->xSetCommand) /* 62 */
#define XSetIconName \
	(tkIntXlibStubsPtr->xSetIconName) /* 63 */
#define XSetInputFocus \
	(tkIntXlibStubsPtr->xSetInputFocus) /* 64 */
#define XSetSelectionOwner \
	(tkIntXlibStubsPtr->xSetSelectionOwner) /* 65 */
#define XSetWindowBackground \
	(tkIntXlibStubsPtr->xSetWindowBackground) /* 66 */
#define XSetWindowBackgroundPixmap \
	(tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 67 */
#define XSetWindowBorder \
	(tkIntXlibStubsPtr->xSetWindowBorder) /* 68 */
#define XSetWindowBorderPixmap \
	(tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 69 */
#define XSetWindowBorderWidth \
	(tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 70 */
#define XSetWindowColormap \
	(tkIntXlibStubsPtr->xSetWindowColormap) /* 71 */
#define XTranslateCoordinates \
	(tkIntXlibStubsPtr->xTranslateCoordinates) /* 72 */
#define XUngrabKeyboard \
	(tkIntXlibStubsPtr->xUngrabKeyboard) /* 73 */
#define XUngrabPointer \
	(tkIntXlibStubsPtr->xUngrabPointer) /* 74 */
#define XUnmapWindow \
	(tkIntXlibStubsPtr->xUnmapWindow) /* 75 */
#define XWindowEvent \
	(tkIntXlibStubsPtr->xWindowEvent) /* 76 */
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */
#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 81 */
#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */
#define XInternAtom \
	(tkIntXlibStubsPtr->xInternAtom) /* 85 */
#define XSetBackground \
	(tkIntXlibStubsPtr->xSetBackground) /* 86 */
#define XSetForeground \
	(tkIntXlibStubsPtr->xSetForeground) /* 87 */
#define XSetClipMask \
	(tkIntXlibStubsPtr->xSetClipMask) /* 88 */
#define XSetClipOrigin \
	(tkIntXlibStubsPtr->xSetClipOrigin) /* 89 */
#define XSetTSOrigin \
	(tkIntXlibStubsPtr->xSetTSOrigin) /* 90 */
#define XChangeGC \
	(tkIntXlibStubsPtr->xChangeGC) /* 91 */
#define XSetFont \
	(tkIntXlibStubsPtr->xSetFont) /* 92 */
#define XSetArcMode \
	(tkIntXlibStubsPtr->xSetArcMode) /* 93 */
#define XSetStipple \
	(tkIntXlibStubsPtr->xSetStipple) /* 94 */
#define XSetFillRule \
	(tkIntXlibStubsPtr->xSetFillRule) /* 95 */
#define XSetFillStyle \
	(tkIntXlibStubsPtr->xSetFillStyle) /* 96 */
#define XSetFunction \
	(tkIntXlibStubsPtr->xSetFunction) /* 97 */
#define XSetLineAttributes \
	(tkIntXlibStubsPtr->xSetLineAttributes) /* 98 */
#define _XInitImageFuncPtrs \
	(tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 99 */
#define XCreateIC \
	(tkIntXlibStubsPtr->xCreateIC) /* 100 */
#define XGetVisualInfo \
	(tkIntXlibStubsPtr->xGetVisualInfo) /* 101 */
#define XSetWMClientMachine \
	(tkIntXlibStubsPtr->xSetWMClientMachine) /* 102 */
#define XStringListToTextProperty \
	(tkIntXlibStubsPtr->xStringListToTextProperty) /* 103 */




#define XDrawLine \
	(tkIntXlibStubsPtr->xDrawLine) /* 104 */








#define XWarpPointer \
	(tkIntXlibStubsPtr->xWarpPointer) /* 105 */






#define XFillRectangle \
	(tkIntXlibStubsPtr->xFillRectangle) /* 106 */






























#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */
#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */
#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */
#define XFree \
	(tkIntXlibStubsPtr->xFree) /* 110 */
#define XNoOp \
	(tkIntXlibStubsPtr->xNoOp) /* 111 */
#define XSynchronize \
	(tkIntXlibStubsPtr->xSynchronize) /* 112 */
#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 113 */
#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
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
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */
#define XFillArcs \
	(tkIntXlibStubsPtr->xFillArcs) /* 130 */
#define XDrawArcs \
	(tkIntXlibStubsPtr->xDrawArcs) /* 131 */
#define XDrawRectangles \
	(tkIntXlibStubsPtr->xDrawRectangles) /* 132 */

/* Slot 133 is reserved */

/* Slot 134 is reserved */

/* Slot 135 is reserved */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 144 */
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 145 */
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 146 */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \







>
|
>
|
>
|
















<
|
<
|
<
|







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
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */
#define XFillArcs \
	(tkIntXlibStubsPtr->xFillArcs) /* 130 */
#define XDrawArcs \
	(tkIntXlibStubsPtr->xDrawArcs) /* 131 */
#define XDrawRectangles \
	(tkIntXlibStubsPtr->xDrawRectangles) /* 132 */
#define XDrawSegments \
	(tkIntXlibStubsPtr->xDrawSegments) /* 133 */
#define XDrawPoint \
	(tkIntXlibStubsPtr->xDrawPoint) /* 134 */
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 135 */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */

/* Slot 144 is reserved */

/* Slot 145 is reserved */

/* Slot 146 is reserved */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \

Changes to generic/tkListbox.c.

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.
 *
 * 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"







|
|







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 © 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"
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    Tk_OptionTable optionTable;	/* Table that defines configuration options
				 * available for this widget. */
    Tk_OptionTable itemAttrOptionTable;
				/* Table that defines configuration options
				 * available for listbox items. */
    char *listVarName;		/* List variable name */
    Tcl_Obj *listObj;		/* Pointer to the list object being used */
    int nElements;		/* Holds the current count of elements */
    Tcl_HashTable *selection;	/* Tracks selection */
    Tcl_HashTable *itemAttrTable;
				/* Tracks item attributes */

    /*
     * Information used when displaying widget:
     */







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    Tk_OptionTable optionTable;	/* Table that defines configuration options
				 * available for this widget. */
    Tk_OptionTable itemAttrOptionTable;
				/* Table that defines configuration options
				 * available for listbox items. */
    char *listVarName;		/* List variable name */
    Tcl_Obj *listObj;		/* Pointer to the list object being used */
    Tcl_Size nElements;		/* Holds the current count of elements */
    Tcl_HashTable *selection;	/* Tracks selection */
    Tcl_HashTable *itemAttrTable;
				/* Tracks item attributes */

    /*
     * Information used when displaying widget:
     */
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
 * below.
 */

enum state {
    STATE_DISABLED, STATE_NORMAL
};

static const char *const stateStrings[] = {
    "disabled", "normal", NULL
};

enum activeStyle {
    ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
};

static const char *const activeStyleStrings[] = {
    "dotbox", "none", "underline", NULL
};







<
<
<
<







216
217
218
219
220
221
222




223
224
225
226
227
228
229
 * below.
 */

enum state {
    STATE_DISABLED, STATE_NORMAL
};





enum activeStyle {
    ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
};

static const char *const activeStyleStrings[] = {
    "dotbox", "none", "underline", NULL
};
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_LISTBOX_JUSTIFY, TCL_INDEX_NONE, offsetof(Listbox, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, TCL_INDEX_NONE, offsetof(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selBorder),
	 0, DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, TCL_INDEX_NONE,
	 offsetof(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selFgColorPtr),
	 TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
	 DEF_LISTBOX_SELECT_MODE, TCL_INDEX_NONE, offsetof(Listbox, selectMode),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
	 DEF_LISTBOX_SET_GRID, TCL_INDEX_NONE, offsetof(Listbox, setGrid), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_LISTBOX_STATE, TCL_INDEX_NONE, offsetof(Listbox, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Listbox, takeFocus),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	 DEF_LISTBOX_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, xScrollCmd),







|


















|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_LISTBOX_JUSTIFY, TCL_INDEX_NONE, offsetof(Listbox, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, TCL_INDEX_NONE, offsetof(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selBorder),
	 0, DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, TCL_INDEX_NONE,
	 offsetof(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selFgColorPtr),
	 TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
	 DEF_LISTBOX_SELECT_MODE, TCL_INDEX_NONE, offsetof(Listbox, selectMode),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
	 DEF_LISTBOX_SET_GRID, TCL_INDEX_NONE, offsetof(Listbox, setGrid), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_LISTBOX_STATE, TCL_INDEX_NONE, offsetof(Listbox, state),
	0, &tkStateStrings[1], 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Listbox, takeFocus),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	 DEF_LISTBOX_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, xScrollCmd),
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

/*
 * The itemAttrOptionSpecs table defines the valid configuration options for
 * listbox items.
 */

static const Tk_OptionSpec itemAttrOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, border),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, fgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selBorder),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selFgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The following tables define the listbox widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the listbox widget command.
 */







|

|
<




|

|
|

|
<
|

|
<
|







313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332

333
334
335

336
337
338
339
340
341
342
343

/*
 * The itemAttrOptionSpecs table defines the valid configuration options for
 * listbox items.
 */

static const Tk_OptionSpec itemAttrOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, border),
     TK_OPTION_NULL_OK, NULL, 0},

    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, fgColor),
     TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selBorder),
     TK_OPTION_NULL_OK, NULL, 0},

    {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selFgColor),
     TK_OPTION_NULL_OK, NULL, 0},

    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, NULL, 0}
};

/*
 * The following tables define the listbox widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the listbox widget command.
 */
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    "anchor", "clear", "includes", "set", NULL
};
enum selcommand {
    SELECTION_ANCHOR, SELECTION_CLEAR, SELECTION_INCLUDES, SELECTION_SET
};

static const char *const scanCommandNames[] = {
    "mark", "dragto", NULL
};
enum scancommand {
    SCAN_MARK, SCAN_DRAGTO
};

static const char *const indexNames[] = {
    "active", "anchor", NULL
};
enum indices {
    INDEX_ACTIVE, INDEX_ANCHOR
};

/*
 * Declarations for procedures defined later in this file.
 */

static void		ChangeListboxOffset(Listbox *listPtr, int offset);
static void		ChangeListboxView(Listbox *listPtr, int index);
static int		ConfigureListbox(Tcl_Interp *interp, Listbox *listPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		ConfigureListboxItem(Tcl_Interp *interp,
			    Listbox *listPtr, ItemAttr *attrs, int objc,
			    Tcl_Obj *const objv[], int index);
static int		ListboxDeleteSubCmd(Listbox *listPtr,
			    int first, int last);
static void		DestroyListbox(void *memPtr);
static void		DestroyListboxOptionTables(ClientData clientData,
			    Tcl_Interp *interp);
static void		DisplayListbox(ClientData clientData);
static int		GetListboxIndex(Tcl_Interp *interp, Listbox *listPtr,
			    Tcl_Obj *index, int endIsSize, int *indexPtr);
static int		ListboxInsertSubCmd(Listbox *listPtr,
			    int index, int objc, Tcl_Obj *const objv[]);
static void		ListboxCmdDeletedProc(ClientData clientData);
static void		ListboxComputeGeometry(Listbox *listPtr,
			    int fontChanged, int maxIsStale, int updateGrid);
static void		ListboxEventProc(ClientData clientData,
			    XEvent *eventPtr);
static TkSizeT	ListboxFetchSelection(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static void		ListboxLostSelection(ClientData clientData);
static void		GenerateListboxSelectEvent(Listbox *listPtr);
static void		EventuallyRedrawRange(Listbox *listPtr,
			    int first, int last);
static void		ListboxScanTo(Listbox *listPtr, int x, int y);
static int		ListboxSelect(Listbox *listPtr,
			    int first, int last, int select);
static void		ListboxUpdateHScrollbar(Listbox *listPtr);
static void		ListboxUpdateVScrollbar(Listbox *listPtr);
static int		ListboxWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		ListboxBboxSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, int index);
static int		ListboxSelectionSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, int objc, Tcl_Obj *const objv[]);
static int		ListboxXviewSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, int objc, Tcl_Obj *const objv[]);
static int		ListboxYviewSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, int objc, Tcl_Obj *const objv[]);
static ItemAttr *	ListboxGetItemAttributes(Tcl_Interp *interp,
			    Listbox *listPtr, int index);
static void		ListboxWorldChanged(ClientData instanceData);
static int		NearestListboxElement(Listbox *listPtr, int y);
static char *		ListboxListVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		MigrateHashEntries(Tcl_HashTable *table,
			    int first, int last, int offset);
static int		GetMaxOffset(Listbox *listPtr);

/*
 * The structure below defines button class behavior by means of procedures
 * that can be invoked from generic window code.
 */








|


|
















|

|
|


|
|

|

|

|
|


|

|
|
|


|





|
<
<



|

|

|


|

|



|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416


417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    "anchor", "clear", "includes", "set", NULL
};
enum selcommand {
    SELECTION_ANCHOR, SELECTION_CLEAR, SELECTION_INCLUDES, SELECTION_SET
};

static const char *const scanCommandNames[] = {
    "dragto", "mark", NULL
};
enum scancommand {
    SCAN_DRAGTO, SCAN_MARK
};

static const char *const indexNames[] = {
    "active", "anchor", NULL
};
enum indices {
    INDEX_ACTIVE, INDEX_ANCHOR
};

/*
 * Declarations for procedures defined later in this file.
 */

static void		ChangeListboxOffset(Listbox *listPtr, int offset);
static void		ChangeListboxView(Listbox *listPtr, int index);
static int		ConfigureListbox(Tcl_Interp *interp, Listbox *listPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		ConfigureListboxItem(Tcl_Interp *interp,
			    Listbox *listPtr, ItemAttr *attrs, Tcl_Size objc,
			    Tcl_Obj *const objv[], Tcl_Size index);
static int		ListboxDeleteSubCmd(Listbox *listPtr,
			    int first, int last);
static Tcl_FreeProc	DestroyListbox;
static void		DestroyListboxOptionTables(void *clientData,
			    Tcl_Interp *interp);
static void		DisplayListbox(void *clientData);
static int		GetListboxIndex(Tcl_Interp *interp, Listbox *listPtr,
			    Tcl_Obj *index, int endIsSize, Tcl_Size *indexPtr);
static int		ListboxInsertSubCmd(Listbox *listPtr,
			    Tcl_Size index, Tcl_Size objc, Tcl_Obj *const objv[]);
static void		ListboxCmdDeletedProc(void *clientData);
static void		ListboxComputeGeometry(Listbox *listPtr,
			    int fontChanged, int maxIsStale, int updateGrid);
static void		ListboxEventProc(void *clientData,
			    XEvent *eventPtr);
static Tcl_Size	ListboxFetchSelection(void *clientData,
			    Tcl_Size offset, char *buffer, Tcl_Size maxBytes);
static void		ListboxLostSelection(void *clientData);
static void		GenerateListboxSelectEvent(Listbox *listPtr);
static void		EventuallyRedrawRange(Listbox *listPtr,
			    Tcl_Size first, Tcl_Size last);
static void		ListboxScanTo(Listbox *listPtr, int x, int y);
static int		ListboxSelect(Listbox *listPtr,
			    int first, int last, int select);
static void		ListboxUpdateHScrollbar(Listbox *listPtr);
static void		ListboxUpdateVScrollbar(Listbox *listPtr);
static Tcl_ObjCmdProc ListboxWidgetObjCmd;


static int		ListboxBboxSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, int index);
static int		ListboxSelectionSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static int		ListboxXviewSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static int		ListboxYviewSubCmd(Tcl_Interp *interp,
			    Listbox *listPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static ItemAttr *	ListboxGetItemAttributes(Tcl_Interp *interp,
			    Listbox *listPtr, int index);
static void		ListboxWorldChanged(void *instanceData);
static int		NearestListboxElement(Listbox *listPtr, int y);
static char *		ListboxListVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		MigrateHashEntries(Tcl_HashTable *table,
			    Tcl_Size first, Tcl_Size last, Tcl_Size offset);
static int		GetMaxOffset(Listbox *listPtr);

/*
 * The structure below defines button class behavior by means of procedures
 * that can be invoked from generic window code.
 */

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ListboxObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Listbox *listPtr;
    Tk_Window tkwin;
    ListboxOptionTables *optionTables;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    optionTables = (ListboxOptionTables *)Tcl_GetAssocData(interp, "ListboxOptionTables", NULL);
    if (optionTables == NULL) {
	/*
	 * We haven't created the option tables for this widget class yet. Do
	 * it now and save the a pointer to them as the ClientData for the
	 * command, so future invocations will have access to it.
	 */

	optionTables = (ListboxOptionTables *)ckalloc(sizeof(ListboxOptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.







|







<
















|







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ListboxObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Listbox *listPtr;
    Tk_Window tkwin;
    ListboxOptionTables *optionTables;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    optionTables = (ListboxOptionTables *)Tcl_GetAssocData(interp, "ListboxOptionTables", NULL);
    if (optionTables == NULL) {
	/*
	 * We haven't created the option tables for this widget class yet. Do
	 * it now and save the a pointer to them as the void *for the
	 * command, so future invocations will have access to it.
	 */

	optionTables = (ListboxOptionTables *)ckalloc(sizeof(ListboxOptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
599
600
601
602
603
604
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ListboxWidgetObjCmd(
    ClientData clientData,	/* Information about listbox widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Arguments as Tcl_Obj's. */
{
    Listbox *listPtr = (Listbox *)clientData;
    int cmdIndex, index;

    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }







|





|
>







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ListboxWidgetObjCmd(
    void *clientData,	/* Information about listbox widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Arguments as Tcl_Obj's. */
{
    Listbox *listPtr = (Listbox *)clientData;
    int cmdIndex;
    Tcl_Size index;
    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	 * search functions (Tcl_FirstHashEntry, Tcl_NextHashEntry), but then
	 * the result wouldn't be in sorted order. So instead we loop through
	 * the indices in order, adding them to the result if they are
	 * selected.
	 */

	objPtr = Tcl_NewObj();
	for (i = 0; i < listPtr->nElements; i++) {
	    if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewWideIntObj(i));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;
    }

    case COMMAND_DELETE: {
	int first, last;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
	if (result != TCL_OK) {
	    break;
	}

	if (!(listPtr->state & STATE_NORMAL)) {
	    break;
	}

	if (first < listPtr->nElements) {
	    /*
	     * if a "last index" was given, get it now; otherwise, use the
	     * first index as the last index.
	     */

	    if (objc == 4) {
		result = GetListboxIndex(interp, listPtr, objv[3], 0, &last);
		if (result != TCL_OK) {
		    break;
		}
	    } else {
		last = first;
	    }
	    if (last >= listPtr->nElements) {
		last = listPtr->nElements - 1;
	    }
	    result = ListboxDeleteSubCmd(listPtr, first, last);
	} else {
	    result = TCL_OK;
	}
	break;
    }

    case COMMAND_GET: {
	int first, last, listLen;
	Tcl_Obj **elemPtrs;

	if (objc != 3 && objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
	if (result != TCL_OK) {
	    break;
	}
	last = first;
	if (objc == 4) {
	    result = GetListboxIndex(interp, listPtr, objv[3], 0, &last);
	    if (result != TCL_OK) {
		break;
	    }
	}
	if (first >= listPtr->nElements) {
	    result = TCL_OK;
	    break;
	}
	if (last >= listPtr->nElements) {
	    last = listPtr->nElements - 1;
	}
	if (first < 0) {
	    first = 0;
	}
	if (first > last) {
	    result = TCL_OK;







|










|
















|













|










|


















|



|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
	 * search functions (Tcl_FirstHashEntry, Tcl_NextHashEntry), but then
	 * the result wouldn't be in sorted order. So instead we loop through
	 * the indices in order, adding them to the result if they are
	 * selected.
	 */

	objPtr = Tcl_NewObj();
	for (i = 0; i < (int)listPtr->nElements; i++) {
	    if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewWideIntObj(i));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;
    }

    case COMMAND_DELETE: {
	Tcl_Size first, last;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
	if (result != TCL_OK) {
	    break;
	}

	if (!(listPtr->state & STATE_NORMAL)) {
	    break;
	}

	if (first < (int)listPtr->nElements) {
	    /*
	     * if a "last index" was given, get it now; otherwise, use the
	     * first index as the last index.
	     */

	    if (objc == 4) {
		result = GetListboxIndex(interp, listPtr, objv[3], 0, &last);
		if (result != TCL_OK) {
		    break;
		}
	    } else {
		last = first;
	    }
	    if (last >= (int)listPtr->nElements) {
		last = listPtr->nElements - 1;
	    }
	    result = ListboxDeleteSubCmd(listPtr, first, last);
	} else {
	    result = TCL_OK;
	}
	break;
    }

    case COMMAND_GET: {
	Tcl_Size listLen, first, last;
	Tcl_Obj **elemPtrs;

	if (objc != 3 && objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
	if (result != TCL_OK) {
	    break;
	}
	last = first;
	if (objc == 4) {
	    result = GetListboxIndex(interp, listPtr, objv[3], 0, &last);
	    if (result != TCL_OK) {
		break;
	    }
	}
	if (first >= (int)listPtr->nElements) {
	    result = TCL_OK;
	    break;
	}
	if (last >= (int)listPtr->nElements) {
	    last = listPtr->nElements - 1;
	}
	if (first < 0) {
	    first = 0;
	}
	if (first > last) {
	    result = TCL_OK;
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}







|







866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= (int)listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}







|







903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= (int)listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}
	if (index >= listPtr->nElements) {
	    index = listPtr->nElements - 1;
	}
	if (index < 0) {
	    index = 0;
	}
	diff = listPtr->topIndex - index;
	if (diff > 0) {







|







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}
	if (index >= (int)listPtr->nElements) {
	    index = listPtr->nElements - 1;
	}
	if (index < 0) {
	    index = 0;
	}
	diff = listPtr->topIndex - index;
	if (diff > 0) {
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

    /*
     * Determine the index of the last visible item in the listbox.
     */

    lastVisibleIndex = listPtr->topIndex + listPtr->fullLines
	    + listPtr->partialLine;
    if (listPtr->nElements < lastVisibleIndex) {
	lastVisibleIndex = listPtr->nElements;
    }

    /*
     * Only allow bbox requests for indices that are visible.
     */

    if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
	Tcl_Obj *el, *results[4];
	const char *stringRep;
	int pixelWidth, x, y, result;
	TkSizeT stringLen;
	Tk_FontMetrics fm;

	/*
	 * Compute the pixel width of the requested element.
	 */

	result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
	if (result != TCL_OK) {
	    return result;
	}

	stringRep = TkGetStringFromObj(el, &stringLen);
	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)







|











|











|







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

    /*
     * Determine the index of the last visible item in the listbox.
     */

    lastVisibleIndex = listPtr->topIndex + listPtr->fullLines
	    + listPtr->partialLine;
    if ((int)listPtr->nElements < lastVisibleIndex) {
	lastVisibleIndex = listPtr->nElements;
    }

    /*
     * Only allow bbox requests for indices that are visible.
     */

    if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
	Tcl_Obj *el, *results[4];
	const char *stringRep;
	int pixelWidth, x, y, result;
	Tcl_Size stringLen;
	Tk_FontMetrics fm;

	/*
	 * Compute the pixel width of the requested element.
	 */

	result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
	if (result != TCL_OK) {
	    return result;
	}

	stringRep = 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)
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
 *----------------------------------------------------------------------
 */

static int
ListboxSelectionSubCmd(
    Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
    Listbox *listPtr,		/* Information about the listbox */
    int objc,			/* Number of arguments in the objv array */
    Tcl_Obj *const objv[])	/* Array of arguments to the procedure */
{
    int selCmdIndex, first, last;

    int result = TCL_OK;

    if (objc != 4 && objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "option index ?index?");
	return TCL_ERROR;
    }
    result = GetListboxIndex(interp, listPtr, objv[3], 0, &first);







|


|
>







1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
 *----------------------------------------------------------------------
 */

static int
ListboxSelectionSubCmd(
    Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
    Listbox *listPtr,		/* Information about the listbox */
    Tcl_Size objc,			/* Number of arguments in the objv array */
    Tcl_Obj *const objv[])	/* Array of arguments to the procedure */
{
    int selCmdIndex;
    Tcl_Size first, last;
    int result = TCL_OK;

    if (objc != 4 && objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "option index ?index?");
	return TCL_ERROR;
    }
    result = GetListboxIndex(interp, listPtr, objv[3], 0, &first);
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213

    switch (selCmdIndex) {
    case SELECTION_ANCHOR:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}
	if (first >= listPtr->nElements) {
	    first = listPtr->nElements - 1;
	}
	if (first < 0) {
	    first = 0;
	}
	listPtr->selectAnchor = first;
	result = TCL_OK;







|







1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205

    switch (selCmdIndex) {
    case SELECTION_ANCHOR:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}
	if (first >= (int)listPtr->nElements) {
	    first = listPtr->nElements - 1;
	}
	if (first < 0) {
	    first = 0;
	}
	listPtr->selectAnchor = first;
	result = TCL_OK;
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
 *----------------------------------------------------------------------
 */

static int
ListboxXviewSubCmd(
    Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
    Listbox *listPtr,		/* Information about the listbox */
    int objc,			/* Number of arguments in the objv array */
    Tcl_Obj *const objv[])	/* Array of arguments to the procedure */
{
    int index, count, windowWidth, windowUnits;
    int offset = 0;		/* Initialized to stop gcc warnings. */
    double fraction;

    windowWidth = Tk_Width(listPtr->tkwin)







|







1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
 *----------------------------------------------------------------------
 */

static int
ListboxXviewSubCmd(
    Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
    Listbox *listPtr,		/* Information about the listbox */
    Tcl_Size objc,			/* Number of arguments in the objv array */
    Tcl_Obj *const objv[])	/* Array of arguments to the procedure */
{
    int index, count, windowWidth, windowUnits;
    int offset = 0;		/* Initialized to stop gcc warnings. */
    double fraction;

    windowWidth = Tk_Width(listPtr->tkwin)
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
    } else if (objc == 3) {
	if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
	case TK_SCROLL_ERROR:
	    return TCL_ERROR;
	case TK_SCROLL_MOVETO:
	    offset = (int) (fraction*listPtr->maxWidth + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    windowUnits = windowWidth / listPtr->xScrollUnit;
	    if (windowUnits > 2) {
		offset = listPtr->xOffset
			+ count*listPtr->xScrollUnit*(windowUnits-2);
	    } else {
		offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    break;


	}
	ChangeListboxOffset(listPtr, offset);
    }
    return TCL_OK;
}

/*







<
<















>
>







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
    } else if (objc == 3) {
	if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {


	case TK_SCROLL_MOVETO:
	    offset = (int) (fraction*listPtr->maxWidth + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    windowUnits = windowWidth / listPtr->xScrollUnit;
	    if (windowUnits > 2) {
		offset = listPtr->xOffset
			+ count*listPtr->xScrollUnit*(windowUnits-2);
	    } else {
		offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    break;
	default:
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, offset);
    }
    return TCL_OK;
}

/*
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339
1340
1341
1342
 *----------------------------------------------------------------------
 */

static int
ListboxYviewSubCmd(
    Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
    Listbox *listPtr,		/* Information about the listbox */
    int objc,			/* Number of arguments in the objv array */
    Tcl_Obj *const objv[])	/* Array of arguments to the procedure */
{

    int index, count;
    double fraction;

    if (objc == 2) {
	Tcl_Obj *results[2];

	if (listPtr->nElements == 0) {
	    results[0] = Tcl_NewDoubleObj(0.0);







|


>
|







1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
 *----------------------------------------------------------------------
 */

static int
ListboxYviewSubCmd(
    Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
    Listbox *listPtr,		/* Information about the listbox */
    Tcl_Size objc,			/* Number of arguments in the objv array */
    Tcl_Obj *const objv[])	/* Array of arguments to the procedure */
{
    Tcl_Size index;
    int count;
    double fraction;

    if (objc == 2) {
	Tcl_Obj *results[2];

	if (listPtr->nElements == 0) {
	    results[0] = Tcl_NewDoubleObj(0.0);
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
	if (GetListboxIndex(interp, listPtr, objv[2], 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
	case TK_SCROLL_MOVETO:
	    index = (int) (listPtr->nElements*fraction + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    if (listPtr->fullLines > 2) {
		index = listPtr->topIndex + count*(listPtr->fullLines-2);
	    } else {
		index = listPtr->topIndex + count;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    index = listPtr->topIndex + count;
	    break;
	case TK_SCROLL_ERROR:
	default:
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    }
    return TCL_OK;
}







|











<







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
	if (GetListboxIndex(interp, listPtr, objv[2], 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
	case TK_SCROLL_MOVETO:
	    index = (Tcl_Size)(listPtr->nElements*fraction + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    if (listPtr->fullLines > 2) {
		index = listPtr->topIndex + count*(listPtr->fullLines-2);
	    } else {
		index = listPtr->topIndex + count;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    index = listPtr->topIndex + count;
	    break;

	default:
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    }
    return TCL_OK;
}
1442
1443
1444
1445
1446
1447
1448

1449



1450
1451
1452
1453
1454
1455
1456
 *	Everything associated with the listbox is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListbox(

    void *memPtr)		/* Info about listbox widget. */



{
    Listbox *listPtr = (Listbox *)memPtr;
    Tcl_HashEntry *entry;
    Tcl_HashSearch search;

    /*
     * If we have an internal list object, free it.







>

>
>
>







1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
 *	Everything associated with the listbox is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListbox(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Info about listbox widget. */
#else
    char *memPtr)
#endif
{
    Listbox *listPtr = (Listbox *)memPtr;
    Tcl_HashEntry *entry;
    Tcl_HashSearch search;

    /*
     * If we have an internal list object, free it.
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
    if (listPtr->selTextGC != NULL) {
	Tk_FreeGC(listPtr->display, listPtr->selTextGC);
    }
    if (listPtr->gray != None) {
	Tk_FreeBitmap(Tk_Display(listPtr->tkwin), listPtr->gray);
    }

    Tk_FreeConfigOptions((char *) listPtr, listPtr->optionTable,
	    listPtr->tkwin);
    Tcl_Release(listPtr->tkwin);
    listPtr->tkwin = NULL;
    ckfree(listPtr);
}

/*







|







1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
    if (listPtr->selTextGC != NULL) {
	Tk_FreeGC(listPtr->display, listPtr->selTextGC);
    }
    if (listPtr->gray != None) {
	Tk_FreeBitmap(Tk_Display(listPtr->tkwin), listPtr->gray);
    }

    Tk_FreeConfigOptions(listPtr, listPtr->optionTable,
	    listPtr->tkwin);
    Tcl_Release(listPtr->tkwin);
    listPtr->tkwin = NULL;
    ckfree(listPtr);
}

/*
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
 *	Frees memory.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *dummy)		/* Pointer to the calling interp */
{
    (void)dummy;

    ckfree(clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *







|
|

<
<







1519
1520
1521
1522
1523
1524
1525
1526
1527
1528


1529
1530
1531
1532
1533
1534
1535
 *	Frees memory.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    void *clientData,	/* Pointer to the OptionTables struct */
    TCL_UNUSED(Tcl_Interp *))		/* Pointer to the calling interp */
{


    ckfree(clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
 */

static int
ConfigureListbox(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Listbox *listPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *oldListObj = NULL;
    Tcl_Obj *errorResult = NULL;
    int oldExport, error;








|







1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
 */

static int
ConfigureListbox(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Listbox *listPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *oldListObj = NULL;
    Tcl_Obj *errorResult = NULL;
    int oldExport, error;

1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
	 * no listvar     | no listvar | no special action
	 */

	oldListObj = listPtr->listObj;
	if (listPtr->listVarName != NULL) {
	    Tcl_Obj *listVarObj = Tcl_GetVar2Ex(interp, listPtr->listVarName,
		    NULL, TCL_GLOBAL_ONLY);
	    int dummy;

	    if (listVarObj == NULL) {
		listVarObj = (oldListObj ? oldListObj : Tcl_NewObj());
		if (Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
			listVarObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
			== NULL) {
		    continue;







|







1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
	 * no listvar     | no listvar | no special action
	 */

	oldListObj = listPtr->listObj;
	if (listPtr->listVarName != NULL) {
	    Tcl_Obj *listVarObj = Tcl_GetVar2Ex(interp, listPtr->listVarName,
		    NULL, TCL_GLOBAL_ONLY);
	    Tcl_Size dummy;

	    if (listVarObj == NULL) {
		listVarObj = (oldListObj ? oldListObj : Tcl_NewObj());
		if (Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
			listVarObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
			== NULL) {
		    continue;
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734

static int
ConfigureListboxItem(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Listbox *listPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    ItemAttr *attrs,		/* Information about the item to configure */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    int index)			/* Index of the listbox item being configure */
{
    Tk_SavedOptions savedOptions;

    if (Tk_SetOptions(interp, attrs,
	    listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
	    &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);







|

|







1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728

static int
ConfigureListboxItem(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Listbox *listPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    ItemAttr *attrs,		/* Information about the item to configure */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    Tcl_Size index)			/* Index of the listbox item being configure */
{
    Tk_SavedOptions savedOptions;

    if (Tk_SetOptions(interp, attrs,
	    listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
	    &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
 *	Listbox will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
ListboxWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    Listbox *listPtr = (Listbox *)instanceData;

    if (listPtr->state & STATE_NORMAL) {







|







1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
 *	Listbox will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
ListboxWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    Listbox *listPtr = (Listbox *)instanceData;

    if (listPtr->state & STATE_NORMAL) {
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayListbox(
    ClientData clientData)	/* Information about window. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tk_Window tkwin = listPtr->tkwin;
    GC gc;
    int i, limit, x, y, prevSelected, freeGC;
    TkSizeT stringLen;
    Tk_FontMetrics fm;
    Tcl_Obj *curElement;
    Tcl_HashEntry *entry;
    const char *stringRep;
    ItemAttr *attrs;
    Tk_3DBorder selectedBg;
    XGCValues gcValues;







|





|







1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayListbox(
    void *clientData)	/* Information about window. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tk_Window tkwin = listPtr->tkwin;
    GC gc;
    int i, limit, x, y, prevSelected, freeGC;
    Tcl_Size stringLen;
    Tk_FontMetrics fm;
    Tcl_Obj *curElement;
    Tcl_HashEntry *entry;
    const char *stringRep;
    ItemAttr *attrs;
    Tk_3DBorder selectedBg;
    XGCValues gcValues;
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    /*
     * Display each item in the listbox.
     */

    limit = listPtr->topIndex + listPtr->fullLines + listPtr->partialLine - 1;
    if (limit >= listPtr->nElements) {
	limit = listPtr->nElements-1;
    }
    left = right = 0;
    if (listPtr->xOffset > 0) {
	left = listPtr->selBorderWidth+1;
    }
    if ((listPtr->maxWidth - listPtr->xOffset) > (Tk_Width(listPtr->tkwin)







|







1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    /*
     * Display each item in the listbox.
     */

    limit = listPtr->topIndex + listPtr->fullLines + listPtr->partialLine - 1;
    if (limit >= (int)listPtr->nElements) {
	limit = listPtr->nElements-1;
    }
    left = right = 0;
    if (listPtr->xOffset > 0) {
	left = listPtr->selBorderWidth+1;
    }
    if ((listPtr->maxWidth - listPtr->xOffset) > (Tk_Width(listPtr->tkwin)
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
		if (!prevSelected) {
		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg,
			    x-left, y, width+left+right,
			    listPtr->selBorderWidth,
			    1, 1, 1, TK_RELIEF_RAISED);
		}
		/* Draw bottom bevel */
		if (i + 1 == listPtr->nElements ||
			!Tcl_FindHashEntry(listPtr->selection, KEY(i + 1))) {
		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left,
			    y + listPtr->lineHeight - listPtr->selBorderWidth,
			    width+left+right, listPtr->selBorderWidth, 0, 0, 0,
			    TK_RELIEF_RAISED);
		}
		prevSelected = 1;







|







2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
		if (!prevSelected) {
		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg,
			    x-left, y, width+left+right,
			    listPtr->selBorderWidth,
			    1, 1, 1, TK_RELIEF_RAISED);
		}
		/* Draw bottom bevel */
		if (i + 1 == (int)listPtr->nElements ||
			!Tcl_FindHashEntry(listPtr->selection, KEY(i + 1))) {
		    Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left,
			    y + listPtr->lineHeight - listPtr->selBorderWidth,
			    width+left+right, listPtr->selBorderWidth, 0, 0, 0,
			    TK_RELIEF_RAISED);
		}
		prevSelected = 1;
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);
        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;







|







2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
	}

	/*
	 * Draw the actual text of this item.
	 */

        Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
        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;
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
	    listPtr->borderWidth, listPtr->relief);
    if (listPtr->highlightWidth > 0) {
	GC fgGC, bgGC;

	bgGC = Tk_GCForColor(listPtr->highlightBgColorPtr, pixmap);
	if (listPtr->flags & GOT_FOCUS) {
	    fgGC = Tk_GCForColor(listPtr->highlightColorPtr, pixmap);
	    TkpDrawHighlightBorder(tkwin, fgGC, bgGC,
		    listPtr->highlightWidth, pixmap);
	} else {
	    TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
		    listPtr->highlightWidth, pixmap);
	}
    }
#ifndef TK_NO_DOUBLE_BUFFERING
    XCopyArea(listPtr->display, pixmap, Tk_WindowId(tkwin),
	    listPtr->textGC, 0, 0, (unsigned) Tk_Width(tkwin),
	    (unsigned) Tk_Height(tkwin), 0, 0);







|


|







2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
	    listPtr->borderWidth, listPtr->relief);
    if (listPtr->highlightWidth > 0) {
	GC fgGC, bgGC;

	bgGC = Tk_GCForColor(listPtr->highlightBgColorPtr, pixmap);
	if (listPtr->flags & GOT_FOCUS) {
	    fgGC = Tk_GCForColor(listPtr->highlightColorPtr, pixmap);
	    Tk_DrawHighlightBorder(tkwin, fgGC, bgGC,
		    listPtr->highlightWidth, pixmap);
	} else {
	    Tk_DrawHighlightBorder(tkwin, bgGC, bgGC,
		    listPtr->highlightWidth, pixmap);
	}
    }
#ifndef TK_NO_DOUBLE_BUFFERING
    XCopyArea(listPtr->display, pixmap, Tk_WindowId(tkwin),
	    listPtr->textGC, 0, 0, (unsigned) Tk_Width(tkwin),
	    (unsigned) Tk_Height(tkwin), 0, 0);
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
				 * recomputed. If fontChanged is 1 then this
				 * must be 1. */
    int updateGrid)		/* Non-zero means call Tk_SetGrid or
				 * Tk_UnsetGrid to update gridding for the
				 * window. */
{
    int width, height, pixelWidth, pixelHeight, i, result;
    TkSizeT textLength;
    Tk_FontMetrics fm;
    Tcl_Obj *element;
    const char *text;

    if (fontChanged || maxIsStale) {
	listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1);
	if (listPtr->xScrollUnit == 0) {
	    listPtr->xScrollUnit = 1;
	}
	listPtr->maxWidth = 0;
	for (i = 0; i < listPtr->nElements; i++) {
	    /*
	     * Compute the pixel width of the current element.
	     */

	    result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &element);
	    if (result != TCL_OK) {
		continue;
	    }
	    text = TkGetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }







|










|









|







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
				 * recomputed. If fontChanged is 1 then this
				 * must be 1. */
    int updateGrid)		/* Non-zero means call Tk_SetGrid or
				 * Tk_UnsetGrid to update gridding for the
				 * window. */
{
    int width, height, pixelWidth, pixelHeight, i, result;
    Tcl_Size textLength;
    Tk_FontMetrics fm;
    Tcl_Obj *element;
    const char *text;

    if (fontChanged || maxIsStale) {
	listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1);
	if (listPtr->xScrollUnit == 0) {
	    listPtr->xScrollUnit = 1;
	}
	listPtr->maxWidth = 0;
	for (i = 0; i < (int)listPtr->nElements; i++) {
	    /*
	     * Compute the pixel width of the current element.
	     */

	    result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &element);
	    if (result != TCL_OK) {
		continue;
	    }
	    text = Tcl_GetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
	    width = 1;
	}
    }
    pixelWidth = width*listPtr->xScrollUnit + 2*listPtr->inset
	    + 2*listPtr->selBorderWidth;
    height = listPtr->height;
    if (listPtr->height <= 0) {
	height = listPtr->nElements;
	if (height < 1) {
	    height = 1;
	}
    }
    pixelHeight = height*listPtr->lineHeight + 2*listPtr->inset;
    Tk_GeometryRequest(listPtr->tkwin, pixelWidth, pixelHeight);
    Tk_SetInternalBorder(listPtr->tkwin, listPtr->inset);







|







2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
	    width = 1;
	}
    }
    pixelWidth = width*listPtr->xScrollUnit + 2*listPtr->inset
	    + 2*listPtr->selBorderWidth;
    height = listPtr->height;
    if (listPtr->height <= 0) {
	height = (int)listPtr->nElements;
	if (height < 1) {
	    height = 1;
	}
    }
    pixelHeight = height*listPtr->lineHeight + 2*listPtr->inset;
    Tk_GeometryRequest(listPtr->tkwin, pixelWidth, pixelHeight);
    Tk_SetInternalBorder(listPtr->tkwin, listPtr->inset);
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
 *
 *----------------------------------------------------------------------
 */

static int
ListboxInsertSubCmd(
    Listbox *listPtr,	/* Listbox that is to get the new elements. */
    int index,			/* Add the new elements before this
				 * element. */
    int objc,			/* Number of new elements to add. */
    Tcl_Obj *const objv[])	/* New elements (one per entry). */
{
    int i, oldMaxWidth, pixelWidth, result;
    TkSizeT length;
    Tcl_Obj *newListObj;
    const char *stringRep;

    oldMaxWidth = listPtr->maxWidth;
    for (i = 0; i < objc; i++) {
	/*
	 * Check if any of the new elements are wider than the current widest;
	 * if so, update our notion of "widest."
	 */

	stringRep = TkGetStringFromObj(objv[i], &length);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	if (pixelWidth > listPtr->maxWidth) {
	    listPtr->maxWidth = pixelWidth;
	}
    }

    /*







|

|


|
|










|







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
 *
 *----------------------------------------------------------------------
 */

static int
ListboxInsertSubCmd(
    Listbox *listPtr,	/* Listbox that is to get the new elements. */
    Tcl_Size index,		/* Add the new elements before this
				 * element. */
    Tcl_Size objc,			/* Number of new elements to add. */
    Tcl_Obj *const objv[])	/* New elements (one per entry). */
{
    int oldMaxWidth, pixelWidth, result;
    Tcl_Size i, length;
    Tcl_Obj *newListObj;
    const char *stringRep;

    oldMaxWidth = listPtr->maxWidth;
    for (i = 0; i < objc; i++) {
	/*
	 * Check if any of the new elements are wider than the current widest;
	 * if so, update our notion of "widest."
	 */

	stringRep = Tcl_GetStringFromObj(objv[i], &length);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	if (pixelWidth > listPtr->maxWidth) {
	    listPtr->maxWidth = pixelWidth;
	}
    }

    /*
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
	listPtr->selectAnchor += objc;
    }
    if (index < listPtr->topIndex) {
	listPtr->topIndex += objc;
    }
    if (index <= listPtr->active) {
	listPtr->active += objc;
	if ((listPtr->active >= listPtr->nElements) &&
		(listPtr->nElements > 0)) {
	    listPtr->active = listPtr->nElements-1;
	}
    }
    listPtr->flags |= UPDATE_V_SCROLLBAR;
    if (listPtr->maxWidth != oldMaxWidth) {
	listPtr->flags |= UPDATE_H_SCROLLBAR;
    }







|
|







2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
	listPtr->selectAnchor += objc;
    }
    if (index < listPtr->topIndex) {
	listPtr->topIndex += objc;
    }
    if (index <= listPtr->active) {
	listPtr->active += objc;
	if ((listPtr->active >= (int)listPtr->nElements) &&
		((int)listPtr->nElements > 0)) {
	    listPtr->active = listPtr->nElements-1;
	}
    }
    listPtr->flags |= UPDATE_V_SCROLLBAR;
    if (listPtr->maxWidth != oldMaxWidth) {
	listPtr->flags |= UPDATE_H_SCROLLBAR;
    }
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
static int
ListboxDeleteSubCmd(
    Listbox *listPtr,	/* Listbox widget to modify. */
    int first,			/* Index of first element to delete. */
    int last)			/* Index of last element to delete. */
{
    int count, i, widthChanged, result, pixelWidth;
    TkSizeT length;
    Tcl_Obj *newListObj, *element;
    const char *stringRep;
    Tcl_HashEntry *entry;

    /*
     * Adjust the range to fit within the existing elements of the listbox,
     * and make sure there's something to delete.
     */

    if (first < 0) {
	first = 0;
    }
    if (last >= listPtr->nElements) {
	last = listPtr->nElements-1;
    }
    count = last + 1 - first;
    if (count <= 0) {
	return TCL_OK;
    }








|












|







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
static int
ListboxDeleteSubCmd(
    Listbox *listPtr,	/* Listbox widget to modify. */
    int first,			/* Index of first element to delete. */
    int last)			/* Index of last element to delete. */
{
    int count, i, widthChanged, result, pixelWidth;
    Tcl_Size length;
    Tcl_Obj *newListObj, *element;
    const char *stringRep;
    Tcl_HashEntry *entry;

    /*
     * Adjust the range to fit within the existing elements of the listbox,
     * and make sure there's something to delete.
     */

    if (first < 0) {
	first = 0;
    }
    if (last >= (int)listPtr->nElements) {
	last = listPtr->nElements-1;
    }
    count = last + 1 - first;
    if (count <= 0) {
	return TCL_OK;
    }

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);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	    if (pixelWidth == listPtr->maxWidth) {
		widthChanged = 1;
	    }
	}
    }








|







2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
	 * Check width of the element. We only have to check if widthChanged
	 * has not already been set to 1, because we only need one maxWidth
	 * element to disappear for us to have to recompute the width.
	 */

	if (widthChanged == 0) {
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element);
	    stringRep = Tcl_GetStringFromObj(element, &length);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	    if (pixelWidth == listPtr->maxWidth) {
		widthChanged = 1;
	    }
	}
    }

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
    }
    if (first <= listPtr->topIndex) {
	listPtr->topIndex -= count;
	if (listPtr->topIndex < first) {
	    listPtr->topIndex = first;
	}
    }
    if (listPtr->topIndex > (listPtr->nElements - listPtr->fullLines)) {
	listPtr->topIndex = listPtr->nElements - listPtr->fullLines;
	if (listPtr->topIndex < 0) {
	    listPtr->topIndex = 0;
	}
    }
    if (listPtr->active > last) {
	listPtr->active -= count;
    } else if (listPtr->active >= first) {
	listPtr->active = first;
	if ((listPtr->active >= listPtr->nElements) &&
		(listPtr->nElements > 0)) {
	    listPtr->active = listPtr->nElements-1;
	}
    }
    listPtr->flags |= UPDATE_V_SCROLLBAR;
    ListboxComputeGeometry(listPtr, 0, widthChanged, 0);
    if (widthChanged) {
	listPtr->flags |= UPDATE_H_SCROLLBAR;







|









|
|







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
    }
    if (first <= listPtr->topIndex) {
	listPtr->topIndex -= count;
	if (listPtr->topIndex < first) {
	    listPtr->topIndex = first;
	}
    }
    if (listPtr->topIndex > ((int)listPtr->nElements - listPtr->fullLines)) {
	listPtr->topIndex = listPtr->nElements - listPtr->fullLines;
	if (listPtr->topIndex < 0) {
	    listPtr->topIndex = 0;
	}
    }
    if (listPtr->active > last) {
	listPtr->active -= count;
    } else if (listPtr->active >= first) {
	listPtr->active = first;
	if ((listPtr->active >= (int)listPtr->nElements) &&
		((int)listPtr->nElements > 0)) {
	    listPtr->active = listPtr->nElements-1;
	}
    }
    listPtr->flags |= UPDATE_V_SCROLLBAR;
    ListboxComputeGeometry(listPtr, 0, widthChanged, 0);
    if (widthChanged) {
	listPtr->flags |= UPDATE_H_SCROLLBAR;
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
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ListboxEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Listbox *listPtr = (Listbox *)clientData;

    if (eventPtr->type == Expose) {
	EventuallyRedrawRange(listPtr,
		NearestListboxElement(listPtr, eventPtr->xexpose.y),
		NearestListboxElement(listPtr, eventPtr->xexpose.y
		+ eventPtr->xexpose.height));
    } else if (eventPtr->type == DestroyNotify) {
	if (!(listPtr->flags & LISTBOX_DELETED)) {
	    listPtr->flags |= LISTBOX_DELETED;
	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
	    if (listPtr->setGrid) {
		Tk_UnsetGrid(listPtr->tkwin);
	    }
	    if (listPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayListbox, clientData);
	    }
	    Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyListbox);
	}
    } else if (eventPtr->type == ConfigureNotify) {
	int vertSpace;

	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;
	listPtr->fullLines = vertSpace / listPtr->lineHeight;
	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {







|



















|







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
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ListboxEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Listbox *listPtr = (Listbox *)clientData;

    if (eventPtr->type == Expose) {
	EventuallyRedrawRange(listPtr,
		NearestListboxElement(listPtr, eventPtr->xexpose.y),
		NearestListboxElement(listPtr, eventPtr->xexpose.y
		+ eventPtr->xexpose.height));
    } else if (eventPtr->type == DestroyNotify) {
	if (!(listPtr->flags & LISTBOX_DELETED)) {
	    listPtr->flags |= LISTBOX_DELETED;
	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
	    if (listPtr->setGrid) {
		Tk_UnsetGrid(listPtr->tkwin);
	    }
	    if (listPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayListbox, clientData);
	    }
	    Tcl_EventuallyFree(clientData, DestroyListbox);
	}
    } else if (eventPtr->type == ConfigureNotify) {
	int vertSpace;

	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;
	listPtr->fullLines = vertSpace / listPtr->lineHeight;
	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Listbox *listPtr = (Listbox *)clientData;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this procedure destroys the







|







2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    Listbox *listPtr = (Listbox *)clientData;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this procedure destroys the
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
    Tcl_Interp *interp,		/* For error messages. */
    Listbox *listPtr,		/* Listbox for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,		/* Specifies an element in the listbox. */
    int lastOK,		/* If 1, "end" refers to the number of entries
				 * in the listbox. If 0, "end" refers to 1
				 * less than the number of entries. */
    int *indexPtr)		/* Where to store converted index. */
{
    int result, index;
    TkSizeT idx;
    const char *stringRep;

    result = TkGetIntForIndex(indexObj, listPtr->nElements - 1, lastOK, &idx);
    if (result == TCL_OK) {
    	if ((idx != TCL_INDEX_NONE) && (idx > (TkSizeT)listPtr->nElements)) {
    	    idx = listPtr->nElements;
    	}
    	*indexPtr = (int)idx;
    	return TCL_OK;
    }

    /*
     * First see if the index is one of the named indices.
     */








|

|
|
|



|


|







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
    Tcl_Interp *interp,		/* For error messages. */
    Listbox *listPtr,		/* Listbox for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,		/* Specifies an element in the listbox. */
    int lastOK,		/* If 1, "end" refers to the number of entries
				 * in the listbox. If 0, "end" refers to 1
				 * less than the number of entries. */
    Tcl_Size *indexPtr)		/* Where to store converted index. */
{
    int result;
    Tcl_Size idx, index;
    char *stringRep;

    result = TkGetIntForIndex(indexObj, listPtr->nElements - 1, lastOK, &idx);
    if (result == TCL_OK) {
    	if ((idx != TCL_INDEX_NONE) && (idx > listPtr->nElements)) {
    	    idx = listPtr->nElements;
    	}
    	*indexPtr = idx;
    	return TCL_OK;
    }

    /*
     * First see if the index is one of the named indices.
     */

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
    if (stringRep[0] == '@') {

        /*
         * @x,y index
         */

	int y;
	const char *start;
	char *end;

	start = stringRep + 1;
	y = strtol(start, &end, 0);





	if ((start == end) || (*end != ',')) {
	    goto badIndex;
	}

	start = end+1;
	y = strtol(start, &end, 0);
	if ((start == end) || (*end != '\0')) {
	    goto badIndex;
	}
	*indexPtr = NearestListboxElement(listPtr, y);
	return TCL_OK;
    }

    /*
     * Everything failed, nothing matched. Throw up an error message.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad listbox index \"%s\": must be active, anchor, end, @x,y,"
	    " or a number", Tcl_GetString(indexObj)));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "LISTBOX_INDEX", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







|
|


|
>
>
>
>
>
|


>
|
|
<













|







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
    if (stringRep[0] == '@') {

        /*
         * @x,y index
         */

	int y;
	char *start;
	char *rest;

	start = stringRep + 1;
	rest = strchr(start, ',');
	if (!rest) {
	    goto badIndex;
	}
	*rest = '\0';
	if (Tcl_GetInt(NULL, start, &y) != TCL_OK) {
	    *rest = ',';
	    goto badIndex;
	}
	*rest = ',';
	start = rest+1;
	if (Tcl_GetInt(NULL, start, &y) != TCL_OK) {

	    goto badIndex;
	}
	*indexPtr = NearestListboxElement(listPtr, y);
	return TCL_OK;
    }

    /*
     * Everything failed, nothing matched. Throw up an error message.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad listbox index \"%s\": must be active, anchor, end, @x,y,"
	    " or an index", Tcl_GetString(indexObj)));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "LISTBOX_INDEX", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844

static void
ChangeListboxView(
    Listbox *listPtr,	/* Information about widget. */
    int index)			/* Index of element in listPtr that should now
				 * appear at the top of the listbox. */
{
    if (index >= (listPtr->nElements - listPtr->fullLines)) {
	index = listPtr->nElements - listPtr->fullLines;
    }
    if (index < 0) {
	index = 0;
    }
    if (listPtr->topIndex != index) {
	listPtr->topIndex = index;







|







2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843

static void
ChangeListboxView(
    Listbox *listPtr,	/* Information about widget. */
    int index)			/* Index of element in listPtr that should now
				 * appear at the top of the listbox. */
{
    if (index >= ((int)listPtr->nElements - listPtr->fullLines)) {
	index = listPtr->nElements - listPtr->fullLines;
    }
    if (index < 0) {
	index = 0;
    }
    if (listPtr->topIndex != index) {
	listPtr->topIndex = index;
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
    if (index >= (listPtr->fullLines + listPtr->partialLine)) {
	index = listPtr->fullLines + listPtr->partialLine - 1;
    }
    if (index < 0) {
	index = 0;
    }
    index += listPtr->topIndex;
    if (index >= listPtr->nElements) {
	index = listPtr->nElements-1;
    }
    return index;
}

/*
 *----------------------------------------------------------------------







|







2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
    if (index >= (listPtr->fullLines + listPtr->partialLine)) {
	index = listPtr->fullLines + listPtr->partialLine - 1;
    }
    if (index < 0) {
	index = 0;
    }
    index += listPtr->topIndex;
    if (index >= (int)listPtr->nElements) {
	index = listPtr->nElements-1;
    }
    return index;
}

/*
 *----------------------------------------------------------------------
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
    Tcl_HashEntry *entry;

    if (last < first) {
	i = first;
	first = last;
	last = i;
    }
    if ((last < 0) || (first >= listPtr->nElements)) {
	return TCL_OK;
    }
    if (first < 0) {
	first = 0;
    }
    if (last >= listPtr->nElements) {
	last = listPtr->nElements - 1;
    }
    oldCount = listPtr->numSelected;
    firstRedisplay = -1;

    /*
     * For each index in the range, find it in our selection hash table. If







|





|







3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
    Tcl_HashEntry *entry;

    if (last < first) {
	i = first;
	first = last;
	last = i;
    }
    if ((last < 0) || (first >= (int)listPtr->nElements)) {
	return TCL_OK;
    }
    if (first < 0) {
	first = 0;
    }
    if (last >= (int)listPtr->nElements) {
	last = listPtr->nElements - 1;
    }
    oldCount = listPtr->numSelected;
    firstRedisplay = -1;

    /*
     * For each index in the range, find it in our selection hash table. If
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
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ListboxFetchSelection(
    ClientData clientData,	/* Information about listbox widget. */
    TkSizeT offset,			/* Offset within selection of first byte to be
				 * returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_DString selection;
    int count, needNewline, i;
    TkSizeT length, stringLen;
    Tcl_Obj *curElement;
    const char *stringRep;
    Tcl_HashEntry *entry;

    if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
	return -1;
    }

    /*
     * Use a dynamic string to accumulate the contents of the selection.
     */

    needNewline = 0;
    Tcl_DStringInit(&selection);
    for (i = 0; i < listPtr->nElements; i++) {
	entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
	if (entry != NULL) {
	    if (needNewline) {
		Tcl_DStringAppend(&selection, "\n", 1);
	    }
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &curElement);
	    stringRep = TkGetStringFromObj(curElement, &stringLen);
	    Tcl_DStringAppend(&selection, stringRep, stringLen);
	    needNewline = 1;
	}
    }

    length = Tcl_DStringLength(&selection);
    if (length == 0) {







|

|
|


|






|














|







|







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
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
ListboxFetchSelection(
    void *clientData,	/* Information about listbox widget. */
    Tcl_Size offset,			/* Offset within selection of first byte to be
				 * returned. */
    char *buffer,		/* Location in which to place selection. */
    Tcl_Size maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_DString selection;
    int count, needNewline, i;
    Tcl_Size length, stringLen;
    Tcl_Obj *curElement;
    const char *stringRep;
    Tcl_HashEntry *entry;

    if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
	return -1;
    }

    /*
     * Use a dynamic string to accumulate the contents of the selection.
     */

    needNewline = 0;
    Tcl_DStringInit(&selection);
    for (i = 0; i < (int)listPtr->nElements; i++) {
	entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
	if (entry != NULL) {
	    if (needNewline) {
		Tcl_DStringAppend(&selection, "\n", 1);
	    }
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &curElement);
	    stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
	    Tcl_DStringAppend(&selection, stringRep, stringLen);
	    needNewline = 1;
	}
    }

    length = Tcl_DStringLength(&selection);
    if (length == 0) {
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxLostSelection(
    ClientData clientData)	/* Information about listbox widget. */
{
    Listbox *listPtr = (Listbox *)clientData;

    if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
	    && (listPtr->nElements > 0)) {
	ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
        GenerateListboxSelectEvent(listPtr);







|







3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
ListboxLostSelection(
    void *clientData)	/* Information about listbox widget. */
{
    Listbox *listPtr = (Listbox *)clientData;

    if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
	    && (listPtr->nElements > 0)) {
	ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
        GenerateListboxSelectEvent(listPtr);
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyRedrawRange(
    Listbox *listPtr,	/* Information about widget. */
    int first,			/* Index of first element in list that needs
				 * to be redrawn. */
    int last)			/* Index of last element in list that needs to
				 * be redrawn. May be less than first; these
				 * just bracket a range. */
{
    (void)first;
    (void)last;

    /*
     * We don't have to register a redraw callback if one is already pending,
     * or if the window doesn't exist, or if the window isn't mapped.
     */

    if ((listPtr->flags & REDRAW_PENDING)
	    || (listPtr->flags & LISTBOX_DELETED)







|

|



<
<
<







3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259



3260
3261
3262
3263
3264
3265
3266
 *
 *----------------------------------------------------------------------
 */

static void
EventuallyRedrawRange(
    Listbox *listPtr,	/* Information about widget. */
    TCL_UNUSED(Tcl_Size),			/* Index of first element in list that needs
				 * to be redrawn. */
    TCL_UNUSED(Tcl_Size))			/* Index of last element in list that needs to
				 * be redrawn. May be less than first; these
				 * just bracket a range. */
{



    /*
     * We don't have to register a redraw callback if one is already pending,
     * or if the window doesn't exist, or if the window isn't mapped.
     */

    if ((listPtr->flags & REDRAW_PENDING)
	    || (listPtr->flags & LISTBOX_DELETED)
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
     * We must hold onto the interpreter from the listPtr because the data at
     * listPtr might be freed as a result of the Tcl_EvalEx.
     */

    interp = listPtr->interp;
    Tcl_Preserve(interp);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, listPtr->yScrollCmd, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, firstStr, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, lastStr, -1);
    result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (vertical scrolling command executed by listbox)");
	Tcl_BackgroundException(interp, result);
    }
    Tcl_Release(interp);







|
|
|
|
|
|







3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
     * We must hold onto the interpreter from the listPtr because the data at
     * listPtr might be freed as a result of the Tcl_EvalEx.
     */

    interp = listPtr->interp;
    Tcl_Preserve(interp);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, listPtr->yScrollCmd, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, firstStr, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, lastStr, TCL_INDEX_NONE);
    result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (vertical scrolling command executed by listbox)");
	Tcl_BackgroundException(interp, result);
    }
    Tcl_Release(interp);
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
     * We must hold onto the interpreter because the data referred to at
     * listPtr might be freed as a result of the call to Tcl_EvalEx.
     */

    interp = listPtr->interp;
    Tcl_Preserve(interp);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, listPtr->xScrollCmd, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, firstStr, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, lastStr, -1);
    result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (horizontal scrolling command executed by listbox)");
	Tcl_BackgroundException(interp, result);
    }
    Tcl_Release(interp);







|
|
|
|
|
|







3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
     * We must hold onto the interpreter because the data referred to at
     * listPtr might be freed as a result of the call to Tcl_EvalEx.
     */

    interp = listPtr->interp;
    Tcl_Preserve(interp);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, listPtr->xScrollCmd, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, firstStr, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, lastStr, TCL_INDEX_NONE);
    result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (horizontal scrolling command executed by listbox)");
	Tcl_BackgroundException(interp, result);
    }
    Tcl_Release(interp);
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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
ListboxListVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_Obj *oldListObj, *varListObj;
    int oldLength, i;
    Tcl_HashEntry *entry;
    (void)name1;
    (void)name2;

    /*
     * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
     */

    if (flags & TCL_TRACE_UNSETS) {

        if (!Tcl_InterpDeleted(interp) && listPtr->listVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        listPtr->listVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        ListboxListVarProc, probe);
                if (probe == (ClientData)listPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * listVarName, which means it is not unset and not







|

|
|




|

<
<








|






|







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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
ListboxListVarProc(
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),
    TCL_UNUSED(const char *),
    int flags)			/* Information about what happened. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Tcl_Obj *oldListObj, *varListObj;
    Tcl_Size oldLength, i;
    Tcl_HashEntry *entry;



    /*
     * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
     */

    if (flags & TCL_TRACE_UNSETS) {

        if (!Tcl_InterpDeleted(interp) && listPtr->listVarName) {
            void *probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        listPtr->listVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        ListboxListVarProc, probe);
                if (probe == (void *)listPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * listVarName, which means it is not unset and not
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
		Tcl_DeleteHashEntry(entry);
	    }
	}
    }

    if (oldLength != listPtr->nElements) {
	listPtr->flags |= UPDATE_V_SCROLLBAR;
	if (listPtr->topIndex > (listPtr->nElements - listPtr->fullLines)) {
	    listPtr->topIndex = listPtr->nElements - listPtr->fullLines;
	    if (listPtr->topIndex < 0) {
		listPtr->topIndex = 0;
	    }
	}
    }








|







3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
		Tcl_DeleteHashEntry(entry);
	    }
	}
    }

    if (oldLength != listPtr->nElements) {
	listPtr->flags |= UPDATE_V_SCROLLBAR;
	if (listPtr->topIndex > ((int)listPtr->nElements - listPtr->fullLines)) {
	    listPtr->topIndex = listPtr->nElements - listPtr->fullLines;
	    if (listPtr->topIndex < 0) {
		listPtr->topIndex = 0;
	    }
	}
    }

3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597

3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
 *
 *----------------------------------------------------------------------
 */

static void
MigrateHashEntries(
    Tcl_HashTable *table,
    int first,
    int last,
    int offset)
{

    int i, isNew;
    Tcl_HashEntry *entry;
    ClientData clientData;

    if (offset == 0) {
	return;
    }

    /*
     * It's more efficient to do one if/else and nest the for loops inside,







|
|
|

>
|

|







3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
 *
 *----------------------------------------------------------------------
 */

static void
MigrateHashEntries(
    Tcl_HashTable *table,
    Tcl_Size first,
    Tcl_Size last,
    Tcl_Size offset)
{
    Tcl_Size i;
    int isNew;
    Tcl_HashEntry *entry;
    void *clientData;

    if (offset == 0) {
	return;
    }

    /*
     * It's more efficient to do one if/else and nest the for loops inside,

Changes to generic/tkMacWinMenu.c.

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.
 *
 * 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"






|







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 © 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"
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
     * Now, we go through structure and process all of the commands. Since the
     * structure is changing, we stop after we do one command, and start over.
     * When we get through without doing any, we are done.
     */

    do {
	finished = 1;
	for (index = 0; index < (int)menuPtr->numEntries; index++) {
	    TkMenuEntry *entryPtr = menuPtr->entries[index];

	    if ((entryPtr->type == CASCADE_ENTRY)
		    && (entryPtr->namePtr != NULL)
		    && (entryPtr->childMenuRefPtr != NULL)
		    && (entryPtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr = entryPtr->childMenuRefPtr->menuPtr;







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
     * Now, we go through structure and process all of the commands. Since the
     * structure is changing, we stop after we do one command, and start over.
     * When we get through without doing any, we are done.
     */

    do {
	finished = 1;
	for (index = 0; index < menuPtr->numEntries; index++) {
	    TkMenuEntry *entryPtr = menuPtr->entries[index];

	    if ((entryPtr->type == CASCADE_ENTRY)
		    && (entryPtr->namePtr != NULL)
		    && (entryPtr->childMenuRefPtr != NULL)
		    && (entryPtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr = entryPtr->childMenuRefPtr->menuPtr;

Changes to generic/tkMain.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

/*
 * The default prompt used when the user has not overridden it.
 */

static const char DEFAULT_PRIMARY_PROMPT[] = "% ";


/*
 * This file can be compiled on Windows in UNICODE mode, as well as
 * on all other platforms using the native encoding. This is done
 * by using the normal Windows functions like _tcscmp, but on
 * platforms which don't have <tchar.h> we have to translate that
 * to strcmp here.
 */
#ifdef _WIN32
#ifdef __cplusplus
extern "C" {
#endif
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntPlatStubs, just







|






>


|
|
|
|
<







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

extern int TkCygwinMainEx(Tcl_Size, char **, Tcl_AppInitProc *, Tcl_Interp *);

/*
 * The default prompt used when the user has not overridden it.
 */

static const char DEFAULT_PRIMARY_PROMPT[] = "% ";
static const char ENCODING_ERROR[] = "\n\t(encoding error in stderr)";

/*
 * This file can be compiled on Windows in UNICODE mode, as well as on all
 * other platforms using the native encoding. This is done by using the normal
 * Windows functions like _tcscmp, but on platforms which don't have <tchar.h>
 * we have to translate that to strcmp here.

 */
#ifdef _WIN32
#ifdef __cplusplus
extern "C" {
#endif
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntPlatStubs, just
63
64
65
66
67
68
69

70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

static inline Tcl_Obj *
NewNativeObj(
    TCHAR *string)
{
    Tcl_Obj *obj;
    Tcl_DString ds;


#ifdef UNICODE
    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(string, wcslen(string), &ds);

#else
    Tcl_ExternalToUtfDString(NULL, (char *) string, -1, &ds);
#endif
    obj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    return obj;
}

/*
 * Declarations for various library functions and variables (don't want to
 * include tkInt.h or tkPort.h here, because people might copy this file out
 * of the Tk source directory to make their own modified versions). Note: do
 * not declare "exit" here even though a declaration is really needed, because
 * it will conflict with a declaration elsewhere on some systems.
 */

#if defined(_WIN32)
#define isatty WinIsTty
static int WinIsTty(int fd) {
    HANDLE handle;

    /*
     * For now, under Windows, we assume we are not running as a console mode
     * app, so we need to use the GUI console. In order to enable this, we
     * always claim to be running on a tty. This probably isn't the right way
     * to do it.
     */

#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9 && tclIntPlatStubsPtr->tclpIsAtty) {
	    /* We are running on Cygwin */
	    return tclIntPlatStubsPtr->tclpIsAtty(fd);
	}
#endif
    handle = GetStdHandle(STD_INPUT_HANDLE + fd);
	/*
	 * If it's a bad or closed handle, then it's been connected to a wish
	 * console window. A character file handle is a tty by definition.
	 */
    return (handle == INVALID_HANDLE_VALUE) || (handle == 0)
	     || (GetFileType(handle) == FILE_TYPE_UNKNOWN)
	     || (GetFileType(handle) == FILE_TYPE_CHAR);
}
#else
extern int		isatty(int fd);
#endif

typedef struct InteractiveState {
    Tcl_Channel input;		/* The standard input channel from which lines
				 * are read. */
    int tty;			/* Non-zero means standard input is a
				 * terminal-like device. Zero means it's a
				 * file. */
    Tcl_DString command;	/* Used to assemble lines of terminal input
				 * into Tcl commands. */
    Tcl_DString line;		/* Used to read the next line from the
				 * terminal input. */
    int gotPartial;
    Tcl_Interp *interp;		/* Interpreter that evaluates interactive
				 * commands. */
} InteractiveState;

/*
 * Forward declarations for functions defined later in this file.
 */

static void		Prompt(Tcl_Interp *interp, InteractiveState *isPtr);
static void		StdinProc(ClientData clientData, int mask);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MainEx --
 *
 *	Main program for Wish and most other Tk-based applications.







>

|


>

|

|






|


















|

















|



















|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

static inline Tcl_Obj *
NewNativeObj(
    TCHAR *string)
{
    Tcl_Obj *obj;
    Tcl_DString ds;
    const char *str;

#if defined(_WIN32) && defined(UNICODE)
    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(string, wcslen(string), &ds);
    str = Tcl_DStringValue(&ds);
#else
    str = Tcl_ExternalToUtfDString(NULL, (char *)string, strlen(string), &ds);
#endif
    obj = Tcl_NewStringObj(str, Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    return obj;
}

/*
 * Declarations for various library functions and variables (don't want to
 * include tclInt.h or tclPort.h here, because people might copy this file out
 * of the Tk source directory to make their own modified versions). Note: do
 * not declare "exit" here even though a declaration is really needed, because
 * it will conflict with a declaration elsewhere on some systems.
 */

#if defined(_WIN32)
#define isatty WinIsTty
static int WinIsTty(int fd) {
    HANDLE handle;

    /*
     * For now, under Windows, we assume we are not running as a console mode
     * app, so we need to use the GUI console. In order to enable this, we
     * always claim to be running on a tty. This probably isn't the right way
     * to do it.
     */

#if !defined(STATIC_BUILD)
	if (tclStubsPtr->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
	 * console window. A character file handle is a tty by definition.
	 */
    return (handle == INVALID_HANDLE_VALUE) || (handle == 0)
	     || (GetFileType(handle) == FILE_TYPE_UNKNOWN)
	     || (GetFileType(handle) == FILE_TYPE_CHAR);
}
#else
extern int		isatty(int fd);
#endif

typedef struct {
    Tcl_Channel input;		/* The standard input channel from which lines
				 * are read. */
    int tty;			/* Non-zero means standard input is a
				 * terminal-like device. Zero means it's a
				 * file. */
    Tcl_DString command;	/* Used to assemble lines of terminal input
				 * into Tcl commands. */
    Tcl_DString line;		/* Used to read the next line from the
				 * terminal input. */
    int gotPartial;
    Tcl_Interp *interp;		/* Interpreter that evaluates interactive
				 * commands. */
} InteractiveState;

/*
 * Forward declarations for functions defined later in this file.
 */

static void		Prompt(Tcl_Interp *interp, InteractiveState *isPtr);
static void		StdinProc(void *clientData, int mask);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MainEx --
 *
 *	Main program for Wish and most other Tk-based applications.
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176





177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
 *	interpreted.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MainEx(
    int argc,			/* Number of arguments. */
    TCHAR **argv,		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * function to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{

    Tcl_Obj *path, *argvPtr, *appName;
    const char *encodingName;
    int code, nullStdin = 0;
    Tcl_Channel chan;
    InteractiveState is;






    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
	if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
	    abort();
	} else {
	    Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
	}
    }

#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)

    if (tclStubsPtr->reserved9) {
	/* We are running win32 Tk under Cygwin, so let's check
	 * whether the env("DISPLAY") variable or the -display
	 * argument is set. If so, we really want to run the
	 * Tk_MainEx function of libtk8.?.dll, not this one. */
	if (Tcl_GetVar2(interp, "env", "DISPLAY", TCL_GLOBAL_ONLY)) {
	loadCygwinTk:
	    if (TkCygwinMainEx(argc, argv, appInitProc, interp)) {
		/* Should never reach here. */
		return;
	    }
	} else {
	    int i;

	    for (i = 1; i < argc; ++i) {
		if (!_tcscmp(argv[i], TEXT("-display"))) {
		    goto loadCygwinTk;
		}
	    }
	}
    }
#endif

    Tcl_InitMemory(interp);

    is.interp = interp;
    is.gotPartial = 0;
    Tcl_Preserve(interp);

#if defined(_WIN32)
#if !defined(STATIC_BUILD)
    /* If compiled for Win32 but running on Cygwin, don't use console */
    if (!tclStubsPtr->reserved9)
#endif
    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
    }
#endif

    /*
     * If the application has not already set a startup script, parse the
     * first few command line arguments to determine the script path and
     * encoding.
     */

    if (NULL == Tcl_GetStartupScript(NULL)) {
	size_t length;

	/*
	 * Check whether first 3 args (argv[1] - argv[3]) look like
	 *  -encoding ENCODING FILENAME
	 * or like
	 *  FILENAME
	 * or like
	 *  -file FILENAME		(ancient history support only)
	 */


	if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
		&& (TEXT('-') != argv[3][0])) {
	    Tcl_Obj *value = NewNativeObj(argv[2]);
	    Tcl_SetStartupScript(NewNativeObj(argv[3]), Tcl_GetString(value));

	    Tcl_DecrRefCount(value);
	    argc -= 3;
	    argv += 3;
	} else if ((argc > 1) && (TEXT('-') != argv[1][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[1]), NULL);
	    argc--;
	    argv++;
	} else if ((argc > 2) && (length = _tcslen(argv[1]))
		&& (length > 1) && (0 == _tcsncmp(TEXT("-file"), argv[1], length))
		&& (TEXT('-') != argv[2][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[2]), NULL);
	    argc -= 2;
	    argv += 2;
	}
    }

    path = Tcl_GetStartupScript(&encodingName);
    if (path == NULL) {
	appName = NewNativeObj(argv[0]);
    } else {
	appName = path;
    }
    Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY);
    argc--;
    argv++;

    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewWideIntObj(argc), TCL_GLOBAL_ONLY);

    argvPtr = Tcl_NewListObj(0, NULL);
    while (argc--) {
	Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++));
    }
    Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);

    /*
     * Set the "tcl_interactive" variable.
     */








|







>





>
>
>
>
>





|









|











|

|
|
















|

















<







|


>
|
|

|
>


|
|


|
<
<
<
<
<
<










<
<

|



|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272






273
274
275
276
277
278
279
280
281
282


283
284
285
286
287
288
289
290
291
292
293
294
295
 *	interpreted.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MainEx(
    Tcl_Size argc,			/* Number of arguments. */
    TCHAR **argv,		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * function to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{
    int i=0;			/* argv[i] index */
    Tcl_Obj *path, *argvPtr, *appName;
    const char *encodingName;
    int code, nullStdin = 0;
    Tcl_Channel chan;
    InteractiveState is;

    if (0 < argc) {
	--argc;			/* "consume" argv[0] */
	++i;
    }

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
	if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
	    abort();
	} else {
	    Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
	}
    }

#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)

    if (tclStubsPtr->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)) {
		/* Should never reach here. */
		return;
	    }
	} else {
	    Tcl_Size j;

	    for (j = 1; j < argc; ++j) {
		if (!strcmp(argv[j], "-display")) {
		    goto loadCygwinTk;
		}
	    }
	}
    }
#endif

    Tcl_InitMemory(interp);

    is.interp = interp;
    is.gotPartial = 0;
    Tcl_Preserve(interp);

#if defined(_WIN32)
#if !defined(STATIC_BUILD)
    /* If compiled for Win32 but running on Cygwin, don't use console */
    if (!tclStubsPtr->tcl_CreateFileHandler)
#endif
    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
    }
#endif

    /*
     * If the application has not already set a startup script, parse the
     * first few command line arguments to determine the script path and
     * encoding.
     */

    if (NULL == Tcl_GetStartupScript(NULL)) {


	/*
	 * Check whether first 3 args (argv[1] - argv[3]) look like
	 *  -encoding ENCODING FILENAME
	 * or like
	 *  FILENAME
	 * or like
	 *  -file FILENAME (ancient history support only, removed with Tcl 9.0)
	 */

	/* mind argc is being adjusted as we proceed */
	if ((argc >= 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
		&& ('-' != argv[3][0])) {
	    Tcl_Obj *value = NewNativeObj(argv[2]);
	    Tcl_SetStartupScript(NewNativeObj(argv[3]),
		    Tcl_GetString(value));
	    Tcl_DecrRefCount(value);
	    argc -= 3;
	    i += 3;
	} else if ((argc >= 1) && ('-' != argv[1][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[1]), NULL);
	    argc--;
	    i++;






	}
    }

    path = Tcl_GetStartupScript(&encodingName);
    if (path == NULL) {
	appName = NewNativeObj(argv[0]);
    } else {
	appName = path;
    }
    Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY);



    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewWideIntObj((Tcl_WideInt)argc), TCL_GLOBAL_ONLY);

    argvPtr = Tcl_NewListObj(0, NULL);
    while (argc--) {
	Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(argv[i++]));
    }
    Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);

    /*
     * Set the "tcl_interactive" variable.
     */

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418






419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453
454


455
456



457









458
459
460
461
462
463
464
 *	Could be almost arbitrary, depending on the command that's typed.
 *
 *----------------------------------------------------------------------
 */

static void
StdinProc(
    ClientData clientData,	/* The state of interactive cmd line */
    TCL_UNUSED(int))
{
    char *cmd;
    int code;
    TkSizeT count;
    InteractiveState *isPtr = (InteractiveState *)clientData;
    Tcl_Channel chan = isPtr->input;
    Tcl_Interp *interp = isPtr->interp;

    count = Tcl_Gets(chan, &isPtr->line);

    if ((count == TCL_IO_FAILURE) && !isPtr->gotPartial) {
	if (isPtr->tty) {






	    Tcl_Exit(0);
	} else {
	    Tcl_DeleteChannelHandler(chan, StdinProc, isPtr);
	}

	return;
    }

    Tcl_DStringAppend(&isPtr->command, Tcl_DStringValue(&isPtr->line), -1);
    cmd = Tcl_DStringAppend(&isPtr->command, "\n", -1);
    Tcl_DStringFree(&isPtr->line);
    if (!Tcl_CommandComplete(cmd)) {
	isPtr->gotPartial = 1;
	goto prompt;
    }
    isPtr->gotPartial = 0;

    /*
     * Disable the stdin channel handler while evaluating the command;
     * otherwise if the command re-enters the event loop we might process
     * commands from stdin before the current command is finished. Among other
     * things, this will trash the text of the command being evaluated.
     */

    Tcl_CreateChannelHandler(chan, 0, StdinProc, isPtr);
    code = Tcl_RecordAndEval(interp, cmd, TCL_EVAL_GLOBAL);

    isPtr->input = Tcl_GetStdChannel(TCL_STDIN);
    if (isPtr->input) {
	Tcl_CreateChannelHandler(isPtr->input, TCL_READABLE, StdinProc, isPtr);
    }
    Tcl_DStringFree(&isPtr->command);
    if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') {
	if ((code != TCL_OK) || (isPtr->tty)) {
	    chan = Tcl_GetStdChannel((code != TCL_OK) ? TCL_STDERR : TCL_STDOUT);

	    if (chan) {
		Tcl_WriteObj(chan, Tcl_GetObjResult(interp));


		Tcl_WriteChars(chan, "\n", 1);
	    }



	}









    }

    /*
     * If a tty stdin is still around, output a prompt.
     */

  prompt:







|
|



|




|

|

>
>
>
>
>
>

<
<

>



|
|
















<
|
|
|


<
|
|
>
|
|
>
>
|
|
>
>
>
|
>
>
>
>
>
>
>
>
>







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426


427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 *	Could be almost arbitrary, depending on the command that's typed.
 *
 *----------------------------------------------------------------------
 */

static void
StdinProc(
    void *clientData,	/* The state of interactive cmd line */
    TCL_UNUSED(int) /*mask*/)
{
    char *cmd;
    int code;
    Tcl_Size length;
    InteractiveState *isPtr = (InteractiveState *)clientData;
    Tcl_Channel chan = isPtr->input;
    Tcl_Interp *interp = isPtr->interp;

    length = Tcl_Gets(chan, &isPtr->line);

    if ((length < 0) && !isPtr->gotPartial) {
	if (isPtr->tty) {
	    /*
	     * Would be better to find a way to exit the mainLoop? Or perhaps
	     * evaluate [exit]? Leaving as is for now due to compatibility
	     * concerns.
	     */

	    Tcl_Exit(0);


	}
	Tcl_DeleteChannelHandler(chan, StdinProc, isPtr);
	return;
    }

    Tcl_DStringAppend(&isPtr->command, Tcl_DStringValue(&isPtr->line), TCL_INDEX_NONE);
    cmd = Tcl_DStringAppend(&isPtr->command, "\n", TCL_INDEX_NONE);
    Tcl_DStringFree(&isPtr->line);
    if (!Tcl_CommandComplete(cmd)) {
	isPtr->gotPartial = 1;
	goto prompt;
    }
    isPtr->gotPartial = 0;

    /*
     * Disable the stdin channel handler while evaluating the command;
     * otherwise if the command re-enters the event loop we might process
     * commands from stdin before the current command is finished. Among other
     * things, this will trash the text of the command being evaluated.
     */

    Tcl_CreateChannelHandler(chan, 0, StdinProc, isPtr);
    code = Tcl_RecordAndEval(interp, cmd, TCL_EVAL_GLOBAL);

    isPtr->input = chan = Tcl_GetStdChannel(TCL_STDIN);
    if (chan != NULL) {
	Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc, isPtr);
    }
    Tcl_DStringFree(&isPtr->command);

    if (code != TCL_OK) {
	chan = Tcl_GetStdChannel(TCL_STDERR);

	if (chan != NULL) {
	    if (Tcl_WriteObj(chan, Tcl_GetObjResult(interp)) < 0) {
		Tcl_WriteChars(chan, ENCODING_ERROR, -1);
	    }
	    Tcl_WriteChars(chan, "\n", 1);
	}
    } else if (isPtr->tty) {
	Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
	chan = Tcl_GetStdChannel(TCL_STDOUT);

	Tcl_IncrRefCount(resultPtr);
	(void)Tcl_GetStringFromObj(resultPtr, &length);
	if ((length > 0) && (chan != NULL)) {
	    if (Tcl_WriteObj(chan, resultPtr) < 0) {
		Tcl_WriteChars(chan, "\n\t(encoding error in stdout)", -1);
	    }
	    Tcl_WriteChars(chan, "\n", 1);
	}
	Tcl_DecrRefCount(resultPtr);
    }

    /*
     * If a tty stdin is still around, output a prompt.
     */

  prompt:
506
507
508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
	    }
	}
    } else {
	code = Tcl_EvalObjEx(interp, promptCmdPtr, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (script that generates prompt)");
	    if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') {
		chan = Tcl_GetStdChannel(TCL_STDERR);
		if (chan != NULL) {
		    Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
		    Tcl_WriteChars(chan, "\n", 1);
		}

	    }
	    goto defaultPrompt;
	}
    }

    chan = Tcl_GetStdChannel(TCL_STDOUT);
    if (chan != NULL) {







<
|
|
|
|
|
>







525
526
527
528
529
530
531

532
533
534
535
536
537
538
539
540
541
542
543
544
	    }
	}
    } else {
	code = Tcl_EvalObjEx(interp, promptCmdPtr, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (script that generates prompt)");

	    chan = Tcl_GetStdChannel(TCL_STDERR);
	    if (chan != NULL) {
	    if (Tcl_WriteObj(chan, Tcl_GetObjResult(interp)) < 0) {
		Tcl_WriteChars(chan, ENCODING_ERROR, -1);
	    }
		Tcl_WriteChars(chan, "\n", 1);
	    }
	    goto defaultPrompt;
	}
    }

    chan = Tcl_GetStdChannel(TCL_STDOUT);
    if (chan != NULL) {

Changes to generic/tkMenu.c.

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.
 *
 * 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:








|
|







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 © 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:
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
TCL_DECLARE_MUTEX(menuMutex)

/*
 * Configuration specs for individual menu entries. If this changes, be sure
 * to update code in TkpMenuInit that changes the font string entry.
 */

static const char *const menuStateStrings[] = {"active", "normal", "disabled", NULL};

static const char *const menuEntryTypeStrings[] = {
    "cascade", "checkbutton", "command", "radiobutton", "separator", NULL
};

/*
 * The following table defines the legal values for the -compound option. It
 * is used with the "enum compound" declaration in tkMenu.h
 */

static const char *const compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_BG, offsetof(TkMenuEntry, activeBorderPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_FG,
	offsetof(TkMenuEntry, activeFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},







<
<




<
<
<
<
<
<
<
<
<







97
98
99
100
101
102
103


104
105
106
107









108
109
110
111
112
113
114
TCL_DECLARE_MUTEX(menuMutex)

/*
 * Configuration specs for individual menu entries. If this changes, be sure
 * to update code in TkpMenuInit that changes the font string entry.
 */



static const char *const menuEntryTypeStrings[] = {
    "cascade", "checkbutton", "command", "radiobutton", "separator", NULL
};










static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_BG, offsetof(TkMenuEntry, activeBorderPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_FG,
	offsetof(TkMenuEntry, activeFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
	DEF_MENU_ENTRY_COLUMN_BREAK,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, columnBreak), 0, NULL, 0},
    {TK_OPTION_STRING, "-command", NULL, NULL,
	DEF_MENU_ENTRY_COMMAND,
	offsetof(TkMenuEntry, commandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_MENU_ENTRY_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuEntry, compound), 0,
	(ClientData) compoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	offsetof(TkMenuEntry, fontPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	DEF_MENU_ENTRY_FG,
	offsetof(TkMenuEntry, fgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
	DEF_MENU_ENTRY_HIDE_MARGIN,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, hideMargin), 0, NULL, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	DEF_MENU_ENTRY_IMAGE,
	offsetof(TkMenuEntry, imagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-label", NULL, NULL,
	DEF_MENU_ENTRY_LABEL,
	offsetof(TkMenuEntry, labelPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
    {TK_OPTION_INT, "-underline", NULL, NULL,
	DEF_MENU_ENTRY_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuEntry, underline), 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},







|

















|
|
|
|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	DEF_MENU_ENTRY_COLUMN_BREAK,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, columnBreak), 0, NULL, 0},
    {TK_OPTION_STRING, "-command", NULL, NULL,
	DEF_MENU_ENTRY_COMMAND,
	offsetof(TkMenuEntry, commandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_MENU_ENTRY_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuEntry, compound), 0,
	tkCompoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	offsetof(TkMenuEntry, fontPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	DEF_MENU_ENTRY_FG,
	offsetof(TkMenuEntry, fgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
	DEF_MENU_ENTRY_HIDE_MARGIN,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, hideMargin), 0, NULL, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	DEF_MENU_ENTRY_IMAGE,
	offsetof(TkMenuEntry, imagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-label", NULL, NULL,
	DEF_MENU_ENTRY_LABEL,
	offsetof(TkMenuEntry, labelPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, state),
	0, tkStateStrings, 0},
    {TK_OPTION_INDEX, "-underline", NULL, NULL,
	TK_OPTION_UNDERLINE_DEF(TkMenuEntry, underline), 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
};

static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE, TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec *specsArray[] = {
    tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
    tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
    tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
};

/*
 * Menu type strings for use with Tcl_GetIndexFromObj.
 */

static const char *const menuTypeStrings[] = {
    "normal", "tearoff", "menubar", NULL
};

static const Tk_OptionSpec tkMenuConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground",
	"Foreground", DEF_MENU_ACTIVE_BG_COLOR,
	offsetof(TkMenu, activeBorderPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_ACTIVE_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth",
	"BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH,
	offsetof(TkMenu, activeBorderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
	"Background", DEF_MENU_ACTIVE_FG_COLOR,
	offsetof(TkMenu, activeFgPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_ACTIVE_FG_MONO, 0},
    {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_MENU_ACTIVE_RELIEF, offsetof(TkMenu, activeReliefPtr),
	TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENU_BG_COLOR, offsetof(TkMenu, borderPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENU_BORDER_WIDTH,
	offsetof(TkMenu, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENU_CURSOR,
	offsetof(TkMenu, cursorPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
	offsetof(TkMenu, disabledFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	(ClientData) DEF_MENU_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENU_FONT, offsetof(TkMenu, fontPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENU_FG, offsetof(TkMenu, fgPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING, "-postcommand", "postCommand", "Command",
	DEF_MENU_POST_COMMAND,
	offsetof(TkMenu, postCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, offsetof(TkMenu, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, offsetof(TkMenu, indicatorFgPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENU_TAKE_FOCUS,
	offsetof(TkMenu, takeFocusPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, TCL_INDEX_NONE, offsetof(TkMenu, tearoff), 0, NULL, 0},
    {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand",
	"TearOffCommand", DEF_MENU_TEAROFF_CMD,
	offsetof(TkMenu, tearoffCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 offsetof(TkMenu, titlePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-type", "type", "Type",
	DEF_MENU_TYPE, offsetof(TkMenu, menuTypePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	(ClientData) menuTypeStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

/*
 * Command line options. Put here because MenuCmd has to look at them along
 * with MenuWidgetObjCmd.
 */

static const char *const menuOptions[] = {
    "activate", "add", "cget", "clone", "configure", "delete", "entrycget",
    "entryconfigure", "index", "insert", "invoke", "post", "postcascade",
    "type", "unpost", "xposition", "yposition", NULL
};
enum options {
    MENU_ACTIVATE, MENU_ADD, MENU_CGET, MENU_CLONE, MENU_CONFIGURE,
    MENU_DELETE, MENU_ENTRYCGET, MENU_ENTRYCONFIGURE, MENU_INDEX,
    MENU_INSERT, MENU_INVOKE, MENU_POST, MENU_POSTCASCADE, MENU_TYPE,
    MENU_UNPOST, MENU_XPOSITION, MENU_YPOSITION
};

/*
 * Prototypes for static functions in this file:
 */

static int		CloneMenu(TkMenu *menuPtr, Tcl_Obj *newMenuName,
			    Tcl_Obj *newMenuTypeString);
static int		ConfigureMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		ConfigureMenuCloneEntries(Tcl_Interp *interp,
			    TkMenu *menuPtr, int index,
			    int objc, Tcl_Obj *const objv[]);
static int		ConfigureMenuEntry(TkMenuEntry *mePtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteMenuCloneEntries(TkMenu *menuPtr,
			    int first, int last);
static void		DestroyMenuHashTable(ClientData clientData,
			    Tcl_Interp *interp);
static void		DestroyMenuInstance(TkMenu *menuPtr);
static void		DestroyMenuEntry(void *memPtr);
static TkSizeT	GetIndexFromCoords(Tcl_Interp *interp,
			    TkMenu *menuPtr, const char *string,
			    TkSizeT *indexPtr);
static int		MenuDoYPosition(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *objPtr);
static int		MenuDoXPosition(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *objPtr);
static int		MenuAddOrInsert(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *indexPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		MenuCmdDeletedProc(ClientData clientData);
static TkMenuEntry *	MenuNewEntry(TkMenu *menuPtr, TkSizeT index, int type);
static char *		MenuVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		MenuWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		MenuWorldChanged(ClientData instanceData);
static int		PostProcessEntry(TkMenuEntry *mePtr);
static void		RecursivelyDeleteMenu(TkMenu *menuPtr);
static void		UnhookCascadeEntry(TkMenuEntry *mePtr);
static void		MenuCleanup(ClientData unused);
static int		GetMenuIndex(Tcl_Interp *interp, TkMenu *menuPtr,
			    Tcl_Obj *objPtr, int lastOK, TkSizeT *indexPtr);

/*
 * The structure below is a list of procs that respond to certain window
 * manager events. One of these includes a font change, which forces the
 * geometry proc to be called.
 */








|
|














|






|






|





|













|










|


|












|
|










|




|











|
|
<
|

|


|


|
|

|





|

|
|
|


|
<
<
|



|

|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352


353
354
355
356
357
358
359
360
361
362
363
364
365
366
};

static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE, TCL_INDEX_NONE, offsetof(TkMenuEntry, state),
	0, tkStateStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec *specsArray[] = {
    tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
    tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
    tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
};

/*
 * Menu type strings for use with Tcl_GetIndexFromObj.
 */

static const char *const menuTypeStrings[] = {
    "menubar", "normal", "tearoff", NULL
};

static const Tk_OptionSpec tkMenuConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground",
	"Foreground", DEF_MENU_ACTIVE_BG_COLOR,
	offsetof(TkMenu, activeBorderPtr), TCL_INDEX_NONE, 0,
	DEF_MENU_ACTIVE_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth",
	"BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH,
	offsetof(TkMenu, activeBorderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
	"Background", DEF_MENU_ACTIVE_FG_COLOR,
	offsetof(TkMenu, activeFgPtr), TCL_INDEX_NONE, 0,
	DEF_MENU_ACTIVE_FG_MONO, 0},
    {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_MENU_ACTIVE_RELIEF, offsetof(TkMenu, activeReliefPtr),
	TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENU_BG_COLOR, offsetof(TkMenu, borderPtr), TCL_INDEX_NONE, 0,
	DEF_MENU_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENU_BORDER_WIDTH,
	offsetof(TkMenu, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENU_CURSOR,
	offsetof(TkMenu, cursorPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
	offsetof(TkMenu, disabledFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	DEF_MENU_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENU_FONT, offsetof(TkMenu, fontPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENU_FG, offsetof(TkMenu, fgPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING, "-postcommand", "postCommand", "Command",
	DEF_MENU_POST_COMMAND,
	offsetof(TkMenu, postCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, TCL_INDEX_NONE, offsetof(TkMenu, relief), 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, offsetof(TkMenu, indicatorFgPtr), TCL_INDEX_NONE, 0,
	DEF_MENU_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENU_TAKE_FOCUS,
	offsetof(TkMenu, takeFocusPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, TCL_INDEX_NONE, offsetof(TkMenu, tearoff), 0, NULL, 0},
    {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand",
	"TearOffCommand", DEF_MENU_TEAROFF_CMD,
	offsetof(TkMenu, tearoffCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 offsetof(TkMenu, titlePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-type", "type", "Type",
	DEF_MENU_TYPE, offsetof(TkMenu, menuTypePtr), TCL_INDEX_NONE,
	0, menuTypeStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

/*
 * Command line options. Put here because MenuCmd has to look at them along
 * with MenuWidgetObjCmd.
 */

static const char *const menuOptions[] = {
    "activate", "add", "cget", "clone", "configure", "delete", "entrycget",
    "entryconfigure", "id", "index", "insert", "invoke", "post", "postcascade",
    "type", "unpost", "xposition", "yposition", NULL
};
enum options {
    MENU_ACTIVATE, MENU_ADD, MENU_CGET, MENU_CLONE, MENU_CONFIGURE,
    MENU_DELETE, MENU_ENTRYCGET, MENU_ENTRYCONFIGURE, MENU_ID, MENU_INDEX,
    MENU_INSERT, MENU_INVOKE, MENU_POST, MENU_POSTCASCADE, MENU_TYPE,
    MENU_UNPOST, MENU_XPOSITION, MENU_YPOSITION
};

/*
 * Prototypes for static functions in this file:
 */

static int		CloneMenu(TkMenu *menuPtr, Tcl_Obj *newMenuName,
			    Tcl_Obj *newMenuTypeString);
static int		ConfigureMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		ConfigureMenuCloneEntries(TkMenu *menuPtr, int index,

			    Tcl_Size objc, Tcl_Obj *const objv[]);
static int		ConfigureMenuEntry(TkMenuEntry *mePtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteMenuCloneEntries(TkMenu *menuPtr,
			    int first, int last);
static void		DestroyMenuHashTable(void *clientData,
			    Tcl_Interp *interp);
static void		DestroyMenuInstance(TkMenu *menuPtr);
static Tcl_FreeProc	DestroyMenuEntry;
static Tcl_Size	GetIndexFromCoords(Tcl_Interp *interp,
			    TkMenu *menuPtr, const char *string,
			    Tcl_Size *indexPtr);
static int		MenuDoYPosition(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *objPtr);
static int		MenuDoXPosition(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *objPtr);
static int		MenuAddOrInsert(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *indexPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static void		MenuCmdDeletedProc(void *clientData);
static TkMenuEntry *	MenuNewEntry(TkMenu *menuPtr, Tcl_Size index, int type);
static char *		MenuVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static Tcl_ObjCmdProc MenuWidgetObjCmd;


static void		MenuWorldChanged(void *instanceData);
static int		PostProcessEntry(TkMenuEntry *mePtr);
static void		RecursivelyDeleteMenu(TkMenu *menuPtr);
static void		UnhookCascadeEntry(TkMenuEntry *mePtr);
static void		MenuCleanup(void *unused);
static int		GetMenuIndex(Tcl_Interp *interp, TkMenu *menuPtr,
			    Tcl_Obj *objPtr, int lastOK, Tcl_Size *indexPtr);

/*
 * The structure below is a list of procs that respond to certain window
 * manager events. One of these includes a font change, which forces the
 * geometry proc to be called.
 */

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenuObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tk_Window newWin;
    TkMenu *menuPtr;
    TkMenuReferences *menuRefPtr;

    int i, index, toplevel;
    const char *windowName;
    static const char *const typeStringList[] = {"-type", NULL};
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");







|








>
|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenuObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tk_Window newWin;
    TkMenu *menuPtr;
    TkMenuReferences *menuRefPtr;
    Tcl_Size i;
    int index, toplevel;
    const char *windowName;
    static const char *const typeStringList[] = {"-type", NULL};
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
459
460
461
462
463
464
465


466
467
468
469
470
471
472
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
	    MenuCmdDeletedProc);
    menuPtr->active = TCL_INDEX_NONE;
    menuPtr->cursorPtr = NULL;
    menuPtr->mainMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;


    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
	    TkMenuEventProc, menuPtr);







>
>







446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
	    MenuCmdDeletedProc);
    menuPtr->active = TCL_INDEX_NONE;
    menuPtr->cursorPtr = NULL;
    menuPtr->mainMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;
    Tcl_InitHashTable(&menuPtr->items, TCL_STRING_KEYS);
    menuPtr->serial = 0;
    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
	    TkMenuEventProc, menuPtr);
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
	     * creating exists.
     	     */

     	    if ((menuPtr->mainMenuPtr != menuPtr)
     	    	    || ((menuPtr->mainMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->mainMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
     	    } else {
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		Tcl_Obj *windowNamePtr = Tcl_NewStringObj(
			Tk_PathName(cascadeListPtr->menuPtr->tkwin), -1);

		Tcl_IncrRefCount(normalPtr);
		Tcl_IncrRefCount(windowNamePtr);
		newMenuName = TkNewMenuName(menuPtr->interp,
     	    		windowNamePtr, menuPtr);
		Tcl_IncrRefCount(newMenuName);
		CloneMenu(menuPtr, newMenuName, normalPtr);

		/*
		 * Now we can set the new menu instance to be the cascade
		 * entry of the parent's instance.
		 */

		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = newMenuName;
		Tcl_IncrRefCount(newObjv[0]);
		ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(normalPtr);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
		Tcl_DecrRefCount(windowNamePtr);







|







|

|













|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
	     * creating exists.
     	     */

     	    if ((menuPtr->mainMenuPtr != menuPtr)
     	    	    || ((menuPtr->mainMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->mainMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", TCL_INDEX_NONE);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
     	    } else {
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", TCL_INDEX_NONE);
		Tcl_Obj *windowNamePtr = Tcl_NewStringObj(
			Tk_PathName(cascadeListPtr->menuPtr->tkwin), TCL_INDEX_NONE);

		Tcl_IncrRefCount(normalPtr);
		Tcl_IncrRefCount(windowNamePtr);
		newMenuName = TkNewMenuName(menuPtr->interp,
     	    		windowNamePtr, menuPtr);
		Tcl_IncrRefCount(newMenuName);
		CloneMenu(menuPtr, newMenuName, normalPtr);

		/*
		 * Now we can set the new menu instance to be the cascade
		 * entry of the parent's instance.
		 */

		newObjv[0] = Tcl_NewStringObj("-menu", TCL_INDEX_NONE);
		newObjv[1] = newMenuName;
		Tcl_IncrRefCount(newObjv[0]);
		ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(normalPtr);
		Tcl_DecrRefCount(newObjv[0]);
		Tcl_DecrRefCount(newObjv[1]);
		Tcl_DecrRefCount(windowNamePtr);
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
    if (menuRefPtr->topLevelListPtr != NULL) {
    	TkMenuTopLevelList *topLevelListPtr = menuRefPtr->topLevelListPtr;
    	TkMenuTopLevelList *nextPtr;
    	Tk_Window listtkwin;

	while (topLevelListPtr != NULL) {
    	    /*
    	     * Need to get the next pointer first. TkSetWindowMenuBar changes
    	     * the list, so that the next pointer is different after calling
    	     * it.
    	     */

    	    nextPtr = topLevelListPtr->nextPtr;
    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(menuPtr->tkwin));
    return TCL_OK;







|






|







565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
    if (menuRefPtr->topLevelListPtr != NULL) {
    	TkMenuTopLevelList *topLevelListPtr = menuRefPtr->topLevelListPtr;
    	TkMenuTopLevelList *nextPtr;
    	Tk_Window listtkwin;

	while (topLevelListPtr != NULL) {
    	    /*
    	     * Need to get the next pointer first. Tk_SetWindowMenubar changes
    	     * the list, so that the next pointer is different after calling
    	     * it.
    	     */

    	    nextPtr = topLevelListPtr->nextPtr;
    	    listtkwin = topLevelListPtr->tkwin;
    	    Tk_SetWindowMenubar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(menuPtr->tkwin));
    return TCL_OK;
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MenuWidgetObjCmd(
    ClientData clientData,	/* Information about menu widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    int result = TCL_OK;







|







602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MenuWidgetObjCmd(
    void *clientData,	/* Information about menu widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    int result = TCL_OK;
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
	    sizeof(char *), "option", 0, &option) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(menuPtr);

    switch ((enum options) option) {
    case MENU_ACTIVATE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (menuPtr->active == index) {
	    goto done;
	}
	if ((index != TCL_INDEX_NONE) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY)
		|| (menuPtr->entries[index]->state == ENTRY_DISABLED))) {
	    index = TCL_INDEX_NONE;
	}
	result = TkActivateMenuEntry(menuPtr, index);
	break;
    }
    case MENU_ADD:







|











|







626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
	    sizeof(char *), "option", 0, &option) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(menuPtr);

    switch ((enum options) option) {
    case MENU_ACTIVATE: {
	Tcl_Size index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (menuPtr->active == index) {
	    goto done;
	}
	if ((index >= 0) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY)
		|| (menuPtr->entries[index]->state == ENTRY_DISABLED))) {
	    index = TCL_INDEX_NONE;
	}
	result = TkActivateMenuEntry(menuPtr, index);
	break;
    }
    case MENU_ADD:
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
	}
	if (result != TCL_OK) {
	    goto error;
	}
	break;
    }
    case MENU_DELETE: {
	TkSizeT first, last;
	Tcl_WideInt w;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "first ?last?");
	    goto error;
	}








|







710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
	}
	if (result != TCL_OK) {
	    goto error;
	}
	break;
    }
    case MENU_DELETE: {
	Tcl_Size first, last;
	Tcl_WideInt w;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "first ?last?");
	    goto error;
	}

757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	    /*
	     * Sorry, can't delete the tearoff entry; must reconfigure the
	     * menu.
	     */

	    first = 1;
	}
	if ((first == TCL_INDEX_NONE) || (last < first)) {
	    goto done;
	}
	DeleteMenuCloneEntries(menuPtr, first, last);
	break;
    }
    case MENU_ENTRYCGET: {
	TkSizeT index;
	Tcl_Obj *resultPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	resultPtr = Tk_GetOptionValue(interp, mePtr,
		mePtr->optionTable, objv[3], menuPtr->tkwin);
	Tcl_Release(mePtr);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_ENTRYCONFIGURE: {
	TkSizeT index;
	Tcl_Obj *resultPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?-option value ...?");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, mePtr,
		    mePtr->optionTable, NULL, menuPtr->tkwin);







|






|









|














|









|







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
	    /*
	     * Sorry, can't delete the tearoff entry; must reconfigure the
	     * menu.
	     */

	    first = 1;
	}
	if ((first < 0) || (last < first)) {
	    goto done;
	}
	DeleteMenuCloneEntries(menuPtr, first, last);
	break;
    }
    case MENU_ENTRYCGET: {
	Tcl_Size index;
	Tcl_Obj *resultPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	resultPtr = Tk_GetOptionValue(interp, mePtr,
		mePtr->optionTable, objv[3], menuPtr->tkwin);
	Tcl_Release(mePtr);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_ENTRYCONFIGURE: {
	Tcl_Size index;
	Tcl_Obj *resultPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?-option value ...?");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, mePtr,
		    mePtr->optionTable, NULL, menuPtr->tkwin);
823
824
825
826
827
828
829
830
831
832
833
834
835






















836
837
838
839
840
841
842
843
844
845
846
847
848
849

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
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenuCloneEntries(interp, menuPtr, index,
		    objc-3, objv+3);
	}
	Tcl_Release(mePtr);
	break;
    }






















    case MENU_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else
	Tcl_SetObjResult(interp, TkNewIndexObj(index));

	break;
    }
    case MENU_INSERT:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index type ?-option value ...?");
	    goto error;
	}
	if (MenuAddOrInsert(interp,menuPtr,objv[2],objc-3,objv+3) != TCL_OK) {
	    goto error;
	}
	break;
    case MENU_INVOKE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	result = TkInvokeMenu(interp, menuPtr, index);
	break;
    }
    case MENU_POST: {
	int x, y;
	TkSizeT index = TCL_INDEX_NONE;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {







|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|








|
|
|
|
>













|








|







|







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
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenuCloneEntries(menuPtr, index,
		    objc-3, objv+3);
	}
	Tcl_Release(mePtr);
	break;
    }
    case MENU_ID: {
	Tcl_Size index;
	const char *idStr;
	Tcl_HashEntry *entryPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	entryPtr = menuPtr->entries[index]->entryPtr;
	if (entryPtr) {
	    idStr = (const char *)Tcl_GetHashKey(&menuPtr->items, entryPtr);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(idStr, TCL_INDEX_NONE));
	}
	break;
    }
    case MENU_INDEX: {
	Tcl_Size index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewObj());
	} else {
	    Tcl_SetObjResult(interp, TkNewIndexObj(index));
	}
	break;
    }
    case MENU_INSERT:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index type ?-option value ...?");
	    goto error;
	}
	if (MenuAddOrInsert(interp,menuPtr,objv[2],objc-3,objv+3) != TCL_OK) {
	    goto error;
	}
	break;
    case MENU_INVOKE: {
	Tcl_Size index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	result = TkInvokeMenu(interp, menuPtr, index);
	break;
    }
    case MENU_POST: {
	int x, y;
	Tcl_Size index = TCL_INDEX_NONE;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
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
	    result = TkpPostMenu(interp, menuPtr, x, y, index);
	} else {
	    result = TkpPostTearoffMenu(interp, menuPtr, x, y, index);
	}
	break;
    }
    case MENU_POSTCASCADE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}

	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if ((index == TCL_INDEX_NONE) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) {
	    result = TkPostSubmenu(interp, menuPtr, NULL);
	} else {
	    result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]);
	}
	break;
    }
    case MENU_TYPE: {
	TkSizeT index;
	const char *typeStr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	if (menuPtr->entries[index]->type == TEAROFF_ENTRY) {
	    typeStr = "tearoff";
	} else {
	    typeStr = menuEntryTypeStrings[menuPtr->entries[index]->type];
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1));
	break;
    }
    case MENU_UNPOST:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}







|









|







|









|







|







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
	    result = TkpPostMenu(interp, menuPtr, x, y, index);
	} else {
	    result = TkpPostTearoffMenu(interp, menuPtr, x, y, index);
	}
	break;
    }
    case MENU_POSTCASCADE: {
	Tcl_Size index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}

	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if ((index < 0) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) {
	    result = TkPostSubmenu(interp, menuPtr, NULL);
	} else {
	    result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]);
	}
	break;
    }
    case MENU_TYPE: {
	Tcl_Size index;
	const char *typeStr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	if (menuPtr->entries[index]->type == TEAROFF_ENTRY) {
	    typeStr = "tearoff";
	} else {
	    typeStr = menuEntryTypeStrings[menuPtr->entries[index]->type];
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, TCL_INDEX_NONE));
	break;
    }
    case MENU_UNPOST:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
 *----------------------------------------------------------------------
 */

int
TkInvokeMenu(
    Tcl_Interp *interp,		/* The interp that the menu lives in. */
    TkMenu *menuPtr,		/* The menu we are invoking. */
    TkSizeT index)			/* The zero based index of the item we are
    				 * invoking. */
{
    int result = TCL_OK;
    TkMenuEntry *mePtr;

    if (index == TCL_INDEX_NONE) {
    	goto done;
    }
    mePtr = menuPtr->entries[index];
    if (mePtr->state == ENTRY_DISABLED) {
	goto done;
    }

    Tcl_Preserve(mePtr);
    if (mePtr->type == TEAROFF_ENTRY) {
	Tcl_DString ds;

	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "tk::TearOffMenu ", -1);
	Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&ds), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&ds);
    } else if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    && (mePtr->namePtr != NULL)) {
	Tcl_Obj *valuePtr;

	if (mePtr->entryFlags & ENTRY_SELECTED) {
	    valuePtr = mePtr->offValuePtr;







|





|












|
|
|







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
 *----------------------------------------------------------------------
 */

int
TkInvokeMenu(
    Tcl_Interp *interp,		/* The interp that the menu lives in. */
    TkMenu *menuPtr,		/* The menu we are invoking. */
    Tcl_Size index)			/* The zero based index of the item we are
    				 * invoking. */
{
    int result = TCL_OK;
    TkMenuEntry *mePtr;

    if (index < 0) {
    	goto done;
    }
    mePtr = menuPtr->entries[index];
    if (mePtr->state == ENTRY_DISABLED) {
	goto done;
    }

    Tcl_Preserve(mePtr);
    if (mePtr->type == TEAROFF_ENTRY) {
	Tcl_DString ds;

	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "tk::TearOffMenu ", TCL_INDEX_NONE);
	Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), TCL_INDEX_NONE);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&ds), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&ds);
    } else if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    && (mePtr->namePtr != NULL)) {
	Tcl_Obj *valuePtr;

	if (mePtr->entryFlags & ENTRY_SELECTED) {
	    valuePtr = mePtr->offValuePtr;
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->mainMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMainMenuPtr = cascadePtr->menuPtr->mainMenuPtr;
	    parentMainEntryPtr =
		    parentMainMenuPtr->entries[cascadePtr->index];
	    newObjv[0] = menuNamePtr;
	    newObjv[1] = parentMainEntryPtr->namePtr;








|







1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->mainMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", TCL_INDEX_NONE);

	    parentMainMenuPtr = cascadePtr->menuPtr->mainMenuPtr;
	    parentMainEntryPtr =
		    parentMainMenuPtr->entries[cascadePtr->index];
	    newObjv[0] = menuNamePtr;
	    newObjv[1] = parentMainEntryPtr->namePtr;

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

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

    for (i = menuPtr->numEntries; --i >= 0; ) {











	/*
	 * As each menu entry is deleted from the end of the array of entries,
	 * decrement menuPtr->numEntries. Otherwise, the act of deleting menu
	 * entry i will dereference freed memory attempting to queue a redraw
	 * for menu entries (i+1)...numEntries.
	 */


	DestroyMenuEntry(menuPtr->entries[i]);
	menuPtr->numEntries = i;
    }

    if (menuPtr->entries != NULL) {
	ckfree(menuPtr->entries);

    }

    TkMenuFreeDrawOptions(menuPtr);
    Tk_FreeConfigOptions((char *) menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin);
    if (menuPtr->tkwin != NULL) {
	Tk_Window tkwin = menuPtr->tkwin;

	menuPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDestroyMenu --
 *
 *	This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
 *	up the internal structure of a menu at a safe time (when no-one is
 *	using it anymore). If called on a main instance, destroys all of the
 *	instances. If called on a non-main instance, just destroys
 *	that instance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the menu is freed up.
 *







>
>
>
>
>
>
>
>
>
>
>







>
|


>


>

>

|














<
|
|
|
|







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

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

    for (i = menuPtr->numEntries; --i >= 0; ) {
        /*
         * Clean up the hash entry for the menu item ID.
         * This cannot be postponed until the entry is eventually freed,
         * because the hash table may already have been deleted by then.
         */

        if (menuPtr->entries[i]->entryPtr) {
            Tcl_DeleteHashEntry(menuPtr->entries[i]->entryPtr);
            menuPtr->entries[i]->entryPtr = NULL;
        }

	/*
	 * As each menu entry is deleted from the end of the array of entries,
	 * decrement menuPtr->numEntries. Otherwise, the act of deleting menu
	 * entry i will dereference freed memory attempting to queue a redraw
	 * for menu entries (i+1)...numEntries.
	 */

	Tcl_EventuallyFree(menuPtr->entries[i],
		DestroyMenuEntry);
	menuPtr->numEntries = i;
    }
    menuPtr->active = -1;
    if (menuPtr->entries != NULL) {
	ckfree(menuPtr->entries);
	menuPtr->entries = NULL;
    }
    Tcl_DeleteHashTable(&menuPtr->items);
    TkMenuFreeDrawOptions(menuPtr);
    Tk_FreeConfigOptions(menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin);
    if (menuPtr->tkwin != NULL) {
	Tk_Window tkwin = menuPtr->tkwin;

	menuPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDestroyMenu --
 *

 *	This function is invoked to clean up the internal structure of a menu
 *	at a safe time (when no-one is using it anymore). If called on a main
 *	instance, destroys all of the instances. If called on a non-main
 *	instance, just destroys that instance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the menu is freed up.
 *
1386
1387
1388
1389
1390
1391
1392

1393



1394
1395
1396
1397
1398
1399
1400
 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuEntry(

    void *memPtr)		/* Pointer to entry to be freed. */



{
    TkMenuEntry *mePtr = (TkMenuEntry *)memPtr;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (menuPtr->postedCascade == mePtr) {
    	/*
	 * Ignore errors while unposting the menu, since it's possible that







>

>
>
>







1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuEntry(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Pointer to entry to be freed. */
#else
    char *memPtr)
#endif
{
    TkMenuEntry *mePtr = (TkMenuEntry *)memPtr;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (menuPtr->postedCascade == mePtr) {
    	/*
	 * Ignore errors while unposting the menu, since it's possible that
1460
1461
1462
1463
1464
1465
1466




1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
	    && (mePtr->namePtr != NULL)) {
	const char *varName = Tcl_GetString(mePtr->namePtr);

	Tcl_UntraceVar2(menuPtr->interp, varName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, mePtr);
    }




    TkpDestroyMenuEntry(mePtr);
    TkMenuEntryFreeDrawOptions(mePtr);
    Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, menuPtr->tkwin);
    ckfree(mePtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * MenuWorldChanged --







>
>
>
>


|







1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
	    && (mePtr->namePtr != NULL)) {
	const char *varName = Tcl_GetString(mePtr->namePtr);

	Tcl_UntraceVar2(menuPtr->interp, varName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, mePtr);
    }
    if (mePtr->entryPtr) {
        Tcl_DeleteHashEntry(mePtr->entryPtr);
        mePtr->entryPtr = NULL;
    }
    TkpDestroyMenuEntry(mePtr);
    TkMenuEntryFreeDrawOptions(mePtr);
    Tk_FreeConfigOptions(mePtr, mePtr->optionTable, menuPtr->tkwin);
    ckfree(mePtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * MenuWorldChanged --
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
 *	Menu will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
MenuWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)instanceData;
    TkSizeT i;

    TkMenuConfigureDrawOptions(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],
		menuPtr->entries[i]->index);
	TkpConfigureMenuEntry(menuPtr->entries[i]);
    }







|


|







1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
 *	Menu will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
MenuWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)instanceData;
    Tcl_Size i;

    TkMenuConfigureDrawOptions(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],
		menuPtr->entries[i]->index);
	TkpConfigureMenuEntry(menuPtr->entries[i]);
    }
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
 */

static int
ConfigureMenu(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkMenu *menuPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    int i;
    TkMenu *menuListPtr, *cleanupPtr;
    int result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));







|







1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
 */

static int
ConfigureMenu(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkMenu *menuPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    int i;
    TkMenu *menuListPtr, *cleanupPtr;
    int result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
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
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {

	    Tcl_EventuallyFree(menuListPtr->entries[0], (Tcl_FreeProc *) DestroyMenuEntry);

	    for (i = 0; i < (int)menuListPtr->numEntries - 1; i++) {
		menuListPtr->entries[i] = menuListPtr->entries[i + 1];
		menuListPtr->entries[i]->index = i;
	    }
	    if (--menuListPtr->numEntries == 0) {
		ckfree(menuListPtr->entries);
		menuListPtr->entries = NULL;
	    }
	}

	TkMenuConfigureDrawOptions(menuListPtr);

	/*
	 * After reconfiguring a menu, we need to reconfigure all of the
	 * entries in the menu, since some of the things in the children (such
	 * as graphics contexts) may have to change to reflect changes in the
	 * parent.
	 */

	for (i = 0; i < (int)menuListPtr->numEntries; i++) {
	    TkMenuEntry *mePtr;

	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);







|

|


















|







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
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {

	    Tcl_EventuallyFree(menuListPtr->entries[0], DestroyMenuEntry);

	    for (i = 0; i < menuListPtr->numEntries - 1; i++) {
		menuListPtr->entries[i] = menuListPtr->entries[i + 1];
		menuListPtr->entries[i]->index = i;
	    }
	    if (--menuListPtr->numEntries == 0) {
		ckfree(menuListPtr->entries);
		menuListPtr->entries = NULL;
	    }
	}

	TkMenuConfigureDrawOptions(menuListPtr);

	/*
	 * After reconfiguring a menu, we need to reconfigure all of the
	 * entries in the menu, since some of the things in the children (such
	 * as graphics contexts) may have to change to reflect changes in the
	 * parent.
	 */

	for (i = 0; i < menuListPtr->numEntries; i++) {
	    TkMenuEntry *mePtr;

	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);
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);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	(void)TkGetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
    }

    /*
     * If this is a cascade entry, the platform-specific data of the child
     * menu has to be updated. Also, the links that point to parents and
     * cascades have to be updated.
     */







|




|







1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
     * Tk_ConfigureWidget, such as special processing for defaults, sizing
     * strings, graphics contexts, etc.
     */

    if (mePtr->labelPtr == NULL) {
	mePtr->labelLength = 0;
    } else {
	(void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	(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.
     */
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuEntry(
    TkMenuEntry *mePtr,/* Information about menu entry; may or may
				 * not already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_SavedOptions errorStruct;
    int result;

    /*







|







1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuEntry(
    TkMenuEntry *mePtr,/* Information about menu entry; may or may
				 * not already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_SavedOptions errorStruct;
    int result;

    /*
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
 *----------------------------------------------------------------------
 *
 * ConfigureMenuCloneEntries --
 *
 *	Calls ConfigureMenuEntry for each menu in the clone chain.
 *
 * Results:
 *	The return value is a standard Tcl result. If TCL_ERROR is returned,
 *	then the interp's result contains an error message.
 *
 * Side effects:
 *	Configuration information such as label and accelerator get set for
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuCloneEntries(
    Tcl_Interp *dummy,		/* Used for error reporting. */
    TkMenu *menuPtr,		/* Information about whole menu. */
    int index,			/* Index of mePtr within menuPtr's entries. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;
    int cascadeEntryChanged = 0;
    TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL;
    Tcl_Obj *oldCascadePtr = NULL;
    const char *newCascadeName;
    (void)dummy;

    /*
     * Cascades are kind of tricky here. This is special case #3 in the
     * comment at the top of this file. Basically, if a menu is the main
     * menu of a clone chain, and has an entry with a cascade menu, the clones
     * of the menu will point to clones of the cascade menu. We have to
     * destroy the clones of the cascades, clone the new cascade menu, and







|
<










<


|








<







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
 *----------------------------------------------------------------------
 *
 * ConfigureMenuCloneEntries --
 *
 *	Calls ConfigureMenuEntry for each menu in the clone chain.
 *
 * Results:
 *	The return value is a standard Tcl result.

 *
 * Side effects:
 *	Configuration information such as label and accelerator get set for
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuCloneEntries(

    TkMenu *menuPtr,		/* Information about whole menu. */
    int index,			/* Index of mePtr within menuPtr's entries. */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;
    int cascadeEntryChanged = 0;
    TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL;
    Tcl_Obj *oldCascadePtr = NULL;
    const char *newCascadeName;


    /*
     * Cascades are kind of tricky here. This is special case #3 in the
     * comment at the top of this file. Basically, if a menu is the main
     * menu of a clone chain, and has an entry with a cascade menu, the clones
     * of the menu will point to clones of the cascade menu. We have to
     * destroy the clones of the cascades, clone the new cascade menu, and
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
    	}

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    if (cascadeMenuRefPtr && cascadeMenuRefPtr->menuPtr != NULL) {
		Tcl_Obj *newObjv[2];
		Tcl_Obj *newCloneNamePtr;
		Tcl_Obj *pathNamePtr = Tcl_NewStringObj(
			Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		Tcl_Obj *menuObjPtr = Tcl_NewStringObj("-menu", -1);

		Tcl_IncrRefCount(pathNamePtr);
		newCloneNamePtr = TkNewMenuName(menuPtr->interp,
			pathNamePtr,
			cascadeMenuRefPtr->menuPtr);
		Tcl_IncrRefCount(newCloneNamePtr);
		Tcl_IncrRefCount(normalPtr);







|
|
|







2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
    	}

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    if (cascadeMenuRefPtr && cascadeMenuRefPtr->menuPtr != NULL) {
		Tcl_Obj *newObjv[2];
		Tcl_Obj *newCloneNamePtr;
		Tcl_Obj *pathNamePtr = Tcl_NewStringObj(
			Tk_PathName(menuListPtr->tkwin), TCL_INDEX_NONE);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", TCL_INDEX_NONE);
		Tcl_Obj *menuObjPtr = Tcl_NewStringObj("-menu", TCL_INDEX_NONE);

		Tcl_IncrRefCount(pathNamePtr);
		newCloneNamePtr = TkNewMenuName(menuPtr->interp,
			pathNamePtr,
			cascadeMenuRefPtr->menuPtr);
		Tcl_IncrRefCount(newCloneNamePtr);
		Tcl_IncrRefCount(normalPtr);
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
    Tcl_Interp *interp,		/* For error messages. */
    TkMenu *menuPtr,		/* Menu for which the index is being
				 * specified. */
    Tcl_Obj *objPtr,		/* Specification of an entry in menu. See
				 * manual entry for valid .*/
    int lastOK,			/* Non-zero means its OK to return index just
				 * *after* last entry. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    int i;
    const char *string;


    if (TkGetIntForIndex(objPtr, menuPtr->numEntries - 1, lastOK, indexPtr) == TCL_OK) {
	/* TCL_INDEX_NONE is only accepted if it does not result from a negative number */
	if (*indexPtr != TCL_INDEX_NONE || Tcl_GetString(objPtr)[0] != '-') {
	    if (*indexPtr >= menuPtr->numEntries) {
		*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	    }
	    return TCL_OK;
	}
    }

    string = Tcl_GetString(objPtr);

    if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {
	*indexPtr = menuPtr->active;
	goto success;
    }

    if ((string[0] == 'l') && (strcmp(string, "last") == 0)) {
	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	goto success;
    }






    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {
	*indexPtr = TCL_INDEX_NONE;
	goto success;

    }


    if (string[0] == '@') {
	if (GetIndexFromCoords(NULL, menuPtr, string, indexPtr)
		== TCL_OK) {
	    goto success;

	}
    }








    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr;
	const char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr);

	if ((label != NULL) && (Tcl_StringCaseMatch(label, string, 0))) {
	    *indexPtr = i;
	    goto success;
	}
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad menu entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
    return TCL_ERROR;

  success:
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * MenuCmdDeletedProc --
 *







|

|

>



|











|




|


>
>
>
>
>


<
>

>


|

<
>



>
>
>
>
>
>
>
|





|







<
<
<







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
    Tcl_Interp *interp,		/* For error messages. */
    TkMenu *menuPtr,		/* Menu for which the index is being
				 * specified. */
    Tcl_Obj *objPtr,		/* Specification of an entry in menu. See
				 * manual entry for valid .*/
    int lastOK,			/* Non-zero means its OK to return index just
				 * *after* last entry. */
    Tcl_Size *indexPtr)		/* Where to store converted index. */
{
    Tcl_Size i;
    const char *string;
    Tcl_HashEntry *entryPtr;

    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 >= 0 || Tcl_GetString(objPtr)[0] != '-') {
	    if (*indexPtr >= menuPtr->numEntries) {
		*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	    }
	    return TCL_OK;
	}
    }

    string = Tcl_GetString(objPtr);

    if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {
	*indexPtr = menuPtr->active;
	return TCL_OK;
    }

    if ((string[0] == 'l') && (strcmp(string, "last") == 0)) {
	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	return TCL_OK;
    }

    if (string[0] == 0) {
	*indexPtr = TCL_INDEX_NONE;
	return TCL_OK;
    }
#if !defined(TK_NO_DEPRECATED)
    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {
	*indexPtr = TCL_INDEX_NONE;

	return TCL_OK;
    }
#endif

    if (string[0] == '@') {
	if (GetIndexFromCoords(interp, menuPtr, string, indexPtr)
		== TCL_OK) {

	    return TCL_OK;
	}
    }

    entryPtr = Tcl_FindHashEntry(&menuPtr->items, string);
    if (entryPtr) {
        TkMenuEntry *mePtr = (TkMenuEntry *)Tcl_GetHashValue(entryPtr);
        *indexPtr = mePtr->index;
        return TCL_OK;
    }

    for (i = 0; i < menuPtr->numEntries; i++) {
	Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr;
	const char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr);

	if ((label != NULL) && (Tcl_StringCaseMatch(label, string, 0))) {
	    *indexPtr = i;
	    return TCL_OK;
	}
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad menu entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
    return TCL_ERROR;



}

/*
 *----------------------------------------------------------------------
 *
 * MenuCmdDeletedProc --
 *
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
MenuCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    Tk_Window tkwin = menuPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or







|







2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
MenuCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    Tk_Window tkwin = menuPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
 *
 *----------------------------------------------------------------------
 */

static TkMenuEntry *
MenuNewEntry(
    TkMenu *menuPtr,		/* Menu that will hold the new entry. */
    TkSizeT index,			/* Where in the menu the new entry is to
				 * go. */
    int type)			/* The type of the new entry. */
{
    TkMenuEntry *mePtr;
    TkMenuEntry **newEntries;
    TkSizeT i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Create a new array of entries with an empty slot for the new entry.
     */








|





|







2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
 *
 *----------------------------------------------------------------------
 */

static TkMenuEntry *
MenuNewEntry(
    TkMenu *menuPtr,		/* Menu that will hold the new entry. */
    Tcl_Size index,			/* Where in the menu the new entry is to
				 * go. */
    int type)			/* The type of the new entry. */
{
    TkMenuEntry *mePtr;
    TkMenuEntry **newEntries;
    Tcl_Size i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Create a new array of entries with an empty slot for the new entry.
     */

2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
    mePtr = (TkMenuEntry *)ckalloc(sizeof(TkMenuEntry));
    menuPtr->entries[index] = mePtr;
    mePtr->type = type;
    mePtr->optionTable = tsdPtr->entryOptionTables[type];
    mePtr->menuPtr = menuPtr;
    mePtr->labelPtr = NULL;
    mePtr->labelLength = 0;
    mePtr->underline = -1;
    mePtr->bitmapPtr = NULL;
    mePtr->imagePtr = NULL;
    mePtr->image = NULL;
    mePtr->selectImagePtr = NULL;
    mePtr->selectImage = NULL;
    mePtr->accelPtr = NULL;
    mePtr->accelLength = 0;







|







2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
    mePtr = (TkMenuEntry *)ckalloc(sizeof(TkMenuEntry));
    menuPtr->entries[index] = mePtr;
    mePtr->type = type;
    mePtr->optionTable = tsdPtr->entryOptionTables[type];
    mePtr->menuPtr = menuPtr;
    mePtr->labelPtr = NULL;
    mePtr->labelLength = 0;
    mePtr->underline = INT_MIN;
    mePtr->bitmapPtr = NULL;
    mePtr->imagePtr = NULL;
    mePtr->image = NULL;
    mePtr->selectImagePtr = NULL;
    mePtr->selectImage = NULL;
    mePtr->accelPtr = NULL;
    mePtr->accelLength = 0;
2303
2304
2305
2306
2307
2308
2309

2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
    mePtr->index = index;
    mePtr->nextCascadePtr = NULL;
    if (Tk_InitOptions(menuPtr->interp, mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree(mePtr);
	return NULL;
    }

    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable,
		menuPtr->tkwin);
    	ckfree(mePtr);
    	return NULL;
    }

    return mePtr;
}







>


|







2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
    mePtr->index = index;
    mePtr->nextCascadePtr = NULL;
    if (Tk_InitOptions(menuPtr->interp, mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree(mePtr);
	return NULL;
    }
    mePtr->entryPtr = NULL;
    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions(mePtr, mePtr->optionTable,
		menuPtr->tkwin);
    	ckfree(mePtr);
    	return NULL;
    }

    return mePtr;
}
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

static int
MenuAddOrInsert(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkMenu *menuPtr,		/* Widget in which to create new entry. */
    Tcl_Obj *indexPtr,		/* Object describing index at which to insert.
				 * NULL means insert at end. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[])	/* Arguments to command: first arg is type of
				 * entry, others are config options. */
{
    int type;
    TkSizeT index;
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;





    if (indexPtr != NULL) {
	if (GetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad menu entry index \"%s\"", Tcl_GetString(indexPtr)));
	Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (menuPtr->tearoff && (index == 0)) {
	index = 1;
    }

    /*
     * Figure out the type of the new entry.
     */

    if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings,
	    sizeof(char *), "menu entry type", 0, &type) != TCL_OK) {
	return TCL_ERROR;
    }

















    /*
     * Now we have to add an entry for every instance related to this menu.
     */

    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
    	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = MenuNewEntry(menuListPtr, index, type);
    	if (mePtr == NULL) {
    	    return TCL_ERROR;
    	}
    	if (ConfigureMenuEntry(mePtr, objc - 1, objv + 1) != TCL_OK) {
	    TkMenu *errorMenuPtr;
	    TkSizeT i;

	    for (errorMenuPtr = menuPtr->mainMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree(errorMenuPtr->entries[index],
    	    		(Tcl_FreeProc *) DestroyMenuEntry);
		for (i = index; i < errorMenuPtr->numEntries - 1; i++) {
		    errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1];
		    errorMenuPtr->entries[i]->index = i;
		}
		if (--errorMenuPtr->numEntries == 0) {
		    ckfree(errorMenuPtr->entries);
		    errorMenuPtr->entries = NULL;
		}
		if (errorMenuPtr == menuListPtr) {
		    break;
		}
	    }
    	    return TCL_ERROR;
    	}


















    	/*
	 * If a menu has cascades, then every instance of the menu has to have
	 * its own parallel cascade structure. So adding an entry to a menu
	 * with clones means that the menu that the entry points to has to be
	 * cloned for every clone the main menu has. This is special case #2
	 * in the comment at the top of this file.
    	 */

    	if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->mainMenuPtr;
		Tcl_Obj *newCascadePtr, *newObjv[2];
		Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
		Tcl_Obj *windowNamePtr =
			Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		TkMenuReferences *menuRefPtr;

		Tcl_IncrRefCount(windowNamePtr);
		newCascadePtr = TkNewMenuName(menuListPtr->interp,
			windowNamePtr, cascadeMenuPtr);
		Tcl_IncrRefCount(newCascadePtr);
		Tcl_IncrRefCount(normalPtr);







|




|


>
>
>
>








|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<







|

|





|















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















|

|
|







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

static int
MenuAddOrInsert(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkMenu *menuPtr,		/* Widget in which to create new entry. */
    Tcl_Obj *indexPtr,		/* Object describing index at which to insert.
				 * NULL means insert at end. */
    Tcl_Size objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[])	/* Arguments to command: first arg is type of
				 * entry, others are config options. */
{
    int type;
    Tcl_Size index;
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;
    Tcl_HashEntry *entryPtr;
    Tcl_Obj *idPtr = NULL;
    int isNew;
    int offs;

    if (indexPtr != NULL) {
	if (GetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad menu entry index \"%s\"", Tcl_GetString(indexPtr)));
	Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (menuPtr->tearoff && (index == 0)) {
	index = 1;
    }

    /*
     * Figure out the type of the new entry.
     */

    if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings,
	    sizeof(char *), "menu entry type", 0, &type) != TCL_OK) {
	return TCL_ERROR;
    }
    offs = 1;

    /*
     * Check for a user supplied id
     */

    if (objc % 2 == 0) {
        idPtr = objv[offs];
        if (Tcl_FindHashEntry(&menuPtr->items, Tcl_GetString(idPtr))) {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "entry \"%s\" already exists", Tcl_GetString(idPtr)));
            Tcl_SetErrorCode(interp, "TK", "MENU", "ENTRY_EXISTS", NULL);
            return TCL_ERROR;
        }
        offs++;
    }

    /*
     * Now we have to add an entry for every instance related to this menu.
     */

    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
    	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = MenuNewEntry(menuListPtr, index, type);
    	if (mePtr == NULL) {
    	    return TCL_ERROR;
    	}
    	if (ConfigureMenuEntry(mePtr, objc - offs, objv + offs) != TCL_OK) {
	    TkMenu *errorMenuPtr;
	    Tcl_Size i;

	    for (errorMenuPtr = menuPtr->mainMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree(errorMenuPtr->entries[index],
    	    		DestroyMenuEntry);
		for (i = index; i < errorMenuPtr->numEntries - 1; i++) {
		    errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1];
		    errorMenuPtr->entries[i]->index = i;
		}
		if (--errorMenuPtr->numEntries == 0) {
		    ckfree(errorMenuPtr->entries);
		    errorMenuPtr->entries = NULL;
		}
		if (errorMenuPtr == menuListPtr) {
		    break;
		}
	    }
    	    return TCL_ERROR;
    	}

        if (idPtr == NULL) {
            char idbuf[16];
            /* Generate an id for the new entry on the main menu */
            do {
                snprintf(idbuf, sizeof(idbuf), "e%03X", ++menuPtr->serial);
                entryPtr = Tcl_CreateHashEntry(
			&menuListPtr->items, idbuf, &isNew);
            } while (!isNew);
            idPtr = Tcl_NewStringObj(idbuf, TCL_INDEX_NONE);
        } else {
            /* Reuse the specified or previously generated id on all clones */
            entryPtr = Tcl_CreateHashEntry(
		    &menuListPtr->items, Tcl_GetString(idPtr), &isNew);
        }
        Tcl_SetHashValue(entryPtr, mePtr);
        mePtr->entryPtr = entryPtr;

    	/*
	 * If a menu has cascades, then every instance of the menu has to have
	 * its own parallel cascade structure. So adding an entry to a menu
	 * with clones means that the menu that the entry points to has to be
	 * cloned for every clone the main menu has. This is special case #2
	 * in the comment at the top of this file.
    	 */

    	if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->mainMenuPtr;
		Tcl_Obj *newCascadePtr, *newObjv[2];
		Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", TCL_INDEX_NONE);
		Tcl_Obj *windowNamePtr =
			Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), TCL_INDEX_NONE);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", TCL_INDEX_NONE);
		TkMenuReferences *menuRefPtr;

		Tcl_IncrRefCount(windowNamePtr);
		newCascadePtr = TkNewMenuName(menuListPtr->interp,
			windowNamePtr, cascadeMenuPtr);
		Tcl_IncrRefCount(newCascadePtr);
		Tcl_IncrRefCount(normalPtr);
2452
2453
2454
2455
2456
2457
2458


2459
2460
2461
2462
2463
2464
2465
		Tcl_DecrRefCount(newCascadePtr);
		Tcl_DecrRefCount(menuNamePtr);
		Tcl_DecrRefCount(windowNamePtr);
		Tcl_DecrRefCount(normalPtr);
    	    }
    	}
    }


    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuVarProc --







>
>







2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
		Tcl_DecrRefCount(newCascadePtr);
		Tcl_DecrRefCount(menuNamePtr);
		Tcl_DecrRefCount(windowNamePtr);
		Tcl_DecrRefCount(normalPtr);
    	    }
    	}
    }

    Tcl_SetObjResult(interp, idPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuVarProc --
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
 *	The menu entry may become selected or deselected.
 *
 *--------------------------------------------------------------
 */

static char *
MenuVarProc(
    ClientData clientData,	/* Information about menu entry. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* First part of variable's name. */
    const char *name2,		/* Second part of variable's name. */
    int flags)			/* Describes what just happened. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)clientData;
    TkMenu *menuPtr;
    const char *value;
    const char *name, *onValue;
    (void)name1;
    (void)name2;

    if (Tcl_InterpDeleted(interp) || (mePtr->namePtr == NULL)) {
	/*
	 * Do nothing if the interpreter is going away or we have
	 * no variable name.
	 */








|

|
|






<
<







2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572


2573
2574
2575
2576
2577
2578
2579
 *	The menu entry may become selected or deselected.
 *
 *--------------------------------------------------------------
 */

static char *
MenuVarProc(
    void *clientData,	/* Information about menu entry. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),	/* First part of variable's name. */
    TCL_UNUSED(const char *),	/* Second part of variable's name. */
    int flags)			/* Describes what just happened. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)clientData;
    TkMenu *menuPtr;
    const char *value;
    const char *name, *onValue;



    if (Tcl_InterpDeleted(interp) || (mePtr->namePtr == NULL)) {
	/*
	 * Do nothing if the interpreter is going away or we have
	 * no variable name.
	 */

2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
    name = Tcl_GetString(mePtr->namePtr);

    /*
     * If the variable is being unset, then re-establish the trace.
     */

    if (flags & TCL_TRACE_UNSETS) {
        ClientData probe = NULL;
	mePtr->entryFlags &= ~ENTRY_SELECTED;

        do {
                probe = Tcl_VarTraceInfo(interp, name,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MenuVarProc, probe);
                if (probe == (ClientData)mePtr) {
                    break;
                }
        } while (probe);
        if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * namePtr, which means it is not unset and not







|






|







2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
    name = Tcl_GetString(mePtr->namePtr);

    /*
     * If the variable is being unset, then re-establish the trace.
     */

    if (flags & TCL_TRACE_UNSETS) {
        void *probe = NULL;
	mePtr->entryFlags &= ~ENTRY_SELECTED;

        do {
                probe = Tcl_VarTraceInfo(interp, name,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MenuVarProc, probe);
                if (probe == (void *)mePtr) {
                    break;
                }
        } while (probe);
        if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * namePtr, which means it is not unset and not
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
 *
 *----------------------------------------------------------------------
 */

int
TkActivateMenuEntry(
    TkMenu *menuPtr,	/* Menu in which to activate. */
    TkSizeT index)			/* Index of entry to activate, or
				 * TCL_INDEX_NONE to deactivate all entries. */
{
    TkMenuEntry *mePtr;
    int result = TCL_OK;

    if (menuPtr->active != TCL_INDEX_NONE) {
	mePtr = menuPtr->entries[menuPtr->active];

	/*
	 * Don't change the state unless it's currently active (state might
	 * already have been changed to disabled).
	 */

	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	TkEventuallyRedrawMenu(menuPtr, menuPtr->entries[menuPtr->active]);
    }
    menuPtr->active = index;
    if (index != TCL_INDEX_NONE) {
	mePtr = menuPtr->entries[index];
	mePtr->state = ENTRY_ACTIVE;
	TkEventuallyRedrawMenu(menuPtr, mePtr);
    }
    return result;
}








|





|













|







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
 *
 *----------------------------------------------------------------------
 */

int
TkActivateMenuEntry(
    TkMenu *menuPtr,	/* Menu in which to activate. */
    Tcl_Size index)			/* Index of entry to activate, or
				 * TCL_INDEX_NONE to deactivate all entries. */
{
    TkMenuEntry *mePtr;
    int result = TCL_OK;

    if (menuPtr->active >= 0) {
	mePtr = menuPtr->entries[menuPtr->active];

	/*
	 * Don't change the state unless it's currently active (state might
	 * already have been changed to disabled).
	 */

	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	TkEventuallyRedrawMenu(menuPtr, menuPtr->entries[menuPtr->active]);
    }
    menuPtr->active = index;
    if (index >= 0) {
	mePtr = menuPtr->entries[index];
	mePtr->state = ENTRY_ACTIVE;
	TkEventuallyRedrawMenu(menuPtr, mePtr);
    }
    return result;
}

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
CloneMenu(
    TkMenu *menuPtr,		/* The menu we are going to clone. */
    Tcl_Obj *newMenuNamePtr,	/* The name to give the new menu. */
    Tcl_Obj *newMenuTypePtr)	/* What kind of menu is this, a normal menu a
    				 * menubar, or a tearoff? */
{
    int returnResult;
    int menuType, i;

    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MAIN_MENU;
    } else {
	if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
		menuTypeStrings, sizeof(char *), "menu type", 0, &menuType) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    menuDupCommandArray[0] = Tcl_NewStringObj("tk::MenuDup", -1);
    menuDupCommandArray[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1);
    menuDupCommandArray[2] = newMenuNamePtr;
    if (newMenuTypePtr == NULL) {
	menuDupCommandArray[3] = Tcl_NewStringObj("normal", -1);
    } else {
	menuDupCommandArray[3] = newMenuTypePtr;
    }
    for (i = 0; i < 4; i++) {
	Tcl_IncrRefCount(menuDupCommandArray[i]);
    }
    Tcl_Preserve(menuPtr);







|
>












|
|


|







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
CloneMenu(
    TkMenu *menuPtr,		/* The menu we are going to clone. */
    Tcl_Obj *newMenuNamePtr,	/* The name to give the new menu. */
    Tcl_Obj *newMenuTypePtr)	/* What kind of menu is this, a normal menu a
    				 * menubar, or a tearoff? */
{
    int returnResult;
    int menuType;
    Tcl_Size i;
    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MAIN_MENU;
    } else {
	if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
		menuTypeStrings, sizeof(char *), "menu type", 0, &menuType) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    menuDupCommandArray[0] = Tcl_NewStringObj("tk::MenuDup", TCL_INDEX_NONE);
    menuDupCommandArray[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), TCL_INDEX_NONE);
    menuDupCommandArray[2] = newMenuNamePtr;
    if (newMenuTypePtr == NULL) {
	menuDupCommandArray[3] = Tcl_NewStringObj("normal", TCL_INDEX_NONE);
    } else {
	menuDupCommandArray[3] = newMenuTypePtr;
    }
    for (i = 0; i < 4; i++) {
	Tcl_IncrRefCount(menuDupCommandArray[i]);
    }
    Tcl_Preserve(menuPtr);
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743

    if ((returnResult == TCL_OK) &&
	    ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
	    newMenuNamePtr)) != NULL)
	    && (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) {
	TkMenu *newMenuPtr = menuRefPtr->menuPtr;
	Tcl_Obj *newObjv[3];
	int numElements;

	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {







|







2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823

    if ((returnResult == TCL_OK) &&
	    ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
	    newMenuNamePtr)) != NULL)
	    && (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) {
	TkMenu *newMenuPtr = menuRefPtr->menuPtr;
	Tcl_Obj *newObjv[3];
	Tcl_Size numElements;

	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
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
	/*
	 * Add the main menu's window to the bind tags for this window after
	 * this window's tag. This is so the user can bind to either this
	 * clone (which may not be easy to do) or the entire menu clone
	 * structure.
	 */

	newObjv[0] = Tcl_NewStringObj("bindtags", -1);
	newObjv[1] = Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), -1);
	Tcl_IncrRefCount(newObjv[0]);
	Tcl_IncrRefCount(newObjv[1]);
	if (Tk_BindtagsObjCmd(newMenuPtr->tkwin, newMenuPtr->interp, 2,
		newObjv) == TCL_OK) {
	    const char *windowName;
	    Tcl_Obj *bindingsPtr =
		    Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp));
	    Tcl_Obj *elementPtr;

	    Tcl_IncrRefCount(bindingsPtr);
	    Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements);
	    for (i = 0; i < numElements; i++) {
		Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
			&elementPtr);
		windowName = Tcl_GetString(elementPtr);
		if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
			== 0) {
		    Tcl_Obj *newElementPtr = Tcl_NewStringObj(
			    Tk_PathName(newMenuPtr->mainMenuPtr->tkwin), -1);

		    /*
		     * The newElementPtr will have its refCount incremented
		     * here, so we don't need to worry about it any more.
		     */

		    Tcl_ListObjReplace(menuPtr->interp, bindingsPtr,







|
|


















|







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
	/*
	 * 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", TCL_INDEX_NONE);
	newObjv[1] = Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), TCL_INDEX_NONE);
	Tcl_IncrRefCount(newObjv[0]);
	Tcl_IncrRefCount(newObjv[1]);
	if (Tk_BindtagsObjCmd(newMenuPtr->tkwin, newMenuPtr->interp, 2,
		newObjv) == TCL_OK) {
	    const char *windowName;
	    Tcl_Obj *bindingsPtr =
		    Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp));
	    Tcl_Obj *elementPtr;

	    Tcl_IncrRefCount(bindingsPtr);
	    Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements);
	    for (i = 0; i < numElements; i++) {
		Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
			&elementPtr);
		windowName = Tcl_GetString(elementPtr);
		if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
			== 0) {
		    Tcl_Obj *newElementPtr = Tcl_NewStringObj(
			    Tk_PathName(newMenuPtr->mainMenuPtr->tkwin), TCL_INDEX_NONE);

		    /*
		     * The newElementPtr will have its refCount incremented
		     * here, so we don't need to worry about it any more.
		     */

		    Tcl_ListObjReplace(menuPtr->interp, bindingsPtr,
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
	Tcl_DecrRefCount(newObjv[1]);
	Tcl_ResetResult(menuPtr->interp);

	/*
	 * Clone all of the cascade menus that this menu points to.
	 */

	for (i = 0; i < (int)menuPtr->numEntries; i++) {
	    TkMenuReferences *cascadeRefPtr;
	    TkMenu *oldCascadePtr;

	    if ((menuPtr->entries[i]->type == CASCADE_ENTRY)
		&& (menuPtr->entries[i]->namePtr != NULL)) {
		cascadeRefPtr =
			TkFindMenuReferencesObj(menuPtr->interp,







|







2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
	Tcl_DecrRefCount(newObjv[1]);
	Tcl_ResetResult(menuPtr->interp);

	/*
	 * Clone all of the cascade menus that this menu points to.
	 */

	for (i = 0; i < menuPtr->numEntries; i++) {
	    TkMenuReferences *cascadeRefPtr;
	    TkMenu *oldCascadePtr;

	    if ((menuPtr->entries[i]->type == CASCADE_ENTRY)
		&& (menuPtr->entries[i]->namePtr != NULL)) {
		cascadeRefPtr =
			TkFindMenuReferencesObj(menuPtr->interp,
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837

		    Tcl_IncrRefCount(windowNamePtr);
		    newCascadePtr = TkNewMenuName(menuPtr->interp,
			    windowNamePtr, oldCascadePtr);
		    Tcl_IncrRefCount(newCascadePtr);
		    CloneMenu(oldCascadePtr, newCascadePtr, NULL);

		    newObjv[0] = Tcl_NewStringObj("-menu", -1);
		    newObjv[1] = newCascadePtr;
		    Tcl_IncrRefCount(newObjv[0]);
		    ConfigureMenuEntry(newMenuPtr->entries[i], 2, newObjv);
		    Tcl_DecrRefCount(newObjv[0]);
		    Tcl_DecrRefCount(newCascadePtr);
		    Tcl_DecrRefCount(windowNamePtr);
		}







|







2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917

		    Tcl_IncrRefCount(windowNamePtr);
		    newCascadePtr = TkNewMenuName(menuPtr->interp,
			    windowNamePtr, oldCascadePtr);
		    Tcl_IncrRefCount(newCascadePtr);
		    CloneMenu(oldCascadePtr, newCascadePtr, NULL);

		    newObjv[0] = Tcl_NewStringObj("-menu", TCL_INDEX_NONE);
		    newObjv[1] = newCascadePtr;
		    Tcl_IncrRefCount(newObjv[0]);
		    ConfigureMenuEntry(newMenuPtr->entries[i], 2, newObjv);
		    Tcl_DecrRefCount(newObjv[0]);
		    Tcl_DecrRefCount(newCascadePtr);
		    Tcl_DecrRefCount(windowNamePtr);
		}
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885

static int
MenuDoXPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->x));
    }
    return TCL_OK;
}








|






|







2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965

static int
MenuDoXPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    Tcl_Size index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_ResetResult(interp);
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->x));
    }
    return TCL_OK;
}

2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922

static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->y));
    }

    return TCL_OK;








|






|







2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002

static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    Tcl_Size index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->y));
    }

    return TCL_OK;

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
 *
 * Side effects:
 *	If int is invalid, interp's result will be set to NULL.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
GetIndexFromCoords(
    Tcl_Interp *interp,		/* Interpreter of menu. */
    TkMenu *menuPtr,		/* The menu we are searching. */
    const char *string,		/* The @string we are parsing. */
    TkSizeT *indexPtr)		/* The index of the item that matches. */
{
    int x, y, i;

    const char *p;
    char *end;
    int x2, borderwidth, max;

    TkRecomputeMenu(menuPtr);
    p = string + 1;
    y = strtol(p, &end, 0);
    if (end == p) {
	goto error;
    }
    Tk_GetPixelsFromObj(interp, menuPtr->tkwin,
	menuPtr->borderWidthPtr, &borderwidth);

    if (*end == ',') {
	x = y;

	p = end + 1;
	y = strtol(p, &end, 0);
	if (end == p) {
	    goto error;
	}
    } else {
	x = borderwidth;

    }





    *indexPtr = -1;

    /* set the width of the final column to the remainder of the window
     * being aware of windows that may not be mapped yet.
     */
    max = Tk_IsMapped(menuPtr->tkwin)
      ? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin);
    max -= borderwidth;

    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	if (menuPtr->entries[i]->entryFlags & ENTRY_LAST_COLUMN) {
	    x2 = max;
	} else {
	    x2 = menuPtr->entries[i]->x + menuPtr->entries[i]->width;
	}
	if ((x >= menuPtr->entries[i]->x) && (y >= menuPtr->entries[i]->y)
		&& (x < x2)







|




|

|
>

|




<
<
<
<
|
|
>
|
|
>
|
|
|




>

>
>
>
>










|







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
 *
 * Side effects:
 *	If int is invalid, interp's result will be set to NULL.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
GetIndexFromCoords(
    Tcl_Interp *interp,		/* Interpreter of menu. */
    TkMenu *menuPtr,		/* The menu we are searching. */
    const char *string,		/* The @string we are parsing. */
    Tcl_Size *indexPtr)		/* The index of the item that matches. */
{
    int x, y;
    Tcl_Size i;
    const char *p;
    const char *rest;
    int x2, borderwidth, max;

    TkRecomputeMenu(menuPtr);
    p = string + 1;




    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
	    menuPtr->borderWidthPtr, &borderwidth);
    rest = strchr(p, ',');
    if (rest) {
	Tcl_DString ds;
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, p, rest - p);

	if (Tcl_GetInt(NULL, Tcl_DStringValue(&ds), &x) != TCL_OK) {
	    goto error;
	}
    } else {
	x = borderwidth;
	rest = string;
    }
    p = rest + 1;
    if (Tcl_GetInt(NULL, p, &y) != TCL_OK) {
	    goto error;
	}

    *indexPtr = -1;

    /* set the width of the final column to the remainder of the window
     * being aware of windows that may not be mapped yet.
     */
    max = Tk_IsMapped(menuPtr->tkwin)
      ? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin);
    max -= borderwidth;

    for (i = 0; i < menuPtr->numEntries; i++) {
	if (menuPtr->entries[i]->entryFlags & ENTRY_LAST_COLUMN) {
	    x2 = max;
	} else {
	    x2 = menuPtr->entries[i]->x + menuPtr->entries[i]->width;
	}
	if ((x >= menuPtr->entries[i]->x) && (y >= menuPtr->entries[i]->y)
		&& (x < x2)
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
 *----------------------------------------------------------------------
 */

static void
RecursivelyDeleteMenu(
    TkMenu *menuPtr)		/* The menubar instance we are deleting. */
{
    TkSizeT i;
    TkMenuEntry *mePtr;

    /*
     * It is not 100% clear that this preserve/release pair is required, but
     * we have added them for safety in this very complex code.
     */








|







3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
 *----------------------------------------------------------------------
 */

static void
RecursivelyDeleteMenu(
    TkMenu *menuPtr)		/* The menubar instance we are deleting. */
{
    Tcl_Size i;
    TkMenuEntry *mePtr;

    /*
     * It is not 100% clear that this preserve/release pair is required, but
     * we have added them for safety in this very complex code.
     */

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

    if (winPtr->mainPtr != NULL) {
	nameTablePtr = &(winPtr->mainPtr->nameTable);
    }

    doDot = parentName[strlen(parentName) - 1] != '.';

    childPtr = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1);
    for (destString = Tcl_GetString(childPtr);
    	    *destString != '\0'; destString++) {
    	if (*destString == '.') {
    	    *destString = '#';
    	}
    }

    for (i = 0; ; i++) {
    	if (i == 0) {
	    resultPtr = Tcl_DuplicateObj(parentPtr);
    	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", -1);
    	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
    	} else {
	    Tcl_Obj *intPtr;

	    Tcl_DecrRefCount(resultPtr);
	    resultPtr = Tcl_DuplicateObj(parentPtr);
	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", -1);
	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
	    intPtr = Tcl_NewWideIntObj(i);
	    Tcl_AppendObjToObj(resultPtr, intPtr);
	    Tcl_DecrRefCount(intPtr);
    	}
	destString = Tcl_GetString(resultPtr);
    	if ((Tcl_FindCommand(interp, destString, NULL, 0) == NULL)
		&& ((nameTablePtr == NULL)
		|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
    	    break;
    	}
    }
    Tcl_DecrRefCount(childPtr);
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetWindowMenuBar --
 *
 *	Associates a menu with a window. Called by ConfigureFrame in in
 *	response to a "-menu .foo" configuration option for a top level.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The old menu clones for the menubar are thrown away, and a handler is
 *	set up to allocate the new ones.
 *
 *----------------------------------------------------------------------
 */

void
TkSetWindowMenuBar(
    Tcl_Interp *interp,		/* The interpreter the toplevel lives in. */
    Tk_Window tkwin,		/* The toplevel window. */
    const char *oldMenuName, /* The name of the menubar previously set in
    				 * this toplevel. NULL means no menu was set
    				 * previously. */
    const char *menuName)	/* The name of the new menubar that the
				 * toplevel needs to be set to. NULL means







|











|








|




















|















|







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

    if (winPtr->mainPtr != NULL) {
	nameTablePtr = &(winPtr->mainPtr->nameTable);
    }

    doDot = parentName[strlen(parentName) - 1] != '.';

    childPtr = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), TCL_INDEX_NONE);
    for (destString = Tcl_GetString(childPtr);
    	    *destString != '\0'; destString++) {
    	if (*destString == '.') {
    	    *destString = '#';
    	}
    }

    for (i = 0; ; i++) {
    	if (i == 0) {
	    resultPtr = Tcl_DuplicateObj(parentPtr);
    	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", TCL_INDEX_NONE);
    	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
    	} else {
	    Tcl_Obj *intPtr;

	    Tcl_DecrRefCount(resultPtr);
	    resultPtr = Tcl_DuplicateObj(parentPtr);
	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", TCL_INDEX_NONE);
	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
	    intPtr = Tcl_NewWideIntObj(i);
	    Tcl_AppendObjToObj(resultPtr, intPtr);
	    Tcl_DecrRefCount(intPtr);
    	}
	destString = Tcl_GetString(resultPtr);
    	if ((Tcl_FindCommand(interp, destString, NULL, 0) == NULL)
		&& ((nameTablePtr == NULL)
		|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
    	    break;
    	}
    }
    Tcl_DecrRefCount(childPtr);
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetWindowMenubar --
 *
 *	Associates a menu with a window. Called by ConfigureFrame in in
 *	response to a "-menu .foo" configuration option for a top level.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The old menu clones for the menubar are thrown away, and a handler is
 *	set up to allocate the new ones.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetWindowMenubar(
    Tcl_Interp *interp,		/* The interpreter the toplevel lives in. */
    Tk_Window tkwin,		/* The toplevel window. */
    const char *oldMenuName, /* The name of the menubar previously set in
    				 * this toplevel. NULL means no menu was set
    				 * previously. */
    const char *menuName)	/* The name of the new menubar that the
				 * toplevel needs to be set to. NULL means
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
	menuPtr = menuRefPtr->menuPtr;
	if (menuPtr != NULL) {
	    Tcl_Obj *cloneMenuPtr;
	    TkMenuReferences *cloneMenuRefPtr;
	    Tcl_Obj *newObjv[4];
	    Tcl_Obj *windowNamePtr = Tcl_NewStringObj(Tk_PathName(tkwin),
		    -1);
	    Tcl_Obj *menubarPtr = Tcl_NewStringObj("menubar", -1);

	    /*
	     * Clone the menu and all of the cascades underneath it.
	     */

	    Tcl_IncrRefCount(windowNamePtr);
	    cloneMenuPtr = TkNewMenuName(interp, windowNamePtr,
		    menuPtr);
	    Tcl_IncrRefCount(cloneMenuPtr);
	    Tcl_IncrRefCount(menubarPtr);
	    CloneMenu(menuPtr, cloneMenuPtr, menubarPtr);

	    cloneMenuRefPtr = TkFindMenuReferencesObj(interp, cloneMenuPtr);
	    if ((cloneMenuRefPtr != NULL)
		    && (cloneMenuRefPtr->menuPtr != NULL)) {
		Tcl_Obj *cursorPtr = Tcl_NewStringObj("-cursor", -1);
		Tcl_Obj *nullPtr = Tcl_NewObj();

		cloneMenuRefPtr->menuPtr->parentTopLevelPtr = tkwin;
		menuBarPtr = cloneMenuRefPtr->menuPtr;
		newObjv[0] = cursorPtr;
		newObjv[1] = nullPtr;
		Tcl_IncrRefCount(cursorPtr);







|















|







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
	menuPtr = menuRefPtr->menuPtr;
	if (menuPtr != NULL) {
	    Tcl_Obj *cloneMenuPtr;
	    TkMenuReferences *cloneMenuRefPtr;
	    Tcl_Obj *newObjv[4];
	    Tcl_Obj *windowNamePtr = Tcl_NewStringObj(Tk_PathName(tkwin),
		    -1);
	    Tcl_Obj *menubarPtr = Tcl_NewStringObj("menubar", TCL_INDEX_NONE);

	    /*
	     * Clone the menu and all of the cascades underneath it.
	     */

	    Tcl_IncrRefCount(windowNamePtr);
	    cloneMenuPtr = TkNewMenuName(interp, windowNamePtr,
		    menuPtr);
	    Tcl_IncrRefCount(cloneMenuPtr);
	    Tcl_IncrRefCount(menubarPtr);
	    CloneMenu(menuPtr, cloneMenuPtr, menubarPtr);

	    cloneMenuRefPtr = TkFindMenuReferencesObj(interp, cloneMenuPtr);
	    if ((cloneMenuRefPtr != NULL)
		    && (cloneMenuRefPtr->menuPtr != NULL)) {
		Tcl_Obj *cursorPtr = Tcl_NewStringObj("-cursor", TCL_INDEX_NONE);
		Tcl_Obj *nullPtr = Tcl_NewObj();

		cloneMenuRefPtr->menuPtr->parentTopLevelPtr = tkwin;
		menuBarPtr = cloneMenuRefPtr->menuPtr;
		newObjv[0] = cursorPtr;
		newObjv[1] = nullPtr;
		Tcl_IncrRefCount(cursorPtr);
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
	topLevelListPtr = (TkMenuTopLevelList *)ckalloc(sizeof(TkMenuTopLevelList));
	topLevelListPtr->tkwin = tkwin;
	topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr;
	menuRefPtr->topLevelListPtr = topLevelListPtr;
    } else {
	TkpSetWindowMenuBar(tkwin, NULL);
    }
    TkpSetMainMenubar(interp, tkwin, menuName);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyMenuHashTable --
 *







|







3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
	topLevelListPtr = (TkMenuTopLevelList *)ckalloc(sizeof(TkMenuTopLevelList));
	topLevelListPtr->tkwin = tkwin;
	topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr;
	menuRefPtr->topLevelListPtr = topLevelListPtr;
    } else {
	TkpSetWindowMenuBar(tkwin, NULL);
    }
    Tk_SetMainMenubar(interp, tkwin, menuName);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyMenuHashTable --
 *
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
 *	The hash table is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuHashTable(
    ClientData clientData,	/* The menu hash table we are destroying. */
    Tcl_Interp *dummy)		/* The interpreter we are destroying. */
{
    (void)dummy;

    Tcl_DeleteHashTable((Tcl_HashTable *)clientData);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *







|
|

<
<







3391
3392
3393
3394
3395
3396
3397
3398
3399
3400


3401
3402
3403
3404
3405
3406
3407
 *	The hash table is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuHashTable(
    void *clientData,	/* The menu hash table we are destroying. */
    TCL_UNUSED(Tcl_Interp *))		/* The interpreter we are destroying. */
{


    Tcl_DeleteHashTable((Tcl_HashTable *)clientData);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
DeleteMenuCloneEntries(
    TkMenu *menuPtr,		/* The menu the command was issued with. */
    int	first,			/* The zero-based first entry in the set of
				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    int numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {
	    Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry);
	}
	for (i = last + 1; i < (int)menuListPtr->numEntries; i++) {
	    j = i - numDeleted;
	    menuListPtr->entries[j] = menuListPtr->entries[i];
	    menuListPtr->entries[j]->index = j;
	}
	menuListPtr->numEntries -= numDeleted;
	if (menuListPtr->numEntries == 0) {
	    ckfree(menuListPtr->entries);







|





|

|







3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
DeleteMenuCloneEntries(
    TkMenu *menuPtr,		/* The menu the command was issued with. */
    int	first,			/* The zero-based first entry in the set of
				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    Tcl_Size numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {
	    Tcl_EventuallyFree(menuListPtr->entries[i], DestroyMenuEntry);
	}
	for (i = last + 1; i < menuListPtr->numEntries; i++) {
	    j = i - numDeleted;
	    menuListPtr->entries[j] = menuListPtr->entries[i];
	    menuListPtr->entries[j]->index = j;
	}
	menuListPtr->numEntries -= numDeleted;
	if (menuListPtr->numEntries == 0) {
	    ckfree(menuListPtr->entries);
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
MenuCleanup(
    ClientData dummy)
{
    (void)dummy;

    menusInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --







<
<
|
|







3649
3650
3651
3652
3653
3654
3655


3656
3657
3658
3659
3660
3661
3662
3663
3664
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
MenuCleanup(


    TCL_UNUSED(void *))
{
    menusInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --

Changes to generic/tkMenu.h.

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.
 *
 * 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






|







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 © 1996-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMENU
#define _TKMENU
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    int type;			/* Type of menu entry; see below for valid
				 * types. */
    struct TkMenu *menuPtr;	/* Menu with which this entry is
				 * associated. */
    Tk_OptionTable optionTable;	/* Option table for this menu entry. */
    Tcl_Obj *labelPtr;		/* Main text label displayed in entry (NULL if
				 * no label). */
    TkSizeT labelLength;	/* Number of non-NULL characters in label. */
    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (-1 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or NULL.
				 * If not NULL then label is ignored. */
    Tcl_Obj *imagePtr;		/* Name of image to display, or NULL. If not
				 * NULL, bitmap, text, and textVarName are
				 * ignored. */
    Tk_Image image;		/* Image to display in menu entry, or NULL if
				 * none. */
    Tcl_Obj *selectImagePtr;	/* Name of image to display when selected, or
				 * NULL. */
    Tk_Image selectImage;	/* Image to display in entry when selected, or
				 * NULL if none. Ignored if image is NULL. */
    Tcl_Obj *accelPtr;		/* Accelerator string displayed at right of
				 * menu entry. NULL means no such accelerator.
				 * Malloc'ed. */
    TkSizeT accelLength;	/* Number of non-NULL characters in
				 * accelerator. */
    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */







|




















|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    int type;			/* Type of menu entry; see below for valid
				 * types. */
    struct TkMenu *menuPtr;	/* Menu with which this entry is
				 * associated. */
    Tk_OptionTable optionTable;	/* Option table for this menu entry. */
    Tcl_Obj *labelPtr;		/* Main text label displayed in entry (NULL if
				 * no label). */
    Tcl_Size labelLength;	/* Number of non-NULL characters in label. */
    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (-1 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or NULL.
				 * If not NULL then label is ignored. */
    Tcl_Obj *imagePtr;		/* Name of image to display, or NULL. If not
				 * NULL, bitmap, text, and textVarName are
				 * ignored. */
    Tk_Image image;		/* Image to display in menu entry, or NULL if
				 * none. */
    Tcl_Obj *selectImagePtr;	/* Name of image to display when selected, or
				 * NULL. */
    Tk_Image selectImage;	/* Image to display in entry when selected, or
				 * NULL if none. Ignored if image is NULL. */
    Tcl_Obj *accelPtr;		/* Accelerator string displayed at right of
				 * menu entry. NULL means no such accelerator.
				 * Malloc'ed. */
    Tcl_Size accelLength;	/* Number of non-NULL characters in
				 * accelerator. */
    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */
179
180
181
182
183
184
185

186
187
188
189
190
191
192
     */

    int entryFlags;		/* Various flags. See below for
				 * definitions. */
    int index;			/* Need to know which index we are. This is
    				 * zero-based. This is the top-left entry of
    				 * the menu. */


    /*
     * Bookeeping for main menus and cascade menus.
     */

    struct TkMenuReferences *childMenuRefPtr;
    				/* A pointer to the hash table entry for the







>







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
     */

    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. */
    Tcl_HashEntry *entryPtr;	/* Back-pointer to hash table entry */

    /*
     * Bookeeping for main menus and cascade menus.
     */

    struct TkMenuReferences *childMenuRefPtr;
    				/* A pointer to the hash table entry for the
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#define TEAROFF_ENTRY 5

/*
 * Menu states
 */

#define ENTRY_ACTIVE 0
#define ENTRY_NORMAL 1
#define ENTRY_DISABLED 2

/*
 * A data structure of the following type is kept for each menu widget:
 */

typedef struct TkMenu {
    Tk_Window tkwin;		/* Window that embodies the pane. NULL means
				 * that the window has been destroyed but the
				 * data structures haven't yet been cleaned
				 * up. */
    Display *display;		/* Display containing widget. Needed, among
				 * other things, so that resources can be
				 * freed up even after tkwin has gone away. */
    Tcl_Interp *interp;		/* Interpreter associated with menu. */
    Tcl_Command widgetCmd;	/* Token for menu's widget command. */
    TkMenuEntry **entries;	/* Array of pointers to all the entries in the
				 * menu. NULL means no entries. */
    TkSizeT numEntries;		/* Number of elements in entries. */
    TkSizeT active;			/* Index of active entry. TCL_INDEX_NONE means
				 * nothing active. */
    int menuType;		/* MAIN_MENU, TEAROFF_MENU, or MENUBAR. See
    				 * below for definitions. */
    Tcl_Obj *menuTypePtr;	/* Used to control whether created tkwin is a
				 * toplevel or not. "normal", "menubar", or
				 * "toplevel" */

    /*
     * Information used when displaying widget:
     */

    Tcl_Obj *borderPtr;		/* Structure used to draw 3-D border and
				 * background for menu. */
    Tcl_Obj *borderWidthPtr;	/* Width of border around whole menu. */
    Tcl_Obj *activeBorderPtr;	/* Used to draw background and border for
				 * active element (if any). */
    Tcl_Obj *activeBorderWidthPtr;
				/* Width of border around active element. */
    Tcl_Obj *reliefPtr;		/* 3-d effect: TK_RELIEF_RAISED, etc. */
    Tcl_Obj *fontPtr;		/* Text font for menu entries. */
    Tcl_Obj *fgPtr;		/* Foreground color for entries. */
    Tcl_Obj *disabledFgPtr;	/* Foreground color when disabled. NULL means
				 * use normalFg with a 50% stipple instead. */
    Tcl_Obj *activeFgPtr;	/* Foreground color for active entry. */
    Tcl_Obj *indicatorFgPtr;	/* Color for indicators in radio and check
				 * button entries. */







|
|

















|
|


















|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#define TEAROFF_ENTRY 5

/*
 * Menu states
 */

#define ENTRY_ACTIVE 0
#define ENTRY_DISABLED 1
#define ENTRY_NORMAL 2

/*
 * A data structure of the following type is kept for each menu widget:
 */

typedef struct TkMenu {
    Tk_Window tkwin;		/* Window that embodies the pane. NULL means
				 * that the window has been destroyed but the
				 * data structures haven't yet been cleaned
				 * up. */
    Display *display;		/* Display containing widget. Needed, among
				 * other things, so that resources can be
				 * freed up even after tkwin has gone away. */
    Tcl_Interp *interp;		/* Interpreter associated with menu. */
    Tcl_Command widgetCmd;	/* Token for menu's widget command. */
    TkMenuEntry **entries;	/* Array of pointers to all the entries in the
				 * menu. NULL means no entries. */
    Tcl_Size numEntries;		/* Number of elements in entries. */
    Tcl_Size active;			/* Index of active entry. TCL_INDEX_NONE means
				 * nothing active. */
    int menuType;		/* MAIN_MENU, TEAROFF_MENU, or MENUBAR. See
    				 * below for definitions. */
    Tcl_Obj *menuTypePtr;	/* Used to control whether created tkwin is a
				 * toplevel or not. "normal", "menubar", or
				 * "toplevel" */

    /*
     * Information used when displaying widget:
     */

    Tcl_Obj *borderPtr;		/* Structure used to draw 3-D border and
				 * background for menu. */
    Tcl_Obj *borderWidthPtr;	/* Width of border around whole menu. */
    Tcl_Obj *activeBorderPtr;	/* Used to draw background and border for
				 * active element (if any). */
    Tcl_Obj *activeBorderWidthPtr;
				/* Width of border around active element. */
    int relief;		/* 3-d effect: TK_RELIEF_RAISED, etc. */
    Tcl_Obj *fontPtr;		/* Text font for menu entries. */
    Tcl_Obj *fgPtr;		/* Foreground color for entries. */
    Tcl_Obj *disabledFgPtr;	/* Foreground color when disabled. NULL means
				 * use normalFg with a 50% stipple instead. */
    Tcl_Obj *activeFgPtr;	/* Foreground color for active entry. */
    Tcl_Obj *indicatorFgPtr;	/* Color for indicators in radio and check
				 * button entries. */
375
376
377
378
379
380
381


382
383
384
385
386
387
388
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */
    Tcl_Obj *activeReliefPtr;	/* 3-d effect for active element. */


} TkMenu;

/*
 * When the toplevel configure -menu command is executed, the menu may not
 * exist yet. We need to keep a linked list of windows that reference a
 * particular menu.
 */







>
>







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */
    Tcl_Obj *activeReliefPtr;	/* 3-d effect for active element. */
    Tcl_HashTable items;	/* Map: id -> entry */
    int serial;			/* Next item # for autogenerated ids */
} TkMenu;

/*
 * When the toplevel configure -menu command is executed, the menu may not
 * exist yet. We need to keep a linked list of windows that reference a
 * particular menu.
 */
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
 * a menu bar, a MENUBAR instance is created. All instances have the same
 * configuration information. If the main instance is deleted, all instances
 * are deleted. If one of the other instances is deleted, only that instance
 * is deleted.
 */

#define UNKNOWN_TYPE		-1

#define MAIN_MENU 		0
#define TEAROFF_MENU 		1
#define MENUBAR 		2

/*
 * Various geometry definitions:
 */

#define CASCADE_ARROW_HEIGHT	10
#define CASCADE_ARROW_WIDTH	8
#define DECORATION_BORDER_WIDTH	2

/*
 * Menu-related functions that are shared among Tk modules but not exported to
 * the outside world:
 */

MODULE_SCOPE int	TkActivateMenuEntry(TkMenu *menuPtr, TkSizeT index);
MODULE_SCOPE void	TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr);
MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp,
			    const char *name);
MODULE_SCOPE void	TkDestroyMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkEventuallyRecomputeMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkEventuallyRedrawMenu(TkMenu *menuPtr,
			    TkMenuEntry *mePtr);
MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, const char *name);
MODULE_SCOPE TkMenuReferences*TkFindMenuReferencesObj(Tcl_Interp *interp,
			    Tcl_Obj *namePtr);
MODULE_SCOPE int	TkFreeMenuReferences(TkMenuReferences *menuRefPtr);
MODULE_SCOPE Tcl_HashTable *TkGetMenuHashTable(Tcl_Interp *interp);
MODULE_SCOPE void	TkMenuInitializeDrawingFields(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuInitializeEntryDrawingFields(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkInvokeMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    TkSizeT index);
MODULE_SCOPE void	TkMenuConfigureDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE int	TkMenuConfigureEntryDrawOptions(
			    TkMenuEntry *mePtr, TkSizeT index);
MODULE_SCOPE void	TkMenuFreeDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuEntryFreeDrawOptions(TkMenuEntry *mePtr);
MODULE_SCOPE void	TkMenuEventProc(ClientData clientData,
    			    XEvent *eventPtr);
MODULE_SCOPE void	TkMenuImageProc(ClientData clientData, int x, int y,
			    int width, int height, int imgWidth,
			    int imgHeight);
MODULE_SCOPE void	TkMenuInit(void);
MODULE_SCOPE void	TkMenuSelectImageProc(ClientData clientData, int x,
			    int y, int width, int height, int imgWidth,
			    int imgHeight);
MODULE_SCOPE Tcl_Obj *	TkNewMenuName(Tcl_Interp *interp,
			    Tcl_Obj *parentNamePtr, TkMenu *menuPtr);
MODULE_SCOPE int	TkPostCommand(TkMenu *menuPtr);
MODULE_SCOPE int	TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    TkMenuEntry *mePtr);
MODULE_SCOPE int	TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
					   int x, int y);
MODULE_SCOPE int	TkPreprocessMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkRecomputeMenu(TkMenu *menuPtr);

/*
 * These routines are the platform-dependent routines called by the common
 * code.
 */







>
|
|
<














|















|


|


|

|



|








|







460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
 * a menu bar, a MENUBAR instance is created. All instances have the same
 * configuration information. If the main instance is deleted, all instances
 * are deleted. If one of the other instances is deleted, only that instance
 * is deleted.
 */

#define UNKNOWN_TYPE		-1
#define MENUBAR 		0
#define MAIN_MENU 		1
#define TEAROFF_MENU 		2


/*
 * Various geometry definitions:
 */

#define CASCADE_ARROW_HEIGHT	10
#define CASCADE_ARROW_WIDTH	8
#define DECORATION_BORDER_WIDTH	2

/*
 * Menu-related functions that are shared among Tk modules but not exported to
 * the outside world:
 */

MODULE_SCOPE int	TkActivateMenuEntry(TkMenu *menuPtr, Tcl_Size index);
MODULE_SCOPE void	TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr);
MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp,
			    const char *name);
MODULE_SCOPE void	TkDestroyMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkEventuallyRecomputeMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkEventuallyRedrawMenu(TkMenu *menuPtr,
			    TkMenuEntry *mePtr);
MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, const char *name);
MODULE_SCOPE TkMenuReferences*TkFindMenuReferencesObj(Tcl_Interp *interp,
			    Tcl_Obj *namePtr);
MODULE_SCOPE int	TkFreeMenuReferences(TkMenuReferences *menuRefPtr);
MODULE_SCOPE Tcl_HashTable *TkGetMenuHashTable(Tcl_Interp *interp);
MODULE_SCOPE void	TkMenuInitializeDrawingFields(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuInitializeEntryDrawingFields(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkInvokeMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    Tcl_Size index);
MODULE_SCOPE void	TkMenuConfigureDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE int	TkMenuConfigureEntryDrawOptions(
			    TkMenuEntry *mePtr, Tcl_Size index);
MODULE_SCOPE void	TkMenuFreeDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuEntryFreeDrawOptions(TkMenuEntry *mePtr);
MODULE_SCOPE void	TkMenuEventProc(void *clientData,
    			    XEvent *eventPtr);
MODULE_SCOPE void	TkMenuImageProc(void *clientData, int x, int y,
			    int width, int height, int imgWidth,
			    int imgHeight);
MODULE_SCOPE void	TkMenuInit(void);
MODULE_SCOPE void	TkMenuSelectImageProc(void *clientData, int x,
			    int y, int width, int height, int imgWidth,
			    int imgHeight);
MODULE_SCOPE Tcl_Obj *	TkNewMenuName(Tcl_Interp *interp,
			    Tcl_Obj *parentNamePtr, TkMenu *menuPtr);
MODULE_SCOPE int	TkPostCommand(TkMenu *menuPtr);
MODULE_SCOPE int	TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    TkMenuEntry *mePtr);
MODULE_SCOPE int	TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y);
MODULE_SCOPE int	TkPreprocessMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkRecomputeMenu(TkMenu *menuPtr);

/*
 * These routines are the platform-dependent routines called by the common
 * code.
 */
534
535
536
537
538
539
540
541
542
543
544
545
546
			    const Tk_FontMetrics *menuMetricsPtr, int x,
			    int y, int width, int height, int strictMotif,
			    int drawingParameters);
MODULE_SCOPE void	TkpMenuInit(void);
MODULE_SCOPE int	TkpMenuNewEntry(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkpNewMenu(TkMenu *menuPtr);
MODULE_SCOPE int	TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y, int index);
MODULE_SCOPE int	TkpPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
					   int x, int y, int index);
MODULE_SCOPE void	TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr);

#endif /* _TKMENU */







|

|



537
538
539
540
541
542
543
544
545
546
547
548
549
			    const Tk_FontMetrics *menuMetricsPtr, int x,
			    int y, int width, int height, int strictMotif,
			    int drawingParameters);
MODULE_SCOPE void	TkpMenuInit(void);
MODULE_SCOPE int	TkpMenuNewEntry(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkpNewMenu(TkMenu *menuPtr);
MODULE_SCOPE int	TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y, Tcl_Size index);
MODULE_SCOPE int	TkpPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y, Tcl_Size index);
MODULE_SCOPE void	TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr);

#endif /* _TKMENU */

Changes to generic/tkMenuDraw.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
 * tkMenuDraw.c --
 *
 *	This module implements the platform-independent drawing and geometry
 *	calculations of menu widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenu.h"

/*
 * Forward declarations for functions defined later in this file:
 */

static void		AdjustMenuCoords(TkMenu *menuPtr, TkMenuEntry *mePtr,
			    int *xPtr, int *yPtr);
static void		ComputeMenuGeometry(ClientData clientData);
static void		DisplayMenu(ClientData clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInitializeDrawingFields --
 *
 *	Fills in drawing fields of a new menu. Called when new menu is created






|














|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
 * tkMenuDraw.c --
 *
 *	This module implements the platform-independent drawing and geometry
 *	calculations of menu widgets.
 *
 * 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"

/*
 * Forward declarations for functions defined later in this file:
 */

static void		AdjustMenuCoords(TkMenu *menuPtr, TkMenuEntry *mePtr,
			    int *xPtr, int *yPtr);
static void		ComputeMenuGeometry(void *clientData);
static void		DisplayMenu(void *clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInitializeDrawingFields --
 *
 *	Fills in drawing fields of a new menu. Called when new menu is created
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    TkSizeT index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;

    tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
	    (mePtr->fontPtr != NULL) ? mePtr->fontPtr : menuPtr->fontPtr);

    if (mePtr->state == ENTRY_ACTIVE) {
	if (index != menuPtr->active) {
	    TkActivateMenuEntry(menuPtr, index);
	}
    } else {
	if (index == menuPtr->active) {
	    TkActivateMenuEntry(menuPtr, -1);
	}
    }

    if ((mePtr->fontPtr != NULL)
	    || (mePtr->borderPtr != NULL)
	    || (mePtr->fgPtr != NULL)
	    || (mePtr->activeBorderPtr != NULL)







|
















|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    Tcl_Size index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;

    tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
	    (mePtr->fontPtr != NULL) ? mePtr->fontPtr : menuPtr->fontPtr);

    if (mePtr->state == ENTRY_ACTIVE) {
	if (index != menuPtr->active) {
	    TkActivateMenuEntry(menuPtr, index);
	}
    } else {
	if (index == menuPtr->active) {
	    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
	}
    }

    if ((mePtr->fontPtr != NULL)
	    || (mePtr->borderPtr != NULL)
	    || (mePtr->fgPtr != NULL)
	    || (mePtr->activeBorderPtr != NULL)
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

void
TkEventuallyRedrawMenu(
    TkMenu *menuPtr,	/* Information about menu to redraw. */
    TkMenuEntry *mePtr)/* Entry to redraw. NULL means redraw all the
				 * entries in the menu. */
{
    TkSizeT i;

    if (menuPtr->tkwin == NULL) {
	return;
    }
    if (mePtr != NULL) {
	mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY;
    } else {







|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

void
TkEventuallyRedrawMenu(
    TkMenu *menuPtr,	/* Information about menu to redraw. */
    TkMenuEntry *mePtr)/* Entry to redraw. NULL means redraw all the
				 * entries in the menu. */
{
    Tcl_Size i;

    if (menuPtr->tkwin == NULL) {
	return;
    }
    if (mePtr != NULL) {
	mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY;
    } else {
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
 *	and the size of the menu window itself may be changed.
 *
 *--------------------------------------------------------------
 */

static void
ComputeMenuGeometry(
    ClientData clientData)	/* Structure describing menu. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;

    if (menuPtr->tkwin == NULL) {
	return;
    }








|







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
 *	and the size of the menu window itself may be changed.
 *
 *--------------------------------------------------------------
 */

static void
ComputeMenuGeometry(
    void *clientData)	/* Structure describing menu. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;

    if (menuPtr->tkwin == NULL) {
	return;
    }

575
576
577
578
579
580
581
582
583
584
585
586

587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
 *	Arranges for the menu to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkMenuSelectImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be
				 * <=0). */

    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if ((mePtr->entryFlags & ENTRY_SELECTED)
	    && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) {
	mePtr->menuPtr->menuFlags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayMenu, mePtr->menuPtr);
    }
}







|
|
|
|
|
>
|


<
<
<
<
<
<







575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590






591
592
593
594
595
596
597
 *	Arranges for the menu to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkMenuSelectImageProc(
    void *clientData,	/* Pointer to widget record. */
    TCL_UNUSED(int), /* Upper left pixel (within image) that must */
    TCL_UNUSED(int), /* be redisplayed. */
    TCL_UNUSED(int), /* Dimensions of area to redisplay (may be */
    TCL_UNUSED(int), /* <= 0). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))/* New dimensions of image. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)clientData;







    if ((mePtr->entryFlags & ENTRY_SELECTED)
	    && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) {
	mePtr->menuPtr->menuFlags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayMenu, mePtr->menuPtr);
    }
}
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayMenu(
    ClientData clientData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    Tk_Window tkwin = menuPtr->tkwin;
    TkSizeT index;
    int strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;
    int relief;


    menuPtr->menuFlags &= ~REDRAW_PENDING;
    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }








|




|






<







610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayMenu(
    void *clientData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    Tk_Window tkwin = menuPtr->tkwin;
    Tcl_Size index;
    int strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;



    menuPtr->menuFlags &= ~REDRAW_PENDING;
    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
         * This has zero width except after menu resizing.
         */

	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y,
		width, height, 0, TK_RELIEF_FLAT);
    }

    Tk_GetReliefFromObj(NULL, menuPtr->reliefPtr, &relief);
    Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin),
	    border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth,
	    relief);
}

/*
 *--------------------------------------------------------------
 *
 * TkMenuEventProc --
 *







<


|







727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
         * This has zero width except after menu resizing.
         */

	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y,
		width, height, 0, TK_RELIEF_FLAT);
    }


    Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin),
	    border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth,
	    menuPtr->relief);
}

/*
 *--------------------------------------------------------------
 *
 * TkMenuEventProc --
 *
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

void
TkMenuEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ConfigureNotify) {
	TkEventuallyRecomputeMenu(menuPtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ActivateNotify) {
	if (menuPtr->menuType == TEAROFF_MENU) {
	    TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL);
	}
    } else if (eventPtr->type == DestroyNotify) {
	if (menuPtr->tkwin != NULL) {
	    if (!(menuPtr->menuFlags & MENU_DELETION_PENDING)) {
		TkDestroyMenu(menuPtr);
	    }
	    menuPtr->tkwin = NULL;







|











|







752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

void
TkMenuEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ConfigureNotify) {
	TkEventuallyRecomputeMenu(menuPtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ActivateNotify) {
	if (menuPtr->menuType == TEAROFF_MENU) {
	    Tk_SetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL);
	}
    } else if (eventPtr->type == DestroyNotify) {
	if (menuPtr->tkwin != NULL) {
	    if (!(menuPtr->menuFlags & MENU_DELETION_PENDING)) {
		TkDestroyMenu(menuPtr);
	    }
	    menuPtr->tkwin = NULL;
820
821
822
823
824
825
826
827
828
829
830
831
832

833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
 *	Arranges for the menu to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkMenuImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be
				 * <=0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */

{
    TkMenu *menuPtr = (TkMenu *)((TkMenuEntry *) clientData)->menuPtr;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr);
    }
}








|
|
|
|
|
|
>


<
<
<
<
<
<







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828






829
830
831
832
833
834
835
 *	Arranges for the menu to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkMenuImageProc(
    void *clientData,/* Pointer to widget record. */
    TCL_UNUSED(int), /* Upper left pixel (within image) that must */
    TCL_UNUSED(int), /*		 * be redisplayed. */
    TCL_UNUSED(int), /* Dimensions of area to redisplay (may be */
    TCL_UNUSED(int), /* <=0). */
    TCL_UNUSED(int), /* New dimensions of image. */
    TCL_UNUSED(int))
{
    TkMenu *menuPtr = (TkMenu *)((TkMenuEntry *) clientData)->menuPtr;







    if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr);
    }
}

920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
	 *     posted, in which case the saved information is no longer
	 *     correct.
	 * The simplest solution is just force a complete redisplay of the
	 * parent.
	 */

	subary[0] = menuPtr->postedCascade->namePtr;
	subary[1] = Tcl_NewStringObj("unpost", -1);
	Tcl_IncrRefCount(subary[1]);
	TkEventuallyRedrawMenu(menuPtr, NULL);
	result = Tcl_EvalObjv(interp, 2, subary, 0);
	Tcl_DecrRefCount(subary[1]);
	menuPtr->postedCascade = NULL;
	if (result != TCL_OK) {
	    return result;







|







908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
	 *     posted, in which case the saved information is no longer
	 *     correct.
	 * The simplest solution is just force a complete redisplay of the
	 * parent.
	 */

	subary[0] = menuPtr->postedCascade->namePtr;
	subary[1] = Tcl_NewStringObj("unpost", TCL_INDEX_NONE);
	Tcl_IncrRefCount(subary[1]);
	TkEventuallyRedrawMenu(menuPtr, NULL);
	result = Tcl_EvalObjv(interp, 2, subary, 0);
	Tcl_DecrRefCount(subary[1]);
	menuPtr->postedCascade = NULL;
	if (result != TCL_OK) {
	    return result;
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
	 */

	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);
	AdjustMenuCoords(menuPtr, mePtr, &x, &y);

	menuPtr->postedCascade = mePtr;
	subary[0] = mePtr->namePtr;
	subary[1] = Tcl_NewStringObj("post", -1);
	subary[2] = Tcl_NewWideIntObj(x);
	subary[3] = Tcl_NewWideIntObj(y);
	Tcl_IncrRefCount(subary[1]);
	Tcl_IncrRefCount(subary[2]);
	Tcl_IncrRefCount(subary[3]);
	result = Tcl_EvalObjv(interp, 4, subary, 0);
	Tcl_DecrRefCount(subary[1]);







|







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
	 */

	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);
	AdjustMenuCoords(menuPtr, mePtr, &x, &y);

	menuPtr->postedCascade = mePtr;
	subary[0] = mePtr->namePtr;
	subary[1] = Tcl_NewStringObj("post", TCL_INDEX_NONE);
	subary[2] = Tcl_NewWideIntObj(x);
	subary[3] = Tcl_NewWideIntObj(y);
	Tcl_IncrRefCount(subary[1]);
	Tcl_IncrRefCount(subary[2]);
	Tcl_IncrRefCount(subary[3]);
	result = Tcl_EvalObjv(interp, 4, subary, 0);
	Tcl_DecrRefCount(subary[1]);

Changes to generic/tkMenubutton.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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.
 *
 * 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"






|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkMenubutton.c --
 *
 *	This module implements button-like widgets that are used to invoke
 *	pull-down menus.
 *
 * 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"
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 * is used together with the "enum direction" declaration in tkMenubutton.h.
 */

static const char *const directionStrings[] = {
    "above", "below", "flush", "left", "right", NULL
};

/*
 * The following table defines the legal values for the -state option. It is
 * used together with the "enum state" declaration in tkMenubutton.h.
 */

static const char *const stateStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -compound option. It
 * is used with the "enum compound" declaration in tkMenuButton.h
 */

static const char *const compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

/*
 * Information used for parsing configuration specs:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_MENUBUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, activeBorder), 0,
	(ClientData) DEF_MENUBUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_MENUBUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE,
	 offsetof(TkMenuButton, activeFg),
	 0, DEF_MENUBUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_MENUBUTTON_ANCHOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENUBUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkMenuButton, normalBorder),
	0, DEF_MENUBUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	(ClientData) "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	(ClientData) "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_MENUBUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkMenuButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENUBUTTON_BORDER_WIDTH, TCL_INDEX_NONE,
	offsetof(TkMenuButton, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENUBUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkMenuButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	DEF_MENUBUTTON_DIRECTION, TCL_INDEX_NONE, offsetof(TkMenuButton, direction),
	0, directionStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkMenuButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_MENUBUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, NULL, 0, TCL_INDEX_NONE, 0,
	(ClientData) "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENUBUTTON_FONT, TCL_INDEX_NONE, offsetof(TkMenuButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENUBUTTON_FG, TCL_INDEX_NONE, offsetof(TkMenuButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_MENUBUTTON_HEIGHT, TCL_INDEX_NONE, offsetof(TkMenuButton, heightString),
	0, 0, 0},







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|


|
|


|



|
|
|
|











|



|
|
|







31
32
33
34
35
36
37


















38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 * is used together with the "enum direction" declaration in tkMenubutton.h.
 */

static const char *const directionStrings[] = {
    "above", "below", "flush", "left", "right", NULL
};



















/*
 * Information used for parsing configuration specs:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_MENUBUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, activeBorder), 0,
	DEF_MENUBUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_MENUBUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, activeFg),
	0, DEF_MENUBUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_MENUBUTTON_ANCHOR, TCL_INDEX_NONE,
	offsetof(TkMenuButton, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENUBUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkMenuButton, normalBorder),
	0, DEF_MENUBUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE,
	0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE,
	0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_MENUBUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkMenuButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENUBUTTON_BORDER_WIDTH, TCL_INDEX_NONE,
	offsetof(TkMenuButton, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENUBUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkMenuButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	DEF_MENUBUTTON_DIRECTION, TCL_INDEX_NONE, offsetof(TkMenuButton, direction),
	TK_OPTION_ENUM_VAR, directionStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkMenuButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_MENUBUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, NULL, 0, TCL_INDEX_NONE,
	0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENUBUTTON_FONT, TCL_INDEX_NONE, offsetof(TkMenuButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENUBUTTON_FG, TCL_INDEX_NONE, offsetof(TkMenuButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_MENUBUTTON_HEIGHT, TCL_INDEX_NONE, offsetof(TkMenuButton, heightString),
	0, 0, 0},
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, TCL_INDEX_NONE, offsetof(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkMenuButton, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, TCL_INDEX_NONE, offsetof(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, TCL_INDEX_NONE, offsetof(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, TCL_INDEX_NONE, offsetof(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_MENUBUTTON_STATE, TCL_INDEX_NONE, offsetof(TkMenuButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENUBUTTON_TAKE_FOCUS, TCL_INDEX_NONE,
	offsetof(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, TCL_INDEX_NONE, offsetof(TkMenuButton, text), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MENUBUTTON_TEXT_VARIABLE, TCL_INDEX_NONE,
	offsetof(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_MENUBUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuButton, underline),
	 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, TCL_INDEX_NONE, offsetof(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, TCL_INDEX_NONE, offsetof(TkMenuButton, wrapLength),
	0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}







|













|
|


|








|
|
<







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, TCL_INDEX_NONE, offsetof(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkMenuButton, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, TCL_INDEX_NONE, offsetof(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, TCL_INDEX_NONE, offsetof(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, TCL_INDEX_NONE, offsetof(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_MENUBUTTON_STATE, TCL_INDEX_NONE, offsetof(TkMenuButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENUBUTTON_TAKE_FOCUS, TCL_INDEX_NONE,
	offsetof(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, TCL_INDEX_NONE, offsetof(TkMenuButton, text), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MENUBUTTON_TEXT_VARIABLE, TCL_INDEX_NONE,
	offsetof(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TK_OPTION_UNDERLINE_DEF(TkMenuButton, underline), 0},

    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, TCL_INDEX_NONE, offsetof(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, TCL_INDEX_NONE, offsetof(TkMenuButton, wrapLength),
	0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    COMMAND_CGET, COMMAND_CONFIGURE
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		MenuButtonCmdDeletedProc(ClientData clientData);
static void		MenuButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		MenuButtonImageProc(ClientData clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static char *		MenuButtonTextVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		MenuButtonWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		ConfigureMenuButton(Tcl_Interp *interp,
			    TkMenuButton *mbPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		DestroyMenuButton(char *memPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_MenubuttonObjCmd --
 *
 *	This function is invoked to process the "button", "label",







|
|

|


|


|
<
<



|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167


168
169
170
171
172
173
174
175
176
177
178
    COMMAND_CGET, COMMAND_CONFIGURE
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		MenuButtonCmdDeletedProc(void *clientData);
static void		MenuButtonEventProc(void *clientData,
			    XEvent *eventPtr);
static void		MenuButtonImageProc(void *clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static char *		MenuButtonTextVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static Tcl_ObjCmdProc MenuButtonWidgetObjCmd;


static int		ConfigureMenuButton(Tcl_Interp *interp,
			    TkMenuButton *mbPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		DestroyMenuButton(void *memPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_MenubuttonObjCmd --
 *
 *	This function is invoked to process the "button", "label",
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenubuttonObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;







|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenubuttonObjCmd(
    void *dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    mbPtr->interp = interp;
    mbPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd, mbPtr,
	    MenuButtonCmdDeletedProc);
    mbPtr->optionTable = optionTable;
    mbPtr->menuName = NULL;
    mbPtr->text = NULL;
    mbPtr->underline = -1;
    mbPtr->textVarName = NULL;
    mbPtr->bitmap = None;
    mbPtr->imageString = NULL;
    mbPtr->image = NULL;
    mbPtr->state = STATE_NORMAL;
    mbPtr->normalBorder = NULL;
    mbPtr->activeBorder = NULL;







|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    mbPtr->interp = interp;
    mbPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd, mbPtr,
	    MenuButtonCmdDeletedProc);
    mbPtr->optionTable = optionTable;
    mbPtr->menuName = NULL;
    mbPtr->text = NULL;
    mbPtr->underline = INT_MIN;
    mbPtr->textVarName = NULL;
    mbPtr->bitmap = None;
    mbPtr->imageString = NULL;
    mbPtr->image = NULL;
    mbPtr->state = STATE_NORMAL;
    mbPtr->normalBorder = NULL;
    mbPtr->activeBorder = NULL;
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MenuButtonWidgetObjCmd(
    ClientData clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    int result, index;
    Tcl_Obj *objPtr;







|







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MenuButtonWidgetObjCmd(
    void *clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    int result, index;
    Tcl_Obj *objPtr;
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
 *	Everything associated with the widget is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuButton(
    char *memPtr)		/* Info about button widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *) memPtr;
    TkpDestroyMenuButton(mbPtr);

    if (mbPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayMenuButton, mbPtr);
    }

    /*







|

|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
 *	Everything associated with the widget is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuButton(
    void *memPtr)		/* Info about button widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)memPtr;
    TkpDestroyMenuButton(mbPtr);

    if (mbPtr->flags & REDRAW_PENDING) {
	Tcl_CancelIdleCall(TkpDisplayMenuButton, mbPtr);
    }

    /*
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
    }
    if (mbPtr->gray != None) {
	Tk_FreeBitmap(mbPtr->display, mbPtr->gray);
    }
    if (mbPtr->textLayout != NULL) {
	Tk_FreeTextLayout(mbPtr->textLayout);
    }
    Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, mbPtr->tkwin);
    mbPtr->tkwin = NULL;
    Tcl_EventuallyFree(mbPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *







|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
    }
    if (mbPtr->gray != None) {
	Tk_FreeBitmap(mbPtr->display, mbPtr->gray);
    }
    if (mbPtr->textLayout != NULL) {
	Tk_FreeTextLayout(mbPtr->textLayout);
    }
    Tk_FreeConfigOptions(mbPtr, mbPtr->optionTable, mbPtr->tkwin);
    mbPtr->tkwin = NULL;
    Tcl_EventuallyFree(mbPtr, TCL_DYNAMIC);
}

/*
 *----------------------------------------------------------------------
 *
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
 *	TkMenuButton will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

void
TkMenuButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr = (TkMenuButton *)instanceData;

    gcValues.font = Tk_FontId(mbPtr->tkfont);







|







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
 *	TkMenuButton will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

void
TkMenuButtonWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr = (TkMenuButton *)instanceData;

    gcValues.font = Tk_FontId(mbPtr->tkfont);
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	/*
	 * Must redraw after size changes, since layout could have changed and
	 * borders will need to be redrawn.
	 */

	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	DestroyMenuButton((char *) mbPtr);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    mbPtr->flags |= GOT_FOCUS;
	    if (mbPtr->highlightWidth > 0) {
		goto redraw;
	    }
	}







|














|







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	/*
	 * Must redraw after size changes, since layout could have changed and
	 * borders will need to be redrawn.
	 */

	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	DestroyMenuButton(mbPtr);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    mbPtr->flags |= GOT_FOCUS;
	    if (mbPtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    Tk_Window tkwin = mbPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or







|







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    Tk_Window tkwin = mbPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
 *	variable.
 *
 *--------------------------------------------------------------
 */

static char *
MenuButtonTextVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    const char *value;
    size_t len;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && mbPtr->textVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        mbPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MenuButtonTextVarProc, probe);
                if (probe == (ClientData)mbPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not







|


















|






|







845
846
847
848
849
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
 *	variable.
 *
 *--------------------------------------------------------------
 */

static char *
MenuButtonTextVarProc(
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    const char *value;
    size_t len;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && mbPtr->textVarName) {
            void *probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        mbPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MenuButtonTextVarProc, probe);
                if (probe == (void *)mbPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
MenuButtonImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;







|







933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
MenuButtonImageProc(
    void *clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;

Changes to generic/tkMenubutton.h.

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.
 *
 * 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






|







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 © 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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

    /*
     * Information about what's displayed in the menu button:
     */

    char *text;			/* Text to display in button (malloc'ed) or
				 * NULL. */
    int underline;		/* Index of character to underline. */
    char *textVarName;		/* Name of variable (malloc'ed) or NULL. If
				 * non-NULL, button displays the contents of
				 * this variable. */
    Pixmap bitmap;		/* Bitmap to display or None. If not None then
				 * text and textVar and underline are
				 * ignored. */
    char *imageString;		/* Name of image to display (malloc'ed), or







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

    /*
     * Information about what's displayed in the menu button:
     */

    char *text;			/* Text to display in button (malloc'ed) or
				 * NULL. */
    int underline;		/* Index of character to underline. INT_MIN means no underline */
    char *textVarName;		/* Name of variable (malloc'ed) or NULL. If
				 * non-NULL, button displays the contents of
				 * this variable. */
    Pixmap bitmap;		/* Bitmap to display or None. If not None then
				 * text and textVar and underline are
				 * ignored. */
    char *imageString;		/* Name of image to display (malloc'ed), or
157
158
159
160
161
162
163
164
165
166
167
168
169


170
171
172
173
174
175
176
     * Miscellaneous information:
     */

    int compound;		/* Value of -compound option; specifies
				 * whether the menubutton should show both an
				 * image and text, and, if so, how. */
    enum direction direction;	/* Direction for where to pop the menu. Valid
    				 * directions are "above", "below", "left",
    				 * "right", and "flush". "flush" means that
    				 * the upper left corner of the menubutton is
    				 * where the menu pops up. "above" and "below"
    				 * will attempt to pop the menu compleletly
    				 * above or below the menu respectively.


    				 * "left" and "right" will pop the menu left
    				 * or right, and the active item will be next
    				 * to the button. */
    Tk_Cursor cursor;		/* Current cursor for window, or NULL. */
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */







|
<
<
|
|

>
>







157
158
159
160
161
162
163
164


165
166
167
168
169
170
171
172
173
174
175
176
     * Miscellaneous information:
     */

    int compound;		/* Value of -compound option; specifies
				 * whether the menubutton should show both an
				 * image and text, and, if so, how. */
    enum direction direction;	/* Direction for where to pop the menu. Valid
    				 * directions are "above", "below", "flush",


    				 * "left", and "right". "above" and "below"
    				 * will attempt to pop the menu completely
    				 * above or below the menu respectively.
    				 * "flush" means that the upper left corner
    				 * of the menubutton is where the menu pops up.
    				 * "left" and "right" will pop the menu left
    				 * or right, and the active item will be next
    				 * to the button. */
    Tk_Cursor cursor;		/* Current cursor for window, or NULL. */
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
205
206
207
208
209
210
211
212
213
214
215
216

/*
 * Declaration of procedures used in the implementation of the button widget.
 */

MODULE_SCOPE void	TkpComputeMenuButtonGeometry(TkMenuButton *mbPtr);
MODULE_SCOPE TkMenuButton *TkpCreateMenuButton(Tk_Window tkwin);
MODULE_SCOPE void	TkpDisplayMenuButton(ClientData clientData);
MODULE_SCOPE void 	TkpDestroyMenuButton(TkMenuButton *mbPtr);
MODULE_SCOPE void	TkMenuButtonWorldChanged(ClientData instanceData);

#endif /* _TKMENUBUTTON */







|

|


205
206
207
208
209
210
211
212
213
214
215
216

/*
 * Declaration of procedures used in the implementation of the button widget.
 */

MODULE_SCOPE void	TkpComputeMenuButtonGeometry(TkMenuButton *mbPtr);
MODULE_SCOPE TkMenuButton *TkpCreateMenuButton(Tk_Window tkwin);
MODULE_SCOPE void	TkpDisplayMenuButton(void *clientData);
MODULE_SCOPE void 	TkpDestroyMenuButton(TkMenuButton *mbPtr);
MODULE_SCOPE void	TkMenuButtonWorldChanged(void *instanceData);

#endif /* _TKMENUBUTTON */

Changes to generic/tkMessage.c.

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.
 *
 * 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"







|
|
|







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 © 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"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    Tcl_Command widgetCmd;	/* Token for message's widget command. */

    /*
     * Information used when displaying widget:
     */

    char *string;		/* String displayed in message. */
    int numChars;		/* Number of characters in string, not
				 * including terminating NULL. */
    char *textVarName;		/* Name of variable (malloc'ed) or NULL.
				 * If non-NULL, message displays the contents
				 * of this variable. */
    Tk_3DBorder border;		/* Structure used to draw 3-D border and
				 * background. NULL means a border hasn't been
				 * created yet. */







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    Tcl_Command widgetCmd;	/* Token for message's widget command. */

    /*
     * Information used when displaying widget:
     */

    char *string;		/* String displayed in message. */
    Tcl_Size numChars;		/* Number of characters in string, not
				 * including terminating NULL. */
    char *textVarName;		/* Name of variable (malloc'ed) or NULL.
				 * If non-NULL, message displays the contents
				 * of this variable. */
    Tk_3DBorder border;		/* Structure used to draw 3-D border and
				 * background. NULL means a border hasn't been
				 * created yet. */
82
83
84
85
86
87
88





89
90
91
92
93
94
95

    Tk_Cursor cursor;		/* Current cursor for window, or None. */
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    int flags;			/* Various flags; see below for
				 * definitions. */





} Message;

/*
 * Flag bits for messages:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler
 *				has already been queued to redraw







>
>
>
>
>







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

    Tk_Cursor cursor;		/* Current cursor for window, or None. */
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    int flags;			/* Various flags; see below for
				 * definitions. */
    Tcl_Obj *borderWidthObj;		/* Width of border. */
    Tcl_Obj *highlightWidthObj;		/* Width in pixels of highlight to draw
	     * around widget when it has the focus. <= 0 means don't draw a highlight. */
    Tcl_Obj *widthObj;			/* User-requested width, in pixels. 0 means
				 * compute width using aspect ratio. */
} Message;

/*
 * Flag bits for messages:
 *
 * REDRAW_PENDING:		Non-zero means a DoWhenIdle handler
 *				has already been queued to redraw
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MESSAGE_ANCHOR,
	 TCL_INDEX_NONE, offsetof(Message, anchor), 0, 0, 0},
    {TK_OPTION_INT, "-aspect", "aspect", "Aspect", DEF_MESSAGE_ASPECT,
	 TCL_INDEX_NONE, offsetof(Message, aspect), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_MESSAGE_BG_COLOR, TCL_INDEX_NONE, offsetof(Message, border), 0,
	 DEF_MESSAGE_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_MESSAGE_BORDER_WIDTH, TCL_INDEX_NONE,
	 offsetof(Message, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_MESSAGE_CURSOR, TCL_INDEX_NONE, offsetof(Message, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MESSAGE_FONT, TCL_INDEX_NONE, offsetof(Message, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MESSAGE_FG, TCL_INDEX_NONE, offsetof(Message, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Message, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_MESSAGE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Message, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Message, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MESSAGE_JUSTIFY, TCL_INDEX_NONE, offsetof(Message, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	 DEF_MESSAGE_PADX, offsetof(Message, padXPtr),
	 offsetof(Message, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	 DEF_MESSAGE_PADY, offsetof(Message, padYPtr),
	 offsetof(Message, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MESSAGE_RELIEF, TCL_INDEX_NONE, offsetof(Message, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MESSAGE_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Message, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MESSAGE_TEXT, TCL_INDEX_NONE, offsetof(Message, string), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MESSAGE_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Message, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_MESSAGE_WIDTH, TCL_INDEX_NONE, offsetof(Message, width), 0, 0 ,0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		MessageCmdDeletedProc(ClientData clientData);
static void		MessageEventProc(ClientData clientData,
			    XEvent *eventPtr);
static char *		MessageTextVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		MessageWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		MessageWorldChanged(ClientData instanceData);
static void		ComputeMessageGeometry(Message *msgPtr);
static int		ConfigureMessage(Tcl_Interp *interp, Message *msgPtr,
			    int objc, Tcl_Obj *const objv[], int flags);
static void		DestroyMessage(void *memPtr);
static void		DisplayMessage(ClientData clientData);

/*
 * The structure below defines message class behavior by means of functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs messageClass = {







|










|

















|


|


|


|











|







|
|

|


|
<
<
|




|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181


182
183
184
185
186
187
188
189
190
191
192
193
194

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MESSAGE_ANCHOR,
	 TCL_INDEX_NONE, offsetof(Message, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_INT, "-aspect", "aspect", "Aspect", DEF_MESSAGE_ASPECT,
	 TCL_INDEX_NONE, offsetof(Message, aspect), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_MESSAGE_BG_COLOR, TCL_INDEX_NONE, offsetof(Message, border), 0,
	 DEF_MESSAGE_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_MESSAGE_BORDER_WIDTH, offsetof(Message, borderWidthObj),
	 offsetof(Message, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_MESSAGE_CURSOR, TCL_INDEX_NONE, offsetof(Message, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MESSAGE_FONT, TCL_INDEX_NONE, offsetof(Message, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MESSAGE_FG, TCL_INDEX_NONE, offsetof(Message, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Message, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_MESSAGE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Message, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, offsetof(Message, highlightWidthObj),
	 offsetof(Message, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MESSAGE_JUSTIFY, TCL_INDEX_NONE, offsetof(Message, justify), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	 DEF_MESSAGE_PADX, offsetof(Message, padXPtr),
	 offsetof(Message, padX), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	 DEF_MESSAGE_PADY, offsetof(Message, padYPtr),
	 offsetof(Message, padY), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MESSAGE_RELIEF, TCL_INDEX_NONE, offsetof(Message, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MESSAGE_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Message, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MESSAGE_TEXT, TCL_INDEX_NONE, offsetof(Message, string), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MESSAGE_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Message, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_MESSAGE_WIDTH, offsetof(Message, widthObj), offsetof(Message, width), 0, 0 ,0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		MessageCmdDeletedProc(void *clientData);
static void		MessageEventProc(void *clientData,
			    XEvent *eventPtr);
static char *		MessageTextVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static Tcl_ObjCmdProc MessageWidgetObjCmd;


static void		MessageWorldChanged(void *instanceData);
static void		ComputeMessageGeometry(Message *msgPtr);
static int		ConfigureMessage(Tcl_Interp *interp, Message *msgPtr,
			    int objc, Tcl_Obj *const objv[], int flags);
static void		DestroyMessage(void *memPtr);
static void		DisplayMessage(void *clientData);

/*
 * The structure below defines message class behavior by means of functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs messageClass = {
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MessageObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),







|







<







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MessageObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MessageWidgetObjCmd(
    ClientData clientData,	/* Information about message widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr = (Message *)clientData;
    static const char *const optionStrings[] = { "cget", "configure", NULL };
    enum options { MESSAGE_CGET, MESSAGE_CONFIGURE };







|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MessageWidgetObjCmd(
    void *clientData,	/* Information about message widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr = (Message *)clientData;
    static const char *const optionStrings[] = { "cget", "configure", NULL };
    enum options { MESSAGE_CGET, MESSAGE_CONFIGURE };
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
	Tk_FreeTextLayout(msgPtr->textLayout);
    }
    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(msgPtr->interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }
    Tk_FreeConfigOptions((char *) msgPtr, msgPtr->optionTable, msgPtr->tkwin);
    msgPtr->tkwin = NULL;
    ckfree(msgPtr);
}

/*
 *----------------------------------------------------------------------
 *







|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
	Tk_FreeTextLayout(msgPtr->textLayout);
    }
    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(msgPtr->interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }
    Tk_FreeConfigOptions(msgPtr, msgPtr->optionTable, msgPtr->tkwin);
    msgPtr->tkwin = NULL;
    ckfree(msgPtr);
}

/*
 *----------------------------------------------------------------------
 *
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
static int
ConfigureMessage(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Message *msgPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    Tk_SavedOptions savedOptions;
    (void)flags;

    /*
     * Eliminate any existing trace on a variable monitored by the message.
     */

    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL,







|


<







440
441
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
static int
ConfigureMessage(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Message *msgPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    TCL_UNUSED(int))			/* Flags to pass to Tk_ConfigureWidget. */
{
    Tk_SavedOptions savedOptions;


    /*
     * Eliminate any existing trace on a variable monitored by the message.
     */

    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL,
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503

    /*
     * A few other options need special processing, such as setting the
     * background from a 3-D border or handling special defaults that couldn't
     * be specified to Tk_ConfigureWidget.
     */

    msgPtr->numChars = Tcl_NumUtfChars(msgPtr->string, -1);

    if (msgPtr->highlightWidth < 0) {
	msgPtr->highlightWidth = 0;
    }

    Tk_FreeSavedOptions(&savedOptions);
    MessageWorldChanged(msgPtr);







|







490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

    /*
     * A few other options need special processing, such as setting the
     * background from a 3-D border or handling special defaults that couldn't
     * be specified to Tk_ConfigureWidget.
     */

    msgPtr->numChars = Tcl_NumUtfChars(msgPtr->string, TCL_INDEX_NONE);

    if (msgPtr->highlightWidth < 0) {
	msgPtr->highlightWidth = 0;
    }

    Tk_FreeSavedOptions(&savedOptions);
    MessageWorldChanged(msgPtr);
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
 *	Message will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
MessageWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    Tk_FontMetrics fm;
    Message *msgPtr = (Message *)instanceData;

    if (msgPtr->border != NULL) {







|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
 *	Message will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
MessageWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    Tk_FontMetrics fm;
    Message *msgPtr = (Message *)instanceData;

    if (msgPtr->border != NULL) {
542
543
544
545
546
547
548




549
550
551




552
553
554
555
556
557
558
	Tk_FreeGC(msgPtr->display, msgPtr->textGC);
    }
    msgPtr->textGC = gc;

    Tk_GetFontMetrics(msgPtr->tkfont, &fm);
    if (msgPtr->padX < 0) {
	msgPtr->padX = fm.ascent / 2;




    }
    if (msgPtr->padY == -1) {
	msgPtr->padY = fm.ascent / 4;




    }

    /*
     * Recompute the desired geometry for the window, and arrange for the
     * window to be redisplayed.
     */








>
>
>
>



>
>
>
>







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
	Tk_FreeGC(msgPtr->display, msgPtr->textGC);
    }
    msgPtr->textGC = gc;

    Tk_GetFontMetrics(msgPtr->tkfont, &fm);
    if (msgPtr->padX < 0) {
	msgPtr->padX = fm.ascent / 2;
	if (msgPtr->padXPtr) {
	    Tcl_DecrRefCount(msgPtr->padXPtr);
	    msgPtr->padXPtr = NULL;
	}
    }
    if (msgPtr->padY == -1) {
	msgPtr->padY = fm.ascent / 4;
	if (msgPtr->padYPtr) {
	    Tcl_DecrRefCount(msgPtr->padYPtr);
	    msgPtr->padYPtr = NULL;
	}
    }

    /*
     * Recompute the desired geometry for the window, and arrange for the
     * window to be redisplayed.
     */

662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    ClientData clientData)	/* Information about window. */
{
    Message *msgPtr = (Message *)clientData;
    Tk_Window tkwin = msgPtr->tkwin;
    int x, y;
    int borderWidth = msgPtr->highlightWidth;

    msgPtr->flags &= ~REDRAW_PENDING;







|







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    void *clientData)	/* Information about window. */
{
    Message *msgPtr = (Message *)clientData;
    Tk_Window tkwin = msgPtr->tkwin;
    int x, y;
    int borderWidth = msgPtr->highlightWidth;

    msgPtr->flags &= ~REDRAW_PENDING;
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
    }
    if (msgPtr->highlightWidth != 0) {
	GC fgGC, bgGC;

	bgGC = Tk_GCForColor(msgPtr->highlightBgColorPtr, Tk_WindowId(tkwin));
	if (msgPtr->flags & GOT_FOCUS) {
	    fgGC = Tk_GCForColor(msgPtr->highlightColorPtr,Tk_WindowId(tkwin));
	    TkpDrawHighlightBorder(tkwin, fgGC, bgGC, msgPtr->highlightWidth,
		    Tk_WindowId(tkwin));
	} else {
	    TkpDrawHighlightBorder(tkwin, bgGC, bgGC, msgPtr->highlightWidth,
		    Tk_WindowId(tkwin));
	}
    }
}

/*
 *--------------------------------------------------------------







|


|







717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
    }
    if (msgPtr->highlightWidth != 0) {
	GC fgGC, bgGC;

	bgGC = Tk_GCForColor(msgPtr->highlightBgColorPtr, Tk_WindowId(tkwin));
	if (msgPtr->flags & GOT_FOCUS) {
	    fgGC = Tk_GCForColor(msgPtr->highlightColorPtr,Tk_WindowId(tkwin));
	    Tk_DrawHighlightBorder(tkwin, fgGC, bgGC, msgPtr->highlightWidth,
		    Tk_WindowId(tkwin));
	} else {
	    Tk_DrawHighlightBorder(tkwin, bgGC, bgGC, msgPtr->highlightWidth,
		    Tk_WindowId(tkwin));
	}
    }
}

/*
 *--------------------------------------------------------------
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MessageEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = (Message *)clientData;

    if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
	    || (eventPtr->type == ConfigureNotify)) {
	goto redraw;







|







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MessageEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = (Message *)clientData;

    if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
	    || (eventPtr->type == ConfigureNotify)) {
	goto redraw;
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
MessageCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Message *msgPtr = (Message *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the







|







800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
MessageCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    Message *msgPtr = (Message *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
 *	The text displayed in the message will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
MessageTextVarProc(
    ClientData clientData,	/* Information about message. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    Message *msgPtr = (Message *)clientData;
    const char *value;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && msgPtr->textVarName) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        msgPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MessageTextVarProc, probe);
                if (probe == (ClientData)msgPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not







|

|
|




<
<








|






|







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849


850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
 *	The text displayed in the message will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
MessageTextVarProc(
    void *clientData,	/* Information about message. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),	/* Name of variable. */
    TCL_UNUSED(const char *),	/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    Message *msgPtr = (Message *)clientData;
    const char *value;



    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && msgPtr->textVarName) {
            void *probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        msgPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        MessageTextVarProc, probe);
                if (probe == (void *)msgPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
    value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, -1);
    msgPtr->string = (char *)ckalloc(strlen(value) + 1);
    strcpy(msgPtr->string, value);
    ComputeMessageGeometry(msgPtr);

    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);







|







887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, TCL_INDEX_NONE);
    msgPtr->string = (char *)ckalloc(strlen(value) + 1);
    strcpy(msgPtr->string, value);
    ComputeMessageGeometry(msgPtr);

    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);

Changes to generic/tkObj.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|







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 © 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"

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 * Tcl_ObjTypes that we can use as screen distances without conversion. The
 * "dataKey" below is used to locate the ThreadSpecificData for the current
 * thread.
 */

typedef struct {
    const Tcl_ObjType *doubleTypePtr;
    const Tcl_ObjType *intTypePtr;
    const Tcl_ObjType *endTypePtr;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is the internal representation for mm objects.
 */








<
<







45
46
47
48
49
50
51


52
53
54
55
56
57
58
 * Tcl_ObjTypes that we can use as screen distances without conversion. The
 * "dataKey" below is used to locate the ThreadSpecificData for the current
 * thread.
 */

typedef struct {
    const Tcl_ObjType *doubleTypePtr;


} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is the internal representation for mm objects.
 */

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135


136
137
138
139
140
141
142
143
144
145
146
147
148
149


150
151
152
153
154
155
156
157
158
159
160
161
162


163
164
165
166
167
168
169
static void		FreeWindowInternalRep(Tcl_Obj *objPtr);
static ThreadSpecificData *GetTypeCache(void);
static void		UpdateStringOfMM(Tcl_Obj *objPtr);
static int		SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

#if TCL_MAJOR_VERSION < 9
#if defined(USE_TCL_STUBS)
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntStubs, just
    enough to make it work */
typedef struct TclIntStubs {
    int magic;
    void *hooks;
    void (*dummy[34]) (void); /* dummy entries 0-33, not used */
    int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, int endValue, int *indexPtr); /* 34 */
} TclIntStubs;
extern const struct TclIntStubs *tclIntStubsPtr;

# undef Tcl_GetIntForIndex
# define Tcl_GetIntForIndex(interp, obj, max, ptr) ((tclIntStubsPtr->tclGetIntForIndex == NULL)? \
    ((int (*)(Tcl_Interp*,  Tcl_Obj *, int, int*))(void *)((&(tclStubsPtr->tcl_PkgProvideEx))[645]))((interp), (obj), (max), (ptr)): \
	tclIntStubsPtr->tclGetIntForIndex((interp), (obj), (max), (ptr)))
#elif TCL_MINOR_VERSION < 7
extern int TclGetIntForIndex(Tcl_Interp*,  Tcl_Obj *, int, int*);
# define Tcl_GetIntForIndex(interp, obj, max, ptr) TclGetIntForIndex(interp, obj, max, ptr)
#endif
#endif

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType pixelObjType = {
    "pixel",			/* name */
    FreePixelInternalRep,	/* freeIntRepProc */
    DupPixelInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType mmObjType = {
    "mm",			/* name */
    FreeMMInternalRep,		/* freeIntRepProc */
    DupMMInternalRep,		/* dupIntRepProc */
    UpdateStringOfMM,		/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 * The following structure defines the implementation of the "window"
 * Tcl object.
 */

static const Tcl_ObjType windowObjType = {
    "window",			/* name */
    FreeWindowInternalRep,	/* freeIntRepProc */
    DupWindowInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *----------------------------------------------------------------------
 *
 * GetTypeCache --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
|



|
>
>








|
|



|
>
>







|
|



|
>
>







92
93
94
95
96
97
98























99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
static void		FreeWindowInternalRep(Tcl_Obj *objPtr);
static ThreadSpecificData *GetTypeCache(void);
static void		UpdateStringOfMM(Tcl_Obj *objPtr);
static int		SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
























/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const TkObjType pixelObjType = {
    {"pixel",			/* name */
    FreePixelInternalRep,	/* freeIntRepProc */
    DupPixelInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const TkObjType mmObjType = {
    {"mm",			/* name */
    FreeMMInternalRep,		/* freeIntRepProc */
    DupMMInternalRep,		/* dupIntRepProc */
    UpdateStringOfMM,		/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 * The following structure defines the implementation of the "window"
 * Tcl object.
 */

static const TkObjType windowObjType = {
    {"window",			/* name */
    FreeWindowInternalRep,	/* freeIntRepProc */
    DupWindowInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *----------------------------------------------------------------------
 *
 * GetTypeCache --
 *
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
static ThreadSpecificData *
GetTypeCache(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	/* Smart initialization of doubleTypePtr/intTypePtr without
	 * hash-table lookup or creating complete Tcl_Obj's */
	Tcl_Obj obj;
	obj.bytes = (char *)"end";
	obj.length = 3;
	obj.typePtr = NULL;
	Tcl_GetIntForIndex(NULL, &obj, TCL_INDEX_NONE, (TkSizeT *)&obj.internalRep.doubleValue);
	tsdPtr->endTypePtr = obj.typePtr;
	obj.bytes = (char *)"0.0";
	obj.length = 3;
	obj.typePtr = NULL;
	Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
	tsdPtr->doubleTypePtr = obj.typePtr;
	obj.bytes = (char *)"0";
	obj.length = 1;
	obj.typePtr = NULL;
	Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue);
	tsdPtr->intTypePtr = obj.typePtr;
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetIntForIndex --
 *
 *	Almost the same as Tcl_GetIntForIndex, but it return an int, and it is
 *	more restricted. For example it only accepts "end", not "end-1", and
 *	only "2", not "1+1"
 *
 * Results:
 *	The return value is a standard Tcl object result.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

int
TkGetIntForIndex(
    Tcl_Obj *indexObj,
    TkSizeT end,
    int lastOK,
    TkSizeT *indexPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) {
	return TCL_ERROR;
    }

    if (indexObj->typePtr == tsdPtr->endTypePtr) {

	/* check for "end", but not "end-??" or "end+??" */
	return (*indexPtr == (end + lastOK)) ? TCL_OK :  TCL_ERROR;
    }
    if (indexObj->typePtr != tsdPtr->intTypePtr) {
	/* Neither do we accept "??-??" or "??+??" */
	return TCL_ERROR;
    }
#if TCL_MAJOR_VERSION < 9
    if ((*indexPtr < -1) || (end < -1)) {
	return TCL_ERROR;
    }
#endif
    if ((*indexPtr + 1) > (end + 1)) {
	*indexPtr = end + 1;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|


<

<
<
<

<



<
<
<
<
<









|
|
<













|

|

<
<
|
|
|

>
|
>
|
|
<
<
<
|
|
<
<

<
<
<
<







158
159
160
161
162
163
164
165
166
167

168



169

170
171
172





173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200


201
202
203
204
205
206
207
208
209



210
211


212




213
214
215
216
217
218
219
static ThreadSpecificData *
GetTypeCache(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	/* Smart initialization of doubleTypePtr without
	 * hash-table lookup or creating complete Tcl_Obj's */
	Tcl_Obj obj;

	obj.length = 3;



	obj.bytes = (char *)"0.0";

	obj.typePtr = NULL;
	Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
	tsdPtr->doubleTypePtr = obj.typePtr;





    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetIntForIndex --
 *
 *	Almost the same as Tcl_GetIntForIndex, but it retrieves an int. Accepts
 *	"" (empty string) as well.

 *
 * Results:
 *	The return value is a standard Tcl object result.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

int
TkGetIntForIndex(
    Tcl_Obj *indexObj,
    Tcl_Size end,
    int lastOK,
    Tcl_Size *indexPtr)
{


    if (indexObj == NULL) {
	*indexPtr = TCL_INDEX_NONE;
	return TCL_OK;
    }
    if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) {
	const char *value = Tcl_GetString(indexObj);
	if (!*value) {
	    /* empty string */
	    *indexPtr = (end == -1) ? -1 - TCL_SIZE_MAX : TCL_INDEX_NONE;



	    return TCL_OK;
	}


	return TCL_ERROR;




    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static const double bias[] = {
	1.0,	10.0,	25.4,	0.35278 /*25.4 / 72.0*/
    };

    /*
     * Special hacks where the type of the object is known to be something
     * that is just numeric and cannot require distance conversion. This pokes
     * holes in Tcl's abstractions, but they are just for optimization, not
     * semantics.
     */

    if (objPtr->typePtr != &pixelObjType) {
	ThreadSpecificData *typeCache = GetTypeCache();

	if (objPtr->typePtr == typeCache->doubleTypePtr) {
	    (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
	    if (dblPtr != NULL) {
		*dblPtr = d;
	    }
	    *intPtr = (int) (d<0 ? d-0.5 : d+0.5);
	    return TCL_OK;
	} else if (objPtr->typePtr == typeCache->intTypePtr) {
	    (void) Tcl_GetIntFromObj(interp, objPtr, intPtr);
	    if (dblPtr) {
		*dblPtr = (double) (*intPtr);
	    }
	    return TCL_OK;
	}
    }

 retry:
    fresh = (objPtr->typePtr != &pixelObjType);
    if (fresh) {
	result = SetPixelFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }








<
<
<
<
<
<
<
|
<

<
|




<
<
<
<
<
<





|







247
248
249
250
251
252
253







254

255

256
257
258
259
260






261
262
263
264
265
266
267
268
269
270
271
272
273
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static const double bias[] = {
	1.0,	10.0,	25.4,	0.35278 /*25.4 / 72.0*/
    };








    if (objPtr->typePtr != &pixelObjType.objType) {



	if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
	    if (dblPtr != NULL) {
		*dblPtr = d;
	    }
	    *intPtr = (int) (d<0 ? d-0.5 : d+0.5);






	    return TCL_OK;
	}
    }

 retry:
    fresh = (objPtr->typePtr != &pixelObjType.objType);
    if (fresh) {
	result = SetPixelFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
    double d;
    int result, val;

    result = GetPixelsFromObjEx(interp, tkwin, objPtr, &val, &d);
    if (result != TCL_OK) {
	return result;
    }
    if (objPtr->typePtr == &pixelObjType && !SIMPLE_PIXELREP(objPtr)) {
	PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);

	if (pixelPtr->units >= 0) {
	    /*
	     * Internally "shimmer" to pixel units.
	     */








|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
    double d;
    int result, val;

    result = GetPixelsFromObjEx(interp, tkwin, objPtr, &val, &d);
    if (result != TCL_OK) {
	return result;
    }
    if (objPtr->typePtr == &pixelObjType.objType && !SIMPLE_PIXELREP(objPtr)) {
	PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);

	if (pixelPtr->units >= 0) {
	    /*
	     * Internally "shimmer" to pixel units.
	     */

531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549

550

551

552
553
554
555

556



557


















558
559
560
561
562
563
564
565
566
567
568
569
570
571








572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
 */

static int
SetPixelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{

    const Tcl_ObjType *typePtr;
    const char *string;
    char *rest;
    double d;
    int i, units;

    string = Tcl_GetString(objPtr);

    d = strtod(string, &rest);
    if (rest == string) {
	goto error;
    }

    while ((*rest != '\0') && isspace(UCHAR(*rest))) {

	rest++;

    }

    switch (*rest) {
    case '\0':

	units = -1;



	break;


















    case 'm':
	units = 0;
	break;
    case 'c':
	units = 1;
	break;
    case 'i':
	units = 2;
	break;
    case 'p':
	units = 3;
	break;
    default:
	goto error;








    }

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &pixelObjType;

    i = (int) d;
    if ((units < 0) && (i == d)) {
	SET_SIMPLEPIXEL(objPtr, i);
    } else {
	PixelRep *pixelPtr = (PixelRep *)ckalloc(sizeof(PixelRep));

	pixelPtr->value = d;
	pixelPtr->units = units;
	pixelPtr->tkwin = NULL;
	pixelPtr->returnValue = i;
	SET_COMPLEXPIXEL(objPtr, pixelPtr);
    }
    return TCL_OK;

  error:
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad screen distance \"%.50s\"", string));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetMMFromObj --
 *







>

|




|
|
|
|
<
|
>
|
>
|
>
|
|
<
<
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>











|














<
<
<
<
<
<
<
<







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502


503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574








575
576
577
578
579
580
581
 */

static int
SetPixelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    char *string;
    char *rest;
    double d;
    int i, units;

    if (objPtr->typePtr != typeCache->doubleTypePtr
	    && Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) {
	d = (double) units;
	units = -1;


	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to
	 * ints again from pixel obj types.
	 */

	(void) Tcl_GetString(objPtr);


    } else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
	units = -1;
    } else {
	char savechar;
	string = Tcl_GetString(objPtr);

	rest = string + strlen(string);
	while ((rest > string) && isspace(UCHAR(rest[-1]))) {
	    --rest; /* skip all spaces at the end */
	}
	if (rest > string) {
	    --rest; /* point to the character just before the last space */
	}
	if (rest == string) {
	error:
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"expected screen distance but got \"%.50s\"", string));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	    }
	    return TCL_ERROR;
	}

	switch (*rest) {
	case 'm':
	    units = 0;
	    break;
	case 'c':
	    units = 1;
	    break;
	case 'i':
	    units = 2;
	    break;
	case 'p':
	    units = 3;
	    break;
	default:
	    goto error;
	}
	savechar = *rest;
	*rest = '\0';
	if (Tcl_GetDouble(NULL, string, &d) != TCL_OK) {
	    *rest = savechar;
	    goto error;
	}
	*rest = savechar;
    }

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &pixelObjType.objType;

    i = (int) d;
    if ((units < 0) && (i == d)) {
	SET_SIMPLEPIXEL(objPtr, i);
    } else {
	PixelRep *pixelPtr = (PixelRep *)ckalloc(sizeof(PixelRep));

	pixelPtr->value = d;
	pixelPtr->units = units;
	pixelPtr->tkwin = NULL;
	pixelPtr->returnValue = i;
	SET_COMPLEXPIXEL(objPtr, pixelPtr);
    }
    return TCL_OK;








}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetMMFromObj --
 *
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
    int result;
    double d;
    MMRep *mmPtr;
    static const double bias[] = {
	10.0,	25.4,	1.0,	0.35278 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    mmPtr = (MMRep *)objPtr->internalRep.twoPtrValue.ptr1;







|







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
    int result;
    double d;
    MMRep *mmPtr;
    static const double bias[] = {
	10.0,	25.4,	1.0,	0.35278 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType.objType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    mmPtr = (MMRep *)objPtr->internalRep.twoPtrValue.ptr1;
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

static void
UpdateStringOfMM(
    Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    TkSizeT len;

    mmPtr = (MMRep *)objPtr->internalRep.twoPtrValue.ptr1;
    /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
    if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
	Tcl_Panic("UpdateStringOfMM: false precondition");
    }








|







716
717
718
719
720
721
722
723
724
725
726
727
728
729
730

static void
UpdateStringOfMM(
    Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    size_t len;

    mmPtr = (MMRep *)objPtr->internalRep.twoPtrValue.ptr1;
    /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
    if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
	Tcl_Panic("UpdateStringOfMM: false precondition");
    }

789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816


817


818
819
820
821
822
823
824



825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
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
static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    const char *string;
    char *rest;
    double d;
    int units;
    MMRep *mmPtr;

    if (objPtr->typePtr == typeCache->doubleTypePtr) {
	Tcl_GetDoubleFromObj(interp, objPtr, &d);
	units = -1;
    } else if (objPtr->typePtr == typeCache->intTypePtr) {
	Tcl_GetIntFromObj(interp, objPtr, &units);
	d = (double) units;
	units = -1;

	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to
	 * ints again from mm obj types.
	 */

	(void) Tcl_GetString(objPtr);


    } else {


	/*
	 * It wasn't a known int or double, so parse it.
	 */

	string = Tcl_GetString(objPtr);

	d = strtod(string, &rest);



	if (rest == string) {
	    /*
	     * Must copy string before resetting the result in case a caller
	     * is trying to convert the interpreter's result to mms.
	     */


	error:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad screen distance \"%s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "DISTANCE", NULL);
	    return TCL_ERROR;
	}
	while ((*rest != '\0') && isspace(UCHAR(*rest))) {
	    rest++;
	}

	switch (*rest) {
	case '\0':
	    units = -1;
	    break;
	case 'c':
	    units = 0;
	    break;
	case 'i':
	    units = 1;
	    break;
	case 'm':
	    units = 2;
	    break;
	case 'p':
	    units = 3;
	    break;
	default:
	    goto error;
	}







    }

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &mmObjType;

    mmPtr = (MMRep *)ckalloc(sizeof(MMRep));
    mmPtr->value = d;
    mmPtr->units = units;
    mmPtr->tkwin = NULL;
    mmPtr->returnValue	= d;








|





|
<
<
<
|










>
>

>
>






|
>
>
>
|
<
|
<
<
|
>


|
|


<
<
<
<

<
<
<















>
>
>
>
>
>
>











|







758
759
760
761
762
763
764
765
766
767
768
769
770
771



772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798

799


800
801
802
803
804
805
806
807




808



809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    char *string;
    char *rest;
    double d;
    int units;
    MMRep *mmPtr;

    if (objPtr->typePtr != typeCache->doubleTypePtr



	    && Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) {
	d = (double) units;
	units = -1;

	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to
	 * ints again from mm obj types.
	 */

	(void) Tcl_GetString(objPtr);
    } else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
	units = -1;
    } else {
	char savechar;

	/*
	 * It wasn't a known int or double, so parse it.
	 */

	string = Tcl_GetString(objPtr);

	rest = string + strlen(string);
	while ((rest > string) && isspace(UCHAR(rest[-1]))) {
	    --rest; /* skip all spaces at the end */
	}
	if (rest > string) {

	    --rest; /* point to the character just before the last space */


	}
	if (rest == string) {
	error:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "expected screen distance but got \"%.50s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	    return TCL_ERROR;
	}




	switch (*rest) {



	case 'c':
	    units = 0;
	    break;
	case 'i':
	    units = 1;
	    break;
	case 'm':
	    units = 2;
	    break;
	case 'p':
	    units = 3;
	    break;
	default:
	    goto error;
	}
	savechar = *rest;
	*rest = '\0';
	if (Tcl_GetDouble(NULL, string, &d) != TCL_OK) {
	    *rest = savechar;
	    goto error;
	}
	*rest = savechar;
    }

    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &mmObjType.objType;

    mmPtr = (MMRep *)ckalloc(sizeof(MMRep));
    mmPtr->value = d;
    mmPtr->units = units;
    mmPtr->tkwin = NULL;
    mmPtr->returnValue	= d;

908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
    Tk_Window tkwin,		/* A token to get the main window from. */
    Tcl_Obj *objPtr,		/* The object from which to get window. */
    Tk_Window *windowPtr)	/* Place to store resulting window. */
{
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    if (objPtr->typePtr != &windowObjType) {
	int result = SetWindowFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    winPtr = (WindowRep *)objPtr->internalRep.twoPtrValue.ptr1;







|







879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
    Tk_Window tkwin,		/* A token to get the main window from. */
    Tcl_Obj *objPtr,		/* The object from which to get window. */
    Tk_Window *windowPtr)	/* Place to store resulting window. */
{
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    if (objPtr->typePtr != &windowObjType.objType) {
	int result = SetWindowFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    winPtr = (WindowRep *)objPtr->internalRep.twoPtrValue.ptr1;
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997

    winPtr = (WindowRep *)ckalloc(sizeof(WindowRep));
    winPtr->tkwin = NULL;
    winPtr->mainPtr = NULL;
    winPtr->epoch = 0;

    objPtr->internalRep.twoPtrValue.ptr1 = winPtr;
    objPtr->typePtr = &windowObjType;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|







954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

    winPtr = (WindowRep *)ckalloc(sizeof(WindowRep));
    winPtr->tkwin = NULL;
    winPtr->mainPtr = NULL;
    winPtr->epoch = 0;

    objPtr->internalRep.twoPtrValue.ptr1 = winPtr;
    objPtr->typePtr = &windowObjType.objType;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
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
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NewWindowObj --
 *
 *	This function allocates a new Tcl_Obj that refers to a particular to a
 *	particular Tk window.
 *
 * Results:
 *	A standard Tcl object reference, with refcount 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_NewWindowObj(
    Tk_Window tkwin)
{
    Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    SetWindowFromAny(NULL, objPtr);

    winPtr = (WindowRep *)objPtr->internalRep.twoPtrValue.ptr1;
    winPtr->tkwin = tkwin;







|
|














|







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_NewWindowObj --
 *
 *	This function allocates a new Tcl_Obj that refers to a particular
 *	Tk window.
 *
 * Results:
 *	A standard Tcl object reference, with refcount 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_NewWindowObj(
    Tk_Window tkwin)
{
    Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), TCL_INDEX_NONE);
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    SetWindowFromAny(NULL, objPtr);

    winPtr = (WindowRep *)objPtr->internalRep.twoPtrValue.ptr1;
    winPtr->tkwin = tkwin;
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
    Tk_Window tkwin,		/* A window.  Needed by Tk_GetPixels() */
    Tcl_Obj *specObj,		/* The argument to "-padx", "-pady", "-ipadx",
				 * or "-ipady". The thing to be parsed. */
    int *halfPtr,		/* Write the left/top part of padding here */
    int *allPtr)		/* Write the total padding here */
{
    int firstInt, secondInt;    /* The two components of the padding */
    int objc;			/* The length of the list (should be 1 or 2) */
    Tcl_Obj **objv;		/* The objects in the list */

    /*
     * Check for a common case where a single object would otherwise be
     * shimmered between a list and a pixel spec.
     */

    if (specObj->typePtr == &pixelObjType) {
	if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK){
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad pad value \"%s\": must be positive screen distance",
		    Tcl_GetString(specObj)));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
	    return TCL_ERROR;
	}







|







|







1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
    Tk_Window tkwin,		/* A window.  Needed by Tk_GetPixels() */
    Tcl_Obj *specObj,		/* The argument to "-padx", "-pady", "-ipadx",
				 * or "-ipady". The thing to be parsed. */
    int *halfPtr,		/* Write the left/top part of padding here */
    int *allPtr)		/* Write the total padding here */
{
    int firstInt, secondInt;    /* The two components of the padding */
    Tcl_Size objc;			/* The length of the list (should be 1 or 2) */
    Tcl_Obj **objv;		/* The objects in the list */

    /*
     * Check for a common case where a single object would otherwise be
     * shimmered between a list and a pixel spec.
     */

    if (specObj->typePtr == &pixelObjType.objType) {
	if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK){
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad pad value \"%s\": must be positive screen distance",
		    Tcl_GetString(specObj)));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL);
	    return TCL_ERROR;
	}
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
     */

    if (Tcl_ListObjGetElements(interp, specObj, &objc, &objv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (objc != 1 && objc != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"wrong number of parts to pad specification", -1));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "PARTS", NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the first part.
     */







|







1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
     */

    if (Tcl_ListObjGetElements(interp, specObj, &objc, &objv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (objc != 1 && objc != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"wrong number of parts to pad specification", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "PARTS", NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the first part.
     */
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
 *
 *----------------------------------------------------------------------
 */

void
TkRegisterObjTypes(void)
{
    Tcl_RegisterObjType(&tkBorderObjType);
    Tcl_RegisterObjType(&tkBitmapObjType);
    Tcl_RegisterObjType(&tkColorObjType);
    Tcl_RegisterObjType(&tkCursorObjType);
    Tcl_RegisterObjType(&tkFontObjType);
    Tcl_RegisterObjType(&mmObjType);
    Tcl_RegisterObjType(&pixelObjType);
    Tcl_RegisterObjType(&tkStateKeyObjType);
    Tcl_RegisterObjType(&windowObjType);
    Tcl_RegisterObjType(&tkTextIndexType);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|
|
|
|
|
|
|
|
<









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
 *
 *----------------------------------------------------------------------
 */

void
TkRegisterObjTypes(void)
{
    Tcl_RegisterObjType(&tkBorderObjType.objType);
    Tcl_RegisterObjType(&tkBitmapObjType.objType);
    Tcl_RegisterObjType(&tkColorObjType.objType);
    Tcl_RegisterObjType(&tkCursorObjType.objType);
    Tcl_RegisterObjType(&tkFontObjType.objType);
    Tcl_RegisterObjType(&mmObjType.objType);
    Tcl_RegisterObjType(&pixelObjType.objType);
    Tcl_RegisterObjType(&tkStateKeyObjType.objType);
    Tcl_RegisterObjType(&windowObjType.objType);

}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkOldConfig.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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * Values for "flags" field of Tk_ConfigSpec structures. Be sure to coordinate
 * these values with those defined in tk.h (TK_CONFIG_COLOR_ONLY, etc.) There
 * must not be overlap!
 *
 * INIT -		Non-zero means (char *) things have been converted to
 *			Tk_Uid's.
 */

#define INIT		0x20

#ifndef TK_CONFIG_OPTION_SPECIFIED
#  define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)
#endif





/*
 * Forward declarations for functions defined later in this file:
 */

static int		DoConfig(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_ConfigSpec *specPtr, Tk_Uid value,
			    int valueIsUid, void *widgRec);
static Tk_ConfigSpec *	FindConfigSpec(Tcl_Interp *interp,
			    Tk_ConfigSpec *specs, const char *argvName,
			    int needFlags, int hateFlags);
static char *		FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *widgRec);
static const char *	FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *widgRec,
			    char *buffer, Tcl_FreeProc **freeProcPtr);
static Tk_ConfigSpec *	GetCachedSpecs(Tcl_Interp *interp,
			    const Tk_ConfigSpec *staticSpecs);
static void		DeleteSpecCacheTable(ClientData clientData,
			    Tcl_Interp *interp);

/*
 *--------------------------------------------------------------
 *
 * Tk_ConfigureWidget --
 *
 *	Process command-line options and database options to fill in fields of
 *	a widget record with resources and other parameters.
 *
 * Results:
 *	A standard Tcl return value. In case of an error, the interp's result
 *	will hold an error message.
 *
 * Side effects:
 *	The fields of widgRec get filled in with information from argc/argv
 *	and the option database. Old information in widgRec's fields gets
 *	recycled. A copy of the spec-table is taken with (some of) the char*
 *	fields converted into Tk_Uid fields; this copy will be released when
 *	the interpreter terminates.
 *
 *--------------------------------------------------------------
 */

int
Tk_ConfigureWidget(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window containing widget (needed to set up
				 * X resources). */
    const Tk_ConfigSpec *specs,	/* Describes legal options. */
    int argc,			/* Number of elements in argv. */
    const char **argv,		/* Command-line options. */
    char *widgRec,		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. Also, may have
				 * TK_CONFIG_ARGV_ONLY set. */
{
    Tk_ConfigSpec *specPtr, *staticSpecs;
    Tk_Uid value;		/* Value of option from database. */
    int needFlags;		/* Specs must contain this set of flags or
				 * else they are not considered. */
    int hateFlags;		/* If a spec contains any bits here, it's not
				 * considered. */

    if (tkwin == NULL) {
	/*
	 * Either we're not really in Tk, or the main window was destroyed and
	 * we're on our way out of the application
	 */

	Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window", -1));
	Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
	return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {







|
|











<
<
<


<
<



>
>
>
>


















|















|














|
|
|



















|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20



21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * 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 © 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"

/*
 * Values for "flags" field of Tk_ConfigSpec structures. Be sure to coordinate
 * these values with those defined in tk.h (TK_CONFIG_COLOR_ONLY, etc.) There
 * must not be overlap!



 */



#ifndef TK_CONFIG_OPTION_SPECIFIED
#  define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)
#endif

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static int		DoConfig(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_ConfigSpec *specPtr, Tk_Uid value,
			    int valueIsUid, void *widgRec);
static Tk_ConfigSpec *	FindConfigSpec(Tcl_Interp *interp,
			    Tk_ConfigSpec *specs, const char *argvName,
			    int needFlags, int hateFlags);
static char *		FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *widgRec);
static const char *	FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *widgRec,
			    char *buffer, Tcl_FreeProc **freeProcPtr);
static Tk_ConfigSpec *	GetCachedSpecs(Tcl_Interp *interp,
			    const Tk_ConfigSpec *staticSpecs);
static void		DeleteSpecCacheTable(void *clientData,
			    Tcl_Interp *interp);

/*
 *--------------------------------------------------------------
 *
 * Tk_ConfigureWidget --
 *
 *	Process command-line options and database options to fill in fields of
 *	a widget record with resources and other parameters.
 *
 * Results:
 *	A standard Tcl return value. In case of an error, the interp's result
 *	will hold an error message.
 *
 * Side effects:
 *	The fields of widgRec get filled in with information from objc/objv
 *	and the option database. Old information in widgRec's fields gets
 *	recycled. A copy of the spec-table is taken with (some of) the char*
 *	fields converted into Tk_Uid fields; this copy will be released when
 *	the interpreter terminates.
 *
 *--------------------------------------------------------------
 */

int
Tk_ConfigureWidget(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window containing widget (needed to set up
				 * X resources). */
    const Tk_ConfigSpec *specs,	/* Describes legal options. */
    Tcl_Size objc,			/* Number of elements in objv. */
    Tcl_Obj *const *objv,		/* Command-line options. */
    void *widgRec,		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. Also, may have
				 * TK_CONFIG_ARGV_ONLY set. */
{
    Tk_ConfigSpec *specPtr, *staticSpecs;
    Tk_Uid value;		/* Value of option from database. */
    int needFlags;		/* Specs must contain this set of flags or
				 * else they are not considered. */
    int hateFlags;		/* If a spec contains any bits here, it's not
				 * considered. */

    if (tkwin == NULL) {
	/*
	 * Either we're not really in Tk, or the main window was destroyed and
	 * we're on our way out of the application
	 */

	Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", (char *)NULL);
	return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    }

    /*
     * Pass one: scan through all of the arguments, processing those that
     * match entries in the specs.
     */

    for ( ; argc > 0; argc -= 2, argv += 2) {
	const char *arg;

	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) *argv);
	} else {
	    arg = *argv;
	}
	specPtr = FindConfigSpec(interp, staticSpecs, arg, needFlags, hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}

	/*
	 * Process the entry.
	 */

	if (argc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", arg));
	    Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", NULL);
	    return TCL_ERROR;
	}
	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) argv[1]);
	} else {
	    arg = argv[1];
	}
	if (DoConfig(interp, tkwin, specPtr, arg, 0, widgRec) != TCL_OK) {
	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (processing \"%.40s\" option)",specPtr->argvName));
	    return TCL_ERROR;
	}
	if (!(flags & TK_CONFIG_ARGV_ONLY)) {
	    specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED;







|


<
|
<
<
<









|


|


<
|
<
<
<







121
122
123
124
125
126
127
128
129
130

131



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

147



148
149
150
151
152
153
154
    }

    /*
     * Pass one: scan through all of the arguments, processing those that
     * match entries in the specs.
     */

    for ( ; objc > 0; objc -= 2, objv += 2) {
	const char *arg;


	arg = Tcl_GetString(*objv);



	specPtr = FindConfigSpec(interp, staticSpecs, arg, needFlags, hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}

	/*
	 * Process the entry.
	 */

	if (objc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", arg));
	    Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", (char *)NULL);
	    return TCL_ERROR;
	}

	arg = Tcl_GetString(objv[1]);



	if (DoConfig(interp, tkwin, specPtr, arg, 0, widgRec) != TCL_OK) {
	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (processing \"%.40s\" option)",specPtr->argvName));
	    return TCL_ERROR;
	}
	if (!(flags & TK_CONFIG_ARGV_ONLY)) {
	    specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED;
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
	if (specPtr->argvName[length] == 0) {
	    matchPtr = specPtr;
	    goto gotMatch;
	}
	if (matchPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "ambiguous option \"%s\"", argvName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName,NULL);
	    return NULL;
	}
	matchPtr = specPtr;
    }

    if (matchPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown option \"%s\"", argvName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, NULL);
	return NULL;
    }

    /*
     * Found a matching entry. If it's a synonym, then find the entry that
     * it's a synonym for.
     */

  gotMatch:
    specPtr = matchPtr;
    if (specPtr->type == TK_CONFIG_SYNONYM) {
	for (specPtr = specs; ; specPtr++) {
	    if (specPtr->type == TK_CONFIG_END) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't find synonym for option \"%s\"",
			argvName));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName,
			NULL);
		return NULL;
	    }
	    if ((specPtr->dbName == matchPtr->dbName)
		    && (specPtr->type != TK_CONFIG_SYNONYM)
		    && ((specPtr->specFlags & needFlags) == needFlags)
		    && !(specPtr->specFlags & hateFlags)) {
		break;







|








|

















|







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	if (specPtr->argvName[length] == 0) {
	    matchPtr = specPtr;
	    goto gotMatch;
	}
	if (matchPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "ambiguous option \"%s\"", argvName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, (char *)NULL);
	    return NULL;
	}
	matchPtr = specPtr;
    }

    if (matchPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown option \"%s\"", argvName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, (char *)NULL);
	return NULL;
    }

    /*
     * Found a matching entry. If it's a synonym, then find the entry that
     * it's a synonym for.
     */

  gotMatch:
    specPtr = matchPtr;
    if (specPtr->type == TK_CONFIG_SYNONYM) {
	for (specPtr = specs; ; specPtr++) {
	    if (specPtr->type == TK_CONFIG_END) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't find synonym for option \"%s\"",
			argvName));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName,
			(char *)NULL);
		return NULL;
	    }
	    if ((specPtr->dbName == matchPtr->dbName)
		    && (specPtr->type != TK_CONFIG_SYNONYM)
		    && ((specPtr->specFlags & needFlags) == needFlags)
		    && !(specPtr->specFlags & hateFlags)) {
		break;
348
349
350
351
352
353
354
355
356
357
358
359



360
361
362
363
364
365
366
				 * Values must be properly initialized. */
{
    void *ptr;
    Tk_Uid uid;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) {
	nullValue = 1;
    }

    do {



	ptr = (char *)widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;







|




>
>
>







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
				 * Values must be properly initialized. */
{
    void *ptr;
    Tk_Uid uid;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & (TK_CONFIG_NULL_OK|TCL_NULL_OK))) {
	nullValue = 1;
    }

    do {
	if (specPtr->offset < 0) {
	    break;
	}
	ptr = (char *)widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
		    interp, tkwin, value, (char *)widgRec, specPtr->offset)!=TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	default:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad config table: unknown type %d", specPtr->type));
	    Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", NULL);
	    return TCL_ERROR;
	}
	specPtr++;
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
    return TCL_OK;
}








|







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
		    interp, tkwin, value, (char *)widgRec, specPtr->offset)!=TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	default:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad config table: unknown type %d", specPtr->type));
	    Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", (char *)NULL);
	    return TCL_ERROR;
	}
	specPtr++;
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
    return TCL_OK;
}

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
 */

int
Tk_ConfigureInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    const Tk_ConfigSpec *specs, /* Describes legal options. */
    char *widgRec,		/* Record whose fields contain current values
				 * for options. */
    const char *argvName,	/* If non-NULL, indicates a single option
				 * whose info is to be returned. Otherwise
				 * info is returned for all options. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */







|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
 */

int
Tk_ConfigureInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    const Tk_ConfigSpec *specs, /* Describes legal options. */
    void *widgRec,		/* Record whose fields contain current values
				 * for options. */
    const char *argvName,	/* If non-NULL, indicates a single option
				 * whose info is to be returned. Otherwise
				 * info is returned for all options. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
    if (argvName != NULL) {
	specPtr = FindConfigSpec(interp, staticSpecs, argvName, needFlags,
		hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}
	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_SetObjResult(interp, Tcl_NewStringObj(list, -1));
	ckfree(list);
	return TCL_OK;
    }

    /*
     * Loop through all the specs, creating a big list with all their
     * information.
     */

    for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((argvName != NULL) && (specPtr->argvName != argvName)) {
	    continue;
	}
	if (((specPtr->specFlags & needFlags) != needFlags)
		|| (specPtr->specFlags & hateFlags)) {
	    continue;
	}
	if (specPtr->argvName == NULL) {
	    continue;
	}
	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_AppendResult(interp, leader, list, "}", NULL);
	ckfree(list);
	leader = " {";
    }
    return TCL_OK;
}

/*







|

















|



|







628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
    if (argvName != NULL) {
	specPtr = FindConfigSpec(interp, staticSpecs, argvName, needFlags,
		hateFlags);
	if (specPtr == NULL) {
	    return TCL_ERROR;
	}
	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_SetObjResult(interp, Tcl_NewStringObj(list, TCL_INDEX_NONE));
	ckfree(list);
	return TCL_OK;
    }

    /*
     * Loop through all the specs, creating a big list with all their
     * information.
     */

    for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((argvName != NULL) && (specPtr->argvName != argvName)) {
	    continue;
	}
	if (((specPtr->specFlags & needFlags) != needFlags)
		|| (specPtr->specFlags & hateFlags)) {
	    continue;
	}
	if ((specPtr->argvName == NULL) || (specPtr->offset < 0)) {
	    continue;
	}
	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_AppendResult(interp, leader, list, "}", (char *)NULL);
	ckfree(list);
	leader = " {";
    }
    return TCL_OK;
}

/*
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
	argv[3] = "";
    }
    if (argv[4] == NULL) {
	argv[4] = "";
    }
    result = Tcl_Merge(5, argv);
    if (freeProc != NULL) {
	if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
	    ckfree((char *) argv[4]);
	} else {
	    freeProc((char *) argv[4]);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------







|
|

|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
	argv[3] = "";
    }
    if (argv[4] == NULL) {
	argv[4] = "";
    }
    result = Tcl_Merge(5, argv);
    if (freeProc != NULL) {
	if (freeProc == TCL_DYNAMIC) {
	    ckfree((char *)argv[4]);
	} else {
	    freeProc((char *)argv[4]);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
767
768
769
770
771
772
773



774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
				 * function to free the result, or NULL if
				 * result is static. */
{
    void *ptr;
    const char *result;

    *freeProcPtr = NULL;



    ptr = (char *)widgRec + specPtr->offset;
    result = "";
    switch (specPtr->type) {
    case TK_CONFIG_BOOLEAN:
	if (*((int *)ptr) == 0) {
	    result = "0";
	} else {
	    result = "1";
	}
	break;
    case TK_CONFIG_INT:
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:







>
>
>











|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
				 * function to free the result, or NULL if
				 * result is static. */
{
    void *ptr;
    const char *result;

    *freeProcPtr = NULL;
    if (specPtr->offset < 0) {
	return NULL;
    }
    ptr = (char *)widgRec + specPtr->offset;
    result = "";
    switch (specPtr->type) {
    case TK_CONFIG_BOOLEAN:
	if (*((int *)ptr) == 0) {
	    result = "0";
	} else {
	    result = "1";
	}
	break;
    case TK_CONFIG_INT:
	snprintf(buffer, 200, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
    case TK_CONFIG_CAP_STYLE:
	result = Tk_NameOfCapStyle(*((int *)ptr));
	break;
    case TK_CONFIG_JOIN_STYLE:
	result = Tk_NameOfJoinStyle(*((int *)ptr));
	break;
    case TK_CONFIG_PIXELS:
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_MM:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_WINDOW: {







|







853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
    case TK_CONFIG_CAP_STYLE:
	result = Tk_NameOfCapStyle(*((int *)ptr));
	break;
    case TK_CONFIG_JOIN_STYLE:
	result = Tk_NameOfJoinStyle(*((int *)ptr));
	break;
    case TK_CONFIG_PIXELS:
	snprintf(buffer, 200, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_MM:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_WINDOW: {
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
 */

int
Tk_ConfigureValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    const Tk_ConfigSpec *specs, /* Describes legal options. */
    char *widgRec,		/* Record whose fields contain current values
				 * for options. */
    const char *argvName,	/* Gives the command-line name for the option
				 * whose value is to be returned. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
{







|







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
 */

int
Tk_ConfigureValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    const Tk_ConfigSpec *specs, /* Describes legal options. */
    void *widgRec,		/* Record whose fields contain current values
				 * for options. */
    const char *argvName,	/* Gives the command-line name for the option
				 * whose value is to be returned. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
{
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

    specPtr = FindConfigSpec(interp, specPtr, argvName, needFlags, hateFlags);
    if (specPtr == NULL) {
	return TCL_ERROR;
    }
    result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
	    &freeProc);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
    if (freeProc != NULL) {
	if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
	    ckfree((char *) result);
	} else {
	    freeProc((char *) result);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|

|
|

|







935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954

    specPtr = FindConfigSpec(interp, specPtr, argvName, needFlags, hateFlags);
    if (specPtr == NULL) {
	return TCL_ERROR;
    }
    result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
	    &freeProc);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(result, TCL_INDEX_NONE));
    if (freeProc != NULL) {
	if (freeProc == TCL_DYNAMIC) {
	    ckfree((char *)result);
	} else {
	    freeProc((char *)result);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeOptions(
    const Tk_ConfigSpec *specs,	/* Describes legal options. */
    char *widgRec,		/* Record whose fields contain current values
				 * for options. */
    Display *display,		/* X display; needed for freeing some
				 * resources. */
    int needFlags)		/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
{
    const Tk_ConfigSpec *specPtr;
    char *ptr;

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((specPtr->specFlags & needFlags) != needFlags) {
	    continue;
	}



	ptr = widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_STRING:
	    if (*((char **) ptr) != NULL) {
		ckfree(*((char **) ptr));
		*((char **) ptr) = NULL;
	    }
	    break;







|














>
>
>
|







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
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeOptions(
    const Tk_ConfigSpec *specs,	/* Describes legal options. */
    void *widgRec,		/* Record whose fields contain current values
				 * for options. */
    Display *display,		/* X display; needed for freeing some
				 * resources. */
    int needFlags)		/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
{
    const Tk_ConfigSpec *specPtr;
    char *ptr;

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((specPtr->specFlags & needFlags) != needFlags) {
	    continue;
	}
	if (specPtr->offset < 0) {
	    continue;
	}
	ptr = (char *)widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_STRING:
	    if (*((char **) ptr) != NULL) {
		ckfree(*((char **) ptr));
		*((char **) ptr) = NULL;
	    }
	    break;
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
 *	None (does *not* use any Tk API).
 *
 *--------------------------------------------------------------
 */

static void
DeleteSpecCacheTable(
    ClientData clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    Tcl_HashTable *tablePtr = (Tcl_HashTable *)clientData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

    for (entryPtr = Tcl_FirstHashEntry(tablePtr,&search); entryPtr != NULL;







|







1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
 *	None (does *not* use any Tk API).
 *
 *--------------------------------------------------------------
 */

static void
DeleteSpecCacheTable(
    void *clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    Tcl_HashTable *tablePtr = (Tcl_HashTable *)clientData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

    for (entryPtr = Tcl_FirstHashEntry(tablePtr,&search); entryPtr != NULL;

Deleted 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
/*
 * tkOldTest.c --
 *
 *	This file contains C command functions for additional Tcl
 *	commands that are used to test Tk's support for legacy
 *	interfaces.  These commands are not normally included in Tcl/Tk
 *	applications; they're only used for testing.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Contributions by Don Porter, NIST, 2007.  (not subject to US copyright)
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#define USE_OLD_IMAGE
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"

#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
/*
 * The following data structure represents the model for a test image:
 */

typedef struct TImageModel {
    Tk_ImageModel model;        /* Tk's token for image model. */
    Tcl_Interp *interp;         /* Interpreter for application. */
    int width, height;          /* Dimensions of image. */
    char *imageName;            /* Name of image (malloc-ed). */
    char *varName;              /* Name of variable in which to log events for
                                 * image (malloc-ed). */
} TImageModel;

/*
 * The following data structure represents a particular use of a particular
 * test image.
 */

typedef struct TImageInstance {
    TImageModel *modelPtr;    /* Pointer to model for image. */
    XColor *fg;                 /* Foreground color for drawing in image. */
    GC gc;                      /* Graphics context for drawing in image. */
} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    char *name, int argc, char **argv,
			    Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static ClientData	ImageGet(Tk_Window tkwin, ClientData clientData);
static void		ImageDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width,
			    int height, int drawableX,
			    int drawableY);
static void		ImageFree(ClientData clientData, Display *display);
static void		ImageDelete(ClientData clientData);

static Tk_ImageType imageType = {
    "oldtest",			/* name */
    (Tk_ImageCreateProc *) ImageCreate, /* createProc */
    ImageGet,			/* getProc */
    ImageDisplay,		/* displayProc */
    ImageFree,			/* freeProc */
    ImageDelete,		/* deleteProc */
    NULL,			/* postscriptPtr */
    NULL,			/* nextPtr */
    NULL
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int              ImageObjCmd(ClientData dummy,
                            Tcl_Interp *interp, int objc,
            			    Tcl_Obj * const objv[]);
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkOldTestInit --
 *
 *	This function performs initialization for the Tk test suite
 *	extensions for testing support for legacy interfaces.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error message in
 *	the interp's result if an error occurs.
 *
 * Side effects:
 *	Creates several test commands.
 *
 *----------------------------------------------------------------------
 */

int
TkOldTestInit(
    Tcl_Interp *dummy)
{
    static int initialized = 0;
    (void)dummy;

    if (!initialized) {
	initialized = 1;
#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
	Tk_CreateImageType(&imageType);
#endif
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageCreate --
 *
 *	This function is called by the Tk image code to create "oldtest" images.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The data structure for a new image is allocated.
 *
 *----------------------------------------------------------------------
 */
#if !defined(TK_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
static int
ImageCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    char *name,			/* Name to use for image. */
    int argc,			/* Number of arguments. */
    char **argv,		/* Argument strings for options (doesn't
				 * include image name or type). */
    Tk_ImageType *typePtr,	/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    ClientData *clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    TImageModel *timPtr;
    const char *varName;
    int i;
    (void)typePtr;

    varName = "log";
    for (i = 0; i < argc; i += 2) {
	if (strcmp(argv[i], "-variable") != 0) {
	    Tcl_AppendResult(interp, "bad option name \"",
		    argv[i], "\"", NULL);
	    return TCL_ERROR;
	}
	if ((i+1) == argc) {
	    Tcl_AppendResult(interp, "no value given for \"",
		    argv[i], "\" option", NULL);
	    return TCL_ERROR;
	}
	varName = argv[i+1];
    }

    timPtr = (TImageModel *)ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = (char *)ckalloc(strlen(varName) + 1);
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageObjCmd --
 *
 *	This function implements the commands corresponding to individual
 *	images.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

static int
ImageObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
	if (objc != 8) {
	    Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
		    " imageWidth imageHeight");
	    return TCL_ERROR;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
	    return TCL_ERROR;
	}
	Tk_ImageChanged(timPtr->model, x, y, width, height, timPtr->width,
		timPtr->height);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be changed", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageGet --
 *
 *	This function is called by Tk to set things up for using a test image
 *	in a particular widget.
 *
 * Results:
 *	The return value is a token for the image instance, which is used in
 *	future callbacks to ImageDisplay and ImageFree.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static ClientData
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;
    instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
    return instPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDisplay --
 *
 *	This function is invoked to redisplay part or all of an image in a
 *	given drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The image gets partially redrawn, as an "X" that shows the exact
 *	redraw area.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDisplay(
    ClientData clientData,	/* Pointer to TImageInstance for image. */
    Display *display,		/* Display to use for drawing. */
    Drawable drawable,		/* Where to redraw image. */
    int imageX, int imageY,	/* Origin of area to redraw, relative to
				 * origin of image. */
    int width, int height,	/* Dimensions of area to redraw. */
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    sprintf(buffer, "%s display %d %d %d %d %d %d",
	    instPtr->modelPtr->imageName, imageX, imageY, width, height,
	    drawableX, drawableY);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
    if (height > (instPtr->modelPtr->height - imageY)) {
	height = instPtr->modelPtr->height - imageY;
    }
    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
	    (int) (drawableY + height - 1),
	    (int) (drawableX + width - 1), drawableY);
}

/*
 *----------------------------------------------------------------------
 *
 * ImageFree --
 *
 *	This function is called when an instance of an image is no longer
 *	used.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information related to the instance is freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImageFree(
    ClientData clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200];

    sprintf(buffer, "%s free", instPtr->modelPtr->imageName);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    Tk_FreeColor(instPtr->fg);
    Tk_FreeGC(display, instPtr->gc);
    ckfree(instPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImageDelete --
 *
 *	This function is called to clean up a test image when an application
 *	goes away.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
    ckfree(timPtr->imageName);
    ckfree(timPtr->varName);
    ckfree(timPtr);
}
#endif

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkOption.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"








|
|







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 © 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"

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
			    char *string, int priority);
static void		ClearOptionTree(ElArray *arrayPtr);
static ElArray *	ExtendArray(ElArray *arrayPtr, Element *elPtr);
static void		ExtendStacks(ElArray *arrayPtr, int leaf);
static int		GetDefaultOptions(Tcl_Interp *interp,
			    TkWindow *winPtr);
static ElArray *	NewArray(int numEls);
static void		OptionThreadExitProc(ClientData clientData);
static void		OptionInit(TkMainInfo *mainPtr);
static int		ParsePriority(Tcl_Interp *interp, const char *string);
static int		ReadOptionFile(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *fileName, int priority);
static void		SetupStacks(TkWindow *winPtr, int leaf);

/*







|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
			    char *string, int priority);
static void		ClearOptionTree(ElArray *arrayPtr);
static ElArray *	ExtendArray(ElArray *arrayPtr, Element *elPtr);
static void		ExtendStacks(ElArray *arrayPtr, int leaf);
static int		GetDefaultOptions(Tcl_Interp *interp,
			    TkWindow *winPtr);
static ElArray *	NewArray(int numEls);
static void		OptionThreadExitProc(void *clientData);
static void		OptionInit(TkMainInfo *mainPtr);
static int		ParsePriority(Tcl_Interp *interp, const char *string);
static int		ReadOptionFile(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *fileName, int priority);
static void		SetupStacks(TkWindow *winPtr, int leaf);

/*
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
     * option database is densely populated, or if the widget has many
     * masquerading options.
     */

    if (masqName != NULL) {
	char *masqClass;
	Tk_Uid nodeId, winClassId, winNameId;
	TkSizeT classNameLength;
	Element *nodePtr, *leafPtr;
	static const int searchOrder[] = {
	    EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS,
	    WILDCARD_NODE_CLASS, -1
	};
	const int *currentPtr;
	int currentStack, leafCount;







|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
     * option database is densely populated, or if the widget has many
     * masquerading options.
     */

    if (masqName != NULL) {
	char *masqClass;
	Tk_Uid nodeId, winClassId, winNameId;
	Tcl_Size 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;
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_OptionObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of Tcl_Obj arguments. */
    Tcl_Obj *const objv[])	/* Tcl_Obj arguments. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int index, result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)







|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_OptionObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of Tcl_Obj arguments. */
    Tcl_Obj *const objv[])	/* Tcl_Obj arguments. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    int index, result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
	window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
	if (window == NULL) {
	    return TCL_ERROR;
	}
	value = Tk_GetOption(window, Tcl_GetString(objv[3]),
		Tcl_GetString(objv[4]));
	if (value != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
	}
	break;
    }

    case OPTION_READFILE: {
	int priority;








|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
	window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
	if (window == NULL) {
	    return TCL_ERROR;
	}
	value = Tk_GetOption(window, Tcl_GetString(objv[3]),
		Tcl_GetString(objv[4]));
	if (value != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(value, TCL_INDEX_NONE));
	}
	break;
    }

    case OPTION_READFILE: {
	int priority;

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
     * If this window is in the option stacks, then clear the stacks.
     *
     * XXX: OptionThreadExitProc will be invoked before DeleteWindowsExitProc
     * XXX: if it is thread-specific (which it should be), invalidating the
     * XXX: tsd. Tk shutdown needs to be verified to handle this correctly.
     */

    if (tsdPtr->initialized && (winPtr->optionLevel != -1)) {
	int i;

	for (i = 1; i <= tsdPtr->curLevel; i++) {
	    tsdPtr->levels[i].winPtr->optionLevel = -1;
	}
	tsdPtr->curLevel = -1;
	tsdPtr->cachedWindow = NULL;
    }

    /*
     * If this window was a main window, then delete its option database.







|



|







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
     * If this window is in the option stacks, then clear the stacks.
     *
     * XXX: OptionThreadExitProc will be invoked before DeleteWindowsExitProc
     * XXX: if it is thread-specific (which it should be), invalidating the
     * XXX: tsd. Tk shutdown needs to be verified to handle this correctly.
     */

    if (tsdPtr->initialized && (winPtr->optionLevel != TCL_INDEX_NONE)) {
	int i;

	for (i = 1; i <= tsdPtr->curLevel; i++) {
	    tsdPtr->levels[i].winPtr->optionLevel = TCL_INDEX_NONE;
	}
	tsdPtr->curLevel = -1;
	tsdPtr->cachedWindow = NULL;
    }

    /*
     * If this window was a main window, then delete its option database.
795
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
    TkWindow *winPtr)		/* Window whose class changed. */
{
    int i, j, *basePtr;
    ElArray *arrayPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->optionLevel == -1) {
	return;
    }

    /*
     * Find the lowest stack level that refers to this window, then flush all
     * of the levels above the matching one.
     */

    for (i = 1; i <= tsdPtr->curLevel; i++) {
	if (tsdPtr->levels[i].winPtr == winPtr) {
	    for (j = i; j <= tsdPtr->curLevel; j++) {
		tsdPtr->levels[j].winPtr->optionLevel = -1;
	    }
	    tsdPtr->curLevel = i-1;
	    basePtr = tsdPtr->levels[i].bases;
	    for (j = 0; j < NUM_STACKS; j++) {
		arrayPtr = tsdPtr->stacks[j];
		arrayPtr->numUsed = basePtr[j];
		arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed];







|











|







795
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
    TkWindow *winPtr)		/* Window whose class changed. */
{
    int i, j, *basePtr;
    ElArray *arrayPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->optionLevel < 0) {
	return;
    }

    /*
     * Find the lowest stack level that refers to this window, then flush all
     * of the levels above the matching one.
     */

    for (i = 1; i <= tsdPtr->curLevel; i++) {
	if (tsdPtr->levels[i].winPtr == winPtr) {
	    for (j = i; j <= tsdPtr->curLevel; j++) {
		tsdPtr->levels[j].winPtr->optionLevel = TCL_INDEX_NONE;
	    }
	    tsdPtr->curLevel = i-1;
	    basePtr = tsdPtr->levels[i].bases;
	    for (j = 0; j < NUM_STACKS; j++) {
		arrayPtr = tsdPtr->stacks[j];
		arrayPtr->numUsed = basePtr[j];
		arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed];
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
				 * file, such as TK_USER_DEFAULT_PRIO or
				 * TK_INTERACTIVE_PRIO. Must be between 0 and
				 * TK_MAX_PRIO. */
{
    const char *realName;
    Tcl_Obj *buffer;
    int result;
    TkSizeT bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't read options from a file in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "OPTION_FILE", NULL);
	return TCL_ERROR;
    }

    realName = Tcl_TranslateFileName(interp, fileName, &newName);
    if (realName == NULL) {
	return TCL_ERROR;
    }
    chan = Tcl_OpenFileChannel(interp, realName, "r", 0);
    Tcl_DStringFree(&newName);
    if (chan == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't open \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    buffer = Tcl_NewObj();
    Tcl_IncrRefCount(buffer);
    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
    bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
    if (bufferSize == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }







|









|



















|







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
				 * 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;
    Tcl_Size bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't read options from a file in a safe interpreter", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "OPTION_FILE", NULL);
	return TCL_ERROR;
    }

    realName = Tcl_TranslateFileName(interp, fileName, &newName);
    if (realName == NULL) {
	return TCL_ERROR;
    }
    chan = Tcl_OpenFileChannel(interp, realName, "r", 0);
    Tcl_DStringFree(&newName);
    if (chan == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't open \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    buffer = Tcl_NewObj();
    Tcl_IncrRefCount(buffer);
    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
    bufferSize = Tcl_ReadChars(chan, buffer, TCL_INDEX_NONE, 0);
    if (bufferSize == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
    /*
     * Step 2: pop extra unneeded information off the stacks and mark those
     * windows as no longer having cached information.
     */

    if (tsdPtr->curLevel >= level) {
	while (tsdPtr->curLevel >= level) {
	    tsdPtr->levels[tsdPtr->curLevel].winPtr->optionLevel = -1;
	    tsdPtr->curLevel--;
	}
	levelPtr = &tsdPtr->levels[level];
	for (i = 0; i < NUM_STACKS; i++) {
	    arrayPtr = tsdPtr->stacks[i];
	    arrayPtr->numUsed = levelPtr->bases[i];
	    arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed];







|







1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
    /*
     * Step 2: pop extra unneeded information off the stacks and mark those
     * windows as no longer having cached information.
     */

    if (tsdPtr->curLevel >= level) {
	while (tsdPtr->curLevel >= level) {
	    tsdPtr->levels[tsdPtr->curLevel].winPtr->optionLevel = TCL_INDEX_NONE;
	    tsdPtr->curLevel--;
	}
	levelPtr = &tsdPtr->levels[level];
	for (i = 0; i < NUM_STACKS; i++) {
	    arrayPtr = tsdPtr->stacks[i];
	    arrayPtr->numUsed = levelPtr->bases[i];
	    arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed];

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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side;
static const char *const sideNames[] = {
    "top", "bottom", "left", "right", NULL
};

/*
 * For each window that the packer cares about (either because the window is
 * managed by the packer or because the window has content that are managed by
 * the packer), there is a structure of the following type:
 */






|
|







|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * tkPack.c --
 *
 *	This file contains code to implement the "packer" geometry manager for
 *	Tk.
 *
 * 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 {BOTTOM, LEFT, RIGHT, TOP} Side;
static const char *const sideNames[] = {
    "bottom", "left", "right", "top", NULL
};

/*
 * For each window that the packer cares about (either because the window is
 * managed by the packer or because the window has content that are managed by
 * the packer), there is a structure of the following type:
 */
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#define DONT_PROPAGATE		32
#define ALLOCED_CONTAINER	64

/*
 * The following structure is the official type record for the packer:
 */

static void		PackReqProc(ClientData clientData, Tk_Window tkwin);
static void		PackLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr packerType = {
    "pack",			/* name */
    PackReqProc,		/* requestProc */
    PackLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ArrangePacking(ClientData clientData);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyPacker(void *memPtr);
static Packer *		GetPacker(Tk_Window tkwin);
#ifndef TK_NO_DEPRECATED
static int		PackAfter(Tcl_Interp *interp, Packer *prevPtr,
			    Packer *containerPtr, int objc,Tcl_Obj *const objv[]);
#endif /* !TK_NO_DEPRECATED */
static void		PackStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		Unlink(Packer *packPtr);
static int		XExpansion(Packer *contentPtr, int cavityWidth);
static int		YExpansion(Packer *contentPtr, int cavityHeight);

/*
 *------------------------------------------------------------------------







|
|












|


|

<
<
<
<
|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124




125
126
127
128
129
130
131
132
#define DONT_PROPAGATE		32
#define ALLOCED_CONTAINER	64

/*
 * The following structure is the official type record for the packer:
 */

static void		PackReqProc(void *clientData, Tk_Window tkwin);
static void		PackLostContentProc(void *clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr packerType = {
    "pack",			/* name */
    PackReqProc,		/* requestProc */
    PackLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ArrangePacking(void *clientData);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static Tcl_FreeProc	DestroyPacker;
static Packer *		GetPacker(Tk_Window tkwin);




static void		PackStructureProc(void *clientData,
			    XEvent *eventPtr);
static void		Unlink(Packer *packPtr);
static int		XExpansion(Packer *contentPtr, int cavityWidth);
static int		YExpansion(Packer *contentPtr, int cavityHeight);

/*
 *------------------------------------------------------------------------
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
				 * "ipady" */
    int halfSpace,		/* The left or top padding amount */
    int allSpace)		/* The total amount of padding */
{
    Tcl_Obj *padding[2];

    if (halfSpace*2 == allSpace) {
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewWideIntObj(halfSpace));
    } else {
	padding[0] = Tcl_NewWideIntObj(halfSpace);
	padding[1] = Tcl_NewWideIntObj(allSpace - halfSpace);
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewListObj(2, padding));
    }
}

/*
 *------------------------------------------------------------------------
 *







|




|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
				 * "ipady" */
    int halfSpace,		/* The left or top padding amount */
    int allSpace)		/* The total amount of padding */
{
    Tcl_Obj *padding[2];

    if (halfSpace*2 == allSpace) {
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, TCL_INDEX_NONE),
		Tcl_NewWideIntObj(halfSpace));
    } else {
	padding[0] = Tcl_NewWideIntObj(halfSpace);
	padding[1] = Tcl_NewWideIntObj(allSpace - halfSpace);
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, TCL_INDEX_NONE),
		Tcl_NewListObj(2, padding));
    }
}

/*
 *------------------------------------------------------------------------
 *
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
 *	See the user documentation.
 *
 *------------------------------------------------------------------------
 */

int
Tk_PackObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *argv2;
    static const char *const optionStrings[] = {
#ifndef TK_NO_DEPRECATED
	"after", "append", "before", "unpack",
#endif /* !TK_NO_DEPRECATED */
	"configure", "content", "forget", "info", "propagate", "slaves", NULL };
    static const char *const optionStringsNoDep[] = {
	"configure", "content", "forget", "info", "propagate", NULL };
    enum options {
#ifndef TK_NO_DEPRECATED
	PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK,
#endif /* !TK_NO_DEPRECATED */
	PACK_CONFIGURE, PACK_CONTENT, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
    int index;

    if (objc >= 2) {
	const char *string = Tcl_GetString(objv[1]);

	if (string[0] == '.') {
	    return ConfigureContent(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(NULL, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    argv2 = Tcl_GetString(objv[2]);
    switch ((enum options) index) {
#ifndef TK_NO_DEPRECATED
    case PACK_AFTER: {
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	prevPtr = GetPacker(tkwin2);
	if (prevPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}
	return PackAfter(interp, prevPtr, prevPtr->containerPtr, objc-3, objv+3);
    }
    case PACK_APPEND: {
	Packer *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	containerPtr = GetPacker(tkwin2);
	prevPtr = containerPtr->contentPtr;
	if (prevPtr != NULL) {
	    while (prevPtr->nextPtr != NULL) {
		prevPtr = prevPtr->nextPtr;
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
    case PACK_BEFORE: {
	Packer *packPtr, *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if (packPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}
	containerPtr = packPtr->containerPtr;
	prevPtr = containerPtr->contentPtr;
	if (prevPtr == packPtr) {
	    prevPtr = NULL;
	} else {
	    for ( ; ; prevPtr = prevPtr->nextPtr) {
		if (prevPtr == NULL) {
		    Tcl_Panic("\"pack before\" couldn't find predecessor");
		}
		if (prevPtr->nextPtr == packPtr) {
		    break;
		}
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
#endif /* !TK_NO_DEPRECATED */
    case PACK_CONFIGURE:
	if (argv2[0] != '.') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad argument \"%s\": must be name of window", argv2));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	    return TCL_ERROR;
	}







|







<
<
<




<
<
<















|
|






|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197



198
199
200
201



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231


































































232
233
234
235
236
237
238
 *	See the user documentation.
 *
 *------------------------------------------------------------------------
 */

int
Tk_PackObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *argv2;
    static const char *const optionStrings[] = {



	"configure", "content", "forget", "info", "propagate", "slaves", NULL };
    static const char *const optionStringsNoDep[] = {
	"configure", "content", "forget", "info", "propagate", NULL };
    enum options {



	PACK_CONFIGURE, PACK_CONTENT, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
    int index;

    if (objc >= 2) {
	const char *string = Tcl_GetString(objv[1]);

	if (string[0] == '.') {
	    return ConfigureContent(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(NULL, objv[1], optionStrings,
	    "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObj(interp, objv[1], optionStringsNoDep,
		"option", 0, &index);
	return TCL_ERROR;
    }

    argv2 = Tcl_GetString(objv[2]);
    switch ((enum options) index) {


































































    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;
	}
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}

	infoObj = Tcl_NewObj();
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", -1),
		Tcl_NewStringObj(Tk_NameOfAnchor(contentPtr->anchor), -1));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", -1),
		Tcl_NewBooleanObj(contentPtr->flags & EXPAND));
	switch (contentPtr->flags & (FILLX|FILLY)) {
	case 0:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("none", -1));
	    break;
	case FILLX:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("x", -1));
	    break;
	case FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("y", -1));
	    break;
	case FILLX|FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
		    Tcl_NewStringObj("both", -1));
	    break;
	}
	TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
	TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
	TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft,contentPtr->padX);
	TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-side", -1),
		Tcl_NewStringObj(sideNames[contentPtr->side], -1));
	Tcl_SetObjResult(interp, infoObj);
	break;
    }
    case PACK_PROPAGATE: {
	Tk_Window container;
	Packer *containerPtr;
	int propagate;







|

|
|
|



|
|


|
|


|
|


|
|






|
|







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
	    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", TCL_INDEX_NONE),
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", TCL_INDEX_NONE),
		Tcl_NewStringObj(Tk_NameOfAnchor(contentPtr->anchor), TCL_INDEX_NONE));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", TCL_INDEX_NONE),
		Tcl_NewBooleanObj(contentPtr->flags & EXPAND));
	switch (contentPtr->flags & (FILLX|FILLY)) {
	case 0:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", TCL_INDEX_NONE),
		    Tcl_NewStringObj("none", TCL_INDEX_NONE));
	    break;
	case FILLX:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", TCL_INDEX_NONE),
		    Tcl_NewStringObj("x", TCL_INDEX_NONE));
	    break;
	case FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", TCL_INDEX_NONE),
		    Tcl_NewStringObj("y", TCL_INDEX_NONE));
	    break;
	case FILLX|FILLY:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", TCL_INDEX_NONE),
		    Tcl_NewStringObj("both", TCL_INDEX_NONE));
	    break;
	}
	TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
	TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
	TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft,contentPtr->padX);
	TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-side", TCL_INDEX_NONE),
		Tcl_NewStringObj(sideNames[contentPtr->side], TCL_INDEX_NONE));
	Tcl_SetObjResult(interp, infoObj);
	break;
    }
    case PACK_PROPAGATE: {
	Tk_Window container;
	Packer *containerPtr;
	int propagate;
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(contentPtr->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
#ifndef TK_NO_DEPRECATED
    case PACK_UNPACK: {
	Tk_Window tkwin2;
	Packer *packPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if ((packPtr != NULL) && (packPtr->containerPtr != NULL)) {
	    Tk_ManageGeometry(tkwin2, NULL, NULL);
	    if (packPtr->containerPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
		Tk_UnmaintainGeometry(packPtr->tkwin,
			packPtr->containerPtr->tkwin);
	    }
	    Unlink(packPtr);
	    Tk_UnmapWindow(packPtr->tkwin);
	}
	break;
    }
#endif /* !TK_NO_DEPRECATED */
    }

    return TCL_OK;
}

/*
 *------------------------------------------------------------------------







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







387
388
389
390
391
392
393

























394
395
396
397
398
399
400
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(contentPtr->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }

























    }

    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
 *	the next idle point.
 *
 *------------------------------------------------------------------------
 */

static void
PackReqProc(
    ClientData clientData,	/* Packer's information about window that got
				 * new preferred geometry.  */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Packer *packPtr = (Packer *)clientData;

    packPtr = packPtr->containerPtr;







|







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
 *	the next idle point.
 *
 *------------------------------------------------------------------------
 */

static void
PackReqProc(
    void *clientData,	/* Packer's information about window that got
				 * new preferred geometry.  */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Packer *packPtr = (Packer *)clientData;

    packPtr = packPtr->containerPtr;
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
 *	The packed content of containerPtr may get resized or moved.
 *
 *------------------------------------------------------------------------
 */

static void
ArrangePacking(
    ClientData clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Packer *containerPtr = (Packer *)clientData;
    Packer *contentPtr;
    int cavityX, cavityY, cavityWidth, cavityHeight;
				/* These variables keep track of the
				 * as-yet-unallocated space remaining in the







|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
 *	The packed content of containerPtr may get resized or moved.
 *
 *------------------------------------------------------------------------
 */

static void
ArrangePacking(
    void *clientData)	/* Structure describing container whose content
				 * are to be re-layed out. */
{
    Packer *containerPtr = (Packer *)clientData;
    Packer *contentPtr;
    int cavityX, cavityY, cavityWidth, cavityHeight;
				/* These variables keep track of the
				 * as-yet-unallocated space remaining in the
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
	    x = frameX + borderLeft;
	    y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
	    break;
	case TK_ANCHOR_NW:
	    x = frameX + borderLeft;
	    y = frameY + borderTop;
	    break;
	case TK_ANCHOR_CENTER:
	    x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
	    y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
	    break;
	default:
	    Tcl_Panic("bad frame factor in ArrangePacking");
	}
	width -= contentPtr->doubleBw;
	height -= contentPtr->doubleBw;

	/*
	 * The final step is to set the position, size, and mapped/unmapped
	 * state of the content. If the content is a child of the container, then do







|



<
<







721
722
723
724
725
726
727
728
729
730
731


732
733
734
735
736
737
738
	    x = frameX + borderLeft;
	    y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
	    break;
	case TK_ANCHOR_NW:
	    x = frameX + borderLeft;
	    y = frameY + borderTop;
	    break;
	default:
	    x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
	    y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
	    break;


	}
	width -= contentPtr->doubleBw;
	height -= contentPtr->doubleBw;

	/*
	 * The final step is to set the position, size, and mapped/unmapped
	 * state of the content. If the content is a child of the container, then do
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
    packPtr->flags = 0;
    Tcl_SetHashValue(hPtr, packPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    PackStructureProc, packPtr);
    return packPtr;
}

/*
 *------------------------------------------------------------------------
 *
 * PackAfter --
 *
 *	This function does most of the real work of adding one or more windows
 *	into the packing order for its container.
 *
 * Results:
 *	A standard Tcl return value.
 *
 * Side effects:
 *	The geometry of the specified windows may change, both now and again
 *	in the future.
 *
 *------------------------------------------------------------------------
 */

#ifndef TK_NO_DEPRECATED
static int
PackAfter(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Packer *prevPtr,		/* Pack windows in argv just after this
				 * window; NULL means pack as first child of
				 * containerPtr. */
    Packer *containerPtr,		/* Container in which to pack windows. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[])	/* Array of lists, each containing 2 elements:
				 * window name and side against which to
				 * pack. */
{
    Packer *packPtr;
    Tk_Window tkwin, ancestor, parent;
    Tcl_Obj **options;
    int index, optionCount, c;

    /*
     * Iterate over all of the window specifiers, each consisting of two
     * arguments. The first argument contains the window name and the
     * additional arguments contain options such as "top" or "padx 20".
     */

    for ( ; objc > 0; objc -= 2, objv += 2, prevPtr = packPtr) {
	if (objc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "wrong # args: window \"%s\" should be followed by options",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Find the packer for the window to be packed, and make sure that the
	 * window in which it will be packed is either its or a descendant of
	 * its parent.
	 */

	if (TkGetWindowFromObj(interp, containerPtr->tkwin, objv[0], &tkwin)
		!= TCL_OK) {
	    return TCL_ERROR;
	}

	parent = Tk_Parent(tkwin);
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
	    badWindow:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack \"%s\" inside \"%s\"", Tcl_GetString(objv[0]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		return TCL_ERROR;
	    }
	}
	if (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY) {
	    goto badWindow;
	}
	if (tkwin == containerPtr->tkwin) {
	    goto badWindow;
	}
	packPtr = GetPacker(tkwin);

	/*
	 * Process options for this window.
	 */

	if (Tcl_ListObjGetElements(interp, objv[1], &optionCount, &options)
		!= TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr->side = TOP;
	packPtr->anchor = TK_ANCHOR_CENTER;
	packPtr->padX = packPtr->padY = 0;
	packPtr->padLeft = packPtr->padTop = 0;
	packPtr->iPadX = packPtr->iPadY = 0;
	packPtr->flags &= ~(FILLX|FILLY|EXPAND);
	packPtr->flags |= OLD_STYLE;
	for (index = 0 ; index < optionCount; index++) {
	    Tcl_Obj *curOptPtr = options[index];
	    TkSizeT length;
	    const char *curOpt = TkGetStringFromObj(curOptPtr, &length);

	    c = curOpt[0];

	    if ((c == 't')
		    && (strncmp(curOpt, "top", length)) == 0) {
		packPtr->side = TOP;
	    } else if ((c == 'b')
		    && (strncmp(curOpt, "bottom", length)) == 0) {
		packPtr->side = BOTTOM;
	    } else if ((c == 'l')
		    && (strncmp(curOpt, "left", length)) == 0) {
		packPtr->side = LEFT;
	    } else if ((c == 'r')
		    && (strncmp(curOpt, "right", length)) == 0) {
		packPtr->side = RIGHT;
	    } else if ((c == 'e')
		    && (strncmp(curOpt, "expand", length)) == 0) {
		packPtr->flags |= EXPAND;
	    } else if ((c == 'f')
		    && (strcmp(curOpt, "fill")) == 0) {
		packPtr->flags |= FILLX|FILLY;
	    } else if ((length == 5) && (strcmp(curOpt, "fillx")) == 0) {
		packPtr->flags |= FILLX;
	    } else if ((length == 5) && (strcmp(curOpt, "filly")) == 0) {
		packPtr->flags |= FILLY;
	    } else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) {
		if (optionCount < (index+2)) {
		missingPad:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "wrong # args: \"%s\" option must be"
			    " followed by screen distance", curOpt));
		    Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			    NULL);
		    return TCL_ERROR;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padLeft, &packPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		packPtr->padX /= 2;
		packPtr->padLeft /= 2;
		packPtr->iPadX = 0;
		index++;
	    } else if ((c == 'p') && (strcmp(curOpt, "pady")) == 0) {
		if (optionCount < (index+2)) {
		    goto missingPad;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padTop, &packPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		packPtr->padY /= 2;
		packPtr->padTop /= 2;
		packPtr->iPadY = 0;
		index++;
	    } else if ((c == 'f') && (length > 1)
		    && (strncmp(curOpt, "frame", length) == 0)) {
		if (optionCount < (index+2)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "wrong # args: \"frame\""
			    " option must be followed by anchor point", -1));
		    Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			    NULL);
		    return TCL_ERROR;
		}
		if (Tk_GetAnchorFromObj(interp, options[index+1],
			&packPtr->anchor) != TCL_OK) {
		    return TCL_ERROR;
		}
		index++;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": should be top, bottom, left,"
			" right, expand, fill, fillx, filly, padx, pady, or"
			" frame", curOpt));
		Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			NULL);
		return TCL_ERROR;
	    }
	}

	if (packPtr != prevPtr) {
	    /*
	     * Unpack this window if it's currently packed.
	     */

	    if (packPtr->containerPtr != NULL) {
		if ((packPtr->containerPtr != containerPtr) &&
			(packPtr->containerPtr->tkwin
			!= Tk_Parent(packPtr->tkwin))) {
		    Tk_UnmaintainGeometry(packPtr->tkwin,
			    packPtr->containerPtr->tkwin);
		}
		Unlink(packPtr);
	    }

	    /*
	     * Add the window in the correct place in its container's packing
	     * order, then make sure that the window is managed by us.
	     */

	    packPtr->containerPtr = containerPtr;
	    if (prevPtr == NULL) {
		packPtr->nextPtr = containerPtr->contentPtr;
		containerPtr->contentPtr = packPtr;
	    } else {
		packPtr->nextPtr = prevPtr->nextPtr;
		prevPtr->nextPtr = packPtr;
	    }
	    Tk_ManageGeometry(tkwin, &packerType, packPtr);

	    if (!(containerPtr->flags & DONT_PROPAGATE)) {
		if (TkSetGeometryContainer(interp, containerPtr->tkwin, "pack")
			!= TCL_OK) {
		    Tk_ManageGeometry(tkwin, NULL, NULL);
		    Unlink(packPtr);
		    return TCL_ERROR;
		}
		containerPtr->flags |= ALLOCED_CONTAINER;
	    }
	}
    }

    /*
     * Arrange for the container to be re-packed at the first idle moment.
     */

    if (containerPtr->abortPtr != NULL) {
	*containerPtr->abortPtr = 1;
    }
    if (!(containerPtr->flags & REQUESTED_REPACK)) {
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
    }
    return TCL_OK;
}
#endif /* !TK_NO_DEPRECATED */

/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a packer from its container's list of content.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







972
973
974
975
976
977
978

















































































































































































































































979
980
981
982
983
984
985
    packPtr->flags = 0;
    Tcl_SetHashValue(hPtr, packPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    PackStructureProc, packPtr);
    return packPtr;
}


















































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a packer from its container's list of content.
 *
1401
1402
1403
1404
1405
1406
1407

1408

1409

1410
1411
1412



1413
1414
1415
1416
1417
1418
1419
 *	Everything associated with the packer is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyPacker(

    void *memPtr)		/* Info about packed window that is now

				 * dead. */

{
    Packer *packPtr = (Packer *)memPtr;




    ckfree(packPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PackStructureProc --







>
|
>
|
>



>
>
>







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
 *	Everything associated with the packer is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyPacker(
#if TCL_MAJOR_VERSION > 8
    void *memPtr)		/* Info about packed window that is now dead. */
#else
    char *memPtr)
#endif
{
    Packer *packPtr = (Packer *)memPtr;

    if (packPtr->flags & REQUESTED_REPACK) {
	Tcl_CancelIdleCall(ArrangePacking, packPtr);
    }
    ckfree(packPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PackStructureProc --
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
 *	information. If it was just resized, repack its content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
PackStructureProc(
    ClientData clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Packer *packPtr = (Packer *)clientData;

    if (eventPtr->type == ConfigureNotify) {
	if ((packPtr->contentPtr != NULL)







|







1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
 *	information. If it was just resized, repack its content, if any.
 *
 *----------------------------------------------------------------------
 */

static void
PackStructureProc(
    void *clientData,	/* Our information about window referred to by
				 * eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Packer *packPtr = (Packer *)clientData;

    if (eventPtr->type == ConfigureNotify) {
	if ((packPtr->contentPtr != NULL)
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
		    packPtr->tkwin));
	}

	if (packPtr->flags & REQUESTED_REPACK) {
	    Tcl_CancelIdleCall(ArrangePacking, packPtr);
	}
	packPtr->tkwin = NULL;
	Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker);
    } else if (eventPtr->type == MapNotify) {
	/*
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((packPtr->contentPtr != NULL)







|







1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
		    packPtr->tkwin));
	}

	if (packPtr->flags & REQUESTED_REPACK) {
	    Tcl_CancelIdleCall(ArrangePacking, packPtr);
	}
	packPtr->tkwin = NULL;
	Tcl_EventuallyFree(packPtr, DestroyPacker);
    } else if (eventPtr->type == MapNotify) {
	/*
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((packPtr->contentPtr != NULL)
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
	    if ((i+2) > objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"extra option \"%s\" (option with no value?)",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL);
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum options) index) {
	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)







|
|







1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
	    if ((i+2) > objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"extra option \"%s\" (option with no value?)",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL);
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		    "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum options) index) {
	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
	    case CONF_PADY:
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_SIDE:
		if (Tcl_GetIndexFromObjStruct(interp, objv[i+1], sideNames,
			sizeof(char *), "side", TCL_EXACT, &side) != TCL_OK) {
		    return TCL_ERROR;
		}
		contentPtr->side = (Side) side;
		break;
	    }
	}








|
|







1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
	    case CONF_PADY:
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_SIDE:
		if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames,
			"side", TCL_EXACT, &side) != TCL_OK) {
		    return TCL_ERROR;
		}
		contentPtr->side = (Side) side;
		break;
	    }
	}

Changes to generic/tkPanedWindow.c.

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.
 *
 * 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"








|
|







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 © 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"
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#define PROXY_REDRAW_PENDING	0x0010
#define RESIZE_PENDING		0x0020

/*
 * Forward declarations for functions defined later in this file:
 */

int			Tk_PanedWindowObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		PanedWindowCmdDeletedProc(ClientData clientData);
static int		ConfigurePanedWindow(Tcl_Interp *interp,
			    PanedWindow *pwPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		DestroyPanedWindow(PanedWindow *pwPtr);
static void		DisplayPanedWindow(ClientData clientData);
static void		PanedWindowEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		ProxyWindowEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		DisplayProxyWindow(ClientData clientData);
static void		PanedWindowWorldChanged(ClientData instanceData);
static int		PanedWindowWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *, int objc, Tcl_Obj * const objv[]);
static void		PanedWindowLostPaneProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PanedWindowReqProc(ClientData clientData,
			    Tk_Window tkwin);
static void		ArrangePanes(ClientData clientData);
static void		Unlink(Pane *panePtr);
static Pane *		GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
static void		GetFirstLastVisiblePane(PanedWindow *pwPtr,
			    int *firstPtr, int *lastPtr);
static void		PaneStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		PanedWindowSashCommand(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		PanedWindowProxyCommand(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		ComputeGeometry(PanedWindow *pwPtr);
static int		ConfigurePanes(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		DestroyOptionTables(ClientData clientData,
			    Tcl_Interp *interp);
static int		SetSticky(ClientData clientData, Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
			    TkSizeT internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetSticky(ClientData clientData, Tk_Window tkwin,
			    char *recordPtr, TkSizeT internalOffset);
static void		RestoreSticky(ClientData clientData, Tk_Window tkwin,
			    char *internalPtr, char *oldInternalPtr);
static void		AdjustForSticky(int sticky, int cavityWidth,
			    int cavityHeight, int *xPtr, int *yPtr,
			    int *paneWidthPtr, int *paneHeightPtr);
static void		MoveSash(PanedWindow *pwPtr, int sash, int diff);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static void *	ComputeSlotAddress(void *recordPtr, TkSizeT offset);
static int		PanedWindowIdentifyCoords(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int x, int y);

/*
 * Sashes are between panes only, so there is one less sash than panes
 */








<
<
<
|




|
|

|

|
|
|

|

|

|




|











|

|

|

|
|
|






|







179
180
181
182
183
184
185



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#define PROXY_REDRAW_PENDING	0x0010
#define RESIZE_PENDING		0x0020

/*
 * Forward declarations for functions defined later in this file:
 */




static void		PanedWindowCmdDeletedProc(void *clientData);
static int		ConfigurePanedWindow(Tcl_Interp *interp,
			    PanedWindow *pwPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		DestroyPanedWindow(PanedWindow *pwPtr);
static void		DisplayPanedWindow(void *clientData);
static void		PanedWindowEventProc(void *clientData,
			    XEvent *eventPtr);
static void		ProxyWindowEventProc(void *clientData,
			    XEvent *eventPtr);
static void		DisplayProxyWindow(void *clientData);
static void		PanedWindowWorldChanged(void *instanceData);
static int		PanedWindowWidgetObjCmd(void *clientData,
			    Tcl_Interp *, int objc, Tcl_Obj * const objv[]);
static void		PanedWindowLostPaneProc(void *clientData,
			    Tk_Window tkwin);
static void		PanedWindowReqProc(void *clientData,
			    Tk_Window tkwin);
static void		ArrangePanes(void *clientData);
static void		Unlink(Pane *panePtr);
static Pane *		GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
static void		GetFirstLastVisiblePane(PanedWindow *pwPtr,
			    int *firstPtr, int *lastPtr);
static void		PaneStructureProc(void *clientData,
			    XEvent *eventPtr);
static int		PanedWindowSashCommand(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		PanedWindowProxyCommand(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		ComputeGeometry(PanedWindow *pwPtr);
static int		ConfigurePanes(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		DestroyOptionTables(void *clientData,
			    Tcl_Interp *interp);
static int		SetSticky(void *clientData, Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
			    Tcl_Size internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetSticky(void *clientData, Tk_Window tkwin,
			    char *recordPtr, Tcl_Size internalOffset);
static void		RestoreSticky(void *clientData, Tk_Window tkwin,
			    char *internalPtr, char *oldInternalPtr);
static void		AdjustForSticky(int sticky, int cavityWidth,
			    int cavityHeight, int *xPtr, int *yPtr,
			    int *paneWidthPtr, int *paneHeightPtr);
static void		MoveSash(PanedWindow *pwPtr, int sash, int diff);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static void *	ComputeSlotAddress(void *recordPtr, Tcl_Size offset);
static int		PanedWindowIdentifyCoords(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int x, int y);

/*
 * Sashes are between panes only, so there is one less sash than panes
 */

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    RestoreSticky,		/* restoreProc */
    NULL,			/* freeProc */
    0
};

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_PANEDWINDOW_BG_COLOR, TCL_INDEX_NONE, offsetof(PanedWindow, background), 0,
	 DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_PANEDWINDOW_BORDERWIDTH, TCL_INDEX_NONE, offsetof(PanedWindow, borderWidth),
	 0, 0, GEOMETRY},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_PANEDWINDOW_CURSOR, TCL_INDEX_NONE, offsetof(PanedWindow, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-handlepad", "handlePad", "HandlePad",
	 DEF_PANEDWINDOW_HANDLEPAD, TCL_INDEX_NONE, offsetof(PanedWindow, handlePad),
	 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
	 DEF_PANEDWINDOW_HANDLESIZE, offsetof(PanedWindow, handleSizePtr),
	 offsetof(PanedWindow, handleSize), 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	 DEF_PANEDWINDOW_HEIGHT, offsetof(PanedWindow, heightPtr),
	 offsetof(PanedWindow, height), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-opaqueresize", "opaqueResize", "OpaqueResize",
	 DEF_PANEDWINDOW_OPAQUERESIZE, TCL_INDEX_NONE,
	 offsetof(PanedWindow, resizeOpaque), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	 DEF_PANEDWINDOW_ORIENT, TCL_INDEX_NONE, offsetof(PanedWindow, orient),
	 0, orientStrings, GEOMETRY},
    {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground",
	 0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyBackground), TK_OPTION_NULL_OK,
	 (ClientData) DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth",
	 DEF_PANEDWINDOW_PROXYBORDER, offsetof(PanedWindow, proxyBorderWidthPtr),
	 offsetof(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
	 0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_PANEDWINDOW_RELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, relief), 0, 0, 0},
    {TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor",
	 DEF_PANEDWINDOW_SASHCURSOR, TCL_INDEX_NONE, offsetof(PanedWindow, sashCursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-sashpad", "sashPad", "SashPad",
	 DEF_PANEDWINDOW_SASHPAD, TCL_INDEX_NONE, offsetof(PanedWindow, sashPad),
	 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
	 DEF_PANEDWINDOW_SASHRELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, sashRelief),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-sashwidth", "sashWidth", "Width",
	 DEF_PANEDWINDOW_SASHWIDTH, offsetof(PanedWindow, sashWidthPtr),
	 offsetof(PanedWindow, sashWidth), 0, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-showhandle", "showHandle", "ShowHandle",
	 DEF_PANEDWINDOW_SHOWHANDLE, TCL_INDEX_NONE, offsetof(PanedWindow, showHandle),
	 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	 DEF_PANEDWINDOW_WIDTH, offsetof(PanedWindow, widthPtr),
	 offsetof(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec paneOptionSpecs[] = {
    {TK_OPTION_WINDOW, "-after", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_AFTER, TCL_INDEX_NONE, offsetof(Pane, after),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-before", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_BEFORE, TCL_INDEX_NONE, offsetof(Pane, before),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_HEIGHT, offsetof(Pane, heightPtr),
	 offsetof(Pane, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
	 DEF_PANEDWINDOW_PANE_HIDE, TCL_INDEX_NONE, offsetof(Pane, hide), 0,0,GEOMETRY},
    {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_MINSIZE, TCL_INDEX_NONE, offsetof(Pane, minSize), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADX, TCL_INDEX_NONE, offsetof(Pane, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADY, TCL_INDEX_NONE, offsetof(Pane, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_STICKY, TCL_INDEX_NONE, offsetof(Pane, sticky), 0,
	 &stickyOption, 0},
    {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch",
	DEF_PANEDWINDOW_PANE_STRETCH, TCL_INDEX_NONE, offsetof(Pane, stretch), 0,
	(ClientData) stretchStrings, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_WIDTH, offsetof(Pane, widthPtr),
	 offsetof(Pane, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * Tk_PanedWindowObjCmd --







|
|

|

|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|

|
|

|
|

|
|

|
|

|
|

|
|





|
|

|
|

|
|

|

|

|

|

|
|

|
|

|
|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    RestoreSticky,		/* restoreProc */
    NULL,			/* freeProc */
    0
};

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_PANEDWINDOW_BG_COLOR, TCL_INDEX_NONE, offsetof(PanedWindow, background), 0,
	DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_PANEDWINDOW_BORDERWIDTH, TCL_INDEX_NONE, offsetof(PanedWindow, borderWidth),
	0, 0, GEOMETRY},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_PANEDWINDOW_CURSOR, TCL_INDEX_NONE, offsetof(PanedWindow, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-handlepad", "handlePad", "HandlePad",
	DEF_PANEDWINDOW_HANDLEPAD, TCL_INDEX_NONE, offsetof(PanedWindow, handlePad),
	0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
	DEF_PANEDWINDOW_HANDLESIZE, offsetof(PanedWindow, handleSizePtr),
	offsetof(PanedWindow, handleSize), 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_PANEDWINDOW_HEIGHT, offsetof(PanedWindow, heightPtr),
	offsetof(PanedWindow, height), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-opaqueresize", "opaqueResize", "OpaqueResize",
	DEF_PANEDWINDOW_OPAQUERESIZE, TCL_INDEX_NONE,
	offsetof(PanedWindow, resizeOpaque), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_PANEDWINDOW_ORIENT, TCL_INDEX_NONE, offsetof(PanedWindow, orient),
	TK_OPTION_ENUM_VAR, orientStrings, GEOMETRY},
    {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground",
	0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyBackground), TK_OPTION_NULL_OK,
	(void *)DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth",
	DEF_PANEDWINDOW_PROXYBORDER, offsetof(PanedWindow, proxyBorderWidthPtr),
	offsetof(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
	0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyRelief),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_PANEDWINDOW_RELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, relief), 0, 0, 0},
    {TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor",
	DEF_PANEDWINDOW_SASHCURSOR, TCL_INDEX_NONE, offsetof(PanedWindow, sashCursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-sashpad", "sashPad", "SashPad",
	DEF_PANEDWINDOW_SASHPAD, TCL_INDEX_NONE, offsetof(PanedWindow, sashPad),
	0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
	DEF_PANEDWINDOW_SASHRELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, sashRelief),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-sashwidth", "sashWidth", "Width",
	DEF_PANEDWINDOW_SASHWIDTH, offsetof(PanedWindow, sashWidthPtr),
	offsetof(PanedWindow, sashWidth), 0, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-showhandle", "showHandle", "ShowHandle",
	DEF_PANEDWINDOW_SHOWHANDLE, TCL_INDEX_NONE, offsetof(PanedWindow, showHandle),
	0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_PANEDWINDOW_WIDTH, offsetof(PanedWindow, widthPtr),
	offsetof(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec paneOptionSpecs[] = {
    {TK_OPTION_WINDOW, "-after", NULL, NULL,
	DEF_PANEDWINDOW_PANE_AFTER, TCL_INDEX_NONE, offsetof(Pane, after),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-before", NULL, NULL,
	DEF_PANEDWINDOW_PANE_BEFORE, TCL_INDEX_NONE, offsetof(Pane, before),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL,
	DEF_PANEDWINDOW_PANE_HEIGHT, offsetof(Pane, heightPtr),
	offsetof(Pane, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
	DEF_PANEDWINDOW_PANE_HIDE, TCL_INDEX_NONE, offsetof(Pane, hide), 0,0,GEOMETRY},
    {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
	DEF_PANEDWINDOW_PANE_MINSIZE, TCL_INDEX_NONE, offsetof(Pane, minSize), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	DEF_PANEDWINDOW_PANE_PADX, TCL_INDEX_NONE, offsetof(Pane, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	DEF_PANEDWINDOW_PANE_PADY, TCL_INDEX_NONE, offsetof(Pane, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	DEF_PANEDWINDOW_PANE_STICKY, TCL_INDEX_NONE, offsetof(Pane, sticky),
	0, &stickyOption, 0},
    {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch",
	DEF_PANEDWINDOW_PANE_STRETCH, TCL_INDEX_NONE, offsetof(Pane, stretch),
	TK_OPTION_ENUM_VAR, stretchStrings, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL,
	DEF_PANEDWINDOW_PANE_WIDTH, offsetof(Pane, widthPtr),
	offsetof(Pane, width), TK_OPTION_NULL_OK, 0, 0},
    {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
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
Tk_PanedWindowObjCmd(
    TCL_UNUSED(ClientData),	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    PanedWindow *pwPtr;
    Tk_Window tkwin, parent;
    OptionTables *pwOpts;







|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
Tk_PanedWindowObjCmd(
    TCL_UNUSED(void *),	/* 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;
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

    pwOpts = (OptionTables *)
	    Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
    if (pwOpts == NULL) {
	/*
	 * The first time this function is invoked, the option tables will be
	 * NULL. We then create the option tables from the templates and store
	 * a pointer to the tables as the command's clinical so we'll have
	 * easy access to it in the future.
	 */

	pwOpts = (OptionTables *)ckalloc(sizeof(OptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.







|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

    pwOpts = (OptionTables *)
	    Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
    if (pwOpts == NULL) {
	/*
	 * The first time this function is invoked, the option tables will be
	 * NULL. We then create the option tables from the templates and store
	 * a pointer to the tables as the command's clientData so we'll have
	 * easy access to it in the future.
	 */

	pwOpts = (OptionTables *)ckalloc(sizeof(OptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
PanedWindowWidgetObjCmd(
    ClientData clientData,	/* Information about square widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    int result = TCL_OK;
    static const char *const optionStrings[] = {







|







523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
PanedWindowWidgetObjCmd(
    void *clientData,	/* Information about square widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    int result = TCL_OK;
    static const char *const optionStrings[] = {
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
			pwPtr->panes[i], pwPtr->paneOpts,
			objv[3], tkwin);
	    }
	}
	if (resultObj == NULL) {
	    if (i == pwPtr->numPanes) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"not managed by this window", -1));
		Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED",
			NULL);
	    }
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}







|







668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
			pwPtr->panes[i], pwPtr->paneOpts,
			objv[3], tkwin);
	    }
	}
	if (resultObj == NULL) {
	    if (i == pwPtr->numPanes) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"not managed by this window", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED",
			NULL);
	    }
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
     */

    if (haveLoc && index == -1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" is not managed by %s",
		Tk_PathName(tkwin), Tk_PathName(pwPtr->tkwin)));
	Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED", NULL);
	Tk_FreeConfigOptions((char *) &options, pwPtr->paneOpts,
		pwPtr->tkwin);
	return TCL_ERROR;
    }

    /*
     * Allocate an array to hold, in order, the pointers to the pane
     * structures corresponding to the windows specified. Some of those







|







884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
     */

    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(&options, pwPtr->paneOpts,
		pwPtr->tkwin);
	return TCL_ERROR;
    }

    /*
     * Allocate an array to hold, in order, the pointers to the pane
     * structures corresponding to the windows specified. Some of those
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
    i = sizeof(Pane *) * (pwPtr->numPanes + numNewPanes);
    newPanes = (Pane **)ckalloc(i);
    memset(newPanes, 0, i);
    if (index == -1) {
	/*
	 * If none of the existing panes have to be moved, just copy the old
	 * and append the new.


	 */

	memcpy((void *)&(newPanes[0]), pwPtr->panes,
		sizeof(Pane *) * pwPtr->numPanes);

	memcpy((void *)&(newPanes[pwPtr->numPanes]), inserts,
		sizeof(Pane *) * numNewPanes);
    } else {
	/*
	 * If some of the existing panes were moved, the old panes array
	 * will be partially populated, with some valid and some invalid
	 * entries. Walk through it, copying valid entries to the new panes
	 * array as we go; when we get to the insert location for the new
	 * panes, copy the inserts array over, then finish off the old panes
	 * array.
	 */

	for (i = 0, j = 0; i < index; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
	}

	memcpy((void *)&(newPanes[j]), inserts, sizeof(Pane *)*insertIndex);
	j += firstOptionArg - 2;

	for (i = index; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }







>
>

>
|
|
>
|


















|







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
    i = sizeof(Pane *) * (pwPtr->numPanes + numNewPanes);
    newPanes = (Pane **)ckalloc(i);
    memset(newPanes, 0, i);
    if (index == -1) {
	/*
	 * If none of the existing panes have to be moved, just copy the old
	 * and append the new.
	 * Be careful about the case pwPtr->numPanes == 0 since in this case
	 * pwPtr->panes is NULL, and the memcpy would have undefined behavior.
	 */
	if (pwPtr->numPanes) {
	    memcpy(newPanes, pwPtr->panes,
		    sizeof(Pane *) * pwPtr->numPanes);
	}
	memcpy(&newPanes[pwPtr->numPanes], inserts,
		sizeof(Pane *) * numNewPanes);
    } else {
	/*
	 * If some of the existing panes were moved, the old panes array
	 * will be partially populated, with some valid and some invalid
	 * entries. Walk through it, copying valid entries to the new panes
	 * array as we go; when we get to the insert location for the new
	 * panes, copy the inserts array over, then finish off the old panes
	 * array.
	 */

	for (i = 0, j = 0; i < index; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
	}

	memcpy(&newPanes[j], inserts, sizeof(Pane *)*insertIndex);
	j += firstOptionArg - 2;

	for (i = index; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i] != NULL) {
		newPanes[j] = pwPtr->panes[i];
		j++;
	    }
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072

    /*
     * Set the paned window's pane count to the new value.
     */

    pwPtr->numPanes += numNewPanes;

    Tk_FreeConfigOptions((char *) &options, pwPtr->paneOpts, pwPtr->tkwin);

    ComputeGeometry(pwPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|







1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073

    /*
     * Set the paned window's pane count to the new value.
     */

    pwPtr->numPanes += numNewPanes;

    Tk_FreeConfigOptions(&options, pwPtr->paneOpts, pwPtr->tkwin);

    ComputeGeometry(pwPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135

	if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}
	panePtr = pwPtr->panes[sash];

	coords[0] = Tcl_NewWideIntObj(panePtr->sashx);
	coords[1] = Tcl_NewWideIntObj(panePtr->sashy);







|







1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136

	if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}
	panePtr = pwPtr->panes[sash];

	coords[0] = Tcl_NewWideIntObj(panePtr->sashx);
	coords[1] = Tcl_NewWideIntObj(panePtr->sashy);
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158

	if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}

	if (objc == 6) {
	    if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
		return TCL_ERROR;







|







1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159

	if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}

	if (objc == 6) {
	    if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
		return TCL_ERROR;
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194

	if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}

	if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
	    return TCL_ERROR;
	}







|







1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

	if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!ValidSashIndex(pwPtr, sash)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}

	if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
	    return TCL_ERROR;
	}
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
 *	Paned window will be relayed out and redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
PanedWindowWorldChanged(
    ClientData instanceData)	/* Information about the paned window. */
{
    XGCValues gcValues;
    GC newGC;
    PanedWindow *pwPtr = (PanedWindow *)instanceData;

    /*
     * Allocated a graphics context for drawing the paned window widget







|







1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
 *	Paned window will be relayed out and redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
PanedWindowWorldChanged(
    void *instanceData)	/* Information about the paned window. */
{
    XGCValues gcValues;
    GC newGC;
    PanedWindow *pwPtr = (PanedWindow *)instanceData;

    /*
     * Allocated a graphics context for drawing the paned window widget
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    int i;

    if (eventPtr->type == Expose) {
	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {







|







1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    int i;

    if (eventPtr->type == Expose) {
	if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
PanedWindowCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted or because the command was deleted,
     * and then this function destroys the widget. The WIDGET_DELETED flag







|







1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
PanedWindowCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted or because the command was deleted,
     * and then this function destroys the widget. The WIDGET_DELETED flag
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayPanedWindow(
    ClientData clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pane *panePtr;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->tkwin;
    int i, sashWidth, sashHeight;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);







|







1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayPanedWindow(
    void *clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pane *panePtr;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->tkwin;
    int i, sashWidth, sashHeight;
    const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
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
     *  o  Free memory for the pane
     */

    for (i = 0; i < pwPtr->numPanes; i++) {
	Tk_DeleteEventHandler(pwPtr->panes[i]->tkwin, StructureNotifyMask,
		PaneStructureProc, pwPtr->panes[i]);
	Tk_ManageGeometry(pwPtr->panes[i]->tkwin, NULL, NULL);
	Tk_FreeConfigOptions((char *) pwPtr->panes[i], pwPtr->paneOpts,
		pwPtr->tkwin);
	ckfree(pwPtr->panes[i]);
	pwPtr->panes[i] = NULL;
    }
    if (pwPtr->panes) {
	ckfree(pwPtr->panes);
    }

    /*
     * Remove the widget command from the interpreter.
     */

    Tcl_DeleteCommandFromToken(pwPtr->interp, pwPtr->widgetCmd);

    /*
     * Let Tk_FreeConfigOptions clean up the rest.
     */

    Tk_FreeConfigOptions((char *) pwPtr, pwPtr->optionTable, pwPtr->tkwin);
    Tcl_Release(pwPtr->tkwin);
    pwPtr->tkwin = NULL;

    Tcl_EventuallyFree(pwPtr, TCL_DYNAMIC);
}

/*







|


















|







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
     *  o  Free memory for the pane
     */

    for (i = 0; i < pwPtr->numPanes; i++) {
	Tk_DeleteEventHandler(pwPtr->panes[i]->tkwin, StructureNotifyMask,
		PaneStructureProc, pwPtr->panes[i]);
	Tk_ManageGeometry(pwPtr->panes[i]->tkwin, NULL, NULL);
	Tk_FreeConfigOptions(pwPtr->panes[i], pwPtr->paneOpts,
		pwPtr->tkwin);
	ckfree(pwPtr->panes[i]);
	pwPtr->panes[i] = NULL;
    }
    if (pwPtr->panes) {
	ckfree(pwPtr->panes);
    }

    /*
     * Remove the widget command from the interpreter.
     */

    Tcl_DeleteCommandFromToken(pwPtr->interp, pwPtr->widgetCmd);

    /*
     * Let Tk_FreeConfigOptions clean up the rest.
     */

    Tk_FreeConfigOptions(pwPtr, pwPtr->optionTable, pwPtr->tkwin);
    Tcl_Release(pwPtr->tkwin);
    pwPtr->tkwin = NULL;

    Tcl_EventuallyFree(pwPtr, TCL_DYNAMIC);
}

/*
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
 *	the next idle point.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowReqProc(
    ClientData clientData,	/* Paned window's information about window
				 * that got new preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;








|







1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
 *	the next idle point.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowReqProc(
    void *clientData,	/* Paned window's information about window
				 * that got new preferred geometry. */
    TCL_UNUSED(Tk_Window))		/* Other Tk-related information about the
				 * window. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
 *	recomputed for the panedwindow.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowLostPaneProc(
    ClientData clientData,	/* Grid structure for the pane that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the pane. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;

    if (pwPtr->tkwin != Tk_Parent(panePtr->tkwin)) {







|







1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
 *	recomputed for the panedwindow.
 *
 *--------------------------------------------------------------
 */

static void
PanedWindowLostPaneProc(
    void *clientData,	/* Grid structure for the pane that was
				 * stolen away. */
    TCL_UNUSED(Tk_Window))		/* Tk's handle for the pane. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = (PanedWindow *) panePtr->containerPtr;

    if (pwPtr->tkwin != Tk_Parent(panePtr->tkwin)) {
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
 *	The panes of containerPtr may get resized or moved.
 *
 *--------------------------------------------------------------
 */

static void
ArrangePanes(
    ClientData clientData)	/* Structure describing parent whose panes
				 * are to be re-layed out. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pane *panePtr;
    int i, newPaneWidth, newPaneHeight, paneX, paneY;
    int paneWidth, paneHeight, paneSize, paneMinSize;
    int doubleBw;







|







1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
 *	The panes of containerPtr may get resized or moved.
 *
 *--------------------------------------------------------------
 */

static void
ArrangePanes(
    void *clientData)	/* Structure describing parent whose panes
				 * are to be re-layed out. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pane *panePtr;
    int i, newPaneWidth, newPaneHeight, paneX, paneY;
    int paneWidth, paneHeight, paneSize, paneMinSize;
    int doubleBw;
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
 *	window which managed it.
 *
 *--------------------------------------------------------------
 */

static void
PaneStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = panePtr->containerPtr;

    if (eventPtr->type == DestroyNotify) {
	Unlink(panePtr);







|







2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
 *	window which managed it.
 *
 *--------------------------------------------------------------
 */

static void
PaneStructureProc(
    void *clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Pane *panePtr = (Pane *)clientData;
    PanedWindow *pwPtr = panePtr->containerPtr;

    if (eventPtr->type == DestroyNotify) {
	Unlink(panePtr);
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
 *	Frees memory.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    TCL_UNUSED(Tcl_Interp *))		/* Pointer to the calling interp */
{
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------







|







2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
 *	Frees memory.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyOptionTables(
    void *clientData,	/* Pointer to the OptionTables struct */
    TCL_UNUSED(Tcl_Interp *))		/* Pointer to the calling interp */
{
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
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
 */

static Tcl_Obj *
GetSticky(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
				 * sticky value. */
{
    int sticky = *(int *)(recordPtr + internalOffset);
    char buffer[5];
    char *p = &buffer[0];

    if (sticky & STICK_NORTH) {
	*p++ = 'n';
    }
    if (sticky & STICK_EAST) {
	*p++ = 'e';
    }
    if (sticky & STICK_SOUTH) {
	*p++ = 's';
    }
    if (sticky & STICK_WEST) {
	*p++ = 'w';
    }
    *p = '\0';

    return Tcl_NewStringObj(buffer, -1);
}

/*
 *----------------------------------------------------------------------
 *
 * SetSticky --
 *







|




















|







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
 */

static Tcl_Obj *
GetSticky(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    Tcl_Size internalOffset)		/* Offset within *recordPtr containing the
				 * sticky value. */
{
    int sticky = *(int *)(recordPtr + internalOffset);
    char buffer[5];
    char *p = &buffer[0];

    if (sticky & STICK_NORTH) {
	*p++ = 'n';
    }
    if (sticky & STICK_EAST) {
	*p++ = 'e';
    }
    if (sticky & STICK_SOUTH) {
	*p++ = 's';
    }
    if (sticky & STICK_WEST) {
	*p++ = 'w';
    }
    *p = '\0';

    return Tcl_NewStringObj(buffer, TCL_INDEX_NONE);
}

/*
 *----------------------------------------------------------------------
 *
 * SetSticky --
 *
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    TCL_UNUSED(Tk_Window),	/* Window for which option is being set. */
    Tcl_Obj **value,		/* Pointer to the pointer to the value object.
				 * We use a pointer to the pointer because we
				 * may need to return a value (NULL). */
    char *recordPtr,		/* Pointer to storage for the widget record. */
    TkSizeT internalOffset,		/* Offset within *recordPtr at which the
				 * internal value is to be stored. */
    char *oldInternalPtr,	/* Pointer to storage for the old value. */
    int flags)			/* Flags for the option, set Tk_SetOptions. */
{
    int sticky = 0;
    char c;
    void *internalPtr;







|







2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    TCL_UNUSED(Tk_Window),	/* Window for which option is being set. */
    Tcl_Obj **value,		/* Pointer to the pointer to the value object.
				 * We use a pointer to the pointer because we
				 * may need to return a value (NULL). */
    char *recordPtr,		/* Pointer to storage for the widget record. */
    Tcl_Size 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;
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ProxyWindowEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;

    if (eventPtr->type == Expose) {
	if (pwPtr->proxywin != NULL &&!(pwPtr->flags & PROXY_REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayProxyWindow, pwPtr);







|







2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ProxyWindowEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;

    if (eventPtr->type == Expose) {
	if (pwPtr->proxywin != NULL &&!(pwPtr->flags & PROXY_REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(DisplayProxyWindow, pwPtr);
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayProxyWindow(
    ClientData clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->proxywin;
    pwPtr->flags &= ~PROXY_REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;







|







2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayProxyWindow(
    void *clientData)	/* Information about window. */
{
    PanedWindow *pwPtr = (PanedWindow *)clientData;
    Pixmap pixmap;
    Tk_Window tkwin = pwPtr->proxywin;
    pwPtr->flags &= ~PROXY_REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
 *
 *----------------------------------------------------------------------
 */

static void *
ComputeSlotAddress(
    void *recordPtr,	/* Pointer to the start of a record. */
    TkSizeT offset)		/* Offset of a slot within that record; may be TCL_INDEX_NONE. */
{
    if (offset != TCL_INDEX_NONE) {
	return (char *)recordPtr + offset;
    } else {
	return NULL;
    }
}







|







3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
 *
 *----------------------------------------------------------------------
 */

static void *
ComputeSlotAddress(
    void *recordPtr,	/* Pointer to the start of a record. */
    Tcl_Size offset)		/* Offset of a slot within that record; may be TCL_INDEX_NONE. */
{
    if (offset != TCL_INDEX_NONE) {
	return (char *)recordPtr + offset;
    } else {
	return NULL;
    }
}
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
     * is called inside the implementation of a command).
     */

    if (found != -1) {
	Tcl_Obj *list[2];

	list[0] = Tcl_NewWideIntObj(found);
	list[1] = Tcl_NewStringObj((isHandle ? "handle" : "sash"), -1);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, list));
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|












3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
     * is called inside the implementation of a command).
     */

    if (found != -1) {
	Tcl_Obj *list[2];

	list[0] = Tcl_NewWideIntObj(found);
	list[1] = Tcl_NewStringObj((isHandle ? "handle" : "sash"), TCL_INDEX_NONE);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, list));
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkPkgConfig.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * 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]>
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/* Note, the definitions in this module are influenced by the following C
 * preprocessor macros:
 *
 * OSCMa  = shortcut for "old style configuration macro activates"
 * NSCMdt = shortcut for "new style configuration macro declares that"
 *
 * - TCL_THREADS		OSCMa compilation as threaded.
 * - TCL_MEM_DEBUG		OSCMa memory debugging.
 *
 * - TCL_CFG_DO64BIT		NSCMdt tk is compiled for a 64bit system.
 * - NDEBUG			NSCMdt tk is compiled with symbol info off.
 * - TCL_CFG_OPTIMIZED		NSCMdt tk is compiled with cc optimizations on
 * - TCL_CFG_PROFILED		NSCMdt tk is compiled with profiling info.
 *
 * - _WIN32 || __CYGWIN__	The value for the fontsytem key will be
 *   MAC_OSX_TK			chosen based on these macros/defines.
 *   HAVE_XFT			NSCMdt xft font support was requested.
 *
 * - CFG_RUNTIME_*		Paths to various stuff at runtime.
 * - CFG_INSTALL_*		Paths to various stuff at installation time.
 *
 * - TCL_CFGVAL_ENCODING	string containing the encoding used for the
 *				configuration values.
 */

#include "tkInt.h"


#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "utf-8"
#endif

/*
 * Use C preprocessor statements to define the various values for the embedded
 * configuration information.
 */

#ifdef TCL_THREADS
#  define  CFG_THREADED		"1"
#else
#  define  CFG_THREADED		"0"
#endif

#ifdef TCL_MEM_DEBUG
#  define CFG_MEMDEBUG		"1"
#else
#  define CFG_MEMDEBUG		"0"
#endif

#ifdef TCL_CFG_DO64BIT
#  define CFG_64		"1"
#else
#  define CFG_64		"0"
#endif

#ifndef NDEBUG
#  define CFG_DEBUG		"1"
#else
#  define CFG_DEBUG		"0"
#endif

#ifdef TCL_CFG_OPTIMIZED
#  define CFG_OPTIMIZED		"1"
#else
#  define CFG_OPTIMIZED		"0"
#endif

#ifdef TCL_CFG_PROFILED
#  define CFG_PROFILED		"1"
#else
#  define CFG_PROFILED		"0"
#endif

#if defined(_WIN32)
#  define CFG_FONTSYSTEM	"gdi"
#elif defined(MAC_OSX_TK)
#  define CFG_FONTSYSTEM	"cocoa"
#elif defined(HAVE_XFT)
#  define CFG_FONTSYSTEM	"xft"
#else
#  define CFG_FONTSYSTEM	"x11"
#endif

static const Tcl_Config cfg[] = {
    {"debug",			CFG_DEBUG},
    {"threaded",		CFG_THREADED},
    {"profiled",		CFG_PROFILED},
    {"64bit",			CFG_64},
    {"optimized",		CFG_OPTIMIZED},
#ifdef TK_NO_DEPRECATED
    {"nodeprecated",	"1"},
#endif
    {"mem_debug",		CFG_MEMDEBUG},
    {"fontsystem",		CFG_FONTSYSTEM},

    /* Runtime paths to various stuff */

#ifdef CFG_RUNTIME_LIBDIR
    {"libdir,runtime",		CFG_RUNTIME_LIBDIR},
#endif






|
|








<
<
<
<
<
<
<
<
<
<
<


|




















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16











17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39




































40
41
42
43
44
45
46
47
48
49
50









51
52
53
54
55
56
57
/*
 * tkPkgConfig.c --
 *
 *	This file contains the configuration information to embed into the tcl
 *	binary library.
 *
 * 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:
 *











 * - _WIN32 || __CYGWIN__	The value for the fontsytem key will be
 *   MAC_OSX_TK			chosen based on these macros/defines.
 *   HAVE_XFT			declares that xft font support was requested.
 *
 * - CFG_RUNTIME_*		Paths to various stuff at runtime.
 * - CFG_INSTALL_*		Paths to various stuff at installation time.
 *
 * - TCL_CFGVAL_ENCODING	string containing the encoding used for the
 *				configuration values.
 */

#include "tkInt.h"


#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "utf-8"
#endif

/*
 * Use C preprocessor statements to define the various values for the embedded
 * configuration information.
 */





































#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[] = {









    {"fontsystem",		CFG_FONTSYSTEM},

    /* Runtime paths to various stuff */

#ifdef CFG_RUNTIME_LIBDIR
    {"libdir,runtime",		CFG_RUNTIME_LIBDIR},
#endif
122
123
124
125
126
127
128



129
130
131
132
133
134
135
#endif
#ifdef CFG_RUNTIME_DOCDIR
    {"docdir,runtime",		CFG_RUNTIME_DOCDIR},
#endif
#ifdef CFG_RUNTIME_DEMODIR
    {"demodir,runtime",		CFG_RUNTIME_DEMODIR},
#endif




    /* Installation paths to various stuff */

#ifdef CFG_INSTALL_LIBDIR
    {"libdir,install",		CFG_INSTALL_LIBDIR},
#endif
#ifdef CFG_INSTALL_BINDIR







>
>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#endif
#ifdef CFG_RUNTIME_DOCDIR
    {"docdir,runtime",		CFG_RUNTIME_DOCDIR},
#endif
#ifdef CFG_RUNTIME_DEMODIR
    {"demodir,runtime",		CFG_RUNTIME_DEMODIR},
#endif
#if !defined(STATIC_BUILD)
    {"dllfile,runtime",		CFG_RUNTIME_DLLFILE},
#endif

    /* Installation paths to various stuff */

#ifdef CFG_INSTALL_LIBDIR
    {"libdir,install",		CFG_INSTALL_LIBDIR},
#endif
#ifdef CFG_INSTALL_BINDIR

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
/*
 * 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.
 *
 * 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 container window.
 * BM_OUTSIDE:		relative distances computed using outside area that
 *			includes all borders of container.
 * BM_IGNORE:		border issues are ignored: place relative to container's
 *			actual window size.
 */

static const char *const borderModeStrings[] = {
    "inside", "outside", "ignore", NULL
};

typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;

/*
 * For each window whose geometry is managed by the placer there is a
 * structure of the following type:
 */

typedef struct Content {






|
|



















|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
 * tkPlace.c --
 *
 *	This file contains code to implement a simple geometry manager for Tk
 *	based on absolute placement or "rubber-sheet" placement.
 *
 * 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 container window.
 * BM_OUTSIDE:		relative distances computed using outside area that
 *			includes all borders of container.
 * BM_IGNORE:		border issues are ignored: place relative to container's
 *			actual window size.
 */

static const char *const borderModeStrings[] = {
    "inside", "ignore", "outside", NULL
};

typedef enum {BM_INSIDE, BM_IGNORE, BM_OUTSIDE} BorderMode;

/*
 * For each window whose geometry is managed by the placer there is a
 * structure of the following type:
 */

typedef struct Content {
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    double relWidth, relHeight;	/* Dimensions for tkwin relative to size of
				 * container. */
    Tcl_Obj *relWidthPtr;
    Tcl_Obj *relHeightPtr;
    Tk_Anchor anchor;		/* Which point on tkwin is placed at the given
				 * position. */
    BorderMode borderMode;	/* How to treat borders of container window. */
    int flags;			/* Various flags; see below for bit
				 * definitions. */
} Content;

/*
 * Type masks for options:
 */

#define IN_MASK		1

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", TCL_INDEX_NONE,
	 offsetof(Content, anchor), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", TCL_INDEX_NONE,
	 offsetof(Content, borderMode), 0, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", offsetof(Content, heightPtr),
	 offsetof(Content, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", TCL_INDEX_NONE, offsetof(Content, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 offsetof(Content, relHeightPtr), offsetof(Content, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 offsetof(Content, relWidthPtr), offsetof(Content, relWidth),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", TCL_INDEX_NONE,
	 offsetof(Content, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", TCL_INDEX_NONE,
	 offsetof(Content, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", offsetof(Content, widthPtr),
	 offsetof(Content, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", offsetof(Content, xPtr),
	 offsetof(Content, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", offsetof(Content, yPtr),
	 offsetof(Content, y), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * Flag definitions for Content structures:
 *
 * CHILD_WIDTH -		1 means -width was specified;
 * CHILD_REL_WIDTH -		1 means -relwidth was specified.
 * CHILD_HEIGHT -		1 means -height was specified;
 * CHILD_REL_HEIGHT -		1 means -relheight was specified.
 */

#define CHILD_WIDTH		1
#define CHILD_REL_WIDTH		2
#define CHILD_HEIGHT		4
#define CHILD_REL_HEIGHT	8

/*
 * For each container window that has a content managed by the placer there is a
 * structure of the following form:
 */

typedef struct Container {
    Tk_Window tkwin;		/* Tk's token for container window. */







<
<










|

|










|

|










<
<
<
<
<
<
<
<
<
<
<
<
<
<







66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108














109
110
111
112
113
114
115
    double relWidth, relHeight;	/* Dimensions for tkwin relative to size of
				 * container. */
    Tcl_Obj *relWidthPtr;
    Tcl_Obj *relHeightPtr;
    Tk_Anchor anchor;		/* Which point on tkwin is placed at the given
				 * position. */
    BorderMode borderMode;	/* How to treat borders of container window. */


} Content;

/*
 * Type masks for options:
 */

#define IN_MASK		1

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", TCL_INDEX_NONE,
	 offsetof(Content, anchor), TK_OPTION_ENUM_VAR, 0, 0},
    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", TCL_INDEX_NONE,
	 offsetof(Content, borderMode), TK_OPTION_ENUM_VAR, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", offsetof(Content, heightPtr),
	 offsetof(Content, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", TCL_INDEX_NONE, offsetof(Content, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 offsetof(Content, relHeightPtr), offsetof(Content, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 offsetof(Content, relWidthPtr), offsetof(Content, relWidth),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0.0", TCL_INDEX_NONE,
	 offsetof(Content, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0.0", TCL_INDEX_NONE,
	 offsetof(Content, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", offsetof(Content, widthPtr),
	 offsetof(Content, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", offsetof(Content, xPtr),
	 offsetof(Content, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", offsetof(Content, yPtr),
	 offsetof(Content, y), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};















/*
 * For each container window that has a content managed by the placer there is a
 * structure of the following form:
 */

typedef struct Container {
    Tk_Window tkwin;		/* Tk's token for container window. */
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

#define PARENT_RECONFIG_PENDING	1

/*
 * The following structure is the official type record for the placer:
 */

static void		PlaceRequestProc(ClientData clientData,
			    Tk_Window tkwin);
static void		PlaceLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr placerType = {
    "place",			/* name */
    PlaceRequestProc,		/* requestProc */
    PlaceLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ContentStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_OptionTable table, int objc,
			    Tcl_Obj *const objv[]);
static int		PlaceInfoCommand(Tcl_Interp *interp, Tk_Window tkwin);
static Content *		CreateContent(Tk_Window tkwin, Tk_OptionTable table);
static void		FreeContent(Content *contentPtr);
static Content *		FindContent(Tk_Window tkwin);
static Container *		CreateContainer(Tk_Window tkwin);
static Container *		FindContainer(Tk_Window tkwin);
static void		PlaceStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		RecomputePlacement(ClientData clientData);
static void		UnlinkContent(Content *contentPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_PlaceObjCmd --
 *







|

|












|










|

|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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 PARENT_RECONFIG_PENDING	1

/*
 * The following structure is the official type record for the placer:
 */

static void		PlaceRequestProc(void *clientData,
			    Tk_Window tkwin);
static void		PlaceLostContentProc(void *clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr placerType = {
    "place",			/* name */
    PlaceRequestProc,		/* requestProc */
    PlaceLostContentProc,		/* lostContentProc */
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		ContentStructureProc(void *clientData,
			    XEvent *eventPtr);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_OptionTable table, int objc,
			    Tcl_Obj *const objv[]);
static int		PlaceInfoCommand(Tcl_Interp *interp, Tk_Window tkwin);
static Content *		CreateContent(Tk_Window tkwin, Tk_OptionTable table);
static void		FreeContent(Content *contentPtr);
static Content *		FindContent(Tk_Window tkwin);
static Container *		CreateContainer(Tk_Window tkwin);
static Container *		FindContainer(Tk_Window tkwin);
static void		PlaceStructureProc(void *clientData,
			    XEvent *eventPtr);
static void		RecomputePlacement(void *clientData);
static void		UnlinkContent(Content *contentPtr);

/*
 *--------------------------------------------------------------
 *
 * Tk_PlaceObjCmd --
 *
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_PlaceObjCmd(
    ClientData clientData,	/* Interpreter main window. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window main_win = (Tk_Window)clientData;
    Tk_Window tkwin;
    Content *contentPtr;







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_PlaceObjCmd(
    void *clientData,	/* Interpreter main window. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window main_win = (Tk_Window)clientData;
    Tk_Window tkwin;
    Content *contentPtr;
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,







|
|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObj(NULL, objv[1], optionStrings,
	    "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
406
407
408
409
410
411
412




413
414
415
416
417
418
419

    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;
}








>
>
>
>







390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

    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->width = INT_MIN;
    contentPtr->height = INT_MIN;
    contentPtr->relWidth = NAN;
    contentPtr->relHeight = NAN;
    contentPtr->optionTable = table;
    Tcl_SetHashValue(hPtr, contentPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    return contentPtr;
}

433
434
435
436
437
438
439



440
441
442
443
444
445
446
447
 *----------------------------------------------------------------------
 */

static void
FreeContent(
    Content *contentPtr)
{



    Tk_FreeConfigOptions((char *) contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------
 *







>
>
>
|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
 *----------------------------------------------------------------------
 */

static void
FreeContent(
    Content *contentPtr)
{
    if (contentPtr->containerPtr && (contentPtr->containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	Tcl_CancelIdleCall(RecomputePlacement, contentPtr->containerPtr);
    }
    Tk_FreeConfigOptions(contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------
 *
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
    contentPtr = CreateContent(tkwin, table);

    if (Tk_SetOptions(interp, contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set content flags. First clear the field, then add bits as needed.
     */

    contentPtr->flags = 0;
    if (contentPtr->heightPtr) {
	contentPtr->flags |= CHILD_HEIGHT;
    }

    if (contentPtr->relHeightPtr) {
	contentPtr->flags |= CHILD_REL_HEIGHT;
    }

    if (contentPtr->relWidthPtr) {
	contentPtr->flags |= CHILD_REL_WIDTH;
    }

    if (contentPtr->widthPtr) {
	contentPtr->flags |= CHILD_WIDTH;
    }

    if (!(mask & IN_MASK) && (contentPtr->containerPtr != NULL)) {
	/*
	 * If no -in option was passed and the content is already placed then
	 * just recompute the placement.
	 */

	containerPtr = contentPtr->containerPtr;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







633
634
635
636
637
638
639





















640
641
642
643
644
645
646
    contentPtr = CreateContent(tkwin, table);

    if (Tk_SetOptions(interp, contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }






















    if (!(mask & IN_MASK) && (contentPtr->containerPtr != NULL)) {
	/*
	 * If no -in option was passed and the content is already placed then
	 * just recompute the placement.
	 */

	containerPtr = contentPtr->containerPtr;
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

    contentPtr = FindContent(tkwin);
    if (contentPtr == NULL) {
	return TCL_OK;
    }
    infoObj = Tcl_NewObj();
    if (contentPtr->containerPtr != NULL) {
	Tcl_AppendToObj(infoObj, "-in", -1);
	Tcl_ListObjAppendElement(NULL, infoObj,
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_AppendToObj(infoObj, " ", -1);
    }
    Tcl_AppendPrintfToObj(infoObj,
	    "-x %d -relx %.4g -y %d -rely %.4g",
	    contentPtr->x, contentPtr->relX, contentPtr->y, contentPtr->relY);
    if (contentPtr->flags & CHILD_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj, " -width %d", contentPtr->width);
    } else {
	Tcl_AppendToObj(infoObj, " -width {}", -1);
    }
    if (contentPtr->flags & CHILD_REL_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relwidth %.4g", contentPtr->relWidth);
    } else {
	Tcl_AppendToObj(infoObj, " -relwidth {}", -1);
    }
    if (contentPtr->flags & CHILD_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj, " -height %d", contentPtr->height);
    } else {
	Tcl_AppendToObj(infoObj, " -height {}", -1);
    }
    if (contentPtr->flags & CHILD_REL_HEIGHT) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relheight %.4g", contentPtr->relHeight);
    } else {
	Tcl_AppendToObj(infoObj, " -relheight {}", -1);
    }

    Tcl_AppendPrintfToObj(infoObj, " -anchor %s -bordermode %s",
	    Tk_NameOfAnchor(contentPtr->anchor),
	    borderModeStrings[contentPtr->borderMode]);
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;







|


|




|


|

|



|

|


|

|



|







782
783
784
785
786
787
788
789
790
791
792
793
794
795
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

    contentPtr = FindContent(tkwin);
    if (contentPtr == NULL) {
	return TCL_OK;
    }
    infoObj = Tcl_NewObj();
    if (contentPtr->containerPtr != NULL) {
	Tcl_AppendToObj(infoObj, "-in", TCL_INDEX_NONE);
	Tcl_ListObjAppendElement(NULL, infoObj,
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_AppendToObj(infoObj, " ", TCL_INDEX_NONE);
    }
    Tcl_AppendPrintfToObj(infoObj,
	    "-x %d -relx %.4g -y %d -rely %.4g",
	    contentPtr->x, contentPtr->relX, contentPtr->y, contentPtr->relY);
    if (contentPtr->widthPtr) {
	Tcl_AppendPrintfToObj(infoObj, " -width %d", contentPtr->width);
    } else {
	Tcl_AppendToObj(infoObj, " -width {}", TCL_INDEX_NONE);
    }
    if (contentPtr->relWidthPtr) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relwidth %.4g", contentPtr->relWidth);
    } else {
	Tcl_AppendToObj(infoObj, " -relwidth {}", TCL_INDEX_NONE);
    }
    if (contentPtr->heightPtr) {
	Tcl_AppendPrintfToObj(infoObj, " -height %d", contentPtr->height);
    } else {
	Tcl_AppendToObj(infoObj, " -height {}", TCL_INDEX_NONE);
    }
    if (contentPtr->relHeightPtr) {
	Tcl_AppendPrintfToObj(infoObj,
		" -relheight %.4g", contentPtr->relHeight);
    } else {
	Tcl_AppendToObj(infoObj, " -relheight {}", TCL_INDEX_NONE);
    }

    Tcl_AppendPrintfToObj(infoObj, " -anchor %s -bordermode %s",
	    Tk_NameOfAnchor(contentPtr->anchor),
	    borderModeStrings[contentPtr->borderMode]);
    Tcl_SetObjResult(interp, infoObj);
    return TCL_OK;
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
 *	Windows may change size or shape.
 *
 *----------------------------------------------------------------------
 */

static void
RecomputePlacement(
    ClientData clientData)	/* Pointer to Container record. */
{
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr;
    int x, y, width, height, tmp;
    int containerWidth, containerHeight, containerX, containerY;
    double x1, y1, x2, y2;
    int abort;			/* May get set to non-zero to abort this







|







839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
 *	Windows may change size or shape.
 *
 *----------------------------------------------------------------------
 */

static void
RecomputePlacement(
    void *clientData)	/* Pointer to Container record. */
{
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr;
    int x, y, width, height, tmp;
    int containerWidth, containerHeight, containerX, containerY;
    double x1, y1, x2, y2;
    int abort;			/* May get set to non-zero to abort this
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
	 * and location of anchor point within container.
	 */

	x1 = contentPtr->x + containerX + (contentPtr->relX*containerWidth);
	x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
	y1 = contentPtr->y + containerY + (contentPtr->relY*containerHeight);
	y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
	if (contentPtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
	    width = 0;
	    if (contentPtr->flags & CHILD_WIDTH) {
		width += contentPtr->width;
	    }
	    if (contentPtr->flags & CHILD_REL_WIDTH) {
		/*
		 * The code below is a bit tricky. In order to round correctly
		 * when both relX and relWidth are specified, compute the
		 * location of the right edge and round that, then compute
		 * width. If we compute the width and round it, rounding
		 * errors in relX and relWidth accumulate.
		 */

		x2 = x1 + (contentPtr->relWidth*containerWidth);
		tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
		width += tmp - x;
	    }
	} else {
	    width = Tk_ReqWidth(contentPtr->tkwin)
		    + 2*Tk_Changes(contentPtr->tkwin)->border_width;
	}
	if (contentPtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
	    height = 0;
	    if (contentPtr->flags & CHILD_HEIGHT) {
		height += contentPtr->height;
	    }
	    if (contentPtr->flags & CHILD_REL_HEIGHT) {
		/*
		 * See note above for rounding errors in width computation.
		 */

		y2 = y1 + (contentPtr->relHeight*containerHeight);
		tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
		height += tmp - y;







|

|


|
















|

|


|







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
	 * and location of anchor point within container.
	 */

	x1 = contentPtr->x + containerX + (contentPtr->relX*containerWidth);
	x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
	y1 = contentPtr->y + containerY + (contentPtr->relY*containerHeight);
	y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
	if ((contentPtr->widthPtr) || contentPtr->relWidthPtr) {
	    width = 0;
	    if (contentPtr->widthPtr) {
		width += contentPtr->width;
	    }
	    if (contentPtr->relWidthPtr) {
		/*
		 * The code below is a bit tricky. In order to round correctly
		 * when both relX and relWidth are specified, compute the
		 * location of the right edge and round that, then compute
		 * width. If we compute the width and round it, rounding
		 * errors in relX and relWidth accumulate.
		 */

		x2 = x1 + (contentPtr->relWidth*containerWidth);
		tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
		width += tmp - x;
	    }
	} else {
	    width = Tk_ReqWidth(contentPtr->tkwin)
		    + 2*Tk_Changes(contentPtr->tkwin)->border_width;
	}
	if (contentPtr->heightPtr || contentPtr->relHeightPtr) {
	    height = 0;
	    if (contentPtr->heightPtr) {
		height += contentPtr->height;
	    }
	    if (contentPtr->relHeightPtr) {
		/*
		 * See note above for rounding errors in width computation.
		 */

		y2 = y1 + (contentPtr->relHeight*containerHeight);
		tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
		height += tmp - y;
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
	    y -= height;
	    break;
	case TK_ANCHOR_W:
	    y -= height/2;
	    break;
	case TK_ANCHOR_NW:
	    break;
	case TK_ANCHOR_CENTER:
	    x -= width/2;
	    y -= height/2;
	    break;
	}

	/*
	 * Step 4: adjust width and height again to reflect inside dimensions







|







976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
	    y -= height;
	    break;
	case TK_ANCHOR_W:
	    y -= height/2;
	    break;
	case TK_ANCHOR_NW:
	    break;
	default:
	    x -= width/2;
	    y -= height/2;
	    break;
	}

	/*
	 * Step 4: adjust width and height again to reflect inside dimensions
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
 *	resized then content geometries get recomputed.
 *
 *----------------------------------------------------------------------
 */

static void
PlaceStructureProc(
    ClientData clientData,	/* Pointer to Container structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr, *nextPtr;
    TkDisplay *dispPtr = ((TkWindow *) containerPtr->tkwin)->dispPtr;








|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
 *	resized then content geometries get recomputed.
 *
 *----------------------------------------------------------------------
 */

static void
PlaceStructureProc(
    void *clientData,	/* Pointer to Container structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Container *containerPtr = (Container *)clientData;
    Content *contentPtr, *nextPtr;
    TkDisplay *dispPtr = ((TkWindow *) containerPtr->tkwin)->dispPtr;

1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
 *	Structures get cleaned up if the window was deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ContentStructureProc(
    ClientData clientData,	/* Pointer to Content structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {







|







1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
 *	Structures get cleaned up if the window was deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ContentStructureProc(
    void *clientData,	/* Pointer to Content structure for window
				 * referred to by eventPtr. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
 *	do with its actual size.
 *
 *----------------------------------------------------------------------
 */

static void
PlaceRequestProc(
    ClientData clientData,	/* Pointer to our record for content. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    Content *contentPtr = (Content *)clientData;
    Container *containerPtr;

    if ((contentPtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH))
	    && (contentPtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) {
        /*
         * Send a ConfigureNotify to indicate that the size change
         * request was rejected.
         */

        TkDoConfigureNotify((TkWindow *)(contentPtr->tkwin));
	return;







|





|
|







1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
 *	do with its actual size.
 *
 *----------------------------------------------------------------------
 */

static void
PlaceRequestProc(
    void *clientData,	/* Pointer to our record for content. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    Content *contentPtr = (Content *)clientData;
    Container *containerPtr;

    if ((contentPtr->widthPtr || contentPtr->relWidthPtr)
	    && (contentPtr->heightPtr || contentPtr->relHeightPtr)) {
        /*
         * Send a ConfigureNotify to indicate that the size change
         * request was rejected.
         */

        TkDoConfigureNotify((TkWindow *)(contentPtr->tkwin));
	return;
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
 *	Forgets all placer-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
PlaceLostContentProc(
    ClientData clientData,	/* Content structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {







|







1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
 *	Forgets all placer-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
PlaceLostContentProc(
    void *clientData,	/* Content structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {

Changes to generic/tkPlatDecls.h.

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.
 *
 * 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





|







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 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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
EXTERN Window		Tk_AttachHWND(Tk_Window tkwin, HWND hwnd);
/* 1 */
EXTERN HINSTANCE	Tk_GetHINSTANCE(void);
/* 2 */
EXTERN HWND		Tk_GetHWND(Window window);
/* 3 */
EXTERN Tk_Window	Tk_HWNDToWindow(HWND hwnd);
/* 4 */
EXTERN void		Tk_PointerEvent(HWND hwnd, int x, int y);
/* 5 */
EXTERN int		Tk_TranslateWinEvent(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam,
				LRESULT *result);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */
/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);
/* 5 */
EXTERN void		TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);
/* 6 */
EXTERN void		TkMacOSXInvalClipRgns(Tk_Window tkwin);
/* Slot 7 is reserved */
/* 8 */
EXTERN void *		TkMacOSXGetRootControl(Drawable drawable);
/* 9 */
EXTERN void		Tk_MacOSXSetupTkNotifier(void);







<
<
<
<
<
<








|
<
<







42
43
44
45
46
47
48






49
50
51
52
53
54
55
56
57


58
59
60
61
62
63
64
EXTERN Window		Tk_AttachHWND(Tk_Window tkwin, HWND hwnd);
/* 1 */
EXTERN HINSTANCE	Tk_GetHINSTANCE(void);
/* 2 */
EXTERN HWND		Tk_GetHWND(Window window);
/* 3 */
EXTERN Tk_Window	Tk_HWNDToWindow(HWND hwnd);






#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */
/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);
/* Slot 5 is reserved */


/* 6 */
EXTERN void		TkMacOSXInvalClipRgns(Tk_Window tkwin);
/* Slot 7 is reserved */
/* 8 */
EXTERN void *		TkMacOSXGetRootControl(Drawable drawable);
/* 9 */
EXTERN void		Tk_MacOSXSetupTkNotifier(void);
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    Window (*tk_AttachHWND) (Tk_Window tkwin, HWND hwnd); /* 0 */
    HINSTANCE (*tk_GetHINSTANCE) (void); /* 1 */
    HWND (*tk_GetHWND) (Window window); /* 2 */
    Tk_Window (*tk_HWNDToWindow) (HWND hwnd); /* 3 */
    void (*tk_PointerEvent) (HWND hwnd, int x, int y); /* 4 */
    int (*tk_TranslateWinEvent) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved0)(void);
    void (*reserved1)(void);
    void (*reserved2)(void);
    void (*reserved3)(void);
    void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */
    void (*tkGenWMConfigureEvent_) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */
    void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */
    void (*reserved7)(void);
    void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
    void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
    int (*tk_MacOSXIsAppInFront) (void); /* 10 */
    Tk_Window (*tk_MacOSXGetTkWindow) (void *w); /* 11 */
    void * (*tk_MacOSXGetCGContextForDrawable) (Drawable drawable); /* 12 */







<
<







|







82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    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 */


#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved0)(void);
    void (*reserved1)(void);
    void (*reserved2)(void);
    void (*reserved3)(void);
    void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */
    void (*reserved5)(void);
    void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */
    void (*reserved7)(void);
    void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
    void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
    int (*tk_MacOSXIsAppInFront) (void); /* 10 */
    Tk_Window (*tk_MacOSXGetTkWindow) (void *w); /* 11 */
    void * (*tk_MacOSXGetCGContextForDrawable) (Drawable drawable); /* 12 */
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
	(tkPlatStubsPtr->tk_AttachHWND) /* 0 */
#define Tk_GetHINSTANCE \
	(tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */
#define Tk_GetHWND \
	(tkPlatStubsPtr->tk_GetHWND) /* 2 */
#define Tk_HWNDToWindow \
	(tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */
#define Tk_PointerEvent \
	(tkPlatStubsPtr->tk_PointerEvent) /* 4 */
#define Tk_TranslateWinEvent \
	(tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */
#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */
#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 5 */
#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */
/* Slot 7 is reserved */
#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */
#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */







<
<
<
<








|
<







125
126
127
128
129
130
131




132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
	(tkPlatStubsPtr->tk_AttachHWND) /* 0 */
#define Tk_GetHINSTANCE \
	(tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */
#define Tk_GetHWND \
	(tkPlatStubsPtr->tk_GetHWND) /* 2 */
#define Tk_HWNDToWindow \
	(tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */




#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */
#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */
/* Slot 5 is reserved */

#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */
/* Slot 7 is reserved */
#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */
#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */
181
182
183
184
185
186
187
188
189
190
191
#ifdef __cplusplus
}
#endif

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkGenWMConfigureEvent_
#define Tk_MacOSXGetNSViewForDrawable TkMacOSXGetRootControl

#endif /* _TKPLATDECLS */







<



166
167
168
169
170
171
172

173
174
175
#ifdef __cplusplus
}
#endif

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT


#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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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 © 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"

430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
    (void)event_mask;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)confine_to;
    (void)cursor;
    (void)time;

    display->request++;
    tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window);
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(tsdPtr->grabWinPtr);
    if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr)
	    != TK_GRAB_IN_TREE) {
	UpdateCursor(tsdPtr->grabWinPtr);
    }







|







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
    (void)event_mask;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)confine_to;
    (void)cursor;
    (void)time;

    LastKnownRequestProcessed(display)++;
    tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window);
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(tsdPtr->grabWinPtr);
    if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr)
	    != TK_GRAB_IN_TREE) {
	UpdateCursor(tsdPtr->grabWinPtr);
    }
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
    Display *display,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)time;

    display->request++;
    tsdPtr->grabWinPtr = NULL;
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(NULL);
    UpdateCursor(tsdPtr->lastWinPtr);
    return Success;
}








|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
    Display *display,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)time;

    LastKnownRequestProcessed(display)++;
    tsdPtr->grabWinPtr = NULL;
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(NULL);
    UpdateCursor(tsdPtr->lastWinPtr);
    return Success;
}

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
TkPointerDeadWindow(
    TkWindow *winPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr == tsdPtr->lastWinPtr) {
	tsdPtr->lastWinPtr = NULL;
    }
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;
    }







|







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
TkPointerDeadWindow(
    TkWindow *winPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr == tsdPtr->lastWinPtr) {
	tsdPtr->lastWinPtr = TkGetContainer(winPtr);
    }
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;
    }
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)cursor;

    if (tsdPtr->cursorWinPtr == winPtr) {
	UpdateCursor(winPtr);
    }
    display->request++;
    return Success;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|










594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)cursor;

    if (tsdPtr->cursorWinPtr == winPtr) {
	UpdateCursor(winPtr);
    }
    LastKnownRequestProcessed(display)++;
    return Success;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Added generic/tkRangeList.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
/*
 * tkRangeList.c --
 *
 *	This module implements operations on a list of integer ranges.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkRangeList.h"

#include <assert.h>

#ifndef MIN
# define MIN(a,b) ((a) < (b) ? a : b)
#endif
#ifndef MAX
# define MAX(a,b) ((a) < (b) ? b : a)
#endif

#ifdef TK_CHECK_ALLOCS
# define DEBUG_ALLOC(expr) expr
#else
# define DEBUG_ALLOC(expr)
#endif


#define MEM_SIZE(size) (offsetof(TkRangeList, items) + (size)*sizeof(TkRange))


DEBUG_ALLOC(unsigned tkRangeListCountNew = 0);
DEBUG_ALLOC(unsigned tkRangeListCountDestroy = 0);


#ifndef NDEBUG

static unsigned
CountIntegers(
    const TkRangeList *ranges)
{
    int count = 0;

    if (ranges->size > 0) {
	const TkRange *r = ranges->items;
	unsigned i;

	assert(r->low <= r->high);
	count += TkRangeSpan(r);

	for (i = 1; i < ranges->size; ++i) {
	    r = ranges->items + i;
	    assert(r->low <= r->high);
	    assert((r - 1)->high + 1 < r->low);
	    count += TkRangeSpan(r);
	}
    }

    return count;
}

#endif /* NDEBUG */


static TkRange *
LowerBound(
    TkRange *first,
    TkRange *last,
    int low)
{
    /*
     * Note that we want to amalgamate adjacent ranges, and this binary
     * search is designed for this requirement.
     *
     * Example for ranges={{2,3}{6,7}}:
     *
     *   low < 5       -> {2,3}
     *   low = 5,6,7,8 -> {6,7}
     *   low > 8       -> last
     */

    if (first == last) {
	return first;
    }

    low -= 1;

    do {
	TkRange *mid = first + (last - first)/2;

	if (mid->high < low) {
	    first = mid + 1;
	} else {
	    last = mid;
	}
    } while (first != last);

    return first;
}


static TkRange *
Increase(
    TkRangeList **rangesPtr)
{
    TkRangeList *ranges = *rangesPtr;

    if (ranges->size == ranges->capacity) {
	ranges->capacity = MAX(1, 2*ranges->capacity);
	ranges = (TkRangeList *)ckrealloc(ranges, MEM_SIZE(ranges->capacity));
	*rangesPtr = ranges;
    }

    return ranges->items + ranges->size++;
}


static TkRange *
Insert(
    TkRangeList **rangesPtr,
    TkRange *entry)
{
    TkRangeList *ranges = *rangesPtr;
    unsigned pos = entry - ranges->items;

    if (ranges->size == ranges->capacity) {
	TkRangeList *newRanges;
	TkRange *newEntry;

	ranges->capacity = MAX(1, 2*ranges->capacity);
	newRanges = (TkRangeList *)ckalloc(MEM_SIZE(ranges->capacity));
	newRanges->capacity = ranges->capacity;
	newRanges->size = ranges->size + 1;
	newRanges->count = ranges->count;
	newEntry = newRanges->items + pos;
	memcpy(newRanges->items, ranges->items, pos*sizeof(TkRange));
	memcpy(newEntry + 1, entry, (ranges->size - pos)*sizeof(TkRange));
	ckfree(ranges);
	*rangesPtr = ranges = newRanges;
	entry = newEntry;
    } else {
	memmove(entry + 1, entry, (ranges->size - pos)*sizeof(TkRange));
	ranges->size += 1;
    }

    return entry;
}


static void
Amalgamate(
    TkRangeList *ranges,
    TkRange *curr)
{
    const TkRange *last = ranges->items + ranges->size;
    TkRange *next = curr + 1;
    int high = curr->high;

    while (next != last && high + 1 >= next->low) {
	if (high >= next->high) {
	    ranges->count -= TkRangeSpan(next);
	} else if (high >= next->low) {
	    ranges->count -= high - next->low + 1;
	}
	next += 1;
    }

    if (next != curr + 1) {
	curr->high = MAX((next - 1)->high, high);
	memmove(curr + 1, next, (last - next)*sizeof(TkRange));
	ranges->size -= (next - curr) - 1;
	assert(CountIntegers(ranges) == ranges->count);
    }
}


TkRangeList *
TkRangeListCreate(unsigned capacity)
{
    TkRangeList *ranges;

    ranges = (TkRangeList *)ckalloc(MEM_SIZE(capacity));
    ranges->size = 0;
    ranges->capacity = capacity;
    ranges->count = 0;
    DEBUG_ALLOC(tkRangeListCountNew++);
    return ranges;
}


TkRangeList *
TkRangeListCopy(
    const TkRangeList *ranges)
{
    TkRangeList *copy;
    unsigned memSize;

    assert(ranges);

    copy = (TkRangeList *)ckalloc(memSize = MEM_SIZE(ranges->size));
    memcpy(copy, ranges, memSize);
    DEBUG_ALLOC(tkRangeListCountNew++);
    return copy;
}


void
TkRangeListDestroy(
    TkRangeList **rangesPtr)
{
    assert(rangesPtr);

    if (*rangesPtr) {
	ckfree(*rangesPtr);
	*rangesPtr = NULL;
	DEBUG_ALLOC(tkRangeListCountDestroy++);
    }
}


void
TkRangeListClear(
    TkRangeList *ranges)
{
    assert(ranges);

    ranges->size = 0;
    ranges->count = 0;
}


int
TkRangeListContainsAny(
    const TkRangeList *ranges,
    int low,
    int high)
{
    const TkRange *last;
    const TkRange *entry;

    assert(ranges);

    last = ranges->items + ranges->size;
    entry = LowerBound((TkRange *) ranges->items, (TkRange *) last, low);

    if (entry == last) {
	return 0;
    }

    if (entry->high == low + 1 && ++entry == last) {
	return 0;
    }

    return high >= entry->low;
}


void
TkRangeListTruncateAtFront(
    TkRangeList *ranges,
    int untilThisValue)
{
    TkRange *last;
    TkRange *curr;
    TkRange *r;

    assert(ranges);

    last = ranges->items + ranges->size;
    curr = LowerBound(ranges->items, last, untilThisValue);

    if (curr == last) {
	return;
    }

    if (curr->low <= untilThisValue) {
	if (untilThisValue < curr->high) {
	    ranges->count -= untilThisValue - curr->low + 1;
	    curr->low = untilThisValue + 1;
	} else {
	    curr += 1;
	}
    }

    if (curr != ranges->items) {
	for (r = ranges->items; r != curr; ++r) {
	    ranges->count -= TkRangeSpan(r);
	}
	memmove(ranges->items, curr, (last - curr)*sizeof(TkRange));
	ranges->size -= curr - ranges->items;
    }

    assert(CountIntegers(ranges) == ranges->count);
}


void
TkRangeListTruncateAtEnd(
    TkRangeList *ranges,
    int maxValue)
{
    TkRange *last;
    TkRange *curr;

    assert(ranges);

    last = ranges->items + ranges->size;
    curr = LowerBound(ranges->items, last, maxValue);

    if (curr == last) {
	return;
    }

    if (curr->low <= maxValue) {
	if (curr->high > maxValue) {
	    ranges->count -= curr->high - maxValue;
	    curr->high = maxValue;
	}
	curr += 1;
    }

    ranges->size -= last - curr;

    for ( ; curr != last; ++curr) {
	ranges->count -= TkRangeSpan(curr);
    }

    assert(CountIntegers(ranges) == ranges->count);
}


const TkRange *
TkRangeListFind(
    const TkRangeList *ranges,
    int value)
{
    const TkRange *last;
    const TkRange *entry;

    assert(ranges);

    last = ranges->items + ranges->size;
    entry = LowerBound((TkRange *) ranges->items, (TkRange *) last, value);

    if (entry == last || entry->low > value || value > entry->high) {
	return NULL;
    }
    return entry;
}


const TkRange *
TkRangeListFindNearest(
    const TkRangeList *ranges,
    int value)
{
    const TkRange *last;
    const TkRange *entry;

    assert(ranges);

    last = ranges->items + ranges->size;
    entry = LowerBound((TkRange *) ranges->items, (TkRange *) last, value);

    if (entry == last) {
	return NULL;
    }
    if (value > entry->high) {
	if (++entry == last) {
	    return NULL;
	}
    }
    return entry;
}


TkRangeList *
TkRangeListAdd(
    TkRangeList *ranges,
    int low,
    int high)
{
    TkRange *last;
    TkRange *curr;

    assert(low <= high);

    last = ranges->items + ranges->size;

    if (ranges->size == 0) {
	curr = last;
    } else if (low >= (last - 1)->low) {
	/* catch a frequent case */
	curr = (low > (last - 1)->high + 1) ? last : last - 1;
    } else {
	curr = LowerBound(ranges->items, last, low);
    }

    if (curr == last) {
	/* append new entry */
	curr = Increase(&ranges);
	curr->low = low;
	curr->high = high;
	ranges->count += high - low + 1;
    } else if (low + 1 < curr->low) {
	if (curr->low <= high + 1) {
	    /* new lower bound of current range */
	    ranges->count += curr->low - low;
	    curr->low = low;
	} else {
	    /* insert new entry before current */
	    curr = Insert(&ranges, curr);
	    curr->low = low;
	    curr->high = high;
	    ranges->count += high - low + 1;
	}
    } else {
	if (low + 1 == curr->low) {
	    /* new lower bound of current range */
	    ranges->count += 1;
	    curr->low = low;
	}
	if (last - 1 != curr && (last - 1)->high <= high) {
	    /* catch a frequent case: we don't need the succeeding items */
	    for (--last; last > curr; --last) {
		ranges->count -= TkRangeSpan(last);
	    }
	    ranges->count += high - curr->high;
	    ranges->size = (curr + 1) - ranges->items;
	    curr->high = high;
	} else if (curr->high < high) {
	    /* new upper bound of current range */
	    ranges->count += high - curr->high;
	    curr->high = high;
	    /* possibly we have to amalgamate succeeding items */
	    Amalgamate(ranges, curr);
	}
    }

    return ranges;
}


TkRangeList *
TkRangeListInsert(
    TkRangeList *ranges,
    int low,
    int high)
{
    TkRange *curr;
    TkRange *last;
    int span = high - low + 1;

    assert(ranges);
    assert(low <= high);

    last = ranges->items + ranges->size;
    curr = LowerBound(ranges->items, last, low);

    /* {2,2} : insert {0,0} -> {0,0}{3,3} */
    /* {2,2} : insert {1,1} -> {1,1}{3,3} */
    /* {2,2} : insert {2,2} -> {2,3} */
    /* {2,2} : insert {3,3} -> {2,3} */
    /* {2,4} : insert {3,3} -> {2,5} */
    /* {2,4} : insert {4,4} -> {2,5} */
    /* {2,4} : insert {5,5} -> {2,5} */

    if (curr == last || low > curr->high + 1) {
	/* append new entry */
	curr = Increase(&ranges);
	curr->low = low;
	curr->high = high;
    } else {
	if (low >= curr->low) {
	    /* new upper bound of current range */
	    curr->high += span;
	} else {
	    /* insert new entry before current */
	    curr = Insert(&ranges, curr);
	    curr->low = low;
	    curr->high = high;
	}
	/* adjust all successors */
	last = ranges->items + ranges->size;
	for (++curr; curr != last; ++curr) {
	    curr->low += span;
	    curr->high += span;
	}
    }

    ranges->count += span;
    assert(CountIntegers(ranges) == ranges->count);
    return ranges;
}


TkRangeList *
TkRangeListRemove(
    TkRangeList *ranges,
    int low,
    int high)
{
    TkRange *curr;
    TkRange *last;
    int span;

    assert(ranges);
    assert(low <= high);

    if (ranges->size == 0) {
	return ranges;
    }

    last = ranges->items + ranges->size;
    low = MAX(low, ranges->items[0].low);
    high = MIN(high, (last - 1)->high);

    if (low > high) {
	return ranges;
    }

    span = high - low + 1;
    curr = LowerBound(ranges->items, last, low);

    if (curr != last) {
	TkRange *next;
	unsigned size;

	if (high < curr->high) {
	    if (curr->low < low) {
		/* Example: cur:{1,4} - arg:{2,3} -> {1,1}{4,4} */
		int h = curr->high;
		ranges->count -= span;
		curr->high = low - 1;
		low = high + 1;
		curr = (curr == last) ? Increase(&ranges) : Insert(&ranges, curr + 1);
		curr->low = low;
		curr->high = h;
	    } else if (curr->low <= high) {
		/* Example: cur:{1,4} - arg:{1,3} -> {4,4} */
		int tmp = high + 1;
		ranges->count -= tmp - curr->low;
		curr->low = tmp;
	    }
	} else {
	    if (curr->low < low && low <= curr->high) {
		/* Example: cur:{1,7} - arg:{2,5} -> {1,1} */
		/* Example: cur:{1,3} - arg:{3,6} -> {1,2} */
		/* Example: cur:{1,1} - arg:{2,5} -> {1,1} */
		int tmp = low - 1;
		ranges->count -= curr->high - tmp;
		curr->high = tmp;
		curr += 1;
	    } else if (curr->high < low) {
		curr += 1;
	    }

	    for (next = curr; next != last && next->high <= high; ++next) {
		ranges->count -= TkRangeSpan(next);
	    }

	    memmove(curr, next, (last - next)*sizeof(TkRange));
	    ranges->size -= (size = next - curr);
	    last -= size;

	    if (curr != last) {
		if (curr->low <= high) {
		    ranges->count -= high + 1 - curr->low;
		    curr->low = high + 1;
		}
	    }
	}
    }

    assert(CountIntegers(ranges) == ranges->count);
    return ranges;
}


TkRangeList *
TkRangeListDelete(
    TkRangeList *ranges,
    int low,
    int high)
{
    TkRange *curr;
    TkRange *last;
    TkRange *next;
    unsigned size;
    int span;

    assert(ranges);
    assert(low <= high);

    if (ranges->size == 0 || low > TkRangeListHigh(ranges)) {
	return ranges;
    }

    last = ranges->items + ranges->size;
    span = high - low + 1;
    curr = LowerBound(ranges->items, last, low);
    assert(curr != last);

    while (curr != last && curr->high < low) {
	curr += 1;
    }

    /* we have: low <= curr->high */

    for ( ; curr != last && curr->low < low; ++curr) {
	if (curr->high <= high) {
	    ranges->count -= TkRangeSpan(curr);
	    curr->high = curr->low;
	    ranges->count += 1;
	} else {
	    ranges->count -= span;
	    curr->high -= span;
	}
    }

    /* we have: low <= curr->low AND low <= curr->high */

    for (next = curr; next != last && next->high <= high; ++next) {
	ranges->count -= TkRangeSpan(next);
    }
    memmove(curr, next, (last - next)*sizeof(TkRange));
    ranges->size -= (size = next - curr);
    last -= size;

    if (curr != last) {
	/* we have: low <= curr->low AND high < curr->high */

	if (curr->low <= high) {
	    ranges->count -= TkRangeSpan(curr);
	    if (curr->low <= high) {
		curr->low = high + 1 - span;
	    } else {
		curr->low -= span;
	    }
	    curr->high -= span;
	    assert(curr->low <= curr->high);
	    ranges->count += TkRangeSpan(curr);

	    /* possibly we have to amalgamate with previous */

	    if (curr > ranges->items) {
		TkRange *prev = curr - 1;

		if (prev->high + 1 >= curr->low) {
		    ranges->count -= TkRangeSpan(curr);
		    ranges->count -= TkRangeSpan(prev);
		    prev->high = curr->high;
		    ranges->count += TkRangeSpan(prev);
		    next = curr + 1;
		    memmove(curr, next, (last - curr)*sizeof(TkRange));
		    ranges->size -= 1;
		    last -= 1;
		}
	    } else {
		curr += 1;
	    }
	}

	/* reduce the rest by span: */

	for ( ; curr != last; ++curr) {
	    assert(curr->low > high);
	    curr->low -= span;
	    curr->high -= span;
	}
    }

    assert(CountIntegers(ranges) == ranges->count);
    return ranges;
}


#ifndef NDEBUG

void
TkRangeListPrint(
    const TkRangeList *ranges)
{
    unsigned i;

    printf("RangeList(%d):", ranges->count);
    for (i = 0; i < ranges->size; ++i) {
	printf(" {%d,%d}", ranges->items[i].low, ranges->items[i].high);
    }
    printf("\n");
}

#endif /* NDEBUG */


/* Additionally we need stand-alone object code. */
extern int TkRangeSpan(const TkRange *range);
extern int TkRangeTest(const TkRange *range, int value);
extern int TkRangeListLow(const TkRangeList *ranges);
extern int TkRangeListHigh(const TkRangeList *ranges);
extern unsigned TkRangeListSpan(const TkRangeList *ranges);
extern unsigned TkRangeListCount(const TkRangeList *ranges);
extern unsigned TkRangeListSize(const TkRangeList *ranges);
extern const TkRange *TkRangeListAccess(const TkRangeList *ranges, unsigned index);
extern const TkRange *TkRangeListFirst(const TkRangeList *ranges);
extern const TkRange *TkRangeListNext(const TkRangeList *ranges, const TkRange *item);
extern int TkRangeListIsEmpty(const TkRangeList *ranges);
extern int TkRangeListContains(const TkRangeList *ranges, int value);
extern int TkRangeListContainsRange(const TkRangeList *ranges, int low, int high);

/* vi:set ts=8 sw=4: */

Added generic/tkRangeList.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
/*
 * tkRangeList.h --
 *
 *	This module implements operations on a list of integer ranges.
 *	Note that the current implementation expects short lists of
 *	ranges, it is quite slow for large list sizes (large number of
 *	range items).
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKRANGELIST
#define _TKRANGELIST

#include "tkInt.h" /* required for inline support */

#if defined(__GNUC__) || defined(__clang__)
# define __warn_unused__ __attribute__((warn_unused_result))
#else
# define __warn_unused__
#endif


typedef struct TkRange {
    int low;
    int high;
} TkRange;

/*
 * Return the span of given range.
 */
inline int TkRangeSpan(const TkRange *range);

/*
 * Test whether given range contains the specified value.
 */
inline int TkRangeTest(const TkRange *range, int value);


typedef struct TkRangeList {
    unsigned size;
    unsigned capacity;
    unsigned count;
    TkRange items[1];
} TkRangeList;

/*
 * Create a range list, and reserve some space for range entries.
 */
TkRangeList *TkRangeListCreate(unsigned capacity) __warn_unused__;

/*
 * Make a copy of given list.
 */
TkRangeList *TkRangeListCopy(const TkRangeList *ranges) __warn_unused__;

/*
 * Destroy the range list, the derefenced pointer can be NULL (in this case the
 * list is already destroyed).
 */
void TkRangeListDestroy(TkRangeList **rangesPtr);

/*
 * Clear the given list of ranges.
 */
void TkRangeListClear(TkRangeList *ranges);

/*
 * Truncate this list at front until given value (inclusive). This means that after
 * truncation the lowest value in this list will be larger than 'untilThisValue'.
 */
void TkRangeListTruncateAtFront(TkRangeList *ranges, int untilThisValue);

/*
 * Truncate this list at end with given value (exclusive). This means that after
 * truncation the highest value in this list will be less or equal to 'maxValue'.
 */
void TkRangeListTruncateAtEnd(TkRangeList *ranges, int maxValue);

/*
 * Return the lower value of the entry with lowest order (ths lowest value inside
 * the whole list).
 */
inline int TkRangeListLow(const TkRangeList *ranges);

/*
 * Return the upper value of the entry with highest order (ths highest value inside
 * the whole list).
 */
inline int TkRangeListHigh(const TkRangeList *ranges);

/*
 * Return the span of the whole list (= TkRangeListHigh(ranges) - TkRangeListLow(ranges) + 1).
 */
inline unsigned TkRangeListSpan(const TkRangeList *ranges);

/*
 * Return the number of integers contained in this list.
 */
inline unsigned TkRangeListCount(const TkRangeList *ranges);

/*
 * Return the number of entries (pairs) in this list.
 */
inline unsigned TkRangeListSize(const TkRangeList *ranges);

/*
 * Return a specific entry (pair), the index must not exceed the size of this list.
 */
inline const TkRange *TkRangeListAccess(const TkRangeList *ranges, unsigned index);

/*
 * Find entry (pair) which contains the given value. NULL will be returned if
 * this value is not contained in this list.
 */
const TkRange *TkRangeListFind(const TkRangeList *ranges, int value);

/*
 * Find entry (pair) which contains the given value. If this value is not contained
 * in given list then return the item with a low value nearest to specified value.
 * But it never returns an item with a high value less than given value, so it's
 * possible that NULL we returned.
 */
const TkRange *TkRangeListFindNearest(const TkRangeList *ranges, int value);

/*
 * Return the first item in given list, can be NULL if list is empty.
 */
inline const TkRange *TkRangeListFirst(const TkRangeList *ranges);

/*
 * Return the next item in given list, can be NULL if at end of list.
 */
inline const TkRange *TkRangeListNext(const TkRangeList *ranges, const TkRange *item);

/*
 * Return whether this list is empty.
 */
inline int TkRangeListIsEmpty(const TkRangeList *ranges);

/*
 * Return whether the given value is contained in this list.
 */
inline int TkRangeListContains(const TkRangeList *ranges, int value);

/*
 * Return whether the given range is contained in this list.
 */
inline int TkRangeListContainsRange(const TkRangeList *ranges, int low, int high);

/*
 * Return whether any value of the given range is contained in this list.
 */
int TkRangeListContainsAny(const TkRangeList *ranges, int low, int high);

/*
 * Add given range to this list. Adjacent entries (pairs) will be amalgamated
 * automatically.
 */
TkRangeList *TkRangeListAdd(TkRangeList *ranges, int low, int high) __warn_unused__;

/*
 * Remove given range from list. Adjacent entries (pairs) will be amalgamated
 * automatically.
 */
TkRangeList *TkRangeListRemove(TkRangeList *ranges, int low, int high);

/*
 * Insert given range to this list. This method has the side effect that all contained
 * integers with a value higher than the 'high' value will be increased by the span of
 * the given range (high - low + 1). Adjacent entries (pairs) will be amalgamated
 * automatically.
 *
 * Example: TkRangeListInsert({{5,6} {8,9}}, 1, 5) -> {{1,5} {10,11} {13,14}}
 */
TkRangeList *TkRangeListInsert(TkRangeList *ranges, int low, int high) __warn_unused__;

/*
 * Delete given range from list. This method has the side effect that all contained
 * integers with a value higher than the 'low' value will be decreased by the span of
 * the given range (high - low + 1). Adjacent entries (pairs) will be amalgamated
 * automatically.
 *
 * Example: TkRangeListDelete({{5,6} {8,9}}, 1, 5) -> {{1} {3,4}}
 */
TkRangeList *TkRangeListDelete(TkRangeList *ranges, int low, int high);

#ifndef NDEBUG
void TkRangeListPrint(const TkRangeList *ranges);
#endif


#define _TK_NEED_IMPLEMENTATION
#include "tkRangeListPriv.h"
#endif /* _TKRANGELIST */
/* vi:set ts=8 sw=4: */

Added generic/tkRangeListPriv.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
/*
 * tkRangeListPriv.h --
 *
 *	Private implementation for range list.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKRANGELIST
# error "do not include this private header file"
#endif


#ifdef _TK_NEED_IMPLEMENTATION

#include <stddef.h>
#include <assert.h>


inline
int
TkRangeSpan(
    const TkRange *range)
{
    assert(range);
    return range->high - range->low + 1;
}


inline
int
TkRangeTest(
    const TkRange *range,
    int value)
{
    assert(range);
    return range->low <= value && value <= range->high;
}


inline
int
TkRangeListIsEmpty(
    const TkRangeList *ranges)
{
    assert(ranges);
    return ranges->size == 0;
}


inline
int
TkRangeListLow(
    const TkRangeList *ranges)
{
    assert(ranges);
    assert(!TkRangeListIsEmpty(ranges));
    return ranges->items[0].low;
}


inline
int
TkRangeListHigh(
    const TkRangeList *ranges)
{
    assert(ranges);
    assert(!TkRangeListIsEmpty(ranges));
    return ranges->items[ranges->size - 1].high;
}


inline
unsigned
TkRangeListSpan(
    const TkRangeList *ranges)
{
    assert(ranges);
    return ranges->size ? TkRangeListHigh(ranges) - TkRangeListLow(ranges) + 1 : 0;
}


inline
unsigned
TkRangeListSize(
    const TkRangeList *ranges)
{
    assert(ranges);
    return ranges->size;
}


inline
unsigned
TkRangeListCount(
    const TkRangeList *ranges)
{
    assert(ranges);
    return ranges->count;
}


inline
const TkRange *
TkRangeListAccess(
    const TkRangeList *ranges,
    unsigned index)
{
    assert(ranges);
    assert(index < TkRangeListSize(ranges));
    return &ranges->items[index];
}


inline
int
TkRangeListContains(
    const TkRangeList *ranges,
    int value)
{
    return !!TkRangeListFind(ranges, value);
}


inline
int
TkRangeListContainsRange(
    const TkRangeList *ranges,
    int low,
    int high)
{
    const TkRange *range = TkRangeListFind(ranges, low);
    return range && range->high <= high;
}


inline
const TkRange *
TkRangeListFirst(
    const TkRangeList *ranges)
{
    assert(ranges);
    return ranges->size == 0 ? NULL : ranges->items;
}


inline
const TkRange *
TkRangeListNext(
    const TkRangeList *ranges,
    const TkRange *item)
{
    assert(item);
    assert(ranges);
    assert(ranges->items <= item && item < ranges->items + ranges->size);
    return ++item == ranges->items + ranges->size ? NULL : item;
}


#undef _TK_NEED_IMPLEMENTATION
#endif /* _TK_NEED_IMPLEMENTATION */
/* vi:set ts=8 sw=4: */

Changes to generic/tkRectOval.c.

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.
 *
 * 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"





|
|







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 © 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"
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};







|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
	NULL, offsetof(RectOvalItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(RectOvalItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(RectOvalItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(RectOvalItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},







|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
	NULL, offsetof(RectOvalItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(RectOvalItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(RectOvalItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(RectOvalItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeRectOvalBbox(Tk_Canvas canvas,
			    RectOvalItem *rectOvalPtr);
static int		ConfigureRectOval(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[],
			    int flags);
static int		CreateRectOval(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);
static void		DeleteRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
			    Display *display);
static void		DisplayRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
			    Display *display, Drawable dst, int x, int y,
			    int width, int height);
static int		OvalToArea(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *areaPtr);
static double		OvalToPoint(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *pointPtr);
static int		RectOvalCoords(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);
static int		RectOvalToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static int		RectToArea(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *areaPtr);
static double		RectToPoint(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *pointPtr);
static void		RotateRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,







|


|










|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeRectOvalBbox(Tk_Canvas canvas,
			    RectOvalItem *rectOvalPtr);
static int		ConfigureRectOval(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[],
			    int flags);
static int		CreateRectOval(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static void		DeleteRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
			    Display *display);
static void		DisplayRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
			    Display *display, Drawable dst, int x, int y,
			    int width, int height);
static int		OvalToArea(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *areaPtr);
static double		OvalToPoint(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *pointPtr);
static int		RectOvalCoords(Tcl_Interp *interp, Tk_Canvas canvas,
			    Tk_Item *itemPtr, Tcl_Size objc, Tcl_Obj *const objv[]);
static int		RectOvalToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static int		RectToArea(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *areaPtr);
static double		RectToPoint(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double *pointPtr);
static void		RotateRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    sizeof(RectOvalItem),	/* itemSize */
    CreateRectOval,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureRectOval,		/* configureProc */
    RectOvalCoords,		/* coordProc */
    DeleteRectOval,		/* deleteProc */
    DisplayRectOval,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    RectToPoint,		/* pointProc */
    RectToArea,			/* areaProc */
    RectOvalToPostscript,	/* postscriptProc */
    ScaleRectOval,		/* scaleProc */
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */







|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    sizeof(RectOvalItem),	/* itemSize */
    CreateRectOval,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureRectOval,		/* configureProc */
    RectOvalCoords,		/* coordProc */
    DeleteRectOval,		/* deleteProc */
    DisplayRectOval,		/* displayProc */
    0,				/* flags */
    RectToPoint,		/* pointProc */
    RectToArea,			/* areaProc */
    RectOvalToPostscript,	/* postscriptProc */
    ScaleRectOval,		/* scaleProc */
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    sizeof(RectOvalItem),	/* itemSize */
    CreateRectOval,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureRectOval,		/* configureProc */
    RectOvalCoords,		/* coordProc */
    DeleteRectOval,		/* deleteProc */
    DisplayRectOval,		/* displayProc */
    TK_CONFIG_OBJS,		/* flags */
    OvalToPoint,		/* pointProc */
    OvalToArea,			/* areaProc */
    RectOvalToPostscript,	/* postscriptProc */
    ScaleRectOval,		/* scaleProc */
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */







|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    sizeof(RectOvalItem),	/* itemSize */
    CreateRectOval,		/* createProc */
    configSpecs,		/* configSpecs */
    ConfigureRectOval,		/* configureProc */
    RectOvalCoords,		/* coordProc */
    DeleteRectOval,		/* deleteProc */
    DisplayRectOval,		/* displayProc */
    0,				/* flags */
    OvalToPoint,		/* pointProc */
    OvalToArea,			/* areaProc */
    RectOvalToPostscript,	/* postscriptProc */
    ScaleRectOval,		/* scaleProc */
    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

static int
CreateRectOval(
    Tcl_Interp *interp,		/* For error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    int objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    int i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after







|



|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

static int
CreateRectOval(
    Tcl_Interp *interp,		/* For error reporting. */
    Tk_Canvas canvas,		/* Canvas to hold new item. */
    Tk_Item *itemPtr,		/* Record to hold new item; header has been
				 * initialized by caller. */
    Tcl_Size objc,			/* Number of arguments in objv. */
    Tcl_Obj *const objv[])	/* Arguments describing rectangle. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    Tcl_Size i;

    if (objc == 0) {
	Tcl_Panic("canvas did not pass any coords");
    }

    /*
     * Carry out initialization that is needed in order to clean up after
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

static int
RectOvalCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    int objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1,y1,x2,y2,... */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;

    /*
     * If no coordinates, return the current coordinates (i.e. bounding box).
     */







|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

static int
RectOvalCoords(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item whose coordinates are to be read or
				 * modified. */
    Tcl_Size objc,			/* Number of coordinates supplied in objv. */
    Tcl_Obj *const objv[])	/* Array of coordinates: x1,y1,x2,y2,... */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;

    /*
     * If no coordinates, return the current coordinates (i.e. bounding box).
     */
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

    /*
     * Better have four coordinates now. Spit out an error message otherwise.
     */

    if (objc != 4) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS",
		(rectOvalPtr->header.typePtr == &tkRectangleType
			? "RECTANGLE" : "OVAL"), NULL);
	return TCL_ERROR;
    }

    /*







|







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

    /*
     * Better have four coordinates now. Spit out an error message otherwise.
     */

    if (objc != 4) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %" TCL_SIZE_MODIFIER "d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS",
		(rectOvalPtr->header.typePtr == &tkRectangleType
			? "RECTANGLE" : "OVAL"), NULL);
	return TCL_ERROR;
    }

    /*
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
 */

static int
ConfigureRectOval(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Rectangle item to reconfigure. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);

    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **)objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }
    state = itemPtr->state;

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.







|
















|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
 */

static int
ConfigureRectOval(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Rectangle item to reconfigure. */
    Tcl_Size objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    XGCValues gcValues;
    GC newGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_TSOffset *tsoffset;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);

    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    objv, rectOvalPtr, flags)) {
	return TCL_ERROR;
    }
    state = itemPtr->state;

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteRectOval(
    Tk_Canvas canvas,		/* Info about overall widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    (void)canvas;

    Tk_DeleteOutline(display, &(rectOvalPtr->outline));
    if (rectOvalPtr->fillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->fillColor);
    }
    if (rectOvalPtr->activeFillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->activeFillColor);







|




<







570
571
572
573
574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteRectOval(
    TCL_UNUSED(Tk_Canvas),		/* Info about overall widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;


    Tk_DeleteOutline(display, &(rectOvalPtr->outline));
    if (rectOvalPtr->fillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->fillColor);
    }
    if (rectOvalPtr->activeFillColor != NULL) {
	Tk_FreeColor(rectOvalPtr->activeFillColor);
740
741
742
743
744
745
746
747
748
749


750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

static void
DisplayRectOval(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y, int width, int height)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */


{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    short x1, y1, x2, y2;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    (void)x;
    (void)y;
    (void)width;
    (void)height;

    /*
     * Compute the screen coordinates of the bounding box for the item. Make
     * sure that the bbox is at least one pixel large, since some X servers
     * will die if it isn't.
     */








<
|
|
>
>





<
<
<
<







739
740
741
742
743
744
745

746
747
748
749
750
751
752
753
754




755
756
757
758
759
760
761

static void
DisplayRectOval(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */

    TCL_UNUSED(int),/* Describes region of canvas that must be */
    TCL_UNUSED(int),/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    short x1, y1, x2, y2;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;





    /*
     * Compute the screen coordinates of the bounding box for the item. Make
     * sure that the bbox is at least one pixel large, since some X servers
     * will die if it isn't.
     */

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
 */

static int
RectOvalToPostscript(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    int prepass)		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    Tcl_Obj *pathObj, *psObj;
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    double y1, y2;
    XColor *color;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    Tcl_InterpState interpState;
    (void)prepass;

    y1 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[1]);
    y2 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[3]);

    /*
     * Generate a string that creates a path for the rectangle or oval. This
     * is the only part of the function's code that is type-specific.







|











<







1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448
1449
1450
1451
 */

static int
RectOvalToPostscript(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Information about overall canvas. */
    Tk_Item *itemPtr,		/* Item for which Postscript is wanted. */
    TCL_UNUSED(int))		/* 1 means this is a prepass to collect font
				 * information; 0 means final Postscript is
				 * being created. */
{
    Tcl_Obj *pathObj, *psObj;
    RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
    double y1, y2;
    XColor *color;
    XColor *fillColor;
    Pixmap fillStipple;
    Tk_State state = itemPtr->state;
    Tcl_InterpState interpState;


    y1 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[1]);
    y2 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[3]);

    /*
     * Generate a string that creates a path for the rectangle or oval. This
     * is the only part of the function's code that is type-specific.
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
	Tcl_AppendObjToObj(psObj, pathObj);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {
	Tcl_AppendObjToObj(psObj, pathObj);
	Tcl_AppendToObj(psObj, "0 setlinejoin 2 setlinecap\n", -1);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &rectOvalPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    }

    /*







|





|


|









|







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
	Tcl_AppendObjToObj(psObj, pathObj);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", TCL_INDEX_NONE);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", TCL_INDEX_NONE);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", TCL_INDEX_NONE);
	}
    }

    /*
     * Now draw the outline, if there is one.
     */

    if (color != NULL) {
	Tcl_AppendObjToObj(psObj, pathObj);
	Tcl_AppendToObj(psObj, "0 setlinejoin 2 setlinecap\n", TCL_INDEX_NONE);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &rectOvalPtr->outline);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    }

    /*

Changes to generic/tkScale.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScale.h"
#include "default.h"

#if defined(_WIN32)
#define snprintf _snprintf
#endif

/*
 * The following table defines the legal values for the -orient option. It is
 * used together with the "enum orient" declaration in tkScale.h.
 */

static const char *const orientStrings[] = {
    "horizontal", "vertical", NULL
};

/*
 * The following table defines the legal values for the -state option. It is
 * used together with the "enum state" declaration in tkScale.h.
 */

static const char *const stateStrings[] = {
    "active", "disabled", "normal", NULL
};

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCALE_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, activeBorder),
	0, DEF_SCALE_ACTIVE_BG_MONO, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_SCALE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, bgBorder),
	0, DEF_SCALE_BG_MONO, 0},











|
|
|









|
|











<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36









37
38
39
40
41
42
43
/*
 * 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 © 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"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following table defines the legal values for the -orient option. It is
 * used together with the "enum orient" declaration in tkScale.h.
 */

static const char *const orientStrings[] = {
    "horizontal", "vertical", NULL
};










static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCALE_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, activeBorder),
	0, DEF_SCALE_ACTIVE_BG_MONO, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_SCALE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, bgBorder),
	0, DEF_SCALE_BG_MONO, 0},
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_SCALE_FONT, TCL_INDEX_NONE, offsetof(TkScale, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_SCALE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, textColorPtr), 0,
	(ClientData) DEF_SCALE_FG_MONO, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From", DEF_SCALE_FROM, TCL_INDEX_NONE,
	offsetof(TkScale, fromValue), 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCALE_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkScale, highlightBorder),
	0, DEF_SCALE_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCALE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkScale, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(TkScale, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-label", "label", "Label",
	DEF_SCALE_LABEL, TCL_INDEX_NONE, offsetof(TkScale, label),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, length), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_SCALE_ORIENT, TCL_INDEX_NONE, offsetof(TkScale, orient),
	0, orientStrings, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_SCALE_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, relief), 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCALE_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkScale, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCALE_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, repeatInterval),







|



















|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_SCALE_FONT, TCL_INDEX_NONE, offsetof(TkScale, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_SCALE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, textColorPtr), 0,
	DEF_SCALE_FG_MONO, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From", DEF_SCALE_FROM, TCL_INDEX_NONE,
	offsetof(TkScale, fromValue), 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCALE_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkScale, highlightBorder),
	0, DEF_SCALE_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCALE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkScale, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(TkScale, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-label", "label", "Label",
	DEF_SCALE_LABEL, TCL_INDEX_NONE, offsetof(TkScale, label),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, length), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_SCALE_ORIENT, TCL_INDEX_NONE, offsetof(TkScale, orient),
	TK_OPTION_ENUM_VAR, orientStrings, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_SCALE_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, relief), 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCALE_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkScale, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCALE_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, repeatInterval),
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
	DEF_SCALE_SLIDER_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, sliderLength),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief",
	DEF_SCALE_SLIDER_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, sliderRelief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_SCALE_STATE, TCL_INDEX_NONE, offsetof(TkScale, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCALE_TAKE_FOCUS, offsetof(TkScale, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-tickinterval", "tickInterval", "TickInterval",
	DEF_SCALE_TICK_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, tickInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	DEF_SCALE_SLIDER_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, sliderLength),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief",
	DEF_SCALE_SLIDER_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, sliderRelief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_SCALE_STATE, TCL_INDEX_NONE, offsetof(TkScale, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCALE_TAKE_FOCUS, offsetof(TkScale, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-tickinterval", "tickInterval", "TickInterval",
	DEF_SCALE_TICK_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, tickInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
static void		ComputeFormat(TkScale *scalePtr, int forTicks);
static void		ComputeScaleGeometry(TkScale *scalePtr);
static int		ConfigureScale(Tcl_Interp *interp, TkScale *scalePtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyScale(void *memPtr);
static double		MaxTickRoundingError(TkScale *scalePtr,
			    double tickResolution);
static void		ScaleCmdDeletedProc(ClientData clientData);
static void		ScaleEventProc(ClientData clientData,
			    XEvent *eventPtr);
static char *		ScaleVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		ScaleWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		ScaleWorldChanged(ClientData instanceData);
static void		ScaleSetVariable(TkScale *scalePtr);

/*
 * The structure below defines scale class behavior by means of procedures
 * that can be invoked from generic window code.
 */








|
|

|


|
<
<
|







151
152
153
154
155
156
157
158
159
160
161
162
163
164


165
166
167
168
169
170
171
172
static void		ComputeFormat(TkScale *scalePtr, int forTicks);
static void		ComputeScaleGeometry(TkScale *scalePtr);
static int		ConfigureScale(Tcl_Interp *interp, TkScale *scalePtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DestroyScale(void *memPtr);
static double		MaxTickRoundingError(TkScale *scalePtr,
			    double tickResolution);
static void		ScaleCmdDeletedProc(void *clientData);
static void		ScaleEventProc(void *clientData,
			    XEvent *eventPtr);
static char *		ScaleVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static Tcl_ObjCmdProc ScaleWidgetObjCmd;


static void		ScaleWorldChanged(void *instanceData);
static void		ScaleSetVariable(TkScale *scalePtr);

/*
 * The structure below defines scale class behavior by means of procedures
 * that can be invoked from generic window code.
 */

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScaleObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    TkScale *scalePtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),







|







<







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScaleObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    TkScale *scalePtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ScaleWidgetObjCmd(
    ClientData clientData,	/* Information about scale widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tcl_Obj *objPtr;
    int index, result;







|







365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ScaleWidgetObjCmd(
    void *clientData,	/* Information about scale widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tcl_Obj *objPtr;
    int index, result;
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
	    goto error;
	}
	switch (TkpScaleElement(scalePtr, x, y)) {
	case TROUGH1:	zone = "trough1"; break;
	case SLIDER:	zone = "slider";  break;
	case TROUGH2:	zone = "trough2"; break;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	break;
    }
    case COMMAND_SET: {
	double value;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "set value");







|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
	    goto error;
	}
	switch (TkpScaleElement(scalePtr, x, y)) {
	case TROUGH1:	zone = "trough1"; break;
	case SLIDER:	zone = "slider";  break;
	case TROUGH2:	zone = "trough2"; break;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, TCL_INDEX_NONE));
	break;
    }
    case COMMAND_SET: {
	double value;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "set value");
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
    }
    if (scalePtr->copyGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->copyGC);
    }
    if (scalePtr->textGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->textGC);
    }
    Tk_FreeConfigOptions((char *) scalePtr, scalePtr->optionTable,
	    scalePtr->tkwin);
    scalePtr->tkwin = NULL;
    TkpDestroyScale(scalePtr);
}

/*
 *----------------------------------------------------------------------







|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
    }
    if (scalePtr->copyGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->copyGC);
    }
    if (scalePtr->textGC != NULL) {
	Tk_FreeGC(scalePtr->display, scalePtr->textGC);
    }
    Tk_FreeConfigOptions(scalePtr, scalePtr->optionTable,
	    scalePtr->tkwin);
    scalePtr->tkwin = NULL;
    TkpDestroyScale(scalePtr);
}

/*
 *----------------------------------------------------------------------
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
 *	Scale will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
ScaleWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    TkScale *scalePtr = (TkScale *)instanceData;

    gcValues.foreground = scalePtr->troughColorPtr->pixel;
    gc = Tk_GetGC(scalePtr->tkwin, GCForeground, &gcValues);







|







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
 *	Scale will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
ScaleWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    TkScale *scalePtr = (TkScale *)instanceData;

    gcValues.foreground = scalePtr->troughColorPtr->pixel;
    gc = Tk_GetGC(scalePtr->tkwin, GCForeground, &gcValues);
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
    }
    if (mostSigDigit < 0) {
	fDigits++;			/* Zero to left of decimal point. */
    }

    if (forTicks) {
	if (fDigits <= eDigits) {
	    sprintf(scalePtr->tickFormat, "%%.%df", afterDecimal);
	} else {
	    sprintf(scalePtr->tickFormat, "%%.%de", numDigits - 1);
	}
    } else {
	if (fDigits <= eDigits) {
	    sprintf(scalePtr->valueFormat, "%%.%df", afterDecimal);
	} else {
	    sprintf(scalePtr->valueFormat, "%%.%de", numDigits - 1);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *







|

|



|

|







968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
    }
    if (mostSigDigit < 0) {
	fDigits++;			/* Zero to left of decimal point. */
    }

    if (forTicks) {
	if (fDigits <= eDigits) {
	    snprintf(scalePtr->tickFormat, sizeof(scalePtr->tickFormat), "%%.%df", afterDecimal);
	} else {
	    snprintf(scalePtr->tickFormat, sizeof(scalePtr->tickFormat), "%%.%de", numDigits - 1);
	}
    } else {
	if (fDigits <= eDigits) {
	    snprintf(scalePtr->valueFormat, sizeof(scalePtr->valueFormat), "%%.%df", afterDecimal);
	} else {
	    snprintf(scalePtr->valueFormat, sizeof(scalePtr->valueFormat), "%%.%de", numDigits - 1);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScale *scalePtr = (TkScale *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
    } else if (eventPtr->type == DestroyNotify) {







|







1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ScaleEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScale *scalePtr = (TkScale *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawScale(scalePtr, REDRAW_ALL);
    } else if (eventPtr->type == DestroyNotify) {
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ScaleCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tk_Window tkwin = scalePtr->tkwin;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or







|







1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ScaleCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tk_Window tkwin = scalePtr->tkwin;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
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
 *	value of the scale.
 *
 *----------------------------------------------------------------------
 */

static char *
ScaleVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    const char *resultStr;
    double value;
    Tcl_Obj *valuePtr;
    int result;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && scalePtr->varNamePtr) {
            ClientData probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        Tcl_GetString(scalePtr->varNamePtr),
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        ScaleVarProc, probe);
                if (probe == (ClientData)scalePtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * varNamePtr, which means it is not unset and not







|

|
|







<
<








|






|







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
 *	value of the scale.
 *
 *----------------------------------------------------------------------
 */

static char *
ScaleVarProc(
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    TCL_UNUSED(const char *),	/* Name of variable. */
    TCL_UNUSED(const char *),	/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    const char *resultStr;
    double value;
    Tcl_Obj *valuePtr;
    int result;



    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
        if (!Tcl_InterpDeleted(interp) && scalePtr->varNamePtr) {
            void *probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        Tcl_GetString(scalePtr->varNamePtr),
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        ScaleVarProc, probe);
                if (probe == (void *)scalePtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * varNamePtr, which means it is not unset and not
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520

        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
                scalePtr->value) < 0) {
            string[TCL_DOUBLE_SPACE - 1] = '\0';
        }
	scalePtr->flags |= SETTING_VAR;
	Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
		Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY);
	scalePtr->flags &= ~SETTING_VAR;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506

        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
                scalePtr->value) < 0) {
            string[TCL_DOUBLE_SPACE - 1] = '\0';
        }
	scalePtr->flags |= SETTING_VAR;
	Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
		Tcl_NewStringObj(string, TCL_INDEX_NONE), TCL_GLOBAL_ONLY);
	scalePtr->flags &= ~SETTING_VAR;
    }
}

/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkScale.h.

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.
 *
 * 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






|
|







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 © 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
				 * display any tick marks. */
    double resolution;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    int digits;			/* Number of significant digits to print in
				 * values. 0 means we get to choose the number
				 * based on resolution and/or the range of the
				 * scale. */
    char valueFormat[16];	/* Sprintf conversion specifier computed from
				 * digits and other information. */
    char tickFormat[16];	/* Sprintf conversion specifier computed from
				 * tick interval. */
    double bigIncrement;	/* Amount to use for large increments to scale
				 * value. (0 means we pick a value). */
    char *command;		/* Command prefix to use when invoking Tcl
				 * commands because the scale value changed.
				 * NULL means don't invoke commands. */
    int repeatDelay;		/* How long to wait before auto-repeating on
				 * scrolling actions (in ms). */
    int repeatInterval;		/* Interval between autorepeats (in ms). */
    char *label;		/* Label to display above or to right of
				 * scale; NULL means don't display a label. */
    TkSizeT labelLength;	/* Number of non-NULL chars. in label. */
    enum state state;		/* Values are active, normal, or disabled.
				 * Value of scale cannot be changed when
				 * disabled. */

    /*
     * Information used when displaying widget:
     */







|

|











|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
				 * display any tick marks. */
    double resolution;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    int digits;			/* Number of significant digits to print in
				 * values. 0 means we get to choose the number
				 * based on resolution and/or the range of the
				 * scale. */
    char valueFormat[16];	/* Snprintf conversion specifier computed from
				 * digits and other information. */
    char tickFormat[16];	/* Snprintf conversion specifier computed from
				 * tick interval. */
    double bigIncrement;	/* Amount to use for large increments to scale
				 * value. (0 means we pick a value). */
    char *command;		/* Command prefix to use when invoking Tcl
				 * commands because the scale value changed.
				 * NULL means don't invoke commands. */
    int repeatDelay;		/* How long to wait before auto-repeating on
				 * scrolling actions (in ms). */
    int repeatInterval;		/* Interval between autorepeats (in ms). */
    char *label;		/* Label to display above or to right of
				 * scale; NULL means don't display a label. */
    Tcl_Size labelLength;	/* Number of non-NULL chars. in label. */
    enum state state;		/* Values are active, normal, or disabled.
				 * Value of scale cannot be changed when
				 * disabled. */

    /*
     * Information used when displaying widget:
     */
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
 */

MODULE_SCOPE void	TkEventuallyRedrawScale(TkScale *scalePtr, int what);
MODULE_SCOPE double	TkRoundValueToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE double	TkRoundIntervalToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE TkScale *	TkpCreateScale(Tk_Window tkwin);
MODULE_SCOPE void	TkpDestroyScale(TkScale *scalePtr);
MODULE_SCOPE void	TkpDisplayScale(ClientData clientData);
MODULE_SCOPE int	TkpScaleElement(TkScale *scalePtr, int x, int y);
MODULE_SCOPE void	TkScaleSetValue(TkScale *scalePtr, double value,
			    int setVar, int invokeCommand);
MODULE_SCOPE double	TkScalePixelToValue(TkScale *scalePtr, int x, int y);
MODULE_SCOPE int	TkScaleValueToPixel(TkScale *scalePtr, double value);

#endif /* _TKSCALE */







|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
 */

MODULE_SCOPE void	TkEventuallyRedrawScale(TkScale *scalePtr, int what);
MODULE_SCOPE double	TkRoundValueToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE double	TkRoundIntervalToResolution(TkScale *scalePtr, double value);
MODULE_SCOPE TkScale *	TkpCreateScale(Tk_Window tkwin);
MODULE_SCOPE void	TkpDestroyScale(TkScale *scalePtr);
MODULE_SCOPE void	TkpDisplayScale(void *clientData);
MODULE_SCOPE int	TkpScaleElement(TkScale *scalePtr, int x, int y);
MODULE_SCOPE void	TkScaleSetValue(TkScale *scalePtr, double value,
			    int setVar, int invokeCommand);
MODULE_SCOPE double	TkScalePixelToValue(TkScale *scalePtr, int x, int y);
MODULE_SCOPE int	TkScaleValueToPixel(TkScale *scalePtr, double value);

#endif /* _TKSCALE */

Changes to generic/tkScrollbar.c.

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.
 *
 * 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"







|
|







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 © 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"
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureScrollbar(Tcl_Interp *interp,
			    TkScrollbar *scrollPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static void		ScrollbarCmdDeletedProc(ClientData clientData);
static int		ScrollbarWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *, int objc, Tcl_Obj *const objv[]);

/*
 *--------------------------------------------------------------
 *
 * Tk_ScrollbarObjCmd --
 *
 *	This function is invoked to process the "scrollbar" Tcl command. See
 *	the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScrollbarObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkScrollbar *scrollPtr;
    Tk_Window newWin;







|

|
|
<




















|







93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
};

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureScrollbar(Tcl_Interp *interp,
			    TkScrollbar *scrollPtr, Tcl_Size objc,
			    Tcl_Obj *const objv[], int flags);
static void		ScrollbarCmdDeletedProc(void *clientData);
static Tcl_ObjCmdProc ScrollbarWidgetObjCmd;


/*
 *--------------------------------------------------------------
 *
 * Tk_ScrollbarObjCmd --
 *
 *	This function is invoked to process the "scrollbar" Tcl command. See
 *	the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScrollbarObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    TkScrollbar *scrollPtr;
    Tk_Window newWin;
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    scrollPtr->inset = 0;
    scrollPtr->elementBorderWidth = -1;
    scrollPtr->arrowLength = 0;
    scrollPtr->sliderFirst = 0;
    scrollPtr->sliderLast = 0;
    scrollPtr->activeField = 0;
    scrollPtr->activeRelief = TK_RELIEF_RAISED;
#ifndef TK_NO_DEPRECATED
    scrollPtr->totalUnits = 0;
    scrollPtr->windowUnits = 0;
    scrollPtr->firstUnit = 0;
    scrollPtr->lastUnit = 0;
#endif /* TK_NO_DEPRECATED */
    scrollPtr->firstFraction = 0.0;
    scrollPtr->lastFraction = 0.0;
    scrollPtr->cursor = NULL;
    scrollPtr->takeFocus = NULL;
    scrollPtr->flags = 0;

    if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) {







<
<
<
<
<
<







174
175
176
177
178
179
180






181
182
183
184
185
186
187
    scrollPtr->inset = 0;
    scrollPtr->elementBorderWidth = -1;
    scrollPtr->arrowLength = 0;
    scrollPtr->sliderFirst = 0;
    scrollPtr->sliderLast = 0;
    scrollPtr->activeField = 0;
    scrollPtr->activeRelief = TK_RELIEF_RAISED;






    scrollPtr->firstFraction = 0.0;
    scrollPtr->lastFraction = 0.0;
    scrollPtr->cursor = NULL;
    scrollPtr->takeFocus = NULL;
    scrollPtr->flags = 0;

    if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) {
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarWidgetObjCmd(
    ClientData clientData,	/* Information about scrollbar widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    int result = TCL_OK, cmdIndex, length;
    TkSizeT len;
    static const char *const commandNames[] = {
        "activate", "cget", "configure", "delta", "fraction",
        "get", "identify", "set", NULL
    };
    enum command {
        COMMAND_ACTIVATE, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELTA,
        COMMAND_FRACTION, COMMAND_GET, COMMAND_IDENTIFY, COMMAND_SET







|






|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarWidgetObjCmd(
    void *clientData,	/* Information about scrollbar widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    int result = TCL_OK, cmdIndex, length;
    Tcl_Size 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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	    const char *zone = "";

	    switch (scrollPtr->activeField) {
	    case TOP_ARROW:	zone = "arrow1"; break;
	    case SLIDER:	zone = "slider"; break;
	    case BOTTOM_ARROW:	zone = "arrow2"; break;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	    goto done;
	}
	if (objc != 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "activate element");
	    goto error;
	}
	c = TkGetStringFromObj(objv[2], &len)[0];
	oldActiveField = scrollPtr->activeField;
	if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) {
	    scrollPtr->activeField = TOP_ARROW;
	} else if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow2") == 0)) {
	    scrollPtr->activeField = BOTTOM_ARROW;
	} else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", len) == 0)) {
	    scrollPtr->activeField = SLIDER;







|






|







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
	    const char *zone = "";

	    switch (scrollPtr->activeField) {
	    case TOP_ARROW:	zone = "arrow1"; break;
	    case SLIDER:	zone = "slider"; break;
	    case BOTTOM_ARROW:	zone = "arrow2"; break;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, TCL_INDEX_NONE));
	    goto done;
	}
	if (objc != 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "activate element");
	    goto error;
	}
	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", len) == 0)) {
	    scrollPtr->activeField = SLIDER;
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    }
    case COMMAND_CGET: {
	if (objc != 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}
	result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
		configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0);
	break;
    }
    case COMMAND_CONFIGURE: {
	if (objc == 2) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, (char *) scrollPtr, NULL, 0);
	} else if (objc == 3) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0);
	} else {
	    result = ConfigureScrollbar(interp, scrollPtr, objc-2,
		    objv+2, TK_CONFIG_ARGV_ONLY);
	}
	break;
    }
    case COMMAND_DELTA: {







|





|


|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
    }
    case COMMAND_CGET: {
	if (objc != 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}
	result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
		configSpecs, scrollPtr, Tcl_GetString(objv[2]), 0);
	break;
    }
    case COMMAND_CONFIGURE: {
	if (objc == 2) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, scrollPtr, NULL, 0);
	} else if (objc == 3) {
	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
		    configSpecs, scrollPtr, Tcl_GetString(objv[2]), 0);
	} else {
	    result = ConfigureScrollbar(interp, scrollPtr, objc-2,
		    objv+2, TK_CONFIG_ARGV_ONLY);
	}
	break;
    }
    case COMMAND_DELTA: {
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
    case COMMAND_GET: {
	Tcl_Obj *resObjs[4];

	if (objc != 2) {
		Tcl_WrongNumArgs(interp, 1, objv, "get");
	    goto error;
	}
#ifndef TK_NO_DEPRECATED
	if (scrollPtr->flags & OLD_STYLE_COMMANDS) {
	    resObjs[0] = Tcl_NewWideIntObj(scrollPtr->totalUnits);
	    resObjs[1] = Tcl_NewWideIntObj(scrollPtr->windowUnits);
	    resObjs[2] = Tcl_NewWideIntObj(scrollPtr->firstUnit);
	    resObjs[3] = Tcl_NewWideIntObj(scrollPtr->lastUnit);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs));
	    break;
	}
#endif /* TK_NO_DEPRECATED */
	resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction);
	resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs));
	break;
    }
    case COMMAND_IDENTIFY: {
	int x, y;







<
<
<
<
<
<
<
<
<
<







368
369
370
371
372
373
374










375
376
377
378
379
380
381
    case COMMAND_GET: {
	Tcl_Obj *resObjs[4];

	if (objc != 2) {
		Tcl_WrongNumArgs(interp, 1, objv, "get");
	    goto error;
	}










	resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction);
	resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs));
	break;
    }
    case COMMAND_IDENTIFY: {
	int x, y;
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
	switch (TkpScrollbarPosition(scrollPtr, x, y)) {
	case TOP_ARROW:		zone = "arrow1";  break;
	case TOP_GAP:		zone = "trough1"; break;
	case SLIDER:		zone = "slider";  break;
	case BOTTOM_GAP:	zone = "trough2"; break;
	case BOTTOM_ARROW:	zone = "arrow2";  break;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	break;
    }
    case COMMAND_SET: {
	if (objc == 4) {
	    double first, last;

	    if (Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) {







|







392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
	switch (TkpScrollbarPosition(scrollPtr, x, y)) {
	case TOP_ARROW:		zone = "arrow1";  break;
	case TOP_GAP:		zone = "trough1"; break;
	case SLIDER:		zone = "slider";  break;
	case BOTTOM_GAP:	zone = "trough2"; break;
	case BOTTOM_ARROW:	zone = "arrow2";  break;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, TCL_INDEX_NONE));
	break;
    }
    case COMMAND_SET: {
	if (objc == 4) {
	    double first, last;

	    if (Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) {
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
	    if (last < scrollPtr->firstFraction) {
		scrollPtr->lastFraction = scrollPtr->firstFraction;
	    } else if (last > 1.0) {
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->lastFraction = last;
	    }
#ifndef TK_NO_DEPRECATED
	    scrollPtr->flags &= ~OLD_STYLE_COMMANDS;
	} else if (objc == 6) {
	    int totalUnits, windowUnits, firstUnit, lastUnit;
	    if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) {
		goto error;
	    }
	    if (totalUnits < 0) {
		totalUnits = 0;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[3], &windowUnits) != TCL_OK) {
		goto error;
	    }
	    if (windowUnits < 0) {
		windowUnits = 0;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[4], &firstUnit) != TCL_OK) {
		goto error;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[5], &lastUnit) != TCL_OK) {
		goto error;
	    }
	    if (totalUnits > 0) {
		if (lastUnit < firstUnit) {
		    lastUnit = firstUnit;
		}
	    } else {
		firstUnit = lastUnit = 0;
	    }
	    scrollPtr->totalUnits = totalUnits;
	    scrollPtr->windowUnits = windowUnits;
	    scrollPtr->firstUnit = firstUnit;
	    scrollPtr->lastUnit = lastUnit;
	    if (scrollPtr->totalUnits == 0) {
		scrollPtr->firstFraction = 0.0;
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->firstFraction = ((double) firstUnit)/totalUnits;
		scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits;
	    }
	    scrollPtr->flags |= OLD_STYLE_COMMANDS;
#endif /* !TK_NO_DEPRECATED */
	} else {
		Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction");
	    goto error;
	}
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







419
420
421
422
423
424
425










































426
427
428
429
430
431
432
	    if (last < scrollPtr->firstFraction) {
		scrollPtr->lastFraction = scrollPtr->firstFraction;
	    } else if (last > 1.0) {
		scrollPtr->lastFraction = 1.0;
	    } else {
		scrollPtr->lastFraction = last;
	    }










































	} else {
		Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction");
	    goto error;
	}
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

static int
ConfigureScrollbar(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkScrollbar *scrollPtr,
				/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],		/* Arguments. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, objc,
	    (const char **)objv, (char *) scrollPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * A few options need special processing, such as setting the background
     * from a 3-D border.
     */







|




|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

static int
ConfigureScrollbar(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkScrollbar *scrollPtr,
				/* Information about widget; may or may not
				 * already have values for some fields. */
    Tcl_Size objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],		/* Arguments. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, objc,
	    objv, scrollPtr, flags) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * A few options need special processing, such as setting the background
     * from a 3-D border.
     */
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

void
TkScrollbarEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == DestroyNotify) {







|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

void
TkScrollbarEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == DestroyNotify) {
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
	    Tcl_CancelIdleCall(TkpDisplayScrollbar, scrollPtr);
	}
	/*
	 * Free up all the stuff that requires special handling, then let
	 * Tk_FreeOptions handle all the standard option-related stuff.
	 */

	Tk_FreeOptions(configSpecs, (char*) scrollPtr, scrollPtr->display, 0);
	Tcl_EventuallyFree(scrollPtr, TCL_DYNAMIC);
    } else if (eventPtr->type == ConfigureNotify) {
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    scrollPtr->flags |= GOT_FOCUS;







|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
	    Tcl_CancelIdleCall(TkpDisplayScrollbar, scrollPtr);
	}
	/*
	 * Free up all the stuff that requires special handling, then let
	 * Tk_FreeOptions handle all the standard option-related stuff.
	 */

	Tk_FreeOptions(configSpecs, scrollPtr, scrollPtr->display, 0);
	Tcl_EventuallyFree(scrollPtr, TCL_DYNAMIC);
    } else if (eventPtr->type == ConfigureNotify) {
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    scrollPtr->flags |= GOT_FOCUS;
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ScrollbarCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or







|







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
ScrollbarCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or

Changes to generic/tkScrollbar.h.

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.
 *
 * 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






|







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 © 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
     * command. This information can now be provided in two ways: the "old"
     * form (totalUnits, windowUnits, firstUnit, and lastUnit), or the "new"
     * form (firstFraction and lastFraction). FirstFraction and lastFraction
     * will always be valid, but the old-style information is only valid if
     * the OLD_STYLE_COMMANDS flag is 1.
     */

#ifndef TK_NO_DEPRECATED
    int totalUnits;		/* Total dimension of application, in units.
				 * Valid only if the OLD_STYLE_COMMANDS flag
				 * is set. */
    int windowUnits;		/* Maximum number of units that can be
				 * displayed in the window at once. Valid only
				 * if the OLD_STYLE_COMMANDS flag is set. */
    int firstUnit;		/* Number of last unit visible in
				 * application's window. Valid only if the
				 * OLD_STYLE_COMMANDS flag is set. */
    int lastUnit;		/* Index of last unit visible in window.
				 * Valid only if the OLD_STYLE_COMMANDS flag
				 * isn't set. */
#else
    int dummy1,dummy2,dummy3,dummy4; /* sizeof(TkScrollbar) should not depend on TK_NO_DEPRECATED */
#endif /* TK_NO_DEPRECATED */
    double firstFraction;	/* Position of first visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */
    double lastFraction;	/* Position of last visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







92
93
94
95
96
97
98
















99
100
101
102
103
104
105
     * command. This information can now be provided in two ways: the "old"
     * form (totalUnits, windowUnits, firstUnit, and lastUnit), or the "new"
     * form (firstFraction and lastFraction). FirstFraction and lastFraction
     * will always be valid, but the old-style information is only valid if
     * the OLD_STYLE_COMMANDS flag is 1.
     */

















    double firstFraction;	/* Position of first visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */
    double lastFraction;	/* Position of last visible thing in window,
				 * specified as a fraction between 0 and
				 * 1.0. */

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
 *				".t yview 40", instead of
 *				".t yview scroll 2 lines", for example.
 * GOT_FOCUS:			Non-zero means this window has the input
 *				focus.
 */

#define REDRAW_PENDING		1
#ifndef TK_NO_DEPRECATED
#   define OLD_STYLE_COMMANDS	2
#endif /* TK_NO_DEPRECATED */
#define GOT_FOCUS		4

/*
 * Declaration of scrollbar class functions structure
 * and default scrollbar width, for use in configSpec.
 */

MODULE_SCOPE const Tk_ClassProcs tkpScrollbarProcs;
MODULE_SCOPE char tkDefScrollbarWidth[TCL_INTEGER_SPACE];

/*
 * Declaration of functions used in the implementation of the scrollbar
 * widget.
 */

MODULE_SCOPE void	TkScrollbarEventProc(ClientData clientData,
			    XEvent *eventPtr);
MODULE_SCOPE void	TkScrollbarEventuallyRedraw(TkScrollbar *scrollPtr);
MODULE_SCOPE void	TkpComputeScrollbarGeometry(TkScrollbar *scrollPtr);
MODULE_SCOPE TkScrollbar *TkpCreateScrollbar(Tk_Window tkwin);
MODULE_SCOPE void 	TkpDestroyScrollbar(TkScrollbar *scrollPtr);
MODULE_SCOPE void	TkpDisplayScrollbar(ClientData clientData);
MODULE_SCOPE void	TkpConfigureScrollbar(TkScrollbar *scrollPtr);
MODULE_SCOPE int	TkpScrollbarPosition(TkScrollbar *scrollPtr,
			    int x, int y);

#endif /* _TKSCROLLBAR */







<
<
<















|





|





137
138
139
140
141
142
143



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
 *				".t yview 40", instead of
 *				".t yview scroll 2 lines", for example.
 * GOT_FOCUS:			Non-zero means this window has the input
 *				focus.
 */

#define REDRAW_PENDING		1



#define GOT_FOCUS		4

/*
 * Declaration of scrollbar class functions structure
 * and default scrollbar width, for use in configSpec.
 */

MODULE_SCOPE const Tk_ClassProcs tkpScrollbarProcs;
MODULE_SCOPE char tkDefScrollbarWidth[TCL_INTEGER_SPACE];

/*
 * Declaration of functions used in the implementation of the scrollbar
 * widget.
 */

MODULE_SCOPE void	TkScrollbarEventProc(void *clientData,
			    XEvent *eventPtr);
MODULE_SCOPE void	TkScrollbarEventuallyRedraw(TkScrollbar *scrollPtr);
MODULE_SCOPE void	TkpComputeScrollbarGeometry(TkScrollbar *scrollPtr);
MODULE_SCOPE TkScrollbar *TkpCreateScrollbar(Tk_Window tkwin);
MODULE_SCOPE void 	TkpDestroyScrollbar(TkScrollbar *scrollPtr);
MODULE_SCOPE void	TkpDisplayScrollbar(void *clientData);
MODULE_SCOPE void	TkpConfigureScrollbar(TkScrollbar *scrollPtr);
MODULE_SCOPE int	TkpScrollbarPosition(TkScrollbar *scrollPtr,
			    int x, int y);

#endif /* _TKSCROLLBAR */

Changes to generic/tkSelect.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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkSelect.h"





/*
 * When a selection handler is set up by invoking "selection handle", one of
 * the following data structures is set up to hold information about the
 * command to invoke and its interpreter.
 */

typedef struct {
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    int cmdLength;		/* # of non-NULL bytes in command. */
    int charOffset;		/* The offset of the next char to retrieve. */
    int byteOffset;		/* The expected byte offset of the next
				 * chunk. */
    char buffer[4];		/* A buffer to hold part of a UTF character
				 * that is split across chunks. */
    char command[TKFLEXARRAY];		/* Command to invoke. Actual space is
				 * allocated as large as necessary. This must
				 * be the last entry in the structure. */
} CommandInfo;






|
|







>
>
>
>









|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
 * tkSelect.c --
 *
 *	This file manages the selection for the Tk toolkit, translating
 *	between the standard X ICCCM conventions and Tcl commands.
 *
 * 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * When a selection handler is set up by invoking "selection handle", one of
 * the following data structures is set up to hold information about the
 * command to invoke and its interpreter.
 */

typedef struct {
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    Tcl_Size cmdLength;		/* # of non-NULL bytes in command. */
    Tcl_Size charOffset;		/* The offset of the next char to retrieve. */
    Tcl_Size byteOffset;	/* The expected byte offset of the next
				 * chunk. */
    char buffer[4];		/* A buffer to hold part of a UTF character
				 * that is split across chunks. */
    char command[TKFLEXARRAY];		/* Command to invoke. Actual space is
				 * allocated as large as necessary. This must
				 * be the last entry in the structure. */
} CommandInfo;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

static TkSizeT	HandleTclCommand(ClientData clientData,
			    TkSizeT offset, char *buffer, TkSizeT maxBytes);
static void		LostSelection(ClientData clientData);
static int		SelGetProc(ClientData clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateSelHandler --
 *







|
|
|
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

static Tcl_Size	HandleTclCommand(void *clientData,
			    Tcl_Size offset, char *buffer, Tcl_Size maxBytes);
static void		LostSelection(void *clientData);
static int		SelGetProc(void *clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *--------------------------------------------------------------
 *
 * Tk_CreateSelHandler --
 *
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 *	invoked to provide part or all of the selection in the given form. If
 *	there was already a handler declared for the given window, target and
 *	selection type, then it is replaced. Proc should have the following
 *	form:
 *
 *	int
 *	proc(
 *	    ClientData clientData,
 *	    int offset,
 *	    char *buffer,
 *	    int maxBytes)
 *	{
 *	}
 *
 *	The clientData argument to proc will be the same as the clientData







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
 *	invoked to provide part or all of the selection in the given form. If
 *	there was already a handler declared for the given window, target and
 *	selection type, then it is replaced. Proc should have the following
 *	form:
 *
 *	int
 *	proc(
 *	    void *clientData,
 *	    int offset,
 *	    char *buffer,
 *	    int maxBytes)
 *	{
 *	}
 *
 *	The clientData argument to proc will be the same as the clientData
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    Tk_Window tkwin,		/* Token for window. */
    Atom selection,		/* Selection to be handled. */
    Atom target,		/* The kind of selection conversions that can
				 * be handled by proc, e.g. TARGETS or
				 * STRING. */
    Tk_SelectionProc *proc,	/* Function to invoke to convert selection to
				 * type "target". */
    ClientData clientData,	/* Value to pass to proc. */
    Atom format)		/* Format in which the selection information
				 * should be returned to the requestor.
				 * XA_STRING is best by far, but anything
				 * listed in the ICCCM will be tolerated
				 * (blech). */
{
    TkSelHandler *selPtr;







|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    Tk_Window tkwin,		/* Token for window. */
    Atom selection,		/* Selection to be handled. */
    Atom target,		/* The kind of selection conversions that can
				 * be handled by proc, e.g. TARGETS or
				 * STRING. */
    Tk_SelectionProc *proc,	/* Function to invoke to convert selection to
				 * type "target". */
    void *clientData,	/* Value to pass to proc. */
    Atom format)		/* Format in which the selection information
				 * should be returned to the requestor.
				 * XA_STRING is best by far, but anything
				 * listed in the ICCCM will be tolerated
				 * (blech). */
{
    TkSelHandler *selPtr;
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

void
Tk_OwnSelection(
    Tk_Window tkwin,		/* Window to become new selection owner. */
    Atom selection,		/* Selection that window should own. */
    Tk_LostSelProc *proc,	/* Function to call when selection is taken
				 * away from tkwin. */
    ClientData clientData)	/* Arbitrary one-word argument to pass to
				 * proc. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    Tk_LostSelProc *clearProc = NULL;
    void *clearData = NULL;/* Initialization needed only to prevent







|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

void
Tk_OwnSelection(
    Tk_Window tkwin,		/* Window to become new selection owner. */
    Atom selection,		/* Selection that window should own. */
    Tk_LostSelProc *proc,	/* Function to call when selection is taken
				 * away from tkwin. */
    void *clientData)	/* Arbitrary one-word argument to pass to
				 * proc. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    Tk_LostSelProc *clearProc = NULL;
    void *clearData = NULL;/* Initialization needed only to prevent
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
 *	The standard X11 protocols are used to retrieve the selection. When it
 *	arrives, it is passed to proc. If the selection is very large, it will
 *	be passed to proc in several pieces. Proc should have the following
 *	structure:
 *
 *	int
 *	proc(
 *	    ClientData clientData,
 *	    Tcl_Interp *interp,
 *	    char *portion)
 *	{
 *	}
 *
 *	The interp and clientData arguments to proc will be the same as the
 *	corresponding arguments to Tk_GetSelection. The portion argument







|







520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
 *	The standard X11 protocols are used to retrieve the selection. When it
 *	arrives, it is passed to proc. If the selection is very large, it will
 *	be passed to proc in several pieces. Proc should have the following
 *	structure:
 *
 *	int
 *	proc(
 *	    void *clientData,
 *	    Tcl_Interp *interp,
 *	    char *portion)
 *	{
 *	}
 *
 *	The interp and clientData arguments to proc will be the same as the
 *	corresponding arguments to Tk_GetSelection. The portion argument
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Function to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));








|







551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Function to call to process the selection,
				 * once it has been retrieved. */
    void *clientData)	/* Arbitrary value to pass to proc. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    TkSelectionInfo *infoPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600


601
602
603
604
605
606
607
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == selection) {
	    break;
	}
    }
    if (infoPtr != NULL) {
	TkSelHandler *selPtr;

	int offset, result, count;
	char buffer[TK_SEL_BYTES_AT_ONCE+1];
	TkSelInProgress ip;

	for (selPtr = ((TkWindow *) infoPtr->owner)->selHandlerList;
		selPtr != NULL; selPtr = selPtr->nextPtr) {
	    if (selPtr->target==target && selPtr->selection==selection) {
		break;
	    }
	}
	if (selPtr == NULL) {
	    Atom type;

	    count = TkSelDefaultSelection(infoPtr, target, buffer,
		    TK_SEL_BYTES_AT_ONCE, &type);
	    if (count > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
	    }
	    if (count < 0) {
		goto cantget;


	    }
	    buffer[count] = 0;
	    result = proc(clientData, interp, buffer);
	} else {
	    offset = 0;
	    result = TCL_OK;
	    ip.selPtr = selPtr;







>
|














<
<
<


>
>







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600



601
602
603
604
605
606
607
608
609
610
611
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->selection == selection) {
	    break;
	}
    }
    if (infoPtr != NULL) {
	TkSelHandler *selPtr;
	Tcl_Size offset, count;
	int result;
	char buffer[TK_SEL_BYTES_AT_ONCE+1];
	TkSelInProgress ip;

	for (selPtr = ((TkWindow *) infoPtr->owner)->selHandlerList;
		selPtr != NULL; selPtr = selPtr->nextPtr) {
	    if (selPtr->target==target && selPtr->selection==selection) {
		break;
	    }
	}
	if (selPtr == NULL) {
	    Atom type;

	    count = TkSelDefaultSelection(infoPtr, target, buffer,
		    TK_SEL_BYTES_AT_ONCE, &type);



	    if (count < 0) {
		goto cantget;
	    } else if (count > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
	    }
	    buffer[count] = 0;
	    result = proc(clientData, interp, buffer);
	} else {
	    offset = 0;
	    result = TCL_OK;
	    ip.selPtr = selPtr;
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SelectionObjCmd(
    ClientData clientData,	/* Main window associated with
				 * interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *path = NULL;
    Atom selection;
    const char *selName = NULL;
    const char *string;
    int count, index;
    Tcl_Obj **objs;
    static const char *const optionStrings[] = {
	"clear", "get", "handle", "own", NULL
    };
    enum options {
	SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE, SELECTION_OWN
    };








|











|







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SelectionObjCmd(
    void *clientData,	/* Main window associated with
				 * interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *path = NULL;
    Atom selection;
    const char *selName = NULL;
    const char *string;
    int count, index;
    Tcl_Obj *const *objs;
    static const char *const optionStrings[] = {
	"clear", "get", "handle", "own", NULL
    };
    enum options {
	SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE, SELECTION_OWN
    };

698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    case SELECTION_CLEAR: {
	static const char *const clearOptionStrings[] = {
	    "-displayof", "-selection", NULL
	};
	enum clearOptions { CLEAR_DISPLAYOF, CLEAR_SELECTION };
	int clearIndex;

	for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
		count-=2, objs+=2) {
	    string = Tcl_GetString(objs[0]);
	    if (string[0] != '-') {
		break;
	    }
	    if (count < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
    case SELECTION_CLEAR: {
	static const char *const clearOptionStrings[] = {
	    "-displayof", "-selection", NULL
	};
	enum clearOptions { CLEAR_DISPLAYOF, CLEAR_SELECTION };
	int clearIndex;

	for (count = objc-2, objs = objv+2; count > 0;
		count-=2, objs+=2) {
	    string = Tcl_GetString(objs[0]);
	    if (string[0] != '-') {
		break;
	    }
	    if (count < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
    }

    case SELECTION_HANDLE: {
	Atom target, format;
	const char *targetName = NULL;
	const char *formatName = NULL;
	CommandInfo *cmdInfoPtr;
	TkSizeT cmdLength;
	static const char *const handleOptionStrings[] = {
	    "-format", "-selection", "-type", NULL
	};
	enum handleOptions {
	    HANDLE_FORMAT, HANDLE_SELECTION, HANDLE_TYPE
	};
	int handleIndex;







|







831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
    }

    case SELECTION_HANDLE: {
	Atom target, format;
	const char *targetName = NULL;
	const char *formatName = NULL;
	CommandInfo *cmdInfoPtr;
	Tcl_Size cmdLength;
	static const char *const handleOptionStrings[] = {
	    "-format", "-selection", "-type", NULL
	};
	enum handleOptions {
	    HANDLE_FORMAT, HANDLE_SELECTION, HANDLE_TYPE
	};
	int handleIndex;
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
	if (count > 3) {
	    format = Tk_InternAtom(tkwin, Tcl_GetString(objs[3]));
	} else if (formatName != NULL) {
	    format = Tk_InternAtom(tkwin, formatName);
	} else {
	    format = XA_STRING;
	}
	string = TkGetStringFromObj(objs[1], &cmdLength);
	if (cmdLength == 0) {
	    Tk_DeleteSelHandler(tkwin, selection, target);
	} else {
	    cmdInfoPtr = (CommandInfo *)ckalloc(offsetof(CommandInfo, command)
		    + 1 + cmdLength);
	    cmdInfoPtr->interp = interp;
	    cmdInfoPtr->charOffset = 0;







|







900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
	if (count > 3) {
	    format = Tk_InternAtom(tkwin, Tcl_GetString(objs[3]));
	} else if (formatName != NULL) {
	    format = Tk_InternAtom(tkwin, formatName);
	} else {
	    format = XA_STRING;
	}
	string = Tcl_GetStringFromObj(objs[1], &cmdLength);
	if (cmdLength == 0) {
	    Tk_DeleteSelHandler(tkwin, selection, target);
	} else {
	    cmdInfoPtr = (CommandInfo *)ckalloc(offsetof(CommandInfo, command)
		    + 1 + cmdLength);
	    cmdInfoPtr->interp = interp;
	    cmdInfoPtr->charOffset = 0;
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
    dispPtr->clipboardAtom	= Tk_InternAtom(tkwin, "CLIPBOARD");
    dispPtr->atomPairAtom	= Tk_InternAtom(tkwin, "ATOM_PAIR");

    /*
     * Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us to
     * support older X servers that didn't have UTF8_STRING yet. This is
     * necessary on Unix systems. For more information, see:
     *	  http://www.cl.cam.ac.uk/~mgk25/unicode.html#x11
     */

#if !defined(_WIN32)
    dispPtr->utf8Atom		= Tk_InternAtom(tkwin, "UTF8_STRING");
#else
    dispPtr->utf8Atom		= (Atom) 0;
#endif







|







1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
    dispPtr->clipboardAtom	= Tk_InternAtom(tkwin, "CLIPBOARD");
    dispPtr->atomPairAtom	= Tk_InternAtom(tkwin, "ATOM_PAIR");

    /*
     * Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us to
     * support older X servers that didn't have UTF8_STRING yet. This is
     * necessary on Unix systems. For more information, see:
     *	  https://www.cl.cam.ac.uk/~mgk25/unicode.html#x11
     */

#if !defined(_WIN32)
    dispPtr->utf8Atom		= Tk_InternAtom(tkwin, "UTF8_STRING");
#else
    dispPtr->utf8Atom		= (Atom) 0;
#endif
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
 *	argument.
 *
 *--------------------------------------------------------------
 */

static int
SelGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),	/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    Tcl_DStringAppend((Tcl_DString *)clientData, portion, -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * HandleTclCommand --







|





|







1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
 *	argument.
 *
 *--------------------------------------------------------------
 */

static int
SelGetProc(
    void *clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),	/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    Tcl_DStringAppend((Tcl_DString *)clientData, portion, TCL_INDEX_NONE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * HandleTclCommand --
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333

1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
 *
 * Side effects:
 *	None except for things done by the Tcl command.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
HandleTclCommand(
    ClientData clientData,	/* Information about command to execute. */
    TkSizeT offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    CommandInfo *cmdInfoPtr = (CommandInfo *)clientData;
    int length;
    Tcl_Obj *command;
    const char *string;
    Tcl_Interp *interp = cmdInfoPtr->interp;
    Tcl_InterpState savedState;

    int extraBytes, charOffset, count, numChars, code;
    const char *p;

    /*
     * We must also protect the interpreter and the command from being deleted
     * too soon.
     */

    Tcl_Preserve(clientData);
    Tcl_Preserve(interp);

    /*
     * Compute the proper byte offset in the case where the last chunk split a
     * character.
     */

    if ((int)offset == cmdInfoPtr->byteOffset) {
	charOffset = cmdInfoPtr->charOffset;
	extraBytes = strlen(cmdInfoPtr->buffer);
	if (extraBytes > 0) {
	    strcpy(buffer, cmdInfoPtr->buffer);
	    maxBytes -= extraBytes;
	    buffer += extraBytes;
	}
    } else {
	cmdInfoPtr->byteOffset = 0;
	cmdInfoPtr->charOffset = 0;
	extraBytes = 0;
	charOffset = 0;
    }

    /*
     * First, generate a command by taking the command string and appending
     * the offset and maximum # of bytes.
     */

    command = Tcl_ObjPrintf("%s %d %d",
	    cmdInfoPtr->command, charOffset, (int)maxBytes);
    Tcl_IncrRefCount(command);

    /*
     * Execute the command. Be sure to restore the state of the interpreter
     * after executing the command.
     */

    savedState = Tcl_SaveInterpState(interp, TCL_OK);
    code = Tcl_EvalObjEx(interp, command, TCL_EVAL_GLOBAL);
    Tcl_DecrRefCount(command);
    if (code == TCL_OK) {
	/*
	 * TODO: This assumes that bytes are characters; that's not true!
	 */

	string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
	count = (length > (int)maxBytes) ? (int)maxBytes : length;
	memcpy(buffer, string, count);
	buffer[count] = '\0';

	/*
	 * Update the partial character information for the next retrieval if
	 * the command has not been deleted.
	 */

	if (cmdInfoPtr->interp != NULL) {
	    if (length <= (int)maxBytes) {
		cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, -1);
		cmdInfoPtr->buffer[0] = '\0';
	    } else {
		int ch;
		p = string;
		string += count;
		numChars = 0;
		while (p < string) {
		    p += TkUtfToUniChar(p, &ch);
		    numChars++;
		}
		cmdInfoPtr->charOffset += numChars;
		length = p - string;
		if (length > 0) {
		    strncpy(cmdInfoPtr->buffer, string, length);
		}







|

|
|


|


|




>
|















|



















|
|
















|









|
|


|




|







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
 *
 * Side effects:
 *	None except for things done by the Tcl command.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Size
HandleTclCommand(
    void *clientData,	/* Information about command to execute. */
    Tcl_Size offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    Tcl_Size maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    CommandInfo *cmdInfoPtr = (CommandInfo *)clientData;
    Tcl_Size length;
    Tcl_Obj *command;
    const char *string;
    Tcl_Interp *interp = cmdInfoPtr->interp;
    Tcl_InterpState savedState;
    int code;
    Tcl_Size extraBytes, charOffset, numChars, count;
    const char *p;

    /*
     * We must also protect the interpreter and the command from being deleted
     * too soon.
     */

    Tcl_Preserve(clientData);
    Tcl_Preserve(interp);

    /*
     * Compute the proper byte offset in the case where the last chunk split a
     * character.
     */

    if (offset == cmdInfoPtr->byteOffset) {
	charOffset = cmdInfoPtr->charOffset;
	extraBytes = strlen(cmdInfoPtr->buffer);
	if (extraBytes > 0) {
	    strcpy(buffer, cmdInfoPtr->buffer);
	    maxBytes -= extraBytes;
	    buffer += extraBytes;
	}
    } else {
	cmdInfoPtr->byteOffset = 0;
	cmdInfoPtr->charOffset = 0;
	extraBytes = 0;
	charOffset = 0;
    }

    /*
     * First, generate a command by taking the command string and appending
     * the offset and maximum # of bytes.
     */

    command = Tcl_ObjPrintf("%s %" TCL_SIZE_MODIFIER "d %" TCL_SIZE_MODIFIER "d",
	    cmdInfoPtr->command, charOffset, maxBytes);
    Tcl_IncrRefCount(command);

    /*
     * Execute the command. Be sure to restore the state of the interpreter
     * after executing the command.
     */

    savedState = Tcl_SaveInterpState(interp, TCL_OK);
    code = Tcl_EvalObjEx(interp, command, TCL_EVAL_GLOBAL);
    Tcl_DecrRefCount(command);
    if (code == TCL_OK) {
	/*
	 * TODO: This assumes that bytes are characters; that's not true!
	 */

	string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
	count = (length > maxBytes) ? maxBytes : length;
	memcpy(buffer, string, count);
	buffer[count] = '\0';

	/*
	 * Update the partial character information for the next retrieval if
	 * the command has not been deleted.
	 */

	if (cmdInfoPtr->interp != NULL) {
	    if (length <= maxBytes) {
		cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, TCL_INDEX_NONE);
		cmdInfoPtr->buffer[0] = '\0';
	    } else {
		Tcl_UniChar ch = 0;
		p = string;
		string += count;
		numChars = 0;
		while (p < string) {
		    p += Tcl_UtfToUniChar(p, &ch);
		    numChars++;
		}
		cmdInfoPtr->charOffset += numChars;
		length = p - string;
		if (length > 0) {
		    strncpy(cmdInfoPtr->buffer, string, length);
		}
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
	 * drop everything else.
	 */

	if (code == TCL_ERROR) {
	    Tcl_AddErrorInfo(interp, "\n    (command handling selection)");
	    Tcl_BackgroundException(interp, code);
	}
	count = -1;
    }
    (void) Tcl_RestoreInterpState(interp, savedState);

    Tcl_Release(clientData);
    Tcl_Release(interp);
    return count;
}







|







1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
	 * drop everything else.
	 */

	if (code == TCL_ERROR) {
	    Tcl_AddErrorInfo(interp, "\n    (command handling selection)");
	    Tcl_BackgroundException(interp, code);
	}
	count = TCL_INDEX_NONE;
    }
    (void) Tcl_RestoreInterpState(interp, savedState);

    Tcl_Release(clientData);
    Tcl_Release(interp);
    return count;
}
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
 * Results:
 *	If "target" is a standard target understood by this function, the
 *	selection is converted to that form and stored as a character string
 *	in buffer. The type of the selection (e.g. STRING or ATOM) is stored
 *	in *typePtr, and the return value is a count of the # of non-NULL
 *	bytes at buffer. If the target wasn't understood, or if there isn't
 *	enough space at buffer to hold the entire selection (no INCR-mode
 *	transfers for this stuff!), then -1 is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkSelDefaultSelection(
    TkSelectionInfo *infoPtr,	/* Info about selection being retrieved. */
    Atom target,		/* Desired form of selection. */
    char *buffer,		/* Place to put selection characters. */
    int maxBytes,		/* Maximum # of bytes to store at buffer. */
    Atom *typePtr)		/* Store here the type of the selection, for
				 * use in converting to proper X format. */
{
    TkWindow *winPtr = (TkWindow *) infoPtr->owner;
    TkDisplay *dispPtr = winPtr->dispPtr;

    if (target == dispPtr->timestampAtom) {
	if (maxBytes < 20) {
	    return -1;
	}
	sprintf(buffer, "0x%x", (unsigned int) infoPtr->time);
	*typePtr = XA_INTEGER;
	return strlen(buffer);
    }

    if (target == dispPtr->targetsAtom) {
	TkSelHandler *selPtr;
	int length;
	Tcl_DString ds;

	if (maxBytes < 50) {
	    return -1;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds,
		"MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW", -1);
	for (selPtr = winPtr->selHandlerList; selPtr != NULL;
		selPtr = selPtr->nextPtr) {
	    if ((selPtr->selection == infoPtr->selection)
		    && (selPtr->target != dispPtr->applicationAtom)
		    && (selPtr->target != dispPtr->windowAtom)) {
		const char *atomString = Tk_GetAtomName((Tk_Window) winPtr,
			selPtr->target);

		Tcl_DStringAppendElement(&ds, atomString);
	    }
	}
	length = Tcl_DStringLength(&ds);
	if (length >= maxBytes) {
	    Tcl_DStringFree(&ds);
	    return -1;
	}
	memcpy(buffer, Tcl_DStringValue(&ds), length + 1);
	Tcl_DStringFree(&ds);
	*typePtr = XA_ATOM;
	return length;
    }

    if (target == dispPtr->applicationAtom) {
	int length;
	Tk_Uid name = winPtr->mainPtr->winPtr->nameUid;

	length = strlen(name);
	if (maxBytes <= length) {
	    return -1;
	}
	strcpy(buffer, name);
	*typePtr = XA_STRING;
	return length;
    }

    if (target == dispPtr->windowAtom) {
	int length;
	char *name = winPtr->pathName;

	length = strlen(name);
	if (maxBytes <= length) {
	    return -1;
	}
	strcpy(buffer, name);
	*typePtr = XA_STRING;
	return length;
    }

    return -1;
}

/*
 *----------------------------------------------------------------------
 *
 * LostSelection --
 *







|







|




|








|

|






|



|



|














|








|




|







|




|






|







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
 * Results:
 *	If "target" is a standard target understood by this function, the
 *	selection is converted to that form and stored as a character string
 *	in buffer. The type of the selection (e.g. STRING or ATOM) is stored
 *	in *typePtr, and the return value is a count of the # of non-NULL
 *	bytes at buffer. If the target wasn't understood, or if there isn't
 *	enough space at buffer to hold the entire selection (no INCR-mode
 *	transfers for this stuff!), then TCL_INDEX_NONE is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Size
TkSelDefaultSelection(
    TkSelectionInfo *infoPtr,	/* Info about selection being retrieved. */
    Atom target,		/* Desired form of selection. */
    char *buffer,		/* Place to put selection characters. */
    Tcl_Size maxBytes,		/* Maximum # of bytes to store at buffer. */
    Atom *typePtr)		/* Store here the type of the selection, for
				 * use in converting to proper X format. */
{
    TkWindow *winPtr = (TkWindow *) infoPtr->owner;
    TkDisplay *dispPtr = winPtr->dispPtr;

    if (target == dispPtr->timestampAtom) {
	if (maxBytes < 20) {
	    return TCL_INDEX_NONE;
	}
	snprintf(buffer, maxBytes, "0x%x", (unsigned int) infoPtr->time);
	*typePtr = XA_INTEGER;
	return strlen(buffer);
    }

    if (target == dispPtr->targetsAtom) {
	TkSelHandler *selPtr;
	Tcl_Size length;
	Tcl_DString ds;

	if (maxBytes < 50) {
	    return TCL_INDEX_NONE;
	}
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds,
		"MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW", TCL_INDEX_NONE);
	for (selPtr = winPtr->selHandlerList; selPtr != NULL;
		selPtr = selPtr->nextPtr) {
	    if ((selPtr->selection == infoPtr->selection)
		    && (selPtr->target != dispPtr->applicationAtom)
		    && (selPtr->target != dispPtr->windowAtom)) {
		const char *atomString = Tk_GetAtomName((Tk_Window) winPtr,
			selPtr->target);

		Tcl_DStringAppendElement(&ds, atomString);
	    }
	}
	length = Tcl_DStringLength(&ds);
	if (length >= maxBytes) {
	    Tcl_DStringFree(&ds);
	    return TCL_INDEX_NONE;
	}
	memcpy(buffer, Tcl_DStringValue(&ds), length + 1);
	Tcl_DStringFree(&ds);
	*typePtr = XA_ATOM;
	return length;
    }

    if (target == dispPtr->applicationAtom) {
	Tcl_Size length;
	Tk_Uid name = winPtr->mainPtr->winPtr->nameUid;

	length = strlen(name);
	if (maxBytes <= length) {
	    return TCL_INDEX_NONE;
	}
	strcpy(buffer, name);
	*typePtr = XA_STRING;
	return length;
    }

    if (target == dispPtr->windowAtom) {
	Tcl_Size length;
	char *name = winPtr->pathName;

	length = strlen(name);
	if (maxBytes <= length) {
	    return TCL_INDEX_NONE;
	}
	strcpy(buffer, name);
	*typePtr = XA_STRING;
	return length;
    }

    return TCL_INDEX_NONE;
}

/*
 *----------------------------------------------------------------------
 *
 * LostSelection --
 *
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
 *	A Tcl script is executed; it can do almost anything.
 *
 *----------------------------------------------------------------------
 */

static void
LostSelection(
    ClientData clientData)	/* Pointer to LostCommand structure. */
{
    LostCommand *lostPtr = (LostCommand *)clientData;
    Tcl_Interp *interp = lostPtr->interp;
    Tcl_InterpState savedState;
    int code;

    Tcl_Preserve(interp);







|







1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
 *	A Tcl script is executed; it can do almost anything.
 *
 *----------------------------------------------------------------------
 */

static void
LostSelection(
    void *clientData)	/* Pointer to LostCommand structure. */
{
    LostCommand *lostPtr = (LostCommand *)clientData;
    Tcl_Interp *interp = lostPtr->interp;
    Tcl_InterpState savedState;
    int code;

    Tcl_Preserve(interp);

Changes to generic/tkSelect.h.

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.
 *
 * 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






|







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 © 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    Atom target;		/* Target type for selection conversion, such
				 * as TARGETS or STRING. */
    Atom format;		/* Format in which selection info will be
				 * returned, such as STRING or ATOM. */
    Tk_SelectionProc *proc;	/* Procedure to generate selection in this
				 * format. */
    void *clientData;	/* Argument to pass to proc. */
    TkSizeT size;			/* Size of units returned by proc (8 for
				 * STRING, 32 for almost anything else). */
    struct TkSelHandler *nextPtr;
				/* Next selection handler associated with same
				 * window (NULL for end of list). */
} TkSelHandler;

/*







|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    Atom target;		/* Target type for selection conversion, such
				 * as TARGETS or STRING. */
    Atom format;		/* Format in which selection info will be
				 * returned, such as STRING or ATOM. */
    Tk_SelectionProc *proc;	/* Procedure to generate selection in this
				 * format. */
    void *clientData;	/* Argument to pass to proc. */
    Tcl_Size size;			/* Size of units returned by proc (8 for
				 * STRING, 32 for almost anything else). */
    struct TkSelHandler *nextPtr;
				/* Next selection handler associated with same
				 * window (NULL for end of list). */
} TkSelHandler;

/*
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    TkWindow *winPtr;		/* Window used as requestor for selection. */
    Atom selection;		/* Selection being requested. */
    Atom property;		/* Property where selection will appear. */
    Atom target;		/* Desired form for selection. */
    Tk_GetSelProc *proc;	/* Procedure to call to handle pieces of
				 * selection. */
    ClientData clientData;	/* Argument for proc. */
    int result;			/* Initially -1. Set to a Tcl return value
				 * once the selection has been retrieved. */
    Tcl_TimerToken timeout;	/* Token for current timeout procedure. */
    int idleTime;		/* Number of seconds that have gone by without
				 * hearing anything from the selection
				 * owner. */
    Tcl_EncodingState encState;	/* Holds intermediate state during translations







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    TkWindow *winPtr;		/* Window used as requestor for selection. */
    Atom selection;		/* Selection being requested. */
    Atom property;		/* Property where selection will appear. */
    Atom target;		/* Desired form for selection. */
    Tk_GetSelProc *proc;	/* Procedure to call to handle pieces of
				 * selection. */
    void *clientData;	/* Argument for proc. */
    int result;			/* Initially -1. Set to a Tcl return value
				 * once the selection has been retrieved. */
    Tcl_TimerToken timeout;	/* Token for current timeout procedure. */
    int idleTime;		/* Number of seconds that have gone by without
				 * hearing anything from the selection
				 * owner. */
    Tcl_EncodingState encState;	/* Holds intermediate state during translations
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 * CLIPBOARD selection is retrieved. All buffers of a given type on the same
 * clipboard must have the same format. The TkClipboardTarget structure is
 * used to record the information about a chain of buffers of the same type.
 */

typedef struct TkClipboardBuffer {
    char *buffer;		/* Null terminated data buffer. */
    TkSizeT length;		/* Length of string in buffer. */
    struct TkClipboardBuffer *nextPtr;
				/* Next in list of buffers. NULL means end of
				 * list . */
} TkClipboardBuffer;

typedef struct TkClipboardTarget {
    Atom type;			/* Type conversion supported. */







|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 * CLIPBOARD selection is retrieved. All buffers of a given type on the same
 * clipboard must have the same format. The TkClipboardTarget structure is
 * used to record the information about a chain of buffers of the same type.
 */

typedef struct TkClipboardBuffer {
    char *buffer;		/* Null terminated data buffer. */
    Tcl_Size length;		/* Length of string in buffer. */
    struct TkClipboardBuffer *nextPtr;
				/* Next in list of buffers. NULL means end of
				 * list . */
} TkClipboardBuffer;

typedef struct TkClipboardTarget {
    Atom type;			/* Type conversion supported. */
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
 * Declarations for procedures that are used by the selection-related files
 * but shouldn't be used anywhere else in Tk (or by Tk clients):
 */

MODULE_SCOPE TkSelInProgress *TkSelGetInProgress(void);
MODULE_SCOPE void	TkSelSetInProgress(TkSelInProgress *pendingPtr);
MODULE_SCOPE void	TkSelClearSelection(Tk_Window tkwin, XEvent *eventPtr);
MODULE_SCOPE int	TkSelDefaultSelection(TkSelectionInfo *infoPtr,
			    Atom target, char *buffer, int maxBytes,
			    Atom *typePtr);
#ifndef TkSelUpdateClipboard
MODULE_SCOPE void	TkSelUpdateClipboard(TkWindow *winPtr,
			    TkClipboardTarget *targetPtr);
#endif

#endif /* _TKSELECT */







|
|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
 * Declarations for procedures that are used by the selection-related files
 * but shouldn't be used anywhere else in Tk (or by Tk clients):
 */

MODULE_SCOPE TkSelInProgress *TkSelGetInProgress(void);
MODULE_SCOPE void	TkSelSetInProgress(TkSelInProgress *pendingPtr);
MODULE_SCOPE void	TkSelClearSelection(Tk_Window tkwin, XEvent *eventPtr);
MODULE_SCOPE Tcl_Size TkSelDefaultSelection(TkSelectionInfo *infoPtr,
			    Atom target, char *buffer, Tcl_Size maxBytes,
			    Atom *typePtr);
#ifndef TkSelUpdateClipboard
MODULE_SCOPE void	TkSelUpdateClipboard(TkWindow *winPtr,
			    TkClipboardTarget *targetPtr);
#endif

#endif /* _TKSELECT */

Changes to generic/tkSquare.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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#if 0
#define __NO_OLD_CONFIG
#endif
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"


/*
 * A data structure of the following type is kept for each square widget
 * managed by this file:
 */

typedef struct {









|















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * 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 © 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
#endif
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"
#include <stdbool.h>

/*
 * A data structure of the following type is kept for each square widget
 * managed by this file:
 */

typedef struct {
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

    Tcl_Obj *borderWidthPtr;	/* Width of 3-D border around whole widget. */
    Tcl_Obj *bgBorderPtr;
    Tcl_Obj *fgBorderPtr;
    Tcl_Obj *reliefPtr;
    GC gc;			/* Graphics context for copying from
				 * off-screen pixmap onto screen. */
    Tcl_Obj *doubleBufferPtr;	/* Non-zero means double-buffer redisplay with
				 * pixmap; zero means draw straight onto the
				 * display. */
    int updatePending;		/* Non-zero means a call to SquareDisplay has
				 * already been scheduled. */
} Square;

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	    "#d9d9d9", offsetof(Square, bgBorderPtr), TCL_INDEX_NONE, 0,
	    "white", 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	    "2", offsetof(Square, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BOOLEAN, "-dbl", "doubleBuffer", "DoubleBuffer",
	    "1", offsetof(Square, doubleBufferPtr), TCL_INDEX_NONE, 0 , NULL, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-foreground", 0},
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
	    "#b03060", offsetof(Square, fgBorderPtr), TCL_INDEX_NONE, 0,
	    "black", 0},
    {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0",
	    offsetof(Square, xPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0",
	    offsetof(Square, yPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	    "raised", offsetof(Square, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-size", "size", "Size", "20",
	    offsetof(Square, sizeObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};

/*
 * Forward declarations for procedures defined later in this file:
 */

static void		SquareDeletedProc(ClientData clientData);
static int		SquareConfigure(Tcl_Interp *interp, Square *squarePtr);
static void		SquareDestroy(void *memPtr);
static void		SquareDisplay(ClientData clientData);
static void		KeepInWindow(Square *squarePtr);
static void		SquareObjEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		SquareWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *, int objc, Tcl_Obj * const objv[]);

/*
 *--------------------------------------------------------------
 *
 * SquareCmd --
 *
 *	This procedure is invoked to process the "square" Tcl command. It
 *	creates a new "square" widget.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
SquareObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Square *squarePtr;
    Tk_Window tkwin;
    Tk_OptionTable optionTable;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),







|
|

|


















|




















|

<
|

|

|
<




















|







<







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141

    Tcl_Obj *borderWidthPtr;	/* Width of 3-D border around whole widget. */
    Tcl_Obj *bgBorderPtr;
    Tcl_Obj *fgBorderPtr;
    Tcl_Obj *reliefPtr;
    GC gc;			/* Graphics context for copying from
				 * off-screen pixmap onto screen. */
    bool doubleBuffer;	/* true means double-buffer redisplay with
				 * pixmap; false means draw straight onto the
				 * display. */
    bool updatePending;		/* true means a call to SquareDisplay has
				 * already been scheduled. */
} Square;

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	    "#d9d9d9", offsetof(Square, bgBorderPtr), TCL_INDEX_NONE, 0,
	    "white", 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	    "2", offsetof(Square, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BOOLEAN, "-dbl", "doubleBuffer", "DoubleBuffer",
	    "1", TCL_INDEX_NONE, offsetof(Square, doubleBuffer), TK_OPTION_VAR(bool) , NULL, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
	    "-foreground", 0},
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
	    "#b03060", offsetof(Square, fgBorderPtr), TCL_INDEX_NONE, 0,
	    "black", 0},
    {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0",
	    offsetof(Square, xPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0",
	    offsetof(Square, yPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	    "raised", offsetof(Square, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-size", "size", "Size", "20",
	    offsetof(Square, sizeObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};

/*
 * Forward declarations for procedures defined later in this file:
 */

static void		SquareDeletedProc(void *clientData);
static int		SquareConfigure(Tcl_Interp *interp, Square *squarePtr);

static void		SquareDisplay(void *clientData);
static void		KeepInWindow(Square *squarePtr);
static void		SquareObjEventProc(void *clientData,
			    XEvent *eventPtr);
static Tcl_ObjCmdProc SquareWidgetObjCmd;


/*
 *--------------------------------------------------------------
 *
 * SquareCmd --
 *
 *	This procedure is invoked to process the "square" Tcl command. It
 *	creates a new "square" widget.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
SquareObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Square *squarePtr;
    Tk_Window tkwin;
    Tk_OptionTable optionTable;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
	goto error;
    }
    if (SquareConfigure(interp, squarePtr) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp,
	    Tcl_NewStringObj(Tk_PathName(squarePtr->tkwin), -1));
    return TCL_OK;

  error:
    Tk_DestroyWindow(squarePtr->tkwin);
    return TCL_ERROR;
}








|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
	goto error;
    }
    if (SquareConfigure(interp, squarePtr) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp,
	    Tcl_NewStringObj(Tk_PathName(squarePtr->tkwin), TCL_INDEX_NONE));
    return TCL_OK;

  error:
    Tk_DestroyWindow(squarePtr->tkwin);
    return TCL_ERROR;
}

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
SquareWidgetObjCmd(
    ClientData clientData,	/* Information about square widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    Square *squarePtr = (Square *)clientData;
    int result = TCL_OK;
    static const char *const squareOptions[] = {"cget", "configure", NULL};







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
SquareWidgetObjCmd(
    void *clientData,	/* Information about square widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    Square *squarePtr = (Square *)clientData;
    int result = TCL_OK;
    static const char *const squareOptions[] = {"cget", "configure", NULL};
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
		    squarePtr->optionTable, objc - 2, objv + 2,
		    squarePtr->tkwin, NULL, NULL);
	    if (result == TCL_OK) {
		result = SquareConfigure(interp, squarePtr);
	    }
	    if (!squarePtr->updatePending) {
		Tcl_DoWhenIdle(SquareDisplay, squarePtr);
		squarePtr->updatePending = 1;
	    }
	}
	if (resultObjPtr != NULL) {
	    Tcl_SetObjResult(interp, resultObjPtr);
	}
    }
    Tcl_Release(squarePtr);







|







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
		    squarePtr->optionTable, objc - 2, objv + 2,
		    squarePtr->tkwin, NULL, NULL);
	    if (result == TCL_OK) {
		result = SquareConfigure(interp, squarePtr);
	    }
	    if (!squarePtr->updatePending) {
		Tcl_DoWhenIdle(SquareDisplay, squarePtr);
		squarePtr->updatePending = true;
	    }
	}
	if (resultObjPtr != NULL) {
	    Tcl_SetObjResult(interp, resultObjPtr);
	}
    }
    Tcl_Release(squarePtr);
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
 *	for squarePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
SquareConfigure(
    Tcl_Interp *dummy,		/* Used for error reporting. */
    Square *squarePtr)		/* Information about widget. */
{
    int borderWidth;
    Tk_3DBorder bgBorder;
    int doubleBuffer;
    (void)dummy;

    /*
     * Set the background for the window and create a graphics context for use
     * during redisplay.
     */

    bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
	    squarePtr->bgBorderPtr);
    Tk_SetWindowBackground(squarePtr->tkwin,
	    Tk_3DBorderColor(bgBorder)->pixel);
    Tcl_GetBooleanFromObj(NULL, squarePtr->doubleBufferPtr, &doubleBuffer);
    if ((squarePtr->gc == NULL) && doubleBuffer) {
	XGCValues gcValues;
	gcValues.function = GXcopy;
	gcValues.graphics_exposures = False;
	squarePtr->gc = Tk_GetGC(squarePtr->tkwin,
		GCFunction|GCGraphicsExposures, &gcValues);
    }

    /*
     * Register the desired geometry for the window. Then arrange for the
     * window to be redisplayed.
     */

    Tk_GeometryRequest(squarePtr->tkwin, 200, 150);
    Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr,
	    &borderWidth);
    Tk_SetInternalBorder(squarePtr->tkwin, borderWidth);
    if (!squarePtr->updatePending) {
	Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	squarePtr->updatePending = 1;
    }
    KeepInWindow(squarePtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







|




<
<










<
|


















|







313
314
315
316
317
318
319
320
321
322
323
324


325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
 *	for squarePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
SquareConfigure(
    TCL_UNUSED(Tcl_Interp *),		/* Used for error reporting. */
    Square *squarePtr)		/* Information about widget. */
{
    int borderWidth;
    Tk_3DBorder bgBorder;



    /*
     * Set the background for the window and create a graphics context for use
     * during redisplay.
     */

    bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
	    squarePtr->bgBorderPtr);
    Tk_SetWindowBackground(squarePtr->tkwin,
	    Tk_3DBorderColor(bgBorder)->pixel);

    if ((squarePtr->gc == NULL) && squarePtr->doubleBuffer) {
	XGCValues gcValues;
	gcValues.function = GXcopy;
	gcValues.graphics_exposures = False;
	squarePtr->gc = Tk_GetGC(squarePtr->tkwin,
		GCFunction|GCGraphicsExposures, &gcValues);
    }

    /*
     * Register the desired geometry for the window. Then arrange for the
     * window to be redisplayed.
     */

    Tk_GeometryRequest(squarePtr->tkwin, 200, 150);
    Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr,
	    &borderWidth);
    Tk_SetInternalBorder(squarePtr->tkwin, borderWidth);
    if (!squarePtr->updatePending) {
	Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	squarePtr->updatePending = true;
    }
    KeepInWindow(squarePtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
SquareObjEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Square *squarePtr = (Square *)clientData;

    if (eventPtr->type == Expose) {
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == ConfigureNotify) {
	KeepInWindow(squarePtr);
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == DestroyNotify) {
	if (squarePtr->tkwin != NULL) {
	    Tk_FreeConfigOptions((char *) squarePtr, squarePtr->optionTable,
		    squarePtr->tkwin);
	    if (squarePtr->gc != NULL) {
		Tk_FreeGC(squarePtr->display, squarePtr->gc);
	    }
	    squarePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(squarePtr->interp,
		    squarePtr->widgetCmd);
	}
	if (squarePtr->updatePending) {
	    Tcl_CancelIdleCall(SquareDisplay, squarePtr);
	}
	Tcl_EventuallyFree(squarePtr, (Tcl_FreeProc *) SquareDestroy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDeletedProc --







|







|





|



|











|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
SquareObjEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Square *squarePtr = (Square *)clientData;

    if (eventPtr->type == Expose) {
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = true;
	}
    } else if (eventPtr->type == ConfigureNotify) {
	KeepInWindow(squarePtr);
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = true;
	}
    } else if (eventPtr->type == DestroyNotify) {
	if (squarePtr->tkwin != NULL) {
	    Tk_FreeConfigOptions(squarePtr, squarePtr->optionTable,
		    squarePtr->tkwin);
	    if (squarePtr->gc != NULL) {
		Tk_FreeGC(squarePtr->display, squarePtr->gc);
	    }
	    squarePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(squarePtr->interp,
		    squarePtr->widgetCmd);
	}
	if (squarePtr->updatePending) {
	    Tcl_CancelIdleCall(SquareDisplay, squarePtr);
	}
	Tcl_EventuallyFree(squarePtr, TCL_DYNAMIC);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDeletedProc --
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
SquareDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Square *squarePtr = (Square *)clientData;
    Tk_Window tkwin = squarePtr->tkwin;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
SquareDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    Square *squarePtr = (Square *)clientData;
    Tk_Window tkwin = squarePtr->tkwin;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
SquareDisplay(
    ClientData clientData)	/* Information about window. */
{
    Square *squarePtr = (Square *)clientData;
    Tk_Window tkwin = squarePtr->tkwin;
    Pixmap pm = None;
    Drawable d;
    int borderWidth, size, relief;
    Tk_3DBorder bgBorder, fgBorder;
    int doubleBuffer;

    squarePtr->updatePending = 0;
    if (!Tk_IsMapped(tkwin)) {
	return;
    }

    /*
     * Create a pixmap for double-buffering, if necessary.
     */

    Tcl_GetBooleanFromObj(NULL, squarePtr->doubleBufferPtr, &doubleBuffer);
    if (doubleBuffer) {
	pm = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
		Tk_Width(tkwin), Tk_Height(tkwin),
		DefaultDepthOfScreen(Tk_Screen(tkwin)));
	d = pm;
    } else {
	d = Tk_WindowId(tkwin);
    }







|







<

|








<
|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
SquareDisplay(
    void *clientData)	/* Information about window. */
{
    Square *squarePtr = (Square *)clientData;
    Tk_Window tkwin = squarePtr->tkwin;
    Pixmap pm = None;
    Drawable d;
    int borderWidth, size, relief;
    Tk_3DBorder bgBorder, fgBorder;


    squarePtr->updatePending = false;
    if (!Tk_IsMapped(tkwin)) {
	return;
    }

    /*
     * Create a pixmap for double-buffering, if necessary.
     */


    if (squarePtr->doubleBuffer) {
	pm = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
		Tk_Width(tkwin), Tk_Height(tkwin),
		DefaultDepthOfScreen(Tk_Screen(tkwin)));
	d = pm;
    } else {
	d = Tk_WindowId(tkwin);
    }
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
    Tk_Fill3DRectangle(tkwin, d, fgBorder, squarePtr->x, squarePtr->y, size,
	    size, borderWidth, TK_RELIEF_RAISED);

    /*
     * If double-buffered, copy to the screen and release the pixmap.
     */

    if (doubleBuffer) {
	XCopyArea(Tk_Display(tkwin), pm, Tk_WindowId(tkwin), squarePtr->gc,
		0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
		0, 0);
	Tk_FreePixmap(Tk_Display(tkwin), pm);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDestroy --
 *
 *	This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
 *	clean up the internal structure of a square at a safe time (when
 *	no-one is using it anymore).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the square is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
SquareDestroy(
    void *memPtr)		/* Info about square widget. */
{
    Square *squarePtr = (Square *)memPtr;

    ckfree(squarePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * KeepInWindow --
 *
 *	Adjust the position of the square if necessary to keep it in the







|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







517
518
519
520
521
522
523
524
525
526
527
528
529
530



























531
532
533
534
535
536
537
    Tk_Fill3DRectangle(tkwin, d, fgBorder, squarePtr->x, squarePtr->y, size,
	    size, borderWidth, TK_RELIEF_RAISED);

    /*
     * If double-buffered, copy to the screen and release the pixmap.
     */

    if (squarePtr->doubleBuffer) {
	XCopyArea(Tk_Display(tkwin), pm, Tk_WindowId(tkwin), squarePtr->gc,
		0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
		0, 0);
	Tk_FreePixmap(Tk_Display(tkwin), pm);
    }
}




























/*
 *----------------------------------------------------------------------
 *
 * KeepInWindow --
 *
 *	Adjust the position of the square if necessary to keep it in the

Changes to generic/tkStubInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkStubInit.c --
 *
 *	This file contains the initializers for the Tk stub vectors.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkStubInit.c --
 *
 *	This file contains the initializers for the Tk stub vectors.
 *
 * Copyright © 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"

21
22
23
24
25
26
27


28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60

61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114



115
116
117
118
119
120
121
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
/* we could have used _TKMACINT */
#include "tkMacOSXInt.h"
#include "tkMacOSXPrivate.h"


#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"


MODULE_SCOPE const TkStubs tkStubs;

/*
 * Remove macro that might interfere with the definition below.
 */

#undef Tk_MainEx
#undef Tk_FreeXId
#undef Tk_FreeStyleFromObj
#undef Tk_GetStyleFromObj
#undef TkWinGetPlatformId
#undef TkPutImage
#undef XPutImage
#define TkMacOSXSetUpClippingRgn (void (*)(Drawable))(void *)doNothing

#if defined(_WIN32) && !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#   define Tk_TranslateWinEvent TkTranslateWinEvent

#   define Tk_PointerEvent TkWinPointerEvent
#define TkWinGetPlatformId winGetPlatformId
static int TkWinGetPlatformId(void) {
    return 2;
}
#else
#   define Tk_TranslateWinEvent 0
#   define Tk_PointerEvent 0
#   define TkWinGetPlatformId 0
#endif



static int
doNothing(void)
{
    /* dummy implementation, no need to do anything */
    return 0;
}

#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#define Tk_MainEx 0
#define Tk_FreeXId 0
#define Tk_FreeStyleFromObj 0
#define Tk_GetStyleFromObj 0
#define TkWinGetPlatformId 0
#define Tk_PhotoPutBlock_NoComposite 0
#define Tk_PhotoPutZoomedBlock_NoComposite 0
#define Tk_PhotoExpand_Panic 0
#define Tk_PhotoPutBlock_Panic 0
#define Tk_PhotoPutZoomedBlock_Panic 0
#define Tk_PhotoSetSize_Panic 0
#define Tk_CreateOldPhotoImageFormat 0
#else
#define Tk_FreeXId ((void (*)(Display *, XID))(void *)doNothing)
#define Tk_FreeStyleFromObj ((void (*)(Tcl_Obj *))(void *)doNothing)
#define Tk_GetStyleFromObj getStyleFromObj
static Tk_Style Tk_GetStyleFromObj(Tcl_Obj *obj)
{
	return Tk_AllocStyleFromObj(NULL, obj);
}
#endif /* !TK_NO_DEPRECATED */

#define TkpCmapStressed_ TkpCmapStressed
#define TkpSync_ TkpSync
#define TkUnixContainerId_ TkUnixContainerId
#define TkUnixDoOneXEvent_ TkUnixDoOneXEvent
#define TkUnixSetMenubar_ TkUnixSetMenubar
#define TkWmCleanup_ TkWmCleanup
#define TkSendCleanup_ TkSendCleanup
#define TkpTestsendCmd_ TkpTestsendCmd
#define TkGenWMConfigureEvent_ TkGenWMConfigureEvent
#define TkGenerateActivateEvents_ TkGenerateActivateEvents
#define TkMacOSXDrawable Tk_MacOSXGetNSWindowForDrawable
#define Tk_CanvasTagsParseProc \
		(int (*) (void *, Tcl_Interp *,Tk_Window, const char *, char *, \
		int offset))(void *)TkCanvasTagsParseProc
#define Tk_CanvasTagsPrintProc \
		(const char *(*) (void *,Tk_Window, char *, int, \
		Tcl_FreeProc **))(void *)TkCanvasTagsPrintProc

#if !defined(MAC_OSX_TK) && defined(MAC_OSX_TCL)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   define TkpWillDrawWidget ((int (*)(Tk_Window))(void *)doNothing)
#   define TkpRedrawWidget ((void (*)(Tk_Window))(void *)doNothing)



#endif

#ifdef _WIN32

int
TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
{







>
>





>







<
<
<
<
<


|
|
|
|
>
|
|
<
<
<
<
|
|
|
<
>

>






|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|


>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42





43
44
45
46
47
48
49
50
51




52
53
54

55
56
57
58
59
60
61
62
63
64






















65

















66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
/* we could have used _TKMACINT */
#include "tkMacOSXInt.h"
#include "tkMacOSXPrivate.h"
#else
#   define Tk_ClipDrawableToRect 0
#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"
#include "tkText.h"

MODULE_SCOPE const TkStubs tkStubs;

/*
 * Remove macro that might interfere with the definition below.
 */






#undef TkPutImage
#undef XPutImage
#define TkpTesttextCmd TkrTesttextCmd
#define TkTextGetIndex TkrTextGetIndex
#define TkTextIndexBackBytes TkrTextIndexBackBytes
#define TkTextIndexForwBytes TkrTextIndexForwBytes
#define TkTextMakeByteIndex TkrTextMakeByteIndex
#define TkTextPrintIndex TkrTextPrintIndex
#define TkTextSetMark TkrTextSetMark




#define TkTextXviewCmd TkrTextXviewCmd
#define TkTextChanged TkrTextChanged
#define TkBTreeNumLines TkrBTreeNumLines

#define TkTextInsertDisplayProc TkrTextInsertDisplayProc

#if !defined(MAC_OSX_TK)
static int
doNothing(void)
{
    /* dummy implementation, no need to do anything */
    return 0;
}
#   undef TkpWillDrawWidget






















#   undef TkpRedrawWidget

















#   undef TkpDefineNativeBitmaps

#   undef TkpCreateNativeBitmap
#   undef TkpGetNativeAppBitmap
#   define TkpWillDrawWidget ((int (*)(Tk_Window))(void *)doNothing)
#   define TkpRedrawWidget ((void (*)(Tk_Window))(void *)doNothing)
#   define TkpDefineNativeBitmaps ((void (*)(void))(void *)doNothing)
#   define TkpCreateNativeBitmap ((Pixmap (*)(Display *, const void *))(void *)doNothing)
#   define TkpGetNativeAppBitmap ((Pixmap (*)(Display *, const char*, int *, int *))(void *)doNothing)
#endif

#ifdef _WIN32

int
TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
{
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

void
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold
				 * the hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
}

int
TkPutImage(
    unsigned long *colors,	/* Array of pixel values used by this image.
				 * May be NULL. */
    int ncolors,		/* Number of colors used, or 0. */







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

void
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold
				 * the hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    snprintf(buf, TCL_INTEGER_SPACE, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
}

int
TkPutImage(
    unsigned long *colors,	/* Array of pixel values used by this image.
				 * May be NULL. */
    int ncolors,		/* Number of colors used, or 0. */
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    TkOvalToArea, /* 53 */
    TkOvalToPoint, /* 54 */
    TkpChangeFocus, /* 55 */
    TkpCloseDisplay, /* 56 */
    TkpClaimFocus, /* 57 */
    TkpDisplayWarning, /* 58 */
    TkpGetAppName, /* 59 */
    TkpGetOtherWindow, /* 60 */
    TkpGetWrapperWindow, /* 61 */
    TkpInit, /* 62 */
    TkpInitializeMenuBindings, /* 63 */
    TkpMakeContainer, /* 64 */
    TkpMakeMenuWindow, /* 65 */
    TkpMakeWindow, /* 66 */
    TkpMenuNotifyToplevelCreate, /* 67 */
    TkpOpenDisplay, /* 68 */
    TkPointerEvent, /* 69 */
    TkPolygonToArea, /* 70 */
    TkPolygonToPoint, /* 71 */
    TkPositionInTree, /* 72 */
    TkpRedirectKeyEvent, /* 73 */
    TkpSetMainMenubar, /* 74 */
    TkpUseWindow, /* 75 */
    0, /* 76 */
    TkQueueEventForAllChildren, /* 77 */
    TkReadBitmapFile, /* 78 */
    TkScrollWindow, /* 79 */
    TkSelDeadWindow, /* 80 */
    TkSelEventProc, /* 81 */
    TkSelInit, /* 82 */
    TkSelPropProc, /* 83 */
    0, /* 84 */
    TkSetWindowMenuBar, /* 85 */
    TkStringToKeysym, /* 86 */
    TkThickPolyLineToArea, /* 87 */
    TkWmAddToColormapWindows, /* 88 */
    TkWmDeadWindow, /* 89 */
    TkWmFocusToplevel, /* 90 */
    TkWmMapWindow, /* 91 */
    TkWmNewWindow, /* 92 */







|



|

|







|
|









|







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
    TkOvalToArea, /* 53 */
    TkOvalToPoint, /* 54 */
    TkpChangeFocus, /* 55 */
    TkpCloseDisplay, /* 56 */
    TkpClaimFocus, /* 57 */
    TkpDisplayWarning, /* 58 */
    TkpGetAppName, /* 59 */
    0, /* 60 */
    TkpGetWrapperWindow, /* 61 */
    TkpInit, /* 62 */
    TkpInitializeMenuBindings, /* 63 */
    0, /* 64 */
    TkpMakeMenuWindow, /* 65 */
    0, /* 66 */
    TkpMenuNotifyToplevelCreate, /* 67 */
    TkpOpenDisplay, /* 68 */
    TkPointerEvent, /* 69 */
    TkPolygonToArea, /* 70 */
    TkPolygonToPoint, /* 71 */
    TkPositionInTree, /* 72 */
    TkpRedirectKeyEvent, /* 73 */
    0, /* 74 */
    0, /* 75 */
    0, /* 76 */
    TkQueueEventForAllChildren, /* 77 */
    TkReadBitmapFile, /* 78 */
    TkScrollWindow, /* 79 */
    TkSelDeadWindow, /* 80 */
    TkSelEventProc, /* 81 */
    TkSelInit, /* 82 */
    TkSelPropProc, /* 83 */
    0, /* 84 */
    0, /* 85 */
    TkStringToKeysym, /* 86 */
    TkThickPolyLineToArea, /* 87 */
    TkWmAddToColormapWindows, /* 88 */
    TkWmDeadWindow, /* 89 */
    TkWmFocusToplevel, /* 90 */
    TkWmMapWindow, /* 91 */
    TkWmNewWindow, /* 92 */
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    TkFindStateNumObj, /* 104 */
    TkGetBitmapPredefTable, /* 105 */
    TkGetDisplayList, /* 106 */
    TkGetMainInfoList, /* 107 */
    TkGetWindowFromObj, /* 108 */
    TkpGetString, /* 109 */
    TkpGetSubFonts, /* 110 */
    TkpGetSystemDefault, /* 111 */
    TkpMenuThreadInit, /* 112 */
    XClipBox, /* 113 */
    XCreateRegion, /* 114 */
    XDestroyRegion, /* 115 */
    XIntersectRegion, /* 116 */
    XRectInRegion, /* 117 */
    XSetRegion, /* 118 */
    XUnionRectWithRegion, /* 119 */
    0, /* 120 */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 121 */
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    0, /* 121 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 121 */ /* Dummy entry for stubs table backwards compatibility */
    TkpCreateNativeBitmap, /* 121 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 122 */
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    0, /* 122 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 122 */ /* Dummy entry for stubs table backwards compatibility */
    TkpDefineNativeBitmaps, /* 122 */
#endif /* AQUA */
    0, /* 123 */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    0, /* 124 */
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    0, /* 124 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 124 */ /* Dummy entry for stubs table backwards compatibility */
    TkpGetNativeAppBitmap, /* 124 */
#endif /* AQUA */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    0, /* 129 */
    0, /* 130 */
    0, /* 131 */
    0, /* 132 */
    0, /* 133 */
    0, /* 134 */
    TkpDrawHighlightBorder, /* 135 */
    TkSetFocusWin, /* 136 */
    TkpSetKeycodeAndState, /* 137 */
    TkpGetKeySym, /* 138 */
    TkpInitKeymapInfo, /* 139 */
    TkPhotoGetValidRegion, /* 140 */
    TkWmStackorderToplevel, /* 141 */
    TkFocusFree, /* 142 */







|









<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<

<

<
<
<
<
<
<
<
<

<










|







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371








372









373

374








375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
    TkFindStateNumObj, /* 104 */
    TkGetBitmapPredefTable, /* 105 */
    TkGetDisplayList, /* 106 */
    TkGetMainInfoList, /* 107 */
    TkGetWindowFromObj, /* 108 */
    TkpGetString, /* 109 */
    TkpGetSubFonts, /* 110 */
    0, /* 111 */
    TkpMenuThreadInit, /* 112 */
    XClipBox, /* 113 */
    XCreateRegion, /* 114 */
    XDestroyRegion, /* 115 */
    XIntersectRegion, /* 116 */
    XRectInRegion, /* 117 */
    XSetRegion, /* 118 */
    XUnionRectWithRegion, /* 119 */
    0, /* 120 */








    TkpCreateNativeBitmap, /* 121 */









    TkpDefineNativeBitmaps, /* 122 */

    0, /* 123 */








    TkpGetNativeAppBitmap, /* 124 */

    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    0, /* 129 */
    0, /* 130 */
    0, /* 131 */
    0, /* 132 */
    0, /* 133 */
    0, /* 134 */
    0, /* 135 */
    TkSetFocusWin, /* 136 */
    TkpSetKeycodeAndState, /* 137 */
    TkpGetKeySym, /* 138 */
    TkpInitKeymapInfo, /* 139 */
    TkPhotoGetValidRegion, /* 140 */
    TkWmStackorderToplevel, /* 141 */
    TkFocusFree, /* 142 */
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
    TkOrientPrintProc, /* 178 */
    TkSmoothParseProc, /* 179 */
    TkSmoothPrintProc, /* 180 */
    TkDrawAngledTextLayout, /* 181 */
    TkUnderlineAngledTextLayout, /* 182 */
    TkIntersectAngledTextLayout, /* 183 */
    TkDrawAngledChars, /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    0, /* 185 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 185 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    TkpRedrawWidget, /* 185 */
#endif /* MACOSX */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    0, /* 186 */
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 186 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    TkpWillDrawWidget, /* 186 */
#endif /* MACOSX */
    TkDebugPhotoStringMatchDef, /* 187 */
};

static const TkIntPlatStubs tkIntPlatStubs = {
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    TkAlignImageData, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpGetMS, /* 3 */
    TkPointerDeadWindow, /* 4 */
    TkpPrintWindowId, /* 5 */
    TkpScanWindowId, /* 6 */
    TkpSetCapture, /* 7 */







<
<
<
<
<
<
<

<
<
<
<
<
<
<
<

<







|







429
430
431
432
433
434
435







436








437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    TkOrientPrintProc, /* 178 */
    TkSmoothParseProc, /* 179 */
    TkSmoothPrintProc, /* 180 */
    TkDrawAngledTextLayout, /* 181 */
    TkUnderlineAngledTextLayout, /* 182 */
    TkIntersectAngledTextLayout, /* 183 */
    TkDrawAngledChars, /* 184 */







    TkpRedrawWidget, /* 185 */








    TkpWillDrawWidget, /* 186 */

    TkDebugPhotoStringMatchDef, /* 187 */
};

static const TkIntPlatStubs tkIntPlatStubs = {
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    TkCreateXEventSource, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpGetMS, /* 3 */
    TkPointerDeadWindow, /* 4 */
    TkpPrintWindowId, /* 5 */
    TkpScanWindowId, /* 6 */
    TkpSetCapture, /* 7 */
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582
583
584

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
    TkWinSetWindowPos, /* 26 */
    TkWinWmCleanup, /* 27 */
    TkWinXCleanup, /* 28 */
    TkWinXInit, /* 29 */
    TkWinSetForegroundWindow, /* 30 */
    TkWinDialogDebug, /* 31 */
    TkWinGetMenuSystemDefault, /* 32 */
    TkWinGetPlatformId, /* 33 */
    TkWinSetHINSTANCE, /* 34 */
    TkWinGetPlatformTheme, /* 35 */
    TkWinChildProc, /* 36 */
    TkCreateXEventSource, /* 37 */
    TkpCmapStressed, /* 38 */
    TkpSync, /* 39 */
    TkUnixContainerId, /* 40 */
    TkUnixDoOneXEvent, /* 41 */
    TkUnixSetMenubar, /* 42 */
    TkWmCleanup, /* 43 */
    TkSendCleanup, /* 44 */
    TkpTestsendCmd, /* 45 */
    0, /* 46 */
    TkpGetCapture, /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    TkGenerateActivateEvents, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents_, /* 2 */

    TkPointerDeadWindow, /* 3 */
    TkpSetCapture, /* 4 */
    TkpSetCursor, /* 5 */

    TkpWmSetState, /* 6 */
    TkAboutDlg, /* 7 */
    TkMacOSXButtonKeyState, /* 8 */
    TkMacOSXClearMenubarActive, /* 9 */
    TkMacOSXDispatchMenuEvent, /* 10 */
    0, /* 11 */
    TkMacOSXHandleTearoffMenu, /* 12 */
    0, /* 13 */
    TkMacOSXDoHLEvent, /* 14 */
    0, /* 15 */
    TkMacOSXGetXWindow, /* 16 */
    TkMacOSXGrowToplevel, /* 17 */
    TkMacOSXHandleMenuSelect, /* 18 */
    0, /* 19 */
    0, /* 20 */
    TkMacOSXInvalidateWindow, /* 21 */
    TkMacOSXIsCharacterMissing, /* 22 */
    TkMacOSXMakeRealWindowExist, /* 23 */
    TkMacOSXMakeStippleMap, /* 24 */
    TkMacOSXMenuClick, /* 25 */
    0, /* 26 */
    TkMacOSXResizable, /* 27 */
    TkMacOSXSetHelpMenuItemCount, /* 28 */
    TkMacOSXSetScrollbarGrow, /* 29 */
    TkMacOSXSetUpClippingRgn, /* 30 */
    TkMacOSXSetUpGraphicsPort, /* 31 */
    TkMacOSXUpdateClipRgn, /* 32 */
    0, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */







|



|












|
|
|
>
|
<

>
|
<



|










|







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

500
501
502

503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
    TkWinSetWindowPos, /* 26 */
    TkWinWmCleanup, /* 27 */
    TkWinXCleanup, /* 28 */
    TkWinXInit, /* 29 */
    TkWinSetForegroundWindow, /* 30 */
    TkWinDialogDebug, /* 31 */
    TkWinGetMenuSystemDefault, /* 32 */
    TkAlignImageData, /* 33 */
    TkWinSetHINSTANCE, /* 34 */
    TkWinGetPlatformTheme, /* 35 */
    TkWinChildProc, /* 36 */
    0, /* 37 */
    TkpCmapStressed, /* 38 */
    TkpSync, /* 39 */
    TkUnixContainerId, /* 40 */
    TkUnixDoOneXEvent, /* 41 */
    TkUnixSetMenubar, /* 42 */
    TkWmCleanup, /* 43 */
    TkSendCleanup, /* 44 */
    TkpTestsendCmd, /* 45 */
    0, /* 46 */
    TkpGetCapture, /* 47 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 0 */
    TkAboutDlg, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpGetMS, /* 3 */
    TkPointerDeadWindow, /* 4 */

    TkpSetCursor, /* 5 */
    TkpScanWindowId, /* 6 */
    TkpWmSetState, /* 7 */

    TkMacOSXButtonKeyState, /* 8 */
    TkMacOSXClearMenubarActive, /* 9 */
    TkMacOSXDispatchMenuEvent, /* 10 */
    TkpSetCapture, /* 11 */
    TkMacOSXHandleTearoffMenu, /* 12 */
    0, /* 13 */
    TkMacOSXDoHLEvent, /* 14 */
    0, /* 15 */
    TkMacOSXGetXWindow, /* 16 */
    TkMacOSXGrowToplevel, /* 17 */
    TkMacOSXHandleMenuSelect, /* 18 */
    0, /* 19 */
    0, /* 20 */
    TkMacOSXInvalidateWindow, /* 21 */
    0, /* 22 */
    TkMacOSXMakeRealWindowExist, /* 23 */
    TkMacOSXMakeStippleMap, /* 24 */
    TkMacOSXMenuClick, /* 25 */
    0, /* 26 */
    TkMacOSXResizable, /* 27 */
    TkMacOSXSetHelpMenuItemCount, /* 28 */
    TkMacOSXSetScrollbarGrow, /* 29 */
    0, /* 30 */
    TkMacOSXSetUpGraphicsPort, /* 31 */
    TkMacOSXUpdateClipRgn, /* 32 */
    0, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    TkpIsWindowFloating, /* 46 */
    TkpGetCapture, /* 47 */
    0, /* 48 */
    TkMacOSXGetContainer, /* 49 */
    TkGenerateButtonEvent, /* 50 */
    TkGenWMDestroyEvent, /* 51 */
    TkMacOSXSetDrawingEnabled, /* 52 */
    TkpGetMS, /* 53 */
    TkMacOSXDrawable, /* 54 */
    TkpScanWindowId, /* 55 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    TkCreateXEventSource, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    TkpCmapStressed, /* 3 */
    TkpSync, /* 4 */
    TkUnixContainerId, /* 5 */
    TkUnixDoOneXEvent, /* 6 */
    TkUnixSetMenubar, /* 7 */
    TkpScanWindowId, /* 8 */
    TkWmCleanup, /* 9 */
    TkSendCleanup, /* 10 */
    0, /* 11 */
    TkpWmSetState, /* 12 */
    TkpTestsendCmd, /* 13 */
    0, /* 14 */
    0, /* 15 */
    0, /* 16 */
    0, /* 17 */
    0, /* 18 */
    0, /* 19 */
    0, /* 20 */







<
<
<





|
|
|
|
|
|
|
|

|
|







541
542
543
544
545
546
547



548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
    TkpIsWindowFloating, /* 46 */
    TkpGetCapture, /* 47 */
    0, /* 48 */
    TkMacOSXGetContainer, /* 49 */
    TkGenerateButtonEvent, /* 50 */
    TkGenWMDestroyEvent, /* 51 */
    TkMacOSXSetDrawingEnabled, /* 52 */



#endif /* AQUA */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
    TkCreateXEventSource, /* 0 */
    0, /* 1 */
    TkGenerateActivateEvents, /* 2 */
    0, /* 3 */
    0, /* 4 */
    0, /* 5 */
    TkpScanWindowId, /* 6 */
    0, /* 7 */
    0, /* 8 */
    TkpWmSetState, /* 9 */
    0, /* 10 */
    0, /* 11 */
    0, /* 12 */
    0, /* 13 */
    0, /* 14 */
    0, /* 15 */
    0, /* 16 */
    0, /* 17 */
    0, /* 18 */
    0, /* 19 */
    0, /* 20 */
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
    0, /* 31 */
    0, /* 32 */
    0, /* 33 */
    0, /* 34 */
    0, /* 35 */
    0, /* 36 */
    0, /* 37 */
    TkpCmapStressed_, /* 38 */
    TkpSync_, /* 39 */
    TkUnixContainerId_, /* 40 */
    TkUnixDoOneXEvent_, /* 41 */
    TkUnixSetMenubar_, /* 42 */
    TkWmCleanup_, /* 43 */
    TkSendCleanup_, /* 44 */
    TkpTestsendCmd_, /* 45 */
#endif /* X11 */
};

static const TkIntXlibStubs tkIntXlibStubs = {
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */







|
|
|
|
|
|
|
|







581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    0, /* 31 */
    0, /* 32 */
    0, /* 33 */
    0, /* 34 */
    0, /* 35 */
    0, /* 36 */
    0, /* 37 */
    TkpCmapStressed, /* 38 */
    TkpSync, /* 39 */
    TkUnixContainerId, /* 40 */
    TkUnixDoOneXEvent, /* 41 */
    TkUnixSetMenubar, /* 42 */
    TkWmCleanup, /* 43 */
    TkSendCleanup, /* 44 */
    TkpTestsendCmd, /* 45 */
#endif /* X11 */
};

static const TkIntXlibStubs tkIntXlibStubs = {
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    XUngrabPointer, /* 74 */
    XUnmapWindow, /* 75 */
    XWindowEvent, /* 76 */
    XDestroyIC, /* 77 */
    XFilterEvent, /* 78 */
    XmbLookupString, /* 79 */
    TkPutImage, /* 80 */
    0, /* 81 */
    XParseColor, /* 82 */
    XCreateGC, /* 83 */
    XFreeGC, /* 84 */
    XInternAtom, /* 85 */
    XSetBackground, /* 86 */
    XSetForeground, /* 87 */
    XSetClipMask, /* 88 */







|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    XUngrabPointer, /* 74 */
    XUnmapWindow, /* 75 */
    XWindowEvent, /* 76 */
    XDestroyIC, /* 77 */
    XFilterEvent, /* 78 */
    XmbLookupString, /* 79 */
    TkPutImage, /* 80 */
    XSetClipRectangles, /* 81 */
    XParseColor, /* 82 */
    XCreateGC, /* 83 */
    XFreeGC, /* 84 */
    XInternAtom, /* 85 */
    XSetBackground, /* 86 */
    XSetForeground, /* 87 */
    XSetClipMask, /* 88 */
851
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
    XSetDashes, /* 0 */
    XGetModifierMapping, /* 1 */
    XCreateImage, /* 2 */
    XGetImage, /* 3 */
    XGetAtomName, /* 4 */
    XKeysymToString, /* 5 */
    XCreateColormap, /* 6 */


    XGContextFromGC, /* 7 */

    XKeycodeToKeysym, /* 8 */
    XStringToKeysym, /* 9 */
    XRootWindow, /* 10 */
    XSetErrorHandler, /* 11 */



    XAllocColor, /* 12 */
    XBell, /* 13 */
    XChangeProperty, /* 14 */
    XChangeWindowAttributes, /* 15 */

    XConfigureWindow, /* 16 */
    XCopyArea, /* 17 */
    XCopyPlane, /* 18 */
    XCreateBitmapFromData, /* 19 */
    XDefineCursor, /* 20 */

    XDestroyWindow, /* 21 */
    XDrawArc, /* 22 */
    XDrawLines, /* 23 */
    XDrawRectangle, /* 24 */
    XFillArc, /* 25 */
    XFillPolygon, /* 26 */
    XFillRectangles, /* 27 */

    XFreeColormap, /* 28 */
    XFreeColors, /* 29 */

    XFreeModifiermap, /* 30 */
    XGetGeometry, /* 31 */

    XGetWindowProperty, /* 32 */

    XGrabKeyboard, /* 33 */
    XGrabPointer, /* 34 */
    XKeysymToKeycode, /* 35 */

    XMapWindow, /* 36 */
    XMoveResizeWindow, /* 37 */
    XMoveWindow, /* 38 */



    XQueryPointer, /* 39 */

    XRaiseWindow, /* 40 */
    XRefreshKeyboardMapping, /* 41 */
    XResizeWindow, /* 42 */
    XSelectInput, /* 43 */
    XSendEvent, /* 44 */

    XSetIconName, /* 45 */
    XSetInputFocus, /* 46 */
    XSetSelectionOwner, /* 47 */
    XSetWindowBackground, /* 48 */
    XSetWindowBackgroundPixmap, /* 49 */
    XSetWindowBorder, /* 50 */
    XSetWindowBorderPixmap, /* 51 */
    XSetWindowBorderWidth, /* 52 */
    XSetWindowColormap, /* 53 */

    XUngrabKeyboard, /* 54 */
    XUngrabPointer, /* 55 */
    XUnmapWindow, /* 56 */
    TkPutImage, /* 57 */
    XParseColor, /* 58 */






    XCreateGC, /* 59 */
    XFreeGC, /* 60 */
    XInternAtom, /* 61 */
    XSetBackground, /* 62 */
    XSetForeground, /* 63 */
    XSetClipMask, /* 64 */
    XSetClipOrigin, /* 65 */
    XSetTSOrigin, /* 66 */
    XChangeGC, /* 67 */
    XSetFont, /* 68 */
    XSetArcMode, /* 69 */
    XSetStipple, /* 70 */
    XSetFillRule, /* 71 */
    XSetFillStyle, /* 72 */
    XSetFunction, /* 73 */
    XSetLineAttributes, /* 74 */
    _XInitImageFuncPtrs, /* 75 */
    XCreateIC, /* 76 */
    XGetVisualInfo, /* 77 */
    XSetWMClientMachine, /* 78 */
    XStringListToTextProperty, /* 79 */
    XDrawSegments, /* 80 */
    XForceScreenSaver, /* 81 */
    XDrawLine, /* 82 */
    XFillRectangle, /* 83 */
    XClearWindow, /* 84 */
    XDrawPoint, /* 85 */
    XDrawPoints, /* 86 */
    XWarpPointer, /* 87 */
    XQueryColor, /* 88 */
    XQueryColors, /* 89 */
    XQueryTree, /* 90 */
    XSync, /* 91 */
    XTranslateCoordinates, /* 92 */
    XDeleteProperty, /* 93 */
    XFreeCursor, /* 94 */
    XGetInputFocus, /* 95 */
    XmbLookupString, /* 96 */
    XNextEvent, /* 97 */
    XPutBackEvent, /* 98 */
    XSetCommand, /* 99 */
    XWindowEvent, /* 100 */
    XGetWindowAttributes, /* 101 */
    XGetWMColormapWindows, /* 102 */
    XIconifyWindow, /* 103 */
    XWithdrawWindow, /* 104 */
    XListHosts, /* 105 */
    XSetClipRectangles, /* 106 */
    XFlush, /* 107 */
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XLookupColor, /* 113 */
    XVisualIDFromVisual, /* 114 */
    0, /* 115 */
    0, /* 116 */
    0, /* 117 */
    0, /* 118 */
    0, /* 119 */
    XOffsetRegion, /* 120 */
    XUnionRegion, /* 121 */
    XCreateWindow, /* 122 */
    0, /* 123 */
    0, /* 124 */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    XLowerWindow, /* 129 */
    XFillArcs, /* 130 */
    XDrawArcs, /* 131 */
    XDrawRectangles, /* 132 */
    0, /* 133 */
    0, /* 134 */
    0, /* 135 */
    XReparentWindow, /* 136 */
    XPutImage, /* 137 */
    XPolygonRegion, /* 138 */
    XPointInRegion, /* 139 */
    XVaCreateNestedList, /* 140 */
    XSetICValues, /* 141 */
    XGetICValues, /* 142 */
    XSetICFocus, /* 143 */
    XDestroyIC, /* 144 */
    XCreatePixmapCursor, /* 145 */
    XCreateGlyphCursor, /* 146 */
    XFreeFontSet, /* 147 */
    XCloseIM, /* 148 */
    XRegisterIMInstantiateCallback, /* 149 */
    XUnregisterIMInstantiateCallback, /* 150 */
    XSetLocaleModifiers, /* 151 */
    XOpenIM, /* 152 */
    XGetIMValues, /* 153 */







>
>
|
>
|
|
|
|
>
>
>
|
|
|
|
>
|
|
|
|
|
>
|
|
|
|
|
|
|
>
|
|
>
|
|
>
|
>
|
|
|
>
|
|
|
>
>
>
|
>
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
>
|
|
|
|
<
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|






|



















|
|
|








|
|
|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    XSetDashes, /* 0 */
    XGetModifierMapping, /* 1 */
    XCreateImage, /* 2 */
    XGetImage, /* 3 */
    XGetAtomName, /* 4 */
    XKeysymToString, /* 5 */
    XCreateColormap, /* 6 */
    XCreatePixmapCursor, /* 7 */
    XCreateGlyphCursor, /* 8 */
    XGContextFromGC, /* 9 */
    XListHosts, /* 10 */
    XKeycodeToKeysym, /* 11 */
    XStringToKeysym, /* 12 */
    XRootWindow, /* 13 */
    XSetErrorHandler, /* 14 */
    XIconifyWindow, /* 15 */
    XWithdrawWindow, /* 16 */
    XGetWMColormapWindows, /* 17 */
    XAllocColor, /* 18 */
    XBell, /* 19 */
    XChangeProperty, /* 20 */
    XChangeWindowAttributes, /* 21 */
    XClearWindow, /* 22 */
    XConfigureWindow, /* 23 */
    XCopyArea, /* 24 */
    XCopyPlane, /* 25 */
    XCreateBitmapFromData, /* 26 */
    XDefineCursor, /* 27 */
    XDeleteProperty, /* 28 */
    XDestroyWindow, /* 29 */
    XDrawArc, /* 30 */
    XDrawLines, /* 31 */
    XDrawRectangle, /* 32 */
    XFillArc, /* 33 */
    XFillPolygon, /* 34 */
    XFillRectangles, /* 35 */
    XForceScreenSaver, /* 36 */
    XFreeColormap, /* 37 */
    XFreeColors, /* 38 */
    XFreeCursor, /* 39 */
    XFreeModifiermap, /* 40 */
    XGetGeometry, /* 41 */
    XGetInputFocus, /* 42 */
    XGetWindowProperty, /* 43 */
    XGetWindowAttributes, /* 44 */
    XGrabKeyboard, /* 45 */
    XGrabPointer, /* 46 */
    XKeysymToKeycode, /* 47 */
    XLookupColor, /* 48 */
    XMapWindow, /* 49 */
    XMoveResizeWindow, /* 50 */
    XMoveWindow, /* 51 */
    XNextEvent, /* 52 */
    XPutBackEvent, /* 53 */
    XQueryColors, /* 54 */
    XQueryPointer, /* 55 */
    XQueryTree, /* 56 */
    XRaiseWindow, /* 57 */
    XRefreshKeyboardMapping, /* 58 */
    XResizeWindow, /* 59 */
    XSelectInput, /* 60 */
    XSendEvent, /* 61 */
    XSetCommand, /* 62 */
    XSetIconName, /* 63 */
    XSetInputFocus, /* 64 */
    XSetSelectionOwner, /* 65 */
    XSetWindowBackground, /* 66 */
    XSetWindowBackgroundPixmap, /* 67 */
    XSetWindowBorder, /* 68 */
    XSetWindowBorderPixmap, /* 69 */
    XSetWindowBorderWidth, /* 70 */
    XSetWindowColormap, /* 71 */
    XTranslateCoordinates, /* 72 */
    XUngrabKeyboard, /* 73 */
    XUngrabPointer, /* 74 */
    XUnmapWindow, /* 75 */
    XWindowEvent, /* 76 */

    XDestroyIC, /* 77 */
    XFilterEvent, /* 78 */
    XmbLookupString, /* 79 */
    TkPutImage, /* 80 */
    XSetClipRectangles, /* 81 */
    XParseColor, /* 82 */
    XCreateGC, /* 83 */
    XFreeGC, /* 84 */
    XInternAtom, /* 85 */
    XSetBackground, /* 86 */
    XSetForeground, /* 87 */
    XSetClipMask, /* 88 */
    XSetClipOrigin, /* 89 */
    XSetTSOrigin, /* 90 */
    XChangeGC, /* 91 */
    XSetFont, /* 92 */
    XSetArcMode, /* 93 */
    XSetStipple, /* 94 */
    XSetFillRule, /* 95 */
    XSetFillStyle, /* 96 */
    XSetFunction, /* 97 */
    XSetLineAttributes, /* 98 */
    _XInitImageFuncPtrs, /* 99 */
    XCreateIC, /* 100 */
    XGetVisualInfo, /* 101 */
    XSetWMClientMachine, /* 102 */
    XStringListToTextProperty, /* 103 */


    XDrawLine, /* 104 */




    XWarpPointer, /* 105 */


















    XFillRectangle, /* 106 */
    XFlush, /* 107 */
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XSync, /* 113 */
    XVisualIDFromVisual, /* 114 */
    0, /* 115 */
    0, /* 116 */
    0, /* 117 */
    0, /* 118 */
    0, /* 119 */
    XOffsetRegion, /* 120 */
    XUnionRegion, /* 121 */
    XCreateWindow, /* 122 */
    0, /* 123 */
    0, /* 124 */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    XLowerWindow, /* 129 */
    XFillArcs, /* 130 */
    XDrawArcs, /* 131 */
    XDrawRectangles, /* 132 */
    XDrawSegments, /* 133 */
    XDrawPoint, /* 134 */
    XDrawPoints, /* 135 */
    XReparentWindow, /* 136 */
    XPutImage, /* 137 */
    XPolygonRegion, /* 138 */
    XPointInRegion, /* 139 */
    XVaCreateNestedList, /* 140 */
    XSetICValues, /* 141 */
    XGetICValues, /* 142 */
    XSetICFocus, /* 143 */
    0, /* 144 */
    0, /* 145 */
    0, /* 146 */
    XFreeFontSet, /* 147 */
    XCloseIM, /* 148 */
    XRegisterIMInstantiateCallback, /* 149 */
    XUnregisterIMInstantiateCallback, /* 150 */
    XSetLocaleModifiers, /* 151 */
    XOpenIM, /* 152 */
    XGetIMValues, /* 153 */
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    Tk_AttachHWND, /* 0 */
    Tk_GetHINSTANCE, /* 1 */
    Tk_GetHWND, /* 2 */
    Tk_HWNDToWindow, /* 3 */
    Tk_PointerEvent, /* 4 */
    Tk_TranslateWinEvent, /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 0 */
    0, /* 1 */
    0, /* 2 */
    0, /* 3 */
    TkMacOSXInitAppleEvents, /* 4 */
    TkGenWMConfigureEvent_, /* 5 */
    TkMacOSXInvalClipRgns, /* 6 */
    0, /* 7 */
    TkMacOSXGetRootControl, /* 8 */
    Tk_MacOSXSetupTkNotifier, /* 9 */
    Tk_MacOSXIsAppInFront, /* 10 */
    Tk_MacOSXGetTkWindow, /* 11 */
    Tk_MacOSXGetCGContextForDrawable, /* 12 */







<
<







|







927
928
929
930
931
932
933


934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    Tk_AttachHWND, /* 0 */
    Tk_GetHINSTANCE, /* 1 */
    Tk_GetHWND, /* 2 */
    Tk_HWNDToWindow, /* 3 */


#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    0, /* 0 */
    0, /* 1 */
    0, /* 2 */
    0, /* 3 */
    TkMacOSXInitAppleEvents, /* 4 */
    0, /* 5 */
    TkMacOSXInvalClipRgns, /* 6 */
    0, /* 7 */
    TkMacOSXGetRootControl, /* 8 */
    Tk_MacOSXSetupTkNotifier, /* 9 */
    Tk_MacOSXIsAppInFront, /* 10 */
    Tk_MacOSXGetTkWindow, /* 11 */
    Tk_MacOSXGetCGContextForDrawable, /* 12 */
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
    Tk_FreeCursor, /* 70 */
    Tk_FreeFont, /* 71 */
    Tk_FreeGC, /* 72 */
    Tk_FreeImage, /* 73 */
    Tk_FreeOptions, /* 74 */
    Tk_FreePixmap, /* 75 */
    Tk_FreeTextLayout, /* 76 */
    Tk_FreeXId, /* 77 */
    Tk_GCForColor, /* 78 */
    Tk_GeometryRequest, /* 79 */
    Tk_Get3DBorder, /* 80 */
    Tk_GetAllBindings, /* 81 */
    Tk_GetAnchor, /* 82 */
    Tk_GetAtomName, /* 83 */
    Tk_GetBinding, /* 84 */







|







1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
    Tk_FreeCursor, /* 70 */
    Tk_FreeFont, /* 71 */
    Tk_FreeGC, /* 72 */
    Tk_FreeImage, /* 73 */
    Tk_FreeOptions, /* 74 */
    Tk_FreePixmap, /* 75 */
    Tk_FreeTextLayout, /* 76 */
    0, /* 77 */
    Tk_GCForColor, /* 78 */
    Tk_GeometryRequest, /* 79 */
    Tk_Get3DBorder, /* 80 */
    Tk_GetAllBindings, /* 81 */
    Tk_GetAnchor, /* 82 */
    Tk_GetAtomName, /* 83 */
    Tk_GetBinding, /* 84 */
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
    Tk_GetUid, /* 111 */
    Tk_GetVisual, /* 112 */
    Tk_GetVRootGeometry, /* 113 */
    Tk_Grab, /* 114 */
    Tk_HandleEvent, /* 115 */
    Tk_IdToWindow, /* 116 */
    Tk_ImageChanged, /* 117 */
    Tk_Init, /* 118 */
    Tk_InternAtom, /* 119 */
    Tk_IntersectTextLayout, /* 120 */
    Tk_MaintainGeometry, /* 121 */
    Tk_MainWindow, /* 122 */
    Tk_MakeWindowExist, /* 123 */
    Tk_ManageGeometry, /* 124 */
    Tk_MapWindow, /* 125 */







|







1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
    Tk_GetUid, /* 111 */
    Tk_GetVisual, /* 112 */
    Tk_GetVRootGeometry, /* 113 */
    Tk_Grab, /* 114 */
    Tk_HandleEvent, /* 115 */
    Tk_IdToWindow, /* 116 */
    Tk_ImageChanged, /* 117 */
    0, /* 118 */
    Tk_InternAtom, /* 119 */
    Tk_IntersectTextLayout, /* 120 */
    Tk_MaintainGeometry, /* 121 */
    Tk_MainWindow, /* 122 */
    Tk_MakeWindowExist, /* 123 */
    Tk_ManageGeometry, /* 124 */
    Tk_MapWindow, /* 125 */
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
    Tk_NameOfImage, /* 137 */
    Tk_NameOfJoinStyle, /* 138 */
    Tk_NameOfJustify, /* 139 */
    Tk_NameOfRelief, /* 140 */
    Tk_NameToWindow, /* 141 */
    Tk_OwnSelection, /* 142 */
    Tk_ParseArgv, /* 143 */
    Tk_PhotoPutBlock_NoComposite, /* 144 */
    Tk_PhotoPutZoomedBlock_NoComposite, /* 145 */
    Tk_PhotoGetImage, /* 146 */
    Tk_PhotoBlank, /* 147 */
    Tk_PhotoExpand_Panic, /* 148 */
    Tk_PhotoGetSize, /* 149 */
    Tk_PhotoSetSize_Panic, /* 150 */
    Tk_PointToChar, /* 151 */
    Tk_PostscriptFontName, /* 152 */
    Tk_PreserveColormap, /* 153 */
    Tk_QueueWindowEvent, /* 154 */
    Tk_RedrawImage, /* 155 */
    Tk_ResizeWindow, /* 156 */
    Tk_RestackWindow, /* 157 */
    Tk_RestrictEvents, /* 158 */
    Tk_SafeInit, /* 159 */
    Tk_SetAppName, /* 160 */
    Tk_SetBackgroundFromBorder, /* 161 */
    Tk_SetClass, /* 162 */
    Tk_SetGrid, /* 163 */
    Tk_SetInternalBorder, /* 164 */
    Tk_SetWindowBackground, /* 165 */
    Tk_SetWindowBackgroundPixmap, /* 166 */







|
|


|

|








|







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
    Tk_NameOfImage, /* 137 */
    Tk_NameOfJoinStyle, /* 138 */
    Tk_NameOfJustify, /* 139 */
    Tk_NameOfRelief, /* 140 */
    Tk_NameToWindow, /* 141 */
    Tk_OwnSelection, /* 142 */
    Tk_ParseArgv, /* 143 */
    0, /* 144 */
    0, /* 145 */
    Tk_PhotoGetImage, /* 146 */
    Tk_PhotoBlank, /* 147 */
    0, /* 148 */
    Tk_PhotoGetSize, /* 149 */
    0, /* 150 */
    Tk_PointToChar, /* 151 */
    Tk_PostscriptFontName, /* 152 */
    Tk_PreserveColormap, /* 153 */
    Tk_QueueWindowEvent, /* 154 */
    Tk_RedrawImage, /* 155 */
    Tk_ResizeWindow, /* 156 */
    Tk_RestackWindow, /* 157 */
    Tk_RestrictEvents, /* 158 */
    0, /* 159 */
    Tk_SetAppName, /* 160 */
    Tk_SetBackgroundFromBorder, /* 161 */
    Tk_SetClass, /* 162 */
    Tk_SetGrid, /* 163 */
    Tk_SetInternalBorder, /* 164 */
    Tk_SetWindowBackground, /* 165 */
    Tk_SetWindowBackgroundPixmap, /* 166 */
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
    Tk_GetOptionValue, /* 205 */
    Tk_GetJustifyFromObj, /* 206 */
    Tk_GetMMFromObj, /* 207 */
    Tk_GetPixelsFromObj, /* 208 */
    Tk_GetReliefFromObj, /* 209 */
    Tk_GetScrollInfoObj, /* 210 */
    Tk_InitOptions, /* 211 */
    Tk_MainEx, /* 212 */
    Tk_RestoreSavedOptions, /* 213 */
    Tk_SetOptions, /* 214 */
    Tk_InitConsoleChannels, /* 215 */
    Tk_CreateConsoleWindow, /* 216 */
    Tk_CreateSmoothMethod, /* 217 */
    0, /* 218 */
    0, /* 219 */
    Tk_GetDash, /* 220 */
    Tk_CreateOutline, /* 221 */
    Tk_DeleteOutline, /* 222 */
    Tk_ConfigOutlineGC, /* 223 */







|



|







1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
    Tk_GetOptionValue, /* 205 */
    Tk_GetJustifyFromObj, /* 206 */
    Tk_GetMMFromObj, /* 207 */
    Tk_GetPixelsFromObj, /* 208 */
    Tk_GetReliefFromObj, /* 209 */
    Tk_GetScrollInfoObj, /* 210 */
    Tk_InitOptions, /* 211 */
    0, /* 212 */
    Tk_RestoreSavedOptions, /* 213 */
    Tk_SetOptions, /* 214 */
    Tk_InitConsoleChannels, /* 215 */
    0, /* 216 */
    Tk_CreateSmoothMethod, /* 217 */
    0, /* 218 */
    0, /* 219 */
    Tk_GetDash, /* 220 */
    Tk_CreateOutline, /* 221 */
    Tk_DeleteOutline, /* 222 */
    Tk_ConfigOutlineGC, /* 223 */
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
    Tk_CreateClientMessageHandler, /* 239 */
    Tk_DeleteClientMessageHandler, /* 240 */
    Tk_CreateAnonymousWindow, /* 241 */
    Tk_SetClassProcs, /* 242 */
    Tk_SetInternalBorderEx, /* 243 */
    Tk_SetMinimumRequestSize, /* 244 */
    Tk_SetCaretPos, /* 245 */
    Tk_PhotoPutBlock_Panic, /* 246 */
    Tk_PhotoPutZoomedBlock_Panic, /* 247 */
    Tk_CollapseMotionEvents, /* 248 */
    Tk_RegisterStyleEngine, /* 249 */
    Tk_GetStyleEngine, /* 250 */
    Tk_RegisterStyledElement, /* 251 */
    Tk_GetElementId, /* 252 */
    Tk_CreateStyle, /* 253 */
    Tk_GetStyle, /* 254 */
    Tk_FreeStyle, /* 255 */
    Tk_NameOfStyle, /* 256 */
    Tk_AllocStyleFromObj, /* 257 */
    Tk_GetStyleFromObj, /* 258 */
    Tk_FreeStyleFromObj, /* 259 */
    Tk_GetStyledElement, /* 260 */
    Tk_GetElementSize, /* 261 */
    Tk_GetElementBox, /* 262 */
    Tk_GetElementBorderWidth, /* 263 */
    Tk_DrawElement, /* 264 */
    Tk_PhotoExpand, /* 265 */
    Tk_PhotoPutBlock, /* 266 */
    Tk_PhotoPutZoomedBlock, /* 267 */
    Tk_PhotoSetSize, /* 268 */
    Tk_GetUserInactiveTime, /* 269 */
    Tk_ResetUserInactiveTime, /* 270 */
    Tk_Interp, /* 271 */
    Tk_CreateOldImageType, /* 272 */
    Tk_CreateOldPhotoImageFormat, /* 273 */
    Tk_AlwaysShowSelection, /* 274 */
    Tk_GetButtonMask, /* 275 */
    Tk_GetDoublePixelsFromObj, /* 276 */
    Tk_NewWindowObj, /* 277 */
    Tk_SendVirtualEvent, /* 278 */
    Tk_FontGetDescription, /* 279 */











};

/* !END!: Do not edit above this line. */


#ifdef __CYGWIN__
void *Tk_GetHINSTANCE(void)







|
|










|
|












|
|






>
>
>
>
>
>
>
>
>
>
>







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
    Tk_CreateClientMessageHandler, /* 239 */
    Tk_DeleteClientMessageHandler, /* 240 */
    Tk_CreateAnonymousWindow, /* 241 */
    Tk_SetClassProcs, /* 242 */
    Tk_SetInternalBorderEx, /* 243 */
    Tk_SetMinimumRequestSize, /* 244 */
    Tk_SetCaretPos, /* 245 */
    0, /* 246 */
    0, /* 247 */
    Tk_CollapseMotionEvents, /* 248 */
    Tk_RegisterStyleEngine, /* 249 */
    Tk_GetStyleEngine, /* 250 */
    Tk_RegisterStyledElement, /* 251 */
    Tk_GetElementId, /* 252 */
    Tk_CreateStyle, /* 253 */
    Tk_GetStyle, /* 254 */
    Tk_FreeStyle, /* 255 */
    Tk_NameOfStyle, /* 256 */
    Tk_AllocStyleFromObj, /* 257 */
    0, /* 258 */
    0, /* 259 */
    Tk_GetStyledElement, /* 260 */
    Tk_GetElementSize, /* 261 */
    Tk_GetElementBox, /* 262 */
    Tk_GetElementBorderWidth, /* 263 */
    Tk_DrawElement, /* 264 */
    Tk_PhotoExpand, /* 265 */
    Tk_PhotoPutBlock, /* 266 */
    Tk_PhotoPutZoomedBlock, /* 267 */
    Tk_PhotoSetSize, /* 268 */
    Tk_GetUserInactiveTime, /* 269 */
    Tk_ResetUserInactiveTime, /* 270 */
    Tk_Interp, /* 271 */
    0, /* 272 */
    0, /* 273 */
    Tk_AlwaysShowSelection, /* 274 */
    Tk_GetButtonMask, /* 275 */
    Tk_GetDoublePixelsFromObj, /* 276 */
    Tk_NewWindowObj, /* 277 */
    Tk_SendVirtualEvent, /* 278 */
    Tk_FontGetDescription, /* 279 */
    Tk_CreatePhotoImageFormatVersion3, /* 280 */
    Tk_DrawHighlightBorder, /* 281 */
    Tk_SetMainMenubar, /* 282 */
    Tk_SetWindowMenubar, /* 283 */
    Tk_ClipDrawableToRect, /* 284 */
    Tk_GetSystemDefault, /* 285 */
    Tk_UseWindow, /* 286 */
    Tk_MakeContainer, /* 287 */
    Tk_GetOtherWindow, /* 288 */
    Tk_Get3DBorderColors, /* 289 */
    Tk_MakeWindow, /* 290 */
};

/* !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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|
|







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 © 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
#undef Tk_InitStubs
MODULE_SCOPE const char *
Tk_InitStubs(
    Tcl_Interp *interp,
    const char *version,
    int exact)
{
    const char *packageName = "Tk";
    const char *errMsg = NULL;
    void *clientData = NULL;
    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
	    packageName, version, 0, &clientData);
    const TkStubs *stubsPtr = (const TkStubs *)clientData;

    if (actualVersion == NULL) {




	return NULL;

    }

    if (exact) {
	const char *p = version;
	int count = 0;

	while (*p) {







|




<


>
>
>
>
|
>







71
72
73
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 *errMsg = NULL;
    void *clientData = NULL;
    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
	    packageName, version, 0, &clientData);


    if (actualVersion == NULL) {
	packageName = "Tk";
	actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
    	    packageName, version, 0, &clientData);
	if (actualVersion == 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
	    actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName,
		    version, 1, NULL);
	    if (actualVersion == NULL) {
		return NULL;
	    }
	}
    }
    if (stubsPtr == 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;
	} else {
	    tkPlatStubsPtr = NULL;
	    tkIntStubsPtr = NULL;
	    tkIntPlatStubsPtr = NULL;
	    tkIntXlibStubsPtr = NULL;
	}
	return actualVersion;







|


|
|
|
|
|
|







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 (clientData == NULL) {
	errMsg = "missing stub table pointer";
    } else {
	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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|
|







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 © 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"

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158


159
160
161
162
163
164
165
} Element;

/*
 * Thread-local data.
 */

typedef struct {
    int nbInit;			/* Number of calls to the init proc. */
    Tcl_HashTable engineTable;	/* Map a name to a style engine. Keys are
				 * strings, values are Tk_StyleEngine
				 * pointers. */
    StyleEngine *defaultEnginePtr;
				/* Default, core-defined style engine. Global
				 * fallback for all engines. */
    Tcl_HashTable styleTable;	/* Map a name to a style. Keys are strings,
				 * values are Tk_Style pointers.*/
    int nbElements;		/* Size of the below tables. */
    Tcl_HashTable elementTable;	/* Map a name to an element Id. Keys are
				 * strings, values are integer element IDs. */
    Element *elements;		/* Array of Elements. */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined later in this file:
 */

static int		CreateElement(const char *name, int create);
static void		DupStyleObjProc(Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr);
static void		FreeElement(Element *elementPtr);
static void		FreeStyledElement(StyledElement *elementPtr);
static void		FreeStyleEngine(StyleEngine *enginePtr);
static void		FreeStyleObjProc(Tcl_Obj *objPtr);
static void		FreeWidgetSpec(StyledWidgetSpec *widgetSpecPtr);
static StyledElement *	GetStyledElement(StyleEngine *enginePtr,
			    int elementId);
static StyledWidgetSpec*GetWidgetSpec(StyledElement *elementPtr,
			    Tk_OptionTable optionTable);
static void		InitElement(Element *elementPtr, const char *name,
			    int id, int genericId, int created);
static void		InitStyle(Style *stylePtr, const char *name,
			    StyleEngine *enginePtr, ClientData clientData);
static void		InitStyledElement(StyledElement *elementPtr);
static void		InitStyleEngine(StyleEngine *enginePtr,
			    const char *name, StyleEngine *parentPtr);
static void		InitWidgetSpec(StyledWidgetSpec *widgetSpecPtr,
			    StyledElement *elementPtr,
			    Tk_OptionTable optionTable);
static int		SetStyleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

/*
 * The following structure defines the implementation of the "style" Tcl
 * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
 * style object points to the Style structure for the stylefont, or NULL.
 */

static const Tcl_ObjType styleObjType = {
    "style",			/* name */
    FreeStyleObjProc,		/* freeIntRepProc */
    DupStyleObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *---------------------------------------------------------------------------
 *
 * TkStylePkgInit --
 *







|








|




















|




















|
|



|
>
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
} Element;

/*
 * Thread-local data.
 */

typedef struct {
    size_t nbInit;			/* Number of calls to the init proc. */
    Tcl_HashTable engineTable;	/* Map a name to a style engine. Keys are
				 * strings, values are Tk_StyleEngine
				 * pointers. */
    StyleEngine *defaultEnginePtr;
				/* Default, core-defined style engine. Global
				 * fallback for all engines. */
    Tcl_HashTable styleTable;	/* Map a name to a style. Keys are strings,
				 * values are Tk_Style pointers.*/
    Tcl_Size nbElements;		/* Size of the below tables. */
    Tcl_HashTable elementTable;	/* Map a name to an element Id. Keys are
				 * strings, values are integer element IDs. */
    Element *elements;		/* Array of Elements. */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined later in this file:
 */

static int		CreateElement(const char *name, int create);
static void		DupStyleObjProc(Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr);
static void		FreeElement(Element *elementPtr);
static void		FreeStyledElement(StyledElement *elementPtr);
static void		FreeStyleEngine(StyleEngine *enginePtr);
static void		FreeStyleObjProc(Tcl_Obj *objPtr);
static void		FreeWidgetSpec(StyledWidgetSpec *widgetSpecPtr);
static StyledElement *	GetStyledElement(StyleEngine *enginePtr,
			    Tcl_Size elementId);
static StyledWidgetSpec*GetWidgetSpec(StyledElement *elementPtr,
			    Tk_OptionTable optionTable);
static void		InitElement(Element *elementPtr, const char *name,
			    int id, int genericId, int created);
static void		InitStyle(Style *stylePtr, const char *name,
			    StyleEngine *enginePtr, ClientData clientData);
static void		InitStyledElement(StyledElement *elementPtr);
static void		InitStyleEngine(StyleEngine *enginePtr,
			    const char *name, StyleEngine *parentPtr);
static void		InitWidgetSpec(StyledWidgetSpec *widgetSpecPtr,
			    StyledElement *elementPtr,
			    Tk_OptionTable optionTable);
static int		SetStyleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

/*
 * The following structure defines the implementation of the "style" Tcl
 * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
 * style object points to the Style structure for the stylefont, or NULL.
 */

static const TkObjType styleObjType = {
    {"style",			/* name */
    FreeStyleObjProc,		/* freeIntRepProc */
    DupStyleObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *---------------------------------------------------------------------------
 *
 * TkStylePkgInit --
 *
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    TCL_UNUSED(TkMainInfo *))	/* The application being deleted. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr;
    StyleEngine *enginePtr;
    int i;

    tsdPtr->nbInit--;
    if (tsdPtr->nbInit != 0) {
	return;
    }

    /*







|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    TCL_UNUSED(TkMainInfo *))	/* The application being deleted. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr;
    StyleEngine *enginePtr;
    Tcl_Size i;

    tsdPtr->nbInit--;
    if (tsdPtr->nbInit != 0) {
	return;
    }

    /*
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
				 * means the default system engine. Usually
				 * points to the hash key. */
    StyleEngine *parentPtr)	/* The engine's parent. NULL means the default
				 * system engine. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    int elementId;

    if (name == NULL || *name == '\0') {
	/*
	 * This is the default style engine.
	 */

	enginePtr->parentPtr = NULL;







|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
				 * means the default system engine. Usually
				 * points to the hash key. */
    StyleEngine *parentPtr)	/* The engine's parent. NULL means the default
				 * system engine. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Size elementId;

    if (name == NULL || *name == '\0') {
	/*
	 * This is the default style engine.
	 */

	enginePtr->parentPtr = NULL;
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

static void
FreeStyleEngine(
    StyleEngine *enginePtr)	/* The style engine to free. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    int elementId;

    /*
     * Free allocated elements.
     */

    for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) {
	FreeStyledElement(enginePtr->elements+elementId);







|







419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

static void
FreeStyleEngine(
    StyleEngine *enginePtr)	/* The style engine to free. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Size elementId;

    /*
     * Free allocated elements.
     */

    for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) {
	FreeStyledElement(enginePtr->elements+elementId);
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
 *---------------------------------------------------------------------------
 */

static StyledElement *
GetStyledElement(
    StyleEngine *enginePtr,	/* Style engine providing the implementation.
				 * NULL means the default system engine. */
    int elementId)		/* Unique element ID */
{
    StyledElement *elementPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    StyleEngine *enginePtr2;

    if (enginePtr == NULL) {
	enginePtr = tsdPtr->defaultEnginePtr;
    }

    while (elementId >= 0 && elementId < tsdPtr->nbElements) {
	/*
	 * Look for an implemented element through the engine chain.
	 */

	enginePtr2 = enginePtr;
	do {
	    elementPtr = enginePtr2->elements+elementId;







|










|







839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
 *---------------------------------------------------------------------------
 */

static StyledElement *
GetStyledElement(
    StyleEngine *enginePtr,	/* Style engine providing the implementation.
				 * NULL means the default system engine. */
    Tcl_Size elementId)		/* Unique element ID */
{
    StyledElement *elementPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    StyleEngine *enginePtr2;

    if (enginePtr == NULL) {
	enginePtr = tsdPtr->defaultEnginePtr;
    }

    while (elementId != TCL_INDEX_NONE && elementId < tsdPtr->nbElements) {
	/*
	 * Look for an implemented element through the engine chain.
	 */

	enginePtr2 = enginePtr;
	do {
	    elementPtr = enginePtr2->elements+elementId;
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
 *
 *---------------------------------------------------------------------------
 */

Tk_StyledElement
Tk_GetStyledElement(
    Tk_Style style,		/* The widget style. */
    int elementId,		/* Unique element ID. */
    Tk_OptionTable optionTable)	/* Option table for the widget. */
{
    Style *stylePtr = (Style *) style;
    StyledElement *elementPtr;

    /*
     * Get an element implementation and call corresponding hook.







|







1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
 *
 *---------------------------------------------------------------------------
 */

Tk_StyledElement
Tk_GetStyledElement(
    Tk_Style style,		/* The widget style. */
    Tcl_Size elementId,		/* Unique element ID. */
    Tk_OptionTable optionTable)	/* Option table for the widget. */
{
    Style *stylePtr = (Style *) style;
    StyledElement *elementPtr;

    /*
     * Get an element implementation and call corresponding hook.
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412

Tk_Style
Tk_AllocStyleFromObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    Tcl_Obj *objPtr)		/* Object containing name of the style to
				 * retrieve. */
{
    if (objPtr->typePtr != &styleObjType) {
	if (SetStyleFromAny(interp, objPtr) != TCL_OK) {
	    return NULL;
	}
    }
    return (Tk_Style)objPtr->internalRep.twoPtrValue.ptr1;
}








|







1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414

Tk_Style
Tk_AllocStyleFromObj(
    Tcl_Interp *interp,		/* Interp for error return. */
    Tcl_Obj *objPtr)		/* Object containing name of the style to
				 * retrieve. */
{
    if (objPtr->typePtr != &styleObjType.objType) {
	if (SetStyleFromAny(interp, objPtr) != TCL_OK) {
	    return NULL;
	}
    }
    return (Tk_Style)objPtr->internalRep.twoPtrValue.ptr1;
}

1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
	typePtr->freeIntRepProc(objPtr);
    }

    style = Tk_GetStyle(interp, name);
    if (style == NULL) {
    	return TCL_ERROR;
    }
    objPtr->typePtr = &styleObjType;
    objPtr->internalRep.twoPtrValue.ptr1 = style;

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------







|







1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
	typePtr->freeIntRepProc(objPtr);
    }

    style = Tk_GetStyle(interp, name);
    if (style == NULL) {
    	return TCL_ERROR;
    }
    objPtr->typePtr = &styleObjType.objType;
    objPtr->internalRep.twoPtrValue.ptr1 = style;

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------

Changes to generic/tkTest.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * 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.
 *
 * 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








|
|
|







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 © 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
52
53
54
55
56
57
58




59
60
61
62
63
64
65
extern "C" {
#endif
EXTERN int		Tktest_Init(Tcl_Interp *interp);
#ifdef __cplusplus
}
#endif





/*
 * The following data structure represents the model for a test image:
 */

typedef struct TImageModel {
    Tk_ImageModel model;	/* Tk's token for image model. */
    Tcl_Interp *interp;		/* Interpreter for application. */







>
>
>
>







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
extern "C" {
#endif
EXTERN int		Tktest_Init(Tcl_Interp *interp);
#ifdef __cplusplus
}
#endif

#if TCL_MAJOR_VERSION < 9
#   undef Tcl_CreateObjCommand2
#   define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
#endif
/*
 * The following data structure represents the model for a test image:
 */

typedef struct TImageModel {
    Tk_ImageModel model;	/* Tk's token for image model. */
    Tcl_Interp *interp;		/* Interpreter for application. */
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static ClientData	ImageGet(Tk_Window tkwin, ClientData clientData);
static void		ImageDisplay(ClientData clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width,
			    int height, int drawableX,
			    int drawableY);
static void		ImageFree(ClientData clientData, Display *display);
static void		ImageDelete(ClientData clientData);

static Tk_ImageType imageType = {
    "test",			/* name */
    ImageCreate,		/* createProc */
    ImageGet,			/* getProc */
    ImageDisplay,		/* displayProc */
    ImageFree,			/* freeProc */







|

|
|
|




|
|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    const char *name, Tcl_Size objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    void **clientDataPtr);
static void	*ImageGet(Tk_Window tkwin, void *clientData);
static void		ImageDisplay(void *clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width,
			    int height, int drawableX,
			    int drawableY);
static void		ImageFree(void *clientData, Display *display);
static void		ImageDelete(void *clientData);

static Tk_ImageType imageType = {
    "test",			/* name */
    ImageCreate,		/* createProc */
    ImageGet,			/* getProc */
    ImageDisplay,		/* displayProc */
    ImageFree,			/* freeProc */
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
				 * this widget. */
} TrivialCommandHeader;

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ImageObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestbitmapObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestborderObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestcolorObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestcursorObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestdeleteappsObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestfontObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestmakeexistObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestmenubarObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#endif
#if defined(_WIN32)
static int		TestmetricsObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#endif
static int		TestobjconfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static Tk_CustomOptionSetProc CustomOptionSet;
static Tk_CustomOptionGetProc CustomOptionGet;
static Tk_CustomOptionRestoreProc CustomOptionRestore;
static Tk_CustomOptionFreeProc CustomOptionFree;
static int		TestpropObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static int		TestprintfObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestwrapperObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#endif
static void		TrivialCmdDeletedProc(ClientData clientData);
static int		TrivialConfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		TrivialEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int              TestPhotoStringMatchCmd(ClientData dummy,
                            Tcl_Interp *interp, int objc,
                            Tcl_Obj * const objv[]);

/*
 *----------------------------------------------------------------------
 *
 * Tktest_Init --
 *
 *	This function performs initialization for the Tk test suite extensions.







|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|
<
<

|
<
<


|
<
<

|
<
<




|
<
<
|
<
<

|
<
<

|
|
<
<
|

|
<
<







151
152
153
154
155
156
157
158


159


160


161


162


163


164


165


166
167


168
169
170


171
172


173
174
175
176
177


178


179
180


181
182
183


184
185
186


187
188
189
190
191
192
193
				 * this widget. */
} TrivialCommandHeader;

/*
 * Forward declarations for functions defined later in this file:
 */

static Tcl_ObjCmdProc ImageObjCmd;


static Tcl_ObjCmdProc TestbitmapObjCmd;


static Tcl_ObjCmdProc TestborderObjCmd;


static Tcl_ObjCmdProc TestcolorObjCmd;


static Tcl_ObjCmdProc TestcursorObjCmd;


static Tcl_ObjCmdProc TestdeleteappsObjCmd;


static Tcl_ObjCmdProc TestfontObjCmd;


static Tcl_ObjCmdProc TestmakeexistObjCmd;


#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static Tcl_ObjCmdProc TestmenubarObjCmd;


#endif
#if defined(_WIN32)
static Tcl_ObjCmdProc TestmetricsObjCmd;


#endif
static Tcl_ObjCmdProc TestobjconfigObjCmd;


static Tk_CustomOptionSetProc CustomOptionSet;
static Tk_CustomOptionGetProc CustomOptionGet;
static Tk_CustomOptionRestoreProc CustomOptionRestore;
static Tk_CustomOptionFreeProc CustomOptionFree;
static Tcl_ObjCmdProc TestpropObjCmd;


static Tcl_ObjCmdProc TestprintfObjCmd;


#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static Tcl_ObjCmdProc TestwrapperObjCmd;


#endif
static void		TrivialCmdDeletedProc(void *clientData);
static Tcl_ObjCmdProc TrivialConfigObjCmd;


static void		TrivialEventProc(void *clientData,
			    XEvent *eventPtr);
static Tcl_ObjCmdProc TestPhotoStringMatchCmd;



/*
 *----------------------------------------------------------------------
 *
 * Tktest_Init --
 *
 *	This function performs initialization for the Tk test suite extensions.
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

int
Tktest_Init(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    static int initialized = 0;

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
	return TCL_ERROR;
    }
    if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
	return TCL_ERROR;
    }

    /*
     * Create additional commands for testing Tk.
     */

    if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcolor", TestcolorObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testdeleteapps", TestdeleteappsObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testembed", TkpTestembedCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprintf", TestprintfObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testphotostringmatch",
            TestPhotoStringMatchCmd, (ClientData) Tk_MainWindow(interp),
            NULL);

#if defined(_WIN32)
    Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
    Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#endif /* _WIN32 */

    /*
     * Create test image type.
     */

    if (!initialized) {
	initialized = 1;
	Tk_CreateImageType(&imageType);
    }

    /*
     *	Enable testing of legacy interfaces.
     */

    if (TkOldTestInit(interp) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * And finally add any platform specific test commands.
     */

    return TkplatformtestInit(interp);
}








|










|





|

|

|

|

|
|
|

|

|

|

|

|
|

|




|


|
|
|

|











<
<
<
<
<
<
<
<







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274








275
276
277
278
279
280
281

int
Tktest_Init(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    static int initialized = 0;

    if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
	return TCL_ERROR;
    }
    if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
	return TCL_ERROR;
    }

    /*
     * Create additional commands for testing Tk.
     */

    if (Tcl_PkgProvideEx(interp, "tk::test", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcolor", TestcolorObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testdeleteapps", TestdeleteappsObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand2(interp, "testembed", TkpTestembedCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprintf", TestprintfObjCmd, NULL, NULL);
    Tcl_CreateObjCommand2(interp, "testtext", TkpTesttextCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testphotostringmatch",
            TestPhotoStringMatchCmd, Tk_MainWindow(interp),
            NULL);

#if defined(_WIN32)
    Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
	    Tk_MainWindow(interp), NULL);
#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
    Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand2(interp, "testsend", TkpTestsendCmd,
	    Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
	    Tk_MainWindow(interp), NULL);
#endif /* _WIN32 */

    /*
     * Create test image type.
     */

    if (!initialized) {
	initialized = 1;
	Tk_CreateImageType(&imageType);
    }









    /*
     * And finally add any platform specific test commands.
     */

    return TkplatformtestInit(interp);
}

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestborderObjCmd(
    TCL_UNUSED(ClientData),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "border");
	return TCL_ERROR;







|







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestborderObjCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "border");
	return TCL_ERROR;
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestobjconfigObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const options[] = {
	"alltypes", "chain1", "chain2", "chain3", "configerror", "delete", "info",
	"internal", "new", "notenoughparams", "twowindows", NULL







|







463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestobjconfigObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const options[] = {
	"alltypes", "chain1", "chain2", "chain3", "configerror", "delete", "info",
	"internal", "new", "notenoughparams", "twowindows", NULL
569
570
571
572
573
574
575

576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592



593
594
595
596
597
598
599
600
601
602
603
604
605
606




607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
	typedef struct {
	    TrivialCommandHeader header;
	    Tcl_Obj *booleanPtr;
	    Tcl_Obj *integerPtr;
	    Tcl_Obj *doublePtr;
	    Tcl_Obj *stringPtr;
	    Tcl_Obj *stringTablePtr;

	    Tcl_Obj *colorPtr;
	    Tcl_Obj *fontPtr;
	    Tcl_Obj *bitmapPtr;
	    Tcl_Obj *borderPtr;
	    Tcl_Obj *reliefPtr;
	    Tcl_Obj *cursorPtr;
	    Tcl_Obj *activeCursorPtr;
	    Tcl_Obj *justifyPtr;
	    Tcl_Obj *anchorPtr;
	    Tcl_Obj *pixelPtr;
	    Tcl_Obj *mmPtr;
	    Tcl_Obj *customPtr;
	} TypesRecord;
	TypesRecord *recordPtr;
	static const char *const stringTable[] = {
	    "one", "two", "three", "four", NULL
	};



	static const Tk_OptionSpec typesSpecs[] = {
	    {TK_OPTION_BOOLEAN, "-boolean", "boolean", "Boolean", "1",
		offsetof(TypesRecord, booleanPtr), TCL_INDEX_NONE, 0, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "7",
		offsetof(TypesRecord, integerPtr), TCL_INDEX_NONE, 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		offsetof(TypesRecord, doublePtr), TCL_INDEX_NONE, 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String",
		"foo", offsetof(TypesRecord, stringPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x8},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable", "StringTable", "stringTable",
		"one", offsetof(TypesRecord, stringTablePtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, stringTable, 0x10},




	    {TK_OPTION_COLOR, "-color", "color", "Color",
		"red", offsetof(TypesRecord, colorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, "black", 0x20},
	    {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12",
		offsetof(TypesRecord, fontPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		offsetof(TypesRecord, bitmapPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border",
		"blue", offsetof(TypesRecord, borderPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised",
		offsetof(TypesRecord, reliefPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		offsetof(TypesRecord, cursorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x400},
	    {TK_OPTION_JUSTIFY, "-justify", NULL, NULL, "left",
		offsetof(TypesRecord, justifyPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", NULL,
		offsetof(TypesRecord, anchorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel",
		"1", offsetof(TypesRecord, pixelPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL,
		"", offsetof(TypesRecord, customPtr), TCL_INDEX_NONE,







>

















>
>
>

|
|











>
>
>
>












|








|







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
	typedef struct {
	    TrivialCommandHeader header;
	    Tcl_Obj *booleanPtr;
	    Tcl_Obj *integerPtr;
	    Tcl_Obj *doublePtr;
	    Tcl_Obj *stringPtr;
	    Tcl_Obj *stringTablePtr;
	    Tcl_Obj *stringTablePtr2;
	    Tcl_Obj *colorPtr;
	    Tcl_Obj *fontPtr;
	    Tcl_Obj *bitmapPtr;
	    Tcl_Obj *borderPtr;
	    Tcl_Obj *reliefPtr;
	    Tcl_Obj *cursorPtr;
	    Tcl_Obj *activeCursorPtr;
	    Tcl_Obj *justifyPtr;
	    Tcl_Obj *anchorPtr;
	    Tcl_Obj *pixelPtr;
	    Tcl_Obj *mmPtr;
	    Tcl_Obj *customPtr;
	} TypesRecord;
	TypesRecord *recordPtr;
	static const char *const stringTable[] = {
	    "one", "two", "three", "four", NULL
	};
	static const char *const stringTable2[] = {
	    "one", "two", NULL
	};
	static const Tk_OptionSpec typesSpecs[] = {
	    {TK_OPTION_BOOLEAN, "-boolean", "boolean", "Boolean", NULL,
		offsetof(TypesRecord, booleanPtr), TCL_INDEX_NONE, TK_CONFIG_NULL_OK, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "7",
		offsetof(TypesRecord, integerPtr), TCL_INDEX_NONE, 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		offsetof(TypesRecord, doublePtr), TCL_INDEX_NONE, 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String",
		"foo", offsetof(TypesRecord, stringPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x8},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable", "StringTable", "stringTable",
		"one", offsetof(TypesRecord, stringTablePtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, stringTable, 0x10},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable2", "StringTable2", "stringTable2",
		"two", offsetof(TypesRecord, stringTablePtr2), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, stringTable2, 0x10},
	    {TK_OPTION_COLOR, "-color", "color", "Color",
		"red", offsetof(TypesRecord, colorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, "black", 0x20},
	    {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12",
		offsetof(TypesRecord, fontPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		offsetof(TypesRecord, bitmapPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border",
		"blue", offsetof(TypesRecord, borderPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
		offsetof(TypesRecord, reliefPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		offsetof(TypesRecord, cursorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x400},
	    {TK_OPTION_JUSTIFY, "-justify", NULL, NULL, "left",
		offsetof(TypesRecord, justifyPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "center",
		offsetof(TypesRecord, anchorPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel",
		"1", offsetof(TypesRecord, pixelPtr), TCL_INDEX_NONE,
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL,
		"", offsetof(TypesRecord, customPtr), TCL_INDEX_NONE,
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
	recordPtr->reliefPtr = NULL;
	recordPtr->cursorPtr = NULL;
	recordPtr->justifyPtr = NULL;
	recordPtr->anchorPtr = NULL;
	recordPtr->pixelPtr = NULL;
	recordPtr->mmPtr = NULL;
	recordPtr->stringTablePtr = NULL;

	recordPtr->customPtr = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable,
		tkwin);
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    (ClientData) recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, (ClientData) recordPtr);
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_DestroyWindow(tkwin);
	    }
	} else {
	    Tk_DestroyWindow(tkwin);







>






|

|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
	recordPtr->reliefPtr = NULL;
	recordPtr->cursorPtr = NULL;
	recordPtr->justifyPtr = NULL;
	recordPtr->anchorPtr = NULL;
	recordPtr->pixelPtr = NULL;
	recordPtr->mmPtr = NULL;
	recordPtr->stringTablePtr = NULL;
	recordPtr->stringTablePtr2 = NULL;
	recordPtr->customPtr = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable,
		tkwin);
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, recordPtr);
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_DestroyWindow(tkwin);
	    }
	} else {
	    Tk_DestroyWindow(tkwin);
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
	    if (result != TCL_OK) {
		Tk_FreeConfigOptions(recordPtr, optionTable, tkwin);
	    }
	}
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    (ClientData) recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, (ClientData) recordPtr);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CHAIN2:
    case CHAIN3: {
	ExtensionWidgetRecord *recordPtr;
	static const Tk_OptionSpec extensionSpecs[] = {
	    {TK_OPTION_STRING, "-three", "three", "Three", "three",
		offsetof(ExtensionWidgetRecord, extension3ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-four", "four", "Four", "four",
		offsetof(ExtensionWidgetRecord, extension4ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-two", "two", "Two", "two and a half",
		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING,
		"-oneAgain", "oneAgain", "OneAgain", "one again",
		offsetof(ExtensionWidgetRecord, extension5ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
		(ClientData) baseSpecs, 0}
	};
	Tk_OptionTable optionTable;

	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
		Tcl_GetString(objv[2]), NULL);
	if (tkwin == NULL) {
	    return TCL_ERROR;







|

|



















|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	    if (result != TCL_OK) {
		Tk_FreeConfigOptions(recordPtr, optionTable, tkwin);
	    }
	}
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, recordPtr);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CHAIN2:
    case CHAIN3: {
	ExtensionWidgetRecord *recordPtr;
	static const Tk_OptionSpec extensionSpecs[] = {
	    {TK_OPTION_STRING, "-three", "three", "Three", "three",
		offsetof(ExtensionWidgetRecord, extension3ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-four", "four", "Four", "four",
		offsetof(ExtensionWidgetRecord, extension4ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING, "-two", "two", "Two", "two and a half",
		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_STRING,
		"-oneAgain", "oneAgain", "OneAgain", "one again",
		offsetof(ExtensionWidgetRecord, extension5ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
		baseSpecs, 0}
	};
	Tk_OptionTable optionTable;

	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
		Tcl_GetString(objv[2]), NULL);
	if (tkwin == NULL) {
	    return TCL_ERROR;
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
	recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL;
	recordPtr->extension5ObjPtr = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_FreeConfigOptions((char *) recordPtr, optionTable, tkwin);
	    }
	}
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    (ClientData) recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, (ClientData) recordPtr);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CONFIG_ERROR: {
	typedef struct {
	    Tcl_Obj *intPtr;
	} ErrorWidgetRecord;
	ErrorWidgetRecord widgetRecord;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-int", "integer", "Integer", "bogus",
		offsetof(ErrorWidgetRecord, intPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;

	widgetRecord.intPtr = NULL;
	optionTable = Tk_CreateOptionTable(interp, errorSpecs);
	tables[index] = optionTable;







|





|

|












|







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
	recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL;
	recordPtr->extension5ObjPtr = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_FreeConfigOptions(recordPtr, optionTable, tkwin);
	    }
	}
	if (result == TCL_OK) {
	    recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
		    Tcl_GetString(objv[2]), TrivialConfigObjCmd,
		    recordPtr, TrivialCmdDeletedProc);
	    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
		    TrivialEventProc, recordPtr);
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case CONFIG_ERROR: {
	typedef struct {
	    Tcl_Obj *intPtr;
	} ErrorWidgetRecord;
	ErrorWidgetRecord widgetRecord;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-int", "integer", "Integer", "bogus",
		offsetof(ErrorWidgetRecord, intPtr), 0, TK_OPTION_NULL_OK, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tk_OptionTable optionTable;

	widgetRecord.intPtr = NULL;
	optionTable = Tk_CreateOptionTable(interp, errorSpecs);
	tables[index] = optionTable;
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
	 * This command is similar to the "alltypes" command except that it
	 * stores all the configuration options as internal forms instead of
	 * objects.
	 */

	typedef struct {
	    TrivialCommandHeader header;
	    int boolean;
	    int integer;
	    double doubleValue;
	    char *string;
	    int index;
	    XColor *colorPtr;
	    Tk_Font tkfont;
	    Pixmap bitmap;







|







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
	 * This command is similar to the "alltypes" command except that it
	 * stores all the configuration options as internal forms instead of
	 * objects.
	 */

	typedef struct {
	    TrivialCommandHeader header;
	    int boolValue;
	    int integer;
	    double doubleValue;
	    char *string;
	    int index;
	    XColor *colorPtr;
	    Tk_Font tkfont;
	    Pixmap bitmap;
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
	} InternalRecord;
	InternalRecord *recordPtr;
	static const char *const internalStringTable[] = {
	    "one", "two", "three", "four", NULL
	};
	static const Tk_OptionSpec internalSpecs[] = {
	    {TK_OPTION_BOOLEAN, "-boolean", "boolean", "Boolean", "1",
		TCL_INDEX_NONE, offsetof(InternalRecord, boolean), 0, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "148962237",
		TCL_INDEX_NONE, offsetof(InternalRecord, integer), 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		TCL_INDEX_NONE, offsetof(InternalRecord, doubleValue), 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String", "foo",
		TCL_INDEX_NONE, offsetof(InternalRecord, string),
		TK_CONFIG_NULL_OK, 0, 0x8},







|







833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
	} InternalRecord;
	InternalRecord *recordPtr;
	static const char *const internalStringTable[] = {
	    "one", "two", "three", "four", NULL
	};
	static const Tk_OptionSpec internalSpecs[] = {
	    {TK_OPTION_BOOLEAN, "-boolean", "boolean", "Boolean", "1",
		TCL_INDEX_NONE, offsetof(InternalRecord, boolValue), TK_CONFIG_NULL_OK, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "148962237",
		TCL_INDEX_NONE, offsetof(InternalRecord, integer), 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		TCL_INDEX_NONE, offsetof(InternalRecord, doubleValue), 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String", "foo",
		TCL_INDEX_NONE, offsetof(InternalRecord, string),
		TK_CONFIG_NULL_OK, 0, 0x8},
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
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		TCL_INDEX_NONE, offsetof(InternalRecord, bitmap),
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border", "blue",
		TCL_INDEX_NONE, offsetof(InternalRecord, border),
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised",
		TCL_INDEX_NONE, offsetof(InternalRecord, relief),
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		TCL_INDEX_NONE, offsetof(InternalRecord, cursor),
		TK_CONFIG_NULL_OK, 0, 0x400},
	    {TK_OPTION_JUSTIFY, "-justify", NULL, NULL, "left",
		TCL_INDEX_NONE, offsetof(InternalRecord, justify),
		TK_CONFIG_NULL_OK, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, anchor),
		TK_CONFIG_NULL_OK, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel", "1",
		TCL_INDEX_NONE, offsetof(InternalRecord, pixels),
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_WINDOW, "-window", "window", "Window", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, tkwin),
		TK_CONFIG_NULL_OK, 0, 0},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "",







|







|
|

|







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		TCL_INDEX_NONE, offsetof(InternalRecord, bitmap),
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border", "blue",
		TCL_INDEX_NONE, offsetof(InternalRecord, border),
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, relief),
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		TCL_INDEX_NONE, offsetof(InternalRecord, cursor),
		TK_CONFIG_NULL_OK, 0, 0x400},
	    {TK_OPTION_JUSTIFY, "-justify", NULL, NULL, "left",
		TCL_INDEX_NONE, offsetof(InternalRecord, justify),
		TK_CONFIG_NULL_OK|TK_OPTION_ENUM_VAR, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "center",
		TCL_INDEX_NONE, offsetof(InternalRecord, anchor),
		TK_CONFIG_NULL_OK|TK_OPTION_ENUM_VAR, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel", "1",
		TCL_INDEX_NONE, offsetof(InternalRecord, pixels),
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_WINDOW, "-window", "window", "Window", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, tkwin),
		TK_CONFIG_NULL_OK, 0, 0},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "",
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
	}
	Tk_SetClass(tkwin, "Test");

	recordPtr = (InternalRecord *)ckalloc(sizeof(InternalRecord));
	recordPtr->header.interp = interp;
	recordPtr->header.optionTable = optionTable;
	recordPtr->header.tkwin = tkwin;
	recordPtr->boolean = 0;
	recordPtr->integer = 0;
	recordPtr->doubleValue = 0.0;
	recordPtr->string = NULL;
	recordPtr->index = 0;
	recordPtr->colorPtr = NULL;
	recordPtr->tkfont = NULL;
	recordPtr->bitmap = None;
	recordPtr->border = NULL;
	recordPtr->relief = TK_RELIEF_FLAT;
	recordPtr->cursor = NULL;
	recordPtr->justify = TK_JUSTIFY_LEFT;
	recordPtr->anchor = TK_ANCHOR_N;
	recordPtr->pixels = 0;
	recordPtr->mm = 0.0;
	recordPtr->tkwin = NULL;
	recordPtr->custom = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable,
		tkwin);
	if (result == TCL_OK) {







|











|







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
	}
	Tk_SetClass(tkwin, "Test");

	recordPtr = (InternalRecord *)ckalloc(sizeof(InternalRecord));
	recordPtr->header.interp = interp;
	recordPtr->header.optionTable = optionTable;
	recordPtr->header.tkwin = tkwin;
	recordPtr->boolValue = 0;
	recordPtr->integer = 0;
	recordPtr->doubleValue = 0.0;
	recordPtr->string = NULL;
	recordPtr->index = 0;
	recordPtr->colorPtr = NULL;
	recordPtr->tkfont = NULL;
	recordPtr->bitmap = None;
	recordPtr->border = NULL;
	recordPtr->relief = TK_RELIEF_FLAT;
	recordPtr->cursor = NULL;
	recordPtr->justify = TK_JUSTIFY_LEFT;
	recordPtr->anchor = TK_ANCHOR_CENTER;
	recordPtr->pixels = 0;
	recordPtr->mm = 0.0;
	recordPtr->tkwin = NULL;
	recordPtr->custom = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable,
		tkwin);
	if (result == TCL_OK) {
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr,
		    recordPtr->header.optionTable, objc - 3, objv + 3,
		    (Tk_Window) NULL, NULL, NULL);
	    if (result == TCL_OK) {
		recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
			Tcl_GetString(objv[2]), TrivialConfigObjCmd,
			(ClientData) recordPtr, TrivialCmdDeletedProc);
	    } else {
		Tk_FreeConfigOptions(recordPtr,
			recordPtr->header.optionTable, (Tk_Window) NULL);
	    }
	}
	if (result != TCL_OK) {
	    ckfree(recordPtr);







|







984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr,
		    recordPtr->header.optionTable, objc - 3, objv + 3,
		    (Tk_Window) NULL, NULL, NULL);
	    if (result == TCL_OK) {
		recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
			Tcl_GetString(objv[2]), TrivialConfigObjCmd,
			recordPtr, TrivialCmdDeletedProc);
	    } else {
		Tk_FreeConfigOptions(recordPtr,
			recordPtr->header.optionTable, (Tk_Window) NULL);
	    }
	}
	if (result != TCL_OK) {
	    ckfree(recordPtr);
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
	} NotEnoughRecord;
	NotEnoughRecord record;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-foo", "foo", "Foo", "0",
		offsetof(NotEnoughRecord, fooObjPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tcl_Obj *newObjPtr = Tcl_NewStringObj("-foo", -1);
	Tk_OptionTable optionTable;

	record.fooObjPtr = NULL;

	tkwin = Tk_CreateWindowFromPath(interp, mainWin, ".config", NULL);
	Tk_SetClass(tkwin, "Config");
	optionTable = Tk_CreateOptionTable(interp, errorSpecs);







|







1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
	} NotEnoughRecord;
	NotEnoughRecord record;
	static const Tk_OptionSpec errorSpecs[] = {
	    {TK_OPTION_INT, "-foo", "foo", "Foo", "0",
		offsetof(NotEnoughRecord, fooObjPtr), 0, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
	};
	Tcl_Obj *newObjPtr = Tcl_NewStringObj("-foo", TCL_INDEX_NONE);
	Tk_OptionTable optionTable;

	record.fooObjPtr = NULL;

	tkwin = Tk_CreateWindowFromPath(interp, mainWin, ".config", NULL);
	Tk_SetClass(tkwin, "Config");
	optionTable = Tk_CreateOptionTable(interp, errorSpecs);
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TrivialConfigObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int result = TCL_OK;
    static const char *const options[] = {
	"cget", "configure", "csave", NULL







|







1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TrivialConfigObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int result = TCL_OK;
    static const char *const options[] = {
	"cget", "configure", "csave", NULL
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
TrivialCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;
    Tk_Window tkwin = headerPtr->tkwin;

    if (tkwin != NULL) {
	Tk_DestroyWindow(tkwin);
    } else if (headerPtr->optionTable != NULL) {







|







1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
TrivialCmdDeletedProc(
    void *clientData)	/* Pointer to widget record for widget. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;
    Tk_Window tkwin = headerPtr->tkwin;

    if (tkwin != NULL) {
	Tk_DestroyWindow(tkwin);
    } else if (headerPtr->optionTable != NULL) {
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
 *	When the window gets deleted, internal structures get cleaned up.
 *
 *--------------------------------------------------------------
 */

static void
TrivialEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;

    if (eventPtr->type == DestroyNotify) {
	if (headerPtr->tkwin != NULL) {
	    Tk_FreeConfigOptions(clientData,







|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
 *	When the window gets deleted, internal structures get cleaned up.
 *
 *--------------------------------------------------------------
 */

static void
TrivialEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;

    if (eventPtr->type == DestroyNotify) {
	if (headerPtr->tkwin != NULL) {
	    Tk_FreeConfigOptions(clientData,
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestfontObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const options[] = {"counts", "subfonts", NULL};
    enum option {COUNTS, SUBFONTS};
    int index;







|







1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestfontObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const options[] = {"counts", "subfonts", NULL};
    enum option {COUNTS, SUBFONTS};
    int index;
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
 */

static int
ImageCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,			/* Name to use for image. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument strings for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),	/* Pointer to our type record (not used). */
	Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    ClientData *clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    TImageModel *timPtr;
    const char *varName;
    int i;

    varName = "log";
    for (i = 0; i < objc; i += 2) {
	if (strcmp(Tcl_GetString(objv[i]), "-variable") != 0) {
	    Tcl_AppendResult(interp, "bad option name \"",
		    Tcl_GetString(objv[i]), "\"", NULL);
	    return TCL_ERROR;







|





|




|







1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
 */

static int
ImageCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    const char *name,			/* Name to use for image. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument strings for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),	/* Pointer to our type record (not used). */
	Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    void **clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    TImageModel *timPtr;
    const char *varName;
    Tcl_Size i;

    varName = "log";
    for (i = 0; i < objc; i += 2) {
	if (strcmp(Tcl_GetString(objv[i]), "-variable") != 0) {
	    Tcl_AppendResult(interp, "bad option name \"",
		    Tcl_GetString(objv[i]), "\"", NULL);
	    return TCL_ERROR;
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

static int
ImageObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;








|







1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

static int
ImageObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    int x, y, width, height;

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
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static ClientData
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;







|



|






|







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
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void *
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    void *clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    snprintf(buffer, sizeof(buffer), "%s get", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance));
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
 *	redraw area.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDisplay(
    ClientData clientData,	/* Pointer to TImageInstance for image. */
    Display *display,		/* Display to use for drawing. */
    Drawable drawable,		/* Where to redraw image. */
    int imageX, int imageY,	/* Origin of area to redraw, relative to
				 * origin of image. */
    int width, int height,	/* Dimensions of area to redraw. */
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to







|







1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
 *	redraw area.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDisplay(
    void *clientData,	/* Pointer to TImageInstance for image. */
    Display *display,		/* Display to use for drawing. */
    Drawable drawable,		/* Where to redraw image. */
    int imageX, int imageY,	/* Origin of area to redraw, relative to
				 * origin of image. */
    int width, int height,	/* Dimensions of area to redraw. */
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
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
	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;
    }







|














|







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
	if (instPtr->displayFailed == False) {

	    /*
	     * Drawing is possible on the first call to DisplayImage.
	     * Log the message.
	     */

	    snprintf(instPtr->buffer, sizeof(instPtr->buffer), "%s display %d %d %d %d",
	    instPtr->modelPtr->imageName, imageX, imageY, width, height);
	}
	Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName,
		    NULL, instPtr->buffer,
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
	instPtr->displayFailed = False;
    } else {

	/*
         * Drawing is not possible on the first call to DisplayImage.
	 * Save the message, but do not log it until the actual display.
	 */

	if (instPtr->displayFailed == False) {
	    snprintf(instPtr->buffer, sizeof(instPtr->buffer), "%s display %d %d %d %d",
		    instPtr->modelPtr->imageName, imageX, imageY, width, height);
	}
	instPtr->displayFailed = True;
    }
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
 *	Information related to the instance is freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImageFree(
    ClientData clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200];

    sprintf(buffer, "%s free", instPtr->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);
}








|





|







1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
 *	Information related to the instance is freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImageFree(
    void *clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    char buffer[200];

    snprintf(buffer, sizeof(buffer), "%s free", instPtr->modelPtr->imageName);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    Tk_FreeColor(instPtr->fg);
    Tk_FreeGC(display, instPtr->gc);
    ckfree(instPtr);
}

1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
    ckfree(timPtr->imageName);
    ckfree(timPtr->varName);
    ckfree(timPtr);







|






|







1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
 *	Information about the image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImageDelete(
    void *clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    char buffer[100];

    snprintf(buffer, sizeof(buffer), "%s delete", timPtr->imageName);
    Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);

    Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
    ckfree(timPtr->imageName);
    ckfree(timPtr->varName);
    ckfree(timPtr);
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

static int
TestmakeexistObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window mainWin = (Tk_Window)clientData;
    int i;
    Tk_Window tkwin;







|







1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

static int
TestmakeexistObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window mainWin = (Tk_Window)clientData;
    int i;
    Tk_Window tkwin;
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
 *
 *----------------------------------------------------------------------
 */

#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int
TestmenubarObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
#ifdef __UNIX__
    Tk_Window mainWin = (Tk_Window)clientData;
    Tk_Window tkwin, menubar;







|







1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
 *
 *----------------------------------------------------------------------
 */

#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int
TestmenubarObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
#ifdef __UNIX__
    Tk_Window mainWin = (Tk_Window)clientData;
    Tk_Window tkwin, menubar;
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
    } else  if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {
	val = GetSystemMetrics(SM_CXHSCROLL);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be cxhscroll or cyvscroll", NULL);
	return TCL_ERROR;
    }
    sprintf(buf, "%d", val);
    Tcl_AppendResult(interp, buf, NULL);
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------







|







1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
    } else  if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {
	val = GetSystemMetrics(SM_CXHSCROLL);
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be cxhscroll or cyvscroll", NULL);
	return TCL_ERROR;
    }
    snprintf(buf, sizeof(buf), "%d", val);
    Tcl_AppendResult(interp, buf, NULL);
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestpropObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window mainWin = (Tk_Window)clientData;
    int result, actualFormat;
    unsigned long bytesAfter, length, value;







|







1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestpropObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tk_Window mainWin = (Tk_Window)clientData;
    int result, actualFormat;
    unsigned long bytesAfter, length, value;
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
    if ((result == Success) && (actualType != None)) {
	if ((actualFormat == 8) && (actualType == XA_STRING)) {
	    for (p = property; ((unsigned long)(p-property)) < length; p++) {
		if (*p == 0) {
		    *p = '\n';
		}
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj((/*!unsigned*/char*)property, -1));
	} else {
	    for (p = property; length > 0; length--) {
		if (actualFormat == 32) {
		    value = *((long *) p);
		    p += sizeof(long);
		} else if (actualFormat == 16) {
		    value = 0xffff & (*((short *) p));
		    p += sizeof(short);
		} else {
		    value = 0xff & *p;
		    p += 1;
		}
		sprintf(buffer, "0x%lx", value);
		Tcl_AppendElement(interp, buffer);
	    }
	}
    }
    if (property != NULL) {
	XFree(property);
    }







|












|







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
    if ((result == Success) && (actualType != None)) {
	if ((actualFormat == 8) && (actualType == XA_STRING)) {
	    for (p = property; ((unsigned long)(p-property)) < length; p++) {
		if (*p == 0) {
		    *p = '\n';
		}
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj((/*!unsigned*/char*)property, TCL_INDEX_NONE));
	} else {
	    for (p = property; length > 0; length--) {
		if (actualFormat == 32) {
		    value = *((long *) p);
		    p += sizeof(long);
		} else if (actualFormat == 16) {
		    value = 0xffff & (*((short *) p));
		    p += sizeof(short);
		} else {
		    value = 0xff & *p;
		    p += 1;
		}
		snprintf(buffer, sizeof(buffer), "0x%lx", value);
		Tcl_AppendElement(interp, buffer);
	    }
	}
    }
    if (property != NULL) {
	XFree(property);
    }
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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestprintfObjCmd(
    ClientData dummy,	/* Not used */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    char buffer[256];
    Tcl_WideInt wideInt;
#ifdef _WIN32
    __int64 longLongInt;
#else
    long long longLongInt;
#endif
    (void)dummy;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "wideint");
	return TCL_ERROR;
    }
    if (Tcl_GetWideIntFromObj(interp, objv[1], &wideInt) != TCL_OK) {
	return TCL_ERROR;
    }
    longLongInt = wideInt;

    /* Just add a lot of arguments to sprintf. Reason: on AMD64, the first
     * 4 or 6 arguments (we assume 8, just in case) might be put in registers,
     * which still woudn't tell if the assumed size is correct: We want this
     * test-case to fail if the 64-bit value is printed as truncated to 32-bit.
     */
    sprintf(buffer, "%s%s%s%s%s%s%s%s%" TCL_LL_MODIFIER "d %"
	    TCL_LL_MODIFIER "u", "", "", "", "", "", "", "", "",
	    (Tcl_WideInt)longLongInt, (Tcl_WideUInt)longLongInt);
    Tcl_AppendResult(interp, buffer, NULL);
    return TCL_OK;
}

#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
 *----------------------------------------------------------------------







|






<
<
<

<
<










|




|

|







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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestprintfObjCmd(
    TCL_UNUSED(void *),	/* Not used */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    char buffer[256];
    Tcl_WideInt wideInt;



    long long longLongInt;



    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 snprintf. 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.
     */
    snprintf(buffer, sizeof(buffer), "%s%s%s%s%s%s%s%s%" TCL_LL_MODIFIER "d %"
	    TCL_LL_MODIFIER "u", "", "", "", "", "", "", "", "",
	    longLongInt, (unsigned long long)longLongInt);
    Tcl_AppendResult(interp, buffer, NULL);
    return TCL_OK;
}

#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
 *----------------------------------------------------------------------
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwrapperObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkWindow *winPtr, *wrapperPtr;
    Tk_Window tkwin;








|







1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwrapperObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TkWindow *winPtr, *wrapperPtr;
    Tk_Window tkwin;

2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
    }

    wrapperPtr = TkpGetWrapperWindow(winPtr);
    if (wrapperPtr != NULL) {
	char buf[TCL_INTEGER_SPACE];

	TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    }
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------







|







1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
    }

    wrapperPtr = TkpGetWrapperWindow(winPtr);
    if (wrapperPtr != NULL) {
	char buf[TCL_INTEGER_SPACE];

	TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
    }
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
static int
CustomOptionSet(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(Tk_Window),
    Tcl_Obj **value,
    char *recordPtr,
    TkSizeT internalOffset,
    char *saveInternalPtr,
    int flags)
{
    int objEmpty;
    char *newStr, *string, *internalPtr;

    objEmpty = 0;







|







2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
static int
CustomOptionSet(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(Tk_Window),
    Tcl_Obj **value,
    char *recordPtr,
    Tcl_Size internalOffset,
    char *saveInternalPtr,
    int flags)
{
    int objEmpty;
    char *newStr, *string, *internalPtr;

    objEmpty = 0;
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

    if ((flags & TK_OPTION_NULL_OK) && objEmpty) {
	*value = NULL;
    } else {
	string = Tcl_GetString(*value);
	Tcl_UtfToUpper(string);
	if (strcmp(string, "BAD") == 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected good value, got \"BAD\"", -1));
	    return TCL_ERROR;
	}
    }
    if (internalPtr != NULL) {
	if (*value != NULL) {
	    string = Tcl_GetString(*value);
	    newStr = (char *)ckalloc((*value)->length + 1);







|







2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057

    if ((flags & TK_OPTION_NULL_OK) && objEmpty) {
	*value = NULL;
    } else {
	string = Tcl_GetString(*value);
	Tcl_UtfToUpper(string);
	if (strcmp(string, "BAD") == 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected good value, got \"BAD\"", TCL_INDEX_NONE));
	    return TCL_ERROR;
	}
    }
    if (internalPtr != NULL) {
	if (*value != NULL) {
	    string = Tcl_GetString(*value);
	    newStr = (char *)ckalloc((*value)->length + 1);
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
}

static Tcl_Obj *
CustomOptionGet(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,
    TkSizeT internalOffset)
{
    return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1));
}

static void
CustomOptionRestore(
    ClientData dummy,
    Tk_Window tkwin,
    char *internalPtr,
    char *saveInternalPtr)
{
    (void)dummy;
    (void)tkwin;

    *(char **)internalPtr = *(char **)saveInternalPtr;
    return;
}

static void
CustomOptionFree(
    ClientData dummy,
    Tk_Window tkwin,
    char *internalPtr)
{
    (void)dummy;
    (void)tkwin;

    if (*(char **)internalPtr != NULL) {
	ckfree(*(char **)internalPtr);
    }
}
/*
 *----------------------------------------------------------------------
 *







|

|




|
|



<
<
<






|
|


<
<
<







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
}

static Tcl_Obj *
CustomOptionGet(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,
    Tcl_Size internalOffset)
{
    return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), TCL_INDEX_NONE));
}

static void
CustomOptionRestore(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *internalPtr,
    char *saveInternalPtr)
{



    *(char **)internalPtr = *(char **)saveInternalPtr;
    return;
}

static void
CustomOptionFree(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *internalPtr)
{



    if (*(char **)internalPtr != NULL) {
	ckfree(*(char **)internalPtr);
    }
}
/*
 *----------------------------------------------------------------------
 *
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestPhotoStringMatchCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tcl_Obj *dummy = NULL;
    Tcl_Obj *resultObj[2];
    int width, height;
    (void)clientData;

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "imageData");
        return TCL_ERROR;
    }
    if (TkDebugPhotoStringMatchDef(interp, objv[1], dummy, &width, &height)) {
        resultObj[0] = Tcl_NewWideIntObj(width);







|







<







2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130

2131
2132
2133
2134
2135
2136
2137
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestPhotoStringMatchCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    Tcl_Obj *dummy = NULL;
    Tcl_Obj *resultObj[2];
    int width, height;


    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "imageData");
        return TCL_ERROR;
    }
    if (TkDebugPhotoStringMatchDef(interp, objv[1], dummy, &width, &height)) {
        resultObj[0] = Tcl_NewWideIntObj(width);

Changes to generic/tkText.c.

more than 10,000 changes

Changes to generic/tkText.h.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16






17




18
19











20
21
































22












































23
24
25
26
27
28


29
30
31
32
33
34
35
36

37






38
39



40

41
42
43
44
45

46
47
48
49


























































































































50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66





67


68
69
70
71
72
73
74















75
76
77
78
79
80



81
82
83
84
85
86
87
88
89
90
91
92
93


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146




147
148
149
150
151
152
153
154
155
156












157
158
159
160
161
162
163
164
165
166
167













168









169
170
171
172
173
174
175
176
177



178
179
180























181
182
183
184
185
186
187
188
189
190









191

192

193
194
195

196

197



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224



























225
226
227
228
229
230
231
232

233
234
235
236
237
238
239








240



241


















242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269


270
271
272
273









274

275












276
277
278




















































279
280
281
282
283
284

285


286
287








































































288
289
290
291
292
293
294

295
296
297
298



299
300
301
302






303



304






305

306

307

308
309







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329


330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376




377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404




405
406
407
408
409
410




411


412
413



414



415

416
417
418
419
420
421
422

423
424
425

426

427
428



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

451

452


453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476


477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553






























554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572













573



574









575



576





577











578
579
580
581
582

583
584
585
586
587

588

589
590
591
592
593
594

595
596
597




598


599













600



601
602
603
604
605
606

607
608
609
610
611
612
613
614
615
616
617
618
619
















620
621
622
623


624
625
626
627
628
629
630
631
632

633
634

635


636




637
638
639
640
641
642







643
644
645
646
647
648
649
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666
/*
 * tkText.h --
 *
 *	Declarations shared among the files that implement text widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.

 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXT
#define _TKTEXT

#ifndef _TK






#include "tk.h"




#endif












#ifndef _TKUNDO
#include "tkUndo.h"
































#endif













































/*
 * The data structure below defines a single logical line of text (from
 * newline to newline, not necessarily what appears on one display line of the
 * screen).
 */



typedef struct TkTextLine {
    struct Node *parentPtr;	/* Pointer to parent node containing line. */
    struct TkTextLine *nextPtr;	/* Next in linked list of lines with same
				 * parent node in B-tree. NULL means end of
				 * list. */
    struct TkTextSegment *segPtr;
				/* First in ordered list of segments that make

				 * up the line. */






    int *pixels;		/* Array containing two integers for each
				 * referring text widget. The first of these



				 * is the number of vertical pixels taken up

				 * by this line, whether currently displayed
				 * or not. This number is only updated
				 * asychronously. The second of these is the
				 * last epoch at which the pixel height was
				 * recalculated. */

} TkTextLine;

/*
 * -----------------------------------------------------------------------


























































































































 * Segments: each line is divided into one or more segments, where each
 * segment is one of several things, such as a group of characters, a tag
 * toggle, a mark, or an embedded widget. Each segment starts with a standard
 * header followed by a body that varies from type to type.
 * -----------------------------------------------------------------------
 */

/*
 * The data structure below defines the body of a segment that represents a
 * tag toggle. There is one of these structures at both the beginning and end
 * of each tagged range.
 */

typedef struct TkTextToggle {
    struct TkTextTag *tagPtr;	/* Tag that starts or ends here. */
    int inNodeCounts;		/* 1 means this toggle has been accounted for
				 * in node toggle counts; 0 means it hasn't,





				 * yet. */


} TkTextToggle;

/*
 * The data structure below defines line segments that represent marks. There
 * is one of these for each mark in the text.
 */
















typedef struct TkTextMark {
    struct TkText *textPtr;	/* Overall information about text widget. */
    TkTextLine *linePtr;	/* Line structure that contains the
				 * segment. */
    Tcl_HashEntry *hPtr;	/* Pointer to hash table entry for mark (in
				 * sharedTextPtr->markTable). */



} TkTextMark;

/*
 * A structure of the following type holds information for each window
 * embedded in a text widget. This information is only used by the file
 * tkTextWind.c
 */

typedef struct TkTextEmbWindowClient {
    struct TkText *textPtr;	/* Information about the overall text
				 * widget. */
    Tk_Window tkwin;		/* Window for this segment. NULL means that
				 * the window hasn't been created yet. */


    int chunkCount;		/* Number of display chunks that refer to this
				 * window. */
    int displayed;		/* Non-zero means that the window has been
				 * displayed on the screen recently. */
    struct TkTextSegment *parent;
    struct TkTextEmbWindowClient *next;
} TkTextEmbWindowClient;

typedef struct TkTextEmbWindow {
    struct TkSharedText *sharedTextPtr;
				/* Information about the shared portion of the
				 * text widget. */
    Tk_Window tkwin;		/* Window for this segment. This is just a
				 * temporary value, copied from 'clients', to
				 * make option table updating easier. NULL
				 * means that the window hasn't been created
				 * yet. */
    TkTextLine *linePtr;	/* Line structure that contains this
				 * window. */
    char *create;		/* Script to create window on-demand. NULL
				 * means no such script. Malloc-ed. */
    int align;			/* How to align window in vertical space. See
				 * definitions in tkTextWind.c. */
    int padX, padY;		/* Padding to leave around each side of
				 * window, in pixels. */
    int stretch;		/* Should window stretch to fill vertical
				 * space of line (except for pady)? 0 or 1. */



    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    TkTextEmbWindowClient *clients;
				/* Linked list of peer-widget specific
				 * information for this embedded window. */
} TkTextEmbWindow;

/*
 * A structure of the following type holds information for each image embedded
 * in a text widget. This information is only used by the file tkTextImage.c
 */

typedef struct TkTextEmbImage {
    struct TkSharedText *sharedTextPtr;
				/* Information about the shared portion of the
				 * text widget. This is used when the image
				 * changes or is deleted. */
    TkTextLine *linePtr;	/* Line structure that contains this image. */
    char *imageString;		/* Name of the image for this segment. */
    char *imageName;		/* Name used by text widget to identify this
				 * image. May be unique-ified. */
    char *name;			/* Name used in the hash table. Used by
				 * "image names" to identify this instance of
				 * the image. */
    Tk_Image image;		/* Image for this segment. NULL means that the
				 * image hasn't been created yet. */




    int align;			/* How to align image in vertical space. See
				 * definitions in tkTextImage.c. */
    int padX, padY;		/* Padding to leave around each side of image,
				 * in pixels. */
    int chunkCount;		/* Number of display chunks that refer to this
				 * image. */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
} TkTextEmbImage;













/*
 * The data structure below defines line segments.
 */

typedef struct TkTextSegment {
    const struct Tk_SegType *typePtr;
				/* Pointer to record describing segment's
				 * type. */
    struct TkTextSegment *nextPtr;
				/* Next in list of segments for this line, or
				 * NULL for end of list. */













    TkSizeT size;			/* Size of this segment (# of bytes of index









				 * space it occupies). */
    union {
	char chars[TKFLEXARRAY];		/* Characters that make up character info.
				 * Actual length varies to hold as many
				 * characters as needed.*/
	TkTextToggle toggle;	/* Information about tag toggle. */
	TkTextMark mark;	/* Information about mark. */
	TkTextEmbWindow ew;	/* Information about embedded window. */
	TkTextEmbImage ei;	/* Information about embedded image. */



    } body;
} TkTextSegment;
























/*
 * Data structures of the type defined below are used during the execution of
 * Tcl commands to keep track of various interesting places in a text. An
 * index is only valid up until the next modification to the character
 * structure of the b-tree so they can't be retained across Tcl commands.
 * However, mods to marks or tags don't invalidate indices.
 */

typedef struct TkTextIndex {
    TkTextBTree tree;		/* Tree containing desired position. */









    TkTextLine *linePtr;	/* Pointer to line containing position of

				 * interest. */

    int byteIndex;		/* Index within line of desired character (0
				 * means first one). */
    struct TkText *textPtr;	/* May be NULL, but otherwise the text widget

				 * with which this index is associated. If not

				 * NULL, then we have a refCount on the



				 * widget. */
} TkTextIndex;

/*
 * Types for procedure pointers stored in TkTextDispChunk strutures:
 */

typedef struct TkTextDispChunk TkTextDispChunk;

typedef void 		Tk_ChunkDisplayProc(struct TkText *textPtr,
			    TkTextDispChunk *chunkPtr, int x, int y,
			    int height, int baseline, Display *display,
			    Drawable dst, int screenY);
typedef void		Tk_ChunkUndisplayProc(struct TkText *textPtr,
			    TkTextDispChunk *chunkPtr);
typedef int		Tk_ChunkMeasureProc(TkTextDispChunk *chunkPtr, int x);
typedef void		Tk_ChunkBboxProc(struct TkText *textPtr,
			    TkTextDispChunk *chunkPtr, int index, int y,
			    int lineHeight, int baseline, int *xPtr,
			    int *yPtr, int *widthPtr, int *heightPtr);

/*
 * The structure below represents a chunk of stuff that is displayed together
 * on the screen. This structure is allocated and freed by generic display
 * code but most of its fields are filled in by segment-type-specific code.
 */




























struct TkTextDispChunk {
    /*
     * The fields below are set by the type-independent code before calling
     * the segment-type-specific layoutProc. They should not be modified by
     * segment-type-specific code.
     */

    int x;			/* X position of chunk, in pixels. This

				 * position is measured from the left edge of
				 * the logical line, not from the left edge of
				 * the window (i.e. it doesn't change under
				 * horizontal scrolling). */
    struct TkTextDispChunk *nextPtr;
				/* Next chunk in the display line or NULL for
				 * the end of the list. */








    struct TextStyle *stylePtr;	/* Display information, known only to



				 * tkTextDisp.c. */



















    /*
     * The fields below are set by the layoutProc that creates the chunk.
     */

    Tk_ChunkDisplayProc *displayProc;
				/* Procedure to invoke to draw this chunk on
				 * the display or an off-screen pixmap. */
    Tk_ChunkUndisplayProc *undisplayProc;
				/* Procedure to invoke when segment ceases to
				 * be displayed on screen anymore. */
    Tk_ChunkMeasureProc *measureProc;
				/* Procedure to find character under a given
				 * x-location. */
    Tk_ChunkBboxProc *bboxProc;	/* Procedure to find bounding box of character
				 * in chunk. */
    int numBytes;		/* Number of bytes that will be displayed in
				 * the chunk. */

    int minAscent;		/* Minimum space above the baseline needed by
				 * this chunk. */
    int minDescent;		/* Minimum space below the baseline needed by
				 * this chunk. */
    int minHeight;		/* Minimum total line height needed by this
				 * chunk. */
    int width;			/* Width of this chunk, in pixels. Initially
				 * set by chunk-specific code, but may be
				 * increased to include tab or extra space at
				 * end of line. */


    int breakIndex;		/* Index within chunk of last acceptable
				 * position for a line (break just before this
				 * byte index). <= 0 means don't break during
				 * or immediately after this chunk. */









    ClientData clientData;	/* Additional information for use of

				 * displayProc and undisplayProc. */












};

/*




















































 * One data structure of the following type is used for each tag in a text
 * widget. These structures are kept in sharedTextPtr->tagTable and referred
 * to in other structures.
 */

typedef enum {

    TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD,


    TEXT_WRAPMODE_NULL
} TkWrapMode;









































































typedef struct TkTextTag {
    const char *name;		/* Name of this tag. This field is actually a
				 * pointer to the key from the entry in
				 * sharedTextPtr->tagTable, so it needn't be
				 * freed explicitly. For 'sel' tags this is
				 * just a static string, so again need not be

				 * freed. */
    const struct TkText *textPtr;
				/* If non-NULL, then this tag only applies to
				 * the given text widget (when there are peer



				 * widgets). */
    int priority;		/* Priority of this tag within widget. 0 means
				 * lowest priority. Exactly one tag has each
				 * integer value between 0 and numTags-1. */






    struct Node *tagRootPtr;	/* Pointer into the B-Tree at the lowest node



				 * that completely dominates the ranges of






				 * text occupied by the tag. At this node

				 * there is no information about the tag. One

				 * or more children of the node do contain

				 * information about the tag. */
    int toggleCount;		/* Total number of tag toggles. */








    /*
     * Information for displaying text with this tag. The information belows
     * acts as an override on information specified by lower-priority tags.
     * If no value is specified, then the next-lower-priority tag on the text
     * determins the value. The text widget itself provides defaults if no tag
     * specifies an override.
     */

    Tk_3DBorder border;		/* Used for drawing background. NULL means no
				 * value specified here. */
    int borderWidth;		/* Width of 3-D border for background. */
    Tcl_Obj *borderWidthPtr;	/* Width of 3-D border for background. */
    char *reliefString;		/* -relief option string (malloc-ed). NULL
				 * means option not specified. */
    int relief;			/* 3-D relief for background. */
    Pixmap bgStipple;		/* Stipple bitmap for background. None means
				 * no value specified here. */

    XColor *fgColor;		/* Foreground color for text. NULL means no
				 * value specified here. */


    Tk_Font tkfont;		/* Font for displaying text. NULL means no
				 * value specified here. */
    Pixmap fgStipple;		/* Stipple bitmap for text and other
				 * foreground stuff. None means no value
				 * specified here.*/
    char *justifyString;	/* -justify option string (malloc-ed). NULL
				 * means option not specified. */
    Tk_Justify justify;		/* How to justify text: TK_JUSTIFY_LEFT,
				 * TK_JUSTIFY_RIGHT, or TK_JUSTIFY_CENTER.
				 * Only valid if justifyString is non-NULL. */
    char *lMargin1String;	/* -lmargin1 option string (malloc-ed). NULL
				 * means option not specified. */
    int lMargin1;		/* Left margin for first display line of each
				 * text line, in pixels. Only valid if
				 * lMargin1String is non-NULL. */
    char *lMargin2String;	/* -lmargin2 option string (malloc-ed). NULL
				 * means option not specified. */
    int lMargin2;		/* Left margin for second and later display
				 * lines of each text line, in pixels. Only
				 * valid if lMargin2String is non-NULL. */
    Tk_3DBorder lMarginColor;	/* Used for drawing background in left margins.
                                 * This is used for both lmargin1 and lmargin2.
				 * NULL means no value specified here. */
    char *offsetString;		/* -offset option string (malloc-ed). NULL
				 * means option not specified. */
    int offset;			/* Vertical offset of text's baseline from
				 * baseline of line. Used for superscripts and
				 * subscripts. Only valid if offsetString is
				 * non-NULL. */
    char *overstrikeString;	/* -overstrike option string (malloc-ed). NULL
				 * means option not specified. */
    int overstrike;		/* Non-zero means draw horizontal line through
				 * middle of text. Only valid if
				 * overstrikeString is non-NULL. */
    XColor *overstrikeColor;    /* Color for the overstrike. NULL means same
                                 * color as foreground. */
    char *rMarginString;	/* -rmargin option string (malloc-ed). NULL
				 * means option not specified. */
    int rMargin;		/* Right margin for text, in pixels. Only
				 * valid if rMarginString is non-NULL. */
    Tk_3DBorder rMarginColor;	/* Used for drawing background in right margin.
				 * NULL means no value specified here. */
    Tk_3DBorder selBorder;	/* Used for drawing background for selected text.
				 * NULL means no value specified here. */
    XColor *selFgColor;		/* Foreground color for selected text. NULL means
				 * no value specified here. */
    char *spacing1String;	/* -spacing1 option string (malloc-ed). NULL




				 * means option not specified. */
    int spacing1;		/* Extra spacing above first display line for
				 * text line. Only valid if spacing1String is
				 * non-NULL. */
    char *spacing2String;	/* -spacing2 option string (malloc-ed). NULL
				 * means option not specified. */
    int spacing2;		/* Extra spacing between display lines for the
				 * same text line. Only valid if
				 * spacing2String is non-NULL. */
    char *spacing3String;	/* -spacing2 option string (malloc-ed). NULL
				 * means option not specified. */
    int spacing3;		/* Extra spacing below last display line for
				 * text line. Only valid if spacing3String is
				 * non-NULL. */
    Tcl_Obj *tabStringPtr;	/* -tabs option string. NULL means option not
				 * specified. */
    struct TkTextTabArray *tabArrayPtr;
				/* Info about tabs for tag (malloc-ed) or
				 * NULL. Corresponds to tabString. */
    int tabStyle;		/* One of TABULAR or WORDPROCESSOR or NONE (if
				 * not specified). */
    char *underlineString;	/* -underline option string (malloc-ed). NULL
				 * means option not specified. */
    int underline;		/* Non-zero means draw underline underneath
				 * text. Only valid if underlineString is
				 * non-NULL. */
    XColor *underlineColor;     /* Color for the underline. NULL means same
                                 * color as foreground. */




    TkWrapMode wrapMode;	/* How to handle wrap-around for this tag.
				 * Must be TEXT_WRAPMODE_CHAR,
				 * TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD, or
				 * TEXT_WRAPMODE_NULL to use wrapmode for
				 * whole widget. */
    char *elideString;		/* -elide option string (malloc-ed). NULL




				 * means option not specified. */


    int elide;			/* Non-zero means that data under this tag
				 * should not be displayed. */



    int affectsDisplay;		/* Non-zero means that this tag affects the



				 * way information is displayed on the screen

				 * (so need to redisplay if tag changes). */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    int affectsDisplayGeometry;	/* Non-zero means that this tag affects the
				 * size with which information is displayed on
				 * the screen (so need to recalculate line
				 * dimensions if tag changes). */

} TkTextTag;

#define TK_TAG_AFFECTS_DISPLAY	0x1

#define TK_TAG_UNDERLINE	0x2

#define TK_TAG_JUSTIFY		0x4
#define TK_TAG_OFFSET		0x10




/*
 * The data structure below is used for searching a B-tree for transitions on
 * a single tag (or for all tag transitions). No code outside of tkTextBTree.c
 * should ever modify any of the fields in these structures, but it's OK to
 * use them for read-only information.
 */

typedef struct TkTextSearch {
    TkTextIndex curIndex;	/* Position of last tag transition returned by
				 * TkBTreeNextTag, or index of start of
				 * segment containing starting position for
				 * search if TkBTreeNextTag hasn't been called
				 * yet, or same as stopIndex if search is
				 * over. */
    TkTextSegment *segPtr;	/* Actual tag segment returned by last call to
				 * TkBTreeNextTag, or NULL if TkBTreeNextTag
				 * hasn't returned anything yet. */
    TkTextSegment *nextPtr;	/* Where to resume search in next call to
				 * TkBTreeNextTag. */
    TkTextSegment *lastPtr;	/* Stop search before just before considering
				 * this segment. */

    TkTextTag *tagPtr;		/* Tag to search for (or tag found, if allTags

				 * is non-zero). */


    int linesLeft;		/* Lines left to search (including curIndex
				 * and stopIndex). When this becomes <= 0 the
				 * search is over. */
    int allTags;		/* Non-zero means ignore tag check: search for
				 * transitions on all tags. */

} TkTextSearch;

/*
 * The following data structure describes a single tab stop. It must be kept
 * in sync with the 'tabOptionStrings' array in the function 'TkTextGetTabs'
 */

typedef enum {LEFT, RIGHT, CENTER, NUMERIC} TkTextTabAlign;

/*
 * The following are the supported styles of tabbing, used for the -tabstyle
 * option of the text widget. The last element is only used for tag options.
 */

typedef enum {
    TK_TEXT_TABSTYLE_TABULAR,
    TK_TEXT_TABSTYLE_WORDPROCESSOR,
    TK_TEXT_TABSTYLE_NONE
} TkTextTabStyle;



typedef struct TkTextTab {
    int location;		/* Offset in pixels of this tab stop from the
				 * left margin (lmargin2) of the text. */
    TkTextTabAlign alignment;	/* Where the tab stop appears relative to the
				 * text. */
} TkTextTab;

typedef struct TkTextTabArray {
    int numTabs;		/* Number of tab stops. */
    double lastTab;		/* The accurate fractional pixel position of
				 * the last tab. */
    double tabIncrement;	/* The accurate fractional pixel increment
				 * between interpolated tabs we have to create
				 * when we exceed numTabs. */
    TkTextTab tabs[TKFLEXARRAY];/* Array of tabs. The actual size will be
				 * numTabs. THIS FIELD MUST BE THE LAST IN THE
				 * STRUCTURE. */
} TkTextTabArray;

/*
 * Enumeration defining the edit modes of the widget.
 */

typedef enum {
    TK_TEXT_EDIT_INSERT,	/* insert mode */
    TK_TEXT_EDIT_DELETE,	/* delete mode */
    TK_TEXT_EDIT_REPLACE,	/* replace mode */
    TK_TEXT_EDIT_OTHER		/* none of the above */
} TkTextEditMode;

/*
 * Enumeration defining the ways in which a text widget may be modified (for
 * undo/redo handling).
 */

typedef enum {
    TK_TEXT_DIRTY_NORMAL,	/* Normal behavior. */
    TK_TEXT_DIRTY_UNDO,		/* Reverting a compound action. */
    TK_TEXT_DIRTY_REDO,		/* Reapplying a compound action. */
    TK_TEXT_DIRTY_FIXED		/* Forced to be dirty; can't be undone/redone
				 * by normal activity. */
} TkTextDirtyMode;

/*
 * The following enum is used to define a type for the -state option of the
 * Text widget.
 */

typedef enum {
    TK_TEXT_STATE_DISABLED, TK_TEXT_STATE_NORMAL
} TkTextState;

/*
 * A data structure of the following type is shared between each text widget
 * that are peers.
 */

#ifndef TkSizeT
#   if TCL_MAJOR_VERSION > 8
#	define TkSizeT size_t
#   else
#	define TkSizeT int
#   endif
#endif

typedef struct TkSharedText {
    TkSizeT refCount;		/* Reference count this shared object. */
    TkTextBTree tree;		/* B-tree representation of text and tags for
				 * widget. */
    Tcl_HashTable tagTable;	/* Hash table that maps from tag names to
				 * pointers to TkTextTag structures. The "sel"
				 * tag does not feature in this table, since
				 * there's one of those for each text peer. */
    int numTags;		/* Number of tags currently defined for
				 * widget; needed to keep track of
				 * priorities. */






























    Tcl_HashTable markTable;	/* Hash table that maps from mark names to
				 * pointers to mark segments. The special
				 * "insert" and "current" marks are not stored
				 * in this table, but directly accessed as
				 * fields of textPtr. */
    Tcl_HashTable windowTable;	/* Hash table that maps from window names to
				 * pointers to window segments. If a window
				 * segment doesn't yet have an associated
				 * window, there is no entry for it here. */
    Tcl_HashTable imageTable;	/* Hash table that maps from image names to
				 * pointers to image segments. If an image
				 * segment doesn't yet have an associated
				 * image, there is no entry for it here. */
    Tk_BindingTable bindingTable;
				/* Table of all bindings currently defined for
				 * this widget. NULL means that no bindings
				 * exist, so the table hasn't been created.
				 * Each "object" used for this table is the
				 * name of a tag. */













    TkSizeT stateEpoch;	/* This is incremented each time the B-tree's



				 * contents change structurally, or when the









				 * start/end limits change, and means that any



				 * cached TkTextIndex objects are no longer





				 * valid. */












    /*
     * Information related to the undo/redo functionality.
     */


    TkUndoRedoStack *undoStack;	/* The undo/redo stack. */
    int undo;			/* Non-zero means the undo/redo behaviour is
				 * enabled. */
    int maxUndo;		/* The maximum depth of the undo stack
				 * expressed as the maximum number of compound

				 * statements. */

    int autoSeparators;		/* Non-zero means the separators will be
				 * inserted automatically. */
    int undoMarkId;             /* Counts undo marks temporarily used during
                                   undo and redo operations. */
    int isDirty;		/* Flag indicating the 'dirtyness' of the
				 * text widget. If the flag is not zero,

				 * unsaved modifications have been applied to
				 * the text widget. */
    TkTextDirtyMode dirtyMode;	/* The nature of the dirtyness characterized




				 * by the isDirty flag. */


    TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode













				 * was. */




    /*
     * Keep track of all the peers
     */

    struct TkText *peers;

} TkSharedText;

/*
 * The following enum is used to define a type for the -insertunfocussed
 * option of the Text widget.
 */

typedef enum {
    TK_TEXT_INSERT_NOFOCUS_HOLLOW,
    TK_TEXT_INSERT_NOFOCUS_NONE,
    TK_TEXT_INSERT_NOFOCUS_SOLID
} TkTextInsertUnfocussed;

















/*
 * A data structure of the following type is kept for each text widget that
 * currently exists for this process:
 */



typedef struct TkText {
    /*
     * Information related to and accessed by widget peers and the
     * TkSharedText handling routines.
     */

    TkSharedText *sharedTextPtr;/* Shared section of all peers. */
    struct TkText *next;	/* Next in list of linked peers. */

    TkTextLine *start;		/* First B-tree line to show, or NULL to start
				 * at the beginning. */

    TkTextLine *end;		/* Last B-tree line to show, or NULL for up to


				 * the end. */




    int pixelReference;		/* Counter into the current tree reference
				 * index corresponding to this widget. */
    int abortSelections;	/* Set to 1 whenever the text is modified in a
				 * way that interferes with selection
				 * retrieval: used to abort incremental
				 * selection retrievals. */








    /*
     * Standard Tk widget information and text-widget specific items
     */

    Tk_Window tkwin;		/* Window that embodies the text. NULL means
				 * that the window has been destroyed but the
				 * data structures haven't yet been cleaned
				 * up.*/
    Display *display;		/* Display for widget. Needed, among other
				 * things, to allow resources to be freed even
				 * after tkwin has gone away. */
    Tcl_Interp *interp;		/* Interpreter associated with widget. Used to
				 * delete widget command. */
    Tcl_Command widgetCmd;	/* Token for text's widget command. */

    int state;			/* Either STATE_NORMAL or STATE_DISABLED. A
				 * text widget is read-only when disabled. */

    /*
     * Default information for displaying (may be overridden by tags applied
     * to ranges of characters).
     */

    Tk_3DBorder border;		/* Structure used to draw 3-D border and







>








|
>
>
>
>
>
>
|
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>



|
|
|

|
>
|
>
>
>
>
>
>
|
|
>
>
>
|
>
|
<
|
<
|
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|





|
|
|


|
|
|
|
>
>
>
>
>
|
>
>
|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
|
|
>
>
>













>
>
|
















<
<








>
>
>

















<








>
>
>
>




<
<




>
>
>
>
>
>
>
>
>
>
>
>











>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|

|


<
|


>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>
>
>
>
>
>
|
>
|
>
|
|
<
>
|
>
|
>
>
>
|








|
<
|
|
|
<
|
|
<
|
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
>
|
<
|
<



>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
<
<
<
<
<
<
<
<
<
<
|
|
>
|
<
|
<
|
<
|
|
<
|
>
>
|
<
|
|
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
|
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<
|
|
|
>
|
|
|
|
>
>
>
|
|
<
|
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
|
>
|
>
|
>
|
<
>
>
>
>
>
>
>









|
<
|
<
<
|



>
|
|
>
>





<
<
|
|
<
|



|
<
|


|



<
|


|

<
<
|
|
<


<
|

|






|
>
>
>
>
|

|
<
<
|



<
|

|






|
|
<
<
|
|
<


>
>
>
>





<
>
>
>
>
|
>
>
|
|
>
>
>
|
>
>
>
|
>
|
<
<
|
<
|
|
>


<
>
|
>
|
|
>
>
>


















|
<


>
|
>
|
>
>
|
|
<
<
<
>











|



|
|
|

>
>















|
















|
<



<
<
<
<
<
<
|
<
<
<
<
|
<
|



|
<


|
<
<
<
|
<
<


|






|
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
|
|
|
|
<
|

|
<
|

|
|
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>





>
|
<
<
|
|
>
|
>
|
<
|
<
|
|
>
|
|
|
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>






>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>









>
|
|
>
|
>
>
|
>
>
>
>






>
>
>
>
>
>
>















>
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330


331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411


412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543

544
545

546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591

592

593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632










633
634
635
636

637

638

639
640

641
642
643
644

645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
/*
 * tkText.h --
 *
 *	Declarations shared among the files that implement text widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright (c) 2015-2018 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXT
#define _TKTEXT

#ifndef _TKINT
# include "tkInt.h"
#endif

/* Support of assertion handler. */
#define CATCH_ASSERTION_FAILED 0

#include "tkTextUndo.h"

#ifdef MAC_OSX_TK
/* required for TK_LAYOUT_WITH_BASE_CHUNKS */
# include "tkMacOSXInt.h"
#endif

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

#ifdef TK_CHECK_ALLOCS
# define DEBUG_ALLOC(expr) expr
#else
# define DEBUG_ALLOC(expr)
#endif

#ifndef TK_NO_DEPRECATED

/* We are still supporting the deprecated -startline/-endline options. */
# define SUPPORT_DEPRECATED_STARTLINE_ENDLINE 1

/* We are still supporting invalid changes in readonly/disabled widgets. */
# define SUPPORT_DEPRECATED_MODS_OF_DISABLED_WIDGET 1

/*
 * The special index identifier "begin" currently has the lowest precedence,
 * because of portability reasons. But in a future Tk version it should have
 * the same precedence as the special index identifier "end".
 */
# define BEGIN_DOES_NOT_BELONG_TO_BASE 1

/* We are still supporting deprecated tag options. */
# define SUPPORT_DEPRECATED_TAG_OPTIONS 1

/* We are still supporting the deprecated commands "edit canundo/redo". */
# define SUPPORT_DEPRECATED_CANUNDO_REDO 1

#else /* TK_NO_DEPRECATED */

# define SUPPORT_DEPRECATED_STARTLINE_ENDLINE 0
# define SUPPORT_DEPRECATED_MODS_OF_DISABLED_WIDGET 0
# define BEGIN_DOES_NOT_BELONG_TO_BASE 0
# define SUPPORT_DEPRECATED_TAG_OPTIONS 0
# define SUPPORT_DEPRECATED_CANUNDO_REDO 0

#endif /* TK_NO_DEPRECATED */

#ifdef _MSC_VER
/* earlier versions of MSVC don't know snprintf, but _snprintf is compatible. */
# define snprintf _snprintf
#endif

/*
 * Forward declarations.
 */

struct TkTextUndoStack_;
struct TkBitField;
struct TkTextUndoToken;
union TkTextTagSet;

/*
 * The data structure below defines the pixel information for a single line of text.
 */

typedef struct TkTextDispLineEntry {
    uint32_t height;		/* Height of display line in pixels. */
    uint32_t pixels;		/* Accumulated height of display lines. In last entry this attribute
    				 * will contain the old number of display lines. */
    uint32_t byteOffset;	/* Byte offet relative to logical line. */
    uint32_t tabIndex:24;	/* Tab index of last char chunk of this display line. */
    uint32_t hyphenRule:7;	/* Hyphenation rule applied to last char chunk of this display line. */
    uint32_t tabApplied:1;	/* Tab index of last char chunk has been already applied? */
} TkTextDispLineEntry;

typedef struct TkTextDispLineInfo {
    uint32_t numDispLines;	/* Number of display lines (so far). */
    TkTextDispLineEntry entry[1];
				/* Cached information about the display line, this is required for
				 * long lines to avoid repeated display line height calculations
				 * when scrolling. If numDispLines <= 1 then this information is
				 * NULL, in this case attribute height of TkTextPixelInfo is
				 * identical to the pixel height of the (single) display line. */
} TkTextDispLineInfo;

typedef struct TkTextPixelInfo {
    uint32_t height;		/* Number of vertical pixels taken up by this line, whether
    				 * currently displayed or not. This number is only updated
				 * asychronously. Note that this number is the sum of
				 * dispLineInfo, but only when dispLineInfo != NULL. */
    uint32_t epoch;		/* Last epoch at which the pixel height was recalculated. */
    TkTextDispLineInfo *dispLineInfo;
				/* Pixel information for each display line, available only
     				 * if more than one display line exists, otherwise it is NULL. */
} TkTextPixelInfo;

/*
 * The data structure below defines a single logical line of text (from
 * newline to newline, not necessarily what appears on one display line of the
 * screen).
 */

struct TkTextSegment;

typedef struct TkTextLine {
    struct Node *parentPtr;	/* Pointer to parent node containing line. */
    struct TkTextLine *nextPtr;	/* Next in linked list of lines with same parent node in B-tree.
    				 * NULL means end of list. */
    struct TkTextLine *prevPtr;	/* Previous in linked list of lines. NULL means no predecessor. */
    struct TkTextSegment *segPtr;
				/* First in ordered list of segments that make up the line. */
    struct TkTextSegment *lastPtr;
				/* Last in ordered list of segments that make up the line. */
    union TkTextTagSet *tagonPtr;
				/* This set contains all tags used in this line. */
    union TkTextTagSet *tagoffPtr;
    				/* This set contains tag t if and only if at least one segment in
				 * this line does not use tag t, provided that tag t is also included
				 * in tagonPtr. */
    TkTextPixelInfo *pixelInfo;	/* Array containing the pixel information for each referring
    				 * text widget. */
    int32_t size;		/* Sum of sizes over all segments belonging to this line. */
    uint32_t numBranches;	/* Counting the number of branches on this line. Only count branches
    				 * connected with links, do not count branches pointing to a mark. */
    uint32_t numLinks:30;	/* Counting the number of links on this line. */
    uint32_t changed:1;		/* Will be set when the content of this logical line has changed. The
    				 * display stuff will use (and reset) this flag, but only for logical

				 * lines. The purpose of this flag is the acceleration of the line

				 * break information. */
    uint32_t logicalLine:1;	/* Flag whether this is the start of a logical line. */
} TkTextLine;

/*
 * -----------------------------------------------------------------------
 * Index structure containing line and byte index.
 * -----------------------------------------------------------------------
 */

typedef struct TkTextPosition {
    int32_t lineIndex;
    int32_t byteIndex;
} TkTextPosition;

/*
 * -----------------------------------------------------------------------
 * Structures for undo/redo mechanism.
 *
 * Note that TkTextUndoToken is a generic type, used as a base struct for
 * inheritance. Inheritance in C is portable due to C99 section 6.7.2.1
 * bullet point 13:
 *
 *	Within a structure object, the non-bit-field members and the units
 *	in which bit-fields reside have addresses that increase in the order
 *	in which they are declared. A pointer to a structure object, suitably
 *	converted, points to its initial member (or if that member is a
 *	bit-field, then to the unit in which it resides), and vice versa.
 *	There may be unnamed padding within a structure object, but not at
 *	beginning.
 *
 * This inheritance concept is also used in the portable GTK library.
 * -----------------------------------------------------------------------
 */

/* we need some forward declarations */
struct TkSharedText;
struct TkTextIndex;
struct TkTextUndoInfo;
struct TkTextUndoIndex;

typedef enum {
    TK_TEXT_UNDO_INSERT,	TK_TEXT_REDO_INSERT,
    TK_TEXT_UNDO_DELETE,	TK_TEXT_REDO_DELETE,
    TK_TEXT_UNDO_IMAGE,		TK_TEXT_REDO_IMAGE,
    TK_TEXT_UNDO_WINDOW,	TK_TEXT_REDO_WINDOW,
    TK_TEXT_UNDO_TAG,		TK_TEXT_REDO_TAG,
    TK_TEXT_UNDO_TAG_CLEAR,	TK_TEXT_REDO_TAG_CLEAR,
    TK_TEXT_UNDO_TAG_PRIORITY,	TK_TEXT_REDO_TAG_PRIORITY,
    TK_TEXT_UNDO_MARK_SET,	TK_TEXT_REDO_MARK_SET,
    TK_TEXT_UNDO_MARK_MOVE,	TK_TEXT_REDO_MARK_MOVE,
    TK_TEXT_UNDO_MARK_GRAVITY,	TK_TEXT_REDO_MARK_GRAVITY
} TkTextUndoAction;

typedef Tcl_Obj *(*TkTextGetUndoCommandProc)(
    const struct TkSharedText *sharedTextPtr,
    const struct TkTextUndoToken *item);

typedef void (*TkTextUndoProc)(
    struct TkSharedText *sharedTextPtr,
    struct TkTextUndoInfo *undoInfo,
    struct TkTextUndoInfo *redoInfo,
    int isRedo);

typedef void (*TkTextDestroyUndoItemProc)(
    struct TkSharedText *sharedTextPtr,
    struct TkTextUndoToken *item,
    int reused);

typedef void (*TkTextGetUndoRangeProc)(
    const struct TkSharedText *sharedTextPtr,
    const struct TkTextUndoToken *item,
    struct TkTextIndex *startIndex,
    struct TkTextIndex *endIndex);

typedef Tcl_Obj *(*TkTextInspectProc)(
    const struct TkSharedText *sharedTextPtr,
    const struct TkTextUndoToken *item);

typedef struct Tk_UndoType {
    TkTextUndoAction action;
    TkTextGetUndoCommandProc commandProc;	/* mandatory */
    TkTextUndoProc undoProc;			/* mandatory */
    TkTextDestroyUndoItemProc destroyProc;	/* optional */
    TkTextGetUndoRangeProc rangeProc;		/* mandatory */
    TkTextInspectProc inspectProc;		/* mandatory */
} Tk_UndoType;

/*
 * The struct below either contains a mark segment or a line/byte index pair.
 * This struct is portable due to C99 7.18.1.4.
 */

typedef struct TkTextUndoIndex {
    union {
	struct TkTextSegment *markPtr;	/* Predecessor/successor segment. */
	uintptr_t byteIndex;		/* Byte index in this line. */
    } u;
    int32_t lineIndex;	/* Line index, if -1 this struct contains a mark segment, otherwise
    			 * (if >= 0) this struct contains a line/byte index pair. */
} TkTextUndoIndex;

/*
 * This is a generic type, any "derived" struct must contain
 * 'const Tk_UndoType *' as the first member (see note above).
 */
typedef struct TkTextUndoToken {
    const Tk_UndoType *undoType;
} TkTextUndoToken;

/*
 * This is a generic type, any "derived" struct must also contain
 * these members. Especially the tokens for insert/delete must be
 * derived from this struct.
 */
typedef struct TkTextUndoTokenRange {
    const Tk_UndoType *undoType;
    TkTextUndoIndex startIndex;
    TkTextUndoIndex endIndex;
} TkTextUndoTokenRange;

typedef struct TkTextUndoInfo {
    TkTextUndoToken *token;	/* The data of this undo/redo item. */
    uint32_t byteSize;		/* Byte size of this item. */
} TkTextUndoInfo;

/*
 * -----------------------------------------------------------------------
 * Segments: each line is divided into one or more segments, where each
 * segment is one of several things, such as a group of characters, a hyphen,
 * a mark, or an embedded widget. Each segment starts with a standard
 * header followed by a body that varies from type to type.
 * -----------------------------------------------------------------------
 */

/*
 * The data structure below defines the body of a segment that represents
 * a branch. A branch is adjusting the chain of segments, depending whether
 * elided text will be processed or not.
 */

typedef struct TkTextBranch {
    struct TkTextSegment *nextPtr; /* The next in list of segments for the alternative branch. */
} TkTextBranch;

/*
 * The data structure below defines the body of a segment that represents
 * a link. A link is the connection point for a segment chain of elided
 * text.
 */

typedef struct TkTextLink {
    struct TkTextSegment *prevPtr; /* Previous in list of segments for the alternative branch. */
} TkTextLink;

/*
 * The data structure below defines line segments that represent marks. There
 * is one of these for each mark in the text.
 */

typedef struct TkTextMarkChange {
    struct TkTextSegment *markPtr;
    				/* Pointer to mark segment which contains this item. */
    struct TkTextUndoToken *toggleGravity;
    				/* Undo token for "mark gravity". */
    struct TkTextUndoToken *moveMark;
    				/* Undo token for "mark move". */
    struct TkTextUndoToken *setMark;
    				/* Undo token for "mark set". */
    const struct Tk_SegType *savedMarkType;
    				/* Type of mark (left or right gravity) before "mark gravity". We
				 * need this information for optimizing succeeding calls of
				 * "mark gravity" with same mark. */
} TkTextMarkChange;

typedef struct TkTextMark {
    struct TkText *textPtr;	/* Overall information about text widget. */


    uintptr_t ptr;		/* [Address is even - real type is Tcl_HashEntry *]
				 *   Pointer to hash table entry for mark (in sharedTextPtr->markTable).
				 * [Address is odd - real type is const char *]
				 *   Name of mark, this is used iff the segment is preserved for undo. */
    TkTextMarkChange *changePtr;/* Pointer to retained undo tokens. */
} TkTextMark;

/*
 * A structure of the following type holds information for each window
 * embedded in a text widget. This information is only used by the file
 * tkTextWind.c
 */

typedef struct TkTextEmbWindowClient {
    struct TkText *textPtr;	/* Information about the overall text
				 * widget. */
    Tk_Window tkwin;		/* Window for this segment. NULL means that
				 * the window hasn't been created yet. */
    Tcl_HashEntry *hPtr;	/* Pointer to hash table entry for mark
				 * (in sharedTextPtr->windowTable). */
    size_t chunkCount;		/* Number of display chunks that refer to this
				 * window. */
    int displayed;		/* Non-zero means that the window has been
				 * displayed on the screen recently. */
    struct TkTextSegment *parent;
    struct TkTextEmbWindowClient *next;
} TkTextEmbWindowClient;

typedef struct TkTextEmbWindow {
    struct TkSharedText *sharedTextPtr;
				/* Information about the shared portion of the
				 * text widget. */
    Tk_Window tkwin;		/* Window for this segment. This is just a
				 * temporary value, copied from 'clients', to
				 * make option table updating easier. NULL
				 * means that the window hasn't been created
				 * yet. */


    char *create;		/* Script to create window on-demand. NULL
				 * means no such script. Malloc-ed. */
    int align;			/* How to align window in vertical space. See
				 * definitions in tkTextWind.c. */
    int padX, padY;		/* Padding to leave around each side of
				 * window, in pixels. */
    int stretch;		/* Should window stretch to fill vertical
				 * space of line (except for pady)? 0 or 1. */
    int isOwner;		/* Should destroy the window when un-embed? This will only be
				 * done if the text widget is the owner. Default is true
				 * (this is compatible to older versions). */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    TkTextEmbWindowClient *clients;
				/* Linked list of peer-widget specific
				 * information for this embedded window. */
} TkTextEmbWindow;

/*
 * A structure of the following type holds information for each image embedded
 * in a text widget. This information is only used by the file tkTextImage.c
 */

typedef struct TkTextEmbImage {
    struct TkSharedText *sharedTextPtr;
				/* Information about the shared portion of the
				 * text widget. This is used when the image
				 * changes or is deleted. */

    char *imageString;		/* Name of the image for this segment. */
    char *imageName;		/* Name used by text widget to identify this
				 * image. May be unique-ified. */
    char *name;			/* Name used in the hash table. Used by
				 * "image names" to identify this instance of
				 * the image. */
    Tk_Image image;		/* Image for this segment. NULL means that the
				 * image hasn't been created yet. */
    int imgWidth;		/* Width of displayed image. */
    int imgHeight;		/* Height of displayed image. */
    Tcl_HashEntry *hPtr;	/* Pointer to hash table entry for image
    				 * (in sharedTextPtr->imageTable).*/
    int align;			/* How to align image in vertical space. See
				 * definitions in tkTextImage.c. */
    int padX, padY;		/* Padding to leave around each side of image,
				 * in pixels. */


    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
} TkTextEmbImage;

/*
 * A structure of the following type is for the definition of the hyphenation
 * segments. Note that this structure is a derivation of a char segment. This
 * is portable due to C99 section 6.7.2.1 (see above - undo/redo).
 */

typedef struct TkTextHyphen {
    char chars[6];		/* Characters that make up character info. Actual length varies. */
    int8_t textSize;		/* Actual length of text, but not greater than 5. */
    int8_t rules;		/* Set of rules for this hyphen, will be set by tk_textInsert. */
} TkTextHyphen;

/*
 * The data structure below defines line segments.
 */

typedef struct TkTextSegment {
    const struct Tk_SegType *typePtr;
				/* Pointer to record describing segment's
				 * type. */
    struct TkTextSegment *nextPtr;
				/* Next in list of segments for this line, or
				 * NULL for end of list. */
    struct TkTextSegment *prevPtr;
				/* Previous in list of segments for this line, or NULL for start
				 * of list. */
    struct TkTextSection *sectionPtr;
    				/* The section where this segment belongs. */
    union TkTextTagSet *tagInfoPtr;
				/* Tag information for this segment, needed for testing whether
				 * this content is tagged with a specific tag. Used only if size > 0.
				 * (In case of segments with size == 0 memory will be wasted - these
				 * segments do not need this attribute - but the alternative would be
				 * a quite complex structure with some nested structs and unions, and
				 * this is quite inconvenient. Only marks and branches/links do not
				 * use this information, so the waste of memory is relatively low.) */
    int32_t size;		/* Size of this segment (# of bytes of index space it occupies). */
    uint32_t refCount:26;	/* Reference counter, don't delete until counter is zero, or
    				 * tree is gone. */
    uint32_t protectionFlag:1;	/* This (char) segment is protected, join is not allowed. */
    uint32_t insertMarkFlag:1;	/* This segment is the special "insert" mark? */
    uint32_t currentMarkFlag:1;	/* This segment is the special "current" mark? */
    uint32_t privateMarkFlag:1;	/* This mark segment is private (generated)? */
    uint32_t normalMarkFlag:1;	/* This mark segment is neither protected, nor special, nor private,
    				 * nor start or end marker. */
    uint32_t startEndMarkFlag:1;/* This segment is a start marker or an end marker? */

    union {
	char chars[TCL_UTF_MAX];	/* Characters that make up character info.
				 * Actual length varies to hold as many
				 * characters as needed.*/

	TkTextHyphen hyphen;	/* Information about hyphen. */
	TkTextEmbWindow ew;	/* Information about embedded window. */
	TkTextEmbImage ei;	/* Information about embedded image. */
	TkTextMark mark;	/* Information about mark. */
	TkTextBranch branch;	/* Information about branch. */
	TkTextLink link;	/* Information about link. */
    } body;
} TkTextSegment;

/*
 * Macro that determines how much space to allocate for a specific segment:
 */

#define SEG_SIZE(bodyType) (offsetof(TkTextSegment, body) + sizeof(bodyType))

/*
 * The data structure below defines sections of text segments. Each section
 * contains 40 line segments in average. In this way fast search for segments
 * is possible.
 */
typedef struct TkTextSection {
    struct TkTextLine *linePtr;	/* The line where this section belongs. */
    struct TkTextSection *nextPtr;
    				/* Next in list of sections, or NULL if last. */
    struct TkTextSection *prevPtr;
    				/* Previous in list of sections, or NULL if first. */
    struct TkTextSegment *segPtr;
    				/* First segment belonging to this section. */
    int32_t size:24;		/* Sum of size over all segments belonging to this section. */
    uint32_t length:8;		/* Number of segments belonging to this section. */
} TkTextSection;

/*
 * Data structures of the type defined below are used during the execution of
 * Tcl commands to keep track of various interesting places in a text. An
 * index is only valid up until the next modification to the character
 * structure of the b-tree so they can't be retained across Tcl commands.
 * However, mods to marks or tags don't invalidate indices.
 */

typedef struct TkTextIndex {
    TkTextBTree tree;		/* Tree containing desired position. */
    struct TkText *textPtr;	/* The associated text widget (required). */
    Tcl_Size stateEpoch;	/* The epoch of the segment pointer. */

    /*
     * The following attribtes should not be accessed directly, use the TkTextIndex*
     * functions if you want to set or get attributes.
     */

    struct {
	TkTextLine *linePtr;	/* Pointer to line containing position of interest. */
	TkTextSegment *segPtr;	/* Pointer to segment containing position
				 * of interest (NULL means not yet computed). */
	int isCharSegment;	/* Whether 'segPtr' is a char segment (if not NULL). */
	int32_t byteIndex;	/* Index within line of desired character (0 means first one,
				 * -1 means not yet computed). */

	int32_t lineNo;		/* The line number of the line pointer. */
	int32_t lineNoRel;	/* The line number of the line pointer in associated text widget. */
    } priv;

    int discardConsistencyCheck;
				/* This flag is for debugging only: in certain situations consistency
				 * checks should not be done (for example when inserting or deleting
				 * text). */
} TkTextIndex;

/*
 * Types for procedure pointers stored in TkTextDispChunk strutures:
 */

typedef struct TkTextDispChunk TkTextDispChunk;

typedef void 	Tk_ChunkDisplayProc(struct TkText *textPtr, TkTextDispChunk *chunkPtr,

		    int x, int y, int height, int baseline, Display *display, Drawable dst,
		    int screenY);
typedef void	Tk_ChunkUndisplayProc(struct TkText *textPtr, TkTextDispChunk *chunkPtr);

typedef Tcl_Size	Tk_ChunkMeasureProc(TkTextDispChunk *chunkPtr, int x);
typedef void	Tk_ChunkBboxProc(struct TkText *textPtr, TkTextDispChunk *chunkPtr,

		    Tcl_Size index, int y, int lineHeight, int baseline, int *xPtr, int *yPtr,
		    int *widthPtr, int *heightPtr);

/*
 * The structure below represents a chunk of stuff that is displayed together
 * on the screen. This structure is allocated and freed by generic display
 * code but most of its fields are filled in by segment-type-specific code.
 */

typedef enum {
    TEXT_DISP_CHAR   = 1 << 0, /* Character layout */
    TEXT_DISP_HYPHEN = 1 << 1, /* Hyphen layout */
    TEXT_DISP_ELIDED = 1 << 2, /* Elided content layout */
    TEXT_DISP_WINDOW = 1 << 3, /* Embedded window layout */
    TEXT_DISP_IMAGE  = 1 << 4, /* Embedded image layout */
    TEXT_DISP_CURSOR = 1 << 5, /* Insert cursor layout */
} TkTextDispType;

/* This constant can be used for a test whether the chunk has any content. */
#define TEXT_DISP_CONTENT (TEXT_DISP_CHAR|TEXT_DISP_HYPHEN|TEXT_DISP_WINDOW|TEXT_DISP_IMAGE)
/* This constant can be used for a test whether the chunk contains text. */
#define TEXT_DISP_TEXT    (TEXT_DISP_CHAR|TEXT_DISP_HYPHEN)

typedef struct TkTextDispChunkProcs {
    TkTextDispType type;	/* Layout type. */
    Tk_ChunkDisplayProc *displayProc;
				/* Procedure to invoke to draw this chunk on the display
				 * or an off-screen pixmap. */
    Tk_ChunkUndisplayProc *undisplayProc;
				/* Procedure to invoke when segment ceases to be displayed
				 * on screen anymore. */
    Tk_ChunkMeasureProc *measureProc;
				/* Procedure to find character under a given x-location. */
    Tk_ChunkBboxProc *bboxProc;	/* Procedure to find bounding box of character in chunk. */
} TkTextDispChunkProcs;

struct TkTextDispChunk {
    /*
     * The fields below are set by the type-independent code before calling
     * the segment-type-specific layoutProc. They should not be modified by
     * segment-type-specific code.
     */

    const struct TkTextDispLine *dlPtr;
    				/* Pointer to display line of this chunk. We need this for the retrieval
				 * of the y position.

				 */

    struct TkTextDispChunk *nextPtr;
				/* Next chunk in the display line or NULL for
				 * the end of the list. */
    struct TkTextDispChunk *prevPtr;
				/* Previous chunk in the display line or NULL for the start of the
				 * list. */
    struct TkTextDispChunk *prevCharChunkPtr;
				/* Previous char chunk in the display line, or NULL. */
    struct TkTextDispChunkSection *sectionPtr;
    				/* The section of this chunk. The section structure allows fast search
				 * for x positions, and character positions. */
    struct TextStyle *stylePtr;	/* Display information, known only to tkTextDisp.c. This attribute
    				 * is set iff the associated segment has tag information AND is not
				 * elided. */
    size_t uniqID;		/* Unique identifier for this chunk, used by TkTextPickCurrent. */

    /*
     * The fields below are set by the layoutProc that creates the chunk.
     */

    const TkTextDispChunkProcs *layoutProcs;
    const char *brks;		/* Line break information of this chunk for TEXT_WRAPMODE_CODEPOINT. */
    void *clientData;	/* Additional information for use of displayProc and undisplayProc. */

    /*
     * The fields below are set by the type-independent code before calling
     * the segment-type-specific layoutProc. They should not be modified by
     * segment-type-specific code.
     */

    int32_t x;			/* X position of chunk, in pixels. This position is measured
    				 * from the left edge of the logical line, not from the left
				 * edge of the window (i.e. it doesn't change under horizontal
				 * scrolling). */

    /*
     * The fields below are set by the layoutProc that creates the chunk.
     */

    uint32_t byteOffset;	/* Byte offset relative to display line start. */










    uint32_t numBytes;		/* Number of bytes that will be used in the chunk. */
    uint32_t numSpaces;		/* Number of expandable spaces. */
    uint32_t segByteOffset;	/* Starting offset in corresponding char segment. */
    int32_t minAscent;		/* Minimum space above the baseline needed by this chunk. */

    int32_t minDescent;		/* Minimum space below the baseline needed by this chunk. */

    int32_t minHeight;		/* Minimum total line height needed by this chunk. */

    int32_t width;		/* Width of this chunk, in pixels. Initially set by
    				 * chunk-specific code, but may be increased to include tab

				 * or extra space at end of line. */
    int32_t additionalWidth;	/* Additional width when expanding spaces for full justification. */
    int32_t hyphenRules;	/* Allowed hyphenation rules for this (hyphen) chunk. */
    int32_t breakIndex;		/* Index within chunk of last acceptable position for a line

    				 * (break just before this byte index). <= 0 means don't break
				 * during or immediately after this chunk. */
    int wrappedAtSpace;	/* This flag will be set when the a chunk has been wrapped while
    				 * gobbling a trailing space. */
    int endsWithSyllable;	/* This flag will be set when the corresponding sgement for
    				 * this chunk will be followed by a hyphen segment. */
    int skipFirstChar;		/* This flag will be set if the first byte has to be skipped due
    				 * to a spelling change. */
    int endOfLineSymbol;	/* This flag will be set if this chunk contains (only) the end of
    				 * line symbol. */
    int integralPart;		/* This chunk contains the start of the integral part of a numeric. */

#ifdef TK_LAYOUT_WITH_BASE_CHUNKS

    /*
     * Support of context drawing (Mac):
     */

    Tcl_DString baseChars;	/* Actual characters for the stretch of text, only defined in
    				 * base chunk. */
    int32_t baseWidth;		/* Width in pixels of the whole string, if known, else 0. */
    int32_t xAdjustment;	/* Adjustment of x-coord for next chunk. */
    struct TkTextDispChunk *baseChunkPtr;
    				/* Points to base chunk. */

#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
};

/*
 * The following structure describes one line of the display, which may be
 * either part or all of one line of the text. This structure will be defined
 * here because we want to provide inlined functions.
 */

typedef struct TkTextDispLine {
    TkTextIndex index;		/* Identifies first character in text that is displayed on this line. */
    struct TkTextDispLine *nextPtr;
    				/* Next in list of all display lines for this window. The list is
    				 * sorted in order from top to bottom. Note: the next DLine doesn't
				 * always correspond to the next line of text: (a) can have multiple
				 * DLines for one text line (wrapping), (b) can have elided newlines,
				 * and (c) can have gaps where DLine's have been deleted because
				 * they're out of date. */
    struct TkTextDispLine *prevPtr;
    				/* Previous in list of all display lines for this window. */
    TkTextDispChunk *chunkPtr;	/* Pointer to first chunk in list of all of those that are displayed
    				 * on this line of the screen. */
    TkTextDispChunk *firstCharChunkPtr;
    				/* Pointer to first chunk in list containing chars, window, or image. */
    TkTextDispChunk *lastChunkPtr;
    				/* Pointer to last chunk in list containing chars. */
    TkTextDispChunk *cursorChunkPtr;
    				/* Pointer to chunk which displays the insert cursor. */
    struct TkTextBreakInfo *breakInfo;
    				/* Line break information of logical line. */
    uint32_t displayLineNo;	/* The number of this display line relative to the related logical
    				 * line. */
    uint32_t hyphenRule;	/* Hyphenation rule applied to last char chunk (only if hyphenation
    				 * has been applied). */
    uint32_t byteCount;		/* Number of bytes accounted for by this display line, including a
    				 * trailing space or newline that isn't actually displayed. */
    int invisible;		/* Whether this display line is invisible (no chunk with width > 0). */
    int32_t y;			/* Y-position at which line is supposed to be drawn (topmost pixel
    				 * of rectangular area occupied by line). */
    int32_t oldY;		/* Y-position at which line currently appears on display. This is
    				 * used to move lines by scrolling rather than re-drawing. If 'flags'
				 * have the OLD_Y_INVALID bit set, then we will never examine this
				 * field (which means line isn't currently visible on display and
				 * must be redrawn). */
    int32_t width;		/* Width of line, in pixels, not including any indent. */
    int32_t height;		/* Height of line, in pixels. */
    int32_t baseline;		/* Offset of text baseline from y, in pixels. */
    int32_t spaceAbove;		/* How much extra space was added to the top of the line because of
    				 * spacing options. This is included in height and baseline. */
    int32_t spaceBelow;		/* How much extra space was added to the bottom of the line because
    				 * of spacing options. This is included in height. */
    uint32_t length;		/* Total length of line, in pixels, including possible left indent. */
    uint32_t flags;		/* Various flag bits: see below for values. */
} TkTextDispLine;

/*
 * One data structure of the following type is used for each tag in a text
 * widget. These structures are kept in sharedTextPtr->tagTable and referred
 * to in other structures.
 */

typedef enum {
    TEXT_WRAPMODE_NULL = -1,
    TEXT_WRAPMODE_CHAR,
    TEXT_WRAPMODE_NONE,
    TEXT_WRAPMODE_WORD,
    TEXT_WRAPMODE_CODEPOINT
} TkWrapMode;

MODULE_SCOPE const char *const tkTextWrapStrings[];

/*
 * The spacing mode of the text widget:
 */

typedef enum {
    TEXT_SPACEMODE_NONE,
    TEXT_SPACEMODE_EXACT,
    TEXT_SPACEMODE_TRIM,
    TEXT_SPACEMODE_NULL,
} TkTextSpaceMode;

/*
 * If the soft hyphen is the right neighbor of character "c", and the right neighbor is character
 * "k", then the ck hyphenation rule will be applied.
 */
#define TK_TEXT_HYPHEN_CK		1 /* de */
/*
 * Hungarian has an unusual hyphenation case which involves reinsertion of a root-letter, as in the
 * following example: "vissza" becomes "visz-sza". These special cases, occurring when the characters
 * are in the middle of a word are: "ccs" becomes "cs-cs", "ggy" becomes "gy-gy", "lly" becomes "ly-ly",
 * "nny" becomes "ny-ny", "tty" becomes "ty-ty", "zzs" becomes "zs-zs", "ssz" becomes "sz-sz".
 */
#define TK_TEXT_HYPHEN_DOUBLE_DIGRAPH	2 /* hu */
/*
 * If the soft hyphen is the right neighbor of any vowel, and the right neighbor is the same vowel,
 * then the doublevowel hyphenation rule will be applied.
 */
#define TK_TEXT_HYPHEN_DOUBLE_VOWEL	3 /* nl */
/*
 * In Catalan, a geminated consonant can be splitted: the word "paral·lel" hyphenates
 * into "paral-lel".
 */
#define TK_TEXT_HYPHEN_GEMINATION	4 /* ca */
/*
 * In Polish the hyphen will be repeated after line break, this means for example that "kong-fu"
 * becomes "kong- -fu".
 */
#define TK_TEXT_HYPHEN_REPEAT		5 /* pl */
/*
 * If the soft hyphen is the right neighbor of any vocal, and the right neighbor of any vocal with
 * trema (umlaut), then the trema hyphenation rule will be applied.
 */
#define TK_TEXT_HYPHEN_TREMA		6 /* nl */
/*
 * If the soft hyphen is the right neighbor of any consonant, and the right neighbor is the same
 * consonant, and the right consonant is followed by a vowel, then the tripleconsonant hyphenation
 * rule will be applied when not hyphenating.
 */
#define TK_TEXT_HYPHEN_TRIPLE_CONSONANT	7 /* de, nb, nn, no, sv */
/*
 * Mask of all defined hyphen rules.
 */
#define TK_TEXT_HYPHEN_MASK		((1 << (TK_TEXT_HYPHEN_TRIPLE_CONSONANT + 1)) - 1)

/*
 * Some constants for the mouse hovering:
 */

#define TK_TEXT_NEARBY_IS_UNDETERMINED	INT_MAX /* is not yet determined */
#define TK_TEXT_IS_NEARBY		INT_MIN /* is on border */

typedef struct TkTextSharedAttrs {
    Tk_3DBorder border;		/* Used for drawing background. NULL means no value specified here. */
    Tk_3DBorder inactiveBorder;	/* Used for drawing background. NULL means no value specified here. */
    XColor *fgColor;		/* Foreground color for text. NULL means no value specified here. */
    XColor *inactiveFgColor;	/* Foreground color for text. NULL means no value specified here. */
    Tcl_Obj *borderWidthObj;	/* Width of 3-D border for background. */
    int borderWidth;		/* Width of 3-D border for background. */
} TkTextSharedAttrs;

typedef struct TkTextTag {
    const char *name;		/* Name of this tag. This field is actually a pointer to the key

    				 * from the entry in 'sharedTextPtr->tagTable', so it needn't be
				 * freed explicitly. For "sel" tags this is just a static string,
				 * so again need not be freed. */
    const struct TkSharedText *sharedTextPtr;
				/* Shared section of all peers. */
    struct TkText *textPtr;
				/* If non-NULL, then this tag only applies to the given text widget
				 * (when there are peer widgets). */
    struct Node *rootPtr;	/* Pointer into the B-Tree at the lowest node that completely
    				 * dominates the ranges of text occupied by the tag. At this node
				 * there is no information about the tag. One or more children of
				 * the node do contain information about the tag. */
    uint32_t priority;		/* Priority of this tag within widget. 0 means lowest priority.

    				 * Exactly one tag has each integer value between 0 and numTags-1. */
    uint32_t index;		/* Unique index for fast tag lookup. It is guaranteed that the index
    				 * number is less than 'TkBitSize(sharedTextPtr->usedTags)'.*/
    uint32_t tagEpoch;		/* Epoch of creation time. */
    uint32_t refCount;		/* Number of objects referring to us. */
    int isDisabled;		/* This tag is disabled? */
    int isSelTag;		/* This tag is the special "sel" tag? */

    /*
     * Information for tag collection [TkBTreeGetTags, TextInspectCmd, TkTextPickCurrent].
     */

    struct TkTextTag *nextPtr;	/* Will be set by TkBTreeGetTags, TkBTreeClearTags, and TextInsertCmd. */
    struct TkTextTag *succPtr;	/* Only TextInspectCmd will use this attribute. */
    uint32_t flag;		/* Only for temporary usage (currently only TextInspectCmd, and
    				 * EmbImageConfigure will use this attribute). */
    Tcl_Size epoch;		/* Only TkBTreeGetTags, TkBTreeGetSegmentTags, and TkBTreeClearTags
    				 * will use this attribute. */

    /*
     * Information for undo/redo.
     */

    TkTextUndoToken *recentTagAddRemoveToken;
    				/* Holds the undo information of last tag add/remove operation. */

    TkTextUndoToken *recentChangePriorityToken;
    				/* Holds the undo information of last tag lower/raise operation. */
    int recentTagAddRemoveTokenIsNull;
    				/* 'recentTagAddRemoveToken' is null, this means the pointer still
				 * is valid, but should not be saved onto undo stack. */
    uint32_t savedPriority; 	/* Contains the priority before recentChangePriorityToken will be set. */
    int32_t undoTagListIndex;	/* Index to entry in 'undoTagList', is -1 if not in 'undoTagList'. */

    /*
     * Information for displaying text with this tag. The information belows
     * acts as an override on information specified by lower-priority tags.
     * If no value is specified, then the next-lower-priority tag on the text
     * determins the value. The text widget itself provides defaults if no tag
     * specifies an override.
     */

    TkTextSharedAttrs attrs;	/* Contains the following attributes: border, inactiveBorder,

				 * fgColor, inactiveFgColor, and borderWidth. These attributes will


				 * be shared with attributes from "sel" tag. */
    int relief;			/* 3-D relief for background. */
    Pixmap bgStipple;		/* Stipple bitmap for background. None means
				 * no value specified here. */
    Tcl_Obj *indentBgPtr;	/* -indentbackground option. Background will be indented
				 * accordingly to the -lmargin1, and -lmargin2 options. NULL means
				 * option not specified. */
    int indentBg;		/* If 1, Background will be indented accordingly to the -lmargin1
    				 * and -lmargin2 options. -1 means not specified */
    Tk_Font tkfont;		/* Font for displaying text. NULL means no
				 * value specified here. */
    Pixmap fgStipple;		/* Stipple bitmap for text and other
				 * foreground stuff. None means no value
				 * specified here.*/


    Tk_Justify justify;		/* How to justify text: TK_JUSTIFY_LEFT, TK_JUSTIFY_RIGHT,
    				 * TK_JUSTIFY_CENTER, or TK_JUSTIFY_FULL, or TK_JUSTIFY_NULL. */

    Tcl_Obj *lMargin1Obj;	/* -lmargin1 option. NULL
				 * means option not specified. */
    int lMargin1;		/* Left margin for first display line of each
				 * text line, in pixels. Only valid if
				 * lMargin1Obj is non-NULL. */

    Tcl_Obj *lMargin2Obj;	/* -lmargin2 option. NULL means option not specified. */
    int lMargin2;		/* Left margin for second and later display
				 * lines of each text line, in pixels. Only
				 * valid if lMargin2Obj is non-NULL. */
    Tk_3DBorder lMarginColor;	/* Used for drawing background in left margins.
                                 * This is used for both lmargin1 and lmargin2.
				 * NULL means no value specified here. */

    Tcl_Obj *offsetObj;		/* -offset option. NULL means option not specified. */
    int offset;			/* Vertical offset of text's baseline from
				 * baseline of line. Used for superscripts and
				 * subscripts. Only valid if offsetObj is
				 * non-NULL. */


    int overstrike;		/* > 0 means draw horizontal line through
				 * middle of text. -1 means not specified. */

    XColor *overstrikeColor;    /* Color for the overstrike. NULL means same
                                 * color as foreground. */

    Tcl_Obj *rMarginObj;	/* -rmargin option. NULL means option not specified. */
    int rMargin;		/* Right margin for text, in pixels. Only
				 * valid if rMarginObj is non-NULL. */
    Tk_3DBorder rMarginColor;	/* Used for drawing background in right margin.
				 * NULL means no value specified here. */
    Tk_3DBorder selBorder;	/* Used for drawing background for selected text.
				 * NULL means no value specified here. */
    XColor *selFgColor;		/* Foreground color for selected text. NULL means
				 * no value specified here. */
    Tk_3DBorder inactiveSelBorder;
    				/* Used for drawing background for inactive selected text.
				 * NULL means no value specified here. */
    XColor *inactiveSelFgColor;	/* Foreground color for inactive selected text. NULL means no value
    				 * specified here. */
    Tcl_Obj *spacing1Obj;	/* -spacing1 option. NULL means option not specified. */
    int spacing1;		/* Extra spacing above first display line for
				 * text line. Only valid if spacing1Obj is non-NULL. */


    Tcl_Obj *spacing2Obj;	/* -spacing2 option. NULL means option not specified. */
    int spacing2;		/* Extra spacing between display lines for the
				 * same text line. Only valid if
				 * spacing2String is non-NULL. */

    Tcl_Obj *spacing3Obj;	/* -spacing2 option. NULL means option not specified. */
    int spacing3;		/* Extra spacing below last display line for
				 * text line. Only valid if spacing3Obj is
				 * non-NULL. */
    Tcl_Obj *tabStringPtr;	/* -tabs option string. NULL means option not
				 * specified. */
    struct TkTextTabArray *tabArrayPtr;
				/* Info about tabs for tag (malloc-ed) or
				 * NULL. Corresponds to tabString. */
    int tabStyle;		/* One of TK_TEXT_TABSTYLE_TABULAR or TK_TEXT_TABSTYLE_WORDPROCESSOR
				 * or TK_TEXT_TABSTYLE_NULL (if not specified). */


    int underline;		/* > 0 means draw underline underneath
				 * text. -1 means not specified. */

    XColor *underlineColor;     /* Color for the underline. NULL means same
                                 * color as foreground. */
    XColor *eolColor;		/* Color for the end of line symbol. NULL means same color as
    				 * foreground. */
    XColor *hyphenColor;	/* Color for the soft hyphen character. NULL means same color as
    				 * foreground. */
    TkWrapMode wrapMode;	/* How to handle wrap-around for this tag.
				 * Must be TEXT_WRAPMODE_CHAR,
				 * TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD, or
				 * TEXT_WRAPMODE_NULL to use wrapmode for
				 * whole widget. */

    TkTextSpaceMode spaceMode;	/* How to handle displaying spaces. Must be TEXT_SPACEMODE_NULL,
    				 * TEXT_SPACEMODE_NONE, TEXT_SPACEMODE_EXACT, or TEXT_SPACEMODE_TRIM. */
    Tcl_Obj *hyphenRulesPtr;	/* The hyphen rules string. */
    int hyphenRules;		/* The hyphen rules, only useful for soft hyphen segments. */
    Tcl_Obj *langPtr;		/* -lang option string. NULL means option not specified. */
    char lang[3];		/* The specified language for the text content, only enabled if not
    				 * NUL. */
    int elide;			/* > 0 means that data under this tag
				 * should not be displayed. -1 means not specified. */
    int undo;			/* True means that any change of tagging with this tag will be pushed
    				 * on the undo stack (if undo stack is enabled), otherwise this tag
				 * will not regarded in the undo/redo process. */

    /*
     * Derived values, and the container for all the options.
     */

    int affectsDisplay;	/* True means that this tag affects the way information is
    				 * displayed on the screen (so need to redisplay if tag changes). */


    int affectsDisplayGeometry;/* True means that this tag affects the size with which

    				 * information is displayed on the screen (so need to recalculate
				 * line dimensions if tag changes). */
    Tk_OptionTable optionTable;	/* Token representing the configuration specifications. */
} TkTextTag;


/*
 * Some definitions for tag search, used by TkBTreeStartSearch, TkBTreeStartSearchBack:
 */

typedef enum {
    SEARCH_NEXT_TAGON,		/* Search for next range, this will skip the current range. */
    SEARCH_EITHER_TAGON_TAGOFF,	/* Search for next tagon/tagoff change. */
} TkTextSearchMode;

/*
 * The data structure below is used for searching a B-tree for transitions on
 * a single tag (or for all tag transitions). No code outside of tkTextBTree.c
 * should ever modify any of the fields in these structures, but it's OK to
 * use them for read-only information.
 */

typedef struct TkTextSearch {
    TkTextIndex curIndex;	/* Position of last tag transition returned by
				 * TkBTreeNextTag, or index of start of
				 * segment containing starting position for
				 * search if TkBTreeNextTag hasn't been called
				 * yet, or same as stopIndex if search is
				 * over. */
    TkTextSegment *segPtr;	/* Actual tag segment returned by last call to
				 * TkBTreeNextTag, or NULL if TkBTreeNextTag
				 * hasn't returned anything yet. */
    TkTextSegment *resultPtr;	/* Actual result of last search. */

    TkTextSegment *lastPtr;	/* Stop search before just before considering
				 * this segment. */
    TkTextLine *lastLinePtr;	/* The last line of the search range. */
    const TkTextTag *tagPtr;	/* Tag to search for. */
    struct TkText *textPtr;	/* Where we are searching. */
    TkTextSearchMode mode;	/* Search mode. */
    int tagon;			/* We have to search for toggle on? */
    int endOfText;		/* Search is ending at end of text? */
    int linesLeft;		/* Lines left to search (including curIndex and stopIndex).
    				 * When this becomes <= 0 the search is over. */



    int linesToEndOfText;	/* Add this to linesLeft when searching to end of text. */
} TkTextSearch;

/*
 * The following data structure describes a single tab stop. It must be kept
 * in sync with the 'tabOptionStrings' array in the function 'TkTextGetTabs'
 */

typedef enum {LEFT, RIGHT, CENTER, NUMERIC} TkTextTabAlign;

/*
 * The following are the supported styles of tabbing, used for the -tabstyle
 * option of the text widget. The first element is only used for tag options.
 */

typedef enum {
    TK_TEXT_TABSTYLE_NULL = -1,
    TK_TEXT_TABSTYLE_TABULAR,
    TK_TEXT_TABSTYLE_WORDPROCESSOR
} TkTextTabStyle;

MODULE_SCOPE const char *const tkTextTabStyleStrings[];

typedef struct TkTextTab {
    int location;		/* Offset in pixels of this tab stop from the
				 * left margin (lmargin2) of the text. */
    TkTextTabAlign alignment;	/* Where the tab stop appears relative to the
				 * text. */
} TkTextTab;

typedef struct TkTextTabArray {
    int numTabs;		/* Number of tab stops. */
    double lastTab;		/* The accurate fractional pixel position of
				 * the last tab. */
    double tabIncrement;	/* The accurate fractional pixel increment
				 * between interpolated tabs we have to create
				 * when we exceed numTabs. */
    TkTextTab tabs[1];/* Array of tabs. The actual size will be
				 * numTabs. THIS FIELD MUST BE THE LAST IN THE
				 * STRUCTURE. */
} TkTextTabArray;

/*
 * Enumeration defining the edit modes of the widget.
 */

typedef enum {
    TK_TEXT_EDIT_INSERT,	/* insert mode */
    TK_TEXT_EDIT_DELETE,	/* delete mode */
    TK_TEXT_EDIT_REPLACE,	/* replace mode */
    TK_TEXT_EDIT_OTHER		/* none of the above */
} TkTextEditMode;

/*
 * The following enum is used to define a type for the -state option of the Text widget.

 */

typedef enum {






    TK_TEXT_STATE_DISABLED,	/* Don't receive any text. */




    TK_TEXT_STATE_NORMAL,	/* Allows all operations. */

    TK_TEXT_STATE_READONLY	/* Do not allow user operations. */
} TkTextState;

/*
 * A data structure of the following type is shared between each text widget that are peers.

 */

struct TkRangeList;



struct TkText;



typedef struct TkSharedText {
    Tcl_Size refCount;		/* Reference count this shared object. */
    TkTextBTree tree;		/* B-tree representation of text and tags for
				 * widget. */
    Tcl_HashTable tagTable;	/* Hash table that maps from tag names to
				 * pointers to TkTextTag structures. The "sel"
				 * tag does not feature in this table, since
				 * there's one of those for each text peer. */
    size_t numEnabledTags;	/* Number of tags currently enabled; needed to keep track of

    				 * priorities. */
    size_t numTags;		/* Number of tags currently defined for widget. */
    size_t numMarks;		/* Number of marks, not including private or special marks. */
    size_t numPrivateMarks;	/* Number of private marks. */
    size_t numImages;		/* Number of embedded images; for information only. */
    size_t numWindows;	/* Number of embedded windows; for information only. */
    size_t tagInfoSize;	/* The required index size for tag info sets. */
    size_t tagEpoch;		/* Increase whenever a new tag has been created. */
    struct TkBitField *usedTags;
				/* Bit set of used tag indices. */
    struct TkBitField *elisionTags;
				/* Bit set of tags with elide information. */
    struct TkBitField *selectionTags;
				/* Bit set of all selection tags. */
    struct TkBitField *dontUndoTags;
				/* Bit set of all tags with -undo=no. */
    struct TkBitField *affectDisplayTags;
				/* Bit set of tags which are affecting the display. */
    struct TkBitField *notAffectDisplayTags;
				/* Bit set of tags which are *not* affecting the display. */
    struct TkBitField *affectDisplayNonSelTags;
				/* Bit set of tags which are affecting the display, but exclusive
				 * the special selection tags. */
    struct TkBitField *affectGeometryTags;
				/* Bit set of tags which are affecting the display geometry. */
    struct TkBitField *affectGeometryNonSelTags;
				/* Bit set of tags which are affecting the display geometry, but
				 * exclusive the special selection tags. */
    struct TkBitField *affectLineHeightTags;
				/* Bit set of tags which are affecting the line heigth. */
    TkTextTag **tagLookup;	/* Lookup vector for tags. */
    Tcl_HashTable markTable;	/* Hash table that maps from mark names to pointers to mark

    				 * segments. The special "insert" and "current" marks are not
				 * stored in this table, but directly accessed as fields of
				 * textPtr. */
    Tcl_HashTable windowTable;	/* Hash table that maps from window names to pointers to window

    				 * segments. If a window segment doesn't yet have an associated
				 * window, there is no entry for it here. */
    Tcl_HashTable imageTable;	/* Hash table that maps from image names to pointers to image

    				 * segments. If an image segment doesn't yet have an associated
				 * image, there is no entry for it here. */
    Tk_BindingTable tagBindingTable;
				/* Table of all tag bindings currently defined for this widget.

				 * NULL means that no bindings exist, so the table hasn't been
				 * created. Each "object" used for this table is the name of a
				 * tag. */
    TkTextSegment *startMarker;	/* The start marker, the content of this widget starts after this
    				 * merker. */
    TkTextSegment *endMarker;	/* If the end marker is at byte index zero, then the next newline
				 * does not belong to this widget, otherwise the next newline
				 * also belongs to this widget. */
    union TkTextTagSet *emptyTagInfoPtr;
    				/* Empty tag information. */
    size_t numMotionEventBindings;
				/* Number of tags with bindings to motion events. */
    size_t numElisionTags;	/* Number of tags with elide. */
    int allowUpdateLineMetrics;
				/* We don't allow line height computations before first Configure
				 * event has been accepted. */

    /*
     * Miscellaneous information.
     */

    int steadyMarks;		/* This option causes that any mark now simultaneous behaves like
    				 * an invisible character, this means that the relative order of
				 * marks will not change. */
    size_t imageCount;	/* Used for creating unique image names. */
    size_t countEmbWindows;	/* Used for counting embedded windows. */
    int triggerWatchCmd;	/* Whether we should trigger the watch command for any peer. */
    int triggerAlways;		/* Whether we should always trigger the watch command for any peer. */
    int haveToSetCurrentMark;	/* Flag whether a position change of the "current" mark has
    				 * been postponed in any peer. */

    /*
     * Miscellaneous mutual data.
     */

    size_t inspectEpoch;	/* Only used in TextInspectCmd. */
    size_t pickEpoch;		/* Only used in TkTextPickCurrent. */
    TkTextSegment *protectionMark[2];
    				/* Protection markers for segments .*/
    struct TkText *mainPeer;	/* Needed for unrelated index lookup. */

    /*
     * Information for displaying.
     */

    Tcl_HashTable breakInfoTable;
    				/* Hash table that maps from logical line pointers to BreakInfos for
				 * this widget. Note that this table is used in display stuff, but
				 * for technical reasons we have to keep this table in shared
				 * resource, because it's a shared table. */
    int breakInfoTableIsInitialized;
    				/* Flag whether breakInfoTable is initialized. */

    /*
     * Information related to the undo/redo functionality.
     */

    TkTextUndoStack undoStack;
				/* The undo/redo stack. */


    int maxUndoDepth;		/* The maximum depth of the undo stack expressed as the
    				 * maximum number of compound statements. */
    int maxRedoDepth;		/* The maximum depth of the redo stack expressed as the
    				 * maximum number of compound statements. */
    int maxUndoSize;		/* The maximum number of bytes kept on the undo stack. */
    int autoSeparators;		/* Non-zero means the separators will be inserted automatically. */

    int undo;			/* Non-zero means the undo/redo behaviour is enabled. */

    int isModified;		/* Flag indicating the computed 'modified' state of the text widget. */
    int isAltered;		/* Flag indicating the computed 'altered' state of the text widget. */
    int isIrreversible;	/* Flag indicating the computed 'irreversible' flag. Value
    				 * 'true' can never change to 'false', except the widget will
				 * be cleared, or the user is clearing. */
    int userHasSetModifiedFlag;/* Flag indicating if the user has set the 'modified' flag.
    				 * Value 'true' is superseding the computed value, but value
				 * 'false' is only clearing to the initial state of this flag. */
    int undoStackEvent;	/* Flag indicating whether <<UndoStack>> is already triggered. */
    int pushSeparator;		/* Flag indicating whether a separator has to be pushed before next
    				 * insert/delete item. */
    int undoTagging;		/* Global default value for TkTextTag::undo. */
    size_t undoLevel;		/* The undo level which corresponds to the unmodified state. */
    TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode was. */
    int lastUndoTokenType;	/* Type of newest undo token on stack. */
    TkTextTag **undoTagList;	/* Array of tags, prepared for undo stack. */
    TkTextMarkChange *undoMarkList;
    				/* Array of mark changes, prepared for undo stack. */
    uint32_t undoTagListCount;	/* Number of entries in array 'undoTagList'. */
    uint32_t undoTagListSize;	/* Size of array 'undoTagList'. */
    				/* Array of undo entries for mark operations. */
    uint32_t undoMarkListCount;	/* Number of entries in array 'undoMarkList'. */
    uint32_t undoMarkListSize;	/* Size of array 'undoMarkList'. */
    uint32_t insertDeleteUndoTokenCount;
    				/* Count number of tokens on undo stack for insert/delete actions. */
    TkTextUndoIndex prevUndoStartIndex;
    				/* Start index (left position) of previous undo operation; only for
				 * 'insert' and 'delete'. */
    TkTextUndoIndex prevUndoEndIndex;
    				/* End index (right position) of previous undo operation; only for
				 * 'insert' and 'delete'. */

    /*
     * Keep track of all the peers
     */

    struct TkText *peers;
    size_t numPeers;
} TkSharedText;

/*
 * The following enum is used to define a type for the -insertunfocussed
 * option of the Text widget.
 */

typedef enum {
    TK_TEXT_INSERT_NOFOCUS_HOLLOW,
    TK_TEXT_INSERT_NOFOCUS_NONE,
    TK_TEXT_INSERT_NOFOCUS_SOLID
} TkTextInsertUnfocussed;

/*
 * The tagging modes:
 */

typedef enum {
    TK_TEXT_TAGGING_WITHIN,	/* The new text will receive any tags that are present on both
				 * the character before and the character after the insertion point.
				 * This is the default. */
    TK_TEXT_TAGGING_GRAVITY,	/* The new text will receive any tags that are present at one side
    				 * of the insertion point: if insert cursor has gravity right then
				 * receive the tags of the character after the insertion point,
				 * otherwise it will receive the tags of the character before the
				 * insertion point (supports Arabian, and the like). */
    TK_TEXT_TAGGING_NONE	/* The new text will not receive any tags from adjacent characters. */
} TkTextTagging;

/*
 * A data structure of the following type is kept for each text widget that
 * currently exists for this process:
 */

struct TkTextStringList;

typedef struct TkText {
    /*
     * Information related to and accessed by widget peers and the
     * TkSharedText handling routines.
     */

    TkSharedText *sharedTextPtr;/* Shared section of all peers. */
    struct TkText *next;	/* Next in list of linked peers. */
#if SUPPORT_DEPRECATED_STARTLINE_ENDLINE
    TkTextLine *startLine;	/* First B-tree line to show, or NULL to start at the beginning.
    				 * Note that this feature is deprecated and should be removed some day.
				 */
    TkTextLine *endLine;	/* Last B-tree line to show, or NULL for up to the end.
    				 * Note that this feature is deprecated and should be removed some day.
				 */
#endif
    TkTextSegment *startMarker;	/* First B-Tree segment (mark) belonging to this widget. */
    TkTextSegment *endMarker;	/* Last B-Tree segment (mark) belonging to this widget */
    Tcl_Obj *newStartIndex;	/* New position for start marker. */
    Tcl_Obj *newEndIndex;	/* New position for end marker. */
    int pixelReference;		/* Counter into the current tree reference
				 * index corresponding to this widget. */
    int abortSelections;	/* Set to 1 whenever the text is modified in a
				 * way that interferes with selection
				 * retrieval: used to abort incremental
				 * selection retrievals. */
    int pendingAfterSync;	/* RunAfterSyncCmd is in event queue. */
    int pendingFireEvent;	/* FireWidgetViewSyncEvent is in event queue. */
    int sendSyncEvent;		/* Send <<WidgetViewSync>> event as soon as the line metric is
    				 * up-to-date, even if we have no sync state change. */
    int prevSyncState;		/* Previous sync state of the line-height calculation. */
    int dontRepick;		/* Set to 'true' during scroll operation, but only when -responsiveness
    				 * is greater than zero. */

    /*
     * Standard Tk widget information and text-widget specific items
     */

    Tk_Window tkwin;		/* Window that embodies the text. NULL means
				 * that the window has been destroyed but the
				 * data structures haven't yet been cleaned
				 * up.*/
    Display *display;		/* Display for widget. Needed, among other
				 * things, to allow resources to be freed even
				 * after tkwin has gone away. */
    Tcl_Interp *interp;		/* Interpreter associated with widget. Used to
				 * delete widget command. */
    Tcl_Command widgetCmd;	/* Token for text's widget command. */
    TkTextState state;		/* Either TK_TEXT_STATE_NORMAL, TK_TEXT_STATE_READONLY, or
    				 * TK_TEXT_STATE_DISABLED. A text widget is also read-only when
				 * disabled. */

    /*
     * Default information for displaying (may be overridden by tags applied
     * to ranges of characters).
     */

    Tk_3DBorder border;		/* Structure used to draw 3-D border and
675
676
677
678
679
680
681







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698







699
700
701
702
703
704
705
706







707
708
709
710
711
712
713
714
715





716
717
718
719
720







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750



751
752
753
754
755
756
757
758
759
760
761
762


















763
764
765
766
767
768
769





770
771
772
773

774
775
776




777
778
779
780
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
				 * don't draw a highlight. */
    XColor *highlightBgColorPtr;
				/* Color for drawing traversal highlight area
				 * when highlight is off. */
    XColor *highlightColorPtr;	/* Color for drawing traversal highlight. */
    Tk_Cursor cursor;		/* Current cursor for window, or NULL. */
    XColor *fgColor;		/* Default foreground color for text. */







    Tk_Font tkfont;		/* Default font for displaying text. */
    int charWidth;		/* Width of average character in default
				 * font. */
    int charHeight;		/* Height of average character in default
				 * font, including line spacing. */
    int spacing1;		/* Default extra spacing above first display
				 * line for each text line. */
    int spacing2;		/* Default extra spacing between display lines
				 * for the same text line. */
    int spacing3;		/* Default extra spacing below last display
				 * line for each text line. */
    Tcl_Obj *tabOptionPtr; 	/* Value of -tabs option string. */
    TkTextTabArray *tabArrayPtr;
				/* Information about tab stops (malloc'ed).
				 * NULL means perform default tabbing
				 * behavior. */
    int tabStyle;		/* One of TABULAR or WORDPROCESSOR. */








    /*
     * Additional information used for displaying:
     */

    TkWrapMode wrapMode;	/* How to handle wrap-around. Must be
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */







    int width, height;		/* Desired dimensions for window, measured in
				 * characters. */
    int setGrid;		/* Non-zero means pass gridding information to
				 * window manager. */
    int prevWidth, prevHeight;	/* Last known dimensions of window; used to
				 * detect changes in size. */
    TkTextIndex topIndex;	/* Identifies first character in top display
				 * line of window. */
    struct TextDInfo *dInfoPtr;	/* Information maintained by tkTextDisp.c. */






    /*
     * Information related to selection.
     */








    TkTextTag *selTagPtr;	/* Pointer to "sel" tag. Used to tell when a
				 * new selection has been made. */
    Tk_3DBorder selBorder;	/* Border and background for selected
				 * characters. This is a copy of information
				 * in *selTagPtr, so it shouldn't be
				 * explicitly freed. */
    Tk_3DBorder inactiveSelBorder;
				/* Border and background for selected
				 * characters when they don't have the
				 * focus. */
    int selBorderWidth;		/* Width of border around selection. */
    Tcl_Obj *selBorderWidthPtr;	/* Width of border around selection. */
    XColor *selFgColorPtr;	/* Foreground color for selected text. This is
				 * a copy of information in *selTagPtr, so it
				 * shouldn't be explicitly freed. */
    int exportSelection;	/* Non-zero means tie "sel" tag to X
				 * selection. */

    TkTextIndex selIndex;	/* Used during multi-pass selection
				 * retrievals. This index identifies the next
				 * character to be returned from the
				 * selection. */

    /*
     * Information related to insertion cursor:
     */

    TkTextSegment *insertMarkPtr;
				/* Points to segment for "insert" mark. */
    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. */



    int insertWidth;		/* Total width of insert cursor. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor */
    TkTextInsertUnfocussed insertUnfocussed;
				/* How to display the insert cursor when the
				 * text widget does not have the focus. */
    int insertOnTime;		/* Number of milliseconds cursor should spend
				 * in "on" state for each blink. */
    int insertOffTime;		/* Number of milliseconds cursor should spend
				 * in "off" state for each blink. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */



















    /*
     * Information used for event bindings associated with tags:
     */

    TkTextSegment *currentMarkPtr;
				/* Pointer to segment for "current" mark, or





				 * NULL if none. */
    XEvent pickEvent;		/* The event from which the current character
				 * was chosen. Must be saved so that we can
				 * repick after modifications to the text. */

    int numCurTags;		/* Number of tags associated with character at
				 * current mark. */
    TkTextTag **curTagArrayPtr;	/* Pointer to array of tags for current mark,




				 * or NULL if none. */

    /*
     * Miscellaneous additional information:
     */

    char *takeFocus;		/* Value of -takeFocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    char *xScrollCmd;		/* Prefix of command to issue to update
				 * horizontal scrollbar when view changes. */
    char *yScrollCmd;		/* Prefix of command to issue to update
				 * vertical scrollbar when view changes. */
    int flags;			/* Miscellaneous flags; see below for
				 * definitions. */
    Tk_OptionTable optionTable;	/* Token representing the configuration
				 * specifications. */
    TkSizeT refCount;		/* Number of cached TkTextIndex objects
				 * refering to us. */
    int insertCursorType;	/* 0 = standard insertion cursor, 1 = block






				 * cursor. */


    /*
     * Copies of information from the shared section relating to the undo/redo

     * functonality





     */

    int undo;			/* Non-zero means the undo/redo behaviour is
				 * enabled. */
    int maxUndo;		/* The maximum depth of the undo stack
				 * expressed as the maximum number of compound

				 * statements. */

    int autoSeparators;		/* Non-zero means the separators will be

				 * inserted automatically. */




    Tcl_Obj *afterSyncCmd;	/* Command to be executed when lines are up to
                                 * date */



} TkText;

/*
 * Flag values for TkText records:
 *
 * GOT_SELECTION:		Non-zero means we've already claimed the
 *				selection.
 * INSERT_ON:			Non-zero means insertion cursor should be
 *				displayed on screen.
 * GOT_FOCUS:			Non-zero means this window has the input
 *				focus.
 * BUTTON_DOWN:			1 means that a mouse button is currently down;
 *				this is used to implement grabs for the
 *				duration of button presses.
 * UPDATE_SCROLLBARS:		Non-zero means scrollbar(s) should be updated
 *				during next redisplay operation.
 * NEED_REPICK			This appears unused and should probably be
 *				ignored.
 * OPTIONS_FREED		The widget's options have been freed.
 * DESTROYED			The widget is going away.

 */

#define GOT_SELECTION		1
#define INSERT_ON		2
#define GOT_FOCUS		4
#define BUTTON_DOWN		8
#define UPDATE_SCROLLBARS	0x10
#define NEED_REPICK		0x20
#define OPTIONS_FREED		0x40
#define DESTROYED		0x80

















/*
 * Records of the following type define segment types in terms of a collection
 * of procedures that may be called to manipulate segments of that type.
 */

typedef TkTextSegment *	Tk_SegSplitProc(struct TkTextSegment *segPtr,
			    TkSizeT index);
typedef int		Tk_SegDeleteProc(struct TkTextSegment *segPtr,
			    TkTextLine *linePtr, int treeGone);
typedef TkTextSegment *	Tk_SegCleanupProc(struct TkTextSegment *segPtr,
			    TkTextLine *linePtr);
typedef void		Tk_SegLineChangeProc(struct TkTextSegment *segPtr,
			    TkTextLine *linePtr);
typedef int		Tk_SegLayoutProc(struct TkText *textPtr,
			    struct TkTextIndex *indexPtr,
			    TkTextSegment *segPtr, TkSizeT offset, int maxX,
			    TkSizeT maxChars, int noCharsYet, TkWrapMode wrapMode,
			    struct TkTextDispChunk *chunkPtr);
typedef void		Tk_SegCheckProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);


typedef struct Tk_SegType {
    const char *name;		/* Name of this kind of segment. */

    int leftGravity;		/* If a segment has zero size (e.g. a mark or
				 * tag toggle), does it attach to character to
				 * its left or right? 1 means left, 0 means
				 * right. */
    Tk_SegSplitProc *splitProc;	/* Procedure to split large segment into two
				 * smaller ones. */
    Tk_SegDeleteProc *deleteProc;
				/* Procedure to call to delete segment. */
    Tk_SegCleanupProc *cleanupProc;
				/* After any change to a line, this procedure
				 * is invoked for all segments left in the
				 * line to perform any cleanup they wish
				 * (e.g. joining neighboring segments). */
    Tk_SegLineChangeProc *lineChangeProc;
				/* Invoked when a segment is about to be moved
				 * from its current line to an earlier line
				 * because of a deletion. The linePtr is that
				 * for the segment's old line. CleanupProc
				 * will be invoked after the deletion is
				 * finished. */
    Tk_SegLayoutProc *layoutProc;
				/* Returns size information when figuring out
				 * what to display in window. */
    Tk_SegCheckProc *checkProc;	/* Called during consistency checks to check
				 * internal consistency of segment. */


} Tk_SegType;







/*
 * The following type and items describe different flags for text widget items
 * to count. They are used in both tkText.c and tkTextIndex.c, in
 * 'CountIndices', 'TkTextIndexBackChars', 'TkTextIndexForwChars', and
 * 'TkTextIndexCount'.
 */

typedef int TkTextCountType;


#define COUNT_CHARS 0
#define COUNT_INDICES 1
#define COUNT_DISPLAY 2
#define COUNT_DISPLAY_CHARS (COUNT_CHARS | COUNT_DISPLAY)


#define COUNT_DISPLAY_INDICES (COUNT_INDICES | COUNT_DISPLAY)


/*



 * The following structure is used to keep track of elided text taking account




 * of different tag priorities, it is need for quick calculations of whether a
 * single index is elided, and to start at a given index and maintain a
 * correct elide state as we move or count forwards or backwards.
 */










#define LOTSA_TAGS 1000
typedef struct TkTextElideInfo {
    int numTags;		/* Total tags in widget. */
    int elide;			/* Is the state currently elided. */
    int elidePriority;		/* Tag priority controlling elide state. */
    TkTextSegment *segPtr;	/* Segment to look at next. */
    int segOffset;		/* Offset of segment within line. */
    int deftagCnts[LOTSA_TAGS];
    TkTextTag *deftagPtrs[LOTSA_TAGS];


    int *tagCnts;		/* 0 or 1 depending if the tag with that

				 * priority is on or off. */

    TkTextTag **tagPtrs;	/* Only filled with a tagPtr if the
				 * corresponding tagCnt is 1. */



} TkTextElideInfo;

/*
 * The constant below is used to specify a line when what is really wanted is
 * the entire text. For now, just use a very big number.

 */

#define TK_END_OF_TEXT		1000000


/*
 * The following definition specifies the maximum number of characters needed
 * in a string to hold a position specifier.
 */

#define TK_POS_CHARS		30









/*
 * Mask used for those options which may impact the pixel height calculations
 * of individual lines displayed in the widget.
 */

#define TK_TEXT_LINE_GEOMETRY	1

/*







 * Mask used for those options which may impact the start and end lines used
 * in the widget.
 */


#define TK_TEXT_LINE_RANGE	2










/*
 * Used as 'action' values in calls to TkTextInvalidateLineMetrics
 */


#define TK_TEXT_INVALIDATE_ONLY		0
#define TK_TEXT_INVALIDATE_INSERT	1
#define TK_TEXT_INVALIDATE_DELETE	2




/*
 * Used as special 'pickPlace' values in calls to TkTextSetYView. Zero or
 * positive values indicate a number of pixels.
 */

#define TK_TEXT_PICKPLACE	-1
#define TK_TEXT_NOPIXELADJUST	-2

/*
 * Declarations for variables shared among the text-related files:
 */

MODULE_SCOPE int	tkBTreeDebug;
MODULE_SCOPE int	tkTextDebug;
MODULE_SCOPE const Tk_SegType tkTextCharType;


MODULE_SCOPE const Tk_SegType tkTextLeftMarkType;
MODULE_SCOPE const Tk_SegType tkTextRightMarkType;
MODULE_SCOPE const Tk_SegType tkTextToggleOnType;
MODULE_SCOPE const Tk_SegType tkTextToggleOffType;
MODULE_SCOPE const Tk_SegType tkTextEmbWindowType;
MODULE_SCOPE const Tk_SegType tkTextEmbImageType;

/*


 * Convenience macros for use by B-tree clients which want to access pixel

 * information on each line. Currently only used by TkTextDisp.c


 */






#define TkBTreeLinePixelCount(text, line) \


	(line)->pixels[2*(text)->pixelReference]




#define TkBTreeLinePixelEpoch(text, line) \







	(line)->pixels[1+2*(text)->pixelReference]

















/*
 * Declarations for procedures that are used by the text-related files but
 * shouldn't be used anywhere else in Tk (or by Tk clients):
 */



MODULE_SCOPE int	TkBTreeAdjustPixelHeight(const TkText *textPtr,
			    TkTextLine *linePtr, int newPixelHeight,




			    int mergedLogicalLines);


MODULE_SCOPE int	TkBTreeCharTagged(const TkTextIndex *indexPtr,
			    TkTextTag *tagPtr);
MODULE_SCOPE void	TkBTreeCheck(TkTextBTree tree);
MODULE_SCOPE TkTextBTree TkBTreeCreate(TkSharedText *sharedTextPtr);
MODULE_SCOPE void	TkBTreeAddClient(TkTextBTree tree, TkText *textPtr,
			    int defaultHeight);
MODULE_SCOPE void	TkBTreeClientRangeChanged(TkText *textPtr,
			    int defaultHeight);
MODULE_SCOPE void	TkBTreeRemoveClient(TkTextBTree tree,
			    TkText *textPtr);
MODULE_SCOPE void	TkBTreeDestroy(TkTextBTree tree);

MODULE_SCOPE void	TkBTreeDeleteIndexRange(TkTextBTree tree,
			    TkTextIndex *index1Ptr, TkTextIndex *index2Ptr);

MODULE_SCOPE TkSizeT	TkBTreeEpoch(TkTextBTree tree);



MODULE_SCOPE TkTextLine *TkBTreeFindLine(TkTextBTree tree,
			    const TkText *textPtr, int line);
MODULE_SCOPE TkTextLine *TkBTreeFindPixelLine(TkTextBTree tree,
			    const TkText *textPtr, int pixels,





			    int *pixelOffset);






MODULE_SCOPE TkTextTag **TkBTreeGetTags(const TkTextIndex *indexPtr,


			    const TkText *textPtr, int *numTagsPtr);


MODULE_SCOPE void	TkBTreeInsertChars(TkTextBTree tree,















			    TkTextIndex *indexPtr, const char *string);
MODULE_SCOPE int	TkBTreeLinesTo(const TkText *textPtr,
			    TkTextLine *linePtr);
MODULE_SCOPE int	TkBTreePixelsTo(const TkText *textPtr,
			    TkTextLine *linePtr);
MODULE_SCOPE void	TkBTreeLinkSegment(TkTextSegment *segPtr,
			    TkTextIndex *indexPtr);


MODULE_SCOPE TkTextLine *TkBTreeNextLine(const TkText *textPtr,
			    TkTextLine *linePtr);


MODULE_SCOPE int	TkBTreeNextTag(TkTextSearch *searchPtr);
MODULE_SCOPE int	TkBTreeNumPixels(TkTextBTree tree,






			    const TkText *textPtr);


MODULE_SCOPE TkTextLine *TkBTreePreviousLine(TkText *textPtr,

			    TkTextLine *linePtr);
MODULE_SCOPE int	TkBTreePrevTag(TkTextSearch *searchPtr);
MODULE_SCOPE void	TkBTreeStartSearch(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    TkTextSearch *searchPtr);
MODULE_SCOPE void	TkBTreeStartSearchBack(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    TkTextSearch *searchPtr);

MODULE_SCOPE int	TkBTreeTag(TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    int add);






MODULE_SCOPE void	TkBTreeUnlinkSegment(TkTextSegment *segPtr,

			    TkTextLine *linePtr);



MODULE_SCOPE void	TkTextBindProc(ClientData clientData,
			    XEvent *eventPtr);
MODULE_SCOPE void	TkTextSelectionEvent(TkText *textPtr);












MODULE_SCOPE int	TkTextIndexBbox(TkText *textPtr,
			    const TkTextIndex *indexPtr, int *xPtr, int *yPtr,
			    int *widthPtr, int *heightPtr, int *charWidthPtr);
MODULE_SCOPE int	TkTextCharLayoutProc(TkText *textPtr,
			    TkTextIndex *indexPtr, TkTextSegment *segPtr,
			    TkSizeT offset, int maxX, TkSizeT maxChars, int noBreakYet,
			    TkWrapMode wrapMode, TkTextDispChunk *chunkPtr);
MODULE_SCOPE void	TkTextCreateDInfo(TkText *textPtr);
MODULE_SCOPE int	TkTextDLineInfo(TkText *textPtr,
			    const TkTextIndex *indexPtr, int *xPtr, int *yPtr,
			    int *widthPtr, int *heightPtr, int *basePtr);
MODULE_SCOPE void	TkTextEmbWinDisplayProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr, int x, int y,
			    int lineHeight, int baseline, Display *display,
			    Drawable dst, int screenY);
MODULE_SCOPE TkTextTag *TkTextCreateTag(TkText *textPtr,
			    const char *tagName, int *newTag);
MODULE_SCOPE void	TkTextFreeDInfo(TkText *textPtr);
MODULE_SCOPE void	TkTextDeleteTag(TkText *textPtr, TkTextTag *tagPtr);
MODULE_SCOPE void	TkTextFreeTag(TkText *textPtr, TkTextTag *tagPtr);

MODULE_SCOPE int	TkTextGetObjIndex(Tcl_Interp *interp, TkText *textPtr,
			    Tcl_Obj *idxPtr, TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextSharedGetObjIndex(Tcl_Interp *interp,

			    TkSharedText *sharedTextPtr, Tcl_Obj *idxPtr,
			    TkTextIndex *indexPtr);
MODULE_SCOPE const	TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp,
			    TkText *textPtr, Tcl_Obj *objPtr);
MODULE_SCOPE TkTextTabArray *TkTextGetTabs(Tcl_Interp *interp,

			    TkText *textPtr, Tcl_Obj *stringPtr);


MODULE_SCOPE void	TkTextFindDisplayLineEnd(TkText *textPtr,
			    TkTextIndex *indexPtr, int end, int *xOffset);





MODULE_SCOPE void	TkTextIndexBackChars(const TkText *textPtr,
			    const TkTextIndex *srcPtr, int count,




			    TkTextIndex *dstPtr, TkTextCountType type);
MODULE_SCOPE int	TkTextIndexCmp(const TkTextIndex *index1Ptr,


			    const TkTextIndex *index2Ptr);
MODULE_SCOPE int	TkTextIndexCountBytes(const TkText *textPtr,
			    const TkTextIndex *index1Ptr,






















			    const TkTextIndex *index2Ptr);


MODULE_SCOPE int	TkTextIndexCount(const TkText *textPtr,



			    const TkTextIndex *index1Ptr,

			    const TkTextIndex *index2Ptr,
			    TkTextCountType type);
MODULE_SCOPE void	TkTextIndexForwChars(const TkText *textPtr,
			    const TkTextIndex *srcPtr, int count,
			    TkTextIndex *dstPtr, TkTextCountType type);
MODULE_SCOPE void	TkTextIndexOfX(TkText *textPtr, int x,
			    TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexYPixels(TkText *textPtr,
			    const TkTextIndex *indexPtr);
MODULE_SCOPE TkTextSegment *TkTextIndexToSeg(const TkTextIndex *indexPtr,
			    TkSizeT *offsetPtr);
MODULE_SCOPE void	TkTextLostSelection(ClientData clientData);
MODULE_SCOPE TkTextIndex *TkTextMakeCharIndex(TkTextBTree tree, TkText *textPtr,
			    int lineIndex, int charIndex,
			    TkTextIndex *indexPtr);


MODULE_SCOPE int	TkTextMeasureDown(TkText *textPtr,












			    TkTextIndex *srcPtr, int distance);

MODULE_SCOPE void	TkTextFreeElideInfo(TkTextElideInfo *infoPtr);


MODULE_SCOPE int	TkTextIsElided(const TkText *textPtr,
			    const TkTextIndex *indexPtr,
			    TkTextElideInfo *infoPtr);
MODULE_SCOPE int	TkTextMakePixelIndex(TkText *textPtr,
			    int pixelIndex, TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextInvalidateLineMetrics(
			    TkSharedText *sharedTextPtr, TkText *textPtr,
			    TkTextLine *linePtr, int lineCount, int action);
MODULE_SCOPE int	TkTextUpdateLineMetrics(TkText *textPtr, int lineNum,
			    int endLine, int doThisMuch);
MODULE_SCOPE int	TkTextUpdateOneLine(TkText *textPtr,
			    TkTextLine *linePtr, int pixelHeight,
			    TkTextIndex *indexPtr, int partialCalc);
MODULE_SCOPE int	TkTextMarkCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);


MODULE_SCOPE int	TkTextMarkNameToIndex(TkText *textPtr,
			    const char *name, TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextMarkSegToIndex(TkText *textPtr,
			    TkTextSegment *markPtr, TkTextIndex *indexPtr);





















MODULE_SCOPE void	TkTextEventuallyRepick(TkText *textPtr);
MODULE_SCOPE Bool	TkTextPendingsync(TkText *textPtr);
MODULE_SCOPE void	TkTextPickCurrent(TkText *textPtr, XEvent *eventPtr);













MODULE_SCOPE void	TkTextPixelIndex(TkText *textPtr, int x, int y,
			    TkTextIndex *indexPtr, int *nearest);
MODULE_SCOPE Tcl_Obj *	TkTextNewIndexObj(TkText *textPtr,
			    const TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextRedrawRegion(TkText *textPtr, int x, int y,
			    int width, int height);
MODULE_SCOPE void	TkTextRedrawTag(TkSharedText *sharedTextPtr,
			    TkText *textPtr, TkTextIndex *index1Ptr,
			    TkTextIndex *index2Ptr, TkTextTag *tagPtr,
			    int withTag);
MODULE_SCOPE void	TkTextRelayoutWindow(TkText *textPtr, int mask);


MODULE_SCOPE int	TkTextScanCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextSeeCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextSegToOffset(const TkTextSegment *segPtr,
			    const TkTextLine *linePtr);
MODULE_SCOPE void	TkTextSetYView(TkText *textPtr,
			    TkTextIndex *indexPtr, int pickPlace);
MODULE_SCOPE int	TkTextTagCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextImageCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextImageIndex(TkText *textPtr,
			    const char *name, TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextWindowCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextWindowIndex(TkText *textPtr, const char *name,
			    TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);

MODULE_SCOPE void	TkTextWinFreeClient(Tcl_HashEntry *hPtr,





















































































			    TkTextEmbWindowClient *client);



MODULE_SCOPE void       TkTextRunAfterSyncCmd(ClientData clientData);










#endif /* _TKTEXT */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
>
>
>
>
>



|
|











|
>
>
>
>
>
>
>





|
<
|
>
>
>
>
>
>
>









>
>
>
>
>





>
>
>
>
>
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<


>













>
>
>












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
>
>
>
>
>
|
|
|
|
>
|
|
<
>
>
>
>
|





|


|

|

|
<
|
<
|
<
|
>
>
>
>
>
>
|
>


|
>
|
>
>
>
>
>




|
|
>
|
>
|
>
|
>
>
>
>
|
|
>
>
>




















>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






<
<
|
<
<
<
|
<
<
|
<
|
|
|
<
>



>
|
<
<
|
<
<


|
<
<
<
<
<
<
<
<
<
|
|

|
|
|
|
>
>


>
>
>
>
>
>







|
|
>
|
|
|
|
>
>
|
>


>
>
>
|
>
>
>
>
|
<
<
|
>
>
>
>
>
>
>
>
>

|
<
<
<
<
<
|
|
|
>
>
|
>
|
>
|
<
>
>
>
|


<
<
>


|
>








>
>
>
>
>
>
>
>





|


>
>
>
>
>
>
>
|
|


>
|
>
>
>
>
>
>
>
>
>





>
|
|
|
>
>
>
















>
>


|
|

|


>
>
|
>
|
>
>


>
>
>
>
>
|
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
|
|
>
>
>
>
|
>
>
|
<

|
|
<
|
<
|
<

>
|
|
>
|
>
>
>
|
|
|
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
<
|
|
>
>
|
|
>
>

|
>
>
>
>
>
>
|
>
>
|
>
|
<
|
|
|
|
|
|
>
|
|
|
>
>
>
>
>
>
|
>
|
>
>
>
|
<

>
>
>
>
>
>
>
>
>
>
>
>

|
|
|
<
|
|

|
|
|
|
<
<
|
<
|
|
|
|
>
|
|
<
>
|
|
|
|
|
>
|
>
>
|
|
>
>
>
>
>
|
|
>
>
>
>
|
|
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
|
>
|

|
<
|
|
<
|
<
<
<
<
<
<
<
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
|
|
|
|
<
|
|
|
|
<
<
<
<

|
>
>
|
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|

>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
<
|
<
|
|
|
<

>
>

|

|
<
<
|
<

|

|
|
|

|
|
|

|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>









1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420













1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506

1507

1508

1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601


1602



1603


1604

1605
1606
1607

1608
1609
1610
1611
1612
1613


1614


1615
1616
1617









1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663


1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675





1676
1677
1678
1679
1680
1681
1682
1683
1684
1685

1686
1687
1688
1689
1690
1691


1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845

1846
1847
1848

1849

1850

1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901

1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923

1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946

1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963

1964
1965
1966
1967
1968
1969
1970


1971

1972
1973
1974
1975
1976
1977
1978

1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042

2043
2044

2045







2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069

2070
2071
2072
2073




2074
2075
2076
2077
2078

2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120

2121

2122
2123
2124

2125
2126
2127
2128
2129
2130
2131


2132

2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
				 * don't draw a highlight. */
    XColor *highlightBgColorPtr;
				/* Color for drawing traversal highlight area
				 * when highlight is off. */
    XColor *highlightColorPtr;	/* Color for drawing traversal highlight. */
    Tk_Cursor cursor;		/* Current cursor for window, or NULL. */
    XColor *fgColor;		/* Default foreground color for text. */
    XColor *eolColor;		/* Foreground color for end of line symbol, can be NULL. */
    XColor *eotColor;		/* Foreground color for end of text symbol, can be NULL. */
    Tcl_Obj *eolCharPtr;	/* Use this character for displaying end of line. Can be NULL or empty,
    				 * in this case the default char U+00B6 (pilcrow) will be used. */
    Tcl_Obj *eotCharPtr;	/* Use this character for displaying end of text. Can be NULL or empty,
    				 * in this case the default char U+00B6 (pilcrow) will be used. */
    XColor *hyphenColor;	/* Foreground color for soft hyphens, can be NULL. */
    Tk_Font tkfont;		/* Default font for displaying text. */
    int charWidth;		/* Width of average character in default
				 * font. */
    int spaceWidth;		/* Width of space character in default font. */
    int lineHeight;		/* Height of line in default font, including line spacing. */
    int spacing1;		/* Default extra spacing above first display
				 * line for each text line. */
    int spacing2;		/* Default extra spacing between display lines
				 * for the same text line. */
    int spacing3;		/* Default extra spacing below last display
				 * line for each text line. */
    Tcl_Obj *tabOptionPtr; 	/* Value of -tabs option string. */
    TkTextTabArray *tabArrayPtr;
				/* Information about tab stops (malloc'ed).
				 * NULL means perform default tabbing
				 * behavior. */
    int tabStyle;		/* One of TK_TEXT_TABSTYLE_TABULAR or TK_TEXT_TABSTYLE_WORDPROCESSOR. */
    Tk_Justify justify;		/* How to justify text: TK_JUSTIFY_LEFT, TK_JUSTIFY_RIGHT,
    				 * TK_JUSTIFY_CENTER, or TK_JUSTIFY_FULL. */
    Tcl_Obj *hyphenRulesPtr;	/* The hyphen rules string. */
    int hyphenRules;		/* The hyphen rules, only useful for soft hyphen segments. */
    Tcl_Obj *langPtr;		/* -lang option string. NULL means option not specified. */
    char lang[3];		/* The specified language for the text content, only enabled if not
    				 * NUL. */

    /*
     * Additional information used for displaying:
     */

    TkWrapMode wrapMode;	/* How to handle wrap-around. Must be TEXT_WRAPMODE_CHAR,

    				 * TEXT_WRAPMODE_WORD, TEXT_WRAPMODE_CODEPOINT, or TEXT_WRAPMODE_NONE. */
    TkTextSpaceMode spaceMode;	/* How to handle displaying spaces. Must be TEXT_SPACEMODE_NONE,
    				 * TEXT_SPACEMODE_EXACT, or TEXT_SPACEMODE_TRIM. */
    int useHyphenSupport;	/* Indicating the hypenation support. */
    int hyphenate;		/* Indicating whether the soft hyphens will be used for line breaks
    				 * (if not in state TK_TEXT_STATE_NORMAL). */
    int useUniBreak;		/* Use library libunibreak for line break computation, otherwise the
    				 * internal algorithm will be used. */
    int width, height;		/* Desired dimensions for window, measured in
				 * characters. */
    int setGrid;		/* Non-zero means pass gridding information to
				 * window manager. */
    int prevWidth, prevHeight;	/* Last known dimensions of window; used to
				 * detect changes in size. */
    TkTextIndex topIndex;	/* Identifies first character in top display
				 * line of window. */
    struct TextDInfo *dInfoPtr;	/* Information maintained by tkTextDisp.c. */
    int showEndOfLine;		/* Flag whether the end of line symbol will be shown at end of
    				 * each logical line. */
    int showEndOfText;		/* Flag whether the end of text symbol will be shown at end of text. */
    int syncTime;		/* Synchronization timeout, used for line metric calculation, default is
    				 * 200. */

    /*
     * Information related to selection.
     */

    TkTextSharedAttrs selAttrs;	/* Contains the following attributes: border, inactiveBorder,
				 * fgColor, inactiveFgColor, and borderWidth. These attributes will
				 * be shared with attributes from "sel" tag. */
    TkTextSharedAttrs textConfigAttrs;
    				/* Contains the original attributes of the text widget. */
    TkTextSharedAttrs selTagConfigAttrs;
    				/* Contains the original attributes of the "sel" tag. */
    TkTextTag *selTagPtr;	/* Pointer to "sel" tag. Used to tell when a new selection
    				 * has been made. */













    int exportSelection;	/* Non-zero means tie "sel" tag to X
				 * selection. */
    TkTextSearch selSearch;	/* Used during multi-pass selection retrievals. */
    TkTextIndex selIndex;	/* Used during multi-pass selection
				 * retrievals. This index identifies the next
				 * character to be returned from the
				 * selection. */

    /*
     * Information related to insertion cursor:
     */

    TkTextSegment *insertMarkPtr;
				/* Points to segment for "insert" mark. */
    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. */
    XColor *insertFgColor;	/* Foreground color for text behind a block cursor.
    				 * NULL means no value specified here. */
    int showInsertFgColor;	/* Flag whether insertFgColor is relevant. */
    int insertWidth;		/* Total width of insert cursor. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor */
    TkTextInsertUnfocussed insertUnfocussed;
				/* How to display the insert cursor when the
				 * text widget does not have the focus. */
    int insertOnTime;		/* Number of milliseconds cursor should spend
				 * in "on" state for each blink. */
    int insertOffTime;		/* Number of milliseconds cursor should spend
				 * in "off" state for each blink. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    TkTextTagging tagging;	/* Tagging mode, used when inserting chars; the mode how to extend
				 * tagged ranges of characters. */

    /*
     * Information used for the watch of changes:
     */

    Tcl_Obj *watchCmd;		/* The command prefix for the "watch" command. */
    int triggerAlways;		/* Whether we should trigger for any modification. */
    TkTextIndex insertIndex;	/* Saved position of insertion cursor. */

    /*
     * Information related to the language support functionality.
     */

    char *brksBuffer;		/* Buffer for line break information, will be filled by
    				 * TkTextComputeBreakLocations (for TEXT_WRAPMODE_CODEPOINT). */
    size_t brksBufferSize;	/* Size of line break buffer. */

    /*
     * Information used for event bindings associated with tags:
     */

    TkTextSegment *currentMarkPtr;
				/* Pointer to segment for "current" mark, or NULL if none. */
    TkTextIndex currentMarkIndex;
    				/* The index of the "current" mark, needed for postponing the
				 * insertion of the "current" mark segment.
				 */
    int haveToSetCurrentMark;	/* Flag whether a position change of the "current" mark has
    				 * been postponed. */
    XEvent pickEvent;		/* The event from which the current character was chosen.
    				 * Must be saved so that we can repick after modifications
				 * to the text. */
    union TkTextTagSet *curTagInfoPtr;
    				/* Set of tags associated with character at current mark. */
    uint32_t lastChunkID;	/* Cache chunk ID of last mouse hovering. */

    int32_t lastX;		/* Cache x coordinate of last mouse hovering. */
    int32_t lastLineY;		/* Cache y coordinate of the display line of last mouse hovering.
    				 * If lastLineY == INT_MAX then it is undetermined (initialized).
				 * If lastLineY == INT_MIN then it is on the border.
				 * Otherwise it's inside a display chunk. */

    /*
     * Miscellaneous additional information:
     */

    Tcl_Obj *takeFocusObj;		/* Value of -takeFocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    Tcl_Obj *xScrollCmdObj;		/* Prefix of command to issue to update
				 * horizontal scrollbar when view changes. */
    Tcl_Obj *yScrollCmdObj;		/* Prefix of command to issue to update
				 * vertical scrollbar when view changes. */
    unsigned flags;		/* Miscellaneous flags; see below for definitions. */

    Tk_OptionTable optionTable;	/* Token representing the configuration specifications. */

    size_t refCount;		/* Number of objects referring to us. */

    int blockCursorType;	/* false = standard insertion cursor, true = block cursor. */
    int accelerateTagSearch;	/* Update B-Tree tag information for search? */
    int responsiveness;		/* The delay in ms before repick the mouse position (behavior when
				 * scrolling the widget). */
    size_t uniqueIdCounter;	/* Used for the generation of unique mark names. */
    struct TkTextStringList *varBindingList;
    				/* Linked list of variables which should be unset when the widget
				 * will be destroyed. */
    int sharedIsReleased;	/* Boolean value whether shared resource have been released. */

    /*
     * Copies of information from the shared section relating to the editor control mode:
     */

    int steadyMarks;		/* false = behavior of original implementation,
    				 * true  = new editor control mode. */

    /*
     * Copies of information from the shared section relating to the undo/redo functionality:
     */

    int undo;			/* Non-zero means the undo/redo behaviour is
				 * enabled. */
    int maxUndoDepth;		/* The maximum depth of the undo stack expressed as the
    				 * maximum number of compound statements. */
    int maxRedoDepth;		/* The maximum depth of the redo stack expressed as the
    				 * maximum number of compound statements. */
    int maxUndoSize;		/* The maximum number of bytes kept on the undo stack. */
    int autoSeparators;		/* Non-zero means the separators will be inserted automatically. */
    int undoTagging;		/* Global default value for TkTextTag::undo. */

    /*
     * Support of sync command:
     */

    Tcl_Obj *afterSyncCmd;	/* Commands to be executed when lines are up to date */

#ifdef TK_CHECK_ALLOCS
    size_t widgetNumber;
#endif
} TkText;

/*
 * Flag values for TkText records:
 *
 * GOT_SELECTION:		Non-zero means we've already claimed the
 *				selection.
 * INSERT_ON:			Non-zero means insertion cursor should be
 *				displayed on screen.
 * GOT_FOCUS:			Non-zero means this window has the input
 *				focus.
 * BUTTON_DOWN:			1 means that a mouse button is currently down;
 *				this is used to implement grabs for the
 *				duration of button presses.
 * UPDATE_SCROLLBARS:		Non-zero means scrollbar(s) should be updated
 *				during next redisplay operation.
 * NEED_REPICK			This appears unused and should probably be
 *				ignored.
 * OPTIONS_FREED		The widget's options have been freed.
 * DESTROYED			The widget is going away.
 * MEM_RELEASED			The memory of text widget has been released (only for debugging).
 */

#define GOT_SELECTION		1
#define INSERT_ON		2
#define GOT_FOCUS		4
#define BUTTON_DOWN		8
#define UPDATE_SCROLLBARS	0x10
#define NEED_REPICK		0x20
#define OPTIONS_FREED		0x40
#define DESTROYED		0x80
#define MEM_RELEASED		0x100

/*
 * The categories of segment types:
 */

typedef enum {
    SEG_GROUP_CHAR    = 1 << 0,	/* tkTextCharType */
    SEG_GROUP_MARK    = 1 << 1,	/* tkTextLeftMarkType, tkTextRightMarkType */
    SEG_GROUP_HYPHEN  = 1 << 2,	/* tkTextHyphenType */
    SEG_GROUP_BRANCH  = 1 << 3,	/* tkTextBranchType, tkTextLinkType */
    SEG_GROUP_IMAGE   = 1 << 4,	/* tkTextEmbImageType */
    SEG_GROUP_WINDOW  = 1 << 5,	/* tkTextEmbWindowType */
    SEG_GROUP_PROTECT = 1 << 6,	/* tkTextProtectionMarkType */
    SEG_GROUP_TAG     = 1 << 7,	/* this is only needed for convenience */
} TkSegGroupType;

/*
 * Records of the following type define segment types in terms of a collection
 * of procedures that may be called to manipulate segments of that type.
 */



typedef int Tk_SegDeleteProc(TkSharedText *sharedTextPtr, struct TkTextSegment *segPtr, int flags);



typedef int Tk_SegReuseProc(TkSharedText *sharedTextPtr, struct TkTextSegment *segPtr);


typedef int Tk_SegLayoutProc(const struct TkTextIndex *indexPtr, TkTextSegment *segPtr,

		    Tcl_Size offset, int maxX, Tcl_Size maxChars, int noCharsYet, TkWrapMode wrapMode,
		    TkTextSpaceMode spaceMode, struct TkTextDispChunk *chunkPtr);
typedef void Tk_SegCheckProc(const struct TkSharedText *sharedTextPtr, const TkTextSegment *segPtr);

typedef Tcl_Obj *Tk_SegInspectProc(const TkSharedText *sharedTextPtr, const TkTextSegment *segPtr);

typedef struct Tk_SegType {
    const char *name;		/* Name of this kind of segment. */
    TkSegGroupType group;	/* Group information. */
    int gravity;		/* The gravity of this segment, one of GRAVITY_LEFT, GRAVITY_NEUTRAL,


    				 * GRAVITY_RIGHT. */


    Tk_SegDeleteProc *deleteProc;
				/* Procedure to call to delete segment. */
    Tk_SegReuseProc *restoreProc;









    				/* Restore a preserved segment. This will be done when performing
    				 * an undo. */
    Tk_SegLayoutProc *layoutProc;
				/* Returns size information when figuring out what to display
				 * in window. */
    Tk_SegCheckProc *checkProc;	/* Called during consistency checks to check internal consistency
    				 * of segment. */
    Tk_SegInspectProc *inspectProc;
     				/* Called when creating the information for "inspect". */
} Tk_SegType;

/*
 * These items are the gravity values:
 */

enum { GRAVITY_LEFT, GRAVITY_NEUTRAL, GRAVITY_RIGHT };

/*
 * The following type and items describe different flags for text widget items
 * to count. They are used in both tkText.c and tkTextIndex.c, in
 * 'CountIndices', 'TkTextIndexBackChars', 'TkTextIndexForwChars', and
 * 'TkTextIndexCount'.
 */

typedef enum {
    COUNT_HYPHENS		= 1 << 1,
    COUNT_TEXT			= 1 << 2,
    COUNT_CHARS			= COUNT_HYPHENS | COUNT_TEXT,
    COUNT_INDICES		= 1 << 3,
    COUNT_DISPLAY		= 1 << 4,
    COUNT_DISPLAY_CHARS		= COUNT_CHARS | COUNT_DISPLAY,
    COUNT_DISPLAY_HYPHENS	= COUNT_HYPHENS | COUNT_DISPLAY,
    COUNT_DISPLAY_TEXT		= COUNT_TEXT | COUNT_DISPLAY,
    COUNT_DISPLAY_INDICES	= COUNT_INDICES | COUNT_DISPLAY
} TkTextCountType;

/*
 * Some definitions for line break support, must coincide with the defintions
 * in /usr/include/linebreak.h:
 */

#define LINEBREAK_MUSTBREAK	0 /* Break is mandatory */
#define LINEBREAK_ALLOWBREAK	1 /* Break is allowed */
#define LINEBREAK_NOBREAK	2 /* No break is possible */
#define LINEBREAK_INSIDEACHAR	3 /* Inside UTF-8 sequence */



/*
 * Flags for the delete function (Tk_SegDeleteProc):
 *
 * TREE_GONE		The entire tree is being deleted, so everything must get cleaned up.
 * DELETE_BRANCHES	The branches and links will be deleted.
 * DELETE_MARKS		The marks will be deleted.
 * DELETE_INCLUSIVE	The deletion of the marks includes also the marks given as arguments
 *			for the range.
 * DELETE_CLEANUP	We have to delete anyway, due to a cleanup.
 */

#define TREE_GONE		(1 << 0)





#define DELETE_BRANCHES		(1 << 1)
#define DELETE_MARKS		(1 << 2)
#define DELETE_INCLUSIVE	(1 << 3)
#define DELETE_CLEANUP		(1 << 4)
#define DELETE_LASTLINE		(1 << 5)

/*
 * Flags for sorting.
 */


typedef enum {
    TK_TEXT_SORT_NONE,
    TK_TEXT_SORT_ASCENDING
} TkTextSortMethod;

/*


 * Flags needed for function TkBTreeGetSegmentTags().
 */

#define TK_TEXT_IS_ELIDED	(1 << 0)
#define TK_TEXT_IS_SELECTED	(1 << 1)

/*
 * The following definition specifies the maximum number of characters needed
 * in a string to hold a position specifier.
 */

#define TK_POS_CHARS		30

/*
 * Mask used for those options which may impact the text content
 * of individual lines displayed in the widget.
 */

#define TK_TEXT_LINE_REDRAW		(1 << 0)
#define TK_TEXT_LINE_REDRAW_BOTTOM_LINE	(1 << 1)

/*
 * Mask used for those options which may impact the pixel height calculations
 * of individual lines displayed in the widget.
 */

#define TK_TEXT_LINE_GEOMETRY		(1 << 2)

/*
 * Mask used for those options which should invoke the line metric update
 * immediately.
 */

#define TK_TEXT_SYNCHRONIZE		(1 << 3)

/*
 * Mask used for those options which may impact the start and end lines/index
 * used in the widget.
 */

#if SUPPORT_DEPRECATED_STARTLINE_ENDLINE
# define TK_TEXT_LINE_RANGE		(1 << 4)
# define TK_TEXT_INDEX_RANGE		((1 << 5)|TK_TEXT_LINE_RANGE)
#else
# define TK_TEXT_INDEX_RANGE		(1 << 4)
#endif /* SUPPORT_DEPRECATED_STARTLINE_ENDLINE */

#if SUPPORT_DEPRECATED_TAG_OPTIONS
# define TK_TEXT_DEPRECATED_OVERSTRIKE_FG	(1 << 6)
# define TK_TEXT_DEPRECATED_UNDERLINE_FG	(1 << 7)
#endif /* SUPPORT_DEPRECATED_TAG_OPTIONS */

/*
 * Used as 'action' values in calls to TkTextInvalidateLineMetrics
 */

typedef enum {
    TK_TEXT_INVALIDATE_ONLY,
    TK_TEXT_INVALIDATE_INSERT,
    TK_TEXT_INVALIDATE_DELETE,
    TK_TEXT_INVALIDATE_ELIDE,
    TK_TEXT_INVALIDATE_REINSERTED
} TkTextInvalidateAction;

/*
 * Used as special 'pickPlace' values in calls to TkTextSetYView. Zero or
 * positive values indicate a number of pixels.
 */

#define TK_TEXT_PICKPLACE	-1
#define TK_TEXT_NOPIXELADJUST	-2

/*
 * Declarations for variables shared among the text-related files:
 */

MODULE_SCOPE int	tkBTreeDebug;
MODULE_SCOPE int	tkTextDebug;
MODULE_SCOPE const Tk_SegType tkTextCharType;
MODULE_SCOPE const Tk_SegType tkTextBranchType;
MODULE_SCOPE const Tk_SegType tkTextLinkType;
MODULE_SCOPE const Tk_SegType tkTextLeftMarkType;
MODULE_SCOPE const Tk_SegType tkTextRightMarkType;
MODULE_SCOPE const Tk_SegType tkTextHyphenType;
MODULE_SCOPE const Tk_SegType tkTextEmbImageType;
MODULE_SCOPE const Tk_SegType tkTextEmbWindowType;
MODULE_SCOPE const Tk_SegType tkTextProtectionMarkType;

/*
 * Convenience constants for a better readability of TkTextFindDisplayLineStartEnd call:
 */

enum { DISP_LINE_START = 0, DISP_LINE_END = 1 };

/*
 * Helper for guarded allocation/deallocation.
 */

#define FREE_SEGMENT(ptr) { \
    /* printf("destroy(%p) %s:%d\n", ptr, __FILE__, __LINE__); */ \
    assert(ptr->typePtr); \
    assert(!(ptr->typePtr = NULL)); \
    ckfree(ptr); }

#define NEW_SEGMENT(ptr) \
    /* printf("alloc(%p) %s:%d\n", ptr, __FILE__, __LINE__) */

/*
 * We need a callback function for tag changes. The return value informs whether
 * this operation is undoable.
 */

typedef int TkTextTagChangedProc(
    const TkSharedText *sharedTextPtr,
    TkText *textPtr,
    const TkTextIndex *indexPtr1,
    const TkTextIndex *indexPtr2,
    const TkTextTag *tagPtr,
    int affectsDisplayGeometry);

/*
 * Callback function for TkTextPerformWatchCmd().
 */

typedef void (*TkTextWatchGetIndexProc)(TkText *textPtr, TkTextIndex *indexPtr, void *clientData);

/*
 * These flages are needed for TkTextInspectOptions():
 */

#define INSPECT_DONT_RESOLVE_COLORS     (1 << 0)
#define INSPECT_DONT_RESOLVE_FONTS      (1 << 1)
#define INSPECT_INCLUDE_DATABASE_CONFIG (1 << 2)
#define INSPECT_INCLUDE_SYSTEM_CONFIG   (1 << 3)
#define INSPECT_INCLUDE_DEFAULT_CONFIG  (1 << 4)
#define INSPECT_INCLUDE_SYSTEM_COLORS   (1 << 5)

/*
 * Declarations for procedures that are used by the text-related files but
 * shouldn't be used anywhere else in Tk (or by Tk clients):
 */

inline TkSharedText *	TkBTreeGetShared(TkTextBTree tree);
inline int		TkBTreeGetNumberOfDisplayLines(const TkTextPixelInfo *pixelInfo);
MODULE_SCOPE void	TkBTreeAdjustPixelHeight(const TkText *textPtr,
			TkTextLine *linePtr, int newPixelHeight, unsigned mergedLogicalLines,
			    unsigned oldNumDispLines);
MODULE_SCOPE void	TkBTreeUpdatePixelHeights(const TkText *textPtr, TkTextLine *linePtr,
			    int numLines, unsigned epoch);
MODULE_SCOPE void	TkBTreeResetDisplayLineCounts(TkText *textPtr, TkTextLine *linePtr,
			    unsigned numLines);
MODULE_SCOPE int	TkBTreeHaveElidedSegments(const TkSharedText *sharedTextPtr);
inline TkTextPixelInfo * TkBTreeLinePixelInfo(const TkText *textPtr, TkTextLine *linePtr);
MODULE_SCOPE int	TkBTreeCharTagged(const TkTextIndex *indexPtr, const TkTextTag *tagPtr);

MODULE_SCOPE void	TkBTreeCheck(TkTextBTree tree);
MODULE_SCOPE TkTextBTree TkBTreeCreate(TkSharedText *sharedTextPtr, unsigned epoch);
MODULE_SCOPE void	TkBTreeAddClient(TkTextBTree tree, TkText *textPtr, int defaultHeight);

MODULE_SCOPE void	TkBTreeClientRangeChanged(TkText *textPtr, unsigned defaultHeight);

MODULE_SCOPE void	TkBTreeRemoveClient(TkTextBTree tree, TkText *textPtr);

MODULE_SCOPE void	TkBTreeDestroy(TkTextBTree tree);
MODULE_SCOPE int	TkBTreeLoad(TkText *textPtr, Tcl_Obj *content, int validOptions);
MODULE_SCOPE void	TkBTreeDeleteIndexRange(TkSharedText *sharedTextPtr,
			    TkTextIndex *index1Ptr, TkTextIndex *index2Ptr,
			    int flags, TkTextUndoInfo *undoInfo);
inline Tcl_Size		TkBTreeEpoch(TkTextBTree tree);
inline Tcl_Size		TkBTreeIncrEpoch(TkTextBTree tree);
inline struct Node	* TkBTreeGetRoot(TkTextBTree tree);
MODULE_SCOPE TkTextLine * TkBTreeFindLine(TkTextBTree tree, const TkText *textPtr, unsigned line);
MODULE_SCOPE TkTextLine * TkBTreeFindPixelLine(TkTextBTree tree,
			    const TkText *textPtr, int pixels, int32_t *pixelOffset);
MODULE_SCOPE TkTextLine * TkBTreeGetLogicalLine(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, TkTextLine *linePtr);
MODULE_SCOPE TkTextLine * TkBTreeNextLogicalLine(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, TkTextLine *linePtr);
inline TkTextLine *	TkBTreePrevLogicalLine(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, TkTextLine *linePtr);
MODULE_SCOPE TkTextLine * TkBTreeNextDisplayLine(TkText *textPtr, TkTextLine *linePtr,
			    unsigned *displayLineNo, unsigned offset);
MODULE_SCOPE TkTextLine * TkBTreePrevDisplayLine(TkText *textPtr, TkTextLine *linePtr,
			    unsigned *displayLineNo, unsigned offset);
MODULE_SCOPE TkTextSegment * TkBTreeFindStartOfElidedRange(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE TkTextSegment * TkBTreeFindEndOfElidedRange(const TkSharedText *sharedTextPtr,
			    const TkText *textPtr, const TkTextSegment *segPtr);
inline TkTextTag *	TkBTreeGetTags(const TkTextIndex *indexPtr, TkTextSortMethod sortMeth,
			    int *flags);
MODULE_SCOPE TkTextTag * TkBTreeGetSegmentTags(const TkSharedText *sharedTextPtr,
			    const TkTextSegment *segPtr, const TkText *textPtr,
			    TkTextSortMethod sortMeth, int *flags);
MODULE_SCOPE const char * TkBTreeGetLang(const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE void	TkBTreeInsertChars(TkTextBTree tree, TkTextIndex *indexPtr, const char *string,
			    union TkTextTagSet *tagInfoPtr, TkTextTag *hyphenTagPtr,
			    TkTextUndoInfo *undoInfo);
MODULE_SCOPE TkTextSegment *TkBTreeMakeCharSegment(const char *string, unsigned length,
			    union TkTextTagSet *tagInfoPtr);
MODULE_SCOPE void	TkBTreeMakeUndoIndex(const TkSharedText *sharedTextPtr,
			    TkTextSegment *segPtr, TkTextUndoIndex *indexPtr);
MODULE_SCOPE void	TkBTreeUndoIndexToIndex(const TkSharedText *sharedTextPtr,
			    const TkTextUndoIndex *srcPtr, TkTextIndex *dstPtr);
MODULE_SCOPE Tcl_Obj *	TkBTreeUndoTagInspect(const TkSharedText *sharedTextPtr,
			    const TkTextUndoToken *item);
MODULE_SCOPE int	TkBTreeJoinUndoInsert(TkTextUndoToken *token1, unsigned byteSize1,
			    TkTextUndoToken *token2, unsigned byteSize2);
MODULE_SCOPE int	TkBTreeJoinUndoDelete(TkTextUndoToken *token1, unsigned byteSize1,
			    TkTextUndoToken *token2, unsigned byteSize2);
MODULE_SCOPE void	TkBTreeReInsertSegment(const TkSharedText *sharedTextPtr,
			    const TkTextUndoIndex *indexPtr, TkTextSegment *segPtr);
MODULE_SCOPE unsigned	TkBTreeLinesTo(TkTextBTree tree, const TkText *textPtr,
			    const TkTextLine *linePtr, int *deviation);
MODULE_SCOPE unsigned	TkBTreePixelsTo(const TkText *textPtr, const TkTextLine *linePtr);

MODULE_SCOPE void	TkBTreeLinkSegment(const TkSharedText *sharedTextPtr,
			    TkTextSegment *segPtr, TkTextIndex *indexPtr);
inline TkTextLine *	TkBTreeGetStartLine(const TkText *textPtr);
inline TkTextLine *	TkBTreeGetLastLine(const TkText *textPtr);
inline TkTextLine *	TkBTreeNextLine(const TkText *textPtr, TkTextLine *linePtr);
inline TkTextLine *	TkBTreePrevLine(const TkText *textPtr, TkTextLine *linePtr);
MODULE_SCOPE int	TkBTreeMoveForward(TkTextIndex *indexPtr, unsigned byteCount);
MODULE_SCOPE int	TkBTreeMoveBackward(TkTextIndex *indexPtr, unsigned byteCount);
MODULE_SCOPE int	TkBTreeNextTag(TkTextSearch *searchPtr);
MODULE_SCOPE int	TkBTreePrevTag(TkTextSearch *searchPtr);
MODULE_SCOPE TkTextSegment * TkBTreeFindNextTagged(const TkTextIndex *indexPtr1,
			    const TkTextIndex *indexPtr2, const struct TkBitField *discardTags);
MODULE_SCOPE TkTextSegment * TkBTreeFindPrevTagged(const TkTextIndex *indexPtr1,
			    const TkTextIndex *indexPtr2, int discardSelection);
MODULE_SCOPE TkTextSegment * TkBTreeFindNextUntagged(const TkTextIndex *indexPtr1,
			    const TkTextIndex *indexPtr2, const struct TkBitField *discardTags);
MODULE_SCOPE unsigned	TkBTreeNumPixels(const TkText *textPtr);
MODULE_SCOPE unsigned	TkBTreeSize(const TkTextBTree tree, const TkText *textPtr);
MODULE_SCOPE unsigned	TkBTreeCountSize(const TkTextBTree tree, const TkText *textPtr,
			    const TkTextLine *linePtr1, const TkTextLine *linePtr2);
inline unsigned		TkBTreeCountLines(const TkTextBTree tree, const TkTextLine *linePtr1,
			    const TkTextLine *linePtr2);

MODULE_SCOPE void	TkBTreeStartSearch(const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr, const TkTextTag *tagPtr,
			    TkTextSearch *searchPtr, TkTextSearchMode mode);
MODULE_SCOPE void	TkBTreeStartSearchBack(const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr, const TkTextTag *tagPtr,
			    TkTextSearch *searchPtr, TkTextSearchMode mode);
MODULE_SCOPE void	TkBTreeLiftSearch(TkTextSearch *searchPtr);
MODULE_SCOPE int	TkBTreeTag(TkSharedText *sharedTextPtr, TkText *textPtr,
			    const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr,
			    TkTextTag *tagPtr, int add, TkTextUndoInfo *undoInfo,
			    TkTextTagChangedProc changedProc);
MODULE_SCOPE TkTextTag * TkBTreeClearTags(TkSharedText *sharedTextPtr, TkText *textPtr,
			    const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr,
			    TkTextUndoInfo *undoInfo, int discardSelection,
			    TkTextTagChangedProc changedProc);
MODULE_SCOPE void	TkBTreeUpdateElideInfo(TkText *textPtr, TkTextTag *tagPtr);
MODULE_SCOPE void	TkBTreeUnlinkSegment(const TkSharedText *sharedTextPtr, TkTextSegment *segPtr);
MODULE_SCOPE void	TkBTreeFreeSegment(TkTextSegment *segPtr);
MODULE_SCOPE unsigned	TkBTreeChildNumber(const TkTextBTree tree, const TkTextLine *linePtr,
			    unsigned *depth);
MODULE_SCOPE unsigned	TkBTreeLinesPerNode(const TkTextBTree tree);
MODULE_SCOPE const union TkTextTagSet * TkBTreeRootTagInfo(const TkTextBTree tree);
MODULE_SCOPE void	TkTextBindProc(void *clientData, XEvent *eventPtr);

MODULE_SCOPE void	TkTextSelectionEvent(TkText *textPtr);
MODULE_SCOPE int	TkConfigureText(Tcl_Interp *interp, TkText *textPtr, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE const TkTextSegment * TkTextGetUndeletableNewline(const TkTextLine *lastLinePtr);
MODULE_SCOPE void	TkTextPerformWatchCmd(TkSharedText *sharedTextPtr, TkText *textPtr,
			    const char *operation,
			    TkTextWatchGetIndexProc index1Proc, void *index1ProcData,
			    TkTextWatchGetIndexProc index2Proc, void *index2ProcData,
			    const char *arg1, const char *arg2, const char *arg3, int userFlag);
MODULE_SCOPE int	TkTextTriggerWatchCmd(TkText *textPtr, const char *operation,
			    const char *index1, const char *index2, const char *arg1, const char *arg2,
			    const char *arg3, int userFlag);
MODULE_SCOPE void	TkTextUpdateAlteredFlag(TkSharedText *sharedTextPtr);
MODULE_SCOPE int	TkTextIndexBbox(TkText *textPtr,
			    const TkTextIndex *indexPtr, int extents, int *xPtr, int *yPtr,
			    int *widthPtr, int *heightPtr, int *charWidthPtr, Tcl_UniChar *thisChar);
MODULE_SCOPE int	TkTextCharLayoutProc(const TkTextIndex *indexPtr, TkTextSegment *segPtr,

			    Tcl_Size byteOffset, int maxX, Tcl_Size maxBytes, int noCharsYet,
			    TkWrapMode wrapMode, TkTextSpaceMode spaceMode, TkTextDispChunk *chunkPtr);
MODULE_SCOPE void	TkTextCreateDInfo(TkText *textPtr);
MODULE_SCOPE int	TkTextGetDLineInfo(TkText *textPtr, const TkTextIndex *indexPtr,
			    int extents, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr,
			    int *basePtr);
MODULE_SCOPE int	TkTextBindEvent(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],


			     TkSharedText *sharedTextPtr, Tk_BindingTable *bindingTablePtr,

			     const char *name);
MODULE_SCOPE void	TkTextTagFindStartOfRange(TkText *textPtr, const TkTextTag *tagPtr,
			    const TkTextIndex *currentPtr, TkTextIndex *resultPtr);
MODULE_SCOPE void	TkTextTagFindEndOfRange(TkText *textPtr, const TkTextTag *tagPtr,
			    const TkTextIndex *currentPtr, TkTextIndex *resultPtr);
MODULE_SCOPE TkTextTag * TkTextClearTags(TkSharedText *sharedTextPtr, TkText *textPtr,
			    const TkTextIndex *indexPtr1, const TkTextIndex *indexPtr2,

			    int discardSelection);
MODULE_SCOPE void	TkTextClearSelection(TkSharedText *sharedTextPtr,
			    const TkTextIndex *indexPtr1, const TkTextIndex *indexPtr2);
MODULE_SCOPE void	TkTextUpdateTagDisplayFlags(TkTextTag *tagPtr);
MODULE_SCOPE TkTextTag * TkTextCreateTag(TkText *textPtr, const char *tagName, int *newTag);
MODULE_SCOPE TkTextTag * TkTextFindTag(const TkText *textPtr, const char *tagName);
MODULE_SCOPE int	TkConfigureTag(Tcl_Interp *interp, TkText *textPtr, const char *tagName,
			    int redraw, int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE void	TkTextEnableTag(TkSharedText *sharedTextPtr, TkTextTag *tagPtr);
MODULE_SCOPE void	TkTextSortTags(unsigned numTags, TkTextTag **tagArrayPtr);
MODULE_SCOPE void	TkTextFreeDInfo(TkText *textPtr);
MODULE_SCOPE void	TkTextResetDInfo(TkText *textPtr);
MODULE_SCOPE void	TkTextDeleteBreakInfoTableEntries(Tcl_HashTable *breakInfoTable);
MODULE_SCOPE void	TkTextPushTagPriorityUndo(TkSharedText *sharedTextPtr, TkTextTag *tagPtr,
			    unsigned priority);
MODULE_SCOPE void	TkTextPushTagPriorityRedo(TkSharedText *sharedTextPtr, TkTextTag *tagPtr,
			    unsigned priority);
MODULE_SCOPE void	TkTextInspectUndoTagItem(const TkSharedText *sharedTextPtr,
			    const TkTextTag *tagPtr, Tcl_Obj* objPtr);
MODULE_SCOPE void	TkTextTagAddRetainedUndo(TkSharedText *sharedTextPtr, TkTextTag *tagPtr);
MODULE_SCOPE void	TkTextPushUndoTagTokens(TkSharedText *sharedTextPtr, TkTextTag *tagPtr);
MODULE_SCOPE void	TkTextReleaseUndoTagToken(TkSharedText *sharedTextPtr, TkTextTag *tagPtr);
MODULE_SCOPE void	TkTextPushUndoMarkTokens(TkSharedText *sharedTextPtr,
			    TkTextMarkChange *changePtr);
MODULE_SCOPE void	TkTextReleaseUndoMarkTokens(TkSharedText *sharedTextPtr,
			    TkTextMarkChange *changePtr);
MODULE_SCOPE void	TkTextInspectUndoMarkItem(const TkSharedText *sharedTextPtr,
			    const TkTextMarkChange *changePtr, Tcl_Obj* objPtr);
MODULE_SCOPE int	TkTextTagChangedUndoRedo(const TkSharedText *sharedTextPtr, TkText *textPtr,
			    const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr,
			    const TkTextTag *tagPtr, int affectsDisplayGeometry);
MODULE_SCOPE void	TkTextReplaceTags(TkText *textPtr, TkTextSegment *segPtr, int undoable,
			    Tcl_Obj *tagListPtr);
MODULE_SCOPE void	TkTextFindTags(Tcl_Interp *interp, TkText *textPtr, const TkTextSegment *segPtr,
			    int discardSelection);
MODULE_SCOPE int	TkTextDeleteTag(TkText *textPtr, TkTextTag *tagPtr, Tcl_HashEntry *hPtr);
MODULE_SCOPE void	TkTextReleaseTag(TkSharedText *sharedTextPtr, TkTextTag *tagPtr,
			    Tcl_HashEntry *hPtr);
MODULE_SCOPE void	TkTextFontHeightChanged(TkText *textPtr);
MODULE_SCOPE int	TkTextTestRelation(Tcl_Interp *interp, int relation, const char *op);
MODULE_SCOPE int	TkTextAttemptToModifyDisabledWidget(Tcl_Interp *interp);
MODULE_SCOPE int	TkTextAttemptToModifyDeadWidget(Tcl_Interp *interp);
MODULE_SCOPE int	TkTextReleaseIfDestroyed(TkText *textPtr);
MODULE_SCOPE int	TkTextDecrRefCountAndTestIfDestroyed(TkText *textPtr);
MODULE_SCOPE void	TkTextFreeAllTags(TkText *textPtr);
inline int		TkTextGetIndexFromObj(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *objPtr,
			    TkTextIndex *indexPtr);
MODULE_SCOPE TkTextTabArray * TkTextGetTabs(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *stringPtr);
MODULE_SCOPE void	TkTextInspectOptions(TkText *textPtr, const void *recordPtr,
			    Tk_OptionTable optionTable, Tcl_DString *result, int flags);
MODULE_SCOPE void	TkTextFindDisplayLineStartEnd(TkText *textPtr, TkTextIndex *indexPtr, int end);
MODULE_SCOPE unsigned	TkTextCountDisplayLines(TkText *textPtr, const TkTextIndex *indexFrom,
			    const TkTextIndex *indexTo);
MODULE_SCOPE void	TkTextFindDisplayIndex(TkText *textPtr, TkTextIndex *indexPtr,
			    int displayLineOffset, int *xOffset);
MODULE_SCOPE int	TkTextIndexBackChars(const TkText *textPtr, const TkTextIndex *srcPtr,
			    Tcl_Size count, TkTextIndex *dstPtr, TkTextCountType type);
MODULE_SCOPE Tcl_UniChar TkTextIndexGetChar(const TkTextIndex *indexPtr);
MODULE_SCOPE unsigned	TkTextIndexCountBytes(const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr);
MODULE_SCOPE unsigned	TkTextIndexCount(const TkText *textPtr,
			    const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr,
			    TkTextCountType type);
MODULE_SCOPE int	TkTextIndexForwChars(const TkText *textPtr, const TkTextIndex *srcPtr,

			    Tcl_Size count, TkTextIndex *dstPtr, TkTextCountType type);
MODULE_SCOPE void	TkTextIndexOfX(TkText *textPtr, int x, TkTextIndex *indexPtr);

MODULE_SCOPE int	TkTextIndexYPixels(TkText *textPtr, const TkTextIndex *indexPtr);







MODULE_SCOPE int	TkTextComputeBreakLocations(Tcl_Interp *interp, const char *text, unsigned len,
			    const char *lang, char *brks);
MODULE_SCOPE int	TkTextTestLangCode(Tcl_Interp *interp, Tcl_Obj *langCodePtr);
MODULE_SCOPE int	TkTextParseHyphenRules(TkText *textPtr, Tcl_Obj *objPtr, int *rulesPtr);
MODULE_SCOPE void	TkTextLostSelection(void *clientData);
MODULE_SCOPE void	TkTextConfigureUndoStack(TkSharedText *sharedTextPtr, int maxUndoDepth,
			    int maxByteSize);
MODULE_SCOPE void	TkTextConfigureRedoStack(TkSharedText *sharedTextPtr, int maxRedoDepth);
MODULE_SCOPE void	TkTextPushUndoToken(TkSharedText *sharedTextPtr, void *token,
			    unsigned byteSize);
MODULE_SCOPE void	TkTextPushRedoToken(TkSharedText *sharedTextPtr, void *token,
			    unsigned byteSize);
MODULE_SCOPE void	TkTextUndoAddMoveSegmentItem(TkSharedText *sharedTextPtr,
			    TkTextSegment *oldPos, TkTextSegment *newPos);
MODULE_SCOPE TkTextIndex * TkTextMakeCharIndex(TkTextBTree tree, TkText *textPtr,
			    int lineIndex, int charIndex, TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextSegmentIsElided(const TkText *textPtr, const TkTextSegment *segPtr);
MODULE_SCOPE void	TkTextDispAllocStatistic();
MODULE_SCOPE int	TkTextLineIsElided(const TkSharedText *sharedTextPtr, const TkTextLine *linePtr,
			    const TkText *textPtr);
MODULE_SCOPE int	TkTextIsElided(const TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextTestTag(const TkTextIndex *indexPtr, const TkTextTag *tagPtr);
inline int		TkTextIsDeadPeer(const TkText *textPtr);
MODULE_SCOPE void	TkTextGenerateWidgetViewSyncEvent(TkText *textPtr, int sendImmediately);

MODULE_SCOPE void	TkTextRunAfterSyncCmd(TkText *textPtr);
MODULE_SCOPE void	TkTextInvalidateLineMetrics(TkSharedText *sharedTextPtr, TkText *textPtr,
			    TkTextLine *linePtr, unsigned lineCount, TkTextInvalidateAction action);
MODULE_SCOPE void	TkTextUpdateLineMetrics(TkText *textPtr, unsigned lineNum, unsigned endLine);




MODULE_SCOPE int	TkTextMarkCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE TkTextSegment * TkTextFindMark(const TkText *textPtr, const char *name);
MODULE_SCOPE TkTextSegment * TkTextFreeMarks(TkSharedText *sharedTextPtr, int retainPrivateMarks);
MODULE_SCOPE int	TkTextMarkNameToIndex(TkText *textPtr, const char *name, TkTextIndex *indexPtr);

MODULE_SCOPE void	TkTextMarkSegToIndex(TkText *textPtr,
			    TkTextSegment *markPtr, TkTextIndex *indexPtr);
MODULE_SCOPE TkTextSegment * TkTextMakeStartEndMark(TkText *textPtr, Tk_SegType const *typePtr);
MODULE_SCOPE TkTextSegment * TkTextMakeMark(TkText *textPtr, const char *name);
MODULE_SCOPE TkTextSegment * TkTextMakeNewMark(TkSharedText *sharedTextPtr, const char *name);
MODULE_SCOPE void	TkTextUnsetMark(TkText *textPtr, TkTextSegment *markPtr);
inline int		TkTextIsMark(const TkTextSegment *segPtr);
inline int		TkTextIsStartEndMarker(const TkTextSegment *segPtr);
inline int		TkTextIsSpecialMark(const TkTextSegment *segPtr);
inline int		TkTextIsPrivateMark(const TkTextSegment *segPtr);
inline int		TkTextIsSpecialOrPrivateMark(const TkTextSegment *segPtr);
inline int		TkTextIsNormalOrSpecialMark(const TkTextSegment *segPtr);
inline int		TkTextIsNormalMark(const TkTextSegment *segPtr);
inline int		TkTextIsStableMark(const TkTextSegment *segPtr);
MODULE_SCOPE const char * TkTextMarkName(const TkSharedText *sharedTextPtr, const TkText *textPtr,
			    const TkTextSegment *markPtr);
MODULE_SCOPE void	TkTextUpdateCurrentMark(TkSharedText *sharedTextPtr);
MODULE_SCOPE void	TkTextSaveCursorIndex(TkText *textPtr);
MODULE_SCOPE int	TkTextTriggerWatchCursor(TkText *textPtr);
MODULE_SCOPE void	TkTextInsertGetBBox(TkText *textPtr, int x, int y, int height, XRectangle *bbox);
MODULE_SCOPE int	TkTextDrawBlockCursor(TkText *textPtr);
MODULE_SCOPE int	TkTextGetCursorBbox(TkText *textPtr, int *x, int *y, int *w, int *h);
MODULE_SCOPE unsigned	TkTextGetCursorWidth(TkText *textPtr, int *x, int *offs);
MODULE_SCOPE void	TkTextEventuallyRepick(TkText *textPtr);
MODULE_SCOPE int	TkTextPendingSync(const TkText *textPtr);
MODULE_SCOPE void	TkTextPickCurrent(TkText *textPtr, XEvent *eventPtr);
MODULE_SCOPE union TkTextTagSet * TkTextGetTagSetFromChunk(const TkTextDispChunk *chunkPtr);
MODULE_SCOPE int	TkTextGetXPixelFromChunk(const TkText *textPtr,
			    const TkTextDispChunk *chunkPtr);
MODULE_SCOPE int	TkTextGetYPixelFromChunk(const TkText *textPtr,
			    const TkTextDispChunk *chunkPtr);
inline const TkTextDispChunk * TkTextGetFirstChunkOfNextDispLine(const TkTextDispChunk *chunkPtr);
inline const TkTextDispChunk * TkTextGetLastChunkOfPrevDispLine(const TkTextDispChunk *chunkPtr);
MODULE_SCOPE int	TkTextGetFirstXPixel(const TkText *textPtr);
MODULE_SCOPE int	TkTextGetFirstYPixel(const TkText *textPtr);
MODULE_SCOPE int	TkTextGetLastXPixel(const TkText *textPtr);
MODULE_SCOPE int	TkTextGetLastYPixel(const TkText *textPtr);
MODULE_SCOPE unsigned	TkTextCountVisibleImages(const TkText *textPtr);
MODULE_SCOPE unsigned	TkTextCountVisibleWindows(const TkText *textPtr);
MODULE_SCOPE const TkTextDispChunk * TkTextPixelIndex(TkText *textPtr, int x, int y,
			    TkTextIndex *indexPtr, int *nearest);
MODULE_SCOPE Tcl_Obj *	TkTextNewIndexObj(const TkTextIndex *indexPtr);

MODULE_SCOPE void	TkTextRedrawRegion(TkText *textPtr, int x, int y, int width, int height);

MODULE_SCOPE int	TkTextRedrawTag(const TkSharedText *sharedTextPtr, TkText *textPtr,
			    const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr,
			    const TkTextTag *tagPtr, int affectsDisplayGeometry);

MODULE_SCOPE void	TkTextRelayoutWindow(TkText *textPtr, int mask);
MODULE_SCOPE void	TkTextCheckLineMetricUpdate(const TkText *textPtr);
MODULE_SCOPE void	TkTextCheckDisplayLineConsistency(const TkText *textPtr);
MODULE_SCOPE int	TkTextScanCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextSeeCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);


MODULE_SCOPE void	TkTextSetYView(TkText *textPtr, TkTextIndex *indexPtr, int pickPlace);

MODULE_SCOPE int	TkTextTagCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextImageCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextImageIndex(TkText *textPtr, const char *name, TkTextIndex *indexPtr);
MODULE_SCOPE TkTextSegment * TkTextMakeImage(TkText *textPtr, Tcl_Obj *options);
MODULE_SCOPE int	TkTextWindowCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkTextWindowIndex(TkText *textPtr, const char *name, TkTextIndex *indexPtr);
MODULE_SCOPE TkTextSegment * TkTextMakeWindow(TkText *textPtr, Tcl_Obj *options);
MODULE_SCOPE int	TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE void	TkTextGetViewOffset(TkText *textPtr, int *x, int *y);
MODULE_SCOPE void	TkTextWinFreeClient(Tcl_HashEntry *hPtr, TkTextEmbWindowClient *client);
MODULE_SCOPE void	TkTextIndexSetPosition(TkTextIndex *indexPtr,
			    int byteIndex, TkTextSegment *segPtr);
MODULE_SCOPE int	TkTextSegToIndex(const TkTextSegment *segPtr);
MODULE_SCOPE int	TkTextIndexGetFromString(Tcl_Interp *interp, struct TkText *textPtr,
			    const char *string, unsigned lengthOfString, struct TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexPrint(const TkSharedText *sharedTextPtr, const TkText *textPtr,
				const struct TkTextIndex *indexPtr, char *string);
MODULE_SCOPE void	TkTextIndexSetByteIndex(TkTextIndex *indexPtr, Tcl_Size byteIndex);
MODULE_SCOPE void	TkTextIndexSetByteIndex2(TkTextIndex *indexPtr,
			    TkTextLine *linePtr, Tcl_Size byteIndex);
inline void		TkTextIndexSetEpoch(TkTextIndex *indexPtr, size_t epoch);
MODULE_SCOPE void	TkTextIndexSetSegment(TkTextIndex *indexPtr, TkTextSegment *segPtr);
inline void		TkTextIndexSetPeer(TkTextIndex *indexPtr, TkText *textPtr);
MODULE_SCOPE int	TkTextIndexIsEmpty(const TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextIndexSetLine(TkTextIndex *indexPtr, TkTextLine *linePtr);
MODULE_SCOPE void	TkTextIndexSetToStartOfLine(TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextIndexSetToStartOfLine2(TkTextIndex *indexPtr, TkTextLine *linePtr);
MODULE_SCOPE void	TkTextIndexSetToEndOfLine2(TkTextIndex *indexPtr, TkTextLine *linePtr);
MODULE_SCOPE void	TkTextIndexSetToLastChar(TkTextIndex *indexPtr);
inline void		TkTextIndexSetToLastChar2(TkTextIndex *indexPtr, TkTextLine *linePtr);
MODULE_SCOPE void	TkTextIndexSetupToStartOfText(TkTextIndex *indexPtr, TkText *textPtr,
			    TkTextBTree tree);
MODULE_SCOPE void	TkTextIndexSetupToEndOfText(TkTextIndex *indexPtr, TkText *textPtr,
			    TkTextBTree tree);
MODULE_SCOPE int	TkTextIndexAddToByteIndex(TkTextIndex *indexPtr, Tcl_Size numBytes);
inline TkTextLine *	TkTextIndexGetLine(const TkTextIndex *indexPtr);
MODULE_SCOPE Tcl_Size	TkTextIndexGetByteIndex(const TkTextIndex *indexPtr);
MODULE_SCOPE unsigned	TkTextIndexGetLineNumber(const TkTextIndex *indexPtr, const TkText *textPtr);
inline TkTextSegment *	TkTextIndexGetSegment(const TkTextIndex *indexPtr);
MODULE_SCOPE TkTextSegment * TkTextIndexGetContentSegment(const TkTextIndex *indexPtr, Tcl_Size *offset);
MODULE_SCOPE TkTextSegment * TkTextIndexGetFirstSegment(const TkTextIndex *indexPtr, Tcl_Size *offset);
inline TkSharedText *	TkTextIndexGetShared(const TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextIndexClear(TkTextIndex *indexPtr, TkText *textPtr);
MODULE_SCOPE void	TkTextIndexClear2(TkTextIndex *indexPtr, TkText *textPtr, TkTextBTree tree);
inline void		TkTextIndexInvalidate(TkTextIndex *indexPtr);
MODULE_SCOPE void	TkTextIndexToByteIndex(TkTextIndex *indexPtr);
inline void		TkTextIndexMakePersistent(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexIsZero(const TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexIsStartOfLine(const TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexIsEndOfLine(const TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexIsStartOfText(const TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexIsEndOfText(const TkTextIndex *indexPtr);
inline int		TkTextIndexSameLines(const TkTextIndex *indexPtr1, const TkTextIndex *indexPtr2);
MODULE_SCOPE int	TkTextIndexIsEqual(const TkTextIndex *indexPtr1, const TkTextIndex *indexPtr2);
MODULE_SCOPE int	TkTextIndexCompare(const TkTextIndex *indexPtr1, const TkTextIndex *indexPtr2);
inline void		TkTextIndexSave(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexRebuild(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexRestrictToStartRange(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexRestrictToEndRange(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexOutsideStartEnd(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextIndexEnsureBeforeLastChar(TkTextIndex *indexPtr);
MODULE_SCOPE int	TkTextSkipElidedRegion(TkTextIndex *indexPtr);
MODULE_SCOPE int		TkrTesttextCmd(void *dummy, Tcl_Interp *interp,
				Tcl_Size objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int		TkrTextGetIndex(Tcl_Interp *interp,
				struct TkText *textPtr, const char *string,
				struct TkTextIndex *indexPtr);
MODULE_SCOPE int		TkrTextIndexBackBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr, Tcl_Size count,
				struct TkTextIndex *dstPtr);
MODULE_SCOPE int		TkrTextIndexForwBytes(const struct TkText *textPtr,
				const struct TkTextIndex *srcPtr, Tcl_Size count,
				struct TkTextIndex *dstPtr);
MODULE_SCOPE struct TkTextIndex * TkrTextMakeByteIndex(TkTextBTree tree,
				const struct TkText *textPtr, int lineIndex,
				Tcl_Size byteIndex, struct TkTextIndex *indexPtr);
MODULE_SCOPE Tcl_Size		TkrTextPrintIndex(const struct TkText *textPtr,
				const struct TkTextIndex *indexPtr,
				char *string);
MODULE_SCOPE struct TkTextSegment * TkrTextSetMark(struct TkText *textPtr,
				const char *name,
				struct TkTextIndex *indexPtr);
MODULE_SCOPE int		TkrTextXviewCmd(struct TkText *textPtr,
				Tcl_Interp *interp, Tcl_Size objc,
				Tcl_Obj *const objv[]);
MODULE_SCOPE void		TkrTextChanged(struct TkSharedText *sharedTextPtr,
				struct TkText *textPtr,
				const struct TkTextIndex *index1Ptr,
				const struct TkTextIndex *index2Ptr);
MODULE_SCOPE int		TkrBTreeNumLines(TkTextBTree tree,
				const struct TkText *textPtr);
MODULE_SCOPE void		TkrTextInsertDisplayProc(struct TkText *textPtr,
				struct TkTextDispChunk *chunkPtr, int x,
				int y, int height, int baseline,
				Display *display, Drawable dst, int screenY);

/*
 * Debugging info macros:
 */

#if defined(NDEBUG) || defined(TK_TEXT_NDEBUG)
# define TK_BTREE_DEBUG(expr)
#else
# define TK_BTREE_DEBUG(expr)	{ if (tkBTreeDebug) { expr; } }
#endif

#define TK_TEXT_DEBUG(expr)	{ if (tkTextDebug) { expr; } }

#define _TK_NEED_IMPLEMENTATION
#include "tkTextPriv.h"
#endif /* _TKTEXT */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkTextBTree.c.

more than 10,000 changes

Changes to generic/tkTextDisp.c.

more than 10,000 changes

Changes to generic/tkTextImage.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
/*
 * 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.

 *
 * 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"

/*

 * Macro that determines the size of an embedded image segment:
 */


#define EI_SEG_SIZE \
	(offsetof(TkTextSegment, body) + sizeof(TkTextEmbImage))



/*
 * Prototypes for functions defined in this file:
 */

static TkTextSegment *	EmbImageCleanupProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);
static void		EmbImageCheckProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);


static void		EmbImageBboxProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr, int index, int y,
			    int lineHeight, int baseline, int *xPtr, int *yPtr,
			    int *widthPtr, int *heightPtr);
static int		EmbImageConfigure(TkText *textPtr,
			    TkTextSegment *eiPtr, int objc,
			    Tcl_Obj *const objv[]);
static int		EmbImageDeleteProc(TkTextSegment *segPtr,











			    TkTextLine *linePtr, int treeGone);














static void		EmbImageDisplayProc(TkText *textPtr,

			    TkTextDispChunk *chunkPtr, int x, int y,





			    int lineHeight, int baseline, Display *display,








			    Drawable dst, int screenY);








static int		EmbImageLayoutProc(TkText *textPtr,


			    TkTextIndex *indexPtr, TkTextSegment *segPtr,

			    TkSizeT offset, int maxX, TkSizeT maxChars,


			    int noCharsYet, TkWrapMode wrapMode,
			    TkTextDispChunk *chunkPtr);
static void		EmbImageProc(ClientData clientData, int x, int y,
			    int width, int height, int imageWidth,
			    int imageHeight);

/*
 * The following structure declares the "embedded image" segment type.
 */

const Tk_SegType tkTextEmbImageType = {
    "image",			/* name */
    0,				/* leftGravity */
    NULL,			/* splitProc */
    EmbImageDeleteProc,		/* deleteProc */
    EmbImageCleanupProc,	/* cleanupProc */
    NULL,			/* lineChangeProc */
    EmbImageLayoutProc,		/* layoutProc */
    EmbImageCheckProc		/* checkProc */

};

/*
 * Definitions for alignment values:
 */

static const char *const alignStrings[] = {
    "baseline", "bottom", "center", "top", NULL
};

typedef enum {
    ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
} alignMode;

/*
 * Information used for parsing image configuration options:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
	"center", TCL_INDEX_NONE, offsetof(TkTextEmbImage, align),
	0, alignStrings, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-name", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageName),

	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};












































































































































































/*
 *--------------------------------------------------------------
 *
 * TkTextImageCmd --
 *
 *	This function implements the "image" widget command for text widgets.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result or error.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */


















int
TkTextImageCmd(
    TkText *textPtr,	/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already
				 * parsed this command enough to know that
				 * objv[1] is "image". */
{
    int idx;
    TkTextSegment *eiPtr;

    TkTextIndex index;
    static const char *const optionStrings[] = {
	"cget", "configure", "create", "names", NULL
    };
    enum opts {
	CMD_CGET, CMD_CONF, CMD_CREATE, CMD_NAMES
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[2], optionStrings,
	    sizeof(char *), "option", 0, &idx) != TCL_OK) {
	return TCL_ERROR;
    }



    switch ((enum opts) idx) {
    case CMD_CGET: {
	Tcl_Obj *objPtr;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexToSeg(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded image at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL);
	    return TCL_ERROR;
	}



	objPtr = Tk_GetOptionValue(interp, &eiPtr->body.ei,
		eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin);
	if (objPtr == NULL) {
	    return TCL_ERROR;
	} else {

	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
    }

    case CMD_CONF:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexToSeg(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded image at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL);
	    return TCL_ERROR;
	}
	if (objc <= 5) {



	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp,
		    &eiPtr->body.ei, eiPtr->body.ei.optionTable,
		    (objc == 5) ? objv[4] : NULL, textPtr->tkwin);



	    if (objPtr == NULL) {



		return TCL_ERROR;



	    } else {






		Tcl_SetObjResult(interp, objPtr);
		return TCL_OK;
	    }
	} else {
	    TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);

	    /*
	     * It's probably not true that all window configuration can change
	     * the line height, so we could be more efficient here and only
	     * call this when necessary.
	     */

	    TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
		    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
	    return EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4);
	}
    case CMD_CREATE: {
	int lineIndex;

	/*
	 * Add a new image. Find where to put the new image, and mark that
	 * position for redisplay.
	 */

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}





	/*
	 * Don't allow insertions on the last (dummy) line of the text.
	 */

	lineIndex = TkBTreeLinesTo(textPtr, index.linePtr);
	if (lineIndex == TkBTreeNumLines(textPtr->sharedTextPtr->tree,
		textPtr)) {
	    lineIndex--;
	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
		    lineIndex, 1000000, &index);
	}

	/*
	 * Create the new image segment and initialize it.
	 */

	eiPtr = (TkTextSegment *)ckalloc(EI_SEG_SIZE);
	eiPtr->typePtr = &tkTextEmbImageType;
	eiPtr->size = 1;
	eiPtr->body.ei.sharedTextPtr = textPtr->sharedTextPtr;
	eiPtr->body.ei.linePtr = NULL;
	eiPtr->body.ei.imageName = NULL;
	eiPtr->body.ei.imageString = NULL;
	eiPtr->body.ei.name = NULL;
	eiPtr->body.ei.image = NULL;
	eiPtr->body.ei.align = ALIGN_CENTER;
	eiPtr->body.ei.padX = eiPtr->body.ei.padY = 0;
	eiPtr->body.ei.chunkCount = 0;
	eiPtr->body.ei.optionTable = Tk_CreateOptionTable(interp, optionSpecs);

	/*
	 * Link the segment into the text widget, then configure it (delete it
	 * again if the configuration fails).
	 */

	TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);
	TkBTreeLinkSegment(eiPtr, &index);
	if (EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4) != TCL_OK) {

	    TkTextIndex index2;



	    TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
	    TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index, &index2);

	    return TCL_ERROR;


	}



	TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,

		index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);


	return TCL_OK;

    }

    case CMD_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,

		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));
	}
	if (resultObj == NULL) {



	    return TCL_ERROR;

	} else {















	    Tcl_SetObjResult(interp, resultObj);

















	    return TCL_OK;
	}
    }







    default:








	Tcl_Panic("unexpected switch fallthrough");








    }



    return TCL_ERROR;












}

/*
 *--------------------------------------------------------------
 *
 * EmbImageConfigure --
 *
 *	This function is called to handle configuration options for an
 *	embedded image, using an objc/objv list.
 *
 * Results:
 *	The return value is a standard Tcl result. If TCL_ERROR is returned,
 *	then the interp's result contains an error message..
 *
 * Side effects:
 *	Configuration information for the embedded image changes, such as
 *	alignment, or name of the image.
 *
 *--------------------------------------------------------------
 */








































static int
EmbImageConfigure(
    TkText *textPtr,		/* Information about text widget that contains
				 * embedded image. */
    TkTextSegment *eiPtr,	/* Embedded image to be configured. */



    int objc,			/* Number of strings in objv. */
    Tcl_Obj *const objv[])	/* Array of strings describing configuration
				 * options. */
{
    Tk_Image image;
    Tcl_DString newName;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char *name;
    int dummy;
    int count = 0;		/* The counter for picking a unique name */
    int conflict = 0;		/* True if we have a name conflict */
    size_t len;			/* length of image name */



    if (Tk_SetOptions(textPtr->interp, &eiPtr->body.ei,
	    eiPtr->body.ei.optionTable,
	    objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }







    /*
     * Create the image. Save the old image around and don't free it until
     * after the new one is allocated. This keeps the reference count from
     * going to zero so the image doesn't have to be recreated if it hasn't
     * changed.
     */

    if (eiPtr->body.ei.imageString != NULL) {
	image = Tk_GetImage(textPtr->interp, textPtr->tkwin,
		eiPtr->body.ei.imageString, EmbImageProc, eiPtr);
	if (image == NULL) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (eiPtr->body.ei.image != NULL) {
	Tk_FreeImage(eiPtr->body.ei.image);
    }
    eiPtr->body.ei.image = image;

    if (eiPtr->body.ei.name != NULL) {
    	return TCL_OK;
    }

    /*
     * Find a unique name for this image. Use imageName (or imageString) if
     * available, otherwise tack on a #nn and use it. If a name is already
     * associated with this image, delete the name.
     */

    name = eiPtr->body.ei.imageName;
    if (name == NULL) {
    	name = eiPtr->body.ei.imageString;
    }
    if (name == NULL) {
	Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(
		"Either a \"-name\" or a \"-image\" argument must be"
		" provided to the \"image create\" subcommand", -1));
	Tcl_SetErrorCode(textPtr->interp, "TK", "TEXT", "IMAGE_CREATE_USAGE",
		NULL);
	return TCL_ERROR;
    }
    len = strlen(name);
    for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
	    &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	char *haveName = (char *)
		Tcl_GetHashKey(&textPtr->sharedTextPtr->imageTable, hPtr);

	if (strncmp(name, haveName, len) == 0) {
	    int newVal = 0;

	    sscanf(haveName+len, "#%d", &newVal);
	    if (newVal > count) {
		count = newVal;
	    }
	    if (len == strlen(haveName)) {
	    	conflict = 1;
	    }
	}
    }

    Tcl_DStringInit(&newName);
    Tcl_DStringAppend(&newName, name, -1);

    if (conflict) {
    	char buf[4 + TCL_INTEGER_SPACE];

	sprintf(buf, "#%d", count+1);
	Tcl_DStringAppend(&newName, buf, -1);
    }
    name = Tcl_DStringValue(&newName);
    hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name,
	    &dummy);
    Tcl_SetHashValue(hPtr, eiPtr);
    Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(name, -1));
    eiPtr->body.ei.name = (char *)ckalloc(Tcl_DStringLength(&newName) + 1);
    strcpy(eiPtr->body.ei.name, name);
    Tcl_DStringFree(&newName);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *



























































































 * EmbImageDeleteProc --
 *
 *	This function is invoked by the text B-tree code whenever an embedded
 *	image lies in a range of characters being deleted.
 *
 * Results:
 *	Returns 0 to indicate that the deletion has been accepted.
 *
 * Side effects:
 *	The embedded image is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

static int
EmbImageDeleteProc(

    TkTextSegment *eiPtr,	/* Segment being deleted. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    Tcl_HashEntry *hPtr;

    if (eiPtr->body.ei.image != NULL) {

	hPtr = Tcl_FindHashEntry(&eiPtr->body.ei.sharedTextPtr->imageTable,
		eiPtr->body.ei.name);
	if (hPtr != NULL) {
	    /*
	     * (It's possible for there to be no hash table entry for this
	     * image, if an error occurred while creating the image segment
	     * but before the image got added to the table)
	     */



	    Tcl_DeleteHashEntry(hPtr);

	}
	Tk_FreeImage(eiPtr->body.ei.image);
    }

    /*
     * No need to supply a tkwin argument, since we have no window-specific

     * options.
     */


    Tk_FreeConfigOptions((char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable,
	    NULL);
    if (eiPtr->body.ei.name) {
	ckfree(eiPtr->body.ei.name);
    }
    ckfree(eiPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageCleanupProc --
 *
 *	This function is invoked by the B-tree code whenever a segment
 *	containing an embedded image is moved from one line to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The linePtr field of the segment gets updated.

 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
EmbImageCleanupProc(

    TkTextSegment *eiPtr,	/* Mark segment that's being moved. */



    TkTextLine *linePtr)	/* Line that now contains segment. */

{







    eiPtr->body.ei.linePtr = linePtr;
    return eiPtr;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageLayoutProc --
 *






|
>







|
<
>
|
<

>
|
|
>
>





<
<
|
|
>
>
|
<
|
|
|
<
|
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
|
>
|
>
>
|
|
<
<
|







|
|

|
<

|
>




















|
<



|

|
<

|
>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

|






>












<
|


>
>
>

|
<
<




|


|

<
|
|
<


>
>
>
|
|
|
|
<
>

<

<
>





|


|

<
|
|
<



>
>
>


|
>
>
|
|
>
>
>
|
>
>
>
|
>
>
>
>
>
>
|
|
<

<
|
<
<
<
<
<
|
|
<
|


|

|
|
|
|

|
|
|
|
|
|
|
>
>
>
|
>
|
|
|

<
<
<
|
|
<
|

|
|
|

<
<
|
<
<
<
<
<
<
<
<
<
<

|
|
|
|

<
|
|
>
|
>
|
>
|
|
>
|
>
>
|
>
>
>
|
>
|
>
>
|
>
|
>



<





<
|
>
|
<
|
<

|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>












|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<

>
>
>

|
<


<
<
<

|
|
|
|
>
|
>
|
<
|


>
>
>
>
>
>








|
|
<
|





|
|

|
|
<
<


<
<
<
<
<
|
|
<
<
<
<
|
|
|
|
<
|
|
<
<
<
<
<

<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|


|










>

<
|
<
<

|

|
>
|
|
<
<
<
<
<
<

>
>
|
>
|
<
|
|
<
<
>
|
<
>
|
<
<
<
<
|
<
|





|

|
|





|
>




|
|
>
|
>
>
>
|
>
|
>
>
>
>
>
>
>
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18

19
20
21
22
23
24
25
26
27
28
29


30
31
32
33
34

35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396

397
398

399
400
401
402
403
404
405
406
407

408
409

410

411
412
413
414
415
416
417
418
419
420
421

422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453

454





455
456

457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482



483
484

485
486
487
488
489
490


491










492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531

532
533
534

535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690

691
692



693
694
695
696
697
698
699
700
701

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720

721
722
723
724
725
726
727
728
729
730
731


732
733





734
735




736
737
738
739

740
741





742


743









744


745














746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
/*
 * 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 © 1997 Sun Microsystems, Inc.
 * Copyright © 2015-2017 Gregor Cramer
 *
 * 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"
#include "tkTextTagSet.h"

#include "tkTextUndo.h"
#include <assert.h>


#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

/*
 * Prototypes for functions defined in this file:
 */



static void		EmbImageCheckProc(const TkSharedText *sharedTextPtr,
			    const TkTextSegment *segPtr);
static Tcl_Obj *	EmbImageInspectProc(const TkSharedText *sharedTextPtr,
			    const TkTextSegment *segPtr);
static void		EmbImageBboxProc(TkText *textPtr, TkTextDispChunk *chunkPtr, Tcl_Size index, int y,

			    int lineHeight, int baseline, int *xPtr, int *yPtr, int *widthPtr,
			    int *heightPtr);
static int		EmbImageConfigure(TkText *textPtr, TkTextSegment *eiPtr, int *maskPtr,

			    int undoable, int objc, Tcl_Obj *const objv[]);
static int		EmbImageDeleteProc(TkSharedText *sharedTextPtr, TkTextSegment *segPtr,
			    int flags);
static int		EmbImageRestoreProc(TkSharedText *sharedTextPtr, TkTextSegment *segPtr);
static void		EmbImageDisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr, int x, int y,
			    int lineHeight, int baseline, Display *display, Drawable dst, int screenY);
static int		EmbImageLayoutProc(const TkTextIndex *indexPtr, TkTextSegment *segPtr,
			    Tcl_Size offset, int maxX, Tcl_Size maxChars, int noCharsYet, TkWrapMode wrapMode,
			    TkTextSpaceMode spaceMode, TkTextDispChunk *chunkPtr);
static void		EmbImageProc(void *clientData, int x, int y, int width, int height,
			    int imageWidth, int imageHeight);
static TkTextSegment *	MakeImage(TkText *textPtr);
static void		ReleaseImage(TkTextSegment *eiPtr);

static const TkTextDispChunkProcs layoutImageProcs = {
    TEXT_DISP_IMAGE,		/* type */
    EmbImageDisplayProc,	/* displayProc */
    NULL,			/* undisplayProc */
    NULL,			/* measureProc */
    EmbImageBboxProc,	        /* bboxProc */
};

/*
 * We need some private undo/redo stuff.
 */

static void UndoLinkSegmentPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void RedoLinkSegmentPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void UndoLinkSegmentDestroy(TkSharedText *, TkTextUndoToken *, int);
static void UndoLinkSegmentGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static void RedoLinkSegmentGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static Tcl_Obj *UndoLinkSegmentGetCommand(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *UndoLinkSegmentInspect(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *RedoLinkSegmentInspect(const TkSharedText *, const TkTextUndoToken *);

static const Tk_UndoType undoTokenLinkSegmentType = {
    TK_TEXT_UNDO_IMAGE,		/* action */
    UndoLinkSegmentGetCommand,	/* commandProc */
    UndoLinkSegmentPerform,	/* undoProc */
    UndoLinkSegmentDestroy,	/* destroyProc */
    UndoLinkSegmentGetRange,	/* rangeProc */
    UndoLinkSegmentInspect	/* inspectProc */
};

static const Tk_UndoType redoTokenLinkSegmentType = {
    TK_TEXT_REDO_IMAGE,		/* action */
    UndoLinkSegmentGetCommand,	/* commandProc */
    RedoLinkSegmentPerform,	/* undoProc */
    UndoLinkSegmentDestroy,	/* destroyProc */
    RedoLinkSegmentGetRange,	/* rangeProc */
    RedoLinkSegmentInspect	/* inspectProc */
};

typedef struct UndoTokenLinkSegment {
    const Tk_UndoType *undoType;
    TkTextSegment *segPtr;
} UndoTokenLinkSegment;

typedef struct RedoTokenLinkSegment {
    const Tk_UndoType *undoType;
    TkTextSegment *segPtr;
    TkTextUndoIndex index;


} RedoTokenLinkSegment;

/*
 * The following structure declares the "embedded image" segment type.
 */

const Tk_SegType tkTextEmbImageType = {
    "image",			/* name */
    SEG_GROUP_IMAGE,		/* group */
    GRAVITY_NEUTRAL,		/* gravity */
    EmbImageDeleteProc,		/* deleteProc */
    EmbImageRestoreProc,	/* restoreProc */

    EmbImageLayoutProc,		/* layoutProc */
    EmbImageCheckProc,		/* checkProc */
    EmbImageInspectProc		/* inspectProc */
};

/*
 * Definitions for alignment values:
 */

static const char *const alignStrings[] = {
    "baseline", "bottom", "center", "top", NULL
};

typedef enum {
    ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
} alignMode;

/*
 * Information used for parsing image configuration options:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
	"center", TCL_INDEX_NONE, offsetof(TkTextEmbImage, align), 0, alignStrings, TK_TEXT_LINE_GEOMETRY},

    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padY), 0, 0, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageString), TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY},

    {TK_OPTION_STRING, "-name", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tags", NULL, NULL,
	NULL, TCL_INDEX_NONE, TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

DEBUG_ALLOC(extern unsigned tkTextCountNewUndoToken);
DEBUG_ALLOC(extern unsigned tkTextCountNewSegment);

/*
 * Some helper functions.
 */

static void
TextChanged(
    TkSharedText *sharedTextPtr,
    TkTextIndex *indexPtr,
    int mask)
{
    TkrTextChanged(sharedTextPtr, NULL, indexPtr, indexPtr);

    if (mask & TK_TEXT_LINE_GEOMETRY) {
	TkTextInvalidateLineMetrics(sharedTextPtr, NULL,
		TkTextIndexGetLine(indexPtr), 0, TK_TEXT_INVALIDATE_ONLY);
    }
}

static void
GetIndex(
    const TkSharedText *sharedTextPtr,
    TkTextSegment *segPtr,
    TkTextIndex *indexPtr)
{
    TkTextIndexClear2(indexPtr, NULL, sharedTextPtr->tree);
    TkTextIndexSetSegment(indexPtr, segPtr);
}

/*
 * Some functions for the undo/redo mechanism.
 */

static Tcl_Obj *
UndoLinkSegmentGetCommand(
    TCL_UNUSED(const TkSharedText *),
    TCL_UNUSED(const TkTextUndoToken *))
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("image", TCL_INDEX_NONE));
    return objPtr;
}

static Tcl_Obj *
UndoLinkSegmentInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const UndoTokenLinkSegment *token = (const UndoTokenLinkSegment *) item;
    Tcl_Obj *objPtr = UndoLinkSegmentGetCommand(sharedTextPtr, item);
    char buf[TK_POS_CHARS];
    TkTextIndex index;

    GetIndex(sharedTextPtr, token->segPtr, &index);
    TkTextIndexPrint(sharedTextPtr, NULL, &index, buf);
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
    return objPtr;
}

static void
UndoLinkSegmentPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    TCL_UNUSED(int))
{
    const UndoTokenLinkSegment *token = (const UndoTokenLinkSegment *) undoInfo->token;
    TkTextSegment *segPtr = token->segPtr;
    TkTextIndex index;

    if (redoInfo) {
	RedoTokenLinkSegment *redoToken;
	redoToken = (RedoTokenLinkSegment *)ckalloc(sizeof(RedoTokenLinkSegment));
	redoToken->undoType = &redoTokenLinkSegmentType;
	TkBTreeMakeUndoIndex(sharedTextPtr, segPtr, &redoToken->index);
	redoInfo->token = (TkTextUndoToken *) redoToken;
	(redoToken->segPtr = segPtr)->refCount += 1;
	DEBUG_ALLOC(tkTextCountNewUndoToken++);
    }

    GetIndex(sharedTextPtr, segPtr, &index);
    TextChanged(sharedTextPtr, &index, TK_TEXT_LINE_GEOMETRY);
    TkBTreeUnlinkSegment(sharedTextPtr, segPtr);
    EmbImageDeleteProc(sharedTextPtr, segPtr, 0);
    TK_BTREE_DEBUG(TkBTreeCheck(sharedTextPtr->tree));
}

static void
UndoLinkSegmentDestroy(
    TCL_UNUSED(TkSharedText *),
    TkTextUndoToken *item,
    int reused)
{
    if (!reused) {
	UndoTokenLinkSegment *token = (UndoTokenLinkSegment *) item;

	if (--token->segPtr->refCount == 0) {
	    ReleaseImage(token->segPtr);
	}
    }
}

static void
UndoLinkSegmentGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    const UndoTokenLinkSegment *token = (const UndoTokenLinkSegment *) item;

    GetIndex(sharedTextPtr, token->segPtr, startIndex);
    *endIndex = *startIndex;
}

static Tcl_Obj *
RedoLinkSegmentInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const RedoTokenLinkSegment *token = (const RedoTokenLinkSegment *) item;
    Tcl_Obj *objPtr = EmbImageInspectProc(sharedTextPtr, token->segPtr);
    char buf[TK_POS_CHARS];
    TkTextIndex index;
    Tcl_Obj *idxPtr;

    TkBTreeUndoIndexToIndex(sharedTextPtr, &token->index, &index);
    TkTextIndexPrint(sharedTextPtr, NULL, &index, buf);
    idxPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
    Tcl_ListObjReplace(NULL, objPtr, 0, 0, 1, &idxPtr);
    return objPtr;
}

static void
RedoLinkSegmentPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    TCL_UNUSED(int))
{
    RedoTokenLinkSegment *token = (RedoTokenLinkSegment *) undoInfo->token;
    TkTextIndex index;

    TkBTreeReInsertSegment(sharedTextPtr, &token->index, token->segPtr);

    if (redoInfo) {
	redoInfo->token = undoInfo->token;
	token->undoType = &undoTokenLinkSegmentType;
    }

    GetIndex(sharedTextPtr, token->segPtr, &index);
    TextChanged(sharedTextPtr, &index, TK_TEXT_LINE_GEOMETRY);
    token->segPtr->refCount += 1;
    TK_BTREE_DEBUG(TkBTreeCheck(sharedTextPtr->tree));
}

static void
RedoLinkSegmentGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    const RedoTokenLinkSegment *token = (const RedoTokenLinkSegment *) item;
    TkBTreeUndoIndexToIndex(sharedTextPtr, &token->index, startIndex);
    *endIndex = *startIndex;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextImageCmd --
 *
 *	This function implements the "image" widget command for text widgets.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result or error.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MatchTagsOption(
    const char *opt)
{
    static const char *pattern = "-tags";
    const char *p = pattern;
    const char *start = opt;

    for ( ; *opt; ++p, ++opt) {
	if (*p != *opt) {
	    return opt > start && *p == '\0';
	}
    }

    return 1;
}

int
TkTextImageCmd(
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already
				 * parsed this command enough to know that
				 * objv[1] is "image". */
{
    int idx;
    TkTextSegment *eiPtr;
    TkSharedText *sharedTextPtr;
    TkTextIndex index;
    static const char *const optionStrings[] = {
	"cget", "configure", "create", "names", NULL
    };
    enum opts {
	CMD_CGET, CMD_CONF, CMD_CREATE, CMD_NAMES
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "option", 0, &idx) != TCL_OK) {
	return TCL_ERROR;
    }

    sharedTextPtr = textPtr->sharedTextPtr;

    switch ((enum opts) idx) {
    case CMD_CGET:


	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[3], &index)) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexGetContentSegment(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {

	    Tcl_AppendResult(interp, "no embedded image at index \"",
		    Tcl_GetString(objv[3]), "\"", (char *)NULL);

	    return TCL_ERROR;
	}
	if (MatchTagsOption(Tcl_GetString(objv[4]))) {
	    TkTextFindTags(interp, textPtr, eiPtr, 1);
	} else {
	    Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) &eiPtr->body.ei,
		    eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin);
	    if (!objPtr) {
		return TCL_ERROR;

	    }
	    Tcl_SetObjResult(interp, objPtr);

	}

	return TCL_OK;
    case CMD_CONF:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[3], &index)) {
	    return TCL_ERROR;
	}
	eiPtr = TkTextIndexGetContentSegment(&index, NULL);
	if (eiPtr->typePtr != &tkTextEmbImageType) {

	    Tcl_AppendResult(interp, "no embedded image at index \"",
		    Tcl_GetString(objv[3]), "\"", (char *)NULL);

	    return TCL_ERROR;
	}
	if (objc <= 5) {
	    Tcl_Obj **objs;
	    Tcl_Size objn = 0, i;

	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp,
		    &eiPtr->body.ei, eiPtr->body.ei.optionTable,
		    objc == 5 ? objv[4] : NULL, textPtr->tkwin);
	    if (!objPtr) {
		return TCL_ERROR;
	    }
	    Tcl_ListObjGetElements(NULL, objPtr, &objn, &objs);
	    for (i = 0; i < objn; ++i) {
		Tcl_Obj **objv1;
		Tcl_Size objc1 = 0;

		Tcl_ListObjGetElements(NULL, objs[i], &objc1, &objv1);
		if (objc1 == 5 && strcmp(Tcl_GetString(objv1[0]), "-tags") == 0) {
		    Tcl_Obj *valuePtr;

		    /* { argvName, dbName, dbClass, defValue, current value } */
		    TkTextFindTags(interp, textPtr, eiPtr, 1);
		    valuePtr = Tcl_GetObjResult(interp);
		    Tcl_ListObjReplace(NULL, objs[i], 4, 1, 1, &valuePtr);
		}
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;

	} else {

	    int mask;





	    int rc = EmbImageConfigure(textPtr, eiPtr, &mask, 1, objc - 4, objv + 4);
	    TextChanged(sharedTextPtr, &index, mask);

	    return rc;
	}
    case CMD_CREATE: {
	    int mask;

	    /*
	     * Add a new image. Find where to put the new image, and mark that
	     * position for redisplay.
	     */

	    if (objc < 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
		return TCL_ERROR;
	    }
	    if (!TkTextGetIndexFromObj(interp, textPtr, objv[3], &index)) {
		return TCL_ERROR;
	    }
	    if (textPtr->state == TK_TEXT_STATE_DISABLED &&
		    TkTextAttemptToModifyDisabledWidget(interp) != TCL_OK) {
		return TCL_ERROR;
	    }

	    /*
	     * Don't allow insertions on the last line of the text.
	     */




	    if (!TkTextIndexEnsureBeforeLastChar(&index)) {
		return TkTextAttemptToModifyDeadWidget(interp);

	    }

	    /*
	     * Create the new image segment and initialize it.
	     */



	    eiPtr = MakeImage(textPtr);











	    /*
	     * Link the segment into the text widget, then configure it (delete it
	     * again if the configuration fails).
	     */


	    TkBTreeLinkSegment(sharedTextPtr, eiPtr, &index);
	    if (EmbImageConfigure(textPtr, eiPtr, &mask, 0, objc - 4, objv + 4) != TCL_OK) {
		TkBTreeUnlinkSegment(sharedTextPtr, eiPtr);
		EmbImageDeleteProc(sharedTextPtr, eiPtr, 0);
		return TCL_ERROR;
	    }
	    TextChanged(sharedTextPtr, &index, mask);

	    if (!TkTextUndoStackIsFull(sharedTextPtr->undoStack)) {
		UndoTokenLinkSegment *token;

		assert(sharedTextPtr->undoStack);
		assert(eiPtr->typePtr == &tkTextEmbImageType);

		token = (UndoTokenLinkSegment *)ckalloc(sizeof(UndoTokenLinkSegment));
		token->undoType = &undoTokenLinkSegmentType;
		token->segPtr = eiPtr;
		eiPtr->refCount += 1;
		DEBUG_ALLOC(tkTextCountNewUndoToken++);

		TkTextPushUndoToken(sharedTextPtr, token, 0);
	    }

	    TkTextUpdateAlteredFlag(sharedTextPtr);
	}
	return TCL_OK;
    case CMD_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;


	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}

	for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->imageTable, &search);
		hPtr;
		hPtr = Tcl_NextHashEntry(&search)) {

	    Tcl_AppendElement(interp, (const char *)Tcl_GetHashKey(&sharedTextPtr->imageTable, hPtr));

	}
	return TCL_OK;
    }
    }
    assert(!"unexpected switch fallthrough");
    return TCL_ERROR; /* shouldn't be reached */
}

/*
 *--------------------------------------------------------------
 *
 * MakeImage --
 *
 *	This function is called to create an image segment.
 *
 * Results:
 *	The return value is the newly created image.
 *
 * Side effects:
 *	Some memory will be allocated.
 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
MakeImage(
    TkText *textPtr)		/* Information about text widget that contains embedded image. */
{
    TkTextSegment *eiPtr;

    eiPtr = (TkTextSegment *)ckalloc(SEG_SIZE(TkTextEmbImage));
    memset(eiPtr, 0, SEG_SIZE(TkTextEmbImage));
    NEW_SEGMENT(eiPtr);
    eiPtr->typePtr = &tkTextEmbImageType;
    eiPtr->size = 1;
    eiPtr->refCount = 1;
    eiPtr->body.ei.sharedTextPtr = textPtr->sharedTextPtr;
    eiPtr->body.ei.align = ALIGN_CENTER;
    eiPtr->body.ei.optionTable = Tk_CreateOptionTable(textPtr->interp, optionSpecs);
    DEBUG_ALLOC(tkTextCountNewSegment++);

    return eiPtr;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextMakeImage --
 *
 *	This function is called to create an image segment.
 *
 * Results:
 *	The return value is a standard Tcl result. If TCL_ERROR is returned,
 *	then the interp's result contains an error message.
 *
 * Side effects:
 *	Some memory will be allocated.
 *
 *--------------------------------------------------------------
 */

TkTextSegment *
TkTextMakeImage(
    TkText *textPtr,		/* Information about text widget that contains embedded image. */
    Tcl_Obj *options)		/* Options for this image. */
{
    TkTextSegment *eiPtr;
    Tcl_Obj **objv;
    Tcl_Size objc;

    assert(options);

    if (Tcl_ListObjGetElements(textPtr->interp, options, &objc, &objv) != TCL_OK) {
	return NULL;
    }

    eiPtr = MakeImage(textPtr);

    if (EmbImageConfigure(textPtr, eiPtr, NULL, 0, objc, objv) == TCL_OK) {
	Tcl_ResetResult(textPtr->interp);
    } else {
	EmbImageDeleteProc(textPtr->sharedTextPtr, eiPtr, 0);
	eiPtr = NULL;
    }

    return eiPtr;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageConfigure --
 *
 *	This function is called to handle configuration options for an
 *	embedded image, using an objc/objv list.
 *
 * Results:
 *	The return value is a standard Tcl result. If TCL_ERROR is returned,
 *	then the interp's result contains an error message.
 *
 * Side effects:
 *	Configuration information for the embedded image changes, such as
 *	alignment, or name of the image.
 *
 *--------------------------------------------------------------
 */

static void
SetImageName(
    TkText *textPtr,
    TkTextSegment *eiPtr,
    const char *name)
{
    Tcl_DString newName;
    TkTextEmbImage *img;
    int dummy, length;

    assert(name);
    assert(!eiPtr->body.ei.name);
    assert(!eiPtr->body.ei.hPtr);

    /*
     * Create an unique name for this image.
     */

    Tcl_DStringInit(&newName);
    while (Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name)) {
	char buf[4 + TCL_INTEGER_SPACE];
	snprintf(buf, sizeof(buf), "#%" TCL_Z_MODIFIER "u", ++textPtr->sharedTextPtr->imageCount);
	Tcl_DStringSetLength(&newName, 0);
	Tcl_DStringAppend(&newName, name, TCL_INDEX_NONE);
	Tcl_DStringAppend(&newName, buf, TCL_INDEX_NONE);
	name = Tcl_DStringValue(&newName);
    }
    length = strlen(name);

    img = &eiPtr->body.ei;
    img->hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name, &dummy);
    textPtr->sharedTextPtr->numImages += 1;
    Tcl_SetHashValue(img->hPtr, eiPtr);
    img->name = (char *)ckalloc(length + 1);
    memcpy(img->name, name, length + 1);
    Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(name, TCL_INDEX_NONE));
    Tcl_DStringFree(&newName);
}

static int
EmbImageConfigure(
    TkText *textPtr,		/* Information about text widget that contains embedded image. */

    TkTextSegment *eiPtr,	/* Embedded image to be configured. */
    int *maskPtr,		/* Return the bit-wise OR of the typeMask fields of affected options,
    				 * can be NULL. */
    int undoable,		/* Replacement of tags is undoable? */
    int objc,			/* Number of strings in objv. */
    Tcl_Obj *const objv[])	/* Array of strings describing configuration options. */

{
    Tk_Image image;



    char *name;
    int i;
    TkTextEmbImage *img = &eiPtr->body.ei;

    if (maskPtr) {
	*maskPtr = 0;
    }

    if (Tk_SetOptions(textPtr->interp, img, img->optionTable, objc, objv, textPtr->tkwin,

		NULL, maskPtr) != TCL_OK) {
	return TCL_ERROR;
    }

    for (i = 0; i + 1 < objc; i += 2) {
	if (MatchTagsOption(Tcl_GetString(objv[i]))) {
	    TkTextReplaceTags(textPtr, eiPtr, undoable, objv[i + 1]);
	}
    }

    /*
     * Create the image. Save the old image around and don't free it until
     * after the new one is allocated. This keeps the reference count from
     * going to zero so the image doesn't have to be recreated if it hasn't
     * changed.
     */

    if (img->imageString) {
	image = Tk_GetImage(textPtr->interp, textPtr->tkwin, img->imageString, EmbImageProc, eiPtr);

	if (!image) {
	    return TCL_ERROR;
	}
    } else {
	image = NULL;
    }
    if (img->image) {
	Tk_FreeImage(img->image);
    }
    if ((img->image = image)) {
	Tk_SizeOfImage(image, &img->imgWidth, &img->imgHeight);


    }






    if (!img->name) {
	if (!(name = img->imageName) && !(name = img->imageString)) {




	    Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(
		    "Either a \"-name\" or a \"-image\" argument must be"
		    " provided to the \"image create\" subcommand", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(textPtr->interp, "TK", "TEXT", "IMAGE_CREATE_USAGE", (char *)NULL);

	    return TCL_ERROR;
	}








	Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(img->name, TCL_INDEX_NONE));









	SetImageName(textPtr, eiPtr, name);


    }















    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageInspectProc --
 *
 *	This function is invoked to build the information for
 *	"inspect".
 *
 * Results:
 *	Return a TCL object containing the information for
 *	"inspect".
 *
 * Side effects:
 *	Storage is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
EmbImageInspectProc(
    const TkSharedText *sharedTextPtr,
    const TkTextSegment *segPtr)
{
    Tcl_Obj *objPtr = Tcl_NewObj();
    Tcl_Obj *objPtr2 = Tcl_NewObj();
    TkTextTag **tagLookup = sharedTextPtr->tagLookup;
    const TkTextTagSet *tagInfoPtr = segPtr->tagInfoPtr;
    unsigned i = TkTextTagSetFindFirst(tagInfoPtr);
    const TkTextEmbImage *img = &segPtr->body.ei;
    Tcl_DString opts;

    assert(sharedTextPtr->peers);

    for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) {
	const TkTextTag *tagPtr = tagLookup[i];
	Tcl_ListObjAppendElement(NULL, objPtr2, Tcl_NewStringObj(tagPtr->name, TCL_INDEX_NONE));
    }

    Tcl_DStringInit(&opts);
    TkTextInspectOptions(sharedTextPtr->peers, &segPtr->body.ei, segPtr->body.ei.optionTable,
	    &opts, 0);

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(segPtr->typePtr->name, TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(img->name, TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, objPtr2);
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(Tcl_DStringValue(&opts),
	    Tcl_DStringLength(&opts)));

    Tcl_DStringFree(&opts);
    return objPtr;
}

/*
 *--------------------------------------------------------------
 *
 * ReleaseImage --
 *
 *	This function is releasing the embedded image all it's
 *	associated resources.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The embedded image is deleted, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

static void
ReleaseImage(
    TkTextSegment *eiPtr)
{
    TkTextEmbImage *img = &eiPtr->body.ei;

    if (img->image) {
	Tk_FreeImage(img->image);
    }

    /*
     * No need to supply a tkwin argument, since we have no window-specific options.
     */

    Tk_FreeConfigOptions(img, img->optionTable, NULL);
    if (img->name) {
	ckfree(img->name);
    }
    TkBTreeFreeSegment(eiPtr);
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageDeleteProc --
 *
 *	This function is invoked by the text B-tree code whenever an
 *	embedded image lies in a range of characters being deleted.
 *
 * Results:
 *	Returns true to indicate that the deletion has been accepted.
 *
 * Side effects:
 *	The embedded image is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

static int
EmbImageDeleteProc(
    TCL_UNUSED(TkSharedText *),/* Handle to shared text resource. */
    TkTextSegment *eiPtr,	/* Segment being deleted. */

    TCL_UNUSED(int))			/* Flags controlling the deletion. */


{
    TkTextEmbImage *img;

    assert(eiPtr->typePtr);
    assert(eiPtr->refCount > 0);

    img = &eiPtr->body.ei;







    if (img->hPtr) {
	img->sharedTextPtr->numImages -= 1;
	Tcl_DeleteHashEntry(img->hPtr);
	img->hPtr = NULL;
    }


    if (eiPtr->refCount == 1) {


	ReleaseImage(eiPtr);
    } else {

	eiPtr->refCount -= 1;
    }






    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageRestoreProc --
 *
 *	This function is called when an image segment will be
 *	restored from the undo chain.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The name of the mark will be freed, and the mark will be
 *	re-entered into the hash table.
 *
 *--------------------------------------------------------------
 */

static int
EmbImageRestoreProc(
    TkSharedText *sharedTextPtr,/* Handle to shared text resource. */
    TkTextSegment *eiPtr)	/* Segment to reuse. */
{
    TkTextEmbImage *img = &eiPtr->body.ei;
    int isNew;

    assert(img->sharedTextPtr == sharedTextPtr);

    if (img->image) {
	assert(!img->hPtr);
	img->hPtr = Tcl_CreateHashEntry(&sharedTextPtr->imageTable, img->name, &isNew);
	sharedTextPtr->numImages += 1;
	assert(isNew);
	Tcl_SetHashValue(img->hPtr, eiPtr);
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageLayoutProc --
 *
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

554
555
556
557
558

559
560
561
562
563
564
565
566


567
568


569
570
571
572

573
574
575
576

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
606
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

static int
EmbImageLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *eiPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TCL_UNUSED(TkSizeT),	/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */
    TkTextDispChunk *chunkPtr)
				/* Structure to fill in with information about
				 * this chunk. The x field has already been
				 * set by the caller. */
{

    int width, height;

    if (offset != 0) {
	Tcl_Panic("Non-zero offset in EmbImageLayoutProc");
    }


    /*
     * See if there's room for this image on this line.
     */

    if (eiPtr->body.ei.image == NULL) {
	width = 0;
	height = 0;


    } else {
	Tk_SizeOfImage(eiPtr->body.ei.image, &width, &height);


	width += 2*eiPtr->body.ei.padX;
	height += 2*eiPtr->body.ei.padY;
    }
    if ((width > (maxX - chunkPtr->x))

	    && !noCharsYet && (textPtr->wrapMode != TEXT_WRAPMODE_NONE)) {
	return 0;
    }


    /*
     * Fill in the chunk structure.
     */

    chunkPtr->displayProc = EmbImageDisplayProc;
    chunkPtr->undisplayProc = NULL;
    chunkPtr->measureProc = NULL;
    chunkPtr->bboxProc = EmbImageBboxProc;
    chunkPtr->numBytes = 1;
    if (eiPtr->body.ei.align == ALIGN_BASELINE) {
	chunkPtr->minAscent = height - eiPtr->body.ei.padY;
	chunkPtr->minDescent = eiPtr->body.ei.padY;
	chunkPtr->minHeight = 0;
    } else {
	chunkPtr->minAscent = 0;
	chunkPtr->minDescent = 0;
	chunkPtr->minHeight = height;
    }
    chunkPtr->width = width;
    chunkPtr->breakIndex = -1;
    chunkPtr->breakIndex = 1;
    chunkPtr->clientData = eiPtr;

    eiPtr->body.ei.chunkCount += 1;
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageCheckProc --







<
|

|
<
|
<
|
<
<
|
|
|
<
|
|
|
|

>


<
<
<
>





|


>
>

|
>
>
|
|

|
>
|



>
|
|
|

<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
<
|
>
|







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
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

static int
EmbImageLayoutProc(

    const TkTextIndex *indexPtr,/* Identifies first character in chunk. */
    TkTextSegment *eiPtr,	/* Segment corresponding to indexPtr. */
    TCL_UNUSED(Tcl_Size),			/* Offset within segPtr corresponding to indexPtr (always 0). */

    int maxX,			/* Chunk must not occupy pixels at this position or higher. */

    TCL_UNUSED(Tcl_Size),		/* Chunk must not include more than this many characters. */


    int noCharsYet,		/* 'true' means no characters have been assigned to this line yet. */
    TkWrapMode wrapMode,	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or TEXT_WRAPMODE_WORD. */

    TCL_UNUSED(TkTextSpaceMode),	/* Not used. */
    TkTextDispChunk *chunkPtr)	/* Structure to fill in with information about this chunk. The x
				 * field has already been set by the caller. This argument may be
				 * NULL. */
{
    TkTextEmbImage *img = &eiPtr->body.ei;
    int width, height;




    assert(indexPtr->textPtr);

    /*
     * See if there's room for this image on this line.
     */

    if (!img->image) {
	width = 0;
	height = 0;
	img->imgWidth = 0;
	img->imgHeight = 0;
    } else {
	Tk_SizeOfImage(img->image, &width, &height);
	img->imgWidth = width;
	img->imgHeight = height;
	width += 2*img->padX;
	height += 2*img->padY;
    }
    if ((width > maxX - (chunkPtr ? chunkPtr->x : 0))
	    && !noCharsYet
	    && (indexPtr->textPtr->wrapMode != TEXT_WRAPMODE_NONE)) {
	return 0;
    }

    if (chunkPtr) {
	/*
	 * Fill in the chunk structure.
	 */



	chunkPtr->layoutProcs = &layoutImageProcs;

	chunkPtr->numBytes = 1;
	if (img->align == ALIGN_BASELINE) {
	    chunkPtr->minAscent = height - img->padY;
	    chunkPtr->minDescent = img->padY;
	    chunkPtr->minHeight = 0;
	} else {
	    chunkPtr->minAscent = 0;
	    chunkPtr->minDescent = 0;
	    chunkPtr->minHeight = height;
	}
	chunkPtr->width = width;
	chunkPtr->breakIndex = (wrapMode == TEXT_WRAPMODE_NONE) ? -1 : 1;

	chunkPtr->clientData = eiPtr;
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageCheckProc --
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
 *	image.
 *
 *--------------------------------------------------------------
 */

static void
EmbImageCheckProc(

    TkTextSegment *eiPtr,	/* Segment to check. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    if (eiPtr->nextPtr == NULL) {
	Tcl_Panic("EmbImageCheckProc: embedded image is last segment in line");
    }
    if (eiPtr->size != 1) {
	Tcl_Panic("EmbImageCheckProc: embedded image has size %d",
		(int)eiPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageDisplayProc --







>
|
<

|



|
<







1022
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036

1037
1038
1039
1040
1041
1042
1043
 *	image.
 *
 *--------------------------------------------------------------
 */

static void
EmbImageCheckProc(
    TCL_UNUSED(const TkSharedText *),	/* Handle to shared text resource. */
    const TkTextSegment *eiPtr)		/* Segment to check. */

{
    if (!eiPtr->nextPtr) {
	Tcl_Panic("EmbImageCheckProc: embedded image is last segment in line");
    }
    if (eiPtr->size != 1) {
	Tcl_Panic("EmbImageCheckProc: embedded image has size %d", eiPtr->size);

    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageDisplayProc --
658
659
660
661
662
663
664
665
666
667
668
669
670
671

672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688
689
690


691


692
693
694
695
696
697
698
				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    int y,			/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),	/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw */
    TCL_UNUSED(int))	/* Y-coordinate in text window that
				 * corresponds to y. */
{
    TkTextSegment *eiPtr = (TkTextSegment *)chunkPtr->clientData;
    int lineX, imageX, imageY, width, height;

    Tk_Image image;

    image = eiPtr->body.ei.image;
    if (image == NULL) {
	return;
    }
    if ((x + chunkPtr->width) <= 0) {
	return;

    }

    /*
     * Compute the image's location and size in the text widget, taking into
     * account the align value for the image.
     */

    EmbImageBboxProc(textPtr, chunkPtr, 0, y, lineHeight, baseline, &lineX,
	    &imageY, &width, &height);
    imageX = lineX - chunkPtr->x + x;



    Tk_RedrawImage(image, 0, 0, width, height, dst, imageX, imageY);


}

/*
 *--------------------------------------------------------------
 *
 * EmbImageBboxProc --
 *







|

|
<


<
>


<
<
<
<
|
<
>
|
<
|
|
|
|

|
|
<

>
>
|
>
>







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
				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    int y,			/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),		/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw */
    TCL_UNUSED(int))		/* Y-coordinate in text window that corresponds to y. */

{
    TkTextSegment *eiPtr = (TkTextSegment *)chunkPtr->clientData;

    TkTextEmbImage *img = &eiPtr->body.ei;
    Tk_Image image;





    if ((image = img->image) && x + chunkPtr->width > 0) {

	int lineX, imageY, width, height;


	/*
	 * Compute the image's location and size in the text widget, taking into
	 * account the align value for the image.
	 */

	EmbImageBboxProc(textPtr, chunkPtr, 0, y, lineHeight, baseline, &lineX,
		&imageY, &width, &height);


	if (x + chunkPtr->width > 0) {
	    int imageX = lineX - chunkPtr->x + x;
	    Tk_RedrawImage(image, 0, 0, width, height, dst, imageX, imageY);
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageBboxProc --
 *
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
 *--------------------------------------------------------------
 */

static void
EmbImageBboxProc(
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(int),			/* Index of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Location of line's baseline, in pixels
				 * measured down from y. */
    int *xPtr, int *yPtr,	/* Gets filled in with coords of character's
				 * upper-left pixel. */
    int *widthPtr,		/* Gets filled in with width of image, in
				 * pixels. */
    int *heightPtr)		/* Gets filled in with height of image, in
				 * pixels. */
{
    TkTextSegment *eiPtr = (TkTextSegment *)chunkPtr->clientData;

    Tk_Image image;

    image = eiPtr->body.ei.image;
    if (image != NULL) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    } else {
	*widthPtr = 0;
	*heightPtr = 0;
    }

    *xPtr = chunkPtr->x + eiPtr->body.ei.padX;

    switch (eiPtr->body.ei.align) {
    case ALIGN_BOTTOM:
	*yPtr = y + (lineHeight - *heightPtr - eiPtr->body.ei.padY);
	break;
    case ALIGN_CENTER:
	*yPtr = y + (lineHeight - *heightPtr)/2;
	break;
    case ALIGN_TOP:
	*yPtr = y + eiPtr->body.ei.padY;
	break;
    case ALIGN_BASELINE:
	*yPtr = y + (baseline - *heightPtr);
	break;
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextImageIndex --
 *
 *	Given the name of an embedded image within a text widget, returns an
 *	index corresponding to the image's position in the text.
 *
 * Results:
 *	The return value is 1 if there is an embedded image by the given name
 *	in the text widget, 0 otherwise. If the image exists, *indexPtr is
 *	filled in with its index.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextImageIndex(
    TkText *textPtr,		/* Text widget containing image. */
    const char *name,		/* Name of image. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *eiPtr;

    if (textPtr == NULL) {
	return 0;
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name);
    if (hPtr == NULL) {
	return 0;
    }
    eiPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);

    indexPtr->tree = textPtr->sharedTextPtr->tree;


    indexPtr->linePtr = eiPtr->body.ei.linePtr;



    indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr);
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageProc --
 *
 *	This function is called by the image code whenever an image or its
 *	contents changes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The image will be redisplayed.
 *
 *--------------------------------------------------------------
 */

static void










EmbImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    TCL_UNUSED(int),		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    TCL_UNUSED(int),
    TCL_UNUSED(int),	/* Dimensions of area to redisplay (may be
				 * <= 0). */
    TCL_UNUSED(int),
    TCL_UNUSED(int),/* New dimensions of image. */
    TCL_UNUSED(int))

{
    TkTextSegment *eiPtr = (TkTextSegment *)clientData;




    TkTextIndex index;



    index.tree = eiPtr->body.ei.sharedTextPtr->tree;
    index.linePtr = eiPtr->body.ei.linePtr;
    index.byteIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr);

    TkTextChanged(eiPtr->body.ei.sharedTextPtr, NULL, &index, &index);

    /*
     * It's probably not true that all image changes can change the line
     * height, so we could be more efficient here and only call this when



     * necessary.
     */






    TkTextInvalidateLineMetrics(eiPtr->body.ei.sharedTextPtr, NULL,

	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);


}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:

 */







|
<
|
<

|
<
|
<
|
<
|
<


>
|

<
|


|
<


|

|

|





|
















|
|

















|
<
|
<
|
<



>
|
>
>
|
>
>
>
|





















>
>
>
>
>
>
>
>
>
>

|
|
<
|
|
<
|
|
<



>
>
>
>
|
>

>
|
<
<
>
|

<
<
<
>
>
>
|
|
>
>
>
>
>
|
|
>
|
>
>








>

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
 *--------------------------------------------------------------
 */

static void
EmbImageBboxProc(
    TCL_UNUSED(TkText *),
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(Tcl_Size),			/* 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;
    TkTextEmbImage *img = &eiPtr->body.ei;
    Tk_Image image = img->image;


    if (image) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    } else {
	*widthPtr = *heightPtr = 0;

    }

    *xPtr = chunkPtr->x + img->padX;

    switch (img->align) {
    case ALIGN_BOTTOM:
	*yPtr = y + (lineHeight - *heightPtr - img->padY);
	break;
    case ALIGN_CENTER:
	*yPtr = y + (lineHeight - *heightPtr)/2;
	break;
    case ALIGN_TOP:
	*yPtr = y + img->padY;
	break;
    case ALIGN_BASELINE:
	*yPtr = y + (baseline - *heightPtr);
	break;
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextImageIndex --
 *
 *	Given the name of an embedded image within a text widget, returns an
 *	index corresponding to the image's position in the text.
 *
 * Results:
 *	The return value is true if there is an embedded image by the given name
 *	in the text widget, false otherwise. If the image exists, *indexPtr is
 *	filled in with its index.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextImageIndex(
    TkText *textPtr,		/* Text widget containing image. */
    const char *name,		/* Name of image. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *eiPtr;

    assert(textPtr);



    if (!(hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name))) {

	return 0;
    }
    eiPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    TkTextIndexClear(indexPtr, textPtr);
    DEBUG(indexPtr->discardConsistencyCheck = 1);
    TkTextIndexSetSegment(indexPtr, eiPtr);
    DEBUG(indexPtr->discardConsistencyCheck = 0);

    if (TkTextIndexOutsideStartEnd(indexPtr)) {
	return 0;
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageProc --
 *
 *	This function is called by the image code whenever an image or its
 *	contents changes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The image will be redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
GetIndexForWatch(
    TkText* textPtr,
    TkTextIndex *indexPtr,
    void *clientData)
{
    TkTextIndexClear(indexPtr, textPtr);
    TkTextIndexSetSegment(indexPtr, (TkTextSegment *)clientData);
}

static void
EmbImageProc(
    void *clientData,	/* Pointer to widget record. */
    TCL_UNUSED(int),		/* Upper left pixel (within image) that must be redisplayed. */

	TCL_UNUSED(int),
    TCL_UNUSED(int),	/* Dimensions of area to redisplay (may be <= 0). */

	TCL_UNUSED(int),
    int imgWidth, int imgHeight)/* New dimensions of image. */


{
    TkTextSegment *eiPtr = (TkTextSegment *)clientData;
    TkTextEmbImage *img = &eiPtr->body.ei;

    if (img->hPtr) {
	TkSharedText *sharedTextPtr = img->sharedTextPtr;
	TkTextIndex index;
	int mask;

	assert(img->image);
	GetIndex(sharedTextPtr, eiPtr, &index);


	mask = (img->imgHeight == imgHeight) ? 0 : TK_TEXT_LINE_GEOMETRY;
	TextChanged(sharedTextPtr, &index, mask);




	if (sharedTextPtr->triggerWatchCmd) {
	    const char *w = NULL;
	    const char *h = NULL;
	    char buf[2][100];

	    if (img->imgHeight != imgHeight || img->imgWidth != imgWidth) {
		snprintf(buf[0], sizeof(buf[0]), "%d", img->imgWidth);
		snprintf(buf[1], sizeof(buf[1]), "%d", img->imgHeight);
		w = buf[0];
		h = buf[1];
	    }

	    TkTextPerformWatchCmd(sharedTextPtr, NULL, "image", GetIndexForWatch, eiPtr, NULL, NULL,
		    img->name, w, h, 0);
	}
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 * vi:set ts=8 sw=4:
 */

Changes to generic/tkTextIndex.c.

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15

16


17
18
19
20






21

22



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38


39










40















41

42
43
44








45





46

47
48


49
50







51
















52




53







54

55
56
57








58


59
60



61
62


63





64




65


66





67




68




























69
70


71











72







73
74
75





76










77


78



79













80







81































82

83


84
85



86
87



88
89
90
91
92
93
94














95



96







97

98





99


100



101















102
103
104






105
106







107



108











109










110





111








112






















113
114
115
116
117
118
119

120
121















122









123






124



125











126
127










128







129














130
131
132
133
134
135



136





137


138


139
140
141










142






143
144
145







146











147
148
149
150
151
152


153
154




155




156
157

158

159




160






161




















162
163
164
165
166
167

168
169
170




















171




172







173




174
175
176

177
178




179



















180











181
182


183





184


















185







186









187
188















189







190


































































191




192


193







194
195



















































196















197

198

199



200


201













202


203























204















































205



206


207























208









209




210

211



212



















































213








214
215



































216
217
218















219











220



221



222











223


224














225




































226







227


228

































































































229
230











































231




232



233





234


235
236


237




238


239













































240

241





242
































































243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387


388
389
390

391
392
393



394


395
396

397
398
399
400


401

402
403







404
405










406


407












408
409
410
411
412
413
414
415
416











417
418


419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437
438
439
440


441
442
443
444
445
446
447
448
449
450
451
452
453
/*
 * tkTextIndex.c --
 *
 *	This module provides functions that manipulate indices for text
 *	widgets.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.

 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"

#include "default.h"



/*
 * Index to use to select last character in line (very large integer):
 */








#define LAST_CHAR 1000000




/*
 * Modifiers for index parsing: 'display', 'any' or nothing.
 */

#define TKINDEX_NONE	0
#define TKINDEX_DISPLAY	1
#define TKINDEX_ANY	2

/*
 * Forward declarations for functions defined later in this file:
 */

static const char *	ForwBack(TkText *textPtr, const char *string,
			    TkTextIndex *indexPtr);
static const char *	StartEnd(TkText *textPtr, const char *string,


			    TkTextIndex *indexPtr);










static int		GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr,















			    TkText *textPtr, const char *string,

			    TkTextIndex *indexPtr, int *canCachePtr);
static int              IndexCountBytesOrdered(const TkText *textPtr,
                            const TkTextIndex *indexPtr1,








                            const TkTextIndex *indexPtr2);







/*
 * The "textindex" Tcl_Obj definition:


 */








static void		DupTextIndexInternalRep(Tcl_Obj *srcPtr,
















			    Tcl_Obj *copyPtr);




static void		FreeTextIndexInternalRep(Tcl_Obj *listPtr);







static void		UpdateStringOfTextIndex(Tcl_Obj *objPtr);


/*
 * Accessor macros for the "textindex" type.








 */



#define GET_TEXTINDEX(objPtr) \



	((TkTextIndex *) (objPtr)->internalRep.twoPtrValue.ptr1)
#define GET_INDEXEPOCH(objPtr) \


	(PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2))





#define SET_TEXTINDEX(objPtr, indexPtr) \




	((objPtr)->internalRep.twoPtrValue.ptr1 = (void *)(indexPtr))


#define SET_INDEXEPOCH(objPtr, epoch) \





	((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (size_t) (epoch))

































/*
 * Define the 'textindex' object type, which Tk uses to represent indices in


 * text widgets internally.











 */








const Tcl_ObjType tkTextIndexType = {
    "textindex",		/* name */





    FreeTextIndexInternalRep,	/* freeIntRepProc */










    DupTextIndexInternalRep,	/* dupIntRepProc */


    NULL,			/* updateStringProc */



    NULL			/* setFromAnyProc */













};







































static void

FreeTextIndexInternalRep(


    Tcl_Obj *indexObjPtr)	/* TextIndex object with internal rep to
				 * free. */



{
    TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr);




    if (indexPtr->textPtr != NULL) {
	if (indexPtr->textPtr->refCount-- <= 1) {
	    /*
	     * The text widget has been deleted and we need to free it now.
	     */















	    ckfree(indexPtr->textPtr);



	}







    }

    ckfree(indexPtr);





    indexObjPtr->typePtr = NULL;


}



















static void
DupTextIndexInternalRep(
    Tcl_Obj *srcPtr,		/* TextIndex obj with internal rep to copy. */






    Tcl_Obj *copyPtr)		/* TextIndex obj with internal rep to set. */
{







    TkSizeT epoch;



    TkTextIndex *dupIndexPtr, *indexPtr;






















    dupIndexPtr = (TkTextIndex *)ckalloc(sizeof(TkTextIndex));





    indexPtr = GET_TEXTINDEX(srcPtr);








    epoch = GET_INDEXEPOCH(srcPtr);























    dupIndexPtr->tree = indexPtr->tree;
    dupIndexPtr->linePtr = indexPtr->linePtr;
    dupIndexPtr->byteIndex = indexPtr->byteIndex;
    dupIndexPtr->textPtr = indexPtr->textPtr;
    if (dupIndexPtr->textPtr != NULL) {
	dupIndexPtr->textPtr->refCount++;

    }
    SET_TEXTINDEX(copyPtr, dupIndexPtr);















    SET_INDEXEPOCH(copyPtr, epoch);









    copyPtr->typePtr = &tkTextIndexType;






}















/*
 * This will not be called except by TkTextNewIndexObj below. This is because










 * if a TkTextIndex is no longer valid, it is not possible to regenerate the







 * string representation.














 */

static void
UpdateStringOfTextIndex(
    Tcl_Obj *objPtr)
{



    char buffer[TK_POS_CHARS];





    size_t len;


    const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr);



    len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);











    objPtr->bytes = (char *)ckalloc(len + 1);






    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
}



















/*
 *---------------------------------------------------------------------------
 *
 * MakeObjIndex --
 *
 *	This function generates a Tcl_Obj description of an index, suitable


 *	for reading in again later. If the 'textPtr' is NULL then we still
 *	generate an index object, but it's internal description is deemed




 *	non-cacheable, and therefore effectively useless (apart from as a




 *	temporary memory storage). This is used for indices whose meaning is
 *	very temporary (like @0,0 or the name of a mark or tag). The mapping

 *	from such strings/objects to actual TkTextIndex pointers is not stable

 *	to minor text widget changes which we do not track (we track




 *	insertions and deletions).






 *




















 * Results:
 *	A pointer to an allocated TkTextIndex which will be freed
 *	automatically when the Tcl_Obj is used for other purposes.
 *
 * Side effects:
 *	A small amount of memory is allocated.

 *
 *---------------------------------------------------------------------------
 */

























static TkTextIndex *







MakeObjIndex(




    TkText *textPtr,		/* Information about text widget. */
    Tcl_Obj *objPtr,		/* Object containing description of
				 * position. */

    const TkTextIndex *origPtr)	/* Pointer to index. */
{




    TkTextIndex *indexPtr = (TkTextIndex *)ckalloc(sizeof(TkTextIndex));































    indexPtr->tree = origPtr->tree;
    indexPtr->linePtr = origPtr->linePtr;


    indexPtr->byteIndex = origPtr->byteIndex;





    SET_TEXTINDEX(objPtr, indexPtr);


















    objPtr->typePtr = &tkTextIndexType;







    indexPtr->textPtr = textPtr;










    if (textPtr != NULL) {















	textPtr->refCount++;







	SET_INDEXEPOCH(objPtr, textPtr->sharedTextPtr->stateEpoch);


































































    } else {




	SET_INDEXEPOCH(objPtr, 0);


    }







    return indexPtr;
}



































































const TkTextIndex *

TkTextGetIndexFromObj(

    Tcl_Interp *interp,		/* Use this for error reporting. */



    TkText *textPtr,		/* Information about text widget. */


    Tcl_Obj *objPtr)		/* Object containing description of













				 * position. */


{























    TkTextIndex index;















































    TkTextIndex *indexPtr = NULL;



    int cache;


























    if (objPtr->typePtr == &tkTextIndexType) {









	TkSizeT epoch;






	indexPtr = GET_TEXTINDEX(objPtr);



	epoch = GET_INDEXEPOCH(objPtr);




























































	if (epoch == textPtr->sharedTextPtr->stateEpoch) {
	    if (indexPtr->textPtr == textPtr) {



































		return indexPtr;
	    }
	}















    }















    /*



     * The object is either not an index type or referred to a different text











     * widget, or referred to the correct widget, but it is out of date (text


     * has been added/deleted since).














     */












































    if (GetIndex(interp, NULL, textPtr, Tcl_GetString(objPtr), &index,


	    &cache) != TCL_OK) {

































































































	return NULL;
    }
















































    if (objPtr->typePtr != NULL) {



	if (objPtr->bytes == NULL) {





	    objPtr->typePtr->updateStringProc(objPtr);


	}
	if (objPtr->typePtr->freeIntRepProc != NULL) {


	    objPtr->typePtr->freeIntRepProc(objPtr);




	}


    }















































    return MakeObjIndex((cache ? textPtr : NULL), objPtr, &index);





}

































































/*
 *---------------------------------------------------------------------------
 *
 * TkTextNewIndexObj --
 *
 *	This function generates a Tcl_Obj description of an index, suitable
 *	for reading in again later. The index generated is effectively stable
 *	to all except insertion/deletion operations on the widget.
 *
 * Results:
 *	A new Tcl_Obj with refCount zero.
 *
 * Side effects:
 *	A small amount of memory is allocated.
 *
 *---------------------------------------------------------------------------
 */

Tcl_Obj *
TkTextNewIndexObj(
    TkText *textPtr,		/* Text widget for this index */
    const TkTextIndex *indexPtr)/* Pointer to index. */
{
    Tcl_Obj *retVal;

    retVal = Tcl_NewObj();
    retVal->bytes = NULL;

    /*
     * Assumption that the above call returns an object with:
     * retVal->typePtr == NULL
     */

    MakeObjIndex(textPtr, retVal, indexPtr);

    /*
     * Unfortunately, it isn't possible for us to regenerate the string
     * representation so we have to create it here, while we can be sure the
     * contents of the index are still valid.
     */

    UpdateStringOfTextIndex(retVal);
    return retVal;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextMakePixelIndex --
 *
 *	Given a pixel index and a byte index, look things up in the B-tree and
 *	fill in a TkTextIndex structure.
 *
 *	The valid input range for pixelIndex is from 0 to the number of pixels
 *	in the widget-1. Anything outside that range will be rounded to the
 *	closest acceptable value.
 *
 * Results:
 *
 *	The structure at *indexPtr is filled in with information about the
 *	character at pixelIndex (or the closest existing character, if the
 *	specified one doesn't exist), and the number of excess pixels is
 *	returned as a result. This means if the given pixel index is exactly
 *	correct for the top-edge of the indexPtr, then zero will be returned,
 *	and otherwise we will return the calculation 'desired pixelIndex' -
 *	'actual pixel index of indexPtr'.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextMakePixelIndex(
    TkText *textPtr,		/* The Text Widget */
    int pixelIndex,		/* Pixel-index of desired line (0 means first
				 * pixel of first line of text). */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    int pixelOffset = 0;

    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->textPtr = textPtr;

    if (pixelIndex < 0) {
	pixelIndex = 0;
    }
    indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree,
	    textPtr, pixelIndex, &pixelOffset);

    /*
     * 'pixelIndex' was too large, so we try again, just to find the last
     * pixel in the window.
     */

    if (indexPtr->linePtr == NULL) {
	int lastMinusOne = TkBTreeNumPixels(textPtr->sharedTextPtr->tree,
		textPtr)-1;

	indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree,
		textPtr, lastMinusOne, &pixelOffset);
	indexPtr->byteIndex = 0;
	return pixelOffset;
    }
    indexPtr->byteIndex = 0;

    if (pixelOffset <= 0) {
	return 0;
    }
    return TkTextMeasureDown(textPtr, indexPtr, pixelOffset);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextMakeByteIndex --
 *
 *	Given a line index and a byte index, look things up in the B-tree and
 *	fill in a TkTextIndex structure.
 *
 * Results:
 *	The structure at *indexPtr is filled in with information about the
 *	character at lineIndex and byteIndex (or the closest existing
 *	character, if the specified one doesn't exist), and indexPtr is
 *	returned as result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextIndex *
TkTextMakeByteIndex(
    TkTextBTree tree,	/* Tree that lineIndex and byteIndex refer
				 * to. */
    const TkText *textPtr,
    int lineIndex,		/* Index of desired line (0 means first line
				 * of text). */
    int byteIndex,		/* Byte index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    TkTextSegment *segPtr;


    int index;
    const char *p, *start;
    int ch;


    indexPtr->tree = tree;
    if (lineIndex < 0) {



	lineIndex = 0;


	byteIndex = 0;
    }

    if (byteIndex < 0) {
	byteIndex = 0;
    }
    indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, lineIndex);


    if (indexPtr->linePtr == NULL) {

	indexPtr->linePtr = TkBTreeFindLine(tree, textPtr,
		TkBTreeNumLines(tree, textPtr));







	byteIndex = 0;
    }










    if (byteIndex == 0) {


	indexPtr->byteIndex = byteIndex;












	return indexPtr;
    }

    /*
     * Verify that the index is within the range of the line and points to a
     * valid character boundary.
     */

    index = 0;











    for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
	if (segPtr == NULL) {


	    /*
	     * Use the index of the last character in the line. Since the last
	     * character on the line is guaranteed to be a '\n', we can back
	     * up a constant sizeof(char) bytes.
	     */

	    indexPtr->byteIndex = index - sizeof(char);
	    break;

	}
	if (index + (int)segPtr->size > byteIndex) {
	    indexPtr->byteIndex = byteIndex;
	    if ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) {
		/*
		 * Prevent UTF-8 character from being split up by ensuring
		 * that byteIndex falls on a character boundary. If the index
		 * falls in the middle of a UTF-8 character, it will be
		 * adjusted to the end of that UTF-8 character.
		 */

		start = segPtr->body.chars + (byteIndex - index);
		p = TkUtfPrev(start, segPtr->body.chars);
		p += TkUtfToUniChar(p, &ch);


		indexPtr->byteIndex += p - start;
	    }
	    break;
	}
	index += segPtr->size;
    }
    return indexPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextMakeCharIndex --



|
<

|
|
>







>

>
>

<
<
<
>
>
>
>
>
>

>
|
>
>
>





<
|
<





|
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
<
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
|
<
>
>


>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
|
>
|
|
|
>
>
>
>
>
>
>
>
|
>
>
|
|
>
>
>
|
|
>
>
|
>
>
>
>
>
|
>
>
>
>
|
>
>
|
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
>
>
|
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
|
|
>
>
>
|
<
>
>
>
|
<
<
|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
>
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
|

>
>
>
|
>
>
>
>
>
|
>
>
|
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>

|

|

<
>
>
|
<
>
>
>
>
|
>
>
>
>
|
<
>
|
>
|
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<


<
>

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
|
<
|
>
|

>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
|
>
>

>
>
>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
|
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>

>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
|
>
>
>
|
>
>
>
>
>
|
>
>
|
|
>
>
|
>
>
>
>
|
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|









<


<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
|

<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
|
<



|

















|
|
<
|
|
<
|



>
>
|
|
<
>

<

>
>
>
|
>
>
|

>



|
>
>
|
>
|
|
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>

>
>
|
>
>
>
>
>
>
>
>
>
>
>
>



<
<
<
<
|

>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
|
<
<
|

|
<
>
|
<
<
<
|
|
|
<
|
|

<
<
<
>
>
|
|
<
|
<
|







1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334


335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642

643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692

693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678

1679
1680

1681
















































1682





1683



1684
1685





1686

















1687
1688

1689

1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712

1713
1714

1715
1716
1717
1718
1719
1720
1721
1722

1723
1724

1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782




1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801


1802
1803
1804

1805
1806



1807
1808
1809

1810
1811
1812



1813
1814
1815
1816

1817

1818
1819
1820
1821
1822
1823
1824
1825
/*
 * tkTextIndex.c --
 *
 *	This module provides functions that manipulate indices for text widgets.

 *
 * Copyright © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2015-2017 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 "tkText.h"
#include "tkTextTagSet.h"
#include "default.h"
#include <stdlib.h>
#include <assert.h>




#ifndef MAX
# define MAX(a,b) (((int) a) < ((int) b) ? b : a)
#endif
#ifndef MIN
# define MIN(a,b) (((int) a) < ((int) b) ? a : b)
#endif

#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

/*
 * Modifiers for index parsing: 'display', 'any' or nothing.
 */


enum { TKINDEX_NONE, TKINDEX_DISPLAY, TKINDEX_CHAR };


/*
 * Forward declarations for functions defined later in this file:
 */

static const char *	ForwBack(TkText *textPtr, const char *string, TkTextIndex *indexPtr,
			    int charCount);
static const char *	StartEnd(TkText *textPtr, const char *string, TkTextIndex *indexPtr);
static TkTextSegment *	IndexToSeg(const TkTextIndex *indexPtr, Tcl_Size *offsetPtr);
static int		SegToIndex(const TkTextLine *linePtr, const TkTextSegment *segPtr);

/*
 * A note about sizeof(char). Due to the specification of sizeof in C99,
 * sizeof(char) is always 1, see section 6.5.3.4:
 *
 *	When applied to an operand that has type char, unsigned char, or
 *	signed char, (or a qualified version thereof) the result is 1.
 *
 * This means that the expression "== sizeof(char)" is not required, the
 * expression "== 1" is good as well.
 */

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexIsEmpty --
 *
 *	Return whether the given index is empty (still unset, or invalid).
 *
 * Results:
 *	True if empty, false otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexIsEmpty(

    const TkTextIndex *indexPtr)
{
    assert(indexPtr);
    return indexPtr->priv.byteIndex == -1 && !indexPtr->priv.segPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetLine --
 *
 *	Set the line pointer of this index.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.

 *
 *----------------------------------------------------------------------
 */

#ifndef NDEBUG
static int
CheckLine(
    const TkTextIndex *indexPtr,
    const TkTextLine *linePtr)
{
    assert(linePtr);

    if (indexPtr->stateEpoch == TkBTreeEpoch(indexPtr->tree)) {
	if (indexPtr->priv.segPtr
		&& indexPtr->priv.segPtr->sectionPtr->linePtr != indexPtr->priv.linePtr) {
	    return 0;
	}
	if (indexPtr->priv.lineNo != -1
		&& indexPtr->priv.lineNo !=
		(int) TkBTreeLinesTo(indexPtr->tree, NULL, indexPtr->priv.linePtr, NULL)) {
	    return 0;
	}
	if (indexPtr->priv.lineNoRel != -1
		&& indexPtr->priv.lineNoRel !=
		(int) TkBTreeLinesTo(indexPtr->tree, indexPtr->textPtr, indexPtr->priv.linePtr, NULL)) {
	    return 0;
	}
    }

    if (!indexPtr->discardConsistencyCheck && indexPtr->textPtr) {
	const TkTextLine *startLine = TkBTreeGetStartLine(indexPtr->textPtr);
	const TkTextLine *endLine = TkBTreeGetLastLine(indexPtr->textPtr);
	int lineNo = TkBTreeLinesTo(indexPtr->tree, NULL, linePtr, NULL);

	if (lineNo < (int) TkBTreeLinesTo(indexPtr->tree, NULL, startLine, NULL)) {
	    return 0;
	}
	if (lineNo > (int) TkBTreeLinesTo(indexPtr->tree, NULL, endLine, NULL)) {
	    return 0;
	}
    }

    return 1;
}
#endif /* NDEBUG */

static Tcl_Size
FindStartByteIndex(
    const TkTextIndex *indexPtr)
{
    const TkText *textPtr = indexPtr->textPtr;
    const TkTextSegment *segPtr;
    const TkTextSection *sectionPtr;
    Tcl_Size byteIndex;

    if (!textPtr) {
	return 0;
    }

    if (textPtr->startMarker == TkBTreeGetShared(indexPtr->tree)->startMarker) {
	return 0;
    }

    segPtr = textPtr->startMarker;
    sectionPtr = segPtr->sectionPtr;
    byteIndex = 0;

    if (sectionPtr->linePtr == indexPtr->priv.linePtr) {
	while (segPtr && sectionPtr == segPtr->sectionPtr) {
	    byteIndex += segPtr->size;
	    segPtr = segPtr->prevPtr;
	}
	while (sectionPtr->prevPtr) {
	    sectionPtr = sectionPtr->prevPtr;
	    byteIndex += sectionPtr->size;
	}
    }

    return byteIndex;
}

static int
DontNeedSpecialStartLineTreatment(
    const TkTextIndex *indexPtr)
{
    const TkText *textPtr = indexPtr->textPtr;

    return !textPtr
	    || textPtr->startMarker == TkBTreeGetShared(indexPtr->tree)->startMarker
	    || indexPtr->priv.linePtr != textPtr->startMarker->sectionPtr->linePtr;
}

void
TkTextIndexSetLine(
    TkTextIndex *indexPtr,
    TkTextLine *linePtr)
{
    assert(linePtr);
    assert(indexPtr->tree);
    assert(CheckLine(indexPtr, linePtr));

    indexPtr->stateEpoch = TkBTreeEpoch(indexPtr->tree);
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.byteIndex = -1;

    if ((indexPtr->priv.linePtr = linePtr)) {
	assert(linePtr->parentPtr); /* expired? */

	if (DontNeedSpecialStartLineTreatment(indexPtr)) {
	    indexPtr->priv.byteIndex = 0;
	} else {
	    indexPtr->priv.segPtr = indexPtr->textPtr->startMarker;
	    indexPtr->priv.isCharSegment = 0;
	    indexPtr->priv.byteIndex = FindStartByteIndex(indexPtr);
	}
    }
}

/*

 *----------------------------------------------------------------------
 *
 * TkTextIndexSetPosition --
 *
 *	Set the byte index and the segment, the user is responsible
 *	for proper values.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#ifndef NDEBUG
static int
CheckByteIndex(
    const TkTextIndex *indexPtr,
    const TkTextLine *linePtr,
    Tcl_Size byteIndex)
{
    const TkText *textPtr = indexPtr->textPtr;

    if (byteIndex == -1 && (byteIndex = indexPtr->priv.byteIndex) == -1) {
	assert(indexPtr->priv.segPtr);
	assert(!indexPtr->priv.isCharSegment || TkBTreeEpoch(indexPtr->tree) == indexPtr->stateEpoch);
	byteIndex = SegToIndex(indexPtr->priv.linePtr, indexPtr->priv.segPtr);
    }

    if (!indexPtr->discardConsistencyCheck && textPtr) {
	if (linePtr == textPtr->startMarker->sectionPtr->linePtr) {
	    if (byteIndex < FindStartByteIndex(indexPtr)) {
		return 0;
	    }
	}
	if (linePtr == textPtr->endMarker->sectionPtr->linePtr) {
	    return byteIndex <= SegToIndex(linePtr, textPtr->endMarker);
	}
	if (linePtr == textPtr->endMarker->sectionPtr->linePtr->nextPtr) {
	    return byteIndex == 0;
	}
    }

    return byteIndex < linePtr->size;
}
#endif /* NDEBUG */

void
TkTextIndexSetPosition(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    int byteIndex,		/* New byte index. */
    TkTextSegment *segPtr)	/* The segment which belongs to the byte index. */
{
    assert(indexPtr->tree);
    assert(byteIndex >= 0);
    assert(segPtr);
    assert(segPtr->typePtr);    /* expired? */
    assert(segPtr->sectionPtr); /* linked? */
    assert(CheckLine(indexPtr, segPtr->sectionPtr->linePtr));
    assert(CheckByteIndex(indexPtr, segPtr->sectionPtr->linePtr, byteIndex));

    indexPtr->stateEpoch = TkBTreeEpoch(indexPtr->tree);
    indexPtr->priv.linePtr = segPtr->sectionPtr->linePtr;
    indexPtr->priv.byteIndex = byteIndex;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.segPtr = segPtr;
    indexPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType;

#ifndef NDEBUG
    {
	int pos = SegToIndex(indexPtr->priv.linePtr, segPtr);

	if (segPtr->typePtr == &tkTextCharType) {
	    assert(byteIndex - pos < segPtr->size);
	} else {
	    assert(pos == byteIndex);
	}
    }
#endif /* NDEBUG */
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetByteIndex --
 *
 *	Set the byte index. We allow to set to the start of the next
 *	line (this means that argument byteIndex is equal to line size),
 *	required that the next line exists.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
DontNeedSpecialEndLineTreatment(
    const TkTextIndex *indexPtr)
{
    const TkText *textPtr = indexPtr->textPtr;

    return !textPtr
	    || textPtr->endMarker == TkBTreeGetShared(indexPtr->tree)->endMarker
	    || indexPtr->priv.linePtr != textPtr->endMarker->sectionPtr->linePtr;
}


static Tcl_Size
FindEndByteIndex(
    const TkTextIndex *indexPtr)
{


    /*
     * We do not handle the special case with last line, because CheckLine is testing this.
     */

    if (indexPtr->textPtr && indexPtr->priv.linePtr == TkBTreeGetLastLine(indexPtr->textPtr)) {
	return 0;
    }
    if (DontNeedSpecialEndLineTreatment(indexPtr)) {
	return indexPtr->priv.linePtr->size - 1;
    }
    return SegToIndex(indexPtr->priv.linePtr, indexPtr->textPtr->endMarker);
}

void
TkTextIndexSetByteIndex(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    Tcl_Size byteIndex)		/* New byte index. */
{
    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(byteIndex >= 0);

    if (byteIndex == FindEndByteIndex(indexPtr) + 1) {
	assert(indexPtr->priv.linePtr->nextPtr);
	indexPtr->priv.linePtr = indexPtr->priv.linePtr->nextPtr;
	indexPtr->priv.byteIndex = 0;
	indexPtr->priv.segPtr = NULL;
	if (indexPtr->priv.lineNo >= 0) {
	    indexPtr->priv.lineNo += 1;
	}
	if (indexPtr->priv.lineNoRel >= 0) {
	    indexPtr->priv.lineNoRel += 1;
	}
    } else {
	indexPtr->priv.byteIndex = byteIndex;
	indexPtr->priv.segPtr = NULL;
    }

    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, byteIndex));
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetByteIndex2 --
 *
 *	Set the new line pointer and the byte index. We allow to set to
 *	the start of the next line (this means that argument byteIndex
 *	is equal to line size), required that the next line exists.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetByteIndex2(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkTextLine *linePtr,	/* Pointer to line. */
    Tcl_Size byteIndex)		/* New byte index. */
{
    assert(indexPtr->tree);
    assert(linePtr);
    assert(linePtr->parentPtr); /* expired? */
    assert(byteIndex >= 0);

    if (indexPtr->priv.linePtr != linePtr) {
	indexPtr->priv.linePtr = linePtr;
	indexPtr->priv.lineNo = -1;
	indexPtr->priv.lineNoRel = -1;
    }
    TkTextIndexSetByteIndex(indexPtr, byteIndex);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetSegment --
 *
 *	Set the segment pointer.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The byte index will be cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetSegment(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkTextSegment *segPtr)	/* Pointer to segment. */
{
    assert(indexPtr->tree);
    assert(segPtr);
    assert(segPtr->typePtr);    /* expired? */
    assert(segPtr->sectionPtr); /* linked? */
    assert(CheckLine(indexPtr, segPtr->sectionPtr->linePtr));

    indexPtr->stateEpoch = TkBTreeEpoch(indexPtr->tree);
    indexPtr->priv.linePtr = segPtr->sectionPtr->linePtr;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.segPtr = segPtr;

    if (segPtr->typePtr == &tkTextCharType) {
	/* this segment is volatile, thus we need the byte index. */
	indexPtr->priv.byteIndex = SegToIndex(indexPtr->priv.linePtr, segPtr);
	indexPtr->priv.isCharSegment = 1;
    } else {
	indexPtr->priv.byteIndex = -1;
	indexPtr->priv.isCharSegment = 0;
    }

    assert(CheckByteIndex(indexPtr, segPtr->sectionPtr->linePtr, -1));
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetToStartOfLine --
 *
 *	Set this index to the start of the line.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetToStartOfLine(
    TkTextIndex *indexPtr)	/* Pointer to index. */
{
    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));

    indexPtr->priv.byteIndex = FindStartByteIndex(indexPtr);
    TkTextIndexSetEpoch(indexPtr, TkBTreeEpoch(indexPtr->tree));
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetToStartOfLine2 --
 *
 *	Set the new line pointer, and set this index to the start of the line.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetToStartOfLine2(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkTextLine *linePtr)	/* Pointer to line. */
{
    assert(indexPtr->tree);
    assert(linePtr);
    assert(linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, linePtr));

    indexPtr->stateEpoch = TkBTreeEpoch(indexPtr->tree);
    indexPtr->priv.linePtr = linePtr;
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.byteIndex = FindStartByteIndex(indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetToEndOfLine2 --
 *
 *	Set the new line pointer, and set this index to the end of the line.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetToEndOfLine2(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkTextLine *linePtr)	/* Pointer to line. */
{
    assert(indexPtr->tree);
    assert(linePtr);
    assert(linePtr->parentPtr); /* expired? */
    assert(linePtr->nextPtr);
    assert(CheckLine(indexPtr, linePtr->nextPtr));

    indexPtr->stateEpoch = TkBTreeEpoch(indexPtr->tree);
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.linePtr = linePtr->nextPtr;
    indexPtr->priv.byteIndex = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetToLastChar --
 *
 *	Set this index to one byte before the end of the line.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetToLastChar(
    TkTextIndex *indexPtr)	/* Pointer to index. */
{
    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    indexPtr->stateEpoch = TkBTreeEpoch(indexPtr->tree);
    indexPtr->priv.byteIndex = FindEndByteIndex(indexPtr);
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;

    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetupToStartOfText --
 *
 *	Setup this index to the start of the text.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexSetupToStartOfText(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkText *textPtr,		/* Text widget for this index, can be NULL. */
    TkTextBTree tree)		/* B-tree for this index. */
{
    assert(indexPtr);
    assert(tree);

    indexPtr->textPtr = textPtr;
    indexPtr->tree = tree;
    indexPtr->stateEpoch = TkBTreeEpoch(tree);
    indexPtr->priv.lineNo = textPtr ? -1 : 0;
    indexPtr->priv.lineNoRel = 0;
    indexPtr->priv.isCharSegment = 0;
    DEBUG(indexPtr->discardConsistencyCheck = 0);

    if (textPtr) {
	indexPtr->priv.segPtr = textPtr->startMarker;
	indexPtr->priv.linePtr = indexPtr->priv.segPtr->sectionPtr->linePtr;
	indexPtr->priv.byteIndex = FindStartByteIndex(indexPtr);
    } else {
	indexPtr->priv.segPtr = TkBTreeGetShared(tree)->startMarker;
	indexPtr->priv.linePtr = indexPtr->priv.segPtr->sectionPtr->linePtr;
	indexPtr->priv.byteIndex = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetupToEndOfText --
 *

 *	Setup this index to the end of the text. If a peer is given,
 *	then this is the start of last line in this peer, otherwise
 *	it's the start of the very last line.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


void
TkTextIndexSetupToEndOfText(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkText *textPtr,		/* Text widget for this index, can be NULL. */
    TkTextBTree tree)		/* B-tree for this index. */
{
    assert(indexPtr);
    assert(tree);

    indexPtr->textPtr = textPtr;
    indexPtr->tree = tree;
    indexPtr->stateEpoch = TkBTreeEpoch(tree);
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    DEBUG(indexPtr->discardConsistencyCheck = 0);

    if (!textPtr) {
	indexPtr->priv.segPtr = TkBTreeGetShared(tree)->endMarker;
	indexPtr->priv.isCharSegment = 0;
	indexPtr->priv.linePtr = indexPtr->priv.segPtr->sectionPtr->linePtr;
	indexPtr->priv.byteIndex = 0;
    } else {
	indexPtr->priv.linePtr = TkBTreeGetLastLine(textPtr);
	indexPtr->priv.segPtr = indexPtr->priv.linePtr->segPtr;
	indexPtr->priv.isCharSegment = indexPtr->priv.segPtr->typePtr == &tkTextCharType;
	indexPtr->priv.byteIndex = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetByteIndex --
 *
 *	Get the byte index.
 *
 * Results:
 *	The byte index.

 *
 * Side effects:

 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Size
TkTextIndexGetByteIndex(
    const TkTextIndex *indexPtr)	/* Pointer to index. */
{
    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    if (indexPtr->priv.byteIndex == -1) {
	assert(indexPtr->priv.segPtr);
	assert(!indexPtr->priv.isCharSegment || TkBTreeEpoch(indexPtr->tree) == indexPtr->stateEpoch);
	assert(indexPtr->priv.segPtr->typePtr);    /* expired? */
	assert(indexPtr->priv.segPtr->sectionPtr); /* linked? */
	assert(indexPtr->priv.segPtr->sectionPtr->linePtr == indexPtr->priv.linePtr);
	/* is mutable due to concept */
	((TkTextIndex *)indexPtr)->priv.byteIndex =
		SegToIndex(indexPtr->priv.linePtr, indexPtr->priv.segPtr);
    }
    return indexPtr->priv.byteIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexToByteIndex --
 *
 *	Force the conversion from segment pointer to byte index. This
 *	will unset the segment pointer.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The segment pointer will be unset.
 *
 *----------------------------------------------------------------------
 */


void
TkTextIndexToByteIndex(
    TkTextIndex *indexPtr)	/* Pointer to index. */
{
    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));

    if (indexPtr->priv.byteIndex == -1) {
	(void) TkTextIndexGetByteIndex(indexPtr);
    }
    indexPtr->priv.segPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexClear --
 *
 *	Clear all attributes, and set up the corresponding text pointer.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The given index will be in an invalid state, the TkIndexGet*
 *	functions cannot be used.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexClear(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkText *textPtr)		/* Overall information for text widget. */
{
    assert(textPtr);

    indexPtr->textPtr = textPtr;
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->stateEpoch = 0;
    indexPtr->priv.linePtr = NULL;
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.byteIndex = -1;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.isCharSegment = 0;
    DEBUG(indexPtr->discardConsistencyCheck = 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexClear2 --
 *
 *	Clear all attributes, and set up the corresponding tree.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The given index will be in an invalid state, the TkIndexGet*
 *	functions cannot be used.
 *
 *----------------------------------------------------------------------
 */

void
TkTextIndexClear2(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkText *textPtr,		/* Overall information for text widget, can be NULL */
    TkTextBTree tree)		/* B-tree for this index. */
{
    assert(textPtr || tree);
    assert(!textPtr || !tree || textPtr->sharedTextPtr->tree == tree);

    indexPtr->textPtr = textPtr;
    indexPtr->tree = tree ? tree : textPtr->sharedTextPtr->tree;
    indexPtr->stateEpoch = 0;
    indexPtr->priv.linePtr = NULL;
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.byteIndex = -1;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.isCharSegment = 0;
    DEBUG(indexPtr->discardConsistencyCheck = 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetLineNumber --
 *
 *	Get the line number.
 *
 * Results:
 *	The line number.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

unsigned
TkTextIndexGetLineNumber(
    const TkTextIndex *indexPtr,
    const TkText *textPtr)	/* we want the line number belonging to this peer, can be NULL */
{
    Tcl_Size epoch;
    int32_t *lineNo;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(!textPtr || indexPtr->textPtr == textPtr);

    lineNo = (int32_t *) (textPtr ? &indexPtr->priv.lineNoRel : &indexPtr->priv.lineNo);
    epoch = TkBTreeEpoch(indexPtr->tree);

    if (*lineNo == -1 || indexPtr->stateEpoch != epoch) {
	TkTextIndex *iPtr = (TkTextIndex *) indexPtr;

	if (iPtr->priv.byteIndex == -1) {
	    assert(iPtr->priv.segPtr);
	    assert(!iPtr->priv.isCharSegment || indexPtr->stateEpoch == epoch);
	    iPtr->priv.byteIndex = SegToIndex(iPtr->priv.linePtr, iPtr->priv.segPtr);
	    assert(CheckByteIndex(iPtr, iPtr->priv.linePtr, iPtr->priv.byteIndex));
	}
	TkTextIndexSetEpoch(iPtr, epoch);
	*lineNo = TkBTreeLinesTo(iPtr->tree, textPtr, iPtr->priv.linePtr, NULL);
    } else {
	assert(*lineNo == (int) TkBTreeLinesTo(indexPtr->tree, textPtr, indexPtr->priv.linePtr, NULL));
    }

    return *lineNo;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexRebuild --
 *
 *	Rebuild the index after possible modifications, it is required
 *	that TkTextIndexSave has been called before.
 *
 * Results:
 *	Returns whether the original line/byte position could be restored.
 *	This does not meean that we have the same content at this position,
 *	this only means that the we have the same position as before.
 *
 * Side effects:
 *	Adjust the line and the byte offset, if required.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexRebuild(
    TkTextIndex *indexPtr)
{
    TkTextLine *linePtr;
    int byteIndex;
    int lineNo;
    int rc;

    assert(indexPtr->tree);
    assert(indexPtr->priv.lineNo >= 0 || indexPtr->priv.lineNoRel >= 0);
    assert(indexPtr->priv.byteIndex >= 0);

    if (indexPtr->stateEpoch == TkBTreeEpoch(indexPtr->tree)) {
	return 1; /* still up-to-date */
    }

    if (indexPtr->priv.lineNo >= 0) {
	lineNo = MIN(TkrBTreeNumLines(indexPtr->tree, NULL), indexPtr->priv.lineNo);
	linePtr = TkBTreeFindLine(indexPtr->tree, NULL, lineNo);
	indexPtr->priv.lineNo = lineNo;
    } else {
	lineNo = MIN(TkrBTreeNumLines(indexPtr->tree, indexPtr->textPtr), indexPtr->priv.lineNoRel);
	linePtr = TkBTreeFindLine(indexPtr->tree, indexPtr->textPtr, lineNo);
	indexPtr->priv.lineNoRel = lineNo;
    }

    if (!(rc = (linePtr == indexPtr->priv.linePtr))) {
	indexPtr->priv.linePtr = linePtr;
    }
    byteIndex = MIN(indexPtr->priv.byteIndex, FindEndByteIndex(indexPtr));
    if (byteIndex != indexPtr->priv.byteIndex) {
	rc = 0;
    }
    indexPtr->priv.byteIndex = byteIndex;
    indexPtr->priv.segPtr = NULL;

    return rc;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexRestrictToStartRange --
 *
 *	If given index is beyond the range of the widget (at left side),
 *	then this index will be set to start range.
 *
 * Results:
 *	Returns -1 if the index is earlier than start of range, 0 if index
 *	is at start of range, and +1 if index is after start of range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexRestrictToStartRange(
    TkTextIndex *indexPtr)
{
    TkText *textPtr = indexPtr->textPtr;
    TkTextIndex start;
    int cmp;

    assert(indexPtr->tree);

    if (!textPtr || textPtr->startMarker == textPtr->sharedTextPtr->startMarker) {
	return TkTextIndexIsStartOfText(indexPtr) ? 0 : 1;
    }

    start = *indexPtr;
    TkTextIndexSetSegment(&start, textPtr->startMarker);

    if ((cmp = TkTextIndexCompare(indexPtr, &start)) < 0) {
	*indexPtr = start;
	cmp = -1;
    }

    return cmp;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexRestrictToEndRange --
 *
 *	If given index is beyond the range of the widget (at right side),
 *	then this index will be set to end range.
 *
 * Results:
 *	Returns +1 if the index has exceeded the range, 0 if index was at
 *	end of range, and -1 if index is earlier than end of range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexRestrictToEndRange(
    TkTextIndex *indexPtr)
{
    TkText *textPtr = indexPtr->textPtr;
    TkTextIndex last;
    int cmp;

    assert(indexPtr->tree);

    if (!textPtr || textPtr->endMarker == textPtr->sharedTextPtr->endMarker) {
	return TkTextIndexIsEndOfText(indexPtr) ? 0 : -1;
    }

    last = *indexPtr;
    TkTextIndexSetByteIndex2(&last, TkBTreeGetLastLine(textPtr), 0);

    if ((cmp = TkTextIndexCompare(indexPtr, &last)) > 0) {
	*indexPtr = last;
	cmp = 1;
    } else if (cmp < 0) {
	TkTextIndex end = *indexPtr;
	TkTextIndexSetSegment(&end, textPtr->endMarker);
	if (TkTextIndexCompare(indexPtr, &end) > 0) {
	    *indexPtr = last;
	    cmp = 0;
	} else {
	    cmp = -1;
	}
    }

    return cmp;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexOutsideStartEnd --
 *
 *	Check if given index is outside the range of the widget (at either
 *	side).
 *
 * Results:
 *	Returns 0 if the index is within range, or 1 if index is outside
 *	range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexOutsideStartEnd(
    TkTextIndex* indexPtr)
{
    TkText* textPtr = indexPtr->textPtr;
    TkTextIndex index;

    assert(textPtr);

    if (textPtr->startMarker != textPtr->sharedTextPtr->startMarker) {
	TkTextIndexClear(&index, textPtr);
	TkTextIndexSetSegment(&index, textPtr->startMarker);
	if (TkTextIndexCompare(indexPtr, &index) < 0) {
	    return 1;
	}
    }
    if (textPtr->endMarker != textPtr->sharedTextPtr->endMarker) {
	if (TkTextIndexGetLine(indexPtr) == textPtr->endMarker->sectionPtr->linePtr) {
	    TkTextIndexClear(&index, textPtr);
	    TkTextIndexSetSegment(&index, textPtr->endMarker);
	}
	else {
	    TkTextIndexSetupToEndOfText(&index, textPtr, indexPtr->tree);
	}
	if (TkTextIndexCompare(indexPtr, &index) > 0) {
	    return 1;
	}
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexEnsureBeforeLastChar --
 *
 *	If given index is on last line, then this index will be set to
 *	the position of the last character in second last line.
 *
 * Results:
 *	Returns 'true' if the index is now before last character position.
 *	This is not possible if the peer is empty, and in this case this
 *	function returns 'false'.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexEnsureBeforeLastChar(
    TkTextIndex *indexPtr)
{
    TkText *textPtr = indexPtr->textPtr;
    const TkTextLine *lastLinePtr;

    assert(indexPtr->tree);
    assert(indexPtr->textPtr);

    if (TkTextIsDeadPeer(indexPtr->textPtr)) {
        return 0;
    }

    lastLinePtr = TkBTreeGetLastLine(textPtr);

    if (lastLinePtr == indexPtr->priv.linePtr
	    && (!textPtr || lastLinePtr != textPtr->startMarker->sectionPtr->linePtr)) {
	TkTextIndexSetToLastChar2(indexPtr, lastLinePtr->prevPtr);
    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetContentSegment --
 *
 *	Get the pointer to the segment at this byte position which
 *	contains any content (chars, image, or window).
 *
 *	This is the equivalent to the older (and eliminated) function
 *	TkTextIndexToSeg.
 *
 * Results:
 *	Pointer to a segment with size > 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextIndexGetContentSegment(
    const TkTextIndex *indexPtr,/* Pointer to index. */
    Tcl_Size *offset)		/* Get offset in segment, can be NULL. */
{
    TkTextSegment *segPtr;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    if ((segPtr = indexPtr->priv.segPtr)
	    && (!indexPtr->priv.isCharSegment || TkBTreeEpoch(indexPtr->tree) == indexPtr->stateEpoch)) {
	while (segPtr->size == 0) {
	    segPtr = segPtr->nextPtr;
	}

	if (offset) {
	    if (indexPtr->priv.byteIndex == -1) {
		*offset = 0;
	    } else {
		int byteIndex = SegToIndex(indexPtr->priv.linePtr, segPtr);
		assert(byteIndex <= indexPtr->priv.byteIndex);
		assert(indexPtr->priv.byteIndex < byteIndex + segPtr->size);
		*offset = indexPtr->priv.byteIndex - byteIndex;
	    }
	    assert(*offset >= 0);
	    assert(*offset < segPtr->size);
	}
    } else {
	Tcl_Size myOffset;

	assert(indexPtr->priv.byteIndex >= 0);
	segPtr = IndexToSeg(indexPtr, &myOffset);
	if (myOffset == 0) {
	    TkTextIndex *iPtr = (TkTextIndex *) indexPtr; /* mutable due to concept */
	    iPtr->priv.segPtr = segPtr;
	    iPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType;
	}
	if (offset) {
	    *offset = myOffset;
	}
    }

    return segPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetFirstSegment --
 *
 *	Get the pointer to first segment at this byte position.
 *
 * Results:
 *	Pointer to a segment.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextIndexGetFirstSegment(
    const TkTextIndex *indexPtr,/* Pointer to index. */
    Tcl_Size *offset)		/* Get offset in segment, can be NULL. */
{
    TkTextSegment *segPtr;
    TkTextSegment *prevPtr;
    Tcl_Size myOffset;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    if ((segPtr = indexPtr->priv.segPtr)
	    && (!indexPtr->priv.isCharSegment || TkBTreeEpoch(indexPtr->tree) == indexPtr->stateEpoch)) {
	if (indexPtr->priv.byteIndex >= 0) {
	    myOffset = indexPtr->priv.byteIndex - SegToIndex(indexPtr->priv.linePtr, segPtr);
	    assert(myOffset >= 0);
	    assert(segPtr->size == 0 || myOffset < segPtr->size);
	} else {
	    myOffset = 0;
	}
    } else {
	assert(indexPtr->priv.byteIndex >= 0);
	segPtr = IndexToSeg(indexPtr, &myOffset);
    }

    assert(segPtr->typePtr);    /* expired? */
    assert(segPtr->sectionPtr); /* linked? */
    assert(segPtr->sectionPtr->linePtr == indexPtr->priv.linePtr);

    if (myOffset == 0) {
	TkTextIndex *iPtr = (TkTextIndex *) indexPtr; /* mutable due to concept */

	while ((prevPtr = segPtr->prevPtr) && prevPtr->size == 0) {
	    segPtr = prevPtr;
	}

	iPtr->priv.segPtr = segPtr;
	iPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType;
    }
    if (offset) {
	*offset = myOffset;
    }

    return segPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexIsStartOfLine --
 *
 *	Test whether this index refers to the start of a line.
 *
 * Results:
 *	Returns true if the start of a line is referred, zero otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexIsStartOfLine(
    const TkTextIndex *indexPtr)
{
    const TkTextSegment *segPtr;
    const TkTextSegment *startPtr;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));

    if (indexPtr->priv.byteIndex >= 0) {
	return FindStartByteIndex(indexPtr) == indexPtr->priv.byteIndex;
    }

    assert(indexPtr->priv.segPtr);
    assert(!indexPtr->priv.isCharSegment || TkBTreeEpoch(indexPtr->tree) == indexPtr->stateEpoch);
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));

    startPtr = indexPtr->textPtr ? indexPtr->textPtr->startMarker : NULL;
    segPtr = indexPtr->priv.segPtr;
    if (segPtr->size > 0) {
	segPtr = segPtr->prevPtr;
    }
    while (segPtr && segPtr->size == 0) {
	if (segPtr == startPtr) {
	    return 1;
	}
	segPtr = segPtr->prevPtr;
    }

    return !segPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexIsEndOfLine --
 *
 *	Test whether this index refers to the end of the line.
 *
 * Results:
 *	Returns true if the end of the line is referred, false otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexIsEndOfLine(
    const TkTextIndex *indexPtr)
{
    const TkTextSegment *segPtr;
    const TkTextSegment *endPtr;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));

    if (indexPtr->priv.byteIndex >= 0) {
	return indexPtr->priv.byteIndex == FindEndByteIndex(indexPtr);
    }

    assert(indexPtr->priv.segPtr);
    assert(!indexPtr->priv.isCharSegment || TkBTreeEpoch(indexPtr->tree) == indexPtr->stateEpoch);

    if (indexPtr->priv.linePtr == TkBTreeGetLastLine(indexPtr->textPtr)) {
	return 1;
    }

    segPtr = indexPtr->priv.segPtr;

    if (DontNeedSpecialEndLineTreatment(indexPtr)) {
	while (segPtr->size == 0) {
	    segPtr = segPtr->nextPtr;
	}
	return segPtr->size == 1 && segPtr == indexPtr->priv.linePtr->lastPtr;
    }

    assert(indexPtr->textPtr);
    assert(indexPtr->textPtr->endMarker != indexPtr->textPtr->sharedTextPtr->endMarker);

    endPtr = indexPtr->textPtr->endMarker;
    while (segPtr->size == 0) {
	if (segPtr == endPtr) {
	    return 1;
	}
	segPtr = segPtr->nextPtr;
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexIsStartOfText --
 *
 *	Test whether this index refers to the start of the text.
 *
 * Results:
 *	Returns true if the start of the text is referred, false otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexIsStartOfText(
    const TkTextIndex *indexPtr)
{
    const TkText *textPtr = indexPtr->textPtr;
    const TkTextSegment *segPtr;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));

    segPtr = textPtr ? textPtr->startMarker : TkBTreeGetShared(indexPtr->tree)->startMarker;
    return indexPtr->priv.linePtr == segPtr->sectionPtr->linePtr && TkTextIndexIsStartOfLine(indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexIsEndOfText --
 *
 *	Test whether this index refers to the end of the text.
 *
 * Results:
 *	Returns true if the end of the text is referred, false otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexIsEndOfText(
    const TkTextIndex *indexPtr)
{
    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));

    if (indexPtr->textPtr) {
	return indexPtr->priv.linePtr == TkBTreeGetLastLine(indexPtr->textPtr);
    }
    return !indexPtr->priv.linePtr->nextPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexIsEqual --
 *
 *	Test whether both given indicies are referring the same byte
 *	index. Such a test makes sense only if both indices are
 *	belonging to the same line.
 *
 * Results:
 *	Return true if both indices are equal, otherwise false will be returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexIsEqual(
    const TkTextIndex *indexPtr1,	/* Pointer to index. */
    const TkTextIndex *indexPtr2)	/* Pointer to index. */
{
    const TkTextSegment *segPtr1;
    const TkTextSegment *segPtr2;

    assert(indexPtr1->priv.linePtr);
    assert(indexPtr2->priv.linePtr);
    assert(indexPtr1->priv.linePtr->parentPtr); /* expired? */
    assert(indexPtr2->priv.linePtr->parentPtr); /* expired? */

    if (indexPtr1->priv.linePtr != indexPtr2->priv.linePtr) {
	return 0;
    }

    if ((segPtr1 = TkTextIndexGetSegment(indexPtr1))) {
	if ((segPtr2 = TkTextIndexGetSegment(indexPtr2))) {
	    while (segPtr1->prevPtr && segPtr1->prevPtr->size == 0) {
		segPtr1 = segPtr1->prevPtr;
	    }
	    while (segPtr2->prevPtr && segPtr2->prevPtr->size == 0) {
		segPtr2 = segPtr2->prevPtr;
	    }
	    return segPtr1 == segPtr2;
	}
    }

    return TkTextIndexGetByteIndex(indexPtr1) == TkTextIndexGetByteIndex(indexPtr2);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexCompare --
 *
 *	Compare two indicies.
 *
 * Results:
 *	It returns an integer less than, equal to, or greater than zero if
 *	indexPtr1 is found, respectively, to be less than, to match, or be
 *	greater than indexPtr2.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexCompare(
    const TkTextIndex *indexPtr1,	/* Pointer to index. */
    const TkTextIndex *indexPtr2)	/* Pointer to index. */
{
    const TkTextSection *sectionPtr1;
    const TkTextSection *sectionPtr2;
    const TkTextSegment *segPtr1;
    const TkTextSegment *segPtr2;

    assert(indexPtr1->priv.linePtr);
    assert(indexPtr2->priv.linePtr);
    assert(indexPtr1->priv.linePtr->parentPtr); /* expired? */
    assert(indexPtr2->priv.linePtr->parentPtr); /* expired? */

    if (indexPtr1->priv.linePtr != indexPtr2->priv.linePtr) {
	int lineNo1 = TkTextIndexGetLineNumber(indexPtr1, NULL);
	int lineNo2 = TkTextIndexGetLineNumber(indexPtr2, NULL);

	return lineNo1 - lineNo2;
    }
    if (indexPtr1->priv.byteIndex >= 0 && indexPtr2->priv.byteIndex >= 0) {
	return indexPtr1->priv.byteIndex - indexPtr2->priv.byteIndex;
    }

    if (!(segPtr1 = TkTextIndexGetSegment(indexPtr1)) || !(segPtr2 = TkTextIndexGetSegment(indexPtr2))) {
	return TkTextIndexGetByteIndex(indexPtr1) - TkTextIndexGetByteIndex(indexPtr2);
    }

    assert(!indexPtr1->priv.isCharSegment || TkBTreeEpoch(indexPtr1->tree) == indexPtr1->stateEpoch);
    assert(!indexPtr2->priv.isCharSegment || TkBTreeEpoch(indexPtr2->tree) == indexPtr2->stateEpoch);

    segPtr1 = indexPtr1->priv.segPtr;
    segPtr2 = indexPtr2->priv.segPtr;
    while (segPtr1->size == 0) {
	segPtr1 = segPtr1->nextPtr;
    }
    while (segPtr2->size == 0) {
	segPtr2 = segPtr2->nextPtr;
    }
    if (segPtr1 == segPtr2) {
	return 0;
    }
    sectionPtr1 = indexPtr1->priv.segPtr->sectionPtr;
    sectionPtr2 = indexPtr2->priv.segPtr->sectionPtr;
    if (sectionPtr1 != sectionPtr2) {
	while (sectionPtr1 && sectionPtr1 != sectionPtr2) {
	    sectionPtr1 = sectionPtr1->nextPtr;
	}
	return sectionPtr1 ? -1 : +1;
    }
    segPtr1 = indexPtr1->priv.segPtr;
    segPtr2 = indexPtr2->priv.segPtr;
    while (segPtr1 != segPtr2) {
	if (!(segPtr1 = segPtr1->nextPtr) || segPtr1->sectionPtr != sectionPtr1) {
	    return +1;
	}
    }
    return -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexAddToByteIndex --
 *
 *	Add given byte offset to byte index.
 *
 *	Note that this function allows that the byte index will reach the
 *	size of the line, in this case the line will be advanced, and the
 *	byte index will be set to zero.
 *
 * Results:
 *	Returns whether we're on same line.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextIndexAddToByteIndex(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    Tcl_Size byteOffset)		/* Add this offset. */
{
    int rc = 1;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));

    if (byteOffset == 0) {
	return 1;
    }

    if (indexPtr->priv.byteIndex == -1) {
	(void) TkTextIndexGetByteIndex(indexPtr);
    }

    if (byteOffset > 0) {
	if ((indexPtr->priv.byteIndex += byteOffset) > FindEndByteIndex(indexPtr)) {
	    assert(indexPtr->priv.linePtr->nextPtr);
	    assert(indexPtr->priv.byteIndex <= indexPtr->priv.linePtr->size);
	    indexPtr->priv.linePtr = indexPtr->priv.linePtr->nextPtr;
	    if (indexPtr->priv.lineNo >= 0) {
		indexPtr->priv.lineNo += 1;
	    }
	    if (indexPtr->priv.lineNoRel >= 0) {
		indexPtr->priv.lineNoRel += 1;
	    }
	    indexPtr->priv.byteIndex = 0;
	    rc = 0;
	}
    } else {
	assert(-byteOffset <= indexPtr->priv.byteIndex);
	indexPtr->priv.byteIndex += byteOffset;
    }

    indexPtr->priv.segPtr = NULL;

    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));

    return rc;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpTextIndexDump --
 *
 *	This function is for debugging only, printing the given index
 *	on stdout.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
#ifndef NDEBUG

void
TkpTextIndexDump(
    TkText *textPtr,		/* May be NULL. */
    const TkTextIndex *indexPtr)/* Pointer to index. */
{
    char buf[TK_POS_CHARS];
    TkTextIndexPrint(TkTextIndexGetShared(indexPtr), textPtr, indexPtr, buf);
    fprintf(stdout, "%s\n", buf);
}

#endif /* NDEBUG */

/*
 *---------------------------------------------------------------------------
 *
 * TkTextNewIndexObj --
 *
 *	This function generates a Tcl_Obj description of an index, suitable
 *	for reading in again later. The index generated is effectively stable
 *	to all except insertion/deletion operations on the widget.
 *
 * Results:
 *	A new Tcl_String with refCount zero.
 *
 * Side effects:
 *	A small amount of memory is allocated.
 *
 *---------------------------------------------------------------------------
 */

Tcl_Obj *
TkTextNewIndexObj(

    const TkTextIndex *indexPtr)/* Pointer to index. */
{

    char buffer[TK_POS_CHARS];
















































    int len;









    assert(indexPtr->textPtr);






    len = TkrTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);

















    return Tcl_NewStringObj(buffer, len);
}



/*
 *---------------------------------------------------------------------------
 *
 * TkrTextMakeByteIndex --
 *
 *	Given a line index and a byte index, look things up in the B-tree and
 *	fill in a TkTextIndex structure.
 *
 * Results:
 *	The structure at *indexPtr is filled in with information about the
 *	character at lineIndex and byteIndex (or the closest existing
 *	character, if the specified one doesn't exist), and indexPtr is
 *	returned as result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextIndex *
TkrTextMakeByteIndex(
    TkTextBTree tree,		/* Tree that lineIndex and byteIndex refer TkTextBTree tree, to. */

    const TkText *textPtr,	/* Client that lineIndex and byteIndex refer to, can be NULL. */
    int lineIndex,		/* Index of desired line (0 means first line of text). */

    Tcl_Size byteIndex,		/* Byte index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    TkTextSegment *segPtr;
    TkTextSection *sectionPtr;
    TkTextLine *linePtr;
    int index, nextIndex;


    TkTextIndexClear2(indexPtr, (TkText *) textPtr, tree);


    if (lineIndex < 0) {
	TkTextIndexSetupToStartOfText(indexPtr, (TkText *) textPtr, tree);
	return indexPtr;
    }

    if (!(linePtr = TkBTreeFindLine(tree, textPtr, lineIndex))) {
	TkTextIndexSetupToEndOfText(indexPtr, (TkText *) textPtr, tree);
	return indexPtr;
    }

    if (byteIndex < 0) {
	byteIndex = 0;
    }

    if (textPtr) {
	if (textPtr->startMarker != textPtr->sharedTextPtr->startMarker
		&& textPtr->startMarker->sectionPtr->linePtr == linePtr) {
	    Tcl_Size startByteIndex;

	    TkTextIndexSetSegment(indexPtr, textPtr->startMarker);
	    startByteIndex = FindStartByteIndex(indexPtr);
	    if (byteIndex <= startByteIndex) {
		return indexPtr;
	    }
	}
	if (textPtr->endMarker != textPtr->sharedTextPtr->endMarker
		&& textPtr->endMarker->sectionPtr->linePtr == linePtr) {
	    int endByteIndex;

	    TkTextIndexSetSegment(indexPtr, textPtr->endMarker);
	    endByteIndex = FindEndByteIndex(indexPtr);
	    if (endByteIndex <= byteIndex) {
		return indexPtr;
	    }
	}
    }

    indexPtr->priv.linePtr = linePtr;

    if (byteIndex == 0) {
	/* this is catching a frequent case */
	TkTextIndexSetByteIndex(indexPtr, 0);
	return indexPtr;
    }

    if (byteIndex >= linePtr->size) {
	/*
	 * Use the index of the last character in the line. Since the last
	 * character on the line is guaranteed to be a '\n', we can back
	 * up one byte.
	 *
	 * Note that it is already guaranteed that we do not exceed the position
	 * of the end marker.
	 */
	TkTextIndexSetByteIndex(indexPtr, linePtr->size - 1);
	return indexPtr;
    }





    indexPtr->priv.byteIndex = byteIndex;
    index = 0;

    sectionPtr = linePtr->segPtr->sectionPtr;
    while ((nextIndex = index + sectionPtr->size) <= byteIndex) {
	index = nextIndex;
	sectionPtr = sectionPtr->nextPtr;
	assert(sectionPtr);
    }

    segPtr = sectionPtr->segPtr;
    while ((nextIndex = index + segPtr->size) < byteIndex) {
	index = nextIndex;
	segPtr = segPtr->nextPtr;
	assert(segPtr);
    }

    /*
     * Verify that the index points to a valid character boundary.


     */

    if (segPtr->typePtr == &tkTextCharType && byteIndex > index && index + segPtr->size > byteIndex) {

	const char *p = segPtr->body.chars + (byteIndex - index);




	/*
	 * Prevent UTF-8 character from being split up by ensuring that byteIndex
	 * falls on a character boundary. If index falls in the middle of a UTF-8

	 * character, it will be adjusted to the end of that UTF-8 character.
	 */




	while ((*p & 0xc0) == 0x80) {
	    ++p;
	    indexPtr->priv.byteIndex += 1;
	}

    }


    return indexPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextMakeCharIndex --
462
463
464
465
466
467
468








469
470
471
472
473
474
475
476
477
478
479
480

481
482
483

484
485
486



487







488



489

490















491


492



493
494
495
496





497








498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528
529






530

531
532



533
534
535
536
537

538




539
540
541


542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570

571


572


573








574
575
576







577



578


579






















580
581
582
583
584
585
586
587

































































588
589
590
591



592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
 *	returned as result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */









TkTextIndex *
TkTextMakeCharIndex(
    TkTextBTree tree,		/* Tree that lineIndex and charIndex refer
				 * to. */
    TkText *textPtr,
    int lineIndex,		/* Index of desired line (0 means first line
				 * of text). */
    int charIndex,		/* Index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    TkTextSegment *segPtr;

    char *p, *start, *end;
    int index, offset;
    int ch;


    indexPtr->tree = tree;
    if (lineIndex < 0) {



	lineIndex = 0;







	charIndex = 0;



    }

    if (charIndex < 0) {















	charIndex = 0;


    }



    indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, lineIndex);
    if (indexPtr->linePtr == NULL) {
	indexPtr->linePtr = TkBTreeFindLine(tree, textPtr,
		TkBTreeNumLines(tree, textPtr));





	charIndex = 0;








    }

    /*
     * Verify that the index is within the range of the line. If not, just use
     * the index of the last character in the line.
     */

    index = 0;
    for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
	if (segPtr == NULL) {
	    /*
	     * Use the index of the last character in the line. Since the last
	     * character on the line is guaranteed to be a '\n', we can back
	     * up a constant sizeof(char) bytes.
	     */

	    indexPtr->byteIndex = index - sizeof(char);
	    break;
	}
	if (segPtr->typePtr == &tkTextCharType) {
	    /*
	     * Turn character offset into a byte offset.
	     */

	    start = segPtr->body.chars;
	    end = start + segPtr->size;

	    for (p = start; p < end; p += offset) {
		if (charIndex == 0) {
		    indexPtr->byteIndex = index;
		    return indexPtr;
		}
		charIndex--;






		offset = TkUtfToUniChar(p, &ch);

		index += offset;
	    }



	} else {
	    if (charIndex < (int)segPtr->size) {
		indexPtr->byteIndex = index;
		break;
	    }

	    charIndex -= segPtr->size;




	    index += segPtr->size;
	}
    }


    return indexPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexToSeg --
 *
 *	Given an index, this function returns the segment and offset within
 *	segment for the index.
 *
 * Results:
 *	The return value is a pointer to the segment referred to by indexPtr;
 *	this will always be a segment with non-zero size. The variable at
 *	*offsetPtr is set to hold the integer offset within the segment of the
 *	character given by indexPtr.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkTextSegment *
TkTextIndexToSeg(
    const TkTextIndex *indexPtr,/* Text index. */
    TkSizeT *offsetPtr)		/* Where to store offset within segment, or
				 * NULL if offset isn't wanted. */
{

    TkTextSegment *segPtr;


    TkSizeT offset;











    for (offset = indexPtr->byteIndex, segPtr = indexPtr->linePtr->segPtr;
	    offset >= segPtr->size;
	    offset -= segPtr->size, segPtr = segPtr->nextPtr) {







	/* Empty loop body. */



    }


    if (offsetPtr != NULL) {






















	*offsetPtr = offset;
    }
    return segPtr;
}

/*
 *---------------------------------------------------------------------------
 *

































































 * TkTextSegToOffset --
 *
 *	Given a segment pointer and the line containing it, this function
 *	returns the offset of the segment within its line.



 *
 * Results:
 *	The return value is the offset (within its line) of the first
 *	character in segPtr.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextSegToOffset(
    const TkTextSegment *segPtr,/* Segment whose offset is desired. */
    const TkTextLine *linePtr)	/* Line containing segPtr. */
{
    const TkTextSegment *segPtr2;
    int offset = 0;

    for (segPtr2 = linePtr->segPtr; segPtr2 != segPtr;
	    segPtr2 = segPtr2->nextPtr) {
	offset += segPtr2->size;
    }
    return offset;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextGetObjIndex --
 *
 *	Simpler wrapper around the string based function, but could be
 *	enhanced with a new object type in the future.
 *
 * Results:
 *	see TkTextGetIndex
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextGetObjIndex(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Obj *idxObj,		/* Object containing textual description of
				 * position. */
    TkTextIndex *indexPtr)	/* Index structure to fill in. */
{
    return GetIndex(interp, NULL, textPtr, Tcl_GetString(idxObj), indexPtr,
	    NULL);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextSharedGetObjIndex --
 *
 *	Simpler wrapper around the string based function, but could be
 *	enhanced with a new object type in the future.
 *
 * Results:
 *	see TkTextGetIndex
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextSharedGetObjIndex(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkSharedText *sharedTextPtr,/* Information about text widget. */
    Tcl_Obj *idxObj,		/* Object containing textual description of
				 * position. */
    TkTextIndex *indexPtr)	/* Index structure to fill in. */
{
    return GetIndex(interp, sharedTextPtr, NULL, Tcl_GetString(idxObj),
	    indexPtr, NULL);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextGetIndex --
 *







>
>
>
>
>
>
>
>



|
<
|
|
<



|
>


|
>

<

>
>
>
|
>
>
>
>
>
>
>
|
>
>
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
|
|
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>







<
<
|
<
<
<
<
<
|
<
<
<
|
|
|
|

|
|
>
|
|
|
|
|
|
>
>
>
>
>
>
|
>
|
|
>
>
>
|
|
|
|

>
|
>
>
>
>
|


>
>






|
















|
|

|
|

>

>
>
|
>
>

>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
|
>
>
>












|
<
<
<
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
 *	returned as result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static unsigned
CountCharsInSeg(
    const TkTextSegment *segPtr)
{
    assert(segPtr->typePtr == &tkTextCharType);
    return Tcl_NumUtfChars(segPtr->body.chars, segPtr->size);
}

TkTextIndex *
TkTextMakeCharIndex(
    TkTextBTree tree,		/* Tree that lineIndex and charIndex refer to. */

    TkText *textPtr,		/* Client that lineIndex and charIndex refer to, can be NULL. */
    int lineIndex,		/* Index of desired line (0 means first line of text). */

    int charIndex,		/* Index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    TkTextSegment *segPtr, *lastPtr;
    TkTextLine *linePtr;
    char *p, *start, *end;
    int index, offset;

    TkTextIndexClear2(indexPtr, textPtr, tree);


    if (lineIndex < 0) {
	TkTextIndexSetupToStartOfText(indexPtr, textPtr, tree);
	return indexPtr;
    }

    if (!(linePtr = TkBTreeFindLine(tree, textPtr, lineIndex))) {
	TkTextIndexSetupToEndOfText(indexPtr, textPtr, tree);
	return indexPtr;
    }

    indexPtr->priv.linePtr = linePtr;

    if (charIndex >= linePtr->size - 1) {
	/* this is catching a frequent case */
	TkTextIndexSetToLastChar(indexPtr);
	return indexPtr;
    }

    if (charIndex <= 0) {
	/* this is catching a frequent case */
	TkTextIndexSetToStartOfLine(indexPtr);
	return indexPtr;
    }

    if (textPtr && textPtr->endMarker->sectionPtr->linePtr == linePtr) {
	lastPtr = textPtr->endMarker;
    } else {
	lastPtr = NULL;
    }

    if (!textPtr
	    || textPtr->startMarker == TkBTreeGetShared(indexPtr->tree)->startMarker
	    || linePtr != textPtr->startMarker->sectionPtr->linePtr) {
	segPtr = linePtr->segPtr;
	index = 0;
    } else {
	TkTextSegment *startPtr;

	/*
	 * We have to skip some segments not belonging to this peer.
	 */

	TkTextIndexSetSegment(indexPtr, textPtr->startMarker);
	startPtr = TkTextIndexGetFirstSegment(indexPtr, NULL);

	for (segPtr = linePtr->segPtr; segPtr != startPtr; segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr == &tkTextCharType) {
		charIndex -= CountCharsInSeg(segPtr);
	    } else {
		assert(segPtr->size <= 1);
		charIndex -= segPtr->size;
	    }
	    if (charIndex <= 0) {
		return indexPtr;
	    }
	}

	index = TkTextIndexGetByteIndex(indexPtr);
	indexPtr->priv.segPtr = NULL;
    }

    /*
     * Verify that the index is within the range of the line. If not, just use
     * the index of the last character in the line.
     */



    while (segPtr != lastPtr) {





	if (segPtr->tagInfoPtr) {



	    if (segPtr->typePtr == &tkTextCharType) {
		/*
		 * Turn character offset into a byte offset.
		 */

		start = segPtr->body.chars;
		end = start + segPtr->size;

		for (p = start; p < end; p += offset) {
		    if (charIndex == 0) {
			indexPtr->priv.byteIndex = index;
			return indexPtr;
		    }
		    charIndex -= 1;
		    { /* local scope */
			/*
			 * Proper implementation for UTF-8 strings:
			 */

			Tcl_UniChar ch;
			offset = Tcl_UtfToUniChar(p, &ch);
		    }
		    index += offset;
		}
	    } else if (charIndex < segPtr->size) {
		indexPtr->priv.byteIndex = index;
		return indexPtr;
	    } else {
		assert(segPtr->size == 1);
		charIndex -= 1;
		index += 1;
	    }
	}
	if (!(segPtr = segPtr->nextPtr)) {
	    /*
	     * Use the index of the last character in the line.
	     */
	    TkTextIndexSetToLastChar(indexPtr);
	    return indexPtr;
	}
    }

    indexPtr->priv.byteIndex = index;
    return indexPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * IndexToSeg --
 *
 *	Given an index, this function returns the segment and offset within
 *	segment for the index.
 *
 * Results:
 *	The return value is a pointer to the segment referred to by indexPtr;
 *	this will always be a segment with non-zero size. The variable at
 *	*offsetPtr is set to hold the integer offset within the segment of the
 *	character given by indexPtr.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static TkTextSegment *
IndexToSeg(
    const TkTextIndex *indexPtr,/* Text index. */
    Tcl_Size *offsetPtr)		/* Where to store offset within segment, or NULL if offset isn't
    				 * wanted. */
{
    TkTextSection *sectionPtr;
    TkTextSegment *segPtr;
    TkTextLine *linePtr;
    Tcl_Size index;

    assert(indexPtr->priv.byteIndex >= 0);
    assert(indexPtr->priv.byteIndex < indexPtr->priv.linePtr->size);

    index = indexPtr->priv.byteIndex;
    linePtr = indexPtr->priv.linePtr;

    /*
     * Speed up a frequent use case.
     */

    if (index == 0) {
	segPtr = linePtr->segPtr;
	while (segPtr->size == 0) {
	    segPtr = segPtr->nextPtr;
	    assert(segPtr);
	}
	if (offsetPtr) {
	    *offsetPtr = 0;
	}
	return segPtr;
    }

    /*
     * Speed up a frequent use case.
     */

    if (index == linePtr->size - 1) {
	assert(linePtr->lastPtr->typePtr == &tkTextCharType);
	if (offsetPtr) {
	    *offsetPtr = linePtr->lastPtr->size - 1;
	}
	return linePtr->lastPtr;
    }

    /*
     * Now we iterate through the section an segment structure until we reach the
     * wanted byte index.
     */

    sectionPtr = linePtr->segPtr->sectionPtr;
    for ( ; index >= sectionPtr->size; sectionPtr = sectionPtr->nextPtr) {
	index -= sectionPtr->size;
	assert(sectionPtr->nextPtr);
    }
    for (segPtr = sectionPtr->segPtr; index >= segPtr->size; segPtr = segPtr->nextPtr) {
	index -= segPtr->size;
	assert(segPtr->nextPtr);
    }
    assert(segPtr->size > 0);

    if (offsetPtr) {
	*offsetPtr = index;
    }
    return segPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * SegToIndex --
 *
 *	Given a segment pointer, this function returns the offset of the
 *	segment within its line.
 *
 *	This function assumes that we want the index to the current line,
 *	and not the index from the start of the logical line.
 *
 * Results:
 *	The return value is the offset (within its line) of the first
 *	character in segPtr.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
SegToIndex(
    const TkTextLine *linePtr,
    const TkTextSegment *segPtr)/* Segment whose offset is desired. */
{
    const TkTextSection *sectionPtr;
    const TkTextSegment *segPtr2;
    int offset;

    assert(segPtr->sectionPtr); /* otherwise not linked */
    assert(segPtr->sectionPtr->linePtr == linePtr);

    sectionPtr = linePtr->segPtr->sectionPtr; /* first segment in line */

    /*
     * Speed up frequent use cases.
     */

    if (segPtr == sectionPtr->segPtr) {
	return 0;
    }

    if (segPtr == linePtr->lastPtr) {
	return linePtr->size - segPtr->size;
    }

    /*
     * Now we iterate through the section an segment structure until we reach the
     * given segment.
     */

    offset = 0;

    for ( ; sectionPtr != segPtr->sectionPtr; sectionPtr = sectionPtr->nextPtr) {
	offset += sectionPtr->size;
	assert(sectionPtr->nextPtr);
    }
    for (segPtr2 = segPtr->sectionPtr->segPtr; segPtr2 != segPtr; segPtr2 = segPtr2->nextPtr) {
	offset += segPtr2->size;
	assert(segPtr2->nextPtr);
    }

    return offset;
}
/*
 *---------------------------------------------------------------------------
 *
 * TkTextSegToIndex --
 *
 *	Given a segment pointer, this function returns the offset of the
 *	segment within its line.
 *
 *	This function assumes that we want the index to the current line,
 *	and not the index from the start of the logical line.
 *
 * Results:
 *	The return value is the offset (within its line) of the first
 *	character in segPtr.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextSegToIndex(



    const TkTextSegment *segPtr)/* Segment whose offset is desired. */

{






    return SegToIndex(segPtr->sectionPtr->linePtr, segPtr);
























































}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextGetIndex --
 *
688
689
690
691
692
693
694



695
696
697
698
699
700
701


702


703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728


















729
730
731
732
733

734
735
736
737
738
739
740
741
742

743





744

745
746
747
748


749





750
751
752
753
754
755

756
757


758

759
760
761
762

763
764
765

766







767



768
769
770
771


772
773
774
775
776
777
778
779
780
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
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */




int
TkTextGetIndex(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* Textual description of position. */
    TkTextIndex *indexPtr)	/* Index structure to fill in. */
{


    return GetIndex(interp, NULL, textPtr, string, indexPtr, NULL);


}

/*
 *---------------------------------------------------------------------------
 *
 * GetIndex --
 *
 *	Given a string, return the index that is described.
 *
 * Results:
 *	The return value is a standard Tcl return result. If TCL_OK is
 *	returned, then everything went well and the index at *indexPtr is
 *	filled in; otherwise TCL_ERROR is returned and an error message is
 *	left in the interp's result.
 *
 *	If *canCachePtr is non-NULL, and everything went well, the integer it
 *	points to is set to 1 if the indexPtr is something which can be
 *	cached, and zero otherwise.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int


















GetIndex(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkSharedText *sharedPtr,
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* Textual description of position. */

    TkTextIndex *indexPtr,	/* Index structure to fill in. */
    int *canCachePtr)		/* Pointer to integer to store whether we can
				 * cache the index (or NULL). */
{
    char *p, *end, *endOfBase;
    TkTextIndex first, last;
    int wantLast, result;
    char c;
    const char *cp;

    Tcl_DString copy;





    int canCache = 0;


    if (sharedPtr == NULL) {
	sharedPtr = textPtr->sharedTextPtr;
    }








    /*
     *---------------------------------------------------------------------
     * Stage 1: check to see if the index consists of nothing but a mark
     * name, an embedded window or an embedded image.  We do this check
     * now even though it's also done later, in order to allow mark names,
     * embedded window names or image names that include funny characters

     * such as spaces or "+1c".
     *---------------------------------------------------------------------


     */


    if (TkTextMarkNameToIndex(textPtr, string, indexPtr) == TCL_OK) {
	goto done;
    }


    if (TkTextWindowIndex(textPtr, string, indexPtr) != 0) {
	goto done;

    }











    if (TkTextImageIndex(textPtr, string, indexPtr) != 0) {
	goto done;
    }



    /*
     *------------------------------------------------
     * Stage 2: start again by parsing the base index.
     *------------------------------------------------
     */

    indexPtr->tree = sharedPtr->tree;

    /*
     * First look for the form "tag.first" or "tag.last" where "tag" is the
     * name of a valid tag. Try to use up as much as possible of the string in
     * this check (strrchr instead of strchr below). Doing the check now, and
     * in this way, allows tag names to include funny characters like "@" or
     * "+1c".
     */

    Tcl_DStringInit(&copy);
    p = strrchr(Tcl_DStringAppend(&copy, string, -1), '.');
    if (p != NULL) {
	TkTextSearch search;


	TkTextTag *tagPtr;
	Tcl_HashEntry *hPtr = NULL;
	const char *tagName;


	if ((p[1] == 'f') && (strncmp(p+1, "first", 5) == 0)) {

	    wantLast = 0;
	    endOfBase = p+6;

	} else if ((p[1] == 'l') && (strncmp(p+1, "last", 4) == 0)) {
	    wantLast = 1;
	    endOfBase = p+5;

	} else {
	    goto tryxy;
	}





	tagPtr = NULL;

	tagName = Tcl_DStringValue(&copy);


	if (((p - tagName) == 3) && !strncmp(tagName, "sel", 3)) {





	    /*
	     * Special case for sel tag which is not stored in the hash table.
	     */

	    tagPtr = textPtr->selTagPtr;

	} else {
	    *p = 0;
	    hPtr = Tcl_FindHashEntry(&sharedPtr->tagTable, tagName);
	    *p = '.';
	    if (hPtr != NULL) {
		tagPtr = (TkTextTag *)Tcl_GetHashValue(hPtr);









	    }
	}





	if (tagPtr == NULL) {


	    goto tryxy;

	}



























	TkTextMakeByteIndex(sharedPtr->tree, textPtr, 0, 0, &first);
	TkTextMakeByteIndex(sharedPtr->tree, textPtr,
		TkBTreeNumLines(sharedPtr->tree, textPtr), 0, &last);



	TkBTreeStartSearch(&first, &last, tagPtr, &search);
	if (!TkBTreeCharTagged(&first, tagPtr) && !TkBTreeNextTag(&search)) {
	    if (tagPtr == textPtr->selTagPtr) {
		tagName = "sel";


	    } else if (hPtr != NULL) {





		tagName = (const char *)Tcl_GetHashKey(&sharedPtr->tagTable, hPtr);






	    }
















	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "text doesn't contain any characters tagged with \"%s\"",
		    tagName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_INDEX", tagName,
		    NULL);
	    Tcl_DStringFree(&copy);
	    return TCL_ERROR;
	}
	*indexPtr = search.curIndex;
	if (wantLast) {
	    while (TkBTreeNextTag(&search)) {
		*indexPtr = search.curIndex;
	    }
	}
	goto gotBase;
    }

  tryxy:
    if (string[0] == '@') {
	/*
	 * Find character at a given x,y location in the window.
	 */

	int x, y;

	cp = string+1;







	x = strtol(cp, &end, 0);
	if ((end == cp) || (*end != ',')) {
	    goto error;
	}

	cp = end+1;







	y = strtol(cp, &end, 0);
	if (end == cp) {
	    goto error;

	}
	TkTextPixelIndex(textPtr, x, y, indexPtr, NULL);
	endOfBase = end;
	goto gotBase;
    }

    if (isdigit(UCHAR(string[0])) || (string[0] == '-')) {
	int lineIndex, charIndex;

	/*
	 * Base is identified with line and character indices.
	 */

	lineIndex = strtol(string, &end, 0) - 1;
	if ((end == string) || (*end != '.')) {
	    goto error;
	}
	p = end+1;
	if ((*p == 'e') && (strncmp(p, "end", 3) == 0)) {
	    charIndex = LAST_CHAR;
	    endOfBase = p+3;



	} else {
	    charIndex = strtol(p, &end, 0);
	    if (end == p) {
		goto error;
	    }
	    endOfBase = end;
	}



	TkTextMakeCharIndex(sharedPtr->tree, textPtr, lineIndex, charIndex,
		indexPtr);
	canCache = 1;
	goto gotBase;
    }

    for (p = Tcl_DStringValue(&copy); *p != 0; p++) {
	if (isspace(UCHAR(*p)) || (*p == '+') || (*p == '-')) {
	    break;
	}
    }
    endOfBase = p;
    if (string[0] == '.') {
	/*
	 * See if the base position is the name of an embedded window.
	 */

	c = *endOfBase;
	*endOfBase = 0;
	result = TkTextWindowIndex(textPtr, Tcl_DStringValue(&copy), indexPtr);
	*endOfBase = c;
	if (result != 0) {
	    goto gotBase;
	}
    }
    if ((string[0] == 'e')



	    && (strncmp(string, "end",

	    endOfBase-Tcl_DStringValue(&copy)) == 0)) {


	/*
	 * Base position is end of text.
	 */

	TkTextMakeByteIndex(sharedPtr->tree, textPtr,
		TkBTreeNumLines(sharedPtr->tree, textPtr), 0, indexPtr);
	canCache = 1;
	goto gotBase;

    } else {
	/*
	 * See if the base position is the name of a mark.
	 */

	c = *endOfBase;
	*endOfBase = 0;
	result = TkTextMarkNameToIndex(textPtr, Tcl_DStringValue(&copy),
		indexPtr);

	*endOfBase = c;
	if (result == TCL_OK) {
	    goto gotBase;
	}

	/*
	 * See if the base position is the name of an embedded image.
	 */

	c = *endOfBase;
	*endOfBase = 0;
	result = TkTextImageIndex(textPtr, Tcl_DStringValue(&copy), indexPtr);
	*endOfBase = c;
	if (result != 0) {
	    goto gotBase;
	}
    }







    goto error;






    /*
     *-------------------------------------------------------------------
     * Stage 3: process zero or more modifiers. Each modifier is either a
     * keyword like "wordend" or "linestart", or it has the form "op count
     * units" where op is + or -, count is a number, and units is "chars" or
     * "lines".
     *-------------------------------------------------------------------
     */

  gotBase:
    cp = endOfBase;

    while (1) {
	while (isspace(UCHAR(*cp))) {
	    cp++;
	}
	if (*cp == 0) {
	    break;
	}

	if ((*cp == '+') || (*cp == '-')) {
	    cp = ForwBack(textPtr, cp, indexPtr);
	} else {
	    cp = StartEnd(textPtr, cp, indexPtr);
	}
	if (cp == NULL) {
	    goto error;
	}
    }
    Tcl_DStringFree(&copy);

  done:
    if (canCachePtr != NULL) {
	*canCachePtr = canCache;
    }
    if (indexPtr->linePtr == NULL) {
	Tcl_Panic("Bad index created");
    }
    return TCL_OK;

  error:
    Tcl_DStringFree(&copy);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad text index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_INDEX", NULL);
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextPrintIndex --
 *
 *	This function generates a string description of an index, suitable for
 *	reading in again later.
 *
 * Results:
 *	The characters pointed to by string are modified. Returns the number
 *	of characters in the string.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkSizeT
TkTextPrintIndex(


    const TkText *textPtr,
    const TkTextIndex *indexPtr,/* Pointer to index. */
    char *string)		/* Place to store the position. Must have at
				 * least TK_POS_CHARS characters. */
{
    TkTextSegment *segPtr;
    TkTextLine *linePtr;
    int numBytes, charIndex;

    numBytes = indexPtr->byteIndex;
    charIndex = 0;
    linePtr = indexPtr->linePtr;

    for (segPtr = linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
	if (segPtr == NULL) {
	    /*
	     * Two logical lines merged into one display line through eliding
	     * of a newline.
	     */

	    linePtr = TkBTreeNextLine(NULL, linePtr);
	    segPtr = linePtr->segPtr;
	}
	if (numBytes <= (int)segPtr->size) {
	    break;
	}
	if (segPtr->typePtr == &tkTextCharType) {
	    charIndex += Tcl_NumUtfChars(segPtr->body.chars, segPtr->size);
	} else {
	    charIndex += segPtr->size;
	}
	numBytes -= segPtr->size;


    }



    if (segPtr->typePtr == &tkTextCharType) {
	charIndex += Tcl_NumUtfChars(segPtr->body.chars, numBytes);
    } else {
	charIndex += numBytes;




    }



    return sprintf(string, "%d.%d",
	    TkBTreeLinesTo(textPtr, indexPtr->linePtr) + 1, charIndex);
}



/*
 *---------------------------------------------------------------------------
 *

 * TkTextIndexCmp --
 *
 *	Compare two indices to see which one is earlier in the text.
 *
 * Results:
 *	The return value is 0 if index1Ptr and index2Ptr refer to the same
 *	position in the file, -1 if index1Ptr refers to an earlier position
 *	than index2Ptr, and 1 otherwise.
 *
 * Side effects:

 *	None.
 *
 *---------------------------------------------------------------------------
 */

int

TkTextIndexCmp(
    const TkTextIndex*index1Ptr,/* First index. */
    const TkTextIndex*index2Ptr)/* Second index. */
{
    int line1, line2;



    if (index1Ptr->linePtr == index2Ptr->linePtr) {


	if (index1Ptr->byteIndex < index2Ptr->byteIndex) {
	    return -1;
	} else if (index1Ptr->byteIndex > index2Ptr->byteIndex) {
	    return 1;
	} else {
	    return 0;

	}


    }

    /*
     * Assumption here that it is ok for comparisons to reflect the full
     * B-tree and not just the portion that is available to any client. This
     * should be true because the only indexPtr's we should be given are ones
     * which are valid for the current client.
     */





    line1 = TkBTreeLinesTo(NULL, index1Ptr->linePtr);
    line2 = TkBTreeLinesTo(NULL, index2Ptr->linePtr);
    if (line1 < line2) {
	return -1;
    }
    if (line1 > line2) {
	return 1;
    }

    return 0;

}

/*
 *---------------------------------------------------------------------------
 *
 * ForwBack --
 *







>
>
>

|





>
>
|
>
>





|




<
|
|
|
<
<
<
<







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|


>
|
<
<



<


>

>
>
>
>
>
|
>

|
|
|
>
>
|
>
>
>
>
>
|
<
|
<
<
<
>
|
<
>
>
|
>
|
<
|
<
>
|
|
<
>
|
>
>
>
>
>
>
>

>
>
>
|
|
|
|
>
>


|



|


|
|
|
|
<



|
|
|
>
>
|
|
<
|
>
|
>
|
|
>
|
|
|
>
|
|
|

>
>
>
>
|
>
|
>
>
|
>
>
>
>
>



<

>

|
|
|
|

>
>
>
>
>
>
>
>
>


>

>
>
>
|
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
>
|
<
|
<
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<
|
<

|


<
<
<
|
|
|
<









|
>
>
>
>
>
>
>
|
|
|
|
>
|
>
>
>
>
>
>
>
|
|
|
>






|







|
|

|
|
|
|
>
>
>

|

|



>
>
>
|
<
<



|
|










|
|

|



|
>
>
>
|
>
|
>
>




|
<
<

>
|
|
|
|

|
|
|
<
>

<
|
|

|
|
|

<
<
|
|
|
|
|
|
>
>
>
>
>
>
>
|
>
>
>
>
>



|








>




|


|
<
|



|
|


<

<
<
<
<
<
<
<
<
<
<

<
<
|





|














|
|
>
>
|

|
|

|
|
<
|
<
|
<

|
|
<
<
<
<
|
|
|
|
<
<
<
<
<
<
|
<
|
>
>
|
>
>
|
<
<
<
<
>
>
>
>
|
>
>

<
|
|
>
>
|
<
<
|
>
|
<
|
<
|
<
<
|
<
|
>
|
<
<
<
|
<
>
|
<
<
|
<
>
>
|
|
>
>
|
|
|
|
|
|
>
|
>
>
|

<
<
<
|
|
<
>
>
>
>
|
<
<
<
<
|
<
<

>
|
>







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
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

MODULE_SCOPE int TkpTextGetIndex(Tcl_Interp *interp, TkSharedText *sharedTextPtr, TkText *textPtr,
			    const char *string, unsigned lenOfString, TkTextIndex *indexPtr);

int
TkrTextGetIndex(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* Textual description of position. */
    TkTextIndex *indexPtr)	/* Index structure to fill in. */
{
    assert(textPtr);
    assert(string);

    return TkpTextGetIndex(interp, textPtr->sharedTextPtr, textPtr, string, strlen(string), indexPtr) ?
	    TCL_OK : TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpTextGetIndex --
 *
 *	Given a string, return the index that is described.
 *
 * Results:

 *	If 'true' is returned, then everything went well and the index at
 *	*indexPtr is filled in; otherwise 'false' is returned and an error
 *	message is left in the interp's result.




 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static unsigned
SkipSegments(
    TkTextSegment *startMarkPtr)
{
    TkTextSegment *segPtr = startMarkPtr->sectionPtr->linePtr->segPtr;
    unsigned charIndex = 0;

    /* Skip chars not belonging to this text widget. */

    for ( ; segPtr != startMarkPtr; segPtr = segPtr->nextPtr) {
	if (segPtr->tagInfoPtr) {
	    charIndex += (segPtr->typePtr == &tkTextCharType) ? CountCharsInSeg(segPtr) : 1;
	}
    }

    return charIndex;
}

int
TkpTextGetIndex(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkSharedText *sharedTextPtr,/* Pointer to shared resource. */
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* Textual description of position. */
    unsigned lenOfString,	/* Length of textual description. */
    TkTextIndex *indexPtr)	/* Index structure to fill in. */


{
    char *p, *end, *endOfBase;
    TkTextIndex first, last;

    char c;
    const char *cp;
    char *myString;
    Tcl_DString copy;
    Tcl_HashEntry *hPtr;
    TkTextTag *tagPtr;
    int skipMark;
    int wantLast;
    int wantCurrent;
    int result;
    int charCount = -1;

    assert(textPtr);
    assert(sharedTextPtr);

    /*
     * The documentation about indices says:
     *
     *	The base for an index must have one of the following forms:
     *
     *		<line>.<char>
     *		@<x>,<y>
     *		begin
     *		end

     *		<mark>



     *		<tag>.first
     *		<tag>.last

     *		<tag>.current.first
     *		<tag>.current.last
     *		<pathName>
     *		<imageName>
     *

     * Furthermore the documentation says:

     *
     *	If the base could match more than one of the above forms, such as a mark and imageName
     *	both having the same value, then the form earlier in the above list takes precedence.

     */

#if BEGIN_DOES_NOT_BELONG_TO_BASE
    /*
     *------------------------------------------------
     * Stage 0: for portability reasons keyword "begin" has the lowest
     * precedence (but this should be corrected in a future version).
     *------------------------------------------------
     */

    if (string[0] == 'b' && strncmp(string, "begin", 5)) {
	if (TkTextMarkNameToIndex(textPtr, string, indexPtr)
		|| TkTextWindowIndex(textPtr, string, indexPtr)
		|| TkTextImageIndex(textPtr, string, indexPtr)) {
	    return 1;
	}
    }
#endif /* BEGIN_DOES_NOT_BELONG_TO_BASE */

    /*
     *------------------------------------------------
     * Stage 1: start by parsing the base index.
     *------------------------------------------------
     */

    TkTextIndexClear(indexPtr, textPtr);

    /*
     * First look for the form "tag.first", "tag.last", and then for "tag.current.first"
     * or "tag.current.last", where "tag" is the name of a valid tag. Try to use up as
     * much as possible of the string in this check. Doing the check now, and in this way,
     * allows tag names to include funny characters like "@" or "+1c".

     */

    Tcl_DStringInit(&copy);
    myString = Tcl_DStringAppend(&copy, string, TCL_INDEX_NONE);
    skipMark = 0;

    p = myString + lenOfString;
    do {
	if (p-- == myString) {
	    goto tryxy;

	}
    } while (*p != '.');

    if (p[1] == 'f' && strncmp(p + 2, "irst", 4) == 0) {
	wantLast = 0;
	endOfBase = p + 6;
	lenOfString = p - myString;
    } else if (p[1] == 'l' && strncmp(p + 2, "ast", 3) == 0) {
	wantLast = 1;
	endOfBase = p + 5;
	lenOfString = p - myString;
    } else {
	goto tryxy;
    }

    /*
     * Marks have a higher precedence than tag.first or tag.last, so we will
     * search for marks before proceeding with tags.
     */

    if (TkTextMarkNameToIndex(textPtr, string, indexPtr)) {
	Tcl_DStringFree(&copy);
	return 1;
    }

    skipMark = 1;
    wantCurrent = 0;

    do {
	if (lenOfString == 3 && strncmp(myString, "sel", 3) == 0) {
	    /*
	     * Special case for sel tag which is not stored in the hash table.
	     */

	    tagPtr = textPtr->selTagPtr;
	    hPtr = NULL;
	} else {
	    myString[lenOfString] = '\0';
	    hPtr = Tcl_FindHashEntry(&sharedTextPtr->tagTable, myString);
	    myString[lenOfString] = '.';
	    if (hPtr) {
		tagPtr = (TkTextTag *)Tcl_GetHashValue(hPtr);
	    } else if (!wantCurrent
		    && lenOfString >= 8
		    && p[-8] == '.'
		    && strncmp(p - 7, "current", 7) == 0) {
		tagPtr = NULL;
		wantCurrent = 1;
		lenOfString -= 8;
	    } else {
		goto tryxy;
	    }
	}
    } while (!tagPtr);

    if (wantCurrent) {
	int tagFound = 0;

	if (tagPtr->rootPtr) {
	    TkTextIndex currIndex;
	    TkTextSegment *segPtr;

	    assert(!textPtr->haveToSetCurrentMark);

	    segPtr = textPtr->currentMarkPtr;
	    do {
		segPtr = segPtr->nextPtr;
	    } while (!segPtr->tagInfoPtr);

	    if (TkTextTagSetTest(segPtr->tagInfoPtr, tagPtr->index)) {
		TkTextIndexClear(&currIndex, textPtr);
		TkTextIndexSetSegment(&currIndex, segPtr);
		TkTextIndexForwChars(textPtr, &currIndex, 1, &currIndex, COUNT_INDICES);
		tagFound = 1;
	    } else {
		segPtr = textPtr->currentMarkPtr;
		do {
		    segPtr = segPtr->prevPtr;
		} while (segPtr && !segPtr->tagInfoPtr);

		if (!segPtr) {
		    TkTextLine *linePtr = textPtr->currentMarkPtr->sectionPtr->linePtr->prevPtr;
		    segPtr = linePtr ? linePtr->lastPtr : NULL;
		}
		if (segPtr && TkTextTagSetTest(segPtr->tagInfoPtr, tagPtr->index)) {
		    if (wantLast) {
			/* in this case we've already found the end of the range */
			TkTextIndexClear(indexPtr, textPtr);
			TkTextIndexSetSegment(indexPtr, textPtr->currentMarkPtr);
			goto gotBase;
		    }

		    TkTextIndexClear(&currIndex, textPtr);
		    TkTextIndexSetSegment(&currIndex, textPtr->currentMarkPtr);
		    tagFound = 1;
		}
	    }


	    if (tagFound) {

		if (wantLast) {
		    TkTextTagFindEndOfRange(textPtr, tagPtr, &currIndex, indexPtr);
		} else {
		    TkTextTagFindStartOfRange(textPtr, tagPtr, &currIndex, indexPtr);
		}
	    }
	}
	if (!tagFound) {
	    const char *tagName = hPtr ? (const char *)Tcl_GetHashKey(&sharedTextPtr->tagTable, hPtr) : "sel";

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "character near current position isn't tagged with \"%s\"", tagName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_INDEX", tagName, (char *)NULL);
	    Tcl_DStringFree(&copy);
	    return 0;
	}
    } else {
	TkTextSearch search;
	int tagFound;

	TkTextIndexSetupToStartOfText(&first, textPtr, sharedTextPtr->tree);
	TkTextIndexSetupToEndOfText(&last, textPtr, sharedTextPtr->tree);
	if (wantLast) {
	    TkBTreeStartSearchBack(&last, &first, tagPtr, &search, SEARCH_EITHER_TAGON_TAGOFF);
	    tagFound = TkBTreePrevTag(&search);
	} else {
	    TkBTreeStartSearch(&first, &last, tagPtr, &search, SEARCH_NEXT_TAGON);
	    tagFound = TkBTreeNextTag(&search);
	}
	if (!tagFound) {
	    const char *tagName = hPtr ? (const char *)Tcl_GetHashKey(&sharedTextPtr->tagTable, hPtr) : "sel";

	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "text doesn't contain any characters tagged with \"%s\"", tagName));

	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_INDEX", tagName, (char *)NULL);

	    Tcl_DStringFree(&copy);
	    return 0;
	}
	*indexPtr = search.curIndex;



    }

    goto gotBase;


  tryxy:
    if (string[0] == '@') {
	/*
	 * Find character at a given x,y location in the window.
	 */

	int x, y;

	cp = string + 1;
	if (*cp == 'f' && strncmp(cp, "first,", 6) == 0) {
	    x = TkTextGetFirstXPixel(textPtr);
	    end = (char *) cp + 5;
	} else if (*cp == 'l' && strncmp(cp, "last,", 5) == 0) {
	    x = TkTextGetLastXPixel(textPtr);
	    end = (char *) cp + 4;
	} else {
	    x = strtol(cp, &end, 0);
	    if (end == cp || *end != ',') {
		goto noBaseFound;
	    }
	}
	cp = end + 1;
	if (*cp == 'f' && strcmp(cp, "first") == 0) {
	    y = TkTextGetFirstYPixel(textPtr);
	    end += 6;
	} else if (*cp == 'l' && strcmp(cp, "last") == 0) {
	    y = TkTextGetLastYPixel(textPtr);
	    end += 5;
	} else {
	    y = strtol(cp, &end, 0);
	    if (end == cp) {
		goto noBaseFound;
	    }
	}
	TkTextPixelIndex(textPtr, x, y, indexPtr, NULL);
	endOfBase = end;
	goto gotBase;
    }

    if (isdigit(UCHAR(string[0])) || string[0] == '-') {
	int lineIndex, charIndex;

	/*
	 * Base is identified with line and character indices.
	 */

	lineIndex = strtol(string, &end, 0) - 1;
	if (end == string || *end != '.') {
	    goto noBaseFound;
	}
	p = end + 1;
	if (*p == 'e' && strncmp(p, "end", 3) == 0) {
	    charIndex = INT_MAX;
	    endOfBase = p + 3;
	} else if (*p == 'b' && strncmp(p, "begin", 5) == 0) {
	    charCount = charIndex = 0;
	    endOfBase = p + 5;
	} else {
	    charCount = charIndex = strtol(p, &end, 0);
	    if (end == p) {
		goto noBaseFound;
	    }
	    endOfBase = end;
	}
	if (lineIndex == 0 && textPtr->startMarker != sharedTextPtr->startMarker) {
	    charIndex += SkipSegments(textPtr->startMarker);
	}
	TkTextMakeCharIndex(sharedTextPtr->tree, textPtr, lineIndex, charIndex, indexPtr);


	goto gotBase;
    }

    for (p = myString; *p; ++p) {
	if (isspace(UCHAR(*p)) || *p == '+' || *p == '-') {
	    break;
	}
    }
    endOfBase = p;
    if (string[0] == '.') {
	/*
	 * See if the base position is the name of an embedded window.
	 */

	c = *endOfBase;
	*endOfBase = '\0';
	result = TkTextWindowIndex(textPtr, myString, indexPtr);
	*endOfBase = c;
	if (result) {
	    goto gotBase;
	}
    }
    if (string[0] == 'b' && endOfBase - myString == 5 && strncmp(string, "begin", 5) == 0) {
	/*
	 * Base position is start of text.
	 */

	TkTextIndexSetupToStartOfText(indexPtr, textPtr, sharedTextPtr->tree);
	goto gotBase;
    }
    if (string[0] == 'e' && endOfBase - myString == 3 && strncmp(string, "end", 3) == 0) {
	/*
	 * Base position is end of text.
	 */

	TkTextIndexSetupToEndOfText(indexPtr, textPtr, sharedTextPtr->tree);


	goto gotBase;
    }

    /*
     * See if the base position is the name of a mark.
     */

    c = *endOfBase;
    *endOfBase = '\0';
    result = TkTextMarkNameToIndex(textPtr, myString, indexPtr);

    if (result) {
	*endOfBase = c;

	goto gotBase;
    }

    /*
     * See if the base position is the name of an embedded image.
     */



    result = TkTextImageIndex(textPtr, myString, indexPtr);
    *endOfBase = c;
    if (result) {
	goto gotBase;
    }

  noBaseFound:
    if ((!skipMark && TkTextMarkNameToIndex(textPtr, string, indexPtr))
	    || TkTextWindowIndex(textPtr, string, indexPtr)
	    || TkTextImageIndex(textPtr, string, indexPtr)) {
	Tcl_DStringFree(&copy);
	return 1;
    }

    Tcl_DStringFree(&copy);
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad text index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_INDEX", (char *)NULL);
    return 0;

    /*
     *-------------------------------------------------------------------
     * Stage 2: process zero or more modifiers. Each modifier is either a
     * keyword like "wordend" or "linestart", or it has the form "op count
     * units" where op is + or -, count is a number, and units is "chars" or
     * "lines".
     *-------------------------------------------------------------------
     */

  gotBase:
    cp = endOfBase;

    while (1) {
	while (isspace(UCHAR(*cp))) {
	    cp++;
	}
	if (*cp == '\0') {
	    break;
	}
	if (*cp == '+' || *cp == '-') {

	    cp = ForwBack(textPtr, cp, indexPtr, charCount);
	} else {
	    cp = StartEnd(textPtr, cp, indexPtr);
	}
	if (!cp) {
	    goto noBaseFound;
	}
    }












    Tcl_DStringFree(&copy);


    return 1;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexPrint --
 *
 *	This function generates a string description of an index, suitable for
 *	reading in again later.
 *
 * Results:
 *	The characters pointed to by string are modified. Returns the number
 *	of characters in the string.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexPrint(
    const TkSharedText *sharedTextPtr,
    				/* Pointer to shared resource. */
    const TkText *textPtr,	/* Information about text widget, can be NULL. */
    const TkTextIndex *indexPtr,/* Pointer to index. */
    char *string)		/* Place to store the position. Must have at least TK_POS_CHARS
    				 * characters. */
{
    const TkTextSegment *segPtr;
    const TkTextLine *linePtr;

    const TkTextSegment *startMarker;

    int charIndex;


    assert(sharedTextPtr);
    assert(indexPtr);




    assert(string);
    assert(CheckLine(indexPtr, indexPtr->priv.linePtr));
    assert(CheckByteIndex(indexPtr, indexPtr->priv.linePtr, -1));







    charIndex = 0;

    linePtr = indexPtr->priv.linePtr;
    startMarker = textPtr ? textPtr->startMarker : sharedTextPtr->startMarker;
    segPtr = (linePtr == startMarker->sectionPtr->linePtr) ? startMarker : linePtr->segPtr;

    /*
     * Too bad that we cannot use the section structure here.
     *




     * The user of the Tk text widget is encouraged to work with marks,
     * in this way the expensive mappings between char indices and byte
     * indices can be avoided in many cases.
     */

    if (indexPtr->priv.segPtr && !indexPtr->priv.isCharSegment) {
	TkTextSegment *lastPtr = indexPtr->priv.segPtr;


	assert(indexPtr->priv.segPtr->typePtr);

	while (lastPtr->size == 0) {
	    lastPtr = lastPtr->nextPtr;
	}



	for ( ; segPtr != lastPtr; segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr == &tkTextCharType) {

		charIndex += CountCharsInSeg(segPtr);

	    } else {


		assert(segPtr->size <= 1);

		charIndex += segPtr->size;
	    }
	    assert(segPtr->nextPtr);



	}

    } else {
	Tcl_Size numBytes = TkTextIndexGetByteIndex(indexPtr);




	if (segPtr == startMarker && startMarker != sharedTextPtr->startMarker) {
	    numBytes -= TkTextSegToIndex(startMarker);
	}

	assert(numBytes >= 0);
	assert(numBytes < linePtr->size);

	for ( ; numBytes > segPtr->size; segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr == &tkTextCharType) {
		charIndex += CountCharsInSeg(segPtr);
	    } else {
		assert(segPtr->size <= 1);
		charIndex += segPtr->size;
	    }
	    numBytes -= segPtr->size;
	    assert(segPtr->nextPtr);
	}




	if (numBytes) {
	    if (segPtr->typePtr == &tkTextCharType) {

		charIndex += Tcl_NumUtfChars(segPtr->body.chars, numBytes);
	    } else {
		assert(segPtr->size <= 1);
		charIndex += numBytes;
	    }




	}


    }

    return snprintf(string, TK_POS_CHARS, "%d.%d",
	    TkBTreeLinesTo(indexPtr->tree, textPtr, linePtr, NULL) + 1, charIndex);
}

/*
 *---------------------------------------------------------------------------
 *
 * ForwBack --
 *
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

static const char *
ForwBack(
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* String to parse for additional info about
				 * modifier (count and units). Points to "+"
				 * or "-" that starts modifier. */
    TkTextIndex *indexPtr)	/* Index to update as specified in string. */

{
    const char *p, *units;
    char *end;
    int count, lineIndex, modifier;
    size_t length;



    /*
     * Get the count (how many units forward or backward).
     */

    p = string+1;
    while (isspace(UCHAR(*p))) {
	p++;
    }
    count = strtol(p, &end, 0);
    if (end == p) {
	return NULL;
    }







|
>






>
>




|







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

static const char *
ForwBack(
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* String to parse for additional info about
				 * modifier (count and units). Points to "+"
				 * or "-" that starts modifier. */
    TkTextIndex *indexPtr,	/* Index to update as specified in string. */
    int charCount)		/* The character position in this line, -1 if not yet determined. */
{
    const char *p, *units;
    char *end;
    int count, lineIndex, modifier;
    size_t length;

    assert(textPtr);

    /*
     * Get the count (how many units forward or backward).
     */

    p = string + 1;
    while (isspace(UCHAR(*p))) {
	p++;
    }
    count = strtol(p, &end, 0);
    if (end == p) {
	return NULL;
    }
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231

1232
















1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276


1277


1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346








1347


1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358

1359
1360
1361


1362




1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415

1416
1417


1418



1419
1420
1421
1422
1423

1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450




1451

1452


























1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472



1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490

1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506

1507
1508


1509

1510

1511


1512
1513


1514
1515
1516

1517
1518
1519
1520
1521
1522



1523


1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552


1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569

1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582

1583




1584

1585




1586



1587

1588
1589
1590
1591
1592
1593
1594


1595
1596
1597
1598








1599
1600
1601
1602
1603
1604
1605


1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623


1624
1625
1626
1627



1628




















1629





1630


1631




1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682


1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697

1698
1699
1700















1701

1702
1703


1704
1705

1706
1707
1708
1709
1710




1711



1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731


1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753

1754
1755
1756
1757
1758
1759












1760
1761
1762
1763
1764
1765

1766

1767





1768
1769










1770




1771
1772













1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860


1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937





1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948







1949
1950
1951
1952

1953

1954
1955
1956



1957
1958
1959
1960


1961
1962



1963


1964
1965
1966




1967
1968
1969

1970

1971

1972
1973


1974
1975
1976
1977
1978

1979
1980

1981
1982
1983
1984
1985
1986
1987
     * modifiers can be their own word (in which case they can be abbreviated)
     * or they can follow on to the actual unit in a single word (in which
     * case no abbreviation is allowed). So, 'display lines', 'd lines',
     * 'displaylin' are all ok, but 'dline' is not.
     */

    units = p;
    while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) {
	p++;
    }
    length = p - units;
    if ((*units == 'd') &&
	    (strncmp(units, "display", (length > 7 ? 7 : length)) == 0)) {
	modifier = TKINDEX_DISPLAY;
	if (length > 7) {
	    p -= (length - 7);
	}
    } else if ((*units == 'a') &&
	    (strncmp(units, "any", (length > 3 ? 3 : length)) == 0)) {
	modifier = TKINDEX_ANY;
	if (length > 3) {
	    p -= (length - 3);
	}
    } else {
	modifier = TKINDEX_NONE;
    }

    /*
     * If we had a modifier, which we interpreted ok, so now forward to the
     * actual units.
     */

    if (modifier != TKINDEX_NONE) {
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	units = p;
	while (*p!='\0' && !isspace(UCHAR(*p)) && *p!='+' && *p!='-') {
	    p++;
	}
	length = p - units;
    }

    /*
     * Finally parse the units.
     */

    if ((*units == 'c') && (strncmp(units, "chars", length) == 0)) {
	TkTextCountType type;

	if (modifier == TKINDEX_NONE) {
	    type = COUNT_INDICES;
	} else if (modifier == TKINDEX_ANY) {

	    type = COUNT_CHARS;
















	} else {
	    type = COUNT_DISPLAY_CHARS;
	}

	if (*string == '+') {
	    TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type);
	} else {
	    TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type);
	}
    } else if ((*units == 'i') && (strncmp(units, "indices", length) == 0)) {
	TkTextCountType type;

	if (modifier == TKINDEX_DISPLAY) {
	    type = COUNT_DISPLAY_INDICES;
	} else {
	    type = COUNT_INDICES;
	}

	if (*string == '+') {
	    TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type);
	} else {
	    TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type);
	}
    } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) {
	if (modifier == TKINDEX_DISPLAY) {
	    /*
	     * Find the appropriate pixel offset of the current position
	     * within its display line. This also has the side-effect of
	     * moving indexPtr, but that doesn't matter since we will do it
	     * again below.
	     *
	     * Then find the right display line, and finally calculated the
	     * index we want in that display line, based on the original pixel
	     * offset.
	     */

	    int xOffset, forward;


	    if (TkTextIsElided(textPtr, indexPtr, NULL)) {
		/*
		 * Go forward to the first non-elided index.
		 */

		TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,


			COUNT_DISPLAY_INDICES);


	    }

	    /*
	     * Unlike the Forw/BackChars code, the display line code is
	     * sensitive to whether we are genuinely going forwards or
	     * backwards. So, we need to determine that. This is important in
	     * the case where we have "+ -3 displaylines", for example.
	     */

	    if ((count < 0) ^ (*string == '-')) {
		forward = 0;
	    } else {
		forward = 1;
	    }

	    count = abs(count);
	    if (count == 0) {
		return p;
	    }

	    if (forward) {
		TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, &xOffset);
		while (count-- > 0) {

		    /*
		     * Go to the end of the line, then forward one char/byte
		     * to get to the beginning of the next line.
		     */

		    TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, NULL);
		    TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
			    COUNT_DISPLAY_INDICES);
		}
	    } else {
		TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, &xOffset);
		while (count-- > 0) {
                    TkTextIndex indexPtr2;

		    /*
		     * Go to the beginning of the line, then backward one
		     * char/byte to get to the end of the previous line.
		     */

		    TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
		    TkTextIndexBackChars(textPtr, indexPtr, 1, &indexPtr2,
			    COUNT_DISPLAY_INDICES);

                    /*
                     * If we couldn't go to the previous line, then we wanted
                       to go before the start of the text: arrange for returning
                       the first index of the first display line.
                     */

                    if (!TkTextIndexCmp(indexPtr, &indexPtr2)) {
                        xOffset = 0;
                        break;
                    }
                    *indexPtr = indexPtr2;
		}
	    }
            TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);

	    /*
	     * This call assumes indexPtr is the beginning of a display line
	     * and moves it to the 'xOffset' position of that line, which is
	     * just what we want.
	     */

	    TkTextIndexOfX(textPtr, xOffset, indexPtr);








	} else {


	    lineIndex = TkBTreeLinesTo(textPtr, indexPtr->linePtr);
	    if (*string == '+') {
		lineIndex += count;
	    } else {
		lineIndex -= count;

		/*
		 * The check below retains the character position, even if the
		 * line runs off the start of the file. Without it, the
		 * character position will get reset to 0 by TkTextMakeIndex.
		 */


		if (lineIndex < 0) {
		    lineIndex = 0;


		}




	    }

	    /*
	     * This doesn't work quite right if using a proportional font or
	     * UTF-8 characters with varying numbers of bytes, or if there are
	     * embedded windows, images, etc. The cursor will bop around,
	     * keeping a constant number of bytes (not characters) from the
	     * left edge (but making sure not to split any UTF-8 characters),
	     * regardless of the x-position the index corresponds to. The
	     * proper way to do this is to get the x-position of the index and
	     * then pick the character at the same x-position in the new line.
	     */

	    TkTextMakeByteIndex(indexPtr->tree, textPtr, lineIndex,
		    indexPtr->byteIndex, indexPtr);
	}
    } else {
	return NULL;
    }
    return p;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexForwBytes --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" bytes ahead of the source index.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" bytes after
 *	srcPtr, or to the last character in the TkText if there aren't "count"
 *	bytes left.
 *
 *	In this latter case, the function returns '1' to indicate that not all
 *	of 'byteCount' could be used.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexForwBytes(
    const TkText *textPtr,
    const TkTextIndex *srcPtr,	/* Source index. */
    int byteCount,		/* How many bytes forward to move. May be
				 * negative. */
    TkTextIndex *dstPtr)	/* Destination index: gets modified. */
{
    TkTextLine *linePtr;

    TkTextSegment *segPtr;
    int lineLength;






    if (byteCount < 0) {
	TkTextIndexBackBytes(textPtr, srcPtr, -byteCount, dstPtr);
	return 0;
    }


    *dstPtr = *srcPtr;
    dstPtr->byteIndex += byteCount;
    while (1) {
	/*
	 * Compute the length of the current line.
	 */

	lineLength = 0;
	for (segPtr = dstPtr->linePtr->segPtr; segPtr != NULL;
		segPtr = segPtr->nextPtr) {
	    lineLength += segPtr->size;
	}

	/*
	 * If the new index is in the same line then we're done. Otherwise go
	 * on to the next line.
	 */

	if (dstPtr->byteIndex < lineLength) {
	    return 0;
	}
	dstPtr->byteIndex -= lineLength;
	linePtr = TkBTreeNextLine(textPtr, dstPtr->linePtr);
	if (linePtr == NULL) {
	    dstPtr->byteIndex = lineLength - 1;
	    return 1;
	}




	dstPtr->linePtr = linePtr;

    }


























}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexForwChars --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" items of type given by "type" ahead of the source
 *	index. "count" can be zero, which is useful in the case where one
 *	wishes to move forward by display (non-elided) chars or indices or one
 *	wishes to move forward by chars, skipping any intervening indices. In
 *	this case dstPtr will point to the first acceptable index which is
 *	encountered.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" items after
 *	srcPtr, or to the last character in the TkText if there aren't
 *	sufficient items left in the widget.
 *



 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TkTextIndexForwChars(
    const TkText *textPtr,	/* Overall information about text widget. */
    const TkTextIndex *srcPtr,	/* Source index. */
    int charCount,		/* How many characters forward to move. May
				 * be negative. */
    TkTextIndex *dstPtr,	/* Destination index: gets modified. */
    TkTextCountType type)	/* The type of item to count */
{
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    TkTextElideInfo *infoPtr = NULL;

    TkSizeT byteOffset;
    char *start, *end, *p;
    int ch;
    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);

    if (charCount < 0) {
	TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);
	return;
    }
    if (checkElided) {
	infoPtr = (TkTextElideInfo *)ckalloc(sizeof(TkTextElideInfo));
	elide = TkTextIsElided(textPtr, srcPtr, infoPtr);
    }

    *dstPtr = *srcPtr;


    /*


     * Find seg that contains src byteIndex. Move forward specified number of

     * chars.

     */



    if (checkElided) {


	/*
	 * In this case we have already calculated the information we need, so
	 * no need to use TkTextIndexToSeg()

	 */

	segPtr = infoPtr->segPtr;
	byteOffset = dstPtr->byteIndex - infoPtr->segOffset;
    } else {
	segPtr = TkTextIndexToSeg(dstPtr, &byteOffset);



    }



    while (1) {
	/*
	 * Go through each segment in line looking for specified character
	 * index.
	 */

	for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) {
	    /*
	     * If we do need to pay attention to the visibility of
	     * characters/indices, check that first. If the current segment
	     * isn't visible, then we simply continue the loop.
	     */

	    if (checkElided && ((segPtr->typePtr == &tkTextToggleOffType)
		    || (segPtr->typePtr == &tkTextToggleOnType))) {
		TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;

		/*
		 * The elide state only changes if this tag is either the
		 * current highest priority tag (and is therefore being
		 * toggled off), or it's a new tag with higher priority.
		 */

		if (tagPtr->elideString != NULL) {
		    infoPtr->tagCnts[tagPtr->priority]++;
		    if (infoPtr->tagCnts[tagPtr->priority] & 1) {
			infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
		    }



		    if (tagPtr->priority >= infoPtr->elidePriority) {
			if (segPtr->typePtr == &tkTextToggleOffType) {
			    /*
			     * If it is being toggled off, and it has an elide
			     * string, it must actually be the current highest
			     * priority tag, so this check is redundant:
			     */

			    if (tagPtr->priority != infoPtr->elidePriority) {
				Tcl_Panic("Bad tag priority being toggled off");
			    }

			    /*
			     * Find previous elide tag, if any (if not then
			     * elide will be zero, of course).
			     */


			    elide = 0;
			    while (--infoPtr->elidePriority > 0) {
				if (infoPtr->tagCnts[infoPtr->elidePriority]
					& 1) {
				    elide = infoPtr->tagPtrs
					    [infoPtr->elidePriority]->elide;
				    break;
				}
			    }
			} else {
			    elide = tagPtr->elide;
			    infoPtr->elidePriority = tagPtr->priority;

			}




		    }

		}




	    }





	    if (!elide) {
		if (segPtr->typePtr == &tkTextCharType) {
		    start = segPtr->body.chars + byteOffset;
		    end = segPtr->body.chars + segPtr->size;
		    for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) {
			if (charCount == 0) {
			    dstPtr->byteIndex += (p - start);


			    goto forwardCharDone;
			}
			charCount--;
		    }








		} else if (type & COUNT_INDICES) {
		    if (charCount + byteOffset < segPtr->size) {
			dstPtr->byteIndex += charCount;
			goto forwardCharDone;
		    }
		    charCount -= segPtr->size - byteOffset;
		}


	    }

	    dstPtr->byteIndex += segPtr->size - byteOffset;
	    byteOffset = 0;
	}

	/*
	 * Go to the next line. If we are at the end of the text item, back up
	 * one byte (for the terminal '\n' character) and return that index.
	 */

	linePtr = TkBTreeNextLine(textPtr, dstPtr->linePtr);
	if (linePtr == NULL) {
	    dstPtr->byteIndex -= sizeof(char);
	    goto forwardCharDone;

	}
	dstPtr->linePtr = linePtr;
	dstPtr->byteIndex = 0;


	segPtr = dstPtr->linePtr->segPtr;
    }

  forwardCharDone:



    if (infoPtr != NULL) {




















	TkTextFreeElideInfo(infoPtr);





	ckfree(infoPtr);


    }




}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCountBytes --
 *
 *	Given a pair of indices in a text widget, this function counts how
 *	many bytes are between the two indices. The two indices do not need
 *	to be ordered.
 *
 * Results:
 *	The number of bytes in the given range.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexCountBytes(
    const TkText *textPtr,
    const TkTextIndex *indexPtr1, /* Index describing one location. */
    const TkTextIndex *indexPtr2) /* Index describing second location. */
{
    int compare = TkTextIndexCmp(indexPtr1, indexPtr2);

    if (compare == 0) {
	return 0;
    } else if (compare > 0) {
	return IndexCountBytesOrdered(textPtr, indexPtr2, indexPtr1);
    } else {
	return IndexCountBytesOrdered(textPtr, indexPtr1, indexPtr2);
    }
}

static int
IndexCountBytesOrdered(
    const TkText *textPtr,
    const TkTextIndex *indexPtr1,
				/* Index describing location of character from
				 * which to count. */
    const TkTextIndex *indexPtr2)
				/* Index describing location of last character
				 * at which to stop the count. */
{
    TkSizeT byteCount, offset;
    TkTextSegment *segPtr, *segPtr1;
    TkTextLine *linePtr;



    if (indexPtr1->linePtr == indexPtr2->linePtr) {
        return indexPtr2->byteIndex - indexPtr1->byteIndex;
    }

    /*
     * indexPtr2 is on a line strictly after the line containing indexPtr1.
     * Add up:
     *   bytes between indexPtr1 and end of its line
     *   bytes in lines strictly between indexPtr1 and indexPtr2
     *   bytes between start of the indexPtr2 line and indexPtr2
     */

    segPtr1 = TkTextIndexToSeg(indexPtr1, &offset);
    byteCount = -offset;
    for (segPtr = segPtr1; segPtr != NULL; segPtr = segPtr->nextPtr) {

        byteCount += segPtr->size;
    }
















    linePtr = TkBTreeNextLine(textPtr, indexPtr1->linePtr);

    while (linePtr != indexPtr2->linePtr) {
	for (segPtr = linePtr->segPtr; segPtr != NULL;


                segPtr = segPtr->nextPtr) {
            byteCount += segPtr->size;

        }
        linePtr = TkBTreeNextLine(textPtr, linePtr);
        if (linePtr == NULL) {
            Tcl_Panic("TextIndexCountBytesOrdered ran out of lines");
        }




    }




    byteCount += indexPtr2->byteIndex;

    return byteCount;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCount --
 *
 *	Given an ordered pair of indices in a text widget, this function
 *	counts how many characters (not bytes) are between the two indices.
 *
 *	It is illegal to call this function with unordered indices.
 *
 *	Note that 'textPtr' is only used if we need to check for elided
 *	attributes, i.e. if type is COUNT_DISPLAY_INDICES or
 *	COUNT_DISPLAY_CHARS.
 *


 * Results:
 *	The number of characters in the given range, which meet the
 *	appropriate 'type' attributes.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexCount(
    const TkText *textPtr,	/* Overall information about text widget. */
    const TkTextIndex *indexPtr1,
				/* Index describing location of character from
				 * which to count. */
    const TkTextIndex *indexPtr2,
				/* Index describing location of last character
				 * at which to stop the count. */
    TkTextCountType type)	/* The kind of indices to count. */
{
    TkTextLine *linePtr1;

    TkTextSegment *segPtr, *seg2Ptr = NULL;
    TkTextElideInfo *infoPtr = NULL;
    TkSizeT byteOffset, maxBytes, count = 0;
    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);













    /*
     * Find seg that contains src index, and remember how many bytes not to
     * count in the given segment.
     */

    segPtr = TkTextIndexToSeg(indexPtr1, &byteOffset);

    linePtr1 = indexPtr1->linePtr;







    seg2Ptr = TkTextIndexToSeg(indexPtr2, &maxBytes);











    if (checkElided) {




	infoPtr = (TkTextElideInfo *)ckalloc(sizeof(TkTextElideInfo));
	elide = TkTextIsElided(textPtr, indexPtr1, infoPtr);













    }

    while (1) {
	/*
	 * Go through each segment in line adding up the number of characters.
	 */

	for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) {
	    /*
	     * If we do need to pay attention to the visibility of
	     * characters/indices, check that first. If the current segment
	     * isn't visible, then we simply continue the loop.
	     */

	    if (checkElided) {
		if ((segPtr->typePtr == &tkTextToggleOffType)
			|| (segPtr->typePtr == &tkTextToggleOnType)) {
		    TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;

		    /*
		     * The elide state only changes if this tag is either the
		     * current highest priority tag (and is therefore being
		     * toggled off), or it's a new tag with higher priority.
		     */

		    if (tagPtr->elideString != NULL) {
			infoPtr->tagCnts[tagPtr->priority]++;
			if (infoPtr->tagCnts[tagPtr->priority] & 1) {
			    infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
			}
			if (tagPtr->priority >= infoPtr->elidePriority) {
			    if (segPtr->typePtr == &tkTextToggleOffType) {
				/*
				 * If it is being toggled off, and it has an
				 * elide string, it must actually be the
				 * current highest priority tag, so this check
				 * is redundant:
				 */

				if (tagPtr->priority!=infoPtr->elidePriority) {
				    Tcl_Panic("Bad tag priority being toggled off");
				}

				/*
				 * Find previous elide tag, if any (if not
				 * then elide will be zero, of course).
				 */

				elide = 0;
				while (--infoPtr->elidePriority > 0) {
				    if (infoPtr->tagCnts[
					    infoPtr->elidePriority] & 1) {
					elide = infoPtr->tagPtrs[
						infoPtr->elidePriority]->elide;
					break;
				    }
				}
			    } else {
				elide = tagPtr->elide;
				infoPtr->elidePriority = tagPtr->priority;
			    }
			}
		    }
		}
		if (elide) {
		    if (segPtr == seg2Ptr) {
			goto countDone;
		    }
		    byteOffset = 0;
		    continue;
		}
	    }

	    if (segPtr->typePtr == &tkTextCharType) {
		TkSizeT byteLen = segPtr->size - byteOffset;
		unsigned char *str = (unsigned char *)
			segPtr->body.chars + byteOffset;
		TkSizeT i;

		if (segPtr == seg2Ptr) {
		    if (byteLen + byteOffset > maxBytes) {
			byteLen = maxBytes - byteOffset;
		    }
		}
		i = byteLen;

		/*
		 * This is a speed sensitive function, so run specially over


		 * the string to count continuous ascii characters before
		 * resorting to the Tcl_NumUtfChars call. This is a long form
		 * of:
		 *
		 *   stringPtr->numChars =
		 *	     Tcl_NumUtfChars(objPtr->bytes, objPtr->length);
		 */

		while (i && (*str < 0xC0)) {
		    i--;
		    str++;
		}
		count += byteLen - i;
		if (i) {
		    count += Tcl_NumUtfChars(segPtr->body.chars + byteOffset
			    + (byteLen - i), i);
		}
	    } else {
		if (type & COUNT_INDICES) {
		    TkSizeT byteLen = segPtr->size - byteOffset;

		    if (segPtr == seg2Ptr) {
			if (byteLen + byteOffset > maxBytes) {
			    byteLen = maxBytes - byteOffset;
			}
		    }
		    count += byteLen;
		}
	    }
	    if (segPtr == seg2Ptr) {
		goto countDone;
	    }
	    byteOffset = 0;
	}

	/*
	 * Go to the next line. If we are at the end of the text item, back up
	 * one byte (for the terminal '\n' character) and return that index.
	 */

	linePtr1 = TkBTreeNextLine(textPtr, linePtr1);
	if (linePtr1 == NULL) {
	    Tcl_Panic("Reached end of text widget when counting characters");
	}
	segPtr = linePtr1->segPtr;
    }

  countDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);
	ckfree(infoPtr);
    }
    return count;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexBackBytes --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" bytes earlier than the source index.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" bytes before
 *	srcPtr, or to the first character in the TkText if there aren't
 *	"count" bytes earlier than srcPtr.
 *
 *	Returns 1 if we couldn't use all of 'byteCount' because we have run
 *	into the beginning or end of the text, and zero otherwise.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */






int
TkTextIndexBackBytes(
    const TkText *textPtr,
    const TkTextIndex *srcPtr,	/* Source index. */
    int byteCount,		/* How many bytes backward to move. May be
				 * negative. */
    TkTextIndex *dstPtr)	/* Destination index: gets modified. */
{
    TkTextSegment *segPtr;
    int lineIndex;








    if (byteCount < 0) {
	return TkTextIndexForwBytes(textPtr, srcPtr, -byteCount, dstPtr);
    }


    *dstPtr = *srcPtr;

    dstPtr->byteIndex -= byteCount;
    lineIndex = -1;
    while (dstPtr->byteIndex < 0) {



	/*
	 * Move back one line in the text. If we run off the beginning of the
	 * file then just return the first character in the text.
	 */



	if (lineIndex < 0) {



	    lineIndex = TkBTreeLinesTo(textPtr, dstPtr->linePtr);


	}
	if (lineIndex == 0) {
	    dstPtr->byteIndex = 0;




	    return 1;
	}
	lineIndex--;

	dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, textPtr, lineIndex);



	/*
	 * Compute the length of the line and add that to dstPtr->charIndex.


	 */

	for (segPtr = dstPtr->linePtr->segPtr; segPtr != NULL;
		segPtr = segPtr->nextPtr) {
	    dstPtr->byteIndex += segPtr->size;

	}
    }

    return 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexBackChars --







|



<
|




<
|
|

















|









|


|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|







|













|












|
>

<
|
|
|

|
>
>
|
>
>









<
|
<
<
<
<

<
<
|
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
|

|
|
|
|

<
<
<
|
<
<
<
<
<
|
|
|
<
|
<
|
<
<








>
>
>
>
>
>
>
>

>
>
|

|

|
|
<
<
|
<
<
>

|
|
>
>

>
>
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<










|


|



|












|
|

|
<



>
|
|
>
>
|
>
>
>

|



>
|
<
<
<
<
<
|
<
<
<
<
|
|
<
<
<
<
|
<
<
|
<
|
|
<


>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















>
>
>






|

|

|
<





|
>
|
<
|
|
|


|
<

|
|
|


|
>
|
|
>
>
|
>
|
>
|
>
>
|
|
>
>
|
<
<
>
|

<
<
<
|
>
>
>
|
>
>



|
<


|
<
<
<
<
<
|
<
|
|
|
<
|
<
<
<
|
<
<
<
<
|
>
>

|
|
|
<
<
<
<
|
<
<
|
|
<
<
<
<
>
|
<
<
<
|
<
<



<
<
|
>

>
>
>
>
|
>
|
>
>
>
>
|
>
>
>
|
>
|
<
|
|
<
|
|
>
>
|
|
|
|
>
>
>
>
>
>
>
>
|
|
<
|
|
<
<
>
>

<
<
<







|
<
|
<
>

|
|
>
>
|


|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
|
>
>
>
>








|
|










|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
|

|
<


>
>
|
|










|
|
|
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
<
>
>
|
|
>
|
|
|
<
|
>
>
>
>
|
>
>
>
|
<

|
















>
>










|



|
<

|
|


|
>
|
<
|
|
|

>
>
>
>
>
>
>
>
>
>
>
>

|
<


|
>
|
>

>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>







|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<

<
<
<
<
|
<
|
<
<
<
|
<
<
<
|
<
<
|
<
<
>
>
|
<
<
<
<
<
<
|
<
<
|
|
<
<
<
<
|
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<


|
|
<
<
|


<
<
<
<
<
|





|


















>
>
>
>
>

|
|

|
<


|
|

>
>
>
>
>
>
>

|


>
|
>
|
|
|
>
>
>

<
<
<
>
>

|
>
>
>
|
>
>
|
|
|
>
>
>
>
|
|
|
>
|
>
|
>
|
<
>
>
|

<
|
|
>
|
|
>







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
     * modifiers can be their own word (in which case they can be abbreviated)
     * or they can follow on to the actual unit in a single word (in which
     * case no abbreviation is allowed). So, 'display lines', 'd lines',
     * 'displaylin' are all ok, but 'dline' is not.
     */

    units = p;
    while (*p != '\0' && !isspace(UCHAR(*p)) && *p != '+' && *p != '-') {
	p++;
    }
    length = p - units;

    if (*units == 'd' && strncmp(units, "display", MIN(length, 7u)) == 0) {
	modifier = TKINDEX_DISPLAY;
	if (length > 7) {
	    p -= (length - 7);
	}

    } else if (*units == 'a' && strncmp(units, "any", MIN(length, 3u)) == 0) {
	modifier = TKINDEX_CHAR;
	if (length > 3) {
	    p -= (length - 3);
	}
    } else {
	modifier = TKINDEX_NONE;
    }

    /*
     * If we had a modifier, which we interpreted ok, so now forward to the
     * actual units.
     */

    if (modifier != TKINDEX_NONE) {
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	units = p;
	while (*p != '\0' && !isspace(UCHAR(*p)) && *p != '+' && *p != '-') {
	    p++;
	}
	length = p - units;
    }

    /*
     * Finally parse the units.
     */

    if (*units == 'c' && strncmp(units, "chars", length) == 0) {
	TkTextCountType type;

	if (modifier == TKINDEX_DISPLAY) {
	    type = COUNT_DISPLAY_CHARS;
	} else { /* if (modifier == TKINDEX_NONE) */
	    assert(modifier == TKINDEX_NONE || modifier == TKINDEX_CHAR);

	    /*
	     * The following is incompatible to 8.4 (and prior versions), but I think that
	     * now it's the time to eliminate this known issue:
	     *
	     *    Before Tk 8.5, the widget used the string “chars” to refer to index positions
	     *    (which included characters, embedded windows and embedded images). As of Tk 8.5
	     *    the text widget deals separately and correctly with “chars” and “indices”. For
	     *    backwards compatibility, however, the index modifiers “+N chars” and “-N chars”
	     *    continue to refer to indices. One must use any of the full forms “+N any chars”
	     *    or “-N any chars” etc. to refer to actual character indices. This confusion may
	     *    be fixed in a future release by making the widget correctly interpret “+N chars”
	     *    as a synonym for “+N any chars”.
	     *
	     * This confusion is fixed now, we will interpret "+N chars" as a synonym for
	     * “+N any chars”.
	     */

	    type = COUNT_CHARS;
	}

	if (*string == '+') {
	    TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type);
	} else {
	    TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type);
	}
    } else if (*units == 'i' && strncmp(units, "indices", length) == 0) {
	TkTextCountType type;

	if (modifier == TKINDEX_DISPLAY) {
	    type = COUNT_DISPLAY_INDICES;
	} else {
	    type = COUNT_INDICES;
	}

	if (*string == '+') {
	    TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type);
	} else {
	    TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type);
	}
    } else if (*units == 'l' && strncmp(units, "lines", length) == 0) {
	if (modifier == TKINDEX_DISPLAY) {
	    /*
	     * Find the appropriate pixel offset of the current position
	     * within its display line. This also has the side-effect of
	     * moving indexPtr, but that doesn't matter since we will do it
	     * again below.
	     *
	     * Then find the right display line, and finally calculated the
	     * index we want in that display line, based on the original pixel
	     * offset.
	     */

	    int xOffset;
	    int forward;


	    /*
	     * Go forward to the first non-elided index.
	     */

	    if (TkTextIsElided(indexPtr)) {
		TkTextSkipElidedRegion(indexPtr);
	    }

	    if (count == 0) {
		return p;
	    }

	    /*
	     * Unlike the Forw/BackChars code, the display line code is
	     * sensitive to whether we are genuinely going forwards or
	     * backwards. So, we need to determine that. This is important in
	     * the case where we have "+ -3 displaylines", for example.
	     */


	    forward = (count < 0) == (*string == '-');




	    count = abs(count);




            if (forward) {









                TkTextFindDisplayIndex(textPtr, indexPtr, count, &xOffset);


            } else {


                TkTextIndex indexPtr2 = *indexPtr;

                /*
                 * Check crossing of the start of text boundary. If crossed, adjust
                 * xOffset so that the returned index will refer to the start of line.
                 */




                TkTextFindDisplayIndex(textPtr, &indexPtr2, -(count - 1), NULL);





                TkTextFindDisplayIndex(textPtr, indexPtr, -count, &xOffset);
                if (!TkTextIndexCompare(indexPtr, &indexPtr2)) {
                    xOffset = 0;

                }

            }



	    /*
	     * This call assumes indexPtr is the beginning of a display line
	     * and moves it to the 'xOffset' position of that line, which is
	     * just what we want.
	     */

	    TkTextIndexOfX(textPtr, xOffset, indexPtr);

	    /*
	     * We must skip any elided range.
	     */

	    if (TkTextIsElided(indexPtr)) {
		TkTextSkipElidedRegion(indexPtr);
	    }
	} else {
	    int newLineIndex;

	    lineIndex = TkBTreeLinesTo(indexPtr->tree, textPtr, indexPtr->priv.linePtr, NULL);
	    if (*string == '+') {
		newLineIndex = MIN(TkrBTreeNumLines(indexPtr->tree, textPtr), lineIndex + count);
	    } else {
		newLineIndex = MAX(0, lineIndex - count);
	    }


	    if (newLineIndex != lineIndex) {


		TkTextLine *linePtr = TkBTreeFindLine(indexPtr->tree, textPtr, newLineIndex);

		if (charCount == -1) {
		    TkTextIndex lineStart = *indexPtr;
		    TkTextIndexSetToStartOfLine(&lineStart);
		    charCount = TkTextIndexCount(textPtr, &lineStart, indexPtr, COUNT_CHARS);
		}
		TkTextIndexSetToStartOfLine2(indexPtr, linePtr);
		TkTextIndexForwChars(textPtr, indexPtr, charCount, indexPtr, COUNT_CHARS);
		if (linePtr != TkTextIndexGetLine(indexPtr)) {
		    TkTextIndexSetToEndOfLine2(indexPtr, linePtr);
		}
	    }













	}
    } else {
	return NULL;
    }
    return p;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkrTextIndexForwBytes --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "byteCount" bytes ahead of the source index.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" bytes after
 *	srcPtr, or to the last character in the TkText if there aren't "byteCount"
 *	bytes left.
 *
 *	In this latter case, the function returns '1' to indicate that not all
 *	of 'byteCount' could be used.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkrTextIndexForwBytes(
    const TkText *textPtr,	/* Overall information about text widget, can be NULL. */
    const TkTextIndex *srcPtr,	/* Source index. */
    Tcl_Size byteCount,		/* How many bytes forward to move. May be negative. */

    TkTextIndex *dstPtr)	/* Destination index: gets modified. */
{
    TkTextLine *linePtr;
    Tcl_Size byteIndex;

    if (byteCount == 0) {
	if (dstPtr != srcPtr) {
	    *dstPtr = *srcPtr;
	}
	return 0;
    }

    if (byteCount < 0) {
	TkrTextIndexBackBytes(textPtr, srcPtr, -byteCount, dstPtr);
	return 0;
    }

    if (dstPtr != srcPtr) {
	*dstPtr = *srcPtr;





    }





    TkTextIndexToByteIndex(dstPtr);




    linePtr = TkTextIndexGetLine(dstPtr);




    if (textPtr) {
	if (linePtr == TkBTreeGetLastLine(textPtr)) {

	    return 1;
	}
	if (textPtr->endMarker->sectionPtr->linePtr == linePtr) {
	    /*
	     * Special case: line contains end marker.
	     */

	    int lineLength = SegToIndex(linePtr, textPtr->endMarker);

	    if ((byteIndex = (dstPtr->priv.byteIndex += byteCount)) > lineLength) {
		assert(linePtr->nextPtr);
		TkTextIndexSetByteIndex2(dstPtr, linePtr->nextPtr, 0);
	    }
	    return byteIndex <= lineLength ? 0 : 1;
	}
    } else if (!linePtr->nextPtr) {
	return 1;
    }

    if ((byteIndex = dstPtr->priv.byteIndex + byteCount) > linePtr->size) {
	int rc;
	DEBUG(TkTextIndex index = *srcPtr);
	rc = TkBTreeMoveForward(dstPtr, byteCount);
	assert(!rc || (int) TkTextIndexCountBytes(&index, dstPtr) == byteCount);
	return rc ? 0 : 1;
    }

    if (byteIndex == linePtr->size) {
	assert(linePtr->nextPtr);
	TkTextIndexSetByteIndex2(dstPtr, linePtr->nextPtr, 0);
    } else {
	TkTextIndexSetByteIndex(dstPtr, byteIndex);
    }

    return 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexForwChars --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" items of type given by "type" ahead of the source
 *	index. "count" can be zero, which is useful in the case where one
 *	wishes to move forward by display (non-elided) chars or indices or one
 *	wishes to move forward by chars, skipping any intervening indices. In
 *	this case dstPtr will point to the first acceptable index which is
 *	encountered.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" items after
 *	srcPtr, or to the last character in the TkText if there aren't
 *	sufficient items left in the widget.
 *
 *	This function returns whether the resulting index is different from
 *	source index.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexForwChars(
    const TkText *textPtr,	/* Overall information about text widget, can be NULL. */
    const TkTextIndex *srcPtr,	/* Source index. */
    Tcl_Size charCount,		/* How many characters forward to move. May be negative. */

    TkTextIndex *dstPtr,	/* Destination index: gets modified. */
    TkTextCountType type)	/* The type of item to count */
{
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    TkTextSegment *endPtr;
    TkSharedText *sharedTextPtr;
    Tcl_Size byteOffset;

    int checkElided;
    int trimmed;
    int skipSpaces;

    if (charCount < 0) {
	return TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);

    }

    if (dstPtr != srcPtr) {
	*dstPtr = *srcPtr;
    }

    if (TkTextIndexIsEndOfText(dstPtr)) {
	return 0;
    }

    sharedTextPtr = TkTextIndexGetShared(srcPtr);
    checkElided = !!(type & COUNT_DISPLAY) && TkBTreeHaveElidedSegments(sharedTextPtr);

    if (checkElided && TkTextIsElided(dstPtr) && !TkTextSkipElidedRegion(dstPtr)) {
	return 0;
    }

    if (charCount == 0) {
	return 0;
    }

    assert(dstPtr->priv.byteIndex <= FindEndByteIndex(dstPtr));

    /*


     * Find seg that contains src byteIndex. Move forward specified number of chars.
     */




    segPtr = TkTextIndexGetFirstSegment(dstPtr, &byteOffset);
    endPtr = textPtr ? textPtr->endMarker : sharedTextPtr->endMarker;
    trimmed = textPtr && textPtr->spaceMode == TEXT_SPACEMODE_TRIM && !!(type & COUNT_DISPLAY);
    skipSpaces = 0;

    TkTextIndexToByteIndex(dstPtr);
    dstPtr->priv.segPtr = NULL;

    while (1) {
	/*
	 * Go through each segment in line looking for specified character index.

	 */

	for ( ; segPtr; segPtr = segPtr->nextPtr) {





	    if (segPtr->tagInfoPtr) {

		if (segPtr->typePtr == &tkTextCharType) {
		    const char *start = segPtr->body.chars + byteOffset;
		    const char *end = segPtr->body.chars + segPtr->size;

		    const char *p = start;



		    int n;





		    for (p = start; p < end; p += n) {
			Tcl_UniChar ch;

			if (charCount <= 0) {
			    if (skipSpaces) {
				while (*p == ' ') {




				    ++p;


				}
				if (*p == '\n') {




				    ++p;
				}



				if (p == end) {


				    break;
				}
			    }


			    dstPtr->priv.byteIndex += (p - start);
			    goto forwardCharDone;
			}
			{ /* local scope */
			    /*
			     * Proper implementation for UTF-8 strings:
			     */

			    n = Tcl_UtfToUniChar(p, &ch);
			}
			if (ch == ' ') {
			    if (!skipSpaces) {
				skipSpaces = trimmed;
				charCount -= 1;
			    }
			} else {
			    skipSpaces = 0;
			    charCount -= (type & COUNT_INDICES) ? n : 1;
			}
		    }
		} else if (type & COUNT_INDICES) {

		    assert(byteOffset == 0);
		    assert(segPtr->size <= 1);

		    if (charCount < segPtr->size) {
			dstPtr->priv.byteIndex += charCount;
			dstPtr->priv.segPtr = segPtr;
			dstPtr->priv.isCharSegment = 0;
			goto forwardCharDone;
		    }
		    charCount -= segPtr->size;
		}
		dstPtr->priv.byteIndex += segPtr->size - byteOffset;
		byteOffset = 0;
	    } else if (checkElided && segPtr->typePtr == &tkTextBranchType) {
		TkTextIndexSetSegment(dstPtr, segPtr = segPtr->body.branch.nextPtr);
		if (TkTextIndexRestrictToEndRange(dstPtr) >= 0) {
		    return 1;
		}
		TkTextIndexToByteIndex(dstPtr);
	    } else if (segPtr == endPtr) {
		if (charCount <= 0) {

		    goto forwardCharDone;
		}


		TkTextIndexSetupToEndOfText(dstPtr, (TkText *) textPtr, srcPtr->tree);
		return 1;
	    }



	}

	/*
	 * Go to the next line. If we are at the end of the text item, back up
	 * one byte (for the terminal '\n' character) and return that index.
	 */

	if (!(linePtr = TkBTreeNextLine(textPtr, dstPtr->priv.linePtr))) {

	    TkTextIndexSetToLastChar(dstPtr);

	    return 1;
	}
	dstPtr->priv.linePtr = linePtr;
	dstPtr->priv.byteIndex = 0;
	dstPtr->priv.lineNo = -1;
	dstPtr->priv.lineNoRel = -1;
	segPtr = linePtr->segPtr;
    }

forwardCharDone:
    dstPtr->stateEpoch = TkBTreeEpoch(dstPtr->tree);
    return 1;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextSkipElidedRegion --
 *
 *	Given an index for a text widget, this function returns an index with
 *	the position of first un-elided character, or end of text, if the first
 *	un-elided character is beyond of this text widget. This functions assumes
 *	that the text position specified with incoming index is elided.
 *
 * Results:
 *	*indexPtr is modified to refer to the first un-elided character. This
 *	functions returns 'false' iff we reach the end of the text (belonging to
 *	this widget).
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextSkipElidedRegion(
    TkTextIndex *indexPtr)
{
    TkTextSegment *segPtr;

    assert(indexPtr->textPtr);
    assert(TkTextIsElided(indexPtr));

    segPtr = TkBTreeFindEndOfElidedRange(indexPtr->textPtr->sharedTextPtr,
	    indexPtr->textPtr, TkTextIndexGetContentSegment(indexPtr, NULL));
    TkTextIndexSetSegment(indexPtr, segPtr);
    return !TkTextIndexIsEndOfText(indexPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCountBytes --
 *
 *	Given a pair of indices in a text widget, this function counts how
 *	many bytes are between the two indices. The two indices must be
 *	ordered.
 *
 * Results:
 *	The number of bytes in the given range.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

unsigned
TkTextIndexCountBytes(


















    const TkTextIndex *indexPtr1,	/* Index describing location of character from which to count. */


    const TkTextIndex *indexPtr2)	/* Index describing location of last character at which to

    					 * stop the count. */
{
    int byteCount;

    TkTextLine *linePtr;

    assert(TkTextIndexCompare(indexPtr1, indexPtr2) <= 0);

    if (indexPtr1->priv.linePtr == indexPtr2->priv.linePtr) {
        return TkTextIndexGetByteIndex(indexPtr2) - TkTextIndexGetByteIndex(indexPtr1);
    }

    /*
     * indexPtr2 is on a line strictly after the line containing indexPtr1.
     * Add up:
     *   bytes between indexPtr1 and end of its line
     *   bytes in lines strictly between indexPtr1 and indexPtr2
     *   bytes between start of the indexPtr2 line and indexPtr2
     */

    linePtr = indexPtr1->priv.linePtr;
    byteCount = linePtr->size - TkTextIndexGetByteIndex(indexPtr1);
    byteCount += TkTextIndexGetByteIndex(indexPtr2);
    byteCount += TkBTreeCountSize(indexPtr1->tree, NULL, linePtr->nextPtr, indexPtr2->priv.linePtr);
    return byteCount;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexGetChar --
 *
 *	Return the character at given index.
 *
 * Results:
 *	The character at given index.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

Tcl_UniChar
TkTextIndexGetChar(

    const TkTextIndex *indexPtr)/* Index describing location of character. */
{
    TkTextSegment *segPtr;
    Tcl_Size byteOffset;
    const char *s;

    segPtr = TkTextIndexGetContentSegment(indexPtr, &byteOffset);
    s = segPtr->body.chars + byteOffset;


    { /* local scope */
	/*
	 * Proper implementation for UTF-8 strings:
	 */

	Tcl_UniChar ch;
	Tcl_UtfToUniChar(s, &ch);
	return ch;
    }


    return 0; /* never reached */
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCount --
 *
 *	Given an ordered pair of indices in a text widget, this function
 *	counts how many characters (not bytes) are between the two indices.
 *
 *	It is illegal to call this function with unordered indices.
 *
 *	Note that 'textPtr' is only used if we need to check for elided
 *	attributes, i.e. if type is COUNT_DISPLAY_INDICES or
 *	COUNT_DISPLAY_CHARS.
 *
 *	NOTE: here COUNT_INDICES is also counting chars in text segments.
 *
 * Results:
 *	The number of characters in the given range, which meet the
 *	appropriate 'type' attributes.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

unsigned
TkTextIndexCount(
    const TkText *textPtr,	/* Overall information about text widget. */
    const TkTextIndex *indexPtr1,
				/* Index describing location of character from which to count. */

    const TkTextIndex *indexPtr2,
				/* Index describing location of last character at which to stop
				 * the count. */
    TkTextCountType type)	/* The kind of indices to count. */
{
    TkTextLine *linePtr;
    TkTextIndex index;
    TkTextSegment *segPtr, *lastPtr;

    Tcl_Size byteOffset, maxBytes;
    unsigned count;
    int checkElided;

    assert(textPtr);
    assert(TkTextIndexCompare(indexPtr1, indexPtr2) <= 0);

    checkElided = !!(type & COUNT_DISPLAY) && TkBTreeHaveElidedSegments(textPtr->sharedTextPtr);
    index = *indexPtr1;

    if (checkElided
	    && TkTextIsElided(&index)
	    && (!TkTextSkipElidedRegion(&index) || TkTextIndexCompare(&index, indexPtr2) >= 0)) {
	return 0;
    }

    /*
     * Find seg that contains src index, and remember how many bytes not to count in the given segment.

     */

    segPtr = TkTextIndexGetContentSegment(&index, &byteOffset);
    lastPtr = TkTextIndexGetContentSegment(indexPtr2, &maxBytes);
    linePtr = index.priv.linePtr;
    count = 0;

    if (byteOffset > 0) {
	if (segPtr->tagInfoPtr) {
	    if (segPtr->typePtr == &tkTextCharType) {
		if (type & (COUNT_INDICES|COUNT_TEXT)) {
		    count += Tcl_NumUtfChars(segPtr->body.chars + byteOffset,
			    (segPtr == lastPtr ? maxBytes : segPtr->size) - byteOffset);
		}
	    } else if (segPtr->typePtr == &tkTextHyphenType) {
		if (type & (COUNT_HYPHENS|COUNT_INDICES)) {
		    assert(segPtr->size == 1);
		    count += 1;
		}
	    } else if (type & COUNT_INDICES) {
		assert(segPtr->size == 1);
		count += 1;
	    }
	}
	if (segPtr == lastPtr) {
	    return count;
	}
	segPtr = segPtr->nextPtr;
    }

    if (maxBytes > 0 && (!checkElided || !TkTextSegmentIsElided(textPtr, lastPtr))) {
	if (lastPtr->typePtr == &tkTextCharType) {
	    if (type & (COUNT_TEXT|COUNT_INDICES)) {
		count += Tcl_NumUtfChars(lastPtr->body.chars, maxBytes);
	    }
	} else if (lastPtr->typePtr == &tkTextHyphenType) {
	    if (type & (COUNT_HYPHENS|COUNT_INDICES)) {
		assert(lastPtr->size == 1);
		count += 1;
	    }
	} else if (type & COUNT_INDICES) {
	    assert(lastPtr->size == 1);
	    count += 1;
	}
    }

    while (1) {
	/*
	 * Go through each segment in line adding up the number of characters.
	 */

	for ( ; segPtr; segPtr = segPtr->nextPtr) {





	    if (segPtr == lastPtr) {




		return count;





	    }

	    if (segPtr->tagInfoPtr) {




		if (segPtr->typePtr == &tkTextCharType) {






		    if (type & (COUNT_TEXT|COUNT_INDICES)) {



			count += CountCharsInSeg(segPtr);




		    }









		} else if (segPtr->typePtr == &tkTextHyphenType) {






		    if (type & (COUNT_HYPHENS|COUNT_INDICES)) {
			count += CountCharsInSeg(segPtr);

		    }




		} else if (type & COUNT_INDICES) {

		    assert(segPtr->size == 1);



		    count += 1;



		}


	    } else if (checkElided && segPtr->typePtr == &tkTextBranchType) {


		TkTextIndexSetSegment(&index, segPtr = segPtr->body.branch.nextPtr);
		if (TkTextIndexCompare(&index, indexPtr2) >= 0) {
		    return count;






		}


		linePtr = TkTextIndexGetLine(&index);
	    }




	}


















	/*
	 * Go to the next line.

	 */

	linePtr = TkBTreeNextLine(textPtr, linePtr);
	assert(linePtr);


	segPtr = linePtr->segPtr;
    }






    return 0; /* never reached */
}

/*
 *---------------------------------------------------------------------------
 *
 * TkrTextIndexBackBytes --
 *
 *	Given an index for a text widget, this function creates a new index
 *	that points "count" bytes earlier than the source index.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" bytes before
 *	srcPtr, or to the first character in the TkText if there aren't
 *	"count" bytes earlier than srcPtr.
 *
 *	Returns 1 if we couldn't use all of 'byteCount' because we have run
 *	into the beginning or end of the text, and zero otherwise.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

/*
 * NOTE: This function has external linkage, so we cannot change the return
 * type to 'int'.
 */

int
TkrTextIndexBackBytes(
    const TkText *textPtr,	/* Overall information about text widget, can be NULL. */
    const TkTextIndex *srcPtr,	/* Source index. */
    Tcl_Size byteCount,		/* How many bytes backward to move. May be negative. */

    TkTextIndex *dstPtr)	/* Destination index: gets modified. */
{
    TkTextLine *linePtr;
    Tcl_Size byteIndex;

    if (byteCount == 0) {
	if (dstPtr != srcPtr) {
	    *dstPtr = *srcPtr;
	}
	return 0;
    }

    if (byteCount < 0) {
	return TkrTextIndexForwBytes(textPtr, srcPtr, -byteCount, dstPtr);
    }

    if (dstPtr != srcPtr) {
	*dstPtr = *srcPtr;
    }
    byteIndex = TkTextIndexGetByteIndex(dstPtr);
    linePtr = TkTextIndexGetLine(dstPtr);

    if (textPtr
	    && linePtr == textPtr->startMarker->sectionPtr->linePtr
	    && textPtr->startMarker != textPtr->sharedTextPtr->startMarker) {
	/*



	 * Special case: this is the first line, and we have to consider the start marker.
	 */

	if ((byteIndex -= byteCount) < SegToIndex(linePtr, textPtr->startMarker)) {
	    TkTextIndexSetupToStartOfText(dstPtr, (TkText *) textPtr, textPtr->sharedTextPtr->tree);
	    return 1;
	}

	TkTextIndexSetByteIndex(dstPtr, byteIndex);
	return 0;
    }

    if (byteCount > byteIndex + 1) {
	int rc;
	DEBUG(TkTextIndex index = *srcPtr);
	rc = TkBTreeMoveBackward(dstPtr, byteCount);
	assert(!rc || (int) TkTextIndexCountBytes(dstPtr, &index) == byteCount);
	return rc ? 0 : 1;
    }

    if ((byteIndex -= byteCount) >= 0) {
	TkTextIndexSetByteIndex(dstPtr, byteIndex);
	return 0;
    }

    /*

     * Move back one line in the text. If we run off the beginning
     * then just return the first character in the text widget.
     */


    if (!(linePtr = TkBTreePrevLine(textPtr, linePtr))) {
	TkTextIndexSetToStartOfLine(dstPtr);
	return 1;
    }

    TkTextIndexSetToLastChar2(dstPtr, linePtr);
    return 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexBackChars --
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
 *	_after_ the first acceptable index which is encountered.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" items before
 *	srcPtr, or to the first index in the window if there aren't sufficient
 *	items earlier than srcPtr.
 *



 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TkTextIndexBackChars(
    const TkText *textPtr,	/* Overall information about text widget. */
    const TkTextIndex *srcPtr,	/* Source index. */
    int charCount,		/* How many characters backward to move. May
				 * be negative. */
    TkTextIndex *dstPtr,	/* Destination index: gets modified. */
    TkTextCountType type)	/* The type of item to count */
{

    TkTextSegment *segPtr, *oldPtr;

    TkTextElideInfo *infoPtr = NULL;
    int lineIndex, segSize;
    const char *p, *start, *end;



    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);

    if (charCount < 0) {
	TkTextIndexForwChars(textPtr, srcPtr, -charCount, dstPtr, type);
	return;
    }
    if (checkElided) {
	infoPtr = (TkTextElideInfo *)ckalloc(sizeof(TkTextElideInfo));
	elide = TkTextIsElided(textPtr, srcPtr, infoPtr);
    }

    *dstPtr = *srcPtr;


    /*
     * Find offset within seg that contains byteIndex. Move backward specified
     * number of chars.

     */




    lineIndex = -1;


    segSize = dstPtr->byteIndex;

    if (checkElided) {
	segPtr = infoPtr->segPtr;
	segSize -= infoPtr->segOffset;
    } else {
	TkTextLine *linePtr = dstPtr->linePtr;
	for (segPtr = linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
	    if (segPtr == NULL) {
		/*
		 * Two logical lines merged into one display line through
		 * eliding of a newline.

		 */



		linePtr = TkBTreeNextLine(NULL, linePtr);
		segPtr = linePtr->segPtr;


	    }
	    if (segSize <= (int)segPtr->size) {
		break;
	    }
	    segSize -= segPtr->size;
	}
    }









    /*
     * Now segPtr points to the segment containing the starting index.
     */




    while (1) {
	/*
	 * If we do need to pay attention to the visibility of
	 * characters/indices, check that first. If the current segment isn't
	 * visible, then we simply continue the loop.
	 */

	if (checkElided && ((segPtr->typePtr == &tkTextToggleOffType)
		|| (segPtr->typePtr == &tkTextToggleOnType))) {
	    TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;

	    /*
	     * The elide state only changes if this tag is either the current
	     * highest priority tag (and is therefore being toggled off), or
	     * it's a new tag with higher priority.
	     */

	    if (tagPtr->elideString != NULL) {
		infoPtr->tagCnts[tagPtr->priority]++;
		if (infoPtr->tagCnts[tagPtr->priority] & 1) {
		    infoPtr->tagPtrs[tagPtr->priority] = tagPtr;

		}
		if (tagPtr->priority >= infoPtr->elidePriority) {
		    if (segPtr->typePtr == &tkTextToggleOnType) {
			/*
			 * If it is being toggled on, and it has an elide
			 * string, it must actually be the current highest
			 * priority tag, so this check is redundant:
			 */

			if (tagPtr->priority != infoPtr->elidePriority) {
			    Tcl_Panic("Bad tag priority being toggled on");
			}

			/*
			 * Find previous elide tag, if any (if not then elide
			 * will be zero, of course).
			 */

			elide = 0;
			while (--infoPtr->elidePriority > 0) {
			    if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) {
				elide = infoPtr->tagPtrs[
					infoPtr->elidePriority]->elide;
				break;
			    }
			}
		    } else {
			elide = tagPtr->elide;
			infoPtr->elidePriority = tagPtr->priority;
		    }
		}
	    }
	}

	if (!elide) {
	    if (segPtr->typePtr == &tkTextCharType) {
		start = segPtr->body.chars;
		end = segPtr->body.chars + segSize;
		for (p = end; ; p = TkUtfPrev(p, start)) {
		    if (charCount == 0) {
			dstPtr->byteIndex -= (end - p);
			goto backwardCharDone;
		    }
		    if (p == start) {
			break;
		    }




		    charCount--;
		}
	    } else {




		if (type & COUNT_INDICES) {

		    if (charCount <= segSize) {
			dstPtr->byteIndex -= charCount;


			goto backwardCharDone;
		    }
		    charCount -= segSize;
		}




	    }





	}
	dstPtr->byteIndex -= segSize;

	/*
	 * Move back into previous segment.
	 */

	oldPtr = segPtr;
	segPtr = dstPtr->linePtr->segPtr;
	if (segPtr != oldPtr) {
	    for ( ; segPtr->nextPtr != oldPtr; segPtr = segPtr->nextPtr) {
		/* Empty body. */
	    }
	    segSize = segPtr->size;
	    continue;
	}

	/*
	 * Move back to previous line.
	 */

	if (lineIndex < 0) {
	    lineIndex = TkBTreeLinesTo(textPtr, dstPtr->linePtr);
	}
	if (lineIndex == 0) {

	    dstPtr->byteIndex = 0;
	    goto backwardCharDone;
	}
	lineIndex--;
	dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, textPtr, lineIndex);

	/*
	 * Compute the length of the line and add that to dstPtr->byteIndex.
	 */

	oldPtr = dstPtr->linePtr->segPtr;
	for (segPtr = oldPtr; segPtr != NULL; segPtr = segPtr->nextPtr) {
	    dstPtr->byteIndex += segPtr->size;
	    oldPtr = segPtr;
	}
	segPtr = oldPtr;
	segSize = segPtr->size;
    }

  backwardCharDone:
    if (infoPtr != NULL) {
	TkTextFreeElideInfo(infoPtr);

	ckfree(infoPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * StartEnd --
 *







>
>
>






|

|

|
<



>
|
>
|
|
|
>
>
>
|
|


|
<

|
|
|


|
>
|
|
<
|
>
|
>
>
>

|
>
|
<

|
|
|
<
|
<
<
|
<
<
>
|

>
>
|
|
>
>

|
<
|
<
|
|
>
>
>

>
>
>
>
>



>
>
>








|
|
|
|
<
|
<
<
<

<
<
|
<
>
|
|
|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
|
|
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
|





>
>
>
>
|
|
|
>
>
>
>
|
>
|
|
>
>
|
|
|
|
>
>
>
>

>
>
>
>
>

<





|
<
<
<
<
<
<
<
<
<
|
|
|

|
|
|
|
>
|
<
<
|
<
|
<
|
<
|
<
<
<
<
|
<




|
<
>
|
<







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
 *	_after_ the first acceptable index which is encountered.
 *
 * Results:
 *	*dstPtr is modified to refer to the character "count" items before
 *	srcPtr, or to the first index in the window if there aren't sufficient
 *	items earlier than srcPtr.
 *
 *	This function returns whether the resulting index is different from
 *	source index.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexBackChars(
    const TkText *textPtr,	/* Overall information about text widget, can be NULL. */
    const TkTextIndex *srcPtr,	/* Source index. */
    Tcl_Size charCount,		/* How many characters backward to move. May be negative. */

    TkTextIndex *dstPtr,	/* Destination index: gets modified. */
    TkTextCountType type)	/* The type of item to count */
{
    TkSharedText *sharedTextPtr;
    TkTextSegment *segPtr;
    TkTextSegment *startPtr;
    TkTextLine *linePtr;
    Tcl_Size segSize;
    int checkElided;
    int trimmed;
    int skipSpaces;
    Tcl_Size byteIndex;

    assert(textPtr || !(type & COUNT_DISPLAY));

    if (charCount < 0) {
	return TkTextIndexForwChars(textPtr, srcPtr, -charCount, dstPtr, type);

    }

    if (dstPtr != srcPtr) {
	*dstPtr = *srcPtr;
    }

    if (charCount == 0) {
	return 0;
    }


    sharedTextPtr = TkTextIndexGetShared(srcPtr);
    checkElided = !!(type & COUNT_DISPLAY) && TkBTreeHaveElidedSegments(textPtr->sharedTextPtr);

    if (checkElided && TkTextIsElided(dstPtr) && !TkTextSkipElidedRegion(dstPtr)) {
	return 0;
    }

    if (TkTextIndexIsStartOfLine(dstPtr) && !TkBTreePrevLine(textPtr, dstPtr->priv.linePtr)) {
	return 0;
    }


    if (textPtr && textPtr->endMarker != sharedTextPtr->endMarker) {
	linePtr = TkBTreeGetLastLine(textPtr);


	if (dstPtr->priv.linePtr == linePtr && linePtr != textPtr->endMarker->sectionPtr->linePtr) {


	    /*


	     * Special case: we are at start of last line, but this is not the end line.
	     */

	    if (--charCount == 0) {
		byteIndex = TkTextSegToIndex(textPtr->endMarker);
		dstPtr->priv.linePtr = textPtr->endMarker->sectionPtr->linePtr;
		dstPtr->priv.segPtr = NULL;
		dstPtr->priv.lineNo = dstPtr->priv.lineNoRel = -1;
		goto backwardCharDone;
	    }
	    TkTextIndexSetSegment(dstPtr, textPtr->endMarker);

	}

    }

    /*
     * Move backward specified number of chars.
     */

    segPtr = TkTextIndexGetFirstSegment(dstPtr, &segSize);
    startPtr = textPtr ? textPtr->startMarker : sharedTextPtr->startMarker;
    byteIndex = TkTextIndexGetByteIndex(dstPtr);
    dstPtr->priv.segPtr = NULL;

    /*
     * Now segPtr points to the segment containing the starting index.
     */

    trimmed = textPtr && textPtr->spaceMode == TEXT_SPACEMODE_TRIM && !!(type & COUNT_DISPLAY);
    skipSpaces = 0;

    while (1) {
	/*
	 * If we do need to pay attention to the visibility of
	 * characters/indices, check that first. If the current segment isn't
	 * visible, then we simply continue the loop.
	 */

	if (segPtr->tagInfoPtr) {
	    if (segPtr->typePtr == &tkTextCharType) {
		const char *start = segPtr->body.chars;
		const char *end = segPtr->body.chars + segSize;

		const char *p = end;






		while (1) {

		    const char *q;

		    if (charCount <= 0) {
			if (skipSpaces) {





			    while (p > start && p[-1] == ' ') {



				--p;




			    }
			    if (p == start) {




				break;
			    }
			}














			byteIndex -= (end - p);
			goto backwardCharDone;
		    }
		    if (p == start) {
			break;
		    }
		    p = Tcl_UtfPrev(q = p, start);
		    if (*p == ' ') {
			if (!skipSpaces) {
			    skipSpaces = trimmed;
			    charCount -= 1;
			}
		    } else {
			skipSpaces = trimmed && *p == '\n';
			charCount -= (type & COUNT_INDICES) ? q - p : 1;
		    }
		}
	    } else if (type & COUNT_INDICES) {
		assert(segPtr->size <= 1);
		if (charCount <= segSize) {
		    byteIndex -= charCount;
		    dstPtr->priv.segPtr = segPtr;
		    dstPtr->priv.isCharSegment = 0;
		    goto backwardCharDone;
		}
		charCount -= segSize;
	    }
	} else if (checkElided && segPtr->typePtr == &tkTextLinkType) {
	    TkTextIndexSetSegment(dstPtr, segPtr = segPtr->body.link.prevPtr);
	    if (TkTextIndexRestrictToStartRange(dstPtr) <= 0) {
		return 1;
	    }
	    TkTextIndexToByteIndex(dstPtr);
	    byteIndex = TkTextIndexGetByteIndex(dstPtr);
	} else if (segPtr == startPtr) {
	    TkTextIndexSetSegment(dstPtr, segPtr = startPtr);
	    return 1;
	}


	/*
	 * Move back into previous segment.
	 */

	if (!(segPtr = segPtr->prevPtr)) {









	    /*
	     * Move back to previous line
	     */

	    linePtr = TkBTreePrevLine(textPtr, dstPtr->priv.linePtr);
	    assert(linePtr);

	    dstPtr->priv.linePtr = linePtr;
	    dstPtr->priv.lineNo = dstPtr->priv.lineNoRel = -1;
	    byteIndex = linePtr->size;


	    segPtr = linePtr->lastPtr;

	} else {

	    byteIndex -= segSize;

	}






	segSize = segPtr->size;
    }

  backwardCharDone:
    dstPtr->priv.byteIndex = byteIndex;

    dstPtr->stateEpoch = TkBTreeEpoch(dstPtr->tree);
    return 1;

}

/*
 *----------------------------------------------------------------------
 *
 * StartEnd --
 *
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
 *
 *----------------------------------------------------------------------
 */

static const char *
StartEnd(
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* String to parse for additional info about
				 * modifier (count and units). Points to first
				 * character of modifier word. */
    TkTextIndex *indexPtr)	/* Index to modify based on string. */
{
    const char *p;
    size_t length;
    TkTextSegment *segPtr;
    int modifier;




    /*
     * Find the end of the modifier word.
     */

    for (p = string; isalnum(UCHAR(*p)); p++) {
	/* Empty loop body. */
    }


    length = p-string;
    if ((*string == 'd') &&
	    (strncmp(string, "display", (length > 7 ? 7 : length)) == 0)) {
	modifier = TKINDEX_DISPLAY;

	if (length > 7) {
	    p -= (length - 7);
	}


    } else if ((*string == 'a') &&
	    (strncmp(string, "any", (length > 3 ? 3 : length)) == 0)) {
	modifier = TKINDEX_ANY;

	if (length > 3) {
	    p -= (length - 3);
	}

    } else {
	modifier = TKINDEX_NONE;
    }

    /*
     * If we had a modifier, which we interpreted ok, so now forward to the
     * actual units.
     */

    if (modifier != TKINDEX_NONE) {
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	string = p;
	while ((*p!='\0') && !isspace(UCHAR(*p)) && (*p!='+') && (*p!='-')) {
	    p++;
	}
	length = p - string;
    }

    if ((*string == 'l') && (strncmp(string, "lineend", length) == 0)
	    && (length >= 5)) {





	if (modifier == TKINDEX_DISPLAY) {
	    TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, NULL);
	} else {
	    indexPtr->byteIndex = 0;
	    for (segPtr = indexPtr->linePtr->segPtr; segPtr != NULL;
		    segPtr = segPtr->nextPtr) {
		indexPtr->byteIndex += segPtr->size;
	    }

	    /*
	     * We know '\n' is encoded with a single byte index.
	     */

	    indexPtr->byteIndex -= sizeof(char);
	}


    } else if ((*string == 'l') && (strncmp(string, "linestart", length) == 0)
	    && (length >= 5)) {
	if (modifier == TKINDEX_DISPLAY) {
	    TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
	} else {
	    indexPtr->byteIndex = 0;
	}








    } else if ((*string == 'w') && (strncmp(string, "wordend", length) == 0)
	    && (length >= 5)) {
	int firstChar = 1;
	TkSizeT offset;

	/*
	 * If the current character isn't part of a word then just move
	 * forward one character. Otherwise move forward until finding a
	 * character that isn't part of a word and stop there.
	 */

	if (modifier == TKINDEX_DISPLAY) {
	    TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,
		    COUNT_DISPLAY_INDICES);
	}
	segPtr = TkTextIndexToSeg(indexPtr, &offset);

	while (1) {
	    int chSize = 1;

	    if (segPtr->typePtr == &tkTextCharType) {

		int ch;






		chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch);
		if (!Tcl_UniCharIsWordChar(ch)) {
		    break;
		}
		firstChar = 0;
	    }
	    offset += chSize;
	    indexPtr->byteIndex += chSize;
	    if (offset >= segPtr->size) {

		segPtr = TkTextIndexToSeg(indexPtr, &offset);


	    }
	}


	if (firstChar) {
	    if (modifier == TKINDEX_DISPLAY) {
		TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
			COUNT_DISPLAY_INDICES);
	    } else {
		TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr,
			COUNT_INDICES);
	    }

	}


    } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0)
	    && (length >= 5)) {
	int firstChar = 1;
	TkSizeT offset;

	if (modifier == TKINDEX_DISPLAY) {



	    TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,
		    COUNT_DISPLAY_INDICES);
	}

	/*
	 * Starting with the current character, look for one that's not part
	 * of a word and keep moving backward until you find one. Then if the
	 * character found wasn't the first one, move forward again one
	 * position.
	 */

	segPtr = TkTextIndexToSeg(indexPtr, &offset);

	while (1) {
	    int chSize = 1;

	    if (segPtr->typePtr == &tkTextCharType) {






		int ch;
		TkUtfToUniChar(segPtr->body.chars + offset, &ch);

		if (!Tcl_UniCharIsWordChar(ch)) {
		    break;
		}
		if (offset + 1 > 1) {
		    chSize = (segPtr->body.chars + offset
			    - TkUtfPrev(segPtr->body.chars + offset,
			    segPtr->body.chars));
		}
		firstChar = 0;
	    }
            if (offset == 0) {
                if (modifier == TKINDEX_DISPLAY) {
                    TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr,
                        COUNT_DISPLAY_INDICES);
                } else {
                    TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr,
                        COUNT_INDICES);
                }
            } else {
                indexPtr->byteIndex -= chSize;


            }

            offset -= chSize;
	    if ((int)offset < 0) {
		if (indexPtr->byteIndex == 0) {
		    goto done;
		}

		segPtr = TkTextIndexToSeg(indexPtr, &offset);
	    }
	}



	if (!firstChar) {
	    if (modifier == TKINDEX_DISPLAY) {
		TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
			COUNT_DISPLAY_INDICES);
	    } else {
		TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr,
			COUNT_INDICES);
	    }

	}
    } else {

	return NULL;
    }

  done:
    return p;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:

 */







|
<
|





|
>
>
>





|


>

|
|
|
|
>
|
|
|
>
>
|
|
|
>
|
|
|
>
|
<



|
<




|


|
|




<
|
>
>
>
>
>
|
|
|
|
<
<
<
|
|
<
<
<
|
<
<
>
>
|
<
|
|
|
|
|
>
>
>
>
>
>
>
>
|
<
|
|

|
|
|
|
|

|
|
<
|
|
>
|
|

|
>
|
>
>
>

>
>
|
|
|
|
|
|
|
|
|
>
|
>
>
|
|
>
>
|
<
|
<
<
<
<
|
>
|
>
>
|
<
|
|

|
>
>
>
|
<
|

|
|
|
|
|
|

|
>
|
|

|
>
>

>
>
>
|
|
>
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
|
>
>
|
>
|
<
|
<
|
>
|
|
|

>
>
|
<
|
<
<
<
<
|
>
|
|
>
|
|
|
|
|








>

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
 *
 *----------------------------------------------------------------------
 */

static const char *
StartEnd(
    TkText *textPtr,		/* Information about text widget. */
    const char *string,		/* String to parse for additional info about modifier (count and units).

    				 * Points to first character of modifier word. */
    TkTextIndex *indexPtr)	/* Index to modify based on string. */
{
    const char *p;
    size_t length;
    TkTextSegment *segPtr;
    int modifier = TKINDEX_NONE;
    int mode = COUNT_INDICES;

    assert(textPtr);

    /*
     * Find the end of the modifier word.
     */

    for (p = string; isalnum(UCHAR(*p)); ++p) {
	/* Empty loop body. */
    }
    length = p - string;

    switch (string[0]) {
	case 'd':
	    if (strncmp(string, "display", MIN(length, 7u)) == 0) {
		modifier = TKINDEX_DISPLAY;
		mode = COUNT_DISPLAY_INDICES;
		if (length > 7) {
		    p -= (length - 7);
		}
	    }
	    break;
	case 'a':
	    if (strncmp(string, "any", MIN(length, 3u)) == 0) {
		modifier = TKINDEX_CHAR;
		mode = COUNT_CHARS;
		if (length > 3) {
		    p -= (length - 3);
		}
	    }
	    break;

    }

    /*
     * If we had a modifier, which we interpreted ok, so now forward to the actual units.

     */

    if (modifier != TKINDEX_NONE) {
	while (isspace(UCHAR(*p))) {
	    ++p;
	}
	string = p;
	while (*p && !isspace(UCHAR(*p)) && *p != '+' && *p != '-') {
	    ++p;
	}
	length = p - string;
    }


    if (length >= 5) {
	switch (string[0]) {
	case 'l':
	    switch (string[4]) {
	    case 'e':
		if (strncmp(string, "lineend", length) == 0) {
		    if (modifier == TKINDEX_DISPLAY) {
			TkTextFindDisplayLineStartEnd(textPtr, indexPtr, DISP_LINE_END);
		    } else {
			TkTextIndexSetToLastChar(indexPtr);



		    }
		    return p;



		}


		break;
	    case 's':
		if (strncmp(string, "linestart", length) == 0) {

		    if (modifier == TKINDEX_DISPLAY) {
			TkTextFindDisplayLineStartEnd(textPtr, indexPtr, DISP_LINE_START);
		    } else {
			TkTextIndexSetToStartOfLine(indexPtr);
		    }
		    return p;
		}
		break;
	    }
	    break;
	case 'w':
	    switch (string[4]) {
	    case 'e':
		if (strncmp(string, "wordend", length) == 0) {

		    Tcl_Size firstChar = 1;
		    Tcl_Size offset;

		    /*
		     * If the current character isn't part of a word then just move
		     * forward one character. Otherwise move forward until finding a
		     * character that isn't part of a word and stop there.
		     */

		    if (modifier == TKINDEX_DISPLAY) {
			TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, COUNT_DISPLAY_INDICES);

		    }
		    segPtr = TkTextIndexGetContentSegment(indexPtr, &offset);

		    while (1) {
			int chSize = 1;

			if (segPtr->typePtr == &tkTextCharType) {
			    const char *s = segPtr->body.chars + offset;

			    /*
			     * Proper implementation for UTF-8 strings:
			     */

			    Tcl_UniChar ch;
			    chSize = Tcl_UtfToUniChar(s, &ch);

			    if (!Tcl_UniCharIsWordChar(ch)) {
				break;
			    }
			    firstChar = 0;
			}
			offset += chSize;
			indexPtr->priv.byteIndex += chSize;
			if (offset >= segPtr->size) {
			    do {
				segPtr = segPtr->nextPtr;
			    } while (segPtr->size == 0);
			    offset = 0;
			}
		    }
		    indexPtr->priv.segPtr = segPtr;
		    indexPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType;
		    if (firstChar) {

			TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, (TkTextCountType)mode);




		    }
		    return p;
		}
		break;
	    case 's':
		if (strncmp(string, "wordstart", length) == 0) {

		    Tcl_Size firstChar = 1;
		    Tcl_Size offset;

		    if (modifier == TKINDEX_DISPLAY) {
			/*
			 * Skip elided region.
			 */
			TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, COUNT_DISPLAY_INDICES);

		    }

		    /*
		     * Starting with the current character, look for one that's not part
		     * of a word and keep moving backward until you find one. Then if the
		     * character found wasn't the first one, move forward again one
		     * position.
		     */

		    segPtr = TkTextIndexGetContentSegment(indexPtr, &offset);

		    while (1) {
			int chSize = 1;

			if (segPtr->typePtr == &tkTextCharType) {
			    Tcl_UniChar ch;
			    const char *q = segPtr->body.chars + offset;

			    /*
			     * Proper implementation for UTF-8 strings:
			     */

			    Tcl_UtfToUniChar(q, &ch);

			    if (!Tcl_UniCharIsWordChar(ch)) {
				break;
			    }
			    if (offset > 0) {
				const char *prevPtr;
				prevPtr = Tcl_UtfPrev(segPtr->body.chars + offset, segPtr->body.chars);
				chSize = segPtr->body.chars + offset - prevPtr;
			    }
			    firstChar = 0;
			}
			if (offset == 0) {

			    if (indexPtr->priv.byteIndex == 0) {






				indexPtr->priv.segPtr = segPtr;
				indexPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType;
				return p;
			    }
			    TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr, (TkTextCountType)mode);
			} else {

			    indexPtr->priv.byteIndex -= chSize;

			}
			if ((offset -= chSize) < 0) {
			    segPtr = TkTextIndexGetContentSegment(indexPtr, &offset);
			}
		    }

		    indexPtr->priv.segPtr = segPtr;
		    indexPtr->priv.isCharSegment = segPtr->typePtr == &tkTextCharType;
		    if (!firstChar) {

			TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, (TkTextCountType)mode);




		    }
		    return p;
		}
		break;
	    }
	    break;
	}
    }

    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 * vi:set ts=8 sw=4:
 */

Added generic/tkTextLineBreak.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
/*
 * tkTextLineBreak.c --
 *
 *	This module provides line break computation for line wrapping.
 *	It uses the library "libunibreak" (from Wu Yongwei) for the
 *	computation, but only if available (currently only UNIX), and if
 *	the language support is enabled, otherwise our own line break
 *	algorithm is used (it's a simplified version of the recommendation
 *	at http://www.unicode.org/reports/tr14/tr14-26.html).
 *
 *	The alternative is the use of ICU library (http://site.icu-project.org/),
 *	instead of libunibreak, but this would require to support a very
 *	complex interface of a dynamic load library, with other words, we
 *	would need dozens of functions pointers. This is not really a drawback,
 *	and probably the ICU library is the better choice, but I think that a
 *	change to the ICU library is reasonable only if the Tcl/Tk developer team
 *	is deciding to use this library also for complete Unicode support (character
 *	conversion, for instance).
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkText.h"

#include <ctype.h>
#include <assert.h>

#ifndef MAX
# define MAX(a,b) (((int) a) < ((int) b) ? b : a)
#endif


typedef void (*ComputeBreakLocationsFunc)(
    const unsigned char *text, size_t len, const char *lang, char *brks);

static void ComputeBreakLocations(
    const unsigned char *text, size_t len, const char *lang, char *brks);

static ComputeBreakLocationsFunc libLinebreakFunc = ComputeBreakLocations;

/*
 *----------------------------------------------------------------------
 *
 * GetLineBreakFunc --
 *
 *	Return the appropriate line break function. If argument 'lang'
 *	is NULL, then our own line break algorithm will be used (fast,
 *	but a bit simple). If 'lang' is not NULL, then this function
 *	tries to load the library "libunibreak" (currently only UNIX).
 *	If the load succeeds, then set_linebreaks_utf8 will be returned,
 *	otherwise ComputeBreakLocations will be returned.
 *
 *	Note that "libunibreak" has language specific support, but
 *	currently only for zh, ja, and ko. Nethertheless any non-NULL
 *	value for 'lang' tries to use this library.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The "libunibreak" library may be loaded, if available.
 *
 *----------------------------------------------------------------------
 */

#ifdef __UNIX__

static int
LoadFile(
    Tcl_Interp *interp,
    Tcl_Obj *pathPtr,
    Tcl_LoadHandle *handle,
    char const **symbols,
    void **funcs)
{
    return Tcl_LoadFile(interp, pathPtr, symbols, TCL_LOAD_GLOBAL, funcs, handle);
}

static void
LoadLibUnibreak(
    Tcl_Interp *interp)
{
    typedef void *VoidP;
    typedef void (*InitFunc)();

    static char const *Symbols[3] = {
	"init_linebreak",
	"set_linebreaks_utf8",
	NULL
    };

    VoidP Funcs[sizeof(Symbols)/sizeof(Symbols[0])];
    Tcl_LoadHandle handle;
    Tcl_Obj *pathPtr = Tcl_NewStringObj("libunibreak.so.1", TCL_INDEX_NONE);
    int rc;

    Tcl_IncrRefCount(pathPtr);
    rc = LoadFile(interp, pathPtr, &handle, Symbols, Funcs);
    if (rc != TCL_OK) {
	/*
	 * We couldn't find "libunibreak.so.1", so try the predecessor "liblinebreak.so.2".
	 */

	Tcl_ResetResult(interp);
	Tcl_DecrRefCount(pathPtr);
	Tcl_IncrRefCount(pathPtr = Tcl_NewStringObj("liblinebreak.so.2", TCL_INDEX_NONE));
	rc = LoadFile(interp, pathPtr, &handle, Symbols, Funcs);
    }
    Tcl_DecrRefCount(pathPtr);
    if (rc == TCL_OK) {
	((InitFunc)(void *)Funcs[0])();
	libLinebreakFunc = (ComputeBreakLocationsFunc)(void *)Funcs[1];
    } else {
	Tcl_ResetResult(interp);
    }
}

#endif /* __UNIX__ */

static ComputeBreakLocationsFunc
GetLineBreakFunc(
    Tcl_Interp *interp,
    char const *lang)
{
#ifdef __UNIX__
    if (lang) {
	static int loaded = 0;

	if (!loaded) {
	    LoadLibUnibreak(interp);
	}
    }
#else
    (void)interp;
    (void)lang;
#endif
    return libLinebreakFunc;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextComputeBreakLocations --
 *
 *	Compute break locations in UTF-8 text. This function expects
 *	a nul-terminated string (this mean that the character at position
 *	'len' must be NUL). Thus it is also required that the break buffer
 *	'brks' has at least size 'len+1'. If 'lang' is not NULL, then the
 *	external library linunibreak will be used for the line break
 *	computation, but only if this library is loadable, otherwise the
 *	internal algorithm will be used.
 *
 * Results:
 *	The computed break locations. This function returns 'true' if
 *	the external linebreak library has been used for the computation,
 *	otherwise 'false' will be returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkTextComputeBreakLocations(
    Tcl_Interp *interp,
    const char *text,	/* must be nul-terminated */
    unsigned len,	/* without trailing nul byte */
    const char *lang,	/* can be NULL */
    char *brks)
{
    ComputeBreakLocationsFunc func;
    int lastBreakablePos = -1;
    unsigned i;

    assert(text);
    assert(brks);
    assert(text[len] == '\0');
    assert(!lang || (isalpha(lang[0]) && isalpha(lang[1]) && !lang[2]));

    func = GetLineBreakFunc(interp, lang);

    /*
     * The algorithm don't give us a break value for the last character if we do
     * not include the final nul char into the computation.
     */

    len += 1;
    (*func)((const unsigned char *) text, len, lang, brks);
    len -= 1;

    for (i = 0; i < len; ++i) {
	switch (brks[i]) {
	case LINEBREAK_MUSTBREAK:
	    break;
	case LINEBREAK_ALLOWBREAK:
	    if (text[i] == '-') {
		if (brks[i] == LINEBREAK_ALLOWBREAK) {
		    /*
		     * Fix the problem with the contextual hyphen-minus sign, the implementation of
		     * libunibreak has (possibly) forgotten this case.
		     *
		     * The HYPHEN-MINUS (U+002D) needs special context treatment. For simplicity we
		     * will only check whether we have two preceding, and two succeeding letters.
		     * TODO: Is there a better method for the decision?
		     */

		    const char *r = text + i;
		    const char *p, *q, *s;
		    Tcl_UniChar uc;
		    int allow = 0;

		    q = Tcl_UtfPrev(r, text);
		    if (q != r) {
			Tcl_UtfToUniChar(q, &uc);
			if (Tcl_UniCharIsAlpha(uc)) {
			    p = Tcl_UtfPrev(q, text);
			    if (p != q) {
				Tcl_UtfToUniChar(p, &uc);
				if (Tcl_UniCharIsAlpha(uc)) {
				    s = r + 1;
				    s += Tcl_UtfToUniChar(s, &uc);
				    if (Tcl_UniCharIsAlpha(uc)) {
					Tcl_UtfToUniChar(s, &uc);
					if (Tcl_UniCharIsAlpha(uc)) {
					    allow = 1;
					}
				    }
				}
			    }
			}
		    }

		    if (!allow) {
			brks[i] = LINEBREAK_NOBREAK;
		    }
		}
	    } else if (text[i] == '/' && i > 8) {
		/*
		 * Ignore the breaking chance if there is a chance immediately before:
		 * no break inside "c/o", and no break after "http://" in a long line
		 * (a suggestion from Wu Yongwei).
		 */

		if (lastBreakablePos >= (int) i - 2
			|| (i > 40u && lastBreakablePos >= (int) i - 7 && text[i - 1] == '/')) {
		    continue;
		}

		/*
		 * Special rule to treat Unix paths more nicely (a suggestion from Wu Yongwei).
		 */

		if (i < len - 1 && text[i + 1] != ' ' && text[i - 1] == ' ') {
		    lastBreakablePos = i - 1;
		    continue;
		}
	    }
	    lastBreakablePos = i;
	    break;
        case LINEBREAK_INSIDEACHAR:
	    break;
	}
    }

    return func != ComputeBreakLocations;
}

/*
 * The following is implementing the recommendations at
 * http://www.unicode.org/reports/tr14/tr14-26.html, but simplified -
 * no language specific support, not all the rules (especially no
 * combining marks), and mostly restricted to Latin-1 and relevant
 * letters not belonging to specific languages. For a more sophisticated
 * line break algorithm the library "libunibreak" (from Wu Yongwei)
 * should be used.
 */

typedef enum {
    /* Note that CR, LF, and NL will be interpreted as BK, so only BK is used. */
    AI, AL, B2, BA, BB, BK, CL, CP, EX, GL, HY, IN, IS, NS, NU, OP, PO, PR, QU, SP, SY, WJ, ZW
} LBClass;

#define __ AI

/*
 * Changes in table below (different from Unicode recommendation):
 *
 * 0a: CB -> BK	(LINE FEED)
 * 0d: CR -> BK (CARRIAGE RETURN)
 * 0e: XX -> BK (SHIFT OUT)
 * 23: AL -> IN (NUMBER SIGN)
 * 26: AL -> BB (AMPERSAND)
 * 3d: AL -> GL (EQUALS SIGN)
 * 60: CM -> AL (GRAVE ACCENT)
 */

static const char Table_0000[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, BA, BK, BK, BK, BK, BK, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ SP, EX, QU, IN, PR, PO, BB, QU, OP, CP, AL, PR, IS, HY, IS, SY, /* 20 - 2f */
/* 3 */ NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, IS, IS, AL, GL, AL, EX, /* 30 - 3f */
/* 4 */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, /* 40 - 4f */
/* 5 */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, OP, PR, CP, AL, AL, /* 50 - 5f */
/* 6 */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, /* 60 - 6f */
/* 7 */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, OP, BA, CL, AL, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 90 - 9f */
/* a */ GL, OP, PO, PR, PR, PR, AL, AL, AL, AL, __, QU, __, __, AL, AL, /* a0 - af */
/* b */ PO, PR, AL, AL, BB, __, AL, AL, AL, AL, __, __, AL, AL, AL, OP, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

/*
 * Changes in table below (different from Unicode recommendation):
 *
 * e2 80 89: BA -> WJ (THIN SPACE)
 * e2 80 0a: BA -> WJ (HAIR SPACE)
 */

static const char Table_E280[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ BA, BA, BA, BA, BA, BA, BA, GL, BA, __, __, ZW, __, __, __, __, /* 80 - 8f */
/* 9 */ BA, AL, BA, BA, B2, AL, AL, AL, QU, QU, OP, QU, QU, QU, OP, QU, /* 90 - 9f */
/* a */ AL, AL, AL, AL, IN, IN, IN, BA, BK, BK, __, __, __, __, __, GL, /* a0 - af */
/* b */ PO, PO, PO, PO, PO, PO, PO, PO, AL, QU, QU, AL, NS, NS, AL, AL, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E281[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ AL, AL, AL, AL, IS, OP, CL, NS, NS, NS, AL, AL, AL, AL, AL, AL, /* 80 - 8f */
/* 9 */ AL, AL, __, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, __, /* 90 - 9f */
/* a */ WJ, AL, AL, AL, AL, __, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, __, OP, CL, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E282[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, __, __, __, __, __, CL, CL, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 90 - 9f */
/* a */ PR, PR, PR, PR, PR, PR, PR, PO, PR, PR, PR, PR, PR, PR, PR, PR, /* a0 - af */
/* b */ PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E28C[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, OP, CL, OP, CL, __, __, __, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 90 - 9f */
/* a */ __, __, __, __, __, __, __, __, __, OP, CL, __, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E29D[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 90 - 9f */
/* a */ __, __, __, __, __, __, __, __, OP, CL, OP, CL, OP, CL, OP, CL, /* a0 - af */
/* b */ OP, CL, OP, CL, OP, CL, __, __, __, __, __, __, __, __, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E29F[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, OP, CL, __, __, __, __, __, __, __, __, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 90 - 9f */
/* a */ __, __, __, __, __, __, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E2A6[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, OP, /* 80 - 8f */
/* 9 */ CL, OP, CL, OP, CL, OP, CL, OP, CL, __, __, __, __, __, __, __, /* 90 - 9f */
/* a */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E2A7[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, OP, CL, OP, CL, __, __, __, __, /* 90 - 9f */
/* a */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, OP, CL, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E2B8[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ AL, AL, QU, QU, QU, QU, AL, AL, AL, QU, QU, AL, QU, QU, AL, AL, /* 80 - 8f */
/* 9 */ AL, AL, AL, AL, AL, AL, AL, AL, OP, AL, AL, AL, QU, QU, AL, AL, /* 90 - 9f */
/* a */ QU, QU, OP, CL, OP, CL, OP, CL, OP, CL, AL, AL, AL, AL, AL, __, /* a0 - af */
/* b */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, B2, B2, AL, AL, AL, AL, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_E380[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, CL, CL, AL, __, NS, __, __, OP, CL, OP, CL, OP, CL, OP, CL, /* 80 - 8f */
/* 9 */ OP, CL, __, __, OP, CL, OP, CL, OP, CL, OP, CL, NS, OP, CL, CL, /* 90 - 9f */
/* a */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ AL, __, __, __, __, __, __, __, __, __, __, NS, NS, AL, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_EFB8[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 80 - 8f */
/* 9 */ IS, CL, CL, IS, IS, AL, AL, OP, CL, IN, __, __, __, __, __, __, /* 90 - 9f */
/* a */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ AL, AL, AL, AL, AL, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, OP, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_EFB9[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ CL, OP, CL, OP, CL, AL, AL, OP, CL, AL, AL, AL, AL, AL, AL, AL, /* 80 - 8f */
/* 9 */ CL, CL, CL, __, NS, NS, AL, AL, B2, OP, CL, OP, CL, OP, CL, AL, /* 90 - 9f */
/* a */ AL, AL, __, B2, __, __, __, __, AL, PR, PO, AL, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_EFBC[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, AL, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, EX, AL, AL, PR, PO, AL, AL, OP, CL, AL, __, CL, B2, CL, AL, /* 80 - 8f */
/* 9 */ NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NS, NS, __, __, __, EX, /* 90 - 9f */
/* a */ AL, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, OP, AL, CL, __, __, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

static const char Table_EFBD[256] = {
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 0 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 00 - 0f */
/* 1 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 10 - 1f */
/* 2 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 20 - 2f */
/* 3 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 30 - 3f */
/* 4 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 40 - 4f */
/* 5 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 50 - 5f */
/* 6 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 60 - 6f */
/* 7 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 70 - 7f */
/* 8 */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* 80 - 8f */
/* 9 */ __, __, __, __, __, __, __, __, __, __, __, OP, __, CL, __, OP, /* 90 - 9f */
/* a */ CL, CL, OP, CL, CL, AL, __, __, __, __, __, __, __, __, __, __, /* a0 - af */
/* b */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, WJ, /* b0 - bf */
/* c */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* c0 - cf */
/* d */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* d0 - df */
/* e */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* e0 - ef */
/* f */ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, /* f0 - ff */
/*      00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
};

#undef __

#define PROHIBITED	LINEBREAK_NOBREAK
#define DIRECT		LINEBREAK_ALLOWBREAK
#define INDIRECT	((char) (~LINEBREAK_NOBREAK & ~LINEBREAK_ALLOWBREAK & 0x7f))

#define X PROHIBITED	/* B ^ A === B SP* × A */
#define i INDIRECT	/* B % A === B × A and B SP+ ÷ A */
#define _ DIRECT	/* B ÷ A */

/* Note that BK, SP will no be used for lookup. */
static const char BrkPairTable[23][23] = {
/*        AI AL B2 BA BB BK CL CP EX GL HY IN IS NS NU OP PO PR QU SP SY WJ ZW */
/* AI */ { X, X, _, i, _, _, X, X, X, i, i, i, X, i, i, i, _, _, i, _, X, X, X }, /* AI */
/* AL */ { i, i, _, i, _, _, X, X, X, i, i, i, X, i, i, i, _, _, i, _, X, X, X }, /* AL */
/* B2 */ { _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X }, /* B2 */
/* BA */ { _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X }, /* BA */
/* BB */ { i, i, i, i, i, _, X, X, X, _, i, i, X, i, i, i, i, i, i, _, X, X, X }, /* BB */
/* BK */ { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ }, /* BK */
/* CL */ { _, _, _, i, _, _, X, X, X, i, i, _, X, X, _, _, i, i, i, _, X, X, X }, /* CL */
/* CP */ { i, i, _, i, _, _, X, X, X, i, i, _, X, X, i, _, i, i, i, _, X, X, X }, /* CP */
/* EX */ { _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X }, /* EX */
/* GL */ { i, i, i, i, i, _, X, X, X, i, i, i, X, i, i, i, i, i, i, _, X, X, X }, /* GL */
/* HY */ { _, _, _, i, _, _, X, X, X, _, i, _, X, i, i, _, _, _, i, _, X, X, X }, /* HY */
/* IN */ { _, _, _, i, _, _, X, X, X, i, i, i, X, i, _, _, _, _, i, _, X, X, X }, /* IN */
/* IS */ { i, i, _, i, _, _, X, X, X, i, i, _, X, i, i, _, _, _, i, _, X, X, X }, /* IS */
/* NS */ { _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X }, /* NS */
/* NU */ { i, i, _, i, _, _, X, X, X, i, i, i, X, i, i, i, i, i, i, _, X, X, X }, /* NU */
/* OP */ { X, X, X, X, X, _, X, X, X, X, X, X, X, X, X, X, X, X, X, _, X, X, X }, /* OP */
/* PO */ { i, i, _, i, _, _, X, X, X, i, i, _, X, i, i, i, _, _, i, _, X, X, X }, /* PO */
/* PR */ { _, i, _, i, _, _, X, X, X, i, i, _, X, i, i, i, _, _, i, _, X, X, X }, /* PR */
/* QU */ { i, i, i, i, i, _, X, X, X, i, i, i, X, i, i, X, i, i, i, _, X, X, X }, /* QU */
/* SP */ { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ }, /* SP */
/* SY */ { _, _, _, i, _, _, X, X, X, i, i, _, X, i, i, _, _, _, i, _, X, X, X }, /* SY */
/* WJ */ { i, i, i, i, i, _, X, X, X, i, i, i, X, i, i, i, i, i, i, _, X, X, X }, /* WJ */
/* ZW */ { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, X }, /* ZW */
/*        AI AL B2 BA BB BK CL CP EX GL HY IN IS NS NU OP PO PR QU SP SY WJ ZW */
};

#undef _
#undef i
#undef X

/*
 *----------------------------------------------------------------------
 *
 * ComputeBreakLocations --
 *
 *	Compute break locations in UTF-8 text. This function is doing
 *	the same as set_linebreaks_utf8 (from "libunibreak"), but this
 *	function is using a simplified line break algorithm, although
 *	it is following the recommendations at
 *	http://www.unicode.org/reports/tr14/tr14-26.html.
 *
 *	Note that this functions expects that the whole line will be
 *	parsed at once. This interface corresponds to the interface
 *	of the linebreak library. Of course, such a design is a bit
 *	unluckily.
 *
 * Results:
 *	The computed break locations, in 'brks'. This array must be as
 *	large as the input length (specified by 'len').
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ComputeBreakLocations(
    const unsigned char *text,
    size_t len,
    TCL_UNUSED(const char *),
    char *brks)
{
    size_t i;
    size_t nbytes;
    size_t nletters;
    size_t brkIndex;
    LBClass cls;
    LBClass prevCls;

    if (len == 0) {
	return;
    }

    i = 0;
    nletters = 0;
    brkIndex = 0;
    cls = BK;
    prevCls = WJ;
    brks[len - 1] = LINEBREAK_MUSTBREAK;

    while (i < len) {
	unsigned char ch;
	LBClass pcls;

	ch = text[i];

	if (ch < 0x80) {
	    pcls = (LBClass)Table_0000[ch];
	    nbytes = 1;
	} else if ((ch & 0xe0) == 0xc0) {
	    pcls = AI;
	    switch (ch) {
	    case 0xc2:
		switch (UCHAR(text[i + 1])) {
		case 0x85: pcls = BK; break; /* NL */
		case 0xac: pcls = AL; break;
		case 0xad: pcls = BA; break;
		case 0xb1: pcls = AL; break;
		case 0xbb: pcls = QU; break;
		}
		break;
	    case 0xc3:
	    case 0xc4:
	    case 0xc5:
	    case 0xc6:
	    case 0xc7:
	    case 0xc8:
	    case 0xc9:
		ch = text[i + 1];
		if (0x80 <= ch && ch <= 0xbf) {
		    pcls = AL;
		}
		break;
	    case 0xca:
		ch = text[i + 1];
		if (0x80 <= ch && ch <= 0xaf) {
		    pcls = AL;
		}
		break;
	    case 0xcb:
		switch (UCHAR(text[i + 1])) {
		case 0x88: /* fallthru */
		case 0x8c: /* fallthru */
		case 0x9f: pcls = BB; break;
		}
		break;
	    case 0xcd:
		if (UCHAR(text[i + 1]) == 0x8f) {
		    pcls = GL;
		}
		break;
	    case 0xd7:
		if (UCHAR(text[i + 1]) == 0x86) {
		    pcls = EX;
		}
		break;
	    case 0xdf:
		if (UCHAR(text[i + 1]) == 0xb8) {
		    pcls = IS;
		}
		break;
	    }
	    nbytes = 2;
	    brks[i] = LINEBREAK_INSIDEACHAR;
	} else if ((ch & 0xf0) == 0xe0) {
	    pcls = AI;
	    switch (ch) {
		case 0xe2:
		    switch (UCHAR(text[i + 1])) {
		    case 0x80: pcls = (LBClass)Table_E280[UCHAR(text[i + 2])]; break;
		    case 0x81: pcls = (LBClass)Table_E281[UCHAR(text[i + 2])]; break;
		    case 0x82: pcls = (LBClass)Table_E282[UCHAR(text[i + 2])]; break;
		    case 0x8c: pcls = (LBClass)Table_E28C[UCHAR(text[i + 2])]; break;
		    case 0x9d: pcls = (LBClass)Table_E29D[UCHAR(text[i + 2])]; break;
		    case 0x9f: pcls = (LBClass)Table_E29F[UCHAR(text[i + 2])]; break;
		    case 0xa6: pcls = (LBClass)Table_E2A6[UCHAR(text[i + 2])]; break;
		    case 0xa7: pcls = (LBClass)Table_E2A7[UCHAR(text[i + 2])]; break;
		    case 0xb8: pcls = (LBClass)Table_E2B8[UCHAR(text[i + 2])]; break;
		    case 0x84:
			switch (UCHAR(text[i + 2])) {
			    case 0x83: /* fallthru */
			    case 0x89: pcls = PO; break;
			    case 0x96: pcls = PR; break;
			}
			break;
		    case 0x88:
			switch (UCHAR(text[i + 2])) {
			    case 0x92: /* fallthru */
			    case 0x93: pcls = PR; break;
			}
			break;
		    case 0xb9:
			switch (UCHAR(text[i + 2])) {
			    case 0x80: pcls = B2; break;
			    case 0x81: pcls = AL; break;
			    case 0x82: pcls = OP; break;
			}
			break;
		    }
		    break;
		case 0xe3:
		    if (UCHAR(text[i + 1]) == 0x80) {
			pcls = (LBClass)Table_E380[UCHAR(text[i + 2])];
		    }
		    break;
		case 0xef:
		    switch (UCHAR(text[i + 1])) {
		    case 0xb8: pcls = (LBClass)Table_EFB8[UCHAR(text[i + 2])]; break;
		    case 0xb9: pcls = (LBClass)Table_EFB9[UCHAR(text[i + 2])]; break;
		    case 0xbc: pcls = (LBClass)Table_EFBC[UCHAR(text[i + 2])]; break;
		    case 0xbd: pcls = (LBClass)Table_EFBD[UCHAR(text[i + 2])]; break;
		    case 0xb4:
			switch (UCHAR(text[i + 2])) {
			    case 0xbe: pcls = CL; break;
			    case 0xbf: pcls = OP; break;
			}
			break;
		    case 0xbb:
			if (UCHAR(text[i + 2]) == 0xbf) {
			    pcls = WJ; /* ZWNBSP (deprecated word joiner) */
			}
			break;
		    case 0xbf:
			switch (UCHAR(text[i + 2])) {
			    case 0xa0: pcls = PO; break;
			    case 0xa1: /* fallthru */
			    case 0xa5: /* fallthru */
			    case 0xa6: pcls = PR; break;
			}
			break;
		    }
		    break;
	    }
	    nbytes = 3;
	    brks[i + 0] = LINEBREAK_INSIDEACHAR;
	    brks[i + 1] = LINEBREAK_INSIDEACHAR;
	} else if ((ch & 0xf8) == 0xf0) {
	    pcls = AI;
	    nbytes = 4;
	    brks[i + 0] = LINEBREAK_INSIDEACHAR;
	    brks[i + 1] = LINEBREAK_INSIDEACHAR;
	    brks[i + 2] = LINEBREAK_INSIDEACHAR;
	} else {
	    /*
	     * This fallback is required, because the current character conversion
	     * algorithm in Tcl library is producing overlong sequences (a violation
	     * of the UTF-8 standard). This observation has been reported to the
	     * Tcl/Tk team, but the response was ignorance.
	     */

	    unsigned k;
	    const char *p = (const char *) text + i;

	    pcls = AI;
	    nbytes = Tcl_UtfNext(p) - p;
	    for (k = 0; k < nbytes; ++k) {
		brks[i + k] = LINEBREAK_INSIDEACHAR;
	    }
	}

	if (i == 0) {
	    if ((cls = pcls) == SP) {
		/* treat SP at start of input as if it followed a WJ */
		prevCls = cls = WJ;
	    }
	} else {
	    switch (pcls) {
	    case BK:
		brks[i - 1] = LINEBREAK_NOBREAK;
		brks[i] = LINEBREAK_MUSTBREAK;
		prevCls = WJ;
		return;
	    case SP:
		/* handle spaces explicitly; do not update cls */
		if (i > 0) {
		    brks[i - 1] = LINEBREAK_NOBREAK;
		    prevCls = SP;
		} else {
		    prevCls = WJ;
		}
		nletters = 0;
		break;
	    case HY: {
		char brk = BrkPairTable[cls][HY];

	    	/*
		 * The HYPHEN-MINUS (U+002D) needs special context treatment. For simplicity we
		 * will only check whether we have two preceding, and two succeeding letters.
		 * TODO: Is there a better method for the decision?
		 */

		brks[i - 1] = LINEBREAK_NOBREAK;
		cls = pcls;

		if (brk == INDIRECT) {
		    prevCls = pcls;
		} else {
		    prevCls = WJ;

		    if (brk == LINEBREAK_ALLOWBREAK && nletters >= 2) {
			brkIndex = i - 1;
		    }
		}
		nletters = 0;
	    	break;
	    }
	    default: {
		char brk = BrkPairTable[cls][pcls];

		if (brk == INDIRECT) {
		    brk = (prevCls == SP) ? LINEBREAK_ALLOWBREAK : LINEBREAK_NOBREAK;
		    prevCls = pcls;
		} else {
		    prevCls = WJ;
		}
		brks[i - 1] = brk;
		cls = pcls;

		if (pcls == AL) {
		    nletters += 1;

		    if (brkIndex && nletters >= 2) {
			brks[brkIndex] = LINEBREAK_ALLOWBREAK;
			brkIndex = 0;
		    }
		} else {
		    nletters = 0;
		}
		break;
	    }
	    }
	}

	i += nbytes;
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */

Changes to generic/tkTextMark.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
/*
 * 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.

 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
#include "tk3d.h"


/*
 * Macro that determines the size of a mark segment:
 */







#define MSEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextMark))




/*
 * Forward references for functions defined in this file:
 */

static Tcl_Obj *	GetMarkName(TkText *textPtr, TkTextSegment *segPtr);
static void		InsertUndisplayProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr);
static int		MarkDeleteProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr, int treeGone);

static TkTextSegment *	MarkCleanupProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);
static void		MarkCheckProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);
static int		MarkLayoutProc(TkText *textPtr, TkTextIndex *indexPtr,
			    TkTextSegment *segPtr, TkSizeT offset, int maxX,
			    TkSizeT maxChars, int noCharsYet, TkWrapMode wrapMode,
			    TkTextDispChunk *chunkPtr);
static int		MarkFindNext(Tcl_Interp *interp,









			    TkText *textPtr, Tcl_Obj *markName);










static int		MarkFindPrev(Tcl_Interp *interp,


















			    TkText *textPtr, Tcl_Obj *markName);


























































































/*
 * The following structures declare the "mark" segment types. There are
 * actually two types for marks, one with left gravity and one with right
 * gravity. They are identical except for their gravity property.
 */

const Tk_SegType tkTextRightMarkType = {
    "mark",			/* name */

    0,				/* leftGravity */
    NULL,			/* splitProc */
    MarkDeleteProc,		/* deleteProc */
    MarkCleanupProc,		/* cleanupProc */
    NULL,			/* lineChangeProc */
    MarkLayoutProc,		/* layoutProc */
    MarkCheckProc		/* checkProc */

};

const Tk_SegType tkTextLeftMarkType = {
    "mark",			/* name */

    1,				/* leftGravity */
    NULL,			/* splitProc */
    MarkDeleteProc,		/* deleteProc */
    MarkCleanupProc,		/* cleanupProc */
    NULL,			/* lineChangeProc */
    MarkLayoutProc,		/* layoutProc */
    MarkCheckProc		/* checkProc */

};






















































































































































































































































































































/*
 *--------------------------------------------------------------
 *
 * TkTextMarkCmd --
 *
 *	This function is invoked to process the "mark" options of the widget
 *	command for text widgets. See the user documentation for details on
 *	what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */








int
TkTextMarkCmd(
    TkText *textPtr,	/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already
				 * parsed this command enough to know that
				 * objv[1] is "mark". */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *markPtr;
    Tcl_HashSearch search;
    TkTextIndex index;
    const Tk_SegType *newTypePtr;
    int optionIndex;
    static const char *const markOptionStrings[] = {
	"gravity", "names", "next", "previous", "set", "unset", NULL

    };
    enum markOptions {
	MARK_GRAVITY, MARK_NAMES, MARK_NEXT, MARK_PREVIOUS, MARK_SET,
	MARK_UNSET
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], markOptionStrings,
	    sizeof(char *), "mark option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum markOptions) optionIndex) {

























































    case MARK_GRAVITY: {


	char c;























	TkSizeT length;
	const char *str;

	if (objc < 4 || objc > 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
	    return TCL_ERROR;
	}
	str = TkGetStringFromObj(objv[3], &length);
	if (length == 6 && !strcmp(str, "insert")) {
	    markPtr = textPtr->insertMarkPtr;
	} else if (length == 7 && !strcmp(str, "current")) {
	    markPtr = textPtr->currentMarkPtr;
	} else {
	    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, str);
	    if (hPtr == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"there is no mark named \"%s\"", str));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_MARK", str,
			NULL);
		return TCL_ERROR;
	    }
	    markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
	}
	if (objc == 4) {
	    const char *typeStr;

	    if (markPtr->typePtr == &tkTextRightMarkType) {
		typeStr = "right";
	    } else {
		typeStr = "left";
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1));
	    return TCL_OK;
	}
	str = TkGetStringFromObj(objv[4],&length);
	c = str[0];
	if ((c == 'l') && (strncmp(str, "left", length) == 0)) {
	    newTypePtr = &tkTextLeftMarkType;
	} else if ((c == 'r') &&
		(strncmp(str, "right", length) == 0)) {
	    newTypePtr = &tkTextRightMarkType;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad mark gravity \"%s\": must be left or right", str));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_GRAVITY", NULL);
	    return TCL_ERROR;
	}



	TkTextMarkSegToIndex(textPtr, markPtr, &index);



	TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
	markPtr->typePtr = newTypePtr;
	TkBTreeLinkSegment(markPtr, &index);





	break;
    }
    case MARK_NAMES: {



	Tcl_Obj *resultObj;













	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}


	resultObj = Tcl_NewObj();


	Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		"insert", -1));


	Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(

		"current", -1));
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->markTable,

		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {

	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(

		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));


	}



	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    case MARK_NEXT:
















	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}


	return MarkFindNext(interp, textPtr, objv[3]);

    case MARK_PREVIOUS:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index");
	    return TCL_ERROR;
	}
	return MarkFindPrev(interp, textPtr, objv[3]);



















    case MARK_SET:



	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName index");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[4], &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	TkTextSetMark(textPtr, Tcl_GetString(objv[3]), &index);
	return TCL_OK;


    case MARK_UNSET: {

	int i;






	for (i = 3; i < objc; i++) {
	    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable,
		    Tcl_GetString(objv[i]));
	    if (hPtr != NULL) {

		markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);












		/*
		 * Special case not needed with peer widgets.







		 */






		if ((markPtr == textPtr->insertMarkPtr)











			|| (markPtr == textPtr->currentMarkPtr)) {

		    continue;



		}
		TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);



		Tcl_DeleteHashEntry(hPtr);
		ckfree(markPtr);







	    }
	}
	break;
    }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *





































































































































































































































































































































































































































































 * TkTextSetMark --









































































































































































































































































 *
 *	Set a mark to a particular position, creating a new mark if one
 *	doesn't already exist.










 *
 * Results:
 *	The return value is a pointer to the mark that was just set.
 *
 * Side effects:
 *	A new mark is created, or an existing mark is moved.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextSetMark(
    TkText *textPtr,		/* Text widget in which to create mark. */
    const char *name,		/* Name of mark to set. */


    TkTextIndex *indexPtr)	/* Where to set mark. */
{
    Tcl_HashEntry *hPtr = NULL;

    TkTextSegment *markPtr;
    TkTextIndex insertIndex;


    int isNew, widgetSpecific;










    if (!strcmp(name, "insert")) {
	widgetSpecific = 1;
	markPtr = textPtr->insertMarkPtr;
	isNew = (markPtr == NULL ? 1 : 0);






    } else if (!strcmp(name, "current")) {
	widgetSpecific = 2;
	markPtr = textPtr->currentMarkPtr;



	isNew = (markPtr == NULL ? 1 : 0);


    } else {
	widgetSpecific = 0;

	hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->markTable, name,
		&isNew);
	markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    }

    if (!isNew) {





























































	/*
	 * If this is the insertion point that's being moved, be sure to force
	 * a display update at the old position. Also, don't let the insertion
	 * cursor be after the final newline of the file.
	 */

	if (markPtr == textPtr->insertMarkPtr) {
	    TkTextIndex index, index2;
            int nblines;

	    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	    TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);








	    /*
	     * While we wish to redisplay, no heights have changed, so no need
	     * to call TkTextInvalidateLineMetrics.
	     */

	    TkTextChanged(NULL, textPtr, &index, &index2);

            /*


             * The number of lines in the widget is zero if and only if it is
             * a partial peer with -startline == -endline, i.e. an empty
             * peer. In this case the mark shall be set exactly at the given
             * index, and not one character backwards (bug 3487407).
             */








	    nblines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);



	    if ((TkBTreeLinesTo(textPtr, indexPtr->linePtr) == nblines)




		    && (nblines > 0))  {


		TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex,




			COUNT_INDICES);


		indexPtr = &insertIndex;


	    }

	}



	TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);








    } else {

	markPtr = (TkTextSegment *)ckalloc(MSEG_SIZE);

	markPtr->typePtr = &tkTextRightMarkType;
	markPtr->size = 0;
	markPtr->body.mark.textPtr = textPtr;

	markPtr->body.mark.linePtr = indexPtr->linePtr;
	markPtr->body.mark.hPtr = hPtr;
	if (widgetSpecific == 0) {
	    Tcl_SetHashValue(hPtr, markPtr);
	} else if (widgetSpecific == 1) {
	    textPtr->insertMarkPtr = markPtr;


	} else {

	    textPtr->currentMarkPtr = markPtr;
	}
    }
    TkBTreeLinkSegment(markPtr, indexPtr);





    /*
     * If the mark is the insertion cursor, then update the screen at the
     * mark's new location.
     */

    if (markPtr == textPtr->insertMarkPtr) {
	TkTextIndex index2;

	TkTextIndexForwChars(NULL, indexPtr, 1, &index2, COUNT_INDICES);

	/*
	 * While we wish to redisplay, no heights have changed, so no need to
	 * call TkTextInvalidateLineMetrics
	 */










































































	TkTextChanged(NULL, textPtr, indexPtr, &index2);

















    }


































    return markPtr;




}

/*
 *--------------------------------------------------------------
 *
 * TkTextMarkSegToIndex --
 *






|
|
>








>

<
|
|
>
>
>
>
>
>

|
|
>
>
>





<
|
<
|
<
>
|
<
|
<
|
|
|
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
>
|
<
|
<
|
|
|
>



|
>
|
<
|
<
|
|
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


















>
>
>
>
>
>
>



|

|
|
<
|








|
>


|
|






>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|






|
|

|


|
<
|
<
<
<
<





<
|
<
<
<
<
|


|
<
|

<
|




|


>
>
>
|
>
>
>
|
|
|
>
>
>
>
>



>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
|
|


>
>

>
>
|
<
>
>
|
>
|
|
>
|
>
|
>
|
|
>
>
|
>
>
>



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|


>
>
|
>
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
|


|


>
|
|
>
>
|
>
|
>
>
>
>
|
>
|
<
|
|
>
|
>
>

>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
|
>
>
>
>
>

|
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
|
|
>
>
>
|
|
>
>
>
>
>
>
>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>










|
|


>
>



>

|
>
>
|
>

>
>
>
>
>
>
>
>
|
|
|
<
>
>
>
>
>
>
|
|
|
>
>
>
|
>
>
|
|
>
|
<


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
<

<
|

>
>
>
>
>
>
>
|
|
|
|

<
<
|
>
>
|
<
<
<
|
>
|
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
|
>
>
|
>
>
>
>
|
>
>
|
>
>
|
>
|
>
>
>
|
>
>
>
>
>
>
>
>
|
>
|
>
|
|
|
>
|
|
<
<
<
|
>
>
|
>
|


|
>
>
|
>
>
|
|
<
|

|
|

|

|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39

40

41
42

43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189

190
191
192
193
194
195
196
197
198
199

200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672

673




674
675
676
677
678

679




680
681
682
683

684
685

686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738

739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680

1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699

1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772

1773

1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787


1788
1789
1790
1791



1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848



1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
/*
 * tkTextMark.c --
 *
 *	This file contains the functions that implement marks for text
 *	widgets.
 *
 * Copyright © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2015-2017 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 "tkText.h"
#include "tk3d.h"
#include <assert.h>


#include <inttypes.h>

#ifndef MAX
# define MAX(a,b) ((a) < (b) ? b : a)
#endif
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? a : b)
#endif

#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

/*
 * Forward references for functions defined in this file:
 */


static void		InsertUndisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr);

static int		MarkDeleteProc(TkSharedText *sharedTextPtr, TkTextSegment *segPtr, int flags);

static Tcl_Obj *	MarkInspectProc(const TkSharedText *sharedTextPtr, const TkTextSegment *segPtr);
static int		MarkRestoreProc(TkSharedText *sharedTextPtr, TkTextSegment *segPtr);

static void		MarkCheckProc(const TkSharedText *sharedTextPtr, const TkTextSegment *segPtr);

static int		MarkLayoutProc(const TkTextIndex *indexPtr,
			    TkTextSegment *segPtr, Tcl_Size offset, int maxX,
			    Tcl_Size maxChars, int noCharsYet, TkWrapMode wrapMode,
			    TkTextSpaceMode spaceMode, TkTextDispChunk *chunkPtr);
static int		MarkFindNext(Tcl_Interp *interp, TkText *textPtr, int discardSpecial,
			    Tcl_Obj* indexObj, const char *pattern, int forward);
static void		ChangeGravity(TkSharedText *sharedTextPtr, TkText *textPtr,
			    TkTextSegment *markPtr, const Tk_SegType *newTypePtr,
			    TkTextUndoInfo *redoInfo);
static struct TkTextSegment *SetMark(struct TkText *textPtr, const char *name,
			    const Tk_SegType *typePtr, TkTextIndex *indexPtr);
static void		UnsetMark(TkSharedText *sharedTextPtr, TkTextSegment *markPtr,
			    TkTextUndoInfo *redoInfo);
static void		ReactivateMark(TkSharedText *sharedTextPtr, TkTextSegment *markPtr);

static const TkTextDispChunkProcs layoutInsertProcs = {
    TEXT_DISP_CURSOR,		/* type */
    TkrTextInsertDisplayProc,	/* displayProc */
    InsertUndisplayProc,	/* undisplayProc */
    NULL,	                /* measureProc */
    NULL,		        /* bboxProc */
};
/*
 * We need some private undo/redo stuff.
 */

static void UndoToggleGravityPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void UndoSetMarkPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void RedoSetMarkPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void UndoMoveMarkPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void UndoToggleGravityDestroy(TkSharedText *, TkTextUndoToken *, int);
static void UndoSetMarkDestroy(TkSharedText *, TkTextUndoToken *, int);
static void RedoSetMarkDestroy(TkSharedText *, TkTextUndoToken *, int);
static void UndoMoveMarkDestroy(TkSharedText *, TkTextUndoToken *, int);
static void UndoMarkGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static void RedoSetMarkGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static void RedoMoveMarkGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static Tcl_Obj *UndoToggleGravityGetCommand(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *UndoSetMarkGetCommand(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *UndoToggleGravityInspect(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *UndoSetMarkInspect(const TkSharedText *, const TkTextUndoToken *);

static const Tk_UndoType undoTokenToggleGravityType = {
    TK_TEXT_UNDO_MARK_GRAVITY,	/* action */
    UndoToggleGravityGetCommand,/* commandProc */
    UndoToggleGravityPerform,	/* undoProc */
    UndoToggleGravityDestroy,	/* destroyProc */
    UndoMarkGetRange,		/* rangeProc */
    UndoToggleGravityInspect	/* inspectProc */
};

static const Tk_UndoType redoTokenToggleGravityType = {
    TK_TEXT_REDO_MARK_GRAVITY,	/* action */
    UndoToggleGravityGetCommand,/* commandProc */
    UndoToggleGravityPerform,	/* undoProc */
    UndoToggleGravityDestroy,	/* destroyProc */
    UndoMarkGetRange,		/* rangeProc */
    UndoToggleGravityInspect	/* inspectProc */
};

static const Tk_UndoType undoTokenSetMarkType = {
    TK_TEXT_UNDO_MARK_SET,	/* action */
    UndoSetMarkGetCommand,	/* commandProc */
    UndoSetMarkPerform,		/* undoProc */
    UndoSetMarkDestroy,		/* destroyProc */
    UndoMarkGetRange,		/* rangeProc */
    UndoSetMarkInspect		/* inspectProc */
};

static const Tk_UndoType redoTokenSetMarkType = {
    TK_TEXT_REDO_MARK_SET,	/* action */
    UndoSetMarkGetCommand,	/* commandProc */
    RedoSetMarkPerform,		/* undoProc */
    RedoSetMarkDestroy,		/* destroyProc */
    RedoSetMarkGetRange,	/* rangeProc */
    UndoSetMarkInspect		/* inspectProc */
};

static const Tk_UndoType undoTokenMoveMarkType = {
    TK_TEXT_UNDO_MARK_MOVE,	/* action */
    UndoSetMarkGetCommand,	/* commandProc */
    UndoMoveMarkPerform,	/* undoProc */
    UndoMoveMarkDestroy,	/* destroyProc */
    RedoMoveMarkGetRange,	/* rangeProc */
    UndoSetMarkInspect		/* inspectProc */
};

static const Tk_UndoType redoTokenMoveMarkType = {
    TK_TEXT_REDO_MARK_MOVE,	/* action */
    UndoSetMarkGetCommand,	/* commandProc */
    UndoMoveMarkPerform,	/* undoProc */
    UndoMoveMarkDestroy,	/* destroyProc */
    RedoMoveMarkGetRange,	/* rangeProc */
    UndoSetMarkInspect		/* inspectProc */
};

typedef struct UndoTokenToggleMark {
    const Tk_UndoType *undoType;
    TkTextSegment *markPtr;
} UndoTokenToggleMark;

typedef struct UndoTokenToggleIndex {
    const Tk_UndoType *undoType;
    TkTextSegment *markPtr;
} UndoTokenToggleIndex;

/* derivation of UndoTokenToggleMark */
typedef struct UndoTokenToggleGravity {
    const Tk_UndoType *undoType;
    TkTextSegment *markPtr;
} UndoTokenToggleGravity;

/* derivation of UndoTokenToggleMark */
typedef struct UndoTokenSetMark {
    const Tk_UndoType *undoType;
    TkTextSegment *markPtr;
} UndoTokenSetMark;

/* derivation of UndoTokenSetMark */
typedef struct RedoTokenSetMark {
    const Tk_UndoType *undoType;
    TkTextSegment *markPtr;
    TkTextUndoIndex index;
} RedoTokenSetMark;

/* derivation of UndoTokenSetMark */
typedef struct UndoTokenMoveMark {
    const Tk_UndoType *undoType;
    TkTextSegment *markPtr;
    TkTextUndoIndex index;
} UndoTokenMoveMark;

/*
 * The following structures declare the "mark" segment types. There are
 * actually two types for marks, one with left gravity and one with right
 * gravity. They are identical except for their gravity property.
 */

const Tk_SegType tkTextRightMarkType = {
    "mark",		/* name */
    SEG_GROUP_MARK,	/* group */
    GRAVITY_RIGHT,	/* gravity */

    MarkDeleteProc,	/* deleteProc */

    MarkRestoreProc,	/* restoreProc */
    MarkLayoutProc,	/* layoutProc */
    MarkCheckProc,	/* checkProc */
    MarkInspectProc	/* inspectProc */
};

const Tk_SegType tkTextLeftMarkType = {
    "mark",		/* name */
    SEG_GROUP_MARK,	/* group */
    GRAVITY_LEFT,	/* gravity */

    MarkDeleteProc,	/* deleteProc */

    MarkRestoreProc,	/* restoreProc */
    MarkLayoutProc,	/* layoutProc */
    MarkCheckProc,	/* checkProc */
    MarkInspectProc	/* inspectProc */
};

/*
 * Pointer to int, for some portable pointer hacks - it's guaranteed that
 * 'uintptr_t' and 'void *' are convertible in both directions (C99 7.18.1.4).
 */

typedef union {
    void *ptr;
    uintptr_t flag;
} __ptr_to_int;

#define MARK_POINTER(ptr)	(((__ptr_to_int *) &ptr)->flag |= (uintptr_t) 1)
#define UNMARK_POINTER(ptr)	(((__ptr_to_int *) &ptr)->flag &= ~(uintptr_t) 1)
#define POINTER_IS_MARKED(ptr)	(((__ptr_to_int *) &ptr)->flag & (uintptr_t) 1)

#define IS_PRESERVED(seg)	POINTER_IS_MARKED(seg->body.mark.ptr)
#define MAKE_PRESERVED(seg)	MARK_POINTER(seg->body.mark.ptr)

#define GET_POINTER(ptr)	((void *) (((__ptr_to_int *) &ptr)->flag & ~(uintptr_t) 1))

#define GET_NAME(seg)		((char *) GET_POINTER(seg->body.mark.ptr))
#define GET_HPTR(seg)		((Tcl_HashEntry *) seg->body.mark.ptr)
#define PTR_TO_INT(ptr)		((uintptr_t) ptr)

#ifndef NDEBUG

# undef GET_HPTR
# undef GET_NAME

static Tcl_HashEntry *GET_HPTR(const TkTextSegment *markPtr)
{ assert(!IS_PRESERVED(markPtr)); return (Tcl_HashEntry *) markPtr->body.mark.ptr; }

static char *GET_NAME(const TkTextSegment *markPtr)
{ assert(IS_PRESERVED(markPtr)); return (char *) GET_POINTER(markPtr->body.mark.ptr); }

#endif /* NDEBUG */

DEBUG_ALLOC(extern unsigned tkTextCountNewSegment);
DEBUG_ALLOC(extern unsigned tkTextCountDestroySegment);
DEBUG_ALLOC(extern unsigned tkTextCountNewUndoToken);
DEBUG_ALLOC(extern unsigned tkTextCountDestroyUndoToken);

/*
 * Some functions for the undo/redo mechanism.
 */

static Tcl_Obj *
AppendName(
    Tcl_Obj *objPtr,
    const TkSharedText *sharedTextPtr,
    const TkTextSegment *markPtr)
{
    const char *name;

    if (IS_PRESERVED(markPtr)) {
	name = GET_NAME(markPtr);
    } else {
	name = TkTextMarkName(sharedTextPtr, NULL, markPtr);
    }
    assert(name);
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(name, TCL_INDEX_NONE));
    return objPtr;
}

static Tcl_Obj *
UndoToggleGravityGetCommand(
    TCL_UNUSED(const TkSharedText *),
    TCL_UNUSED(const TkTextUndoToken *))
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("mark", TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("gravity", TCL_INDEX_NONE));
    return objPtr;
}

static Tcl_Obj *
UndoToggleGravityInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const UndoTokenToggleGravity *token = (const UndoTokenToggleGravity *) item;
    return AppendName(UndoToggleGravityGetCommand(sharedTextPtr, item), sharedTextPtr, token->markPtr);
}

static void
UndoToggleGravityPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    int isRedo)
{
    UndoTokenToggleGravity *token = (UndoTokenToggleGravity *) undoInfo->token;
    const Tk_SegType *newTypePtr;
    const Tk_SegType *oldTypePtr;

    assert(!token->markPtr->body.mark.changePtr);

    oldTypePtr = token->markPtr->typePtr;
    newTypePtr = (oldTypePtr == &tkTextRightMarkType) ? &tkTextLeftMarkType : &tkTextRightMarkType;
    ChangeGravity(sharedTextPtr, NULL, token->markPtr, newTypePtr, NULL);

    if (redoInfo) {
	redoInfo->token = undoInfo->token;
	redoInfo->token->undoType = isRedo ? &undoTokenToggleGravityType : &redoTokenToggleGravityType;
    }
}

static void
UndoToggleGravityDestroy(
    TkSharedText *sharedTextPtr,
    TkTextUndoToken *item,
    int reused)
{
    assert(!((UndoTokenToggleGravity *) item)->markPtr->body.mark.changePtr);

    if (!reused) {
	UndoTokenToggleGravity *token = (UndoTokenToggleGravity *) item;
	MarkDeleteProc(sharedTextPtr, token->markPtr, DELETE_MARKS);
    }
}

static void
UndoMoveMarkPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    int isRedo)
{
    UndoTokenMoveMark *token = (UndoTokenMoveMark *) undoInfo->token;
    TkTextUndoIndex index = token->index;

    assert(!token->markPtr->body.mark.changePtr);

    if (redoInfo) {
	TkBTreeMakeUndoIndex(sharedTextPtr, token->markPtr, &index);
	token->index = index;
	redoInfo->token = undoInfo->token;
	redoInfo->token->undoType = isRedo ? &undoTokenMoveMarkType : &redoTokenMoveMarkType;
    }

    TkBTreeUnlinkSegment(sharedTextPtr, token->markPtr);
    TkBTreeReInsertSegment(sharedTextPtr, &index, token->markPtr);
}

static void
UndoMoveMarkDestroy(
    TkSharedText *sharedTextPtr,
    TkTextUndoToken *item,
    int reused)
{
    assert(!((UndoTokenMoveMark *) item)->markPtr->body.mark.changePtr);

    if (!reused) {
	UndoTokenMoveMark *token = (UndoTokenMoveMark *) item;
	MarkDeleteProc(sharedTextPtr, token->markPtr, DELETE_MARKS);
    }
}

static Tcl_Obj *
UndoSetMarkGetCommand(
    TCL_UNUSED(const TkSharedText *),
    const TkTextUndoToken *item)
{
    const UndoTokenSetMark *token = (const UndoTokenSetMark *) item;
    const char *operation = POINTER_IS_MARKED(token->markPtr) ? "unset" : "set";
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("mark", TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(operation, TCL_INDEX_NONE));
    return objPtr;
}

static Tcl_Obj *
UndoSetMarkInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const UndoTokenSetMark *token = (const UndoTokenSetMark *) item;
    const TkTextSegment *markPtr = (const TkTextSegment *)GET_POINTER(token->markPtr);
    Tcl_Obj *objPtr = UndoSetMarkGetCommand(sharedTextPtr, item);

    objPtr = AppendName(objPtr, sharedTextPtr, markPtr);

    if (!POINTER_IS_MARKED(token->markPtr)) {
	const char *gravity = (markPtr->typePtr == &tkTextLeftMarkType) ? "left" : "right";
	Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(gravity, TCL_INDEX_NONE));
    }

    return objPtr;
}

static void
UndoSetMarkPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    int isRedo)
{
    const UndoTokenSetMark *token = (const UndoTokenSetMark *) undoInfo->token;
    TkTextSegment *markPtr = (TkTextSegment *)GET_POINTER(token->markPtr);

    assert(!markPtr->body.mark.changePtr);
    UnsetMark(sharedTextPtr, markPtr, redoInfo);
    if (redoInfo && !isRedo) {
	UNMARK_POINTER(((RedoTokenSetMark *) redoInfo->token)->markPtr);
    }
}

static void
UndoSetMarkDestroy(
    TkSharedText *sharedTextPtr,
    TkTextUndoToken *item,
    TCL_UNUSED(int))
{
    UndoTokenSetMark *token = (UndoTokenSetMark *) item;
    TkTextSegment *markPtr = (TkTextSegment *)GET_POINTER(token->markPtr);

    assert(!markPtr->body.mark.changePtr);

    MarkDeleteProc(sharedTextPtr, markPtr, DELETE_CLEANUP);
}

static void
RedoSetMarkPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    TCL_UNUSED(int))
{
    RedoTokenSetMark *token = (RedoTokenSetMark *) undoInfo->token;
    TkTextSegment *markPtr = (TkTextSegment *)GET_POINTER(token->markPtr);

    assert(!markPtr->body.mark.changePtr);
    assert(TkTextIsNormalMark(markPtr));

    if (IS_PRESERVED(markPtr)) {
	ReactivateMark(sharedTextPtr, markPtr);
	sharedTextPtr->numMarks += 1;
    }

    TkBTreeReInsertSegment(sharedTextPtr, &token->index, markPtr);
    markPtr->refCount += 1;

    if (redoInfo) {
	UndoTokenSetMark *redoToken;

	redoToken = (UndoTokenSetMark *)ckalloc(sizeof(UndoTokenSetMark));
	redoToken->markPtr = token->markPtr;
	redoToken->undoType = &undoTokenSetMarkType;
	redoInfo->token = (TkTextUndoToken *) redoToken;
	DEBUG_ALLOC(tkTextCountNewUndoToken++);
	markPtr->refCount += 1;
    }
}

static void
RedoSetMarkDestroy(
    TkSharedText *sharedTextPtr,
    TkTextUndoToken *item,
    TCL_UNUSED(int))
{
    RedoTokenSetMark *token = (RedoTokenSetMark *) item;
    TkTextSegment *markPtr = (TkTextSegment *)GET_POINTER(token->markPtr);

    assert(!markPtr->body.mark.changePtr);
    MarkDeleteProc(sharedTextPtr, markPtr, DELETE_MARKS);
}

static void
UndoMarkGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    const UndoTokenToggleMark *token = (UndoTokenToggleMark *) item;

    TkTextIndexClear2(startIndex, NULL, sharedTextPtr->tree);
    TkTextIndexSetSegment(startIndex, (TkTextSegment *)GET_POINTER(token->markPtr));
    *endIndex = *startIndex;
}

static void
RedoSetMarkGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    RedoTokenSetMark *token = (RedoTokenSetMark *) item;
    TkBTreeUndoIndexToIndex(sharedTextPtr, &token->index, startIndex);
    *endIndex = *startIndex;
}

static void
RedoMoveMarkGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    UndoTokenMoveMark *token = (UndoTokenMoveMark *) item;
    TkTextSegment *markPtr = (TkTextSegment *)GET_POINTER(token->markPtr);

    TkBTreeUndoIndexToIndex(sharedTextPtr, &token->index, startIndex);
    TkTextIndexClear2(endIndex, NULL, sharedTextPtr->tree);
    TkTextIndexSetSegment(endIndex, markPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TkTextMarkCmd --
 *
 *	This function is invoked to process the "mark" options of the widget
 *	command for text widgets. See the user documentation for details on
 *	what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
SetResultNoMarkNamed(Tcl_Interp *interp, const char *name) {
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("there is no mark named \"%s\"", name));
    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_MARK", name, (char *)NULL);
    return TCL_ERROR;
}

int
TkTextMarkCmd(
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already parsed this command

    				 * enough to know that objv[1] is "mark". */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *markPtr;
    Tcl_HashSearch search;
    TkTextIndex index;
    const Tk_SegType *newTypePtr;
    int optionIndex;
    static const char *const markOptionStrings[] = {
	"compare", "exists", "generate", "gravity", "names", "next", "previous",
	"set", "unset", NULL
    };
    enum markOptions {
	MARK_COMPARE, MARK_EXISTS, MARK_GENERATE, MARK_GRAVITY, MARK_NAMES, MARK_NEXT, MARK_PREVIOUS,
	MARK_SET, MARK_UNSET
    };

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], markOptionStrings,
	    sizeof(char *), "mark option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum markOptions) optionIndex) {
    case MARK_COMPARE: {
	TkTextSegment *markPtr1, *markPtr2;
	int relation, value;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "markName1 op markName2");
	    return TCL_ERROR;
	}
	if (!(markPtr1 = TkTextFindMark(textPtr, Tcl_GetString(objv[2])))) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad comparison operand \"%s\": "
		    "must be an existing mark", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_COMPARISON", (char *)NULL);
	    return TCL_ERROR;
	}
	if (!(markPtr2 = TkTextFindMark(textPtr, Tcl_GetString(objv[4])))) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad comparison operand \"%s\": "
		    "must be an existing mark", Tcl_GetString(objv[4])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_COMPARISON", (char *)NULL);
	    return TCL_ERROR;
	}

	if (markPtr1 == markPtr2) {
	    relation = 0;
	} else {
	    TkTextIndex index1, index2;

	    TkTextIndexClear(&index1, textPtr);
	    TkTextIndexClear(&index2, textPtr);
	    TkTextIndexSetSegment(&index1, markPtr1);
	    TkTextIndexSetSegment(&index2, markPtr2);
	    relation = TkTextIndexCompare(&index1, &index2);

	    if (relation == 0) {
		TkTextSegment *segPtr = markPtr1->nextPtr;

		while (segPtr && segPtr != markPtr2 && segPtr->size == 0) {
		    segPtr = segPtr->nextPtr;
		}
		relation = (segPtr == markPtr2) ? -1 : +1;
	    }
	}

	value = TkTextTestRelation(interp, relation, Tcl_GetString(objv[3]));
	if (value == -1) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
	break;
    }
    case MARK_EXISTS: {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName");
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!!TkTextFindMark(textPtr, Tcl_GetString(objv[3]))));
	break;
    }
    case MARK_GENERATE: {
	TkTextSegment *markPtr1;
	TkTextIndex index1;
	char uniqName[100];

	TkTextIndexClear(&index1, textPtr);
	TkTextIndexSetSegment(&index1, textPtr->startMarker);
	/* IMPORTANT NOTE: ensure fixed length (depending on pointer size) */
	snprintf(uniqName, sizeof(uniqName),
#ifdef TK_IS_64_BIT_ARCH
	    "##ID##0x%016" PRIx64 "##0x%016" PRIx64 "##%08" TCL_Z_MODIFIER "u##", /* we're on a real 64-bit system */
	    (uint64_t) textPtr, (uint64_t) textPtr->sharedTextPtr, ++textPtr->uniqueIdCounter
#else /* if !defined(TK_IS_64_BIT_ARCH) */
	    "##ID##0x%08" PRIx32 "##0x%08" PRIx32 "##%08" TCL_Z_MODIFIER "u##",   /* we're most likely on a 32-bit system */
	    (uint32_t) textPtr, (uint32_t) textPtr->sharedTextPtr, ++textPtr->uniqueIdCounter
#endif /* TK_IS_64_BIT_ARCH */
	);
	assert(!TkTextFindMark(textPtr, uniqName));
    	markPtr1 = TkTextMakeMark(textPtr, uniqName);
    	markPtr1->privateMarkFlag = 1;
	textPtr->sharedTextPtr->numMarks -= 1; /* take back counting */
	textPtr->sharedTextPtr->numPrivateMarks += 1;
	TkBTreeLinkSegment(textPtr->sharedTextPtr, markPtr1, &index1);
	Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(uniqName, TCL_INDEX_NONE));
	break;
    }
    case MARK_GRAVITY: {
	Tcl_Size length;
	const char *str;

	if (objc < 4 || objc > 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
	    return TCL_ERROR;
	}
	str = Tcl_GetStringFromObj(objv[3], &length);
	if (strcmp(str, "insert") == 0) {
	    markPtr = textPtr->insertMarkPtr;
	} else if (strcmp(str, "current") == 0) {
	    markPtr = textPtr->currentMarkPtr;
	} else {
	    if (!(hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, str))) {

		return SetResultNoMarkNamed(interp, Tcl_GetString(objv[3]));




	    }
	    markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
	}
	if (objc == 4) {
	    const char *typeStr;

	    typeStr = markPtr->typePtr == &tkTextRightMarkType ? "right" : "left";




	    Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, TCL_INDEX_NONE));
	    return TCL_OK;
	}
	str = Tcl_GetStringFromObj(objv[4], &length);

	if (strncmp(str, "left", length) == 0) {
	    newTypePtr = &tkTextLeftMarkType;

	} else if (strncmp(str, "right", length) == 0) {
	    newTypePtr = &tkTextRightMarkType;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad mark gravity \"%s\": must be left or right", str));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_GRAVITY", (char *)NULL);
	    return TCL_ERROR;
	}
	/*
	 * We have to force the re-insertion of the mark when steadyMarks is not enabled.
	 */

	if (markPtr->typePtr != newTypePtr || !textPtr->sharedTextPtr->steadyMarks) {
	    TkTextUndoInfo undoInfo;
	    TkTextUndoInfo *undoInfoPtr = NULL;

	    if (textPtr->sharedTextPtr->steadyMarks
		    && TkTextIsNormalMark(markPtr)
		    && !TkTextUndoUndoStackIsFull(textPtr->sharedTextPtr->undoStack)) {
		undoInfoPtr = &undoInfo;
	    }
	    ChangeGravity(textPtr->sharedTextPtr, textPtr, markPtr, newTypePtr, undoInfoPtr);
	}
	break;
    }
    case MARK_NAMES: {
	int discardSpecial = 0;
	Tcl_Size numArgs = 3;
	const char *pattern;
	Tcl_Obj *resultObj;

	if (objc > 4 && *Tcl_GetString(objv[3]) == '-') {
	    if (strcmp(Tcl_GetString(objv[3]), "-discardspecial") == 0) {
		discardSpecial = 1;
		numArgs = 4;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": must be -discardspecial", Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_OPTION", (char *)NULL);
		return TCL_ERROR;
	    }
	}

	if (objc != numArgs && objc != numArgs + 1) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?-discardspecial? ?pattern?");
	    return TCL_ERROR;
	}

	pattern = objc > numArgs ? Tcl_GetString(objv[numArgs]) : NULL;
	resultObj = Tcl_NewObj();

	if (!discardSpecial && (!pattern || Tcl_StringMatch("insert", pattern))) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj("insert", TCL_INDEX_NONE));

	}
	if (!discardSpecial && (!pattern || Tcl_StringMatch("current", pattern))) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj("current", TCL_INDEX_NONE));
	}

	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->markTable, &search);
		hPtr;
		hPtr = Tcl_NextHashEntry(&search)) {
	    TkTextSegment *markPtr1 = (TkTextSegment *)Tcl_GetHashValue(hPtr);

	    if (!markPtr1->privateMarkFlag && !markPtr1->startEndMarkFlag) {
		const char *name = (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr);

		if (!pattern || Tcl_StringMatch(name, pattern)) {
		    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(name, TCL_INDEX_NONE));
		}
	    }
	}

	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    case MARK_NEXT: {
	int discardSpecial = 0;
	Tcl_Size numArgs = 4;
	const char *pattern;

	if (objc > 4 && *Tcl_GetString(objv[3]) == '-') {
	    if (strcmp(Tcl_GetString(objv[3]), "-discardspecial") == 0) {
		discardSpecial = 1;
		numArgs = 5;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": must be -discardspecial", Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_OPTION", (char *)NULL);
		return TCL_ERROR;
	    }
	}

	if (objc != numArgs && objc != numArgs + 1) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?-discardspecial? index ?pattern?");
	    return TCL_ERROR;
	}

	pattern = objc > numArgs ? Tcl_GetString(objv[numArgs]) : NULL;
	return MarkFindNext(interp, textPtr, discardSpecial, objv[numArgs - 1], pattern, 1);
    }
    case MARK_PREVIOUS: {
	int discardSpecial = 0;
	Tcl_Size numArgs = 4;
	const char *pattern;

	if (objc > 4 && *Tcl_GetString(objv[3]) == '-') {
	    if (strcmp(Tcl_GetString(objv[3]), "-discardspecial") == 0) {
		discardSpecial = 1;
		numArgs = 5;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": must be -discardspecial", Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_OPTION", (char *)NULL);
		return TCL_ERROR;
	    }
	}

	if (objc != numArgs && objc != numArgs + 1) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?-discardspecial? index ?pattern?");
	    return TCL_ERROR;
	}

	pattern = objc > numArgs ? Tcl_GetString(objv[numArgs]) : NULL;
	return MarkFindNext(interp, textPtr, discardSpecial, objv[numArgs - 1], pattern, 0);
    }
    case MARK_SET: {
	const Tk_SegType *typePtr = NULL;
	const char *name;

	if (objc != 5 && objc != 6) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName index ?direction?");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[4], &index)) {
	    return TCL_ERROR;
	}
	if (objc == 6) {
	    const char *direction = Tcl_GetString(objv[5]);

	    if (strcmp(direction, "left") == 0) {
		typePtr = &tkTextLeftMarkType;
	    } else if (strcmp(direction, "right") == 0) {
		typePtr = &tkTextRightMarkType;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad mark gravity \"%s\": must be left or right", direction));
		Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_GRAVITY", (char *)NULL);
		return TCL_ERROR;
	    }
	}


	name = Tcl_GetString(objv[3]);

#if BEGIN_DOES_NOT_BELONG_TO_BASE

	if (*name == 'b' && strcmp(name, "begin") == 0) {
	    static int printWarning = 1;

	    if (printWarning) {
		fprintf(stderr, "tk::text: \"begin\" is a reserved index identifier and shouldn't "
			"be used for mark names anymore.\n");
		printWarning = 0;
	    }
	}

#else /* if !BEGIN_DOES_NOT_BELONG_TO_BASE */

	/*

	 * TODO:
	 * Probably we should print a warning if the mark name is matching any of the
	 * following forms:
	 *	- "begin"|"end"
	 *	- <integer> "." (<integer>|"begin"|"end")
	 *	- "@" (<integer>|"first"|"last") "," (<integer>|"first"|"last")
	 *	- "##ID##" .*
	 */

#endif /* BEGIN_DOES_NOT_BELONG_TO_BASE */

	if (!SetMark(textPtr, name, typePtr, &index)) {
	    Tcl_Obj *msgPtr;

	    if (strcmp(name, "insert") == 0) {
		return TCL_OK; /* the "watch" command did destroy the widget */
	    }
	    msgPtr = Tcl_ObjPrintf("\"%s\" is an expired generated mark", name);
	    Tcl_SetObjResult(interp, msgPtr);
	    Tcl_SetErrorCode(interp, "TK", "SET", "TEXT_MARK", name, (char *)NULL);
	    return TCL_ERROR;
	}
	break;
    }
    case MARK_UNSET: {
	TkTextUndoInfo undoInfo;
	TkTextUndoInfo *undoInfoPtr = NULL;
	Tcl_Size i;

	if (textPtr->sharedTextPtr->steadyMarks
		&& !TkTextUndoUndoStackIsFull(textPtr->sharedTextPtr->undoStack)) {
	    undoInfoPtr = &undoInfo;
	}

	for (i = 3; i < objc; i++) {
	    if ((hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, Tcl_GetString(objv[i])))) {
		TkTextSegment *markPtr3 = (TkTextSegment *)Tcl_GetHashValue(hPtr);

		if (TkTextIsPrivateMark(markPtr3)) {
		    UnsetMark(textPtr->sharedTextPtr, markPtr3, NULL);
		} else if (!TkTextIsSpecialMark(markPtr3)) {
		    UnsetMark(textPtr->sharedTextPtr, markPtr3, undoInfoPtr);
		    if (undoInfoPtr && undoInfo.token) {
			TkTextPushUndoToken(textPtr->sharedTextPtr, undoInfo.token, 0);
		    }
		}
	    }
	}
	break;
    }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFindMark --
 *
 *	Return mark segment of given name, if exisiting.
 *
 * Results:
 *	The mark with this name, or NULL if not existing.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextFindMark(
    const TkText *textPtr,
    const char *name)
{
    Tcl_HashEntry *hPtr;

    assert(textPtr);
    assert(name);

    switch (name[0]) {
    case 'i':
	if (strcmp(name, "insert") == 0) {
	    return textPtr->insertMarkPtr;
	}
	break;
    case 'c':
	if (strcmp(name, "current") == 0) {
	    return textPtr->currentMarkPtr;
	}
	break;
    }
    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);
    return hPtr ? (TkTextSegment *)Tcl_GetHashValue(hPtr) : NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * ReactivateMark --
 *
 *	Reactivate a preserved mark.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates some memory for hash table entry, and release memory
 *	of preserved name.
 *
 *----------------------------------------------------------------------
 */

static void
ReactivateMark(
    TkSharedText *sharedTextPtr,	/* Handle to shared text resource. */
    TkTextSegment *markPtr)		/* Reactivate this mark. */
{
    Tcl_HashEntry *hPtr;
    char *name;
    int isNew;

    assert(IS_PRESERVED(markPtr));

    name = GET_NAME(markPtr);
    hPtr = Tcl_CreateHashEntry(&sharedTextPtr->markTable, name, &isNew);
    assert(isNew);
    ckfree(name);
    Tcl_SetHashValue(hPtr, markPtr);
    markPtr->body.mark.ptr = PTR_TO_INT(hPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFreeMarks --
 *
 *	Free all used marks, also the hash table for marks will be
 *	destroyed. But do not free private marks if 'retainPrivateMarks'
 *	is true, in this case a new hash table will be built, only
 *	with the remaining private marks.
 *
 * Results:
 *	If 'retainPrivateMarks' is false, then return NULL. Otherwise
 *	the chain of retained private marks will be returned.
 *
 * Side effects:
 *	Free some memory, the old hash table for marks will be destroyed,
 *	and a new one will be created if 'retainPrivateMarks' is true.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextFreeMarks(
    TkSharedText *sharedTextPtr,	/* Handle to shared text resource. */
    int retainPrivateMarks)		/* Priate marks will be retained? */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&sharedTextPtr->markTable, &search);
    TkTextSegment *deletePtr = NULL;
    TkTextSegment *retainedPtr = NULL;
    TkTextSegment *markPtr;

    for ( ; hPtr; hPtr = Tcl_NextHashEntry(&search)) {
	markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);

	assert(markPtr->body.mark.changePtr != (void *) 0xdeadbeef);
	assert(markPtr->refCount > 0);

	if (!retainPrivateMarks || !TkTextIsPrivateMark(markPtr)) {
	    markPtr->nextPtr = deletePtr;
	    markPtr->prevPtr = NULL;
	    deletePtr = markPtr;
	} else {
	    const char *name = (const char *)Tcl_GetHashKey(&sharedTextPtr->markTable, hPtr);
	    char *dup;

	    markPtr->sectionPtr = NULL;
	    markPtr->prevPtr = NULL;
	    markPtr->nextPtr = retainedPtr;
	    dup = (char *)ckalloc(strlen(name) + 1);
	    markPtr->body.mark.ptr = PTR_TO_INT(strcpy(dup, name));
	    MAKE_PRESERVED(markPtr);
	    retainedPtr = markPtr;
	}
    }

    markPtr = deletePtr;
    while (markPtr) {
	TkTextSegment *nextPtr = markPtr->nextPtr;
	assert(TkTextIsSpecialMark(markPtr) || markPtr->refCount == 1);
	MarkDeleteProc(sharedTextPtr, markPtr, DELETE_CLEANUP|TREE_GONE);
	markPtr = nextPtr;
    }

    Tcl_DeleteHashTable(&sharedTextPtr->markTable);
    sharedTextPtr->numMarks = 0;

    if (retainPrivateMarks) {
	Tcl_InitHashTable(&sharedTextPtr->markTable, TCL_STRING_KEYS);

	for (markPtr = retainedPtr; markPtr; markPtr = markPtr->nextPtr) {
	    ReactivateMark(sharedTextPtr, markPtr);
	}
    } else {
	sharedTextPtr->numPrivateMarks = 0;
    }

    return retainedPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateCurrentMark --
 *
 *	If a position change of the "current" mark has been postponed
 *	we will do now the update.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The "current" mark will change the position.
 *
 *----------------------------------------------------------------------
 */

void
TkTextUpdateCurrentMark(
    TkSharedText *sharedTextPtr)	/* Shared text resource. */
{
    TkText *tPtr;

    assert(sharedTextPtr->haveToSetCurrentMark);

    sharedTextPtr->haveToSetCurrentMark = 0;

    for (tPtr = sharedTextPtr->peers; tPtr; tPtr = tPtr->next) {
	if (tPtr->haveToSetCurrentMark) {
	    tPtr->haveToSetCurrentMark = 0;
	    TkBTreeUnlinkSegment(sharedTextPtr, tPtr->currentMarkPtr);
	    TkBTreeLinkSegment(sharedTextPtr, tPtr->currentMarkPtr, &tPtr->currentMarkIndex);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextMakeStartEndMark --
 *
 *	Make (allocate) a new start/end mark.
 *
 * Results:
 *	The return value is a pointer to the new mark.
 *
 * Side effects:
 *	A new mark is created.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextMakeStartEndMark(
    TkText *textPtr,		/* can be NULL */
    Tk_SegType const *typePtr)
{
    TkTextSegment *markPtr = TkTextMakeMark(NULL, NULL);

    assert(typePtr == &tkTextLeftMarkType || typePtr == &tkTextRightMarkType);

    markPtr->typePtr = typePtr;
    markPtr->startEndMarkFlag = 1;
    markPtr->privateMarkFlag = 1;
    markPtr->body.mark.textPtr = textPtr;
    return markPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextMakeMark --
 *
 *	Make (allocate) a new mark, the gravity default to right.
 *
 * Results:
 *	The return value is a pointer to the new mark.
 *
 * Side effects:
 *	A new mark is created.
 *
 *----------------------------------------------------------------------
 */

static TkTextSegment *
MakeMark(
    TkText *textPtr)		/* Text widget in which to create mark. */
{
    TkTextSegment *markPtr;

    markPtr = (TkTextSegment *)ckalloc(SEG_SIZE(TkTextMark));
    memset(markPtr, 0, SEG_SIZE(TkTextMark));
    NEW_SEGMENT(markPtr);
    markPtr->typePtr = &tkTextRightMarkType;
    markPtr->refCount = 1;
    markPtr->body.mark.textPtr = textPtr;
    DEBUG_ALLOC(tkTextCountNewSegment++);
    return markPtr;
}

TkTextSegment *
TkTextMakeMark(
    TkText *textPtr,		/* Text widget in which to create mark, can be NULL. */
    const char *name)		/* Name of this mark, can be NULL. */
{
    TkTextSegment *markPtr;
    Tcl_HashEntry *hPtr;
    int isNew;

    assert(!name || textPtr);
    assert(!name || strcmp(name, "insert") != 0);
    assert(!name || strcmp(name, "current") != 0);

    if (!name) {
	return MakeMark(textPtr);
    }

    hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->markTable, name, &isNew);

    if (isNew) {
	markPtr = MakeMark(textPtr);
	markPtr->body.mark.ptr = PTR_TO_INT(hPtr);
	Tcl_SetHashValue(hPtr, markPtr);
	textPtr->sharedTextPtr->numMarks += 1;
    } else {
	markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    }

    return markPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextMakeNewMark --
 *
 *	Make (allocate) a new mark, the gravity default to right. This
 *	function will return NULL if the mark name already exists.
 *
 * Results:
 *	The return value is a pointer to the new mark, and will be NULL
 *	if the mark already exists.
 *
 * Side effects:
 *	A new mark is created.
 *
 *----------------------------------------------------------------------
 */

TkTextSegment *
TkTextMakeNewMark(
    TkSharedText *sharedTextPtr,	/* Shared text resource. */
    const char *name)			/* Name of this mark. */
{
    TkTextSegment *markPtr;
    Tcl_HashEntry *hPtr;
    int isNew;

    assert(name);

    hPtr = Tcl_CreateHashEntry(&sharedTextPtr->markTable, name, &isNew);

    if (!isNew) {
	return NULL;
    }

    markPtr = MakeMark(NULL);
    markPtr->body.mark.ptr = PTR_TO_INT(hPtr);
    markPtr->normalMarkFlag = 1;
    Tcl_SetHashValue(hPtr, markPtr);
    sharedTextPtr->numMarks += 1;

    return markPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ChangeGravity --
 *
 *	Change the gravity of a given mark.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Reset the type pointer of the mark, and set the undo information.
 *
 *----------------------------------------------------------------------
 */

static TkTextMarkChange *
MakeChangeItem(
    TkSharedText *sharedTextPtr,
    TkTextSegment *markPtr)
{
    TkTextMarkChange *changePtr = markPtr->body.mark.changePtr;

    assert(TkTextIsNormalMark(markPtr));

    if (!changePtr) {
	if (sharedTextPtr->undoMarkListCount == sharedTextPtr->undoMarkListSize) {
	    sharedTextPtr->undoMarkListSize = MAX(20u, 2*sharedTextPtr->undoMarkListSize);
	    sharedTextPtr->undoMarkList = (TkTextMarkChange *)ckrealloc(sharedTextPtr->undoMarkList,
		    sharedTextPtr->undoMarkListSize * sizeof(sharedTextPtr->undoMarkList[0]));
	}
	changePtr = &sharedTextPtr->undoMarkList[sharedTextPtr->undoMarkListCount++];
	memset(changePtr, 0, sizeof(*changePtr));
	markPtr->body.mark.changePtr = changePtr;
	(changePtr->markPtr = markPtr)->refCount += 1;
    }

    return changePtr;
}

static TkTextUndoToken *
MakeUndoToggleGravity(
    TkSharedText *sharedTextPtr,
    TkTextSegment *markPtr,
    const Tk_SegType *oldTypePtr)
{
    assert(TkTextIsNormalMark(markPtr));

    sharedTextPtr->undoStackEvent = 1;

    if (!markPtr->body.mark.changePtr
	    || (!markPtr->body.mark.changePtr->setMark
		&& !markPtr->body.mark.changePtr->toggleGravity)) {
	TkTextMarkChange *changePtr = MakeChangeItem(sharedTextPtr, markPtr);
	UndoTokenToggleGravity *token;

	token = (UndoTokenToggleGravity *)ckalloc(sizeof(UndoTokenToggleGravity));
	memset(token, 0, sizeof(UndoTokenToggleGravity));
	token->undoType = &undoTokenToggleGravityType;
	(token->markPtr = markPtr)->refCount += 1;
	DEBUG_ALLOC(tkTextCountNewUndoToken++);
	changePtr->toggleGravity = (TkTextUndoToken *) token;
	changePtr->savedMarkType = oldTypePtr;
	sharedTextPtr->lastUndoTokenType = -1;
	return (TkTextUndoToken *) token;
    }

    return NULL;
}

static void
ChangeGravity(
    TkSharedText *sharedTextPtr,	/* Shared text resource. */
    TkText *textPtr,			/* The text widget, can be NULL. */
    TkTextSegment *markPtr,		/* Change toggle of this mark. */
    const Tk_SegType *newTypePtr,	/* This is the new toggle type. */
    TkTextUndoInfo *undoInfo)		/* Undo information, can be NULL */
{
    const Tk_SegType *oldTypePtr;
    int isNormalMark;

    assert(markPtr);
    assert(markPtr->typePtr->group == SEG_GROUP_MARK);
    assert(sharedTextPtr);
    assert(!undoInfo || TkTextIsNormalMark(markPtr));

    oldTypePtr = markPtr->typePtr;
    markPtr->typePtr = newTypePtr;
    isNormalMark = TkTextIsNormalMark(markPtr);

    if (!sharedTextPtr->steadyMarks) {
	if (!textPtr || markPtr != textPtr->insertMarkPtr) {
	    /*
	     * We must re-insert the mark, the old rules of gravity may force
	     * a shuffle of the existing marks.
	     */

	    TkTextIndex index;

	    if (textPtr) {
		TkTextIndexClear(&index, textPtr);
	    } else {
		TkTextIndexClear2(&index, NULL, sharedTextPtr->tree);
	    }
	    TkTextIndexSetSegment(&index, markPtr);
	    TkTextIndexToByteIndex(&index);
	    TkBTreeUnlinkSegment(sharedTextPtr, markPtr);
	    TkBTreeLinkSegment(sharedTextPtr, markPtr, &index);
	}

	if (isNormalMark) {
	    TkTextUpdateAlteredFlag(sharedTextPtr);
	}
    }

    if (undoInfo && isNormalMark) {
	undoInfo->token = MakeUndoToggleGravity(sharedTextPtr, markPtr, oldTypePtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UnsetMark --
 *
 *	Unset given mark.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Free some memory, and add a token to the undo/redo stack.
 *
 *----------------------------------------------------------------------
 */

static void
UnsetMark(
    TkSharedText *sharedTextPtr,
    TkTextSegment *markPtr,
    TkTextUndoInfo *redoInfo)
{
    assert(markPtr);
    assert(markPtr->typePtr->group == SEG_GROUP_MARK);
    assert(!TkTextIsSpecialMark(markPtr));
    assert(!TkTextIsPrivateMark(markPtr) || !redoInfo);

    if (redoInfo) {
	RedoTokenSetMark *token;
	TkTextMarkChange *changePtr;

	if ((changePtr = markPtr->body.mark.changePtr)) {
	    if (changePtr->toggleGravity) {
		TkTextUndoPushItem(sharedTextPtr->undoStack, changePtr->toggleGravity, 0);
		changePtr->toggleGravity = NULL;
	    }
	    if (changePtr->moveMark) {
		ckfree(changePtr->moveMark);
		changePtr->moveMark = NULL;
		DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
		assert(markPtr->refCount > 1);
		markPtr->refCount -= 1;
	    }
	    if (changePtr->setMark) {
		ckfree(changePtr->setMark);
		changePtr->setMark = NULL;
		DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
		assert(markPtr->refCount > 1);
		markPtr->refCount -= 1;
	    }
	}

	memset(redoInfo, 0, sizeof(*redoInfo));
	token = (RedoTokenSetMark *)ckalloc(sizeof(RedoTokenSetMark));
	token->undoType = &redoTokenSetMarkType;
	markPtr->refCount += 1;
	token->markPtr = markPtr;
	MARK_POINTER(token->markPtr);
	TkBTreeMakeUndoIndex(sharedTextPtr, markPtr, &token->index);
	DEBUG_ALLOC(tkTextCountNewUndoToken++);
	redoInfo->token = (TkTextUndoToken *) token;
	redoInfo->byteSize = 0;
    }

    sharedTextPtr->undoStackEvent = 1;
    sharedTextPtr->lastUndoTokenType = -1;
    TkBTreeUnlinkSegment(sharedTextPtr, markPtr);
    MarkDeleteProc(sharedTextPtr, markPtr, DELETE_CLEANUP);
}

/*
 *----------------------------------------------------------------------
 *
 * TriggerWatchCursor --
 *
 *	Trigger the watch command for movements of the insert cursor.
 *
 * Results:
 *	Returns 'false' if the referenced widget has been destroyed, otherwise
 *	'true' will be returned.
 *
 * Side effects:
 *	It might happen that the receiver of the "watch" command is destroying the widget.
 *
 *----------------------------------------------------------------------
 */

static int
TriggerWatchCursor(
    TkText *textPtr,
    const TkTextIndex *oldCursorIndexPtr,
    const TkTextIndex *newCursorIndexPtr)	/* NULL is allowed. */
{
    TkTextIndex index, newIndex;
    char idx[2][TK_POS_CHARS];
    TkTextTag *tagPtr;
    TkTextTag *tagArrayBuffer[32];
    TkTextTag **tagArrayPtr;
    unsigned tagArraySize;
    unsigned numTags, i;
    Tcl_DString buf;
    int rc;

    assert(oldCursorIndexPtr);
    assert(!TkTextIndexIsEmpty(oldCursorIndexPtr));
    assert(!newCursorIndexPtr || !TkTextIndexIsEmpty(newCursorIndexPtr));

    if (!newCursorIndexPtr) {
	TkTextIndexClear(&newIndex, textPtr);
	TkTextIndexSetSegment(&newIndex, textPtr->insertMarkPtr);
	newCursorIndexPtr = &newIndex;
    }

    if (TkTextIndexIsEqual(oldCursorIndexPtr, newCursorIndexPtr)) {
	return 1;
    }

    Tcl_DStringInit(&buf);
    if (TkTextIndexIsEmpty(oldCursorIndexPtr)) {
	idx[0][0] = '\0';
    } else {
	TkrTextPrintIndex(textPtr, oldCursorIndexPtr, idx[0]);
    }
    TkrTextPrintIndex(textPtr, newCursorIndexPtr, idx[1]);
    if (textPtr->insertMarkPtr->typePtr == &tkTextLeftMarkType) {
	index = *newCursorIndexPtr;
    } else {
	TkTextIndexBackChars(textPtr, newCursorIndexPtr, 1, &index, COUNT_INDICES);
    }

    numTags = 0;
    tagArrayPtr = tagArrayBuffer;
    tagArraySize = sizeof(tagArrayBuffer)/sizeof(tagArrayBuffer[0]);
    tagPtr = TkBTreeGetTags(&index, TK_TEXT_SORT_ASCENDING, NULL);
    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (numTags == tagArraySize) {
	    tagArraySize *= 2;
	    tagArrayPtr = (TkTextTag **)ckrealloc(tagArrayPtr == tagArrayBuffer ? NULL : tagArrayPtr, tagArraySize);
	}
	tagArrayPtr[numTags++] = tagPtr;
    }
    for (i = 0; i < numTags; ++i) {
	Tcl_DStringAppendElement(&buf, tagArrayPtr[i]->name);
    }
    if (tagArrayPtr != tagArrayBuffer) {
	ckfree(tagArrayPtr);
    }

    rc = TkTextTriggerWatchCmd(textPtr, "cursor", idx[0], idx[1], Tcl_DStringValue(&buf),
	    NULL, NULL, 0);
    Tcl_DStringFree(&buf);
    return rc;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextReleaseUndoMarkTokens --
 *
 *	Release retained undo tokens for mark operations.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Free some memory.
 *
 *----------------------------------------------------------------------
 */

void
TkTextReleaseUndoMarkTokens(
    TCL_UNUSED(TkSharedText *),
    TkTextMarkChange *changePtr)
{
    assert(changePtr);

    if (!changePtr->markPtr) {
	return; /* already released */
    }

    assert(changePtr->markPtr->body.mark.changePtr);

    if (changePtr->toggleGravity) {
	ckfree(changePtr->toggleGravity);
	changePtr->toggleGravity = NULL;
	DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	assert(changePtr->markPtr->refCount > 1);
	changePtr->markPtr->refCount -= 1;
    }
    if (changePtr->moveMark) {
	ckfree(changePtr->moveMark);
	changePtr->moveMark = NULL;
	DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	assert(changePtr->markPtr->refCount > 1);
	changePtr->markPtr->refCount -= 1;
    }
    if (changePtr->setMark) {
	ckfree(changePtr->setMark);
	changePtr->setMark = NULL;
	DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	assert(changePtr->markPtr->refCount > 1);
	changePtr->markPtr->refCount -= 1;
    }

    assert(changePtr->markPtr->refCount > 1);
    changePtr->markPtr->refCount -= 1;
    changePtr->markPtr->body.mark.changePtr = NULL;
    changePtr->markPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextPushUndoMarkTokens --
 *
 *	Push retained undo tokens for mark operations onto the undo stack.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Same as TkTextUndoPushItem.
 *
 *----------------------------------------------------------------------
 */

void
TkTextPushUndoMarkTokens(
    TkSharedText *sharedTextPtr,
    TkTextMarkChange *changePtr)
{
    assert(sharedTextPtr);
    assert(sharedTextPtr->undoStack);
    assert(changePtr);
    assert(changePtr->markPtr);
    assert(changePtr->markPtr->body.mark.changePtr == changePtr);

    if (changePtr->toggleGravity) {
	UndoTokenToggleGravity *token = (UndoTokenToggleGravity *) changePtr->toggleGravity;

	if (changePtr->savedMarkType != token->markPtr->typePtr) {
	    TkTextUndoPushItem(sharedTextPtr->undoStack, (TkTextUndoToken *) token, 0);
	} else {
	    ckfree(token);
	    DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	    assert(changePtr->markPtr->refCount > 1);
	    changePtr->markPtr->refCount -= 1;
	}
	changePtr->toggleGravity = NULL;
    }
    if (changePtr->moveMark) {
	TkTextUndoPushItem(sharedTextPtr->undoStack, changePtr->moveMark, 0);
	changePtr->moveMark = NULL;
    }
    if (changePtr->setMark) {
	TkTextUndoPushItem(sharedTextPtr->undoStack, changePtr->setMark, 0);
	changePtr->setMark = NULL;
    }

    assert(changePtr->markPtr->refCount > 1);
    changePtr->markPtr->refCount -= 1;
    changePtr->markPtr->body.mark.changePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkrTextSetMark -- SetMark --
 *
 *	Set a mark to a particular position, creating a new mark if one
 *	doesn't already exist.
 *
 *	Take care when setting the "insert" mark. In this case it might
 *	happen that the receiver of the "watch" command is destroying the
 *	widget. In this case this function will return NULL (otherwise
 *	this function will always return non-NULL in case of setting the
 *	"insert" mark).
 *
 *	Note that parameter indexPtr may be adjusted if the position
 *	is outside of visible text, and we are setting the "insert"
 *	mark.
 *
 * Results:
 *	The return value is a pointer to the mark that was just set.
 *
 * Side effects:
 *	A new mark is created, or an existing mark is moved.
 *
 *----------------------------------------------------------------------
 */

static TkTextSegment *
SetMark(
    TkText *textPtr,		/* Text widget in which to create mark. */
    const char *name,		/* Name of mark to set. */
    const Tk_SegType *typePtr,	/* Sepcifies the gravity, either tkTextLeftMarkType,
    				 * tkTextRightMarkType, or NULL. */
    TkTextIndex *indexPtr)	/* Where to set mark. */
{
    Tcl_HashEntry *hPtr = NULL;
    TkSharedText *sharedTextPtr;
    TkTextSegment *markPtr;
    TkTextIndex oldIndex;
    TkTextUndoIndex undoIndex;
    int pushUndoToken;
    int widgetSpecific;
    const Tk_SegType *oldTypePtr = NULL;

    assert(textPtr);
    assert(indexPtr->textPtr == textPtr);

    widgetSpecific = 0;
    markPtr = NULL;

    switch (*name) {
    case 'i':
	if (strcmp(name, "insert") == 0) {
	    widgetSpecific = 1;
	    markPtr = textPtr->insertMarkPtr;

	    if (TkTextIsElided(indexPtr)) {
		TkTextSkipElidedRegion(indexPtr);
	    }
	}
	break;
    case 'c':
	if (strcmp(name, "current") == 0) {
	    widgetSpecific = 1;
	    markPtr = textPtr->currentMarkPtr;
	}
	break;
    }

    sharedTextPtr = textPtr->sharedTextPtr;
    TkTextIndexClear(&oldIndex, textPtr);

    if (!widgetSpecific) {
	int dummy;
	hPtr = Tcl_CreateHashEntry(&sharedTextPtr->markTable, name, &dummy);

	markPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    }

    if (!markPtr) {
	if (name[0] == '#' && name[1] == '#' && name[2] == 'I') {
#ifdef TK_IS_64_BIT_ARCH
	    static const size_t length = 32 + 2*sizeof(uint64_t);
#else /* if !defined(TK_IS_64_BIT_ARCH) */
	    static const size_t length = 32 + 2*sizeof(uint32_t);
#endif /* TK_IS_64_BIT_ARCH */

	    void *sPtr, *tPtr;
	    unsigned num;

	    if (strlen(name) == length && sscanf(name, "##ID##%p##%p##%u##", &sPtr, &tPtr, &num) == 3) {
		assert(hPtr);
		Tcl_DeleteHashEntry(hPtr);
		return NULL; /* this is an expired generated mark */
	    }
	}

	if (widgetSpecific) {
	    /*
	     * This is a special mark.
	     */
	    markPtr = MakeMark(textPtr);
	    if (*name == 'i') { /* "insert" */
		textPtr->insertMarkPtr = markPtr;
		markPtr->insertMarkFlag = 1;
	    } else { /* "current" */
		textPtr->currentMarkPtr = markPtr;
		markPtr->currentMarkFlag = 1;
	    }
	    pushUndoToken = 0;
	} else {
	    markPtr = MakeMark(NULL);
	    markPtr->body.mark.ptr = PTR_TO_INT(hPtr);
	    markPtr->normalMarkFlag = 1;
	    Tcl_SetHashValue(hPtr, markPtr);
	    textPtr->sharedTextPtr->numMarks += 1;
	    pushUndoToken = sharedTextPtr->steadyMarks && sharedTextPtr->undoStack;
	}
    } else {
	const TkTextSegment *segPtr;

	TkTextMarkSegToIndex(textPtr, markPtr, &oldIndex);

	if (markPtr == textPtr->insertMarkPtr && TkTextIndexIsEndOfText(indexPtr)) {
	    /*
	     * The index is outside of visible text, so backup one char.
	     */
	    TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr, COUNT_INDICES);
	}

	if (!sharedTextPtr->steadyMarks
		&& (!typePtr || typePtr == markPtr->typePtr)
		&& TkTextIndexIsEqual(&oldIndex, indexPtr)) {
	    return markPtr; /* this mark did not change the position */
	}

	TkTextIndexToByteIndex(&oldIndex);
	pushUndoToken = sharedTextPtr->steadyMarks
		&& sharedTextPtr->undoStack
		&& TkTextIsNormalMark(markPtr);

	/*
	 * If this is the insertion point that's being moved, be sure to force
	 * a display update at the old position. Also, don't let the insertion
	 * cursor be after the final newline of the file.
	 */

	if (markPtr == textPtr->insertMarkPtr) {
	    TkTextIndex index2;



	    TkTextIndexToByteIndex(indexPtr);

	    if (textPtr->state == TK_TEXT_STATE_NORMAL) {
		/*
		 * Test whether cursor is inside the actual range.
		 */
		if (TkTextIndexRestrictToStartRange(&oldIndex) >= 0
			&& TkTextIndexRestrictToEndRange(&oldIndex) <= 0
			&& TkTextIndexForwChars(textPtr, &oldIndex, 1, &index2, COUNT_INDICES)) {
		    /*
		     * While we wish to redisplay, no heights have changed, so no need
		     * to call TkTextInvalidateLineMetrics.
		     */



		    /*
		     * TODO: this will do too much, but currently the implementation
		     * lacks on an efficient redraw functionality especially designed
		     * for cursor updates.



		     */
		    TkrTextChanged(NULL, textPtr, &oldIndex, &index2);
		}
	    }
	} else if (markPtr == textPtr->currentMarkPtr) {
	    textPtr->haveToSetCurrentMark = 0;
	} else if (pushUndoToken) {
	    TkBTreeMakeUndoIndex(sharedTextPtr, markPtr, &undoIndex);
	}

	if ((segPtr = TkTextIndexGetSegment(indexPtr)) == markPtr) {
	    return markPtr;
	}

	if (segPtr && segPtr->size > 1) {
	    /* because TkBTreeUnlinkSegment may invalidate this index */
	    TkTextIndexToByteIndex(indexPtr);
	}

	TkBTreeUnlinkSegment(sharedTextPtr, markPtr);
    }

    if (typePtr && typePtr != markPtr->typePtr) {
	oldTypePtr = markPtr->typePtr;
	markPtr->typePtr = typePtr;
    }

    /* this function will also update 'sectionPtr' */
    TkBTreeLinkSegment(sharedTextPtr, markPtr, indexPtr);

    if (pushUndoToken) {
	TkTextMarkChange *changePtr;

	changePtr = MakeChangeItem(sharedTextPtr, markPtr);

	if (!changePtr->setMark && !changePtr->moveMark) {
	    if (TkTextIndexIsEmpty(&oldIndex)) {
		UndoTokenSetMark *token;

		token = (UndoTokenSetMark *)ckalloc(sizeof(UndoTokenSetMark));
		token->undoType = &undoTokenSetMarkType;
		(token->markPtr = markPtr)->refCount += 1;
		DEBUG_ALLOC(tkTextCountNewUndoToken++);
		changePtr->setMark = (TkTextUndoToken *) token;
		sharedTextPtr->undoStackEvent = 1;
		sharedTextPtr->lastUndoTokenType = -1;
		oldTypePtr = NULL;
	    } else {
		UndoTokenMoveMark *token;

		token = (UndoTokenMoveMark *)ckalloc(sizeof(UndoTokenMoveMark));
		token->undoType = &undoTokenMoveMarkType;
		(token->markPtr = markPtr)->refCount += 1;
		token->index = undoIndex;
		DEBUG_ALLOC(tkTextCountNewUndoToken++);
		changePtr->moveMark = (TkTextUndoToken *) token;
		sharedTextPtr->undoStackEvent = 1;



		sharedTextPtr->lastUndoTokenType = -1;
	    }
	}

	if (oldTypePtr) {
	    MakeUndoToggleGravity(sharedTextPtr, markPtr, oldTypePtr);
	}
    }

    if (sharedTextPtr->steadyMarks && TkTextIsNormalMark(markPtr)) {
	TkTextUpdateAlteredFlag(sharedTextPtr);
    }

    if (textPtr->state == TK_TEXT_STATE_NORMAL) {
	/*
	 * If the mark is the insertion cursor, then update the screen at the mark's new location.

	 */

	if (markPtr == textPtr->insertMarkPtr) {
	    TkTextIndex index2;

	    TkTextIndexForwChars(textPtr, indexPtr, 1, &index2, COUNT_INDICES);

	    /*
	     * While we wish to redisplay, no heights have changed, so no need to
	     * call TkTextInvalidateLineMetrics.
	     */

	    /* TODO: this is very inefficient, it would be more appopriate to trigger
	     * a special cursor redraw function (see DisplayDLine in tkTextDisp).
	     * Instead of inserting a cursor chunk (not needed) we want to overlay
	     * with a cursor. This would speed up cursor movement.
	     */

	    TkrTextChanged(NULL, textPtr, indexPtr, &index2);

	    /*
	     * Finally trigger the "watch" command for the "insert" cursor,
	     * this must be the last action.
	     */

	    if (textPtr->watchCmd && !TriggerWatchCursor(textPtr, &oldIndex, indexPtr)) {
		return NULL; /* the receiver did destroy the widget */
	    }
	}
    }

    return markPtr;
}

TkTextSegment *
TkrTextSetMark(
    TkText *textPtr,		/* Text widget in which to create mark. */
    const char *name,		/* Name of mark to set. */
    TkTextIndex *indexPtr)	/* Where to set mark. */
{
    return SetMark(textPtr, name, NULL, indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextUnsetMark --
 *
 *	Unset (delete) given mark.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A mark will be deleted.
 *
 *----------------------------------------------------------------------
 */

void
TkTextUnsetMark(
    TkText *textPtr,		/* Text widget in which to create mark. */
    TkTextSegment *markPtr)	/* Delete this mark. */
{
    TkTextUndoInfo undoInfo;
    TkTextUndoInfo *undoInfoPtr = NULL;
    int isNormalMark = TkTextIsNormalMark(markPtr);

    assert(TkTextIsNormalMark(markPtr));

    if (isNormalMark
	    && textPtr->sharedTextPtr->steadyMarks
	    && !TkTextUndoUndoStackIsFull(textPtr->sharedTextPtr->undoStack)) {
	undoInfoPtr = &undoInfo;
    }
    UnsetMark(textPtr->sharedTextPtr, markPtr, undoInfoPtr);
    if (isNormalMark) {
	if (undoInfoPtr && undoInfo.token) {
	    TkTextPushUndoToken(textPtr->sharedTextPtr, undoInfo.token, 0);
	}
	if (textPtr->sharedTextPtr->steadyMarks) {
	    TkTextUpdateAlteredFlag(textPtr->sharedTextPtr);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextSaveCursorIndex --
 *
 *	Save the current position of the insert cursor, but only if
 *	it is not yet saved. Use this function only if a trigger of
 *	the "watch" command is wanted in case of cursor movement.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextSaveCursorIndex(
    TkText *textPtr)
{
    if (TkTextIndexIsEmpty(&textPtr->insertIndex)) {
	TkTextIndexSetSegment(&textPtr->insertIndex, textPtr->insertMarkPtr);
	TkTextIndexSave(&textPtr->insertIndex);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTriggerWatchCursor --
 *
 *	Trigger the watch command for movements of the insert cursor.
 *
 * Results:
 *	Returns 'false' if the referenced widget has been destroyed, otherwise
 *	'true' will be returned.
 *
 * Side effects:
 *	It might happen that the receiver of the "watch" command is destroying the widget.
 *
 *----------------------------------------------------------------------
 */

int
TkTextTriggerWatchCursor(
    TkText *textPtr)
{
    assert(textPtr->watchCmd);

    if (TkTextIndexIsEmpty(&textPtr->insertIndex)) {
	return 1;
    }

    TkTextIndexRebuild(&textPtr->insertIndex);
    return TriggerWatchCursor(textPtr, &textPtr->insertIndex, NULL);
}

/*
 *--------------------------------------------------------------
 *
 * TkTextMarkSegToIndex --
 *
382
383
384
385
386
387
388
389
390
391
392
393


394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

















429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461







462






463





















464
465
466
467
468
469
470
471
472





473











474


475
476
477




478


479


480


481
482
483
484
485
486
487
488
489
490
491
492
493



494
495
496
497


498
499
500
501
502
503

504



505




506















507



508

509





































































































510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531

532






















533




534










535







536





























537
538
539
540
541
542
543
 *	None.
 *
 *--------------------------------------------------------------
 */

void
TkTextMarkSegToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    TkTextSegment *markPtr,	/* Mark segment. */
    TkTextIndex *indexPtr)	/* Index information gets stored here.  */
{
    TkTextSegment *segPtr;



    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = markPtr->body.mark.linePtr;

    indexPtr->byteIndex = 0;
    for (segPtr = indexPtr->linePtr->segPtr; segPtr != markPtr;
	    segPtr = segPtr->nextPtr) {
	indexPtr->byteIndex += segPtr->size;
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextMarkNameToIndex --
 *
 *	Given the name of a mark, return an index corresponding to the mark
 *	name.
 *
 * Results:
 *	The return value is TCL_OK if "name" exists as a mark in the text
 *	widget and is located within its -starline/-endline range. In this
 *	case *indexPtr is filled in with the next segment who is after the
 *	mark whose size is non-zero. TCL_ERROR is returned if the mark
 *	doesn't exist in the text widget, or if it is out of its -starline/
 *	-endline range. In this latter case *indexPtr still contains valid
 *	information, in particular TkTextMarkNameToIndex called with the
 *	"insert" or "current" mark name may return TCL_ERROR, but *indexPtr
 *	contains the correct index of this mark before -startline or after
 *	-endline.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


















int
TkTextMarkNameToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    const char *name,		/* Name of mark. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    TkTextSegment *segPtr;
    TkTextIndex index;
    int start, end;

    if (textPtr == NULL) {
        return TCL_ERROR;
    }

    if (!strcmp(name, "insert")) {
	segPtr = textPtr->insertMarkPtr;
    } else if (!strcmp(name, "current")) {
	segPtr = textPtr->currentMarkPtr;
    } else {
	Tcl_HashEntry *hPtr =
		Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);

	if (hPtr == NULL) {
	    return TCL_ERROR;
	}
	segPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    }

    TkTextMarkSegToIndex(textPtr, segPtr, indexPtr);

    /* If indexPtr refers to somewhere outside the -startline/-endline
     * range limits of the widget, error out since the mark indeed is not
     * reachable from this text widget (it may be reachable from a peer)







     * (bug 1630271).






     */






















    if (textPtr->start != NULL) {
	start = TkBTreeLinesTo(NULL, textPtr->start);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
		&index);
	if (TkTextIndexCmp(indexPtr, &index) < 0) {
	    return TCL_ERROR;
	}
    }





    if (textPtr->end != NULL) {











	end = TkBTreeLinesTo(NULL, textPtr->end);


	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,
		&index);
	if (TkTextIndexCmp(indexPtr, &index) > 0) {




	    return TCL_ERROR;


	}


    }


    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MarkDeleteProc --
 *
 *	This function is invoked by the text B-tree code whenever a mark lies
 *	in a range of characters being deleted.
 *
 * Results:
 *	Returns 1 to indicate that deletion has been rejected.



 *
 * Side effects:
 *	None (even if the whole tree is being deleted we don't free up the
 *	mark; it will be done elsewhere).


 *
 *--------------------------------------------------------------
 */

static int
MarkDeleteProc(

    TCL_UNUSED(TkTextSegment *),	/* Segment being deleted. */



    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */




    TCL_UNUSED(int))		/* Non-zero means the entire tree is being















				 * deleted, so everything must get cleaned



				 * up. */

{





































































































    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * MarkCleanupProc --
 *
 *	This function is invoked by the B-tree code whenever a mark segment is
 *	moved from one line to another.
 *
 * Results:
 *	None.
 *
 * Side effects:

 *	The linePtr field of the segment gets updated.
 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
MarkCleanupProc(

    TkTextSegment *markPtr,	/* Mark segment that's being moved. */






















    TkTextLine *linePtr)	/* Line that now contains segment. */




{










    markPtr->body.mark.linePtr = linePtr;







    return markPtr;





























}

/*
 *--------------------------------------------------------------
 *
 * MarkLayoutProc --
 *







|



|
>
>

|
<
>
|
<
<
|
<











|
|

|
|
|


|
|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<
<

|
<
|
<
|

|


<
|


|



>
|
|
|
<
<
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
<
<
<
|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
<
|
>
>
>
>
|
>
>
|
>
>
|
>
>
|








|


|
>
>
>


|
|
>
>






>
|
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|

|
|





>
|




|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
 *	None.
 *
 *--------------------------------------------------------------
 */

void
TkTextMarkSegToIndex(
    TkText *textPtr,		/* Text widget containing mark, can be NULL. */
    TkTextSegment *markPtr,	/* Mark segment. */
    TkTextIndex *indexPtr)	/* Index information gets stored here.  */
{
    assert(textPtr);
    assert(markPtr);
    assert(markPtr->sectionPtr); /* otherwise not linked */

    TkTextIndexClear(indexPtr, textPtr);

    /* disable range checks, because here it's is allowed that the index is out of range. */
    DEBUG(indexPtr->discardConsistencyCheck = 1);


    TkTextIndexSetSegment(indexPtr, markPtr);

}

/*
 *--------------------------------------------------------------
 *
 * TkTextMarkNameToIndex --
 *
 *	Given the name of a mark, return an index corresponding to the mark
 *	name.
 *
 * Results:
 *	The return value is 'true' if "name" exists as a mark in the text
 *	widget and is located within its -start/-end range. In this
 *	case *indexPtr is filled in with the next segment who is after the
 *	mark whose size is non-zero. 'false' is returned if the mark
 *	doesn't exist in the text widget, or if it is out of its -start/
 *	-end range. In this latter case *indexPtr still contains valid
 *	information, in particular TkTextMarkNameToIndex called with the
 *	"insert" or "current" mark name may return TCL_ERROR, but *indexPtr
 *	contains the correct index of this mark before -start or after
 *	-end.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
MarkToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    TkTextSegment *markPtr,	/* Pointer to mark segment. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    assert(textPtr);
    TkTextMarkSegToIndex(textPtr, markPtr, indexPtr);
    indexPtr->textPtr = textPtr;

    if (TkTextIndexOutsideStartEnd(indexPtr)) {
	return 0;
    }

    return 1;
}

int
TkTextMarkNameToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    const char *name,		/* Name of mark. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    TkTextSegment *segPtr;



    assert(textPtr);



    if (strcmp(name, "insert") == 0) {
	segPtr = textPtr->insertMarkPtr;
    } else if (strcmp(name, "current") == 0) {
	segPtr = textPtr->currentMarkPtr;
    } else {

	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);

	if (hPtr == NULL) {
	    return 0;
	}
	segPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    }

    return MarkToIndex(textPtr, segPtr, indexPtr);
}



/*
 *----------------------------------------------------------------------
 *
 * TkTextInspectUndoMarkItem --
 *
 *	Inspect retained undo token.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is allocated for the result.
 *
 *----------------------------------------------------------------------
 */

void
TkTextInspectUndoMarkItem(
    const TkSharedText *sharedTextPtr,
    const TkTextMarkChange *changePtr,
    Tcl_Obj* objPtr)
{
    assert(changePtr);

    if (changePtr->setMark) {
	Tcl_ListObjAppendElement(NULL, objPtr,
		changePtr->setMark->undoType->inspectProc(sharedTextPtr, changePtr->setMark));
    }
    if (changePtr->moveMark) {
	Tcl_ListObjAppendElement(NULL, objPtr,
		changePtr->moveMark->undoType->inspectProc(sharedTextPtr, changePtr->moveMark));
    }
    if (changePtr->toggleGravity) {
	Tcl_ListObjAppendElement(NULL, objPtr,
		changePtr->toggleGravity->undoType->inspectProc(sharedTextPtr,
		changePtr->toggleGravity));
    }






}

/*
 *--------------------------------------------------------------
 *
 * MarkInspectProc --
 *
 *	This function is invoked to build the information for
 *	"inspect".
 *
 * Results:
 *	Return a TCL object containing the information for
 *	"inspect".
 *
 * Side effects:
 *	Storage is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
MarkInspectProc(
    const TkSharedText *sharedTextPtr,

    const TkTextSegment *segPtr)
{
    Tcl_Obj *objPtr = Tcl_NewObj();
    const char *gravity = (segPtr->typePtr == &tkTextLeftMarkType) ? "left" : "right";
    const char *name;

    assert(!TkTextIsPrivateMark(segPtr));
    assert(!IS_PRESERVED(segPtr));

    name = TkTextMarkName(sharedTextPtr, NULL, segPtr);
    assert(name);

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(gravity, TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(name, TCL_INDEX_NONE));
    return objPtr;
}

/*
 *--------------------------------------------------------------
 *
 * MarkDeleteProc --
 *
 *	This function is invoked by the text B-tree code whenever a mark lies
 *	in a range being deleted.
 *
 * Results:
 *	Returns false to indicate that deletion has been rejected. Otherwise, if
 *	deletion has been done (virtually) because DELETE_MARKS is set, true
 *	will be returned. If the reference count of this segment is not going
 *	to zero then this segment will be preserved for undo.
 *
 * Side effects:
 *	None when this functions returns false (even if the whole tree is being
 *	deleted we don't free up the mark; it will be done elsewhere). But
 *	if a deletion has been done the hash entry of this mark will be
 *	removed.
 *
 *--------------------------------------------------------------
 */

static int
MarkDeleteProc(
    TkSharedText *sharedTextPtr,/* Handle to shared text resource. */
    TkTextSegment *segPtr,	/* Segment being deleted. */
    int flags)			/* The deletion flags. */
{
    assert(segPtr->refCount > 0);

    if (TkTextIsSpecialMark(segPtr)) {
	assert(!segPtr->body.mark.changePtr);
	return 0;
    }

    if (TkTextIsPrivateMark(segPtr)) {
	assert(!segPtr->body.mark.changePtr);
	if (!(flags & DELETE_CLEANUP)) {
	    return 0;
	}
	if (--segPtr->refCount == 0) {
	    DEBUG(segPtr->body.mark.changePtr = (void *) 0xdeadbeef);
	    if (!(flags & TREE_GONE)) {
		Tcl_DeleteHashEntry(GET_HPTR(segPtr));
	    }
	    FREE_SEGMENT(segPtr);
	    DEBUG_ALLOC(tkTextCountDestroySegment++);
	}
	return 1;
    }

    if (!(flags & (DELETE_CLEANUP|DELETE_MARKS|TREE_GONE))) {
	return 0;
    }

    assert(segPtr->body.mark.ptr);

    if (segPtr->body.mark.changePtr) {
	unsigned index;

	assert(sharedTextPtr->steadyMarks);
	index = segPtr->body.mark.changePtr - sharedTextPtr->undoMarkList;
	TkTextReleaseUndoMarkTokens(sharedTextPtr, segPtr->body.mark.changePtr);
	memmove(sharedTextPtr->undoMarkList + index, sharedTextPtr->undoMarkList + index + 1,
		--sharedTextPtr->undoMarkListCount - index);
	assert(!segPtr->body.mark.changePtr);
    }

    if (--segPtr->refCount == 0) {
	if (IS_PRESERVED(segPtr)) {
	    assert(sharedTextPtr->steadyMarks);
	    ckfree(GET_NAME(segPtr));
	} else {
	    Tcl_DeleteHashEntry(GET_HPTR(segPtr));
	    sharedTextPtr->numMarks -= 1;
	}
	DEBUG(segPtr->body.mark.changePtr = (void *) 0xdeadbeef);
	FREE_SEGMENT(segPtr);
	DEBUG_ALLOC(tkTextCountDestroySegment++);
    } else if (!IS_PRESERVED(segPtr)) {
	if (sharedTextPtr->steadyMarks) {
	    /*
	     * This case should only happen if this mark belongs to undo/redo stack.
	     * We have to preserve the mark if not already preserved.
	     */

	    Tcl_HashEntry *hPtr = GET_HPTR(segPtr);
	    const char *name = (const char *)Tcl_GetHashKey(&sharedTextPtr->markTable, hPtr);
	    size_t size = strlen(name) + 1;

	    assert(sharedTextPtr->steadyMarks);
	    segPtr->body.mark.ptr = PTR_TO_INT(memcpy(ckalloc(size), name, size));
	    MAKE_PRESERVED(segPtr);
	    Tcl_DeleteHashEntry(hPtr);
	    sharedTextPtr->numMarks -= 1;
	} else {
	    /*
	     * It seems that we have a bug with reference counting. So print a warning
	     * and delete it anyway.
	     */

	    fprintf(stderr, "reference count of mark '%s' is %d (should be zero)\n",
		    TkTextMarkName(sharedTextPtr, NULL, segPtr), segPtr->refCount);
	    Tcl_DeleteHashEntry(GET_HPTR(segPtr));
	    sharedTextPtr->numMarks -= 1;
	    FREE_SEGMENT(segPtr);
	    DEBUG_ALLOC(tkTextCountDestroySegment++);
	}
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * MarkRestoreProc --
 *
 *	This function is called when a mark segment will be resused
 *	from the undo chain. But a re-use is possible only if option
 *	-steadymarks is enabled, otherwise the segment will be
 *	deleted instead if this is a preserved mark.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Either the name of the mark will be freed, and the mark
 *	will be re-entered into the hash table, or it will be
 *	deleted.
 *
 *--------------------------------------------------------------
 */

static int
MarkRestoreProc(
    TkSharedText *sharedTextPtr,/* Handle to shared text resource. */
    TkTextSegment *segPtr)	/* Segment to restore. */
{
    assert(TkTextIsNormalMark(segPtr));

    if (IS_PRESERVED(segPtr)) {
	Tcl_HashEntry *hPtr;
	int isNew;

	if (!sharedTextPtr->steadyMarks) {
	    MarkDeleteProc(sharedTextPtr, segPtr, DELETE_CLEANUP);
	    return 0;
	}

	hPtr = Tcl_CreateHashEntry(&sharedTextPtr->markTable, GET_NAME(segPtr), &isNew);
	assert(isNew);
	Tcl_SetHashValue(hPtr, segPtr);
	sharedTextPtr->numMarks += 1;
	ckfree(GET_NAME(segPtr));
	segPtr->body.mark.ptr = PTR_TO_INT(hPtr);
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * MarkCheckProc --
 *
 *	This function is invoked by the B-tree code to perform consistency
 *	checks on mark segments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The function panics if it detects anything wrong with
 *	the mark.
 *
 *--------------------------------------------------------------
 */

static void
MarkCheckProc(
    const TkSharedText *sharedTextPtr,	/* Handle to shared text resource. */
    const TkTextSegment *markPtr)	/* Segment to check. */
{
    if (!markPtr->nextPtr) {
	Tcl_Panic("MarkCheckProc: mark is last segment in line");
    }
    if (markPtr->size != 0) {
	Tcl_Panic("MarkCheckProc: mark has size %d", markPtr->size);
    }
    if (!markPtr->insertMarkFlag
	    && !markPtr->currentMarkFlag
	    && !markPtr->privateMarkFlag
	    && !markPtr->normalMarkFlag) {
	Tcl_Panic("MarkCheckProc: mark is not specialized");
    }
    if (markPtr->insertMarkFlag +
	    markPtr->currentMarkFlag +
	    markPtr->privateMarkFlag +
	    markPtr->normalMarkFlag > 1) {
	Tcl_Panic("MarkCheckProc: mark has more than one specialization");
    }
    if (markPtr->startEndMarkFlag && !markPtr->privateMarkFlag) {
	Tcl_Panic("MarkCheckProc: start/end marks have to be private");
    }

    if (markPtr->body.mark.changePtr) {
	/*
	 * Private marks and special marks will not have undo/redo data.
	 */

	if (TkTextIsSpecialOrPrivateMark(markPtr)) {
	    Tcl_Panic("MarkCheckProc: private/special marks should not have undo/redo data");
	}
    }

    /*
     * The special marks ("insert", "current") are not in the hash table,
     * the same with the start/end markers.
     */

    if (markPtr->body.mark.ptr) {
	if (IS_PRESERVED(markPtr)) {
	    if (!sharedTextPtr->steadyMarks) {
		Tcl_Panic("MarkCheckProc: preserved mark detected, though we don't have steady marks");
	    }
	    else
	    {
		Tcl_Panic("MarkCheckProc: detected preserved mark '%s' outside of the undo chain",
			GET_NAME(markPtr));
	    }
	} else {
	    void *hPtr;
	    hPtr = Tcl_GetHashKey(&sharedTextPtr->markTable, (Tcl_HashEntry *) markPtr->body.mark.ptr);
	    if (!hPtr) {
		Tcl_Panic("MarkCheckProc: couldn't find hash table entry for mark");
	    }
	}
    } else if (!markPtr->insertMarkFlag && !markPtr->currentMarkFlag && !markPtr->startEndMarkFlag) {
	Tcl_Panic("MarkCheckProc: mark is not in hash table, though it's not a special mark");
    }

    if (markPtr->startEndMarkFlag) {
	if (markPtr->typePtr == &tkTextLeftMarkType) {
	    if (markPtr->prevPtr
		    && markPtr->prevPtr->typePtr->group == SEG_GROUP_MARK
		    && (!markPtr->prevPtr->startEndMarkFlag
			|| markPtr->prevPtr->typePtr != &tkTextLeftMarkType)) {
		Tcl_Panic("MarkCheckProc: start marker must be leftmost mark");
	    }
	} else {
	    if (markPtr->nextPtr
		    && markPtr->nextPtr->typePtr->group == SEG_GROUP_MARK
		    && (!markPtr->nextPtr->startEndMarkFlag
			|| markPtr->nextPtr->typePtr != &tkTextRightMarkType)) {
		Tcl_Panic("MarkCheckProc: end marker must be rightmost mark");
	    }
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * MarkLayoutProc --
 *
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574


575

576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603






































































































































































604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660






661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

static int
MarkLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *segPtr,	/* Segment corresponding to indexPtr. */
    TCL_UNUSED(TkSizeT),		/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    TCL_UNUSED(int),			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TCL_UNUSED(TkSizeT),		/* Chunk must not include more than this many
				 * characters. */
    TCL_UNUSED(int),		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Not used. */
    TkTextDispChunk *chunkPtr)
				/* Structure to fill in with information about
				 * this chunk. The x field has already been


				 * set by the caller. */

{
    if (segPtr != textPtr->insertMarkPtr) {
	return -1;
    }

    chunkPtr->displayProc = TkTextInsertDisplayProc;
    chunkPtr->undisplayProc = InsertUndisplayProc;
    chunkPtr->measureProc = NULL;
    chunkPtr->bboxProc = NULL;
    chunkPtr->numBytes = 0;
    chunkPtr->minAscent = 0;
    chunkPtr->minDescent = 0;
    chunkPtr->minHeight = 0;
    chunkPtr->width = 0;

    /*
     * Note: can't break a line after the insertion cursor: this prevents the
     * insertion cursor from being stranded at the end of a line.
     */

    chunkPtr->breakIndex = -1;
    chunkPtr->clientData = textPtr;
    return 1;
}

/*
 *--------------------------------------------------------------
 *






































































































































































 * TkTextInsertDisplayProc --
 *
 *	This function is called to display the insertion cursor.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */

void
TkTextInsertDisplayProc(
    TkText *textPtr,		/* The current text widget. */
    TCL_UNUSED(TkTextDispChunk *),	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (may differ from the x-position in
				 * the chunk because of scrolling). */
    int y,			/* Y-position at which to draw this chunk in
				 * dst (x-position is in the chunk itself). */
    int height,			/* Total height of line. */
    TCL_UNUSED(int),		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),		/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw chunk. */
    int screenY)		/* Y-coordinate in text window that
				 * corresponds to y. */
{
    /*
     * We have no need for the clientData.
     */

    /* TkText *textPtr = chunkPtr->clientData; */
    TkTextIndex index;
    int halfWidth = textPtr->insertWidth/2;
    int rightSideWidth;
    int ix = 0, iy = 0, iw = 0, ih = 0, charWidth = 0;

    if (textPtr->insertCursorType) {
	TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth);
	rightSideWidth = charWidth + halfWidth;
    } else {
	rightSideWidth = halfWidth;
    }

    if ((x + rightSideWidth) < 0) {
	/*
	 * The insertion cursor is off-screen. Indicate caret at 0,0 and
	 * return.
	 */

	Tk_SetCaretPos(textPtr->tkwin, 0, 0, height);
	return;
    }







    Tk_SetCaretPos(textPtr->tkwin, x - halfWidth, screenY, height);

    /*
     * As a special hack to keep the cursor visible on mono displays (or
     * anywhere else that the selection and insertion cursors have the same
     * color) write the default background in the cursor area (instead of
     * nothing) when the cursor isn't on. Otherwise the selection might hide
     * the cursor.
     */

    if (textPtr->flags & GOT_FOCUS) {
	if (textPtr->flags & INSERT_ON) {
	    Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
		    x - halfWidth, y, charWidth + textPtr->insertWidth,
		    height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
	} else if (textPtr->selBorder == textPtr->insertBorder) {
	    Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border,
		    x - halfWidth, y, charWidth + textPtr->insertWidth,
		    height, 0, TK_RELIEF_FLAT);
	}
    } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_HOLLOW) {
	if (textPtr->insertBorderWidth < 1) {
	    /*
	     * Hack to work around the fact that a "solid" border always
	     * paints in black.
	     */

	    TkBorder *borderPtr = (TkBorder *) textPtr->insertBorder;

	    XDrawRectangle(Tk_Display(textPtr->tkwin), dst, borderPtr->bgGC,
		    x - halfWidth, y, charWidth + textPtr->insertWidth - 1,
		    height - 1);
	} else {
	    Tk_Draw3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
		    x - halfWidth, y, charWidth + textPtr->insertWidth,
		    height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
	}
    } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_SOLID) {
	Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
		x - halfWidth, y, charWidth + textPtr->insertWidth, height,
		textPtr->insertBorderWidth, TK_RELIEF_RAISED);
    }
}

/*
 *--------------------------------------------------------------
 *
 * InsertUndisplayProc --







<
|

|
<
|
<
|
<
<
|

|
|
|
>
>
|
>
|




<
<
<
|



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|













|


|
<
|
|
|




|
<

<
<
<
<
<
<

<
<
|
<
<
<
<
<
|
<



|
<






>
>
>
>
>
>
|











|
<
|
|
|
<
|




|
<




|
<
|

|
<
|


|
<
|







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
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

static int
MarkLayoutProc(

    const TkTextIndex *indexPtr,/* Identifies first character in chunk. */
    TkTextSegment *segPtr,	/* Segment corresponding to indexPtr. */
    TCL_UNUSED(Tcl_Size),			/* Offset within segPtr corresponding to indexPtr (always 0). */

    TCL_UNUSED(int),			/* Chunk must not occupy pixels at this position or higher. */

    TCL_UNUSED(Tcl_Size),		/* Chunk must not include more than this many characters. */


    TCL_UNUSED(int),		/* 'true' means no characters have been assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Not used. */
    TCL_UNUSED(TkTextSpaceMode),	/* Not used. */
    TkTextDispChunk *chunkPtr)	/* Structure to fill in with information about this chunk. The x
    				 * field has already been set by the caller. */
{
    TkText *textPtr = indexPtr->textPtr;

    assert(indexPtr->textPtr);

    if (segPtr != textPtr->insertMarkPtr) {
	return -1;
    }




    chunkPtr->layoutProcs = &layoutInsertProcs;
    chunkPtr->numBytes = 0;
    chunkPtr->minAscent = 0;
    chunkPtr->minDescent = 0;
    chunkPtr->minHeight = 0;
    chunkPtr->width = 0;

    /*
     * Note: can't break a line after the insertion cursor: this prevents the
     * insertion cursor from being stranded at the end of a line.
     */

    chunkPtr->breakIndex = -1;
    chunkPtr->clientData = textPtr;
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextDrawBlockCursor --
 *
 *	This function returns whether a block will be drawn, which covers
 *	characters.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextDrawBlockCursor(
    TkText *textPtr)		/* The current text widget. */
{
    if (textPtr->blockCursorType) {
	if (textPtr->flags & GOT_FOCUS) {
	    if ((textPtr->flags & INSERT_ON) || textPtr->selAttrs.border == textPtr->insertBorder) {
		return 1;
	    }
	} else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_SOLID) {
	    return 1;
	}
    }
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextGetCursorBbox --
 *
 *	This function computes the cursor dimensions.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextGetCursorBbox(
    TkText *textPtr,		/* The current text widget. */
    int *x, int *y,		/* X/Y coordinate. */
    int *w, int *h)		/* Width/height of cursor. */
{
    TkTextIndex index;
    Tcl_UniChar thisChar;
    int cursorExtent;
    int charWidth = -1;

    assert(textPtr);
    assert(x);
    assert(y);
    assert(w);
    assert(h);

    cursorExtent = MAX(1, textPtr->insertWidth/2);
    TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);

    if (!TkTextIndexBbox(textPtr, &index, 0, x, y, w, h, &charWidth, &thisChar)) {
	int base, ix, iw;

	/*
	 * Testing whether the cursor is visible is not as trivial at it seems,
	 * see this example:
	 *
	 * ~~~~~~~~~~~~~~~~
	 * |   +-----+
	 * |   |     |
	 * |~~~|~~~~~|~~~~~
	 * |   |     |
	 * | a |     |
	 * |   |     |
	 * |   +-----+
	 *
	 * At left side we have the visible cursor, then char "a", then a window.
	 * The region between the tilde bars is the visible screen. The cursor
	 * is positioned before char "a", and the bbox of char "a" is outside of
	 * the visible screen, so a simple test with TkTextIndexBbox() at char
	 * position "a" fails here. Now we have to test with the display line.
	 */

	if (!TkTextGetDLineInfo(textPtr, &index, 0, &ix, y, &iw, h, &base)) {
	    return 0; /* cursor is not visible at all */
	}

	if (charWidth == -1) {
	    /* This char is outside of the screen, so use a default. */
	    charWidth = textPtr->charWidth;
	}
    }

    /*
     * Don't draw the full lengh of a tab, in this case we are drawing
     * a cursor at the right boundary with a standard width.
     */

    if (thisChar == '\t') {
	*x += charWidth;
	charWidth = MIN(textPtr->charWidth, charWidth);
	*x -= charWidth;
    }

    if (textPtr->blockCursorType) {
	/* NOTE: the block cursor extent is always rounded towards zero. */
	*w = charWidth + 2*cursorExtent;
    } else {
	*w = textPtr->insertWidth;
    }

    *x -= cursorExtent;
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextGetCursorWidth --
 *
 *	This function computes the cursor dimensions.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

unsigned
TkTextGetCursorWidth(
    TkText *textPtr,		/* The current text widget. */
    TCL_UNUSED(int *),			/* Shift x coordinate, can be NULL. */
    int *extent)		/* Extent of cursor to left side, can be NULL. */
{
    int width;
    int cursorExtent = MAX(1, textPtr->insertWidth/2);

    if (extent) {
	*extent = -cursorExtent;
    }

    if (textPtr->blockCursorType) {
	int ix, iy, ih;

	if (!TkTextGetCursorBbox(textPtr, &ix, &iy, &width, &ih)) {
	    return 0; /* cursor is not visible at all */
	}
    } else {
	width = textPtr->insertWidth;
    }

    return width;
}

/*
 *--------------------------------------------------------------
 *
 * TkrTextInsertDisplayProc --
 *
 *	This function is called to display the insertion cursor.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Graphics are drawn.
 *
 *--------------------------------------------------------------
 */

void
TkrTextInsertDisplayProc(
    TkText *textPtr,		/* The current text widget. */
    TCL_UNUSED(TkTextDispChunk *),	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this chunk (may differ

    				 * from the x-position in the chunk because of scrolling). */
    int y,			/* Y-position at which to draw this chunk in dst (x-position
    				 * is in the chunk itself). */
    int height,			/* Total height of line. */
    TCL_UNUSED(int),		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),		/* Display to use for drawing. */
    Drawable dst,		/* Pixmap or window in which to draw chunk. */
    int screenY)		/* Y-coordinate in text window that corresponds to y. */

{






    int halfWidth = textPtr->insertWidth/2;


    int width = TkTextGetCursorWidth(textPtr, &x, NULL);





    int rightSideWidth = MAX(1, width + halfWidth - textPtr->insertWidth);


    if ((x + rightSideWidth) < 0) {
	/*
	 * The insertion cursor is off-screen. Indicate caret at 0,0 and return.

	 */

	Tk_SetCaretPos(textPtr->tkwin, 0, 0, height);
	return;
    }

    x -= halfWidth;
    if (halfWidth == 0 && x >= TkTextGetLastXPixel(textPtr)) {
	/* Ensure visibility of at least 1 pixel */
	x -= 1;
    }

    Tk_SetCaretPos(textPtr->tkwin, x, screenY, height);

    /*
     * As a special hack to keep the cursor visible on mono displays (or
     * anywhere else that the selection and insertion cursors have the same
     * color) write the default background in the cursor area (instead of
     * nothing) when the cursor isn't on. Otherwise the selection might hide
     * the cursor.
     */

    if (textPtr->flags & GOT_FOCUS) {
	if (textPtr->flags & INSERT_ON) {
	    Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, x, y,

		    width, height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
	} else if (textPtr->selAttrs.border == textPtr->insertBorder) {
	    Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border, x, y,

		    width, height, 0, TK_RELIEF_FLAT);
	}
    } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_HOLLOW) {
	if (textPtr->insertBorderWidth < 1) {
	    /*
	     * Hack to work around the fact that a "solid" border always paints in black.

	     */

	    TkBorder *borderPtr = (TkBorder *) textPtr->insertBorder;

	    XDrawRectangle(Tk_Display(textPtr->tkwin), dst, borderPtr->bgGC, x, y,

		    width - 1, height - 1);
	} else {
	    Tk_Draw3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, x, y,

		    width, height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
	}
    } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_SOLID) {
	Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, x, y,

		width, height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
    }
}

/*
 *--------------------------------------------------------------
 *
 * InsertUndisplayProc --
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
 *
 *--------------------------------------------------------------
 */

static void
InsertUndisplayProc(
    TCL_UNUSED(TkText *),		/* Overall information about text widget. */
    TCL_UNUSED(TkTextDispChunk *))	/* Chunk that is about to be freed. */
{
    return;
}

/*
 *--------------------------------------------------------------
 *
 * MarkCheckProc --
 *
 *	This function is invoked by the B-tree code to perform consistency
 *	checks on mark segments.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The function panics if it detects anything wrong with
 *	the mark.
 *
 *--------------------------------------------------------------
 */

static void
MarkCheckProc(
    TkTextSegment *markPtr,	/* Segment to check. */
    TkTextLine *linePtr)	/* Line containing segment. */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;

    if (markPtr->body.mark.linePtr != linePtr) {
	Tcl_Panic("MarkCheckProc: markPtr->body.mark.linePtr bogus");
    }

    /*
     * These two marks are not in the hash table
     */

    if (markPtr->body.mark.textPtr->insertMarkPtr == markPtr) {
        return;
    }
    if (markPtr->body.mark.textPtr->currentMarkPtr == markPtr) {
	return;
    }

    /*
     * Make sure that the mark is still present in the text's mark hash table.
     */

    for (hPtr = Tcl_FirstHashEntry(
	    &markPtr->body.mark.textPtr->sharedTextPtr->markTable,
	    &search); hPtr != markPtr->body.mark.hPtr;
	    hPtr = Tcl_NextHashEntry(&search)) {
	if (hPtr == NULL) {
	    Tcl_Panic("MarkCheckProc couldn't find hash table entry for mark");
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * MarkFindNext --
 *







|

<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2775
2776
2777
2778
2779
2780
2781
2782
2783


2784



































2785

















2786
2787
2788
2789
2790
2791
2792
 *
 *--------------------------------------------------------------
 */

static void
InsertUndisplayProc(
    TCL_UNUSED(TkText *),		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{


    chunkPtr->clientData = NULL;



































    return;

















}

/*
 *--------------------------------------------------------------
 *
 * MarkFindNext --
 *
798
799
800
801
802
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
 *--------------------------------------------------------------
 */

static int
MarkFindNext(
    Tcl_Interp *interp,		/* For error reporting */
    TkText *textPtr,		/* The widget */

    Tcl_Obj *obj)			/* The starting index or mark name */


{
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextSegment *segPtr;


    int offset;







    const char *string = Tcl_GetString(obj);

    if (!strcmp(string, "insert")) {
	segPtr = textPtr->insertMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
	segPtr = segPtr->nextPtr;

    } else if (!strcmp(string, "current")) {
	segPtr = textPtr->currentMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
	segPtr = segPtr->nextPtr;

    } else {
	hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, string);
	if (hPtr != NULL) {
	    /*
	     * If given a mark name, return the next mark in the list of
	     * segments, even if it happens to be at the same character
	     * position.
	     */

	    segPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
	    TkTextMarkSegToIndex(textPtr, segPtr, &index);
	    segPtr = segPtr->nextPtr;
	} else {
	    /*
	     * For non-mark name indices we want to return any marks that are
	     * right at the index.
	     */

	    if (TkTextGetObjIndex(interp, textPtr, obj, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    for (offset = 0, segPtr = index.linePtr->segPtr;
		    segPtr != NULL && offset < index.byteIndex;
		    offset += segPtr->size, segPtr = segPtr->nextPtr) {
		/* Empty loop body */ ;
	    }
	}



    }


    while (1) {
	/*

	 * segPtr points at the first possible candidate, or NULL if we ran
	 * off the end of the line.

	 */

	for ( ; segPtr != NULL ; segPtr = segPtr->nextPtr) {
	    if (segPtr->typePtr == &tkTextRightMarkType ||
		    segPtr->typePtr == &tkTextLeftMarkType) {
		Tcl_Obj *markName = GetMarkName(textPtr, segPtr);

		if (markName != NULL) {
		    Tcl_SetObjResult(interp, markName);
		    return TCL_OK;
		}
	    }
	}
	index.linePtr = TkBTreeNextLine(textPtr, index.linePtr);
	if (index.linePtr == NULL) {

	    return TCL_OK;
	}


	index.byteIndex = 0;


	segPtr = index.linePtr->segPtr;
    }
}

/*
 *--------------------------------------------------------------

 *
 * MarkFindPrev --
 *
 *	This function searches backwards for the previous mark.
 *
 * Results:
 *	A standard Tcl result, which is a mark name or an empty string.
 *
 * Side effects:

 *	None.
 *
 *--------------------------------------------------------------
 */

static int
MarkFindPrev(
    Tcl_Interp *interp,		/* For error reporting */
    TkText *textPtr,		/* The widget */

    Tcl_Obj *obj)			/* The starting index or mark name */





{
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextSegment *segPtr, *seg2Ptr, *prevPtr;
    int offset;
    const char *string = Tcl_GetString(obj);

    if (!strcmp(string, "insert")) {
	segPtr = textPtr->insertMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
    } else if (!strcmp(string, "current")) {
	segPtr = textPtr->currentMarkPtr;
	TkTextMarkSegToIndex(textPtr, segPtr, &index);
    } else {
	hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, string);
	if (hPtr != NULL) {
	    /*

	     * If given a mark name, return the previous mark in the list of
	     * segments, even if it happens to be at the same character
	     * position.
	     */

	    segPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
	    TkTextMarkSegToIndex(textPtr, segPtr, &index);
	} else {
	    /*
	     * For non-mark name indices we do not return any marks that are
	     * right at the index.
	     */


	    if (TkTextGetObjIndex(interp, textPtr, obj, &index) != TCL_OK) {

		return TCL_ERROR;
	    }
	    for (offset = 0, segPtr = index.linePtr->segPtr;
		    segPtr != NULL && offset < index.byteIndex;


		    offset += segPtr->size, segPtr = segPtr->nextPtr) {
		/* Empty loop body */
	    }



	}


    }

    while (1) {
	/*
	 * segPtr points just past the first possible candidate, or at the
	 * beginning of the line.
	 */

	for (prevPtr = NULL, seg2Ptr = index.linePtr->segPtr;
		seg2Ptr != NULL && seg2Ptr != segPtr;
		seg2Ptr = seg2Ptr->nextPtr) {
	    if (seg2Ptr->typePtr == &tkTextRightMarkType ||
		    seg2Ptr->typePtr == &tkTextLeftMarkType) {
	        if (seg2Ptr->body.mark.hPtr == NULL) {
                    if (seg2Ptr != textPtr->currentMarkPtr &&

                            seg2Ptr != textPtr->insertMarkPtr) {
	                /*
                         * This is an insert or current mark from a
                         * peer of textPtr.
                         */
                        continue;
                    }





	        }
		prevPtr = seg2Ptr;
	    }
	}
	if (prevPtr != NULL) {
	    Tcl_Obj *markName = GetMarkName(textPtr, prevPtr);

	    if (markName != NULL) {
		Tcl_SetObjResult(interp, markName);
		return TCL_OK;
	    }

	}
	index.linePtr = TkBTreePreviousLine(textPtr, index.linePtr);
	if (index.linePtr == NULL) {
	    return TCL_OK;
	}
	segPtr = NULL;
    }

}

/*
 * ------------------------------------------------------------------------
 *
 * GetMarkName --

 *	Returns the name of the mark that is the given text segment, or NULL
 *	if it is unnamed (i.e., a widget-specific mark that isn't "current" or
 *	"insert").
 *






 * ------------------------------------------------------------------------
 */

static Tcl_Obj *
GetMarkName(

    TkText *textPtr,
    TkTextSegment *segPtr)
{
    const char *markName;

    if (segPtr == textPtr->currentMarkPtr) {
	markName = "current";
    } else if (segPtr == textPtr->insertMarkPtr) {
	markName = "insert";
    } else if (segPtr->body.mark.hPtr == NULL) {
	/*
	 * Ignore widget-specific marks for the other widgets. This is either

	 * an insert or a current mark (markPtr->body.mark.hPtr actually
	 * receives NULL for these marks in TkTextSetMark). The insert and
	 * current marks for textPtr having already been tested above, the
	 * current segment is an insert or current mark from a peer of
	 * textPtr, which we don't want to return.
	 */


	return NULL;
    } else {
	markName = (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable,
		segPtr->body.mark.hPtr);
    }
    return Tcl_NewStringObj(markName, -1);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:

 */







>
|
>
>




>
>
|
>
>
>
>
>
>
>
|

|

<
|
>
|

<
|
>

|
<

|
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
|
|
>
|
|
>
|
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
|
>
>
|
>
>
|
|
|
|
<
<
>
|
|
<
<
<
<
|
|
<
>
|
<
<
|

|
<
<
|
>
|
>
>
>
>
>
|
<
|
|
|
<
|
<
|
|
<
<
<
<
|
|
<
>
|
|
|
<
|
<
<
<
<
<
<
<
|
>
|
>
|

|
<
>
>
|
<
|
>
>
>
|
>
>
|

|
|
|
|
|

<
<
|
<
<
|
|
>
|
<
|
<
<
<
|
>
>
>
>
>
|
<
|
|
<
<

|
<


>

<
<
<
|
<
|
>





|
>




>
>
>
>
>
>



|
|
>
|
|

|

<
<
|
<
|
<
<
>
|
<
<
<
|
<
|
>

<
<
<

|






|

>

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
 *--------------------------------------------------------------
 */

static int
MarkFindNext(
    Tcl_Interp *interp,		/* For error reporting */
    TkText *textPtr,		/* The widget */
    int discardSpecial,	/* Discard marks "insert" and "current" when searching= */
    Tcl_Obj* indexObj,		/* Start search at this index. */
    const char *pattern,	/* Result must match this pattern, can be NULL. */
    int forward)		/* Search forward. */
{
    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextSegment *segPtr;
    TkTextLine *linePtr;
    const char *indexStr;

    assert(textPtr);
    assert(indexObj);

    if (TkTextIsDeadPeer(textPtr)) {
	return TCL_OK;
    }

    indexStr = Tcl_GetString(indexObj);

    if (strcmp(indexStr, "insert") == 0) {
	segPtr = textPtr->insertMarkPtr;

	linePtr = segPtr->sectionPtr->linePtr;
	segPtr = forward ? segPtr->nextPtr : segPtr->prevPtr;
    } else if (strcmp(indexStr, "current") == 0) {
	segPtr = textPtr->currentMarkPtr;

	linePtr = segPtr->sectionPtr->linePtr;
	segPtr = forward ? segPtr->nextPtr : segPtr->prevPtr;
    } else {
	if ((hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, indexStr))) {

	    /*
	     * If given a mark name, return the next/prev mark in the list of segments, even
	     * if it happens to be at the same character position.

	     */



















	    segPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
	    if (!MarkToIndex(textPtr, segPtr, &index)) {
		return SetResultNoMarkNamed(interp, indexStr);
	    }
	    linePtr = segPtr->sectionPtr->linePtr;
	    segPtr = forward ? segPtr->nextPtr : segPtr->prevPtr;
	} else {
	    /*
	     * For non-mark name indices we want to return any marks that are
	     * right at the index, when searching forward, otherwise we do not

	     * return any marks that are right at the index.
	     */














	    if (!TkTextGetIndexFromObj(interp, textPtr, indexObj, &index)) {
		return TCL_ERROR;
	    }
	    segPtr = TkTextIndexGetFirstSegment(&index, NULL);
	    linePtr = segPtr->sectionPtr->linePtr;

	    if (!forward) {
		while (segPtr && segPtr->size == 0) {
		    segPtr = segPtr->prevPtr;
		}
	    }
	}


    }

    if (forward) {




	TkTextSegment *lastPtr = textPtr->endMarker;


	/*
	 * Ensure that we can reach 'lastPtr'.


	 */

	while (lastPtr->size == 0) {


	    lastPtr = lastPtr->nextPtr;
	}

	while (1) {
	    /*
	     * 'segPtr' points at the first possible candidate, or NULL if we ran
	     * off the end of the line.
	     */


	    for ( ; segPtr; segPtr = segPtr->nextPtr) {
		if (segPtr == lastPtr) {
		    return TCL_OK;

		}

		if (TkTextIsNormalOrSpecialMark(segPtr)) {
		    const char *name = TkTextMarkName(textPtr->sharedTextPtr, textPtr, segPtr);





		    if (name /* otherwise it's a special mark not belonging to this widget */

			    && (!discardSpecial || !TkTextIsSpecialMark(segPtr))
			    && (!pattern || Tcl_StringMatch(name, pattern))) {
			Tcl_SetObjResult(interp, Tcl_NewStringObj(name, TCL_INDEX_NONE));
			return TCL_OK;

		    }







		}
	    }

	    if (!(linePtr = linePtr->nextPtr)) {
		return TCL_OK;
	    }
	    segPtr = linePtr->segPtr;

	}
    } else {
	TkTextSegment *firstPtr = textPtr->startMarker;


	/*
	 * Ensure that we can reach 'firstPtr'.
	 */

	while (firstPtr->prevPtr && firstPtr->prevPtr->size == 0) {
	    firstPtr = firstPtr->prevPtr;
	}

	while (1) {
	    /*
	     * 'segPtr' points at the first possible candidate, or NULL if we ran
	     * off the start of the line.
	     */



	    for ( ; segPtr; segPtr = segPtr->prevPtr) {


		if (segPtr == firstPtr) {
		    return TCL_OK;
		}
		if (TkTextIsNormalOrSpecialMark(segPtr)) {

		    const char *name = TkTextMarkName(textPtr->sharedTextPtr, textPtr, segPtr);




		    if (name /* otherwise it's a special mark not belonging to this widget */
			    && (!discardSpecial || !TkTextIsSpecialMark(segPtr))
			    && (!pattern || Tcl_StringMatch(name, pattern))) {
			Tcl_SetObjResult(interp, Tcl_NewStringObj(name, TCL_INDEX_NONE));
			return TCL_OK;
		    }

		}
	    }



	    if (!(linePtr = linePtr->prevPtr)) {

		return TCL_OK;
	    }
	    segPtr = linePtr->lastPtr;
	}



    }


    return TCL_OK; /* never reached */
}

/*
 * ------------------------------------------------------------------------
 *
 * TkTextMarkName --
 *
 *	Returns the name of the mark that is the given text segment, or NULL
 *	if it is unnamed (i.e., a widget-specific mark that isn't "current" or
 *	"insert").
 *
 * Results:
 *	The name of the mark, or NULL.
 *
 * Side effects:
 *	None.
 *
 * ------------------------------------------------------------------------
 */

const char *
TkTextMarkName(
    const TkSharedText *sharedTextPtr,
    const TkText *textPtr,		/* can be NULL */
    const TkTextSegment *markPtr)
{
    assert(!IS_PRESERVED(markPtr));



    if (markPtr->insertMarkFlag) {

	return !textPtr || textPtr == markPtr->body.mark.textPtr ? "insert" : NULL;


    }
    if (markPtr->currentMarkFlag) {



	return !textPtr || textPtr == markPtr->body.mark.textPtr ? "current" : NULL;

    }
    if (!markPtr->body.mark.ptr) {
	return NULL;



    }
    return (const char *)Tcl_GetHashKey(&sharedTextPtr->markTable, (Tcl_HashEntry *) markPtr->body.mark.ptr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */

Added generic/tkTextPriv.h.













































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
/*
 * tkTextPriv.h --
 *
 *	Private implementation for text widget.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXT
# error "do not include this private header file"
#endif


#ifndef _TKTEXTPRIV
#define _TKTEXTPRIV

/*
 * The following struct is private for TkTextBTree.c, but we want fast access to
 * the internal content.
 *
 * The data structure below defines an entire B-tree. Since text widgets are
 * the only current B-tree clients, 'clients' and 'numPixelReferences' are
 * identical.
 */

struct TkBTreeNodePixelInfo;

struct TkTextMyBTree {
    struct Node *rootPtr;
				/* Pointer to root of B-tree. */
    size_t clients;		/* Number of clients of this B-tree. */
    size_t numPixelReferences;
				/* Number of clients of this B-tree which care about pixel heights. */
    struct TkBTreeNodePixelInfo *pixelInfoBuffer;
    				/* Buffer of size numPixelReferences used for recomputation of pixel
    				 * information. */
    size_t stateEpoch;	/* Updated each time any aspect of the B-tree changes. */
    TkSharedText *sharedTextPtr;/* Used to find tagTable in consistency checking code, and to access
    				 * list of all B-tree clients. */
};


MODULE_SCOPE int TkpTextGetIndex(Tcl_Interp *interp, TkSharedText *sharedTextPtr, TkText *textPtr,
			    const char *string, unsigned lenOfString, TkTextIndex *indexPtr);

#endif /* _TKTEXTPRIV */

#ifdef _TK_NEED_IMPLEMENTATION

#include <assert.h>

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsMark --
 *
 *	Test whether this is a mark.
 *
 * Results:
 *	Whether this is a mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsMark(
    const TkTextSegment *segPtr)
{
    assert(segPtr);
    return segPtr->typePtr == &tkTextLeftMarkType || segPtr->typePtr == &tkTextRightMarkType;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsSpecialMark --
 *
 *	Test whether this is a special mark: "insert", or "current".
 *
 * Results:
 *	Whether this is a special mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsSpecialMark(
    const TkTextSegment *segPtr)
{
    assert(segPtr);
    return !!(segPtr->insertMarkFlag | segPtr->currentMarkFlag);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsPrivateMark --
 *
 *	Test whether this is a private mark, not visible with "inspect"
 *	or "dump". These kind of marks will be used in library/text.tcl.
 *	Furthemore in practice it is guaranteed that this mark has a
 *	unique name.
 *
 * Results:
 *	Whether this is a private mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsPrivateMark(
    const TkTextSegment *segPtr)
{
    assert(segPtr);
    return segPtr->privateMarkFlag;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsNormalMark --
 *
 *	Test whether this is a mark, and it is neither special, nor
 *	private, nor a start/end marker.
 *
 * Results:
 *	Whether this is a normal mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsNormalMark(
    const TkTextSegment *segPtr)
{
    assert(segPtr);
    return segPtr->normalMarkFlag;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsStartEndMarker --
 *
 *	Test whether this is a start/end marker. This must not be a mark,
 *	it can also be a break segment.
 *
 * Results:
 *	Whether this is a start/end marker.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsStartEndMarker(
    const TkTextSegment *segPtr)
{
    assert(segPtr);
    return segPtr->startEndMarkFlag;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsStableMark --
 *
 *	Test whether this is a mark, and it is neither special, nor
 *	private. Note that also a break segment is interpreted as
 *	a stable mark.
 *
 * Results:
 *	Whether this is a stable mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsStableMark(
    const TkTextSegment *segPtr)
{
    return TkTextIsStartEndMarker(segPtr) || TkTextIsNormalMark(segPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsSpecialOrPrivateMark --
 *
 *	Test whether this is a special mark, or a private mark.
 *
 * Results:
 *	Whether this is a special or private mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsSpecialOrPrivateMark(
    const TkTextSegment *segPtr)
{
    assert(segPtr);
    return !!(segPtr->privateMarkFlag | segPtr->insertMarkFlag | segPtr->currentMarkFlag);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsNormalOrSpecialMark --
 *
 *	Test whether this is a normal mark, or a special mark.
 *
 * Results:
 *	Whether this is a normal or special mark.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsNormalOrSpecialMark(
    const TkTextSegment *segPtr)
{
    return TkTextIsNormalMark(segPtr) || TkTextIsSpecialMark(segPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIsDeadPeer --
 *
 *	Test whether given widget is dead, this means that the start
 *	index is on last line. If it is dead, then this peer will not
 *	have an insert mark.
 *
 * Results:
 *	Returns whether given peer is dead.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIsDeadPeer(
    const TkText *textPtr)
{
    return !textPtr->startMarker->sectionPtr->linePtr->nextPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeLinePixelInfo --
 *
 *	Return widget pixel information for specified line.
 *
 * Results:
 *	The pixel information of this line for specified widget.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextPixelInfo *
TkBTreeLinePixelInfo(
    const TkText *textPtr,
    TkTextLine *linePtr)
{
    assert(textPtr);
    assert(textPtr->pixelReference >= 0);
    assert(linePtr);

    return linePtr->pixelInfo + textPtr->pixelReference;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetStartLine --
 *
 *	This function returns the first line for this text widget.
 *
 * Results:
 *	The first line in this widget.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextLine *
TkBTreeGetStartLine(
    const TkText *textPtr)
{
    assert(textPtr);
    return textPtr->startMarker->sectionPtr->linePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetLastLine --
 *
 *	This function returns the last line for this text widget.
 *
 * Results:
 *	The last line in this widget.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextLine *
TkBTreeGetLastLine(
    const TkText *textPtr)
{
    TkTextLine *endLine;

    assert(textPtr);
    endLine = textPtr->endMarker->sectionPtr->linePtr;
    return endLine->nextPtr ? endLine->nextPtr : endLine;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetShared --
 *
 *	Get the shared resource for given tree.
 *
 * Results:
 *	The shared resource.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkSharedText *
TkBTreeGetShared(
    TkTextBTree tree)		/* Return shared resource of this tree. */
{
    return ((struct TkTextMyBTree *) tree)->sharedTextPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeIncrEpoch --
 *
 *	Increment the epoch of the tree.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Increment the epoch number.
 *
 *----------------------------------------------------------------------
 */

inline
Tcl_Size
TkBTreeIncrEpoch(
    TkTextBTree tree)		/* Tree to increment epoch. */
{
    return ((struct TkTextMyBTree *) tree)->stateEpoch += 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeEpoch --
 *
 *	Return the epoch for the B-tree. This number is incremented any time
 *	anything changes in the tree.
 *
 * Results:
 *	The epoch number.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
Tcl_Size
TkBTreeEpoch(
    TkTextBTree tree)		/* Tree to get epoch for. */
{
    return ((struct TkTextMyBTree *) tree)->stateEpoch;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetRoot --
 *
 *	Return the root node of the B-Tree.
 *
 * Results:
 *	The root node of the B-Tree.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
struct Node *
TkBTreeGetRoot(
    TkTextBTree tree)		/* Tree to get root node for. */
{
    return ((struct TkTextMyBTree *) tree)->rootPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeNextLine --
 *
 *	Given an existing line in a B-tree, this function locates the next
 *	line in the B-tree, regarding the end line of this widget.
 *	B-tree.
 *
 * Results:
 *	The return value is a pointer to the line that immediately follows
 *	linePtr, or NULL if there is no such line.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextLine *
TkBTreeNextLine(
    const TkText *textPtr,	/* Next line in the context of this client, can be NULL. */
    TkTextLine *linePtr)	/* Pointer to existing line in B-tree. */
{
    return textPtr && linePtr == TkBTreeGetLastLine(textPtr) ? NULL : linePtr->nextPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreePrevLine --
 *
 *	Given an existing line in a B-tree, this function locates the previous
 *	line in the B-tree, regarding the start line of this widget.
 *
 * Results:
 *	The return value is a pointer to the line that immediately preceeds
 *	linePtr, or NULL if there is no such line.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextLine *
TkBTreePrevLine(
    const TkText *textPtr,	/* Relative to this client of the B-tree, can be NULL. */
    TkTextLine *linePtr)	/* Pointer to existing line in B-tree. */
{
    return textPtr && linePtr == TkBTreeGetStartLine(textPtr) ? NULL : linePtr->prevPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreePrevLogicalLine --
 *
 *	Given a line, this function is searching for the previous logical line,
 *	which don't has a predecessing line with elided newline. If the search
 *	reaches the start of the text, then the first line will be returned,
 *	even if it's not a logical line (the latter can only happen in peers
 *	with restricted ranges).
 *
 * Results:
 *	The return value is the previous logical line, in most cases this
 *	will be simply the previous line.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextLine *
TkBTreePrevLogicalLine(
    const TkSharedText* sharedTextPtr,
    const TkText *textPtr,	/* can be NULL */
    TkTextLine *linePtr)
{
    assert(linePtr);
    assert(linePtr != (textPtr ?
	    TkBTreeGetStartLine(textPtr) : sharedTextPtr->startMarker->sectionPtr->linePtr));

    return TkBTreeGetLogicalLine(sharedTextPtr, textPtr, linePtr->prevPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeCountLines --
 *
 *	This function counts the number of lines inside a given range.
 *
 * Results:
 *	The return value is the number of lines inside a given range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
unsigned
TkBTreeCountLines(
    const TkTextBTree tree,
    const TkTextLine *linePtr1,	/* Start counting at this line. */
    const TkTextLine *linePtr2)	/* Stop counting at this line (don't count this line). */
{
    assert(TkBTreeLinesTo(tree, NULL, linePtr1, NULL) <= TkBTreeLinesTo(tree, NULL, linePtr2, NULL));

    if (linePtr1 == linePtr2) {
	return 0; /* this is catching a frequent case */
    }
    if (linePtr1->nextPtr == linePtr2) {
	return 1; /* this is catching a frequent case */
    }

    return TkBTreeLinesTo(tree, NULL, linePtr2, NULL) - TkBTreeLinesTo(tree, NULL, linePtr1, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexMakePersistent --
 *
 *	Make given index persistent.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
void
TkTextIndexMakePersistent(
    TkTextIndex *indexPtr)
{
    TkTextIndexToByteIndex(indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetPeer --
 *
 *	Set this index to the start of the line.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
void
TkTextIndexSetPeer(
    TkTextIndex *indexPtr,
    TkText *textPtr)
{
    assert(indexPtr->tree);

    indexPtr->textPtr = textPtr;
    indexPtr->priv.lineNoRel = -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetShared --
 *
 *	Get the shared resource of this index.
 *
 * Results:
 *	The shared resource.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkSharedText *
TkTextIndexGetShared(
    const TkTextIndex *indexPtr)
{
    assert(indexPtr);
    assert(indexPtr->tree);
    return TkBTreeGetShared(indexPtr->tree);
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetTags --
 *
 *	Return information about all of the tags that are associated with a
 *	particular character in a B-tree of text.
 *
 * Results:
 *      The return value is the root of the tag chain, containing all tags
 *	associated with the character at the position given by linePtr and ch.
 *	If there are no tags at the given character then a NULL pointer is
 *	returned.
 *
 * Side effects:
 *	The attribute nextPtr of TkTextTag will be modified for any tag.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextTag *
TkBTreeGetTags(
    const TkTextIndex *indexPtr,	/* Indicates a particular position in the B-tree. */
    TkTextSortMethod sortMeth,		/* Sort tags according to this method. */
    int *flags)				/* Store flags from TkBTreeGetSegmentTags(), can be NULL. */
{
    return TkBTreeGetSegmentTags(TkTextIndexGetShared(indexPtr),
	    TkTextIndexGetContentSegment(indexPtr, NULL), indexPtr->textPtr, sortMeth, flags);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextGetFirstChunkOfNextDispLine --
 *
 *	This function returns the first chunk of succeeding display line
 *	which contains characters.
 *
 * Results:
 *	Returns the first chunk of succeeding display line which contains
 *	characters.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
const TkTextDispChunk *
TkTextGetFirstChunkOfNextDispLine(
    const TkTextDispChunk *chunkPtr)
{
    return chunkPtr->dlPtr->nextPtr ? chunkPtr->dlPtr->nextPtr->firstCharChunkPtr : NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextGetLastChunkOfPrevDispLine --
 *
 *	This function returns the last chunk of predecessing display line
 *	which contains characters.
 *
 * Results:
 *	Returns the last chunk of predecessing display line which contains
 *	characters.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
const TkTextDispChunk *
TkTextGetLastChunkOfPrevDispLine(
    const TkTextDispChunk *chunkPtr)
{
    return chunkPtr->dlPtr->prevPtr ? chunkPtr->dlPtr->prevPtr->lastChunkPtr : NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetLine --
 *
 *	Get the line pointer of this index.
 *
 * Results:
 *	The line pointer.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextLine *
TkTextIndexGetLine(
    const TkTextIndex *indexPtr)/* Indicates a particular position in the B-tree. */
{
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    return indexPtr->priv.linePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetToLastChar2 --
 *
 *	Set the new line pointer, and set this index to one before the
 *	end of the line.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
void
TkTextIndexSetToLastChar2(
    TkTextIndex *indexPtr,	/* Pointer to index. */
    TkTextLine *linePtr)	/* Pointer to line. */
{
    assert(indexPtr->tree);
    assert(linePtr);
    assert(linePtr->parentPtr); /* expired? */

    indexPtr->priv.linePtr = linePtr;
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    TkTextIndexSetToLastChar(indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexGetSegment --
 *
 *	Get the pointer to stored segment.
 *
 * Results:
 *	Pointer to the stored segment, this can be NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
TkTextSegment *
TkTextIndexGetSegment(
    const TkTextIndex *indexPtr)/* Pointer to index. */
{
    TkTextSegment *segPtr;

    assert(indexPtr->tree);
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    segPtr = indexPtr->priv.segPtr;

    if (!segPtr
	    || (indexPtr->priv.isCharSegment
		&& TkBTreeEpoch(indexPtr->tree) != indexPtr->stateEpoch)) {
	return NULL;
    }

    assert(!segPtr || segPtr->typePtr);    /* expired? */
    assert(!segPtr || segPtr->sectionPtr); /* linked? */
    assert(!segPtr || segPtr->sectionPtr->linePtr == indexPtr->priv.linePtr);

    return segPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextGetIndexFromObj --
 *
 *	Create new text index from given position.
 *
 * Results:
 *	Returns true if and only if the index could be created.
 *
 * Side effects:
 *	Store the new text index in 'indexPtr'.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextGetIndexFromObj(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    TkText *textPtr,		/* Information about text widget, can be NULL. */
    Tcl_Obj *objPtr,		/* Object containing description of position. */
    TkTextIndex *indexPtr)	/* Store the result here. */
{
    Tcl_Size length;
    const char *str;

    assert(textPtr);
    assert(objPtr);

    str = Tcl_GetStringFromObj(objPtr, &length);
    return TkpTextGetIndex(interp, textPtr->sharedTextPtr, textPtr,
	    str, length, indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSave --
 *
 *	Makes the index robust, so that it can be rebuild after modifications.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
void
TkTextIndexSave(
    TkTextIndex *indexPtr)
{
    TkTextIndexGetLineNumber(indexPtr, indexPtr->textPtr);
    TkTextIndexGetByteIndex(indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSameLines --
 *
 *	Test whether both given indicies are referring the same line.
 *
 * Results:
 *	Return true if both indices are referring the same line, otherwise
 *	false will be returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkTextIndexSameLines(
    const TkTextIndex *indexPtr1,	/* Pointer to index. */
    const TkTextIndex *indexPtr2)	/* Pointer to index. */
{
    assert(indexPtr1->priv.linePtr);
    assert(indexPtr2->priv.linePtr);
    assert(indexPtr1->priv.linePtr->parentPtr); /* expired? */
    assert(indexPtr2->priv.linePtr->parentPtr); /* expired? */

    return indexPtr1->priv.linePtr == indexPtr2->priv.linePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexInvalidate --
 *
 *	Clear position attributes: segPtr, and byteIndex.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The given index will be in an invalid state, the TkIndexGet*
 *	functions cannot be used.
 *
 *----------------------------------------------------------------------
 */

inline
void
TkTextIndexInvalidate(
    TkTextIndex *indexPtr)	/* Pointer to index. */
{
    indexPtr->priv.segPtr = NULL;
    indexPtr->priv.byteIndex = -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextIndexSetEpoch --
 *
 *	Set epoch of given index, and clear the cached values.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
void
TkTextIndexSetEpoch(
    TkTextIndex *indexPtr,
    size_t epoch)
{
    assert(indexPtr->priv.linePtr);
    assert(indexPtr->priv.linePtr->parentPtr); /* expired? */

    assert(indexPtr->priv.byteIndex >= 0);
    indexPtr->stateEpoch = epoch;

    /* clear the cached values in any case */
    indexPtr->priv.lineNo = -1;
    indexPtr->priv.lineNoRel = -1;
    indexPtr->priv.segPtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkBTreeGetNumberOfDisplayLines --
 *
 *	Return the current number of display lines. This is the number
 *	of lines known by the B-Tree (not the number of lines known
 *	by the display stuff).
 *
 *	We are including the implementation into this private header file,
 *	because it uses some facts only known by the display stuff.
 *
 * Results:
 *	Returns the current number of display lines (known by B-Tree).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkBTreeGetNumberOfDisplayLines(
    const TkTextPixelInfo *pixelInfo)
{
    const TkTextDispLineInfo *dispLineInfo;

    if (pixelInfo->height == 0) {
	return 0;
    }
    if (!(dispLineInfo = pixelInfo->dispLineInfo)) {
	return 1;
    }
    if (pixelInfo->epoch & 0x80000000) {
	/*
	 * This will return the old number of display lines, because the
	 * computation of the corresponding logical line is currently in
	 * progress, and unfinished.
	 */
	return dispLineInfo->entry[dispLineInfo->numDispLines].pixels;
    }
    return dispLineInfo->numDispLines;
}

#if TCL_UTF_MAX <= 4 && TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 7
/*
 *----------------------------------------------------------------------
 *
 * TkUtfToUniChar --
 *
 *	Only needed for backporting, see source of version 8.7 about
 *	this function.
 *
 *	IMO this function is only a bad hack, Tcl should provide the
 *	appropriate functionality.
 *
 *----------------------------------------------------------------------
 */

inline
int
TkUtfToUniChar(const char *src, int *chPtr)
{
    Tcl_UniChar ch;
    int result = Tcl_UtfToUniChar(src, &ch);
    *chPtr = ch;
    return result;
}

#endif /* end of backport for 8.6/8.5 */

#undef _TK_NEED_IMPLEMENTATION
#endif /* _TK_NEED_IMPLEMENTATION */
/* vi:set ts=8 sw=4: */

Changes to generic/tkTextTag.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
/*
 * 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.

 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"



#include "default.h"



/*

 * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap
 * option of tags in a Text widget. These values are used as indices into the
 * string table below. Tags are allowed an empty wrap value, but the widget as
 * a whole is not.
 */


static const char *const wrapStrings[] = {
    "char", "none", "word", "", NULL
};






/*
 * The 'TkTextTabStyle' enum in tkText.h is used to define a type for the
 * -tabstyle option of the Text widget. These values are used as indices into
 * the string table below. Tags are allowed an empty tabstyle value, but the
 * widget as a whole is not.
 */

static const char *const tabStyleStrings[] = {
    "tabular", "wordprocessor", "", NULL

};


static const Tk_OptionSpec tagOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BITMAP, "-bgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", NULL, NULL,
	NULL, offsetof(TkTextTag, borderWidthPtr), offsetof(TkTextTag, borderWidth),
	TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_STRING, "-elide", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, elideString),
	TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},


    {TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,


	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-justify", NULL, NULL,






	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0,0},





    {TK_OPTION_STRING, "-lmargin1", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-lmargin2", NULL, NULL,




	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-offset", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-overstrike", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrikeString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-overstrikefg", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrikeColor),


        TK_OPTION_NULL_OK, 0, 0},

    {TK_OPTION_STRING, "-relief", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-rmargin", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0},
    {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-spacing1", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-spacing2", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, spacing2String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-spacing3", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-tabs", NULL, NULL,
	NULL, offsetof(TkTextTag, tabStringPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tabStyle),
	TK_OPTION_NULL_OK, tabStyleStrings, 0},
    {TK_OPTION_STRING, "-underline", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underlineString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-underlinefg", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underlineColor),


        TK_OPTION_NULL_OK, 0, 0},



    {TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, wrapMode),
	TK_OPTION_NULL_OK, wrapStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};






/*
 * Forward declarations for functions defined later in this file:
 */

static void		ChangeTagPriority(TkText *textPtr, TkTextTag *tagPtr,
			    int prio);





static TkTextTag *	FindTag(Tcl_Interp *interp, TkText *textPtr,





































			    Tcl_Obj *tagName);

























static void		SortTags(int numTags, TkTextTag **tagArrayPtr);








static int		TagSortProc(const void *first, const void *second);









static void		TagBindEvent(TkText *textPtr, XEvent *eventPtr,






			    int numTags, TkTextTag **tagArrayPtr);



/*
 *--------------------------------------------------------------
 *
 * TkTextTagCmd --
 *
 *	This function is invoked to process the "tag" options of the widget







|
|
>







>
>
>

>
>

<
>
|
<
<
<
<
>

<
<
<
>
>
>
>
>


|
|
<
<


|
<
>


>


|



|
|
|
|
|
>
>





>
>
|
|
>
>
>
>
>
>
|
>
>
>
>
>
|
|
|
>
>
>
>
|


|
|
|
|
<
|
|
>
>
|
>
|
|
|
|






|
|
|
|
|
|



|
<
|
|
<
|
|
>
>
|
>
>
>

|
<



>
>
>
>
>




|
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26




27
28



29
30
31
32
33
34
35
36
37


38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120

121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/*
 * 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 © 1992-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2015-2018 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 "tkText.h"
#include "tkTextUndo.h"
#include "tkTextTagSet.h"
#include "tkBitField.h"
#include "default.h"
#include <assert.h>
#include <stdlib.h>


#ifndef MAX
# define MAX(a,b) (((int) a) < ((int) b) ? b : a)




#endif




#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

/*
 * The 'Tk_Justify' enum in tk.h is used to define a type for the -justify option of
 * the Text widget. These values are used as indices into the string table below.


 */

static const char *const justifyStrings[] = {

    "left", "right", "center", "full", NULL
};


static const Tk_OptionSpec tagOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, attrs.border), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BITMAP, "-bgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", NULL, NULL,
	NULL, offsetof(TkTextTag, attrs.borderWidthObj), offsetof(TkTextTag, attrs.borderWidth),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-elide", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, elide),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-eolcolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, eolColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, attrs.fgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-hyphencolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, hyphenColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-hyphenrules", NULL, NULL,
	NULL, offsetof(TkTextTag, hyphenRulesPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-inactivebackground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, attrs.inactiveBorder), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-inactiveforeground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, attrs.inactiveFgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-inactiveselectbackground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, inactiveSelBorder), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-inactiveselectforeground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, inactiveSelFgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indentbackground", NULL, NULL,
	NULL, offsetof(TkTextTag, indentBgPtr), offsetof(TkTextTag, indentBg),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-justify", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, justify), TK_OPTION_NULL_OK|TK_OPTION_ENUM_VAR, justifyStrings, 0},
    {TK_OPTION_STRING, "-lang", NULL, NULL,
	NULL, offsetof(TkTextTag, langPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-lmargin1", NULL, NULL,
	NULL, offsetof(TkTextTag, lMargin1Obj), offsetof(TkTextTag, lMargin1), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-lmargin2", NULL, NULL,
	NULL, offsetof(TkTextTag, lMargin2Obj), offsetof(TkTextTag, lMargin2), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-offset", NULL, NULL,
	NULL, offsetof(TkTextTag, offsetObj), offsetof(TkTextTag, offset), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-overstrike", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrike), TK_OPTION_NULL_OK, 0, 0},

    {TK_OPTION_COLOR, "-overstrikecolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrikeColor), TK_OPTION_NULL_OK, 0, 0},
#if SUPPORT_DEPRECATED_TAG_OPTIONS
    {TK_OPTION_SYNONYM, "-overstrikefg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, TK_OPTION_NULL_OK, "-overstrikecolor", TK_TEXT_DEPRECATED_OVERSTRIKE_FG},
#endif /* SUPPORT_DEPRECATED_TAG_OPTIONS */
    {TK_OPTION_RELIEF, "-relief", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, relief), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-rmargin", NULL, NULL,
	NULL, offsetof(TkTextTag, rMarginObj), offsetof(TkTextTag, rMargin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-spacing1", NULL, NULL,
	NULL, offsetof(TkTextTag, spacing1Obj), offsetof(TkTextTag, spacing1), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-spacing2", NULL, NULL,
	NULL, offsetof(TkTextTag, spacing2Obj), offsetof(TkTextTag, spacing2), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-spacing3", NULL, NULL,
	NULL, offsetof(TkTextTag, spacing3Obj), offsetof(TkTextTag, spacing3), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tabs", NULL, NULL,
	NULL, offsetof(TkTextTag, tabStringPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tabStyle), TK_OPTION_NULL_OK, tkTextTabStyleStrings, 0},

    {TK_OPTION_BOOLEAN, "-underline", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underline), TK_OPTION_NULL_OK, 0, 0},

    {TK_OPTION_COLOR, "-underlinecolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underlineColor), TK_OPTION_NULL_OK, 0, 0},
#if SUPPORT_DEPRECATED_TAG_OPTIONS
    {TK_OPTION_SYNONYM, "-underlinefg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, TK_OPTION_NULL_OK, "-underlinecolor", 0},
#endif /* SUPPORT_DEPRECATED_TAG_OPTIONS */
    {TK_OPTION_BOOLEAN, "-undo", NULL, NULL,
	"1", TCL_INDEX_NONE, offsetof(TkTextTag, undo), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, wrapMode), TK_OPTION_NULL_OK|TK_OPTION_ENUM_VAR, tkTextWrapStrings, 0},

    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

DEBUG_ALLOC(extern unsigned tkTextCountNewTag);
DEBUG_ALLOC(extern unsigned tkTextCountDestroyTag);
DEBUG_ALLOC(extern unsigned tkTextCountNewUndoToken);
DEBUG_ALLOC(extern unsigned tkTextCountDestroyUndoToken);

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ChangeTagPriority(TkSharedText *sharedTextPtr, TkTextTag *tagPtr,
			    unsigned newPriority, int undo);
static int		TagAddRemove(TkText *textPtr, const TkTextIndex *index1Ptr,
			    const TkTextIndex *index2Ptr, TkTextTag *tagPtr, int add);
static void		TagBindEvent(TkText *textPtr, XEvent *eventPtr, TkTextTagSet *tagInfoPtr,
			    unsigned epoch);
static void		AppendTags(Tcl_Interp *interp, unsigned numTags, TkTextTag **tagArray);
static TkTextTag *	FindTag(Tcl_Interp *interp, const TkText *textPtr, Tcl_Obj *tagName);
static int		EnumerateTags(Tcl_Interp *interp, TkText *textPtr, int objc,
			    Tcl_Obj *const *objv);
static void		GrabSelection(TkText *textPtr, const TkTextTag *tagPtr, int add, int changed);

/*
 * We need some private undo/redo stuff.
 */

static void UndoChangeTagPriorityPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void UndoChangeTagPriorityDestroy(TkSharedText *, TkTextUndoToken *, int);
static Tcl_Obj *UndoChangeTagPriorityGetCommand(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *UndoChangeTagPriorityInspect(const TkSharedText *, const TkTextUndoToken *);

static const Tk_UndoType undoTokenTagPriorityType = {
    TK_TEXT_UNDO_TAG_PRIORITY,		/* action */
    UndoChangeTagPriorityGetCommand,	/* commandProc */
    UndoChangeTagPriorityPerform,	/* undoProc */
    UndoChangeTagPriorityDestroy,	/* destroyProc */
    NULL,				/* rangeProc */
    UndoChangeTagPriorityInspect	/* inspectProc */
};

static const Tk_UndoType redoTokenTagPriorityType = {
    TK_TEXT_REDO_TAG_PRIORITY,		/* action */
    UndoChangeTagPriorityGetCommand,	/* commandProc */
    UndoChangeTagPriorityPerform,	/* undoProc */
    UndoChangeTagPriorityDestroy,	/* destroyProc */
    NULL,				/* rangeProc */
    UndoChangeTagPriorityInspect	/* inspectProc */
};

typedef struct UndoTokenTagPriority {
    const Tk_UndoType *undoType;
    TkTextTag *tagPtr;
    uint32_t priority;
} UndoTokenTagPriority;

static Tcl_Obj *
UndoChangeTagPriorityGetCommand(
    TCL_UNUSED(const TkSharedText *),
    const TkTextUndoToken *item)
{
    const UndoTokenTagPriority *token = (const UndoTokenTagPriority *) item;
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("tag", TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("priority", TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(token->tagPtr->name, TCL_INDEX_NONE));
    return objPtr;
}

static Tcl_Obj *
UndoChangeTagPriorityInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const UndoTokenTagPriority *token = (const UndoTokenTagPriority *) item;
    Tcl_Obj *objPtr = UndoChangeTagPriorityGetCommand(sharedTextPtr, item);

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(token->priority));
    return objPtr;
}

static void
UndoChangeTagPriorityPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    TCL_UNUSED(int))
{
    UndoTokenTagPriority *token = (UndoTokenTagPriority *) undoInfo->token;
    unsigned oldPriority = token->tagPtr->priority;

    ChangeTagPriority(sharedTextPtr, token->tagPtr, token->priority, 1);

    if (redoInfo) {
	redoInfo->token = undoInfo->token;
	redoInfo->token->undoType = &redoTokenTagPriorityType;
	token->priority = oldPriority;
    }
}

static void
UndoChangeTagPriorityDestroy(
    TkSharedText *sharedTextPtr,
    TkTextUndoToken *item,
    TCL_UNUSED(int))
{
    UndoTokenTagPriority *token = (UndoTokenTagPriority *) item;

    TkTextReleaseTag(sharedTextPtr, token->tagPtr, NULL);
}

/*
 *--------------------------------------------------------------
 *
 * TkTextTagCmd --
 *
 *	This function is invoked to process the "tag" options of the widget
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156

157
158

159
160
161
162
163
164
165
166
167
168


169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355




356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471


472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563



564
565
566
567

568
569

570
571
572
573
574
575

576
577
578
579
580
581
582
583
584
585
586
587














588





















589




590





591





















592









593



594













595


596



597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657



658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684



685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762

763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextTagCmd(
    TkText *textPtr,	/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already
				 * parsed this command enough to know that
				 * objv[1] is "tag". */
{
    static const char *const tagOptionStrings[] = {
	"add", "bind", "cget", "configure", "delete", "lower", "names",

	"nextrange", "prevrange", "raise", "ranges", "remove", NULL
    };
    enum tagOptions {
	TAG_ADD, TAG_BIND, TAG_CGET, TAG_CONFIGURE, TAG_DELETE, TAG_LOWER,
	TAG_NAMES, TAG_NEXTRANGE, TAG_PREVRANGE, TAG_RAISE, TAG_RANGES,
	TAG_REMOVE
    };
    int optionIndex, i;

    TkTextTag *tagPtr;
    TkTextIndex index1, index2;


    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], tagOptionStrings,
	    sizeof(char *), "tag option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }



    switch ((enum tagOptions)optionIndex) {
    case TAG_ADD:
    case TAG_REMOVE: {
	int addTag;


	if (((enum tagOptions)optionIndex) == TAG_ADD) {
	    addTag = 1;
	} else {
	    addTag = 0;
	}
	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 3, objv,
		    "tagName index1 ?index2 index1 index2 ...?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
	if (tagPtr->elide) {
		/*
		* Indices are potentially obsolete after adding or removing
		* elided character ranges, especially indices having "display"
		* or "any" submodifier, therefore increase the epoch.
		*/
		textPtr->sharedTextPtr->stateEpoch++;
	}
	for (i = 4; i < objc; i += 2) {
	    if (TkTextGetObjIndex(interp, textPtr, objv[i],
		    &index1) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (objc > (i+1)) {
		if (TkTextGetObjIndex(interp, textPtr, objv[i+1],
			&index2) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (TkTextIndexCmp(&index1, &index2) >= 0) {
		    return TCL_OK;
		}
	    } else {
		index2 = index1;
		TkTextIndexForwChars(NULL,&index2, 1, &index2, COUNT_INDICES);
	    }

	    if (tagPtr->affectsDisplay) {
		TkTextRedrawTag(textPtr->sharedTextPtr, NULL, &index1, &index2,
			tagPtr, !addTag);
	    } else {
		/*
		 * Still need to trigger enter/leave events on tags that have
		 * changed.
		 */

		TkTextEventuallyRepick(textPtr);
	    }
	    if (TkBTreeTag(&index1, &index2, tagPtr, addTag)) {
		/*
		 * If the tag is "sel", and we actually adjusted something
		 * then grab the selection if we're supposed to export it and
		 * don't already have it.
		 *
		 * Also, invalidate partially-completed selection retrievals.
		 * We only need to check whether the tag is "sel" for this
		 * textPtr (not for other peer widget's "sel" tags) because we
		 * cannot reach this code path with a different widget's "sel"
		 * tag.
		 */

		if (tagPtr == textPtr->selTagPtr) {
		    /*
		     * Send an event that the selection changed. This is
		     * equivalent to:
		     *	   event generate $textWidget <<Selection>>
		     */


		    TkTextSelectionEvent(textPtr);

		    if (addTag && textPtr->exportSelection
			    && (!Tcl_IsSafe(textPtr->interp))
			    && !(textPtr->flags & GOT_SELECTION)) {
			Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
				TkTextLostSelection, textPtr);
			textPtr->flags |= GOT_SELECTION;
		    }

		    textPtr->abortSelections = 1;
		}
	    }
	}
	break;
    }
    case TAG_BIND:
	if ((objc < 4) || (objc > 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?command?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);

	/*
	 * Make a binding table if the widget doesn't already have one.
	 */

	if (textPtr->sharedTextPtr->bindingTable == NULL) {
	    textPtr->sharedTextPtr->bindingTable =
		    Tk_CreateBindingTable(interp);
	}

	if (objc == 6) {
	    int append = 0;
	    unsigned long mask;
	    const char *fifth = Tcl_GetString(objv[5]);

	    if (fifth[0] == 0) {
		return Tk_DeleteBinding(interp,
			textPtr->sharedTextPtr->bindingTable,
			(ClientData) tagPtr->name, Tcl_GetString(objv[4]));
	    }
	    if (fifth[0] == '+') {
		fifth++;
		append = 1;
	    }
	    mask = Tk_CreateBinding(interp,
		    textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name, Tcl_GetString(objv[4]), fifth,
		    append);
	    if (mask == 0) {
		return TCL_ERROR;
	    }
	    if (mask & ~(unsigned long)(ButtonMotionMask|Button1MotionMask
		    |Button2MotionMask|Button3MotionMask|Button4MotionMask
		    |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
		    |EnterWindowMask|LeaveWindowMask|KeyPressMask
		    |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
		Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable,
			(ClientData) tagPtr->name, Tcl_GetString(objv[4]));
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"requested illegal events; only key, button, motion,"
			" enter, leave, and virtual events may be used", -1));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "TAG_BIND_EVENT",NULL);
		return TCL_ERROR;
	    }
	} else if (objc == 5) {
	    const char *command;

	    command = Tk_GetBinding(interp,
		    textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name, Tcl_GetString(objv[4]));
	    if (command == NULL) {
		const char *string = Tcl_GetString(Tcl_GetObjResult(interp));

		/*
		 * Ignore missing binding errors. This is a special hack that
		 * relies on the error message returned by FindSequence in
		 * tkBind.c.
		 */

		if (string[0] != '\0') {
		    return TCL_ERROR;
		}
		Tcl_ResetResult(interp);
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
	    }
	} else {
	    Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name);
	}
	break;
    case TAG_CGET:
	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 1, objv, "tag cget tagName option");
	    return TCL_ERROR;
	} else {
	    Tcl_Obj *objPtr;

	    tagPtr = FindTag(interp, textPtr, objv[3]);
	    if (tagPtr == NULL) {
		return TCL_ERROR;
	    }
	    objPtr = Tk_GetOptionValue(interp, tagPtr,
		    tagPtr->optionTable, objv[4], textPtr->tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
	break;
    case TAG_CONFIGURE: {




	int newTag;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv,
		    "tagName ?-option value ...?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag);
	if (objc <= 5) {
	    Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, tagPtr,
		    tagPtr->optionTable,
		    (objc == 5) ? objv[4] : NULL, textPtr->tkwin);

	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);

	    return TCL_OK;
	} else {
	    int result = TCL_OK;

	    if (Tk_SetOptions(interp, tagPtr, tagPtr->optionTable,
		    objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) {
		return TCL_ERROR;
	    }

	    /*
	     * Some of the configuration options, like -underline and
	     * -justify, require additional translation (this is needed
	     * because we need to distinguish a particular value of an option
	     * from "unspecified").
	     */

	    if (tagPtr->borderWidth < 0) {
		tagPtr->borderWidth = 0;
	    }
	    if (tagPtr->reliefString != NULL) {
		if (Tk_GetRelief(interp, tagPtr->reliefString,
			&tagPtr->relief) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->justifyString != NULL) {
		if (Tk_GetJustify(interp, tagPtr->justifyString,
			&tagPtr->justify) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->lMargin1String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->lMargin2String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) {
		    return TCL_ERROR;

		}
	    }
	    if (tagPtr->offsetString != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString,
			&tagPtr->offset) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->overstrikeString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->overstrikeString,
			&tagPtr->overstrike) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->rMarginString != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->spacing1String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (tagPtr->spacing1 < 0) {
		    tagPtr->spacing1 = 0;
		}
	    }
	    if (tagPtr->spacing2String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (tagPtr->spacing2 < 0) {
		    tagPtr->spacing2 = 0;
		}
	    }
	    if (tagPtr->spacing3String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) {
		    return TCL_ERROR;

		}
		if (tagPtr->spacing3 < 0) {
		    tagPtr->spacing3 = 0;
		}
	    }
	    if (tagPtr->tabArrayPtr != NULL) {
		ckfree(tagPtr->tabArrayPtr);
		tagPtr->tabArrayPtr = NULL;
	    }
	    if (tagPtr->tabStringPtr != NULL) {
		tagPtr->tabArrayPtr =
			TkTextGetTabs(interp, textPtr, tagPtr->tabStringPtr);
		if (tagPtr->tabArrayPtr == NULL) {
		    return TCL_ERROR;
		}
	    }


	    if (tagPtr->underlineString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->underlineString,
			&tagPtr->underline) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->elideString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->elideString,
			&tagPtr->elide) != TCL_OK) {
		    return TCL_ERROR;
		}

		/*
		 * Indices are potentially obsolete after changing -elide,
		 * especially those computed with "display" or "any"
		 * submodifier, therefore increase the epoch.
		 */

		textPtr->sharedTextPtr->stateEpoch++;
	    }

	    /*
	     * If the "sel" tag was changed, be sure to mirror information
	     * from the tag back into the text widget record. NOTE: we don't
	     * have to free up information in the widget record before
	     * overwriting it, because it was mirrored in the tag and hence
	     * freed when the tag field was overwritten.
	     */

	    if (tagPtr == textPtr->selTagPtr) {
                if (tagPtr->selBorder == NULL) {
                    textPtr->selBorder = tagPtr->border;
                } else {
                    textPtr->selBorder = tagPtr->selBorder;
                }
		textPtr->selBorderWidth = tagPtr->borderWidth;
		textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr;
                if (tagPtr->selFgColor == NULL) {
                    textPtr->selFgColorPtr = tagPtr->fgColor;
                } else {
                    textPtr->selFgColorPtr = tagPtr->selFgColor;
                }
	    }

	    tagPtr->affectsDisplay = 0;
	    tagPtr->affectsDisplayGeometry = 0;
	    if ((tagPtr->elideString != NULL)
		    || (tagPtr->tkfont != NULL)
		    || (tagPtr->justifyString != NULL)
		    || (tagPtr->lMargin1String != NULL)
		    || (tagPtr->lMargin2String != NULL)
		    || (tagPtr->offsetString != NULL)
		    || (tagPtr->rMarginString != NULL)
		    || (tagPtr->spacing1String != NULL)
		    || (tagPtr->spacing2String != NULL)
		    || (tagPtr->spacing3String != NULL)
		    || (tagPtr->tabStringPtr != NULL)
		    || (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
		    || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
		tagPtr->affectsDisplay = 1;
		tagPtr->affectsDisplayGeometry = 1;
	    }
	    if ((tagPtr->border != NULL)
		    || (tagPtr->selBorder != NULL)
		    || (tagPtr->reliefString != NULL)
		    || (tagPtr->bgStipple != None)
		    || (tagPtr->fgColor != NULL)
		    || (tagPtr->selFgColor != NULL)
		    || (tagPtr->fgStipple != None)
		    || (tagPtr->overstrikeString != NULL)
                    || (tagPtr->overstrikeColor != NULL)
		    || (tagPtr->underlineString != NULL)
                    || (tagPtr->underlineColor != NULL)
                    || (tagPtr->lMarginColor != NULL)
                    || (tagPtr->rMarginColor != NULL)) {
		tagPtr->affectsDisplay = 1;

	    }
	    if (!newTag) {
		/*
		 * This line is not necessary if this is a new tag, since it
		 * can't possibly have been applied to anything yet.
		 */

		/*
		 * VMD: If this is the 'sel' tag, then we don't need to call
		 * this for all peers, unless we actually want to synchronize
		 * sel-style changes across the peers.
		 */

		TkTextRedrawTag(textPtr->sharedTextPtr, NULL,
			NULL, NULL, tagPtr, 1);
	    }



	    return result;
	}
	break;
    }

    case TAG_DELETE: {
	Tcl_HashEntry *hPtr;


	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?");
	    return TCL_ERROR;
	}
	for (i = 3; i < objc; i++) {

	    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable,
		    Tcl_GetString(objv[i]));
	    if (hPtr == NULL) {
		/*
		 * Either this tag doesn't exist or it's the 'sel' tag (which
		 * is not in the hash table). Either way we don't want to
		 * delete it.
		 */

		continue;
	    }
	    tagPtr = (TkTextTag *)Tcl_GetHashValue(hPtr);














	    if (tagPtr == textPtr->selTagPtr) {





















		continue;




	    }





	    if (tagPtr->affectsDisplay) {





















		TkTextRedrawTag(textPtr->sharedTextPtr, NULL,









			NULL, NULL, tagPtr, 1);



	    }













	    TkTextDeleteTag(textPtr, tagPtr);


	    Tcl_DeleteHashEntry(hPtr);



	}
	break;
    }
    case TAG_LOWER: {
	TkTextTag *tagPtr2;
	int prio;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?belowThis?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(interp, textPtr, objv[3]);
	if (tagPtr == NULL) {
	    return TCL_ERROR;
	}
	if (objc == 5) {
	    tagPtr2 = FindTag(interp, textPtr, objv[4]);
	    if (tagPtr2 == NULL) {
		return TCL_ERROR;
	    }

	    if (tagPtr->priority < tagPtr2->priority) {
		prio = tagPtr2->priority - 1;
	    } else {
		prio = tagPtr2->priority;
	    }
	} else {
	    prio = 0;
	}
	ChangeTagPriority(textPtr, tagPtr, prio);

	/*
	 * If this is the 'sel' tag, then we don't actually need to call this
	 * for all peers.
	 */

	TkTextRedrawTag(textPtr->sharedTextPtr, NULL, NULL, NULL, tagPtr, 1);
	break;
    }
    case TAG_NAMES: {
	TkTextTag **arrayPtr;
	int arraySize;
	Tcl_Obj *listObj;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?index?");
	    return TCL_ERROR;
	}
	if (objc == 3) {
	    Tcl_HashSearch search;
	    Tcl_HashEntry *hPtr;

	    arrayPtr = (TkTextTag **)ckalloc(textPtr->sharedTextPtr->numTags
		    * sizeof(TkTextTag *));
	    for (i=0, hPtr = Tcl_FirstHashEntry(
		    &textPtr->sharedTextPtr->tagTable, &search);
		    hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
		arrayPtr[i] = (TkTextTag *)Tcl_GetHashValue(hPtr);
	    }

	    /*
	     * The 'sel' tag is not in the hash table.



	     */

	    arrayPtr[i] = textPtr->selTagPtr;
	    arraySize = ++i;
	} else {
	    if (TkTextGetObjIndex(interp, textPtr, objv[3],
		    &index1) != TCL_OK) {
		return TCL_ERROR;
	    }
	    arrayPtr = TkBTreeGetTags(&index1, textPtr, &arraySize);
	    if (arrayPtr == NULL) {
		return TCL_OK;
	    }
	}

	SortTags(arraySize, arrayPtr);
	listObj = Tcl_NewListObj(0, NULL);

	for (i = 0; i < arraySize; i++) {
	    tagPtr = arrayPtr[i];
	    Tcl_ListObjAppendElement(interp, listObj,
		    Tcl_NewStringObj(tagPtr->name,-1));
	}
	Tcl_SetObjResult(interp, listObj);
	ckfree(arrayPtr);
	break;
    }



    case TAG_NEXTRANGE: {
	TkTextIndex last;
	TkTextSearch tSearch;
	char position[TK_POS_CHARS];
	Tcl_Obj *resultObj;

	if ((objc != 5) && (objc != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {
	    return TCL_OK;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
		TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
		0, &last);
	if (objc == 5) {
	    index2 = last;
	} else if (TkTextGetObjIndex(interp, textPtr, objv[5],
		&index2) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * The search below is a bit tricky. Rather than use the B-tree
	 * facilities to stop the search at index2, let it search up until the
	 * end of the file but check for a position past index2 ourselves.
	 * The reason for doing it this way is that we only care whether the
	 * *start* of the range is before index2; once we find the start, we
	 * don't want TkBTreeNextTag to abort the search because the end of
	 * the range is after index2.
	 */

	TkBTreeStartSearch(&index1, &last, tagPtr, &tSearch);
	if (TkBTreeCharTagged(&index1, tagPtr)) {
	    TkTextSegment *segPtr;
	    int offset;

	    /*
	     * The first character is tagged. See if there is an on-toggle
	     * just before the character. If not, then skip to the end of this
	     * tagged range.
	     */

	    for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex;
		    offset >= 0;
		    offset -= segPtr->size, segPtr = segPtr->nextPtr) {
		if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType)
			&& (segPtr->body.toggle.tagPtr == tagPtr)) {
		    goto gotStart;
		}
	    }
	    if (!TkBTreeNextTag(&tSearch)) {
		return TCL_OK;
	    }
	}

	/*
	 * Find the start of the tagged range.
	 */

	if (!TkBTreeNextTag(&tSearch)) {
	    return TCL_OK;
	}

    gotStart:
	if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) {
	    return TCL_OK;
	}
	resultObj = Tcl_NewObj();
	TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position, -1));

	TkBTreeNextTag(&tSearch);

	TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position, -1));
	Tcl_SetObjResult(interp, resultObj);

	break;
    }
    case TAG_PREVRANGE: {
	TkTextIndex last;
	TkTextSearch tSearch;
	char position1[TK_POS_CHARS];
	char position2[TK_POS_CHARS];
	Tcl_Obj *resultObj;

	if ((objc != 5) && (objc != 6)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {
	    return TCL_OK;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 5) {
	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
		    &index2);
	} else if (TkTextGetObjIndex(interp, textPtr, objv[5],
		&index2) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * The search below is a bit weird. The previous toggle can be either
	 * an on or off toggle. If it is an on toggle, then we need to turn
	 * around and search forward for the end toggle. Otherwise we keep
	 * searching backwards.
	 */

	TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch);

	if (!TkBTreePrevTag(&tSearch)) {
	    /*


	     * Special case, there may be a tag off toggle at index1, and a
	     * tag on toggle before the start of a partial peer widget. In
	     * this case we missed it.
	     */

	    if (textPtr->start != NULL && (textPtr->start == index2.linePtr)
		    && (index2.byteIndex == 0)
		    && TkBTreeCharTagged(&index2, tagPtr)
		    && (TkTextIndexCmp(&index2, &index1) < 0)) {
		/*
		 * The first character is tagged, so just add the range from
		 * the first char to the start of the range.

		 */

		TkTextPrintIndex(textPtr, &index2, position1);
		TkTextPrintIndex(textPtr, &index1, position2);
		goto gotPrevIndexPair;
	    }
	    return TCL_OK;
	}



	if (tSearch.segPtr->typePtr == &tkTextToggleOnType) {

	    TkTextPrintIndex(textPtr, &tSearch.curIndex, position1);
	    if (textPtr->start != NULL) {

		/*
		 * Make sure the first index is not before the first allowed
		 * text index in this widget.

		 */

		TkTextIndex firstIndex;

		firstIndex.linePtr = textPtr->start;
		firstIndex.byteIndex = 0;
		firstIndex.textPtr = NULL;
		if (TkTextIndexCmp(&tSearch.curIndex, &firstIndex) < 0) {
		    if (TkTextIndexCmp(&firstIndex, &index1) >= 0) {
			/*
			 * But now the new first index is actually too far
			 * along in the text, so nothing is returned.
			 */


			return TCL_OK;
		    }
		    TkTextPrintIndex(textPtr, &firstIndex, position1);
		}
	    }
	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
		    TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
		    0, &last);
	    TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch);
	    TkBTreeNextTag(&tSearch);
	    TkTextPrintIndex(textPtr, &tSearch.curIndex, position2);
	} else {
	    TkTextPrintIndex(textPtr, &tSearch.curIndex, position2);
	    TkBTreePrevTag(&tSearch);
	    TkTextPrintIndex(textPtr, &tSearch.curIndex, position1);
	    if (TkTextIndexCmp(&tSearch.curIndex, &index2) < 0) {
		if (textPtr->start != NULL && index2.linePtr == textPtr->start
			&& index2.byteIndex == 0) {
		    /* It's ok */
		    TkTextPrintIndex(textPtr, &index2, position1);
		} else {
		    return TCL_OK;
		}
	    }
	}

    gotPrevIndexPair:
	resultObj = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position1, -1));
	Tcl_ListObjAppendElement(NULL, resultObj,
		Tcl_NewStringObj(position2, -1));
	Tcl_SetObjResult(interp, resultObj);

	break;
    }










    case TAG_RAISE: {
	TkTextTag *tagPtr2;
	int prio;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?aboveThis?");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(interp, textPtr, objv[3]);
	if (tagPtr == NULL) {
	    return TCL_ERROR;
	}
	if (objc == 5) {
	    tagPtr2 = FindTag(interp, textPtr, objv[4]);
	    if (tagPtr2 == NULL) {
		return TCL_ERROR;
	    }
	    if (tagPtr->priority <= tagPtr2->priority) {
		prio = tagPtr2->priority;
	    } else {
		prio = tagPtr2->priority + 1;
	    }
	} else {
	    prio = textPtr->sharedTextPtr->numTags-1;
	}
	ChangeTagPriority(textPtr, tagPtr, prio);




	/*
	 * If this is the 'sel' tag, then we don't actually need to call this
	 * for all peers.



	 */


	TkTextRedrawTag(textPtr->sharedTextPtr, NULL, NULL, NULL, tagPtr, 1);

	break;
    }
    case TAG_RANGES: {
	TkTextIndex first, last;
	TkTextSearch tSearch;
	Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
	int count = 0;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName");
	    return TCL_ERROR;
	}
	tagPtr = FindTag(NULL, textPtr, objv[3]);
	if (tagPtr == NULL) {
	    return TCL_OK;
	}
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
		&first);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
		TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
		0, &last);
	TkBTreeStartSearch(&first, &last, tagPtr, &tSearch);
	if (TkBTreeCharTagged(&first, tagPtr)) {
	    Tcl_ListObjAppendElement(NULL, listObj,
		    TkTextNewIndexObj(textPtr, &first));
	    count++;
	}
	while (TkBTreeNextTag(&tSearch)) {
	    Tcl_ListObjAppendElement(NULL, listObj,
		    TkTextNewIndexObj(textPtr, &tSearch.curIndex));
	    count++;
	}
	if (count % 2 == 1) {
	    /*
	     * If a text widget uses '-end', it won't necessarily run to the
	     * end of the B-tree, and therefore the tag range might not be
	     * closed. In this case we add the end of the range.
	     */

	    Tcl_ListObjAppendElement(NULL, listObj,
		    TkTextNewIndexObj(textPtr, &last));
	}
	Tcl_SetObjResult(interp, listObj);
	break;
    }
    }





















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextCreateTag --
 *
 *	Find the record describing a tag within a given text widget, creating
 *	a new record if one doesn't already exist.
 *
 * Results:
 *	The return value is a pointer to the TkTextTag record for tagName.
 *
 * Side effects:
 *	A new tag record is created if there isn't one already defined for
 *	tagName.
 *
 *----------------------------------------------------------------------
 */
















TkTextTag *
TkTextCreateTag(
    TkText *textPtr,		/* Widget in which tag is being used. */
    const char *tagName,	/* Name of desired tag. */
    int *newTag)		/* If non-NULL, then return 1 if new, or 0 if
				 * already exists. */
{

    TkTextTag *tagPtr;
    Tcl_HashEntry *hPtr = NULL;
    int isNew;

    const char *name;


    if (!strcmp(tagName, "sel")) {


	if (textPtr->selTagPtr != NULL) {
	    if (newTag != NULL) {
		*newTag = 0;
	    }
	    return textPtr->selTagPtr;
	}
	if (newTag != NULL) {
	    *newTag = 1;
	}
	name = "sel";
    } else {
	hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->tagTable,
		tagName, &isNew);
	if (newTag != NULL) {
	    *newTag = isNew;
	}
	if (!isNew) {
	    return (TkTextTag *)Tcl_GetHashValue(hPtr);
	}
	name = (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->tagTable, hPtr);
























    }

    /*
     * No existing entry. Create a new one, initialize it, and add a pointer
     * to it to the hash table entry.
     */

    tagPtr = (TkTextTag *)ckalloc(sizeof(TkTextTag));

    tagPtr->name = name;
    tagPtr->textPtr = NULL;
    tagPtr->toggleCount = 0;
    tagPtr->tagRootPtr = NULL;
    tagPtr->priority = textPtr->sharedTextPtr->numTags;
    tagPtr->border = NULL;
    tagPtr->borderWidth = 0;
    tagPtr->borderWidthPtr = NULL;
    tagPtr->reliefString = NULL;
    tagPtr->relief = TK_RELIEF_FLAT;
    tagPtr->bgStipple = None;
    tagPtr->fgColor = NULL;
    tagPtr->tkfont = NULL;
    tagPtr->fgStipple = None;
    tagPtr->justifyString = NULL;
    tagPtr->justify = TK_JUSTIFY_LEFT;
    tagPtr->lMargin1String = NULL;
    tagPtr->lMargin1 = 0;
    tagPtr->lMargin2String = NULL;
    tagPtr->lMargin2 = 0;
    tagPtr->lMarginColor = NULL;
    tagPtr->offsetString = NULL;
    tagPtr->offset = 0;
    tagPtr->overstrikeString = NULL;
    tagPtr->overstrike = 0;
    tagPtr->overstrikeColor = NULL;
    tagPtr->rMarginString = NULL;
    tagPtr->rMargin = 0;
    tagPtr->rMarginColor = NULL;
    tagPtr->selBorder = NULL;
    tagPtr->selFgColor = NULL;
    tagPtr->spacing1String = NULL;
    tagPtr->spacing1 = 0;
    tagPtr->spacing2String = NULL;
    tagPtr->spacing2 = 0;
    tagPtr->spacing3String = NULL;
    tagPtr->spacing3 = 0;
    tagPtr->tabStringPtr = NULL;
    tagPtr->tabArrayPtr = NULL;
    tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE;
    tagPtr->underlineString = NULL;
    tagPtr->underline = 0;
    tagPtr->underlineColor = NULL;
    tagPtr->elideString = NULL;
    tagPtr->elide = 0;
    tagPtr->wrapMode = TEXT_WRAPMODE_NULL;



    tagPtr->affectsDisplay = 0;


    tagPtr->affectsDisplayGeometry = 0;


    textPtr->sharedTextPtr->numTags++;

    if (!strcmp(tagName, "sel")) {

	tagPtr->textPtr = textPtr;
	textPtr->refCount++;


    } else {
	CLANG_ASSERT(hPtr);
	Tcl_SetHashValue(hPtr, tagPtr);
    }
    tagPtr->optionTable =
	    Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs);

    return tagPtr;
}






































/*
 *----------------------------------------------------------------------
 *
 * FindTag --
 *
 *	See if tag is defined for a given widget.







|

|
|
<
|


|
>
|


|
|
|

|
>


>





<
|
|


>
>





>

<
|
<
<
<

|
<



|
|
|
|
|
|
|


|
<


|
|
<


|
<
<
<
|
<
|
<
<
<
<

<
<
<
<
|
<

|
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
>
|
|
|
|
<
<
|
<
|
>
|
<
<




|




|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<







|
<




|






|
>
>
>
>
|


|
<


<
<
<
<
<

|
<
|
|
>
|
|
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
>
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
|
<
<
<
<
<
|
|
<
<
<
<
|
<


|
|

|
<
<
<
<
>
|
<
<
<
<
<
<
<
|
|
<
|
<
<
|
|
>
>
|
|
|
<
|
<
|
|
<
<
|
|
<
<
<
<
<
|
<
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
|
<
<
<
<
|
<
<
<
<
<
|
<
<
|
>
>
>
|

<
<
>


>






>
|
|
<

|
|
<





>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>





|

|



|
<



|
<


>

|
<
<


|

<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<

|
>
>
>


<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<

<
<


>
>
>

<




|



|
<


|


<
<
<

|
|
<



<
<
|
<
<
<
|
<
<
|
|
|
|
<

|
|
|
<
|

<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
|
|
|
<
<
|
<
|
|
|
|
<
>
|
>
|
|
<
|
>



<





|



|
<


|



|
<
|
<



<
<
<
<
<
<
<
|

|
<
>
>
|
<
<
<
|
|
|
<
<

<
<
>


<
|
|
<
<
<
|
>
>
|
>
|
<
>

<
<
>

<
<
<
<
<
<
<
<
<
<
<
<

>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
<
<
|
<
<
<
<
|
|
<
|
<
|
>


>
>
>
>
>
>
>
>
>
>


|

|



|
<



|
<


|
|
<
|


|

|
>
>
|
>
|
|
<
>
>
>
|

>
|
>





|
|





|
<
<
<
<
<
|
|
<
|
<
<
<
<
<
|
|
<
|
|
<
<
<
<
<
<
|
|
<

<



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
<

>



>

>

|
>
>
|
|




|




|
<
|



|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>

|
<
<
|
|
<
<
<
<

<
<

|
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<

>
>
>
|
>
>
|
>
>
|
>
|
>

|
>
>

|


|
|
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301
302

303



304
305

306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321
322

323
324
325



326

327




328




329

330
331



332







333






334
335
336
337
338
339


340

341
342
343


344
345
346
347
348
349
350
351
352
353



































































354


355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

383
384





385
386

387
388
389
390
391

392




393






394






395
396











397
398
399
400
401
402
403
404

405












406

407
408





409
410




411

412
413
414
415
416
417




418
419







420
421

422


423
424
425
426
427
428
429

430

431
432


433
434





435

436
437







438





439






440



















441
442













443
444
445




446





447


448
449
450
451
452
453


454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

591
592
593
594

595
596
597
598
599


600
601
602
603

604




605







606



607










608

609
610
611
612
613
614
615












616


617




618


619
620
621
622
623
624

625
626
627
628
629
630
631
632
633

634
635
636
637
638



639
640
641

642
643
644


645



646


647
648
649
650

651
652
653
654

655
656












657



658
659
660
661


662

663
664
665
666

667
668
669
670
671

672
673
674
675
676

677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693

694

695
696
697







698
699
700

701
702
703



704
705
706


707


708
709
710

711
712



713
714
715
716
717
718

719
720


721
722












723
724
725
726













727
728


729


730




731
732

733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760

761
762
763
764

765
766
767
768
769
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797





798
799

800





801
802

803
804






805
806

807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832

1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898


1899
1900




1901


1902
1903
1904











1905











1906





1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkTextTagCmd(
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already parsed this command

    				 * enough to know that objv[1] is "tag". */
{
    static const char *const tagOptionStrings[] = {
	"add", "bind", "cget", "clear", "configure", "delete", "findnext", "findprev",
	"getrange", "lower", "names", "nextrange", "prevrange", "priority", "raise",
	"ranges", "remove", NULL
    };
    enum tagOptions {
	TAG_ADD, TAG_BIND, TAG_CGET, TAG_CLEAR, TAG_CONFIGURE, TAG_DELETE, TAG_FINDNEXT, TAG_FINDPREV,
	TAG_GETRANGE, TAG_LOWER, TAG_NAMES, TAG_NEXTRANGE, TAG_PREVRANGE, TAG_PRIORITY, TAG_RAISE,
	TAG_RANGES, TAG_REMOVE
    };
    int optionIndex;
    Tcl_Size i;
    TkTextTag *tagPtr;
    TkTextIndex index1, index2;
    TkSharedText *sharedTextPtr;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], tagOptionStrings, sizeof(char *),
	    "tag option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    sharedTextPtr = textPtr->sharedTextPtr;

    switch ((enum tagOptions)optionIndex) {
    case TAG_ADD:
    case TAG_REMOVE: {
	int addTag;
	int anyChanges = 0;


	addTag = ((enum tagOptions) optionIndex) == TAG_ADD;



	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2 index1 index2 ...?");

	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
	if (tagPtr->elide >= 0) {
	    /*
	     * Indices are potentially obsolete after adding or removing
	     * elided character ranges, especially indices having "display"
	     * or "any" submodifier, therefore increase the epoch.
	     */
	    TkBTreeIncrEpoch(sharedTextPtr->tree);
	}
	for (i = 4; i < objc; i += 2) {
	    if (!TkTextGetIndexFromObj(interp, textPtr, objv[i], &index1)) {

		return TCL_ERROR;
	    }
	    if (objc > i + 1) {
		if (!TkTextGetIndexFromObj(interp, textPtr, objv[i + 1], &index2)) {

		    return TCL_ERROR;
		}
		if (TkTextIndexCompare(&index1, &index2) >= 0) {



		    continue;

		}




	    } else {




		TkTextIndexForwChars(textPtr, &index1, 1, &index2, COUNT_INDICES);

	    }
	    if (TagAddRemove(textPtr, &index1, &index2, tagPtr, addTag)) {



		anyChanges = 1;







	    }






	}
	if (tagPtr->isSelTag) {
	    GrabSelection(textPtr, tagPtr, addTag, anyChanges);
	}
	if (anyChanges) {
	    if (tagPtr->undo) {


		TkTextUpdateAlteredFlag(sharedTextPtr);

	    }
	    /* still need to trigger enter/leave events on tags that have changed */
	    TkTextEventuallyRepick(textPtr);


	}
	break;
    }
    case TAG_BIND:
	if (objc < 4 || objc > 6) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?command?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
	return TkTextBindEvent(interp, objc - 4, objv + 4, sharedTextPtr,



































































		&sharedTextPtr->tagBindingTable, tagPtr->name);


    case TAG_CGET:
	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 1, objv, "tag cget tagName option");
	    return TCL_ERROR;
	} else {
	    Tcl_Obj *objPtr;

	    if (!(tagPtr = FindTag(interp, textPtr, objv[3]))) {

		return TCL_ERROR;
	    }
	    objPtr = Tk_GetOptionValue(interp, tagPtr,
		    tagPtr->optionTable, objv[4], textPtr->tkwin);
	    if (!objPtr) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
	break;
    case TAG_CLEAR: {
	int discardSelection;
	Tcl_Size epoch, countTags;
	TkTextTag **arrayPtr;
	int anyChanges;
	int arg;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?-discardselection? index1 ?index2 index1 index2 ...?");

	    return TCL_ERROR;
	}






	arg = 3;


	if (objc > 4 && *Tcl_GetString(objv[arg]) == '-') {
	    if (strcmp(Tcl_GetString(objv[arg++]), "-discardselection") == 0) {
		discardSelection = 1;
	    } else {

		Tcl_SetObjResult(interp, Tcl_ObjPrintf(




			"bad option \"%s\": must be -discardselection", Tcl_GetString(objv[3])));






		Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_OPTION", (char *)NULL);






		return TCL_ERROR;
	    }











	}

	discardSelection = 0;
	epoch = TkBTreeEpoch(sharedTextPtr->tree);
	arrayPtr = (TkTextTag **)ckalloc(sharedTextPtr->numEnabledTags * sizeof(TkTextTag *));
	countTags = 0;
	anyChanges = 0;


	for (i = arg; i < objc; i += 2) {












	    if (!TkTextGetIndexFromObj(interp, textPtr, objv[i], &index1)) {

		return TCL_ERROR;
	    }






	    if (objc > i + 1) {




		if (!TkTextGetIndexFromObj(interp, textPtr, objv[i + 1], &index2)) {

		    return TCL_ERROR;
		}
		if (TkTextIndexCompare(&index1, &index2) >= 0) {
		    continue;
		}
	    } else {




		TkTextIndexForwChars(textPtr, &index1, 1, &index2, COUNT_INDICES);
	    }








	    if (!discardSelection) {

		TkTextClearSelection(sharedTextPtr, &index1, &index2);


	    }

	    if ((tagPtr = TkTextClearTags(sharedTextPtr, textPtr, &index1, &index2, discardSelection))) {
		for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
		    if (tagPtr->epoch != epoch) {
			tagPtr->epoch = epoch;
			arrayPtr[countTags++] = tagPtr;



			if (tagPtr->isSelTag) {
			    GrabSelection(textPtr, tagPtr, 0, 1);


			}
			if (tagPtr->undo) {





			    anyChanges = 1;

			}
		    }







		}





	    }






	}




















	if (anyChanges) {













	    TkTextUpdateAlteredFlag(sharedTextPtr);
	}
	AppendTags(interp, countTags, arrayPtr);




	ckfree(arrayPtr);





	break;


    }
    case TAG_CONFIGURE:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?-option value ...?");
	    return TCL_ERROR;
	}


	return TkConfigureTag(interp, textPtr, Tcl_GetString(objv[3]), 1, objc - 4, objv + 4);
    case TAG_DELETE: {
	Tcl_HashEntry *hPtr;
	int anyChanges = 0;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?");
	    return TCL_ERROR;
	}
	for (i = 3; i < objc; i++) {
	    int undo;

	    if (!(hPtr = Tcl_FindHashEntry(&sharedTextPtr->tagTable, Tcl_GetString(objv[i])))) {

		/*
		 * Either this tag doesn't exist or it's the 'sel' tag (which is not in
		 * the hash table). Either way we don't want to delete it.

		 */

		continue;
	    }
	    tagPtr = (TkTextTag *)Tcl_GetHashValue(hPtr);
	    undo = tagPtr->undo;
	    assert(!tagPtr->isSelTag);
	    if (TkTextDeleteTag(textPtr, tagPtr, hPtr) && undo) {
		anyChanges = 1;
	    }
	}
	if (anyChanges) {
	    TkTextUpdateAlteredFlag(sharedTextPtr);
	}
	break;
    }
    case TAG_FINDNEXT: {
	TkTextSegment *segPtr;
	const TkBitField *selTags = NULL;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?-discardselection? index");
	    return TCL_ERROR;
	}
	if (objc == 5) {
	    if (strcmp(Tcl_GetString(objv[3]), "-discardselection") == 0) {
		selTags = sharedTextPtr->selectionTags;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": must be -discardselection", Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_OPTION", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[objc - 1], &index1)) {
	    return TCL_ERROR;
	}
	TkTextIndexSetupToEndOfText(&index2, textPtr, sharedTextPtr->tree);
	if ((segPtr = TkBTreeFindNextTagged(&index1, &index2, selTags))) {
	    TkTextIndex index;
	    char buf[TK_POS_CHARS];

	    TkTextIndexClear(&index, textPtr);
	    TkTextIndexSetSegment(&index, segPtr);
	    TkrTextPrintIndex(textPtr, &index, buf);
	    Tcl_AppendElement(interp, buf);
	}
	break;
    }
    case TAG_FINDPREV: {
	int discardSelection = 0;
	TkTextSegment *segPtr;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "?-discardselection? index");
	    return TCL_ERROR;
	}
	if (objc == 5) {
	    if (strcmp(Tcl_GetString(objv[3]), "-discardselection") == 0) {
		discardSelection = 1;
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad option \"%s\": must be -discardselection", Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_OPTION", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[objc - 1], &index1)) {
	    return TCL_ERROR;
	}
	TkTextIndexSetupToStartOfText(&index2, textPtr, sharedTextPtr->tree);
	if ((segPtr = TkBTreeFindPrevTagged(&index1, &index2, discardSelection))) {
	    TkTextIndex index;
	    char buf[TK_POS_CHARS];

	    TkTextIndexClear(&index, textPtr);
	    TkTextIndexSetSegment(&index, segPtr);
	    TkrTextPrintIndex(textPtr, &index, buf);
	    Tcl_AppendElement(interp, buf);
	}
	break;
    }
    case TAG_GETRANGE: {
	TkTextIndex index;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[4], &index)) {
	    return TCL_ERROR;
	}
	if (!(tagPtr = FindTag(interp, textPtr, objv[3]))) {
	    return TCL_ERROR;
	}
	if (tagPtr->rootPtr && TkBTreeCharTagged(&index, tagPtr)) {
	    TkTextIndex result;
	    char buf[TK_POS_CHARS];

	    /* point to position after index */
	    TkTextIndexForwChars(textPtr, &index, 1, &index, COUNT_INDICES);

	    TkTextTagFindStartOfRange(textPtr, tagPtr, &index, &result);
	    TkrTextPrintIndex(textPtr, &result, buf);
	    Tcl_AppendElement(interp, buf);

	    TkTextTagFindEndOfRange(textPtr, tagPtr, &index, &result);
	    TkrTextPrintIndex(textPtr, &result, buf);
	    Tcl_AppendElement(interp, buf);
	}
	break;
    }
    case TAG_LOWER: {
	TkTextTag *tagPtr2;
	unsigned newPriority;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?belowThis?");
	    return TCL_ERROR;
	}
	if (!(tagPtr = FindTag(interp, textPtr, objv[3]))) {

	    return TCL_ERROR;
	}
	if (objc == 5) {
	    if (!(tagPtr2 = FindTag(interp, textPtr, objv[4]))) {

		return TCL_ERROR;
	    }
	    newPriority = tagPtr2->priority;
	    if (tagPtr->priority < tagPtr2->priority) {
		newPriority -= 1;


	    }
	} else {
	    newPriority = 0;
	}

	if (ChangeTagPriority(sharedTextPtr, tagPtr, newPriority, 1) && tagPtr->rootPtr) {




	    if (tagPtr->undo) {







		TkTextUpdateAlteredFlag(sharedTextPtr);



	    }












	    /*
	     * If this is the 'sel' tag, then we don't actually need to call this for all peers.
	     *
	     * TODO: The current implementation is sloppy, we need only to refresh the ranges
	     * with actual changes, and not all the ranges of this tag.
	     */













	    TkTextRedrawTag(tagPtr->isSelTag ? NULL : sharedTextPtr,


		    textPtr, NULL, NULL, tagPtr, 0);




	}


	break;
    }
    case TAG_NAMES:
    	return EnumerateTags(interp, textPtr, objc, objv);
	/* not reached */
    case TAG_NEXTRANGE: {

	TkTextSearch tSearch;
	char position[TK_POS_CHARS];
	Tcl_Obj *resultObj;

	if (objc != 5 && objc != 6) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	if (!(tagPtr = FindTag(NULL, textPtr, objv[3])) || !tagPtr->rootPtr) {

	    return TCL_OK;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[4], &index1)) {
	    return TCL_ERROR;
	}



	if (objc == 5) {
	    TkTextIndexSetupToEndOfText(&index2, textPtr, sharedTextPtr->tree);
	} else if (!TkTextGetIndexFromObj(interp, textPtr, objv[5], &index2)) {

	    return TCL_ERROR;
	}



	TkBTreeStartSearch(&index1, &index2, tagPtr, &tSearch, SEARCH_NEXT_TAGON);



	if (TkBTreeNextTag(&tSearch)) {


	    assert(TkTextIndexCompare(&tSearch.curIndex, &index1) >= 0);
	    assert(TkTextIndexCompare(&tSearch.curIndex, &index2) < 0);
	    if (TkTextIndexIsEqual(&index1, &tSearch.curIndex)) {
		TkTextIndex oneBack;


		/*
		 * The first character is tagged. See if there is an on-toggle just
		 * before the character. If not, then skip to the end of this tagged range.

		 */













		if (TkTextIndexBackChars(textPtr, &index1, 1, &oneBack, COUNT_DISPLAY_INDICES)



			&& TkBTreeCharTagged(&oneBack, tagPtr)
			&& (!TkBTreeNextTag(&tSearch) || !TkBTreeNextTag(&tSearch))) {
		    return TCL_OK;
		}


		assert(TkTextIndexCompare(&tSearch.curIndex, &index2) < 0);

	    }
	    resultObj = Tcl_NewObj();
	    TkrTextPrintIndex(textPtr, &tSearch.curIndex, position);
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(position, TCL_INDEX_NONE));

	    TkBTreeLiftSearch(&tSearch); /* we need tagoff even if outside of the range */
	    TkBTreeNextTag(&tSearch);    /* cannot fail */
	    assert(tSearch.segPtr);      /* proof last assumption */
	    TkrTextPrintIndex(textPtr, &tSearch.curIndex, position);
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(position, TCL_INDEX_NONE));

	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    }
    case TAG_PREVRANGE: {

	TkTextSearch tSearch;
	char position1[TK_POS_CHARS];
	char position2[TK_POS_CHARS];
	Tcl_Obj *resultObj;

	if (objc != 5 && objc != 6) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
	    return TCL_ERROR;
	}
	if (!(tagPtr = FindTag(NULL, textPtr, objv[3])) || !tagPtr->rootPtr) {

	    return TCL_OK;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[4], &index1)) {
	    return TCL_ERROR;
	}
	if (objc == 5) {
	    TkTextIndexSetupToStartOfText(&index2, textPtr, sharedTextPtr->tree);

	} else if (!TkTextGetIndexFromObj(interp, textPtr, objv[5], &index2)) {

	    return TCL_ERROR;
	}








	TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch, SEARCH_EITHER_TAGON_TAGOFF);

	if (TkBTreePrevTag(&tSearch)) {

	    assert(TkTextIndexCompare(&tSearch.curIndex, &index1) <= 0);
	    assert(TkTextIndexCompare(&tSearch.curIndex, &index2) >= 0);
	    index1 = tSearch.curIndex;



	    if (tSearch.tagon) {
		TkTextIndex end;



		/*


		 * We've found tagon. Now search forward for tagoff.
		 */


		TkrTextPrintIndex(textPtr, &index1, position1);
		TkTextIndexSetupToEndOfText(&end, textPtr, sharedTextPtr->tree);



		TkTextIndexForwChars(textPtr, &index1, 1, &index1, COUNT_INDICES);
		TkBTreeStartSearch(&index1, &end, tagPtr, &tSearch, SEARCH_EITHER_TAGON_TAGOFF);
		TkBTreeNextTag(&tSearch); /* cannot fail */
		assert(tSearch.segPtr);   /* proof last assumption */
		assert(!tSearch.tagon);   /* must be tagoff */
		TkrTextPrintIndex(textPtr, &tSearch.curIndex, position2);

	    } else {
		/*


		 * We've found tagoff. Now search backwards for tagon.
		 */













		if (!TkBTreePrevTag(&tSearch)) {
		    return TCL_OK;
		}













		assert(TkTextIndexCompare(&tSearch.curIndex, &index2) >= 0);
		TkrTextPrintIndex(textPtr, &tSearch.curIndex, position1);


		TkrTextPrintIndex(textPtr, &index1, position2);


	    }




	    resultObj = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(position1, TCL_INDEX_NONE));

	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(position2, TCL_INDEX_NONE));

	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    }
    case TAG_PRIORITY:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName");
	    return TCL_ERROR;
	}
	if (!(tagPtr = FindTag(interp, textPtr, objv[3]))) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(tagPtr->priority));
	break;
    case TAG_RAISE: {
	TkTextTag *tagPtr2;
	unsigned newPriority;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName ?aboveThis?");
	    return TCL_ERROR;
	}
	if (!(tagPtr = FindTag(interp, textPtr, objv[3]))) {

	    return TCL_ERROR;
	}
	if (objc == 5) {
	    if (!(tagPtr2 = FindTag(interp, textPtr, objv[4]))) {

		return TCL_ERROR;
	    }
	    newPriority = tagPtr2->priority;
	    if (tagPtr->priority > tagPtr2->priority) {

		newPriority += 1;
	    }
	} else {
	    newPriority = sharedTextPtr->numEnabledTags - 1;
	}
	if (ChangeTagPriority(sharedTextPtr, tagPtr, newPriority, 1) && tagPtr->rootPtr) {
	    if (tagPtr->undo) {
		TkTextUpdateAlteredFlag(sharedTextPtr);
	    }

	    /*
	     * If this is the 'sel' tag, then we don't actually need to call this for all peers.

	     *
	     * TODO: The current implementation is sloppy, we need only to refresh the ranges
	     * with actual changes, and not all the ranges of this tag.
	     */

	    TkTextRedrawTag(tagPtr->isSelTag ? NULL : sharedTextPtr,
		    textPtr, NULL, NULL, tagPtr, 0);
	}
	break;
    }
    case TAG_RANGES: {
	TkTextIndex first, last;
	TkTextSearch tSearch;
	Tcl_Obj *listObj = Tcl_NewObj();
	DEBUG(int found = 0);

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "tagName");
	    return TCL_ERROR;
	}
	if ((tagPtr = FindTag(NULL, textPtr, objv[3])) && tagPtr->rootPtr) {





	    TkTextIndexSetupToStartOfText(&first, textPtr, sharedTextPtr->tree);
	    TkTextIndexSetupToEndOfText(&last, textPtr, sharedTextPtr->tree);

	    TkBTreeStartSearch(&first, &last, tagPtr, &tSearch, SEARCH_NEXT_TAGON);





	    while (TkBTreeNextTag(&tSearch)) {
		Tcl_ListObjAppendElement(NULL, listObj, TkTextNewIndexObj(&tSearch.curIndex));

		DEBUG(found = 1);
	    }






	    assert(!found || !tSearch.tagon); /* search must find end of text */
	    Tcl_SetObjResult(interp, listObj);

	}

	break;
    }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTagFindStartOfRange --
 *
 *	Find the start of the range which is marked by given tag. This
 *	functions requires that the given start index for the search
 *	is marked by this tag.
 *
 * Results:
 *	Returns the end index in '*resultPtr'.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextTagFindStartOfRange(
    TkText *textPtr,			/* Info about overall widget. */
    const TkTextTag *tagPtr,		/* Search for this tag. */
    const TkTextIndex *currentPtr,	/* Start search after this position. */
    TkTextIndex *resultPtr)		/* Returns end of tagged range. */
{
    TkTextSearch tSearch;
    TkTextIndex stopIndex;

    assert(textPtr);
    assert(currentPtr);
    assert(resultPtr);

    TkTextIndexSetupToStartOfText(&stopIndex, textPtr, textPtr->sharedTextPtr->tree);
    TkBTreeStartSearchBack(currentPtr, &stopIndex, tagPtr, &tSearch, SEARCH_NEXT_TAGON);
    TkBTreePrevTag(&tSearch);
    assert(tSearch.segPtr); /* last search must not fail */
    *resultPtr = tSearch.curIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTagFindEndOfRange --
 *
 *	Find the end of the range which is marked by given tag. This
 *	functions requires that the given start index for the search
 *	is marked by this tag.
 *
 * Results:
 *	Returns the end index in '*resultPtr'.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextTagFindEndOfRange(
    TkText *textPtr,			/* Info about overall widget. */
    const TkTextTag *tagPtr,		/* Search for this tag. */
    const TkTextIndex *currentPtr,	/* Start search at this position. */
    TkTextIndex *resultPtr)		/* Returns end of tagged range. */
{
    TkTextSearch tSearch;
    TkTextIndex stopIndex;

    assert(textPtr);
    assert(currentPtr);
    assert(resultPtr);

    TkTextIndexSetupToEndOfText(&stopIndex, textPtr, textPtr->sharedTextPtr->tree);
    TkBTreeStartSearch(currentPtr, &stopIndex, tagPtr, &tSearch, SEARCH_EITHER_TAGON_TAGOFF);
    TkBTreeNextTag(&tSearch);
    assert(tSearch.segPtr); /* last search must not fail */
    assert(!tSearch.tagon); /* must be tagoff */
    *resultPtr = tSearch.curIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextClearSelection --
 *
 *	Clear the selection in specified range.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	See TkBTreeTag and TkTextSelectionEvent for side effects.
 *
 *----------------------------------------------------------------------
 */

void
TkTextClearSelection(
    TkSharedText *sharedTextPtr,
    const TkTextIndex *indexPtr1,
    const TkTextIndex *indexPtr2)
{
    TkText *textPtr;

    for (textPtr = sharedTextPtr->peers; textPtr; textPtr = textPtr->next) {
	if (TkBTreeTag(sharedTextPtr, textPtr, indexPtr1, indexPtr2, textPtr->selTagPtr,
		0, NULL, TkTextRedrawTag)) {
	    /*
	     * Send an event that the selection changed. This is equivalent to:
	     *	 event generate $textWidget <<Selection>>
	     */

	    TkTextSelectionEvent(textPtr); /* <<Selection>> will be received after deletion */
	    textPtr->abortSelections = 1;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextClearTags --
 *
 *	Turn all tags off inside a given range.
 *
 * Results:
 *	Whether any tag has been removed.
 *
 * Side effects:
 *	See TkBTreeClearTags and TkTextPushUndoToken for side effects.
 *
 *----------------------------------------------------------------------
 */

TkTextTag *
TkTextClearTags(
    TkSharedText *sharedTextPtr,
    TkText *textPtr,			/* can be NULL */
    const TkTextIndex *indexPtr1,
    const TkTextIndex *indexPtr2,
    int discardSelection)
{
    TkTextTag *tagPtr;
    TkTextUndoInfo undoInfo;
    TkTextUndoInfo *undoInfoPtr;

    undoInfoPtr = TkTextUndoStackIsFull(sharedTextPtr->undoStack) ? NULL : &undoInfo;
    tagPtr = TkBTreeClearTags(sharedTextPtr, textPtr, indexPtr1, indexPtr2, undoInfoPtr,
	    discardSelection, TkTextRedrawTag);
    if (tagPtr && undoInfoPtr && undoInfo.token) {
	TkTextPushUndoToken(sharedTextPtr, undoInfo.token, undoInfo.byteSize);
    }
    return tagPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateTagDisplayFlags --
 *
 *	Update the display flags 'affectsDisplay' and 'affectsDisplayGeometry',
 *	according to the current attributes of the given tag.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The flags 'affectsDisplay' and 'affectsDisplayGeometry' may change.
 *
 *----------------------------------------------------------------------
 */

void
TkTextUpdateTagDisplayFlags(
    TkTextTag *tagPtr)
{
    tagPtr->affectsDisplay = 0;
    tagPtr->affectsDisplayGeometry = 0;

    if ((tagPtr->elide >= 0)
	    || tagPtr->tkfont
	    || tagPtr->justify != TK_JUSTIFY_NULL
	    || tagPtr->lMargin1Obj
	    || tagPtr->lMargin2Obj
	    || tagPtr->offsetObj
	    || tagPtr->rMarginObj
	    || tagPtr->spacing1Obj
	    || tagPtr->spacing2Obj
	    || tagPtr->spacing3Obj
	    || tagPtr->tabStringPtr
	    || tagPtr->tabStyle == TK_TEXT_TABSTYLE_TABULAR
	    || tagPtr->tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR
		|| tagPtr->wrapMode == TEXT_WRAPMODE_CHAR
		|| tagPtr->wrapMode == TEXT_WRAPMODE_NONE
		|| tagPtr->wrapMode == TEXT_WRAPMODE_WORD
		|| tagPtr->wrapMode == TEXT_WRAPMODE_CODEPOINT) {
	tagPtr->affectsDisplay = 1;
	tagPtr->affectsDisplayGeometry = 1;
    } else if (tagPtr->attrs.border
	    || tagPtr->attrs.inactiveBorder
	    || tagPtr->selBorder
	    || tagPtr->inactiveSelBorder
	    || tagPtr->relief != TK_RELIEF_NULL
	    || tagPtr->bgStipple != None
	    || tagPtr->indentBg >= 0
	    || tagPtr->attrs.fgColor
	    || tagPtr->attrs.inactiveFgColor
	    || tagPtr->selFgColor
	    || tagPtr->inactiveSelFgColor
	    || tagPtr->fgStipple != None
	    || tagPtr->eolColor
	    || tagPtr->hyphenColor
	    || tagPtr->overstrike >= 0
	    || tagPtr->overstrikeColor
	    || tagPtr->underline >= 0
	    || tagPtr->underlineColor
	    || tagPtr->lMarginColor
	    || tagPtr->rMarginColor) {
	tagPtr->affectsDisplay = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkConfigureTag --
 *
 *	This function is called to process an objv/objc list, plus the Tk
 *	option database, in order to configure (or reconfigure) a text tag.
 *
 * Results:
 *	Any of the standard Tcl return values.
 *
 * Side effects:
 *	A new tag will be created if required, otherwise an existing tag
 *	will be modified.
 *
 *----------------------------------------------------------------------
 */

static void
SetupDefaultRelief(
    TkText *textPtr,
    TkTextTag *tagPtr)
{
    if (tagPtr->isSelTag) {
	Tk_GetRelief(textPtr->interp, DEF_TEXT_SELECT_RELIEF, &tagPtr->relief);
    } else {
	tagPtr->relief = TK_RELIEF_FLAT;
    }
}

int
TkConfigureTag(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkText *textPtr,		/* Info about overall widget. */
    char const *tagName,	/* Name of affected tag. */
    int redraw,		/* Redraw the affected text if required? */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Remaining argument objects. */
{
    int newTag;
    int mask = 0;
    TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    TkTextTag *tagPtr = TkTextCreateTag(textPtr, tagName, &newTag);
    int relief = tagPtr->relief;
    int elide = tagPtr->elide;
    int undo = tagPtr->undo;
    int affectsDisplay = tagPtr->affectsDisplay;
    int affectsLineHeight = 0;
    int rc = TCL_OK;

    if (objc <= 1) {
	Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr, tagPtr->optionTable,
		objc == 1 ? objv[0] : NULL, textPtr->tkwin);

	if (!objPtr) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }

    if (tagPtr->isSelTag) {
	tagPtr->attrs = textPtr->selTagConfigAttrs;
    }
    if (Tk_SetOptions(interp, (char *) tagPtr, tagPtr->optionTable,
	    objc, objv, textPtr->tkwin, NULL, &mask) != TCL_OK) {
	if (tagPtr->isSelTag) {
	    tagPtr->attrs = textPtr->selAttrs;
	}
	return TCL_ERROR;
    }

#if SUPPORT_DEPRECATED_TAG_OPTIONS

    if (mask & (TK_TEXT_DEPRECATED_OVERSTRIKE_FG|TK_TEXT_DEPRECATED_UNDERLINE_FG)) {
	static int warnAboutOverstrikeFg = 1;
	static int warnAboutUnderlineFg = 1;

	if (mask & TK_TEXT_DEPRECATED_OVERSTRIKE_FG) {
	    if (warnAboutOverstrikeFg) {
		fprintf(stderr, "tk::text: Tag option \"-overstrikefg\" is deprecated, "
			"please use option \"-overstrikecolor\".\n");
		warnAboutOverstrikeFg = 0;
	    }
	}
	if (mask & TK_TEXT_DEPRECATED_UNDERLINE_FG) {
	    if (warnAboutUnderlineFg) {
		fprintf(stderr, "tk::text: Tag option \"-underlinefg\" is deprecated, "
			"please use option \"-underlinecolor\".\n");
		warnAboutUnderlineFg = 0;
	    }
	}
    }

#endif /* SUPPORT_DEPRECATED_TAG_OPTIONS */

    /*
      Some of the configuration options, like -underline and -justify, require
     * additional translation (this is needed because we need to distinguish a
     * particular value of an option from "unspecified").
     */

    tagPtr->attrs.borderWidth = MAX(0, tagPtr->attrs.borderWidth);

    if (tagPtr->langPtr) {
	if (!TkTextTestLangCode(interp, tagPtr->langPtr)) {
	    rc = TCL_ERROR;
	} else {
	    memcpy(tagPtr->lang, Tcl_GetString(tagPtr->langPtr), 3);
	}
    } else {
	memset(tagPtr->lang, 0, 3);
    }
    if (tagPtr->relief != TK_RELIEF_NULL) {
    } else if (relief != TK_RELIEF_NULL) {
	SetupDefaultRelief(textPtr, tagPtr);
    }
    if (tagPtr->spacing1Obj) {
	tagPtr->spacing1 = MAX(0, tagPtr->spacing1);
    }
    if (tagPtr->spacing2Obj) {
	tagPtr->spacing2 = MAX(0, tagPtr->spacing2);
    }
    if (tagPtr->spacing3Obj) {
	tagPtr->spacing3 = MAX(0, tagPtr->spacing3);
    }
    if (tagPtr->tabArrayPtr) {
	ckfree(tagPtr->tabArrayPtr);
	tagPtr->tabArrayPtr = NULL;
    }
    if (tagPtr->tabStringPtr) {
	if (!(tagPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr->tkwin, tagPtr->tabStringPtr))) {
	    rc = TCL_ERROR;
	}
    }
    if (tagPtr->hyphenRulesPtr) {
	int oldHyphenRules = tagPtr->hyphenRules;

	if (TkTextParseHyphenRules(textPtr, tagPtr->hyphenRulesPtr, &tagPtr->hyphenRules) != TCL_OK) {
	    rc = TCL_ERROR;
	}
	if (oldHyphenRules != tagPtr->hyphenRules && textPtr->hyphenate) {
	    affectsDisplay = 1;
	}
    }
    if (tagPtr->elide >= 0) {
	if (elide < 0) {
	    sharedTextPtr->numElisionTags += 1;
	}

	if (TkBitTest(sharedTextPtr->selectionTags, tagPtr->index)) {
	    /*
	     * It's not allowed to set the elide attribute of the special selection tag
	     * to 'true' (this would cause errors, because this case is not implemented).
	     */

	    tagPtr->elide = -1;
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "not allowed to set elide option of selection tag \"%s\"", tagPtr->name));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ELIDE", (char *)NULL);
	    rc = TCL_ERROR;
	}

	/*
	 * Indices are potentially obsolete after changing -elide,
	 * especially those computed with "display" or "any"
	 * submodifier, therefore increase the epoch.
	 */

	TkBTreeIncrEpoch(sharedTextPtr->tree);
    } else {
	if (elide >= 0) {
	    sharedTextPtr->numElisionTags -= 1;
	}
	tagPtr->elide = -1;
    }
    if (tagPtr->undo != undo) {
	TkBitPut(sharedTextPtr->dontUndoTags, tagPtr->index, !tagPtr->undo);
    }

    /*
     * If the "sel" tag was changed, be sure to mirror information
     * from the tag back into the text widget record.
     */

    if (tagPtr->isSelTag) {
	if (tagPtr->attrs.border != textPtr->selTagConfigAttrs.border) {
	    textPtr->selAttrs.border = tagPtr->attrs.border;
	}
	if (tagPtr->attrs.inactiveBorder != textPtr->selTagConfigAttrs.inactiveBorder) {
	    textPtr->selAttrs.inactiveBorder = tagPtr->attrs.inactiveBorder;
	}
	if (tagPtr->attrs.fgColor != textPtr->selTagConfigAttrs.fgColor) {
	    textPtr->selAttrs.fgColor = tagPtr->attrs.fgColor;
	}
	if (tagPtr->attrs.inactiveFgColor != textPtr->selTagConfigAttrs.inactiveFgColor) {
	    textPtr->selAttrs.inactiveFgColor = tagPtr->attrs.inactiveFgColor;
	}
	if (tagPtr->attrs.borderWidthObj != textPtr->selTagConfigAttrs.borderWidthObj) {
	    textPtr->selAttrs.borderWidthObj = tagPtr->attrs.borderWidthObj;
	    textPtr->selAttrs.borderWidth = tagPtr->attrs.borderWidth;
	}
	textPtr->selTagConfigAttrs = tagPtr->attrs;
	tagPtr->attrs = textPtr->selAttrs;
    }

    TkTextUpdateTagDisplayFlags(tagPtr);
    if (tagPtr->affectsDisplay) {
	affectsDisplay = 1;
    }
    if (tagPtr->tkfont != NULL && tagPtr->tkfont != textPtr->tkfont) {
	Tk_FontMetrics fm;

	Tk_GetFontMetrics(tagPtr->tkfont, &fm);
	if (MAX(1, fm.linespace) != textPtr->lineHeight) {
	    affectsLineHeight = 1;
	}
    }

    TkBitPut(sharedTextPtr->elisionTags, tagPtr->index, tagPtr->elide >= 0);
    TkBitPut(sharedTextPtr->affectDisplayTags, tagPtr->index, tagPtr->affectsDisplay);
    TkBitPut(sharedTextPtr->notAffectDisplayTags, tagPtr->index, !tagPtr->affectsDisplay);
    TkBitPut(sharedTextPtr->affectGeometryTags, tagPtr->index, tagPtr->affectsDisplayGeometry);
    TkBitPut(sharedTextPtr->affectLineHeightTags, tagPtr->index, affectsLineHeight);

    if (!TkBitTest(sharedTextPtr->selectionTags, tagPtr->index)) {
	TkBitPut(sharedTextPtr->affectDisplayNonSelTags, tagPtr->index, tagPtr->affectsDisplay);
	TkBitPut(sharedTextPtr->affectGeometryNonSelTags, tagPtr->index,
		tagPtr->affectsDisplayGeometry);
    }

    if ((tagPtr->elide >= 0)!= (elide >= 0) || ((tagPtr->elide >= 0) && elide != tagPtr->elide)) {
	/*
	 * Eventually we have to insert/remove branches and links according to
	 * the elide information of this tag.
	 */

	TkBTreeUpdateElideInfo(textPtr, tagPtr);
    }

    if (redraw && !newTag && affectsDisplay) {
	/*
	 * This action is not necessary if this is a new tag, since it can't have been
	 * applied to anything yet.
	 *
	 * If this is the 'sel' tag, then we don't need to call this for all peers, unless
	 * we actually want to synchronize sel-style changes across the peers.
	 */

	TkTextRedrawTag(sharedTextPtr, NULL, NULL, NULL, tagPtr, 0);
    }

    return rc;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFontHeightChanged --
 *
 *	The font height of the text widget has changed, so we have to update
 *	textPtr->affectLineHeightTags accordingly.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	textPtr->affectLineHeightTags will be updated.
 *
 *----------------------------------------------------------------------
 */

void
TkTextFontHeightChanged(
    TkText *textPtr)		/* Info about overall widget. */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr = NULL;
    TkBitField *affectLineHeightTags = textPtr->sharedTextPtr->affectLineHeightTags;

    TkBitClear(affectLineHeightTags);

    for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->tagTable, &search);
	    hPtr;
	    hPtr = Tcl_NextHashEntry(&search)) {
	const TkTextTag *tagPtr = (const TkTextTag *)Tcl_GetHashValue(hPtr);

	if (tagPtr->tkfont != NULL && tagPtr->tkfont != textPtr->tkfont) {
	    Tk_FontMetrics fm;

	    Tk_GetFontMetrics(tagPtr->tkfont, &fm);
	    if (MAX(1, fm.linespace) != textPtr->lineHeight) {
		TkBitSet(affectLineHeightTags, tagPtr->index);
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * AppendTags --
 *
 *	This function is appending the given array of tags to the interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Results will be appended to the interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
AppendTags(
    Tcl_Interp *interp,		/* Current interpreter. */
    unsigned numTags,		/* Size of array. */
    TkTextTag **tagArray)	/* Array of tag pointer, some pointer may be NULL. */
{
    unsigned i;
    Tcl_Obj *listObj;

    if (numTags == 0) {
	return;
    }

    TkTextSortTags(numTags, tagArray);
    listObj = Tcl_NewObj();

    for (i = 0; i < numTags; ++i) {
	if (tagArray[i]) {
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(tagArray[i]->name, TCL_INDEX_NONE));
	}
    }
    Tcl_SetObjResult(interp, listObj);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextReplaceTags --
 *
 *	This function is replacing the tag information of given segment
 *	with provided list of tags.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

# define TK_TEXT_SET_MAX_BIT_SIZE (((512 + TK_BIT_NBITS - 1)/TK_BIT_NBITS)*TK_BIT_NBITS)

void
TkTextReplaceTags(
    TkText *textPtr,		/* Info about overall window. */
    TkTextSegment *segPtr,	/* Setup tag info of this segment. */
    int undoable,		/* Replacement of tags is undoable? */
    Tcl_Obj *tagListPtr)	/* List of tags. */
{
    TkTextTagSet *newTagInfoPtr;
    TkTextTagSet *oldTagInfoPtr;
    TkSharedText *sharedTextPtr;
    TkTextTag *tagArrBuf[TK_TEXT_SET_MAX_BIT_SIZE];
    TkTextTag **tagArrPtr = tagArrBuf;
    TkTextTag *tagPtr;
    TkTextUndoStack undoStack;
    TkTextIndex index[2];
    int altered = 0;
    int anyChanges = 0;
    Tcl_Obj **objs;
    Tcl_Size objn = 0, k;
    unsigned j;

    assert(textPtr);
    assert(segPtr);
    assert(segPtr->tagInfoPtr);
    assert(tagListPtr);

    Tcl_ListObjGetElements(NULL, tagListPtr, &objn, &objs);
    TkTextIndexClear(&index[0], textPtr);
    TkTextIndexSetSegment(&index[0], segPtr);
    TkrTextIndexForwBytes(textPtr, &index[0], 1, &index[1]);
    TkTextTagSetIncrRefCount(oldTagInfoPtr = segPtr->tagInfoPtr);

    if ((size_t)objn > sizeof(tagArrBuf)/sizeof(tagArrBuf[0])) {
	tagArrPtr = (TkTextTag**)ckalloc(objn*sizeof(tagArrPtr[0]));
    }

    for (k = 0; k < objn; ++k) {
	tagArrPtr[k] = TkTextCreateTag(textPtr, Tcl_GetString(objs[k]), NULL);
    }

    sharedTextPtr = textPtr->sharedTextPtr;
    newTagInfoPtr = TkTextTagSetResize(NULL, sharedTextPtr->tagInfoSize);

    for (k = 0; k < objn; ++k) {
	newTagInfoPtr = TkTextTagSetAddToThis(newTagInfoPtr, tagArrPtr[k]->index);
    }

    undoStack = sharedTextPtr->undoStack;
    if (!undoable) {
	sharedTextPtr->undoStack = NULL; /* disable undo temporarily */
    }

    /*
     * Remove the deleted tags, but ignore the "sel" tag.
     */

    for (j = TkTextTagSetFindFirst(oldTagInfoPtr);
	    j != TK_TEXT_TAG_SET_NPOS;
	    j = TkTextTagSetFindNext(oldTagInfoPtr, j)) {
	if (!TkTextTagSetTest(newTagInfoPtr, j)) {
	    tagPtr = sharedTextPtr->tagLookup[j];
	    if (!tagPtr->isSelTag && TagAddRemove(textPtr, &index[0], &index[1], tagPtr, 0)) {
		anyChanges = 1;
		if (tagPtr->undo) {
		    altered = 1;
		}
	    }
	}
    }

    /*
     * Add new tags, but ignore the "sel" tag.
     */

    for (j = TkTextTagSetFindFirst(newTagInfoPtr);
	    j != TK_TEXT_TAG_SET_NPOS;
	    j = TkTextTagSetFindNext(newTagInfoPtr, j)) {
	if (!TkTextTagSetTest(segPtr->tagInfoPtr, j)) {
	    tagPtr = sharedTextPtr->tagLookup[j];
	    if (!tagPtr->isSelTag && TagAddRemove(textPtr, &index[0], &index[1], tagPtr, 1)) {
		anyChanges = 1;
		if (tagPtr->undo) {
		    altered = 1;
		}
	    }
	}
    }

    TkTextTagSetDecrRefCount(oldTagInfoPtr);
    TkTextTagSetDecrRefCount(newTagInfoPtr);
    sharedTextPtr->undoStack = undoStack;

    if (anyChanges) {
	/* still need to trigger enter/leave events on tags that have changed */
	TkTextEventuallyRepick(textPtr);
    }
    if (altered) {
	TkTextUpdateAlteredFlag(sharedTextPtr);
    }
    if (tagArrPtr != tagArrBuf) {
	ckfree(tagArrPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFindTags --
 *
 *	This function is appending the tags from given char segment to the
 *	interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Results will be appended to the interpreter.
 *
 *----------------------------------------------------------------------
 */

void
TkTextFindTags(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkText *textPtr,		/* Info about overall widget. */
    const TkTextSegment *segPtr,/* Tags from this segment. */
    int discardSelection)	/* "sel" tag will be discarded? */
{
    TkTextTag *tagPtr;
    Tcl_Obj *listObj;

    assert(segPtr);

    tagPtr = TkBTreeGetSegmentTags(textPtr->sharedTextPtr, segPtr, textPtr,
	    TK_TEXT_SORT_ASCENDING, NULL);
    listObj = Tcl_NewObj();

    for ( ; tagPtr; tagPtr = tagPtr->nextPtr) {
	if (!discardSelection || tagPtr != textPtr->selTagPtr) {
	    Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(tagPtr->name, TCL_INDEX_NONE));
	}
    }

    Tcl_SetObjResult(interp, listObj);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTagChangedUndoRedo --
 *
 *	This function is called when any tag range has been changed during
 *	an undo/redo operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	See TkTextRedrawTag, and GrabSelection.
 *
 *----------------------------------------------------------------------
 */

int
TkTextTagChangedUndoRedo(
    const TkSharedText *sharedTextPtr,
    TkText *textPtr,
    const TkTextIndex *indexPtr1,
    const TkTextIndex *indexPtr2,
    const TkTextTag *tagPtr,
    int affectsDisplayGeometry)
{
    if (!TkTextRedrawTag(sharedTextPtr, textPtr, indexPtr1, indexPtr2, tagPtr, affectsDisplayGeometry)) {
	return 0;
    }
    if (textPtr && tagPtr == textPtr->selTagPtr) {
	GrabSelection(tagPtr->textPtr, tagPtr, TkTextTestTag(indexPtr1, tagPtr), 1);
    }
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GrabSelection --
 * 	Grab the selection if we're supposed to export it and don't already
 * 	have it.
 *
 * 	Also, invalidate partially-completed selection retrievals. We only
 *	need to check whether the tag is "sel" for this textPtr (not for
 *	other peer widget's "sel" tags) because we cannot reach this code
 *	path with a different widget's "sel" tag.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Some text segments may be modified.
 *
 *----------------------------------------------------------------------
 */

static void
GrabSelection(
    TkText *textPtr,		/* Info about overall widget. */
    TCL_UNUSED(const TkTextTag *),	/* Tag which has been modified. */
    int add,			/* 'true' means that we have added the "sel" tag;
				 * 'false' means we have removed the "sel" tag. */
    int changed)		/* 'false' means that the selection has not changed, nevertheless
    				 * the text widget should become the owner again. */
{
    int ownSelection = add && textPtr->exportSelection && !(textPtr->flags & GOT_SELECTION);

    assert(textPtr);

    if (changed || ownSelection) {
	/*
	 * Send an event that the selection changed. This is
	 * equivalent to:
	 *	   event generate $textWidget <<Selection>>
	 */

	TkTextSelectionEvent(textPtr);
    }
    if (ownSelection && (!Tcl_IsSafe(textPtr->interp))) {
	Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, TkTextLostSelection, textPtr);
	textPtr->flags |= GOT_SELECTION;
    }
    if (changed) {
	textPtr->abortSelections = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TagAddRemove --
 *	This functions adds or removes a tag (or all tags) from the characters
 *	between given index range.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Some text segments may be modified.
 *
 *----------------------------------------------------------------------
 */

static int
UndoTagOperation(
    const TkSharedText *sharedTextPtr,
    const TkTextTag *tagPtr)
{
    return sharedTextPtr->undoStack && (!tagPtr || tagPtr->undo);
}

static int
TagAddRemove(
    TkText *textPtr,		/* Info about overall widget. */
    const TkTextIndex *index1Ptr,
				/* Indicates first character in range. */
    const TkTextIndex *index2Ptr,
				/* Indicates character just after the last one in range. */
    TkTextTag *tagPtr,		/* Tag to add or remove. */
    int add)			/* 'true' means add tag to the given range of characters;
				 * 'false' means remove the tag from the range. */
{
    TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    TkTextUndoInfo *undoInfoPtr;
    TkTextUndoInfo undoInfo;

    assert(!sharedTextPtr->undoStack || !TkTextUndoIsPerformingUndo(sharedTextPtr->undoStack));
    assert(!sharedTextPtr->undoStack || !TkTextUndoIsPerformingRedo(sharedTextPtr->undoStack));

    if (!add && !tagPtr->rootPtr) {
	return 0; /* no change possible */
    }

    undoInfoPtr = UndoTagOperation(sharedTextPtr, tagPtr) ? &undoInfo : NULL;

    if (!TkBTreeTag(sharedTextPtr, textPtr, index1Ptr, index2Ptr, tagPtr, add,
	    undoInfoPtr, TkTextRedrawTag)) {
	return 0;
    }

    if (undoInfoPtr) {
	if (undoInfo.token) {
	    tagPtr->refCount += 1;
	    TkTextUndoPushItem(sharedTextPtr->undoStack, undoInfo.token, undoInfo.byteSize);
	}
	sharedTextPtr->undoStackEvent = 1;
    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextBindEvent --
 *
 *	Bind events to the specified resource name.
 *
 * Results:
 *	Any of the standard Tcl return values.
 *
 * Side effects:
 *	A new entry in the binding table will be inserted, or an exisiting
 *	entry will be deleted.
 *
 *----------------------------------------------------------------------
 */

int
TkTextBindEvent(
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Remaining argument objects. */
    TkSharedText *sharedTextPtr,/* Shared text resource. */
    Tk_BindingTable *bindingTablePtr,
    				/* Pointer to binding table. */
    const char *name)		/* Bind event to this resource (tag or image). */
{
    static const unsigned motionMask = ButtonMotionMask|Button1MotionMask
		|Button2MotionMask|Button3MotionMask|Button4MotionMask
		|Button5MotionMask|PointerMotionMask;

    /*
     * Make a binding table if the widget doesn't already have one.
     */

    if (!*bindingTablePtr) {
	*bindingTablePtr = Tk_CreateBindingTable(interp);
    }

    if (objc == 2) {
	int append = 0;
	unsigned long mask;
	const char *eventString = Tcl_GetString(objv[0]);
	const char *fifth = Tcl_GetString(objv[1]);

	if (fifth[0] == '\0') {
	    return Tk_DeleteBinding(interp, *bindingTablePtr, (void *)name, eventString);
	}
	if (fifth[0] == '+') {
	    fifth += 1;
	    append = 1;
	}
	mask = Tk_CreateBinding(interp, *bindingTablePtr, (void *)name, eventString, fifth, append);
	if (mask == 0) {
	    return TCL_ERROR;
	}
	if (mask & (unsigned) ~(motionMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask
		|LeaveWindowMask|KeyPressMask|KeyReleaseMask|VirtualEventMask)) {
	    Tk_DeleteBinding(interp, *bindingTablePtr, (void *)name, eventString);
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "requested illegal events; only key, button, motion,"
		    " enter, leave, and virtual events may be used", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "TAG_BIND_EVENT", (char *)NULL);
	    return TCL_ERROR;
	}
	if (mask & motionMask) {
	    /*
	     * TODO: It would be better to count tags with motion mask, but this silly
	     * binding protocol does not provide any function which helps to detect when
	     * bindings with motion masks will be deleted. So we cannot do more than
	     * to detect whether any motion mask has ever been set. This has an effect
	     * on TkTextPickCurrent, this function will be considerably faster if
	     * 'numMotionEventBindings' is zero, because in latter case only traversals
	     * between display chunks will be considered. We assume that the use of a
	     * motion mask is rather seldom, normally only the Enter/Leave events are
	     * of interest.
	     */
	    sharedTextPtr->numMotionEventBindings = 1;
	}
    } else if (objc == 1) {
	const char *command;

	command = Tk_GetBinding(interp, *bindingTablePtr, (void *)name, Tcl_GetString(objv[0]));
	if (!command) {
	    const char *string = Tcl_GetString(Tcl_GetObjResult(interp));

	    /*
	     * Ignore missing binding errors. This is a special hack that relies on the
	     * error message returned by FindSequence in tkBind.c.
	     */

	    if (string[0] != '\0') {
		return TCL_ERROR;
	    }
	    Tcl_ResetResult(interp);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(command, TCL_INDEX_NONE));
	}
    } else {
	Tk_GetAllBindings(interp, *bindingTablePtr, (void *)name);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextCreateTag --
 *
 *	Find the record describing a tag within a given text widget, creating
 *	a new record if one doesn't already exist.
 *
 * Results:
 *	The return value is a pointer to the TkTextTag record for tagName.
 *
 * Side effects:
 *	A new tag record is created if there isn't one already defined for
 *	tagName.
 *
 *----------------------------------------------------------------------
 */

static void
MarkIndex(
    TkSharedText *sharedTextPtr,
    TkTextTag *tagPtr,
    int set)
{
    if (set && tagPtr->index >= TkBitSize(sharedTextPtr->usedTags)) {
	sharedTextPtr->tagInfoSize = TkBitAdjustSize(tagPtr->index + 1);
    }

    TkBitPut(sharedTextPtr->usedTags, tagPtr->index, set);
    assert((!sharedTextPtr->tagLookup[tagPtr->index]) == set);
    sharedTextPtr->tagLookup[tagPtr->index] = set ? tagPtr : NULL;
}

TkTextTag *
TkTextCreateTag(
    TkText *textPtr,		/* Widget in which tag is being used. */
    const char *tagName,	/* Name of desired tag. */
    int *newTag)		/* If non-NULL, then return true if new, or false if already exists. */

{
    TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    TkTextTag *tagPtr;
    Tcl_HashEntry *hPtr = NULL;
    int isNew;
    int isSelTag;
    const char *name;
    unsigned index;

    isSelTag = (strcmp(tagName, "sel") == 0);

    if (isSelTag) {
	if (textPtr->selTagPtr) {
	    if (newTag) {
		*newTag = 0;
	    }
	    return textPtr->selTagPtr;
	}
	if (newTag) {
	    *newTag = 1;
	}
	name = "sel";
    } else {
	hPtr = Tcl_CreateHashEntry(&sharedTextPtr->tagTable, tagName, &isNew);

	if (newTag) {
	    *newTag = isNew;
	}
	if (!isNew) {
	    return (TkTextTag*)Tcl_GetHashValue(hPtr);
	}
	name = (const char *)Tcl_GetHashKey(&sharedTextPtr->tagTable, hPtr);
    }

    if ((index = TkBitFindFirstNot(sharedTextPtr->usedTags)) == TK_BIT_NPOS) {
	unsigned oldSize = TkBitSize(sharedTextPtr->usedTags);
	unsigned newSize = TkBitAdjustSize((index = oldSize) + 1);

	sharedTextPtr->usedTags = TkBitResize(sharedTextPtr->usedTags, newSize);
	sharedTextPtr->elisionTags = TkBitResize(sharedTextPtr->elisionTags, newSize);
	sharedTextPtr->selectionTags = TkBitResize(sharedTextPtr->selectionTags, newSize);
	sharedTextPtr->dontUndoTags = TkBitResize(sharedTextPtr->dontUndoTags, newSize);
	sharedTextPtr->affectDisplayTags = TkBitResize(sharedTextPtr->affectDisplayTags, newSize);
	sharedTextPtr->notAffectDisplayTags = TkBitResize(sharedTextPtr->notAffectDisplayTags, newSize);
	sharedTextPtr->affectDisplayNonSelTags = TkBitResize(
		sharedTextPtr->affectDisplayNonSelTags, newSize);
	sharedTextPtr->affectGeometryTags = TkBitResize( sharedTextPtr->affectGeometryTags, newSize);
	sharedTextPtr->affectGeometryNonSelTags = TkBitResize(
		sharedTextPtr->affectGeometryNonSelTags, newSize);
	sharedTextPtr->affectLineHeightTags = TkBitResize(sharedTextPtr->affectLineHeightTags, newSize);
	sharedTextPtr->tagLookup = (TkTextTag **)ckrealloc(sharedTextPtr->tagLookup, newSize * sizeof(TkTextTag *));
	DEBUG(memset(sharedTextPtr->tagLookup + oldSize, 0, (newSize - oldSize) * sizeof(TkTextTag *)));
    }

    if (sharedTextPtr->tagInfoSize <= index) {
	sharedTextPtr->tagInfoSize = TkBitAdjustSize(index + 1);
    }

    /*
     * No existing entry. Create a new one, initialize it, and add a pointer
     * to it to the hash table entry.
     */

    tagPtr = (TkTextTag *)ckalloc(sizeof(TkTextTag));
    memset(tagPtr, 0, sizeof(TkTextTag));
    tagPtr->name = name;
    tagPtr->index = index;


    tagPtr->priority = sharedTextPtr->numEnabledTags;
    tagPtr->isSelTag = isSelTag;




    tagPtr->bgStipple = None;


    tagPtr->fgStipple = None;
    tagPtr->elide = -1;
    tagPtr->justify = TK_JUSTIFY_NULL;











    tagPtr->relief = TK_RELIEF_NULL;











    tagPtr->tabStyle = TK_TEXT_TABSTYLE_NULL;





    tagPtr->wrapMode = TEXT_WRAPMODE_NULL;
    tagPtr->undo = sharedTextPtr->undoTagging && !isSelTag;
    tagPtr->sharedTextPtr = sharedTextPtr;
    tagPtr->undoTagListIndex = -1;
    tagPtr->refCount = 1;
    tagPtr->tagEpoch = ++sharedTextPtr->tagEpoch;
    DEBUG_ALLOC(tkTextCountNewTag++);

    tagPtr->optionTable = Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs);

    sharedTextPtr->numTags += 1;
    sharedTextPtr->numEnabledTags += 1;

    if (isSelTag) {
	tagPtr->textPtr = textPtr;
	textPtr->refCount += 1;
	TkBitSet(sharedTextPtr->selectionTags, index);
	TkBitSet(sharedTextPtr->dontUndoTags, index);
    } else {
	assert(hPtr);
	Tcl_SetHashValue(hPtr, tagPtr);
    }

    SetupDefaultRelief(textPtr, tagPtr);
    MarkIndex(sharedTextPtr, tagPtr, 1);
    return tagPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFindTag --
 *
 *	See if tag is defined for a given widget.
 *
 * Results:
 *	If tagName is defined in textPtr, a pointer to its TkTextTag structure
 *	is returned. Otherwise NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkTextTag *
TkTextFindTag(
    const TkText *textPtr,	/* Widget in which tag is being used. */
    const char *tagName)	/* Name of desired tag. */
{
    Tcl_HashEntry *hPtr;

    assert(textPtr);
    assert(tagName);

    if (strcmp(tagName, "sel") == 0) {
	return textPtr->selTagPtr;
    }
    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, tagName);
    if (hPtr) {
	return (TkTextTag *)Tcl_GetHashValue(hPtr);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * FindTag --
 *
 *	See if tag is defined for a given widget.
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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkTextTag *
FindTag(
    Tcl_Interp *interp,		/* Interpreter to use for error message; if
				 * NULL, then don't record an error
				 * message. */
    TkText *textPtr,		/* Widget in which tag is being used. */
    Tcl_Obj *tagName)		/* Name of desired tag. */
{
    Tcl_HashEntry *hPtr;
    TkSizeT len;
    const char *str;

    str = TkGetStringFromObj(tagName, &len);
    if (len == 3 && !strcmp(str, "sel")) {
	return textPtr->selTagPtr;
    }
    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable,
	    Tcl_GetString(tagName));
    if (hPtr != NULL) {
	return (TkTextTag *)Tcl_GetHashValue(hPtr);
    }
    if (interp != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"tag \"%s\" isn't defined in text widget",
		Tcl_GetString(tagName)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_TAG",
		Tcl_GetString(tagName), NULL);
    }

    return NULL;





























}

/*
 *----------------------------------------------------------------------
 *





















































































 * TkTextDeleteTag --
 *
 *	This function is called to carry out most actions associated with the
 *	'tag delete' sub-command. It will remove all evidence of the tag from
 *	the B-tree, and then call TkTextFreeTag to clean up the tag structure
 *	itself.
 *
 *	The only actions this doesn't carry out it to check if the deletion of
 *	the tag requires something to be re-displayed, and to remove the tag
 *	from the tagTable (hash table) if that is necessary (i.e. if it's not
 *	the 'sel' tag). It is expected that the caller carry out both of these
 *	actions.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and other resources are freed, the B-tree is manipulated.
 *
 *----------------------------------------------------------------------
 */

void
TkTextDeleteTag(
    TkText *textPtr,		/* Info about overall widget. */
    TkTextTag *tagPtr)	/* Tag being deleted. */

{













    TkTextIndex first, last;




    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, &first);


    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,




	    TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &last),




    TkBTreeTag(&first, &last, tagPtr, 0);








    if (tagPtr == textPtr->selTagPtr) {



	/*
	 * Send an event that the selection changed. This is equivalent to:
	 *	event generate $textWidget <<Selection>>
	 */

	TkTextSelectionEvent(textPtr);
    } else {
	/*
	 * Since all peer widgets have an independent "sel" tag, we
	 * don't want removal of one sel tag to remove bindings which
	 * are still valid in other peer widgets.
	 */

	if (textPtr->sharedTextPtr->bindingTable != NULL) {
	    Tk_DeleteAllBindings(textPtr->sharedTextPtr->bindingTable,
		    (ClientData) tagPtr->name);
	}
    }

    /*
     * Update the tag priorities to reflect the deletion of this tag.
     */



    ChangeTagPriority(textPtr, tagPtr, textPtr->sharedTextPtr->numTags-1);














    textPtr->sharedTextPtr->numTags -= 1;





    TkTextFreeTag(textPtr, tagPtr);



}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFreeTag --
 *
 *	This function is called when a tag is deleted to free up the memory
 *	and other resources associated with the tag.




 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and other resources are freed.
 *
 *----------------------------------------------------------------------
 */

void
TkTextFreeTag(
    TkText *textPtr,		/* Info about overall widget. */




    TkTextTag *tagPtr)	/* Tag being deleted. */

{




    int i;


    /*
     * Let Tk do most of the hard work for us.
     */

    Tk_FreeConfigOptions((char *) tagPtr, tagPtr->optionTable,



	    textPtr->tkwin);

    /*
     * This associated information is managed by us.
     */

    if (tagPtr->tabArrayPtr != NULL) {
	ckfree(tagPtr->tabArrayPtr);
    }

    /*
     * Make sure this tag isn't referenced from the 'current' tag array.
     */

    for (i = 0; i < textPtr->numCurTags; i++) {
	if (textPtr->curTagArrayPtr[i] == tagPtr) {
	    for (; i < textPtr->numCurTags-1; i++) {
		textPtr->curTagArrayPtr[i] = textPtr->curTagArrayPtr[i+1];
	    }
	    textPtr->curTagArrayPtr[textPtr->numCurTags-1] = NULL;
	    textPtr->numCurTags--;
	    break;
	}
    }

    /*
     * If this tag is widget-specific (peer widgets) then clean up the
     * refCount it holds.
     */

    if (tagPtr->textPtr != NULL) {
	if (textPtr != tagPtr->textPtr) {
	    Tcl_Panic("Tag being deleted from wrong widget");
	}
	if (textPtr->refCount-- <= 1) {
	    ckfree(textPtr);
	}
	tagPtr->textPtr = NULL;
    }

    /*
     * Finally free the tag's memory.
     */

    ckfree(tagPtr);

















}

/*
 *----------------------------------------------------------------------
 *
 * SortTags --
 *
 *	This function sorts an array of tag pointers in increasing order of
 *	priority, optimizing for the common case where the array is small.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void








SortTags(
    int numTags,		/* Number of tag pointers at *tagArrayPtr. */
    TkTextTag **tagArrayPtr)	/* Pointer to array of pointers. */
{
    int i, j, prio;
    TkTextTag **tagPtrPtr;
    TkTextTag **maxPtrPtr, *tmp;


    if (numTags < 2) {
	return;
    }
    if (numTags < 20) {
	for (i = numTags-1; i > 0; i--, tagArrayPtr++) {
	    maxPtrPtr = tagPtrPtr = tagArrayPtr;
	    prio = tagPtrPtr[0]->priority;
	    for (j = i, tagPtrPtr++; j > 0; j--, tagPtrPtr++) {
		if (tagPtrPtr[0]->priority < prio) {
		    prio = tagPtrPtr[0]->priority;
		    maxPtrPtr = tagPtrPtr;
		}
	    }
	    tmp = *maxPtrPtr;
	    *maxPtrPtr = *tagArrayPtr;
	    *tagArrayPtr = tmp;
	}
    } else {



	qsort(tagArrayPtr,(unsigned)numTags,sizeof(TkTextTag *),TagSortProc);















    }




































































































































































































}

/*
 *----------------------------------------------------------------------
 *
 * TagSortProc --
 *
 *	This function is called by qsort() when sorting an array of tags in
 *	priority order.
 *
 * Results:
 *	The return value is -1 if the first argument should be before the
 *	second element (i.e. it has lower priority), 0 if it's equivalent
 *	(this should never happen!), and 1 if it should be after the second
 *	element.
 *
 * Side effects:
 *	None.

 *
 *----------------------------------------------------------------------
 */

static int
TagSortProc(
    const void *first,

    const void *second)		/* Elements to be compared. */


{
    TkTextTag *tagPtr1, *tagPtr2;



    tagPtr1 = * (TkTextTag **) first;

    tagPtr2 = * (TkTextTag **) second;
    return tagPtr1->priority - tagPtr2->priority;

}

/*
 *----------------------------------------------------------------------
 *
 * ChangeTagPriority --
 *
 *	This function changes the priority of a tag by modifying its priority
 *	and the priorities of other tags that are affected by the change.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Priorities may be changed for some or all of the tags in textPtr. The
 *	tags will be arranged so that there is exactly one tag at each
 *	priority level between 0 and textPtr->sharedTextPtr->numTags-1, with
 *	tagPtr at priority "prio".
 *
 *----------------------------------------------------------------------
 */

static void
ChangeTagPriority(
    TkText *textPtr,		/* Information about text widget. */
    TkTextTag *tagPtr,		/* Tag whose priority is to be changed. */
    int prio)			/* New priority for tag. */

{

    int low, high, delta;
    TkTextTag *tagPtr2;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;



    if (prio < 0) {

	prio = 0;
    }
    if (prio >= textPtr->sharedTextPtr->numTags) {


	prio = textPtr->sharedTextPtr->numTags-1;






    }

    if (prio == tagPtr->priority) {





	return;



    }

    if (prio < tagPtr->priority) {
	low = prio;
	high = tagPtr->priority-1;
	delta = 1;
    } else {
	low = tagPtr->priority+1;
	high = prio;
	delta = -1;
    }

    /*
     * Adjust first the 'sel' tag, then all others from the hash table
     */

    if ((textPtr->selTagPtr->priority >= low)
	    && (textPtr->selTagPtr->priority <= high)) {
	textPtr->selTagPtr->priority += delta;
    }


    for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->tagTable, &search);

	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	tagPtr2 = (TkTextTag *)Tcl_GetHashValue(hPtr);
	if ((tagPtr2->priority >= low) && (tagPtr2->priority <= high)) {
	    tagPtr2->priority += delta;
	}
    }

    tagPtr->priority = prio;


}

/*
 *--------------------------------------------------------------
 *
 * TkTextBindProc --
 *







|
<
|
|


<
<
|
|
<
<
<
|
<
<
<
<
<
|

|
<
|
<

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
<








|







|


|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>

>
|
>
>
|
>
>
>
>
|
>
>
>
>
|
>
>

>
>
>
>
>
|
>
>
>






<
<
<
<
<
<
<
<
<
<
<






>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>





|

|
|
>
>
>
>











|
|
>
>
>
>
|
>
|
>
>
>
>
|
>

|
|
|

|
>
>
>
|

|
|
|

|
|
|

<
<
<
|
<
|
<
<
<
<
<
<
<
|

|
|
|
|

|
|
<
<
|
<
<
|
|

|
|
|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|













|
>
>
>
>
>
>
>
>
|
|


|

|
>

|


|
|


|










>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|

|
|


<
<
<
|


<
>




<
<
|
>
|
>
>

|

>
>
|
>
|
|
>
















|
|




|

|

|
>

>
|



>

>
|
>
|

|
>
>
|
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
>
>
>

>
|
|
|


|
|







|
|
|
|
>
>
|
>
|

|



>
|
>
>







1985
1986
1987
1988
1989
1990
1991
1992

1993
1994
1995
1996


1997
1998



1999





2000
2001
2002

2003

2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130

2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202











2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293



2294

2295







2296
2297
2298
2299
2300
2301
2302
2303
2304


2305


2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612



2613
2614
2615

2616
2617
2618
2619
2620


2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkTextTag *
FindTag(
    Tcl_Interp *interp,		/* Interpreter to use for error message; if NULL, then don't record

    				 * an error message. */
    const TkText *textPtr,	/* Widget in which tag is being used. */
    Tcl_Obj *tagName)		/* Name of desired tag. */
{


    const char *name = Tcl_GetString(tagName);
    TkTextTag *tagPtr = TkTextFindTag(textPtr, name);









    if (!tagPtr && interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"tag \"%s\" isn't defined in text widget", name));

	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_TAG", name, (char *)NULL);

    }

    return tagPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextEnableTag --
 *
 *	If this tag is disabled, then re-enable it.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkTextEnableTag(
    TkSharedText *sharedTextPtr,/* Shared text resource. */
    TkTextTag *tagPtr)		/* Tag being deleted. */
{
    if (tagPtr->isDisabled) {
	tagPtr->isDisabled = 0;
	MarkIndex(sharedTextPtr, tagPtr, 1);
	sharedTextPtr->numEnabledTags += 1;
	ChangeTagPriority(sharedTextPtr, tagPtr, tagPtr->savedPriority, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextReleaseTag --
 *
 *	Delete this tag if the reference counter is going to zero, in this
 *	case clean up the tag structure itself. This requires that the given
 *	tag is not in use.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and other resources are freed.
 *
 *----------------------------------------------------------------------
 */

void
TkTextReleaseTag(
    TkSharedText *sharedTextPtr,/* Shared text resource. */
    TkTextTag *tagPtr,		/* Tag being deleted. */
    Tcl_HashEntry *hPtr)	/* Pointer into hash table, can be NULL. */
{
    assert(tagPtr->refCount > 1 || !tagPtr->rootPtr);

    if (--tagPtr->refCount > 0) {
	return;
    }

    assert(!tagPtr->recentTagAddRemoveToken);
    assert(!tagPtr->recentChangePriorityToken);

    MarkIndex(sharedTextPtr, tagPtr, 0);
    sharedTextPtr->numTags -= 1;

    if (!hPtr) {
	hPtr = Tcl_FindHashEntry(&sharedTextPtr->tagTable, tagPtr->name);
    }
    if (hPtr) {
	Tcl_DeleteHashEntry(hPtr);
    } else {
	assert(tagPtr->isSelTag);
    }

    /*
     * Let Tk do most of the hard work for us.
     */

    if (tagPtr->isSelTag) {
	assert(tagPtr->textPtr);
	/* Restore the original values. */
	tagPtr->attrs = tagPtr->textPtr->selTagConfigAttrs;
    }
    Tk_FreeConfigOptions(tagPtr, tagPtr->optionTable, sharedTextPtr->peers->tkwin);

    /*
     * This associated information is managed by us.
     */

    if (tagPtr->tabArrayPtr) {
	ckfree(tagPtr->tabArrayPtr);
    }

    if (sharedTextPtr->tagBindingTable) {
	Tk_DeleteAllBindings(sharedTextPtr->tagBindingTable, (void *)tagPtr->name);
    }

    /*
     * If this tag is widget-specific (peer widgets) then clean up the
     * refCount it holds.
     */

    if (tagPtr->textPtr) {
	TkTextDecrRefCountAndTestIfDestroyed((TkText *) tagPtr->textPtr);
	tagPtr->textPtr = NULL;
    }

    /*
     * Finally free the tag's memory.
     */

    ckfree(tagPtr);
    DEBUG_ALLOC(tkTextCountDestroyTag++);
}
/*
 *----------------------------------------------------------------------
 *
 * TkTextDeleteTag --
 *
 *	This function is called to carry out most actions associated with the
 *	'tag delete' sub-command. It will remove all evidence of the tag from
 *	the B-tree, and then clean up the tag structure itself.

 *
 *	The only actions this doesn't carry out it to check if the deletion of
 *	the tag requires something to be re-displayed, and to remove the tag
 *	from the tagTable (hash table) if that is necessary (i.e. if it's not
 *	the 'sel' tag). It is expected that the caller carry out both of these
 *	actions.
 *
 * Results:
 *	Returns whether this tag was used in current text content.
 *
 * Side effects:
 *	Memory and other resources are freed, the B-tree is manipulated.
 *
 *----------------------------------------------------------------------
 */

int
TkTextDeleteTag(
    TkText *textPtr,		/* Info about overall widget. */
    TkTextTag *tagPtr,		/* Tag being deleted. */
    Tcl_HashEntry *hPtr)	/* Pointer into hash table, can be NULL (but only for "sel"). */
{
    TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    int used;

    assert(!sharedTextPtr->undoStack || !TkTextUndoIsPerformingUndo(sharedTextPtr->undoStack));
    assert(!sharedTextPtr->undoStack || !TkTextUndoIsPerformingRedo(sharedTextPtr->undoStack));
    assert(hPtr || tagPtr->isSelTag);

    used = !!tagPtr->rootPtr;

    if (used) {
	TkTextUndoInfo undoInfo;
	TkTextUndoInfo *undoInfoPtr;
	TkTextIndex startIndex;
	TkTextIndex index[2];
	TkTextSearch tSearch;
	int useUndo = !!(textPtr->flags & DESTROYED) && UndoTagOperation(sharedTextPtr, tagPtr);

	undoInfoPtr = useUndo ? &undoInfo : NULL;

	TkTextIndexSetupToStartOfText(&index[0], NULL, sharedTextPtr->tree);
	TkTextIndexSetupToEndOfText(&index[1], NULL, sharedTextPtr->tree);

	TkBTreeStartSearch(&index[0], &index[1], tagPtr, &tSearch, SEARCH_NEXT_TAGON);
	TkBTreeNextTag(&tSearch);
	assert(tSearch.segPtr); /* last search must not fail */
	startIndex = tSearch.curIndex;

	TkBTreeStartSearchBack(&index[1], &index[0], tagPtr, &tSearch, SEARCH_EITHER_TAGON_TAGOFF);
	TkBTreePrevTag(&tSearch);
	assert(tSearch.segPtr); /* last search must not fail */
	assert(!tSearch.tagon); /* we must find tagoff */

	TkBTreeTag(textPtr->sharedTextPtr, textPtr, &startIndex, &tSearch.curIndex,
		tagPtr, 0, undoInfoPtr, TkTextRedrawTag);

	if (undoInfoPtr && undoInfoPtr->token) {
	    tagPtr->refCount += 1;
	    TkTextUndoPushItem(sharedTextPtr->undoStack, undoInfo.token, undoInfo.byteSize);
	}
    }

    assert(!tagPtr->rootPtr);

    if (!(textPtr->flags & DESTROYED) && tagPtr->isSelTag) {
	/*
	 * Send an event that the selection changed. This is equivalent to:
	 *	event generate $textWidget <<Selection>>
	 */

	TkTextSelectionEvent(textPtr);











    }

    /*
     * Update the tag priorities to reflect the deletion of this tag.
     */

    tagPtr->savedPriority = tagPtr->priority;
    ChangeTagPriority(sharedTextPtr, tagPtr, sharedTextPtr->numEnabledTags - 1, 0);
    sharedTextPtr->numEnabledTags -= 1;

    /*
     * Make sure this tag isn't referenced from the 'current' tag array.
     */

    if (tagPtr->index < TkTextTagSetSize(textPtr->curTagInfoPtr)) {
	textPtr->curTagInfoPtr = TkTextTagSetErase(textPtr->curTagInfoPtr, tagPtr->index);
    }

    /*
     * Handle the retained undo tokens.
     */

    if (tagPtr->undoTagListIndex >= 0) {
	if (sharedTextPtr->undoStack) {
	    TkTextPushUndoTagTokens(sharedTextPtr, tagPtr);
	} else {
	    TkTextReleaseUndoTagToken(sharedTextPtr, tagPtr);
	}
    }

    tagPtr->isDisabled = 1;
    TkTextReleaseTag(sharedTextPtr, tagPtr, hPtr);
    return used;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextFreeAllTags --
 *
 *	This function is called when all tags are deleted to free up the memory
 *	and other resources associated with tags.
 *
 *	Note that this function is not freeing the indices
 *	('sharedTextPtr->usedTags', 'sharedTextPtr->elisionTags'), but both
 *	sets will be cleared.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory and other resources are freed.
 *
 *----------------------------------------------------------------------
 */

void
TkTextFreeAllTags(
    TkText *textPtr)		/* Info about overall widget. */
{
    TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;

    DEBUG(textPtr->refCount += 1);

    for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
	    hPtr;
	    hPtr = Tcl_NextHashEntry(&search)) {
	TkTextTag *tagPtr = (TkTextTag *)Tcl_GetHashValue(hPtr);

	assert(tagPtr->refCount == 1);

	/*
	 * Let Tk do most of the hard work for us.
	 */

	if (tagPtr->isSelTag) {
	    assert(tagPtr->textPtr);
	    tagPtr->attrs = tagPtr->textPtr->selTagConfigAttrs;
	}
	Tk_FreeConfigOptions(tagPtr, tagPtr->optionTable, textPtr->tkwin);

	/*
	 * This associated information is managed by us.
	 */

	if (tagPtr->tabArrayPtr) {
	    ckfree(tagPtr->tabArrayPtr);
	}




	if (tagPtr->undoTagListIndex >= 0) {

	    TkTextReleaseUndoTagToken(sharedTextPtr, tagPtr);







	}

	/*
	 * If this tag is widget-specific (peer widgets) then clean up the
	 * refCount it holds.
	 */

	if (tagPtr->textPtr) {
	    assert(textPtr == tagPtr->textPtr);


	    textPtr->refCount -= 1;


	    tagPtr->textPtr = NULL;
	}

	/*
	 * Finally free the tag's memory.
	 */

	ckfree(tagPtr);
	DEBUG_ALLOC(tkTextCountDestroyTag++);
    }

    TkTextTagSetDecrRefCount(textPtr->curTagInfoPtr);
    TkTextTagSetIncrRefCount(textPtr->curTagInfoPtr = sharedTextPtr->emptyTagInfoPtr);

    TkBitClear(sharedTextPtr->usedTags);
    TkBitClear(sharedTextPtr->elisionTags);
    TkBitClear(sharedTextPtr->affectDisplayTags);
    TkBitClear(sharedTextPtr->notAffectDisplayTags);
    TkBitClear(sharedTextPtr->affectDisplayNonSelTags);
    TkBitClear(sharedTextPtr->affectGeometryTags);
    TkBitClear(sharedTextPtr->affectGeometryNonSelTags);
    TkBitClear(sharedTextPtr->affectLineHeightTags);

    DEBUG(textPtr->refCount -= 1);
    assert(textPtr->refCount > 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextSortTags --
 *
 *	This function sorts an array of tag pointers in increasing order of
 *	priority, optimizing for the common case where the array is small.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TagSortProc(
    const void *first,
    const void *second)		/* Elements to be compared. */
{
    return (int) (*(TkTextTag **) first)->priority - (int) (*(TkTextTag **) second)->priority;
}

void
TkTextSortTags(
    unsigned numTags,		/* Number of tag pointers at *tagArrayPtr. */
    TkTextTag **tagArrayPtr)	/* Pointer to array of pointers. */
{
    unsigned i, j, prio;
    TkTextTag **tagPtrPtr;
    TkTextTag **maxPtrPtr;
    TkTextTag *tmp;

    if (numTags <= 1) {
	return;
    }
    if (numTags <= 20) {
	for (i = numTags - 1; i > 0; i--, tagArrayPtr++) {
	    maxPtrPtr = tagPtrPtr = tagArrayPtr;
	    prio = tagPtrPtr[0]->priority;
	    for (j = i, tagPtrPtr += 1; j > 0; --j, ++tagPtrPtr) {
		if (tagPtrPtr[0]->priority < prio) {
		    prio = tagPtrPtr[0]->priority;
		    maxPtrPtr = tagPtrPtr;
		}
	    }
	    tmp = *maxPtrPtr;
	    *maxPtrPtr = *tagArrayPtr;
	    *tagArrayPtr = tmp;
	}
    } else {
	qsort(tagArrayPtr, numTags, sizeof(TkTextTag *), TagSortProc);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextReleaseUndoTagToken --
 *
 *	Release retained undo tokens for tag operations.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Free some memory.
 *
 *----------------------------------------------------------------------
 */

void
TkTextReleaseUndoTagToken(
    TkSharedText *sharedTextPtr,
    TkTextTag *tagPtr)
{
    assert(sharedTextPtr);

    if (!tagPtr) {
	return;
    }

    assert(tagPtr->undoTagListIndex >= 0);
    assert(tagPtr->undoTagListIndex < (int) sharedTextPtr->undoTagListCount);

    if (tagPtr->recentTagAddRemoveToken) {
	ckfree(tagPtr->recentTagAddRemoveToken);
	DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	tagPtr->recentTagAddRemoveToken = NULL;
    }
    if (tagPtr->recentChangePriorityToken) {
	ckfree(tagPtr->recentChangePriorityToken);
	DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	tagPtr->recentChangePriorityToken = NULL;
    }

    sharedTextPtr->undoTagList[tagPtr->undoTagListIndex] = NULL;
    tagPtr->undoTagListIndex = -1;
    assert(tagPtr->refCount > 1);
    tagPtr->refCount -= 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextInspectUndoTagItem --
 *
 *	Inspect retained undo token.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is allocated for the result.
 *
 *----------------------------------------------------------------------
 */

void
TkTextInspectUndoTagItem(
    const TkSharedText *sharedTextPtr,
    const TkTextTag *tagPtr,
    Tcl_Obj* objPtr)
{
    if (tagPtr) {
	if (tagPtr->recentTagAddRemoveToken && !tagPtr->recentTagAddRemoveTokenIsNull) {
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    TkBTreeUndoTagInspect(sharedTextPtr, tagPtr->recentTagAddRemoveToken));
	}
	if (tagPtr->recentChangePriorityToken) {
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    UndoChangeTagPriorityInspect(sharedTextPtr, tagPtr->recentChangePriorityToken));
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextPushUndoTagTokens --
 *
 *	Push retained undo tokens for tag operations onto the undo stack.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Same as TkTextUndoPushItem.
 *
 *----------------------------------------------------------------------
 */

void
TkTextPushUndoTagTokens(
    TkSharedText *sharedTextPtr,
    TkTextTag *tagPtr)
{
    assert(sharedTextPtr);
    assert(sharedTextPtr->undoStack);

    if (!tagPtr) {
	return;
    }

    assert(tagPtr->undoTagListIndex >= 0);
    assert(tagPtr->undoTagListIndex < (int) sharedTextPtr->undoTagListCount);

    if (tagPtr->recentTagAddRemoveToken) {
	if (tagPtr->recentTagAddRemoveTokenIsNull) {
	    ckfree(tagPtr->recentTagAddRemoveToken);
	    DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	} else {
	    TkTextUndoPushItem(sharedTextPtr->undoStack, tagPtr->recentTagAddRemoveToken, 0);
	    tagPtr->refCount += 1;
	}
	tagPtr->recentTagAddRemoveToken = NULL;
    }
    if (tagPtr->recentChangePriorityToken) {
	if (tagPtr->savedPriority != tagPtr->priority) {
	    TkTextUndoPushItem(sharedTextPtr->undoStack, tagPtr->recentChangePriorityToken, 0);
	    tagPtr->refCount += 1;
	} else {
	    ckfree(tagPtr->recentChangePriorityToken);
	    DEBUG_ALLOC(tkTextCountDestroyUndoToken++);
	}
	tagPtr->recentChangePriorityToken = NULL;
    }

    sharedTextPtr->undoTagList[tagPtr->undoTagListIndex] = NULL;
    tagPtr->undoTagListIndex = -1;
    assert(tagPtr->refCount > 1);
    tagPtr->refCount -= 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextTagAddRetainedUndo --
 *
 *	Add given tag to undo list, because this tag has retained undo
 *	tokens.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference counter of the tag will be incremented.
 *
 *----------------------------------------------------------------------
 */

void
TkTextTagAddRetainedUndo(
    TkSharedText *sharedTextPtr,	/* Shared text resource. */
    TkTextTag *tagPtr)			/* Add this tag to undo list. */
{
    assert(sharedTextPtr);
    assert(tagPtr);

    if (tagPtr->undoTagListIndex >= 0) {
	return;
    }

    if (sharedTextPtr->undoTagListCount == sharedTextPtr->undoTagListSize) {
	sharedTextPtr->undoTagListSize = 2*sharedTextPtr->numEnabledTags;
	sharedTextPtr->undoTagList = (TkTextTag**)ckrealloc(sharedTextPtr->undoTagList,
		sharedTextPtr->undoTagListSize * sizeof(sharedTextPtr->undoTagList[0]));
    }
    sharedTextPtr->undoTagList[sharedTextPtr->undoTagListCount] = tagPtr;
    sharedTextPtr->undoStackEvent = 1;
    sharedTextPtr->lastUndoTokenType = -1;
    tagPtr->undoTagListIndex = sharedTextPtr->undoTagListCount++;
    tagPtr->refCount += 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextPushTagPriorityUndo --
 *
 *	This function is pushing an undo item for setting the priority
 *	of a mark (raise/lower command).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Some memory will be allocated, and see TkTextPushUndoToken.
 *
 *----------------------------------------------------------------------
 */

void
TkTextPushTagPriorityUndo(
    TkSharedText *sharedTextPtr,
    TkTextTag *tagPtr,
    unsigned priority)
{
    UndoTokenTagPriority *token;

    token = (UndoTokenTagPriority *)ckalloc(sizeof(UndoTokenTagPriority));
    token->undoType = &undoTokenTagPriorityType;
    (token->tagPtr = tagPtr)->refCount += 1;
    token->priority = priority;
    DEBUG_ALLOC(tkTextCountNewUndoToken++);

    TkTextPushUndoToken(sharedTextPtr, token, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkTextPushTagPriorityRedo --
 *
 *	This function is pushing a redo item for setting the priority
 *	of a mark (raise/lower command).
 *
 * Results:



 *	None.
 *
 * Side effects:

 *	Some memory will be allocated, and see TkTextPushRedoToken.
 *
 *----------------------------------------------------------------------
 */



void
TkTextPushTagPriorityRedo(
    TkSharedText *sharedTextPtr,
    TkTextTag *tagPtr,
    unsigned priority)
{
    UndoTokenTagPriority *token;

    token = (UndoTokenTagPriority *)ckalloc(sizeof(UndoTokenTagPriority));
    token->undoType = &redoTokenTagPriorityType;
    (token->tagPtr = tagPtr)->refCount += 1;
    token->priority = priority;
    DEBUG_ALLOC(tkTextCountNewUndoToken++);

    TkTextPushRedoToken(sharedTextPtr, token, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * ChangeTagPriority --
 *
 *	This function changes the priority of a tag by modifying its priority
 *	and the priorities of other tags that are affected by the change.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Priorities may be changed for some or all of the tags in textPtr. The
 *	tags will be arranged so that there is exactly one tag at each
 *	priority level between 0 and textPtr->sharedTextPtr->numEnabledTags-1,
 *	with tagPtr at priority "newPriority".
 *
 *----------------------------------------------------------------------
 */

static int
ChangeTagPriority(
    TkSharedText *sharedTextPtr,/* Shared text resource. */
    TkTextTag *tagPtr,		/* Tag whose priority is to be changed. */
    unsigned newPriority,	/* New priority for tag. */
    int undo)			/* Push undo item for this action? */
{
    int delta;
    unsigned low, high;
    TkTextTag *tagPtr2;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    TkText *peer;

    assert(newPriority < sharedTextPtr->numEnabledTags);

    if (newPriority == tagPtr->priority) {
	return 0;
    }

    if (undo && tagPtr->undo && !TkTextUndoStackIsFull(sharedTextPtr->undoStack)) {
	UndoTokenTagPriority *token = (UndoTokenTagPriority *) tagPtr->recentChangePriorityToken;

	/*
	 * Don't push changes of tag priorities immediately onto the undo stack, this
	 * may blow up the stack. We save this undo token inside the tag, in this way
	 * only the relevant changes will be pushed as soon as a separator will be
	 * pushed.
	 */

	if (!tagPtr->recentChangePriorityToken) {
	    tagPtr->savedPriority = tagPtr->priority;
	    token = (UndoTokenTagPriority *)ckalloc(sizeof(UndoTokenTagPriority));
	    DEBUG_ALLOC(tkTextCountNewUndoToken++);
	    tagPtr->recentChangePriorityToken = (TkTextUndoToken *) token;
	    TkTextTagAddRetainedUndo(sharedTextPtr, tagPtr);
	}

	token->undoType = &undoTokenTagPriorityType;
	token->tagPtr = tagPtr;
	token->priority = tagPtr->priority;
    }

    if (newPriority < tagPtr->priority) {
	low = newPriority;
	high = tagPtr->priority - 1;
	delta = 1;
    } else {
	low = tagPtr->priority + 1;
	high = newPriority;
	delta = -1;
    }

    /*
     * Adjust first the 'sel' tag, then all others from the hash table
     */

    for (peer = sharedTextPtr->peers; peer; peer = peer->next) {
	if (low <= peer->selTagPtr->priority && peer->selTagPtr->priority <= high) {
	    peer->selTagPtr->priority += delta;
	}
    }

    for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
	    hPtr;
	    hPtr = Tcl_NextHashEntry(&search)) {
	tagPtr2 = (TkTextTag *)Tcl_GetHashValue(hPtr);
	if (low <= tagPtr2->priority && tagPtr2->priority <= high) {
	    tagPtr2->priority += delta;
	}
    }

    tagPtr->priority = newPriority;

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextBindProc --
 *
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
 *	any).
 *
 *--------------------------------------------------------------
 */

void
TkTextBindProc(
    ClientData clientData,	/* Pointer to text widget structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkText *textPtr = (TkText *)clientData;

    int repick = 0;

    textPtr->refCount++;

    /*
     * This code simulates grabs for mouse buttons by keeping track of whether
     * a button is pressed and refusing to pick a new current character while
     * a button is pressed.
     */

    if (eventPtr->type == ButtonPress) {
	textPtr->flags |= BUTTON_DOWN;
    } else if (eventPtr->type == ButtonRelease) {
	unsigned long mask;

	mask = Tk_GetButtonMask(eventPtr->xbutton.button);
	if ((eventPtr->xbutton.state & ALL_BUTTONS) == mask) {
	    textPtr->flags &= ~BUTTON_DOWN;
	    repick = 1;



	}
    } else if ((eventPtr->type == EnterNotify)
	    || (eventPtr->type == LeaveNotify)) {
	if (eventPtr->xcrossing.state & ALL_BUTTONS) {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
	goto done;
    } else if (eventPtr->type == MotionNotify) {
	if (eventPtr->xmotion.state & ALL_BUTTONS) {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
    }
    if ((textPtr->numCurTags > 0)
	    && (textPtr->sharedTextPtr->bindingTable != NULL)
	    && (textPtr->tkwin != NULL) && !(textPtr->flags & DESTROYED)) {






	TagBindEvent(textPtr, eventPtr, textPtr->numCurTags,





		textPtr->curTagArrayPtr);














    }
    if (repick) {
	unsigned int oldState;

	oldState = eventPtr->xbutton.state;
	eventPtr->xbutton.state &= ~(unsigned long)ALL_BUTTONS;
	if (!(textPtr->flags & DESTROYED)) {
	    TkTextPickCurrent(textPtr, eventPtr);
	}
	eventPtr->xbutton.state = oldState;
    }

  done:
    if (textPtr->refCount-- <= 1) {
	ckfree(textPtr);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextPickCurrent --
 *







|



>



















>
>
>


















|
|
|
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|







|
|
<







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
 *	any).
 *
 *--------------------------------------------------------------
 */

void
TkTextBindProc(
    void *clientData,	/* Pointer to text widget structure. */
    XEvent *eventPtr)		/* Pointer to X event that just happened. */
{
    TkText *textPtr = (TkText *)clientData;
    int dontRepick = textPtr->dontRepick;
    int repick = 0;

    textPtr->refCount++;

    /*
     * This code simulates grabs for mouse buttons by keeping track of whether
     * a button is pressed and refusing to pick a new current character while
     * a button is pressed.
     */

    if (eventPtr->type == ButtonPress) {
	textPtr->flags |= BUTTON_DOWN;
    } else if (eventPtr->type == ButtonRelease) {
	unsigned long mask;

	mask = Tk_GetButtonMask(eventPtr->xbutton.button);
	if ((eventPtr->xbutton.state & ALL_BUTTONS) == mask) {
	    textPtr->flags &= ~BUTTON_DOWN;
	    repick = 1;
	    if (eventPtr->xbutton.state & (Button1|Button2|Button3)) {
		textPtr->dontRepick = 0; /* in case of button clicks we must repick */
	    }
	}
    } else if ((eventPtr->type == EnterNotify)
	    || (eventPtr->type == LeaveNotify)) {
	if (eventPtr->xcrossing.state & ALL_BUTTONS) {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
	goto done;
    } else if (eventPtr->type == MotionNotify) {
	if (eventPtr->xmotion.state & ALL_BUTTONS) {
	    textPtr->flags |= BUTTON_DOWN;
	} else {
	    textPtr->flags &= ~BUTTON_DOWN;
	}
	TkTextPickCurrent(textPtr, eventPtr);
    }
    if (!(textPtr->flags & DESTROYED)) {
	const TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;

	if (sharedTextPtr->tagBindingTable) {
	    if (!TkTextTagSetIsEmpty(textPtr->curTagInfoPtr)) {
		/*
		 * The mouse is inside the text widget, the 'current' mark was updated.
		 */

		TagBindEvent(textPtr, eventPtr, textPtr->curTagInfoPtr, sharedTextPtr->tagEpoch);
	    } else if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
		 /*
		  * Key events fire independently of the 'current' mark and use the
		  * 'insert' mark.
		  */

		TkTextIndex index;
		TkTextTagSet *insertTags;

		TkTextMarkNameToIndex(textPtr, "insert", &index);
		insertTags = TkTextIndexGetContentSegment(&index, NULL)->tagInfoPtr;
		if (!TkTextTagSetIsEmpty(insertTags)) {
		    TagBindEvent(textPtr, eventPtr, insertTags, sharedTextPtr->tagEpoch);
		}
	    }
	    if (textPtr->flags & DESTROYED) {
		TkTextDecrRefCountAndTestIfDestroyed(textPtr);
		return;
	    }
	}
    }
    if (repick) {
	unsigned int oldState;

	oldState = eventPtr->xbutton.state;
	eventPtr->xbutton.state &= ~ALL_BUTTONS;
	if (!(textPtr->flags & DESTROYED)) {
	    TkTextPickCurrent(textPtr, eventPtr);
	}
	eventPtr->xbutton.state = oldState;
    }

  done:
    textPtr->dontRepick = dontRepick;
    TkTextDecrRefCountAndTestIfDestroyed(textPtr);

}

/*
 *--------------------------------------------------------------
 *
 * TkTextPickCurrent --
 *
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
 *	associated with character entry and leave could do just about
 *	anything. For example, the text widget might be deleted. It is up to
 *	the caller to protect itself by incrementing the refCount of the text
 *	widget.
 *
 *--------------------------------------------------------------
 */











void
TkTextPickCurrent(
    TkText *textPtr,	/* Text widget in which to select current
				 * character. */
    XEvent *eventPtr)		/* Event describing location of mouse cursor.
				 * Must be EnterWindow, LeaveWindow,
				 * ButtonRelease, or MotionNotify. */
{


    TkTextIndex index;
    TkTextTag **oldArrayPtr, **newArrayPtr;
    TkTextTag **copyArrayPtr = NULL;
				/* Initialization needed to prevent compiler
				 * warning. */
    int numOldTags, numNewTags, i, j, nearby;
    size_t size;


    XEvent event;




    /*
     * If a button is down, then don't do anything at all; we'll be called
     * again when all buttons are up, and we can repick then. This implements
     * a form of mouse grabbing.
     */

    if (textPtr->flags & BUTTON_DOWN) {
	if (((eventPtr->type == EnterNotify)
		|| (eventPtr->type == LeaveNotify))
		&& ((eventPtr->xcrossing.mode == NotifyGrab)


		|| (eventPtr->xcrossing.mode == NotifyUngrab))) {
	    /*
	     * Special case: the window is being entered or left because of a
	     * grab or ungrab. In this case, repick after all. Furthermore,
	     * clear BUTTON_DOWN to release the simulated grab.
	     */

	    textPtr->flags &= ~BUTTON_DOWN;
	} else {
	    return;
	}
    }

    /*
     * Save information about this event in the widget in case we have to
     * synthesize more enter and leave events later (e.g. because a character
     * was deleted, causing a new character to be underneath the mouse
     * cursor). Also translate MotionNotify events into EnterNotify events,
     * since that's what gets reported to event handlers when the current
     * character changes.
     */

    if (eventPtr != &textPtr->pickEvent) {
	if ((eventPtr->type == MotionNotify)
		|| (eventPtr->type == ButtonRelease)) {
	    textPtr->pickEvent.xcrossing.type = EnterNotify;
	    textPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial;
	    textPtr->pickEvent.xcrossing.send_event
		    = eventPtr->xmotion.send_event;
	    textPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display;
	    textPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window;
	    textPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root;
	    textPtr->pickEvent.xcrossing.subwindow = None;
	    textPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
	    textPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
	    textPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
	    textPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
	    textPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
	    textPtr->pickEvent.xcrossing.mode = NotifyNormal;
	    textPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
	    textPtr->pickEvent.xcrossing.same_screen
		    = eventPtr->xmotion.same_screen;
	    textPtr->pickEvent.xcrossing.focus = False;
	    textPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
	} else {
	    textPtr->pickEvent = *eventPtr;
	}
    }


    /*







     * Find the new current character, then find and sort all of the tags

     * associated with it.



















     */

































    if (textPtr->pickEvent.type != LeaveNotify) {


	TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x,


		textPtr->pickEvent.xcrossing.y, &index, &nearby);
	if (nearby) {


	    newArrayPtr = NULL;












	    numNewTags = 0;







	} else {

	    newArrayPtr = TkBTreeGetTags(&index, textPtr, &numNewTags);


	    SortTags(numNewTags, newArrayPtr);



	}




    } else {

	newArrayPtr = NULL;

	numNewTags = 0;
    }






    /*


     * Resort the tags associated with the previous marked character (the











     * priorities might have changed), then make a copy of the new tags, and
     * compare the old tags to the copy, nullifying any tags that are present
     * in both groups (i.e. the tags that haven't changed).




     */











































    SortTags(textPtr->numCurTags, textPtr->curTagArrayPtr);
    if (numNewTags > 0) {



	size = numNewTags * sizeof(TkTextTag *);





	copyArrayPtr = (TkTextTag **)ckalloc(size);



	memcpy(copyArrayPtr, newArrayPtr, size);
	for (i = 0; i < textPtr->numCurTags; i++) {
	    for (j = 0; j < numNewTags; j++) {













		if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) {










		    textPtr->curTagArrayPtr[i] = NULL;
		    copyArrayPtr[j] = NULL;





		    break;
		}
	    }
	}
    }

    /*

     * Invoke the binding system with a LeaveNotify event for all of the tags
     * that have gone away. We have to be careful here, because it's possible
     * that the binding could do something (like calling tkwait) that
     * eventually modifies textPtr->curTagArrayPtr. To avoid problems in
     * situations like this, update curTagArrayPtr to its new value before
     * invoking any bindings, and don't use it any more here.
     */



    numOldTags = textPtr->numCurTags;
    textPtr->numCurTags = numNewTags;
    oldArrayPtr = textPtr->curTagArrayPtr;
    textPtr->curTagArrayPtr = newArrayPtr;
    if (numOldTags != 0) {
	if ((textPtr->sharedTextPtr->bindingTable != NULL)
		&& (textPtr->tkwin != NULL)
		&& !(textPtr->flags & DESTROYED)) {
	    event = textPtr->pickEvent;
	    event.type = LeaveNotify;


	    /*



	     * Always use a detail of NotifyAncestor. Besides being
	     * consistent, this avoids problems where the binding code will
	     * discard NotifyInferior events.
	     */



	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, numOldTags, oldArrayPtr);

	}
	ckfree(oldArrayPtr);
    }




    /*
     * Reset the "current" mark (be careful to recompute its location, since
     * it might have changed during an event binding). Then invoke the binding





     * system with an EnterNotify event for all of the tags that have just


     * appeared.








     */



    TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x,
	    textPtr->pickEvent.xcrossing.y, &index, &nearby);
    TkTextSetMark(textPtr, "current", &index);
    if (numNewTags != 0) {


	if ((textPtr->sharedTextPtr->bindingTable != NULL)





		&& (textPtr->tkwin != NULL)
		&& !(textPtr->flags & DESTROYED) && !nearby) {
	    event = textPtr->pickEvent;
	    event.type = EnterNotify;
	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, numNewTags, copyArrayPtr);
	}
	ckfree(copyArrayPtr);



    }











}

/*
 *--------------------------------------------------------------
 *
 * TagBindEvent --
 *







>
>
>
>
>
>
>
>
>
>



|
<

|
<

>
>
|
|
|
|
<
|
|
>
>

>
>
>








|
|
|
>
>
|
|
|
|
|
|

|
<
<
<












|
<


|
<











|
<







>
|
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
|
>
>
|
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
|
>
>
|
>
>
>
|
>
>
>
>
|
>
|
>
|
|
>
>
>
>
|
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
<
<
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
|
|
>
>
>
|
>
>
>
>
>
|
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
|
|
|
|
|

<
>
|
|
<
|
<
<
<
>
|
>
|
<
<
<
<
|
<
<
<
<

>
|
>
>
>
|
|
|
|

>
>
|
|
>
|
<
|
>
>

>
|
|
|
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
|
>
>
|
|
|
|
|
>
>
|
>
>
>
>
>
|
<



|

|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>







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
 *	associated with character entry and leave could do just about
 *	anything. For example, the text widget might be deleted. It is up to
 *	the caller to protect itself by incrementing the refCount of the text
 *	widget.
 *
 *--------------------------------------------------------------
 */

static int
DispChunkContainsX(
    TkText *textPtr,
    const TkTextDispChunk *chunkPtr,
    int x)
{
    int cx = TkTextGetXPixelFromChunk(textPtr, chunkPtr);
    return cx <= x && x < cx + chunkPtr->width;
}

void
TkTextPickCurrent(
    TkText *textPtr,		/* Text widget in which to select current character. */

    XEvent *eventPtr)		/* Event describing location of mouse cursor.
				 * Must be EnterWindow, LeaveWindow, ButtonRelease, or MotionNotify. */

{
    TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    int sameChunkWithUnchangedTags = 0;
    TkTextTagSet *newTagInfoPtr;
    TkTextTagSet *leaveTags;
    TkTextTagSet *enterTags;
    const TkTextDispChunk *newDispChunkPtr = NULL;

    int nearby = 0;
    int sentEvents = 0;
    int newLineY = TK_TEXT_IS_NEARBY;
    TkTextIndex index;
    XEvent event;
    unsigned tagEpoch;

    assert(!(textPtr->flags & DESTROYED));

    /*
     * If a button is down, then don't do anything at all; we'll be called
     * again when all buttons are up, and we can repick then. This implements
     * a form of mouse grabbing.
     */

    if (textPtr->flags & BUTTON_DOWN) {
	if ((eventPtr->type != EnterNotify && eventPtr->type != LeaveNotify)
		|| (eventPtr->xcrossing.mode != NotifyGrab
		    && eventPtr->xcrossing.mode != NotifyUngrab)) {
	    return;
	}

	/*
	 * Special case: the window is being entered or left because of a
	 * grab or ungrab. In this case, repick after all. Furthermore,
	 * clear BUTTON_DOWN to release the simulated grab.
	 */

	textPtr->flags &= ~BUTTON_DOWN;



    }

    /*
     * Save information about this event in the widget in case we have to
     * synthesize more enter and leave events later (e.g. because a character
     * was deleted, causing a new character to be underneath the mouse
     * cursor). Also translate MotionNotify events into EnterNotify events,
     * since that's what gets reported to event handlers when the current
     * character changes.
     */

    if (eventPtr != &textPtr->pickEvent) {
	if (eventPtr->type == MotionNotify || eventPtr->type == ButtonRelease) {

	    textPtr->pickEvent.xcrossing.type = EnterNotify;
	    textPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial;
	    textPtr->pickEvent.xcrossing.send_event = eventPtr->xmotion.send_event;

	    textPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display;
	    textPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window;
	    textPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root;
	    textPtr->pickEvent.xcrossing.subwindow = None;
	    textPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
	    textPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
	    textPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
	    textPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
	    textPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
	    textPtr->pickEvent.xcrossing.mode = NotifyNormal;
	    textPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
	    textPtr->pickEvent.xcrossing.same_screen = eventPtr->xmotion.same_screen;

	    textPtr->pickEvent.xcrossing.focus = False;
	    textPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
	} else {
	    textPtr->pickEvent = *eventPtr;
	}
    }

    if (textPtr->dontRepick) {
	/*
	 * The widget is scrolling, so avoid repicking until the scroll operation stops,
	 * but it's important that 'pickEvent' is up-to-date (see above).
	 */
	return;
    }

    /*
     * Find the new current character, then find and sort all of the tags associated with it.
     */

    if (textPtr->pickEvent.type == LeaveNotify) {
	TkTextTagSetIncrRefCount(newTagInfoPtr = sharedTextPtr->emptyTagInfoPtr);
	TkTextTagSetIncrRefCount(leaveTags = textPtr->curTagInfoPtr);
	TkTextTagSetIncrRefCount(enterTags = sharedTextPtr->emptyTagInfoPtr);
    } else {
	newDispChunkPtr = TkTextPixelIndex(textPtr,
		textPtr->pickEvent.xcrossing.x, textPtr->pickEvent.xcrossing.y, &index, &nearby);

	if (newDispChunkPtr) {
	    if (!nearby) {
		newLineY = TkTextGetYPixelFromChunk(textPtr, newDispChunkPtr);
	    }
	    sameChunkWithUnchangedTags = (newDispChunkPtr->uniqID == textPtr->lastChunkID);
	}

	/*
	 * We want to avoid that a cursor movement is constantly splitting and
	 * joining char segments. So we postpone the insertion of the "current"
	 * mark until TextWidgetObjCmd will be executed.
	 */

	textPtr->currentMarkIndex = index;
	TkTextIndexToByteIndex(&textPtr->currentMarkIndex);
	textPtr->haveToSetCurrentMark = 1;
	sharedTextPtr->haveToSetCurrentMark = 1;

	if (textPtr->lastLineY == TK_TEXT_NEARBY_IS_UNDETERMINED
		|| (textPtr->lastLineY == TK_TEXT_IS_NEARBY) != nearby) {
	    sameChunkWithUnchangedTags = 0;
	} else if (nearby) {
	    sameChunkWithUnchangedTags = 1;
	} else if (eventPtr->type != MotionNotify || sharedTextPtr->numMotionEventBindings > 0) {
	    sameChunkWithUnchangedTags = 0;
	}

	if (nearby) {
	    TkTextTagSetIncrRefCount(newTagInfoPtr = sharedTextPtr->emptyTagInfoPtr);
	    TkTextTagSetIncrRefCount(leaveTags = textPtr->curTagInfoPtr);
	    TkTextTagSetIncrRefCount(enterTags = sharedTextPtr->emptyTagInfoPtr);
	} else if (sameChunkWithUnchangedTags) {
	    TkTextTagSetIncrRefCount(newTagInfoPtr = textPtr->curTagInfoPtr);
	    TkTextTagSetIncrRefCount(leaveTags = sharedTextPtr->emptyTagInfoPtr);
	    TkTextTagSetIncrRefCount(enterTags = sharedTextPtr->emptyTagInfoPtr);
	} else {
	    /*
	     * NOTE: the tag event handling depends on the display content, and not on
	     * the content of the B-Tree.
	     */

	    if (!(newTagInfoPtr = TkTextGetTagSetFromChunk(newDispChunkPtr))) {
	    	newTagInfoPtr = sharedTextPtr->emptyTagInfoPtr;
	    }
	    TkTextTagSetIncrRefCount(newTagInfoPtr);
	    leaveTags = TkTextTagSetCopy(textPtr->curTagInfoPtr);
	    leaveTags = TkTextTagSetRemoveFromThis(leaveTags, newTagInfoPtr);
	    enterTags = TkTextTagSetRemoveFromThis(TkTextTagSetCopy(newTagInfoPtr), leaveTags);
	    enterTags = TkTextTagSetRemoveFromThis(enterTags, textPtr->curTagInfoPtr);
	}
    }

    if (newLineY != TK_TEXT_IS_NEARBY
	    && textPtr->lastLineY != TK_TEXT_IS_NEARBY
	    && !sameChunkWithUnchangedTags
	    && sharedTextPtr->tagBindingTable) {
	if (textPtr->lastLineY == newLineY) {
	    /*
	     * We have to work-around a severe problem: per default the event handler is
	     * collapsing mouse motion events. This must not happen, a collapse of motion
	     * events has to be done on window level. For the text widget this means that
	     * we sometimes miss the transition from tagged region to tagged region. So we
	     * have to use a work-around for the x-direction: if the display line has not
	     * changed, then call TkTextPixelIndex for every intermediate x position. Of
	     * course this can be handled a bit more clever: traverse all the chunks
	     * between new chunk and old chunk, and send the first leave event, provided
	     * that this happens.
	     *
	     *     leaveTags = old.tags
	     *     for chunk = old.successor to new.predecessor
	     *         foreach t in (leaveTags - chunk.tags)
	     *             t.sendLeave
	     *             leaveTags -= t # do not send anymore
	     *         rof
	     *     rof
	     */

	    const TkTextDispChunk *nextDispChunkPtr;
	    int lastX = textPtr->lastX;
	    int movedToLeft;
	    int sx, sy; /* translation to current scroll position */

	    TkTextGetViewOffset(textPtr, &sx, &sy);
	    movedToLeft = textPtr->pickEvent.xcrossing.x + sx <= lastX;
	    nextDispChunkPtr = newDispChunkPtr;

	    if (movedToLeft) {
		/*
		 * Setup nextDispChunkPtr to predecessor of last chunk.
		 */

		/* find last chunk */
		while (nextDispChunkPtr->nextPtr
			&& !DispChunkContainsX(textPtr, nextDispChunkPtr, lastX)) {
		    nextDispChunkPtr = nextDispChunkPtr->nextPtr;
		}
		if (nextDispChunkPtr != newDispChunkPtr
			&& DispChunkContainsX(textPtr, nextDispChunkPtr, lastX)) {
		    /* move to predecessor of last chunk */
		    nextDispChunkPtr = nextDispChunkPtr->prevPtr;
		}
	    } else {
		/*
		 * Setup nextDispChunkPtr to successor of last chunk.
		 */

		/* find last chunk */
		while (nextDispChunkPtr->prevPtr
			&& !DispChunkContainsX(textPtr, nextDispChunkPtr, lastX)) {
		    nextDispChunkPtr = nextDispChunkPtr->prevPtr;
		}
		if (nextDispChunkPtr != newDispChunkPtr
			&& DispChunkContainsX(textPtr, nextDispChunkPtr, lastX)) {
		    /* move to successor of last chunk */
		    nextDispChunkPtr = nextDispChunkPtr->nextPtr;
		}
	    }



	    if (nextDispChunkPtr != newDispChunkPtr) {
		if (textPtr->curTagInfoPtr != sharedTextPtr->emptyTagInfoPtr) {
		    /*
		     * TkTextTagSetJoinComplementTo() requires this:
		     */
		    if (TkTextTagSetSize(textPtr->curTagInfoPtr) < sharedTextPtr->tagInfoSize) {
			textPtr->curTagInfoPtr = TkTextTagSetResize(
				textPtr->curTagInfoPtr, sharedTextPtr->tagInfoSize);
		    }
		    if (TkTextTagSetSize(leaveTags) < sharedTextPtr->tagInfoSize) {
			leaveTags = TkTextTagSetResize(leaveTags, sharedTextPtr->tagInfoSize);
		    }
		    if (TkTextTagSetSize(enterTags) < sharedTextPtr->tagInfoSize) {
			enterTags = TkTextTagSetResize(enterTags, sharedTextPtr->tagInfoSize);
		    }

		    do {
			const TkTextTagSet *chunkTagInfoPtr;

			if ((chunkTagInfoPtr = TkTextGetTagSetFromChunk(nextDispChunkPtr))) {
			    leaveTags = TkTextTagSetJoinComplementTo(leaveTags,
				    chunkTagInfoPtr, textPtr->curTagInfoPtr);
			    enterTags = TkTextTagSetJoinComplementTo(enterTags,
				    chunkTagInfoPtr, textPtr->curTagInfoPtr);
			}

			nextDispChunkPtr = movedToLeft ?
				nextDispChunkPtr->prevPtr : nextDispChunkPtr->nextPtr;
		    } while (nextDispChunkPtr != newDispChunkPtr);
		}

		/* Delete intermediate enter/leave pairs. */
		leaveTags = TkTextTagSetIntersect(leaveTags, textPtr->curTagInfoPtr);
		enterTags = TkTextTagSetIntersect(enterTags, newTagInfoPtr);
	    }
	} else if (textPtr->lastLineY != TK_TEXT_NEARBY_IS_UNDETERMINED) {
	    const TkTextDispChunk *chunkPtr, *cPtr;
	    const TkTextTagSet *tPtr;
	    TkTextTagSet *commonTags = TkTextTagSetCopy(newTagInfoPtr);

	    /*
	     * The display line has changed, so we have to send leave/enter events
	     * for all the affected tags, otherwise the event handling would depend
	     * on the contingencies of the layout, and this must not happen.
	     *
	     * But do not track a change of the display line if the new display chunk
	     * belongs to the same region as old display chunk.
	     */

	    if (newLineY < textPtr->lastLineY) {
		/*
		 * Mouse pointer has moved to any predecessing display line.
		 */

		for (cPtr = chunkPtr = newDispChunkPtr;
			chunkPtr && textPtr->lastLineY > TkTextGetYPixelFromChunk(textPtr, chunkPtr);
			cPtr = chunkPtr = TkTextGetFirstChunkOfNextDispLine(chunkPtr)) {
		    for ( ; cPtr; cPtr = cPtr->nextPtr) {
			if ((tPtr = TkTextGetTagSetFromChunk(cPtr))) {
			    commonTags = TkTextTagSetIntersectThis(commonTags, tPtr);
			}
		    }
		}
		if (cPtr) {
		    int x = textPtr->lastX;

		    for ( ; cPtr; cPtr = cPtr->nextPtr) {
			if ((tPtr = TkTextGetTagSetFromChunk(cPtr))) {
			    commonTags = TkTextTagSetIntersectThis(commonTags, tPtr);
			}
			if (DispChunkContainsX(textPtr, cPtr, x)) {
			    break;
			}
		    }
		}
	    } else {
		/*
		 * Mouse pointer has moved to any successing display line.
		 */

		for (cPtr = chunkPtr = newDispChunkPtr;
			chunkPtr && textPtr->lastLineY < TkTextGetYPixelFromChunk(textPtr, chunkPtr);
			cPtr = chunkPtr = TkTextGetLastChunkOfPrevDispLine(chunkPtr)) {
		    for ( ; cPtr; cPtr = cPtr->prevPtr) {
			if ((tPtr = TkTextGetTagSetFromChunk(cPtr))) {
			    commonTags = TkTextTagSetIntersectThis(commonTags, tPtr);
			}
		    }
		}
		if (cPtr) {
		    int x = textPtr->lastX;

		    for ( ; cPtr; cPtr = cPtr->prevPtr) {
			if ((tPtr = TkTextGetTagSetFromChunk(cPtr))) {
			    commonTags = TkTextTagSetIntersectThis(commonTags, tPtr);
			}
			if (DispChunkContainsX(textPtr, cPtr, x)) {
			    break;
			}
		    }
		}
	    }


	    TkTextTagSetDecrRefCount(enterTags);
	    TkTextTagSetDecrRefCount(leaveTags);
	    enterTags = TkTextTagSetRemoveFromThis(TkTextTagSetCopy(newTagInfoPtr), commonTags);

	    leaveTags = TkTextTagSetRemoveFromThis(TkTextTagSetCopy(textPtr->curTagInfoPtr), commonTags);



	    TkTextTagSetDecrRefCount(commonTags);
	}
    }





    tagEpoch = sharedTextPtr->tagEpoch;





    if (sharedTextPtr->tagBindingTable && !TkTextTagSetIsEmpty(leaveTags)) {
	/*
	 * Invoke the binding system with a LeaveNotify event for all of the tags
	 * that have gone away.
	 *
	 * Always use a detail of NotifyAncestor. Besides being
	 * consistent, this avoids problems where the binding code will
	 * discard NotifyInferior events.
	 */

	event = textPtr->pickEvent;
	event.type = LeaveNotify;
	event.xcrossing.detail = NotifyAncestor;
	TagBindEvent(textPtr, &event, leaveTags, tagEpoch);
	sentEvents = 1;
    }


    if (!(textPtr->flags & DESTROYED)) {
	int sx, sy; /* translation to current scroll position */

	if (sentEvents) {
	    /*
	     * Reset the "current" mark (be careful to recompute its location, since
	     * it might have changed during an event binding).
	     *
	     * We want to avoid that a cursor movement is constantly splitting and
	     * joining char segments. So we postpone the insertion of the "current"
	     * mark until TextWidgetObjCmd will be executed.
	     */

	    newDispChunkPtr = TkTextPixelIndex(textPtr,
		    textPtr->pickEvent.xcrossing.x, textPtr->pickEvent.xcrossing.y, &index, &nearby);

	    newLineY = nearby ? TK_TEXT_IS_NEARBY : TkTextGetYPixelFromChunk(textPtr, newDispChunkPtr);
	    textPtr->currentMarkIndex = index;
	    TkTextIndexToByteIndex(&textPtr->currentMarkIndex);
	    textPtr->haveToSetCurrentMark = 1;
	    sharedTextPtr->haveToSetCurrentMark = 1;
	}

	if (sharedTextPtr->tagBindingTable && !TkTextTagSetIsEmpty(enterTags)) {
	    /*
	     * Invoke the binding system with a EnterNotify event for all of the tags
	     * that have just appeared.
	     *
	     * Behaviour before ticket #47d4f29159:
	     *   Always use a detail of NotifyAncestor. Besides being
	     *   consistent, this avoids problems where the binding code will
	     *   discard NotifyInferior events.
	     *
	     * Behaviour after ticket #47d4f29159:
	     *   The binding mechanism doesn't discard events with detail field
	     *   NotifyInferior anymore. It would be best to base the detail
	     *   field on the ancestry relationship between the old and new
	     *   tags. For the time being, retain the choice from before
	     *   ticket #47d4f29159, which doesn't harm.
	     */


	    event = textPtr->pickEvent;
	    event.type = EnterNotify;
	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, enterTags, tagEpoch);
	}

	TkTextTagSetDecrRefCount(textPtr->curTagInfoPtr);
	TkTextTagSetIncrRefCount(textPtr->curTagInfoPtr = TkTextTagSetIsEmpty(newTagInfoPtr) ?
		sharedTextPtr->emptyTagInfoPtr : newTagInfoPtr);

	TkTextGetViewOffset(textPtr, &sx, &sy);
	textPtr->lastLineY = newLineY;
	textPtr->lastX = textPtr->pickEvent.xcrossing.x + sx;
	if (newDispChunkPtr) {
	    textPtr->lastChunkID = newDispChunkPtr->uniqID;
	}
    }

    TkTextTagSetDecrRefCount(leaveTags);
    TkTextTagSetDecrRefCount(enterTags);
    TkTextTagSetDecrRefCount(newTagInfoPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TagBindEvent --
 *
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
 *--------------------------------------------------------------
 */

static void
TagBindEvent(
    TkText *textPtr,		/* Text widget to fire bindings in. */
    XEvent *eventPtr,		/* What actually happened. */
    int numTags,		/* Number of relevant tags. */



    TkTextTag **tagArrayPtr)	/* Array of relevant tags. */




{

#   define NUM_BIND_TAGS 10




    const char *nameArray[NUM_BIND_TAGS];



    const char **nameArrPtr;













    int i;














    /*










     * Try to avoid allocation unless there are lots of tags.



     */












    if (numTags > NUM_BIND_TAGS) {











	nameArrPtr = (const char **)ckalloc(numTags * sizeof(const char *));







    } else {




	nameArrPtr = nameArray;







    }




    /*

















     * We use tag names as keys in the hash table. We do this instead of using







     * the actual tagPtr objects because we want one "sel" tag binding for all


     * peer widgets, despite the fact that each has its own tagPtr object.



     */






    for (i = 0; i < numTags; i++) {



	TkTextTag *tagPtr = tagArrayPtr[i];


















































	if (tagPtr != NULL) {
	    nameArrPtr[i] = tagPtr->name;


	} else {

	    /*



	     * Tag has been deleted elsewhere, and therefore nulled out in

	     * this array. Tk_BindEvent is clever enough to cope with NULLs


	     * being thrown at it.

	     */











	    nameArrPtr[i] = NULL;


	}





    }




    Tk_BindEvent(textPtr->sharedTextPtr->bindingTable, eventPtr,


	    textPtr->tkwin, numTags, (ClientData *) nameArrPtr);



    if (numTags > NUM_BIND_TAGS) {

	ckfree(nameArrPtr);
    }



}









































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:

 */







|
>
>
>
|
>
>
>
>
|
>
|
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
|
>
>
>
|
>
>
>
>
>
|
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
<
>
>
|
>
|
>
>
>
|
>
|
>
>
|
>
|
>
>
>
>
|
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
|
>
>
>
>
|
>
>
|
>
>
|
|
>
|
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|

>

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
 *--------------------------------------------------------------
 */

static void
TagBindEvent(
    TkText *textPtr,		/* Text widget to fire bindings in. */
    XEvent *eventPtr,		/* What actually happened. */
    TkTextTagSet *tagInfoPtr,	/* Set of relevant tags. */
    unsigned epoch)		/* Last epoch of tag creation. */
{
    TkTextTag *tagArrayBuf[TK_TEXT_SET_MAX_BIT_SIZE];
    TkTextTag **tagArrPtr = tagArrayBuf;
    const TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    unsigned maxTags = sharedTextPtr->numTags;
    unsigned countTags = 0;
    unsigned i;

    assert(textPtr->sharedTextPtr->tagBindingTable);

    for (i = TkTextTagSetFindFirst(tagInfoPtr);
	    i != TK_TEXT_TAG_SET_NPOS;
	    i = TkTextTagSetFindNext(tagInfoPtr, i)) {
	TkTextTag *tagPtr;

	/*
	 * Take into account that some tags have been gone in the meanwhile.
	 */

	if (i >= maxTags) {
	    break;
	}
	if ((tagPtr = sharedTextPtr->tagLookup[i]) && tagPtr->tagEpoch <= epoch) {
	    if (countTags == sizeof(tagArrayBuf)/sizeof(tagArrayBuf[0])) {
		/* It's quite unexpected that this case happens. */
		unsigned count = TkTextTagSetCount(tagInfoPtr);
		tagArrPtr = (TkTextTag **)ckalloc(count*sizeof(tagArrayBuf[0]));
		memcpy(tagArrPtr, tagArrayBuf, countTags*sizeof(tagArrayBuf[0]));
	    }
	    tagArrPtr[countTags++] = tagPtr;
	}
    }

    if (countTags) {
	TkTextSortTags(countTags, tagArrPtr);
	for (i = 0; i < countTags; ++i) {
	    tagArrPtr[i] = (TkTextTag *) tagArrPtr[i]->name;
	}
	Tk_BindEvent(textPtr->sharedTextPtr->tagBindingTable, eventPtr,
		textPtr->tkwin, countTags, (void **) tagArrPtr);

	if (tagArrPtr != tagArrayBuf) {
	    ckfree(tagArrPtr);
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * EnumerateTags --
 *
 *	Implements the "tag enumerate" command, see documentation.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Memory is allocated for the result, if needed (standard Tcl result
 *	side effects).
 *
 *--------------------------------------------------------------
 */

static TkBitField *
AddBits(
    TkBitField *dst,		/* can be NULL */
    const TkBitField *src)
{
    if (!dst) {
	dst = TkBitResize(NULL, TkBitSize(src));
    }
    TkBitJoin(dst, src);
    return dst;
}

static TkBitField *
AddComplementBits(
    TkBitField *dst,		/* can be NULL */
    const TkBitField *src)
{
    if (!dst) {
	dst = TkBitResize(NULL, TkBitSize(src));
    }
    TkBitComplementTo(dst, src);
    return dst;
}

static TkBitField *
AddSet(
    const TkSharedText *sharedTextPtr,
    TkBitField *dst,		/* can be NULL */
    const TkTextTagSet *src)
{
    TkBitField *cmpl = TkTextTagSetToBits(src, TkBitSize(sharedTextPtr->usedTags));

    dst = AddBits(dst, cmpl);
    TkBitDecrRefCount(cmpl);
    return dst;
}

static TkBitField *
AddComplementSet(
    const TkSharedText *sharedTextPtr,
    TkBitField *dst,		/* can be NULL */
    const TkTextTagSet *src)
{
    TkBitField *cmpl = TkTextTagSetToBits(src, TkBitSize(sharedTextPtr->usedTags));

    dst = AddComplementBits(dst, cmpl);
    TkBitDecrRefCount(cmpl);
    return dst;
}

static int
EnumerateTags(
    Tcl_Interp *interp,
    TkText *textPtr,
    int objc,
    Tcl_Obj *const *objv)
{
    static const char *const optStrings[] = {
	"-all", "-discardselection", "-display", "-elide", "-geometry", "-lineheight",
	"-nodisplay", "-noelide", "-nogeometry", "-nolineheight", "-noselection",
	"-noundo", "-noused", "-selection", "-undo", "-unused", "-used", NULL
    };
    enum opts {
	ENUM_ALL, ENUM_DISCARD_SELECTION, ENUM_DISPLAY, ENUM_ELIDE, ENUM_GEOEMTRY, ENUM_LINEHEIGHT,
	ENUM_NO_DISPLAY, ENUM_NO_ELIDE, ENUM_NO_GEOMETRY, ENUM_NO_LINEHEIGHT, ENUM_NO_SELECTION,
	ENUM_NO_UNDO, ENUM_NO_USED, ENUM_SELECTION, ENUM_UNDO, ENUM_UNUSED, ENUM_USED
    };

    const TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    TkBitField *includeBits = NULL;
    TkBitField *discardBits = NULL;
    int discardSelection = 0;
    TkTextTag **arrayPtr;
    int index, countTags, i;
    unsigned k;

    for (i = 3; i < objc; ++i) {
	const char *option = Tcl_GetString(objv[i]);

	if (*option != '-') {
	    break;
	}

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings, sizeof(char *),
		"tag option", 0, &index) != TCL_OK) {
	    if (includeBits) { TkBitDecrRefCount(includeBits); }
	    if (discardBits) { TkBitDecrRefCount(discardBits); }
	    return TCL_ERROR;
	}

	switch ((enum opts) index) {
	case ENUM_ALL:
	case ENUM_DISCARD_SELECTION:
	    discardSelection = 1;
	    break;
	case ENUM_DISPLAY:
	    includeBits = AddBits(includeBits, sharedTextPtr->affectDisplayTags);
	    break;
	case ENUM_ELIDE:
	    includeBits = AddBits(includeBits, sharedTextPtr->elisionTags);
	    break;
	case ENUM_GEOEMTRY:
	    includeBits = AddBits(includeBits, sharedTextPtr->affectGeometryTags);
	    break;
	case ENUM_LINEHEIGHT:
	    includeBits = AddBits(includeBits, sharedTextPtr->affectLineHeightTags);
	    break;
	case ENUM_NO_DISPLAY:
	    discardBits = AddBits(discardBits, sharedTextPtr->affectDisplayTags);
	    break;
	case ENUM_NO_ELIDE:
	    discardBits = AddBits(discardBits, sharedTextPtr->elisionTags);
	    break;
	case ENUM_NO_GEOMETRY:
	    discardBits = AddBits(discardBits, sharedTextPtr->affectGeometryTags);
	    break;
	case ENUM_NO_LINEHEIGHT:
	    discardBits = AddBits(discardBits, sharedTextPtr->affectLineHeightTags);
	    break;
	case ENUM_NO_SELECTION:
	    discardSelection = 1;
	    break;
	case ENUM_NO_UNDO:
	    discardBits = AddComplementBits(discardBits, sharedTextPtr->dontUndoTags);
	    break;
	case ENUM_NO_USED:
	    discardBits = AddComplementSet(sharedTextPtr, discardBits,
		    TkBTreeRootTagInfo(sharedTextPtr->tree));
	    break;
	case ENUM_SELECTION:
	    includeBits = AddBits(includeBits, sharedTextPtr->selectionTags);
	    break;
	case ENUM_UNDO:
	    includeBits = AddComplementBits(includeBits, sharedTextPtr->dontUndoTags);
	    break;
	case ENUM_UNUSED:
	    includeBits = AddComplementSet(sharedTextPtr, includeBits,
		    TkBTreeRootTagInfo(sharedTextPtr->tree));
	    break;
	case ENUM_USED:
	    includeBits = AddSet(sharedTextPtr, includeBits, TkBTreeRootTagInfo(sharedTextPtr->tree));
	    break;
	}
    }


    if (objc == i + 1) {
	TkTextIndex index1;
	TkTextSegment *segPtr;
	TkTextTagSet *tagInfoPtr;

	if (!TkTextGetIndexFromObj(interp, textPtr, objv[i], &index1)) {
	    return TCL_ERROR;
	}

	segPtr = TkTextIndexGetContentSegment(&index1, NULL);

	if (!includeBits && !discardBits) {
	    TkTextFindTags(interp, textPtr, segPtr, discardSelection);
	    return TCL_OK;
	}

	TkTextTagSetIncrRefCount(tagInfoPtr = segPtr->tagInfoPtr);
	if (includeBits) {
	    tagInfoPtr = TkTextTagSetIntersectBits(tagInfoPtr, includeBits);
	    TkBitDecrRefCount(includeBits);
	}
	includeBits = TkTextTagSetToBits(tagInfoPtr, TkBitSize(sharedTextPtr->usedTags));
	TkTextTagSetDecrRefCount(tagInfoPtr);
    } else if (objc > i) {
	Tcl_WrongNumArgs(interp, 3, objv, "?options? ?index?");
	return TCL_ERROR;
    }

    if (discardSelection) {
	discardBits = AddBits(discardBits, sharedTextPtr->selectionTags);
    }
    if (!includeBits) {
	if (discardBits) {
	    includeBits = TkBitCopy(sharedTextPtr->usedTags, -1);
	} else {
	    TkBitIncrRefCount(includeBits = sharedTextPtr->usedTags);
	}
    }
    if (discardBits) {
	TkBitRemove(includeBits, discardBits);
    }

    arrayPtr = (TkTextTag **)ckalloc(sharedTextPtr->numEnabledTags * sizeof(TkTextTag *));
    countTags = 0;

    for (k = TkBitFindFirst(includeBits); k != TK_BIT_NPOS; k = TkBitFindNext(includeBits, k)) {
	arrayPtr[countTags++] = sharedTextPtr->tagLookup[k];
    }

    AppendTags(interp, countTags, arrayPtr);
    ckfree(arrayPtr);

    TkBitDecrRefCount(includeBits);
    if (discardBits) {
	TkBitDecrRefCount(discardBits);
    }

    return TCL_OK;
}

#ifndef NDEBUG
/*
 *--------------------------------------------------------------
 *
 * TkpTextPrintTagSet --
 *
 *	This function is for debugging only, printing the content of
 *	the given tag set on stdout.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

void
TkpTextPrintTagSet(
    const TkSharedText *sharedTextPtr,
    const TkTextTagSet *tagInfoPtr)
{
    const char *comma = "";
    unsigned i;

    printf("{");
    for (i = TkTextTagSetFindFirst(tagInfoPtr);
	    i != TK_TEXT_TAG_SET_NPOS;
	    i = TkTextTagSetFindNext(tagInfoPtr, i)) {
	printf("%s%s", comma, sharedTextPtr->tagLookup[i]->name);
	comma = ", ";
    }
    printf("}\n");
}
#endif /* !NDEBUG */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */

Added generic/tkTextTagSet.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
/*
 * tkTextTagSet.c --
 *
 *	This module implements a set for tagging information.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkTextTagSet.h"

# include <assert.h>
# include <string.h>

# ifndef MAX
#  define MAX(a,b) (((int) a) < ((int) b) ? b : a)
# endif

/*
 * Don't use expensive checks for speed improvements. But probably these "expensive"
 * checks aren't so much expensive? This needs more testing for a final decision.
 */
#define USE_EXPENSIVE_CHECKS 0


static int IsPowerOf2(unsigned n) { return !(n & (n - 1)); }


static unsigned
NextPowerOf2(
    unsigned n)
{
    --n;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;

#if !(UINT_MAX <= 4294967295u)
    /* unsigned is 64 bit wide, this is unusual, but possible */
    n |= n >> 32;
#endif

    return ++n;
}


static TkTextTagSet *
ConvertToBitField(
    TkTextTagSet *ts,
    unsigned newSize)
{
    TkBitField *bf;
    assert(ts->base.isSetFlag);
    assert(ts->base.refCount > 0);
    bf = TkBitFromSet(&ts->set, newSize);
    TkIntSetDecrRefCount(&ts->set);
    return (TkTextTagSet *) bf;
}


static TkTextTagSet *
ConvertToIntSet(
    TkTextTagSet *ts)
{
    TkIntSet *set;
    assert(!ts->base.isSetFlag);
    assert(ts->base.refCount > 0);
    set = TkIntSetFromBits(&ts->bf);
    TkBitDecrRefCount(&ts->bf);
    return (TkTextTagSet *) set;
}


static TkTextTagSet *
ConvertToEmptySet(
    TkTextTagSet *ts)
{
    if (TkTextTagSetIsEmpty(ts)) {
	return ts;
    }
    if (ts->base.refCount > 1) {
	ts->base.refCount -= 1;
	return (TkTextTagSet *) TkBitResize(NULL, 0);
    }
    if (ts->base.isSetFlag) {
	return (TkTextTagSet *) TkIntSetClear(&ts->set);
    }
    TkBitClear(&ts->bf);
    return ts;
}


static TkTextTagSet *
Convert(
    TkTextTagSet *ts)
{
    if (ts->base.isSetFlag) {
	TkIntSetType size;

	if (TkIntSetIsEmpty(&ts->set)) {
	    return ts;
	}

	size = TkIntSetMax(&ts->set) + 1;

	if (size <= TK_TEXT_SET_MAX_BIT_SIZE) {
	    if (!IsPowerOf2(size)) {
		size = NextPowerOf2(size);
	    }
	    return ConvertToBitField(ts, size);
	}
    } else if (TkBitSize(&ts->bf) > TK_TEXT_SET_MAX_BIT_SIZE) {
	return ConvertToIntSet(ts);
    }
    return ts;
}


static TkBitField *
MakeBitCopy(
    TkTextTagSet *ts)
{
    assert(ts->base.refCount > 1);
    assert(!ts->base.isSetFlag);

    ts->base.refCount -= 1;
    return TkBitCopy(&ts->bf, -1);
}


static TkIntSet *
MakeIntSetCopy(
    TkTextTagSet *ts)
{
    assert(ts->base.refCount > 1);
    assert(ts->base.isSetFlag);

    ts->base.refCount -= 1;
    return TkIntSetCopy(&ts->set);
}


static TkTextTagSet *
MakeBitCopyIfNeeded(
    TkTextTagSet *ts)
{
    assert(ts->base.refCount > 0);
    assert(!ts->base.isSetFlag);

    return (TkTextTagSet *) (ts->base.refCount == 1 ? &ts->bf : MakeBitCopy(ts));
}


static TkIntSet *
MakeIntSetCopyIfNeeded(
    TkTextTagSet *ts)
{
    assert(ts->base.refCount > 0);
    assert(ts->base.isSetFlag);

    return ts->base.refCount == 1 ? &ts->set : MakeIntSetCopy(ts);
}


static TkIntSet *
ToIntSet(
    const TkTextTagSet *set)
{
    if (set->base.isSetFlag) {
	return (TkIntSet *) &set->set;
    }
    return (TkIntSet *) TkIntSetFromBits(&((TkTextTagSet *) set)->bf);
}


TkBitField *
TkTextTagSetToBits(
    const TkTextTagSet *src,
    int size)
{
    assert(src);

    if (src->base.isSetFlag) {
	return TkBitFromSet(&src->set, size < 0 ? (int) TkIntSetMax(&src->set) + 1 : size);
    }

    if (size < 0 || (int) TkBitSize(&src->bf) == size) {
	((TkTextTagSet *) src)->base.refCount += 1;
	return (TkBitField *) &src->bf;
    }

    return TkBitCopy(&src->bf, size);
}


void
TkTextTagSetDestroy(
    TkTextTagSet **tsPtr)
{
    assert(tsPtr);

    if (*tsPtr) {
	if ((*tsPtr)->base.isSetFlag) {
	    TkIntSetDestroy((TkIntSet **) tsPtr);
	} else {
	    TkBitDestroy((TkBitField **) tsPtr);
	}
    }
}


TkTextTagSet *
TkTextTagSetResize(
    TkTextTagSet *ts,
    unsigned newSize)
{
    assert(!ts || TkTextTagSetRefCount(ts) > 0);

    if (!ts) {
	ts = TkTextTagSetNew(newSize);
	ts->base.refCount = 1;
	return ts;
    }
    if (ts->base.isSetFlag) {
	if (newSize <= TK_TEXT_SET_MAX_BIT_SIZE) {
	    ts = ConvertToBitField(ts, newSize);
	}
    } else {
	if (newSize <= TK_TEXT_SET_MAX_BIT_SIZE) {
	    ts = (TkTextTagSet *) TkBitResize(&ts->bf, newSize);
	} else {
	    ts = ConvertToIntSet(ts);
	}
    }

    return ts;
}


int
TkTextTagSetIsEqual_(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(ts1);
    assert(ts2);
    assert(ts1->base.isSetFlag || ts2->base.isSetFlag);

    if (ts1->base.isSetFlag) {
	if (ts2->base.isSetFlag) {
	    return TkIntSetIsEqual(&ts1->set, &ts2->set);
	}
	return TkIntSetIsEqualBits(&ts1->set, &ts2->bf);
    }
    return TkIntSetIsEqualBits(&ts2->set, &ts1->bf);
}


int
TkTextTagSetContains_(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(ts1);
    assert(ts2);
    assert(ts1->base.isSetFlag || ts2->base.isSetFlag);

    if (ts1->base.isSetFlag) {
	if (ts2->base.isSetFlag) {
	    return TkIntSetContains(&ts1->set, &ts2->set);
	}
	return TkIntSetContainsBits(&ts1->set, &ts2->bf);
    }
    return TkIntSetIsContainedBits(&ts2->set, &ts1->bf);
}


int
TkTextTagSetDisjunctive_(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(ts1);
    assert(ts2);
    assert(ts1->base.isSetFlag || ts2->base.isSetFlag);

    if (ts1->base.isSetFlag) {
	if (ts2->base.isSetFlag) {
	    return TkIntSetDisjunctive(&ts1->set, &ts2->set);
	}
	return TkIntSetDisjunctiveBits(&ts1->set, &ts2->bf);
    }
    return TkIntSetDisjunctiveBits(&ts2->set, &ts1->bf);
}


int
TkTextTagSetIntersectionIsEqual_(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2,
    const TkBitField *bf)
{
    assert(ts1);
    assert(ts2);
    assert(bf);
    assert(ts1->base.isSetFlag || ts2->base.isSetFlag);

    if (ts1->base.isSetFlag) {
	if (ts2->base.isSetFlag) {
	    return TkIntSetIntersectionIsEqual(&ts1->set, &ts2->set, bf);
	}
	return TkIntSetIntersectionIsEqualBits(&ts1->set, &ts2->bf, bf);
    }
    return TkIntSetIntersectionIsEqualBits(&ts2->set, &ts1->bf, bf);
}


TkTextTagSet *
TkTextTagSetJoin(
    TkTextTagSet *dst,
    const TkTextTagSet *src)
{
    assert(src);
    assert(dst);

    if (src == dst || TkTextTagSetIsEmpty(src)) {
	return dst;
    }

    if (TkTextTagSetIsEmpty(dst)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) src); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return Convert((TkTextTagSet *) src);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(src, dst) || TkTextTagSetContains(dst, src)) {
	return dst;
    }
#endif

    if (src->base.isSetFlag | dst->base.isSetFlag) {
	if (src->base.isSetFlag) {
	    if (dst->base.isSetFlag) {
		return (TkTextTagSet *) TkIntSetJoin(&dst->set, &src->set);
	    }
	    return (TkTextTagSet *) TkIntSetJoin(&ConvertToIntSet(dst)->set, &src->set);
	}
	return (TkTextTagSet *) TkIntSetJoinBits(&dst->set, &src->bf);
    }

    if (TkBitSize(&dst->bf) < TkBitSize(&src->bf)) {
	TkTextTagSet *set = dst;
	dst = (TkTextTagSet *) TkBitCopy(&src->bf, -1);
	TkBitJoin(&dst->bf, &set->bf);
	TkBitDecrRefCount(&set->bf);
	return dst;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitJoin(&dst->bf, &src->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetJoin2(
    TkTextTagSet *dst,
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(dst);
    assert(ts1);
    assert(ts2);

    if (ts2 == dst || TkTextTagSetIsEmpty(ts2)) {
	return TkTextTagSetJoin(dst, ts1);
    }
    if (ts1 == dst || ts1 == ts2 || TkTextTagSetIsEmpty(ts1)) {
	return TkTextTagSetJoin(dst, ts2);
    }
    if (TkTextTagSetIsEmpty(dst)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) ts1); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return TkTextTagSetJoin((TkTextTagSet *) ts1, ts2);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(ts1, ts2) || TkTextTagSetContains(dst, ts2)) {
	return TkTextTagSetJoin(dst, ts1);
    }
    if (TkTextTagSetContains(ts2, ts1) || TkTextTagSetContains(dst, ts1)) {
	return TkTextTagSetJoin(dst, ts2);
    }
    if (TkTextTagSetContains(ts1, dst)) {
	TkTextTagSetDecrRefCount(dst);
	return TkTextTagSetJoin(TkTextTagSetCopy(ts1), ts2);
    }
    if (TkTextTagSetContains(ts2, dst)) {
	TkTextTagSetDecrRefCount(dst);
	return TkTextTagSetJoin(TkTextTagSetCopy(ts2), ts1);
    }
#endif

    if (ts1->base.isSetFlag | ts2->base.isSetFlag | dst->base.isSetFlag) {
	return TkTextTagSetJoin(TkTextTagSetJoin(dst, ts1), ts2);
    }

    if (TkBitSize(&ts1->bf) < TkBitSize(&ts2->bf)) {
	const TkTextTagSet *tmp = ts1;
	ts1 = ts2;
	ts2 = tmp;
    }
    if (TkBitSize(&dst->bf) < TkBitSize(&ts1->bf)) {
	TkTextTagSet *set = dst;
	dst = (TkTextTagSet *) TkBitCopy(&ts1->bf, -1);
	TkBitJoin2(&dst->bf, &set->bf, &ts2->bf);
	TkBitDecrRefCount(&set->bf);
	return dst;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitJoin2(&dst->bf, &ts1->bf, &ts2->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetIntersect(
    TkTextTagSet *dst,
    const TkTextTagSet *src)
{
    assert(src);
    assert(dst);

    if (src == dst || TkTextTagSetIsEmpty(dst)) {
	return dst;
    }
    if (TkTextTagSetIsEmpty(src)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) src); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return (TkTextTagSet *) src;
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(dst, src)) {
	return dst;
    }
    if (TkTextTagSetContains(src, dst)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) src); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return (TkTextTagSet *) src;
    }
#endif

    if (src->base.isSetFlag | dst->base.isSetFlag) {
	TkBitField *bf, *tmp;

	assert(dst->base.refCount > 0);

	if (src->base.isSetFlag) {
	    if (dst->base.isSetFlag) {
		return (TkTextTagSet *) TkIntSetIntersect(&dst->set, &src->set);
	    }

	    tmp = TkBitFromSet(&src->set, TkBitSize(&dst->bf));
	    dst = MakeBitCopyIfNeeded(dst);
	    TkBitIntersect(&dst->bf, tmp);
	    TkBitDestroy(&tmp);
	    return dst;
	}

	bf = TkBitCopy(&src->bf, -1);
	tmp = TkBitFromSet(&dst->set, TkBitSize(&src->bf));
	TkBitIntersect(bf, tmp);
	TkBitDestroy(&tmp);
	TkIntSetDecrRefCount(&dst->set);
	return (TkTextTagSet *) bf;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitIntersect(&dst->bf, &src->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetIntersectThis(
    TkTextTagSet *dst,
    const TkTextTagSet *src)
{
    assert(src);
    assert(dst);

    if (src == dst || TkTextTagSetIsEmpty(dst)) {
	return dst;
    }
    if (src->base.isSetFlag | dst->base.isSetFlag) {
	TkBitField *bf, *tmp;

	assert(dst->base.refCount > 0);

	if (src->base.isSetFlag) {
	    if (dst->base.isSetFlag) {
		return (TkTextTagSet *) TkIntSetIntersect(&dst->set, &src->set);
	    }

	    tmp = TkBitFromSet(&src->set, TkBitSize(&dst->bf));
	    TkBitIntersect(&dst->bf, tmp);
	    TkBitDestroy(&tmp);
	    return dst;
	}

	bf = TkBitCopy(&src->bf, -1);
	tmp = TkBitFromSet(&dst->set, TkBitSize(&src->bf));
	TkBitIntersect(bf, tmp);
	TkBitDestroy(&tmp);
	TkIntSetDecrRefCount(&dst->set);
	return (TkTextTagSet *) bf;
    }

    TkBitIntersect(&dst->bf, &src->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetIntersectBits(
    TkTextTagSet *dst,
    const TkBitField *src)
{
    assert(src);
    assert(dst);

    if ((const TkTextTagSet *) src == dst || TkTextTagSetIsEmpty(dst)) {
	return dst;
    }
    if (TkBitNone(src)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) src); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return Convert((TkTextTagSet *) src);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContainsBits(dst, src)) {
	return dst;
    }
    if (TkTextTagIsContainedInBits(dst, src)) {
	TkBitIncrRefCount((TkBitField *) src); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return (TkTextTagSet *) src;
    }
#endif

    if (dst->base.isSetFlag) {
	return Convert((TkTextTagSet *) TkIntSetIntersectBits(&dst->set, src));
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitIntersect(&dst->bf, src);
    return dst;
}


TkTextTagSet *
TkTextTagSetRemove(
    TkTextTagSet *dst,
    const TkTextTagSet *src)
{
    assert(src);
    assert(dst);

    if (TkTextTagSetIsEmpty(src) || TkTextTagSetIsEmpty(dst)) {
	return dst;
    }
    if (src == dst) {
	return ConvertToEmptySet(dst);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(src, dst)) {
	return ConvertToEmptySet(dst);
    }
#endif

    if (src->base.isSetFlag | dst->base.isSetFlag) {
	TkBitField *bf;

	assert(dst->base.refCount > 0);

	if (dst->base.isSetFlag) {
	    if (src->base.isSetFlag) {
		return Convert((TkTextTagSet *) TkIntSetRemove(&dst->set, &src->set));
	    }
	    return Convert((TkTextTagSet *) TkIntSetRemoveBits(&dst->set, &src->bf));
	}

	bf = TkBitFromSet(&src->set, TkBitSize(&dst->bf));
	dst = MakeBitCopyIfNeeded(dst);
	TkBitRemove(&dst->bf, bf);
	TkBitDestroy(&bf);
	return dst;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitRemove(&dst->bf, &src->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetRemoveFromThis(
    TkTextTagSet *dst,
    const TkTextTagSet *src)
{
    assert(src);
    assert(dst);

    if (TkTextTagSetIsEmpty(src) || TkTextTagSetIsEmpty(dst)) {
	return dst;
    }
    if (src == dst) {
	if (dst->base.isSetFlag) {
	    return (TkTextTagSet *) TkIntSetClear(&dst->set);
	}
	TkBitClear(&dst->bf);
	return dst;
    }

    if (src->base.isSetFlag | dst->base.isSetFlag) {
	TkBitField *bf;

	assert(dst->base.refCount > 0);

	if (dst->base.isSetFlag) {
	    if (src->base.isSetFlag) {
		return Convert((TkTextTagSet *) TkIntSetRemove(&dst->set, &src->set));
	    }
	    return Convert((TkTextTagSet *) TkIntSetRemoveBits(&dst->set, &src->bf));
	}

	bf = TkBitFromSet(&src->set, TkBitSize(&dst->bf));
	TkBitRemove(&dst->bf, bf);
	TkBitDestroy(&bf);
	return dst;
    }

    TkBitRemove(&dst->bf, &src->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetRemoveBits(
    TkTextTagSet *dst,
    const TkBitField *src)
{
    assert(src);
    assert(dst);

    if (TkBitNone(src) || TkTextTagSetIsEmpty(dst)) {
	return dst;
    }
    if ((const TkTextTagSet *) src == dst) {
	return ConvertToEmptySet(dst);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetIsContainedBits(dst, src)) {
	return ConvertToEmptySet(dst);
    }
#endif

    if (dst->base.isSetFlag) {
	return Convert((TkTextTagSet *) TkIntSetRemoveBits(&dst->set, src));
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitRemove(&dst->bf, src);
    return dst;
}


TkTextTagSet *
TkTextTagSetComplementTo(
    TkTextTagSet *dst,
    const TkTextTagSet *src)
{
    assert(src);
    assert(dst);

    if (src == dst) {
	return ConvertToEmptySet(dst);
    }
    if (TkTextTagSetIsEmpty(src) || TkTextTagSetIsEmpty(dst)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) src); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return (TkTextTagSet *) src;
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(dst, src)) {
	return ConvertToEmptySet(dst);
    }
#endif

    if (src->base.isSetFlag | dst->base.isSetFlag) {
	TkIntSet *set;

	if (dst->base.isSetFlag) {
	    if (src->base.isSetFlag) {
		return Convert((TkTextTagSet *) TkIntSetComplementTo(&dst->set, &src->set));
	    }
	    return Convert((TkTextTagSet *) TkIntSetComplementToBits(&dst->set, &src->bf));
	}

	TkIntSetIncrRefCount((TkIntSet *) &src->set);
	set = TkIntSetRemoveBits((TkIntSet *) &src->set, &dst->bf);
	TkBitDecrRefCount(&dst->bf);
	return Convert((TkTextTagSet *) set);
    }

    if (dst->base.refCount > 1 || TkBitSize(&dst->bf) < TkBitSize(&src->bf)) {
	TkBitField *bf;

	bf = TkBitCopy(&src->bf, -1);
	TkBitRemove(bf, &dst->bf);
	TkBitDecrRefCount(&dst->bf);
	return (TkTextTagSet *) bf;
    }
    TkBitComplementTo(&dst->bf, &src->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetJoinComplementTo(
    TkTextTagSet *dst,
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(dst);
    assert(ts1);
    assert(ts2);

    if (dst == ts2 || TkTextTagSetIsEmpty(ts2)) {
	return dst;
    }
    if (TkTextTagSetIsEmpty(ts1)) {
	return TkTextTagSetJoin(dst, ts2);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(dst, ts2) || TkTextTagSetContains(ts1, ts2)) {
	return dst;
    }
    if (TkTextTagSetContains(dst, ts1)) {
	return TkTextTagSetJoin(dst, ts2);
    }
    if (TkTextTagSetContains(ts2, dst)) {
	TkTextTagSetDecrRefCount(dst);
	return TkTextTagSetRemove(TkTextTagSetCopy(ts2), ts1);
    }
#endif

    if (dst->base.isSetFlag | ts1->base.isSetFlag | ts2->base.isSetFlag) {
	TkTextTagSet *tmp;

	if (!(dst->base.isSetFlag | ts1->base.isSetFlag)) {
	    TkBitField *bf2 = TkBitFromSet(&ts2->set, TkBitSize(&ts1->bf));

	    dst = MakeBitCopyIfNeeded(dst);
	    TkBitJoinComplementTo(&dst->bf, &ts1->bf, bf2);
	    TkBitDestroy(&bf2);
	    return dst;
	}

	tmp = TkTextTagSetRemove(TkTextTagSetCopy(ts2), ts1);
	dst = TkTextTagSetJoin(dst, tmp);
	TkTextTagSetDecrRefCount(tmp);
	return dst;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitJoinComplementTo(&dst->bf, &ts1->bf, &ts2->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetJoinNonIntersection(
    TkTextTagSet *dst,
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(dst);
    assert(ts1);
    assert(ts2);

    if (ts1 == ts2) {
	return dst;
    }
    if (TkTextTagSetIsEmpty(ts1) && TkTextTagSetIsEmpty(ts2)) {
	return dst;
    }
    if (dst == ts1 || TkTextTagSetIsEmpty(ts1)) {
	return TkTextTagSetJoin(dst, ts2);
    }
    if (dst == ts2 || TkTextTagSetIsEmpty(ts2)) {
	return TkTextTagSetJoin(dst, ts1);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetIsEqual(ts1, ts2)) {
	return dst;
    }
    if (TkTextTagSetContains(dst, ts1)) {
	return TkTextTagSetJoin(dst, ts2);
    }
    if (TkTextTagSetContains(dst, ts2)) {
	return TkTextTagSetJoin(dst, ts1);
    }
#endif

    if (dst->base.isSetFlag | ts1->base.isSetFlag | ts2->base.isSetFlag) {
	TkIntSet *set1, *set2;

	dst = dst->base.isSetFlag ? (TkTextTagSet *) MakeIntSetCopyIfNeeded(dst) : ConvertToIntSet(dst);
	set1 = ToIntSet(ts1);
	set2 = ToIntSet(ts2);
	dst = (TkTextTagSet *) TkIntSetJoinNonIntersection(&dst->set, set1, set2);
	if (&ts1->set != set1) { TkIntSetDestroy(&set1); }
	if (&ts2->set != set2) { TkIntSetDestroy(&set2); }
	return Convert(dst);
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitJoinNonIntersection(&dst->bf, &ts1->bf, &ts2->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetJoin2ComplementToIntersection(
    TkTextTagSet *dst,
    const TkTextTagSet *add,
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(dst);
    assert(add);
    assert(ts1);
    assert(ts2);

    if (ts1 == ts2) {
	return TkTextTagSetJoin(dst, add);
    }
    if (TkTextTagSetIsEmpty(ts1)) {
	return TkTextTagSetJoin2(dst, add, ts2);
    }
    if (TkTextTagSetIsEmpty(ts2)) {
	return TkTextTagSetJoin2(dst, add, ts1);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetIsEqual(ts1, ts2)) {
	return TkTextTagSetJoin(dst, add);
    }
    if (TkTextTagSetContains(dst, ts1) && TkTextTagSetContains(dst, ts2)) {
	return TkTextTagSetJoin(dst, add);
    }
#endif

    if (dst->base.isSetFlag | add->base.isSetFlag | ts1->base.isSetFlag | ts2->base.isSetFlag) {
	TkIntSet *set1, *set2, *set3;

	dst = dst->base.isSetFlag ? (TkTextTagSet *) MakeIntSetCopyIfNeeded(dst) : ConvertToIntSet(dst);
	set1 = ToIntSet(add);
	set2 = ToIntSet(ts1);
	set3 = ToIntSet(ts2);
	dst = (TkTextTagSet *) TkIntSetJoin2ComplementToIntersection(&dst->set, set1, set2, set3);
	if (&add->set != set1) { TkIntSetDestroy(&set1); }
	if (&ts1->set != set2) { TkIntSetDestroy(&set2); }
	if (&ts2->set != set3) { TkIntSetDestroy(&set3); }
	return dst;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitJoin2ComplementToIntersection(&dst->bf, &add->bf, &ts1->bf, &ts2->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetJoinOfDifferences(
    TkTextTagSet *dst,
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(dst);
    assert(ts1);
    assert(ts2);

    if (ts1 == ts2) {
	return TkTextTagSetRemove(dst, ts1);
    }
    if (dst == ts1) {
	TkTextTagSetDecrRefCount(dst);
	TkTextTagSetIncrRefCount((TkTextTagSet *) ts1); /* mutable due to concept */
	return TkTextTagSetRemove((TkTextTagSet *) ts1, ts2);
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetIsEqual(ts1, ts2)) {
	return TkTextTagSetRemove(dst, ts1);
    }
    if (TkTextTagSetContains(ts1, dst)) {
	TkTextTagSetDecrRefCount(dst);
	TkTextTagSetIncrRefCount(ts1);
	return TkTextTagSetRemove(ts1, ts2);
    }
#endif

    if (dst->base.isSetFlag | ts1->base.isSetFlag | ts2->base.isSetFlag) {
	TkIntSet *set1, *set2;

	dst = dst->base.isSetFlag ? (TkTextTagSet *) MakeIntSetCopyIfNeeded(dst) : ConvertToIntSet(dst);
	set1 = ToIntSet(ts1);
	set2 = ToIntSet(ts2);
	dst = (TkTextTagSet *) TkIntSetJoinOfDifferences(&dst->set, set1, set2);
	if (&ts1->set != set1) { TkIntSetDestroy(&set1); }
	if (&ts2->set != set2) { TkIntSetDestroy(&set2); }
	return Convert(dst);
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitJoinOfDifferences(&dst->bf, &ts1->bf, &ts2->bf);
    return dst;
}


TkTextTagSet *
TkTextTagSetAdd(
    TkTextTagSet *dst,
    unsigned n)
{
    assert(dst);

    if (dst->base.isSetFlag) {
	return (TkTextTagSet *) TkIntSetAdd(MakeIntSetCopyIfNeeded(dst), n);
    }
    dst = MakeBitCopyIfNeeded(dst);
    TkBitSet(&dst->bf, n);
    return dst;
}


TkTextTagSet *
TkTextTagSetErase(
    TkTextTagSet *dst,
    unsigned n)
{
    assert(dst);

    if (dst->base.isSetFlag) {
	return (TkTextTagSet *) TkIntSetErase(MakeIntSetCopyIfNeeded(dst), n);
    }
    dst = MakeBitCopyIfNeeded(dst);
    TkBitUnset(&dst->bf, n);
    return dst;
}


TkTextTagSet *
TkTextTagSetTestAndSet(
    TkTextTagSet *dst,
    unsigned n)
{
    assert(dst);

    if (dst->base.isSetFlag) {
	if (dst->base.refCount <= 1) {
	    return (TkTextTagSet *) TkIntSetTestAndSet(&dst->set, n);
	}
	if (TkIntSetTest(&dst->set, n)) {
	    return NULL;
	}
	return (TkTextTagSet *) TkIntSetAdd(MakeIntSetCopy(dst), n);
    }
    if (dst->base.refCount <= 1) {
	return TkBitTestAndSet(&dst->bf, n) ? dst : NULL;
    }
    if (TkBitTest(&dst->bf, n)) {
	return NULL;
    }
    dst = (TkTextTagSet *) MakeBitCopy(dst);
    TkBitSet(&dst->bf, n);
    return dst;
}


TkTextTagSet *
TkTextTagSetTestAndUnset(
    TkTextTagSet *dst,
    unsigned n)
{
    assert(dst);

    if (dst->base.isSetFlag) {
	if (dst->base.refCount <= 1) {
	    return (TkTextTagSet *) TkIntSetTestAndUnset(&dst->set, n);
	}
	if (!TkIntSetTest(&dst->set, n)) {
	    return NULL;
	}
	return (TkTextTagSet *) TkIntSetErase(MakeIntSetCopy(dst), n);
    }
    if (dst->base.refCount <= 1) {
	return TkBitTestAndUnset(&dst->bf, n) ? dst : NULL;
    }
    if (!TkBitTest(&dst->bf, n)) {
	return NULL;
    }
    dst = (TkTextTagSet *) MakeBitCopy(dst);
    TkBitUnset(&dst->bf, n);
    return dst;
}


TkTextTagSet *
TkTextTagSetClear(
    TkTextTagSet *dst)
{
    assert(dst);

    if (dst->base.isSetFlag) {
	TkIntSetDecrRefCount(&dst->set);
	return (TkTextTagSet *) TkBitResize(NULL, 0);
    }
    return ConvertToEmptySet(dst);
}


unsigned
TkTextTagSetFindFirstInIntersection(
    const TkTextTagSet *ts,
    const TkBitField *bf)
{
    unsigned size, i;

    assert(ts);
    assert(bf);

    if (!ts->base.isSetFlag) {
	return TkBitFindFirstInIntersection(&ts->bf, bf);
    }

    if (!TkBitNone(bf)) {
	size = TkIntSetSize(&ts->set);

	for (i = 0; i < size; ++i) {
	    TkIntSetType value = TkIntSetAccess(&ts->set, i);

	    if (TkBitTest(bf, value)) {
		return value;
	    }
	}
    }

    return TK_TEXT_TAG_SET_NPOS;
}

#ifndef NDEBUG

void
TkTextTagSetPrint(
    const TkTextTagSet *set)
{
    if (!set) {
	printf("<null>\n");
    } else if (TkTextTagSetIsEmpty(set)) {
	printf("<empty>\n");
    } else if (set->base.isSetFlag) {
	TkIntSetPrint(&set->set);
    } else {
	TkBitPrint(&set->bf);
    }
}

#endif /* NDEBUG */

#ifdef TK_UNUSED_TAGSET_FUNCTIONS

/*
 * These functions are not needed anymore, but shouldn't be removed, because sometimes
 * any of these functions might be useful.
 */

static unsigned
MaxSize3(
    const TkTextTagSet *ts1, const TkTextTagSet *ts2, const TkTextTagSet *ts3)
{
    return TkBitAdjustSize(MAX(TkTextTagSetRangeSize(ts1),
	    MAX(TkTextTagSetRangeSize(ts2), TkTextTagSetRangeSize(ts3))));
}


static unsigned
MaxSize4(
    const TkTextTagSet *ts1, const TkTextTagSet *ts2,
    const TkTextTagSet *ts3, const TkTextTagSet *ts4)
{
    return TkBitAdjustSize(MAX(TkTextTagSetRangeSize(ts1), MAX(TkTextTagSetRangeSize(ts2),
	    MAX(TkTextTagSetRangeSize(ts3), TkTextTagSetRangeSize(ts4)))));
}


static TkBitField *
GetBitField(
    const TkTextTagSet *ts,
    int size)
{
    assert(size == -1 || size >= TkTextTagSetRangeSize(ts));
    assert(size == -1 || size == TkBitAdjustSize(size));

    if (ts->base.isSetFlag) {
	return TkBitFromSet(&ts->set, size);
    }

    if (size >= 0 && TkBitSize(&ts->bf) != size) {
	return TkBitCopy(&ts->bf, size);
    }

    /* mutable due to concept */
    TkBitIncrRefCount((TkBitField *) &ts->bf);
    return (TkBitField *) &ts->bf;
}


TkTextTagSet *
TkTextTagSetInnerJoinDifference(
    TkTextTagSet *dst,
    const TkTextTagSet *add,
    const TkTextTagSet *sub)
{
    assert(dst);
    assert(add);
    assert(sub);

    /* dst := (dst & add) + (add - sub) */

    if (add == dst) {
	return dst;
    }
    if (TkTextTagSetIsEmpty(add)) {
	return TkTextTagSetClear(dst);
    }
    if (TkTextTagSetIsEqual(add, dst)) {
	return dst;
    }

#if USE_EXPENSIVE_CHECKS
    if (TkTextTagSetContains(dst, add)) {
	return dst;
    }
    if (TkTextTagSetContains(add, dst) || TkTextTagSetContains(dst, sub)) {
	TkTextTagSetIncrRefCount((TkTextTagSet *) add); /* mutable by definition */
	TkTextTagSetDecrRefCount(dst);
	return (TkTextTagSet *) add;
    }
    if (TkTextTagSetContains(sub, add) || TkTextTagSetContains(add, sub)) {
	return TkTextTagSetIntersect(dst, add);
    }
#endif

    if (dst->base.isSetFlag | add->base.isSetFlag | sub->base.isSetFlag) {
	TkIntSet *set1, *set2, *res;

	res = dst->base.isSetFlag ? TkIntSetCopy(&dst->set) : ConvertToIntSet(dst);
	set1 = ToIntSet(add);
	set2 = ToIntSet(sub);
	res = TkIntSetInnerJoinDifference(res, set1, set2);
	if (&add->set != set1) { TkIntSetDestroy(&set1); }
	if (&sub->set != set2) { TkIntSetDestroy(&set2); }
	return (TkTextTagSet *) res;
    }

    dst = MakeBitCopyIfNeeded(dst);
    TkBitInnerJoinDifference(&dst->bf, &add->bf, &sub->bf);
    return dst;
}


int
TkTextTagSetInnerJoinDifferenceIsEmpty(
    const TkTextTagSet *ts,
    const TkTextTagSet *add,
    const TkTextTagSet *sub)
{
    TkBitField *bf, *bfAdd, *bfSub;
    int isEmpty;
    unsigned n, size;

    assert(ts);
    assert(add);
    assert(sub);

    if (ts == add) {
	return TkTextTagSetIsEmpty(ts);
    }
    if ((n = ts->base.isSetFlag + add->base.isSetFlag + sub->base.isSetFlag) == 0) {
	return TkBitInnerJoinDifferenceIsEmpty(&ts->bf, &add->bf, &sub->bf);
    }
    if (n == 3) {
	return TkIntSetInnerJoinDifferenceIsEmpty(&ts->set, &add->set, &sub->set);
    }
    if (TkTextTagSetIsEmpty(add)) {
	return true;
    }
    if (TkTextTagSetIsEqual(ts, add)) {
	return TkTextTagSetIsEmpty(add);
    }

    size = MaxSize3(ts, add, sub);
    bf = GetBitField(ts, size);
    bfAdd = GetBitField(add, size);
    bfSub = GetBitField(sub, size);
    isEmpty = TkBitInnerJoinDifferenceIsEmpty(bf, bfAdd, bfSub);
    TkBitDecrRefCount(bf);
    TkBitDecrRefCount(bfAdd);
    TkBitDecrRefCount(bfSub);

    return isEmpty;
}


int
TkTextTagSetIsEqualToDifference(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2,
    const TkTextTagSet *sub2)
{
    TkBitField *bf1, *bf2, *bfSub;
    int isEqual;
    unsigned n, size;

    assert(ts1);
    assert(ts2);
    assert(sub2);

    if ((n = ts1->base.isSetFlag + ts2->base.isSetFlag + sub2->base.isSetFlag) == 0) {
	return TkBitIsEqualToDifference(&ts1->bf, &ts2->bf, &sub2->bf);
    }
    if (n == 3) {
	return TkIntSetIsEqualToDifference(&ts1->set, &ts2->set, &sub2->set);
    }
    if (TkTextTagSetIsEmpty(ts2)) {
	return TkTextTagSetIsEmpty(ts1);
    }
    if (TkTextTagSetIsEmpty(ts1)) {
	return TkTextTagSetContains(sub2, ts2);
    }

    size = MaxSize3(ts1, ts2, sub2);
    bf1 = GetBitField(ts1, size);
    bf2 = GetBitField(ts2, size);
    bfSub = GetBitField(sub2, size);
    isEqual = TkBitIsEqualToDifference(bf1, bf2, bfSub);
    TkBitDecrRefCount(bf1);
    TkBitDecrRefCount(bf2);
    TkBitDecrRefCount(bfSub);

    return isEqual;
}


int
TkTextTagSetIsEqualToInnerJoin(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2,
    const TkTextTagSet *add2)
{
    TkBitField *bf1, *bf2, *bfAdd;
    int isEqual;
    unsigned n, size;

    assert(ts1);
    assert(ts2);
    assert(add2);

    if (ts1 == ts2) {
	return true;
    }
    if ((n = ts1->base.isSetFlag + ts2->base.isSetFlag + add2->base.isSetFlag) == 0) {
	return TkBitIsEqualToInnerJoin(&ts1->bf, &ts2->bf, &add2->bf);
    }
    if (n == 3) {
	return TkIntSetIsEqualToInnerJoin(&ts1->set, &ts2->set, &add2->set);
    }
    if (TkTextTagSetIsEqual(ts2, add2)) {
	return TkTextTagSetIsEqual(ts1, ts2);
    }
    if (TkTextTagSetIsEmpty(ts2)) {
	return TkTextTagSetIsEmpty(ts1);
    }
    if (TkTextTagSetIsEqual(ts1, ts2)) {
	return true;
    }

    size = MaxSize3(ts1, ts2, add2);
    bf1 = GetBitField(ts1, size);
    bf2 = GetBitField(ts2, size);
    bfAdd = GetBitField(add2, size);
    isEqual = TkBitIsEqualToInnerJoin(bf1, bf2, bfAdd);
    TkBitDecrRefCount(bf1);
    TkBitDecrRefCount(bf2);
    TkBitDecrRefCount(bfAdd);

    return isEqual;
}


int
TkTextTagSetIsEqualToInnerJoinDifference(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2,
    const TkTextTagSet *add2,
    const TkTextTagSet *sub2)
{
    TkBitField *bf1, *bf2, *bfAdd, *bfSub;
    int isEqual;
    unsigned n, size;

    assert(ts1);
    assert(ts2);
    assert(add2);
    assert(sub2);

    n = ts1->base.isSetFlag + ts2->base.isSetFlag + add2->base.isSetFlag + sub2->base.isSetFlag;

    if (n == 0) {
	return TkBitIsEqualToInnerJoinDifference(&ts1->bf, &ts2->bf, &add2->bf, &sub2->bf);
    }
    if (n == 4) {
	return TkIntSetIsEqualToInnerJoinDifference(&ts1->set, &ts2->set, &add2->set, &sub2->set);
    }
    if (TkTextTagSetIsEmpty(add2)) {
	return TkTextTagSetIsEmpty(ts1);
    }
    if (TkTextTagSetIsEmpty(sub2)) {
	return TkTextTagSetIsEqualToInnerJoin(ts1, add2, ts2);
    }

    size = MaxSize4(ts1, ts2, add2, sub2);
    bf1 = GetBitField(ts1, size);
    bf2 = GetBitField(ts2, size);
    bfAdd = GetBitField(add2, size);
    bfSub = GetBitField(sub2, size);
    isEqual = TkBitIsEqualToInnerJoinDifference(bf1, bf2, bfAdd, bfSub);
    TkBitDecrRefCount(bf1);
    TkBitDecrRefCount(bf2);
    TkBitDecrRefCount(bfAdd);
    TkBitDecrRefCount(bfSub);

    return isEqual;
}


int
TkTextTagSetInnerJoinDifferenceIsEqual(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2,
    const TkTextTagSet *add,
    const TkTextTagSet *sub)
{
    TkBitField *bf1, *bf2, *bfAdd, *bfSub;
    int isEqual;
    unsigned n, size;

    assert(ts1);
    assert(ts2);
    assert(add);
    assert(sub);

    n = ts1->base.isSetFlag + ts2->base.isSetFlag + add->base.isSetFlag + sub->base.isSetFlag;

    if (n == 0) {
	return TkBitInnerJoinDifferenceIsEqual(&ts1->bf, &ts2->bf, &add->bf, &sub->bf);
    }
    if (n == 4) {
	return TkIntSetInnerJoinDifferenceIsEqual(&ts1->set, &ts2->set, &add->set, &sub->set);
    }
    if (TkTextTagSetIsEmpty(add)) {
	return true;
    }

    size = MaxSize4(ts1, ts2, add, sub);
    bf1 = GetBitField(ts1, size);
    bf2 = GetBitField(ts2, size);
    bfAdd = GetBitField(add, size);
    bfSub = GetBitField(sub, size);
    isEqual = TkBitInnerJoinDifferenceIsEqual(bf1, bf2, bfAdd, bfSub);
    TkBitDecrRefCount(bf1);
    TkBitDecrRefCount(bf2);
    TkBitDecrRefCount(bfAdd);
    TkBitDecrRefCount(bfSub);

    return isEqual;
}

#endif /* TK_UNUSED_TAGSET_FUNCTIONS */

/* Additionally we need stand-alone object code. */
extern TkTextTagSet *TkTextTagSetNew(unsigned size);
extern unsigned TkTextTagSetRefCount(const TkTextTagSet *ts);
extern void TkTextTagSetIncrRefCount(TkTextTagSet *ts);
extern unsigned TkTextTagSetDecrRefCount(TkTextTagSet *ts);
extern TkTextTagSet *TkTextTagSetCopy(const TkTextTagSet *src);
extern int TkTextTagSetIsEmpty(const TkTextTagSet *ts);
extern int TkTextTagSetIsBitField(const TkTextTagSet *ts);
extern unsigned TkTextTagSetSize(const TkTextTagSet *ts);
extern unsigned TkTextTagSetCount(const TkTextTagSet *ts);
extern int TkTextTagSetTest(const TkTextTagSet *ts, unsigned n);
extern int TkTextTagSetNone(const TkTextTagSet *ts);
extern int TkTextTagSetAny(const TkTextTagSet *ts);
extern int TkTextTagSetIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
extern int TkTextTagSetContains(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
extern int TkTextTagSetDisjunctive(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
extern int TkTextTagSetIntersects(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
extern int TkTextTagSetIntersectionIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2,
    const TkBitField *bf);
extern int TkTextTagBitContainsSet(const TkBitField *bf, const TkTextTagSet *ts);
extern int TkTextTagSetIsEqualBits(const TkTextTagSet *ts, const TkBitField *bf);
extern int TkTextTagSetContainsBits(const TkTextTagSet *ts, const TkBitField *bf);
extern int TkTextTagSetDisjunctiveBits(const TkTextTagSet *ts, const TkBitField *bf);
extern int TkTextTagSetIntersectsBits(const TkTextTagSet *ts, const TkBitField *bf);
extern unsigned TkTextTagSetFindFirst(const TkTextTagSet *ts);
extern unsigned TkTextTagSetFindNext(const TkTextTagSet *ts, unsigned prev);
extern TkTextTagSet *TkTextTagSetAddOrErase(TkTextTagSet *ts, unsigned n, int value);
extern TkTextTagSet *TkTextTagSetAddToThis(TkTextTagSet *ts, unsigned n);
extern TkTextTagSet *TkTextTagSetEraseFromThis(TkTextTagSet *ts, unsigned n);
extern unsigned TkTextTagSetRangeSize(const TkTextTagSet *ts);
extern const unsigned char *TkTextTagSetData(const TkTextTagSet *ts);
extern unsigned TkTextTagSetByteSize(const TkTextTagSet *ts);

/* vi:set ts=8 sw=4: */

Added generic/tkTextTagSet.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
/*
 * tkTextTagSet.h --
 *
 *	This module implements a set for tagging information. The real type
 *	is either a bit field, or a set of integers, depending on the size
 *	of the tag set.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXTTAGSET
#define _TKTEXTTAGSET

#include "tkInt.h"
#include "tkBitField.h"
#include "tkIntSet.h"

#if defined(__GNUC__) || defined(__clang__)
# define __warn_unused__ __attribute__((warn_unused_result))
#else
# define __warn_unused__
#endif


/*
 * Currently our implementation is using a shared bitfield/integer set implementation.
 * Bitfields will be used as long as the number of tags is below a certain limit
 * (will be satisfied in most applications), but in some sophisticated applications
 * this limit will be exceeded, and in this case the integer set comes into play,
 * because a bitfield is too memory hungry with a large number of tags. Bitfields
 * are very, very fast, and integer sets are moderate in speed. So a bitfield will be
 * preferred. Nevertheless this implementation might be a bit over the top, probably
 * an implementation only with integer sets is already satisfactory.
 *
 * NOTE: The bit field implementation shouldn't be removed, even if this implementation
 * will not be used, because it is required for testing the integer set (TkIntSet).
 */

/* This is common to both implementations. */
# define TK_TEXT_TAG_SET_NPOS TK_SET_NPOS


/*
 * The struct below is using C inheritance, this is portable due to C99 section
 * 6.7.2.1 bullet point 13:
 *
 *	Within a structure object, the non-bit-field members and the units
 *	in which bit-fields reside have addresses that increase in the order
 *	in which they are declared. A pointer to a structure object, suitably
 *	converted, points to its initial member (or if that member is a
 *	bit-field, then to the unit in which it resides), and vice versa.
 *	There may be unnamed padding within a structure object, but not at
 *	beginning.
 *
 * This inheritance concept is also used in the portable GTK library.
 */

typedef struct TkTextTagSetBase {
    uint32_t refCount:31;
    uint32_t isSetFlag:1;
} TkTextTagSetBase;

typedef union TkTextTagSet {
    TkTextTagSetBase base;
    TkBitField bf;
    TkIntSet set;
} TkTextTagSet;


inline TkTextTagSet *TkTextTagSetNew(unsigned size) __warn_unused__;
TkTextTagSet *TkTextTagSetResize(TkTextTagSet *ts, unsigned newSize) __warn_unused__;
void TkTextTagSetDestroy(TkTextTagSet **tsPtr);

inline unsigned TkTextTagSetRefCount(const TkTextTagSet *ts);
inline void TkTextTagSetIncrRefCount(TkTextTagSet *ts);
inline unsigned TkTextTagSetDecrRefCount(TkTextTagSet *ts);

inline TkTextTagSet *TkTextTagSetCopy(const TkTextTagSet *src) __warn_unused__;
TkBitField *TkTextTagSetToBits(const TkTextTagSet *src, int size) __warn_unused__;

TkTextTagSet *TkTextTagSetJoin(TkTextTagSet *dst, const TkTextTagSet *src) __warn_unused__;
TkTextTagSet *TkTextTagSetIntersect(TkTextTagSet *dst, const TkTextTagSet *src) __warn_unused__;
TkTextTagSet *TkTextTagSetRemove(TkTextTagSet *dst, const TkTextTagSet *src) __warn_unused__;

TkTextTagSet *TkTextTagSetIntersectBits(TkTextTagSet *dst, const TkBitField *src) __warn_unused__;
TkTextTagSet *TkTextTagSetRemoveBits(TkTextTagSet *dst, const TkBitField *src) __warn_unused__;

/* dst := dst + ts1 + ts2 */
TkTextTagSet *TkTextTagSetJoin2(TkTextTagSet *dst, const TkTextTagSet *ts1, const TkTextTagSet *ts2)
    __warn_unused__;
/* dst := src - dst */
TkTextTagSet *TkTextTagSetComplementTo(TkTextTagSet *dst, const TkTextTagSet *src) __warn_unused__;
/* dst := dst + (ts2 - ts1) */
TkTextTagSet *TkTextTagSetJoinComplementTo(TkTextTagSet *dst,
    const TkTextTagSet *ts1, const TkTextTagSet *ts2) __warn_unused__;
/* dst := dst + (ts1 - ts2) + (ts2 - ts1) */
TkTextTagSet *TkTextTagSetJoinNonIntersection(TkTextTagSet *dst,
    const TkTextTagSet *ts1, const TkTextTagSet *ts2) __warn_unused__;
/* dst := dst + add + ((ts1 + ts2) - (ts1 & ts2)) */
TkTextTagSet *TkTextTagSetJoin2ComplementToIntersection(TkTextTagSet *dst,
    const TkTextTagSet *add, const TkTextTagSet *ts1, const TkTextTagSet *ts2) __warn_unused__;
/* dst := (dst - ts1) + (ts1 - ts2) */
TkTextTagSet *TkTextTagSetJoinOfDifferences(TkTextTagSet *dst, const TkTextTagSet *ts1,
    const TkTextTagSet *ts2) __warn_unused__;

inline int TkTextTagSetIsEmpty(const TkTextTagSet *ts);
inline int TkTextTagSetIsBitField(const TkTextTagSet *ts);

inline unsigned TkTextTagSetSize(const TkTextTagSet *ts);
inline unsigned TkTextTagSetCount(const TkTextTagSet *ts);

inline int TkTextTagSetTest(const TkTextTagSet *ts, unsigned n);
inline int TkTextTagSetNone(const TkTextTagSet *ts);
inline int TkTextTagSetAny(const TkTextTagSet *ts);

inline int TkTextTagSetIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
inline int TkTextTagSetContains(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
inline int TkTextTagSetDisjunctive(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
inline int TkTextTagSetIntersects(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
/* (ts1 & bf) == (ts2 & bf) */
inline int TkTextTagSetIntersectionIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2,
    const TkBitField *bf);
inline int TkTextTagBitContainsSet(const TkBitField *bf, const TkTextTagSet *ts);

inline int TkTextTagSetIsEqualBits(const TkTextTagSet *ts, const TkBitField *bf);
inline int TkTextTagSetContainsBits(const TkTextTagSet *ts, const TkBitField *bf);
inline int TkTextTagSetDisjunctiveBits(const TkTextTagSet *ts, const TkBitField *bf);
inline int TkTextTagSetIntersectsBits(const TkTextTagSet *ts, const TkBitField *bf);

inline unsigned TkTextTagSetFindFirst(const TkTextTagSet *ts);
inline unsigned TkTextTagSetFindNext(const TkTextTagSet *ts, unsigned prev);
unsigned TkTextTagSetFindFirstInIntersection(const TkTextTagSet *ts, const TkBitField *bf);

TkTextTagSet *TkTextTagSetAdd(TkTextTagSet *ts, unsigned n) __warn_unused__;
TkTextTagSet *TkTextTagSetErase(TkTextTagSet *ts, unsigned n) __warn_unused__;
inline TkTextTagSet *TkTextTagSetAddOrErase(TkTextTagSet *ts, unsigned n, int value)
    __warn_unused__;
TkTextTagSet *TkTextTagSetTestAndSet(TkTextTagSet *ts, unsigned n) __warn_unused__;
TkTextTagSet *TkTextTagSetTestAndUnset(TkTextTagSet *ts, unsigned n) __warn_unused__;
TkTextTagSet *TkTextTagSetClear(TkTextTagSet *ts) __warn_unused__;

inline TkTextTagSet *TkTextTagSetAddToThis(TkTextTagSet *ts, unsigned n) __warn_unused__;
inline TkTextTagSet *TkTextTagSetEraseFromThis(TkTextTagSet *ts, unsigned n) __warn_unused__;
TkTextTagSet *TkTextTagSetRemoveFromThis(TkTextTagSet *dst, const TkTextTagSet *src) __warn_unused__;
TkTextTagSet *TkTextTagSetIntersectThis(TkTextTagSet *dst, const TkTextTagSet *src) __warn_unused__;

inline unsigned TkTextTagSetRangeSize(const TkTextTagSet *ts);

inline const unsigned char *TkTextTagSetData(const TkTextTagSet *ts);
inline unsigned TkTextTagSetByteSize(const TkTextTagSet *ts);

# ifndef NDEBUG
void TkTextTagSetPrint(const TkTextTagSet *set);
# endif

# ifdef TK_UNUSED_TAGSET_FUNCTIONS

/*
 * These functions are not needed anymore, but shouldn't be removed, because sometimes
 * any of these functions might be useful.
 */

/* dst := (dst + (ts - sub)) & ts */
TkTextTagSet *TkTextTagSetInnerJoinDifference(TkTextTagSet *dst,
    const TkTextTagSet *ts, const TkTextTagSet *sub) __warn_unused__;
/* ((ts + (add - sub)) & add) == nil */
int TkTextTagSetInnerJoinDifferenceIsEmpty(const TkTextTagSet *ts,
    const TkTextTagSet *add, const TkTextTagSet *sub);
/* ts1 == ts2 - sub2 */
int TkTextTagSetIsEqualToDifference(const TkTextTagSet *ts1,
    const TkTextTagSet *ts2, const TkTextTagSet *sub2);
/* ts1 == ts2 + (add2 & ts2) */
int TkTextTagSetIsEqualToInnerJoin(const TkTextTagSet *ts1, const TkTextTagSet *ts2,
    const TkTextTagSet *add2);
/* ts1 == ((ts2 + (add2 - sub2)) & add2) */
int TkTextTagSetIsEqualToInnerJoinDifference(const TkTextTagSet *ts1, const TkTextTagSet *ts2,
    const TkTextTagSet *add2, const TkTextTagSet *sub2);
/* ((ts1 + (add - sub)) & add) == ((ts2 + (add - sub)) & add) */
int TkTextTagSetInnerJoinDifferenceIsEqual(const TkTextTagSet *ts1, const TkTextTagSet *ts2,
    const TkTextTagSet *add, const TkTextTagSet *sub);

# endif /* TK_UNUSED_TAGSET_FUNCTIONS */

#undef __warn_unused__

#define _TK_NEED_IMPLEMENTATION
#include "tkTextTagSetPriv.h"
#endif /* _TKTEXTTAGSET */
/* vi:set ts=8 sw=4: */

Added generic/tkTextTagSetPriv.h.

















































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
/*
 * tkTextTagSetPriv.h --
 *
 *	Private implementation.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXTTAGSET
# error "do not include this private header file"
#endif


#ifndef _TKTEXTTAGSETPRIV
#define _TKTEXTTAGSETPRIV

/*
 * The constant TK_TEXT_SET_MAX_BIT_SIZE is defining the upper bound of
 * the bit size in bit fields. This means that if more than TK_TEXT_SET_MAX_BIT_SIZE
 * tags are in usage, the tag set is using integer sets instead of bit fields,
 * because large bit fields are exploding the memory usage.
 *
 * The constant TK_TEXT_SET_MAX_BIT_SIZE must be a multiple of TK_BIT_NBITS.
 */

#ifdef TK_IS_64_BIT_ARCH

/*
 * On 64 bit systems this is the optimal size and it is not recommended to
 * choose a lower size.
 */
# define TK_TEXT_SET_MAX_BIT_SIZE (((512 + TK_BIT_NBITS - 1)/TK_BIT_NBITS)*TK_BIT_NBITS)

#else /* TK_IS_64_BIT_ARCH */

/*
 * On 32 bit systems the current size (512) might be too large. If so it should
 * be reduced to 256, but it is not recommended to define a lower constant than
 * 256.
 */
# define TK_TEXT_SET_MAX_BIT_SIZE (((512 + TK_BIT_NBITS - 1)/TK_BIT_NBITS)*TK_BIT_NBITS)

#endif /* TK_IS_64_BIT_ARCH */


MODULE_SCOPE int TkTextTagSetIsEqual_(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
MODULE_SCOPE int TkTextTagSetContains_(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
MODULE_SCOPE int TkTextTagSetDisjunctive_(const TkTextTagSet *ts1, const TkTextTagSet *ts2);
MODULE_SCOPE int TkTextTagSetIntersectionIsEqual_(const TkTextTagSet *ts1, const TkTextTagSet *ts2,
		    const TkBitField *bf);

#endif /* _TKTEXTTAGSETPRIV */


#ifdef _TK_NEED_IMPLEMENTATION

#ifndef _TK
#include "tk.h"
#endif

#include <assert.h>


inline
TkTextTagSet *
TkTextTagSetNew(
    unsigned size)
{
    if (size <= TK_TEXT_SET_MAX_BIT_SIZE) {
	return (TkTextTagSet *) TkBitNew(size);
    }
    return (TkTextTagSet *) TkIntSetNew();
}


inline
unsigned
TkTextTagSetRefCount(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.refCount;
}


inline
void
TkTextTagSetIncrRefCount(
    TkTextTagSet *ts)
{
    assert(ts);
    ts->base.refCount += 1;
}


inline
unsigned
TkTextTagSetDecrRefCount(
    TkTextTagSet *ts)
{
    unsigned refCount;

    assert(ts);
    assert(TkTextTagSetRefCount(ts) > 0);

    if ((refCount = --ts->base.refCount) == 0) {
	TkTextTagSetDestroy(&ts);
    }
    return refCount;
}


inline
int
TkTextTagSetIsEmpty(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetIsEmpty(&ts->set) : TkBitNone(&ts->bf);
}


inline
int
TkTextTagSetIsBitField(
    const TkTextTagSet *ts)
{
    assert(ts);
    return !ts->base.isSetFlag;
}


inline
unsigned
TkTextTagSetSize(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TK_TEXT_TAG_SET_NPOS - 1 : TkBitSize(&ts->bf);
}


inline
unsigned
TkTextTagSetRangeSize(
    const TkTextTagSet *ts)
{
    assert(ts);

    if (!ts->base.isSetFlag) {
	return TkBitSize(&ts->bf);
    }
    return TkIntSetIsEmpty(&ts->set) ? 0 : TkIntSetMax(&ts->set) + 1;
}


inline
unsigned
TkTextTagSetCount(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetSize(&ts->set) : TkBitCount(&ts->bf);
}


inline
int
TkTextTagSetIsEqual(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(ts1);
    assert(ts2);

    if (ts1->base.isSetFlag || ts2->base.isSetFlag) {
	return TkTextTagSetIsEqual_(ts1, ts2);
    }
    return TkBitIsEqual(&ts1->bf, &ts2->bf);
}


inline
int
TkTextTagSetContains(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(ts1);
    assert(ts2);

    if (ts1->base.isSetFlag || ts2->base.isSetFlag) {
	return TkTextTagSetContains_(ts1, ts2);
    }
    return TkBitContains(&ts1->bf, &ts2->bf);
}


inline
int
TkTextTagSetDisjunctive(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    assert(ts1);
    assert(ts2);

    if (ts1->base.isSetFlag || ts2->base.isSetFlag) {
	return TkTextTagSetDisjunctive_(ts1, ts2);
    }
    return TkBitDisjunctive(&ts1->bf, &ts2->bf);
}


inline
int
TkTextTagSetIntersects(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2)
{
    return !TkTextTagSetDisjunctive(ts1, ts2);
}


inline
int
TkTextTagSetIntersectionIsEqual(
    const TkTextTagSet *ts1,
    const TkTextTagSet *ts2,
    const TkBitField *bf)
{
    assert(ts1);
    assert(ts2);

    if (ts1->base.isSetFlag || ts2->base.isSetFlag) {
	return TkTextTagSetIntersectionIsEqual_(ts1, ts2, bf);
    }
    return TkBitIntersectionIsEqual(&ts1->bf, &ts2->bf, bf);
}


inline
int
TkTextTagBitContainsSet(
    const TkBitField *bf,
    const TkTextTagSet *ts)
{
    return ts->base.isSetFlag ? TkIntSetIsContainedBits(&ts->set, bf) : TkBitContains(bf, &ts->bf);
}


inline
int
TkTextTagSetIsEqualBits(
    const TkTextTagSet *ts,
    const TkBitField *bf)
{
    assert(ts);
    assert(bf);
    return ts->base.isSetFlag ? TkIntSetIsEqualBits(&ts->set, bf) : TkBitIsEqual(&ts->bf, bf);
}


inline
int
TkTextTagSetContainsBits(
    const TkTextTagSet *ts,
    const TkBitField *bf)
{
    assert(ts);
    assert(bf);
    return ts->base.isSetFlag ? TkIntSetContainsBits(&ts->set, bf) : TkBitContains(&ts->bf, bf);
}


inline
int
TkTextTagSetDisjunctiveBits(
    const TkTextTagSet *ts,
    const TkBitField *bf)
{
    assert(ts);
    assert(bf);
    return ts->base.isSetFlag ? TkIntSetDisjunctiveBits(&ts->set, bf) : TkBitDisjunctive(&ts->bf, bf);
}


inline
int
TkTextTagSetIntersectsBits(
    const TkTextTagSet *ts,
    const TkBitField *bf)
{
    return !TkTextTagSetDisjunctiveBits(ts, bf);
}


inline
int
TkTextTagSetTest(
    const TkTextTagSet *ts,
    unsigned n)
{
    assert(ts);

    if (ts->base.isSetFlag) {
	return TkIntSetTest(&ts->set, n);
    }
    return n < TkBitSize(&ts->bf) && TkBitTest(&ts->bf, n);
}


inline
int
TkTextTagSetNone(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetNone(&ts->set) : TkBitNone(&ts->bf);
}


inline
int
TkTextTagSetAny(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetAny(&ts->set) : TkBitAny(&ts->bf);
}


inline
TkTextTagSet *
TkTextTagSetCopy(
    const TkTextTagSet *src)
{
    assert(src);

    if (src->base.isSetFlag) {
	return (TkTextTagSet *) TkIntSetCopy(&src->set);
    }
    return (TkTextTagSet *) TkBitCopy(&src->bf, -1);
}


inline
unsigned
TkTextTagSetFindFirst(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetFindFirst(&ts->set) : TkBitFindFirst(&ts->bf);
}


inline
unsigned
TkTextTagSetFindNext(
    const TkTextTagSet *ts,
    unsigned prev)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetFindNext(&ts->set) :  TkBitFindNext(&ts->bf, prev);
}


inline
TkTextTagSet *
TkTextTagSetAddOrErase(
    TkTextTagSet *ts,
    unsigned n,
    int value)
{
    assert(ts);
    return value ? TkTextTagSetAdd(ts, n) : TkTextTagSetErase(ts, n);
}


inline
TkTextTagSet *
TkTextTagSetAddToThis(
    TkTextTagSet *ts,
    unsigned n)
{
    assert(ts);
    assert(n < TkTextTagSetSize(ts));

    if (ts->base.isSetFlag) {
	ts = (TkTextTagSet *) TkIntSetAdd(&ts->set, n);
    } else {
	TkBitSet(&ts->bf, n);
    }
    return ts;
}


inline
TkTextTagSet *
TkTextTagSetEraseFromThis(
    TkTextTagSet *ts,
    unsigned n)
{
    assert(ts);
    assert(n < TkTextTagSetSize(ts));

    if (ts->base.isSetFlag) {
	ts = (TkTextTagSet *) TkIntSetErase(&ts->set, n);
    } else {
	TkBitUnset(&ts->bf, n);
    }
    return ts;
}


inline
const unsigned char *
TkTextTagSetData(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetData(&ts->set) : TkBitData(&ts->bf);
}


inline
unsigned
TkTextTagSetByteSize(
    const TkTextTagSet *ts)
{
    assert(ts);
    return ts->base.isSetFlag ? TkIntSetByteSize(&ts->set) : TkBitByteSize(&ts->bf);
}

#undef _TK_NEED_IMPLEMENTATION
#endif /* _TK_NEED_IMPLEMENTATION */
/* vi:set ts=8 sw=4: */

Added generic/tkTextUndo.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
/*
 * tkTextUndo.c --
 *
 *	This module provides the implementation of an undo stack.
 *
 * Copyright (c) 2015-2017 Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkTextUndo.h"
#include <assert.h>

#ifndef MAX
# define MAX(a,b) ((a) < (b) ? b : a)
#endif

#ifndef MIN
# define MIN(a,b) ((a) < (b) ? a : b)
#endif


typedef TkTextUndoMyAtom MyUndoAtom;


/*
 * Our list of undo/redo atoms is a circular double linked list.
 * It's circular beause the "last" pointer is connected with the
 * "root" pointer. The list starts either with the oldest undo atom,
 * or with the newest redo atom if no undo atom exists.
 *
 * 'stack->last' is always pointing to the newest undo item, or
 * NULL if no undo item exists.
 *
 * 'stack->root' is always pointing either to the oldest undo item,
 * or to the oldest redo item if no undo item exists.
 *
 * 'stack->current' is the current atom which receives all pushed
 * items (TkTextUndoPushItem), and is not yet linked into the list.
 * 'stack->current' can be NULL, in this case it has to be created
 * when the user is pushing an item.
 *
 * last ------------------+
 * root --+               |
 *        V               V
 *      +---+   +---+   +---+   +---+   +---+
 *   +->| A |-->| B |-->| C |-->| d |-->| e |--+
 *   |  +---+   +---+   +---+   +---+   +---+  |
 *   ------------------------------------------+
 *      undo: 3	                redo: 2
 *
 * A = oldest undo item
 * B = second oldest undo item
 * C = newest undo item
 * d = newest redo item
 * e = oldest redo item
 */


#define ATOM_SIZE(n) (offsetof(TkTextUndoMyAtom, data) \
	+ offsetof(TkTextUndoAtom, array) + (n)*sizeof(TkTextUndoSubAtom))


enum { InitialCapacity = 20 };


static void
FreeItems(
    const TkTextUndoStack stack,
    const TkTextUndoAtom *atom)
{
    TkTextUndoFreeProc *freeProc = stack->freeProc;
    const TkTextUndoSubAtom *arr;
    unsigned i, n;

    assert(atom);

    if (!freeProc) {
	return;
    }

    arr = atom->array;
    n = atom->arraySize;

    for (i = 0; i < n; ++i) {
	freeProc(stack, &arr[i]);
    }
}


static void
Release(
    TkTextUndoStack stack,
    MyUndoAtom *atom)
{
    MyUndoAtom *first, *root, *prev;

    if (!atom) {
	return;
    }

    assert(stack->root);
    first = atom;
    root = stack->root;
    prev = atom->prev;

    /*
     * Now delete all atoms starting at 'atom' until we reach the end (inclusive).
     */

    do {
	MyUndoAtom *next = atom->next;
	FreeItems(stack, &atom->data);
	ckfree(atom);
	atom = next;
    } while (atom != root);

    /*
     * Update the list pointers accordingly.
     */

    if (first == root) {
	stack->root = stack->last = NULL;
    } else {
	root->prev = prev;
	prev->next = root;
    }
}


static void
ResetCurrent(
    TkTextUndoStack stack,
    int force)
{
    TkTextUndoMyAtom *current = stack->current;

    if (current) {
	FreeItems(stack, &current->data);
    }

    if (force || !current || current->capacity > InitialCapacity) {
	static unsigned Size = ATOM_SIZE(InitialCapacity);
	current = stack->current = (TkTextUndoMyAtom *)ckrealloc(current, Size);
	memset((void *)current, 0, Size);
	current->capacity = InitialCapacity;
    }

    current->data.arraySize = 0;
    current->data.size = 0;
    current->undoSize = 0;
}


static MyUndoAtom *
SwapCurrent(
    TkTextUndoStack stack,
    MyUndoAtom *atom)
{
    MyUndoAtom *current = stack->current;

    assert(atom != current);

    if (current->capacity != current->data.size) {
	current = stack->current = (MyUndoAtom *)ckrealloc(current, ATOM_SIZE(current->data.arraySize));
	current->capacity = current->data.arraySize;
    }

    if (!atom) {
	/*
	 * Just use the 'stack->current' item.
	 */
	stack->current = NULL;
	return current;
    }

    /*
     * Exchange given 'atom' with 'stack->current', this means that
     * 'stack->current' will be linked into the list replacing 'atom',
     * and 'atom' will become 'stack->current'.
     */

    if (atom->next == atom) {
	current->next = current;
	current->prev = current;
    } else {
	current->next = atom->next;
	current->prev = atom->prev;
	atom->next->prev = current;
	atom->prev->next = current;
    }

    stack->current = atom;
    atom->data.arraySize = 0;
    atom->data.size = 0;
    atom->undoSize = 0;
    atom->next = atom->prev = NULL;

    if (stack->root == atom) {
	stack->root = current;
    }
    if (stack->last == atom) {
	stack->last = current;
    }

    return current;
}


static int
ClearRedoStack(
    TkTextUndoStack stack)
{
    MyUndoAtom *atom;

    if (stack->redoDepth == 0) {
	return 0;
    }

    atom = stack->last ? stack->last->next : stack->root;

    assert(atom);
    stack->redoDepth = 0;
    stack->redoSize = 0;
    stack->redoItems = 0;
    Release(stack, atom);

    return 1;
}


static void
InsertCurrentAtom(
    TkTextUndoStack stack)
{
    MyUndoAtom *atom;
    MyUndoAtom *current = stack->current;

    if (!current || current->data.arraySize == 0) {
	assert(!stack->doingUndo && !stack->doingRedo);
	return;
    }

    if (stack->maxSize > 0 && !stack->doingRedo) {
	unsigned newStackSize = current->data.size;

	if (stack->doingUndo) {
	    newStackSize = MAX(current->undoSize, newStackSize);
	}
	newStackSize += stack->undoSize + stack->redoSize;

	if (newStackSize > stack->maxSize) {
	    /*
	     * We do not push this atom, because the addtional size would
	     * exceed the maximal content size.
	     *
	     * Note that we must push an undo atom while performing a redo,
	     * but this case is already catched, and the size of this atom
	     * has already been taken into account (with the check of
	     * 'current->undoSize' when inserting the reverting redo atom;
	     * we assume that the new undo atom size is the same as the
	     * undo size before the redo).
	     */
	    if (stack->doingUndo) {
		/*
		 * We do not push this redo atom while peforming an undo, so all
		 * redoes are expired, we have to delete them.
		 */
		ClearRedoStack(stack);
	    } else {
		/*
		 * We do not push this undo atom, so the content becomes irreversible.
		 */
		stack->irreversible = 1;
	    }
	    FreeItems(stack, &stack->current->data);
	    ResetCurrent(stack, 0);
	    return;
	}
    }

    if (stack->doingRedo) {
	/*
	 * We'll push an undo atom while performing a redo.
	 */
	if (!stack->last) {
	    stack->last = stack->root;
	}
	atom = stack->last;
	SwapCurrent(stack, atom);
	stack->undoDepth += 1;
	stack->undoSize += atom->data.size;
	stack->undoItems += atom->data.arraySize;
    } else if (stack->doingUndo) {
	/*
	 * We'll push a redo atom while performing an undo.
	 */
	assert(stack->maxRedoDepth <= 0 || (int) stack->redoDepth < stack->maxRedoDepth);
	atom = stack->last ? stack->last->next : stack->root;
	SwapCurrent(stack, atom);
	stack->redoDepth += 1;
	stack->redoSize += atom->data.size;
	stack->redoItems += atom->data.arraySize;
    } else if (stack->last && stack->undoDepth == stack->maxUndoDepth) {
	/*
	 * We've reached the maximal stack limit, so delete the oldest undo
	 * before inserting the new item. The consequence is that now the content
	 * becomes irreversible. Furthermore all redo items will expire.
	 */
	ClearRedoStack(stack);
	assert(stack->last);
	atom = stack->last->next;
	stack->root = atom->next;
	stack->last = atom;
	stack->undoSize -= atom->data.size;
	stack->undoItems -= atom->data.arraySize;
	stack->irreversible = 1;
	FreeItems(stack, &atom->data);
	SwapCurrent(stack, atom);
	stack->undoSize += atom->data.size;
	stack->undoItems += atom->data.arraySize;
    } else {
	/*
	 * Just insert the newly undo atom. Furthermore all redo items will expire.
	 */
	ClearRedoStack(stack);
	if (stack->last == NULL) {
	    stack->last = stack->root;
	}
	atom = SwapCurrent(stack, NULL);
	if ((atom->prev = stack->last)) {
	    atom->next = stack->last->next;
	    stack->last->next->prev = atom;
	    stack->last->next = atom;
	} else {
	    atom->next = atom->prev = stack->root = atom;
	}
	stack->last = atom;
	stack->undoDepth += 1;
	stack->undoSize += atom->data.size;
	stack->undoItems += atom->data.arraySize;
    }

    if (!stack->doingUndo) {
	/*
	 * Remember the size of this undo atom, probably we need it for the
	 * decision whether to push a redo atom when performing an undo.
	 */
	atom->undoSize = atom->data.size;
    }

    /*
     * Reset the buffer for next action.
     */
    ResetCurrent(stack, 0);
}


static int
ResetStack(
    TkTextUndoStack stack,
    int irreversible)
{
    int contentChanged;

    assert(stack);

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    contentChanged = stack->undoDepth > 0 || stack->redoDepth > 0 || stack->current;

    if (contentChanged) {
	Release(stack, stack->root);
	ResetCurrent(stack, 1);
	stack->root = NULL;
	stack->last = NULL;
	stack->undoDepth = 0;
	stack->redoDepth = 0;
	stack->undoItems = 0;
	stack->redoItems = 0;
	stack->undoSize = 0;
	stack->redoSize = 0;
	stack->irreversible = irreversible;
	stack->pushSeparator = 0;

	if (stack->contentChangedProc) {
	    stack->contentChangedProc(stack);
	}
    }

    return TCL_OK;
}


TkTextUndoStack
TkTextUndoCreateStack(
    unsigned maxUndoDepth,
    int maxRedoDepth,
    unsigned maxSize,
    TkTextUndoPerformProc undoProc,
    TkTextUndoFreeProc freeProc,
    TkTextUndoStackContentChangedProc contentChangedProc)
{
    TkTextUndoStack stack;

#ifndef _MSC_VER /* MSVC erroneously triggers warning C4550 */
    assert(undoProc);
#endif

    stack = (TkTextUndoStack)ckalloc(sizeof(*stack));
    memset(stack, 0, sizeof(*stack));
    stack->undoProc = undoProc;
    stack->freeProc = freeProc;
    stack->contentChangedProc = contentChangedProc;
    stack->maxUndoDepth = maxUndoDepth;
    stack->maxRedoDepth = MAX(maxRedoDepth, -1);
    stack->maxSize = maxSize;

    return stack;
}


void
TkTextUndoDestroyStack(
    TkTextUndoStack *stackPtr)
{
    if (stackPtr) {
	TkTextUndoStack stack = *stackPtr;

	if (stack) {
	    assert(stack);
	    TkTextUndoClearStack(stack);
	    if (stack->current) {
		FreeItems(stack, &stack->current->data);
	    }
	    ckfree(stack);
	    *stackPtr = NULL;
	}
    }
}


int
TkTextUndoResetStack(
    TkTextUndoStack stack)
{
    return stack ? ResetStack(stack, 0) : TCL_ERROR;
}


int
TkTextUndoClearStack(
    TkTextUndoStack stack)
{
    return stack ? ResetStack(stack, stack->undoDepth > 0) : TCL_ERROR;
}


int
TkTextUndoClearUndoStack(
    TkTextUndoStack stack)
{
    if (!stack) {
	return TCL_OK;
    }

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    if (stack->undoDepth > 0) {
	TkTextUndoMyAtom *atom;

	assert(stack->last);
	stack->undoDepth = 0;
	stack->undoSize = 0;
	stack->undoItems = 0;
	atom = stack->root;
	stack->root = stack->last->next;
	stack->last = NULL;
	Release(stack, atom);
	ResetCurrent(stack, 1);
	stack->irreversible = 1;

	if (stack->contentChangedProc) {
	    stack->contentChangedProc(stack);
	}
    }

    return TCL_OK;
}


int
TkTextUndoClearRedoStack(
    TkTextUndoStack stack)
{
    if (!stack) {
	return TCL_OK;
    }

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    if (ClearRedoStack(stack) && stack->contentChangedProc) {
	stack->contentChangedProc(stack);
    }

    return TCL_OK;
}


int
TkTextUndoSetMaxStackDepth(
    TkTextUndoStack stack,
    unsigned maxUndoDepth,
    int maxRedoDepth)
{
    assert(stack);

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    if (maxUndoDepth > 0 || maxRedoDepth >= 0) {
	unsigned depth = stack->maxUndoDepth;

	if (depth == 0) {
	    depth = stack->undoDepth + stack->redoDepth;
	}

	if ((0 < maxUndoDepth && maxUndoDepth < depth)
		|| (0 <= maxRedoDepth && (unsigned) maxRedoDepth < (unsigned) stack->maxRedoDepth)) {
	    unsigned deleteRedos = MIN(stack->redoDepth, depth - maxUndoDepth);

	    if (0 <= maxRedoDepth && maxRedoDepth < stack->maxRedoDepth) {
		deleteRedos = MIN(stack->redoDepth,
			MAX(deleteRedos, (unsigned) stack->maxRedoDepth - maxRedoDepth));
	    }

	    stack->redoDepth -= deleteRedos;
	    depth = maxUndoDepth - deleteRedos;

	    if (deleteRedos > 0) {
		MyUndoAtom *atom = stack->root;

		/*
		 * We have to reduce the stack size until the depth will not
		 * exceed the given limit anymore. Start with oldest redoes,
		 * and continue with oldest undoes if necessary.
		 */

		for ( ; deleteRedos > 0; --deleteRedos) {
		    atom = atom->prev;
		    stack->redoSize -= atom->data.size;
		    stack->redoItems -= atom->data.arraySize;
		}

		Release(stack, atom);
	    }

	    if (maxUndoDepth > 0 && stack->undoDepth > depth) {
		MyUndoAtom *root = stack->root;
		MyUndoAtom *atom = stack->root;
		unsigned deleteUndos = stack->undoDepth - depth;

		stack->undoDepth -= deleteUndos;

		for ( ; deleteUndos > 0; --deleteUndos) {
		    stack->undoSize -= root->data.size;
		    stack->undoItems -= root->data.arraySize;
		    root = root->next;
		}

		stack->root = root;

		/* We have to delete undoes, so the content becomes irreversible. */
		stack->irreversible = 1;

		Release(stack, atom);
	    }

	    if (stack->contentChangedProc) {
		stack->contentChangedProc(stack);
	    }
	}
    }

    stack->maxUndoDepth = maxUndoDepth;
    stack->maxRedoDepth = MAX(maxRedoDepth, -1);
    return TCL_OK;
}


int
TkTextUndoSetMaxStackSize(
    TkTextUndoStack stack,
    unsigned maxSize,
    int applyImmediately)
{
    assert(stack);

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    if (applyImmediately
	    && 0 < maxSize
	    && maxSize < stack->undoSize + stack->redoSize) {
	unsigned size = stack->undoSize + stack->redoSize;
	MyUndoAtom *atom = stack->root;
	unsigned depth = stack->redoDepth;

	/*
	 * We have to reduce the stack size until the size will not exceed
	 * the given limit anymore. Start with oldest redoes, and continue
	 * with oldest undoes if necessary.
	 */

	while (depth > 0 && maxSize < size) {
	    atom = atom->prev;
	    size -= atom->data.size;
	    stack->redoSize -= atom->data.size;
	    stack->redoItems -= atom->data.arraySize;
	    depth -= 1;
	}

	while (atom->data.size == 0 && atom != stack->root) {
	    stack->redoItems += atom->data.arraySize;
	    atom = atom->next;
	    depth += 1;
	}

	if (depth < stack->redoDepth) {
	    stack->redoDepth = depth;
	    Release(stack, atom);
	}

	if (maxSize < size && stack->last) {
	    MyUndoAtom *root = stack->root;

	    depth = stack->undoDepth;

	    while (depth > 0 && maxSize < size) {
		size -= root->data.size;
		stack->undoSize -= root->data.size;
		stack->undoItems -= root->data.arraySize;
		depth -= 1;
		root = root->next;
	    }

	    while (root->data.size == 0 && depth < stack->undoDepth) {
		stack->undoItems += root->data.arraySize;
		depth += 1;
		root = root->prev;
	    }

	    if (depth < stack->undoDepth) {
		stack->undoDepth = depth;
		atom = stack->root;
		stack->root = root;
		/*
		 * We have to delete undoes, so the content becomes irreversible.
		 */
		stack->irreversible = 1;
		Release(stack, atom);
	    }
	}

	if (stack->contentChangedProc) {
	    stack->contentChangedProc(stack);
	}
    }

    stack->maxSize = maxSize;
    return TCL_OK;
}


static void
PushSeparator(
    TkTextUndoStack stack,
    int force)
{
    assert(stack);

    if (force || stack->pushSeparator) {
	/*
	 * When performing an undo/redo, exact one reverting undo/redo atom has
	 * to be inserted, not more. So we do not allow the push of separators
	 * as long as an undo/redo action is in progress.
	 */

	if (!stack->doingUndo && !stack->doingRedo) {
	    /*
	     * Do not trigger stack->contentChangedProc here, because this has been
	     * already done via TkTextUndoPushItem/TkTextUndoPushRedoItem.
	     */
	    InsertCurrentAtom(stack);
	}
    }

    stack->pushSeparator = 0;
}


void
TkTextUndoPushSeparator(
    TkTextUndoStack stack,
    int immediately)
{
    assert(stack);

    if (immediately) {
	PushSeparator(stack, 1);
    } else {
	/* Postpone pushing a separator until next item will be pushed. */
	stack->pushSeparator = 1;
    }
}


int
TkTextUndoPushItem(
    TkTextUndoStack stack,
    TkTextUndoItem item,
    unsigned size)
{
    MyUndoAtom *atom;
    TkTextUndoSubAtom *subAtom;

    assert(stack);
    assert(item);

    PushSeparator(stack, 0);

    if (stack->doingUndo && TkTextUndoRedoStackIsFull(stack)) {
	if (stack->freeProc) {
	    stack->freeProc(stack, (const TkTextUndoSubAtom *)item);
	}
	return TCL_ERROR;
    }

    atom = stack->current;

    if (!atom) {
	ResetCurrent(stack, 1);
	atom = stack->current;
    } else if (atom->data.arraySize == atom->capacity) {
	atom->capacity *= 2;
	atom = stack->current = (TkTextUndoMyAtom *)ckrealloc(atom, ATOM_SIZE(atom->capacity));
    }

    subAtom = ((TkTextUndoSubAtom *) atom->data.array) + atom->data.arraySize++;
    subAtom->item = item;
    subAtom->size = size;
    subAtom->redo = stack->doingUndo;
    atom->data.size += size;
    atom->data.redo = stack->doingUndo;

    if (stack->contentChangedProc && !stack->doingUndo && !stack->doingRedo) {
	stack->contentChangedProc(stack);
    }

    return TCL_OK;
}


int
TkTextUndoPushRedoItem(
    TkTextUndoStack stack,
    TkTextUndoItem item,
    unsigned size)
{
    int rc;

    assert(stack);
    assert(!TkTextUndoIsPerformingUndoRedo(stack));

    PushSeparator(stack, 1);
    stack->doingUndo = 1;
    rc = TkTextUndoPushItem(stack, item, size);
    stack->doingUndo = 0;

    return rc;
}


TkTextUndoItem
TkTextUndoSwapLastItem(
    TkTextUndoStack stack,
    TkTextUndoItem item,
    unsigned *size)
{
    TkTextUndoAtom *last;
    TkTextUndoSubAtom *subAtom;
    TkTextUndoItem oldItem;
    unsigned oldSize;

    assert(stack);
    assert(TkTextUndoGetLastUndoSubAtom(stack));

    last = stack->current ? &stack->current->data : &stack->last->data;
    subAtom = (TkTextUndoSubAtom *) last->array + (last->arraySize - 1);
    oldSize = subAtom->size;
    last->size -= oldSize;
    last->size += *size;
    stack->undoSize -= oldSize;
    stack->undoSize += *size;
    oldItem = subAtom->item;
    subAtom->item = item;
    subAtom->size = *size;
    *size = oldSize;

    return oldItem;
}


int
TkTextUndoDoUndo(
    TkTextUndoStack stack)
{
    int rc;

    assert(stack);

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    InsertCurrentAtom(stack);

    if (stack->undoDepth == 0) {
	rc = TCL_ERROR;
    } else {
	MyUndoAtom *atom;

	assert(stack->last);

	stack->actual = atom = stack->last;
	stack->doingUndo = 1;
	stack->undoDepth -= 1;
	stack->undoSize -= stack->actual->data.size;
	stack->undoItems -= stack->actual->data.arraySize;
	stack->undoProc(stack, &stack->actual->data);
	stack->last = stack->undoDepth ? stack->last->prev : NULL;
	stack->actual = NULL;

	if (!stack->current || stack->current->data.arraySize == 0) {
	    /*
	     * We didn't receive reverting items while performing an undo.
	     * So all redo items are expired, we have to delete them.
	     */
	    stack->redoDepth = 0;
	    stack->redoSize = 0;
	    stack->redoItems = 0;
	    Release(stack, stack->last ? stack->last->next : stack->root);
	} else {
	    FreeItems(stack, &atom->data);
	    InsertCurrentAtom(stack);
	}

	stack->doingUndo = 0;
	rc = TCL_OK;

	if (stack->contentChangedProc) {
	    stack->contentChangedProc(stack);
	}
    }
    return rc;
}


int
TkTextUndoDoRedo(
    TkTextUndoStack stack)
{
    int rc;

    assert(stack);

    if (stack->doingUndo || stack->doingRedo) {
	return TCL_ERROR;
    }

    InsertCurrentAtom(stack);

    if (stack->redoDepth == 0) {
	rc = TCL_ERROR;
    } else {
	MyUndoAtom *atom;

	stack->actual = atom = stack->last ? stack->last->next : stack->root;
	stack->doingRedo = 1;
	stack->redoDepth -= 1;
	stack->redoSize -= atom->data.size;
	stack->redoItems -= atom->data.arraySize;
	stack->undoProc(stack, &atom->data);
	stack->last = atom;
	stack->actual = NULL;

	if (!stack->current || stack->current->data.arraySize == 0) {
	    /*
	     * Oops, we did not receive reverting items while performing a redo.
	     * So we cannot apply the preceding undoes, we have to remove them.
	     * Now the content will become irreversible.
	     */
	    if (stack->undoDepth > 0) {
		stack->undoDepth = 0;
		stack->undoItems = 0;
		stack->undoSize = 0;
		atom = stack->root;
		stack->root = stack->last->next;
		stack->last = NULL;
	    } else {
		stack->root = atom->next;
	    }
	    Release(stack, atom);
	    stack->irreversible = 1;
	} else {
	    FreeItems(stack, &atom->data);
	    InsertCurrentAtom(stack);
	}

	stack->doingRedo = 0;
	rc = TCL_OK;

	if (stack->contentChangedProc) {
	    stack->contentChangedProc(stack);
	}
    }

    return rc;
}

int
TkTextUndoStackIsFull(
    const TkTextUndoStack stack)
{
    if (!stack) {
	return 1;
    }
    if (stack->doingUndo) {
	return stack->maxRedoDepth >= 0 && (int) stack->redoDepth >= stack->maxRedoDepth;
    }
    return stack->maxUndoDepth > 0 && stack->undoDepth >= stack->maxUndoDepth;
}


const TkTextUndoAtom *
TkTextUndoFirstUndoAtom(
    TkTextUndoStack stack)
{
    assert(stack);

    if (stack->current && stack->current->data.arraySize && !stack->doingUndo) {
	return &(stack->iter = stack->current)->data;
    }

    if (stack->undoDepth > 0 && stack->last != stack->actual) {
	return &(stack->iter = stack->last)->data;
    }

    stack->iter = NULL;
    return NULL;
}


const TkTextUndoAtom *
TkTextUndoNextUndoAtom(
    TkTextUndoStack stack)
{
    assert(stack);

    if (stack->iter) {
	if (stack->iter == stack->current) {
	    if (stack->undoDepth > 0 && stack->last != stack->actual) {
		return &(stack->iter = stack->last)->data;
	    }
	    stack->iter = NULL;
	} else if (stack->iter != stack->root && (stack->iter = stack->iter->prev) != stack->actual) {
	    return &stack->iter->data;
	} else {
	    stack->iter = NULL;
	}
    }

    return NULL;
}


const TkTextUndoAtom *
TkTextUndoFirstRedoAtom(
    TkTextUndoStack stack)
{
    assert(stack);

    if (stack->redoDepth > 0 && stack->root->prev != stack->actual) {
	return &(stack->iter = stack->root->prev)->data;
    }

    stack->iter = NULL;

    if (stack->current && stack->current->data.arraySize && stack->doingUndo) {
	return &stack->current->data;
    }

    return NULL;
}


const TkTextUndoAtom *
TkTextUndoNextRedoAtom(
    TkTextUndoStack stack)
{
    assert(stack);

    if (stack->iter) {
	if (stack->iter != stack->root
		&& (stack->iter = stack->iter->prev) != stack->last
		&& stack->iter != stack->actual) {
	    return &stack->iter->data;
	}

	stack->iter = NULL;

	if (stack->current && stack->current->data.arraySize && stack->doingUndo) {
	    return &stack->current->data;
	}
    }

    return NULL;
}


/* Additionally we need stand-alone object code. */
extern void TkTextUndoSetContext(TkTextUndoStack stack, TkTextUndoContext context);
extern TkTextUndoContext TkTextUndoGetContext(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetMaxUndoDepth(const TkTextUndoStack stack);
extern int TkTextUndoGetMaxRedoDepth(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetMaxSize(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetCurrentDepth(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetCurrentSize(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetCurrentUndoStackDepth(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetCurrentRedoStackDepth(const TkTextUndoStack stack);
extern unsigned TkTextUndoCountUndoItems(const TkTextUndoStack stack);
extern unsigned TkTextUndoCountRedoItems(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetCurrentUndoSize(const TkTextUndoStack stack);
extern unsigned TkTextUndoGetCurrentRedoSize(const TkTextUndoStack stack);
extern unsigned TkTextUndoCountCurrentUndoItems(const TkTextUndoStack stack);
extern unsigned TkTextUndoCountCurrentRedoItems(const TkTextUndoStack stack);
extern int TkTextUndoContentIsIrreversible(const TkTextUndoStack stack);
extern int TkTextUndoContentIsModified(const TkTextUndoStack stack);
extern int TkTextUndoIsPerformingUndo(const TkTextUndoStack stack);
extern int TkTextUndoIsPerformingRedo(const TkTextUndoStack stack);
extern int TkTextUndoIsPerformingUndoRedo(const TkTextUndoStack stack);
extern const TkTextUndoAtom *TkTextUndoCurrentUndoAtom(const TkTextUndoStack stack);
extern const TkTextUndoAtom *TkTextUndoCurrentRedoAtom(const TkTextUndoStack stack);
extern const TkTextUndoSubAtom *TkTextUndoGetLastUndoSubAtom(const TkTextUndoStack stack);
extern int TkTextUndoUndoStackIsFull(const TkTextUndoStack stack);
extern int TkTextUndoRedoStackIsFull(const TkTextUndoStack stack);

/* vi:set ts=8 sw=4: */

Added generic/tkTextUndo.h.





































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * tkTextUndo.h --
 *
 * The implementation of an undo/redo stack. The design and implementation
 * of tkUndo is not useful for our purposes:
 *
 * 1. We are not pushing an undo/redo pair on the stack. Our stack is only
 *    pushing the undo item, and applying this undo item will replace this
 *    item by a redo item (and vice versa when performing the redo; in fact
 *    there is no difference between an undo and redo item - the undo of
 *    insert is delete, the undo of delete is insert, and the same applies
 *    to redo). The advantage is that our undo (or redo) item for insert
 *    contains exact zero characters, contrary to the undo/redo pairs in
 *    tkUndo, one of the undo/redo items in this pair always contains a
 *    copy of the text content (a waste of memory).
 *
 * 2. tkUndo expects a script, our stack expects memory addresses (it's also
 *    an general implementation which can be shared).
 *
 * 3. Our stack allows to control the undo and redo stacks separately.
 *
 * 4. Moreover our stack supports to limit the size, not only the depth.
 *
 * Copyright (c) 2015-2017 Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXTUNDO
#define _TKTEXTUNDO

#include "tkInt.h"

/*
 * Our (private) stack type.
 */

struct TkTextUndoStack_;
typedef struct TkTextUndoStack_ *TkTextUndoStack;

/*
 * The generic context type.
 */

typedef void * TkTextUndoContext;

/*
 * Basic type of an undo/redo item, the user has to know the real type.
 */

typedef void * TkTextUndoItem;

/*
 * Struct defining a single action, one or more of which may be defined (and
 * stored in a linked list) separately for each undo and redo action of an
 * undo atom.
 */

typedef struct TkTextUndoSubAtom {
    TkTextUndoItem item;	/* The data of this undo/redo item. */
    uint32_t size:31;		/* Size info for this item. */
    uint32_t redo:1;		/* Is redo item? */
} TkTextUndoSubAtom;

/*
 * Struct representing a single undo+redo atom to be placed in the stack.
 */

typedef struct TkTextUndoAtom {
    uint32_t arraySize;		/* Number of elements in this array. */
    uint32_t size:31;		/* Total size of all items. */
    uint32_t redo:1;		/* Is redo atom? */
    const TkTextUndoSubAtom array[1];
				/* Array of undo/redo actions. */
} TkTextUndoAtom;

/*
 * Callback to carry out undo or redo actions. This function may
 * push redo (undo) items for this undo (redo) onto the stack.
 * The user should push the reverting items while this action will
 * be performed.
 *
 * Note that the atom is given as a const value, but it's allowed
 * to change/reset the items of the sub-atoms.
 */

typedef void (TkTextUndoPerformProc)(TkTextUndoStack stack, const TkTextUndoAtom *atom);

/*
 * Callback proc type to free undo/redo items. This function will be
 * called when the user is clearing the stack (destroying the stack
 * is implicitly clearing the stack), or when the push operation
 * is deleting the oldest undo atom (for keeping the max. depth and
 * max. size).
 */

typedef void (TkTextUndoFreeProc)(const TkTextUndoStack stack, const TkTextUndoSubAtom *atom);

/*
 * Callback proc type for stack changes. Every time when the stack is
 * changing this callback function will be triggered.
 */

typedef void (TkTextUndoStackContentChangedProc)(const TkTextUndoStack stack);

/*
 * Functions for constructing/destructing the stack. Use zero for unlimited
 * stack depth, also use zero for unlimited size. 'freeProc' can be NULL,
 * but normally this function is required. It's clear that 'undoProc' is
 * mandatory. 'informStackChangeProc' and pushSeparatorProc can also be NULL.
 */

TkTextUndoStack TkTextUndoCreateStack(
    unsigned maxUndoDepth, int maxRedoDepth, unsigned maxSize,
    TkTextUndoPerformProc undoProc, TkTextUndoFreeProc freeProc,
    TkTextUndoStackContentChangedProc contentChangedProc);
void TkTextUndoDestroyStack(TkTextUndoStack *stackPtr);

/*
 * Managing the stack. Use zero for unlimited stack depth, also use zero
 * for unlimited size. Setting a lower limit than the current depth is
 * reducing the stack immediately. Setting a lower limit than the current
 * size is also reducing the stack immediately iff 'applyImmediately' is
 * 'true', otherwise the size will shrink when performing undo actions.
 * It is not allowed to use these functions while an undo/redo action is
 * performed, TCL_ERROR will be returned in this case.
 *
 * For convenience the functions TkTextUndoResetStack, TkTextUndoClearStack,
 * TkTextUndoClearUndoStack, and TkTextUndoClearRedoStack, are allowing
 * NULL arguments.
 */

int TkTextUndoSetMaxStackDepth(TkTextUndoStack stack,
    unsigned maxUndoDepth, int maxRedoDepth);
int TkTextUndoSetMaxStackSize(TkTextUndoStack stack,
    unsigned maxSize, int applyImmediately);
int TkTextUndoResetStack(TkTextUndoStack stack);
int TkTextUndoClearStack(TkTextUndoStack stack);
int TkTextUndoClearUndoStack(TkTextUndoStack stack);
int TkTextUndoClearRedoStack(TkTextUndoStack stack);

/*
 * Functions to set/get the context. This is an additional information
 * for the user.
 */

inline void TkTextUndoSetContext(TkTextUndoStack stack, TkTextUndoContext context);
inline TkTextUndoContext TkTextUndoGetContext(const TkTextUndoStack stack);

/*
 * Accessing attributes.
 *
 * The content is irreversible if:
 * 1. The stack has exceeded the depth/size limit when adding undo atoms.
 * 2. Setting a lower limit has caused the deletion of undo atoms.
 * 3. Performing an redo did not push undo items.
 * Clearing the stack is resetting this state to false.
 *
 * The content is modified if undo stack is not empty, or the content
 * is irreversible.
 */

inline unsigned TkTextUndoGetMaxUndoDepth(const TkTextUndoStack stack);
inline int TkTextUndoGetMaxRedoDepth(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetMaxSize(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetCurrentDepth(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetCurrentSize(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetCurrentUndoStackDepth(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetCurrentRedoStackDepth(const TkTextUndoStack stack);
inline unsigned TkTextUndoCountUndoItems(const TkTextUndoStack stack);
inline unsigned TkTextUndoCountRedoItems(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetCurrentUndoSize(const TkTextUndoStack stack);
inline unsigned TkTextUndoGetCurrentRedoSize(const TkTextUndoStack stack);
inline unsigned TkTextUndoCountCurrentUndoItems(const TkTextUndoStack stack);
inline unsigned TkTextUndoCountCurrentRedoItems(const TkTextUndoStack stack);
inline int TkTextUndoContentIsIrreversible(const TkTextUndoStack stack);
inline int TkTextUndoContentIsModified(const TkTextUndoStack stack);
inline int TkTextUndoIsPerformingUndo(const TkTextUndoStack stack);
inline int TkTextUndoIsPerformingRedo(const TkTextUndoStack stack);
inline int TkTextUndoIsPerformingUndoRedo(const TkTextUndoStack stack);
inline const TkTextUndoAtom *TkTextUndoCurrentUndoAtom(const TkTextUndoStack stack);
inline const TkTextUndoAtom *TkTextUndoCurrentRedoAtom(const TkTextUndoStack stack);
inline const TkTextUndoSubAtom *TkTextUndoGetLastUndoSubAtom(const TkTextUndoStack stack);

/*
 * Stack iterator functions.
 */

const TkTextUndoAtom *TkTextUndoFirstUndoAtom(TkTextUndoStack stack);
const TkTextUndoAtom *TkTextUndoNextUndoAtom(TkTextUndoStack stack);
const TkTextUndoAtom *TkTextUndoFirstRedoAtom(TkTextUndoStack stack);
const TkTextUndoAtom *TkTextUndoNextRedoAtom(TkTextUndoStack stack);

/* For convenience these functions are allowing NULL for the stack argument. */
inline int TkTextUndoUndoStackIsFull(const TkTextUndoStack stack);
inline int TkTextUndoRedoStackIsFull(const TkTextUndoStack stack);
int TkTextUndoStackIsFull(const TkTextUndoStack stack);

/*
 * Push the items. Pushing a separator will group items into compound edit
 * actions. Pushing a separator without existing items will be ignored.
 *
 * While an undo/redo action is still in progress pushing separators will be
 * ignored, in this case the undo/action will push automatically a single
 * separator after the action is completed.
 */

int TkTextUndoPushItem(TkTextUndoStack stack, TkTextUndoItem item, unsigned size);
void TkTextUndoPushSeparator(TkTextUndoStack stack, int immediately);

/*
 * Normally redo items will be pushed while undo will be performed. The next function
 * is only useful for the reconstruction of the stack.
 */

int TkTextUndoPushRedoItem(TkTextUndoStack stack, TkTextUndoItem item, unsigned size);

/*
 * Swap newest undo item with given item. Returns the old item. Note that this
 * function does not check whether the maximal undo byte size will be exceeded.
 *
 * Parameter 'size':
 * In: size of given item.
 * Out: size of returned item.
 */

TkTextUndoItem TkTextUndoSwapLastItem(TkTextUndoStack stack, TkTextUndoItem item, unsigned *size);

/*
 * Perform undo/redo operations. Before the action starts a separator will be
 * pushed. Returns an error (TCL_ERROR) if no undo (redo) action is possible.
 */

int TkTextUndoDoUndo(TkTextUndoStack stack);
int TkTextUndoDoRedo(TkTextUndoStack stack);


#define _TK_NEED_IMPLEMENTATION
#include "tkTextUndoPriv.h"
#endif /* _TKTEXTUNDO */
/* vi:set ts=8 sw=4: */

Added generic/tkTextUndoPriv.h.









































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
 * tkTextUndoPriv.h --
 *
 *	Private implementation for undo stack.
 *
 * Copyright (c) 2015-2017 Gregor Cramer
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKTEXTUNDO
# error "do not include this private header file"
#endif

#ifndef _TKTEXTUNDOPRIV
#define _TKTEXTUNDOPRIV

#include <stddef.h>

typedef struct TkTextUndoMyAtom {
    unsigned capacity;
    unsigned undoSize;
    struct TkTextUndoMyAtom* next;
    struct TkTextUndoMyAtom* prev;
    TkTextUndoAtom data;
} TkTextUndoMyAtom;

typedef struct TkTextUndoStack_ {
    TkTextUndoPerformProc *undoProc;
    				/* Function for callback to perform undo/redo actions. */
    TkTextUndoFreeProc *freeProc;
    				/* Function which frees stack items, can be NULL. */
    TkTextUndoStackContentChangedProc *contentChangedProc;
    				/* Function which informs about stack changes. */
    TkTextUndoContext context;	/* User data. */
    TkTextUndoMyAtom *current;	/* Current undo atom (not yet pushed). */
    TkTextUndoMyAtom *root;	/* The root of the undo/redo stack. */
    TkTextUndoMyAtom *last;	/* Last added undo atom. */
    TkTextUndoMyAtom *iter;	/* Current atom in iteration loop. */
    TkTextUndoMyAtom *actual;	/* Current undo/redo atom in processing. */
    int irreversible;		/* Whether undo actions has been released due to limited depth/size. */
    unsigned maxUndoDepth;	/* Maximal depth of the undo stack. */
    int maxRedoDepth;		/* Maximal depth of the redo stack. */
    unsigned maxSize;		/* Maximal size of the stack. */
    unsigned undoDepth;		/* Current depth of undo stack. */
    unsigned redoDepth;		/* Current depth of redo stack. */
    unsigned undoItems;		/* Current number of items on undo stack. */
    unsigned redoItems;		/* Current number of items on redo stack. */
    unsigned undoSize;		/* Total size of undo items. */
    unsigned redoSize;		/* Total size of redo items. */
    int doingUndo;		/* Currently an undo action is performed? */
    int doingRedo;		/* Currently a redo action is performed? */
    int pushSeparator;		/* Push a separator before pushing a new item (iff true). */
} TkTextUndoStack_;

#endif /* _TKTEXTUNDOPRIV */

#ifdef _TK_NEED_IMPLEMENTATION

#include <assert.h>

inline unsigned
TkTextUndoGetMaxUndoDepth(const TkTextUndoStack stack)
{ assert(stack); return stack->maxUndoDepth; }

inline int
TkTextUndoGetMaxRedoDepth(const TkTextUndoStack stack)
{ assert(stack); return stack->maxRedoDepth; }

inline unsigned
TkTextUndoGetMaxSize(const TkTextUndoStack stack)
{ assert(stack); return stack->maxSize; }

inline int
TkTextUndoContentIsModified(const TkTextUndoStack stack)
{ assert(stack); return stack->undoDepth > 0 || stack->irreversible; }

inline int
TkTextUndoContentIsIrreversible(const TkTextUndoStack stack)
{ assert(stack); return stack->irreversible; }

inline int
TkTextUndoIsPerformingUndo(const TkTextUndoStack stack)
{ assert(stack); return stack->doingUndo; }

inline int
TkTextUndoIsPerformingRedo(const TkTextUndoStack stack)
{ assert(stack); return stack->doingRedo; }

inline int
TkTextUndoIsPerformingUndoRedo(const TkTextUndoStack stack)
{ assert(stack); return stack->doingUndo || stack->doingRedo; }

inline int
TkTextUndoUndoStackIsFull(const TkTextUndoStack stack)
{ return !stack || (stack->maxUndoDepth > 0 && stack->undoDepth >= stack->maxUndoDepth); }

inline int
TkTextUndoRedoStackIsFull(const TkTextUndoStack stack)
{ return !stack || (stack->maxRedoDepth >= 0 && (int) stack->redoDepth >= stack->maxRedoDepth); }

inline unsigned
TkTextUndoCountCurrentUndoItems(const TkTextUndoStack stack)
{ assert(stack); return stack->current && !stack->doingUndo ? stack->current->data.arraySize : 0; }

inline unsigned
TkTextUndoCountCurrentRedoItems(const TkTextUndoStack stack)
{ assert(stack); return stack->current && stack->doingUndo ? stack->current->data.arraySize : 0; }

inline unsigned
TkTextUndoGetCurrentUndoStackDepth(const TkTextUndoStack stack)
{ assert(stack); return stack->undoDepth + (TkTextUndoCountCurrentUndoItems(stack) ? 1 : 0); }

inline unsigned
TkTextUndoGetCurrentRedoStackDepth(const TkTextUndoStack stack)
{ assert(stack); return stack->redoDepth + (TkTextUndoCountCurrentRedoItems(stack) ? 1 : 0); }

inline unsigned
TkTextUndoCountUndoItems(const TkTextUndoStack stack)
{ assert(stack); return stack->undoItems + TkTextUndoCountCurrentUndoItems(stack); }

inline unsigned
TkTextUndoCountRedoItems(const TkTextUndoStack stack)
{ assert(stack); return stack->redoItems + TkTextUndoCountCurrentRedoItems(stack); }

inline void
TkTextUndoSetContext(TkTextUndoStack stack, TkTextUndoContext context)
{ assert(stack); stack->context = context; }

inline TkTextUndoContext
TkTextUndoGetContext(const TkTextUndoStack stack)
{ assert(stack); return stack->context; }

inline unsigned
TkTextUndoGetCurrentDepth(
    const TkTextUndoStack stack)
{
    assert(stack);
    return stack->undoDepth + stack->redoDepth +
	    (stack->current && stack->current->data.arraySize > 0 ? 1 : 0);
}

inline unsigned
TkTextUndoGetCurrentUndoSize(
    const TkTextUndoStack stack)
{
    assert(stack);
    return stack->undoSize + (!stack->doingUndo && stack->current ? stack->current->undoSize : 0);
}

inline unsigned
TkTextUndoGetCurrentRedoSize(
    const TkTextUndoStack stack)
{
    assert(stack);
    return stack->redoSize + (!stack->doingRedo && stack->current ? stack->current->undoSize : 0);
}

inline unsigned
TkTextUndoGetCurrentSize(
    const TkTextUndoStack stack)
{
    assert(stack);
    return stack->undoSize + stack->redoSize + (stack->current ? stack->current->undoSize : 0);
}

inline const TkTextUndoAtom *
TkTextUndoCurrentUndoAtom(
    const TkTextUndoStack stack)
{
    assert(stack);

    if (stack->doingUndo) {
	return NULL;
    }
    return stack->current && stack->current->data.arraySize > 0 ? &stack->current->data : NULL;
}

inline const TkTextUndoAtom *
TkTextUndoCurrentRedoAtom(
    const TkTextUndoStack stack)
{
    assert(stack);

    if (stack->doingRedo) {
	return NULL;
    }
    return stack->current && stack->current->data.arraySize > 0 ? &stack->current->data : NULL;
}

inline const TkTextUndoSubAtom *
TkTextUndoGetLastUndoSubAtom(
    const TkTextUndoStack stack)
{
    TkTextUndoAtom *last;

    assert(stack);

    if (stack->current) {
	last = &stack->current->data;
    } else if (stack->last) {
	last = &stack->last->data;
    } else {
	return NULL;
    }
    return last->arraySize > 0 ? last->array + (last->arraySize - 1) : NULL;
}

#undef _TK_NEED_IMPLEMENTATION
#endif /* _TK_NEED_IMPLEMENTATION */
/* vi:set ts=8 sw=4: */

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
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62


63
64
65
66















































67









68
69
70
71
72
73
74

75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105


106
107
108
109
110
111


112
113
114
115


















































































































































































116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

















133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192



193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231
232
233
234


235

236
237
238















239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271





272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

322



323

324
325

326


327






328
329

330

331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354









































































































355
356
357
358
359
360
361
/*
 * 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.

 *
 * 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		EmbWinLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr textGeomType = {
    "text",			/* name */
    EmbWinRequestProc,		/* requestProc */
    EmbWinLostContentProc,	/* lostContentProc */
};

/*
 * Macro that determines the size of an embedded window segment:
 */

#define EW_SEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextEmbWindow))

/*
 * Prototypes for functions defined in this file:
 */

static TkTextSegment *	EmbWinCleanupProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr);
static void		EmbWinCheckProc(TkTextSegment *segPtr,

			    TkTextLine *linePtr);
static void		EmbWinBboxProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr, int index, int y,
			    int lineHeight, int baseline, int *xPtr,int *yPtr,
			    int *widthPtr, int *heightPtr);
static int		EmbWinConfigure(TkText *textPtr, TkTextSegment *ewPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		EmbWinDelayedUnmap(ClientData clientData);
static int		EmbWinDeleteProc(TkTextSegment *segPtr,
			    TkTextLine *linePtr, int treeGone);
static int		EmbWinLayoutProc(TkText *textPtr,
			    TkTextIndex *indexPtr, TkTextSegment *segPtr,
			    TkSizeT offset, int maxX, TkSizeT maxChars,int noCharsYet,
			    TkWrapMode wrapMode, TkTextDispChunk *chunkPtr);
static void		EmbWinStructureProc(ClientData clientData,


			    XEvent *eventPtr);
static void		EmbWinUndisplayProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr);
static TkTextEmbWindowClient *EmbWinGetClient(const TkText *textPtr,















































			    TkTextSegment *ewPtr);










/*
 * The following structure declares the "embedded window" segment type.
 */

const Tk_SegType tkTextEmbWindowType = {
    "window",			/* name */

    0,				/* leftGravity */
    NULL,			/* splitProc */
    EmbWinDeleteProc,		/* deleteProc */
    EmbWinCleanupProc,		/* cleanupProc */
    NULL,			/* lineChangeProc */
    EmbWinLayoutProc,		/* layoutProc */
    EmbWinCheckProc		/* checkProc */

};

/*
 * Definitions for alignment values:
 */

static const char *const alignStrings[] = {
    "baseline", "bottom", "center", "top", NULL
};

typedef enum {
    ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
} alignMode;

/*
 * Information used for parsing window configuration options:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
	"center", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, align),
	0, alignStrings, 0},
    {TK_OPTION_STRING, "-create", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0},


    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padY), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-stretch", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, stretch), 0, 0, 0},


    {TK_OPTION_WINDOW, "-window", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};



















































































































































































/*
 *--------------------------------------------------------------
 *
 * TkTextWindowCmd --
 *
 *	This function implements the "window" widget command for text widgets.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result or error.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */


















int
TkTextWindowCmd(
    TkText *textPtr,	/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already
				 * parsed this command enough to know that
				 * objv[1] is "window". */
{
    int optionIndex;
    static const char *const windOptionStrings[] = {
	"cget", "configure", "create", "names", NULL
    };
    enum windOptions {
	WIND_CGET, WIND_CONFIGURE, WIND_CREATE, WIND_NAMES
    };
    TkTextSegment *ewPtr;



    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[2], windOptionStrings,
	    sizeof(char *), "window option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum windOptions) optionIndex) {
    case WIND_CGET: {
	TkTextIndex index;
	Tcl_Obj *objPtr;
	TkTextEmbWindowClient *client;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexToSeg(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded window at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Copy over client specific value before querying.
	 */

	client = EmbWinGetClient(textPtr, ewPtr);
	if (client != NULL) {
	    ewPtr->body.ew.tkwin = client->tkwin;
	} else {
	    ewPtr->body.ew.tkwin = NULL;
	}




	objPtr = Tk_GetOptionValue(interp, &ewPtr->body.ew,
		ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin);
	if (objPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, objPtr);

	return TCL_OK;
    }
    case WIND_CONFIGURE: {
	TkTextIndex index;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexToSeg(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded window at index \"%s\"",
		    Tcl_GetString(objv[3])));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL);
	    return TCL_ERROR;
	}
	if (objc <= 5) {
	    TkTextEmbWindowClient *client;
	    Tcl_Obj *objPtr;



	    /*
	     * Copy over client specific value before querying.
	     */

	    client = EmbWinGetClient(textPtr, ewPtr);
	    if (client != NULL) {
		ewPtr->body.ew.tkwin = client->tkwin;
	    } else {
		ewPtr->body.ew.tkwin = NULL;
	    }

	    objPtr = Tk_GetOptionInfo(interp, &ewPtr->body.ew,


		    ewPtr->body.ew.optionTable, (objc == 5) ? objv[4] : NULL,

		    textPtr->tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;















	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	} else {
	    TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);

	    /*
	     * It's probably not true that all window configuration can change
	     * the line height, so we could be more efficient here and only
	     * call this when necessary.
	     */

	    TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
		    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
	    return EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4);
	}
    }
    case WIND_CREATE: {

	TkTextIndex index;
	int lineIndex;
	TkTextEmbWindowClient *client;
	int res;

	/*
	 * Add a new window. Find where to put the new window, and mark that
	 * position for redisplay.
	 */

	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;
	}

	/*
	 * Don't allow insertions on the last (dummy) line of the text.
	 */

	lineIndex = TkBTreeLinesTo(textPtr, index.linePtr);
	if (lineIndex == TkBTreeNumLines(textPtr->sharedTextPtr->tree,
		textPtr)) {
	    lineIndex--;
	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
		    lineIndex, 1000000, &index);
	}

	/*
	 * Create the new window segment and initialize it.
	 */

	ewPtr = (TkTextSegment *)ckalloc(EW_SEG_SIZE);
	ewPtr->typePtr = &tkTextEmbWindowType;
	ewPtr->size = 1;
	ewPtr->body.ew.sharedTextPtr = textPtr->sharedTextPtr;
	ewPtr->body.ew.linePtr = NULL;
	ewPtr->body.ew.tkwin = NULL;
	ewPtr->body.ew.create = NULL;
	ewPtr->body.ew.align = ALIGN_CENTER;
	ewPtr->body.ew.padX = ewPtr->body.ew.padY = 0;
	ewPtr->body.ew.stretch = 0;
	ewPtr->body.ew.optionTable = Tk_CreateOptionTable(interp, optionSpecs);

	client = (TkTextEmbWindowClient *)ckalloc(sizeof(TkTextEmbWindowClient));
	client->next = NULL;
	client->textPtr = textPtr;
	client->tkwin = NULL;
	client->chunkCount = 0;
	client->displayed = 0;
	client->parent = ewPtr;
	ewPtr->body.ew.clients = client;

	/*
	 * Link the segment into the text widget, then configure it (delete it
	 * again if the configuration fails).
	 */

	TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);
	TkBTreeLinkSegment(ewPtr, &index);
	res = EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4);
	client->tkwin = ewPtr->body.ew.tkwin;
	if (res != TCL_OK) {

	    TkTextIndex index2;





	    TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
	    TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index,

		    &index2);


	    return TCL_ERROR;






	}
	TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,

		index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);

	break;
    }
    case WIND_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->windowTable,

		&search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr),
		    -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    }
    return TCL_OK;
}










































































































/*
 *--------------------------------------------------------------
 *
 * EmbWinConfigure --
 *
 *	This function is called to handle configuration options for an







|
|
>







>
>
>
>
>
>
>
>
>






<
|
<
|







<
<
<
<
<
<
<




<
<
|
>
|

|


|

|
|
<
|
|
|
|
|
>
>
|
|
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>







>
|
<

|
<

|
>




















|
<


>
>






>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

|













>
>








>










|


|


|
<








|
<





>
>
>
|
|
|
|
|
|
>









|


|


|
<






>
>





|
<





|
>
>
|
>

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<
|
<
<
<
<
<
<
<
<
|



>

<












|
>
>
>
>
>




|


<
<
<
|
|
<






<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|






<
|
|


>
|
>
>
>
|
>
|
|
>
|
>
>
|
>
>
>
>
>
>
|
|
>
|
>












|
>
|

|
<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33

34
35
36
37
38
39
40
41







42
43
44
45


46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520








521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551



552
553

554
555
556
557
558
559











560







561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
/*
 * 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 © 1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2015-2017 Gregor Cramer
 *
 * 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"
#include "tkTextTagSet.h"
#include "tkTextUndo.h"
#include <assert.h>

#ifdef NDEBUG
# define DEBUG(expr)
#else
# define DEBUG(expr) expr
#endif

/*
 * The following structure is the official type record for the embedded window
 * geometry manager:
 */


static void EmbWinRequestProc(void *clientData, Tk_Window tkwin);

static void EmbWinLostContentProc(void *clientData, Tk_Window tkwin);

static const Tk_GeomMgr textGeomType = {
    "text",			/* name */
    EmbWinRequestProc,		/* requestProc */
    EmbWinLostContentProc,	/* lostContentProc */
};








/*
 * Prototypes for functions defined in this file:
 */



static void		EmbWinCheckProc(const TkSharedText *sharedTextPtr, const TkTextSegment *segPtr);
static Tcl_Obj *	EmbWinInspectProc(const TkSharedText *sharedTextPtr,
			    const TkTextSegment *segPtr);
static void		EmbWinBboxProc(TkText *textPtr,
			    TkTextDispChunk *chunkPtr, Tcl_Size index, int y,
			    int lineHeight, int baseline, int *xPtr,int *yPtr,
			    int *widthPtr, int *heightPtr);
static int		EmbWinConfigure(TkText *textPtr, TkTextSegment *ewPtr, int undoable,
			    int objc, Tcl_Obj *const objv[]);
static void		EmbWinDelayedUnmap(void *clientData);
static int		EmbWinDeleteProc(TkSharedText *sharedTextPtr, TkTextSegment *segPtr, int flags);

static int		EmbWinRestoreProc(TkSharedText *sharedTextPtr, TkTextSegment *segPtr);
static int		EmbWinLayoutProc(const TkTextIndex *indexPtr, TkTextSegment *segPtr,
			    Tcl_Size offset, int maxX, Tcl_Size maxChars, int noCharsYet,
			    TkWrapMode wrapMode, TkTextSpaceMode spaceMode, TkTextDispChunk *chunkPtr);
static void		EmbWinStructureProc(void *clientData, XEvent *eventPtr);
static void	        EmbWinDisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr,
                            int x, int y, int lineHeight, int baseline, Display *display,
			    Drawable dst, int screenY);
static void		EmbWinUndisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr);

static TkTextEmbWindowClient *EmbWinGetClient(const TkText *textPtr, TkTextSegment *ewPtr);
static TkTextSegment *	MakeWindow(TkText *textPtr);
static void		ReleaseEmbeddedWindow(TkTextSegment *ewPtr);
static void		DestroyOrUnmapWindow(TkTextSegment *ewPtr);

static const TkTextDispChunkProcs layoutWindowProcs = {
    TEXT_DISP_WINDOW,		/* type */
    EmbWinDisplayProc,	        /* displayProc */
    EmbWinUndisplayProc,        /* undisplayProc */
    NULL,	                /* measureProc */
    EmbWinBboxProc,	        /* bboxProc */
};

/*
 * We need some private undo/redo stuff.
 */

static void UndoLinkSegmentPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void RedoLinkSegmentPerform(TkSharedText *, TkTextUndoInfo *, TkTextUndoInfo *, int);
static void UndoLinkSegmentDestroy(TkSharedText *, TkTextUndoToken *, int);
static void UndoLinkSegmentGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static void RedoLinkSegmentGetRange(const TkSharedText *, const TkTextUndoToken *,
	TkTextIndex *, TkTextIndex *);
static Tcl_Obj *UndoLinkSegmentGetCommand(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *UndoLinkSegmentInspect(const TkSharedText *, const TkTextUndoToken *);
static Tcl_Obj *RedoLinkSegmentInspect(const TkSharedText *, const TkTextUndoToken *);

static const Tk_UndoType undoTokenLinkSegmentType = {
    TK_TEXT_UNDO_WINDOW,	/* action */
    UndoLinkSegmentGetCommand,	/* commandProc */
    UndoLinkSegmentPerform,	/* undoProc */
    UndoLinkSegmentDestroy,	/* destroyProc */
    UndoLinkSegmentGetRange,	/* rangeProc */
    UndoLinkSegmentInspect	/* inspectProc */
};

static const Tk_UndoType redoTokenLinkSegmentType = {
    TK_TEXT_REDO_WINDOW,	/* action */
    UndoLinkSegmentGetCommand,	/* commandProc */
    RedoLinkSegmentPerform,	/* undoProc */
    UndoLinkSegmentDestroy,	/* destroyProc */
    RedoLinkSegmentGetRange,	/* rangeProc */
    RedoLinkSegmentInspect	/* inspectProc */
};

typedef struct UndoTokenLinkSegment {
    const Tk_UndoType *undoType;
    TkTextSegment *segPtr;
    TkTextEmbWindowClient *client;
} UndoTokenLinkSegment;

typedef struct RedoTokenLinkSegment {
    const Tk_UndoType *undoType;
    TkTextSegment *segPtr;
    TkTextEmbWindowClient *client;
    TkTextUndoIndex index;
} RedoTokenLinkSegment;

/*
 * The following structure declares the "embedded window" segment type.
 */

const Tk_SegType tkTextEmbWindowType = {
    "window",			/* name */
    SEG_GROUP_WINDOW,		/* group */
    GRAVITY_NEUTRAL,		/* leftGravity */

    EmbWinDeleteProc,		/* deleteProc */
    EmbWinRestoreProc,		/* restoreProc */

    EmbWinLayoutProc,		/* layoutProc */
    EmbWinCheckProc,		/* checkProc */
    EmbWinInspectProc		/* inspectProc */
};

/*
 * Definitions for alignment values:
 */

static const char *const alignStrings[] = {
    "baseline", "bottom", "center", "top", NULL
};

typedef enum {
    ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
} alignMode;

/*
 * Information used for parsing window configuration options:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
	"center", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, align), 0, alignStrings, 0},

    {TK_OPTION_STRING, "-create", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-owner", NULL, NULL,
	"1", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, isOwner), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padY), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-stretch", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, stretch), 0, 0, 0},
    {TK_OPTION_STRING, "-tags", NULL, NULL,
	NULL, TCL_INDEX_NONE, TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-window", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

DEBUG_ALLOC(extern unsigned tkTextCountNewSegment);
DEBUG_ALLOC(extern unsigned tkTextCountNewUndoToken);

/*
 * Some useful helpers.
 */

static void
TextChanged(
    TkTextIndex *indexPtr)
{
    assert(indexPtr->textPtr);

    TkrTextChanged(NULL, indexPtr->textPtr, indexPtr, indexPtr);

    /*
     * TODO: It's probably not true that all window configuration can change
     * the line height, so we could be more efficient here and only call this
     * when necessary.
     */

    TkTextInvalidateLineMetrics(NULL, indexPtr->textPtr,
	    TkTextIndexGetLine(indexPtr), 0, TK_TEXT_INVALIDATE_ONLY);
}

/*
 * Some functions for the undo/redo mechanism.
 */

static void
GetIndex(
    const TkSharedText *sharedTextPtr,
    TkTextSegment *segPtr,
    TkTextIndex *indexPtr)
{
    TkTextIndexClear2(indexPtr, NULL, sharedTextPtr->tree);
    TkTextIndexSetSegment(indexPtr, segPtr);
}

static Tcl_Obj *
UndoLinkSegmentGetCommand(
    TCL_UNUSED(const TkSharedText *),
    TCL_UNUSED(const TkTextUndoToken *))
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("window", TCL_INDEX_NONE));
    return objPtr;
}

static Tcl_Obj *
UndoLinkSegmentInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const UndoTokenLinkSegment *token = (const UndoTokenLinkSegment *) item;
    Tcl_Obj *objPtr = UndoLinkSegmentGetCommand(sharedTextPtr, item);
    char buf[TK_POS_CHARS];
    TkTextIndex index;

    GetIndex(sharedTextPtr, token->segPtr, &index);
    TkTextIndexPrint(sharedTextPtr, NULL, &index, buf);
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
    return objPtr;
}

static void
UndoLinkSegmentPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    TCL_UNUSED(int))
{
    const UndoTokenLinkSegment *token = (const UndoTokenLinkSegment *) undoInfo->token;
    TkTextSegment *segPtr = token->segPtr;
    TkTextIndex index;

    if (redoInfo) {
	RedoTokenLinkSegment *redoToken;
	redoToken = (RedoTokenLinkSegment *)ckalloc(sizeof(RedoTokenLinkSegment));
	redoToken->undoType = &redoTokenLinkSegmentType;
	redoToken->client = token->client;
	TkBTreeMakeUndoIndex(sharedTextPtr, segPtr, &redoToken->index);
	redoInfo->token = (TkTextUndoToken *) redoToken;
	(redoToken->segPtr = segPtr)->refCount += 1;
	DEBUG_ALLOC(tkTextCountNewUndoToken++);
    }

    GetIndex(sharedTextPtr, segPtr, &index);
    index.textPtr = token->client->textPtr;
    TextChanged(&index);
    TkBTreeUnlinkSegment(sharedTextPtr, segPtr);
    EmbWinDeleteProc(sharedTextPtr, segPtr, 0);
    TK_BTREE_DEBUG(TkBTreeCheck(sharedTextPtr->tree));
}

static void
UndoLinkSegmentDestroy(
    TCL_UNUSED(TkSharedText *),
    TkTextUndoToken *item,
    int reused)
{
    if (!reused) {
	UndoTokenLinkSegment *token = (UndoTokenLinkSegment *) item;

	if (--token->segPtr->refCount == 0) {
	    ReleaseEmbeddedWindow(token->segPtr);
	}
    }
}

static void
UndoLinkSegmentGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    const UndoTokenLinkSegment *token = (const UndoTokenLinkSegment *) item;

    GetIndex(sharedTextPtr, token->segPtr, startIndex);
    *endIndex = *startIndex;
}

static Tcl_Obj *
RedoLinkSegmentInspect(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item)
{
    const RedoTokenLinkSegment *token = (const RedoTokenLinkSegment *) item;
    Tcl_Obj *objPtr = EmbWinInspectProc(sharedTextPtr, token->segPtr);
    char buf[TK_POS_CHARS];
    TkTextIndex index;
    Tcl_Obj *idxPtr;

    TkBTreeUndoIndexToIndex(sharedTextPtr, &token->index, &index);
    TkTextIndexPrint(sharedTextPtr, NULL, &index, buf);
    idxPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
    Tcl_ListObjReplace(NULL, objPtr, 1, 0, 1, &idxPtr);
    return objPtr;
}

static void
RedoLinkSegmentPerform(
    TkSharedText *sharedTextPtr,
    TkTextUndoInfo *undoInfo,
    TkTextUndoInfo *redoInfo,
    TCL_UNUSED(int))
{
    RedoTokenLinkSegment *token = (RedoTokenLinkSegment *) undoInfo->token;
    TkTextIndex index;

    TkBTreeReInsertSegment(sharedTextPtr, &token->index, token->segPtr);

    if (redoInfo) {
	redoInfo->token = undoInfo->token;
	token->undoType = &undoTokenLinkSegmentType;
    }

    GetIndex(sharedTextPtr, token->segPtr, &index);
    index.textPtr = token->client->textPtr;
    TextChanged(&index);
    token->segPtr->refCount += 1;
    TK_BTREE_DEBUG(TkBTreeCheck(sharedTextPtr->tree));
}

static void
RedoLinkSegmentGetRange(
    const TkSharedText *sharedTextPtr,
    const TkTextUndoToken *item,
    TkTextIndex *startIndex,
    TkTextIndex *endIndex)
{
    const RedoTokenLinkSegment *token = (const RedoTokenLinkSegment *) item;
    TkBTreeUndoIndexToIndex(sharedTextPtr, &token->index, startIndex);
    *endIndex = *startIndex;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextWindowCmd --
 *
 *	This function implements the "window" widget command for text widgets.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result or error.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
MatchTagsOption(
    const char *opt)
{
    static const char *pattern = "-tags";
    const char *p = pattern;
    const char *start = opt;

    for ( ; *opt; ++p, ++opt) {
	if (*p != *opt) {
	    return opt > start && *p == '\0';
	}
    }

    return 1;
}

int
TkTextWindowCmd(
    TkText *textPtr,		/* Information about text widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. Someone else has already
				 * parsed this command enough to know that
				 * objv[1] is "window". */
{
    int optionIndex;
    static const char *const windOptionStrings[] = {
	"cget", "configure", "create", "names", NULL
    };
    enum windOptions {
	WIND_CGET, WIND_CONFIGURE, WIND_CREATE, WIND_NAMES
    };
    TkTextSegment *ewPtr;

    assert(textPtr);

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[2], windOptionStrings,
	    sizeof(char *), "window option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum windOptions) optionIndex) {
    case WIND_CGET: {
	TkTextIndex index;
	Tcl_Obj *objPtr;
	TkTextEmbWindowClient *client;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index option");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[3], &index)) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexGetContentSegment(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded window at index \"%s\"", Tcl_GetString(objv[3])));

	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Copy over client specific value before querying.
	 */

	if ((client = EmbWinGetClient(textPtr, ewPtr))) {

	    ewPtr->body.ew.tkwin = client->tkwin;
	} else {
	    ewPtr->body.ew.tkwin = NULL;
	}

	if (MatchTagsOption(Tcl_GetString(objv[4]))) {
	    TkTextFindTags(interp, textPtr, ewPtr, 1);
	} else {
	    objPtr = Tk_GetOptionValue(interp, (char *) &ewPtr->body.ew,
		    ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin);
	    if (!objPtr) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	}
	return TCL_OK;
    }
    case WIND_CONFIGURE: {
	TkTextIndex index;

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[3], &index)) {
	    return TCL_ERROR;
	}
	ewPtr = TkTextIndexGetContentSegment(&index, NULL);
	if (ewPtr->typePtr != &tkTextEmbWindowType) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no embedded window at index \"%s\"", Tcl_GetString(objv[3])));

	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL);
	    return TCL_ERROR;
	}
	if (objc <= 5) {
	    TkTextEmbWindowClient *client;
	    Tcl_Obj *objPtr;
	    Tcl_Obj **objs;
	    Tcl_Size objn = 0, i;

	    /*
	     * Copy over client specific value before querying.
	     */

	    if ((client = EmbWinGetClient(textPtr, ewPtr))) {

		ewPtr->body.ew.tkwin = client->tkwin;
	    } else {
		ewPtr->body.ew.tkwin = NULL;
	    }

	    objPtr = Tk_GetOptionInfo(
		    interp,
		    &ewPtr->body.ew,
		    ewPtr->body.ew.optionTable,
		    objc == 5 ? objv[4] : NULL,
		    textPtr->tkwin);
	    if (!objPtr) {
		return TCL_ERROR;
	    }
	    Tcl_ListObjGetElements(NULL, objPtr, &objn, &objs);
	    for (i = 0; i < objn; ++i) {
		Tcl_Obj **objv1;
		Tcl_Size objc1 = 0;

		Tcl_ListObjGetElements(NULL, objs[i], &objc1, &objv1);
		if (objc1 == 5 && strcmp(Tcl_GetString(objv1[0]), "-tags") == 0) {
		    Tcl_Obj *valuePtr;

		    /* { argvName, dbName, dbClass, defValue, current value } */
		    TkTextFindTags(interp, textPtr, ewPtr, 1);
		    valuePtr = Tcl_GetObjResult(interp);
		    Tcl_ListObjReplace(NULL, objs[i], 4, 1, 1, &valuePtr);
		}
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	} else {

	    TextChanged(&index);








	    return EmbWinConfigure(textPtr, ewPtr, 1, objc - 4, objv + 4);
	}
    }
    case WIND_CREATE: {
	TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
	TkTextIndex index;

	TkTextEmbWindowClient *client;
	int res;

	/*
	 * Add a new window. Find where to put the new window, and mark that
	 * position for redisplay.
	 */

	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?");
	    return TCL_ERROR;
	}
	if (!TkTextGetIndexFromObj(interp, textPtr, objv[3], &index)) {
	    return TCL_ERROR;
	}

	if (textPtr->state == TK_TEXT_STATE_DISABLED &&
		TkTextAttemptToModifyDisabledWidget(interp) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * Don't allow insertions on the last line of the text.
	 */




	if (!TkTextIndexEnsureBeforeLastChar(&index)) {
	    return TkTextAttemptToModifyDeadWidget(interp);

	}

	/*
	 * Create the new window segment and initialize it.
	 */












	ewPtr = MakeWindow(textPtr);







	client = ewPtr->body.ew.clients;

	/*
	 * Link the segment into the text widget, then configure it (delete it
	 * again if the configuration fails).
	 */


	TkBTreeLinkSegment(sharedTextPtr, ewPtr, &index);
	res = EmbWinConfigure(textPtr, ewPtr, 0, objc - 4, objv + 4);
	client->tkwin = ewPtr->body.ew.tkwin;
	if (res != TCL_OK) {
	    TkBTreeUnlinkSegment(sharedTextPtr, ewPtr);
	    TkTextWinFreeClient(NULL, client);
	    ewPtr->body.ew.clients = NULL;
	    ReleaseEmbeddedWindow(ewPtr);
	    return TCL_ERROR;
	}
	TextChanged(&index);

	if (!TkTextUndoStackIsFull(sharedTextPtr->undoStack)) {
	    UndoTokenLinkSegment *token;

	    assert(sharedTextPtr->undoStack);
	    assert(ewPtr->typePtr == &tkTextEmbWindowType);

	    token = (UndoTokenLinkSegment *)ckalloc(sizeof(UndoTokenLinkSegment));
	    token->undoType = &undoTokenLinkSegmentType;
	    token->segPtr = ewPtr;
	    token->client = client;
	    ewPtr->refCount += 1;
	    DEBUG_ALLOC(tkTextCountNewUndoToken++);

	    TkTextPushUndoToken(sharedTextPtr, token, 0);
	}

	TkTextUpdateAlteredFlag(sharedTextPtr);
	break;
    }
    case WIND_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->windowTable, &search);
		hPtr;
		hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    (const char *)Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr), TCL_INDEX_NONE));

	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MakeWindow --
 *
 *	This function is called to create a window segment.
 *
 * Results:
 *	The return value is the newly created window.
 *
 * Side effects:
 *	Some memory will be allocated.
 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
MakeWindow(
    TkText *textPtr)		/* Information about text widget that contains embedded image. */
{
    TkTextSegment *ewPtr;
    TkTextEmbWindowClient *client;

    ewPtr = (TkTextSegment *)ckalloc(SEG_SIZE(TkTextEmbWindow));
    memset(ewPtr, 0, SEG_SIZE(TkTextEmbWindow))
    NEW_SEGMENT(ewPtr);
    ewPtr->typePtr = &tkTextEmbWindowType;
    ewPtr->size = 1;
    ewPtr->refCount = 1;
    ewPtr->body.ew.sharedTextPtr = textPtr->sharedTextPtr;
    ewPtr->body.ew.align = ALIGN_CENTER;
    ewPtr->body.ew.isOwner = 1;
    ewPtr->body.ew.optionTable = Tk_CreateOptionTable(textPtr->interp, optionSpecs);
    DEBUG_ALLOC(tkTextCountNewSegment++);

    client = (TkTextEmbWindowClient *)ckalloc(sizeof(TkTextEmbWindowClient));
    memset(client, 0, sizeof(TkTextEmbWindowClient));
    client->textPtr = textPtr;
    client->parent = ewPtr;
    ewPtr->body.ew.clients = client;

    return ewPtr;
}

/*
 *--------------------------------------------------------------
 *
 * TkTextMakeWindow --
 *
 *	This function is called to create a window segment.
 *
 * Results:
 *	The return value is a standard Tcl result. If TCL_ERROR is returned,
 *	then the interp's result contains an error message.
 *
 * Side effects:
 *	Some memory will be allocated.
 *
 *--------------------------------------------------------------
 */

TkTextSegment *
TkTextMakeWindow(
    TkText *textPtr,		/* Information about text widget that contains embedded window. */
    Tcl_Obj *options)		/* Options for this window. */
{
    TkTextSegment *ewPtr;
    Tcl_Obj **objv;
    Tcl_Obj **argv;
    Tcl_Size objc, i;

    assert(options);

    if (Tcl_ListObjGetElements(textPtr->interp, options, &objc, &objv) != TCL_OK) {
	return NULL;
    }

    argv = (Tcl_Obj **)ckalloc(objc*sizeof(argv[0]));
    memcpy(argv, objv, objc*sizeof(argv[0]));
    for (i = 0; i < objc; i += 2) {
	if (strncmp(Tcl_GetString(argv[i]), "-w", 2) == 0) {
	    if (!Tk_NameToWindow(textPtr->interp, Tcl_GetString(argv[i + 1]), textPtr->tkwin)) {
		/*
		 * The specified window (given with option -window) does not exist, so
		 * set the value to NULL.
		 */
		argv[i + 1] = NULL;
	    }
	}
    }

    ewPtr = MakeWindow(textPtr);

    if (EmbWinConfigure(textPtr, ewPtr, 0, objc, argv) == TCL_OK) {
	Tcl_ResetResult(textPtr->interp);
    } else {
	TkTextWinFreeClient(NULL, ewPtr->body.ew.clients);
	ewPtr->body.ew.clients = NULL;
	ReleaseEmbeddedWindow(ewPtr);
	ewPtr = NULL;
    }

    return ewPtr;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinConfigure --
 *
 *	This function is called to handle configuration options for an
372
373
374
375
376
377
378


























379
380
381
382
383
384

385
386
387
388
389
390



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409






410
411

412
413
414


415
416
417
418
419
420
421
422





423


424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444






445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496

497

498
499
500
501
502
503
504
 *	Note that this function may leave widget specific client information
 *	with a NULL tkwin attached to ewPtr. While we could choose to clean up
 *	the client data structure here, there is no need to do so, and it is
 *	likely that the user is going to adjust the tkwin again soon.
 *
 *--------------------------------------------------------------
 */



























static int
EmbWinConfigure(
    TkText *textPtr,		/* Information about text widget that contains
				 * embedded window. */
    TkTextSegment *ewPtr,	/* Embedded window to be configured. */

    int objc,			/* Number of strings in objv. */
    Tcl_Obj *const objv[])	/* Array of objects describing configuration
				 * options. */
{
    Tk_Window oldWindow;
    TkTextEmbWindowClient *client;




    /*
     * Copy over client specific value before querying or setting.
     */

    client = EmbWinGetClient(textPtr, ewPtr);
    if (client != NULL) {
	ewPtr->body.ew.tkwin = client->tkwin;
    } else {
	ewPtr->body.ew.tkwin = NULL;
    }

    oldWindow = ewPtr->body.ew.tkwin;
    if (Tk_SetOptions(textPtr->interp, &ewPtr->body.ew,
	    ewPtr->body.ew.optionTable, objc, objv, textPtr->tkwin, NULL,
	    NULL) != TCL_OK) {
	return TCL_ERROR;
    }







    if (oldWindow != ewPtr->body.ew.tkwin) {
	if (oldWindow != NULL) {

	    Tcl_DeleteHashEntry(Tcl_FindHashEntry(
		    &textPtr->sharedTextPtr->windowTable,
		    Tk_PathName(oldWindow)));


	    Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
		    EmbWinStructureProc, client);
	    Tk_ManageGeometry(oldWindow, NULL, NULL);
	    if (textPtr->tkwin != Tk_Parent(oldWindow)) {
		Tk_UnmaintainGeometry(oldWindow, textPtr->tkwin);
	    } else {
		Tk_UnmapWindow(oldWindow);
	    }





	}


	if (client != NULL) {
	    client->tkwin = NULL;

	}
	if (ewPtr->body.ew.tkwin != NULL) {
	    Tk_Window ancestor, parent;
	    Tcl_HashEntry *hPtr;
	    int isNew;

	    /*
	     * Make sure that the text is either the parent of the embedded
	     * window or a descendant of that parent. Also, don't allow a
	     * top-level window to be managed inside a text.
	     */

	    parent = Tk_Parent(ewPtr->body.ew.tkwin);
	    for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
		if (ancestor == parent) {
		    break;
		}
		if (Tk_TopWinHierarchy(ancestor)) {
		badContainer:






		    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf(
			    "can't embed %s in %s",
			    Tk_PathName(ewPtr->body.ew.tkwin),
			    Tk_PathName(textPtr->tkwin)));
		    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY",
			    "HIERARCHY", NULL);
		    ewPtr->body.ew.tkwin = NULL;
		    if (client != NULL) {
			client->tkwin = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	    if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		    || (ewPtr->body.ew.tkwin == textPtr->tkwin)) {
		goto badContainer;
	    }

	    if (client == NULL) {
		/*
		 * Have to make the new client.
		 */

		client = (TkTextEmbWindowClient *)ckalloc(sizeof(TkTextEmbWindowClient));

		client->next = ewPtr->body.ew.clients;
		client->textPtr = textPtr;
		client->tkwin = NULL;
		client->chunkCount = 0;
		client->displayed = 0;
		client->parent = ewPtr;
		ewPtr->body.ew.clients = client;
	    }
	    client->tkwin = ewPtr->body.ew.tkwin;

	    /*
	     * Take over geometry management for the window, plus create an
	     * event handler to find out when it is deleted.
	     */

	    Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType, client);
	    Tk_CreateEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
		    EmbWinStructureProc, client);

	    /*
	     * Special trick!  Must enter into the hash table *after* calling
	     * Tk_ManageGeometry: if the window was already managed elsewhere
	     * in this text, the Tk_ManageGeometry call will cause the entry
	     * to be removed, which could potentially lose the new entry.
	     */


	    hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->windowTable,
		    Tk_PathName(ewPtr->body.ew.tkwin), &isNew);

	    Tcl_SetHashValue(hPtr, ewPtr);

	}
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>

|
<



>
>
>






<
|
<
|
|
<
<

|
<



>
>
>
>
>
>
|
|
>
|
|
|
>
>
|
<






>
>
>
>
>
|
>
>
|

>

|

|














|
>
>
>
>
>
>
|
<
|
<
|
<
|
|
|
|
|
|
|
<
<
<
<
<
|





>


<
<
<















|





>
|
|
>
|
>







743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
 *	Note that this function may leave widget specific client information
 *	with a NULL tkwin attached to ewPtr. While we could choose to clean up
 *	the client data structure here, there is no need to do so, and it is
 *	likely that the user is going to adjust the tkwin again soon.
 *
 *--------------------------------------------------------------
 */

static int
IsPreservedWindow(
    const TkTextEmbWindowClient *client)
{
    return client && !client->hPtr;
}

static void
TriggerWatchCmd(
    TkText *textPtr,
    TkTextSegment *ewPtr,
    Tk_Window tkwin,
    const char *arg1,
    const char *arg2)
{
    if (!(textPtr->flags & DESTROYED)) {
	TkTextIndex index;
	char buf[TK_POS_CHARS];

	TkTextIndexClear(&index, textPtr);
	TkTextIndexSetSegment(&index, ewPtr);
	TkrTextPrintIndex(textPtr, &index, buf);
	TkTextTriggerWatchCmd(textPtr, "window", buf, buf, Tk_PathName(tkwin), arg1, arg2, 0);
    }
}

static int
EmbWinConfigure(
    TkText *textPtr,		/* Information about text widget that contains
				 * embedded window. */
    TkTextSegment *ewPtr,	/* Embedded window to be configured. */
    int undoable,		/* Replacement of tags is undoable? */
    int objc,			/* Number of strings in objv. */
    Tcl_Obj *const objv[])	/* Array of objects describing configuration options. */

{
    Tk_Window oldWindow;
    TkTextEmbWindowClient *client;
    int i;

    assert(textPtr);

    /*
     * Copy over client specific value before querying or setting.
     */

    client = EmbWinGetClient(textPtr, ewPtr);

    ewPtr->body.ew.tkwin = client ? client->tkwin : NULL;

    oldWindow = ewPtr->body.ew.tkwin;



    if (Tk_SetOptions(textPtr->interp, &ewPtr->body.ew,
	    ewPtr->body.ew.optionTable, objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) {

	return TCL_ERROR;
    }

    for (i = 0; i + 1 < objc; i += 2) {
	if (MatchTagsOption(Tcl_GetString(objv[i]))) {
	    TkTextReplaceTags(textPtr, ewPtr, undoable, objv[i + 1]);
	}
    }

    if (oldWindow != ewPtr->body.ew.tkwin && (!oldWindow || !IsPreservedWindow(client))) {
	if (oldWindow) {
	    Tcl_HashEntry *hPtr;

	    textPtr->sharedTextPtr->numWindows -= 1;
	    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, Tk_PathName(oldWindow));
	    assert(hPtr);
	    Tcl_DeleteHashEntry(hPtr);
	    Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, EmbWinStructureProc, client);

	    Tk_ManageGeometry(oldWindow, NULL, NULL);
	    if (textPtr->tkwin != Tk_Parent(oldWindow)) {
		Tk_UnmaintainGeometry(oldWindow, textPtr->tkwin);
	    } else {
		Tk_UnmapWindow(oldWindow);
	    }
	    if (textPtr->watchCmd) {
		textPtr->refCount += 1;
		TriggerWatchCmd(textPtr, ewPtr, oldWindow, NULL, NULL);
		if (TkTextDecrRefCountAndTestIfDestroyed(textPtr)) {
		    return TCL_OK;
		}
	    }
	}
	if (client) {
	    client->tkwin = NULL;
	    client->hPtr = NULL;
	}
	if (ewPtr->body.ew.tkwin) {
	    Tk_Window ancestor, parent;
	    int cantEmbed = 0;
	    int isNew;

	    /*
	     * Make sure that the text is either the parent of the embedded
	     * window or a descendant of that parent. Also, don't allow a
	     * top-level window to be managed inside a text.
	     */

	    parent = Tk_Parent(ewPtr->body.ew.tkwin);
	    for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
		if (ancestor == parent) {
		    break;
		}
		if (Tk_TopWinHierarchy(ancestor)) {
		    cantEmbed = 1;
		    break;
		}
	    }
	    if (cantEmbed
		    || Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		    || (ewPtr->body.ew.tkwin == textPtr->tkwin)) {
		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) {
		    client->tkwin = NULL;
		}
		return TCL_ERROR;
	    }






	    if (!client) {
		/*
		 * Have to make the new client.
		 */

		client = (TkTextEmbWindowClient *)ckalloc(sizeof(TkTextEmbWindowClient));
		memset(client, 0, sizeof(TkTextEmbWindowClient));
		client->next = ewPtr->body.ew.clients;
		client->textPtr = textPtr;



		client->parent = ewPtr;
		ewPtr->body.ew.clients = client;
	    }
	    client->tkwin = ewPtr->body.ew.tkwin;

	    /*
	     * Take over geometry management for the window, plus create an
	     * event handler to find out when it is deleted.
	     */

	    Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType, client);
	    Tk_CreateEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
		    EmbWinStructureProc, client);

	    /*
	     * Special trick! Must enter into the hash table *after* calling
	     * Tk_ManageGeometry: if the window was already managed elsewhere
	     * in this text, the Tk_ManageGeometry call will cause the entry
	     * to be removed, which could potentially lose the new entry.
	     */

	    client->hPtr = Tcl_CreateHashEntry(
		    &textPtr->sharedTextPtr->windowTable,
		    Tk_PathName(ewPtr->body.ew.tkwin),
		    &isNew);
	    Tcl_SetHashValue(client->hPtr, ewPtr);
	    textPtr->sharedTextPtr->numWindows += 1;
	}
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535




536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552

553

554
555
556
557
558
559
560
 *	of the text is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;
    Tcl_HashEntry *hPtr;

    if (eventPtr->type != DestroyNotify) {
	return;
    }





    hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
	    Tk_PathName(client->tkwin));
    if (hPtr != NULL) {
	/*
	 * This may not exist if the entire widget is being deleted.
	 */

	Tcl_DeleteHashEntry(hPtr);
    }

    ewPtr->body.ew.tkwin = NULL;
    client->tkwin = NULL;
    index.tree = ewPtr->body.ew.sharedTextPtr->tree;
    index.linePtr = ewPtr->body.ew.linePtr;
    index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
    TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,

	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);

}

/*
 *--------------------------------------------------------------
 *
 * EmbWinRequestProc --
 *







|



|
|
<

|



>
>
>
>
|
|
|
|
|
|

|
<
|


<
|
<
|
|
>
|
>







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
 *	of the text is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinStructureProc(
    void *clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr;
    Tk_Window tkwin;


    if (eventPtr->type != DestroyNotify || !client->hPtr) {
	return;
    }

    ewPtr = client->parent;
    tkwin = client->tkwin;

    assert(ewPtr->typePtr);
    assert(client->hPtr == Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
	    Tk_PathName(tkwin)));

    /*
     * This may not exist if the entire widget is being deleted.
     */

    Tcl_DeleteHashEntry(client->hPtr);

    ewPtr->body.ew.sharedTextPtr->numWindows -= 1;
    ewPtr->body.ew.tkwin = NULL;
    client->tkwin = NULL;

    client->hPtr = NULL;

    EmbWinRequestProc(client, NULL);

    if (client->textPtr->watchCmd) {
	TriggerWatchCmd(client->textPtr, ewPtr, tkwin, NULL, NULL);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinRequestProc --
 *
569
570
571
572
573
574
575
576
577
578
579
580
581
582


583

584

585


586
587


588


589
590
591
592
593
594
595
 *	depending on the options specified for the window item.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;



    index.tree = ewPtr->body.ew.sharedTextPtr->tree;

    index.linePtr = ewPtr->body.ew.linePtr;

    index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);


    TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,


	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);


}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLostContentProc --
 *







|
|





>
>
|
>
|
>
|
>
>
|
|
>
>
|
>
>







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
 *	depending on the options specified for the window item.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinRequestProc(
    void *clientData,	/* Pointer to record for window item. */
    TCL_UNUSED(Tk_Window))	/* Window that changed its desired size. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;
    TkTextIndex index;

    assert(ewPtr->typePtr);
    assert(ewPtr->sectionPtr);

    TkTextIndexClear(&index, client->textPtr);

    /*
	* ewPtr->body.ew.tkwin == NULL means the embedded window is already
	* destroyed. The ewPtr segment is no longer linked.
	*/

    if (ewPtr->body.ew.tkwin) {
	TkTextIndexSetSegment(&index, ewPtr);
    } else {
	TkTextIndexSetByteIndex2(&index, ewPtr->sectionPtr->linePtr, 0);
    }
    TextChanged(&index);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLostContentProc --
 *
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620
621




622
623
624

625
626
627
628
629
630
631
632


633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

656

657
658
659
660
661
662
663
 *	of the text is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinLostContentProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    Tk_Window tkwin)		/* Window that was claimed away by another
				 * geometry manager. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;
    TkTextSegment *ewPtr = client->parent;

    TkTextIndex index;
    Tcl_HashEntry *hPtr;
    TkTextEmbWindowClient *loop;





    Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask,
	    EmbWinStructureProc, client);
    Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);

    if (client->textPtr->tkwin != Tk_Parent(tkwin)) {
	Tk_UnmaintainGeometry(tkwin, client->textPtr->tkwin);
    } else {
	Tk_UnmapWindow(tkwin);
    }
    hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
	    Tk_PathName(client->tkwin));
    Tcl_DeleteHashEntry(hPtr);


    client->tkwin = NULL;
    ewPtr->body.ew.tkwin = NULL;

    /*
     * Free up the memory allocation for this client.
     */

    loop = ewPtr->body.ew.clients;
    if (loop == client) {
	ewPtr->body.ew.clients = client->next;
    } else {
	while (loop->next != client) {
	    loop = loop->next;
	}
	loop->next = client->next;
    }
    ckfree(client);

    index.tree = ewPtr->body.ew.sharedTextPtr->tree;
    index.linePtr = ewPtr->body.ew.linePtr;
    index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
    TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,

	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);

}

/*
 *--------------------------------------------------------------
 *
 * TkTextWinFreeClient --
 *







|
|
<



>

<


>
>
>
>
|
<

>
|
<
<
<
<
|
<
|
>
>


















|
|
<
|
|
>
|
>







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
 *	of the text is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinLostContentProc(
    void *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;
    TkText *textPtr = client->textPtr;
    TkTextIndex index;

    TkTextEmbWindowClient *loop;

    assert(!IsPreservedWindow(client));

    assert(client->tkwin);
    client->displayed = 0;
    Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask, EmbWinStructureProc, client);

    Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);
    EmbWinDelayedUnmap(client);
    if (client->hPtr) {




	ewPtr->body.ew.sharedTextPtr->numWindows -= 1;

	Tcl_DeleteHashEntry(client->hPtr);
	client->hPtr = NULL;
    }
    client->tkwin = NULL;
    ewPtr->body.ew.tkwin = NULL;

    /*
     * Free up the memory allocation for this client.
     */

    loop = ewPtr->body.ew.clients;
    if (loop == client) {
	ewPtr->body.ew.clients = client->next;
    } else {
	while (loop->next != client) {
	    loop = loop->next;
	}
	loop->next = client->next;
    }
    ckfree(client);

    TkTextIndexClear(&index, textPtr);
    TkTextIndexSetSegment(&index, ewPtr);

    TextChanged(&index);

    if (textPtr->watchCmd) {
	TriggerWatchCmd(textPtr, ewPtr, tkwin, NULL, NULL);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextWinFreeClient --
 *
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716
717
718
719
720




































































































































721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784

785
786
787
788
789
790

791


792







793



794









795
796
797
798
799
800
801
802
 *	exists, and any resources associated with it are released.
 *
 *--------------------------------------------------------------
 */

void
TkTextWinFreeClient(
    Tcl_HashEntry *hPtr,	/* Hash entry corresponding to this client, or
				 * NULL */
    TkTextEmbWindowClient *client)
				/* Client data structure, with the 'tkwin'
				 * field to be cleaned up. */
{
    if (hPtr != NULL) {
	/*
	 * (It's possible for there to be no hash table entry for this window,
	 * if an error occurred while creating the window segment but before
	 * the window got added to the table)
	 */


	Tcl_DeleteHashEntry(hPtr);
    }

    /*
     * Delete the event handler for the window before destroying the window,
     * so that EmbWinStructureProc doesn't get called (we'll already do
     * everything that it would have done, and it will just get confused).
     */

    if (client->tkwin != NULL) {
	Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask,
		EmbWinStructureProc, client);
	Tk_DestroyWindow(client->tkwin);

    }
    Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);

    /*
     * Free up this client.
     */

    ckfree(client);
}

/*
 *--------------------------------------------------------------
 *




































































































































 * EmbWinDeleteProc --
 *
 *	This function is invoked by the text B-tree code whenever an embedded
 *	window lies in a range of characters being deleted.
 *
 * Results:
 *	Returns 0 to indicate that the deletion has been accepted.
 *
 * Side effects:
 *	The embedded window is deleted, if it exists, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

static int
EmbWinDeleteProc(

    TkTextSegment *ewPtr,	/* Segment being deleted. */
    TCL_UNUSED(TkTextLine *),	/* Line containing segment. */
    TCL_UNUSED(int))		/* Non-zero means the entire tree is being
				 * deleted, so everything must get cleaned
				 * up. */
{
    TkTextEmbWindowClient *client;
    client = ewPtr->body.ew.clients;

    while (client != NULL) {
	TkTextEmbWindowClient *next = client->next;
	Tcl_HashEntry *hPtr = NULL;

	if (client->tkwin != NULL) {
	    hPtr = Tcl_FindHashEntry(
		    &ewPtr->body.ew.sharedTextPtr->windowTable,
		    Tk_PathName(client->tkwin));
	}
	TkTextWinFreeClient(hPtr, client);
	client = next;
    }
    ewPtr->body.ew.clients = NULL;

    Tk_FreeConfigOptions((char *) &ewPtr->body.ew, ewPtr->body.ew.optionTable,
	    NULL);

    /*
     * Free up all memory allocated.
     */

    ckfree(ewPtr);
    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinCleanupProc --
 *
 *	This function is invoked by the B-tree code whenever a segment
 *	containing an embedded window is moved from one line to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The linePtr field of the segment gets updated.

 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
EmbWinCleanupProc(

    TkTextSegment *ewPtr,	/* Mark segment that's being moved. */


    TkTextLine *linePtr)	/* Line that now contains segment. */







{



    ewPtr->body.ew.linePtr = linePtr;









    return ewPtr;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLayoutProc --
 *







|
<

|
<

|






>









|
|
|
|
>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|


|
<






>

<
|
<
<

<
<
|
<
<
<
|
<
<
<
<
|
<
|
<
|
|
|
<
|
<
<
<
|
<
|





|

|
|





|
>




|
|
>
|
>
>
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
|







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
 *	exists, and any resources associated with it are released.
 *
 *--------------------------------------------------------------
 */

void
TkTextWinFreeClient(
    Tcl_HashEntry *hPtr,	/* Hash entry corresponding to this client, or NULL */

    TkTextEmbWindowClient *client)
				/* Client data structure, with the 'tkwin' field to be cleaned up. */

{
    if (hPtr) {
	/*
	 * (It's possible for there to be no hash table entry for this window,
	 * if an error occurred while creating the window segment but before
	 * the window got added to the table)
	 */

	client->parent->body.ew.sharedTextPtr->numWindows -= 1;
	Tcl_DeleteHashEntry(hPtr);
    }

    /*
     * Delete the event handler for the window before destroying the window,
     * so that EmbWinStructureProc doesn't get called (we'll already do
     * everything that it would have done, and it will just get confused).
     */

    if (client->tkwin) {
	Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask, EmbWinStructureProc, client);
	if (client->parent->body.ew.isOwner) {
	    Tk_DestroyWindow(client->tkwin);
	}
    }
    Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);

    /*
     * Free up this client.
     */

    ckfree(client);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinInspectProc --
 *
 *	This function is invoked to build the information for
 *	"inspect".
 *
 * Results:
 *	Return a TCL object containing the information for
 *	"inspect".
 *
 * Side effects:
 *	Storage is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
EmbWinInspectProc(
    const TkSharedText *sharedTextPtr,
    const TkTextSegment *segPtr)
{
    Tcl_Obj *objPtr = Tcl_NewObj();
    Tcl_Obj *objPtr2 = Tcl_NewObj();
    TkTextTag **tagLookup = sharedTextPtr->tagLookup;
    const TkTextTagSet *tagInfoPtr = segPtr->tagInfoPtr;
    unsigned i = TkTextTagSetFindFirst(tagInfoPtr);
    Tcl_DString opts;

    assert(sharedTextPtr->peers);

    for ( ; i != TK_TEXT_TAG_SET_NPOS; i = TkTextTagSetFindNext(tagInfoPtr, i)) {
	const TkTextTag *tagPtr = tagLookup[i];
	Tcl_ListObjAppendElement(NULL, objPtr2, Tcl_NewStringObj(tagPtr->name, TCL_INDEX_NONE));
    }

    Tcl_DStringInit(&opts);
    TkTextInspectOptions(sharedTextPtr->peers, &segPtr->body.ew, segPtr->body.ew.optionTable,
	    &opts, 0);

    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(segPtr->typePtr->name, TCL_INDEX_NONE));
    Tcl_ListObjAppendElement(NULL, objPtr, objPtr2);
    Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(Tcl_DStringValue(&opts),
	    Tcl_DStringLength(&opts)));

    Tcl_DStringFree(&opts);
    return objPtr;
}

/*
 *--------------------------------------------------------------
 *
 * ReleaseEmbeddedWindow --
 *
 *	Free embedded window
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The embedded window is deleted, and any resources
 *	associated with it are released.
 *
 *--------------------------------------------------------------
 */

static void
ReleaseEmbeddedWindow(
    TkTextSegment *ewPtr)
{
    TkTextEmbWindowClient *client = ewPtr->body.ew.clients;

    assert(ewPtr->typePtr);

    while (client) {
	TkTextEmbWindowClient *next = client->next;
	if (client->hPtr) {
	    TkTextWinFreeClient(client->hPtr, client);
	}
	client = next;
    }
    ewPtr->body.ew.clients = NULL;
    Tk_FreeConfigOptions(&ewPtr->body.ew, ewPtr->body.ew.optionTable, NULL);
    TkBTreeFreeSegment(ewPtr);
}

/*
 *--------------------------------------------------------------
 *
 * DestroyOrUnmapWindow --
 *
 *	Unmap all clients of given window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Either destroy or only unmap the embedded window.
 *
 *--------------------------------------------------------------
 */

static void
DestroyOrUnmapWindow(
    TkTextSegment *ewPtr)
{
    TkTextEmbWindowClient *client = ewPtr->body.ew.clients;

    assert(ewPtr->typePtr);
    assert(ewPtr->refCount > 0);

    for ( ; client; client = client->next) {
	if (client->hPtr) {
	    client->parent->body.ew.sharedTextPtr->numWindows -= 1;
	    Tcl_DeleteHashEntry(client->hPtr);
	    client->hPtr = NULL;
	    client->displayed = 0;
	}
	Tcl_CancelIdleCall(EmbWinDelayedUnmap, client);
	if (client->tkwin && ewPtr->body.ew.create) {
	    Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask, EmbWinStructureProc, client);
	    if (ewPtr->body.ew.isOwner) {
		Tk_DestroyWindow(client->tkwin);
	    }
	    client->tkwin = NULL;
	    ewPtr->body.ew.tkwin = NULL;
	} else {
	    EmbWinDelayedUnmap(client);
	}
    }
}
/*
 *--------------------------------------------------------------
 *
 * EmbWinDeleteProc --
 *
 *	This function is invoked by the text B-tree code whenever an embedded
 *	window lies in a range of characters being deleted.
 *
 * Results:
 *	Returns true to indicate that the deletion has been accepted.
 *
 * Side effects:
 *	Depends on the action, see ReleaseEmbeddedWindow and DestroyOrUnmapWindow.

 *
 *--------------------------------------------------------------
 */

static int
EmbWinDeleteProc(
    TCL_UNUSED(TkSharedText *),/* Handle to shared text resource. */
    TkTextSegment *ewPtr,	/* Segment being deleted. */

    TCL_UNUSED(int))			/* Flags controlling the deletion. */


{


    assert(ewPtr->typePtr);



    assert(ewPtr->refCount > 0);






    if (ewPtr->refCount == 1) {

	ReleaseEmbeddedWindow(ewPtr);
    } else {
	ewPtr->refCount -= 1;

	DestroyOrUnmapWindow(ewPtr);



    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinRestoreProc --
 *
 *	This function is called when a window segment will be restored
 *	from the undo chain.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The name of the mark will be freed, and the mark will be
 *	re-entered into the hash table.
 *
 *--------------------------------------------------------------
 */

static int
EmbWinRestoreProc(
    TCL_UNUSED(TkSharedText *),/* Handle to shared text resource. */
    TkTextSegment *ewPtr)	/* Segment to reuse. */
{
    int isNew;

    if (ewPtr->body.ew.create) {
	/*
	 * EmbWinLayoutProc is doing the creation of the window.
	 */
	assert(!ewPtr->body.ew.tkwin);
    } else {
	TkTextEmbWindowClient *client = ewPtr->body.ew.clients;

	for ( ; client; client = client->next) {
	    if (client->tkwin && !client->hPtr) {
		client->hPtr = Tcl_CreateHashEntry(
			&ewPtr->body.ew.sharedTextPtr->windowTable,
			Tk_PathName(client->tkwin),
			&isNew);
		assert(isNew);
		Tcl_SetHashValue(client->hPtr, ewPtr);
		ewPtr->body.ew.sharedTextPtr->numWindows += 1;
	    }
	}
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinLayoutProc --
 *
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
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

static int
EmbWinLayoutProc(
    TkText *textPtr,		/* Text widget being layed out. */
    TCL_UNUSED(TkTextIndex *),	/* Identifies first character in chunk. */
    TkTextSegment *ewPtr,	/* Segment corresponding to indexPtr. */
    TkSizeT offset,			/* Offset within segPtr corresponding to
				 * indexPtr (always 0). */
    int maxX,			/* Chunk must not occupy pixels at this
				 * position or higher. */
    TCL_UNUSED(TkSizeT),	/* Chunk must not include more than this many
				 * characters. */
    int noCharsYet,		/* Non-zero means no characters have been
				 * assigned to this line yet. */
    TCL_UNUSED(TkWrapMode),	/* Wrap mode to use for line:
				 * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
				 * TEXT_WRAPMODE_WORD. */
    TkTextDispChunk *chunkPtr)
				/* Structure to fill in with information about
				 * this chunk. The x field has already been
				 * set by the caller. */
{
    int width, height;
    TkTextEmbWindowClient *client;

    if (offset != 0) {
	Tcl_Panic("Non-zero offset in EmbWinLayoutProc");

    }


    client = EmbWinGetClient(textPtr, ewPtr);
    if (client == NULL) {
	ewPtr->body.ew.tkwin = NULL;
    } else {
	ewPtr->body.ew.tkwin = client->tkwin;
    }

    if ((ewPtr->body.ew.tkwin == NULL) && (ewPtr->body.ew.create != NULL)) {
	int code, isNew;

	Tk_Window ancestor;
	Tcl_HashEntry *hPtr;
	const char *before, *string;
	Tcl_DString buf, *dsPtr = NULL;
	Tcl_Obj *nameObj;

	before = ewPtr->body.ew.create;

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */

	string = before;
	while (*string != 0) {
	    if ((*string == '%') && (string[1] == '%' || string[1] == 'W')) {
		if (dsPtr == NULL) {
		    Tcl_DStringInit(&buf);
		    dsPtr = &buf;
		}
		if (string != before) {
		    Tcl_DStringAppend(dsPtr, before, (int) (string-before));
		    before = string;
		}







<
|

|
<
|
<
|
<
<
|
<
|
|
|
|
|
|



|
|
<
>
|
>


<
<
<
|
|
<
|
|
>

<

|
<










|
|







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
 *	None, except for filling in chunkPtr.
 *
 *--------------------------------------------------------------
 */

static int
EmbWinLayoutProc(

    const TkTextIndex *indexPtr,/* Identifies first character in chunk. */
    TkTextSegment *ewPtr,	/* Segment corresponding to indexPtr. */
    TCL_UNUSED(Tcl_Size),			/* Offset within segPtr corresponding to indexPtr (always 0). */

    int maxX,			/* Chunk must not occupy pixels at this position or higher. */

    TCL_UNUSED(Tcl_Size),		/* Chunk must not include more than this many characters. */


    int noCharsYet,		/* 'true' means no characters have been assigned to this line yet. */

    TkWrapMode wrapMode,	/* Wrap mode to use for line: TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE,
    				 * TEXT_WRAPMODE_WORD, or TEXT_WRAPMODE_CODEPOINT. */
    TCL_UNUSED(TkTextSpaceMode),	/* Not used. */
    TkTextDispChunk *chunkPtr)	/* Structure to fill in with information about this chunk. The x
    				 * field has already been set by the caller. This argument may be
				 * NULL. */
{
    int width, height;
    TkTextEmbWindowClient *client;
    TkText *textPtr = indexPtr->textPtr;
    int cantEmbed = 0;

    int x;

    assert(indexPtr->textPtr);

    client = EmbWinGetClient(textPtr, ewPtr);



    ewPtr->body.ew.tkwin = client ? client->tkwin : NULL;


    if (!ewPtr->body.ew.tkwin && ewPtr->body.ew.create) {
	int code;
	int isNew;
	Tk_Window ancestor;

	const char *before, *string;
	Tcl_DString name, buf, *dsPtr = NULL;


	before = ewPtr->body.ew.create;

	/*
	 * Find everything up to the next % character and append it to the
	 * result string.
	 */

	string = before;
	while (*string != 0) {
	    if (string[0] == '%' && (string[1] == '%' || string[1] == 'W')) {
		if (!dsPtr) {
		    Tcl_DStringInit(&buf);
		    dsPtr = &buf;
		}
		if (string != before) {
		    Tcl_DStringAppend(dsPtr, before, (int) (string-before));
		    before = string;
		}
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
		    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
		    spaceNeeded = Tcl_ConvertElement(str,
			    Tcl_DStringValue(dsPtr) + length,
			    cvtFlags | TCL_DONT_USE_BRACES);
		    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
		}
		before += 2;
		string++;
	    }
	    string++;
	}

	/*
	 * The window doesn't currently exist. Create it by evaluating the
	 * creation script. The script must return the window's path name:
	 * look up that name to get back to the window token. Then register
	 * ourselves as the geometry manager for the window.
	 */

	if (dsPtr != NULL) {
	    Tcl_DStringAppend(dsPtr, before, (int) (string-before));
	    code = Tcl_EvalEx(textPtr->interp, Tcl_DStringValue(dsPtr), -1, TCL_EVAL_GLOBAL);
	    Tcl_DStringFree(dsPtr);
	} else {
	    code = Tcl_EvalEx(textPtr->interp, ewPtr->body.ew.create, -1, TCL_EVAL_GLOBAL);
	}
	if (code != TCL_OK) {
	    Tcl_BackgroundException(textPtr->interp, code);
	    goto gotWindow;
	}

	nameObj = Tcl_GetObjResult(textPtr->interp);
	Tcl_IncrRefCount(nameObj);
	Tcl_ResetResult(textPtr->interp);
	ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp,
		Tcl_GetString(nameObj), textPtr->tkwin);
	Tcl_DecrRefCount(nameObj);
	if (ewPtr->body.ew.tkwin == NULL) {
	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    goto gotWindow;
	}

	for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		goto badContainer;

	    }
	}

	if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		|| (textPtr->tkwin == ewPtr->body.ew.tkwin)) {
	badContainer:
	    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf(
		    "can't embed %s relative to %s",
		    Tk_PathName(ewPtr->body.ew.tkwin),
		    Tk_PathName(textPtr->tkwin)));
	    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", "HIERARCHY",
		    NULL);
	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    ewPtr->body.ew.tkwin = NULL;
	    goto gotWindow;
	}

	if (client == NULL) {
	    /*
	     * We just used a '-create' script to make a new window, which we
	     * now need to add to our client list.
	     */

	    client = (TkTextEmbWindowClient *)ckalloc(sizeof(TkTextEmbWindowClient));

	    client->next = ewPtr->body.ew.clients;
	    client->textPtr = textPtr;
	    client->tkwin = NULL;
	    client->chunkCount = 0;
	    client->displayed = 0;
	    client->parent = ewPtr;
	    ewPtr->body.ew.clients = client;
	}

	client->tkwin = ewPtr->body.ew.tkwin;
	Tk_ManageGeometry(client->tkwin, &textGeomType, client);
	Tk_CreateEventHandler(client->tkwin, StructureNotifyMask,
		EmbWinStructureProc, client);

	/*
	 * Special trick! Must enter into the hash table *after* calling
	 * Tk_ManageGeometry: if the window was already managed elsewhere in
	 * this text, the Tk_ManageGeometry call will cause the entry to be
	 * removed, which could potentially lose the new entry.
	 */

	hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->windowTable,
		Tk_PathName(client->tkwin), &isNew);
	Tcl_SetHashValue(hPtr, ewPtr);

    }

    /*
     * See if there's room for this window on this line.
     */

  gotWindow:
    if (ewPtr->body.ew.tkwin == NULL) {
	width = 0;
	height = 0;
    } else {
	width = Tk_ReqWidth(ewPtr->body.ew.tkwin) + 2*ewPtr->body.ew.padX;
	height = Tk_ReqHeight(ewPtr->body.ew.tkwin) + 2*ewPtr->body.ew.padY;
    }
    if ((width > (maxX - chunkPtr->x))


	    && !noCharsYet && (textPtr->wrapMode != TEXT_WRAPMODE_NONE)) {
	return 0;
    }


    /*
     * Fill in the chunk structure.
     */

    chunkPtr->displayProc = TkTextEmbWinDisplayProc;
    chunkPtr->undisplayProc = EmbWinUndisplayProc;
    chunkPtr->measureProc = NULL;
    chunkPtr->bboxProc = EmbWinBboxProc;
    chunkPtr->numBytes = 1;
    if (ewPtr->body.ew.align == ALIGN_BASELINE) {
	chunkPtr->minAscent = height - ewPtr->body.ew.padY;
	chunkPtr->minDescent = ewPtr->body.ew.padY;
	chunkPtr->minHeight = 0;
    } else {
	chunkPtr->minAscent = 0;
	chunkPtr->minDescent = 0;
	chunkPtr->minHeight = height;
    }
    chunkPtr->width = width;
    chunkPtr->breakIndex = -1;
    chunkPtr->breakIndex = 1;
    chunkPtr->clientData = ewPtr;


    if (client != NULL) {
	client->chunkCount += 1;
    }







    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinCheckProc --







|

|









|
|
|


|





>
|
<

|
<
|
|









|
>


>
|
|
<
|
<
|
<
|
<





|






>


<
<
<






|
<








|
|
|
>







|






|
>
>
|



>
|
|
|

<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
<
|
>
>
|

|
>
>
>
>
>
>
>







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
		    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
		    spaceNeeded = Tcl_ConvertElement(str,
			    Tcl_DStringValue(dsPtr) + length,
			    cvtFlags | TCL_DONT_USE_BRACES);
		    Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
		}
		before += 2;
		string += 1;
	    }
	    string += 1;
	}

	/*
	 * The window doesn't currently exist. Create it by evaluating the
	 * creation script. The script must return the window's path name:
	 * look up that name to get back to the window token. Then register
	 * ourselves as the geometry manager for the window.
	 */

	if (dsPtr) {
	    Tcl_DStringAppend(dsPtr, before, string - before);
	    code = Tcl_EvalEx(textPtr->interp, Tcl_DStringValue(dsPtr), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	    Tcl_DStringFree(dsPtr);
	} else {
	    code = Tcl_EvalEx(textPtr->interp, ewPtr->body.ew.create, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	}
	if (code != TCL_OK) {
	    Tcl_BackgroundException(textPtr->interp, code);
	    goto gotWindow;
	}
	Tcl_DStringInit(&name);
	Tcl_DStringAppend(&name, Tcl_GetStringResult(textPtr->interp), TCL_INDEX_NONE);

	Tcl_ResetResult(textPtr->interp);
	ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp, Tcl_DStringValue(&name), textPtr->tkwin);

	Tcl_DStringFree(&name);
	if (!ewPtr->body.ew.tkwin) {
	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    goto gotWindow;
	}

	for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
	    	cantEmbed = 1;
		break;
	    }
	}
	if (cantEmbed
		|| Tk_TopWinHierarchy(ewPtr->body.ew.tkwin)
		|| textPtr->tkwin == ewPtr->body.ew.tkwin) {

	    Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf("can't embed %s relative to %s",

		    Tk_PathName(ewPtr->body.ew.tkwin), Tk_PathName(textPtr->tkwin)));

	    Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", "HIERARCHY", NULL);

	    Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
	    ewPtr->body.ew.tkwin = NULL;
	    goto gotWindow;
	}

	if (!client) {
	    /*
	     * We just used a '-create' script to make a new window, which we
	     * now need to add to our client list.
	     */

	    client = (TkTextEmbWindowClient *)ckalloc(sizeof(TkTextEmbWindowClient));
	    memset(client, 0, sizeof(TkTextEmbWindowClient));
	    client->next = ewPtr->body.ew.clients;
	    client->textPtr = textPtr;



	    client->parent = ewPtr;
	    ewPtr->body.ew.clients = client;
	}

	client->tkwin = ewPtr->body.ew.tkwin;
	Tk_ManageGeometry(client->tkwin, &textGeomType, client);
	Tk_CreateEventHandler(client->tkwin, StructureNotifyMask, EmbWinStructureProc, client);


	/*
	 * Special trick! Must enter into the hash table *after* calling
	 * Tk_ManageGeometry: if the window was already managed elsewhere in
	 * this text, the Tk_ManageGeometry call will cause the entry to be
	 * removed, which could potentially lose the new entry.
	 */

	client->hPtr = Tcl_CreateHashEntry(
		&textPtr->sharedTextPtr->windowTable, Tk_PathName(client->tkwin), &isNew);
	Tcl_SetHashValue(client->hPtr, ewPtr);
	ewPtr->body.ew.sharedTextPtr->numWindows += 1;
    }

    /*
     * See if there's room for this window on this line.
     */

  gotWindow:
    if (!ewPtr->body.ew.tkwin) {
	width = 0;
	height = 0;
    } else {
	width = Tk_ReqWidth(ewPtr->body.ew.tkwin) + 2*ewPtr->body.ew.padX;
	height = Tk_ReqHeight(ewPtr->body.ew.tkwin) + 2*ewPtr->body.ew.padY;
    }

    x = chunkPtr ? chunkPtr->x : 0;

    if (width > maxX - x && !noCharsYet && textPtr->wrapMode != TEXT_WRAPMODE_NONE) {
	return 0;
    }

    if (chunkPtr) {
	/*
	 * Fill in the chunk structure.
	 */



	chunkPtr->layoutProcs = &layoutWindowProcs;

	chunkPtr->numBytes = 1;
	if (ewPtr->body.ew.align == ALIGN_BASELINE) {
	    chunkPtr->minAscent = height - ewPtr->body.ew.padY;
	    chunkPtr->minDescent = ewPtr->body.ew.padY;
	    chunkPtr->minHeight = 0;
	} else {
	    chunkPtr->minAscent = 0;
	    chunkPtr->minDescent = 0;
	    chunkPtr->minHeight = height;
	}
	chunkPtr->width = width;
	chunkPtr->breakIndex = (wrapMode == TEXT_WRAPMODE_NONE) ? -1 : 1;

	chunkPtr->clientData = ewPtr;
    }

    if (client) {
	client->chunkCount += 1;

	if (!chunkPtr) {
	    TkTextDispChunk chunk;
	    chunk.clientData = ewPtr;
	    EmbWinUndisplayProc(textPtr, &chunk);
	}
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinCheckProc --
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
 *	window.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinCheckProc(

    TkTextSegment *ewPtr,	/* Segment to check. */
    TCL_UNUSED(TkTextLine *))	/* Line containing segment. */
{
    if (ewPtr->nextPtr == NULL) {
	Tcl_Panic("EmbWinCheckProc: embedded window is last segment in line");
    }
    if (ewPtr->size != 1) {
	Tcl_Panic("EmbWinCheckProc: embedded window has size %d", (int)ewPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextEmbWinDisplayProc --
 *
 *	This function is invoked by the text displaying code when it is time
 *	to actually draw an embedded window chunk on the screen.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The embedded window gets moved to the correct location and mapped onto
 *	the screen.
 *
 *--------------------------------------------------------------
 */

void
TkTextEmbWinDisplayProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    TCL_UNUSED(int),	/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),	/* Display to use for drawing (unused).  */
    TCL_UNUSED(Drawable),	/* Pixmap or window in which to draw
				 * (unused).  */
    int screenY)		/* Y-coordinate in text window that
				 * corresponds to y. */
{
    int lineX, windowX, windowY, width, height;
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	return;
    }

    tkwin = client->tkwin;
    if (tkwin == NULL) {
	return;
    }

    if ((x + chunkPtr->width) <= 0) {
	/*
	 * The window is off-screen; just unmap it.
	 */

	if (textPtr->tkwin != Tk_Parent(tkwin)) {
	    Tk_UnmaintainGeometry(tkwin, textPtr->tkwin);
	} else {
	    Tk_UnmapWindow(tkwin);
	}
	return;
    }

    /*
     * Compute the window's location and size in the text widget, taking into
     * account the align and stretch values for the window.
     */







>
|
<

|



|






|














|
|





|




|
|
<
|
<






|



<
<
<
<
<
|




|
<
<
|
<







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
 *	window.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinCheckProc(
    TCL_UNUSED(const TkSharedText *),	/* Handle to shared text resource. */
    const TkTextSegment *ewPtr)		/* Segment to check. */

{
    if (!ewPtr->nextPtr) {
	Tcl_Panic("EmbWinCheckProc: embedded window is last segment in line");
    }
    if (ewPtr->size != 1) {
	Tcl_Panic("EmbWinCheckProc: embedded window has size %d", ewPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinDisplayProc --
 *
 *	This function is invoked by the text displaying code when it is time
 *	to actually draw an embedded window chunk on the screen.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The embedded window gets moved to the correct location and mapped onto
 *	the screen.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinDisplayProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    TCL_UNUSED(int),			/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    TCL_UNUSED(Display *),		/* Display to use for drawing (unused).  */
    TCL_UNUSED(Drawable),		/* Pixmap or window in which to draw (unused).  */

    int screenY)		/* Y-coordinate in text window that corresponds to y. */

{
    int lineX, windowX, windowY, width, height;
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (!client || !(tkwin = client->tkwin)) {
	return;
    }






    if (x + chunkPtr->width <= 0) {
	/*
	 * The window is off-screen; just unmap it.
	 */

	client->displayed = 0;


	EmbWinDelayedUnmap(client);

	return;
    }

    /*
     * Compute the window's location and size in the text widget, taking into
     * account the align and stretch values for the window.
     */
1136
1137
1138
1139
1140
1141
1142
1143

1144
1145
1146
1147










1148





1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
     * particular for the <Map> event, and if the bound script deletes
     * the embedded window its clients will get freed.
     */

    client->displayed = 1;

    if (textPtr->tkwin == Tk_Parent(tkwin)) {
	if ((windowX != Tk_X(tkwin)) || (windowY != Tk_Y(tkwin))

		|| (Tk_ReqWidth(tkwin) != Tk_Width(tkwin))
		|| (height != Tk_Height(tkwin))) {
	    Tk_MoveResizeWindow(tkwin, windowX, windowY, width, height);
	}










	Tk_MapWindow(tkwin);





    } else {
	Tk_MaintainGeometry(tkwin, textPtr->tkwin, windowX, windowY,
		width, height);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinUndisplayProc --







|
>
|
|

|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>

|
<







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
     * particular for the <Map> event, and if the bound script deletes
     * the embedded window its clients will get freed.
     */

    client->displayed = 1;

    if (textPtr->tkwin == Tk_Parent(tkwin)) {
	if (windowX != Tk_X(tkwin)
		|| windowY != Tk_Y(tkwin)
		|| Tk_ReqWidth(tkwin) != Tk_Width(tkwin)
		|| height != Tk_Height(tkwin)) {
	    Tk_MoveResizeWindow(tkwin, windowX, windowY, width, height);

	    if (textPtr->watchCmd && Tk_IsMapped(tkwin)) {
		char w[100], h[100];

		snprintf(h, sizeof(h), "%d", Tk_Height(tkwin));
		snprintf(w, sizeof(w), "%d", Tk_Width(tkwin));

		TriggerWatchCmd(textPtr, ewPtr, tkwin, w, h);
	    }
	}
	if (!Tk_IsMapped(tkwin)) {
	    Tk_MapWindow(tkwin);

	    if (textPtr->watchCmd) {
		TriggerWatchCmd(textPtr, ewPtr, tkwin, NULL, NULL);
	    }
	}
    } else {
	Tk_MaintainGeometry(tkwin, textPtr->tkwin, windowX, windowY, width, height);

    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinUndisplayProc --
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
EmbWinUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	return;
    }

    client->chunkCount--;
    if (client->chunkCount == 0) {
	/*
	 * Don't unmap the window immediately, since there's a good chance
	 * that it will immediately be redisplayed, perhaps even in the same
	 * place. Instead, schedule the window to be unmapped later; the call
	 * to EmbWinDelayedUnmap will be cancelled in the likely event that
	 * the unmap becomes unnecessary.
	 */







<
<
<
<
|
<







1731
1732
1733
1734
1735
1736
1737




1738

1739
1740
1741
1742
1743
1744
1745
EmbWinUndisplayProc(
    TkText *textPtr,		/* Overall information about text widget. */
    TkTextDispChunk *chunkPtr)	/* Chunk that is about to be freed. */
{
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);





    if (client && --client->chunkCount == 0) {

	/*
	 * Don't unmap the window immediately, since there's a good chance
	 * that it will immediately be redisplayed, perhaps even in the same
	 * place. Instead, schedule the window to be unmapped later; the call
	 * to EmbWinDelayedUnmap will be cancelled in the likely event that
	 * the unmap becomes unnecessary.
	 */
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
 *--------------------------------------------------------------
 */

static void
EmbWinBboxProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(int),			/* Index of desired character within the
				 * chunk. */
    int y,			/* Topmost pixel in area allocated for this
				 * line. */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Location of line's baseline, in pixels
				 * measured down from y. */
    int *xPtr, int *yPtr,	/* Gets filled in with coords of character's
				 * upper-left pixel. */
    int *widthPtr,		/* Gets filled in with width of window, in
				 * pixels. */
    int *heightPtr)		/* Gets filled in with height of window, in
				 * pixels. */
{
    Tk_Window tkwin;
    TkTextSegment *ewPtr = (TkTextSegment *)chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	tkwin = NULL;
    } else {
	tkwin = client->tkwin;
    }
    if (tkwin != NULL) {
	*widthPtr = Tk_ReqWidth(tkwin);
	*heightPtr = Tk_ReqHeight(tkwin);
    } else {
	*widthPtr = 0;
	*heightPtr = 0;
    }
    *xPtr = chunkPtr->x + ewPtr->body.ew.padX;







|
<
|
<

|
<
|
<
|
<
|
<





<
<
<
|
<
|







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
 *--------------------------------------------------------------
 */

static void
EmbWinBboxProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk containing desired char. */
    TCL_UNUSED(Tcl_Size),			/* 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);




    tkwin = client ? client->tkwin : NULL;

    if (tkwin) {
	*widthPtr = Tk_ReqWidth(tkwin);
	*heightPtr = Tk_ReqHeight(tkwin);
    } else {
	*widthPtr = 0;
	*heightPtr = 0;
    }
    *xPtr = chunkPtr->x + ewPtr->body.ew.padX;
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
 *	non-zero again.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinDelayedUnmap(
    ClientData clientData)	/* Token for the window to be unmapped. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;

    if (!client->displayed && (client->tkwin != NULL)) {
	if (client->textPtr->tkwin != Tk_Parent(client->tkwin)) {
	    Tk_UnmaintainGeometry(client->tkwin, client->textPtr->tkwin);
	} else {
	    Tk_UnmapWindow(client->tkwin);
	}






    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextWindowIndex --
 *
 *	Given the name of an embedded window within a text widget, returns an
 *	index corresponding to the window's position in the text.
 *
 * Results:
 *	The return value is 1 if there is an embedded window by the given name
 *	in the text widget, 0 otherwise. If the window exists, *indexPtr is
 *	filled in with its index.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextWindowIndex(
    TkText *textPtr,		/* Text widget containing window. */
    const char *name,		/* Name of window. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *ewPtr;

    if (textPtr == NULL) {
	return 0;
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name);
    if (hPtr == NULL) {
	return 0;
    }

    ewPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);

    indexPtr->tree = textPtr->sharedTextPtr->tree;


    indexPtr->linePtr = ewPtr->body.ew.linePtr;



    indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr);
    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinGetClient --







|



|





>
>
>
>
>
>












|
|

















|
<
|
<
|
<




>
|
>
>
|
>
>
>
|







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
 *	non-zero again.
 *
 *--------------------------------------------------------------
 */

static void
EmbWinDelayedUnmap(
    void *clientData)	/* Token for the window to be unmapped. */
{
    TkTextEmbWindowClient *client = (TkTextEmbWindowClient *)clientData;

    if (!client->displayed && client->tkwin) {
	if (client->textPtr->tkwin != Tk_Parent(client->tkwin)) {
	    Tk_UnmaintainGeometry(client->tkwin, client->textPtr->tkwin);
	} else {
	    Tk_UnmapWindow(client->tkwin);
	}

	assert(client->textPtr);

	if (client->textPtr->watchCmd) {
	    TriggerWatchCmd(client->textPtr, client->parent, client->tkwin, NULL, NULL);
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextWindowIndex --
 *
 *	Given the name of an embedded window within a text widget, returns an
 *	index corresponding to the window's position in the text.
 *
 * Results:
 *	The return value is true if there is an embedded window by the given name
 *	in the text widget, false otherwise. If the window exists, *indexPtr is
 *	filled in with its index.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextWindowIndex(
    TkText *textPtr,		/* Text widget containing window. */
    const char *name,		/* Name of window. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *ewPtr;

    assert(textPtr);



    if (!(hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name))) {

	return 0;
    }

    ewPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    TkTextIndexClear(indexPtr, textPtr);
    DEBUG(indexPtr->discardConsistencyCheck = 1);
    TkTextIndexSetSegment(indexPtr, ewPtr);
    DEBUG(indexPtr->discardConsistencyCheck = 0);

    if (TkTextIndexOutsideStartEnd(indexPtr)) {
	return 0;
    }

    return 1;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinGetClient --
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403

1404
static TkTextEmbWindowClient *
EmbWinGetClient(
    const TkText *textPtr,	/* Information about text widget. */
    TkTextSegment *ewPtr)	/* Segment containing embedded window. */
{
    TkTextEmbWindowClient *client = ewPtr->body.ew.clients;

    while (client != NULL) {
	if (client->textPtr == textPtr) {
	    return client;
	}
	client = client->next;
    }
    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:

 */







|












|

>

1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
static TkTextEmbWindowClient *
EmbWinGetClient(
    const TkText *textPtr,	/* Information about text widget. */
    TkTextSegment *ewPtr)	/* Segment containing embedded window. */
{
    TkTextEmbWindowClient *client = ewPtr->body.ew.clients;

    while (client) {
	if (client->textPtr == textPtr) {
	    return client;
	}
	client = client->next;
    }
    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 105
 * End:
 * vi:set ts=8 sw=4:
 */

Changes to generic/tkTrig.c.

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.
 *
 * 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"







|
|







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 © 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"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkLineToPoint(
    double end1Ptr[2],		/* Coordinates of first end-point of line. */
    double end2Ptr[2],		/* Coordinates of second end-point of line. */
    double pointPtr[2])		/* Points to coords for point. */
{
    double x, y;

    /*
     * Compute the point on the line that is closest to the point. This must
     * be done separately for vertical edges, horizontal edges, and other
     * edges.







|
|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkLineToPoint(
    double end1Ptr[],		/* Coordinates of first end-point of line. */
    double end2Ptr[],		/* Coordinates of second end-point of line. */
    double pointPtr[])		/* Points to coords for point. */
{
    double x, y;

    /*
     * Compute the point on the line that is closest to the point. This must
     * be done separately for vertical edges, horizontal edges, and other
     * edges.
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkLineToArea(
    double end1Ptr[2],		/* X and y coordinates for one endpoint of
				 * line. */
    double end2Ptr[2],		/* X and y coordinates for other endpoint of
				 * line. */
    double rectPtr[4])		/* Points to coords for rectangle, in the
				 * order x1, y1, x2, y2. X1 must be no larger
				 * than x2, and y1 no larger than y2. */
{
    int inside1, inside2;

    /*
     * First check the two points individually to see whether they are inside







|

|

|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkLineToArea(
    double end1Ptr[],		/* X and y coordinates for one endpoint of
				 * line. */
    double end2Ptr[],		/* X and y coordinates for other endpoint of
				 * line. */
    double rectPtr[])		/* Points to coords for rectangle, in the
				 * order x1, y1, x2, y2. X1 must be no larger
				 * than x2, and y1 no larger than y2. */
{
    int inside1, inside2;

    /*
     * First check the two points individually to see whether they are inside
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkOvalToPoint(
    double ovalPtr[4],		/* Pointer to array of four coordinates (x1,
				 * y1, x2, y2) defining oval's bounding
				 * box. */
    double width,		/* Width of outline for oval. */
    int filled,			/* Non-zero means oval should be treated as
				 * filled; zero means only consider
				 * outline. */
    double pointPtr[2])		/* Coordinates of point. */
{
    double xDelta, yDelta, scaledDistance, distToOutline, distToCenter;
    double xDiam, yDiam;

    /*
     * Compute the distance between the center of the oval and the point in
     * question, using a coordinate system where the oval has been transformed







|






|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkOvalToPoint(
    double ovalPtr[],		/* Pointer to array of four coordinates (x1,
				 * y1, x2, y2) defining oval's bounding
				 * box. */
    double width,		/* Width of outline for oval. */
    int filled,			/* Non-zero means oval should be treated as
				 * filled; zero means only consider
				 * outline. */
    double pointPtr[])		/* Coordinates of point. */
{
    double xDelta, yDelta, scaledDistance, distToOutline, distToCenter;
    double xDiam, yDiam;

    /*
     * Compute the distance between the center of the oval and the point in
     * question, using a coordinate system where the oval has been transformed

Changes to generic/tkUndo.c.

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.
 *
 * 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"





|
|







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 © 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"
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
 *----------------------------------------------------------------------
 */

TkUndoSubAtom *
TkUndoMakeSubAtom(
    TkUndoProc *funcPtr,	/* Callback function to perform the
				 * undo/redo. */
    ClientData clientData,	/* Data to pass to the callback function. */
    Tcl_Obj *actionScript,	/* Additional Tcl data to pass to the callback
				 * function (may be NULL). */
    TkUndoSubAtom *subAtomList)	/* Add to the end of this list of actions if
				 * non-NULL */
{
    TkUndoSubAtom *atom;








|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
 *----------------------------------------------------------------------
 */

TkUndoSubAtom *
TkUndoMakeSubAtom(
    TkUndoProc *funcPtr,	/* Callback function to perform the
				 * undo/redo. */
    void *clientData,	/* Data to pass to the callback function. */
    Tcl_Obj *actionScript,	/* Additional Tcl data to pass to the callback
				 * function (may be NULL). */
    TkUndoSubAtom *subAtomList)	/* Add to the end of this list of actions if
				 * non-NULL */
{
    TkUndoSubAtom *atom;

Changes to generic/tkUndo.h.

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.
 *
 * 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





|







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 © 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
} TkUndoAtomType;

/*
 * Callback proc type to carry out an undo or redo action via C code. (Actions
 * can also be defined by Tcl scripts).
 */

typedef int (TkUndoProc)(Tcl_Interp *interp, ClientData clientData,
			Tcl_Obj *objPtr);

/*
 * Struct defining a single action, one or more of which may be defined (and
 * stored in a linked list) separately for each undo and redo action of an
 * undo atom.
 */

typedef struct TkUndoSubAtom {
    Tcl_Command command;	/* Tcl token used to get the current Tcl
				 * command name which will be used to execute
				 * apply/revert scripts. If NULL then it is
				 * assumed the apply/revert scripts already
				 * contain everything. */
    TkUndoProc *funcPtr;	/* Function pointer for callback to perform
				 * undo/redo actions. */
    ClientData clientData;	/* Data for 'funcPtr'. */
    Tcl_Obj *action;		/* Command to apply the action that was
				 * taken. */
    struct TkUndoSubAtom *next;	/* Pointer to the next element in the linked
				 * list. */
} TkUndoSubAtom;

/*







|
















|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
} TkUndoAtomType;

/*
 * Callback proc type to carry out an undo or redo action via C code. (Actions
 * can also be defined by Tcl scripts).
 */

typedef int (TkUndoProc)(Tcl_Interp *interp, void *clientData,
			Tcl_Obj *objPtr);

/*
 * Struct defining a single action, one or more of which may be defined (and
 * stored in a linked list) separately for each undo and redo action of an
 * undo atom.
 */

typedef struct TkUndoSubAtom {
    Tcl_Command command;	/* Tcl token used to get the current Tcl
				 * command name which will be used to execute
				 * apply/revert scripts. If NULL then it is
				 * assumed the apply/revert scripts already
				 * contain everything. */
    TkUndoProc *funcPtr;	/* Function pointer for callback to perform
				 * undo/redo actions. */
    void *clientData;	/* Data for 'funcPtr'. */
    Tcl_Obj *action;		/* Command to apply the action that was
				 * taken. */
    struct TkUndoSubAtom *next;	/* Pointer to the next element in the linked
				 * list. */
} TkUndoSubAtom;

/*
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
MODULE_SCOPE void	TkUndoFreeStack(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoCanRedo(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoCanUndo(TkUndoRedoStack *stack);
MODULE_SCOPE void	TkUndoInsertUndoSeparator(TkUndoRedoStack *stack);
MODULE_SCOPE TkUndoSubAtom *TkUndoMakeCmdSubAtom(Tcl_Command command,
			    Tcl_Obj *actionScript, TkUndoSubAtom *subAtomList);
MODULE_SCOPE TkUndoSubAtom *TkUndoMakeSubAtom(TkUndoProc *funcPtr,
			    ClientData clientData, Tcl_Obj *actionScript,
			    TkUndoSubAtom *subAtomList);
MODULE_SCOPE void	TkUndoPushAction(TkUndoRedoStack *stack,
			    TkUndoSubAtom *apply, TkUndoSubAtom *revert);
MODULE_SCOPE int	TkUndoRevert(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoApply(TkUndoRedoStack *stack);

#endif /* _TKUNDO */







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
MODULE_SCOPE void	TkUndoFreeStack(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoCanRedo(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoCanUndo(TkUndoRedoStack *stack);
MODULE_SCOPE void	TkUndoInsertUndoSeparator(TkUndoRedoStack *stack);
MODULE_SCOPE TkUndoSubAtom *TkUndoMakeCmdSubAtom(Tcl_Command command,
			    Tcl_Obj *actionScript, TkUndoSubAtom *subAtomList);
MODULE_SCOPE TkUndoSubAtom *TkUndoMakeSubAtom(TkUndoProc *funcPtr,
			    void *clientData, Tcl_Obj *actionScript,
			    TkUndoSubAtom *subAtomList);
MODULE_SCOPE void	TkUndoPushAction(TkUndoRedoStack *stack,
			    TkUndoSubAtom *apply, TkUndoSubAtom *revert);
MODULE_SCOPE int	TkUndoRevert(TkUndoRedoStack *stack);
MODULE_SCOPE int	TkUndoApply(TkUndoRedoStack *stack);

#endif /* _TKUNDO */

Changes to generic/tkUtil.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
/*
 * 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.
 *
 * 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 structure below defines the implementation of the "statekey" Tcl
 * object, used for quickly finding a mapping in a TkStateMap.
 */

const Tcl_ObjType tkStateKeyObjType = {
    "statekey",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */


};

/*
 *--------------------------------------------------------------
 *
 * TkStateParseProc --
 *






|
|







>
>
>
>





|
|



|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * 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 © 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The structure below defines the implementation of the "statekey" Tcl
 * object, used for quickly finding a mapping in a TkStateMap.
 */

const TkObjType tkStateKeyObjType = {
    {"statekey",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0},
    0
};

/*
 *--------------------------------------------------------------
 *
 * TkStateParseProc --
 *
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 *	value argument.
 *
 *--------------------------------------------------------------
 */

int
TkStateParseProc(
    ClientData clientData,	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    int flags = PTR2INT(clientData);
    size_t length;
    Tcl_Obj *msgObj;
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);








|




|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 *	value argument.
 *
 *--------------------------------------------------------------
 */

int
TkStateParseProc(
    void *clientData,	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item. */
{
    int c;
    int flags = PTR2INT(clientData);
    size_t length;
    Tcl_Obj *msgObj;
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
	*statePtr = TK_STATE_HIDDEN;
	return TCL_OK;
    }

    msgObj = Tcl_ObjPrintf("bad %s value \"%s\": must be normal",
	    ((flags & 4) ? "-default" : "state"), value);
    if (flags & 1) {
	Tcl_AppendToObj(msgObj, ", active", -1);
    }
    if (flags & 2) {
	Tcl_AppendToObj(msgObj, ", hidden", -1);
    }
    if (flags & 3) {
	Tcl_AppendToObj(msgObj, ",", -1);
    }
    Tcl_AppendToObj(msgObj, " or disabled", -1);
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "VALUE", "STATE", NULL);
    *statePtr = TK_STATE_NORMAL;
    return TCL_ERROR;
}

/*







|


|


|

|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
	*statePtr = TK_STATE_HIDDEN;
	return TCL_OK;
    }

    msgObj = Tcl_ObjPrintf("bad %s value \"%s\": must be normal",
	    ((flags & 4) ? "-default" : "state"), value);
    if (flags & 1) {
	Tcl_AppendToObj(msgObj, ", active", TCL_INDEX_NONE);
    }
    if (flags & 2) {
	Tcl_AppendToObj(msgObj, ", hidden", TCL_INDEX_NONE);
    }
    if (flags & 3) {
	Tcl_AppendToObj(msgObj, ",", TCL_INDEX_NONE);
    }
    Tcl_AppendToObj(msgObj, " or disabled", TCL_INDEX_NONE);
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "VALUE", "STATE", NULL);
    *statePtr = TK_STATE_NORMAL;
    return TCL_ERROR;
}

/*
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 */

const char *
TkStatePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);

    switch (*statePtr) {







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
 */

const char *
TkStatePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);

    switch (*statePtr) {
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
int
TkOrientParseProc(
    TCL_UNUSED(void *),	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset)			/* Offset into item. */
{
    int c;
    size_t length;
    int *orientPtr = (int *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*orientPtr = 0;







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
int
TkOrientParseProc(
    TCL_UNUSED(void *),	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset)			/* Offset into item. */
{
    int c;
    size_t length;
    int *orientPtr = (int *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*orientPtr = 0;
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
 */

const char *
TkOrientPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    int *statePtr = (int *) (widgRec + offset);

    if (*statePtr) {







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
 */

const char *
TkOrientPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    Tcl_Size offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    int *statePtr = (int *) (widgRec + offset);

    if (*statePtr) {
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
 *	structure.
 *
 *----------------------------------------------------------------------
 */

int
TkOffsetParseProc(
    ClientData clientData,	/* not used */
    Tcl_Interp *interp,		/* Interpreter to send results back to */
    Tk_Window tkwin,		/* Window on same display as tile */
    const char *value,		/* Name of image */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset)			/* Offset of tile in record */
{
    Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
    Tk_TSOffset tsoffset;
    const char *q, *p;
    int result;
    Tcl_Obj *msgObj;








|




|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
 *	structure.
 *
 *----------------------------------------------------------------------
 */

int
TkOffsetParseProc(
    void *clientData,	/* not used */
    Tcl_Interp *interp,		/* Interpreter to send results back to */
    Tk_Window tkwin,		/* Window on same display as tile */
    const char *value,		/* Name of image */
    char *widgRec,		/* Widget structure record */
    Tcl_Size offset)			/* Offset of tile in record */
{
    Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
    Tk_TSOffset tsoffset;
    const char *q, *p;
    int result;
    Tcl_Obj *msgObj;

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
  goodTSOffset:
    memcpy(offsetPtr, &tsoffset, sizeof(Tk_TSOffset));
    return TCL_OK;

  badTSOffset:
    msgObj = Tcl_ObjPrintf("bad offset \"%s\": expected \"x,y\"", value);
    if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
	Tcl_AppendToObj(msgObj, ", \"#x,y\"", -1);
    }
    if (PTR2INT(clientData) & TK_OFFSET_INDEX) {
	Tcl_AppendToObj(msgObj, ", <index>", -1);
    }
    Tcl_AppendToObj(msgObj, ", n, ne, e, se, s, sw, w, nw, or center", -1);
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "VALUE", "OFFSET", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------







|


|

|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
  goodTSOffset:
    memcpy(offsetPtr, &tsoffset, sizeof(Tk_TSOffset));
    return TCL_OK;

  badTSOffset:
    msgObj = Tcl_ObjPrintf("bad offset \"%s\": expected \"x,y\"", value);
    if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
	Tcl_AppendToObj(msgObj, ", \"#x,y\"", TCL_INDEX_NONE);
    }
    if (PTR2INT(clientData) & TK_OFFSET_INDEX) {
	Tcl_AppendToObj(msgObj, ", <index>", TCL_INDEX_NONE);
    }
    Tcl_AppendToObj(msgObj, ", n, ne, e, se, s, sw, w, nw, or center", TCL_INDEX_NONE);
    Tcl_SetObjResult(interp, msgObj);
    Tcl_SetErrorCode(interp, "TK", "VALUE", "OFFSET", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
 */

const char *
TkOffsetPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset,			/* Offset of tile in record */
    Tcl_FreeProc **freeProcPtr)	/* not used */
{
    Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
    char *p, *q;

    if (offsetPtr->flags & TK_OFFSET_INDEX) {
	if (offsetPtr->flags >= INT_MAX) {
	    return "end";
	}
	p = (char *)ckalloc(32);
	sprintf(p, "%d", offsetPtr->flags & ~TK_OFFSET_INDEX);
	*freeProcPtr = TCL_DYNAMIC;
	return p;
    }
    if (offsetPtr->flags & TK_OFFSET_TOP) {
	if (offsetPtr->flags & TK_OFFSET_LEFT) {
	    return "nw";
	} else if (offsetPtr->flags & TK_OFFSET_CENTER) {







|










|







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
 */

const char *
TkOffsetPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    char *widgRec,		/* Widget structure record */
    Tcl_Size offset,			/* Offset of tile in record */
    Tcl_FreeProc **freeProcPtr)	/* not used */
{
    Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
    char *p, *q;

    if (offsetPtr->flags & TK_OFFSET_INDEX) {
	if (offsetPtr->flags >= INT_MAX) {
	    return "end";
	}
	p = (char *)ckalloc(32);
	snprintf(p, 32, "%d", offsetPtr->flags & ~TK_OFFSET_INDEX);
	*freeProcPtr = TCL_DYNAMIC;
	return p;
    }
    if (offsetPtr->flags & TK_OFFSET_TOP) {
	if (offsetPtr->flags & TK_OFFSET_LEFT) {
	    return "nw";
	} else if (offsetPtr->flags & TK_OFFSET_CENTER) {
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
	    return "se";
	}
    }
    q = p = (char *)ckalloc(32);
    if (offsetPtr->flags & TK_OFFSET_RELATIVE) {
	*q++ = '#';
    }
    sprintf(q, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPixelParseProc --
 *
 *	Converts the name of an image into a tile.
 *
 *----------------------------------------------------------------------
 */

int
TkPixelParseProc(
    ClientData clientData,	/* If non-NULL, negative values are allowed as
				 * well. */
    Tcl_Interp *interp,		/* Interpreter to send results back to */
    Tk_Window tkwin,		/* Window on same display as tile */
    const char *value,		/* Name of image */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset)			/* Offset of tile in record */
{
    double *doublePtr = (double *) (widgRec + offset);
    int result;

    result = TkGetDoublePixels(interp, tkwin, value, doublePtr);

    if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad screen distance \"%s\"", value));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	return TCL_ERROR;
    }
    return result;
}

/*







|
















|





|








|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
	    return "se";
	}
    }
    q = p = (char *)ckalloc(32);
    if (offsetPtr->flags & TK_OFFSET_RELATIVE) {
	*q++ = '#';
    }
    snprintf(q, 32, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPixelParseProc --
 *
 *	Converts the name of an image into a tile.
 *
 *----------------------------------------------------------------------
 */

int
TkPixelParseProc(
    void *clientData,	/* If non-NULL, negative values are allowed as
				 * well. */
    Tcl_Interp *interp,		/* Interpreter to send results back to */
    Tk_Window tkwin,		/* Window on same display as tile */
    const char *value,		/* Name of image */
    char *widgRec,		/* Widget structure record */
    Tcl_Size offset)			/* Offset of tile in record */
{
    double *doublePtr = (double *) (widgRec + offset);
    int result;

    result = TkGetDoublePixels(interp, tkwin, value, doublePtr);

    if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"expected screen distance but got \"%.50s\"", value));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL);
	return TCL_ERROR;
    }
    return result;
}

/*
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
 */

const char *
TkPixelPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset,			/* Offset of tile in record */
    Tcl_FreeProc **freeProcPtr)	/* not used */
{
    double *doublePtr = (double *) (widgRec + offset);
    char *p = (char *)ckalloc(24);

    Tcl_PrintDouble(NULL, *doublePtr, p);
    *freeProcPtr = TCL_DYNAMIC;







|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
 */

const char *
TkPixelPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    char *widgRec,		/* Widget structure record */
    Tcl_Size offset,			/* Offset of tile in record */
    Tcl_FreeProc **freeProcPtr)	/* not used */
{
    double *doublePtr = (double *) (widgRec + offset);
    char *p = (char *)ckalloc(24);

    Tcl_PrintDouble(NULL, *doublePtr, p);
    *freeProcPtr = TCL_DYNAMIC;
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
 *----------------------------------------------------------------------
 *
 * Tk_DrawFocusHighlight --
 *
 *	This function draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *	This function is now deprecated. Use TkpDrawHighlightBorder instead,
 *	since this function does not handle drawing the Focus ring properly on
 *	the Macintosh - you need to know the background GC as well as the
 *	foreground since the Mac focus ring separated from the widget by a 1
 *	pixel border.
 *
 * Results:
 *	None.







|







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
 *----------------------------------------------------------------------
 *
 * Tk_DrawFocusHighlight --
 *
 *	This function draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *	This function is now deprecated. Use Tk_DrawHighlightBorder instead,
 *	since this function does not handle drawing the Focus ring properly on
 *	the Macintosh - you need to know the background GC as well as the
 *	foreground since the Mac focus ring separated from the widget by a 1
 *	pixel border.
 *
 * Results:
 *	None.
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetScrollInfo(
    Tcl_Interp *interp,		/* Used for error reporting. */
    int argc,			/* # arguments for command. */
    const char **argv,		/* Arguments for command. */
    double *dblPtr,		/* Filled in with argument "moveto" option, if
				 * any. */
    int *intPtr)		/* Filled in with number of pages or lines to
				 * scroll, if any. */
{
    int c = argv[2][0];







|







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetScrollInfo(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Size argc,			/* # arguments for command. */
    const char **argv,		/* Arguments for command. */
    double *dblPtr,		/* Filled in with argument "moveto" option, if
				 * any. */
    int *intPtr)		/* Filled in with number of pages or lines to
				 * scroll, if any. */
{
    int c = argv[2][0];
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735





736
737
738
739
740
741
742
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetScrollInfoObj(
    Tcl_Interp *interp,		/* Used for error reporting. */
    int objc,			/* # arguments for command. */
    Tcl_Obj *const objv[],	/* Arguments for command. */
    double *dblPtr,		/* Filled in with argument "moveto" option, if
				 * any. */
    int *intPtr)		/* Filled in with number of pages or lines to
				 * scroll, if any. */
{
    TkSizeT length;
    const char *arg = TkGetStringFromObj(objv[2], &length);






#define ArgPfxEq(str) \
	((arg[0] == str[0]) && !strncmp(arg, str, length))

    if (ArgPfxEq("moveto")) {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
	    return TK_SCROLL_ERROR;







|






|
|

>
>
>
>
>







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetScrollInfoObj(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Size objc,			/* # arguments for command. */
    Tcl_Obj *const objv[],	/* Arguments for command. */
    double *dblPtr,		/* Filled in with argument "moveto" option, if
				 * any. */
    int *intPtr)		/* Filled in with number of pages or lines to
				 * scroll, if any. */
{
    Tcl_Size length;
    const char *arg;

    if (objc + 1 < 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "moveto|scroll args");
	return TK_SCROLL_ERROR;
    }
    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;
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d >= 0) ? ceil(d) : floor(d);
	if (dblPtr) {
	    *dblPtr = d;
	}

	arg = TkGetStringFromObj(objv[4], &length);
	if (ArgPfxEq("pages")) {
	    return TK_SCROLL_PAGES;
	} else if (ArgPfxEq("units")) {
	    return TK_SCROLL_UNITS;
	}

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d >= 0) ? ceil(d) : floor(d);
	if (dblPtr) {
	    *dblPtr = d;
	}

	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(
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
    switch (anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_W:
    case TK_ANCHOR_SW:
	*xPtr = Tk_InternalBorderLeft(tkwin) + padX;
	break;

    case TK_ANCHOR_N:
    case TK_ANCHOR_CENTER:
    case TK_ANCHOR_S:
	*xPtr = (Tk_Width(tkwin) - innerWidth - Tk_InternalBorderLeft(tkwin) -
		Tk_InternalBorderRight(tkwin)) / 2 +
		Tk_InternalBorderLeft(tkwin);
	break;

    default:

	*xPtr = Tk_Width(tkwin) - Tk_InternalBorderRight(tkwin) - padX
		- innerWidth;
	break;
    }

    /*
     * Handle the vertical parts.
     */

    switch (anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_N:
    case TK_ANCHOR_NE:
	*yPtr = Tk_InternalBorderTop(tkwin) + padY;
	break;

    case TK_ANCHOR_W:
    case TK_ANCHOR_CENTER:
    case TK_ANCHOR_E:
	*yPtr = (Tk_Height(tkwin) - innerHeight- Tk_InternalBorderTop(tkwin) -
		Tk_InternalBorderBottom(tkwin)) / 2 +
		Tk_InternalBorderTop(tkwin);
	break;

    default:

	*yPtr = Tk_Height(tkwin) - Tk_InternalBorderBottom(tkwin) - padY
		- innerHeight;
	break;
    }
}

/*
 *---------------------------------------------------------------------------
 *







|
|
|
<
|
|



>
|
|














|
|
|
<
|
|



>
|
|







827
828
829
830
831
832
833
834
835
836

837
838
839
840
841
842
843
844
845
846
847
848
849
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
    switch (anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_W:
    case TK_ANCHOR_SW:
	*xPtr = Tk_InternalBorderLeft(tkwin) + padX;
	break;

    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:

	*xPtr = Tk_Width(tkwin) - Tk_InternalBorderRight(tkwin) - padX
		- innerWidth;
	break;

    default:
	*xPtr = (Tk_Width(tkwin) - innerWidth - Tk_InternalBorderLeft(tkwin) -
		Tk_InternalBorderRight(tkwin)) / 2 +
		Tk_InternalBorderLeft(tkwin);
	break;
    }

    /*
     * Handle the vertical parts.
     */

    switch (anchor) {
    case TK_ANCHOR_NW:
    case TK_ANCHOR_N:
    case TK_ANCHOR_NE:
	*yPtr = Tk_InternalBorderTop(tkwin) + padY;
	break;

    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:

	*yPtr = Tk_Height(tkwin) - Tk_InternalBorderBottom(tkwin) - padY
		- innerHeight;
	break;

    default:
	*yPtr = (Tk_Height(tkwin) - innerHeight- Tk_InternalBorderTop(tkwin) -
		Tk_InternalBorderBottom(tkwin)) / 2 +
		Tk_InternalBorderTop(tkwin);
	break;
    }
}

/*
 *---------------------------------------------------------------------------
 *
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
    const char *key;
    const Tcl_ObjType *typePtr;

    /*
     * See if the value is in the object cache.
     */

    if ((keyPtr->typePtr == &tkStateKeyObjType)
	    && (keyPtr->internalRep.twoPtrValue.ptr1 == mapPtr)) {
	return PTR2INT(keyPtr->internalRep.twoPtrValue.ptr2);
    }

    /*
     * Not there. Look in the state map.
     */

    key = Tcl_GetString(keyPtr);
    for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
	if (strcmp(key, mPtr->strKey) == 0) {
	    typePtr = keyPtr->typePtr;
	    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
		typePtr->freeIntRepProc(keyPtr);
	    }
	    keyPtr->internalRep.twoPtrValue.ptr1 = (void *) mapPtr;
	    keyPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(mPtr->numKey);
	    keyPtr->typePtr = &tkStateKeyObjType;
	    return mPtr->numKey;
	}
    }

    /*
     * Not there either. Generate an error message (if we can) and return the
     * default.







|

















|







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
    const char *key;
    const Tcl_ObjType *typePtr;

    /*
     * See if the value is in the object cache.
     */

    if ((keyPtr->typePtr == &tkStateKeyObjType.objType)
	    && (keyPtr->internalRep.twoPtrValue.ptr1 == mapPtr)) {
	return PTR2INT(keyPtr->internalRep.twoPtrValue.ptr2);
    }

    /*
     * Not there. Look in the state map.
     */

    key = Tcl_GetString(keyPtr);
    for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
	if (strcmp(key, mPtr->strKey) == 0) {
	    typePtr = keyPtr->typePtr;
	    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
		typePtr->freeIntRepProc(keyPtr);
	    }
	    keyPtr->internalRep.twoPtrValue.ptr1 = (void *) mapPtr;
	    keyPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(mPtr->numKey);
	    keyPtr->typePtr = &tkStateKeyObjType.objType;
	    return mPtr->numKey;
	}
    }

    /*
     * Not there either. Generate an error message (if we can) and return the
     * default.
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043

1044
1045
1046
1047
1048
1049
1050
 *
 * ----------------------------------------------------------------------
 */

int
TkBackgroundEvalObjv(
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const *objv,
    int flags)
{
    Tcl_InterpState state;
    int n, r = TCL_OK;


    /*
     * Record the state of the interpreter.
     */

    Tcl_Preserve(interp);
    state = Tcl_SaveInterpState(interp, TCL_OK);







|




|
>







1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
 *
 * ----------------------------------------------------------------------
 */

int
TkBackgroundEvalObjv(
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const *objv,
    int flags)
{
    Tcl_InterpState state;
    int r = TCL_OK;
    Tcl_Size n;

    /*
     * Record the state of the interpreter.
     */

    Tcl_Preserve(interp);
    state = Tcl_SaveInterpState(interp, TCL_OK);
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
 */

Tcl_Command
TkMakeEnsemble(
    Tcl_Interp *interp,
    const char *namesp,
    const char *name,
    ClientData clientData,
    const TkEnsemble map[])
{
    Tcl_Namespace *namespacePtr = NULL;
    Tcl_Command ensemble = NULL;
    Tcl_Obj *dictObj = NULL, *nameObj;
    Tcl_DString ds;
    int i;







|







1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
 */

Tcl_Command
TkMakeEnsemble(
    Tcl_Interp *interp,
    const char *namesp,
    const char *name,
    void *clientData,
    const TkEnsemble map[])
{
    Tcl_Namespace *namespacePtr = NULL;
    Tcl_Command ensemble = NULL;
    Tcl_Obj *dictObj = NULL, *nameObj;
    Tcl_DString ds;
    int i;
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
    if (namespacePtr == NULL) {
	namespacePtr = Tcl_CreateNamespace(interp, namesp, NULL, NULL);
	if (namespacePtr == NULL) {
	    Tcl_Panic("failed to create namespace \"%s\"", namesp);
	}
    }

    nameObj = Tcl_NewStringObj(name, -1);
    ensemble = Tcl_FindEnsemble(interp, nameObj, 0);
    Tcl_DecrRefCount(nameObj);
    if (ensemble == NULL) {
	ensemble = Tcl_CreateEnsemble(interp, name, namespacePtr,
		TCL_ENSEMBLE_PREFIX);
	if (ensemble == NULL) {
	    Tcl_Panic("failed to create ensemble \"%s\"", name);
	}
    }

    Tcl_DStringSetLength(&ds, 0);
    Tcl_DStringAppend(&ds, namesp, -1);
    if (!(strlen(namesp) == 2 && namesp[1] == ':')) {
	Tcl_DStringAppend(&ds, "::", -1);
    }
    Tcl_DStringAppend(&ds, name, -1);

    dictObj = Tcl_NewObj();
    for (i = 0; map[i].name != NULL ; ++i) {
	Tcl_Obj *fqdnObj;

	nameObj = Tcl_NewStringObj(map[i].name, -1);
	fqdnObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds));
	Tcl_AppendStringsToObj(fqdnObj, "::", map[i].name, NULL);
	Tcl_DictObjPut(NULL, dictObj, nameObj, fqdnObj);
	if (map[i].proc) {




	    Tcl_CreateObjCommand(interp, Tcl_GetString(fqdnObj),
		    map[i].proc, clientData, NULL);

	} else if (map[i].subensemble) {
	    TkMakeEnsemble(interp, Tcl_DStringValue(&ds),
		    map[i].name, clientData, map[i].subensemble);
	}
    }

    if (ensemble) {
	Tcl_SetEnsembleMappingDict(interp, ensemble, dictObj);
    }

    Tcl_DStringFree(&ds);
    return ensemble;
}

































/*
 *----------------------------------------------------------------------
 *
 * Tk_SendVirtualEvent --
 *
 * 	Send a virtual event notification to the specified target window.







|











|

|

|





|





>
>
>
>


>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    if (namespacePtr == NULL) {
	namespacePtr = Tcl_CreateNamespace(interp, namesp, NULL, NULL);
	if (namespacePtr == NULL) {
	    Tcl_Panic("failed to create namespace \"%s\"", namesp);
	}
    }

    nameObj = Tcl_NewStringObj(name, TCL_INDEX_NONE);
    ensemble = Tcl_FindEnsemble(interp, nameObj, 0);
    Tcl_DecrRefCount(nameObj);
    if (ensemble == NULL) {
	ensemble = Tcl_CreateEnsemble(interp, name, namespacePtr,
		TCL_ENSEMBLE_PREFIX);
	if (ensemble == NULL) {
	    Tcl_Panic("failed to create ensemble \"%s\"", name);
	}
    }

    Tcl_DStringSetLength(&ds, 0);
    Tcl_DStringAppend(&ds, namesp, TCL_INDEX_NONE);
    if (!(strlen(namesp) == 2 && namesp[1] == ':')) {
	Tcl_DStringAppend(&ds, "::", TCL_INDEX_NONE);
    }
    Tcl_DStringAppend(&ds, name, TCL_INDEX_NONE);

    dictObj = Tcl_NewObj();
    for (i = 0; map[i].name != NULL ; ++i) {
	Tcl_Obj *fqdnObj;

	nameObj = Tcl_NewStringObj(map[i].name, TCL_INDEX_NONE);
	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) {
#if TCL_MAJOR_VERSION > 8
	    Tcl_CreateObjCommand2(interp, Tcl_GetString(fqdnObj),
		    map[i].proc, clientData, NULL);
#else
	    Tcl_CreateObjCommand(interp, Tcl_GetString(fqdnObj),
		    map[i].proc, clientData, NULL);
#endif
	} else if (map[i].subensemble) {
	    TkMakeEnsemble(interp, Tcl_DStringValue(&ds),
		    map[i].name, clientData, map[i].subensemble);
	}
    }

    if (ensemble) {
	Tcl_SetEnsembleMappingDict(interp, ensemble, dictObj);
    }

    Tcl_DStringFree(&ds);
    return ensemble;
}

/*
 *----------------------------------------------------------------------
 *
 * TkScalingLevel --
 *
 *	Returns the display's DPI scaling level as 1.0, 1.25, 1.5, ....
 *
 * Results:
 *      The scaling level.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */

double
TkScalingLevel(
    Tk_Window tkwin)
{
    Tcl_Interp *interp = Tk_Interp(tkwin);
    Tcl_Obj *scalingPctPtr = Tcl_GetVar2Ex(interp, "::tk::scalingPct", NULL,
	    TCL_GLOBAL_ONLY);
    if (scalingPctPtr == NULL) {
	return 1.0;
    } else {
	int scalingPct;
	Tcl_GetIntFromObj(interp, scalingPctPtr, &scalingPct);
	return scalingPct / 100.0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SendVirtualEvent --
 *
 * 	Send a virtual event notification to the specified target window.
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
    event.general.xany.type = VirtualEvent;
    event.general.xany.serial = NextRequest(Tk_Display(target));
    event.general.xany.send_event = False;
    event.general.xany.window = Tk_WindowId(target);
    event.general.xany.display = Tk_Display(target);
    event.virt.name = Tk_GetUid(eventName);
    event.virt.user_data = detail;


    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

#if TCL_UTF_MAX <= 4
/*
 *---------------------------------------------------------------------------
 *
 * TkUtfToUniChar --
 *
 *	Almost the same as Tcl_UtfToUniChar but using int instead of Tcl_UniChar.
 *	This function is capable of collapsing a upper/lower surrogate pair to a
 *	single unicode character. So, up to 6 bytes might be consumed.
 *
 * Results:
 *	*chPtr is filled with the Tcl_UniChar, and the return value is the
 *	number of bytes from the UTF-8 string that were consumed.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

size_t
TkUtfToUniChar(
    const char *src,	/* The UTF-8 string. */
    int *chPtr)		/* Filled with the Unicode value represented by
			 * the UTF-8 string. */
{
    Tcl_UniChar uniChar = 0;

    size_t len = Tcl_UtfToUniChar(src, &uniChar);
    if ((sizeof(Tcl_UniChar) == 2)
	    && ((uniChar & 0xFC00) == 0xD800)
#if TCL_MAJOR_VERSION > 8
	    && (len == 1)
#endif
	) {
	Tcl_UniChar low = uniChar;
	/* This can only happen if Tcl is compiled with TCL_UTF_MAX=4,
	 * or when a high surrogate character is detected in UTF-8 form */
	size_t len2 = Tcl_UtfToUniChar(src+len, &low);
	if ((low & 0xFC00) == 0xDC00) {
	    *chPtr = (((uniChar & 0x3FF) << 10) | (low & 0x3FF)) + 0x10000;
	    return len + len2;
	}
    }
    *chPtr = uniChar;
    return len;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkUniCharToUtf --
 *
 *	Almost the same as Tcl_UniCharToUtf but producing 2 x 3-byte UTF-8
 *	sequences for out-of-bmp characters when TCL_UTF_MAX==3.
 *	So, up to 6 bytes might be produced.
 *
 * Results:
 *	*buf is filled with the UTF-8 string, and the return value is the
 *	number of bytes produced.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

size_t TkUniCharToUtf(int ch, char *buf)
{
    if ((sizeof(Tcl_UniChar) == 2) && (((unsigned)(ch - 0x10000) <= 0xFFFFF))) {
	/* Spit out a 4-byte UTF-8 character or 2 x 3-byte UTF-8 characters, depending on Tcl
	 * version and/or TCL_UTF_MAX build value */
	int len = Tcl_UniCharToUtf(0xD800 | ((ch - 0x10000) >> 10), buf);
	return len + Tcl_UniCharToUtf(0xDC00 | (ch & 0x7FF), buf + len);
    }
    return Tcl_UniCharToUtf(ch, buf);
}
/*
 *---------------------------------------------------------------------------
 *
 * TkUtfPrev --
 *
 *	Almost the same as Tcl_UtfPrev.
 *	This function is capable of jumping over a upper/lower surrogate pair.
 *	So, might jump back up to 6 bytes.
 *
 * Results:
 *	pointer to the first byte of the current UTF-8 character. A surrogate
 *	pair is also handled as being a single entity.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

const char *
TkUtfPrev(
    const char *src,	/* The UTF-8 string. */
    const char *start)		/* Start position of string */
{
    const char *p = Tcl_UtfPrev(src, start);
    const char *first = Tcl_UtfPrev(p, start);
    int ch;

#if TCL_UTF_MAX == 3
    if ((src - start > 3) && ((src[-1] & 0xC0) == 0x80) && ((src[-2] & 0xC0) == 0x80)
	    && ((src[-3] & 0xC0) == 0x80) && (UCHAR(src[-4]) >= 0xF0)) {
	return src - 4;
    }
#endif

    return (first + TkUtfToUniChar(first, &ch) >= src) ? first : p ;
}

#endif

#if TCL_MAJOR_VERSION > 8
unsigned char *
TkGetByteArrayFromObj(
	Tcl_Obj *objPtr,
	size_t *lengthPtr
) {
    unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, NULL);
    *lengthPtr = *(size_t *) objPtr->internalRep.twoPtrValue.ptr1;
    return result;
}
#endif /* TCL_MAJOR_VERSION > 8 */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248

































































































































1249
1250
1251
1252
1253
1254
1255
    event.general.xany.type = VirtualEvent;
    event.general.xany.serial = NextRequest(Tk_Display(target));
    event.general.xany.send_event = False;
    event.general.xany.window = Tk_WindowId(target);
    event.general.xany.display = Tk_Display(target);
    event.virt.name = Tk_GetUid(eventName);
    event.virt.user_data = detail;
    if (detail) Tcl_IncrRefCount(detail); // Event code will DecrRefCount

    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}


































































































































/*
 * 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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"








|
|







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 © 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"

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
	    Tcl_Obj *msgObj = Tcl_ObjPrintf(
		    "unknown or ambiguous visual name \"%s\": class must be ",
		    string);

	    for (dictPtr = visualNames; dictPtr->minLength; dictPtr++) {
		Tcl_AppendPrintfToObj(msgObj, "%s, ", dictPtr->name);
	    }
	    Tcl_AppendToObj(msgObj, "or default", -1);
	    Tcl_SetObjResult(interp, msgObj);
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "VISUAL", string, NULL);
	    return NULL;
	}
	while (isspace(UCHAR(*p))) {
	    p++;
	}







|







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
	    Tcl_Obj *msgObj = Tcl_ObjPrintf(
		    "unknown or ambiguous visual name \"%s\": class must be ",
		    string);

	    for (dictPtr = visualNames; dictPtr->minLength; dictPtr++) {
		Tcl_AppendPrintfToObj(msgObj, "%s, ", dictPtr->name);
	    }
	    Tcl_AppendToObj(msgObj, "or default", TCL_INDEX_NONE);
	    Tcl_SetObjResult(interp, msgObj);
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "VISUAL", string, NULL);
	    return NULL;
	}
	while (isspace(UCHAR(*p))) {
	    p++;
	}
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

    templ.screen = Tk_ScreenNumber(tkwin);
    mask |= VisualScreenMask;
    visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &templ,
	    &numVisuals);
    if (visInfoList == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't find an appropriate visual", -1));
	Tcl_SetErrorCode(interp, "TK", "VISUAL", "INAPPROPRIATE", NULL);
	return NULL;
    }

    /*
     * Search through the visuals that were returned to find the best one.
     * The choice is based on the following criteria, in decreasing order of







|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

    templ.screen = Tk_ScreenNumber(tkwin);
    mask |= VisualScreenMask;
    visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &templ,
	    &numVisuals);
    if (visInfoList == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't find an appropriate visual", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "VISUAL", "INAPPROPRIATE", NULL);
	return NULL;
    }

    /*
     * Search through the visuals that were returned to find the best one.
     * The choice is based on the following criteria, in decreasing order of
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    newBest:
	bestPtr = &visInfoList[i];
	bestPrio = prio;
    }
    CLANG_ASSERT(bestPtr);
    *depthPtr = bestPtr->depth;
    visual = bestPtr->visual;
    XFree((char *) visInfoList);

    /*
     * If we need to find a colormap for this visual, do it now. If the visual
     * is the default visual for the screen, then use the default colormap.
     * Otherwise search for an existing colormap that's shareable. If all else
     * fails, create a new colormap.
     */







|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    newBest:
	bestPtr = &visInfoList[i];
	bestPrio = prio;
    }
    CLANG_ASSERT(bestPtr);
    *depthPtr = bestPtr->depth;
    visual = bestPtr->visual;
    XFree(visInfoList);

    /*
     * If we need to find a colormap for this visual, do it now. If the visual
     * is the default visual for the screen, then use the default colormap.
     * Otherwise search for an existing colormap that's shareable. If all else
     * fails, create a new colormap.
     */

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
24
25
26
27
28
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkPort.h"
#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif


/*
 * Type used to keep track of Window objects that were only partially
 * deallocated by Tk_DestroyWindow.
 */

#define HD_CLEANUP		1







|
|












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * 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 © 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
#include "tkUuid.h"

/*
 * Type used to keep track of Window objects that were only partially
 * deallocated by Tk_DestroyWindow.
 */

#define HD_CLEANUP		1
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
 * the C functions that execute them.
 */

#define ISSAFE 1
#define PASSMAINWINDOW 2
#define WINMACONLY 4
#define USEINITPROC 8


typedef int (TkInitProc)(Tcl_Interp *interp, ClientData clientData);
typedef struct {
    const char *name;		/* Name of command. */
    Tcl_ObjCmdProc *objProc;	/* Command's object- (or string-) based
				 * function, or initProc. */
    int flags;
} TkCmd;








>

|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 * the C functions that execute them.
 */

#define ISSAFE 1
#define PASSMAINWINDOW 2
#define WINMACONLY 4
#define USEINITPROC 8
#define SAVEUPDATECMD 16 /* better only be one of these! */

typedef int (TkInitProc)(Tcl_Interp *interp, void *clientData);
typedef struct {
    const char *name;		/* Name of command. */
    Tcl_ObjCmdProc *objProc;	/* Command's object- (or string-) based
				 * function, or initProc. */
    int flags;
} TkCmd;

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    {"option",		Tk_OptionObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"pack",		Tk_PackObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"place",		Tk_PlaceObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"raise",		Tk_RaiseObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"selection",	Tk_SelectionObjCmd,	PASSMAINWINDOW},
    {"tk",		(Tcl_ObjCmdProc *)(void *)TkInitTkCmd,  USEINITPROC|PASSMAINWINDOW|ISSAFE},
    {"tkwait",		Tk_TkwaitObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"update",		Tk_UpdateObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"winfo",		Tk_WinfoObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"wm",		Tk_WmObjCmd,		PASSMAINWINDOW},

    /*
     * Default widget class commands.
     */








|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    {"option",		Tk_OptionObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"pack",		Tk_PackObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"place",		Tk_PlaceObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"raise",		Tk_RaiseObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"selection",	Tk_SelectionObjCmd,	PASSMAINWINDOW},
    {"tk",		(Tcl_ObjCmdProc *)(void *)TkInitTkCmd,  USEINITPROC|PASSMAINWINDOW|ISSAFE},
    {"tkwait",		Tk_TkwaitObjCmd,	PASSMAINWINDOW|ISSAFE},
    {"update",		Tk_UpdateObjCmd,	PASSMAINWINDOW|ISSAFE|SAVEUPDATECMD},
    {"winfo",		Tk_WinfoObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"wm",		Tk_WmObjCmd,		PASSMAINWINDOW},

    /*
     * Default widget class commands.
     */

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
 * Forward declarations to functions defined later in this file:
 */

static Tk_Window	CreateTopLevelWindow(Tcl_Interp *interp,
			    Tk_Window parent, const char *name,
			    const char *screenName, unsigned int flags);
static void		DeleteWindowsExitProc(ClientData clientData);
static TkDisplay *	GetScreen(Tcl_Interp *interp, const char *screenName,
			    int *screenPtr);
static int		Initialize(Tcl_Interp *interp);
static int		NameWindow(Tcl_Interp *interp, TkWindow *winPtr,
			    TkWindow *parentPtr, const char *name);
static void		UnlinkWindow(TkWindow *winPtr);








|







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
 * Forward declarations to functions defined later in this file:
 */

static Tk_Window	CreateTopLevelWindow(Tcl_Interp *interp,
			    Tk_Window parent, const char *name,
			    const char *screenName, unsigned int flags);
static void		DeleteWindowsExitProc(void *clientData);
static TkDisplay *	GetScreen(Tcl_Interp *interp, const char *screenName,
			    int *screenPtr);
static int		Initialize(Tcl_Interp *interp);
static int		NameWindow(Tcl_Interp *interp, TkWindow *winPtr,
			    TkWindow *parentPtr, const char *name);
static void		UnlinkWindow(TkWindow *winPtr);

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
	Tk_CreateImageType(&tkBitmapImageType);
	Tk_CreateImageType(&tkPhotoImageType);

	/*
	 * Create built-in photo image formats.
	 */

        Tk_CreatePhotoImageFormat(&tkImgFmtDefault);
	Tk_CreatePhotoImageFormat(&tkImgFmtGIF);
	Tk_CreatePhotoImageFormat(&tkImgFmtPNG);
	Tk_CreatePhotoImageFormat(&tkImgFmtPPM);
	Tk_CreatePhotoImageFormat(&tkImgFmtSVGnano);
    }

    if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) {
	dispPtr = ((TkWindow *) parent)->dispPtr;
	screenId = Tk_ScreenNumber(parent);







|
|
|







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
	Tk_CreateImageType(&tkBitmapImageType);
	Tk_CreateImageType(&tkPhotoImageType);

	/*
	 * Create built-in photo image formats.
	 */

	Tk_CreatePhotoImageFormat(&tkImgFmtDefault);
	Tk_CreatePhotoImageFormatVersion3(&tkImgFmtGIF);
	Tk_CreatePhotoImageFormatVersion3(&tkImgFmtPNG);
	Tk_CreatePhotoImageFormat(&tkImgFmtPPM);
	Tk_CreatePhotoImageFormat(&tkImgFmtSVGnano);
    }

    if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) {
	dispPtr = ((TkWindow *) parent)->dispPtr;
	screenId = Tk_ScreenNumber(parent);
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
     * ScreenName is assumed to have the syntax <display>.<screen> with the
     * dot and the screen being optional.
     */

    screenName = TkGetDefaultScreenName(interp, screenName);
    if (screenName == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no display name and no $DISPLAY environment variable", -1));
	Tcl_SetErrorCode(interp, "TK", "NO_DISPLAY", NULL);
	return NULL;
    }
    length = strlen(screenName);
    screenId = 0;
    p = screenName+length-1;
    while (isdigit(UCHAR(*p)) && (p != screenName)) {
	p--;
    }
    if ((*p == '.') && (p[1] != '\0')) {
	length = p - screenName;
	screenId = strtoul(p+1, NULL, 10);
    }

    /*
     * See if we already have a connection to this display. If not, then open
     * a new connection.
     */








|










|
|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
     * ScreenName is assumed to have the syntax <display>.<screen> with the
     * dot and the screen being optional.
     */

    screenName = TkGetDefaultScreenName(interp, screenName);
    if (screenName == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no display name and no $DISPLAY environment variable", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "NO_DISPLAY", NULL);
	return NULL;
    }
    length = strlen(screenName);
    screenId = 0;
    p = screenName+length-1;
    while (isdigit(UCHAR(*p)) && (p != screenName)) {
	p--;
    }
    if ((*p == '.') && (p[1] != '\0')) {
	length = (size_t)(p - screenName);
	screenId = (int)strtoul(p+1, NULL, 10);
    }

    /*
     * See if we already have a connection to this display. If not, then open
     * a new connection.
     */

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
    winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity;
    winPtr->flags = 0;
    winPtr->handlerList = NULL;
    winPtr->ximGeneration = 0;
    winPtr->inputContext = NULL;
    winPtr->tagPtr = NULL;
    winPtr->numTags = 0;
    winPtr->optionLevel = -1;
    winPtr->selHandlerList = NULL;
    winPtr->geomMgrPtr = NULL;
    winPtr->geomData = NULL;
    winPtr->geomMgrName = NULL;
    winPtr->maintainerPtr = NULL;
    winPtr->reqWidth = winPtr->reqHeight = 1;
    winPtr->internalBorderLeft = 0;







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
    winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity;
    winPtr->flags = 0;
    winPtr->handlerList = NULL;
    winPtr->ximGeneration = 0;
    winPtr->inputContext = NULL;
    winPtr->tagPtr = NULL;
    winPtr->numTags = 0;
    winPtr->optionLevel = TCL_INDEX_NONE;
    winPtr->selHandlerList = NULL;
    winPtr->geomMgrPtr = NULL;
    winPtr->geomData = NULL;
    winPtr->geomMgrName = NULL;
    winPtr->maintainerPtr = NULL;
    winPtr->reqWidth = winPtr->reqHeight = 1;
    winPtr->internalBorderLeft = 0;
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
 *	with the window and registered for "send" commands under "baseName".
 *	BaseName may be extended with an instance number in the form "#2" if
 *	necessary to make it globally unique. Tk-related commands are bound
 *	into interp.
 *
 *----------------------------------------------------------------------
 */






Tk_Window
TkCreateMainWindow(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    const char *screenName,	/* Name of screen on which to create window.
				 * Empty or NULL string means use DISPLAY
				 * environment variable. */
    const char *baseName)	/* Base name for application; usually of the
				 * form "prog instance". */
{
    Tk_Window tkwin;
    int dummy, isSafe;
    Tcl_HashEntry *hPtr;
    TkMainInfo *mainPtr;
    TkWindow *winPtr;
    const TkCmd *cmdPtr;
    ClientData clientData;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Panic if someone updated the TkWindow structure without also updating
     * the Tk_FakeWin structure (or vice versa).
     */







>
>
>
>
>
















|
>







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
 *	with the window and registered for "send" commands under "baseName".
 *	BaseName may be extended with an instance number in the form "#2" if
 *	necessary to make it globally unique. Tk-related commands are bound
 *	into interp.
 *
 *----------------------------------------------------------------------
 */

#ifndef STRINGIFY
#  define STRINGIFY(x) STRINGIFY1(x)
#  define STRINGIFY1(x) #x
#endif

Tk_Window
TkCreateMainWindow(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    const char *screenName,	/* Name of screen on which to create window.
				 * Empty or NULL string means use DISPLAY
				 * environment variable. */
    const char *baseName)	/* Base name for application; usually of the
				 * form "prog instance". */
{
    Tk_Window tkwin;
    int dummy, isSafe;
    Tcl_HashEntry *hPtr;
    TkMainInfo *mainPtr;
    TkWindow *winPtr;
    const TkCmd *cmdPtr;
    void *clientData;
    Tcl_CmdInfo info;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Panic if someone updated the TkWindow structure without also updating
     * the Tk_FakeWin structure (or vice versa).
     */
872
873
874
875
876
877
878




879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
    TkStylePkgInit(mainPtr);
    mainPtr->tlFocusPtr = NULL;
    mainPtr->displayFocusPtr = NULL;
    mainPtr->optionRootPtr = NULL;
    Tcl_InitHashTable(&mainPtr->imageTable, TCL_STRING_KEYS);
    mainPtr->strictMotif = 0;
    mainPtr->alwaysShowSelection = 0;




    if (Tcl_LinkVar(interp, "tk_strictMotif", (char *) &mainPtr->strictMotif,
	    TCL_LINK_BOOLEAN) != TCL_OK) {
	Tcl_ResetResult(interp);
    }
    if (Tcl_CreateNamespace(interp, "::tk", NULL, NULL) == NULL) {
	Tcl_ResetResult(interp);
    }
    if (Tcl_LinkVar(interp, "::tk::AlwaysShowSelection",
	    (char *) &mainPtr->alwaysShowSelection,
	    TCL_LINK_BOOLEAN) != TCL_OK) {
	Tcl_ResetResult(interp);
    }
    mainPtr->nextPtr = tsdPtr->mainWindowList;
    tsdPtr->mainWindowList = mainPtr;
    winPtr->mainPtr = mainPtr;
    hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy);







>
>
>
>
|







|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    TkStylePkgInit(mainPtr);
    mainPtr->tlFocusPtr = NULL;
    mainPtr->displayFocusPtr = NULL;
    mainPtr->optionRootPtr = NULL;
    Tcl_InitHashTable(&mainPtr->imageTable, TCL_STRING_KEYS);
    mainPtr->strictMotif = 0;
    mainPtr->alwaysShowSelection = 0;
    mainPtr->tclUpdateObjProc = NULL;
#if TCL_MAJOR_VERSION > 8
    mainPtr->tclUpdateObjProc2 = NULL;
#endif
    if (Tcl_LinkVar(interp, "tk_strictMotif", &mainPtr->strictMotif,
	    TCL_LINK_BOOLEAN) != TCL_OK) {
	Tcl_ResetResult(interp);
    }
    if (Tcl_CreateNamespace(interp, "::tk", NULL, NULL) == NULL) {
	Tcl_ResetResult(interp);
    }
    if (Tcl_LinkVar(interp, "::tk::AlwaysShowSelection",
	    &mainPtr->alwaysShowSelection,
	    TCL_LINK_BOOLEAN) != TCL_OK) {
	Tcl_ResetResult(interp);
    }
    mainPtr->nextPtr = tsdPtr->mainWindowList;
    tsdPtr->mainWindowList = mainPtr;
    winPtr->mainPtr = mainPtr;
    hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy);
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

    /*
     * Bind in Tk's commands.
     */

    isSafe = Tcl_IsSafe(interp);
    for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {


	if (cmdPtr->objProc == NULL) {
	    Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
	}

#if defined(_WIN32) && !defined(STATIC_BUILD)
	if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) {
	    /*
	     * We are running on Cygwin, so don't use the win32 dialogs.
	     */

	    continue;
	}
#endif /* _WIN32 && !STATIC_BUILD */

	if (cmdPtr->flags & PASSMAINWINDOW) {
	    clientData = tkwin;
	} else {
	    clientData = NULL;
	}












	if (cmdPtr->flags & USEINITPROC) {
	    ((TkInitProc *)(void *)cmdPtr->objProc)(interp, clientData);
	} else {
	    Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc,
		    clientData, NULL);
	}
	if (isSafe && !(cmdPtr->flags & ISSAFE)) {
	    Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name);
	}




















































































    }

    /*
     * Set variables for the interpreter.
     */

    Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);







>
>





|













>
>
>
>
>
>
>
>
>
>
>
>









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

    /*
     * Bind in Tk's commands.
     */

    isSafe = Tcl_IsSafe(interp);
    for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
	Tcl_CmdInfo cmdInfo;

	if (cmdPtr->objProc == NULL) {
	    Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
	}

#if defined(_WIN32) && !defined(STATIC_BUILD)
	if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->tcl_CreateFileHandler) {
	    /*
	     * We are running on Cygwin, so don't use the win32 dialogs.
	     */

	    continue;
	}
#endif /* _WIN32 && !STATIC_BUILD */

	if (cmdPtr->flags & PASSMAINWINDOW) {
	    clientData = tkwin;
	} else {
	    clientData = NULL;
	}
	if ((cmdPtr->flags & SAVEUPDATECMD) &&
	    Tcl_GetCommandInfo(interp, cmdPtr->name, &cmdInfo) &&
	    cmdInfo.isNativeObjectProc && !cmdInfo.deleteProc) {
#if TCL_MAJOR_VERSION > 8
	    if ((cmdInfo.isNativeObjectProc == 2) && !cmdInfo.objClientData2) {
		mainPtr->tclUpdateObjProc2 = cmdInfo.objProc2;
	    } else
#endif
	    if (!cmdInfo.objClientData) {
		mainPtr->tclUpdateObjProc = cmdInfo.objProc;
	    }
	}
	if (cmdPtr->flags & USEINITPROC) {
	    ((TkInitProc *)(void *)cmdPtr->objProc)(interp, clientData);
	} else {
	    Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc,
		    clientData, NULL);
	}
	if (isSafe && !(cmdPtr->flags & ISSAFE)) {
	    Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name);
	}
    }
    if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) {
	static const char version[] = TK_PATCH_LEVEL "+" STRINGIFY(TK_VERSION_UUID)
#if defined(MAC_OSX_TK)
		".aqua"
#endif
#if defined(__clang__) && defined(__clang_major__)
		".clang-" STRINGIFY(__clang_major__)
#if __clang_minor__ < 10
		"0"
#endif
		STRINGIFY(__clang_minor__)
#endif
#if defined(__cplusplus) && !defined(__OBJC__)
		".cplusplus"
#endif
#ifndef NDEBUG
		".debug"
#endif
#if !defined(__clang__) && !defined(__INTEL_COMPILER) && defined(__GNUC__)
		".gcc-" STRINGIFY(__GNUC__)
#if __GNUC_MINOR__ < 10
		"0"
#endif
		STRINGIFY(__GNUC_MINOR__)
#endif
#ifdef __INTEL_COMPILER
		".icc-" STRINGIFY(__INTEL_COMPILER)
#endif
#ifdef TCL_MEM_DEBUG
		".memdebug"
#endif
#if defined(_MSC_VER)
		".msvc-" STRINGIFY(_MSC_VER)
#endif
#ifdef USE_NMAKE
		".nmake"
#endif
#ifdef TK_NO_DEPRECATED
		".no-deprecate"
#endif
#ifndef TCL_CFG_OPTIMIZED
		".no-optimize"
#endif
#ifdef __OBJC__
		".objective-c"
#if defined(__cplusplus)
		"plusplus"
#endif
#endif
#ifdef TCL_CFG_PROFILED
		".profile"
#endif
#ifdef PURIFY
		".purify"
#endif
		".revised-text"
#ifdef STATIC_BUILD
		".static"
#endif
#if TCL_UTF_MAX < 4
		".utf-16"
#endif
#if defined(_WIN32)
		".win32"
#endif
#if !defined(_WIN32) && !defined(MAC_OSX_TK)
		".x11"
#if !defined(HAVE_XFT)
		".no-xft"
#endif
#endif
		;
#if TCL_MAJOR_VERSION > 8
	if (info.isNativeObjectProc == 2) {
	    Tcl_CreateObjCommand2(interp, "::tk::build-info",
		    info.objProc2, (void *)
		    version, NULL);

	} else
#endif
	Tcl_CreateObjCommand(interp, "::tk::build-info",
		info.objProc, (void *)
		version, NULL);
    }

    /*
     * Set variables for the interpreter.
     */

    Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;

    if (parentPtr) {
	if (parentPtr->flags & TK_ALREADY_DEAD) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: parent has been destroyed", -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	    return NULL;
	} else if (parentPtr->flags & TK_CONTAINER) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: its parent has -container = yes",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	    return NULL;
	} else if (screenName == NULL) {
	    TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr,
		    parentPtr->screenNum, parentPtr);

	    if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) {







|





|







1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;

    if (parentPtr) {
	if (parentPtr->flags & TK_ALREADY_DEAD) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: parent has been destroyed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	    return NULL;
	} else if (parentPtr->flags & TK_CONTAINER) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: its parent has -container = yes",
		    TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	    return NULL;
	} else if (screenName == NULL) {
	    TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr,
		    parentPtr->screenNum, parentPtr);

	    if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) {
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;

    if (parentPtr) {
	if (parentPtr->flags & TK_ALREADY_DEAD) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: parent has been destroyed", -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	    return NULL;
	} else if (parentPtr->flags & TK_CONTAINER) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: its parent has -container = yes",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	    return NULL;
	} else if (screenName == NULL) {
	    TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr,
		    parentPtr->screenNum, parentPtr);
	    /*
	     * Add the anonymous window flag now, so that NameWindow will







|





|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
				 * window. */
{
    TkWindow *parentPtr = (TkWindow *) parent;

    if (parentPtr) {
	if (parentPtr->flags & TK_ALREADY_DEAD) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: parent has been destroyed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	    return NULL;
	} else if (parentPtr->flags & TK_CONTAINER) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't create window: its parent has -container = yes",
		    TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	    return NULL;
	} else if (screenName == NULL) {
	    TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr,
		    parentPtr->screenNum, parentPtr);
	    /*
	     * Add the anonymous window flag now, so that NameWindow will
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
    p = (char *)strrchr(pathName, '.');
    if (p == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad window path name \"%s\"", pathName));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	return NULL;
    }
    numChars = p-pathName;
    if (numChars > FIXED_SPACE) {
	p = (char *)ckalloc(numChars + 1);
    } else {
	p = fixedSpace;
    }
    if (numChars == 0) {
	*p = '.';







|







1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
    p = (char *)strrchr(pathName, '.');
    if (p == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad window path name \"%s\"", pathName));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	return NULL;
    }
    numChars = (size_t)(p - pathName);
    if (numChars > FIXED_SPACE) {
	p = (char *)ckalloc(numChars + 1);
    } else {
	p = fixedSpace;
    }
    if (numChars == 0) {
	*p = '.';
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
	ckfree(p);
    }
    if (parent == NULL) {
	return NULL;
    }
    if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't create window: parent has been destroyed", -1));
	Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	return NULL;
    } else if (((TkWindow *) parent)->flags & TK_CONTAINER) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't create window: its parent has -container = yes", -1));
	Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	return NULL;
    }

    /*
     * Create the window.
     */







|




|







1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
	ckfree(p);
    }
    if (parent == NULL) {
	return NULL;
    }
    if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't create window: parent has been destroyed", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL);
	return NULL;
    } else if (((TkWindow *) parent)->flags & TK_CONTAINER) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't create window: its parent has -container = yes", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL);
	return NULL;
    }

    /*
     * Create the window.
     */
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
 *--------------------------------------------------------------
 */

void
Tk_DestroyWindow(
    Tk_Window tkwin)		/* Window to destroy. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    XEvent event;
    TkHalfdeadWindow *halfdeadPtr, *prev_halfdeadPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->flags & TK_ALREADY_DEAD) {







|







1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
 *--------------------------------------------------------------
 */

void
Tk_DestroyWindow(
    Tk_Window tkwin)		/* Window to destroy. */
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;
    XEvent event;
    TkHalfdeadWindow *halfdeadPtr, *prev_halfdeadPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->flags & TK_ALREADY_DEAD) {
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
	halfdeadPtr->winPtr = winPtr;
	halfdeadPtr->nextPtr = tsdPtr->halfdeadWindowList;
	tsdPtr->halfdeadWindowList = halfdeadPtr;
    }

    /*
     * Some cleanup needs to be done immediately, rather than later, because
     * it needs information that will be destoyed before we get to the main
     * cleanup point. For example, TkFocusDeadWindow needs to access the
     * parentPtr field from a window, but if a Destroy event handler deletes
     * the window's parent this field will be NULL before the main cleanup
     * point is reached.
     */

    if (!(halfdeadPtr->flags & HD_FOCUS)) {







|







1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
	halfdeadPtr->winPtr = winPtr;
	halfdeadPtr->nextPtr = tsdPtr->halfdeadWindowList;
	tsdPtr->halfdeadWindowList = halfdeadPtr;
    }

    /*
     * Some cleanup needs to be done immediately, rather than later, because
     * it needs information that will be destroyed before we get to the main
     * cleanup point. For example, TkFocusDeadWindow needs to access the
     * parentPtr field from a window, but if a Destroy event handler deletes
     * the window's parent this field will be NULL before the main cleanup
     * point is reached.
     */

    if (!(halfdeadPtr->flags & HD_FOCUS)) {
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
	/*
	 * This is the container for an embedded application, and the embedded
	 * application is also in this process. Delete the embedded window
	 * in-line here, for the same reasons we delete children in-line
	 * (otherwise, for example, the Tk window may appear to exist even
	 * though its X window is gone; this could cause errors). Special
	 * note: it's possible that the embedded window has already been
	 * deleted, in which case TkpGetOtherWindow will return NULL.
	 */

	TkWindow *childPtr = TkpGetOtherWindow(winPtr);

	if (childPtr != NULL) {
	    childPtr->flags |= TK_DONT_DESTROY_WINDOW;
	    Tk_DestroyWindow((Tk_Window) childPtr);
	}
    }








|


|







1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
	/*
	 * This is the container for an embedded application, and the embedded
	 * application is also in this process. Delete the embedded window
	 * in-line here, for the same reasons we delete children in-line
	 * (otherwise, for example, the Tk window may appear to exist even
	 * though its X window is gone; this could cause errors). Special
	 * note: it's possible that the embedded window has already been
	 * deleted, in which case Tk_GetOtherWindow will return NULL.
	 */

	TkWindow *childPtr = (TkWindow *)Tk_GetOtherWindow(tkwin);

	if (childPtr != NULL) {
	    childPtr->flags |= TK_DONT_DESTROY_WINDOW;
	    Tk_DestroyWindow((Tk_Window) childPtr);
	}
    }

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
	     *
	     * NOTE: Only replace the commands it if the interpreter is not
	     * being deleted. If it *is*, the interpreter cleanup will do all
	     * the needed work.
	     */

	    if ((winPtr->mainPtr->interp != NULL) &&
		    !Tcl_InterpDeleted(winPtr->mainPtr->interp)) {
		for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {











		    Tcl_CreateObjCommand(winPtr->mainPtr->interp, cmdPtr->name,


			    TkDeadAppObjCmd, NULL, NULL);






		}
		Tcl_CreateObjCommand(winPtr->mainPtr->interp, "send",
			TkDeadAppObjCmd, NULL, NULL);
		Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif");
		Tcl_UnlinkVar(winPtr->mainPtr->interp,
			"::tk::AlwaysShowSelection");
	    }

	    Tcl_DeleteHashTable(&winPtr->mainPtr->busyTable);
	    Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable);
	    TkBindFree(winPtr->mainPtr);
	    TkDeleteAllImages(winPtr->mainPtr);
	    TkFontPkgFree(winPtr->mainPtr);
	    TkFocusFree(winPtr->mainPtr);
	    TkStylePkgFree(winPtr->mainPtr);


	    /*
	     * When embedding Tk into other applications, make sure that all
	     * destroy events reach the server. Otherwise the embedding
	     * application may also attempt to destroy the windows, resulting
	     * in an X error
	     */







|

>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>















>







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
	     *
	     * NOTE: Only replace the commands it if the interpreter is not
	     * being deleted. If it *is*, the interpreter cleanup will do all
	     * the needed work.
	     */

	    if ((winPtr->mainPtr->interp != NULL) &&
		!Tcl_InterpDeleted(winPtr->mainPtr->interp)) {
		for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
		    if (cmdPtr->flags & SAVEUPDATECMD) {
			/* Restore Tcl's version of [update] */
#if TCL_MAJOR_VERSION > 8
			if (winPtr->mainPtr->tclUpdateObjProc2 != NULL) {
			    Tcl_CreateObjCommand2(winPtr->mainPtr->interp,
				    cmdPtr->name,
				    winPtr->mainPtr->tclUpdateObjProc2,
				    NULL, NULL);
			} else
#endif
			if (winPtr->mainPtr->tclUpdateObjProc != NULL) {
			    Tcl_CreateObjCommand(winPtr->mainPtr->interp,
				    cmdPtr->name,
				    winPtr->mainPtr->tclUpdateObjProc,
				    NULL, NULL);
			}
		    } else {
			Tcl_CreateObjCommand(winPtr->mainPtr->interp,
					     cmdPtr->name, TkDeadAppObjCmd,
					     NULL, NULL);
		    }
		}
		Tcl_CreateObjCommand(winPtr->mainPtr->interp, "send",
			TkDeadAppObjCmd, NULL, NULL);
		Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif");
		Tcl_UnlinkVar(winPtr->mainPtr->interp,
			"::tk::AlwaysShowSelection");
	    }

	    Tcl_DeleteHashTable(&winPtr->mainPtr->busyTable);
	    Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable);
	    TkBindFree(winPtr->mainPtr);
	    TkDeleteAllImages(winPtr->mainPtr);
	    TkFontPkgFree(winPtr->mainPtr);
	    TkFocusFree(winPtr->mainPtr);
	    TkStylePkgFree(winPtr->mainPtr);
	    Ttk_TkDestroyedHandler(winPtr->mainPtr->interp);

	    /*
	     * When embedding Tk into other applications, make sure that all
	     * destroy events reach the server. Otherwise the embedding
	     * application may also attempt to destroy the windows, resulting
	     * in an X error
	     */
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
    event.type = MapNotify;
    event.xmap.serial = LastKnownRequestProcessed(winPtr->display);
    event.xmap.send_event = False;
    event.xmap.display = winPtr->display;
    event.xmap.event = winPtr->window;
    event.xmap.window = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MakeWindowExist --
 *







|







1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
    event.type = MapNotify;
    event.xmap.serial = LastKnownRequestProcessed(winPtr->display);
    event.xmap.send_event = False;
    event.xmap.display = winPtr->display;
    event.xmap.event = winPtr->window;
    event.xmap.window = winPtr->window;
    event.xmap.override_redirect = winPtr->atts.override_redirect;
    Tk_HandleEvent(&event);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MakeWindowExist --
 *
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
	parent = winPtr->parentPtr->window;
    }

    createProc = Tk_GetClassProc(winPtr->classProcsPtr, createProc);
    if (createProc != NULL && parent != None) {
	winPtr->window = createProc(tkwin, parent, winPtr->instanceData);
    } else {
	winPtr->window = TkpMakeWindow(winPtr, parent);
    }

    hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable,
	    (char *) winPtr->window, &isNew);
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->dirtyAtts = 0;
    winPtr->dirtyChanges = 0;







|







1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
	parent = winPtr->parentPtr->window;
    }

    createProc = Tk_GetClassProc(winPtr->classProcsPtr, createProc);
    if (createProc != NULL && parent != None) {
	winPtr->window = createProc(tkwin, parent, winPtr->instanceData);
    } else {
	winPtr->window = Tk_MakeWindow(tkwin, parent);
    }

    hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable,
	    (char *) winPtr->window, &isNew);
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->dirtyAtts = 0;
    winPtr->dirtyChanges = 0;
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;
	TkpHandleMapOrUnmap((Tk_Window)winPtr, &event);
    }
}

void
Tk_ConfigureWindow(
    Tk_Window tkwin,		/* Window to re-configure. */
    unsigned int valueMask,	/* Mask indicating which parts of *valuePtr







|







1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
	event.type = UnmapNotify;
	event.xunmap.serial = LastKnownRequestProcessed(winPtr->display);
	event.xunmap.send_event = False;
	event.xunmap.display = winPtr->display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	Tk_HandleEvent(&event);
    }
}

void
Tk_ConfigureWindow(
    Tk_Window tkwin,		/* Window to re-configure. */
    unsigned int valueMask,	/* Mask indicating which parts of *valuePtr
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
void
Tk_ResizeWindow(
    Tk_Window tkwin,		/* Window to resize. */
    int width, int height)	/* New dimensions for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.width = (unsigned) width;
    winPtr->changes.height = (unsigned) height;
    if (winPtr->window != None) {
	XResizeWindow(winPtr->display, winPtr->window, (unsigned) width,
		(unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_MoveResizeWindow(
    Tk_Window tkwin,		/* Window to move and resize. */
    int x, int y,		/* New location for window (within parent). */
    int width, int height)	/* New dimensions for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    winPtr->changes.width = (unsigned) width;
    winPtr->changes.height = (unsigned) height;
    if (winPtr->window != None) {
	XMoveResizeWindow(winPtr->display, winPtr->window, x, y,
		(unsigned) width, (unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;







|
|




















|
|







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
void
Tk_ResizeWindow(
    Tk_Window tkwin,		/* Window to resize. */
    int width, int height)	/* New dimensions for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.width = width;
    winPtr->changes.height = height;
    if (winPtr->window != None) {
	XResizeWindow(winPtr->display, winPtr->window, (unsigned) width,
		(unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
    }
}

void
Tk_MoveResizeWindow(
    Tk_Window tkwin,		/* Window to move and resize. */
    int x, int y,		/* New location for window (within parent). */
    int width, int height)	/* New dimensions for window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    winPtr->changes.width = width;
    winPtr->changes.height = height;
    if (winPtr->window != None) {
	XMoveResizeWindow(winPtr->display, winPtr->window, x, y,
		(unsigned) width, (unsigned) height);
	TkDoConfigureNotify(winPtr);
    } else {
	winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight;
	winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
 *----------------------------------------------------------------------
 */

void
Tk_SetClassProcs(
    Tk_Window tkwin,		/* Token for window to modify. */
    const Tk_ClassProcs *procs,	/* Class procs structure. */
    ClientData instanceData)	/* Data to be passed to class functions. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->classProcsPtr = procs;
    winPtr->instanceData = instanceData;
}








|







2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
 *----------------------------------------------------------------------
 */

void
Tk_SetClassProcs(
    Tk_Window tkwin,		/* Token for window to modify. */
    const Tk_ClassProcs *procs,	/* Class procs structure. */
    void *instanceData)	/* Data to be passed to class functions. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    winPtr->classProcsPtr = procs;
    winPtr->instanceData = instanceData;
}

2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
    if (tkwin == NULL) {
	/*
	 * Either we're not really in Tk, or the main window was destroyed and
	 * we're on our way out of the application.
	 */

	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window",-1));
	    Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
	}
	return NULL;
    }

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
	    pathName);







|







2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
    if (tkwin == NULL) {
	/*
	 * Either we're not really in Tk, or the main window was destroyed and
	 * we're on our way out of the application.
	 */

	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window",TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
	}
	return NULL;
    }

    hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
	    pathName);
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
    for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL;
	    mainPtr = mainPtr->nextPtr) {
	if (mainPtr->interp == interp) {
	    return (Tk_Window) mainPtr->winPtr;
	}
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "this isn't a Tk application", -1));
    Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *







|







2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
    for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL;
	    mainPtr = mainPtr->nextPtr) {
	if (mainPtr->interp == interp) {
	    return (Tk_Window) mainPtr->winPtr;
	}
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "this isn't a Tk application", TCL_INDEX_NONE));
    Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteWindowsExitProc(
    ClientData clientData)	/* tsdPtr when handler was created. */
{
    TkDisplay *dispPtr, *nextPtr;
    Tcl_Interp *interp;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)clientData;

    if (tsdPtr == NULL) {
	return;







|







2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteWindowsExitProc(
    void *clientData)	/* tsdPtr when handler was created. */
{
    TkDisplay *dispPtr, *nextPtr;
    Tcl_Interp *interp;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)clientData;

    if (tsdPtr == NULL) {
	return;
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
/*
 * Run Tk_MainEx from libtk8.?.dll
 *
 * This function is only ever called from wish8.?.exe, the cygwin port of Tcl.
 * This means that the system encoding is utf-8, so we don't have to do any
 * encoding conversions.
 */


int
TkCygwinMainEx(
    int argc,			/* Number of arguments. */
    char **argv,		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * procedure to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{
    WCHAR name[MAX_PATH];
    size_t len;
    void (*tkmainex)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
    len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH);
    name[len-2] = '.';
    name[len-1] = name[len-5];
    wcscpy(name+len, L".dll");
    memcpy(name+len-8, L"libtk8", 6 * sizeof(WCHAR));

    tkcygwindll = LoadLibraryW(name);
    if (!tkcygwindll) {
	/* dll is not present */
	return 0;
    }
    tkmainex = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *))
	    (void *)GetProcAddress(tkcygwindll, "Tk_MainEx");
    if (!tkmainex) {
	return 0;
    }
    tkmainex(argc, argv, appInitProc, interp);
    return 1;
}







>



|









|


|










|







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
/*
 * Run Tk_MainEx from libtk8.?.dll
 *
 * This function is only ever called from wish8.?.exe, the cygwin port of Tcl.
 * This means that the system encoding is utf-8, so we don't have to do any
 * encoding conversions.
 */
extern int TkCygwinMainEx(Tcl_Size, char **, Tcl_AppInitProc *, Tcl_Interp *);

int
TkCygwinMainEx(
    Tcl_Size argc,			/* Number of arguments. */
    char **argv,		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * procedure to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{
    WCHAR name[MAX_PATH];
    size_t len;
    void (*tkmainex)(Tcl_Size, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
    len = GetModuleFileNameW((HINSTANCE)Tk_GetHINSTANCE(), name, MAX_PATH);
    name[len-2] = '.';
    name[len-1] = name[len-5];
    wcscpy(name+len, L".dll");
    memcpy(name+len-8, L"libtk8", 6 * sizeof(WCHAR));

    tkcygwindll = LoadLibraryW(name);
    if (!tkcygwindll) {
	/* dll is not present */
	return 0;
    }
    tkmainex = (void (*)(Tcl_Size, char **, Tcl_AppInitProc *, Tcl_Interp *))
	    (void *)GetProcAddress(tkcygwindll, "Tk_MainEx");
    if (!tkmainex) {
	return 0;
    }
    tkmainex(argc, argv, appInitProc, interp);
    return 1;
}
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
 *	Depends on the initialization scripts that are invoked.
 *
 *----------------------------------------------------------------------
 */

static int
CopyValue(
    ClientData dummy,
    Tcl_Obj *objPtr,
    void *dstPtr)
{
    (void)dummy;

    *(Tcl_Obj **)dstPtr = objPtr;
    return 1;
}

static int
Initialize(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
    int code = TCL_OK;
    ThreadSpecificData *tsdPtr;
    Tcl_Obj *value = NULL;
    Tcl_Obj *cmd;

    Tcl_Obj *nameObj = NULL;

    Tcl_Obj *classObj = NULL;
    Tcl_Obj *displayObj = NULL;
    Tcl_Obj *colorMapObj = NULL;
    Tcl_Obj *useObj = NULL;
    Tcl_Obj *visualObj = NULL;
    Tcl_Obj *geometryObj = NULL;








|



<
<














>







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
 *	Depends on the initialization scripts that are invoked.
 *
 *----------------------------------------------------------------------
 */

static int
CopyValue(
    TCL_UNUSED(void *),
    Tcl_Obj *objPtr,
    void *dstPtr)
{


    *(Tcl_Obj **)dstPtr = objPtr;
    return 1;
}

static int
Initialize(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
    int code = TCL_OK;
    ThreadSpecificData *tsdPtr;
    Tcl_Obj *value = NULL;
    Tcl_Obj *cmd;

    Tcl_Obj *nameObj = NULL;
    Tcl_Obj* appNameObj = NULL;
    Tcl_Obj *classObj = NULL;
    Tcl_Obj *displayObj = NULL;
    Tcl_Obj *colorMapObj = NULL;
    Tcl_Obj *useObj = NULL;
    Tcl_Obj *visualObj = NULL;
    Tcl_Obj *geometryObj = NULL;

3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
	TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END
    };

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
	return TCL_ERROR;
    }

    /*
     * TIP #59: Make embedded configuration information available.
     */








|







3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
	TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END
    };

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
	return TCL_ERROR;
    }

    /*
     * TIP #59: Make embedded configuration information available.
     */

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

	Tcl_Interp *parent = interp;

	while (Tcl_IsSafe(parent)) {
	    parent = Tcl_GetParent(parent);
	    if (parent == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no controlling parent interpreter", -1));
		Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_PARENT", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Construct the name (rewalk...)
	 */

	code = Tcl_GetInterpPath(parent, interp);
	if (code != TCL_OK) {
	    Tcl_Panic("Tcl_GetInterpPath broken!");
	}

	/*
	 * Build the command to eval in trusted parent.
	 */

	cmd = Tcl_NewListObj(2, NULL);
	Tcl_ListObjAppendElement(NULL, cmd,
		Tcl_NewStringObj("::safe::TkInit", -1));
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(parent));

	/*
	 * Step 2 : Eval in the parent. The argument is the *reversed* interp
	 * path of the child.
	 */








|




















|







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

	Tcl_Interp *parent = interp;

	while (Tcl_IsSafe(parent)) {
	    parent = Tcl_GetParent(parent);
	    if (parent == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"no controlling parent interpreter", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_PARENT", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Construct the name (rewalk...)
	 */

	code = Tcl_GetInterpPath(parent, interp);
	if (code != TCL_OK) {
	    Tcl_Panic("Tcl_GetInterpPath broken!");
	}

	/*
	 * Build the command to eval in trusted parent.
	 */

	cmd = Tcl_NewListObj(2, NULL);
	Tcl_ListObjAppendElement(NULL, cmd,
		Tcl_NewStringObj("::safe::TkInit", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(parent));

	/*
	 * Step 2 : Eval in the parent. The argument is the *reversed* interp
	 * path of the child.
	 */

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
	 * that we used.
	 */

	value = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY);
    }

    if (value) {
	int objc;
	Tcl_Obj **objv, **rest;
	Tcl_Obj *parseList = Tcl_NewListObj(1, NULL);

	Tcl_ListObjAppendElement(NULL, parseList, Tcl_NewObj());

	Tcl_IncrRefCount(value);
	if (TCL_OK != Tcl_ListObjAppendList(interp, parseList, value) ||
	    TCL_OK != Tcl_ListObjGetElements(NULL, parseList, &objc, &objv) ||
	    TCL_OK != Tcl_ParseArgsObjv(interp, table, &objc, objv, &rest)) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (processing arguments in argv variable)");
	    code = TCL_ERROR;
	}
	if (code == TCL_OK) {
	    Tcl_SetVar2Ex(interp, "argv", NULL,
		    Tcl_NewListObj(objc-1, rest+1), TCL_GLOBAL_ONLY);
	    Tcl_SetVar2Ex(interp, "argc", NULL,
		    Tcl_NewWideIntObj(objc-1), TCL_GLOBAL_ONLY);
	    ckfree(rest);
	}
	Tcl_DecrRefCount(parseList);
	if (code != TCL_OK) {
	    goto done;
	}
    }







|

















|







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
	 * that we used.
	 */

	value = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY);
    }

    if (value) {
	Tcl_Size objc;
	Tcl_Obj **objv, **rest;
	Tcl_Obj *parseList = Tcl_NewListObj(1, NULL);

	Tcl_ListObjAppendElement(NULL, parseList, Tcl_NewObj());

	Tcl_IncrRefCount(value);
	if (TCL_OK != Tcl_ListObjAppendList(interp, parseList, value) ||
	    TCL_OK != Tcl_ListObjGetElements(NULL, parseList, &objc, &objv) ||
	    TCL_OK != Tcl_ParseArgsObjv(interp, table, &objc, objv, &rest)) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (processing arguments in argv variable)");
	    code = TCL_ERROR;
	}
	if (code == TCL_OK) {
	    Tcl_SetVar2Ex(interp, "argv", NULL,
		    Tcl_NewListObj(objc-1, rest+1), TCL_GLOBAL_ONLY);
	    Tcl_SetVar2Ex(interp, "argc", NULL,
		    Tcl_NewWideIntObj((Tcl_WideInt)objc-1), TCL_GLOBAL_ONLY);
	    ckfree(rest);
	}
	Tcl_DecrRefCount(parseList);
	if (code != TCL_OK) {
	    goto done;
	}
    }
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
    if (nameObj == NULL) {
	Tcl_DString nameDS;

	Tcl_DStringInit(&nameDS);
	TkpGetAppName(interp, &nameDS);
	nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS),
		Tcl_DStringLength(&nameDS));


	Tcl_DStringFree(&nameDS);
    }

    /*
     * The -class argument is always the ToTitle of the -name
     */

    {
	TkSizeT numBytes;
	const char *bytes = TkGetStringFromObj(nameObj, &numBytes);

	classObj = Tcl_NewStringObj(bytes, numBytes);

	numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj));
	Tcl_SetObjLength(classObj, numBytes);
    }

    /*
     * Create an argument list for creating the top-level window, using the
     * information parsed from argv, if any.
     */

    cmd = Tcl_NewStringObj("toplevel . -class", -1);

    Tcl_ListObjAppendElement(NULL, cmd, classObj);
    classObj = NULL;

    if (displayObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-screen", -1));
	Tcl_ListObjAppendElement(NULL, cmd, displayObj);

	/*
	 * If this is the first application for this process, save the display
	 * name in the DISPLAY environment variable so that it will be
	 * available to subprocesses created by us.
	 */

	if (tsdPtr->numMainWindows == 0) {
	    Tcl_SetVar2Ex(interp, "env", "DISPLAY", displayObj, TCL_GLOBAL_ONLY);
	}
	displayObj = NULL;
    }
    if (colorMapObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-colormap", -1));
	Tcl_ListObjAppendElement(NULL, cmd, colorMapObj);
	colorMapObj = NULL;
    }
    if (useObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-use", -1));
	Tcl_ListObjAppendElement(NULL, cmd, useObj);
	useObj = NULL;
    }
    if (visualObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-visual", -1));
	Tcl_ListObjAppendElement(NULL, cmd, visualObj);
	visualObj = NULL;
    }







    code = TkListCreateFrame(NULL, interp, cmd, 1, nameObj);


    Tcl_DecrRefCount(cmd);

    if (code != TCL_OK) {
	goto done;
    }
    Tcl_ResetResult(interp);
    if (sync) {
	(void)XSynchronize(Tk_Display(Tk_MainWindow(interp)), True);
    }

    /*
     * Set the geometry of the main window, if requested. Put the requested
     * geometry into the "geometry" variable.
     */

    if (geometryObj) {

	Tcl_SetVar2Ex(interp, "geometry", NULL, geometryObj, TCL_GLOBAL_ONLY);

	cmd = Tcl_NewStringObj("wm geometry .", -1);
	Tcl_ListObjAppendElement(NULL, cmd, geometryObj);
	Tcl_IncrRefCount(cmd);
	code = Tcl_EvalObjEx(interp, cmd, 0);
	Tcl_DecrRefCount(cmd);
	geometryObj = NULL;
	if (code != TCL_OK) {
	    goto done;
	}
    }

    /*
     * Provide Tk and its stub table.
     */


    code = Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,
	    (ClientData) &tkStubs);



    if (code != TCL_OK) {
	goto done;
    }

    /*
     * If we were able to provide ourselves as a package, then set the main
     * loop function in Tcl to our main loop proc. This will cause tclsh to be







>
>








|
|












|





|














|




|




|




>
>
>
>
>
>
|
>




















|











|


>
|
|
>
>
>







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
    if (nameObj == NULL) {
	Tcl_DString nameDS;

	Tcl_DStringInit(&nameDS);
	TkpGetAppName(interp, &nameDS);
	nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS),
		Tcl_DStringLength(&nameDS));
	appNameObj = nameObj;
	Tcl_IncrRefCount(appNameObj);
	Tcl_DStringFree(&nameDS);
    }

    /*
     * The -class argument is always the ToTitle of the -name
     */

    {
	Tcl_Size numBytes;
	const char *bytes = Tcl_GetStringFromObj(nameObj, &numBytes);

	classObj = Tcl_NewStringObj(bytes, numBytes);

	numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj));
	Tcl_SetObjLength(classObj, numBytes);
    }

    /*
     * Create an argument list for creating the top-level window, using the
     * information parsed from argv, if any.
     */

    cmd = Tcl_NewStringObj("toplevel . -class", TCL_INDEX_NONE);

    Tcl_ListObjAppendElement(NULL, cmd, classObj);
    classObj = NULL;

    if (displayObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-screen", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, cmd, displayObj);

	/*
	 * If this is the first application for this process, save the display
	 * name in the DISPLAY environment variable so that it will be
	 * available to subprocesses created by us.
	 */

	if (tsdPtr->numMainWindows == 0) {
	    Tcl_SetVar2Ex(interp, "env", "DISPLAY", displayObj, TCL_GLOBAL_ONLY);
	}
	displayObj = NULL;
    }
    if (colorMapObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-colormap", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, cmd, colorMapObj);
	colorMapObj = NULL;
    }
    if (useObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-use", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, cmd, useObj);
	useObj = NULL;
    }
    if (visualObj) {
	Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-visual", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, cmd, visualObj);
	visualObj = NULL;
    }

    Tcl_Size objc;
    Tcl_Obj **objv;

    if (TCL_OK != Tcl_ListObjGetElements(interp, cmd, &objc, &objv)) {
	return TCL_ERROR;
    }
    code = TkCreateFrame(NULL, interp, objc, objv,
	    1, nameObj ? Tcl_GetString(nameObj) : NULL);

    Tcl_DecrRefCount(cmd);

    if (code != TCL_OK) {
	goto done;
    }
    Tcl_ResetResult(interp);
    if (sync) {
	(void)XSynchronize(Tk_Display(Tk_MainWindow(interp)), True);
    }

    /*
     * Set the geometry of the main window, if requested. Put the requested
     * geometry into the "geometry" variable.
     */

    if (geometryObj) {

	Tcl_SetVar2Ex(interp, "geometry", NULL, geometryObj, TCL_GLOBAL_ONLY);

	cmd = Tcl_NewStringObj("wm geometry .", TCL_INDEX_NONE);
	Tcl_ListObjAppendElement(NULL, cmd, geometryObj);
	Tcl_IncrRefCount(cmd);
	code = Tcl_EvalObjEx(interp, cmd, 0);
	Tcl_DecrRefCount(cmd);
	geometryObj = NULL;
	if (code != TCL_OK) {
	    goto done;
	}
    }

    /*
     * Provide "tk" and its stub table.
     */

#ifndef TK_NO_DEPRECATED
    Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,
	    (void *)&tkStubs);
#endif
    code = Tcl_PkgProvideEx(interp, "tk", TK_PATCH_LEVEL,
	    (void *)&tkStubs);
    if (code != TCL_OK) {
	goto done;
    }

    /*
     * If we were able to provide ourselves as a package, then set the main
     * loop function in Tcl to our main loop proc. This will cause tclsh to be
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
"if {[namespace which -command tkInit] eq \"\"} {\n\
  proc tkInit {} {\n\
    global tk_library tk_version tk_patchLevel\n\
      rename tkInit {}\n\
    tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\
  }\n\
}\n\
tkInit", -1, TCL_EVAL_GLOBAL);
    }
    if (code == TCL_OK) {
	/*
	 * Create exit handlers to delete all windows when the application or
	 * thread exits. The handler need to be invoked before other platform
	 * specific cleanups take place to avoid panics in finalization.
	 */

	TkCreateThreadExitHandler(DeleteWindowsExitProc, tsdPtr);
    }
  done:
    if (value) {
	Tcl_DecrRefCount(value);
	value = NULL;




    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *







|














>
>
>
>







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
"if {[namespace which -command tkInit] eq \"\"} {\n\
  proc tkInit {} {\n\
    global tk_library tk_version tk_patchLevel\n\
      rename tkInit {}\n\
    tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\
  }\n\
}\n\
tkInit", TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    }
    if (code == TCL_OK) {
	/*
	 * Create exit handlers to delete all windows when the application or
	 * thread exits. The handler need to be invoked before other platform
	 * specific cleanups take place to avoid panics in finalization.
	 */

	TkCreateThreadExitHandler(DeleteWindowsExitProc, tsdPtr);
    }
  done:
    if (value) {
	Tcl_DecrRefCount(value);
	value = NULL;
    }
    if (appNameObj) {
	Tcl_DecrRefCount(appNameObj);
	appNameObj = NULL;
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
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

const char *
Tk_PkgInitStubsCheck(
    Tcl_Interp *interp,
    const char * version,
    int exact)
{
    const char *actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 0, NULL);

    if (exact && actualVersion) {
	const char *p = version;
	int count = 0;

	while (*p) {
	    count += !isdigit(UCHAR(*p++));
	}
	if (count == 1) {
	    if (0 != strncmp(version, actualVersion, strlen(version))) {
		/* Construct error message */
		Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
		return NULL;
	    }
	} else {
	    return Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
	}
    }
    return actualVersion;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|











|



|












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

const char *
Tk_PkgInitStubsCheck(
    Tcl_Interp *interp,
    const char * version,
    int exact)
{
    const char *actualVersion = Tcl_PkgRequireEx(interp, "tk", version, 0, NULL);

    if (exact && actualVersion) {
	const char *p = version;
	int count = 0;

	while (*p) {
	    count += !isdigit(UCHAR(*p++));
	}
	if (count == 1) {
	    if (0 != strncmp(version, actualVersion, strlen(version))) {
		/* Construct error message */
		Tcl_PkgPresentEx(interp, "tk", version, 1, NULL);
		return NULL;
	    }
	} else {
	    return Tcl_PkgPresentEx(interp, "tk", version, 1, NULL);
	}
    }
    return actualVersion;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/ttk/ttk.decls.

139
140
141
142
143
144
145
146
147
148
149
150
declare 35 {
    Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box)
}

#
# Utilities.
#
declare 40 {deprecated {}} {
    int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient)
}









|
|



139
140
141
142
143
144
145
146
147
148
149
150
declare 35 {
    Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box)
}

#
# Utilities.
#
declare 40 {
    int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Orient *orient)
}


Changes to generic/ttk/ttkBlink.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
/*
 * Copyright 2004, Joe English.
 *
 * Usage:
 * 	TtkBlinkCursor(corePtr), usually called in a widget's Init hook,
 * 	arranges to periodically toggle the corePtr->flags CURSOR_ON bit
 * 	on and off (and schedule a redisplay) whenever the widget has focus.
 *
 * 	Note: Widgets may have additional logic to decide whether
 * 	to display the cursor or not (e.g., readonly or disabled states);
 * 	TtkBlinkCursor() does not account for this.
 *
 * TODO:
 * 	Add script-level access to configure application-wide blink rate.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#define DEF_CURSOR_ON_TIME	600		/* milliseconds */
#define DEF_CURSOR_OFF_TIME	300		/* milliseconds */

/* Interp-specific data for tracking cursors:
 */
typedef struct
{
    WidgetCore		*owner; 	/* Widget that currently has cursor */
    Tcl_TimerToken	timer;		/* Blink timer */
    int 		onTime;		/* #milliseconds to blink cursor on */
    int 		offTime;	/* #milliseconds to blink cursor off */
} CursorManager;

/* CursorManagerDeleteProc --
 * 	InterpDeleteProc for cursor manager.
 */
static void CursorManagerDeleteProc(ClientData clientData, Tcl_Interp *dummy)


{
    CursorManager *cm = (CursorManager*)clientData;
    (void)dummy;

    if (cm->timer) {
	Tcl_DeleteTimerHandler(cm->timer);
    }
    ckfree(clientData);
}

/* GetCursorManager --
 * 	Look up and create if necessary the interp's cursor manager.
 */
static CursorManager *GetCursorManager(Tcl_Interp *interp)
{
    static const char *cm_key = "ttk::CursorManager";
    CursorManager *cm = (CursorManager *)Tcl_GetAssocData(interp, cm_key,0);




    if (!cm) {
	cm = (CursorManager *)ckalloc(sizeof(*cm));
	cm->timer = 0;
	cm->owner = 0;
	cm->onTime = DEF_CURSOR_ON_TIME;
	cm->offTime = DEF_CURSOR_OFF_TIME;





















	Tcl_SetAssocData(interp, cm_key, CursorManagerDeleteProc, cm);
    }
    return cm;
}

/* CursorBlinkProc --
 *	Timer handler to blink the insert cursor on and off.
 */
static void
CursorBlinkProc(ClientData clientData)
{
    CursorManager *cm = (CursorManager *)clientData;
    int blinkTime;

    if (cm->owner->flags & CURSOR_ON) {
	cm->owner->flags &= ~CURSOR_ON;
	blinkTime = cm->offTime;












<
<



|


















|
>
>


<














>
>
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|







1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 2004, Joe English.
 *
 * Usage:
 * 	TtkBlinkCursor(corePtr), usually called in a widget's Init hook,
 * 	arranges to periodically toggle the corePtr->flags CURSOR_ON bit
 * 	on and off (and schedule a redisplay) whenever the widget has focus.
 *
 * 	Note: Widgets may have additional logic to decide whether
 * 	to display the cursor or not (e.g., readonly or disabled states);
 * 	TtkBlinkCursor() does not account for this.
 *


 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"

#define DEF_CURSOR_ON_TIME	600		/* milliseconds */
#define DEF_CURSOR_OFF_TIME	300		/* milliseconds */

/* Interp-specific data for tracking cursors:
 */
typedef struct
{
    WidgetCore		*owner; 	/* Widget that currently has cursor */
    Tcl_TimerToken	timer;		/* Blink timer */
    int 		onTime;		/* #milliseconds to blink cursor on */
    int 		offTime;	/* #milliseconds to blink cursor off */
} CursorManager;

/* CursorManagerDeleteProc --
 * 	InterpDeleteProc for cursor manager.
 */
static void CursorManagerDeleteProc(
    void *clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    CursorManager *cm = (CursorManager*)clientData;


    if (cm->timer) {
	Tcl_DeleteTimerHandler(cm->timer);
    }
    ckfree(clientData);
}

/* GetCursorManager --
 * 	Look up and create if necessary the interp's cursor manager.
 */
static CursorManager *GetCursorManager(Tcl_Interp *interp)
{
    static const char *cm_key = "ttk::CursorManager";
    CursorManager *cm = (CursorManager *)Tcl_GetAssocData(interp, cm_key,0);
    Tk_Window window;
    Tk_Uid value;
    int intValue;

    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;

	/* Override on and off default times with values obtained from
	 * the option database (if such values are specified).
	 */

	window = Tk_MainWindow(interp);
	if (window) {
	    value = Tk_GetOption(window, "insertOnTime", "OnTime");
	    if (value) {
		if (Tcl_GetInt(interp, value, &intValue) == TCL_OK) {
		    cm->onTime = intValue;
		}
	    }
	    value = Tk_GetOption(window, "insertOffTime", "OffTime");
	    if (value) {
		if (Tcl_GetInt(interp, value, &intValue) == TCL_OK) {
		    cm->offTime = intValue;
		}
	    }
	}

	Tcl_SetAssocData(interp, cm_key, CursorManagerDeleteProc, cm);
    }
    return cm;
}

/* CursorBlinkProc --
 *	Timer handler to blink the insert cursor on and off.
 */
static void
CursorBlinkProc(void *clientData)
{
    CursorManager *cm = (CursorManager *)clientData;
    int blinkTime;

    if (cm->owner->flags & CURSOR_ON) {
	cm->owner->flags &= ~CURSOR_ON;
	blinkTime = cm->offTime;
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 */

#define CursorEventMask (FocusChangeMask|StructureNotifyMask)
#define RealFocusEvent(d) \
    (d == NotifyInferior || d == NotifyAncestor || d == NotifyNonlinear)

static void
CursorEventProc(ClientData clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    CursorManager *cm = GetCursorManager(corePtr->interp);

    switch (eventPtr->type) {
	case DestroyNotify:
	    if (cm->owner == corePtr)







|







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
 */

#define CursorEventMask (FocusChangeMask|StructureNotifyMask)
#define RealFocusEvent(d) \
    (d == NotifyInferior || d == NotifyAncestor || d == NotifyNonlinear)

static void
CursorEventProc(void *clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    CursorManager *cm = GetCursorManager(corePtr->interp);

    switch (eventPtr->type) {
	case DestroyNotify:
	    if (cm->owner == corePtr)
150
151
152
153
154
155
156











































157
158
159
160
161
162
163
164
165
166
167
168
	case FocusOut:
	    if (RealFocusEvent(eventPtr->xfocus.detail))
		LoseCursor(cm, corePtr);
	    break;
    }
}












































/*
 * TtkBlinkCursor (main routine) --
 * 	Arrange to blink the cursor on and off whenever the
 * 	widget has focus.
 */
void TtkBlinkCursor(WidgetCore *corePtr)
{
    Tk_CreateEventHandler(
	corePtr->tkwin, CursorEventMask, CursorEventProc, corePtr);
}

/*EOF*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
	case FocusOut:
	    if (RealFocusEvent(eventPtr->xfocus.detail))
		LoseCursor(cm, corePtr);
	    break;
    }
}

void TtkSetBlinkCursorOnTime(Tcl_Interp* interp, int onTime)
{
    CursorManager* cm = GetCursorManager(interp);

    if (onTime >= 0)
	cm->onTime = onTime;
}

void TtkSetBlinkCursorOffTime(Tcl_Interp* interp, int offTime)
{
    CursorManager* cm = GetCursorManager(interp);

    if (offTime >= 0)
	cm->offTime = offTime;
}

/*
 * TtkSetBlinkCursorTimes --
 * 	Set cursor blink on and off times from the "." style defaults
 * 	-insertontime and -insertofftime - For instance to set cursor
 * 	blinking off:
 * 	    ttk::style configure . -insertofftime 0
 */
void TtkSetBlinkCursorTimes(Tcl_Interp* interp)
{
    Ttk_Theme theme;
    Ttk_Style style = NULL;
    Tcl_Obj* result;
    int timeInterval;

    theme = Ttk_GetCurrentTheme(interp);
    style = Ttk_GetStyle(theme, ".");
    result = Ttk_StyleDefault(style, "-insertontime");
    if (result) {
	Tcl_GetIntFromObj(interp, result, &timeInterval);
	TtkSetBlinkCursorOnTime(interp, timeInterval);
    }
    result = Ttk_StyleDefault(style, "-insertofftime");
    if (result) {
	Tcl_GetIntFromObj(interp, result, &timeInterval);
	TtkSetBlinkCursorOffTime(interp, timeInterval);
    }
}
/*
 * TtkBlinkCursor (main routine) --
 * 	Arrange to blink the cursor on and off whenever the
 * 	widget has focus.
 */
void TtkBlinkCursor(WidgetCore *corePtr)
{
    Tk_CreateEventHandler(
	corePtr->tkwin, CursorEventMask, CursorEventProc, corePtr);
}

/*EOF*/

Changes to generic/ttk/ttkButton.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright (c) 2003, Joe English
 *
 * label, button, checkbutton, radiobutton, and menubutton widgets.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/* Bit fields for OptionSpec mask field:
 */
#define STATE_CHANGED	 	(0x100)		/* -state option changed */
#define DEFAULTSTATE_CHANGED	(0x200)		/* -default option changed */


|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright © 2003, Joe English
 *
 * label, button, checkbutton, radiobutton, and menubutton widgets.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"

/* Bit fields for OptionSpec mask field:
 */
#define STATE_CHANGED	 	(0x100)		/* -state option changed */
#define DEFAULTSTATE_CHANGED	(0x200)		/* -default option changed */

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    WidgetCore	core;
    BasePart	base;
} Base;

static const Tk_OptionSpec BaseOptionSpecs[] =
{
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
        "left", offsetof(Base,base.justifyObj), TCL_INDEX_NONE,
        TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Base,base.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "",
	offsetof(Base,base.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	"-1", offsetof(Base,base.underlineObj), TCL_INDEX_NONE,
	0,0,0 },
    /* SB: OPTION_INT, see <<NOTE-NULLOPTIONS>> */
    {TK_OPTION_STRING, "-width", "width", "Width",
	NULL, offsetof(Base,base.widthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    /*
     * Image options
     */
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Base,base.imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    /*
     * Compound base/image options
     */
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 NULL, offsetof(Base,base.compoundObj), TCL_INDEX_NONE,
	 TK_OPTION_NULL_OK, (void *)ttkCompoundStrings,
         GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Base,base.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},

    /*
     * Compatibility/legacy options
     */
    {TK_OPTION_STRING, "-state", "state", "State",
	 "normal", offsetof(Base,base.stateObj), TCL_INDEX_NONE,
	 0,0,STATE_CHANGED },

    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Variable trace procedure for -textvariable option:
 */







|
|






|
|
<
<















|
|
|








|
|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    WidgetCore	core;
    BasePart	base;
} Base;

static const Tk_OptionSpec BaseOptionSpecs[] =
{
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", offsetof(Base,base.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Base,base.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "",
	offsetof(Base,base.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TTK_OPTION_UNDERLINE_DEF(Base, base.underlineObj), 0},


    {TK_OPTION_STRING, "-width", "width", "Width",
	NULL, offsetof(Base,base.widthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    /*
     * Image options
     */
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Base,base.imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    /*
     * Compound base/image options
     */
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	NULL, offsetof(Base,base.compoundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, ttkCompoundStrings,
	GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Base,base.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},

    /*
     * Compatibility/legacy options
     */
    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Base,base.stateObj), TCL_INDEX_NONE,
	0,0,STATE_CHANGED },

    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Variable trace procedure for -textvariable option:
 */
119
120
121
122
123
124
125
126


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148





149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    Tcl_DecrRefCount(basePtr->base.textObj);
    basePtr->base.textObj = newText;

    TtkResizeWidget(&basePtr->core);
}

static void
BaseInitialize(Tcl_Interp *dummy, void *recordPtr)


{
    Base *basePtr = (Base *)recordPtr;
    (void)dummy;

    basePtr->base.textVariableTrace = 0;
    basePtr->base.imageSpec = NULL;
}

static void
BaseCleanup(void *recordPtr)
{
    Base *basePtr = (Base *)recordPtr;
    if (basePtr->base.textVariableTrace)
	Ttk_UntraceVariable(basePtr->base.textVariableTrace);
    if (basePtr->base.imageSpec)
    	TtkFreeImageSpec(basePtr->base.imageSpec);
}

static void
BaseImageChanged(
	ClientData clientData, int x, int y, int width, int height,
	int imageWidth, int imageHeight)





{
    Base *basePtr = (Base *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imageWidth;
    (void)imageHeight;

    TtkResizeWidget(&basePtr->core);
}

static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Base *basePtr = (Base *)recordPtr;







|
>
>


<

















|
|
>
>
>
>
>


<
<
<
<
<
<







117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154






155
156
157
158
159
160
161
    Tcl_DecrRefCount(basePtr->base.textObj);
    basePtr->base.textObj = newText;

    TtkResizeWidget(&basePtr->core);
}

static void
BaseInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Base *basePtr = (Base *)recordPtr;


    basePtr->base.textVariableTrace = 0;
    basePtr->base.imageSpec = NULL;
}

static void
BaseCleanup(void *recordPtr)
{
    Base *basePtr = (Base *)recordPtr;
    if (basePtr->base.textVariableTrace)
	Ttk_UntraceVariable(basePtr->base.textVariableTrace);
    if (basePtr->base.imageSpec)
    	TtkFreeImageSpec(basePtr->base.imageSpec);
}

static void
BaseImageChanged(
    void *clientData,
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    Base *basePtr = (Base *)clientData;







    TtkResizeWidget(&basePtr->core);
}

static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Base *basePtr = (Base *)recordPtr;
199
200
201
202
203
204
205
206



207
208
209
210
211
212
213
214
215
216
217
218
	TtkCheckStateOption(&basePtr->core, basePtr->base.stateObj);
    }

    return TCL_OK;
}

static int
BasePostConfigure(Tcl_Interp *dummy, void *recordPtr, int mask)



{
    Base *basePtr = (Base *)recordPtr;
    int status = TCL_OK;
    (void)dummy;
    (void)mask;

    if (basePtr->base.textVariableTrace) {
	status = Ttk_FireTrace(basePtr->base.textVariableTrace);
    }

    return status;
}







|
>
>
>



<
<







197
198
199
200
201
202
203
204
205
206
207
208
209
210


211
212
213
214
215
216
217
	TtkCheckStateOption(&basePtr->core, basePtr->base.stateObj);
    }

    return TCL_OK;
}

static int
BasePostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr,
    TCL_UNUSED(int))
{
    Base *basePtr = (Base *)recordPtr;
    int status = TCL_OK;



    if (basePtr->base.textVariableTrace) {
	status = Ttk_FireTrace(basePtr->base.textVariableTrace);
    }

    return status;
}
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	NULL, offsetof(Label,label.borderWidthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	NULL, offsetof(Label,label.reliefObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	NULL, offsetof(Label,label.anchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	NULL, offsetof(Label, label.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	NULL, offsetof(Label, label.wrapLengthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED /*SB: SIZE_CHANGED*/ },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static const Ttk_Ensemble LabelCommands[] = {

    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec LabelWidgetSpec =
{
    "TLabel",			/* className */
    sizeof(Label),		/* recordSize */







|
|

|
|









>

|


|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	NULL, offsetof(Label,label.borderWidthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	NULL, offsetof(Label,label.reliefObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"w", offsetof(Label,label.anchorObj), TCL_INDEX_NONE,
	0, 0, GEOMETRY_CHANGED},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", offsetof(Label, label.justifyObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	NULL, offsetof(Label, label.wrapLengthObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED /*SB: SIZE_CHANGED*/ },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static const Ttk_Ensemble LabelCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec LabelWidgetSpec =
{
    "TLabel",			/* className */
    sizeof(Label),		/* recordSize */
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
 */
static const Tk_OptionSpec ButtonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Button, button.commandObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
	"normal", offsetof(Button, button.defaultStateObj), TCL_INDEX_NONE,
	0, (void *)ttkDefaultStrings, DEFAULTSTATE_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static int ButtonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{







|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
 */
static const Tk_OptionSpec ButtonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Button, button.commandObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
	"normal", offsetof(Button, button.defaultStateObj), TCL_INDEX_NONE,
	0, ttkDefaultStrings, DEFAULTSTATE_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static int ButtonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384

385
386
387
388
389
390
391
392
393
}

/* $button invoke --
 * 	Evaluate the button's -command.
 */
static int
ButtonInvokeCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Button *buttonPtr = (Button *)recordPtr;
    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");
	return TCL_ERROR;
    }
    if (buttonPtr->core.state & TTK_STATE_DISABLED) {
	return TCL_OK;
    }
    return Tcl_EvalObjEx(interp, buttonPtr->button.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble ButtonCommands[] = {

    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "invoke",		ButtonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },

    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ButtonWidgetSpec =
{
    "TButton",			/* className */
    sizeof(Button),		/* recordSize */







|













>

|
<

>

|







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
}

/* $button invoke --
 * 	Evaluate the button's -command.
 */
static int
ButtonInvokeCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Button *buttonPtr = (Button *)recordPtr;
    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");
	return TCL_ERROR;
    }
    if (buttonPtr->core.state & TTK_STATE_DISABLED) {
	return TCL_OK;
    }
    return Tcl_EvalObjEx(interp, buttonPtr->button.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble ButtonCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },

    { "instate",	TtkWidgetInstateCommand,0 },
    { "invoke",		ButtonInvokeCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ButtonWidgetSpec =
{
    "TButton",			/* className */
    sizeof(Button),		/* recordSize */
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557

/*
 * Checkbutton 'invoke' subcommand:
 * 	Toggles the checkbutton state.
 */
static int
CheckbuttonInvokeCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Checkbutton *checkPtr = (Checkbutton *)recordPtr;
    WidgetCore *corePtr = &checkPtr->core;
    Tcl_Obj *newValue;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");







|







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558

/*
 * Checkbutton 'invoke' subcommand:
 * 	Toggles the checkbutton state.
 */
static int
CheckbuttonInvokeCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Checkbutton *checkPtr = (Checkbutton *)recordPtr;
    WidgetCore *corePtr = &checkPtr->core;
    Tcl_Obj *newValue;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");
581
582
583
584
585
586
587

588
589
590
591

592
593
594
595
596
597
598
599
600
	return TCL_ERROR;

    return Tcl_EvalObjEx(interp,
	checkPtr->checkbutton.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble CheckbuttonCommands[] = {

    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "invoke",		CheckbuttonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },

    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    /* MISSING: select, deselect, toggle */
    { 0,0,0 }
};

static const WidgetSpec CheckbuttonWidgetSpec =
{
    "TCheckbutton",		/* className */







>

|
<

>

|







582
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602
	return TCL_ERROR;

    return Tcl_EvalObjEx(interp,
	checkPtr->checkbutton.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble CheckbuttonCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },

    { "instate",	TtkWidgetInstateCommand,0 },
    { "invoke",		CheckbuttonInvokeCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    /* MISSING: select, deselect, toggle */
    { 0,0,0 }
};

static const WidgetSpec CheckbuttonWidgetSpec =
{
    "TCheckbutton",		/* className */
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

/*
 * Radiobutton 'invoke' subcommand:
 * 	Sets the radiobutton -variable to the -value, evaluates the -command.
 */
static int
RadiobuttonInvokeCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Radiobutton *radioPtr = (Radiobutton *)recordPtr;
    WidgetCore *corePtr = &radioPtr->core;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");
	return TCL_ERROR;







|







732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

/*
 * Radiobutton 'invoke' subcommand:
 * 	Sets the radiobutton -variable to the -value, evaluates the -command.
 */
static int
RadiobuttonInvokeCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Radiobutton *radioPtr = (Radiobutton *)recordPtr;
    WidgetCore *corePtr = &radioPtr->core;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "invoke");
	return TCL_ERROR;
757
758
759
760
761
762
763

764
765
766
767

768
769
770
771
772
773
774
775
776
	return TCL_ERROR;

    return Tcl_EvalObjEx(interp,
	radioPtr->radiobutton.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble RadiobuttonCommands[] = {

    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "invoke",		RadiobuttonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },

    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    /* MISSING: select, deselect */
    { 0,0,0 }
};

static const WidgetSpec RadiobuttonWidgetSpec =
{
    "TRadiobutton",		/* className */







>

|
<

>

|







759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
	return TCL_ERROR;

    return Tcl_EvalObjEx(interp,
	radioPtr->radiobutton.commandObj, TCL_EVAL_GLOBAL);
}

static const Ttk_Ensemble RadiobuttonCommands[] = {
    { "cget",		TtkWidgetCgetCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },

    { "instate",	TtkWidgetInstateCommand,0 },
    { "invoke",		RadiobuttonInvokeCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    /* MISSING: select, deselect */
    { 0,0,0 }
};

static const WidgetSpec RadiobuttonWidgetSpec =
{
    "TRadiobutton",		/* className */
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
    MenubuttonPart menubutton;
} Menubutton;

/*
 * Option specifications:
 */
static const char *const directionStrings[] = {
    "above", "below", "left", "right", "flush", NULL
};
static const Tk_OptionSpec MenubuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	"", offsetof(Menubutton, menubutton.menuObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	"below", offsetof(Menubutton, menubutton.directionObj), TCL_INDEX_NONE,
	0, (void *)directionStrings, GEOMETRY_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

static const Ttk_Ensemble MenubuttonCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },

    { 0,0,0 }
};

static const WidgetSpec MenubuttonWidgetSpec =
{
    "TMenubutton",		/* className */
    sizeof(Menubutton), 	/* recordSize */







|







|











>







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
    MenubuttonPart menubutton;
} Menubutton;

/*
 * Option specifications:
 */
static const char *const directionStrings[] = {
    "above", "below", "flush", "left", "right", NULL
};
static const Tk_OptionSpec MenubuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	"", offsetof(Menubutton, menubutton.menuObj), TCL_INDEX_NONE, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	"below", offsetof(Menubutton, menubutton.directionObj), TCL_INDEX_NONE,
	0, 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 */
861
862
863
864
865
866
867


868
869
870
871
872
873
874
	    TTK_GROUP("Menubutton.padding", TTK_FILL_X,
	        TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */



MODULE_SCOPE
void TtkButton_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TLabel", LabelLayout);







>
>







865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
	    TTK_GROUP("Menubutton.padding", TTK_FILL_X,
	        TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE void TtkButton_Init(Tcl_Interp *);

MODULE_SCOPE
void TtkButton_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TLabel", LabelLayout);

Changes to generic/ttk/ttkCache.c.

1
2
3
4
5
6
7
8
9
10
11
/*
 *      Theme engine resource cache.
 *
 * Copyright (c) 2004, Joe English
 *
 * The problem:
 *
 * Tk maintains reference counts for fonts, colors, and images,
 * and deallocates them when the reference count goes to zero.
 * With the theme engine, resources are allocated right before
 * drawing an element and released immediately after.



|







1
2
3
4
5
6
7
8
9
10
11
/*
 *      Theme engine resource cache.
 *
 * 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.
26
27
28
29
30
31
32




33
34
35
36
37
38
39
 *
 * @@@ Colormap flashing on PseudoColor visuals is still possible,
 * but this will be a transient effect.
 */

#include "tkInt.h"
#include "ttkTheme.h"





struct Ttk_ResourceCache_ {
    Tcl_Interp	  *interp;	/* Interpreter for error reporting */
    Tk_Window	  tkwin;	/* Cache window. */
    Tcl_HashTable fontTable;	/* Entries: Tcl_Obj* holding FontObjs */
    Tcl_HashTable colorTable;	/* Entries: Tcl_Obj* holding ColorObjs */
    Tcl_HashTable borderTable;	/* Entries: Tcl_Obj* holding BorderObjs */







>
>
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 *
 * @@@ Colormap flashing on PseudoColor visuals is still possible,
 * but this will be a transient effect.
 */

#include "tkInt.h"
#include "ttkTheme.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

struct Ttk_ResourceCache_ {
    Tcl_Interp	  *interp;	/* Interpreter for error reporting */
    Tk_Window	  tkwin;	/* Cache window. */
    Tcl_HashTable fontTable;	/* Entries: Tcl_Obj* holding FontObjs */
    Tcl_HashTable colorTable;	/* Entries: Tcl_Obj* holding ColorObjs */
    Tcl_HashTable borderTable;	/* Entries: Tcl_Obj* holding BorderObjs */
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    ckfree(cache);
}

/*
 * CacheWinEventHandler --
 * 	Detect when the cache window is destroyed, clear cache.
 */
static void CacheWinEventHandler(ClientData clientData, XEvent *eventPtr)
{
    Ttk_ResourceCache cache = (Ttk_ResourceCache)clientData;

    if (eventPtr->type != DestroyNotify) {
	return;
    }
    Tk_DeleteEventHandler(cache->tkwin, StructureNotifyMask,







|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
    ckfree(cache);
}

/*
 * CacheWinEventHandler --
 * 	Detect when the cache window is destroyed, clear cache.
 */
static void CacheWinEventHandler(void *clientData, XEvent *eventPtr)
{
    Ttk_ResourceCache cache = (Ttk_ResourceCache)clientData;

    if (eventPtr->type != DestroyNotify) {
	return;
    }
    Tk_DeleteEventHandler(cache->tkwin, StructureNotifyMask,
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    XColor *colorPtr)
{
    int newEntry;
    Tcl_HashEntry *entryPtr;
    char nameBuf[14];
    Tcl_Obj *colorNameObj;

    sprintf(nameBuf, "#%04X%04X%04X",
    	colorPtr->red, colorPtr->green, colorPtr->blue);
    colorNameObj = Tcl_NewStringObj(nameBuf, -1);
    Tcl_IncrRefCount(colorNameObj);

    entryPtr = Tcl_CreateHashEntry(&cache->namedColors, colorName, &newEntry);
    if (!newEntry) {
    	Tcl_Obj *oldColor = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);







|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    XColor *colorPtr)
{
    int newEntry;
    Tcl_HashEntry *entryPtr;
    char nameBuf[14];
    Tcl_Obj *colorNameObj;

    snprintf(nameBuf, sizeof(nameBuf), "#%04X%04X%04X",
    	colorPtr->red, colorPtr->green, colorPtr->blue);
    colorNameObj = Tcl_NewStringObj(nameBuf, -1);
    Tcl_IncrRefCount(colorNameObj);

    entryPtr = Tcl_CreateHashEntry(&cache->namedColors, colorName, &newEntry);
    if (!newEntry) {
    	Tcl_Obj *oldColor = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
239
240
241
242
243
244
245










246
247
248
249
250
251
252
    return objPtr;
}

/*
 * Template for allocation routines:
 */
typedef void *(*Allocator)(Tcl_Interp *, Tk_Window, Tcl_Obj *);











static Tcl_Obj *Ttk_Use(
    Tcl_Interp *interp,
    Tcl_HashTable *table,
    Allocator allocate,
    Tk_Window tkwin,
    Tcl_Obj *objPtr)







>
>
>
>
>
>
>
>
>
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
    return objPtr;
}

/*
 * Template for allocation routines:
 */
typedef void *(*Allocator)(Tcl_Interp *, Tk_Window, Tcl_Obj *);

static void *AllocFont(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) {
	return Tk_AllocFontFromObj(interp, tkwin, objPtr);
}
static void *AllocColor(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) {
	return Tk_AllocColorFromObj(interp, tkwin, objPtr);
}
static void *AllocBorder(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) {
	return Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr);
}

static Tcl_Obj *Ttk_Use(
    Tcl_Interp *interp,
    Tcl_HashTable *table,
    Allocator allocate,
    Tk_Window tkwin,
    Tcl_Obj *objPtr)
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318






319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
 * Ttk_UseFont --
 * 	Acquire a font from the cache.
 */
Tcl_Obj *Ttk_UseFont(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->fontTable,(Allocator)Tk_AllocFontFromObj, tkwin, objPtr);
}

/*
 * Ttk_UseColor --
 * 	Acquire a color from the cache.
 */
Tcl_Obj *Ttk_UseColor(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    objPtr = CheckNamedColor(cache, objPtr);
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->colorTable,(Allocator)Tk_AllocColorFromObj, tkwin, objPtr);
}

/*
 * Ttk_UseBorder --
 * 	Acquire a Tk_3DBorder from the cache.
 */
Tcl_Obj *Ttk_UseBorder(
    Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    objPtr = CheckNamedColor(cache, objPtr);
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->borderTable,(Allocator)Tk_Alloc3DBorderFromObj, tkwin, objPtr);
}

/* NullImageChanged --
 * 	Tk_ImageChangedProc for Ttk_UseImage
 */

static void NullImageChanged(ClientData dummy,
    int x, int y, int width, int height, int imageWidth, int imageHeight)






{ /* No-op */
    (void)dummy;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imageWidth;
    (void)imageHeight;
}

/*
 * Ttk_UseImage --
 * 	Acquire a Tk_Image from the cache.
 */
Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)







|











|












|






|
|
>
>
>
>
>
>

<
<
<
<
<
<
<







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339







340
341
342
343
344
345
346
 * Ttk_UseFont --
 * 	Acquire a font from the cache.
 */
Tcl_Obj *Ttk_UseFont(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->fontTable, AllocFont, tkwin, objPtr);
}

/*
 * Ttk_UseColor --
 * 	Acquire a color from the cache.
 */
Tcl_Obj *Ttk_UseColor(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    objPtr = CheckNamedColor(cache, objPtr);
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->colorTable, AllocColor, tkwin, objPtr);
}

/*
 * Ttk_UseBorder --
 * 	Acquire a Tk_3DBorder from the cache.
 */
Tcl_Obj *Ttk_UseBorder(
    Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    objPtr = CheckNamedColor(cache, objPtr);
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->borderTable, AllocBorder, tkwin, objPtr);
}

/* NullImageChanged --
 * 	Tk_ImageChangedProc for Ttk_UseImage
 */

static void NullImageChanged(
    TCL_UNUSED(void *),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{ /* No-op */







}

/*
 * Ttk_UseImage --
 * 	Acquire a Tk_Image from the cache.
 */
Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)

Changes to generic/ttk/ttkClamTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * Copyright (C) 2004 Joe English
 *
 * "clam" theme; inspired by the XFCE family of Gnome themes.
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*
 * Under windows, the Tk-provided XDrawLine and XDrawArc have an
 * off-by-one error in the end point. This is especially apparent with this
 * theme. Defining this macro as true handles this case.
 */
#if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK)
#	define WIN32_XDRAWLINE_HACK 1
#else
#	define WIN32_XDRAWLINE_HACK 0
#endif

#define STR(x) StR(x)
#define StR(x) #x

#define SCROLLBAR_THICKNESS 14


|













|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * Copyright © 2004 Joe English
 *
 * "clam" theme; inspired by the XFCE family of Gnome themes.
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*
 * Under windows, the Tk-provided XDrawLine and XDrawArc have an
 * off-by-one error in the end point. This is especially apparent with this
 * theme. Defining this macro as true handles this case.
 */
#if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK)
  #define WIN32_XDRAWLINE_HACK 1
#else
  #define WIN32_XDRAWLINE_HACK 0
#endif

#define STR(x) StR(x)
#define StR(x) #x

#define SCROLLBAR_THICKNESS 14

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    int y1 = b.y, y2 = b.y + b.height - 1;
    const int w = WIN32_XDRAWLINE_HACK;
    GC gc;

    if (   outerColorObj
	&& (gc=Ttk_GCForColor(tkwin,outerColorObj,d)))
    {
	XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1); /* N */
	XDrawLine(display,d,gc, x1+1,y2, x2-1+w,y2); /* S */
	XDrawLine(display,d,gc, x1,y1+1, x1,y2-1+w); /* E */
	XDrawLine(display,d,gc, x2,y1+1, x2,y2-1+w); /* W */
    }

    if (   upperColorObj
	&& (gc=Ttk_GCForColor(tkwin,upperColorObj,d)))
    {
	XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1); /* N */
	XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1);   /* E */
    }

    if (   lowerColorObj
	&& (gc=Ttk_GCForColor(tkwin,lowerColorObj,d)))
    {
	XDrawLine(display,d,gc, x2-1,y2-1, x1+1-w,y2-1); /* S */
	XDrawLine(display,d,gc, x2-1,y2-1, x2-1,y1+1-w); /* W */
    }
}

static GC BackgroundGC(Tk_Window tkwin, Tcl_Obj *backgroundObj)
{
    Tk_3DBorder bd = Tk_Get3DBorderFromObj(tkwin, backgroundObj);
    return Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC);







|
|
|
|





|
|





|
|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    int y1 = b.y, y2 = b.y + b.height - 1;
    const int w = WIN32_XDRAWLINE_HACK;
    GC gc;

    if (   outerColorObj
	&& (gc=Ttk_GCForColor(tkwin,outerColorObj,d)))
    {
	XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1);		/* N */
	XDrawLine(display,d,gc, x1+1,y2, x2-1+w,y2);		/* S */
	XDrawLine(display,d,gc, x1,y1+1, x1,y2-1+w);		/* W */
	XDrawLine(display,d,gc, x2,y1+1, x2,y2-1+w);		/* E */
    }

    if (   upperColorObj
	&& (gc=Ttk_GCForColor(tkwin,upperColorObj,d)))
    {
	XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1);	/* N */
	XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1);		/* W */
    }

    if (   lowerColorObj
	&& (gc=Ttk_GCForColor(tkwin,lowerColorObj,d)))
    {
	XDrawLine(display,d,gc, x2-1,y2-1, x1+1-w,y2-1);	/* S */
	XDrawLine(display,d,gc, x2-1,y2-1, x2-1,y1+1-w);	/* E */
    }
}

static GC BackgroundGC(Tk_Window tkwin, Tcl_Obj *backgroundObj)
{
    Tk_3DBorder bd = Tk_Get3DBorderFromObj(tkwin, backgroundObj);
    return Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC);
125
126
127
128
129
130
131

132



133
134
135
136
137
138
139
140
141
142
143
144
145
146

147

148


149
150
151
152
153
154
155
156
157
158
159
160
161
162
 * in this theme, borders are always exactly 2 pixels thick.
 * With -borderwidth 0, border is not drawn at all;
 * otherwise a 2-pixel border is used.  For -borderwidth > 2,
 * the excess is used as padding.
 */

static void BorderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    BorderElement *border = (BorderElement*)elementRecord;
    int borderWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);
    if (borderWidth == 1) ++borderWidth;
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned state)


{
    BorderElement *border = (BorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    int borderWidth = 2;
    Tcl_Obj *outer = 0, *upper = 0, *lower = 0;
    (void)dummy;
    (void)state;

    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);
    Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);

    if (borderWidth == 0) return;

    switch (relief) {







>
|
>
>
>
|



<
<
<







>
|
>
|
>
>





<
<







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158


159
160
161
162
163
164
165
 * in this theme, borders are always exactly 2 pixels thick.
 * With -borderwidth 0, border is not drawn at all;
 * otherwise a 2-pixel border is used.  For -borderwidth > 2,
 * the excess is used as padding.
 */

static void BorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    BorderElement *border = (BorderElement*)elementRecord;
    int borderWidth = 2;




    Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);
    if (borderWidth == 1) ++borderWidth;
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    BorderElement *border = (BorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    int borderWidth = 2;
    Tcl_Obj *outer = 0, *upper = 0, *lower = 0;



    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);
    Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);

    if (borderWidth == 0) return;

    switch (relief) {
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230

231

232


233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*------------------------------------------------------------------------
 * +++ Field element.
 */

typedef struct {
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*backgroundObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(FieldElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,darkColorObj), DARK_COLOR },
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,backgroundObj), "white" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;


    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned state)


{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
    Ttk_Box f = Ttk_PadBox(b, Ttk_UniformPadding(2));
    Tcl_Obj *outer = field->borderColorObj,
	    *inner = field->lightColorObj;
    (void)dummy;
    (void)state;

    DrawSmoothBorder(tkwin, d, b, outer, inner, inner);
    Tk_Fill3DRectangle(
	tkwin, d, bg, f.x, f.y, f.width, f.height, 0, TK_RELIEF_SUNKEN);
}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};

/*
 * Modified field element for comboboxes:
 * 	Right edge is expanded to overlap the dropdown button.
 */
static void ComboboxFieldElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    GC gc = Ttk_GCForColor(tkwin,field->borderColorObj,d);

    ++b.width;
    FieldElementDraw(clientData, elementRecord, tkwin, d, b, state);








<








<
<






<
<
<
|
|
|
|
|
>
|




>
|
>
|
>
>






<
<




















|







197
198
199
200
201
202
203

204
205
206
207
208
209
210
211


212
213
214
215
216
217



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240


241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*------------------------------------------------------------------------
 * +++ Field element.
 */

typedef struct {
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*lightColorObj;

    Tcl_Obj 	*backgroundObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(FieldElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,lightColorObj), LIGHT_COLOR },


    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,backgroundObj), "white" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(



    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
    Ttk_Box f = Ttk_PadBox(b, Ttk_UniformPadding(2));
    Tcl_Obj *outer = field->borderColorObj,
	    *inner = field->lightColorObj;



    DrawSmoothBorder(tkwin, d, b, outer, inner, inner);
    Tk_Fill3DRectangle(
	tkwin, d, bg, f.x, f.y, f.width, f.height, 0, TK_RELIEF_SUNKEN);
}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};

/*
 * Modified field element for comboboxes:
 * 	Right edge is expanded to overlap the dropdown button.
 */
static void ComboboxFieldElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    GC gc = Ttk_GCForColor(tkwin,field->borderColorObj,d);

    ++b.width;
    FieldElementDraw(clientData, elementRecord, tkwin, d, b, state);

279
280
281
282
283
284
285



286





287





















































288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

330



331
332
333
334
335
336
337








338
339
340
341
342
343
344



345
346

347

348

349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368


369
370
371
372



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396












397

398
399


400
401
402
403
404
405
406
407
408
409
410
411
412




413
414


415

416
417
418
419
420
421
422

423
424
425
426

427

428
429
430
431
432
433
434



435
436
437

438



439
440
441




442



443
444
445
446
447
448




449
450


451

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467


468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
    ComboboxFieldElementDraw
};

/*------------------------------------------------------------------------
 * +++ Indicator elements for check and radio buttons.
 */




typedef struct {





    Tcl_Obj *sizeObj;





















































    Tcl_Obj *marginObj;
    Tcl_Obj *backgroundObj;
    Tcl_Obj *foregroundObj;
    Tcl_Obj *upperColorObj;
    Tcl_Obj *lowerColorObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-indicatorsize", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,sizeObj), "10" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "1" },
    { "-indicatorbackground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,backgroundObj), "white" },
    { "-indicatorforeground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,foregroundObj), "black" },
    { "-upperbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,upperColorObj), DARKEST_COLOR },
    { "-lowerbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,lowerColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{

    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int size = 10;
    (void)dummy;
    (void)paddingPtr;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
    *widthPtr = size + Ttk_PaddingWidth(margins);
    *heightPtr = size + Ttk_PaddingHeight(margins);
}

static void RadioIndicatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)

{



    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    GC gcb=Ttk_GCForColor(tkwin,indicator->backgroundObj,d);
    GC gcf=Ttk_GCForColor(tkwin,indicator->foregroundObj,d);
    GC gcu=Ttk_GCForColor(tkwin,indicator->upperColorObj,d);
    GC gcl=Ttk_GCForColor(tkwin,indicator->lowerColorObj,d);
    Ttk_Padding padding;
    (void)dummy;









    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);

    XFillArc(Tk_Display(tkwin),d,gcb, b.x,b.y,b.width,b.height, 0,360*64);
    XDrawArc(Tk_Display(tkwin),d,gcl, b.x,b.y,b.width,b.height, 225*64,180*64);
    XDrawArc(Tk_Display(tkwin),d,gcu, b.x,b.y,b.width,b.height, 45*64,180*64);




    if (state & TTK_STATE_SELECTED) {

	b = Ttk_PadBox(b,Ttk_UniformPadding(3));

	XFillArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 0,360*64);

	XDrawArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 0,360*64);
#if WIN32_XDRAWLINE_HACK
	XDrawArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 300*64,360*64);
#endif
    }
}

static void CheckIndicatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)

{
    Display *display = Tk_Display(tkwin);
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;

    GC gcb=Ttk_GCForColor(tkwin,indicator->backgroundObj,d);
    GC gcf=Ttk_GCForColor(tkwin,indicator->foregroundObj,d);
    GC gcu=Ttk_GCForColor(tkwin,indicator->upperColorObj,d);
    GC gcl=Ttk_GCForColor(tkwin,indicator->lowerColorObj,d);
    Ttk_Padding padding;
    const int w = WIN32_XDRAWLINE_HACK;


    (void)dummy;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);




    XFillRectangle(display,d,gcb, b.x,b.y,b.width,b.height);
    XDrawLine(display,d,gcl,b.x,b.y+b.height,b.x+b.width+w,b.y+b.height);/*S*/
    XDrawLine(display,d,gcl,b.x+b.width,b.y,b.x+b.width,b.y+b.height+w); /*E*/
    XDrawLine(display,d,gcu,b.x,b.y, b.x,b.y+b.height+w); /*W*/
    XDrawLine(display,d,gcu,b.x,b.y, b.x+b.width+w,b.y);  /*N*/

    if (state & TTK_STATE_SELECTED) {
	int p,q,r,s;

	b = Ttk_PadBox(b,Ttk_UniformPadding(2));
	p = b.x, q = b.y, r = b.x+b.width, s = b.y+b.height;

	r+=w, s+=w;
	XDrawLine(display, d, gcf, p,   q,   r,   s);
	XDrawLine(display, d, gcf, p+1, q,   r,   s-1);
	XDrawLine(display, d, gcf, p,   q+1, r-1, s);

	s-=w, q-=w;
	XDrawLine(display, d, gcf, p,   s,   r,   q);
	XDrawLine(display, d, gcf, p+1, s,   r,   q+1);
	XDrawLine(display, d, gcf, p,   s-1, r-1, q);
    }
}














static const Ttk_ElementSpec RadioIndicatorElementSpec = {
    TK_STYLE_VERSION_2,


    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    RadioIndicatorElementDraw
};

static const Ttk_ElementSpec CheckIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    CheckIndicatorElementDraw
};





#define MENUBUTTON_ARROW_SIZE 5




typedef struct {
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *paddingObj;
} MenuIndicatorElement;

static const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =

{
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,sizeObj),
	STR(MENUBUTTON_ARROW_SIZE)},

    { "-arrowcolor",TK_OPTION_COLOR,

	offsetof(MenuIndicatorElement,colorObj),
	"black" },
    { "-arrowpadding",TK_OPTION_STRING,
	offsetof(MenuIndicatorElement,paddingObj),
	"3" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};




static void MenuIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)



{
    MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
    Ttk_Padding margins;




    int size = MENUBUTTON_ARROW_SIZE;



    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->paddingObj, &margins);
    TtkArrowSize(size, ARROW_DOWN, widthPtr, heightPtr);




    *widthPtr += Ttk_PaddingWidth(margins);
    *heightPtr += Ttk_PaddingHeight(margins);


}


static void MenuIndicatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);
    int size = MENUBUTTON_ARROW_SIZE;
    int width, height;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);

    TtkArrowSize(size, ARROW_DOWN, &width, &height);


    b = Ttk_StickBox(b, width, height, 0);
    TtkFillArrow(Tk_Display(tkwin), d, gc, b, ARROW_DOWN);

}

static const Ttk_ElementSpec MenuIndicatorElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(MenuIndicatorElement),
    MenuIndicatorElementOptions,
    MenuIndicatorElementSize,
    MenuIndicatorElementDraw
};

/*------------------------------------------------------------------------
 * +++ Grips.
 *
 * TODO: factor this with ThumbElementDraw
 */

typedef struct {
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*gripCountObj;
} GripElement;

static const Ttk_ElementOptionSpec GripElementOptions[] = {
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(GripElement,lightColorObj), LIGHT_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(GripElement,borderColorObj), DARKEST_COLOR },
    { "-gripcount", TK_OPTION_INT,
	offsetof(GripElement,gripCountObj), "5" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void GripElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    GripElement *grip = (GripElement *)elementRecord;
    int gripCount = 0;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = 2*gripCount;
    } else {
	*heightPtr = 2*gripCount;
    }
}

static void GripElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)

{
    const int w = WIN32_XDRAWLINE_HACK;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    GripElement *grip = (GripElement *)elementRecord;
    GC lightGC = Ttk_GCForColor(tkwin,grip->lightColorObj,d);
    GC darkGC = Ttk_GCForColor(tkwin,grip->borderColorObj,d);
    int gripPad = 1, gripCount = 0;
    int i;
    (void)state;

    Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	int x = b.x + b.width / 2 - gripCount;
	int y1 = b.y + gripPad, y2 = b.y + b.height - gripPad - 1 + w;
	for (i=0; i<gripCount; ++i) {
	    XDrawLine(Tk_Display(tkwin), d, darkGC,  x,y1, x,y2); ++x;
	    XDrawLine(Tk_Display(tkwin), d, lightGC, x,y1, x,y2); ++x;
	}
    } else {
	int y = b.y + b.height / 2 - gripCount;
	int x1 = b.x + gripPad, x2 = b.x + b.width - gripPad - 1 + w;
	for (i=0; i<gripCount; ++i) {
	    XDrawLine(Tk_Display(tkwin), d, darkGC,  x1,y, x2,y); ++y;
	    XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y, x2,y); ++y;
	}
    }
}

static const Ttk_ElementSpec GripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(GripElement),







>
>
>

>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<
<














|
|
>

>


<
<
|


<
|
|


|
<
<
>

>
>
>
|
<
<
<
<
<
<
>
>
>
>
>
>
>
>
|
<
<
|
|
<
<
>
>
>
|
<
>
|
>
|
>
|
<
<
<
<
|
|
|
|
|
>
|
<
|
|
|
|
<
<
<
|
>
>
|



>
>
>
|
|
|
|
|
<
|
<
<
|
|
<
|
<
<
<
<
|
<
<
<
<

|
>
>
>
>
>
>
>
>
>
>
>
>

>
|
<
>
>
|
<
|
|
<
|
<
<
|
|
|
<
<
>
>
>
>

<
>
>
|
>
|
<
|
|
|
|
|
>
|
<
<
<
>
|
>
|
|
|
|
|
|
<
>
>
>

<
|
>
|
>
>
>
|
<
<
>
>
>
>
|
>
>
>
|
<
|
<
<
<
>
>
>
>
|
<
>
>
|
>
|
<
<
<
<
<
<
<
<
<
<
<

<
|
<
>
>
|
<
>


|
<

|
|
|
|











|







|
|





|
>



|
<
<

|

|

|





|
>






|

<

|


|

|
|
|


|

|
|
|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356


357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377


378
379
380

381
382
383
384
385


386
387
388
389
390
391






392
393
394
395
396
397
398
399
400


401
402


403
404
405
406

407
408
409
410
411
412




413
414
415
416
417
418
419

420
421
422
423



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

439


440
441

442




443




444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463

464
465

466


467
468
469


470
471
472
473
474

475
476
477
478
479

480
481
482
483
484
485
486



487
488
489
490
491
492
493
494
495

496
497
498
499

500
501
502
503
504
505
506


507
508
509
510
511
512
513
514
515

516



517
518
519
520
521

522
523
524
525
526











527

528

529
530
531

532
533
534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572


573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
    ComboboxFieldElementDraw
};

/*------------------------------------------------------------------------
 * +++ Indicator elements for check and radio buttons.
 */

/*
 * Indicator image descriptor:
 */
typedef struct {
    int width;				/* unscaled width */
    int height;				/* unscaled height */
    const char *const offDataPtr;
    const char *const onDataPtr;
} IndicatorSpec;

static const char checkbtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <path d='m0 0v16h1v-15h15v-1z' fill='#9e9a91'/>\n\
     <path d='m15 1v14h-14v1h15v-15z' fill='#cfcdc8'/>\n\
     <rect x='1' y='1' width='14' height='14' fill='#ffffff'/>\n\
    </svg>";

static const char checkbtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <path d='m0 0v16h1v-15h15v-1z' fill='#9e9a91'/>\n\
     <path d='m15 1v14h-14v1h15v-15z' fill='#cfcdc8'/>\n\
     <rect x='1' y='1' width='14' height='14' fill='#ffffff'/>\n\
     <path d='m5 5 6 6m0-6-6 6' fill='none' stroke='#000000' stroke-linecap='round' stroke-width='2'/>\n\
    </svg>";

static const IndicatorSpec checkbutton_spec = {
    16, 16,
    checkbtnOffData,
    checkbtnOnData
};

static const char radiobtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <defs>\n\
      <linearGradient id='linearGradient' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#9e9a91' offset='0'/>\n\
       <stop stop-color='#cfcdc8' offset='1'/>\n\
      </linearGradient>\n\
     </defs>\n\
     <circle cx='8' cy='8' r='8' fill='url(#linearGradient)'/>\n\
     <circle cx='8' cy='8' r='7' fill='#ffffff'/>\n\
    </svg>";

static const char radiobtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <defs>\n\
      <linearGradient id='linearGradient' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#9e9a91' offset='0'/>\n\
       <stop stop-color='#cfcdc8' offset='1'/>\n\
      </linearGradient>\n\
     </defs>\n\
     <circle cx='8' cy='8' r='8' fill='url(#linearGradient)'/>\n\
     <circle cx='8' cy='8' r='7' fill='#ffffff'/>\n\
     <circle cx='8' cy='8' r='4' fill='#000000'/>\n\
    </svg>";

static const IndicatorSpec radiobutton_spec = {
    16, 16,
    radiobtnOffData,
    radiobtnOnData
};

typedef struct {
    Tcl_Obj *marginObj;
    Tcl_Obj *backgroundObj;
    Tcl_Obj *foregroundObj;
    Tcl_Obj *upperColorObj;
    Tcl_Obj *lowerColorObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {


    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "1" },
    { "-indicatorbackground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,backgroundObj), "white" },
    { "-indicatorforeground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,foregroundObj), "black" },
    { "-upperbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,upperColorObj), DARKEST_COLOR },
    { "-lowerbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,lowerColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;


    double scalingLevel = TkScalingLevel(tkwin);

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);

    *widthPtr = spec->width * scalingLevel + Ttk_PaddingWidth(margins);
    *heightPtr = spec->height * scalingLevel + Ttk_PaddingHeight(margins);
}

static void ColorToStr(


    const XColor *colorPtr, char *colorStr)	/* in the format "RRGGBB" */
{
    snprintf(colorStr, 7, "%02x%02x%02x",
	     colorPtr->red >> 8, colorPtr->green >> 8, colorPtr->blue >> 8);
}







static void ImageChanged(		/* to be passed to Tk_GetImage() */
    TCL_UNUSED(void *),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{


}



static void IndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{

    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding padding;
    const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
    double scalingLevel = TkScalingLevel(tkwin);
    int width = spec->width * scalingLevel;
    int height = spec->height * scalingLevel;





    char upperBdColorStr[7], lowerBdColorStr[7], bgColorStr[7], fgColorStr[7];
    unsigned int selected = (state & TTK_STATE_SELECTED);
    Tcl_Interp *interp = Tk_Interp(tkwin);
    char imgName[60];
    Tk_Image img;


    const char *svgDataPtr;
    size_t svgDataLen;
    char *svgDataCopy;
    char *upperBdColorPtr, *lowerBdColorPtr, *bgColorPtr, *fgColorPtr;



    const char *cmdFmt;
    size_t scriptSize;
    char *script;
    int code;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);

    /*
     * Sanity check
     */
    if (   b.x < 0
	|| b.y < 0
	|| Tk_Width(tkwin) < b.x + width
	|| Tk_Height(tkwin) < b.y + height)

    {


	/* Oops!  Not enough room to display the image.
	 * Don't draw anything.

	 */




	return;




    }

    /*
     * Construct the color strings upperBdColorStr, lowerBdColorStr,
     * bgColorStr, and fgColorStr
     */
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->upperColorObj),
	       upperBdColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->lowerColorObj),
	       lowerBdColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->backgroundObj),
	       bgColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->foregroundObj),
	       fgColorStr);

    /*
     * Check whether there is an SVG image of this size for the indicator's

     * type (0 = checkbtn, 1 = radiobtn) and these color strings
     */
    snprintf(imgName, sizeof(imgName),

	     "::tk::icons::indicator_clam%d_%d_%s_%s_%s_%s",
	     width, spec->offDataPtr == radiobtnOffData,

	     upperBdColorStr, lowerBdColorStr, bgColorStr,


	     selected ? fgColorStr : "XXXXXX");
    img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    if (img == NULL) {


	/*
	 * Determine the SVG data to use for the photo image
	 */
	svgDataPtr = (selected ? spec->onDataPtr : spec->offDataPtr);


	/*
	 * Copy the string pointed to by svgDataPtr to
	 * a newly allocated memory area svgDataCopy
	 */
	svgDataLen = strlen(svgDataPtr);

	svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
	if (svgDataCopy == NULL) {
	    return;
	}
	memcpy(svgDataCopy, svgDataPtr, svgDataLen);
	svgDataCopy[svgDataLen] = '\0';




	/*
	 * Update the colors within svgDataCopy
	 */

	upperBdColorPtr = strstr(svgDataCopy, "9e9a91");
	lowerBdColorPtr = strstr(svgDataCopy, "cfcdc8");
	bgColorPtr =	  strstr(svgDataCopy, "ffffff");
	fgColorPtr =	  strstr(svgDataCopy, "000000");


	assert(upperBdColorPtr);
	assert(lowerBdColorPtr);
	assert(bgColorPtr);


	memcpy(upperBdColorPtr, upperBdColorStr, 6);
	memcpy(lowerBdColorPtr, lowerBdColorStr, 6);
	memcpy(bgColorPtr, bgColorStr, 6);
	if (fgColorPtr != NULL) {
	    memcpy(fgColorPtr, fgColorStr, 6);
	}



	/*
	 * Create an SVG photo image from svgDataCopy
	 */
	cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
	scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
	script = (char *)attemptckalloc(scriptSize);
	if (script == NULL) {
	    ckfree(svgDataCopy);
	    return;

	}



	snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
	ckfree(svgDataCopy);
	code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
	ckfree(script);
	if (code != TCL_OK) {

	    Tcl_BackgroundException(interp, code);
	    return;
	}
	img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    }













    /*

     * Display the image
     */
    Tk_RedrawImage(img, 0, 0, width, height, d, b.x, b.y);

    Tk_FreeImage(img);
}

static const Ttk_ElementSpec IndicatorElementSpec = {

    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    IndicatorElementDraw
};

/*------------------------------------------------------------------------
 * +++ Grips.
 *
 * TODO: factor this with ThumbElementDraw
 */

typedef struct {
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*gripSizeObj;
} GripElement;

static const Ttk_ElementOptionSpec GripElementOptions[] = {
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(GripElement,lightColorObj), LIGHT_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(GripElement,borderColorObj), DARKEST_COLOR },
    { "-gripsize", TK_OPTION_PIXELS,
	offsetof(GripElement,gripSizeObj), "7.5p" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void GripElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    GripElement *grip = (GripElement *)elementRecord;
    int gripSize = 0;



    Tk_GetPixelsFromObj(NULL, tkwin, grip->gripSizeObj, &gripSize);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = gripSize;
    } else {
	*heightPtr = gripSize;
    }
}

static void GripElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    const int w = WIN32_XDRAWLINE_HACK;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    GripElement *grip = (GripElement *)elementRecord;
    GC lightGC = Ttk_GCForColor(tkwin,grip->lightColorObj,d);
    GC darkGC = Ttk_GCForColor(tkwin,grip->borderColorObj,d);
    int gripPad = 1, gripSize = 0;
    int i;


    Tk_GetPixelsFromObj(NULL, tkwin, grip->gripSizeObj, &gripSize);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	int x = b.x + (b.width - gripSize) / 2;
	int y1 = b.y + gripPad, y2 = b.y + b.height - gripPad - 1 + w;
	for (i=0; i<gripSize; ++i) {
	    XDrawLine(Tk_Display(tkwin), d, (i&1)?lightGC:darkGC, x,y1, x,y2);
	    ++x;
	}
    } else {
	int y = b.y + (b.height - gripSize) / 2;
	int x1 = b.x + gripPad, x2 = b.x + b.width - gripPad - 1 + w;
	for (i=0; i<gripSize; ++i) {
	    XDrawLine(Tk_Display(tkwin), d, (i&1)?lightGC:darkGC, x1,y, x2,y);
	    ++y;
	}
    }
}

static const Ttk_ElementSpec GripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(GripElement),
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605

606

607


608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627

628

629


630
631
632
633
634
635
636
637
638
639
640
641

642

643


644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700

701


702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
    Tcl_Obj 	*backgroundObj;
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*troughColorObj;
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*arrowColorObj;
    Tcl_Obj 	*arrowSizeObj;
    Tcl_Obj 	*gripCountObj;
    Tcl_Obj 	*sliderlengthObj;
} ScrollbarElement;

static const Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(ScrollbarElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(ScrollbarElement,backgroundObj), FRAME_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,borderColorObj), DARKEST_COLOR },
    { "-troughcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,troughColorObj), DARKER_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,darkColorObj), DARK_COLOR },
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,arrowColorObj), "#000000" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
    { "-gripcount", TK_OPTION_INT,
	offsetof(ScrollbarElement,gripCountObj), "5" },
    { "-sliderlength", TK_OPTION_INT,
	offsetof(ScrollbarElement,sliderlengthObj), "30" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned state)


{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    GC gcb = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
    GC gct = Ttk_GCForColor(tkwin,sb->troughColorObj,d);
    (void)dummy;
    (void)state;

    XFillRectangle(Tk_Display(tkwin), d, gct, b.x, b.y, b.width-1, b.height-1);
    XDrawRectangle(Tk_Display(tkwin), d, gcb, b.x, b.y, b.width-1, b.height-1);
}

static const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TtkNullElementSize,
    TroughElementDraw
};

static void ThumbElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int size = SCROLLBAR_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);
    *widthPtr = *heightPtr = size;
}

static void ThumbElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned state)


{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int gripCount = 0;
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    GC lightGC, darkGC;
    int x1, y1, x2, y2, dx, dy, i;
    const int w = WIN32_XDRAWLINE_HACK;
    (void)dummy;
    (void)state;

    DrawSmoothBorder(tkwin, d, b,
	sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
    XFillRectangle(
	Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj),
	b.x+2, b.y+2, b.width-4, b.height-4);

    /*
     * Draw grip:
     */
    TtkGetOrientFromObj(NULL, sb->orientObj, &orient);
    Tcl_GetIntFromObj(NULL, sb->gripCountObj, &gripCount);
    lightGC = Ttk_GCForColor(tkwin,sb->lightColorObj,d);
    darkGC = Ttk_GCForColor(tkwin,sb->borderColorObj,d);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	dx = 1; dy = 0;
	x1 = x2 = b.x + b.width / 2 - gripCount;
	y1 = b.y + 2;
	y2 = b.y + b.height - 3 + w;
    } else {
	dx = 0; dy = 1;
	y1 = y2 = b.y + b.height / 2 - gripCount;
	x1 = b.x + 2;
	x2 = b.x + b.width - 3 + w;
    }

    for (i=0; i<gripCount; ++i) {
	XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2);
	x1 += dx; x2 += dx; y1 += dy; y2 += dy;
	XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2);
	x1 += dx; x2 += dx; y1 += dy; y2 += dy;
    }
}

static const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*------------------------------------------------------------------------
 * +++ Slider element.
 */
static void SliderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int length, thickness;
    Ttk_Orient orient;
    (void)dummy;
    (void)paddingPtr;

    length = thickness = SCROLLBAR_THICKNESS;
    TtkGetOrientFromObj(NULL, sb->orientObj, &orient);
    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &thickness);
    Tk_GetPixelsFromObj(NULL, tkwin, sb->sliderlengthObj, &length);
    if (orient == TTK_ORIENT_VERTICAL) {
	*heightPtr = length;
	*widthPtr = thickness;
    } else {
	*heightPtr = thickness;
	*widthPtr = length;
    }

}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    SliderElementSize,







|




















|
|
|





>
|
>
|
>
>




<
<














>
|
>
|
>
>



<
<
<

|




>
|
>
|
>
>


|




<
<










|
|





|




|




|
|

|
<















>
|
>
|
>
>




<
<


|
|








<







631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676


677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699



700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718


719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774


775
776
777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
    Tcl_Obj 	*backgroundObj;
    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*troughColorObj;
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*arrowColorObj;
    Tcl_Obj 	*arrowSizeObj;
    Tcl_Obj 	*gripSizeObj;
    Tcl_Obj 	*sliderlengthObj;
} ScrollbarElement;

static const Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(ScrollbarElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(ScrollbarElement,backgroundObj), FRAME_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,borderColorObj), DARKEST_COLOR },
    { "-troughcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,troughColorObj), DARKER_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,darkColorObj), DARK_COLOR },
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,arrowColorObj), "#000000" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
    { "-gripsize", TK_OPTION_PIXELS,
	offsetof(ScrollbarElement,gripSizeObj), "7.5p" },
    { "-sliderlength", TK_OPTION_PIXELS,
	offsetof(ScrollbarElement,sliderlengthObj), "30" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    GC gcb = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
    GC gct = Ttk_GCForColor(tkwin,sb->troughColorObj,d);



    XFillRectangle(Tk_Display(tkwin), d, gct, b.x, b.y, b.width-1, b.height-1);
    XDrawRectangle(Tk_Display(tkwin), d, gcb, b.x, b.y, b.width-1, b.height-1);
}

static const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TtkNullElementSize,
    TroughElementDraw
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int size = SCROLLBAR_THICKNESS;




    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
    *widthPtr = *heightPtr = size;
}

static void ThumbElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int gripSize = 0;
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    GC lightGC, darkGC;
    int x1, y1, x2, y2, dx, dy, i;
    const int w = WIN32_XDRAWLINE_HACK;



    DrawSmoothBorder(tkwin, d, b,
	sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
    XFillRectangle(
	Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj),
	b.x+2, b.y+2, b.width-4, b.height-4);

    /*
     * Draw grip:
     */
    Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, sb->gripSizeObj, &gripSize);
    lightGC = Ttk_GCForColor(tkwin,sb->lightColorObj,d);
    darkGC = Ttk_GCForColor(tkwin,sb->borderColorObj,d);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	dx = 1; dy = 0;
	x1 = x2 = b.x + (b.width - gripSize) / 2;
	y1 = b.y + 2;
	y2 = b.y + b.height - 3 + w;
    } else {
	dx = 0; dy = 1;
	y1 = y2 = b.y + (b.height - gripSize) / 2;
	x1 = b.x + 2;
	x2 = b.x + b.width - 3 + w;
    }

    for (i=0; i<gripSize; ++i) {
	XDrawLine(Tk_Display(tkwin), d, (i&1)?lightGC:darkGC, x1,y1, x2,y2);
	x1 += dx; x2 += dx; y1 += dy; y2 += dy;


    }
}

static const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*------------------------------------------------------------------------
 * +++ Slider element.
 */
static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int length, thickness;
    Ttk_Orient orient;



    length = thickness = SCROLLBAR_THICKNESS;
    Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &thickness);
    Tk_GetPixelsFromObj(NULL, tkwin, sb->sliderlengthObj, &length);
    if (orient == TTK_ORIENT_VERTICAL) {
	*heightPtr = length;
	*widthPtr = thickness;
    } else {
	*heightPtr = thickness;
	*widthPtr = length;
    }

}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    SliderElementSize,
739
740
741
742
743
744
745

746

747


748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779



780
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
	    widthPtr, heightPtr, paddingPtr);
    *paddingPtr = Ttk_UniformPadding(2);
    *widthPtr += 4;
    *heightPtr += 4;
}

static void PbarElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned state)


{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    (void)dummy;
    (void)state;

    b = Ttk_PadBox(b, Ttk_UniformPadding(2));
    if (b.width > 4 && b.height > 4) {
	DrawSmoothBorder(tkwin, d, b,
	    sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
	XFillRectangle(Tk_Display(tkwin), d,
	    BackgroundGC(tkwin, sb->backgroundObj),
	    b.x+2, b.y+2, b.width-4, b.height-4);
    }
}

static const Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    PbarElementSize,
    PbarElementDraw
};


/*------------------------------------------------------------------------
 * +++ Scrollbar arrows.
 */
static void ArrowElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;



    int size = SCROLLBAR_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);





    *widthPtr = *heightPtr = size;



}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)

{
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;




    GC gc = Ttk_GCForColor(tkwin,sb->arrowColorObj, d);
    int h, cx, cy;
    (void)state;

    DrawSmoothBorder(tkwin, d, b,
	sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);

    XFillRectangle(
	Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj),
	b.x+2, b.y+2, b.width-4, b.height-4);

    b = Ttk_PadBox(b, Ttk_UniformPadding(3));
    h = b.width < b.height ? b.width : b.height;



    TtkArrowSize(h/2, direction, &cx, &cy);













    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};































/*------------------------------------------------------------------------
 * +++ Notebook elements.
 *
 * Note: Tabs, except for the rightmost, overlap the neighbor to
 * their right by one pixel.
 */







>
|
>
|
>
>


<
<



















<




|
|
>


>
>
>

<
<
<

|
>
>
>
>
>
|
>
>
>




|
>

<

>
>
>
>
|
<
<








|
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	    widthPtr, heightPtr, paddingPtr);
    *paddingPtr = Ttk_UniformPadding(2);
    *widthPtr += 4;
    *heightPtr += 4;
}

static void PbarElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;



    b = Ttk_PadBox(b, Ttk_UniformPadding(2));
    if (b.width > 4 && b.height > 4) {
	DrawSmoothBorder(tkwin, d, b,
	    sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
	XFillRectangle(Tk_Display(tkwin), d,
	    BackgroundGC(tkwin, sb->backgroundObj),
	    b.x+2, b.y+2, b.width-4, b.height-4);
    }
}

static const Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    PbarElementSize,
    PbarElementDraw
};


/*------------------------------------------------------------------------
 * +++ Scrollbar arrows.
 */
static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding = Ttk_UniformPadding(round(3 * scalingLevel));
    int size = SCROLLBAR_THICKNESS;




    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
    if (*widthPtr < *heightPtr) {
	*widthPtr = *heightPtr;
    } else {
	*heightPtr = *widthPtr;
    }
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{

    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding = Ttk_UniformPadding(round(3 * scalingLevel));
    int cx, cy;
    GC gc = Ttk_GCForColor(tkwin, sb->arrowColorObj, d);



    DrawSmoothBorder(tkwin, d, b,
	sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);

    XFillRectangle(
	Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj),
	b.x+2, b.y+2, b.width-4, b.height-4);

    b = Ttk_PadBox(b, padding);

    switch (direction) {
	case ARROW_UP:
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_LEFT:
	case ARROW_RIGHT:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*
 * Modified arrow element for spinboxes:
 * 	The width and height are different.
 */
static void SpinboxArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding = Ttk_UniformPadding(round(3 * scalingLevel));
    int size = 10;

    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
}

static const Ttk_ElementSpec SpinboxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    SpinboxArrowElementSize,
    ArrowElementDraw
};

/*------------------------------------------------------------------------
 * +++ Notebook elements.
 *
 * Note: Tabs, except for the rightmost, overlap the neighbor to
 * their right by one pixel.
 */
843
844
845
846
847
848
849


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
	offsetof(NotebookElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,darkColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TabElementSize(


    void *dummy, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{


    int borderWidth = 2;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;










    paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;


    paddingPtr->bottom = 0;




}


static void TabElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{



    NotebookElement *tab = (NotebookElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    Display *display = Tk_Display(tkwin);
    int borderWidth = 2, dh = 0;
    int x1,y1,x2,y2;
    GC gc;
    const int w = WIN32_XDRAWLINE_HACK;
    (void)dummy;




    if (state & TTK_STATE_SELECTED) {
	dh = borderWidth;
    }




    if (state & TTK_STATE_USER2) {	/* Rightmost tab */
	--b.width;
    }













































    Tk_Fill3DRectangle(tkwin, d, border,
	b.x+2, b.y+2, b.width-1, b.height-2+dh, borderWidth, TK_RELIEF_FLAT);



    x1 = b.x, x2 = b.x + b.width;













    y1 = b.y, y2 = b.y + b.height;









    gc=Ttk_GCForColor(tkwin,tab->borderColorObj,d);
    XDrawLine(display,d,gc, x1,y1+1, x1,y2+w);
    XDrawLine(display,d,gc, x2,y1+1, x2,y2+w);
    XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1);

    gc=Ttk_GCForColor(tkwin,tab->lightColorObj,d);
    XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1+dh+w);
    XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1);


}

static const Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NotebookElement),
    NotebookElementOptions,
    TabElementSize,
    TabElementDraw
};

static void ClientElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    int borderWidth = 2;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void ClientElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    NotebookElement *ce = (NotebookElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 2;
    (void)dummy;
    (void)state;

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_FLAT);
    DrawSmoothBorder(tkwin, d, b,
    	ce->borderColorObj, ce->lightColorObj, ce->darkColorObj);
}








>
>
|
>
>
|

>
>

|
<
<
|
<
>
|
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
|
|
>

>
|
>
|
>
>

>
>
>



<
|


|
>
>
|
>

|


>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
|
|
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

>
>
>
>
>
>
>
|
|
|
|

|
|
|
>
>












>
|
>
>
>
|


<
<
<
<
<





>
|
>
|
>
>




<
<







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
	offsetof(NotebookElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,darkColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TabElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    int borderWidth = 2;



    if (mainInfoPtr != NULL) {

	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    int borderWidth = 2, delta = 0;
    NotebookElement *tab = (NotebookElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    Display *display = Tk_Display(tkwin);

    int x1, y1, x2, y2;
    GC gc;
    const int w = WIN32_XDRAWLINE_HACK;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    if (state & TTK_STATE_SELECTED) {
	delta = borderWidth;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    if (state & TTK_STATE_USER2) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x;		y1 = b.y;		/* top left */
	    x2 = b.x + b.width; y2 = b.y + b.height-1;	/* bottom right */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1+1, x1, y2+1+w);
	    XDrawLine(display, d, gc, x2, y1+1, x2, y2+1+w);
	    XDrawLine(display, d, gc, x1+1, y1, x2-1+w, y1);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2+delta+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2-1+w, y1+1);
	    break;

	case TTK_STICK_N:
	    if (state & TTK_STATE_USER2) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y-delta, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x;		y1 = b.y + b.height-1;	/* bottom left */
	    x2 = b.x + b.width; y2 = b.y;		/* top right */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1-1, x1, y2-1-w);
	    XDrawLine(display, d, gc, x2, y1-1, x2, y2-1-w);
	    XDrawLine(display, d, gc, x1+1, y1, x2-1+w, y1);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1-1, x1+1, y2-delta-w);
	    XDrawLine(display, d, gc, x1+1, y1-1, x2-1+w, y1-1);
	    break;

	case TTK_STICK_E:
	    if (state & TTK_STATE_USER2) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x;		  y1 = b.y;		/* top left */
	    x2 = b.x + b.width-1; y2 = b.y + b.height;	/* bottom right */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1+1, x1, y2-1+w);
	    XDrawLine(display, d, gc, x1+1, y1, x2+1+w, y1);
	    XDrawLine(display, d, gc, x1+1, y2, x2+1+w, y2);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2-1+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2+delta+w, y1+1);
	    break;

	case TTK_STICK_W:
	    if (state & TTK_STATE_USER2) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x-delta, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x + b.width-1; y1 = b.y;		/* top right */
	    x2 = b.x;		  y2 = b.y + b.height;	/* bottom left */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1+1, x1, y2-1+w);
	    XDrawLine(display, d, gc, x1-1, y1, x2-1-w, y1);
	    XDrawLine(display, d, gc, x1-1, y2, x2-1-w, y2);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1-1, y1+1, x1-1, y2-1+w);
	    XDrawLine(display, d, gc, x1-1, y1+1, x2-delta-w, y1+1);
	    break;
    }
}

static const Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NotebookElement),
    NotebookElementOptions,
    TabElementSize,
    TabElementDraw
};

static void ClientElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    int borderWidth = 2;






    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void ClientElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    NotebookElement *ce = (NotebookElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 2;



    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_FLAT);
    DrawSmoothBorder(tkwin, d, b,
    	ce->borderColorObj, ce->lightColorObj, ce->darkColorObj);
}

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
	TTK_NODE("Sash.vgrip", TTK_FILL_BOTH)))

TTK_END_LAYOUT_TABLE

/*------------------------------------------------------------------------
 * +++ Initialization.
 */


MODULE_SCOPE int
TtkClamTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_CreateTheme(interp, "clam", 0);

    if (!theme) {
        return TCL_ERROR;
    }

    Ttk_RegisterElement(interp,
	theme, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "Combobox.field", &ComboboxFieldElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "trough", &TroughElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "uparrow", &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp,


	theme, "downarrow", &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp,


	theme, "leftarrow", &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp,
	theme, "rightarrow", &ArrowElementSpec, INT2PTR(ARROW_RIGHT));

    Ttk_RegisterElement(interp,

	theme, "Radiobutton.indicator", &RadioIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "Checkbutton.indicator", &CheckIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "Menubutton.indicator", &MenuIndicatorElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "bar", &PbarElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "pbar", &PbarElementSpec, NULL);







>










|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
>
>
|
|
|
<
|
>
|
|
|
|
|







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
	TTK_NODE("Sash.vgrip", TTK_FILL_BOTH)))

TTK_END_LAYOUT_TABLE

/*------------------------------------------------------------------------
 * +++ Initialization.
 */
MODULE_SCOPE int TtkClamTheme_Init(Tcl_Interp *);

MODULE_SCOPE int
TtkClamTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_CreateTheme(interp, "clam", 0);

    if (!theme) {
        return TCL_ERROR;
    }

    Ttk_RegisterElement(interp, theme, "border",
	    &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "field",
	    &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Combobox.field",
	    &ComboboxFieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "trough",
	    &TroughElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "thumb",
	    &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
	    &SpinboxArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
	    &SpinboxArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));

    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &IndicatorElementSpec, (void *)&checkbutton_spec);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &IndicatorElementSpec, (void *)&radiobutton_spec);

    Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "bar", &PbarElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "pbar", &PbarElementSpec, NULL);

Changes to generic/ttk/ttkClassicTheme.c.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2004, Joe English
 *
 * "classic" theme; implements the classic Motif-like Tk look.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright © 2004, Joe English
 *
 * "classic" theme; implements the classic Motif-like Tk look.
 *
 */

#include "tkInt.h"
#include "ttkTheme.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
51
52
53
54
55
56
57
58
59
60
61
62
63
	offsetof(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND },
    { "-highlightthickness",TK_OPTION_PIXELS,
	offsetof(HighlightElement,highlightThicknessObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void HighlightElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
    *paddingPtr = Ttk_UniformPadding((short)highlightThickness);
}

static void HighlightElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;
    XColor *highlightColor = Tk_GetColorFromObj(tkwin, hl->highlightColorObj);
    (void)dummy;
    (void)b;
    (void)state;

    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
    if (highlightColor && highlightThickness > 0) {
	GC gc = Tk_GCForColor(highlightColor, d);
	Tk_DrawFocusHighlight(tkwin, gc, highlightThickness, d);
    }
}







>
|
>
>
>
|



<
<
<
<






>
|
>
|
>
>




<
<
<







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41




42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57



58
59
60
61
62
63
64
	offsetof(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND },
    { "-highlightthickness",TK_OPTION_PIXELS,
	offsetof(HighlightElement,highlightThicknessObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void HighlightElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;





    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
    *paddingPtr = Ttk_UniformPadding((short)highlightThickness);
}

static void HighlightElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;
    XColor *highlightColor = Tk_GetColorFromObj(tkwin, hl->highlightColorObj);




    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
    if (highlightColor && highlightThickness > 0) {
	GC gc = Tk_GCForColor(highlightColor, d);
	Tk_DrawFocusHighlight(tkwin, gc, highlightThickness, d);
    }
}
98
99
100
101
102
103
104

105



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131

132


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	offsetof(ButtonBorderElement,reliefObj), "flat" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ButtonBorderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int borderWidth = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
	borderWidth += 5;
    }
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

/*
 * (@@@ Note: ButtonBorderElement still still still buggy:
 * padding for default ring is drawn in the wrong color
 * when the button is active.)
 */
static void ButtonBorderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int inset = 0;
    (void)dummy;
    (void)state;

    /*
     * Get option values.
     */
    border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);







>
|
>
>
>
|




<
<
<
<
















>
|
>
|
>
>






<
<







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115




116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
	offsetof(ButtonBorderElement,reliefObj), "flat" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ButtonBorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int borderWidth = 0;





    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
	borderWidth += 5;
    }
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

/*
 * (@@@ Note: ButtonBorderElement still still still buggy:
 * padding for default ring is drawn in the wrong color
 * when the button is active.)
 */
static void ButtonBorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int inset = 0;



    /*
     * Get option values.
     */
    border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
187
188
189
190
191
192
193






















































































































































































































































194
195
196
197
198
199
200
{
    TK_STYLE_VERSION_2,
    sizeof(ButtonBorderElement),
    ButtonBorderElementOptions,
    ButtonBorderElementSize,
    ButtonBorderElementDraw
};























































































































































































































































/*----------------------------------------------------------------------
 * +++ Arrow element(s).
 *
 * Draws a 3-D shaded triangle.
 * clientData is an enum ArrowDirection pointer.
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
{
    TK_STYLE_VERSION_2,
    sizeof(ButtonBorderElement),
    ButtonBorderElementOptions,
    ButtonBorderElementSize,
    ButtonBorderElementDraw
};

/*----------------------------------------------------------------------
 * +++ Indicator element.
 *
 * Draws the on/off indicator for checkbuttons and radiobuttons.
 *
 * Draws a 3-D square (or diamond), raised if off, sunken if on.
 *
 * This is actually a regression from Tk 8.5 back to the ugly old Motif
 * style; use the "alt", "clam", or "default" theme" for newer, nicer
 * versions.
 */

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *borderWidthObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorcolor", TK_OPTION_BORDER,
	offsetof(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(IndicatorElement,reliefObj), "raised" },
    { "-indicatorsize", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,sizeObj), "9p" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "0 2 4 2" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * Checkbutton indicators: 3-D square.
 */
static void SquareIndicatorElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int diameter = 0;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &diameter);
    *widthPtr = diameter + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + Ttk_PaddingHeight(margins);
}

static void SquareIndicatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Tk_3DBorder border = 0, interior = 0;
    int relief = TK_RELIEF_RAISED;
    Ttk_Padding padding;
    int borderWidth = 2;
    int diameter;

    interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
    border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
    Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
    Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);

    b = Ttk_PadBox(b, padding);

    diameter = b.width < b.height ? b.width : b.height;
    Tk_Fill3DRectangle(tkwin, d, interior, b.x, b.y,
	    diameter, diameter,borderWidth, TK_RELIEF_FLAT);
    Tk_Draw3DRectangle(tkwin, d, border, b.x, b.y,
	    diameter, diameter, borderWidth, relief);
}

/*
 * Radiobutton indicators: 3-D diamond.
 */
static void DiamondIndicatorElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int diameter = 0;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &diameter);
    *widthPtr = diameter + 3 + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + 3 + Ttk_PaddingHeight(margins);
}

static void DiamondIndicatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Tk_3DBorder border = 0, interior = 0;
    int borderWidth = 2;
    int relief = TK_RELIEF_RAISED;
    int diameter, radius;
    XPoint points[4];
    Ttk_Padding padding;

    interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
    border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
    Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
    Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);

    b = Ttk_PadBox(b, padding);

    diameter = b.width < b.height ? b.width : b.height;
    radius = diameter / 2;

    points[0].x = b.x;
    points[0].y = b.y + radius;
    points[1].x = b.x + radius;
    points[1].y = b.y + 2*radius;
    points[2].x = b.x + 2*radius;
    points[2].y = b.y + radius;
    points[3].x = b.x + radius;
    points[3].y = b.y;

    Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT);
    Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief);
}

static const Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    SquareIndicatorElementSize,
    SquareIndicatorElementDraw
};

static const Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    DiamondIndicatorElementSize,
    DiamondIndicatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Menubutton indicators.
 *
 * These aren't functional like radio/check indicators,
 * they're just affordability indicators.
 *
 * Standard Tk sets the indicator size to 4.0 mm by 1.7 mm.
 * I have no idea where these numbers came from.
 */

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *widthObj;
    Tcl_Obj *heightObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *marginObj;
} MenuIndicatorElement;

static const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,widthObj), "4.0m" },
    { "-indicatorheight", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,heightObj), "1.7m" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(MenuIndicatorElement,reliefObj),"raised" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(MenuIndicatorElement,marginObj), "5 0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void MenuIndicatorElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    Ttk_Padding margins;

    Tk_GetPixelsFromObj(NULL, tkwin, mi->widthObj, widthPtr);
    Tk_GetPixelsFromObj(NULL, tkwin, mi->heightObj, heightPtr);
    Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj, &margins);
    *widthPtr += Ttk_PaddingWidth(margins);
    *heightPtr += Ttk_PaddingHeight(margins);
}

static void MenuIndicatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, mi->backgroundObj);
    Ttk_Padding margins;
    int borderWidth = 2;

    Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj,&margins);
    b = Ttk_PadBox(b, margins);
    Tk_GetPixelsFromObj(NULL, tkwin, mi->borderWidthObj, &borderWidth);
    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, TK_RELIEF_RAISED);
}

static const Ttk_ElementSpec MenuIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(MenuIndicatorElement),
    MenuIndicatorElementOptions,
    MenuIndicatorElementSize,
    MenuIndicatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Arrow element(s).
 *
 * Draws a 3-D shaded triangle.
 * clientData is an enum ArrowDirection pointer.
 */
216
217
218
219
220
221
222

223

224


225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(ArrowElement,borderWidthObj),
    	DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF, offsetof(ArrowElement,reliefObj),"raised" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ArrowElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int size = 12;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    *widthPtr = *heightPtr = size;
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    int borderWidth = 2;
    int relief = TK_RELIEF_RAISED;
    int size = b.width < b.height ? b.width : b.height;
    XPoint points[3];
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);


    /*
     * @@@ There are off-by-one pixel errors in the way these are drawn;
     * @@@ need to take a look at Tk_Fill3DPolygon and X11 to find the
     * @@@ exact rules.
     */
    switch (direction)







>
|
>
|
>
>



<
<







|
>

|






<



<







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480


481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500

501
502
503
504
505
506
507
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(ArrowElement,borderWidthObj),
    	DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF, offsetof(ArrowElement,reliefObj),"raised" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ArrowElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int size = 12;



    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    *widthPtr = *heightPtr = size;
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    int borderWidth = 2;
    int relief = TK_RELIEF_RAISED;
    int size = b.width < b.height ? b.width : b.height;
    XPoint points[3];


    Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);


    /*
     * @@@ There are off-by-one pixel errors in the way these are drawn;
     * @@@ need to take a look at Tk_Fill3DPolygon and X11 to find the
     * @@@ exact rules.
     */
    switch (direction)
286
287
288
289
290
291
292


















































































































293
294
295
296
297
298
299
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};




















































































































/*------------------------------------------------------------------------
 * +++ Sash element (for ttk::panedwindow)
 *
 * NOTES:
 *
 * panedwindows with -orient horizontal use vertical sashes, and vice versa.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*------------------------------------------------------------------------
 * +++ Slider element.
 *
 * This is the moving part of the scale widget.  Drawn as a raised box.
 */

typedef struct {
    Tcl_Obj *orientObj;	     /* orientation of overall slider */
    Tcl_Obj *lengthObj;      /* slider length */
    Tcl_Obj *thicknessObj;   /* slider thickness */
    Tcl_Obj *reliefObj;      /* the relief for this object */
    Tcl_Obj *borderObj;      /* the background color */
    Tcl_Obj *borderWidthObj; /* the size of the border */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
	"30" },
    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int length, thickness;

    Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->lengthObj, &length);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);

    switch (orient) {
	case TTK_ORIENT_VERTICAL:
	    *widthPtr = thickness;
	    *heightPtr = length;
	    break;

	case TTK_ORIENT_HORIZONTAL:
	    *widthPtr = length;
	    *heightPtr = thickness;
	    break;
    }
}

static void SliderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    Ttk_Orient orient;

    border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
    Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height,
	borderWidth, relief);

    if (relief != TK_RELIEF_FLAT) {
	if (orient == TTK_ORIENT_HORIZONTAL) {
	    if (b.width > 4) {
		b.x += b.width/2;
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		    b.x-1, b.y+borderWidth, b.x-1, b.y+b.height-borderWidth);
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		    b.x, b.y+borderWidth, b.x, b.y+b.height-borderWidth);
	    }
	} else {
	    if (b.height > 4) {
		b.y += b.height/2;
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		    b.x+borderWidth, b.y-1, b.x+b.width-borderWidth, b.y-1);
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		    b.x+borderWidth, b.y, b.x+b.width-borderWidth, b.y);
	    }
	}
    }
}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Sash element (for ttk::panedwindow)
 *
 * NOTES:
 *
 * panedwindows with -orient horizontal use vertical sashes, and vice versa.
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
    { "-handlepad", TK_OPTION_PIXELS,
	offsetof(SashElement,handlePadObj), "8" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    SashElement *sash = (SashElement *)elementRecord;
    int sashPad = 2, sashThickness = 6, handleSize = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    (void)paddingPtr;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, sash->sashThicknessObj, &sashThickness);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->handleSizeObj, &handleSize);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->sashPadObj, &sashPad);

    if (sashThickness < handleSize + 2*sashPad)
	sashThickness = handleSize + 2*sashPad;

    if (orient == TTK_ORIENT_HORIZONTAL)
	*heightPtr = sashThickness;
    else
	*widthPtr = sashThickness;
}

static void SashElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)

{
    SashElement *sash = (SashElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, sash->borderObj);
    GC gc1,gc2;
    int relief = TK_RELIEF_RAISED;
    int handleSize = 8, handlePad = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    Ttk_Box hb;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, sash->handleSizeObj, &handleSize);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->handlePadObj, &handlePad);
    Tk_GetReliefFromObj(NULL, sash->sashReliefObj, &relief);

    switch (relief) {
	case TK_RELIEF_RAISED: case TK_RELIEF_RIDGE:







|
>




<
<
















|
>








<







692
693
694
695
696
697
698
699
700
701
702
703
704


705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
    { "-handlepad", TK_OPTION_PIXELS,
	offsetof(SashElement,handlePadObj), "8" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SashElement *sash = (SashElement *)elementRecord;
    int sashPad = 2, sashThickness = 6, handleSize = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);



    Tk_GetPixelsFromObj(NULL, tkwin, sash->sashThicknessObj, &sashThickness);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->handleSizeObj, &handleSize);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->sashPadObj, &sashPad);

    if (sashThickness < handleSize + 2*sashPad)
	sashThickness = handleSize + 2*sashPad;

    if (orient == TTK_ORIENT_HORIZONTAL)
	*heightPtr = sashThickness;
    else
	*widthPtr = sashThickness;
}

static void SashElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SashElement *sash = (SashElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, sash->borderObj);
    GC gc1,gc2;
    int relief = TK_RELIEF_RAISED;
    int handleSize = 8, handlePad = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    Ttk_Box hb;


    Tk_GetPixelsFromObj(NULL, tkwin, sash->handleSizeObj, &handleSize);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->handlePadObj, &handlePad);
    Tk_GetReliefFromObj(NULL, sash->sashReliefObj, &relief);

    switch (relief) {
	case TK_RELIEF_RAISED: case TK_RELIEF_RIDGE:
475
476
477
478
479
480
481


482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497







498
499
500
501
502
503
504
505
506
507
508



509
510
511
512
513
514
515
 */

/*------------------------------------------------------------------------
 * TtkClassicTheme_Init --
 * 	Install classic theme.
 */



MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_CreateTheme(interp, "classic", NULL);

    if (!theme) {
	return TCL_ERROR;
    }

    /*
     * Register elements:
     */
    Ttk_RegisterElement(interp, theme, "highlight",
	    &HighlightElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Button.border",
	    &ButtonBorderElementSpec, NULL);








    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));




    Ttk_RegisterElement(interp, theme, "hsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_HORIZONTAL));
    Ttk_RegisterElement(interp, theme, "vsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_VERTICAL));

    /*







>
>
















>
>
>
>
>
>
>











>
>
>







838
839
840
841
842
843
844
845
846
847
848
849
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
 */

/*------------------------------------------------------------------------
 * TtkClassicTheme_Init --
 * 	Install classic theme.
 */

MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp);

MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_CreateTheme(interp, "classic", NULL);

    if (!theme) {
	return TCL_ERROR;
    }

    /*
     * Register elements:
     */
    Ttk_RegisterElement(interp, theme, "highlight",
	    &HighlightElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Button.border",
	    &ButtonBorderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &CheckbuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &RadiobuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenuIndicatorElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

    Ttk_RegisterElement(interp, theme, "slider",
	    &SliderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "hsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_HORIZONTAL));
    Ttk_RegisterElement(interp, theme, "vsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_VERTICAL));

    /*

Changes to generic/ttk/ttkDecls.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

extern const char *TtkInitializeStubs(
	Tcl_Interp *, const char *version, int epoch, int revision);
#define Ttk_InitStubs(interp) TtkInitializeStubs( \
	interp, TTK_VERSION, TTK_STUBS_EPOCH, TTK_STUBS_REVISION)
#else

#define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "Ttk", TTK_VERSION, 0, NULL)

#endif

#if !defined(BUILD_tk)
# define TTK_DEPRECATED(msg) TTKAPI TCL_DEPRECATED_API(msg)
#elif defined(TK_NO_DEPRECATED)
# define TTK_DEPRECATED(msg) MODULE_SCOPE







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

extern const char *TtkInitializeStubs(
	Tcl_Interp *, const char *version, int epoch, int revision);
#define Ttk_InitStubs(interp) TtkInitializeStubs( \
	interp, TTK_VERSION, TTK_STUBS_EPOCH, TTK_STUBS_REVISION)
#else

#define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "ttk", TTK_VERSION, 0, NULL)

#endif

#if !defined(BUILD_tk)
# define TTK_DEPRECATED(msg) TTKAPI TCL_DEPRECATED_API(msg)
#elif defined(TK_NO_DEPRECATED)
# define TTK_DEPRECATED(msg) MODULE_SCOPE
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* 35 */
TTKAPI Tcl_Obj *	Ttk_NewBoxObj(Ttk_Box box);
/* Slot 36 is reserved */
/* Slot 37 is reserved */
/* Slot 38 is reserved */
/* Slot 39 is reserved */
/* 40 */
TTK_DEPRECATED("")
int			Ttk_GetOrientFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *orient);

typedef struct TtkStubs {
    int magic;
    int epoch;
    int revision;
    void *hooks;








<
|
|







135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
/* 35 */
TTKAPI Tcl_Obj *	Ttk_NewBoxObj(Ttk_Box box);
/* Slot 36 is reserved */
/* Slot 37 is reserved */
/* Slot 38 is reserved */
/* Slot 39 is reserved */
/* 40 */

TTKAPI int		Ttk_GetOrientFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Ttk_Orient *orient);

typedef struct TtkStubs {
    int magic;
    int epoch;
    int revision;
    void *hooks;

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    Ttk_Box (*ttk_ExpandBox) (Ttk_Box b, Ttk_Padding p); /* 33 */
    Ttk_Box (*ttk_PlaceBox) (Ttk_Box *cavity, int w, int h, Ttk_Side side, Ttk_Sticky sticky); /* 34 */
    Tcl_Obj * (*ttk_NewBoxObj) (Ttk_Box box); /* 35 */
    void (*reserved36)(void);
    void (*reserved37)(void);
    void (*reserved38)(void);
    void (*reserved39)(void);
    TCL_DEPRECATED_API("") int (*ttk_GetOrientFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); /* 40 */
} TtkStubs;

extern const TtkStubs *ttkStubsPtr;

#ifdef __cplusplus
}
#endif







|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    Ttk_Box (*ttk_ExpandBox) (Ttk_Box b, Ttk_Padding p); /* 33 */
    Ttk_Box (*ttk_PlaceBox) (Ttk_Box *cavity, int w, int h, Ttk_Side side, Ttk_Sticky sticky); /* 34 */
    Tcl_Obj * (*ttk_NewBoxObj) (Ttk_Box box); /* 35 */
    void (*reserved36)(void);
    void (*reserved37)(void);
    void (*reserved38)(void);
    void (*reserved39)(void);
    int (*ttk_GetOrientFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Orient *orient); /* 40 */
} TtkStubs;

extern const TtkStubs *ttkStubsPtr;

#ifdef __cplusplus
}
#endif

Changes to generic/ttk/ttkDefaultTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Copyright (c) 2003, Joe English
 *
 * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme
 */

#include "tkInt.h"
#include "ttkTheme.h"

#if defined(_WIN32)
static const int WIN32_XDRAWLINE_HACK = 1;
#else
static const int WIN32_XDRAWLINE_HACK = 0;
#endif

#if defined(MAC_OSX_TK)
  #define IGNORES_VISUAL
#endif

#define BORDERWIDTH     2

|





|


|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Copyright © 2003 Joe English
 *
 * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme
 */

#include "tkInt.h"
#include "ttkThemeInt.h"

#if defined(_WIN32)
  #define WIN32_XDRAWLINE_HACK 1
#else
  #define WIN32_XDRAWLINE_HACK 0
#endif

#if defined(MAC_OSX_TK)
  #define IGNORES_VISUAL
#endif

#define BORDERWIDTH     2
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
	    DrawCorner(tkwin, d, border, borderGC,
		b.x, b.y, b.width, b.height, 1, thinShadowColors[relief][1]);
	    break;
	case 0:	/* no border -- do nothing */
	    break;
	default: /* Fall back to Motif-style borders: */
	    Tk_Draw3DRectangle(tkwin, d, border,
		b.x, b.y, b.width, b.height, borderWidth,relief);
	    break;
    }
}

/* Alternate shadow colors for entry fields:
 * NOTE: FLAT color is normally white, and the LITE color is a darker shade.
 */







|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
	    DrawCorner(tkwin, d, border, borderGC,
		b.x, b.y, b.width, b.height, 1, thinShadowColors[relief][1]);
	    break;
	case 0:	/* no border -- do nothing */
	    break;
	default: /* Fall back to Motif-style borders: */
	    Tk_Draw3DRectangle(tkwin, d, border,
		b.x, b.y, b.width, b.height, borderWidth, relief);
	    break;
    }
}

/* Alternate shadow colors for entry fields:
 * NOTE: FLAT color is normally white, and the LITE color is a darker shade.
 */
253
254
255
256
257
258
259

260



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    	STRINGIFY(BORDERWIDTH) },
    { "-relief", TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj),
    	"flat" },
        { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
	++borderWidth;
    }

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(

    void *dummy, void *elementRecord,
    Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state)



{
    BorderElement *bd = (BorderElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, bd->borderColorObj);
    int borderWidth = 2;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    (void)dummy;
    (void)state;

    /*
     * Get option values.
     */
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);







>
|
>
>
>
|




<
<
<
<












>
|
|
>
>
>







<
<







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269




270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294


295
296
297
298
299
300
301
    	STRINGIFY(BORDERWIDTH) },
    { "-relief", TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj),
    	"flat" },
        { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;





    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
	++borderWidth;
    }

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    BorderElement *bd = (BorderElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, bd->borderColorObj);
    int borderWidth = 2;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;



    /*
     * Get option values.
     */
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
322
323
324
325
326
327
328


329
330
331
332
333
334
335




336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352

353
354
355
356
357
358

359

360




361




























362









363

364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396


397
398
399
400
401
402
403
404
405
406
407

408


409
410
411
412
413
414
415


416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435



436
437
438









439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454






455
456
457
458
459
460





461
462
463
464
465
466
467
468
469
470
471
472
473
474
/*----------------------------------------------------------------------
 * +++ Field element:
 * 	Used for editable fields.
 */
typedef struct {
    Tcl_Obj	*borderObj;
    Tcl_Obj	*borderColorObj;	/* Extra border color */


} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER, offsetof(FieldElement,borderObj),
    	"white" },
    { "-bordercolor",TK_OPTION_COLOR, offsetof(FieldElement,borderColorObj),
	"black" },




    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;


    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, field->borderColorObj);

    (void)dummy;

    (void)state;

































    Tk_Fill3DRectangle(









	tkwin, d, border, b.x, b.y, b.width, b.height, 0, TK_RELIEF_SUNKEN);

    DrawFieldBorder(tkwin, d, border, borderColor, b);

}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};

/*------------------------------------------------------------------------
 * Indicators --
 *
 * 	Code derived (probably incorrectly) from TIP 109 implementation,
 * 	unix/tkUnixButton.c r 1.15.
 */

/*
 * Indicator bitmap descriptor:
 */
typedef struct {
    int width;		/* Width of each image */
    int height;		/* Height of each image */
    int nimages;	/* #images / row */
    const char *const *pixels;	/* array[height] of char[width*nimage] */
    const Ttk_StateTable *map;/* used to look up image index by state */
} IndicatorSpec;

#if 0
/*XPM*/
static const char *const button_images[] = {
    /* width height ncolors chars_per_pixel */


    "52 13 8 1",
    /* colors */
    "A c #808000000000 s shadow",
    "B c #000080800000 s highlight",
    "C c #808080800000 s 3dlight",
    "D c #000000008080 s window",
    "E c #808000008080 s 3ddark",
    "F c #000080808080 s frame",
    "G c #000000000000 s foreground",
    "H c #000080800000 s disabledfg",
};

#endif



static const Ttk_StateTable checkbutton_states[] = {
    { 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED },
    { 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED },
    { 2, TTK_STATE_DISABLED, TTK_STATE_SELECTED },
    { 3, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 },
    { 0, 0, 0 }


};

static const char *const checkbutton_pixels[] = {
    "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB",
    "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB",
    "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
    "AEDDDDDDDDDCBAEDDDDDDDGDCBAEFFFFFFFFFCBAEFFFFFFFHFCB",
    "AEDDDDDDDDDCBAEDDDDDDGGDCBAEFFFFFFFFFCBAEFFFFFFHHFCB",
    "AEDDDDDDDDDCBAEDGDDDGGGDCBAEFFFFFFFFFCBAEFHFFFHHHFCB",
    "AEDDDDDDDDDCBAEDGGDGGGDDCBAEFFFFFFFFFCBAEFHHFHHHFFCB",
    "AEDDDDDDDDDCBAEDGGGGGDDDCBAEFFFFFFFFFCBAEFHHHHHFFFCB",
    "AEDDDDDDDDDCBAEDDGGGDDDDCBAEFFFFFFFFFCBAEFFHHHFFFFCB",
    "AEDDDDDDDDDCBAEDDDGDDDDDCBAEFFFFFFFFFCBAEFFFHFFFFFCB",
    "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
    "ACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCB",
    "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
};

static IndicatorSpec checkbutton_spec = {
    13, 13, 4,		/* width, height, nimages */



    checkbutton_pixels,
    checkbutton_states
};










static const Ttk_StateTable radiobutton_states[] = {
    { 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED },
    { 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED },
    { 2, TTK_STATE_DISABLED, TTK_STATE_SELECTED },
    { 3, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 },
    { 0, 0, 0 }
};


static const char *const radiobutton_pixels[] = {
    "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF",
    "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF",
    "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF",
    "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
    "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
    "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",






    "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
    "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
    "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
    "FACCDDDDCCBFFFACCDDDDCCBFFFACCFFFFCCBFFFACCFFFFCCBFF",
    "FFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFF",
    "FFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFF",





    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
};

static IndicatorSpec radiobutton_spec = {
    13, 13, 4,		/* width, height, nimages */
    radiobutton_pixels,
    radiobutton_states
};

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *foregroundObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *lightColorObj;







>
>







>
>
>
>




<
<
<
|
|
|
|
|
>
|




>
|
|




>
|
>
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
|
>












<
<
<



|


|
|
<
|
|


<
<
|
|
>
>
|
|
|
|
|
|
|
|
|
|
<
>
|
>
>

|
<
<
<
<
|
>
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
>
>
>
|
|
<
>
>
>
>
>
>
>
>
>

|
<
<
<
<
<
<
>
|
|
<
<
<
<
<
<
>
>
>
>
>
>
|
<
<
<
<
<
>
>
>
>
>
|
<

|
|
|
|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428



429
430
431
432
433
434
435
436

437
438
439
440


441
442
443
444
445
446
447
448
449
450
451
452
453
454

455
456
457
458
459
460




461
462
463
464
















465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483






484
485
486






487
488
489
490
491
492
493





494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510
511
/*----------------------------------------------------------------------
 * +++ Field element:
 * 	Used for editable fields.
 */
typedef struct {
    Tcl_Obj	*borderObj;
    Tcl_Obj	*borderColorObj;	/* Extra border color */
    Tcl_Obj	*focusWidthObj;
    Tcl_Obj	*focusColorObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER, offsetof(FieldElement,borderObj),
    	"white" },
    { "-bordercolor",TK_OPTION_COLOR, offsetof(FieldElement,borderColorObj),
	"black" },
    { "-focuswidth", TK_OPTION_PIXELS, offsetof(FieldElement,focusWidthObj),
	"2" },
    { "-focuscolor", TK_OPTION_COLOR, offsetof(FieldElement,focusColorObj),
	"#4a6984" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(



    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, field->borderColorObj);
    int focusWidth = 2;

    Tk_GetPixelsFromObj(NULL, tkwin, field->focusWidthObj, &focusWidth);

    if (focusWidth > 0 && (state & TTK_STATE_FOCUS)) {
	Display *disp = Tk_Display(tkwin);
	XColor *focusColor = Tk_GetColorFromObj(tkwin, field->focusColorObj);
	GC focusGC = Tk_GCForColor(focusColor, d);

	if (focusWidth > 1) {
	    int x1 = b.x, x2 = b.x + b.width - 1;
	    int y1 = b.y, y2 = b.y + b.height - 1;
	    int w = WIN32_XDRAWLINE_HACK;

	    /*
	     * Draw the outer rounded rectangle
	     */
	    XDrawLine(disp, d, focusGC, x1+1, y1, x2-1+w, y1);	/* N */
	    XDrawLine(disp, d, focusGC, x1+1, y2, x2-1+w, y2);	/* S */
	    XDrawLine(disp, d, focusGC, x1, y1+1, x1, y2-1+w);	/* W */
	    XDrawLine(disp, d, focusGC, x2, y1+1, x2, y2-1+w);	/* E */

	    /*
	     * Draw the inner rectangle
	     */
	    b.x += 1; b.y += 1; b.width -= 2; b.height -= 2;
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);

	    /*
	     * Fill the inner rectangle
	     */
	    GC bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
	    XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2);
	} else {
	    /*
	     * Draw the field element as usual
	     */
	    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
		0, TK_RELIEF_SUNKEN);
	    DrawFieldBorder(tkwin, d, border, borderColor, b);

	    /*
	     * Change the color of the border's outermost pixels
	     */
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);
	}
    } else {
	Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    0, TK_RELIEF_SUNKEN);
	DrawFieldBorder(tkwin, d, border, borderColor, b);
    }
}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
    FieldElementDraw
};

/*------------------------------------------------------------------------
 * Indicators --



 */

/*
 * Indicator image descriptor:
 */
typedef struct {
    int width;				/* unscaled width */
    int height;				/* unscaled height */

    const char *const offDataPtr;
    const char *const onDataPtr;
} IndicatorSpec;



static const char checkbtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <path d='m0 0v15h1v-14h14v-1z' fill='#888888'/>\n\
     <path d='m1 1v13h1v-12h12v-1z' fill='#414141'/>\n\
     <path d='m14 1v13h-13v1h14v-14z' fill='#d9d9d9'/>\n\
     <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
     <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
    </svg>";

static const char checkbtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <path d='m0 0v15h1v-14h14v-1z' fill='#888888'/>\n\
     <path d='m1 1v13h1v-12h12v-1z' fill='#414141'/>\n\
     <path d='m14 1v13h-13v1h14v-14z' fill='#d9d9d9'/>\n\

     <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
     <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
     <path d='m4.5 8 3 3 4-6' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/>\n\
    </svg>";

static const IndicatorSpec checkbutton_spec = {




    16, 16,
    checkbtnOffData,
    checkbtnOnData
};

















static const char radiobtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <defs>\n\
      <linearGradient id='linearGradientOuter' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#888888' offset='0'/>\n\
       <stop stop-color='#eeeeee' offset='1'/>\n\
      </linearGradient>\n\

      <linearGradient id='linearGradientInner' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#414141' offset='0'/>\n\
       <stop stop-color='#d9d9d9' offset='1'/>\n\
      </linearGradient>\n\
     </defs>\n\
     <circle cx='8' cy='8' r='8' fill='url(#linearGradientOuter)'/>\n\
     <circle cx='8' cy='8' r='7' fill='url(#linearGradientInner)'/>\n\
     <circle cx='8' cy='8' r='6' fill='#ffffff'/>\n\
    </svg>";

static const char radiobtnOnData[] = "\






    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <defs>\n\
      <linearGradient id='linearGradientOuter' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\






       <stop stop-color='#888888' offset='0'/>\n\
       <stop stop-color='#eeeeee' offset='1'/>\n\
      </linearGradient>\n\
      <linearGradient id='linearGradientInner' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#414141' offset='0'/>\n\
       <stop stop-color='#d9d9d9' offset='1'/>\n\
      </linearGradient>\n\





     </defs>\n\
     <circle cx='8' cy='8' r='8' fill='url(#linearGradientOuter)'/>\n\
     <circle cx='8' cy='8' r='7' fill='url(#linearGradientInner)'/>\n\
     <circle cx='8' cy='8' r='6' fill='#ffffff'/>\n\
     <circle cx='8' cy='8' r='3' fill='#000000'/>\n\
    </svg>";


static const IndicatorSpec radiobutton_spec = {
    16, 16,
    radiobtnOffData,
    radiobtnOnData
};

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *foregroundObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *lightColorObj;
488
489
490
491
492
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
508
509


















510
511
512
513
514
515
516
517
518
519
520



521





522
523


524

525


526

527
528
529
530



531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547


548

549

550

551
552
553
554
555
556



557

558
559
560
561
562

563
564

565
566
567
568
569
570
571
572
573




574
575
576
577
578

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601



602
603
604
605
606
607
608
609
610
611
612

613
614
615
616
617
618






619
620

621
622

623



624
625
626
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661

662
663
664
665
666
667
668
669
670


671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691

692
693
694


695
696




697
698
699
700
701
702




703
704

705
706
707

708
709
710

711
712




713
714
715
716
717
718
719
720
721

722




723





















724
725
726
727
728
729
730
731
732
733
734















































































735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767

768


769
770
771
772
773

774
775






776
777
778
779
780
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
	    offsetof(IndicatorElement,lightColorObj), "#DDDDDD" },
    { "-shadecolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,shadeColorObj), "#888888" },
    { "-bordercolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,borderColorObj), "black" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(IndicatorElement,marginObj), "0 2 4 2" },
	    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    IndicatorSpec *spec = (IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    (void)paddingPtr;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    *widthPtr = spec->width + Ttk_PaddingWidth(margins);
    *heightPtr = spec->height + Ttk_PaddingHeight(margins);


















}

static void IndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    IndicatorSpec *spec = (IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Display *display = Tk_Display(tkwin);
    Ttk_Padding padding;
    XColor *fgColor, *frameColor, *shadeColor, *indicatorColor, *borderColor;









    int index, ix, iy;
    XGCValues gcValues;


    GC copyGC;

    unsigned long imgColors[8];


    XImage *img = NULL;


    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);




    if (   b.x < 0
	|| b.y < 0
	|| Tk_Width(tkwin) < b.x + spec->width
	|| Tk_Height(tkwin) < b.y + spec->height)
    {
	/* Oops!  not enough room to display the image.
	 * Don't draw anything.
	 */
	return;
    }

    /*
     * Fill in imgColors palette:
     *
     * (SHOULD: take light and shade colors from the border object,
     * but Tk doesn't provide easy access to these in the public API.)
     */


    fgColor = Tk_GetColorFromObj(tkwin, indicator->foregroundObj);

    frameColor = Tk_GetColorFromObj(tkwin, indicator->backgroundObj);

    shadeColor = Tk_GetColorFromObj(tkwin, indicator->shadeColorObj);

    indicatorColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    borderColor = Tk_GetColorFromObj(tkwin, indicator->borderColorObj);

    imgColors[0 /*A*/] = shadeColor->pixel;
    imgColors[1 /*B*/] = indicatorColor->pixel;
    imgColors[2 /*C*/] = frameColor->pixel;



    imgColors[3 /*D*/] = indicatorColor->pixel;

    imgColors[4 /*E*/] = borderColor->pixel;
    imgColors[5 /*F*/] = frameColor->pixel;
    imgColors[6 /*G*/] = fgColor->pixel;
    imgColors[7 /*H*/] = fgColor->pixel;


    /*
     * Create a scratch buffer to store the image:

     */

#if defined(IGNORES_VISUAL)

    /*
     * Platforms which ignore the VisualInfo can use XCreateImage to get the
     * scratch image.  This is essential on macOS, where it is not safe to call
     * XGetImage in a display procedure.
     */





    img = XCreateImage(display, NULL, 32, ZPixmap, 0, NULL,
		       (unsigned int)spec->width, (unsigned int)spec->height,
		       0, 0);
#else


    /*
     * This trick allows creating the scratch XImage without having to
     * construct a VisualInfo.
     */

    img = XGetImage(display, d, 0, 0,
		    (unsigned int)spec->width, (unsigned int)spec->height,
		    AllPlanes, ZPixmap);
#endif

    if (img == NULL) {
        return;
    }

#if defined(IGNORES_VISUAL)

    img->data = (char *)ckalloc(img->bytes_per_line * img->height);
    if (img->data == NULL) {
        XDestroyImage(img);
	return;
    }




#endif

    /*
     * Create the image, painting it into the XImage one pixel at a time.
     */

    index = Ttk_StateTableLookup(spec->map, state);
    for (iy=0 ; iy<spec->height ; iy++) {
	for (ix=0 ; ix<spec->width ; ix++) {
	    XPutPixel(img, ix, iy,
		imgColors[spec->pixels[iy][index*spec->width+ix] - 'A'] );

	}
    }

    /*
     * Copy the image onto our target drawable surface.
     */







    memset(&gcValues, 0, sizeof(gcValues));

    copyGC = Tk_GetGC(tkwin, 0, &gcValues);
    TkPutImage(NULL, 0, display, d, copyGC, img, 0, 0, b.x, b.y,

               spec->width, spec->height);




    /*
     * Tidy up.
     */


    Tk_FreeGC(display, copyGC);

    /*
     * Protect against the possibility that some future platform might
     * not use the Tk memory manager in its implementation of XDestroyImage,
     * even though that would be an extremely strange thing to do.
     */

#if defined(IGNORES_VISUAL)
    ckfree(img->data);
    img->data = NULL;
#endif

    XDestroyImage(img);
}

static const Ttk_ElementSpec IndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    IndicatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Arrow element(s).
 *
 * 	Draws a solid triangle, inside a box.
 * 	clientData is an enum ArrowDirection pointer.
 */

typedef struct {
    Tcl_Obj *sizeObj;

    Tcl_Obj *borderObj;
    Tcl_Obj *borderColorObj;	/* Extra color for borders */
    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;		/* Arrow color */
} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) },


    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,borderColorObj), "black" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj),"raised"},
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj),"black"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * Note asymmetric padding:
 * top/left padding is 1 less than bottom/right,
 * since in this theme 2-pixel borders are asymmetric.
 */
static const Ttk_Padding ArrowPadding = { 3,3,4,4 };

static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);


    int width = SCROLLBAR_WIDTH;
    (void)paddingPtr;





    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &width);
    width -= Ttk_PaddingWidth(ArrowPadding);
    TtkArrowSize(width/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(ArrowPadding);
    *heightPtr += Ttk_PaddingHeight(ArrowPadding);




}


static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;

    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, arrow->borderColorObj);




    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    int relief = TK_RELIEF_RAISED;
    int borderWidth = 2;
    (void)state;

    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);

    Tk_Fill3DRectangle(
	tkwin, d, border, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT);

    DrawBorder(tkwin,d,border,borderColor,b,borderWidth,relief);


























    TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
	Ttk_PadBox(b, ArrowPadding), direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};
















































































/*----------------------------------------------------------------------
 * +++ Menubutton indicator:
 * 	Draw an arrow in the direction where the menu will be posted.
 */

#define MENUBUTTON_ARROW_SIZE 5

typedef struct {
    Tcl_Obj *directionObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
} MenubuttonArrowElement;

static const char *const directionStrings[] = {	/* See also: button.c */
    "above", "below", "left", "right", "flush", NULL
};
enum { POST_ABOVE, POST_BELOW, POST_LEFT, POST_RIGHT, POST_FLUSH };

static const Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = {
    { "-direction", TK_OPTION_STRING,
	offsetof(MenubuttonArrowElement,directionObj), "below" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(MenubuttonArrowElement,colorObj), "black"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 };

static void MenubuttonArrowElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    MenubuttonArrowElement *arrow = (MenubuttonArrowElement *)elementRecord;
    int size = MENUBUTTON_ARROW_SIZE;
    (void)dummy;
    (void)paddingPtr;


    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);






    *widthPtr = *heightPtr = 2 * size + 1;
    *widthPtr += Ttk_PaddingWidth(MenubuttonArrowPadding);
    *heightPtr += Ttk_PaddingHeight(MenubuttonArrowPadding);
}

static void MenubuttonArrowElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    MenubuttonArrowElement *arrow = (MenubuttonArrowElement *)elementRecord;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);
    int size = MENUBUTTON_ARROW_SIZE;
    int postDirection = POST_BELOW;
    ArrowDirection arrowDirection = ARROW_DOWN;
    int width = 0, height = 0;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    Tcl_GetIndexFromObjStruct(NULL, arrow->directionObj, directionStrings,
	   sizeof(char *), ""/*message*/, 0/*flags*/, &postDirection);

    /* ... this might not be such a great idea ... */
    switch (postDirection) {
	case POST_ABOVE:	arrowDirection = ARROW_UP; break;
	case POST_BELOW:	arrowDirection = ARROW_DOWN; break;
	case POST_LEFT:		arrowDirection = ARROW_LEFT; break;
	case POST_RIGHT:	arrowDirection = ARROW_RIGHT; break;
	case POST_FLUSH:	arrowDirection = ARROW_DOWN; break;
    }

    TtkArrowSize(size, arrowDirection, &width, &height);






    b = Ttk_PadBox(b, MenubuttonArrowPadding);
    b = Ttk_AnchorBox(b, width, height, TK_ANCHOR_CENTER);
    TtkFillArrow(Tk_Display(tkwin), d, gc, b, arrowDirection);
}

static const Ttk_ElementSpec MenubuttonArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(MenubuttonArrowElement),
    MenubuttonArrowElementOptions,
    MenubuttonArrowElementSize,
    MenubuttonArrowElementDraw
};

/*----------------------------------------------------------------------
 * +++ Trough element
 *
 * Used in scrollbars and the scale.
 *
 * The -groovewidth option can be used to set the size of the short axis
 * for the drawn area. This will not affect the geometry, but can be used
 * to draw a thin centered trough inside the packet alloted. This is used
 * to show a win32-style scale widget. Use -1 or a large number to use the
 * full area (default).
 *
 */

typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *grooveWidthObj;
    Tcl_Obj *orientObj;
} TroughElement;

static const Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(TroughElement, orientObj), "horizontal" },
    { "-troughborderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), "1" },
    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
    { "-groovewidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,grooveWidthObj), "-1" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    int borderWidth = 2, grooveWidth = 0;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->grooveWidthObj, &grooveWidth);

    if (grooveWidth <= 0) {
	*paddingPtr = Ttk_UniformPadding((short)borderWidth);
    }
}

static void TroughElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 2, relief = TK_RELIEF_SUNKEN, groove = -1;
    Ttk_Orient orient;
    (void)dummy;
    (void)state;

    border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
    TtkGetOrientFromObj(NULL, troughPtr->orientObj, &orient);
    Tk_GetReliefFromObj(NULL, troughPtr->reliefObj, &relief);
    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->grooveWidthObj, &groove);

    if (groove != -1 && groove < b.height && groove < b.width) {
	if (orient == TTK_ORIENT_HORIZONTAL) {
	    b.y = b.y + b.height/2 - groove/2;
	    b.height = groove;
	} else {
	    b.x = b.x + b.width/2 - groove/2;
	    b.width = groove;
	}
    }

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);
}

static const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TroughElement),
    TroughElementOptions,
    TroughElementSize,
    TroughElementDraw
};

/*
 *----------------------------------------------------------------------
 * +++ Thumb element.
 */

typedef struct {
    Tcl_Obj *sizeObj;







|




|
>

|


|


|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|

<

<

|
>
>
>

>
>
>
>
>
|
|
>
>
|
>
|
>
>
|
>




>
>
>


|
|

|






|
<
|
<

>
>
|
>
|
>
|
>
|
|

|
|
<
>
>
>
|
>
|
<
|
<
|
>
|
<
>
|
|
<

|
|
|
<
|
>
>
>
>
|
<
<
<
|
>

|
<
|
|
<
<
<
<
<
<
<
<
<

|
|
|
|
|
|
|
|
>
>
>
|

<
<
<
|
|
|
|
|
|
>

|
<
|
|
|
>
>
>
>
>
>
|
<
>
|
<
>
|
>
>
>
|
<
<
<
>
|
<


|
<
<

|
<
<
<
<
<
|



















>



<





>
>





|
<
<












|
>


|
>
>
|
|
>
>
>
>

|
|
|
|
|
>
>
>
>
|
|
>


|
>

<

>


>
>
>
>

|
<
<



|
|
>
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















|

|






|







>
|
>
|
>
>



<
|
>


>
>
>
>
>
>

|
|



>
|
>
|
>
>








|
|















>
>
>
>
>
>
|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615

616
617
618
619
620
621
622
623
624
625
626
627
628
629

630
631
632
633
634
635

636

637
638
639

640
641
642

643
644
645
646

647
648
649
650
651
652



653
654
655
656

657
658









659
660
661
662
663
664
665
666
667
668
669
670
671
672



673
674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
689
690
691

692
693

694
695
696
697
698
699



700
701

702
703
704


705
706





707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738
739
740
741
742
743


744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	    offsetof(IndicatorElement,lightColorObj), "#DDDDDD" },
    { "-shadecolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,shadeColorObj), "#888888" },
    { "-bordercolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,borderColorObj), "black" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(IndicatorElement,marginObj), "0 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    double scalingLevel = TkScalingLevel(tkwin);

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    *widthPtr = spec->width * scalingLevel + Ttk_PaddingWidth(margins);
    *heightPtr = spec->height * scalingLevel + Ttk_PaddingHeight(margins);
}

static void ColorToStr(
    const XColor *colorPtr, char *colorStr)	/* in the format "RRGGBB" */
{
    snprintf(colorStr, 7, "%02x%02x%02x",
	     colorPtr->red >> 8, colorPtr->green >> 8, colorPtr->blue >> 8);
}

static void ImageChanged(		/* to be passed to Tk_GetImage() */
    TCL_UNUSED(void *),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
}

static void IndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{

    IndicatorElement *indicator = (IndicatorElement *)elementRecord;

    Ttk_Padding padding;
    const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
    double scalingLevel = TkScalingLevel(tkwin);
    int width = spec->width * scalingLevel;
    int height = spec->height * scalingLevel;

    char bgColorStr[7], fgColorStr[7], indicatorColorStr[7],
	 shadeColorStr[7], borderColorStr[7];
    unsigned int selected = (state & TTK_STATE_SELECTED);
    Tcl_Interp *interp = Tk_Interp(tkwin);
    char imgName[70];
    Tk_Image img;

    const char *svgDataPtr;
    size_t svgDataLen;
    char *svgDataCopy;
    char *shadeColorPtr, *highlightColorPtr, *borderColorPtr, *bgColorPtr,
	 *indicatorColorPtr, *fgColorPtr;
    const char *cmdFmt;
    size_t scriptSize;
    char *script;
    int code;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);

    /*
     * Sanity check
     */
    if (   b.x < 0
	|| b.y < 0
	|| Tk_Width(tkwin) < b.x + width
	|| Tk_Height(tkwin) < b.y + height)
    {
	/* Oops!  Not enough room to display the image.
	 * Don't draw anything.
	 */
	return;
    }

    /*
     * Construct the color strings bgColorStr, fgColorStr,

     * indicatorColorStr, shadeColorStr, and borderColorStr

     */
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->backgroundObj),
	       bgColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->foregroundObj),
	       fgColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->colorObj),
	       indicatorColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->shadeColorObj),
	       shadeColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->borderColorObj),
	       borderColorStr);

    /*
     * Check whether there is an SVG image of this size for the indicator's

     * type (0 = checkbtn, 1 = radiobtn) and these color strings
     */
    snprintf(imgName, sizeof(imgName),
	     "::tk::icons::indicator_alt%d_%d_%s_%s_%s_%s_%s",
	     width, spec->offDataPtr == radiobtnOffData,
	     shadeColorStr, indicatorColorStr, borderColorStr, bgColorStr,

	     selected ? fgColorStr : "XXXXXX");

    img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    if (img == NULL) {
	/*

	 * Determine the SVG data to use for the photo image
	 */
	svgDataPtr = (selected ? spec->onDataPtr : spec->offDataPtr);


	/*
	 * Copy the string pointed to by svgDataPtr to
	 * a newly allocated memory area svgDataCopy

	 */
	svgDataLen = strlen(svgDataPtr);
	svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
	if (svgDataCopy == NULL) {
	    return;
	}



	memcpy(svgDataCopy, svgDataPtr, svgDataLen);
	svgDataCopy[svgDataLen] = '\0';

	/*

	 * Update the colors within svgDataCopy
	 */










	shadeColorPtr =	    strstr(svgDataCopy, "888888");
	highlightColorPtr = strstr(svgDataCopy, "eeeeee");
	borderColorPtr =    strstr(svgDataCopy, "414141");
	bgColorPtr =	    strstr(svgDataCopy, "d9d9d9");
	indicatorColorPtr = strstr(svgDataCopy, "ffffff");
	fgColorPtr =	    strstr(svgDataCopy, "000000");

	assert(shadeColorPtr);
	assert(highlightColorPtr);
	assert(borderColorPtr);
	assert(bgColorPtr);
	assert(indicatorColorPtr);




	memcpy(shadeColorPtr, shadeColorStr, 6);
	memcpy(highlightColorPtr, indicatorColorStr, 6);
	memcpy(borderColorPtr, borderColorStr, 6);
	memcpy(bgColorPtr, bgColorStr, 6);
	memcpy(indicatorColorPtr, indicatorColorStr, 6);
	if (fgColorPtr != NULL) {
	    memcpy(fgColorPtr, fgColorStr, 6);
	}


	/*
	 * Create an SVG photo image from svgDataCopy
	 */
	cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
	scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
	script = (char *)attemptckalloc(scriptSize);
	if (script == NULL) {
	    ckfree(svgDataCopy);
	    return;
	}

	snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
	ckfree(svgDataCopy);

	code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
	ckfree(script);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(interp, code);
	    return;
	}



	img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    }


    /*
     * Display the image


     */
    Tk_RedrawImage(img, 0, 0, width, height, d, b.x, b.y);





    Tk_FreeImage(img);
}

static const Ttk_ElementSpec IndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    IndicatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Arrow element(s).
 *
 * 	Draws a solid triangle, inside a box.
 * 	clientData is an enum ArrowDirection pointer.
 */

typedef struct {
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;		/* Arrow color */
    Tcl_Obj *borderObj;
    Tcl_Obj *borderColorObj;	/* Extra color for borders */
    Tcl_Obj *reliefObj;

} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) },
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj), "black"},
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,borderColorObj), "black" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj), "raised"},


    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

/*
 * Note asymmetric padding:
 * top/left padding is 1 less than bottom/right,
 * since in this theme 2-pixel borders are asymmetric.
 */
static const Ttk_Padding ArrowPadding = { 3,3,4,4 };

static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding;
    int size = SCROLLBAR_WIDTH;

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.right = padding.left + 1;
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.bottom = padding.top + 1;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
    if (*widthPtr < *heightPtr) {
	*widthPtr = *heightPtr;
    } else {
	*heightPtr = *widthPtr;
    }
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{

    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, arrow->borderColorObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;
    Ttk_Padding padding;
    double scalingLevel = TkScalingLevel(tkwin);
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);



    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    0, TK_RELIEF_FLAT);
    DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.right = padding.left + 1;
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.bottom = padding.top + 1;

    b = Ttk_PadBox(b, padding);

    switch (direction) {
	case ARROW_UP:
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_LEFT:
	case ARROW_RIGHT:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);

}

static const Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*
 * Modified arrow element for comboboxes and spinboxes:
 * 	The width and height are different, and the left edge is drawn in the
 *	same color as the inner part of the right one.
 */

static void BoxArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding;
    int size = 14;

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.right = round(ArrowPadding.right * scalingLevel);
    padding.bottom = round(ArrowPadding.bottom * scalingLevel);

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
}

static void BoxArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, arrow->borderColorObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;
    Display *disp = Tk_Display(tkwin);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    int w = WIN32_XDRAWLINE_HACK;
    Ttk_Padding padding;
    double scalingLevel = TkScalingLevel(tkwin);
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC arrowGC = Tk_GCForColor(arrowColor, d);

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    0, TK_RELIEF_FLAT);
    DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);

    XDrawLine(disp, d, darkGC, b.x, b.y+1, b.x, b.y+b.height-2+w);

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.right = round(ArrowPadding.right * scalingLevel);
    padding.bottom = round(ArrowPadding.bottom * scalingLevel);

    b = Ttk_PadBox(b, padding);

    TtkArrowSize(b.width/2, direction, &cx, &cy);
    if ((b.height - cy) % 2 == 1) {
	++cy;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(disp, d, arrowGC, b, direction);
}

static const Ttk_ElementSpec BoxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    BoxArrowElementSize,
    BoxArrowElementDraw
};

/*----------------------------------------------------------------------
 * +++ Menubutton indicator:
 * 	Draw an arrow in the direction where the menu will be posted.
 */

#define MENUBUTTON_ARROW_SIZE 5

typedef struct {
    Tcl_Obj *directionObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
} MenubuttonArrowElement;

static const char *const directionStrings[] = {	/* See also: button.c */
    "above", "below", "flush", "left", "right", NULL
};
enum { POST_ABOVE, POST_BELOW, POST_FLUSH, POST_LEFT, POST_RIGHT };

static const Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = {
    { "-direction", TK_OPTION_STRING,
	offsetof(MenubuttonArrowElement,directionObj), "below" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(MenubuttonArrowElement,colorObj), "black"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 };

static void MenubuttonArrowElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    MenubuttonArrowElement *arrow = (MenubuttonArrowElement *)elementRecord;
    int size = MENUBUTTON_ARROW_SIZE;

    Ttk_Padding padding;
    double scalingLevel = TkScalingLevel(tkwin);

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);

    padding.left = round(MenubuttonArrowPadding.left * scalingLevel);
    padding.top = round(MenubuttonArrowPadding.top * scalingLevel);
    padding.right = round(MenubuttonArrowPadding.right * scalingLevel);
    padding.bottom = round(MenubuttonArrowPadding.bottom * scalingLevel);

    *widthPtr = *heightPtr = 2 * size + 1;
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
}

static void MenubuttonArrowElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    MenubuttonArrowElement *arrow = (MenubuttonArrowElement *)elementRecord;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);
    int size = MENUBUTTON_ARROW_SIZE;
    int postDirection = POST_BELOW;
    ArrowDirection arrowDirection = ARROW_DOWN;
    int width = 0, height = 0;
    Ttk_Padding padding;
    double scalingLevel = TkScalingLevel(tkwin);

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    Tcl_GetIndexFromObjStruct(NULL, arrow->directionObj, directionStrings,
	   sizeof(char *), ""/*message*/, 0/*flags*/, &postDirection);

    /* ... this might not be such a great idea ... */
    switch (postDirection) {
	case POST_ABOVE:	arrowDirection = ARROW_UP; break;
	case POST_BELOW:	arrowDirection = ARROW_DOWN; break;
	case POST_LEFT:		arrowDirection = ARROW_LEFT; break;
	case POST_RIGHT:	arrowDirection = ARROW_RIGHT; break;
	case POST_FLUSH:	arrowDirection = ARROW_DOWN; break;
    }

    TtkArrowSize(size, arrowDirection, &width, &height);

    padding.left = round(MenubuttonArrowPadding.left * scalingLevel);
    padding.top = round(MenubuttonArrowPadding.top * scalingLevel);
    padding.right = round(MenubuttonArrowPadding.right * scalingLevel);
    padding.bottom = round(MenubuttonArrowPadding.bottom * scalingLevel);

    b = Ttk_PadBox(b, padding);
    b = Ttk_AnchorBox(b, width, height, TK_ANCHOR_CENTER);
    TtkFillArrow(Tk_Display(tkwin), d, gc, b, arrowDirection);
}

static const Ttk_ElementSpec MenubuttonArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(MenubuttonArrowElement),
    MenubuttonArrowElementOptions,
    MenubuttonArrowElementSize,
    MenubuttonArrowElementDraw
};





























































































/*
 *----------------------------------------------------------------------
 * +++ Thumb element.
 */

typedef struct {
    Tcl_Obj *sizeObj;
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
	"black" },
    { "-relief", TK_OPTION_RELIEF, offsetof(ThumbElement,reliefObj),"raised" },
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int size;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->sizeObj, &size);
    TtkGetOrientFromObj(NULL, thumb->orientObj, &orient);

    if (orient == TTK_ORIENT_VERTICAL) {
	*widthPtr = size;
	*heightPtr = MIN_THUMB_SIZE;
    } else {
	*widthPtr = MIN_THUMB_SIZE;
	*heightPtr = size;
    }
}

static void ThumbElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, thumb->borderColorObj);
    int relief = TK_RELIEF_RAISED;
    int borderWidth = 2;
    (void)dummy;
    (void)state;

    /*
     * Don't draw the thumb if we are disabled.
     * This makes it behave like Windows ... if that's what we want.
    if (state & TTK_STATE_DISABLED)
	return;
     */







>
|
>
|
>
>




<
<


|











>
|
>
|
>
>






<
<







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
	"black" },
    { "-relief", TK_OPTION_RELIEF, offsetof(ThumbElement,reliefObj),"raised" },
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int size;



    Tk_GetPixelsFromObj(NULL, tkwin, thumb->sizeObj, &size);
    Ttk_GetOrientFromObj(NULL, thumb->orientObj, &orient);

    if (orient == TTK_ORIENT_VERTICAL) {
	*widthPtr = size;
	*heightPtr = MIN_THUMB_SIZE;
    } else {
	*widthPtr = MIN_THUMB_SIZE;
	*heightPtr = size;
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, thumb->borderColorObj);
    int relief = TK_RELIEF_RAISED;
    int borderWidth = 2;



    /*
     * Don't draw the thumb if we are disabled.
     * This makes it behave like Windows ... if that's what we want.
    if (state & TTK_STATE_DISABLED)
	return;
     */
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
 *
 * The slider element is the thumb in the scale widget. This is drawn
 * as an arrow-type element that can point up, down, left or right.
 *
 */

typedef struct {
    Tcl_Obj *lengthObj;		/* Long axis dimension */
    Tcl_Obj *thicknessObj;	/* Short axis dimension */
    Tcl_Obj *reliefObj;		/* Relief for this object */
    Tcl_Obj *borderObj;		/* Border / background color */
    Tcl_Obj *borderColorObj;	/* Additional border color */
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *orientObj;		/* Orientation of overall slider */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
	"15" },
    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	STRINGIFY(BORDERWIDTH) },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(ThumbElement,borderColorObj),
	"black" },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int length, thickness, borderWidth;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->lengthObj, &length);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);

    switch (orient) {
	case TTK_ORIENT_VERTICAL:
	    *widthPtr = thickness + (borderWidth *2);
	    *heightPtr = *widthPtr/2;
	    break;

	case TTK_ORIENT_HORIZONTAL:
	    *heightPtr = thickness + (borderWidth *2);
	    *widthPtr = *heightPtr/2;
	    break;
    }
}

static void SliderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    SliderElement *slider = (SliderElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, slider->borderColorObj);
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height,
	borderWidth, TK_RELIEF_FLAT);







<









<
<








|







>
|
>
|
>
>



|
<
<

|

<







<








>
|
>
|
>
>





<
<







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
 *
 * The slider element is the thumb in the scale widget. This is drawn
 * as an arrow-type element that can point up, down, left or right.
 *
 */

typedef struct {

    Tcl_Obj *thicknessObj;	/* Short axis dimension */
    Tcl_Obj *reliefObj;		/* Relief for this object */
    Tcl_Obj *borderObj;		/* Border / background color */
    Tcl_Obj *borderColorObj;	/* Additional border color */
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *orientObj;		/* Orientation of overall slider */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {


    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	STRINGIFY(BORDERWIDTH) },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(SliderElement,borderColorObj),
	"black" },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int thickness, borderWidth;



    Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);

    Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);

    switch (orient) {
	case TTK_ORIENT_VERTICAL:
	    *widthPtr = thickness + (borderWidth *2);
	    *heightPtr = *widthPtr/2;
	    break;

	case TTK_ORIENT_HORIZONTAL:
	    *heightPtr = thickness + (borderWidth *2);
	    *widthPtr = *heightPtr/2;
	    break;
    }
}

static void SliderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, slider->borderColorObj);
    int relief = TK_RELIEF_RAISED, borderWidth = 2;



    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height,
	borderWidth, TK_RELIEF_FLAT);
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

#define TTK_STATE_OPEN TTK_STATE_USER1		/* XREF: treeview.c */
#define TTK_STATE_LEAF TTK_STATE_USER2

typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *diameterObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
    { "-diameter", TK_OPTION_PIXELS,
	offsetof(TreeitemIndicator,diameterObj), "9" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    int diameter = 0;
    Ttk_Padding margins;
    (void)dummy;
    (void)paddingPtr;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
    *widthPtr = diameter + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + Ttk_PaddingHeight(margins);
}

static void TreeitemIndicatorDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    XColor *color = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    GC gc = Tk_GCForColor(color, d);
    Ttk_Padding padding = Ttk_UniformPadding(0);
    int w = WIN32_XDRAWLINE_HACK;
    int cx, cy;
    (void)dummy;

    if (state & TTK_STATE_LEAF) {
	/* don't draw anything ... */
	return;
    }

    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);







|





|
|






>
|
>
|
>
>




<
<


|





>
|








<







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

#define TTK_STATE_OPEN TTK_STATE_USER1		/* XREF: treeview.c */
#define TTK_STATE_LEAF TTK_STATE_USER2

typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *sizeObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
    { "-size", TK_OPTION_PIXELS,
	offsetof(TreeitemIndicator,sizeObj), "6.75p" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    int diameter = 0;
    Ttk_Padding margins;



    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &diameter);
    *widthPtr = diameter + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + Ttk_PaddingHeight(margins);
}

static void TreeitemIndicatorDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    XColor *color = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    GC gc = Tk_GCForColor(color, d);
    Ttk_Padding padding = Ttk_UniformPadding(0);
    int w = WIN32_XDRAWLINE_HACK;
    int cx, cy;


    if (state & TTK_STATE_LEAF) {
	/* don't draw anything ... */
	return;
    }

    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
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
    TreeitemIndicatorDraw
};

/*------------------------------------------------------------------------
 * TtkAltTheme_Init --
 * 	Install alternate theme.
 */


MODULE_SCOPE int TtkAltTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_CreateTheme(interp, "alt", NULL);

    if (!theme) {
	return TCL_ERROR;
    }

    Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &IndicatorElementSpec, &checkbutton_spec);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &IndicatorElementSpec, &radiobutton_spec);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenubuttonArrowElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "trough", &TroughElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));


    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));




    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, 0);

    Tcl_PkgProvide(interp, "ttk::theme::alt", TTK_VERSION);

    return TCL_OK;
}

/*EOF*/







>
>











|

|





<





>
>


>
>
>
>








|







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
    TreeitemIndicatorDraw
};

/*------------------------------------------------------------------------
 * TtkAltTheme_Init --
 * 	Install alternate theme.
 */
MODULE_SCOPE int TtkAltTheme_Init(Tcl_Interp *interp);

MODULE_SCOPE int TtkAltTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_CreateTheme(interp, "alt", NULL);

    if (!theme) {
	return TCL_ERROR;
    }

    Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &IndicatorElementSpec, (void *)&checkbutton_spec);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &IndicatorElementSpec, (void *)&radiobutton_spec);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenubuttonArrowElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);


    Ttk_RegisterElement(interp, theme, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
	    &BoxArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
	    &BoxArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "Combobox.downarrow",
	    &BoxArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, NULL);

    Tcl_PkgProvide(interp, "ttk::theme::alt", TTK_VERSION);

    return TCL_OK;
}

/*EOF*/

Changes to generic/ttk/ttkElements.c.

1
2
3
4
5
6
7
8
9
10






11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38

39

40


41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * Copyright (c) 2003, Joe English
 *
 * Default implementation for themed elements.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"







#define DEFAULT_BORDERWIDTH "2"
#define DEFAULT_ARROW_SIZE "15"
#define MIN_THUMB_SIZE 10

/*----------------------------------------------------------------------
 * +++ Null element.  Does nothing; used as a stub.
 * Null element methods, option table and element spec are public,
 * and may be used in other engines.
 */

/* public */ const Ttk_ElementOptionSpec TtkNullElementOptions[] = { { NULL, TK_OPTION_BOOLEAN, 0, NULL } };

/* public */ void
TtkNullElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;
    (void)paddingPtr;

}

/* public */ void
TtkNullElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)d;
    (void)b;
    (void)state;
}

/* public */ Ttk_ElementSpec ttkNullElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,

|






|

>
>
>
>
>
>















<
<
<
|
|
|
|
|
|
>




>
|
>
|
>
>

<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49






50
51
52
53
54
55
56
/*
 * Copyright © 2003 Joe English
 *
 * Default implementation for themed elements.
 *
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"

#if defined(_WIN32)
  #define WIN32_XDRAWLINE_HACK 1
#else
  #define WIN32_XDRAWLINE_HACK 0
#endif

#define DEFAULT_BORDERWIDTH "2"
#define DEFAULT_ARROW_SIZE "15"
#define MIN_THUMB_SIZE 10

/*----------------------------------------------------------------------
 * +++ Null element.  Does nothing; used as a stub.
 * Null element methods, option table and element spec are public,
 * and may be used in other engines.
 */

/* public */ const Ttk_ElementOptionSpec TtkNullElementOptions[] = { { NULL, TK_OPTION_BOOLEAN, 0, NULL } };

/* public */ void
TtkNullElementSize(



    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    TCL_UNUSED(Ttk_Padding *))
{
}

/* public */ void
TtkNullElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(Drawable),
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{






}

/* public */ Ttk_ElementSpec ttkNullElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TtkNullElementSize,
71
72
73
74
75
76
77

78

79


80
81
82
83
84
85
86
87
88
89
90
91
92
93


94
95
96
97
98
99
100
101
102
103
static const Ttk_ElementOptionSpec BackgroundElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	    offsetof(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FillElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    BackgroundElement *bg = (BackgroundElement *)elementRecord;
    Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,bg->backgroundObj);
    (void)dummy;
    (void)state;

    XFillRectangle(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
	b.x, b.y, b.width, b.height);
}

static void BackgroundElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)


{
    (void)b;

    FillElementDraw(
	clientData, elementRecord, tkwin,
	d, Ttk_WinBox(tkwin), state);
}

static const Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,







>
|
>
|
>
>



<
<








|
>
>

<
<







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97
98
99
100


101
102
103
104
105
106
107
static const Ttk_ElementOptionSpec BackgroundElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	    offsetof(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FillElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    BackgroundElement *bg = (BackgroundElement *)elementRecord;
    Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,bg->backgroundObj);



    XFillRectangle(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
	b.x, b.y, b.width, b.height);
}

static void BackgroundElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    Ttk_State state)
{


    FillElementDraw(
	clientData, elementRecord, tkwin,
	d, Ttk_WinBox(tkwin), state);
}

static const Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,
132
133
134
135
136
137
138

139



140
141
142
143
144
145
146
147
148
149
150
151
152
153

154

155


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190
191
192
193
194




195
196
197

198

199



200
201
202
203
204
205
206
207
208




209
210
211
212

213
214
215
216
217





































218

219


220




221


222
223
224

225
226
227
228
229
230
231
	offsetof(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(BorderElement,reliefObj), "flat" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    BorderElement *bd = (BorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    (void)dummy;
    (void)state;

    border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);

    if (border && borderWidth > 0 && relief != TK_RELIEF_FLAT) {
	Tk_Draw3DRectangle(tkwin, d, border,
	    b.x, b.y, b.width, b.height, borderWidth,relief);
    }
}

static const Ttk_ElementSpec BorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(BorderElement),
    BorderElementOptions,
    BorderElementSize,
    BorderElementDraw
};

/*----------------------------------------------------------------------
 * +++ Field element.
 * 	Used for editable fields.
 */
typedef struct {
    Tcl_Obj	*borderObj;
    Tcl_Obj	*borderWidthObj;


} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,borderObj), "white" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(FieldElement,borderWidthObj), "2" },




    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};


static void FieldElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    FieldElement *field = (FieldElement *)elementRecord;
    int borderWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);




    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void FieldElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);





































    int borderWidth = 2;

    (void)dummy;


    (void)state;







    Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
    Tk_Fill3DRectangle(tkwin, d, border,
	    b.x, b.y, b.width, b.height, borderWidth, TK_RELIEF_SUNKEN);

}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,







>
|
>
>
>
|



<
<
<
<






>
|
>
|
>
>




<
<







|


















>
>







>
>
>
>



>

>
|
>
>
>
|


|
<
<
<


>
>
>
>




>
|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
|
>
>
>
>
|
>
>
|
|
|
>







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151




152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
	offsetof(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(BorderElement,reliefObj), "flat" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;





    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    BorderElement *bd = (BorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;



    border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);

    if (border && borderWidth > 0 && relief != TK_RELIEF_FLAT) {
	Tk_Draw3DRectangle(tkwin, d, border,
	    b.x, b.y, b.width, b.height, borderWidth, relief);
    }
}

static const Ttk_ElementSpec BorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(BorderElement),
    BorderElementOptions,
    BorderElementSize,
    BorderElementDraw
};

/*----------------------------------------------------------------------
 * +++ Field element.
 * 	Used for editable fields.
 */
typedef struct {
    Tcl_Obj	*borderObj;
    Tcl_Obj	*borderWidthObj;
    Tcl_Obj	*focusWidthObj;
    Tcl_Obj	*focusColorObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,borderObj), "white" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(FieldElement,borderWidthObj), "2" },
    { "-focuswidth", TK_OPTION_PIXELS,
	offsetof(FieldElement,focusWidthObj), "2" },
    { "-focuscolor", TK_OPTION_COLOR,
	offsetof(FieldElement,focusColorObj), "#4a6984" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};


static void FieldElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    FieldElement *field = (FieldElement *)elementRecord;
    int borderWidth = 2, focusWidth = 2;




    Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, field->focusWidthObj, &focusWidth);
    if (focusWidth > 0 && borderWidth < 2) {
	borderWidth += (focusWidth - borderWidth);
    }
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    int focusWidth = 2;

    Tk_GetPixelsFromObj(NULL, tkwin, field->focusWidthObj, &focusWidth);

    if (focusWidth > 0 && (state & TTK_STATE_FOCUS)) {
	Display *disp = Tk_Display(tkwin);
	XColor *focusColor = Tk_GetColorFromObj(tkwin, field->focusColorObj);
	GC focusGC = Tk_GCForColor(focusColor, d);

	if (focusWidth > 1) {
	    int x1 = b.x, x2 = b.x + b.width - 1;
	    int y1 = b.y, y2 = b.y + b.height - 1;
	    int w = WIN32_XDRAWLINE_HACK;

	    /*
	     * Draw the outer rounded rectangle
	     */
	    XDrawLine(disp, d, focusGC, x1+1, y1, x2-1+w, y1);	/* N */
	    XDrawLine(disp, d, focusGC, x1+1, y2, x2-1+w, y2);	/* S */
	    XDrawLine(disp, d, focusGC, x1, y1+1, x1, y2-1+w);	/* W */
	    XDrawLine(disp, d, focusGC, x2, y1+1, x2, y2-1+w);	/* E */

	    /*
	     * Draw the inner rectangle
	     */
	    b.x += 1; b.y += 1; b.width -= 2; b.height -= 2;
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);

	    /*
	     * Fill the inner rectangle
	     */
	    GC bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
	    XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2);
	} else {
	    /*
	     * Draw the field element as usual
	     */
	    int borderWidth = 2;
	    Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj,
		    &borderWidth);
	    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
		    borderWidth, TK_RELIEF_SUNKEN);

	    /*
	     * Change the color of the border's outermost pixels
	     */
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);
	}
    } else {
	int borderWidth = 2;
	Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
	Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
		borderWidth, TK_RELIEF_SUNKEN);
    }
}

static const Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    FieldElementSize,
256
257
258
259
260
261
262

263



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
	offsetof(PaddingElement,reliefObj), "flat" },
    { "-shiftrelief", TK_OPTION_INT,
	offsetof(PaddingElement,shiftreliefObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PaddingElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    PaddingElement *padding = (PaddingElement *)elementRecord;
    int shiftRelief = 0;
    int relief = TK_RELIEF_FLAT;
    Ttk_Padding pad;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetReliefFromObj(NULL, padding->reliefObj, &relief);
    Tcl_GetIntFromObj(NULL, padding->shiftreliefObj, &shiftRelief);
    Ttk_GetPaddingFromObj(NULL,tkwin,padding->paddingObj,&pad);
    *paddingPtr = Ttk_RelievePadding(pad, relief, shiftRelief);
}








>
|
>
>
>
|





<
<
<







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339



340
341
342
343
344
345
346
	offsetof(PaddingElement,reliefObj), "flat" },
    { "-shiftrelief", TK_OPTION_INT,
	offsetof(PaddingElement,shiftreliefObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PaddingElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    PaddingElement *padding = (PaddingElement *)elementRecord;
    int shiftRelief = 0;
    int relief = TK_RELIEF_FLAT;
    Ttk_Padding pad;




    Tk_GetReliefFromObj(NULL, padding->reliefObj, &relief);
    Tcl_GetIntFromObj(NULL, padding->shiftreliefObj, &shiftRelief);
    Ttk_GetPaddingFromObj(NULL,tkwin,padding->paddingObj,&pad);
    *paddingPtr = Ttk_RelievePadding(pad, relief, shiftRelief);
}

323
324
325
326
327
328
329

330



331
332
333
334
335
336
337
338
339
340
341
342
343
344

345

346


347
348
349
350
351
352
353
354
355
356
357
	offsetof(FocusElement,focusColorObj), "black" },
    { "-focusthickness",TK_OPTION_PIXELS,
	offsetof(FocusElement,focusThicknessObj), "1" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FocusElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, focus->focusThicknessObj, &focusThickness);
    *paddingPtr = Ttk_UniformPadding((short)focusThickness);
}

static void FocusElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;
    (void)dummy;

    if (state & TTK_STATE_FOCUS) {
	Tcl_GetIntFromObj(NULL,focus->focusThicknessObj,&focusThickness);
	DrawFocusRing(tkwin, d, focus->focusColorObj, b);
    }
}








>
|
>
>
>
|



<
<
<
<






>
|
>
|
>
>



<







390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405




406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
	offsetof(FocusElement,focusColorObj), "black" },
    { "-focusthickness",TK_OPTION_PIXELS,
	offsetof(FocusElement,focusThicknessObj), "1" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FocusElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;





    Tcl_GetIntFromObj(NULL, focus->focusThicknessObj, &focusThickness);
    *paddingPtr = Ttk_UniformPadding((short)focusThickness);
}

static void FocusElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;


    if (state & TTK_STATE_FOCUS) {
	Tcl_GetIntFromObj(NULL,focus->focusThicknessObj,&focusThickness);
	DrawFocusRing(tkwin, d, focus->focusColorObj, b);
    }
}

380
381
382
383
384
385
386

387

388
389
390
391
392
393
394
395
396
397
398

399

400


401
402
403
404
405
406
407
408
409
410
411
412
413

414

415


416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	offsetof(SeparatorElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SeparatorElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;

    *widthPtr = *heightPtr = 2;
}

static void HorizontalSeparatorElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
    GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    (void)dummy;
    (void)state;

    XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x + b.width, b.y);
    XDrawLine(Tk_Display(tkwin), d, lightGC, b.x, b.y+1, b.x + b.width, b.y+1);
}

static void VerticalSeparatorElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
    GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    (void)dummy;
    (void)state;

    XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x, b.y + b.height);
    XDrawLine(Tk_Display(tkwin), d, lightGC, b.x+1, b.y, b.x+1, b.y+b.height);
}

static void GeneralSeparatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Ttk_Orient orient;

    TtkGetOrientFromObj(NULL, separator->orientObj, &orient);
    switch (orient) {
	case TTK_ORIENT_HORIZONTAL:
	    HorizontalSeparatorElementDraw(
		clientData, elementRecord, tkwin, d, b, state);
	    break;
	case TTK_ORIENT_VERTICAL:
	    VerticalSeparatorElementDraw(







>
|
>
|
<
<
<
|
|
|




>
|
>
|
>
>





<
<






>
|
>
|
>
>





<
<







|




|







450
451
452
453
454
455
456
457
458
459
460



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478


479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495


496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
	offsetof(SeparatorElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SeparatorElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    int *widthPtr,



    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    *widthPtr = *heightPtr = 2;
}

static void HorizontalSeparatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
    GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);



    XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x + b.width, b.y);
    XDrawLine(Tk_Display(tkwin), d, lightGC, b.x, b.y+1, b.x + b.width, b.y+1);
}

static void VerticalSeparatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
    GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);



    XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x, b.y + b.height);
    XDrawLine(Tk_Display(tkwin), d, lightGC, b.x+1, b.y, b.x+1, b.y+b.height);
}

static void GeneralSeparatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Ttk_Orient orient;

    Ttk_GetOrientFromObj(NULL, separator->orientObj, &orient);
    switch (orient) {
	case TTK_ORIENT_HORIZONTAL:
	    HorizontalSeparatorElementDraw(
		clientData, elementRecord, tkwin, d, b, state);
	    break;
	case TTK_ORIENT_VERTICAL:
	    VerticalSeparatorElementDraw(
471
472
473
474
475
476
477

478
479
480
481
482


483
484
485
486

487

488


489
490
491
492
493
494
495

496
497
498
499

500

501


502
503

504
505
506
507
508
509
510
511



512
513

514
515

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539


540
541
542
543
544
545
546
547
548



549
550
551
552
553
554
555
556
557
558


559
560
561
562




563



564
565




566
567
568
569
570
571
572
573




574
575
576
577
578
579
580




581
582





583
584
585
586

587

588
589

590
591
592
593
594
595
596
597

598
599
600


601



602
603
604



605
606
607
608
609



610
611
612
613
614
615
616

617
618
619
620
621
622

623
624
625
626
627
628








629


630
631
632
633
634
635
636
637
638
639
640



641
642
643
644
645
646
647
648





649










650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665




666
667
668
669
670
671
672
673
674



675
676
677
678
679
680
681
682
683
684
685

686

687

688
689









690


691
692



693
694
695
696
697
698
699
700
701
702



703
704
705
706
707
708
709

710
711

712
713
714
715
716

717


718


719
720
721
722

723
724
725
726
727

728
729
730
731
732
733
734









735
736
737
738
739
740
741
742
743
744


745
746
747
748
749

750



751

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769


770
771
772
773
774
775
776
777
778
779
780
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

/*----------------------------------------------------------------------
 * +++ Sizegrip: lower-right corner grip handle for resizing window.
 */

typedef struct {
    Tcl_Obj	*backgroundObj;

} SizegripElement;

static const Ttk_ElementOptionSpec SizegripOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },


    {0,TK_OPTION_BOOLEAN,0,0}
};

static void SizegripSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    int gripCount = 3, gripSpace = 2, gripThickness = 3;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;


    *widthPtr = *heightPtr = gripCount * (gripSpace + gripThickness);
}

static void SizegripDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    SizegripElement *grip = (SizegripElement *)elementRecord;

    int gripCount = 3, gripSpace = 2;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, grip->backgroundObj);
    GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    int x1 = b.x + b.width-1, y1 = b.y + b.height-1, x2 = x1, y2 = y1;
    (void)dummy;
    (void)state;




    while (gripCount--) {
	x1 -= gripSpace; y2 -= gripSpace;

	XDrawLine(Tk_Display(tkwin), d, darkGC,  x1,y1, x2,y2); --x1; --y2;
	XDrawLine(Tk_Display(tkwin), d, darkGC,  x1,y1, x2,y2); --x1; --y2;

	XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2); --x1; --y2;
    }
}

static const Ttk_ElementSpec SizegripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SizegripElement),
    SizegripOptions,
    SizegripSize,
    SizegripDraw
};

/*----------------------------------------------------------------------
 * +++ Indicator element.
 *
 * Draws the on/off indicator for checkbuttons and radiobuttons.
 *
 * Draws a 3-D square (or diamond), raised if off, sunken if on.
 *

 * This is actually a regression from Tk 8.5 back to the ugly old Motif
 * style; use "altTheme" for the newer, nicer version.
 */

typedef struct {


    Tcl_Obj *backgroundObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *diameterObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *borderWidthObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {



    { "-background", TK_OPTION_BORDER,
	offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorcolor", TK_OPTION_BORDER,
	offsetof(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(IndicatorElement,reliefObj), "raised" },
    { "-indicatordiameter", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,diameterObj), "12" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "0 2 4 2" },


    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};








/*
 * Checkbutton indicators (default): 3-D square.




 */
static void SquareIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int diameter = 0;




    (void)dummy;
    (void)paddingPtr;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
    *widthPtr = diameter + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + Ttk_PaddingHeight(margins);




}






static void SquareIndicatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{

    IndicatorElement *indicator = (IndicatorElement *)elementRecord;

    Tk_3DBorder border = 0, interior = 0;
    int relief = TK_RELIEF_RAISED;

    Ttk_Padding padding;
    int borderWidth = 2;
    int diameter;
    (void)dummy;
    (void)state;

    interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
    border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);

    Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
    Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);






    b = Ttk_PadBox(b, padding);

    diameter = b.width < b.height ? b.width : b.height;



    Tk_Fill3DRectangle(tkwin, d, interior, b.x, b.y,
	    diameter, diameter,borderWidth, TK_RELIEF_FLAT);
    Tk_Draw3DRectangle(tkwin, d, border, b.x, b.y,
	    diameter, diameter, borderWidth, relief);
}




/*
 * Radiobutton indicators:  3-D diamond.
 */
static void DiamondIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int diameter = 0;
    (void)dummy;
    (void)paddingPtr;


    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
    *widthPtr = diameter + 3 + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + 3 + Ttk_PaddingHeight(margins);
}











static void DiamondIndicatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Tk_3DBorder border = 0, interior = 0;
    int borderWidth = 2;
    int relief = TK_RELIEF_RAISED;
    int diameter, radius;
    XPoint points[4];
    Ttk_Padding padding;



    (void)dummy;
    (void)state;

    interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
    border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
    Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
    Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
















    b = Ttk_PadBox(b, padding);

    diameter = b.width < b.height ? b.width : b.height;
    radius = diameter / 2;

    points[0].x = b.x;
    points[0].y = b.y + radius;

    points[1].x = b.x + radius;
    points[1].y = b.y + 2*radius;
    points[2].x = b.x + 2*radius;
    points[2].y = b.y + radius;
    points[3].x = b.x + radius;
    points[3].y = b.y;

    Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT);
    Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief);




}

static const Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    SquareIndicatorElementSize,
    SquareIndicatorElementDraw
};




static const Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    DiamondIndicatorElementSize,
    DiamondIndicatorElementDraw
};

/*
 *----------------------------------------------------------------------

 * +++ Menubutton indicators.

 *

 * These aren't functional like radio/check indicators,
 * they're just affordability indicators.









 *


 * Standard Tk sets the indicator size to 4.0 mm by 1.7 mm.
 * I have no idea where these numbers came from.



 */

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *widthObj;
    Tcl_Obj *heightObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *marginObj;
} MenuIndicatorElement;




static const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,widthObj), "4.0m" },
    { "-indicatorheight", TK_OPTION_PIXELS,

	offsetof(MenuIndicatorElement,heightObj), "1.7m" },
    { "-borderwidth", TK_OPTION_PIXELS,

	offsetof(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(MenuIndicatorElement,reliefObj),"raised" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(MenuIndicatorElement,marginObj), "5 0" },

    { NULL, TK_OPTION_BOOLEAN, 0, NULL }


};



static void MenuIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    Ttk_Padding margins;
    (void)dummy;
    (void)paddingPtr;


    Tk_GetPixelsFromObj(NULL, tkwin, mi->widthObj, widthPtr);
    Tk_GetPixelsFromObj(NULL, tkwin, mi->heightObj, heightPtr);
    Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj, &margins);
    *widthPtr += Ttk_PaddingWidth(margins);
    *heightPtr += Ttk_PaddingHeight(margins);
}










static void MenuIndicatorElementDraw(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, mi->backgroundObj);
    Ttk_Padding margins;
    int borderWidth = 2;
    (void)dummy;


    (void)state;

    Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj,&margins);
    b = Ttk_PadBox(b, margins);
    Tk_GetPixelsFromObj(NULL, tkwin, mi->borderWidthObj, &borderWidth);

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,



	    borderWidth, TK_RELIEF_RAISED);

}

static const Ttk_ElementSpec MenuIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(MenuIndicatorElement),
    MenuIndicatorElementOptions,
    MenuIndicatorElementSize,
    MenuIndicatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Arrow elements.
 *
 * 	Draws a solid triangle inside a box.
 * 	clientData is an enum ArrowDirection pointer.
 */

typedef struct {


    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-relief",TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj),"raised"},
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ArrowElement,borderWidthObj), "1" },
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj),"black"},
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), "14" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding ArrowMargins = { 3,3,3,3 };

static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);


    int width = 14;
    (void)paddingPtr;





    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &width);
    width -= Ttk_PaddingWidth(ArrowMargins);
    TtkArrowSize(width/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(ArrowMargins);
    *heightPtr += Ttk_PaddingWidth(ArrowMargins);





}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;

    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);




    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    int relief = TK_RELIEF_RAISED;
    int borderWidth = 1;
    (void)state;


    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);

    Tk_Fill3DRectangle( tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);



























    TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
	    Ttk_PadBox(b, ArrowMargins), direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};















































































/*----------------------------------------------------------------------










































































 * +++ Trough element.
 *
 * Used in scrollbars and scales in place of "border".





 */

typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;



} TroughElement;

static const Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), DEFAULT_BORDERWIDTH },


    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },


    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    int borderWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);



    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}




static void TroughElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 2, relief = TK_RELIEF_SUNKEN;
    (void)dummy;
    (void)state;


    border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);

    Tk_GetReliefFromObj(NULL, troughPtr->reliefObj, &relief);

    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);















    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);
}

static const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,







>





>
>




>
|
>
|
>
>

<
<
|
|
<

>
|



>
|
>
|
>
>


>
|




<
<

>
>
>


>
|
<
>
|















|
<
|
>
|
<

<

>
>
|
|
|
<
<
<
|

|
>
>
>
|
|
|
|
|
|
|
|
|
|
>
>
|
|
|
<
>
>
>
>

>
>
>
|
|
>
>
>
>
|
<
<
<
|
<
<
<
>
>
>
>
|
<

<
|
<
<
>
>
>
>
|

>
>
>
>
>
|
<
<
|
>
|
>
|
|
>
|
<
|
<
<
|
|
|
>
|
|
|
>
>

>
>
>
|
|
<
>
>
>
|
<
<
<
|
>
>
>
|
|
<
<
|
<
<
>

<
<
|
<
<
>
|
<
<
<
<
|
>
>
>
>
>
>
>
>
|
>
>
|
|
|


<
<
<
<
<

>
>
>
|
<

<
|
<
<
<
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>


<
<
|
<
|
>
|
|
|
|
<
<
|
<
<
>
>
>
>
|

<
<
<
<
<
<
<
>
>
>
|
|
<
|
|
|
|
<

|
<
>
|
>
|
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
|
<
>
>
>
|
|
<
<
<
<
<
<
<
<
>
>
>
|
<
<
|
|
|
<
>
|
<
>
|
|
|
|
|
>
|
>
>
|
>
>

<
<
|
>
|
<
<
<
|
>
|
<
<
<
<
<
|
>
>
>
>
>
>
>
>
>
|
<
<
<
<
<
|
|
|
|
>
>
|
|
<
<
|
>
|
>
>
>
|
>


|

|
|
|
|



|






>
>



<
<



|
|
|
|
|
|
|
|
|
|



|



|
>



>
>
|
|
>
>
>
>

|
|
|
|
|
>
>
>
>
>




|
>

<

>

>
>
>
>

|
<
<

>


|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>



<


>
>
>



|
|
>
>


>
>
|
|




>
|
>
>
>
|


|
<
<
<


>
>
>
|
|
|
>
>
>

>
|
|
>


|
|
<
<
>

|
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569


570
571

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591


592
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620

621

622
623
624
625
626
627



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663



664



665
666
667
668
669

670

671


672
673
674
675
676
677
678
679
680
681
682
683


684
685
686
687
688
689
690
691

692


693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711



712
713
714
715
716
717


718


719
720


721


722
723




724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740





741
742
743
744
745

746

747



748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765


766

767
768
769
770
771
772


773


774
775
776
777
778
779







780
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

/*----------------------------------------------------------------------
 * +++ Sizegrip: lower-right corner grip handle for resizing window.
 */

typedef struct {
    Tcl_Obj	*backgroundObj;
    Tcl_Obj	*gripSizeObj;
} SizegripElement;

static const Ttk_ElementOptionSpec SizegripOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-gripsize", TK_OPTION_PIXELS,
	offsetof(SizegripElement,gripSizeObj), "11.25p" },
    {0,TK_OPTION_BOOLEAN,0,0}
};

static void SizegripSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{


    SizegripElement *grip = (SizegripElement *)elementRecord;
    int gripSize = 0;


    Tk_GetPixelsFromObj(NULL, tkwin, grip->gripSizeObj, &gripSize);
    *widthPtr = *heightPtr = gripSize;
}

static void SizegripDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SizegripElement *grip = (SizegripElement *)elementRecord;
    int gripSize = 0;
    int gripCount = 3, gripSpace, gripThickness;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, grip->backgroundObj);
    GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    int x1 = b.x + b.width-1, y1 = b.y + b.height-1, x2 = x1, y2 = y1;



    Tk_GetPixelsFromObj(NULL, tkwin, grip->gripSizeObj, &gripSize);
    gripThickness = gripSize * 3 / (gripCount * 5);
    gripSpace = gripSize / 3 - gripThickness;
    while (gripCount--) {
	x1 -= gripSpace; y2 -= gripSpace;
	for (int i = 1; i < gripThickness; i++) {
	    XDrawLine(Tk_Display(tkwin), d, darkGC,  x1,y1, x2,y2); --x1; --y2;

	}
	XDrawLine(Tk_Display(tkwin), d, lightGC,  x1,y1, x2,y2); --x1; --y2;
    }
}

static const Ttk_ElementSpec SizegripElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SizegripElement),
    SizegripOptions,
    SizegripSize,
    SizegripDraw
};

/*----------------------------------------------------------------------
 * +++ Indicator element.
 *
 * Draws the on/off indicator for checkbuttons and radiobuttons.
 */


/*
 * Indicator image descriptor:

 */

typedef struct {
    int width;				/* unscaled width */
    int height;				/* unscaled height */
    const char *const offDataPtr;
    const char *const onDataPtr;
    const char *const triDataPtr;



} IndicatorSpec;

static const char checkbtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <rect x='.5' y='.5' width='15' height='15' rx='1.5' fill='#ffffff' stroke='#888888'/>\n\
    </svg>";

static const char checkbtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <rect x='0' y='0' width='16' height='16' fill='#4a6984' rx='2'/>\n\
     <path d='m4.5 8 3 3 4-6' fill='none' stroke='#ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/>\n\
    </svg>";

static const char checkbtnTriData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <rect x='0' y='0' width='16' height='16' fill='#4a6984' rx='2'/>\n\
     <path d='m4 8h8' fill='none' stroke='#ffffff' stroke-width='2'/>\n\
    </svg>";

static const IndicatorSpec checkbutton_spec = {
    16, 16,

    checkbtnOffData,
    checkbtnOnData,
    checkbtnTriData
};

static const char radiobtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <circle cx='8' cy='8' r='7.5' fill='#ffffff' stroke='#888888'/>\n\
    </svg>";

static const char radiobtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <circle cx='8' cy='8' r='8' fill='#4a6984'/>\n\
     <circle cx='8' cy='8' r='3' fill='#ffffff'/>\n\
    </svg>";







static const char radiobtnTriData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <circle cx='8' cy='8' r='8' fill='#4a6984'/>\n\
     <path d='m4 8h8' fill='none' stroke='#ffffff' stroke-width='2'/>\n\
    </svg>";



static const IndicatorSpec radiobutton_spec = {


    16, 16,
    radiobtnOffData,
    radiobtnOnData,
    radiobtnTriData
};

typedef struct {
    Tcl_Obj *backgroundObj;
    Tcl_Obj *foregroundObj;
    Tcl_Obj *borderColorObj;
    Tcl_Obj *marginObj;
} IndicatorElement;



/*
 * Note that the -indicatorbackground and -indicatorforeground options below
 * have the same default value "#ffffff", but the -indicatorforeground option
 * will only be used for the alternate and selected states, in which the
 * -indicatorbackground option will have a different value (e.g., "#4a6984").
 */
static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {

    { "-indicatorbackground", TK_OPTION_COLOR,


	offsetof(IndicatorElement,backgroundObj), "#ffffff" },
    { "-indicatorforeground", TK_OPTION_COLOR,
        offsetof(IndicatorElement,foregroundObj), "#ffffff" },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,borderColorObj), "#888888" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "0 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void IndicatorElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{

    const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    Ttk_Padding margins;
    double scalingLevel = TkScalingLevel(tkwin);




    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    *widthPtr = spec->width * scalingLevel + Ttk_PaddingWidth(margins);
    *heightPtr = spec->height * scalingLevel + Ttk_PaddingHeight(margins);
}



static void ColorToStr(


    const XColor *colorPtr, char *colorStr)     /* in the format "RRGGBB" */
{


    snprintf(colorStr, 7, "%02x%02x%02x",


             colorPtr->red >> 8, colorPtr->green >> 8, colorPtr->blue >> 8);
}





static void ImageChanged(               /* to be passed to Tk_GetImage() */
    TCL_UNUSED(void *),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
}

static void IndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;





    Ttk_Padding padding;
    const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
    double scalingLevel = TkScalingLevel(tkwin);
    int width = spec->width * scalingLevel;
    int height = spec->height * scalingLevel;



    char bgColorStr[7], fgColorStr[7], borderColorStr[7];



    unsigned int selected = (state & TTK_STATE_SELECTED);
    unsigned int tristate = (state & TTK_STATE_ALTERNATE);
    Tcl_Interp *interp = Tk_Interp(tkwin);
    char imgName[60];
    Tk_Image img;

    const char *svgDataPtr;
    size_t svgDataLen;
    char *svgDataCopy;
    char *bgColorPtr, *fgColorPtr, *borderColorPtr;
    const char *cmdFmt;
    size_t scriptSize;
    char *script;
    int code;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);



    /*

     * Sanity check
     */
    if (   b.x < 0
	|| b.y < 0
	|| Tk_Width(tkwin) < b.x + width
	|| Tk_Height(tkwin) < b.y + height)


    {


	/* Oops!  Not enough room to display the image.
	 * Don't draw anything.
	 */
	return;
    }








    /*
     * Construct the color strings bgColorStr, fgColorStr, and borderColorStr
     */
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->backgroundObj),
	       bgColorStr);

    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->foregroundObj),
	       fgColorStr);
    ColorToStr(Tk_GetColorFromObj(tkwin, indicator->borderColorObj),
	       borderColorStr);


    /*

     * Check whether there is an SVG image of this size for the
     * indicator's type (0 = checkbtn, 1 = radiobtn), "state"
     * (0 = off, 1 = on, 2 = tristate), and these color strings
     */
    snprintf(imgName, sizeof(imgName),
	     "::tk::icons::indicator_default%d_%d,%d_%s_%s_%s",
	     width,
	     spec->offDataPtr == radiobtnOffData,
	     tristate ? 2 : (selected ? 1 : 0),
	     bgColorStr,
	     selected || tristate ? fgColorStr : "XXXXXX",
	     selected || tristate ? "XXXXXX" : borderColorStr);
    img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    if (img == NULL) {
	/*
	 * Determine the SVG data to use for the photo image
	 */
	svgDataPtr = (tristate ? spec->triDataPtr :
		      (selected ? spec->onDataPtr : spec->offDataPtr));


	/*
	 * Copy the string pointed to by svgDataPtr to
	 * a newly allocated memory area svgDataCopy
	 */
	svgDataLen = strlen(svgDataPtr);








	svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
	if (svgDataCopy == NULL) {
	    return;
	}


	memcpy(svgDataCopy, svgDataPtr, svgDataLen);
	svgDataCopy[svgDataLen] = '\0';


	/*
	 * Update the colors within svgDataCopy

	 */
	if (selected || tristate) {
	    bgColorPtr = strstr(svgDataCopy, "4a6984");
	    fgColorPtr = strstr(svgDataCopy, "ffffff");

	    assert(bgColorPtr);
	    assert(fgColorPtr);

	    memcpy(bgColorPtr, bgColorStr, 6);
	    memcpy(fgColorPtr, fgColorStr, 6);
	} else {
	    bgColorPtr =     strstr(svgDataCopy, "ffffff");
	    borderColorPtr = strstr(svgDataCopy, "888888");



	    assert(bgColorPtr);
	    assert(borderColorPtr);




	    memcpy(bgColorPtr, bgColorStr, 6);
	    memcpy(borderColorPtr, borderColorStr, 6);
	}






	/*
	 * Create an SVG photo image from svgDataCopy
	 */
	cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
	scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
	script = (char *)attemptckalloc(scriptSize);
	if (script == NULL) {
	    ckfree(svgDataCopy);
	    return;
	}





	snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
	ckfree(svgDataCopy);
	code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
	ckfree(script);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(interp, code);
	    return;
	}


	img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    }

    /*
     * Display the image
     */
    Tk_RedrawImage(img, 0, 0, width, height, d, b.x, b.y);
    Tk_FreeImage(img);
}

static const Ttk_ElementSpec IndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    IndicatorElementDraw
};

/*----------------------------------------------------------------------
 * +++ Arrow element(s).
 *
 * 	Draws a solid triangle inside a box.
 * 	clientData is an enum ArrowDirection pointer.
 */

typedef struct {
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;


} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), "14" },
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj), "black"},
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ArrowElement,borderWidthObj), "1" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj), "raised"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding ArrowPadding = { 3,3,3,3 };

static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding;
    int size = 14;

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.right = round(ArrowPadding.right * scalingLevel);
    padding.bottom = round(ArrowPadding.bottom * scalingLevel);

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
    if (*widthPtr < *heightPtr) {
	*widthPtr = *heightPtr;
    } else {
	*heightPtr = *widthPtr;
    }
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{

    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    int borderWidth = 1, relief = TK_RELIEF_RAISED;
    Ttk_Padding padding;
    double scalingLevel = TkScalingLevel(tkwin);
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);



    Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.right = round(ArrowPadding.right * scalingLevel);
    padding.bottom = round(ArrowPadding.bottom * scalingLevel);

    b = Ttk_PadBox(b, padding);

    switch (direction) {
	case ARROW_UP:
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_LEFT:
	case ARROW_RIGHT:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);

}

static const Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*
 * Modified arrow element for comboboxes and spinboxes:
 * 	The width and height are different, and the left edge is drawn in the
 *	same color as the right one.
 */

static void BoxArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    double scalingLevel = TkScalingLevel(tkwin);
    Ttk_Padding padding;
    int size = 14;

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.right = round(ArrowPadding.right * scalingLevel);
    padding.bottom = round(ArrowPadding.bottom * scalingLevel);

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
}

static void BoxArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    int borderWidth = 1, relief = TK_RELIEF_RAISED;
    Display *disp = Tk_Display(tkwin);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    int w = WIN32_XDRAWLINE_HACK;
    Ttk_Padding padding;
    double scalingLevel = TkScalingLevel(tkwin);
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC arrowGC = Tk_GCForColor(arrowColor, d);

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);

    XDrawLine(disp, d, darkGC, b.x, b.y+1, b.x, b.y+b.height-1+w);

    padding.left = round(ArrowPadding.left * scalingLevel);
    padding.top = round(ArrowPadding.top * scalingLevel);
    padding.right = round(ArrowPadding.right * scalingLevel);
    padding.bottom = round(ArrowPadding.bottom * scalingLevel);

    b = Ttk_PadBox(b, padding);

    TtkArrowSize(b.width/2, direction, &cx, &cy);
    if ((b.height - cy) % 2 == 1) {
	++cy;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(disp, d, arrowGC, b, direction);
}

static const Ttk_ElementSpec BoxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    BoxArrowElementSize,
    BoxArrowElementDraw
};

/*
 *----------------------------------------------------------------------
 * +++ Menubutton indicators.
 *
 * These aren't functional like radio/check indicators,
 * they're just affordability indicators.
 */

#define MENUBUTTON_ARROW_SIZE 5

typedef struct {
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *paddingObj;
} MenuIndicatorElement;

static const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(MenuIndicatorElement,colorObj), "black" },
    { "-arrowpadding", TK_OPTION_STRING,
	offsetof(MenuIndicatorElement,paddingObj), "3" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void MenuIndicatorElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
    Ttk_Padding margins;
    int size = MENUBUTTON_ARROW_SIZE;

    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->paddingObj, &margins);
    TtkArrowSize(size, ARROW_DOWN, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(margins);
    *heightPtr += Ttk_PaddingHeight(margins);
}

static void MenuIndicatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    GC gc = Tk_GCForColor(arrowColor, d);
    int size = MENUBUTTON_ARROW_SIZE;
    int width, height;

    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);

    TtkArrowSize(size, ARROW_DOWN, &width, &height);
    b = Ttk_StickBox(b, width, height, 0);
    TtkFillArrow(Tk_Display(tkwin), d, gc, b, ARROW_DOWN);
}

static const Ttk_ElementSpec MenuIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(MenuIndicatorElement),
    MenuIndicatorElementOptions,
    MenuIndicatorElementSize,
    MenuIndicatorElementDraw
};

/*
 *----------------------------------------------------------------------
 * +++ Trough element.
 *
 * Used in scrollbars and scales in place of "border".
 *
 * The -groovewidth option can be used to set the size of the short axis
 * for the drawn area. This will not affect the geometry, but can be used
 * to draw a thin centered trough inside the packet alloted. Use -1 or a
 * large number to use the full area (default).
 */

typedef struct {

    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *grooveWidthObj;
    Tcl_Obj *orientObj;
} TroughElement;

static const Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-troughborderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), "1" },
    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-groovewidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,grooveWidthObj), "-1" },
    { "-orient", TK_OPTION_ANY,
	offsetof(TroughElement, orientObj), "horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    int borderWidth = 1, grooveWidth = -1;




    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->grooveWidthObj, &grooveWidth);

    if (grooveWidth <= 0) {
	*paddingPtr = Ttk_UniformPadding((short)borderWidth);
    }
}

static Ttk_Box troughInnerBox;

static void TroughElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
    int borderWidth = 1, grooveWidth = -1, relief = TK_RELIEF_SUNKEN;


    Ttk_Orient orient;

    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->grooveWidthObj, &grooveWidth);
    Tk_GetReliefFromObj(NULL, troughPtr->reliefObj, &relief);
    Ttk_GetOrientFromObj(NULL, troughPtr->orientObj, &orient);

    if (grooveWidth > 0 && grooveWidth < b.height && grooveWidth < b.width) {
	if (orient == TTK_ORIENT_HORIZONTAL) {
	    b.y += (b.height - grooveWidth) / 2;
	    b.height = grooveWidth;
	} else {
	    b.x += (b.width - grooveWidth) / 2;
	    b.width = grooveWidth;
        }

	troughInnerBox.x = b.x + borderWidth;
	troughInnerBox.y = b.y + borderWidth;
	troughInnerBox.width =  b.width -  2*borderWidth;
	troughInnerBox.height = b.height - 2*borderWidth;
    }

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);
}

static const Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
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
	offsetof(ThumbElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int thickness;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->thicknessObj, &thickness);
    TtkGetOrientFromObj(NULL, thumb->orientObj, &orient);

    if (orient == TTK_ORIENT_VERTICAL) {
	*widthPtr = thickness;
	*heightPtr = MIN_THUMB_SIZE;
    } else {
	*widthPtr = MIN_THUMB_SIZE;
	*heightPtr = thickness;
    }
}

static void ThumbElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Tk_3DBorder  border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, thumb->reliefObj, &relief);
    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);
}

static const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*
 *----------------------------------------------------------------------
 * +++ Slider element.
 *
 * This is the moving part of the scale widget.  Drawn as a raised box.
 */









typedef struct {
    Tcl_Obj *orientObj;	     /* orientation of overall slider */
    Tcl_Obj *lengthObj;      /* slider length */
    Tcl_Obj *thicknessObj;   /* slider thickness */
    Tcl_Obj *reliefObj;      /* the relief for this object */
    Tcl_Obj *borderObj;      /* the background color */
    Tcl_Obj *borderWidthObj; /* the size of the border */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
	"30" },
    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(


    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int length, thickness;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->lengthObj, &length);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);

    switch (orient) {
	case TTK_ORIENT_VERTICAL:
	    *widthPtr = thickness;
	    *heightPtr = length;
	    break;

	case TTK_ORIENT_HORIZONTAL:
	    *widthPtr = length;
	    *heightPtr = thickness;
	    break;
    }
}

static void SliderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{



    SliderElement *slider = (SliderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    Ttk_Orient orient;





    (void)dummy;




    (void)state;






















    border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);




    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);










    Tk_Fill3DRectangle(tkwin, d, border,







	b.x, b.y, b.width, b.height,
	borderWidth, relief);

































    if (relief != TK_RELIEF_FLAT) {
	if (orient == TTK_ORIENT_HORIZONTAL) {
	    if (b.width > 4) {
		b.x += b.width/2;
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),

		    b.x-1, b.y+borderWidth, b.x-1, b.y+b.height-borderWidth);
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		    b.x, b.y+borderWidth, b.x, b.y+b.height-borderWidth);


	    }
	} else {
	    if (b.height > 4) {
		b.y += b.height/2;
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		    b.x+borderWidth, b.y-1, b.x+b.width-borderWidth, b.y-1);
		XDrawLine(Tk_Display(tkwin), d,
		    Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		    b.x+borderWidth, b.y, b.x+b.width-borderWidth, b.y);
	    }

	}
    }





}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,







>
|
|
>




<
<


|











>
|
|
>




<
<



















|


>
>
>
>
>
>
>
>

<
|
|
<
|
|



|
|
|
|
|
|
<
<
<
<






>
>
|
|
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
|
<
|
<
<
|
|
<

>
|
|
>

>
>
>

<
<

>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
<
<
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
<
<
|
|
<
>
|
|
|
|
>
>
|
<
<
|
|
|
|
|
|
|
|
>
|
|
>
>
>
>
>







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
	offsetof(ThumbElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int thickness;



    Tk_GetPixelsFromObj(NULL, tkwin, thumb->thicknessObj, &thickness);
    Ttk_GetOrientFromObj(NULL, thumb->orientObj, &orient);

    if (orient == TTK_ORIENT_VERTICAL) {
	*widthPtr = thickness;
	*heightPtr = MIN_THUMB_SIZE;
    } else {
	*widthPtr = MIN_THUMB_SIZE;
	*heightPtr = thickness;
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Tk_3DBorder  border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;



    Tk_GetPixelsFromObj(NULL, tkwin, thumb->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, thumb->reliefObj, &relief);
    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);
}

static const Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*
 *----------------------------------------------------------------------
 * +++ Slider element.
 *
 * This is the moving part of the scale widget.  Drawn as a filled circle.
 */

#define SLIDER_DIM 16

static const char sliderData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <circle cx='8' cy='8' r='7.5' fill='#ffffff' stroke='#c3c3c3'/>\n\
     <circle cx='8' cy='8' r='4' fill='#4a6984'/>\n\
    </svg>";

typedef struct {

    Tcl_Obj *innerColorObj;
    Tcl_Obj *outerColorObj;

    Tcl_Obj *borderColorObj;
    Tcl_Obj *orientObj;		/* Orientation of overall slider */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-innercolor", TK_OPTION_COLOR, offsetof(SliderElement,innerColorObj),
	"#4a6984" },
    { "-outercolor", TK_OPTION_COLOR, offsetof(SliderElement,outerColorObj),
	"#ffffff" },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(SliderElement,borderColorObj),
	"#c3c3c3" },




    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *widthPtr, int *heightPtr,






    TCL_UNUSED(Ttk_Padding *))



{





    double scalingLevel = TkScalingLevel(tkwin);

    *widthPtr = *heightPtr = SLIDER_DIM * scalingLevel;


}


static void SliderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    double scalingLevel = TkScalingLevel(tkwin);
    int dim = SLIDER_DIM * scalingLevel;

    SliderElement *slider = (SliderElement *)elementRecord;


    Ttk_Orient orient;
    Display *disp = Tk_Display(tkwin);
    XColor *innerColor = Tk_GetColorFromObj(tkwin, slider->innerColorObj);
    XColor *outerColor = Tk_GetColorFromObj(tkwin, slider->outerColorObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, slider->borderColorObj);
    GC gc = Tk_GCForColor(innerColor, d);

    char innerColorStr[7], outerColorStr[7], borderColorStr[7];
    Tcl_Interp *interp = Tk_Interp(tkwin);
    char imgName[50];
    Tk_Image img;

    const char *svgDataPtr = sliderData;
    size_t svgDataLen;
    char *svgDataCopy;
    char *innerColorPtr, *outerColorPtr, *borderColorPtr;
    const char *cmdFmt;
    size_t scriptSize;
    char *script;
    int code;

    /*
     * Sanity check
     */
    if (   b.x < 0
	|| b.y < 0
	|| Tk_Width(tkwin) < b.x + dim
	|| Tk_Height(tkwin) < b.y + dim)
    {
	/* Oops!  Not enough room to display the image.
	 * Don't draw anything.
	 */
	return;
    }

    /*
     * Fill the thin trough area preceding the
     * slider's center with the inner color
     */
    Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);


    switch (orient) {
	case TTK_ORIENT_HORIZONTAL:
	    XFillRectangle(disp, d, gc, troughInnerBox.x, troughInnerBox.y,
		    b.x + dim/2 - 1, troughInnerBox.height);
	    break;
	case TTK_ORIENT_VERTICAL:
	    XFillRectangle(disp, d, gc, troughInnerBox.x, troughInnerBox.y,
		    troughInnerBox.width, b.y + dim/2 - 1);
	    break;
    }

    /*
     * Construct the color strings innerColorStr,
     * outerColorStr, and borderColorStr
     */
    ColorToStr(innerColor, innerColorStr);
    ColorToStr(outerColor, outerColorStr);
    ColorToStr(borderColor, borderColorStr);


    /*
     * Check whether there is an SVG image of this size for these color strings
     */
    snprintf(imgName, sizeof(imgName),
	     "::tk::icons::slider_default%d_%s_%s_%s",
	     dim, innerColorStr, outerColorStr, borderColorStr);
    img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    if (img == NULL) {
	/*
	 * Copy the string pointed to by svgDataPtr to
	 * a newly allocated memory area svgDataCopy
	 */
	svgDataLen = strlen(svgDataPtr);
	svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
	if (svgDataCopy == NULL) {
	    return;
	}
	memcpy(svgDataCopy, svgDataPtr, svgDataLen);
	svgDataCopy[svgDataLen] = '\0';

	/*
	 * Update the colors within svgDataCopy
	 */
	innerColorPtr = strstr(svgDataCopy, "4a6984");
	outerColorPtr = strstr(svgDataCopy, "ffffff");
	borderColorPtr = strstr(svgDataCopy, "c3c3c3");
	assert(innerColorPtr);
	assert(outerColorPtr);
	assert(borderColorPtr);
	memcpy(innerColorPtr, innerColorStr, 6);
	memcpy(outerColorPtr, outerColorStr, 6);
	memcpy(borderColorPtr, borderColorStr, 6);




	/*
	 * Create an SVG photo image from svgDataCopy

	 */
	cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
	scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
	script = (char *)attemptckalloc(scriptSize);
	if (script == NULL) {
	    ckfree(svgDataCopy);
	    return;
	}


	snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
	ckfree(svgDataCopy);
	code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
	ckfree(script);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(interp, code);
	    return;
	}
	img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    }

    /*
     * Display the image
     */
    Tk_RedrawImage(img, 0, 0, dim, dim, d, b.x, b.y);
    Tk_FreeImage(img);
}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
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
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(PbarElement,borderObj),
	DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PbarElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)

{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Ttk_Orient orient;
    int thickness = 15, length = 30, borderWidth = 2;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, pbar->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, pbar->thicknessObj, &thickness);
    Tk_GetPixelsFromObj(NULL, tkwin, pbar->lengthObj, &length);
    Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);

    switch (orient) {
	case TTK_ORIENT_HORIZONTAL:
	    *widthPtr	= length + 2 * borderWidth;
	    *heightPtr	= thickness + 2 * borderWidth;
	    break;
	case TTK_ORIENT_VERTICAL:
	    *widthPtr	= thickness + 2 * borderWidth;
	    *heightPtr	= length + 2 * borderWidth;
	    break;
    }
}

static void PbarElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)

{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, pbar->borderObj);
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, pbar->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height,
	borderWidth, relief);







>
|
|
>




<
<

|

















>
|
|
>




<
<







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
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(PbarElement,borderObj),
	DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PbarElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Ttk_Orient orient;
    int thickness = 15, length = 30, borderWidth = 2;



    Ttk_GetOrientFromObj(NULL, pbar->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, pbar->thicknessObj, &thickness);
    Tk_GetPixelsFromObj(NULL, tkwin, pbar->lengthObj, &length);
    Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);

    switch (orient) {
	case TTK_ORIENT_HORIZONTAL:
	    *widthPtr	= length + 2 * borderWidth;
	    *heightPtr	= thickness + 2 * borderWidth;
	    break;
	case TTK_ORIENT_VERTICAL:
	    *widthPtr	= thickness + 2 * borderWidth;
	    *heightPtr	= length + 2 * borderWidth;
	    break;
    }
}

static void PbarElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, pbar->borderObj);
    int relief = TK_RELIEF_RAISED, borderWidth = 2;



    Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, pbar->reliefObj, &relief);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height,
	borderWidth, relief);
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
/*------------------------------------------------------------------------
 * +++ Notebook tabs and client area.
 */

typedef struct {
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *backgroundObj;


} TabElement;

static const Ttk_ElementOptionSpec TabElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TabElement,borderWidthObj),"1" },
    { "-background", TK_OPTION_BORDER,
	offsetof(TabElement,backgroundObj), DEFAULT_BACKGROUND },




    {0,TK_OPTION_BOOLEAN,0,0}
};

static void TabElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TabElement *tab = (TabElement *)elementRecord;
    int borderWidth = 1;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);












    paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;


    paddingPtr->bottom = 0;




}


static void TabElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{


    TabElement *tab = (TabElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    int borderWidth = 1;
    int cut = 2;
    XPoint pts[6];



    int n = 0;
    (void)dummy;



    Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);

    if (state & TTK_STATE_SELECTED) {
	/*
	 * Draw slightly outside of the allocated parcel,
	 * to overwrite the client area border.
	 */



	b.height += borderWidth;










    }










    pts[n].x = b.x; 			pts[n].y = b.y + b.height - 1; ++n;
    pts[n].x = b.x;			pts[n].y = b.y + cut; ++n;
    pts[n].x = b.x + cut;  		pts[n].y = b.y; ++n;
    pts[n].x = b.x + b.width-1-cut;	pts[n].y = b.y; ++n;









    pts[n].x = b.x + b.width-1; 	pts[n].y = b.y + cut; ++n;


    pts[n].x = b.x + b.width-1; 	pts[n].y = b.y + b.height; ++n;















    XFillPolygon(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
	pts, 6, Convex, CoordModeOrigin);




#ifndef _WIN32
    /*

     * Account for whether XDrawLines draws endpoints by platform
     */
    --pts[5].y;
#endif









    while (borderWidth--) {
	XDrawLines(Tk_Display(tkwin), d,
		Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		pts, 4, CoordModeOrigin);
	XDrawLines(Tk_Display(tkwin), d,
		Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		pts+3, 3, CoordModeOrigin);
	++pts[0].x; ++pts[1].x; ++pts[2].x;             --pts[4].x; --pts[5].x;




	                        ++pts[2].y; ++pts[3].y;













    }























}

static const Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TabElement),
    TabElementOptions,
    TabElementSize,
    TabElementDraw
};

/*
 * Client area element:
 * Uses same resources as tab element.
 */
typedef TabElement ClientElement;
#define ClientElementOptions TabElementOptions















static void ClientElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)

{
    ClientElement *ce = (ClientElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 1;
    (void)dummy;
    (void)state;

    Tcl_GetIntFromObj(NULL, ce->borderWidthObj, &borderWidth);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_RAISED);
}

static void ClientElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ClientElement *ce = (ClientElement *)elementRecord;
    int borderWidth = 1;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static const Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ClientElement),
    ClientElementOptions,
    ClientElementSize,
    ClientElementDraw
};

/*----------------------------------------------------------------------
 * TtkElements_Init --
 *	Register default element implementations.
 */




MODULE_SCOPE
void TtkElements_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    /*
     * Elements:
     */
    Ttk_RegisterElement(interp, theme, "background",
	    &BackgroundElementSpec,NULL);

    Ttk_RegisterElement(interp, theme, "fill", &FillElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "focus", &FocusElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "padding", &PaddingElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &CheckbuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &RadiobuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenuIndicatorElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec,NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));


    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));




    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));








>
>




|


>
>
>
>




>
|
>
>
|



|
|
<


>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
|
|
>

>
|
|

>
>


|
|

>
>
>
|
|
>
>
|
<






>
>
>
|
>
>
>
>
>
>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
>
|
|
<
>
|
<
|
|
>
>
>
>
>
>
|
>
>

<
|

<
|

|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
|
|
>




<
<







<
<
<
<
<
<
<
<
<
<
<
<
<
<













>
>
>



















|

|



|



>
>


>
>
>
>







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
/*------------------------------------------------------------------------
 * +++ Notebook tabs and client area.
 */

typedef struct {
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *backgroundObj;
    Tcl_Obj *highlightObj;
    Tcl_Obj *highlightColorObj;
} TabElement;

static const Ttk_ElementOptionSpec TabElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TabElement,borderWidthObj), "1" },
    { "-background", TK_OPTION_BORDER,
	offsetof(TabElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-highlight", TK_OPTION_BOOLEAN,
	offsetof(TabElement,highlightObj), "0" },
    { "-highlightcolor", TK_OPTION_COLOR,
	offsetof(TabElement,highlightColorObj), "#4a6984" },
    {0,TK_OPTION_BOOLEAN,0,0}
};

static void TabElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    TabElement *tab = (TabElement *)elementRecord;
    int borderWidth = 1;
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;


    Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    TabElement *tab = (TabElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    int highlight = 0;
    XColor *hlColor = NULL;
    XPoint pts[6];
    double scalingLevel = TkScalingLevel(tkwin);
    int cut = round(2 * scalingLevel);
    Display *disp = Tk_Display(tkwin);
    int borderWidth = 1;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }


    if (state & TTK_STATE_SELECTED) {
	/*
	 * Draw slightly outside of the allocated parcel,
	 * to overwrite the client area border.
	 */
	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		b.height += 1;
		break;
	    case TTK_STICK_N:
		b.height += 1; b.y -= 1;
		break;
	    case TTK_STICK_E:
		b.width += 1;
		break;
	    case TTK_STICK_W:
		b.width += 1; b.x -= 1;
		break;
	}

	Tcl_GetBooleanFromObj(NULL, tab->highlightObj, &highlight);
	if (highlight) {
	    hlColor = Tk_GetColorFromObj(tkwin, tab->highlightColorObj);
	}
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    pts[0].x = b.x;  pts[0].y = b.y + b.height-1;
	    pts[1].x = b.x;  pts[1].y = b.y + cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y + b.height;
	    break;
	case TTK_STICK_N:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x;  pts[1].y = b.y + b.height-1 - cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y + b.height-1;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y + b.height-1;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + b.height-1 - cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y-1;
	    break;
	case TTK_STICK_E:
	    pts[0].x = b.x + b.width-1;  pts[0].y = b.y;
	    pts[1].x = b.x + cut;  pts[1].y = b.y;
	    pts[2].x = b.x;  pts[2].y = b.y + cut;
	    pts[3].x = b.x;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x + b.width;  pts[5].y = b.y + b.height-1;
	    break;
	case TTK_STICK_W:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x + b.width-1 - cut;  pts[1].y = b.y;
	    pts[2].x = b.x + b.width-1;  pts[2].y = b.y + cut;
	    pts[3].x = b.x + b.width-1;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + b.width-1 - cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x-1;  pts[5].y = b.y + b.height-1;
	    break;
    }

    XFillPolygon(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
	    pts, 6, Convex, CoordModeOrigin);

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    pts[5].y -= 1 - WIN32_XDRAWLINE_HACK;

	    break;
	case TTK_STICK_N:

	    pts[5].y += 1 - WIN32_XDRAWLINE_HACK;
	    break;
	case TTK_STICK_E:
	    pts[5].x -= 1 - WIN32_XDRAWLINE_HACK;
	    break;
	case TTK_STICK_W:
	    pts[5].x += 1 - WIN32_XDRAWLINE_HACK;
	    break;
    }

    Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);
    while (borderWidth--) {

	XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		pts, 4, CoordModeOrigin);

	XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		pts+3, 3, CoordModeOrigin);

	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		++pts[0].x;  ++pts[1].x;  ++pts[2].y;
		++pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_N:
		++pts[0].x;  ++pts[1].x;  --pts[2].y;
		--pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_E:
		++pts[0].y;  ++pts[1].y;  ++pts[2].x;
		++pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	    case TTK_STICK_W:
		++pts[0].y;  ++pts[1].y;  --pts[2].x;
		--pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	}
    }

    if (highlight) {
	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x + cut, b.y, b.width - 2*cut, cut);
		break;
	    case TTK_STICK_N:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x + cut, b.y + b.height - cut, b.width - 2*cut, cut);
		break;
	    case TTK_STICK_E:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x, b.y + cut, cut, b.height - 2*cut);
		break;
	    case TTK_STICK_W:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x + b.width - cut, b.y + cut, cut, b.height - 2*cut);
		break;
	}
    }
}

static const Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TabElement),
    TabElementOptions,
    TabElementSize,
    TabElementDraw
};

/*
 * Client area element:
 * Uses same resources as tab element.
 */
typedef TabElement ClientElement;
#define ClientElementOptions TabElementOptions

static void ClientElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    ClientElement *ce = (ClientElement *)elementRecord;
    int borderWidth = 1;

    Tk_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void ClientElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ClientElement *ce = (ClientElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 1;



    Tcl_GetIntFromObj(NULL, ce->borderWidthObj, &borderWidth);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_RAISED);
}















static const Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ClientElement),
    ClientElementOptions,
    ClientElementSize,
    ClientElementDraw
};

/*----------------------------------------------------------------------
 * TtkElements_Init --
 *	Register default element implementations.
 */

MODULE_SCOPE
void TtkElements_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkElements_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    /*
     * Elements:
     */
    Ttk_RegisterElement(interp, theme, "background",
	    &BackgroundElementSpec,NULL);

    Ttk_RegisterElement(interp, theme, "fill", &FillElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "focus", &FocusElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "padding", &PaddingElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &IndicatorElementSpec, (void *)&checkbutton_spec);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &IndicatorElementSpec, (void *)&radiobutton_spec);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenuIndicatorElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
	    &BoxArrowElementSpec, INT2PTR(ARROW_UP));
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
	    &BoxArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "Combobox.downarrow",
	    &BoxArrowElementSpec, INT2PTR(ARROW_DOWN));
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));

Changes to generic/ttk/ttkEntry.c.

1
2
3
4
5
6
7
8
9
10
11
12
13




14
15
16
17
18
19
20
/*
 * DERIVED FROM: tk/generic/tkEntry.c r1.35.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2000 Ajuba Solutions.
 * Copyright (c) 2002 ActiveState Corporation.
 * Copyright (c) 2004 Joe English
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"





/*
 * Extra bits for core.flags:
 */
#define GOT_SELECTION		(WIDGET_USER_FLAG<<1)
#define SYNCING_VARIABLE	(WIDGET_USER_FLAG<<2)
#define VALIDATING		(WIDGET_USER_FLAG<<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
/*
 * DERIVED FROM: tk/generic/tkEntry.c r1.35.
 *
 * 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Extra bits for core.flags:
 */
#define GOT_SELECTION		(WIDGET_USER_FLAG<<1)
#define SYNCING_VARIABLE	(WIDGET_USER_FLAG<<2)
#define VALIDATING		(WIDGET_USER_FLAG<<3)
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
} EntryStyleData;

typedef struct {
    /*
     * Internal state:
     */
    char *string;		/* Storage for string (malloced) */
    TkSizeT numBytes;		/* Length of string in bytes. */
    TkSizeT numChars;		/* Length of string in characters. */

    TkSizeT insertPos;		/* Insert index */
    TkSizeT selectFirst;		/* Index of start of selection, or TCL_INDEX_NONE */
    TkSizeT selectLast;		/* Index of end of selection, or TCL_INDEX_NONE */

    Scrollable xscroll;		/* Current scroll position */
    ScrollHandle xscrollHandle;

    /*
     * Options managed by Tk_SetOptions:
     */







|
|

|
|
|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
} EntryStyleData;

typedef struct {
    /*
     * Internal state:
     */
    char *string;		/* Storage for string (malloced) */
    Tcl_Size numBytes;		/* Length of string in bytes. */
    Tcl_Size numChars;		/* Length of string in characters. */

    Tcl_Size insertPos;		/* Insert index */
    Tcl_Size selectFirst;		/* Index of start of selection, or TCL_INDEX_NONE */
    Tcl_Size selectLast;		/* Index of end of selection, or TCL_INDEX_NONE */

    Scrollable xscroll;		/* Current scroll position */
    ScrollHandle xscrollHandle;

    /*
     * Options managed by Tk_SetOptions:
     */
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
	DEF_ENTRY_FONT, offsetof(Entry, entry.fontObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", TCL_INDEX_NONE, offsetof(Entry, entry.justify),
	0, 0, GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	NULL, offsetof(Entry, entry.placeholderObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-show", "show", "Show",
        NULL, TCL_INDEX_NONE, offsetof(Entry, entry.showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Entry, entry.stateObj), TCL_INDEX_NONE,
        0,0,STATE_CHANGED},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	NULL, offsetof(Entry, entry.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,TEXTVAR_CHANGED},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	"none", TCL_INDEX_NONE, offsetof(Entry, entry.validate),
	0, (void *) validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.validateCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, offsetof(Entry, entry.widthObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",







|














|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
	DEF_ENTRY_FONT, offsetof(Entry, entry.fontObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", TCL_INDEX_NONE, offsetof(Entry, entry.justify),
	TK_OPTION_ENUM_VAR, 0, GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	NULL, offsetof(Entry, entry.placeholderObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-show", "show", "Show",
        NULL, TCL_INDEX_NONE, offsetof(Entry, entry.showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Entry, entry.stateObj), TCL_INDEX_NONE,
        0,0,STATE_CHANGED},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	NULL, offsetof(Entry, entry.textVariableObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,TEXTVAR_CHANGED},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	"none", TCL_INDEX_NONE, offsetof(Entry, entry.validate),
	TK_OPTION_ENUM_VAR, 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",
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
static char *EntryDisplayString(const char *showChar, int numChars)
{
    char *displayString, *p;
    int size;
    int ch;
    char buf[6];

    TkUtfToUniChar(showChar, &ch);
    size = TkUniCharToUtf(ch, buf);
    p = displayString = (char *)ckalloc(numChars * size + 1);

    while (numChars--) {
	memcpy(p, buf, size);
	p += size;
    }
    *p = '\0';

    return displayString;
}

/* EntryUpdateTextLayout --
 * 	Recompute textLayout, layoutWidth, and layoutHeight
 * 	from displayString and fontObj.
 */
static void EntryUpdateTextLayout(Entry *entryPtr)
{
    TkSizeT length;
    char *text;
    Tk_FreeTextLayout(entryPtr->entry.textLayout);
    if ((entryPtr->entry.numChars != 0) || (entryPtr->entry.placeholderObj == NULL)) {
        entryPtr->entry.textLayout = Tk_ComputeTextLayout(
	    Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
	    entryPtr->entry.displayString, entryPtr->entry.numChars,
	    0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
	    &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
    } else {
        text = TkGetStringFromObj(entryPtr->entry.placeholderObj, &length);
        entryPtr->entry.textLayout = Tk_ComputeTextLayout(
	    Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
	    text, length,
	    0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
	    &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
    }
}







|
|

















|









|







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
static char *EntryDisplayString(const char *showChar, int numChars)
{
    char *displayString, *p;
    int size;
    int ch;
    char buf[6];

    Tcl_UtfToUniChar(showChar, &ch);
    size = Tcl_UniCharToUtf(ch, buf);
    p = displayString = (char *)ckalloc(numChars * size + 1);

    while (numChars--) {
	memcpy(p, buf, size);
	p += size;
    }
    *p = '\0';

    return displayString;
}

/* EntryUpdateTextLayout --
 * 	Recompute textLayout, layoutWidth, and layoutHeight
 * 	from displayString and fontObj.
 */
static void EntryUpdateTextLayout(Entry *entryPtr)
{
    Tcl_Size length;
    char *text;
    Tk_FreeTextLayout(entryPtr->entry.textLayout);
    if ((entryPtr->entry.numChars != 0) || (entryPtr->entry.placeholderObj == NULL)) {
        entryPtr->entry.textLayout = Tk_ComputeTextLayout(
	    Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
	    entryPtr->entry.displayString, entryPtr->entry.numChars,
	    0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
	    &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
    } else {
        text = 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);
    }
}
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*------------------------------------------------------------------------
 * +++ Selection management.
 */

/* EntryFetchSelection --
 *	Selection handler for entry widgets.
 */
static TkSizeT
EntryFetchSelection(
    ClientData clientData, TkSizeT offset, char *buffer, TkSizeT maxBytes)
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if (entryPtr->entry.selectFirst == TCL_INDEX_NONE || (!entryPtr->entry.exportSelection)
	    || Tcl_IsSafe(entryPtr->core.interp)) {
	return TCL_INDEX_NONE;
    }
    string = entryPtr->entry.displayString;

    selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,







|

|


|



|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/*------------------------------------------------------------------------
 * +++ Selection management.
 */

/* EntryFetchSelection --
 *	Selection handler for entry widgets.
 */
static Tcl_Size
EntryFetchSelection(
    void *clientData, Tcl_Size offset, char *buffer, Tcl_Size maxBytes)
{
    Entry *entryPtr = (Entry *)clientData;
    Tcl_Size byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection)
	    || Tcl_IsSafe(entryPtr->core.interp)) {
	return TCL_INDEX_NONE;
    }
    string = entryPtr->entry.displayString;

    selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    return byteCount;
}

/* EntryLostSelection --
 *	Tk_LostSelProc for Entry widgets; called when an entry
 *	loses ownership of the selection.
 */
static void EntryLostSelection(ClientData clientData)
{
    Entry *entryPtr = (Entry *)clientData;
    entryPtr->core.flags &= ~GOT_SELECTION;
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    TtkRedisplayWidget(&entryPtr->core);
}








|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
    return byteCount;
}

/* EntryLostSelection --
 *	Tk_LostSelProc for Entry widgets; called when an entry
 *	loses ownership of the selection.
 */
static void EntryLostSelection(void *clientData)
{
    Entry *entryPtr = (Entry *)clientData;
    entryPtr->core.flags &= ~GOT_SELECTION;
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    TtkRedisplayWidget(&entryPtr->core);
}

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 *	or -invalidcommand).
 */
static void
ExpandPercents(
     Entry *entryPtr,		/* Entry that needs validation. */
     const char *templ, 	/* Script template */
     const char *newValue,		/* Potential new value of entry string */
     TkSizeT index,			/* index of insert/delete */
     int count,			/* #changed characters */
     VREASON reason,		/* Reason for change */
     Tcl_DString *dsPtr)	/* Result of %-substitutions */
{
    int spaceNeeded, cvtFlags;
    int number, length;
    const char *string;
    int stringLength;
    int ch;
    char numStorage[2*TCL_INTEGER_SPACE];

    while (*templ) {
	/* Find everything up to the next % character and append it
	 * to the result string.
	 */
	string = Tcl_UtfFindFirst(templ, '%');
	if (string == NULL) {
	    /* No more %-sequences to expand.
	     * Copy the rest of the template.
	     */
	    Tcl_DStringAppend(dsPtr, templ, -1);
	    return;
	}
	if (string != templ) {
	    Tcl_DStringAppend(dsPtr, templ, string - templ);
	    templ = string;
	}

	/* There's a percent sequence here.  Process it.
	 */
	++templ; /* skip over % */
	if (*templ != '\0') {
	    templ += TkUtfToUniChar(templ, &ch);
	} else {
	    ch = '%';
	}

	stringLength = -1;
	switch (ch) {
	    case 'd': /* Type of call that caused validation */
		if (reason == VALIDATE_INSERT) {
		    number = 1;
		} else if (reason == VALIDATE_DELETE) {
		    number = 0;
		} else {
		    number = -1;
		}
		sprintf(numStorage, "%d", number);
		string = numStorage;
		break;
	    case 'i': /* index of insert/delete */
		sprintf(numStorage, "%d", (int)index);
		string = numStorage;
		break;
	    case 'P': /* 'Peeked' new value of the string */
		string = newValue;
		break;
	    case 's': /* Current string value */
		string = entryPtr->entry.string;







|




















|











|














|



|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
 *	or -invalidcommand).
 */
static void
ExpandPercents(
     Entry *entryPtr,		/* Entry that needs validation. */
     const char *templ, 	/* Script template */
     const char *newValue,		/* Potential new value of entry string */
     Tcl_Size index,			/* index of insert/delete */
     int count,			/* #changed characters */
     VREASON reason,		/* Reason for change */
     Tcl_DString *dsPtr)	/* Result of %-substitutions */
{
    int spaceNeeded, cvtFlags;
    int number, length;
    const char *string;
    int stringLength;
    int ch;
    char numStorage[2*TCL_INTEGER_SPACE];

    while (*templ) {
	/* Find everything up to the next % character and append it
	 * to the result string.
	 */
	string = Tcl_UtfFindFirst(templ, '%');
	if (string == NULL) {
	    /* No more %-sequences to expand.
	     * Copy the rest of the template.
	     */
	    Tcl_DStringAppend(dsPtr, templ, TCL_INDEX_NONE);
	    return;
	}
	if (string != templ) {
	    Tcl_DStringAppend(dsPtr, templ, string - templ);
	    templ = string;
	}

	/* There's a percent sequence here.  Process it.
	 */
	++templ; /* skip over % */
	if (*templ != '\0') {
	    templ += Tcl_UtfToUniChar(templ, &ch);
	} else {
	    ch = '%';
	}

	stringLength = -1;
	switch (ch) {
	    case 'd': /* Type of call that caused validation */
		if (reason == VALIDATE_INSERT) {
		    number = 1;
		} else if (reason == VALIDATE_DELETE) {
		    number = 0;
		} else {
		    number = -1;
		}
		snprintf(numStorage, sizeof(numStorage), "%d", number);
		string = numStorage;
		break;
	    case 'i': /* index of insert/delete */
		snprintf(numStorage, sizeof(numStorage), "%" TCL_SIZE_MODIFIER "d", index);
		string = numStorage;
		break;
	    case 'P': /* 'Peeked' new value of the string */
		string = newValue;
		break;
	    case 's': /* Current string value */
		string = entryPtr->entry.string;
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
	    case 'V': /* type of validation in effect */
		string = validateReasonStrings[reason];
		break;
	    case 'W': /* widget name */
		string = Tk_PathName(entryPtr->core.tkwin);
		break;
	    default:
		length = TkUniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	}

	spaceNeeded = Tcl_ScanCountedElement(string, stringLength, &cvtFlags);
	length = Tcl_DStringLength(dsPtr);







|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
	    case 'V': /* type of validation in effect */
		string = validateReasonStrings[reason];
		break;
	    case 'W': /* widget name */
		string = Tk_PathName(entryPtr->core.tkwin);
		break;
	    default:
		length = Tcl_UniCharToUtf(ch, numStorage);
		numStorage[length] = '\0';
		string = numStorage;
		break;
	}

	spaceNeeded = Tcl_ScanCountedElement(string, stringLength, &cvtFlags);
	length = Tcl_DStringLength(dsPtr);
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
 */
static int RunValidationScript(
    Tcl_Interp *interp, 	/* Interpreter to use */
    Entry *entryPtr,		/* Entry being validated */
    const char *templ,	/* Script template */
    const char *optionName,	/* "-validatecommand", "-invalidcommand" */
    const char *newValue,	/* Potential new value of entry string */
    TkSizeT index,			/* index of insert/delete */
    TkSizeT count,			/* #changed characters */
    VREASON reason)		/* Reason for change */
{
    Tcl_DString script;
    int code;

    Tcl_DStringInit(&script);
    ExpandPercents(entryPtr, templ, newValue, index, count, reason, &script);







|
|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
 */
static int RunValidationScript(
    Tcl_Interp *interp, 	/* Interpreter to use */
    Entry *entryPtr,		/* Entry being validated */
    const char *templ,	/* Script template */
    const char *optionName,	/* "-validatecommand", "-invalidcommand" */
    const char *newValue,	/* Potential new value of entry string */
    Tcl_Size index,			/* index of insert/delete */
    Tcl_Size count,			/* #changed characters */
    VREASON reason)		/* Reason for change */
{
    Tcl_DString script;
    int code;

    Tcl_DStringInit(&script);
    ExpandPercents(entryPtr, templ, newValue, index, count, reason, &script);
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
/* EntryValidateChange --
 *	Validate a proposed change to the entry widget's value if required.
 *	Call the -invalidcommand if validation fails.
 *
 * Returns:
 *	TCL_OK if the change is accepted
 *	TCL_BREAK if the change is rejected
 *      TCL_ERROR if any errors occurred
 *
 * The change will be rejected if -validatecommand returns 0,
 * or if -validatecommand or -invalidcommand modifies the value.
 */
static int
EntryValidateChange(
    Entry *entryPtr,		/* Entry that needs validation. */
    const char *newValue,	/* Potential new value of entry string */
    TkSizeT index,			/* index of insert/delete, TCL_INDEX_NONE otherwise */
    TkSizeT count,			/* #changed characters */
    VREASON reason)		/* Reason for change */
{
    Tcl_Interp *interp = entryPtr->core.interp;
    VMODE vmode = entryPtr->entry.validate;
    int code, change_ok;

    if ((entryPtr->entry.validateCmd == NULL)







|








|
|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
/* EntryValidateChange --
 *	Validate a proposed change to the entry widget's value if required.
 *	Call the -invalidcommand if validation fails.
 *
 * Returns:
 *	TCL_OK if the change is accepted
 *	TCL_BREAK if the change is rejected
 *	TCL_ERROR if any errors occurred
 *
 * The change will be rejected if -validatecommand returns 0,
 * or if -validatecommand or -invalidcommand modifies the value.
 */
static int
EntryValidateChange(
    Entry *entryPtr,		/* Entry that needs validation. */
    const char *newValue,	/* Potential new value of entry string */
    Tcl_Size index,			/* index of insert/delete, TCL_INDEX_NONE otherwise */
    Tcl_Size count,			/* #changed characters */
    VREASON reason)		/* Reason for change */
{
    Tcl_Interp *interp = entryPtr->core.interp;
    VMODE vmode = entryPtr->entry.validate;
    int code, change_ok;

    if ((entryPtr->entry.validateCmd == NULL)
652
653
654
655
656
657
658
659



660
661
662
663
664
665
666
667
668
669
670
/* EntryRevalidate --
 * 	Revalidate the current value of an entry widget,
 * 	update the TTK_STATE_INVALID bit.
 *
 * Returns:
 * 	TCL_OK if valid, TCL_BREAK if invalid, TCL_ERROR on error.
 */
static int EntryRevalidate(Tcl_Interp *dummy, Entry *entryPtr, VREASON reason)



{
    int code = EntryValidateChange(
		    entryPtr, entryPtr->entry.string, -1,0, reason);
    (void)dummy;

    if (code == TCL_BREAK) {
	TtkWidgetChangeState(&entryPtr->core, TTK_STATE_INVALID, 0);
    } else if (code == TCL_OK) {
	TtkWidgetChangeState(&entryPtr->core, 0, TTK_STATE_INVALID);
    }








|
>
>
>



<







656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
/* EntryRevalidate --
 * 	Revalidate the current value of an entry widget,
 * 	update the TTK_STATE_INVALID bit.
 *
 * Returns:
 * 	TCL_OK if valid, TCL_BREAK if invalid, TCL_ERROR on error.
 */
static int EntryRevalidate(
    TCL_UNUSED(Tcl_Interp *),
    Entry *entryPtr,
    VREASON reason)
{
    int code = EntryValidateChange(
		    entryPtr, entryPtr->entry.string, -1,0, reason);


    if (code == TCL_BREAK) {
	TtkWidgetChangeState(&entryPtr->core, TTK_STATE_INVALID, 0);
    } else if (code == TCL_OK) {
	TtkWidgetChangeState(&entryPtr->core, 0, TTK_STATE_INVALID);
    }

716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
    int g = nChars > 0;		/* left gravity adjustment */

    e->insertPos    = AdjustIndex(e->insertPos, index, nChars);
    e->selectFirst  = AdjustIndex(e->selectFirst, index, nChars);
    e->selectLast   = AdjustIndex(e->selectLast, index+g, nChars);
    e->xscroll.first= AdjustIndex(e->xscroll.first, index+g, nChars);

    if (e->selectLast + 1 <= e->selectFirst + 1)
	e->selectFirst = e->selectLast = TCL_INDEX_NONE;
}

/* EntryStoreValue --
 *	Replace the contents of a text entry with a given value,
 *	recompute dependent resources, and schedule a redisplay.
 *
 *	See also: EntrySetValue().
 */
static void
EntryStoreValue(Entry *entryPtr, const char *value)
{
    size_t numBytes = strlen(value);
    TkSizeT numChars = Tcl_NumUtfChars(value, numBytes);

    if (entryPtr->core.flags & VALIDATING)
	entryPtr->core.flags |= VALIDATION_SET_VALUE;

    /* Make sure all indices remain in bounds:
     */
    if (numChars < entryPtr->entry.numChars)







|













|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
    int g = nChars > 0;		/* left gravity adjustment */

    e->insertPos    = AdjustIndex(e->insertPos, index, nChars);
    e->selectFirst  = AdjustIndex(e->selectFirst, index, nChars);
    e->selectLast   = AdjustIndex(e->selectLast, index+g, nChars);
    e->xscroll.first= AdjustIndex(e->xscroll.first, index+g, nChars);

    if (e->selectLast <= e->selectFirst)
	e->selectFirst = e->selectLast = TCL_INDEX_NONE;
}

/* EntryStoreValue --
 *	Replace the contents of a text entry with a given value,
 *	recompute dependent resources, and schedule a redisplay.
 *
 *	See also: EntrySetValue().
 */
static void
EntryStoreValue(Entry *entryPtr, const char *value)
{
    size_t numBytes = strlen(value);
    Tcl_Size numChars = Tcl_NumUtfChars(value, numBytes);

    if (entryPtr->core.flags & VALIDATING)
	entryPtr->core.flags |= VALIDATION_SET_VALUE;

    /* Make sure all indices remain in bounds:
     */
    if (numChars < entryPtr->entry.numChars)
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845

/* InsertChars --
 *	Add new characters to an entry widget.
 */
static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    TkSizeT index,			/* Insert before this index */
    const char *value)		/* New characters to add */
{
    char *string = entryPtr->entry.string;
    size_t byteIndex = Tcl_UtfAtIndex(string, index) - string;
    size_t byteCount = strlen(value);
    int charsAdded = Tcl_NumUtfChars(value, byteCount);
    size_t newByteCount = entryPtr->entry.numBytes + byteCount + 1;







|







837
838
839
840
841
842
843
844
845
846
847
848
849
850
851

/* InsertChars --
 *	Add new characters to an entry widget.
 */
static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    Tcl_Size index,			/* Insert before this index */
    const char *value)		/* New characters to add */
{
    char *string = entryPtr->entry.string;
    size_t byteIndex = Tcl_UtfAtIndex(string, index) - string;
    size_t byteCount = strlen(value);
    int charsAdded = Tcl_NumUtfChars(value, byteCount);
    size_t newByteCount = entryPtr->entry.numBytes + byteCount + 1;
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899

/* DeleteChars --
 *	Remove one or more characters from an entry widget.
 */
static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    TkSizeT index,			/* Index of first character to delete. */
    TkSizeT count)			/* How many characters to delete. */
{
    char *string = entryPtr->entry.string;
    size_t byteIndex, byteCount, newByteCount;
    char *newBytes;
    int code;

    if (index == TCL_INDEX_NONE) {
	index = 0;
    }
    if (count + index + 1 > entryPtr->entry.numChars + 1) {
	count = entryPtr->entry.numChars - index;
    }
    if (count + 1 <= 1) {
	return TCL_OK;
    }

    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string+byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->entry.numBytes + 1 - byteCount;







|
|






|


|


|







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905

/* DeleteChars --
 *	Remove one or more characters from an entry widget.
 */
static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    Tcl_Size index,			/* Index of first character to delete. */
    Tcl_Size count)			/* How many characters to delete. */
{
    char *string = entryPtr->entry.string;
    size_t byteIndex, byteCount, newByteCount;
    char *newBytes;
    int code;

    if (index < 0) {
	index = 0;
    }
    if (count + index  > entryPtr->entry.numChars) {
	count = entryPtr->entry.numChars - index;
    }
    if (count <= 0) {
	return TCL_OK;
    }

    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string+byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->entry.numBytes + 1 - byteCount;
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935

/* EntryEventProc --
 *	Extra event handling for entry widgets:
 *	Triggers validation on FocusIn and FocusOut events.
 */
#define EntryEventMask (FocusChangeMask)
static void
EntryEventProc(ClientData clientData, XEvent *eventPtr)
{
    Entry *entryPtr = (Entry *)clientData;

    Tcl_Preserve(clientData);
    switch (eventPtr->type) {
	case DestroyNotify:
	    Tk_DeleteEventHandler(entryPtr->core.tkwin,







|







927
928
929
930
931
932
933
934
935
936
937
938
939
940
941

/* EntryEventProc --
 *	Extra event handling for entry widgets:
 *	Triggers validation on FocusIn and FocusOut events.
 */
#define EntryEventMask (FocusChangeMask)
static void
EntryEventProc(void *clientData, XEvent *eventPtr)
{
    Entry *entryPtr = (Entry *)clientData;

    Tcl_Preserve(clientData);
    switch (eventPtr->type) {
	case DestroyNotify:
	    Tk_DeleteEventHandler(entryPtr->core.tkwin,
946
947
948
949
950
951
952
953


954
955
956
957
958
959
960
961
962
963
}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup.
 */

static void
EntryInitialize(Tcl_Interp *dummy, void *recordPtr)


{
    Entry *entryPtr = (Entry *)recordPtr;
    (void)dummy;

    Tk_CreateEventHandler(
	entryPtr->core.tkwin, EntryEventMask, EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->core.tkwin, XA_PRIMARY, XA_STRING,
	EntryFetchSelection, entryPtr, XA_STRING);
    TtkBlinkCursor(&entryPtr->core);








|
>
>


<







952
953
954
955
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup.
 */

static void
EntryInitialize(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr)
{
    Entry *entryPtr = (Entry *)recordPtr;


    Tk_CreateEventHandler(
	entryPtr->core.tkwin, EntryEventMask, EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->core.tkwin, XA_PRIMARY, XA_STRING,
	EntryFetchSelection, entryPtr, XA_STRING);
    TtkBlinkCursor(&entryPtr->core);

1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
	if (entryPtr->entry.textVariableTrace)
	    Ttk_UntraceVariable(entryPtr->entry.textVariableTrace);
	entryPtr->entry.textVariableTrace = vt;
    }

    /* Claim the selection, in case we've suddenly started exporting it.
     */
    if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != TCL_INDEX_NONE)
	    && (!Tcl_IsSafe(entryPtr->core.interp))) {
	EntryOwnSelection(entryPtr);
    }

    /* Handle -state compatibility option:
     */
    if (mask & STATE_CHANGED) {







|







1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
	if (entryPtr->entry.textVariableTrace)
	    Ttk_UntraceVariable(entryPtr->entry.textVariableTrace);
	entryPtr->entry.textVariableTrace = vt;
    }

    /* Claim the selection, in case we've suddenly started exporting it.
     */
    if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst >= 0)
	    && (!Tcl_IsSafe(entryPtr->core.interp))) {
	EntryOwnSelection(entryPtr);
    }

    /* Handle -state compatibility option:
     */
    if (mask & STATE_CHANGED) {
1062
1063
1064
1065
1066
1067
1068
1069



1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
    EntryUpdateTextLayout(entryPtr);
    return TCL_OK;
}

/* EntryPostConfigure --
 * 	Post-configuration hook for entry widgets.
 */
static int EntryPostConfigure(Tcl_Interp *dummy, void *recordPtr, int mask)



{
    Entry *entryPtr = (Entry *)recordPtr;
    int status = TCL_OK;
    (void)dummy;

    if ((mask & TEXTVAR_CHANGED) && entryPtr->entry.textVariableTrace != NULL) {
	status = Ttk_FireTrace(entryPtr->entry.textVariableTrace);
    }

    return status;
}

/*------------------------------------------------------------------------
 * +++ Layout and display.
 */

/* EntryCharPosition --
 * 	Return the X coordinate of the specified character index.
 * 	Precondition: textLayout and layoutX up-to-date.
 */
static int
EntryCharPosition(Entry *entryPtr, TkSizeT index)
{
    int xPos;
    Tk_CharBbox(entryPtr->entry.textLayout, index, &xPos, NULL, NULL, NULL);
    return xPos + entryPtr->entry.layoutX;
}

/* EntryDoLayout --







|
>
>
>



<

















|







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
    EntryUpdateTextLayout(entryPtr);
    return TCL_OK;
}

/* EntryPostConfigure --
 * 	Post-configuration hook for entry widgets.
 */
static int EntryPostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr,
    int mask)
{
    Entry *entryPtr = (Entry *)recordPtr;
    int status = TCL_OK;


    if ((mask & TEXTVAR_CHANGED) && entryPtr->entry.textVariableTrace != NULL) {
	status = Ttk_FireTrace(entryPtr->entry.textVariableTrace);
    }

    return status;
}

/*------------------------------------------------------------------------
 * +++ Layout and display.
 */

/* EntryCharPosition --
 * 	Return the X coordinate of the specified character index.
 * 	Precondition: textLayout and layoutX up-to-date.
 */
static int
EntryCharPosition(Entry *entryPtr, Tcl_Size index)
{
    int xPos;
    Tk_CharBbox(entryPtr->entry.textLayout, index, &xPos, NULL, NULL, NULL);
    return xPos + entryPtr->entry.layoutX;
}

/* EntryDoLayout --
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
/* EntryDisplay --
 *	Redraws the contents of an entry window.
 */
static void EntryDisplay(void *clientData, Drawable d)
{
    Entry *entryPtr = (Entry *)clientData;
    Tk_Window tkwin = entryPtr->core.tkwin;
    TkSizeT leftIndex = entryPtr->entry.xscroll.first,
	rightIndex = entryPtr->entry.xscroll.last + 1,
	selFirst = entryPtr->entry.selectFirst,
	selLast = entryPtr->entry.selectLast;
    EntryStyleData es;
    GC gc;
    int showSelection, showCursor;
    Ttk_Box textarea;
    TkRegion clipRegion;
    XRectangle rect;
    Tcl_Obj *foregroundObj;

    EntryInitStyleData(entryPtr, &es);

    textarea = Ttk_ClientRegion(entryPtr->core.layout, "textarea");
    showCursor =
	   (entryPtr->core.flags & CURSOR_ON)
	&& EntryEditable(entryPtr)
	&& entryPtr->entry.insertPos + 1 >= leftIndex + 1
	&& entryPtr->entry.insertPos + 1 <= rightIndex + 1
	;
    showSelection =
	   !(entryPtr->core.state & TTK_STATE_DISABLED)
	&& selFirst != TCL_INDEX_NONE
	&& selLast + 1 > leftIndex + 1
	&& selFirst + 1 <= rightIndex + 1;

    /* Adjust selection range to keep in display bounds.
     */
    if (showSelection) {
	if (selFirst + 1 < leftIndex + 1)
	    selFirst = leftIndex;
	if (selLast + 1 > rightIndex + 1)
	    selLast = rightIndex;
    }

    /* Draw widget background & border
     */
    Ttk_DrawLayout(entryPtr->core.layout, entryPtr->core.state, d);








|

















|
|



|
|
|




|

|







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
/* EntryDisplay --
 *	Redraws the contents of an entry window.
 */
static void EntryDisplay(void *clientData, Drawable d)
{
    Entry *entryPtr = (Entry *)clientData;
    Tk_Window tkwin = entryPtr->core.tkwin;
    Tcl_Size leftIndex = entryPtr->entry.xscroll.first,
	rightIndex = entryPtr->entry.xscroll.last + 1,
	selFirst = entryPtr->entry.selectFirst,
	selLast = entryPtr->entry.selectLast;
    EntryStyleData es;
    GC gc;
    int showSelection, showCursor;
    Ttk_Box textarea;
    TkRegion clipRegion;
    XRectangle rect;
    Tcl_Obj *foregroundObj;

    EntryInitStyleData(entryPtr, &es);

    textarea = Ttk_ClientRegion(entryPtr->core.layout, "textarea");
    showCursor =
	   (entryPtr->core.flags & CURSOR_ON)
	&& EntryEditable(entryPtr)
	&& entryPtr->entry.insertPos >= leftIndex
	&& entryPtr->entry.insertPos <= rightIndex
	;
    showSelection =
	   !(entryPtr->core.state & TTK_STATE_DISABLED)
	&& selFirst >= 0
	&& selLast > leftIndex
	&& selFirst <= rightIndex;

    /* Adjust selection range to keep in display bounds.
     */
    if (showSelection) {
	if (selFirst < leftIndex)
	    selFirst = leftIndex;
	if (selLast > rightIndex)
	    selLast = rightIndex;
    }

    /* Draw widget background & border
     */
    Ttk_DrawLayout(entryPtr->core.layout, entryPtr->core.state, d);

1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
     */
    if ((*(entryPtr->entry.displayString) == '\0')
		&& (entryPtr->entry.placeholderObj != NULL)) {
	/* No text displayed, but -placeholder is given */
	if (Tcl_GetCharLength(es.placeholderForegroundObj) > 0) {
	    foregroundObj = es.placeholderForegroundObj;
	} else {
            foregroundObj = es.foregroundObj;
	}
	/* Use placeholder text width */
	leftIndex = 0;
	(void)TkGetStringFromObj(entryPtr->entry.placeholderObj, &rightIndex);
    } else {
	foregroundObj = es.foregroundObj;
    }
    gc = EntryGetGC(entryPtr, foregroundObj, clipRegion);
    if (showSelection) {

        /* Draw the selected and unselected portions separately.







|



|







1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
     */
    if ((*(entryPtr->entry.displayString) == '\0')
		&& (entryPtr->entry.placeholderObj != NULL)) {
	/* No text displayed, but -placeholder is given */
	if (Tcl_GetCharLength(es.placeholderForegroundObj) > 0) {
	    foregroundObj = es.placeholderForegroundObj;
	} else {
	    foregroundObj = es.foregroundObj;
	}
	/* Use placeholder text width */
	leftIndex = 0;
	(void)Tcl_GetStringFromObj(entryPtr->entry.placeholderObj, &rightIndex);
    } else {
	foregroundObj = es.foregroundObj;
    }
    gc = EntryGetGC(entryPtr, foregroundObj, clipRegion);
    if (showSelection) {

        /* Draw the selected and unselected portions separately.
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
 *	error occurs then an error message is left in the interp's result.
 */
static int
EntryIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Entry *entryPtr,		/* Entry widget to query */
    Tcl_Obj *indexObj,		/* Symbolic index name */
    TkSizeT *indexPtr)		/* Return value */
{
#   define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
    TkSizeT length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->entry.numChars - 1, 1, &idx)) {


    	if ((idx != TCL_INDEX_NONE) && (idx > entryPtr->entry.numChars)) {
    	    idx = entryPtr->entry.numChars;
    	}
    	*indexPtr = idx;
    	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);

    if (strncmp(string, "insert", length) == 0) {
	*indexPtr = entryPtr->entry.insertPos;
    } else if (strncmp(string, "left", length) == 0) {	/* for debugging */
	*indexPtr = entryPtr->entry.xscroll.first;
    } else if (strncmp(string, "right", length) == 0) {	/* for debugging */
	*indexPtr = entryPtr->entry.xscroll.last;
    } else if (strncmp(string, "sel.", 4) == 0) {
	if (entryPtr->entry.selectFirst == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->core.tkwin)));
	    Tcl_SetErrorCode(interp, "TTK", "ENTRY", "NO_SELECTION", NULL);
	    return TCL_ERROR;
	}
	if (strncmp(string, "sel.first", length) == 0) {







|


|



>
>
|
|
|
|
|


|








|







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
 *	error occurs then an error message is left in the interp's result.
 */
static int
EntryIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Entry *entryPtr,		/* Entry widget to query */
    Tcl_Obj *indexObj,		/* Symbolic index name */
    Tcl_Size *indexPtr)		/* Return value */
{
#   define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
    Tcl_Size length, idx;
    const char *string;

    if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->entry.numChars - 1, 1, &idx)) {
	if (idx < 0) {
	    idx = 0;
	} else if (idx > entryPtr->entry.numChars) {
	    idx = entryPtr->entry.numChars;
	}
	*indexPtr = idx;
	return TCL_OK;
    }

    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;
    } else if (strncmp(string, "sel.", 4) == 0) {
	if (entryPtr->entry.selectFirst < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->core.tkwin)));
	    Tcl_SetErrorCode(interp, "TTK", "ENTRY", "NO_SELECTION", NULL);
	    return TCL_ERROR;
	}
	if (strncmp(string, "sel.first", length) == 0) {
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
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
	    x = maxWidth;
	    roundUp = 1;
	}
	*indexPtr = Tk_PointToChar(entryPtr->entry.textLayout,
		x - entryPtr->entry.layoutX, 0);

        TtkUpdateScrollInfo(entryPtr->entry.xscrollHandle);
	if (*indexPtr + 1 < (TkSizeT)entryPtr->entry.xscroll.first + 1) {
	    *indexPtr = entryPtr->entry.xscroll.first;
	}

	/*
	 * Special trick:  if the x-position was off-screen to the right,
	 * round the index up to refer to the character just after the
	 * last visible one on the screen.  This is needed to enable the
	 * last character to be selected, for example.
	 */

	if (roundUp && ((TkSizeT)*indexPtr + 1 < entryPtr->entry.numChars + 1 )) {
	    *indexPtr += 1;
	}
    } else {
	goto badIndex;
    }
    return TCL_OK;

badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TTK", "ENTRY", "INDEX", NULL);
    return TCL_ERROR;
}

/* $entry bbox $index --
 * 	Return the bounding box of the character at the specified index.
 */
static int
EntryBBoxCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    Ttk_Box b;
    TkSizeT index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "index");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if ((index == entryPtr->entry.numChars) && (index + 1 > 1)) {
	index--;
    }
    Tk_CharBbox(entryPtr->entry.textLayout, index,
	    &b.x, &b.y, &b.width, &b.height);
    b.x += entryPtr->entry.layoutX;
    b.y += entryPtr->entry.layoutY;
    Tcl_SetObjResult(interp, Ttk_NewBoxObj(b));
    return TCL_OK;
}

/* $entry delete $from ?$to? --
 *	Delete the characters in the range [$from,$to).
 *	$to defaults to $from+1 if not specified.
 */
static int
EntryDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    TkSizeT first, last;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &first) != TCL_OK) {
	return TCL_ERROR;
    }
    if (objc == 3) {
	last = first + 1;
    } else if (EntryIndex(interp, entryPtr, objv[3], &last) != TCL_OK) {
	return TCL_ERROR;
    }

    if (last + 1 >= first + 1 && EntryEditable(entryPtr)) {
	return DeleteChars(entryPtr, first, last - first);
    }
    return TCL_OK;
}

/* $entry get --
 * 	Return the current value of the entry widget.
 */
static int
EntryGetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->entry.string, -1));
    return TCL_OK;
}

/* $entry icursor $index --
 * 	Set the insert cursor position.
 */
static int
EntryICursorCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "pos");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2],
	    &entryPtr->entry.insertPos) != TCL_OK) {
	return TCL_ERROR;
    }
    TtkRedisplayWidget(&entryPtr->core);
    return TCL_OK;
}

/* $entry index $index --
 * 	Return numeric value (0..numChars) of the specified index.
 */
static int
EntryIndexCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    TkSizeT index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "string");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkNewIndexObj(index));
    return TCL_OK;
}

/* $entry insert $index $text --
 * 	Insert $text after position $index.
 * 	Silent no-op if the entry is disabled or read-only.
 */
static int
EntryInsertCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    TkSizeT index;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "index text");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (EntryEditable(entryPtr)) {
	return InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
    }
    return TCL_OK;
}

/* $entry selection clear --
 * 	Clear selection.
 */
static int EntrySelectionClearCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    TtkRedisplayWidget(&entryPtr->core);
    return TCL_OK;
}

/* $entry selection present --
 * 	Returns 1 if any characters are selected, 0 otherwise.
 */
static int EntrySelectionPresentCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewWideIntObj(entryPtr->entry.selectFirst != TCL_INDEX_NONE));
    return TCL_OK;
}

/* $entry selection range $start $end --
 * 	Explicitly set the selection range.
 */
static int EntrySelectionRangeCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    TkSizeT start, end;
    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "start end");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[3], &start) != TCL_OK
         || EntryIndex(interp, entryPtr, objv[4], &end) != TCL_OK) {
	return TCL_ERROR;
    }
    if (entryPtr->core.state & TTK_STATE_DISABLED) {
	return TCL_OK;
    }

    if (start + 1 >= end + 1 ) {
	entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    } else {
	entryPtr->entry.selectFirst = start;
	entryPtr->entry.selectLast = end;
	EntryOwnSelection(entryPtr);
    }
    TtkRedisplayWidget(&entryPtr->core);







|










|



















|



|








|
















|


|














|










|















|



















|


|


















|


|


















|
















|







|







|


|












|







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
	    x = maxWidth;
	    roundUp = 1;
	}
	*indexPtr = Tk_PointToChar(entryPtr->entry.textLayout,
		x - entryPtr->entry.layoutX, 0);

        TtkUpdateScrollInfo(entryPtr->entry.xscrollHandle);
	if (*indexPtr < entryPtr->entry.xscroll.first) {
	    *indexPtr = entryPtr->entry.xscroll.first;
	}

	/*
	 * Special trick:  if the x-position was off-screen to the right,
	 * round the index up to refer to the character just after the
	 * last visible one on the screen.  This is needed to enable the
	 * last character to be selected, for example.
	 */

	if (roundUp && (*indexPtr < entryPtr->entry.numChars)) {
	    *indexPtr += 1;
	}
    } else {
	goto badIndex;
    }
    return TCL_OK;

badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TTK", "ENTRY", "INDEX", NULL);
    return TCL_ERROR;
}

/* $entry bbox $index --
 * 	Return the bounding box of the character at the specified index.
 */
static int
EntryBBoxCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    Ttk_Box b;
    Tcl_Size index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "index");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if ((index == entryPtr->entry.numChars) && (index > 0)) {
	index--;
    }
    Tk_CharBbox(entryPtr->entry.textLayout, index,
	    &b.x, &b.y, &b.width, &b.height);
    b.x += entryPtr->entry.layoutX;
    b.y += entryPtr->entry.layoutY;
    Tcl_SetObjResult(interp, Ttk_NewBoxObj(b));
    return TCL_OK;
}

/* $entry delete $from ?$to? --
 *	Delete the characters in the range [$from,$to).
 *	$to defaults to $from+1 if not specified.
 */
static int
EntryDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    Tcl_Size first, last;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &first) != TCL_OK) {
	return TCL_ERROR;
    }
    if (objc == 3) {
	last = first + 1;
    } else if (EntryIndex(interp, entryPtr, objv[3], &last) != TCL_OK) {
	return TCL_ERROR;
    }

    if (last >= first && EntryEditable(entryPtr)) {
	return DeleteChars(entryPtr, first, last - first);
    }
    return TCL_OK;
}

/* $entry get --
 * 	Return the current value of the entry widget.
 */
static int
EntryGetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->entry.string, -1));
    return TCL_OK;
}

/* $entry icursor $index --
 * 	Set the insert cursor position.
 */
static int
EntryICursorCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "pos");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2],
	    &entryPtr->entry.insertPos) != TCL_OK) {
	return TCL_ERROR;
    }
    TtkRedisplayWidget(&entryPtr->core);
    return TCL_OK;
}

/* $entry index $index --
 * 	Return numeric value (0..numChars) of the specified index.
 */
static int
EntryIndexCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    Tcl_Size index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "string");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TkNewIndexObj(index));
    return TCL_OK;
}

/* $entry insert $index $text --
 * 	Insert $text after position $index.
 * 	Silent no-op if the entry is disabled or read-only.
 */
static int
EntryInsertCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    Tcl_Size index;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "index text");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (EntryEditable(entryPtr)) {
	return InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
    }
    return TCL_OK;
}

/* $entry selection clear --
 * 	Clear selection.
 */
static int EntrySelectionClearCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    TtkRedisplayWidget(&entryPtr->core);
    return TCL_OK;
}

/* $entry selection present --
 * 	Returns 1 if any characters are selected, 0 otherwise.
 */
static int EntrySelectionPresentCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewWideIntObj(entryPtr->entry.selectFirst >= 0));
    return TCL_OK;
}

/* $entry selection range $start $end --
 * 	Explicitly set the selection range.
 */
static int EntrySelectionRangeCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    Tcl_Size start, end;
    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "start end");
	return TCL_ERROR;
    }
    if (EntryIndex(interp, entryPtr, objv[3], &start) != TCL_OK
         || EntryIndex(interp, entryPtr, objv[4], &end) != TCL_OK) {
	return TCL_ERROR;
    }
    if (entryPtr->core.state & TTK_STATE_DISABLED) {
	return TCL_OK;
    }

    if (start >= end) {
	entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    } else {
	entryPtr->entry.selectFirst = start;
	entryPtr->entry.selectLast = end;
	EntryOwnSelection(entryPtr);
    }
    TtkRedisplayWidget(&entryPtr->core);
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
    { 0,0,0 }
};

/* $entry set $value
 * 	Sets the value of an entry widget.
 */
static int EntrySetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "value");
	return TCL_ERROR;
    }
    EntrySetValue(entryPtr, Tcl_GetString(objv[2]));
    return TCL_OK;
}

/* $entry validate --
 * 	Trigger forced validation.  Returns 1/0 if validation succeeds/fails
 * 	or error status from -validatecommand / -invalidcommand.
 */
static int EntryValidateCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    int code;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, NULL);
	return TCL_ERROR;







|















|







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
    { 0,0,0 }
};

/* $entry set $value
 * 	Sets the value of an entry widget.
 */
static int EntrySetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "value");
	return TCL_ERROR;
    }
    EntrySetValue(entryPtr, Tcl_GetString(objv[2]));
    return TCL_OK;
}

/* $entry validate --
 * 	Trigger forced validation.  Returns 1/0 if validation succeeds/fails
 * 	or error status from -validatecommand / -invalidcommand.
 */
static int EntryValidateCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    int code;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, NULL);
	return TCL_ERROR;
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
    return TCL_OK;
}

/* $entry xview	-- horizontal scrolling interface
 */
static int EntryXViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc == 3) {
	TkSizeT newFirst;
	if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
	TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst, 1);
	return TCL_OK;
    }
    return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);







|



|







1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
    return TCL_OK;
}

/* $entry xview	-- horizontal scrolling interface
 */
static int EntryXViewCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Entry *entryPtr = (Entry *)recordPtr;
    if (objc == 3) {
	Tcl_Size newFirst;
	if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
	TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst, 1);
	return TCL_OK;
    }
    return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
    { "icursor", 	EntryICursorCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "index", 		EntryIndexCommand,0 },
    { "insert", 	EntryInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "selection", 	0,EntrySelectionCommands },
    { "state",  	TtkWidgetStateCommand,0 },

    { "validate", 	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Entry widget definition.







>







1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
    { "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.
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
 * +++ Combobox widget record.
 */

typedef struct {
    Tcl_Obj	*postCommandObj;
    Tcl_Obj	*valuesObj;
    Tcl_Obj	*heightObj;
    TkSizeT	currentIndex;
} ComboboxPart;

typedef struct {
    WidgetCore core;
    EntryPart entry;
    ComboboxPart combobox;
} Combobox;







|







1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
 * +++ Combobox widget record.
 */

typedef struct {
    Tcl_Obj	*postCommandObj;
    Tcl_Obj	*valuesObj;
    Tcl_Obj	*heightObj;
    Tcl_Size	currentIndex;
} ComboboxPart;

typedef struct {
    WidgetCore core;
    EntryPart entry;
    ComboboxPart combobox;
} Combobox;
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
/* ComboboxConfigure --
 * 	Configuration hook for combobox widgets.
 */
static int
ComboboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Combobox *cbPtr = (Combobox *)recordPtr;
    int unused;

    /* Make sure -values is a valid list:
     */
    if (Tcl_ListObjLength(interp,cbPtr->combobox.valuesObj,&unused) != TCL_OK)
	return TCL_ERROR;

    return EntryConfigure(interp, recordPtr, mask);
}

/* $cb current ?newIndex? -- get or set current index.
 * 	Setting the current index updates the combobox value,
 * 	but the value and -values may be changed independently
 * 	of the index.  Instead of trying to keep currentIndex
 * 	in sync at all times, [$cb current] double-checks
 */
static int ComboboxCurrentCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Combobox *cbPtr = (Combobox *)recordPtr;
    TkSizeT currentIndex = cbPtr->combobox.currentIndex;
    const char *currentValue = cbPtr->entry.string;
    int nValues;
    Tcl_Obj **values;

    Tcl_ListObjGetElements(interp, cbPtr->combobox.valuesObj, &nValues, &values);

    if (objc == 2) {
	/* Check if currentIndex still valid:
	 */
	if (currentIndex == TCL_INDEX_NONE
	     || currentIndex >= (TkSizeT)nValues
	     || strcmp(currentValue,Tcl_GetString(values[currentIndex]))
	   )
	{
	    /* Not valid.  Check current value against each element in -values:
	     */
	    for (currentIndex = 0; currentIndex < (TkSizeT)nValues; ++currentIndex) {
		if (!strcmp(currentValue,Tcl_GetString(values[currentIndex]))) {
		    break;
		}
	    }
	    if (currentIndex >= (TkSizeT)nValues) {
		/* Not found */
		currentIndex = TCL_INDEX_NONE;
	    }
	}
	cbPtr->combobox.currentIndex = currentIndex;
	Tcl_SetObjResult(interp, TkNewIndexObj(currentIndex));
	return TCL_OK;
    } else if (objc == 3) {
	TkSizeT idx;

	if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, 0, &idx)) {
	    if (idx == TCL_INDEX_NONE || idx > (TkSizeT)nValues) {
	        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		        "index \"%s\" out of range", Tcl_GetString(objv[2])));
	        Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_RANGE", NULL);
	        return TCL_ERROR;
	    }
	    currentIndex = idx;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Incorrect index %s", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_VALUE", NULL);
	    return TCL_ERROR;
	}

	cbPtr->combobox.currentIndex = currentIndex;

	return EntrySetValue((Entry *)recordPtr, Tcl_GetString(values[currentIndex]));







|
















|


|

|







|
|





|




|








|


|








|







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
/* ComboboxConfigure --
 * 	Configuration hook for combobox widgets.
 */
static int
ComboboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Combobox *cbPtr = (Combobox *)recordPtr;
    Tcl_Size unused;

    /* Make sure -values is a valid list:
     */
    if (Tcl_ListObjLength(interp,cbPtr->combobox.valuesObj,&unused) != TCL_OK)
	return TCL_ERROR;

    return EntryConfigure(interp, recordPtr, mask);
}

/* $cb current ?newIndex? -- get or set current index.
 * 	Setting the current index updates the combobox value,
 * 	but the value and -values may be changed independently
 * 	of the index.  Instead of trying to keep currentIndex
 * 	in sync at all times, [$cb current] double-checks
 */
static int ComboboxCurrentCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Combobox *cbPtr = (Combobox *)recordPtr;
    Tcl_Size currentIndex = cbPtr->combobox.currentIndex;
    const char *currentValue = cbPtr->entry.string;
    Tcl_Size nValues;
    Tcl_Obj **values;

    Tcl_ListObjGetElements(interp, cbPtr->combobox.valuesObj, &nValues, &values);

    if (objc == 2) {
	/* Check if currentIndex still valid:
	 */
	if (currentIndex < 0
	     || currentIndex >= nValues
	     || strcmp(currentValue,Tcl_GetString(values[currentIndex]))
	   )
	{
	    /* Not valid.  Check current value against each element in -values:
	     */
	    for (currentIndex = 0; currentIndex < nValues; ++currentIndex) {
		if (!strcmp(currentValue,Tcl_GetString(values[currentIndex]))) {
		    break;
		}
	    }
	    if (currentIndex >= nValues) {
		/* Not found */
		currentIndex = TCL_INDEX_NONE;
	    }
	}
	cbPtr->combobox.currentIndex = currentIndex;
	Tcl_SetObjResult(interp, TkNewIndexObj(currentIndex));
	return TCL_OK;
    } else if (objc == 3) {
	Tcl_Size idx;

	if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, 0, &idx)) {
	    if (idx < 0 || idx >= nValues) {
	        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		        "index \"%s\" out of range", Tcl_GetString(objv[2])));
	        Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_RANGE", NULL);
	        return TCL_ERROR;
	    }
	    currentIndex = idx;
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad index \"%s\"", Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_VALUE", NULL);
	    return TCL_ERROR;
	}

	cbPtr->combobox.currentIndex = currentIndex;

	return EntrySetValue((Entry *)recordPtr, Tcl_GetString(values[currentIndex]));
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1923
1924
    { "get", 		EntryGetCommand,0 },
    { "icursor", 	EntryICursorCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "index", 		EntryIndexCommand,0 },
    { "insert", 	EntryInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "selection", 	0,EntrySelectionCommands },

    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ComboboxWidgetSpec = {
    "TCombobox",		/* className */







>

|







1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
    { "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 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ComboboxWidgetSpec = {
    "TCombobox",		/* className */
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979

static const Tk_OptionSpec SpinboxOptionSpecs[] = {
    {TK_OPTION_STRING, "-values", "values", "Values",
        "", offsetof(Spinbox, spinbox.valuesObj), TCL_INDEX_NONE,
	0,0,0 },

    {TK_OPTION_DOUBLE, "-from", "from", "From",
	"0", offsetof(Spinbox,spinbox.fromObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	"0", offsetof(Spinbox,spinbox.toObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	"1", offsetof(Spinbox,spinbox.incrementObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-format", "format", "Format",
	"", offsetof(Spinbox, spinbox.formatObj), TCL_INDEX_NONE,
	0,0,0 },

    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Spinbox, spinbox.commandObj), TCL_INDEX_NONE,







|


|


|







1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992

static const Tk_OptionSpec SpinboxOptionSpecs[] = {
    {TK_OPTION_STRING, "-values", "values", "Values",
        "", offsetof(Spinbox, spinbox.valuesObj), TCL_INDEX_NONE,
	0,0,0 },

    {TK_OPTION_DOUBLE, "-from", "from", "From",
	"0.0", offsetof(Spinbox,spinbox.fromObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	"0.0", offsetof(Spinbox,spinbox.toObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	"1.0", offsetof(Spinbox,spinbox.incrementObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-format", "format", "Format",
	"", offsetof(Spinbox, spinbox.formatObj), TCL_INDEX_NONE,
	0,0,0 },

    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Spinbox, spinbox.commandObj), TCL_INDEX_NONE,
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
/* SpinboxConfigure --
 * 	Configuration hook for spinbox widgets.
 */
static int
SpinboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Spinbox *sb = (Spinbox *)recordPtr;
    int unused;

    /* Make sure -values is a valid list:
     */
    if (Tcl_ListObjLength(interp,sb->spinbox.valuesObj,&unused) != TCL_OK)
	return TCL_ERROR;

    return EntryConfigure(interp, recordPtr, mask);







|







2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
/* SpinboxConfigure --
 * 	Configuration hook for spinbox widgets.
 */
static int
SpinboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
    Spinbox *sb = (Spinbox *)recordPtr;
    Tcl_Size unused;

    /* Make sure -values is a valid list:
     */
    if (Tcl_ListObjLength(interp,sb->spinbox.valuesObj,&unused) != TCL_OK)
	return TCL_ERROR;

    return EntryConfigure(interp, recordPtr, mask);
2021
2022
2023
2024
2025
2026
2027

2028
2029
2030
2031
2032
2033
2034
2035
2036
    { "get", 		EntryGetCommand,0 },
    { "icursor", 	EntryICursorCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "index", 		EntryIndexCommand,0 },
    { "insert", 	EntryInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "selection", 	0,EntrySelectionCommands },

    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec SpinboxWidgetSpec = {
    "TSpinbox",			/* className */







>

|







2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
    { "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 },
    { "style",		TtkWidgetStyleCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec SpinboxWidgetSpec = {
    "TSpinbox",			/* className */
2064
2065
2066
2067
2068
2069
2070

2071

2072


2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
	offsetof(TextareaElement,fontObj), DEF_ENTRY_FONT },
    { "-width", TK_OPTION_INT,
	offsetof(TextareaElement,widthObj), "20" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TextareaElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    TextareaElement *textarea = (TextareaElement *)elementRecord;
    Tk_Font font = Tk_GetFontFromObj(tkwin, textarea->fontObj);
    int avgWidth = Tk_TextWidth(font, "0", 1);
    Tk_FontMetrics fm;
    int prefWidth = 1;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetFontMetrics(font, &fm);
    Tcl_GetIntFromObj(NULL, textarea->widthObj, &prefWidth);
    if (prefWidth <= 0)
	prefWidth = 1;

    *heightPtr = fm.linespace;







>
|
>
|
>
>






<
<







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
	offsetof(TextareaElement,fontObj), DEF_ENTRY_FONT },
    { "-width", TK_OPTION_INT,
	offsetof(TextareaElement,widthObj), "20" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TextareaElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TextareaElement *textarea = (TextareaElement *)elementRecord;
    Tk_Font font = Tk_GetFontFromObj(tkwin, textarea->fontObj);
    int avgWidth = Tk_TextWidth(font, "0", 1);
    Tk_FontMetrics fm;
    int prefWidth = 1;



    Tk_GetFontMetrics(font, &fm);
    Tcl_GetIntFromObj(NULL, textarea->widthObj, &prefWidth);
    if (prefWidth <= 0)
	prefWidth = 1;

    *heightPtr = fm.linespace;
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
    TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
	TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
	TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
	    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(SpinboxLayout)
     TTK_GROUP("Spinbox.field", TTK_PACK_TOP|TTK_FILL_X,
	 TTK_GROUP("null", TTK_PACK_RIGHT,
	     TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP|TTK_STICK_E)
	     TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E))
	 TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH,
	     TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH)))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */



MODULE_SCOPE
void TtkEntry_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, themePtr, "textarea", &TextareaElementSpec, 0);








|
|
|
|
|
|





>
>
>







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
    TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
	TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
	TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
	    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(SpinboxLayout)
    TTK_GROUP("Spinbox.field", TTK_PACK_TOP|TTK_FILL_X,
	TTK_GROUP("null", TTK_PACK_RIGHT,
	    TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP|TTK_STICK_E)
	    TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E))
	TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH,
	    TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH)))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */
MODULE_SCOPE
void TtkEntry_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkEntry_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, themePtr, "textarea", &TextareaElementSpec, 0);

Changes to generic/ttk/ttkFrame.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::frame and ttk::labelframe widgets.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
#include "ttkManager.h"

/* ======================================================================
 * +++ Frame widget:
 */


|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright © 2004 Joe English
 *
 * ttk::frame and ttk::labelframe widgets.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"
#include "ttkManager.h"

/* ======================================================================
 * +++ Frame widget:
 */

44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
62
	0,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static const Ttk_Ensemble FrameCommands[] = {

    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",   	TtkWidgetCgetCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { 0,0,0 }
};

/*
 * FrameMargins --
 * 	Compute internal margins for a frame widget.
 * 	This includes the -borderWidth, plus any additional -padding.







>

|


|







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 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

/*
 * FrameMargins --
 * 	Compute internal margins for a frame widget.
 * 	This includes the -borderWidth, plus any additional -padding.
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

/* FrameSize procedure --
 * 	The frame doesn't request a size of its own by default,
 * 	but it does have an internal border.  See also <<NOTE-SIZE>>
 */
static int FrameSize(
    void *recordPtr,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *))
{
    Frame *framePtr = (Frame *)recordPtr;
    Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
    return 0;
}

/*







|
|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

/* FrameSize procedure --
 * 	The frame doesn't request a size of its own by default,
 * 	but it does have an internal border.  See also <<NOTE-SIZE>>
 */
static int FrameSize(
    void *recordPtr,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *)) /* heightPtr */
{
    Frame *framePtr = (Frame *)recordPtr;
    Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
    return 0;
}

/*
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

/*
 * Labelframe widget record:
 */
typedef struct {
    Tcl_Obj 	*labelAnchorObj;
    Tcl_Obj	*textObj;
    Tcl_Obj 	*underlineObj;
    Tk_Window	labelWidget;

    Ttk_Manager	*mgr;
    Ttk_Layout	labelLayout;	/* Sublayout for label */
    Ttk_Box	labelParcel;	/* Set in layoutProc */
} LabelframePart;








|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

/*
 * Labelframe widget record:
 */
typedef struct {
    Tcl_Obj 	*labelAnchorObj;
    Tcl_Obj	*textObj;
    Tcl_Obj	*underlineObj;
    Tk_Window	labelWidget;

    Ttk_Manager	*mgr;
    Ttk_Layout	labelLayout;	/* Sublayout for label */
    Ttk_Box	labelParcel;	/* Set in layoutProc */
} LabelframePart;

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
static const Tk_OptionSpec LabelframeOptionSpecs[] = {
    {TK_OPTION_STRING, "-labelanchor", "labelAnchor", "LabelAnchor",
	"nw", offsetof(Labelframe, label.labelAnchorObj),TCL_INDEX_NONE,
        0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Labelframe,label.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	"-1", offsetof(Labelframe,label.underlineObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
	TCL_INDEX_NONE, offsetof(Labelframe,label.labelWidget),
	TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },

    WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
};








|
|
<







254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
static const Tk_OptionSpec LabelframeOptionSpecs[] = {
    {TK_OPTION_STRING, "-labelanchor", "labelAnchor", "LabelAnchor",
	"nw", offsetof(Labelframe, label.labelAnchorObj),TCL_INDEX_NONE,
        0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Labelframe,label.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TTK_OPTION_UNDERLINE_DEF(Labelframe, label.underlineObj), 0},

    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
	TCL_INDEX_NONE, offsetof(Labelframe,label.labelWidget),
	TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },

    WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
};

294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
    if ((objPtr = Ttk_QueryOption(layout, "-padding", 0)) != NULL) {
	Ttk_GetPaddingFromObj(NULL, lf->core.tkwin, objPtr, &style->padding);
    }
    if ((objPtr = Ttk_QueryOption(layout,"-labelanchor", 0)) != NULL) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &style->labelAnchor);
    }
    if ((objPtr = Ttk_QueryOption(layout,"-labelmargins", 0)) != NULL) {

	Ttk_GetBorderFromObj(NULL, objPtr, &style->labelMargins);
    } else {
	if (style->labelAnchor & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
	    style->labelMargins =
		Ttk_MakePadding(DEFAULT_LABELINSET,0,DEFAULT_LABELINSET,0);
	} else {
	    style->labelMargins =
		Ttk_MakePadding(0,DEFAULT_LABELINSET,0,DEFAULT_LABELINSET);







>
|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    if ((objPtr = Ttk_QueryOption(layout, "-padding", 0)) != NULL) {
	Ttk_GetPaddingFromObj(NULL, lf->core.tkwin, objPtr, &style->padding);
    }
    if ((objPtr = Ttk_QueryOption(layout,"-labelanchor", 0)) != NULL) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &style->labelAnchor);
    }
    if ((objPtr = Ttk_QueryOption(layout,"-labelmargins", 0)) != NULL) {
	Ttk_GetPaddingFromObj(NULL, lf->core.tkwin, objPtr,
	    &style->labelMargins);
    } else {
	if (style->labelAnchor & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
	    style->labelMargins =
		Ttk_MakePadding(DEFAULT_LABELINSET,0,DEFAULT_LABELINSET,0);
	} else {
	    style->labelMargins =
		Ttk_MakePadding(0,DEFAULT_LABELINSET,0,DEFAULT_LABELINSET);
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/*
 * LabelframeSize --
 * 	Like the frame, this doesn't request a size of its own
 * 	but it does have internal padding and a minimum size.
 */
static int LabelframeSize(
    void *recordPtr,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *))
{
    Labelframe *lframePtr = (Labelframe *)recordPtr;
    WidgetCore *corePtr = &lframePtr->core;
    Ttk_Padding margins;
    LabelframeStyle style;
    int labelWidth, labelHeight;








|
|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
 * LabelframeSize --
 * 	Like the frame, this doesn't request a size of its own
 * 	but it does have internal padding and a minimum size.
 */
static int LabelframeSize(
    void *recordPtr,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *)) /* heightPtr */
{
    Labelframe *lframePtr = (Labelframe *)recordPtr;
    WidgetCore *corePtr = &lframePtr->core;
    Ttk_Padding margins;
    LabelframeStyle style;
    int labelWidth, labelHeight;

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
	b = lframe->label.labelParcel;
	/* ASSERT: content #0 is lframe->label.labelWidget */
	Ttk_PlaceContent(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
    }
}

static int LabelRequest(
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    return 1;
}

/* LabelRemoved --
 * 	Unset the -labelwidget option.
 *
 * <<NOTE-LABELREMOVED>>:
 * 	This routine is also called when the widget voluntarily forgets
 * 	the window in LabelframeConfigure.
 */
static void LabelRemoved(
    void *managerData,
    TCL_UNUSED(TkSizeT))
{
    Labelframe *lframe = (Labelframe *)managerData;

    lframe->label.labelWidget = 0;
}

static Ttk_ManagerSpec LabelframeManagerSpec = {
    { "labelframe", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    LabelframeSize,
    LabelframePlaceContent,
    LabelRequest,
    LabelRemoved
};








|
|
|
|













|






|







491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
	b = lframe->label.labelParcel;
	/* ASSERT: content #0 is lframe->label.labelWidget */
	Ttk_PlaceContent(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
    }
}

static int LabelRequest(
    TCL_UNUSED(void *), /* managerData */
    TCL_UNUSED(Tcl_Size), /* index */
    TCL_UNUSED(int), /* width */
    TCL_UNUSED(int)) /* height */
{
    return 1;
}

/* LabelRemoved --
 * 	Unset the -labelwidget option.
 *
 * <<NOTE-LABELREMOVED>>:
 * 	This routine is also called when the widget voluntarily forgets
 * 	the window in LabelframeConfigure.
 */
static void LabelRemoved(
    void *managerData,
    TCL_UNUSED(Tcl_Size)) /* index */
{
    Labelframe *lframe = (Labelframe *)managerData;

    lframe->label.labelWidget = 0;
}

static const Ttk_ManagerSpec LabelframeManagerSpec = {
    { "labelframe", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    LabelframeSize,
    LabelframePlaceContent,
    LabelRequest,
    LabelRemoved
};

650
651
652
653
654
655
656



657
658
659
660
661
662
663
664
665
666
667
668
669
	TTK_NODE("Label.text", TTK_FILL_BOTH))
TTK_END_LAYOUT

/* ======================================================================
 * +++ Initialization.
 */




MODULE_SCOPE
void TtkFrame_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TFrame", FrameLayout);
    Ttk_RegisterLayout(theme, "TLabelframe", LabelframeLayout);
    Ttk_RegisterLayout(theme, "Label", LabelSublayout);

    RegisterWidget(interp, "ttk::frame", &FrameWidgetSpec);
    RegisterWidget(interp, "ttk::labelframe", &LabelframeWidgetSpec);
}








>
>
>













651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
	TTK_NODE("Label.text", TTK_FILL_BOTH))
TTK_END_LAYOUT

/* ======================================================================
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkFrame_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkFrame_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TFrame", FrameLayout);
    Ttk_RegisterLayout(theme, "TLabelframe", LabelframeLayout);
    Ttk_RegisterLayout(theme, "Label", LabelSublayout);

    RegisterWidget(interp, "ttk::frame", &FrameWidgetSpec);
    RegisterWidget(interp, "ttk::labelframe", &LabelframeWidgetSpec);
}

Changes to generic/ttk/ttkImage.c.

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
 *
 * 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].
 */




|
|







1
2
3
4
5
6
7
8
9
10
11
12
/*
 *	Image specifications and image element factory.
 *
 * 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].
 */

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

struct TtkImageSpec {
    Tk_Image 		baseImage;	/* Base image to use */
    int 		mapCount;	/* #state-specific overrides */
    Ttk_StateSpec	*states;	/* array[mapCount] of states ... */
    Tk_Image		*images;	/* ... per-state images to use */
    Tk_ImageChangedProc *imageChanged;
    ClientData		imageChangedClientData;
};

/* NullImageChanged --
 * 	Do-nothing Tk_ImageChangedProc.
 */
static void NullImageChanged(ClientData dummy,
    int x, int y, int width, int height, int imageWidth, int imageHeight)







{ /* No-op */
    (void)dummy;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imageWidth;
    (void)imageHeight;
}

/* ImageSpecImageChanged --
 *     Image changes should trigger a repaint.
 */
static void ImageSpecImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{
    Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData;
    if (imageSpec->imageChanged != NULL) {
	imageSpec->imageChanged(imageSpec->imageChangedClientData,
		x, y, width, height,
		imageWidth, imageHeight);







|





|
|
>
>
>
>
>
>
>
|
<
<
<
<
<
<
<





|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43







44
45
46
47
48
49
50
51
52
53
54
55
56

struct TtkImageSpec {
    Tk_Image 		baseImage;	/* Base image to use */
    int 		mapCount;	/* #state-specific overrides */
    Ttk_StateSpec	*states;	/* array[mapCount] of states ... */
    Tk_Image		*images;	/* ... per-state images to use */
    Tk_ImageChangedProc *imageChanged;
    void		*imageChangedClientData;
};

/* NullImageChanged --
 * 	Do-nothing Tk_ImageChangedProc.
 */
static void NullImageChanged(
    TCL_UNUSED(void *),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    /* No-op */







}

/* ImageSpecImageChanged --
 *     Image changes should trigger a repaint.
 */
static void ImageSpecImageChanged(void *clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{
    Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData;
    if (imageSpec->imageChanged != NULL) {
	imageSpec->imageChanged(imageSpec->imageChangedClientData,
		x, y, width, height,
		imageWidth, imageHeight);
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
 * 	Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
 * 	Result must be released using TtkFreeImageSpec.
 * 	imageChangedProc will be called when not NULL when
 * 	the image changes to allow widgets to repaint.
 */
Ttk_ImageSpec *
TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr,
    Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData)
{
    Ttk_ImageSpec *imageSpec = 0;
    int i = 0, n = 0, objc;

    Tcl_Obj **objv;

    imageSpec = (Ttk_ImageSpec *)ckalloc(sizeof(*imageSpec));
    imageSpec->baseImage = 0;
    imageSpec->mapCount = 0;
    imageSpec->states = 0;
    imageSpec->images = 0;







|


|
>







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
 * 	Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
 * 	Result must be released using TtkFreeImageSpec.
 * 	imageChangedProc will be called when not NULL when
 * 	the image changes to allow widgets to repaint.
 */
Ttk_ImageSpec *
TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr,
    Tk_ImageChangedProc *imageChangedProc, void *imageChangedClientData)
{
    Ttk_ImageSpec *imageSpec = 0;
    int i = 0, n = 0;
    Tcl_Size objc;
    Tcl_Obj **objv;

    imageSpec = (Ttk_ImageSpec *)ckalloc(sizeof(*imageSpec));
    imageSpec->baseImage = 0;
    imageSpec->mapCount = 0;
    imageSpec->states = 0;
    imageSpec->images = 0;
160
161
162
163
164
165
166
167



168
169
170
171
172
173
174

    ckfree(imageSpec);
}

/* TtkSelectImage --
 * 	Return a state-specific image from an ImageSpec
 */
Tk_Image TtkSelectImage(Ttk_ImageSpec *imageSpec, Ttk_State state)



{
    int i;
    for (i = 0; i < imageSpec->mapCount; ++i) {
	if (Ttk_StateMatches(state, imageSpec->states+i)) {
	    return imageSpec->images[i];
	}
    }







|
>
>
>







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

    ckfree(imageSpec);
}

/* TtkSelectImage --
 * 	Return a state-specific image from an ImageSpec
 */
Tk_Image TtkSelectImage(
    Ttk_ImageSpec *imageSpec,
    TCL_UNUSED(Tk_Window),
    Ttk_State state)
{
    int i;
    for (i = 0; i < imageSpec->mapCount; ++i) {
	if (Ttk_StateMatches(state, imageSpec->states+i)) {
	    return imageSpec->images[i];
	}
    }
204
205
206
207
208
209
210


211


212
213
214
215
216
217
218
219
220
221
222
223
    { return Ttk_MakeBox(b.x, b.y+b.height-p.bottom, b.width, p.bottom); }

/* Ttk_Fill --
 *	Fill the destination area of the drawable by replicating
 *	the source area of the image.
 */
static void Ttk_Fill(


    Tk_Window tkwin, Drawable d, Tk_Image image, Ttk_Box src, Ttk_Box dst)


{
    int dr = dst.x + dst.width;
    int db = dst.y + dst.height;
    int x,y;
    (void)tkwin;

    if (!(src.width && src.height && dst.width && dst.height))
	return;

    for (x = dst.x; x < dr; x += src.width) {
	int cw = MIN(src.width, dr - x);
	for (y = dst.y; y <= db; y += src.height) {







>
>
|
>
>




<







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
    { return Ttk_MakeBox(b.x, b.y+b.height-p.bottom, b.width, p.bottom); }

/* Ttk_Fill --
 *	Fill the destination area of the drawable by replicating
 *	the source area of the image.
 */
static void Ttk_Fill(
    TCL_UNUSED(Tk_Window),
    Drawable d,
    Tk_Image image,
    Ttk_Box src,
    Ttk_Box dst)
{
    int dr = dst.x + dst.width;
    int db = dst.y + dst.height;
    int x,y;


    if (!(src.width && src.height && dst.width && dst.height))
	return;

    for (x = dst.x; x < dr; x += src.width) {
	int cw = MIN(src.width, dr - x);
	for (y = dst.y; y <= db; y += src.height) {
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*------------------------------------------------------------------------
 * +++ Image element definition.
 */

typedef struct {		/* ClientData for image elements */
    Ttk_ImageSpec *imageSpec;	/* Image(s) to use */
    int minWidth;		/* Minimum width; overrides image width */
    int minHeight;		/* Minimum width; overrides image width */
    Ttk_Sticky sticky;		/* -stickiness specification */
    Ttk_Padding border;		/* Fixed border region */
    Ttk_Padding padding;	/* Internal padding */

#ifdef TILE_07_COMPAT
    Ttk_ResourceCache cache;	/* Resource cache for images */
    Ttk_StateMap imageMap;	/* State-based lookup table for images */







|







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/*------------------------------------------------------------------------
 * +++ Image element definition.
 */

typedef struct {		/* ClientData for image elements */
    Ttk_ImageSpec *imageSpec;	/* Image(s) to use */
    int minWidth;		/* Minimum width; overrides image width */
    int minHeight;		/* Minimum height; overrides image height */
    Ttk_Sticky sticky;		/* -stickiness specification */
    Ttk_Padding border;		/* Fixed border region */
    Ttk_Padding padding;	/* Internal padding */

#ifdef TILE_07_COMPAT
    Ttk_ResourceCache cache;	/* Resource cache for images */
    Ttk_StateMap imageMap;	/* State-based lookup table for images */
276
277
278
279
280
281
282
283


284


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305


306


307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#ifdef TILE_07_COMPAT
    if (imageData->imageMap)	{ Tcl_DecrRefCount(imageData->imageMap); }
#endif
    ckfree(clientData);
}

static void ImageElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ImageData *imageData = (ImageData *)clientData;
    Tk_Image image = imageData->imageSpec->baseImage;
    (void)elementRecord;
    (void)tkwin;

    if (image) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    }
    if (imageData->minWidth >= 0) {
	*widthPtr = imageData->minWidth;
    }
    if (imageData->minHeight >= 0) {
	*heightPtr = imageData->minHeight;
    }

    *paddingPtr = imageData->padding;
}

static void ImageElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)


{
    ImageData *imageData = (ImageData *)clientData;
    Tk_Image image = 0;
    int imgWidth, imgHeight;
    Ttk_Box src, dst;
    (void)elementRecord;

#ifdef TILE_07_COMPAT
    if (imageData->imageMap) {
	Tcl_Obj *imageObj = Ttk_StateMapLookup(NULL,imageData->imageMap,state);
	if (imageObj) {
	    image = Ttk_UseImage(imageData->cache, tkwin, imageObj);
	}
    }
    if (!image) {
	image = TtkSelectImage(imageData->imageSpec, state);
    }
#else
    image = TtkSelectImage(imageData->imageSpec, state);
#endif

    if (!image) {
	return;
    }

    Tk_SizeOfImage(image, &imgWidth, &imgHeight);







|
>
>
|
>
>



<
<















|
>
>
|
>
>





<









|


|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298


299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#ifdef TILE_07_COMPAT
    if (imageData->imageMap)	{ Tcl_DecrRefCount(imageData->imageMap); }
#endif
    ckfree(clientData);
}

static void ImageElementSize(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    ImageData *imageData = (ImageData *)clientData;
    Tk_Image image = imageData->imageSpec->baseImage;



    if (image) {
	Tk_SizeOfImage(image, widthPtr, heightPtr);
    }
    if (imageData->minWidth >= 0) {
	*widthPtr = imageData->minWidth;
    }
    if (imageData->minHeight >= 0) {
	*heightPtr = imageData->minHeight;
    }

    *paddingPtr = imageData->padding;
}

static void ImageElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ImageData *imageData = (ImageData *)clientData;
    Tk_Image image = 0;
    int imgWidth, imgHeight;
    Ttk_Box src, dst;


#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) {
	image = TtkSelectImage(imageData->imageSpec, tkwin, state);
    }
#else
    image = TtkSelectImage(imageData->imageSpec, tkwin, state);
#endif

    if (!image) {
	return;
    }

    Tk_SizeOfImage(image, &imgWidth, &imgHeight);
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

/*------------------------------------------------------------------------
 * +++ Image element factory.
 */
static int
Ttk_CreateImageElement(
    Tcl_Interp *interp,
    void *dummy,
    Ttk_Theme theme,
    const char *elementName,
    int objc, Tcl_Obj *const objv[])
{
    static const char *const optionStrings[] =
	 { "-border","-height","-padding","-sticky","-width",NULL };
    enum { O_BORDER, O_HEIGHT, O_PADDING, O_STICKY, O_WIDTH };

    Ttk_ImageSpec *imageSpec = 0;
    ImageData *imageData = 0;
    int padding_specified = 0;
    int i;
    (void)dummy;

    if (objc <= 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Must supply a base image", -1));
	Tcl_SetErrorCode(interp, "TTK", "IMAGE", "BASE", NULL);
	return TCL_ERROR;
    }

    imageSpec = TtkGetImageSpec(interp, Tk_MainWindow(interp), objv[0]);







|


|








|
<

|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387

/*------------------------------------------------------------------------
 * +++ Image element factory.
 */
static int
Ttk_CreateImageElement(
    Tcl_Interp *interp,
    TCL_UNUSED(void *),
    Ttk_Theme theme,
    const char *elementName,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    static const char *const optionStrings[] =
	 { "-border","-height","-padding","-sticky","-width",NULL };
    enum { O_BORDER, O_HEIGHT, O_PADDING, O_STICKY, O_WIDTH };

    Ttk_ImageSpec *imageSpec = 0;
    ImageData *imageData = 0;
    int padding_specified = 0;
    Tcl_Size i;


    if (objc + 1 < 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Must supply a base image", -1));
	Tcl_SetErrorCode(interp, "TTK", "IMAGE", "BASE", NULL);
	return TCL_ERROR;
    }

    imageSpec = TtkGetImageSpec(interp, Tk_MainWindow(interp), objv[0]);
451
452
453
454
455
456
457



458
459
460
461
462
463
464
    return TCL_OK;

error:
    FreeImageData(imageData);
    return TCL_ERROR;
}




MODULE_SCOPE
void TtkImage_Init(Tcl_Interp *interp)
{
    Ttk_RegisterElementFactory(interp, "image", Ttk_CreateImageElement, NULL);
}

/*EOF*/







>
>
>







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
    return TCL_OK;

error:
    FreeImageData(imageData);
    return TCL_ERROR;
}

MODULE_SCOPE
void TtkImage_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkImage_Init(Tcl_Interp *interp)
{
    Ttk_RegisterElementFactory(interp, "image", Ttk_CreateImageElement, NULL);
}

/*EOF*/

Changes to generic/ttk/ttkInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * Copyright (c) 2003, Joe English
 *
 * Ttk package: initialization routine and miscellaneous utilities.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*
 * Legal values for the button -default option.
 * See also: enum Ttk_ButtonDefaultState.
 */
const char *const ttkDefaultStrings[] = {
    "normal", "active", "disabled", NULL
};

int Ttk_GetButtonDefaultStateFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_ButtonDefaultState *statePtr)
{
    int state = (int)TTK_BUTTON_DEFAULT_DISABLED;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings,
	    sizeof(char *), "default state", 0, &state);

    *statePtr = (Ttk_ButtonDefaultState)state;
    return result;
}

/*
 * Legal values for the -compound option.
 * See also: enum Ttk_Compound.
 */
const char *const ttkCompoundStrings[] = {
    "none", "text", "image", "center",
    "top", "bottom", "left", "right", NULL
};

int Ttk_GetCompoundFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Compound *compoundPtr)
{
    int compound = (int)TTK_COMPOUND_NONE;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings,
	    sizeof(char *), "compound layout", 0, &compound);

    *compoundPtr = (Ttk_Compound)compound;
    return result;
}

/*
 * Legal values for the -orient option.
 * See also: enum Ttk_Orient.
 */
const char *const ttkOrientStrings[] = {
    "horizontal", "vertical", NULL
};

#if !defined(TK_NO_DEPRECATED) && TK_MAJOR_VERSION < 9
int Ttk_GetOrientFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
{
    *resultPtr = TTK_ORIENT_HORIZONTAL;
    return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
	    sizeof(char *), "orientation", 0, resultPtr);
}
#endif

int TtkGetOrientFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Orient *resultPtr)
{
    int orient = (int)TTK_ORIENT_HORIZONTAL;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
    	    sizeof(char *), "orientation", 0, &orient);

    *resultPtr = (Ttk_Orient)orient;
    return result;
}

/*
 * Recognized values for the -state compatibility option.
 * Other options are accepted and interpreted as synonyms for "normal".
 */
static const char *const ttkStateStrings[] = {
    "normal", "readonly", "disabled", "active", NULL
};
enum {
    TTK_COMPAT_STATE_NORMAL,
    TTK_COMPAT_STATE_READONLY,
    TTK_COMPAT_STATE_DISABLED,
    TTK_COMPAT_STATE_ACTIVE
};

/* TtkCheckStateOption --
 * 	Handle -state compatibility option.
 *
 *	NOTE: setting -state disabled / -state enabled affects the
 *	widget state, but the internal widget state does *not* affect
 *	the value of the -state option.
 *	This option is present for compatibility only.
 */
void TtkCheckStateOption(WidgetCore *corePtr, Tcl_Obj *objPtr)
{
    int stateOption = TTK_COMPAT_STATE_NORMAL;
    unsigned all = TTK_STATE_DISABLED|TTK_STATE_READONLY|TTK_STATE_ACTIVE;
#   define SETFLAGS(f) TtkWidgetChangeState(corePtr, f, all^f)

    (void)Tcl_GetIndexFromObjStruct(NULL, objPtr, ttkStateStrings,
	    sizeof(char *), "", 0, &stateOption);
    switch (stateOption) {
	case TTK_COMPAT_STATE_NORMAL:
	default:
	    SETFLAGS(0);
	    break;
	case TTK_COMPAT_STATE_READONLY:
	    SETFLAGS(TTK_STATE_READONLY);

|













|






|
|


















|
|













<

<
<
<
<
<
<
<
<
<



|
|










|


|
|
|
|
















|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58









59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * Copyright © 2003 Joe English
 *
 * Ttk package: initialization routine and miscellaneous utilities.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*
 * Legal values for the button -default option.
 * See also: enum Ttk_ButtonDefaultState.
 */
const char *const ttkDefaultStrings[] = {
    "active", "disabled", "normal", NULL
};

int Ttk_GetButtonDefaultStateFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_ButtonDefaultState *statePtr)
{
    int state = (int)TTK_BUTTON_DEFAULT_DISABLED;
    int result = Tcl_GetIndexFromObj(interp, objPtr, ttkDefaultStrings,
	    "default state", 0, &state);

    *statePtr = (Ttk_ButtonDefaultState)state;
    return result;
}

/*
 * Legal values for the -compound option.
 * See also: enum Ttk_Compound.
 */
const char *const ttkCompoundStrings[] = {
    "none", "text", "image", "center",
    "top", "bottom", "left", "right", NULL
};

int Ttk_GetCompoundFromObj(
    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Compound *compoundPtr)
{
    int compound = (int)TTK_COMPOUND_NONE;
    int result = Tcl_GetIndexFromObj(interp, objPtr, ttkCompoundStrings,
	    "compound layout", 0, &compound);

    *compoundPtr = (Ttk_Compound)compound;
    return result;
}

/*
 * Legal values for the -orient option.
 * See also: enum Ttk_Orient.
 */
const char *const ttkOrientStrings[] = {
    "horizontal", "vertical", NULL
};


int Ttk_GetOrientFromObj(









    Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Orient *resultPtr)
{
    int orient = (int)TTK_ORIENT_HORIZONTAL;
    int result = Tcl_GetIndexFromObj(interp, objPtr, ttkOrientStrings,
    	    "orientation", 0, &orient);

    *resultPtr = (Ttk_Orient)orient;
    return result;
}

/*
 * Recognized values for the -state compatibility option.
 * Other options are accepted and interpreted as synonyms for "normal".
 */
static const char *const ttkStateStrings[] = {
    "active", "disabled", "normal", "readonly", NULL
};
enum {
    TTK_COMPAT_STATE_ACTIVE,
    TTK_COMPAT_STATE_DISABLED,
    TTK_COMPAT_STATE_NORMAL,
    TTK_COMPAT_STATE_READONLY
};

/* TtkCheckStateOption --
 * 	Handle -state compatibility option.
 *
 *	NOTE: setting -state disabled / -state enabled affects the
 *	widget state, but the internal widget state does *not* affect
 *	the value of the -state option.
 *	This option is present for compatibility only.
 */
void TtkCheckStateOption(WidgetCore *corePtr, Tcl_Obj *objPtr)
{
    int stateOption = TTK_COMPAT_STATE_NORMAL;
    unsigned all = TTK_STATE_DISABLED|TTK_STATE_READONLY|TTK_STATE_ACTIVE;
#   define SETFLAGS(f) TtkWidgetChangeState(corePtr, f, all^f)

    Tcl_GetIndexFromObj(NULL, objPtr, ttkStateStrings,
	    "", 0, &stateOption);
    switch (stateOption) {
	case TTK_COMPAT_STATE_NORMAL:
	default:
	    SETFLAGS(0);
	    break;
	case TTK_COMPAT_STATE_READONLY:
	    SETFLAGS(TTK_STATE_READONLY);
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*------------------------------------------------------------------------
 * +++ Initialization: elements and element factories.
 */

extern void TtkElements_Init(Tcl_Interp *);
extern void TtkLabel_Init(Tcl_Interp *);
extern void TtkImage_Init(Tcl_Interp *);

static void RegisterElements(Tcl_Interp *interp)
{
    TtkElements_Init(interp);
    TtkLabel_Init(interp);
    TtkImage_Init(interp);
}

/*------------------------------------------------------------------------
 * +++ Initialization: Widget definitions.
 */

extern void TtkButton_Init(Tcl_Interp *);
extern void TtkEntry_Init(Tcl_Interp *);
extern void TtkFrame_Init(Tcl_Interp *);
extern void TtkNotebook_Init(Tcl_Interp *);
extern void TtkPanedwindow_Init(Tcl_Interp *);
extern void TtkProgressbar_Init(Tcl_Interp *);
extern void TtkScale_Init(Tcl_Interp *);
extern void TtkScrollbar_Init(Tcl_Interp *);
extern void TtkSeparator_Init(Tcl_Interp *);
extern void TtkTreeview_Init(Tcl_Interp *);

#ifdef TTK_SQUARE_WIDGET
extern int TtkSquareWidget_Init(Tcl_Interp *);
#endif

static void RegisterWidgets(Tcl_Interp *interp)
{
    TtkButton_Init(interp);
    TtkEntry_Init(interp);
    TtkFrame_Init(interp);







|
|
|












|
|
|
|
|
|
|
|
|
|


|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*------------------------------------------------------------------------
 * +++ Initialization: elements and element factories.
 */

MODULE_SCOPE void TtkElements_Init(Tcl_Interp *);
MODULE_SCOPE void TtkLabel_Init(Tcl_Interp *);
MODULE_SCOPE void TtkImage_Init(Tcl_Interp *);

static void RegisterElements(Tcl_Interp *interp)
{
    TtkElements_Init(interp);
    TtkLabel_Init(interp);
    TtkImage_Init(interp);
}

/*------------------------------------------------------------------------
 * +++ Initialization: Widget definitions.
 */

MODULE_SCOPE void TtkButton_Init(Tcl_Interp *);
MODULE_SCOPE void TtkEntry_Init(Tcl_Interp *);
MODULE_SCOPE void TtkFrame_Init(Tcl_Interp *);
MODULE_SCOPE void TtkNotebook_Init(Tcl_Interp *);
MODULE_SCOPE void TtkPanedwindow_Init(Tcl_Interp *);
MODULE_SCOPE void TtkProgressbar_Init(Tcl_Interp *);
MODULE_SCOPE void TtkScale_Init(Tcl_Interp *);
MODULE_SCOPE void TtkScrollbar_Init(Tcl_Interp *);
MODULE_SCOPE void TtkSeparator_Init(Tcl_Interp *);
MODULE_SCOPE void TtkTreeview_Init(Tcl_Interp *);

#ifdef TTK_SQUARE_WIDGET
MODULE_SCOPE int TtkSquareWidget_Init(Tcl_Interp *);
#endif

static void RegisterWidgets(Tcl_Interp *interp)
{
    TtkButton_Init(interp);
    TtkEntry_Init(interp);
    TtkFrame_Init(interp);
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#endif
}

/*------------------------------------------------------------------------
 * +++ Initialization: Built-in themes.
 */

extern int TtkAltTheme_Init(Tcl_Interp *);
extern int TtkClassicTheme_Init(Tcl_Interp *);
extern int TtkClamTheme_Init(Tcl_Interp *);

static void RegisterThemes(Tcl_Interp *interp)
{

    TtkAltTheme_Init(interp);
    TtkClassicTheme_Init(interp);
    TtkClamTheme_Init(interp);







|
|
|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#endif
}

/*------------------------------------------------------------------------
 * +++ Initialization: Built-in themes.
 */

MODULE_SCOPE int TtkAltTheme_Init(Tcl_Interp *);
MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *);
MODULE_SCOPE int TtkClamTheme_Init(Tcl_Interp *);

static void RegisterThemes(Tcl_Interp *interp)
{

    TtkAltTheme_Init(interp);
    TtkClassicTheme_Init(interp);
    TtkClamTheme_Init(interp);
267
268
269
270
271
272
273

274


275
276
277
278
279

    RegisterElements(interp);
    RegisterWidgets(interp);
    RegisterThemes(interp);

    Ttk_PlatformInit(interp);


    Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (void *)&ttkStubs);



    return TCL_OK;
}

/*EOF*/







>

>
>





257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

    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.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    Tcl_Obj	*fontObj;
    Tcl_Obj	*foregroundObj;
    Tcl_Obj	*underlineObj;
    Tcl_Obj	*widthObj;
    Tcl_Obj	*anchorObj;
    Tcl_Obj	*justifyObj;
    Tcl_Obj	*wrapLengthObj;
    Tcl_Obj     *embossedObj;

    /*
     * Computed resources:
     */
    Tk_Font		tkfont;
    Tk_TextLayout	textLayout;
    int 		width;







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    Tcl_Obj	*fontObj;
    Tcl_Obj	*foregroundObj;
    Tcl_Obj	*underlineObj;
    Tcl_Obj	*widthObj;
    Tcl_Obj	*anchorObj;
    Tcl_Obj	*justifyObj;
    Tcl_Obj	*wrapLengthObj;
    Tcl_Obj	*embossedObj;

    /*
     * Computed resources:
     */
    Tk_Font		tkfont;
    Tk_TextLayout	textLayout;
    int 		width;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
static const Ttk_ElementOptionSpec TextElementOptions[] = {
    { "-text", TK_OPTION_STRING,
	offsetof(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(TextElement,fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TextElement,foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	offsetof(TextElement,underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(TextElement,widthObj), "-1"},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(TextElement,anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(TextElement,justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,







|
|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
static const Ttk_ElementOptionSpec TextElementOptions[] = {
    { "-text", TK_OPTION_STRING,
	offsetof(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(TextElement,fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TextElement,foregroundObj), "black" },
    { "-underline", TK_OPTION_INDEX,
	offsetof(TextElement,underlineObj), NULL},
    { "-width", TK_OPTION_INT,
	offsetof(TextElement,widthObj), "-1"},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(TextElement,anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(TextElement,justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
 * TextDraw --
 * 	Draw a text element.
 * 	Called by TextElementDraw() and LabelElementDraw().
 */
static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
{
    XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj);
    int underline = -1;
    XGCValues gcValues;
    GC gc1, gc2;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;
    TkRegion clipRegion = NULL;

    gcValues.font = Tk_FontId(text->tkfont);
    gcValues.foreground = color->pixel;







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
 * TextDraw --
 * 	Draw a text element.
 * 	Called by TextElementDraw() and LabelElementDraw().
 */
static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
{
    XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj);
    Tcl_Size underline = INT_MIN;
    XGCValues gcValues;
    GC gc1, gc2;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;
    TkRegion clipRegion = NULL;

    gcValues.font = Tk_FontId(text->tkfont);
    gcValues.foreground = color->pixel;
166
167
168
169
170
171
172
173

174





175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196

197


198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215

216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234













































235
236
237
238
239
240
241
    if (text->embossed) {
	Tk_DrawTextLayout(Tk_Display(tkwin), d, gc2,
	    text->textLayout, b.x+1, b.y+1, 0/*firstChar*/, -1/*lastChar*/);
    }
    Tk_DrawTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, 0/*firstChar*/, -1/*lastChar*/);

    Tcl_GetIntFromObj(NULL, text->underlineObj, &underline);

    if (underline >= 0) {





	if (text->embossed) {
	    Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc2,
		text->textLayout, b.x+1, b.y+1, underline);
	}
	Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, underline);

    }

    if (clipRegion != NULL) {
#ifdef HAVE_XFT
	TkUnixSetXftClipRegion(NULL);
#endif
	XSetClipMask(Tk_Display(tkwin), gc1, None);
	XSetClipMask(Tk_Display(tkwin), gc2, None);
	TkDestroyRegion(clipRegion);
    }
    Tk_FreeGC(Tk_Display(tkwin), gc1);
    Tk_FreeGC(Tk_Display(tkwin), gc2);
}

static void TextElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    TextElement *text = (TextElement *)elementRecord;
    (void)dummy;
    (void)paddingPtr;

    if (!TextSetup(text, tkwin))
	return;

    *heightPtr = text->height;
    *widthPtr = TextReqWidth(text);

    TextCleanup(text);

    return;
}

static void TextElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    TextElement *text = (TextElement *)elementRecord;
    (void)dummy;
    (void)state;

    if (TextSetup(text, tkwin)) {
	TextDraw(text, tkwin, d, b);
	TextCleanup(text);
    }
}

static const Ttk_ElementSpec TextElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};














































/*----------------------------------------------------------------------
 * +++ Image element.
 * Draws an image.
 */

typedef struct {







|
>
|
>
>
>
>
>
|
|
|
|
|
|
>















>
|
>
|
>
>


<
<













>
|
>
|
>
>


<
<














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    if (text->embossed) {
	Tk_DrawTextLayout(Tk_Display(tkwin), d, gc2,
	    text->textLayout, b.x+1, b.y+1, 0/*firstChar*/, -1/*lastChar*/);
    }
    Tk_DrawTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, 0/*firstChar*/, -1/*lastChar*/);

    if (text->underlineObj != NULL) {
	TkGetIntForIndex(text->underlineObj, TCL_INDEX_NONE, 0, &underline);
	if (underline < INT_MIN) {
	    underline = INT_MIN;
	} else if (underline > INT_MAX) {
	    underline = INT_MAX;
	}
	if (underline != INT_MIN) {
	    if (text->embossed) {
		Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc2,
			text->textLayout, b.x+1, b.y+1, underline);
	    }
	    Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1,
		    text->textLayout, b.x, b.y, underline);
	}
    }

    if (clipRegion != NULL) {
#ifdef HAVE_XFT
	TkUnixSetXftClipRegion(NULL);
#endif
	XSetClipMask(Tk_Display(tkwin), gc1, None);
	XSetClipMask(Tk_Display(tkwin), gc2, None);
	TkDestroyRegion(clipRegion);
    }
    Tk_FreeGC(Tk_Display(tkwin), gc1);
    Tk_FreeGC(Tk_Display(tkwin), gc2);
}

static void TextElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TextElement *text = (TextElement *)elementRecord;



    if (!TextSetup(text, tkwin))
	return;

    *heightPtr = text->height;
    *widthPtr = TextReqWidth(text);

    TextCleanup(text);

    return;
}

static void TextElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    TextElement *text = (TextElement *)elementRecord;



    if (TextSetup(text, tkwin)) {
	TextDraw(text, tkwin, d, b);
	TextCleanup(text);
    }
}

static const Ttk_ElementSpec TextElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};

/*----------------------------------------------------------------------
 * +++ cText (collapsing text) element.
 *
 * This element is the same as the Text element, except its dimensions
 * are 0,0 when the text to display is "".
 */

static int cTextSetup(TextElement *text, Tk_Window tkwin)
{
    if (*Tcl_GetString(text->textObj) == '\0') {
        return 0;
    } else {
        return TextSetup(text, tkwin);
    }
}

static void cTextElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TextElement *text = (TextElement *)elementRecord;

    if (!cTextSetup(text, tkwin))
	return;

    *heightPtr = text->height;
    *widthPtr = TextReqWidth(text);

    TextCleanup(text);

    return;
}

static const Ttk_ElementSpec cTextElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    cTextElementSize,
    TextElementDraw
};

/*----------------------------------------------------------------------
 * +++ Image element.
 * Draws an image.
 */

typedef struct {
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
    if (!image->imageObj) {
	return 0;
    }
    image->imageSpec = TtkGetImageSpec(NULL, tkwin, image->imageObj);
    if (!image->imageSpec) {
	return 0;
    }
    image->tkimg = TtkSelectImage(image->imageSpec, state);
    if (!image->tkimg) {
	TtkFreeImageSpec(image->imageSpec);
	return 0;
    }
    Tk_SizeOfImage(image->tkimg, &image->width, &image->height);

    return 1;







|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    if (!image->imageObj) {
	return 0;
    }
    image->imageSpec = TtkGetImageSpec(NULL, tkwin, image->imageObj);
    if (!image->imageSpec) {
	return 0;
    }
    image->tkimg = TtkSelectImage(image->imageSpec, tkwin, state);
    if (!image->tkimg) {
	TtkFreeImageSpec(image->imageSpec);
	return 0;
    }
    Tk_SizeOfImage(image->tkimg, &image->width, &image->height);

    return 1;
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368

369


370
371
372
373
374
375
376
377
378
379
380
381
382

383

384


385
386
387
388
389
390
391
392
393
394
     * @@@ it's ugly and out of fashion.
     * Do not stipple at all under Aqua, just draw the image: it shows up
     * as a white rectangle otherwise.
     */


    if (state & TTK_STATE_DISABLED) {
	if (TtkSelectImage(image->imageSpec, 0ul) == image->tkimg) {
#ifndef MAC_OSX_TK
	    StippleOver(image, tkwin, d, b.x,b.y);
#endif
	}
    }
}

static void ImageElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ImageElement *image = (ImageElement *)elementRecord;
    (void)dummy;
    (void)paddingPtr;

    if (ImageSetup(image, tkwin, 0)) {
	*widthPtr = image->width;
	*heightPtr = image->height;
	ImageCleanup(image);
    }
}

static void ImageElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    ImageElement *image = (ImageElement *)elementRecord;
    (void)dummy;

    if (ImageSetup(image, tkwin, state)) {
	ImageDraw(image, tkwin, d, b, state);
	ImageCleanup(image);
    }
}








|








>
|
>
|
>
>


<
<









>
|
>
|
>
>


<







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431


432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
     * @@@ it's ugly and out of fashion.
     * Do not stipple at all under Aqua, just draw the image: it shows up
     * as a white rectangle otherwise.
     */


    if (state & TTK_STATE_DISABLED) {
	if (TtkSelectImage(image->imageSpec, tkwin, 0ul) == image->tkimg) {
#ifndef MAC_OSX_TK
	    StippleOver(image, tkwin, d, b.x,b.y);
#endif
	}
    }
}

static void ImageElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ImageElement *image = (ImageElement *)elementRecord;



    if (ImageSetup(image, tkwin, 0)) {
	*widthPtr = image->width;
	*heightPtr = image->height;
	ImageCleanup(image);
    }
}

static void ImageElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ImageElement *image = (ImageElement *)elementRecord;


    if (ImageSetup(image, tkwin, state)) {
	ImageDraw(image, tkwin, d, b, state);
	ImageCleanup(image);
    }
}

459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
     */
    { "-text", TK_OPTION_STRING,
	offsetof(LabelElement,text.textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(LabelElement,text.fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(LabelElement,text.foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	offsetof(LabelElement,text.underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(LabelElement,text.widthObj), ""},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(LabelElement,text.anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(LabelElement,text.justifyObj), "left" },







|







520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
     */
    { "-text", TK_OPTION_STRING,
	offsetof(LabelElement,text.textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(LabelElement,text.fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(LabelElement,text.foregroundObj), "black" },
    { "-underline", TK_OPTION_INDEX,
	offsetof(LabelElement,text.underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(LabelElement,text.widthObj), ""},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(LabelElement,text.anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(LabelElement,text.justifyObj), "left" },
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
 * LabelSetup --
 * 	Fills in computed fields of the label element.
 *
 * 	Calculate the text, image, and total width and height.
 */

#undef  MAX
#define MAX(a,b) ((a) > (b) ? a : b);
static void LabelSetup(
    LabelElement *c, Tk_Window tkwin, Ttk_State state)
{
    Ttk_Compound *compoundPtr = &c->compound;

    Tk_GetPixelsFromObj(NULL, tkwin, c->spaceObj, &c->space);
    Ttk_GetCompoundFromObj(NULL, c->compoundObj, compoundPtr);







|







553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
 * LabelSetup --
 * 	Fills in computed fields of the label element.
 *
 * 	Calculate the text, image, and total width and height.
 */

#undef  MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b));
static void LabelSetup(
    LabelElement *c, Tk_Window tkwin, Ttk_State state)
{
    Ttk_Compound *compoundPtr = &c->compound;

    Tk_GetPixelsFromObj(NULL, tkwin, c->spaceObj, &c->space);
    Ttk_GetCompoundFromObj(NULL, c->compoundObj, compoundPtr);
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
    if (c->compound != TTK_COMPOUND_TEXT)
	ImageCleanup(&c->image);
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextCleanup(&c->text);
}

static void LabelElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    LabelElement *label = (LabelElement *)elementRecord;







|







626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
    if (c->compound != TTK_COMPOUND_TEXT)
	ImageCleanup(&c->image);
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextCleanup(&c->text);
}

static void LabelElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    LabelElement *label = (LabelElement *)elementRecord;
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
    Ttk_Box textBox =
	Ttk_PlaceBox(&b, l->text.width, l->text.height, textSide, 0);
    ImageDraw(&l->image,tkwin,d,imageBox,state);
    TextDraw(&l->text,tkwin,d,textBox);
}

static void LabelElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    LabelElement *l = (LabelElement *)elementRecord;







|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
    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 *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    LabelElement *l = (LabelElement *)elementRecord;
697
698
699
700
701
702
703



704
705
706
707
708
709

710
711
712
713
    LabelElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialization.
 */




MODULE_SCOPE
void TtkLabel_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, theme, "text", &TextElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, NULL);
}








>
>
>






>




758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    LabelElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkLabel_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkLabel_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, theme, "text", &TextElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "ctext", &cTextElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, NULL);
}

Changes to generic/ttk/ttkLayout.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
/*
 * ttkLayout.c --
 *
 * Generic layout processing.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a < b ? a : b)

/*------------------------------------------------------------------------
 * +++ Ttk_Box and Ttk_Padding utilities:
 */

Ttk_Box
Ttk_MakeBox(int x, int y, int width, int height)
{
    Ttk_Box b;
    b.x = x; b.y = y; b.width = width; b.height = height;
    return b;
}

int
Ttk_BoxContains(Ttk_Box box, int x, int y)
{
    return box.x <= x && x < box.x + box.width
	&& box.y <= y && y < box.y + box.height;
}








Tcl_Obj *
Ttk_NewBoxObj(Ttk_Box box)
{
    Tcl_Obj *result[4];

    result[0] = Tcl_NewWideIntObj(box.x);





|





|
|



















>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
 * ttkLayout.c --
 *
 * Generic layout processing.
 *
 * 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))

/*------------------------------------------------------------------------
 * +++ Ttk_Box and Ttk_Padding utilities:
 */

Ttk_Box
Ttk_MakeBox(int x, int y, int width, int height)
{
    Ttk_Box b;
    b.x = x; b.y = y; b.width = width; b.height = height;
    return b;
}

int
Ttk_BoxContains(Ttk_Box box, int x, int y)
{
    return box.x <= x && x < box.x + box.width
	&& box.y <= y && y < box.y + box.height;
}

int
TtkBoxEqual(Ttk_Box box1, Ttk_Box box2)
{
    return box1.x == box2.x && box1.y == box2.y
	&& box1.width == box2.width && box1.height == box2.height;
}

Tcl_Obj *
Ttk_NewBoxObj(Ttk_Box box)
{
    Tcl_Obj *result[4];

    result[0] = Tcl_NewWideIntObj(box.x);
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
	case TK_ANCHOR_NE:	return TTK_STICK_N | TTK_STICK_E;
	case TK_ANCHOR_E:	return TTK_STICK_E;
	case TK_ANCHOR_SE:	return TTK_STICK_S | TTK_STICK_E;
	case TK_ANCHOR_S:	return TTK_STICK_S;
	case TK_ANCHOR_SW:	return TTK_STICK_S | TTK_STICK_W;
	case TK_ANCHOR_W:	return TTK_STICK_W;
	case TK_ANCHOR_NW:	return TTK_STICK_N | TTK_STICK_W;
	default:
	case TK_ANCHOR_CENTER:	return 0;
    }
}

/*
 * Ttk_AnchorBox --
 * 	Place a box of size w * h in the specified parcel,
 * 	according to the specified anchor.







|
<







223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
	case TK_ANCHOR_NE:	return TTK_STICK_N | TTK_STICK_E;
	case TK_ANCHOR_E:	return TTK_STICK_E;
	case TK_ANCHOR_SE:	return TTK_STICK_S | TTK_STICK_E;
	case TK_ANCHOR_S:	return TTK_STICK_S;
	case TK_ANCHOR_SW:	return TTK_STICK_S | TTK_STICK_W;
	case TK_ANCHOR_W:	return TTK_STICK_W;
	case TK_ANCHOR_NW:	return TTK_STICK_N | TTK_STICK_W;
	default:	return 0;

    }
}

/*
 * Ttk_AnchorBox --
 * 	Place a box of size w * h in the specified parcel,
 * 	according to the specified anchor.
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
int Ttk_GetPaddingFromObj(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj *objPtr,
    Ttk_Padding *pad)
{
    Tcl_Obj **padv;

    int i, padc, pixels[4];

    if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
	goto error;
    }

    if (padc > 4) {
	if (interp) {







>
|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
int Ttk_GetPaddingFromObj(
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj *objPtr,
    Ttk_Padding *pad)
{
    Tcl_Obj **padv;
    Tcl_Size i, padc;
    int pixels[4];

    if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
	goto error;
    }

    if (padc > 4) {
	if (interp) {
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
 * 	instead of Tk_Pixel specifications.  Does not require a Tk_Window
 * 	parameter.
 *
 */
int Ttk_GetBorderFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Padding *pad)
{
    Tcl_Obj **padv;

    int i, padc, pixels[4];

    if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
	goto error;
    }

    if (padc > 4) {
	if (interp) {







>
|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
 * 	instead of Tk_Pixel specifications.  Does not require a Tk_Window
 * 	parameter.
 *
 */
int Ttk_GetBorderFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Padding *pad)
{
    Tcl_Obj **padv;
    Tcl_Size i, padc;
    int pixels[4];

    if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
	goto error;
    }

    if (padc > 4) {
	if (interp) {
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
    enum {  OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN };
    static const char *const optStrings[] = {
	"-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 };

    int i = 0, objc;
    Tcl_Obj **objv;
    Ttk_TemplateNode *head = 0, *tail = 0;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return 0;

    while (i < objc) {







|







616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
    enum {  OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN };
    static const char *const optStrings[] = {
	"-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 };

    Tcl_Size i = 0, objc;
    Tcl_Obj **objv;
    Ttk_TemplateNode *head = 0, *tail = 0;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return 0;

    while (i < objc) {
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
{
    Tcl_DString buf;
    const char *styleName;
    Ttk_Style style;
    Ttk_LayoutTemplate layoutTemplate;

    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, Ttk_StyleName(parentLayout->style), -1);
    Tcl_DStringAppend(&buf, baseName, -1);
    styleName = Tcl_DStringValue(&buf);

    style = Ttk_GetStyle(themePtr, styleName);
    layoutTemplate = Ttk_FindLayoutTemplate(themePtr, styleName);

    if (!layoutTemplate) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|
|







916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
{
    Tcl_DString buf;
    const char *styleName;
    Ttk_Style style;
    Ttk_LayoutTemplate layoutTemplate;

    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, Ttk_StyleName(parentLayout->style), TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, baseName, TCL_INDEX_NONE);
    styleName = Tcl_DStringValue(&buf);

    style = Ttk_GetStyle(themePtr, styleName);
    layoutTemplate = Ttk_FindLayoutTemplate(themePtr, styleName);

    if (!layoutTemplate) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
1242
1243
1244
1245
1246
1247
1248































1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
{
    node->parcel = b;
    if (node->child) {
	Ttk_PlaceNodeList(layout, node->child, 0,
	    Ttk_PadBox(b, Ttk_LayoutNodeInternalPadding(layout, node)));
    }
}
































/*
 * Ttk_ChangeElementState --
 */
void Ttk_ChangeElementState(Ttk_LayoutNode *node,unsigned set,unsigned clr)
{
    node->state = (node->state | set) & ~clr;
}

/*EOF*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










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
{
    node->parcel = b;
    if (node->child) {
	Ttk_PlaceNodeList(layout, node->child, 0,
	    Ttk_PadBox(b, Ttk_LayoutNodeInternalPadding(layout, node)));
    }
}

/*
 * AnchorToPosition --
 * 	Convert a Tk_Anchor enum to a position bitmask.
 */
static Ttk_PositionSpec AnchorToPosition(Tk_Anchor anchor)
{
    switch (anchor)
    {
	case TK_ANCHOR_N:	return TTK_PACK_TOP;
	case TK_ANCHOR_S:	return TTK_PACK_BOTTOM;
	case TK_ANCHOR_NE:	return TTK_PACK_RIGHT|TTK_STICK_N;
	case TK_ANCHOR_SE:	return TTK_PACK_RIGHT|TTK_STICK_S;
	case TK_ANCHOR_E:	return TTK_PACK_RIGHT;
	case TK_ANCHOR_NW:	return TTK_PACK_LEFT|TTK_STICK_N;
	case TK_ANCHOR_SW:	return TTK_PACK_LEFT|TTK_STICK_S;
	case TK_ANCHOR_W:	return TTK_PACK_LEFT;
	case TK_ANCHOR_CENTER:	return 0;
	default:;
    }
    return TTK_PACK_LEFT;
}

/*
 * Ttk_AnchorElement --
 * 	Explicitly specify an element's anchoring.
 */
void Ttk_AnchorElement(Ttk_Element node, Tk_Anchor anchor)
{
    node->flags = AnchorToPosition(anchor);
}

/*
 * Ttk_ChangeElementState --
 */
void Ttk_ChangeElementState(Ttk_LayoutNode *node,unsigned set,unsigned clr)
{
    node->state = (node->state | set) & ~clr;
}

/*EOF*/

Changes to generic/ttk/ttkManager.c.

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

/* content->flags bits:
 */
#define CONTENT_MAPPED 	0x1	/* content windows to be mapped when container is */

struct TtkManager_
{
    Ttk_ManagerSpec	*managerSpec;
    void 		*managerData;
    Tk_Window   	window;
    unsigned		flags;
    TkSizeT 	 	nContent;
    Ttk_Content 		**content;
};

/* manager->flags bits:
 */
#define MGR_UPDATE_PENDING	0x1
#define MGR_RESIZE_REQUIRED	0x2







|



|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

/* content->flags bits:
 */
#define CONTENT_MAPPED 	0x1	/* content windows to be mapped when container is */

struct TtkManager_
{
    const Ttk_ManagerSpec	*managerSpec;
    void 		*managerData;
    Tk_Window   	window;
    unsigned		flags;
    Tcl_Size 	 	nContent;
    Ttk_Content 		**content;
};

/* manager->flags bits:
 */
#define MGR_UPDATE_PENDING	0x1
#define MGR_RESIZE_REQUIRED	0x2
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    mgr->managerSpec->PlaceContent(mgr->managerData);
    mgr->flags &= ~MGR_RELAYOUT_REQUIRED;
}

/* ++ ManagerIdleProc --
 * 	DoWhenIdle procedure for deferred updates.
 */
static void ManagerIdleProc(ClientData clientData)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    mgr->flags &= ~MGR_UPDATE_PENDING;

    if (mgr->flags & MGR_RESIZE_REQUIRED) {
	RecomputeSize(mgr);
    }







|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    mgr->managerSpec->PlaceContent(mgr->managerData);
    mgr->flags &= ~MGR_RELAYOUT_REQUIRED;
}

/* ++ ManagerIdleProc --
 * 	DoWhenIdle procedure for deferred updates.
 */
static void ManagerIdleProc(void *clientData)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    mgr->flags &= ~MGR_UPDATE_PENDING;

    if (mgr->flags & MGR_RESIZE_REQUIRED) {
	RecomputeSize(mgr);
    }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 */

/* ++ ManagerEventHandler --
 * 	Recompute content layout when container widget is resized.
 * 	Keep the content's map state in sync with the container's.
 */
static const int ManagerEventMask = StructureNotifyMask;
static void ManagerEventHandler(ClientData clientData, XEvent *eventPtr)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT i;

    switch (eventPtr->type)
    {
	case ConfigureNotify:
	    RecomputeLayout(mgr);
	    break;
	case MapNotify:







|


|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 */

/* ++ ManagerEventHandler --
 * 	Recompute content layout when container widget is resized.
 * 	Keep the content's map state in sync with the container's.
 */
static const int ManagerEventMask = StructureNotifyMask;
static void ManagerEventHandler(void *clientData, XEvent *eventPtr)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    Tcl_Size i;

    switch (eventPtr->type)
    {
	case ConfigureNotify:
	    RecomputeLayout(mgr);
	    break;
	case MapNotify:
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
}

/*------------------------------------------------------------------------
 * +++ Manager initialization and cleanup.
 */

Ttk_Manager *Ttk_CreateManager(
    Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)ckalloc(sizeof(*mgr));

    mgr->managerSpec 	= managerSpec;
    mgr->managerData	= managerData;
    mgr->window	= window;
    mgr->nContent 	= 0;







|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
}

/*------------------------------------------------------------------------
 * +++ Manager initialization and cleanup.
 */

Ttk_Manager *Ttk_CreateManager(
    const Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)ckalloc(sizeof(*mgr));

    mgr->managerSpec 	= managerSpec;
    mgr->managerData	= managerData;
    mgr->window	= window;
    mgr->nContent 	= 0;
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*------------------------------------------------------------------------
 * +++ Content window management.
 */

/* ++ InsertContent --
 * 	Adds content to the list of managed windows.
 */
static void InsertContent(Ttk_Manager *mgr, Ttk_Content *content, TkSizeT index)
{
    TkSizeT endIndex = mgr->nContent++;
    mgr->content = (Ttk_Content **)ckrealloc(mgr->content, mgr->nContent * sizeof(Ttk_Content *));

    while (endIndex > index) {
	mgr->content[endIndex] = mgr->content[endIndex - 1];
	--endIndex;
    }








|

|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*------------------------------------------------------------------------
 * +++ Content window management.
 */

/* ++ InsertContent --
 * 	Adds content to the list of managed windows.
 */
static void InsertContent(Ttk_Manager *mgr, Ttk_Content *content, Tcl_Size index)
{
    Tcl_Size endIndex = mgr->nContent++;
    mgr->content = (Ttk_Content **)ckrealloc(mgr->content, mgr->nContent * sizeof(Ttk_Content *));

    while (endIndex > index) {
	mgr->content[endIndex] = mgr->content[endIndex - 1];
	--endIndex;
    }

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 * 	Unmanage and delete the content window.
 *
 * NOTES/ASSUMPTIONS:
 *
 * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
 * routine is called from the content window's DestroyNotify event handler.
 */
static void RemoveContent(Ttk_Manager *mgr, TkSizeT index)
{
    Ttk_Content *content = mgr->content[index];
    TkSizeT i;

    /* Notify manager:
     */
    mgr->managerSpec->ContentRemoved(mgr->managerData, index);

    /* Remove from array:
     */







|


|







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
 * 	Unmanage and delete the content window.
 *
 * NOTES/ASSUMPTIONS:
 *
 * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
 * routine is called from the content window's DestroyNotify event handler.
 */
static void RemoveContent(Ttk_Manager *mgr, Tcl_Size index)
{
    Ttk_Content *content = mgr->content[index];
    Tcl_Size i;

    /* Notify manager:
     */
    mgr->managerSpec->ContentRemoved(mgr->managerData, index);

    /* Remove from array:
     */
306
307
308
309
310
311
312
313
314
315
316


317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/*------------------------------------------------------------------------
 * +++ Tk_GeomMgr hooks.
 */

void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT index = Ttk_ContentIndex(mgr, window);


    int reqWidth = Tk_ReqWidth(window);
    int reqHeight= Tk_ReqHeight(window);

    if (mgr->managerSpec->ContentRequest(
		mgr->managerData, index, reqWidth, reqHeight))
    {
	ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
    }
}


void Ttk_LostContentProc(ClientData clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    TkSizeT index = Ttk_ContentIndex(mgr, window);

    /* ASSERT: index >= 0 */
    RemoveContent(mgr, index);
}

/*------------------------------------------------------------------------
 * +++ Public API.
 */

/* ++ Ttk_InsertContent --
 * 	Add a new content window at the specified index.
 */
void Ttk_InsertContent(
    Ttk_Manager *mgr, TkSizeT index, Tk_Window tkwin, void *data)
{
    Ttk_Content *content = NewContent(mgr, tkwin, data);
    InsertContent(mgr, content, index);
}

/* ++ Ttk_ForgetContent --
 * 	Unmanage the specified content window.
 */
void Ttk_ForgetContent(Ttk_Manager *mgr, TkSizeT index)
{
    Tk_Window window = mgr->content[index]->window;
    RemoveContent(mgr, index);
    Tk_ManageGeometry(window, NULL, 0);
}

/* ++ Ttk_PlaceContent --
 * 	Set the position and size of the specified content window.
 *
 * NOTES:
 * 	Contrary to documentation, Tk_MaintainGeometry doesn't always
 * 	map the content window.
 */
void Ttk_PlaceContent(
    Ttk_Manager *mgr, TkSizeT index, int x, int y, int width, int height)
{
    Ttk_Content *content = mgr->content[index];
    Tk_MaintainGeometry(content->window,mgr->window,x,y,width,height);
    content->flags |= CONTENT_MAPPED;
    if (Tk_IsMapped(mgr->window)) {
	Tk_MapWindow(content->window);
    }
}

/* ++ Ttk_UnmapContent --
 * 	Unmap the specified content window, but leave it managed.
 */
void Ttk_UnmapContent(Ttk_Manager *mgr, TkSizeT index)
{
    Ttk_Content *content = mgr->content[index];
    Tk_UnmaintainGeometry(content->window, mgr->window);
    content->flags &= ~CONTENT_MAPPED;
    /* Contrary to documentation, Tk_UnmaintainGeometry doesn't always
     * unmap the content window:
     */







|


|
>
>
|
|
<
|
|
<
|
|
|
|
>
|


|













|








|














|












|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/*------------------------------------------------------------------------
 * +++ Tk_GeomMgr hooks.
 */

void Ttk_GeometryRequestProc(void *clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    Tcl_Size index = Ttk_ContentIndex(mgr, window);

    if (index >= 0) {
	int reqWidth = Tk_ReqWidth(window);
	int reqHeight= Tk_ReqHeight(window);

	if (mgr->managerSpec->ContentRequest(
	    mgr->managerData, index, reqWidth, reqHeight)) {

	    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
	}
    }
}

void Ttk_LostContentProc(void *clientData, Tk_Window window)
{
    Ttk_Manager *mgr = (Ttk_Manager *)clientData;
    Tcl_Size index = Ttk_ContentIndex(mgr, window);

    /* ASSERT: index >= 0 */
    RemoveContent(mgr, index);
}

/*------------------------------------------------------------------------
 * +++ Public API.
 */

/* ++ Ttk_InsertContent --
 * 	Add a new content window at the specified index.
 */
void Ttk_InsertContent(
    Ttk_Manager *mgr, Tcl_Size index, Tk_Window tkwin, void *data)
{
    Ttk_Content *content = NewContent(mgr, tkwin, data);
    InsertContent(mgr, content, index);
}

/* ++ Ttk_ForgetContent --
 * 	Unmanage the specified content window.
 */
void Ttk_ForgetContent(Ttk_Manager *mgr, Tcl_Size index)
{
    Tk_Window window = mgr->content[index]->window;
    RemoveContent(mgr, index);
    Tk_ManageGeometry(window, NULL, 0);
}

/* ++ Ttk_PlaceContent --
 * 	Set the position and size of the specified content window.
 *
 * NOTES:
 * 	Contrary to documentation, Tk_MaintainGeometry doesn't always
 * 	map the content window.
 */
void Ttk_PlaceContent(
    Ttk_Manager *mgr, Tcl_Size index, int x, int y, int width, int height)
{
    Ttk_Content *content = mgr->content[index];
    Tk_MaintainGeometry(content->window,mgr->window,x,y,width,height);
    content->flags |= CONTENT_MAPPED;
    if (Tk_IsMapped(mgr->window)) {
	Tk_MapWindow(content->window);
    }
}

/* ++ Ttk_UnmapContent --
 * 	Unmap the specified content window, but leave it managed.
 */
void Ttk_UnmapContent(Ttk_Manager *mgr, Tcl_Size index)
{
    Ttk_Content *content = mgr->content[index];
    Tk_UnmaintainGeometry(content->window, mgr->window);
    content->flags &= ~CONTENT_MAPPED;
    /* Contrary to documentation, Tk_UnmaintainGeometry doesn't always
     * unmap the content window:
     */
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* +++ Accessors.
 */
TkSizeT Ttk_NumberContent(Ttk_Manager *mgr)
{
    return mgr->nContent;
}
void *Ttk_ContentData(Ttk_Manager *mgr, TkSizeT index)
{
    return mgr->content[index]->data;
}
Tk_Window Ttk_ContentWindow(Ttk_Manager *mgr, TkSizeT index)
{
    return mgr->content[index]->window;
}

/*------------------------------------------------------------------------
 * +++ Utility routines.
 */

/* ++ Ttk_ContentIndex --
 * 	Returns the index of specified content window, -1 if not found.
 */
TkSizeT Ttk_ContentIndex(Ttk_Manager *mgr, Tk_Window window)
{
    TkSizeT index;
    for (index = 0; index < mgr->nContent; ++index)
	if (mgr->content[index]->window == window)
	    return index;
    return TCL_INDEX_NONE;
}

/* ++ Ttk_GetContentIndexFromObj(interp, mgr, objPtr, indexPtr) --
 * 	Return the index of the content window specified by objPtr.
 * 	Content windows may be specified as an integer index or
 * 	as the name of the managed window.
 *
 * Returns:
 * 	Standard Tcl completion code.  Leaves an error message in case of error.
 */

int Ttk_GetContentIndexFromObj(
    Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, TkSizeT *indexPtr)
{
    const char *string = Tcl_GetString(objPtr);
    TkSizeT index = 0;
    Tk_Window tkwin;

    /* Try interpreting as an integer first:
     */
    if (TkGetIntForIndex(objPtr, mgr->nContent - 1, 1, &index) == TCL_OK) {
	if (index + 1 > mgr->nContent + 1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Managed window index %d out of bounds", (int)index));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "INDEX", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = index;
	return TCL_OK;
    }

    /* Try interpreting as a window name;
     */
    if ((*string == '.') &&
	    (tkwin = Tk_NameToWindow(interp, string, mgr->window))) {
	index = Ttk_ContentIndex(mgr, tkwin);
	if (index == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is not managed by %s", string,
		    Tk_PathName(mgr->window)));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "MANAGER", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = index;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Invalid managed window specification %s", string));
    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "SPEC", NULL);
    return TCL_ERROR;
}

/* ++ Ttk_ReorderContent(mgr, fromIndex, toIndex) --
 * 	Change content window order.
 */
void Ttk_ReorderContent(Ttk_Manager *mgr, TkSizeT fromIndex, TkSizeT toIndex)
{
    Ttk_Content *moved = mgr->content[fromIndex];

    /* Shuffle down: */
    while (fromIndex > toIndex) {
	mgr->content[fromIndex] = mgr->content[fromIndex - 1];
	--fromIndex;







|



|



|









|

|

|



|












|


|





|














|



















|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* +++ Accessors.
 */
Tcl_Size Ttk_NumberContent(Ttk_Manager *mgr)
{
    return mgr->nContent;
}
void *Ttk_ContentData(Ttk_Manager *mgr, Tcl_Size index)
{
    return mgr->content[index]->data;
}
Tk_Window Ttk_ContentWindow(Ttk_Manager *mgr, Tcl_Size index)
{
    return mgr->content[index]->window;
}

/*------------------------------------------------------------------------
 * +++ Utility routines.
 */

/* ++ Ttk_ContentIndex --
 * 	Returns the index of specified content window, TCL_INDEX_NONE if not found.
 */
Tcl_Size Ttk_ContentIndex(Ttk_Manager *mgr, Tk_Window window)
{
    Tcl_Size index;
    for (index = 0; index < mgr->nContent; ++index)
	if (mgr->content[index]->window == window)
	    return index;
    return -1;
}

/* ++ Ttk_GetContentIndexFromObj(interp, mgr, objPtr, indexPtr) --
 * 	Return the index of the content window specified by objPtr.
 * 	Content windows may be specified as an integer index or
 * 	as the name of the managed window.
 *
 * Returns:
 * 	Standard Tcl completion code.  Leaves an error message in case of error.
 */

int Ttk_GetContentIndexFromObj(
    Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, Tcl_Size *indexPtr)
{
    const char *string = Tcl_GetString(objPtr);
    Tcl_Size index = 0;
    Tk_Window tkwin;

    /* Try interpreting as an integer first:
     */
    if (TkGetIntForIndex(objPtr, mgr->nContent - 1, 1, &index) == TCL_OK) {
	if (index < 0 || index > mgr->nContent) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Managed window index %d out of bounds", (int)index));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "INDEX", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = index;
	return TCL_OK;
    }

    /* Try interpreting as a window name;
     */
    if ((*string == '.') &&
	    (tkwin = Tk_NameToWindow(interp, string, mgr->window))) {
	index = Ttk_ContentIndex(mgr, tkwin);
	if (index < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is not managed by %s", string,
		    Tk_PathName(mgr->window)));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "MANAGER", NULL);
	    return TCL_ERROR;
	}
	*indexPtr = index;
	return TCL_OK;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Invalid managed window specification %s", string));
    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "SPEC", NULL);
    return TCL_ERROR;
}

/* ++ Ttk_ReorderContent(mgr, fromIndex, toIndex) --
 * 	Change content window order.
 */
void Ttk_ReorderContent(Ttk_Manager *mgr, Tcl_Size fromIndex, Tcl_Size toIndex)
{
    Ttk_Content *moved = mgr->content[fromIndex];

    /* Shuffle down: */
    while (fromIndex > toIndex) {
	mgr->content[fromIndex] = mgr->content[fromIndex - 1];
	--fromIndex;

Changes to generic/ttk/ttkManager.h.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2005, Joe English.  Freely redistributable.
 *
 * Geometry manager utilities.
 */

#ifndef _TTKMANAGER
#define _TTKMANAGER


|







1
2
3
4
5
6
7
8
9
/*
 * Copyright © 2005 Joe English.  Freely redistributable.
 *
 * Geometry manager utilities.
 */

#ifndef _TTKMANAGER
#define _TTKMANAGER

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 * It should return 1 if the request should propagate, 0 otherwise.
 */
typedef struct {			/* Manager hooks */
    Tk_GeomMgr tkGeomMgr;		/* "real" Tk Geometry Manager */

    int  (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
    void (*PlaceContent)(void *managerData);
    int  (*ContentRequest)(void *managerData, TkSizeT index, int w, int h);
    void (*ContentRemoved)(void *managerData, TkSizeT index);
} Ttk_ManagerSpec;

/*
 * Default implementations for Tk_GeomMgr hooks:
 */
#define Ttk_LostSlaveProc Ttk_LostContentProc
MODULE_SCOPE void Ttk_GeometryRequestProc(ClientData, Tk_Window window);
MODULE_SCOPE void Ttk_LostContentProc(ClientData, Tk_Window window);

/*
 * Public API:
 */
MODULE_SCOPE Ttk_Manager *Ttk_CreateManager(
	Ttk_ManagerSpec *, void *managerData, Tk_Window window);
MODULE_SCOPE void Ttk_DeleteManager(Ttk_Manager *);

#define  Ttk_InsertSlave Ttk_InsertContent
MODULE_SCOPE void Ttk_InsertContent(
    Ttk_Manager *, TkSizeT position, Tk_Window, void *clientData);

#define Ttk_ForgetSlave Ttk_ForgetContent
MODULE_SCOPE void Ttk_ForgetContent(Ttk_Manager *, TkSizeT index);

#define Ttk_ReorderSlave Ttk_ReorderContent
MODULE_SCOPE void Ttk_ReorderContent(Ttk_Manager *, TkSizeT fromIndex, TkSizeT toIndex);
    /* Rearrange content window positions */

#define Ttk_PlaceSlave Ttk_PlaceContent
MODULE_SCOPE void Ttk_PlaceContent(
    Ttk_Manager *, TkSizeT index, int x, int y, int width, int height);
    /* Position and map the content window */

#define Ttk_UnmapSlave Ttk_UnmapContent
MODULE_SCOPE void Ttk_UnmapContent(Ttk_Manager *, TkSizeT index);
    /* Unmap the content window */

MODULE_SCOPE void Ttk_ManagerSizeChanged(Ttk_Manager *);
MODULE_SCOPE void Ttk_ManagerLayoutChanged(Ttk_Manager *);
    /* Notify manager that size (resp. layout) needs to be recomputed */

/* Utilities:
 */
#define Ttk_SlaveIndex Ttk_ContentIndex
MODULE_SCOPE TkSizeT Ttk_ContentIndex(Ttk_Manager *, Tk_Window);
    /* Returns: index in content array of specified window, TCL_INDEX_NONE if not found */

#define Ttk_GetSlaveIndexFromObj Ttk_GetContentIndexFromObj
MODULE_SCOPE int Ttk_GetContentIndexFromObj(
    Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, TkSizeT *indexPtr);

/* Accessor functions:
 */
#define Ttk_NumberSlaves Ttk_NumberContent
MODULE_SCOPE TkSizeT Ttk_NumberContent(Ttk_Manager *);
    /* Returns: number of managed content windows */

#define Ttk_SlaveData Ttk_ContentData
MODULE_SCOPE void *Ttk_ContentData(Ttk_Manager *, TkSizeT index);
    /* Returns: client data associated with content window */

#define Ttk_SlaveWindow Ttk_ContentWindow
MODULE_SCOPE Tk_Window Ttk_ContentWindow(Ttk_Manager *, TkSizeT index);
    /* Returns: content window */

MODULE_SCOPE int Ttk_Maintainable(Tcl_Interp *, Tk_Window content, Tk_Window container);
    /* Returns: 1 if container can manage content; 0 otherwise leaving error msg */

#endif /* _TTKMANAGER */







|
|






|
|





|




|


|


|




|



|









|




|




|



|



|






27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 * It should return 1 if the request should propagate, 0 otherwise.
 */
typedef struct {			/* Manager hooks */
    Tk_GeomMgr tkGeomMgr;		/* "real" Tk Geometry Manager */

    int  (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
    void (*PlaceContent)(void *managerData);
    int  (*ContentRequest)(void *managerData, Tcl_Size index, int width, int height);
    void (*ContentRemoved)(void *managerData, Tcl_Size index);
} Ttk_ManagerSpec;

/*
 * Default implementations for Tk_GeomMgr hooks:
 */
#define Ttk_LostSlaveProc Ttk_LostContentProc
MODULE_SCOPE void Ttk_GeometryRequestProc(void *, Tk_Window window);
MODULE_SCOPE void Ttk_LostContentProc(void *, Tk_Window window);

/*
 * Public API:
 */
MODULE_SCOPE Ttk_Manager *Ttk_CreateManager(
	const Ttk_ManagerSpec *, void *managerData, Tk_Window window);
MODULE_SCOPE void Ttk_DeleteManager(Ttk_Manager *);

#define  Ttk_InsertSlave Ttk_InsertContent
MODULE_SCOPE void Ttk_InsertContent(
    Ttk_Manager *, Tcl_Size position, Tk_Window, void *clientData);

#define Ttk_ForgetSlave Ttk_ForgetContent
MODULE_SCOPE void Ttk_ForgetContent(Ttk_Manager *, Tcl_Size index);

#define Ttk_ReorderSlave Ttk_ReorderContent
MODULE_SCOPE void Ttk_ReorderContent(Ttk_Manager *, Tcl_Size fromIndex, Tcl_Size toIndex);
    /* Rearrange content window positions */

#define Ttk_PlaceSlave Ttk_PlaceContent
MODULE_SCOPE void Ttk_PlaceContent(
    Ttk_Manager *, Tcl_Size index, int x, int y, int width, int height);
    /* Position and map the content window */

#define Ttk_UnmapSlave Ttk_UnmapContent
MODULE_SCOPE void Ttk_UnmapContent(Ttk_Manager *, Tcl_Size 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 Tcl_Size Ttk_ContentIndex(Ttk_Manager *, Tk_Window);
    /* Returns: index in content array of specified window, TCL_INDEX_NONE if not found */

#define Ttk_GetSlaveIndexFromObj Ttk_GetContentIndexFromObj
MODULE_SCOPE int Ttk_GetContentIndexFromObj(
    Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, Tcl_Size *indexPtr);

/* Accessor functions:
 */
#define Ttk_NumberSlaves Ttk_NumberContent
MODULE_SCOPE Tcl_Size Ttk_NumberContent(Ttk_Manager *);
    /* Returns: number of managed content windows */

#define Ttk_SlaveData Ttk_ContentData
MODULE_SCOPE void *Ttk_ContentData(Ttk_Manager *, Tcl_Size index);
    /* Returns: client data associated with content window */

#define Ttk_SlaveWindow Ttk_ContentWindow
MODULE_SCOPE Tk_Window Ttk_ContentWindow(Ttk_Manager *, Tcl_Size index);
    /* Returns: content window */

MODULE_SCOPE int Ttk_Maintainable(Tcl_Interp *, Tk_Window content, Tk_Window container);
    /* Returns: 1 if container can manage content; 0 otherwise leaving error msg */

#endif /* _TTKMANAGER */

Changes to generic/ttk/ttkNotebook.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 * Copyright (c) 2004, Joe English
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
#include "ttkManager.h"

#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))

/*------------------------------------------------------------------------
 * +++ Tab resources.
 */

#define DEFAULT_MIN_TAB_WIDTH 24

static const char *const TabStateStrings[] = { "normal", "disabled", "hidden", 0 };
typedef enum {
    TAB_STATE_NORMAL, TAB_STATE_DISABLED, TAB_STATE_HIDDEN
} TAB_STATE;

typedef struct
{
    /* Internal data:
     */
    int 	width, height;		/* Requested size of tab */

|



|












|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 * Copyright © 2004 Joe English
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"
#include "ttkManager.h"

#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))

/*------------------------------------------------------------------------
 * +++ Tab resources.
 */

#define DEFAULT_MIN_TAB_WIDTH 24

static const char *const TabStateStrings[] = { "disabled", "hidden", "normal", 0 };
typedef enum {
    TAB_STATE_DISABLED, TAB_STATE_HIDDEN, TAB_STATE_NORMAL
} TAB_STATE;

typedef struct
{
    /* Internal data:
     */
    int 	width, height;		/* Requested size of tab */
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 * PaneOptionSpecs includes additional options for child window placement
 * and is used to configure the pane.
 */
static const Tk_OptionSpec TabOptionSpecs[] =
{
    {TK_OPTION_STRING_TABLE, "-state", "", "",
	"normal", TCL_INDEX_NONE, offsetof(Tab,state),
	0, (void *)TabStateStrings, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Tab,textObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Tab,imageObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	NULL, offsetof(Tab,compoundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,(void *)ttkCompoundStrings,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
	offsetof(Tab,underlineObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
};

static const Tk_OptionSpec PaneOptionSpecs[] =
{
    {TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
	offsetof(Tab,paddingObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },







|






|
|
|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 * PaneOptionSpecs includes additional options for child window placement
 * and is used to configure the pane.
 */
static const Tk_OptionSpec TabOptionSpecs[] =
{
    {TK_OPTION_STRING_TABLE, "-state", "", "",
	"normal", TCL_INDEX_NONE, offsetof(Tab,state),
	TK_OPTION_ENUM_VAR, TabStateStrings, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Tab,textObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
	offsetof(Tab,imageObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED },
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	NULL, offsetof(Tab,compoundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,ttkCompoundStrings,GEOMETRY_CHANGED },
    {TK_OPTION_INDEX, "-underline", "underline", "Underline",
	TTK_OPTION_UNDERLINE_DEF(Tab, underlineObj), 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 },
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    Tcl_Obj *widthObj;		/* Default width */
    Tcl_Obj *heightObj;		/* Default height */
    Tcl_Obj *paddingObj;	/* Padding around notebook */

    Ttk_Manager *mgr;		/* Geometry manager */
    Tk_OptionTable tabOptionTable;	/* Tab options */
    Tk_OptionTable paneOptionTable;	/* Tab+pane options */
    TkSizeT currentIndex;		/* index of currently selected tab */
    TkSizeT activeIndex;		/* index of currently active tab */
    Ttk_Layout tabLayout;	/* Sublayout for tabs */

    Ttk_Box clientArea;		/* Where to pack content windows */
} NotebookPart;

typedef struct
{
    WidgetCore core;
    NotebookPart notebook;
} Notebook;

static const Tk_OptionSpec NotebookOptionSpecs[] =
{
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	offsetof(Notebook,notebook.widthObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	offsetof(Notebook,notebook.heightObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
	offsetof(Notebook,notebook.paddingObj),TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_TRUE,







|
|













|


|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    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 */
    Tcl_Size currentIndex;		/* index of currently selected tab */
    Tcl_Size activeIndex;		/* index of currently active tab */
    Ttk_Layout tabLayout;	/* Sublayout for tabs */

    Ttk_Box clientArea;		/* Where to pack content windows */
} NotebookPart;

typedef struct
{
    WidgetCore core;
    NotebookPart notebook;
} Notebook;

static const Tk_OptionSpec NotebookOptionSpecs[] =
{
    {TK_OPTION_PIXELS, "-width", "width", "Width", "0",
	offsetof(Notebook,notebook.widthObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-height", "height", "Height", "0",
	offsetof(Notebook,notebook.heightObj),TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
	offsetof(Notebook,notebook.paddingObj),TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_TRUE,
131
132
133
134
135
136
137
138

139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
    Ttk_Padding 	tabMargins;	/* Margins around tab row */
    Ttk_PositionSpec 	tabPlacement;	/* How to pack tabs within tab row */
    Ttk_Orient		tabOrient;	/* ... */
    int 		minTabWidth;	/* Minimum tab width */
    Ttk_Padding 	padding;	/* External padding */
} NotebookStyle;

static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle)

{
    Tcl_Obj *objPtr;


    nbstyle->tabPosition = TTK_PACK_TOP | TTK_STICK_W;
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabposition", 0)) != 0) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition);
    }

    /* Guess default tabPlacement as function of tabPosition:
     */
    if (nbstyle->tabPosition & TTK_PACK_LEFT) {
	nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E;
    } else if (nbstyle->tabPosition & TTK_PACK_RIGHT) {
	nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W;
    } else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) {
	nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N;
    } else { /* Assume TTK_PACK_TOP */
	nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S;
    }
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabplacement", 0)) != 0) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPlacement);
    }








    /* Compute tabOrient as function of tabPlacement:
     */
    if (nbstyle->tabPlacement & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) {
	nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
    } else {
	nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
    }

    nbstyle->tabMargins = Ttk_UniformPadding(0);
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabmargins", 0)) != 0) {

	Ttk_GetBorderFromObj(NULL, objPtr, &nbstyle->tabMargins);
    }

    nbstyle->padding = Ttk_UniformPadding(0);
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-padding", 0)) != 0) {
	Ttk_GetPaddingFromObj(NULL,nb->core.tkwin,objPtr,&nbstyle->padding);
    }

    nbstyle->minTabWidth = DEFAULT_MIN_TAB_WIDTH;
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-mintabwidth", 0)) != 0) {
	Tcl_GetIntFromObj(NULL, objPtr, &nbstyle->minTabWidth);
    }
}







|
>


>




















>
>
>
>
>
>
>











>
|




|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    Ttk_Padding 	tabMargins;	/* Margins around tab row */
    Ttk_PositionSpec 	tabPlacement;	/* How to pack tabs within tab row */
    Ttk_Orient		tabOrient;	/* ... */
    int 		minTabWidth;	/* Minimum tab width */
    Ttk_Padding 	padding;	/* External padding */
} NotebookStyle;

static void NotebookStyleOptions(
    Notebook *nb, NotebookStyle *nbstyle, Tk_Window tkwin)
{
    Tcl_Obj *objPtr;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;

    nbstyle->tabPosition = TTK_PACK_TOP | TTK_STICK_W;
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabposition", 0)) != 0) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition);
    }

    /* Guess default tabPlacement as function of tabPosition:
     */
    if (nbstyle->tabPosition & TTK_PACK_LEFT) {
	nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E;
    } else if (nbstyle->tabPosition & TTK_PACK_RIGHT) {
	nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W;
    } else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) {
	nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N;
    } else { /* Assume TTK_PACK_TOP */
	nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S;
    }
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabplacement", 0)) != 0) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPlacement);
    }

    /* Save the stick bit for later.  One of the values
     * TTK_STICK_S, TTK_STICK_N, TTK_STICK_E, or TTK_STICK_W:
     */
    if (mainInfoPtr != NULL) {
	mainInfoPtr->ttkNbTabsStickBit = (nbstyle->tabPlacement & 0x0f);
    }

    /* Compute tabOrient as function of tabPlacement:
     */
    if (nbstyle->tabPlacement & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) {
	nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
    } else {
	nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
    }

    nbstyle->tabMargins = Ttk_UniformPadding(0);
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabmargins", 0)) != 0) {
	Ttk_GetPaddingFromObj(NULL, nb->core.tkwin, objPtr,
	    &nbstyle->tabMargins);
    }

    nbstyle->padding = Ttk_UniformPadding(0);
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-padding", 0)) != 0) {
	Ttk_GetPaddingFromObj(NULL, nb->core.tkwin, objPtr, &nbstyle->padding);
    }

    nbstyle->minTabWidth = DEFAULT_MIN_TAB_WIDTH;
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-mintabwidth", 0)) != 0) {
	Tcl_GetIntFromObj(NULL, objPtr, &nbstyle->minTabWidth);
    }
}
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    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 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,







|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    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 window,
    Tcl_Size 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,
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
}

/*
 * IdentifyTab --
 * 	Return the index of the tab at point x,y,
 * 	or -1 if no tab at that point.
 */
static TkSizeT IdentifyTab(Notebook *nb, int x, int y)
{
    TkSizeT index;
    for (index = 0; index < Ttk_NumberContent(nb->notebook.mgr); ++index) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr,index);
	if (	tab->state != TAB_STATE_HIDDEN
	     && Ttk_BoxContains(tab->parcel, x,y))
	{
	    return index;
	}
    }
    return TCL_INDEX_NONE;
}

/*
 * ActivateTab --
 * 	Set the active tab index, redisplay if necessary.
 */
static void ActivateTab(Notebook *nb, TkSizeT index)
{
    if (index != nb->notebook.activeIndex) {
	nb->notebook.activeIndex = index;
	TtkRedisplayWidget(&nb->core);
    }
}

/*
 * TabState --
 * 	Return the state of the specified tab, based on
 * 	notebook state, currentIndex, activeIndex, and user-specified tab state.
 *	The USER1 bit is set for the leftmost visible tab, and USER2
 * 	is set for the rightmost visible tab.
 */
static Ttk_State TabState(Notebook *nb, TkSizeT index)
{
    Ttk_State state = nb->core.state;
    Tab *itab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT i = 0;

    if (index == nb->notebook.currentIndex) {
	state |= TTK_STATE_SELECTED;
    } else {
	state &= ~TTK_STATE_FOCUS;
    }

    if (index == nb->notebook.activeIndex) {
	state |= TTK_STATE_ACTIVE;
    }
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER1;
	}
	break;
    }
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i != TCL_INDEX_NONE; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER2;
	}







|

|















|














|



|




















|







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
}

/*
 * IdentifyTab --
 * 	Return the index of the tab at point x,y,
 * 	or -1 if no tab at that point.
 */
static Tcl_Size IdentifyTab(Notebook *nb, int x, int y)
{
    Tcl_Size index;
    for (index = 0; index < Ttk_NumberContent(nb->notebook.mgr); ++index) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr,index);
	if (	tab->state != TAB_STATE_HIDDEN
	     && Ttk_BoxContains(tab->parcel, x,y))
	{
	    return index;
	}
    }
    return TCL_INDEX_NONE;
}

/*
 * ActivateTab --
 * 	Set the active tab index, redisplay if necessary.
 */
static void ActivateTab(Notebook *nb, Tcl_Size index)
{
    if (index != nb->notebook.activeIndex) {
	nb->notebook.activeIndex = index;
	TtkRedisplayWidget(&nb->core);
    }
}

/*
 * TabState --
 * 	Return the state of the specified tab, based on
 * 	notebook state, currentIndex, activeIndex, and user-specified tab state.
 *	The USER1 bit is set for the leftmost visible tab, and USER2
 * 	is set for the rightmost visible tab.
 */
static Ttk_State TabState(Notebook *nb, Tcl_Size index)
{
    Ttk_State state = nb->core.state;
    Tab *itab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    Tcl_Size i = 0;

    if (index == nb->notebook.currentIndex) {
	state |= TTK_STATE_SELECTED;
    } else {
	state &= ~TTK_STATE_FOCUS;
    }

    if (index == nb->notebook.activeIndex) {
	state |= TTK_STATE_ACTIVE;
    }
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER1;
	}
	break;
    }
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i >= 0; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER2;
	}
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
 * 	(max height/width) but not parallel (total width/height).
 */
static void TabrowSize(
    Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    int tabrowWidth = 0, tabrowHeight = 0;
    TkSizeT i;

    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	Ttk_State tabState = TabState(nb,i);

	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);







|







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
 * 	(max height/width) but not parallel (total width/height).
 */
static void TabrowSize(
    Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr)
{
    Ttk_Layout tabLayout = nb->notebook.tabLayout;
    int tabrowWidth = 0, tabrowHeight = 0;
    Tcl_Size i;

    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	Ttk_State tabState = TabState(nb,i);

	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
 * 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 content windows:
     */
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tk_Window window = Ttk_ContentWindow(nb->notebook.mgr, i);
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	int width
	    = Tk_ReqWidth(window) + Ttk_PaddingWidth(tab->padding);
	int height
	    = Tk_ReqHeight(window) + Ttk_PaddingHeight(tab->padding);

	clientWidth = MAX(clientWidth, width);
	clientHeight = MAX(clientHeight, height);
    }

    /* Client width/height overridable by widget options:
     */
    Tcl_GetIntFromObj(NULL, nb->notebook.widthObj,&reqWidth);
    Tcl_GetIntFromObj(NULL, nb->notebook.heightObj,&reqHeight);
    if (reqWidth > 0)
	clientWidth = reqWidth;
    if (reqHeight > 0)
	clientHeight = reqHeight;

    /* Tab row:
     */







>






|

|

















|
|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
 * Client area size determined by max size of content windows,
 * overridden by -width and/or -height if nonzero.
 */

static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
{
    Notebook *nb = (Notebook *)clientData;
    Tk_Window nbwin = nb->core.tkwin;
    NotebookStyle nbstyle;
    Ttk_Padding padding;
    Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
    int clientWidth = 0, clientHeight = 0,
    	reqWidth = 0, reqHeight = 0,
	tabrowWidth = 0, tabrowHeight = 0;
    Tcl_Size i;

    NotebookStyleOptions(nb, &nbstyle, nbwin);

    /* Compute max requested size of all content windows:
     */
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tk_Window window = Ttk_ContentWindow(nb->notebook.mgr, i);
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	int width
	    = Tk_ReqWidth(window) + Ttk_PaddingWidth(tab->padding);
	int height
	    = Tk_ReqHeight(window) + Ttk_PaddingHeight(tab->padding);

	clientWidth = MAX(clientWidth, width);
	clientHeight = MAX(clientHeight, height);
    }

    /* Client width/height overridable by widget options:
     */
    Tk_GetPixelsFromObj(NULL, nb->core.tkwin, nb->notebook.widthObj,&reqWidth);
    Tk_GetPixelsFromObj(NULL, nb->core.tkwin, nb->notebook.heightObj,&reqHeight);
    if (reqWidth > 0)
	clientWidth = reqWidth;
    if (reqHeight > 0)
	clientHeight = reqHeight;

    /* Tab row:
     */
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

















511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
	Ttk_State tabState = TabState(nb, i);

	if (tab->state != TAB_STATE_HIDDEN) {
	    Ttk_Padding expand = Ttk_UniformPadding(0);
	    Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);

	    if (expandObj) {
		Ttk_GetBorderFromObj(NULL, expandObj, &expand);
	    }

	    tab->parcel =
		Ttk_ExpandBox(
		    Ttk_PositionBox(&tabrowBox,
			tab->width, tab->height, tabPlacement),
		    expand);
	}
    }
}


















/* NotebookDoLayout --
 *	Computes notebook layout and places tabs.
 *
 * Side effects:
 * 	Sets clientArea, used to place panes.
 */
static void NotebookDoLayout(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    Tk_Window nbwin = nb->core.tkwin;
    Ttk_Box cavity = Ttk_WinBox(nbwin);
    int tabrowWidth = 0, tabrowHeight = 0;
    Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
    Ttk_Box tabrowBox;
    NotebookStyle nbstyle;


    NotebookStyleOptions(nb, &nbstyle);

    /* Notebook internal padding:
     */
    cavity = Ttk_PadBox(cavity, nbstyle.padding);

    /* Layout for notebook background (base layout):
     */







|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>

|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
	Ttk_State tabState = TabState(nb, i);

	if (tab->state != TAB_STATE_HIDDEN) {
	    Ttk_Padding expand = Ttk_UniformPadding(0);
	    Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);

	    if (expandObj) {
		Ttk_GetPaddingFromObj(NULL, nb->core.tkwin, expandObj, &expand);
	    }

	    tab->parcel =
		Ttk_ExpandBox(
		    Ttk_PositionBox(&tabrowBox,
			tab->width, tab->height, tabPlacement),
		    expand);
	}
    }
}

/*
 * NotebookPlaceContent --
 * 	Set the position and size of a child widget
 * 	based on the current client area and content window options:
 */
static void NotebookPlaceContent(Notebook* nb, Tcl_Size index)
{
    Tab* tab = (Tab*)Ttk_ContentData(nb->notebook.mgr, index);
    Tk_Window window = Ttk_ContentWindow(nb->notebook.mgr, index);
    Ttk_Box box =
	Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
	    Tk_ReqWidth(window), Tk_ReqHeight(window), tab->sticky);

    Ttk_PlaceContent(nb->notebook.mgr, index,
	box.x, box.y, box.width, box.height);
}

/* NotebookDoLayout --
 *	Computes notebook layout and places tabs.
 *
 * Side effects:
 * 	Sets clientArea, used to place panes.
 */
static void NotebookDoLayout(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    Tk_Window nbwin = nb->core.tkwin;
    Ttk_Box cavity = Ttk_WinBox(nbwin);
    int tabrowWidth = 0, tabrowHeight = 0;
    Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
    Ttk_Box tabrowBox;
    NotebookStyle nbstyle;
    Tcl_Size currentIndex = nb->notebook.currentIndex;

    NotebookStyleOptions(nb, &nbstyle, nbwin);

    /* Notebook internal padding:
     */
    cavity = Ttk_PadBox(cavity, nbstyle.padding);

    /* Layout for notebook background (base layout):
     */
559
560
561
562
563
564
565

566


567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
	Ttk_PlaceElement(nb->core.layout, clientNode, cavity);
	cavity = Ttk_LayoutNodeInternalParcel(nb->core.layout, clientNode);
    }

    if (cavity.height <= 0) cavity.height = 1;
    if (cavity.width <= 0) cavity.width = 1;


    nb->notebook.clientArea = cavity;


}

/*
 * NotebookPlaceContent --
 * 	Set the position and size of a child widget
 * 	based on the current client area and content window options:
 */
static void NotebookPlaceContent(Notebook *nb, TkSizeT index)
{
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    Tk_Window window = Ttk_ContentWindow(nb->notebook.mgr, index);
    Ttk_Box box =
	Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
	    Tk_ReqWidth(window), Tk_ReqHeight(window),tab->sticky);

    Ttk_PlaceContent(nb->notebook.mgr, index,
	box.x, box.y, box.width, box.height);
}

/* NotebookPlaceContents --
 * 	Geometry manager hook.
 */
static void NotebookPlaceContents(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT currentIndex = nb->notebook.currentIndex;
    if (currentIndex != TCL_INDEX_NONE) {
	NotebookDoLayout(nb);
	NotebookPlaceContent(nb, currentIndex);
    }
}

/*
 * SelectTab(nb, index) --
 * 	Change the currently-selected tab.
 */
static void SelectTab(Notebook *nb, TkSizeT index)
{
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT currentIndex = nb->notebook.currentIndex;

    if (index == currentIndex) {
	return;
    }

    if (TabState(nb, index) & TTK_STATE_DISABLED) {
	return;
    }

    /* Unhide the tab if it is currently hidden and being selected.
     */
    if (tab->state == TAB_STATE_HIDDEN) {
	tab->state = TAB_STATE_NORMAL;
    }

    if (currentIndex != TCL_INDEX_NONE) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }

    /* Must be set before calling NotebookPlaceContent(), otherwise it may
     * happen that NotebookPlaceContents(), triggered by an interveaning
     * geometry request, will swap to old index. */
    nb->notebook.currentIndex = index;







>
|
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
|









|


|















|







588
589
590
591
592
593
594
595
596
597
598
599
600















601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
	Ttk_PlaceElement(nb->core.layout, clientNode, cavity);
	cavity = Ttk_LayoutNodeInternalParcel(nb->core.layout, clientNode);
    }

    if (cavity.height <= 0) cavity.height = 1;
    if (cavity.width <= 0) cavity.width = 1;

    if (!TtkBoxEqual(nb->notebook.clientArea, cavity)) {
	nb->notebook.clientArea = cavity;
	if (currentIndex >= 0) {
	    NotebookPlaceContent(nb, currentIndex);
	}
    }















}

/* NotebookPlaceContents --
 * 	Geometry manager hook.
 */
static void NotebookPlaceContents(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    Tcl_Size currentIndex = nb->notebook.currentIndex;
    if (currentIndex >= 0) {
	NotebookDoLayout(nb);
	NotebookPlaceContent(nb, currentIndex);
    }
}

/*
 * SelectTab(nb, index) --
 * 	Change the currently-selected tab.
 */
static void SelectTab(Notebook *nb, Tcl_Size index)
{
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    Tcl_Size currentIndex = nb->notebook.currentIndex;

    if (index == currentIndex) {
	return;
    }

    if (TabState(nb, index) & TTK_STATE_DISABLED) {
	return;
    }

    /* Unhide the tab if it is currently hidden and being selected.
     */
    if (tab->state == TAB_STATE_HIDDEN) {
	tab->state = TAB_STATE_NORMAL;
    }

    if (currentIndex >= 0) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }

    /* Must be set before calling NotebookPlaceContent(), otherwise it may
     * happen that NotebookPlaceContents(), triggered by an interveaning
     * geometry request, will swap to old index. */
    nb->notebook.currentIndex = index;
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
/* NextTab --
 * 	Returns the index of the next tab after the specified tab
 * 	in the normal state (e.g., not hidden or disabled),
 * 	or -1 if all tabs are disabled or hidden.
 */
static int NextTab(Notebook *nb, int index)
{
    TkSizeT nTabs = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT nextIndex;

    /* Scan forward for following usable tab:
     */
    for (nextIndex = index + 1; nextIndex + 1 < nTabs + 1; ++nextIndex) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Not found -- scan backwards.
     */
    for (nextIndex = index - 1; nextIndex != TCL_INDEX_NONE; --nextIndex) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Still nothing.  Give up.
     */
    return -1;
}

/* SelectNearestTab --
 * 	Handles the case where the current tab is forgotten, hidden,
 * 	or destroyed.
 *
 * 	Unmap the current tab and schedule the next available one
 * 	to be mapped at the next GM update.
 */
static void SelectNearestTab(Notebook *nb)
{
    TkSizeT currentIndex = nb->notebook.currentIndex;
    TkSizeT nextIndex = NextTab(nb, currentIndex);

    if (currentIndex != TCL_INDEX_NONE) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }
    if (currentIndex != nextIndex) {
	Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
    }

    nb->notebook.currentIndex = nextIndex;
    Ttk_ManagerLayoutChanged(nb->notebook.mgr);
    TtkRedisplayWidget(&nb->core);
}

/* TabRemoved -- GM TabRemoved hook.
 * 	Select the next tab if the current one is being removed.
 * 	Adjust currentIndex to account for removed content window.
 */
static void TabRemoved(void *managerData, TkSizeT index)
{
    Notebook *nb = (Notebook *)managerData;
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);

    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    if (index + 1 < nb->notebook.currentIndex + 1) {
	--nb->notebook.currentIndex;
    }

    DestroyTab(nb, tab);

    TtkRedisplayWidget(&nb->core);
}

static int TabRequest(
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    return 1;
}

/* AddTab --
 * 	Add new tab at specified index.
 */
static int AddTab(
    Tcl_Interp *interp, Notebook *nb,
    TkSizeT destIndex, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Tab *tab;
    if (!Ttk_Maintainable(interp, window, nb->core.tkwin)) {
	return TCL_ERROR;
    }
#if 0 /* can't happen */
    if (Ttk_ContentIndex(nb->notebook.mgr, window) != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s already added",
	    Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "PRESENT", NULL);
	return TCL_ERROR;
    }
#endif








|
|



|








|




















|
|

|















|








|









|
|
|
|









|
|






|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
/* 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)
{
    Tcl_Size nTabs = Ttk_NumberContent(nb->notebook.mgr);
    Tcl_Size nextIndex;

    /* Scan forward for following usable tab:
     */
    for (nextIndex = index + 1; nextIndex < nTabs; ++nextIndex) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Not found -- scan backwards.
     */
    for (nextIndex = index - 1; nextIndex >= 0; --nextIndex) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, nextIndex);
	if (tab->state == TAB_STATE_NORMAL) {
	    return nextIndex;
	}
    }

    /* Still nothing.  Give up.
     */
    return -1;
}

/* SelectNearestTab --
 * 	Handles the case where the current tab is forgotten, hidden,
 * 	or destroyed.
 *
 * 	Unmap the current tab and schedule the next available one
 * 	to be mapped at the next GM update.
 */
static void SelectNearestTab(Notebook *nb)
{
    Tcl_Size currentIndex = nb->notebook.currentIndex;
    Tcl_Size nextIndex = NextTab(nb, currentIndex);

    if (currentIndex >= 0) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }
    if (currentIndex != nextIndex) {
	Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
    }

    nb->notebook.currentIndex = nextIndex;
    Ttk_ManagerLayoutChanged(nb->notebook.mgr);
    TtkRedisplayWidget(&nb->core);
}

/* TabRemoved -- GM TabRemoved hook.
 * 	Select the next tab if the current one is being removed.
 * 	Adjust currentIndex to account for removed content window.
 */
static void TabRemoved(void *managerData, Tcl_Size index)
{
    Notebook *nb = (Notebook *)managerData;
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);

    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    if (index < nb->notebook.currentIndex) {
	--nb->notebook.currentIndex;
    }

    DestroyTab(nb, tab);

    TtkRedisplayWidget(&nb->core);
}

static int TabRequest(
    TCL_UNUSED(void *), /* managerData */
    TCL_UNUSED(Tcl_Size), /* index */
    TCL_UNUSED(int), /* width */
    TCL_UNUSED(int)) /* height */
{
    return 1;
}

/* AddTab --
 * 	Add new tab at specified index.
 */
static int AddTab(
    Tcl_Interp *interp, Notebook *nb,
    Tcl_Size destIndex, Tk_Window window,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Tab *tab;
    if (!Ttk_Maintainable(interp, window, nb->core.tkwin)) {
	return TCL_ERROR;
    }
#if 0 /* can't happen */
    if (Ttk_ContentIndex(nb->notebook.mgr, window) >= 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s already added",
	    Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "PRESENT", NULL);
	return TCL_ERROR;
    }
#endif

754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	return TCL_ERROR;
    }

    Ttk_InsertContent(nb->notebook.mgr, destIndex, window, tab);

    /* Adjust indices and/or autoselect first tab:
     */
    if (nb->notebook.currentIndex == TCL_INDEX_NONE) {
	SelectTab(nb, destIndex);
    } else if (nb->notebook.currentIndex + 1 >= destIndex + 1) {
	++nb->notebook.currentIndex;
    }

    return TCL_OK;
}

static Ttk_ManagerSpec NotebookManagerSpec = {
    { "notebook", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    NotebookSize,
    NotebookPlaceContents,
    TabRequest,
    TabRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */

/* NotebookEventHandler --
 * 	Tracks the active tab.
 */
static const int NotebookEventMask
    = StructureNotifyMask
    | PointerMotionMask
    | LeaveWindowMask
    ;
static void NotebookEventHandler(ClientData clientData, XEvent *eventPtr)
{
    Notebook *nb = (Notebook *)clientData;

    if (eventPtr->type == DestroyNotify) { /* Remove self */
	Tk_DeleteEventHandler(nb->core.tkwin,
	    NotebookEventMask, NotebookEventHandler, clientData);
    } else if (eventPtr->type == MotionNotify) {
	TkSizeT index = IdentifyTab(nb, eventPtr->xmotion.x, eventPtr->xmotion.y);
	ActivateTab(nb, index);
    } else if (eventPtr->type == LeaveNotify) {
	ActivateTab(nb, -1);
    }
}

/*------------------------------------------------------------------------







|

|






|



















|







|







771
772
773
774
775
776
777
778
779
780
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
	return TCL_ERROR;
    }

    Ttk_InsertContent(nb->notebook.mgr, destIndex, window, tab);

    /* Adjust indices and/or autoselect first tab:
     */
    if (nb->notebook.currentIndex < 0) {
	SelectTab(nb, destIndex);
    } else if (nb->notebook.currentIndex  >= destIndex) {
	++nb->notebook.currentIndex;
    }

    return TCL_OK;
}

static const Ttk_ManagerSpec NotebookManagerSpec = {
    { "notebook", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    NotebookSize,
    NotebookPlaceContents,
    TabRequest,
    TabRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */

/* NotebookEventHandler --
 * 	Tracks the active tab.
 */
static const int NotebookEventMask
    = StructureNotifyMask
    | PointerMotionMask
    | LeaveWindowMask
    ;
static void NotebookEventHandler(void *clientData, XEvent *eventPtr)
{
    Notebook *nb = (Notebook *)clientData;

    if (eventPtr->type == DestroyNotify) { /* Remove self */
	Tk_DeleteEventHandler(nb->core.tkwin,
	    NotebookEventMask, NotebookEventHandler, clientData);
    } else if (eventPtr->type == MotionNotify) {
	Tcl_Size index = IdentifyTab(nb, eventPtr->xmotion.x, eventPtr->xmotion.y);
	ActivateTab(nb, index);
    } else if (eventPtr->type == LeaveNotify) {
	ActivateTab(nb, -1);
    }
}

/*------------------------------------------------------------------------
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
 *
 *	Returns TCL_ERROR and leaves an error message in interp->result
 *	if the tab identifier was incorrect.
 *
 *	See also: GetTabIndex.
 */
static int FindTabIndex(
    Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, TkSizeT *index_rtn)
{
    const char *string = Tcl_GetString(objPtr);
    int x, y;

    *index_rtn = TCL_INDEX_NONE;

    /* Check for @x,y ...







|







836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
 *
 *	Returns TCL_ERROR and leaves an error message in interp->result
 *	if the tab identifier was incorrect.
 *
 *	See also: GetTabIndex.
 */
static int FindTabIndex(
    Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, Tcl_Size *index_rtn)
{
    const char *string = Tcl_GetString(objPtr);
    int x, y;

    *index_rtn = TCL_INDEX_NONE;

    /* Check for @x,y ...
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
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

/* GetTabIndex --
 * 	Get the index of an existing tab.
 * 	Tab identifiers are as per FindTabIndex.
 * 	Returns TCL_ERROR if the tab does not exist.
 */
static int GetTabIndex(
    Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, TkSizeT *index_rtn)
{
    int status = FindTabIndex(interp, nb, objPtr, index_rtn);
	if (status == TCL_OK && *index_rtn + 1 >= Ttk_NumberContent(nb->notebook.mgr) + 1) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"tab index %s out of bounds", Tcl_GetString(objPtr)));
	    Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "INDEX", NULL);
	    return TCL_ERROR;
	}

    if (status == TCL_OK && *index_rtn == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "tab '%s' not found", Tcl_GetString(objPtr)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "TAB", NULL);
	status = TCL_ERROR;
    }
    return status;
}

/*------------------------------------------------------------------------
 * +++ Widget command routines.
 */

/* $nb add window ?options ... ?
 */
static int NotebookAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Tk_Window window;
    int index;
    Tab *tab;

    if (objc <= 2 || objc % 2 != 1) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	return TCL_ERROR;
    }








|


|






|















|



|







882
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

/* 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, Tcl_Size *index_rtn)
{
    int status = FindTabIndex(interp, nb, objPtr, index_rtn);
	if (status == TCL_OK && *index_rtn  >= Ttk_NumberContent(nb->notebook.mgr)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"tab index %s out of bounds", Tcl_GetString(objPtr)));
	    Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "INDEX", NULL);
	    return TCL_ERROR;
	}

    if (status == TCL_OK && *index_rtn < 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "tab '%s' not found", Tcl_GetString(objPtr)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "TAB", NULL);
	status = TCL_ERROR;
    }
    return status;
}

/*------------------------------------------------------------------------
 * +++ Widget command routines.
 */

/* $nb add window ?options ... ?
 */
static int NotebookAddCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Tk_Window window;
    Tcl_Size index;
    Tab *tab;

    if (objc <= 2 || objc % 2 != 1) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	return TCL_ERROR;
    }

930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
    return TCL_OK;
}

/* $nb insert $index $tab ?-option value ...?
 * 	Insert new tab, or move existing one.
 */
static int NotebookInsertCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT current = nb->notebook.currentIndex;
    TkSizeT nContent = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT srcIndex, destIndex;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(







|


|
|
|







947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
    return TCL_OK;
}

/* $nb insert $index $tab ?-option value ...?
 * 	Insert new tab, or move existing one.
 */
static int NotebookInsertCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Tcl_Size current = nb->notebook.currentIndex;
    Tcl_Size nContent = Ttk_NumberContent(nb->notebook.mgr);
    Tcl_Size srcIndex, destIndex;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
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
	    Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);

	if (!window) {
	    return TCL_ERROR;
	}

	srcIndex = Ttk_ContentIndex(nb->notebook.mgr, window);
	if (srcIndex == TCL_INDEX_NONE) {	/* New content window */
	    return AddTab(interp, nb, destIndex, window, objc-4,objv+4);
	}
    } else if (Ttk_GetContentIndexFromObj(
		interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
    {
	return TCL_ERROR;
    } else if (srcIndex + 1 >= Ttk_NumberContent(nb->notebook.mgr) + 1) {
	srcIndex = Ttk_NumberContent(nb->notebook.mgr) - 1;
    }

    /* Move existing content window:
     */
    if (ConfigureTab(interp, nb,
	     (Tab *)Ttk_ContentData(nb->notebook.mgr, srcIndex),
		 Ttk_ContentWindow(nb->notebook.mgr, srcIndex),
	     objc-4,objv+4) != TCL_OK)
    {
	return TCL_ERROR;
    }

    if (destIndex + 1 >= nContent + 1) {
	destIndex  = nContent - 1;
    }
    Ttk_ReorderContent(nb->notebook.mgr, srcIndex, destIndex);

    /* Adjust internal indexes:
     */
    nb->notebook.activeIndex = TCL_INDEX_NONE;
    if (current == srcIndex) {
	nb->notebook.currentIndex = destIndex;
    } else if (destIndex + 1 <= current + 1 && current + 1 < srcIndex + 1) {
	++nb->notebook.currentIndex;
    } else if (srcIndex + 1 < current + 1 && current + 1 <= destIndex + 1) {
	--nb->notebook.currentIndex;
    }

    TtkRedisplayWidget(&nb->core);

    return TCL_OK;
}

/* $nb forget $tab --
 * 	Removes the specified tab.
 */
static int NotebookForgetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Ttk_ForgetContent(nb->notebook.mgr, index);
    TtkRedisplayWidget(&nb->core);

    return TCL_OK;
}

/* $nb hide $tab --
 * 	Hides the specified tab.
 */
static int NotebookHideCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT index;
    Tab *tab;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    tab->state = TAB_STATE_HIDDEN;
    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    TtkRedisplayWidget(&nb->core);


    return TCL_OK;
}

/* $nb identify $x $y --
 * 	Returns name of tab element at $x,$y; empty string if none.
 */
static int NotebookIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    static const char *const whatTable[] = { "element", "tab", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_TAB };
    int what = IDENTIFY_ELEMENT;
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Element element = NULL;
    int x, y;
    TkSizeT tabIndex;

    if (objc < 4 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2,objv, "?what? x y");
	return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
	|| (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
		sizeof(char *), "option", 0, &what) != TCL_OK)
    ) {
	return TCL_ERROR;
    }

    tabIndex = IdentifyTab(nb, x, y);
    if (tabIndex != TCL_INDEX_NONE) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, tabIndex);
	Ttk_State state = TabState(nb, tabIndex);
	Ttk_Layout tabLayout = nb->notebook.tabLayout;

	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_PlaceLayout(tabLayout, state, tab->parcel);

	element = Ttk_IdentifyElement(tabLayout, x, y);
    }

    switch (what) {
	case IDENTIFY_ELEMENT:
	    if (element) {
		const char *elementName = Ttk_ElementName(element);

		Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
	    }
	    break;
	case IDENTIFY_TAB:
	    if (tabIndex != TCL_INDEX_NONE)
	    Tcl_SetObjResult(interp, TkNewIndexObj(tabIndex));

	    break;
    }
    return TCL_OK;
}

/* $nb index $item --
 * 	Returns the integer index of the tab specified by $item,
 * 	the empty string if $item does not identify a tab.
 *	See above for valid item formats.
 */
static int NotebookIndexCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    TkSizeT index;
    int status;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    status = FindTabIndex(interp, nb, objv[2], &index);
	if (status == TCL_OK) {
	if (index != TCL_INDEX_NONE)
	Tcl_SetObjResult(interp, TkNewIndexObj(index));

    }

    return status;
}

/* $nb select ?$item? --
 * 	Select the specified tab, or return the widget path of
 * 	the currently-selected pane.
 */
static int NotebookSelectCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;

    if (objc == 2) {
	if (nb->notebook.currentIndex != TCL_INDEX_NONE) {
	    Tk_Window pane = Ttk_ContentWindow(
		nb->notebook.mgr, nb->notebook.currentIndex);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
	}
	return TCL_OK;
    } else if (objc == 3) {
	TkSizeT index;
	int status = GetTabIndex(interp, nb, objv[2], &index);
	if (status == TCL_OK) {
	    SelectTab(nb, index);
	}
	return status;
    } /*else*/
    Tcl_WrongNumArgs(interp, 2, objv, "?tab?");
    return TCL_ERROR;
}

/* $nb tabs --
 * 	Return list of tabs.
 */
static int NotebookTabsCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    Tcl_Obj *result;
    TkSizeT i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    result = Tcl_NewListObj(0, NULL);
    for (i = 0; i < Ttk_NumberContent(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_ContentWindow(mgr,i));

	Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(pathName,-1));
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/* $nb tab $tab ?-option ?value -option value...??
 */
static int NotebookTabCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    TkSizeT index;
    Tk_Window window;
    Tab *tab;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
	return TCL_ERROR;
    }







|






|













|









|

|












|


|




















|


|















<
|
|
|
>







|







|















|



















|
|
>











|


|









|
|
>










|




|






|














|




|



















|



|







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
	    Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);

	if (!window) {
	    return TCL_ERROR;
	}

	srcIndex = Ttk_ContentIndex(nb->notebook.mgr, window);
	if (srcIndex < 0) {	/* New content window */
	    return AddTab(interp, nb, destIndex, window, objc-4,objv+4);
	}
    } else if (Ttk_GetContentIndexFromObj(
		interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
    {
	return TCL_ERROR;
    } else if (srcIndex  >= Ttk_NumberContent(nb->notebook.mgr)) {
	srcIndex = Ttk_NumberContent(nb->notebook.mgr) - 1;
    }

    /* Move existing content window:
     */
    if (ConfigureTab(interp, nb,
	     (Tab *)Ttk_ContentData(nb->notebook.mgr, srcIndex),
		 Ttk_ContentWindow(nb->notebook.mgr, srcIndex),
	     objc-4,objv+4) != TCL_OK)
    {
	return TCL_ERROR;
    }

    if (destIndex  >= nContent) {
	destIndex  = nContent - 1;
    }
    Ttk_ReorderContent(nb->notebook.mgr, srcIndex, destIndex);

    /* Adjust internal indexes:
     */
    nb->notebook.activeIndex = TCL_INDEX_NONE;
    if (current == srcIndex) {
	nb->notebook.currentIndex = destIndex;
    } else if (destIndex <= current && current < srcIndex) {
	++nb->notebook.currentIndex;
    } else if (srcIndex < current && current <= destIndex) {
	--nb->notebook.currentIndex;
    }

    TtkRedisplayWidget(&nb->core);

    return TCL_OK;
}

/* $nb forget $tab --
 * 	Removes the specified tab.
 */
static int NotebookForgetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Tcl_Size index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    Ttk_ForgetContent(nb->notebook.mgr, index);
    TtkRedisplayWidget(&nb->core);

    return TCL_OK;
}

/* $nb hide $tab --
 * 	Hides the specified tab.
 */
static int NotebookHideCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Tcl_Size index;
    Tab *tab;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
	return TCL_ERROR;
    }

    tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    tab->state = TAB_STATE_HIDDEN;
    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);

    } else {
        TtkRedisplayWidget(&nb->core);
    }

    return TCL_OK;
}

/* $nb identify $x $y --
 * 	Returns name of tab element at $x,$y; empty string if none.
 */
static int NotebookIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    static const char *const whatTable[] = { "element", "tab", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_TAB };
    int what = IDENTIFY_ELEMENT;
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Element element = NULL;
    int x, y;
    Tcl_Size tabIndex;

    if (objc < 4 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2,objv, "?what? x y");
	return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
	|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
	|| (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
		sizeof(char *), "option", 0, &what) != TCL_OK)
    ) {
	return TCL_ERROR;
    }

    tabIndex = IdentifyTab(nb, x, y);
    if (tabIndex >= 0) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, tabIndex);
	Ttk_State state = TabState(nb, tabIndex);
	Ttk_Layout tabLayout = nb->notebook.tabLayout;

	Ttk_RebindSublayout(tabLayout, tab);
	Ttk_PlaceLayout(tabLayout, state, tab->parcel);

	element = Ttk_IdentifyElement(tabLayout, x, y);
    }

    switch (what) {
	case IDENTIFY_ELEMENT:
	    if (element) {
		const char *elementName = Ttk_ElementName(element);

		Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
	    }
	    break;
	case IDENTIFY_TAB:
	    if (tabIndex >= 0) {
		Tcl_SetObjResult(interp, TkNewIndexObj(tabIndex));
	    }
	    break;
    }
    return TCL_OK;
}

/* $nb index $item --
 * 	Returns the integer index of the tab specified by $item,
 * 	the empty string if $item does not identify a tab.
 *	See above for valid item formats.
 */
static int NotebookIndexCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Tcl_Size index;
    int status;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    status = FindTabIndex(interp, nb, objv[2], &index);
	if (status == TCL_OK) {
	if (index >= 0) {
	    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, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;

    if (objc == 2) {
	if (nb->notebook.currentIndex >= 0) {
	    Tk_Window pane = Ttk_ContentWindow(
		nb->notebook.mgr, nb->notebook.currentIndex);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
	}
	return TCL_OK;
    } else if (objc == 3) {
	Tcl_Size index;
	int status = GetTabIndex(interp, nb, objv[2], &index);
	if (status == TCL_OK) {
	    SelectTab(nb, index);
	}
	return status;
    } /*else*/
    Tcl_WrongNumArgs(interp, 2, objv, "?tab?");
    return TCL_ERROR;
}

/* $nb tabs --
 * 	Return list of tabs.
 */
static int NotebookTabsCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    Tcl_Obj *result;
    Tcl_Size i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    result = Tcl_NewListObj(0, NULL);
    for (i = 0; i < Ttk_NumberContent(mgr); ++i) {
	const char *pathName = Tk_PathName(Ttk_ContentWindow(mgr,i));

	Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(pathName,-1));
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/* $nb tab $tab ?-option ?value -option value...??
 */
static int NotebookTabCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Notebook *nb = (Notebook *)recordPtr;
    Ttk_Manager *mgr = nb->notebook.mgr;
    Tcl_Size index;
    Tk_Window window;
    Tab *tab;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
	return TCL_ERROR;
    }
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
    return TCL_OK;
}

/* Subcommand table:
 */
static const Ttk_Ensemble NotebookCommands[] = {
    { "add",    	NotebookAddCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "forget",		NotebookForgetCommand,0 },
    { "hide",		NotebookHideCommand,0 },
    { "identify",	NotebookIdentifyCommand,0 },
    { "index",		NotebookIndexCommand,0 },
    { "insert",  	NotebookInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "select",		NotebookSelectCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { "tab",   		NotebookTabCommand,0 },
    { "tabs",   	NotebookTabsCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget class hooks.







<

>








>







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
    return TCL_OK;
}

/* Subcommand table:
 */
static const Ttk_Ensemble NotebookCommands[] = {
    { "add",    	NotebookAddCommand,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.
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
	Ttk_DrawLayout(tabLayout, state, d);
    }
}

static void NotebookDisplay(void *clientData, Drawable d)
{
    Notebook *nb = (Notebook *)clientData;
    TkSizeT nContent = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT index;

    /* Draw notebook background (base layout):
     */
    Ttk_DrawLayout(nb->core.layout, nb->core.state, d);

    /* Draw tabs from left to right, but draw the current tab last
     * so it will overwrite its neighbors.
     */
    for (index = 0; index < nContent; ++index) {
	if (index != nb->notebook.currentIndex) {
	    DisplayTab(nb, index, d);
	}
    }
    if (nb->notebook.currentIndex != TCL_INDEX_NONE) {
	DisplayTab(nb, nb->notebook.currentIndex, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget specification and layout definitions.
 */







|
|













|







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
	Ttk_DrawLayout(tabLayout, state, d);
    }
}

static void NotebookDisplay(void *clientData, Drawable d)
{
    Notebook *nb = (Notebook *)clientData;
    Tcl_Size nContent = Ttk_NumberContent(nb->notebook.mgr);
    Tcl_Size index;

    /* Draw notebook background (base layout):
     */
    Ttk_DrawLayout(nb->core.layout, nb->core.state, d);

    /* Draw tabs from left to right, but draw the current tab last
     * so it will overwrite its neighbors.
     */
    for (index = 0; index < nContent; ++index) {
	if (index != nb->notebook.currentIndex) {
	    DisplayTab(nb, index, d);
	}
    }
    if (nb->notebook.currentIndex >= 0) {
	DisplayTab(nb, nb->notebook.currentIndex, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget specification and layout definitions.
 */
1408
1409
1410
1411
1412
1413
1414



1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
		TTK_NODE("Notebook.label", TTK_PACK_TOP))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */




MODULE_SCOPE
void TtkNotebook_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(themePtr, "Tab", TabLayout);
    Ttk_RegisterLayout(themePtr, "TNotebook", NotebookLayout);

    RegisterWidget(interp, "ttk::notebook", &NotebookWidgetSpec);
}

/*EOF*/







>
>
>












1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
		TTK_NODE("Notebook.label", TTK_PACK_TOP))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkNotebook_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkNotebook_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(themePtr, "Tab", TabLayout);
    Ttk_RegisterLayout(themePtr, "TNotebook", NotebookLayout);

    RegisterWidget(interp, "ttk::notebook", &NotebookWidgetSpec);
}

/*EOF*/

Changes to generic/ttk/ttkPanedwindow.c.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2005, Joe English.  Freely redistributable.
 *
 * ttk::panedwindow widget implementation.
 *
 * TODO: track active/pressed sash.
 */

#include "tkInt.h"

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright © 2005 Joe English.  Freely redistributable.
 *
 * ttk::panedwindow widget implementation.
 *
 * TODO: track active/pressed sash.
 */

#include "tkInt.h"
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
} Paned;

/* @@@ NOTE: -orient is readonly 'cause dynamic oriention changes NYI
 */
static const Tk_OptionSpec PanedOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Paned,paned.orientObj), offsetof(Paned,paned.orient),
	0, (void *)ttkOrientStrings, READONLY_OPTION|STYLE_CHANGED },
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.width),
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.height),
	0, 0, GEOMETRY_CHANGED },








|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
} 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, ttkOrientStrings, READONLY_OPTION|STYLE_CHANGED },
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.width),
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.height),
	0, 0, GEOMETRY_CHANGED },

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
}

/* ConfigurePane --
 * 	Set pane options.
 */
static int ConfigurePane(
    Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Manager *mgr = pw->paned.mgr;
    Tk_SavedOptions savedOptions;
    int mask = 0;

    if (Tk_SetOptions(interp, pane, pw->paned.paneOptionTable,
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)







|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
}

/* ConfigurePane --
 * 	Set pane options.
 */
static int ConfigurePane(
    Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window window,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Ttk_Manager *mgr = pw->paned.mgr;
    Tk_SavedOptions savedOptions;
    int mask = 0;

    if (Tk_SetOptions(interp, pane, pw->paned.paneOptionTable,
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    return pane->sashPos = pos;
}

/* ShoveDown --
 * 	Same as ShoveUp, but going in the opposite direction
 * 	and stopping at the sentinel sash.
 */
static int ShoveDown(Paned *pw, TkSizeT i, int pos)
{
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr,i);
    int sashThickness = pw->paned.sashThickness;

    if (i == Ttk_NumberContent(pw->paned.mgr) - 1) {
	pos = pane->sashPos; /* Sentinel value == container window size */
    } else {







|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    return pane->sashPos = pos;
}

/* ShoveDown --
 * 	Same as ShoveUp, but going in the opposite direction
 * 	and stopping at the sentinel sash.
 */
static int ShoveDown(Paned *pw, Tcl_Size i, int pos)
{
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr,i);
    int sashThickness = pw->paned.sashThickness;

    if (i == Ttk_NumberContent(pw->paned.mgr) - 1) {
	pos = pane->sashPos; /* Sentinel value == container window size */
    } else {
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
 * 	will leave the sashes in the same place, as long as available size
 * 	remains contant.
 */
static void AdjustPanes(Paned *pw)
{
    int sashThickness = pw->paned.sashThickness;
    int pos = 0;
    TkSizeT index;

    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;
	pane->reqSize = size >= 0 ? size : 0;
	pos = pane->sashPos + sashThickness;
    }







|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
 * 	will leave the sashes in the same place, as long as available size
 * 	remains contant.
 */
static void AdjustPanes(Paned *pw)
{
    int sashThickness = pw->paned.sashThickness;
    int pos = 0;
    Tcl_Size index;

    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;
	pane->reqSize = size >= 0 ? size : 0;
	pos = pane->sashPos + sashThickness;
    }
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
 */
static void PlacePanes(Paned *pw)
{
    int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
    int width = Tk_Width(pw->core.tkwin), height = Tk_Height(pw->core.tkwin);
    int sashThickness = pw->paned.sashThickness;
    int pos = 0;
    TkSizeT index;

    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;

	if (size > 0) {
	    if (horizontal) {







|







368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
 */
static void PlacePanes(Paned *pw)
{
    int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
    int width = Tk_Width(pw->core.tkwin), height = Tk_Height(pw->core.tkwin);
    int sashThickness = pw->paned.sashThickness;
    int pos = 0;
    Tcl_Size index;

    for (index = 0; index < Ttk_NumberContent(pw->paned.mgr); ++index) {
	Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
	int size = pane->sashPos - pos;

	if (size > 0) {
	    if (horizontal) {
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
static void PanedPlaceContent(void *managerData)
{
    Paned *pw = (Paned *)managerData;
    PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
    PlacePanes(pw);
}

static void PaneRemoved(void *managerData, TkSizeT index)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    DestroyPane(pw, pane);
}

static int AddPane(
    Tcl_Interp *interp, Paned *pw,
    int destIndex, Tk_Window window,
    int objc, Tcl_Obj *const objv[])
{
    Pane *pane;
    if (!Ttk_Maintainable(interp, window, pw->core.tkwin)) {
	return TCL_ERROR;
    }
    if (Ttk_ContentIndex(pw->paned.mgr, window) != TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%s already added", Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "PRESENT", NULL);
	return TCL_ERROR;
    }

    pane = CreatePane(interp, pw, window);







|









|





|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
static void PanedPlaceContent(void *managerData)
{
    Paned *pw = (Paned *)managerData;
    PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
    PlacePanes(pw);
}

static void PaneRemoved(void *managerData, Tcl_Size index)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    DestroyPane(pw, pane);
}

static int AddPane(
    Tcl_Interp *interp, Paned *pw,
    int destIndex, Tk_Window window,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Pane *pane;
    if (!Ttk_Maintainable(interp, window, pw->core.tkwin)) {
	return TCL_ERROR;
    }
    if (Ttk_ContentIndex(pw->paned.mgr, window) >= 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%s already added", Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "PRESENT", NULL);
	return TCL_ERROR;
    }

    pane = CreatePane(interp, pw, window);
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479








480
481
482
483
484
485
486
487
488
489
490

/* PaneRequest --
 * 	Only update pane request size if pane is currently unmapped.
 * 	Geometry requests from mapped panes are not directly honored
 * 	in order to avoid unexpected pane resizes (esp. while the
 * 	user is dragging a sash [#1325286]).
 */
static int PaneRequest(void *managerData, TkSizeT index, int width, int height)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);
    int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;

    if (!Tk_IsMapped(window)) {
	pane->reqSize = horizontal ? width : height;
    }
    return 1;
}

static Ttk_ManagerSpec PanedManagerSpec = {
    { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    PanedSize,
    PanedPlaceContent,
    PaneRequest,
    PaneRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handler.
 *
 * <<NOTE-PW-LEAVE-NOTIFYINFERIOR>>
 * Tk does not execute binding scripts for <Leave> events when
 * the pointer crosses from a parent to a child.  This widget
 * needs to know when that happens, though, so it can reset
 * the cursor.
 *
 * This event handler generates an <<EnteredChild>> virtual event
 * on LeaveNotify/NotifyInferior.








 */

static const unsigned PanedEventMask = LeaveWindowMask;
static void PanedEventProc(ClientData clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    if (   eventPtr->type == LeaveNotify
	&& eventPtr->xcrossing.detail == NotifyInferior)
    {
	Tk_SendVirtualEvent(corePtr->tkwin, "EnteredChild", NULL);
    }







|












|










<
<
<
<
<
<


>
>
>
>
>
>
>
>



|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471






472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

/* PaneRequest --
 * 	Only update pane request size if pane is currently unmapped.
 * 	Geometry requests from mapped panes are not directly honored
 * 	in order to avoid unexpected pane resizes (esp. while the
 * 	user is dragging a sash [#1325286]).
 */
static int PaneRequest(void *managerData, Tcl_Size index, int width, int height)
{
    Paned *pw = (Paned *)managerData;
    Pane *pane = (Pane *)Ttk_ContentData(pw->paned.mgr, index);
    Tk_Window window = Ttk_ContentWindow(pw->paned.mgr, index);
    int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;

    if (!Tk_IsMapped(window)) {
	pane->reqSize = horizontal ? width : height;
    }
    return 1;
}

static const Ttk_ManagerSpec PanedManagerSpec = {
    { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostContentProc },
    PanedSize,
    PanedPlaceContent,
    PaneRequest,
    PaneRemoved
};

/*------------------------------------------------------------------------
 * +++ Event handler.
 *






 * This event handler generates an <<EnteredChild>> virtual event
 * on LeaveNotify/NotifyInferior.
 * This was originally introduced because Tk used to discard events with
 * detail field NotifyInferior. The <<EnteredChild>> event was then used
 * to reset the cursor when the pointer crosses from a parent to a child.
 * Since ticket #47d4f29159, LeaveNotify/NotifyInferior are no longer
 * discarded: the <Leave> event will trigger even with NotifyInferior
 * detail field. The generated <<EnteredChild>> is nevertheless kept for
 * backwards compatibility purpose since it is publicly documented,
 * meaning that someone could bind to it.
 */

static const unsigned PanedEventMask = LeaveWindowMask;
static void PanedEventProc(void *clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    if (   eventPtr->type == LeaveNotify
	&& eventPtr->xcrossing.detail == NotifyInferior)
    {
	Tk_SendVirtualEvent(corePtr->tkwin, "EnteredChild", NULL);
    }
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
{
    Ttk_DrawLayout(SashLayout(pw, index), pw->core.state, d);
}

static void PanedDisplay(void *recordPtr, Drawable d)
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT i, nContent = Ttk_NumberContent(pw->paned.mgr);

    TtkWidgetDisplay(recordPtr, d);
    for (i = 1; i < nContent; ++i) {
	DrawSash(pw, i - 1, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget commands.
 */

/* $pw add window [ options ... ]
 */
static int PanedAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tk_Window window;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;







|














|







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
{
    Ttk_DrawLayout(SashLayout(pw, index), pw->core.state, d);
}

static void PanedDisplay(void *recordPtr, Drawable d)
{
    Paned *pw = (Paned *)recordPtr;
    Tcl_Size i, nContent = Ttk_NumberContent(pw->paned.mgr);

    TtkWidgetDisplay(recordPtr, d);
    for (i = 1; i < nContent; ++i) {
	DrawSash(pw, i - 1, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget commands.
 */

/* $pw add window [ options ... ]
 */
static int PanedAddCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tk_Window window;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
	    objc - 3, objv + 3);
}

/* $pw insert $index $window ?-option value ...?
 * 	Insert new content window, or move existing one.
 */
static int PanedInsertCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT nContent = Ttk_NumberContent(pw->paned.mgr);
    TkSizeT srcIndex, destIndex;
    Tk_Window window;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[3]), pw->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		interp,pw->paned.mgr, objv[2], &destIndex))
    {
	return TCL_ERROR;
    }

    srcIndex = Ttk_ContentIndex(pw->paned.mgr, window);
    if (srcIndex == TCL_INDEX_NONE) { /* New content: */
	return AddPane(interp, pw, destIndex, window, objc-4, objv+4);
    } /* else -- move existing content: */

    if (destIndex + 1 >= nContent + 1)
	destIndex  = nContent - 1;
    Ttk_ReorderContent(pw->paned.mgr, srcIndex, destIndex);

    return objc == 4 ? TCL_OK :
	ConfigurePane(interp, pw,
		(Pane *)Ttk_ContentData(pw->paned.mgr, destIndex),
		Ttk_ContentWindow(pw->paned.mgr, destIndex),
		objc-4, objv+4);
}

/* $pw forget $pane
 */
static int PanedForgetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT paneIndex;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp, pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex + 1 >= Ttk_NumberContent(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }
    Ttk_ForgetContent(pw->paned.mgr, paneIndex);

    return TCL_OK;
}

/* $pw identify ?what? $x $y --
 * 	Return index of sash at $x,$y
 */
static int PanedIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    static const char *const whatTable[] = { "element", "sash", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_SASH };
    int what = IDENTIFY_SASH;
    Paned *pw = (Paned *)recordPtr;
    int sashThickness = pw->paned.sashThickness;
    int nSashes = Ttk_NumberContent(pw->paned.mgr) - 1;







|


|
|




















|



|













|


|










|











|







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	    objc - 3, objv + 3);
}

/* $pw insert $index $window ?-option value ...?
 * 	Insert new content window, or move existing one.
 */
static int PanedInsertCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tcl_Size nContent = Ttk_NumberContent(pw->paned.mgr);
    Tcl_Size srcIndex, destIndex;
    Tk_Window window;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[3]), pw->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		interp,pw->paned.mgr, objv[2], &destIndex))
    {
	return TCL_ERROR;
    }

    srcIndex = Ttk_ContentIndex(pw->paned.mgr, window);
    if (srcIndex < 0) { /* New content: */
	return AddPane(interp, pw, destIndex, window, objc-4, objv+4);
    } /* else -- move existing content: */

    if (destIndex >= nContent)
	destIndex  = nContent - 1;
    Ttk_ReorderContent(pw->paned.mgr, srcIndex, destIndex);

    return objc == 4 ? TCL_OK :
	ConfigurePane(interp, pw,
		(Pane *)Ttk_ContentData(pw->paned.mgr, destIndex),
		Ttk_ContentWindow(pw->paned.mgr, destIndex),
		objc-4, objv+4);
}

/* $pw forget $pane
 */
static int PanedForgetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tcl_Size paneIndex;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp, pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex >= Ttk_NumberContent(pw->paned.mgr)) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }
    Ttk_ForgetContent(pw->paned.mgr, paneIndex);

    return TCL_OK;
}

/* $pw identify ?what? $x $y --
 * 	Return index of sash at $x,$y
 */
static int PanedIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    static const char *const whatTable[] = { "element", "sash", NULL };
    enum { IDENTIFY_ELEMENT, IDENTIFY_SASH };
    int what = IDENTIFY_SASH;
    Paned *pw = (Paned *)recordPtr;
    int sashThickness = pw->paned.sashThickness;
    int nSashes = Ttk_NumberContent(pw->paned.mgr) - 1;
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
    return TCL_OK; /* nothing found - return empty string */
}

/* $pw pane $pane ?-option ?value -option value ...??
 * 	Query/modify pane options.
 */
static int PanedPaneCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    TkSizeT paneIndex;
    Tk_Window window;
    Pane *pane;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp,pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex + 1 >= Ttk_NumberContent(pw->paned.mgr) + 1) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }

    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, paneIndex);
    window = Ttk_ContentWindow(pw->paned.mgr, paneIndex);

    switch (objc) {







|


|












|







767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
    return TCL_OK; /* nothing found - return empty string */
}

/* $pw pane $pane ?-option ?value -option value ...??
 * 	Query/modify pane options.
 */
static int PanedPaneCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tcl_Size paneIndex;
    Tk_Window window;
    Pane *pane;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value ...?");
	return TCL_ERROR;
    }

    if (TCL_OK != Ttk_GetContentIndexFromObj(
		    interp,pw->paned.mgr, objv[2], &paneIndex))
    {
	return TCL_ERROR;
    } else if (paneIndex >= Ttk_NumberContent(pw->paned.mgr)) {
	paneIndex = Ttk_NumberContent(pw->paned.mgr) - 1;
    }

    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, paneIndex);
    window = Ttk_ContentWindow(pw->paned.mgr, paneIndex);

    switch (objc) {
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
    }
}

/* $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);







|




|







806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
    }
}

/* $pw panes --
 * 	Return list of managed panes.
 */
static int PanedPanesCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Ttk_Manager *mgr = pw->paned.mgr;
    Tcl_Obj *panes;
    Tcl_Size i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    panes = Tcl_NewListObj(0, NULL);
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
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
}


/* $pw sashpos $index ?$newpos?
 * 	Query or modify sash position.
 */
static int PanedSashposCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    int sashIndex, position = -1;
    Pane *pane;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index ?newpos?");
	return TCL_ERROR;
    }
    if (Tcl_GetIntFromObj(interp, objv[2], &sashIndex) != TCL_OK) {
	return TCL_ERROR;
    }
    if (sashIndex < 0 || (TkSizeT)sashIndex + 1 >= Ttk_NumberContent(pw->paned.mgr)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "sash index %d out of range", sashIndex));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "SASH_INDEX", NULL);
	return TCL_ERROR;
    }

    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, sashIndex);

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pane->sashPos));
	return TCL_OK;
    }
    /* else -- set new sash position */

    if (Tcl_GetIntFromObj(interp, objv[3], &position) != TCL_OK) {
	return TCL_ERROR;
    }

    if (position < pane->sashPos) {
	ShoveUp(pw, sashIndex, position);
    } else {
	ShoveDown(pw, sashIndex, position);
    }

    AdjustPanes(pw);
    Ttk_ManagerLayoutChanged(pw->paned.mgr);

    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pane->sashPos));
    return TCL_OK;
}

static const Ttk_Ensemble PanedCommands[] = {
    { "add", 		PanedAddCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "forget", 	PanedForgetCommand,0 },
    { "identify", 	PanedIdentifyCommand,0 },
    { "insert", 	PanedInsertCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "pane",   	PanedPaneCommand,0 },
    { "panes",   	PanedPanesCommand,0 },
    { "sashpos",  	PanedSashposCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */








|


|






|


|

|












|


















<

>








>







833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
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
}


/* $pw sashpos $index ?$newpos?
 * 	Query or modify sash position.
 */
static int PanedSashposCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Paned *pw = (Paned *)recordPtr;
    Tcl_WideInt sashIndex, position = -1;
    Pane *pane;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index ?newpos?");
	return TCL_ERROR;
    }
    if (Tcl_GetWideIntFromObj(interp, objv[2], &sashIndex) != TCL_OK) {
	return TCL_ERROR;
    }
    if (sashIndex < 0 || sashIndex >= Ttk_NumberContent(pw->paned.mgr) - 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "sash index %" TCL_LL_MODIFIER "d out of range", sashIndex));
	Tcl_SetErrorCode(interp, "TTK", "PANE", "SASH_INDEX", NULL);
	return TCL_ERROR;
    }

    pane = (Pane *)Ttk_ContentData(pw->paned.mgr, sashIndex);

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pane->sashPos));
	return TCL_OK;
    }
    /* else -- set new sash position */

    if (Tcl_GetWideIntFromObj(interp, objv[3], &position) != TCL_OK) {
	return TCL_ERROR;
    }

    if (position < pane->sashPos) {
	ShoveUp(pw, sashIndex, position);
    } else {
	ShoveDown(pw, sashIndex, position);
    }

    AdjustPanes(pw);
    Ttk_ManagerLayoutChanged(pw->paned.mgr);

    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pane->sashPos));
    return TCL_OK;
}

static const Ttk_Ensemble PanedCommands[] = {
    { "add", 		PanedAddCommand,0 },

    { "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.
 */

928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
static const Ttk_ElementOptionSpec SashElementOptions[] = {
    { "-sashthickness", TK_OPTION_INT,
	    offsetof(SashElement,thicknessObj), "5" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SashElement *sash = (SashElement *)elementRecord;







|







931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
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 *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SashElement *sash = (SashElement *)elementRecord;
965
966
967
968
969
970
971



972
973
974
975
976
977
978
TTK_BEGIN_LAYOUT(VerticalSashLayout)
    TTK_NODE("Sash.vsash", TTK_FILL_Y)
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Registration routine.
 */



MODULE_SCOPE
void TtkPanedwindow_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
    RegisterWidget(interp, "ttk::panedwindow", &PanedWidgetSpec);

    Ttk_RegisterElement(interp, themePtr, "hsash", &SashElementSpec, 0);







>
>
>







968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
TTK_BEGIN_LAYOUT(VerticalSashLayout)
    TTK_NODE("Sash.vsash", TTK_FILL_Y)
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Registration routine.
 */
MODULE_SCOPE
void TtkPanedwindow_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkPanedwindow_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
    RegisterWidget(interp, "ttk::panedwindow", &PanedWidgetSpec);

    Ttk_RegisterElement(interp, themePtr, "hsash", &SashElementSpec, 0);

Changes to generic/ttk/ttkProgress.c.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) Joe English, Pat Thoyts, Michael Kirkham
 *
 * ttk::progressbar widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright © Joe English, Pat Thoyts, Michael Kirkham
 *
 * ttk::progressbar widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	"black", offsetof(Progressbar,progress.foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", offsetof(Progressbar,progress.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-length", "length", "Length",
        DEF_PROGRESSBAR_LENGTH, offsetof(Progressbar,progress.lengthObj), TCL_INDEX_NONE,
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
	"100", offsetof(Progressbar,progress.maximumObj), TCL_INDEX_NONE,
	0, 0, 0 },
    {TK_OPTION_STRING_TABLE, "-mode", "mode", "ProgressMode", "determinate",
	offsetof(Progressbar,progress.modeObj),
	offsetof(Progressbar,progress.mode),
	0, (void *)ProgressbarModeStrings, 0 },
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	"horizontal", offsetof(Progressbar,progress.orientObj), TCL_INDEX_NONE,
	0, (void *)ttkOrientStrings, STYLE_CHANGED },
    {TK_OPTION_INT, "-phase", "phase", "Phase",
	"0", offsetof(Progressbar,progress.phaseObj), TCL_INDEX_NONE,
	0, 0, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Progressbar,progress.textObj), TCL_INDEX_NONE,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_DOUBLE, "-value", "value", "Value",







|


|




|


|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	"black", offsetof(Progressbar,progress.foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", offsetof(Progressbar,progress.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_PROGRESSBAR_LENGTH, offsetof(Progressbar,progress.lengthObj), TCL_INDEX_NONE,
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
	"100.0", 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, ProgressbarModeStrings, 0 },
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	"horizontal", offsetof(Progressbar,progress.orientObj), TCL_INDEX_NONE,
	0, 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",
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138

139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
}

/* AnimateProgressProc --
 * 	Timer callback for progress bar animation.
 * 	Increments the -phase option, redisplays the widget,
 * 	and reschedules itself if animation still enabled.
 */
static void AnimateProgressProc(ClientData clientData)
{
    Progressbar *pb = (Progressbar *)clientData;

    pb->progress.timer = 0;

    if (AnimationEnabled(pb)) {
	int phase = 0;
	Tcl_GetIntFromObj(NULL, pb->progress.phaseObj, &phase);

	/*
	 * Update -phase:
	 */

	++phase;
	if (pb->progress.maxPhase)
	    phase %= pb->progress.maxPhase;

	Tcl_DecrRefCount(pb->progress.phaseObj);
	pb->progress.phaseObj = Tcl_NewWideIntObj(phase);
	Tcl_IncrRefCount(pb->progress.phaseObj);

	/*
	 * Reschedule:
	 */

	pb->progress.timer = Tcl_CreateTimerHandler(
	    pb->progress.period, AnimateProgressProc, clientData);

	TtkRedisplayWidget(&pb->core);
    }
}

/* CheckAnimation --
 * 	If animation is enabled and not scheduled, schedule it.
 * 	If animation is disabled but scheduled, cancel it.







|




<







>

|
|
>







>


<







116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
}

/* AnimateProgressProc --
 * 	Timer callback for progress bar animation.
 * 	Increments the -phase option, redisplays the widget,
 * 	and reschedules itself if animation still enabled.
 */
static void AnimateProgressProc(void *clientData)
{
    Progressbar *pb = (Progressbar *)clientData;

    pb->progress.timer = 0;

    if (AnimationEnabled(pb)) {
	int phase = 0;
	Tcl_GetIntFromObj(NULL, pb->progress.phaseObj, &phase);

	/*
	 * Update -phase:
	 */

	++phase;
	if (phase > pb->progress.maxPhase) {
	    phase = 0;
	}
	Tcl_DecrRefCount(pb->progress.phaseObj);
	pb->progress.phaseObj = Tcl_NewWideIntObj(phase);
	Tcl_IncrRefCount(pb->progress.phaseObj);

	/*
	 * Reschedule:
	 */

	pb->progress.timer = Tcl_CreateTimerHandler(
	    pb->progress.period, AnimateProgressProc, clientData);

	TtkRedisplayWidget(&pb->core);
    }
}

/* CheckAnimation --
 * 	If animation is enabled and not scheduled, schedule it.
 * 	If animation is disabled but scheduled, cancel it.
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;

    TtkWidgetSize(recordPtr, widthPtr, heightPtr);

    /* Override requested width (height) based on -length and -orient
     */
    Tk_GetPixelsFromObj(NULL, pb->core.tkwin, pb->progress.lengthObj, &length);
    TtkGetOrientFromObj(NULL, pb->progress.orientObj, &orient);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = length;
    } else {
	*heightPtr = length;
    }








|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;

    TtkWidgetSize(recordPtr, widthPtr, heightPtr);

    /* Override requested width (height) based on -length and -orient
     */
    Tk_GetPixelsFromObj(NULL, pb->core.tkwin, pb->progress.lengthObj, &length);
    Ttk_GetOrientFromObj(NULL, pb->progress.orientObj, &orient);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = length;
    } else {
	*heightPtr = length;
    }

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
    Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));

    /* Adjust the bar size:
     */

    Tcl_GetDoubleFromObj(NULL, pb->progress.valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum);
    TtkGetOrientFromObj(NULL, pb->progress.orientObj, &orient);

    if (pbar) {
	double fraction = value / maximum;
	Ttk_Box parcel = Ttk_ClientRegion(corePtr->layout, "trough");

	if (pb->progress.mode == TTK_PROGRESSBAR_DETERMINATE) {
	    ProgressbarDeterminateLayout(







|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));

    /* Adjust the bar size:
     */

    Tcl_GetDoubleFromObj(NULL, pb->progress.valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum);
    Ttk_GetOrientFromObj(NULL, pb->progress.orientObj, &orient);

    if (pbar) {
	double fraction = value / maximum;
	Ttk_Box parcel = Ttk_ClientRegion(corePtr->layout, "trough");

	if (pb->progress.mode == TTK_PROGRESSBAR_DETERMINATE) {
	    ProgressbarDeterminateLayout(
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
/*------------------------------------------------------------------------
 * +++ Widget commands:
 */

/* $sb step ?amount?
 */
static int ProgressbarStepCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Progressbar *pb = (Progressbar *)recordPtr;
    double value = 0.0, stepAmount = 1.0;
    Tcl_Obj *newValueObj;

    if (objc == 3) {
	if (Tcl_GetDoubleFromObj(interp, objv[2], &stepAmount) != TCL_OK) {







|







419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
/*------------------------------------------------------------------------
 * +++ Widget commands:
 */

/* $sb step ?amount?
 */
static int ProgressbarStepCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Progressbar *pb = (Progressbar *)recordPtr;
    double value = 0.0, stepAmount = 1.0;
    Tcl_Obj *newValueObj;

    if (objc == 3) {
	if (Tcl_GetDoubleFromObj(interp, objv[2], &stepAmount) != TCL_OK) {
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522

523
524
525
526
527
528

529
530
531
532
533
534
535
}

/* $sb start|stop ?args? --
 * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...]
 * and pass to interpreter.
 */
static int ProgressbarStartStopCommand(
    Tcl_Interp *interp, const char *cmdName, int objc, Tcl_Obj *const objv[])
{
    Tcl_Obj *cmd = Tcl_NewListObj(objc, objv);
    Tcl_Obj *prefix[2];
    int status;

    /* ASSERT: objc >= 2 */

    prefix[0] = Tcl_NewStringObj(cmdName, -1);
    prefix[1] = objv[0];
    Tcl_ListObjReplace(interp, cmd, 0,2, 2,prefix);

    Tcl_IncrRefCount(cmd);
    status = Tcl_EvalObjEx(interp, cmd, 0);
    Tcl_DecrRefCount(cmd);

    return status;
}

static int ProgressbarStartCommand(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	    interp, "::ttk::progressbar::start", objc, objv);
}

static int ProgressbarStopCommand(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	    interp, "::ttk::progressbar::stop", objc, objv);
}

static const Ttk_Ensemble ProgressbarCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "start", 		ProgressbarStartCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "step", 		ProgressbarStepCommand,0 },
    { "stop", 		ProgressbarStopCommand,0 },

    { 0,0,0 }
};

/*
 * Widget specification:
 */
static const WidgetSpec ProgressbarWidgetSpec =







|









|











|









|







<

>






>







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
}

/* $sb start|stop ?args? --
 * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...]
 * and pass to interpreter.
 */
static int ProgressbarStartStopCommand(
    Tcl_Interp *interp, const char *cmdName, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Tcl_Obj *cmd = Tcl_NewListObj(objc, objv);
    Tcl_Obj *prefix[2];
    int status;

    /* ASSERT: objc >= 2 */

    prefix[0] = Tcl_NewStringObj(cmdName, -1);
    prefix[1] = objv[0];
    Tcl_ListObjReplace(interp, cmd, 0, 2, 2,prefix);

    Tcl_IncrRefCount(cmd);
    status = Tcl_EvalObjEx(interp, cmd, 0);
    Tcl_DecrRefCount(cmd);

    return status;
}

static int ProgressbarStartCommand(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	    interp, "::ttk::progressbar::start", objc, objv);
}

static int ProgressbarStopCommand(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    return ProgressbarStartStopCommand(
	    interp, "::ttk::progressbar::stop", objc, objv);
}

static const Ttk_Ensemble ProgressbarCommands[] = {

    { "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 =
555
556
557
558
559
560
561
562
563
564
565
566
567
568



569
570
571
572
573
574
575
    TTK_GROUP("Vertical.Progressbar.trough", TTK_FILL_BOTH,
	TTK_NODE("Vertical.Progressbar.pbar", TTK_PACK_BOTTOM|TTK_FILL_X))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(HorizontalProgressbarLayout)
    TTK_GROUP("Horizontal.Progressbar.trough", TTK_FILL_BOTH,
	TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y)
	TTK_NODE("Horizontal.Progressbar.text", TTK_PACK_LEFT))
TTK_END_LAYOUT

/*
 * Initialization:
 */




MODULE_SCOPE
void TtkProgressbar_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(themePtr,
	"Vertical.TProgressbar", VerticalProgressbarLayout);







|






>
>
>







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
    TTK_GROUP("Vertical.Progressbar.trough", TTK_FILL_BOTH,
	TTK_NODE("Vertical.Progressbar.pbar", TTK_PACK_BOTTOM|TTK_FILL_X))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(HorizontalProgressbarLayout)
    TTK_GROUP("Horizontal.Progressbar.trough", TTK_FILL_BOTH,
	TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y)
	TTK_NODE("Horizontal.Progressbar.ctext", TTK_PACK_LEFT))
TTK_END_LAYOUT

/*
 * Initialization:
 */

MODULE_SCOPE
void TtkProgressbar_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkProgressbar_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(themePtr,
	"Vertical.TProgressbar", VerticalProgressbarLayout);

Changes to generic/ttk/ttkScale.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * Copyright (C) 2004 Pat Thoyts <[email protected]>
 *
 * ttk::scale widget.
 */

#include "tkInt.h"
#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#define DEF_SCALE_LENGTH "100"

#define MAX(a,b) ((a) > (b) ? (a) : (b))

|




<







1
2
3
4
5
6

7
8
9
10
11
12
13
/*
 * Copyright © 2004 Pat Thoyts <[email protected]>
 *
 * ttk::scale widget.
 */


#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#define DEF_SCALE_LENGTH "100"

#define MAX(a,b) ((a) > (b) ? (a) : (b))
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
	offsetof(Scale,scale.commandObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable", "",
	offsetof(Scale,scale.variableObj), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Scale,scale.orientObj),
	offsetof(Scale,scale.orient), 0,
	(void *)ttkOrientStrings, STYLE_CHANGED },

    {TK_OPTION_DOUBLE, "-from", "from", "From", "0",
	offsetof(Scale,scale.fromObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0",
	offsetof(Scale,scale.toObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
	offsetof(Scale,scale.valueObj), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, offsetof(Scale,scale.lengthObj), TCL_INDEX_NONE, 0, 0,
    	GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Scale,scale.stateObj), TCL_INDEX_NONE,







|
|

|



|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
	offsetof(Scale,scale.commandObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable", "",
	offsetof(Scale,scale.variableObj), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Scale,scale.orientObj),
	offsetof(Scale,scale.orient),
	0, ttkOrientStrings, STYLE_CHANGED },

    {TK_OPTION_DOUBLE, "-from", "from", "From", "0.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.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,
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

/* $scale get ?x y? --
 * 	Returns the current value of the scale widget, or if $x and
 * 	$y are specified, the value represented by point @x,y.
 */
static int
ScaleGetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)recordPtr;
    int x, y, r = TCL_OK;
    double value = 0;

    if ((objc != 2) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 1, objv, "get ?x y?");
	return TCL_ERROR;
    }
    if (objc == 2) {
	Tcl_SetObjResult(interp, scalePtr->scale.valueObj);
    } else {
	r = Tcl_GetIntFromObj(interp, objv[2], &x);
	if (r == TCL_OK)
	    r = Tcl_GetIntFromObj(interp, objv[3], &y);
	if (r == TCL_OK) {
	    value = PointToValue(scalePtr, x, y);
	    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
	}



    }
    return r;
}

/* $scale set $newValue
 */
static int
ScaleSetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)recordPtr;
    double from = 0.0, to = 1.0, value;
    int result = TCL_OK;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "set value");







|





<
<
<
<


|







>
>
>








|







257
258
259
260
261
262
263
264
265
266
267
268
269




270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

/* $scale get ?x y? --
 * 	Returns the current value of the scale widget, or if $x and
 * 	$y are specified, the value represented by point @x,y.
 */
static int
ScaleGetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)recordPtr;
    int x, y, r = TCL_OK;
    double value = 0;





    if (objc == 2) {
	Tcl_SetObjResult(interp, scalePtr->scale.valueObj);
    } else if (objc == 4) {
	r = Tcl_GetIntFromObj(interp, objv[2], &x);
	if (r == TCL_OK)
	    r = Tcl_GetIntFromObj(interp, objv[3], &y);
	if (r == TCL_OK) {
	    value = PointToValue(scalePtr, x, y);
	    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
	}
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "get ?x y?");
	return TCL_ERROR;
    }
    return r;
}

/* $scale set $newValue
 */
static int
ScaleSetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)recordPtr;
    double from = 0.0, to = 1.0, value;
    int result = TCL_OK;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "set value");
354
355
356
357
358
359
360
361
362
363
364
365
366
367




368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    }

    return result;
}

static int
ScaleCoordsCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)recordPtr;
    double value;
    int r = TCL_OK;

    if (objc < 2 || objc > 3) {




	Tcl_WrongNumArgs(interp, 1, objv, "coords ?value?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	r = Tcl_GetDoubleFromObj(interp, objv[2], &value);
    } else {
	r = Tcl_GetDoubleFromObj(interp, scalePtr->scale.valueObj, &value);
    }

    if (r == TCL_OK) {
	Tcl_Obj *point[2];
	XPoint pt = ValueToPoint(scalePtr, value);
	point[0] = Tcl_NewWideIntObj(pt.x);
	point[1] = Tcl_NewWideIntObj(pt.y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, point));
    }







|





|
>
>
>
>




<
<
<
<
<
<







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373






374
375
376
377
378
379
380
    }

    return result;
}

static int
ScaleCoordsCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scale *scalePtr = (Scale *)recordPtr;
    double value;
    int r = TCL_OK;

    if (objc == 3) {
	r = Tcl_GetDoubleFromObj(interp, objv[2], &value);
    } else if (objc == 2) {
	r = Tcl_GetDoubleFromObj(interp, scalePtr->scale.valueObj, &value);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "coords ?value?");
	return TCL_ERROR;
    }







    if (r == TCL_OK) {
	Tcl_Obj *point[2];
	XPoint pt = ValueToPoint(scalePtr, value);
	point[0] = Tcl_NewWideIntObj(pt.x);
	point[1] = Tcl_NewWideIntObj(pt.y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, point));
    }
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[] = {

    { "configure",   TtkWidgetConfigureCommand,0 },

    { "cget",        TtkWidgetCgetCommand,0 },
    { "state",       TtkWidgetStateCommand,0 },
    { "instate",     TtkWidgetInstateCommand,0 },
    { "identify",    TtkWidgetIdentifyCommand,0 },
    { "set",         ScaleSetCommand,0 },
    { "get",         ScaleGetCommand,0 },
    { "coords",      ScaleCoordsCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ScaleWidgetSpec =
{
    "TScale",			/* Class name */
    sizeof(Scale),		/* record size */







>

>
|
|

<

|
|







475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
495
496
497
	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 },
    { "get",         ScaleGetCommand,0 },
    { "identify",    TtkWidgetIdentifyCommand,0 },
    { "instate",     TtkWidgetInstateCommand,0 },

    { "set",         ScaleSetCommand,0 },
    { "state",       TtkWidgetStateCommand,0 },
    { "style",		TtkWidgetStyleCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ScaleWidgetSpec =
{
    "TScale",			/* Class name */
    sizeof(Scale),		/* record size */
519
520
521
522
523
524
525



526
527
528
529
530
531
532
533
534
535
536
    TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
	TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )
TTK_END_LAYOUT

/*
 * Initialization.
 */



MODULE_SCOPE
void TtkScale_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "Vertical.TScale", VerticalScaleLayout);
    Ttk_RegisterLayout(theme, "Horizontal.TScale", HorizontalScaleLayout);

    RegisterWidget(interp, "ttk::scale", &ScaleWidgetSpec);
}








>
>
>











516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
    TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
	TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )
TTK_END_LAYOUT

/*
 * Initialization.
 */
MODULE_SCOPE
void TtkScale_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkScale_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "Vertical.TScale", VerticalScaleLayout);
    Ttk_RegisterLayout(theme, "Horizontal.TScale", HorizontalScaleLayout);

    RegisterWidget(interp, "ttk::scale", &ScaleWidgetSpec);
}

Changes to generic/ttk/ttkScroll.c.

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
	return TCL_OK;
    }

    arg1[0] = arg2[0] = ' ';
    Tcl_PrintDouble(interp, (double)s->first / s->total, arg1+1);
    Tcl_PrintDouble(interp, (double)s->last / s->total, arg2+1);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, s->scrollCmd, -1);
    Tcl_DStringAppend(&buf, arg1, -1);
    Tcl_DStringAppend(&buf, arg2, -1);

    Tcl_Preserve(corePtr);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (WidgetDestroyed(corePtr)) {
	Tcl_Release(corePtr);
	return TCL_ERROR;







|
|
|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
	return TCL_OK;
    }

    arg1[0] = arg2[0] = ' ';
    Tcl_PrintDouble(interp, (double)s->first / s->total, arg1+1);
    Tcl_PrintDouble(interp, (double)s->last / s->total, arg2+1);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, s->scrollCmd, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, arg1, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, arg2, TCL_INDEX_NONE);

    Tcl_Preserve(corePtr);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (WidgetDestroyed(corePtr)) {
	Tcl_Release(corePtr);
	return TCL_ERROR;
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    }
    return code;
}

/* UpdateScrollbarBG --
 * 	Idle handler to update the scrollbar.
 */
static void UpdateScrollbarBG(ClientData clientData)
{
    ScrollHandle h = (ScrollHandle)clientData;
    Tcl_Interp *interp = h->corePtr->interp;
    int code;

    h->flags &= ~SCROLL_UPDATE_PENDING;
    Tcl_Preserve(interp);







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    }
    return code;
}

/* UpdateScrollbarBG --
 * 	Idle handler to update the scrollbar.
 */
static void UpdateScrollbarBG(void *clientData)
{
    ScrollHandle h = (ScrollHandle)clientData;
    Tcl_Interp *interp = h->corePtr->interp;
    int code;

    h->flags &= ~SCROLL_UPDATE_PENDING;
    Tcl_Preserve(interp);
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 *
 *  $w [xy]view -- return current view region
 *  $w [xy]view $index -- set topmost item
 *  $w [xy]view moveto $fraction
 *  $w [xy]view scroll $number $what -- scrollbar interface
 */
int TtkScrollviewCommand(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle h)
{
    Scrollable *s = h->scrollPtr;
    int newFirst;

    TtkUpdateScrollInfo(h);
    newFirst = s->first;








|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 *
 *  $w [xy]view -- return current view region
 *  $w [xy]view $index -- set topmost item
 *  $w [xy]view moveto $fraction
 *  $w [xy]view scroll $number $what -- scrollbar interface
 */
int TtkScrollviewCommand(
    Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], ScrollHandle h)
{
    Scrollable *s = h->scrollPtr;
    int newFirst;

    TtkUpdateScrollInfo(h);
    newFirst = s->first;

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244


245
246
247
248
249
250
251
	    return TCL_ERROR;
	}
    } else {
	double fraction;
	int count;

	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
	    case TK_SCROLL_ERROR:
		return TCL_ERROR;
	    case TK_SCROLL_MOVETO:
		newFirst = (int) ((fraction * s->total) + 0.5);
		break;
	    case TK_SCROLL_UNITS:
		newFirst = s->first + count;
		break;
	    case TK_SCROLL_PAGES: {
		int perPage = s->last - s->first;	/* @@@ */
		newFirst = s->first + count * perPage;
		break;
	    }


	}
    }

    TtkScrollTo(h, newFirst, 0);

    return TCL_OK;
}







<
<











>
>







225
226
227
228
229
230
231


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
	    return TCL_ERROR;
	}
    } else {
	double fraction;
	int count;

	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {


	    case TK_SCROLL_MOVETO:
		newFirst = (int) ((fraction * s->total) + 0.5);
		break;
	    case TK_SCROLL_UNITS:
		newFirst = s->first + count;
		break;
	    case TK_SCROLL_PAGES: {
		int perPage = s->last - s->first;	/* @@@ */
		newFirst = s->first + count * perPage;
		break;
	    }
	    default:
		return TCL_ERROR;
	}
    }

    TtkScrollTo(h, newFirst, 0);

    return TCL_OK;
}

Changes to generic/ttk/ttkScrollbar.c.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2003, Joe English
 *
 * ttk::scrollbar widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright © 2003 Joe English
 *
 * ttk::scrollbar widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scrollbar, scrollbar.commandObj), TCL_INDEX_NONE, 0, 0, 0},

    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Scrollbar, scrollbar.orientObj),
	offsetof(Scrollbar, scrollbar.orient),
	0, (void *)ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Widget hooks.







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scrollbar, scrollbar.commandObj), TCL_INDEX_NONE, 0, 0, 0},

    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Scrollbar, scrollbar.orientObj),
	offsetof(Scrollbar, scrollbar.orient),
	0, ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Widget hooks.
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
 */

/* $sb set $first $last --
 * 	Set the position of the scrollbar.
 */
static int
ScrollbarSetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scrollbar *scrollbar = (Scrollbar *)recordPtr;
    Tcl_Obj *firstObj, *lastObj;
    double first, last;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "first last");







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
 */

/* $sb set $first $last --
 * 	Set the position of the scrollbar.
 */
static int
ScrollbarSetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scrollbar *scrollbar = (Scrollbar *)recordPtr;
    Tcl_Obj *firstObj, *lastObj;
    double first, last;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "first last");
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
}

/* $sb get --
 * 	Returns the last thing passed to 'set'.
 */
static int
ScrollbarGetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scrollbar *scrollbar = (Scrollbar *)recordPtr;
    Tcl_Obj *result[2];

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
}

/* $sb get --
 * 	Returns the last thing passed to 'set'.
 */
static int
ScrollbarGetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scrollbar *scrollbar = (Scrollbar *)recordPtr;
    Tcl_Obj *result[2];

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

/* $sb delta $dx $dy --
 * 	Returns the percentage change corresponding to a mouse movement
 * 	of $dx, $dy.
 */
static int
ScrollbarDeltaCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scrollbar *sb = (Scrollbar *)recordPtr;
    double dx, dy;
    double delta = 0.0;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "dx dy");







|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

/* $sb delta $dx $dy --
 * 	Returns the percentage change corresponding to a mouse movement
 * 	of $dx, $dy.
 */
static int
ScrollbarDeltaCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scrollbar *sb = (Scrollbar *)recordPtr;
    double dx, dy;
    double delta = 0.0;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "dx dy");
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

/* $sb fraction $x $y --
 * 	Returns a real number between 0 and 1 indicating  where  the
 * 	point given by x and y lies in the trough area of the scrollbar.
 */
static int
ScrollbarFractionCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Scrollbar *sb = (Scrollbar *)recordPtr;
    Ttk_Box b = sb->scrollbar.troughBox;
    int minSize = sb->scrollbar.minSize;
    double x, y;
    double fraction = 0.0;








|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

/* $sb fraction $x $y --
 * 	Returns a real number between 0 and 1 indicating  where  the
 * 	point given by x and y lies in the trough area of the scrollbar.
 */
static int
ScrollbarFractionCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Scrollbar *sb = (Scrollbar *)recordPtr;
    Ttk_Box b = sb->scrollbar.troughBox;
    int minSize = sb->scrollbar.minSize;
    double x, y;
    double fraction = 0.0;

278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293

294
295
296
297
298
299
300
    }

    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
    return TCL_OK;
}

static const Ttk_Ensemble ScrollbarCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "delta",    	ScrollbarDeltaCommand,0 },
    { "fraction",    	ScrollbarFractionCommand,0 },
    { "get",    	ScrollbarGetCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "set",  		ScrollbarSetCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */
static const WidgetSpec ScrollbarWidgetSpec =







<

>







>







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[] = {

    { "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 =
327
328
329
330
331
332
333



334
335
336
337
338
339
340
341
342
343
344
345
	TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */




MODULE_SCOPE
void TtkScrollbar_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme,"Vertical.TScrollbar",VerticalScrollbarLayout);
    Ttk_RegisterLayout(theme,"Horizontal.TScrollbar",HorizontalScrollbarLayout);

    RegisterWidget(interp, "ttk::scrollbar", &ScrollbarWidgetSpec);
}

/*EOF*/







>
>
>












328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
	TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkScrollbar_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkScrollbar_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme,"Vertical.TScrollbar",VerticalScrollbarLayout);
    Ttk_RegisterLayout(theme,"Horizontal.TScrollbar",HorizontalScrollbarLayout);

    RegisterWidget(interp, "ttk::scrollbar", &ScrollbarWidgetSpec);
}

/*EOF*/

Changes to generic/ttk/ttkSeparator.c.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::separator and ttk::sizegrip widgets.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

|







1
2
3
4
5
6
7
8
9
/*
 * 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
    SeparatorPart separator;
} Separator;

static const Tk_OptionSpec SeparatorOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Separator,separator.orientObj),
	offsetof(Separator,separator.orient),
	0, (void *)ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * GetLayout hook --







|







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, 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
	interp, theme, recordPtr, sep->separator.orientObj);
}

/*
 * Widget commands:
 */
static const Ttk_Ensemble SeparatorCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { 0,0,0 }
};

/*
 * Widget specification:
 */
static const WidgetSpec SeparatorWidgetSpec =







<

>



>







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[] = {

    { "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

static const Tk_OptionSpec SizegripOptionSpecs[] = {
    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static const Ttk_Ensemble SizegripCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { 0,0,0 }
};

static const WidgetSpec SizegripWidgetSpec =
{
    "TSizegrip",		/* className */
    sizeof(WidgetCore),		/* recordSize */







<

>



>







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[] = {

    { "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 */
116
117
118
119
120
121
122



123
124
125
126
127
128
129
130
131
132
133
134
135
TTK_BEGIN_LAYOUT(SizegripLayout)
    TTK_NODE("Sizegrip.sizegrip", TTK_PACK_BOTTOM|TTK_STICK_S|TTK_STICK_E)
TTK_END_LAYOUT

/* +++ Initialization:
 */




MODULE_SCOPE
void TtkSeparator_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TSeparator", SeparatorLayout);
    Ttk_RegisterLayout(theme, "TSizegrip", SizegripLayout);

    RegisterWidget(interp, "ttk::separator", &SeparatorWidgetSpec);
    RegisterWidget(interp, "ttk::sizegrip", &SizegripWidgetSpec);
}

/*EOF*/







>
>
>













118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
TTK_BEGIN_LAYOUT(SizegripLayout)
    TTK_NODE("Sizegrip.sizegrip", TTK_PACK_BOTTOM|TTK_STICK_S|TTK_STICK_E)
TTK_END_LAYOUT

/* +++ Initialization:
 */

MODULE_SCOPE
void TtkSeparator_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkSeparator_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TSeparator", SeparatorLayout);
    Ttk_RegisterLayout(theme, "TSizegrip", SizegripLayout);

    RegisterWidget(interp, "ttk::separator", &SeparatorWidgetSpec);
    RegisterWidget(interp, "ttk::sizegrip", &SizegripWidgetSpec);
}

/*EOF*/

Changes to generic/ttk/ttkSquare.c.

1
2
3
4
5
6
7
8
/* square.c - Copyright (C) 2004 Pat Thoyts <[email protected]>
 *
 * Minimal sample ttk widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
|







1
2
3
4
5
6
7
8
/* square.c - Copyright © 2004 Pat Thoyts <[email protected]>
 *
 * Minimal sample ttk widget.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
     offsetof(Square,square.paddingObj), TCL_INDEX_NONE,
     TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
     NULL, offsetof(Square,square.reliefObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},

    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
     NULL, offsetof(Square,square.anchorObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Almost all of the widget functionality is handled by the default Ttk







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
     offsetof(Square,square.paddingObj), TCL_INDEX_NONE,
     TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
     NULL, offsetof(Square,square.reliefObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},

    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
     "center", offsetof(Square,square.anchorObj), TCL_INDEX_NONE, 0, 0, 0},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Almost all of the widget functionality is handled by the default Ttk
125
126
127
128
129
130
131
132
133

134
135
136

137
138
139
140
141
142
143
/*
 * Widget commands. A widget is impelemented as an ensemble and the
 * subcommands are listed here. Ttk provides default implementations
 * that are sufficient for our needs.
 */

static const Ttk_Ensemble SquareCommands[] = {
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },

    { "identify",	TtkWidgetIdentifyCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { 0,0,0 }
};

/*
 * The Widget specification structure holds all the implementation
 * information about this widget and this is what must be registered
 * with Tk in the package initialization code (see bottom).







<

>



>







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[] = {

    { "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
234
/*
 * The element geometry function is called when the layout code wishes to
 * find out how big this element wants to be. We must return our preferred
 * size and padding information
 */

static void SquareElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    SquareElement *square = (SquareElement *)elementRecord;
    int borderWidth = 0;

    Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, square->widthObj, widthPtr);
    Tk_GetPixelsFromObj(NULL, tkwin, square->heightObj, heightPtr);
}

/*
 * Draw the element in the box provided.
 */

static void SquareElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(unsigned int))
{
    SquareElement *square = (SquareElement *)elementRecord;
    Tk_3DBorder foreground = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;

    foreground = Tk_Get3DBorderFromObj(tkwin, square->foregroundObj);
    Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);







|




















|




|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 * 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 *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    SquareElement *square = (SquareElement *)elementRecord;
    int borderWidth = 0;

    Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
    *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 *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    SquareElement *square = (SquareElement *)elementRecord;
    Tk_3DBorder foreground = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;

    foreground = Tk_Get3DBorderFromObj(tkwin, square->foregroundObj);
    Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
284
285
286
287
288
289
290



291
292
293
294
295
296
297
 * new instance. If this is done, a new layout will need to be created (which
 * can be done at script level). Some widgets may require particular elements
 * to be present but we try to avoid this where possible. In this widget's C
 * code, no reference is made to any particular elements. The programmer is
 * free to specify a new style using completely different elements.
 */




/* public */ MODULE_SCOPE int
TtkSquareWidget_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    /* register the new elements for this theme engine */
    Ttk_RegisterElement(interp, theme, "square", &SquareElementSpec, NULL);







>
>
>







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
 * new instance. If this is done, a new layout will need to be created (which
 * can be done at script level). Some widgets may require particular elements
 * to be present but we try to avoid this where possible. In this widget's C
 * code, no reference is made to any particular elements. The programmer is
 * free to specify a new style using completely different elements.
 */

MODULE_SCOPE int
TtkSquareWidget_Init(Tcl_Interp *interp);

/* public */ MODULE_SCOPE int
TtkSquareWidget_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    /* register the new elements for this theme engine */
    Ttk_RegisterElement(interp, theme, "square", &SquareElementSpec, NULL);

Changes to generic/ttk/ttkState.c.

1
2
3
4
5
6
7
8
9
10
11
/*
 * Tk widget state utilities.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*



|







1
2
3
4
5
6
7
8
9
10
11
/*
 * Tk widget state utilities.
 *
 * Copyright © 2003 Joe English.  Freely redistributable.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

static int  StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);
/* static void StateSpecFreeIntRep(Tcl_Obj *); */
#define StateSpecFreeIntRep 0		/* not needed */
static void StateSpecDupIntRep(Tcl_Obj *, Tcl_Obj *);
static void StateSpecUpdateString(Tcl_Obj *);

static
struct Tcl_ObjType StateSpecObjType =
{
    "StateSpec",
    StateSpecFreeIntRep,
    StateSpecDupIntRep,
    StateSpecUpdateString,
    StateSpecSetFromAny


};

static void StateSpecDupIntRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr)
{
    copyPtr->internalRep.longValue = srcPtr->internalRep.longValue;
    copyPtr->typePtr = &StateSpecObjType;
}

static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
    int status;
    int objc;
    Tcl_Obj **objv;
    int i;
    unsigned int onbits = 0, offbits = 0;

    status = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv);
    if (status != TCL_OK)
	return status;

    for (i = 0; i < objc; ++i) {







|
|

|



|
>
>





|





|

<







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82

static int  StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);
/* static void StateSpecFreeIntRep(Tcl_Obj *); */
#define StateSpecFreeIntRep 0		/* not needed */
static void StateSpecDupIntRep(Tcl_Obj *, Tcl_Obj *);
static void StateSpecUpdateString(Tcl_Obj *);

static const
TkObjType StateSpecObjType =
{
    {"StateSpec",
    StateSpecFreeIntRep,
    StateSpecDupIntRep,
    StateSpecUpdateString,
    StateSpecSetFromAny,
    TCL_OBJTYPE_V0},
    0
};

static void StateSpecDupIntRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr)
{
    copyPtr->internalRep.longValue = srcPtr->internalRep.longValue;
    copyPtr->typePtr = &StateSpecObjType.objType;
}

static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
    int status;
    Tcl_Size i, objc;
    Tcl_Obj **objv;

    unsigned int onbits = 0, offbits = 0;

    status = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv);
    if (status != TCL_OK)
	return status;

    for (i = 0; i < objc; ++i) {
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

    /* Invalidate old intrep:
     */
    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &StateSpecObjType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return TCL_OK;
}

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    unsigned int mask = onbits | offbits;
    Tcl_DString result;
    int i;
    int len;

    Tcl_DStringInit(&result);

    for (i=0; stateNames[i] != NULL; ++i) {
	if (mask & (1<<i)) {
	    if (offbits & (1<<i))
		Tcl_DStringAppend(&result, "!", 1);
	    Tcl_DStringAppend(&result, stateNames[i], -1);
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */







|




















|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

    /* Invalidate old intrep:
     */
    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &StateSpecObjType.objType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return TCL_OK;
}

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    unsigned int mask = onbits | offbits;
    Tcl_DString result;
    int i;
    int len;

    Tcl_DStringInit(&result);

    for (i=0; stateNames[i] != NULL; ++i) {
	if (mask & (1<<i)) {
	    if (offbits & (1<<i))
		Tcl_DStringAppend(&result, "!", 1);
	    Tcl_DStringAppend(&result, stateNames[i], TCL_INDEX_NONE);
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
}

Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits, unsigned int offbits)
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_InvalidateStringRep(objPtr);
    objPtr->typePtr = &StateSpecObjType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return objPtr;
}

int Ttk_GetStateSpecFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    Ttk_StateSpec *spec)
{
    if (objPtr->typePtr != &StateSpecObjType) {
	int status = StateSpecSetFromAny(interp, objPtr);
	if (status != TCL_OK)
	    return status;
    }

    spec->onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    spec->offbits = objPtr->internalRep.longValue & 0x0000FFFF;







|










|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
}

Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits, unsigned int offbits)
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_InvalidateStringRep(objPtr);
    objPtr->typePtr = &StateSpecObjType.objType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return objPtr;
}

int Ttk_GetStateSpecFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    Ttk_StateSpec *spec)
{
    if (objPtr->typePtr != &StateSpecObjType.objType) {
	int status = StateSpecSetFromAny(interp, objPtr);
	if (status != TCL_OK)
	    return status;
    }

    spec->onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    spec->offbits = objPtr->internalRep.longValue & 0x0000FFFF;
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 */
Tcl_Obj *Ttk_StateMapLookup(
    Tcl_Interp *interp,		/* Where to leave error messages; may be NULL */
    Ttk_StateMap map,		/* State map */
    Ttk_State state)    	/* State to look up */
{
    Tcl_Obj **specs;
    int nSpecs;
    int j, status;

    status = Tcl_ListObjGetElements(interp, map, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    for (j = 0; j < nSpecs; j += 2) {
	Ttk_StateSpec spec;







|
|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 */
Tcl_Obj *Ttk_StateMapLookup(
    Tcl_Interp *interp,		/* Where to leave error messages; may be NULL */
    Ttk_StateMap map,		/* State map */
    Ttk_State state)    	/* State to look up */
{
    Tcl_Obj **specs;
    Tcl_Size j, nSpecs;
    int status;

    status = Tcl_ListObjGetElements(interp, map, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    for (j = 0; j < nSpecs; j += 2) {
	Ttk_StateSpec spec;
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
 * 	this basically just checks for errors.
 */
Ttk_StateMap Ttk_GetStateMapFromObj(
    Tcl_Interp *interp,		/* Where to leave error messages; may be NULL */
    Tcl_Obj *mapObj)		/* State map */
{
    Tcl_Obj **specs;
    int nSpecs;
    int j, status;

    status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    if (nSpecs % 2 != 0) {
	if (interp) {







|
|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
 * 	this basically just checks for errors.
 */
Ttk_StateMap Ttk_GetStateMapFromObj(
    Tcl_Interp *interp,		/* Where to leave error messages; may be NULL */
    Tcl_Obj *mapObj)		/* State map */
{
    Tcl_Obj **specs;
    Tcl_Size j, nSpecs;
    int status;

    status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    if (nSpecs % 2 != 0) {
	if (interp) {
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    return mapObj;
}

/*
 * Ttk_StateTableLooup --
 * 	Look up an index from a statically allocated state table.
 */
int Ttk_StateTableLookup(const Ttk_StateTable *map, unsigned int state)
{
    while ((state & map->onBits) != map->onBits
	    || (~state & map->offBits) != map->offBits)
    {
	++map;
    }
    return map->index;
}

/*EOF*/







|










258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
    return mapObj;
}

/*
 * Ttk_StateTableLooup --
 * 	Look up an index from a statically allocated state table.
 */
int Ttk_StateTableLookup(const Ttk_StateTable *map, Ttk_State state)
{
    while ((state & map->onBits) != map->onBits
	    || (~state & map->offBits) != map->offBits)
    {
	++map;
    }
    return map->index;
}

/*EOF*/

Changes to generic/ttk/ttkStubInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * This file is (mostly) automatically generated from ttk.decls.
 * It is compiled and linked in with the ttk package proper.
 */

#include "tkInt.h"
#include "ttkTheme.h"

MODULE_SCOPE const TtkStubs ttkStubs;

#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
#define Ttk_GetOrientFromObj 0
#endif

#ifdef __GNUC__
/*
 * The rest of this file shouldn't warn about deprecated functions; they're
 * there because we intend them to be so and know that this file is OK to
 * touch those fields.
 */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"










<
<
<
<







1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
/*
 * This file is (mostly) automatically generated from ttk.decls.
 * It is compiled and linked in with the ttk package proper.
 */

#include "tkInt.h"
#include "ttkTheme.h"

MODULE_SCOPE const TtkStubs ttkStubs;





#ifdef __GNUC__
/*
 * The rest of this file shouldn't warn about deprecated functions; they're
 * there because we intend them to be so and know that this file is OK to
 * touch those fields.
 */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

Changes to generic/ttk/ttkStubLib.c.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44




45
46
47


48
49
50
51
52
53
54
 *
 */
MODULE_SCOPE const char *
TtkInitializeStubs(
    Tcl_Interp *interp, const char *version, int epoch, int revision)
{
    int exact = 0;
    const char *packageName = "Ttk";
    const char *errMsg = NULL;
    void *pkgClientData = NULL;
    const char *actualVersion = Tcl_PkgRequireEx(
	interp, packageName, version, exact, &pkgClientData);
    const TtkStubs *stubsPtr = (const TtkStubs *)pkgClientData;

    if (!actualVersion) {




	return NULL;
    }



    if (!stubsPtr) {
	errMsg = "missing stub table pointer";
	goto error;
    }
    if (stubsPtr->epoch != epoch) {
	errMsg = "epoch number mismatch";
	goto error;







|




|


>
>
>
>
|
|
|
>
>







30
31
32
33
34
35
36
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 *errMsg = NULL;
    void *pkgClientData = NULL;
    const char *actualVersion = Tcl_PkgRequireEx(
	interp, packageName, version, exact, &pkgClientData);
    const TtkStubs *stubsPtr;

    if (!actualVersion) {
	packageName = "Ttk";
	actualVersion = Tcl_PkgRequireEx(
		interp, packageName, version, exact, &pkgClientData);
	if (!actualVersion) {
	    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
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * Tag tables.  3/4-baked, work in progress.
 *
 * Copyright (C) 2005, Joe English.  Freely redistributable.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*------------------------------------------------------------------------
 * +++ Internal data structures.
 */
struct TtkTag {
    int 	priority;		/* 1=>highest */
    const char	*tagName;		/* Back-pointer to hash table entry */
    void	*tagRecord;		/* User data */
};

struct TtkTagTable {
    Tk_Window		tkwin;		/* owner window */
    const Tk_OptionSpec	*optionSpecs;	/* ... */
    Tk_OptionTable	optionTable;	/* ... */
    int         	recordSize;	/* size of tag record */
    int 		nTags;		/* #tags defined so far */
    Tcl_HashTable	tags;		/* defined tags */
};

/*------------------------------------------------------------------------
 * +++ Tags.
 */
static Ttk_Tag NewTag(Ttk_TagTable tagTable, const char *tagName)



|










|








|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * Tag tables.  3/4-baked, work in progress.
 *
 * Copyright © 2005, Joe English.  Freely redistributable.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

/*------------------------------------------------------------------------
 * +++ Internal data structures.
 */
struct TtkTag {
    Tcl_Size 	priority;		/* 1=>highest */
    const char	*tagName;		/* Back-pointer to hash table entry */
    void	*tagRecord;		/* User data */
};

struct TtkTagTable {
    Tk_Window		tkwin;		/* owner window */
    const Tk_OptionSpec	*optionSpecs;	/* ... */
    Tk_OptionTable	optionTable;	/* ... */
    size_t         	recordSize;	/* size of tag record */
    Tcl_Size 		nTags;		/* #tags defined so far */
    Tcl_HashTable	tags;		/* defined tags */
};

/*------------------------------------------------------------------------
 * +++ Tags.
 */
static Ttk_Tag NewTag(Ttk_TagTable tagTable, const char *tagName)
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

/*------------------------------------------------------------------------
 * +++ Tag tables.
 */

Ttk_TagTable Ttk_CreateTagTable(
    Tcl_Interp *interp, Tk_Window tkwin,
    const Tk_OptionSpec *optionSpecs, int recordSize)
{
    Ttk_TagTable tagTable = (Ttk_TagTable)ckalloc(sizeof(*tagTable));
    tagTable->tkwin = tkwin;
    tagTable->optionSpecs = optionSpecs;
    tagTable->optionTable = Tk_CreateOptionTable(interp, optionSpecs);
    tagTable->recordSize = recordSize;
    tagTable->nTags = 0;







|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

/*------------------------------------------------------------------------
 * +++ Tag tables.
 */

Ttk_TagTable Ttk_CreateTagTable(
    Tcl_Interp *interp, Tk_Window tkwin,
    const Tk_OptionSpec *optionSpecs, size_t recordSize)
{
    Ttk_TagTable tagTable = (Ttk_TagTable)ckalloc(sizeof(*tagTable));
    tagTable->tkwin = tkwin;
    tagTable->optionSpecs = optionSpecs;
    tagTable->optionTable = Tk_CreateOptionTable(interp, optionSpecs);
    tagTable->recordSize = recordSize;
    tagTable->nTags = 0;
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203






























204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
 * Non-NULL results must be passed to Ttk_FreeTagSet().
 */
Ttk_TagSet Ttk_GetTagSetFromObj(
    Tcl_Interp *interp, Ttk_TagTable tagTable, Tcl_Obj *objPtr)
{
    Ttk_TagSet tagset = (Ttk_TagSet)ckalloc(sizeof(*tagset));
    Tcl_Obj **objv;
    int i, objc;

    if (objPtr == NULL) {
	tagset->tags = NULL;
	tagset->nTags = 0;
	return tagset;
    }

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
	ckfree(tagset);
    	return NULL;
    }

    tagset->tags = (Ttk_Tag *)ckalloc((objc+1) * sizeof(Ttk_Tag));
    for (i=0; i<objc; ++i) {
	tagset->tags[i] = Ttk_GetTagFromObj(tagTable, objv[i]);
    }
    tagset->tags[i] = NULL;
    tagset->nTags = objc;

    return tagset;
}

/* Ttk_NewTagSetObj --
 * 	Construct a fresh Tcl_Obj * from a tag set.
 */
Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet tagset)
{
    Tcl_Obj *result = Tcl_NewListObj(0,0);
    int i;

    for (i = 0; i < tagset->nTags; ++i) {
	Tcl_ListObjAppendElement(
	    NULL, result, Tcl_NewStringObj(tagset->tags[i]->tagName, -1));
    }
    return result;
}

void Ttk_FreeTagSet(Ttk_TagSet tagset)
{
    ckfree(tagset->tags);
    ckfree(tagset);
}

/* Ttk_TagSetContains -- test if tag set contains a tag.
 */
int Ttk_TagSetContains(Ttk_TagSet tagset, Ttk_Tag tag)
{
    int i;
    for (i = 0; i < tagset->nTags; ++i) {
	if (tagset->tags[i] == tag) {
	    return 1;
	}
    }
    return 0;
}

/* Ttk_TagSetAdd -- add a tag to a tag set.
 *
 * Returns: 0 if tagset already contained tag,
 * 1 if tagset was modified.
 */
int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag)
{
    int i;
    for (i = 0; i < tagset->nTags; ++i) {
	if (tagset->tags[i] == tag) {
	    return 0;
	}
    }
    tagset->tags = (Ttk_Tag *)ckrealloc(tagset->tags,
	    (tagset->nTags+1)*sizeof(tagset->tags[0]));
    tagset->tags[tagset->nTags++] = tag;
    return 1;
}































/* Ttk_TagSetRemove -- remove a tag from a tag set.
 *
 * Returns: 0 if tagset did not contain tag,
 * 1 if tagset was modified.
 */
int Ttk_TagSetRemove(Ttk_TagSet tagset, Ttk_Tag tag)
{
    int i = 0, j = 0;
    while (i < tagset->nTags) {
	if ((tagset->tags[j] = tagset->tags[i]) != tag) {
	    ++j;
	}
	++i;
    }
    tagset->nTags = j;







|













|














|


















|















|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 * Non-NULL results must be passed to Ttk_FreeTagSet().
 */
Ttk_TagSet Ttk_GetTagSetFromObj(
    Tcl_Interp *interp, Ttk_TagTable tagTable, Tcl_Obj *objPtr)
{
    Ttk_TagSet tagset = (Ttk_TagSet)ckalloc(sizeof(*tagset));
    Tcl_Obj **objv;
    Tcl_Size i, objc;

    if (objPtr == NULL) {
	tagset->tags = NULL;
	tagset->nTags = 0;
	return tagset;
    }

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
	ckfree(tagset);
    	return NULL;
    }

    tagset->tags = (Ttk_Tag *)ckalloc((objc+1) * sizeof(Ttk_Tag));
    for (i = 0; i < objc; ++i) {
	tagset->tags[i] = Ttk_GetTagFromObj(tagTable, objv[i]);
    }
    tagset->tags[i] = NULL;
    tagset->nTags = objc;

    return tagset;
}

/* Ttk_NewTagSetObj --
 * 	Construct a fresh Tcl_Obj * from a tag set.
 */
Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet tagset)
{
    Tcl_Obj *result = Tcl_NewListObj(0,0);
    Tcl_Size i;

    for (i = 0; i < tagset->nTags; ++i) {
	Tcl_ListObjAppendElement(
	    NULL, result, Tcl_NewStringObj(tagset->tags[i]->tagName, -1));
    }
    return result;
}

void Ttk_FreeTagSet(Ttk_TagSet tagset)
{
    ckfree(tagset->tags);
    ckfree(tagset);
}

/* Ttk_TagSetContains -- test if tag set contains a tag.
 */
int Ttk_TagSetContains(Ttk_TagSet tagset, Ttk_Tag tag)
{
    Tcl_Size i;
    for (i = 0; i < tagset->nTags; ++i) {
	if (tagset->tags[i] == tag) {
	    return 1;
	}
    }
    return 0;
}

/* Ttk_TagSetAdd -- add a tag to a tag set.
 *
 * Returns: 0 if tagset already contained tag,
 * 1 if tagset was modified.
 */
int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag)
{
    Tcl_Size i;
    for (i = 0; i < tagset->nTags; ++i) {
	if (tagset->tags[i] == tag) {
	    return 0;
	}
    }
    tagset->tags = (Ttk_Tag *)ckrealloc(tagset->tags,
	    (tagset->nTags+1)*sizeof(tagset->tags[0]));
    tagset->tags[tagset->nTags++] = tag;
    return 1;
}

/* Ttk_TagSetAddSet -- add a tag set to a tag set.
 *
 * Returns: 0 if tagset already contained tags,
 * 1 if tagset was modified.
 */
int Ttk_TagSetAddSet(Ttk_TagSet tagset, Ttk_TagSet tagsetFrom)
{
    Tcl_Size i, j, total, nTags = tagset->nTags;
    int result = 0, found;
    Ttk_Tag tag;

    total = tagsetFrom->nTags + tagset->nTags;
    tagset->tags = (Ttk_Tag *)ckrealloc(tagset->tags,
	    (total)*sizeof(tagset->tags[0]));
    for (j = 0; j < tagsetFrom->nTags; ++j) {
	tag = tagsetFrom->tags[j];
	found = 0;
	for (i = 0; i < nTags; ++i) {
	    if (tagset->tags[i] == tag) {
		found = 1;
		break;
	    }
	}
	if (found) continue;
	tagset->tags[tagset->nTags++] = tag;
	result = 1;
    }
    return result;
}

/* Ttk_TagSetRemove -- remove a tag from a tag set.
 *
 * Returns: 0 if tagset did not contain tag,
 * 1 if tagset was modified.
 */
int Ttk_TagSetRemove(Ttk_TagSet tagset, Ttk_Tag tag)
{
    Tcl_Size i = 0, j = 0;
    while (i < tagset->nTags) {
	if ((tagset->tags[j] = tagset->tags[i]) != tag) {
	    ++j;
	}
	++i;
    }
    tagset->nTags = j;
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273













274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

/* Ttk_ConfigureTag -- implements [$w tag configure $tag -option value...]
 */
int Ttk_ConfigureTag(
    Tcl_Interp *interp,
    Ttk_TagTable tagTable,
    Ttk_Tag tag,
    int objc, Tcl_Obj *const objv[])
{
    return Tk_SetOptions(
	interp, tag->tagRecord, tagTable->optionTable,
	objc, objv, tagTable->tkwin, NULL/*savedOptions*/, NULL/*mask*/);
}

/*------------------------------------------------------------------------
 * +++ Tag values.
 */

#define OBJ_AT(record, offset) (*(Tcl_Obj**)(((char*)record)+offset))














void Ttk_TagSetValues(Ttk_TagTable tagTable, Ttk_TagSet tagSet, void *record)
{
    const int LOWEST_PRIORITY = 0x7FFFFFFF;
    int i, j;

    memset(record, 0, tagTable->recordSize);

    for (i = 0; tagTable->optionSpecs[i].type != TK_OPTION_END; ++i) {
	const Tk_OptionSpec *optionSpec = tagTable->optionSpecs + i;
	TkSizeT offset = optionSpec->objOffset;
	int prio = LOWEST_PRIORITY;

	for (j = 0; j < tagSet->nTags; ++j) {
	    Ttk_Tag tag = tagSet->tags[j];
	    if (OBJ_AT(tag->tagRecord, offset) != 0 && tag->priority < prio) {
		OBJ_AT(record, offset) = OBJ_AT(tag->tagRecord, offset);
		prio = tag->priority;
	    }
	}
    }
}

void Ttk_TagSetApplyStyle(
    Ttk_TagTable tagTable, Ttk_Style style, Ttk_State state, void *record)
{
    const Tk_OptionSpec *optionSpec = tagTable->optionSpecs;

    while (optionSpec->type != TK_OPTION_END) {
	TkSizeT offset = optionSpec->objOffset;
	const char *optionName = optionSpec->optionName;
	Tcl_Obj *val = Ttk_StyleMap(style, optionName, state);
	if (val) {
	    OBJ_AT(record, offset) = val;
	} else if (OBJ_AT(record, offset) == 0) {
	    OBJ_AT(record, offset) = Ttk_StyleDefault(style, optionName);
	}
	++optionSpec;
    }
}








|











>
>
>
>
>
>
>
>
>
>
>
>
>




|
<
<



|


















|




<
<





285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321


322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348


349
350
351
352
353

/* Ttk_ConfigureTag -- implements [$w tag configure $tag -option value...]
 */
int Ttk_ConfigureTag(
    Tcl_Interp *interp,
    Ttk_TagTable tagTable,
    Ttk_Tag tag,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    return Tk_SetOptions(
	interp, tag->tagRecord, tagTable->optionTable,
	objc, objv, tagTable->tkwin, NULL/*savedOptions*/, NULL/*mask*/);
}

/*------------------------------------------------------------------------
 * +++ Tag values.
 */

#define OBJ_AT(record, offset) (*(Tcl_Obj**)(((char*)record)+offset))

void Ttk_TagSetDefaults(Ttk_TagTable tagTable, Ttk_Style style, void *record)
{
    const Tk_OptionSpec *optionSpec = tagTable->optionSpecs;
    memset(record, 0, tagTable->recordSize);

    while (optionSpec->type != TK_OPTION_END) {
	int offset = optionSpec->objOffset;
	const char *optionName = optionSpec->optionName;
	OBJ_AT(record, offset) = Ttk_StyleDefault(style, optionName);
	++optionSpec;
    }
}

void Ttk_TagSetValues(Ttk_TagTable tagTable, Ttk_TagSet tagSet, void *record)
{
    const int LOWEST_PRIORITY = 0x7FFFFFFF;
    Tcl_Size i, j;



    for (i = 0; tagTable->optionSpecs[i].type != TK_OPTION_END; ++i) {
	const Tk_OptionSpec *optionSpec = tagTable->optionSpecs + i;
	Tcl_Size offset = optionSpec->objOffset;
	int prio = LOWEST_PRIORITY;

	for (j = 0; j < tagSet->nTags; ++j) {
	    Ttk_Tag tag = tagSet->tags[j];
	    if (OBJ_AT(tag->tagRecord, offset) != 0 && tag->priority < prio) {
		OBJ_AT(record, offset) = OBJ_AT(tag->tagRecord, offset);
		prio = tag->priority;
	    }
	}
    }
}

void Ttk_TagSetApplyStyle(
    Ttk_TagTable tagTable, Ttk_Style style, Ttk_State state, void *record)
{
    const Tk_OptionSpec *optionSpec = tagTable->optionSpecs;

    while (optionSpec->type != TK_OPTION_END) {
	Tcl_Size offset = optionSpec->objOffset;
	const char *optionName = optionSpec->optionName;
	Tcl_Obj *val = Ttk_StyleMap(style, optionName, state);
	if (val) {
	    OBJ_AT(record, offset) = val;


	}
	++optionSpec;
    }
}

Changes to generic/ttk/ttkTheme.c.

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
 *
 * 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"





|
|







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 © 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
	style = style->parentStyle;
    }
    return 0;
}

/*
 * Ttk_StyleDefault --
 * 	Look up default resource setting the in the specified style.
 */
Tcl_Obj *Ttk_StyleDefault(Ttk_Style style, const char *optionName)
{
    while (style) {
	Tcl_HashEntry *entryPtr =
	    Tcl_FindHashEntry(&style->defaultsTable, optionName);
	if (entryPtr)







|







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 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)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    const Tk_OptionSpec *optionSpec = TkGetOptionSpec(optionName, optionTable);

    if (!optionSpec)
	return 0;

    /* Make sure widget option has a Tcl_Obj* entry:
     */
    if (optionSpec->objOffset == TCL_INDEX_NONE) {
	return 0;
    }

    /* Grrr.  Ignore accidental mismatches caused by prefix-matching:
     */
    if (strcmp(optionSpec->optionName, optionName)) {
	return 0;







|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    const Tk_OptionSpec *optionSpec = TkGetOptionSpec(optionName, optionTable);

    if (!optionSpec)
	return 0;

    /* Make sure widget option has a Tcl_Obj* entry:
     */
    if (optionSpec->objOffset < 0) {
	return 0;
    }

    /* Grrr.  Ignore accidental mismatches caused by prefix-matching:
     */
    if (strcmp(optionSpec->optionName, optionName)) {
	return 0;
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
    Theme *defaultTheme;		/* Default theme; global fallback*/
    Theme *currentTheme;		/* Currently-selected theme */
    Cleanup *cleanupList;		/* Cleanup records */
    Ttk_ResourceCache cache;		/* Resource cache */
    int themeChangePending;		/* scheduled ThemeChangedProc call? */
} StylePackageData;

static void ThemeChangedProc(void *);	/* Forward */

/* Ttk_StylePkgFree --
 *	Cleanup procedure for StylePackageData.
 */
static void Ttk_StylePkgFree(
    ClientData clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr;
    Cleanup *cleanup;

    /*
     * Cancel any pending ThemeChanged calls:
     */
    if (pkgPtr->themeChangePending) {
	Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr);
    }

    /*
     * Free themes.
     */
    entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search);
    while (entryPtr != NULL) {
	Theme *themePtr = (Theme *)Tcl_GetHashValue(entryPtr);
	FreeTheme(themePtr);







<
<




|







<
<
<
<
<
<
<







399
400
401
402
403
404
405


406
407
408
409
410
411
412
413
414
415
416
417







418
419
420
421
422
423
424
    Theme *defaultTheme;		/* Default theme; global fallback*/
    Theme *currentTheme;		/* Currently-selected theme */
    Cleanup *cleanupList;		/* Cleanup records */
    Ttk_ResourceCache cache;		/* Resource cache */
    int themeChangePending;		/* scheduled ThemeChangedProc call? */
} StylePackageData;



/* Ttk_StylePkgFree --
 *	Cleanup procedure for StylePackageData.
 */
static void Ttk_StylePkgFree(
    void *clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr;
    Cleanup *cleanup;








    /*
     * Free themes.
     */
    entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search);
    while (entryPtr != NULL) {
	Theme *themePtr = (Theme *)Tcl_GetHashValue(entryPtr);
	FreeTheme(themePtr);
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527


528
529
530
531
532



















533
534
535
536
537
538
539
 *	Register a function to be called when a theme engine is deleted.
 *	(This only happens when the main interp is destroyed). The cleanup
 *	function is called with the current Tcl interpreter and the client
 *	data provided here.
 *
 */
void Ttk_RegisterCleanup(
    Tcl_Interp *interp, ClientData clientData, Ttk_CleanupProc *cleanupProc)
{
    StylePackageData *pkgPtr = (StylePackageData *)GetStylePackageData(interp);
    Cleanup *cleanup = (Cleanup *)ckalloc(sizeof(*cleanup));

    cleanup->clientData = clientData;
    cleanup->cleanupProc = cleanupProc;
    cleanup->next = pkgPtr->cleanupList;
    pkgPtr->cleanupList = cleanup;
}

/* ThemeChangedProc --
 * 	Notify all widgets that the theme has been changed.
 * 	Scheduled as an idle callback; clientData is a StylePackageData *.
 *
 * 	Sends a <<ThemeChanged>> event to every widget in the hierarchy.
 * 	Widgets respond to this by calling the  WorldChanged class proc,
 * 	which in turn recreates the layout.
 *
 * 	The Tk C API doesn't doesn't provide an easy way to traverse
 * 	the widget hierarchy, so this is done by evaluating a Tcl script.
 */

static void ThemeChangedProc(ClientData clientData)
{
    static char ThemeChangedScript[] = "ttk::ThemeChanged";
    StylePackageData *pkgPtr = (StylePackageData *)clientData;

    int code = Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundException(pkgPtr->interp, code);
    }
    pkgPtr->themeChangePending = 0;
}

/*
 * ThemeChanged --
 * 	Schedule a call to ThemeChanged if one is not already pending.
 */
static void ThemeChanged(StylePackageData *pkgPtr)
{


    if (!pkgPtr->themeChangePending) {
	Tcl_DoWhenIdle(ThemeChangedProc, pkgPtr);
	pkgPtr->themeChangePending = 1;
    }
}




















/*
 * Ttk_CreateTheme --
 *	Create a new theme and register it in the global theme table.
 *
 * Returns:
 * 	Pointer to new Theme structure; NULL if named theme already exists.







|

|




















|

















>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
 *	Register a function to be called when a theme engine is deleted.
 *	(This only happens when the main interp is destroyed). The cleanup
 *	function is called with the current Tcl interpreter and the client
 *	data provided here.
 *
 */
void Ttk_RegisterCleanup(
    Tcl_Interp *interp, void *clientData, Ttk_CleanupProc *cleanupProc)
{
    StylePackageData *pkgPtr = GetStylePackageData(interp);
    Cleanup *cleanup = (Cleanup *)ckalloc(sizeof(*cleanup));

    cleanup->clientData = clientData;
    cleanup->cleanupProc = cleanupProc;
    cleanup->next = pkgPtr->cleanupList;
    pkgPtr->cleanupList = cleanup;
}

/* ThemeChangedProc --
 * 	Notify all widgets that the theme has been changed.
 * 	Scheduled as an idle callback; clientData is a StylePackageData *.
 *
 * 	Sends a <<ThemeChanged>> event to every widget in the hierarchy.
 * 	Widgets respond to this by calling the  WorldChanged class proc,
 * 	which in turn recreates the layout.
 *
 * 	The Tk C API doesn't doesn't provide an easy way to traverse
 * 	the widget hierarchy, so this is done by evaluating a Tcl script.
 */

static void ThemeChangedProc(void *clientData)
{
    static char ThemeChangedScript[] = "ttk::ThemeChanged";
    StylePackageData *pkgPtr = (StylePackageData *)clientData;

    int code = Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {
	Tcl_BackgroundException(pkgPtr->interp, code);
    }
    pkgPtr->themeChangePending = 0;
}

/*
 * ThemeChanged --
 * 	Schedule a call to ThemeChanged if one is not already pending.
 */
static void ThemeChanged(StylePackageData *pkgPtr)
{
    TtkSetBlinkCursorTimes(pkgPtr->interp);

    if (!pkgPtr->themeChangePending) {
	Tcl_DoWhenIdle(ThemeChangedProc, pkgPtr);
	pkgPtr->themeChangePending = 1;
    }
}

/* Ttk_TkDestroyedHandler --
 *	See bug [310c74ecf440]: idle calls to ThemeChangedProc()
 *	need to be canceled when Tk is destroyed, since the interp
 *	may still be active afterward; canceling them from
 *	Ttk_StylePkgFree() would be too late.
 */
void Ttk_TkDestroyedHandler(
    Tcl_Interp* interp)
{
    StylePackageData* pkgPtr = GetStylePackageData(interp);

    /*
     * Cancel any pending ThemeChanged calls:
     */
    if (pkgPtr->themeChangePending) {
	Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr);
    }
}

/*
 * Ttk_CreateTheme --
 *	Create a new theme and register it in the global theme table.
 *
 * Returns:
 * 	Pointer to new Theme structure; NULL if named theme already exists.
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839

/* Ttk_CloneElement -- element factory procedure.
 * 	(style element create $name) "from" $theme ?$element?
 */
static int Ttk_CloneElement(
    Tcl_Interp *interp, TCL_UNUSED(void *),
    Ttk_Theme theme, const char *elementName,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Theme fromTheme;
    Ttk_ElementClass *fromElement;

    if (objc <= 0 || objc > 2) {
	Tcl_WrongNumArgs(interp, 0, objv, "theme ?element?");
	return TCL_ERROR;







|







837
838
839
840
841
842
843
844
845
846
847
848
849
850
851

/* Ttk_CloneElement -- element factory procedure.
 * 	(style element create $name) "from" $theme ?$element?
 */
static int Ttk_CloneElement(
    Tcl_Interp *interp, TCL_UNUSED(void *),
    Ttk_Theme theme, const char *elementName,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Ttk_Theme fromTheme;
    Ttk_ElementClass *fromElement;

    if (objc <= 0 || objc > 2) {
	Tcl_WrongNumArgs(interp, 0, objv, "theme ?element?");
	return TCL_ERROR;
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
/* + style map $style ? -resource statemap ... ?
 *
 * 	Note that resource names are unconstrained; the Style
 * 	doesn't know what resources individual elements may use.
 */
static int
StyleMapCmd(
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
    Style *stylePtr;
    int i;







|

|







1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
/* + 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(
    void *clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    Tcl_Size objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
    Style *stylePtr;
    int i;
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
    ThemeChanged(pkgPtr);
    return TCL_OK;
}

/* + style configure $style -option ?value...
 */
static int StyleConfigureCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
    Style *stylePtr;
    int i;

    if (objc < 3) {
usage:
	Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??");
	return TCL_ERROR;
    }

    styleName = Tcl_GetString(objv[2]);
    stylePtr = Ttk_GetStyle(theme, styleName);

    if (objc == 3) {		/* style default $styleName */
	Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->defaultsTable));
	return TCL_OK;
    } else if (objc == 4) {	/* style default $styleName -option */
	const char *optionName = Tcl_GetString(objv[3]);
	Tcl_HashEntry *entryPtr =
	    Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName);
	if (entryPtr) {
	    Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr));
	}
	return TCL_OK;







|
















|


|







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
    ThemeChanged(pkgPtr);
    return TCL_OK;
}

/* + style configure $style -option ?value...
 */
static int StyleConfigureCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *styleName;
    Style *stylePtr;
    int i;

    if (objc < 3) {
usage:
	Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??");
	return TCL_ERROR;
    }

    styleName = Tcl_GetString(objv[2]);
    stylePtr = Ttk_GetStyle(theme, styleName);

    if (objc == 3) {		/* style configure $styleName */
	Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->defaultsTable));
	return TCL_OK;
    } else if (objc == 4) {	/* style configure $styleName -option */
	const char *optionName = Tcl_GetString(objv[3]);
	Tcl_HashEntry *entryPtr =
	    Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName);
	if (entryPtr) {
	    Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr));
	}
	return TCL_OK;
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
    ThemeChanged(pkgPtr);
    return TCL_OK;
}

/* + style lookup $style -option ?statespec? ?defaultValue?
 */
static int StyleLookupCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    Ttk_Style style = NULL;
    const char *optionName;
    Ttk_State state = 0ul;
    Tcl_Obj *result;

    if (objc < 4 || objc > 6) {
	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;







|














<
<
|







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
    ThemeChanged(pkgPtr);
    return TCL_OK;
}

/* + style lookup $style -option ?statespec? ?defaultValue?
 */
static int StyleLookupCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    Ttk_Style style = NULL;
    const char *optionName;
    Ttk_State state = 0ul;
    Tcl_Obj *result;

    if (objc < 4 || objc > 6) {
	Tcl_WrongNumArgs(interp, 2, objv, "style -option ?state? ?default?");
	return TCL_ERROR;
    }

    style = Ttk_GetStyle(theme, Tcl_GetString(objv[2]));



    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;
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
	Tcl_SetObjResult(interp, result);
    }

    return TCL_OK;
}

static int StyleThemeCurrentCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr = NULL;
    const char *name = NULL;

    if (objc != 3) {







|







1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
	Tcl_SetObjResult(interp, result);
    }

    return TCL_OK;
}

static int StyleThemeCurrentCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj * const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr = NULL;
    const char *name = NULL;

    if (objc != 3) {
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
    Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
    return TCL_OK;
}

/* + style theme create name ?-parent $theme? ?-settings { script }?
 */
static int StyleThemeCreateCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    static const char *const optStrings[] =
    	 { "-parent", "-settings", NULL };
    enum { OP_PARENT, OP_SETTINGS };
    Ttk_Theme parentTheme = pkgPtr->defaultTheme, newTheme;
    Tcl_Obj *settingsScript = NULL;







|







1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
    Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
    return TCL_OK;
}

/* + style theme create name ?-parent $theme? ?-settings { script }?
 */
static int StyleThemeCreateCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    static const char *const optStrings[] =
    	 { "-parent", "-settings", NULL };
    enum { OP_PARENT, OP_SETTINGS };
    Ttk_Theme parentTheme = pkgPtr->defaultTheme, newTheme;
    Tcl_Obj *settingsScript = NULL;
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
    }
}

/* + style theme names --
 * 	Return list of registered themes.
 */
static int StyleThemeNamesCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;

    return TtkEnumerateHashTable(interp, &pkgPtr->themeTable);
}

/* + style theme settings $theme $script
 *
 * 	Temporarily sets the current theme to $themeName,
 * 	evaluates $script, then restores the old theme.
 */
static int
StyleThemeSettingsCmd(
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme oldTheme = pkgPtr->currentTheme;
    Ttk_Theme newTheme;
    int status;








|

|
|













|

|







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
    }
}

/* + style theme names --
 * 	Return list of registered themes.
 */
static int StyleThemeNamesCmd(
    void *clientData,
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Size), /* objc */
    TCL_UNUSED(Tcl_Obj *const *)) /* objv */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;

    return TtkEnumerateHashTable(interp, &pkgPtr->themeTable);
}

/* + style theme settings $theme $script
 *
 * 	Temporarily sets the current theme to $themeName,
 * 	evaluates $script, then restores the old theme.
 */
static int
StyleThemeSettingsCmd(
    void *clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    Tcl_Size objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme oldTheme = pkgPtr->currentTheme;
    Ttk_Theme newTheme;
    int status;

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498

    return status;
}

/* + style element create name type ? ...args ?
 */
static int StyleElementCreateCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *elementName, *factoryName;
    Tcl_HashEntry *entryPtr;
    FactoryRec *recPtr;








|







1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508

    return status;
}

/* + style element create name type ? ...args ?
 */
static int StyleElementCreateCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *elementName, *factoryName;
    Tcl_HashEntry *entryPtr;
    FactoryRec *recPtr;

1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
	    theme, elementName, objc - 5, objv + 5);
}

/* + style element names --
 * 	Return a list of elements defined in the current theme.
 */
static int StyleElementNamesCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    return TtkEnumerateHashTable(interp, &theme->elementTable);
}

/* + style element options $element --
 * 	Return list of element options for specified element
 */
static int StyleElementOptionsCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *elementName;
    Ttk_ElementClass *elementClass;

    if (objc != 4) {







|















|







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
	    theme, elementName, objc - 5, objv + 5);
}

/* + style element names --
 * 	Return a list of elements defined in the current theme.
 */
static int StyleElementNamesCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	return TCL_ERROR;
    }
    return TtkEnumerateHashTable(interp, &theme->elementTable);
}

/* + style element options $element --
 * 	Return list of element options for specified element
 */
static int StyleElementOptionsCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *elementName;
    Ttk_ElementClass *elementClass;

    if (objc != 4) {
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
    Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT", elementName, NULL);
    return TCL_ERROR;
}

/* + style layout name ?spec?
 */
static int StyleLayoutCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *layoutName;
    Ttk_LayoutTemplate layoutTemplate;

    if (objc < 3 || objc > 4) {







|







1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
    Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT", elementName, NULL);
    return TCL_ERROR;
}

/* + style layout name ?spec?
 */
static int StyleLayoutCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme = pkgPtr->currentTheme;
    const char *layoutName;
    Ttk_LayoutTemplate layoutTemplate;

    if (objc < 3 || objc > 4) {
1607
1608
1609
1610
1611
1612
1613




























1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
	    return TCL_ERROR;
	}
	Ttk_RegisterLayoutTemplate(theme, layoutName, layoutTemplate);
	ThemeChanged(pkgPtr);
    }
    return TCL_OK;
}





























/* + style theme use $theme --
 *  	Sets the current theme to $theme
 */
static int
StyleThemeUseCmd(
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "?theme?");







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|

|







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
	    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(void *),
    Tcl_Interp *interp,
    Tcl_Size 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(
    void *clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    Tcl_Size objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    StylePackageData *pkgPtr = (StylePackageData *)clientData;
    Ttk_Theme theme;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "?theme?");
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
 *	Implementation of the [style] command.
 */

static const Ttk_Ensemble StyleThemeEnsemble[] = {
    { "create", StyleThemeCreateCmd, 0 },
    { "names", StyleThemeNamesCmd, 0 },
    { "settings", StyleThemeSettingsCmd, 0 },

    { "use", StyleThemeUseCmd, 0 },
    { NULL, 0, 0 }
};

static const Ttk_Ensemble StyleElementEnsemble[] = {
    { "create", StyleElementCreateCmd, 0 },
    { "names", StyleElementNamesCmd, 0 },







>







1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
 *	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 },
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
    { "theme", 0, StyleThemeEnsemble },
    { "element", 0, StyleElementEnsemble },
    { NULL, 0, 0 }
};

static int
StyleObjCmd(
    ClientData clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv);
}

MODULE_SCOPE
int Ttk_InvokeEnsemble(	/* Run an ensemble command */
    const Ttk_Ensemble *ensemble, int cmdIndex,
    void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    while (cmdIndex < objc) {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp,
		objv[cmdIndex], ensemble, sizeof(ensemble[0]),
		"command", 0, &index)
	    != TCL_OK)







|









|
|







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
    { "theme", 0, StyleThemeEnsemble },
    { "element", 0, StyleElementEnsemble },
    { NULL, 0, 0 }
};

static int
StyleObjCmd(
    void *clientData,		/* StylePackageData pointer */
    Tcl_Interp *interp,			/* Current interpreter */
    int objc,				/* Number of arguments */
    Tcl_Obj *const objv[])		/* Argument objects */
{
    return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv);
}

MODULE_SCOPE
int Ttk_InvokeEnsemble(	/* Run an ensemble command */
    const Ttk_Ensemble *ensemble, Tcl_Size cmdIndex,
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    while (cmdIndex < objc) {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp,
		objv[cmdIndex], ensemble, sizeof(ensemble[0]),
		"command", 0, &index)
	    != TCL_OK)

Changes to generic/ttk/ttkTheme.h.

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
enum TTKStyleVersion2 { TK_STYLE_VERSION_2 = 2 };

typedef void (Ttk_ElementSizeProc)(void *clientData, void *elementRecord,
        Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding*);
typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord,
        Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);

#ifndef TkSizeT
#   if TCL_MAJOR_VERSION > 8
#	define TkSizeT size_t
#   else
#	define TkSizeT int
#   endif
#endif

typedef struct Ttk_ElementOptionSpec
{
    const char *optionName;		/* Command-line name of the widget option */
    Tk_OptionType type; 	/* Accepted option types */
    TkSizeT offset;			/* Offset of Tcl_Obj* field in element record */
    const char *defaultValue;		/* Default value to used if resource missing */
} Ttk_ElementOptionSpec;

#define TK_OPTION_ANY TK_OPTION_STRING

typedef struct Ttk_ElementSpec {
    enum TTKStyleVersion2 version;	/* Version of the style support. */
    size_t elementSize;			/* Size of element record */
    const Ttk_ElementOptionSpec *options;	/* List of options, NULL-terminated */
    Ttk_ElementSizeProc *size;		/* Compute min size and padding */
    Ttk_ElementDrawProc *draw;  	/* Draw the element */
} Ttk_ElementSpec;

typedef int (*Ttk_ElementFactory)
	(Tcl_Interp *, void *clientData,
	 Ttk_Theme, const char *elementName, int objc, Tcl_Obj *const objv[]);

/*
 * Null element implementation:
 * has no geometry or layout; may be used as a stub or placeholder.
 */

typedef struct {
    Tcl_Obj	*unused;
} NullElement;

MODULE_SCOPE void TtkNullElementSize
	(void *, void *, Tk_Window, int *, int *, Ttk_Padding *);
MODULE_SCOPE void TtkNullElementDraw
	(void *, void *, Tk_Window, Drawable, Ttk_Box, Ttk_State);
MODULE_SCOPE const Ttk_ElementOptionSpec TtkNullElementOptions[];
MODULE_SCOPE Ttk_ElementSpec ttkNullElementSpec;

/*------------------------------------------------------------------------
 * +++ Layout templates.
 */
typedef struct {







<
<
<
<
<
<
<
<




|















|










|
<
|
<







199
200
201
202
203
204
205








206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238

239
240
241
242
243
244
245
enum TTKStyleVersion2 { TK_STYLE_VERSION_2 = 2 };

typedef void (Ttk_ElementSizeProc)(void *clientData, void *elementRecord,
        Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding*);
typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord,
        Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);









typedef struct Ttk_ElementOptionSpec
{
    const char *optionName;		/* Command-line name of the widget option */
    Tk_OptionType type; 	/* Accepted option types */
    Tcl_Size offset;			/* Offset of Tcl_Obj* field in element record */
    const char *defaultValue;		/* Default value to used if resource missing */
} Ttk_ElementOptionSpec;

#define TK_OPTION_ANY TK_OPTION_STRING

typedef struct Ttk_ElementSpec {
    enum TTKStyleVersion2 version;	/* Version of the style support. */
    size_t elementSize;			/* Size of element record */
    const Ttk_ElementOptionSpec *options;	/* List of options, NULL-terminated */
    Ttk_ElementSizeProc *size;		/* Compute min size and padding */
    Ttk_ElementDrawProc *draw;  	/* Draw the element */
} Ttk_ElementSpec;

typedef int (*Ttk_ElementFactory)
	(Tcl_Interp *, void *clientData,
	 Ttk_Theme, const char *elementName, Tcl_Size objc, Tcl_Obj *const objv[]);

/*
 * Null element implementation:
 * has no geometry or layout; may be used as a stub or placeholder.
 */

typedef struct {
    Tcl_Obj	*unused;
} NullElement;

MODULE_SCOPE Ttk_ElementSizeProc TtkNullElementSize;

MODULE_SCOPE Ttk_ElementDrawProc TtkNullElementDraw;

MODULE_SCOPE const Ttk_ElementOptionSpec TtkNullElementOptions[];
MODULE_SCOPE Ttk_ElementSpec ttkNullElementSpec;

/*------------------------------------------------------------------------
 * +++ Layout templates.
 */
typedef struct {
304
305
306
307
308
309
310

311
312
313
314
315
316
317
MODULE_SCOPE Ttk_Box Ttk_ClientRegion(Ttk_Layout, const char *elementName);

MODULE_SCOPE Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout,Ttk_Element);
MODULE_SCOPE Ttk_Padding Ttk_LayoutNodeInternalPadding(Ttk_Layout,Ttk_Element);
MODULE_SCOPE void Ttk_LayoutNodeReqSize(Ttk_Layout, Ttk_Element, int *w, int *h);

MODULE_SCOPE void Ttk_PlaceElement(Ttk_Layout, Ttk_Element, Ttk_Box);

MODULE_SCOPE void Ttk_ChangeElementState(Ttk_Element,unsigned set,unsigned clr);

MODULE_SCOPE Tcl_Obj *Ttk_QueryOption(Ttk_Layout, const char *, Ttk_State);

TTKAPI Ttk_Style Ttk_LayoutStyle(Ttk_Layout);
TTKAPI Tcl_Obj *Ttk_StyleDefault(Ttk_Style, const char *optionName);
TTKAPI Tcl_Obj *Ttk_StyleMap(Ttk_Style, const char *optionName, Ttk_State);







>







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
MODULE_SCOPE Ttk_Box Ttk_ClientRegion(Ttk_Layout, const char *elementName);

MODULE_SCOPE Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout,Ttk_Element);
MODULE_SCOPE Ttk_Padding Ttk_LayoutNodeInternalPadding(Ttk_Layout,Ttk_Element);
MODULE_SCOPE void Ttk_LayoutNodeReqSize(Ttk_Layout, Ttk_Element, int *w, int *h);

MODULE_SCOPE void Ttk_PlaceElement(Ttk_Layout, Ttk_Element, Ttk_Box);
MODULE_SCOPE void Ttk_AnchorElement(Ttk_Element node, Tk_Anchor anchor);
MODULE_SCOPE void Ttk_ChangeElementState(Ttk_Element,unsigned set,unsigned clr);

MODULE_SCOPE Tcl_Obj *Ttk_QueryOption(Ttk_Layout, const char *, Ttk_State);

TTKAPI Ttk_Style Ttk_LayoutStyle(Ttk_Layout);
TTKAPI Tcl_Obj *Ttk_StyleDefault(Ttk_Style, const char *optionName);
TTKAPI Tcl_Obj *Ttk_StyleMap(Ttk_Style, const char *optionName, Ttk_State);
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
/*------------------------------------------------------------------------
 * +++ Image specifications.
 */

typedef struct TtkImageSpec Ttk_ImageSpec;
TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *);
TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *,
					Tk_ImageChangedProc *, ClientData);
TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *);
TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State);

/*------------------------------------------------------------------------
 * +++ Miscellaneous enumerations.
 * 	Other stuff that element implementations need to know about.
 */
typedef enum 			/* -default option values */
{
    TTK_BUTTON_DEFAULT_NORMAL,	/* widget defaultable */
    TTK_BUTTON_DEFAULT_ACTIVE,	/* currently the default widget */
    TTK_BUTTON_DEFAULT_DISABLED	/* not defaultable */

} Ttk_ButtonDefaultState;

TTKAPI int Ttk_GetButtonDefaultStateFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_ButtonDefaultState *);

typedef enum 			/* -compound option values */
{
    TTK_COMPOUND_NONE,  	/* image if specified, otherwise text */







|

|







<

|
>







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
/*------------------------------------------------------------------------
 * +++ Image specifications.
 */

typedef struct TtkImageSpec Ttk_ImageSpec;
TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *);
TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *,
					Tk_ImageChangedProc *, void *);
TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *);
TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Tk_Window, Ttk_State);

/*------------------------------------------------------------------------
 * +++ Miscellaneous enumerations.
 * 	Other stuff that element implementations need to know about.
 */
typedef enum 			/* -default option values */
{

    TTK_BUTTON_DEFAULT_ACTIVE,	/* currently the default widget */
    TTK_BUTTON_DEFAULT_DISABLED,	/* not defaultable */
    TTK_BUTTON_DEFAULT_NORMAL	/* widget defaultable */
} Ttk_ButtonDefaultState;

TTKAPI int Ttk_GetButtonDefaultStateFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_ButtonDefaultState *);

typedef enum 			/* -compound option values */
{
    TTK_COMPOUND_NONE,  	/* image if specified, otherwise text */
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
TTKAPI int Ttk_GetCompoundFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_Compound *);

typedef enum { 		/* -orient option values */
    TTK_ORIENT_HORIZONTAL,
    TTK_ORIENT_VERTICAL
} Ttk_Orient;

MODULE_SCOPE int		TtkGetOrientFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Ttk_Orient *orient);

/*------------------------------------------------------------------------
 * +++ Utilities.
 */

typedef struct TtkEnsemble {
    const char *name;			/* subcommand name */
    Tcl_ObjCmdProc *command; 		/* subcommand implementation, OR: */
    const struct TtkEnsemble *ensemble;	/* subcommand ensemble */
} Ttk_Ensemble;

MODULE_SCOPE int Ttk_InvokeEnsemble(	/* Run an ensemble command */
    const Ttk_Ensemble *commands, int cmdIndex,
    void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);

MODULE_SCOPE int TtkEnumerateHashTable(Tcl_Interp *, Tcl_HashTable *);

/*------------------------------------------------------------------------
 * +++ Stub table declarations.
 */








<
<
<






|




|
|







363
364
365
366
367
368
369



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
TTKAPI int Ttk_GetCompoundFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_Compound *);

typedef enum { 		/* -orient option values */
    TTK_ORIENT_HORIZONTAL,
    TTK_ORIENT_VERTICAL
} Ttk_Orient;




/*------------------------------------------------------------------------
 * +++ Utilities.
 */

typedef struct TtkEnsemble {
    const char *name;			/* subcommand name */
    Tcl_ObjCmdProc2 *command; 		/* subcommand implementation, OR: */
    const struct TtkEnsemble *ensemble;	/* subcommand ensemble */
} Ttk_Ensemble;

MODULE_SCOPE int Ttk_InvokeEnsemble(	/* Run an ensemble command */
    const Ttk_Ensemble *commands, Tcl_Size cmdIndex,
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]);

MODULE_SCOPE int TtkEnumerateHashTable(Tcl_Interp *, Tcl_HashTable *);

/*------------------------------------------------------------------------
 * +++ Stub table declarations.
 */

Changes to generic/ttk/ttkThemeInt.h.

35
36
37
38
39
40
41






42

MODULE_SCOPE Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName);
MODULE_SCOPE Ttk_LayoutTemplate Ttk_FindLayoutTemplate(
    Ttk_Theme themePtr, const char *layoutName);

MODULE_SCOPE const char *Ttk_StyleName(Ttk_Style);







#endif /* _TTKTHEMEINT */







>
>
>
>
>
>

35
36
37
38
39
40
41
42
43
44
45
46
47
48

MODULE_SCOPE Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName);
MODULE_SCOPE Ttk_LayoutTemplate Ttk_FindLayoutTemplate(
    Ttk_Theme themePtr, const char *layoutName);

MODULE_SCOPE const char *Ttk_StyleName(Ttk_Style);

MODULE_SCOPE void TtkSetBlinkCursorTimes(Tcl_Interp* interp);

MODULE_SCOPE int TtkBoxEqual(Ttk_Box, Ttk_Box);

#define TTK_OPTION_UNDERLINE_DEF(type, field) NULL, offsetof(type, field), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL

#endif /* _TTKTHEMEINT */

Changes to generic/ttk/ttkTrace.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
};

/*
 * Tcl_VarTraceProc for trace handles.
 */
static char *
VarTraceProc(
    ClientData clientData,	/* Widget record pointer */
    Tcl_Interp *interp, 	/* Interpreter containing variable. */
    TCL_UNUSED(const char *),	/* name1 */
    TCL_UNUSED(const char *),	/* name2 */
    int flags)			/* Information about what happened. */
{
    Ttk_TraceHandle *tracePtr = (Ttk_TraceHandle *)clientData;
    const char *name, *value;







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
};

/*
 * Tcl_VarTraceProc for trace handles.
 */
static char *
VarTraceProc(
    void *clientData,	/* Widget record pointer */
    Tcl_Interp *interp, 	/* Interpreter containing variable. */
    TCL_UNUSED(const char *),	/* name1 */
    TCL_UNUSED(const char *),	/* name2 */
    int flags)			/* Information about what happened. */
{
    Ttk_TraceHandle *tracePtr = (Ttk_TraceHandle *)clientData;
    const char *name, *value;
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * Ttk_UntraceVariable --
 * 	Remove previously-registered trace and free the handle.
 */
void Ttk_UntraceVariable(Ttk_TraceHandle *h)
{
    if (h) {
	ClientData cd = NULL;

	/*
	 * Workaround for Tcl Bug 3062331.  The trace design problem is
	 * that when variable unset traces fire, Tcl documents that the
	 * traced variable has already been unset.  It's already gone.
	 * So from within an unset trace, if you try to call
	 * Tcl_UntraceVar() on that variable, it will do nothing, because







|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * Ttk_UntraceVariable --
 * 	Remove previously-registered trace and free the handle.
 */
void Ttk_UntraceVariable(Ttk_TraceHandle *h)
{
    if (h) {
	void *cd = NULL;

	/*
	 * Workaround for Tcl Bug 3062331.  The trace design problem is
	 * that when variable unset traces fire, Tcl documents that the
	 * traced variable has already been unset.  It's already gone.
	 * So from within an unset trace, if you try to call
	 * Tcl_UntraceVar() on that variable, it will do nothing, because

Changes to generic/ttk/ttkTrack.c.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2004, Joe English
 *
 * TtkTrackElementState() -- helper routine for widgets
 * like scrollbars in which individual elements may
 * be active or pressed instead of the widget as a whole.
 *
 * Usage:
 * 	TtkTrackElementState(&recordPtr->core);

|







1
2
3
4
5
6
7
8
9
/*
 * 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);
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    | PointerMotionMask
    | LeaveWindowMask
    | EnterWindowMask
    | StructureNotifyMask
    ;

static void
ElementStateEventProc(ClientData clientData, XEvent *ev)
{
    ElementStateTracker *es = (ElementStateTracker *)clientData;
    Ttk_Layout layout = es->corePtr->layout;
    Ttk_Element element;

    /* Guard against dangling pointers [#2431428]
     */







|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    | PointerMotionMask
    | LeaveWindowMask
    | EnterWindowMask
    | StructureNotifyMask
    ;

static void
ElementStateEventProc(void *clientData, XEvent *ev)
{
    ElementStateTracker *es = (ElementStateTracker *)clientData;
    Ttk_Layout layout = es->corePtr->layout;
    Ttk_Element element;

    /* Guard against dangling pointers [#2431428]
     */

Changes to generic/ttk/ttkTreeview.c.

1
2
3
4
5
6
7
8
9
10




11



12
13
14
15
16
17
18
19
20
21
22


23
24
25
26
27
28
29
/*
 * Copyright (c) 2004, Joe English
 *
 * ttk::treeview widget implementation.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"





#define DEF_TREE_ROWS		"10"



#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"

static const int DEFAULT_ROWHEIGHT 	= 20;
static const int DEFAULT_INDENT 	= 20;
static const int HALO   		= 4;	/* separator */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

#define STATE_CHANGED	 	(0x100)	/* item state option changed */



/*------------------------------------------------------------------------
 * +++ Tree items.
 *
 * INVARIANTS:
 * 	item->children	==> item->children->parent == item
 *	item->next	==> item->next->parent == item->parent

|





|


>
>
>
>

>
>
>



|

|





>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 © 2004, Joe English
 *
 * ttk::treeview widget implementation.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#define DEF_TREE_ROWS		"10"
#define DEF_TITLECOLUMNS	"0"
#define DEF_TITLEITEMS		"0"
#define DEF_STRIPED		"0"
#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"

static const Tk_Anchor DEFAULT_IMAGEANCHOR = TK_ANCHOR_W;
static const int DEFAULT_INDENT 	= 20;
static const int HALO   		= 4;	/* heading separator */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

#define STATE_CHANGED	 	(0x100)	/* item state option changed */

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

/*------------------------------------------------------------------------
 * +++ Tree items.
 *
 * INVARIANTS:
 * 	item->children	==> item->children->parent == item
 *	item->next	==> item->next->parent == item->parent
44
45
46
47
48
49
50







51
52
53
54
55
56



57
58
59
60
61
62
63
64






65
66
67
68



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100






101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117


118
119
120








121
122
123
124
125
126
127
     */
    Ttk_State 	state;
    Tcl_Obj	*textObj;
    Tcl_Obj	*imageObj;
    Tcl_Obj	*valuesObj;
    Tcl_Obj	*openObj;
    Tcl_Obj	*tagsObj;








    /*
     * Derived resources:
     */
    Ttk_TagSet	tagset;
    Ttk_ImageSpec *imagespec;



};

#define ITEM_OPTION_TAGS_CHANGED	0x100
#define ITEM_OPTION_IMAGE_CHANGED	0x200

static const Tk_OptionSpec ItemOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	"", offsetof(TreeItem,textObj), TCL_INDEX_NONE,






	0,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(TreeItem,imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_IMAGE_CHANGED },



    {TK_OPTION_STRING, "-values", "values", "Values",
	NULL, offsetof(TreeItem,valuesObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_BOOLEAN, "-open", "open", "Open",
	"0", offsetof(TreeItem,openObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-tags", "tags", "Tags",
	NULL, offsetof(TreeItem,tagsObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_TAGS_CHANGED },

    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

/* Forward declaration */
static void RemoveTag(TreeItem *, Ttk_Tag);


/* + NewItem --
 * 	Allocate a new, uninitialized, unlinked item
 */
static TreeItem *NewItem(void)
{
    TreeItem *item = (TreeItem *)ckalloc(sizeof(*item));

    item->entryPtr = 0;
    item->parent = item->children = item->next = item->prev = NULL;

    item->state = 0ul;
    item->textObj = NULL;
    item->imageObj = NULL;
    item->valuesObj = NULL;
    item->openObj = NULL;
    item->tagsObj = NULL;







    item->tagset = NULL;
    item->imagespec = NULL;

    return item;
}

/* + FreeItem --
 * 	Destroy an item
 */
static void FreeItem(TreeItem *item)
{

    if (item->textObj) { Tcl_DecrRefCount(item->textObj); }
    if (item->imageObj) { Tcl_DecrRefCount(item->imageObj); }
    if (item->valuesObj) { Tcl_DecrRefCount(item->valuesObj); }
    if (item->openObj) { Tcl_DecrRefCount(item->openObj); }
    if (item->tagsObj) { Tcl_DecrRefCount(item->tagsObj); }



    if (item->tagset)	{ Ttk_FreeTagSet(item->tagset); }
    if (item->imagespec) { TtkFreeImageSpec(item->imagespec); }









    ckfree(item);
}

static void FreeItemCB(void *clientData) { FreeItem((TreeItem *)clientData); }

/* + DetachItem --







>
>
>
>
>
>
>






>
>
>








>
>
>
>
>
>




>
>
>













|

>

















>
>
>
>
>
>












>





>
>



>
>
>
>
>
>
>
>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
     */
    Ttk_State 	state;
    Tcl_Obj	*textObj;
    Tcl_Obj	*imageObj;
    Tcl_Obj	*valuesObj;
    Tcl_Obj	*openObj;
    Tcl_Obj	*tagsObj;
    Tcl_Obj     *selObj;
    Tcl_Obj     *imageAnchorObj;
    int 	hidden;
    int		height; 	/* Height is in number of row heights */

    Ttk_TagSet  *cellTagSets;
    Tcl_Size	nTagSets;

    /*
     * Derived resources:
     */
    Ttk_TagSet	tagset;
    Ttk_ImageSpec *imagespec;
    int itemPos; 		/* Counting items */
    int visiblePos; 		/* Counting visible items */
    int rowPos;			/* Counting rows (visible physical space) */
};

#define ITEM_OPTION_TAGS_CHANGED	0x100
#define ITEM_OPTION_IMAGE_CHANGED	0x200

static const Tk_OptionSpec ItemOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	"", offsetof(TreeItem,textObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_INT, "-height", "height", "Height",
	"1", TCL_INDEX_NONE, offsetof(TreeItem,height),
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-hidden", "hidden", "Hidden",
	"0", TCL_INDEX_NONE, offsetof(TreeItem,hidden),
	0,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(TreeItem,imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_IMAGE_CHANGED },
    {TK_OPTION_ANCHOR, "-imageanchor", "imageAnchor", "ImageAnchor",
	NULL, offsetof(TreeItem,imageAnchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "-values", "values", "Values",
	NULL, offsetof(TreeItem,valuesObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_BOOLEAN, "-open", "open", "Open",
	"0", offsetof(TreeItem,openObj), TCL_INDEX_NONE,
	0,0,0 },
    {TK_OPTION_STRING, "-tags", "tags", "Tags",
	NULL, offsetof(TreeItem,tagsObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_TAGS_CHANGED },

    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

/* Forward declarations */
static void RemoveTag(TreeItem *, Ttk_Tag);
static void RemoveTagFromCellsAtItem(TreeItem *, Ttk_Tag);

/* + NewItem --
 * 	Allocate a new, uninitialized, unlinked item
 */
static TreeItem *NewItem(void)
{
    TreeItem *item = (TreeItem *)ckalloc(sizeof(*item));

    item->entryPtr = 0;
    item->parent = item->children = item->next = item->prev = NULL;

    item->state = 0ul;
    item->textObj = NULL;
    item->imageObj = NULL;
    item->valuesObj = NULL;
    item->openObj = NULL;
    item->tagsObj = NULL;
    item->selObj = NULL;
    item->imageAnchorObj = NULL;
    item->hidden = 0;
    item->height = 1;
    item->cellTagSets = NULL;
    item->nTagSets = 0;

    item->tagset = NULL;
    item->imagespec = NULL;

    return item;
}

/* + FreeItem --
 * 	Destroy an item
 */
static void FreeItem(TreeItem *item)
{
    Tcl_Size i;
    if (item->textObj) { Tcl_DecrRefCount(item->textObj); }
    if (item->imageObj) { Tcl_DecrRefCount(item->imageObj); }
    if (item->valuesObj) { Tcl_DecrRefCount(item->valuesObj); }
    if (item->openObj) { Tcl_DecrRefCount(item->openObj); }
    if (item->tagsObj) { Tcl_DecrRefCount(item->tagsObj); }
    if (item->selObj) { Tcl_DecrRefCount(item->selObj); }
    if (item->imageAnchorObj) { Tcl_DecrRefCount(item->imageAnchorObj); }

    if (item->tagset)	{ Ttk_FreeTagSet(item->tagset); }
    if (item->imagespec) { TtkFreeImageSpec(item->imagespec); }
    if (item->cellTagSets) {
	for (i = 0; i < item->nTagSets; ++i) {
	    if (item->cellTagSets[i] != NULL) {
		Ttk_FreeTagSet(item->cellTagSets[i]);
	    }
	}
	ckfree(item->cellTagSets);
    }

    ckfree(item);
}

static void FreeItemCB(void *clientData) { FreeItem((TreeItem *)clientData); }

/* + DetachItem --
179
180
181
182
183
184
185
186

187
188

189
190

191
192
193
194
195
196






197
198
199
200
201
202
203
204



205
206
207
208
209
210
211



212
213
214


215
216
217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242


243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267

/*------------------------------------------------------------------------
 * +++ Display items and tag options.
 */

typedef struct {
    Tcl_Obj *textObj;		/* taken from item / data cell */
    Tcl_Obj *imageObj;		/* taken from item */

    Tcl_Obj *anchorObj;		/* from column <<NOTE-ANCHOR>> */
    Tcl_Obj *backgroundObj;	/* remainder from tag */

    Tcl_Obj *foregroundObj;
    Tcl_Obj *fontObj;

} DisplayItem;

static const Tk_OptionSpec TagOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	NULL, offsetof(DisplayItem,textObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },






    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(DisplayItem,imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	NULL, offsetof(DisplayItem,anchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},	/* <<NOTE-ANCHOR>> */
    {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
	NULL, offsetof(DisplayItem,backgroundObj), TCL_INDEX_NONE,



	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(DisplayItem,foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	NULL, offsetof(DisplayItem,fontObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },




    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};



/*------------------------------------------------------------------------
 * +++ Columns.
 *
 * There are separate option tables associated with the column record:
 * ColumnOptionSpecs is for configuring the column,
 * and HeadingOptionSpecs is for drawing headings.
 */
typedef struct {
    int 	width;		/* Column width, in pixels */
    int 	minWidth;	/* Minimum column width, in pixels */
    int 	stretch;	/* Should column stretch while resizing? */

    Tcl_Obj	*idObj;		/* Column identifier, from -columns option */

    Tcl_Obj	*anchorObj;	/* -anchor for cell data <<NOTE-ANCHOR>> */

    /* Column heading data:
     */
    Tcl_Obj 	*headingObj;		/* Heading label */
    Tcl_Obj	*headingImageObj;	/* Heading image */
    Tcl_Obj 	*headingAnchorObj;	/* -anchor for heading label */
    Tcl_Obj	*headingCommandObj;	/* Command to execute */
    Tcl_Obj 	*headingStateObj;	/* @@@ testing ... */
    Ttk_State	headingState;		/* ... */

    /* Temporary storage for cell data
     */
    Tcl_Obj 	*data;


} TreeColumn;

static void InitColumn(TreeColumn *column)
{
    column->width = 200;
    column->minWidth = 20;
    column->stretch = 1;

    column->idObj = 0;
    column->anchorObj = 0;

    column->headingState = 0;
    column->headingObj = 0;
    column->headingImageObj = 0;
    column->headingAnchorObj = 0;
    column->headingStateObj = 0;
    column->headingCommandObj = 0;

    column->data = 0;

}

static void FreeColumn(TreeColumn *column)
{
    if (column->idObj) { Tcl_DecrRefCount(column->idObj); }
    if (column->anchorObj) { Tcl_DecrRefCount(column->anchorObj); }








|
>


>


>


|



>
>
>
>
>
>



|
|
|


>
>
>







>
>
>



>
>












>
















>
>




|
|

>











>







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

/*------------------------------------------------------------------------
 * +++ Display items and tag options.
 */

typedef struct {
    Tcl_Obj *textObj;		/* taken from item / data cell */
    Tcl_Obj *imageObj;		/* taken from item or tag*/
    Tcl_Obj *imageAnchorObj;	/* taken from item or tag */
    Tcl_Obj *anchorObj;		/* from column <<NOTE-ANCHOR>> */
    Tcl_Obj *backgroundObj;	/* remainder from tag */
    Tcl_Obj *stripedBgObj;
    Tcl_Obj *foregroundObj;
    Tcl_Obj *fontObj;
    Tcl_Obj *paddingObj;
} DisplayItem;

static const Tk_OptionSpec DisplayOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	NULL, offsetof(DisplayItem,textObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"center", offsetof(DisplayItem,anchorObj), TCL_INDEX_NONE,
	0, 0, GEOMETRY_CHANGED},	/* <<NOTE-ANCHOR>> */
    /* From here down are the tags options. The index in TagOptionSpecs
     * below should be kept in synch with this position.
     */
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(DisplayItem,imageObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_ANCHOR, "-imageanchor", "imageAnchor", "ImageAnchor",
	NULL, offsetof(DisplayItem,imageAnchorObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
	NULL, offsetof(DisplayItem,backgroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-stripedbackground", "windowColor", "WindowColor",
	NULL, offsetof(DisplayItem,stripedBgObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(DisplayItem,foregroundObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	NULL, offsetof(DisplayItem,fontObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(DisplayItem,paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
};

static const Tk_OptionSpec *TagOptionSpecs = &DisplayOptionSpecs[2];

/*------------------------------------------------------------------------
 * +++ Columns.
 *
 * There are separate option tables associated with the column record:
 * ColumnOptionSpecs is for configuring the column,
 * and HeadingOptionSpecs is for drawing headings.
 */
typedef struct {
    int 	width;		/* Column width, in pixels */
    int 	minWidth;	/* Minimum column width, in pixels */
    int 	stretch;	/* Should column stretch while resizing? */
    int         separator;      /* Should this column have a separator? */
    Tcl_Obj	*idObj;		/* Column identifier, from -columns option */

    Tcl_Obj	*anchorObj;	/* -anchor for cell data <<NOTE-ANCHOR>> */

    /* Column heading data:
     */
    Tcl_Obj 	*headingObj;		/* Heading label */
    Tcl_Obj	*headingImageObj;	/* Heading image */
    Tcl_Obj 	*headingAnchorObj;	/* -anchor for heading label */
    Tcl_Obj	*headingCommandObj;	/* Command to execute */
    Tcl_Obj 	*headingStateObj;	/* @@@ testing ... */
    Ttk_State	headingState;		/* ... */

    /* Temporary storage for cell data
     */
    Tcl_Obj 	*data;
    int         selected;
    Ttk_TagSet	tagset;
} TreeColumn;

static void InitColumn(TreeColumn *column)
{
    column->width = atoi(DEF_COLWIDTH);
    column->minWidth = atoi(DEF_MINWIDTH);
    column->stretch = 1;
    column->separator = 0;
    column->idObj = 0;
    column->anchorObj = 0;

    column->headingState = 0;
    column->headingObj = 0;
    column->headingImageObj = 0;
    column->headingAnchorObj = 0;
    column->headingStateObj = 0;
    column->headingCommandObj = 0;

    column->data = 0;
    column->tagset = NULL;
}

static void FreeColumn(TreeColumn *column)
{
    if (column->idObj) { Tcl_DecrRefCount(column->idObj); }
    if (column->anchorObj) { Tcl_DecrRefCount(column->anchorObj); }

276
277
278
279
280
281
282



283
284
285
286
287
288
289

static const Tk_OptionSpec ColumnOptionSpecs[] = {
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_COLWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,width),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-minwidth", "minWidth", "MinWidth",
	DEF_MINWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,minWidth),



	0,0,0 },
    {TK_OPTION_BOOLEAN, "-stretch", "stretch", "Stretch",
	"1", TCL_INDEX_NONE, offsetof(TreeColumn,stretch),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"w", offsetof(TreeColumn,anchorObj), TCL_INDEX_NONE,	/* <<NOTE-ANCHOR>> */
	0,0,0 },







>
>
>







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

static const Tk_OptionSpec ColumnOptionSpecs[] = {
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_COLWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,width),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-minwidth", "minWidth", "MinWidth",
	DEF_MINWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,minWidth),
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-separator", "separator", "Separator",
	"0", TCL_INDEX_NONE, offsetof(TreeColumn,separator),
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-stretch", "stretch", "Stretch",
	"1", TCL_INDEX_NONE, offsetof(TreeColumn,stretch),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"w", offsetof(TreeColumn,anchorObj), TCL_INDEX_NONE,	/* <<NOTE-ANCHOR>> */
	0,0,0 },
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
static int GetEnumSetFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    const char *const table[],
    unsigned *resultPtr)
{
    unsigned result = 0;
    int i, objc;
    Tcl_Obj **objv;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return TCL_ERROR;

    for (i = 0; i < objc; ++i) {
	int index;







|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
static int GetEnumSetFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    const char *const table[],
    unsigned *resultPtr)
{
    unsigned result = 0;
    Tcl_Size i, objc;
    Tcl_Obj **objv;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return TCL_ERROR;

    for (i = 0; i < objc; ++i) {
	int index;
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404



405
406
407

408
409
410
411
412
413
414
415
416
417
418
419
420
421



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454



455
456
457
458
459
460









461
462
463
464
465
466
467
468
 */
typedef struct {
    /* Resources acquired at initialization-time:
     */
    Tk_OptionTable itemOptionTable;
    Tk_OptionTable columnOptionTable;
    Tk_OptionTable headingOptionTable;
    Tk_OptionTable tagOptionTable;
    Tk_BindingTable bindingTable;
    Ttk_TagTable tagTable;

    /* Acquired in GetLayout hook:
     */
    Ttk_Layout itemLayout;
    Ttk_Layout cellLayout;
    Ttk_Layout headingLayout;
    Ttk_Layout rowLayout;


    int headingHeight;		/* Space for headings */
    int rowHeight;		/* Height of each item */

    int indent;			/* #pixels horizontal offset for child items */

    /* Tree data:
     */
    Tcl_HashTable items;	/* Map: item name -> item */
    int serial;			/* Next item # for autogenerated names */
    TreeItem *root;		/* Root item */

    TreeColumn column0;		/* Column options for display column #0 */
    TreeColumn *columns;	/* Array of column options for data columns */

    TreeItem *focus;		/* Current focus item */
    TreeItem *endPtr;		/* See EndPosition() */

    /* Widget options:
     */
    Tcl_Obj *columnsObj;	/* List of symbolic column names */
    Tcl_Obj *displayColumnsObj;	/* List of columns to display */

    Tcl_Obj *heightObj;		/* height (rows) */
    Tcl_Obj *paddingObj;	/* internal padding */




    Tcl_Obj *showObj;		/* -show list */
    Tcl_Obj *selectModeObj;	/* -selectmode option */


    Scrollable xscroll;
    ScrollHandle xscrollHandle;
    Scrollable yscroll;
    ScrollHandle yscrollHandle;

    /* Derived resources:
     */
    Tcl_HashTable columnNames;	/* Map: column name -> column table entry */
    int nColumns; 		/* #columns */
    unsigned showFlags;		/* bitmask of subparts to display */

    TreeColumn **displayColumns; /* List of columns for display (incl tree) */
    int nDisplayColumns;	/* #display columns */



    Ttk_Box headingArea;	/* Display area for column headings */
    Ttk_Box treeArea;   	/* Display area for tree */
    int slack;			/* Slack space (see Resizing section) */

} TreePart;

typedef struct {
    WidgetCore core;
    TreePart tree;
} Treeview;

#define USER_MASK 		0x0100
#define COLUMNS_CHANGED 	(USER_MASK)
#define DCOLUMNS_CHANGED	(USER_MASK<<1)
#define SCROLLCMD_CHANGED	(USER_MASK<<2)
#define SHOW_CHANGED 		(USER_MASK<<3)

static const char *const SelectModeStrings[] = { "none", "browse", "extended", NULL };


static const Tk_OptionSpec TreeviewOptionSpecs[] = {
    {TK_OPTION_STRING, "-columns", "columns", "Columns",
	"", offsetof(Treeview,tree.columnsObj), TCL_INDEX_NONE,
	0, 0,COLUMNS_CHANGED | GEOMETRY_CHANGED /*| READONLY_OPTION*/ },
    {TK_OPTION_STRING, "-displaycolumns","displayColumns","DisplayColumns",
	"#all", offsetof(Treeview,tree.displayColumnsObj), TCL_INDEX_NONE,
	0, 0,DCOLUMNS_CHANGED | GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-show", "show", "Show",
	DEFAULT_SHOW, offsetof(Treeview,tree.showObj), TCL_INDEX_NONE,
	0, 0,SHOW_CHANGED | GEOMETRY_CHANGED },

    {TK_OPTION_STRING_TABLE, "-selectmode", "selectMode", "SelectMode",
	"extended", offsetof(Treeview,tree.selectModeObj), TCL_INDEX_NONE,
	0, (void *)SelectModeStrings, 0 },




    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TREE_ROWS, offsetof(Treeview,tree.heightObj), TCL_INDEX_NONE,
	0, 0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Treeview,tree.paddingObj), TCL_INDEX_NONE,









	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.xscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.yscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},







|









>



>
|




















>
>
>



>









|
<
|

|
>
>
>



|














>




|


|


|



|
>
>
>



|


>
>
>
>
>
>
>
>
>
|







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
 */
typedef struct {
    /* Resources acquired at initialization-time:
     */
    Tk_OptionTable itemOptionTable;
    Tk_OptionTable columnOptionTable;
    Tk_OptionTable headingOptionTable;
    Tk_OptionTable displayOptionTable;
    Tk_BindingTable bindingTable;
    Ttk_TagTable tagTable;

    /* Acquired in GetLayout hook:
     */
    Ttk_Layout itemLayout;
    Ttk_Layout cellLayout;
    Ttk_Layout headingLayout;
    Ttk_Layout rowLayout;
    Ttk_Layout separatorLayout;

    int headingHeight;		/* Space for headings */
    int rowHeight;		/* Height of each item */
    int colSeparatorWidth;	/* Width of column separator, if used (screen units) */
    int indent;			/* Horizontal offset for child items (screen units) */

    /* Tree data:
     */
    Tcl_HashTable items;	/* Map: item name -> item */
    int serial;			/* Next item # for autogenerated names */
    TreeItem *root;		/* Root item */

    TreeColumn column0;		/* Column options for display column #0 */
    TreeColumn *columns;	/* Array of column options for data columns */

    TreeItem *focus;		/* Current focus item */
    TreeItem *endPtr;		/* See EndPosition() */

    /* Widget options:
     */
    Tcl_Obj *columnsObj;	/* List of symbolic column names */
    Tcl_Obj *displayColumnsObj;	/* List of columns to display */

    Tcl_Obj *heightObj;		/* height (rows) */
    Tcl_Obj *paddingObj;	/* internal padding */
    Tcl_Size nTitleColumns;	/* -titlecolumns */
    Tcl_Size nTitleItems;		/* -titleitems */
    int striped;		/* -striped option */

    Tcl_Obj *showObj;		/* -show list */
    Tcl_Obj *selectModeObj;	/* -selectmode option */
    Tcl_Obj *selectTypeObj;	/* -selecttype option */

    Scrollable xscroll;
    ScrollHandle xscrollHandle;
    Scrollable yscroll;
    ScrollHandle yscrollHandle;

    /* Derived resources:
     */
    Tcl_HashTable columnNames;	/* Map: column name -> column table entry */
    Tcl_Size nColumns; 		/* #columns */

    Tcl_Size nDisplayColumns;	/* #display columns */
    TreeColumn **displayColumns; /* List of columns for display (incl tree) */
    int titleWidth;		/* Width of non-scrolled columns */
    int titleRows;		/* Height of non-scrolled items, in rows */
    int totalRows;		/* Height of non-hidden items, in rows */
    int rowPosNeedsUpdate;	/* Internal rowPos data needs update */
    Ttk_Box headingArea;	/* Display area for column headings */
    Ttk_Box treeArea;   	/* Display area for tree */
    int slack;			/* Slack space (see Resizing section) */
    unsigned showFlags;		/* bitmask of subparts to display */
} TreePart;

typedef struct {
    WidgetCore core;
    TreePart tree;
} Treeview;

#define USER_MASK 		0x0100
#define COLUMNS_CHANGED 	(USER_MASK)
#define DCOLUMNS_CHANGED	(USER_MASK<<1)
#define SCROLLCMD_CHANGED	(USER_MASK<<2)
#define SHOW_CHANGED 		(USER_MASK<<3)

static const char *const SelectModeStrings[] = { "none", "browse", "extended", NULL };
static const char *const SelectTypeStrings[] = { "item", "cell", NULL };

static const Tk_OptionSpec TreeviewOptionSpecs[] = {
    {TK_OPTION_STRING, "-columns", "columns", "Columns",
	"", offsetof(Treeview,tree.columnsObj), TCL_INDEX_NONE,
	0, 0, COLUMNS_CHANGED | GEOMETRY_CHANGED /*| READONLY_OPTION*/ },
    {TK_OPTION_STRING, "-displaycolumns","displayColumns","DisplayColumns",
	"#all", offsetof(Treeview,tree.displayColumnsObj), TCL_INDEX_NONE,
	0, 0, DCOLUMNS_CHANGED | GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-show", "show", "Show",
	DEFAULT_SHOW, offsetof(Treeview,tree.showObj), TCL_INDEX_NONE,
	0, 0, SHOW_CHANGED | GEOMETRY_CHANGED },

    {TK_OPTION_STRING_TABLE, "-selectmode", "selectMode", "SelectMode",
	"extended", offsetof(Treeview,tree.selectModeObj), TCL_INDEX_NONE,
	0, SelectModeStrings, 0 },
    {TK_OPTION_STRING_TABLE, "-selecttype", "selectType", "SelectType",
	"item", offsetof(Treeview,tree.selectTypeObj), TCL_INDEX_NONE,
	0, SelectTypeStrings, 0 },

    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TREE_ROWS, offsetof(Treeview,tree.heightObj), TCL_INDEX_NONE,
	0, 0, GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Treeview,tree.paddingObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-titlecolumns", "titlecolumns", "Titlecolumns",
	DEF_TITLECOLUMNS, TCL_INDEX_NONE, offsetof(Treeview,tree.nTitleColumns),
	TK_OPTION_VAR(Tcl_Size), 0, GEOMETRY_CHANGED},
    {TK_OPTION_INT, "-titleitems", "titleitems", "Titleitems",
	DEF_TITLEITEMS, TCL_INDEX_NONE, offsetof(Treeview,tree.nTitleItems),
	TK_OPTION_VAR(Tcl_Size), 0, GEOMETRY_CHANGED},
    {TK_OPTION_BOOLEAN, "-striped", "striped", "Striped",
	DEF_STRIPED, TCL_INDEX_NONE, offsetof(Treeview,tree.striped),
	0, 0, GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.xscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.yscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
481
482
483
484
485
486
487














488
489
490
491
492
493
494
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(ht, &search);
    while (entryPtr != NULL) {
	func(Tcl_GetHashValue(entryPtr));
	entryPtr = Tcl_NextHashEntry(&search);
    }
}















/* + unshareObj(objPtr) --
 * 	Ensure that a Tcl_Obj * has refcount 1 -- either return objPtr
 * 	itself,	or a duplicated copy.
 */
static Tcl_Obj *unshareObj(Tcl_Obj *objPtr)
{







>
>
>
>
>
>
>
>
>
>
>
>
>
>







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
    Tcl_HashSearch search;
    Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(ht, &search);
    while (entryPtr != NULL) {
	func(Tcl_GetHashValue(entryPtr));
	entryPtr = Tcl_NextHashEntry(&search);
    }
}

static int CellSelectionClear(Treeview *tv)
{
    TreeItem *item;
    int anyChange = 0;
    for (item=tv->tree.root; item; item = NextPreorder(item)) {
	if (item->selObj != NULL) {
	    Tcl_DecrRefCount(item->selObj);
	    item->selObj = NULL;
	    anyChange = 1;
	}
    }
    return anyChange;
}

/* + unshareObj(objPtr) --
 * 	Ensure that a Tcl_Obj * has refcount 1 -- either return objPtr
 * 	itself,	or a duplicated copy.
 */
static Tcl_Obj *unshareObj(Tcl_Obj *objPtr)
{
507
508
509
510
511
512
513



























514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
static void DisplayLayout(
    Ttk_Layout layout, void *recordPtr, Ttk_State state, Ttk_Box b, Drawable d)
{
    Ttk_RebindSublayout(layout, recordPtr);
    Ttk_PlaceLayout(layout, state, b);
    Ttk_DrawLayout(layout, state, d);
}




























/* + GetColumn --
 * 	Look up column by name or number.
 * 	Returns: pointer to column table entry, NULL if not found.
 * 	Leaves an error message in interp->result on error.
 */
static TreeColumn *GetColumn(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *columnIDObj)
{
    Tcl_HashEntry *entryPtr;
    int columnIndex;

    /* Check for named column:
     */
    entryPtr = Tcl_FindHashEntry(
	    &tv->tree.columnNames, Tcl_GetString(columnIDObj));
    if (entryPtr) {
	return (TreeColumn *)Tcl_GetHashValue(entryPtr);
    }

    /* Check for number:
     */
    if (Tcl_GetIntFromObj(NULL, columnIDObj, &columnIndex) == TCL_OK) {
	if (columnIndex < 0 || columnIndex >= tv->tree.nColumns) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Column index %s out of bounds",
		    Tcl_GetString(columnIDObj)));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLBOUND", NULL);
	    return NULL;
	}

	return tv->tree.columns + columnIndex;
    }
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	"Invalid column index %s", Tcl_GetString(columnIDObj)));
    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN", NULL);
    return NULL;
}

/* + FindColumn --
 * 	Look up column by name, number, or display index.
 */
static TreeColumn *FindColumn(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *columnIDObj)
{
    int colno;

    if (sscanf(Tcl_GetString(columnIDObj), "#%d", &colno) == 1)
    {	/* Display column specification, #n */
	if (colno >= 0 && colno < tv->tree.nDisplayColumns) {
	    return tv->tree.displayColumns[colno];
	}
	/* else */
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Column %s out of range", Tcl_GetString(columnIDObj)));







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|









|

|


|



















|

|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
static void DisplayLayout(
    Ttk_Layout layout, void *recordPtr, Ttk_State state, Ttk_Box b, Drawable d)
{
    Ttk_RebindSublayout(layout, recordPtr);
    Ttk_PlaceLayout(layout, state, b);
    Ttk_DrawLayout(layout, state, d);
}

/* DisplayLayoutTree --
 *	Like DisplayLayout, but for the tree column.
 */
static void DisplayLayoutTree(
    Tk_Anchor imageAnchor, Tk_Anchor textAnchor,
    Ttk_Layout layout, void *recordPtr, Ttk_State state, Ttk_Box b, Drawable d)
{
    Ttk_Element elem;
    Ttk_RebindSublayout(layout, recordPtr);

    elem = Ttk_FindElement(layout, "image");
    if (elem != NULL) {
	Ttk_AnchorElement(elem, imageAnchor);
    }
    elem = Ttk_FindElement(layout, "text");
    if (elem != NULL) {
	Ttk_AnchorElement(elem, textAnchor);
    }
    elem = Ttk_FindElement(layout, "focus");
    if (elem != NULL) {
	Ttk_AnchorElement(elem, textAnchor);
    }

    Ttk_PlaceLayout(layout, state, b);
    Ttk_DrawLayout(layout, state, d);
}

/* + GetColumn --
 * 	Look up column by name or number.
 * 	Returns: pointer to column table entry, NULL if not found.
 * 	Leaves an error message in interp->result on error.
 */
static TreeColumn *GetColumn(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *columnIDObj)
{
    Tcl_HashEntry *entryPtr;
    Tcl_Size columnIndex;

    /* Check for named column:
     */
    entryPtr = Tcl_FindHashEntry(
	    &tv->tree.columnNames, Tcl_GetString(columnIDObj));
    if (entryPtr) {
	return (TreeColumn *)Tcl_GetHashValue(entryPtr);
    }

    /* Check for index:
     */
    if (TkGetIntForIndex(columnIDObj, tv->tree.nColumns - 1, 1, &columnIndex) == TCL_OK) {
	if (columnIndex < 0 || columnIndex >= tv->tree.nColumns) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "Column index \"%s\" out of bounds",
		    Tcl_GetString(columnIDObj)));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLBOUND", NULL);
	    return NULL;
	}

	return tv->tree.columns + columnIndex;
    }
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	"Invalid column index %s", Tcl_GetString(columnIDObj)));
    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN", NULL);
    return NULL;
}

/* + FindColumn --
 * 	Look up column by name, number, or display index.
 */
static TreeColumn *FindColumn(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *columnIDObj)
{
    Tcl_WideInt colno;

    if (sscanf(Tcl_GetString(columnIDObj), "#%" TCL_LL_MODIFIER "d", &colno) == 1)
    {	/* Display column specification, #n */
	if (colno >= 0 && colno < tv->tree.nDisplayColumns) {
	    return tv->tree.displayColumns[colno];
	}
	/* else */
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Column %s out of range", Tcl_GetString(columnIDObj)));
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
 */

static TreeItem **GetItemListFromObj(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *objPtr)
{
    TreeItem **items;
    Tcl_Obj **elements;
    int i, nElements;

    if (Tcl_ListObjGetElements(interp,objPtr,&nElements,&elements) != TCL_OK) {
	return NULL;
    }

    items = (TreeItem **)ckalloc((nElements + 1)*sizeof(TreeItem*));
    for (i = 0; i < nElements; ++i) {







|







733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
 */

static TreeItem **GetItemListFromObj(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *objPtr)
{
    TreeItem **items;
    Tcl_Obj **elements;
    Tcl_Size i, nElements;

    if (Tcl_ListObjGetElements(interp,objPtr,&nElements,&elements) != TCL_OK) {
	return NULL;
    }

    items = (TreeItem **)ckalloc((nElements + 1)*sizeof(TreeItem*));
    for (i = 0; i < nElements; ++i) {
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
 */

/* + TreeviewFreeColumns --
 * 	Free column data.
 */
static void TreeviewFreeColumns(Treeview *tv)
{
    int i;

    Tcl_DeleteHashTable(&tv->tree.columnNames);
    Tcl_InitHashTable(&tv->tree.columnNames, TCL_STRING_KEYS);

    if (tv->tree.columns) {
	for (i = 0; i < tv->tree.nColumns; ++i)
	    FreeColumn(tv->tree.columns + i);
	ckfree(tv->tree.columns);
	tv->tree.columns = 0;
    }
}

/* + TreeviewInitColumns --
 *	Initialize column data when -columns changes.
 *	Returns: TCL_OK or TCL_ERROR;
 */
static int TreeviewInitColumns(Tcl_Interp *interp, Treeview *tv)
{
    Tcl_Obj **columns;
    int i, ncols;

    if (Tcl_ListObjGetElements(
	    interp, tv->tree.columnsObj, &ncols, &columns) != TCL_OK)
    {
	return TCL_ERROR;
    }








|



















|







777
778
779
780
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
 */

/* + TreeviewFreeColumns --
 * 	Free column data.
 */
static void TreeviewFreeColumns(Treeview *tv)
{
    Tcl_Size i;

    Tcl_DeleteHashTable(&tv->tree.columnNames);
    Tcl_InitHashTable(&tv->tree.columnNames, TCL_STRING_KEYS);

    if (tv->tree.columns) {
	for (i = 0; i < tv->tree.nColumns; ++i)
	    FreeColumn(tv->tree.columns + i);
	ckfree(tv->tree.columns);
	tv->tree.columns = 0;
    }
}

/* + TreeviewInitColumns --
 *	Initialize column data when -columns changes.
 *	Returns: TCL_OK or TCL_ERROR;
 */
static int TreeviewInitColumns(Tcl_Interp *interp, Treeview *tv)
{
    Tcl_Obj **columns;
    Tcl_Size i, ncols;

    if (Tcl_ListObjGetElements(
	    interp, tv->tree.columnsObj, &ncols, &columns) != TCL_OK)
    {
	return TCL_ERROR;
    }

693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730

	Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
	    &tv->tree.columnNames, Tcl_GetString(columnName), &isNew);
	Tcl_SetHashValue(entryPtr, tv->tree.columns + i);

	InitColumn(tv->tree.columns + i);
	Tk_InitOptions(
	    interp, (ClientData)(tv->tree.columns + i),
	    tv->tree.columnOptionTable, tv->core.tkwin);
	Tk_InitOptions(
	    interp, (ClientData)(tv->tree.columns + i),
	    tv->tree.headingOptionTable, tv->core.tkwin);
	Tcl_IncrRefCount(columnName);
	tv->tree.columns[i].idObj = columnName;
    }

    return TCL_OK;
}

/* + TreeviewInitDisplayColumns --
 * 	Initializes the 'displayColumns' array.
 *
 * 	Note that displayColumns[0] is always the tree column,
 * 	even when SHOW_TREE is not set.
 *
 * @@@ TODO: disallow duplicated columns
 */
static int TreeviewInitDisplayColumns(Tcl_Interp *interp, Treeview *tv)
{
    Tcl_Obj **dcolumns;
    int index, ndcols;
    TreeColumn **displayColumns = 0;

    if (Tcl_ListObjGetElements(interp,
	    tv->tree.displayColumnsObj, &ndcols, &dcolumns) != TCL_OK) {
	return TCL_ERROR;
    }








|


|



















|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863

	Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
	    &tv->tree.columnNames, Tcl_GetString(columnName), &isNew);
	Tcl_SetHashValue(entryPtr, tv->tree.columns + i);

	InitColumn(tv->tree.columns + i);
	Tk_InitOptions(
	    interp, tv->tree.columns + i,
	    tv->tree.columnOptionTable, tv->core.tkwin);
	Tk_InitOptions(
	    interp, tv->tree.columns + i,
	    tv->tree.headingOptionTable, tv->core.tkwin);
	Tcl_IncrRefCount(columnName);
	tv->tree.columns[i].idObj = columnName;
    }

    return TCL_OK;
}

/* + TreeviewInitDisplayColumns --
 * 	Initializes the 'displayColumns' array.
 *
 * 	Note that displayColumns[0] is always the tree column,
 * 	even when SHOW_TREE is not set.
 *
 * @@@ TODO: disallow duplicated columns
 */
static int TreeviewInitDisplayColumns(Tcl_Interp *interp, Treeview *tv)
{
    Tcl_Obj **dcolumns;
    Tcl_Size index, ndcols;
    TreeColumn **displayColumns = 0;

    if (Tcl_ListObjGetElements(interp,
	    tv->tree.displayColumnsObj, &ndcols, &dcolumns) != TCL_OK) {
	return TCL_ERROR;
    }

762
763
764
765
766
767
768
769
770
771

772



773



774
775
776
777
778
779
780
#define FirstColumn(tv)  ((tv->tree.showFlags&SHOW_TREE) ? 0 : 1)

/* + TreeWidth --
 * 	Compute the requested tree width from the sum of visible column widths.
 */
static int TreeWidth(Treeview *tv)
{
    int i = FirstColumn(tv);
    int width = 0;


    while (i < tv->tree.nDisplayColumns) {



	width += tv->tree.displayColumns[i++]->width;



    }
    return width;
}

/* + RecomputeSlack --
 */
static void RecomputeSlack(Treeview *tv)







|


>

>
>
>

>
>
>







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
#define FirstColumn(tv)  ((tv->tree.showFlags&SHOW_TREE) ? 0 : 1)

/* + TreeWidth --
 * 	Compute the requested tree width from the sum of visible column widths.
 */
static int TreeWidth(Treeview *tv)
{
    Tcl_Size i = FirstColumn(tv);
    int width = 0;

    tv->tree.titleWidth = 0;
    while (i < tv->tree.nDisplayColumns) {
	if (i == tv->tree.nTitleColumns) {
	    tv->tree.titleWidth = width;
	}
	width += tv->tree.displayColumns[i++]->width;
    }
    if (tv->tree.nTitleColumns >= tv->tree.nDisplayColumns) {
	tv->tree.titleWidth = width;
    }
    return width;
}

/* + RecomputeSlack --
 */
static void RecomputeSlack(Treeview *tv)
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
    return n;
}

/* + ShoveLeft --
 * 	Adjust width of (stretchable) columns to the left by N pixels.
 * 	Returns: leftover slack.
 */
static int ShoveLeft(Treeview *tv, int i, int n)
{
    int first = FirstColumn(tv);
    while (n != 0 && i >= first) {
	TreeColumn *c = tv->tree.displayColumns[i];
	if (c->stretch) {
	    n -= Stretch(c, n);
	}
	--i;
    }
    return n;
}

/* + ShoveRight --
 * 	Adjust width of (stretchable) columns to the right by N pixels.
 * 	Returns: leftover slack.
 */
static int ShoveRight(Treeview *tv, int i, int n)
{
    while (n != 0 && i < tv->tree.nDisplayColumns) {
	TreeColumn *c = tv->tree.displayColumns[i];
	if (c->stretch) {
	    n -= Stretch(c, n);
	}
	++i;







|

|














|







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
    return n;
}

/* + ShoveLeft --
 * 	Adjust width of (stretchable) columns to the left by N pixels.
 * 	Returns: leftover slack.
 */
static int ShoveLeft(Treeview *tv, Tcl_Size i, int n)
{
    Tcl_Size first = FirstColumn(tv);
    while (n != 0 && i >= first) {
	TreeColumn *c = tv->tree.displayColumns[i];
	if (c->stretch) {
	    n -= Stretch(c, n);
	}
	--i;
    }
    return n;
}

/* + ShoveRight --
 * 	Adjust width of (stretchable) columns to the right by N pixels.
 * 	Returns: leftover slack.
 */
static int ShoveRight(Treeview *tv, Tcl_Size i, int n)
{
    while (n != 0 && i < tv->tree.nDisplayColumns) {
	TreeColumn *c = tv->tree.displayColumns[i];
	if (c->stretch) {
	    n -= Stretch(c, n);
	}
	++i;
863
864
865
866
867
868
869

870
871
872
873
874
875
876
877
 * 	The "((++w % m) < r)" term is there so that the remainder r = n % m
 * 	is distributed round-robin.
 */
static int DistributeWidth(Treeview *tv, int n)
{
    int w = TreeWidth(tv);
    int m = 0;

    int i, d, r;

    for (i = FirstColumn(tv); i < tv->tree.nDisplayColumns; ++i) {
	if (tv->tree.displayColumns[i]->stretch) {
	    ++m;
	}
    }
    if (m == 0) {







>
|







1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
 * 	The "((++w % m) < r)" term is there so that the remainder r = n % m
 * 	is distributed round-robin.
 */
static int DistributeWidth(Treeview *tv, int n)
{
    int w = TreeWidth(tv);
    int m = 0;
    Tcl_Size  i;
    int d, r;

    for (i = FirstColumn(tv); i < tv->tree.nDisplayColumns; ++i) {
	if (tv->tree.displayColumns[i]->stretch) {
	    ++m;
	}
    }
    if (m == 0) {
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
	    DistributeWidth(tv, PickupSlack(tv, delta))));
}

/* + DragColumn --
 * 	Move the separator to the right of specified column,
 * 	adjusting other column widths as necessary.
 */
static void DragColumn(Treeview *tv, int i, int delta)
{
    TreeColumn *c = tv->tree.displayColumns[i];
    int dl = delta - ShoveLeft(tv, i-1, delta - Stretch(c, delta));
    int dr = ShoveRight(tv, i+1, PickupSlack(tv, -dl));
    DepositSlack(tv, dr);
}













































































































/*------------------------------------------------------------------------
 * +++ Event handlers.
 */

static TreeItem *IdentifyItem(Treeview *tv, int y); /*forward*/


static const unsigned long TreeviewBindEventMask =
      KeyPressMask|KeyReleaseMask
    | ButtonPressMask|ButtonReleaseMask
    | PointerMotionMask|ButtonMotionMask
    | VirtualEventMask
    ;

static void TreeviewBindEventProc(void *clientData, XEvent *event)
{
    Treeview *tv = (Treeview *)clientData;
    TreeItem *item = NULL;
    Ttk_TagSet tagset;




    /*
     * Figure out where to deliver the event.
     */
    switch (event->type)
    {
	case KeyPress:
	case KeyRelease:
	case VirtualEvent:
	    item = tv->tree.focus;
	    break;
	case ButtonPress:
	case ButtonRelease:
	    item = IdentifyItem(tv, event->xbutton.y);

	    break;
	case MotionNotify:
	    item = IdentifyItem(tv, event->xmotion.y);

	    break;
	default:
	    break;
    }

    if (!item) {
	return;
    }

    /* ASSERT: Ttk_GetTagSetFromObj succeeds.
     * NB: must use a local copy of the tagset,
     * in case a binding script stomps on -tags.
     */
    tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, item->tagsObj);


















    /*
     * Fire binding:
     */
    Tcl_Preserve(clientData);
    Tk_BindEvent(tv->tree.bindingTable, event, tv->core.tkwin,
	    tagset->nTags, (void **)tagset->tags);







|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>













>
>
>














>



>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	    DistributeWidth(tv, PickupSlack(tv, delta))));
}

/* + DragColumn --
 * 	Move the separator to the right of specified column,
 * 	adjusting other column widths as necessary.
 */
static void DragColumn(Treeview *tv, Tcl_Size i, int delta)
{
    TreeColumn *c = tv->tree.displayColumns[i];
    int dl = delta - ShoveLeft(tv, i-1, delta - Stretch(c, delta));
    int dr = ShoveRight(tv, i+1, PickupSlack(tv, -dl));
    DepositSlack(tv, dr);
}

/*------------------------------------------------------------------------
 * +++ Cells.
 */

typedef struct {
    TreeItem *item;
    TreeColumn *column;
    Tcl_Obj *colObj;
} TreeCell;

/* + GetCellFromObj
 * 	Get Row and Column from a cell ID.
 */
static int GetCellFromObj(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *obj,
    int displayColumnOnly, int *displayColumn,
    TreeCell *cell)
{
    Tcl_Size nElements;
    Tcl_Obj **elements;

    if (Tcl_ListObjGetElements(interp, obj, &nElements, &elements) != TCL_OK) {
	return TCL_ERROR;
    }
    if (nElements != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Cell id must be a list of two elements", -1));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "CELL", NULL);
	return TCL_ERROR;
    }
    /* Valid item/column in each pair? */
    cell->item = FindItem(interp, tv, elements[0]);
    if (!cell->item) {
	return TCL_ERROR;
    }
    cell->column = FindColumn(interp, tv, elements[1]);
    if (!cell->column) {
	return TCL_ERROR;
    }
    /* colObj is short lived and do not keep a reference counted */
    cell->colObj = elements[1];
    if (displayColumnOnly) {
	Tcl_Size i = FirstColumn(tv);
	while (i < tv->tree.nDisplayColumns) {
	    if (tv->tree.displayColumns[i] == cell->column) {
		break;
	    }
	    ++i;
	}
	if (i == tv->tree.nDisplayColumns) { /* specified column unviewable */
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Cell id must be in a visible column", -1));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "CELL", NULL);
	    return TCL_ERROR;
	}
	if (displayColumn != NULL) {
	    *displayColumn = i;
	}
    }
    return TCL_OK;
}

/* + GetCellListFromObj --
 * 	Parse a Tcl_Obj * as a list of cells.
 * 	Returns an array of cells; result must be ckfree()d.
 *      On error, returns NULL and leaves an error
 * 	message in interp.
 */

static TreeCell *GetCellListFromObj(
	Tcl_Interp *interp, Treeview *tv, Tcl_Obj *objPtr, Tcl_Size *nCells)
{
    TreeCell *cells;
    TreeCell cell;
    Tcl_Obj **elements;
    Tcl_Obj *oneCell;
    Tcl_Size i, n;

    if (Tcl_ListObjGetElements(interp, objPtr, &n, &elements) != TCL_OK) {
	return NULL;
    }

    /* A two element list might be a single cell */
    if (n == 2) {
	if (GetCellFromObj(interp, tv, objPtr, 0, NULL, &cell)
		== TCL_OK) {
	    n = 1;
	    oneCell = objPtr;
	    elements = &oneCell;
	} else {
	    Tcl_ResetResult(interp);
	}
    }

    cells = (TreeCell *) ckalloc(n * sizeof(TreeCell));
    for (i = 0; i < n; ++i) {
	if (GetCellFromObj(interp, tv, elements[i], 0, NULL, &cells[i]) != TCL_OK) {
	    ckfree(cells);
	    return NULL;
	}
    }

    if (nCells) {
	*nCells = n;
    }
    return cells;
}

/*------------------------------------------------------------------------
 * +++ Event handlers.
 */

static TreeItem *IdentifyItem(Treeview *tv, int y); /*forward*/
static Tcl_Size IdentifyDisplayColumn(Treeview *tv, int x, int *x1); /*forward*/

static const unsigned long TreeviewBindEventMask =
      KeyPressMask|KeyReleaseMask
    | ButtonPressMask|ButtonReleaseMask
    | PointerMotionMask|ButtonMotionMask
    | VirtualEventMask
    ;

static void TreeviewBindEventProc(void *clientData, XEvent *event)
{
    Treeview *tv = (Treeview *)clientData;
    TreeItem *item = NULL;
    Ttk_TagSet tagset;
    int unused;
    Tcl_Size colno = TCL_INDEX_NONE;
    TreeColumn *column = NULL;

    /*
     * Figure out where to deliver the event.
     */
    switch (event->type)
    {
	case KeyPress:
	case KeyRelease:
	case VirtualEvent:
	    item = tv->tree.focus;
	    break;
	case ButtonPress:
	case ButtonRelease:
	    item = IdentifyItem(tv, event->xbutton.y);
	    colno = IdentifyDisplayColumn(tv, event->xbutton.x, &unused);
	    break;
	case MotionNotify:
	    item = IdentifyItem(tv, event->xmotion.y);
	    colno = IdentifyDisplayColumn(tv, event->xmotion.x, &unused);
	    break;
	default:
	    break;
    }

    if (!item) {
	return;
    }

    /* ASSERT: Ttk_GetTagSetFromObj succeeds.
     * NB: must use a local copy of the tagset,
     * in case a binding script stomps on -tags.
     */
    tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, item->tagsObj);

    /*
     * Pick up any cell tags.
     */
    if (colno >= 0) {
	column = tv->tree.displayColumns[colno];
	if (column == &tv->tree.column0) {
	    colno = 0;
	} else {
	    colno = column - tv->tree.columns + 1;
	}
	if (colno < item->nTagSets) {
	    if (item->cellTagSets[colno] != NULL) {
		Ttk_TagSetAddSet(tagset, item->cellTagSets[colno]);
	    }
	}
    }

    /*
     * Fire binding:
     */
    Tcl_Preserve(clientData);
    Tk_BindEvent(tv->tree.bindingTable, event, tv->core.tkwin,
	    tagset->nTags, (void **)tagset->tags);
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

    tv->tree.itemOptionTable =
	Tk_CreateOptionTable(interp, ItemOptionSpecs);
    tv->tree.columnOptionTable =
	Tk_CreateOptionTable(interp, ColumnOptionSpecs);
    tv->tree.headingOptionTable =
	Tk_CreateOptionTable(interp, HeadingOptionSpecs);
    tv->tree.tagOptionTable =
	Tk_CreateOptionTable(interp, TagOptionSpecs);

    tv->tree.tagTable = Ttk_CreateTagTable(
	interp, tv->core.tkwin, TagOptionSpecs, sizeof(DisplayItem));
    tv->tree.bindingTable = Tk_CreateBindingTable(interp);
    Tk_CreateEventHandler(tv->core.tkwin,
	TreeviewBindEventMask, TreeviewBindEventProc, tv);

    tv->tree.itemLayout
	= tv->tree.cellLayout
	= tv->tree.headingLayout
	= tv->tree.rowLayout

	= 0;
    tv->tree.headingHeight = tv->tree.rowHeight = DEFAULT_ROWHEIGHT;

    tv->tree.indent = DEFAULT_INDENT;

    Tcl_InitHashTable(&tv->tree.columnNames, TCL_STRING_KEYS);
    tv->tree.nColumns = tv->tree.nDisplayColumns = 0;







    tv->tree.columns = NULL;
    tv->tree.displayColumns = NULL;
    tv->tree.showFlags = ~0;

    InitColumn(&tv->tree.column0);


    Tk_InitOptions(
	interp, (ClientData)(&tv->tree.column0),
	tv->tree.columnOptionTable, tv->core.tkwin);
    Tk_InitOptions(
	interp, (ClientData)(&tv->tree.column0),
	tv->tree.headingOptionTable, tv->core.tkwin);

    Tcl_InitHashTable(&tv->tree.items, TCL_STRING_KEYS);
    tv->tree.serial = 0;

    tv->tree.focus = tv->tree.endPtr = 0;

    /* Create root item "":
     */
    tv->tree.root = NewItem();
    Tk_InitOptions(interp, (ClientData)tv->tree.root,
	tv->tree.itemOptionTable, tv->core.tkwin);
    tv->tree.root->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    tv->tree.root->entryPtr = Tcl_CreateHashEntry(&tv->tree.items, "", &unused);
    Tcl_SetHashValue(tv->tree.root->entryPtr, tv->tree.root);

    /* Scroll handles:
     */







|
|











>

|
>




>
>
>
>
>
>
>





>
>

|


|










|







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

    tv->tree.itemOptionTable =
	Tk_CreateOptionTable(interp, ItemOptionSpecs);
    tv->tree.columnOptionTable =
	Tk_CreateOptionTable(interp, ColumnOptionSpecs);
    tv->tree.headingOptionTable =
	Tk_CreateOptionTable(interp, HeadingOptionSpecs);
    tv->tree.displayOptionTable =
	Tk_CreateOptionTable(interp, DisplayOptionSpecs);

    tv->tree.tagTable = Ttk_CreateTagTable(
	interp, tv->core.tkwin, TagOptionSpecs, sizeof(DisplayItem));
    tv->tree.bindingTable = Tk_CreateBindingTable(interp);
    Tk_CreateEventHandler(tv->core.tkwin,
	TreeviewBindEventMask, TreeviewBindEventProc, tv);

    tv->tree.itemLayout
	= tv->tree.cellLayout
	= tv->tree.headingLayout
	= tv->tree.rowLayout
	= tv->tree.separatorLayout
	= 0;
    tv->tree.headingHeight = tv->tree.rowHeight = 0;
    tv->tree.colSeparatorWidth = 1;
    tv->tree.indent = DEFAULT_INDENT;

    Tcl_InitHashTable(&tv->tree.columnNames, TCL_STRING_KEYS);
    tv->tree.nColumns = tv->tree.nDisplayColumns = 0;
    tv->tree.nTitleColumns = 0;
    tv->tree.nTitleItems = 0;
    tv->tree.titleWidth = 0;
    tv->tree.titleRows = 0;
    tv->tree.totalRows = 0;
    tv->tree.rowPosNeedsUpdate = 1;
    tv->tree.striped = 0;
    tv->tree.columns = NULL;
    tv->tree.displayColumns = NULL;
    tv->tree.showFlags = ~0;

    InitColumn(&tv->tree.column0);
    tv->tree.column0.idObj = Tcl_NewStringObj("#0", 2);
    Tcl_IncrRefCount(tv->tree.column0.idObj);
    Tk_InitOptions(
	interp, &tv->tree.column0,
	tv->tree.columnOptionTable, tv->core.tkwin);
    Tk_InitOptions(
	interp, &tv->tree.column0,
	tv->tree.headingOptionTable, tv->core.tkwin);

    Tcl_InitHashTable(&tv->tree.items, TCL_STRING_KEYS);
    tv->tree.serial = 0;

    tv->tree.focus = tv->tree.endPtr = 0;

    /* Create root item "":
     */
    tv->tree.root = NewItem();
    Tk_InitOptions(interp, tv->tree.root,
	tv->tree.itemOptionTable, tv->core.tkwin);
    tv->tree.root->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    tv->tree.root->entryPtr = Tcl_CreateHashEntry(&tv->tree.items, "", &unused);
    Tcl_SetHashValue(tv->tree.root->entryPtr, tv->tree.root);

    /* Scroll handles:
     */
1058
1059
1060
1061
1062
1063
1064

1065

1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
    Tk_DeleteBindingTable(tv->tree.bindingTable);
    Ttk_DeleteTagTable(tv->tree.tagTable);

    if (tv->tree.itemLayout) Ttk_FreeLayout(tv->tree.itemLayout);
    if (tv->tree.cellLayout) Ttk_FreeLayout(tv->tree.cellLayout);
    if (tv->tree.headingLayout) Ttk_FreeLayout(tv->tree.headingLayout);
    if (tv->tree.rowLayout) Ttk_FreeLayout(tv->tree.rowLayout);



    TreeviewFreeColumns(tv);

    if (tv->tree.displayColumns)
	ckfree((ClientData)tv->tree.displayColumns);

    foreachHashEntry(&tv->tree.items, FreeItemCB);
    Tcl_DeleteHashTable(&tv->tree.items);

    TtkFreeScrollHandle(tv->tree.xscrollHandle);
    TtkFreeScrollHandle(tv->tree.yscrollHandle);
}







>

>



|







1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
    Tk_DeleteBindingTable(tv->tree.bindingTable);
    Ttk_DeleteTagTable(tv->tree.tagTable);

    if (tv->tree.itemLayout) Ttk_FreeLayout(tv->tree.itemLayout);
    if (tv->tree.cellLayout) Ttk_FreeLayout(tv->tree.cellLayout);
    if (tv->tree.headingLayout) Ttk_FreeLayout(tv->tree.headingLayout);
    if (tv->tree.rowLayout) Ttk_FreeLayout(tv->tree.rowLayout);
    if (tv->tree.separatorLayout) Ttk_FreeLayout(tv->tree.separatorLayout);

    FreeColumn(&tv->tree.column0);
    TreeviewFreeColumns(tv);

    if (tv->tree.displayColumns)
	ckfree(tv->tree.displayColumns);

    foreachHashEntry(&tv->tree.items, FreeItemCB);
    Tcl_DeleteHashTable(&tv->tree.items);

    TtkFreeScrollHandle(tv->tree.xscrollHandle);
    TtkFreeScrollHandle(tv->tree.yscrollHandle);
}
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
	if (TreeviewInitColumns(interp, tv) != TCL_OK)
	    return TCL_ERROR;
	mask |= DCOLUMNS_CHANGED;
    }
    if (mask & DCOLUMNS_CHANGED) {
	if (TreeviewInitDisplayColumns(interp, tv) != TCL_OK)
	    return TCL_ERROR;

















    }
    if (mask & SCROLLCMD_CHANGED) {
	TtkScrollbarUpdateRequired(tv->tree.xscrollHandle);
	TtkScrollbarUpdateRequired(tv->tree.yscrollHandle);
    }
    if ((mask & SHOW_CHANGED)
	    && GetEnumSetFromObj(
		    interp,tv->tree.showObj,showStrings,&showFlags) != TCL_OK) {
	return TCL_ERROR;
    }

    if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
	return TCL_ERROR;
    }


    tv->tree.showFlags = showFlags;

    if (mask & (SHOW_CHANGED | DCOLUMNS_CHANGED)) {
	RecomputeSlack(tv);
    }
    return TCL_OK;
}

/* + ConfigureItem --
 * 	Set item options.
 */
static int ConfigureItem(
    Tcl_Interp *interp, Treeview *tv, TreeItem *item,
    int objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;
    Ttk_ImageSpec *newImageSpec = NULL;
    Ttk_TagSet newTagSet = NULL;

    if (Tk_SetOptions(interp, item, tv->tree.itemOptionTable,
		objc, objv, tv->core.tkwin, &savedOptions, &mask)
		!= TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Make sure that -values is a valid list:
     */
    if (item->valuesObj) {
	int unused;
	if (Tcl_ListObjLength(interp, item->valuesObj, &unused) != TCL_OK)
	    goto error;
    }










    /* Check -image.
     */
    if ((mask & ITEM_OPTION_IMAGE_CHANGED) && item->imageObj) {
	newImageSpec = TtkGetImageSpec(interp, tv->core.tkwin, item->imageObj);
	if (!newImageSpec) {
	    goto error;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















>













|
















|



>
>
>
>
>
>
>
>
>







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
	if (TreeviewInitColumns(interp, tv) != TCL_OK)
	    return TCL_ERROR;
	mask |= DCOLUMNS_CHANGED;
    }
    if (mask & DCOLUMNS_CHANGED) {
	if (TreeviewInitDisplayColumns(interp, tv) != TCL_OK)
	    return TCL_ERROR;
    }
    if (mask & COLUMNS_CHANGED) {
	CellSelectionClear(tv);
    }
    if (tv->tree.nTitleColumns < 0) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "\"#%" TCL_SIZE_MODIFIER "d\" is out of range",
                tv->tree.nTitleColumns));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "TITLECOLUMNS", NULL);
	return TCL_ERROR;
    }
    if (tv->tree.nTitleItems < 0) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "\"%" TCL_SIZE_MODIFIER "d\" is out of range",
                tv->tree.nTitleItems));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "TITLEITEMS", NULL);
	return TCL_ERROR;
    }
    if (mask & SCROLLCMD_CHANGED) {
	TtkScrollbarUpdateRequired(tv->tree.xscrollHandle);
	TtkScrollbarUpdateRequired(tv->tree.yscrollHandle);
    }
    if ((mask & SHOW_CHANGED)
	    && GetEnumSetFromObj(
		    interp,tv->tree.showObj,showStrings,&showFlags) != TCL_OK) {
	return TCL_ERROR;
    }

    if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
	return TCL_ERROR;
    }

    tv->tree.rowPosNeedsUpdate = 1;
    tv->tree.showFlags = showFlags;

    if (mask & (SHOW_CHANGED | DCOLUMNS_CHANGED)) {
	RecomputeSlack(tv);
    }
    return TCL_OK;
}

/* + ConfigureItem --
 * 	Set item options.
 */
static int ConfigureItem(
    Tcl_Interp *interp, Treeview *tv, TreeItem *item,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;
    Ttk_ImageSpec *newImageSpec = NULL;
    Ttk_TagSet newTagSet = NULL;

    if (Tk_SetOptions(interp, item, tv->tree.itemOptionTable,
		objc, objv, tv->core.tkwin, &savedOptions, &mask)
		!= TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Make sure that -values is a valid list:
     */
    if (item->valuesObj) {
	Tcl_Size unused;
	if (Tcl_ListObjLength(interp, item->valuesObj, &unused) != TCL_OK)
	    goto error;
    }

    /* Check -height
     */
    if (item->height < 1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Invalid item height %d", item->height));
	Tcl_SetErrorCode(interp, "TTK", "TREE", "HEIGHT", NULL);
	goto error;
    }

    /* Check -image.
     */
    if ((mask & ITEM_OPTION_IMAGE_CHANGED) && item->imageObj) {
	newImageSpec = TtkGetImageSpec(interp, tv->core.tkwin, item->imageObj);
	if (!newImageSpec) {
	    goto error;
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
	if (item->tagset) { Ttk_FreeTagSet(item->tagset); }
	item->tagset = newTagSet;
    }
    if (mask & ITEM_OPTION_IMAGE_CHANGED) {
	if (item->imagespec) { TtkFreeImageSpec(item->imagespec); }
	item->imagespec = newImageSpec;
    }

    TtkRedisplayWidget(&tv->core);
    return TCL_OK;

error:
    Tk_RestoreSavedOptions(&savedOptions);
    if (newTagSet) { Ttk_FreeTagSet(newTagSet); }
    if (newImageSpec) { TtkFreeImageSpec(newImageSpec); }
    return TCL_ERROR;
}

/* + ConfigureColumn --
 * 	Set column options.
 */
static int ConfigureColumn(
    Tcl_Interp *interp, Treeview *tv, TreeColumn *column,
    int objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;

    if (Tk_SetOptions(interp, column,
	    tv->tree.columnOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)







>















|







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
	if (item->tagset) { Ttk_FreeTagSet(item->tagset); }
	item->tagset = newTagSet;
    }
    if (mask & ITEM_OPTION_IMAGE_CHANGED) {
	if (item->imagespec) { TtkFreeImageSpec(item->imagespec); }
	item->imagespec = newImageSpec;
    }
    tv->tree.rowPosNeedsUpdate = 1;
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;

error:
    Tk_RestoreSavedOptions(&savedOptions);
    if (newTagSet) { Ttk_FreeTagSet(newTagSet); }
    if (newImageSpec) { TtkFreeImageSpec(newImageSpec); }
    return TCL_ERROR;
}

/* + ConfigureColumn --
 * 	Set column options.
 */
static int ConfigureColumn(
    Tcl_Interp *interp, Treeview *tv, TreeColumn *column,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;

    if (Tk_SetOptions(interp, column,
	    tv->tree.columnOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
}

/* + ConfigureHeading --
 * 	Set heading options.
 */
static int ConfigureHeading(
    Tcl_Interp *interp, Treeview *tv, TreeColumn *column,
    int objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;

    if (Tk_SetOptions(interp, column,
	    tv->tree.headingOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)







|







1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
}

/* + ConfigureHeading --
 * 	Set heading options.
 */
static int ConfigureHeading(
    Tcl_Interp *interp, Treeview *tv, TreeColumn *column,
    Tcl_Size objc, Tcl_Obj *const objv[])
{
    Tk_SavedOptions savedOptions;
    int mask;

    if (Tk_SetOptions(interp, column,
	    tv->tree.headingOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)
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
    return TCL_ERROR;
}

/*------------------------------------------------------------------------
 * +++ Geometry routines.
 */

/* + CountRows --
 * 	Returns the number of viewable rows rooted at item
 */

static int CountRows(TreeItem *item)

{


    int rows = 1;

    if (item->state & TTK_STATE_OPEN) {
	TreeItem *child = item->children;
	while (child) {
	    rows += CountRows(child);
	    child = child->next;
	}
    }

    return rows;






}

/* + IdentifyRow --
 * 	Recursive search for item at specified y position.
 * 	Main work routine for IdentifyItem()
 */
static TreeItem *IdentifyRow(
    Treeview *tv,	/* Widget record */
    TreeItem *item, 	/* Where to start search */
    int *ypos,		/* Scan position */
    int y)		/* Target y coordinate */
{
    while (item) {
	int next_ypos = *ypos + tv->tree.rowHeight;
	if (*ypos <= y && y <= next_ypos) {
	    return item;
	}
	*ypos = next_ypos;
	if (item->state & TTK_STATE_OPEN) {
	    TreeItem *subitem = IdentifyRow(tv, item->children, ypos, y);
	    if (subitem) {
		return subitem;
	    }



	}
	item = item->next;
    }
    return 0;











}

/* + IdentifyItem --
 * 	Locate the item at the specified y position, if any.
 */
static TreeItem *IdentifyItem(Treeview *tv, int y)
{

    int rowHeight = tv->tree.rowHeight;
    int ypos = tv->tree.treeArea.y - rowHeight * tv->tree.yscroll.first;











    return IdentifyRow(tv, tv->tree.root->children, &ypos, y);




}

/* + IdentifyDisplayColumn --
 * 	Returns the display column number at the specified x position,
 * 	or -1 if x is outside any columns.
 */
static int IdentifyDisplayColumn(Treeview *tv, int x, int *x1)
{
    int colno = FirstColumn(tv);
    int xpos = tv->tree.treeArea.x - tv->tree.xscroll.first;





    while (colno < tv->tree.nDisplayColumns) {
	TreeColumn *column = tv->tree.displayColumns[colno];
	int next_xpos = xpos + column->width;
	if (xpos <= x && x <= next_xpos + HALO) {
	    *x1 = next_xpos;
	    return colno;
	}
	++colno;
	xpos = next_xpos;
    }

    return -1;
}

/* + RowNumber --
 * 	Calculate which row the specified item appears on;
 * 	returns -1 if the item is not viewable.
 * 	Xref: DrawForest, IdentifyItem.
 */
static int RowNumber(Treeview *tv, TreeItem *item)
{
    TreeItem *p = tv->tree.root->children;
    int n = 0;

    while (p) {
	if (p == item)
	    return n;

	++n;

	/* Find next viewable item in preorder traversal order
	 */
	if (p->children && (p->state & TTK_STATE_OPEN)) {
	    p = p->children;
	} else {
	    while (!p->next && p && p->parent)
		p = p->parent;
	    if (p)
		p = p->next;
	}
    }

    return -1;
}

/* + ItemDepth -- return the depth of a tree item.
 * 	The depth of an item is equal to the number of proper ancestors,
 * 	not counting the root node.
 */
static int ItemDepth(TreeItem *item)
{
    int depth = 0;
    while (item->parent) {
	++depth;
	item = item->parent;
    }
    return depth-1;
}

/* + ItemRow --
 * 	Returns row number of specified item relative to root,
 * 	-1 if item is not viewable.
 */
static int ItemRow(Treeview *tv, TreeItem *p)
{
    TreeItem *root = tv->tree.root;
    int rowNumber = 0;

    for (;;) {
	if (p->prev) {
	    p = p->prev;
	    rowNumber += CountRows(p);
	} else {
	    p = p->parent;
	    if (!(p && (p->state & TTK_STATE_OPEN))) {
		/* detached or closed ancestor */
		return -1;
	    }

	    if (p == root) {


		return rowNumber;
	    }
	    ++rowNumber;
	}
    }

}

/* + BoundingBox --
 * 	Compute the parcel of the specified column of the specified item,
 *	(or the entire item if column is NULL)
 *	Returns: 0 if item or column is not viewable, 1 otherwise.
 */
static int BoundingBox(
    Treeview *tv,		/* treeview widget */
    TreeItem *item,		/* desired item */
    TreeColumn *column,		/* desired column */
    Ttk_Box *bbox_rtn)		/* bounding box of item */
{
    int row = ItemRow(tv, item);
    Ttk_Box bbox = tv->tree.treeArea;

    if (row < tv->tree.yscroll.first || row > tv->tree.yscroll.last) {




	/* not viewable, or off-screen */
	return 0;
    }

    bbox.y += (row - tv->tree.yscroll.first) * tv->tree.rowHeight;
    bbox.height = tv->tree.rowHeight;

    bbox.x -= tv->tree.xscroll.first;
    bbox.width = TreeWidth(tv);

    if (column) {
	int xpos = 0, i = FirstColumn(tv);

	while (i < tv->tree.nDisplayColumns) {
	    if (tv->tree.displayColumns[i] == column) {
		break;
	    }
	    xpos += tv->tree.displayColumns[i]->width;
	    ++i;
	}
	if (i == tv->tree.nDisplayColumns) { /* specified column unviewable */
	    return 0;
	}
	bbox.x += xpos;
	bbox.width = column->width;






	/* Account for indentation in tree column:
	 */
	if (column == &tv->tree.column0) {
	    int indent = tv->tree.indent * ItemDepth(item);
	    bbox.x += indent;
	    bbox.width -= indent;







|
|

>
|
>

>
>
|

|
<
<
<
|
|
|
>
|
>
>
>
>
>
>
|

<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
|
|
<
<
|
|
>
>
>
|
<
|
|
>
>
>
>
>
>
>
>
>
>
>







>

|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>






|

|
|
>
>
>
>










<
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<

<
<
<
<
<
<
<
<
<
<
<
<
|
















|
|
<

|

|
<
|
<
|
<
<
<
<
<
<
|
|
>
|
>
>
|
|
<
<
<
>













|


|
>
>
>
>




|
|





|
>












>
>
>
>
>







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
    return TCL_ERROR;
}

/*------------------------------------------------------------------------
 * +++ Geometry routines.
 */

/* + UpdatePositionItem --
 * 	Update position data for all visible items.
 */
static void UpdatePositionItem(
    Treeview *tv, TreeItem *item, int hidden,
    int *rowPos, int *itemPos, int *visiblePos)
{
    TreeItem *child = item->children;
    item->itemPos = *itemPos;
    *itemPos += 1;

    if (item->hidden) {



	hidden = 1;
    }

    if (hidden) {
	item->rowPos = -1;
	item->visiblePos = -1;
    } else {
	item->rowPos = *rowPos;
	item->visiblePos = *visiblePos;
	if (*visiblePos == tv->tree.nTitleItems) {
	    tv->tree.titleRows = *rowPos;
	}











	*visiblePos += 1;


	*rowPos += item->height;
    }

    if (!(item->state & TTK_STATE_OPEN)) {


	hidden = 1;
    }
    while (child) {
	UpdatePositionItem(tv, child, hidden, rowPos, itemPos, visiblePos);
	child = child->next;
    }

}

/* + UpdatePositionTree --
 * 	Update position data for all visible items.
 */
static void UpdatePositionTree(Treeview *tv)
{
    /* -1 for the invisible root */
    int rowPos = -1, itemPos = -1, visiblePos = -1;
    tv->tree.titleRows = 0;
    UpdatePositionItem(tv, tv->tree.root, 0, &rowPos, &itemPos, &visiblePos);
    tv->tree.totalRows = rowPos;
    tv->tree.rowPosNeedsUpdate = 0;
}

/* + IdentifyItem --
 * 	Locate the item at the specified y position, if any.
 */
static TreeItem *IdentifyItem(Treeview *tv, int y)
{
    TreeItem *item;
    int rowHeight = tv->tree.rowHeight;
    int ypos = tv->tree.treeArea.y;
    int nextRow, row;
    if (y < ypos) {
	return NULL;
    }
    if (tv->tree.rowPosNeedsUpdate) {
	UpdatePositionTree(tv);
    }
    row = (y - ypos) / rowHeight;
    if (row >= tv->tree.titleRows) {
	row += tv->tree.yscroll.first;
    }
    for (item = tv->tree.root->children; item; item = NextPreorder(item)) {
	nextRow = item->rowPos + item->height;
	if (item->rowPos <= row && row < nextRow) break;
    }
    return item;
}

/* + IdentifyDisplayColumn --
 * 	Returns the display column number at the specified x position,
 * 	or -1 if x is outside any columns.
 */
static Tcl_Size IdentifyDisplayColumn(Treeview *tv, int x, int *x1)
{
    Tcl_Size colno = FirstColumn(tv);
    int xpos = tv->tree.treeArea.x;

    if (tv->tree.nTitleColumns <= colno) {
	xpos -= tv->tree.xscroll.first;
    }

    while (colno < tv->tree.nDisplayColumns) {
	TreeColumn *column = tv->tree.displayColumns[colno];
	int next_xpos = xpos + column->width;
	if (xpos <= x && x <= next_xpos + HALO) {
	    *x1 = next_xpos;
	    return colno;
	}
	++colno;
	xpos = next_xpos;

	if (tv->tree.nTitleColumns == colno) {


	    xpos -= tv->tree.xscroll.first;









	}



    }














    return TCL_INDEX_NONE;
}

/* + ItemDepth -- return the depth of a tree item.
 * 	The depth of an item is equal to the number of proper ancestors,
 * 	not counting the root node.
 */
static int ItemDepth(TreeItem *item)
{
    int depth = 0;
    while (item->parent) {
	++depth;
	item = item->parent;
    }
    return depth-1;
}

/* + DisplayRow --
 * 	Returns the position row has on screen, or -1 if off-screen.

 */
static int DisplayRow(int row, Treeview *tv)
{
    int visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight

	    - tv->tree.titleRows;

    if (row < tv->tree.titleRows) {






	return row;
    }
    row -= tv->tree.titleRows;
    if (row < tv->tree.yscroll.first
	    || row > tv->tree.yscroll.first + visibleRows) {
	/* not viewable, or off-screen */
	return -1;
    }



    return row - tv->tree.yscroll.first + tv->tree.titleRows;
}

/* + BoundingBox --
 * 	Compute the parcel of the specified column of the specified item,
 *	(or the entire item if column is NULL)
 *	Returns: 0 if item or column is not viewable, 1 otherwise.
 */
static int BoundingBox(
    Treeview *tv,		/* treeview widget */
    TreeItem *item,		/* desired item */
    TreeColumn *column,		/* desired column */
    Ttk_Box *bbox_rtn)		/* bounding box of item */
{
    int dispRow;
    Ttk_Box bbox = tv->tree.treeArea;

    if (tv->tree.rowPosNeedsUpdate) {
	UpdatePositionTree(tv);
    }
    dispRow = DisplayRow(item->rowPos, tv);
    if (dispRow < 0) {
	/* not viewable, or off-screen */
	return 0;
    }

    bbox.y += dispRow * tv->tree.rowHeight;
    bbox.height = tv->tree.rowHeight * item->height;

    bbox.x -= tv->tree.xscroll.first;
    bbox.width = TreeWidth(tv);

    if (column) {
	int xpos = 0;
	Tcl_Size i = FirstColumn(tv);
	while (i < tv->tree.nDisplayColumns) {
	    if (tv->tree.displayColumns[i] == column) {
		break;
	    }
	    xpos += tv->tree.displayColumns[i]->width;
	    ++i;
	}
	if (i == tv->tree.nDisplayColumns) { /* specified column unviewable */
	    return 0;
	}
	bbox.x += xpos;
	bbox.width = column->width;

	if (i < tv->tree.nTitleColumns) {
	    /* Unscrollable column, remove scroll shift */
	    bbox.x += tv->tree.xscroll.first;
	}

	/* Account for indentation in tree column:
	 */
	if (column == &tv->tree.column0) {
	    int indent = tv->tree.indent * ItemDepth(item);
	    bbox.x += indent;
	    bbox.width -= indent;
1504
1505
1506
1507
1508
1509
1510
1511

1512
1513
1514
1515
1516
1517
1518
1519
1520

static const char *const regionStrings[] = {
    "nothing", "heading", "separator", "tree", "cell", 0
};

static TreeRegion IdentifyRegion(Treeview *tv, int x, int y)
{
    int x1 = 0, colno;


    colno = IdentifyDisplayColumn(tv, x, &x1);
    if (Ttk_BoxContains(tv->tree.headingArea, x, y)) {
	if (colno < 0) {
	    return REGION_NOTHING;
	} else if (-HALO <= x1 - x  && x1 - x <= HALO) {
	    return REGION_SEPARATOR;
	} else {
	    return REGION_HEADING;







|
>

<







1818
1819
1820
1821
1822
1823
1824
1825
1826
1827

1828
1829
1830
1831
1832
1833
1834

static const char *const regionStrings[] = {
    "nothing", "heading", "separator", "tree", "cell", 0
};

static TreeRegion IdentifyRegion(Treeview *tv, int x, int y)
{
    int x1 = 0;
    Tcl_Size colno = IdentifyDisplayColumn(tv, x, &x1);


    if (Ttk_BoxContains(tv->tree.headingArea, x, y)) {
	if (colno < 0) {
	    return REGION_NOTHING;
	} else if (-HALO <= x1 - x  && x1 - x <= HALO) {
	    return REGION_SEPARATOR;
	} else {
	    return REGION_HEADING;
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
 */
static Ttk_Layout TreeviewGetLayout(
    Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Layout treeLayout = TtkWidgetGetLayout(interp, themePtr, recordPtr);
    Tcl_Obj *objPtr;
    int unused;



    if (!(
	treeLayout
     && GetSublayout(interp, themePtr, treeLayout, ".Item",
	    tv->tree.tagOptionTable, &tv->tree.itemLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Cell",
	    tv->tree.tagOptionTable, &tv->tree.cellLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Heading",
	    tv->tree.headingOptionTable, &tv->tree.headingLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Row",
	    tv->tree.tagOptionTable, &tv->tree.rowLayout)


    )) {
	return 0;
    }

    /* Compute heading height.
     */
    Ttk_RebindSublayout(tv->tree.headingLayout, &tv->tree.column0);
    Ttk_LayoutSize(tv->tree.headingLayout, 0, &unused, &tv->tree.headingHeight);

    /* Get item height, indent from style:
     * @@@ TODO: sanity-check.
     */










    tv->tree.rowHeight = DEFAULT_ROWHEIGHT;

    tv->tree.indent = DEFAULT_INDENT;
    if ((objPtr = Ttk_QueryOption(treeLayout, "-rowheight", 0))) {


	(void)Tcl_GetIntFromObj(NULL, objPtr, &tv->tree.rowHeight);
    }







    if ((objPtr = Ttk_QueryOption(treeLayout, "-indent", 0))) {
	(void)Tcl_GetIntFromObj(NULL, objPtr, &tv->tree.indent);
    }

    return treeLayout;
}

/* + TreeviewDoLayout --
 * 	DoLayout() widget hook.  Computes widget layout.
 *
 * Side effects:
 * 	Computes headingArea and treeArea.
 * 	Computes subtree height.
 * 	Invokes scroll callbacks.
 */
static void TreeviewDoLayout(void *clientData)
{
    Treeview *tv = (Treeview *)clientData;
    int visibleRows;


    Ttk_PlaceLayout(tv->core.layout,tv->core.state,Ttk_WinBox(tv->core.tkwin));
    tv->tree.treeArea = Ttk_ClientRegion(tv->core.layout, "treearea");

    ResizeColumns(tv, tv->tree.treeArea.width);

    TtkScrolled(tv->tree.xscrollHandle,
	    tv->tree.xscroll.first,
	    tv->tree.xscroll.first + tv->tree.treeArea.width,
	    TreeWidth(tv));


    if (tv->tree.showFlags & SHOW_HEADINGS) {
	tv->tree.headingArea = Ttk_PackBox(
	    &tv->tree.treeArea, 1, tv->tree.headingHeight, TTK_SIDE_TOP);
    } else {
	tv->tree.headingArea = Ttk_MakeBox(0,0,0,0);
    }

    visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight;
    tv->tree.root->state |= TTK_STATE_OPEN;
    TtkScrolled(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first,
	    tv->tree.yscroll.first + visibleRows,

	    CountRows(tv->tree.root) - 1);









}

/* + TreeviewSize --
 * 	SizeProc() widget hook.  Size is determined by
 * 	-height option and column widths.
 */
static int TreeviewSize(void *clientData, int *widthPtr, int *heightPtr)







|
>
>




|

|



|
>
>









|
|

>
>
>
>
>
>
>
>
>
>
|
>
|

>
>
|
|
>
>
>
>
>
>
>

|

















>






<
|
|
|
>










|
|
|
>
|
>
>
>
>
>
>
>
>
>







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
 */
static Ttk_Layout TreeviewGetLayout(
    Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Layout treeLayout = TtkWidgetGetLayout(interp, themePtr, recordPtr);
    Tcl_Obj *objPtr;
    int unused, cellHeight;
    DisplayItem displayItem;
    Ttk_Style style;

    if (!(
	treeLayout
     && GetSublayout(interp, themePtr, treeLayout, ".Item",
	    tv->tree.displayOptionTable, &tv->tree.itemLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Cell",
	    tv->tree.displayOptionTable, &tv->tree.cellLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Heading",
	    tv->tree.headingOptionTable, &tv->tree.headingLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Row",
	    tv->tree.displayOptionTable, &tv->tree.rowLayout)
     && GetSublayout(interp, themePtr, treeLayout, ".Separator",
	    tv->tree.displayOptionTable, &tv->tree.separatorLayout)
    )) {
	return 0;
    }

    /* Compute heading height.
     */
    Ttk_RebindSublayout(tv->tree.headingLayout, &tv->tree.column0);
    Ttk_LayoutSize(tv->tree.headingLayout, 0, &unused, &tv->tree.headingHeight);

    /* Get row height from style, or compute it to fit Item and Cell.
     * Pick up default font from the Treeview style.
     */
    style = Ttk_LayoutStyle(treeLayout);
    Ttk_TagSetDefaults(tv->tree.tagTable, style, &displayItem);

    Ttk_RebindSublayout(tv->tree.itemLayout, &displayItem);
    Ttk_LayoutSize(tv->tree.itemLayout, 0, &unused, &tv->tree.rowHeight);

    Ttk_RebindSublayout(tv->tree.cellLayout, &displayItem);
    Ttk_LayoutSize(tv->tree.cellLayout, 0, &unused, &cellHeight);

    if (cellHeight > tv->tree.rowHeight) {
	tv->tree.rowHeight = cellHeight;
    }

    if ((objPtr = Ttk_QueryOption(treeLayout, "-rowheight", 0))) {
	(void)Tk_GetPixelsFromObj(NULL, tv->core.tkwin, objPtr, &tv->tree.rowHeight);
    }
    tv->tree.rowHeight = MAX(tv->tree.rowHeight, 1);

    if ((objPtr = Ttk_QueryOption(treeLayout, "-columnseparatorwidth", 0))) {
	(void)Tk_GetPixelsFromObj(NULL, tv->core.tkwin, objPtr, &tv->tree.colSeparatorWidth);
    }

    /* Get item indent from style:
     */
    tv->tree.indent = DEFAULT_INDENT;
    if ((objPtr = Ttk_QueryOption(treeLayout, "-indent", 0))) {
	(void)Tk_GetPixelsFromObj(NULL, tv->core.tkwin, objPtr, &tv->tree.indent);
    }

    return treeLayout;
}

/* + TreeviewDoLayout --
 * 	DoLayout() widget hook.  Computes widget layout.
 *
 * Side effects:
 * 	Computes headingArea and treeArea.
 * 	Computes subtree height.
 * 	Invokes scroll callbacks.
 */
static void TreeviewDoLayout(void *clientData)
{
    Treeview *tv = (Treeview *)clientData;
    int visibleRows;
    int first, last, total;

    Ttk_PlaceLayout(tv->core.layout,tv->core.state,Ttk_WinBox(tv->core.tkwin));
    tv->tree.treeArea = Ttk_ClientRegion(tv->core.layout, "treearea");

    ResizeColumns(tv, tv->tree.treeArea.width);


    first = tv->tree.xscroll.first;
    last = first + tv->tree.treeArea.width - tv->tree.titleWidth;
    total = TreeWidth(tv) - tv->tree.titleWidth;
    TtkScrolled(tv->tree.xscrollHandle, first, last, total);

    if (tv->tree.showFlags & SHOW_HEADINGS) {
	tv->tree.headingArea = Ttk_PackBox(
	    &tv->tree.treeArea, 1, tv->tree.headingHeight, TTK_SIDE_TOP);
    } else {
	tv->tree.headingArea = Ttk_MakeBox(0,0,0,0);
    }

    visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight;
    tv->tree.root->state |= TTK_STATE_OPEN;
    UpdatePositionTree(tv);
    first = tv->tree.yscroll.first;
    last = tv->tree.yscroll.first + visibleRows - tv->tree.titleRows;
    total = tv->tree.totalRows - tv->tree.titleRows;
    if (tv->tree.treeArea.height % tv->tree.rowHeight) {
        /* When the treeview height doesn't correspond to an exact number
         * of rows, the last row count must be incremented to draw a
         * partial row at the bottom. The total row count must also be
         * incremented to be able to scroll all the way to the bottom.
         */
        last++;
        total++;
    }
    TtkScrolled(tv->tree.yscrollHandle, first, last, total);
}

/* + TreeviewSize --
 * 	SizeProc() widget hook.  Size is determined by
 * 	-height option and column widths.
 */
static int TreeviewSize(void *clientData, int *widthPtr, int *heightPtr)
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
}

/* + DrawHeadings --
 *	Draw tree headings.
 */
static void DrawHeadings(Treeview *tv, Drawable d)
{
    const int x0 = tv->tree.headingArea.x - tv->tree.xscroll.first;
    const int y0 = tv->tree.headingArea.y;
    const int h0 = tv->tree.headingArea.height;
    int i = FirstColumn(tv);
    int x = 0;






    while (i < tv->tree.nDisplayColumns) {
	TreeColumn *column = tv->tree.displayColumns[i];
	Ttk_Box parcel = Ttk_MakeBox(x0+x, y0, column->width, h0);

	DisplayLayout(tv->tree.headingLayout,
	    column, column->headingState, parcel, d);

	x += column->width;
	++i;
    }
}






























































/* + PrepareItem --
 * 	Fill in a displayItem record.
 */
static void PrepareItem(
    Treeview *tv, TreeItem *item, DisplayItem *displayItem)
{
    Ttk_Style style = Ttk_LayoutStyle(tv->core.layout);
    Ttk_State state = ItemState(tv, item);



    Ttk_TagSetValues(tv->tree.tagTable, item->tagset, displayItem);

    Ttk_TagSetApplyStyle(tv->tree.tagTable, style, state, displayItem);
}







































/* + DrawCells --
 *	Draw data cells for specified item.
 */
static void DrawCells(
    Treeview *tv, TreeItem *item, DisplayItem *displayItem,

    Drawable d, int x, int y)
{
    Ttk_Layout layout = tv->tree.cellLayout;

    Ttk_State state = ItemState(tv, item);
    Ttk_Padding cellPadding = {4, 0, 4, 0};


    int rowHeight = tv->tree.rowHeight;
    int nValues = 0;
    Tcl_Obj **values = 0;
    int i;

    if (!item->valuesObj) {

	return;
    }









    Tcl_ListObjGetElements(NULL, item->valuesObj, &nValues, &values);

    for (i = 0; i < tv->tree.nColumns; ++i) {
	tv->tree.columns[i].data = (i < nValues) ? values[i] : 0;

    }

    for (i = 1; i < tv->tree.nDisplayColumns; ++i) {
	TreeColumn *column = tv->tree.displayColumns[i];



	Ttk_Box parcel = Ttk_PadBox(





	    Ttk_MakeBox(x, y, column->width, rowHeight), cellPadding);



















	displayItem->textObj = column->data;
	displayItem->anchorObj = column->anchorObj;	/* <<NOTE-ANCHOR>> */











	DisplayLayout(layout, displayItem, state, parcel, d);

	x += column->width;







    }
}

/* + DrawItem --
 * 	Draw an item (row background, tree label, and cells).
 */
static void DrawItem(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{

    Ttk_State state = ItemState(tv, item);
    DisplayItem displayItem;
    int rowHeight = tv->tree.rowHeight;
    int x = tv->tree.treeArea.x - tv->tree.xscroll.first;


    int y = tv->tree.treeArea.y + rowHeight * (row - tv->tree.yscroll.first);

    if (row % 2) state |= TTK_STATE_ALTERNATE;

    PrepareItem(tv, item, &displayItem);

    /* Draw row background:
     */
    {
	Ttk_Box rowBox = Ttk_MakeBox(x, y, TreeWidth(tv), rowHeight);
	DisplayLayout(tv->tree.rowLayout, &displayItem, state, rowBox, d);
    }

    /* Draw tree label:
     */
    if (tv->tree.showFlags & SHOW_TREE) {
	int indent = depth * tv->tree.indent;
	int colwidth = tv->tree.column0.width;
	Ttk_Box parcel = Ttk_MakeBox(
		x+indent, y, colwidth-indent, rowHeight);
	if (item->textObj) { displayItem.textObj = item->textObj; }
	if (item->imageObj) { displayItem.imageObj = item->imageObj; }
        displayItem.anchorObj = tv->tree.column0.anchorObj;
	DisplayLayout(tv->tree.itemLayout, &displayItem, state, parcel, d);
	x += colwidth;
    }

    /* Draw data cells:
     */

    DrawCells(tv, item, &displayItem, d, x, y);
}







/* + DrawSubtree --














 * 	Draw an item and all of its (viewable) descendants.




 *









 * Returns:














 * 	Row number of the last item drawn.




















 */

static int DrawForest(	/* forward */
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row);

static int DrawSubtree(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{

    if (row >= tv->tree.yscroll.first) {
	DrawItem(tv, item, d, depth, row);
    }

    if (item->state & TTK_STATE_OPEN) {
	return DrawForest(tv, item->children, d, depth + 1, row + 1);
    } else {
	return row + 1;
    }
}

/* + DrawForest --
 * 	Draw a sequence of items and their visible descendants.
 *
 * Returns:
 * 	Row number of the last item drawn.
 */
static int DrawForest(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{
    while (item && row < tv->tree.yscroll.last) {
        row = DrawSubtree(tv, item, d, depth, row);
	item = item->next;
    }
    return row;
}

/* + TreeviewDisplay --
 * 	Display() widget hook.  Draw the widget contents.
 */
static void TreeviewDisplay(void *clientData, Drawable d)
{
    Treeview *tv = (Treeview *)clientData;

    Ttk_DrawLayout(tv->core.layout, tv->core.state, d);
    if (tv->tree.showFlags & SHOW_HEADINGS) {
	DrawHeadings(tv, d);
    }
    DrawForest(tv, tv->tree.root->children, d, 0,0);

}

/*------------------------------------------------------------------------
 * +++ Utilities for widget commands
 */

/* + InsertPosition --







|


|

>
>
>
>
>




>
|
|
>



|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|


<

>
>

>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
>
|


>


>
>
|
|
<
|

|
>
|


>
>
>
>
>
>
>
>
|
>
|
|
>




>
>
>
|
>
>
>
>
>
|
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>

>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>







|

>

|
|

>
>
|

<
|
|








|


<
|
<
<
<
<
<
<
<




>
|
|
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|

|
|

>
|
|



|
<
<





<
<
<

|
|

|
|


<













|
>







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
}

/* + DrawHeadings --
 *	Draw tree headings.
 */
static void DrawHeadings(Treeview *tv, Drawable d)
{
    int x0 = tv->tree.headingArea.x - tv->tree.xscroll.first;
    const int y0 = tv->tree.headingArea.y;
    const int h0 = tv->tree.headingArea.height;
    Tcl_Size i = FirstColumn(tv);
    int x = 0;

    if (tv->tree.nTitleColumns > i) {
	x = tv->tree.titleWidth;
	i = tv->tree.nTitleColumns;
    }

    while (i < tv->tree.nDisplayColumns) {
	TreeColumn *column = tv->tree.displayColumns[i];
	Ttk_Box parcel = Ttk_MakeBox(x0+x, y0, column->width, h0);
	if (x0+x+column->width > tv->tree.titleWidth) {
	    DisplayLayout(tv->tree.headingLayout,
		    column, column->headingState, parcel, d);
	}
	x += column->width;
	++i;
    }

    x0 = tv->tree.headingArea.x;
    i = FirstColumn(tv);
    x = 0;
    while ((i < tv->tree.nTitleColumns) && (i < tv->tree.nDisplayColumns)) {
	TreeColumn *column = tv->tree.displayColumns[i];
	Ttk_Box parcel = Ttk_MakeBox(x0+x, y0, column->width, h0);
	DisplayLayout(tv->tree.headingLayout,
	    column, column->headingState, parcel, d);
	x += column->width;
	++i;
    }
}

/* + DrawSeparators --
 *	Draw separators between columns
 */
static void DrawSeparators(Treeview *tv, Drawable d)
{
    const int y0 = tv->tree.treeArea.y;
    const int h0 = tv->tree.treeArea.height;
    DisplayItem displayItem;
    Ttk_Style style = Ttk_LayoutStyle(tv->tree.separatorLayout);
    int x = tv->tree.treeArea.x;
    Tcl_Size i;

    Ttk_TagSetDefaults(tv->tree.tagTable, style, &displayItem);

    for (i = FirstColumn(tv); i < tv->tree.nDisplayColumns; ++i) {
	TreeColumn *column = tv->tree.displayColumns[i];
	Ttk_Box parcel;
	int xDraw = x + column->width;
	x += column->width;

	if (!column->separator) continue;

	if (i >= tv->tree.nTitleColumns) {
	    xDraw -= tv->tree.xscroll.first;
	    if (xDraw < tv->tree.titleWidth) continue;
	}

	parcel = Ttk_MakeBox(xDraw - (tv->tree.colSeparatorWidth+1)/2, y0,
		tv->tree.colSeparatorWidth, h0);
	DisplayLayout(tv->tree.separatorLayout, &displayItem, 0, parcel, d);
    }
}

/* + OverrideStriped --
 * 	Each level of settings might add stripedbackground, and it should
 * 	override background if this is indeed on a striped item.
 * 	By copying it between each level, and NULL-ing stripedBgObj,
 * 	it can be detected if the next level overrides it.
 */
 static void OverrideStriped(
    Treeview *tv, TreeItem *item, DisplayItem *displayItem)
{
    int striped = item->visiblePos % 2 && tv->tree.striped;
    if (striped && displayItem->stripedBgObj) {
	displayItem->backgroundObj = displayItem->stripedBgObj;
	displayItem->stripedBgObj = NULL;
    }
}

/* + PrepareItem --
 * 	Fill in a displayItem record.
 */
static void PrepareItem(
    Treeview *tv, TreeItem *item, DisplayItem *displayItem, Ttk_State state)
{
    Ttk_Style style = Ttk_LayoutStyle(tv->core.layout);


    Ttk_TagSetDefaults(tv->tree.tagTable, style, displayItem);
    OverrideStriped(tv, item, displayItem);
    Ttk_TagSetValues(tv->tree.tagTable, item->tagset, displayItem);
    OverrideStriped(tv, item, displayItem);
    Ttk_TagSetApplyStyle(tv->tree.tagTable, style, state, displayItem);
}

/* Fill in data from item to temporary storage in columns. */
static void PrepareCells(
   Treeview *tv, TreeItem *item)
{
    Tcl_Size i, nValues = 0;
    Tcl_Obj **values = NULL;
    TreeColumn *column;

    if (item->valuesObj) {
	Tcl_ListObjGetElements(NULL, item->valuesObj, &nValues, &values);
    }
    for (i = 0; i < tv->tree.nColumns; ++i) {
	tv->tree.columns[i].data = (i < nValues) ? values[i] : 0;
	tv->tree.columns[i].selected = 0;
	tv->tree.columns[i].tagset = NULL;
    }
    tv->tree.column0.data = NULL;
    tv->tree.column0.selected = 0;
    tv->tree.column0.tagset = NULL;

    if (item->selObj != NULL) {
	Tcl_ListObjGetElements(NULL, item->selObj, &nValues, &values);
	for (i = 0; i < nValues; ++i) {
	    column = FindColumn(NULL, tv, values[i]);
	    /* Just in case. It should not be possible for column to be NULL */
	    if (column != NULL) {
		column->selected = 1;
	    }
	}
    }
    if (item->nTagSets > 0) {
	tv->tree.column0.tagset = item->cellTagSets[0];
    }
    for (i = 1; i < item->nTagSets && i <= tv->tree.nColumns; ++i) {
	tv->tree.columns[i-1].tagset = item->cellTagSets[i];
    }
}

/* + DrawCells --
 *	Draw data cells for specified item.
 */
static void DrawCells(
    Treeview *tv, TreeItem *item,
    DisplayItem *displayItem, DisplayItem *displayItemSel,
    Drawable d, int x, int y, int title)
{
    Ttk_Layout layout = tv->tree.cellLayout;
    Ttk_Style style = Ttk_LayoutStyle(tv->core.layout);
    Ttk_State state = ItemState(tv, item);
    Ttk_Padding cellPadding = {4, 0, 4, 0};
    DisplayItem displayItemLocal;
    DisplayItem displayItemCell, displayItemCellSel;
    int rowHeight = tv->tree.rowHeight * item->height;
    int xPad = 0, defaultPadding = 1;

    Tcl_Size i;

    /* Adjust if the tree column has a separator */
    if (tv->tree.showFlags & SHOW_TREE && tv->tree.column0.separator) {
	xPad = tv->tree.colSeparatorWidth/2;
    }

    /* An Item's image should not propagate to a Cell.
       A Cell's image can only be set by cell tags. */
    displayItemCell = *displayItem;
    displayItemCellSel = *displayItemSel;
    displayItemCell.imageObj = NULL;
    displayItemCellSel.imageObj = NULL;
    displayItemCell.imageAnchorObj = NULL;
    displayItemCellSel.imageAnchorObj = NULL;

    /* If explicit padding was asked for, skip default. */
    if (Ttk_QueryStyle(Ttk_LayoutStyle(tv->tree.cellLayout), &displayItemCell,
		    tv->tree.displayOptionTable, "-padding", state) != NULL) {
	defaultPadding = 0;
    }

    for (i = 1; i < tv->tree.nDisplayColumns; ++i) {
	TreeColumn *column = tv->tree.displayColumns[i];
	int parcelX = x + xPad;
	int parcelWidth = column->separator ?
		column->width - tv->tree.colSeparatorWidth : column->width;
	Ttk_Box parcel = Ttk_MakeBox(parcelX, y, parcelWidth, rowHeight);
	DisplayItem *displayItemUsed = &displayItemCell;
	Ttk_State stateCell = state;
	Tk_Anchor textAnchor, imageAnchor;
	xPad = column->separator ? tv->tree.colSeparatorWidth/2 : 0;

	x += column->width;
	if (title  && i >= tv->tree.nTitleColumns) break;
	if (!title && i <  tv->tree.nTitleColumns) continue;
	if (!title && x <  tv->tree.titleWidth) continue;

	if (column->selected) {
	    displayItemUsed = &displayItemCellSel;
	    stateCell |= TTK_STATE_SELECTED;
	}

	if (column->tagset) {
	    displayItemLocal = *displayItemUsed;
	    displayItemUsed = &displayItemLocal;
	    Ttk_TagSetValues(tv->tree.tagTable, column->tagset,
		    displayItemUsed);
	    OverrideStriped(tv, item, displayItemUsed);
	    Ttk_TagSetApplyStyle(tv->tree.tagTable, style, stateCell,
		    displayItemUsed);
	}

	displayItemUsed->textObj = column->data;
	displayItemUsed->anchorObj = column->anchorObj;/* <<NOTE-ANCHOR>> */
	Tk_GetAnchorFromObj(NULL, column->anchorObj, &textAnchor);

	imageAnchor = DEFAULT_IMAGEANCHOR;
	if (displayItemUsed->imageAnchorObj) {
	    Tk_GetAnchorFromObj(NULL, displayItemUsed->imageAnchorObj,
		    &imageAnchor);
	}
	/* displayItem was used to draw the full item backgound.
	   Redraw cell background if needed. */
	if (displayItemUsed != &displayItemCell) {
	    DisplayLayout(tv->tree.rowLayout, displayItemUsed, stateCell,
		    parcel, d);
	}

	if (defaultPadding && displayItemUsed->paddingObj == NULL) {
	    /* If no explicit padding was asked for, add some default. */
	    parcel = Ttk_PadBox(parcel, cellPadding);
	}

	DisplayLayoutTree(imageAnchor, textAnchor,
		layout, displayItemUsed, state, parcel, d);
    }
}

/* + DrawItem --
 * 	Draw an item (row background, tree label, and cells).
 */
static void DrawItem(
    Treeview *tv, TreeItem *item, Drawable d, int depth)
{
    Ttk_Style style = Ttk_LayoutStyle(tv->core.layout);
    Ttk_State state = ItemState(tv, item);
    DisplayItem displayItem, displayItemSel, displayItemLocal;
    int rowHeight = tv->tree.rowHeight * item->height;
    int x = tv->tree.treeArea.x - tv->tree.xscroll.first;
    int xTitle = tv->tree.treeArea.x;
    int dispRow = DisplayRow(item->rowPos, tv);
    int y = tv->tree.treeArea.y + tv->tree.rowHeight * dispRow;


    PrepareItem(tv, item, &displayItem, state);
    PrepareItem(tv, item, &displayItemSel, state | TTK_STATE_SELECTED);

    /* Draw row background:
     */
    {
	Ttk_Box rowBox = Ttk_MakeBox(x, y, TreeWidth(tv), rowHeight);
	DisplayLayout(tv->tree.rowLayout, &displayItem, state, rowBox, d);
    }

    /* Make room for tree label:
     */
    if (tv->tree.showFlags & SHOW_TREE) {

	x += tv->tree.column0.width;







    }

    /* Draw data cells:
     */
    PrepareCells(tv, item);
    DrawCells(tv, item, &displayItem, &displayItemSel, d, x, y, 0);

    /* Draw row background for non-scrolled area:
     */
    if (tv->tree.nTitleColumns >= 1) {
	Ttk_Box rowBox = Ttk_MakeBox(tv->tree.treeArea.x, y,
		tv->tree.titleWidth, rowHeight);
	DisplayLayout(tv->tree.rowLayout, &displayItem, state, rowBox, d);
    }

    /* Draw tree label:
     */
    x = tv->tree.treeArea.x - tv->tree.xscroll.first;
    if (tv->tree.showFlags & SHOW_TREE) {
	TreeColumn *column = &tv->tree.column0;
	int indent = depth * tv->tree.indent;
	int colwidth = tv->tree.column0.width -
		(tv->tree.column0.separator ? tv->tree.colSeparatorWidth/2 : 0);
	int xTree = tv->tree.nTitleColumns >= 1 ? xTitle : x;
	Ttk_Box parcel = Ttk_MakeBox(xTree, y, colwidth, rowHeight);
	DisplayItem *displayItemUsed = &displayItem;
	Ttk_State stateCell = state;
	Tk_Anchor textAnchor, imageAnchor = DEFAULT_IMAGEANCHOR;
	Ttk_Padding cellPadding = {(short)indent, 0, 0, 0};

	if (column->selected) {
	    displayItemUsed = &displayItemSel;
 	    stateCell |= TTK_STATE_SELECTED;
	}

	if (column->tagset) {
	    displayItemLocal = *displayItemUsed;
	    displayItemUsed = &displayItemLocal;
	    Ttk_TagSetValues(tv->tree.tagTable, column->tagset,
		    displayItemUsed);
	    OverrideStriped(tv, item, displayItemUsed);
	    Ttk_TagSetApplyStyle(tv->tree.tagTable, style, stateCell,
		    displayItemUsed);
	}

        displayItem.anchorObj = tv->tree.column0.anchorObj;
	Tk_GetAnchorFromObj(NULL, column->anchorObj, &textAnchor);
	displayItemUsed->textObj = item->textObj;
	/* Item's image can be null, and may come from the tag */
	if (item->imageObj) {
	    displayItemUsed->imageObj = item->imageObj;
	}
	if (item->imageAnchorObj) {
	    displayItemUsed->imageAnchorObj = item->imageAnchorObj;
	}
	if (displayItemUsed->imageAnchorObj) {
	    Tk_GetAnchorFromObj(NULL, displayItemUsed->imageAnchorObj,
		    &imageAnchor);
	}

	if (displayItemUsed != &displayItem) {
	    DisplayLayout(tv->tree.rowLayout, displayItemUsed, stateCell,
		    parcel, d);
	}

	parcel = Ttk_PadBox(parcel, cellPadding);
	DisplayLayoutTree(imageAnchor, textAnchor,
		tv->tree.itemLayout, displayItemUsed, state, parcel, d);
	xTitle += colwidth;
    }

    /* Draw non-scrolled data cells:
     */
    if (tv->tree.nTitleColumns > 1) {
	DrawCells(tv, item, &displayItem, &displayItemSel, d, xTitle, y, 1);
    }
}

/* + DrawSubtree --
 * 	Draw an item and all of its (viewable) descendants.
 */

static void DrawForest(	/* forward */
    Treeview *tv, TreeItem *item, Drawable d, int depth);

static void DrawSubtree(
    Treeview *tv, TreeItem *item, Drawable d, int depth)
{
    int dispRow = DisplayRow(item->rowPos, tv);
    if (dispRow >= 0) {
	DrawItem(tv, item, d, depth);
    }

    if (item->state & TTK_STATE_OPEN) {
	DrawForest(tv, item->children, d, depth + 1);


    }
}

/* + DrawForest --
 * 	Draw a sequence of items and their visible descendants.



 */
static void DrawForest(
    Treeview *tv, TreeItem *item, Drawable d, int depth)
{
    while (item) {
        DrawSubtree(tv, item, d, depth);
	item = item->next;
    }

}

/* + TreeviewDisplay --
 * 	Display() widget hook.  Draw the widget contents.
 */
static void TreeviewDisplay(void *clientData, Drawable d)
{
    Treeview *tv = (Treeview *)clientData;

    Ttk_DrawLayout(tv->core.layout, tv->core.state, d);
    if (tv->tree.showFlags & SHOW_HEADINGS) {
	DrawHeadings(tv, d);
    }
    DrawForest(tv, tv->tree.root->children, d, 0);
    DrawSeparators(tv, d);
}

/*------------------------------------------------------------------------
 * +++ Utilities for widget commands
 */

/* + InsertPosition --
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
 * +++ Widget commands -- item inquiry.
 */

/* + $tv children $item ?newchildren? --
 * 	Return the list of children associated with $item
 */
static int TreeviewChildrenCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;
    Tcl_Obj *result;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?newchildren?");







|







2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
 * +++ Widget commands -- item inquiry.
 */

/* + $tv children $item ?newchildren? --
 * 	Return the list of children associated with $item
 */
static int TreeviewChildrenCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;
    Tcl_Obj *result;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?newchildren?");
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
	int i;

	if (!newChildren)
	    return TCL_ERROR;

	/* Sanity-check:
	 */
	for (i=0; newChildren[i]; ++i) {
	    if (!AncestryCheck(interp, tv, newChildren[i], item)) {
		ckfree(newChildren);
		return TCL_ERROR;
	    }
	}

	/* Detach old children:
	 */
	child = item->children;
	while (child) {
	    TreeItem *next = child->next;
	    DetachItem(child);
	    child = next;
	}

	/* Detach new children from their current locations:
	 */
	for (i=0; newChildren[i]; ++i) {
	    DetachItem(newChildren[i]);
	}

	/* Reinsert new children:
	 * Note: it is not an error for an item to be listed more than once,
	 * though it probably should be...
	 */
	child = 0;
	for (i=0; newChildren[i]; ++i) {
	    if (newChildren[i]->parent) {
		/* This is a duplicate element which has already been
		 * inserted.  Ignore it.
		 */
		continue;
	    }
	    InsertItem(item, child, newChildren[i]);
	    child = newChildren[i];
	}

	ckfree(newChildren);

	TtkRedisplayWidget(&tv->core);
    }

    return TCL_OK;
}

/* + $tv parent $item --
 * 	Return the item ID of $item's parent.
 */
static int TreeviewParentCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;







|

















|








|











>










|







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
	int i;

	if (!newChildren)
	    return TCL_ERROR;

	/* Sanity-check:
	 */
	for (i = 0; newChildren[i]; ++i) {
	    if (!AncestryCheck(interp, tv, newChildren[i], item)) {
		ckfree(newChildren);
		return TCL_ERROR;
	    }
	}

	/* Detach old children:
	 */
	child = item->children;
	while (child) {
	    TreeItem *next = child->next;
	    DetachItem(child);
	    child = next;
	}

	/* Detach new children from their current locations:
	 */
	for (i = 0; newChildren[i]; ++i) {
	    DetachItem(newChildren[i]);
	}

	/* Reinsert new children:
	 * Note: it is not an error for an item to be listed more than once,
	 * though it probably should be...
	 */
	child = 0;
	for (i = 0; newChildren[i]; ++i) {
	    if (newChildren[i]->parent) {
		/* This is a duplicate element which has already been
		 * inserted.  Ignore it.
		 */
		continue;
	    }
	    InsertItem(item, child, newChildren[i]);
	    child = newChildren[i];
	}

	ckfree(newChildren);
	tv->tree.rowPosNeedsUpdate = 1;
	TtkRedisplayWidget(&tv->core);
    }

    return TCL_OK;
}

/* + $tv parent $item --
 * 	Return the item ID of $item's parent.
 */
static int TreeviewParentCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
    return TCL_OK;
}

/* + $tv next $item
 * 	Return the ID of $item's next sibling.
 */
static int TreeviewNextCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;







|







2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
    return TCL_OK;
}

/* + $tv next $item
 * 	Return the ID of $item's next sibling.
 */
static int TreeviewNextCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
    return TCL_OK;
}

/* + $tv prev $item
 * 	Return the ID of $item's previous sibling.
 */
static int TreeviewPrevCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;







|







2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
    return TCL_OK;
}

/* + $tv prev $item
 * 	Return the ID of $item's previous sibling.
 */
static int TreeviewPrevCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
    return TCL_OK;
}

/* + $tv index $item --
 * 	Return the index of $item within its parent.
 */
static int TreeviewIndexCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;
    TkSizeT index = 0;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    item = FindItem(interp, tv, objv[2]);
    if (!item) {







|



|







2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
    return TCL_OK;
}

/* + $tv index $item --
 * 	Return the index of $item within its parent.
 */
static int TreeviewIndexCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;
    Tcl_Size index = 0;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    item = FindItem(interp, tv, objv[2]);
    if (!item) {
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
    return TCL_OK;
}

/* + $tv exists $itemid --
 * 	Test if the specified item id is present in the tree.
 */
static int TreeviewExistsCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Tcl_HashEntry *entryPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "itemid");
	return TCL_ERROR;
    }

    entryPtr = Tcl_FindHashEntry(&tv->tree.items, Tcl_GetString(objv[2]));
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(entryPtr != 0));
    return TCL_OK;
}

/* + $tv bbox $itemid ?$column? --
 * 	Return bounding box [x y width height] of specified item.
 */
static int TreeviewBBoxCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item = 0;
    TreeColumn *column = 0;
    Ttk_Box bbox;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "itemid ?column");
	return TCL_ERROR;
    }

    item = FindItem(interp, tv, objv[2]);
    if (!item) {
	return TCL_ERROR;
    }
    if (objc >=4 && (column = FindColumn(interp,tv,objv[3])) == NULL) {
	return TCL_ERROR;
    }

    if (BoundingBox(tv, item, column, &bbox)) {
	Tcl_SetObjResult(interp, Ttk_NewBoxObj(bbox));
    }

    return TCL_OK;
}

/* + $tv identify $x $y -- (obsolescent)
 * 	Implements the old, horrible, 2-argument form of [$tv identify].
 *
 * Returns: one of
 * 	heading #n
 * 	cell itemid #n
 * 	item itemid element
 * 	row itemid
 */
static int TreeviewHorribleIdentify(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Treeview *tv)



{
    const char *what = "nothing", *detail = NULL;
    TreeItem *item = 0;
    Tcl_Obj *result;
    int dColumnNumber;
    char dcolbuf[16];
    int x, y, x1;
    (void)objc;

    /* ASSERT: objc == 4 */

    if (Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    dColumnNumber = IdentifyDisplayColumn(tv, x, &x1);
    if (dColumnNumber < 0) {
	goto done;
    }
    sprintf(dcolbuf, "#%d", dColumnNumber);

    if (Ttk_BoxContains(tv->tree.headingArea,x,y)) {
	if (-HALO <= x1 - x  && x1 - x <= HALO) {
	    what = "separator";
	} else {
	    what = "heading";
	}
	detail = dcolbuf;
    } else if (Ttk_BoxContains(tv->tree.treeArea,x,y)) {
	item = IdentifyItem(tv, y);
	if (item && dColumnNumber > 0) {
	    what = "cell";
	    detail = dcolbuf;
	} else if (item) {
	    Ttk_Layout layout = tv->tree.itemLayout;
	    Ttk_Box itemBox;
	    DisplayItem displayItem;
	    Ttk_Element element;


	    BoundingBox(tv, item, NULL, &itemBox);
	    PrepareItem(tv, item, &displayItem);
            if (item->textObj) { displayItem.textObj = item->textObj; }
            if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	    Ttk_RebindSublayout(layout, &displayItem);
	    Ttk_PlaceLayout(layout, ItemState(tv,item), itemBox);
	    element = Ttk_IdentifyElement(layout, x, y);

	    if (element) {
		what = "item";
		detail = Ttk_ElementName(element);
	    } else {
		what = "row";







|


















|















|




















|
>
>
>




|
|

<












|


















>


|



|







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
    return TCL_OK;
}

/* + $tv exists $itemid --
 * 	Test if the specified item id is present in the tree.
 */
static int TreeviewExistsCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Tcl_HashEntry *entryPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "itemid");
	return TCL_ERROR;
    }

    entryPtr = Tcl_FindHashEntry(&tv->tree.items, Tcl_GetString(objv[2]));
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(entryPtr != 0));
    return TCL_OK;
}

/* + $tv bbox $itemid ?$column? --
 * 	Return bounding box [x y width height] of specified item.
 */
static int TreeviewBBoxCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item = 0;
    TreeColumn *column = 0;
    Ttk_Box bbox;

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "itemid ?column");
	return TCL_ERROR;
    }

    item = FindItem(interp, tv, objv[2]);
    if (!item) {
	return TCL_ERROR;
    }
    if (objc >= 4 && (column = FindColumn(interp,tv,objv[3])) == NULL) {
	return TCL_ERROR;
    }

    if (BoundingBox(tv, item, column, &bbox)) {
	Tcl_SetObjResult(interp, Ttk_NewBoxObj(bbox));
    }

    return TCL_OK;
}

/* + $tv identify $x $y -- (obsolescent)
 * 	Implements the old, horrible, 2-argument form of [$tv identify].
 *
 * Returns: one of
 * 	heading #n
 * 	cell itemid #n
 * 	item itemid element
 * 	row itemid
 */
static int TreeviewHorribleIdentify(
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Size), /* objc */
    Tcl_Obj *const objv[],
    Treeview *tv)
{
    const char *what = "nothing", *detail = NULL;
    TreeItem *item = 0;
    Tcl_Obj *result;
    Tcl_Size dColumnNumber;
    char dcolbuf[32];
    int x, y, x1;


    /* ASSERT: objc == 4 */

    if (Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    dColumnNumber = IdentifyDisplayColumn(tv, x, &x1);
    if (dColumnNumber < 0) {
	goto done;
    }
    snprintf(dcolbuf, sizeof(dcolbuf), "#%" TCL_SIZE_MODIFIER "d", dColumnNumber);

    if (Ttk_BoxContains(tv->tree.headingArea,x,y)) {
	if (-HALO <= x1 - x  && x1 - x <= HALO) {
	    what = "separator";
	} else {
	    what = "heading";
	}
	detail = dcolbuf;
    } else if (Ttk_BoxContains(tv->tree.treeArea,x,y)) {
	item = IdentifyItem(tv, y);
	if (item && dColumnNumber > 0) {
	    what = "cell";
	    detail = dcolbuf;
	} else if (item) {
	    Ttk_Layout layout = tv->tree.itemLayout;
	    Ttk_Box itemBox;
	    DisplayItem displayItem;
	    Ttk_Element element;
	    Ttk_State state = ItemState(tv, item);

	    BoundingBox(tv, item, NULL, &itemBox);
	    PrepareItem(tv, item, &displayItem, state);
            if (item->textObj) { displayItem.textObj = item->textObj; }
            if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	    Ttk_RebindSublayout(layout, &displayItem);
	    Ttk_PlaceLayout(layout, state, itemBox);
	    element = Ttk_IdentifyElement(layout, x, y);

	    if (element) {
		what = "item";
		detail = Ttk_ElementName(element);
	    } else {
		what = "row";
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
}

/* + $tv identify $component $x $y --
 * 	Identify the component at position x,y.
 */

static int TreeviewIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    static const char *const submethodStrings[] =
	 { "region", "item", "column", "row", "element", NULL };
    enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT };

    Treeview *tv = (Treeview *)recordPtr;
    int submethod;
    int x, y;

    TreeRegion region;
    Ttk_Box bbox;
    TreeItem *item;
    TreeColumn *column = 0;
    int colno, x1;


    if (objc == 4) {	/* Old form */
	return TreeviewHorribleIdentify(interp, objc, objv, tv);
    } else if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "command x y");
	return TCL_ERROR;
    }







|


|
|









|
>







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
}

/* + $tv identify $component $x $y --
 * 	Identify the component at position x,y.
 */

static int TreeviewIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    static const char *const submethodStrings[] =
	 { "region", "item", "column", "row", "element", "cell", NULL };
    enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT, I_CELL };

    Treeview *tv = (Treeview *)recordPtr;
    int submethod;
    int x, y;

    TreeRegion region;
    Ttk_Box bbox;
    TreeItem *item;
    TreeColumn *column = 0;
    Tcl_Size colno;
    int x1;

    if (objc == 4) {	/* Old form */
	return TreeviewHorribleIdentify(interp, objc, objv, tv);
    } else if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "command x y");
	return TCL_ERROR;
    }
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
	    if (item) {
		Tcl_SetObjResult(interp, ItemID(tv, item));
	    }
	    break;

	case I_COLUMN :
	    if (colno >= 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf("#%d", colno));









	    }
	    break;

	case I_ELEMENT :
	{
	    Ttk_Layout layout = 0;
	    DisplayItem displayItem;
	    Ttk_Element element;


	    switch (region) {
		case REGION_NOTHING:
		    layout = tv->core.layout;
		    return TCL_OK; /* @@@ NYI */
		case REGION_HEADING:
		case REGION_SEPARATOR:
		    layout = tv->tree.headingLayout;
		    return TCL_OK; /* @@@ NYI */
		case REGION_TREE:
		    layout = tv->tree.itemLayout;
		    break;
		case REGION_CELL:
		    layout = tv->tree.cellLayout;
		    break;
	    }




	    if (!BoundingBox(tv, item, column, &bbox)) {
		return TCL_OK;
	    }

	    PrepareItem(tv, item, &displayItem);
            if (item->textObj) { displayItem.textObj = item->textObj; }
            if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	    Ttk_RebindSublayout(layout, &displayItem);
	    Ttk_PlaceLayout(layout, ItemState(tv,item), bbox);
	    element = Ttk_IdentifyElement(layout, x, y);

	    if (element) {
		const char *elementName = Ttk_ElementName(element);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
	    }
	    break;
	}
    }
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- item and column configuration.
 */

/* + $tv item $item ?options ....?
 * 	Query or configure item options.
 */
static int TreeviewItemCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?-option ?value??...");
	return TCL_ERROR;







|
>
>
>
>
>
>
>
>
>








>

















>
>
>



|
|



|




















|







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
	    if (item) {
		Tcl_SetObjResult(interp, ItemID(tv, item));
	    }
	    break;

	case I_COLUMN :
	    if (colno >= 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf("#%" TCL_SIZE_MODIFIER "d", colno));
	    }
	    break;

	case I_CELL :
	    if (item && colno >= 0) {
		Tcl_Obj *elem[2];
		elem[0] = ItemID(tv, item);
		elem[1] = Tcl_ObjPrintf("#%" TCL_SIZE_MODIFIER "d", colno);
		Tcl_SetObjResult(interp, Tcl_NewListObj(2, elem));
	    }
	    break;

	case I_ELEMENT :
	{
	    Ttk_Layout layout = 0;
	    DisplayItem displayItem;
	    Ttk_Element element;
	    Ttk_State state;

	    switch (region) {
		case REGION_NOTHING:
		    layout = tv->core.layout;
		    return TCL_OK; /* @@@ NYI */
		case REGION_HEADING:
		case REGION_SEPARATOR:
		    layout = tv->tree.headingLayout;
		    return TCL_OK; /* @@@ NYI */
		case REGION_TREE:
		    layout = tv->tree.itemLayout;
		    break;
		case REGION_CELL:
		    layout = tv->tree.cellLayout;
		    break;
	    }

	    if (item == NULL) {
		return TCL_OK;
	    }
	    if (!BoundingBox(tv, item, column, &bbox)) {
		return TCL_OK;
	    }
	    state = ItemState(tv, item);
	    PrepareItem(tv, item, &displayItem, state);
            if (item->textObj) { displayItem.textObj = item->textObj; }
            if (item->imageObj) { displayItem.imageObj = item->imageObj; }
	    Ttk_RebindSublayout(layout, &displayItem);
	    Ttk_PlaceLayout(layout, state, bbox);
	    element = Ttk_IdentifyElement(layout, x, y);

	    if (element) {
		const char *elementName = Ttk_ElementName(element);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
	    }
	    break;
	}
    }
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- item and column configuration.
 */

/* + $tv item $item ?options ....?
 * 	Query or configure item options.
 */
static int TreeviewItemCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?-option ?value??...");
	return TCL_ERROR;
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
    }
}

/* + $tv column column ?options ....?
 * 	Column data accessor
 */
static int TreeviewColumnCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeColumn *column;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "column -option value...");
	return TCL_ERROR;







|







2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
    }
}

/* + $tv column column ?options ....?
 * 	Column data accessor
 */
static int TreeviewColumnCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeColumn *column;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "column -option value...");
	return TCL_ERROR;
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
    }
}

/* + $tv heading column ?options ....?
 * 	Heading data accessor
 */
static int TreeviewHeadingCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Tk_OptionTable optionTable = tv->tree.headingOptionTable;
    Tk_Window tkwin = tv->core.tkwin;
    TreeColumn *column;

    if (objc < 3) {







|







3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
    }
}

/* + $tv heading column ?options ....?
 * 	Heading data accessor
 */
static int TreeviewHeadingCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Tk_OptionTable optionTable = tv->tree.headingOptionTable;
    Tk_Window tkwin = tv->core.tkwin;
    TreeColumn *column;

    if (objc < 3) {
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
    }
}

/* + $tv set $item ?$column ?value??
 * 	Query or configure cell values
 */
static int TreeviewSetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;
    TreeColumn *column;
    int columnNumber;

    if (objc < 3 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?column ?value??");
	return TCL_ERROR;
    }
    if (!(item = FindItem(interp, tv, objv[2])))
	return TCL_ERROR;

    /* Make sure -values exists:
     */
    if (!item->valuesObj) {
	item->valuesObj = Tcl_NewListObj(0,0);
	Tcl_IncrRefCount(item->valuesObj);
    }

    if (objc == 3) {
	/* Return dictionary:
	 */
	Tcl_Obj *result = Tcl_NewListObj(0,0);
	Tcl_Obj *value;
	for (columnNumber=0; columnNumber<tv->tree.nColumns; ++columnNumber) {
	    Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &value);
	    if (value) {
		Tcl_ListObjAppendElement(NULL, result,
			tv->tree.columns[columnNumber].idObj);
		Tcl_ListObjAppendElement(NULL, result, value);
	    }
	}







|




|




















|







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
    }
}

/* + $tv set $item ?$column ?value??
 * 	Query or configure cell values
 */
static int TreeviewSetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;
    TreeColumn *column;
    Tcl_Size columnNumber;

    if (objc < 3 || objc > 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "item ?column ?value??");
	return TCL_ERROR;
    }
    if (!(item = FindItem(interp, tv, objv[2])))
	return TCL_ERROR;

    /* Make sure -values exists:
     */
    if (!item->valuesObj) {
	item->valuesObj = Tcl_NewListObj(0,0);
	Tcl_IncrRefCount(item->valuesObj);
    }

    if (objc == 3) {
	/* Return dictionary:
	 */
	Tcl_Obj *result = Tcl_NewListObj(0,0);
	Tcl_Obj *value;
	for (columnNumber = 0; columnNumber < tv->tree.nColumns; ++columnNumber) {
	    Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &value);
	    if (value) {
		Tcl_ListObjAppendElement(NULL, result,
			tv->tree.columns[columnNumber].idObj);
		Tcl_ListObjAppendElement(NULL, result, value);
	    }
	}
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
	Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &result);
	if (!result) {
	    result = Tcl_NewStringObj("",0);
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else {		/* set column */
	int length;

	item->valuesObj = unshareObj(item->valuesObj);

	/* Make sure -values is fully populated:
	 */
	Tcl_ListObjLength(interp, item->valuesObj, &length);
	while (length < tv->tree.nColumns) {







|







3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
	Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &result);
	if (!result) {
	    result = Tcl_NewStringObj("",0);
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else {		/* set column */
	Tcl_Size length;

	item->valuesObj = unshareObj(item->valuesObj);

	/* Make sure -values is fully populated:
	 */
	Tcl_ListObjLength(interp, item->valuesObj, &length);
	while (length < tv->tree.nColumns) {
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
 * +++ Widget commands -- tree modification.
 */

/* + $tv insert $parent $index ?-id id? ?-option value ...?
 * 	Insert a new item.
 */
static int TreeviewInsertCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *parent, *sibling, *newItem;
    Tcl_HashEntry *entryPtr;
    int isNew;

    if (objc < 4) {







|







3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
 * +++ Widget commands -- tree modification.
 */

/* + $tv insert $parent $index ?-id id? ?-option value ...?
 * 	Insert a new item.
 */
static int TreeviewInsertCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *parent, *sibling, *newItem;
    Tcl_HashEntry *entryPtr;
    int isNew;

    if (objc < 4) {
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
	    return TCL_ERROR;
	}
	objc -= 2; objv += 2;
    } else {
	char idbuf[16];
	do {
	    ++tv->tree.serial;
	    sprintf(idbuf, "I%03X", tv->tree.serial);
	    entryPtr = Tcl_CreateHashEntry(&tv->tree.items, idbuf, &isNew);
	} while (!isNew);
    }

    /* Create and configure new item:
     */
    newItem = NewItem();
    Tk_InitOptions(
	interp, (ClientData)newItem, tv->tree.itemOptionTable, tv->core.tkwin);
    newItem->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    if (ConfigureItem(interp, tv, newItem, objc, objv) != TCL_OK) {
    	Tcl_DeleteHashEntry(entryPtr);
	FreeItem(newItem);
	return TCL_ERROR;
    }

    /* Store in hash table, link into tree:
     */
    Tcl_SetHashValue(entryPtr, newItem);
    newItem->entryPtr = entryPtr;
    InsertItem(parent, sibling, newItem);

    TtkRedisplayWidget(&tv->core);

    Tcl_SetObjResult(interp, ItemID(tv, newItem));
    return TCL_OK;
}

/* + $tv detach $item --
 * 	Unlink $item from the tree.
 */
static int TreeviewDetachCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem **items;
    int i;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    if (!(items = GetItemListFromObj(interp, tv, objv[2]))) {
	return TCL_ERROR;







|








|












>






|
|


|



|







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
	    return TCL_ERROR;
	}
	objc -= 2; objv += 2;
    } else {
	char idbuf[16];
	do {
	    ++tv->tree.serial;
	    snprintf(idbuf, sizeof(idbuf), "I%03X", tv->tree.serial);
	    entryPtr = Tcl_CreateHashEntry(&tv->tree.items, idbuf, &isNew);
	} while (!isNew);
    }

    /* Create and configure new item:
     */
    newItem = NewItem();
    Tk_InitOptions(
	interp, newItem, tv->tree.itemOptionTable, tv->core.tkwin);
    newItem->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    if (ConfigureItem(interp, tv, newItem, objc, objv) != TCL_OK) {
    	Tcl_DeleteHashEntry(entryPtr);
	FreeItem(newItem);
	return TCL_ERROR;
    }

    /* Store in hash table, link into tree:
     */
    Tcl_SetHashValue(entryPtr, newItem);
    newItem->entryPtr = entryPtr;
    InsertItem(parent, sibling, newItem);
    tv->tree.rowPosNeedsUpdate = 1;
    TtkRedisplayWidget(&tv->core);

    Tcl_SetObjResult(interp, ItemID(tv, newItem));
    return TCL_OK;
}

/* + $tv detach $items --
 * 	Unlink each item in $items from the tree.
 */
static int TreeviewDetachCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem **items;
    Tcl_Size i;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    if (!(items = GetItemListFromObj(interp, tv, objv[2]))) {
	return TCL_ERROR;
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
	}
    }

    for (i = 0; items[i]; ++i) {
	DetachItem(items[i]);
    }


    TtkRedisplayWidget(&tv->core);
    ckfree(items);
    return TCL_OK;
}













































/* + $tv delete $items --
 * 	Delete each item in $items.
 *
 * 	Do this in two passes:
 * 	First detach the item and all its descendants and remove them
 * 	from the hash table.  Free the items themselves in a second pass.
 *
 * 	It's done this way because an item may appear more than once
 *	in the list of items to delete (either directly or as a descendant
 *	of a previously deleted item.)
 */

static int TreeviewDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem **items, *delq;

    int i, selItemDeleted = 0;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "items");
	return TCL_ERROR;
    }

    if (!(items = GetItemListFromObj(interp, tv, objv[2]))) {
	return TCL_ERROR;
    }

    /* Sanity-check:
     */
    for (i=0; items[i]; ++i) {
	if (items[i] == tv->tree.root) {
	    ckfree(items);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Cannot delete root item", -1));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "ROOT", NULL);
	    return TCL_ERROR;
	}
    }

    /* Remove items from hash table.
     */
    delq = 0;
    for (i=0; items[i]; ++i) {
        if (items[i]->state & TTK_STATE_SELECTED) {
            selItemDeleted = 1;





        }

	delq = DeleteItems(items[i], delq);
    }

    /* Free items:
     */
    while (delq) {
	TreeItem *next = delq->next;
	if (tv->tree.focus == delq)
	    tv->tree.focus = 0;
	if (tv->tree.endPtr == delq)
	    tv->tree.endPtr = 0;
	FreeItem(delq);
	delq = next;
    }

    ckfree(items);
    if (selItemDeleted) {
        Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }

    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/* + $tv move $item $parent $index
 * 	Move $item to the specified $index in $parent's child list.
 */
static int TreeviewMoveCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item, *parent;
    TreeItem *sibling;

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "item parent index");







>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|



>
|












|












|

|
>
>
>
>
>
|
>
















|


>








|







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
	}
    }

    for (i = 0; items[i]; ++i) {
	DetachItem(items[i]);
    }

    tv->tree.rowPosNeedsUpdate = 1;
    TtkRedisplayWidget(&tv->core);
    ckfree(items);
    return TCL_OK;
}

/* Is an item detached? The root is never detached. */
static int IsDetached(Treeview *tv, TreeItem *item)
{
	return item->next == NULL && item->prev == NULL &&
			item->parent == NULL && item != tv->tree.root;
}

/* + $tv detached ?$item? --
 * 	List detached items (in arbitrary order) or query the detached state of
 * 	$item.
 */
static int TreeviewDetachedCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item;

    if (objc == 2) {
	/* List detached items */
	Tcl_HashSearch search;
	Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(&tv->tree.items, &search);
	Tcl_Obj *objPtr = Tcl_NewObj();

	while (entryPtr != NULL) {
	    item = (TreeItem *)Tcl_GetHashValue(entryPtr);
	    entryPtr = Tcl_NextHashEntry(&search);
	    if (IsDetached(tv, item)) {
		Tcl_ListObjAppendElement(NULL, objPtr, ItemID(tv, item));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    } else if (objc == 3) {
	/* Query; the root is never reported as detached */
	if (!(item = FindItem(interp, tv, objv[2]))) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(IsDetached(tv, item)));
	return TCL_OK;
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "?item?");
	return TCL_ERROR;
    }
}
/* + $tv delete $items --
 * 	Delete each item in $items.
 *
 * 	Do this in two passes:
 * 	First detach the item and all its descendants and remove them
 * 	from the hash table.  Free the items themselves in a second pass.
 *
 * 	It's done this way because an item may appear more than once
 *	in the list of items to delete (either directly or as a descendant
 *	of a previously deleted item.)
 */

static int TreeviewDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem **items, *delq;
    Tcl_Size i;
    int selChange = 0;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "items");
	return TCL_ERROR;
    }

    if (!(items = GetItemListFromObj(interp, tv, objv[2]))) {
	return TCL_ERROR;
    }

    /* Sanity-check:
     */
    for (i = 0; items[i]; ++i) {
	if (items[i] == tv->tree.root) {
	    ckfree(items);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Cannot delete root item", -1));
	    Tcl_SetErrorCode(interp, "TTK", "TREE", "ROOT", NULL);
	    return TCL_ERROR;
	}
    }

    /* Remove items from hash table.
     */
    delq = 0;
    for (i = 0; items[i]; ++i) {
        if (items[i]->state & TTK_STATE_SELECTED) {
            selChange = 1;
        } else if (items[i]->selObj != NULL) {
	    Tcl_Size length;
	    Tcl_ListObjLength(interp, items[i]->selObj, &length);
	    if (length > 0) {
		selChange = 1;
	    }
	}
	delq = DeleteItems(items[i], delq);
    }

    /* Free items:
     */
    while (delq) {
	TreeItem *next = delq->next;
	if (tv->tree.focus == delq)
	    tv->tree.focus = 0;
	if (tv->tree.endPtr == delq)
	    tv->tree.endPtr = 0;
	FreeItem(delq);
	delq = next;
    }

    ckfree(items);
    if (selChange) {
        Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }
    tv->tree.rowPosNeedsUpdate = 1;
    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, Tcl_Size 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");
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
    }

    /* Move item:
     */
    DetachItem(item);
    InsertItem(parent, sibling, item);


    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- scrolling
 */

static int TreeviewXViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    return TtkScrollviewCommand(interp, objc, objv, tv->tree.xscrollHandle);
}

static int TreeviewYViewCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    return TtkScrollviewCommand(interp, objc, objv, tv->tree.yscrollHandle);
}

/* $tree see $item --
 * 	Ensure that $item is visible.
 */
static int TreeviewSeeCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item, *parent;
    int rowNumber;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    if (!(item = FindItem(interp, tv, objv[2]))) {
	return TCL_ERROR;
    }

    /* Make sure all ancestors are open:
     */
    for (parent = item->parent; parent; parent = parent->parent) {
	if (!(parent->state & TTK_STATE_OPEN)) {
	    parent->openObj = unshareObj(parent->openObj);
	    Tcl_SetBooleanObj(parent->openObj, 1);
	    parent->state |= TTK_STATE_OPEN;

	    TtkRedisplayWidget(&tv->core);
	}



    }

    /* Make sure item is visible:
     */




    rowNumber = RowNumber(tv, item);


    if (rowNumber < tv->tree.yscroll.first) {
	TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1);
    } else if (rowNumber >= tv->tree.yscroll.last) {

	TtkScrollTo(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last), 1);
    }

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- interactive column resize
 */

/* + $tree drag $column $newX --
 * 	Set right edge of display column $column to x position $X
 */
static int TreeviewDragCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    int left = tv->tree.treeArea.x - tv->tree.xscroll.first;
    int i = FirstColumn(tv);
    TreeColumn *column;
    int newx;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "column xposition");
	return TCL_ERROR;
    }

    if ((column = FindColumn(interp, tv, objv[2])) == 0
	    || Tcl_GetIntFromObj(interp, objv[3], &newx) != TCL_OK) {
	return TCL_ERROR;
    }

    for (;i < tv->tree.nDisplayColumns; ++i) {
	TreeColumn *c = tv->tree.displayColumns[i];
	int right = left + c->width;
	if (c == column) {




	    DragColumn(tv, i, newx - right);
	    TtkRedisplayWidget(&tv->core);
	    return TCL_OK;
	}
	left = right;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	"column %s is not displayed", Tcl_GetString(objv[2])));
    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN_INVISIBLE", NULL);
    return TCL_ERROR;
}

static int TreeviewDropCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "drop");
	return TCL_ERROR;
    }
    ResizeColumns(tv, TreeWidth(tv));
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- focus and selection
 */

/* + $tree focus ?item?
 */
static int TreeviewFocusCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc == 2) {
	if (tv->tree.focus) {
	    Tcl_SetObjResult(interp, ItemID(tv, tv->tree.focus));
	}







>









|






|









|



|
















>


>
>
>




>
>
>
>
|
>
>
|
|
|
>
|
<













|



|

















>
>
>
>














|



















|







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
    }

    /* Move item:
     */
    DetachItem(item);
    InsertItem(parent, sibling, item);

    tv->tree.rowPosNeedsUpdate = 1;
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- scrolling
 */

static int TreeviewXViewCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    return TtkScrollviewCommand(interp, objc, objv, tv->tree.xscrollHandle);
}

static int TreeviewYViewCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    return TtkScrollviewCommand(interp, objc, objv, tv->tree.yscrollHandle);
}

/* $tree see $item --
 * 	Ensure that $item is visible.
 */
static int TreeviewSeeCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeItem *item, *parent;
    int scrollRow1, scrollRow2, visibleRows;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "item");
	return TCL_ERROR;
    }
    if (!(item = FindItem(interp, tv, objv[2]))) {
	return TCL_ERROR;
    }

    /* Make sure all ancestors are open:
     */
    for (parent = item->parent; parent; parent = parent->parent) {
	if (!(parent->state & TTK_STATE_OPEN)) {
	    parent->openObj = unshareObj(parent->openObj);
	    Tcl_SetBooleanObj(parent->openObj, 1);
	    parent->state |= TTK_STATE_OPEN;
	    tv->tree.rowPosNeedsUpdate = 1;
	    TtkRedisplayWidget(&tv->core);
	}
    }
    if (tv->tree.rowPosNeedsUpdate) {
	UpdatePositionTree(tv);
    }

    /* Make sure item is visible:
     */
    if (item->rowPos < tv->tree.titleRows) {
	return TCL_OK;
    }
    visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight
	    - tv->tree.titleRows;
    scrollRow1 = item->rowPos - tv->tree.titleRows;
    scrollRow2 = scrollRow1 + item->height - 1;
    if (scrollRow1 < tv->tree.yscroll.first || item->height > visibleRows) {
	TtkScrollTo(tv->tree.yscrollHandle, scrollRow1, 1);
    } else if (scrollRow2 >= tv->tree.yscroll.first + visibleRows) {
	scrollRow1 = 1 + scrollRow2 - visibleRows;
	TtkScrollTo(tv->tree.yscrollHandle, scrollRow1, 1);

    }

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- interactive column resize
 */

/* + $tree drag $column $newX --
 * 	Set right edge of display column $column to x position $X
 */
static int TreeviewDragCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    int left = tv->tree.treeArea.x - tv->tree.xscroll.first;
    Tcl_Size i = FirstColumn(tv);
    TreeColumn *column;
    int newx;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "column xposition");
	return TCL_ERROR;
    }

    if ((column = FindColumn(interp, tv, objv[2])) == 0
	    || Tcl_GetIntFromObj(interp, objv[3], &newx) != TCL_OK) {
	return TCL_ERROR;
    }

    for (;i < tv->tree.nDisplayColumns; ++i) {
	TreeColumn *c = tv->tree.displayColumns[i];
	int right = left + c->width;
	if (c == column) {
	    if (i < tv->tree.nTitleColumns) {
		/* Unscrollable column, remove scroll shift */
		right += tv->tree.xscroll.first;
	    }
	    DragColumn(tv, i, newx - right);
	    TtkRedisplayWidget(&tv->core);
	    return TCL_OK;
	}
	left = right;
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	"column %s is not displayed", Tcl_GetString(objv[2])));
    Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN_INVISIBLE", NULL);
    return TCL_ERROR;
}

static int TreeviewDropCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "drop");
	return TCL_ERROR;
    }
    ResizeColumns(tv, TreeWidth(tv));
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- focus and selection
 */

/* + $tree focus ?item?
 */
static int TreeviewFocusCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc == 2) {
	if (tv->tree.focus) {
	    Tcl_SetObjResult(interp, ItemID(tv, tv->tree.focus));
	}
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
	return TCL_ERROR;
    }
}

/* + $tree selection ?add|remove|set|toggle $items?
 */
static int TreeviewSelectionCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    enum {
	SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE
    };
    static const char *const selopStrings[] = {
	"set", "add", "remove", "toggle", NULL
    };

    Treeview *tv = (Treeview *)recordPtr;
    int selop, i;
    TreeItem *item, **items;

    if (objc == 2) {
	Tcl_Obj *result = Tcl_NewListObj(0,0);
	for (item = tv->tree.root->children; item; item = NextPreorder(item)) {
	    if (item->state & TTK_STATE_SELECTED)
		Tcl_ListObjAppendElement(NULL, result, ItemID(tv, item));







|









|







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
	return TCL_ERROR;
    }
}

/* + $tree selection ?add|remove|set|toggle $items?
 */
static int TreeviewSelectionCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    enum {
	SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE
    };
    static const char *const selopStrings[] = {
	"set", "add", "remove", "toggle", NULL
    };

    Treeview *tv = (Treeview *)recordPtr;
    int selop, i, selChange = 0;
    TreeItem *item, **items;

    if (objc == 2) {
	Tcl_Obj *result = Tcl_NewListObj(0,0);
	for (item = tv->tree.root->children; item; item = NextPreorder(item)) {
	    if (item->state & TTK_STATE_SELECTED)
		Tcl_ListObjAppendElement(NULL, result, ItemID(tv, item));
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
    if (!items) {
	return TCL_ERROR;
    }

    switch (selop)
    {
	case SELECTION_SET:

	    for (item=tv->tree.root; item; item = NextPreorder(item)) {

		item->state &= ~TTK_STATE_SELECTED;

	    }
	    /*FALLTHRU*/






	case SELECTION_ADD:
	    for (i=0; items[i]; ++i) {

		items[i]->state |= TTK_STATE_SELECTED;


	    }
	    break;
	case SELECTION_REMOVE:
	    for (i=0; items[i]; ++i) {

		items[i]->state &= ~TTK_STATE_SELECTED;


	    }
	    break;
	case SELECTION_TOGGLE:
	    for (i=0; items[i]; ++i) {
		items[i]->state ^= TTK_STATE_SELECTED;

	    }
	    break;
    }

    ckfree(items);

    Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);






















































































































































































































































    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- tags and bindings.
 */

/* + $tv tag bind $tag ?$sequence ?$script??
 */
static int TreeviewTagBindCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    Tk_BindingTable bindingTable = tv->tree.bindingTable;
    Ttk_Tag tag;

    if (objc < 4 || objc > 6) {







>

>
|
>
|
<
>
>
>
>
>
>


>
|
>
>




>
|
>
>





>





>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|







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
    if (!items) {
	return TCL_ERROR;
    }

    switch (selop)
    {
	case SELECTION_SET:
	    /* Clear */
	    for (item=tv->tree.root; item; item = NextPreorder(item)) {
		if (item->state & TTK_STATE_SELECTED) {
		    item->state &= ~TTK_STATE_SELECTED;
		    selChange = 1;
		}

	    }
	    for (i=0; items[i]; ++i) {
		items[i]->state |= TTK_STATE_SELECTED;
		selChange = 1;
	    }
	    break;
	case SELECTION_ADD:
	    for (i=0; items[i]; ++i) {
		if (!(items[i]->state & TTK_STATE_SELECTED)) {
		    items[i]->state |= TTK_STATE_SELECTED;
		    selChange = 1;
		}
	    }
	    break;
	case SELECTION_REMOVE:
	    for (i=0; items[i]; ++i) {
		if (items[i]->state & TTK_STATE_SELECTED) {
		    items[i]->state &= ~TTK_STATE_SELECTED;
		    selChange = 1;
		}
	    }
	    break;
	case SELECTION_TOGGLE:
	    for (i=0; items[i]; ++i) {
		items[i]->state ^= TTK_STATE_SELECTED;
		selChange = 1;
	    }
	    break;
    }

    ckfree(items);
    if (selChange) {
	Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + SelObjChangeElement --
 * 	Change an element in a cell selection list.
 */
static int SelObjChangeElement(
    Treeview *tv, Tcl_Obj *listPtr, Tcl_Obj *elemPtr,
    int add,
    TCL_UNUSED(int) /*remove*/,
    int toggle)
{
    Tcl_Size i, nElements;
    int anyChange = 0;
    TreeColumn *column, *elemColumn;
    Tcl_Obj **elements;

    elemColumn = FindColumn(NULL, tv, elemPtr);
    Tcl_ListObjGetElements(NULL, listPtr, &nElements, &elements);
    for (i = 0; i < nElements; i++) {
	column = FindColumn(NULL, tv, elements[i]);
	if (column == elemColumn) {
	    if (add) {
		return anyChange;
	    }
	    Tcl_ListObjReplace(NULL, listPtr, i, 1, 0, NULL);
	    anyChange = 1;
	    return anyChange;
	}
    }
    if (add || toggle) {
	Tcl_ListObjAppendElement(NULL, listPtr, elemColumn->idObj);
	anyChange = 1;
    }
    return anyChange;
}

/* + $tree cellselection ?add|remove|set|toggle $items?
 */
static int CellSelectionRange(
    Tcl_Interp *interp, Treeview *tv, Tcl_Obj *fromCell, Tcl_Obj *toCell,
    int add, int remove, int toggle)
{
    TreeCell cellFrom, cellTo;
    TreeItem *item;
    Tcl_Obj *columns, **elements;
    int colno, fromNo, toNo, anyChange = 0;
    Tcl_Size i, nElements;
    int set = !(add || remove || toggle);

    if (GetCellFromObj(interp, tv, fromCell, 1, &fromNo, &cellFrom)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    if (GetCellFromObj(interp, tv, toCell, 1, &toNo, &cellTo)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    /* Correct order.
     */
    if (fromNo > toNo) {
	colno = fromNo;
	fromNo = toNo;
	toNo = colno;
    }

    /* Make a list of columns in this rectangle.
     */
    columns = Tcl_NewListObj(0, 0);
    Tcl_IncrRefCount(columns);
    for (colno = fromNo; colno <= toNo; colno++) {
	Tcl_ListObjAppendElement(NULL, columns,
		tv->tree.displayColumns[colno]->idObj);
    }

    /* Set is the only operation that affects items outside its rectangle.
     * Start with clearing out.
     */
    if (set) {
	anyChange = CellSelectionClear(tv);
    }

    /* Correct order.
     */
    if (tv->tree.rowPosNeedsUpdate) {
	UpdatePositionTree(tv);
    }
    if (cellFrom.item->itemPos > cellTo.item->itemPos) {
	item = cellFrom.item;
	cellFrom.item = cellTo.item;
	cellTo.item = item;
    }

    /* Go through all items in this rectangle.
     */
    for (item = cellFrom.item; item; item = NextPreorder(item)) {
	if (item->selObj != NULL) {
	    item->selObj = unshareObj(item->selObj);

	    Tcl_ListObjGetElements(NULL, columns, &nElements, &elements);
	    for (i = 0; i < nElements; ++i) {
		anyChange |= SelObjChangeElement(tv, item->selObj, elements[i],
			add, remove, toggle);
	    }
	} else {
	    /* Set, add and toggle do the same thing when empty before.
	     */
	    if (!remove) {
		item->selObj = columns;
		Tcl_IncrRefCount(item->selObj);
		anyChange = 1;
	    }
	}
	if (item == cellTo.item) {
	    break;
	}
    }

    Tcl_DecrRefCount(columns);

    if (anyChange) {
	Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/* + $tree cellselection ?add|remove|set|toggle $items?
 */
static int TreeviewCellSelectionCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    enum {
	SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE
    };
    static const char *const selopStrings[] = {
	"set", "add", "remove", "toggle", NULL
    };

    Treeview *tv = (Treeview *)recordPtr;
    int selop, anyChange = 0;
    Tcl_Size i, nCells;
    TreeCell *cells;
    TreeItem *item;

    if (objc == 2) {
	Tcl_Obj *result = Tcl_NewListObj(0,0);
	for (item = tv->tree.root->children; item; item = NextPreorder(item)) {
	    if (item->selObj != NULL) {
		Tcl_Size n, elemc;
		Tcl_Obj **elemv;

		Tcl_ListObjGetElements(interp, item->selObj, &n, &elemv);
		elemc = n;
		for (i = 0; i < elemc; ++i) {
		    Tcl_Obj *elem[2];
		    elem[0] = ItemID(tv, item);
		    elem[1] = elemv[i];
		    Tcl_ListObjAppendElement(NULL, result,
			    Tcl_NewListObj(2, elem));
		}
	    }
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    }

    if (objc < 4 || objc > 5) {
    	Tcl_WrongNumArgs(interp, 2, objv, "?add|remove|set|toggle arg...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[2], selopStrings,
	    sizeof(char *), "cellselection operation", 0, &selop) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc == 5) {
	switch (selop)
	{
	    case SELECTION_SET:
		return CellSelectionRange(interp, tv, objv[3], objv[4], 0, 0, 0);
	    case SELECTION_ADD:
		return CellSelectionRange(interp, tv, objv[3], objv[4], 1, 0, 0);
	    case SELECTION_REMOVE:
		return CellSelectionRange(interp, tv, objv[3], objv[4], 0, 1, 0);
	    case SELECTION_TOGGLE:
		return CellSelectionRange(interp, tv, objv[3], objv[4], 0, 0, 1);
	}
    }

    cells = GetCellListFromObj(interp, tv, objv[3], &nCells);
    if (cells == NULL) {
	return TCL_ERROR;
    }

    switch (selop)
    {
	case SELECTION_SET:
	    anyChange = CellSelectionClear(tv);
	    /*FALLTHRU*/
	case SELECTION_ADD:
	    for (i = 0; i < nCells; i++) {
		item = cells[i].item;
		if (item->selObj == NULL) {
		    item->selObj = Tcl_NewListObj(0, 0);
		    Tcl_IncrRefCount(item->selObj);
		}
		item->selObj = unshareObj(item->selObj);
		anyChange |= SelObjChangeElement(tv, item->selObj,
			cells[i].colObj, 1, 0, 0);
	    }
	    break;
	case SELECTION_REMOVE:
	    for (i = 0; i < nCells; i++) {
		item = cells[i].item;
		if (item->selObj == NULL) {
		    continue;
		}
		item->selObj = unshareObj(item->selObj);
		anyChange |= SelObjChangeElement(tv, item->selObj,
			cells[i].colObj, 0, 1, 0);
	    }
	    break;
	case SELECTION_TOGGLE:
	    for (i = 0; i < nCells; i++) {
		item = cells[i].item;
		if (item->selObj == NULL) {
		    item->selObj = Tcl_NewListObj(0, 0);
		    Tcl_IncrRefCount(item->selObj);
		}
		item->selObj = unshareObj(item->selObj);
		anyChange = SelObjChangeElement(tv, item->selObj,
			cells[i].colObj, 0, 0, 1);
	    }
	    break;
    }

    ckfree(cells);
    if (anyChange) {
	Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
    }
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- tags and bindings.
 */

/* + $tv tag bind $tag ?$sequence ?$script??
 */
static int TreeviewTagBindCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    Tk_BindingTable bindingTable = tv->tree.bindingTable;
    Ttk_Tag tag;

    if (objc < 4 || objc > 6) {
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
    }
    return TCL_OK;
}

/* + $tv tag configure $tag ?-option ?value -option value...??
 */
static int TreeviewTagConfigureCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    Ttk_Tag tag;

    if (objc < 4) {
    	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?-option ?value ...??");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);

    if (objc == 4) {
	return Ttk_EnumerateTagOptions(interp, tagTable, tag);







|






|







3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
    }
    return TCL_OK;
}

/* + $tv tag configure $tag ?-option ?value -option value...??
 */
static int TreeviewTagConfigureCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    Ttk_Tag tag;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?-option ?value ...??");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);

    if (objc == 4) {
	return Ttk_EnumerateTagOptions(interp, tagTable, tag);
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
    TtkRedisplayWidget(&tv->core);
    return Ttk_ConfigureTag(interp, tagTable, tag, objc - 4, objv + 4);
}

/* + $tv tag delete $tag
 */
static int TreeviewTagDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    TreeItem *item = tv->tree.root;
    Ttk_Tag tag;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);
    /* remove the tag from all items */
    while (item) {

	RemoveTag(item, tag);
	item = NextPreorder(item);
    }
    /* then remove the tag from the tag table */

    Ttk_DeleteTagFromTable(tagTable, tag);
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + $tv tag has $tag ?$item?
 */
static int TreeviewTagHasCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc == 4) {	/* Return list of all items with tag */
	Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
	TreeItem *item = tv->tree.root;
	Tcl_Obj *result = Tcl_NewListObj(0,0);







|












|

>




>









|







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
    TtkRedisplayWidget(&tv->core);
    return Ttk_ConfigureTag(interp, tagTable, tag, objc - 4, objv + 4);
}

/* + $tv tag delete $tag
 */
static int TreeviewTagDeleteCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_TagTable tagTable = tv->tree.tagTable;
    TreeItem *item = tv->tree.root;
    Ttk_Tag tag;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);
    /* remove the tag from all cells and items */
    while (item) {
        RemoveTagFromCellsAtItem(item, tag);
	RemoveTag(item, tag);
	item = NextPreorder(item);
    }
    /* then remove the tag from the tag table */
    Tk_DeleteAllBindings(tv->tree.bindingTable, tag);
    Ttk_DeleteTagFromTable(tagTable, tag);
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + $tv tag has $tag ?$item?
 */
static int TreeviewTagHasCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc == 4) {	/* Return list of all items with tag */
	Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
	TreeItem *item = tv->tree.root;
	Tcl_Obj *result = Tcl_NewListObj(0,0);
3160
3161
3162
3163
3164
3165
3166






























































3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
	return TCL_OK;
    } else {
    	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?item?");
	return TCL_ERROR;
    }
}































































/* + $tv tag names $tag
 */
static int TreeviewTagNamesCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, "");
	return TCL_ERROR;
    }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


|







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
	return TCL_OK;
    } else {
    	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?item?");
	return TCL_ERROR;
    }
}

/* + $tv tag cell has $tag ?$cell?
 */
static int TreeviewCtagHasCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    TreeCell cell;
    Tcl_Size i, columnNumber;

    if (objc == 5) {	/* Return list of all cells with tag */
	Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[4]);
	TreeItem *item = tv->tree.root;
	Tcl_Obj *result = Tcl_NewListObj(0,0);

	while (item) {
	    for (i = 0; i < item->nTagSets && i <= tv->tree.nColumns; ++i) {
		if (item->cellTagSets[i] != NULL) {
		    if (Ttk_TagSetContains(item->cellTagSets[i], tag)) {
			Tcl_Obj *elem[2];
			elem[0] = ItemID(tv, item);
			if (i == 0) {
			    elem[1] = tv->tree.column0.idObj;
			} else {
			    elem[1] = tv->tree.columns[i-1].idObj;
			}
			Tcl_ListObjAppendElement(NULL, result,
				Tcl_NewListObj(2, elem));
		    }
		}
	    }
	    item = NextPreorder(item);
	}

	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else if (objc == 6) {	/* Test if cell has specified tag */
	Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[4]);
	int result = 0;
	if (GetCellFromObj(interp, tv, objv[5], 0, NULL, &cell) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (cell.column == &tv->tree.column0) {
	    columnNumber = 0;
	} else {
	    columnNumber = cell.column - tv->tree.columns + 1;
	}
	if (columnNumber < cell.item->nTagSets) {
	    if (cell.item->cellTagSets[columnNumber] != NULL) {
		result = Ttk_TagSetContains(
			cell.item->cellTagSets[columnNumber],
			tag);
	    }
	}

	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
	return TCL_OK;
    } else {
    	Tcl_WrongNumArgs(interp, 4, objv, "tagName ?cell?");
	return TCL_ERROR;
    }
}

/* + $tv tag names
 */
static int TreeviewTagNamesCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 3, objv, "");
	return TCL_ERROR;
    }
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
	if (item->tagsObj) Tcl_DecrRefCount(item->tagsObj);
	item->tagsObj = Ttk_NewTagSetObj(item->tagset);
	Tcl_IncrRefCount(item->tagsObj);
    }
}

static int TreeviewTagAddCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;
    TreeItem **items;
    int i;

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
    items = GetItemListFromObj(interp, tv, objv[4]);

    if (!items) {
	return TCL_ERROR;
    }

    for (i=0; items[i]; ++i) {
	AddTag(items[i], tag);
    }


































































    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + $tv tag remove $tag ?$items?
 */
static void RemoveTag(TreeItem *item, Ttk_Tag tag)
{
    if (Ttk_TagSetRemove(item->tagset, tag)) {
	if (item->tagsObj) Tcl_DecrRefCount(item->tagsObj);
	item->tagsObj = Ttk_NewTagSetObj(item->tagset);
	Tcl_IncrRefCount(item->tagsObj);
    }
}














static int TreeviewTagRemoveCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);

    if (objc == 5) {
	TreeItem **items = GetItemListFromObj(interp, tv, objv[4]);
	int i;

	if (!items) {
	    return TCL_ERROR;
	}
	for (i=0; items[i]; ++i) {
	    RemoveTag(items[i], tag);
	}

    } else if (objc == 4) {
	TreeItem *item = tv->tree.root;
	while (item) {
	    RemoveTag(item, tag);
	    item = NextPreorder(item);
	}
    }

    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}
























































static const Ttk_Ensemble TreeviewTagCommands[] = {
    { "add",		TreeviewTagAddCommand,0 },
    { "bind",		TreeviewTagBindCommand,0 },

    { "configure",	TreeviewTagConfigureCommand,0 },
    { "delete",		TreeviewTagDeleteCommand,0 },
    { "has",		TreeviewTagHasCommand,0 },
    { "names",		TreeviewTagNamesCommand,0 },
    { "remove",		TreeviewTagRemoveCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget commands record.
 */
static const Ttk_Ensemble TreeviewCommands[] = {
    { "bbox",  		TreeviewBBoxCommand,0 },

    { "children",	TreeviewChildrenCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "column", 	TreeviewColumnCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "delete", 	TreeviewDeleteCommand,0 },
    { "detach", 	TreeviewDetachCommand,0 },

    { "drag",   	TreeviewDragCommand,0 },
    { "drop",   	TreeviewDropCommand,0 },
    { "exists", 	TreeviewExistsCommand,0 },
    { "focus", 		TreeviewFocusCommand,0 },
    { "heading", 	TreeviewHeadingCommand,0 },
    { "identify",  	TreeviewIdentifyCommand,0 },
    { "index",  	TreeviewIndexCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "insert", 	TreeviewInsertCommand,0 },

    { "item", 		TreeviewItemCommand,0 },
    { "move", 		TreeviewMoveCommand,0 },
    { "next", 		TreeviewNextCommand,0 },
    { "parent", 	TreeviewParentCommand,0 },
    { "prev", 		TreeviewPrevCommand,0 },
    { "see", 		TreeviewSeeCommand,0 },
    { "selection" ,	TreeviewSelectionCommand,0 },
    { "set",  		TreeviewSetCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },

    { "tag",    	0,TreeviewTagCommands },
    { "xview",  	TreeviewXViewCommand,0 },
    { "yview",  	TreeviewYViewCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------







|




|













|


>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>

|




|
|












|


>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>













>






>







<

>









>







4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420

4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
	if (item->tagsObj) Tcl_DecrRefCount(item->tagsObj);
	item->tagsObj = Ttk_NewTagSetObj(item->tagset);
	Tcl_IncrRefCount(item->tagsObj);
    }
}

static int TreeviewTagAddCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;
    TreeItem **items;
    Tcl_Size i;

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
    items = GetItemListFromObj(interp, tv, objv[4]);

    if (!items) {
	return TCL_ERROR;
    }

    for (i = 0; items[i]; ++i) {
	AddTag(items[i], tag);
    }
    ckfree(items);

    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* Make sure tagset at column is allocated and initialised */
static void AllocCellTagSets(Treeview *tv, TreeItem *item, Tcl_Size columnNumber)
{
    Tcl_Size i, newSize = MAX(columnNumber + 1, tv->tree.nColumns + 1);
    if (item->nTagSets < newSize) {
	if (item->cellTagSets == NULL) {
	    item->cellTagSets = (Ttk_TagSet *)
		    ckalloc(sizeof(Ttk_TagSet)*newSize);
	} else {
	    item->cellTagSets = (Ttk_TagSet *)
		    ckrealloc(item->cellTagSets, sizeof(Ttk_TagSet) * newSize);
	}
	for (i = item->nTagSets; i < newSize; i++) {
	    item->cellTagSets[i] = NULL;
	}
	item->nTagSets = newSize;
    }

    if (item->cellTagSets[columnNumber] == NULL) {
	item->cellTagSets[columnNumber] =
		Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    }
}

/* + $tv tag cell add $tag $cells
 */
static int TreeviewCtagAddCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;
    TreeCell *cells;
    TreeItem *item;
    Tcl_Size i, nCells, columnNumber;

    if (objc != 6) {
	Tcl_WrongNumArgs(interp, 4, objv, "tagName cells");
	return TCL_ERROR;
    }

    cells = GetCellListFromObj(interp, tv, objv[5], &nCells);
    if (cells == NULL) {
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[4]);

    for (i = 0; i < nCells; i++) {
	if (cells[i].column == &tv->tree.column0) {
	    columnNumber = 0;
	} else {
	    columnNumber = cells[i].column - tv->tree.columns  + 1;
	}
	item = cells[i].item;
	AllocCellTagSets(tv, item, columnNumber);
	Ttk_TagSetAdd(item->cellTagSets[columnNumber], tag);
    }

    ckfree(cells);
    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + $tv tag remove $tag ?$items?
 */
static void RemoveTag(TreeItem *item, Ttk_Tag tag)
{
    if (Ttk_TagSetRemove(item->tagset, tag)) {
	if (item->tagsObj) Tcl_DecrRefCount(item->tagsObj);
	item->tagsObj = Ttk_NewTagSetObj(item->tagset);
	Tcl_IncrRefCount(item->tagsObj);
    }
}

/* Remove tag from all cells at row 'item'
 */
static void RemoveTagFromCellsAtItem(TreeItem *item, Ttk_Tag tag)
{
    Tcl_Size i;

    for (i = 0; i < item->nTagSets; i++) {
        if (item->cellTagSets[i] != NULL) {
            Ttk_TagSetRemove(item->cellTagSets[i], tag);
        }
    }
}

static int TreeviewTagRemoveCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;

    if (objc < 4 || objc > 5) {
	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?items?");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);

    if (objc == 5) {
	TreeItem **items = GetItemListFromObj(interp, tv, objv[4]);
	int i;

	if (!items) {
	    return TCL_ERROR;
	}
	for (i = 0; items[i]; ++i) {
	    RemoveTag(items[i], tag);
	}
	ckfree(items);
    } else if (objc == 4) {
	TreeItem *item = tv->tree.root;
	while (item) {
	    RemoveTag(item, tag);
	    item = NextPreorder(item);
	}
    }

    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

/* + $tv tag cell remove $tag ?$cells?
 */
static int TreeviewCtagRemoveCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;
    Ttk_Tag tag;
    TreeCell *cells;
    TreeItem *item;
    Tcl_Size i, nCells, columnNumber;

    if (objc < 5 || objc > 6) {
	Tcl_WrongNumArgs(interp, 4, objv, "tagName ?cells?");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[4]);

    if (objc == 6) {
	cells = GetCellListFromObj(interp, tv, objv[5], &nCells);
	if (cells == NULL) {
	    return TCL_ERROR;
	}

	for (i = 0; i < nCells; i++) {
	    if (cells[i].column == &tv->tree.column0) {
		columnNumber = 0;
	    } else {
		columnNumber = cells[i].column - tv->tree.columns  + 1;
	    }
	    item = cells[i].item;
	    AllocCellTagSets(tv, item, columnNumber);
	    Ttk_TagSetRemove(item->cellTagSets[columnNumber], tag);
	}
	ckfree(cells);
    } else {
	item = tv->tree.root;
	while (item) {
            RemoveTagFromCellsAtItem(item, tag);
	    item = NextPreorder(item);
	}
    }

    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}

static const Ttk_Ensemble TreeviewCtagCommands[] = {
    { "add",		TreeviewCtagAddCommand,0 },
    { "has",		TreeviewCtagHasCommand,0 },
    { "remove",		TreeviewCtagRemoveCommand,0 },
    { 0,0,0 }
};

static const Ttk_Ensemble TreeviewTagCommands[] = {
    { "add",		TreeviewTagAddCommand,0 },
    { "bind",		TreeviewTagBindCommand,0 },
    { "cell",    	0,TreeviewCtagCommands },
    { "configure",	TreeviewTagConfigureCommand,0 },
    { "delete",		TreeviewTagDeleteCommand,0 },
    { "has",		TreeviewTagHasCommand,0 },
    { "names",		TreeviewTagNamesCommand,0 },
    { "remove",		TreeviewTagRemoveCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget commands record.
 */
static const Ttk_Ensemble TreeviewCommands[] = {
    { "bbox",  		TreeviewBBoxCommand,0 },
    { "cellselection" ,	TreeviewCellSelectionCommand,0 },
    { "children",	TreeviewChildrenCommand,0 },
    { "cget",		TtkWidgetCgetCommand,0 },
    { "column", 	TreeviewColumnCommand,0 },
    { "configure",	TtkWidgetConfigureCommand,0 },
    { "delete", 	TreeviewDeleteCommand,0 },
    { "detach", 	TreeviewDetachCommand,0 },
    { "detached", 	TreeviewDetachedCommand,0 },
    { "drag",   	TreeviewDragCommand,0 },
    { "drop",   	TreeviewDropCommand,0 },
    { "exists", 	TreeviewExistsCommand,0 },
    { "focus", 		TreeviewFocusCommand,0 },
    { "heading", 	TreeviewHeadingCommand,0 },
    { "identify",  	TreeviewIdentifyCommand,0 },
    { "index",  	TreeviewIndexCommand,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 }
};

/*------------------------------------------------------------------------
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
    TTK_GROUP("Treeitem.padding", TTK_FILL_BOTH,
	TTK_NODE("Treeitem.indicator", TTK_PACK_LEFT)
	TTK_NODE("Treeitem.image", TTK_PACK_LEFT)
	TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))

TTK_LAYOUT("Cell",
    TTK_GROUP("Treedata.padding", TTK_FILL_BOTH,

	TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))

TTK_LAYOUT("Heading",
    TTK_NODE("Treeheading.cell", TTK_FILL_BOTH)
    TTK_GROUP("Treeheading.border", TTK_FILL_BOTH,
	TTK_GROUP("Treeheading.padding", TTK_FILL_BOTH,
	    TTK_NODE("Treeheading.image", TTK_PACK_RIGHT)
	    TTK_NODE("Treeheading.text", TTK_FILL_X))))

TTK_LAYOUT("Row",
    TTK_NODE("Treeitem.row", TTK_FILL_BOTH))




TTK_END_LAYOUT_TABLE

/*------------------------------------------------------------------------
 * +++ Tree indicator element.
 */

typedef struct {







>












>
>
>







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
    TTK_GROUP("Treeitem.padding", TTK_FILL_BOTH,
	TTK_NODE("Treeitem.indicator", TTK_PACK_LEFT)
	TTK_NODE("Treeitem.image", TTK_PACK_LEFT)
	TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))

TTK_LAYOUT("Cell",
    TTK_GROUP("Treedata.padding", TTK_FILL_BOTH,
	TTK_NODE("Treeitem.image", TTK_PACK_LEFT)
	TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))

TTK_LAYOUT("Heading",
    TTK_NODE("Treeheading.cell", TTK_FILL_BOTH)
    TTK_GROUP("Treeheading.border", TTK_FILL_BOTH,
	TTK_GROUP("Treeheading.padding", TTK_FILL_BOTH,
	    TTK_NODE("Treeheading.image", TTK_PACK_RIGHT)
	    TTK_NODE("Treeheading.text", TTK_FILL_X))))

TTK_LAYOUT("Row",
    TTK_NODE("Treeitem.row", TTK_FILL_BOTH))

TTK_LAYOUT("Separator",
    TTK_NODE("Treeitem.separator", TTK_FILL_BOTH))

TTK_END_LAYOUT_TABLE

/*------------------------------------------------------------------------
 * +++ Tree indicator element.
 */

typedef struct {
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
	offsetof(TreeitemIndicator,sizeObj), "12" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginsObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    Ttk_Padding margins;
    int size = 0;
    (void)dummy;
    (void)paddingPtr;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginsObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);

    *widthPtr = size + Ttk_PaddingWidth(margins);
    *heightPtr = size + Ttk_PaddingHeight(margins);
}

static void TreeitemIndicatorDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    ArrowDirection direction =
	(state & TTK_STATE_OPEN) ? ARROW_DOWN : ARROW_RIGHT;
    Ttk_Padding margins;
    XColor *borderColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    XGCValues gcvalues; GC gc; unsigned mask;
    (void)dummy;

    if (state & TTK_STATE_LEAF) /* don't draw anything */
	return;

    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginsObj,&margins);
    b = Ttk_PadBox(b, margins);








>
|
>
|
>
>




<
<









>
|
>
|
>
>







<







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
	offsetof(TreeitemIndicator,sizeObj), "12" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginsObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    Ttk_Padding margins;
    int size = 0;



    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginsObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);

    *widthPtr = size + Ttk_PaddingWidth(margins);
    *heightPtr = size + Ttk_PaddingHeight(margins);
}

static void TreeitemIndicatorDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    ArrowDirection direction =
	(state & TTK_STATE_OPEN) ? ARROW_DOWN : ARROW_RIGHT;
    Ttk_Padding margins;
    XColor *borderColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
    XGCValues gcvalues; GC gc; unsigned mask;


    if (state & TTK_STATE_LEAF) /* don't draw anything */
	return;

    Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginsObj,&margins);
    b = Ttk_PadBox(b, margins);

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
	offsetof(RowElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-rownumber", TK_OPTION_INT,
	offsetof(RowElement,rowNumberObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void RowElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, Ttk_State state)


{
    RowElement *row = (RowElement *)elementRecord;
    XColor *color = Tk_GetColorFromObj(tkwin, row->backgroundObj);
    GC gc = Tk_GCForColor(color, d);
    (void)dummy;
    (void)state;

    XFillRectangle(Tk_Display(tkwin), d, gc,
	    b.x, b.y, b.width, b.height);
}

static const Ttk_ElementSpec RowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(RowElement),
    RowElementOptions,
    TtkNullElementSize,
    RowElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialisation.
 */




MODULE_SCOPE
void TtkTreeview_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    RegisterWidget(interp, "ttk::treeview", &TreeviewWidgetSpec);

    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, 0);
    Ttk_RegisterElement(interp, theme, "Treeitem.row", &RowElementSpec, 0);

    Ttk_RegisterElement(interp, theme, "Treeheading.cell", &RowElementSpec, 0);
    Ttk_RegisterElement(interp, theme, "treearea", &ttkNullElementSpec, 0);

    Ttk_RegisterLayouts(theme, LayoutTable);
}

/*EOF*/







>
|
>
|
>
>




<
<

















>
>
>










>







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
	offsetof(RowElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-rownumber", TK_OPTION_INT,
	offsetof(RowElement,rowNumberObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void RowElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    RowElement *row = (RowElement *)elementRecord;
    XColor *color = Tk_GetColorFromObj(tkwin, row->backgroundObj);
    GC gc = Tk_GCForColor(color, d);



    XFillRectangle(Tk_Display(tkwin), d, gc,
	    b.x, b.y, b.width, b.height);
}

static const Ttk_ElementSpec RowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(RowElement),
    RowElementOptions,
    TtkNullElementSize,
    RowElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialisation.
 */

MODULE_SCOPE
void TtkTreeview_Init(Tcl_Interp *interp);

MODULE_SCOPE
void TtkTreeview_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    RegisterWidget(interp, "ttk::treeview", &TreeviewWidgetSpec);

    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, 0);
    Ttk_RegisterElement(interp, theme, "Treeitem.row", &RowElementSpec, 0);
    Ttk_RegisterElement(interp, theme, "Treeitem.separator", &RowElementSpec, 0);
    Ttk_RegisterElement(interp, theme, "Treeheading.cell", &RowElementSpec, 0);
    Ttk_RegisterElement(interp, theme, "treearea", &ttkNullElementSpec, 0);

    Ttk_RegisterLayouts(theme, LayoutTable);
}

/*EOF*/

Changes to generic/ttk/ttkWidget.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Copyright (c) 2003, Joe English
 *
 * Core widget utilities.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#ifdef MAC_OSX_TK
#define TK_NO_DOUBLE_BUFFERING 1
#endif

/*------------------------------------------------------------------------
 * +++ Internal helper routines.
 */

/* UpdateLayout --
 * 	Call the widget's get-layout hook to recompute corePtr->layout.
 * 	Returns TCL_OK if successful, returns TCL_ERROR and leaves

|





|


<
<
<
<







1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
/*
 * Copyright © 2003, Joe English
 *
 * Core widget utilities.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"





/*------------------------------------------------------------------------
 * +++ Internal helper routines.
 */

/* UpdateLayout --
 * 	Call the widget's get-layout hook to recompute corePtr->layout.
 * 	Returns TCL_OK if successful, returns TCL_ERROR and leaves
81
82
83
84
85
86
87
88




89
90
91
92
93
94
95
96
97
98
99
100
101

    Tk_FreePixmap(Tk_Display(tkwin), d);
    Tk_FreeGC(Tk_Display(tkwin), gc);
}
#else
/* No double-buffering: draw directly into the window. */
static Drawable BeginDrawing(Tk_Window tkwin) { return Tk_WindowId(tkwin); }
static void EndDrawing(Tk_Window tkwin, Drawable d) { (void)tkwin; (void)d;}




#endif

/* DrawWidget --
 *	Redraw a widget.  Called as an idle handler.
 */
static void DrawWidget(ClientData recordPtr)
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;

    corePtr->flags &= ~REDISPLAY_PENDING;
    if (Tk_IsMapped(corePtr->tkwin)) {
	Drawable d = BeginDrawing(corePtr->tkwin);
	corePtr->widgetSpec->layoutProc(recordPtr);







|
>
>
>
>





|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

    Tk_FreePixmap(Tk_Display(tkwin), d);
    Tk_FreeGC(Tk_Display(tkwin), gc);
}
#else
/* No double-buffering: draw directly into the window. */
static Drawable BeginDrawing(Tk_Window tkwin) { return Tk_WindowId(tkwin); }
static void EndDrawing(
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(Drawable))
{
}
#endif

/* DrawWidget --
 *	Redraw a widget.  Called as an idle handler.
 */
static void DrawWidget(void *recordPtr)
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;

    corePtr->flags &= ~REDISPLAY_PENDING;
    if (Tk_IsMapped(corePtr->tkwin)) {
	Drawable d = BeginDrawing(corePtr->tkwin);
	corePtr->widgetSpec->layoutProc(recordPtr);
114
115
116
117
118
119
120














121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    }

    if (!(corePtr->flags & REDISPLAY_PENDING)) {
	Tcl_DoWhenIdle(DrawWidget, corePtr);
	corePtr->flags |= REDISPLAY_PENDING;
    }
}















/* TtkResizeWidget --
 * 	Recompute widget size, schedule geometry propagation and redisplay.
 */
void TtkResizeWidget(WidgetCore *corePtr)
{
    if (corePtr->flags & WIDGET_DESTROYED) {
	return;
    }

    SizeChanged(corePtr);
    TtkRedisplayWidget(corePtr);
}

/* TtkWidgetChangeState --
 * 	Set / clear the specified bits in the 'state' flag,
 */
void TtkWidgetChangeState(WidgetCore *corePtr,
    unsigned int setBits, unsigned int clearBits)
{
    Ttk_State oldState = corePtr->state;
    corePtr->state = (oldState & ~clearBits) | setBits;
    if (corePtr->state ^ oldState) {
	TtkRedisplayWidget(corePtr);
    }
}

/* WidgetInstanceObjCmd --
 *	Widget instance command implementation.
 */
static int
WidgetInstanceObjCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    const Ttk_Ensemble *commands = corePtr->widgetSpec->commands;
    int status;

    Tcl_Preserve(clientData);
    status = Ttk_InvokeEnsemble(commands,1, clientData,interp,objc,objv);







>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
<




















|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    }

    if (!(corePtr->flags & REDISPLAY_PENDING)) {
	Tcl_DoWhenIdle(DrawWidget, corePtr);
	corePtr->flags |= REDISPLAY_PENDING;
    }
}

/*
 * WidgetWorldChanged --
 * 	Default Tk_ClassWorldChangedProc() for widgets.
 * 	Invoked whenever fonts or other system resources are changed;
 * 	recomputes geometry.
 */
static void WidgetWorldChanged(void *clientData)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    (void)UpdateLayout(corePtr->interp, corePtr);
    SizeChanged(corePtr);
    TtkRedisplayWidget(corePtr);
}

/* TtkResizeWidget --
 * 	Recompute widget size, schedule geometry propagation and redisplay.
 */
void TtkResizeWidget(WidgetCore *corePtr)
{
    if (corePtr->flags & WIDGET_DESTROYED) {
	return;
    }

    WidgetWorldChanged(corePtr);

}

/* TtkWidgetChangeState --
 * 	Set / clear the specified bits in the 'state' flag,
 */
void TtkWidgetChangeState(WidgetCore *corePtr,
    unsigned int setBits, unsigned int clearBits)
{
    Ttk_State oldState = corePtr->state;
    corePtr->state = (oldState & ~clearBits) | setBits;
    if (corePtr->state ^ oldState) {
	TtkRedisplayWidget(corePtr);
    }
}

/* WidgetInstanceObjCmd --
 *	Widget instance command implementation.
 */
static int
WidgetInstanceObjCmd(
    void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    const Ttk_Ensemble *commands = corePtr->widgetSpec->commands;
    int status;

    Tcl_Preserve(clientData);
    status = Ttk_InvokeEnsemble(commands,1, clientData,interp,objc,objv);
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 * the WIDGET_DESTROYED flag bit upon return.
 */

/* WidgetInstanceObjCmdDeleted --
 * 	Widget instance command	deletion callback.
 */
static void
WidgetInstanceObjCmdDeleted(ClientData clientData)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    corePtr->widgetCmd = NULL;
    if (corePtr->tkwin != NULL)
	Tk_DestroyWindow(corePtr->tkwin);
}

/* FreeWidget --
 *	 Final cleanup for widget; called via Tcl_EventuallyFree().
 */
static void
FreeWidget(void *memPtr)
{
    ckfree(memPtr);
}

/* DestroyWidget --
 * 	Main widget destructor; called from <DestroyNotify> event handler.
 */
static void
DestroyWidget(WidgetCore *corePtr)
{
    corePtr->flags |= WIDGET_DESTROYED;







|







<
<
<
<
<
<
<
<
<







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208









209
210
211
212
213
214
215
 * the WIDGET_DESTROYED flag bit upon return.
 */

/* WidgetInstanceObjCmdDeleted --
 * 	Widget instance command	deletion callback.
 */
static void
WidgetInstanceObjCmdDeleted(void *clientData)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    corePtr->widgetCmd = NULL;
    if (corePtr->tkwin != NULL)
	Tk_DestroyWindow(corePtr->tkwin);
}










/* DestroyWidget --
 * 	Main widget destructor; called from <DestroyNotify> event handler.
 */
static void
DestroyWidget(WidgetCore *corePtr)
{
    corePtr->flags |= WIDGET_DESTROYED;
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    corePtr->tkwin = NULL;
    if (corePtr->widgetCmd) {
	Tcl_Command cmd = corePtr->widgetCmd;
	corePtr->widgetCmd = 0;
	/* NB: this can reenter the interpreter via a command traces */
	Tcl_DeleteCommandFromToken(corePtr->interp, cmd);
    }
    Tcl_EventuallyFree(corePtr, (Tcl_FreeProc *) FreeWidget);
}

/*
 * CoreEventProc --
 *	Event handler for basic events.
 *	Processes Expose, Configure, FocusIn/Out, and Destroy events.
 *	Also handles <<ThemeChanged>> virtual events.
 *
 *	For Expose and Configure, simply schedule the widget for redisplay.
 *	For Destroy events, handle the cleanup process.
 *
 *	For Focus events, set/clear the focus bit in the state field.
 *	It turns out this is impossible to do correctly in a binding script,
 *	because Tk filters out focus events with detail == NotifyInferior.
 *
 *	For Deactivate/Activate pseudo-events, set/clear the background state
 *	flag.
 */

static const unsigned CoreEventMask
    = ExposureMask
    | StructureNotifyMask
    | FocusChangeMask
    | VirtualEventMask
    | ActivateMask
    | EnterWindowMask
    | LeaveWindowMask
    ;

static void CoreEventProc(ClientData clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;

    switch (eventPtr->type)
    {
	case ConfigureNotify :
	    TtkRedisplayWidget(corePtr);







|












<
<















|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249


250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    corePtr->tkwin = NULL;
    if (corePtr->widgetCmd) {
	Tcl_Command cmd = corePtr->widgetCmd;
	corePtr->widgetCmd = 0;
	/* NB: this can reenter the interpreter via a command traces */
	Tcl_DeleteCommandFromToken(corePtr->interp, cmd);
    }
    Tcl_EventuallyFree(corePtr, TCL_DYNAMIC);
}

/*
 * CoreEventProc --
 *	Event handler for basic events.
 *	Processes Expose, Configure, FocusIn/Out, and Destroy events.
 *	Also handles <<ThemeChanged>> virtual events.
 *
 *	For Expose and Configure, simply schedule the widget for redisplay.
 *	For Destroy events, handle the cleanup process.
 *
 *	For Focus events, set/clear the focus bit in the state field.


 *
 *	For Deactivate/Activate pseudo-events, set/clear the background state
 *	flag.
 */

static const unsigned CoreEventMask
    = ExposureMask
    | StructureNotifyMask
    | FocusChangeMask
    | VirtualEventMask
    | ActivateMask
    | EnterWindowMask
    | LeaveWindowMask
    ;

static void CoreEventProc(void *clientData, XEvent *eventPtr)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;

    switch (eventPtr->type)
    {
	case ConfigureNotify :
	    TtkRedisplayWidget(corePtr);
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
	case EnterNotify:
	    corePtr->state |= TTK_STATE_HOVER;
	    TtkRedisplayWidget(corePtr);
	    break;
	case VirtualEvent: {
	    const char *name = ((XVirtualEvent *)eventPtr)->name;
	    if ((name != NULL) && !strcmp("ThemeChanged", name)) {
		(void)UpdateLayout(corePtr->interp, corePtr);
		SizeChanged(corePtr);
		TtkRedisplayWidget(corePtr);
	    }
	    break;
	}
	default:
	    /* can't happen... */
	    break;
    }
}

/*
 * WidgetWorldChanged --
 * 	Default Tk_ClassWorldChangedProc() for widgets.
 * 	Invoked whenever fonts or other system resources are changed;
 * 	recomputes geometry.
 */
static void WidgetWorldChanged(ClientData clientData)
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    SizeChanged(corePtr);
    TtkRedisplayWidget(corePtr);
}

static const Tk_ClassProcs widgetClassProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    WidgetWorldChanged,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * TtkWidgetConstructorObjCmd --
 *	General-purpose widget constructor command implementation.
 *	ClientData is a WidgetSpec *.
 */
int TtkWidgetConstructorObjCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetSpec *widgetSpec = (WidgetSpec *)clientData;
    const char *className = widgetSpec->className;
    Tk_OptionTable optionTable =
	Tk_CreateOptionTable(interp, widgetSpec->optionSpecs);
    Tk_Window tkwin;
    void *recordPtr;
    WidgetCore *corePtr;
    Tk_SavedOptions savedOptions;
    int i;

    if (objc < 2 || objc % 2 == 1) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /* Check if a -class option has been specified.







<
|
<









<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|








|









|







310
311
312
313
314
315
316

317

318
319
320
321
322
323
324
325
326













327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
	case EnterNotify:
	    corePtr->state |= TTK_STATE_HOVER;
	    TtkRedisplayWidget(corePtr);
	    break;
	case VirtualEvent: {
	    const char *name = ((XVirtualEvent *)eventPtr)->name;
	    if ((name != NULL) && !strcmp("ThemeChanged", name)) {

		WidgetWorldChanged(corePtr);

	    }
	    break;
	}
	default:
	    /* can't happen... */
	    break;
    }
}














static const Tk_ClassProcs widgetClassProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    WidgetWorldChanged,		/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*
 * TtkWidgetConstructorObjCmd --
 *	General-purpose widget constructor command implementation.
 *	ClientData is a WidgetSpec *.
 */
int TtkWidgetConstructorObjCmd(
    void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    WidgetSpec *widgetSpec = (WidgetSpec *)clientData;
    const char *className = widgetSpec->className;
    Tk_OptionTable optionTable =
	Tk_CreateOptionTable(interp, widgetSpec->optionSpecs);
    Tk_Window tkwin;
    void *recordPtr;
    WidgetCore *corePtr;
    Tk_SavedOptions savedOptions;
    Tcl_Size i;

    if (objc < 2 || objc % 2 == 1) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /* Check if a -class option has been specified.
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531
532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    Ttk_Layout layout;

    Tcl_DStringInit(&styleName);

    /* Prefix:
     */
    TtkGetOrientFromObj(NULL, orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL)
	Tcl_DStringAppend(&styleName, "Horizontal.", -1);
    else
	Tcl_DStringAppend(&styleName, "Vertical.", -1);

    /* Add base style name:
     */
    if (corePtr->styleObj)
    	baseStyleName = Tcl_GetString(corePtr->styleObj);
    if (!baseStyleName || *baseStyleName == '\0')
    	baseStyleName = corePtr->widgetSpec->className;

    Tcl_DStringAppend(&styleName, baseStyleName, -1);

    /* Create layout:
     */
    layout= Ttk_CreateLayout(interp, themePtr, Tcl_DStringValue(&styleName),
	recordPtr, corePtr->optionTable, corePtr->tkwin);

    Tcl_DStringFree(&styleName);

    return layout;
}

/* TtkNullInitialize --
 * 	Default widget initializeProc (no-op)
 */
void TtkNullInitialize(Tcl_Interp *interp, void *recordPtr)


{
    (void)interp;
    (void)recordPtr;
}

/* TtkNullPostConfigure --
 * 	Default widget postConfigureProc (no-op)
 */
int TtkNullPostConfigure(Tcl_Interp *interp, void *clientData, int mask)
{
    (void)interp;
    (void)clientData;
    (void)mask;


    return TCL_OK;
}

/* TtkCoreConfigure --
 * 	Default widget configureProc.
 * 	Handles -style option.
 */







|

|

|








|














|
>
>

<
<





|
<
|
<
|
>
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516


517
518
519
520
521
522

523

524
525
526
527
528
529
530
531
532
533
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    Ttk_Layout layout;

    Tcl_DStringInit(&styleName);

    /* Prefix:
     */
    Ttk_GetOrientFromObj(NULL, orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL)
	Tcl_DStringAppend(&styleName, "Horizontal.", TCL_INDEX_NONE);
    else
	Tcl_DStringAppend(&styleName, "Vertical.", TCL_INDEX_NONE);

    /* Add base style name:
     */
    if (corePtr->styleObj)
    	baseStyleName = Tcl_GetString(corePtr->styleObj);
    if (!baseStyleName || *baseStyleName == '\0')
    	baseStyleName = corePtr->widgetSpec->className;

    Tcl_DStringAppend(&styleName, baseStyleName, TCL_INDEX_NONE);

    /* Create layout:
     */
    layout= Ttk_CreateLayout(interp, themePtr, Tcl_DStringValue(&styleName),
	recordPtr, corePtr->optionTable, corePtr->tkwin);

    Tcl_DStringFree(&styleName);

    return layout;
}

/* TtkNullInitialize --
 * 	Default widget initializeProc (no-op)
 */
void TtkNullInitialize(
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(void *))
{


}

/* TtkNullPostConfigure --
 * 	Default widget postConfigureProc (no-op)
 */
int TtkNullPostConfigure(

    TCL_UNUSED(Tcl_Interp *),

    TCL_UNUSED(void *),
    TCL_UNUSED(int))
{
    return TCL_OK;
}

/* TtkCoreConfigure --
 * 	Default widget configureProc.
 * 	Handles -style option.
 */
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572

    return status;
}

/* TtkNullCleanup --
 * 	Default widget cleanupProc (no-op)
 */
void TtkNullCleanup(void *recordPtr)

{
    (void)recordPtr;
    return;
}

/* TtkWidgetDoLayout --
 * 	Default widget layoutProc.
 */
void TtkWidgetDoLayout(void *clientData)







|
>

<







542
543
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558

    return status;
}

/* TtkNullCleanup --
 * 	Default widget cleanupProc (no-op)
 */
void TtkNullCleanup(
    TCL_UNUSED(void *))
{

    return;
}

/* TtkWidgetDoLayout --
 * 	Default widget layoutProc.
 */
void TtkWidgetDoLayout(void *clientData)
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
/*------------------------------------------------------------------------
 * +++ Default implementations for widget subcommands.
 */

/* $w cget -option
 */
int TtkWidgetCgetCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Tcl_Obj *result;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option");
	return TCL_ERROR;
    }
    result = Tk_GetOptionValue(interp, recordPtr,
		corePtr->optionTable, objv[2], corePtr->tkwin);
    if (result == NULL)
	return TCL_ERROR;
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/* $w configure ?-option ?value ....??
 */
int TtkWidgetConfigureCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Tcl_Obj *result;

    if (objc == 2) {
	result = Tk_GetOptionInfo(interp, recordPtr,
		corePtr->optionTable, NULL, corePtr->tkwin);







|



















|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
/*------------------------------------------------------------------------
 * +++ Default implementations for widget subcommands.
 */

/* $w cget -option
 */
int TtkWidgetCgetCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Tcl_Obj *result;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option");
	return TCL_ERROR;
    }
    result = Tk_GetOptionValue(interp, recordPtr,
		corePtr->optionTable, objv[2], corePtr->tkwin);
    if (result == NULL)
	return TCL_ERROR;
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/* $w configure ?-option ?value ....??
 */
int TtkWidgetConfigureCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Tcl_Obj *result;

    if (objc == 2) {
	result = Tk_GetOptionInfo(interp, recordPtr,
		corePtr->optionTable, NULL, corePtr->tkwin);
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
 * 	If $stateSpec is specified, modify the widget state accordingly,
 * 	return a new stateSpec representing the changed bits.
 *
 * 	Otherwise, return a statespec matching all the currently-set bits.
 */

int TtkWidgetStateCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_StateSpec spec;
    int status;
    Ttk_State oldState, changed;

    if (objc == 2) {







|







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
 * 	If $stateSpec is specified, modify the widget state accordingly,
 * 	return a new stateSpec representing the changed bits.
 *
 * 	Otherwise, return a statespec matching all the currently-set bits.
 */

int TtkWidgetStateCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_StateSpec spec;
    int status;
    Ttk_State oldState, changed;

    if (objc == 2) {
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
 *
 * 	Tests if widget state matches $stateSpec.
 *	If $script is specified, execute script if state matches.
 *	Otherwise, return true/false
 */

int TtkWidgetInstateCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_State state = corePtr->state;
    Ttk_StateSpec spec;
    int status = TCL_OK;

    if (objc < 3 || objc > 4) {







|







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
 *
 * 	Tests if widget state matches $stateSpec.
 *	If $script is specified, execute script if state matches.
 *	Otherwise, return true/false
 */

int TtkWidgetInstateCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_State state = corePtr->state;
    Ttk_StateSpec spec;
    int status = TCL_OK;

    if (objc < 3 || objc > 4) {
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
}

/* $w identify $x $y
 * $w identify element $x $y
 * 	Returns: name of element at $x, $y
 */
int TtkWidgetIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_Element element;
    static const char *const whatTable[] = { "element", NULL };
    int x, y, what;

    if (objc < 4 || objc > 5) {







|







744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
}

/* $w identify $x $y
 * $w identify element $x $y
 * 	Returns: name of element at $x, $y
 */
int TtkWidgetIdentifyCommand(
    void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    Ttk_Element element;
    static const char *const whatTable[] = { "element", NULL };
    int x, y, what;

    if (objc < 4 || objc > 5) {
790
791
792
793
794
795
796




















797
798
799
800

    element = Ttk_IdentifyElement(corePtr->layout, x, y);
    if (element) {
	const char *elementName = Ttk_ElementName(element);
	Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
    }





















    return TCL_OK;
}

/*EOF*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




776
777
778
779
780
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

    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, Tcl_Size 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

108




109
110

111
112
113
114
115
116
117
MODULE_SCOPE void TtkWidgetDoLayout(void *recordPtr);
MODULE_SCOPE void TtkWidgetDisplay(void *recordPtr, Drawable);

MODULE_SCOPE int TtkCoreConfigure(Tcl_Interp*, void *, int mask);

/* Common widget commands:
 */


MODULE_SCOPE int TtkWidgetConfigureCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetCgetCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetInstateCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetStateCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetIdentifyCommand(
	void *,Tcl_Interp *, int, Tcl_Obj*const[]);

/* Widget constructor:
 */
MODULE_SCOPE int TtkWidgetConstructorObjCmd(
	ClientData, Tcl_Interp*, int, Tcl_Obj*const[]);


#define RegisterWidget(interp, name, specPtr) \




    Tcl_CreateObjCommand(interp, name, \
	TtkWidgetConstructorObjCmd, (ClientData)specPtr,NULL)


/* WIDGET_TAKEFOCUS_TRUE --
 * WIDGET_TAKEFOCUS_FALSE --
 *	Add one or the other of these to each OptionSpecs table
 *	to indicate whether the widget should take focus
 *	during keyboard traversal.
 */







>
>

|
|
|

|

|
|
|



|
<

>

>
>
>
>

|
>







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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 *, Tcl_Size, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetConfigureCommand(
	void *,Tcl_Interp *, Tcl_Size, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetIdentifyCommand(
	void *,Tcl_Interp *, Tcl_Size, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetInstateCommand(
	void *,Tcl_Interp *, Tcl_Size, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetStateCommand(
	void *,Tcl_Interp *, Tcl_Size, Tcl_Obj*const[]);
MODULE_SCOPE int TtkWidgetStyleCommand(
	void *,Tcl_Interp *, Tcl_Size, Tcl_Obj*const[]);

/* Widget constructor:
 */
MODULE_SCOPE Tcl_ObjCmdProc2 TtkWidgetConstructorObjCmd;


#if TCL_MAJOR_VERSION > 8
#define RegisterWidget(interp, name, specPtr) \
    Tcl_CreateObjCommand2(interp, name, \
	TtkWidgetConstructorObjCmd, (void *)specPtr,NULL)
#else
#define RegisterWidget(interp, name, specPtr) \
    Tcl_CreateObjCommand(interp, name, \
	TtkWidgetConstructorObjCmd, (void *)specPtr,NULL)
#endif

/* WIDGET_TAKEFOCUS_TRUE --
 * WIDGET_TAKEFOCUS_FALSE --
 *	Add one or the other of these to each OptionSpecs table
 *	to indicate whether the widget should take focus
 *	during keyboard traversal.
 */
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239

240
241
242
243
244
245
246

typedef struct ScrollHandleRec *ScrollHandle;

MODULE_SCOPE ScrollHandle TtkCreateScrollHandle(WidgetCore *, Scrollable *);
MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle);

MODULE_SCOPE int TtkScrollviewCommand(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle);

MODULE_SCOPE void TtkUpdateScrollInfo(ScrollHandle h);
MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst, int updateScrollInfo);
MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total);
MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle);

/*
 * Tag sets (work in progress, half-baked)
 */

typedef struct TtkTag *Ttk_Tag;
typedef struct TtkTagTable *Ttk_TagTable;
typedef struct TtkTagSet {	/* TODO: make opaque */
    Ttk_Tag	*tags;
    int 	nTags;
} *Ttk_TagSet;

MODULE_SCOPE Ttk_TagTable Ttk_CreateTagTable(
	Tcl_Interp *, Tk_Window tkwin, const Tk_OptionSpec *, int recordSize);
MODULE_SCOPE void Ttk_DeleteTagTable(Ttk_TagTable);

MODULE_SCOPE Ttk_Tag Ttk_GetTag(Ttk_TagTable, const char *tagName);
MODULE_SCOPE Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable, Tcl_Obj *);

MODULE_SCOPE Tcl_Obj *Ttk_TagOptionValue(
    Tcl_Interp *, Ttk_TagTable, Ttk_Tag, Tcl_Obj *optionName);

MODULE_SCOPE int Ttk_EnumerateTagOptions(
    Tcl_Interp *, Ttk_TagTable, Ttk_Tag);

MODULE_SCOPE int Ttk_EnumerateTags(Tcl_Interp *, Ttk_TagTable);

MODULE_SCOPE void Ttk_DeleteTagFromTable(Ttk_TagTable, Ttk_Tag);

MODULE_SCOPE int Ttk_ConfigureTag(
    Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag,
    int objc, Tcl_Obj *const objv[]);

MODULE_SCOPE Ttk_TagSet Ttk_GetTagSetFromObj(
    Tcl_Interp *interp, Ttk_TagTable, Tcl_Obj *objPtr);
MODULE_SCOPE Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet);

MODULE_SCOPE void Ttk_FreeTagSet(Ttk_TagSet);

MODULE_SCOPE int Ttk_TagSetContains(Ttk_TagSet, Ttk_Tag tag);
MODULE_SCOPE int Ttk_TagSetAdd(Ttk_TagSet, Ttk_Tag tag);

MODULE_SCOPE int Ttk_TagSetRemove(Ttk_TagSet, Ttk_Tag tag);


MODULE_SCOPE void Ttk_TagSetValues(Ttk_TagTable, Ttk_TagSet, void *record);
MODULE_SCOPE void Ttk_TagSetApplyStyle(Ttk_TagTable,Ttk_Style,Ttk_State,void*);

/*
 * String tables for widget resource specifications:
 */








|














|



|

















|









>


>







191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

typedef struct ScrollHandleRec *ScrollHandle;

MODULE_SCOPE ScrollHandle TtkCreateScrollHandle(WidgetCore *, Scrollable *);
MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle);

MODULE_SCOPE int TtkScrollviewCommand(
    Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], ScrollHandle);

MODULE_SCOPE void TtkUpdateScrollInfo(ScrollHandle h);
MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst, int updateScrollInfo);
MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total);
MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle);

/*
 * Tag sets (work in progress, half-baked)
 */

typedef struct TtkTag *Ttk_Tag;
typedef struct TtkTagTable *Ttk_TagTable;
typedef struct TtkTagSet {	/* TODO: make opaque */
    Ttk_Tag	*tags;
    Tcl_Size 	nTags;
} *Ttk_TagSet;

MODULE_SCOPE Ttk_TagTable Ttk_CreateTagTable(
	Tcl_Interp *, Tk_Window tkwin, const Tk_OptionSpec *, size_t recordSize);
MODULE_SCOPE void Ttk_DeleteTagTable(Ttk_TagTable);

MODULE_SCOPE Ttk_Tag Ttk_GetTag(Ttk_TagTable, const char *tagName);
MODULE_SCOPE Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable, Tcl_Obj *);

MODULE_SCOPE Tcl_Obj *Ttk_TagOptionValue(
    Tcl_Interp *, Ttk_TagTable, Ttk_Tag, Tcl_Obj *optionName);

MODULE_SCOPE int Ttk_EnumerateTagOptions(
    Tcl_Interp *, Ttk_TagTable, Ttk_Tag);

MODULE_SCOPE int Ttk_EnumerateTags(Tcl_Interp *, Ttk_TagTable);

MODULE_SCOPE void Ttk_DeleteTagFromTable(Ttk_TagTable, Ttk_Tag);

MODULE_SCOPE int Ttk_ConfigureTag(
    Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag,
    Tcl_Size objc, Tcl_Obj *const objv[]);

MODULE_SCOPE Ttk_TagSet Ttk_GetTagSetFromObj(
    Tcl_Interp *interp, Ttk_TagTable, Tcl_Obj *objPtr);
MODULE_SCOPE Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet);

MODULE_SCOPE void Ttk_FreeTagSet(Ttk_TagSet);

MODULE_SCOPE int Ttk_TagSetContains(Ttk_TagSet, Ttk_Tag tag);
MODULE_SCOPE int Ttk_TagSetAdd(Ttk_TagSet, Ttk_Tag tag);
MODULE_SCOPE int Ttk_TagSetAddSet(Ttk_TagSet, Ttk_TagSet);
MODULE_SCOPE int Ttk_TagSetRemove(Ttk_TagSet, Ttk_Tag tag);

MODULE_SCOPE void Ttk_TagSetDefaults(Ttk_TagTable, Ttk_Style, void *);
MODULE_SCOPE void Ttk_TagSetValues(Ttk_TagTable, Ttk_TagSet, void *record);
MODULE_SCOPE void Ttk_TagSetApplyStyle(Ttk_TagTable,Ttk_Style,Ttk_State,void*);

/*
 * String tables for widget resource specifications:
 */

Changes to library/bgerror.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# bgerror.tcl --
#
#	Implementation of the bgerror procedure.  It posts a dialog box with
#	the error message and gives the user a chance to see a more detailed
#	stack trace, and possible do something more interesting with that
#	trace (like save it to a log).  This is adapted from work done by
#	Donal K. Fellows.
#
# Copyright © 1998-2000 by Ajuba Solutions.
# Copyright © 2007 by ActiveState Software Inc.
# Copyright © 2007 Daniel A. Steffen <[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"] \








|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# bgerror.tcl --
#
#	Implementation of the bgerror procedure.  It posts a dialog box with
#	the error message and gives the user a chance to see a more detailed
#	stack trace, and possible do something more interesting with that
#	trace (like save it to a log).  This is adapted from work done by
#	Donal K. Fellows.
#
# Copyright © 1998-2000 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"] \
119
120
121
122
123
124
125
126
127
128
129
130

131





132
133
134
135
136
137
138



139
140
141
142
143

144
145
146
147
148
149
150
	    after 500 [list bgerror "$err" 0]
	    return
	}
    }

    set ok [mc OK]
    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>4 lines).  Truncation occurs at the first point at
    # which one of those conditions is met.
    set displayedErr ""
    set lines 0
    set maxLine 45

    foreach line [split $err \n] {





	if {[string length $line] > $maxLine} {
	    append displayedErr "[string range $line 0 $maxLine-3]..."
	    break
	}
	if {$lines > 4} {
	    append displayedErr "..."
	    break



	} else {
	    append displayedErr "${line}\n"
	}
	incr lines
    }


    set title [mc "Application Error"]
    set text [mc "Error: %1\$s" $displayedErr]
    set buttons [list ok $ok dismiss [mc "Skip Messages"] \
		     function [mc "Details >>"]]

    # 1. Create the top-level window and divide it into top







|
|



>

>
>
>
>
>




|
|

>
>
>





>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	    after 500 [list bgerror "$err" 0]
	    return
	}
    }

    set ok [mc OK]
    # Truncate the message if it is too wide (>maxLine characters) or
    # too tall (>maxRows lines).  Truncation occurs at the first point at
    # which one of those conditions is met. No trailing newline.
    set displayedErr ""
    set lines 0
    set maxLine 45
    set maxRows 5
    foreach line [split $err \n] {
	if {$lines > $maxRows - 1} {
            # No more lines.  Append to previous line.
	    append displayedErr { ...}
	    break
	}
	if {[string length $line] > $maxLine} {
	    append displayedErr "[string range $line 0 $maxLine-3]..."
	    break
	}
	if {$lines > $maxRows - 2 && [string length $line] > $maxLine-4} {
	    append displayedErr "[string range $line 0 $maxLine-3]..."
	    break
	} elseif {$lines > $maxRows - 2} {
            # Last line, but no break or newline.  Room to add 4 chars.
	    append displayedErr "${line}"
	} else {
	    append displayedErr "${line}\n"
	}
	incr lines
    }
    set displayedErr [string trim $displayedErr]

    set title [mc "Application Error"]
    set text [mc "Error: %1\$s" $displayedErr]
    set buttons [list ok $ok dismiss [mc "Skip Messages"] \
		     function [mc "Details >>"]]

    # 1. Create the top-level window and divide it into top
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

    ttk::frame $dlg.bot
    ttk::frame $dlg.top
    pack $dlg.bot -side bottom -fill both
    pack $dlg.top -side top -fill both -expand 1

    set W [ttk::frame $dlg.top.info]
    text $W.text -setgrid true -height 10 -wrap char \
	-yscrollcommand [list $W.scroll set]
    if {$windowingsystem ne "aqua"} {
	$W.text configure -width 40
    }

    ttk::scrollbar $W.scroll -command [list $W.text yview]
    pack $W.scroll -side right -fill y







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

    ttk::frame $dlg.bot
    ttk::frame $dlg.top
    pack $dlg.bot -side bottom -fill both
    pack $dlg.top -side top -fill both -expand 1

    set W [ttk::frame $dlg.top.info]
    text $W.text -setgrid false -height 10 -wrap char \
	-yscrollcommand [list $W.scroll set]
    if {$windowingsystem ne "aqua"} {
	$W.text configure -width 40
    }

    ttk::scrollbar $W.scroll -command [list $W.text yview]
    pack $W.scroll -side right -fill y
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

    # 3. Create a row of buttons at the bottom of the dialog.

    set i 0
    foreach {name caption} $buttons {
	ttk::button $dlg.$name -text $caption -default normal \
	    -command [namespace code [list set button $i]]
	grid $dlg.$name -in $dlg.bot -column $i -row 0 -sticky ew -padx 10
	grid columnconfigure $dlg.bot $i -weight 1
	# We boost the size of some Mac buttons for l&f
	if {$windowingsystem eq "aqua"} {
	    if {($name eq "ok") || ($name eq "dismiss")} {
		grid columnconfigure $dlg.bot $i -minsize 90
	    }
	    grid configure $dlg.$name -pady 7







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

    # 3. Create a row of buttons at the bottom of the dialog.

    set i 0
    foreach {name caption} $buttons {
	ttk::button $dlg.$name -text $caption -default normal \
	    -command [namespace code [list set button $i]]
	grid $dlg.$name -in $dlg.bot -column $i -row 0 -sticky ew -padx 7.5p
	grid columnconfigure $dlg.bot $i -weight 1
	# We boost the size of some Mac buttons for l&f
	if {$windowingsystem eq "aqua"} {
	    if {($name eq "ok") || ($name eq "dismiss")} {
		grid columnconfigure $dlg.bot $i -minsize 90
	    }
	    grid configure $dlg.$name -pady 7

Changes to library/button.tcl.

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> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <plus> {
	tk::CheckRadioInvoke %W select
    }
    bind Checkbutton <minus> {
	tk::CheckRadioInvoke %W deselect
    }
    bind Checkbutton <Button-1> {
	tk::CheckRadioDown %W







|


|







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 <=> {
	tk::CheckRadioInvoke %W select
    }
    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
# choosedir.tcl --
#
#	Choose directory dialog implementation for Unix/Mac.
#
# Copyright © 1998-2000 by Scriptics Corporation.
# All rights reserved.

# Make sure the tk::dialog namespace, in which all dialogs should live, exists
namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {}

# Make the chooseDir namespace inside the dialog namespace




|







1
2
3
4
5
6
7
8
9
10
11
12
# choosedir.tcl --
#
#	Choose directory dialog implementation for Unix/Mac.
#
# Copyright © 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
114
115
116
117
118
119
120

121

122
123
124
125
126
127
128

    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }

    $data(dirMenuBtn) configure -textvariable {}


    # Return value to user
    #

    return $Priv(selectFilePath)
}








>
|
>







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }
    if {[winfo exists $data(dirMenuBtn)]} {
	$data(dirMenuBtn) configure -textvariable {}
    }

    # Return value to user
    #

    return $Priv(selectFilePath)
}

Changes to library/clrpick.tcl.

46
47
48
49
50
51
52

53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
    # This is the actual number of lines that are drawn in each color strip.
    # Note that the bars may be of any width.
    # However, NUM_COLORBARS must be a number that evenly divides 256.
    # Such as 256, 128, 64, etc.
    set data(NUM_COLORBARS) 16

    # BARS_WIDTH is the number of pixels wide the color bar portion of the

    # canvas is. This number must be a multiple of NUM_COLORBARS
    set data(BARS_WIDTH) 160

    # PLGN_WIDTH is the number of pixels wide of the triangular selection
    # polygon. This also results in the definition of the padding on the
    # left and right sides which is half of PLGN_WIDTH. Make this number even.

    set data(PLGN_HEIGHT) 10

    # PLGN_HEIGHT is the height of the selection polygon and the height of the
    # selection rectangle at the bottom of the color bar. No restrictions.
    set data(PLGN_WIDTH) 10

    Config $dataName $args
    InitValues $dataName

    set sc [winfo screen $data(-parent)]
    set winExists [winfo exists $w]
    if {!$winExists || $sc ne [winfo screen $w]} {







>
|
|



|
>
|



|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    # This is the actual number of lines that are drawn in each color strip.
    # Note that the bars may be of any width.
    # However, NUM_COLORBARS must be a number that evenly divides 256.
    # Such as 256, 128, 64, etc.
    set data(NUM_COLORBARS) 16

    # BARS_WIDTH is the number of pixels wide the color bar portion of the
    # canvas is. BARS_WIDTH, BARS_WIDTH * 1.25, BARS_WIDTH * 1.5, and
    # BARS_WIDTH * 1.75 must be multiples of NUM_COLORBARS.
    set data(BARS_WIDTH) [::tk::ScaleNum 192]

    # PLGN_WIDTH is the number of pixels wide of the triangular selection
    # polygon. This also results in the definition of the padding on the
    # left and right sides which is half of PLGN_WIDTH. PLGN_WIDTH,
    # PLGN_WIDTH * 1.25, PLGN_WIDTH * 1.5, and PLGN_WIDTH * 1.75 must be even.
    set data(PLGN_WIDTH) [::tk::ScaleNum 8]

    # PLGN_HEIGHT is the height of the selection polygon and the height of the
    # selection rectangle at the bottom of the color bar. No restrictions.
    set data(PLGN_HEIGHT) [::tk::ScaleNum 8]

    Config $dataName $args
    InitValues $dataName

    set sc [winfo screen $data(-parent)]
    set winExists [winfo exists $w]
    if {!$winExists || $sc ne [winfo screen $w]} {
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
	::tk::AmpWidget label $box.label -text "[mc $l]:" \
		-width $maxWidth -anchor ne
	bind $box.label <<AltUnderlined>> [list focus $box.entry]

	entry $box.entry -textvariable \
		::tk::dialog::color::[winfo name $w]($color,intensity) \
		-width 4
	pack $box.label -side left -fill y -padx 2 -pady 3
	pack $box.entry -side left -anchor n -pady 0
	pack $box -side left -fill both

	set height [expr {
	    [winfo reqheight $box.entry] -
	    2*([$box.entry cget -highlightthickness] + [$box.entry cget -bd])
	}]

	canvas $f.color -height $height \
		-width $data(BARS_WIDTH) -relief sunken -bd 2
	canvas $f.sel -height $data(PLGN_HEIGHT) \
		-width $data(canvasWidth) -highlightthickness 0
	pack $f.color -expand yes -fill both
	pack $f.sel -expand yes -fill both

	pack $f -side top -fill x -padx 0 -pady 2

	set data($color,entry) $box.entry
	set data($color,col) $f.color
	set data($color,sel) $f.sel

	bind $data($color,col) <Configure> \
		[list tk::dialog::color::DrawColorScale $w $color 1]
	bind $data($color,col) <Enter> \
		[list tk::dialog::color::EnterColorBar $w $color]
	bind $data($color,col) <Leave> \
		[list tk::dialog::color::LeaveColorBar $w $color]

	bind $data($color,sel) <Enter> \
		[list tk::dialog::color::EnterColorBar $w $color]
	bind $data($color,sel) <Leave> \
		[list tk::dialog::color::LeaveColorBar $w $color]

	bind $box.entry <Return> [list tk::dialog::color::HandleRGBEntry $w]
    }

    pack $stripsFrame -side left -fill both -padx 4 -pady 10

    # The selFrame contains a frame that demonstrates the currently
    # selected color
    #
    set selFrame [frame $topFrame.sel]
    set lab [::tk::AmpWidget label $selFrame.lab \
	    -text [mc "&Selection:"] -anchor sw]
    set ent [entry $selFrame.ent \
	    -textvariable ::tk::dialog::color::[winfo name $w](selection) \
	    -width 16]
    set f1  [frame $selFrame.f1 -relief sunken -bd 2]
    set data(finalCanvas) [frame $f1.demo -bd 0 -width 100 -height 70]

    pack $lab $ent -side top -fill x -padx 4 -pady 2
    pack $f1 -expand yes -anchor nw -fill both -padx 6 -pady 10
    pack $data(finalCanvas) -expand yes -fill both

    bind $ent <Return> [list tk::dialog::color::HandleSelEntry $w]

    pack $selFrame -side left -fill none -anchor nw
    pack $topFrame -side top -expand yes -fill both -anchor nw

    # the botFrame frame contains the buttons
    #
    set botFrame [frame $w.bot -relief raised -bd 1]

    ::tk::AmpWidget button $botFrame.ok     -text [mc "&OK"]		\
	    -command [list tk::dialog::color::OkCmd $w]
    ::tk::AmpWidget button $botFrame.cancel -text [mc "&Cancel"]	\
	    -command [list tk::dialog::color::CancelCmd $w]

    set data(okBtn)      $botFrame.ok
    set data(cancelBtn)  $botFrame.cancel

    grid x $botFrame.ok x $botFrame.cancel x -sticky ew
    grid configure $botFrame.ok $botFrame.cancel -padx 10 -pady 10
    grid columnconfigure $botFrame {0 4} -weight 1 -uniform space
    grid columnconfigure $botFrame {1 3} -weight 1 -uniform button
    grid columnconfigure $botFrame 2 -weight 2 -uniform space
    pack $botFrame -side bottom -fill x

    # Accelerator bindings
    bind $lab <<AltUnderlined>> [list focus $ent]
    bind $w <Escape> [list tk::ButtonInvoke $data(cancelBtn)]
    bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A]

    wm protocol $w WM_DELETE_WINDOW [list tk::dialog::color::CancelCmd $w]
    bind $lab <Destroy> [list tk::dialog::color::CancelCmd $w]
}

# ::tk::dialog::color::SetRGBValue --
#
#	Sets the current selection of the dialog box
#
proc ::tk::dialog::color::SetRGBValue {w color} {







|















|




















|











|

|
|




















|











<







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
	::tk::AmpWidget label $box.label -text "[mc $l]:" \
		-width $maxWidth -anchor ne
	bind $box.label <<AltUnderlined>> [list focus $box.entry]

	entry $box.entry -textvariable \
		::tk::dialog::color::[winfo name $w]($color,intensity) \
		-width 4
	pack $box.label -side left -fill y -padx 1.5p -pady 2p
	pack $box.entry -side left -anchor n -pady 0
	pack $box -side left -fill both

	set height [expr {
	    [winfo reqheight $box.entry] -
	    2*([$box.entry cget -highlightthickness] + [$box.entry cget -bd])
	}]

	canvas $f.color -height $height \
		-width $data(BARS_WIDTH) -relief sunken -bd 2
	canvas $f.sel -height $data(PLGN_HEIGHT) \
		-width $data(canvasWidth) -highlightthickness 0
	pack $f.color -expand yes -fill both
	pack $f.sel -expand yes -fill both

	pack $f -side top -fill x -padx 0 -pady 1.5p

	set data($color,entry) $box.entry
	set data($color,col) $f.color
	set data($color,sel) $f.sel

	bind $data($color,col) <Configure> \
		[list tk::dialog::color::DrawColorScale $w $color 1]
	bind $data($color,col) <Enter> \
		[list tk::dialog::color::EnterColorBar $w $color]
	bind $data($color,col) <Leave> \
		[list tk::dialog::color::LeaveColorBar $w $color]

	bind $data($color,sel) <Enter> \
		[list tk::dialog::color::EnterColorBar $w $color]
	bind $data($color,sel) <Leave> \
		[list tk::dialog::color::LeaveColorBar $w $color]

	bind $box.entry <Return> [list tk::dialog::color::HandleRGBEntry $w]
    }

    pack $stripsFrame -side left -fill both -padx 3p -pady 7.5p

    # The selFrame contains a frame that demonstrates the currently
    # selected color
    #
    set selFrame [frame $topFrame.sel]
    set lab [::tk::AmpWidget label $selFrame.lab \
	    -text [mc "&Selection:"] -anchor sw]
    set ent [entry $selFrame.ent \
	    -textvariable ::tk::dialog::color::[winfo name $w](selection) \
	    -width 16]
    set f1  [frame $selFrame.f1 -relief sunken -bd 2]
    set data(finalCanvas) [frame $f1.demo -bd 0 -width 75p -height 51p]

    pack $lab $ent -side top -fill x -padx 3p -pady 1.5p
    pack $f1 -expand yes -anchor nw -fill both -padx 4.5p -pady 7.5p
    pack $data(finalCanvas) -expand yes -fill both

    bind $ent <Return> [list tk::dialog::color::HandleSelEntry $w]

    pack $selFrame -side left -fill none -anchor nw
    pack $topFrame -side top -expand yes -fill both -anchor nw

    # the botFrame frame contains the buttons
    #
    set botFrame [frame $w.bot -relief raised -bd 1]

    ::tk::AmpWidget button $botFrame.ok     -text [mc "&OK"]		\
	    -command [list tk::dialog::color::OkCmd $w]
    ::tk::AmpWidget button $botFrame.cancel -text [mc "&Cancel"]	\
	    -command [list tk::dialog::color::CancelCmd $w]

    set data(okBtn)      $botFrame.ok
    set data(cancelBtn)  $botFrame.cancel

    grid x $botFrame.ok x $botFrame.cancel x -sticky ew
    grid configure $botFrame.ok $botFrame.cancel -padx 7.5p -pady 7.5p
    grid columnconfigure $botFrame {0 4} -weight 1 -uniform space
    grid columnconfigure $botFrame {1 3} -weight 1 -uniform button
    grid columnconfigure $botFrame 2 -weight 2 -uniform space
    pack $botFrame -side bottom -fill x

    # Accelerator bindings
    bind $lab <<AltUnderlined>> [list focus $ent]
    bind $w <Escape> [list tk::ButtonInvoke $data(cancelBtn)]
    bind $w <Alt-Key> [list tk::AltKeyInDialog $w %A]

    wm protocol $w WM_DELETE_WINDOW [list tk::dialog::color::CancelCmd $w]

}

# ::tk::dialog::color::SetRGBValue --
#
#	Sets the current selection of the dialog box
#
proc ::tk::dialog::color::SetRGBValue {w color} {

Changes to library/comdlg.tcl.

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
# w = widget record to modify. Must be the pathname of a widget.
#
# specs = {
#    {-commandlineswitch resourceName ResourceClass defaultValue verifier}
#    {....}
# }
#
# flags = currently unused.

#
# 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







|
>







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 = 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
	}
	return -code error -errorcode {TK VALUE_MISSING} \
	    "value for \"$cmdsw\" missing"
    }

    # 2: set the default values
    #

    foreach cmdsw [array names cmd] {
	set data($cmdsw) $def($cmdsw)

    }

    # 3: parse the argument list
    #
    foreach {cmdsw value} $argList {
	if {![info exists cmd($cmdsw)]} {
	    return -code error -errorcode [list TK LOOKUP OPTION $cmdsw] \







>
|
|
>







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)
        }
    }

    # 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.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	menu .menubar.help -tearoff 0
	AmpMenuArgs .menubar.help add command -label [mc &About...] \
		-command tk::ConsoleAbout
    }

    AmpMenuArgs .menubar.edit add separator
    if {$::tk::console::useFontchooser} {
        if {[tk windowingsystem] eq "aqua"} {
            .menubar.edit add command -label tk_choose_font_marker
            set index [.menubar.edit index tk_choose_font_marker]
            .menubar.edit entryconfigure $index \
                -label [mc "Show Fonts"]\
                -accelerator "$mod-T"\
                -command [list ::tk::console::FontchooserToggle]
            bind Console <<TkFontchooserVisibility>> \
                [list ::tk::console::FontchooserVisibility $index]
	    ::tk::console::FontchooserVisibility $index
        } else {
            AmpMenuArgs .menubar.edit add command -label [mc "&Font..."] \
                -command [list ::tk::console::FontchooserToggle]
        }
	bind Console <FocusIn>  [list ::tk::console::FontchooserFocus %W 1]
	bind Console <FocusOut> [list ::tk::console::FontchooserFocus %W 0]
    }
    AmpMenuArgs .menubar.edit add command -label [mc "&Increase Font Size"] \
        -accel "$mod++" -command {event generate .console <<Console_FontSizeIncr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "&Decrease Font Size"] \
        -accel "$mod+-" -command {event generate .console <<Console_FontSizeDecr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "Fit To Screen Width"] \
        -command {event generate .console <<Console_FitScreenWidth>>}

    if {[tk windowingsystem] eq "aqua"} {
	.menubar add cascade -label [mc Window] -menu [menu .menubar.window]
	.menubar add cascade -label [mc Help] -menu [menu .menubar.help]
    }

    . configure -menu .menubar

    # See if we can find a better font than the TkFixedFont
    catch {font create TkConsoleFont {*}[font configure TkFixedFont]}
    set families [font families]
    switch -exact -- [tk windowingsystem] {
        aqua { set preferred {Monaco 10} }
        win32 { set preferred {ProFontWindows 8 Consolas 8} }
        default { set preferred {} }
    }
    foreach {family size} $preferred {
        if {$family in $families} {
            font configure TkConsoleFont -family $family -size $size
            break
        }
    }

    # Provide the right border for the text widget (platform dependent).
    ::ttk::style layout ConsoleFrame {
        Entry.field -sticky news -border 1 -children {
            ConsoleFrame.padding -sticky news
        }
    }
    ::ttk::frame .consoleframe -style ConsoleFrame

    set con [text .console -yscrollcommand [list .sb set] -setgrid true \
                 -borderwidth 0 -highlightthickness 0 -font TkConsoleFont]
    if {[tk windowingsystem] eq "aqua"} {
        scrollbar .sb -command [list $con yview]
    } else {
        ::ttk::scrollbar .sb -command [list $con yview]
    }
    pack .sb  -in .consoleframe -fill both -side right -padx 1 -pady 1
    pack $con -in .consoleframe -fill both -expand 1 -side left -padx 1 -pady 1
    pack .consoleframe -fill both -expand 1 -side left

    ConsoleBind $con








|
|
|
|
|
|
|
|
|

|
|
|
|




|

|

|












|
|
|


|
|
|
|




|
|
|




|

|

|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	menu .menubar.help -tearoff 0
	AmpMenuArgs .menubar.help add command -label [mc &About...] \
		-command tk::ConsoleAbout
    }

    AmpMenuArgs .menubar.edit add separator
    if {$::tk::console::useFontchooser} {
	if {[tk windowingsystem] eq "aqua"} {
	    .menubar.edit add command -label tk_choose_font_marker
	    set index [.menubar.edit index tk_choose_font_marker]
	    .menubar.edit entryconfigure $index \
		-label [mc "Show Fonts"]\
		-accelerator "$mod-T"\
		-command [list ::tk::console::FontchooserToggle]
	    bind Console <<TkFontchooserVisibility>> \
		[list ::tk::console::FontchooserVisibility $index]
	    ::tk::console::FontchooserVisibility $index
	} else {
	    AmpMenuArgs .menubar.edit add command -label [mc "&Font..."] \
		-command [list ::tk::console::FontchooserToggle]
	}
	bind Console <FocusIn>  [list ::tk::console::FontchooserFocus %W 1]
	bind Console <FocusOut> [list ::tk::console::FontchooserFocus %W 0]
    }
    AmpMenuArgs .menubar.edit add command -label [mc "&Increase Font Size"] \
	-accel "$mod++" -command {event generate .console <<Console_FontSizeIncr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "&Decrease Font Size"] \
	-accel "$mod+-" -command {event generate .console <<Console_FontSizeDecr>>}
    AmpMenuArgs .menubar.edit add command -label [mc "Fit To Screen Width"] \
	-command {event generate .console <<Console_FitScreenWidth>>}

    if {[tk windowingsystem] eq "aqua"} {
	.menubar add cascade -label [mc Window] -menu [menu .menubar.window]
	.menubar add cascade -label [mc Help] -menu [menu .menubar.help]
    }

    . configure -menu .menubar

    # See if we can find a better font than the TkFixedFont
    catch {font create TkConsoleFont {*}[font configure TkFixedFont]}
    set families [font families]
    switch -exact -- [tk windowingsystem] {
	aqua { set preferred {Monaco 10} }
	win32 { set preferred {ProFontWindows 8 Consolas 8} }
	default { set preferred {} }
    }
    foreach {family size} $preferred {
	if {$family in $families} {
	    font configure TkConsoleFont -family $family -size $size
	    break
	}
    }

    # Provide the right border for the text widget (platform dependent).
    ::ttk::style layout ConsoleFrame {
	Entry.field -sticky news -border 1 -children {
	    ConsoleFrame.padding -sticky news
	}
    }
    ::ttk::frame .consoleframe -style ConsoleFrame

    set con [text .console -yscrollcommand [list .sb set] -setgrid true \
		 -borderwidth 0 -highlightthickness 0 -font TkConsoleFont]
    if {[tk windowingsystem] eq "aqua"} {
	scrollbar .sb -command [list $con yview]
    } else {
	::ttk::scrollbar .sb -command [list $con yview]
    }
    pack .sb  -in .consoleframe -fill both -side right -padx 1 -pady 1
    pack $con -in .consoleframe -fill both -expand 1 -side left -padx 1 -pady 1
    pack .consoleframe -fill both -expand 1 -side left

    ConsoleBind $con

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
proc ::tk::ConsoleSource {} {
    set filename [tk_getOpenFile -defaultextension .tcl -parent . \
	    -title [mc "Select a file to source"] \
	    -filetypes [list \
	    [list [mc "Tcl Scripts"] .tcl] \
	    [list [mc "All Files"] *]]]
    if {$filename ne ""} {
    	set cmd [list source -encoding utf-8 $filename]
	if {[catch {consoleinterp eval $cmd} result]} {
	    ConsoleOutput stderr "$result\n"
	}
    }
}

# ::tk::ConsoleInvoke --







|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
proc ::tk::ConsoleSource {} {
    set filename [tk_getOpenFile -defaultextension .tcl -parent . \
	    -title [mc "Select a file to source"] \
	    -filetypes [list \
	    [list [mc "Tcl Scripts"] .tcl] \
	    [list [mc "All Files"] *]]]
    if {$filename ne ""} {
	set cmd [list source -encoding utf-8 $filename]
	if {[catch {consoleinterp eval $cmd} result]} {
	    ConsoleOutput stderr "$result\n"
	}
    }
}

# ::tk::ConsoleInvoke --
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# cmd -	Which action to take: prev, next, reset.

set ::tk::HistNum 1
proc ::tk::ConsoleHistory {cmd} {
    variable HistNum

    switch $cmd {
    	prev {
	    incr HistNum -1
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } else {
		set cmd "history event $HistNum"
	    }
    	    if {[catch {consoleinterp eval $cmd} cmd]} {
    	    	incr HistNum
    	    	return
    	    }
	    .console delete promptEnd end
    	    .console insert promptEnd $cmd {input stdin}
	    .console see end
    	}
    	next {
	    incr HistNum
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } elseif {$HistNum > 0} {
		set cmd ""
		set HistNum 1
	    } else {
		set cmd "history event $HistNum"
	    }
	    if {$cmd ne ""} {
		catch {consoleinterp eval $cmd} cmd
	    }
	    .console delete promptEnd end
	    .console insert promptEnd $cmd {input stdin}
	    .console see end
    	}
    	reset {
    	    set HistNum 1
    	}
    }
}

# ::tk::ConsolePrompt --
# This procedure draws the prompt.  If tcl_prompt1 or tcl_prompt2
# exists in the main interpreter it will be called to generate the
# prompt.  Otherwise, a hard coded default prompt is printed.
#
# Arguments:
# partial -	Flag to specify which prompt to print.

proc ::tk::ConsolePrompt {{partial normal}} {
    set w .console
    if {$partial eq "normal"} {
	set temp [$w index "end - 1 char"]
	$w mark set output end
    	if {[consoleinterp eval "info exists tcl_prompt1"]} {
    	    consoleinterp eval "eval \[set tcl_prompt1\]"
    	} else {
    	    puts -nonewline [EvalAttached $::tk::console::defaultPrompt]
    	}
    } else {
	set temp [$w index output]
	$w mark set output end
    	if {[consoleinterp eval "info exists tcl_prompt2"]} {
    	    consoleinterp eval "eval \[set tcl_prompt2\]"
    	} else {
	    puts -nonewline "> "
    	}
    }
    flush stdout
    $w mark set output $temp
    ::tk::TextSetCursor $w end
    $w mark set promptEnd insert
    $w mark gravity promptEnd left
    ::tk::console::ConstrainBuffer $w $::tk::console::maxLines
    $w see end
}

# Copy selected text from the console
proc ::tk::console::Copy {w} {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        clipboard clear -displayof $w
        clipboard append -displayof $w $data
    }
}
# Copies selected text. If the selection is within the current active edit
# region then it will be cut, if not it is only copied.
proc ::tk::console::Cut {w} {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        clipboard clear -displayof $w
        clipboard append -displayof $w $data
        if {[$w compare sel.first >= output]} {
            $w delete sel.first sel.last
	}
    }
}
# Paste text from the clipboard
proc ::tk::console::Paste {w} {
    catch {
        set clip [::tk::GetSelection $w CLIPBOARD]
        set list [split $clip \n\r]
        tk::ConsoleInsert $w [lindex $list 0]
        foreach x [lrange $list 1 end] {
            $w mark set insert {end - 1c}
            tk::ConsoleInsert $w "\n"
            tk::ConsoleInvoke
            tk::ConsoleInsert $w $x
        }
    }
}

# Fit TkConsoleFont to window width
proc ::tk::console::FitScreenWidth {w} {
    set width [winfo screenwidth $w]
    set cwidth [$w cget -width]
    set s -50
    set fit 0
    array set fi [font configure TkConsoleFont]
    while {$s < 0} {
        set fi(-size) $s
        set f [font create {*}[array get fi]]
        set c [font measure $f "eM"]
        font delete $f
        if {$c * $cwidth < 1.667 * $width} {
            font configure TkConsoleFont -size $s
            break
        }
	incr s 2
    }
}

# ::tk::ConsoleBind --
# This procedure first ensures that the default bindings for the Text
# class have been defined.  Then certain bindings are overridden for







|






|
|
|
|

|

|
|















|
|
|
|
















|
|
|
|
|



|
|
|

|













|
|






|
|
|
|






|
|
|
|
|
|
|
|
|











|
|
|
|
|
|
|
|







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# cmd -	Which action to take: prev, next, reset.

set ::tk::HistNum 1
proc ::tk::ConsoleHistory {cmd} {
    variable HistNum

    switch $cmd {
	prev {
	    incr HistNum -1
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } else {
		set cmd "history event $HistNum"
	    }
	    if {[catch {consoleinterp eval $cmd} cmd]} {
		incr HistNum
		return
	    }
	    .console delete promptEnd end
	    .console insert promptEnd $cmd {input stdin}
	    .console see end
	}
	next {
	    incr HistNum
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } elseif {$HistNum > 0} {
		set cmd ""
		set HistNum 1
	    } else {
		set cmd "history event $HistNum"
	    }
	    if {$cmd ne ""} {
		catch {consoleinterp eval $cmd} cmd
	    }
	    .console delete promptEnd end
	    .console insert promptEnd $cmd {input stdin}
	    .console see end
	}
	reset {
	    set HistNum 1
	}
    }
}

# ::tk::ConsolePrompt --
# This procedure draws the prompt.  If tcl_prompt1 or tcl_prompt2
# exists in the main interpreter it will be called to generate the
# prompt.  Otherwise, a hard coded default prompt is printed.
#
# Arguments:
# partial -	Flag to specify which prompt to print.

proc ::tk::ConsolePrompt {{partial normal}} {
    set w .console
    if {$partial eq "normal"} {
	set temp [$w index "end - 1 char"]
	$w mark set output end
	if {[consoleinterp eval "info exists tcl_prompt1"]} {
	    consoleinterp eval "eval \[set tcl_prompt1\]"
	} else {
	    puts -nonewline [EvalAttached $::tk::console::defaultPrompt]
	}
    } else {
	set temp [$w index output]
	$w mark set output end
	if {[consoleinterp eval "info exists tcl_prompt2"]} {
	    consoleinterp eval "eval \[set tcl_prompt2\]"
	} else {
	    puts -nonewline "> "
	}
    }
    flush stdout
    $w mark set output $temp
    ::tk::TextSetCursor $w end
    $w mark set promptEnd insert
    $w mark gravity promptEnd left
    ::tk::console::ConstrainBuffer $w $::tk::console::maxLines
    $w see end
}

# Copy selected text from the console
proc ::tk::console::Copy {w} {
    if {![catch {set data [$w get sel.first sel.last]}]} {
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
    }
}
# Copies selected text. If the selection is within the current active edit
# region then it will be cut, if not it is only copied.
proc ::tk::console::Cut {w} {
    if {![catch {set data [$w get sel.first sel.last]}]} {
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	if {[$w compare sel.first >= output]} {
	    $w delete sel.first sel.last
	}
    }
}
# Paste text from the clipboard
proc ::tk::console::Paste {w} {
    catch {
	set clip [::tk::GetSelection $w CLIPBOARD]
	set list [split $clip \n\r]
	tk::ConsoleInsert $w [lindex $list 0]
	foreach x [lrange $list 1 end] {
	    $w mark set insert {end - 1c}
	    tk::ConsoleInsert $w "\n"
	    tk::ConsoleInvoke
	    tk::ConsoleInsert $w $x
	}
    }
}

# Fit TkConsoleFont to window width
proc ::tk::console::FitScreenWidth {w} {
    set width [winfo screenwidth $w]
    set cwidth [$w cget -width]
    set s -50
    set fit 0
    array set fi [font configure TkConsoleFont]
    while {$s < 0} {
	set fi(-size) $s
	set f [font create {*}[array get fi]]
	set c [font measure $f "eM"]
	font delete $f
	if {$c * $cwidth < 1.667 * $width} {
	    font configure TkConsoleFont -size $s
	    break
	}
	incr s 2
    }
}

# ::tk::ConsoleBind --
# This procedure first ensures that the default bindings for the Text
# class have been defined.  Then certain bindings are overridden for
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434


435
436
437
438
439
440
441
    ## ...or any Control-v binding (would block <<Paste>>)
    bind Console <Control-v> {}

    # For the moment, transpose isn't enabled until the console
    # gets and overhaul of how it handles input -- hobbs
    bind Console <Control-t> {}

    # Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
    # Otherwise, if a widget binding for one of these is defined, the
    # <Keypress> class binding will also fire and insert the character
    # which is wrong.

    bind Console <Alt-Key> {# nothing }
    bind Console <Meta-Key> {# nothing}
    bind Console <Control-Key> {# nothing}



    foreach {ev key} {
	<<Console_NextImmediate>>	<Control-n>
	<<Console_PrevImmediate>>	<Control-p>
	<<Console_PrevSearch>>		<Control-r>
	<<Console_NextSearch>>		<Control-s>








|







>
>







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    ## ...or any Control-v binding (would block <<Paste>>)
    bind Console <Control-v> {}

    # For the moment, transpose isn't enabled until the console
    # gets and overhaul of how it handles input -- hobbs
    bind Console <Control-t> {}

    # Ignore all Alt, Meta, Control, Command, and Fn keypresses unless explicitly bound.
    # Otherwise, if a widget binding for one of these is defined, the
    # <Keypress> class binding will also fire and insert the character
    # which is wrong.

    bind Console <Alt-Key> {# nothing }
    bind Console <Meta-Key> {# nothing}
    bind Console <Control-Key> {# nothing}
    bind Console <Command-Key> {# nothing}
    bind Console <Fn-Key> {# nothing}

    foreach {ev key} {
	<<Console_NextImmediate>>	<Control-n>
	<<Console_PrevImmediate>>	<Control-p>
	<<Console_PrevSearch>>		<Control-r>
	<<Console_NextSearch>>		<Control-s>

450
451
452
453
454
455
456
457
458


459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
	<<Console_Eval>>		<KP_Enter>

	<<Console_Clear>>		<Control-l>
	<<Console_KillLine>>		<Control-k>
	<<Console_Transpose>>		<Control-t>
	<<Console_ClearLine>>		<Control-u>
	<<Console_SaveCommand>>		<Control-z>
	<<Console_FontSizeIncr>>	<Control-plus>
	<<Console_FontSizeDecr>>	<Control-minus>


    } {
	event add $ev $key
	bind Console $key {}
    }
    if {[tk windowingsystem] eq "aqua"} {
	foreach {ev key} {
	    <<Console_FontSizeIncr>>	<Command-plus>
	    <<Console_FontSizeDecr>>	<Command-minus>
	} {
	    event add $ev $key
	    bind Console $key {}
	}
	if {$::tk::console::useFontchooser} {
	    bind Console <Command-t> [list ::tk::console::FontchooserToggle]
	}
    }
    bind Console <<Console_Expand>> {
	if {[%W compare insert > promptEnd]} {
	    ::tk::console::Expand %W
	}
    }
    bind Console <<Console_ExpandFile>> {







|

>
>




<
<
<
<
<
<
<
<
|
|
<







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466








467
468

469
470
471
472
473
474
475
	<<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-+>
	<<Console_FontSizeDecr>>	<Control-minus>
	<<Console_FontSizeIncr>>	<Command-+>
	<<Console_FontSizeDecr>>	<Command-minus>
    } {
	event add $ev $key
	bind Console $key {}
    }








    if {$::tk::console::useFontchooser} {
	bind Console <Command-t> [list ::tk::console::FontchooserToggle]

    }
    bind Console <<Console_Expand>> {
	if {[%W compare insert > promptEnd]} {
	    ::tk::console::Expand %W
	}
    }
    bind Console <<Console_ExpandFile>> {
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    bind Console <Insert> {
	catch {tk::ConsoleInsert %W [::tk::GetSelection %W PRIMARY]}
    }
    bind Console <Key> {
	tk::ConsoleInsert %W %A
    }
    bind Console <F9> {
	eval destroy [winfo child .]
	source -encoding utf-8 [file join $tk_library console.tcl]
    }
    if {[tk windowingsystem] eq "aqua"} {
	bind Console <Command-q> {
	    exit
	}
    }
    bind Console <<Cut>> { ::tk::console::Cut %W }
    bind Console <<Copy>> { ::tk::console::Copy %W }
    bind Console <<Paste>> { ::tk::console::Paste %W }

    bind Console <<Console_FontSizeIncr>> {
        set size [font configure TkConsoleFont -size]
        if {$size < 0} {set sign -1} else {set sign 1}
        set size [expr {(abs($size) + 1) * $sign}]
        font configure TkConsoleFont -size $size
	if {$::tk::console::useFontchooser} {
	    tk fontchooser configure -font TkConsoleFont
	}
    }
    bind Console <<Console_FontSizeDecr>> {
        set size [font configure TkConsoleFont -size]
        if {abs($size) < 2} { return }
        if {$size < 0} {set sign -1} else {set sign 1}
        set size [expr {(abs($size) - 1) * $sign}]
        font configure TkConsoleFont -size $size
	if {$::tk::console::useFontchooser} {
	    tk fontchooser configure -font TkConsoleFont
	}
    }
    bind Console <<Console_FitScreenWidth>> {
	::tk::console::FitScreenWidth %W
    }

    ##
    ## Bindings for doing special things based on certain keys
    ##
    bind PostConsole <parenright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \( \) promptEnd
	}
    }
    bind PostConsole <bracketright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \[ \] promptEnd







|


<
|
|
<






|
|
|
|





|
|
|
|
|











|







582
583
584
585
586
587
588
589
590
591

592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
    bind Console <Insert> {
	catch {tk::ConsoleInsert %W [::tk::GetSelection %W PRIMARY]}
    }
    bind Console <Key> {
	tk::ConsoleInsert %W %A
    }
    bind Console <F9> {
	destroy {*}[winfo children .]
	source -encoding utf-8 [file join $tk_library console.tcl]
    }

    bind Console <Command-q> {
	exit

    }
    bind Console <<Cut>> { ::tk::console::Cut %W }
    bind Console <<Copy>> { ::tk::console::Copy %W }
    bind Console <<Paste>> { ::tk::console::Paste %W }

    bind Console <<Console_FontSizeIncr>> {
	set size [font configure TkConsoleFont -size]
	if {$size < 0} {set sign -1} else {set sign 1}
	set size [expr {(abs($size) + 1) * $sign}]
	font configure TkConsoleFont -size $size
	if {$::tk::console::useFontchooser} {
	    tk fontchooser configure -font TkConsoleFont
	}
    }
    bind Console <<Console_FontSizeDecr>> {
	set size [font configure TkConsoleFont -size]
	if {abs($size) < 2} { return }
	if {$size < 0} {set sign -1} else {set sign 1}
	set size [expr {(abs($size) - 1) * $sign}]
	font configure TkConsoleFont -size $size
	if {$::tk::console::useFontchooser} {
	    tk fontchooser configure -font TkConsoleFont
	}
    }
    bind Console <<Console_FitScreenWidth>> {
	::tk::console::FitScreenWidth %W
    }

    ##
    ## Bindings for doing special things based on certain keys
    ##
    bind PostConsole <)> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \( \) promptEnd
	}
    }
    bind PostConsole <bracketright> {
	if {"\\" ne [%W get insert-2c]} {
	    ::tk::console::MatchPair %W \[ \] promptEnd

Changes to library/demos/anilabel.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# anilabel.tcl --
#
# This demonstration script creates a toplevel window containing
# several animated label widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .anilabel
catch {destroy $w}
toplevel $w
wm title $w "Animated Label Demonstration"
wm iconname $w "anilabel"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# anilabel.tcl --
#
# This demonstration script creates a toplevel window containing
# several animated label widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .anilabel
catch {destroy $w}
toplevel $w
wm title $w "Animated Label Demonstration"
wm iconname $w "anilabel"
positionWindow $w
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
	unset animationCallbacks(%W)
    }
}

## Next, a similar pair of procedures to animate a GIF loaded into a
## photo image.
proc SelectNextImageFrame {w interval} {
    global animationCallbacks
    set animationCallbacks($w) \
	    [after $interval SelectNextImageFrame $w $interval]
    set image [$w cget -image]

    # The easy way to animate a GIF!
    set idx -1
    scan [$image cget -format] "GIF -index %d" idx
    if {[catch {
	# Note that we get an error if the index is out of range
	$image configure -format "GIF -index [incr idx]"
    }]} then {
	$image configure -format "GIF -index 0"
    }

}
proc animateLabelImage {w imageData interval} {
    global animationCallbacks

    # Create a multi-frame GIF from base-64-encoded data
    set image [image create photo -format GIF -data $imageData]








    # Install the image into the widget
    $w configure -image $image

    # Schedule the start of the animation loop
    set animationCallbacks($w) \
	    [after $interval SelectNextImageFrame $w $interval]

    # Make sure that the animation stops and is cleaned up after itself
    # when the animated label is destroyed.  Note that at this point we
    # cannot manipulate the widget itself, as that has already died.
    # Also note that this script is in double-quotes; this is always OK
    # because image names are chosen automatically to be simple words.
    bind $w <Destroy> "
	after cancel \$animationCallbacks(%W)
	unset animationCallbacks(%W)
	rename $image {}
    "
}

# Make some widgets to contain the animations
labelframe $w.left -text "Scrolling Texts"
labelframe $w.right -text "GIF Image"
pack $w.left $w.right -side left -padx 10 -pady 10 -expand yes

# This method of scrolling text looks far better with a fixed-width font
label $w.left.l1 -bd 4 -relief ridge -font fixedFont
label $w.left.l2 -bd 4 -relief groove -font fixedFont
label $w.left.l3 -bd 4 -relief flat -font fixedFont -width 18
pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -padx 10 -pady 10 -anchor w
# Don't need to do very much with this label except turn off the border
label $w.right.l -bd 0
pack $w.right.l -side top -expand yes -padx 10 -pady 10

# This is a base-64-encoded animated GIF file.
set tclPoweredData {
    R0lGODlhKgBAAPQAAP//////zP//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM
    zMyZmcyZZsxmZsxmAMwzAJnMzJmZzJmZmZlmmZlmZplmM5kzM2aZzGZmzGZm
    mWZmZmYzZmYzMzNmzDMzZgAzmSH+IE1hZGUgd2l0aCBHSU1QIGJ5IExARGVt
    YWlsbHkuY29tACH5BAVkAAEALAAAAAAqAEAAAAX+YCCOZEkyTKM2jOm66yPP







|


|










>


|




>
>
>
>
>
>
>
|
|




















|


|
|
|
|


|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
	unset animationCallbacks(%W)
    }
}

## Next, a similar pair of procedures to animate a GIF loaded into a
## photo image.
proc SelectNextImageFrame {w interval} {
    global animationCallbacks image zoomFactor
    set animationCallbacks($w) \
	    [after $interval SelectNextImageFrame $w $interval]
    set image2 [$w cget -image]

    # The easy way to animate a GIF!
    set idx -1
    scan [$image cget -format] "GIF -index %d" idx
    if {[catch {
	# Note that we get an error if the index is out of range
	$image configure -format "GIF -index [incr idx]"
    }]} then {
	$image configure -format "GIF -index 0"
    }
    $image2 copy $image -zoom $zoomFactor
}
proc animateLabelImage {w imageData interval} {
    global animationCallbacks image zoomFactor

    # Create a multi-frame GIF from base-64-encoded data
    set image [image create photo -format GIF -data $imageData]

    # Create a copy of the image just created, magnified according to the
    # display's DPI scaling level.  Since the zooom factor must be an integer,
    # the copy will only be effectively magnified if $tk::scalingPct >= 200.
    set image2 [image create photo]
    set zoomFactor [expr {$tk::scalingPct / 100}]
    $image2 copy $image -zoom $zoomFactor

    # Install the image copy into the widget
    $w configure -image $image2

    # Schedule the start of the animation loop
    set animationCallbacks($w) \
	    [after $interval SelectNextImageFrame $w $interval]

    # Make sure that the animation stops and is cleaned up after itself
    # when the animated label is destroyed.  Note that at this point we
    # cannot manipulate the widget itself, as that has already died.
    # Also note that this script is in double-quotes; this is always OK
    # because image names are chosen automatically to be simple words.
    bind $w <Destroy> "
	after cancel \$animationCallbacks(%W)
	unset animationCallbacks(%W)
	rename $image {}
    "
}

# Make some widgets to contain the animations
labelframe $w.left -text "Scrolling Texts"
labelframe $w.right -text "GIF Image"
pack $w.left $w.right -side left -padx 7.5p -pady 7.5p -expand yes

# This method of scrolling text looks far better with a fixed-width font
label $w.left.l1 -bd 3p -relief ridge -font fixedFont
label $w.left.l2 -bd 3p -relief groove -font fixedFont
label $w.left.l3 -bd 3p -relief flat -font fixedFont -width 18
pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -padx 7.5p -pady 7.5p -anchor w
# Don't need to do very much with this label except turn off the border
label $w.right.l -bd 0
pack $w.right.l -side top -expand yes -padx 7.5p -pady 7.5p

# This is a base-64-encoded animated GIF file.
set tclPoweredData {
    R0lGODlhKgBAAPQAAP//////zP//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM
    zMyZmcyZZsxmZsxmAMwzAJnMzJmZzJmZmZlmmZlmZplmM5kzM2aZzGZmzGZm
    mWZmZmYzZmYzMzNmzDMzZgAzmSH+IE1hZGUgd2l0aCBHSU1QIGJ5IExARGVt
    YWlsbHkuY29tACH5BAVkAAEALAAAAAAqAEAAAAX+YCCOZEkyTKM2jOm66yPP

Changes to library/demos/aniwave.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
# aniwave.tcl --
#
# This demonstration script illustrates how to adjust canvas item
# coordinates in a way that does something fairly similar to waveform
# display.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .aniwave
catch {destroy $w}
toplevel $w
wm title $w "Animated Wave Demonstration"
wm iconname $w "aniwave"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration contains a canvas widget with a line item inside it. The animation routines work by adjusting the coordinates list of the line; a trace on a variable is used so updates to the variable result in a change of position of the line."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create a canvas large enough to hold the wave. In fact, the wave
# sticks off both sides of the canvas to prevent visual glitches.
pack [canvas $w.c -width 300 -height 200 -background black] -padx 10 -pady 10 -expand yes

# Ensure that this this is an array
array set animationCallbacks {}

# Creates a coordinates list of a wave. This code does a very sketchy
# job and relies on Tk's line smoothing to make things look better.
set waveCoords {}
for {set x -10} {$x<=300} {incr x 5} {
    lappend waveCoords $x 100
}
lappend waveCoords $x 0 [incr x 5] 200

# Create a smoothed line and arrange for its coordinates to be the
# contents of the variable waveCoords.
$w.c create line $waveCoords -tags wave -width 1 -fill green -smooth 1
proc waveCoordsTracer {w args} {
    global waveCoords
    # Actual visual update will wait until we have finished
    # processing; Tk does that for us automatically.
    $w.c coords wave $waveCoords



}
trace add variable waveCoords write [list waveCoordsTracer $w]

# Basic motion handler. Given what direction the wave is travelling
# in, it advances the y coordinates in the coordinate-list one step in
# that direction.
proc basicMotion {} {










|

















|














|





>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# aniwave.tcl --
#
# This demonstration script illustrates how to adjust canvas item
# coordinates in a way that does something fairly similar to waveform
# display.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .aniwave
catch {destroy $w}
toplevel $w
wm title $w "Animated Wave Demonstration"
wm iconname $w "aniwave"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration contains a canvas widget with a line item inside it. The animation routines work by adjusting the coordinates list of the line; a trace on a variable is used so updates to the variable result in a change of position of the line."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create a canvas large enough to hold the wave. In fact, the wave
# sticks off both sides of the canvas to prevent visual glitches.
pack [canvas $w.c -width 225p -height 150p -background black] -padx 7.5p -pady 7.5p -expand yes

# Ensure that this this is an array
array set animationCallbacks {}

# Creates a coordinates list of a wave. This code does a very sketchy
# job and relies on Tk's line smoothing to make things look better.
set waveCoords {}
for {set x -10} {$x<=300} {incr x 5} {
    lappend waveCoords $x 100
}
lappend waveCoords $x 0 [incr x 5] 200

# Create a smoothed line and arrange for its coordinates to be the
# contents of the variable waveCoords.
$w.c create line $waveCoords -tags wave -width 0.75p -fill green -smooth 1
proc waveCoordsTracer {w args} {
    global waveCoords
    # Actual visual update will wait until we have finished
    # processing; Tk does that for us automatically.
    $w.c coords wave $waveCoords

    set scaleFactor [expr {$tk::scalingPct / 100.0}]
    $w.c scale wave 0 0 $scaleFactor $scaleFactor
}
trace add variable waveCoords write [list waveCoordsTracer $w]

# Basic motion handler. Given what direction the wave is travelling
# in, it advances the y coordinates in the coordinate-list one step in
# that direction.
proc basicMotion {} {

Changes to library/demos/arrow.tcl.

1
2
3
4
5
6
7
8
9
10










11
12
13
14
15
16
17
# arrow.tcl --
#
# This demonstration script creates a canvas widget that displays a
# large line with an arrowhead whose shape can be edited interactively.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk











# arrowSetup --
# This procedure regenerates all the text and graphics in the canvas
# window.  It's called when the canvas is initially created, and also
# whenever any of the parameters of the arrow head are changed
# interactively.
#









|
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# arrow.tcl --
#
# This demonstration script creates a canvas widget that displays a
# large line with an arrowhead whose shape can be edited interactively.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# scl --
# Scales an integer according to the display's current scaling percentage.
#
# Arguments:
#   num -	An integer.

proc scl num {
    return [expr {round($num*$tk::scalingPct/100.0)}]
}

# arrowSetup --
# This procedure regenerates all the text and graphics in the canvas
# window.  It's called when the canvas is initially created, and also
# whenever any of the parameters of the arrow head are changed
# interactively.
#
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62






63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    } else {
	set cur ""
    }

    # Create the arrow and outline.

    $c delete all
    eval {$c create line $v(x1) $v(y) $v(x2) $v(y)  -arrow last \
	    -width [expr {10*$v(width)}] -arrowshape [list \
	    [expr {10*$v(a)}] [expr {10*$v(b)}] [expr {10*$v(c)}]]} \
	    $v(bigLineStyle)
    set xtip [expr {$v(x2)-10*$v(b)}]
    set deltaY [expr {10*$v(c)+5*$v(width)}]
    $c create line $v(x2) $v(y) $xtip [expr {$v(y)+$deltaY}] \
	    [expr {$v(x2)-10*$v(a)}] $v(y) $xtip [expr {$v(y)-$deltaY}] \
	    $v(x2) $v(y) -width 2 -capstyle round -joinstyle round

    # Create the boxes for reshaping the line and arrowhead.


    eval {$c create rect [expr {$v(x2)-10*$v(a)-5}] [expr {$v(y)-5}] \
	    [expr {$v(x2)-10*$v(a)+5}] [expr {$v(y)+5}] \
	    -tags {box1 box}} $v(boxStyle)
    eval {$c create rect [expr {$xtip-5}] [expr {$v(y)-$deltaY-5}] \
	    [expr {$xtip+5}] [expr {$v(y)-$deltaY+5}] \
	    -tags {box2 box}} $v(boxStyle)
    eval {$c create rect [expr {$v(x1)-5}] [expr {$v(y)-5*$v(width)-5}] \
	    [expr {$v(x1)+5}] [expr {$v(y)-5*$v(width)+5}] \
	    -tags {box3 box}} $v(boxStyle)
    if {$cur != ""} {
	eval $c itemconfigure $cur $v(activeStyle)
    }

    # Create three arrows in actual size with the same parameters







    $c create line [expr {$v(x2)+50}] 0 [expr {$v(x2)+50}] 1000 \
	    -width 2
    set tmp [expr {$v(x2)+100}]
    $c create line $tmp [expr {$v(y)-125}] $tmp [expr {$v(y)-75}] \
	    -width $v(width) \
	    -arrow both -arrowshape "$v(a) $v(b) $v(c)"
    $c create line [expr {$tmp-25}] $v(y) [expr {$tmp+25}] $v(y) \
	    -width $v(width) \
	    -arrow both -arrowshape "$v(a) $v(b) $v(c)"
    $c create line [expr {$tmp-25}] [expr {$v(y)+75}] [expr {$tmp+25}] \
	    [expr {$v(y)+125}] -width $v(width) \
	    -arrow both -arrowshape "$v(a) $v(b) $v(c)"

    # Create a bunch of other arrows and text items showing the
    # current dimensions.

    set tmp [expr {$v(x2)+10}]
    $c create line $tmp [expr {$v(y)-5*$v(width)}] \
	    $tmp [expr {$v(y)-$deltaY}] \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x2)+15}] [expr {$v(y)-$deltaY+5*$v(c)}] \
	    -text $v(c) -anchor w
    set tmp [expr {$v(x1)-10}]
    $c create line $tmp [expr {$v(y)-5*$v(width)}] \
	    $tmp [expr {$v(y)+5*$v(width)}] \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x1)-15}] $v(y) -text $v(width) -anchor e
    set tmp [expr {$v(y)+5*$v(width)+10*$v(c)+10}]
    $c create line [expr {$v(x2)-10*$v(a)}] $tmp $v(x2) $tmp \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x2)-5*$v(a)}] [expr {$tmp+5}] \
	    -text $v(a) -anchor n
    set tmp [expr {$tmp+25}]
    $c create line [expr {$v(x2)-10*$v(b)}] $tmp $v(x2) $tmp \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x2)-5*$v(b)}] [expr {$tmp+5}] \
	    -text $v(b) -anchor n

    $c create text $v(x1) 310 -text "-width  $v(width)" \
	    -anchor w -font {Helvetica 18}
    $c create text $v(x1) 330 -text "-arrowshape  {$v(a)  $v(b)  $v(c)}" \
	    -anchor w -font {Helvetica 18}

    incr v(count)
}

set w .arrow
catch {destroy $w}
toplevel $w
wm title $w "Arrowhead Editor Demonstration"
wm iconname $w "arrow"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 5i -justify left -text "This widget allows you to experiment with different widths and arrowhead shapes for lines in canvases.  To change the line width or the shape of the arrowhead, drag any of the three boxes attached to the oversized arrow.  The arrows on the right give examples at normal scale.  The text at the bottom shows the configuration options as you'd enter them for a canvas line item."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

canvas $c -width 500 -height 350 -relief sunken -borderwidth 2
pack $c -expand yes -fill both

set demo_arrowInfo(a) 8
set demo_arrowInfo(b) 10
set demo_arrowInfo(c) 3
set demo_arrowInfo(width) 2
set demo_arrowInfo(motionProc) arrowMoveNull
set demo_arrowInfo(x1) 40
set demo_arrowInfo(x2) 350
set demo_arrowInfo(y) 150
set demo_arrowInfo(smallTips) {5 5 2}
set demo_arrowInfo(count) 0
if {[winfo depth $c] > 1} {
    if {[tk windowingsystem] eq "aqua"} {
	set demo_arrowInfo(bigLineStyle) "-fill systemSelectedTextBackgroundColor"
    } else {
	set demo_arrowInfo(bigLineStyle) "-fill LightSeaGreen"
    }
    set demo_arrowInfo(boxStyle) "-fill {} -width 1"
    set demo_arrowInfo(activeStyle) "-fill red -width 1"
} else {
    # Main widget program sets variable tk_demoDirectory
    set demo_arrowInfo(bigLineStyle) "-fill black \
	-stipple @[file join $tk_demoDirectory images grey.25]"
    set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 1"
    set demo_arrowInfo(activeStyle) "-fill black -outline black -width 1"
}
arrowSetup $c
$c bind box <Enter> "$c itemconfigure current $demo_arrowInfo(activeStyle)"
$c bind box <Leave> "$c itemconfigure current $demo_arrowInfo(boxStyle)"
$c bind box <B1-Enter> " "
$c bind box <B1-Leave> " "
$c bind box1 <Button-1> {set demo_arrowInfo(motionProc) arrowMove1}







|

|
|




|



>
|
|
|
|
|
|
|
|
|

|


|

>
>
>
>
>
>
|
<
|
|
<
|
|
<
|
|
|
|




|



|

|



|
|


|

|


|


|

|




















|


|
|
|
|

|
|
|
|







|
|




|
|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82

83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    } else {
	set cur ""
    }

    # Create the arrow and outline.

    $c delete all
    $c create line $v(x1) $v(y) $v(x2) $v(y) -arrow last \
	    -width [expr {10*$v(width)}] -arrowshape [list \
	    [expr {10*$v(a)}] [expr {10*$v(b)}] [expr {10*$v(c)}]] \
	    {*}$v(bigLineStyle)
    set xtip [expr {$v(x2)-10*$v(b)}]
    set deltaY [expr {10*$v(c)+5*$v(width)}]
    $c create line $v(x2) $v(y) $xtip [expr {$v(y)+$deltaY}] \
	    [expr {$v(x2)-10*$v(a)}] $v(y) $xtip [expr {$v(y)-$deltaY}] \
	    $v(x2) $v(y) -width 1.5p -capstyle round -joinstyle round

    # Create the boxes for reshaping the line and arrowhead.

    set _5 [scl 5]
    $c create rect [expr {$v(x2)-10*$v(a)-$_5}] [expr {$v(y)-$_5}] \
	    [expr {$v(x2)-10*$v(a)+$_5}] [expr {$v(y)+$_5}] \
	    -tags {box1 box} {*}$v(boxStyle)
    $c create rect [expr {$xtip-$_5}] [expr {$v(y)-$deltaY-$_5}] \
	    [expr {$xtip+$_5}] [expr {$v(y)-$deltaY+$_5}] \
	    -tags {box2 box} {*}$v(boxStyle)
    $c create rect [expr {$v(x1)-$_5}] [expr {$v(y)-5*$v(width)-$_5}] \
	    [expr {$v(x1)+$_5}] [expr {$v(y)-5*$v(width)+$_5}] \
	    -tags {box3 box} {*}$v(boxStyle)
    if {$cur != ""} {
	$c itemconfigure $cur {*}$v(activeStyle)
    }

    # Create three arrows in actual size with the same parameters.

    set _10  [scl 10]
    set _15  [scl 15]
    set _25  [scl 25]
    set _50  [scl 50]
    set _75  [scl 75]
    set _125 [scl 125]
    $c create line [expr {$v(x2)+$_50}] 0 [expr {$v(x2)+$_50}] 750p -width 1.5p

    set tmp [expr {$v(x2)+[scl 100]}]
    $c create line $tmp [expr {$v(y)-$_125}] $tmp [expr {$v(y)-$_75}] \

	    -width $v(width) -arrow both -arrowshape "$v(a) $v(b) $v(c)"
    $c create line [expr {$tmp-$_25}] $v(y) [expr {$tmp+$_25}] $v(y) \

	    -width $v(width) -arrow both -arrowshape "$v(a) $v(b) $v(c)"
    $c create line [expr {$tmp-$_25}] [expr {$v(y)+$_75}] \
	    [expr {$tmp+$_25}] [expr {$v(y)+$_125}] \
	    -width $v(width) -arrow both -arrowshape "$v(a) $v(b) $v(c)"

    # Create a bunch of other arrows and text items showing the
    # current dimensions.

    set tmp [expr {$v(x2)+$_10}]
    $c create line $tmp [expr {$v(y)-5*$v(width)}] \
	    $tmp [expr {$v(y)-$deltaY}] \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x2)+$_15}] [expr {$v(y)-$deltaY+5*$v(c)}] \
	    -text $v(c) -anchor w
    set tmp [expr {$v(x1)-$_10}]
    $c create line $tmp [expr {$v(y)-5*$v(width)}] \
	    $tmp [expr {$v(y)+5*$v(width)}] \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x1)-$_15}] $v(y) -text $v(width) -anchor e
    set tmp [expr {$v(y)+5*$v(width)+10*$v(c)+$_10}]
    $c create line [expr {$v(x2)-10*$v(a)}] $tmp $v(x2) $tmp \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x2)-5*$v(a)}] [expr {$tmp+$_5}] \
	    -text $v(a) -anchor n
    set tmp [expr {$tmp+$_25}]
    $c create line [expr {$v(x2)-10*$v(b)}] $tmp $v(x2) $tmp \
	    -arrow both -arrowshape $v(smallTips)
    $c create text [expr {$v(x2)-5*$v(b)}] [expr {$tmp+$_5}] \
	    -text $v(b) -anchor n

    $c create text $v(x1) 232.5p -text "-width  $v(width)" \
	    -anchor w -font {Helvetica 18}
    $c create text $v(x1) 247.5p -text "-arrowshape  {$v(a)  $v(b)  $v(c)}" \
	    -anchor w -font {Helvetica 18}

    incr v(count)
}

set w .arrow
catch {destroy $w}
toplevel $w
wm title $w "Arrowhead Editor Demonstration"
wm iconname $w "arrow"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 5i -justify left -text "This widget allows you to experiment with different widths and arrowhead shapes for lines in canvases.  To change the line width or the shape of the arrowhead, drag any of the three boxes attached to the oversized arrow.  The arrows on the right give examples at normal scale.  The text at the bottom shows the configuration options as you'd enter them for a canvas line item."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

canvas $c -width 375p -height 262.5p -relief sunken -borderwidth 2
pack $c -expand yes -fill both

set demo_arrowInfo(a)	  [scl 8]
set demo_arrowInfo(b)	  [scl 10]
set demo_arrowInfo(c)	  [scl 3]
set demo_arrowInfo(width) [scl 2]
set demo_arrowInfo(motionProc) arrowMoveNull
set demo_arrowInfo(x1)	  [scl 40]
set demo_arrowInfo(x2)	  [scl 350]
set demo_arrowInfo(y)	  [scl 150]
set demo_arrowInfo(smallTips) {3.75p 3.75p 1.5p}
set demo_arrowInfo(count) 0
if {[winfo depth $c] > 1} {
    if {[tk windowingsystem] eq "aqua"} {
	set demo_arrowInfo(bigLineStyle) "-fill systemSelectedTextBackgroundColor"
    } else {
	set demo_arrowInfo(bigLineStyle) "-fill LightSeaGreen"
    }
    set demo_arrowInfo(boxStyle) "-fill {} -width 0.75p"
    set demo_arrowInfo(activeStyle) "-fill red -width 0.75p"
} else {
    # Main widget program sets variable tk_demoDirectory
    set demo_arrowInfo(bigLineStyle) "-fill black \
	-stipple @[file join $tk_demoDirectory images grey.25]"
    set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 0.75p"
    set demo_arrowInfo(activeStyle) "-fill black -outline black -width 0.75p"
}
arrowSetup $c
$c bind box <Enter> "$c itemconfigure current $demo_arrowInfo(activeStyle)"
$c bind box <Leave> "$c itemconfigure current $demo_arrowInfo(boxStyle)"
$c bind box <B1-Enter> " "
$c bind box <B1-Leave> " "
$c bind box1 <Button-1> {set demo_arrowInfo(motionProc) arrowMove1}
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201

202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
#
# Arguments:
# c -		The name of the canvas window.
# x, y -	The coordinates of the mouse.

proc arrowMove1 {c x y} {
    upvar #0 demo_arrowInfo v
    set newA [expr {($v(x2)+5-round([$c canvasx $x]))/10}]
    if {$newA < 0} {
	set newA 0
    }

    if {$newA > 25} {
	set newA 25
    }
    if {$newA != $v(a)} {
	$c move box1 [expr {10*($v(a)-$newA)}] 0
	set v(a) $newA
    }
}

# arrowMove2 --
# This procedure is called for each mouse motion event on box2 (the
# one at the trailing tip of the arrowhead).  It updates the controlling
# parameters for the line and arrowhead.
#
# Arguments:
# c -		The name of the canvas window.
# x, y -	The coordinates of the mouse.

proc arrowMove2 {c x y} {
    upvar #0 demo_arrowInfo v

    set newB [expr {($v(x2)+5-round([$c canvasx $x]))/10}]
    if {$newB < 0} {
	set newB 0
    }

    if {$newB > 25} {
	set newB 25
    }
    set newC [expr {($v(y)+5-round([$c canvasy $y])-5*$v(width))/10}]
    if {$newC < 0} {
	set newC 0
    }

    if {$newC > 20} {
	set newC 20
    }
    if {($newB != $v(b)) || ($newC != $v(c))} {
	$c move box2 [expr {10*($v(b)-$newB)}] [expr {10*($v(c)-$newC)}]
	set v(b) $newB
	set v(c) $newC
    }
}

# arrowMove3 --
# This procedure is called for each mouse motion event on box3 (the
# one that controls the thickness of the line).  It updates the
# controlling parameters for the line and arrowhead.
#
# Arguments:
# c -		The name of the canvas window.
# x, y -	The coordinates of the mouse.

proc arrowMove3 {c x y} {
    upvar #0 demo_arrowInfo v
    set newWidth [expr {($v(y)+2-round([$c canvasy $y]))/5}]
    if {$newWidth < 0} {
	set newWidth 0
    }

    if {$newWidth > 20} {
	set newWidth 20
    }
    if {$newWidth != $v(width)} {
	$c move box3 0 [expr {5*($v(width)-$newWidth)}]
	set v(width) $newWidth
    }
}







|



>
|
|


















>
|



>
|
|

|



>
|
|



















|



>
|
|






181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#
# Arguments:
# c -		The name of the canvas window.
# x, y -	The coordinates of the mouse.

proc arrowMove1 {c x y} {
    upvar #0 demo_arrowInfo v
    set newA [expr {($v(x2)+[scl 5]-round([$c canvasx $x]))/10}]
    if {$newA < 0} {
	set newA 0
    }
    set _25 [scl 25]
    if {$newA > $_25} {
	set newA $_25
    }
    if {$newA != $v(a)} {
	$c move box1 [expr {10*($v(a)-$newA)}] 0
	set v(a) $newA
    }
}

# arrowMove2 --
# This procedure is called for each mouse motion event on box2 (the
# one at the trailing tip of the arrowhead).  It updates the controlling
# parameters for the line and arrowhead.
#
# Arguments:
# c -		The name of the canvas window.
# x, y -	The coordinates of the mouse.

proc arrowMove2 {c x y} {
    upvar #0 demo_arrowInfo v
    set _5 [scl 5]
    set newB [expr {($v(x2)+$_5-round([$c canvasx $x]))/10}]
    if {$newB < 0} {
	set newB 0
    }
    set _25 [scl 25]
    if {$newB > $_25} {
	set newB $_25
    }
    set newC [expr {($v(y)+$_5-round([$c canvasy $y])-5*$v(width))/10}]
    if {$newC < 0} {
	set newC 0
    }
    set _20 [scl 20]
    if {$newC > $_20} {
	set newC $_20
    }
    if {($newB != $v(b)) || ($newC != $v(c))} {
	$c move box2 [expr {10*($v(b)-$newB)}] [expr {10*($v(c)-$newC)}]
	set v(b) $newB
	set v(c) $newC
    }
}

# arrowMove3 --
# This procedure is called for each mouse motion event on box3 (the
# one that controls the thickness of the line).  It updates the
# controlling parameters for the line and arrowhead.
#
# Arguments:
# c -		The name of the canvas window.
# x, y -	The coordinates of the mouse.

proc arrowMove3 {c x y} {
    upvar #0 demo_arrowInfo v
    set newWidth [expr {($v(y)+[scl 2]-round([$c canvasy $y]))/5}]
    if {$newWidth < 0} {
	set newWidth 0
    }
    set _20 [scl 20]
    if {$newWidth > $_20} {
	set newWidth $_20
    }
    if {$newWidth != $v(width)} {
	$c move box3 0 [expr {5*($v(width)-$newWidth)}]
	set v(width) $newWidth
    }
}

Changes to library/demos/bind.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# bind.tcl --
#
# This demonstration script creates a text widget with bindings set
# up for hypertext-like effects.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .bind
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Tag Bindings"
wm iconname $w "bind"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# bind.tcl --
#
# This demonstration script creates a text widget with bindings set
# up for hypertext-like effects.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .bind
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Tag Bindings"
wm iconname $w "bind"
positionWindow $w

Changes to library/demos/bitmap.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# bitmap.tcl --
#
# This demonstration script creates a toplevel window that displays
# all of Tk's built-in bitmaps.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# bitmapRow --
# Create a row of bitmap items in a window.
#
# Arguments:
# w -		The window that is to contain the row.
# args -	The names of one or more bitmaps, which will be displayed









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# bitmap.tcl --
#
# This demonstration script creates a toplevel window that displays
# all of Tk's built-in bitmaps.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# bitmapRow --
# Create a row of bitmap items in a window.
#
# Arguments:
# w -		The window that is to contain the row.
# args -	The names of one or more bitmaps, which will be displayed

Changes to library/demos/browse.

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+"$@"}

# browse --
# This script generates a directory browser, which lists the working
# directory and allows you to open files or subdirectories by
# double-clicking.

package require Tk

# Create a scrollbar on the right side of the main window and a listbox
# on the left side.

scrollbar .scroll -command ".list yview"
pack .scroll -side right -fill y
listbox .list -yscroll ".scroll set" -relief sunken -width 20 -height 20 \









|







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+"$@"}

# browse --
# This script generates a directory browser, which lists the working
# directory and allows you to open files or subdirectories by
# double-clicking.

package require tk

# Create a scrollbar on the right side of the main window and a listbox
# on the left side.

scrollbar .scroll -command ".list yview"
pack .scroll -side right -fill y
listbox .list -yscroll ".scroll set" -relief sunken -width 20 -height 20 \

Changes to library/demos/button.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# button.tcl --
#
# This demonstration script creates a toplevel window containing
# several button widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .button
catch {destroy $w}
toplevel $w
wm title $w "Button Demonstration"
wm iconname $w "button"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# button.tcl --
#
# This demonstration script creates a toplevel window containing
# several button widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .button
catch {destroy $w}
toplevel $w
wm title $w "Button Demonstration"
wm iconname $w "button"
positionWindow $w
40
41
42
43
44
45
46
47
    -command [list colorrefresh $w PeachPuff1]
button $w.b2 -text "Light Blue" -width 10 \
    -command [list colorrefresh $w LightBlue1]
button $w.b3 -text "Sea Green" -width 10 \
    -command [list colorrefresh $w SeaGreen2]
button $w.b4 -text "Yellow" -width 10 \
    -command [list colorrefresh $w Yellow1]
pack $w.b1 $w.b2 $w.b3 $w.b4 -side top -expand yes -pady 2







|
40
41
42
43
44
45
46
47
    -command [list colorrefresh $w PeachPuff1]
button $w.b2 -text "Light Blue" -width 10 \
    -command [list colorrefresh $w LightBlue1]
button $w.b3 -text "Sea Green" -width 10 \
    -command [list colorrefresh $w SeaGreen2]
button $w.b4 -text "Yellow" -width 10 \
    -command [list colorrefresh $w Yellow1]
pack $w.b1 $w.b2 $w.b3 $w.b4 -side top -expand yes -pady 1.5p

Changes to library/demos/check.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# check.tcl --
#
# This demonstration script creates a toplevel window containing
# several checkbuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .check
catch {destroy $w}
toplevel $w
wm title $w "Checkbutton Demonstration"
wm iconname $w "check"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# check.tcl --
#
# This demonstration script creates a toplevel window containing
# several checkbuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .check
catch {destroy $w}
toplevel $w
wm title $w "Checkbutton Demonstration"
wm iconname $w "check"
positionWindow $w
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
checkbutton $w.b0 -text "Safety Check" -variable safety -relief flat \
    -onvalue "all" \
    -offvalue "none" \
    -tristatevalue "partial"
checkbutton $w.b1 -text "Wipers OK" -variable wipers -relief flat
checkbutton $w.b2 -text "Brakes OK" -variable brakes -relief flat
checkbutton $w.b3 -text "Driver Sober" -variable sober -relief flat
pack $w.b0 -side top -pady 2 -anchor w
pack $w.b1 $w.b2 $w.b3 -side top -pady 2 -anchor w -padx 15

## This code makes $w.b0 function as a tri-state button; it's not
## needed at all for just straight yes/no buttons.

set in_check 0
proc tristate_check {n1 n2 op} {
    global safety wipers brakes sober in_check







|
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
checkbutton $w.b0 -text "Safety Check" -variable safety -relief flat \
    -onvalue "all" \
    -offvalue "none" \
    -tristatevalue "partial"
checkbutton $w.b1 -text "Wipers OK" -variable wipers -relief flat
checkbutton $w.b2 -text "Brakes OK" -variable brakes -relief flat
checkbutton $w.b3 -text "Driver Sober" -variable sober -relief flat
pack $w.b0 -side top -pady 1.5p -anchor w
pack $w.b1 $w.b2 $w.b3 -side top -pady 1.5p -anchor w -padx 12p

## This code makes $w.b0 function as a tri-state button; it's not
## needed at all for just straight yes/no buttons.

set in_check 0
proc tristate_check {n1 n2 op} {
    global safety wipers brakes sober in_check
61
62
63
64
65
66
67
68
69
70
71
	} else {
	    set safety none
	}
    }
    set in_check 0
}

trace variable wipers w tristate_check
trace variable brakes w tristate_check
trace variable sober  w tristate_check
trace variable safety w tristate_check







|
|
|
|
61
62
63
64
65
66
67
68
69
70
71
	} else {
	    set safety none
	}
    }
    set in_check 0
}

trace add variable wipers write tristate_check
trace add variable brakes write tristate_check
trace add variable sober  write tristate_check
trace add variable safety write tristate_check

Changes to library/demos/clrpick.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# clrpick.tcl --
#
# This demonstration script prompts the user to select a color.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .clrpick
catch {destroy $w}
toplevel $w
wm title $w "Color Selection Dialog"
wm iconname $w "colors"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# clrpick.tcl --
#
# This demonstration script prompts the user to select a color.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .clrpick
catch {destroy $w}
toplevel $w
wm title $w "Color Selection Dialog"
wm iconname $w "colors"
positionWindow $w

Changes to library/demos/colors.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
# colors.tcl --
#
# This demonstration script creates a listbox widget that displays
# many of the colors from the X color database.  You can click on
# a color to change the application's palette.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .colors
catch {destroy $w}
toplevel $w
wm title $w "Listbox Demonstration (colors)"
wm iconname $w "Listbox"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing several color names is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by dragging in the listbox window with button 2 pressed.  If you double-click button 1 on a color, then the application's color palette will be set to match that color"
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -expand yes -fill y

scrollbar $w.frame.scroll -command "$w.frame.list yview"
listbox $w.frame.list -yscroll "$w.frame.scroll set" \
	-width 20 -height 16 -setgrid 1
pack $w.frame.list $w.frame.scroll -side left -fill y -expand 1

bind $w.frame.list <Double-Button-1> {
    tk_setPalette [selection get]
}










|















|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# colors.tcl --
#
# This demonstration script creates a listbox widget that displays
# many of the colors from the X color database.  You can click on
# a color to change the application's palette.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .colors
catch {destroy $w}
toplevel $w
wm title $w "Listbox Demonstration (colors)"
wm iconname $w "Listbox"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing several color names is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by dragging in the listbox window with button 2 pressed.  If you double-click button 1 on a color, then the application's color palette will be set to match that color"
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 7.5p
pack $w.frame -side top -expand yes -fill y

ttk::scrollbar $w.frame.scroll -command "$w.frame.list yview"
listbox $w.frame.list -yscroll "$w.frame.scroll set" \
	-width 20 -height 16 -setgrid 1
pack $w.frame.list $w.frame.scroll -side left -fill y -expand 1

bind $w.frame.list <Double-Button-1> {
    tk_setPalette [selection get]
}

Changes to library/demos/combo.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# combo.tcl --
#
# This demonstration script creates several combobox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .combo
catch {destroy $w}
toplevel $w
wm title $w "Combobox Demonstration"
wm iconname $w "combo"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# combo.tcl --
#
# This demonstration script creates several combobox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .combo
catch {destroy $w}
toplevel $w
wm title $w "Combobox Demonstration"
wm iconname $w "combo"
positionWindow $w
52
53
54
55
56
57
58
59
60
61
62
	-values $australianCities
bind $w.c1.c <Return> {
    if {[%W get] ni [%W cget -values]} {
	%W configure -values [concat [%W cget -values] [list [%W get]]]
    }
}

pack $w.c1 $w.c2 $w.c3 -side top -pady 5 -padx 10
pack $w.c1.c -pady 5 -padx 10
pack $w.c2.c -pady 5 -padx 10
pack $w.c3.c -pady 5 -padx 10







|
|
|
|
52
53
54
55
56
57
58
59
60
61
62
	-values $australianCities
bind $w.c1.c <Return> {
    if {[%W get] ni [%W cget -values]} {
	%W configure -values [concat [%W cget -values] [list [%W get]]]
    }
}

pack $w.c1 $w.c2 $w.c3 -side top -pady 3p -padx 7.5p
pack $w.c1.c -pady 3p -padx 7.5p
pack $w.c2.c -pady 3p -padx 7.5p
pack $w.c3.c -pady 3p -padx 7.5p

Changes to library/demos/cscroll.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
# cscroll.tcl --
#
# This demonstration script creates a simple canvas that can be
# scrolled in two dimensions.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .cscroll
catch {destroy $w}
toplevel $w
wm title $w "Scrollable Canvas Demonstration"
wm iconname $w "cscroll"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 4i -justify left -text "This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with button 2 in the canvas.  If you click button 1 on one of the rectangles, its indices will be printed on stdout."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.grid
scrollbar $w.hscroll -orient horiz -command "$c xview"
scrollbar $w.vscroll -command "$c yview"
canvas $c -relief sunken -borderwidth 2 -scrollregion {-11c -11c 50c 20c} \
	-xscrollcommand "$w.hscroll set" \
	-yscrollcommand "$w.vscroll set"
pack $w.grid -expand yes -fill both -padx 1 -pady 1
grid rowconfig    $w.grid 0 -weight 1 -minsize 0
grid columnconfig $w.grid 0 -weight 1 -minsize 0









|









|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# cscroll.tcl --
#
# This demonstration script creates a simple canvas that can be
# scrolled in two dimensions.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .cscroll
catch {destroy $w}
toplevel $w
wm title $w "Scrollable Canvas Demonstration"
wm iconname $w "cscroll"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 4i -justify left -text "This window displays a canvas widget that can be scrolled by using the scrollbars, by dragging with button 2 in the canvas, by using a mouse wheel, or with the two-finger gesture on a touchpad.  If you click button 1 on one of the rectangles, its indices will be printed on stdout."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.grid
scrollbar $w.hscroll -orient horizontal -command "$c xview"
scrollbar $w.vscroll -command "$c yview"
canvas $c -relief sunken -borderwidth 2 -scrollregion {-11c -11c 50c 20c} \
	-xscrollcommand "$w.hscroll set" \
	-yscrollcommand "$w.vscroll set"
pack $w.grid -expand yes -fill both -padx 1 -pady 1
grid rowconfig    $w.grid 0 -weight 1 -minsize 0
grid columnconfig $w.grid 0 -weight 1 -minsize 0
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
	    -anchor center -tags text
    }
}

$c bind all <Enter> "scrollEnter $c"
$c bind all <Leave> "scrollLeave $c"
$c bind all <Button-1> "scrollButton $c"
if {([tk windowingsystem] eq "aqua") && ![package vsatisfies [package provide Tk] 8.7-]} {
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
    bind $c <MouseWheel> {
	%W yview scroll [expr {-%D}] units
    }
    bind $c <Option-MouseWheel> {
	%W yview scroll [expr {-10*%D}] units







|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
	    -anchor center -tags text
    }
}

$c bind all <Enter> "scrollEnter $c"
$c bind all <Leave> "scrollLeave $c"
$c bind all <Button-1> "scrollButton $c"
if {([tk windowingsystem] eq "aqua") && ![package vsatisfies [package provide tk] 8.7-]} {
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
    bind $c <MouseWheel> {
	%W yview scroll [expr {-%D}] units
    }
    bind $c <Option-MouseWheel> {
	%W yview scroll [expr {-10*%D}] units
104
105
106
107
108
109
110




111
112


113
114
115
116
117
118
119
120
121
122
123
124
    bind $c <Shift-Option-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {%D/-3}] units
	} else {
	    %W xview scroll [expr {(%D-2)/-3}] units
	}
    }




}



if {[tk windowingsystem] eq "x11" && ![package vsatisfies [package provide Tk] 8.7-]} {
    # Support for mousewheels on Linux/Unix commonly comes through mapping
    # the wheel to the extended buttons.  If you have a mousewheel, find
    # Linux configuration info at:
    #	http://linuxreviews.org/howtos/xfree/mouse/
    bind $c <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
    }
    bind $c <Shift-Button-4> {
	if {!$tk_strictMotif} {







>
>
>
>
|
|
>
>
|



|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    bind $c <Shift-Option-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {%D/-3}] units
	} else {
	    %W xview scroll [expr {(%D-2)/-3}] units
	}
    }
    bind $c <TouchpadScroll> {
	lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
	if {$deltaX != 0 || $deltaY != 0} {
	    tk::ScrollByPixels %W $deltaX $deltaY
	}
    }
}

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:
    #	https://linuxreviews.org/HOWTO_change_the_mouse_speed_in_X
    bind $c <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
    }
    bind $c <Shift-Button-4> {
	if {!$tk_strictMotif} {

Changes to library/demos/ctext.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ctext.tcl --
#
# This demonstration script creates a canvas widget with a text
# item that can be edited and reconfigured in various ways.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ctext
catch {destroy $w}
toplevel $w
wm title $w "Canvas Text Demonstration"
wm iconname $w "Text"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ctext.tcl --
#
# This demonstration script creates a canvas widget with a text
# item that can be edited and reconfigured in various ways.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ctext
catch {destroy $w}
toplevel $w
wm title $w "Canvas Text Demonstration"
wm iconname $w "Text"
positionWindow $w
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
     the character just after the insertion cursor."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

canvas $c -relief flat -borderwidth 0 -width 500 -height 350
pack $w.c -side top -expand yes -fill both

set textFont {Helvetica 24}

$c create rectangle 245 195 255 205 -outline black -fill red

# First, create the text item and give it bindings so it can be edited.

$c addtag text withtag [$c create text 250 200 -text "This is just a string of text to demonstrate the text facilities of canvas widgets. Bindings have been defined to support editing (see above)." -width 440 -anchor n -font $textFont -justify left]
$c bind text <Button-1> "textB1Press $c %x %y"
$c bind text <B1-Motion> "textB1Move $c %x %y"
$c bind text <Shift-Button-1> "$c select adjust current @%x,%y"
$c bind text <Shift-B1-Motion> "textB1Move $c %x %y"
$c bind text <Key> "textInsert $c %A"
$c bind text <Return> "textInsert $c \\n"
$c bind text <Control-h> "textBs $c"
$c bind text <BackSpace> "textBs $c"
$c bind text <Delete> "textDel $c"
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide Tk] 8.7-]} {
    $c bind text <Button-3> "textPaste $c @%x,%y"
} else {
    $c bind text <Button-2> "textPaste $c @%x,%y"
}

# Next, create some items that allow the text's anchor position
# to be edited.

proc mkTextConfigBox {w x y option value color} {
    set item [$w create rect $x $y [expr {$x+30}] [expr {$y+30}] \
	    -outline black -fill $color -width 1]
    $w bind $item <Button-1> "$w itemconf text $option $value"
    $w addtag config withtag $item
}
proc mkTextConfigPie {w x y a option value color} {
    set item [$w create arc $x $y [expr {$x+90}] [expr {$y+90}] \
	    -start [expr {$a-15}] -extent 30 -outline black -fill $color \
	    -width 1]
    $w bind $item <Button-1> "$w itemconf text $option $value"
    $w addtag config withtag $item
}

set x 50
set y 50
set color LightSkyBlue1
mkTextConfigBox $c $x $y -anchor se $color
mkTextConfigBox $c [expr {$x+30}] [expr {$y   }] -anchor s      $color
mkTextConfigBox $c [expr {$x+60}] [expr {$y   }] -anchor sw     $color
mkTextConfigBox $c [expr {$x   }] [expr {$y+30}] -anchor e      $color
mkTextConfigBox $c [expr {$x+30}] [expr {$y+30}] -anchor center $color
mkTextConfigBox $c [expr {$x+60}] [expr {$y+30}] -anchor w      $color
mkTextConfigBox $c [expr {$x   }] [expr {$y+60}] -anchor ne     $color
mkTextConfigBox $c [expr {$x+30}] [expr {$y+60}] -anchor n      $color
mkTextConfigBox $c [expr {$x+60}] [expr {$y+60}] -anchor nw     $color
set item [$c create rect \
	[expr {$x+40}] [expr {$y+40}] [expr {$x+50}] [expr {$y+50}] \
	-outline black -fill red]
$c bind $item <Button-1> "$c itemconf text -anchor center"
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Text Position}  -anchor s  -font {Times 20}  -fill brown

# Now create some items that allow the text's angle to be changed.

set x 205
set y 50
set color Yellow
mkTextConfigPie $c $x $y   0 -angle  90 $color
mkTextConfigPie $c $x $y  30 -angle 120 $color
mkTextConfigPie $c $x $y  60 -angle 150 $color
mkTextConfigPie $c $x $y  90 -angle 180 $color
mkTextConfigPie $c $x $y 120 -angle 210 $color
mkTextConfigPie $c $x $y 150 -angle 240 $color
mkTextConfigPie $c $x $y 180 -angle 270 $color
mkTextConfigPie $c $x $y 210 -angle 300 $color
mkTextConfigPie $c $x $y 240 -angle 330 $color
mkTextConfigPie $c $x $y 270 -angle   0 $color
mkTextConfigPie $c $x $y 300 -angle  30 $color
mkTextConfigPie $c $x $y 330 -angle  60 $color
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Text Angle}  -anchor s  -font {Times 20}  -fill brown

# Lastly, create some items that allow the text's justification to be
# changed.

set x 350
set y 50
set color SeaGreen2
mkTextConfigBox $c $x $y -justify left $color
mkTextConfigBox $c [expr {$x+30}] $y -justify center $color
mkTextConfigBox $c [expr {$x+60}] $y -justify right $color
$c create text [expr {$x+45}] [expr {$y-5}] \
	-text {Justification}  -anchor s  -font {Times 20}  -fill brown

$c bind config <Enter> "textEnter $c"
$c bind config <Leave> "$c itemconf current -fill \$textConfigFill"

set textConfigFill {}








|




|



|









|








|
|
|



|
|

|




|
|


|
|
|
|
|
|
|
|

|


|




|
|













|
|




|
|


|
|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
     the character just after the insertion cursor."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

canvas $c -relief flat -borderwidth 0 -width 375p -height 262.5p
pack $w.c -side top -expand yes -fill both

set textFont {Helvetica 24}

$c create rectangle 183.75p 122.25p 191.25p 129.75p -outline black -fill red

# First, create the text item and give it bindings so it can be edited.

$c addtag text withtag [$c create text 187.5p 126p -text "This is just a string of text to demonstrate the text facilities of canvas widgets. Bindings have been defined to support editing (see above)." -width 330p -anchor n -font $textFont -justify left]
$c bind text <Button-1> "textB1Press $c %x %y"
$c bind text <B1-Motion> "textB1Move $c %x %y"
$c bind text <Shift-Button-1> "$c select adjust current @%x,%y"
$c bind text <Shift-B1-Motion> "textB1Move $c %x %y"
$c bind text <Key> "textInsert $c %A"
$c bind text <Return> "textInsert $c \\n"
$c bind text <Control-h> "textBs $c"
$c bind text <BackSpace> "textBs $c"
$c bind text <Delete> "textDel $c"
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide tk] 8.7-]} {
    $c bind text <Button-3> "textPaste $c @%x,%y"
} else {
    $c bind text <Button-2> "textPaste $c @%x,%y"
}

# Next, create some items that allow the text's anchor position
# to be edited.

proc mkTextConfigBox {w x y option value color} {	;# x, y are in points
    set item [$w create rect ${x}p ${y}p [expr {$x+22.5}]p [expr {$y+22.5}]p \
	    -outline black -fill $color -width 0.75p]
    $w bind $item <Button-1> "$w itemconf text $option $value"
    $w addtag config withtag $item
}
proc mkTextConfigPie {w x y a option value color} {	;# x, y are in points
    set item [$w create arc ${x}p ${y}p [expr {$x+67.5}]p [expr {$y+67.5}]p \
	    -start [expr {$a-15}] -extent 30 -outline black -fill $color \
	    -width 0.75p]
    $w bind $item <Button-1> "$w itemconf text $option $value"
    $w addtag config withtag $item
}

set x 37.5	;# in points
set y 37.5	;# in points
set color LightSkyBlue1
mkTextConfigBox $c $x $y -anchor se $color
mkTextConfigBox $c [expr {$x+22.5}] [expr {$y     }] -anchor s      $color
mkTextConfigBox $c [expr {$x+45  }] [expr {$y     }] -anchor sw     $color
mkTextConfigBox $c [expr {$x     }] [expr {$y+22.5}] -anchor e      $color
mkTextConfigBox $c [expr {$x+22.5}] [expr {$y+22.5}] -anchor center $color
mkTextConfigBox $c [expr {$x+45  }] [expr {$y+22.5}] -anchor w      $color
mkTextConfigBox $c [expr {$x     }] [expr {$y+45  }] -anchor ne     $color
mkTextConfigBox $c [expr {$x+22.5}] [expr {$y+45  }] -anchor n      $color
mkTextConfigBox $c [expr {$x+45  }] [expr {$y+45  }] -anchor nw     $color
set item [$c create rect \
	[expr {$x+30}]p [expr {$y+30}]p [expr {$x+37.5}]p [expr {$y+37.5}]p \
	-outline black -fill red]
$c bind $item <Button-1> "$c itemconf text -anchor center"
$c create text [expr {$x+33.75}]p [expr {$y-3.75}]p \
	-text {Text Position}  -anchor s  -font {Times 20}  -fill brown

# Now create some items that allow the text's angle to be changed.

set x 153.75	;# in points
set y 37.5	;# in points
set color Yellow
mkTextConfigPie $c $x $y   0 -angle  90 $color
mkTextConfigPie $c $x $y  30 -angle 120 $color
mkTextConfigPie $c $x $y  60 -angle 150 $color
mkTextConfigPie $c $x $y  90 -angle 180 $color
mkTextConfigPie $c $x $y 120 -angle 210 $color
mkTextConfigPie $c $x $y 150 -angle 240 $color
mkTextConfigPie $c $x $y 180 -angle 270 $color
mkTextConfigPie $c $x $y 210 -angle 300 $color
mkTextConfigPie $c $x $y 240 -angle 330 $color
mkTextConfigPie $c $x $y 270 -angle   0 $color
mkTextConfigPie $c $x $y 300 -angle  30 $color
mkTextConfigPie $c $x $y 330 -angle  60 $color
$c create text [expr {$x+33.75}]p [expr {$y-3.75}]p \
	-text {Text Angle}     -anchor s  -font {Times 20}  -fill brown

# Lastly, create some items that allow the text's justification to be
# changed.

set x 262.5	;# in points
set y 37.5	;# in points
set color SeaGreen2
mkTextConfigBox $c $x $y -justify left $color
mkTextConfigBox $c [expr {$x+22.5}] $y -justify center $color
mkTextConfigBox $c [expr {$x+45}] $y -justify right $color
$c create text [expr {$x+33.75}]p [expr {$y-3.75}]p \
	-text {Justification}  -anchor s  -font {Times 20}  -fill brown

$c bind config <Enter> "textEnter $c"
$c bind config <Leave> "$c itemconf current -fill \$textConfigFill"

set textConfigFill {}

Changes to library/demos/en.msg.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60

61
62
63
64
65
66

67
68
69
70
71
72

73
74
75
76
77
78
79
80

81
82
83

84
85
86
87
88
89
90
91
92
93








94
95
96
97

::msgcat::mcset en "Widget Demonstration"
::msgcat::mcset en "tkWidgetDemo"
::msgcat::mcset en "&File"
::msgcat::mcset en "About..."
::msgcat::mcset en "&About..."
::msgcat::mcset en "<F1>"
::msgcat::mcset en "&Quit"
::msgcat::mcset en "Meta+Q"		;# Displayed hotkey
::msgcat::mcset en "Meta-q"		;# Actual binding sequence
::msgcat::mcset en "Ctrl+Q"		;# Displayed hotkey
::msgcat::mcset en "Control-q"		;# Actual binding sequence

::msgcat::mcset en "Variable values"
::msgcat::mcset en "Variable values:"
::msgcat::mcset en "OK"
::msgcat::mcset en "Run the \"%s\" sample program"
::msgcat::mcset en "Dismiss"
::msgcat::mcset en "Rerun Demo"

::msgcat::mcset en "Demo code: %s"
::msgcat::mcset en "About Widget Demo"
::msgcat::mcset en "Tk widget demonstration application"
::msgcat::mcset en "Copyright © %s"
::msgcat::mcset en "
    @@title
    Tk Widget Demonstrations
    @@newline
    @@normal
    @@newline


    This application provides a front end for several short scripts
    that demonstrate what you can do with Tk widgets.  Each of the
    numbered lines below describes a demonstration;  you can click on
    it to invoke the demonstration.  Once the demonstration window
    appears, you can click the
    @@bold
    See Code
    @@normal
    button to see the Tcl/Tk code that created the demonstration.  If
    you wish, you can edit the code and click the
    @@bold
    Rerun Demo
    @@normal
    button in the code window to reinvoke the demonstration with the
    modified code.
    @@newline
"
::msgcat::mcset en "Labels, buttons, checkbuttons, and radiobuttons"
::msgcat::mcset en "Labels (text and bitmaps)"
::msgcat::mcset en "Labels and UNICODE text"
::msgcat::mcset en "Buttons"
::msgcat::mcset en "Check-buttons (select any of a group)"
::msgcat::mcset en "Radio-buttons (select one of a group)"
::msgcat::mcset en "A 15-puzzle game made out of buttons"
::msgcat::mcset en "Iconic buttons that use bitmaps"
::msgcat::mcset en "Two labels displaying images"
::msgcat::mcset en "A simple user interface for viewing images"
::msgcat::mcset en "Labelled frames"

::msgcat::mcset en "Listboxes"
::msgcat::mcset en "The 50 states"
::msgcat::mcset en "Colors: change the color scheme for the application"
::msgcat::mcset en "A collection of famous and infamous sayings"

::msgcat::mcset en "Entries and Spin-boxes"
::msgcat::mcset en "Entries without scrollbars"
::msgcat::mcset en "Entries with scrollbars"
::msgcat::mcset en "Validated entries and password fields"
::msgcat::mcset en "Spin-boxes"
::msgcat::mcset en "Simple Rolodex-like form"

::msgcat::mcset en "Text"
::msgcat::mcset en "Basic editable text"
::msgcat::mcset en "Text display styles"
::msgcat::mcset en "Hypertext (tag bindings)"
::msgcat::mcset en "A text widget with embedded windows"
::msgcat::mcset en "A search tool built with a text widget"

::msgcat::mcset en "Canvases"
::msgcat::mcset en "The canvas item types"
::msgcat::mcset en "A simple 2-D plot"
::msgcat::mcset en "Text items in canvases"
::msgcat::mcset en "An editor for arrowheads on canvas lines"
::msgcat::mcset en "A ruler with adjustable tab stops"
::msgcat::mcset en "A building floor plan"
::msgcat::mcset en "A simple scrollable canvas"

::msgcat::mcset en "Scales"
::msgcat::mcset en "Horizontal scale"
::msgcat::mcset en "Vertical scale"

::msgcat::mcset en "Paned Windows"
::msgcat::mcset en "Horizontal paned window"
::msgcat::mcset en "Vertical paned window"
::msgcat::mcset en "Menus"
::msgcat::mcset en "Menus and cascades (sub-menus)"
::msgcat::mcset en "Menu-buttons"
::msgcat::mcset en "Common Dialogs"
::msgcat::mcset en "Message boxes"
::msgcat::mcset en "File selection dialog"
::msgcat::mcset en "Color picker"








::msgcat::mcset en "Miscellaneous"
::msgcat::mcset en "The built-in bitmaps"
::msgcat::mcset en "A dialog box with a local grab"
::msgcat::mcset en "A dialog box with a global grab"












>






>


|

<
<
<
<
<
<

>
|
|
|
|
|
<
|
<
|
|
<
<
<
|
|
<
|











>




>






>






>








>



>










>
>
>
>
>
>
>
>




>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23






24
25
26
27
28
29
30

31

32
33



34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
::msgcat::mcset en "Widget Demonstration"
::msgcat::mcset en "tkWidgetDemo"
::msgcat::mcset en "&File"
::msgcat::mcset en "About..."
::msgcat::mcset en "&About..."
::msgcat::mcset en "<F1>"
::msgcat::mcset en "&Quit"
::msgcat::mcset en "Meta+Q"		;# Displayed hotkey
::msgcat::mcset en "Meta-q"		;# Actual binding sequence
::msgcat::mcset en "Ctrl+Q"		;# Displayed hotkey
::msgcat::mcset en "Control-q"		;# Actual binding sequence
::msgcat::mcset en "See Variables"
::msgcat::mcset en "Variable values"
::msgcat::mcset en "Variable values:"
::msgcat::mcset en "OK"
::msgcat::mcset en "Run the \"%s\" sample program"
::msgcat::mcset en "Dismiss"
::msgcat::mcset en "Rerun Demo"
::msgcat::mcset en "Print Code"
::msgcat::mcset en "Demo code: %s"
::msgcat::mcset en "About Widget Demo"
::msgcat::mcset en "Tk widget demonstration"
::msgcat::mcset en "Copyright © %s"







::msgcat::mcset en "Tk Widget Demonstrations"
::msgcat::mcset en "This application provides a front end for several short scripts"
::msgcat::mcset en "that demonstrate what you can do with Tk widgets.  Each of the"
::msgcat::mcset en "numbered lines below describes a demonstration;  you can click on"
::msgcat::mcset en "it to invoke the demonstration.  Once the demonstration window"
::msgcat::mcset en "appears, you can click the"

::msgcat::mcset en "See Code"  "See Code"	;# This is also button text!

::msgcat::mcset en "button to see the Tcl/Tk code that created the demonstration.  If"
::msgcat::mcset en "you wish, you can edit the code and click the"



::msgcat::mcset en "button in the code window to reinvoke the demonstration with the"
::msgcat::mcset en "modified code."


::msgcat::mcset en "Labels, buttons, checkbuttons, and radiobuttons"
::msgcat::mcset en "Labels (text and bitmaps)"
::msgcat::mcset en "Labels and UNICODE text"
::msgcat::mcset en "Buttons"
::msgcat::mcset en "Check-buttons (select any of a group)"
::msgcat::mcset en "Radio-buttons (select one of a group)"
::msgcat::mcset en "A 15-puzzle game made out of buttons"
::msgcat::mcset en "Iconic buttons that use bitmaps"
::msgcat::mcset en "Two labels displaying images"
::msgcat::mcset en "A simple user interface for viewing images"
::msgcat::mcset en "Labelled frames"

::msgcat::mcset en "Listboxes"
::msgcat::mcset en "The 50 states"
::msgcat::mcset en "Colors: change the color scheme for the application"
::msgcat::mcset en "A collection of famous and infamous sayings"

::msgcat::mcset en "Entries and Spin-boxes"
::msgcat::mcset en "Entries without scrollbars"
::msgcat::mcset en "Entries with scrollbars"
::msgcat::mcset en "Validated entries and password fields"
::msgcat::mcset en "Spin-boxes"
::msgcat::mcset en "Simple Rolodex-like form"

::msgcat::mcset en "Text"
::msgcat::mcset en "Basic editable text"
::msgcat::mcset en "Text display styles"
::msgcat::mcset en "Hypertext (tag bindings)"
::msgcat::mcset en "A text widget with embedded windows"
::msgcat::mcset en "A search tool built with a text widget"

::msgcat::mcset en "Canvases"
::msgcat::mcset en "The canvas item types"
::msgcat::mcset en "A simple 2-D plot"
::msgcat::mcset en "Text items in canvases"
::msgcat::mcset en "An editor for arrowheads on canvas lines"
::msgcat::mcset en "A ruler with adjustable tab stops"
::msgcat::mcset en "A building floor plan"
::msgcat::mcset en "A simple scrollable canvas"

::msgcat::mcset en "Scales"
::msgcat::mcset en "Horizontal scale"
::msgcat::mcset en "Vertical scale"

::msgcat::mcset en "Paned Windows"
::msgcat::mcset en "Horizontal paned window"
::msgcat::mcset en "Vertical paned window"
::msgcat::mcset en "Menus"
::msgcat::mcset en "Menus and cascades (sub-menus)"
::msgcat::mcset en "Menu-buttons"
::msgcat::mcset en "Common Dialogs"
::msgcat::mcset en "Message boxes"
::msgcat::mcset en "File selection dialog"
::msgcat::mcset en "Color picker"
::msgcat::mcset en "Font selection dialog"
::msgcat::mcset en "System tray icon and notification"
::msgcat::mcset en "Printing from canvas and text widgets"
::msgcat::mcset en "Animation"
::msgcat::mcset en "Animated labels"
::msgcat::mcset en "Animated wave"
::msgcat::mcset en "Pendulum simulation"
::msgcat::mcset en "A celebration of Rube Goldberg"
::msgcat::mcset en "Miscellaneous"
::msgcat::mcset en "The built-in bitmaps"
::msgcat::mcset en "A dialog box with a local grab"
::msgcat::mcset en "A dialog box with a global grab"
::msgcat::mcset en "Window icons and badges"

Changes to library/demos/entry1.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
# entry1.tcl --
#
# This demonstration script creates several entry widgets without
# scrollbars.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .entry1
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (no scrollbars)"
wm iconname $w "entry1"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse the middle mouse button pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

entry $w.e1
entry $w.e2
entry $w.e3 -placeholder {Enter text here} -placeholderforeground gray75
pack $w.e1 $w.e2 $w.e3 -side top -pady 5 -padx 10 -fill x

$w.e1 insert 0 "Initial value"
$w.e2 insert end "This entry contains a long value, much too long "
$w.e2 insert end "to fit in the window at one time, so long in fact "
$w.e2 insert end "that you'll have to scan or scroll to see the end."









|


















|





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# entry1.tcl --
#
# This demonstration script creates several entry widgets without
# scrollbars.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .entry1
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (no scrollbars)"
wm iconname $w "entry1"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse the middle mouse button pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

entry $w.e1
entry $w.e2
entry $w.e3 -placeholder {Enter text here} -placeholderforeground gray75
pack $w.e1 $w.e2 $w.e3 -side top -pady 3p -padx 7.5p -fill x

$w.e1 insert 0 "Initial value"
$w.e2 insert end "This entry contains a long value, much too long "
$w.e2 insert end "to fit in the window at one time, so long in fact "
$w.e2 insert end "that you'll have to scan or scroll to see the end."

Changes to library/demos/entry2.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# entry2.tcl --
#
# This demonstration script is the same as the entry1.tcl script
# except that it creates scrollbars for the entries.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .entry2
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (with scrollbars)"
wm iconname $w "entry2"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below, with a scrollbar for each entry.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries with the scrollbars, or by dragging with the middle mouse button pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -fill x -expand 1

entry $w.frame.e1 -xscrollcommand "$w.frame.s1 set"
ttk::scrollbar $w.frame.s1 -orient horiz -command \
	"$w.frame.e1 xview"
frame $w.frame.spacer1 -width 20 -height 10
entry $w.frame.e2 -xscrollcommand "$w.frame.s2 set"
ttk::scrollbar $w.frame.s2 -orient horiz -command \
	"$w.frame.e2 xview"
frame $w.frame.spacer2 -width 20 -height 10
entry $w.frame.e3 -xscrollcommand "$w.frame.s3 set"
ttk::scrollbar $w.frame.s3 -orient horiz -command \
	"$w.frame.e3 xview"
pack $w.frame.e1 $w.frame.s1 $w.frame.spacer1 $w.frame.e2 $w.frame.s2 \
	$w.frame.spacer2 $w.frame.e3 $w.frame.s3 -side top -fill x

$w.frame.e1 insert 0 "Initial value"
$w.frame.e2 insert end "This entry contains a long value, much too long "
$w.frame.e2 insert end "to fit in the window at one time, so long in fact "
$w.frame.e2 insert end "that you'll have to scan or scroll to see the end."
$w.frame.e3 configure -placeholder {Enter text here} -placeholderforeground gray75









|















|



|

|

|

|

|









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# entry2.tcl --
#
# This demonstration script is the same as the entry1.tcl script
# except that it creates scrollbars for the entries.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .entry2
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration (with scrollbars)"
wm iconname $w "entry2"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different entries are displayed below, with a scrollbar for each entry.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries with the scrollbars, or by dragging with the middle mouse button pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 7.5p
pack $w.frame -side top -fill x -expand 1

entry $w.frame.e1 -xscrollcommand "$w.frame.s1 set"
ttk::scrollbar $w.frame.s1 -orient horizontal -command \
	"$w.frame.e1 xview"
frame $w.frame.spacer1 -width 15p -height 7.5p
entry $w.frame.e2 -xscrollcommand "$w.frame.s2 set"
ttk::scrollbar $w.frame.s2 -orient horizontal -command \
	"$w.frame.e2 xview"
frame $w.frame.spacer2 -width 15p -height 7.5p
entry $w.frame.e3 -xscrollcommand "$w.frame.s3 set"
ttk::scrollbar $w.frame.s3 -orient horizontal -command \
	"$w.frame.e3 xview"
pack $w.frame.e1 $w.frame.s1 $w.frame.spacer1 $w.frame.e2 $w.frame.s2 \
	$w.frame.spacer2 $w.frame.e3 $w.frame.s3 -side top -fill x

$w.frame.e1 insert 0 "Initial value"
$w.frame.e2 insert end "This entry contains a long value, much too long "
$w.frame.e2 insert end "to fit in the window at one time, so long in fact "
$w.frame.e2 insert end "that you'll have to scan or scroll to see the end."
$w.frame.e3 configure -placeholder {Enter text here} -placeholderforeground gray75

Changes to library/demos/entry3.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# entry3.tcl --
#
# This demonstration script creates several entry widgets whose
# permitted input is constrained in some way.  It also shows off a
# password entry.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .entry3
catch {destroy $w}
toplevel $w
wm title $w "Constrained Entry Demonstration"
wm iconname $w "entry3"
positionWindow $w










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# entry3.tcl --
#
# This demonstration script creates several entry widgets whose
# permitted input is constrained in some way.  It also shows off a
# password entry.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .entry3
catch {destroy $w}
toplevel $w
wm title $w "Constrained Entry Demonstration"
wm iconname $w "entry3"
positionWindow $w
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}
$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}}
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







|





|







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 -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 -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
157
158
159
160
161
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}
# Click to focus goes to the first editable character...
bind $w.l3.e <FocusIn> {
    if {"%d" ne "NotifyAncestor"} {
	%W icursor 3
	after idle {%W selection clear}
    }
}
bind $w.l3.e <<PrevChar>> {phoneSkipLeft  %W}
bind $w.l3.e <<NextChar>> {phoneSkipRight %W}
pack $w.l3.e -fill x -expand 1 -padx 1m -pady 1m

labelframe $w.l4 -text "Password Entry"
entry $w.l4.e -validate key -show "*" -vcmd {expr {[string length %P]<=8}}
pack $w.l4.e -fill x -expand 1 -padx 1m -pady 1m

lower [frame $w.mid]
grid $w.l1 $w.l2 -in $w.mid -padx 3m -pady 1m -sticky ew
grid $w.l3 $w.l4 -in $w.mid -padx 3m -pady 1m -sticky ew
grid columnconfigure $w.mid {0 1} -uniform 1
pack $w.msg -side top
pack $w.mid -fill both -expand 1







|












|








157
158
159
160
161
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 \
	-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 "*" -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/filebox.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
# filebox.tcl --
#
# This demonstration script prompts the user to select a file.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .filebox
catch {destroy $w}
toplevel $w
wm title $w "File Selection Dialogs"
wm iconname $w "filebox"
positionWindow $w

ttk::frame $w._bg
place $w._bg -x 0 -y 0 -relwidth 1 -relheight 1

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Enter a file name in the entry box or click on the \"Browse\" buttons to select a file name using the file selection dialog."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x


foreach i {open save} {
    set f [ttk::frame $w.$i]
    ttk::label $f.lab -text "Select a file to $i: " -anchor e
    ttk::entry $f.ent -width 20
    ttk::button $f.but -text "Browse ..." -command "fileDialog $w $f.ent $i"
    pack $f.lab -side left
    pack $f.ent -side left -expand yes -fill x
    pack $f.but -side left
    pack $f -fill x -padx 1c -pady 3
}



if {[tk windowingsystem] eq "x11"} {
    ttk::checkbutton $w.strict -text "Use Motif Style Dialog" \
	-variable tk_strictMotif -onvalue 1 -offvalue 0
    pack $w.strict -anchor c

    # This binding ensures that we don't run the rest of the demos








|


















>

<
|
|
|
<
|
|
|

>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
# filebox.tcl --
#
# This demonstration script prompts the user to select a file.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .filebox
catch {destroy $w}
toplevel $w
wm title $w "File Selection Dialogs"
wm iconname $w "filebox"
positionWindow $w

ttk::frame $w._bg
place $w._bg -x 0 -y 0 -relwidth 1 -relheight 1

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Enter a file name in the entry box or click on the \"Browse\" buttons to select a file name using the file selection dialog."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set f [ttk::frame $w.f]
foreach i {open save} {

    ttk::label $f.lab_$i -text "Select a file to $i:"
    ttk::entry $f.ent_$i -width 20
    ttk::button $f.but_$i -text "Browse ..." -command \

	    "fileDialog $w $f.ent_$i $i"
    grid $f.lab_$i $f.ent_$i $f.but_$i -pady 3p -sticky w
    grid configure $f.ent_$i -padx 3p -sticky ew
}
grid columnconfigure $f 1 -weight 1
pack $f -fill x -padx 1c

if {[tk windowingsystem] eq "x11"} {
    ttk::checkbutton $w.strict -text "Use Motif Style Dialog" \
	-variable tk_strictMotif -onvalue 1 -offvalue 0
    pack $w.strict -anchor c

    # This binding ensures that we don't run the rest of the demos

Changes to library/demos/floor.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# floor.tcl --
#
# This demonstration script creates a canvas widet that displays the
# floorplan for DEC's Western Research Laboratory.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# floorDisplay --
# Recreate the floorplan display in the canvas given by "w".  The
# floor given by "active" is displayed on top with its office structure
# visible.
#
# Arguments:









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# floor.tcl --
#
# This demonstration script creates a canvas widet that displays the
# floorplan for DEC's Western Research Laboratory.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# floorDisplay --
# Recreate the floorplan display in the canvas given by "w".  The
# floor given by "active" is displayed on top with its office structure
# visible.
#
# Arguments:
48
49
50
51
52
53
54






55
56
57
58
59
60
61
62
63
64



65





66
67
68
69
70
71
72
    # transparent polygons that define the rooms on the floor.
    # Make sure that the room polygons are on top.

    catch {unset floorLabels}
    catch {unset floorItems}
    fg$active $w $colors(offices)
    $w raise room







    # Offset the floors diagonally from each other.

    $w move floor1 2c 2c
    $w move floor2 1c 1c

    # Create items for the room entry and its label.

    $w create window 600 100 -anchor w -window $w.entry
    $w create text 600 100 -anchor e -text "Room: "



    $w config -scrollregion [$w bbox all]





}

# newRoom --
# This procedure is invoked whenever the mouse enters a room
# in the floorplan.  It changes tags so that the current room is
# highlighted.
#







>
>
>
>
>
>








|
|
>
>
>
|
>
>
>
>
>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    # transparent polygons that define the rooms on the floor.
    # Make sure that the room polygons are on top.

    catch {unset floorLabels}
    catch {unset floorItems}
    fg$active $w $colors(offices)
    $w raise room

    # Rescale the coordinates in pixels of all of the
    # items according to the display's DPI scaling level.

    set scaleFactor [expr {$tk::scalingPct / 100.0}]
    $w scale all 0 0 $scaleFactor $scaleFactor

    # Offset the floors diagonally from each other.

    $w move floor1 2c 2c
    $w move floor2 1c 1c

    # Create items for the room entry and its label.

    $w create window 450p 75p -anchor w -window $w.entry
    $w create text 450p 75p -anchor e -text "Room: "

    # Configure the canvas.

    set bbox [$w bbox all]
    lassign $bbox x1 y1 x2 y2
    set morePx [expr {round(20 * $tk::scalingPct / 100.0)}]
    set width  [expr {$x2 - $x1 + $morePx}]
    set height [expr {$y2 - $y1 + $morePx}]
    $w configure -scrollregion $bbox -width $width -height $height
}

# newRoom --
# This procedure is invoked whenever the mouse enters a room
# in the floorplan.  It changes tags so that the current room is
# highlighted.
#
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg1 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 375 246 375 172 341 172 341 246 -outline {} -tags {floor1 room}]
    set floorLabels($i) 101
    set {floorItems(101)} $i
    $w create text 358 209 -text 101 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Pub Lift1}
    set {floorItems(Pub Lift1)} $i
    $w create text 323 223 -text {Pub Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Priv Lift1}
    set {floorItems(Priv Lift1)} $i
    $w create text 323 188 -text {Priv Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 42 389 42 337 1 337 1 389 -outline {} -tags {floor1 room}]
    set floorLabels($i) 110
    set {floorItems(110)} $i
    $w create text 21.5 363 -text 110 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 59 389 59 385 90 385 90 337 44 337 44 389 -outline {} -tags {floor1 room}]
    set floorLabels($i) 109
    set {floorItems(109)} $i
    $w create text 67 363 -text 109 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 300 51 253 6 253 6 300 -outline {} -tags {floor1 room}]
    set floorLabels($i) 111
    set {floorItems(111)} $i
    $w create text 28.5 276.5 -text 111 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 98 248 98 309 79 309 79 248 -outline {} -tags {floor1 room}]
    set floorLabels($i) 117B
    set {floorItems(117B)} $i
    $w create text 88.5 278.5 -text 117B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 251 51 204 6 204 6 251 -outline {} -tags {floor1 room}]
    set floorLabels($i) 112
    set {floorItems(112)} $i
    $w create text 28.5 227.5 -text 112 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 6 156 51 156 51 203 6 203 -outline {} -tags {floor1 room}]
    set floorLabels($i) 113
    set {floorItems(113)} $i
    $w create text 28.5 179.5 -text 113 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 85 169 79 169 79 192 85 192 -outline {} -tags {floor1 room}]
    set floorLabels($i) 117A
    set {floorItems(117A)} $i
    $w create text 82 180.5 -text 117A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 77 302 77 168 53 168 53 302 -outline {} -tags {floor1 room}]
    set floorLabels($i) 117
    set {floorItems(117)} $i
    $w create text 65 235 -text 117 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 155 51 115 6 115 6 155 -outline {} -tags {floor1 room}]
    set floorLabels($i) 114
    set {floorItems(114)} $i
    $w create text 28.5 135 -text 114 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 95 115 53 115 53 168 95 168 -outline {} -tags {floor1 room}]
    set floorLabels($i) 115
    set {floorItems(115)} $i
    $w create text 74 141.5 -text 115 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 87 113 87 27 10 27 10 113 -outline {} -tags {floor1 room}]
    set floorLabels($i) 116
    set {floorItems(116)} $i
    $w create text 48.5 70 -text 116 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 89 91 128 91 128 113 89 113 -outline {} -tags {floor1 room}]
    set floorLabels($i) 118
    set {floorItems(118)} $i
    $w create text 108.5 102 -text 118 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 178 128 178 132 216 132 216 91 163 91 163 112 149 112 149 128 -outline {} -tags {floor1 room}]
    set floorLabels($i) 120
    set {floorItems(120)} $i
    $w create text 189.5 111.5 -text 120 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 79 193 87 193 87 169 136 169 136 192 156 192 156 169 175 169 175 246 79 246 -outline {} -tags {floor1 room}]
    set floorLabels($i) 122
    set {floorItems(122)} $i
    $w create text 131 207.5 -text 122 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 169 154 169 154 191 138 191 -outline {} -tags {floor1 room}]
    set floorLabels($i) 121
    set {floorItems(121)} $i
    $w create text 146 180 -text 121 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 99 300 126 300 126 309 99 309 -outline {} -tags {floor1 room}]
    set floorLabels($i) 106A
    set {floorItems(106A)} $i
    $w create text 112.5 304.5 -text 106A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 128 299 128 309 150 309 150 248 99 248 99 299 -outline {} -tags {floor1 room}]
    set floorLabels($i) 105
    set {floorItems(105)} $i
    $w create text 124.5 278.5 -text 105 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 174 309 174 300 152 300 152 309 -outline {} -tags {floor1 room}]
    set floorLabels($i) 106B
    set {floorItems(106B)} $i
    $w create text 163 304.5 -text 106B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 176 299 176 309 216 309 216 248 152 248 152 299 -outline {} -tags {floor1 room}]
    set floorLabels($i) 104
    set {floorItems(104)} $i
    $w create text 184 278.5 -text 104 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 385 138 337 91 337 91 385 -outline {} -tags {floor1 room}]
    set floorLabels($i) 108
    set {floorItems(108)} $i
    $w create text 114.5 361 -text 108 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 256 337 140 337 140 385 256 385 -outline {} -tags {floor1 room}]
    set floorLabels($i) 107
    set {floorItems(107)} $i
    $w create text 198 361 -text 107 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 300 353 300 329 260 329 260 353 -outline {} -tags {floor1 room}]
    set floorLabels($i) Smoking
    set {floorItems(Smoking)} $i
    $w create text 280 341 -text Smoking -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 314 135 314 170 306 170 306 246 177 246 177 135 -outline {} -tags {floor1 room}]
    set floorLabels($i) 123
    set {floorItems(123)} $i
    $w create text 245.5 190.5 -text 123 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 217 248 301 248 301 326 257 326 257 310 217 310 -outline {} -tags {floor1 room}]
    set floorLabels($i) 103
    set {floorItems(103)} $i
    $w create text 259 287 -text 103 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 396 188 377 188 377 169 316 169 316 131 396 131 -outline {} -tags {floor1 room}]
    set floorLabels($i) 124
    set {floorItems(124)} $i
    $w create text 356 150 -text 124 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 226 407 226 407 189 377 189 377 246 397 246 -outline {} -tags {floor1 room}]
    set floorLabels($i) 125
    set {floorItems(125)} $i
    $w create text 392 217.5 -text 125 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 399 187 409 187 409 207 474 207 474 164 399 164 -outline {} -tags {floor1 room}]
    set floorLabels($i) 126
    set {floorItems(126)} $i
    $w create text 436.5 185.5 -text 126 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 409 209 409 229 399 229 399 253 486 253 486 239 474 239 474 209 -outline {} -tags {floor1 room}]
    set floorLabels($i) 127
    set {floorItems(127)} $i
    $w create text 436.5 231 -text 127 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 501 164 501 174 495 174 495 188 490 188 490 204 476 204 476 164 -outline {} -tags {floor1 room}]
    set floorLabels($i) MShower
    set {floorItems(MShower)} $i
    $w create text 488.5 184 -text MShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 497 176 513 176 513 204 492 204 492 190 497 190 -outline {} -tags {floor1 room}]
    set floorLabels($i) Closet
    set {floorItems(Closet)} $i
    $w create text 502.5 190 -text Closet -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 476 237 476 206 513 206 513 254 488 254 488 237 -outline {} -tags {floor1 room}]
    set floorLabels($i) WShower
    set {floorItems(WShower)} $i
    $w create text 494.5 230 -text WShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 486 131 558 131 558 135 724 135 724 166 697 166 697 275 553 275 531 254 515 254 515 174 503 174 503 161 486 161 -outline {} -tags {floor1 room}]
    set floorLabels($i) 130
    set {floorItems(130)} $i
    $w create text 638.5 205 -text 130 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 308 242 339 242 339 248 342 248 342 246 397 246 397 276 393 276 393 309 300 309 300 248 308 248 -outline {} -tags {floor1 room}]
    set floorLabels($i) 102
    set {floorItems(102)} $i
    $w create text 367.5 278.5 -text 102 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 255 486 255 486 276 397 276 -outline {} -tags {floor1 room}]
    set floorLabels($i) 128
    set {floorItems(128)} $i
    $w create text 441.5 265.5 -text 128 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 510 309 486 309 486 255 530 255 552 277 561 277 561 325 510 325 -outline {} -tags {floor1 room}]
    set floorLabels($i) 129
    set {floorItems(129)} $i
    $w create text 535.5 293 -text 129 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 696 281 740 281 740 387 642 387 642 389 561 389 561 277 696 277 -outline {} -tags {floor1 room}]
    set floorLabels($i) 133
    set {floorItems(133)} $i
    $w create text 628.5 335 -text 133 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 742 387 742 281 800 281 800 387 -outline {} -tags {floor1 room}]
    set floorLabels($i) 132
    set {floorItems(132)} $i
    $w create text 771 334 -text 132 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 800 168 800 280 699 280 699 168 -outline {} -tags {floor1 room}]
    set floorLabels($i) 134
    set {floorItems(134)} $i
    $w create text 749.5 224 -text 134 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 726 131 726 166 800 166 800 131 -outline {} -tags {floor1 room}]
    set floorLabels($i) 135
    set {floorItems(135)} $i
    $w create text 763 148.5 -text 135 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 340 360 335 363 331 365 326 366 304 366 304 312 396 312 396 288 400 288 404 288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 342 331 347 332 351 334 354 336 357 341 359 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Ramona Stair}
    set {floorItems(Ramona Stair)} $i
    $w create text 368 323 -text {Ramona Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 30 23 30 5 93 5 98 5 104 7 110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 87 90 87 90 23 -outline {} -tags {floor1 room}]
    set floorLabels($i) {University Stair}
    set {floorItems(University Stair)} $i
    $w create text 155 77.5 -text {University Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 282 37 295 40 312 49 323 56 337 70 352 56 358 48 363 39 365 29 348 25 335 22 321 14 300 5 283 1 260 0 246 0 242 2 236 4 231 8 227 13 223 17 221 22 220 34 260 34 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Stair}
    set {floorItems(Plaza Stair)} $i
    $w create text 317.5 28.5 -text {Plaza Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 220 34 260 34 282 37 295 40 312 49 323 56 337 70 350 83 365 94 377 100 386 104 386 128 220 128 -outline {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Deck}
    set {floorItems(Plaza Deck)} $i
    $w create text 303 81 -text {Plaza Deck} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 257 336 77 336 6 336 6 301 77 301 77 310 257 310 -outline {} -tags {floor1 room}]
    set floorLabels($i) 106
    set {floorItems(106)} $i
    $w create text 131.5 318.5 -text 106 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 146 110 162 110 162 91 130 91 130 115 95 115 95 128 114 128 114 151 157 151 157 153 112 153 112 130 97 130 97 168 175 168 175 131 146 131 -outline {} -tags {floor1 room}]
    set floorLabels($i) 119
    set {floorItems(119)} $i
    $w create text 143.5 133 -text 119 -fill $color -anchor c -tags {floor1 label}
    $w create line 155 191 155 189 -fill $color -tags {floor1 wall}
    $w create line 155 177 155 169 -fill $color -tags {floor1 wall}
    $w create line 96 129 96 169 -fill $color -tags {floor1 wall}
    $w create line 78 169 176 169 -fill $color -tags {floor1 wall}







|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg1 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 101
    set {floorItems(101)} $i
    $w create text 358 209 -text 101 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) {Pub Lift1}
    set {floorItems(Pub Lift1)} $i
    $w create text 323 223 -text {Pub Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) {Priv Lift1}
    set {floorItems(Priv Lift1)} $i
    $w create text 323 188 -text {Priv Lift1} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 42 389 42 337 1 337 1 389 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 110
    set {floorItems(110)} $i
    $w create text 21.5 363 -text 110 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 59 389 59 385 90 385 90 337 44 337 44 389 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 109
    set {floorItems(109)} $i
    $w create text 67 363 -text 109 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 300 51 253 6 253 6 300 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 111
    set {floorItems(111)} $i
    $w create text 28.5 276.5 -text 111 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 98 248 98 309 79 309 79 248 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 117B
    set {floorItems(117B)} $i
    $w create text 88.5 278.5 -text 117B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 251 51 204 6 204 6 251 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 112
    set {floorItems(112)} $i
    $w create text 28.5 227.5 -text 112 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 6 156 51 156 51 203 6 203 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 113
    set {floorItems(113)} $i
    $w create text 28.5 179.5 -text 113 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 85 169 79 169 79 192 85 192 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 117A
    set {floorItems(117A)} $i
    $w create text 82 180.5 -text 117A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 77 302 77 168 53 168 53 302 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 117
    set {floorItems(117)} $i
    $w create text 65 235 -text 117 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 51 155 51 115 6 115 6 155 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 114
    set {floorItems(114)} $i
    $w create text 28.5 135 -text 114 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 95 115 53 115 53 168 95 168 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 115
    set {floorItems(115)} $i
    $w create text 74 141.5 -text 115 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 87 113 87 27 10 27 10 113 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 116
    set {floorItems(116)} $i
    $w create text 48.5 70 -text 116 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 89 91 128 91 128 113 89 113 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 118
    set {floorItems(118)} $i
    $w create text 108.5 102 -text 118 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 178 128 178 132 216 132 216 91 163 91 163 112 149 112 149 128 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 120
    set {floorItems(120)} $i
    $w create text 189.5 111.5 -text 120 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 79 193 87 193 87 169 136 169 136 192 156 192 156 169 175 169 175 246 79 246 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 122
    set {floorItems(122)} $i
    $w create text 131 207.5 -text 122 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 169 154 169 154 191 138 191 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 121
    set {floorItems(121)} $i
    $w create text 146 180 -text 121 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 99 300 126 300 126 309 99 309 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 106A
    set {floorItems(106A)} $i
    $w create text 112.5 304.5 -text 106A -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 128 299 128 309 150 309 150 248 99 248 99 299 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 105
    set {floorItems(105)} $i
    $w create text 124.5 278.5 -text 105 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 174 309 174 300 152 300 152 309 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 106B
    set {floorItems(106B)} $i
    $w create text 163 304.5 -text 106B -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 176 299 176 309 216 309 216 248 152 248 152 299 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 104
    set {floorItems(104)} $i
    $w create text 184 278.5 -text 104 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 138 385 138 337 91 337 91 385 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 108
    set {floorItems(108)} $i
    $w create text 114.5 361 -text 108 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 256 337 140 337 140 385 256 385 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 107
    set {floorItems(107)} $i
    $w create text 198 361 -text 107 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 300 353 300 329 260 329 260 353 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) Smoking
    set {floorItems(Smoking)} $i
    $w create text 280 341 -text Smoking -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 314 135 314 170 306 170 306 246 177 246 177 135 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 123
    set {floorItems(123)} $i
    $w create text 245.5 190.5 -text 123 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 217 248 301 248 301 326 257 326 257 310 217 310 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 103
    set {floorItems(103)} $i
    $w create text 259 287 -text 103 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 396 188 377 188 377 169 316 169 316 131 396 131 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 124
    set {floorItems(124)} $i
    $w create text 356 150 -text 124 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 226 407 226 407 189 377 189 377 246 397 246 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 125
    set {floorItems(125)} $i
    $w create text 392 217.5 -text 125 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 399 187 409 187 409 207 474 207 474 164 399 164 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 126
    set {floorItems(126)} $i
    $w create text 436.5 185.5 -text 126 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 409 209 409 229 399 229 399 253 486 253 486 239 474 239 474 209 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 127
    set {floorItems(127)} $i
    $w create text 436.5 231 -text 127 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 501 164 501 174 495 174 495 188 490 188 490 204 476 204 476 164 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) MShower
    set {floorItems(MShower)} $i
    $w create text 488.5 184 -text MShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 497 176 513 176 513 204 492 204 492 190 497 190 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) Closet
    set {floorItems(Closet)} $i
    $w create text 502.5 190 -text Closet -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 476 237 476 206 513 206 513 254 488 254 488 237 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) WShower
    set {floorItems(WShower)} $i
    $w create text 494.5 230 -text WShower -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 486 131 558 131 558 135 724 135 724 166 697 166 697 275 553 275 531 254 515 254 515 174 503 174 503 161 486 161 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 130
    set {floorItems(130)} $i
    $w create text 638.5 205 -text 130 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 308 242 339 242 339 248 342 248 342 246 397 246 397 276 393 276 393 309 300 309 300 248 308 248 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 102
    set {floorItems(102)} $i
    $w create text 367.5 278.5 -text 102 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 397 255 486 255 486 276 397 276 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 128
    set {floorItems(128)} $i
    $w create text 441.5 265.5 -text 128 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 510 309 486 309 486 255 530 255 552 277 561 277 561 325 510 325 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 129
    set {floorItems(129)} $i
    $w create text 535.5 293 -text 129 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 696 281 740 281 740 387 642 387 642 389 561 389 561 277 696 277 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 133
    set {floorItems(133)} $i
    $w create text 628.5 335 -text 133 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 742 387 742 281 800 281 800 387 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 132
    set {floorItems(132)} $i
    $w create text 771 334 -text 132 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 800 168 800 280 699 280 699 168 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 134
    set {floorItems(134)} $i
    $w create text 749.5 224 -text 134 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 726 131 726 166 800 166 800 131 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 135
    set {floorItems(135)} $i
    $w create text 763 148.5 -text 135 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 340 360 335 363 331 365 326 366 304 366 304 312 396 312 396 288 400 288 404 288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 342 331 347 332 351 334 354 336 357 341 359 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) {Ramona Stair}
    set {floorItems(Ramona Stair)} $i
    $w create text 368 323 -text {Ramona Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 30 23 30 5 93 5 98 5 104 7 110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 87 90 87 90 23 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) {University Stair}
    set {floorItems(University Stair)} $i
    $w create text 155 77.5 -text {University Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 282 37 295 40 312 49 323 56 337 70 352 56 358 48 363 39 365 29 348 25 335 22 321 14 300 5 283 1 260 0 246 0 242 2 236 4 231 8 227 13 223 17 221 22 220 34 260 34 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Stair}
    set {floorItems(Plaza Stair)} $i
    $w create text 317.5 28.5 -text {Plaza Stair} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 220 34 260 34 282 37 295 40 312 49 323 56 337 70 350 83 365 94 377 100 386 104 386 128 220 128 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) {Plaza Deck}
    set {floorItems(Plaza Deck)} $i
    $w create text 303 81 -text {Plaza Deck} -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 257 336 77 336 6 336 6 301 77 301 77 310 257 310 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 106
    set {floorItems(106)} $i
    $w create text 131.5 318.5 -text 106 -fill $color -anchor c -tags {floor1 label}
    set i [$w create polygon 146 110 162 110 162 91 130 91 130 115 95 115 95 128 114 128 114 151 157 151 157 153 112 153 112 130 97 130 97 168 175 168 175 131 146 131 -fill {} -outline {} -tags {floor1 room}]
    set floorLabels($i) 119
    set {floorItems(119)} $i
    $w create text 143.5 133 -text 119 -fill $color -anchor c -tags {floor1 label}
    $w create line 155 191 155 189 -fill $color -tags {floor1 wall}
    $w create line 155 177 155 169 -fill $color -tags {floor1 wall}
    $w create line 96 129 96 169 -fill $color -tags {floor1 wall}
    $w create line 78 169 176 169 -fill $color -tags {floor1 wall}
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg2 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 748 188 755 188 755 205 758 205 758 222 800 222 800 168 748 168 -outline {} -tags {floor2 room}]
    set floorLabels($i) 238
    set {floorItems(238)} $i
    $w create text 774 195 -text 238 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 726 188 746 188 746 166 800 166 800 131 726 131 -outline {} -tags {floor2 room}]
    set floorLabels($i) 237
    set {floorItems(237)} $i
    $w create text 763 148.5 -text 237 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 497 187 497 204 559 204 559 324 641 324 643 324 643 291 641 291 641 205 696 205 696 291 694 291 694 314 715 314 715 291 715 205 755 205 755 190 724 190 724 187 -outline {} -tags {floor2 room}]
    set floorLabels($i) 246
    set {floorItems(246)} $i
    $w create text 600 264 -text 246 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 694 279 643 279 643 314 694 314 -outline {} -tags {floor2 room}]
    set floorLabels($i) 247
    set {floorItems(247)} $i
    $w create text 668.5 296.5 -text 247 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 232 250 308 250 308 242 339 242 339 246 397 246 397 255 476 255 476 250 482 250 559 250 559 274 482 274 482 278 396 278 396 274 232 274 -outline {} -tags {floor2 room}]
    set floorLabels($i) 202
    set {floorItems(202)} $i
    $w create text 285.5 260 -text 202 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 53 228 53 338 176 338 233 338 233 196 306 196 306 180 175 180 175 169 156 169 156 196 176 196 176 228 -outline {} -tags {floor2 room}]
    set floorLabels($i) 206
    set {floorItems(206)} $i
    $w create text 143 267 -text 206 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 277 6 277 6 338 51 338 -outline {} -tags {floor2 room}]
    set floorLabels($i) 212
    set {floorItems(212)} $i
    $w create text 28.5 307.5 -text 212 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 276 486 276 486 309 510 309 510 325 557 325 -outline {} -tags {floor2 room}]
    set floorLabels($i) 245
    set {floorItems(245)} $i
    $w create text 521.5 300.5 -text 245 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 560 389 599 389 599 326 560 326 -outline {} -tags {floor2 room}]
    set floorLabels($i) 244
    set {floorItems(244)} $i
    $w create text 579.5 357.5 -text 244 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 601 389 601 326 643 326 643 389 -outline {} -tags {floor2 room}]
    set floorLabels($i) 243
    set {floorItems(243)} $i
    $w create text 622 357.5 -text 243 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 688 316 645 316 645 365 688 365 -outline {} -tags {floor2 room}]
    set floorLabels($i) 242
    set {floorItems(242)} $i
    $w create text 666.5 340.5 -text 242 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 802 367 759 367 759 226 802 226 -outline {} -tags {floor2 room}]
    set floorLabels($i) {Barbecue Deck}
    set {floorItems(Barbecue Deck)} $i
    $w create text 780.5 296.5 -text {Barbecue Deck} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 262 755 314 717 314 717 262 -outline {} -tags {floor2 room}]
    set floorLabels($i) 240
    set {floorItems(240)} $i
    $w create text 736 288 -text 240 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 316 689 316 689 365 755 365 -outline {} -tags {floor2 room}]
    set floorLabels($i) 241
    set {floorItems(241)} $i
    $w create text 722 340.5 -text 241 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 206 717 206 717 261 755 261 -outline {} -tags {floor2 room}]
    set floorLabels($i) 239
    set {floorItems(239)} $i
    $w create text 736 233.5 -text 239 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 695 277 643 277 643 206 695 206 -outline {} -tags {floor2 room}]
    set floorLabels($i) 248
    set {floorItems(248)} $i
    $w create text 669 241.5 -text 248 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 676 135 676 185 724 185 724 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 236
    set {floorItems(236)} $i
    $w create text 700 160 -text 236 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 675 135 635 135 635 145 628 145 628 185 675 185 -outline {} -tags {floor2 room}]
    set floorLabels($i) 235
    set {floorItems(235)} $i
    $w create text 651.5 160 -text 235 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 626 143 633 143 633 135 572 135 572 143 579 143 579 185 626 185 -outline {} -tags {floor2 room}]
    set floorLabels($i) 234
    set {floorItems(234)} $i
    $w create text 606 160 -text 234 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 135 571 135 571 145 578 145 578 185 527 185 527 131 557 131 -outline {} -tags {floor2 room}]
    set floorLabels($i) 233
    set {floorItems(233)} $i
    $w create text 552.5 158 -text 233 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 249 557 249 557 205 476 205 -outline {} -tags {floor2 room}]
    set floorLabels($i) 230
    set {floorItems(230)} $i
    $w create text 516.5 227 -text 230 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 164 486 164 486 131 525 131 525 185 476 185 -outline {} -tags {floor2 room}]
    set floorLabels($i) 232
    set {floorItems(232)} $i
    $w create text 500.5 158 -text 232 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 186 495 186 495 204 476 204 -outline {} -tags {floor2 room}]
    set floorLabels($i) 229
    set {floorItems(229)} $i
    $w create text 485.5 195 -text 229 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 474 207 409 207 409 187 399 187 399 164 474 164 -outline {} -tags {floor2 room}]
    set floorLabels($i) 227
    set {floorItems(227)} $i
    $w create text 436.5 185.5 -text 227 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 399 228 399 253 474 253 474 209 409 209 409 228 -outline {} -tags {floor2 room}]
    set floorLabels($i) 228
    set {floorItems(228)} $i
    $w create text 436.5 231 -text 228 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 397 246 397 226 407 226 407 189 377 189 377 246 -outline {} -tags {floor2 room}]
    set floorLabels($i) 226
    set {floorItems(226)} $i
    $w create text 392 217.5 -text 226 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 377 169 316 169 316 131 397 131 397 188 377 188 -outline {} -tags {floor2 room}]
    set floorLabels($i) 225
    set {floorItems(225)} $i
    $w create text 356.5 150 -text 225 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 198 306 198 306 249 234 249 -outline {} -tags {floor2 room}]
    set floorLabels($i) 224
    set {floorItems(224)} $i
    $w create text 270 223.5 -text 224 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 270 179 306 179 306 170 314 170 314 135 270 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 223
    set {floorItems(223)} $i
    $w create text 292 157 -text 223 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 268 179 221 179 221 135 268 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 222
    set {floorItems(222)} $i
    $w create text 244.5 157 -text 222 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 177 179 219 179 219 135 177 135 -outline {} -tags {floor2 room}]
    set floorLabels($i) 221
    set {floorItems(221)} $i
    $w create text 198 157 -text 221 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 299 327 349 327 349 284 341 284 341 276 299 276 -outline {} -tags {floor2 room}]
    set floorLabels($i) 204
    set {floorItems(204)} $i
    $w create text 324 301.5 -text 204 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 276 297 276 297 327 257 327 257 338 234 338 -outline {} -tags {floor2 room}]
    set floorLabels($i) 205
    set {floorItems(205)} $i
    $w create text 265.5 307 -text 205 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 256 385 256 340 212 340 212 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 207
    set {floorItems(207)} $i
    $w create text 234 362.5 -text 207 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 210 340 164 340 164 385 210 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 208
    set {floorItems(208)} $i
    $w create text 187 362.5 -text 208 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 115 340 162 340 162 385 115 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 209
    set {floorItems(209)} $i
    $w create text 138.5 362.5 -text 209 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 228 89 156 53 156 53 228 -outline {} -tags {floor2 room}]
    set floorLabels($i) 217
    set {floorItems(217)} $i
    $w create text 71 192 -text 217 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 169 97 169 97 190 89 190 -outline {} -tags {floor2 room}]
    set floorLabels($i) 217A
    set {floorItems(217A)} $i
    $w create text 93 179.5 -text 217A -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 156 89 168 95 168 95 135 53 135 53 156 -outline {} -tags {floor2 room}]
    set floorLabels($i) 216
    set {floorItems(216)} $i
    $w create text 71 145.5 -text 216 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 179 51 135 6 135 6 179 -outline {} -tags {floor2 room}]
    set floorLabels($i) 215
    set {floorItems(215)} $i
    $w create text 28.5 157 -text 215 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 227 6 227 6 180 51 180 -outline {} -tags {floor2 room}]
    set floorLabels($i) 214
    set {floorItems(214)} $i
    $w create text 28.5 203.5 -text 214 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 275 6 275 6 229 51 229 -outline {} -tags {floor2 room}]
    set floorLabels($i) 213
    set {floorItems(213)} $i
    $w create text 28.5 252 -text 213 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 114 340 67 340 67 385 114 385 -outline {} -tags {floor2 room}]
    set floorLabels($i) 210
    set {floorItems(210)} $i
    $w create text 90.5 362.5 -text 210 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 59 389 59 385 65 385 65 340 1 340 1 389 -outline {} -tags {floor2 room}]
    set floorLabels($i) 211
    set {floorItems(211)} $i
    $w create text 33 364.5 -text 211 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 393 309 350 309 350 282 342 282 342 276 393 276 -outline {} -tags {floor2 room}]
    set floorLabels($i) 203
    set {floorItems(203)} $i
    $w create text 367.5 292.5 -text 203 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 99 191 91 191 91 226 174 226 174 198 154 198 154 192 109 192 109 169 99 169 -outline {} -tags {floor2 room}]
    set floorLabels($i) 220
    set {floorItems(220)} $i
    $w create text 132.5 208.5 -text 220 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -outline {} -tags {floor2 room}]
    set floorLabels($i) {Priv Lift2}
    set {floorItems(Priv Lift2)} $i
    $w create text 323 188 -text {Priv Lift2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -outline {} -tags {floor2 room}]
    set floorLabels($i) {Pub Lift 2}
    set {floorItems(Pub Lift 2)} $i
    $w create text 323 223 -text {Pub Lift 2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -outline {} -tags {floor2 room}]
    set floorLabels($i) 218
    set {floorItems(218)} $i
    $w create text 136 149.5 -text 218 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -outline {} -tags {floor2 room}]
    set floorLabels($i) 219
    set {floorItems(219)} $i
    $w create text 132.5 180 -text 219 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -outline {} -tags {floor2 room}]
    set floorLabels($i) 201
    set {floorItems(201)} $i
    $w create text 358 209 -text 201 -fill $color -anchor c -tags {floor2 label}
    $w create line 641 186 678 186 -fill $color -tags {floor2 wall}
    $w create line 757 350 757 367 -fill $color -tags {floor2 wall}
    $w create line 634 133 634 144 -fill $color -tags {floor2 wall}
    $w create line 634 144 627 144 -fill $color -tags {floor2 wall}







|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg2 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 748 188 755 188 755 205 758 205 758 222 800 222 800 168 748 168 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 238
    set {floorItems(238)} $i
    $w create text 774 195 -text 238 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 726 188 746 188 746 166 800 166 800 131 726 131 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 237
    set {floorItems(237)} $i
    $w create text 763 148.5 -text 237 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 497 187 497 204 559 204 559 324 641 324 643 324 643 291 641 291 641 205 696 205 696 291 694 291 694 314 715 314 715 291 715 205 755 205 755 190 724 190 724 187 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 246
    set {floorItems(246)} $i
    $w create text 600 264 -text 246 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 694 279 643 279 643 314 694 314 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 247
    set {floorItems(247)} $i
    $w create text 668.5 296.5 -text 247 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 232 250 308 250 308 242 339 242 339 246 397 246 397 255 476 255 476 250 482 250 559 250 559 274 482 274 482 278 396 278 396 274 232 274 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 202
    set {floorItems(202)} $i
    $w create text 285.5 260 -text 202 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 53 228 53 338 176 338 233 338 233 196 306 196 306 180 175 180 175 169 156 169 156 196 176 196 176 228 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 206
    set {floorItems(206)} $i
    $w create text 143 267 -text 206 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 277 6 277 6 338 51 338 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 212
    set {floorItems(212)} $i
    $w create text 28.5 307.5 -text 212 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 276 486 276 486 309 510 309 510 325 557 325 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 245
    set {floorItems(245)} $i
    $w create text 521.5 300.5 -text 245 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 560 389 599 389 599 326 560 326 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 244
    set {floorItems(244)} $i
    $w create text 579.5 357.5 -text 244 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 601 389 601 326 643 326 643 389 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 243
    set {floorItems(243)} $i
    $w create text 622 357.5 -text 243 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 688 316 645 316 645 365 688 365 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 242
    set {floorItems(242)} $i
    $w create text 666.5 340.5 -text 242 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 802 367 759 367 759 226 802 226 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) {Barbecue Deck}
    set {floorItems(Barbecue Deck)} $i
    $w create text 780.5 296.5 -text {Barbecue Deck} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 262 755 314 717 314 717 262 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 240
    set {floorItems(240)} $i
    $w create text 736 288 -text 240 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 316 689 316 689 365 755 365 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 241
    set {floorItems(241)} $i
    $w create text 722 340.5 -text 241 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 755 206 717 206 717 261 755 261 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 239
    set {floorItems(239)} $i
    $w create text 736 233.5 -text 239 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 695 277 643 277 643 206 695 206 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 248
    set {floorItems(248)} $i
    $w create text 669 241.5 -text 248 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 676 135 676 185 724 185 724 135 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 236
    set {floorItems(236)} $i
    $w create text 700 160 -text 236 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 675 135 635 135 635 145 628 145 628 185 675 185 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 235
    set {floorItems(235)} $i
    $w create text 651.5 160 -text 235 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 626 143 633 143 633 135 572 135 572 143 579 143 579 185 626 185 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 234
    set {floorItems(234)} $i
    $w create text 606 160 -text 234 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 557 135 571 135 571 145 578 145 578 185 527 185 527 131 557 131 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 233
    set {floorItems(233)} $i
    $w create text 552.5 158 -text 233 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 249 557 249 557 205 476 205 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 230
    set {floorItems(230)} $i
    $w create text 516.5 227 -text 230 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 164 486 164 486 131 525 131 525 185 476 185 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 232
    set {floorItems(232)} $i
    $w create text 500.5 158 -text 232 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 476 186 495 186 495 204 476 204 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 229
    set {floorItems(229)} $i
    $w create text 485.5 195 -text 229 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 474 207 409 207 409 187 399 187 399 164 474 164 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 227
    set {floorItems(227)} $i
    $w create text 436.5 185.5 -text 227 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 399 228 399 253 474 253 474 209 409 209 409 228 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 228
    set {floorItems(228)} $i
    $w create text 436.5 231 -text 228 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 397 246 397 226 407 226 407 189 377 189 377 246 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 226
    set {floorItems(226)} $i
    $w create text 392 217.5 -text 226 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 377 169 316 169 316 131 397 131 397 188 377 188 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 225
    set {floorItems(225)} $i
    $w create text 356.5 150 -text 225 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 198 306 198 306 249 234 249 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 224
    set {floorItems(224)} $i
    $w create text 270 223.5 -text 224 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 270 179 306 179 306 170 314 170 314 135 270 135 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 223
    set {floorItems(223)} $i
    $w create text 292 157 -text 223 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 268 179 221 179 221 135 268 135 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 222
    set {floorItems(222)} $i
    $w create text 244.5 157 -text 222 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 177 179 219 179 219 135 177 135 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 221
    set {floorItems(221)} $i
    $w create text 198 157 -text 221 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 299 327 349 327 349 284 341 284 341 276 299 276 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 204
    set {floorItems(204)} $i
    $w create text 324 301.5 -text 204 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 234 276 297 276 297 327 257 327 257 338 234 338 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 205
    set {floorItems(205)} $i
    $w create text 265.5 307 -text 205 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 256 385 256 340 212 340 212 385 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 207
    set {floorItems(207)} $i
    $w create text 234 362.5 -text 207 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 210 340 164 340 164 385 210 385 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 208
    set {floorItems(208)} $i
    $w create text 187 362.5 -text 208 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 115 340 162 340 162 385 115 385 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 209
    set {floorItems(209)} $i
    $w create text 138.5 362.5 -text 209 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 228 89 156 53 156 53 228 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 217
    set {floorItems(217)} $i
    $w create text 71 192 -text 217 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 169 97 169 97 190 89 190 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 217A
    set {floorItems(217A)} $i
    $w create text 93 179.5 -text 217A -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 89 156 89 168 95 168 95 135 53 135 53 156 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 216
    set {floorItems(216)} $i
    $w create text 71 145.5 -text 216 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 179 51 135 6 135 6 179 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 215
    set {floorItems(215)} $i
    $w create text 28.5 157 -text 215 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 227 6 227 6 180 51 180 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 214
    set {floorItems(214)} $i
    $w create text 28.5 203.5 -text 214 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 51 275 6 275 6 229 51 229 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 213
    set {floorItems(213)} $i
    $w create text 28.5 252 -text 213 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 114 340 67 340 67 385 114 385 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 210
    set {floorItems(210)} $i
    $w create text 90.5 362.5 -text 210 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 59 389 59 385 65 385 65 340 1 340 1 389 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 211
    set {floorItems(211)} $i
    $w create text 33 364.5 -text 211 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 393 309 350 309 350 282 342 282 342 276 393 276 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 203
    set {floorItems(203)} $i
    $w create text 367.5 292.5 -text 203 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 99 191 91 191 91 226 174 226 174 198 154 198 154 192 109 192 109 169 99 169 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 220
    set {floorItems(220)} $i
    $w create text 132.5 208.5 -text 220 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) {Priv Lift2}
    set {floorItems(Priv Lift2)} $i
    $w create text 323 188 -text {Priv Lift2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) {Pub Lift 2}
    set {floorItems(Pub Lift 2)} $i
    $w create text 323 223 -text {Pub Lift 2} -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 218
    set {floorItems(218)} $i
    $w create text 136 149.5 -text 218 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 219
    set {floorItems(219)} $i
    $w create text 132.5 180 -text 219 -fill $color -anchor c -tags {floor2 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -outline {} -tags {floor2 room}]
    set floorLabels($i) 201
    set {floorItems(201)} $i
    $w create text 358 209 -text 201 -fill $color -anchor c -tags {floor2 label}
    $w create line 641 186 678 186 -fill $color -tags {floor2 wall}
    $w create line 757 350 757 367 -fill $color -tags {floor2 wall}
    $w create line 634 133 634 144 -fill $color -tags {floor2 wall}
    $w create line 634 144 627 144 -fill $color -tags {floor2 wall}
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg3 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 89 228 89 180 70 180 70 228 -outline {} -tags {floor3 room}]
    set floorLabels($i) 316
    set {floorItems(316)} $i
    $w create text 79.5 204 -text 316 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 115 368 162 368 162 323 115 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 309
    set {floorItems(309)} $i
    $w create text 138.5 345.5 -text 309 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 164 323 164 368 211 368 211 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 308
    set {floorItems(308)} $i
    $w create text 187.5 345.5 -text 308 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 256 368 212 368 212 323 256 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 307
    set {floorItems(307)} $i
    $w create text 234 345.5 -text 307 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 244 276 297 276 297 327 260 327 260 321 244 321 -outline {} -tags {floor3 room}]
    set floorLabels($i) 305
    set {floorItems(305)} $i
    $w create text 270.5 301.5 -text 305 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 219 251 203 244 203 244 219 -outline {} -tags {floor3 room}]
    set floorLabels($i) 324B
    set {floorItems(324B)} $i
    $w create text 247.5 211 -text 324B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 249 244 249 244 232 251 232 -outline {} -tags {floor3 room}]
    set floorLabels($i) 324A
    set {floorItems(324A)} $i
    $w create text 247.5 240.5 -text 324A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 223 135 223 179 177 179 177 135 -outline {} -tags {floor3 room}]
    set floorLabels($i) 320
    set {floorItems(320)} $i
    $w create text 200 157 -text 320 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 114 368 114 323 67 323 67 368 -outline {} -tags {floor3 room}]
    set floorLabels($i) 310
    set {floorItems(310)} $i
    $w create text 90.5 345.5 -text 310 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 277 23 321 68 321 68 277 -outline {} -tags {floor3 room}]
    set floorLabels($i) 312
    set {floorItems(312)} $i
    $w create text 45.5 299 -text 312 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 229 68 229 68 275 23 275 -outline {} -tags {floor3 room}]
    set floorLabels($i) 313
    set {floorItems(313)} $i
    $w create text 45.5 252 -text 313 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 68 227 23 227 23 180 68 180 -outline {} -tags {floor3 room}]
    set floorLabels($i) 314
    set {floorItems(314)} $i
    $w create text 45.5 203.5 -text 314 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 95 179 95 135 23 135 23 179 -outline {} -tags {floor3 room}]
    set floorLabels($i) 315
    set {floorItems(315)} $i
    $w create text 59 157 -text 315 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 99 226 99 204 91 204 91 226 -outline {} -tags {floor3 room}]
    set floorLabels($i) 316B
    set {floorItems(316B)} $i
    $w create text 95 215 -text 316B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 91 202 99 202 99 180 91 180 -outline {} -tags {floor3 room}]
    set floorLabels($i) 316A
    set {floorItems(316A)} $i
    $w create text 95 191 -text 316A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 97 169 109 169 109 192 154 192 154 198 174 198 174 226 101 226 101 179 97 179 -outline {} -tags {floor3 room}]
    set floorLabels($i) 319
    set {floorItems(319)} $i
    $w create text 141.5 209 -text 319 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 65 368 58 368 58 389 1 389 1 333 23 333 23 323 65 323 -outline {} -tags {floor3 room}]
    set floorLabels($i) 311
    set {floorItems(311)} $i
    $w create text 29.5 361 -text 311 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -outline {} -tags {floor3 room}]
    set floorLabels($i) 318
    set {floorItems(318)} $i
    $w create text 132.5 180 -text 318 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -outline {} -tags {floor3 room}]
    set floorLabels($i) 317
    set {floorItems(317)} $i
    $w create text 136 149.5 -text 317 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 274 194 274 221 306 221 306 194 -outline {} -tags {floor3 room}]
    set floorLabels($i) 323
    set {floorItems(323)} $i
    $w create text 290 207.5 -text 323 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 306 222 274 222 274 249 306 249 -outline {} -tags {floor3 room}]
    set floorLabels($i) 325
    set {floorItems(325)} $i
    $w create text 290 235.5 -text 325 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 263 179 224 179 224 135 263 135 -outline {} -tags {floor3 room}]
    set floorLabels($i) 321
    set {floorItems(321)} $i
    $w create text 243.5 157 -text 321 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 314 169 306 169 306 192 273 192 264 181 264 135 314 135 -outline {} -tags {floor3 room}]
    set floorLabels($i) 322
    set {floorItems(322)} $i
    $w create text 293.5 163.5 -text 322 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -outline {} -tags {floor3 room}]
    set floorLabels($i) {Pub Lift3}
    set {floorItems(Pub Lift3)} $i
    $w create text 323 223 -text {Pub Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -outline {} -tags {floor3 room}]
    set floorLabels($i) {Priv Lift3}
    set {floorItems(Priv Lift3)} $i
    $w create text 323 188 -text {Priv Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 350 284 376 284 376 276 397 276 397 309 350 309 -outline {} -tags {floor3 room}]
    set floorLabels($i) 303
    set {floorItems(303)} $i
    $w create text 373.5 292.5 -text 303 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 272 203 272 249 252 249 252 230 244 230 244 221 252 221 252 203 -outline {} -tags {floor3 room}]
    set floorLabels($i) 324
    set {floorItems(324)} $i
    $w create text 262 226 -text 324 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 299 276 299 327 349 327 349 284 341 284 341 276 -outline {} -tags {floor3 room}]
    set floorLabels($i) 304
    set {floorItems(304)} $i
    $w create text 324 301.5 -text 304 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -outline {} -tags {floor3 room}]
    set floorLabels($i) 301
    set {floorItems(301)} $i
    $w create text 358 209 -text 301 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 397 246 377 246 377 185 397 185 -outline {} -tags {floor3 room}]
    set floorLabels($i) 327
    set {floorItems(327)} $i
    $w create text 387 215.5 -text 327 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 316 131 316 169 377 169 377 185 397 185 397 131 -outline {} -tags {floor3 room}]
    set floorLabels($i) 326
    set {floorItems(326)} $i
    $w create text 356.5 150 -text 326 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 308 251 242 251 242 274 342 274 342 282 375 282 375 274 397 274 397 248 339 248 339 242 308 242 -outline {} -tags {floor3 room}]
    set floorLabels($i) 302
    set {floorItems(302)} $i
    $w create text 319.5 261 -text 302 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 70 321 242 321 242 200 259 200 259 203 272 203 272 193 263 180 242 180 175 180 175 169 156 169 156 196 177 196 177 228 107 228 70 228 70 275 107 275 107 248 160 248 160 301 107 301 107 275 70 275 -outline {} -tags {floor3 room}]
    set floorLabels($i) 306
    set {floorItems(306)} $i
    $w create text 200.5 284.5 -text 306 -fill $color -anchor c -tags {floor3 label}
    $w create line 341 275 341 283 -fill $color -tags {floor3 wall}
    $w create line 162 197 155 197 -fill $color -tags {floor3 wall}
    $w create line 396 247 399 247 -fill $color -tags {floor3 wall}
    $w create line 399 129 399 311 -fill $color -tags {floor3 wall}







|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







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
#
# Arguments:
# w -		The canvas window.
# color -	Color to use for drawing foreground information.

proc fg3 {w color} {
    global floorLabels floorItems
    set i [$w create polygon 89 228 89 180 70 180 70 228 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 316
    set {floorItems(316)} $i
    $w create text 79.5 204 -text 316 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 115 368 162 368 162 323 115 323 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 309
    set {floorItems(309)} $i
    $w create text 138.5 345.5 -text 309 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 164 323 164 368 211 368 211 323 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 308
    set {floorItems(308)} $i
    $w create text 187.5 345.5 -text 308 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 256 368 212 368 212 323 256 323 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 307
    set {floorItems(307)} $i
    $w create text 234 345.5 -text 307 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 244 276 297 276 297 327 260 327 260 321 244 321 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 305
    set {floorItems(305)} $i
    $w create text 270.5 301.5 -text 305 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 219 251 203 244 203 244 219 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 324B
    set {floorItems(324B)} $i
    $w create text 247.5 211 -text 324B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 251 249 244 249 244 232 251 232 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 324A
    set {floorItems(324A)} $i
    $w create text 247.5 240.5 -text 324A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 223 135 223 179 177 179 177 135 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 320
    set {floorItems(320)} $i
    $w create text 200 157 -text 320 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 114 368 114 323 67 323 67 368 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 310
    set {floorItems(310)} $i
    $w create text 90.5 345.5 -text 310 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 277 23 321 68 321 68 277 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 312
    set {floorItems(312)} $i
    $w create text 45.5 299 -text 312 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 23 229 68 229 68 275 23 275 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 313
    set {floorItems(313)} $i
    $w create text 45.5 252 -text 313 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 68 227 23 227 23 180 68 180 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 314
    set {floorItems(314)} $i
    $w create text 45.5 203.5 -text 314 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 95 179 95 135 23 135 23 179 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 315
    set {floorItems(315)} $i
    $w create text 59 157 -text 315 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 99 226 99 204 91 204 91 226 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 316B
    set {floorItems(316B)} $i
    $w create text 95 215 -text 316B -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 91 202 99 202 99 180 91 180 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 316A
    set {floorItems(316A)} $i
    $w create text 95 191 -text 316A -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 97 169 109 169 109 192 154 192 154 198 174 198 174 226 101 226 101 179 97 179 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 319
    set {floorItems(319)} $i
    $w create text 141.5 209 -text 319 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 65 368 58 368 58 389 1 389 1 333 23 333 23 323 65 323 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 311
    set {floorItems(311)} $i
    $w create text 29.5 361 -text 311 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 318
    set {floorItems(318)} $i
    $w create text 132.5 180 -text 318 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 317
    set {floorItems(317)} $i
    $w create text 136 149.5 -text 317 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 274 194 274 221 306 221 306 194 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 323
    set {floorItems(323)} $i
    $w create text 290 207.5 -text 323 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 306 222 274 222 274 249 306 249 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 325
    set {floorItems(325)} $i
    $w create text 290 235.5 -text 325 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 263 179 224 179 224 135 263 135 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 321
    set {floorItems(321)} $i
    $w create text 243.5 157 -text 321 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 314 169 306 169 306 192 273 192 264 181 264 135 314 135 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 322
    set {floorItems(322)} $i
    $w create text 293.5 163.5 -text 322 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) {Pub Lift3}
    set {floorItems(Pub Lift3)} $i
    $w create text 323 223 -text {Pub Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) {Priv Lift3}
    set {floorItems(Priv Lift3)} $i
    $w create text 323 188 -text {Priv Lift3} -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 350 284 376 284 376 276 397 276 397 309 350 309 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 303
    set {floorItems(303)} $i
    $w create text 373.5 292.5 -text 303 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 272 203 272 249 252 249 252 230 244 230 244 221 252 221 252 203 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 324
    set {floorItems(324)} $i
    $w create text 262 226 -text 324 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 299 276 299 327 349 327 349 284 341 284 341 276 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 304
    set {floorItems(304)} $i
    $w create text 324 301.5 -text 304 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 301
    set {floorItems(301)} $i
    $w create text 358 209 -text 301 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 397 246 377 246 377 185 397 185 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 327
    set {floorItems(327)} $i
    $w create text 387 215.5 -text 327 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 316 131 316 169 377 169 377 185 397 185 397 131 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 326
    set {floorItems(326)} $i
    $w create text 356.5 150 -text 326 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 308 251 242 251 242 274 342 274 342 282 375 282 375 274 397 274 397 248 339 248 339 242 308 242 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 302
    set {floorItems(302)} $i
    $w create text 319.5 261 -text 302 -fill $color -anchor c -tags {floor3 label}
    set i [$w create polygon 70 321 242 321 242 200 259 200 259 203 272 203 272 193 263 180 242 180 175 180 175 169 156 169 156 196 177 196 177 228 107 228 70 228 70 275 107 275 107 248 160 248 160 301 107 301 107 275 70 275 -fill {} -outline {} -tags {floor3 room}]
    set floorLabels($i) 306
    set {floorItems(306)} $i
    $w create text 200.5 284.5 -text 306 -fill $color -anchor c -tags {floor3 label}
    $w create line 341 275 341 283 -fill $color -tags {floor3 wall}
    $w create line 162 197 155 197 -fill $color -tags {floor3 wall}
    $w create line 396 247 399 247 -fill $color -tags {floor3 wall}
    $w create line 399 129 399 311 -fill $color -tags {floor3 wall}
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
set w .floor
global c currentRoom colors activeFloor
catch {destroy $w}
toplevel $w
wm title $w "Floorplan Canvas Demonstration"
wm iconname $w "Floorplan"
wm geometry $w +20+20
wm minsize $w 100 100

label $w.msg -font $font -wraplength 8i -justify left  -text "This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory.  It has three levels.  At any given time one of the levels is active, meaning that you can see its room structure.  To activate a level, click the left mouse button anywhere on it.  As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \"Room:\" entry.  You can also type a room number in the entry and the room will light up."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set f [frame $w.frame]
pack $f -side top -fill both -expand yes
set h [ttk::scrollbar $f.hscroll -orient horizontal]
set v [ttk::scrollbar $f.vscroll -orient vertical]
set f1 [frame $f.f1 -borderwidth 2 -relief sunken]
set c [canvas $f1.c -width 900 -height 500 -highlightthickness 0 \
	   -xscrollcommand [list $h set] \
	   -yscrollcommand [list $v set]]
pack $c -expand yes -fill both
grid $f1 -padx 1 -pady 1 -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $v -padx 1 -pady 1 -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $h -padx 1 -pady 1 -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid rowconfig    $f 0 -weight 1 -minsize 0
grid columnconfig $f 0 -weight 1 -minsize 0
pack $f -expand yes -fill both -padx 1 -pady 1







|













|
|
<







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
set w .floor
global c currentRoom colors activeFloor
catch {destroy $w}
toplevel $w
wm title $w "Floorplan Canvas Demonstration"
wm iconname $w "Floorplan"
wm geometry $w +20+20
wm minsize $w 75p 75p

label $w.msg -font $font -wraplength 8i -justify left  -text "This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory.  It has three levels.  At any given time one of the levels is active, meaning that you can see its room structure.  To activate a level, click the left mouse button anywhere on it.  As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \"Room:\" entry.  You can also type a room number in the entry and the room will light up."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set f [frame $w.frame]
pack $f -side top -fill both -expand yes
set h [ttk::scrollbar $f.hscroll -orient horizontal]
set v [ttk::scrollbar $f.vscroll -orient vertical]
set f1 [frame $f.f1 -borderwidth 2 -relief sunken]
set c [canvas $f1.c -highlightthickness 0 \
	   -xscrollcommand [list $h set] -yscrollcommand [list $v set]]

pack $c -expand yes -fill both
grid $f1 -padx 1 -pady 1 -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $v -padx 1 -pady 1 -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $h -padx 1 -pady 1 -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid rowconfig    $f 0 -weight 1 -minsize 0
grid columnconfig $f 0 -weight 1 -minsize 0
pack $f -expand yes -fill both -padx 1 -pady 1
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 <Destroy> "unset currentRoom"
set currentRoom ""
trace variable currentRoom w "roomChanged $c"







|








|
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
# Set up event bindings for canvas:

$c bind floor1 <Button-1> "floorDisplay $c 1"
$c bind floor2 <Button-1> "floorDisplay $c 2"
$c bind floor3 <Button-1> "floorDisplay $c 3"
$c bind room <Enter> "newRoom $c"
$c bind room <Leave> {set currentRoom ""}
if {[tk windowingsystem] eq "aqua" && ![package vsatisfies [package provide tk] 8.7-]} {
    bind $c <Button-3> "$c scan mark %x %y"
    bind $c <B3-Motion> "$c scan dragto %x %y"
} else {
    bind $c <Button-2> "$c scan mark %x %y"
    bind $c <B2-Motion> "$c scan dragto %x %y"
}
bind $c <Destroy> "unset currentRoom"
set currentRoom ""
trace add variable currentRoom write "roomChanged $c"

Changes to library/demos/fontchoose.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# fontchoose.tcl --
#
# Show off the stock font selector dialog

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .fontchoose
catch {destroy $w}
toplevel $w
wm title $w "Font Selection Dialog"
wm iconname $w "fontchooser"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# fontchoose.tcl --
#
# Show off the stock font selector dialog

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .fontchoose
catch {destroy $w}
toplevel $w
wm title $w "Font Selection Dialog"
wm iconname $w "fontchooser"
positionWindow $w
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
        %W.f.font state disabled
    } else {
        %W.f.font state !disabled
    }
}


set f [ttk::frame $w.f -relief sunken -padding 2]

text $f.msg -font FontchooseDemoFont -width 40 -height 6 -borderwidth 0 \
    -yscrollcommand [list $f.vs set]
ttk::scrollbar $f.vs -command [list $f.msg yview]

$f.msg insert end "Press the buttons below to choose a new font for the\
  text shown in this window.\n" {}







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
        %W.f.font state disabled
    } else {
        %W.f.font state !disabled
    }
}


set f [ttk::frame $w.f -relief sunken -padding 1.5p]

text $f.msg -font FontchooseDemoFont -width 40 -height 6 -borderwidth 0 \
    -yscrollcommand [list $f.vs set]
ttk::scrollbar $f.vs -command [list $f.msg yview]

$f.msg insert end "Press the buttons below to choose a new font for the\
  text shown in this window.\n" {}

Changes to library/demos/form.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# form.tcl --
#
# This demonstration script creates a simple form with a bunch
# of entry widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .form
catch {destroy $w}
toplevel $w
wm title $w "Form Demonstration"
wm iconname $w "form"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# form.tcl --
#
# This demonstration script creates a simple form with a bunch
# of entry widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .form
catch {destroy $w}
toplevel $w
wm title $w "Form Demonstration"
wm iconname $w "form"
positionWindow $w

Changes to library/demos/goldberg.tcl.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54

55
56
57
58
59
60





















61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102

103
104
105
106
107

108
109
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172





173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221


































222
223
224
225
226
227
228
# I could comment on the code, but it's just 26 state machines with
# lots of canvas create and move calls.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .goldberg
catch {destroy $w}
toplevel $w
wm title $w "Tk Goldberg (demonstration)"
wm iconname $w "goldberg"
wm resizable $w 0 0
#positionWindow $w


label $w.msg -font {Arial 10} -wraplength 4i -justify left -text "This is a\
	demonstration of just how complex you can make your animations\

	become. Click the ball to start things moving!\n\n\"Man will always\
	find a difficult means to perform a simple task\"\n - Rube Goldberg"
pack $w.msg -side top

###--- End of Boilerplate ---###






















# Ensure that this this is an array
array set animationCallbacks {}
bind $w <Destroy> {
    if {"%W" eq [winfo toplevel %W]} {
	unset S C speed
    }
}

set S(title) "Tk Goldberg"
set S(speed) 5
set S(cnt) 0
set S(message) "\\nWelcome\\nto\\nTcl/Tk"
array set speed {1 10 2 20 3 50 4 80 5 100 6 150 7 200 8 300 9 400 10 500}


set MSTART 0; set MGO 1; set MPAUSE 2; set MSSTEP 3; set MBSTEP 4; set MDONE 5
set S(mode) $::MSTART

# Colors for everything
set C(fg) black
set C(bg) gray75
set C(bg) cornflowerblue

set C(0) white;		set C(1a) darkgreen;	set C(1b) yellow
set C(2) red;		set C(3a) green;	set C(3b) darkblue
set C(4) $C(fg);	set C(5a) brown;	set C(5b) white
set C(6) magenta;	set C(7) green;		set C(8) $C(fg)
set C(9) blue4;		set C(10a) white;	set C(10b) cyan
set C(11a) yellow;	set C(11b) mediumblue;	set C(12) tan2
set C(13a) yellow;	set C(13b) red;		set C(14) white
set C(15a) green;	set C(15b) yellow;	set C(16) gray65
set C(17) \#A65353;	set C(18) $C(fg);	set C(19) gray50
set C(20) cyan;		set C(21) gray65;	set C(22) $C(20)
set C(23a) blue;	set C(23b) red;		set C(23c) yellow
set C(24a) red;		set C(24b) white;


proc DoDisplay {w} {
    global S C

    ttk::frame $w.ctrl -relief ridge -borderwidth 2 -padding 5
    pack [frame $w.screen -bd 2 -relief raised] \
	    -side left -fill both -expand 1


    canvas $w.c -width 860 -height 730 -bg $C(bg) -highlightthickness 0
    $w.c config -scrollregion {0 0 1000 1000}	;# Kludge: move everything up
    $w.c yview moveto .05
    pack $w.c -in $w.screen -side top -fill both -expand 1


    bind $w.c <Button-3> [list $w.pause invoke]
    bind $w.c <Destroy> {
	after cancel $animationCallbacks(goldberg)
	unset animationCallbacks(goldberg)
    }
    DoCtrlFrame $w
    DoDetailFrame $w
    if {[tk windowingsystem] ne "aqua"} {
	ttk::button $w.show -text "»" -command [list ShowCtrl $w] -width 2
    } else {


	button $w.show -text "»" -command [list ShowCtrl $w] -width 2 -highlightbackground $C(bg)
    }
    place $w.show -in $w.c -relx 1 -rely 0 -anchor ne
    update
}

proc DoCtrlFrame {w} {
    global S
    ttk::button $w.start -text "Start" -command [list DoButton $w 0]
    ttk::checkbutton $w.pause -text "Pause" -command [list DoButton $w 1] \
	    -variable S(pause)
    ttk::button $w.step -text "Single Step" -command [list DoButton $w 2]
    ttk::button $w.bstep -text "Big Step" -command [list DoButton $w 4]
    ttk::button $w.reset -text "Reset" -command [list DoButton $w 3]
    ttk::labelframe $w.details
    raise $w.details
    set S(details) 0
    ttk::checkbutton $w.details.cb -text "Details" -variable S(details)
    ttk::labelframe $w.message -text "Message"
    ttk::entry $w.message.e -textvariable S(message) -justify center
    ttk::labelframe $w.speed -text "Speed: 0"
    ttk::scale $w.speed.scale -orient h -from 1 -to 10 -variable S(speed)

    ttk::button $w.about -text About -command [list About $w]

    grid $w.start -in $w.ctrl -row 0 -sticky ew
    grid rowconfigure $w.ctrl 1 -minsize 10
    grid $w.pause -in $w.ctrl -row 2 -sticky ew
    grid $w.step  -in $w.ctrl -sticky ew -pady 2
    grid $w.bstep -in $w.ctrl -sticky ew
    grid $w.reset -in $w.ctrl -sticky ew -pady 2
    grid rowconfigure $w.ctrl 10 -minsize 18
    grid $w.details -in $w.ctrl -row 11 -sticky ew
    grid rowconfigure $w.ctrl 11 -minsize 20
    $w.details configure -labelwidget $w.details.cb
    grid [ttk::frame $w.details.b -height 1]	;# Work around minor bug
    raise $w.details
    raise $w.details.cb
    grid rowconfigure $w.ctrl 50 -weight 1
    trace variable ::S(mode) w	  [list ActiveGUI $w]
    trace variable ::S(details) w [list ActiveGUI $w]
    trace variable ::S(speed) w	  [list ActiveGUI $w]

    grid $w.message -in $w.ctrl -row 98 -sticky ew -pady 5
    grid $w.message.e -sticky nsew
    grid $w.speed -in $w.ctrl -row 99 -sticky ew -pady {0 5}
    pack $w.speed.scale -fill both -expand 1
    grid $w.about -in $w.ctrl -row 100 -sticky ew
    bind $w.reset <Button-3> {set S(mode) -1}		;# Debugging

    ## See Code / Dismiss buttons hack!
    set btns [addSeeDismiss $w.ctrl.buttons $w]
    grid [ttk::separator $w.ctrl.sep] -sticky ew -pady 4
    set i 0
    foreach b [winfo children $btns] {
	if {[winfo class $b] eq "TButton"} {





	    grid [set b2 [ttk::button $w.ctrl.b[incr i]]] -sticky ew
	    foreach b3 [$b configure] {
		set b3 [lindex $b3 0]
		# Some options are read-only; ignore those errors
		catch {$b2 configure $b3 [$b cget $b3]}
	    }
	}
    }
    destroy $btns
}

proc DoDetailFrame {w} {
    set w2 $w.details.f
    ttk::frame $w2

    set bd 2
    ttk::label $w2.l -textvariable S(cnt) -background white
    grid $w2.l - - - -sticky ew -row 0
    for {set i 1} {1} {incr i} {
	if {[info procs "Move$i"] eq ""} break
	ttk::label $w2.l$i -text $i -anchor e -width 2 -background white
	ttk::label $w2.ll$i -textvariable STEP($i) -width 5 -background white
	set row [expr {($i + 1) / 2}]
	set col [expr {(($i + 1) & 1) * 2}]
	grid $w2.l$i -sticky ew -row $row -column $col
	grid $w2.ll$i -sticky ew -row $row -column [incr col]
    }
    grid columnconfigure $w2 1 -weight 1
}

# Map or unmap the ctrl window
proc ShowCtrl {w} {
    if {[winfo ismapped $w.ctrl]} {
	pack forget $w.ctrl
	$w.show config -text "»"
    } else {
	pack $w.ctrl -side right -fill both -ipady 5
	$w.show config -text "»"
    }
}

proc DrawAll {w} {

    ResetStep
    $w.c delete all
    for {set i 0} {1} {incr i} {
	set p "Draw$i"
	if {[info procs $p] eq ""} break
	$p $w
    }


































}

proc ActiveGUI {w var1 var2 op} {
    global S MGO MSTART MDONE
    array set z {0 disabled 1 normal}

    set m $S(mode)







|









>
|
|
>
|
|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|



|






|
|
>






<














>


|

|
|


>
|
|
|


>








|

>
>
|




















|
>



|

|

|
|

|





|
|
|

|

|





<
|
|
|

>
>
>
>
>
|
|
|
|
|
<









<


















|


|




>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# I could comment on the code, but it's just 26 state machines with
# lots of canvas create and move calls.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .goldberg
catch {destroy $w}
toplevel $w
wm title $w "Tk Goldberg (demonstration)"
wm iconname $w "goldberg"
wm resizable $w 0 0
#positionWindow $w

proc StartMessage {w} {
    set msg1 "This\
	    is a demonstration of just how complex you can make your animations\
	    become. Close this dialog and click the ball to start things\
	    moving!\n\n\"Man will always find a difficult means to perform a\
	    simple task\"\n - Rube Goldberg"
    PlacedDialog $w.c.messframe $msg1 {Helvetica 12}
}
###--- End of Boilerplate ---###

array set BaseDimensions {
    CanX    675
    CanY    540
    ScrX    750
    ScrY    750
    MsgX    338
    MsgY    573
    MovX     10
    MovY    -45
}

# The original value was 1.0 but this can make the demo
# too large for the screen.  Try a smaller value.
set overallFactor 0.75

foreach el [array names BaseDimensions] {
    set Dims($el) [expr {$BaseDimensions($el) * $overallFactor}]p
}

set scaleFactor [expr {$::tk::scalingPct / 100.0 * $overallFactor}]

# Ensure that this is an array
array set animationCallbacks {}
bind $w <Destroy> {
    if {"%W" eq [winfo toplevel %W]} {
	unset S C delays
    }
}

set S(title) "Tk Goldberg"
set S(speed) 5
set S(cnt) 0
set S(message) "\\nWelcome\\nto\\nTcl/Tk!"
array set delays \
	{1 500  2 400  3 300  4 200  5 150  6 100  7 80  8 50  9 20  10 10}

set MSTART 0; set MGO 1; set MPAUSE 2; set MSSTEP 3; set MBSTEP 4; set MDONE 5
set S(mode) $::MSTART

# Colors for everything
set C(fg) black

set C(bg) cornflowerblue

set C(0) white;		set C(1a) darkgreen;	set C(1b) yellow
set C(2) red;		set C(3a) green;	set C(3b) darkblue
set C(4) $C(fg);	set C(5a) brown;	set C(5b) white
set C(6) magenta;	set C(7) green;		set C(8) $C(fg)
set C(9) blue4;		set C(10a) white;	set C(10b) cyan
set C(11a) yellow;	set C(11b) mediumblue;	set C(12) tan2
set C(13a) yellow;	set C(13b) red;		set C(14) white
set C(15a) green;	set C(15b) yellow;	set C(16) gray65
set C(17) \#A65353;	set C(18) $C(fg);	set C(19) gray50
set C(20) cyan;		set C(21) gray65;	set C(22) $C(20)
set C(23a) blue;	set C(23b) red;		set C(23c) yellow
set C(24a) red;		set C(24b) white;
set C(24c) black;	set C(26) $C(0);

proc DoDisplay {w} {
    global S C Dims

    ttk::frame $w.ctrl -relief ridge -borderwidth 1 -padding 3p
    pack [frame $w.screen -bd 1 -relief raised] \
	    -side left -fill both -expand 1

    canvas $w.c -width $Dims(CanX) -height $Dims(CanY) -bg $C(bg) \
	    -highlightthickness 0
    $w.c config -scrollregion [list 0 0 $Dims(ScrX) $Dims(ScrY)]
    $w.c yview moveto .06			;# Kludge: move everything up
    pack $w.c -in $w.screen -side top -fill both -expand 1

    bind $w.c <Configure> { %W yview moveto .06 }
    bind $w.c <Button-3> [list $w.pause invoke]
    bind $w.c <Destroy> {
	after cancel $animationCallbacks(goldberg)
	unset animationCallbacks(goldberg)
    }
    DoCtrlFrame $w
    DoDetailFrame $w
    if {[tk windowingsystem] ne "aqua"} {
	ttk::button $w.show -text "" -command [list ShowCtrl $w] -width 2
    } else {
	button $w.show -text "▶" -command [list ShowCtrl $w] -width 1 \
		-borderwidth 1 -highlightthickness 0 -padx 0 -pady 0 \
		-highlightbackground $C(bg)
    }
    place $w.show -in $w.c -relx 1 -rely 0 -anchor ne
    update
}

proc DoCtrlFrame {w} {
    global S
    ttk::button $w.start -text "Start" -command [list DoButton $w 0]
    ttk::checkbutton $w.pause -text "Pause" -command [list DoButton $w 1] \
	    -variable S(pause)
    ttk::button $w.step -text "Single Step" -command [list DoButton $w 2]
    ttk::button $w.bstep -text "Big Step" -command [list DoButton $w 4]
    ttk::button $w.reset -text "Reset" -command [list DoButton $w 3]
    ttk::labelframe $w.details
    raise $w.details
    set S(details) 0
    ttk::checkbutton $w.details.cb -text "Details" -variable S(details)
    ttk::labelframe $w.message -text "Message"
    ttk::entry $w.message.e -textvariable S(message) -justify center
    ttk::labelframe $w.speed -text "Speed: 0"
    ttk::scale $w.speed.scale -orient horizontal -from 1 -to 10 \
	    -variable S(speed)
    ttk::button $w.about -text About -command [list About $w]

    grid $w.start -in $w.ctrl -row 0 -sticky ew
    grid rowconfigure $w.ctrl 1 -minsize 3p
    grid $w.pause -in $w.ctrl -row 2 -sticky ew
    grid $w.step  -in $w.ctrl -sticky ew -pady 1.5p
    grid $w.bstep -in $w.ctrl -sticky ew
    grid $w.reset -in $w.ctrl -sticky ew -pady 1.5p
    grid rowconfigure $w.ctrl 10 -minsize 3p
    grid $w.details -in $w.ctrl -row 11 -sticky ew
    grid rowconfigure $w.ctrl 11 -minsize 3p
    $w.details configure -labelwidget $w.details.cb
    grid [ttk::frame $w.details.b -height 1]	;# Work around minor bug
    raise $w.details
    raise $w.details.cb
    grid rowconfigure $w.ctrl 50 -weight 1
    trace add variable ::S(mode) write	  [list ActiveGUI $w]
    trace add variable ::S(details) write [list ActiveGUI $w]
    trace add variable ::S(speed) write	  [list ActiveGUI $w]

    grid $w.message -in $w.ctrl -row 98 -sticky ew -pady {0 3p}
    grid $w.message.e -sticky nsew
    grid $w.speed -in $w.ctrl -row 99 -sticky ew -pady {0 3p}
    pack $w.speed.scale -fill both -expand 1
    grid $w.about -in $w.ctrl -row 100 -sticky ew
    bind $w.reset <Button-3> {set S(mode) -1}		;# Debugging

    ## See Code / Dismiss buttons hack!

    grid [ttk::separator $w.ctrl.sep] -sticky ew -pady {3p 1.5p}
    set btns {}
    foreach b [winfo children [addSeeDismiss $w.ctrl.buttons $w]] {
	if {[winfo class $b] eq "TButton"} {
	    set btns [linsert $btns 0 $b]		;# Prepend
	}
    }
    set i 0
    foreach b $btns {
	grid [set b2 [ttk::button $w.ctrl.b[incr i]]] -sticky ew -pady {1.5p 0}
	foreach b3 [$b configure] {
	    set b3 [lindex $b3 0]
	    # Some options are read-only; ignore those errors
	    catch {$b2 configure $b3 [$b cget $b3]}

	}
    }
    destroy $btns
}

proc DoDetailFrame {w} {
    set w2 $w.details.f
    ttk::frame $w2


    ttk::label $w2.l -textvariable S(cnt) -background white
    grid $w2.l - - - -sticky ew -row 0
    for {set i 1} {1} {incr i} {
	if {[info procs "Move$i"] eq ""} break
	ttk::label $w2.l$i -text $i -anchor e -width 2 -background white
	ttk::label $w2.ll$i -textvariable STEP($i) -width 5 -background white
	set row [expr {($i + 1) / 2}]
	set col [expr {(($i + 1) & 1) * 2}]
	grid $w2.l$i -sticky ew -row $row -column $col
	grid $w2.ll$i -sticky ew -row $row -column [incr col]
    }
    grid columnconfigure $w2 1 -weight 1
}

# Map or unmap the ctrl window
proc ShowCtrl {w} {
    if {[winfo ismapped $w.ctrl]} {
	pack forget $w.ctrl
	$w.show config -text ""
    } else {
	pack $w.ctrl -side right -fill both -ipady 5
	$w.show config -text ""
    }
}

proc DrawAll {w} {
    global scaleFactor
    ResetStep
    $w.c delete all
    for {set i 0} {1} {incr i} {
	set p "Draw$i"
	if {[info procs $p] eq ""} break
	$p $w
    }

    $w.c scale all 0 0 $scaleFactor $scaleFactor

    # Tile the strike box with a 4x4 bitmap image derived
    # from Tk's built-in 16x16 bitmap gray25.  Adjust
    # x1, y2 to make dimensions multiples of 4 pixels.

    image create bitmap smallGray25 -data {
	#define smallGray25_width 4
	#define smallGray25_height 4
	static unsigned char smallGray25_bits[] = {
	    0x08, 0x02, 0x08, 0x02};
    } -foreground $::C(fg)

    lassign [$w.c coords StrikeBox] x1 y1 x2 y2
    set oldMidY [expr {round(($y1 + $y2) / 2.0)}]

    set rowCount [expr {round(($y2 - $y1) / 4.0)}]
    set colCount [expr {round(($x2 - $x1) / 4.0)}]
    set x2 [expr {round($x2)}]
    set x1 [expr {$x2 - $colCount * 4}]
    set y1 [expr {round($y1)}]
    set y2 [expr {$y1 + $rowCount * 4}]

    set newMidY [expr {round(($y1 + $y2) / 2.0)}]
    set deltaY [expr {$oldMidY - $newMidY}]
    incr y1 $deltaY; incr y2 $deltaY
    $w.c coords StrikeBox $x1 $y1 $x2 $y2

    for {set row 0; set y $y1} {$row < $rowCount} {incr row; incr y 4} {
	for {set col 0; set x $x1} {$col < $colCount} {incr col; incr x 4} {
	    $w.c create image $x $y -image smallGray25 -anchor nw
	}
    }
}

proc ActiveGUI {w var1 var2 op} {
    global S MGO MSTART MDONE
    array set z {0 disabled 1 normal}

    set m $S(mode)
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
	Reset $w
    } elseif {$what == 4} {			;# Big step
	set S(mode) $MBSTEP
    }
}

proc Go {w {who {}}} {
    global S speed animationCallbacks MGO MPAUSE MSSTEP MBSTEP

    set now [clock clicks -milliseconds]
    catch {after cancel $animationCallbacks(goldberg)}
    if {$who ne ""} {				;# Start here for debugging
	set S(active) $who;
	set S(mode) $MGO
    }
    if {$S(mode) == -1} return			;# Debugging
    set n 0
    if {$S(mode) != $MPAUSE} {			;# Not paused
	set n [NextStep $w]			;# Do the next move
    }
    if {$S(mode) == $MSSTEP} {			;# Single step
	set S(mode) $MPAUSE
    }
    if {$S(mode) == $MBSTEP && $n} {		;# Big step
	set S(mode) $MSSTEP
    }

    set elapsed [expr {[clock click -milliseconds] - $now}]
    set delay [expr {$speed($S(speed)) - $elapsed}]
    if {$delay <= 0} {
	set delay 1
    }
    set animationCallbacks(goldberg) [after $delay [list Go $w]]
}

# NextStep: drives the next step of the animation







|




|















|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
	Reset $w
    } elseif {$what == 4} {			;# Big step
	set S(mode) $MBSTEP
    }
}

proc Go {w {who {}}} {
    global S delays animationCallbacks MGO MPAUSE MSSTEP MBSTEP

    set now [clock clicks -milliseconds]
    catch {after cancel $animationCallbacks(goldberg)}
    if {$who ne ""} {				;# Start here for debugging
	set S(active) $who
	set S(mode) $MGO
    }
    if {$S(mode) == -1} return			;# Debugging
    set n 0
    if {$S(mode) != $MPAUSE} {			;# Not paused
	set n [NextStep $w]			;# Do the next move
    }
    if {$S(mode) == $MSSTEP} {			;# Single step
	set S(mode) $MPAUSE
    }
    if {$S(mode) == $MBSTEP && $n} {		;# Big step
	set S(mode) $MSSTEP
    }

    set elapsed [expr {[clock click -milliseconds] - $now}]
    set delay [expr {$delays($S(speed)) - $elapsed}]
    if {$delay <= 0} {
	set delay 1
    }
    set animationCallbacks(goldberg) [after $delay [list Go $w]]
}

# NextStep: drives the next step of the animation
318
319
320
321
322
323
324

325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360


361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
	    set S(active) {}			;# No more animation
	    return 1
	}
    }
    set S(active) $alive
    return $rval
}

proc About {w} {
    set msg "$::S(title)\nby Keith Vetter, March 2003\n(Reproduced by kind\
	    permission of the author)\n\n\"Man will always find a difficult\
	    means to perform a simple task.\"\nRube Goldberg"
    tk_messageBox -parent $w -message $msg -title About

}
################################################################
#
# All the drawing and moving routines
#

# START HERE! banner
proc Draw0 {w} {
    set color $::C(0)
    set xy {579 119}
    $w.c create text $xy -text "START HERE!" -fill $color -anchor w \
	    -tag I0 -font {{Times Roman} 12 italic bold}
    set xy {719 119 763 119}
    $w.c create line $xy -tag I0 -fill $color -width 5 -arrow last \
	    -arrowshape {18 18 5}
    $w.c bind I0 <Button-1> Start
}
proc Move0 {w {step {}}} {
    set step [GetStep 0 $step]

    if {$::S(mode) > $::MSTART} {		;# Start the ball rolling
	MoveAbs $w I0 {-100 -100}		;# Hide the banner
	return 2
    }

    set pos {
	{673 119} {678 119} {683 119} {688 119}
	{693 119} {688 119} {683 119} {678 119}
    }
    set step [expr {$step % [llength $pos]}]
    MoveAbs $w I0 [lindex $pos $step]


    return 1
}

# Dropping ball
proc Draw1 {w} {
    set color $::C(1a)
    set color2 $::C(1b)
    set xy {844 133 800 133 800 346 820 346 820 168 844 168 844 133}
    $w.c create poly $xy -width 3 -fill $color -outline {}
    set xy {771 133 685 133 685 168 751 168 751 346 771 346 771 133}
    $w.c create poly $xy -width 3 -fill $color -outline {}

    set xy [box 812 122 9]
    $w.c create oval $xy -tag I1 -fill $color2 -outline {}
    $w.c bind I1 <Button-1> Start
}
proc Move1 {w {step {}}} {
    set step [GetStep 1 $step]
    set pos {
	{807 122} {802 122} {797 123} {793 124} {789 129} {785 153}
	{785 203} {785 278 x} {785 367} {810 392} {816 438} {821 503}
	{824 585 y} {838 587} {848 593} {857 601} {-100 -100}
    }
    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I1 $where

    if {[lindex $where 2] eq "y"} {







>



|
|
>









|
|
|

|
|










|
|
|
|

|
>
>








|

|







|



|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
	    set S(active) {}			;# No more animation
	    return 1
	}
    }
    set S(active) $alive
    return $rval
}

proc About {w} {
    set msg "$::S(title)\nby Keith Vetter, March 2003\n(Reproduced by kind\
	    permission of the author)\n\n\"Man will always find a difficult\
	    means to perform a simple task.\"\n - Rube Goldberg"
    PlacedDialog $w.c.messframe $msg {Helvetica 12 bold}
    return
}
################################################################
#
# All the drawing and moving routines
#

# START HERE! banner
proc Draw0 {w} {
    set color $::C(0)
    set xy {699 119}
    $w.c create text $xy -text "START HERE!" -fill $color -anchor e \
	    -tag {I0 I0_0} -font {Times 12 italic bold}
    set xy {719 119 763 119}
    $w.c create line $xy -tag {I0 I0_1} -fill $color -width 3.75p -arrow last \
	    -arrowshape {13.5p 13.5p 3.75p}
    $w.c bind I0 <Button-1> Start
}
proc Move0 {w {step {}}} {
    set step [GetStep 0 $step]

    if {$::S(mode) > $::MSTART} {		;# Start the ball rolling
	MoveAbs $w I0 {-100 -100}		;# Hide the banner
	return 2
    }

    set pos [scl {
	{719 119} {724 119} {729 119} {734 119}
	{739 119} {734 119} {729 119} {724 119}
    }]
    set step [expr {$step % [llength $pos]}]
    lassign [lindex $pos $step] x y
    $w.c coords I0_0 [expr {$x - [scl 20]}] $y
    $w.c coords I0_1 $x $y [expr {$x + [scl 44]}] $y
    return 1
}

# Dropping ball
proc Draw1 {w} {
    set color $::C(1a)
    set color2 $::C(1b)
    set xy {844 133 800 133 800 346 820 346 820 168 844 168 844 133}
    $w.c create poly $xy -width 2.25p -fill $color -outline {}
    set xy {771 133 685 133 685 168 751 168 751 346 771 346 771 133}
    $w.c create poly $xy -width 2.25p -fill $color -outline {}

    set xy [box 812 122 9]
    $w.c create oval $xy -tag I1 -fill $color2 -outline {}
    $w.c bind I1 <Button-1> Start
}
proc Move1 {w {step {}}} {
    set step [GetStep 1 $step]
    set pos [scl {
	{807 122} {802 122} {797 123} {793 124} {789 129} {785 153}
	{785 203} {785 278 x} {785 367} {810 392} {816 438} {821 503}
	{824 585 y} {838 587} {848 593} {857 601} {-100 -100}
    }]
    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I1 $where

    if {[lindex $where 2] eq "y"} {
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
# Lighting the match
proc Draw2 {w} {
    set color red
    set color $::C(2)
    set xy  {750 369 740 392 760 392}		;# Fulcrum
    $w.c create poly $xy -fill $::C(fg) -outline $::C(fg)
    set xy {628 335 660 383}			;# Strike box
    $w.c create rect $xy -fill {} -outline $::C(fg)
    for {set y 0} {$y < 3} {incr y} {
	set yy [expr {335+$y*16}]
	$w.c create bitmap 628 $yy -bitmap gray25 -anchor nw \
		-foreground $::C(fg)
	$w.c create bitmap 644 $yy -bitmap gray25 -anchor nw \
		-foreground $::C(fg)
    }

    set xy {702 366 798 366}			;# Lever
    $w.c create line $xy -fill $::C(fg) -width 6 -tag I2_0
    set xy {712 363 712 355}			;# R strap
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I2_1
    set xy {705 363 705 355}			;# L strap
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I2_2
    set xy {679 356 679 360 717 360 717 356 679 356}	;# Match stick
    $w.c create line $xy -fill $::C(fg) -tag I2_3

    #set xy {662 352 680 365}			;# Match head
    set xy {
	671 352 677.4 353.9 680 358.5 677.4 363.1 671 365 664.6 363.1
	662 358.5 664.6 353.9
    }
    $w.c create poly $xy -fill $color -outline $color -tag I2_4
}
proc Move2 {w {step {}}} {
    set step [GetStep 2 $step]

    set stages {0 0 1 2 0 2 1 0 1 2 0 2 1}
    set xy(0) {
	686 333 692 323 682 316 674 309 671 295 668 307 662 318 662 328
	671 336
    }

    set xy(1) {687 331 698 322 703 295 680 320 668 297 663 311 661 327 671 335}
    set xy(2) {
	686 331 704 322 688 300 678 283 678 283 674 298 666 309 660 324
	672 336
    }

    if {$step >= [llength $stages]} {
	$w.c delete I2
	return 0
    }

    if {$step == 0} {				;# Rotate the match







|
<
<
<
<
<
<
|
<

|

|

|














|


|
>
|
|


|







469
470
471
472
473
474
475
476






477

478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# Lighting the match
proc Draw2 {w} {
    set color red
    set color $::C(2)
    set xy  {750 369 740 392 760 392}		;# Fulcrum
    $w.c create poly $xy -fill $::C(fg) -outline $::C(fg)
    set xy {628 335 660 383}			;# Strike box
    $w.c create rect $xy -fill {} -outline $::C(fg) -tag StrikeBox








    set xy {702 366 798 366}			;# Lever
    $w.c create line $xy -fill $::C(fg) -width 5.25p -tag I2_0
    set xy {712 363 712 355}			;# R strap
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I2_1
    set xy {705 363 705 355}			;# L strap
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I2_2
    set xy {679 356 679 360 717 360 717 356 679 356}	;# Match stick
    $w.c create line $xy -fill $::C(fg) -tag I2_3

    #set xy {662 352 680 365}			;# Match head
    set xy {
	671 352 677.4 353.9 680 358.5 677.4 363.1 671 365 664.6 363.1
	662 358.5 664.6 353.9
    }
    $w.c create poly $xy -fill $color -outline $color -tag I2_4
}
proc Move2 {w {step {}}} {
    set step [GetStep 2 $step]

    set stages {0 0 1 2 0 2 1 0 1 2 0 2 1}
    set xy(0) [scl {
	686 333 692 323 682 316 674 309 671 295 668 307 662 318 662 328
	671 336
    }]
    set xy(1) [scl {
	687 331 698 322 703 295 680 320 668 297 663 311 661 327 671 335}]
    set xy(2) [scl {
	686 331 704 322 688 300 678 283 678 283 674 298 666 309 660 324
	672 336
    }]

    if {$step >= [llength $stages]} {
	$w.c delete I2
	return 0
    }

    if {$step == 0} {				;# Rotate the match
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
proc Draw3 {w} {
    set color $::C(3a)
    set color2 $::C(3b)

    set xy {602 296 577 174 518 174}
    foreach {x y} $xy {				;# 3 Pulleys
	$w.c create oval [box $x $y 13] -fill $color -outline $::C(fg) \
		-width 3
	$w.c create oval [box $x $y 2] -fill $::C(fg) -outline $::C(fg)
    }

    set xy {750 309 670 309}			;# Wall to flame
    $w.c create line $xy -tag I3_s -width 3 -fill $::C(fg) -smooth 1
    set xy {670 309 650 309}			;# Flame to pulley 1
    $w.c create line $xy -tag I3_0 -width 3 -fill $::C(fg)
    set xy {650 309 600 309}			;# Flame to pulley 1
    $w.c create line $xy -tag I3_1 -width 3 -fill $::C(fg)
    set xy {589 296 589 235}			;# Pulley 1 half way to 2
    $w.c create line $xy -tag I3_2 -width 3 -fill $::C(fg)
    set xy {589 235 589 174}			;# Pulley 1 other half to 2
    $w.c create line $xy -width 3 -fill $::C(fg)
    set xy {577 161 518 161}			;# Across the top
    $w.c create line $xy -width 3 -fill $::C(fg)
    set xy {505 174 505 205}			;# Down to weight
    $w.c create line $xy -tag I3_w -width 3 -fill $::C(fg)

    # Draw the weight as 2 circles, two rectangles and 1 rounded rectangle
    set xy {515 207 495 207}
    foreach {x1 y1 x2 y2} $xy {
	$w.c create oval [box $x1 $y1 6] -tag I3_ -fill $color2 \
		-outline $color2
	$w.c create oval [box $x2 $y2 6] -tag I3_ -fill $color2 \
		-outline $color2
	incr y1 -6; incr y2 6
	$w.c create rect $x1 $y1 $x2 $y2 -tag I3_ -fill $color2 \
		-outline $color2
    }
    set xy {492 220 518 263}
    set xy [RoundRect $w $xy 15]
    $w.c create poly $xy -smooth 1 -tag I3_ -fill $color2 -outline $color2
    set xy {500 217 511 217}
    $w.c create line $xy -tag I3_ -fill $color2 -width 10

    set xy {502 393 522 393 522 465}		;# Bottom weight target
    $w.c create line $xy -tag I3__ -fill $::C(fg) -join miter -width 10
}
proc Move3 {w {step {}}} {
    set step [GetStep 3 $step]

    set pos {{505 247} {505 297} {505 386.5} {505 386.5}}
    set rope(0) {750 309 729 301 711 324 690 300}
    set rope(1) {750 309 737 292 736 335 717 315 712 320}
    set rope(2) {750 309 737 309 740 343 736 351 725 340}
    set rope(3) {750 309 738 321 746 345 742 356}

    if {$step >= [llength $pos]} {
	return 0
    }

    $w.c delete "I3_$step"			;# Delete part of the rope
    MoveAbs $w I3_ [lindex $pos $step]		;# Move weight down
    $w.c coords I3_s $rope($step)		;# Flapping rope end
    $w.c coords I3_w [concat 505 174 [lindex $pos $step]]
    if {$step == 2} {
	$w.c move I3__ 0 30
	return 2
    }
    return 1
}

# Cage and door
proc Draw4 {w} {
    set color $::C(4)
    lassign {527 356 611 464} x0 y0 x1 y1

    for {set y $y0} {$y <= $y1} {incr y 12} {	;# Horizontal bars
	$w.c create line $x0 $y $x1 $y -fill $color -width 1
    }
    for {set x $x0} {$x <= $x1} {incr x 12} {	;# Vertical bars
	$w.c create line $x $y0 $x $y1 -fill $color -width 1
    }

    set xy {518 464 518 428}			;# Swing gate
    $w.c create line $xy -tag I4 -fill $color -width 3
}
proc Move4 {w {step {}}} {
    set step [GetStep 4 $step]

    set angles {-10 -20 -30 -30}
    if {$step >= [llength $angles]} {
	return 0
    }
    RotateItem $w I4 518 464 [lindex $angles $step]
    $w.c raise I4
    return [expr {$step == 3 ? 3 : 1}]
}

# Mouse
proc Draw5 {w} {
    set color $::C(5a)
    set color2 $::C(5b)
    set xy {377 248 410 248 410 465 518 465}	;# Mouse course
    lappend xy 518 428 451 428 451 212 377 212
    $w.c create poly $xy -fill $color2 -outline $::C(fg) -width 3

    set xy {
	534.5 445.5 541 440 552 436 560 436 569 440 574 446 575 452 574 454
	566 456 554 456 545 456 537 454 530 452
    }
    $w.c create poly $xy -tag {I5 I5_0} -fill $color
    set xy {573 452 592 458 601 460 613 456}	;# Tail
    $w.c create line $xy -tag {I5 I5_1} -fill $color -smooth 1 -width 3
    set xy [box 540 446 2]			;# Eye
    set xy {540 444 541 445 541 447 540 448 538 447 538 445}
    #.c create oval $xy -tag {I5 I5_2} -fill $::C(bg) -outline {}
    $w.c create poly $xy -tag {I5 I5_2} -fill $::C(bg) -outline {} -smooth 1
    set xy {538 454 535 461}			;# Front leg
    $w.c create line $xy -tag {I5 I5_3} -fill $color -width 2
    set xy {566 455 569 462}			;# Back leg
    $w.c create line $xy -tag {I5 I5_4} -fill $color -width 2
    set xy {544 455 545 460}			;# 2nd front leg
    $w.c create line $xy -tag {I5 I5_5} -fill $color -width 2
    set xy {560 455 558 460}			;# 2nd back leg
    $w.c create line $xy -tag {I5 I5_6}	 -fill $color -width 2
}
proc Move5 {w {step {}}} {
    set step [GetStep 5 $step]

    set pos {
	{553 452} {533 452} {513 452} {493 452} {473 452}
	{463 442 30} {445.5 441.5 30} {425.5 434.5 30} {422 414} {422 394}
	{422 374} {422 354} {422 334} {422 314} {422 294}
	{422 274 -30} {422 260.5 -30 x} {422.5 248.5 -28} {425 237}
    }
    if {$step >= [llength $pos]} {
	return 0
    }

    lassign [lindex $pos $step] x y beta next
    MoveAbs $w I5 [list $x $y]
    if {$beta ne ""} {







|




|

|

|

|

|

|

|
















|


|




|
|
|
|
|








|













|


|



|








|










|







|





|

|

|

|




|




|







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
proc Draw3 {w} {
    set color $::C(3a)
    set color2 $::C(3b)

    set xy {602 296 577 174 518 174}
    foreach {x y} $xy {				;# 3 Pulleys
	$w.c create oval [box $x $y 13] -fill $color -outline $::C(fg) \
		-width 2.25p
	$w.c create oval [box $x $y 2] -fill $::C(fg) -outline $::C(fg)
    }

    set xy {750 309 670 309}			;# Wall to flame
    $w.c create line $xy -tag I3_s -width 2.25p -fill $::C(fg) -smooth 1
    set xy {670 309 650 309}			;# Flame to pulley 1
    $w.c create line $xy -tag I3_0 -width 2.25p -fill $::C(fg)
    set xy {650 309 600 309}			;# Flame to pulley 1
    $w.c create line $xy -tag I3_1 -width 2.25p -fill $::C(fg)
    set xy {589 296 589 235}			;# Pulley 1 half way to 2
    $w.c create line $xy -tag I3_2 -width 2.25p -fill $::C(fg)
    set xy {589 235 589 174}			;# Pulley 1 other half to 2
    $w.c create line $xy -width 2.25p -fill $::C(fg)
    set xy {577 161 518 161}			;# Across the top
    $w.c create line $xy -width 2.25p -fill $::C(fg)
    set xy {505 174 505 205}			;# Down to weight
    $w.c create line $xy -tag I3_w -width 2.25p -fill $::C(fg)

    # Draw the weight as 2 circles, two rectangles and 1 rounded rectangle
    set xy {515 207 495 207}
    foreach {x1 y1 x2 y2} $xy {
	$w.c create oval [box $x1 $y1 6] -tag I3_ -fill $color2 \
		-outline $color2
	$w.c create oval [box $x2 $y2 6] -tag I3_ -fill $color2 \
		-outline $color2
	incr y1 -6; incr y2 6
	$w.c create rect $x1 $y1 $x2 $y2 -tag I3_ -fill $color2 \
		-outline $color2
    }
    set xy {492 220 518 263}
    set xy [RoundRect $w $xy 15]
    $w.c create poly $xy -smooth 1 -tag I3_ -fill $color2 -outline $color2
    set xy {500 217 511 217}
    $w.c create line $xy -tag I3_ -fill $color2 -width 7.5p

    set xy {502 393 522 393 522 465}		;# Bottom weight target
    $w.c create line $xy -tag I3__ -fill $::C(fg) -join miter -width 7.5p
}
proc Move3 {w {step {}}} {
    set step [GetStep 3 $step]

    set pos [scl {{505 247} {505 297} {505 386.5} {505 386.5}}]
    set rope(0) [scl {750 309 729 301 711 324 690 300}]
    set rope(1) [scl {750 309 737 292 736 335 717 315 712 320}]
    set rope(2) [scl {750 309 737 309 740 343 736 351 725 340}]
    set rope(3) [scl {750 309 738 321 746 345 742 356}]

    if {$step >= [llength $pos]} {
	return 0
    }

    $w.c delete "I3_$step"			;# Delete part of the rope
    MoveAbs $w I3_ [lindex $pos $step]		;# Move weight down
    $w.c coords I3_s $rope($step)		;# Flapping rope end
    $w.c coords I3_w [concat [scl {505 174}] [lindex $pos $step]]
    if {$step == 2} {
	$w.c move I3__ 0 30
	return 2
    }
    return 1
}

# Cage and door
proc Draw4 {w} {
    set color $::C(4)
    lassign {527 356 611 464} x0 y0 x1 y1

    for {set y $y0} {$y <= $y1} {incr y 12} {	;# Horizontal bars
	$w.c create line $x0 $y $x1 $y -fill $color -width 0.75p
    }
    for {set x $x0} {$x <= $x1} {incr x 12} {	;# Vertical bars
	$w.c create line $x $y0 $x $y1 -fill $color -width 0.75p
    }

    set xy {518 464 518 428}			;# Swing gate
    $w.c create line $xy -tag I4 -fill $color -width 2.25p
}
proc Move4 {w {step {}}} {
    set step [GetStep 4 $step]

    set angles {-10 -20 -30 -30}
    if {$step >= [llength $angles]} {
	return 0
    }
    RotateItem $w I4 [scl 518] [scl 464] [lindex $angles $step]
    $w.c raise I4
    return [expr {$step == 3 ? 3 : 1}]
}

# Mouse
proc Draw5 {w} {
    set color $::C(5a)
    set color2 $::C(5b)
    set xy {377 248 410 248 410 465 518 465}	;# Mouse course
    lappend xy 518 428 451 428 451 212 377 212
    $w.c create poly $xy -fill $color2 -outline $::C(fg) -width 2.25p

    set xy {
	534.5 445.5 541 440 552 436 560 436 569 440 574 446 575 452 574 454
	566 456 554 456 545 456 537 454 530 452
    }
    $w.c create poly $xy -tag {I5 I5_0} -fill $color
    set xy {573 452 592 458 601 460 613 456}	;# Tail
    $w.c create line $xy -tag {I5 I5_1} -fill $color -smooth 1 -width 2.25p
    set xy [box 540 446 2]			;# Eye
    set xy {540 444 541 445 541 447 540 448 538 447 538 445}
    #.c create oval $xy -tag {I5 I5_2} -fill $::C(bg) -outline {}
    $w.c create poly $xy -tag {I5 I5_2} -fill $::C(bg) -outline {} -smooth 1
    set xy {538 454 535 461}			;# Front leg
    $w.c create line $xy -tag {I5 I5_3} -fill $color -width 1.5p
    set xy {566 455 569 462}			;# Back leg
    $w.c create line $xy -tag {I5 I5_4} -fill $color -width 1.5p
    set xy {544 455 545 460}			;# 2nd front leg
    $w.c create line $xy -tag {I5 I5_5} -fill $color -width 1.5p
    set xy {560 455 558 460}			;# 2nd back leg
    $w.c create line $xy -tag {I5 I5_6}	 -fill $color -width 1.5p
}
proc Move5 {w {step {}}} {
    set step [GetStep 5 $step]

    set pos [scl {
	{553 452} {533 452} {513 452} {493 452} {473 452}
	{463 442 30} {445.5 441.5 30} {425.5 434.5 30} {422 414} {422 394}
	{422 374} {422 354} {422 334} {422 314} {422 294}
	{422 274 -30} {422 260.5 -30 x} {422.5 248.5 -28} {425 237}
    }]
    if {$step >= [llength $pos]} {
	return 0
    }

    lassign [lindex $pos $step] x y beta next
    MoveAbs $w I5 [list $x $y]
    if {$beta ne ""} {
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686



687

688
689



690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
    13,12 {331 420} 13,13 {360 417} 13,14 {345 412} 13,15 {376 410}
    13,16 {360 403}
}
proc Draw6 {w} {
    set color $::C(6)
    set xy {324 130 391 204}			;# Ball holder
    set xy [RoundRect $w $xy 10]
    $w.c create poly $xy -smooth 1 -outline $::C(fg) -width 3 -fill $color
    set xy {339 204 376 253}			;# Below the ball holder
    $w.c create rect $xy -fill {} -outline $::C(fg) -width 3 -fill $color \
	    -tag I6c
    set xy [box 346 339 28]
    $w.c create oval $xy -fill $color -outline {}	;# Rotor
    $w.c create arc $xy -outline $::C(fg) -width 2 -style arc \
	    -start 80 -extent 205
    $w.c create arc $xy -outline $::C(fg) -width 2 -style arc \
	    -start -41 -extent 85

    set xy [box 346 339 15]			;# Center of rotor
    $w.c create oval $xy -outline $::C(fg) -fill $::C(fg) -tag I6m
    set xy {352 312 352 254 368 254 368 322}	;# Top drop to rotor
    $w.c create poly $xy -fill $color -outline {}
    $w.c create line $xy -fill $::C(fg) -width 2

    set xy {353 240 367 300}			;# Poke bottom hole
    $w.c create rect $xy -fill $color -outline {}
    set xy {341 190 375 210}			;# Poke another hole
    $w.c create rect $xy -fill $color -outline {}

    set xy {368 356 368 403 389 403 389 464 320 464 320 403 352 403 352 366}
    $w.c create poly $xy -fill $color -outline {} -width 2	;# Below rotor
    $w.c create line $xy -fill $::C(fg) -width 2
    set xy [box 275 342 7]			;# On/off rotor
    $w.c create oval $xy -outline $::C(fg) -fill $::C(fg)
    set xy {276 334 342 325}			;# Fan belt top
    $w.c create line $xy -fill $::C(fg) -width 3
    set xy {276 349 342 353}			;# Fan belt bottom
    $w.c create line $xy -fill $::C(fg) -width 3

    set xy {337 212 337 247}			;# What the mouse pushes
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I6_
    set xy {392 212 392 247}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I6_
    set xy {337 230 392 230}
    $w.c create line $xy -fill $::C(fg) -width 7 -tag I6_

    set who -1					;# All the balls
    set colors {red cyan orange green blue darkblue}
    lappend colors {*}$colors {*}$colors

    for {set i 0} {$i < 17} {incr i} {
	set loc [expr {-1 * $i}]
	set color [lindex $colors $i]
	$w.c create oval [box {*}$::XY6($loc) 5] -fill $color \
		-outline $color -tag I6_b$i
    }
    Draw6a $w 12				;# The wheel
}
proc Draw6a {w beta} {
    $w.c delete I6_0



    lassign {346 339} Ox Oy

    for {set i 0} {$i < 4} {incr i} {
	set b [expr {$beta + $i * 45}]



	lassign [RotateC 28 0 0 0 $b] x y

	set xy [list [expr {$Ox+$x}] [expr {$Oy+$y}] \
		[expr {$Ox-$x}] [expr {$Oy-$y}]]
	$w.c create line $xy -tag I6_0 -fill $::C(fg) -width 2
    }
}
proc Move6 {w {step {}}} {
    set step [GetStep 6 $step]
    if {$step > 62} {
	return 0
    }

    if {$step < 2} {				;# Open gate for balls to drop
	$w.c move I6_ -7 0
	if {$step == 1} {			;# Poke a hole
	    set xy {348 226 365 240}
	    $w.c create rect $xy -fill [$w.c itemcget I6c -fill] -outline {}
	}
	return 1
    }

    set s [expr {$step - 1}]			;# Do the gumball drop dance
    for {set i 0} {$i <= int(($s-1) / 3)} {incr i} {
	set tag "I6_b$i"
	if {[$w.c find withtag $tag] eq ""} break
	set loc [expr {$s - 3 * $i}]

	if {[info exists ::XY6($loc,$i)]} {
	    MoveAbs $w $tag $::XY6($loc,$i)
	} elseif {[info exists ::XY6($loc)]} {
	    MoveAbs $w $tag $::XY6($loc)
	}
    }
    if {($s % 3) == 1} {
	set first [expr {($s + 2) / 3}]
	for {set i $first} {1} {incr i} {
	    set tag "I6_b$i"
	    if {[$w.c find withtag $tag] eq ""} break
	    set loc [expr {$first - $i}]
	    MoveAbs $w $tag $::XY6($loc)
	}
    }
    if {$s >= 3} {				;# Rotate the motor
	set idx [expr {$s % 3}]
	#Draw6a $w [lindex {12 35 64} $idx]
	Draw6a $w [expr {12 + $s * 15}]
    }
    return [expr {$s == 3 ? 3 : 1}]
}

# On/off switch
proc Draw7 {w} {
    set color $::C(7)
    set xy {198 306 277 374}			;# Box
    $w.c create rect $xy -outline $::C(fg) -width 2 -fill $color -tag I7z
    $w.c lower I7z
    set xy {275 343 230 349}
    $w.c create line $xy -tag I7 -fill $::C(fg) -arrow last \
	    -arrowshape {23 23 8} -width 6
    set xy {225 324}				;# On button
    $w.c create oval [box {*}$xy 3] -fill $::C(fg) -outline $::C(fg)
    set xy {218 323}				;# On text
    set font {{Times Roman} 8}
    $w.c create text $xy -text "on" -anchor e -fill $::C(fg) -font $font
    set xy {225 350}				;# Off button
    $w.c create oval [box {*}$xy 3] -fill $::C(fg) -outline $::C(fg)
    set xy {218 349}				;# Off button
    $w.c create text $xy -text "off" -anchor e -fill $::C(fg) -font $font
}
proc Move7 {w {step {}}} {
    set step [GetStep 7 $step]
    set numsteps 30
    if {$step > $numsteps} {
	return 0
    }
    set beta [expr {30.0 / $numsteps}]
    RotateItem $w I7 275 343 $beta

    return [expr {$step == $numsteps ? 3 : 1}]
}

# Electricity to the fan
proc Draw8 {w} {
    Sine $w 271 248 271 306 5 8 -tag I8_s -fill $::C(8) -width 3
}
proc Move8 {w {step {}}} {
    set step [GetStep 8 $step]

    if {$step > 3} {
	return 0
    }







|

|



|

|






|







|
|



|

|


|

|

|













|

>
>
>
|
>


>
>
>
|
>


|









|

|












|

|








|





|








|



|



|













|






|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    13,12 {331 420} 13,13 {360 417} 13,14 {345 412} 13,15 {376 410}
    13,16 {360 403}
}
proc Draw6 {w} {
    set color $::C(6)
    set xy {324 130 391 204}			;# Ball holder
    set xy [RoundRect $w $xy 10]
    $w.c create poly $xy -smooth 1 -outline $::C(fg) -width 2.25p -fill $color
    set xy {339 204 376 253}			;# Below the ball holder
    $w.c create rect $xy -fill {} -outline $::C(fg) -width 2.25p -fill $color \
	    -tag I6c
    set xy [box 346 339 28]
    $w.c create oval $xy -fill $color -outline {}	;# Rotor
    $w.c create arc $xy -outline $::C(fg) -width 1.5p -style arc \
	    -start 80 -extent 205
    $w.c create arc $xy -outline $::C(fg) -width 1.5p -style arc \
	    -start -41 -extent 85

    set xy [box 346 339 15]			;# Center of rotor
    $w.c create oval $xy -outline $::C(fg) -fill $::C(fg) -tag I6m
    set xy {352 312 352 254 368 254 368 322}	;# Top drop to rotor
    $w.c create poly $xy -fill $color -outline {}
    $w.c create line $xy -fill $::C(fg) -width 1.5p

    set xy {353 240 367 300}			;# Poke bottom hole
    $w.c create rect $xy -fill $color -outline {}
    set xy {341 190 375 210}			;# Poke another hole
    $w.c create rect $xy -fill $color -outline {}

    set xy {368 356 368 403 389 403 389 464 320 464 320 403 352 403 352 366}
    $w.c create poly $xy -fill $color -outline {} -width 1.5p	;# Below rotor
    $w.c create line $xy -fill $::C(fg) -width 1.5p
    set xy [box 275 342 7]			;# On/off rotor
    $w.c create oval $xy -outline $::C(fg) -fill $::C(fg)
    set xy {276 334 342 325}			;# Fan belt top
    $w.c create line $xy -fill $::C(fg) -width 2.25p
    set xy {276 349 342 353}			;# Fan belt bottom
    $w.c create line $xy -fill $::C(fg) -width 2.25p

    set xy {337 212 337 247}			;# What the mouse pushes
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I6_
    set xy {392 212 392 247}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I6_
    set xy {337 230 392 230}
    $w.c create line $xy -fill $::C(fg) -width 5.25p -tag I6_

    set who -1					;# All the balls
    set colors {red cyan orange green blue darkblue}
    lappend colors {*}$colors {*}$colors

    for {set i 0} {$i < 17} {incr i} {
	set loc [expr {-1 * $i}]
	set color [lindex $colors $i]
	$w.c create oval [box {*}$::XY6($loc) 5] -fill $color \
		-outline $color -tag I6_b$i
    }
    Draw6a $w 12				;# The wheel
}
proc Draw6a {w beta {scale 0}} {
    $w.c delete I6_0
    if {$scale} {
	lassign [scl {346 339}] Ox Oy
    } else {
	lassign {346 339} Ox Oy
    }
    for {set i 0} {$i < 4} {incr i} {
	set b [expr {$beta + $i * 45}]
	if {$scale} {
	    lassign [RotateC [scl 28] 0 0 0 $b] x y
	} else {
	    lassign [RotateC 28 0 0 0 $b] x y
	}
	set xy [list [expr {$Ox+$x}] [expr {$Oy+$y}] \
		[expr {$Ox-$x}] [expr {$Oy-$y}]]
	$w.c create line $xy -tag I6_0 -fill $::C(fg) -width 1.5p
    }
}
proc Move6 {w {step {}}} {
    set step [GetStep 6 $step]
    if {$step > 62} {
	return 0
    }

    if {$step < 2} {				;# Open gate for balls to drop
	$w.c move I6_ -5.25p 0
	if {$step == 1} {			;# Poke a hole
	    set xy [scl {348 226 365 240}]
	    $w.c create rect $xy -fill [$w.c itemcget I6c -fill] -outline {}
	}
	return 1
    }

    set s [expr {$step - 1}]			;# Do the gumball drop dance
    for {set i 0} {$i <= int(($s-1) / 3)} {incr i} {
	set tag "I6_b$i"
	if {[$w.c find withtag $tag] eq ""} break
	set loc [expr {$s - 3 * $i}]

	if {[info exists ::XY6($loc,$i)]} {
	    MoveAbs $w $tag [scl $::XY6($loc,$i)]
	} elseif {[info exists ::XY6($loc)]} {
	    MoveAbs $w $tag [scl $::XY6($loc)]
	}
    }
    if {($s % 3) == 1} {
	set first [expr {($s + 2) / 3}]
	for {set i $first} {1} {incr i} {
	    set tag "I6_b$i"
	    if {[$w.c find withtag $tag] eq ""} break
	    set loc [expr {$first - $i}]
	    MoveAbs $w $tag [scl $::XY6($loc)]
	}
    }
    if {$s >= 3} {				;# Rotate the motor
	set idx [expr {$s % 3}]
	#Draw6a $w [lindex {12 35 64} $idx]
	Draw6a $w [expr {12 + $s * 15}] 1
    }
    return [expr {$s == 3 ? 3 : 1}]
}

# On/off switch
proc Draw7 {w} {
    set color $::C(7)
    set xy {198 306 277 374}			;# Box
    $w.c create rect $xy -outline $::C(fg) -width 1.5p -fill $color -tag I7z
    $w.c lower I7z
    set xy {275 343 230 349}
    $w.c create line $xy -tag I7 -fill $::C(fg) -arrow last \
	    -arrowshape {17.25p 17.25p 6p} -width 4.5p
    set xy {225 324}				;# On button
    $w.c create oval [box {*}$xy 3] -fill $::C(fg) -outline $::C(fg)
    set xy {218 323}				;# On text
    set font {Times 8}
    $w.c create text $xy -text "on" -anchor e -fill $::C(fg) -font $font
    set xy {225 350}				;# Off button
    $w.c create oval [box {*}$xy 3] -fill $::C(fg) -outline $::C(fg)
    set xy {218 349}				;# Off button
    $w.c create text $xy -text "off" -anchor e -fill $::C(fg) -font $font
}
proc Move7 {w {step {}}} {
    set step [GetStep 7 $step]
    set numsteps 30
    if {$step > $numsteps} {
	return 0
    }
    set beta [expr {30.0 / $numsteps}]
    RotateItem $w I7 [scl 275] [scl 343] $beta

    return [expr {$step == $numsteps ? 3 : 1}]
}

# Electricity to the fan
proc Draw8 {w} {
    Sine $w 271 248 271 306 5 8 -tag I8_s -fill $::C(8) -width 2.25p
}
proc Move8 {w {step {}}} {
    set step [GetStep 8 $step]

    if {$step > 3} {
	return 0
    }
802
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
    set xy {288 249 252 249 260 240 280 234 296 234 316 240 324 249 288 249}
    $w.c create poly $xy -fill $color -smooth 1

    set xy {248 205 265 214 264 205 265 196}	;# Spinner
    $w.c create poly $xy -fill $color

    set xy {255 206 265 234}			;# Fan blades
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 3 -tag I9_0
    set xy {255 176 265 204}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 3 -tag I9_0
    set xy {255 206 265 220}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 1 -tag I9_1
    set xy {255 190 265 204}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 1 -tag I9_1
}
proc Move9 {w {step {}}} {
    set step [GetStep 9 $step]

    if {$step & 1} {
	$w.c itemconfig I9_0 -width 4
	$w.c itemconfig I9_1 -width 1
	$w.c lower I9_1 I9_0
    } else {
	$w.c itemconfig I9_0 -width 1
	$w.c itemconfig I9_1 -width 4
	$w.c lower I9_0 I9_1
    }
    if {$step == 0} {
	return 3
    }
    return 1
}

# Boat
proc Draw10 {w} {
    set color $::C(10a)
    set color2 $::C(10b)
    set xy {191 230 233 230 233 178 191 178}	;# Sail
    $w.c create poly $xy -fill $color -width 3 -outline $::C(fg) -tag I10
    set xy [box 209 204 31]			;# Front
    $w.c create arc $xy -outline {} -fill $color -style pie \
	    -start 120 -extent 120 -tag I10
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc \
	    -start 120 -extent 120 -tag I10
    set xy [box 249 204 31]			;# Back
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 3 -style pie \
	    -start 120 -extent 120 -tag I10
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc \
	    -start 120 -extent 120 -tag I10

    set xy {200 171 200 249}			;# Mast
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I10
    set xy {159 234 182 234}			;# Bow sprit
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I10
    set xy {180 234 180 251 220 251}		;# Hull
    $w.c create line $xy -fill $::C(fg) -width 6 -tag I10

    set xy {92 255 221 255}			;# Waves
    Sine $w {*}$xy 2 25 -fill $color2 -width 1 -tag I10w

    set xy [lrange [$w.c coords I10w] 4 end-4]	;# Water
    set xy [concat $xy 222 266 222 277 99 277]
    $w.c create poly $xy -fill $color2 -outline $color2
    set xy {222 266 222 277 97 277 97 266}	;# Water bottom
    $w.c create line $xy -fill $::C(fg) -width 3

    set xy [box 239 262 17]
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc \
	    -start 95 -extent 103
    set xy [box 76 266 21]
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc -extent 190
}
proc Move10 {w {step {}}} {
    set step [GetStep 10 $step]
    set pos {
	{195 212} {193 212} {190 212} {186 212} {181 212} {176 212}
	{171 212} {166 212} {161 212} {156 212} {151 212} {147 212} {142 212}
	{137 212} {132 212 x} {127 212} {121 212} {116 212} {111 212}
    }

    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I10 $where








|

|

|

|





|
|


|
|













|



|


|

|



|

|

|


|





|


|


|



|



|







874
875
876
877
878
879
880
881
882
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
    set xy {288 249 252 249 260 240 280 234 296 234 316 240 324 249 288 249}
    $w.c create poly $xy -fill $color -smooth 1

    set xy {248 205 265 214 264 205 265 196}	;# Spinner
    $w.c create poly $xy -fill $color

    set xy {255 206 265 234}			;# Fan blades
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 2.25p -tag I9_0
    set xy {255 176 265 204}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 2.25p -tag I9_0
    set xy {255 206 265 220}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 0.75p -tag I9_1
    set xy {255 190 265 204}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 0.75p -tag I9_1
}
proc Move9 {w {step {}}} {
    set step [GetStep 9 $step]

    if {$step & 1} {
	$w.c itemconfig I9_0 -width 3p
	$w.c itemconfig I9_1 -width 0.75p
	$w.c lower I9_1 I9_0
    } else {
	$w.c itemconfig I9_0 -width 0.75p
	$w.c itemconfig I9_1 -width 3p
	$w.c lower I9_0 I9_1
    }
    if {$step == 0} {
	return 3
    }
    return 1
}

# Boat
proc Draw10 {w} {
    set color $::C(10a)
    set color2 $::C(10b)
    set xy {191 230 233 230 233 178 191 178}	;# Sail
    $w.c create poly $xy -fill $color -width 2.25p -outline $::C(fg) -tag I10
    set xy [box 209 204 31]			;# Front
    $w.c create arc $xy -outline {} -fill $color -style pie \
	    -start 120 -extent 120 -tag I10
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc \
	    -start 120 -extent 120 -tag I10
    set xy [box 249 204 31]			;# Back
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 2.25p -style pie \
	    -start 120 -extent 120 -tag I10
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc \
	    -start 120 -extent 120 -tag I10

    set xy {200 171 200 249}			;# Mast
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I10
    set xy {159 234 182 234}			;# Bow sprit
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I10
    set xy {180 234 180 251 220 251}		;# Hull
    $w.c create line $xy -fill $::C(fg) -width 4.5p -tag I10

    set xy {92 255 221 255}			;# Waves
    Sine $w {*}$xy 2 25 -fill $color2 -width 0.75p -tag I10w

    set xy [lrange [$w.c coords I10w] 4 end-4]	;# Water
    set xy [concat $xy 222 266 222 277 99 277]
    $w.c create poly $xy -fill $color2 -outline $color2
    set xy {222 266 222 277 97 277 97 266}	;# Water bottom
    $w.c create line $xy -fill $::C(fg) -width 2.25p

    set xy [box 239 262 17]
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc \
	    -start 95 -extent 103
    set xy [box 76 266 21]
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc -extent 190
}
proc Move10 {w {step {}}} {
    set step [GetStep 10 $step]
    set pos [scl {
	{195 212} {193 212} {190 212} {186 212} {181 212} {176 212}
	{171 212} {166 212} {161 212} {156 212} {151 212} {147 212} {142 212}
	{137 212} {132 212 x} {127 212} {121 212} {116 212} {111 212}
    }]

    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I10 $where

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
    set color2 $::C(11b)
    set xy {23 264 55 591}			;# Color the down tube
    $w.c create rect $xy -fill $color -outline {}
    set xy [box 71 460 48]			;# Color the outer loop
    $w.c create oval $xy -fill $color -outline {}

    set xy {55 264 55 458}			;# Top right side
    $w.c create line $xy -fill $::C(fg) -width 3
    set xy {55 504 55 591}			;# Bottom right side
    $w.c create line $xy -fill $::C(fg) -width 3
    set xy [box 71 460 48]			;# Outer loop
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc \
	    -start 110 -extent -290 -tag I11i
    set xy [box 71 460 16]			;# Inner loop
    $w.c create oval $xy -outline $::C(fg) -fill {} -width 3 -tag I11i
    $w.c create oval $xy -outline $::C(fg) -fill $::C(bg) -width 3

    set xy {23 264 23 591}			;# Left side
    $w.c create line $xy -fill $::C(fg) -width 3
    set xy [box 1 266 23]			;# Top left curve
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc -extent 90

    set xy [box 75 235 9]			;# The ball
    $w.c create oval $xy -fill $color2 -outline {} -width 3 -tag I11
}
proc Move11 {w {step {}}} {
    set step [GetStep 11 $step]
    set pos {
	{75 235} {70 235} {65 237} {56 240} {46 247} {38 266} {38 296}
	{38 333} {38 399} {38 475} {74 496} {105 472} {100 437} {65 423}
	{-100 -100} {38 505} {38 527 x} {38 591}
    }

    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I11 $where
    if {[lindex $where 2] eq "x"} {







|

|

|


|
|


|

|


|



|



|







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
    set color2 $::C(11b)
    set xy {23 264 55 591}			;# Color the down tube
    $w.c create rect $xy -fill $color -outline {}
    set xy [box 71 460 48]			;# Color the outer loop
    $w.c create oval $xy -fill $color -outline {}

    set xy {55 264 55 458}			;# Top right side
    $w.c create line $xy -fill $::C(fg) -width 2.25p
    set xy {55 504 55 591}			;# Bottom right side
    $w.c create line $xy -fill $::C(fg) -width 2.25p
    set xy [box 71 460 48]			;# Outer loop
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc \
	    -start 110 -extent -290 -tag I11i
    set xy [box 71 460 16]			;# Inner loop
    $w.c create oval $xy -outline $::C(fg) -fill {} -width 2.25p -tag I11i
    $w.c create oval $xy -outline $::C(fg) -fill $::C(bg) -width 2.25p

    set xy {23 264 23 591}			;# Left side
    $w.c create line $xy -fill $::C(fg) -width 2.25p
    set xy [box 1 266 23]			;# Top left curve
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc -extent 90

    set xy [box 75 235 9]			;# The ball
    $w.c create oval $xy -fill $color2 -outline {} -width 2.25p -tag I11
}
proc Move11 {w {step {}}} {
    set step [GetStep 11 $step]
    set pos [scl {
	{75 235} {70 235} {65 237} {56 240} {46 247} {38 266} {38 296}
	{38 333} {38 399} {38 475} {74 496} {105 472} {100 437} {65 423}
	{-100 -100} {38 505} {38 527 x} {38 591}
    }]

    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I11 $where
    if {[lindex $where 2] eq "x"} {
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
    set y1 645
    for {set x 50} {$x > 20} {incr x -10} {
	set x1 [expr {$x - 5}]
	set x2 [expr {$x - 10}]
	lappend xy $x $y0 $x1 $y1 $x2 $y0
    }
    $w.c create poly $xy -fill $::C(12) -outline $::C(fg) -smooth 1 -tag I12 \
	    -width 3
}
proc Move12 {w {step {}}} {
    set step [GetStep 12 $step]
    set pos {{42.5 641 x}}
    if {$step >= [llength $pos]} {
	return 0
    }

    set where [lindex $pos $step]
    MoveAbs $w I12 $where
    if {[lindex $where 2] eq "x"} {
	return 3
    }
    return 1
}

# Fax
proc Draw13 {w} {
    set color $::C(13a)
    set xy {86 663 149 663 149 704 50 704 50 681 64 681 86 671}
    set xy2 {784 663 721 663 721 704 820 704 820 681 806 681 784 671}
    set radii {2 9 9 8 5 5 2}

    RoundPoly $w.c $xy $radii -width 3 -outline $::C(fg) -fill $color
    RoundPoly $w.c $xy2 $radii -width 3 -outline $::C(fg) -fill $color

    set xy {56 677}
    $w.c create rect [box {*}$xy 4] -fill {} -outline $::C(fg) -width 3 \
	    -tag I13
    set xy {809 677}
    $w.c create rect [box {*}$xy 4] -fill {} -outline $::C(fg) -width 3 \
	    -tag I13R

    set xy {112 687}				;# Label
    $w.c create text $xy -text "FAX" -fill $::C(fg) \
	    -font {{Times Roman} 12 bold}
    set xy {762 687}
    $w.c create text $xy -text "FAX" -fill $::C(fg) \
	    -font {{Times Roman} 12 bold}

    set xy {138 663 148 636 178 636}		;# Paper guide
    $w.c create line $xy -smooth 1 -fill $::C(fg) -width 3
    set xy {732 663 722 636 692 636}
    $w.c create line $xy -smooth 1 -fill $::C(fg) -width 3

    Sine $w 149 688 720 688 5 15 -tag I13_s -fill $::C(fg) -width 3
}
proc Move13 {w {step {}}} {
    set step [GetStep 13 $step]
    set numsteps 7

    if {$step == $numsteps+2} {
	MoveAbs $w I13_star {-100 -100}
	$w.c itemconfig I13R -fill $::C(13b) -width 2
	return 2
    }
    if {$step == 0} {				;# Button down
	$w.c delete I13
	Sparkle $w {-100 -100} I13_star		;# Create off screen
	return 1
    }
    lassign [Anchor $w I13_s w] x0 y0
    lassign [Anchor $w I13_s e] x1 y1
    set x [expr {$x0 + ($x1-$x0) * ($step - 1) / double($numsteps)}]
    MoveAbs $w I13_star [list $x $y0]
    return 1
}

# Paper in fax
proc Draw14 {w} {
    set color $::C(14)
    set xy {102 661 113 632 130 618}		;# Left paper edge
    $w.c create line $xy -smooth 1 -fill $color -width 3 -tag I14L_0
    set xy {148 629 125 640 124 662}		;# Right paper edge
    $w.c create line $xy -smooth 1 -fill $color -width 3 -tag I14L_1
    Draw14a $w L

    set xy {
	768.0 662.5 767.991316225 662.433786215 767.926187912 662.396880171
    }
    $w.c create line $xy -smooth 1 -fill $color -width 3 -tag I14R_0
    $w.c lower I14R_0
    # NB. these numbers are VERY sensitive, you must start with final size
    # and shrink down to get the values
    set xy {
	745.947897349 662.428358855 745.997829056 662.452239237 746.0 662.5
    }
    $w.c create line $xy -smooth 1 -fill $color -width 3 -tag I14R_1
    $w.c lower I14R_1
}
proc Draw14a {w side} {
    set color $::C(14)
    set xy [$w.c coords I14${side}_0]
    set xy2 [$w.c coords I14${side}_1]
    lassign $xy x0 y0 x1 y1 x2 y2
    lassign $xy2 x3 y3 x4 y4 x5 y5
    set zz [concat \
	    $x0 $y0 $x0 $y0 $xy $x2 $y2 $x2 $y2 \
	    $x3 $y3 $x3 $y3 $xy2 $x5 $y5 $x5 $y5]
    $w.c delete I14$side
    $w.c create poly $zz -tag I14$side -smooth 1 -fill $color -outline $color \
	    -width 3
    $w.c lower I14$side
}
proc Move14 {w {step {}}} {
    set step [GetStep 14 $step]

    # Paper going down
    set sc [expr {.9 - .05*$step}]







|



|



















|
|


|


|



|
<

|
<


|

|

|







|


















|

|





|






|













|







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
    set y1 645
    for {set x 50} {$x > 20} {incr x -10} {
	set x1 [expr {$x - 5}]
	set x2 [expr {$x - 10}]
	lappend xy $x $y0 $x1 $y1 $x2 $y0
    }
    $w.c create poly $xy -fill $::C(12) -outline $::C(fg) -smooth 1 -tag I12 \
	    -width 2.25p
}
proc Move12 {w {step {}}} {
    set step [GetStep 12 $step]
    set pos [scl {{42 641 x}}]
    if {$step >= [llength $pos]} {
	return 0
    }

    set where [lindex $pos $step]
    MoveAbs $w I12 $where
    if {[lindex $where 2] eq "x"} {
	return 3
    }
    return 1
}

# Fax
proc Draw13 {w} {
    set color $::C(13a)
    set xy {86 663 149 663 149 704 50 704 50 681 64 681 86 671}
    set xy2 {784 663 721 663 721 704 820 704 820 681 806 681 784 671}
    set radii {2 9 9 8 5 5 2}

    RoundPoly $w.c $xy $radii -width 2.25p -outline $::C(fg) -fill $color
    RoundPoly $w.c $xy2 $radii -width 2.25p -outline $::C(fg) -fill $color

    set xy {56 677}
    $w.c create rect [box {*}$xy 4] -fill {} -outline $::C(fg) -width 2.25p \
	    -tag I13
    set xy {809 677}
    $w.c create rect [box {*}$xy 4] -fill {} -outline $::C(fg) -width 2.25p \
	    -tag I13R

    set xy {112 687}				;# Label
    $w.c create text $xy -text "FAX" -fill $::C(fg) -font {Times 12 bold}

    set xy {762 687}
    $w.c create text $xy -text "FAX" -fill $::C(fg) -font {Times 12 bold}


    set xy {138 663 148 636 178 636}		;# Paper guide
    $w.c create line $xy -smooth 1 -fill $::C(fg) -width 2.25p
    set xy {732 663 722 636 692 636}
    $w.c create line $xy -smooth 1 -fill $::C(fg) -width 2.25p

    Sine $w 149 688 720 688 5 15 -tag I13_s -fill $::C(fg) -width 2.25p
}
proc Move13 {w {step {}}} {
    set step [GetStep 13 $step]
    set numsteps 7

    if {$step == $numsteps+2} {
	MoveAbs $w I13_star {-100 -100}
	$w.c itemconfig I13R -fill $::C(13b) -width 1.5p
	return 2
    }
    if {$step == 0} {				;# Button down
	$w.c delete I13
	Sparkle $w {-100 -100} I13_star		;# Create off screen
	return 1
    }
    lassign [Anchor $w I13_s w] x0 y0
    lassign [Anchor $w I13_s e] x1 y1
    set x [expr {$x0 + ($x1-$x0) * ($step - 1) / double($numsteps)}]
    MoveAbs $w I13_star [list $x $y0]
    return 1
}

# Paper in fax
proc Draw14 {w} {
    set color $::C(14)
    set xy {102 661 113 632 130 618}		;# Left paper edge
    $w.c create line $xy -smooth 1 -fill $color -width 2.25p -tag I14L_0
    set xy {148 629 125 640 124 662}		;# Right paper edge
    $w.c create line $xy -smooth 1 -fill $color -width 2.25p -tag I14L_1
    Draw14a $w L

    set xy {
	768.0 662.5 767.991316225 662.433786215 767.926187912 662.396880171
    }
    $w.c create line $xy -smooth 1 -fill $color -width 2.25p -tag I14R_0
    $w.c lower I14R_0
    # NB. these numbers are VERY sensitive, you must start with final size
    # and shrink down to get the values
    set xy {
	745.947897349 662.428358855 745.997829056 662.452239237 746.0 662.5
    }
    $w.c create line $xy -smooth 1 -fill $color -width 2.25p -tag I14R_1
    $w.c lower I14R_1
}
proc Draw14a {w side} {
    set color $::C(14)
    set xy [$w.c coords I14${side}_0]
    set xy2 [$w.c coords I14${side}_1]
    lassign $xy x0 y0 x1 y1 x2 y2
    lassign $xy2 x3 y3 x4 y4 x5 y5
    set zz [concat \
	    $x0 $y0 $x0 $y0 $xy $x2 $y2 $x2 $y2 \
	    $x3 $y3 $x3 $y3 $xy2 $x5 $y5 $x5 $y5]
    $w.c delete I14$side
    $w.c create poly $zz -tag I14$side -smooth 1 -fill $color -outline $color \
	    -width 2.25p
    $w.c lower I14$side
}
proc Move14 {w {step {}}} {
    set step [GetStep 14 $step]

    # Paper going down
    set sc [expr {.9 - .05*$step}]
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
    return [expr {$step == 10 ? 3 : 1}]
}

# Light beam
proc Draw15 {w} {
    set color $::C(15a)
    set xy {824 599 824 585 820 585 829 585}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I15a
    set xy {789 599 836 643}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 3
    set xy {778 610 788 632}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 3
    set xy {766 617 776 625}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 3

    set xy {633 600 681 640}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 3
    set xy {635 567 657 599}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2
    set xy {765 557 784 583}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2

    Sine $w 658 580 765 580 3 15 -tag I15_s -fill $::C(fg) -width 3
}
proc Move15a {w} {
    set color $::C(15b)
    $w.c scale I15a 824 599 1 .3		;# Button down
    set xy {765 621 681 621}
    $w.c create line $xy -dash "-" -width 3 -fill $color -tag I15
}
proc Move15 {w {step {}}} {
    set step [GetStep 15 $step]
    set numsteps 6

    if {$step == $numsteps+2} {
	MoveAbs $w I15_star {-100 -100}
	return 2
    }
    if {$step == 0} {				;# Break the light beam
	Sparkle $w {-100 -100} I15_star
	set xy {765 621 745 621}
	$w.c coords I15 $xy
	return 1
    }
    lassign [Anchor $w I15_s w] x0 y0
    lassign [Anchor $w I15_s e] x1 y1
    set x [expr {$x0 + ($x1-$x0) * ($step - 1) / double($numsteps)}]
    MoveAbs $w I15_star [list $x $y0]
    return 1
}

# Bell
proc Draw16 {w} {
    set color $::C(16)
    set xy {722 485 791 556}
    $w.c create rect $xy -fill {} -outline $::C(fg) -width 3
    set xy [box 752 515 25]			;# Bell
    $w.c create oval $xy -fill $color -outline black -tag I16b -width 2
    set xy [box 752 515 5]			;# Bell button
    $w.c create oval $xy -fill black -outline black -tag I16b

    set xy {784 523 764 549}			;# Clapper
    $w.c create line $xy -width 3 -tag I16c -fill $::C(fg)
    set xy [box 784 523 4]
    $w.c create oval $xy -fill $::C(fg) -outline $::C(fg) -tag I16d
}
proc Move16 {w {step {}}} {
    set step [GetStep 16 $step]

    # Note: we never stop
    lassign {760 553} Ox Oy
    if {$step & 1} {
	set beta 12
	$w.c move I16b 3 0
    } else {
	set beta -12
	$w.c move I16b -3 0
    }
    RotateItem $w I16c $Ox $Oy $beta
    RotateItem $w I16d $Ox $Oy $beta

    return [expr {$step == 1 ? 3 : 1}]
}

# Cat
proc Draw17 {w} {
    set color $::C(17)

    set xy {584 556 722 556}
    $w.c create line $xy -fill $::C(fg) -width 3
    set xy {584 485 722 485}
    $w.c create line $xy -fill $::C(fg) -width 3

    set xy {664 523 717 549}			;# Body
    $w.c create arc $xy -outline $::C(fg) -fill $color -width 3 \
	    -style chord -start 128 -extent -260 -tag I17

    set xy {709 554 690 543}			;# Paw
    $w.c create oval $xy -outline $::C(fg) -fill $color -width 3 -tag I17
    set xy {657 544 676 555}
    $w.c create oval $xy -outline $::C(fg) -fill $color -width 3 -tag I17

    set xy [box 660 535 15]			;# Lower face
    $w.c create arc $xy -outline $::C(fg) -width 3 -style arc \
	    -start 150 -extent 240 -tag I17_
    $w.c create arc $xy -outline {} -fill $color -width 1 -style chord \
	    -start 150 -extent 240 -tag I17_
    set xy {674 529 670 513 662 521 658 521 650 513 647 529}	;# Ears
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I17_
    $w.c create poly $xy -fill $color -outline {} -width 1 -tag {I17_ I17_c}
    set xy {652 542 628 539}			;# Whiskers
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I17_
    set xy {652 543 632 545}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I17_
    set xy {652 546 632 552}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I17_

    set xy {668 543 687 538}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag {I17_ I17w}
    set xy {668 544 688 546}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag {I17_ I17w}
    set xy {668 547 688 553}
    $w.c create line $xy -fill $::C(fg) -width 3 -tag {I17_ I17w}

    set xy {649 530 654 538 659 530}		;# Left eye
    $w.c create line $xy -fill $::C(fg) -width 2 -smooth 1 -tag I17
    set xy {671 530 666 538 661 530}		;# Right eye
    $w.c create line $xy -fill $::C(fg) -width 2 -smooth 1 -tag I17
    set xy {655 543 660 551 665 543}		;# Mouth
    $w.c create line $xy -fill $::C(fg) -width 2 -smooth 1 -tag I17
}
proc Move17 {w {step {}}} {
    set step [GetStep 17 $step]

    if {$step == 0} {
	$w.c delete I17				;# Delete most of the cat
	set xy {655 543 660 535 665 543}	;# Mouth
	$w.c create line $xy -fill $::C(fg) -width 3 -smooth 1 -tag I17_
	set xy [box 654 530 4]			;# Left eye
	$w.c create oval $xy -outline $::C(fg) -width 3 -fill {} -tag I17_
	set xy [box 666 530 4]			;# Right eye
	$w.c create oval $xy -outline $::C(fg) -width 3 -fill {} -tag I17_

	$w.c move I17_ 0 -20			;# Move face up
	set xy {652 528 652 554}		;# Front leg
	$w.c create line $xy -fill $::C(fg) -width 3 -tag I17_
	set xy {670 528 670 554}		;# 2nd front leg
	$w.c create line $xy -fill $::C(fg) -width 3 -tag I17_

	set xy {
	    675 506 694 489 715 513 715 513 715 513 716 525 716 525 716 525
	    706 530 695 530 679 535 668 527 668 527 668 527 675 522 676 517
	    677 512
	}					;# Body
	$w.c create poly $xy -fill [$w.c itemcget I17_c -fill] \
		-outline $::C(fg) -width 3 -smooth 1 -tag I17_
	set xy {716 514 716 554}		;# Back leg
	$w.c create line $xy -fill $::C(fg) -width 3 -tag I17_
	set xy {694 532 694 554}		;# 2nd back leg
	$w.c create line $xy -fill $::C(fg) -width 3 -tag I17_
	set xy {715 514 718 506 719 495 716 488};# Tail
	$w.c create line $xy -fill $::C(fg) -width 3 -smooth 1 -tag I17_

	$w.c raise I17w				;# Make whiskers visible
	$w.c move I17_ -5 0			;# Move away from wall a bit
	return 2
    }
    return 0
}

# Sling shot
proc Draw18 {w} {
    set color $::C(18)
    set xy {721 506 627 506}			;# Sling hold
    $w.c create line $xy -width 4 -fill $::C(fg) -tag I18

    set xy {607 500 628 513}			;# Sling rock
    $w.c create oval $xy -fill $color -outline {} -tag I18a

    set xy {526 513 606 507 494 502}		;# Sling band
    $w.c create line $xy -fill $::C(fg) -width 4 -tag I18b
    set xy { 485 490 510 540 510 575 510 540 535 491 }	;# Sling
    $w.c create line $xy -fill $::C(fg) -width 6
}
proc Move18 {w {step {}}} {
    set step [GetStep 18 $step]

    set pos {
	{587 506} {537 506} {466 506} {376 506} {266 506 x} {136 506}
	{16 506} {-100 -100}
    }

    set b(0) {490 502 719 507 524 512}		;# Band collapsing
    set b(1) {
	491 503 524 557 563 505 559 496 546 506 551 525 553 536 538 534
	532 519 529 499
    }
    set b(2) {491 503 508 563 542 533 551 526 561 539 549 550 530 500}
    set b(3) {491 503 508 563 530 554 541 562 525 568 519 544 530 501}

    if {$step >= [llength $pos]} {
	return 0
    }

    if {$step == 0} {
	$w.c delete I18







|

|

|

|


|

|

|

|



|
|
|











|














|

|




|







|


|


|












|

|


|



|

|


|

|


|
|

|

|

|


|

|

|


|

|

|






|
|
|
|
|
|

|
|
|
|
|

|



|

|
|
|
|
|
|
|


|









|





|

|




|


|

|
|


|
|
|







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
    return [expr {$step == 10 ? 3 : 1}]
}

# Light beam
proc Draw15 {w} {
    set color $::C(15a)
    set xy {824 599 824 585 820 585 829 585}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I15a
    set xy {789 599 836 643}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2.25p
    set xy {778 610 788 632}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2.25p
    set xy {766 617 776 625}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2.25p

    set xy {633 600 681 640}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2.25p
    set xy {635 567 657 599}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2.25p
    set xy {765 557 784 583}
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 2.25p

    Sine $w 658 580 765 580 3 15 -tag I15_s -fill $::C(fg) -width 2.25p
}
proc Move15a {w} {
    set color $::C(15b)
    $w.c scale I15a [scl 824] [scl 599] 1 .3		;# Button down
    set xy [scl {765 621 681 621}]
    $w.c create line $xy -dash "-" -width 2.25p -fill $color -tag I15
}
proc Move15 {w {step {}}} {
    set step [GetStep 15 $step]
    set numsteps 6

    if {$step == $numsteps+2} {
	MoveAbs $w I15_star {-100 -100}
	return 2
    }
    if {$step == 0} {				;# Break the light beam
	Sparkle $w {-100 -100} I15_star
	set xy [scl {765 621 745 621}]
	$w.c coords I15 $xy
	return 1
    }
    lassign [Anchor $w I15_s w] x0 y0
    lassign [Anchor $w I15_s e] x1 y1
    set x [expr {$x0 + ($x1-$x0) * ($step - 1) / double($numsteps)}]
    MoveAbs $w I15_star [list $x $y0]
    return 1
}

# Bell
proc Draw16 {w} {
    set color $::C(16)
    set xy {722 485 791 556}
    $w.c create rect $xy -fill {} -outline $::C(fg) -width 2.25p
    set xy [box 752 515 25]			;# Bell
    $w.c create oval $xy -fill $color -outline black -tag I16b -width 1.5p
    set xy [box 752 515 5]			;# Bell button
    $w.c create oval $xy -fill black -outline black -tag I16b

    set xy {784 523 764 549}			;# Clapper
    $w.c create line $xy -width 2.25p -tag I16c -fill $::C(fg)
    set xy [box 784 523 4]
    $w.c create oval $xy -fill $::C(fg) -outline $::C(fg) -tag I16d
}
proc Move16 {w {step {}}} {
    set step [GetStep 16 $step]

    # Note: we never stop
    lassign [scl {760 553}] Ox Oy
    if {$step & 1} {
	set beta 12
	$w.c move I16b 2.25p 0
    } else {
	set beta -12
	$w.c move I16b -2.25p 0
    }
    RotateItem $w I16c $Ox $Oy $beta
    RotateItem $w I16d $Ox $Oy $beta

    return [expr {$step == 1 ? 3 : 1}]
}

# Cat
proc Draw17 {w} {
    set color $::C(17)

    set xy {584 556 722 556}
    $w.c create line $xy -fill $::C(fg) -width 2.25p
    set xy {584 485 722 485}
    $w.c create line $xy -fill $::C(fg) -width 2.25p

    set xy {664 523 717 549}			;# Body
    $w.c create arc $xy -outline $::C(fg) -fill $color -width 2.25p \
	    -style chord -start 128 -extent -260 -tag I17

    set xy {709 554 690 543}			;# Paw
    $w.c create oval $xy -outline $::C(fg) -fill $color -width 2.25p -tag I17
    set xy {657 544 676 555}
    $w.c create oval $xy -outline $::C(fg) -fill $color -width 2.25p -tag I17

    set xy [box 660 535 15]			;# Lower face
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -style arc \
	    -start 150 -extent 240 -tag I17_
    $w.c create arc $xy -outline {} -fill $color -width 0.75p -style chord \
	    -start 150 -extent 240 -tag I17_
    set xy {674 529 670 513 662 521 658 521 650 513 647 529}	;# Ears
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_
    $w.c create poly $xy -fill $color -outline {} -width 0.75p -tag {I17_ I17_c}
    set xy {652 542 628 539}			;# Whiskers
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_
    set xy {652 543 632 545}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_
    set xy {652 546 632 552}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_

    set xy {668 543 687 538}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag {I17_ I17w}
    set xy {668 544 688 546}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag {I17_ I17w}
    set xy {668 547 688 553}
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag {I17_ I17w}

    set xy {649 530 654 538 659 530}		;# Left eye
    $w.c create line $xy -fill $::C(fg) -width 1.5p -smooth 1 -tag I17
    set xy {671 530 666 538 661 530}		;# Right eye
    $w.c create line $xy -fill $::C(fg) -width 1.5p -smooth 1 -tag I17
    set xy {655 543 660 551 665 543}		;# Mouth
    $w.c create line $xy -fill $::C(fg) -width 1.5p -smooth 1 -tag I17
}
proc Move17 {w {step {}}} {
    set step [GetStep 17 $step]

    if {$step == 0} {
	$w.c delete I17				;# Delete most of the cat
	set xy [scl {655 543 660 535 665 543}]	;# Mouth
	$w.c create line $xy -fill $::C(fg) -width 2.25p -smooth 1 -tag I17_
	set xy [box [scl 654] [scl 530] [scl 4]]	;# Left eye
	$w.c create oval $xy -outline $::C(fg) -width 2.25p -fill {} -tag I17_
	set xy [box [scl 666] [scl 530] [scl 4]]	;# Right eye
	$w.c create oval $xy -outline $::C(fg) -width 2.25p -fill {} -tag I17_

	$w.c move I17_ 0 -15p			;# Move face up
	set xy [scl {652 528 652 554}]		;# Front leg
	$w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_
	set xy [scl {670 528 670 554}]		;# 2nd front leg
	$w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_

	set xy [scl {
	    675 506 694 489 715 513 715 513 715 513 716 525 716 525 716 525
	    706 530 695 530 679 535 668 527 668 527 668 527 675 522 676 517
	    677 512
	}]					;# Body
	$w.c create poly $xy -fill [$w.c itemcget I17_c -fill] \
		-outline $::C(fg) -width 2.25p -smooth 1 -tag I17_
	set xy [scl {716 514 716 554}]		;# Back leg
	$w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_
	set xy [scl {694 532 694 554}]		;# 2nd back leg
	$w.c create line $xy -fill $::C(fg) -width 2.25p -tag I17_
	set xy [scl {715 514 718 506 719 495 716 488}]	;# Tail
	$w.c create line $xy -fill $::C(fg) -width 2.25p -smooth 1 -tag I17_

	$w.c raise I17w				;# Make whiskers visible
	$w.c move I17_ -3.75p 0			;# Move away from wall a bit
	return 2
    }
    return 0
}

# Sling shot
proc Draw18 {w} {
    set color $::C(18)
    set xy {721 506 627 506}			;# Sling hold
    $w.c create line $xy -width 3p -fill $::C(fg) -tag I18

    set xy {607 500 628 513}			;# Sling rock
    $w.c create oval $xy -fill $color -outline {} -tag I18a

    set xy {526 513 606 507 494 502}		;# Sling band
    $w.c create line $xy -fill $::C(fg) -width 3p -tag I18b
    set xy { 485 490 510 540 510 575 510 540 535 491 }	;# Sling
    $w.c create line $xy -fill $::C(fg) -width 4.5p
}
proc Move18 {w {step {}}} {
    set step [GetStep 18 $step]

    set pos [scl {
	{587 506} {537 506} {466 506} {376 506} {266 506 x} {136 506}
	{16 506} {-100 -100}
    }]

    set b(0) [scl {490 502 719 507 524 512}]		;# Band collapsing
    set b(1) [scl {
	491 503 524 557 563 505 559 496 546 506 551 525 553 536 538 534
	532 519 529 499
    }]
    set b(2) [scl {491 503 508 563 542 533 551 526 561 539 549 550 530 500}]
    set b(3) [scl {491 503 508 563 530 554 541 562 525 568 519 544 530 501}]

    if {$step >= [llength $pos]} {
	return 0
    }

    if {$step == 0} {
	$w.c delete I18
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

# Water pipe
proc Draw19 {w} {
    set color $::C(19)
    set xx {249 181 155 118  86 55 22 0}
    foreach {x1 x2} $xx {
	$w.c create rect $x1 453 $x2 467 -fill $color -outline {} -tag I19
	$w.c create line $x1 453 $x2 453 -fill $::C(fg) -width 1;# Pipe top
	$w.c create line $x1 467 $x2 467 -fill $::C(fg) -width 1;# Pipe bottom
    }
    $w.c raise I11i

    set xy [box 168 460 16]			;# Bulge by the joint
    $w.c create oval $xy -fill $color -outline {}
    $w.c create arc $xy -outline $::C(fg) -width 1 -style arc \
	    -start 21 -extent 136
    $w.c create arc $xy -outline $::C(fg) -width 1 -style arc \
	    -start -21 -extent -130

    set xy {249 447 255 473}			;# First joint 26x6
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 1

    set xy [box 257 433 34]			;# Bend up
    $w.c create arc $xy -outline {} -fill $color -width 1 \
	    -style pie -start 0 -extent -91
    $w.c create arc $xy -outline $::C(fg) -width 1 \
	    -style arc -start 0 -extent -90
    set xy [box 257 433 20]
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 1 \
	    -style pie -start 0 -extent -92
    $w.c create arc $xy -outline $::C(fg) -width 1 \
	    -style arc -start 0 -extent -90
    set xy [box 257 421 34]			;# Bend left
    $w.c create arc $xy -outline {} -fill $color -width 1 \
	    -style pie -start 1 -extent 91
    $w.c create arc $xy -outline $::C(fg) -width 1 \
	    -style arc -start 0 -extent 90
    set xy [box 257 421 20]
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 1 \
	    -style pie -start 0 -extent 90
    $w.c create arc $xy -outline $::C(fg) -width 1 \
	    -style arc -start 0 -extent 90
    set xy [box 243 421 34]			;# Bend down
    $w.c create arc $xy -outline {} -fill $color -width 1 \
	    -style pie -start 90 -extent 90
    $w.c create arc $xy -outline $::C(fg) -width 1 \
	    -style arc -start 90 -extent 90
    set xy [box 243 421 20]
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 1 \
	    -style pie -start 90 -extent 90
    $w.c create arc $xy -outline $::C(fg) -width 1 \
	    -style arc -start 90 -extent 90

    set xy {270 427 296 433}			;# 2nd joint bottom
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 1
    set xy {270 421 296 427}			;# 2nd joint top
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 1
    set xy {249 382 255 408}			;# Third joint right
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 1
    set xy {243 382 249 408}			;# Third joint left
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 1
    set xy {203 420 229 426}			;# Last joint
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 1

    set xy [box 168 460 6]			;# Handle joint
    $w.c create oval $xy -fill $::C(fg) -outline {} -tag I19a
    set xy {168 460 168 512}			;# Handle bar
    $w.c create line $xy -fill $::C(fg) -width 5 -tag I19b
}
proc Move19 {w {step {}}} {
    set step [GetStep 19 $step]

    set angles {30 30 30}
    if {$step == [llength $angles]} {
	return 2
    }

    RotateItem $w I19b {*}[Centroid $w I19a] [lindex $angles $step]
    return 1
}

# Water pouring
proc Draw20 {w} {
}
proc Move20 {w {step {}}} {
    set step [GetStep 20 $step]

    set pos {451 462 473 484 496 504 513 523 532}
    set freq {20 40   40  40  40  40  40  40  40}
    set pos {
	{451 20} {462 40} {473 40} {484 40} {496 40} {504 40} {513 40}
	{523 40} {532 40 x}
    }
    if {$step >= [llength $pos]} {
	return 0
    }

    $w.c delete I20
    set where [lindex $pos $step]
    lassign $where y f
    H2O $w $y $f
    if {[lindex $where 2] eq "x"} {
	return 3
    }
    return 1
}
proc H2O {w y f} {
    set color $::C(20)
    $w.c delete I20

    Sine $w 208 428 208 $y 4 $f -tag {I20 I20s} -width 3 -fill $color \
	    -smooth 1
    $w.c create line [$w.c coords I20s] -width 3 -fill $color -smooth 1 \
	    -tag {I20 I20a}
    $w.c create line [$w.c coords I20s] -width 3 -fill $color -smooth 1 \
	    -tag {I20 I20b}
    $w.c move I20a 8 0
    $w.c move I20b 16 0
}

# Bucket
proc Draw21 {w} {
    set color $::C(21)
    set xy {217 451 244 490}			;# Right handle
    $w.c create line $xy -fill $::C(fg) -width 2 -tag I21_a
    set xy {201 467 182 490}			;# Left handle
    $w.c create line $xy -fill $::C(fg) -width 2 -tag I21_a

    set xy {245 490 237 535}			;# Right side
    set xy2 {189 535 181 490}			;# Left side
    $w.c create poly [concat $xy $xy2] -fill $color -outline {} \
	    -tag {I21 I21f}
    $w.c create line $xy -fill $::C(fg) -width 2 -tag I21
    $w.c create line $xy2 -fill $::C(fg) -width 2 -tag I21

    set xy {182 486 244 498}			;# Top
    $w.c create oval $xy -fill $color -outline {} -width 2 -tag {I21 I21f}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 2 -tag {I21 I21t}
    set xy {189 532 237 540}			;# Bottom
    $w.c create oval $xy -fill $color -outline $::C(fg) -width 2 \
	    -tag {I21 I21b}
}
proc Move21 {w {step {}}} {
    set step [GetStep 21 $step]

    set numsteps 30
    if {$step  >= $numsteps} {
	return 0
    }

    lassign [$w.c coords I21b] x1 y1 x2 y2
    #lassign [$w.c coords I21t] X1 Y1 X2 Y2
    lassign {183 492 243 504} X1 Y1 X2 Y2

    set f [expr {$step / double($numsteps)}]
    set y2 [expr {$y2 - 3}]
    set xx1 [expr {$x1 + ($X1 - $x1) * $f}]
    set yy1 [expr {$y1 + ($Y1 - $y1) * $f}]
    set xx2 [expr {$x2 + ($X2 - $x2) * $f}]
    set yy2 [expr {$y2 + ($Y2 - $y2) * $f}]
    #H2O $w $yy1 40

    $w.c itemconfig I21b -fill $::C(20)







|
|





|

|



|


|

|




|


|

|


|

|


|

|


|

|



|

|

|

|

|




|



















|

|


|

















|
|
|

|

|
|






|

|





|
|


|
|

|












|


|







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

# Water pipe
proc Draw19 {w} {
    set color $::C(19)
    set xx {249 181 155 118  86 55 22 0}
    foreach {x1 x2} $xx {
	$w.c create rect $x1 453 $x2 467 -fill $color -outline {} -tag I19
	$w.c create line $x1 453 $x2 453 -fill $::C(fg) -width 0.75p;# Pipe top
	$w.c create line $x1 467 $x2 467 -fill $::C(fg) -width 0.75p;# Pipe btm
    }
    $w.c raise I11i

    set xy [box 168 460 16]			;# Bulge by the joint
    $w.c create oval $xy -fill $color -outline {}
    $w.c create arc $xy -outline $::C(fg) -width 0.75p -style arc \
	    -start 21 -extent 136
    $w.c create arc $xy -outline $::C(fg) -width 0.75p -style arc \
	    -start -21 -extent -130

    set xy {249 447 255 473}			;# First joint 26x6
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 0.75p

    set xy [box 257 433 34]			;# Bend up
    $w.c create arc $xy -outline {} -fill $color -width 0.75p \
	    -style pie -start 0 -extent -91
    $w.c create arc $xy -outline $::C(fg) -width 0.75p \
	    -style arc -start 0 -extent -90
    set xy [box 257 433 20]
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 1 \
	    -style pie -start 0 -extent -92
    $w.c create arc $xy -outline $::C(fg) -width 0.75p \
	    -style arc -start 0 -extent -90
    set xy [box 257 421 34]			;# Bend left
    $w.c create arc $xy -outline {} -fill $color -width 0.75p \
	    -style pie -start 1 -extent 91
    $w.c create arc $xy -outline $::C(fg) -width 0.75p \
	    -style arc -start 0 -extent 90
    set xy [box 257 421 20]
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 0.75p \
	    -style pie -start 0 -extent 90
    $w.c create arc $xy -outline $::C(fg) -width 0.75p \
	    -style arc -start 0 -extent 90
    set xy [box 243 421 34]			;# Bend down
    $w.c create arc $xy -outline {} -fill $color -width 0.75p \
	    -style pie -start 90 -extent 90
    $w.c create arc $xy -outline $::C(fg) -width 0.75p \
	    -style arc -start 90 -extent 90
    set xy [box 243 421 20]
    $w.c create arc $xy -outline {} -fill $::C(bg) -width 0.75p \
	    -style pie -start 90 -extent 90
    $w.c create arc $xy -outline $::C(fg) -width 0.75p \
	    -style arc -start 90 -extent 90

    set xy {270 427 296 433}			;# 2nd joint bottom
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 0.75p
    set xy {270 421 296 427}			;# 2nd joint top
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 0.75p
    set xy {249 382 255 408}			;# Third joint right
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 0.75p
    set xy {243 382 249 408}			;# Third joint left
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 0.75p
    set xy {203 420 229 426}			;# Last joint
    $w.c create rect $xy -fill $color -outline $::C(fg) -width 0.75p

    set xy [box 168 460 6]			;# Handle joint
    $w.c create oval $xy -fill $::C(fg) -outline {} -tag I19a
    set xy {168 460 168 512}			;# Handle bar
    $w.c create line $xy -fill $::C(fg) -width 3.75p -tag I19b
}
proc Move19 {w {step {}}} {
    set step [GetStep 19 $step]

    set angles {30 30 30}
    if {$step == [llength $angles]} {
	return 2
    }

    RotateItem $w I19b {*}[Centroid $w I19a] [lindex $angles $step]
    return 1
}

# Water pouring
proc Draw20 {w} {
}
proc Move20 {w {step {}}} {
    set step [GetStep 20 $step]

    set pos [scl {451 462 473 484 496 504 513 523 532}]
    set freq {20 40   40  40  40  40  40  40  40}
    set pos [scl {
	{451 20} {462 40} {473 40} {484 40} {496 40} {504 40} {513 40}
	{523 40} {532 40 x}
    }]
    if {$step >= [llength $pos]} {
	return 0
    }

    $w.c delete I20
    set where [lindex $pos $step]
    lassign $where y f
    H2O $w $y $f
    if {[lindex $where 2] eq "x"} {
	return 3
    }
    return 1
}
proc H2O {w y f} {
    set color $::C(20)
    $w.c delete I20

    Sine $w [scl 208] [scl 428] [scl 208] $y 4 $f -tag {I20 I20s} \
	    -width 2.25p -fill $color -smooth 1
    $w.c create line [$w.c coords I20s] -width 2.25p -fill $color -smooth 1 \
	    -tag {I20 I20a}
    $w.c create line [$w.c coords I20s] -width 2.25p -fill $color -smooth 1 \
	    -tag {I20 I20b}
    $w.c move I20a 6p 0
    $w.c move I20b 12p 0
}

# Bucket
proc Draw21 {w} {
    set color $::C(21)
    set xy {217 451 244 490}			;# Right handle
    $w.c create line $xy -fill $::C(fg) -width 1.5p -tag I21_a
    set xy {201 467 182 490}			;# Left handle
    $w.c create line $xy -fill $::C(fg) -width 1.5p -tag I21_a

    set xy {245 490 237 535}			;# Right side
    set xy2 {189 535 181 490}			;# Left side
    $w.c create poly [concat $xy $xy2] -fill $color -outline {} \
	    -tag {I21 I21f}
    $w.c create line $xy -fill $::C(fg) -width 1.5p -tag I21
    $w.c create line $xy2 -fill $::C(fg) -width 1.5p -tag I21

    set xy {182 486 244 498}			;# Top
    $w.c create oval $xy -fill $color -outline {} -width 1.5p -tag {I21 I21f}
    $w.c create oval $xy -fill {} -outline $::C(fg) -width 1.5p -tag {I21 I21t}
    set xy {189 532 237 540}			;# Bottom
    $w.c create oval $xy -fill $color -outline $::C(fg) -width 1.5p \
	    -tag {I21 I21b}
}
proc Move21 {w {step {}}} {
    set step [GetStep 21 $step]

    set numsteps 30
    if {$step  >= $numsteps} {
	return 0
    }

    lassign [$w.c coords I21b] x1 y1 x2 y2
    #lassign [$w.c coords I21t] X1 Y1 X2 Y2
    lassign [scl {183 492 243 504}] X1 Y1 X2 Y2

    set f [expr {$step / double($numsteps)}]
    set y2 [expr {$y2 - [scl 3]}]
    set xx1 [expr {$x1 + ($X1 - $x1) * $f}]
    set yy1 [expr {$y1 + ($Y1 - $y1) * $f}]
    set xx2 [expr {$x2 + ($X2 - $x2) * $f}]
    set yy2 [expr {$y2 + ($Y2 - $y2) * $f}]
    #H2O $w $yy1 40

    $w.c itemconfig I21b -fill $::C(20)
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
}

# Bucket drop
proc Draw22 {w} {
}
proc Move22 {w {step {}}} {
    set step [GetStep 22 $step]
    set pos {{213 513} {213 523} {213 543 x} {213 583} {213 593}}

    if {$step == 0} {$w.c itemconfig I21f -fill $::C(22)}
    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I21 $where







|







1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
}

# Bucket drop
proc Draw22 {w} {
}
proc Move22 {w {step {}}} {
    set step [GetStep 22 $step]
    set pos [scl {{213 513} {213 523} {213 543 x} {213 583} {213 593}}]

    if {$step == 0} {$w.c itemconfig I21f -fill $::C(22)}
    if {$step >= [llength $pos]} {
	return 0
    }
    set where [lindex $pos $step]
    MoveAbs $w I21 $where
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
# Blow dart
proc Draw23 {w} {
    set color  $::C(23a)
    set color2 $::C(23b)
    set color3 $::C(23c)

    set xy {185 623 253 650}			;# Block
    $w.c create rect $xy -fill black -outline $::C(fg) -width 2 -tag I23a
    set xy {187 592 241 623}			;# Balloon
    $w.c create oval $xy -outline {} -fill $color -tag I23b
    $w.c create arc $xy -outline $::C(fg) -width 3 -tag I23b \
	    -style arc -start 12 -extent 336
    set xy {239 604  258 589 258 625 239 610}	;# Balloon nozzle
    $w.c create poly $xy -outline {} -fill $color -tag I23b
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I23b

    set xy {285 611 250 603}			;# Dart body
    $w.c create oval $xy -fill $color2 -outline $::C(fg) -width 3 -tag I23d
    set xy {249 596 249 618 264 607 249 596}	;# Dart tail
    $w.c create poly $xy -fill $color3 -outline $::C(fg) -width 3 -tag I23d
    set xy {249 607 268 607}			;# Dart detail
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I23d
    set xy {285 607 305 607}			;# Dart needle
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I23d
}
proc Move23 {w {step {}}} {
    set step [GetStep 23 $step]

    set pos {
	{277 607} {287 607} {307 607 x} {347 607} {407 607} {487 607}
	{587 607} {687 607} {787 607} {-100 -100}
    }

    if {$step >= [llength $pos]} {
	return 0
    }
    if {$step <= 1} {
	$w.c scale I23b {*}[Anchor $w I23a n] .9 .5
    }
    set where [lindex $pos $step]
    MoveAbs $w I23d $where

    if {[lindex $where 2] eq "x"} {
	return 3
    }
    return 1
}

# Balloon
proc Draw24 {w} {
    set color $::C(24a)
    set xy {366 518 462 665}			;# Balloon
    $w.c create oval $xy -fill $color -outline $::C(fg) -width 3 -tag I24
    set xy {414 666 414 729}			;# String
    $w.c create line $xy -fill $::C(fg) -width 3 -tag I24
    set xy {410 666 404 673 422 673 418 666}	;# Nozzle
    $w.c create poly $xy -fill $color -outline $::C(fg) -width 3 -tag I24

    set xy {387 567 390 549 404 542}		;# Reflections
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 2 -tag I24
    set xy {395 568 399 554 413 547}
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 2 -tag I24
    set xy {403 570 396 555 381 553}
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 2 -tag I24
    set xy {408 564 402 547 386 545}
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 2 -tag I24
}
proc Move24 {w {step {}}} {
    global S
    set step [GetStep 24 $step]

    if {$step > 4} {
	return 0
    } elseif {$step == 4} {
	return 2
    }

    if {$step == 0} {
	$w.c delete I24				;# Exploding balloon
	set xy {
	    347 465 361 557 271 503 272 503 342 574 259 594 259 593 362 626
	    320 737 320 740 398 691 436 738 436 739 476 679 528 701 527 702
	    494 627 548 613 548 613 480 574 577 473 577 473 474 538 445 508
	    431 441 431 440 400 502 347 465 347 465
	}
	$w.c create poly $xy -tag I24 -fill $::C(24b) -outline $::C(24a) \
		-width 10 -smooth 1
	set msg [subst $S(message)]
	$w.c create text [Centroid $w I24] -text $msg -tag {I24 I24t} \
		-justify center -font {{Times Roman} 18 bold}
	return 1
    }

    $w.c itemconfig I24t -font [list {Times Roman} [expr {18 + 6*$step}] bold]
    $w.c move I24 0 -60
    $w.c scale I24 {*}[Centroid $w I24] 1.25 1.25
    return 1
}

# Displaying the message
proc Move25 {w {step {}}} {
    global S







|


|



|


|

|

|

|




|


|




















|

|

|


|

|

|

|


|










|




|

|


|



|
|







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
# Blow dart
proc Draw23 {w} {
    set color  $::C(23a)
    set color2 $::C(23b)
    set color3 $::C(23c)

    set xy {185 623 253 650}			;# Block
    $w.c create rect $xy -fill black -outline $::C(fg) -width 1.5p -tag I23a
    set xy {187 592 241 623}			;# Balloon
    $w.c create oval $xy -outline {} -fill $color -tag I23b
    $w.c create arc $xy -outline $::C(fg) -width 2.25p -tag I23b \
	    -style arc -start 12 -extent 336
    set xy {239 604  258 589 258 625 239 610}	;# Balloon nozzle
    $w.c create poly $xy -outline {} -fill $color -tag I23b
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I23b

    set xy {285 611 250 603}			;# Dart body
    $w.c create oval $xy -fill $color2 -outline $::C(fg) -width 2.25p -tag I23d
    set xy {249 596 249 618 264 607 249 596}	;# Dart tail
    $w.c create poly $xy -fill $color3 -outline $::C(fg) -width 2.25p -tag I23d
    set xy {249 607 268 607}			;# Dart detail
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I23d
    set xy {285 607 305 607}			;# Dart needle
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I23d
}
proc Move23 {w {step {}}} {
    set step [GetStep 23 $step]

    set pos [scl {
	{277 607} {287 607} {307 607 x} {347 607} {407 607} {487 607}
	{587 607} {687 607} {787 607} {-100 -100}
    }]

    if {$step >= [llength $pos]} {
	return 0
    }
    if {$step <= 1} {
	$w.c scale I23b {*}[Anchor $w I23a n] .9 .5
    }
    set where [lindex $pos $step]
    MoveAbs $w I23d $where

    if {[lindex $where 2] eq "x"} {
	return 3
    }
    return 1
}

# Balloon
proc Draw24 {w} {
    set color $::C(24a)
    set xy {366 518 462 665}			;# Balloon
    $w.c create oval $xy -fill $color -outline $::C(fg) -width 2.25p -tag I24
    set xy {414 666 414 729}			;# String
    $w.c create line $xy -fill $::C(fg) -width 2.25p -tag I24
    set xy {410 666 404 673 422 673 418 666}	;# Nozzle
    $w.c create poly $xy -fill $color -outline $::C(fg) -width 2.25p -tag I24

    set xy {387 567 390 549 404 542}		;# Reflections
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 1.5p -tag I24
    set xy {395 568 399 554 413 547}
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 1.5p -tag I24
    set xy {403 570 396 555 381 553}
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 1.5p -tag I24
    set xy {408 564 402 547 386 545}
    $w.c create line $xy -fill $::C(fg) -smooth 1 -width 1.5p -tag I24
}
proc Move24 {w {step {}}} {
    global S Dims
    set step [GetStep 24 $step]

    if {$step > 4} {
	return 0
    } elseif {$step == 4} {
	return 2
    }

    if {$step == 0} {
	$w.c delete I24				;# Exploding balloon
	set xy [scl {
	    347 465 361 557 271 503 272 503 342 574 259 594 259 593 362 626
	    320 737 320 740 398 691 436 738 436 739 476 679 528 701 527 702
	    494 627 548 613 548 613 480 574 577 473 577 473 474 538 445 508
	    431 441 431 440 400 502 347 465 347 465
	}]
	$w.c create poly $xy -tag I24 -fill $::C(24b) -outline $::C(24a) \
		-width 7.5p -smooth 1
	set msg [subst $S(message)]
	$w.c create text [Centroid $w I24] -text $msg -tag {I24 I24t} \
		-fill $::C(24c) -justify center -font {Times 18 bold}
	return 1
    }

    $w.c itemconfig I24t -font [list Times [expr {18 + 6*$step}] bold]
    $w.c move I24 $Dims(MovX) $Dims(MovY)
    $w.c scale I24 {*}[Centroid $w I24] 1.25 1.25
    return 1
}

# Displaying the message
proc Move25 {w {step {}}} {
    global S
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
	return 1
    }
    return 2
}

# Collapsing balloon
proc Move26 {w {step {}}} {
    global S
    set step [GetStep 26 $step]

    if {$step >= 3} {
	$w.c delete I24 I26
	$w.c create text 430 755 -anchor s -tag I26 \
		-text "click to continue" -font {{Times Roman} 24 bold}
	bind $w.c <Button-1> [list Reset $w]
	return 4
    }

    $w.c scale I24 {*}[Centroid $w I24] .8 .8
    $w.c move I24 0 60
    $w.c itemconfig I24t -font [list {Times Roman} [expr {30 - 6*$step}] bold]
    return 1
}

################################################################
#
# Helper functions
#







|




|
|





|
|







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
	return 1
    }
    return 2
}

# Collapsing balloon
proc Move26 {w {step {}}} {
    global S Dims
    set step [GetStep 26 $step]

    if {$step >= 3} {
	$w.c delete I24 I26
	$w.c create text $Dims(MsgX) $Dims(MsgY) -anchor s -tag I26 \
		-fill $::C(26) -text "click to continue" -font {Times 24 bold}
	bind $w.c <Button-1> [list Reset $w]
	return 4
    }

    $w.c scale I24 {*}[Centroid $w I24] .8 .8
    $w.c move I24 0 45p
    $w.c itemconfig I24t -font [list Times [expr {30 - 6*$step}] bold]
    return 1
}

################################################################
#
# Helper functions
#
1823
1824
1825
1826
1827
1828
1829
1830


































































1831
1832
1833

    } elseif {[string match *e* $where]} {
	set x $x2
    } else {
	set x [expr {($x1 + $x2) / 2.0}]
    }
    return [list $x $y]
}



































































DoDisplay $w
Reset $w
Go $w						;# Start everything going









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
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
    } elseif {[string match *e* $where]} {
	set x $x2
    } else {
	set x [expr {($x1 + $x2) / 2.0}]
    }
    return [list $x $y]
}

proc scl {lst} {
    global scaleFactor
    set lst2 {}
    foreach elem $lst {
	set elem2 {}
	set idx 0
	foreach val $elem {
	    if {$idx < 2} {
		set val [expr {round($val * $scaleFactor)}]
	    }
	    lappend elem2 $val
	    incr idx
	}

	lappend lst2 $elem2
    }

    return $lst2
}

# Simple placed dialog - stacked dialogs are not allowed,
# the command does nothing if another grab already exists.

proc PlacedDialog {w msg {labelFnt {Helvetica 10}}} {
    if {[grab current] ne {}} {
        return
    }
    destroy $w

    frame $w -relief raised -bd 3p
    label $w.lab -font $labelFnt -wraplength 3i -justify left -text $msg
    ttk::button $w.but -text "OK" -underline 0 \
	    -command [list ClosePlacedDialog $w]

    foreach key {Escape Return o O} {
	bind $w.but "<KeyPress-${key}>" { ClosePlacedDialog [winfo parent %W] }
    }
    foreach child {{} .but .lab} {
	bind $w$child <<NextWindow>> break
	bind $w$child <<PrevWindow>> break
    }

    pack $w.lab -padx 10p -pady {10p 5p}
    pack $w.but -padx 10p -pady {0p 10p}
    place $w -anchor center -relx 0.5 -rely 0.5

    set tl [winfo toplevel $w]
    set ::PlacedDialogOldFocus [focus -lastfor $tl]
    focus $w.but
    grab set $w
    return
}

proc ClosePlacedDialog {w} {
    set tl [winfo toplevel $w]
    if {![winfo exists $::PlacedDialogOldFocus]} {
        set ::PlacedDialogOldFocus $tl
    }
    focus $::PlacedDialogOldFocus
    set ::PlacedDialogOldFocus {}
    grab release $w
    destroy $w
    return
}


DoDisplay $w
Reset $w
Go $w						;# Start everything going
StartMessage $w					;# Message box at startup

Changes to library/demos/hello.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# hello --
# Simple Tk script to create a button that prints "Hello, world".
# Click on the button to terminate the program.

package require Tk

# The first line below creates the button, and the second line
# asks the packer to shrink-wrap the application's main window
# around the button.

button .hello -text "Hello, world" -command {
    puts stdout "Hello, world"; destroy .








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# hello --
# Simple Tk script to create a button that prints "Hello, world".
# Click on the button to terminate the program.

package require tk

# The first line below creates the button, and the second line
# asks the packer to shrink-wrap the application's main window
# around the button.

button .hello -text "Hello, world" -command {
    puts stdout "Hello, world"; destroy .

Changes to library/demos/hscale.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




# hscale.tcl --
#
# This demonstration script shows an example with a horizontal scale.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .hscale
catch {destroy $w}
toplevel $w
wm title $w "Horizontal Scale Demonstration"
wm iconname $w "hscale"
positionWindow $w

label $w.msg -font $font -wraplength 3.5i -justify left -text "An arrow and a horizontal scale are displayed below.  If you click or drag mouse button 1 in the scale, you can change the length of the arrow."
pack $w.msg -side top -padx .5c

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -fill x

canvas $w.frame.canvas -width 50 -height 50 -bd 0 -highlightthickness 0
$w.frame.canvas create polygon 0 0 1 1 2 2 -fill DeepSkyBlue3 -tags poly
$w.frame.canvas create line 0 0 1 1 2 2 0 0 -fill black -tags line
scale $w.frame.scale -orient horizontal -length 284 -from 0 -to 250 \
	-command "setWidth $w.frame.canvas" -tickinterval 50
pack $w.frame.canvas -side top -expand yes -anchor s -fill x  -padx 15
pack $w.frame.scale -side bottom -expand yes -anchor n
$w.frame.scale set 75

proc setWidth {w width} {
    incr width 21
    set x2 [expr {$width - 30}]
    if {$x2 < 21} {
	set x2 21
    }
    $w coords poly 20 15 20 35 $x2 35 $x2 45 $width 25 $x2 5 $x2 15 20 15
    $w coords line 20 15 20 35 $x2 35 $x2 45 $width 25 $x2 5 $x2 15 20 15
}












|















|


|


|

|











|
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# hscale.tcl --
#
# This demonstration script shows an example with a horizontal scale.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .hscale
catch {destroy $w}
toplevel $w
wm title $w "Horizontal Scale Demonstration"
wm iconname $w "hscale"
positionWindow $w

label $w.msg -font $font -wraplength 3.5i -justify left -text "An arrow and a horizontal scale are displayed below.  If you click or drag mouse button 1 in the scale, you can change the length of the arrow."
pack $w.msg -side top -padx .5c

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 7.5p
pack $w.frame -side top -fill x

canvas $w.frame.canvas -width 37.5p -height 37.5p -bd 0 -highlightthickness 0
$w.frame.canvas create polygon 0 0 1 1 2 2 -fill DeepSkyBlue3 -tags poly
$w.frame.canvas create line 0 0 1 1 2 2 0 0 -fill black -tags line
scale $w.frame.scale -orient horizontal -length 213p -from 0 -to 250 \
	-command "setWidth $w.frame.canvas" -tickinterval 50
pack $w.frame.canvas -side top -expand yes -anchor s -fill x -padx 12p
pack $w.frame.scale -side bottom -expand yes -anchor n
$w.frame.scale set 75

proc setWidth {w width} {
    incr width 21
    set x2 [expr {$width - 30}]
    if {$x2 < 21} {
	set x2 21
    }
    $w coords poly 20 15 20 35 $x2 35 $x2 45 $width 25 $x2 5 $x2 15 20 15
    $w coords line 20 15 20 35 $x2 35 $x2 45 $width 25 $x2 5 $x2 15 20 15

    set scaleFactor [expr {$tk::scalingPct / 100.0}]
    $w scale poly 0 0 $scaleFactor $scaleFactor
    $w scale line 0 0 $scaleFactor $scaleFactor
}

Changes to library/demos/icon.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# icon.tcl --
#
# This demonstration script creates a toplevel window containing
# buttons that display bitmaps instead of text.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .icon
catch {destroy $w}
toplevel $w
wm title $w "Iconic Button Demonstration"
wm iconname $w "icon"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# icon.tcl --
#
# This demonstration script creates a toplevel window containing
# buttons that display bitmaps instead of text.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .icon
catch {destroy $w}
toplevel $w
wm title $w "Iconic Button Demonstration"
wm iconname $w "icon"
positionWindow $w
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Main widget program sets variable tk_demoDirectory
image create bitmap flagup \
	-file [file join $tk_demoDirectory images flagup.xbm] \
	-maskfile [file join $tk_demoDirectory images flagup.xbm]
image create bitmap flagdown \
	-file [file join $tk_demoDirectory images flagdown.xbm] \
	-maskfile [file join $tk_demoDirectory images flagdown.xbm]
frame $w.frame -borderwidth 10
pack $w.frame -side top

checkbutton $w.frame.b1 -image flagdown -selectimage flagup \
	-indicatoron 0
$w.frame.b1 configure -selectcolor [$w.frame.b1 cget -background]
checkbutton $w.frame.b2 \
	-bitmap @[file join $tk_demoDirectory images letters.xbm] \







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Main widget program sets variable tk_demoDirectory
image create bitmap flagup \
	-file [file join $tk_demoDirectory images flagup.xbm] \
	-maskfile [file join $tk_demoDirectory images flagup.xbm]
image create bitmap flagdown \
	-file [file join $tk_demoDirectory images flagdown.xbm] \
	-maskfile [file join $tk_demoDirectory images flagdown.xbm]
frame $w.frame -borderwidth 7.5p
pack $w.frame -side top

checkbutton $w.frame.b1 -image flagdown -selectimage flagup \
	-indicatoron 0
$w.frame.b1 configure -selectcolor [$w.frame.b1 cget -background]
checkbutton $w.frame.b2 \
	-bitmap @[file join $tk_demoDirectory images letters.xbm] \

Changes to library/demos/image1.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
# image1.tcl --
#
# This demonstration script displays two image widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .image1
catch {destroy $w}
toplevel $w
wm title $w "Image Demonstration #1"
wm iconname $w "Image1"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration displays two images, each in a separate label widget."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Main widget program sets variable tk_demoDirectory
catch {image delete image1a}
image create photo image1a -file [file join $tk_demoDirectory images earth.gif]
label $w.l1 -image image1a -bd 1 -relief sunken

catch {image delete image1b}
image create photo image1b \
	-file [file join $tk_demoDirectory images earthris.gif]











label $w.l2 -image image1b -bd 1 -relief sunken

pack $w.l1 $w.l2 -side top -padx .5m -pady .5m








|


















<
<



>
>
>
>
>
>
>
>
>
>
>
|


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# image1.tcl --
#
# This demonstration script displays two image widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .image1
catch {destroy $w}
toplevel $w
wm title $w "Image Demonstration #1"
wm iconname $w "Image1"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration displays two images, each in a separate label widget."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Main widget program sets variable tk_demoDirectory
catch {image delete image1a}
image create photo image1a -file [file join $tk_demoDirectory images earth.gif]


catch {image delete image1b}
image create photo image1b \
	-file [file join $tk_demoDirectory images earthris.gif]

# Create copies of the images just created, magnified according to the
# display's DPI scaling level.  Since the zooom factor must be an integer,
# the copies will only be effectively magnified if $tk::scalingPct >= 200.
set zoomFactor [expr {$tk::scalingPct / 100}]
image create photo image1a2
image1a2 copy image1a -zoom $zoomFactor
image create photo image1b2
image1b2 copy image1b -zoom $zoomFactor

label $w.l1 -image image1a2 -bd 1 -relief sunken
label $w.l2 -image image1b2 -bd 1 -relief sunken

pack $w.l1 $w.l2 -side top -padx .5m -pady .5m

Changes to library/demos/image2.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# image2.tcl --
#
# This demonstration script creates a simple collection of widgets
# that allow you to select and view images in a Tk label.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# loadDir --
# This procedure reloads the directory listbox from the directory
# named in the demo's entry.
#
# Arguments:
# w -			Name of the toplevel window of the demo.









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# image2.tcl --
#
# This demonstration script creates a simple collection of widgets
# that allow you to select and view images in a Tk label.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# loadDir --
# This procedure reloads the directory listbox from the directory
# named in the demo's entry.
#
# Arguments:
# w -			Name of the toplevel window of the demo.
51
52
53
54
55
56
57






58
59
60
61
62
63
64
65
66
# w -			Name of the toplevel window of the demo.
# x, y-			Mouse position within the listbox.

proc loadImage {w x y} {
    global dirName

    set file [file join $dirName [$w.f.list get @$x,$y]]






    if {[catch {
	image2a configure -file $file
    }]} then {
	# Mark the file as not loadable
	$w.f.list itemconfigure @$x,$y -bg \#c00000 -selectbackground \#ff0000
    }
}

set w .image2







>
>
>
>
>
>

|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# w -			Name of the toplevel window of the demo.
# x, y-			Mouse position within the listbox.

proc loadImage {w x y} {
    global dirName

    set file [file join $dirName [$w.f.list get @$x,$y]]
    set opts [list -file $file]
    if {[string tolower [file extension $file]] eq ".svg"} {
	lappend opts -format $tk::svgFmt
    } else {
	lappend opts -format {}
    }
    if {[catch {
	image2a configure {*}$opts
    }]} then {
	# Mark the file as not loadable
	$w.f.list itemconfigure @$x,$y -bg \#c00000 -selectbackground \#ff0000
    }
}

set w .image2
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
pack $w.dir.e -side left -fill both -padx 2m     -pady 2m -expand true
pack $w.dir.b -side left -fill y    -padx {0 2m} -pady 2m
labelframe $w.f -text "File:" -padx 2m -pady 2m

listbox $w.f.list -width 20 -height 10 -yscrollcommand "$w.f.scroll set"
ttk::scrollbar $w.f.scroll -command "$w.f.list yview"
pack $w.f.list $w.f.scroll -side left -fill y -expand 1
$w.f.list insert 0 earth.gif earthris.gif teapot.ppm
bind $w.f.list <Double-Button-1> "loadImage $w %x %y"

catch {image delete image2a}
image create photo image2a
labelframe $w.image -text "Image:"
label $w.image.image -image image2a
pack $w.image.image -padx 2m -pady 2m

grid $w.dir -        -sticky ew -padx 1m -pady 1m -in $w.mid
grid $w.f   $w.image -sticky nw -padx 1m -pady 1m -in $w.mid
grid columnconfigure $w.mid 1 -weight 1







|











96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
pack $w.dir.e -side left -fill both -padx 2m     -pady 2m -expand true
pack $w.dir.b -side left -fill y    -padx {0 2m} -pady 2m
labelframe $w.f -text "File:" -padx 2m -pady 2m

listbox $w.f.list -width 20 -height 10 -yscrollcommand "$w.f.scroll set"
ttk::scrollbar $w.f.scroll -command "$w.f.list yview"
pack $w.f.list $w.f.scroll -side left -fill y -expand 1
$w.f.list insert 0 earth.gif earthris.gif teapot.ppm Tcl.svg
bind $w.f.list <Double-Button-1> "loadImage $w %x %y"

catch {image delete image2a}
image create photo image2a
labelframe $w.image -text "Image:"
label $w.image.image -image image2a
pack $w.image.image -padx 2m -pady 2m

grid $w.dir -        -sticky ew -padx 1m -pady 1m -in $w.mid
grid $w.f   $w.image -sticky nw -padx 1m -pady 1m -in $w.mid
grid columnconfigure $w.mid 1 -weight 1

Added library/demos/images/Tcl.svg.























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://web.resource.org/cc/"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="124.98526"
   height="264.6875"
   id="svg2309"
   sodipodi:version="0.32"
   inkscape:version="0.45"
   sodipodi:modified="true"
   version="1.0">
  <defs
     id="defs2311" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     gridtolerance="10000"
     guidetolerance="10"
     objecttolerance="10"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.35"
     inkscape:cx="375"
     inkscape:cy="520"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     inkscape:window-width="910"
     inkscape:window-height="626"
     inkscape:window-x="5"
     inkscape:window-y="49" />
  <metadata
     id="metadata2314">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(-311.79308,-365.73272)">
    <g
       style="opacity:1;display:inline"
       id="g2244"
       transform="translate(308.95998,366.42022)">
      <path
         id="path4426"
         d="M 445.52492,372.22514 C 445.90652,395.55723 445.21415,418.63757 425.02492,440.56889 L 424.27492,441.41264 L 425.39992,441.41264 L 433.64992,441.53764 C 420.24442,469.42405 411.52244,497.23134 392.24367,525.00639 L 391.55617,526.00639 L 392.74367,525.78764 L 402.93117,523.85014 C 395.71427,542.16045 383.37359,554.28293 369.99367,558.35014 C 366.31107,506.78151 392.04593,461.26308 413.89992,415.88139 C 413.92002,415.83965 413.94233,415.79813 413.96242,415.75639 L 413.14992,415.19389 C 377.36425,455.2074 361.23872,511.6427 355.14992,558.19389 C 343.02146,551.34666 338.97913,542.28079 334.86867,529.94389 L 343.33742,533.50639 L 344.21242,533.88139 L 344.02492,532.94389 C 337.58858,504.32416 347.5814,483.78143 357.27492,456.78764 L 364.24367,461.44389 L 365.05617,462.00639 L 365.02492,461.03764 C 364.47892,439.10645 379.24595,417.08983 398.83742,397.44389 L 401.55617,404.72514 L 401.93117,405.69389 L 402.46242,404.78764 L 408.43117,394.85014 L 408.46242,394.78764 C 418.31429,381.21812 428.72988,376.80082 445.52492,372.22514 z "
         style="fill:#c3b15f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
         transform="translate(-324.02492,-364.63139)" />
      <path
         sodipodi:nodetypes="ccccccccccccccccccccccc"
         id="path7600"
         d="M 121.54988,7.5808058 C 104.81215,12.147023 94.270242,16.613077 84.4375,30.15625 L 84.40625,30.21875 L 78.4375,40.15625 L 77.90625,41.0625 L 77.53125,40.09375 L 74.8125,32.8125 C 55.22103,52.45844 40.454,74.47506 41,96.40625 L 41.03125,97.375 L 40.21875,96.8125 L 33.25,92.15625 C 23.55648,119.15004 13.56366,139.69277 20,168.3125 L 20.1875,169.25 L 19.3125,168.875 L 10.9375,165.34375 C 10.96447,165.51523 11.003113,165.67421 11.03125,165.84375 C 15.080346,177.9015 19.176955,186.81713 31.125,193.5625 C 31.596616,189.95681 32.122231,186.27456 32.71875,182.5625 C 18.12816,148.39836 30.79293,123.2814 36.5625,100.6875 L 45.4375,105.8125 C 44.211577,84.657017 56.63174,61.842112 72.78125,41.9375 L 77.46875,50.1875 C 89.477498,25.486664 98.97512,15.57175 121.54988,7.5808058 z "
         style="opacity:1;fill:#eff1cb;fill-opacity:1;fill-rule:evenodd;stroke:#eff1cb;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
      <path
         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
         d="M 126.9375,-0.6875 L 126.40625,-0.59375 C 106.72165,2.83976 87.4508,10.07244 79,27.375 L 75.4375,21.15625 L 75.125,20.59375 L 74.65625,21.0625 C 64.96254,30.33838 54.55574,42.35306 46.875,54.15625 C 39.66528,65.23562 34.88327,76.07934 35.40625,84.375 L 30.375,78.09375 L 29.875,77.46875 L 29.53125,78.1875 C 23.40732,91.41649 17.22694,107.69157 13.53125,122.625 C 10.02725,136.78385 8.77244,149.67206 12.03125,157.78125 L 3.75,152.96875 L 3.0625,152.5625 L 3,153.375 C 1.44089,176.99202 11.0382,188.26833 22.0625,199.15625 L 12.875,201.4375 L 11.03125,201.90625 L 12.875,202.40625 C 18.14953,203.83558 23.15023,205.44485 26.625,208.125 C 30.09977,210.80515 32.09598,214.49082 31.5,220.375 L 31.5,220.40625 L 31.5,245.90625 L 31.5,246.0625 L 31.59375,246.1875 L 43.09375,262.6875 L 44,264 L 44,262.40625 L 44,223.53125 C 45.52181,216.98735 47.30807,212.4833 49.875,209.5 C 52.44193,206.5167 55.78211,204.98483 60.5625,204.40625 L 62.28125,204.1875 L 60.71875,203.46875 L 54.65625,200.59375 C 69.11174,191.89001 85.3013,170.55445 89.5625,150.28125 L 89.75,149.46875 L 88.96875,149.6875 L 81.46875,151.71875 C 88.13174,145.46249 94.84392,133.06721 101.21875,118.625 C 107.9798,103.3078 114.29247,85.96032 119.46875,72.09375 L 119.75,71.34375 L 118.96875,71.40625 L 113.1875,71.8125 C 120.3346,64.22669 124.30703,51.6996 126.25,38.46875 C 128.27227,24.69793 128.13035,10.1977 127,-0.15625 L 126.9375,-0.6875 z M 121.5,7.59375 C 121.8816,30.92584 121.18923,54.00618 101,75.9375 L 100.25,76.78125 L 101.375,76.78125 L 109.625,76.90625 C 96.2195,104.79266 87.49752,132.59995 68.21875,160.375 L 67.53125,161.375 L 68.71875,161.15625 L 78.90625,159.21875 C 71.68935,177.52906 59.34867,189.65154 45.96875,193.71875 C 42.28615,142.15012 68.02101,96.63169 89.875,51.25 C 89.8951,51.20826 89.91741,51.16674 89.9375,51.125 L 89.125,50.5625 C 53.33933,90.57601 37.2138,147.01131 31.125,193.5625 C 18.99654,186.71527 14.95421,177.6494 10.84375,165.3125 L 19.3125,168.875 L 20.1875,169.25 L 20,168.3125 C 13.56366,139.69277 23.55648,119.15004 33.25,92.15625 L 40.21875,96.8125 L 41.03125,97.375 L 41,96.40625 C 40.454,74.47506 55.22103,52.45844 74.8125,32.8125 L 77.53125,40.09375 L 77.90625,41.0625 L 78.4375,40.15625 L 84.40625,30.21875 L 84.4375,30.15625 C 94.28937,16.58673 104.70496,12.16943 121.5,7.59375 z "
         id="path2177" />
    </g>
  </g>
</svg>

Added library/demos/images/Tk_feather.png.

cannot compute difference between binary files

Changes to library/demos/images/earth.gif.

cannot compute difference between binary files

Added library/demos/images/plowed_field.png.

cannot compute difference between binary files

Added library/demos/images/starry_night.png.

cannot compute difference between binary files

Changes to library/demos/items.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# items.tcl --
#
# This demonstration script creates a canvas that displays the
# canvas item types.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .items
catch {destroy $w}
toplevel $w
wm title $w "Canvas Item Demonstration"
wm iconname $w "Items"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# items.tcl --
#
# This demonstration script creates a canvas that displays the
# canvas item types.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .items
catch {destroy $w}
toplevel $w
wm title $w "Canvas Item Demonstration"
wm iconname $w "Items"
positionWindow $w
28
29
30
31
32
33
34
35







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
pack $w.frame -side top -fill both -expand yes

canvas $c -scrollregion {0c 0c 30c 24c} -width 15c -height 10c \
	-relief sunken -borderwidth 2 \
	-xscrollcommand "$w.frame.hscroll set" \
	-yscrollcommand "$w.frame.vscroll set"
ttk::scrollbar $w.frame.vscroll -command "$c yview"
ttk::scrollbar $w.frame.hscroll -orient horiz -command "$c xview"








grid $c -in $w.frame \
    -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.vscroll \
    -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.hscroll \
    -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid rowconfig    $w.frame 0 -weight 1 -minsize 0
grid columnconfig $w.frame 0 -weight 1 -minsize 0

# Display a 3x3 rectangular grid.

$c create rect 0c 0c 30c 24c -width 2
$c create line 0c 8c 30c 8c -width 2
$c create line 0c 16c 30c 16c -width 2
$c create line 10c 0c 10c 24c -width 2
$c create line 20c 0c 20c 24c -width 2

set font1 {Helvetica 12}
set font2 {Helvetica 24 bold}
if {[winfo depth $c] > 1} {
    set blue DeepSkyBlue3
    set red red
    set bisque bisque3







|
>
>
>
>
>
>
>












|
|
|
|
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
pack $w.frame -side top -fill both -expand yes

canvas $c -scrollregion {0c 0c 30c 24c} -width 15c -height 10c \
	-relief sunken -borderwidth 2 \
	-xscrollcommand "$w.frame.hscroll set" \
	-yscrollcommand "$w.frame.vscroll set"
ttk::scrollbar $w.frame.vscroll -command "$c yview"
ttk::scrollbar $w.frame.hscroll -orient horizontal -command "$c xview"

bind $c <TouchpadScroll> {
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    if {$deltaX != 0 || $deltaY != 0} {
	tk::ScrollByPixels %W $deltaX $deltaY
    }
}

grid $c -in $w.frame \
    -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.vscroll \
    -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid $w.frame.hscroll \
    -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid rowconfig    $w.frame 0 -weight 1 -minsize 0
grid columnconfig $w.frame 0 -weight 1 -minsize 0

# Display a 3x3 rectangular grid.

$c create rect 0c 0c 30c 24c -width 1.5p
$c create line 0c 8c 30c 8c -width 1.5p
$c create line 0c 16c 30c 16c -width 1.5p
$c create line 10c 0c 10c 24c -width 1.5p
$c create line 20c 0c 20c 24c -width 1.5p

set font1 {Helvetica 12}
set font2 {Helvetica 24 bold}
if {[winfo depth $c] > 1} {
    set blue DeepSkyBlue3
    set red red
    set bisque bisque3
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
$c create text 5c .2c -text Lines -anchor n
$c create line 1c 1c 3c 1c 1c 4c 3c 4c -width 2m -fill $blue \
	-cap butt -join miter -tags item
$c create line 4.67c 1c 4.67c 4c -arrow last -tags item
$c create line 6.33c 1c 6.33c 4c -arrow both -tags item
$c create line 5c 6c 9c 6c 9c 1c 8c 1c 8c 4.8c 8.8c 4.8c 8.8c 1.2c \
	8.2c 1.2c 8.2c 4.6c 8.6c 4.6c 8.6c 1.4c 8.4c 1.4c 8.4c 4.4c \
	-width 3 -fill $red -tags item
# Main widget program sets variable tk_demoDirectory
$c create line 1c 5c 7c 5c 7c 7c 9c 7c -width .5c \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-arrow both -arrowshape {15 15 7} -tags item
$c create line 1c 7c 1.75c 5.8c 2.5c 7c 3.25c 5.8c 4c 7c -width .5c \
	-cap round -join round -tags item

$c create text 15c .2c -text "Curves (smoothed lines)" -anchor n
$c create line 11c 4c 11.5c 1c 13.5c 1c 14c 4c -smooth on \
	-fill $blue -tags item
$c create line 15.5c 1c 19.5c 1.5c 15.5c 4.5c 19.5c 4c -smooth on \
	-arrow both -width 3 -tags item
$c create line 12c 6c 13.5c 4.5c 16.5c 7.5c 18c 6c \
	16.5c 4.5c 13.5c 7.5c 12c 6c -smooth on -width 3m -cap round \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $red -tags item

$c create text 25c .2c -text Polygons -anchor n
$c create polygon 21c 1.0c 22.5c 1.75c 24c 1.0c 23.25c 2.5c \
	24c 4.0c 22.5c 3.25c 21c 4.0c 21.75c 2.5c -fill $green \
	-outline {} -width 4 -tags item
$c create polygon 25c 4c 25c 4c 25c 1c 26c 1c 27c 4c 28c 1c \
	29c 1c 29c 4c 29c 4c -fill $red -outline {} -smooth on -tags item
$c create polygon 22c 4.5c 25c 4.5c 25c 6.75c 28c 6.75c \
	28c 5.25c 24c 5.25c 24c 6.0c 26c 6c 26c 7.5c 22c 7.5c \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $blue -outline {} -tags item








|











|








|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
$c create text 5c .2c -text Lines -anchor n
$c create line 1c 1c 3c 1c 1c 4c 3c 4c -width 2m -fill $blue \
	-cap butt -join miter -tags item
$c create line 4.67c 1c 4.67c 4c -arrow last -tags item
$c create line 6.33c 1c 6.33c 4c -arrow both -tags item
$c create line 5c 6c 9c 6c 9c 1c 8c 1c 8c 4.8c 8.8c 4.8c 8.8c 1.2c \
	8.2c 1.2c 8.2c 4.6c 8.6c 4.6c 8.6c 1.4c 8.4c 1.4c 8.4c 4.4c \
	-width 2.25p -fill $red -tags item
# Main widget program sets variable tk_demoDirectory
$c create line 1c 5c 7c 5c 7c 7c 9c 7c -width .5c \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-arrow both -arrowshape {15 15 7} -tags item
$c create line 1c 7c 1.75c 5.8c 2.5c 7c 3.25c 5.8c 4c 7c -width .5c \
	-cap round -join round -tags item

$c create text 15c .2c -text "Curves (smoothed lines)" -anchor n
$c create line 11c 4c 11.5c 1c 13.5c 1c 14c 4c -smooth on \
	-fill $blue -tags item
$c create line 15.5c 1c 19.5c 1.5c 15.5c 4.5c 19.5c 4c -smooth on \
	-arrow both -width 2.25p -tags item
$c create line 12c 6c 13.5c 4.5c 16.5c 7.5c 18c 6c \
	16.5c 4.5c 13.5c 7.5c 12c 6c -smooth on -width 3m -cap round \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $red -tags item

$c create text 25c .2c -text Polygons -anchor n
$c create polygon 21c 1.0c 22.5c 1.75c 24c 1.0c 23.25c 2.5c \
	24c 4.0c 22.5c 3.25c 21c 4.0c 21.75c 2.5c -fill $green \
	-outline {} -width 3p -tags item
$c create polygon 25c 4c 25c 4c 25c 1c 26c 1c 27c 4c 28c 1c \
	29c 1c 29c 4c 29c 4c -fill $red -outline {} -smooth on -tags item
$c create polygon 22c 4.5c 25c 4.5c 25c 6.75c 28c 6.75c \
	28c 5.25c 24c 5.25c 24c 6.0c 26c 6c 26c 7.5c 22c 7.5c \
	-stipple @[file join $tk_demoDirectory images gray25.xbm] \
	-fill $blue -outline {} -tags item

144
145
146
147
148
149
150





151
152
153
154
155
156
157
158
159

$c create text 15c 16.2c -text "Bitmaps and Images" -anchor n
catch {
image create photo items.ousterhout \
    -file [file join $tk_demoDirectory images ouster.png]
image create photo items.ousterhout.active -format "png -alpha 0.5" \
    -file [file join $tk_demoDirectory images ouster.png]





$c create image 13c 20c -tags item -image items.ousterhout \
    -activeimage items.ousterhout.active
}
$c create bitmap 17c 18.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images noletter.xbm]
$c create bitmap 17c 21.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images letters.xbm]

$c create text 25c 16.2c -text Windows -anchor n







>
>
>
>
>
|
|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

$c create text 15c 16.2c -text "Bitmaps and Images" -anchor n
catch {
image create photo items.ousterhout \
    -file [file join $tk_demoDirectory images ouster.png]
image create photo items.ousterhout.active -format "png -alpha 0.5" \
    -file [file join $tk_demoDirectory images ouster.png]
set zoomFactor [expr {$tk::scalingPct / 100}]
foreach img {items.ousterhout items.ousterhout.active} {
    image create photo ${img}2
    ${img}2 copy $img -zoom $zoomFactor
}
$c create image 13c 20c -tags item -image items.ousterhout2 \
    -activeimage items.ousterhout.active2
}
$c create bitmap 17c 18.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images noletter.xbm]
$c create bitmap 17c 21.5c -tags item \
	-bitmap @[file join $tk_demoDirectory images letters.xbm]

$c create text 25c 16.2c -text Windows -anchor n
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
$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"







|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
$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"

Changes to library/demos/ixset.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# ixset --
# A nice interface to "xset" to change X server settings
#
# History :
#   91/11/23 : [email protected], [email protected] : design
#   92/08/01 : [email protected] : cleaning

package require Tk

#
# Button actions
#

proc quit {} {
    destroy .











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# ixset --
# A nice interface to "xset" to change X server settings
#
# History :
#   91/11/23 : [email protected], [email protected] : design
#   92/08/01 : [email protected] : cleaning

package require tk

#
# Button actions
#

proc quit {} {
    destroy .
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
    button .buttons.apply  -default normal -command apply  -text "Apply" \
	    -state disabled
    button .buttons.cancel -default normal -command cancel -text "Cancel" \
	    -state disabled
    button .buttons.quit   -default normal -command quit   -text "Quit"

    pack .buttons.ok .buttons.apply .buttons.cancel .buttons.quit \
	    -side left -expand yes -pady 5

    bind . <Return> {.buttons.ok   flash; .buttons.ok   invoke}
    bind . <Escape> {.buttons.quit flash; .buttons.quit invoke}
    bind . <Button-1> {
	if {![string match .buttons* %W]} {
	    .buttons.apply  configure -state normal
	    .buttons.cancel configure -state normal







|







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
    button .buttons.apply  -default normal -command apply  -text "Apply" \
	    -state disabled
    button .buttons.cancel -default normal -command cancel -text "Cancel" \
	    -state disabled
    button .buttons.quit   -default normal -command quit   -text "Quit"

    pack .buttons.ok .buttons.apply .buttons.cancel .buttons.quit \
	    -side left -expand yes -pady 3p

    bind . <Return> {.buttons.ok   flash; .buttons.ok   invoke}
    bind . <Escape> {.buttons.quit flash; .buttons.quit invoke}
    bind . <Button-1> {
	if {![string match .buttons* %W]} {
	    .buttons.apply  configure -state normal
	    .buttons.cancel configure -state normal
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

    #
    # Bell settings
    #

    labelframe .bell -text "Bell Settings" -padx 1.5m -pady 1.5m
    scale .bell.vol \
	    -from 0 -to 100 -length 200 -tickinterval 20 \
	    -label "Volume (%)" -orient horizontal

    frame .bell.val
    labelentry .bell.val.pit "Pitch (Hz)"    6 {25 20000}
    labelentry .bell.val.dur "Duration (ms)" 6 {1 10000}
    pack .bell.val.pit -side left -padx 5
    pack .bell.val.dur -side right -padx 5
    pack .bell.vol .bell.val -side top -expand yes

    #
    # Keyboard settings
    #

    labelframe .kbd -text "Keyboard Repeat Settings" -padx 1.5m -pady 1.5m

    frame .kbd.val
    checkbutton .kbd.val.onoff \
	    -text "On" \
	    -onvalue "on" -offvalue "off" -variable kbdrep \
	    -relief flat
    scale .kbd.val.cli \
	    -from 0 -to 100 -length 200 -tickinterval 20 \
	    -label "Click Volume (%)" -orient horizontal
    pack .kbd.val.onoff -side left -fill x -expand yes -padx {0 1m}
    pack .kbd.val.cli -side left -expand yes -fill x -padx {1m 0}

    pack .kbd.val -side top -expand yes -pady 2 -fill x

    #
    # Mouse settings
    #

    labelframe .mouse -text "Mouse Settings" -padx 1.5m -pady 1.5m








|





|
|














|




|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

    #
    # Bell settings
    #

    labelframe .bell -text "Bell Settings" -padx 1.5m -pady 1.5m
    scale .bell.vol \
	    -from 0 -to 100 -length 150p -tickinterval 20 \
	    -label "Volume (%)" -orient horizontal

    frame .bell.val
    labelentry .bell.val.pit "Pitch (Hz)"    6 {25 20000}
    labelentry .bell.val.dur "Duration (ms)" 6 {1 10000}
    pack .bell.val.pit -side left -padx 3p
    pack .bell.val.dur -side right -padx 3p
    pack .bell.vol .bell.val -side top -expand yes

    #
    # Keyboard settings
    #

    labelframe .kbd -text "Keyboard Repeat Settings" -padx 1.5m -pady 1.5m

    frame .kbd.val
    checkbutton .kbd.val.onoff \
	    -text "On" \
	    -onvalue "on" -offvalue "off" -variable kbdrep \
	    -relief flat
    scale .kbd.val.cli \
	    -from 0 -to 100 -length 150p -tickinterval 20 \
	    -label "Click Volume (%)" -orient horizontal
    pack .kbd.val.onoff -side left -fill x -expand yes -padx {0 1m}
    pack .kbd.val.cli -side left -expand yes -fill x -padx {1m 0}

    pack .kbd.val -side top -expand yes -pady 1.5p -fill x

    #
    # Mouse settings
    #

    labelframe .mouse -text "Mouse Settings" -padx 1.5m -pady 1.5m

Changes to library/demos/knightstour.tcl.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#	If the call to the Edgemost function is commented out you can see
#	this occur.
#
#	You can drag the knight to a specific square to start if you wish.
#	If you let it repeat then it will choose random start positions
#	for each new tour.

package require Tk

# Return a list of accessible squares from a given square
proc ValidMoves {square} {
    set moves {}
    foreach pair {{-1 -2} {-2 -1} {-2 1} {-1 2} {1 2} {2 1} {2 -1} {1 -2}} {
        set col [expr {($square % 8) + [lindex $pair 0]}]
        set row [expr {($square / 8) + [lindex $pair 1]}]







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#	If the call to the Edgemost function is commented out you can see
#	this occur.
#
#	You can drag the knight to a specific square to start if you wish.
#	If you let it repeat then it will choose random start positions
#	for each new tour.

package require tk

# Return a list of accessible squares from a given square
proc ValidMoves {square} {
    set moves {}
    foreach pair {{-1 -2} {-2 -1} {-2 1} {-1 2} {1 2} {2 1} {2 -1} {1 -2}} {
        set col [expr {($square % 8) + [lindex $pair 0]}]
        set row [expr {($square / 8) + [lindex $pair 1]}]
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    set rowA [expr {3-int(abs(3.5-($a/8)))}]
    set rowB [expr {3-int(abs(3.5-($b/8)))}]
    return [expr {($colA * $rowA) < ($colB * $rowB) ? $a : $b}]
}

# Display a square number as a standard chess square notation.
proc N {square} {
    return [format %c%d [expr {97 + $square % 8}] \
                [expr {$square / 8 + 1}]]
}

# Perform a Knight's move and schedule the next move.
proc MovePiece {dlg last square} {
    variable visited
    variable delay
    variable continuous

    $dlg.f.txt insert end "[llength $visited]. [N $last] .. [N $square]\n" {}
    $dlg.f.txt see end
    $dlg.f.c itemconfigure [expr {1+$last}] -state normal -outline black
    $dlg.f.c itemconfigure [expr {1+$square}] -state normal -outline red
    $dlg.f.c moveto knight {*}[lrange [$dlg.f.c coords [expr {1+$square}]] 0 1]
    lappend visited $square
    set next [Next $square]
    if {$next ne -1} {
        variable aid [after $delay [list MovePiece $dlg $square $next]]
    } else {
        $dlg.tf.b1 configure -state normal
        if {[llength $visited] == 64} {
            variable initial
            if {$initial == $square} {
                $dlg.f.txt insert end "Closed tour!"
            } else {
                $dlg.f.txt insert end "Success\n" {}
                if {$continuous} {
                    after [expr {$delay * 2}] [namespace code \
                        [list Tour $dlg [expr {int(rand() * 64)}]]]
                }
            }
        } else {
            $dlg.f.txt insert end "FAILED!\n" {}
        }
    }
}

# Begin a new tour of the board given a random start position
proc Tour {dlg {square {}}} {
    variable visited {}







|
<







>
|















|






|







77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    set rowA [expr {3-int(abs(3.5-($a/8)))}]
    set rowB [expr {3-int(abs(3.5-($b/8)))}]
    return [expr {($colA * $rowA) < ($colB * $rowB) ? $a : $b}]
}

# Display a square number as a standard chess square notation.
proc N {square} {
    return [format %c%d [expr {97 + $square % 8}] [expr {$square / 8 + 1}]]

}

# Perform a Knight's move and schedule the next move.
proc MovePiece {dlg last square} {
    variable visited
    variable delay
    variable continuous
    set line [format "%2d. %s .. %s" [llength $visited] [N $last] [N $square]]
    $dlg.f.txt insert end $line\n
    $dlg.f.txt see end
    $dlg.f.c itemconfigure [expr {1+$last}] -state normal -outline black
    $dlg.f.c itemconfigure [expr {1+$square}] -state normal -outline red
    $dlg.f.c moveto knight {*}[lrange [$dlg.f.c coords [expr {1+$square}]] 0 1]
    lappend visited $square
    set next [Next $square]
    if {$next ne -1} {
        variable aid [after $delay [list MovePiece $dlg $square $next]]
    } else {
        $dlg.tf.b1 configure -state normal
        if {[llength $visited] == 64} {
            variable initial
            if {$initial == $square} {
                $dlg.f.txt insert end "Closed tour!"
            } else {
                $dlg.f.txt insert end "Success"
                if {$continuous} {
                    after [expr {$delay * 2}] [namespace code \
                        [list Tour $dlg [expr {int(rand() * 64)}]]]
                }
            }
        } else {
            $dlg.f.txt insert end "FAILED!"
        }
    }
}

# Begin a new tour of the board given a random start position
proc Tour {dlg {square {}}} {
    variable visited {}
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155

proc Exit {dlg} {
    Stop
    destroy $dlg
}

proc SetDelay {new} {

    variable delay [expr {int($new)}]
}

proc DragStart {w x y} {
    $w dtag selected
    $w addtag selected withtag current
    variable dragging [list $x $y]
}







>
|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

proc Exit {dlg} {
    Stop
    destroy $dlg
}

proc SetDelay {new} {
    variable speed [expr {int($new)}]
    variable delay [expr {2000 - $speed}]
}

proc DragStart {w x y} {
    $w dtag selected
    $w addtag selected withtag current
    variable dragging [list $x $y]
}
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200

201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218


219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    $w dtag selected
    variable dragging ; unset dragging
}

proc CreateGUI {} {
    catch {destroy .knightstour}
    set dlg [toplevel .knightstour]
    wm title $dlg "Knights tour"
    wm withdraw $dlg
    set f [ttk::frame $dlg.f]
    set c [canvas $f.c -width 240 -height 240]
    text $f.txt -width 10 -height 1 \
        -yscrollcommand [list $f.vs set] -font {Arial 8}
    ttk::scrollbar $f.vs -command [list $f.txt yview]


    variable delay 600
    variable continuous 0
    ttk::frame $dlg.tf
    ttk::label $dlg.tf.ls -text Speed
    ttk::scale $dlg.tf.sc  -from 8 -to 2000 -command [list SetDelay] \
        -variable [namespace which -variable delay]
    ttk::checkbutton $dlg.tf.cc -text Repeat \
        -variable [namespace which -variable continuous]

    ttk::button $dlg.tf.b1 -text Start -command [list Tour $dlg]
    ttk::button $dlg.tf.b2 -text Exit -command [list Exit $dlg]
    set square 0
    for {set row 7} {$row >= 0} {incr row -1} {
        for {set col 0} {$col < 8} {incr col} {
            if {(($col & 1) ^ ($row & 1))} {
                set fill tan3 ; set dfill tan4
            } else {
                set fill bisque ; set dfill bisque3
            }
            set coords [list [expr {$col * 30 + 4}] [expr {$row * 30 + 4}] \

                            [expr {$col * 30 + 30}] [expr {$row * 30 + 30}]]

            $c create rectangle $coords -fill $fill -disabledfill $dfill \
                -width 2 -state disabled -outline black
        }
    }
    if {[tk windowingsystem] ne "x11"} {
        catch {eval font create KnightFont -size -24}
        $c create text 0 0 -font KnightFont -text "♞" \
            -anchor nw -tags knight -fill black -activefill "#600000"
    } else {
        # On X11 we cannot reliably tell if the ♞ glyph is available
        # so just use a polygon
        set pts {
            2 25   24 25  21 19   20 8   14 0   10 0   0 13   0 16
            2 17    4 14   5 15    3 17   5 17   9 14  10 15  5 21
        }
        $c create polygon $pts -tag knight -offset 8 \
            -fill black -activefill "#600000"


    }
    $c moveto knight {*}[lrange [$c coords [expr {1 + int(rand() * 64)}]] 0 1]
    $c bind knight <Button-1> [namespace code [list DragStart %W %x %y]]
    $c bind knight <Motion> [namespace code [list DragMotion %W %x %y]]
    $c bind knight <ButtonRelease-1> [namespace code [list DragEnd %W %x %y]]

    grid $c $f.txt $f.vs  -sticky news
    grid rowconfigure    $f 0 -weight 1
    grid columnconfigure $f 1 -weight 1

    grid $f - - - - - -sticky news
    set things [list $dlg.tf.ls $dlg.tf.sc $dlg.tf.cc $dlg.tf.b1]
    if {![info exists ::widgetDemo]} {
	lappend things $dlg.tf.b2
	if {[tk windowingsystem] ne "aqua"} {
	    set things [linsert $things 0 [ttk::sizegrip $dlg.tf.sg]]
	}
    }
    pack {*}$things -side right
    if {[tk windowingsystem] eq "aqua"} {
	pack configure {*}$things -padx {4 4} -pady {12 12}
	pack configure [lindex $things 0] -padx {4 24}
	pack configure [lindex $things end] -padx {16 4}
    }
    grid $dlg.tf  - - - - - -sticky ew
    if {[info exists ::widgetDemo]} {







|


|
|
|


>
|


|
<
|
|
|
>










|
>
|
>

|



|






|




>
>











|






|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    $w dtag selected
    variable dragging ; unset dragging
}

proc CreateGUI {} {
    catch {destroy .knightstour}
    set dlg [toplevel .knightstour]
    wm title $dlg "Knight's Tour"
    wm withdraw $dlg
    set f [ttk::frame $dlg.f]
    set c [canvas $f.c -width 192p -height 192p]
    text $f.txt -width 12 -height 1 -padx 3p \
        -yscrollcommand [list $f.vs set] -font TkFixedFont
    ttk::scrollbar $f.vs -command [list $f.txt yview]

    variable speed 1400
    variable delay [expr {2000 - $speed}]
    variable continuous 0
    ttk::frame $dlg.tf
    ttk::checkbutton $dlg.tf.cc -text Repeat \

        -variable [namespace which -variable continuous]
    ttk::scale $dlg.tf.sc  -from 0 -to 1992 -command [list SetDelay] \
        -variable [namespace which -variable speed]
    ttk::label $dlg.tf.ls -text Speed
    ttk::button $dlg.tf.b1 -text Start -command [list Tour $dlg]
    ttk::button $dlg.tf.b2 -text Exit -command [list Exit $dlg]
    set square 0
    for {set row 7} {$row >= 0} {incr row -1} {
        for {set col 0} {$col < 8} {incr col} {
            if {(($col & 1) ^ ($row & 1))} {
                set fill tan3 ; set dfill tan4
            } else {
                set fill bisque ; set dfill bisque3
            }
            set coords [list [expr {$col * 24 + 3}]p \
			     [expr {$row * 24 + 3}]p \
                             [expr {$col * 24 + 24}]p \
			     [expr {$row * 24 + 24}]p]
            $c create rectangle $coords -fill $fill -disabledfill $dfill \
                -width 1.5p -state disabled -outline black
        }
    }
    if {[tk windowingsystem] ne "x11"} {
        catch {eval font create KnightFont -size 18}
        $c create text 0 0 -font KnightFont -text "♞" \
            -anchor nw -tags knight -fill black -activefill "#600000"
    } else {
        # On X11 we cannot reliably tell if the ♞ glyph is available
        # so just use a polygon
        set pts {
            2 25   24 25  21 19   20 8   14 0   10 0    0 13  0 16
            2 17    4 14   5 15    3 17   5 17   9 14  10 15  5 21
        }
        $c create polygon $pts -tag knight -offset 8 \
            -fill black -activefill "#600000"
	set scaleFactor [expr {$tk::scalingPct / 100.0}]
	$c scale knight 0 0 $scaleFactor $scaleFactor
    }
    $c moveto knight {*}[lrange [$c coords [expr {1 + int(rand() * 64)}]] 0 1]
    $c bind knight <Button-1> [namespace code [list DragStart %W %x %y]]
    $c bind knight <Motion> [namespace code [list DragMotion %W %x %y]]
    $c bind knight <ButtonRelease-1> [namespace code [list DragEnd %W %x %y]]

    grid $c $f.txt $f.vs  -sticky news
    grid rowconfigure    $f 0 -weight 1
    grid columnconfigure $f 1 -weight 1

    grid $f - - - - - -sticky news
    set things [list $dlg.tf.cc $dlg.tf.sc $dlg.tf.ls $dlg.tf.b1]
    if {![info exists ::widgetDemo]} {
	lappend things $dlg.tf.b2
	if {[tk windowingsystem] ne "aqua"} {
	    set things [linsert $things 0 [ttk::sizegrip $dlg.tf.sg]]
	}
    }
    pack {*}$things -side right -padx 3p
    if {[tk windowingsystem] eq "aqua"} {
	pack configure {*}$things -padx {4 4} -pady {12 12}
	pack configure [lindex $things 0] -padx {4 24}
	pack configure [lindex $things end] -padx {16 4}
    }
    grid $dlg.tf  - - - - - -sticky ew
    if {[info exists ::widgetDemo]} {

Changes to library/demos/label.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
# label.tcl --
#
# This demonstration script creates a toplevel window containing
# several label widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .label
catch {destroy $w}
toplevel $w
wm title $w "Label Demonstration"
wm iconname $w "label"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "Five labels are displayed below: three textual ones on the left, and an image label and a text label on the right.  Labels are pretty boring because you can't do anything with them."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.left
frame $w.right
pack $w.left $w.right -side left -expand yes -padx 10 -pady 10 -fill both

label $w.left.l1 -text "First label"
label $w.left.l2 -text "Second label, raised" -relief raised
label $w.left.l3 -text "Third label, sunken" -relief sunken
pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -pady 2 -anchor w

# Main widget program sets variable tk_demoDirectory
image create photo label.ousterhout \
    -file [file join $tk_demoDirectory images ouster.png]







label $w.right.picture -borderwidth 2 -relief sunken -image label.ousterhout
label $w.right.caption -text "Tcl/Tk Creator"
pack $w.right.picture $w.right.caption -side top









|

















|




|




>
>
>
>
>
>
>
|


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# label.tcl --
#
# This demonstration script creates a toplevel window containing
# several label widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .label
catch {destroy $w}
toplevel $w
wm title $w "Label Demonstration"
wm iconname $w "label"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "Five labels are displayed below: three textual ones on the left, and an image label and a text label on the right.  Labels are pretty boring because you can't do anything with them."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.left
frame $w.right
pack $w.left $w.right -side left -expand yes -padx 7.5p -pady 7.5p -fill both

label $w.left.l1 -text "First label"
label $w.left.l2 -text "Second label, raised" -relief raised
label $w.left.l3 -text "Third label, sunken" -relief sunken
pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -pady 1.5p -anchor w

# Main widget program sets variable tk_demoDirectory
image create photo label.ousterhout \
    -file [file join $tk_demoDirectory images ouster.png]

# Create a copy of the image just created, magnified according to the
# display's DPI scaling level.  Since the zooom factor must be an integer,
# the copy will only be effectively magnified if $tk::scalingPct >= 200.
image create photo label.ousterhout2
label.ousterhout2 copy label.ousterhout -zoom [expr {$tk::scalingPct / 100}]

label $w.right.picture -borderwidth 2 -relief sunken -image label.ousterhout2
label $w.right.caption -text "Tcl/Tk Creator"
pack $w.right.picture $w.right.caption -side top

Changes to library/demos/labelframe.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# labelframe.tcl --
#
# This demonstration script creates a toplevel window containing
# several labelframe widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .labelframe
catch {destroy $w}
toplevel $w
wm title $w "Labelframe Demonstration"
wm iconname $w "labelframe"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# labelframe.tcl --
#
# This demonstration script creates a toplevel window containing
# several labelframe widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .labelframe
catch {destroy $w}
toplevel $w
wm title $w "Labelframe Demonstration"
wm iconname $w "labelframe"
positionWindow $w
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

frame $w.f
pack $w.f -side bottom -fill both -expand 1
set w $w.f

# A group of radiobuttons in a labelframe

labelframe $w.f -text "Value" -padx 2 -pady 2
grid $w.f -row 0 -column 0 -pady 2m -padx 2m

foreach value {1 2 3 4} {
    radiobutton $w.f.b$value -text "This is value $value" \
            -variable lfdummy -value $value
    pack $w.f.b$value -side top -fill x -pady 2
}


# Using a label window to control a group of options.

proc lfEnableButtons {w} {
    foreach child [winfo children $w] {
        if {$child == "$w.cb"} continue
        if {$::lfdummy2} {
            $child configure -state normal
        } else {
            $child configure -state disabled
        }
    }
}

labelframe $w.f2 -pady 2 -padx 2
checkbutton $w.f2.cb -text "Use this option." -variable lfdummy2 \
        -command "lfEnableButtons $w.f2" -padx 0
$w.f2 configure -labelwidget $w.f2.cb
grid $w.f2 -row 0 -column 1 -pady 2m -padx 2m

set t 0
foreach str {Option1 Option2 Option3} {
    checkbutton $w.f2.b$t -text $str
    pack $w.f2.b$t -side top -fill x -pady 2
    incr t
}
lfEnableButtons $w.f2


grid columnconfigure $w {0 1} -weight 1







|





|
















|








|






31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

frame $w.f
pack $w.f -side bottom -fill both -expand 1
set w $w.f

# A group of radiobuttons in a labelframe

labelframe $w.f -text "Value" -padx 1.5p -pady 1.5p
grid $w.f -row 0 -column 0 -pady 2m -padx 2m

foreach value {1 2 3 4} {
    radiobutton $w.f.b$value -text "This is value $value" \
            -variable lfdummy -value $value
    pack $w.f.b$value -side top -fill x -pady 1.5p
}


# Using a label window to control a group of options.

proc lfEnableButtons {w} {
    foreach child [winfo children $w] {
        if {$child == "$w.cb"} continue
        if {$::lfdummy2} {
            $child configure -state normal
        } else {
            $child configure -state disabled
        }
    }
}

labelframe $w.f2 -pady 1.5p -padx 1.5p
checkbutton $w.f2.cb -text "Use this option." -variable lfdummy2 \
        -command "lfEnableButtons $w.f2" -padx 0
$w.f2 configure -labelwidget $w.f2.cb
grid $w.f2 -row 0 -column 1 -pady 2m -padx 2m

set t 0
foreach str {Option1 Option2 Option3} {
    checkbutton $w.f2.b$t -text $str
    pack $w.f2.b$t -side top -fill x -pady 1.5p
    incr t
}
lfEnableButtons $w.f2


grid columnconfigure $w {0 1} -weight 1

Added library/demos/mac_styles.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
# mac_styles.tcl --
#
# This demonstration script creates a toplevel window containing a notebook
# whose pages provide examples of the various mac-specific widgets that are
# provided via special values for the -style option.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

set w .mac_styles
catch {destroy $w}
toplevel $w
package require tk
wm title $w "Tk Aqua Widgets"
wm iconname $w "mac_styles"
positionWindow $w
##
# System images we use in our buttons

set featherImg [file join $tk_demoDirectory images Tk_feather.png]
set starryImg [file join $tk_demoDirectory images starry_night.png]
set fieldImg [file join $tk_demoDirectory images plowed_field.png]
image create nsimage action -source NSAction -width 48 -height 48
image create nsimage bonjour -source NSBonjour -width 48 -height 48
image create nsimage bonjour1 -source NSBonjour -width 48 -height 48 -pressed 1
image create nsimage tkfeather -source $featherImg -as file -width 48 -height 48
image create nsimage tkfeather1 -source $featherImg -as file -width 48 -height 48 -pressed 1
image create nsimage starry -source $starryImg -as file -width 96 -radius 10
image create nsimage starry1 -source $starryImg -as file -width 96 -radius 10 -pressed 1
image create nsimage starry2 -source $starryImg -as file -width 96 -radius 10 -ring 3
image create nsimage field -source $fieldImg -as file -width 96 -radius 10
image create nsimage field1 -source $fieldImg -as file -width 96 -radius 10 -pressed 1
image create nsimage field2 -source $fieldImg -as file -width 96 -radius 10 -ring 3
image create nsimage add -source NSAddTemplate -width 20 -height 20
image create nsimage remove -source NSRemoveTemplate -width 18 -height 4

# Off state and variables for checkbuttons and radio buttons
set off {!selected !alternate}
variable $w.checkVar
variable $w.radioVar
variable $w.triangleVar
variable $w.popupVar
variable $w.stepVar
variable $w.comboVar

# Make a disclosure triangle change state when clicked.
proc toggleTriangle {tri} {
    $tri instate {user1} {
	$tri state {!user1}
	return
    }
    $tri instate {!user1} {
	$tri state {user1}
    }
}

proc popupButton {win varName firstValue args} {
    upvar #0 $varName var
    if {![info exists var]} {
	set var $firstValue
    }
    ttk::menubutton $win -textvariable $varName -menu $win.menu -direction flush
    menu $win.menu -tearoff 0
    $win.menu add radiobutton -label $firstValue -variable $varName
    foreach i $args {
	$win.menu add radiobutton -label $i -variable $varName
    }
    return $win.menu
}

set mag [encoding convertfrom utf-8 "\xf0\x9f\x94\x8d"]

proc searchFocusOut {e} {
    global mag
    if {[$e get] eq ""} {
	$e configure -foreground gray60
	$e insert 0 "Search"
    }
}

proc searchFocusIn {e} {
    if {[$e cget -foreground] == {gray60}} {
	$e delete 0 end
	$e configure -foreground black
    }
}

## Make the notebook and set up Ctrl+Tab traversal
ttk::notebook $w.notebook
ttk::notebook::enableTraversal $w.notebook

# Frames pane
set framesFrame [ttk::frame $w.notebook.frames -padding {40 35 40 50}]
$w.notebook add $framesFrame -text "Frames"
pack [ttk::labelframe $framesFrame.darker -text Darker -padding {50 30 50 50}] \
    -fill both -expand 1
pack [ttk::label $framesFrame.darker.label -padding {0 0 0 6} \
	  -text "This Group Box is nested to depth 2"] \
    -fill x
pack [ttk::labelframe $framesFrame.darker.darker -text "Darker Still" -padding 24] \
    -fill both -expand 1
pack [ttk::label $framesFrame.darker.darker.label \
	  -text "This Group Box is nested to depth 3"] -fill x
pack [button $framesFrame.darker.darker.tkbutton -text "Tk Button" -width 7 \
	  -highlightbackground systemWindowBackgroundColor3] -pady 10
pack [ttk::button $framesFrame.darker.darker.ttkbutton -text "Ttk Button" \
	  -width 7 -padding {-4 0 -4 0}] \
	  -pady 3
# Button pane
set buttonFrame [ttk::frame $w.notebook.buttons -padding {100 20 0 20}]
$w.notebook add $buttonFrame -text "Buttons"
grid columnconfigure $buttonFrame 0 -minsize 100
grid columnconfigure $buttonFrame 1 -minsize 100

set plain [ttk::button $buttonFrame.plain -text Button -padding {-12 0}]
popupButton $buttonFrame.options .popupVar "Item 1" "Item 2" "Item 3"
set options $buttonFrame.options
set check [ttk::checkbutton $buttonFrame.check -text Check -variable .checkVar]
set radio [ttk::frame $buttonFrame.radio]
pack [ttk::radiobutton $radio.r1 -text "Radio 1" -variable .radioVar -value 1] -pady 4
pack [ttk::radiobutton $radio.r2 -text "Radio 2" -variable .radioVar -value 2] -pady 4
set triangle [ttk::checkbutton $buttonFrame.triangle -style Item -variable TriangleVar]
bind $triangle <Button-1> {toggleTriangle %W}
set bonjour [ttk::button $buttonFrame.bonjour -style ImageButton -text Bonjour \
 		     -image {bonjour pressed bonjour1}]
set feather [ttk::button $buttonFrame.feather -style ImageButton -text Tk \
		      -image {tkfeather pressed tkfeather1}]
set gradient [ttk::frame $buttonFrame.gradient]
pack [ttk::button $buttonFrame.gradient.add -style GradientButton \
	  -image add -padding {2 0}] -side left
pack [ttk::button $buttonFrame.gradient.remove -style GradientButton \
	  -image remove -padding {2 8}] -side left
set disclosure [ttk::checkbutton $buttonFrame.disclosure -style DisclosureButton]
set help [ttk::button $buttonFrame.help -style HelpButton];

$check state $off
$radio.r1 state $off
$radio.r2 state $off

grid [ttk::label $buttonFrame.plainLabel -text "Push Button:"]\
    -row 0 -column 0 -padx 4 -sticky e
grid $plain -pady 4 -row 0 -column 1 -sticky w
grid [ttk::label $buttonFrame.optionsLabel -text "Pop-up Button:"]\
    -row 1 -column 0 -padx 4 -sticky e
grid $options  -pady 4 -row 1 -column 1 -sticky w
grid [ttk::label $buttonFrame.checkLabel -text "Check Button:"]\
    -row 2 -column 0 -padx 4 -sticky e
grid $check    -pady 4 -row 2 -column 1 -sticky w
grid [ttk::label $buttonFrame.radioLabel -text "Radio Buttons:"]\
    -row 3 -column 0 -padx 4 -sticky e
grid $radio    -pady 4 -row 3 -column 1 -sticky w
grid [ttk::label $buttonFrame.triangleLabel -text "Disclosure Triangle:"]\
    -row 4 -column 0 -padx 4 -sticky e
grid $triangle -pady 4 -row 4 -column 1 -sticky w
grid [ttk::label $buttonFrame.disclosureLabel -text "Disclosure Button:"]\
    -row 5 -column 0 -padx 4 -sticky e
grid $disclosure -row 5 -column 1 -sticky w
grid [ttk::label $buttonFrame.imageLabel -text "Image Buttons:"]\
    -row 7 -column 0 -padx 4 -sticky e
grid $bonjour -pady 4 -row 6 -rowspan 4 -column 1 -sticky w
grid $feather -padx 10 -pady 4 -row 6 -rowspan 4 -column 2
grid [ttk::label $buttonFrame.gradentLabel -text "Gradient Buttons:"]\
-row 10 -column 0 -padx 4 -sticky e
grid $gradient -pady 4 -row 10 -column 1 -sticky w
grid [ttk::label $buttonFrame.helpLabel -text "Help Button:"]\
-row 11 -column 0 -padx 4 -sticky e
grid $help -row 11 -column 1 -sticky w

#ttk::button .f.b1 -style Toolbutton -image action
#pack $buttonFrame

# Entries Frame
set entryFrame [ttk::frame $w.notebook.entries -padding {0 30 80 0}]
grid columnconfigure $entryFrame 0 -minsize 200
$w.notebook add $entryFrame -text "Entries"

set textfield [ttk::entry $entryFrame.text -width 17]
set searchfield [ttk::entry $entryFrame.search -width 1]
set combo [ttk::combobox $entryFrame.combo -width 1 -textvariable comboVar \
	   -values {"Item 1" "Item 2" "Item 3"}]
set stepper [ttk::spinbox $entryFrame.stepper -width 1 -textvariable stepVar \
		 -from 99000 -to 101000 -increment 1]
set stepVar 100000
searchFocusOut $searchfield
bind $searchfield <FocusIn> {searchFocusIn %W}
bind $searchfield <FocusOut> {searchFocusOut %W}

grid [ttk::label $entryFrame.l0 -text "Text Field"] -row 0 -column 0 -padx 20 -sticky e
grid $textfield -sticky ew -row 0 -column 1 -pady 13
grid [ttk::label $entryFrame.l1 -text "Search Field"] -row 1 -column 0 -padx 20 -sticky e
grid $searchfield -sticky ew -row 1 -column 1 -pady 13
grid [ttk::label $entryFrame.l2 -text "Combo Box"] -row 2 -column 0 -padx 20 -sticky e
grid $combo -sticky ew -row 2 -column 1 -pady 13
grid [ttk::label $entryFrame.l3 -text "Stepper"] -row 3 -column 0 -padx 20 -sticky e
grid $stepper -sticky ew -row 3 -column 1 -pady 13

#Scales Frame
set scaleFrame [ttk::frame $w.notebook.scales -padding {0 40 0 80}]
$w.notebook add $scaleFrame -text "Scales"

variable topVar 50
set topSlider [ttk::scale $scaleFrame.topSlider -from 0 -to 100 \
		   -length 280 -variable topVar]
set topProgress [ttk::progressbar $scaleFrame.topProgress \
		     -maximum 100 -variable topVar]

variable bottomVar 50
set bottomSlider [ttk::scale $scaleFrame.bottomSlider -from 0 -to 100 \
		      -length 280 -variable bottomVar]
$bottomSlider state alternate
set bottomProgress [ttk::progressbar $scaleFrame.bottomProgress \
		    -maximum 100 -variable bottomVar]


grid $topSlider -padx 80 -pady 12 -sticky ew -row 0 -column 0 -columnspan 2
grid $topProgress -padx 120 -pady 15 -sticky ew -row 1 -column 0 -columnspan 2
grid [ttk::frame $scaleFrame.spacer] -row 2 -column 0 -columnspan 2 -pady 32

grid $bottomSlider -padx 80 -sticky new -row 3 -column 0 -columnspan 2
grid [ttk::label $scaleFrame.low -text Low -padding {70 0 0 0}] \
    -row 4 -column 0 -sticky sw
grid [ttk::label $scaleFrame.high -text High -padding {0 0 70 0}] \
    -row 4 -column 1 -sticky se
grid $bottomProgress -padx 120 -pady 15 -sticky ew -row 5 -column 0 -columnspan 2

#Appearance Frame
set appearanceFrame [ttk::frame $w.notebook.appearance -padding {0 40 0 80}]
grid [ttk::label $w.notebook.appearance.info -justify left -padding {0 20 0 40}\
	  -text "Use the image buttons below to view this demo in light or dark mode."] \
    -row 0 -column 0 -columnspan 3
set light [ttk::button $appearanceFrame.light -style ImageButton -text Light \
	       -image {field pressed field1 selected field2} \
	       -command "beLight $appearanceFrame $w"]
grid columnconfigure $appearanceFrame 1 -minsize 10
grid $light -row 1 -column 0 -sticky e
set dark [ttk::button $appearanceFrame.dark -style ImageButton -text Dark \
	      -image {starry pressed starry1 selected starry2} \
	      -command "beDark $appearanceFrame $w"]
grid $dark -row 1 -column 2 -sticky w
if { [wm attributes $w -isdark] } {
    $dark state selected
} else {
    $light state selected
}
proc beLight {f w} {
    wm attributes $w -appearance aqua
    $f.dark state !selected
    $f.light state selected
    after 10 $f.light state !hover
}

proc beDark {f w} {
    wm attributes $w -appearance darkaqua
    $f.light state !selected
    $f.dark state selected
    after 10 $f.dark state !hover
}
$w.notebook add $appearanceFrame -text "Appearance"

## See Code / Dismiss
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x

## Notebook
pack $w.notebook -side bottom -fill both -expand 1 -padx 16 -pady 16

Added library/demos/mac_tabs.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
# mac_tabs.tcl --
#
# This demonstration script creates three tabbable windows and allows the
# wm attributes tabbingid and tabbingmode to be manipulated for the third
# window, to demonstrate the effects of those attributes.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk
catch {font create giant -family {Times New Roman} -size 64}
set w .mac_tabs
catch {destroy $w}
toplevel $w
wm title $w "Tabbed Windows in Aqua"
wm iconname $w "mac_tabs"
positionWindow $w
set suffix 0
set winlist {}
##

## See Code / Dismiss
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x
##
set info "\
This demo shows 3 toplevels, A, B, and C.  \
Each of these has tabbingmode set to preferred. \
The tabbingid of Window A is groupA, the \
tabbingid of Window B is groupB and the tabbingid \
of Window C is groupC.  Use the menubuttons below \
to see the effect of changing the tabbingid and \
tabbingmode attributes for Window C. \
"
pack [message $w.info -text $info -width 300]
wm geometry $w +450+350

ttk::frame $w.f
menu $w.idmenu -tearoff 0
foreach id {groupA groupB groupC} {
    $w.idmenu add command -label $id \
	-command [list wm attributes $w.c -tabbingid $id]
}
menu $w.modemenu -tearoff 0
foreach mode {auto preferred disallowed} {
    $w.modemenu add command -label $mode \
	-command [list wm attributes $w.c -tabbingmode $mode]
}
ttk::menubutton $w.f.idbutton -menu $w.idmenu -text "tabbingid"\
    -direction below
grid $w.f.idbutton -row 0 -column 0
ttk::menubutton $w.f.modebutton -menu $w.modemenu -text "tabbingmode"\
    -direction below
grid $w.f.modebutton -row 1 -column 0
pack $w.f

wm attributes $w.a -tabbingid groupA
wm attributes $w.a -tabbingmode preferred
toplevel $w.a
wm geometry $w.a +50+100
wm title $w.a "Window A"
pack [ttk::label $w.a.l -text A -font giant] -padx 100 -pady 30

wm attributes $w.b -tabbingid groupB
wm attributes $w.b -tabbingmode preferred
toplevel $w.b
wm geometry $w.b +400+100
wm title $w.b "Window B"
pack [ttk::label $w.b.l -text B -font giant] -padx 100 -pady 30

wm attributes $w.c -tabbingid groupC
wm attributes $w.c -tabbingmode preferred
toplevel $w.c
wm geometry $w.c +750+100
wm title $w.c "Window C"
pack [ttk::label $w.c.l -text C -font giant] -padx 100 -pady 30

Added library/demos/mac_wm.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
# mac_window_styles.tcl --
#
# This demonstration script creates a toplevel window containing a notebook
# whose pages provide examples of the various mac-specific widgets that are
# provided via special values for the -style option.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .mac_wm
catch {destroy $w}
toplevel $w
wm title $w "Tk Aqua Window Styles"
wm iconname $w "mac_wm"
positionWindow $w
set suffix 0
set winlist {}
##

## See Code / Dismiss
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x

proc launch {name windowInfo class} {
    if {[winfo exists $name]} {
	wm deiconify $name
	focus -force $name
	return
    }
    wm attributes $name -class $class; toplevel $name
    wm title $name $class
    set f $name.f
    ttk::frame $f
    set t $f.t
    text $t -background systemWindowBackgroundColor \
	-highlightcolor systemWindowBackgroundColor \
	-font systemDefaultFont\
	-wrap word -width 50 -height 6
    $t insert insert $windowInfo
    $t configure -state disabled
    grid columnconfigure $f 0 -weight 1
    grid $t -row 0 -column 0 -columnspan 2 -sticky NSEW
    ttk::labelframe $f.stylemask -text "styleMask bits"
    # titled
    if {$class == "nswindow"} {
       ttk::checkbutton $f.stylemask.titled -text titled -variable $name.titled \
          -command [list setbit $name $f.stylemask.titled titled]
       $f.stylemask.titled state selected
       grid $f.stylemask.titled -row 0 -column 0 -sticky w
    }
    # closable
    ttk::checkbutton $f.stylemask.closable -text closable -variable $name.closable \
        -command [list setbit $name $f.stylemask.closable closable]
    $f.stylemask.closable state selected
    grid $f.stylemask.closable -row 1 -column 0 -sticky w
    # miniaturizableable
    ttk::checkbutton $f.stylemask.miniaturizable -text miniaturizable \
	-variable $name.miniaturizable \
        -command [list setbit $name $f.stylemask.miniaturizable miniaturizable]
    if {$class == "nswindow"} {
        $f.stylemask.miniaturizable state selected
    } else {
        $f.stylemask.miniaturizable state !alternate
    }
    grid $f.stylemask.miniaturizable -row 2 -column 0 -sticky w
    # resizable
    ttk::checkbutton $f.stylemask.resizable -text resizable -variable $name.resizable \
	-command [list setbit $name $f.stylemask.resizable resizable]
    $f.stylemask.resizable state selected
    grid $f.stylemask.resizable -row 3 -column 0 -sticky w
    # docmodal
    ttk::checkbutton $f.stylemask.docmodal -text docmodal -variable $name.docmodal \
	-command [list setbit $name $f.stylemask.docmodal docmodal]
    $f.stylemask.docmodal state !alternate
    grid $f.stylemask.docmodal -row 4 -column 0 -sticky w

    grid $f.stylemask -row 1 -column 0
    pack $name.f -side bottom -fill both -expand 1 -padx 16 -pady 16
}

set info "The command wm attributes window -stylemask ?bitnames? can \
be used to modify bits in the stylemask property of the NSWindow or \
NSPanel underlying a Tk Window.  Changing these bits causes the \
style of the window to change.  This demo allows you to see the \
effects of changing the bits.  (Note that buttons in the title bar \
can also be enabled or disabled with the ::tk::unsupported::MacWindowStyle \
command.)"

set panelInfo "A toplevel based on an NSPanel has a narrower title bar\
than one based on an NSWindow.  In addition the panel remains above all\
windows on the screen, regardless of which app is active. These are\
intended to be used as modal windows."

set windowInfo "This is a standard Apple document window, based on an\
NSWindow.  It has a larger title bar and behaves normally with respect\
to other windows from the same or another app."

## background frame
set f $w.f
ttk::frame $f
set t $f.t
text $t -background systemWindowBackgroundColor \
    -highlightcolor systemWindowBackgroundColor \
    -font systemDefaultFont\
    -wrap word -width 50 -height 8
$t insert insert $info
$t configure -state disabled
grid columnconfigure $f 0 -weight 1
grid $t -row 0 -column 0 -columnspan 2 -sticky NSEW
ttk::labelframe $f.stylemask -text "styleMask"
grid $f.stylemask -row 1 -column 0
grid [ttk::button $f.wbw -text "Open an NSWindow" -width 20 \
	  -command [list launch .nswindow $windowInfo nswindow]] -row 2 -column 0
grid [ttk::button $f.wbp -text "Open an NSPanel" -width 20 \
	  -command [list launch .nspanel $panelInfo nspanel]] -row 3 -column 0
grid [ttk::button $f.wbm -text "Open a modern window" -width 20 \
	  -command launchModernWindow] -row 4 -column 0
pack $w.f -side bottom -fill both -expand 1 -padx 16 -pady 16

proc setbit {win cb bitname} {
    set state [$cb instate selected]
    set bits [wm attributes $win -stylemask]
    set index [lsearch $bits $bitname]
    if {$index >= 0 && !$state} {
        set bits [lreplace $bits $index $index]
    }
    if {$index < 0 && $state} {
        lappend bits $bitname
    }
    wm attributes $win -stylemask $bits
}

set aboutText \
"Most of the apps which ship with a contemporary version of macOS \
feature a window similar to this one, with a left sidebar that \
allows selecting the content to be shown on the right hand side of \
the window.  These windows do not have a (visible) titlebar.\
\n\nApps that use such windows include the Finder and the App Store as \
well as Notes, Messages, Books, Maps and many others.\
\n\nTo create a window like this one in Tk simply set the fullsizecontent bit \
in the stylemask. For example:\n\n"

set aboutCode \
"wm attributes .t -stylemask {titled \\\
\nfullsizecontent closable miniaturizable \\\
\nresizable}\n\n"

set detailsText \
"(1) In the Apple API, setting the fullsizecontent bit in the stylemask \
only allows content to be drawn in the part of the window covered by \
the titlebar.  In order for that content to be visible the title bar \
must be transparent.  Since it would be pointless to draw content under \
an opaque title bar, Tk makes the title bar transparent whenever the \
fullsizecontent bit is set.\

\n\n\(2) Each radio button in the sidebar is a standard ttk::radiobutton \
but created with a special value for its -style option.  The value of the \
-style option used to create these buttons is SidebarButton.\n"

set whichPage 1
trace add variable whichPage write "flipPage whichPage"
proc flipPage {varname args} {
    global whichPage
    set newpage [set $varname]
    grid remove [grid content .mod.right -row 0 -column 0]
    switch $newpage\
	1 {grid .mod.right.about -padx 30 -pady 30 -row 0 -column 0 -sticky nsew}\
	2 {grid .mod.right.details -padx 30 -pady 30 -row 0 -column 0 -sticky nsew}
    update idletasks
}

proc launchModernWindow {} {
    global whichPage
    global aboutText
    global aboutCode
    global detailsText
    if {[winfo exists .mod]} {
	wm deiconify .mod
	focus -force .mod
	return
    }
    toplevel .mod
    wm title .mod {}
    wm attributes .mod -stylemask {titled fullsizecontent closable \
				       miniaturizable resizable}
    .mod configure -background white
    grid columnconfigure .mod 0 -weight 0
    grid columnconfigure .mod 1 -weight 1
    grid rowconfigure .mod 0 -weight 1
    frame .mod.left -width 220 -height 400 -background systemWindowBackgroundColor
    catch {
	font create leftFont -family .AppleSystemUIFont -size 11
        font create rightFont -family .AppleSystemUIFont -size 16
        font create codeFont -family Courier -size 16
    }
    grid [ttk::label .mod.left.spacer -padding {220 30 0 0}] -row 0 -column 0
    grid [ttk::radiobutton .mod.left.about -text About -style SidebarButton \
	      -variable whichPage -value 1] \
	-row 1 -column 0 -sticky nsew -padx 14
    grid [ttk::radiobutton .mod.left.details -text Details -style SidebarButton \
	-variable whichPage -value 2] \
	-row 2 -column 0 -sticky nsew -padx 14
    grid .mod.left -row 0 -column 0 -sticky nsew
    frame .mod.right -width 500 -background systemTextBackgroundColor
    grid rowconfigure .mod.right 0 -weight 0
    text .mod.right.about -highlightcolor systemTextBackgroundColor \
	-background systemTextBackgroundColor -font rightFont \
	-highlightthickness 0 -wrap word -width 40
    .mod.right.about tag configure code -font codeFont
    .mod.right.about insert end $aboutText
    .mod.right.about insert end $aboutCode code
    .mod.right.about configure -state disabled

    text .mod.right.details -highlightcolor systemTextBackgroundColor \
	-background systemTextBackgroundColor -font rightFont\
	-highlightthickness 0 -wrap word -width 40
    .mod.right.details insert end $detailsText
    .mod.right.details configure -state disabled

    grid .mod.right.about -padx 30 -pady 30 -row 0 -column 0 -sticky nsew
    grid .mod.right -row 0 -column 1 -sticky nsew
    wm geometry .mod 800x500
    update idletasks
}

Changes to library/demos/mclist.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
33
34
35
36






37






38





39






40


41





42
43




44
45
46
47
48
49
50
# mclist.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget configured as a multi-column listbox.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .mclist
catch {destroy $w}
toplevel $w
wm title $w "Multi-Column List"
wm iconname $w "mclist"
positionWindow $w

## Explanatory text
ttk::label $w.msg -font $font -wraplength 4i -justify left -anchor n -padding {10 2 10 6} -text "Ttk is the new Tk themed widget set. One of the widgets it includes is a tree widget, which can be configured to display multiple columns of informational data without displaying the tree itself. This is a simple way to build a listbox that has multiple columns. Clicking on the heading for a column will sort the data by that column. You can also change the width of the columns by dragging the boundary between them."
pack $w.msg -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w] -side bottom -fill x




ttk::frame $w.container
ttk::treeview $w.tree -columns {country capital currency} -show headings \
    -yscroll "$w.vsb set" -xscroll "$w.hsb set"
ttk::scrollbar $w.vsb -orient vertical -command "$w.tree yview"
ttk::scrollbar $w.hsb -orient horizontal -command "$w.tree xview"
pack $w.container -fill both -expand 1
grid $w.tree $w.vsb -in $w.container -sticky nsew
grid $w.hsb         -in $w.container -sticky nsew
grid column $w.container 0 -weight 1
grid row    $w.container 0 -weight 1







image create photo upArrow -data {






    R0lGODlhDgAOAJEAANnZ2YCAgPz8/P///yH5BAEAAAAALAAAAAAOAA4AAAImhI+





    py+1LIsJHiBAh+BgmiEAJQITgW6DgUQIAECH4JN8IPqYuNxUAOw==}






image create photo downArrow -data {


    R0lGODlhDgAOAJEAANnZ2YCAgPz8/P///yH5BAEAAAAALAAAAAAOAA4AAAInhI+





    py+1I4ocQ/IgDEYIPgYJICUCE4F+YIBolEoKPEJKZmVJK6ZACADs=}
image create photo noArrow -height 14 -width 14





## The data we're going to insert
set data {
    Argentina		{Buenos Aires}		ARS
    Australia		Canberra		AUD
    Brazil		Brazilia		BRL
    Canada		Ottawa			CAD









|



|









|
>
>
>












>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
|
|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# mclist.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget configured as a multi-column listbox.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .mclist
catch {destroy $w}
toplevel $w -class MCList
wm title $w "Multi-Column List"
wm iconname $w "mclist"
positionWindow $w

## Explanatory text
ttk::label $w.msg -font $font -wraplength 4i -justify left -anchor n -padding {10 2 10 6} -text "Ttk is the new Tk themed widget set. One of the widgets it includes is a tree widget, which can be configured to display multiple columns of informational data without displaying the tree itself. This is a simple way to build a listbox that has multiple columns. Clicking on the heading for a column will sort the data by that column. You can also change the width of the columns by dragging the boundary between them."
pack $w.msg -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w {} {
    ttk::checkbutton $w.seeDismiss.cb1 -text Grid -variable mclistGrid -command tglGrid
}] -side bottom -fill x


ttk::frame $w.container
ttk::treeview $w.tree -columns {country capital currency} -show headings \
    -yscroll "$w.vsb set" -xscroll "$w.hsb set"
ttk::scrollbar $w.vsb -orient vertical -command "$w.tree yview"
ttk::scrollbar $w.hsb -orient horizontal -command "$w.tree xview"
pack $w.container -fill both -expand 1
grid $w.tree $w.vsb -in $w.container -sticky nsew
grid $w.hsb         -in $w.container -sticky nsew
grid column $w.container 0 -weight 1
grid row    $w.container 0 -weight 1

set upArrowData {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="4" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="m4 4 4-4 4 4z" fill="#000000"/>
    </svg>
}

set downArrowData {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="4" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="m4 0 4 4 4-4z" fill="#000000"/>
    </svg>
}

proc createArrowImages {} {
    set fgColor [ttk::style lookup . -foreground {} black]
    lassign [winfo rgb . $fgColor] r g b
    set fgColor [format "#%02x%02x%02x" \
	    [expr {$r >> 8}] [expr {$g >> 8}] [expr {$b >> 8}]]

    foreach dir {up down} {
	upvar ${dir}ArrowData imgData
	set idx1 [string first "#000000" $imgData]
	set idx2 [expr {$idx1 + 6}]
	set data [string replace $imgData $idx1 $idx2 $fgColor]

	image create photo ${dir}Arrow -format $::tk::svgFmt -data $data]
    }
}

createArrowImages
foreach event {<<ThemeChanged>> <<LightAqua>> <<DarkAqua>>} {
    bind MCList $event { createArrowImages }
}
unset event

image create photo noArrow -format $tk::svgFmt -data {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="4" version="1.1" xmlns="http://www.w3.org/2000/svg">
    </svg>
}

## The data we're going to insert
set data {
    Argentina		{Buenos Aires}		ARS
    Australia		Canberra		AUD
    Brazil		Brazilia		BRL
    Canada		Ottawa			CAD
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    Russia		Moscow			RUB
    {South Africa}	Pretoria		ZAR
    {United Kingdom}	London			GBP
    {United States}	{Washington, D.C.}	USD
}

## Code to insert the data nicely
set font [ttk::style lookup Heading -font]

foreach col {country capital currency} name {Country Capital Currency} {
    $w.tree heading $col -text $name -image noArrow -anchor w \
	-command [list SortBy $w.tree $col 0]
    $w.tree column $col -width [expr {
	[font measure $font $name] + [image width noArrow] + 5
    }]
}
set font [ttk::style lookup Treeview -font]
foreach {country capital currency} $data {
    $w.tree insert {} end -values [list $country $capital $currency]
    foreach col {country capital currency} {
	set len [font measure $font "[set $col]  "]
	if {[$w.tree column $col -width] < $len} {
	    $w.tree column $col -width $len
	}







|
>



|
<
<

|







95
96
97
98
99
100
101
102
103
104
105
106
107


108
109
110
111
112
113
114
115
116
    Russia		Moscow			RUB
    {South Africa}	Pretoria		ZAR
    {United Kingdom}	London			GBP
    {United States}	{Washington, D.C.}	USD
}

## Code to insert the data nicely
set font [ttk::style lookup Heading -font {} TkDefaultFont]
set morePx [expr {[image width noArrow] + round(4 * $tk::scalingPct / 100.0)}]
foreach col {country capital currency} name {Country Capital Currency} {
    $w.tree heading $col -text $name -image noArrow -anchor w \
	-command [list SortBy $w.tree $col 0]
    $w.tree column $col -width [expr {[font measure $font $name] + $morePx}]


}
set font [ttk::style lookup Treeview -font {} TkDefaultFont]
foreach {country capital currency} $data {
    $w.tree insert {} end -values [list $country $capital $currency]
    foreach col {country capital currency} {
	set len [font measure $font "[set $col]  "]
	if {[$w.tree column $col -width] < $len} {
	    $w.tree column $col -width $len
	}
113
114
115
116
117
118
119















    if {[ttk::style theme use] eq "aqua"} {
	# Aqua theme displays native sort arrows when user1 state is set
	$tree heading $col state "user1"
    } else {
	$tree heading $col -image [expr {$direction?"upArrow":"downArrow"}]
    }
}






















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    if {[ttk::style theme use] eq "aqua"} {
	# Aqua theme displays native sort arrows when user1 state is set
	$tree heading $col state "user1"
    } else {
	$tree heading $col -image [expr {$direction?"upArrow":"downArrow"}]
    }
}

set mclistGrid 0
proc tglGrid {} {
    if {$::mclistGrid} {
        .mclist.tree configure -stripe 1
        foreach col [.mclist.tree cget -columns] {
            .mclist.tree column $col -separator 1
        }
    } else {
        .mclist.tree configure -stripe 0
        foreach col [.mclist.tree cget -columns] {
            .mclist.tree column $col -separator 0
        }
    }
}

Changes to library/demos/menu.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
# menu.tcl --
#
# This demonstration script creates a window with a bunch of menus
# and cascaded menus using menubars.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .menu
catch {destroy $w}
toplevel $w
wm title $w "Menu Demonstration"
wm iconname $w "menu"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left
if {[tk windowingsystem] eq "aqua"} {
    catch {set origUseCustomMDEF $::tk::mac::useCustomMDEF; set ::tk::mac::useCustomMDEF 1}
    $w.msg configure -text "This window has a menubar with cascaded menus.  You can invoke entries with an accelerator by typing Command+x, where \"x\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by selecting the first item in the menu."
} else {
    $w.msg configure -text "This window contains a menubar with cascaded menus.  You can post a menu from the keyboard by typing Alt+x, where \"x\" is the character underlined on the menu.  You can then traverse among the menus using the arrow keys.  When a menu is posted, you can invoke the current entry by typing space, or you can invoke any entry by typing its underlined character.  If a menu entry has an accelerator, you can invoke the entry without posting the menu just by typing the accelerator. The rightmost menu can be torn off into a palette by selecting the first item in the menu."
}
pack $w.msg -side top

set menustatus "    "









|










<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
# menu.tcl --
#
# This demonstration script creates a window with a bunch of menus
# and cascaded menus using menubars.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .menu
catch {destroy $w}
toplevel $w
wm title $w "Menu Demonstration"
wm iconname $w "menu"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left
if {[tk windowingsystem] eq "aqua"} {

    $w.msg configure -text "This window has a menubar with cascaded menus.  You can invoke entries with an accelerator by typing Command+x, where \"x\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by selecting the first item in the menu."
} else {
    $w.msg configure -text "This window contains a menubar with cascaded menus.  You can post a menu from the keyboard by typing Alt+x, where \"x\" is the character underlined on the menu.  You can then traverse among the menus using the arrow keys.  When a menu is posted, you can invoke the current entry by typing space, or you can invoke any entry by typing its underlined character.  If a menu entry has an accelerator, you can invoke the entry without posting the menu just by typing the accelerator. The rightmost menu can be torn off into a palette by selecting the first item in the menu."
}
pack $w.msg -side top

set menustatus "    "
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

set m $w.menu.basic
$w.menu add cascade -label "Basic" -menu $m -underline 0
menu $m -tearoff 0
$m add command -label "Long entry that does nothing"
if {[tk windowingsystem] eq "aqua"} {
    set modifier Command
} elseif {[tk windowingsystem] == "win32"} {
    set modifier Control
} else {
    set modifier Meta
}
foreach i {A B C D E F} {
    $m add command -label "Print letter \"$i\"" -underline 14 \
	    -accelerator Meta+$i -command "puts $i" -accelerator $modifier+$i
    bind $w <$modifier-[string tolower $i]> "puts $i"
}

set m $w.menu.cascade
$w.menu add cascade -label "Cascades" -menu $m -underline 0
menu $m -tearoff 0
$m add command -label "Print hello" \







|






|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

set m $w.menu.basic
$w.menu add cascade -label "Basic" -menu $m -underline 0
menu $m -tearoff 0
$m add command -label "Long entry that does nothing"
if {[tk windowingsystem] eq "aqua"} {
    set modifier Command
} elseif {[tk windowingsystem] eq "win32"} {
    set modifier Control
} else {
    set modifier Meta
}
foreach i {A B C D E F} {
    $m add command -label "Print letter \"$i\"" -underline 14 \
	    -accelerator $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" \
130
131
132
133
134
135
136


137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153



154











155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170

set m $w.menu.more
$w.menu add cascade -label "More" -menu $m -underline 0
menu $m -tearoff 0
foreach i {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Does almost nothing also} {Make life meaningful}} {
    $m add command -label $i -command [list puts "You invoked \"$i\""]
}


$m entryconfigure "Does almost nothing" -bitmap questhead -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a bitmap and a\
		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

$m entryconfigure "Does almost nothing also" -image lilearth -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a image and a\
		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

set m $w.menu.colors
$w.menu add cascade -label "Colors" -menu $m -underline 1
menu $m -tearoff 1



foreach i {red orange yellow green blue} {











    $m add command -label $i -background $i -command [list \
	    puts "You invoked \"$i\"" ]

}

$w configure -menu $w.menu

bind Menu <<MenuSelect>> {
    global $menustatus
    if {[catch {%W entrycget active -label} label]} {
	set label "    "
    }
    set menustatus $label
    update idletasks
}

if {[tk windowingsystem] eq "aqua"} {catch {set ::tk::mac::useCustomMDEF $origUseCustomMDEF}}







>
>

















>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
>












<
<
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184



set m $w.menu.more
$w.menu add cascade -label "More" -menu $m -underline 0
menu $m -tearoff 0
foreach i {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Does almost nothing also} {Make life meaningful}} {
    $m add command -label $i -command [list puts "You invoked \"$i\""]
}
set emojiLabel [encoding convertfrom utf-8 "\xF0\x9F\x98\x8D Make friends"]
$m add command -label $emojiLabel -command [list puts "Menu labels can include non-BMP characters."]
$m entryconfigure "Does almost nothing" -bitmap questhead -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a bitmap and a\
		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

$m entryconfigure "Does almost nothing also" -image lilearth -compound left \
	-command [list \
	tk_dialog $w.compound {Compound Menu Entry} \
		"The menu entry you invoked displays both a image and a\
		text string.  Other than this, it is just like any other\
		menu entry." {} 0 OK ]

set m $w.menu.colors
$w.menu add cascade -label "Colors" -menu $m -underline 1
menu $m -tearoff 1
if {[tk windowingsystem] eq "aqua"} {
    # Aqua ignores the -background and -foreground options, but a compound
    # button can be used for selecting colors.
    foreach i {red orange yellow green blue} {
	image create photo image_$i -height 16 -width 16
	image_$i put black -to 0 0 16 1
	image_$i put black -to 0 1 1 16
	image_$i put black -to 0 15 16 16
	image_$i put black -to 15 1 16 16
	image_$i put $i -to 1 1 15 15
	$m add command -label $i -image image_$i -compound left -command [list \
	puts "You invoked \"$i\"" ]
    }
} else {
    foreach i {red orange yellow green blue} {
	$m add command -label $i -background $i -command [list \
	puts "You invoked \"$i\"" ]
    }
}

$w configure -menu $w.menu

bind Menu <<MenuSelect>> {
    global $menustatus
    if {[catch {%W entrycget active -label} label]} {
	set label "    "
    }
    set menustatus $label
    update idletasks
}


Changes to library/demos/menubu.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
# menubu.tcl --
#
# This demonstration script creates a window with a bunch of menus
# and cascaded menus using menubuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .menubu
catch {destroy $w}
toplevel $w
wm title $w "Menu Button Demonstration"
wm iconname $w "menubutton"
positionWindow $w

frame $w.body
pack $w.body -expand 1 -fill both
if {[tk windowingsystem] eq "aqua"} {catch {set origUseCustomMDEF $::tk::mac::useCustomMDEF; set ::tk::mac::useCustomMDEF 1}}

menubutton $w.body.below -text "Below" -underline 0 -direction below -menu $w.body.below.m -relief raised
menu $w.body.below.m -tearoff 0
$w.body.below.m add command -label "Below menu: first item" -command "puts \"You have selected the first item from the Below menu.\""
$w.body.below.m add command -label "Below menu: second item" -command "puts \"You have selected the second item from the Below menu.\""
grid $w.body.below -row 0 -column 1 -sticky n
menubutton $w.body.right -text "Right" -underline 0 -direction right -menu $w.body.right.m -relief raised









|










<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
# menubu.tcl --
#
# This demonstration script creates a window with a bunch of menus
# and cascaded menus using menubuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .menubu
catch {destroy $w}
toplevel $w
wm title $w "Menu Button Demonstration"
wm iconname $w "menubutton"
positionWindow $w

frame $w.body
pack $w.body -expand 1 -fill both


menubutton $w.body.below -text "Below" -underline 0 -direction below -menu $w.body.below.m -relief raised
menu $w.body.below.m -tearoff 0
$w.body.below.m add command -label "Below menu: first item" -command "puts \"You have selected the first item from the Below menu.\""
$w.body.below.m add command -label "Below menu: second item" -command "puts \"You have selected the second item from the Below menu.\""
grid $w.body.below -row 0 -column 1 -sticky n
menubutton $w.body.right -text "Right" -underline 0 -direction right -menu $w.body.right.m -relief raised
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
grid $w.body.above -row 2 -column 1 -sticky s

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set body $w.body.center
label $body.label -wraplength 300 -font "Helvetica 14" -justify left -text "This is a demonstration of menubuttons. The \"Below\" menubutton pops its menu below the button; the \"Right\" button pops to the right, etc. There are two option menus directly below this text; one is just a standard menu and the other is a 16-color palette."
pack $body.label -side top -padx 25 -pady 25
frame $body.buttons
pack $body.buttons -padx 25 -pady 25
tk_optionMenu $body.buttons.options menubuttonoptions one two three
pack $body.buttons.options -side left -padx 25 -pady 25
set m [tk_optionMenu $body.buttons.colors paletteColor Black red4 DarkGreen NavyBlue gray75 Red Green Blue gray50 Yellow Cyan Magenta White Brown DarkSeaGreen DarkViolet]
if {[tk windowingsystem] eq "aqua"} {
    set topBorderColor Black
    set bottomBorderColor Black
} else {
    set topBorderColor gray50
    set bottomBorderColor gray75
}



for {set i 0} {$i <= [$m index last]} {incr i} {
    set name [$m entrycget $i -label]
    image create photo image_$name -height 16 -width 16
    image_$name put $topBorderColor -to 0 0 16 1
    image_$name put $topBorderColor -to 0 1 1 16
    image_$name put $bottomBorderColor -to 0 15 16 16
    image_$name put $bottomBorderColor -to 15 1 16 16
    image_$name put $name -to 1 1 15 15

    image create photo image_${name}_s -height 16 -width 16
    image_${name}_s put Black -to 0 0 16 2
    image_${name}_s put Black -to 0 2 2 16
    image_${name}_s put Black -to 2 14 16 16
    image_${name}_s put Black -to 14 2 16 14
    image_${name}_s put $name -to 2 2 14 14

    $m entryconfigure $i -image image_$name -selectimage image_${name}_s -hidemargin 1
}
$m configure -tearoff 1
foreach i {Black gray75 gray50 White} {
	$m entryconfigure $i -columnbreak 1
}

pack $body.buttons.colors -side left -padx 25 -pady 25

if {[tk windowingsystem] eq "aqua"} {catch {set ::tk::mac::useCustomMDEF $origUseCustomMDEF}}







|
|

|

|








>
>
>


|
|
|
|
|
|

|
|
|
|
|
|








|
<
<
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90


grid $w.body.above -row 2 -column 1 -sticky s

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set body $w.body.center
label $body.label -wraplength 225p -font "Helvetica 14" -justify left -text "This is a demonstration of menubuttons. The \"Below\" menubutton pops its menu below the button; the \"Right\" button pops to the right, etc. There are two option menus directly below this text; one is just a standard menu and the other is a 16-color palette."
pack $body.label -side top -padx 18p -pady 18p
frame $body.buttons
pack $body.buttons -padx 18p -pady 18p
tk_optionMenu $body.buttons.options menubuttonoptions one two three
pack $body.buttons.options -side left -padx 18p -pady 18p
set m [tk_optionMenu $body.buttons.colors paletteColor Black red4 DarkGreen NavyBlue gray75 Red Green Blue gray50 Yellow Cyan Magenta White Brown DarkSeaGreen DarkViolet]
if {[tk windowingsystem] eq "aqua"} {
    set topBorderColor Black
    set bottomBorderColor Black
} else {
    set topBorderColor gray50
    set bottomBorderColor gray75
}
set dim  [expr {round(16 * $tk::scalingPct / 100.0)}]
set dim1 [expr {$dim - 1}]
set dim2 [expr {$dim - 2}]
for {set i 0} {$i <= [$m index last]} {incr i} {
    set name [$m entrycget $i -label]
    image create photo image_$name -height $dim -width $dim
    image_$name put $topBorderColor -to 0 0 $dim 1
    image_$name put $topBorderColor -to 0 1 1 $dim
    image_$name put $bottomBorderColor -to 0 $dim1 $dim $dim
    image_$name put $bottomBorderColor -to $dim1 1 $dim $dim
    image_$name put $name -to 1 1 $dim1 $dim1

    image create photo image_${name}_s -height $dim -width $dim
    image_${name}_s put Black -to 0 0 $dim 2
    image_${name}_s put Black -to 0 2 2 $dim
    image_${name}_s put Black -to 2 $dim2 $dim $dim
    image_${name}_s put Black -to $dim2 2 $dim $dim2
    image_${name}_s put $name -to 2 2 $dim2 $dim2

    $m entryconfigure $i -image image_$name -selectimage image_${name}_s -hidemargin 1
}
$m configure -tearoff 1
foreach i {Black gray75 gray50 White} {
	$m entryconfigure $i -columnbreak 1
}

pack $body.buttons.colors -side left -padx 18p -pady 18p


Changes to library/demos/msgbox.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# msgbox.tcl --
#
# This demonstration script creates message boxes of various type

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .msgbox
catch {destroy $w}
toplevel $w
wm title $w "Message Box Demonstration"
wm iconname $w "messagebox"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# msgbox.tcl --
#
# This demonstration script creates message boxes of various type

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .msgbox
catch {destroy $w}
toplevel $w
wm title $w "Message Box Demonstration"
wm iconname $w "messagebox"
positionWindow $w
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
pack $w.left.label -side top
pack $w.left.sep -side top -fill x -expand no

set msgboxIcon info
foreach i {error info question warning} {
    radiobutton $w.left.b$i -text $i -variable msgboxIcon \
	-relief flat -value $i -width 16 -anchor w
    pack $w.left.b$i  -side top -pady 2 -anchor w -fill x
}

label $w.right.label -text "Type"
frame $w.right.sep -relief ridge -bd 1 -height 2
pack $w.right.label -side top
pack $w.right.sep -side top -fill x -expand no

set msgboxType ok
foreach t {abortretryignore ok okcancel retrycancel yesno yesnocancel} {
    radiobutton $w.right.$t -text $t -variable msgboxType \
	-relief flat -value $t -width 16 -anchor w
    pack $w.right.$t -side top -pady 2 -anchor w -fill x
}

proc showMessageBox {w} {
    global msgboxIcon msgboxType
    set button [tk_messageBox -icon $msgboxIcon -type $msgboxType \
	-title Message -parent $w\
	-message "This is a \"$msgboxType\" type messagebox with the \"$msgboxIcon\" icon"]

    tk_messageBox -icon info -message "You have selected \"$button\"" -type ok\
	-parent $w
}







|











|











32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
pack $w.left.label -side top
pack $w.left.sep -side top -fill x -expand no

set msgboxIcon info
foreach i {error info question warning} {
    radiobutton $w.left.b$i -text $i -variable msgboxIcon \
	-relief flat -value $i -width 16 -anchor w
    pack $w.left.b$i  -side top -pady 1.5p -anchor w -fill x
}

label $w.right.label -text "Type"
frame $w.right.sep -relief ridge -bd 1 -height 2
pack $w.right.label -side top
pack $w.right.sep -side top -fill x -expand no

set msgboxType ok
foreach t {abortretryignore ok okcancel retrycancel yesno yesnocancel} {
    radiobutton $w.right.$t -text $t -variable msgboxType \
	-relief flat -value $t -width 16 -anchor w
    pack $w.right.$t -side top -pady 1.5p -anchor w -fill x
}

proc showMessageBox {w} {
    global msgboxIcon msgboxType
    set button [tk_messageBox -icon $msgboxIcon -type $msgboxType \
	-title Message -parent $w\
	-message "This is a \"$msgboxType\" type messagebox with the \"$msgboxIcon\" icon"]

    tk_messageBox -icon info -message "You have selected \"$button\"" -type ok\
	-parent $w
}

Changes to library/demos/nl.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16


17
18
19
20
21
22
23
::msgcat::mcset nl "Widget Demonstration" "Demonstratie van widgets"
::msgcat::mcset nl "tkWidgetDemo" "tkWidgetDemo"
::msgcat::mcset nl "&File"     "&Bestand"
::msgcat::mcset nl "About..."  "Info..."
::msgcat::mcset nl "&About..." "&Info..."
::msgcat::mcset nl "<F1>"      "<F1>"
::msgcat::mcset nl "&Quit"     "&Einde"
::msgcat::mcset nl "Meta+Q"    "Meta+E"		;# Displayed hotkey
::msgcat::mcset nl "Meta-q"    "Meta-e"		;# Actual binding sequence
::msgcat::mcset nl "Ctrl+Q"    "Ctrl+E"		;# Displayed hotkey
::msgcat::mcset nl "Control-q" "Control-e"	;# Actual binding sequence
::msgcat::mcset nl "Dismiss"   "Sluiten"
::msgcat::mcset nl "See Variables"    "Bekijk Variabelen"
::msgcat::mcset nl "Variable Values"  "Waarden Variabelen"

::msgcat::mcset nl "OK"        "OK"
::msgcat::mcset nl "Run the \"%s\" sample program" "Start voorbeeld \"%s\""


::msgcat::mcset nl "Print Code" "Code Afdrukken"
::msgcat::mcset nl "Demo code: %s" "Code van Demo %s"
::msgcat::mcset nl "About Widget Demo" "Over deze demonstratie"
::msgcat::mcset nl "Tk widget demonstration" "Demonstratie van Tk widgets"
::msgcat::mcset nl "Copyright © %s"

::msgcat::mcset nl "Tk Widget Demonstrations" "Demonstratie van Tk widgets"

|









<

|
>
|

>
>







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
::msgcat::mcset nl "Widget Demonstration" "Demonstratie van widgets"
::msgcat::mcset nl "tkWidgetDemo"
::msgcat::mcset nl "&File"     "&Bestand"
::msgcat::mcset nl "About..."  "Info..."
::msgcat::mcset nl "&About..." "&Info..."
::msgcat::mcset nl "<F1>"      "<F1>"
::msgcat::mcset nl "&Quit"     "&Einde"
::msgcat::mcset nl "Meta+Q"    "Meta+E"		;# Displayed hotkey
::msgcat::mcset nl "Meta-q"    "Meta-e"		;# Actual binding sequence
::msgcat::mcset nl "Ctrl+Q"    "Ctrl+E"		;# Displayed hotkey
::msgcat::mcset nl "Control-q" "Control-e"	;# Actual binding sequence

::msgcat::mcset nl "See Variables"    "Bekijk Variabelen"
::msgcat::mcset nl "Variable values"  "Waarden variabelen"
::msgcat::mcset nl "Variable values:"  "Waarden variabelen"
::msgcat::mcset nl "OK"
::msgcat::mcset nl "Run the \"%s\" sample program" "Start voorbeeld \"%s\""
::msgcat::mcset nl "Dismiss"   "Sluiten"
::msgcat::mcset nl "Rerun Demo" "Herstart Demo"	;# This is also button text!
::msgcat::mcset nl "Print Code" "Code Afdrukken"
::msgcat::mcset nl "Demo code: %s" "Code van Demo %s"
::msgcat::mcset nl "About Widget Demo" "Over deze demonstratie"
::msgcat::mcset nl "Tk widget demonstration" "Demonstratie van Tk widgets"
::msgcat::mcset nl "Copyright © %s"

::msgcat::mcset nl "Tk Widget Demonstrations" "Demonstratie van Tk widgets"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
::msgcat::mcset nl "appears, you can click the" \
    "Zodra het nieuwe venster verschijnt, kun je op de knop"
::msgcat::mcset nl "See Code"  "Bekijk Code"	;# This is also button text!
::msgcat::mcset nl "button to see the Tcl/Tk code that created the demonstration.  If" \
    "drukken om de achterliggende Tcl/Tk code te zien.  Als je dat wilt,"
::msgcat::mcset nl "you wish, you can edit the code and click the" \
    "kun je de code wijzigen en op de knop"
::msgcat::mcset nl "Rerun Demo" "Herstart Demo"	;# This is also button text!
::msgcat::mcset nl "button in the code window to reinvoke the demonstration with the" \
    "drukken in het codevenster om de demonstratie uit te voeren met de"
::msgcat::mcset nl "modified code." \
    "nieuwe code."

::msgcat::mcset nl "Labels, buttons, checkbuttons, and radiobuttons" \
    "Labels, knoppen, vinkjes/aankruishokjes en radioknoppen"

::msgcat::mcset nl "Labels (text and bitmaps)" "Labels (tekst en plaatjes)"
::msgcat::mcset nl "Labels and UNICODE text"   "Labels en tekst in UNICODE"
::msgcat::mcset nl "Buttons" "Buttons (drukknoppen)"
::msgcat::mcset nl "Check-buttons (select any of a group)" \
    "Check-buttons (een of meer uit een groep)"
::msgcat::mcset nl "Radio-buttons (select one of a group)" \
    "Radio-buttons (een van een groep)"







<







<







34
35
36
37
38
39
40

41
42
43
44
45
46
47

48
49
50
51
52
53
54
::msgcat::mcset nl "appears, you can click the" \
    "Zodra het nieuwe venster verschijnt, kun je op de knop"
::msgcat::mcset nl "See Code"  "Bekijk Code"	;# This is also button text!
::msgcat::mcset nl "button to see the Tcl/Tk code that created the demonstration.  If" \
    "drukken om de achterliggende Tcl/Tk code te zien.  Als je dat wilt,"
::msgcat::mcset nl "you wish, you can edit the code and click the" \
    "kun je de code wijzigen en op de knop"

::msgcat::mcset nl "button in the code window to reinvoke the demonstration with the" \
    "drukken in het codevenster om de demonstratie uit te voeren met de"
::msgcat::mcset nl "modified code." \
    "nieuwe code."

::msgcat::mcset nl "Labels, buttons, checkbuttons, and radiobuttons" \
    "Labels, knoppen, vinkjes/aankruishokjes en radioknoppen"

::msgcat::mcset nl "Labels (text and bitmaps)" "Labels (tekst en plaatjes)"
::msgcat::mcset nl "Labels and UNICODE text"   "Labels en tekst in UNICODE"
::msgcat::mcset nl "Buttons" "Buttons (drukknoppen)"
::msgcat::mcset nl "Check-buttons (select any of a group)" \
    "Check-buttons (een of meer uit een groep)"
::msgcat::mcset nl "Radio-buttons (select one of a group)" \
    "Radio-buttons (een van een groep)"
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119







120
121
122
123
124
125


::msgcat::mcset nl "Scales" "Schaalverdelingen"
::msgcat::mcset nl "Horizontal scale"          "Horizontale schaal"
::msgcat::mcset nl "Vertical scale"          "Verticale schaal"

::msgcat::mcset nl "Paned Windows" "Vensters opgedeeld in stukken"
::msgcat::mcset nl "Horizontal paned window"   "Horizontaal gedeeld venster"
::msgcat::mcset nl "Vertical paned window"     "Verticaal gedeeld venster"

::msgcat::mcset nl "Menus" "Menu's"
::msgcat::mcset nl "Menus and cascades (sub-menus)" \
    "Menu's en cascades (submenu's)"
::msgcat::mcset nl "Menu-buttons" "Menu-buttons"

::msgcat::mcset nl "Common Dialogs" "Veel voorkomende dialoogvensters"
::msgcat::mcset nl "Message boxes"  "Mededeling (message box)"
::msgcat::mcset nl "File selection dialog"     "Selectie van bestanden"
::msgcat::mcset nl "Color picker"              "Kleurenpalet"








::msgcat::mcset nl "Miscellaneous"             "Diversen"
::msgcat::mcset nl "The built-in bitmaps"      "Ingebouwde plaatjes"
::msgcat::mcset nl "A dialog box with a local grab" \
    "Een dialoogvenster met een locale \"grab\""
::msgcat::mcset nl "A dialog box with a global grab" \
    "Een dialoogvenster met een globale \"grab\""









<




<




|
>
>
>
>
>
>
>






>
>
102
103
104
105
106
107
108

109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
::msgcat::mcset nl "Scales" "Schaalverdelingen"
::msgcat::mcset nl "Horizontal scale"          "Horizontale schaal"
::msgcat::mcset nl "Vertical scale"          "Verticale schaal"

::msgcat::mcset nl "Paned Windows" "Vensters opgedeeld in stukken"
::msgcat::mcset nl "Horizontal paned window"   "Horizontaal gedeeld venster"
::msgcat::mcset nl "Vertical paned window"     "Verticaal gedeeld venster"

::msgcat::mcset nl "Menus" "Menu's"
::msgcat::mcset nl "Menus and cascades (sub-menus)" \
    "Menu's en cascades (submenu's)"
::msgcat::mcset nl "Menu-buttons" "Menu-buttons"

::msgcat::mcset nl "Common Dialogs" "Veel voorkomende dialoogvensters"
::msgcat::mcset nl "Message boxes"  "Mededeling (message box)"
::msgcat::mcset nl "File selection dialog"     "Selectie van bestanden"
::msgcat::mcset nl "Color picker"              "Kleurenpalet"
::msgcat::mcset nl "Font selection dialog"     "Selectie van fonts"
::msgcat::mcset nl "System tray icon and notification" "Systeemvakpictogram en melding"
::msgcat::mcset nl "Printing from canvas and text widgets" "Afdrukken van canvas en tekst widgets"
::msgcat::mcset nl "Animation" "Animaties"
::msgcat::mcset nl "Animated labels" "Geanimeerde labels"
::msgcat::mcset nl "Animated wave" "Geanimeerde golf"
::msgcat::mcset nl "Pendulum simulation" "Pendulum simulatie"
::msgcat::mcset nl "A celebration of Rube Goldberg" "Een viering van Rube Goldberg"
::msgcat::mcset nl "Miscellaneous"             "Diversen"
::msgcat::mcset nl "The built-in bitmaps"      "Ingebouwde plaatjes"
::msgcat::mcset nl "A dialog box with a local grab" \
    "Een dialoogvenster met een locale \"grab\""
::msgcat::mcset nl "A dialog box with a global grab" \
    "Een dialoogvenster met een globale \"grab\""
::msgcat::mcset nl "Window icons and badges" "Vensterpictogrammen en badges"

Changes to library/demos/paned1.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
# paned1.tcl --
#
# This demonstration script creates a toplevel window containing
# a paned window that separates two windows horizontally.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .paned1
catch {destroy $w}
toplevel $w
wm title $w "Horizontal Paned Window Demonstration"
wm iconname $w "paned1"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "The sash between the two coloured windows below can be used to divide the area between them.  Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.)"
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

panedwindow $w.pane
pack $w.pane -side top -expand yes -fill both -pady 2 -padx 2m

label $w.pane.left  -text "This is the\nleft side"  -fg black -bg yellow
label $w.pane.right -text "This is the\nright side" -fg black -bg cyan

$w.pane add $w.pane.left $w.pane.right









|
















|




|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# paned1.tcl --
#
# This demonstration script creates a toplevel window containing
# a paned window that separates two windows horizontally.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .paned1
catch {destroy $w}
toplevel $w
wm title $w "Horizontal Paned Window Demonstration"
wm iconname $w "paned1"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "The sash between the two coloured windows below can be used to divide the area between them.  Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.)"
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

panedwindow $w.pane
pack $w.pane -side top -expand yes -fill both -pady 1.5p -padx 2m

label $w.pane.left  -text "This is the\nleft side"  -fg black -bg yellow
label $w.pane.right -text "This is the\nright side" -fg black -bg cyan

$w.pane add $w.pane.left $w.pane.right -stretch always

Changes to library/demos/paned2.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
# paned2.tcl --
#
# This demonstration script creates a toplevel window containing
# a paned window that separates two windows vertically.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .paned2
catch {destroy $w}
toplevel $w
wm title $w "Vertical Paned Window Demonstration"
wm iconname $w "paned2"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "The sash between the two scrolled windows below can be used to divide the area between them.  Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.)"
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create the pane itself
panedwindow $w.pane -orient vertical
pack $w.pane -side top -expand yes -fill both -pady 2 -padx 2m

# The top window is a listbox with scrollbar
set paneList {
    {List of Tk Widgets}
    button
    canvas
    checkbutton









|

















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# paned2.tcl --
#
# This demonstration script creates a toplevel window containing
# a paned window that separates two windows vertically.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .paned2
catch {destroy $w}
toplevel $w
wm title $w "Vertical Paned Window Demonstration"
wm iconname $w "paned2"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "The sash between the two scrolled windows below can be used to divide the area between them.  Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.)"
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create the pane itself
panedwindow $w.pane -orient vertical
pack $w.pane -side top -expand yes -fill both -pady 1.5p -padx 2m

# The top window is a listbox with scrollbar
set paneList {
    {List of Tk Widgets}
    button
    canvas
    checkbutton
67
68
69
70
71
72
73
74
grid $f.text $f.yscr -sticky nsew
grid $f.xscr         -sticky nsew
grid columnconfigure $f 0 -weight 1
grid rowconfigure    $f 0 -weight 1
$f.text insert 1.0 "This is just a normal text widget"

# Now add our contents to the paned window
$w.pane add $w.pane.top $w.pane.bottom







|
67
68
69
70
71
72
73
74
grid $f.text $f.yscr -sticky nsew
grid $f.xscr         -sticky nsew
grid columnconfigure $f 0 -weight 1
grid rowconfigure    $f 0 -weight 1
$f.text insert 1.0 "This is just a normal text widget"

# Now add our contents to the paned window
$w.pane add $w.pane.top $w.pane.bottom -stretch always

Changes to library/demos/pendulum.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
# pendulum.tcl --
#
# This demonstration illustrates how Tcl/Tk can be used to construct
# simulations of physical systems.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .pendulum
catch {destroy $w}
toplevel $w
wm title $w "Pendulum Animation Demonstration"
wm iconname $w "pendulum"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration shows how Tcl/Tk can be used to carry out animations that are linked to simulations of physical systems. In the left canvas is a graphical representation of the physical system itself, a simple pendulum, and in the right canvas is a graph of the phase space of the system, which is a plot of the angle (relative to the vertical) against the angular velocity. The pendulum bob may be repositioned by clicking and dragging anywhere on the left canvas."
pack $w.msg

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create some structural widgets
pack [panedwindow $w.p] -fill both -expand 1
$w.p add [labelframe $w.p.l1 -text "Pendulum Simulation"]
$w.p add [labelframe $w.p.l2 -text "Phase Space"]

# Create the canvas containing the graphical representation of the
# simulated system.
canvas $w.c -width 320 -height 200 -background white -bd 2 -relief sunken
$w.c create text 5 5 -anchor nw -text "Click to Adjust Bob Start Position"
# Coordinates of these items don't matter; they will be set properly below
$w.c create line 0 25 320 25   -tags plate -fill grey50 -width 2
$w.c create oval 155 20 165 30 -tags pivot -fill grey50 -outline {}
$w.c create line 1 1 1 1       -tags rod   -fill black  -width 3
$w.c create oval 1 1 2 2       -tags bob   -fill yellow -outline black
pack $w.c -in $w.p.l1 -fill both -expand true

# Create the canvas containing the phase space graph; this consists of
# a line that gets gradually paler as it ages, which is an extremely
# effective visual trick.
canvas $w.k -width 320 -height 200 -background white -bd 2 -relief sunken
$w.k create line 160 200 160 0 -fill grey75 -arrow last -tags y_axis
$w.k create line 0 100 320 100 -fill grey75 -arrow last -tags x_axis
for {set i 90} {$i>=0} {incr i -10} {
    # Coordinates of these items don't matter; they will be set properly below
    $w.k create line 0 0 1 1 -smooth true -tags graph$i -fill grey$i
}

$w.k create text 0 0 -anchor ne -text "θ" -tags label_theta
$w.k create text 0 0 -anchor ne -text "δθ" -tags label_dtheta
pack $w.k -in $w.p.l2 -fill both -expand true

# Initialize some variables
set points {}
set Theta   45.0
set dTheta   0.0
set pi       3.1415926535897933

set length 150
set home   160




# This procedure makes the pendulum appear at the correct place on the
# canvas. If the additional arguments "at $x $y" are passed (the 'at'
# is really just syntactic sugar) instead of computing the position of
# the pendulum from the length of the pendulum rod and its angle, the
# length and angle are computed in reverse from the given location
# (which is taken to be the centre of the pendulum bob.)
proc showPendulum {canvas {at {}} {x {}} {y {}}} {
    global Theta dTheta pi length home

    if {$at eq "at" && ($x!=$home || $y!=25)} {
	set dTheta 0.0
	set x2 [expr {$x - $home}]
	set y2 [expr {$y - 25}]
	set length [expr {hypot($x2, $y2)}]
	set Theta  [expr {atan2($x2, $y2) * 180/$pi}]
    } else {
	set angle [expr {$Theta * $pi/180}]
	set x [expr {$home + $length*sin($angle)}]
	set y [expr {25    + $length*cos($angle)}]
    }
    $canvas coords rod $home 25 $x $y
    $canvas coords bob \
	    [expr {$x-15}] [expr {$y-15}] [expr {$x+15}] [expr {$y+15}]
}
showPendulum $w.c

# Update the phase-space graph according to the current angle and the
# rate at which the angle is changing (the first derivative with
# respect to time.)
proc showPhase {canvas} {
    global Theta dTheta points psw psh


    lappend points [expr {$Theta+$psw}] [expr {-20*$dTheta+$psh}]
    if {[llength $points] > 100} {
    	 set points [lrange $points end-99 end]
    }
    for {set i 0} {$i<100} {incr i 10} {
	set list [lrange $points end-[expr {$i-1}] end-[expr {$i-12}]]
	if {[llength $list] >= 4} {
	    $canvas coords graph$i $list

	}
    }
}

# Set up some bindings on the canvases.  Note that when the user
# clicks we stop the animation until they release the mouse
# button. Also note that both canvases are sensitive to <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
# pendulum.tcl --
#
# This demonstration illustrates how Tcl/Tk can be used to construct
# simulations of physical systems.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .pendulum
catch {destroy $w}
toplevel $w
wm title $w "Pendulum Animation Demonstration"
wm iconname $w "pendulum"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "This demonstration shows how Tcl/Tk can be used to carry out animations that are linked to simulations of physical systems. In the left canvas is a graphical representation of the physical system itself, a simple pendulum, and in the right canvas is a graph of the phase space of the system, which is a plot of the angle (relative to the vertical) against the angular velocity. The pendulum bob may be repositioned by clicking and dragging anywhere on the left canvas."
pack $w.msg

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Create some structural widgets
pack [panedwindow $w.p] -fill both -expand 1
$w.p add [labelframe $w.p.l1 -text "Pendulum Simulation"] -stretch always
$w.p add [labelframe $w.p.l2 -text "Phase Space"] -stretch always

# Create the canvas containing the graphical representation of the
# simulated system.
canvas $w.c -width 240p -height 150p -background white -bd 1.5p -relief sunken
$w.c create text 3p 3p -anchor nw -text "Click to Adjust Bob Start Position"
# Coordinates of these items don't matter; they will be set properly below
$w.c create line 0 25 320 25   -tags plate -fill grey50 -width 1.5p
$w.c create oval 155 20 165 30 -tags pivot -fill grey50 -outline {}
$w.c create line 1 1 1 1       -tags rod   -fill black  -width 2.25p
$w.c create oval 1 1 2 2       -tags bob   -fill yellow -outline black
pack $w.c -in $w.p.l1 -fill both -expand true

# Create the canvas containing the phase space graph; this consists of
# a line that gets gradually paler as it ages, which is an extremely
# effective visual trick.
canvas $w.k -width 240p -height 150p -background white -bd 1.5p -relief sunken
$w.k create line 120p 150p 120p 0 -fill grey75 -arrow last -tags y_axis
$w.k create line 0 75p 240p 75p -fill grey75 -arrow last -tags x_axis
for {set i 90} {$i>=0} {incr i -10} {
    # Coordinates of these items don't matter; they will be set properly below
    $w.k create line 0 0 1 1 -smooth true -tags graph$i -fill grey$i
}

$w.k create text 0 0 -anchor ne -text "θ"  -tags label_theta
$w.k create text 0 0 -anchor ne -text "δθ" -tags label_dtheta
pack $w.k -in $w.p.l2 -fill both -expand true

# Initialize some variables
set points {}
set Theta  45.0
set dTheta  0.0
set pi      3.1415926535897933
set tkScl  [tk scaling]
set length [expr {round(111*$tkScl)}]			;# 111p -> pixels
set xHome  [expr {round(120*$tkScl)}]			;# 120p -> pixels
set yHome  [expr {round( 18*$tkScl)}]			;#  18p -> pixels
set rBob   [expr {round( 12*$tkScl)}]			;#  12p -> pixels
set rPivot [expr {round(  3*$tkScl)}]			;#   3p -> pixels

# This procedure makes the pendulum appear at the correct place on the
# canvas. If the additional arguments "at $x $y" are passed (the 'at'
# is really just syntactic sugar) instead of computing the position of
# the pendulum from the length of the pendulum rod and its angle, the
# length and angle are computed in reverse from the given location
# (which is taken to be the centre of the pendulum bob.)
proc showPendulum {canvas {at {}} {x {}} {y {}}} {
    global Theta dTheta pi length xHome yHome rBob

    if {$at eq "at" && ($x!=$xHome || $y!=$yHome)} {
	set dTheta 0.0
	set x2 [expr {$x - $xHome}]
	set y2 [expr {$y - $yHome}]
	set length [expr {hypot($x2, $y2)}]
	set Theta  [expr {atan2($x2, $y2) * 180/$pi}]
    } else {
	set angle [expr {$Theta * $pi/180}]
	set x [expr {$xHome + $length*sin($angle)}]
	set y [expr {$yHome + $length*cos($angle)}]
    }
    $canvas coords rod $xHome $yHome $x $y
    $canvas coords bob [expr {$x - $rBob}] [expr {$y - $rBob}] \
		       [expr {$x + $rBob}] [expr {$y + $rBob}]
}
showPendulum $w.c

# Update the phase-space graph according to the current angle and the
# rate at which the angle is changing (the first derivative with
# respect to time.)
proc showPhase {canvas} {
    global Theta dTheta points psw psh
    set sclFactor [expr {$tk::scalingPct / 100.0}]

    lappend points [expr {$Theta + $psw}] [expr {-20*$sclFactor*$dTheta + $psh}]
    if {[llength $points] > 100} {
	set points [lrange $points end-99 end]
    }
    for {set i 0} {$i<100} {incr i 10} {
	set list [lrange $points end-[expr {$i-1}] end-[expr {$i-12}]]
	if {[llength $list] >= 4} {
	    $canvas coords graph$i $list
	    $canvas scale graph$i $psw $psh $sclFactor $sclFactor
	}
    }
}

# Set up some bindings on the canvases.  Note that when the user
# clicks we stop the animation until they release the mouse
# button. Also note that both canvases are sensitive to <Configure>
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
    showPendulum %W at %x %y
}
bind $w.c <ButtonRelease-1> {
    showPendulum %W at %x %y
    set animationCallbacks(pendulum) [after 15 repeat [winfo toplevel %W]]
}
bind $w.c <Configure> {
    %W coords plate 0 25 %w 25
    set home [expr {%w/2}]
    %W coords pivot [expr {$home-5}] 20 [expr {$home+5}] 30
}
bind $w.k <Configure> {
    set psh [expr {%h/2}]
    set psw [expr {%w/2}]
    %W coords x_axis 2 $psh [expr {%w-2}] $psh
    %W coords y_axis $psw [expr {%h-2}] $psw 2
    %W coords label_dtheta [expr {$psw-4}] 6
    %W coords label_theta [expr {%w-6}] [expr {$psh+4}]

}

# This procedure is the "business" part of the simulation that does
# simple numerical integration of the formula for a simple rotational
# pendulum.
proc recomputeAngle {} {
    global Theta dTheta pi length







|
|
|




|
|
|
|
>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
    showPendulum %W at %x %y
}
bind $w.c <ButtonRelease-1> {
    showPendulum %W at %x %y
    set animationCallbacks(pendulum) [after 15 repeat [winfo toplevel %W]]
}
bind $w.c <Configure> {
    %W coords plate 0 18p %w 18p
    set xHome [expr {%w/2}]
    %W coords pivot [expr {$xHome - $rPivot}] 15p [expr {$xHome + $rPivot}] 21p
}
bind $w.k <Configure> {
    set psh [expr {%h/2}]
    set psw [expr {%w/2}]
    %W coords x_axis	   1.5p $psh [expr {%w - round(1.5*$tkScl)}] $psh
    %W coords y_axis	   $psw [expr {%h - round(1.5*$tkScl)}] $psw 1.5p
    %W coords label_dtheta [expr {$psw - round(3*$tkScl)}] 4.5p
    %W coords label_theta  [expr {%w - round(4.5*$tkScl)}] \
			   [expr {$psh + round(3*$tkScl)}]
}

# This procedure is the "business" part of the simulation that does
# simple numerical integration of the formula for a simple rotational
# pendulum.
proc recomputeAngle {} {
    global Theta dTheta pi length

Changes to library/demos/plot.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# plot.tcl --
#
# This demonstration script creates a canvas widget showing a 2-D
# plot with data points that can be dragged with the mouse.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .plot
catch {destroy $w}
toplevel $w
wm title $w "Plot Demonstration"
wm iconname $w "Plot"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 4i -justify left -text "This window displays a canvas widget containing a simple 2-dimensional plot.  You can doctor the data by dragging any of the points with mouse button 1."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

canvas $c -relief raised -width 450 -height 300
pack $w.c -side top -fill x

set plotFont {Helvetica 18}

$c create line 100 250 400 250 -width 2
$c create line 100 250 100 50 -width 2
$c create text 225 20 -text "A Simple Plot" -font $plotFont -fill brown

for {set i 0} {$i <= 10} {incr i} {
    set x [expr {100 + ($i*30)}]
    $c create line $x 250 $x 245 -width 2
    $c create text $x 254 -text [expr {10*$i}] -anchor n -font $plotFont
}
for {set i 0} {$i <= 5} {incr i} {
    set y [expr {250 - ($i*40)}]
    $c create line 100 $y 105 $y -width 2
    $c create text 96 $y -text [expr {$i*50}].0 -anchor e -font $plotFont
}

foreach point {
    {12 56} {20 94} {33 98} {32 120} {61 180} {75 160} {98 223}
} {
    set x [expr {100 + (3*[lindex $point 0])}]
    set y [expr {250 - (4*[lindex $point 1])/5}]
    set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
	    [expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
	    -fill SkyBlue2]
    $c addtag point withtag $item
}

$c bind point <Enter> "$c itemconfig current -fill red"
$c bind point <Leave> "$c itemconfig current -fill SkyBlue2"
$c bind point <Button-1> "plotDown $c %x %y"









|
















|


|

|
|
|


|
|
|


|
|
|



|

|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# plot.tcl --
#
# This demonstration script creates a canvas widget showing a 2-D
# plot with data points that can be dragged with the mouse.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .plot
catch {destroy $w}
toplevel $w
wm title $w "Plot Demonstration"
wm iconname $w "Plot"
positionWindow $w
set c $w.c

label $w.msg -font $font -wraplength 4i -justify left -text "This window displays a canvas widget containing a simple 2-dimensional plot.  You can doctor the data by dragging any of the points with mouse button 1."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

canvas $c -relief raised -width 337.5p -height 225p
pack $w.c -side top -fill x

set plotFont {Helvetica 16}

$c create line 75p 187.5p 300p 187.5p -width 1.5p
$c create line 75p 187.5p 75p 37.5p -width 1.5p
$c create text 168.75p 15p -text "A Simple Plot" -font $plotFont -fill brown

for {set i 0} {$i <= 10} {incr i} {
    set x [expr {75 + ($i*22.5)}]			;# in points
    $c create line ${x}p 187.5p ${x}p 183.75p -width 1.5p
    $c create text ${x}p 190.5p -text [expr {10*$i}] -anchor n -font $plotFont
}
for {set i 0} {$i <= 5} {incr i} {
    set y [expr {187.5 - ($i*30)}]			;# in points
    $c create line 75p ${y}p 78.75p ${y}p -width 1.5p
    $c create text 72p ${y}p -text [expr {$i*50}].0 -anchor e -font $plotFont
}

foreach point {
    {9 42} {15 70.5} {24.75 73.5} {24 90} {45.75 135} {56.25 120} {73.5 167.25}
} {
    set x [expr {75 + (2.25*[lindex $point 0])}]	;# in points
    set y [expr {187.5 - (3*[lindex $point 1])/5}]	;# in points
    set item [$c create oval [expr {$x-4.5}]p [expr {$y-4.5}]p \
	    [expr {$x+4.5}]p [expr {$y+4.5}]p -width 0.75p -outline black \
	    -fill SkyBlue2]
    $c addtag point withtag $item
}

$c bind point <Enter> "$c itemconfig current -fill red"
$c bind point <Leave> "$c itemconfig current -fill SkyBlue2"
$c bind point <Button-1> "plotDown $c %x %y"

Added library/demos/print.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
# print.tcl --
#
# This demonstration script showcases the tk print commands.
#

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

set w .print
destroy $w
toplevel $w
wm title $w "Printing Demonstration"
positionWindow $w

pack [label $w.l -text "This demonstration showcases
the tk print command. Clicking the buttons below
prints the data from the canvas and text widgets
using platform-native dialogs."] -side top

## See Code / Dismiss buttons
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x

frame $w.m

image create photo logo -data {
R0lGODlhMABLAPUAAP//////zP//mf//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM/8zMzMyZzMyZ
mcyZZsyZAMxmZsxmM8xmAMwzM8wzAJnMzJmZzJmZmZlmmZlmZplmM5kzZpkzM5kzAGaZzGZmzGZm
mWYzZmYzMzNmzDNmmTMzmTMzZgAzmQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH+BSAtZGwtACH5BAEKAAIALAAAAAAw
AEsAAAb+QIFwSCwahY9HRMI8Op/JJVNSqVqv2OvjyRU8slbIJGwYg60S5ZR6jRi/4ITBOhkYIOd8
dltEnAdmFQMJeoVXCEd/VnKGjRVOZ3NVgHlsjpBxVRCEYBIEAAARl4lgZmVgEQAKFx8Mo0ZnpqgA
Fyi2JqKGmGebWRIAILbCIo27cYFWASTCtievRXqSVwQfzLYeeYESxlnSVRIW1igjWHJmjBXbpKXe
FQTizlh1eJNVHbYf0LGc39XW2PIoVZE0whasWPSqFBBHrkKEA3QG0DFTEMXBUsjCWesg4oMFAGwg
tKsiwqA+jGiCiRPGAM6pLCVLGKHQ6EGJlc0IuDxzAgX+CCOW9DjAaUsEyAoT+GHpeSRoHgxEUWgA
UEUpFhMWgTbKEPUBAU15TBZxekYD0RMEqCDLIpYIWTAcmGEd9rWQBxQyjeQqdK/ZTWEO3mK5l+9N
o75SrcHhm9WwnlzNoA5zdM+JHz0HCPQdUauZowoFnSw+c2CBvw6dUXT4LMKE6EIHUqMexgCiIREk
nOwl7Q+FhNQoLuzOc6Kw3kIIVOLqjYKBYCwinmgo9CBEswfMAziK7mRDoQhcUZxwoBKFibq3n3jX
I0GyCPLC0DrS8GR1oaEoRBRYVhT99/qG4DcCA/yNU4Ajbjhhnx4P2DJggR3YZog6RyyYxwM9PSgM
BaP+sQdgIRL0JAKBwnTooRMAFWLdiPyJ8JwvTnyQoh5midCASh149ZkTIFAmHnzOZOBfIU6U4Mhd
4zF34DNEoDAhARGY50BvJkioyxFOGkKAShGkFsJwejiR5Xf8aZAaBp89coQJjuDXAQOApekEm45A
NaAtIbyYxREf0OlICCK841uaahZBQjyfjXCACYjuaASjhFagRKSFNtloHg+hYWIxRohnBQWCSSAh
BVZ+hkgRnlbxwJIVgIqGlaU6wkeTxHxjm6gVLImrFbHWVEQ1taZjWxJX7KqqnqgUEUxDwtqajrOa
RkqhEDcxWwECbEjxTYe9gojqOJQ6JO231ob72bSqAjh4RgfsjiDCCfDCK8K8I9TL7r33nvGtCO7C
O1dUAONk3LcBFxzwwEMwZ/DC4iAsRIE+CWNCbzeV8FfEtoDwVwnlacxMkcKQYIE/F5TQ2QcedUZC
agyc3NsFGrXVZMipWVBCzKv4Q0JvCviDsjAwf4ylxBeX0KcwGs81ccgqGS3MBxc3RjDDVAvdBRcf
eFy1MFd3bcQHJEQdlddkP5E1Cf9yXfbaV2d9RBAAOw==
}

# Create a copy of the image just created, magnified according to the
# display's DPI scaling level.  Since the zooom factor must be an integer,
# the copy will only be effectively magnified if $tk::scalingPct >= 200.
image create photo logo2
logo2 copy logo -zoom [expr {$tk::scalingPct / 100}]

set c [canvas $w.m.c -bg white]
pack $c -fill both -expand yes -fill both -side left

# For scaling-awareness specify the coordinates of the canvas items in points
# rather than pixels.  Create the items with a left and top padding of 15 pt.
$c create rectangle 15p 15p 165p 60p -fill blue -outline black	;# 150p x 45p
$c create oval 15p 75p 165p 120p -fill green			;# 150p x 45p
set imgId [$c create image 90p 135p -image logo2 -anchor n]

# Compute the scaled y coordinate of the next canvas item's top edge in pixels
lassign [$c bbox $imgId] x1 y1 x2 y2		;# x1, y1, x2, y2 are in pixels
incr y2 [expr {round(15 * [tk scaling])}]	;# convert 15 pt to pixels

$c create text 15p $y2 -anchor nw -font {Helvetica 12} \
	-text "A short demo of simple canvas elements."

set txt {
Tcl, or Tool Command Language, is an open-source multi-purpose C library which includes a powerful dynamic scripting language. Together they provide ideal cross-platform development environment for any programming project. It has served for decades as an essential system component in organizations ranging from NASA to Cisco Systems, is a must-know language in the fields of EDA, and powers companies such as FlightAware and F5 Networks.

Tcl is fit for both the smallest and largest programming tasks, obviating the need to decide whether it is overkill for a given job or whether a system written in Tcl will scale up as needed. Wherever a shell script might be used Tcl is a better choice, and entire web ecosystems and mission-critical control and testing systems have also been written in Tcl. Tcl excels in all these roles due to the minimal syntax of the language, the unique programming paradigm exposed at the script level, and the careful engineering that has gone into the design of the Tcl internals.
}

set t [text $w.m.t -wrap word]
pack $t -side right -expand yes -fill both
$t insert end $txt

frame $w.f

pack [button $w.f.c -text "Print Canvas" -command [list tk print $w.m.c]] \
	-side left -anchor w -padx 3p
pack [button $w.f.t -text "Print Text" -command [list tk print $w.m.t]] \
	-side right -anchor e -padx 3p

pack $w.f -side bottom -fill x
pack $w.m -expand yes -fill both -side top

Changes to library/demos/puzzle.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# puzzle.tcl --
#
# This demonstration script creates a 15-puzzle game using a collection
# of buttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# puzzleSwitch --
# This procedure is invoked when the user clicks on a particular button;
# if the button is next to the empty space, it moves the button into th
# empty space.

proc puzzleSwitch {w num} {
    global xpos ypos
    if {(($ypos($num) >= ($ypos(space) - .01))
	    && ($ypos($num) <= ($ypos(space) + .01))
	    && ($xpos($num) >= ($xpos(space) - .26))









|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# puzzle.tcl --
#
# This demonstration script creates a 15-puzzle game using a collection
# of buttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# puzzleSwitch --
# This procedure is invoked when the user clicks on a particular button;
# if the button is next to the empty space, it moves the button into the
# empty space.

proc puzzleSwitch {w num} {
    global xpos ypos
    if {(($ypos($num) >= ($ypos(space) - .01))
	    && ($ypos($num) <= ($ypos(space) + .01))
	    && ($xpos($num) >= ($xpos(space) - .26))
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
scrollbar $w.s

# The button metrics are a bit bigger in Aqua, and since we are
# using place which doesn't autosize, then we need to have a
# slightly larger frame here...

if {[tk windowingsystem] eq "aqua"} {
    set frameSize 168
} else {
    set frameSize 120
}

frame $w.frame -width $frameSize -height $frameSize -borderwidth 2\
	-relief sunken -bg [$w.s cget -troughcolor]
pack $w.frame -side top -pady 1c -padx 1c
destroy $w.s

set order {3 1 6 2 5 7 15 13 4 11 8 9 14 10 12}
for {set i 0} {$i < 15} {set i [expr {$i+1}]} {
    set num [lindex $order $i]







|

|


|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
scrollbar $w.s

# The button metrics are a bit bigger in Aqua, and since we are
# using place which doesn't autosize, then we need to have a
# slightly larger frame here...

if {[tk windowingsystem] eq "aqua"} {
    set frameSize 126p
} else {
    set frameSize 90p
}

frame $w.frame -width $frameSize -height $frameSize -borderwidth 2 \
	-relief sunken -bg [$w.s cget -troughcolor]
pack $w.frame -side top -pady 1c -padx 1c
destroy $w.s

set order {3 1 6 2 5 7 15 13 4 11 8 9 14 10 12}
for {set i 0} {$i < 15} {set i [expr {$i+1}]} {
    set num [lindex $order $i]

Changes to library/demos/radio.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
# radio.tcl --
#
# This demonstration script creates a toplevel window containing
# several radiobutton widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .radio
catch {destroy $w}
toplevel $w
wm title $w "Radiobutton Demonstration"
wm iconname $w "radio"
positionWindow $w
label $w.msg -font $font -wraplength 5i -justify left -text "Three groups of radiobuttons are displayed below.  If you click on a button then the button will become selected exclusively among all the buttons in its group.  A Tcl variable is associated with each group to indicate which of the group's buttons is selected.  When the 'Tristate' button is pressed, the radio buttons will display the tri-state mode. Selecting any radio button will return the buttons to their respective on/off state. Click the \"See Variables\" button to see the current values of the variables."
grid $w.msg -row 0 -column 0 -columnspan 3 -sticky nsew

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w [list size color align]]
grid $btns -row 3 -column 0 -columnspan 3 -sticky ew

labelframe $w.left -pady 2 -text "Point Size" -padx 2
labelframe $w.mid -pady 2 -text "Color" -padx 2
labelframe $w.right -pady 2 -text "Alignment" -padx 2
button $w.tristate -text Tristate -command "set size multi; set color multi" \
    -pady 2 -padx 2
if {[tk windowingsystem] eq "aqua"} {
    $w.tristate configure -padx 10
}
grid $w.left     -column 0 -row 1 -pady .5c -padx .5c -rowspan 2
grid $w.mid      -column 1 -row 1 -pady .5c -padx .5c -rowspan 2
grid $w.right    -column 2 -row 1 -pady .5c -padx .5c
grid $w.tristate -column 2 -row 2 -pady .5c -padx .5c

foreach i {10 12 14 18 24} {
    radiobutton $w.left.b$i -text "Point Size $i" -variable size \
	    -relief flat -value $i -tristatevalue "multi"
    pack $w.left.b$i  -side top -pady 2 -anchor w -fill x
}

foreach c {Red Green Blue Yellow Orange Purple} {
    set lower [string tolower $c]
    radiobutton $w.mid.$lower -text $c -variable color \
	    -relief flat -value $lower -anchor w \
	    -command "$w.mid configure -fg \$color" \
	-tristatevalue "multi"
    pack $w.mid.$lower -side top -pady 2 -fill x
}


label $w.right.l -text "Label" -bitmap questhead -compound left
$w.right.l configure -width [winfo reqwidth $w.right.l] -compound top
$w.right.l configure -height [winfo reqheight $w.right.l]
foreach a {Top Left Right Bottom} {









|














|
|
|

|

|









|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# radio.tcl --
#
# This demonstration script creates a toplevel window containing
# several radiobutton widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .radio
catch {destroy $w}
toplevel $w
wm title $w "Radiobutton Demonstration"
wm iconname $w "radio"
positionWindow $w
label $w.msg -font $font -wraplength 5i -justify left -text "Three groups of radiobuttons are displayed below.  If you click on a button then the button will become selected exclusively among all the buttons in its group.  A Tcl variable is associated with each group to indicate which of the group's buttons is selected.  When the 'Tristate' button is pressed, the radio buttons will display the tri-state mode. Selecting any radio button will return the buttons to their respective on/off state. Click the \"See Variables\" button to see the current values of the variables."
grid $w.msg -row 0 -column 0 -columnspan 3 -sticky nsew

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w [list size color align]]
grid $btns -row 3 -column 0 -columnspan 3 -sticky ew

labelframe $w.left -pady 1.5p -text "Point Size" -padx 1.5p
labelframe $w.mid -pady 1.5p -text "Color" -padx 1.5p
labelframe $w.right -pady 1.5p -text "Alignment" -padx 1.5p
button $w.tristate -text Tristate -command "set size multi; set color multi" \
    -pady 1.5p -padx 1.5p
if {[tk windowingsystem] eq "aqua"} {
    $w.tristate configure -padx 7.5p
}
grid $w.left     -column 0 -row 1 -pady .5c -padx .5c -rowspan 2
grid $w.mid      -column 1 -row 1 -pady .5c -padx .5c -rowspan 2
grid $w.right    -column 2 -row 1 -pady .5c -padx .5c
grid $w.tristate -column 2 -row 2 -pady .5c -padx .5c

foreach i {10 12 14 18 24} {
    radiobutton $w.left.b$i -text "Point Size $i" -variable size \
	    -relief flat -value $i -tristatevalue "multi"
    pack $w.left.b$i  -side top -pady 1.5p -anchor w -fill x
}

foreach c {Red Green Blue Yellow Orange Purple} {
    set lower [string tolower $c]
    radiobutton $w.mid.$lower -text $c -variable color \
	    -relief flat -value $lower -anchor w \
	    -command "$w.mid configure -fg \$color" \
	-tristatevalue "multi"
    pack $w.mid.$lower -side top -pady 1.5p -fill x
}


label $w.right.l -text "Label" -bitmap questhead -compound left
$w.right.l configure -width [winfo reqwidth $w.right.l] -compound top
$w.right.l configure -height [winfo reqheight $w.right.l]
foreach a {Top Left Right Bottom} {

Changes to library/demos/rmt.

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+"$@"}

# rmt --
# This script implements a simple remote-control mechanism for
# Tk applications.  It allows you to select an application and
# then type commands to that application.

package require Tk

wm title . "Tk Remote Controller"
wm iconname . "Tk Remote"
wm minsize . 1 1

# The global variable below keeps track of the remote application
# that we're sending to.  If it's an empty string then we execute









|







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+"$@"}

# rmt --
# This script implements a simple remote-control mechanism for
# Tk applications.  It allows you to select an application and
# then type commands to that application.

package require tk

wm title . "Tk Remote Controller"
wm iconname . "Tk Remote"
wm minsize . 1 1

# The global variable below keeps track of the remote application
# that we're sending to.  If it's an empty string then we execute

Changes to library/demos/rolodex.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# rolodex --
# This script was written as an entry in Tom LaStrange's rolodex
# benchmark.  It creates something that has some of the look and
# feel of a rolodex program, although it's lifeless and doesn't
# actually do the rolodex application.

package require Tk

foreach i [winfo child .] {
    catch {destroy $i}
}

set version 1.2

#------------------------------------------
# Phase 0: create the front end.
#------------------------------------------

frame .frame -relief flat
pack .frame -side top -fill y -anchor center

set names {{} Name: Address: {} {} {Home Phone:} {Work Phone:} Fax:}
foreach i {1 2 3 4 5 6 7} {
    label .frame.label$i -text [lindex $names $i] -anchor e
    entry .frame.entry$i -width 35
    grid .frame.label$i .frame.entry$i -sticky ew -pady 2 -padx 1
}

frame .buttons
pack .buttons -side bottom -pady 2 -anchor center
button .buttons.clear -text Clear
button .buttons.add -text Add
button .buttons.search -text Search
button .buttons.delete -text "Delete ..."
pack .buttons.clear .buttons.add .buttons.search .buttons.delete \
	-side left -padx 2

#------------------------------------------
# Phase 1: Add menus, dialog boxes
#------------------------------------------

# DKF - note that this is an old-style menu bar; I just have not yet
# got around to converting the context help code to work with the new










|

|
















|



|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# rolodex --
# This script was written as an entry in Tom LaStrange's rolodex
# benchmark.  It creates something that has some of the look and
# feel of a rolodex program, although it's lifeless and doesn't
# actually do the rolodex application.

package require tk

foreach i [winfo children .] {
    catch {destroy $i}
}

set version 1.2

#------------------------------------------
# Phase 0: create the front end.
#------------------------------------------

frame .frame -relief flat
pack .frame -side top -fill y -anchor center

set names {{} Name: Address: {} {} {Home Phone:} {Work Phone:} Fax:}
foreach i {1 2 3 4 5 6 7} {
    label .frame.label$i -text [lindex $names $i] -anchor e
    entry .frame.entry$i -width 35
    grid .frame.label$i .frame.entry$i -sticky ew -pady 1.5p -padx 0.75p
}

frame .buttons
pack .buttons -side bottom -pady 1.5p -anchor center
button .buttons.clear -text Clear
button .buttons.add -text Add
button .buttons.search -text Search
button .buttons.delete -text "Delete ..."
pack .buttons.clear .buttons.add .buttons.search .buttons.delete \
	-side left -padx 1.5p

#------------------------------------------
# Phase 1: Add menus, dialog boxes
#------------------------------------------

# DKF - note that this is an old-style menu bar; I just have not yet
# got around to converting the context help code to work with the new

Changes to library/demos/ruler.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ruler.tcl --
#
# This demonstration script creates a canvas widget that displays a ruler
# with tab stops that can be set, moved, and deleted.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# rulerMkTab --
# This procedure creates a new triangular polygon in a canvas to
# represent a tab stop.
#
# Arguments:
# c -		The canvas window.









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ruler.tcl --
#
# This demonstration script creates a canvas widget that displays a ruler
# with tab stops that can be set, moved, and deleted.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# rulerMkTab --
# This procedure creates a new triangular polygon in a canvas to
# represent a tab stop.
#
# Arguments:
# c -		The canvas window.

Changes to library/demos/sayings.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
# sayings.tcl --
#
# This demonstration script creates a listbox that can be scrolled
# both horizontally and vertically.  It displays a collection of
# well-known sayings.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .sayings
catch {destroy $w}
toplevel $w
wm title $w "Listbox Demonstration (well-known sayings)"
wm iconname $w "sayings"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "The listbox below contains a collection of well-known sayings.  You can scan the list using either of the scrollbars or by dragging in the listbox window with button 2 pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame -side top -expand yes -fill both -padx 1c


ttk::scrollbar $w.frame.yscroll -command "$w.frame.list yview"
ttk::scrollbar $w.frame.xscroll -orient horizontal \
    -command "$w.frame.list xview"
listbox $w.frame.list -width 20 -height 10 -setgrid 1 \










|















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# sayings.tcl --
#
# This demonstration script creates a listbox that can be scrolled
# both horizontally and vertically.  It displays a collection of
# well-known sayings.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .sayings
catch {destroy $w}
toplevel $w
wm title $w "Listbox Demonstration (well-known sayings)"
wm iconname $w "sayings"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "The listbox below contains a collection of well-known sayings.  You can scan the list using either of the scrollbars or by dragging in the listbox window with button 2 pressed."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 7.5p
pack $w.frame -side top -expand yes -fill both -padx 1c


ttk::scrollbar $w.frame.yscroll -command "$w.frame.list yview"
ttk::scrollbar $w.frame.xscroll -orient horizontal \
    -command "$w.frame.list xview"
listbox $w.frame.list -width 20 -height 10 -setgrid 1 \

Changes to library/demos/search.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# search.tcl --
#
# This demonstration script creates a collection of widgets that
# allow you to load a file into a text widget, then perform searches
# on that file.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# textLoadFile --
# This procedure below loads a file into a text widget, discarding
# the previous contents of the widget. Tags for the old widget are
# not affected, however.
#
# Arguments:










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# search.tcl --
#
# This demonstration script creates a collection of widgets that
# allow you to load a file into a text widget, then perform searches
# on that file.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# textLoadFile --
# This procedure below loads a file into a text widget, discarding
# the previous contents of the widget. Tags for the old widget are
# not affected, however.
#
# Arguments:
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

frame $w.file
label $w.file.label -text "File name:" -width 13 -anchor w
entry $w.file.entry -width 40 -textvariable fileName
button $w.file.button -text "Load File" \
	-command "textLoadFile $w.text \$fileName"
pack $w.file.label $w.file.entry -side left
pack $w.file.button -side left -pady 5 -padx 10
bind $w.file.entry <Return> "
    textLoadFile $w.text \$fileName
    focus $w.string.entry
"
focus $w.file.entry

frame $w.string
label $w.string.label -text "Search string:" -width 13 -anchor w
entry $w.string.entry -width 40 -textvariable searchString
button $w.string.button -text "Highlight" \
	-command "textSearch $w.text \$searchString search"
pack $w.string.label $w.string.entry -side left
pack $w.string.button -side left -pady 5 -padx 10
bind $w.string.entry <Return> "textSearch $w.text \$searchString search"

text $w.text -yscrollcommand "$w.scroll set" -setgrid true
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.file $w.string -side top -fill x
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both







|












|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

frame $w.file
label $w.file.label -text "File name:" -width 13 -anchor w
entry $w.file.entry -width 40 -textvariable fileName
button $w.file.button -text "Load File" \
	-command "textLoadFile $w.text \$fileName"
pack $w.file.label $w.file.entry -side left
pack $w.file.button -side left -pady 3p -padx 7.5p
bind $w.file.entry <Return> "
    textLoadFile $w.text \$fileName
    focus $w.string.entry
"
focus $w.file.entry

frame $w.string
label $w.string.label -text "Search string:" -width 13 -anchor w
entry $w.string.entry -width 40 -textvariable searchString
button $w.string.button -text "Highlight" \
	-command "textSearch $w.text \$searchString search"
pack $w.string.label $w.string.entry -side left
pack $w.string.button -side left -pady 3p -padx 7.5p
bind $w.string.entry <Return> "textSearch $w.text \$searchString search"

text $w.text -yscrollcommand "$w.scroll set" -setgrid true
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.file $w.string -side top -fill x
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

Changes to library/demos/spin.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# spin.tcl --
#
# This demonstration script creates several spinbox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .spin
catch {destroy $w}
toplevel $w
wm title $w "Spinbox Demonstration"
wm iconname $w "spin"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# spin.tcl --
#
# This demonstration script creates several spinbox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .spin
catch {destroy $w}
toplevel $w
wm title $w "Spinbox Demonstration"
wm iconname $w "spin"
positionWindow $w
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

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}
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

#$w.e1 insert 0 "Initial value"
#$w.e2 insert end "This entry contains a long value, much too long "
#$w.e2 insert end "to fit in the window at one time, so long in fact "
#$w.e2 insert end "that you'll have to scan or scroll to see the end."







|






|





34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

set australianCities {
    Canberra Sydney Melbourne Perth Adelaide Brisbane
    Hobart Darwin "Alice Springs"
}

spinbox $w.s1 -from 1 -to 10 -width 10 -validate key \
	-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 3p -padx 7.5p ;#-fill x

#$w.e1 insert 0 "Initial value"
#$w.e2 insert end "This entry contains a long value, much too long "
#$w.e2 insert end "to fit in the window at one time, so long in fact "
#$w.e2 insert end "that you'll have to scan or scroll to see the end."

Changes to library/demos/square.

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.

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}













|
|







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 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}

Changes to library/demos/states.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
# states.tcl --
#
# This demonstration script creates a listbox widget that displays
# the names of the 50 states in the United States of America.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .states
catch {destroy $w}
toplevel $w
wm title $w "Listbox Demonstration (50 states)"
wm iconname $w "states"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing the 50 states is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by scanning.  To scan, press button 2 in the widget and drag up or down."
pack $w.msg -side top

labelframe $w.justif -text Justification
foreach c {Left Center Right} {
    set lower [string tolower $c]
    radiobutton $w.justif.$lower -text $c -variable just \
        -relief flat -value $lower -anchor w \
        -command "$w.frame.list configure -justify \$just" \
        -tristatevalue "multi"
    pack $w.justif.$lower -side left -pady 2 -fill x
}
pack $w.justif

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x










|


















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# states.tcl --
#
# This demonstration script creates a listbox widget that displays
# the names of the 50 states in the United States of America.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .states
catch {destroy $w}
toplevel $w
wm title $w "Listbox Demonstration (50 states)"
wm iconname $w "states"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing the 50 states is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by scanning.  To scan, press button 2 in the widget and drag up or down."
pack $w.msg -side top

labelframe $w.justif -text Justification
foreach c {Left Center Right} {
    set lower [string tolower $c]
    radiobutton $w.justif.$lower -text $c -variable just \
        -relief flat -value $lower -anchor w \
        -command "$w.frame.list configure -justify \$just" \
        -tristatevalue "multi"
    pack $w.justif.$lower -side left -pady 1.5p -fill x
}
pack $w.justif

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

Changes to library/demos/style.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# style.tcl --
#
# This demonstration script creates a text widget that illustrates the
# various display styles that may be set for tags.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .style
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Display Styles"
wm iconname $w "style"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# style.tcl --
#
# This demonstration script creates a text widget that illustrates the
# various display styles that may be set for tags.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .style
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Display Styles"
wm iconname $w "style"
positionWindow $w
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	    -borderwidth 1
    $w.text tag configure sunken -background white -relief sunken \
	    -borderwidth 1
}
$w.text tag configure bgstipple -background black -borderwidth 0 \
	-bgstipple gray12
$w.text tag configure fgstipple -fgstipple gray50
$w.text tag configure underline -underline on
$w.text tag configure overstrike -overstrike on
$w.text tag configure right -justify right
$w.text tag configure center -justify center
$w.text tag configure super -offset 4p -font "$family 10"
$w.text tag configure sub -offset -2p -font "$family 10"
$w.text tag configure margins -lmargin1 12m -lmargin2 6m -rmargin 10m
$w.text tag configure spacing -spacing1 10p -spacing2 2p \
	-lmargin1 12m -lmargin2 6m -rmargin 10m







|
|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	    -borderwidth 1
    $w.text tag configure sunken -background white -relief sunken \
	    -borderwidth 1
}
$w.text tag configure bgstipple -background black -borderwidth 0 \
	-bgstipple gray12
$w.text tag configure fgstipple -fgstipple gray50
$w.text tag configure underline -underline 1
$w.text tag configure overstrike -overstrike 1
$w.text tag configure right -justify right
$w.text tag configure center -justify center
$w.text tag configure super -offset 4p -font "$family 10"
$w.text tag configure sub -offset -2p -font "$family 10"
$w.text tag configure margins -lmargin1 12m -lmargin2 6m -rmargin 10m
$w.text tag configure spacing -spacing1 10p -spacing2 2p \
	-lmargin1 12m -lmargin2 6m -rmargin 10m

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

## See Code / Dismiss buttons
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x

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 3p -pady 3p -side left -expand true -fill x

button $w.b3 -text "Display Notification" -command notify
pack $w.f $w.b3 -fill x -padx 3p -pady 3p

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

Changes to library/demos/tclIndex.

61
62
63
64
65
66
67



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]]










>
>
>
61
62
63
64
65
66
67
68
69
70
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]]
set auto_index(windoicons [list source -encoding utf-8 [file join $dir windowicons.tcl]]

Changes to library/demos/tcolor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# tcolor --
# This script implements a simple color editor, where you can
# create colors using either the RGB, HSB, or CYM color spaces
# and apply the color to existing applications.

package require Tk
wm title . "Color Editor"

# Global variables that control the program:
#
# colorSpace -			Color space currently being used for
#				editing.  Must be "rgb", "cmy", or "hsb".
# label1, label2, label3 -	Labels for the scales.









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# tcolor --
# This script implements a simple color editor, where you can
# create colors using either the RGB, HSB, or CYM color spaces
# and apply the color to existing applications.

package require tk
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/text.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# text.tcl --
#
# This demonstration script creates a text widget that describes
# the basic editing functions.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .text
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Basic Facilities"
wm iconname $w "text"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# text.tcl --
#
# This demonstration script creates a text widget that describes
# the basic editing functions.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .text
catch {destroy $w}
toplevel $w
wm title $w "Text Demonstration - Basic Facilities"
wm iconname $w "text"
positionWindow $w

Changes to library/demos/textpeer.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# textpeer.tcl --
#
# This demonstration script creates a pair of text widgets that can edit a
# single logical buffer. This is particularly useful when editing related text
# in two (or more) parts of the same file.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .textpeer
catch {destroy $w}
toplevel $w
wm title $w "Text Widget Peering Demonstration"
wm iconname $w "textpeer"
positionWindow $w










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# textpeer.tcl --
#
# This demonstration script creates a pair of text widgets that can edit a
# single logical buffer. This is particularly useful when editing related text
# in two (or more) parts of the same file.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .textpeer
catch {destroy $w}
toplevel $w
wm title $w "Text Widget Peering Demonstration"
wm iconname $w "textpeer"
positionWindow $w

Changes to library/demos/timer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# timer --
# This script generates a counter with start and stop buttons.

package require Tk

label .counter -text 0.00 -relief raised -width 10 -padx 2m -pady 1m
button .start -text Start -command {
    if {$stopped} {
	set stopped 0
	set startMoment [clock clicks -milliseconds]
	tick







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# timer --
# This script generates a counter with start and stop buttons.

package require tk

label .counter -text 0.00 -relief raised -width 10 -padx 2m -pady 1m
button .start -text Start -command {
    if {$stopped} {
	set stopped 0
	set startMoment [clock clicks -milliseconds]
	tick

Changes to library/demos/toolbar.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# toolbar.tcl --
#
# This demonstration script creates a toolbar that can be torn off.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .toolbar
destroy $w
toplevel $w
wm title $w "Toolbar Demonstration"
wm iconname $w "toolbar"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# toolbar.tcl --
#
# This demonstration script creates a toolbar that can be torn off.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .toolbar
destroy $w
toplevel $w
wm title $w "Toolbar Demonstration"
wm iconname $w "toolbar"
positionWindow $w
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

## Set up the toolbar hull
set t [frame $w.toolbar]		;# Must be a frame!
ttk::separator $w.sep
ttk::frame $t.tearoff -cursor fleur
ttk::separator $t.tearoff.to -orient vertical
ttk::separator $t.tearoff.to2 -orient vertical
pack $t.tearoff.to -fill y -expand 1 -padx 4 -side left
pack $t.tearoff.to2 -fill y -expand 1 -side left
ttk::frame $t.contents
grid $t.tearoff $t.contents -sticky nsew
grid columnconfigure $t $t.contents -weight 1
grid columnconfigure $t.contents 1000 -weight 1

## Bindings so that the toolbar can be torn off and reattached







|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

## Set up the toolbar hull
set t [frame $w.toolbar]		;# Must be a frame!
ttk::separator $w.sep
ttk::frame $t.tearoff -cursor fleur
ttk::separator $t.tearoff.to -orient vertical
ttk::separator $t.tearoff.to2 -orient vertical
pack $t.tearoff.to -fill y -expand 1 -padx 3p -side left
pack $t.tearoff.to2 -fill y -expand 1 -side left
ttk::frame $t.contents
grid $t.tearoff $t.contents -sticky nsew
grid columnconfigure $t $t.contents -weight 1
grid columnconfigure $t.contents 1000 -weight 1

## Bindings so that the toolbar can be torn off and reattached
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}

## Some content for the rest of the toplevel
text $w.txt -width 40 -height 10
interp alias {} doInsert {} $w.txt insert end	;# Make bindings easy to write

## Arrange contents
grid $t.button $t.check $t.menu $t.combo -in $t.contents -padx 2 -pady 4 -sticky ns
grid $t -sticky ew
grid $w.sep -sticky ew
grid $w.msg -sticky ew
grid $w.txt -sticky nsew
grid rowconfigure $w $w.txt -weight 1
grid columnconfigure $w $w.txt -weight 1

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
grid $btns -sticky ew







|










75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}

## Some content for the rest of the toplevel
text $w.txt -width 40 -height 10
interp alias {} doInsert {} $w.txt insert end	;# Make bindings easy to write

## Arrange contents
grid $t.button $t.check $t.menu $t.combo -in $t.contents -padx 1.5p -pady 3p -sticky ns
grid $t -sticky ew
grid $w.sep -sticky ew
grid $w.msg -sticky ew
grid $w.txt -sticky nsew
grid rowconfigure $w $w.txt -weight 1
grid columnconfigure $w $w.txt -weight 1

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
grid $btns -sticky ew

Changes to library/demos/tree.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# tree.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .tree
catch {destroy $w}
toplevel $w
wm title $w "Directory Browser"
wm iconname $w "tree"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# tree.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# tree widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .tree
catch {destroy $w}
toplevel $w
wm title $w "Directory Browser"
wm iconname $w "tree"
positionWindow $w

Changes to library/demos/ttkbut.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ttkbut.tcl --
#
# This demonstration script creates a toplevel window containing several
# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and
# radiobuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttkbut
catch {destroy $w}
toplevel $w
wm title $w "Simple Ttk Widgets"
wm iconname $w "ttkbut"
positionWindow $w

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Ttk is the new Tk themed widget set. This is a Ttk themed label, and below are three groups of Ttk widgets in Ttk labelframes. The first group are all buttons that set the current application theme when pressed. The second group contains three sets of checkbuttons, with a separator widget between the sets. Note that the “Enabled” button controls whether all the other themed widgets in this toplevel are in the disabled state. The third group has a collection of linked radiobuttons."
pack $w.msg -side top -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w {enabled cheese tomato basil oregano happiness}]\
	-side bottom -fill x

## Add buttons for setting the theme
ttk::labelframe $w.buttons -text "Buttons"
foreach theme [ttk::themes] {
    ttk::button $w.buttons.$theme -text $theme \
	    -command [list ttk::setTheme $theme]
    pack $w.buttons.$theme -pady 2
}

## Helper procedure for the top checkbutton
proc setState {rootWidget exceptThese value} {
    if {$rootWidget in $exceptThese} {
	return
    }










|

















|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ttkbut.tcl --
#
# This demonstration script creates a toplevel window containing several
# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and
# radiobuttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ttkbut
catch {destroy $w}
toplevel $w
wm title $w "Simple Ttk Widgets"
wm iconname $w "ttkbut"
positionWindow $w

ttk::label $w.msg -font $font -wraplength 4i -justify left -text "Ttk is the new Tk themed widget set. This is a Ttk themed label, and below are three groups of Ttk widgets in Ttk labelframes. The first group are all buttons that set the current application theme when pressed. The second group contains three sets of checkbuttons, with a separator widget between the sets. Note that the “Enabled” button controls whether all the other themed widgets in this toplevel are in the disabled state. The third group has a collection of linked radiobuttons."
pack $w.msg -side top -fill x

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w {enabled cheese tomato basil oregano happiness}]\
	-side bottom -fill x

## Add buttons for setting the theme
ttk::labelframe $w.buttons -text "Buttons"
foreach theme [lsort [ttk::themes]] {
    ttk::button $w.buttons.$theme -text $theme \
	    -command [list ttk::setTheme $theme]
    pack $w.buttons.$theme -pady 1.5p
}

## Helper procedure for the top checkbutton
proc setState {rootWidget exceptThese value} {
    if {$rootWidget in $exceptThese} {
	return
    }
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
ttk::separator   $w.checks.sep1
ttk::checkbutton $w.checks.c1 -text Cheese  -variable cheese
ttk::checkbutton $w.checks.c2 -text Tomato  -variable tomato
ttk::separator   $w.checks.sep2
ttk::checkbutton $w.checks.c3 -text Basil   -variable basil
ttk::checkbutton $w.checks.c4 -text Oregano -variable oregano
pack $w.checks.e $w.checks.sep1 $w.checks.c1 $w.checks.c2 $w.checks.sep2 \
	$w.checks.c3 $w.checks.c4   -fill x -pady 2

## Set up the radiobutton group
ttk::labelframe $w.radios -text "Radiobuttons"
ttk::radiobutton $w.radios.r1 -text "Great" -variable happiness -value great
ttk::radiobutton $w.radios.r2 -text "Good" -variable happiness -value good
ttk::radiobutton $w.radios.r3 -text "OK" -variable happiness -value ok
ttk::radiobutton $w.radios.r4 -text "Poor" -variable happiness -value poor
ttk::radiobutton $w.radios.r5 -text "Awful" -variable happiness -value awful
pack $w.radios.r1 $w.radios.r2 $w.radios.r3 $w.radios.r4 $w.radios.r5 \
	-fill x -padx 3 -pady 2

## Arrange things neatly
pack [ttk::frame $w.f] -fill both -expand 1
lower $w.f
grid $w.buttons $w.checks $w.radios -in $w.f -sticky nwe -pady 2 -padx 3
grid columnconfigure $w.f {0 1 2} -weight 1 -uniform yes







|









|




|

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
ttk::separator   $w.checks.sep1
ttk::checkbutton $w.checks.c1 -text Cheese  -variable cheese
ttk::checkbutton $w.checks.c2 -text Tomato  -variable tomato
ttk::separator   $w.checks.sep2
ttk::checkbutton $w.checks.c3 -text Basil   -variable basil
ttk::checkbutton $w.checks.c4 -text Oregano -variable oregano
pack $w.checks.e $w.checks.sep1 $w.checks.c1 $w.checks.c2 $w.checks.sep2 \
	$w.checks.c3 $w.checks.c4   -fill x -pady 1.5p

## Set up the radiobutton group
ttk::labelframe $w.radios -text "Radiobuttons"
ttk::radiobutton $w.radios.r1 -text "Great" -variable happiness -value great
ttk::radiobutton $w.radios.r2 -text "Good" -variable happiness -value good
ttk::radiobutton $w.radios.r3 -text "OK" -variable happiness -value ok
ttk::radiobutton $w.radios.r4 -text "Poor" -variable happiness -value poor
ttk::radiobutton $w.radios.r5 -text "Awful" -variable happiness -value awful
pack $w.radios.r1 $w.radios.r2 $w.radios.r3 $w.radios.r4 $w.radios.r5 \
	-fill x -padx 3p -pady 1.5p

## Arrange things neatly
pack [ttk::frame $w.f] -fill both -expand 1
lower $w.f
grid $w.buttons $w.checks $w.radios -in $w.f -sticky nwe -pady 1.5p -padx 3p
grid columnconfigure $w.f {0 1 2} -weight 1 -uniform yes

Changes to library/demos/ttkmenu.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ttkmenu.tcl --
#
# This demonstration script creates a toplevel window containing several Ttk
# menubutton widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttkmenu
catch {destroy $w}
toplevel $w
wm title $w "Ttk Menu Buttons"
wm iconname $w "ttkmenu"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ttkmenu.tcl --
#
# This demonstration script creates a toplevel window containing several Ttk
# menubutton widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ttkmenu
catch {destroy $w}
toplevel $w
wm title $w "Ttk Menu Buttons"
wm iconname $w "ttkmenu"
positionWindow $w
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

menu $w.m1.menu -tearoff 0
menu $w.m2.menu -tearoff 0
menu $w.m3.menu -tearoff 0
menu $w.m4.menu -tearoff 0
menu $w.m5.menu -tearoff 0

foreach theme [ttk::themes] {
    $w.m1.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m2.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m3.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m4.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m5.menu add command -label $theme -command [list ttk::setTheme $theme]
}

pack [ttk::frame $w.f] -fill x
pack [ttk::frame $w.f1] -fill both -expand yes
lower $w.f

grid anchor $w.f center
grid   x   $w.m1   x    -in $w.f -padx 3 -pady 2
grid $w.m2 $w.m4 $w.m3  -in $w.f -padx 3 -pady 2
grid   x   $w.m5   x    -in $w.f -padx 3 -pady 2







|












|
|
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

menu $w.m1.menu -tearoff 0
menu $w.m2.menu -tearoff 0
menu $w.m3.menu -tearoff 0
menu $w.m4.menu -tearoff 0
menu $w.m5.menu -tearoff 0

foreach theme [lsort [ttk::themes]] {
    $w.m1.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m2.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m3.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m4.menu add command -label $theme -command [list ttk::setTheme $theme]
    $w.m5.menu add command -label $theme -command [list ttk::setTheme $theme]
}

pack [ttk::frame $w.f] -fill x
pack [ttk::frame $w.f1] -fill both -expand yes
lower $w.f

grid anchor $w.f center
grid   x   $w.m1   x    -in $w.f -padx 2.25p -pady 1.5p
grid $w.m2 $w.m4 $w.m3  -in $w.f -padx 2.25p -pady 1.5p
grid   x   $w.m5   x    -in $w.f -padx 2.25p -pady 1.5p

Changes to library/demos/ttknote.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
# ttknote.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# notebook widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttknote
catch {destroy $w}
toplevel $w
wm title $w "Ttk Notebook Widget"
wm iconname $w "ttknote"
positionWindow $w

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w] -side bottom -fill x

ttk::frame $w.f
pack $w.f -fill both -expand 1
set w $w.f

## Make the notebook and set up Ctrl+Tab traversal
ttk::notebook $w.note
pack $w.note -fill both -expand 1 -padx 2 -pady 3
ttk::notebook::enableTraversal $w.note

## Popuplate the first pane
ttk::frame $w.note.msg
ttk::label $w.note.msg.m -font $font -wraplength 4i -justify left -anchor n -text "Ttk is the new Tk themed widget set. One of the widgets it includes is the notebook widget, which provides a set of tabs that allow the selection of a group of panels, each with distinct content. They are a feature of many modern user interfaces. Not only can the tabs be selected with the mouse, but they can also be switched between using Ctrl+Tab when the notebook page heading itself is selected. Note that the second tab is disabled, and cannot be selected."
ttk::button $w.note.msg.b -text "Neat!" -underline 0 -command {
    set neat "Yeah, I know..."
    after 500 {set neat {}}
}
bind $w <Alt-n> "focus $w.note.msg.b; $w.note.msg.b invoke"
ttk::label $w.note.msg.l -textvariable neat
$w.note add $w.note.msg -text "Description" -underline 0 -padding 2
grid $w.note.msg.m - -sticky new -pady 2
grid $w.note.msg.b $w.note.msg.l -pady {2 4}
grid rowconfigure $w.note.msg 1 -weight 1
grid columnconfigure $w.note.msg {0 1} -weight 1 -uniform 1

## Populate the second pane. Note that the content doesn't really matter
ttk::frame $w.note.disabled
$w.note add $w.note.disabled -text "Disabled" -state disabled

## Popuplate the third pane
ttk::frame $w.note.editor
$w.note add $w.note.editor -text "Text Editor" -underline 0
text $w.note.editor.t -width 40 -height 10 -wrap char \
	-yscroll "$w.note.editor.s set"
ttk::scrollbar $w.note.editor.s -orient vertical -command "$w.note.editor.t yview"
pack $w.note.editor.s -side right -fill y -padx {0 2} -pady 2
pack $w.note.editor.t -fill both -expand 1 -pady 2 -padx {2 0}









|

















|











|
|
|













|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# ttknote.tcl --
#
# This demonstration script creates a toplevel window containing a Ttk
# notebook widget.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ttknote
catch {destroy $w}
toplevel $w
wm title $w "Ttk Notebook Widget"
wm iconname $w "ttknote"
positionWindow $w

## See Code / Dismiss
pack [addSeeDismiss $w.seeDismiss $w] -side bottom -fill x

ttk::frame $w.f
pack $w.f -fill both -expand 1
set w $w.f

## Make the notebook and set up Ctrl+Tab traversal
ttk::notebook $w.note
pack $w.note -fill both -expand 1 -padx 1.5p -pady 3p
ttk::notebook::enableTraversal $w.note

## Popuplate the first pane
ttk::frame $w.note.msg
ttk::label $w.note.msg.m -font $font -wraplength 4i -justify left -anchor n -text "Ttk is the new Tk themed widget set. One of the widgets it includes is the notebook widget, which provides a set of tabs that allow the selection of a group of panels, each with distinct content. They are a feature of many modern user interfaces. Not only can the tabs be selected with the mouse, but they can also be switched between using Ctrl+Tab when the notebook page heading itself is selected. Note that the second tab is disabled, and cannot be selected."
ttk::button $w.note.msg.b -text "Neat!" -underline 0 -command {
    set neat "Yeah, I know..."
    after 500 {set neat {}}
}
bind $w <Alt-n> "focus $w.note.msg.b; $w.note.msg.b invoke"
ttk::label $w.note.msg.l -textvariable neat
$w.note add $w.note.msg -text "Description" -underline 0 -padding 1.5p
grid $w.note.msg.m - -sticky new -pady 1.5p
grid $w.note.msg.b $w.note.msg.l -pady {1.5p 3p}
grid rowconfigure $w.note.msg 1 -weight 1
grid columnconfigure $w.note.msg {0 1} -weight 1 -uniform 1

## Populate the second pane. Note that the content doesn't really matter
ttk::frame $w.note.disabled
$w.note add $w.note.disabled -text "Disabled" -state disabled

## Popuplate the third pane
ttk::frame $w.note.editor
$w.note add $w.note.editor -text "Text Editor" -underline 0
text $w.note.editor.t -width 40 -height 10 -wrap char \
	-yscroll "$w.note.editor.s set"
ttk::scrollbar $w.note.editor.s -orient vertical -command "$w.note.editor.t yview"
pack $w.note.editor.s -side right -fill y -padx {0 1.5p} -pady 1.5p
pack $w.note.editor.t -fill both -expand 1 -pady 1.5p -padx {1.5p 0}

Changes to library/demos/ttkpane.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ttkpane.tcl --
#
# This demonstration script creates a Ttk pane with some content.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttkpane
catch {destroy $w}
toplevel $w
wm title $w "Themed Nested Panes"
wm iconname $w "ttkpane"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ttkpane.tcl --
#
# This demonstration script creates a Ttk pane with some content.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ttkpane
catch {destroy $w}
toplevel $w
wm title $w "Themed Nested Panes"
wm iconname $w "ttkpane"
positionWindow $w
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

# Fill the button pane
ttk::button $w.outer.inLeft.top.b -text "Press Me" -command {
    tk_messageBox -type ok -icon info -message "Ouch!" -detail "That hurt..." \
	    -parent .ttkpane -title "Button Pressed"
}
pack $w.outer.inLeft.top.b -padx 2 -pady 5

# Fill the clocks pane
set i 0
proc every {delay script} {
    uplevel #0 $script
    after $delay [list every $delay $script]
}







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

# Fill the button pane
ttk::button $w.outer.inLeft.top.b -text "Press Me" -command {
    tk_messageBox -type ok -icon info -message "Ouch!" -detail "That hurt..." \
	    -parent .ttkpane -title "Button Pressed"
}
pack $w.outer.inLeft.top.b -padx 1.5p -pady 3p

# Fill the clocks pane
set i 0
proc every {delay script} {
    uplevel #0 $script
    after $delay [list every $delay $script]
}
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    # The trick with the ttk::frame makes the text widget look like it fits with
    # the current Ttk theme despite not being a themed widget itself. It is done
    # by styling the frame like an entry, turning off the border in the text
    # widget, and putting the text widget in the frame with enough space to allow
    # the surrounding border to show through (2 pixels seems to be enough).
    ttk::frame $w.outer.inRight.bot.f				-style TEntry
    text $w.txt -wrap word -yscroll "$w.sb set" -width 30	-borderwidth 0
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot.f	-pady 2 -padx 2
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.outer.inRight.bot.f -fill both -expand 1
    pack $w.outer -fill both -expand 1
} else {
    text $w.txt -wrap word -yscroll "$w.sb set" -width 30 -borderwidth 0
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot
    pack $w.outer -fill both -expand 1 -padx 10 -pady {6 10}
}








|












93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    # The trick with the ttk::frame makes the text widget look like it fits with
    # the current Ttk theme despite not being a themed widget itself. It is done
    # by styling the frame like an entry, turning off the border in the text
    # widget, and putting the text widget in the frame with enough space to allow
    # the surrounding border to show through (2 pixels seems to be enough).
    ttk::frame $w.outer.inRight.bot.f				-style TEntry
    text $w.txt -wrap word -yscroll "$w.sb set" -width 30	-borderwidth 0
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot.f	-pady 1.5p -padx 1.5p
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.outer.inRight.bot.f -fill both -expand 1
    pack $w.outer -fill both -expand 1
} else {
    text $w.txt -wrap word -yscroll "$w.sb set" -width 30 -borderwidth 0
    ttk::scrollbar $w.sb -orient vertical -command "$w.txt yview"
    pack $w.sb -side right -fill y -in $w.outer.inRight.bot
    pack $w.txt -fill both -expand 1 -in $w.outer.inRight.bot
    pack $w.outer -fill both -expand 1 -padx 10 -pady {6 10}
}

Changes to library/demos/ttkprogress.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ttkprogress.tcl --
#
# This demonstration script creates several progress bar widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttkprogress
catch {destroy $w}
toplevel $w
wm title $w "Progress Bar Demonstration"
wm iconname $w "ttkprogress"
positionWindow $w








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ttkprogress.tcl --
#
# This demonstration script creates several progress bar widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ttkprogress
catch {destroy $w}
toplevel $w
wm title $w "Progress Bar Demonstration"
wm iconname $w "ttkprogress"
positionWindow $w
34
35
36
37
38
39
40
41
42
43
44
45
46
ttk::progressbar $w.p1 -mode determinate
ttk::progressbar $w.p2 -mode indeterminate
ttk::button $w.start -text "Start Progress" -command [list \
	doBars start $w.p1 $w.p2]
ttk::button $w.stop -text "Stop Progress" -command [list \
	doBars stop $w.p1 $w.p2]

grid $w.p1 - -pady 5 -padx 10
grid $w.p2 - -pady 5 -padx 10
grid $w.start $w.stop -padx 10 -pady 5
grid configure $w.start -sticky e
grid configure $w.stop -sticky w
grid columnconfigure $w all -weight 1







|
|
|



34
35
36
37
38
39
40
41
42
43
44
45
46
ttk::progressbar $w.p1 -mode determinate
ttk::progressbar $w.p2 -mode indeterminate
ttk::button $w.start -text "Start Progress" -command [list \
	doBars start $w.p1 $w.p2]
ttk::button $w.stop -text "Stop Progress" -command [list \
	doBars stop $w.p1 $w.p2]

grid $w.p1 - -pady 3p -padx 7.5p
grid $w.p2 - -pady 3p -padx 7.5p
grid $w.start $w.stop -padx 7.5p -pady 3p
grid configure $w.start -sticky e
grid configure $w.stop -sticky w
grid columnconfigure $w all -weight 1

Changes to library/demos/ttkscale.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
# ttkscale.tcl --
#
# This demonstration script shows an example with a horizontal scale.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttkscale
catch {destroy $w}
toplevel $w -bg [ttk::style lookup TLabel -background]
wm title $w "Themed Scale Demonstration"
wm iconname $w "ttkscale"
positionWindow $w

pack [ttk::frame [set w $w.contents]] -fill both -expand 1

ttk::label $w.msg -font $font -wraplength 3.5i -justify left -text "A label tied to a horizontal scale is displayed below.  If you click or drag mouse button 1 in the scale, you can change the contents of the label; a callback command is used to couple the slider to both the text and the coloring of the label."
pack $w.msg -side top -padx .5c

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons [winfo toplevel $w]]
pack $btns -side bottom -fill x

ttk::frame $w.frame -borderwidth 10
pack $w.frame -side top -fill x

# List of colors from rainbox; "Indigo" is not a standard color
set colorList {Red Orange Yellow Green Blue Violet}
ttk::label $w.frame.label
ttk::scale $w.frame.scale -from 0 -to 5 -command [list apply {{w idx} {
    set c [lindex $::colorList [tcl::mathfunc::int $idx]]
    $w.frame.label configure -foreground $c -text "Color: $c"
}} $w]
# Trigger the setting of the label's text
$w.frame.scale set 0
pack $w.frame.label $w.frame.scale








|

















|


|









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ttkscale.tcl --
#
# This demonstration script shows an example with a horizontal scale.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .ttkscale
catch {destroy $w}
toplevel $w -bg [ttk::style lookup TLabel -background]
wm title $w "Themed Scale Demonstration"
wm iconname $w "ttkscale"
positionWindow $w

pack [ttk::frame [set w $w.contents]] -fill both -expand 1

ttk::label $w.msg -font $font -wraplength 3.5i -justify left -text "A label tied to a horizontal scale is displayed below.  If you click or drag mouse button 1 in the scale, you can change the contents of the label; a callback command is used to couple the slider to both the text and the coloring of the label."
pack $w.msg -side top -padx .5c

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons [winfo toplevel $w]]
pack $btns -side bottom -fill x

ttk::frame $w.frame -borderwidth 7.5p
pack $w.frame -side top -fill x

# List of colors from rainbow; "Indigo" is not a standard color
set colorList {Red Orange Yellow Green Blue Violet}
ttk::label $w.frame.label
ttk::scale $w.frame.scale -from 0 -to 5 -command [list apply {{w idx} {
    set c [lindex $::colorList [tcl::mathfunc::int $idx]]
    $w.frame.label configure -foreground $c -text "Color: $c"
}} $w]
# Trigger the setting of the label's text
$w.frame.scale set 0
pack $w.frame.label $w.frame.scale

Changes to library/demos/twind.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# twind.tcl --
#
# This demonstration script creates a text widget with a bunch of
# embedded windows.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# Make an Aqua button's fill color match its parent's background
proc blend {bt} {
    if {[tk windowingsystem] eq "aqua"} {
	$bt configure -highlightbackground [[winfo parent $bt] cget -background]
    }
    return $bt









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# twind.tcl --
#
# This demonstration script creates a text widget with a bunch of
# embedded windows.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

# Make an Aqua button's fill color match its parent's background
proc blend {bt} {
    if {[tk windowingsystem] eq "aqua"} {
	$bt configure -highlightbackground [[winfo parent $bt] cget -background]
    }
    return $bt
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
text $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \
	-height 35 -wrap word -highlightthickness 0 -borderwidth 0
pack $t -expand  yes -fill both
ttk::scrollbar $w.scroll -command "$t yview"
pack $w.scroll -side right -fill y
panedwindow $w.pane
pack $w.pane -expand yes -fill both
$w.pane add $w.f
# Import to raise given creation order above
raise $w.f

$t tag configure center -justify center -spacing1 5m -spacing3 5m
$t tag configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c \
	-spacing1 3m -spacing2 0 -spacing3 0








|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
text $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \
	-height 35 -wrap word -highlightthickness 0 -borderwidth 0
pack $t -expand  yes -fill both
ttk::scrollbar $w.scroll -command "$t yview"
pack $w.scroll -side right -fill y
panedwindow $w.pane
pack $w.pane -expand yes -fill both
$w.pane add $w.f -stretch always
# Import to raise given creation order above
raise $w.f

$t tag configure center -justify center -spacing1 5m -spacing3 5m
$t tag configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c \
	-spacing1 3m -spacing2 0 -spacing3 0

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
$t insert end " the plot again.\n\n"

$t insert end "You can also create multiple text widgets each of which "
$t insert end "display the same underlying text. Click this button to "
$t window create end \
  -create {button %W.peer -text "Make A Peer" -command "textMakePeer %W" \
	       -cursor top_left_arrow
      blend %W.peer} -padx 3
$t insert end " widget.  Notice how peer widgets can have different "
$t insert end "font settings, and by default contain all the images "
$t insert end "of the 'parent', but that the embedded windows, "
$t insert end "such as buttons may not appear in the peer.  To ensure "
$t insert end "that embedded windows appear in all peers you can set the "
$t insert end "'-create' option to a script or a string containing %W.  "
$t insert end "(The plot above and the 'Make A Peer' button are "
$t insert end "designed to show up in all peers.)  A good use of "
$t insert end "peers is for "
$t window create end \
  -create {button %W.split -text "Split Windows" -command "textSplitWindow %W" \
	       -cursor top_left_arrow
      blend %W.split} -padx 3
$t insert end " \n\n"

$t insert end "Users of previous versions of Tk will also be interested "
$t insert end "to note that now cursor movement is now by visual line by "
$t insert end "default, and that all scrolling of this widget is by pixel.\n\n"

$t insert end "You may also find it useful to put embedded windows in "







|












|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
$t insert end " the plot again.\n\n"

$t insert end "You can also create multiple text widgets each of which "
$t insert end "display the same underlying text. Click this button to "
$t window create end \
  -create {button %W.peer -text "Make A Peer" -command "textMakePeer %W" \
	       -cursor top_left_arrow
      blend %W.peer} -padx 3p
$t insert end " widget.  Notice how peer widgets can have different "
$t insert end "font settings, and by default contain all the images "
$t insert end "of the 'parent', but that the embedded windows, "
$t insert end "such as buttons may not appear in the peer.  To ensure "
$t insert end "that embedded windows appear in all peers you can set the "
$t insert end "'-create' option to a script or a string containing %W.  "
$t insert end "(The plot above and the 'Make A Peer' button are "
$t insert end "designed to show up in all peers.)  A good use of "
$t insert end "peers is for "
$t window create end \
  -create {button %W.split -text "Split Windows" -command "textSplitWindow %W" \
	       -cursor top_left_arrow
      blend %W.split} -padx 3p
$t insert end " \n\n"

$t insert end "Users of previous versions of Tk will also be interested "
$t insert end "to note that now cursor movement is now by visual line by "
$t insert end "default, and that all scrolling of this widget is by pixel.\n\n"

$t insert end "You may also find it useful to put embedded windows in "
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
$t insert end "you can see how the text widget automatically "
$t insert end "changes the layout.  Click on the button again "
$t insert end "to restore the short string.\n"

$t insert end "\nNOTE: these buttons will not appear in peers!\n" "peer_warning"
button $t.default -text Default -command "embDefBg $t" \
	-cursor top_left_arrow
$t window create end -window $t.default -padx 3
global embToggle
set embToggle Short
checkbutton $t.toggle -textvariable embToggle -indicatoron 0 \
	-variable embToggle -onvalue "A much longer string" \
	-offvalue "Short" -cursor top_left_arrow -pady 5 -padx 2
$t window create end -window $t.toggle -padx 3 -pady 2
set i 1
foreach color {AntiqueWhite3 Bisque1 Bisque2 Bisque3 Bisque4
	SlateBlue3 RoyalBlue1 SteelBlue2 DeepSkyBlue3 LightBlue1
	DarkSlateGray1 Aquamarine2 DarkSeaGreen2 SeaGreen1
	Yellow1 IndianRed1 IndianRed2 Tan1 Tan4} {
    button $t.color$i -text $color -cursor top_left_arrow -command \
	    "changeBg $t $color"
    $t window create end -window [blend $t.color$i] -padx 3 -pady 2
    incr i
}
$t tag add buttons [blend $t.default] end

button $t.bigB -text "Big borders" -command "textWindBigB $t" \
  -cursor top_left_arrow
button $t.smallB -text "Small borders" -command "textWindSmallB $t" \







|




|
|







|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
$t insert end "you can see how the text widget automatically "
$t insert end "changes the layout.  Click on the button again "
$t insert end "to restore the short string.\n"

$t insert end "\nNOTE: these buttons will not appear in peers!\n" "peer_warning"
button $t.default -text Default -command "embDefBg $t" \
	-cursor top_left_arrow
$t window create end -window $t.default -padx 3p
global embToggle
set embToggle Short
checkbutton $t.toggle -textvariable embToggle -indicatoron 0 \
	-variable embToggle -onvalue "A much longer string" \
	-offvalue "Short" -cursor top_left_arrow -pady 3p -padx 1.5p
$t window create end -window $t.toggle -padx 3p -pady 1.5p
set i 1
foreach color {AntiqueWhite3 Bisque1 Bisque2 Bisque3 Bisque4
	SlateBlue3 RoyalBlue1 SteelBlue2 DeepSkyBlue3 LightBlue1
	DarkSlateGray1 Aquamarine2 DarkSeaGreen2 SeaGreen1
	Yellow1 IndianRed1 IndianRed2 Tan1 Tan4} {
    button $t.color$i -text $color -cursor top_left_arrow -command \
	    "changeBg $t $color"
    $t window create end -window [blend $t.color$i] -padx 3p -pady 1.5p
    incr i
}
$t tag add buttons [blend $t.default] end

button $t.bigB -text "Big borders" -command "textWindBigB $t" \
  -cursor top_left_arrow
button $t.smallB -text "Small borders" -command "textWindSmallB $t" \
171
172
173
174
175
176
177








178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
$t window create end -window [blend $t.bigH]
$t window create end -window [blend $t.smallH]
$t window create end -window [blend $t.bigP]
$t window create end -window [blend $t.smallP]

$t insert end "\n\nFinally, images fit comfortably in text widgets too:"









$t image create end -image \
    [image create photo -file [file join $tk_demoDirectory images ouster.png]]

proc textWindBigB w {
    $w configure -borderwidth 15
}

proc textWindBigH w {
    $w configure -highlightthickness 15
}

proc textWindBigP w {
    $w configure -padx 15 -pady 15
}

proc textWindSmallB w {
    $w configure -borderwidth $::text_normal(border)
}

proc textWindSmallH w {







>
>
>
>
>
>
>
>
|
<


|



|



|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
$t window create end -window [blend $t.bigH]
$t window create end -window [blend $t.smallH]
$t window create end -window [blend $t.bigP]
$t window create end -window [blend $t.smallP]

$t insert end "\n\nFinally, images fit comfortably in text widgets too:"

image create photo img -file [file join $tk_demoDirectory images ouster.png]

# Create a copy of the image just created, magnified according to the
# display's DPI scaling level.  Since the zooom factor must be an integer,
# the copy will only be effectively magnified if $tk::scalingPct >= 200.
image create photo img2
img2 copy img -zoom [expr {$tk::scalingPct / 100}]

$t image create end -image img2


proc textWindBigB w {
    $w configure -borderwidth 12p
}

proc textWindBigH w {
    $w configure -highlightthickness 12p
}

proc textWindBigP w {
    $w configure -padx 12p -pady 12p
}

proc textWindSmallB w {
    $w configure -borderwidth $::text_normal(border)
}

proc textWindSmallH w {
339
340
341
342
343
344
345
346
347
348
349
350
351
	    destroy .twind.peer
	} else {
	    set parent [winfo parent $textW]
	    set w [winfo parent $parent]
	    set t [$textW peer create $w.peer \
	      -yscrollcommand "$w.scroll set"]
	    $t tag configure peer_warning -font boldFont
	    $w.pane add $t
	}
    } else {
        return
    }
}







|





346
347
348
349
350
351
352
353
354
355
356
357
358
	    destroy .twind.peer
	} else {
	    set parent [winfo parent $textW]
	    set w [winfo parent $parent]
	    set t [$textW peer create $w.peer \
	      -yscrollcommand "$w.scroll set"]
	    $t tag configure peer_warning -font boldFont
	    $w.pane add $t -stretch always
	}
    } else {
        return
    }
}

Changes to library/demos/unicodeout.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# unicodeout.tcl --
#
# This demonstration script shows how you can produce output (in label
# widgets) using many different alphabets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .unicodeout
catch {destroy $w}
toplevel $w
wm title $w "Unicode Label Demonstration"
wm iconname $w "unicodeout"
positionWindow $w









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# unicodeout.tcl --
#
# This demonstration script shows how you can produce output (in label
# widgets) using many different alphabets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .unicodeout
catch {destroy $w}
toplevel $w
wm title $w "Unicode Label Demonstration"
wm iconname $w "unicodeout"
positionWindow $w

Changes to library/demos/vscale.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




# vscale.tcl --
#
# This demonstration script shows an example with a vertical scale.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .vscale
catch {destroy $w}
toplevel $w
wm title $w "Vertical Scale Demonstration"
wm iconname $w "vscale"
positionWindow $w

label $w.msg -font $font -wraplength 3.5i -justify left -text "An arrow and a vertical scale are displayed below.  If you click or drag mouse button 1 in the scale, you can change the size of the arrow."
pack $w.msg -side top -padx .5c

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 10
pack $w.frame

scale $w.frame.scale -orient vertical -length 284 -from 0 -to 250 \
	-command "setHeight $w.frame.canvas" -tickinterval 50
canvas $w.frame.canvas -width 50 -height 50 -bd 0 -highlightthickness 0
$w.frame.canvas create polygon 0 0 1 1 2 2 -fill SeaGreen3 -tags poly
$w.frame.canvas create line 0 0 1 1 2 2 0 0 -fill black -tags line
frame $w.frame.right -borderwidth 15
pack $w.frame.scale -side left -anchor ne
pack $w.frame.canvas -side left -anchor nw -fill y
$w.frame.scale set 75

proc setHeight {w height} {
    incr height 21
    set y2 [expr {$height - 30}]
    if {$y2 < 21} {
	set y2 21
    }
    $w coords poly 15 20 35 20 35 $y2 45 $y2 25 $height 5 $y2 15 $y2 15 20
    $w coords line 15 20 35 20 35 $y2 45 $y2 25 $height 5 $y2 15 $y2 15 20
}












|















|


|

|


|












|
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# vscale.tcl --
#
# This demonstration script shows an example with a vertical scale.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require tk

set w .vscale
catch {destroy $w}
toplevel $w
wm title $w "Vertical Scale Demonstration"
wm iconname $w "vscale"
positionWindow $w

label $w.msg -font $font -wraplength 3.5i -justify left -text "An arrow and a vertical scale are displayed below.  If you click or drag mouse button 1 in the scale, you can change the size of the arrow."
pack $w.msg -side top -padx .5c

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.frame -borderwidth 7.5p
pack $w.frame

scale $w.frame.scale -orient vertical -length 213p -from 0 -to 250 \
	-command "setHeight $w.frame.canvas" -tickinterval 50
canvas $w.frame.canvas -width 37.5p -height 37.5p -bd 0 -highlightthickness 0
$w.frame.canvas create polygon 0 0 1 1 2 2 -fill SeaGreen3 -tags poly
$w.frame.canvas create line 0 0 1 1 2 2 0 0 -fill black -tags line
frame $w.frame.right -borderwidth 11.25p
pack $w.frame.scale -side left -anchor ne
pack $w.frame.canvas -side left -anchor nw -fill y
$w.frame.scale set 75

proc setHeight {w height} {
    incr height 21
    set y2 [expr {$height - 30}]
    if {$y2 < 21} {
	set y2 21
    }
    $w coords poly 15 20 35 20 35 $y2 45 $y2 25 $height 5 $y2 15 $y2 15 20
    $w coords line 15 20 35 20 35 $y2 45 $y2 25 $height 5 $y2 15 $y2 15 20

    set scaleFactor [expr {$tk::scalingPct / 100.0}]
    $w scale poly 0 0 $scaleFactor $scaleFactor
    $w scale line 0 0 $scaleFactor $scaleFactor
}

Changes to library/demos/widget.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# widget --
# This script demonstrates the various widgets provided by Tk, along with many
# of the features of the Tk toolkit. This file only contains code to generate
# the main window for the application, which invokes individual
# demonstrations. The code for the actual demonstrations is contained in
# separate ".tcl" files is this directory, which are sourced by this script as
# needed.

package require Tk	8.5
package require msgcat

eval destroy [winfo child .]
set tk_demoDirectory [file join [pwd] [file dirname [info script]]]
::msgcat::mcload $tk_demoDirectory
namespace import ::msgcat::mc
wm title . [mc "Widget Demonstration"]
if {[tk windowingsystem] eq "x11"} {
    # This won't work everywhere, but there's no other way in core Tk at the
    # moment to display a coloured icon.












|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# widget --
# This script demonstrates the various widgets provided by Tk, along with many
# of the features of the Tk toolkit. This file only contains code to generate
# the main window for the application, which invokes individual
# demonstrations. The code for the actual demonstrations is contained in
# separate ".tcl" files is this directory, which are sourced by this script as
# needed.

package require tk
package require msgcat

destroy {*}[winfo children .]
set tk_demoDirectory [file join [pwd] [file dirname [info script]]]
::msgcat::mcload $tk_demoDirectory
namespace import ::msgcat::mc
wm title . [mc "Widget Demonstration"]
if {[tk windowingsystem] eq "x11"} {
    # This won't work everywhere, but there's no other way in core Tk at the
    # moment to display a coloured icon.
53
54
55
56
57
58
59
60
61



62




63
64
65
66
67
68
69




70
71
72
73
74





75
76
77
78
79
80
81




82







83
84

85
86
87
88
89
90
91
92
93
94
95
96

97



98






99
100






101
102
103
104
105
106
107
        font create varsFont   -family Helvetica -size 14
    }
}

set widgetDemo 1
set font mainFont

image create photo ::img::refresh -format GIF -data {
    R0lGODlhEAAQAJEDAP///wAAACpnKv///yH5BAEAAAMALAAAAAAQABAAAAI63IKp



    xgcPH2ouwgBCw1HIxHCQ4F3hSJKmwZXqWrmWxj7lKJ2dndcon9EBUq+gz3brVXAR




    2tICU0gXBQA7
}

image create photo ::img::view -format GIF -data {
    R0lGODlhEAAQAKIHAP///wwMDAAAAMDAwNnZ2SYmJmZmZv///yH5BAEAAAcALAAA
    AAAQABAAAANMKLos90+ASamDRxJCgw9YVnlDOXiQBgRDBRgHKE6sW8QR3doPKK27
    yg33q/GIOhdg6OsEJzeZykiBSUcs06e56Xx6np8ScIkFGuhQAgA7




}

image create photo ::img::delete -format GIF -data {
    R0lGODlhEAAQAIABAIQAAP///yH5BAEAAAEALAAAAAAQABAAAAIjjI+pmwAc3HGy
    PUSvqYpuvWQg40FfSVacBa5nN6JYDI3mzRQAOw==





}

image create photo ::img::print -format GIF -data {
    R0lGODlhEAAQALMKAAAAAP///52VunNkl8C82Yl+qldBgq+pyrOzs1fYAP///wAA
    AAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARGUMlJKwU4AztB+ODGeUiJ
    fGLlgeEYmGWQXmx7aXgmAUTv/74N4EAsGhOJg1DAbDqbwoJ0Sp0KB9isNis0eL/g
    ryhH5pgnEQA7




}








# Note that this is run through the message catalog! This is because this is

# actually an image of a word.
image create photo ::img::new -format PNG -data [mc {
    iVBORw0KGgoAAAANSUhEUgAAAB4AAAAOCAYAAAA45qw5AAACMElEQVR4AeVTAwxd
    QRCc2tZHGtQ2w9q2bdsOa9u2bUW1bdt2Z372JZe6DapJLqtb3h7+T8yKi5j4CsYD
    EUQXxETclT7kWOlH2VV+tFkdQHPSwksSISF+BauCqL0qgOcMWgGfgEkaMsHxqUBk
    3plE/sOnh/qDPAPJH/CKFBivGHWzFwBRnHhlqbu1Mh6CoFNnC/JshQ9p4YC2lrKt
    DCAV+THiVejyhMjAbrNSrroiEfKR9g7ZfCgOog8QfnUQV62wAk68ndQ9ZbyoWO1H
    Y6eDY1LCQL6a9ApOp9Hi1T0+gQq2JKMlky/oTKQliKWxEZvyG575kpW4pl1aZnQK
    CLOVt45Lkp8uXp2SL8KO6uitNTZLdpK6s+I/eZbhpmsmWeOGOVQNKYLITzpKPAO3
    tY7LSNZ7ccSLxX9y3uuOxRkg3dKESMoCHvL+GRVCutXsB3guLgDCeXOv4iWWkvwG
    BaS+PmlpK6SI9ApI2oC2UtrwZQEkhkH+NtolVlQXJl1I+QltuU3XEc721bIRFpa8
    IA5iqTo6vNNWmkNBLQbPeXwF2g17Q94nTQAfY3YzeY+WSu8MDzQ2kpELUhSGJUHE

    0zeR3rY1L+Xl5G/re+jbiK6KhThwwInsts1fbMUUcpZszKeVtggZEiGdZDe5AtHh



    7vL4CGiRvvKPS8FAvq9Nr4ZkFadR2y6kggu1z4vlyIbBp6BugQ8JLEg4bTkD9eMZ






    QZ8hpJ3VvTtuvbWrY/ElvP/9R+Aj3603+iE3fkEAAAAASUVORK5CYII=
}]







#----------------------------------------------------------------
# The code below creates the main window, consisting of a menu bar and a text
# widget that explains how to use the program, plus lists all of the demos as
# hypertext items.
#----------------------------------------------------------------








|
|
>
>
>
|
>
>
>
>
|


|
<
<
<
>
>
>
>


|
<
<
>
>
>
>
>


|
<
<
<
<
>
>
>
>
|
>
>
>
>
>
>
>
|
|
>
|
|
<
<
<
<
<
<
<
<
|
<
>
|
>
>
>
|
>
>
>
>
>
>
|
<
>
>
>
>
>
>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73



74
75
76
77
78
79
80


81
82
83
84
85
86
87
88




89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105








106

107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
        font create varsFont   -family Helvetica -size 14
    }
}

set widgetDemo 1
set font mainFont

# The SVG images used below are based on some icons provided by the
# official open source SVG icon library for the Bootstrap project,
# licensed under the MIT license (https://opensource.org/licenses/MIT).
#
# See https://github.com/twbs/icons.

set viewData {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z" fill="#000000"/>
    </svg>
}

set refreshData {



    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="M11 5.466V4H5a4 4 0 0 0-3.584 5.777.5.5 0 1 1-.896.446A5 5 0 0 1 5 3h6V1.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384l-2.36 1.966a.25.25 0 0 1-.41-.192Zm3.81.086a.5.5 0 0 1 .67.225A5 5 0 0 1 11 13H5v1.466a.25.25 0 0 1-.41.192l-2.36-1.966a.25.25 0 0 1 0-.384l2.36-1.966a.25.25 0 0 1 .41.192V12h6a4 4 0 0 0 3.585-5.777.5.5 0 0 1 .225-.67Z" fill="#000000"/>
    </svg>
}

set printData {


    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="M2.5 8a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1z" fill="#000000"/>
     <path d="M5 1a2 2 0 0 0-2 2v2H2a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h1v1a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-1h1a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-1V3a2 2 0 0 0-2-2H5zM4 3a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2H4V3zm1 5a2 2 0 0 0-2 2v1H2a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v-1a2 2 0 0 0-2-2H5zm7 2v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1z" fill="#000000"/>
    </svg>
}

proc images {arg} {




    set fgColor [ttk::style lookup . -foreground {} black]
    lassign [winfo rgb . $fgColor] r g b
    set fgColor [format "#%02x%02x%02x" \
	    [expr {$r >> 8}] [expr {$g >> 8}] [expr {$b >> 8}]]

    foreach action {view refresh print} {
	upvar ${action}Data imgData
	for {set data $imgData; set startIdx 0} \
		{[set idx1 [string first "#000000" $data $startIdx]] >= 0} \
		{set startIdx [expr {$idx1 + 7}]} {
	    set idx2 [expr {$idx1 + 6}]
	    set data [string replace $data $idx1 $idx2 $fgColor]
	}

	switch $arg {
	    create {
		image create photo ::img::$action -format $::tk::svgFmt \








			-data $data

	    }
	    configure { ::img::$action configure -data $data }
	}
    }
}

images create
set mainClass [winfo class .]
foreach event {<<ThemeChanged>> <<LightAqua>> <<DarkAqua>>} {
    bind $mainClass $event { images configure }
}
unset mainClass event


image create photo ::img::delete -format $::tk::svgFmt -data {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z" fill="#d00000"/>
    </svg>
}

#----------------------------------------------------------------
# The code below creates the main window, consisting of a menu bar and a text
# widget that explains how to use the program, plus lists all of the demos as
# hypertext items.
#----------------------------------------------------------------

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

ttk::frame .statusBar
ttk::label .statusBar.lab -text "   " -anchor w
if {[tk windowingsystem] eq "aqua"} {
    ttk::separator .statusBar.sep
    pack .statusBar.sep -side top -expand yes -fill x -pady 0
}
pack .statusBar.lab -side left -padx 2 -expand yes -fill both
if {[tk windowingsystem] ne "aqua"} {
    ttk::sizegrip .statusBar.foo
    pack .statusBar.foo -side left -padx 2
}
pack .statusBar -side bottom -fill x -pady 2

set textheight 30
catch {
    set textheight [expr {
	([winfo screenheight .] * 0.7) /
	[font metrics mainFont -displayof . -linespace]
    }]
}

ttk::frame .textFrame
ttk::scrollbar .s -orient vertical -command {.t yview} -takefocus 1
pack .s -in .textFrame -side right -fill y
text .t -yscrollcommand {.s set} -wrap word -width 70 -height $textheight \
	-font mainFont -setgrid 1 -highlightthickness 0 \
	-padx 4 -pady 2 -takefocus 0
pack .t -in .textFrame -expand y -fill both -padx 1
pack .textFrame -expand yes -fill both
if {[tk windowingsystem] eq "aqua"} {
    pack configure .statusBar.lab -padx {10 18} -pady {4 6}
    pack configure .statusBar -pady 0
    .t configure -padx 10 -pady 0
}







|


|

|














|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

ttk::frame .statusBar
ttk::label .statusBar.lab -text "   " -anchor w
if {[tk windowingsystem] eq "aqua"} {
    ttk::separator .statusBar.sep
    pack .statusBar.sep -side top -expand yes -fill x -pady 0
}
pack .statusBar.lab -side left -padx 1.5p -expand yes -fill both
if {[tk windowingsystem] ne "aqua"} {
    ttk::sizegrip .statusBar.foo
    pack .statusBar.foo -side left -padx 1.5p
}
pack .statusBar -side bottom -fill x -pady 1.5p

set textheight 30
catch {
    set textheight [expr {
	([winfo screenheight .] * 0.7) /
	[font metrics mainFont -displayof . -linespace]
    }]
}

ttk::frame .textFrame
ttk::scrollbar .s -orient vertical -command {.t yview} -takefocus 1
pack .s -in .textFrame -side right -fill y
text .t -yscrollcommand {.s set} -wrap word -width 70 -height $textheight \
	-font mainFont -setgrid 1 -highlightthickness 0 \
	-padx 3p -pady 1.5p -takefocus 0
pack .t -in .textFrame -expand y -fill both -padx 1
pack .textFrame -expand yes -fill both
if {[tk windowingsystem] eq "aqua"} {
    pack configure .statusBar.lab -padx {10 18} -pady {4 6}
    pack configure .statusBar -pady 0
    .t configure -padx 10 -pady 0
}
196
197
198
199
200
201
202





203
204
205
206
207
208
209
	-foreground #303080 -underline 1
    if {[tk windowingsystem] eq "aqua"} {
	.t tag configure demo -foreground systemLinkColor
	.t tag configure visited -foreground purple
    }
    .t tag configure hot -foreground red -underline 1
}





.t tag bind demo <ButtonRelease-1> {
    invoke [.t index {@%x,%y}]
}
set lastLine ""
.t tag bind demo <Enter> {
    set lastLine [.t index {@%x,%y linestart}]
    .t tag add hot "$lastLine +1 chars" "$lastLine lineend -1 chars"







>
>
>
>
>







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
	-foreground #303080 -underline 1
    if {[tk windowingsystem] eq "aqua"} {
	.t tag configure demo -foreground systemLinkColor
	.t tag configure visited -foreground purple
    }
    .t tag configure hot -foreground red -underline 1
}

# The tag "new" must be the one having the highest priority.
#
.t tag configure new -foreground #c00000 -underline 0 -font boldFont

.t tag bind demo <ButtonRelease-1> {
    invoke [.t index {@%x,%y}]
}
set lastLine ""
.t tag bind demo <Enter> {
    set lastLine [.t index {@%x,%y linestart}]
    .t tag add hot "$lastLine +1 chars" "$lastLine lineend -1 chars"
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
		    set demoCount 0
		}
		demo {
		    set description [lassign $values name]
		    .t insert end "[incr demoCount]. [mc $description]" \
			    [list demo demo-$name]
		    if {$new} {
			.t image create end -image ::img::new -padx 5
			set new 0
		    }
		    .t insert end " \n " demospace
		}
		new {
		    set new 1
		}







|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
		    set demoCount 0
		}
		demo {
		    set description [lassign $values name]
		    .t insert end "[incr demoCount]. [mc $description]" \
			    [list demo demo-$name]
		    if {$new} {
			.t insert end " [mc NEW]" new
			set new 0
		    }
		    .t insert end " \n " demospace
		}
		new {
		    set new 1
		}
325
326
327
328
329
330
331
332














333
334
335
336
337
338
339
    @@demo radio	Radio-buttons (select one of a group)
    @@demo puzzle	A 15-puzzle game made out of buttons
    @@demo icon		Iconic buttons that use bitmaps
    @@demo image1	Two labels displaying images
    @@demo image2	A simple user interface for viewing images
    @@demo labelframe	Labelled frames
    @@demo ttkbut	The simple Themed Tk widgets















    @@subtitle	Listboxes and Trees
    @@demo states	The 50 states
    @@demo colors	Colors: change the color scheme for the application
    @@demo sayings	A collection of famous and infamous sayings
    @@demo mclist	A multi-column list of countries
    @@demo tree		A directory browser tree








|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
    @@demo radio	Radio-buttons (select one of a group)
    @@demo puzzle	A 15-puzzle game made out of buttons
    @@demo icon		Iconic buttons that use bitmaps
    @@demo image1	Two labels displaying images
    @@demo image2	A simple user interface for viewing images
    @@demo labelframe	Labelled frames
    @@demo ttkbut	The simple Themed Tk widgets
}

if {[tk windowingsystem] eq "aqua"} {
    addFormattedText {
	@@subtitle Mac-Specific Widgets and Window Styles
	@@new
	@@demo mac_styles	Special widgets for macOS
	@@new
	@@demo mac_wm	Window styles for macOS
	@@new
	@@demo mac_tabs	Tabbed Windows on macOS
    }
}

addFormattedText {
    @@subtitle	Listboxes and Trees
    @@demo states	The 50 states
    @@demo colors	Colors: change the color scheme for the application
    @@demo sayings	A collection of famous and infamous sayings
    @@demo mclist	A multi-column list of countries
    @@demo tree		A directory browser tree

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389




390
391
392
393
394
395
396
397
398
399
400


401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    @@demo floor	A building floor plan
    @@demo cscroll	A simple scrollable canvas
    @@demo knightstour  A Knight's tour of the chess board

    @@subtitle	Scales and Progress Bars
    @@demo hscale	Horizontal scale
    @@demo vscale	Vertical scale
    @@new
    @@demo ttkscale	Themed scale linked to a label with traces
    @@demo ttkprogress	Progress bar

    @@subtitle	Paned Windows and Notebooks
    @@demo paned1	Horizontal paned window
    @@demo paned2	Vertical paned window
    @@demo ttkpane	Themed nested panes
    @@demo ttknote	Notebook widget

    @@subtitle	Menus and Toolbars
    @@demo menu		Menus and cascades (sub-menus)
    @@demo menubu	Menu-buttons
    @@demo ttkmenu	Themed menu buttons
    @@demo toolbar	Themed toolbar

    @@subtitle	Common Dialogs
    @@demo msgbox	Message boxes
    @@demo filebox	File selection dialog
    @@demo clrpick	Color picker
    @@demo fontchoose	Font selection dialog





    @@subtitle	Animation
    @@demo anilabel	Animated labels
    @@demo aniwave	Animated wave
    @@demo pendulum	Pendulum simulation
    @@demo goldberg	A celebration of Rube Goldberg

    @@subtitle	Miscellaneous
    @@demo bitmap	The built-in bitmaps
    @@demo dialog1	A dialog box with a local grab
    @@demo dialog2	A dialog box with a global grab


}

##############################################################################

.t configure -state disabled
focus .s

# addSeeDismiss --
# Add "See Code" and "Dismiss" button frame, with optional "See Vars"
#
# Arguments:
# w -		The name of the frame to use.

proc addSeeDismiss {w show {vars {}} {extra {}}} {
    ## See Code / Dismiss buttons
    ttk::frame $w
    ttk::separator $w.sep
    #ttk::frame $w.sep -height 2 -relief sunken

    grid $w.sep -columnspan 4 -row 0 -sticky ew -pady 2
    ttk::button $w.dismiss -text [mc "Dismiss"] \
	-image ::img::delete -compound left \
	-command [list destroy [winfo toplevel $w]]
    ttk::button $w.code -text [mc "See Code"] \
	-image ::img::view -compound left \
	-command [list showCode $show]
    set buttons [list x $w.code $w.dismiss]
    if {[llength $vars]} {
	ttk::button $w.vars -text [mc "See Variables"] \
	    -image ::img::view -compound left \
	    -command [concat [list showVars $w.dialog] $vars]
	set buttons [linsert $buttons 1 $w.vars]
    }
    if {$extra ne ""} {
	set buttons [linsert $buttons 1 [uplevel 1 $extra]]
    }
    grid {*}$buttons -padx 4 -pady 4
    grid columnconfigure $w 0 -weight 1
    if {[tk windowingsystem] eq "aqua"} {
	foreach b [lrange $buttons 1 end] {$b configure -takefocus 0}
	grid configure $w.sep -pady 0
	grid configure {*}$buttons -pady {10 12}
	grid configure [lindex $buttons 1] -padx {16 4}
	grid configure [lindex $buttons end] -padx {4 18}







<




















>
>
>
>











>
>
















<

>
|
















|







406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
    @@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

    @@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
    @@new
    @@demo print        Printing from canvas and text widgets

    @@subtitle	Animation
    @@demo anilabel	Animated labels
    @@demo aniwave	Animated wave
    @@demo pendulum	Pendulum simulation
    @@demo goldberg	A celebration of Rube Goldberg

    @@subtitle	Miscellaneous
    @@demo bitmap	The built-in bitmaps
    @@demo dialog1	A dialog box with a local grab
    @@demo dialog2	A dialog box with a global grab
    @@new
    @@demo windowicons  Window icons and badges
}

##############################################################################

.t configure -state disabled
focus .s

# addSeeDismiss --
# Add "See Code" and "Dismiss" button frame, with optional "See Vars"
#
# Arguments:
# w -		The name of the frame to use.

proc addSeeDismiss {w show {vars {}} {extra {}}} {
    ## See Code / Dismiss buttons
    ttk::frame $w

    #ttk::frame $w.sep -height 2 -relief sunken
    ttk::separator $w.sep
    grid $w.sep -columnspan 4 -row 0 -sticky ew -pady 1.5p
    ttk::button $w.dismiss -text [mc "Dismiss"] \
	-image ::img::delete -compound left \
	-command [list destroy [winfo toplevel $w]]
    ttk::button $w.code -text [mc "See Code"] \
	-image ::img::view -compound left \
	-command [list showCode $show]
    set buttons [list x $w.code $w.dismiss]
    if {[llength $vars]} {
	ttk::button $w.vars -text [mc "See Variables"] \
	    -image ::img::view -compound left \
	    -command [concat [list showVars $w.dialog] $vars]
	set buttons [linsert $buttons 1 $w.vars]
    }
    if {$extra ne ""} {
	set buttons [linsert $buttons 1 [uplevel 1 $extra]]
    }
    grid {*}$buttons -padx 3p -pady 3p
    grid columnconfigure $w 0 -weight 1
    if {[tk windowingsystem] eq "aqua"} {
	foreach b [lrange $buttons 1 end] {$b configure -takefocus 0}
	grid configure $w.sep -pady 0
	grid configure {*}$buttons -pady {10 12}
	grid configure [lindex $buttons 1] -padx {16 4}
	grid configure [lindex $buttons end] -padx {4 18}
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

    set b [ttk::frame $w.frame]
    grid $b -sticky news
    set f [ttk::labelframe $b.title -text [mc "Variable values:"]]
    foreach var $args {
	ttk::label $f.n$var -text "$var:" -anchor w
	ttk::label $f.v$var -textvariable $var -anchor w
	grid $f.n$var $f.v$var -padx 2 -pady 2 -sticky w
    }
    ttk::button $b.ok -text [mc "OK"] \
	-command [list destroy $w] -default active
    bind $w <Return> [list $b.ok invoke]
    bind $w <Escape> [list $b.ok invoke]

    grid $f -sticky news -padx 4
    grid $b.ok -sticky e -padx 4 -pady {6 4}
    if {[tk windowingsystem] eq "aqua"} {
	$b.ok configure -takefocus 0
	grid configure $b.ok -pady {10 12} -padx {16 18}
	grid configure $f -padx 10 -pady {10 0}
    }
    grid columnconfig $f 1 -weight 1
    grid rowconfigure $f 100 -weight 1







|






|
|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

    set b [ttk::frame $w.frame]
    grid $b -sticky news
    set f [ttk::labelframe $b.title -text [mc "Variable values:"]]
    foreach var $args {
	ttk::label $f.n$var -text "$var:" -anchor w
	ttk::label $f.v$var -textvariable $var -anchor w
	grid $f.n$var $f.v$var -padx 1.5p -pady 1.5p -sticky w
    }
    ttk::button $b.ok -text [mc "OK"] \
	-command [list destroy $w] -default active
    bind $w <Return> [list $b.ok invoke]
    bind $w <Escape> [list $b.ok invoke]

    grid $f -sticky news -padx 3p
    grid $b.ok -sticky e -padx 3p -pady {4.5p 3p}
    if {[tk windowingsystem] eq "aqua"} {
	$b.ok configure -takefocus 0
	grid configure $b.ok -pady {10 12} -padx {16 18}
	grid configure $f -padx 10 -pady {10 0}
    }
    grid columnconfig $f 1 -weight 1
    grid rowconfigure $f 100 -weight 1
571
572
573
574
575
576
577
578

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
	toplevel $top
	if {[tk windowingsystem] eq "x11"} {wm attributes $top -type dialog}

	set t [frame $top.f]
	set text [text $t.text -font fixedFont -height 24 -wrap word \
		      -xscrollcommand [list $t.xscroll set] \
		      -yscrollcommand [list $t.yscroll set] \
		      -setgrid 1 -highlightthickness 0 -pady 2 -padx 3]

	ttk::scrollbar $t.xscroll -command [list $t.text xview] \
	    -orient horizontal
	ttk::scrollbar $t.yscroll -command [list $t.text yview] \
	    -orient vertical

	grid $t.text $t.yscroll -sticky news
	#grid $t.xscroll
	grid rowconfigure $t 0 -weight 1
	grid columnconfig $t 0 -weight 1

	set btns [ttk::frame $top.btns]
	ttk::separator $btns.sep
	grid $btns.sep -columnspan 4 -row 0 -sticky ew -pady 2
	ttk::button $btns.dismiss -text [mc "Dismiss"] \
	    -default active -command [list destroy $top] \
	    -image ::img::delete -compound left
	ttk::button $btns.print   -text [mc "Print Code"] \
	    -command [list printCode $text $file] \
	    -image ::img::print -compound left
	ttk::button $btns.rerun   -text [mc "Rerun Demo"] \
	    -command [list evalShowCode $text] \
	    -image ::img::refresh -compound left
	set buttons [list x $btns.rerun $btns.print $btns.dismiss]
	grid {*}$buttons -padx 4 -pady 4
	grid columnconfigure $btns 0 -weight 1
	if {[tk windowingsystem] eq "aqua"} {
	    foreach b [lrange $buttons 1 end] {$b configure -takefocus 0}
	    grid configure $btns.sep -pady 0
	    grid configure {*}$buttons -pady {10 12}
	    grid configure [lindex $buttons 1] -padx {16 4}
	    grid configure [lindex $buttons end] -padx {4 18}







|
>












|










|







620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
	toplevel $top
	if {[tk windowingsystem] eq "x11"} {wm attributes $top -type dialog}

	set t [frame $top.f]
	set text [text $t.text -font fixedFont -height 24 -wrap word \
		      -xscrollcommand [list $t.xscroll set] \
		      -yscrollcommand [list $t.yscroll set] \
		      -setgrid 1 -highlightthickness 0 -padx 3p -pady 1.5p \
		      -tabstyle wordprocessor]
	ttk::scrollbar $t.xscroll -command [list $t.text xview] \
	    -orient horizontal
	ttk::scrollbar $t.yscroll -command [list $t.text yview] \
	    -orient vertical

	grid $t.text $t.yscroll -sticky news
	#grid $t.xscroll
	grid rowconfigure $t 0 -weight 1
	grid columnconfig $t 0 -weight 1

	set btns [ttk::frame $top.btns]
	ttk::separator $btns.sep
	grid $btns.sep -columnspan 4 -row 0 -sticky ew -pady 1.5p
	ttk::button $btns.dismiss -text [mc "Dismiss"] \
	    -default active -command [list destroy $top] \
	    -image ::img::delete -compound left
	ttk::button $btns.print   -text [mc "Print Code"] \
	    -command [list printCode $text $file] \
	    -image ::img::print -compound left
	ttk::button $btns.rerun   -text [mc "Rerun Demo"] \
	    -command [list evalShowCode $text] \
	    -image ::img::refresh -compound left
	set buttons [list x $btns.rerun $btns.print $btns.dismiss]
	grid {*}$buttons -padx 3p -pady 3p
	grid columnconfigure $btns 0 -weight 1
	if {[tk windowingsystem] eq "aqua"} {
	    foreach b [lrange $buttons 1 end] {$b configure -takefocus 0}
	    grid configure $btns.sep -pady 0
	    grid configure {*}$buttons -pady {10 12}
	    grid configure [lindex $buttons 1] -padx {16 4}
	    grid configure [lindex $buttons end] -padx {4 18}
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
    } 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 --
# Prints the source code currently displayed in the See Code dialog. Much
# thanks to Arjen Markus for this.
#
# Arguments:
# w -		Name of text widget containing code to print
# file -		Name of the original file (implicitly for title)

proc printCode {w file} {
    set code [$w get 1.0 end-1c]

    set dir "."
    if {[info exists ::env(HOME)]} {
	set dir "$::env(HOME)"
    }
    if {[info exists ::env(TMP)]} {
	set dir $::env(TMP)
    }
    if {[info exists ::env(TEMP)]} {
	set dir $::env(TEMP)
    }

    set filename [file join $dir "tkdemo-$file"]
    set outfile [open $filename "w"]
    puts $outfile $code
    close $outfile

    switch -- $::tcl_platform(platform) {
	unix {
	    if {[catch {exec lp -c $filename} msg]} {
		tk_messageBox -title "Print spooling failure" \
			-message "Print spooling probably failed: $msg"
	    }
	}
	windows {
	    if {[catch {PrintTextWin32 $filename} msg]} {
		tk_messageBox -title "Print spooling failure" \
			-message "Print spooling probably failed: $msg"
	    }
	}
	default {
	    tk_messageBox -title "Operation not Implemented" \
		    -message "Wow! Unknown platform: $::tcl_platform(platform)"
	}
    }

    #
    # Be careful to throw away the temporary file in a gentle manner ...
    #
    if {[file exists $filename]} {
	catch {file delete $filename}
    }
}

# PrintTextWin32 --
#    Print a file under Windows using all the "intelligence" necessary
#
# Arguments:
# filename -		Name of the file
#
# Note:
# Taken from the Wiki page by Keith Vetter, "Printing text files under
# Windows".
# Note:
# Do not execute the command in the background: that way we can dispose of the
# file smoothly.
#
proc PrintTextWin32 {filename} {
    package require registry
    set app [auto_execok notepad.exe]
    set pcmd "$app /p %1"
    catch {
	set app [registry get {HKEY_CLASSES_ROOT\.txt} {}]
	set pcmd [registry get \
		{HKEY_CLASSES_ROOT\\$app\\shell\\print\\command} {}]
    }

    regsub -all {%1} $pcmd $filename pcmd
    puts $pcmd

    regsub -all {\\} $pcmd {\\\\} pcmd
    set command "[auto_execok start] /min $pcmd"
    eval exec $command
}

# tkAboutDialog --
#
#	Pops up a message box with an "about" message
#
proc tkAboutDialog {} {
    tk_messageBox -icon info -type ok -title [mc "About Widget Demo"] \
	    -message [mc "Tk widget demonstration application"] -detail \
"[mc "Copyright © %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright © %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright © %s" {2001-2009 Donal K. Fellows}]
[mc "Copyright © %s" {2002-2007 Daniel A. Steffen}]"

}

# Local Variables:
# mode: tcl
# End:







|















<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












|
>





670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692

693








































































694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    } 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 --
# Prints the source code currently displayed in the See Code dialog. Much
# thanks to Arjen Markus for this.
#
# Arguments:
# w -		Name of text widget containing code to print
# file -		Name of the original file (implicitly for title)

proc printCode {w file} {

    tk print $w








































































}

# tkAboutDialog --
#
#	Pops up a message box with an "about" message
#
proc tkAboutDialog {} {
    tk_messageBox -icon info -type ok -title [mc "About Widget Demo"] \
	    -message [mc "Tk widget demonstration application"] -detail \
"[mc "Copyright © %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright © %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright © %s" {2001-2009 Donal K. Fellows}]
[mc "Copyright © %s" {2002-2007 Daniel A. Steffen}]
[mc "Copyright © %s" {2021 Kevin Walzer}]"
}

# Local Variables:
# mode: tcl
# End:

Added library/demos/windowicons.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
# windowicons.tcl --
#
# This demonstration script showcases the wm iconphoto and wm iconbadge commands.
#

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

set w .windowicons
destroy $w
toplevel $w
wm title $w "Window Icon Demonstration"
positionWindow $w

## See Code / Dismiss buttons
pack [addSeeDismiss $w.buttons $w] -side bottom -fill x

image create photo icon -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGP
    C/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3Cc
    ulE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAArQNAAK0DQEdFIm+AAAJ
    QElEQVRYw+WXW2xdV5nHf/ty7lcf2/FxYsdOnMSNC0HTpDiRKJWAQjWCEQNU
    SEAFfUOiQqrEC2+IxwpemDLSzNBBCCQeQEKqRJgBSikiuGlN22TqhsR27OPL
    8eWc43Pdt7X22osHHydOm4FBPM6Slr69paX9/32Xtb614f/7MP6vC3O5f8L3
    G7HJyZPHBwfz5wrF7HQ6nRwxLTOhQuU4PW+z3eq9Xa+33rq9cms7k8pHjvfS
    3w8wOfk52u1u8oHpiUff897JJ8+dO/nI6LHho6OjQ3ahkMYwTTZ2O2zXutS3
    G/7ayubq7Vtr/7Ve2f7RytLam4ViXq1t/vRvB0ilPsjzz3+LZ5/9j7MzM5Nf
    /8hj5//5H97/YNbK5hkfTFLMxAEQQvD766v0yBGIEBEEuPUGi9dv7lx77cb3
    Vm9vfqc0WNi9evUKWr/xLh3rfuLj45+l0bjM7m768U98/OJ/fulLH/3wiemx
    eCafxRcKw7TJxKC+12RpbYdAx7HsOCrSRNpg+sQQj1w8nS0N5h8JAvm+rWr9
    9ZmZB2qWdZq9vWt/GWBm5im+9rUn6HRGPv7EE4/++2P/eOFkV0FkJTDQgCaX
    TbO1tcV2R2EmCxBJQixs2+R9EwV00MFAceJE2ZiZOT7VaTsPLyxU5orFTK1c
    fphq9bX7A8zOfoV8Ps3c3NsXPvWpD37vc5//0ETNt8gNjDAzlsdAE0vliTCR
    xEhnC2CaRIZNMmZiaonv9mh1PcrDJQZzCfK5OGNjQ8e2tvZO37y5+ctk0naq
    1fn7A4yOnmd5uVp4/PGHn/vylz8xe+zoEIP5JAMpA0OHeK6DG4TEk2li8Tha
    QxRpIg0q6DGUNjg6UuLYSInhYoYoigiCgHQ6TrGYnlpd3Q1ffvk3L128+ITe
    2Hj1XoBLl55menqcbDb1haeeevyrDz102tJaE7ctLBMqG1X23Ag7kcKOJzAA
    DSilCVWEZdmMDaXJJCxSiRimaaK1RkqJ7/uUSlk6Hed0oxG9HI9bm+Pjs2xs
    vIp5AKC15oUX/lA8f/7MF2dnz8YADMNASslypYqrUxSHyqSy+f31hzaRZRpM
    DKVYr+7y4usVri1WWavWCWSIZZkYhoFSIRcuTI1MTAw9OTf33Tu7zz54SCRi
    nD17/Pzs7AMPFQqZPlTE8vo2DlmGhgbo12BffD/8SmukitiuNxHKoDwyzPJG
    nTdXmtiWwdnRNCN5GxWGDA/nOH26/NGpqSfHgPU7AJcuPc0nP/kBrl698YGZ
    mYmMEIJmx6Hn+my0DUZGC6gIzEOnhu4Lh2GEbRocGyxRSO/7c3QgiRuEVOtd
    EvEQrSN8IVEq5MSJ4YlSKX3OMKJ14G4KnnnmM9bkZPk92VyKy3M3eentJjd3
    FUYyjxuEeELt7/NoP+eBVAipCFXEsYE4xcydYFIeSHKynOXhUwM0mh32egH1
    tsdL16oo007kcskHs7kYly49fRcALqby+fQopklkZ4jHY3g6gQgjHF/QcgQd
    V+7DHJoGmnzSQuvD0QGlIsJQkU4luLXR4kgxxcRgjM1mQCyZHrv0sUe4JwKF
    XMmu7/VSXV9xaXqI0YzC8328QOJ4gq4raHQDGt2AtitwfIEbSAwibOvdJ7pS
    CiElR3IxGh2X5Y0GV66v0wnAsq3MN5759L1FqKMoCkQoX19u0QkkD47lKSYi
    Th1NoSLYafu0ehrTNNBaE2mNUop2z+DEUJKBbPxecSEIgoAoUjwwmmZpdZPl
    muL4oIFWkbx8rXIvQMfZ9p2e1xBCstOJcFe6nB1NcWokhW1ZHMkazK90qXXD
    fZFII0NFIBW/XQiZHraoNbsU81mmjhbxfZ8gCAiCgELKQitJGCoIQ6SQO//2
    ze/fm4Kf/Px50dzr3Aoch1Ap2o4kn8tgW/sHynAxzcVTBQYzFp4v6boBjidw
    fcFCpcmPf7/Oz+ZrvPBalb12D9/370DUGk1evr6NacWIfD/yveDmXq3F3Nxz
    dwH+5dkfUq8155rb9dA2QcqQcjFx57DRGgaySR47d4RHZ0pYeh/C9QSOJ3EE
    CGWw3fJZ323j+x6e5xH4Pgu3d6g0FMWUjdvu7bo9/5oK1d0IzM09hwhCGrvN
    ubXFylI2pum4AZXtDqEURFGE1hoNxGMW5ZyB22nS8wQ9r1+QvsDzBc1uQGW7
    jee6eN4+RMfxMdHkYgatWmtur9ZaOnD8TgQMA27c+uH68s3KT8O9BoYBv3pj
    kxuVGo7Tw+1/MAh83lreYm1P9r3fT4XjSVxf4voC1/NwHAfXdXFcB891KGVj
    hO2e16q3fzR2cjQwDPPeZrSx8SqXL2/RqDU2EnH7I8dPjQ8v7Tqs1RwmSzEs
    QoQQSBHw1lKVha0AEUb4IiQQIb4I8YUkkCHTQwa5WIjne9xY2mT+VouRfI7N
    xfVfrK8sfTuRSAavXP3Xd7fjavWPRq1+3TeiQTVcGnh0oHwktlZzmBq0SNsR
    QgiuXLvNL/+nQU/aBFL1xSW+kAghEb5PEkE5q3Bdl7dv72LGCrTXdzf+9Nb8
    N5dXfrG6Wf1jeNDP3nkjigOFWm2xpvx0+tjI8LnMYMnMxQT5eIjruVye36LS
    TRAqRSD3vZdCIqUgEj5R4CEDj2O5kMZei3rHoLXV6Sy88cp3Fhf/ew6IAAGE
    9wOIARmtw9Tu7vKa1yY+Wiqeee+ZYdsi4HdvrjK/HiKUiZQhoZREQhDJAC18
    tPSIhEfouwSuQ9cx2VxpNK/PX/n+4uKvXwQdAAHgA/J+AAaQABJRJOydnVsr
    zZ1O13eMcSuezC61LJzQRgY+KvCJhI+WPpH0IAywIkEhaVIupAhdHS0t3F66
    Nv/iD9bW/nAFtAM4QA9wAXX3RnEvQBoYODSL+fzEmalTsx+emjl3YWjsaMlM
    pcwg0ggZEimFoSNsI8JSCtF1wtpmdWt1aeGVSuW133leYwNoA01gr297BzVw
    v/8CA0gBBaDYtzkw87ns6PhI+czM0JHjp/PFUjmZSmUM07RCKUPP6XVae/Vq
    fbdys1ZbvOX5ja2+ULcP0Opbt18H/G8Ah+shDWQPzVQ/RSnLTGRsO5U0TMuM
    VKjC0PUjLd1+fgPAOxTybl9YcvdC9VcBDobV3x0JINm3MfYbmdX/hu57FfZF
    Dgot6Fe8eqfw3wLwzvVmX9jsvx8AHEAcnn91/BlySEFKTpuCtgAAABN0RVh0
    QXV0aG9yAHdhcnN6YXdpYW5rYQy+S5cAAABYdEVYdENvcHlyaWdodABDQzAg
    UHVibGljIERvbWFpbiBEZWRpY2F0aW9uIGh0dHA6Ly9jcmVhdGl2ZWNvbW1v
    bnMub3JnL3B1YmxpY2RvbWFpbi96ZXJvLzEuMC/G4735AAAAIXRFWHRDcmVh
    dGlvbiBUaW1lADIwMTAtMDMtMjlUMDg6MDg6MzD47LxwAAAAJXRFWHRkYXRl
    OmNyZWF0ZQAyMDIxLTA4LTE1VDIwOjU0OjM5LTA0OjAwNBT3DQAAACV0RVh0
    ZGF0ZTptb2RpZnkAMjAyMS0wOC0xNVQyMDo1NDoxMS0wNDowMDSDBqsAAADI
    elRYdERlc2NyaXB0aW9uAAAY042OwQqCQBCGn6B3GOy+Cl0qTAjEc1HRJVhW
    HXUrd2pmLXr7tDrVpcMP838w/F+wxxxyprsgB2ALclAxtRAbaBirRdB4f5mH
    oTeuJlUxYoly8nRRxHW4HahO30SvmI5Y+CCBF4dPhzg0CYwOLs45GdKfG+sK
    hBuy2H4xUlM1i76+BhcBwwirLj/bAlJqjXXzP9UyxmuHzp8feiknLPW6Q/H9
    moy3yK1oqvROUE2yH99suX45PwEyf2MTOoCNrQAAABl0RVh0U29mdHdhcmUA
    d3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABWdEVYdFNvdXJjZQBodHRwczovL29w
    ZW5jbGlwYXJ0Lm9yZy9kZXRhaWwvMzUyMzMvdGFuZ28taW5ldHJuZXQtd2Vi
    LWJyb3dzZXItYnktd2Fyc3phd2lhbmth5nAuRgAAACB0RVh0VGl0bGUAdGF
    uZ28gaW5ldHJuZXQgd2ViIGJyb3dzZXLyr62TAAAAAElFTkSuQmCC
}

set ::tk::icons::base_icon(.) icon

# Create a copy of the image just created, magnified according to the
# display's DPI scaling level.  Since the zooom factor must be an integer,
# the copy will only be effectively magnified if $tk::scalingPct >= 200.
image create photo icon2
icon2 copy icon -zoom [expr {$tk::scalingPct / 100}]

pack [button $w.i -text "Set Window Icon to Globe" -image icon2 \
        -compound top -command {wm iconphoto . icon}] -fill x -padx 3p
pack [button $w.b -text "Set Badge to 3" -command {wm iconbadge . 3}] \
	-fill x -padx 3p
pack [button $w.e -text "Set Badge to 11" -command {wm iconbadge . 11}] \
	-fill x -padx 3p
pack [button $w.f -text "Reset Badge" -command {wm iconbadge . ""}] \
	-fill x -padx 3p

Changes to library/dialog.tcl.

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	button $w.button$i -text $but -command [list set ::tk::Priv(button) $i]
	if {$i == $default} {
	    $w.button$i configure -default active
	} else {
	    $w.button$i configure -default normal
	}
	grid $w.button$i -in $w.bot -column $i -row 0 -sticky ew \
		-padx 10 -pady 4
	grid columnconfigure $w.bot $i
	# We boost the size of some Mac buttons for l&f
	if {$windowingsystem eq "aqua"} {
	    set tmp [string tolower $but]
	    if {$tmp eq "ok" || $tmp eq "cancel"} {
		grid columnconfigure $w.bot $i -minsize 90
	    }







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	button $w.button$i -text $but -command [list set ::tk::Priv(button) $i]
	if {$i == $default} {
	    $w.button$i configure -default active
	} else {
	    $w.button$i configure -default normal
	}
	grid $w.button$i -in $w.bot -column $i -row 0 -sticky ew \
		-padx 7.5p -pady 3p
	grid columnconfigure $w.bot $i
	# We boost the size of some Mac buttons for l&f
	if {$windowingsystem eq "aqua"} {
	    set tmp [string tolower $but]
	    if {$tmp eq "ok" || $tmp eq "cancel"} {
		grid columnconfigure $w.bot $i -minsize 90
	    }

Changes to library/entry.tcl.

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    tk::CancelRepeat
}
bind Entry <Control-Button-1> {
    %W icursor @%x
}

bind Entry <<PrevChar>> {
    tk::EntrySetCursor %W [expr {[%W index insert]-1}]
}
bind Entry <<NextChar>> {
    tk::EntrySetCursor %W [expr {[%W index insert]+1}]
}
bind Entry <<SelectPrevChar>> {
    tk::EntryKeySelect %W [expr {[%W index insert]-1}]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextChar>> {
    tk::EntryKeySelect %W [expr {[%W index insert]+1}]
    tk::EntrySeeInsert %W
}
bind Entry <<PrevWord>> {
    tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
}
bind Entry <<NextWord>> {
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
}
bind Entry <<SelectPrevWord>> {
    tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextWord>> {
    tk::EntryKeySelect %W [tk::EntryNextWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<LineStart>> {
    tk::EntrySetCursor %W 0
}
bind Entry <<SelectLineStart>> {
    tk::EntryKeySelect %W 0







|


|


|



|













|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    tk::CancelRepeat
}
bind Entry <Control-Button-1> {
    %W icursor @%x
}

bind Entry <<PrevChar>> {
    tk::EntrySetCursor %W [tk::EntryPreviousChar %W insert]
}
bind Entry <<NextChar>> {
    tk::EntrySetCursor %W [tk::EntryNextChar %W insert]
}
bind Entry <<SelectPrevChar>> {
    tk::EntryKeySelect %W [tk::EntryPreviousChar %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextChar>> {
    tk::EntryKeySelect %W [tk::EntryNextChar %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<PrevWord>> {
    tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
}
bind Entry <<NextWord>> {
    tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
}
bind Entry <<SelectPrevWord>> {
    tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<SelectNextWord>> {
    tk::EntryKeySelect %W [tk::EntrySelectNextWord %W insert]
    tk::EntrySeeInsert %W
}
bind Entry <<LineStart>> {
    tk::EntrySetCursor %W 0
}
bind Entry <<SelectLineStart>> {
    tk::EntryKeySelect %W 0
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
    tk::EntrySeeInsert %W
}

bind Entry <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last
    } else {
	%W delete insert

    }
}
bind Entry <BackSpace> {
    tk::EntryBackspace %W
}

bind Entry <Control-space> {







|
>







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    tk::EntrySeeInsert %W
}

bind Entry <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last
    } else {
	%W delete [tk::startOfCluster [%W get] [%W index insert]] \
		[tk::endOfCluster [%W get] [%W index insert]]
    }
}
bind Entry <BackSpace> {
    tk::EntryBackspace %W
}

bind Entry <Control-space> {
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
    %W selection clear
}
bind Entry <Key> {
    tk::CancelRepeat
    tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Entry <Alt-Key> {# nothing}
bind Entry <Meta-Key> {# nothing}
bind Entry <Control-Key> {# nothing}
bind Entry <Escape> {# nothing}
bind Entry <Return> {# nothing}
bind Entry <KP_Enter> {# nothing}
bind Entry <Tab> {# nothing}
bind Entry <Prior> {# nothing}
bind Entry <Next> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Entry <Command-Key> {# nothing}
}

# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind Entry <<NextLine>> {# nothing}
bind Entry <<PrevLine>> {# nothing}

# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {







|













<
|
<
>







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213

214
215
216
217
218
219
220
221
    %W selection clear
}
bind Entry <Key> {
    tk::CancelRepeat
    tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, Control, Command, and Fn keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Entry <Alt-Key> {# nothing}
bind Entry <Meta-Key> {# nothing}
bind Entry <Control-Key> {# nothing}
bind Entry <Escape> {# nothing}
bind Entry <Return> {# nothing}
bind Entry <KP_Enter> {# nothing}
bind Entry <Tab> {# nothing}
bind Entry <Prior> {# nothing}
bind Entry <Next> {# nothing}

bind Entry <Command-Key> {# nothing}

bind Entry <Fn-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

# Bindings for IME text input and accents.

bind Entry <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Entry <<TkEndIMEMarkedText>> {
    if {[catch {dict get $::tk::Priv(IMETextMark) "%W"} mark]} {
	bell
    } else {
	%W selection range $mark insert
    }
}
bind Entry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind Entry <<TkAccentBackspace>> {
    tk::EntryBackspace %W
}


















# A few additional bindings of my own.

bind Entry <Button-2> {
    if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
    }







|
<
<
<
<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







274
275
276
277
278
279
280
281




282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

# Bindings for IME text input and accents.

bind Entry <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Entry <<TkEndIMEMarkedText>> {
    ::tk::EntryEndIMEMarkedText %W




}
bind Entry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind Entry <<TkAccentBackspace>> {
    tk::EntryBackspace %W
}

# ::tk::EntryEndIMEMarkedText --
# Handles input method text marking in an entry
#
# Arguments:
# w -		The entry window.

proc ::tk::EntryEndIMEMarkedText {w} {
    variable Priv
    if {[catch {
	set mark [dict get $Priv(IMETextMark) $w]
    }]} {
	bell
	return
    }
    $w selection range $mark insert
}

# A few additional bindings of my own.

bind Entry <Button-2> {
    if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
    }
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
		} else {
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < $anchor} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] $anchor-1]
	    } elseif {$cur > $anchor} {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $cur-1]
	    } else {
		if {[$w index @$Priv(pressX)] < $anchor} {
		      incr anchor -1
		}
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $anchor]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }







|
|

|
|




|
|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
		} else {
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < $anchor} {
		set before [tk::wordBreakBefore [$w get] $cur]
		set after [tk::wordBreakAfter [$w get] $anchor-1]
	    } elseif {$cur > $anchor} {
		set before [tk::wordBreakBefore [$w get] $anchor]
		set after [tk::wordBreakAfter [$w get] $cur-1]
	    } else {
		if {[$w index @$Priv(pressX)] < $anchor} {
		      incr anchor -1
		}
		set before [tk::wordBreakBefore [$w get] $anchor]
		set after [tk::wordBreakAfter [$w get] $anchor]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
# Arguments:
# w -		The entry window in which to backspace.

proc ::tk::EntryBackspace w {
    if {[$w selection present]} {
	$w delete sel.first sel.last
    } else {
	set x [$w index insert]
	if {$x > 0} {
	    $w delete [expr {$x-1}]

	}
	if {[$w index @0] >= [$w index insert]} {
	    set range [$w xview]
	    set left [lindex $range 0]
	    set right [lindex $range 1]
	    $w xview moveto [expr {$left - ($right - $left)/2.0}]
	}







|
|
|
>







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
# 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 [tk::startOfCluster [$w get] $x] \
		      [tk::endOfCluster [$w get] $x]
	}
	if {[$w index @0] >= [$w index insert]} {
	    set range [$w xview]
	    set left [lindex $range 0]
	    set right [lindex $range 1]
	    $w xview moveto [expr {$left - ($right - $left)/2.0}]
	}
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587




588
589
590
591
592
593
594
595
596
597








598




599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616




617
















618
619
620
621
622

623
624
625
626
627
628
629
    set i [$w index insert]
    if {$i < [$w index end]} {
	incr i
    }
    if {$i < 2} {
	return
    }
    set first [expr {$i-2}]
    set data [$w get]
    set new [string index $data $i-1][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --
# Returns the index of the next word position after a given position in the
# entry.  The next word is platform dependent and may be either the next
# end-of-word position or the next start-of-word position after the next
# end-of-word position.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

if {[tk windowingsystem] eq "win32"}  {
    proc ::tk::EntryNextWord {w start} {




	set pos [tcl_endOfWord [$w get] [$w index $start]]
	if {$pos >= 0} {
	    set pos [tcl_startOfNextWord [$w get] $pos]
	}
	if {$pos < 0} {
	    return end
	}
	return $pos
    }
} else {








    proc ::tk::EntryNextWord {w start} {




	set pos [tcl_endOfWord [$w get] [$w index $start]]
	if {$pos < 0} {
	    return end
	}
	return $pos
    }
}

# ::tk::EntryPreviousWord --
#
# Returns the index of the previous word position before a given
# position in the entry.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::EntryPreviousWord {w start} {




    set pos [tcl_startOfPreviousWord [$w get] [$w index $start]]
















    if {$pos < 0} {
	return 0
    }
    return $pos
}


# ::tk::EntryScanMark --
#
# Marks the start of a possible scan drag operation
#
# Arguments:
# w -	The entry window from which the text to get







|








<
<
|
|





<
|
>
>
>
>
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
|
|
|
<












>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>







575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590


591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
    set i [$w index insert]
    if {$i < [$w index end]} {
	incr i
    }
    if {$i < 2} {
	return
    }
    set first $i-2
    set data [$w get]
    set new [string index $data $i-1][string index $data $first]
    $w delete $first $i
    $w insert insert $new
    EntrySeeInsert $w
}

# ::tk::EntryNextWord --


# Returns the index of the next start-of-word position after the next
# end-of-word position after a given position in the text.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.


proc ::tk::EntryNextWord {w start} {
    # the check on [winfo class] is because the spinbox also uses this proc
    if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	return end
    }
    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos >= 0} {
	set pos [tk::startOfNextWord [$w get] $pos]
    }
    if {$pos < 0} {
	return end
    }
    return $pos
}

# ::tk::EntrySelectNextWord --
# Returns the index of the next end-of-word position after a given
# position in the text.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::EntrySelectNextWord {w start} {
    # the check on [winfo class] is because the spinbox also uses this proc
    if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	return end
    }
    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return end
    }
    return $pos

}

# ::tk::EntryPreviousWord --
#
# Returns the index of the previous word position before a given
# position in the entry.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::EntryPreviousWord {w start} {
    # the check on [winfo class] is because the spinbox also uses this proc
    if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	return 0
    }
    set pos [tk::startOfPreviousWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return 0
    }
    return $pos
}

proc ::tk::EntryNextChar {w start} {
    set pos [tk::endOfCluster [$w get] [$w index $start]]
    if {$pos < 0} {
	return end
    }
    return $pos
}

proc ::tk::EntryPreviousChar {w start} {
    set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}]]
    if {$pos < 0} {
	return 0
    }
    return $pos
}


# ::tk::EntryScanMark --
#
# Marks the start of a possible scan drag operation
#
# Arguments:
# w -	The entry window from which the text to get

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63
64
65
66




67

68
69

70

71
72
73
74
75
76
77
# fontchooser.tcl -
#
#	A themeable Tk font selection dialog. See TIP #324.
#
# Copyright (C) 2008 Keith Vetter
# Copyright (C) 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"] \
    ]

    set S(sizes) {8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72}
    set S(strike) 0
    set S(under) 0
    set S(first) 1
    set S(sampletext) [::msgcat::mc "AaBbYyZz01"]
    set S(-parent) .
    set S(-title) [::msgcat::mc "Font"]
    set S(-command) ""
    set S(-font) TkDefaultFont





















}

proc ::tk::fontchooser::Setup {} {
    variable S

    # Canonical versions of font families, styles, etc. for easier searching
    set S(fonts,lcase) {}
    foreach font $S(fonts) {lappend S(fonts,lcase) [string tolower $font]}
    set S(styles,lcase) {}
    foreach style $S(styles) {lappend S(styles,lcase) [string tolower $style]}
    set S(sizes,lcase) $S(sizes)

    ::ttk::style layout FontchooserFrame {
        Entry.field -sticky news -border true -children {
            FontchooserFrame.padding -sticky news
        }
    }
    bind [winfo class .] <<ThemeChanged>> \
        [list +ttk::style layout FontchooserFrame \
             [ttk::style layout FontchooserFrame]]

    namespace ensemble create -map {
        show ::tk::fontchooser::Show
        hide ::tk::fontchooser::Hide
        configure ::tk::fontchooser::Configure
    }
}
::tk::fontchooser::Setup

proc ::tk::fontchooser::Show {} {
    variable S



    if {![winfo exists $S(W)]} {
        Create
        wm transient $S(W) [winfo toplevel $S(-parent)]
        tk::PlaceWindow $S(W) widget $S(-parent)




    }

    set S(fonts) [lsort -dictionary [font families]]
    set S(fonts,lcase) {}

    foreach font $S(fonts) { lappend S(fonts,lcase) [string tolower $font]}

    wm deiconify $S(W)
}

proc ::tk::fontchooser::Hide {} {
    variable S
    wm withdraw $S(W)
}




|
|








|

|
|
|
|

<




<

|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
<
<
<
<
<







|
|











>
>
>




>
>
>
>
|
>
|

>
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56





57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# fontchooser.tcl -
#
#	A themeable Tk font selection dialog. See TIP #324.
#
# 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 -unique [font families]]
    set S(styles) [list \
            [::msgcat::mc Regular] \
            [::msgcat::mc Italic] \
            [::msgcat::mc Bold] \
            [::msgcat::mc {Bold Italic}] \
    ]

    set S(sizes) {8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72}
    set S(strike) 0
    set S(under) 0
    set S(first) 1

    set S(-parent) .
    set S(-title) {}
    set S(-command) ""
    set S(-font) TkDefaultFont
    set S(bad) [list ]
}

proc ::tk::fontchooser::Canonical {} {
    variable S

    foreach style $S(styles) {
        lappend S(styles,lcase) [string tolower $style]
    }
    set S(sizes,lcase) $S(sizes)
    set S(sampletext) [::msgcat::mc "AaBbYyZz01"]

    # Canonical versions of font families, styles, etc. for easier searching
    set S(fonts,lcase) {}
    foreach font $S(fonts) {
        lappend S(fonts,lcase) [string tolower $font]
    }
    set S(styles,lcase) {}
    foreach style $S(styles) {
        lappend S(styles,lcase) [string tolower $style]
    }
}

proc ::tk::fontchooser::Setup {} {
    variable S

    Canonical






    ::ttk::style layout FontchooserFrame {
        Entry.field -sticky news -border true -children {
            FontchooserFrame.padding -sticky news
        }
    }
    bind [winfo class .] <<ThemeChanged>> \
            [list +ttk::style layout FontchooserFrame \
                    [ttk::style layout FontchooserFrame]]

    namespace ensemble create -map {
        show ::tk::fontchooser::Show
        hide ::tk::fontchooser::Hide
        configure ::tk::fontchooser::Configure
    }
}
::tk::fontchooser::Setup

proc ::tk::fontchooser::Show {} {
    variable S

    Canonical

    if {![winfo exists $S(W)]} {
        Create
        wm transient $S(W) [winfo toplevel $S(-parent)]
        tk::PlaceWindow $S(W) widget $S(-parent)
        if {[string trim $S(-title)] eq ""} {
            wm title $S(W) [::msgcat::mc "Font"]
        } else {
            wm title $S(W) $S(-title)
        }
    }
    set S(fonts) [lsort -dictionary -unique [font families]]
    set S(fonts,lcase) {}
    foreach font $S(fonts) {
        lappend S(fonts,lcase) [string tolower $font]
    }
    wm deiconify $S(W)
}

proc ::tk::fontchooser::Hide {} {
    variable S
    wm withdraw $S(W)
}
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126









127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268





269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290

291
292

293
294


295
296
297
298
299
300
301
    }

    if {[llength $args] == 0} {
        set result {}
        foreach spec $specs {
            foreach {name xx yy default} $spec break
            lappend result $name \
                [expr {[info exists S($name)] ? $S($name) : $default}]
        }
        lappend result -visible \
            [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
        return $result
    }
    if {[llength $args] == 1} {
        set option [lindex $args 0]
        if {[string equal $option "-visible"]} {
            return [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
        } elseif {[info exists S($option)]} {
            return $S($option)
        }
        return -code error -errorcode [list TK LOOKUP OPTION $option] \
	    "bad option \"$option\": must be\
            -command, -font, -parent, -title or -visible"
    }

    set cache [dict create -parent $S(-parent) -title $S(-title) \
                   -font $S(-font) -command $S(-command)]
    set r [tclParseConfigSpec [namespace which -variable S] $specs "" $args]
    if {![winfo exists $S(-parent)]} {
	set code [list TK LOOKUP WINDOW $S(-parent)]
        set err "bad window path name \"$S(-parent)\""
        array set S $cache
        return -code error -errorcode $code $err
    }
    if {[string trim $S(-title)] eq ""} {
        set S(-title) [::msgcat::mc "Font"]
    }
    if {[winfo exists $S(W)] && ("-font" in $args)} {

	Init $S(-font)
	event generate $S(-parent) <<TkFontchooserFontChanged>>









    }
    return $r
}

proc ::tk::fontchooser::Create {} {
    variable S
    set windowName __tk__fontchooser
    if {$S(-parent) eq "."} {
        set S(W) .$windowName
    } else {
        set S(W) $S(-parent).$windowName
    }

    # Now build the dialog
    if {![winfo exists $S(W)]} {
        toplevel $S(W) -class TkFontDialog
        if {[package provide tcltest] ne {}} {set ::tk_dialog $S(W)}


        wm withdraw $S(W)
        wm title $S(W) $S(-title)
        wm transient $S(W) [winfo toplevel $S(-parent)]

        set scaling [tk scaling]
        set sizeWidth [expr {int([string length [::msgcat::mc "&Size:"]] * $scaling)}]

        set outer [::ttk::frame $S(W).outer -padding {10 10}]
        ::tk::AmpWidget ::ttk::label $S(W).font -text [::msgcat::mc "&Font:"]
        ::tk::AmpWidget ::ttk::label $S(W).style -text [::msgcat::mc "Font st&yle:"]
        ::tk::AmpWidget ::ttk::label $S(W).size -text [::msgcat::mc "&Size:"] -width $sizeWidth
        ttk::entry $S(W).efont -width 18 \
            -textvariable [namespace which -variable S](font)
        ttk::entry $S(W).estyle -width 10 \
            -textvariable [namespace which -variable S](style)
        ttk::entry $S(W).esize -textvariable [namespace which -variable S](size) \
            -width 3 -validate key -validatecommand {string is double %P}

        ttk_slistbox $S(W).lfonts -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](fonts)
        ttk_slistbox $S(W).lstyles -width 5 -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](styles)
        ttk_slistbox $S(W).lsizes -width 4 -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](sizes)

        set WE $S(W).effects
        ::ttk::labelframe $WE -text [::msgcat::mc "Effects"]
        ::tk::AmpWidget ::ttk::checkbutton $WE.strike \
            -variable [namespace which -variable S](strike) \
            -text [::msgcat::mc "Stri&keout"] \
            -command [namespace code [list Click strike]]
        ::tk::AmpWidget ::ttk::checkbutton $WE.under \
            -variable [namespace which -variable S](under) \
            -text [::msgcat::mc "&Underline"] \
            -command [namespace code [list Click under]]

        set bbox [::ttk::frame $S(W).bbox]
        ::ttk::button $S(W).ok -text [::msgcat::mc OK] -default active\
            -command [namespace code [list Done 1]]
        ::ttk::button $S(W).cancel -text [::msgcat::mc Cancel] \
            -command [namespace code [list Done 0]]
        ::tk::AmpWidget ::ttk::button $S(W).apply -text [::msgcat::mc "&Apply"] \
            -command [namespace code [list Apply]]
        wm protocol $S(W) WM_DELETE_WINDOW [namespace code [list Done 0]]

        # Calculate minimum sizes
        ttk::scrollbar $S(W).tmpvs
        set scroll_width [winfo reqwidth $S(W).tmpvs]
        destroy $S(W).tmpvs
        set minsize(gap) 10
        set minsize(bbox) [winfo reqwidth $S(W).ok]
        set minsize(fonts) \
            [expr {[font measure TkDefaultFont "Helvetica"] + $scroll_width}]
        set minsize(styles) \
            [expr {[font measure TkDefaultFont "Bold Italic"] + $scroll_width}]
        set minsize(sizes) \
            [expr {[font measure TkDefaultFont "-99"] + $scroll_width}]
        set min [expr {$minsize(gap) * 4}]
        foreach {what width} [array get minsize] {incr min $width}


        wm minsize $S(W) $min 260

        bind $S(W) <Return> [namespace code [list Done 1]]
        bind $S(W) <Escape> [namespace code [list Done 0]]
        bind $S(W) <Map> [namespace code [list Visibility %W 1]]
        bind $S(W) <Unmap> [namespace code [list Visibility %W 0]]
        bind $S(W) <Destroy> [namespace code [list Visibility %W 0]]
        bind $S(W).lfonts.list <<ListboxSelect>> [namespace code [list Click font]]
        bind $S(W).lstyles.list <<ListboxSelect>> [namespace code [list Click style]]
        bind $S(W).lsizes.list <<ListboxSelect>> [namespace code [list Click size]]
        bind $S(W) <Alt-Key> [list ::tk::AltKeyInDialog $S(W) %A]
        bind $S(W).font <<AltUnderlined>> [list ::focus $S(W).efont]
        bind $S(W).style <<AltUnderlined>> [list ::focus $S(W).estyle]
        bind $S(W).size <<AltUnderlined>> [list ::focus $S(W).esize]
        bind $S(W).apply <<AltUnderlined>> [namespace code [list Apply]]
        bind $WE.strike <<AltUnderlined>> [list $WE.strike invoke]
        bind $WE.under <<AltUnderlined>> [list $WE.under invoke]

        set WS $S(W).sample
        ::ttk::labelframe $WS -text [::msgcat::mc "Sample"]
        ::ttk::label $WS.sample -relief sunken -anchor center \
            -textvariable [namespace which -variable S](sampletext)
        set S(sample) $WS.sample
        grid $WS.sample -sticky news -padx 6 -pady 4
        grid rowconfigure $WS 0 -weight 1
        grid columnconfigure $WS 0 -weight 1
        grid propagate $WS 0

        grid $S(W).ok     -in $bbox -sticky new -pady {0 2}
        grid $S(W).cancel -in $bbox -sticky new -pady 2
        if {$S(-command) ne ""} {
            grid $S(W).apply -in $bbox -sticky new -pady 2
        }
        grid columnconfigure $bbox 0 -weight 1

        grid $WE.strike -sticky w -padx 10
        grid $WE.under -sticky w -padx 10 -pady {0 30}
        grid columnconfigure $WE 1 -weight 1

        grid $S(W).font   x $S(W).style   x $S(W).size   x       -in $outer -sticky w
        grid $S(W).efont  x $S(W).estyle  x $S(W).esize  x $bbox -in $outer -sticky ew
        grid $S(W).lfonts x $S(W).lstyles x $S(W).lsizes x ^     -in $outer -sticky news
        grid $WE          x $WS           - -            x ^     -in $outer -sticky news -pady {15 30}
        grid configure $bbox -sticky n

        grid columnconfigure $outer {1 3 5} -minsize $minsize(gap)
        grid columnconfigure $outer {0 2 4} -weight 1
        grid columnconfigure $outer 0 -minsize $minsize(fonts)
        grid columnconfigure $outer 2 -minsize $minsize(styles)
        grid columnconfigure $outer 4 -minsize $minsize(sizes)
        grid columnconfigure $outer 6 -minsize $minsize(bbox)

        grid $outer -sticky news
        grid rowconfigure $S(W) 0 -weight 1
        grid columnconfigure $S(W) 0 -weight 1

        Init $S(-font)

        trace add variable [namespace which -variable S](size) \
            write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](style) \
            write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](font) \
            write [namespace code [list Tracer]]





    } else {
        Init $S(-font)
    }

    return
}

# ::tk::fontchooser::Done --
#
#       Handles teardown of the dialog, calling -command if needed
#
# Arguments:
#       ok              true if user pressed OK
#
proc ::tk::fontchooser::Done {ok} {
    variable S

    if {! $ok} {
        set S(result) ""
    }
    trace vdelete S(size) w [namespace code [list Tracer]]

    trace vdelete S(style) w [namespace code [list Tracer]]

    trace vdelete S(font) w [namespace code [list Tracer]]
    destroy $S(W)

    if {$ok && $S(-command) ne ""} {
        uplevel #0 $S(-command) [list $S(result)]


    }
}

# ::tk::fontchooser::Apply --
#
#	Call the -command procedure appending the current font
#	Errors are reported via the background error mechanism







|


|










|
|

<

|
|

|




<
<
|
|
>
|
|
>
>
>
>
>
>
>
>
>
















|
>
>




<
<
<
|


|

|

|

|


|
|

|
|

|
|




|
|
|

|
|
|



|

|

|






|


|

|

|

|
>
>
|




















|

|




|
|
<
|
<


|
|





|

>














|

|

|
>
>
>
>
>
|
|
<

















|
>
|
>
|

>
|
|
>
>







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
    }

    if {[llength $args] == 0} {
        set result {}
        foreach spec $specs {
            foreach {name xx yy default} $spec break
            lappend result $name \
                    [expr {[info exists S($name)] ? $S($name) : $default}]
        }
        lappend result -visible \
                [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
        return $result
    }
    if {[llength $args] == 1} {
        set option [lindex $args 0]
        if {[string equal $option "-visible"]} {
            return [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
        } elseif {[info exists S($option)]} {
            return $S($option)
        }
        return -code error -errorcode [list TK LOOKUP OPTION $option] \
                "bad option \"$option\": must be\
                -command, -font, -parent, -title or -visible"
    }

    set cache [dict create -parent $S(-parent) -title $S(-title) \
            -font $S(-font) -command $S(-command)]
    set r [tclParseConfigSpec [namespace which -variable S] $specs 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 {[winfo exists $S(W)]} {
        if {{-font} in $args} {
            Init $S(-font)
            event generate $S(-parent) <<TkFontchooserFontChanged>>
        }

        if {[string trim $S(-title)] eq {}} {
            wm title $S(W) [::msgcat::mc Font]
        } else {
            wm title $S(W) $S(-title)
        }
        $S(W).ok configure -state $S(nstate)
        $S(W).apply configure -state $S(nstate)
    }
    return $r
}

proc ::tk::fontchooser::Create {} {
    variable S
    set windowName __tk__fontchooser
    if {$S(-parent) eq "."} {
        set S(W) .$windowName
    } else {
        set S(W) $S(-parent).$windowName
    }

    # Now build the dialog
    if {![winfo exists $S(W)]} {
        toplevel $S(W) -class TkFontDialog
        if {[package provide tcltest] ne {}} {
            set ::tk_dialog $S(W)
        }
        wm withdraw $S(W)
        wm title $S(W) $S(-title)
        wm transient $S(W) [winfo toplevel $S(-parent)]




        set outer [::ttk::frame $S(W).outer -padding {7.5p 7.5p}]
        ::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:"]
        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 {regexp -- {^-*[0-9]*$} %P}

        ttk_slistbox $S(W).lfonts -height 7 -exportselection 0 \
                -selectmode browse -activestyle none \
                -listvariable [namespace which -variable S](fonts)
        ttk_slistbox $S(W).lstyles -width 5 -height 7 -exportselection 0 \
                -selectmode browse -activestyle none \
                -listvariable [namespace which -variable S](styles)
        ttk_slistbox $S(W).lsizes -width 4 -height 7 -exportselection 0 \
                -selectmode browse -activestyle none \
                -listvariable [namespace which -variable S](sizes)

        set WE $S(W).effects
        ::ttk::labelframe $WE -text [::msgcat::mc "Effects"]
        ::tk::AmpWidget ::ttk::checkbutton $WE.strike \
                -variable [namespace which -variable S](strike) \
                -text [::msgcat::mc "Stri&keout"] \
                -command [namespace code [list Click strike]]
        ::tk::AmpWidget ::ttk::checkbutton $WE.under \
                -variable [namespace which -variable S](under) \
                -text [::msgcat::mc "&Underline"] \
                -command [namespace code [list Click under]]

        set bbox [::ttk::frame $S(W).bbox]
        ::ttk::button $S(W).ok -text [::msgcat::mc OK] -default active\
                -command [namespace code [list Done 1]]
        ::ttk::button $S(W).cancel -text [::msgcat::mc Cancel] \
                -command [namespace code [list Done 0]]
        ::tk::AmpWidget ::ttk::button $S(W).apply -text [::msgcat::mc "&Apply"] \
                -command [namespace code [list Apply]]
        wm protocol $S(W) WM_DELETE_WINDOW [namespace code [list Done 0]]

        # Calculate minimum sizes
        ttk::scrollbar $S(W).tmpvs
        set scroll_width [winfo reqwidth $S(W).tmpvs]
        destroy $S(W).tmpvs
        set minsize(gap) [::tk::ScaleNum 10]
        set minsize(bbox) [winfo reqwidth $S(W).ok]
        set minsize(fonts) \
                [expr {[font measure TkDefaultFont "Helvetica"] + $scroll_width}]
        set minsize(styles) \
                [expr {[font measure TkDefaultFont "Bold Italic"] + $scroll_width}]
        set minsize(sizes) \
                [expr {[font measure TkDefaultFont "-99"] + $scroll_width}]
        set min [expr {$minsize(gap) * 4}]
        foreach {what width} [array get minsize] {
            incr min $width
        }
        wm minsize $S(W) $min [::tk::ScaleNum 260]

        bind $S(W) <Return> [namespace code [list Done 1]]
        bind $S(W) <Escape> [namespace code [list Done 0]]
        bind $S(W) <Map> [namespace code [list Visibility %W 1]]
        bind $S(W) <Unmap> [namespace code [list Visibility %W 0]]
        bind $S(W) <Destroy> [namespace code [list Visibility %W 0]]
        bind $S(W).lfonts.list <<ListboxSelect>> [namespace code [list Click font]]
        bind $S(W).lstyles.list <<ListboxSelect>> [namespace code [list Click style]]
        bind $S(W).lsizes.list <<ListboxSelect>> [namespace code [list Click size]]
        bind $S(W) <Alt-Key> [list ::tk::AltKeyInDialog $S(W) %A]
        bind $S(W).font <<AltUnderlined>> [list ::focus $S(W).efont]
        bind $S(W).style <<AltUnderlined>> [list ::focus $S(W).estyle]
        bind $S(W).size <<AltUnderlined>> [list ::focus $S(W).esize]
        bind $S(W).apply <<AltUnderlined>> [namespace code [list Apply]]
        bind $WE.strike <<AltUnderlined>> [list $WE.strike invoke]
        bind $WE.under <<AltUnderlined>> [list $WE.under invoke]

        set WS $S(W).sample
        ::ttk::labelframe $WS -text [::msgcat::mc "Sample"]
        ::ttk::label $WS.sample -relief sunken -anchor center \
                -textvariable [namespace which -variable S](sampletext)
        set S(sample) $WS.sample
        grid $WS.sample -sticky news -padx 4.5p -pady 3p
        grid rowconfigure $WS 0 -weight 1
        grid columnconfigure $WS 0 -weight 1
        grid propagate $WS 0

        grid $S(W).ok     -in $bbox -sticky new -pady {0 1.5p}
        grid $S(W).cancel -in $bbox -sticky new -pady 1.5p

        grid $S(W).apply  -in $bbox -sticky new -pady 1.5p

        grid columnconfigure $bbox 0 -weight 1

        grid $WE.strike -sticky w -padx 7.5p
        grid $WE.under -sticky w -padx 7.5p -pady {0 22.5p}
        grid columnconfigure $WE 1 -weight 1

        grid $S(W).font   x $S(W).style   x $S(W).size   x       -in $outer -sticky w
        grid $S(W).efont  x $S(W).estyle  x $S(W).esize  x $bbox -in $outer -sticky ew
        grid $S(W).lfonts x $S(W).lstyles x $S(W).lsizes x ^     -in $outer -sticky news
        grid $WE          x $WS           - -            x ^     -in $outer -sticky news -pady {11p 22.5p}
        grid configure $bbox -sticky n
        grid rowconfigure $outer 2 -weight 1
        grid columnconfigure $outer {1 3 5} -minsize $minsize(gap)
        grid columnconfigure $outer {0 2 4} -weight 1
        grid columnconfigure $outer 0 -minsize $minsize(fonts)
        grid columnconfigure $outer 2 -minsize $minsize(styles)
        grid columnconfigure $outer 4 -minsize $minsize(sizes)
        grid columnconfigure $outer 6 -minsize $minsize(bbox)

        grid $outer -sticky news
        grid rowconfigure $S(W) 0 -weight 1
        grid columnconfigure $S(W) 0 -weight 1

        Init $S(-font)

        trace add variable [namespace which -variable S](size) \
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](style) \
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](font) \
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](strike) \
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](under) \
                write [namespace code [list Tracer]]
    }

    Init $S(-font)


    return
}

# ::tk::fontchooser::Done --
#
#       Handles teardown of the dialog, calling -command if needed
#
# Arguments:
#       ok              true if user pressed OK
#
proc ::tk::fontchooser::Done {ok} {
    variable S

    if {! $ok} {
        set S(result) ""
    }
    trace remove variable S(size) write [namespace code [list Tracer]]
    trace remove variable S(style) write [namespace code [list Tracer]]
    trace remove variable S(font) write [namespace code [list Tracer]]
    trace remove variable S(strike) write [namespace code [list Tracer]]
    trace remove variable S(under) write [namespace code [list Tracer]]
    destroy $S(W)
    if {$ok} {
        if {$S(-command) ne ""} {
            uplevel #0 $S(-command) [list $S(result)]
        }
        event generate $S(-parent) <<TkFontchooserFontChanged>>
    }
}

# ::tk::fontchooser::Apply --
#
#	Call the -command procedure appending the current font
#	Errors are reported via the background error mechanism
317
318
319
320
321
322
323

324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390




391
392
393
394

395
396

397


398
399

400
401


402



403

404
405
406
407
408
409
410
411
412
413
414


415


416


417


418

419

420

421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# Arguments:
#       defaultFont     font to use as the default
#
proc ::tk::fontchooser::Init {{defaultFont ""}} {
    variable S

    if {$S(first) || $defaultFont ne ""} {

        if {$defaultFont eq ""} {
            set defaultFont [[entry .___e] cget -font]
            destroy .___e
        }
        array set F [font actual $defaultFont]
        set S(font) $F(-family)

        set S(size) $F(-size)
        set S(strike) $F(-overstrike)
        set S(under) $F(-underline)
        set S(style) [::msgcat::mc "Regular"]
        if {$F(-weight) eq "bold" && $F(-slant) eq "italic"} {
            set S(style) [::msgcat::mc "Bold Italic"]
        } elseif {$F(-weight) eq "bold"} {
            set S(style) [::msgcat::mc "Bold"]
        } elseif {$F(-slant) eq "italic"} {
            set S(style) [::msgcat::mc "Italic"]
        }

        set S(first) 0
    }

    Tracer a b c
    Update
}

# ::tk::fontchooser::Click --
#
#       Handles all button clicks, updating the appropriate widgets
#
# Arguments:
#       who             which widget got pressed
#
proc ::tk::fontchooser::Click {who} {
    variable S

    if {$who eq "font"} {
        set S(font) [$S(W).lfonts get [$S(W).lfonts curselection]]
    } elseif {$who eq "style"} {
        set S(style) [$S(W).lstyles get [$S(W).lstyles curselection]]
    } elseif {$who eq "size"} {
        set S(size) [$S(W).lsizes get [$S(W).lsizes curselection]]
    }
    Update
}

# ::tk::fontchooser::Tracer --
#
#       Handles traces on key variables, updating the appropriate widgets
#
# Arguments:
#       standard trace arguments (not used)
#
proc ::tk::fontchooser::Tracer {var1 var2 op} {
    variable S

    set bad 0
    set nstate normal
    # Make selection in each listbox
    foreach var {font style size} {
        set value [string tolower $S($var)]
        $S(W).l${var}s selection clear 0 end
        set n [lsearch -exact $S(${var}s,lcase) $value]
        $S(W).l${var}s selection set $n
        if {$n >= 0} {
            set S($var) [lindex $S(${var}s) $n]
            $S(W).e$var icursor end
            $S(W).e$var selection clear




        } else {                                ;# No match, try prefix
            # Size is weird: valid numbers are legal but don't display
            # unless in the font size list
            set n [lsearch -glob $S(${var}s,lcase) "$value*"]

            set bad 1
            if {$var ne "size" || ! [string is double -strict $value]} {

                set nstate disabled


            }
        }

        $S(W).l${var}s see $n
    }


    if {!$bad} {Update}



    $S(W).ok configure -state $nstate

}

# ::tk::fontchooser::Update --
#
#       Shows a sample of the currently selected font
#
proc ::tk::fontchooser::Update {} {
    variable S

    set S(result) [list $S(font) $S(size)]
    if {$S(style) eq [::msgcat::mc "Bold"]} {lappend S(result) bold}


    if {$S(style) eq [::msgcat::mc "Italic"]} {lappend S(result) italic}


    if {$S(style) eq [::msgcat::mc "Bold Italic"]} {lappend S(result) bold italic}


    if {$S(strike)} {lappend S(result) overstrike}


    if {$S(under)} {lappend S(result) underline}



    $S(sample) configure -font $S(result)

}

# ::tk::fontchooser::Visibility --
#
#	Notify the parent when the dialog visibility changes
#
proc ::tk::fontchooser::Visibility {w visible} {
    variable S
    if {$w eq $S(W)} {
        event generate $S(-parent) <<TkFontchooserVisibility>>
    }
}

# ::tk::fontchooser::ttk_listbox --
#
#	Create a properly themed scrolled listbox.
#	This is exactly right on XP but may need adjusting on other platforms.
#
proc ::tk::fontchooser::ttk_slistbox {w args} {
    set f [ttk::frame $w -style FontchooserFrame -padding 2]
    if {[catch {
        listbox $f.list -relief flat -highlightthickness 0 -borderwidth 0 {*}$args
        ttk::scrollbar $f.vs -command [list $f.list yview]
        $f.list configure -yscrollcommand [list $f.vs set]
        grid $f.list $f.vs -sticky news
        grid rowconfigure $f 0 -weight 1
        grid columnconfigure $f 0 -weight 1







>






>



<







<


<
<
<











<







<











|
|
<
|
<
|
|
|
|

|
|
|
>
>
>
>
|
<
<
|
>
|
|
>
|
>
>
|
|
>
|

>
>
|
>
>
>
|
>










|
>
>
|
>
>
|
>
>
|
>
>
|
>
|
>

>













|





|







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381

382
383



384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414

415

416
417
418
419
420
421
422
423
424
425
426
427
428


429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# Arguments:
#       defaultFont     font to use as the default
#
proc ::tk::fontchooser::Init {{defaultFont ""}} {
    variable S

    if {$S(first) || $defaultFont ne ""} {
        Canonical
        if {$defaultFont eq ""} {
            set defaultFont [[entry .___e] cget -font]
            destroy .___e
        }
        array set F [font actual $defaultFont]
        set S(font) $F(-family)
        set S(style) [::msgcat::mc "Regular"]
        set S(size) $F(-size)
        set S(strike) $F(-overstrike)
        set S(under) $F(-underline)

        if {$F(-weight) eq "bold" && $F(-slant) eq "italic"} {
            set S(style) [::msgcat::mc "Bold Italic"]
        } elseif {$F(-weight) eq "bold"} {
            set S(style) [::msgcat::mc "Bold"]
        } elseif {$F(-slant) eq "italic"} {
            set S(style) [::msgcat::mc "Italic"]
        }

        set S(first) 0
    }



}

# ::tk::fontchooser::Click --
#
#       Handles all button clicks, updating the appropriate widgets
#
# Arguments:
#       who             which widget got pressed
#
proc ::tk::fontchooser::Click {who} {
    variable S

    if {$who eq "font"} {
        set S(font) [$S(W).lfonts get [$S(W).lfonts curselection]]
    } elseif {$who eq "style"} {
        set S(style) [$S(W).lstyles get [$S(W).lstyles curselection]]
    } elseif {$who eq "size"} {
        set S(size) [$S(W).lsizes get [$S(W).lsizes curselection]]
    }

}

# ::tk::fontchooser::Tracer --
#
#       Handles traces on key variables, updating the appropriate widgets
#
# Arguments:
#       standard trace arguments (not used)
#
proc ::tk::fontchooser::Tracer {var1 var2 op} {
    variable S
    # We don't need to process strike and under
    if {$var2 ni [list strike under]} {

        # Make selection in listbox

        set value [string tolower $S($var2)]
        $S(W).l${var2}s selection clear 0 end
        set n [lsearch -exact $S(${var2}s,lcase) $value]
        $S(W).l${var2}s selection set $n
        if {$n >= 0} {
            set S($var2) [lindex $S(${var2}s) $n]
            $S(W).e$var2 icursor end
            $S(W).e$var2 selection clear
            if {[set i [lsearch $S(bad) $var2]] >= 0} {
                set S(bad) [lreplace $S(bad) $i $i]
            }
        } else {
            # No match, try prefix


            set n [lsearch -glob $S(${var2}s,lcase) "$value*"]
            if {$var2 ne "size" || !([regexp -- {^(-[0-9]+|[0-9]+)$} $value] && $value >= -4096 && $value <= 4096)} {
                 if {[lsearch $S(bad) $var2] < 0} {
                     lappend S(bad) $var2
                 }
            } else {
                if {[set i [lsearch $S(bad) $var2]] >= 0} {
                    set S(bad) [lreplace $S(bad) $i $i]
                }
            }
        }
        $S(W).l${var2}s see $n
    }
    if {[llength $S(bad)] == 0} {
        set S(nstate) normal
        Update
    } else {
        set S(nstate) disabled
    }
    $S(W).ok configure -state $S(nstate)
    $S(W).apply configure -state $S(nstate)
}

# ::tk::fontchooser::Update --
#
#       Shows a sample of the currently selected font
#
proc ::tk::fontchooser::Update {} {
    variable S

    set S(result) [list $S(font) $S(size)]
    if {$S(style) eq [::msgcat::mc "Bold"]} {
        lappend S(result) bold
    }
    if {$S(style) eq [::msgcat::mc "Italic"]} {
        lappend S(result) italic
    }
    if {$S(style) eq [::msgcat::mc "Bold Italic"]} {
        lappend S(result) bold italic
    }
    if {$S(strike)} {
        lappend S(result) overstrike
    }
    if {$S(under)} {
        lappend S(result) underline
    }

    $S(sample) configure -font $S(result)
    set S(-font) $S(result)
}

# ::tk::fontchooser::Visibility --
#
#	Notify the parent when the dialog visibility changes
#
proc ::tk::fontchooser::Visibility {w visible} {
    variable S
    if {$w eq $S(W)} {
        event generate $S(-parent) <<TkFontchooserVisibility>>
    }
}

# ::tk::fontchooser::ttk_slistbox --
#
#	Create a properly themed scrolled listbox.
#	This is exactly right on XP but may need adjusting on other platforms.
#
proc ::tk::fontchooser::ttk_slistbox {w args} {
    set f [ttk::frame $w -style FontchooserFrame -padding 1.5p]
    if {[catch {
        listbox $f.list -relief flat -highlightthickness 0 -borderwidth 0 {*}$args
        ttk::scrollbar $f.vs -command [list $f.list yview]
        $f.list configure -yscrollcommand [list $f.vs set]
        grid $f.list $f.vs -sticky news
        grid rowconfigure $f 0 -weight 1
        grid columnconfigure $f 0 -weight 1

Added library/iconbadges.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
# iconbadges.tcl --
#
#	Notification badges for Tk applications.
#
#
# Copyright © 2021 Kevin Walzer/WordTech Communications LLC

namespace eval ::tk::icons {}

image create photo ::tk::icons::1-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    kFBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/HBz/V1f/Rkb/BQX/Dw//oKD/////y8v/Bgb/Pz//ra3/+/v/
    zMz/Li7/5ub/+vr/8fH/Ly//uLj/Zmb/n5//Bwf/Dg7/kpL/YWH/rq7/h4f/Cgr/
    AQH/AgLXmjE+AAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34AAAABYktHRBib
    aYUeAAAAnElEQVQY022Q5w6DMBCD78hi03RQuvegg77/25ULCakq/MenT4piGwAQ
    A8aFlIKzABGAiAojbRSFihhinOheSdwyVKn+UaoQsry7x5PpjDzPgBWGlPNqUdJR
    MODky9V6U20N0hwE2W5/ODokQJKdzperQ7JDt7uuPRL299o/5P+IuxA9akO4qI/n
    622jukLNp3GFBmoPjOMnHNkJv3kDExXHctm+AAAAJXRFWHRkYXRlOmNyZWF0ZQAy
    MDIxLTA4LTEwVDA4OjM1OjE0LTA0OjAw0aX6GwAAACV0RVh0ZGF0ZTptb2RpZnkA
    MjAyMS0wOC0xMFQwODozNToxNC0wNDowMKD4QqcAAAAASUVORK5CYII=
}
image create photo ::tk::icons::2-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    21BMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/Cwv/ODj/UlL/UFD/MjL/CAj/ExP/oKD/8fH//v7//f3/7u7/
    kJD/DAz/ZWX/9fX/jIz/lpb/+vr/9/f/TEz/TU3/m5v/iYn/Ly//6+v/////YmL/
    nJz/5OT/MDD/KSn/srL/7Oz/ZGT/AQH/Nzf/zs7/zc3/SUn/AgL/ICD/ysr/7e3/
    gYH/VVX/WVn/Kir/fX3/eXn/AwP/dnb/rKz/qan/q6vjChO4AAAAEXRSTlMAAA5V
    q9/4NK/0St3cDa7z4Pnet34AAAABYktHRCy63XGrAAAAwElEQVQY021Q1xLCMAxz
    uktpS9hQoOwZ9t57/P8XUSesB/RinXz2SQIAQiRZUTVNVWSJEABUdMOkHKaho0ZI
    yKIfWKFAI3qY/iCsE7AdZNFYPJFMIXNskN1gpjNZL5cv+AF1ZVBwVfRK5Uq1Vkeu
    gIqj0Wz57Q7rIldBe/1N91h/gER7S8ORN55MhcQP6WzOFssVFYf8/XrDtrv94Sje
    cxMnxnEWJtDq5Xq7B3gkhFUeaCUwFYH+xP5TzrfCyKvCJ3EzGUFH/1QDAAAAJXRF
    WHRkYXRlOmNyZWF0ZQAyMDIxLTA4LTEwVDA4OjM1OjE0LTA0OjAw0aX6GwAAACV0
    RVh0ZGF0ZTptb2RpZnkAMjAyMS0wOC0xMFQwODozNToxNC0wNDowMKD4QqcAAAAA
    SUVORK5CYII=
}
image create photo ::tk::icons::3-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    +VBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/CQn/NTX/UlL/Tk7/Kir/BAT/ERH/mZn/8PD/+Pj/+vr/5ub/
    cHD/AgL/Vlb/9PT/5eX/X1//nZ3/////29v/HR3/Fhb/QED/RET/Cwv/f3//1dX/
    Ghr/Bwf/mpr/9vb/+fn/b2//lZX/2tr//Pz/wsL/Jyf/Dg7/Bgb/MzP/c3P/XV3/
    wMD/qqr/ExP/KSn/4+P/bm7/Q0P/6ur/vb3/x8f/19f/KCj/SEj/qan/zc3/y8v/
    oKD/ODj/BQX/DQ3/AwON+4wDAAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34A
    AAABYktHRCXDAckPAAAAx0lEQVQY021Q1RLCQBDbo4qW4l7ssOLu7g7//zH07oo8
    kJfNZGczyQIAQhaOF0RR4DkLQgBEkWSrSmGVJaIhZLOrH9hthoYkh/oDh4TA6SLM
    4/X5A0HCXE7gFGOGwpFoLJ7QDKpwwJNVMpXOZHEuTzgPAhmFYkkv40qVcAFEZlur
    N5otysS3pLc73V6fSfRQ8wyGozges0NqP5nO5oslXjF7GmK96W53eH9gIWhU7Xg6
    X643M6pZ6D54PN+F/tT+85zvC93mC1+z9hl5VNGhJwAAACV0RVh0ZGF0ZTpjcmVh
    dGUAMjAyMS0wOC0xMFQwODozNToxNC0wNDowMNGl+hsAAAAldEVYdGRhdGU6bW9k
    aWZ5ADIwMjEtMDgtMTBUMDg6MzU6MTQtMDQ6MDCg+EKnAAAAAElFTkSuQmCC
}
image create photo ::tk::icons::4-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    1VBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/AgL/OTn/W1v/ODj/QED/4uL/////oaH/AQH/KSn/zs7/oqL/
    Fhb/tbX/9PT/1NT/Cgr/l5f//Pz/h4f/fHz/dXX/+/v/trb/HBz/fX3/qKj/DAz/
    EBD/ysr/4eH/zc3/5eX/8fH/lJT/BAT/Dw//uLj/5+f/5ub/8vL/+vr/paX/BQX/
    HR3/JCT/ISH/iYn/sLD/Ghr/Tk7/rq7/a2vT0ZXAAAAAEXRSTlMAAA5Vq9/4NK/0
    St3cDa7z4Pnet34AAAABYktHRBibaYUeAAAAvklEQVQY022QVRPCMBCEL1RSg5Ji
    Ibi7W9Hi//8n0aRBHtiXvflm7mZvAQChmKJquq6pSgwhAE6wYRIh08CcIWTZ5CPb
    ChnCDvmRgxHEE9HspdIZ7ok4KG6EsjmaZ6G7CqgRKRQpLXFEVNAEKVeqNYk00LnV
    G81WWyJdINbp9voDOhxFiC+OJ3Q6m9PFciUW+fn1xt/6O7o/HMV5HsI7BcH5Qq83
    JkK8o5L74ymjfh5iHpMP/Xn7TznfCpOywhdM6Ra8aC+AYwAAACV0RVh0ZGF0ZTpj
    cmVhdGUAMjAyMS0wOC0xMFQwODozNToxNS0wNDowMHfS8a8AAAAldEVYdGRhdGU6
    bW9kaWZ5ADIwMjEtMDgtMTBUMDg6MzU6MTUtMDQ6MDAGj0kTAAAAAElFTkSuQmCC
}
image create photo ::tk::icons::5-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    7VBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/ICD/MjL/Li7/CQn/Bgb/q6v/8/P/8vL/9PT/4uL/FRX/0tL/
    ////wsL/xcX/uLj/Jib/Kyv/6ur/8fH/aGj/XV3/SUn/Fhb/AQH/+Pj//Pz/7Oz/
    +fn/l5f/Dg7/ODj/qan/sLD/W1v/fn7/9/f/+vr/WVn/EBD/Ghr/2dn/gID/X1//
    oKD/EhL/5OT/Y2P/S0v/7e3/vb3/ycn/yMj/HR3/AwP/Skr/zc3/LCz/BQX/DAz/
    AgKLBoLHAAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34AAAABYktHRB5yCiAr
    AAAAyUlEQVQY021Q1RLDMAxzVhp1XcbYMXXMzIz//zmLk9HD9GKdzvZJAgBCbJKs
    qKoiSzZCAFDR7A7K4bBrqBHidNEPXE6mEc1Nf+DWCOgeZD4/QyDImEcHyWAzFI5E
    I7F4gFFDAhmXEkkzmUpnsshlUHDk8oViqVyxkCug4ihXa/VGtNlCrgqp3en2+oPh
    SEj80AqO6WRqzsQhfz/PLJa5lbkW77mJzba225uHozDBrZ7Oncu+eaXC6ivQrXV/
    vAP9if2nnG+F3leFT2jDGOnV8F/uAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIxLTA4
    LTEwVDA4OjM1OjE1LTA0OjAwd9LxrwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMS0w
    OC0xMFQwODozNToxNS0wNDowMAaPSRMAAAAASUVORK5CYII=
}
image create photo ::tk::icons::6-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    9lBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/AQH/ICD/S0v/UlL/NDT/CAj/WVn/2dn/+Pj/+fn/8PD/jY3/
    Cgr/LCz/4OD//f3/hob/cHD/5eX/1NT/NTX/bGz/////39//T0//Bwf/j4//5ub/
    wcH/7+//4uL/f3//CQn/lpb/+/v/n5//iIj/8vL/9/f/UVH/hYX/3t7/Hx//vb3/
    VVX/6Oj/MzP/ExP/x8f/e3v/EhL/t7f/0tL/wMD/MTH/IiL/xsb/zc3/qKj/QkL/
    AgL/Cwv/Dg7/BQWiS7IgAAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34AAAAB
    YktHRCi9sLWyAAAAyklEQVQY021Q1RLCQBDbowalBYq7y+FWirs7/P/PwPawB/Ky
    mezsThIAIMTC8YIoCjxnIQQAFclq00zYrBJqhMh27QO7/NSIpGg/UCQCqgOZ2+P1
    +QPIHCpwTlSCoXAkGos/qZMDHleJZCqdyebyyHkQcBRoMeEvecrIBRBxVGi1Vm80
    W8hFJrWp3jG6vT6TzMMBHY4CY2qwQ/P9RJ/O5gu6ZO9NE6s13Wz14o6ZYFb3scPx
    dHYzq69Al+vt/g70J/afcr4Vul4VPgDLCRmO3FuJegAAACV0RVh0ZGF0ZTpjcmVh
    dGUAMjAyMS0wOC0xMFQwODozNToxNS0wNDowMHfS8a8AAAAldEVYdGRhdGU6bW9k
    aWZ5ADIwMjEtMDgtMTBUMDg6MzU6MTUtMDQ6MDAGj0kTAAAAAElFTkSuQmCC
}
image create photo ::tk::icons::7-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    xlBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/Hh7/Njb/NTX/Ghr/i4v/9/f/8/P/8vL/8fH/9PT/eHj/fHz/
    3Nz/2Nj/19f/6Oj/////+Pj/YGD/DQ3/Fxf/FRX/IiL/trb/j4//CQn/Zmb/+/v/
    xsb/GBj/HR3/0tL//f3/Xl7/ZGT/1dX/BAT/p6f/n5//AQH/Fhb/09P/c3P/GRn/
    mZn/qqr/PT3/AgKXVg1iAAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34AAAAB
    YktHRCJdZVysAAAAu0lEQVQY022Q1xKCMBBFN5LQixFR7Bp77wU7//9TJgTFB+7L
    njmTydxdAECooGCiqgQrBYQAhNF0gyYxdE04hEyL/mKZ3CHNpn+xNQSOy6Hkl3n8
    gKPrgOLxWamGYa3eaHL0FMDieavd6fZYfyAYAxFjOBpPpmw2F0xATf9dLFfrBNSv
    2mx3e5oqIuHAjoEkIr+npzO7RFJhWYJeb+wuDS+RVKWP5+stFa8qF4riOFsoZ+2c
    42QnLKYn/ADYChWCRPB9rQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wOC0xMFQw
    ODozNToxNS0wNDowMHfS8a8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDgtMTBU
    MDg6MzU6MTUtMDQ6MDAGj0kTAAAAAElFTkSuQmCC
}
image create photo ::tk::icons::8-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    6lBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/Bwf/MjL/UVH/TU3/Kir/BAT/DAz/j4//7e3/+Pj/5+f/eXn/
    BQX/Skr/9/f/7+//Z2f/fn7/+/v/6ur/MDD/UFD/4uL/Jib/QUH/9PT/NTX/EhL/
    srL/////09P/2tr/m5v/CAj/ycn//f3/y8v/1dX/s7P/GBj/hYX/HR3/Zmb/0dH/
    LCz/5eX/dHT/S0v/wsL/NDT/V1f/sLD/zc3/ysr/paX/RUX/AQH/Bgb/Dg7/DQ3m
    iTf5AAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34AAAABYktHRC8j1CARAAAA
    yklEQVQY021Q1RLCQBDbowZFSpEWh+J+xd3d/v936N5hD+QlmezsTrIAQIhLECVZ
    lkTBRQgAOorbozN43Ap6hKhe/QOv6nhE8ek/8CkE/AFUoXAkapioAn4QNIdj8UQy
    mUpnHKkJIOIom7PyhWKpjFoECalSrNbqDauJWgIZqdWmdod2e6hlbhn9wXBExxNu
    scUptWfhFJ3zRXY+TheT5Yqu+XkWYmMNtkNa3fEQLGpmfziezpcrj/oqdLs/zHeh
    P7X/POf7wuDrhU+46hlBGTVCQgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wOC0x
    MFQwODozNToxNS0wNDowMHfS8a8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDgt
    MTBUMDg6MzU6MTUtMDQ6MDAGj0kTAAAAAElFTkSuQmCC
}
image create photo ::tk::icons::9-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    8FBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/DAz/OTn/U1P/R0f/HBz/AQH/Fhb/oqL/8/P/+fn/+Pj/1NT/
    S0v/cXH/////29v/W1v/mJj/0ND/AgL/paX/np7/Ly//7e3//Pz/lZX/vr7/GBj/
    VVX/9fX/c3P/QED/5ub//f3/19f/4OD/+/v/eXn/Pz//mZn/oaH/dXX/6Oj/Z2f/
    Kir/cHD/enr/FRX/TU3/8PD/Ojr/Ozv/2tr/nJz/CAj/Tk7/sbH/z8//wcH/Bgb/
    Dw//CgoJOUsyAAAAEXRSTlMAAA5Vq9/4NK/0St3cDa7z4Pnet34AAAABYktHRCCz
    az2AAAAAy0lEQVQY022Q1RLCQAxFs9QovlAozuLu7u72/39D0y3yQB6SO2cmmXsD
    AITYBFGSZUkUbIQAIFHsKjVLtSvICHE46aecDoMRxUV/yqUQcHtQ+QNaMKSj8rhB
    8BozHInG4okkIq8AIs4US2eyLBdCLYJk9HyBFWmpXNEQSSDjqLJavdFkLdQyR+1O
    t9cfsCFHuEj10XgynbE5XzTPL5ar9Sa+3fHzpon9rFI7sOOJmzCt5s+X6221tqxa
    ge6Pp/4O9Cf2n+d8X+izXvgCm5cZM7QQ1AwAAAAldEVYdGRhdGU6Y3JlYXRlADIw
    MjEtMDgtMTBUMDg6MzU6MTUtMDQ6MDB30vGvAAAAJXRFWHRkYXRlOm1vZGlmeQAy
    MDIxLTA4LTEwVDA4OjM1OjE1LTA0OjAwBo9JEwAAAABJRU5ErkJggg==
}

image create photo ::tk::icons::9plus-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAB
    OFBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/ERH/AAD/NDT/AQH/AAD/AAD/Cgr/Nzf/U1P/SUn/Hx//AQH/mJj/8fH/+fn/
    2dn/VFT/BAT/YmL//f3/4uL/YGD/j4//IyP/GBj/xsb/xcX/Fxf/lZX/////rKz/
    JSX/5eX/3t7/3Nz/AgL/hob/yMj/Hh7/Skr/fn7/MTH/srL/vr7/9fX/NDT/NTX/
    39///v7/3d3/+vr/g4P/RET/9PT/+/v/8/P/R0f/OTn/lpb/pKT/c3P/4eH/dHT/
    Dw//Pz//VVX/5ub/ExP/JCT/bW3/fX3/Ghr/QUH/Rkb/Gxv/wsL/1dX/p6f/DAz/
    e3v/enr/Dg7/ra3/zs7/w8P/gYH/GRn/Bgb/CwuphzIHAAAAFHRSTlMAAA5Vq9/4
    NK/0St3cDa7z8/Ou4A5hHfoAAAABYktHRCy63XGrAAAA+ElEQVQY02NgYGBkZGJm
    YWVjY2VhZmJkZGAAibBzcIqAAScHO0iMkZGLWwQOuLmAYozsPCJIgIedkYGXT1RM
    XEJSCibGx8vAzC8tIysrJw/kKUhKKogIMDOwKCopq6gqyamJiKhraGqJiLAwsGrr
    6Erp6euoABUZGEoqGLEysBnrmJiayeiYW1haWVtbWdqwMbDZ2tnLOTjqODm7uNrb
    u7q5szGwinh4enn76Pj6+QcE6gf4B7EysASHhIaFu1lHiIhEGhiGgYxnFvSxj4rW
    iYkVEfGLi08AOYJXKCIxKTklFcmpQA+lJaRLIXsIi7exBA4iCIWhQQgAiNMk9J5+
    e/MAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDgtMTBUMDg6MzU6MTYtMDQ6MDBG
    OusyAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTA4LTEwVDA4OjM1OjE2LTA0OjAw
    N2dTjgAAAABJRU5ErkJggg==
}
image create photo ::tk::icons::!-badge -data {
    iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAABGdBTUEAALGPC/xh
    BQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA
    olBMVEUAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
    AAD/AAD/AAD/AAD/Fhb/QED/Pj7/ExP/VVX/9PT/8PD/SUn/WFj//v7/+fn/S0v/
    SEj/PDz/MjL/6Oj/Jyf/ICD/4+P/2Nj/Fxf/Dw//qKj/nZ3/Cgr/IyP/hIT/gYH/
    Hh7/PT3/Ly//paX/oqL/KCj/AgL///8V6AjgAAAAEXRSTlMAAA5Vq9/4NK/0St3c
    Da7z4Pnet34AAAABYktHRDXettlrAAAAoElEQVQY022QxxKCQBBEZ9hERkygophz
    lv//NmF3Bz0wp1dd1V3dAwCIDuNCSsGZgwjQKMr1Un2eqxoN0Q/S9gK/1lCF6d+F
    CiGKNfYHw5GGOAKWaBpn+URDwoAbw3RWzA1xEAYWRVYaEiANLPPV2pAkabPd7Umy
    xsPxdCajjb9cb3eKtyXq+AeVsFWfr/eHqtKgqmoHdczueM7vhT37wi9PRRMHXNeq
    aAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wOC0xMFQwODozNToxNi0wNDowMEY6
    6zIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDgtMTBUMDg6MzU6MTYtMDQ6MDA3
    Z1OOAAAAAElFTkSuQmCC
}


if {[tk windowingsystem] eq "x11"} {

    # ::tk::icons::IconBadge --
    # This procedure creates an icon with an overlay badge on systems that
    # do not have a native icon/badge API.
    #
    # Arguments:
    # win - window name
    # badgenumber - badge number to draw over the window icon

    proc ::tk::icons::IconBadge {win badgenumber} {

	variable ::tk::icons::base_icon

	if {![info exists ::tk::icons::base_icon]} {
	    return -code error "::tk::icons::base_icon($win) must be set on X11"
	}

	if {![info exists ::tk::icons::base_icon($win)]} {
	    return -code error "::tk::icons::base_icon($win) must be set on X11"
	}

	if {[lsearch -exact [image names] $::tk::icons::base_icon($win)] <= 0} {
	    return -code error "can't use \"$::tk::icons::base_icon($win)\" as iconphoto: not a photo image"
	}

	if {!([string is integer $badgenumber] && $badgenumber > 0)
	        && [string match $badgenumber "!"] == 0
	        && $badgenumber ne ""} {
	    return -code error "can't use \"$badgenumber\" as icon badge"
	}

	wm iconphoto $win $::tk::icons::base_icon($win)

	if {$badgenumber eq ""} {
	    return
	}

	image create photo overlay

	switch -glob -- $badgenumber {
	    ! {
		set badge ::tk::icons::!-badge
	    }
	    [1-9] {
		set badge ::tk::icons::$badgenumber-badge
	    }
	    default {
		set badge ::tk::icons::9plus-badge
	    }

        }

	overlay copy $::tk::icons::base_icon($win)
	overlay copy $badge -from 0 0 18 18 -to 18 0
	wm iconphoto $win overlay

    }
}

Changes to library/iconlist.tcl.

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

::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







|







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

::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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
	foreach sublist $list {
	    set usedColumn 1
	    lassign $sublist iTag tTag rTag iW iH tW tH

	    set i_dy [expr {($dy - $iH)/2}]
	    set t_dy [expr {($dy - $tH)/2}]

	    $canvas coords $iTag $x                    [expr {$y + $i_dy}]
	    $canvas coords $tTag [expr {$x + $shift}]  [expr {$y + $t_dy}]
	    $canvas coords $rTag $x $y [expr {$x+$dx}] [expr {$y+$dy}]

	    incr y $dy
	    if {($y + $dy) > $H} {
		set y [expr {$pad * 1}] ; # *1 ?
		incr x $dx
		set usedColumn 0







|
|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
	foreach sublist $list {
	    set usedColumn 1
	    lassign $sublist iTag tTag rTag iW iH tW tH

	    set i_dy [expr {($dy - $iH)/2}]
	    set t_dy [expr {($dy - $tH)/2}]

	    $canvas coords $iTag $x [expr {$y + $i_dy}]
	    $canvas coords $tTag [expr {$x + $shift}] [expr {$y + $t_dy}]
	    $canvas coords $rTag $x $y [expr {$x+$dx}] [expr {$y+$dy}]

	    incr y $dy
	    if {($y + $dy) > $H} {
		set y [expr {$pad * 1}] ; # *1 ?
		incr x $dx
		set usedColumn 0
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
	}

	my DrawSelection
    }

    method DrawSelection {} {
	$canvas delete selection
	$canvas itemconfigure selectionText -fill black
	$canvas dtag selectionText
	set cbg [ttk::style lookup TEntry -selectbackground focus]
	set cfg [ttk::style lookup TEntry -selectforeground focus]
	foreach item $selection {
	    set rTag [lindex $list $item 2]
	    foreach {iTag tTag text serial} $itemList($rTag) {
		break







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
	}

	my DrawSelection
    }

    method DrawSelection {} {
	$canvas delete selection
	$canvas itemconfigure selectionText -fill $fill
	$canvas dtag selectionText
	set cbg [ttk::style lookup TEntry -selectbackground focus]
	set cfg [ttk::style lookup TEntry -selectforeground focus]
	foreach item $selection {
	    set rTag [lindex $list $item 2]
	    foreach {iTag tTag text serial} $itemList($rTag) {
		break
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
    #	operations.
    #
    method Create {} {
	variable hull
	set sbar [ttk::scrollbar $hull.sbar -orient horizontal -takefocus 0]
	catch {$sbar configure -highlightthickness 0}
	set canvas [canvas $hull.canvas -highlightthick 0 -takefocus 1 \

			-width 400 -height 120 -background white]
	pack $sbar -side bottom -fill x -padx 2 -pady {0 2}
	pack $canvas -expand yes -fill both -padx 2 -pady {2 0}

	$sbar configure -command [list $canvas xview]
	$canvas configure -xscrollcommand [list $sbar set]

	# Initializes the max icon/text width and height and other variables
	#
	set maxIW 1
	set maxIH 1
	set maxTW 1
	set maxTH 1
	set numItems 0
	set noScroll 1
	set selection {}
	set index(anchor) ""
	set fg [option get $canvas foreground Foreground]
	if {$fg eq ""} {
	    set fill black
	} else {
	    set fill $fg
	}

	# Creates the event bindings.
	#
	bind $canvas <Configure>	[namespace code {my WhenIdle Arrange}]

	bind $canvas <Button-1>		[namespace code {my Btn1 %x %y}]
	bind $canvas <B1-Motion>	[namespace code {my Motion1 %x %y}]







>
|
|
|














<
<
<
<
|
<







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425




426

427
428
429
430
431
432
433
    #	operations.
    #
    method Create {} {
	variable hull
	set sbar [ttk::scrollbar $hull.sbar -orient horizontal -takefocus 0]
	catch {$sbar configure -highlightthickness 0}
	set canvas [canvas $hull.canvas -highlightthick 0 -takefocus 1 \
			-width 300p -height 90p \
			-background [ttk::style lookup Treeview -background {} white]]
	pack $sbar -side bottom -fill x -padx 1.5p -pady {0 1.5p}
	pack $canvas -expand yes -fill both -padx 1.5p -pady {1.5p 0}

	$sbar configure -command [list $canvas xview]
	$canvas configure -xscrollcommand [list $sbar set]

	# Initializes the max icon/text width and height and other variables
	#
	set maxIW 1
	set maxIH 1
	set maxTW 1
	set maxTH 1
	set numItems 0
	set noScroll 1
	set selection {}
	set index(anchor) ""




	set fill [ttk::style lookup Treeview -foreground {} black]


	# Creates the event bindings.
	#
	bind $canvas <Configure>	[namespace code {my WhenIdle Arrange}]

	bind $canvas <Button-1>		[namespace code {my Btn1 %x %y}]
	bind $canvas <B1-Motion>	[namespace code {my Motion1 %x %y}]
452
453
454
455
456
457
458


459

460
461
462
463
464
465
466
467

	bind $canvas <<PrevLine>>	[namespace code {my UpDown -1}]
	bind $canvas <<NextLine>>	[namespace code {my UpDown  1}]
	bind $canvas <<PrevChar>>	[namespace code {my LeftRight -1}]
	bind $canvas <<NextChar>>	[namespace code {my LeftRight  1}]
	bind $canvas <Return>		[namespace code {my ReturnKey}]
	bind $canvas <Key>		[namespace code {my KeyPress %A}]


	bind $canvas <Control-Key> ";"

	bind $canvas <Alt-Key>	";"

	bind $canvas <FocusIn>		[namespace code {my FocusIn}]
	bind $canvas <FocusOut>		[namespace code {my FocusOut}]

	return $w
    }








>
>
|
>
|







448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

	bind $canvas <<PrevLine>>	[namespace code {my UpDown -1}]
	bind $canvas <<NextLine>>	[namespace code {my UpDown  1}]
	bind $canvas <<PrevChar>>	[namespace code {my LeftRight -1}]
	bind $canvas <<NextChar>>	[namespace code {my LeftRight  1}]
	bind $canvas <Return>		[namespace code {my ReturnKey}]
	bind $canvas <Key>		[namespace code {my KeyPress %A}]
	bind $canvas <Alt-Key>		{# nothing}
	bind $canvas <Meta-Key> 	{# nothing}
	bind $canvas <Control-Key> 	{# nothing}
	bind $canvas <Command-Key> 	{# nothing}
	bind $canvas <Fn-Key>		{# nothing}

	bind $canvas <FocusIn>		[namespace code {my FocusIn}]
	bind $canvas <FocusOut>		[namespace code {my FocusOut}]

	return $w
    }

Changes to library/icons.tcl.

1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41









42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152





153
# icons.tcl --
#
#	A set of stock icons for use in Tk dialogs. The icons used here
#	were provided by the Tango Desktop project which provides a
#	unified set of high quality icons licensed under the
#	Creative Commons Attribution Share-Alike license
#	(http://creativecommons.org/licenses/by-sa/3.0/)
#
#	See http://tango.freedesktop.org/Tango_Desktop_Project
#
# Copyright © 2009 Pat Thoyts <[email protected]>



namespace eval ::tk::icons {}

image create photo ::tk::icons::warning -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAABSZJREFU
    WIXll1toVEcYgL+Zc87u2Yu7MYmrWRuTJuvdiMuqiJd4yYKXgMQKVkSjFR80kFIVJfWCWlvpg4h9
    8sXGWGof8iKNICYSo6JgkCBEJRG8ImYThNrNxmaTeM7pQ5IlJkabi0/9YZhhZv7///4z/8zPgf+7
    KCNRLgdlJijXwRyuDTlcxV9hbzv8nQmxMjg+XDtiOEplkG9PSfkztGmTgmFQd+FCVzwa3fYN/PHZ
    AcpBaReicW5xcbb64IEQqko8Lc26d/58cxS+/BY6hmJvyEfQBoUpwWCmW1FErKaGWHU13uRk4QkE
    UtxQNFR7QwIoB4eiKD9PWbVKbb10CZmaCqmpxCormRYO26QQx85B0mcD+AeK0xYvHqu1tNDx+DH6
    gQM4jh0j3tCA3tGBLyfHLuD7zwJwAcYqun44sHy51nr5MsqsWWj5+djCYdS5c4ldvUr24sU2qarf
    lUL6qAN0wqH0vDy7+fAhXZEI+v79CNmt7igpofPVK5SmJvyhkJBwYlQBSiHd7vUWZ86bp8WqqtCW
    LkVbuBAhBEIItGAQ2+rVxG7cICMY1KTDsekc5IwagIQTmStXis47dzBiMfR9+xCi+wb39s79+zFi
    MczGRjLmzTMlnBoVgLMwyzF+/Cb/lClq2/Xr2AoKUKdPxzAMWltbiUajmKaJkpGBY8sW3tbW4g8E
    VNXrXVEKK0YMoMKp7Px8K15Tg2VZOHbvBiASiRAMBgkGg0QiEYQQOIuLsRSFrnv3yJo/HxVOW594
    7D4KUAa57qysvNSUFOVtbS32rVuRfj9CCFwuV2Kfy+VCCIFMScFVVET7/fukJidLm883rQy+HhaA
    BUII8cvUNWt4W1WFcLvRd+5MnHl/AOjOB+eOHchx44jX1ZEdCqkSTpaDbcgA5+GrpNmzc9ymKdvr
    67Hv2oVMSko4cjgcKIqCoijoup64EdLpxLV3Lx1PnuCVUrgmTfK9hV1DAjgKqlSUk1PCYdl25QrS
    70cvLEw4SWS+04nT6XxvXgiBc8MGtKlTaa+rIysnR1Ok/OF38PxngAzY4VuwYKL99WvR8fQpjj17
    kLqeiL6393g8eDyeAWBSVfEcOkRXczOOaBRvVpZuDPJEDwD4DVyKrv+UlZurxSorUWfMQC8oGOBc
    CDHgC/Rdc4TD2BctIl5fT+bkyTahaXvOw8RPApiwd2Ju7hjZ2EhXSwvOkhKQcoADgIqKCioqKgYc
    QW9LOnIEIxZDbWpiXCCABT9+FKAUxtm83pKMUEiLVVejLVqEtmTJB50LIdi2bRuFPbnRd7232efM
    wbVuHR2PHjHR77dJXS8sg5mDAihweFJenmrevYvR1oazpGTQ6IQQaJqG7ClI/dd655IOHsSyLMSL
    F6QFAib9nugEQClk2Xy+orTsbK3t1i3sa9ei5eQMGr0QgvLyci5evDiocyEEtsxMPNu30/nsGRO8
    XlVzu8NlkNvrV+0T/fHMZcusrtu3MeNx9PXrobUVq8cYQrw3TrRub1h9+v573Bs3Ej1zBvP5c/zp
    6dbLhoaTwPy+ANKCfF92thq7dg2A6JYt/fNlxGK8eUNSerryHEJHQT8K8V4A5ztojty8OeaLzZul
    1DSwLCzDANPEMozusWFgmWZ33288YK3/nGlixuM0v3xpWfDX0Z4i1VupXEWwIgRnJfhGPfQ+YsLr
    +7DzNFwCuvqWyiRg7DSYoIBu9smPkYqEd4AwIN4ITUAL0A4Da7UC6ICdEfy2fUBMoAvo7GnWKNoe
    mfwLcAuinuFNL7QAAAAASUVORK5CYII=
}










image create photo ::tk::icons::error -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAABiRJREFU
    WIXFl11sHFcVgL97Z/bX693sbtd2ipOqCU7sQKukFYUigQgv/a+hoZGoqipvfQKpAsEDD0hIvCHE
    j/pQ3sIDUdOiIqUyqXioEFSUhqit7cRJFJpEruxs1mt77Z3d2Z259/KwM5vZXTtOERJXOrozZ+6e
    852fuXcW/s9D3O3Cs1Bow1Nx234BKQ9qpYpK6yFLSseScsVoveApdUrAzNOw9j8DOAMTtmX9RsM3
    SqOjevcXDqUzu8dI5AvEc8O0axu4q6s4yzdZvnCxUSmXLWHMXzxjXpmGq/81wGmIZ6T8NXDi8w8d
    id//+GPS8j1YWQXHgVYbfA/sGCRiMDQExTzKtvn3zDv6k9m5FsacXNT6+y+D95kAZqCEEO/cMzIy
    9eBLLybjyodrN6DpDqw1/dfpFNw3TtuSfPz7P7irlZUL2pjHn4GVuwJ4G/JCiLl9U1OjB58/ZnP5
    Mqxv3NGpMWZAz64cHNzHlTf/5N9YuHzTMeaLx6HW78+K3pwGKynEu/snJycOHPuWzdw81BuDUQZO
    dfQ+MmvAuC1MdY3i178izUo15VZXj07DyTf6OGX0Jivlz0vFwgMTz3/bNnMXO0ZCo8b0iIk4C0WF
    zsP1TRc1e4l9x56N5YuFwxkpf9afgW4J/gi7M1IuHH3lezm5uAQbmwOpjc79ujArA2uMgWwGMz7K
    P377u/WW1pPTUB7IQFrKXx44NJWRbQ9d2+hGqbeRMEoTZEQFJdERfVgmvVFH+D57Jw9k4lL+YqAE
    pyGnjZm+95knLHVjcVvHA6WIPgtLE+hVH4i6vsS9T3zTVsY8NwPZHoAUPFUs5JVQCt1q9zqORKm3
    iLKrF6IjkfSHOiUlqu0hhCSXHdYePNYDEBPiu6MT+zOquo6JGNGhESkxUnYNmkCnLQtjWRgpMRG9
    CtZ3JdD7axsU9+3N2EK8EALYQcNMpvfuQTcaXUMIAa+/Hi0Xgs9weASjefx4p5mFQDdbpD63G/HR
    hakeAA2l+EgJU652iIMMyO2sRoYxBq1191oIgZQSITqooT0A7fnEirswUAp/LwG0MZlYIY9WqpPa
    IHU7Da01Sqluo4UQSil830dr3emVsBeMIZbLoI0Z7gGQQtTbjoOOxW/XewcApVQ38jsBNs6fx6tW
    O70Si+GWKwghNsM1NoCAW81KJTeUjKNbrR2N7uS4B7TRwJ+fR6TTxO4fxzUeAio9AMCl+tVrE0NH
    DmM2nU4DAu6JE53UGoNfLuNdv45xnO4OF/ZKz+4X2T179I6D5To0NupouNgD4Btzqjx/8WjpS0cy
    PU1Tr6MqFfylpc4bss1W26/rBwyfybECtcvXNrUxp3oAXJjZ2Kxb7cVP8P61gDGgWy2M624Z5d1E
    3wNkDDKdwMQkjtuygbMhgAQ4DjUhxFvL/5z15X1jeLUaynW7p1u484WiuL3V9m/NoV6F50Ogjx3Y
    Q/mDBV8a3piGzR4AAFfrHy4vlesmm0bks7edRQ6aAafcPoZVH2AUXOYzkI5TvbVa9+FHREYX4Bgs
    I8RrV9/9oJF4eBKTjO8YvdoCJgqujcGkEqQemmDxb7OOFOLV6FHcAwBQ1/onTtOd/fTvH3rJRx/A
    pBIDqd0q+p5sRaInnWDoywdZem+u7bbaH9W1/il9Y2Brfwt22TBfKOVHxr92JOacv4S/UuttuC06
    PKoHsEs5hg7vZ/m9eW+zWltuwoNbfRNuebacgXsEnE2lkof2Hn04ZRouzQvXUU5z29cwFGs4TWpy
    HJGK8+lfP256bnuuDU8+B9WtfG17uL0GsTF4VQrxYn60kBh55JDEbdG6uYq/7qDdFtpTELOQyQRW
    Lk1sLI+MW9w6d8Wv3Vrz2nDyJPzgDDS287MVgAAywBCQ+Q5MTsOPs/BIMpVQ2bFCKlnMYg+nsYeS
    eE6TVq1Be3WD9ZtrTc9tWetw7k341dtwBagDTmTeESAdAAxH5z0w9iQ8ehi+moWxBGRsiPvguVBf
    h8qH8P6f4dxSp9PrdN73cN6k859R3U0J0nS+28JMpIM5FUgCiNP5X2ECox7gAk06KQ8ldLzZ7/xO
    ANHnscBhCkgGjuOB3gb8CEAbaAWO3UA34DQ6/gPnmhBFs5mqXAAAAABJRU5ErkJggg==
}








image create photo ::tk::icons::information -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
    WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gUdFDM4pWaDogAABwNJREFUWMPFlltsVNcVhv+199ln
    bh7PjAdfMGNDcA04EKMkJlIsBVJVbRqlEVUrqyW0QAtFTVWpjVpFfamUF6K+tCTKQyXn0jaiShOr
    bRqRoHJpEEoIEBucENuk2OViPB5f5j5zrvuc3YcMFQ8FPBFVj7S0paN91v+tf1/OAv7PD9UzeeCp
    p0KRCrYyHtymoPrgySYAANdyBBr2Peu1agP+NrR/v3nHAb6/52d7wfivWlet11NdvZG21laEwzo0
    RvA9F4uLi7h08bxxaWLUVp78xSsv/XrwjgAMDDyjRxPWUGOy5Uu9/VsjEA3I5KvIVQ240gHIh9CA
    5YkwelIJRATw94NvGpnpK0fL+eDA0NAzzq3ya7cDjCbsoWWr1j+y4f4vB/41Z8JTeaxqE7hndSNi
    EeELzn3LkapQdfzJTE5JV/GBb28LHz327lcnzp4ZAvB1AOpmAvyWtv/g6R9GW1c+uf6Bx0Kfzpjo
    TmnYtDaKtkTAj4aEFBqTnJPUOfciIeG3N4XVQtmyzl/JuY8/fH9wOjO/smvVmuy5s+8P1w2wa9dP
    46SLN3sf2ha7uiixaU0Qna06NA6PMXIZQRJBMiIXRBKABygv3hBQV+bK1dmcoR7d3Bc5c/pk/8YN
    fYOjo6es/6bDbgbAdLa9uXNj2PYF2pOEloQGAiRIuUTkME42J7IZweYES+NkckZWWNfseEPAKJtO
    oWxLu69/c5jpbPtNdW7qPwvsbO1cF8pVLKxs0+HD94gpl0AOQTlEsDkjizFmMk4WESyNM4NzMgOC
    VYI6q17OlIp9992ngek769+EvtfVEI3jWqaKgAgAIAlFLuOwGZHDiTnElGQgF4DvM1LKV7Bdz2NE
    xaCuhQpVm1Y0p5qhvNV1AyjlRTWhwVM2TMdzgkJzieAQyGGMbMZgfwZBEiBPA3xX+VSouAvBAFeM
    yDddD7rgpHw/WjcAMa0EZScZk5heqFrxiO4BzCGCzYgsBrI4I5sYcxlBKl/5WdOdd6S0gxoLEZEi
    Iq4AnzGq1r0HiPhYuZRFU1R3FgqWkS1aZQA2gWzOyGQcJudkaAwVR3qz8yXzvCXlzJoViaagrlWC
    jJnLm8Jarli2GNMm6wbwPPO31y6Ollc2N3pcI+fyYjW/8a5EKqQTz5WtdLHsTi1W7Im5vDlcMdxx
    wVk2Ys9/pTI3+WhAaIauM+MLbYnlH46MVKVyX6v7Hhg9e2ps3doN32ld0Rlrb1nmmK4stCdCSCUj
    Le1NwW6uXJ08m/t2OarBXh0ie0syHu0plKtTFGw8n4o33q1z1XngD7+X3C/uHBkZces7hoAi1946
    fPSvtpDlYFdLPDI8mR03HC87frXwFpgqLYuFuzrbkg8m49EeDsqDa+cizXcNpppia5ui+sYXnn+O
    29LbOTg4aHzun9GOPT/pDemhf3xzx25DicjkiqaAIs4zhumMRUJaPhzgJZ0LQ5C7gXjQL1kS0YD+
    o337nhWlYvHJV178zZ9vlZ/dDuDVl57/2HWt755894hINoYSmZx11TYKCUZKCs4cnQuDmGtfvDiR
    dD3n04aA6J4YHzeLhfLg7cSXBAAA5NPpufS1WFjwkFSelZ6ZLWfn0kliTDJdue8dO9qenp2d1DVR
    4cTarlyZJgV5dim5lwTw8sv7c1L6H89cm6FlDcHVhlOJffThsa9d+ud72y5+cnTn2PjJJ1avjOoE
    SnBiPadOfRDTGT5YSm5tqR2R7Zp7//L6gRPf27NjVaolqS9MCzh28W6mgDXdKxCNRb/oOlV18O3D
    1xzXGXpx8LnZO94Tbt/x+MFYouexh7dsQU/PWjRGI+BcAyMgm1vAO28fxvj4xOX5jL7u0KEX7Dvq
    AAC0Nucf2rLZhq8Y3njjT8gulOBKDw0NAQjNQT435eQWL3iHDk3YS81ZF0B6psI/GbuAXbu+gQf7
    H4ArPeQWC5jLZKCUhQvjWb2QD3bVk5PVM9nz5LML8waOH38fekBHIhFDqqMFXd0pnDhxGmMTU3Bd
    9/X/GQDntO/eezswMPBjaFwAABxH4sKFq+jt7cX6ni6EQuJbdeWsZ3J3d/PTmqaEYUyhXDZBTEOh
    WIIQwOi5jzA1eRnZXPFSPO7/bmbGlLfqhus5BVotRH9/x7rGxtBeIQJPACrMOYNSPpRiUIpnlTIO
    nzmT+eX8fLH8WZMKF4Csje7ncUAHEKhFcHq6ZE5OZoc7O3tlc3N33+7dP9c2bXoE09NlO52uHDhy
    ZOTVatUWte+otsTXg2pQSwagG6r/jwsAQul0erqjo+OesbGx1tHRUT+fz48dP378j57neQD8mtB1
    B1TtnV9zo64loJqoXhtFDUQHEGhvb2/2fZ9nMpliTcAFYNdC1sIBYN1sCeq5Ca9bqtWcu9Fe3FDl
    9Uqvu3HLjfhvTUo85WzjhogAAAAASUVORK5CYII=
}

image create photo ::tk::icons::question -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAACG5JREFU
    WIXFl3twVdUVxn97n3Nubm7euZcghEdeBBICEQUFIgVECqIo1uJMp3WodqyjMzpjZ7TTh20cK31N
    /2jL2FYdKXaqRcbnDKGpoBFaAY1BHgHMgyRKQkJy87yv3Nyzd/84594k1RlppzPumTXn3Dl3r/Wd
    b31rrbPhS17iSv+4bl2t2ZFhrRGI7QKxRkMAyHEfjwgYEOgjNnpfcXjiSENDbeL/AqBoW22uGE/7
    MYL7yubN4MYVpVkrquaKqwJZ+LPTARgcjdIbHKOx+aI+9EH7WGvnZdA8q9PGf9b5eu3w/wygaPPO
    h6Uhntxcsyj9/q+vtMrnBa6Is7ZPgzzzyvGJ/YfPRpWWj3fWff93/xWAonW1Xu3z/nVx6cxNTz74
    1YzK4gIQjuN/nfyEEx9fIjgaYXAkhhAQyE3Hn5PBsvJZrF46l5I5+QB83NnP40+/FT7d1ltPOPrN
    zoba2BcCWLy91hMOp72/bX1VxU/u3+BJ91i0fhrkuTcaaTzbjTQkhpQIIZBSIBApL1prtNYsryhk
    xy1XUzonn1g8wVPPvh1/5dDpcz5f7LrmfbXxqfGM6eG1yCw+9uq2G6tW7nxoU5plGrzecJYnnnub
    SwMhTNPAmmKmYWCaBoYpMQyJaRhIQ3IpGOKt4+1k+dKoLJ7BjStKjb6hcN7JloFrhlsO7oUnPh9A
    8Rbvo6uuLrr3N4/ckm4Ykt/vPcqe/R9hGAamaWJZbnDL+W2axqRJA8NlxzAkAI3newhF4lxbMZs1
    y4rNM+19c0PZ++NDLQff+0wKCu/Y6c/UVsubv/12/ryZubxUf5Ln3vgQ0zKnvK1kadkMlpQUUFEU
    oCDPR25WOuPxBH2DYZpa+qg/3kEoGsdWCttWJGzF3ZuXcuf6Ci5eHmXrw7sHR4mXd7/2w+A0Bvyl
    N+265/bl19+8eqE8c6GPn+85jGkYWC4Ay3Luf/3AV1g038+MXB8+rwfDkKR5TPKyvCyan8+qqtmc
    au8nFrcdnQCn2vuoLptJSWEeE7bynDjdXTDUcvBNAAmweF1tpmXKu+65bYWh0Ty97zhSyGkUO0BM
    hBAI4RAXTyjiCYWUEukKMz/Ly/b1C7EsE49lYlkmhjTYvf8jNHD3lmsM0zTuWryuNhPABIj4vFvW
    Xl0s87PTOdXWS8snQTwec4ro3DSYBglbcfx8P+8199I7FMEQgg3L53N7TWkKXOV8Px7LJCFtXKx0
    dA9zrnOAyqIAa68tkQePtm4BXpaO9vWOm65b4EPAkY+6HDEZTt4NN/dJML946QSv/fMCA6PjpHks
    LI/F2a5BtNYpMUtJirGpLL7f3A3AxpXlPiHFjhQDaJZVlc0EoPWT4DQ1m8ZkKizTJDRuY1mmC04i
    pWDNksJUD9Bac7E/jGUZrmuN1qCU5sKlIQAqSwrQWi+bBCDwF+RnAk5fl27wqeYAkZM9wLWaxVex
    qnJmKritFO+e7sMyDdBOc1JKYxiSkdA4CMGM3Aw02j+VAfLcwTIWibuiEpNApJMSw208ydJcu3QW
    axZPCW7bHGjspmcwimkYTmAlMWzHTyTmDMiczLRU/ctkNxgajboPvUghppuUGFJMY6O6OJ/ViwIo
    pVBKYds2dR9e4uPuMbc7Tm9MUgqyM70AjITHUy1IAghNsH8oDEAgz4cQOIqWjkkpEC4rSYfXL/Sn
    giulONYyRFd/1GXKAZxkUrgvkp/tAAgORxAQnAQg5InmC5cBWDgv4NS5EAhAINzyIlVmUgiy040U
    9Uop2voiKYakEAiRvDp7EYKS2XkAnOvsR0h5IqUBrfWeQ8fb1t2xvtJXs3QuB462TfZokbxMGZxC
    8If6DtI8Fh6PhcdjojSpBuXin7Kc3csXzQLgrWOtEWWrPSkAvkis7kjTBTU8FqOypIAF8/x09Y6Q
    FGjyTdHJstLsWDsnNZIBXj7Wj1LKYSS5B412nRTNymHBnHxGQ+O8836r8kVidakUNDfUhhIJtfcv
    dU22AO69dRlCCNeZU8fJe6U0ylZYBlgGmNKx+ESCiYRNwlYoWzn/UxqtHOB3ra8AAX/7x0nbttXe
    5oba0GQVAPGE9dju1z4Y7u4fY9F8P9/YWOUEV06O7eTVnXBTBaiUIj4xwcSETSJhk7BtbNtOPdta
    U0ZpYS59wRB/2ndsOBa3HkvGTU3D0fb6aE7ZBt3RM1yzuabcqiwKEI5N0N495ChaSKcihJPRa0pz
    sbUmYTugPmgbJmErB4DLxETC5oYlhWxdXUrCVvxgV32krav/qa4Djx76D4kllxalt/7q9e2bqjf9
    9Lsb0oQQHGrsYO+hc0gp3emW/Bhxm5NbZlqD0g79CTcFt60u4YYlhWhg5/MN4y/WNdW3vfnoNhD6
    Mww46wlmV9/w6snzA1sHRqKBVUvnGQvm+qkuKyA4GqVvKOJAdrcn8zz14yNh2ywozOVbGyuoKg4w
    PmHzyxcOx1+sazqTlhbZ3H92vT29Pj5nzVn1SLqVH3ipunzOxqceutlX6n7lXrw8yqn2flq7hxgL
    TzAWiyOFICfTS44vjbLCXKqK/cwOOHOl49IwP9r192hT84V3e4+9cF90sC0IRL8QAOADsgvXfu9B
    b3bgkTs3LPN+52srzPlX5V7RUerTy6M8/0Zj4uUDH45Hg13PdB/9425gzLUhQH0RgDQgC8hKLyid
    7a/c9oCV4d9WVTpLbF5TmX5tRaGYkecjJ8MLAkZD4wyMRGg636PrDjfHzrT26NhYT33w1Kt/Hh/u
    6XUDh4BBIHwlDIBTohlANpBhWb6s7PKNK30FCzZa6dnVYORoIX2OExVF26Px8NCZSN/5d0bb3mlK
    JGIhHLpDwLAL4jPnxSs9nBqABXhddrw4XdRygSrABuKuxYBx9/6KDqlf2vo3PYe56vmkuwMAAAAA
    SUVORK5CYII=





}



|


|

|


>
>



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

























18
19
20
21
22
23
24
25
26
27
28






























29
30
31
32
33
34
35
36
37









38
39
40
41
42
43
44
45


















46
47
48








































49
50
51
52
53
54
# icons.tcl --
#
#	A set of stock icons for use in Tk dialogs. The icons used here
#	were provided by the Vimix Icon Theme project, which provides a
#	unified set of high quality icons licensed under the
#	Creative Commons Attribution Share-Alike license
#	(https://creativecommons.org/licenses/by-sa/4.0/)
#
#	See https://github.com/vinceliuice/vimix-icon-theme
#
# Copyright © 2009 Pat Thoyts <[email protected]>
# Copyright © 2022 Harald Oehlmann <[email protected]>
# Copyright © 2022 Csaba Nemethi <[email protected]>

namespace eval ::tk::icons {}

variable ::tk::svgFmt [list svg -scale [expr {[::tk::ScalingPct] / 100.0}]]


























image create photo ::tk::icons::error -format $::tk::svgFmt -data {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="32" height="32" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <circle cx="16" cy="16" r="16" fill="#d32f2f"/>
     <g transform="rotate(45,16,16)" fill="#fff">
      <rect x="6" y="14" width="20" height="4"/>
      <rect x="14" y="6" width="4" height="20"/>
     </g>
    </svg>
}































image create photo ::tk::icons::warning -format $::tk::svgFmt -data {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="32" height="32" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <circle cx="16" cy="16" r="16" fill="#f67400"/>
     <circle cx="16" cy="24" r="2" fill="#fff"/>
     <path d="m14 20h4v-14h-4z" fill="#fff"/>
    </svg>
}










image create photo ::tk::icons::information -format $::tk::svgFmt -data {
    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="32" height="32" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <circle cx="16" cy="16" r="16" fill="#2091df"/>
     <circle cx="16" cy="8" r="2" fill="#fff"/>
     <path d="m14 12h4v14h-4z" fill="#fff"/>
    </svg>


















}

image create photo ::tk::icons::question -format $::tk::svgFmt -data {








































    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="32" height="32" version="1.1" xmlns="http://www.w3.org/2000/svg">
     <circle cx="16" cy="16" r="16" fill="#5c6bc0"/>
     <path d="m17.6 27.2h-3.2v-3.2h3.2zm3.312-12.4-1.44 1.472c-1.152 1.168-1.872 2.128-1.872 4.528h-3.2v-0.8c0-1.76 0.72-3.36 1.872-4.528l1.984-2.016a3.128 3.128 0 0 0 0.944-2.256c0-1.76-1.44-3.2-3.2-3.2s-3.2 1.44-3.2 3.2h-3.2c0-3.536 2.864-6.4 6.4-6.4s6.4 2.864 6.4 6.4c0 1.408-0.576 2.688-1.488 3.6z" fill="#fff"/>
    </svg>
}

Changes to library/listbox.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# listbox.tcl --
#
# This file defines the default bindings for Tk listbox widgets
# and provides procedures that help in implementing those bindings.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998 by Scriptics Corporation.
#
# 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:
#







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# listbox.tcl --
#
# This file defines the default bindings for Tk listbox widgets
# and provides procedures that help in implementing those bindings.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998 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:
#
171
172
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
}

bind Listbox <MouseWheel> {
    tk::MouseWheel %W y %D -30.0
}
bind Listbox <Option-MouseWheel> {
    tk::MouseWheel %W y %D -3.0
}
bind Listbox <Shift-MouseWheel> {
    tk::MouseWheel %W x %D -30.0
}
bind Listbox <Shift-Option-MouseWheel> {
    tk::MouseWheel %W x %D -3.0












}

# ::tk::ListboxBeginSelect --
#
# This procedure is typically invoked on button-1 presses.  It begins
# the process of making a selection in the listbox.  Its exact behavior
# depends on the selection mode currently in effect for the listbox;







<

|


|


|


|
>
>
>
>
>
>
>
>
>
>
>
>







171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

bind Listbox <Button-2> {
    %W scan mark %x %y
}
bind Listbox <B2-Motion> {
    %W scan dragto %x %y
}

bind Listbox <MouseWheel> {
    tk::MouseWheel %W y %D -40.0 units
}
bind Listbox <Option-MouseWheel> {
    tk::MouseWheel %W y %D -12.0 units
}
bind Listbox <Shift-MouseWheel> {
    tk::MouseWheel %W x %D -40.0 units
}
bind Listbox <Shift-Option-MouseWheel> {
    tk::MouseWheel %W x %D -12.0 units
}
bind Listbox <TouchpadScroll> {
    if {%# %% 5 != 0} {
	return
    }
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    if {$deltaX != 0} {
 	%W xview scroll [expr {-$deltaX}] units
    }
    if {$deltaY != 0} {
	%W yview scroll [expr {-$deltaY}] units
    }
}

# ::tk::ListboxBeginSelect --
#
# This procedure is typically invoked on button-1 presses.  It begins
# the process of making a selection in the listbox.  Its exact behavior
# depends on the selection mode currently in effect for the listbox;
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
	    $w selection clear 0 end
	    $w selection set $el
	    set Priv(listboxPrev) $el
	    tk::FireListboxSelectEvent $w
	}
	extended {
	    set i $Priv(listboxPrev)
	    if {$i eq ""} {
		set i $el
		$w selection set $el
	    }
	    if {[$w selection includes anchor]} {
		$w selection clear $i $el
		$w selection set anchor $el
	    } else {







|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
	    $w selection clear 0 end
	    $w selection set $el
	    set Priv(listboxPrev) $el
	    tk::FireListboxSelectEvent $w
	}
	extended {
	    set i $Priv(listboxPrev)
	    if {$i < 0} {
		set i $el
		$w selection set $el
	    }
	    if {[$w selection includes anchor]} {
		$w selection clear $i $el
		$w selection set anchor $el
	    } else {
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
proc ::tk::ListboxCancel w {
    variable ::tk::Priv
    if {[$w cget -selectmode] ne "extended"} {
	return
    }
    set first [$w index anchor]
    set last $Priv(listboxPrev)
    if {$last eq ""} {
	# Not actually doing any selection right now
	return
    }
    if {$first > $last} {
	set tmp $first
	set first $last
	set last $tmp







|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
proc ::tk::ListboxCancel w {
    variable ::tk::Priv
    if {[$w cget -selectmode] ne "extended"} {
	return
    }
    set first [$w index anchor]
    set last $Priv(listboxPrev)
    if {$last < 0} {
	# Not actually doing any selection right now
	return
    }
    if {$first > $last} {
	set tmp $first
	set first $last
	set last $tmp

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
# megawidget.tcl
#
#	Basic megawidget support classes. Experimental for any use other than
#	the ::tk::IconList megawdget, which is itself only designed for use in
#	the Unix file dialogs.
#
# Copyright © 2009-2010 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

package require Tk

::oo::class create ::tk::Megawidget {
    superclass ::oo::class
    method unknown {w args} {
	if {[string match .* $w]} {
	    [self] create $w {*}$args
	    return $w












|







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 © 2009-2010 Donal K. Fellows
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

package require tk

::oo::class create ::tk::Megawidget {
    superclass ::oo::class
    method unknown {w args} {
	if {[string match .* $w]} {
	    [self] create $w {*}$args
	    return $w
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
	    {-cursor cursor Cursor {}}
	    {-takefocus takeFocus TakeFocus ::ttk::takefocus}
	}
    }
    method CreateHull {} {
	ttk::frame $w
	set hull [ttk::entry $w.cHull -takefocus 0 -cursor $options(-cursor)]
	pack $hull -expand yes -fill both -ipadx 2 -ipady 2
	my TraceOption -cursor UpdateCursorOption
    }
}

return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|










280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
	    {-cursor cursor Cursor {}}
	    {-takefocus takeFocus TakeFocus ::ttk::takefocus}
	}
    }
    method CreateHull {} {
	ttk::frame $w
	set hull [ttk::entry $w.cHull -takefocus 0 -cursor $options(-cursor)]
	pack $hull -expand yes -fill both -ipadx 1.5p -ipady 1.5p
	my TraceOption -cursor UpdateCursorOption
    }
}

return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to library/menu.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# menu.tcl --
#
# This file defines the default bindings for Tk menus and menubuttons.
# It also implements keyboard traversal of menus and implements a few
# other utility procedures related to menus.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2007 Daniel A. Steffen <[email protected]>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

#-------------------------------------------------------------------------








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# menu.tcl --
#
# This file defines the default bindings for Tk menus and menubuttons.
# It also implements keyboard traversal of menus and implements a few
# other utility procedures related to menus.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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.
#

#-------------------------------------------------------------------------
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	    "can't post $menu: it isn't a descendant of $w"
    }
    set cur $Priv(postedMb)
    if {$cur ne ""} {
	MenuUnpost {}
    }
    if {$::tk_strictMotif} {
        set Priv(cursor) [$w cget -cursor]
        $w configure -cursor arrow
    }
    if {[tk windowingsystem] ne "aqua"} {
	set Priv(relief) [$w cget -relief]
	$w configure -relief raised
    } else {
	$w configure -state active
    }

    set Priv(postedMb) $w
    set Priv(focus) [focus]
    $menu activate none
    GenerateMenuSelect $menu
    update idletasks

    if {[catch {PostMenubuttonMenu $w $menu} msg opt]} {
	# Error posting menu (e.g. bogus -postcommand). Unpost it and
	# reflect the error.
	MenuUnpost {}
	return -options $opt $msg
    }

    set Priv(tearoff) $tearoff







|
|










|



|







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	    "can't post $menu: it isn't a descendant of $w"
    }
    set cur $Priv(postedMb)
    if {$cur ne ""} {
	MenuUnpost {}
    }
    if {$::tk_strictMotif} {
	set Priv(cursor) [$w cget -cursor]
	$w configure -cursor arrow
    }
    if {[tk windowingsystem] ne "aqua"} {
	set Priv(relief) [$w cget -relief]
	$w configure -relief raised
    } else {
	$w configure -state active
    }

    set Priv(postedMb) $w
    set Priv(focus) [focus]
    $menu activate {}
    GenerateMenuSelect $menu
    update idletasks

    if {[catch {PostMenubuttonMenu $w $menu $x $y} msg opt]} {
	# Error posting menu (e.g. bogus -postcommand). Unpost it and
	# reflect the error.
	MenuUnpost {}
	return -options $opt $msg
    }

    set Priv(tearoff) $tearoff
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

    catch {
	if {$mb ne ""} {
	    set menu [$mb cget -menu]
	    $menu unpost
	    set Priv(postedMb) {}
	    if {$::tk_strictMotif} {
	        $mb configure -cursor $Priv(cursor)
	    }
	    if {[tk windowingsystem] ne "aqua"} {
		$mb configure -relief $Priv(relief)
	    } else {
		$mb configure -state normal
	    }
	} elseif {$Priv(popup) ne ""} {
	    $Priv(popup) unpost
	    set Priv(popup) {}
	} elseif {[$menu cget -type] ne "menubar" && [$menu cget -type] ne "tearoff"} {
	    # We're in a cascaded sub-menu from a torn-off menu or popup.
	    # Unpost all the menus up to the toplevel one (but not
	    # including the top-level torn-off one) and deactivate the
	    # top-level torn off menu if there is one.

	    while {1} {
		set parent [winfo parent $menu]
		if {[winfo class $parent] ne "Menu" || ![winfo ismapped $parent]} {
		    break
		}
		$parent activate none
		$parent postcascade none
		GenerateMenuSelect $parent
		set type [$parent cget -type]
		if {$type eq "menubar" || $type eq "tearoff"} {
		    break
		}
		set menu $parent
	    }







|




















|
|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

    catch {
	if {$mb ne ""} {
	    set menu [$mb cget -menu]
	    $menu unpost
	    set Priv(postedMb) {}
	    if {$::tk_strictMotif} {
		$mb configure -cursor $Priv(cursor)
	    }
	    if {[tk windowingsystem] ne "aqua"} {
		$mb configure -relief $Priv(relief)
	    } else {
		$mb configure -state normal
	    }
	} elseif {$Priv(popup) ne ""} {
	    $Priv(popup) unpost
	    set Priv(popup) {}
	} elseif {[$menu cget -type] ne "menubar" && [$menu cget -type] ne "tearoff"} {
	    # We're in a cascaded sub-menu from a torn-off menu or popup.
	    # Unpost all the menus up to the toplevel one (but not
	    # including the top-level torn-off one) and deactivate the
	    # top-level torn off menu if there is one.

	    while {1} {
		set parent [winfo parent $menu]
		if {[winfo class $parent] ne "Menu" || ![winfo ismapped $parent]} {
		    break
		}
		$parent activate {}
		$parent postcascade {}
		GenerateMenuSelect $parent
		set type [$parent cget -type]
		if {$type eq "menubar" || $type eq "tearoff"} {
		    break
		}
		set menu $parent
	    }
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

499
500
501

502
503
504
505
506
507
508
509
510
511
512
# x -			The x position of the mouse.
# y -			The y position of the mouse.
# state -		Modifier state (tells whether buttons are down).

proc ::tk::MenuMotion {menu x y state} {
    variable ::tk::Priv
    if {$menu eq $Priv(window)} {
        set activeindex [$menu index active]
	if {[$menu cget -type] eq "menubar"} {
	    if {[info exists Priv(focus)] && $menu ne $Priv(focus)} {
		$menu activate @$x,$y
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu activate @$x,$y
	    GenerateMenuSelect $menu
	}
        set index [$menu index @$x,$y]
        if {[info exists Priv(menuActivated)] \
                && $index ne "none" \
                && $index ne $activeindex} {
            set mode [option get $menu clickToFocus ClickToFocus]
            if {[string is false $mode]} {
                set delay [expr {[$menu cget -type] eq "menubar" ? 0 : 50}]
                if {[$menu type $index] eq "cascade"} {
                    # Catch these postcascade commands since the menu could be
                    # destroyed before they run.
                    set Priv(menuActivatedTimer) \

                        [after $delay "catch {$menu postcascade active}"]
                } else {
                    set Priv(menuDeactivatedTimer) \

                        [after $delay "catch {$menu postcascade none}"]
                }
            }
        }
    }
}

# ::tk::MenuButtonDown --
# Handles button presses in menus.  There are a couple of tricky things
# here:
# 1. Change the posted cascade entry (if any) to match the mouse position.







|









|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
>
|
|
|
|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# x -			The x position of the mouse.
# y -			The y position of the mouse.
# state -		Modifier state (tells whether buttons are down).

proc ::tk::MenuMotion {menu x y state} {
    variable ::tk::Priv
    if {$menu eq $Priv(window)} {
	set activeindex [$menu index active]
	if {[$menu cget -type] eq "menubar"} {
	    if {[info exists Priv(focus)] && $menu ne $Priv(focus)} {
		$menu activate @$x,$y
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu activate @$x,$y
	    GenerateMenuSelect $menu
	}
	set index [$menu index @$x,$y]
	if {[info exists Priv(menuActivated)] \
		&& $index >= 0 \
		&& $index ne $activeindex} {
	    set mode [option get $menu clickToFocus ClickToFocus]
	    if {[string is false $mode]} {
		set delay [expr {[$menu cget -type] eq "menubar" ? 0 : 50}]
		if {[$menu type $index] eq "cascade"} {
		    # Catch these postcascade commands since the menu could be
		    # destroyed before they run.
		    set Priv(menuActivatedTimer) \
			[after $delay [list catch [list \
			    $menu postcascade active]]]
		} else {
		    set Priv(menuDeactivatedTimer) \
			[after $delay [list catch [list
			    $menu postcascade {}]]]
		}
	    }
	}
    }
}

# ::tk::MenuButtonDown --
# Handles button presses in menus.  There are a couple of tricky things
# here:
# 1. Change the posted cascade entry (if any) to match the mouse position.
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
# Arguments:
# menu -		The menu window.

proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv

    if {![winfo viewable $menu]} {
        return
    }
    if {[$menu index active] eq "none"} {
        if {[$menu cget -type] ne "menubar" } {
            set Priv(window) {}
        }
        return
    }
    $menu postcascade active
    if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
	grab -global $Priv(postedMb)
    } else {
	while {[$menu cget -type] eq "normal" \
		&& [winfo class [winfo parent $menu]] eq "Menu" \
		&& [winfo ismapped [winfo parent $menu]]} {
	    set menu [winfo parent $menu]
	}

	if {$Priv(menuBar) eq {}} {
	    set Priv(menuBar) $menu
	    if {$::tk_strictMotif} {
		set Priv(cursor) [$menu cget -cursor]
		$menu configure -cursor arrow
	    }
	    if {[$menu type active] eq "cascade"} {
		set Priv(menuActivated) 1
	    }
        }

	# Don't update grab information if the grab window isn't changing.
	# Otherwise, we'll get an error when we unpost the menus and
	# restore the grab, since the old grab window will not be viewable
	# anymore.

	if {$menu ne [grab current $menu]} {







|

|
|
|
|
|




















|







523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
# Arguments:
# menu -		The menu window.

proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv

    if {![winfo viewable $menu]} {
	return
    }
    if {[$menu index active] < 0} {
	if {[$menu cget -type] ne "menubar" } {
	    set Priv(window) {}
	}
	return
    }
    $menu postcascade active
    if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
	grab -global $Priv(postedMb)
    } else {
	while {[$menu cget -type] eq "normal" \
		&& [winfo class [winfo parent $menu]] eq "Menu" \
		&& [winfo ismapped [winfo parent $menu]]} {
	    set menu [winfo parent $menu]
	}

	if {$Priv(menuBar) eq {}} {
	    set Priv(menuBar) $menu
	    if {$::tk_strictMotif} {
		set Priv(cursor) [$menu cget -cursor]
		$menu configure -cursor arrow
	    }
	    if {[$menu type active] eq "cascade"} {
		set Priv(menuActivated) 1
	    }
	}

	# Don't update grab information if the grab window isn't changing.
	# Otherwise, we'll get an error when we unpost the menus and
	# restore the grab, since the old grab window will not be viewable
	# anymore.

	if {$menu ne [grab current $menu]} {
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
# menu -		The menu window.
# rootx, rooty -	Root coordinates of mouse.
# state -		Modifier state.

proc ::tk::MenuLeave {menu rootx rooty state} {
    variable ::tk::Priv
    set Priv(window) {}
    if {[$menu index active] eq "none"} {
	return
    }
    if {[$menu type active] eq "cascade" \
	    && [winfo containing $rootx $rooty] eq \
		[$menu entrycget active -menu]} {
	return
    }
    $menu activate none
    GenerateMenuSelect $menu
}

# ::tk::MenuInvoke --
# This procedure is invoked when button 1 is released over a menu.
# It invokes the appropriate menu action and unposts the menu if
# it came from a menubutton.







|







|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
# menu -		The menu window.
# rootx, rooty -	Root coordinates of mouse.
# state -		Modifier state.

proc ::tk::MenuLeave {menu rootx rooty state} {
    variable ::tk::Priv
    set Priv(window) {}
    if {[$menu index active] < 0} {
	return
    }
    if {[$menu type active] eq "cascade" \
	    && [winfo containing $rootx $rooty] eq \
		[$menu entrycget active -menu]} {
	return
    }
    $menu activate {}
    GenerateMenuSelect $menu
}

# ::tk::MenuInvoke --
# This procedure is invoked when button 1 is released over a menu.
# It invokes the appropriate menu action and unposts the menu if
# it came from a menubutton.
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
    variable ::tk::Priv

    if {$buttonRelease && $Priv(window) eq ""} {
	# Mouse was pressed over a menu without a menu button, then
	# dragged off the menu (possibly with a cascade posted) and
	# released.  Unpost everything and quit.

	$w postcascade none
	$w activate none
	event generate $w <<MenuSelect>>
	MenuUnpost $w
	return
    }
    if {[$w type active] eq "cascade"} {
	$w postcascade active
	set menu [$w entrycget active -menu]
	MenuFirstEntry $menu
    } elseif {[$w type active] eq "tearoff"} {
	::tk::TearOffMenu $w
	MenuUnpost $w
    } elseif {[$w cget -type] eq "menubar"} {
	$w postcascade none
	set active [$w index active]
	set isCascade [string equal [$w type $active] "cascade"]

	# Only de-activate the active item if it's a cascade; this prevents
	# the annoying "activation flicker" you otherwise get with
	# checkbuttons/commands/etc. on menubars

	if { $isCascade } {
	    $w activate none
	    event generate $w <<MenuSelect>>
	}

	MenuUnpost $w

	# If the active item is not a cascade, invoke it.  This enables
	# the use of checkbuttons/commands/etc. on menubars (which is legal,
	# but not recommended)

	if { !$isCascade } {
	    uplevel #0 [list $w invoke $active]
	}
    } else {
	set active [$w index active]
	if {$Priv(popup) eq "" || $active ne "none"} {
	    MenuUnpost $w
	}
	uplevel #0 [list $w invoke active]
    }
}

# ::tk::MenuEscape --







|
|












|
|
|






|










|


<
|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
    variable ::tk::Priv

    if {$buttonRelease && $Priv(window) eq ""} {
	# Mouse was pressed over a menu without a menu button, then
	# dragged off the menu (possibly with a cascade posted) and
	# released.  Unpost everything and quit.

	$w postcascade {}
	$w activate {}
	event generate $w <<MenuSelect>>
	MenuUnpost $w
	return
    }
    if {[$w type active] eq "cascade"} {
	$w postcascade active
	set menu [$w entrycget active -menu]
	MenuFirstEntry $menu
    } elseif {[$w type active] eq "tearoff"} {
	::tk::TearOffMenu $w
	MenuUnpost $w
    } elseif {[$w cget -type] eq "menubar"} {
	$w postcascade {}
	set activeindex [$w index active]
	set isCascade [string equal [$w type $activeindex] "cascade"]

	# Only de-activate the active item if it's a cascade; this prevents
	# the annoying "activation flicker" you otherwise get with
	# checkbuttons/commands/etc. on menubars

	if { $isCascade } {
	    $w activate {}
	    event generate $w <<MenuSelect>>
	}

	MenuUnpost $w

	# If the active item is not a cascade, invoke it.  This enables
	# the use of checkbuttons/commands/etc. on menubars (which is legal,
	# but not recommended)

	if { !$isCascade } {
	    uplevel #0 [list $w invoke $activeindex]
	}
    } else {

	if {$Priv(popup) eq "" || [$w index active] >= 0} {
	    MenuUnpost $w
	}
	uplevel #0 [list $w invoke active]
    }
}

# ::tk::MenuEscape --
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
		set parent [winfo parent $parent]
	    }
	}
    } else {
	set count -1
	set m2 [winfo parent $menu]
	if {[winfo class $m2] eq "Menu"} {
	    $menu activate none
	    GenerateMenuSelect $menu
	    tk_menuSetFocus $m2

	    $m2 postcascade none

	    if {[$m2 cget -type] ne "menubar"} {
		return
	    }
	}
    }








|



|







754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
		set parent [winfo parent $parent]
	    }
	}
    } else {
	set count -1
	set m2 [winfo parent $menu]
	if {[winfo class $m2] eq "Menu"} {
	    $menu activate {}
	    GenerateMenuSelect $menu
	    tk_menuSetFocus $m2

	    $m2 postcascade {}

	    if {[$m2 cget -type] ne "menubar"} {
		return
	    }
	}
    }

793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
	while {$i >= $length} {
	    incr i -$length
	}
	set mb [lindex $buttons $i]
	if {[winfo class $mb] eq "Menubutton" \
		&& [$mb cget -state] ne "disabled" \
		&& [$mb cget -menu] ne "" \
		&& [[$mb cget -menu] index last] ne "none"} {
	    break
	}
	if {$mb eq $w} {
	    return
	}
	incr i $count
    }







|







794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
	while {$i >= $length} {
	    incr i -$length
	}
	set mb [lindex $buttons $i]
	if {[winfo class $mb] eq "Menubutton" \
		&& [$mb cget -state] ne "disabled" \
		&& [$mb cget -menu] ne "" \
		&& [[$mb cget -menu] index last] >= 0} {
	    break
	}
	if {$mb eq $w} {
	    return
	}
	incr i $count
    }
815
816
817
818
819
820
821
822

823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
#
# Arguments:
# menu -			Menu window that received the keystroke.
# count -			1 means go to the next lower entry,
#				-1 means go to the next higher entry.

proc ::tk::MenuNextEntry {menu count} {
    if {[$menu index last] eq "none"} {

	return
    }
    set length [expr {[$menu index last]+1}]
    set quitAfter $length
    set active [$menu index active]
    if {$active eq "none"} {
	set i 0
    } else {
	set i [expr {$active + $count}]
    }
    while {1} {
	if {$quitAfter <= 0} {
	    # We've tried every entry in the menu.  Either there are
	    # none, or they're all disabled.  Just give up.

	    return







|
>


|

|
|


|







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
#
# Arguments:
# menu -			Menu window that received the keystroke.
# count -			1 means go to the next lower entry,
#				-1 means go to the next higher entry.

proc ::tk::MenuNextEntry {menu count} {
    set last [$menu index last]
    if {$last < 0} {
	return
    }
    set length [expr {$last+1}]
    set quitAfter $length
    set activeindex [$menu index active]
    if {$activeindex < 0} {
	set i 0
    } else {
	set i [expr {$activeindex + $count}]
    }
    while {1} {
	if {$quitAfter <= 0} {
	    # We've tried every entry in the menu.  Either there are
	    # none, or they're all disabled.  Just give up.

	    return
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
	if {[catch {$menu entrycget $i -state} state] == 0} {
	    if {$state ne "disabled" && \
		    ($i!=0 || [$menu cget -type] ne "tearoff" \
		    || [$menu type 0] ne "tearoff")} {
		break
	    }
	}
	if {$i == $active} {
	    return
	}
	incr i $count
	incr quitAfter -1
    }
    $menu activate $i
    GenerateMenuSelect $menu







|







848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
	if {[catch {$menu entrycget $i -state} state] == 0} {
	    if {$state ne "disabled" && \
		    ($i!=0 || [$menu cget -type] ne "tearoff" \
		    || [$menu type 0] ne "tearoff")} {
		break
	    }
	}
	if {$i == $activeindex} {
	    return
	}
	incr i $count
	incr quitAfter -1
    }
    $menu activate $i
    GenerateMenuSelect $menu
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929

proc ::tk::MenuFind {w char} {
    set char [string tolower $char]
    set windowlist [winfo child $w]

    foreach child $windowlist {
	# Don't descend into other toplevels.
        if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	    continue
	}
	if {[winfo class $child] eq "Menu" && \
		[$child cget -type] eq "menubar"} {
	    if {$char eq ""} {
		return $child
	    }
	    set last [$child index last]
	    for {set i [$child cget -tearoff]} {$i <= $last} {incr i} {
		if {[$child type $i] eq "separator"} {
		    continue
		}
		set char2 [string index [$child entrycget $i -label] \
			[$child entrycget $i -underline]]

		if {$char eq [string tolower $char2] || $char eq ""} {
		    if {[$child entrycget $i -state] ne "disabled"} {
			return $child
		    }
		}
	    }
	}
    }

    foreach child $windowlist {
	# Don't descend into other toplevels.
        if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	    continue
	}
	switch -- [winfo class $child] {
	    Menubutton {
		set char2 [string index [$child cget -text] \
			[$child cget -underline]]
		if {$char eq [string tolower $char2] || $char eq ""} {







|









|


<
|
>
|
<









|







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

proc ::tk::MenuFind {w char} {
    set char [string tolower $char]
    set windowlist [winfo child $w]

    foreach child $windowlist {
	# Don't descend into other toplevels.
	if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	    continue
	}
	if {[winfo class $child] eq "Menu" && \
		[$child cget -type] eq "menubar"} {
	    if {$char eq ""} {
		return $child
	    }
	    set last [$child index last]
	    for {set i [$child cget -tearoff]} {$i <= $last} {incr i} {
		if {([$child type $i] eq "separator") || ([$child entrycget $i -state] eq "disabled")} {
		    continue
		}

		set underline [$child entrycget $i -underline]
		if {$underline >= 0} {
		    if {$char eq [string tolower [string index [$child entrycget $i -label] $underline]]} {

			return $child
		    }
		}
	    }
	}
    }

    foreach child $windowlist {
	# Don't descend into other toplevels.
	if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	    continue
	}
	switch -- [winfo class $child] {
	    Menubutton {
		set char2 [string index [$child cget -text] \
			[$child cget -underline]]
		if {$char eq [string tolower $char2] || $char eq ""} {
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038

proc ::tk::TraverseWithinMenu {w char} {
    if {$char eq ""} {
	return
    }
    set char [string tolower $char]
    set last [$w index last]
    if {$last eq "none"} {
	return
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {[catch {set char2 [string index \
		[$w entrycget $i -label] [$w entrycget $i -underline]]}]} {
	    continue
	}
	if {$char eq [string tolower $char2]} {
	    if {[$w type $i] eq "cascade"} {







<
<
<







1023
1024
1025
1026
1027
1028
1029



1030
1031
1032
1033
1034
1035
1036

proc ::tk::TraverseWithinMenu {w char} {
    if {$char eq ""} {
	return
    }
    set char [string tolower $char]
    set last [$w index last]



    for {set i 0} {$i <= $last} {incr i} {
	if {[catch {set char2 [string index \
		[$w entrycget $i -label] [$w entrycget $i -underline]]}]} {
	    continue
	}
	if {$char eq [string tolower $char2]} {
	    if {[$w type $i] eq "cascade"} {
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
# menu -		Name of the menu window (possibly empty).

proc ::tk::MenuFirstEntry menu {
    if {$menu eq ""} {
	return
    }
    tk_menuSetFocus $menu
    if {[$menu index active] ne "none"} {
	return
    }
    set last [$menu index last]
    if {$last eq "none"} {
	return
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {([catch {set state [$menu entrycget $i -state]}] == 0) \
		&& $state ne "disabled" && [$menu type $i] ne "tearoff"} {
	    $menu activate $i
	    GenerateMenuSelect $menu
	    # Only post the cascade if the current menu is a menubar;
	    # otherwise, if the first entry of the cascade is a cascade,







|



<
<
<







1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072



1073
1074
1075
1076
1077
1078
1079
# menu -		Name of the menu window (possibly empty).

proc ::tk::MenuFirstEntry menu {
    if {$menu eq ""} {
	return
    }
    tk_menuSetFocus $menu
    if {[$menu index active] >= 0} {
	return
    }
    set last [$menu index last]



    for {set i 0} {$i <= $last} {incr i} {
	if {([catch {set state [$menu entrycget $i -state]}] == 0) \
		&& $state ne "disabled" && [$menu type $i] ne "tearoff"} {
	    $menu activate $i
	    GenerateMenuSelect $menu
	    # Only post the cascade if the current menu is a menubar;
	    # otherwise, if the first entry of the cascade is a cascade,
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
proc ::tk::MenuFindName {menu s} {
    set i ""
    if {![regexp {^active$|^last$|^none$|^[0-9]|^@} $s]} {
	catch {set i [$menu index $s]}
	return $i
    }
    set last [$menu index last]
    if {$last eq "none"} {
	return
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]} {
	    if {$label eq $s} {
		return $i
	    }
	}
    }







<
<
<







1105
1106
1107
1108
1109
1110
1111



1112
1113
1114
1115
1116
1117
1118
proc ::tk::MenuFindName {menu s} {
    set i ""
    if {![regexp {^active$|^last$|^none$|^[0-9]|^@} $s]} {
	catch {set i [$menu index $s]}
	return $i
    }
    set last [$menu index last]



    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]} {
	    if {$label eq $s} {
		return $i
	    }
	}
    }
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
# menubutton, meaning that the indicator is on and the direction is
# neither above nor below, then the menu is posted so that the current
# entry is vertically aligned with the menubutton.  On the Mac this
# will expose a small amount of the blue indicator on the right hand
# side.  On other platforms the entry is centered over the button.

if {[tk windowingsystem] eq "aqua"} {
    proc ::tk::PostMenubuttonMenu {button menu} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}







|







1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
# menubutton, meaning that the indicator is on and the direction is
# neither above nor below, then the menu is posted so that the current
# entry is vertically aligned with the menubutton.  On the Mac this
# will expose a small amount of the blue indicator on the right hand
# side.  On other platforms the entry is centered over the button.

if {[tk windowingsystem] eq "aqua"} {
    proc ::tk::PostMenubuttonMenu {button menu cx cy} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214





1215
1216

1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
	    }
	    left {
		incr x [expr {-[winfo reqwidth $menu]}]
	    }
	    right {
		incr x [winfo width $button]
	    }
	    default {
		incr x [expr {[winfo width $button] - [winfo reqwidth $menu] - 5}]
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
} else {
    proc ::tk::PostMenubuttonMenu {button menu} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}
	set x [winfo rootx $button]
	set y [winfo rooty $button]
	switch [$button cget -direction] {
	    above {
		incr y [expr {-[winfo reqheight $menu]}]
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $button]} {
		    set y [expr {[winfo vrooty $button] + [winfo rooty $button]\
                           + [winfo reqheight $button]}]
		}
		set entry {}
	    }
	    below {
		incr y [winfo height $button]
		# if we go offscreen to the bottom, show as 'above'
		set mh [winfo reqheight $menu]
		if {($y + $mh) > ([winfo vrooty $button] + [winfo vrootheight $button])} {
		    set y [expr {[winfo vrooty $button] + [winfo vrootheight $button] \
			   + [winfo rooty $button] - $mh}]
		}
		set entry {}
	    }
	    left {
		# It is not clear why this is needed.
		if {[tk windowingsystem] eq "win32"} {
		    incr x [expr {-4 - [winfo reqwidth $button] / 2}]
		}
		incr x [expr {- [winfo reqwidth $menu]}]
	    }
	    right {
		incr x [expr {[winfo width $button]}]
	    }
	    default {
		if {[$button cget -indicatoron]} {





		    incr x [expr {([winfo width $button] - \
				   [winfo reqwidth $menu])/ 2}]

		} else {
		    incr y [winfo height $button]
		}
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
}

# ::tk::PostOverPoint --







|






|















|














<
<
<
<





|
|
>
>
>
>
>
|
|
>
|
|
|







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
	    }
	    left {
		incr x [expr {-[winfo reqwidth $menu]}]
	    }
	    right {
		incr x [winfo width $button]
	    }
	    default {  # flush
		incr x [expr {[winfo width $button] - [winfo reqwidth $menu] - 5}]
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
} else {
    proc ::tk::PostMenubuttonMenu {button menu cx cy} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}
	set x [winfo rootx $button]
	set y [winfo rooty $button]
	switch [$button cget -direction] {
	    above {
		incr y [expr {-[winfo reqheight $menu]}]
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $button]} {
		    set y [expr {[winfo vrooty $button] + [winfo rooty $button]\
			   + [winfo reqheight $button]}]
		}
		set entry {}
	    }
	    below {
		incr y [winfo height $button]
		# if we go offscreen to the bottom, show as 'above'
		set mh [winfo reqheight $menu]
		if {($y + $mh) > ([winfo vrooty $button] + [winfo vrootheight $button])} {
		    set y [expr {[winfo vrooty $button] + [winfo vrootheight $button] \
			   + [winfo rooty $button] - $mh}]
		}
		set entry {}
	    }
	    left {




		incr x [expr {- [winfo reqwidth $menu]}]
	    }
	    right {
		incr x [expr {[winfo width $button]}]
	    }
	    default {  # flush
                if {[$button cget -indicatoron]} {
                    if {$cx ne ""} {
                        set x [expr {$cx - [winfo reqwidth $menu] / 2}]
                        set l [font metrics [$menu cget -font] -linespace]
                        set y [expr {$cy - $l/2 - 2}]
                    } else {
                        incr x [expr {([winfo width $button] - \
				[winfo reqwidth $menu])/ 2}]
                    }
                } else {
                    incr y [winfo height $button]
                }
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
}

# ::tk::PostOverPoint --
1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252
#			If omitted or specified as {}, then the menu's
#			upper-left corner goes at (x,y).

if {[tk windowingsystem] ne "win32"} {
    proc ::tk::PostOverPoint {menu x y {entry {}}}  {
	if {$entry ne ""} {
	    $menu post $x $y $entry

	    if {[$menu entrycget $entry -state] ne "disabled"} {
		$menu activate $entry
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu post $x $y
	}
	return







>
|







1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
#			If omitted or specified as {}, then the menu's
#			upper-left corner goes at (x,y).

if {[tk windowingsystem] ne "win32"} {
    proc ::tk::PostOverPoint {menu x y {entry {}}}  {
	if {$entry ne ""} {
	    $menu post $x $y $entry
	    if {[$menu type $entry] ni {separator tearoff} &&
		[$menu entrycget $entry -state] ne "disabled"} {
		$menu activate $entry
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu post $x $y
	}
	return
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356
1357
    }
    focus $menu
}

proc ::tk::GenerateMenuSelect {menu} {
    variable ::tk::Priv

    if {$Priv(activeMenu) eq $menu \
	    && $Priv(activeItem) eq [$menu index active]} {
	return
    }

    set Priv(activeMenu) $menu
    set Priv(activeItem) [$menu index active]
    event generate $menu <<MenuSelect>>

}

# ::tk_popup --
# This procedure pops up a menu and sets things up for traversing
# the menu and its submenus.
#
# Arguments:







|
|
<
<
<
|
|
|
>







1331
1332
1333
1334
1335
1336
1337
1338
1339



1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
    }
    focus $menu
}

proc ::tk::GenerateMenuSelect {menu} {
    variable ::tk::Priv

    if {$Priv(activeMenu) ne $menu \
	    || $Priv(activeItem) ne [$menu index active]} {



	set Priv(activeMenu) $menu
	set Priv(activeItem) [$menu index active]
	event generate $menu <<MenuSelect>>
    }
}

# ::tk_popup --
# This procedure pops up a menu and sets things up for traversing
# the menu and its submenus.
#
# Arguments:
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
proc ::tk_popup {menu x y {entry {}}} {
    variable ::tk::Priv
    if {$Priv(popup) ne "" || $Priv(postedMb) ne ""} {
	tk::MenuUnpost {}
    }
    tk::PostOverPoint $menu $x $y $entry
    if {[tk windowingsystem] eq "x11" && [winfo viewable $menu]} {
        tk::SaveGrabInfo $menu
	grab -global $menu
	set Priv(popup) $menu
	set Priv(window) $menu
	set Priv(menuActivated) 1
	tk_menuSetFocus $menu
    }
}







|







1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
proc ::tk_popup {menu x y {entry {}}} {
    variable ::tk::Priv
    if {$Priv(popup) ne "" || $Priv(postedMb) ne ""} {
	tk::MenuUnpost {}
    }
    tk::PostOverPoint $menu $x $y $entry
    if {[tk windowingsystem] eq "x11" && [winfo viewable $menu]} {
	tk::SaveGrabInfo $menu
	grab -global $menu
	set Priv(popup) $menu
	set Priv(window) $menu
	set Priv(menuActivated) 1
	tk_menuSetFocus $menu
    }
}

Changes to library/msgbox.tcl.

119
120
121
122
123
124
125



126
127
128
129
130
131
132
#	by tk_messageBox if the platform does not have native
#	messagebox support, or if the particular type of messagebox is
#	not supported natively.
#
#	Color icons are used on Unix displays that have a color
#	depth of 4 or more and $tk_strictMotif is not on.
#



#	This procedure is a private procedure shouldn't be called
#	directly. Call tk_messageBox instead.
#
#	See the user documentation for details on what tk_messageBox does.
#
proc ::tk::MessageBox {args} {
    global tk_strictMotif







>
>
>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#	by tk_messageBox if the platform does not have native
#	messagebox support, or if the particular type of messagebox is
#	not supported natively.
#
#	Color icons are used on Unix displays that have a color
#	depth of 4 or more and $tk_strictMotif is not on.
#
#	Uses ::tk::Priv.${disp}(button) instead of ::tk::Priv(button) to
#	avoid adverse effects of [::tk::ScreenChanged]. Bug [e2cec2fa41].
#
#	This procedure is a private procedure shouldn't be called
#	directly. Call tk_messageBox instead.
#
#	See the user documentation for details on what tk_messageBox does.
#
proc ::tk::MessageBox {args} {
    global tk_strictMotif
166
167
168
169
170
171
172
























173
174
175
176
177
178
179
	}
    }

    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }

























    switch -- $data(-type) {
	abortretryignore {
	    set names [list abort retry ignore]
	    set labels [list &Abort &Retry &Ignore]
	    set cancel abort
	}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	}
    }

    if {![winfo exists $data(-parent)]} {
	return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \
	    "bad window path name \"$data(-parent)\""
    }

    # Select the vwait variable carefully.
    set oldScreen $Priv(screen)
    set screen [winfo screen $data(-parent)]

    # Extract the display name (cf. ScreenChanged, including [Bug 2912473] fix).
    set disp [string range $screen 0 [string last . $screen]-1]

    # Ensure that namespace separators never occur in the display name (as
    # they cause problems in variable names). Double-colons exist in some VNC
    # display names. [Bug 2912473]
    set disp [string map {:: _doublecolon_} $disp]

    if {![info exists ::tk::Priv.${disp}]} {
	# Use ScreenChanged to create ::tk::Priv.${disp}, then change back to old
	# screen to avoid interfering with Tk expectations for bindings.
	ScreenChanged $screen
	ScreenChanged $oldScreen
    }

    variable ::tk::Priv.${disp}
    # Now in place of ::tk::Priv(button), use ::tk::Priv.${disp}(button) which
    # is the intended target variable of upvar and will not be redefined when
    # ::tk::ScreenChanged is called.

    switch -- $data(-type) {
	abortretryignore {
	    set names [list abort retry ignore]
	    set labels [list &Abort &Retry &Ignore]
	    set cancel abort
	}
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
	if {![llength $opts]} {
	    # Capitalize the first letter of $name
	    set capName [string toupper $name 0]
	    set opts [list -text $capName]
	}

	eval [list tk::AmpWidget ttk::button $w.$name] $opts \
		[list -command [list set tk::Priv(button) $name]]

	if {$name eq $data(-default)} {
	    $w.$name configure -default active
	} else {
	    $w.$name configure -default normal
	}
	grid $w.$name -in $w.bot -row 0 -column $i -padx 3m -pady 2m -sticky ew







|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
	if {![llength $opts]} {
	    # Capitalize the first letter of $name
	    set capName [string toupper $name 0]
	    set opts [list -text $capName]
	}

	eval [list tk::AmpWidget ttk::button $w.$name] $opts \
		[list -command [list set tk::Priv.${disp}(button) $name]]

	if {$name eq $data(-default)} {
	    $w.$name configure -default active
	} else {
	    $w.$name configure -default normal
	}
	grid $w.$name -in $w.bot -row 0 -column $i -padx 3m -pady 2m -sticky ew
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
	}
    }

    # Invoke the designated cancelling operation
    bind $w <Escape> [list $w.$cancel invoke]

    # At <Destroy> the buttons have vanished, so must do this directly.
    bind $w.msg <Destroy> [list set tk::Priv(button) $cancel]

    # 7. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display (Motif style) and de-iconify it.

    ::tk::PlaceWindow $w widget $data(-parent)








|







416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
	}
    }

    # Invoke the designated cancelling operation
    bind $w <Escape> [list $w.$cancel invoke]

    # At <Destroy> the buttons have vanished, so must do this directly.
    bind $w.msg <Destroy> [list set tk::Priv.${disp}(button) $cancel]

    # 7. Withdraw the window, then update all the geometry information
    # so we know how big it wants to be, then center the window in the
    # display (Motif style) and de-iconify it.

    ::tk::PlaceWindow $w widget $data(-parent)

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

    # 9. Wait for the user to respond, then restore the focus and
    # return the index of the selected button.  Restore the focus
    # before deleting the window, since otherwise the window manager
    # may take the focus away so we can't redirect it.  Finally,
    # restore any grab that was in effect.

    vwait ::tk::Priv(button)
    # Copy the result now so any <Destroy> that happens won't cause
    # trouble
    set result $Priv(button)

    ::tk::RestoreFocusGrab $w $focus

    return $result
}







|


|





439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454

    # 9. Wait for the user to respond, then restore the focus and
    # return the index of the selected button.  Restore the focus
    # before deleting the window, since otherwise the window manager
    # may take the focus away so we can't redirect it.  Finally,
    # restore any grab that was in effect.

    vwait ::tk::Priv.${disp}(button)
    # Copy the result now so any <Destroy> that happens won't cause
    # trouble
    set result [set Priv.${disp}(button)]

    ::tk::RestoreFocusGrab $w $focus

    return $result
}

Changes to library/msgs/cs.msg.

70
71
72
73
74
75
76


















77
    ::msgcat::mcset cs "extensions" "pípony"
    ::msgcat::mcset cs "green" "zeleá"
    ::msgcat::mcset cs "ignore" "ignorovat"
    ::msgcat::mcset cs "ok"
    ::msgcat::mcset cs "red" "červeá"
    ::msgcat::mcset cs "retry" "znovu"
    ::msgcat::mcset cs "yes" "ano"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    ::msgcat::mcset cs "extensions" "pípony"
    ::msgcat::mcset cs "green" "zeleá"
    ::msgcat::mcset cs "ignore" "ignorovat"
    ::msgcat::mcset cs "ok"
    ::msgcat::mcset cs "red" "červeá"
    ::msgcat::mcset cs "retry" "znovu"
    ::msgcat::mcset cs "yes" "ano"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  cs "Print" "Tisknout"
    ::msgcat::mcset  cs "Printer" "Tiskárna"
    ::msgcat::mcset  cs "Letter " "Dopis "
    ::msgcat::mcset  cs "Legal " "Legální "
    ::msgcat::mcset  cs "A4" "A4"
    ::msgcat::mcset  cs "Grayscale" "Stupně Šedi"
    ::msgcat::mcset  cs "RGB" "RGB"
    ::msgcat::mcset  cs "Options" "Možnosti"
    ::msgcat::mcset  cs "Copies" "Kopie"
    ::msgcat::mcset  cs "Paper" "Papír"
    ::msgcat::mcset  cs "Scale" "Škála"
    ::msgcat::mcset  cs "Orientation" "Orientace"
    ::msgcat::mcset  cs "Portrait" "Portrét"
    ::msgcat::mcset  cs "Landscape" "Krajina"
    ::msgcat::mcset  cs "Output" "Výstup"
}

Changes to library/msgs/da.msg.

71
72
73
74
75
76
77


















78
    ::msgcat::mcset da "extensions"
    ::msgcat::mcset da "green" "grøn"
    ::msgcat::mcset da "ignore" "ignorer"
    ::msgcat::mcset da "ok"
    ::msgcat::mcset da "red" "rød"
    ::msgcat::mcset da "retry" "gentag"
    ::msgcat::mcset da "yes" "ja"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    ::msgcat::mcset da "extensions"
    ::msgcat::mcset da "green" "grøn"
    ::msgcat::mcset da "ignore" "ignorer"
    ::msgcat::mcset da "ok"
    ::msgcat::mcset da "red" "rød"
    ::msgcat::mcset da "retry" "gentag"
    ::msgcat::mcset da "yes" "ja"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  da "Print" "Trykke"
    ::msgcat::mcset  da "Printer" "Printer"
    ::msgcat::mcset  da "Letter " "Brev"
    ::msgcat::mcset  da "Legal " "Juridisk"
    ::msgcat::mcset  da "A4" "A4"
    ::msgcat::mcset  da "Grayscale" "Gråtoneskala"
    ::msgcat::mcset  da "RGB" "Rgb"
    ::msgcat::mcset  da "Options" "Indstillinger"
    ::msgcat::mcset  da "Copies" "Kopier"
    ::msgcat::mcset  da "Paper" "Papir"
    ::msgcat::mcset  da "Scale" "Skalere"
    ::msgcat::mcset  da "Orientation" "Orientering"
    ::msgcat::mcset  da "Portrait" "Portræt"
    ::msgcat::mcset  da "Landscape" "Landskab"
    ::msgcat::mcset  da "Output" "Udskriv Publikation"
}

Changes to library/msgs/de.msg.

84
85
86
87
88
89
90


















91
    ::msgcat::mcset de "extensions" "Erweiterungen"
    ::msgcat::mcset de "green" "grün"
    ::msgcat::mcset de "ignore" "ignorieren"
    ::msgcat::mcset de "ok"
    ::msgcat::mcset de "red" "rot"
    ::msgcat::mcset de "retry" "wiederholen"
    ::msgcat::mcset de "yes" "ja"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    ::msgcat::mcset de "extensions" "Erweiterungen"
    ::msgcat::mcset de "green" "grün"
    ::msgcat::mcset de "ignore" "ignorieren"
    ::msgcat::mcset de "ok"
    ::msgcat::mcset de "red" "rot"
    ::msgcat::mcset de "retry" "wiederholen"
    ::msgcat::mcset de "yes" "ja"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  de "Print" "Drucken"
    ::msgcat::mcset  de "Printer" "Drucker"
    ::msgcat::mcset  de "Letter " "Letter"
    ::msgcat::mcset  de "Legal " "Legal"
    ::msgcat::mcset  de "A4" "A4"
    ::msgcat::mcset  de "Grayscale" "Graustufen"
    ::msgcat::mcset  de "RGB" "RGB"
    ::msgcat::mcset  de "Options" "Optionen"
    ::msgcat::mcset  de "Copies" "Kopien"
    ::msgcat::mcset  de "Paper" "Papier"
    ::msgcat::mcset  de "Scale" "Skalierung"
    ::msgcat::mcset  de "Orientation" "Ausrichtung"
    ::msgcat::mcset  de "Portrait" "Hochformat"
    ::msgcat::mcset  de "Landscape" "Querformat"
    ::msgcat::mcset  de "Output" "Ausgabe"
}

Changes to library/msgs/el.msg.

79
80
81
82
83
84
85


















86
    ::msgcat::mcset el "extensions"         "επεκτάσεις"
    ::msgcat::mcset el "green"              "πράσινο"
    ::msgcat::mcset el "ignore"             "αγνόηση"
    ::msgcat::mcset el "ok"                 "εντάξει"
    ::msgcat::mcset el "red"                "κόκκινο"
    ::msgcat::mcset el "retry"              "προσπάθησε ξανά"
    ::msgcat::mcset el "yes"                "ναι"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    ::msgcat::mcset el "extensions"         "επεκτάσεις"
    ::msgcat::mcset el "green"              "πράσινο"
    ::msgcat::mcset el "ignore"             "αγνόηση"
    ::msgcat::mcset el "ok"                 "εντάξει"
    ::msgcat::mcset el "red"                "κόκκινο"
    ::msgcat::mcset el "retry"              "προσπάθησε ξανά"
    ::msgcat::mcset el "yes"                "ναι"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  el "Print" "Τυπώνω"
    ::msgcat::mcset  el "Printer" "Εκτυπωτής"
    ::msgcat::mcset  el "Letter " "Γράμμα"
    ::msgcat::mcset  el "Legal " "Νομικός"
    ::msgcat::mcset  el "A4" "Α4"
    ::msgcat::mcset  el "Grayscale" "Κλίμακα Του Γκρι"
    ::msgcat::mcset  el "RGB" "Rgb"
    ::msgcat::mcset  el "Options" "Επιλογές"
    ::msgcat::mcset  el "Copies" "Αντίγραφα"
    ::msgcat::mcset  el "Paper" "Χαρτί"
    ::msgcat::mcset  el "Scale" "Κλίμακα"
    ::msgcat::mcset  el "Orientation" "Προσανατολισμός"
    ::msgcat::mcset  el "Portrait" "Προσωπογραφία"
    ::msgcat::mcset  el "Landscape" "Τοπίο"
    ::msgcat::mcset  el "Output" "Έξοδος"
}

Changes to library/msgs/en.msg.

85
86
87
88
89
90
91



















    ::msgcat::mcset en "green"
    ::msgcat::mcset en "ignore"
    ::msgcat::mcset en "ok"
    ::msgcat::mcset en "red"
    ::msgcat::mcset en "retry"
    ::msgcat::mcset en "yes"
}


























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    ::msgcat::mcset en "green"
    ::msgcat::mcset en "ignore"
    ::msgcat::mcset en "ok"
    ::msgcat::mcset en "red"
    ::msgcat::mcset en "retry"
    ::msgcat::mcset en "yes"
}

#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  en "Print"
    ::msgcat::mcset  en "Printer"
    ::msgcat::mcset  en "Letter "
    ::msgcat::mcset  en "Legal "
    ::msgcat::mcset  en "A4"
    ::msgcat::mcset  en "Grayscale"
    ::msgcat::mcset  en "RGB"
    ::msgcat::mcset  en "Options"
    ::msgcat::mcset  en "Copies"
    ::msgcat::mcset  en "Paper"
    ::msgcat::mcset  en "Scale"
    ::msgcat::mcset  en "Orientation"
    ::msgcat::mcset  en "Portrait"
    ::msgcat::mcset  en "Landscape"
    ::msgcat::mcset  en "Output"
}

Changes to library/msgs/eo.msg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74


















75
namespace eval ::tk {
    ::msgcat::mcset eo "&Abort" "&Ĉesigo"
    ::msgcat::mcset eo "&About..." "Pri..."
    ::msgcat::mcset eo "All Files" "Ĉioj dosieroj"
    ::msgcat::mcset eo "Application Error" "Aplikoerraro"
    ::msgcat::mcset eo "&Blue" "&Blua"
    ::msgcat::mcset eo "Cancel" "Rezignu"
    ::msgcat::mcset eo "&Cancel" "&Rezignu"
    ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble ĉangi al dosierulon \"%1\$s\".\nVi ne rajtas tion."
    ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujo"
    ::msgcat::mcset eo "Cl&ear" "&Klaru"
    ::msgcat::mcset eo "&Clear Console" "&Klaru konzolon"
    ::msgcat::mcset eo "Color" "Farbo"
    ::msgcat::mcset eo "Console" "Konzolo"
    ::msgcat::mcset eo "&Copy" "&Kopiu"
    ::msgcat::mcset eo "Cu&t" "&Enpoŝigu"
    ::msgcat::mcset eo "&Delete" "&Forprenu"
    ::msgcat::mcset eo "Details >>" "Detaloj >>"
    ::msgcat::mcset eo "Directory \"%1\$s\" does not exist." "La dosierujo \"%1\$s\" ne ekzistas."
    ::msgcat::mcset eo "&Directory:" "&Dosierujo:"
    ::msgcat::mcset eo "&Edit" "&Redaktu"
    ::msgcat::mcset eo "Error: %1\$s" "Eraro: %1\$s"
    ::msgcat::mcset eo "E&xit" "&Eliru"
    ::msgcat::mcset eo "&File" "&Dosiero"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\nĈu vi volas anstataûigi la dosieron?"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam egzistas. \n\n"
    ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosierp \"%1\$s\" ne estas."
    ::msgcat::mcset eo "File &name:" "Dosiero&nomo:"
    ::msgcat::mcset eo "File &names:" "Dosiero&nomoj:"
    ::msgcat::mcset eo "Files of &type:" "Dosieroj de &Typo:"
    ::msgcat::mcset eo "Fi&les:" "Do&sieroj:"
    ::msgcat::mcset eo "&Filter" "&Filtrilo"
    ::msgcat::mcset eo "Fil&ter:" "&Filtrilo:"
    ::msgcat::mcset eo "&Green" "&Verda"
    ::msgcat::mcset eo "&Help" "&Helpu"
    ::msgcat::mcset eo "Hi" "Saluton"
    ::msgcat::mcset eo "&Hide Console" "&Kaŝu konzolon"
    ::msgcat::mcset eo "&Ignore" "&Ignoru"
    ::msgcat::mcset eo "Invalid file name \"%1\$s\"." "Malvalida dosieronomo \"%1\$s\"."
    ::msgcat::mcset eo "Log Files" "Protokolo"
    ::msgcat::mcset eo "&No" "&Ne"
    ::msgcat::mcset eo "&OK"
    ::msgcat::mcset eo "OK"
    ::msgcat::mcset eo "Ok"
    ::msgcat::mcset eo "Open" "Malfermu"
    ::msgcat::mcset eo "&Open" "&Malfermu"
    ::msgcat::mcset eo "Open Multiple Files" "Melfermu multan dosierojn"
    ::msgcat::mcset eo "P&aste" "&Elpoŝigi"
    ::msgcat::mcset eo "&Quit" "&Finigu"
    ::msgcat::mcset eo "&Red" "&Rosa"
    ::msgcat::mcset eo "Replace existing file?" "Ĉu anstataûu ekzistantan dosieron?"
    ::msgcat::mcset eo "&Retry" "&Ripetu"
    ::msgcat::mcset eo "&Save" "&Savu"
    ::msgcat::mcset eo "Save As" "Savu kiel"
    ::msgcat::mcset eo "Save To Log" "Savu en protokolon"
    ::msgcat::mcset eo "Select Log File" "Elektu prokolodosieron"
    ::msgcat::mcset eo "Select a file to source" "Elektu dosieron por interpreti"
    ::msgcat::mcset eo "&Selection:" "&Elekto:"
    ::msgcat::mcset eo "Skip Messages" "transsaltu pluajn mesaĝojn"
    ::msgcat::mcset eo "&Source..." "&Fontoprogramo..."
    ::msgcat::mcset eo "Tcl Scripts" "Tcl-skriptoj"
    ::msgcat::mcset eo "Tcl for Windows" "Tcl por vindoso"
    ::msgcat::mcset eo "Text Files" "Tekstodosierojn"
    ::msgcat::mcset eo "&Yes" "&Jes"
    ::msgcat::mcset eo "abort" "ĉesigo"
    ::msgcat::mcset eo "blue" "blua"
    ::msgcat::mcset eo "cancel" "rezignu"
    ::msgcat::mcset eo "extension" "ekspansio"
    ::msgcat::mcset eo "extensions" "ekspansioj"
    ::msgcat::mcset eo "green" "verda"
    ::msgcat::mcset eo "ignore" "ignorieren"
    ::msgcat::mcset eo "red" "ruĝa"
    ::msgcat::mcset eo "retry" "ripetu"
    ::msgcat::mcset eo "yes" "jes"


















}

|

|
|



|
|
|
|
|


|
|







|
|
|


|









|

|
|
|


|
|
|
|
|
|
|
|
|



|


|
|

|


|
|

|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
namespace eval ::tk {
    ::msgcat::mcset eo "&Abort" "&Ĉesigu"
    ::msgcat::mcset eo "&About..." "Pri..."
    ::msgcat::mcset eo "All Files" "Ĉiuj dosieroj"
    ::msgcat::mcset eo "Application Error" "Aplikoeraro"
    ::msgcat::mcset eo "&Blue" "&Blua"
    ::msgcat::mcset eo "Cancel" "Rezignu"
    ::msgcat::mcset eo "&Cancel" "&Rezignu"
    ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble ŝanĝi al dosierujo \"%1\$s\".\nVi ne rajtas tion."
    ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujon"
    ::msgcat::mcset eo "Cl&ear" "&Vakigu"
    ::msgcat::mcset eo "&Clear Console" "&Vakigu konzolon"
    ::msgcat::mcset eo "Color" "Koloro"
    ::msgcat::mcset eo "Console" "Konzolo"
    ::msgcat::mcset eo "&Copy" "&Kopiu"
    ::msgcat::mcset eo "Cu&t" "&Eltondu"
    ::msgcat::mcset eo "&Delete" "&Forigu"
    ::msgcat::mcset eo "Details >>" "Detaloj >>"
    ::msgcat::mcset eo "Directory \"%1\$s\" does not exist." "La dosierujo \"%1\$s\" ne ekzistas."
    ::msgcat::mcset eo "&Directory:" "&Dosierujo:"
    ::msgcat::mcset eo "&Edit" "&Redaktu"
    ::msgcat::mcset eo "Error: %1\$s" "Eraro: %1\$s"
    ::msgcat::mcset eo "E&xit" "&Eliru"
    ::msgcat::mcset eo "&File" "&Dosiero"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\nĈu vi volas anstataŭigi la dosieron?"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam ekzistas. \n\n"
    ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosiero \"%1\$s\" ne ekzistas."
    ::msgcat::mcset eo "File &name:" "Dosiero&nomo:"
    ::msgcat::mcset eo "File &names:" "Dosiero&nomoj:"
    ::msgcat::mcset eo "Files of &type:" "Dosieroj de &Tipo:"
    ::msgcat::mcset eo "Fi&les:" "Do&sieroj:"
    ::msgcat::mcset eo "&Filter" "&Filtrilo"
    ::msgcat::mcset eo "Fil&ter:" "&Filtrilo:"
    ::msgcat::mcset eo "&Green" "&Verda"
    ::msgcat::mcset eo "&Help" "&Helpu"
    ::msgcat::mcset eo "Hi" "Saluton"
    ::msgcat::mcset eo "&Hide Console" "&Kaŝu konzolon"
    ::msgcat::mcset eo "&Ignore" "&Ignoru"
    ::msgcat::mcset eo "Invalid file name \"%1\$s\"." "Malvalida dosieronomo \"%1\$s\"."
    ::msgcat::mcset eo "Log Files" "Protokolaj dosieroj"
    ::msgcat::mcset eo "&No" "&Ne"
    ::msgcat::mcset eo "&OK" "&Bone"
    ::msgcat::mcset eo "OK" "Bone"
    ::msgcat::mcset eo "Ok" "Bone"
    ::msgcat::mcset eo "Open" "Malfermu"
    ::msgcat::mcset eo "&Open" "&Malfermu"
    ::msgcat::mcset eo "Open Multiple Files" "Malfermu plurajn dosierojn"
    ::msgcat::mcset eo "P&aste" "&Algluu"
    ::msgcat::mcset eo "&Quit" "&Forlasu"
    ::msgcat::mcset eo "&Red" "&Ra"
    ::msgcat::mcset eo "Replace existing file?" "Ĉu anstataŭigi ekzistantan dosieron?"
    ::msgcat::mcset eo "&Retry" "&Reprovu"
    ::msgcat::mcset eo "&Save" "&Konservu"
    ::msgcat::mcset eo "Save As" "Konservu kiel"
    ::msgcat::mcset eo "Save To Log" "Konservu en protokolon"
    ::msgcat::mcset eo "Select Log File" "Elektu prokolodosieron"
    ::msgcat::mcset eo "Select a file to source" "Elektu dosieron por interpreti"
    ::msgcat::mcset eo "&Selection:" "&Elekto:"
    ::msgcat::mcset eo "Skip Messages" "transsaltu mesaĝojn"
    ::msgcat::mcset eo "&Source..." "&Fontoprogramo..."
    ::msgcat::mcset eo "Tcl Scripts" "Tcl-skriptoj"
    ::msgcat::mcset eo "Tcl for Windows" "Tcl por Vindozo"
    ::msgcat::mcset eo "Text Files" "Tekstodosieroj"
    ::msgcat::mcset eo "&Yes" "&Jes"
    ::msgcat::mcset eo "abort" "ĉesigu"
    ::msgcat::mcset eo "blue" "blua"
    ::msgcat::mcset eo "cancel" "rezignu"
    ::msgcat::mcset eo "extension" "kromprogramo"
    ::msgcat::mcset eo "extensions" "kromprogramoj"
    ::msgcat::mcset eo "green" "verda"
    ::msgcat::mcset eo "ignore" "ignoru"
    ::msgcat::mcset eo "red" "ruĝa"
    ::msgcat::mcset eo "retry" "reprovu"
    ::msgcat::mcset eo "yes" "jes"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  eo "Print" "Presi"
    ::msgcat::mcset  eo "Printer" "Presilo"
    ::msgcat::mcset  eo "Letter " "Letero"
    ::msgcat::mcset  eo "Legal " "Laŭleĝa"
    ::msgcat::mcset  eo "A4" "A4"
    ::msgcat::mcset  eo "Grayscale" "Grizskalo"
    ::msgcat::mcset  eo "RGB" "RGB"
    ::msgcat::mcset  eo "Options" "Opcioj"
    ::msgcat::mcset  eo "Copies" "Kopioj"
    ::msgcat::mcset  eo "Paper" "Papero"
    ::msgcat::mcset  eo "Scale" "Skalo"
    ::msgcat::mcset  eo "Orientation" "Orientiĝo"
    ::msgcat::mcset  eo "Portrait" "Portreto"
    ::msgcat::mcset  eo "Landscape" "Pejzaĝo"
    ::msgcat::mcset  eo "Output" "Eligo"
}

Changes to library/msgs/es.msg.

69
70
71
72
73
74
75


















76
    ::msgcat::mcset es "extensions" "extensiones"
    ::msgcat::mcset es "green" "verde"
    ::msgcat::mcset es "ignore" "ignorar"
    ::msgcat::mcset es "ok"
    ::msgcat::mcset es "red" "rojo"
    ::msgcat::mcset es "retry" "reintentar"
    ::msgcat::mcset es "yes" "sí"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    ::msgcat::mcset es "extensions" "extensiones"
    ::msgcat::mcset es "green" "verde"
    ::msgcat::mcset es "ignore" "ignorar"
    ::msgcat::mcset es "ok"
    ::msgcat::mcset es "red" "rojo"
    ::msgcat::mcset es "retry" "reintentar"
    ::msgcat::mcset es "yes" "sí"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
	::msgcat::mcset  es "Print" "Imprimir"
	::msgcat::mcset  es "Printer" "Impresora"
	::msgcat::mcset  es "Letter" "Carta"
	::msgcat::mcset  es "Legal" "Legal"
	::msgcat::mcset  es "A4" "A4"
	::msgcat::mcset  es "Grayscale" "Escala De Grises"
	::msgcat::mcset  es "RGB" "Color"
	::msgcat::mcset  es "Options" "Opciones"
	::msgcat::mcset  es "Copies" "Copias"
	::msgcat::mcset  es "Paper" "Papel"
	::msgcat::mcset  es "Scale" "Escala"
	::msgcat::mcset  es "Orientation" "Orientación"
	::msgcat::mcset  es "Portrait" "Retrato"
	::msgcat::mcset  es "Landscape" "Paisaje"
	::msgcat::mcset  es "Output" "Salida"
}

Added library/msgs/fi.msg.





































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
namespace eval ::tk {
    ::msgcat::mcset fi "AaBbYyZz01" "AaBbÄäÖö01"
    ::msgcat::mcset fi "&Abort" "&Keskeytä"
    ::msgcat::mcset fi "&About..." "&Tietoja..."
    ::msgcat::mcset fi "All Files" "Kaikki tiedostot"
    ::msgcat::mcset fi "&Apply" "Kä&ytä"
    ::msgcat::mcset fi "Application Error" "Ohjelmavirhe"
    ::msgcat::mcset fi "&Blue" "&Sininen"
    ::msgcat::mcset fi "Bold" "Lihavoitu"
    ::msgcat::mcset fi "Bold Italic" "Lihavoitu, kursivoitu"
    ::msgcat::mcset fi "Cancel" "Peruuta"
    ::msgcat::mcset fi "&Cancel" "&Peruuta"
    ::msgcat::mcset fi "Cannot change to the directory \"%1\$s\".\nPermission denied." "Ei voitu vaihtaa hakemistoon \"%1\$s\".\nLupa evätty."
    ::msgcat::mcset fi "Choose Directory" "Valitse hakemisto"
    ::msgcat::mcset fi "Cl&ear" "&Tyhjennä"
    ::msgcat::mcset fi "&Clear Console" "&Tyhjennä konsoli"
    ::msgcat::mcset fi "Color" "Väri"
    ::msgcat::mcset fi "Console" "Konsoli"
    ::msgcat::mcset fi "&Copy" "K&opioi"
    ::msgcat::mcset fi "Cu&t" "&Leikkaa"
    ::msgcat::mcset fi "&Decrease Font Size" "&Pienennä kirjasinkokoa"
    ::msgcat::mcset fi "&Delete" "&Poista"
    ::msgcat::mcset fi "Details >>" "Lisätiedot >>"
    ::msgcat::mcset fi "Directory \"%1\$s\" does not exist." "Hakemistoa \"%1\$s\" ei ole olemassa."
    ::msgcat::mcset fi "&Directory:" "&Hakemisto:"
    ::msgcat::mcset fi "&Edit" "&Muokkaa"
    ::msgcat::mcset fi "Effects" "Tehosteet"
    ::msgcat::mcset fi "Error: %1\$s" "Virhe: %1\$s"
    ::msgcat::mcset fi "E&xit" "&Lopeta"
    ::msgcat::mcset fi "&File" "&Tiedosto"
    ::msgcat::mcset fi "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Tiedosto \"%1\$s\" on jo olemassa.\nHaluatko korvata sen?"
    ::msgcat::mcset fi "File \"%1\$s\" already exists.\n\n" "Tiedosto \"%1\$s\" on jo olemassa.\n\n"
    ::msgcat::mcset fi "File \"%1\$s\" does not exist." "Tiedostoa \"%1\$s\" ei ole olemassa."
    ::msgcat::mcset fi "File &name:" "Tiedosto&nimi:"
    ::msgcat::mcset fi "File &names:" "Tiedosto&nimet:"
    ::msgcat::mcset fi "Files of &type:" "T&yyppi:"
    ::msgcat::mcset fi "Fi&les:" "Ti&edostot:"
    ::msgcat::mcset fi "&Filter" "&Suodata"
    ::msgcat::mcset fi "Fil&ter:" "Suo&data:"
    ::msgcat::mcset fi "Fit To Screen Width" "Sovita ruudun kokoon"
    ::msgcat::mcset fi "Font" "Kirjasin"
    ::msgcat::mcset fi "&Font..." "Kir&jasin..."
    ::msgcat::mcset fi "&Font:" "&Kirjasin:"
    ::msgcat::mcset fi "Font st&yle:" "Kirjasint&yyli:"
    ::msgcat::mcset fi "&Green" "&Vihreä"
    ::msgcat::mcset fi "Help" "Ohje"
    ::msgcat::mcset fi "&Help" "&Ohje"
    ::msgcat::mcset fi "Hi" "Hei"
    ::msgcat::mcset fi "&Hide Console" "P&iilota konsoli"
    ::msgcat::mcset fi "Hide Fonts" "Piilota kirjasimet"
    ::msgcat::mcset fi "&Ignore" "&Ohita"
    ::msgcat::mcset fi "&Increase Font Size" "&Suurenna kirjasinkokoa"
    ::msgcat::mcset fi "Invalid file name \"%1\$s\"." "Virheellinen tiedostonimi \"%1\$s\"."
    ::msgcat::mcset fi "Italic" "Kursivoitu"
    ::msgcat::mcset fi "Log Files" "Lokitiedostot"
    ::msgcat::mcset fi "&No" "&Ei"
    ::msgcat::mcset fi "&OK"
    ::msgcat::mcset fi "OK"
    ::msgcat::mcset fi "Ok" "OK"
    ::msgcat::mcset fi "Open" "Avaa"
    ::msgcat::mcset fi "&Open" "&Avaa"
    ::msgcat::mcset fi "Open Multiple Files" "Avaa monta tiedostoa"
    ::msgcat::mcset fi "P&aste" "L&iitä"
    ::msgcat::mcset fi "&Quit" "&Lopeta"
    ::msgcat::mcset fi "&Red" "&Punainen"
    ::msgcat::mcset fi "Regular" "Tavallinen"
    ::msgcat::mcset fi "Replace existing file?" "Korvataanko olemassaoleva tiedosto?"
    ::msgcat::mcset fi "&Retry" "&Yritä uudelleen"
    ::msgcat::mcset fi "Sample" "Malli"
    ::msgcat::mcset fi "&Save" "&Tallenna"
    ::msgcat::mcset fi "Save As" "Tallenna nimellä"
    ::msgcat::mcset fi "Save To Log" "Tallenna lokiin"
    ::msgcat::mcset fi "Select Log File" "Valitse lokitiedosto"
    ::msgcat::mcset fi "Select a file to source" "Valitse lähdetiedosto"
    ::msgcat::mcset fi "&Selection:" "&Valinta:"
    ::msgcat::mcset fi "Show Fonts" "Näytä kirjasimet"
    ::msgcat::mcset fi "Skip Messages" "Jätä viestit huomiotta"
    ::msgcat::mcset fi "&Size:" "K&oko:"
    ::msgcat::mcset fi "&Source..." "L&ähde..."
    ::msgcat::mcset fi "Stri&keout" "&Yliviivaa"
    ::msgcat::mcset fi "Tcl Scripts" "Tcl-skriptit"
    ::msgcat::mcset fi "Tcl for Windows" "Tcl Windowsille"
    ::msgcat::mcset fi "Text Files" "Tekstitiedostot"
    ::msgcat::mcset fi "&Underline" "&Alleviivaa"
    ::msgcat::mcset fi "Window" "Ikkuna"
    ::msgcat::mcset fi "&Yes" "&Kyllä"
    ::msgcat::mcset fi "abort" "keskeytä"
    ::msgcat::mcset fi "blue" "sininen"
    ::msgcat::mcset fi "cancel" "peruuta"
    ::msgcat::mcset fi "extension" "lisäosa"
    ::msgcat::mcset fi "extensions" "lisäosat"
    ::msgcat::mcset fi "green" "vihreä"
    ::msgcat::mcset fi "ignore" "ohita"
    ::msgcat::mcset fi "ok"
    ::msgcat::mcset fi "red" "punainen"
    ::msgcat::mcset fi "retry" "yritä uudelleen"
    ::msgcat::mcset fi "yes" "kyllä"

    ::msgcat::mcset fi "Print" "Tulosta"
    ::msgcat::mcset fi "Printer" "Tulostin"
    ::msgcat::mcset fi "Letter " "Letter"
    ::msgcat::mcset fi "Legal " "Legal"
    ::msgcat::mcset fi "A4" "A4"
    ::msgcat::mcset fi "Grayscale" "Harmaasävy"
    ::msgcat::mcset fi "RGB" "RGB"
    ::msgcat::mcset fi "Options" "Asetukset"
    ::msgcat::mcset fi "Copies" "Tulosteita"
    ::msgcat::mcset fi "Paper" "Paperikoko"
    ::msgcat::mcset fi "Scale" "Skaalaus"
    ::msgcat::mcset fi "Orientation" "Suunta"
    ::msgcat::mcset fi "Portrait" "Pysty"
    ::msgcat::mcset fi "Landscape" "Vaaka"
    ::msgcat::mcset fi "Output" "Tulos"
}

Changes to library/msgs/fr.msg.

65
66
67
68
69
70
71


















72
    ::msgcat::mcset fr "extensions"
    ::msgcat::mcset fr "green" "vert"
    ::msgcat::mcset fr "ignore" "ignorer"
    ::msgcat::mcset fr "ok"
    ::msgcat::mcset fr "red" "rouge"
    ::msgcat::mcset fr "retry" "réessayer"
    ::msgcat::mcset fr "yes" "oui"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    ::msgcat::mcset fr "extensions"
    ::msgcat::mcset fr "green" "vert"
    ::msgcat::mcset fr "ignore" "ignorer"
    ::msgcat::mcset fr "ok"
    ::msgcat::mcset fr "red" "rouge"
    ::msgcat::mcset fr "retry" "réessayer"
    ::msgcat::mcset fr "yes" "oui"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  fr "Print" "Imprimer"
    ::msgcat::mcset  fr "Printer" "Imprimante"
    ::msgcat::mcset  fr "Letter " "Lettre"
    ::msgcat::mcset  fr "Legal " "Légal"
    ::msgcat::mcset  fr "A4" "A4"
    ::msgcat::mcset  fr "Grayscale" "Niveaux de Gris"
    ::msgcat::mcset  fr "RGB" "RVB"
    ::msgcat::mcset  fr "Options" "Options"
    ::msgcat::mcset  fr "Copies" "Nombre d'exemplaires"
    ::msgcat::mcset  fr "Paper" "Papier"
    ::msgcat::mcset  fr "Scale" "Échelle"
    ::msgcat::mcset  fr "Orientation" "Orientation"
    ::msgcat::mcset  fr "Portrait" "Portrait"
    ::msgcat::mcset  fr "Landscape" "Paysage"
    ::msgcat::mcset  fr "Output" "Sortie"
}

Changes to library/msgs/hu.msg.

71
72
73
74
75
76
77


















78
    ::msgcat::mcset hu "extensions" "kiterjesztések"
    ::msgcat::mcset hu "green" "zöld"
    ::msgcat::mcset hu "ignore" "ignorer"
    ::msgcat::mcset hu "ok"
    ::msgcat::mcset hu "red" "vörös"
    ::msgcat::mcset hu "retry" "újra"
    ::msgcat::mcset hu "yes" "igen"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    ::msgcat::mcset hu "extensions" "kiterjesztések"
    ::msgcat::mcset hu "green" "zöld"
    ::msgcat::mcset hu "ignore" "ignorer"
    ::msgcat::mcset hu "ok"
    ::msgcat::mcset hu "red" "vörös"
    ::msgcat::mcset hu "retry" "újra"
    ::msgcat::mcset hu "yes" "igen"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  hu "Print" "Nyomtat"
    ::msgcat::mcset  hu "Printer" "Nyomtató"
    ::msgcat::mcset  hu "Letter " "Levél"
    ::msgcat::mcset  hu "Legal " "Törvényes"
    ::msgcat::mcset  hu "A4" "A4"
    ::msgcat::mcset  hu "Grayscale" "Szürkeárnyalatos"
    ::msgcat::mcset  hu "RGB" "Rgb"
    ::msgcat::mcset  hu "Options" "Beállítások"
    ::msgcat::mcset  hu "Copies" "Másolatok"
    ::msgcat::mcset  hu "Paper" "Papír"
    ::msgcat::mcset  hu "Scale" "Hangsor"
    ::msgcat::mcset  hu "Orientation" "Tájékozódás"
    ::msgcat::mcset  hu "Portrait" "Portré"
    ::msgcat::mcset  hu "Landscape" "Táj"
    ::msgcat::mcset  hu "Output" "Hozam"
}

Changes to library/msgs/it.msg.

66
67
68
69
70
71
72


















73
    ::msgcat::mcset it "extensions" "estensioni"
    ::msgcat::mcset it "green" "verde"
    ::msgcat::mcset it "ignore" "ignora"
    ::msgcat::mcset it "ok"
    ::msgcat::mcset it "red" "rosso"
    ::msgcat::mcset it "retry" "riprova"
    ::msgcat::mcset it "yes" "sì"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    ::msgcat::mcset it "extensions" "estensioni"
    ::msgcat::mcset it "green" "verde"
    ::msgcat::mcset it "ignore" "ignora"
    ::msgcat::mcset it "ok"
    ::msgcat::mcset it "red" "rosso"
    ::msgcat::mcset it "retry" "riprova"
    ::msgcat::mcset it "yes" "sì"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  it "Print" "Stampare"
    ::msgcat::mcset  it "Printer" "Stampante"
    ::msgcat::mcset  it "Letter " "Lettera"
    ::msgcat::mcset  it "Legal " "Legale"
    ::msgcat::mcset  it "A4" "A4"
    ::msgcat::mcset  it "Grayscale" "Scala Di Grigi"
    ::msgcat::mcset  it "RGB" "Rgb"
    ::msgcat::mcset  it "Options" "Opzioni"
    ::msgcat::mcset  it "Copies" "Copie"
    ::msgcat::mcset  it "Paper" "Carta"
    ::msgcat::mcset  it "Scale" "Scala"
    ::msgcat::mcset  it "Orientation" "Orientamento"
    ::msgcat::mcset  it "Portrait" "Ritratto"
    ::msgcat::mcset  it "Landscape" "Paesaggio"
    ::msgcat::mcset  it "Output" "Prodotto"
}

Changes to library/msgs/nl.msg.

84
85
86
87
88
89
90


















91
    ::msgcat::mcset nl "extensions"
    ::msgcat::mcset nl "green" "groen"
    ::msgcat::mcset nl "ignore" "negeren"
    ::msgcat::mcset nl "ok"
    ::msgcat::mcset nl "red" "rood"
    ::msgcat::mcset nl "retry" "opnieuw"
    ::msgcat::mcset nl "yes" "ja"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    ::msgcat::mcset nl "extensions"
    ::msgcat::mcset nl "green" "groen"
    ::msgcat::mcset nl "ignore" "negeren"
    ::msgcat::mcset nl "ok"
    ::msgcat::mcset nl "red" "rood"
    ::msgcat::mcset nl "retry" "opnieuw"
    ::msgcat::mcset nl "yes" "ja"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  nl "Print" "Afdrukken"
    ::msgcat::mcset  nl "Printer" "Printer"
    ::msgcat::mcset  nl "Letter " "Brief"
    ::msgcat::mcset  nl "Legal " "Legaal"
    ::msgcat::mcset  nl "A4" "A4"
    ::msgcat::mcset  nl "Grayscale" "Grijswaarden"
    ::msgcat::mcset  nl "RGB" "Rgb"
    ::msgcat::mcset  nl "Options" "Opties"
    ::msgcat::mcset  nl "Copies" "Kopieën"
    ::msgcat::mcset  nl "Paper" "Papier"
    ::msgcat::mcset  nl "Scale" "Schub"
    ::msgcat::mcset  nl "Orientation" "Oriëntatie"
    ::msgcat::mcset  nl "Portrait" "Portret"
    ::msgcat::mcset  nl "Landscape" "Landschap"
    ::msgcat::mcset  nl "Output" "Uitvoer"
}

Changes to library/msgs/pl.msg.

84
85
86
87
88
89
90


















91
    ::msgcat::mcset pl "extensions" "rozszerzenia"
    ::msgcat::mcset pl "green" "zielony"
    ::msgcat::mcset pl "ignore" "ignoruj"
    ::msgcat::mcset pl "ok"
    ::msgcat::mcset pl "red" "czerwony"
    ::msgcat::mcset pl "retry" "ponów"
    ::msgcat::mcset pl "yes" "tak"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    ::msgcat::mcset pl "extensions" "rozszerzenia"
    ::msgcat::mcset pl "green" "zielony"
    ::msgcat::mcset pl "ignore" "ignoruj"
    ::msgcat::mcset pl "ok"
    ::msgcat::mcset pl "red" "czerwony"
    ::msgcat::mcset pl "retry" "ponów"
    ::msgcat::mcset pl "yes" "tak"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  pl "Print" "Drukować"
    ::msgcat::mcset  pl "Printer" "Drukarka"
    ::msgcat::mcset  pl "Letter " "Litera"
    ::msgcat::mcset  pl "Legal " "Legalny"
    ::msgcat::mcset  pl "A4" "A4"
    ::msgcat::mcset  pl "Grayscale" "Skala Szarości"
    ::msgcat::mcset  pl "RGB" "Rgb"
    ::msgcat::mcset  pl "Options" "Opcje"
    ::msgcat::mcset  pl "Copies" "Kopie"
    ::msgcat::mcset  pl "Paper" "Papier"
    ::msgcat::mcset  pl "Scale" "Skala"
    ::msgcat::mcset  pl "Orientation" "Orientacja"
    ::msgcat::mcset  pl "Portrait" "Portret"
    ::msgcat::mcset  pl "Landscape" "Krajobraz"
    ::msgcat::mcset  pl "Output" "Produkt Wyjściowy"
}

Changes to library/msgs/pt.msg.

67
68
69
70
71
72
73


















74
    ::msgcat::mcset pt "extensions" "extensões"
    ::msgcat::mcset pt "green" "verde"
    ::msgcat::mcset pt "ignore" "ignorar"
    ::msgcat::mcset pt "ok"
    ::msgcat::mcset pt "red" "vermelho"
    ::msgcat::mcset pt "retry" "tentar novamente"
    ::msgcat::mcset pt "yes" "sim"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    ::msgcat::mcset pt "extensions" "extensões"
    ::msgcat::mcset pt "green" "verde"
    ::msgcat::mcset pt "ignore" "ignorar"
    ::msgcat::mcset pt "ok"
    ::msgcat::mcset pt "red" "vermelho"
    ::msgcat::mcset pt "retry" "tentar novamente"
    ::msgcat::mcset pt "yes" "sim"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  pt "Print" "Imprimir"
    ::msgcat::mcset  pt "Printer" "Impressora"
    ::msgcat::mcset  pt "Letter " "Letra"
    ::msgcat::mcset  pt "Legal " "Legal"
    ::msgcat::mcset  pt "A4" "A4"
    ::msgcat::mcset  pt "Grayscale" "Escala De Cinza"
    ::msgcat::mcset  pt "RGB" "Rgb"
    ::msgcat::mcset  pt "Options" "Opções"
    ::msgcat::mcset  pt "Copies" "Exemplares"
    ::msgcat::mcset  pt "Paper" "Papel"
    ::msgcat::mcset  pt "Scale" "Escala"
    ::msgcat::mcset  pt "Orientation" "Orientação"
    ::msgcat::mcset  pt "Portrait" "Retrato"
    ::msgcat::mcset  pt "Landscape" "Paisagem"
    ::msgcat::mcset  pt "Output" "Saída"
}

Changes to library/msgs/ru.msg.

1
2
3
4
5



6
7
8
9
10
11
12

13
14
15
16
17
18
19
20


21
22

23
24
25
26
27
28
29
30
31
32



33

34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50

51
52
53
54
55
56



57
58

59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75


















namespace eval ::tk {
    ::msgcat::mcset ru "&Abort" "&Отменить"
    ::msgcat::mcset ru "&About..." "Про..."
    ::msgcat::mcset ru "All Files" "Все файлы"
    ::msgcat::mcset ru "Application Error" "Ошибка в программе"



    ::msgcat::mcset ru "&Blue" " &Голубой"
    ::msgcat::mcset ru "Cancel" "От&мена"
    ::msgcat::mcset ru "&Cancel" "От&мена"
    ::msgcat::mcset ru "Cannot change to the directory \"%1\$s\".\nPermission denied." \
			"Не могу перейти в каталог \"%1\$s\".\nНедостаточно прав доступа"
    ::msgcat::mcset ru "Choose Directory" "Выберите каталог"
    ::msgcat::mcset ru "Cl&ear" "Очистить"

    ::msgcat::mcset ru "Color" "Цвет"
    ::msgcat::mcset ru "Console" "Консоль"
    ::msgcat::mcset ru "&Copy" "Копировать"
    ::msgcat::mcset ru "Cu&t" "Вырезать"
    ::msgcat::mcset ru "&Delete" "Удалить"
    ::msgcat::mcset ru "Details >>" "Подробнее >>"
    ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "Каталога \"%1\$s\" не существует."
    ::msgcat::mcset ru "&Directory:" "&Каталог:"


    ::msgcat::mcset ru "Error: %1\$s" "Ошибка: %1\$s"
    ::msgcat::mcset ru "E&xit" "Выход"

    ::msgcat::mcset ru "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \
			    "Файл \"%1\$s\" уже существует.\nЗаменить его?"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "Файл \"%1\$s\" уже существует.\n\n"
    ::msgcat::mcset ru "File \"%1\$s\" does not exist." "Файл \"%1\$s\" не найден."
    ::msgcat::mcset ru "File &name:" "&Имя файла:"
    ::msgcat::mcset ru "File &names:" "&Имена файлов:"
    ::msgcat::mcset ru "Files of &type:" "&Тип файлов:"
    ::msgcat::mcset ru "Fi&les:" "Фай&лы:"
    ::msgcat::mcset ru "&Filter" "&Фильтр"
    ::msgcat::mcset ru "Fil&ter:" "Филь&тр:"



    ::msgcat::mcset ru "&Green" " &Зеленый"

    ::msgcat::mcset ru "Hi" "Привет"
    ::msgcat::mcset ru "&Hide Console" "Спрятать консоль"
    ::msgcat::mcset ru "&Ignore" "&Игнорировать"
    ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "Неверное имя файла \"%1\$s\"."

    ::msgcat::mcset ru "Log Files" "Файлы журнала"
    ::msgcat::mcset ru "&No" "&Нет"
    ::msgcat::mcset ru "&OK" "&ОК"
    ::msgcat::mcset ru "OK" "ОК"
    ::msgcat::mcset ru "Ok" "Да"
    ::msgcat::mcset ru "Open" "Открыть"
    ::msgcat::mcset ru "&Open" "&Открыть"
    ::msgcat::mcset ru "Open Multiple Files" "Открыть несколько файлов"
    ::msgcat::mcset ru "P&aste" "Вставить"
    ::msgcat::mcset ru "&Quit" "Выход"
    ::msgcat::mcset ru "&Red" " &Красный"
    ::msgcat::mcset ru "Replace existing file?" "Заменить существующий файл?"

    ::msgcat::mcset ru "&Retry" "&Повторить"

    ::msgcat::mcset ru "&Save" "&Сохранить"
    ::msgcat::mcset ru "Save As" "Сохранить как"
    ::msgcat::mcset ru "Save To Log" "Сохранить в журнал"
    ::msgcat::mcset ru "Select Log File" "Выбрать журнал"
    ::msgcat::mcset ru "Select a file to source" "Выберите файл для интерпретации"
    ::msgcat::mcset ru "&Selection:"



    ::msgcat::mcset ru "Skip Messages" "Пропустить сообщения"
    ::msgcat::mcset ru "&Source..." "Интерпретировать файл..."

    ::msgcat::mcset ru "Tcl Scripts" "Программа на языке TCL"
    ::msgcat::mcset ru "Tcl for Windows" "TCL для Windows"
    ::msgcat::mcset ru "Text Files" "Текстовые файлы"

    ::msgcat::mcset ru "&Yes" "&Да"
    ::msgcat::mcset ru "abort" "отмена"
    ::msgcat::mcset ru "blue" " голубой"
    ::msgcat::mcset ru "cancel" "отмена"
    ::msgcat::mcset ru "extension" "расширение"
    ::msgcat::mcset ru "extensions" "расширения"
    ::msgcat::mcset ru "green" " зеленый"
    ::msgcat::mcset ru "ignore" "пропустить"
    ::msgcat::mcset ru "ok" "ок"
    ::msgcat::mcset ru "red" " красный"
    ::msgcat::mcset ru "retry" "повторить"
    ::msgcat::mcset ru "yes" "да"
}
























>
>
>

|





>








>
>


>










>
>
>

>




>












>

>






>
>
>


>



>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
namespace eval ::tk {
    ::msgcat::mcset ru "&Abort" "&Отменить"
    ::msgcat::mcset ru "&About..." "Про..."
    ::msgcat::mcset ru "All Files" "Все файлы"
    ::msgcat::mcset ru "Application Error" "Ошибка в программе"
    ::msgcat::mcset ru "&Apply" "&Применить"
    ::msgcat::mcset ru "Bold" "Bold"
    ::msgcat::mcset ru "Bold Italic" "Bold Italic"
    ::msgcat::mcset ru "&Blue" " &Голубой"
    ::msgcat::mcset ru "Cancel" "Отмена"
    ::msgcat::mcset ru "&Cancel" "От&мена"
    ::msgcat::mcset ru "Cannot change to the directory \"%1\$s\".\nPermission denied." \
			"Не могу перейти в каталог \"%1\$s\".\nНедостаточно прав доступа"
    ::msgcat::mcset ru "Choose Directory" "Выберите каталог"
    ::msgcat::mcset ru "Cl&ear" "Очистить"
    ::msgcat::mcset ru "&Clear Console" "&Clear Console"
    ::msgcat::mcset ru "Color" "Цвет"
    ::msgcat::mcset ru "Console" "Консоль"
    ::msgcat::mcset ru "&Copy" "Копировать"
    ::msgcat::mcset ru "Cu&t" "Вырезать"
    ::msgcat::mcset ru "&Delete" "Удалить"
    ::msgcat::mcset ru "Details >>" "Подробнее >>"
    ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "Каталога \"%1\$s\" не существует."
    ::msgcat::mcset ru "&Directory:" "&Каталог:"
    ::msgcat::mcset ru "&Edit" "&Edit"
    ::msgcat::mcset ru "Effects" "Эффекты"
    ::msgcat::mcset ru "Error: %1\$s" "Ошибка: %1\$s"
    ::msgcat::mcset ru "E&xit" "Выход"
    ::msgcat::mcset ru "&File" "&File"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \
			    "Файл \"%1\$s\" уже существует.\nЗаменить его?"
    ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "Файл \"%1\$s\" уже существует.\n\n"
    ::msgcat::mcset ru "File \"%1\$s\" does not exist." "Файл \"%1\$s\" не найден."
    ::msgcat::mcset ru "File &name:" "&Имя файла:"
    ::msgcat::mcset ru "File &names:" "&Имена файлов:"
    ::msgcat::mcset ru "Files of &type:" "&Тип файлов:"
    ::msgcat::mcset ru "Fi&les:" "Фай&лы:"
    ::msgcat::mcset ru "&Filter" "&Фильтр"
    ::msgcat::mcset ru "Fil&ter:" "Филь&тр:"
    ::msgcat::mcset ru "Font" "Шрифт"
    ::msgcat::mcset ru "&Font:" "&Шрифт"
    ::msgcat::mcset ru "Font st&yle:" "&Стиль шрифта:"
    ::msgcat::mcset ru "&Green" " &Зеленый"
    ::msgcat::mcset ru "&Help" "&Help"
    ::msgcat::mcset ru "Hi" "Привет"
    ::msgcat::mcset ru "&Hide Console" "Спрятать консоль"
    ::msgcat::mcset ru "&Ignore" "&Игнорировать"
    ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "Неверное имя файла \"%1\$s\"."
    ::msgcat::mcset ru "Italic" "Italic"
    ::msgcat::mcset ru "Log Files" "Файлы журнала"
    ::msgcat::mcset ru "&No" "&Нет"
    ::msgcat::mcset ru "&OK" "&ОК"
    ::msgcat::mcset ru "OK" "ОК"
    ::msgcat::mcset ru "Ok" "Да"
    ::msgcat::mcset ru "Open" "Открыть"
    ::msgcat::mcset ru "&Open" "&Открыть"
    ::msgcat::mcset ru "Open Multiple Files" "Открыть несколько файлов"
    ::msgcat::mcset ru "P&aste" "Вставить"
    ::msgcat::mcset ru "&Quit" "Выход"
    ::msgcat::mcset ru "&Red" " &Красный"
    ::msgcat::mcset ru "Replace existing file?" "Заменить существующий файл?"
    ::msgcat::mcset ru "Regular" "Regular"
    ::msgcat::mcset ru "&Retry" "&Повторить"
    ::msgcat::mcset ru "Sample" "Пример"
    ::msgcat::mcset ru "&Save" "&Сохранить"
    ::msgcat::mcset ru "Save As" "Сохранить как"
    ::msgcat::mcset ru "Save To Log" "Сохранить в журнал"
    ::msgcat::mcset ru "Select Log File" "Выбрать журнал"
    ::msgcat::mcset ru "Select a file to source" "Выберите файл для интерпретации"
    ::msgcat::mcset ru "&Selection:"
    ::msgcat::mcset ru "&Size:" "&Размер:"
    ::msgcat::mcset ru "Show &Hidden Directories" "Show &Hidden Directories"
    ::msgcat::mcset ru "Show &Hidden Files and Directories" "Show &Hidden Files and Directories"
    ::msgcat::mcset ru "Skip Messages" "Пропустить сообщения"
    ::msgcat::mcset ru "&Source..." "Интерпретировать файл..."
    ::msgcat::mcset ru "Stri&keout" "П&еречёркнутый"
    ::msgcat::mcset ru "Tcl Scripts" "Программа на языке TCL"
    ::msgcat::mcset ru "Tcl for Windows" "TCL для Windows"
    ::msgcat::mcset ru "Text Files" "Текстовые файлы"
    ::msgcat::mcset ru "&Underline" "По&дчеркнутый"
    ::msgcat::mcset ru "&Yes" "&Да"
    ::msgcat::mcset ru "abort" "отмена"
    ::msgcat::mcset ru "blue" " голубой"
    ::msgcat::mcset ru "cancel" "отмена"
    ::msgcat::mcset ru "extension" "расширение"
    ::msgcat::mcset ru "extensions" "расширения"
    ::msgcat::mcset ru "green" " зеленый"
    ::msgcat::mcset ru "ignore" "пропустить"
    ::msgcat::mcset ru "ok" "ок"
    ::msgcat::mcset ru "red" " красный"
    ::msgcat::mcset ru "retry" "повторить"
    ::msgcat::mcset ru "yes" "да"
}

#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  ru "Print" "Печатать"
    ::msgcat::mcset  ru "Printer" "Принтер"
    ::msgcat::mcset  ru "Letter " "Письмо"
    ::msgcat::mcset  ru "Legal " "Законный"
    ::msgcat::mcset  ru "A4" "A4"
    ::msgcat::mcset  ru "Grayscale" "Серый Масштаб"
    ::msgcat::mcset  ru "RGB" "Ргб"
    ::msgcat::mcset  ru "Options" "Параметры"
    ::msgcat::mcset  ru "Copies" "Копии"
    ::msgcat::mcset  ru "Paper" "Бумага"
    ::msgcat::mcset  ru "Scale" "Шкала"
    ::msgcat::mcset  ru "Orientation" "Ориентация"
    ::msgcat::mcset  ru "Portrait" "Портрет"
    ::msgcat::mcset  ru "Landscape" "Ландшафт"
    ::msgcat::mcset  ru "Output" "Выпуск"
}

Changes to library/msgs/sv.msg.

69
70
71
72
73
74
75


















76
    ::msgcat::mcset sv "extensions" "utvidgningar"
    ::msgcat::mcset sv "green" "grön"
    ::msgcat::mcset sv "ignore" "ignorera"
    ::msgcat::mcset sv "ok"
    ::msgcat::mcset sv "red" "röd"
    ::msgcat::mcset sv "retry" "försök igen"
    ::msgcat::mcset sv "yes" "ja"


















}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    ::msgcat::mcset sv "extensions" "utvidgningar"
    ::msgcat::mcset sv "green" "grön"
    ::msgcat::mcset sv "ignore" "ignorera"
    ::msgcat::mcset sv "ok"
    ::msgcat::mcset sv "red" "röd"
    ::msgcat::mcset sv "retry" "försök igen"
    ::msgcat::mcset sv "yes" "ja"
}
#localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  sv "Print" "Trycka"
    ::msgcat::mcset  sv "Printer" "Skrivare"
    ::msgcat::mcset  sv "Letter " "Brev"
    ::msgcat::mcset  sv "Legal " "Laglig"
    ::msgcat::mcset  sv "A4" "A4 (På 199"
    ::msgcat::mcset  sv "Grayscale" "Gråskala"
    ::msgcat::mcset  sv "RGB" "Rgb"
    ::msgcat::mcset  sv "Options" "Alternativ"
    ::msgcat::mcset  sv "Copies" "Kopior"
    ::msgcat::mcset  sv "Paper" "Papper"
    ::msgcat::mcset  sv "Scale" "Skala"
    ::msgcat::mcset  sv "Orientation" "Orientering"
    ::msgcat::mcset  sv "Portrait" "Porträtt"
    ::msgcat::mcset  sv "Landscape" "Landskap"
    ::msgcat::mcset  sv "Output" "Utdata"
}

Added library/msgs/zh_cn.msg.





























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
namespace eval ::tk {
    ::msgcat::mcset zh_cn "&Abort" "&中止"
    ::msgcat::mcset zh_cn "&About..." "&关于……"
    ::msgcat::mcset zh_cn "All Files" "所有文件"
    ::msgcat::mcset zh_cn "Application Error" "应用程序错误"
    ::msgcat::mcset zh_cn "&Apply" "&添加"
    ::msgcat::mcset zh_cn "Bold" "粗体"
    ::msgcat::mcset zh_cn "Bold Italic" "加粗斜体"
    ::msgcat::mcset zh_cn "&Blue" "&蓝色"
    ::msgcat::mcset zh_cn "Cancel" "取消"
    ::msgcat::mcset zh_cn "&Cancel" "&取消"
    ::msgcat::mcset zh_cn "Cannot change to the directory \"%1\$s\".\nPermission denied." "无法更改目录 \"%1\$s\"。\n访问被拒绝。"
    ::msgcat::mcset zh_cn "Choose Directory" "选择文件夹"
    ::msgcat::mcset zh_cn "Cl&ear" "清&除"
    ::msgcat::mcset zh_cn "&Clear Console" "&清除终端"
    ::msgcat::mcset zh_cn "Color" "颜色"
    ::msgcat::mcset zh_cn "Console" "终端"
    ::msgcat::mcset zh_cn "&Copy" "&复制"
    ::msgcat::mcset zh_cn "Cu&t" "剪&切"
    ::msgcat::mcset zh_cn "&Delete" "&删除"
    ::msgcat::mcset zh_cn "Details >>" "详细信息 >>"
    ::msgcat::mcset zh_cn "Directory \"%1\$s\" does not exist." "目录 \"%1\$s\" 不存在。"
    ::msgcat::mcset zh_cn "&Directory:" "&目录:"
    ::msgcat::mcset zh_cn "&Edit" "&编辑"
    ::msgcat::mcset zh_cn "Effects" "效果"
    ::msgcat::mcset zh_cn "Error: %1\$s" "错误: %1\$s"
    ::msgcat::mcset zh_cn "E&xit" "退&出"
    ::msgcat::mcset zh_cn "&File" "&文件"
    ::msgcat::mcset zh_cn "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "文件 \"%1\$s\" 已经存在。\n您想要覆盖它吗?"
    ::msgcat::mcset zh_cn "File \"%1\$s\" already exists.\n\n" "文件 \"%1\$s\" 已经存在。\n\n"
    ::msgcat::mcset zh_cn "File \"%1\$s\" does not exist." "文件 \"%1\$s\" 不存在。"
    ::msgcat::mcset zh_cn "File &name:" "文件&名:"
    ::msgcat::mcset zh_cn "File &names:" "文件&名:"
    ::msgcat::mcset zh_cn "Files of &type:" "文件&类型:"
    ::msgcat::mcset zh_cn "Fi&les:" "文&件:"
    ::msgcat::mcset zh_cn "&Filter" "&过滤"
    ::msgcat::mcset zh_cn "Fil&ter:" "过&滤:"
    ::msgcat::mcset zh_cn "Font" "字体"
    ::msgcat::mcset zh_cn "&Font:" "&字体:"
    ::msgcat::mcset zh_cn "Font st&yle:" "字体&样式:"
    ::msgcat::mcset zh_cn "&Green" "&绿色"
    ::msgcat::mcset zh_cn "&Help" "&帮助"
    ::msgcat::mcset zh_cn "Hi" "你好"
    ::msgcat::mcset zh_cn "&Hide Console" "&隐藏终端"
    ::msgcat::mcset zh_cn "&Ignore" "&忽略"
    ::msgcat::mcset zh_cn "Invalid file name \"%1\$s\"." "无效的文件名 \"%1\$s\"。"
    ::msgcat::mcset zh_cn "Italic" "斜体"
    ::msgcat::mcset zh_cn "Log Files" "日志文件"
    ::msgcat::mcset zh_cn "&No" "&否"
    ::msgcat::mcset zh_cn "&OK" "&确定"
    ::msgcat::mcset zh_cn "OK" "确定"
    ::msgcat::mcset zh_cn "Ok" "确定"
    ::msgcat::mcset zh_cn "Open" "打开"
    ::msgcat::mcset zh_cn "&Open" "&打开"
    ::msgcat::mcset zh_cn "Open Multiple Files" "打开多个文件"
    ::msgcat::mcset zh_cn "P&aste" "粘&贴"
    ::msgcat::mcset zh_cn "&Quit" "&退出"
    ::msgcat::mcset zh_cn "&Red" "红色"
    ::msgcat::mcset zh_cn "Regular" "规则"
    ::msgcat::mcset zh_cn "Replace existing file?" "替换已有文件?"
    ::msgcat::mcset zh_cn "&Retry" "&重试"
    ::msgcat::mcset zh_cn "Sample" "样式"
    ::msgcat::mcset zh_cn "&Save" "&保存"
    ::msgcat::mcset zh_cn "Save As" "另存为"
    ::msgcat::mcset zh_cn "Save To Log" "保存到日志"
    ::msgcat::mcset zh_cn "Select Log File" "选择日志文件"
    ::msgcat::mcset zh_cn "Select a file to source" "选择一个源文件"
    ::msgcat::mcset zh_cn "&Selection:" "&选择:"
    ::msgcat::mcset zh_cn "&Size:" "&大小:"
    ::msgcat::mcset zh_cn "Show &Hidden Directories" "显示&隐藏目录"
    ::msgcat::mcset zh_cn "Show &Hidden Files and Directories" "显示&隐藏文件和目录"
    ::msgcat::mcset zh_cn "Skip Messages" "跳过信息"
    ::msgcat::mcset zh_cn "&Source..." "&来源……"
    ::msgcat::mcset zh_cn "Stri&keout" "删&除线"
    ::msgcat::mcset zh_cn "Tcl Scripts" "Tcl脚本"
    ::msgcat::mcset zh_cn "Tcl for Windows" "适用于Windows的Tcl"
    ::msgcat::mcset zh_cn "Text Files" "文本文档"
    ::msgcat::mcset zh_cn "&Underline" "&下划线"
    ::msgcat::mcset zh_cn "&Yes" "&确定"
    ::msgcat::mcset zh_cn "abort" "中止"
    ::msgcat::mcset zh_cn "blue" "蓝色"
    ::msgcat::mcset zh_cn "cancel" "取消"
    ::msgcat::mcset zh_cn "extension" "拓展"
    ::msgcat::mcset zh_cn "extensions" "拓展"
    ::msgcat::mcset zh_cn "green" "绿色"
    ::msgcat::mcset zh_cn "ignore" "忽略"
    ::msgcat::mcset zh_cn "ok" "确定"
    ::msgcat::mcset zh_cn "red" "红色"
    ::msgcat::mcset zh_cn "retry" "重试"
    ::msgcat::mcset zh_cn "yes" "确认"
}

#Kevin Walzer通过微软翻译对打印内容进行本地化    localization of print terms by Kevin Walzer via Microsoft Translator
namespace eval ::tk {
    ::msgcat::mcset  zh_cn "Print" "输出"
    ::msgcat::mcset  zh_cn "Printer" "输出器"
    ::msgcat::mcset  zh_cn "Letter " "信 "
    ::msgcat::mcset  zh_cn "Legal " "合法的 "
    ::msgcat::mcset  zh_cn "A4" "A4"
    ::msgcat::mcset  zh_cn "Grayscale" "灰度"
    ::msgcat::mcset  zh_cn "RGB" "RGB"
    ::msgcat::mcset  zh_cn "Options" "设置"
    ::msgcat::mcset  zh_cn "Copies" "复制"
    ::msgcat::mcset  zh_cn "Paper" "纸"
    ::msgcat::mcset  zh_cn "Scale" "规模"
    ::msgcat::mcset  zh_cn "Orientation" "方向"
    ::msgcat::mcset  zh_cn "Portrait" "竖向"
    ::msgcat::mcset  zh_cn "Landscape" "横向"
    ::msgcat::mcset  zh_cn "Output" "输出"
}

Deleted library/obsolete.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
# obsolete.tcl --
#
# This file contains obsolete procedures that people really shouldn't
# be using anymore, but which are kept around for backward compatibility.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# The procedures below are here strictly for backward compatibility with
# Tk version 3.6 and earlier.  The procedures are no longer needed, so
# they are no-ops.  You should not use these procedures anymore, since
# they may be removed in some future release.

proc tk_menuBar args {}
proc tk_bindForTraversal args {}

# ::tk::classic::restore --
#
# Restore the pre-8.5 (Tk classic) look as the widget defaults for classic
# Tk widgets.
#
# The value following an 'option add' call is the new 8.5 value.
#
namespace eval ::tk::classic {
    # This may need to be adjusted for some window managers that are
    # more aggressive with their own Xdefaults (like KDE and CDE)
    variable prio "widgetDefault"
}

proc ::tk::classic::restore {args} {
    # Restore classic (8.4) look to classic Tk widgets
    variable prio

    if {[llength $args]} {
	foreach what $args {
	    ::tk::classic::restore_$what
	}
    } else {
	foreach cmd [info procs restore_*] {
	    $cmd
	}
    }
}

proc ::tk::classic::restore_font {args} {
    # Many widgets were adjusted from hard-coded defaults to using the
    # TIP#145 fonts defined in fonts.tcl (eg TkDefaultFont, TkFixedFont, ...)
    # For restoring compatibility, we only correct size and weighting changes,
    # as the fonts themselves remained mostly the same.
    if {[tk windowingsystem] eq "x11"} {
	font configure TkDefaultFont -weight bold ; # normal
	font configure TkFixedFont -size -12 ; # -10
    }
    # Add these with prio 21 to override value in dialog/msgbox.tcl
    if {[tk windowingsystem] eq "aqua"} {
	option add *Dialog.msg.font system 21; # TkCaptionFont
	option add *Dialog.dtl.font system 21; # TkCaptionFont
	option add *ErrorDialog*Label.font system 21; # TkCaptionFont
    } else {
	option add *Dialog.msg.font {Times 12} 21; # TkCaptionFont
	option add *Dialog.dtl.font {Times 10} 21; # TkCaptionFont
	option add *ErrorDialog*Label.font {Times -18} 21; # TkCaptionFont
    }
}

proc ::tk::classic::restore_button {args} {
    variable prio
    if {[tk windowingsystem] eq "x11"} {
	foreach cls {Button Radiobutton Checkbutton} {
	    option add *$cls.borderWidth 2 $prio; # 1
	}
    }
}

proc ::tk::classic::restore_entry {args} {
    variable prio
    # Entry and Spinbox share core defaults
    foreach cls {Entry Spinbox} {
	if {[tk windowingsystem] ne "aqua"} {
	    option add *$cls.borderWidth	2 $prio; # 1
	}
	if {[tk windowingsystem] eq "x11"} {
	    option add *$cls.background		"#d9d9d9" $prio; # "white"
	    option add *$cls.selectBorderWidth	1 $prio; # 0
	}
    }
}

proc ::tk::classic::restore_listbox {args} {
    variable prio
    if {[tk windowingsystem] ne "win32"} {
	option add *Listbox.background		"#d9d9d9" $prio; # "white"
	option add *Listbox.activeStyle		"underline" $prio; # "dotbox"
    }
    if {[tk windowingsystem] ne "aqua"} {
	option add *Listbox.borderWidth		2 $prio; # 1
    }
    if {[tk windowingsystem] eq "x11"} {
	option add *Listbox.selectBorderWidth	1 $prio; # 0
    }
    # Remove focus into Listbox added for 8.5
    bind Listbox <Button-1> {
	if {[winfo exists %W]} {
	    tk::ListboxBeginSelect %W [%W index @%x,%y]
	}
    }
}

proc ::tk::classic::restore_menu {args} {
    variable prio
    if {[tk windowingsystem] eq "x11"} {
	option add *Menu.activeBorderWidth	2 $prio; # 1
	option add *Menu.borderWidth		2 $prio; # 1
        option add *Menu.clickToFocus		true $prio
        option add *Menu.useMotifHelp		true $prio
    }
    if {[tk windowingsystem] ne "aqua"} {
	option add *Menu.font		"TkDefaultFont" $prio; # "TkMenuFont"
    }
}

proc ::tk::classic::restore_menubutton {args} {
    variable prio
    option add *Menubutton.borderWidth	2 $prio; # 1
}

proc ::tk::classic::restore_message {args} {
    variable prio
    option add *Message.borderWidth	2 $prio; # 1
}

proc ::tk::classic::restore_panedwindow {args} {
    variable prio
    option add *Panedwindow.borderWidth	2 $prio; # 1
    option add *Panedwindow.sashWidth	2 $prio; # 3
    option add *Panedwindow.sashPad	2 $prio; # 0
    option add *Panedwindow.sashRelief	raised $prio; # flat
    option add *Panedwindow.opaqueResize	0 $prio; # 1
    if {[tk windowingsystem] ne "win32"} {
	option add *Panedwindow.showHandle	1 $prio; # 0
    }
}

proc ::tk::classic::restore_scale {args} {
    variable prio
    option add *Scale.borderWidth	2 $prio; # 1
    if {[tk windowingsystem] eq "x11"} {
	option add *Scale.troughColor	"#c3c3c3" $prio; # "#b3b3b3"
    }
}

proc ::tk::classic::restore_scrollbar {args} {
    variable prio
    if {[tk windowingsystem] eq "x11"} {
	option add *Scrollbar.borderWidth	2 $prio; # 1
	option add *Scrollbar.highlightThickness 1 $prio; # 0
	option add *Scrollbar.width		15 $prio; # 11
	option add *Scrollbar.troughColor	"#c3c3c3" $prio; # "#b3b3b3"
    }
}

proc ::tk::classic::restore_text {args} {
    variable prio
    if {[tk windowingsystem] ne "aqua"} {
	option add *Text.borderWidth	2 $prio; # 1
    }
    if {[tk windowingsystem] eq "win32"} {
	option add *Text.font		"TkDefaultFont" $prio; # "TkFixedFont"
    }
    if {[tk windowingsystem] eq "x11"} {
	option add *Text.background		"#d9d9d9" $prio; # white
	option add *Text.selectBorderWidth	1 $prio; # 0
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































Changes to library/optMenu.tcl.

33
34
35
36
37
38
39
40
41
42
43
    }
    menubutton $w -textvariable $varName -indicatoron 1 -menu $w.menu \
	    -relief raised -highlightthickness 1 -anchor c \
	    -direction flush
    menu $w.menu -tearoff 0
    $w.menu add radiobutton -label $firstValue -variable $varName
    foreach i $args {
    	$w.menu add radiobutton -label $i -variable $varName
    }
    return $w.menu
}







|



33
34
35
36
37
38
39
40
41
42
43
    }
    menubutton $w -textvariable $varName -indicatoron 1 -menu $w.menu \
	    -relief raised -highlightthickness 1 -anchor c \
	    -direction flush
    menu $w.menu -tearoff 0
    $w.menu add radiobutton -label $firstValue -variable $varName
    foreach i $args {
	$w.menu add radiobutton -label $i -variable $varName
    }
    return $w.menu
}

Changes to library/palette.tcl.

66
67
68
69
70
71
72














73
74
75
76
77
78
79
	set new(disabledForeground) [format #%02x%02x%02x \
		[expr {(3*$bg_r + $fg_r)/1024}] \
		[expr {(3*$bg_g + $fg_g)/1024}] \
		[expr {(3*$bg_b + $fg_b)/1024}]]
    }
    if {![info exists new(highlightBackground)]} {
	set new(highlightBackground) $new(background)














    }
    if {![info exists new(activeBackground)]} {
	# Pick a default active background that islighter than the
	# normal background.  To do this, round each color component
	# up by 15% or 1/3 of the way to full white, whichever is
	# greater.








>
>
>
>
>
>
>
>
>
>
>
>
>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
	set new(disabledForeground) [format #%02x%02x%02x \
		[expr {(3*$bg_r + $fg_r)/1024}] \
		[expr {(3*$bg_g + $fg_g)/1024}] \
		[expr {(3*$bg_b + $fg_b)/1024}]]
    }
    if {![info exists new(highlightBackground)]} {
	set new(highlightBackground) $new(background)
    }
    # 'buttonBackground' is the background color of the buttons in
    # the spinbox widget.
    if {![info exists new(buttonBackground)]} {
	set new(buttonBackground) $new(background)
    }
    # 'selectColor' is the background of check & radio buttons.
    if {![info exists new(selectColor)]} {
	foreach {r g b} $bg {break}
	if {$r+1.5*$g+0.5*$b > 100000} {
	    set new(selectColor) white
	} else {
	    set new(selectColor) black
	}
    }
    if {![info exists new(activeBackground)]} {
	# Pick a default active background that islighter than the
	# normal background.  To do this, round each color component
	# up by 15% or 1/3 of the way to full white, whichever is
	# greater.

135
136
137
138
139
140
141




















142
143
144
145
146
147
148
	option add *$option $new($option) widgetDefault
    }

    # Save the options in the variable ::tk::Palette, for use the
    # next time we change the options.

    array set ::tk::Palette [array get new]




















}

# ::tk::RecolorTree --
# This procedure changes the colors in a window and all of its
# descendants, according to information provided by the colors
# argument. This looks at the defaults provided by the option
# database, if it exists, and if not, then it looks at the default







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
	option add *$option $new($option) widgetDefault
    }

    # Save the options in the variable ::tk::Palette, for use the
    # next time we change the options.

    array set ::tk::Palette [array get new]

    if {[tk windowingsystem] ne "x11" || [ttk::style theme use] ne "default"} {
	return
    }

    # Update the 'default' ttk theme with the new palette,
    # and then set 'default' as the current ttk theme,
    # in order to apply the new palette to the ttk widgets.

    foreach option [array names new] {
	if {[info exists ttk::theme::default::colorOptionLookup($option)]} {
	    foreach colorName $ttk::theme::default::colorOptionLookup($option) {
		set ttk::theme::default::colors($colorName) $new($option)
	    }
	}
    }
    ttk::theme::default::reconfigureDefaultTheme
    ttk::setTheme default

    return
}

# ::tk::RecolorTree --
# This procedure changes the colors in a window and all of its
# descendants, according to information provided by the colors
# argument. This looks at the defaults provided by the option
# database, if it exists, and if not, then it looks at the default

Added library/print.tcl.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
# print.tcl --

# This file defines the 'tk print' command for printing of the canvas
# widget and text on X11, Windows, and macOS. It implements an abstraction
# layer that presents a consistent API across the three platforms.

# Copyright © 2009 Michael I. Schwartz.
# Copyright © 2021 Kevin Walzer/WordTech Communications LLC.
# Copyright © 2021 Harald Oehlmann, Elmicron GmbH
# Copyright © 2022 Emiliano Gavilan
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

namespace eval ::tk::print {
    namespace import -force ::tk::msgcat::*

    # makeTempFile:
    #    Create a temporary file and populate its contents
    # Arguments:
    #	 filename - base of the name of the file to create
    #    contents - what to put in the file; defaults to empty
    # Returns:
    #    Full filename for created file
    #
    proc makeTempFile {filename {contents ""}} {
	set dumpfile [file join /tmp rawprint.txt]
	set tmpfile [file join /tmp $filename]
	set f [open $dumpfile w]
	try {
	    puts -nonewline $f $contents
	} finally {
	    close $f
	    if {[file extension $filename] == ".ps"} {
		#don't apply formatting to PostScript
		file rename -force $dumpfile $tmpfile
	    } else {
	    #Make text fixed width for improved printed output
		exec fmt -w 75 $dumpfile > $tmpfile
	    }
	    return $tmpfile
	}
    }

    if {[tk windowingsystem] eq "win32"} {
	variable printer_name
	variable copies
	variable dpi_x
	variable dpi_y
	variable paper_width
	variable paper_height
	variable margin_left
	variable margin_top
	variable printargs
	array set printargs {}

	# Multiple utility procedures for printing text based on the
	# C printer primitives.

	# _set_dc:
	# Select printer and set device context and other parameters
	# for print job.
	#
	proc _set_dc {} {
	    variable printargs
	    variable printer_name
	    variable paper_width
	    variable paper_height
	    variable dpi_x
	    variable dpi_y
	    variable copies

	    #First, we select the printer.
	    _selectprinter

	    #Next, set values. Some are taken from the printer,
	    #some are sane defaults.

        if {[info exists printer_name] && $printer_name ne ""} {
	    set printargs(hDC) $printer_name
	    set printargs(pw) $paper_width
	    set printargs(pl) $paper_height
	    set printargs(lm) 1000
	    set printargs(tm) 1000
	    set printargs(rm) 1000
	    set printargs(bm) 1000
	    set printargs(resx) $dpi_x
	    set printargs(resy) $dpi_y
	    set printargs(copies) $copies
	    set printargs(resolution) [list $dpi_x $dpi_y]
		}
	}

	# _print_data
	# This function prints multiple-page files, using a line-oriented
	# function, taking advantage of knowing the character widths.
	# Arguments:
	# data -       Text data for printing
	# breaklines - If non-zero, keep newlines in the string as
	#              newlines in the output.
	# font -       Font for printing
	proc _print_data {data {breaklines 1} {font ""}} {
	    variable printargs
	    variable printer_name

	    _set_dc

	    if {![info exists printer_name]} {
		return
	    }

	    if {$font eq ""} {
		_gdi characters $printargs(hDC) -array printcharwid
	    } else {
		_gdi characters $printargs(hDC) -font $font -array printcharwid
	    }
	    set pagewid [expr {($printargs(pw) - $printargs(rm) ) / 1000 * $printargs(resx)}]
	    set pagehgt [expr {($printargs(pl) - $printargs(bm) ) / 1000 * $printargs(resy)}]
	    set totallen [string length $data]
	    set curlen 0
	    set curhgt [expr {$printargs(tm) * $printargs(resy) / 1000}]

	    _opendoc
	    _openpage

	    while {$curlen < $totallen} {
		set linestring [string range $data $curlen end]
		if {$breaklines} {
		    set endind [string first "\n" $linestring]
		    if {$endind >= 0} {
			set linestring [string range $linestring 0 $endind]
			# handle blank lines....
			if {$linestring eq ""} {
			    set linestring " "
			}
		    }
		}

		set result [_print_page_nextline $linestring \
				printcharwid printargs $curhgt $font]
		incr curlen [lindex $result 0]
		incr curhgt [lindex $result 1]
		if {$curhgt + [lindex $result 1] > $pagehgt} {
		    _closepage
		    _openpage
		    set curhgt [expr {$printargs(tm) * $printargs(resy) / 1000}]
		}
	    }

	    _closepage
	    _closedoc
	}

	# _print_file
	# This function prints multiple-page files
	# It will either break lines or just let them run over the
	# margins (and thus truncate).
	# The font argument is JUST the font name, not any additional
	# arguments.
	# Arguments:
	#   filename -   File to open for printing
	#   breaklines - 1 to break lines as done on input, 0 to ignore newlines
	#   font -       Optional arguments to supply to the text command
	proc _print_file {filename {breaklines 1} {font ""}} {
	    set fn [open $filename r]
	    set data [read $fn]
	    close $fn
	    _print_data $data $breaklines $font
	}

	# _print_page_nextline
	# Returns the pair "chars y"
	# where chars is the number of characters printed on the line
	# and y is the height of the line printed
	# Arguments:
	#   string -         Data to print
	#   pdata -         Array of values for printer characteristics
	#   cdata -         Array of values for character widths
	#   y -              Y value to begin printing at
	#   font -           if non-empty specifies a font to draw the line in
	proc _print_page_nextline {string carray parray y font} {
	    upvar #0 $carray charwidths
	    upvar #0 $parray printargs

	    variable printargs

	    set endindex 0
	    set totwidth 0
	    set maxwidth [expr {
		(($printargs(pw) - $printargs(rm)) / 1000) * $printargs(resx)
	    }]
	    set maxstring [string length $string]
	    set lm [expr {$printargs(lm) * $printargs(resx) / 1000}]

	    for {set i 0} {($i < $maxstring) && ($totwidth < $maxwidth)} {incr i} {
		incr totwidth $charwidths([string index $string $i])
		# set width($i) $totwidth
	    }

	    set endindex $i
	    set startindex $endindex

	    if {$i < $maxstring} {
		# In this case, the whole data string is not used up, and we
		# wish to break on a word. Since we have all the partial
		# widths calculated, this should be easy.

		set endindex [expr {[string wordstart $string $endindex] - 1}]
		set startindex [expr {$endindex + 1}]

		# If the line is just too long (no word breaks), print as much
		# as you can....
		if {$endindex <= 1} {
		    set endindex $i
		    set startindex $i
		}
	    }

	    set txt [string trim [string range $string 0 $endindex] "\r\n"]
	    if {$font ne ""} {
		set result [_gdi text $printargs(hDC) $lm $y \
				 -anchor nw -justify left \
				 -text $txt -font $font]
	    } else {
		set result [_gdi text $printargs(hDC) $lm $y \
				 -anchor nw -justify left -text $txt]
	    }
	    return "$startindex $result"
	}

	# These procedures read in the canvas widget, and write all of
	# its contents out to the Windows printer.

	variable option
	variable vtgPrint

	proc _init_print_canvas {} {
	    variable option
	    variable vtgPrint
	    variable printargs

	    set vtgPrint(printer.bg) white
	}

	proc _is_win {} {
	    variable printargs

	    return [info exist tk_patchLevel]
	}

	# _print_widget
	# Main procedure for printing a widget.  Currently supports
	# canvas widgets.  Handles opening and closing of printer.
	# Arguments:
	#   wid -              The widget to be printed.
	#   printer -          Flag whether to use the default printer.
	#   name  -            App name to pass to printer.

	proc _print_widget {wid {printer default} {name "Tk Print Output"}} {
	    variable printargs
	    variable printer_name

	    _set_dc

	    if {![info exists printer_name]} {
		return
	    }

	    _opendoc
	    _openpage

	    # Here is where any scaling/gdi mapping should take place
	    # For now, scale so the dimensions of the window are sized to the
	    # width of the page. Scale evenly.

	    # For normal windows, this may be fine--but for a canvas, one
	    # wants the canvas dimensions, and not the WINDOW dimensions.
	    if {[winfo class $wid] eq "Canvas"} {
		set sc [$wid cget -scrollregion]
		# if there is no scrollregion, use width and height.
		if {$sc eq ""} {
		    set window_x [$wid cget -width]
		    set window_y [$wid cget -height]
		} else {
		    set window_x [lindex $sc 2]
		    set window_y [lindex $sc 3]
		}
	    } else {
		set window_x [winfo width $wid]
		set window_y [winfo height $wid]
	    }

	    set printer_x [expr {
		( $printargs(pw) - $printargs(lm) - $printargs(rm) ) *
		$printargs(resx)  / 1000.0
	    }]
	    set printer_y [expr {
		( $printargs(pl) - $printargs(tm) - $printargs(bm) ) *
		$printargs(resy) / 1000.0
	    }]
	    set factor_x [expr {$window_x / $printer_x}]
	    set factor_y [expr {$window_y / $printer_y}]

	    if {$factor_x < $factor_y} {
		set lo $window_y
		set ph $printer_y
	    } else {
		set lo $window_x
		set ph $printer_x
	    }

	    _gdi map $printargs(hDC) -logical $lo -physical $ph \
		-offset $printargs(resolution)

	    # Handling of canvas widgets.
	    switch [winfo class $wid] {
		Canvas {
		    _print_canvas $printargs(hDC) $wid
		}
		default {
		    puts "Can't print items of type [winfo class $wid]. No handler registered"
		}
	    }

	    # End printing process.
	    _closepage
	    _closedoc
	}

	#  _print_canvas
	# Main procedure for writing canvas widget items to printer.
	# Arguments:
	#    hdc -              The printer handle.
	#    cw  -              The canvas widget.
	proc _print_canvas {hdc cw} {
	    variable  vtgPrint
	    variable printargs

	    # Get information about page being printed to
	    # print_canvas.CalcSizing $cw
	    set vtgPrint(canvas.bg) [string tolower [$cw cget -background]]

	    # Re-write each widget from cw to printer
	    foreach id [$cw find all] {
		set type [$cw type $id]
		if {[info commands _print_canvas.$type] eq "_print_canvas.$type"} {
		    _print_canvas.[$cw type $id] $printargs(hDC) $cw $id
		} else {
		    puts "Omitting canvas item of type $type since there is no handler registered for it"
		}
	    }
	}

	# These procedures support the various canvas item types, reading the
	# information about the item on the real canvas and then writing a
	# similar item to the printer.

	# _print_canvas.line
	# Description:
	#   Prints a line item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.line {hdc cw id} {
	    variable vtgPrint
	    variable printargs

	    set color [_print_canvas.TransColor [$cw itemcget $id -fill]]
	    if {[string match $vtgPrint(printer.bg) $color]} {
		return
	    }

	    set coords  [$cw coords $id]
	    set wdth    [$cw itemcget $id -width]
	    set arrow   [$cw itemcget $id -arrow]
	    set arwshp  [$cw itemcget $id -arrowshape]
	    set dash    [$cw itemcget $id -dash]
	    set smooth  [$cw itemcget $id -smooth]
	    set splinesteps [$cw itemcget $id -splinesteps]

	    set cmdargs {}

	    if {$wdth > 1} {
		lappend cmdargs -width $wdth
	    }
	    if {$dash ne ""} {
		lappend cmdargs -dash $dash
	    }
	    if {$smooth ne ""} {
		lappend cmdargs -smooth $smooth
	    }
	    if {$splinesteps ne ""} {
		lappend cmdargs -splinesteps $splinesteps
	    }

	    set result [_gdi line $hdc {*}$coords \
			    -fill $color -arrow $arrow -arrowshape $arwshp \
			    {*}$cmdargs]
	    if {$result ne ""} {
		puts $result
	    }
	}

	# _print_canvas.arc
	#   Prints a arc item.
	# Args:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.arc {hdc cw id} {
	    variable vtgPrint
	    variable printargs

	    set color [_print_canvas.TransColor [$cw itemcget $id -outline]]
	    if {[string match $vtgPrint(printer.bg) $color]} {
		return
	    }
	    set coords  [$cw coords $id]
	    set wdth    [$cw itemcget $id -width]
	    set style   [$cw itemcget $id -style]
	    set start   [$cw itemcget $id -start]
	    set extent  [$cw itemcget $id -extent]
	    set fill    [$cw itemcget $id -fill]

	    set cmdargs {}
	    if {$wdth > 1} {
		lappend cmdargs -width $wdth
	    }
	    if {$fill ne ""} {
		lappend cmdargs -fill $fill
	    }

	    _gdi arc $hdc {*}$coords \
		-outline $color -style $style -start $start -extent $extent \
		{*}$cmdargs
	}

	# _print_canvas.polygon
	#   Prints a polygon item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.polygon {hdc cw id} {
	    variable vtgPrint
	    variable printargs

	    set fcolor [_print_canvas.TransColor [$cw itemcget $id -fill]]
	    if {$fcolor eq ""} {
		set fcolor $vtgPrint(printer.bg)
	    }
	    set ocolor [_print_canvas.TransColor [$cw itemcget $id -outline]]
	    if {$ocolor eq ""} {
		set ocolor $vtgPrint(printer.bg)
	    }
	    set coords  [$cw coords $id]
	    set wdth [$cw itemcget $id -width]
	    set smooth  [$cw itemcget $id -smooth]
	    set splinesteps [$cw itemcget $id -splinesteps]

	    set cmdargs {}
	    if {$smooth ne ""} {
		lappend cmdargs -smooth $smooth
	    }
	    if {$splinesteps ne ""} {
		lappend cmdargs -splinesteps $splinesteps
	    }

	    _gdi polygon $hdc {*}$coords \
		-width $wdth -fill $fcolor -outline $ocolor {*}$cmdargs
	}

	# _print_canvas.oval
	#   Prints an oval item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.oval {hdc cw id} {
	    variable vtgPrint

	    set fcolor [_print_canvas.TransColor [$cw itemcget $id -fill]]
	    if {$fcolor eq ""} {
		set fcolor $vtgPrint(printer.bg)
	    }
	    set ocolor [_print_canvas.TransColor [$cw itemcget $id -outline]]
	    if {$ocolor eq ""} {
		set ocolor $vtgPrint(printer.bg)
	    }
	    set coords  [$cw coords $id]
	    set wdth [$cw itemcget $id -width]

	    _gdi oval $hdc {*}$coords \
		-width $wdth -fill $fcolor -outline $ocolor
	}

	# _print_canvas.rectangle
	#   Prints a rectangle item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.rectangle {hdc cw id} {
	    variable vtgPrint

	    set fcolor [_print_canvas.TransColor [$cw itemcget $id -fill]]
	    if {$fcolor eq ""} {
		set fcolor $vtgPrint(printer.bg)
	    }
	    set ocolor [_print_canvas.TransColor [$cw itemcget $id -outline]]
	    if {$ocolor eq ""} {
		set ocolor $vtgPrint(printer.bg)
	    }
	    set coords  [$cw coords $id]
	    set wdth [$cw itemcget $id -width]

	    _gdi rectangle $hdc {*}$coords \
		-width $wdth -fill $fcolor -outline $ocolor
	}

	# _print_canvas.text
	#   Prints a text item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.text {hdc cw id} {
	    variable vtgPrint
	    variable printargs

	    set color [_print_canvas.TransColor [$cw itemcget $id -fill]]
	    #    if {"white" eq [string tolower $color]} {return}
	    #    set color black
	    set txt [$cw itemcget $id -text]
	    if {$txt eq ""} {
		return
	    }
	    set coords [$cw coords $id]
	    set anchr [$cw itemcget $id -anchor]

	    set bbox [$cw bbox $id]
	    set wdth [expr {[lindex $bbox 2] - [lindex $bbox 0]}]

	    set just [$cw itemcget $id -justify]

	    # Get the real canvas font info and create a compatible font,
	    # suitable for printer name extraction.
	    set font [font create {*}[font actual [$cw itemcget $id -font]]]

	    # Just get the name and family, or some of the _gdi commands will
	    # fail.
	    set font [list [font configure $font -family] \
			  -[font configure $font -size]]

	    _gdi text $hdc {*}$coords \
		-fill $color -text $txt -font $font \
		-anchor $anchr -width $wdth -justify $just
	}

	# _print_canvas.image
	# Prints an image item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.image {hdc cw id} {
	    # First, we have to get the image name.
	    set imagename [$cw itemcget $id -image]

	    # Now we get the size.
	    set wid [image width $imagename]
	    set hgt [image height $imagename]

	    # Next, we get the location and anchor
	    set anchor [$cw itemcget $id -anchor]
	    set coords [$cw coords $id]

	    _gdi photo $hdc -destination $coords -photo $imagename
	}

	# _print_canvas.bitmap
	#   Prints a bitmap item.
	# Arguments:
	#   hdc -              The printer handle.
	#   cw  -              The canvas widget.
	#   id  -              The id of the canvas item.
	proc _print_canvas.bitmap {hdc cw id} {
	    variable option
	    variable vtgPrint

	    # First, we have to get the bitmap name.
	    set imagename [$cw itemcget $id -image]

	    # Now we get the size.
	    set wid [image width $imagename]
	    set hgt [image height $imagename]

	    #Next, we get the location and anchor.
	    set anchor [$cw itemcget $id -anchor]
	    set coords [$cw coords $id]

	    # Since the GDI commands don't yet support images and bitmaps,
	    # and since this represents a rendered bitmap, we CAN use
	    # copybits IF we create a new temporary toplevel to hold the beast.
	    # If this is too ugly, change the option!

	    if {[info exist option(use_copybits)]} {
		set firstcase $option(use_copybits)
	    } else {
		set firstcase 0
	    }
	    if {$firstcase > 0} {
		set tl [toplevel .tmptop[expr {int( rand() * 65535 )}] \
			    -height $hgt -width $wid \
			    -background $vtgPrint(canvas.bg)]
		canvas $tl.canvas -width $wid -height $hgt
		$tl.canvas create image 0 0 -image $imagename -anchor nw
		pack $tl.canvas -side left -expand false -fill none
		tkwait visibility $tl.canvas
		update
		set srccoords [list 0 0 [expr {$wid - 1}] [expr {$hgt - 1}]]
		set dstcoords [list [lindex $coords 0] [lindex $coords 1] [expr {$wid - 1}] [expr {$hgt - 1}]]
		_gdi copybits $hdc -window $tl -client \
		    -source $srccoords -destination $dstcoords
		destroy $tl
	    } else {
		_gdi bitmap $hdc {*}$coords \
		    -anchor $anchor -bitmap $imagename
	    }
	}

	# These procedures transform attribute setting from the real
	# canvas to the appropriate setting for printing to paper.

	# _print_canvas.TransColor
	#   Does the actual transformation of colors from the
	#   canvas widget to paper.
	# Arguments:
	#   color -            The color value to be transformed.
	proc _print_canvas.TransColor {color} {
	    variable vtgPrint
	    variable printargs

	    switch [string toupper $color] {
		$vtgPrint(canvas.bg)       {return $vtgPrint(printer.bg)}
	    }
	    return $color
	}

	# Initialize all the variables once.
	_init_print_canvas
    }
    #end win32 procedures

    #begin X11 procedures

    # X11 procedures wrap standard Unix shell commands such as lp/lpr and
    # lpstat for printing. Some output configuration that on other platforms
    # is managed through the printer driver/dialog is configured through the
    # canvas postscript command.

    if {[tk windowingsystem] eq "x11"} {
	variable printcmd {}

	# print options
	variable optlist
	set optlist(printer) {}
	set optlist(paper)   [list [mc "Letter"] [mc "Legal"] [mc "A4"]]
	set optlist(orient)  [list [mc "Portrait"] [mc "Landscape"]]
	set optlist(color)   [list [mc "Grayscale"] [mc "RGB"]]
	set optlist(zoom)    {100 90 80 70 60 50 40 30 20 10}

	# selected options
	variable sel
	array set sel {
	    printer {}
	    copies  {}
	    paper   {}
	    orient  {}
	    color   {}
	    zoom    {}
	}

	# default values for dialog widgets
	option add *Printdialog*TLabel.anchor e
	option add *Printdialog*TMenubutton.Menu.tearOff 0
	option add *Printdialog*TMenubutton.width 12
	option add *Printdialog*TSpinbox.width 12
	# this is tempting to add, but it's better to leave it to user's taste
	# option add *Printdialog*Menu.background snow

	# returns the full qualified var name
	proc myvar {varname} {
	    set fqvar [uplevel 1 [list namespace which -variable $varname]]
	    # assert var existence
	    if {$fqvar eq ""} {
		return -code error "Wrong varname \"$varname\""
	    }
	    return $fqvar
	}

	# ttk version of [tk_optionMenu]
	# var should be a full qualified varname
	proc ttk_optionMenu {w var args} {
	    ttk::menubutton $w \
		-textvariable $var \
		-menu $w.menu
	    menu $w.menu
	    foreach option $args {
		$w.menu add command \
		    -label $option \
		    -command [list set $var $option]
	    }
	    # return the same value as tk_optionMenu
	    return $w.menu
	}

	# _setprintenv
	#  Set the print environtment - print command, and list of printers.
	#  Arguments:
	#    none.

	proc _setprintenv {} {
	    variable printcmd
	    variable optlist

	    #Test for existence of lpstat command to obtain list of printers. Return error
	    #if not found.

	    catch {exec lpstat -a} msg
	    set notfound "command not found"
	    if {[string first $notfound $msg] >= 0} {
		error "Unable to obtain list of printers. Please install the CUPS package \
		for your system."
		return
	    }
 	    set notfound "No destinations added"
 	    if {[string first $notfound $msg] != -1} {
		error "Please check or update your CUPS installation."
		return
	    }

	    # Select print command. We prefer lpr, but will fall back to lp if
	    # necessary.
	    if {[auto_execok lpr] ne ""} {
		set printcmd lpr
	    } else {
		set printcmd lp
	    }

	    #Build list of printers
	    set printers {}
	    set printdata [exec lpstat -a]
	    foreach item [split $printdata \n] {
		lappend printers [lindex [split $item] 0]
	    }
	    # filter out duplicates
	    set optlist(printer) [lsort -unique $printers]
	}

	# _print
	#  Main printer dialog. Select printer, set options, and
	#  fire print command.
	# Arguments:
	#  w - widget with contents to print.
	#

	proc _print {w} {
	# TODO: revise padding
	    variable optlist
	    variable sel

	    # should this be called with every invocaton?
	    _setprintenv
	    if {$sel(printer) eq "" && [llength $optlist(printer)] > 0} {
		set sel(printer) [lindex $optlist(printer) 0]
	    }

	    set p ._print
	    catch {destroy $p}

	    # copy the current values to a dialog's temorary variable
	    # this allow us to cancel the dialog discarding any changes
	    # made to the options
	    namespace eval dlg {variable sel}
	    array set dlg::sel [array get sel]

	    # The toplevel of our dialog
	    toplevel $p -class Printdialog
	    place [ttk::frame $p.background] -x 0 -y 0 -relwidth 1.0 -relheight 1.0
	    wm title $p [mc "Print"]
	    wm resizable $p 0 0
	    wm attributes $p -type dialog

	    # The printer to use
	    set pf [ttk::frame $p.printerf]
	    pack $pf -side top -fill x -expand no -padx 9p -pady 9p

	    ttk::label $pf.printerl -text "[mc "Printer"] :"
	    ttk::combobox $pf.printer \
		-textvariable [myvar dlg::sel](printer) \
		-state readonly \
		-values $optlist(printer)
	    pack $pf.printerl -side left -padx {0 4.5p}
	    pack $pf.printer  -side left

	    # Start of printing options
	    set of [ttk::labelframe $p.optionsframe -text [mc "Options"]]
	    pack $of -fill x -padx 9p -pady {0 9p} -ipadx 2p -ipady 2p

	    # COPIES
	    ttk::label $of.copiesl -text "[mc "Copies"] :"
	    ttk::spinbox $of.copies -from 1 -to 1000 \
		-textvariable [myvar dlg::sel](copies)
	    grid $of.copiesl $of.copies -sticky ew -padx 2p -pady 2p

	    # PAPER SIZE
	    ttk::label $of.paperl -text "[mc "Paper"] :"
	    ttk_optionMenu $of.paper [myvar dlg::sel](paper) {*}$optlist(paper)
	    grid $of.paperl $of.paper -sticky ew -padx 2p -pady 2p

	    # additional options for canvas output
	    if {[winfo class $w] eq "Canvas"} {
		# SCALE
		ttk::label $of.percentl -text "[mc "Scale"] :"
		ttk_optionMenu $of.percent [myvar dlg::sel](zoom) {*}$optlist(zoom)
		grid $of.percentl $of.percent -sticky ew -padx 2p -pady 2p

		# ORIENT
		ttk::label $of.orientl -text "[mc "Orientation"] :"
		ttk_optionMenu $of.orient [myvar dlg::sel](orient) {*}$optlist(orient)
		grid $of.orientl $of.orient -sticky ew -padx 2p -pady 2p

		# COLOR
		ttk::label $of.colorl -text "[mc "Output"] :"
		ttk_optionMenu $of.color [myvar dlg::sel](color) {*}$optlist(color)
		grid $of.colorl $of.color -sticky ew -padx 2p -pady 2p
	    }

	    # The buttons frame.
	    set bf [ttk::frame $p.buttonf]
	    pack $bf -fill x -expand no -side bottom -padx 9p -pady {0 9p}

	    ttk::button $bf.print -text [mc "Print"] \
		-command [namespace code [list _runprint $w $p]]
	    ttk::button $bf.cancel -text [mc "Cancel"] \
		-command [namespace code [list _cancel $p]]
	    pack $bf.print  -side right
	    pack $bf.cancel -side right -padx {0 4.5p}
	    #Center the window as a dialog.
	    ::tk::PlaceWindow $p
	}

	proc _cancel {p} {
	    namespace delete dlg
	    destroy $p
	}

	# _runprint -
	#   Execute the print command--print the file.
	# Arguments:
	#  w - widget with contents to print.
	#
	proc _runprint {w p} {
	    variable printcmd
	    variable sel

	    # copy the values back from the dialog
	    array set sel [array get dlg::sel]
	    namespace delete dlg

	    #First, generate print file.
	    if {[winfo class $w] eq "Text"} {
		set file [makeTempFile tk_text.txt [$w get 1.0 end]]
	    }

	    if {[winfo class $w] eq "Canvas"} {
		if {$sel(color) eq [mc "RGB"]} {
		    set colormode color
		} else {
		    set colormode gray
		}

		if {$sel(orient) eq [mc "Landscape"]} {
		    set willrotate "1"
		} else {
		    set willrotate "0"
		}

		#Scale based on size of widget, not size of paper.
		set printwidth [expr {$sel(zoom) / 100.00 * [winfo width $w]}]
		set file [makeTempFile tk_canvas.ps]
		$w postscript -file $file -colormode $colormode \
		    -rotate $willrotate -pagewidth $printwidth
	    }

	    #Build list of args to pass to print command.
	    set printargs {}
	    if {$printcmd eq "lpr"} {
		lappend printargs -P $sel(printer) -# $sel(copies)
	    } else {
		lappend printargs -d $sel(printer) -n $sel(copies)
	    }

	    # launch the job in the background
	    after 0 [list exec $printcmd {*}$printargs -o PageSize=$sel(paper) $file]
	    destroy $p
	}

	# Initialize with sane defaults.
	set sel(copies)  1
	set sel(paper)   [mc "A4"]
	set sel(orient)  [mc "Portrait"]
	set sel(color)   [mc "RGB"]
	set sel(zoom)    100
    }
    #end X11 procedures

    #begin macOS Aqua procedures
    if {[tk windowingsystem] eq "aqua"} {
	# makePDF -
	#   Convert a file to PDF
	# Arguments:
	#   inFilename -  file containing the data to convert; format is
	#                 autodetected.
	#   outFilename - base for filename to write to; conventionally should
	#                 have .pdf as suffix
	# Returns:
	#   The full pathname of the generated PDF.
	#
	proc makePDF {inFilename outFilename} {
	    set out [::tk::print::makeTempFile $outFilename]
	    try {
		exec /usr/sbin/cupsfilter $inFilename > $out
	    } trap NONE {msg} {
		# cupsfilter produces a lot of debugging output, which we
		# don't want.
		regsub -all -line {^(?:DEBUG|INFO):.*$} $msg "" msg
		set msg [string trimleft [regsub -all {\n+} $msg "\n"] "\n"]
		if {$msg ne ""} {
		    # Lines should be prefixed with WARN or ERROR now
		    puts $msg
		}
	    }
	    return $out
	}
    }
    #end macOS Aqua procedures

    namespace export canvas text
    namespace ensemble create
}

# tk print --
# This procedure prints the canvas and text widgets using platform-
# native API's.
#   Arguments:
#      w: Widget to print.
proc ::tk::print {w} {
    switch [winfo class $w],[tk windowingsystem] {
	"Canvas,win32" {
	    tailcall ::tk::print::_print_widget $w 0 "Tk Print Output"
	}
	"Canvas,x11" {
	    tailcall ::tk::print::_print $w
	}
	"Canvas,aqua" {
	    ::tk::print::_printcanvas $w
	    set printfile /tmp/tk_canvas.pdf
	    ::tk::print::_print $printfile
	}
	"Text,win32" {
	    tailcall ::tk::print::_print_data [$w get 1.0 end] 1 {Arial 12}
	}
	"Text,x11" {
	    tailcall ::tk::print::_print $w
	}
	"Text,aqua" {
	    set txtfile [::tk::print::makeTempFile tk_text.txt [$w get 1.0 end]]
	    try {
		set printfile [::tk::print::makePDF $txtfile [file join /tmp tk_text.pdf]]
		::tk::print::_print $printfile
	    } finally {
		file delete $txtfile
	    }
	}

	default {
	    return -code error -errorcode {TK PRINT CLASS_UNSUPPORTED} \
		"widgets of class [winfo class $w] are not supported on\
		this platform"
	}
    }
}

#Add this command to the tk command ensemble: tk print
#Thanks to Christian Gollwitzer for the guidance here
namespace ensemble configure tk -map \
    [dict merge [namespace ensemble configure tk -map] \
	 {print ::tk::print}]

return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to library/safetk.tcl.

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    # frame the button so it does not expand horizontally
    # but still have the default background instead of red one from the parent
    ttk::frame  $wc.fb -borderwidth 0
    ttk::button $wc.fb.b -text "Delete" \
	    -command [list ::safe::tkDelete $w $w $child]
    pack $wc.fb.b -side right -fill both
    pack $wc.fb -side right -fill both -expand 1
    pack $wc.l -side left -fill both -expand 1 -ipady 2
    pack $wc -side bottom -fill x

    # Container frame
    frame $w.c -container 1
    pack $w.c -fill both -expand 1

    # return both the toplevel window name and the id to use for embedding







|







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    # frame the button so it does not expand horizontally
    # but still have the default background instead of red one from the parent
    ttk::frame  $wc.fb -borderwidth 0
    ttk::button $wc.fb.b -text "Delete" \
	    -command [list ::safe::tkDelete $w $w $child]
    pack $wc.fb.b -side right -fill both
    pack $wc.fb -side right -fill both -expand 1
    pack $wc.l -side left -fill both -expand 1 -ipady 1.5p
    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

Changes to library/scale.tcl.

198
199
200
201
202
203
204

205












206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225


226
227
228

229
230
231
232
233

234
235
236
237
238
239
240
# repeat -	Whether and how to auto-repeat the action:  "noRepeat"
#		means don't auto-repeat, "initial" means this is the
#		first action in an auto-repeat sequence, and "again"
#		means this is the second repetition or later.

proc ::tk::ScaleIncrement {w dir big repeat} {
    variable ::tk::Priv

    if {![winfo exists $w]} return












    if {$big eq "big"} {
	set inc [$w cget -bigincrement]
	if {$inc == 0} {
	    set inc [expr {abs([$w cget -to] - [$w cget -from])/10.0}]
	}
	if {$inc < [$w cget -resolution]} {
	    set inc [$w cget -resolution]
	}
    } else {
	set inc [$w cget -resolution]
    }
    if {([$w cget -from] > [$w cget -to]) ^ ($dir eq "up")} {
        if {$inc > 0} {
            set inc [expr {-$inc}]
        }
    } else {
        if {$inc < 0} {
            set inc [expr {-$inc}]
        }
    }


    $w set [expr {[$w get] + $inc}]

    if {$repeat eq "again"} {

	set Priv(afterId) [after [$w cget -repeatinterval] \
		[list tk::ScaleIncrement $w $dir $big again]]
    } elseif {$repeat eq "initial"} {
	set delay [$w cget -repeatdelay]
	if {$delay > 0} {

	    set Priv(afterId) [after $delay \
		    [list tk::ScaleIncrement $w $dir $big again]]
	}
    }
}

# ::tk::ScaleControlPress --







>

>
>
>
>
>
>
>
>
>
>
>
>




















>
>



>





>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# repeat -	Whether and how to auto-repeat the action:  "noRepeat"
#		means don't auto-repeat, "initial" means this is the
#		first action in an auto-repeat sequence, and "again"
#		means this is the second repetition or later.

proc ::tk::ScaleIncrement {w dir big repeat} {
    variable ::tk::Priv

    if {![winfo exists $w]} return

    # give the cancel callback a chance to be serviced if the execution time of
    # the -command script lasts longer than -repeatdelay
    set clockms [clock milliseconds]
    if {$repeat eq "again" &&
            [expr {$clockms - $Priv(clockms)}] > [expr {[$w cget -repeatinterval] * 1.1}]} {
        set Priv(clockms) $clockms
	set Priv(afterId) [after [$w cget -repeatinterval] \
		[list tk::ScaleIncrement $w $dir $big again]]
	return
    }

    if {$big eq "big"} {
	set inc [$w cget -bigincrement]
	if {$inc == 0} {
	    set inc [expr {abs([$w cget -to] - [$w cget -from])/10.0}]
	}
	if {$inc < [$w cget -resolution]} {
	    set inc [$w cget -resolution]
	}
    } else {
	set inc [$w cget -resolution]
    }
    if {([$w cget -from] > [$w cget -to]) ^ ($dir eq "up")} {
        if {$inc > 0} {
            set inc [expr {-$inc}]
        }
    } else {
        if {$inc < 0} {
            set inc [expr {-$inc}]
        }
    }
    # this will run the -command script (if any) during the redrawing
    # of the scale at idle time
    $w set [expr {[$w get] + $inc}]

    if {$repeat eq "again"} {
        set Priv(clockms) $clockms
	set Priv(afterId) [after [$w cget -repeatinterval] \
		[list tk::ScaleIncrement $w $dir $big again]]
    } elseif {$repeat eq "initial"} {
	set delay [$w cget -repeatdelay]
	if {$delay > 0} {
	    set Priv(clockms) $clockms
	    set Priv(afterId) [after $delay \
		    [list tk::ScaleIncrement $w $dir $big again]]
	}
    }
}

# ::tk::ScaleControlPress --

Added library/scaling.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
# scaling.tcl --
#
# Contains scaling-related utility procedures.
#
# Copyright © 2022 Csaba Nemethi <[email protected]>

# ::tk::ScalingPct --
#
# Returns the display's "scaling percentage" (the display resolution expressed
# as a percentage of 96dpi), rounded to the nearest multiple of 25 that is at
# least 100.
#
# On X11 systems (but not on SDL systems that claim to be X11), the first call
# of the command also sets [tk scaling] and ::tk::fontScalingFactor to values
# extracted from the X11 configuration.
#
# The command is called during Tk initialization, from icons.tcl, when the
# latter is sourced by tk.tcl.

proc ::tk::ScalingPct {} {
    set pct [expr {[tk scaling] * 75}]

    variable doneScalingInitX11
    if {![info exists doneScalingInitX11]} {
	set pct [::tk::ScalingInitX11 $pct]
	set doneScalingInitX11 1
    }

    #
    # Save the value of pct rounded to the nearest multiple
    # of 25 that is at least 100, in the variable scalingPct.
    # See "man n tk_scalingPct" for use of ::tk::scalingPct.
    #
    variable scalingPct
    for {set scalingPct 100} {1} {incr scalingPct 25} {
	if {$pct < $scalingPct + 12.5} {
	    break
	}
    }

    return $scalingPct
}

proc ::tk::ScalingInitX11 {pct} {
    set onX11 [expr {[tk windowingsystem] eq "x11"}]
    set usingSDL [expr {[info exists ::tk::sdltk] && $::tk::sdltk}]

    if {$onX11 && !$usingSDL} {
	set origPct $pct

	#
	# Try to get the window scaling factor (1 or 2), partly
	# based on https://wiki.archlinux.org/title/HiDPI
	#
	set winScalingFactor 1
	variable fontScalingFactor 1		;# needed in the file ttk/fonts
	if {[catch {exec ps -e | grep xfce4-session}] == 0} {		;# Xfce
	    if {[catch {exec xfconf-query -c xsettings \
		 -p /Gdk/WindowScalingFactor} result] == 0} {
		set winScalingFactor $result
		if {$winScalingFactor >= 2} {
		    set fontScalingFactor 2
		}
	    }

	    #
	    # The DPI value can be set in the "Fonts" tab of the "Appearance"
	    # dialog or (on Linux Lite 5+) via the "HiDPI Settings" dialog.
	    #
	} elseif {[catch {exec ps -e | grep mate-session}] == 0} {	;# MATE
	    if {[catch {exec gsettings get org.mate.interface \
		 window-scaling-factor} result] == 0} {
		if {$result == 0} {			;# means: "Auto-detect"
		    #
		    # Try to get winScalingFactor from the cursor size
		    #
		    if {[catch {exec xrdb -query | grep Xcursor.size} result]
			== 0 &&
			[catch {exec gsettings get org.mate.peripherals-mouse \
			 cursor-size} defCursorSize] == 0} {
			set cursorSize [lindex $result 1]
			set winScalingFactor \
			    [expr {($cursorSize + $defCursorSize - 1) /
				   $defCursorSize}]
		    }
		} else {
		    set winScalingFactor $result
		}
	    }

	    #
	    # The DPI value can be set via the "Font Rendering Details"
	    # dialog, which can be opened using the "Details..." button
	    # in the "Fonts" tab of the "Appearance Preferences" dialog.
	    #
	} elseif {[catch {exec ps -e | grep gnome-session}] == 0 &&
		  [catch {exec gsettings get \
		   org.gnome.settings-daemon.plugins.xsettings overrides} \
		   result] == 0 &&
		  [set idx \
		   [string first "'Gdk/WindowScalingFactor'" $result]] >= 0} {
	    scan [string range $result $idx end] "%*s <%d>" winScalingFactor
	}

	#
	# Get the scaling percentage
	#
	if {$winScalingFactor >= 2} {
	    set pct 200
	} elseif {[catch {exec xrdb -query | grep Xft.dpi} result] == 0} {
	    #
	    # Derive the value of pct from that of the font DPI
	    #
	    set dpi [lindex $result 1]
	    set pct [expr {100.0 * $dpi / 96}]
	} elseif {[catch {exec ps -e | grep gnome-session}] == 0 &&
		  ![info exists ::env(WAYLAND_DISPLAY)] &&
		  [catch {exec xrandr | grep " connected"} result] == 0 &&
		  [catch {open $::env(HOME)/.config/monitors.xml} chan] == 0} {
	    #
	    # Update pct by scanning the file ~/.config/monitors.xml
	    #
	    ScanMonitorsFile $result $chan pct
	}

	if {($pct != 100) && ($pct != $origPct) && (![interp issafe])} {
	    #
	    # Set Tk's scaling factor according to $pct
	    #
	    tk scaling [expr {$pct / 75.0}]
	}
    }
    return $pct
}

# ::tk::ScaleNum --
#
# Scales an integer according to the display's current scaling percentage.
#
# Arguments:
#   num - An integer.

proc ::tk::ScaleNum num {
    return [expr {round($num * [tk scaling] * 0.75)}]
}

# ::tk::FontScalingFactor --
#
# Accessor command for variable ::tk::fontScalingFactor.

proc ::tk::FontScalingFactor {} {
    variable fontScalingFactor
    if {[info exists fontScalingFactor]} {
	return $fontScalingFactor
    } else {
	return 1
    }
}

# ::tk::ScanMonitorsFile --
#
# Updates the scaling percentage by scanning the file ~/.config/monitors.xml.
#
# Arguments:
#   xrandrResult - The output of 'xrandr | grep " connected"'.
#   chan -	   Returned from 'open ~/.config/monitors.xml'.
#   pctName -	   The name of a variable containing the scaling percentage.

proc ::tk::ScanMonitorsFile {xrandrResult chan pctName} {
    upvar $pctName pct

    #
    # Get the list of connected outputs reported by xrandr
    #
    set outputList {}
    foreach line [split $xrandrResult "\n"] {
	set idx [string first " " $line]
	set output [string range $line 0 [incr idx -1]]
	lappend outputList $output
    }
    set outputList [lsort $outputList]

    #
    # Get the content of the file ~/.config/monitors.xml
    #
    set str [read $chan]
    close $chan

    #
    # Run over the file's "configuration" sections
    #
    set idx 0
    while {[set idx2 [string first "<configuration>" $str $idx]] >= 0} {
	set idx2 [string first ">" $str $idx2]
	set idx [string first "</configuration>" $str $idx2]
	set config [string range $str [incr idx2] [incr idx -1]]

	#
	# Get the list of connectors within this configuration
	#
	set connectorList {}
	foreach {dummy connector} [regexp -all -inline \
		{<connector>([^<]+)</connector>} $config] {
	    lappend connectorList $connector
	}
	set connectorList [lsort $connectorList]

	#
	# If $outputList and $connectorList are identical then set the
	# variable pct to 100, 200, 300, 400, or 500, depending on the
	# max. scaling within this configuration, and exit the loop
	#
	if {$outputList eq $connectorList} {
	    set maxScaling 1.0
	    foreach {dummy scaling} [regexp -all -inline \
		    {<scale>([^<]+)</scale>} $config] {
		if {$scaling > $maxScaling} {
		    set maxScaling $scaling
		}
	    }

	    foreach n {4 3 2 1 0} {
		if {$maxScaling > $n} {
		    set pct [expr {($n + 1) * 100}]
		    break
		}
	    }

	    break
	}
    }
}

Changes to library/scrlbar.tcl.

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
}
}




bind Scrollbar <MouseWheel> {
    tk::ScrollByUnits %W hv %D -30.0
}
bind Scrollbar <Option-MouseWheel> {
    tk::ScrollByUnits %W hv %D -3.0















}

# tk::ScrollButtonDown --
# This procedure is invoked when a button is pressed in a scrollbar.
# It changes the way the scrollbar is displayed and takes actions
# depending on where the mouse is.
#







>
>
>

|


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
    tk::ScrollToPos %W 0
}
bind Scrollbar <<LineEnd>> {
    tk::ScrollToPos %W 1
}
}

bind Scrollbar <Enter> {+
    set tk::Priv(xEvents) 0; set tk::Priv(yEvents) 0
}
bind Scrollbar <MouseWheel> {
    tk::ScrollByUnits %W vh %D -40.0
}
bind Scrollbar <Option-MouseWheel> {
    tk::ScrollByUnits %W vh %D -12.0
}
bind Scrollbar <Shift-MouseWheel> {
    tk::ScrollByUnits %W hv %D -40.0
}
bind Scrollbar <Shift-Option-MouseWheel> {
    tk::ScrollByUnits %W hv %D -12.0
}
bind Scrollbar <TouchpadScroll> {
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    if {$deltaX != 0 && [%W cget -orient] eq "horizontal"} {
	tk::ScrollbarScrollByPixels %W h $deltaX
    }
    if {$deltaY != 0 && [%W cget -orient] eq "vertical"} {
	tk::ScrollbarScrollByPixels %W v $deltaY
    }
}

# 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.
#
290
291
292
293
294
295
296









































297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314















315
316
317
318
319
320
321
    if {[$w cget -jump]} {
	set delta [$w delta [expr {$x - $Priv(pressX)}] \
		[expr {$y - $Priv(pressY)}]]
	ScrollToPos $w [expr {$Priv(initPos) + $delta}]
    }
    set Priv(initPos) ""
}










































# ::tk::ScrollByUnits --
# This procedure tells the scrollbar's associated widget to scroll up
# or down by a given number of units.  It notifies the associated widget
# in different ways for old and new command syntaxes.
#
# Arguments:
# w -		The scrollbar widget.
# orient -	Which kinds of scrollbars this applies to:  "h" for
#		horizontal, "v" for vertical, "hv" for both.
# amount -	How many units to scroll:  typically 1 or -1.

proc ::tk::ScrollByUnits {w orient amount {factor 1.0}} {
    set cmd [$w cget -command]
    if {$cmd eq "" || ([string first \
	    [string index [$w cget -orient] 0] $orient] < 0)} {
	return
    }















    set info [$w get]
    if {[llength $info] == 2} {
	uplevel #0 $cmd scroll [expr {$amount/$factor}] units
    } else {
	uplevel #0 $cmd [expr {[lindex $info 2] + [expr {$amount/$factor}]}]
    }
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    if {[$w cget -jump]} {
	set delta [$w delta [expr {$x - $Priv(pressX)}] \
		[expr {$y - $Priv(pressY)}]]
	ScrollToPos $w [expr {$Priv(initPos) + $delta}]
    }
    set Priv(initPos) ""
}

# ::tk::ScrollbarScrollByPixels --
# This procedure tells the scrollbar's associated widget to scroll up
# or down by a given number of pixels.  It only works with scrollbars
# because it uses the delta command.
#
# Arguments:
# w -		The scrollbar widget.
# orient -	Which kind of scrollbar this applies to: "h" for
#		horizontal, "v" for vertical.
# amount -	How many pixels to scroll.

proc ::tk::ScrollbarScrollByPixels {w orient amount} {
    set cmd [$w cget -command]
    if {$cmd eq ""} {
	return
    }
    set xyview [lindex [split $cmd] end]
    if {$orient eq "v"} {
	if {$xyview eq "xview"} {
	    return
	}
    }
    if {$orient eq "h"} {
	if {$xyview eq "yview"} {
	    return
	}
    }

    # The code below works with both the current and old syntax for
    # the scrollbar get command.

    set info [$w get]
    if {[llength $info] == 2} {
	set first [lindex $info 0]
    } else {
	set first [lindex $info 2]
    }
    set pixels [expr {-$amount}]
    uplevel #0 $cmd moveto [expr $first + [$w delta $pixels $pixels]]
}

# ::tk::ScrollByUnits --
# This procedure tells the scrollbar's associated widget to scroll up
# or down by a given number of units.  It notifies the associated widget
# in different ways for old and new command syntaxes.
#
# Arguments:
# w -		The scrollbar widget.
# orient -	Which kinds of scrollbars this applies to:  "h" for
#		horizontal, "v" for vertical, "hv" or "vh" for both.
# amount -	How many units to scroll:  typically 1 or -1.

proc ::tk::ScrollByUnits {w orient amount {factor 1.0}} {
    set cmd [$w cget -command]
    if {$cmd eq "" || ([string first \
	    [string index [$w cget -orient] 0] $orient] < 0)} {
	return
    }

    if {[string length $orient] == 2 && $factor != 1.0} {
	# Count both the <MouseWheel> and <Shift-MouseWheel>
	# events, and ignore the non-dominant ones

	variable ::tk::Priv
	set axis [expr {[string index $orient 0] eq "h" ? "x" : "y"}]
	incr Priv(${axis}Events)
	if {($Priv(xEvents) + $Priv(yEvents) > 10) &&
		($axis eq "x" && $Priv(xEvents) < $Priv(yEvents) ||
		 $axis eq "y" && $Priv(yEvents) < $Priv(xEvents))} {
	    return
	}
    }

    set info [$w get]
    if {[llength $info] == 2} {
	uplevel #0 $cmd scroll [expr {$amount/$factor}] units
    } else {
	uplevel #0 $cmd [expr {[lindex $info 2] + [expr {$amount/$factor}]}]
    }
}

Changes to library/spinbox.tcl.

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    %W invoke buttonup
}
bind Spinbox <<NextLine>> {
    %W invoke buttondown
}

bind Spinbox <<PrevChar>> {
    ::tk::EntrySetCursor %W [expr {[%W index insert] - 1}]
}
bind Spinbox <<NextChar>> {
    ::tk::EntrySetCursor %W [expr {[%W index insert] + 1}]
}
bind Spinbox <<SelectPrevChar>> {
    ::tk::EntryKeySelect %W [expr {[%W index insert] - 1}]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextChar>> {
    ::tk::EntryKeySelect %W [expr {[%W index insert] + 1}]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<PrevWord>> {
    ::tk::EntrySetCursor %W [::tk::EntryPreviousWord %W insert]
}
bind Spinbox <<NextWord>> {
    ::tk::EntrySetCursor %W [::tk::EntryNextWord %W insert]
}
bind Spinbox <<SelectPrevWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryPreviousWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryNextWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<LineStart>> {
    ::tk::EntrySetCursor %W 0
}
bind Spinbox <<SelectLineStart>> {
    ::tk::EntryKeySelect %W 0







|


|


|



|













|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    %W invoke buttonup
}
bind Spinbox <<NextLine>> {
    %W invoke buttondown
}

bind Spinbox <<PrevChar>> {
    ::tk::EntrySetCursor %W [tk::EntryPreviousChar %W insert]
}
bind Spinbox <<NextChar>> {
    ::tk::EntrySetCursor %W [tk::EntryNextChar %W insert]
}
bind Spinbox <<SelectPrevChar>> {
    ::tk::EntryKeySelect %W [tk::EntryPreviousChar %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextChar>> {
    ::tk::EntryKeySelect %W [tk::EntryNextChar %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<PrevWord>> {
    ::tk::EntrySetCursor %W [::tk::EntryPreviousWord %W insert]
}
bind Spinbox <<NextWord>> {
    ::tk::EntrySetCursor %W [::tk::EntryNextWord %W insert]
}
bind Spinbox <<SelectPrevWord>> {
    ::tk::EntryKeySelect %W [::tk::EntryPreviousWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<SelectNextWord>> {
    ::tk::EntryKeySelect %W [::tk::EntrySelectNextWord %W insert]
    ::tk::EntrySeeInsert %W
}
bind Spinbox <<LineStart>> {
    ::tk::EntrySetCursor %W 0
}
bind Spinbox <<SelectLineStart>> {
    ::tk::EntryKeySelect %W 0
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
    ::tk::EntrySeeInsert %W
}

bind Spinbox <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last
    } else {
	%W delete insert

    }
}
bind Spinbox <BackSpace> {
    ::tk::EntryBackspace %W
}

bind Spinbox <Control-space> {







|
>







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    ::tk::EntrySeeInsert %W
}

bind Spinbox <Delete> {
    if {[%W selection present]} {
	%W delete sel.first sel.last
    } else {
	%W delete [tk::startOfCluster [%W get] [%W index insert]] \
		[tk::endOfCluster [%W get] [%W index insert]]
    }
}
bind Spinbox <BackSpace> {
    ::tk::EntryBackspace %W
}

bind Spinbox <Control-space> {
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
bind Spinbox <<SelectNone>> {
    %W selection clear
}
bind Spinbox <Key> {
    ::tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Spinbox <Alt-Key> {# nothing}
bind Spinbox <Meta-Key> {# nothing}
bind Spinbox <Control-Key> {# nothing}
bind Spinbox <Escape> {# nothing}
bind Spinbox <Return> {# nothing}
bind Spinbox <KP_Enter> {# nothing}
bind Spinbox <Tab> {# nothing}
bind Spinbox <Prior> {# nothing}
bind Spinbox <Next> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Spinbox <Command-Key> {# nothing}
}


# On Windows, paste is done using Shift-Insert.  Shift-Insert already
# generates the <<Paste>> event, so we don't need to do anything here.
if {[tk windowingsystem] ne "win32"} {
    bind Spinbox <Insert> {
	catch {::tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
    }







|













<
|
<
>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222

223
224
225
226
227
228
229
230
bind Spinbox <<SelectNone>> {
    %W selection clear
}
bind Spinbox <Key> {
    ::tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, Control, Command, and Fn keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for Escape, Return, and Tab.

bind Spinbox <Alt-Key> {# nothing}
bind Spinbox <Meta-Key> {# nothing}
bind Spinbox <Control-Key> {# nothing}
bind Spinbox <Escape> {# nothing}
bind Spinbox <Return> {# nothing}
bind Spinbox <KP_Enter> {# nothing}
bind Spinbox <Tab> {# nothing}
bind Spinbox <Prior> {# nothing}
bind Spinbox <Next> {# nothing}

bind Spinbox <Command-Key> {# nothing}

bind Spinbox <Fn-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]}
    }
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
		} else {
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < [$w index anchor]} {
		set before [tcl_wordBreakBefore [$w get] $cur]
		set after [tcl_wordBreakAfter [$w get] $anchor-1]
	    } else {
		set before [tcl_wordBreakBefore [$w get] $anchor]
		set after [tcl_wordBreakAfter [$w get] $cur-1]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }







|
|

|
|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
		} else {
		    $w selection clear
		}
	    }
	}
	word {
	    if {$cur < [$w index anchor]} {
		set before [tk::wordBreakBefore [$w get] $cur]
		set after [tk::wordBreakAfter [$w get] $anchor-1]
	    } else {
		set before [tk::wordBreakBefore [$w get] $anchor]
		set after [tk::wordBreakAfter [$w get] $cur-1]
	    }
	    if {$before < 0} {
		set before 0
	    }
	    if {$after < 0} {
		set after end
	    }

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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# 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 100 [list [namespace current]::_balloon_show %W [list $help] cursor]"
	bind $w <Any-Leave> "destroy %W._balloon"
    }

    proc _balloon_show {w msg i} {
	if {![winfo exists $w]} { return }

	# Use string match to allow that the help will be shown when
	# the pointer is in any child of the desired widget
	if {([winfo class $w] ne "Menu") && ![string match $w* [eval [list winfo containing] \
								    [winfo pointerxy $w]]]} {
	    return
	}

	set top $w._balloon
	catch {destroy $top}
	toplevel $top -bg black -bd 1
	wm overrideredirect $top 1
	if {[tk windowingsystem] eq "aqua"}  {
	    ::tk::unsupported::MacWindowStyle style $top help none
	}
	pack [message $top._txt -aspect 10000 -text $msg]

	update idletasks
	set screenw [winfo screenwidth $w]
	set screenh [winfo screenheight $w]
	set reqw [winfo reqwidth $top]
	set reqh [winfo reqheight $top]
	# When adjusting for being on the screen boundary, check that we are
	# near the "edge" already, as Tk handles multiple monitors oddly
	if {$i eq "cursor"} {
	    set y [expr {[winfo pointery $w]+20}]
	    if {($y < $screenh) && ($y+$reqh) > $screenh} {
		set y [expr {[winfo pointery $w]-$reqh-5}]
	    }
	} elseif {$i ne ""} {
	    set y [expr {[winfo rooty $w]+[winfo vrooty $w]+[$w yposition $i]+25}]
	    if {($y < $screenh) && ($y+$reqh) > $screenh} {
		# show above if we would be offscreen
		set y [expr {[winfo rooty $w]+[$w yposition $i]-$reqh-5}]
	    }
	} else {
	    set y [expr {[winfo rooty $w]+[winfo vrooty $w]+[winfo height $w]+5}]
	    if {($y < $screenh) && ($y+$reqh) > $screenh} {
		# show above if we would be offscreen
		set y [expr {[winfo rooty $w]-$reqh-5}]
	    }
	}
	if {$i eq "cursor"} {
	    set x [winfo pointerx $w]
	} else {
	    set x [expr {[winfo rootx $w]+[winfo vrootx $w]+ ([winfo width $w]-$reqw)/2}]
	}
	# only readjust when we would appear right on the screen edge
	if {$x<0 && ($x+$reqw)>0} {
	    set x 0
	} elseif {($x < $screenw) && ($x+$reqw) > $screenw} {
	    set x [expr {$screenw-$reqw}]
	}
	if {[tk windowingsystem] eq "aqua"} {
	    set focus [focus]
	}

	wm geometry $top +$x+$y
	wm deiconify $top
	raise $top

	if {[tk windowingsystem] eq "aqua" && $focus ne ""} {
	    # Aqua's help window steals focus on display
	    after idle [list focus -force $focus]
	}
    }

    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 exists
    namespace ensemble create
}


# Pure-Tcl system notification window for use if native implementation not available.
# This is supposed to happen only on X11 when libnotify is not present.
namespace eval ::tk::sysnotify:: {
    # These defaults mimic the default behaviour of gnome and xfce notifications.
    # These are hardcoded defaults.
    variable defaults {
	padX            3
	padY            3
	background      gray15
	foreground      white
	delay           10000
	alpha           0.85
    }
    # These options are meant to be "public". The user could tinker with
    # these values to adjust the system notification appearance/behaviour.
    option add *Sysnotify.padX       [dict get $defaults padX]
    option add *Sysnotify.padY       [dict get $defaults padY]
    option add *Sysnotify.background [dict get $defaults background]
    option add *Sysnotify.foreground [dict get $defaults foreground]
    option add *Sysnotify.delay      [dict get $defaults delay]
    option add *Sysnotify.alpha      [dict get $defaults alpha]

    proc _notifywindow {title msg} {
	variable defaults

	# cleanup any previous notify window and create a new one
	set w ._notify
	_notifyDestroy $w
	toplevel $w -class Sysnotify

	# read the option database to check out whether the user has set
	# some options; fall back to our hardcoded defaults otherwise
	dict for {option value} [dict remove $defaults alpha] {
	    set $option [option get $w $option ""]
	    if {[set $option] eq ""} {
		set $option $value
	    }
	}

	set xpos [tk::ScaleNum 16]
	set ypos [tk::ScaleNum 48]
	# position from the "ne" corner
	wm geometry $w -$xpos+$ypos
	wm overrideredirect $w true

	# internal options
	option add *Sysnotify.Label.anchor     w
	option add *Sysnotify.Label.justify    left
	option add *Sysnotify.Label.wrapLength [expr {[winfo screenwidth .] / 4}]
	foreach option {padX padY foreground background} {
	    option add *Sysnotify.Label.$option [set $option]
	}
	set icon ::tk::icons::information
	set width [expr {[image width $icon] + 2 * $padX}]
	set height [expr {[image height $icon] + 2 * $padY}]
	label $w.icon -image $icon -width $width -height $height -anchor c
	label $w.title -text $title -font TkHeadingFont
	label $w.message -text [_filterMarkup $msg] -font TkTooltipFont

	grid $w.icon $w.title -sticky news
	grid ^       $w.message -sticky news

	bind Sysnotify <Map> [namespace code {
	    # set the wm attribute here; it is ignored if set
	    # before the window is mapped
	    wm attributes %W -alpha 0.0
	    if {[wm attributes %W -alpha] == 0.0} {
		_fadeIn %W
	    }
	}]
	bind Sysnotify <Enter> [namespace code {_onEnter %W}]
	bind Sysnotify <Leave> [namespace code {_onLeave %W}]
	bind $w <Button-1> [namespace code [list _notifyDestroy $w]]
	after $delay [namespace code [list _fadeOut $w]]
	return
    }

    # Fade the window into view.
    proc _fadeIn {w} {
	variable defaults
        if {![winfo exists $w]} {return}
	if {[set alpha  [option get $w alpha ""]] eq ""} {
	    set alpha [dict get $defaults alpha]
	}
	raise $w
	set before [wm attributes $w -alpha]
	set new    [expr { min($alpha, $before + 0.10) }]
	wm attributes $w -alpha $new
	set after  [wm attributes $w -alpha]
	if {($before == 1.0) || ($before == $after)} {
	    # not supported or we're done
	    return
	}
	after 40 [namespace code [list _fadeIn $w]]
    }

    # Fade out and destroy window.
    proc _fadeOut {w} {
        if {![winfo exists $w]} {return}
	set before [wm attributes $w -alpha]
	set new    [expr { $before - 0.02 }]
	wm attributes $w -alpha $new
	set after  [wm attributes $w -alpha]
	if {($after == 1.0) || ($before == $after)} {
	    _notifyDestroy $w
	    return
	}
	after 40 [namespace code [list _fadeOut $w]]
    }

    proc _notifyDestroy {w} {
	# cancel any pending fade in or fade out
	_cancelFading $w
	destroy $w
    }

    proc _onEnter {w} {
	wm attributes $w -alpha 1.0
	_cancelFading $w
    }

    proc _onLeave {w} {
	variable defaults
	if {[set alpha [option get $w alpha ""]] eq ""} {
	    set alpha [dict get $defaults alpha]
	}
	if {[set delay [option get $w delay ""]] eq ""} {
	    set delay [dict get $defaults delay]
	}
	wm attributes $w -alpha $alpha
	after $delay [namespace code [list _fadeOut $w]]
    }

    proc _cancelFading {w} {
	after cancel [namespace code [list _fadeOut $w]]
	after cancel [namespace code [list _fadeIn $w]]
    }

    # The Desktop Notifications Specification allow for some markup
    # in the message to display. It also specifies
    # "Notification servers that do not support these tags should
    # filter them out"
    # See https://specifications.freedesktop.org/notification-spec/latest/ar01s04.html
    # We don't event try to render those properly
    proc _filterMarkup {txt} {
	# remove fixed tags
	set maplist {<b> "" </b> "" <i> "" </i> "" <u> "" </u> "" </a> ""}
	set txt [string map $maplist $txt]
	# remove <img> tags leaving (possible) alt text
	set txt [regsub -- {<img *src="[^"]*" *(alt="([^"]*)")? */?>} $txt {\2}]
	# remove <a href=""> variable tag
	set txt [regsub -- {<a[^>]*>} $txt {}]
	return $txt
    }
}


# 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 icon existence.
proc tk::systray::exists {} {
    variable _created
    return $_created
}

# 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
namespace ensemble configure tk -map \
    [dict merge [namespace ensemble configure tk -map] \
        {systray ::tk::systray sysnotify ::tk::sysnotify::sysnotify}]

Changes to library/tclIndex.

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146




147
148
149
150
151
152
153
set auto_index(::tk::SaveGrabInfo) [list source [file join $dir menu.tcl]]
set auto_index(::tk::RestoreOldGrab) [list source [file join $dir menu.tcl]]
set auto_index(tk_menuSetFocus) [list source [file join $dir menu.tcl]]
set auto_index(::tk::GenerateMenuSelect) [list source [file join $dir menu.tcl]]
set auto_index(tk_popup) [list source [file join $dir menu.tcl]]
set auto_index(::tk::ensure_psenc_is_loaded) [list source [file join $dir mkpsenc.tcl]]
set auto_index(::tk::MessageBox) [list source [file join $dir msgbox.tcl]]
set auto_index(tk_menuBar) [list source [file join $dir obsolete.tcl]]
set auto_index(tk_bindForTraversal) [list source [file join $dir obsolete.tcl]]
set auto_index(::tk::classic::restore) [list source [file join $dir obsolete.tcl]]
set auto_index(tk_optionMenu) [list source [file join $dir optMenu.tcl]]
set auto_index(tk_setPalette) [list source [file join $dir palette.tcl]]
set auto_index(::tk::RecolorTree) [list source [file join $dir palette.tcl]]
set auto_index(::tk::Darken) [list source [file join $dir palette.tcl]]
set auto_index(tk_bisque) [list source [file join $dir palette.tcl]]
set auto_index(::safe::tkInterpInit) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::loadTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::TkInit) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::allowTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::disallowTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::tkDelete) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::tkTopLevel) [list source [file join $dir safetk.tcl]]
set auto_index(::tk::ScaleActivate) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButtonDown) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleDrag) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleEndDrag) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleIncrement) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleControlPress) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButton2Down) [list source [file join $dir scale.tcl]]




set auto_index(::tk::ScrollButtonDown) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollButtonUp) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollSelect) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollStartDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollEndDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollByUnits) [list source [file join $dir scrlbar.tcl]]







<
<
<



















>
>
>
>







118
119
120
121
122
123
124



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
set auto_index(::tk::SaveGrabInfo) [list source [file join $dir menu.tcl]]
set auto_index(::tk::RestoreOldGrab) [list source [file join $dir menu.tcl]]
set auto_index(tk_menuSetFocus) [list source [file join $dir menu.tcl]]
set auto_index(::tk::GenerateMenuSelect) [list source [file join $dir menu.tcl]]
set auto_index(tk_popup) [list source [file join $dir menu.tcl]]
set auto_index(::tk::ensure_psenc_is_loaded) [list source [file join $dir mkpsenc.tcl]]
set auto_index(::tk::MessageBox) [list source [file join $dir msgbox.tcl]]



set auto_index(tk_optionMenu) [list source [file join $dir optMenu.tcl]]
set auto_index(tk_setPalette) [list source [file join $dir palette.tcl]]
set auto_index(::tk::RecolorTree) [list source [file join $dir palette.tcl]]
set auto_index(::tk::Darken) [list source [file join $dir palette.tcl]]
set auto_index(tk_bisque) [list source [file join $dir palette.tcl]]
set auto_index(::safe::tkInterpInit) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::loadTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::TkInit) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::allowTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::disallowTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::tkDelete) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::tkTopLevel) [list source [file join $dir safetk.tcl]]
set auto_index(::tk::ScaleActivate) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButtonDown) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleDrag) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleEndDrag) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleIncrement) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleControlPress) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButton2Down) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScalingPct) [list source [file join $dir scaling.tcl]]
set auto_index(::tk::ScaleNum) [list source [file join $dir scaling.tcl]]
set auto_index(::tk::FontScalingFactor) [list source [file join $dir scaling.tcl]]
set auto_index(::tk::ScanMonitorsFile) [list source [file join $dir scaling.tcl]]
set auto_index(::tk::ScrollButtonDown) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollButtonUp) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollSelect) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollStartDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollEndDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollByUnits) [list source [file join $dir scrlbar.tcl]]
244
245
246
247
248
249
250
251
252
253
set auto_index(::tk::MotifFDialog_FilterCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_CancelCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Set) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Unset) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Key) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Goto) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Reset) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::unsupported::ExposePrivateCommand) [list source [file join $dir unsupported.tcl]]
set auto_index(::tk::unsupported::ExposePrivateVariable) [list source [file join $dir unsupported.tcl]]
set auto_index(::tk::fontchooser) [list source [file join $dir fontchooser.tcl]]







<
<

245
246
247
248
249
250
251


252
set auto_index(::tk::MotifFDialog_FilterCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_CancelCmd) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Set) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Unset) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Key) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Goto) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Reset) [list source [file join $dir xmfbox.tcl]]


set auto_index(::tk::fontchooser) [list source [file join $dir fontchooser.tcl]]

Changes to library/tearoff.tcl.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    # the parent of the new menu.  This guarantees that the torn off
    # menu will be on the same screen as the original menu.  By making
    # it a child of the ancestor, rather than a child of the menu, it
    # can continue to live even if the menu is deleted;  it will go
    # away when the toplevel goes away.

    if {$x == 0} {
    	set x [winfo rootx $w]
    }
    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}
	}
    }







|


|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    # the parent of the new menu.  This guarantees that the torn off
    # menu will be on the same screen as the original menu.  By making
    # it a child of the ancestor, rather than a child of the menu, it
    # can continue to live even if the menu is deleted;  it will go
    # away when the toplevel goes away.

    if {$x == 0} {
	set x [winfo rootx $w]
    }
    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}
	}
    }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

    # Pick a title for the new menu by looking at the parent of the
    # original: if the parent is a menu, then use the text of the active
    # entry.  If it's a menubutton then use its text.

    set parent [winfo parent $w]
    if {[$menu cget -title] ne ""} {
    	wm title $menu [$menu cget -title]
    } else {
    	switch -- [winfo class $parent] {
	    Menubutton {
	    	wm title $menu [$parent cget -text]
	    }
	    Menu {
	    	wm title $menu [$parent entrycget active -label]
	    }
	}
    }

    if {[tk windowingsystem] eq "win32"} {
        # [Bug 3181181]: Find the toplevel window for the menu
        set parent [winfo toplevel $parent]
        while {[winfo class $parent] eq "Menu"} {
            set parent [winfo toplevel [winfo parent $parent]]
        }
	wm transient $menu [winfo toplevel $parent]
	wm attributes $menu -toolwindow 1
    }

    $menu post $x $y

    if {[winfo exists $menu] == 0} {







|

|

|


|





|
|
|
|
|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

    # Pick a title for the new menu by looking at the parent of the
    # original: if the parent is a menu, then use the text of the active
    # entry.  If it's a menubutton then use its text.

    set parent [winfo parent $w]
    if {[$menu cget -title] ne ""} {
	wm title $menu [$menu cget -title]
    } else {
	switch -- [winfo class $parent] {
	    Menubutton {
		wm title $menu [$parent cget -text]
	    }
	    Menu {
		wm title $menu [$parent entrycget active -label]
	    }
	}
    }

    if {[tk windowingsystem] eq "win32"} {
	# [Bug 3181181]: Find the toplevel window for the menu
	set parent [winfo toplevel $parent]
	while {[winfo class $parent] eq "Menu"} {
	    set parent [winfo toplevel [winfo parent $parent]]
	}
	wm transient $menu [winfo toplevel $parent]
	wm attributes $menu -toolwindow 1
    }

    $menu post $x $y

    if {[winfo exists $menu] == 0} {
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
	}
	if {[lindex $option 0] eq "-type"} {
	    continue
	}
	lappend cmd [lindex $option 0] [lindex $option 4]
    }
    eval $cmd
    set last [$src index last]
    if {$last eq "none"} {
	return
    }

    for {set i [$src cget -tearoff]} {$i <= $last} {incr i} {
	set cmd [list $dst add [$src type $i]]
	foreach option [$src entryconfigure $i]  {
	    lappend cmd [lindex $option 0] [lindex $option 4]
	}
	eval $cmd
    }

    # Duplicate the binding tags and bindings from the source menu.

    set tags [bindtags $src]
    set srcLen [string length $src]

    # Copy tags to x, replacing each substring of src with dst.

    while {[set index [string first $src $tags]] >= 0} {
	if {$index > 0} {
	    append x [string range $tags 0 $index-1]$dst
	}
	set tags [string range $tags $index+$srcLen end]
    }
    append x $tags

    bindtags $dst $x

    foreach event [bind $src] {
	unset x
	set script [bind $src $event]
	set eventLen [string length $event]

	# Copy script to x, replacing each substring of event with dst.

	while {[set index [string first $event $script]] >= 0} {
	    if {$index > 0} {
		append x [string range $script 0 $index-1]
	    }
	    append x $dst
	    set script [string range $script $index+$eventLen end]
	}
	append x $script

	bind $dst $event $x
    }
}







|
|
<
|
>

|






|


<
|
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151

152

153








154
155



















	}
	if {[lindex $option 0] eq "-type"} {
	    continue
	}
	lappend cmd [lindex $option 0] [lindex $option 4]
    }
    eval $cmd

    # Copy the meny entries, if any


    set last [$src index last]
    for {set i [$src cget -tearoff]} {$i <= $last} {incr i} {
	set cmd [list $dst add [$src type $i] [$src id $i]]
	foreach option [$src entryconfigure $i]  {
	    lappend cmd [lindex $option 0] [lindex $option 4]
	}
	eval $cmd
    }

    # Duplicate the binding tags from the source menu, replacing src with dst

    set tags [bindtags $src]

    set x [lsearch -exact $tags $src]

    if {$x >= 0} {lset tags $x $dst}








    bindtags $dst $tags
}



















Changes to library/text.tcl.

1
2
3
4
5
6
7
8

9
10
11
12









13
14
15
16
17
18
19
# text.tcl --
#
# This file defines the default bindings for Tk text widgets and provides
# procedures that help in implementing the bindings.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998 by Scriptics Corporation.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#










#-------------------------------------------------------------------------
# Elements of ::tk::Priv that are used in this file:
#
# afterId -		If non-null, it means that auto-scanning is underway
#			and it gives the "after" id for the next auto-scan
#			command to be executed.







|
>




>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# text.tcl --
#
# This file defines the default bindings for Tk text widgets and provides
# procedures that help in implementing the bindings.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998 Scriptics Corporation.
# Copyright © 2015-2017 Gregor Cramer
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

##########################################################################
# TODO:
# Currently we cannot use identifier "begin" for very first index, because
# it has still lowest precedence, and this may clash if the application is
# using this identifier for marks. In a later version of this file all
# occurences of "1.0" should be replaced with "begin", as soon as "begin"
# has highest precedence.
##########################################################################

#-------------------------------------------------------------------------
# Elements of ::tk::Priv that are used in this file:
#
# afterId -		If non-null, it means that auto-scanning is underway
#			and it gives the "after" id for the next auto-scan
#			command to be executed.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54



# Standard Motif bindings:

bind Text <Button-1> {
    tk::TextButton1 %W %x %y
    %W tag remove sel 0.0 end
}
bind Text <B1-Motion> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::TextSelectTo %W %x %y
}
bind Text <Double-Button-1> {







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64



# Standard Motif bindings:

bind Text <Button-1> {
    tk::TextButton1 %W %x %y
    %W tag remove sel 1.0 end
}
bind Text <B1-Motion> {
    set tk::Priv(x) %x
    set tk::Priv(y) %y
    tk::TextSelectTo %W %x %y
}
bind Text <Double-Button-1> {
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    }
}
# stop an accidental double click triggering <Double-Button-1>
bind Text <Double-Control-Button-1> { # nothing }
# stop an accidental movement triggering <B1-Motion>
bind Text <Control-B1-Motion> { # nothing }
bind Text <<PrevChar>> {
    tk::TextSetCursor %W insert-1displayindices
}
bind Text <<NextChar>> {
    tk::TextSetCursor %W insert+1displayindices
}
bind Text <<PrevLine>> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W -1]
}
bind Text <<NextLine>> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W 1]
}
bind Text <<SelectPrevChar>> {
    tk::TextKeySelect %W [%W index {insert - 1displayindices}]
}
bind Text <<SelectNextChar>> {
    tk::TextKeySelect %W [%W index {insert + 1displayindices}]
}
bind Text <<SelectPrevLine>> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W -1]
}
bind Text <<SelectNextLine>> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W 1]
}
bind Text <<PrevWord>> {
    tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <<NextWord>> {
    tk::TextSetCursor %W [tk::TextNextWord %W insert]
}
bind Text <<PrevPara>> {
    tk::TextSetCursor %W [tk::TextPrevPara %W insert]
}
bind Text <<NextPara>> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <<SelectPrevWord>> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
}
bind Text <<SelectNextWord>> {
    tk::TextKeySelect %W [tk::TextNextWord %W insert]
}
bind Text <<SelectPrevPara>> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <<SelectNextPara>> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}







|


|








|


|








|











|


|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    }
}
# stop an accidental double click triggering <Double-Button-1>
bind Text <Double-Control-Button-1> { # nothing }
# stop an accidental movement triggering <B1-Motion>
bind Text <Control-B1-Motion> { # nothing }
bind Text <<PrevChar>> {
    tk::TextSetCursor %W [tk::TextPrevPos %W insert tk::startOfCluster]
}
bind Text <<NextChar>> {
    tk::TextSetCursor %W [tk::TextNextPos %W insert tk::endOfCluster]
}
bind Text <<PrevLine>> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W -1]
}
bind Text <<NextLine>> {
    tk::TextSetCursor %W [tk::TextUpDownLine %W 1]
}
bind Text <<SelectPrevChar>> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tk::startOfCluster]
}
bind Text <<SelectNextChar>> {
    tk::TextKeySelect %W [tk::TextNextPos %W insert tk::endOfCluster]
}
bind Text <<SelectPrevLine>> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W -1]
}
bind Text <<SelectNextLine>> {
    tk::TextKeySelect %W [tk::TextUpDownLine %W 1]
}
bind Text <<PrevWord>> {
    tk::TextSetCursor %W [tk::TextPrevPos %W insert tk::startOfPreviousWord]
}
bind Text <<NextWord>> {
    tk::TextSetCursor %W [tk::TextNextWord %W insert]
}
bind Text <<PrevPara>> {
    tk::TextSetCursor %W [tk::TextPrevPara %W insert]
}
bind Text <<NextPara>> {
    tk::TextSetCursor %W [tk::TextNextPara %W insert]
}
bind Text <<SelectPrevWord>> {
    tk::TextKeySelect %W [tk::TextPrevPos %W insert tk::startOfPreviousWord]
}
bind Text <<SelectNextWord>> {
    tk::TextKeySelect %W [tk::TextSelectNextWord %W insert]
}
bind Text <<SelectPrevPara>> {
    tk::TextKeySelect %W [tk::TextPrevPara %W insert]
}
bind Text <<SelectNextPara>> {
    tk::TextKeySelect %W [tk::TextNextPara %W insert]
}
208
209
210
211
212
213
214

215
216
217

218
219
220

221
222
223
224
225

226
227

228
229
230

231
232
233
234


235

236
237

238
239
240
241
242
243
244
bind Text <Control-Shift-Tab> {
    focus [tk_focusPrev %W]
}
bind Text <Control-i> {
    tk::TextInsert %W \t
}
bind Text <Return> {

    tk::TextInsert %W \n
    if {[%W cget -autoseparators]} {
	%W edit separator

    }
}
bind Text <Delete> {

    if {[tk::TextCursorInSelection %W]} {
	%W delete sel.first sel.last
    } else {
	if {[%W compare end != insert+1c]} {
	    %W delete insert

	}
	%W see insert

    }
}
bind Text <BackSpace> {

    if {[tk::TextCursorInSelection %W]} {
	%W delete sel.first sel.last
    } else {
	if {[%W compare insert != 1.0]} {


	    %W delete insert-1c

	}
	%W see insert

    }
}

bind Text <Control-space> {
    %W mark set [tk::TextAnchor %W] insert
}
bind Text <Select> {







>
|
|
|
>



>
|
|
|
|
|
>
|
|
>



>
|
|
|
|
>
>
|
>
|
|
>







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
bind Text <Control-Shift-Tab> {
    focus [tk_focusPrev %W]
}
bind Text <Control-i> {
    tk::TextInsert %W \t
}
bind Text <Return> {
    if {[%W cget -state] eq "normal"} {
	tk::TextInsert %W \n
	if {[%W cget -autoseparators]} {
	    %W edit separator
	}
    }
}
bind Text <Delete> {
    if {[%W cget -state] eq "normal"} {
	if {[tk::TextCursorInSelection %W]} {
	    tk::TextDelete %W sel.first sel.last
	} else {
	    if {[%W compare end != insert+1i]} {
		%W delete [tk::TextPrevPos %W insert+1i tk::startOfCluster] \
			[tk::TextNextPos %W insert tk::endOfCluster]
	    }
	    %W see insert
	}
    }
}
bind Text <BackSpace> {
    if {[%W cget -state] eq "normal"} {
	if {[tk::TextCursorInSelection %W]} {
	    tk::TextDelete %W sel.first sel.last
	} else {
	    if {[%W compare insert != 1.0]} {
		# ensure that this operation is triggering "watch"
		%W mark set insert insert-1i
		%W delete [tk::TextPrevPos %W insert+1i tk::startOfCluster] \
			[tk::TextNextPos %W insert tk::endOfCluster]
	    }
	    %W see insert
	}
    }
}

bind Text <Control-space> {
    %W mark set [tk::TextAnchor %W] insert
}
bind Text <Select> {
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292

293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354


355


356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412



















413
414
415
416
417
418
419
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454



























455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470

471
472




473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491

492
493
494






495

496




497

498
499
500
501
502

503
504
505





506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533


534






535
536
537
538
539
540



541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561






562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
bind Text <<Copy>> {
    tk_textCopy %W
}
bind Text <<Paste>> {
    tk_textPaste %W
}
bind Text <<Clear>> {

    # Make <<Clear>> an atomic operation on the Undo stack,
    # i.e. separate it from other delete operations on either side
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
    catch {%W delete sel.first sel.last}
    if {[%W cget -autoseparators]} {
	%W edit separator

    }
}
bind Text <<PasteSelection>> {
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	    || !$tk::Priv(mouseMoved)} {
	tk::TextPasteSelection %W %x %y
    }
}
bind Text <Insert> {

    catch {tk::TextInsert %W [::tk::GetSelection %W PRIMARY]}

}
bind Text <Key> {
    tk::TextInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for <Escape>.

bind Text <Alt-Key> {# nothing }
bind Text <Meta-Key> {# nothing}
bind Text <Control-Key> {# nothing}
bind Text <Escape> {# nothing}
bind Text <KP_Enter> {# nothing}
if {[tk windowingsystem] eq "aqua"} {
    bind Text <Command-Key> {# nothing}
}


# Additional emacs-like bindings:

bind Text <Control-d> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	%W delete insert
    }
}
bind Text <Control-k> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	if {[%W compare insert == {insert lineend}]} {
	    %W delete insert
	} else {
	    %W delete insert {insert lineend}
	}
    }
}
bind Text <Control-o> {
    if {!$tk_strictMotif} {
	%W insert insert \n
	%W mark set insert insert-1c
    }
}
bind Text <Control-t> {
    if {!$tk_strictMotif} {
	tk::TextTranspose %W
    }
}

bind Text <<Undo>> {
    # An Undo operation may remove the separator at the top of the Undo stack.
    # Then the item at the top of the stack gets merged with the subsequent changes.
    # Place separators before and after Undo to prevent this.
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
    catch { %W edit undo }
    if {[%W cget -autoseparators]} {
	%W edit separator
    }
}

bind Text <<Redo>> {


    catch { %W edit redo }


}

bind Text <Meta-b> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W [tk::TextPrevPos %W insert tcl_startOfPreviousWord]
    }
}
bind Text <Meta-d> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	%W delete insert [tk::TextNextWord %W insert]
    }
}
bind Text <Meta-f> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W [tk::TextNextWord %W insert]
    }
}
bind Text <Meta-less> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W 1.0
    }
}
bind Text <Meta-greater> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W end-1c
    }
}
bind Text <Meta-BackSpace> {
    if {!$tk_strictMotif} {
	%W delete [tk::TextPrevPos %W insert tcl_startOfPreviousWord] insert
    }
}
bind Text <Meta-Delete> {
    if {!$tk_strictMotif} {
	%W delete [tk::TextPrevPos %W insert tcl_startOfPreviousWord] insert
    }
}

# Bindings for IME text input.

bind Text <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Text <<TkEndIMEMarkedText>> {
    if { [catch {dict get $::tk::Priv(IMETextMark) "%W"} mark] } {
	bell
    } else {
	%W tag add IMEmarkedtext $mark insert
	%W tag configure IMEmarkedtext -underline on
    }
}
bind Text <<TkClearIMEMarkedText>> {
    %W delete IMEmarkedtext.first IMEmarkedtext.last
}
bind Text <<TkAccentBackspace>> {
    %W delete insert-1c
}




















# Macintosh only bindings:

if {[tk windowingsystem] eq "aqua"} {
bind Text <Control-v> {
    tk::TextScrollPages %W 1
}

# End of Mac only bindings
}

# A few additional bindings of my own.

bind Text <Control-h> {
    if {!$tk_strictMotif && [%W compare insert != 1.0]} {


	%W delete insert-1c
	%W see insert
    }
}
bind Text <Button-2> {
    if {!$tk_strictMotif} {
	tk::TextScanMark %W %x %y
    }
}
bind Text <B2-Motion> {
    if {!$tk_strictMotif} {
	tk::TextScanDrag %W %x %y
    }
}
set ::tk::Priv(prevPos) {}

bind Text <MouseWheel> {
    tk::MouseWheel %W y %D -3.0 pixels
}
bind Text <Option-MouseWheel> {
    tk::MouseWheel %W y %D -0.3 pixels
}
bind Text <Shift-MouseWheel> {
    tk::MouseWheel %W x %D -3.0 pixels
}
bind Text <Shift-Option-MouseWheel> {
    tk::MouseWheel %W x %D -0.3 pixels



























}

# ::tk::TextClosestGap --
# Given x and y coordinates, this procedure finds the closest boundary
# between characters to the given coordinates and returns the index
# of the character just after the boundary.

#
# Arguments:
# w -		The text window.
# x -		X-coordinate within the window.
# y -		Y-coordinate within the window.

proc ::tk::TextClosestGap {w x y} {
    set pos [$w index @$x,$y]
    set bbox [$w bbox $pos]
    if {$bbox eq ""} {

	return $pos
    }




    if {($x - [lindex $bbox 0]) < ([lindex $bbox 2]/2)} {
	return $pos
    }
    $w index "$pos + 1 char"
}

# ::tk::TextButton1 --
# This procedure is invoked to handle button-1 presses in text
# widgets.  It moves the insertion cursor, sets the selection anchor,
# and claims the input focus.
#
# Arguments:
# w -		The text window in which the button was pressed.
# x -		The x-coordinate of the button press.
# y -		The x-coordinate of the button press.

proc ::tk::TextButton1 {w x y} {
    variable ::tk::Priv


    set Priv(selectMode) char
    set Priv(mouseMoved) 0
    set Priv(pressX) $x






    set anchorname [tk::TextAnchor $w]

    $w mark set insert [TextClosestGap $w $x $y]




    $w mark set $anchorname insert

    # Set the anchor mark's gravity depending on the click position
    # relative to the gap
    set bbox [$w bbox [$w index $anchorname]]
    if {$x > [lindex $bbox 0]} {
	$w mark gravity $anchorname right

    } else {
	$w mark gravity $anchorname left
    }





    focus $w
    if {[$w cget -autoseparators]} {
	$w edit separator
    }
}

# ::tk::TextSelectTo --
# This procedure is invoked to extend the selection, typically when
# dragging it with the mouse.  Depending on the selection mode (character,
# word, line) it selects in different-sized units.  This procedure
# ignores mouse motions initially until the mouse has moved from
# one character to another or until there have been multiple clicks.
#
# Note that the 'anchor' is implemented programmatically using
# a text widget mark, and uses a name that will be unique for each
# text widget (even when there are multiple peers).  Currently the
# anchor is considered private to Tk, hence the name 'tk::anchor$w'.
#
# Arguments:
# w -		The text window in which the button was pressed.
# x -		Mouse x position.
# y - 		Mouse y position.

set ::tk::Priv(textanchoruid) 0

proc ::tk::TextAnchor {w} {
    variable Priv
    if {![info exists Priv(textanchor,$w)]} {


        set Priv(textanchor,$w) tk::anchor[incr Priv(textanchoruid)]






    }
    return $Priv(textanchor,$w)
}

proc ::tk::TextSelectTo {w x y {extend 0}} {
    variable ::tk::Priv




    set anchorname [tk::TextAnchor $w]
    set cur [TextClosestGap $w $x $y]
    if {[catch {$w index $anchorname}]} {
	$w mark set $anchorname $cur
    }
    set anchor [$w index $anchorname]
    if {[$w compare $cur != $anchor] || (abs($Priv(pressX) - $x) >= 3)} {
	set Priv(mouseMoved) 1
    }
    switch -- $Priv(selectMode) {
	char {
	    if {[$w compare $cur < $anchorname]} {
		set first $cur
		set last $anchorname
	    } else {
		set first $anchorname
		set last $cur
	    }
	}
	word {






	    # Set initial range based only on the anchor (1 char min width)
	    if {[$w mark gravity $anchorname] eq "right"} {
		set first $anchorname
		set last "$anchorname + 1c"
	    } else {
		set first "$anchorname - 1c"
		set last $anchorname
	    }
	    # Extend range (if necessary) based on the current point
	    if {[$w compare $cur < $first]} {
		set first $cur
	    } elseif {[$w compare $cur > $last]} {
		set last $cur
	    }

	    # Now find word boundaries
	    set first [TextPrevPos $w "$first + 1c" tcl_wordBreakBefore]
	    set last [TextNextPos $w "$last - 1c" tcl_wordBreakAfter]

	}
	line {
	    # Set initial range based only on the anchor
	    set first "$anchorname linestart"
	    set last "$anchorname lineend"

	    # Extend range (if necessary) based on the current point
	    if {[$w compare $cur < $first]} {
		set first "$cur linestart"
	    } elseif {[$w compare $cur > $last]} {
		set last "$cur lineend"
	    }
	    set first [$w index $first]
	    set last [$w index "$last + 1c"]
	}
    }
    if {$Priv(mouseMoved) || ($Priv(selectMode) ne "char")} {
	$w tag remove sel 0.0 end
	$w mark set insert $cur

	$w tag add sel $first $last
	$w tag remove sel $last end
	update idletasks
    }
}

# ::tk::TextKeyExtend --
# This procedure handles extending the selection from the keyboard,
# where the point to extend to is really the boundary between two
# characters rather than a particular character.
#
# Arguments:
# w -		The text window.
# index -	The point to which the selection is to be extended.

proc ::tk::TextKeyExtend {w index} {

    set anchorname [tk::TextAnchor $w]
    set cur [$w index $index]
    if {[catch {$w index $anchorname}]} {
	$w mark set $anchorname $cur
    }
    set anchor [$w index $anchorname]
    if {[$w compare $cur < $anchorname]} {
	set first $cur
	set last $anchorname
    } else {
	set first $anchorname
	set last $cur
    }
    $w tag remove sel 0.0 $first
    $w tag add sel $first $last
    $w tag remove sel $last end
}

# ::tk::TextPasteSelection --
# This procedure sets the insertion cursor to the mouse position,
# inserts the selection, and sets the focus to the window.
#
# Arguments:
# w -		The text window.
# x, y - 	Position of the mouse.

proc ::tk::TextPasteSelection {w x y} {

    $w mark set insert [TextClosestGap $w $x $y]
    if {![catch {::tk::GetSelection $w PRIMARY} sel]} {
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w configure -autoseparators 0
	    $w edit separator
	}
	$w insert insert $sel
	if {$oldSeparator} {
	    $w edit separator
	    $w configure -autoseparators 1
	}
    }
    if {[$w cget -state] eq "normal"} {
	focus $w
    }
}

# ::tk::TextAutoScan --







>
|
|
|
|
|
|
|
|
>









>
|
>





|









<
|
<
>




|




|








|

|









|
|
|
|
|
|
<
<
<




>
>
|
>
>




|



|















|



|
|



|
|









<
<
<
|
<
<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














|
>
>
|
















|


|


|


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
>









|
>


>
>
>
>
|


|














|
>
|
|
|
>
>
>
>
>
>
|
>
|
>
>
>
>
|
>
|
|
|
|
|
>
|
<
|
>
>
>
>
>
|
<
<












|
<






<
<



>
>
|
>
>
>
>
>
>






>
>
>
|

|
|

















>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
>













|



<

>
















<


|
|









|













>
|
|
<
<
<
<
<
<
<
<
<
<







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

333

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423



424


425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

591
592
593
594
595
596
597


598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616


617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748










749
750
751
752
753
754
755
bind Text <<Copy>> {
    tk_textCopy %W
}
bind Text <<Paste>> {
    tk_textPaste %W
}
bind Text <<Clear>> {
    if {[%W cget -state] eq "normal"} {
	# Make <<Clear>> an atomic operation on the Undo stack,
	# i.e. separate it from other delete operations on either side
	if {[%W cget -autoseparators]} {
	    %W edit separator
	}
	catch { tk::TextDelete %W sel.first sel.last }
	if {[%W cget -autoseparators]} {
	    %W edit separator
	}
    }
}
bind Text <<PasteSelection>> {
    if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
	    || !$tk::Priv(mouseMoved)} {
	tk::TextPasteSelection %W %x %y
    }
}
bind Text <Insert> {
    if {[%W cget -state] eq "normal"} {
	catch {tk::TextInsert %W [::tk::GetSelection %W PRIMARY]}
    }
}
bind Text <Key> {
    tk::TextInsert %W %A
}

# Ignore all Alt, Meta, Control, Command, and Fn keypresses unless explicitly bound.
# Otherwise, if a widget binding for one of these is defined, the
# <Key> class binding will also fire and insert the character,
# which is wrong.  Ditto for <Escape>.

bind Text <Alt-Key> {# nothing }
bind Text <Meta-Key> {# nothing}
bind Text <Control-Key> {# nothing}
bind Text <Escape> {# nothing}
bind Text <KP_Enter> {# nothing}

bind Text <Command-Key> {# nothing}

bind Text <Fn-Key> {# nothing}

# Additional emacs-like bindings:

bind Text <Control-d> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif && [%W compare end != insert+1i]} {
	%W delete insert
    }
}
bind Text <Control-k> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif && [%W compare end != insert+1i]} {
	if {[%W compare insert == {insert lineend}]} {
	    %W delete insert
	} else {
	    %W delete insert {insert lineend}
	}
    }
}
bind Text <Control-o> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif} {
	%W insert insert \n
	%W mark set insert insert-1i
    }
}
bind Text <Control-t> {
    if {!$tk_strictMotif} {
	tk::TextTranspose %W
    }
}

bind Text <<Undo>> {
    if {[%W cget -state] eq "normal"} {
	# NOTE: the undo operation is not merging with subsequent changes, so
	# it is safe to do an undo without setting separators.
	if {[%W edit info -undodepth] > 0} {
	    %W edit undo
	}



    }
}

bind Text <<Redo>> {
    if {[%W cget -state] eq "normal"} {
	if {[%W edit info -redodepth] > 0} {
	    %W edit redo
	}
    }
}

bind Text <Meta-b> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W [tk::TextPrevPos %W insert tk::startOfPreviousWord]
    }
}
bind Text <Meta-d> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif && [%W compare end != insert+1i]} {
	%W delete insert [tk::TextNextWord %W insert]
    }
}
bind Text <Meta-f> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W [tk::TextNextWord %W insert]
    }
}
bind Text <Meta-less> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W 1.0
    }
}
bind Text <Meta-greater> {
    if {!$tk_strictMotif} {
	tk::TextSetCursor %W end-1i
    }
}
bind Text <Meta-BackSpace> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif} {
	tk::TextDelete %W [tk::TextPrevPos %W insert tk::startOfPreviousWord] insert
    }
}
bind Text <Meta-Delete> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif} {
	tk::TextDelete %W [tk::TextPrevPos %W insert tk::startOfPreviousWord] insert
    }
}

# Bindings for IME text input.

bind Text <<TkStartIMEMarkedText>> {
    dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
}
bind Text <<TkEndIMEMarkedText>> {



    ::tk::TextEndIMEMarkedText %W


}
bind Text <<TkClearIMEMarkedText>> {
    %W delete IMEmarkedtext.first IMEmarkedtext.last
}
bind Text <<TkAccentBackspace>> {
    %W delete insert-1c
}

# ::tk::TextEndIMEMarkedText --
#
# Handles input method text marking in a text widget.
#
# Arguments:
# w -	The text widget

proc ::tk::TextEndIMEMarkedText {w} {
    variable Priv
    if {[catch {
	set mark [dict get $Priv(IMETextMark) $w]
    }]} {
	bell
	return
    }
    $w tag add IMEmarkedtext $mark insert
    $w tag configure IMEmarkedtext -underline 1
}

# Macintosh only bindings:

if {[tk windowingsystem] eq "aqua"} {
bind Text <Control-v> {
    tk::TextScrollPages %W 1
}

# End of Mac only bindings
}

# A few additional bindings of my own.

bind Text <Control-h> {
    if {[%W cget -state] eq "normal" && !$tk_strictMotif && [%W compare insert != 1.0]} {
	# ensure that this operation is triggering "watch"
	%W mark set insert insert-1i
	%W delete insert
	%W see insert
    }
}
bind Text <Button-2> {
    if {!$tk_strictMotif} {
	tk::TextScanMark %W %x %y
    }
}
bind Text <B2-Motion> {
    if {!$tk_strictMotif} {
	tk::TextScanDrag %W %x %y
    }
}
set ::tk::Priv(prevPos) {}

bind Text <MouseWheel> {
    tk::MouseWheel %W y [tk::ScaleNum %D] -4.0 pixels
}
bind Text <Option-MouseWheel> {
    tk::MouseWheel %W y [tk::ScaleNum %D] -1.2 pixels
}
bind Text <Shift-MouseWheel> {
    tk::MouseWheel %W x [tk::ScaleNum %D] -4.0 pixels
}
bind Text <Shift-Option-MouseWheel> {
    tk::MouseWheel %W x [tk::ScaleNum %D] -1.2 pixels
}
bind Text <TouchpadScroll> {
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    if {$deltaX != 0} {
	%W xview scroll [tk::ScaleNum [expr {-$deltaX}]] pixels
    }
    if {$deltaY != 0} {
	%W yview scroll [tk::ScaleNum [expr {-$deltaY}]] pixels
    }
}

# ::tk::TextCursorPos --
# Given x and y coordinates, this procedure computes the "cursor"
# position, and returns the index of the character at this position.
#
# Arguments:
# w -		The text window.
# x -		X-coordinate within the window.
# y -		Y-coordinate within the window.

proc ::tk::TextCursorPos {w x y} {
    if {[$w cget -blockcursor]} {
	# If we have a block cursor, then use the actual x-position
	# for cursor position.
	return [$w index @$x,$y]
    }
    return [TextClosestGap $w $x $y]
}

# ::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, except at display line end
# where it returns that index.
#
# Arguments:
# w -		The text window.
# x -		X-coordinate within the window.
# y -		Y-coordinate within the window.

proc ::tk::TextClosestGap {w x y} {
    set pos [$w index @$x,$y]
    set bbox [$w bbox $pos]
    if {($bbox eq "")
            || ([$w compare $pos == "$pos display lineend"] == 1)} {
	return $pos
    }
    # The check on y coord of the line bbox with dlineinfo is to fix
    # [a9cf210a42] to properly handle selecting and moving the mouse
    # out of the widget.
    if {$y < [lindex [$w dlineinfo $pos] 1] ||
            $x - [lindex $bbox 0] < [lindex $bbox 2]/2} {
	return $pos
    }
    $w index "$pos + 1i"
}

# ::tk::TextButton1 --
# This procedure is invoked to handle button-1 presses in text
# widgets.  It moves the insertion cursor, sets the selection anchor,
# and claims the input focus.
#
# Arguments:
# w -		The text window in which the button was pressed.
# x -		The x-coordinate of the button press.
# y -		The x-coordinate of the button press.

proc ::tk::TextButton1 {w x y} {
    variable ::tk::Priv
    # Catch the very special case with dead peers.
    if {![$w isdead]} {
	set Priv(selectMode) char
	set Priv(mouseMoved) 0
	set Priv(pressX) $x
	set pos [TextCursorPos $w $x $y]
	set thisLineNo [$w lineno @last,$y]
	if {[$w lineno $pos] == [expr {$thisLineNo + 1}]} {
	    # The button has been pressed at an x position after last character.
	    # In this case [$w index @$x,$y] is returning the start of next line,
	    # but we want the end of this line.
	    set pos "$thisLineNo.end"
	}
	$w mark set insert $pos
	if {[$w cget -blockcursor]} {
	    set anchor [TextClosestGap $w $x $y]
	} else {
	    # this is already the closest gap
	    set anchor insert
	}
	# Set the anchor mark's gravity depending on the click position
	# relative to the gap.
	set bbox [$w bbox $anchor]
	set gravity [expr {$x > [lindex $bbox 0] ? "right" : "left"}]
	$w mark set [TextAnchor $w] $anchor $gravity
	if {[$w cget -state] eq "normal" && [$w cget -autoseparators]} {
	    $w edit separator

	}
    }

    # 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


    }
}

# ::tk::TextSelectTo --
# This procedure is invoked to extend the selection, typically when
# dragging it with the mouse.  Depending on the selection mode (character,
# word, line) it selects in different-sized units.  This procedure
# ignores mouse motions initially until the mouse has moved from
# one character to another or until there have been multiple clicks.
#
# Note that the 'anchor' is implemented programmatically using
# a text widget mark, and uses a name that will be unique for each
# text widget (even when there are multiple peers).

#
# Arguments:
# w -		The text window in which the button was pressed.
# x -		Mouse x position.
# y - 		Mouse y position.



proc ::tk::TextAnchor {w} {
    variable Priv
    if {![info exists Priv(textanchor,$w)]} {
	# This gives us a private mark, not visible with
	# "mark names|next|previous|..".
	set Priv(textanchor,$w) [$w mark generate]
	# The Tk library still has a big weakness: it's not possible to
	# bind variables to a widget, so we use a private command for this
	# binding; this means that the variable will be unset automatically
	# when the widget will be destroyed. This is the only proper way to
	# handle unique identifiers.
	$w tk_bindvar [namespace current]::Priv(textanchor,$w)
    }
    return $Priv(textanchor,$w)
}

proc ::tk::TextSelectTo {w x y {extend 0}} {
    variable ::tk::Priv
    if {[$w isdead]} {
	# Catch the very special case with dead peers.
	return
    }
    set anchorname [tk::TextAnchor $w]
    set cur [TextCursorPos $w $x $y]
    if {![$w mark exists $anchorname]} {
	$w mark set $anchorname $cur
    }
    set anchor [$w index $anchorname]
    if {[$w compare $cur != $anchor] || (abs($Priv(pressX) - $x) >= 3)} {
	set Priv(mouseMoved) 1
    }
    switch -- $Priv(selectMode) {
	char {
	    if {[$w compare $cur < $anchorname]} {
		set first $cur
		set last $anchorname
	    } else {
		set first $anchorname
		set last $cur
	    }
	}
	word {
	    set first [$w index @$x,$y]
	    set isEmbedded [expr {[string length [$w get $first]] == 0}]
	    if {$isEmbedded} {
		# Don't extend the range if we have an embedded item at this position
		set last "$first+1i"
	    } else {
		# Set initial range based only on the anchor (1 char min width)
		if {[$w mark gravity $anchorname] eq "right"} {
		    set first $anchorname
		    set last "$anchorname + 1i"
		} else {
		    set first "$anchorname - 1i"
		    set last $anchorname
		}
		# Extend range (if necessary) based on the current point
		if {[$w compare $cur < $first]} {
		    set first $cur
		} elseif {[$w compare $cur > $last]} {
		    set last $cur
		}

		# Now find word boundaries
		set first [TextPrevPos $w "$first + 1i" tk::wordBreakBefore]
		set last [TextNextPos $w "$last - 1i" tk::wordBreakAfter]
	    }
	}
	line {
	    # Set initial range based only on the anchor
	    set first "$anchorname linestart"
	    set last "$anchorname lineend"

	    # Extend range (if necessary) based on the current point
	    if {[$w compare $cur < $first]} {
		set first "$cur linestart"
	    } elseif {[$w compare $cur > $last]} {
		set last "$cur lineend"
	    }
	    set first [$w index $first]
	    set last [$w index "$last + 1i"]
	}
    }
    if {$Priv(mouseMoved) || ($Priv(selectMode) ne "char")} {

	$w mark set insert $cur
	$w tag remove sel 1.0 $first
	$w tag add sel $first $last
	$w tag remove sel $last end
	update idletasks
    }
}

# ::tk::TextKeyExtend --
# This procedure handles extending the selection from the keyboard,
# where the point to extend to is really the boundary between two
# characters rather than a particular character.
#
# Arguments:
# w -		The text window.
# index -	The point to which the selection is to be extended.

proc ::tk::TextKeyExtend {w index} {

    set anchorname [tk::TextAnchor $w]
    set cur [$w index $index]
    if {![$w mark exists $anchorname]} {
	$w mark set $anchorname $cur left
    }
    set anchor [$w index $anchorname]
    if {[$w compare $cur < $anchorname]} {
	set first $cur
	set last $anchorname
    } else {
	set first $anchorname
	set last $cur
    }
    $w tag remove sel 1.0 $first
    $w tag add sel $first $last
    $w tag remove sel $last end
}

# ::tk::TextPasteSelection --
# This procedure sets the insertion cursor to the mouse position,
# inserts the selection, and sets the focus to the window.
#
# Arguments:
# w -		The text window.
# x, y - 	Position of the mouse.

proc ::tk::TextPasteSelection {w x y} {
    if {[$w cget -state] eq "normal"} {
	$w mark set insert [TextCursorPos $w $x $y]
	TextInsertSelection $w PRIMARY










    }
    if {[$w cget -state] eq "normal"} {
	focus $w
    }
}

# ::tk::TextAutoScan --
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724




725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
#
# Arguments:
# w -		The text window.
# pos -		The desired new position for the cursor in the window.

proc ::tk::TextSetCursor {w pos} {
    if {[$w compare $pos == end]} {
	set pos {end - 1 chars}
    }
    $w mark set insert $pos
    $w tag remove sel 1.0 end
    $w see insert
    if {[$w cget -autoseparators]} {
	$w edit separator
    }
}

# ::tk::TextKeySelect
# This procedure is invoked when stroking out selections using the
# keyboard.  It moves the cursor to a new position, then extends
# the selection to that position.
#
# Arguments:
# w -		The text window.
# new -		A new position for the insertion cursor (the cursor hasn't
#		actually been moved to this position yet).

proc ::tk::TextKeySelect {w new} {




    set anchorname [tk::TextAnchor $w]
    if {[$w tag nextrange sel 1.0 end] eq ""} {
	if {[$w compare $new < insert]} {
	    $w tag add sel $new insert
	} else {
	    $w tag add sel insert $new
	}
	$w mark set $anchorname insert
    } else {
        if {[catch {$w index $anchorname}]} {
            $w mark set $anchorname insert
        }
	if {[$w compare $new < $anchorname]} {
	    set first $new
	    set last $anchorname
	} else {
	    set first $anchorname
	    set last $new
	}







|




















>
>
>
>









<
<
<







791
792
793
794
795
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
#
# Arguments:
# w -		The text window.
# pos -		The desired new position for the cursor in the window.

proc ::tk::TextSetCursor {w pos} {
    if {[$w compare $pos == end]} {
	set pos {end - 1i}
    }
    $w mark set insert $pos
    $w tag remove sel 1.0 end
    $w see insert
    if {[$w cget -autoseparators]} {
	$w edit separator
    }
}

# ::tk::TextKeySelect
# This procedure is invoked when stroking out selections using the
# keyboard.  It moves the cursor to a new position, then extends
# the selection to that position.
#
# Arguments:
# w -		The text window.
# new -		A new position for the insertion cursor (the cursor hasn't
#		actually been moved to this position yet).

proc ::tk::TextKeySelect {w new} {
    if {[$w isdead]} {
	# Catch the very special case with dead peers.
	return
    }
    set anchorname [tk::TextAnchor $w]
    if {[$w tag nextrange sel 1.0 end] eq ""} {
	if {[$w compare $new < insert]} {
	    $w tag add sel $new insert
	} else {
	    $w tag add sel insert $new
	}
	$w mark set $anchorname insert
    } else {



	if {[$w compare $new < $anchorname]} {
	    set first $new
	    set last $anchorname
	} else {
	    set first $anchorname
	    set last $new
	}
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
# Check whether the selection exists and contains the insertion cursor. Note
# that it assumes that the selection is contiguous.
#
# Arguments:
# w -		The text widget whose selection is to be checked

proc ::tk::TextCursorInSelection {w} {
    expr {
	[llength [$w tag ranges sel]]
	&& [$w compare sel.first <= insert]
	&& [$w compare sel.last >= insert]
    }
}

# ::tk::TextInsert --
# Insert a string into a text at the point of the insertion cursor.
# If there is a selection in the text, and it covers the point of the
# insertion cursor, then delete the selection before inserting.
#
# Arguments:
# w -		The text window in which to insert the string
# s -		The string to insert (usually just a single character)

proc ::tk::TextInsert {w s} {
    if {$s eq "" || [$w cget -state] eq "disabled"} {
	return
    }
    set compound 0
    if {[TextCursorInSelection $w]} {
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w configure -autoseparators 0
	    $w edit separator
	    set compound 1
	}


	$w delete sel.first sel.last
    }
    $w insert insert $s
    $w see insert
    if {$compound && $oldSeparator} {
	$w edit separator
	$w configure -autoseparators 1
    }

}

# ::tk::TextUpDownLine --
# Returns the index of the character one display line above or below the
# insertion cursor.  There is a tricky thing here: we want to maintain the
# original x position across repeated operations, even though some lines
# that will get passed through don't have enough characters to cover the







<
|















|


<

|
<
<

<

>
>
|
|
|
<
<
<
<

>







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
# Check whether the selection exists and contains the insertion cursor. Note
# that it assumes that the selection is contiguous.
#
# Arguments:
# w -		The text widget whose selection is to be checked

proc ::tk::TextCursorInSelection {w} {

    expr {[$w tag ranges sel] ne ""
	&& [$w compare sel.first <= insert]
	&& [$w compare sel.last >= insert]
    }
}

# ::tk::TextInsert --
# Insert a string into a text at the point of the insertion cursor.
# If there is a selection in the text, and it covers the point of the
# insertion cursor, then delete the selection before inserting.
#
# Arguments:
# w -		The text window in which to insert the string
# s -		The string to insert (usually just a single character)

proc ::tk::TextInsert {w s} {
    if {$s eq "" || [$w cget -state] ne "normal"} {
	return
    }

    if {[TextCursorInSelection $w]} {
	if {[$w cget -autoseparators]} {


	    $w edit separator

	}
	# ensure that this operation is triggering "watch"
	$w mark set insert sel.first
	$w replace insert sel.last $s
    } else {
	$w insert insert $s




    }
    $w see insert
}

# ::tk::TextUpDownLine --
# Returns the index of the character one display line above or below the
# insertion cursor.  There is a tricky thing here: we want to maintain the
# original x position across repeated operations, even though some lines
# that will get passed through don't have enough characters to cover the
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
# Arguments:
# w -		The text window in which the cursor is to move.
# pos -		Position at which to start search.

proc ::tk::TextPrevPara {w pos} {
    set pos [$w index "$pos linestart"]
    while {1} {

	if {([$w get "$pos - 1 line"] eq "\n" && ([$w get $pos] ne "\n")) \
		|| $pos eq "1.0"} {
	    if {[regexp -indices -- {^[ \t]+(.)} \
		    [$w get $pos "$pos lineend"] -> index]} {
		set pos [$w index "$pos + [lindex $index 0] chars"]
	    }
	    if {[$w compare $pos != insert] || [lindex [split $pos .] 0]==1} {
		return $pos
	    }
	}
	set pos [$w index "$pos - 1 line"]
    }
}

# ::tk::TextNextPara --
# Returns the index of the beginning of the paragraph just after a given
# position in the text (the beginning of a paragraph is the first non-blank
# character after a blank line).
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::TextNextPara {w start} {
    set pos [$w index "$start linestart + 1 line"]
    while {[$w get $pos] ne "\n"} {
	if {[$w compare $pos == end]} {
	    return [$w index "end - 1c"]
	}
	set pos [$w index "$pos + 1 line"]
    }
    while {[$w get $pos] eq "\n"} {
	set pos [$w index "$pos + 1 line"]
	if {[$w compare $pos == end]} {
	    return [$w index "end - 1c"]
	}
    }
    if {[regexp -indices -- {^[ \t]+(.)} \
	    [$w get $pos "$pos lineend"] -> index]} {
	return [$w index "$pos + [lindex $index 0] chars"]
    }
    return $pos







>
|
<
|
<


|



|
















|






|







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
# Arguments:
# w -		The text window in which the cursor is to move.
# pos -		Position at which to start search.

proc ::tk::TextPrevPara {w pos} {
    set pos [$w index "$pos linestart"]
    while {1} {
	set newPos [$w index "$pos - 1 line"]
	if {([$w get $newPos] eq "\n" && ([$w get $pos] ne "\n")) || [$w compare $pos == 1.0]} {

	    if {[regexp -indices -- {^[ \t]+(.)} [$w get $pos "$pos lineend"] -> index]} {

		set pos [$w index "$pos + [lindex $index 0] chars"]
	    }
	    if {[$w compare $pos != insert] || [$w compare [$w index "$pos linestart"] == 1.0]} {
		return $pos
	    }
	}
	set pos $newPos
    }
}

# ::tk::TextNextPara --
# Returns the index of the beginning of the paragraph just after a given
# position in the text (the beginning of a paragraph is the first non-blank
# character after a blank line).
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::TextNextPara {w start} {
    set pos [$w index "$start linestart + 1 line"]
    while {[$w get $pos] ne "\n"} {
	if {[$w compare $pos == end]} {
	    return [$w index "end - 1i"]
	}
	set pos [$w index "$pos + 1 line"]
    }
    while {[$w get $pos] eq "\n"} {
	set pos [$w index "$pos + 1 line"]
	if {[$w compare $pos == end]} {
	    return [$w index "end - 1i"]
	}
    }
    if {[regexp -indices -- {^[ \t]+(.)} \
	    [$w get $pos "$pos lineend"] -> index]} {
	return [$w index "$pos + [lindex $index 0] chars"]
    }
    return $pos
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
#
# Arguments:
# w -		The text window in which the cursor is to move.
# count -	Number of pages forward to scroll;  may be negative
#		to scroll backwards.

proc ::tk::TextScrollPages {w count} {

























    set bbox [$w bbox insert]
    $w yview scroll $count pages
    if {$bbox eq ""} {
	return [$w index @[expr {[winfo height $w]/2}],0]


    }





    return [$w index @[lindex $bbox 0],[lindex $bbox 1]]
}

# ::tk::TextTranspose --
# This procedure implements the "transpose" function for text widgets.
# It tranposes the characters on either side of the insertion cursor,
# unless the cursor is at the end of the line.  In this case it
# transposes the two characters to the left of the cursor.  In either
# case, the cursor ends up to the right of the transposed characters.
#
# Arguments:
# w -		Text window in which to transpose.

proc ::tk::TextTranspose w {
    set pos insert
    if {[$w compare $pos != "$pos lineend"]} {
	set pos [$w index "$pos + 1 char"]
    }
    set new [$w get "$pos - 1 char"][$w get  "$pos - 2 char"]
    if {[$w compare "$pos - 1 char" == 1.0]} {
	return
    }
    # ensure this is seen as an atomic op to undo
    set autosep [$w cget -autoseparators]

    if {$autosep} {
	$w configure -autoseparators 0
	$w edit separator
    }
    $w delete "$pos - 2 char" $pos





    $w insert insert $new
    $w see insert
    if {$autosep} {
	$w edit separator
	$w configure -autoseparators $autosep
    }
}

# ::tk_textCopy --
# This procedure copies the selection from a text widget into the
# clipboard.
#
# Arguments:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
>
>

>
>
>
>
>
|













<
|
<
<
<
<


<
|
>
|
<
<

|
>
>
>
>
>
|

<
<
<
<







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
#
# Arguments:
# w -		The text window in which the cursor is to move.
# count -	Number of pages forward to scroll;  may be negative
#		to scroll backwards.

proc ::tk::TextScrollPages {w count} {
    if {$count > 0} {
	if {[llength [$w dlineinfo end-1c]]} {
	    # Last display line of very last line is visible.
	    if {[llength [set res [$w dlineinfo -extents @first,last]]]} {
		if {[lindex $res 3] == 0} {
		    # Line is fully visible (vertically), so nothing to do.
		    return insert
		}
		# Line is only partially visible, so jump to this line.
		return [$w index "insert +[$w count -displaylines insert end-1c] displayline"]
	    }
	}
    } else {
	if {[llength [$w dlineinfo 1.0]]} {
	    # First display line of very first line is visible.
	    if {[llength [set res [$w dlineinfo -extents @first,0]]]} {
		if {[lindex $res 1] == 0} {
		    # Line is fully visible (vertically), so nothing to do.
		    return insert
		}
		# Line is not fully visible, so jump to first line.
		return [$w index "insert -[$w count -displaylines 1.0 insert] displayline"]
	    }
	}
    }
    set bbox [$w bbox insert]
    $w yview scroll $count pages
    if {[llength $bbox] == 0} {
	set newPos [$w index @[expr {[winfo height $w]/2}],0]
    } else {
	set newPos [$w index @[lindex $bbox 0],[lindex $bbox 1]]
    }
    if {[$w compare insert == $newPos]} {
	# This may happen if a character is spanning the entire view,
	# ensure that at least one line will change.
	set newPos [$w index "[expr {$count > 0 ? "insert +1" : "insert -1"}] displayline"]
    }
    return $newPos
}

# ::tk::TextTranspose --
# This procedure implements the "transpose" function for text widgets.
# It tranposes the characters on either side of the insertion cursor,
# unless the cursor is at the end of the line.  In this case it
# transposes the two characters to the left of the cursor.  In either
# case, the cursor ends up to the right of the transposed characters.
#
# Arguments:
# w -		Text window in which to transpose.

proc ::tk::TextTranspose w {

    if {[$w cget -state] ne "normal" || [$w compare insert == 1.0]} {




	return
    }

    set pos insert
    if {[$w compare insert != "insert lineend"]} {
	append pos +1i


    }
    set pos [$w index $pos]
    # ensure that this operation is triggering "watch"
    set insPos [$w index insert]
    $w mark set insert ${pos}-2c
    set new [$w get insert+1i][$w get insert]
    $w replace insert $pos $new
    $w mark set insert $insPos
    $w see insert




}

# ::tk_textCopy --
# This procedure copies the selection from a text widget into the
# clipboard.
#
# Arguments:
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
# widget).
#
# Arguments:
# w -		Name of a text widget.

proc ::tk_textCut w {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        # make <<Cut>> an atomic operation on the Undo stack,
        # i.e. separate it from other delete operations on either side
	set oldSeparator [$w cget -autoseparators]
	if {([$w cget -state] eq "normal") && $oldSeparator} {
	    $w edit separator
	}
	clipboard clear -displayof $w
	clipboard append -displayof $w $data

	$w delete sel.first sel.last

	if {([$w cget -state] eq "normal") && $oldSeparator} {
	    $w edit separator
	}
    }
}

# ::tk_textPaste --
# This procedure pastes the contents of the clipboard to the insertion
# point in a text widget.
#
# Arguments:
# w -		Name of a text widget.

proc ::tk_textPaste w {

    if {![catch {::tk::GetSelection $w CLIPBOARD} sel]} {
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w configure -autoseparators 0
	    $w edit separator
	}
	if {[tk windowingsystem] ne "x11"} {
	    catch { $w delete sel.first sel.last }
	}
	$w insert insert $sel
	if {$oldSeparator} {
	    $w edit separator
	    $w configure -autoseparators 1
	}







    }



}

# ::tk::TextNextWord --
# Returns the index of the next word position after a given position in the
# text.  The next word is platform dependent and may be either the next
# end-of-word position or the next start-of-word position after the next
# end-of-word position.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.

if {[tk windowingsystem] eq "win32"}  {
    proc ::tk::TextNextWord {w start} {
	TextNextPos $w [TextNextPos $w $start tcl_endOfWord] \
		tcl_startOfNextWord
    }
} else {
    proc ::tk::TextNextWord {w start} {
	TextNextPos $w $start tcl_endOfWord
    }
}

# ::tk::TextNextPos --
# Returns the index of the next position after the given starting
# position in the text as computed by a specified function.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.
# op -		Function to use to find next position.

proc ::tk::TextNextPos {w start op} {
    set text ""
    set cur $start
    while {[$w compare $cur < end]} {

	set text $text[$w get -displaychars $cur "$cur lineend + 1c"]
	set pos [$op $text 0]
	if {$pos >= 0} {
	    return [$w index "$start + $pos display chars"]
	}
	set cur [$w index "$cur lineend +1c"]
    }
    return end
}

# ::tk::TextPrevPos --
# Returns the index of the previous position before the given starting
# position in the text as computed by a specified function.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.
# op -		Function to use to find next position.

proc ::tk::TextPrevPos {w start op} {
    set text ""
    set cur $start
    while {[$w compare $cur > 0.0]} {

	set text [$w get -displaychars "$cur linestart - 1c" $cur]$text
	set pos [$op $text end]
	if {$pos >= 0} {
	    return [$w index "$cur linestart - 1c + $pos display chars"]
	}
	set cur [$w index "$cur linestart - 1c"]

    }
    return 0.0
}

# ::tk::TextScanMark --
#
# Marks the start of a possible scan drag operation
#
# Arguments:







|
|
<
|




>
|
>
|













>
|
<
<
<
<
|
<
<
|
<
<
<
<
|
>
>
>
>
>
>
>
|
>
>
>


|
|
<
<
|





<
|
<
<
<
<
<
|
|
|














>
|




|














|

|
>
|


|

|
>

|







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
# widget).
#
# Arguments:
# w -		Name of a text widget.

proc ::tk_textCut w {
    if {![catch {set data [$w get sel.first sel.last]}]} {
	# make <<Cut>> an atomic operation on the Undo stack,
	# i.e. separate it from other delete operations on either side

	if {[$w cget -autoseparators] && ([$w cget -state] eq "normal")} {
	    $w edit separator
	}
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	if {[$w cget -state] eq "normal"} {
	    ::tk::TextDelete $w sel.first sel.last
	}
	if {[$w cget -autoseparators] && ([$w cget -state] eq "normal")} {
	    $w edit separator
	}
    }
}

# ::tk_textPaste --
# This procedure pastes the contents of the clipboard to the insertion
# point in a text widget.
#
# Arguments:
# w -		Name of a text widget.

proc ::tk_textPaste w {
    if {[$w cget -state] eq "normal"} {
	::tk::TextInsertSelection $w CLIPBOARD




    }


}





# ::tk::TextNextWord --
# Returns the index of the next start-of-word position after the next
# end-of-word position after a given position in the text.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::TextNextWord {w start} {
    TextNextPos $w [TextNextPos $w $start tk::endOfWord] \
	    tk::startOfNextWord
}

# ::tk::TextSelectNextWord --
# Returns the index of the next end-of-word position after a given


# position in the text.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.


proc ::tk::TextSelectNextWord {w start} {





    TextNextPos $w $start tk::endOfWord
}


# ::tk::TextNextPos --
# Returns the index of the next position after the given starting
# position in the text as computed by a specified function.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.
# op -		Function to use to find next position.

proc ::tk::TextNextPos {w start op} {
    set text ""
    set cur $start
    while {[$w compare $cur < end]} {
	set end [$w index "$cur lineend + 1i"]
	append text [$w get -displaychars $cur $end]
	set pos [$op $text 0]
	if {$pos >= 0} {
	    return [$w index "$start + $pos display chars"]
	}
	set cur $end
    }
    return end
}

# ::tk::TextPrevPos --
# Returns the index of the previous position before the given starting
# position in the text as computed by a specified function.
#
# Arguments:
# w -		The text window in which the cursor is to move.
# start -	Position at which to start search.
# op -		Function to use to find next position.

proc ::tk::TextPrevPos {w start op} {
    set succ ""
    set cur $start
    while {[$w compare $cur > 1.0]} {
	set text ""
	append text [$w get -displaychars "$cur linestart - 1i" $cur] $succ
	set pos [$op $text end]
	if {$pos >= 0} {
	    return [$w index "$cur linestart - 1i + $pos display chars"]
	}
	set cur [$w index "$cur linestart - 1i"]
	set succ $text
    }
    return 1.0
}

# ::tk::TextScanMark --
#
# Marks the start of a possible scan drag operation
#
# Arguments:
1163
1164
1165
1166
1167
1168
1169
1170
1171



1172
1173

1174






1175


1176


1177
1178
1179

1180
1181

1182
1183
1184
1185
1186
1187

1188
1189


1190




1191

1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204



1205

1206
1207
1208


1209

1210
1211
1212
1213
1214

1215
1216
1217
1218
1219
1220











1221
1222
1223
1224

1225


1226



1227








1228








1229


1230

1231

1232
1233
1234
1235





1236
1237

1238
1239


1240
1241
1242
1243
1244
1245
1246

1247

1248
1249



1250


1251
1252
1253
1254
1255
1256


1257


1258
1259
1260


1261
1262


    if {($x != $Priv(x)) || ($y != $Priv(y))} {
	set Priv(mouseMoved) 1
    }
    if {[info exists Priv(mouseMoved)] && $Priv(mouseMoved)} {
	$w scan dragto $x $y
    }
}
# ::tk::TextUndoRedoProcessMarks --
#



# This proc is executed after an undo or redo action.
# It processes the list of undo/redo marks temporarily set in the

# text widget to positions delimiting where changes happened, and






# returns a flat list of ranges. The temporary marks are removed


# from the text widget.


#
# Arguments:
# w -	The text widget


proc ::tk::TextUndoRedoProcessMarks {w} {

    set indices {}
    set undoMarks {}

    # only consider the temporary marks set by an undo/redo action
    foreach mark [$w mark names] {
        if {[string range $mark 0 11] eq "tk::undoMark"} {

            lappend undoMarks $mark
        }


    }






    # transform marks into indices
    # the number of undo/redo marks is always even, each right mark
    # completes a left mark to give a range
    # this is true because:
    #   - undo/redo only deals with insertions and deletions of text
    #   - insertions may move marks but not delete them
    #   - when deleting text, marks located inside the deleted range
    #     are not erased but moved to the start of the deletion range

    #         . this is done in TkBTreeDeleteIndexRange ("This segment
    #           refuses to die...")
    #         . because MarkDeleteProc does nothing else than returning
    #           a value indicating that marks are not deleted by this
    #           deleteProc



    #         . mark deletion rather happen through [.text mark unset xxx]

    #           which was not used _up to this point of the code_ (it
    #           is a bit later just before exiting the present proc)
    set nUndoMarks [llength $undoMarks]


    set n [expr {$nUndoMarks / 2}]

    set undoMarks [lsort -dictionary $undoMarks]
    if {$n > 0} {
	set Lmarks [lrange $undoMarks 0 [expr {$n - 1}]]
    } else {
	set Lmarks {}

    }
    set Rmarks [lrange $undoMarks $n [llength $undoMarks]]
    foreach Lmark $Lmarks Rmark $Rmarks {
        lappend indices [$w index $Lmark] [$w index $Rmark]
        $w mark unset $Lmark $Rmark
    }












    # process ranges to:
    #   - remove those already fully included in another range
    #   - merge overlapping ranges

    set ind [lsort -dictionary -stride 2 $indices]


    set indices {}












    for {set i 0} {$i < $nUndoMarks} {incr i 2} {








        set il1 [lindex $ind $i]


        set ir1 [lindex $ind [expr {$i + 1}]]

        lappend indices $il1 $ir1


        for {set j [expr {$i + 2}]} {$j < $nUndoMarks} {incr j 2} {
            set il2 [lindex $ind $j]
            set ir2 [lindex $ind [expr {$j + 1}]]






            if {[$w compare $il2 > $ir1]} {

                # second range starts after the end of first range
                # -> further second ranges do not need to be considered


                #    because ranges were sorted by increasing first index
                set j $nUndoMarks
            } else {
                if {[$w compare $ir2 > $ir1]} {
                    # second range overlaps first range
                    # -> merge them into a single range
                    set indices [lreplace $indices end-1 end]

                    lappend indices $il1 $ir2

                } else {
                    # second range is fully included in first range



                    # -> ignore it


                }
                # in both cases above, the second range shall be
                # trimmed out from the list of ranges
                set ind [lreplace $ind $j [expr {$j + 1}]]
                incr j -2
                incr nUndoMarks -2


            }


        }
    }



    return $indices
}









|

>
>
>
|
|
>
|
>
>
>
>
>
>
|
>
>
|
>
>


|
>

|
>
|
<
|
<
|
|
>
|
|
>
>

>
>
>
>
|
>
|
<
<
<
|
|
<
<
>
|
|
|
|
|
>
>
>
|
>
|
<
<
>
>
|
>
|
<
<
|
|
>
|
<
<
<
<
|
>
>
>
>
>
>
>
>
>
>
>

|
<
<
>
|
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
|
>
|
>
|
|
<
<
>
>
>
>
>

<
>
|
|
>
>
|
<
<
|
<
<
<
>
|
>
|
|
>
>
>
|
>
>
|
<
<
<
<
|
>
>
|
>
>
|


>
>
|

>
>
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
    if {($x != $Priv(x)) || ($y != $Priv(y))} {
	set Priv(mouseMoved) 1
    }
    if {[info exists Priv(mouseMoved)] && $Priv(mouseMoved)} {
	$w scan dragto $x $y
    }
}
# ::tk::TextDelete --
#
# Delete the characters in given range.
# Ensure that "watch" will be triggered, and consider
# that "insert" may be involved in the given range.
# This implementation avoids unnecessary mappings of indices.

proc ::tk::TextDelete {w start end} {
    # Remember old positions, use temporary marks ('mark generate'),
    # take into account that $end may refer "insert" mark.
    $w mark set [set insPos [$w mark generate]] insert
    $w mark set [set endPos [$w mark generate]] $end
    $w mark set insert $start
    $w delete insert $endPos
    $w mark set insert $insPos
    $w mark unset $insPos
    $w mark unset $endPos
}

# ::tk::TextInsertSelection --
# This procedure inserts the selection.
#
# Arguments:
# w -		The text window.
# selection	atom name of the selection

proc ::tk::TextInsertSelection {w selection} {
    if {[catch {GetSelection $w $selection} sel]} {
	return

    }

    set oldSeparator [$w cget -autoseparators]
    if {$oldSeparator} {
	$w configure -autoseparators 0
	$w edit separator
    }
    if {$selection eq "CLIPBOARD" && [tk windowingsystem] ne "x11"} {
	catch { TextDelete $w sel.first sel.last }
    }
    $w insert insert $sel
    if {$oldSeparator} {
	$w edit separator
	$w configure -autoseparators 1
    }
}




# ::tk_textInsert --
# This procedure supports the insertion of text with hyphen information.


#
# Arguments:
# w -		The text window.
# args -	Arguments for text insertion.

proc ::tk_textInsert {w args} {
    # Use an internal command:
    uplevel [list $w tk_textInsert {*}$args]
}

# ::tk_textReplace --
# This procedure supports the replacement of text with hyphen information.


#
# Arguments:
# w -		The text window.
# args -	Arguments for text insertion.



proc ::tk_textReplace {w args} {
    # Use an internal command:
    uplevel [list $w tk_textReplace {*}$args]
}





# ::tk_textRebindMouseWheel --
# This procedure is rebinding the mouse wheel events of the embedded
# window to the container (the text widget). This is a quite important
# convenience function, because the user might not be interested in
# the internal handlings.
#
# Arguments:
# text -	The container (text widget), send mouse wheel events
#		to this container.
# args -	Zero or more embedded windows. If none is specified,
#		then rebind all the windows that are currently embedded.

proc tk_textRebindMouseWheel {w args} {


    if {[llength $args] == 0} {
	set args [$w window names]
    }
    foreach ew $args {
	set cls [winfo class $w]
	foreach ev {MouseWheel Option-MouseWheel Shift-MouseWheel Shift-Option-MouseWheel} {
	    if {[string length [bind $w <$ev>]] || [string length [bind $cls <$ev>]]} {
		bind $ew <$ev> [list event generate $w <$ev> -delta %D]
	    }
	}
	foreach ev {4 5 Shift-4 Shift-5 6 7} {
	    if {[string length [bind $w <$ev>]] || [string length [bind $cls <$ev>]]} {
		bind $ew <$ev> [list event generate $w <$ev>]
	    }
	}
    }
}

# ::tk_mergeRange --
# This procedure is merging a range into a sorted list of ranges.
# If given range is adjacent to, or intersecting a range in given
# list, then it will be amalgamated.
#
# Arguments:
# rangeListVar -	Name of variable containing the list of ranges.
# newRange -		New range which should be merged into given list.

proc tk_mergeRange {rangeListVar newRange} {
    upvar $rangeListVar ranges

    if {![info exists ranges]} {
	lappend ranges $newRange
	return $ranges
    }



    lassign $newRange s e
    lassign [split $s .] sline scol
    lassign [split $e .] eline ecol
    set newRangeList {}
    set n [llength $ranges]


    for {set i 0} {$i < $n} {incr i} {
	set range [lindex $ranges $i]
	lassign $range s1 e1
	lassign [split $s1 .] sline1 scol1
	lassign [split $e1 .] eline1 ecol1



	# compare "$e+1i" < $s1



	if {$eline < $sline1 || ($eline == $sline1 && $ecol + 1 < $scol1)} {
	    lappend newRangeList [list $s $e]
	    lappend newRangeList {*}[lrange $ranges $i end]
	    set ranges $newRangeList
	    return $newRangeList
	}
	# compare $s <= "$e1+1i"
	if {$sline < $eline1 || ($sline == $eline1 && $scol <= $ecol1 + 1)} {
	    # [$w compare $s > $s1]
	    if {$sline > $sline1 || ($sline == $sline1 && $scol > $scol1)} {
		set s $s1; set sline $sline1; set scol $scol1
	    }




	    # compare $e < $e1
	    if {$eline < $eline1 || ($eline == $eline1 && $ecol < $ecol1)} {
		set e $e1; set eline $eline1; set ecol $ecol1
	    }
	} else {
	    lappend newRangeList $range
	}
    }

    lappend newRangeList [list $s $e]
    set ranges $newRangeList
    return $newRangeList
}

# vi:set ts=8 sw=4:

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
# tk.tcl --
#
# Initialization script normally executed in the interpreter for each Tk-based
# application.  Arranges class bindings for widgets.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.

# Verify that we have Tk binary and script components from the same release
package require -exact Tk  8.7a4

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# tk.tcl --
#
# Initialization script normally executed in the interpreter for each Tk-based
# application.  Arranges class bindings for widgets.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
#
# 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  9.0b2

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {
174
175
176
177
178
179
180

181
182
183
184
185

186



187
188
189
190
191
192
193
194
195
196
197
	unset ::tk::FocusGrab($index)
    } else {
	set oldGrab ""
    }

    catch {focus $oldFocus}
    grab release $grab

    if {$destroy eq "withdraw"} {
	wm withdraw $grab
    } else {
	destroy $grab
    }

    if {[winfo exists $oldGrab] && [winfo ismapped $oldGrab]} {



	if {$oldStatus eq "global"} {
	    grab -global $oldGrab
	} else {
	    grab $oldGrab
	}
    }
}

# ::tk::GetSelection --
#   This tries to obtain the default selection.  On Unix, we first try
#   and get a UTF8_STRING, a type supported by modern Unix apps for







>
|
|
|
|
|
>

>
>
>

|

|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	unset ::tk::FocusGrab($index)
    } else {
	set oldGrab ""
    }

    catch {focus $oldFocus}
    grab release $grab
    if {[winfo exists $grab]} {
	if {$destroy eq "withdraw"} {
	    wm withdraw $grab
	} else {
	    destroy $grab
	}
    }
    if {[winfo exists $oldGrab] && [winfo ismapped $oldGrab]} {
	# The "grab" command will fail if another application
	# already holds the grab on a window with the same name.
	# So catch it. See [7447ed20ec] for an example.
	if {$oldStatus eq "global"} {
	    catch {grab -global $oldGrab}
	} else {
	    catch {grab $oldGrab}
	}
    }
}

# ::tk::GetSelection --
#   This tries to obtain the default selection.  On Unix, we first try
#   and get a UTF8_STRING, a type supported by modern Unix apps for
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
	event add <<Copy>>		<Control-c> <F16> <Control-Lock-C>
	event add <<Paste>>		<Control-v> <F18> <Control-Lock-V>
	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-Z> <Control-Lock-z>
	# On Darwin/Aqua, buttons from left to right are 1,3,2.  On Darwin/X11 with recent
	# XQuartz as the X server, they are 1,2,3; other X servers may differ.

	event add <<SelectAll>>		<Control-slash>
	event add <<SelectNone>>	<Control-backslash>
	event add <<NextChar>>		<Right>
	event add <<SelectNextChar>>	<Shift-Right>
	event add <<PrevChar>>		<Left>
	event add <<SelectPrevChar>>	<Shift-Left>
	event add <<NextWord>>		<Control-Right>
	event add <<SelectNextWord>>	<Control-Shift-Right>







|







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
	event add <<Copy>>		<Control-c> <F16> <Control-Lock-C>
	event add <<Paste>>		<Control-v> <F18> <Control-Lock-V>
	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-Z> <Control-Lock-z>
	# On Darwin/Aqua, buttons from left to right are 1,3,2.  On Darwin/X11 with recent
	# XQuartz as the X server, they are 1,2,3; other X servers may differ.

	event add <<SelectAll>>		<Control-/>
	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>
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    "win32" {
	event add <<Cut>>		<Control-x> <Shift-Delete> <Control-Lock-X>
	event add <<Copy>>		<Control-c> <Control-Insert> <Control-Lock-C>
	event add <<Paste>>		<Control-v> <Shift-Insert> <Control-Lock-V>
  	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-y> <Control-Lock-Y>

	event add <<SelectAll>>		<Control-slash> <Control-a> <Control-Lock-A>
	event add <<SelectNone>>	<Control-backslash>
	event add <<NextChar>>		<Right>
	event add <<SelectNextChar>>	<Shift-Right>
	event add <<PrevChar>>		<Left>
	event add <<SelectPrevChar>>	<Shift-Left>
	event add <<NextWord>>		<Control-Right>
	event add <<SelectNextWord>>	<Control-Shift-Right>







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    "win32" {
	event add <<Cut>>		<Control-x> <Shift-Delete> <Control-Lock-X>
	event add <<Copy>>		<Control-c> <Control-Insert> <Control-Lock-C>
	event add <<Paste>>		<Control-v> <Shift-Insert> <Control-Lock-V>
  	event add <<Undo>>		<Control-z> <Control-Lock-Z>
	event add <<Redo>>		<Control-y> <Control-Lock-Y>

	event add <<SelectAll>>		<Control-/> <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>
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    "aqua" {
	event add <<Cut>>		<Command-x> <F2> <Command-Lock-X>
	event add <<Copy>>		<Command-c> <F3> <Command-Lock-C>
	event add <<Paste>>		<Command-v> <F4> <Command-Lock-V>
	event add <<Clear>>		<Clear>

	# Official bindings
	# See http://support.apple.com/kb/HT1343
	event add <<SelectAll>>		<Command-a>
	event add <<Undo>>		<Command-Key-z> <Command-Lock-Key-Z>
	event add <<Redo>>		<Shift-Command-Key-z> <Shift-Command-Lock-Key-z>
	event add <<NextChar>>		<Right> <Control-Key-f> <Control-Lock-Key-F>
	event add <<SelectNextChar>>	<Shift-Right> <Shift-Control-Key-F> <Shift-Control-Lock-Key-F>
	event add <<PrevChar>>		<Left> <Control-Key-b> <Control-Lock-Key-B>
	event add <<SelectPrevChar>>	<Shift-Left> <Shift-Control-Key-B> <Shift-Control-Lock-Key-B>







|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
    "aqua" {
	event add <<Cut>>		<Command-x> <F2> <Command-Lock-X>
	event add <<Copy>>		<Command-c> <F3> <Command-Lock-C>
	event add <<Paste>>		<Command-v> <F4> <Command-Lock-V>
	event add <<Clear>>		<Clear>

	# Official bindings
	# See https://support.apple.com/en-us/HT201236
	event add <<SelectAll>>		<Command-a>
	event add <<Undo>>		<Command-Key-z> <Command-Lock-Key-Z>
	event add <<Redo>>		<Shift-Command-Key-z> <Shift-Command-Lock-Key-z>
	event add <<NextChar>>		<Right> <Control-Key-f> <Control-Lock-Key-F>
	event add <<SelectNextChar>>	<Shift-Right> <Shift-Control-Key-F> <Shift-Control-Lock-Key-F>
	event add <<PrevChar>>		<Left> <Control-Key-b> <Control-Lock-Key-B>
	event add <<SelectPrevChar>>	<Shift-Left> <Shift-Control-Key-B> <Shift-Control-Lock-Key-B>
489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504

505
506
507



508
509
510
511
512
513
514

# ----------------------------------------------------------------------
# Read in files that define all of the class bindings.
# ----------------------------------------------------------------------

if {$::tk_library ne ""} {
    proc ::tk::SourceLibFile {file} {
        namespace eval :: [list source -encoding utf-8 [file join $::tk_library $file.tcl]]
    }
    namespace eval ::tk {
	SourceLibFile icons

	SourceLibFile button
	SourceLibFile entry
	SourceLibFile listbox
	SourceLibFile menu
	SourceLibFile panedwindow

	SourceLibFile scale
	SourceLibFile scrlbar
	SourceLibFile spinbox



	SourceLibFile text
    }
}

# ----------------------------------------------------------------------
# Default bindings for keyboard traversal.
# ----------------------------------------------------------------------







|



>





>



>
>
>







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

# ----------------------------------------------------------------------
# Read in files that define all of the class bindings.
# ----------------------------------------------------------------------

if {$::tk_library ne ""} {
    proc ::tk::SourceLibFile {file} {
        namespace eval :: [list source [file join $::tk_library $file.tcl]]
    }
    namespace eval ::tk {
	SourceLibFile icons
	SourceLibFile iconbadges
	SourceLibFile button
	SourceLibFile entry
	SourceLibFile listbox
	SourceLibFile menu
	SourceLibFile panedwindow
	SourceLibFile print
	SourceLibFile scale
	SourceLibFile scrlbar
	SourceLibFile spinbox
	if {![interp issafe]} {
	    SourceLibFile systray
	}
	SourceLibFile text
    }
}

# ----------------------------------------------------------------------
# Default bindings for keyboard traversal.
# ----------------------------------------------------------------------
535
536
537
538
539
540
541






















542
543
544
545
546
547
548

## ::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.
#







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

## ::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::PreciseScrollDeltas $dxdy

proc ::tk::PreciseScrollDeltas {dxdy} {
    set deltaX [expr {$dxdy >> 16}]
    set low [expr {$dxdy & 0xffff}]
    set deltaY [expr {$low < 0x8000 ? $low : $low - 0x10000}]
    return [list $deltaX $deltaY]
}

# Helper for smooth scrolling of widgets that support xview moveto,
# yview moveto, height and width.

proc ::tk::ScrollByPixels {w deltaX deltaY} {
    set width [expr {1.0 * [$w cget -width]}]
    set height [expr {1.0 * [$w cget -height]}]
    set X [lindex [$w xview] 0]
    set Y [lindex [$w yview] 0]
    set x [expr {$X - $deltaX / $width}]
    set y [expr {$Y - $deltaY / $height}]
    $w xview moveto $x
    $w yview moveto $y
}

# ::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.
#
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
#	button or label which has $char as underlined character.
#
proc ::tk::FindAltKeyTarget {path char} {
    set class [winfo class $path]
    if {$class in {
	Button Checkbutton Label Radiobutton
	TButton TCheckbutton TLabel TRadiobutton
    } && [string equal -nocase $char \
	    [string index [$path cget -text] [$path cget -underline]]]} {
	return $path
    }
    set subwins [concat [grid content $path] [pack content $path] \
	    [place content $path]]
    if {$class eq "Canvas"} {
	foreach item [$path find all] {







|







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
#	button or label which has $char as underlined character.
#
proc ::tk::FindAltKeyTarget {path char} {
    set class [winfo class $path]
    if {$class in {
	Button Checkbutton Label Radiobutton
	TButton TCheckbutton TLabel TRadiobutton
    } && ([$path cget -underline] >= 0) && [string equal -nocase $char \
	    [string index [$path cget -text] [$path cget -underline]]]} {
	return $path
    }
    set subwins [concat [grid content $path] [pack content $path] \
	    [place content $path]]
    if {$class eq "Canvas"} {
	foreach item [$path find all] {
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699


































































































700
701
702
703
704
705
706















707
708
709
710
711

712
713
714
715
716
	if {$length > $maxlen} {
	    set maxlen $length
	}
    }
    return $maxlen
}

# For now, turn off the custom mdef proc for the Mac:

if {[tk windowingsystem] eq "aqua"} {
    namespace eval ::tk::mac {
	set useCustomMDEF 0
    }
}


if {[tk windowingsystem] eq "aqua"} {
    #stub procedures to respond to "do script" Apple Events
    proc ::tk::mac::DoScriptFile {file} {
	uplevel #0 $file
    	source -encoding utf-8 $file
    }
    proc ::tk::mac::DoScriptText {script} {
	uplevel #0 $script
    	eval $script


































































































    }
}

# Create a dictionary to store the starting index of the IME marked
# text in an Entry or Text widget.

set ::tk::Priv(IMETextMark) [dict create]
















# Run the Ttk themed widget set initialization
if {$::ttk::library ne ""} {
    uplevel \#0 [list source -encoding utf-8 $::ttk::library/ttk.tcl]
}


# Local Variables:
# mode: tcl
# fill-column: 78
# End:







<
<
<
<
<
<
<
<
<




|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

>





707
708
709
710
711
712
713









714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	if {$length > $maxlen} {
	    set maxlen $length
	}
    }
    return $maxlen
}










if {[tk windowingsystem] eq "aqua"} {
    #stub procedures to respond to "do script" Apple Events
    proc ::tk::mac::DoScriptFile {file} {
	uplevel #0 $file
	source $file
    }
    proc ::tk::mac::DoScriptText {script} {
	uplevel #0 $script
	eval $script
    }
    #This procedure is required to silence warnings generated
    #by inline AppleScript execution.
    proc ::tk::mac::GetDynamicSdef {} {
         puts ""
     }
}

if {[info commands ::tk::endOfWord] eq ""} {
    proc ::tk::endOfWord {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	}
	set start [tcl_endOfWord $str $start]
	if {$start < 0} {
	    set start ""
	}
	return $start
    }
}
if {[info commands ::tk::startOfNextWord] eq ""} {
    proc ::tk::startOfNextWord {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	}
	set start [tcl_startOfNextWord $str $start]
	if {$start < 0} {
	    set start ""
	}
	return $start
    }
}
if {[info commands ::tk::startOfPreviousWord] eq ""} {
    proc ::tk::startOfPreviousWord {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	}
	set start [tcl_startOfPreviousWord $str $start]
	if {$start < 0} {
	    set start ""
	}
	return $start
    }
}
if {[info commands ::tk::wordBreakBefore] eq ""} {
    proc ::tk::wordBreakBefore {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	}
	set start [tcl_wordBreakBefore $str $start]
	if {$start < 0} {
	    set start ""
	}
	return $start
    }
}
if {[info commands ::tk::wordBreakAfter] eq ""} {
    proc ::tk::wordBreakAfter {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	}
	set start [tcl_wordBreakAfter $str $start]
	if {$start < 0} {
	    set start ""
	}
	return $start
    }
}
if {[info commands ::tk::endOfCluster] eq ""} {
    proc ::tk::endOfCluster {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	} elseif {$start eq "end"} {
	    set start [expr {[string length $str]-1}]
	} elseif {[string match end-* $start]} {
	    set start [expr {[string length $str]-1-[string range $start 4 end]}]
	} elseif {$start >= [string length $str]} {
	    return ""
	}
	incr start
	return $start
    }
}
if {[info commands ::tk::startOfCluster] eq ""} {
    proc ::tk::startOfCluster {str start {locale {}}} {
	if {$start < 0} {
	    set start -1
	} elseif {$start eq "end"} {
	    set start [expr {[string length $str]-1}]
	} elseif {[string match end-* $start]} {
	    set start [expr {[string length $str]-1-[string range $start 4 end]}]
	} elseif {$start >= [string length $str]} {
	    return [string length $str]
	}
	if {$start < 0} {
	    return ""
	}
	return $start
    }
}

# 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]

# Scale the default parameters of the panedwindow sash
option add *Panedwindow.handlePad	6p widgetDefault
option add *Panedwindow.handleSize	6p widgetDefault
option add *Panedwindow.sashWidth	2.25p widgetDefault

# Scale the default size of the scale widget and its slider
option add *Scale.length		75p widgetDefault
option add *Scale.sliderLength		22.5p widgetDefault
option add *Scale.width			11.25p widgetDefault

# Scale the default scrollbar width on X11
if {[tk windowingsystem] eq "x11"} {
    option add *Scrollbar.width		8.25p widgetDefault
}

# Run the Ttk themed widget set initialization
if {$::ttk::library ne ""} {
    uplevel \#0 [list source $::ttk::library/ttk.tcl]
}


# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to library/tkfbox.tcl.

17
18
19
20
21
22
23











































24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55





56



57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
#

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {
    namespace import -force ::tk::msgcat::*
    variable showHiddenBtn 0
    variable showHiddenVar 1












































    # Create the images if they did not already exist.
    if {![info exists ::tk::Priv(updirImage)]} {

	set ::tk::Priv(updirImage) [image create photo -data {
	    iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABmJLR0QA/gD+AP7rGN
	    SCAAAACXBIWXMAAA3WAAAN1gGQb3mcAAAACXZwQWcAAAAWAAAAFgDcxelYAAAENUlE
	    QVQ4y7WUbWiVZRjHf/f9POcc9+Kc5bC2aIq5sGG0XnTzNU13zAIlFMNc9CEhTCKwCC
	    JIgt7AglaR0RcrolAKg14+GBbiGL6xZiYyy63cmzvu7MVznnOe537rw7bDyvlBoT/c
	    n+6L3/3nf13XLZLJJP+HfICysjKvqqpq+rWKysvLR1tbW+11g+fPn/+bEGIe4KYqCs
	    Owu66u7oG2trah6wJrrRc0NTVhjME5h7Vj5pxzCCE4duxYZUdHx/aGhoZmgJ+yb+wF
	    uCO19RmAffv25f8LFslkktraWtvU1CS6u7vRWmOtxVpbAPu+T0tLS04pFU/J34Wd3S
	    cdFtlfZWeZBU4IcaS5uXn1ZLAEMMY4ay1aa4wx/zpKKYIgoL6+vmjxqoXe5ZLTcsPq
	    bTyycjODpe1y3WMrvDAMV14jCuW0VhhjiJQpOJ5w7Zwjk8/y9R+vsHHNNq6oFMrkeX
	    BxI+8d2sktap3YvOPD0lRQrH+Z81fE7t3WB4gihVKazsuaA20aKSUgAG/seQdy2l6W
	    37+EyopqTv39I6HJUT2zlnlza2jLdgiTaxwmDov6alLHcZUTzXPGGAauWJbfO4dHl9
	    bgJs3HyfNf0N4ZsOa+jbT3/ownY/hO09p1kBULtjBw+Tvq7xzwauds4dWPDleAcP5E
	    xlprgtBRUZRgYCRPTzoHwEi2g6OnX+eFrW/RM9qBE4p43CeTz5ATaU6nDrFm2cPs/+
	    E1SopqkZ7MFJqntXZaa7IKppckwIEvJbg8LWd28OT6nVihCPQQ8UScWCLGqO4hXuQx
	    qDtJ204eWrqWb1ufRspwtABWaqx5gRKUFSdwDnxPcuLcyyxbuIyaqntIBV34MY9YzC
	    Owg+S9YeJFkniRpGPkCLMrZzG3+jbktA/KClMxFoUhiKC0OAbAhd79CO8i6xe/STyW
	    4O7KVRgUJ/sP0heeJV4kEVKw/vZd40sFKxat4mLvp6VLdvnb/XHHGGPIKwBBpC1/9n
	    3DpfRZnn9/AwCxRII9O79kVPdjvByxuET6Ai8mePeTt4lyheXzhOSpCcdWa00uckTG
	    kckbGu76nEhbIm2xznH4VB3OWYaiXqQn8GKSWGIMHuXyPL76LBcupmhp69pz4uMnXi
	    w4VloTGcdQRtGdzmHs1f+RdYZslMZJhzUOHVnceN1ooEiP5JUzdqCQMWCD0JCIeQzn
	    NNpO+clhrCYf5rC+A2cxWmDUWG2oHEOZMEKIwclgMnnLrTeXUV7sUzpNXgU9DmijWV
	    v9LEKCkAIhKIBnlvpks6F21qUZ31u/sbExPa9h0/RzwzMov2nGlG5TmW1YOzzlnSfL
	    mVnyGf19Q7lwZHBp+1fPtflAIgiC7389n9qkihP+lWyeqfUO15ZwQTqlw9H+o2cOvN
	    QJCAHEgEqgYnI0NyALjAJdyWQy7wMa6AEujUdzo3LjcAXwD/XCTKIRjWytAAAAJXRF
	    WHRjcmVhdGUtZGF0ZQAyMDA5LTA0LTA2VDIxOjI1OjQxLTAzOjAw8s+uCAAAACV0RV
	    h0bW9kaWZ5LWRhdGUAMjAwOC0wMS0wM1QxNTowODoyMS0wMjowMJEc/44AAAAZdEVY
	    dFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC
	}]





    }



    if {![info exists ::tk::Priv(folderImage)]} {

	set ::tk::Priv(folderImage) [image create photo -data {
	    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiA
	    AAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBl
	    Lm9yZ5vuPBoAAAHCSURBVDiNpZAxa5NRFIafc+9XLCni4BC6FBycMnbrLpkcgtDVX6
	    C70D/g4lZX/4coxLlgxFkpiiSSUGm/JiXfveee45AmNlhawXc53HvPee55X+l2u/yP
	    qt3d3Tfu/viatwt3fzIYDI5uBJhZr9fr3TMzzAx3B+D09PR+v98/7HQ6z5fNOWdCCG
	    U4HH6s67oAVDlnV1UmkwmllBUkhMD29nYHeLuEAkyn06qU8qqu64MrgIyqYmZrkHa7
	    3drc3KTVahFjJITAaDRiPB4/XFlQVVMtHH5IzJo/P4EA4MyB+erWPQB7++zs7ccYvl
	    U5Z08pMW2cl88eIXLZeDUpXzsBkNQ5eP1+p0opmaoCTgzw6fjs6gLLsp58FB60t0Dc
	    K1Ul54yIEIMQ43Uj68pquDmCeJVztpwzuBNE2LgBoMVpslHMCUEAFgDVxQbzVAiA+a
	    K5uGPmmDtZF3VpoUm2ArhqQaRiUjcMf81p1G60UEVhcjZfAFTVUkrgkS+jc06mDX9n
	    vq4YhJ9nlxZExMwMEaHJRutOdWuIIsJFUoBSuTvHJ4YIfP46unV4qdlsjsBRZRtb/X
	    fHd5+C8+P7+J8BIoxFwovfRxYhnhxjpzEAAAAASUVORK5CYII=
	}]
    }
    if {![info exists ::tk::Priv(fileImage)]} {

	set ::tk::Priv(fileImage)   [image create photo -data {
	    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gva
	    eTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1QQWFA84umAmQgAAANpJREFU
	    OMutkj1uhDAQhb8HSLtbISGfgZ+zbJkix0HmFhwhUdocBnMBGvqtTIqIFSReWKK8ai
	    x73nwzHrVt+zEMwwvH9FrX9TsA1trpqKy10+yUzME4jnjvAZB0LzXHkojjmDRNVyh3
	    A+89zrlVwlKSqKrqVy/J8lAUxSZBSMny4ZLgp54iyPM8UPHGNJ2IomibAKDv+9VlWZ
	    bABbgB5/0WQgSSkC4PF2JF4JzbHN430c4vhAm0TyCJruuClefph4yCBCGT3T3Isoy/
	    KDHGfDZNcz2SZIx547/0BVRRX7n8uT/sAAAAAElFTkSuQmCC
	}]

    }
}

# ::tk::dialog::file:: --
#
#	Implements the TK file selection dialog.  This dialog is used when the
#	tk_strictMotif flag is set to false.  This procedure shouldn't be







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
>
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
>
>
>
>
>
|
>
>
>
|
>
|
<
<
<
<
<
<
<
<
<
|
<
<
<

|
>
|
<
<
<
<
<
<
<
<
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
























73
74
75
76
77
78
79
80
81
82
83
84
85
86









87



88
89
90
91








92
93
94
95
96
97
98
99
#

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {
    namespace import -force ::tk::msgcat::*
    variable showHiddenBtn 0
    variable showHiddenVar 1

    # Based on Vimix/16/actions/go-up.svg
    # See https://github.com/vinceliuice/vimix-icon-theme
    set updirImageData {
	<?xml version="1.0" encoding="UTF-8"?>
	<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
	 <path d="m7 14v-9l-4 4-1-1 6-6 6 6-1 1-4-4v9z" fill="#000000"/>
	</svg>
    }

    proc UpdateUpdirImageData {} {
	variable updirImageData
	set idx1 [string first "#000000" $updirImageData]
	set idx2 [expr {$idx1 + 6}]

	set fgColor [ttk::style lookup . -foreground {} black]
	lassign [winfo rgb . $fgColor] r g b
	set fgColor [format "#%02x%02x%02x" \
		[expr {$r >> 8}] [expr {$g >> 8}] [expr {$b >> 8}]]

	return [string replace $updirImageData $idx1 $idx2 $fgColor]
    }

    # Based on https://icons8.com/icon/JXYalxb9XWWd/folder
    set folderImageData {
	<?xml version="1.0" encoding="UTF-8"?>
	<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
	 <path d="m0.5 13.5v-12h4.293l2 2h8.707v10z" fill="#59afff"/>
	 <path d="m4.586 2 2 2h8.414v9h-14v-11h3.586m0.414-1h-5v13h16v-11h-9l-2-2z" fill="#2d8cff"/>
	 <path d="m0.5 14.5v-10h4.618l2-1h8.382v11z" fill="#8cc5ff"/>
	 <path d="m15 4v10h-14v-9h4.236l0.211-0.106 1.789-0.894h7.764m1-1h-9l-2 1h-5v11h16z" fill="#2d8cff"/>
	</svg>
    }

    # Based on https://icons8.com/icon/mEF_vyjYlnE3/file
    set fileImageData {
	<?xml version="1.0" encoding="UTF-8"?>
	<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
	 <path d="m2 1h8l4 4v11h-12z" fill="#808080"/>
	 <path d="m3 2h6.5l3.5 3.5v9.5h-10z" fill="#f0f0f0"/>
	 <path d="m9 1v5h5v-1h-4v-4h-1z" fill="#808080"/>
	</svg>
    }

    # Create the images if they did not already exist.
    if {![info exists ::tk::Priv(updirImage)] ||
	    $::tk::Priv(updirImage) ni [image names]} {
	set ::tk::Priv(updirImage)  [image create photo \

		-format $::tk::svgFmt -data [UpdateUpdirImageData]]

























	if {"TkFileDialog" ni [bindtags .]} {
	    bindtags . [linsert [bindtags .] 1 TkFileDialog]
	    bind TkFileDialog <<ThemeChanged>> {
		if {$::tk::Priv(updirImage) in [image names]} {
		    $::tk::Priv(updirImage) configure \
			    -data [::tk::dialog::file::UpdateUpdirImageData]
		}
	    }
	}
    }
    if {![info exists ::tk::Priv(folderImage)] ||
	    $::tk::Priv(folderImage) ni [image names]} {
	set ::tk::Priv(folderImage) [image create photo \









		-format $::tk::svgFmt -data $folderImageData]



    }
    if {![info exists ::tk::Priv(fileImage)] ||
	    $::tk::Priv(fileImage) ni [image names]} {
	set ::tk::Priv(fileImage)   [image create photo \








		-format $::tk::svgFmt -data $fileImageData]
    }
}

# ::tk::dialog::file:: --
#
#	Implements the TK file selection dialog.  This dialog is used when the
#	tk_strictMotif flag is set to false.  This procedure shouldn't be
222
223
224
225
226
227
228

229

230
231
232
233
234
235
236

    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) {*}$trace
    }

    $data(dirMenuBtn) configure -textvariable {}


    return $Priv(selectFilePath)
}

# ::tk::dialog::file::Config --
#
#	Configures the TK filedialog according to the argument list







>
|
>







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) {*}$trace
    }
    if {[winfo exists $data(dirMenuBtn)]} {
	$data(dirMenuBtn) configure -textvariable {}
    }

    return $Priv(selectFilePath)
}

# ::tk::dialog::file::Config --
#
#	Configures the TK filedialog according to the argument list
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    $data(dirMenu) add radiobutton -label "" -variable \
	    [format %s(selectPath) ::tk::dialog::file::$dataName]
    set data(upBtn) [ttk::button $f1.up]
    $data(upBtn) configure -image $Priv(updirImage)

    $f1.menu configure -takefocus 1;# -highlightthickness 2

    pack $data(upBtn) -side right -padx 4 -fill both
    pack $f1.lab -side left -padx 4 -fill both
    pack $f1.menu -expand yes -fill both -padx 4

    # data(icons): the IconList that list the files and directories.
    #
    if {$class eq "TkFDialog"} {
	if { $data(-multiple) } {
	    set fNameCaption [mc "File &names:"]
	} else {







|
|
|







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
    $data(dirMenu) add radiobutton -label "" -variable \
	    [format %s(selectPath) ::tk::dialog::file::$dataName]
    set data(upBtn) [ttk::button $f1.up]
    $data(upBtn) configure -image $Priv(updirImage)

    $f1.menu configure -takefocus 1;# -highlightthickness 2

    pack $data(upBtn) -side right -padx 3p -fill both
    pack $f1.lab -side left -padx 3p -fill both
    pack $f1.menu -expand yes -fill both -padx 3p

    # data(icons): the IconList that list the files and directories.
    #
    if {$class eq "TkFDialog"} {
	if { $data(-multiple) } {
	    set fNameCaption [mc "File &names:"]
	} else {
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
    } else {
	set text [mc "Show &Hidden Directories"]
    }
    set data(hiddenBtn) [::tk::AmpWidget ttk::checkbutton $f2.hidden \
	    -text $text -state disabled \
	    -variable ::tk::dialog::file::showHiddenVar \
	    -command [list ::tk::dialog::file::UpdateWhenIdle $w]]
# -anchor w -padx 3

    # the okBtn is created after the typeMenu so that the keyboard traversal
    # is in the right order, and add binding so that we find out when the
    # dialog is destroyed by the user (added here instead of to the overall
    # window so no confusion about how much <Destroy> gets called; exactly
    # once will do). [Bug 987169]

    set data(okBtn)     [::tk::AmpWidget ttk::button $f2.ok \
	    -text [mc "&OK"]     -default active];# -pady 3]
    bind $data(okBtn) <Destroy> [list ::tk::dialog::file::Destroyed $w]
    set data(cancelBtn) [::tk::AmpWidget ttk::button $f2.cancel \
	    -text [mc "&Cancel"] -default normal];# -pady 3]

    # grid the widgets in f2
    #
    grid $f2.lab $f2.ent $data(okBtn) -padx 4 -pady 3 -sticky ew
    grid configure $f2.ent -padx 2
    if {$class eq "TkFDialog"} {
	grid $data(typeMenuLab) $data(typeMenuBtn) $data(cancelBtn) \
		-padx 4 -sticky ew
	grid configure $data(typeMenuBtn) -padx 0
	grid $data(hiddenBtn) -columnspan 2 -padx 4 -sticky ew
    } else {
	grid $data(hiddenBtn) - $data(cancelBtn) -padx 4 -sticky ew
    }
    grid columnconfigure $f2 1 -weight 1

    # Pack all the frames together. We are done with widget construction.
    #
    pack $f1 -side top -fill x -pady 4
    pack $f2 -side bottom -pady 4 -fill x
    pack $data(icons) -expand yes -fill both -padx 4 -pady 1

    # Set up the event handlers that are common to Directory and File Dialogs
    #

    wm protocol $w WM_DELETE_WINDOW [list ::tk::dialog::file::CancelCmd $w]
    $data(upBtn)     configure -command [list ::tk::dialog::file::UpDirCmd $w]
    $data(cancelBtn) configure -command [list ::tk::dialog::file::CancelCmd $w]







|








|


|



|
|


|

|

|





|
|
|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    } else {
	set text [mc "Show &Hidden Directories"]
    }
    set data(hiddenBtn) [::tk::AmpWidget ttk::checkbutton $f2.hidden \
	    -text $text -state disabled \
	    -variable ::tk::dialog::file::showHiddenVar \
	    -command [list ::tk::dialog::file::UpdateWhenIdle $w]]
# -anchor w -padx 2p

    # the okBtn is created after the typeMenu so that the keyboard traversal
    # is in the right order, and add binding so that we find out when the
    # dialog is destroyed by the user (added here instead of to the overall
    # window so no confusion about how much <Destroy> gets called; exactly
    # once will do). [Bug 987169]

    set data(okBtn)     [::tk::AmpWidget ttk::button $f2.ok \
	    -text [mc "&OK"]     -default active];# -pady 2p]
    bind $data(okBtn) <Destroy> [list ::tk::dialog::file::Destroyed $w]
    set data(cancelBtn) [::tk::AmpWidget ttk::button $f2.cancel \
	    -text [mc "&Cancel"] -default normal];# -pady 2p]

    # grid the widgets in f2
    #
    grid $f2.lab $f2.ent $data(okBtn) -padx 3p -pady 2p -sticky ew
    grid configure $f2.ent -padx 1.5p
    if {$class eq "TkFDialog"} {
	grid $data(typeMenuLab) $data(typeMenuBtn) $data(cancelBtn) \
		-padx 3p -sticky ew
	grid configure $data(typeMenuBtn) -padx 0
	grid $data(hiddenBtn) -columnspan 2 -padx 3p -sticky ew
    } else {
	grid $data(hiddenBtn) - $data(cancelBtn) -padx 3p -sticky ew
    }
    grid columnconfigure $f2 1 -weight 1

    # Pack all the frames together. We are done with widget construction.
    #
    pack $f1 -side top -fill x -pady 3p
    pack $f2 -side bottom -pady 3p -fill x
    pack $data(icons) -expand yes -fill both -padx 3p -pady 1p

    # Set up the event handlers that are common to Directory and File Dialogs
    #

    wm protocol $w WM_DELETE_WINDOW [list ::tk::dialog::file::CancelCmd $w]
    $data(upBtn)     configure -command [list ::tk::dialog::file::UpDirCmd $w]
    $data(cancelBtn) configure -command [list ::tk::dialog::file::CancelCmd $w]
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
	return
    }

    # Turn on the busy cursor. BUG?? We haven't disabled X events, though,
    # so the user may still click and cause havoc ...
    #
    set entCursor [$data(ent) cget -cursor]
    set dlgCursor [$w         cget -cursor]
    $data(ent) configure -cursor watch
    $w         configure -cursor watch
    update idletasks

    $data(icons) deleteall

    set showHidden $showHiddenVar

    # Make the dir list. Note that using an explicit [pwd] (instead of '.') is







|

|







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
	return
    }

    # Turn on the busy cursor. BUG?? We haven't disabled X events, though,
    # so the user may still click and cause havoc ...
    #
    set entCursor [$data(ent) cget -cursor]
    set dlgCursor [$w cget -cursor]
    $data(ent) configure -cursor watch
    $w configure -cursor watch
    update idletasks

    $data(icons) deleteall

    set showHidden $showHiddenVar

    # Make the dir list. Note that using an explicit [pwd] (instead of '.') is
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
	    ::tk::SetAmpText $data(okBtn) [mc "&Save"]
	}
    }

    # turn off the busy cursor.
    #
    $data(ent) configure -cursor $entCursor
    $w         configure -cursor $dlgCursor
}

# ::tk::dialog::file::SetPathSilently --
#
# 	Sets data(selectPath) without invoking the trace procedure
#
proc ::tk::dialog::file::SetPathSilently {w path} {







|







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
	    ::tk::SetAmpText $data(okBtn) [mc "&Save"]
	}
    }

    # turn off the busy cursor.
    #
    $data(ent) configure -cursor $entCursor
    $w configure -cursor $dlgCursor
}

# ::tk::dialog::file::SetPathSilently --
#
# 	Sets data(selectPath) without invoking the trace procedure
#
proc ::tk::dialog::file::SetPathSilently {w path} {
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
		} else {
		    set data(selectFile) $file
		}
		Done $w
	    }
	}
	PATH {
	    tk_messageBox -icon warning -type ok -parent $w \
		    -message [mc "Directory \"%1\$s\" does not exist." $path]
	    $data(ent) selection range 0 end
	    $data(ent) icursor end
	}
	CHDIR {
	    tk_messageBox -type ok -parent $w -icon warning -message  \
		[mc "Cannot change to the directory\
                     \"%1\$s\".\nPermission denied." $path]
	    $data(ent) selection range 0 end
	    $data(ent) icursor end
	}
	ERROR {
	    tk_messageBox -type ok -parent $w -icon warning -message \
		    [mc "Invalid file name \"%1\$s\"." $path]
	    $data(ent) selection range 0 end







|
|





|
|







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
		} else {
		    set data(selectFile) $file
		}
		Done $w
	    }
	}
	PATH {
	    tk_messageBox -icon warning -type ok -parent $w -message \
		    [mc "Directory \"%1\$s\" does not exist." $path]
	    $data(ent) selection range 0 end
	    $data(ent) icursor end
	}
	CHDIR {
	    tk_messageBox -type ok -parent $w -icon warning -message  \
		    [mc "Cannot change to the directory\
			\"%1\$s\".\nPermission denied." $path]
	    $data(ent) selection range 0 end
	    $data(ent) icursor end
	}
	ERROR {
	    tk_messageBox -type ok -parent $w -icon warning -message \
		    [mc "Invalid file name \"%1\$s\"." $path]
	    $data(ent) selection range 0 end
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
	if {
	    [info exists data(-typevariable)] && $data(-typevariable) ne ""
	    && [info exists data(-filetypes)] && [llength $data(-filetypes)]
	    && [info exists data(filterType)] && $data(filterType) ne ""
	} then {
	    upvar #0 $data(-typevariable) typeVariable
	    set typeVariable [lindex $data(origfiletypes) \
	            [lsearch -exact $data(-filetypes) $data(filterType)] 0]

	}
    }
    bind $data(okBtn) <Destroy> {}
    set Priv(selectFilePath) $selectFilePath
}

# ::tk::dialog::file::GlobFiltered --







|
<







1129
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
	if {
	    [info exists data(-typevariable)] && $data(-typevariable) ne ""
	    && [info exists data(-filetypes)] && [llength $data(-filetypes)]
	    && [info exists data(filterType)] && $data(filterType) ne ""
	} then {
	    upvar #0 $data(-typevariable) typeVariable
	    set typeVariable [lindex $data(origfiletypes) \
		    [lsearch -exact $data(-filetypes) $data(filterType)] 0]

	}
    }
    bind $data(okBtn) <Destroy> {}
    set Priv(selectFilePath) $selectFilePath
}

# ::tk::dialog::file::GlobFiltered --

Changes to library/ttk/altTheme.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
#
# Ttk widget set: Alternate theme
#

namespace eval ttk::theme::alt {

    variable colors
    array set colors {
	-frame 		"#d9d9d9"
	-window		"#ffffff"

	-darker 	"#c3c3c3"
	-border		"#414141"
	-activebg 	"#ececec"
	-disabledfg	"#a3a3a3"
	-selectbg	"#4a6984"
	-selectfg	"#ffffff"
	-altindicator	"#aaaaaa"
    }

    ttk::style theme settings alt {

	ttk::style configure "." \
	    -background 	$colors(-frame) \
	    -foreground 	black \
	    -troughcolor	$colors(-darker) \
	    -bordercolor	$colors(-border) \
	    -selectbackground 	$colors(-selectbg) \
	    -selectforeground 	$colors(-selectfg) \
	    -font 		TkDefaultFont \
	    ;

	ttk::style map "." -background \
	    [list disabled $colors(-frame)  active $colors(-activebg)] ;
	ttk::style map "." -foreground [list disabled $colors(-disabledfg)] ;
        ttk::style map "." -embossed [list disabled 1] ;

	ttk::style configure TButton \
	    -anchor center -width -11 -padding "1 1" \
	    -relief raised -shiftrelief 1 \
	    -highlightthickness 1 -highlightcolor $colors(-frame)

	ttk::style map TButton -relief {
	    {pressed !disabled} 	sunken
	    {active !disabled} 	raised
	} -highlightcolor {alternate black}

	ttk::style configure TCheckbutton -indicatorcolor "#ffffff" -padding 2

	ttk::style configure TRadiobutton -indicatorcolor "#ffffff" -padding 2

	ttk::style map TCheckbutton -indicatorcolor \
	    [list  pressed $colors(-frame) \
	           alternate $colors(-altindicator) \
	           disabled $colors(-frame)]
	ttk::style map TRadiobutton -indicatorcolor \
	    [list  pressed $colors(-frame) \
	           alternate $colors(-altindicator) \
	           disabled $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -padding "3 3" -relief raised

	ttk::style configure TEntry -padding 1

	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -padding 1

	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)] \
		-arrowcolor [list disabled $colors(-disabledfg)]
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}

	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure Toolbutton -relief flat -padding 2
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-darker)  active $colors(-activebg)]

	ttk::style configure TScrollbar -relief raised


	ttk::style configure TLabelframe -relief groove -borderwidth 2

	ttk::style configure TNotebook -tabmargins {2 2 1 0}
	ttk::style configure TNotebook.Tab \
	    -padding {4 2} -background $colors(-darker)
	ttk::style map TNotebook.Tab \
	    -background [list selected $colors(-frame)] \
	    -expand [list selected {2 2 1 0}] \
	    ;

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised


	ttk::style configure Treeview -background $colors(-window)




	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	ttk::style configure TScale \
	    -groovewidth 4 -troughrelief sunken \
	    -sliderwidth raised -borderwidth 2

	ttk::style configure TProgressbar \
	    -background $colors(-selectbg) -borderwidth 0

    }
}










>


















|
|
<

|
|
|


|


<

|
|


|
>
|
>










|

|
>

|
>
|
>

|
|
|
<

|
>




|





|
>



|
|
|


|
<



>
>
|
>
>
>
>







|
|
>

|
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#
# Ttk widget set: Alternate theme
#

namespace eval ttk::theme::alt {

    variable colors
    array set colors {
	-frame 		"#d9d9d9"
	-window		"#ffffff"
	-alternate	"#f0f0f0"
	-darker 	"#c3c3c3"
	-border		"#414141"
	-activebg 	"#ececec"
	-disabledfg	"#a3a3a3"
	-selectbg	"#4a6984"
	-selectfg	"#ffffff"
	-altindicator	"#aaaaaa"
    }

    ttk::style theme settings alt {

	ttk::style configure "." \
	    -background 	$colors(-frame) \
	    -foreground 	black \
	    -troughcolor	$colors(-darker) \
	    -bordercolor	$colors(-border) \
	    -selectbackground 	$colors(-selectbg) \
	    -selectforeground 	$colors(-selectfg) \
	    -font 		TkDefaultFont


	ttk::style map "." -background \
	    [list disabled $colors(-frame)  active $colors(-activebg)]
	ttk::style map "." -foreground [list disabled $colors(-disabledfg)]
        ttk::style map "." -embossed [list disabled 1]

	ttk::style configure TButton \
	    -anchor center -width -11 -padding 0.75p \
	    -relief raised -shiftrelief 1 \
	    -highlightthickness 1 -highlightcolor $colors(-frame)

	ttk::style map TButton -relief {
	    {pressed !disabled}	sunken
	    {active !disabled}	raised
	} -highlightcolor {alternate black}

	ttk::style configure TCheckbutton -indicatorcolor "#ffffff" \
	    -indicatormargin {0 1.5p 3p 1.5p} -padding 1.5p
	ttk::style configure TRadiobutton -indicatorcolor "#ffffff" \
	    -indicatormargin {0 1.5p 3p 1.5p} -padding 1.5p
	ttk::style map TCheckbutton -indicatorcolor \
	    [list  pressed $colors(-frame) \
	           alternate $colors(-altindicator) \
	           disabled $colors(-frame)]
	ttk::style map TRadiobutton -indicatorcolor \
	    [list  pressed $colors(-frame) \
	           alternate $colors(-altindicator) \
	           disabled $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -padding 2.25p -arrowsize 3.75p -relief raised

	ttk::style configure TEntry -padding 1 \
	    -focuswidth 2 -focuscolor $colors(-selectbg)
	ttk::style map TEntry -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -padding 1 -arrowsize 10.5p \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TCombobox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]
	ttk::style configure ComboboxPopdownFrame -relief solid -borderwidth 1


	ttk::style configure TSpinbox -arrowsize 7.5p -padding {1.5p 0 7.5p 0} \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure Toolbutton -relief flat -padding 1.5p
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-darker)  active $colors(-activebg)]

	ttk::style configure TScrollbar -relief raised \
	    -arrowsize 10.5p -width 10.5p

	ttk::style configure TLabelframe -relief groove -borderwidth 2

	ttk::style configure TNotebook -tabmargins {1.5p 1.5p 0.75p 0}
	ttk::style configure TNotebook.Tab -background $colors(-darker) \
	    -padding {3p 1.5p}
	ttk::style map TNotebook.Tab \
	    -background [list selected $colors(-frame)] \
	    -expand {selected {1.5p 1.5p 0.75p 0}}


	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Item \
	    -indicatormargins {1.5p 1.5p 3p 1.5p}
	ttk::style configure Treeview -background $colors(-window) \
	    -stripedbackground $colors(-alternate) -indent 15p
	ttk::setTreeviewRowHeight
	ttk::style configure Treeview.Separator \
	    -background $colors(-alternate)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	ttk::style configure TScale \
	    -groovewidth 3p -troughrelief sunken \
	    -sliderthickness 11.25p -borderwidth 2

	ttk::style configure TProgressbar \
	    -background $colors(-selectbg) -borderwidth 0 \
	    -barsize 22.5p -thickness 11.25p
    }
}

Changes to library/ttk/aquaTheme.tcl.

22
23
24
25
26
27
28
29
30
31
32
33
34



35


36
37























































38
39
40
41
42
43
44
45






46
47
48
49






50



51


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126




127
128
129
130
		background systemSelectedTextBackgroundColor
		!focus systemSelectedTextBackgroundColor} \
	    -selectforeground {
		background systemSelectedTextColor
		!focus systemSelectedTextColor}

	# Button
	ttk::style configure TButton -anchor center -width -6 \
	    -foreground systemControlTextColor
	ttk::style map TButton \
	    -foreground {
		pressed white
	        {alternate !pressed !background} white}



	ttk::style configure TMenubutton -anchor center -padding {2 0 0 2}


	ttk::style configure Toolbutton -anchor center
























































	# Entry
	ttk::style configure TEntry \
	    -foreground systemTextColor \
	    -background systemTextBackgroundColor
	ttk::style map TEntry \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \






	    -selectforeground {
		background systemTextColor
	    } \
	    -selectbackground {






		background systemTextBackgroundColor



	    }




	# Workaround for #1100117:
	# Actually, on Aqua we probably shouldn't stipple images in
	# disabled buttons even if it did work...
	ttk::style configure . -stipple {}

	# Notebook
	ttk::style configure TNotebook -tabmargins {10 0} -tabposition n
	ttk::style configure TNotebook -padding {18 8 18 17}
	ttk::style configure TNotebook.Tab -padding {12 3 12 2}
	ttk::style configure TNotebook.Tab -foreground systemControlTextColor
	ttk::style map TNotebook.Tab \
	    -foreground {
		background systemControlTextColor
		disabled systemDisabledControlTextColor
		selected systemSelectedTabTextColor}

	# Combobox:
	ttk::style configure TCombobox \
	    -foreground systemTextColor \
	    -background systemTransparent
	ttk::style map TCombobox \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectforeground {
		background systemTextColor
	    } \
	    -selectbackground {
		background systemTransparent
	    }

	# Spinbox
	ttk::style configure TSpinbox \
	    -foreground systemTextColor \
	    -background systemTextBackgroundColor \
	    -selectforeground systemSelectedTextColor \
	    -selectbackground systemSelectedTextBackgroundColor
	ttk::style map TSpinbox \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectforeground {
		!active systemTextColor
	    } \
	    -selectbackground {
		!active systemTextBackgroundColor
		!focus systemTextBackgroundColor
		focus systemSelectedTextBackgroundColor
	    }

	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont \
	    -foreground systemTextColor \
	    -background systemWindowBackgroundColor
	ttk::style configure Treeview -rowheight 18 \
	    -background systemTextBackgroundColor \

	    -foreground systemTextColor \
	    -fieldbackground systemTextBackgroundColor
	ttk::style map Treeview \
	    -background {
		selected systemSelectedTextBackgroundColor
	    }

	# Enable animation for ttk::progressbar widget:
	ttk::style configure TProgressbar -period 100 -maxphase 255

	# For Aqua, labelframe labels should appear outside the border,
	# with a 14 pixel inset and 4 pixels spacing between border and label
	# (ref: Apple Human Interface Guidelines / Controls / Grouping Controls)
	#
	ttk::style configure TLabelframe \
		-labeloutside true -labelmargins {14 0 14 4}





	# TODO: panedwindow sashes should be 9 pixels (HIG:Controls:Split Views)
    }
}







|




|
>
>
>

>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
|
|


>
>
>
>
>
>
|
>
>
>
|
>
>
|













|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<







|
>
|







|






|
>
>
>
>




22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143














144


145








146









147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
		background systemSelectedTextBackgroundColor
		!focus systemSelectedTextBackgroundColor} \
	    -selectforeground {
		background systemSelectedTextColor
		!focus systemSelectedTextColor}

	# Button
	ttk::style configure TButton -anchor center \
	    -foreground systemControlTextColor
	ttk::style map TButton \
	    -foreground {
		pressed white
	        {alternate !pressed !background} white
	        disabled systemDisabledControlTextColor}

	# Menubutton
	ttk::style configure TMenubutton -anchor center -padding {2 0 0 2}

	# Toolbutton
	ttk::style configure Toolbutton -anchor center

	# Inline Button
	ttk::style configure InlineButton -anchor center -font TkHeadingFont \
	    -foreground systemTextBackgroundColor
	ttk::style map InlineButton \
	    -foreground {
		disabled systemWindowBackgroundColor
	    }

	# Image Button
	ttk::style configure ImageButton -anchor center -width 1 \
	    -compound top
	ttk::style map ImageButton \
	    -foreground {
		pressed systemLabelColor
		!pressed systemSecondaryLabelColor
	    }

	# Recessed (radio) button
	font create RecessedFont -family EmphasizedSystem -size 11 -weight bold
	ttk::style configure RecessedButton \
	    -foreground systemControlTextColor
	ttk::style map RecessedButton \
	    -foreground {
		{disabled selected} systemWindowBackgroundColor3
		{disabled !selected} systemDisabledControlTextColor
		selected systemTextBackgroundColor
		active white
		pressed white
	    } \
	    -font {
		selected RecessedFont
		active RecessedFont
		pressed RecessedFont
	    }

	# Sidebar (radio) button
	font create SidebarFont -family .AppleSystemUIFont -size 11 -weight normal
	ttk::style configure SidebarButton \
	    -foreground systemControlTextColor \
	    -font SidebarFont
	ttk::style map SidebarButton \
	    -foreground {
		{disabled selected} systemWindowBackgroundColor3
		{disabled !selected} systemDisabledControlTextColor
		selected systemTextColor
		active systemTextColor
		pressed systemTextColor
	    }

	# 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 \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectbackground {
		!focus systemUnemphasizedSelectedTextBackgroundColor
	    }

	# Spinbox
	ttk::style configure TSpinbox \
	    -foreground systemTextColor \
	    -background systemTextBackgroundColor
	ttk::style map TSpinbox \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectbackground {
		!focus systemUnemphasizedSelectedTextBackgroundColor
	    }

	# Workaround for #1100117:
	# Actually, on Aqua we probably shouldn't stipple images in
	# disabled buttons even if it did work...
	ttk::style configure . -stipple {}

	# Notebook
	ttk::style configure TNotebook -tabmargins {10 0} -tabposition n
	ttk::style configure TNotebook -padding {18 8 18 17}
	ttk::style configure TNotebook.Tab -padding {12 3 12 2}
	ttk::style configure TNotebook.Tab -foreground systemControlTextColor
	ttk::style map TNotebook.Tab \
	    -foreground {
		{background !selected} systemControlTextColor














		{background selected} black


		{!background selected} systemSelectedTabTextColor








		disabled systemDisabledControlTextColor}










	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont \
	    -foreground systemTextColor \
	    -background systemWindowBackgroundColor
	ttk::style configure Treeview -rowheight 18 \
	    -background systemControlBackgroundColor \
	    -stripedbackground systemControlAlternatingRowColor \
            -foreground systemTextColor \
	    -fieldbackground systemTextBackgroundColor
	ttk::style map Treeview \
	    -background {
		selected systemSelectedTextBackgroundColor
	    }

	# Enable animation for ttk::progressbar widget:
	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 2}

	ttk::style configure TLabelframe.Label \
	    -font TkSmallCaptionFont

	# 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
ttk::copyBindings TButton TRadiobutton

# ...plus a few more:

bind TRadiobutton <Up>  		{ ttk::button::RadioTraverse %W -1 }
bind TRadiobutton <Down> 		{ ttk::button::RadioTraverse %W +1 }

# bind TCheckbutton <plus> { %W select }
# bind TCheckbutton <minus> { %W deselect }

# activate --
#	Simulate a button press: temporarily set the state to 'pressed',
#	then invoke the button.
#
proc ttk::button::activate {w} {







|







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 <+> { %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} {
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#	A radiobutton group consists of all the radiobuttons with
#	the same parent and -variable; this is a pretty good heuristic
#	that works most of the time.
#
proc ttk::button::RadioTraverse {w dir} {
    set group [list]
    foreach sibling [winfo children [winfo parent $w]] {
    	if {   [winfo class $sibling] eq "TRadiobutton"
	    && [$sibling cget -variable] eq [$w cget -variable]
	    && ![$sibling instate disabled]
	} {
	   lappend group $sibling
	}
    }

    if {![llength $group]} {	 # Shouldn't happen, but can.
    	return
    }

    set pos [expr {([lsearch -exact $group $w] + $dir) % [llength $group]}]
    tk::TabToWindow [lindex $group $pos]
}







|








|





62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#	A radiobutton group consists of all the radiobuttons with
#	the same parent and -variable; this is a pretty good heuristic
#	that works most of the time.
#
proc ttk::button::RadioTraverse {w dir} {
    set group [list]
    foreach sibling [winfo children [winfo parent $w]] {
	if {   [winfo class $sibling] eq "TRadiobutton"
	    && [$sibling cget -variable] eq [$w cget -variable]
	    && ![$sibling instate disabled]
	} {
	   lappend group $sibling
	}
    }

    if {![llength $group]} {	 # Shouldn't happen, but can.
	return
    }

    set pos [expr {([lsearch -exact $group $w] + $dir) % [llength $group]}]
    tk::TabToWindow [lindex $group $pos]
}

Changes to library/ttk/clamTheme.tcl.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
#
# "Clam" theme.
#
# Inspired by the XFCE family of Gnome themes.
#

namespace eval ttk::theme::clam {

    variable colors
    array set colors {
	-disabledfg		"#999999"
	-frame  		"#dcdad5"
	-window  		"#ffffff"
	-dark			"#cfcdc8"
	-darker 		"#bab5ab"







>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#
# "Clam" theme.
#
# Inspired by the XFCE family of Gnome themes.
#

namespace eval ttk::theme::clam {

    variable colors
    array set colors {
	-disabledfg		"#999999"
	-frame  		"#dcdad5"
	-window  		"#ffffff"
	-dark			"#cfcdc8"
	-darker 		"#bab5ab"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113

114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131


132




133
134
135
136
137
138
139
140
141
142






143

144
145
146
147
	    -bordercolor $colors(-darkest) \
	    -darkcolor $colors(-dark) \
	    -lightcolor $colors(-lighter) \
	    -troughcolor $colors(-darker) \
	    -selectbackground $colors(-selectbg) \
	    -selectforeground $colors(-selectfg) \
	    -selectborderwidth 0 \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -background [list disabled $colors(-frame) \
			     active $colors(-lighter)] \
	    -foreground [list disabled $colors(-disabledfg)] \
	    -selectbackground [list  !focus $colors(-darkest)] \
	    -selectforeground [list  !focus white] \
	    ;
	# -selectbackground [list  !focus "#847d73"]

	ttk::style configure TButton \
	    -anchor center -width -11 -padding 5 -relief raised
	ttk::style map TButton \
	    -background [list \
			     disabled $colors(-frame) \
			     pressed $colors(-darker) \
			     active $colors(-lighter)] \
	    -lightcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)] \
	    -bordercolor [list alternate "#000000"] \
	    ;

	ttk::style configure Toolbutton \
	    -anchor center -padding 2 -relief flat
	ttk::style map Toolbutton \
	    -relief [list \
		    disabled flat \
		    selected sunken \
		    pressed sunken \
		    active raised] \
	    -background [list \
		    disabled $colors(-frame) \
		    pressed $colors(-darker) \
		    active $colors(-lighter)] \
	    -lightcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)] \
	    ;

	ttk::style configure TCheckbutton \
	    -indicatorbackground "#ffffff" \
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style configure TRadiobutton \
	    -indicatorbackground "#ffffff" \
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style map TCheckbutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]
	ttk::style map TRadiobutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]

	ttk::style configure TMenubutton \

	    -width -11 -padding 5 -relief raised

	ttk::style configure TEntry -padding 1 -insertwidth 1
	ttk::style map TEntry \
	    -background [list  readonly $colors(-frame)] \
	    -bordercolor [list  focus $colors(-selectbg)] \
	    -lightcolor [list  focus "#6f9dc6"] \
	    -darkcolor [list  focus "#6f9dc6"] \
	    ;

	ttk::style configure TCombobox -padding 1 -insertwidth 1

	ttk::style map TCombobox \
	    -background [list active $colors(-lighter) \
			     pressed $colors(-lighter)] \
	    -fieldbackground [list {readonly focus} $colors(-selectbg) \
				  readonly $colors(-frame)] \
	    -foreground [list {readonly focus} $colors(-selectfg)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox \
	    -background [list  readonly $colors(-frame)] \
            -arrowcolor [list disabled $colors(-disabledfg)]


	ttk::style configure TNotebook.Tab -padding {6 2 6 2}
	ttk::style map TNotebook.Tab \
	    -padding [list selected {6 4 6 2}] \
	    -background [list selected $colors(-frame) {} $colors(-darker)] \
	    -lightcolor [list selected $colors(-lighter) {} $colors(-dark)] \
	    ;

	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont -relief raised -padding {3}


	ttk::style configure Treeview -background $colors(-window)




	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

    	ttk::style configure TLabelframe \
	    -labeloutside true -labelmargins {0 0 0 4} \
	    -borderwidth 2 -relief raised







	ttk::style configure TProgressbar -background $colors(-frame)


	ttk::style configure Sash -sashthickness 6 -gripcount 10
    }
}







|
<





|
|
|



|







|
|
<

|











|
<



|
|


|
|












>
|



|
|
|
<
|
<
|
>






|
>



|

|
|
>

|

|

|
<



|
>
>
|
>
>
>
>






|
|


>
>
>
>
>
>
|
>

|


30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
	    -bordercolor $colors(-darkest) \
	    -darkcolor $colors(-dark) \
	    -lightcolor $colors(-lighter) \
	    -troughcolor $colors(-darker) \
	    -selectbackground $colors(-selectbg) \
	    -selectforeground $colors(-selectfg) \
	    -selectborderwidth 0 \
	    -font TkDefaultFont


	ttk::style map "." \
	    -background [list disabled $colors(-frame) \
			     active $colors(-lighter)] \
	    -foreground [list disabled $colors(-disabledfg)] \
	    -selectbackground [list !focus $colors(-darkest)] \
	    -selectforeground [list !focus white]

	# -selectbackground [list  !focus "#847d73"]

	ttk::style configure TButton \
	    -anchor center -width -11 -padding 3.75p -relief raised
	ttk::style map TButton \
	    -background [list \
			     disabled $colors(-frame) \
			     pressed $colors(-darker) \
			     active $colors(-lighter)] \
	    -lightcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)] \
	    -bordercolor {alternate #000000}


	ttk::style configure Toolbutton \
	    -anchor center -padding 1.5p -relief flat
	ttk::style map Toolbutton \
	    -relief [list \
		    disabled flat \
		    selected sunken \
		    pressed sunken \
		    active raised] \
	    -background [list \
		    disabled $colors(-frame) \
		    pressed $colors(-darker) \
		    active $colors(-lighter)] \
	    -lightcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)]


	ttk::style configure TCheckbutton \
	    -indicatorbackground "#ffffff" \
	    -indicatormargin {0.75p 0.75p 3p 0.75p} \
	    -padding 1.5p
	ttk::style configure TRadiobutton \
	    -indicatorbackground "#ffffff" \
	    -indicatormargin {0.75p 0.75p 3p 0.75p} \
	    -padding 1.5p
	ttk::style map TCheckbutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]
	ttk::style map TRadiobutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]

	ttk::style configure TMenubutton \
	    -width -11 -arrowsize 3.75p -arrowpadding 2.25p -padding 3.75p \
	    -relief raised

	ttk::style configure TEntry -padding 1 -insertwidth 1
	ttk::style map TEntry \
	    -background [list readonly $colors(-frame)] \
	    -bordercolor [list focus $colors(-selectbg)] \
	    -lightcolor [list focus #6f9dc6]



	ttk::style configure TCombobox -padding 1 -insertwidth 1 \
	    -arrowsize 10.5p
	ttk::style map TCombobox \
	    -background [list active $colors(-lighter) \
			     pressed $colors(-lighter)] \
	    -fieldbackground [list {readonly focus} $colors(-selectbg) \
				  readonly $colors(-frame)] \
	    -foreground [list {readonly focus} $colors(-selectfg)] \
	    -arrowcolor [list disabled $colors(-disabledfg)] \
	    -bordercolor [list focus $colors(-selectbg)]
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 7.5p -padding {1.5p 0 7.5p 0}
	ttk::style map TSpinbox \
	    -background [list readonly $colors(-frame)] \
            -arrowcolor [list disabled $colors(-disabledfg)] \
	    -bordercolor [list focus $colors(-selectbg)]

	ttk::style configure TNotebook.Tab -padding {4.5p 1.5p 4.5p 1.5p}
	ttk::style map TNotebook.Tab \
	    -padding {selected {4.5p 3p 4.5p 1.5p}} \
	    -background [list selected $colors(-frame) {} $colors(-darker)] \
	    -lightcolor [list selected $colors(-lighter) {} $colors(-dark)]


	# Treeview:
	ttk::style configure Heading \
	    -font TkHeadingFont -relief raised -padding 2.25p
	ttk::style configure Item -indicatorsize 9p \
	    -indicatormargins {1.5p 1.5p 3p 1.5p}
	ttk::style configure Treeview -background $colors(-window) \
	    -stripedbackground $colors(-lighter) -indent 15p
	ttk::setTreeviewRowHeight
	ttk::style configure Treeview.Separator \
	    -background $colors(-lighter)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	ttk::style configure TLabelframe \
	    -labeloutside true -labelmargins {0 0 0 3p} \
	    -borderwidth 2 -relief raised

	ttk::style configure TScrollbar -gripsize 7.5p \
	    -arrowsize 10.5p -width 10.5p

	ttk::style configure TScale -gripsize 7.5p \
	    -arrowsize 10.5p -sliderlength 22.5p

	ttk::style configure TProgressbar -background $colors(-frame) \
	    -arrowsize 10.5p -sliderlength 22.5p

	ttk::style configure Sash -sashthickness 4.5p -gripsize 15p
    }
}

Changes to library/ttk/classicTheme.tcl.

1
2
3
4
5
6
7
8
9

10
11

12
13
14
15
16
17
18
#
# "classic" Tk theme.
#
# Implements Tk's traditional Motif-like look and feel.
#

namespace eval ttk::theme::classic {

    variable colors; array set colors {

	-frame		"#d9d9d9"
	-window		"#ffffff"

	-activebg	"#ececec"
	-troughbg	"#c3c3c3"
	-selectbg	"#c3c3c3"
	-selectfg	"#000000"
	-disabledfg	"#a3a3a3"
	-indicator	"#b03060"
	-altindicator	"#b05e5e"








|
>


>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
# "classic" Tk theme.
#
# Implements Tk's traditional Motif-like look and feel.
#

namespace eval ttk::theme::classic {

    variable colors
    array set colors {
	-frame		"#d9d9d9"
	-window		"#ffffff"
	-alternate	"#f0f0f0"
	-activebg	"#ececec"
	-troughbg	"#c3c3c3"
	-selectbg	"#c3c3c3"
	-selectfg	"#000000"
	-disabledfg	"#a3a3a3"
	-indicator	"#b03060"
	-altindicator	"#b05e5e"
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68

69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88

89
90
91


92
93
94
95
96
97
98


99




100
101
102
103
104
105
106
107
108
109
110
111
112
113
114


115

	    -selectbackground	$colors(-selectbg) \
	    -selectforeground	$colors(-selectfg) \
	    -troughcolor	$colors(-troughbg) \
	    -indicatorcolor	$colors(-frame) \
	    -highlightcolor	$colors(-frame) \
	    -highlightthickness	1 \
	    -selectborderwidth	1 \
	    -insertwidth	2 \
	    ;

	# To match pre-Xft X11 appearance, use:
	#	ttk::style configure . -font {Helvetica 12 bold}

	ttk::style map "." -background \
	    [list disabled $colors(-frame) active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style map "." -highlightcolor [list focus black]

	ttk::style configure TButton \
	    -anchor center -padding "3m 1m" -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken]

	ttk::style configure TCheckbutton -indicatorrelief raised

	ttk::style map TCheckbutton \
	    -indicatorcolor [list \
		    pressed $colors(-frame) \
		    alternate $colors(-altindicator) \
		    selected $colors(-indicator)] \
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken} \
	    ;

	ttk::style configure TRadiobutton -indicatorrelief raised

	ttk::style map TRadiobutton \
	    -indicatorcolor [list \
		    pressed $colors(-frame) \
		    alternate $colors(-altindicator) \
		    selected $colors(-indicator)] \
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken} \
	    ;

	ttk::style configure TMenubutton -relief raised -padding "3m 1m"


	ttk::style configure TEntry -relief sunken -padding 1 -font TkTextFont
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -padding 1
	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TLabelframe -borderwidth 2 -relief groove

	ttk::style configure TScrollbar -relief raised

	ttk::style map TScrollbar -relief {{pressed !disabled} sunken}

	ttk::style configure TScale -sliderrelief raised

	ttk::style map TScale -sliderrelief {{pressed !disabled} sunken}

	ttk::style configure TProgressbar -background SteelBlue


	ttk::style configure TNotebook.Tab \
	    -padding {3m 1m} \
	    -background $colors(-troughbg)
	ttk::style map TNotebook.Tab -background [list selected $colors(-frame)]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised


	ttk::style configure Treeview -background $colors(-window)




	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	#
	# Toolbar buttons:
	#
	ttk::style configure Toolbutton -padding 2 -relief flat -shiftrelief 2
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-troughbg)  active $colors(-activebg)]
    }


}








|
<









|



|

|
>





|
|
<
|
>





|
|
<
|
>

|


>
|





|





|
>


|
>


|
>
>







>
>
|
>
>
>
>









|




|
>
>
|
>
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
	    -selectbackground	$colors(-selectbg) \
	    -selectforeground	$colors(-selectfg) \
	    -troughcolor	$colors(-troughbg) \
	    -indicatorcolor	$colors(-frame) \
	    -highlightcolor	$colors(-frame) \
	    -highlightthickness	1 \
	    -selectborderwidth	1 \
	    -insertwidth	2


	# To match pre-Xft X11 appearance, use:
	#	ttk::style configure . -font {Helvetica 12 bold}

	ttk::style map "." -background \
	    [list disabled $colors(-frame) active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style map "." -highlightcolor {focus black}

	ttk::style configure TButton \
	    -anchor center -padding "3m 1m" -relief raised -shiftrelief 1
	ttk::style map TButton -relief {{!disabled pressed} sunken}

	ttk::style configure TCheckbutton -indicatorrelief raised \
	    -indicatormargin {0 1.5p 3p 1.5p}
	ttk::style map TCheckbutton \
	    -indicatorcolor [list \
		    pressed $colors(-frame) \
		    alternate $colors(-altindicator) \
		    selected $colors(-indicator)] \
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken}


	ttk::style configure TRadiobutton -indicatorrelief raised \
	    -indicatormargin {0 1.5p 3p 1.5p}
	ttk::style map TRadiobutton \
	    -indicatorcolor [list \
		    pressed $colors(-frame) \
		    alternate $colors(-altindicator) \
		    selected $colors(-indicator)] \
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken}


	ttk::style configure TMenubutton -relief raised \
	    -indicatormargin {3.75p 0} -padding {3m 1m}

	ttk::style configure TEntry -padding 1 -font TkTextFont
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -padding 1 -arrowsize 11.75p
	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 7.5p -padding {1.5p 0 7.5p 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TLabelframe -borderwidth 2 -relief groove

	ttk::style configure TScrollbar -relief raised \
	    -arrowsize 11.25p -width 11.25p -troughborderwidth 2
	ttk::style map TScrollbar -relief {{pressed !disabled} sunken}

	ttk::style configure TScale -sliderrelief raised \
	    -sliderlength 22.5p -sliderthickness 11.25p -troughborderwidth 2
	ttk::style map TScale -sliderrelief {{pressed !disabled} sunken}

	ttk::style configure TProgressbar -background SteelBlue \
	    -barsize 22.5p -thickness 11.25p -troughborderwidth 2

	ttk::style configure TNotebook.Tab \
	    -padding {3m 1m} \
	    -background $colors(-troughbg)
	ttk::style map TNotebook.Tab -background [list selected $colors(-frame)]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Item -indicatorsize 9p \
	    -indicatormargins {1.5p 1.5p 3p 1.5p}
	ttk::style configure Treeview -background $colors(-window) \
	    -stripedbackground $colors(-alternate) -indent 15p
	ttk::setTreeviewRowHeight
	ttk::style configure Treeview.Separator \
	    -background $colors(-alternate)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	#
	# Toolbar buttons:
	#
	ttk::style configure Toolbutton -padding 1.5p -relief flat -shiftrelief 2
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-troughbg)  active $colors(-activebg)]

	ttk::style configure Sash \
	    -sashthickness 4.5p -sashpad 1.5 -handlesize 6p -handlepad 6p
    }
}

Changes to library/ttk/combobox.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25


26
27
28
29
30
31
32

33
34
35
36
37
38
39
#	(Tk 8.4.8+)
#
#	On X11: WM_TRANSIENT_FOR on override-redirect windows
#	may be used by compositing managers and by EWMH-aware
#	window managers (even though the older ICCCM spec says
#	it's meaningless).
#
#	On OSX: [wm transient] does utterly the wrong thing.
#	Instead, we use [MacWindowStyle "help" "noActivates hideOnSuspend"].
#	The "noActivates" attribute prevents the parent toplevel
#	from deactivating when the popdown is posted, and is also
#	necessary for "help" windows to receive mouse events.
#	"hideOnSuspend" makes the popdown disappear (resp. reappear)
#	when the parent toplevel is deactivated (resp. reactivated).


#	(see [#1814778]).  Also set [wm resizable 0 0], to prevent
#	TkAqua from shrinking the scrollbar to make room for a grow box
#	that isn't there.
#
#	In order to work around other platform quirks in TkAqua,
#	[grab] and [focus] are set in <Map> bindings instead of
#	immediately after deiconifying the window.

#

namespace eval ttk::combobox {
    variable Values	;# Values($cb) is -listvariable of listbox widget
    variable State
    set State(entryPress) 0
}







|
|
|
|
<
<
|
>
>
|
|
<
<
|
<
<
>







12
13
14
15
16
17
18
19
20
21
22


23
24
25
26
27


28


29
30
31
32
33
34
35
36
#	(Tk 8.4.8+)
#
#	On X11: WM_TRANSIENT_FOR on override-redirect windows
#	may be used by compositing managers and by EWMH-aware
#	window managers (even though the older ICCCM spec says
#	it's meaningless).
#
#       On OSX: The native combobox uses a popup menu to display the
#       combobox choices.  So this implementation does that as well,
#       rather than construc a Tk listbox.  Since the window manager
#       takes care of scrolling and making sure that the menu can be


#       displayed even when the button is close to the bottom of the
#       screen, this actually simplifies the implementation.  The Post
#       and PopupWindow procs have separate implementations for Aqua
#       and other systems.  The configuration of the menu is handled
#       by a different proc than the one which configures the listbox


#       on other platforms -- ConfigureAquaMenu instead of


#       ConfigureListbox.
#

namespace eval ttk::combobox {
    variable Values	;# Values($cb) is -listvariable of listbox widget
    variable State
    set State(entryPress) 0
}
51
52
53
54
55
56
57
58


59







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78



79
80
81
82
83
84
85
bind TCombobox <Button-1> 		{ ttk::combobox::Press "" %W %x %y }
bind TCombobox <Shift-Button-1>		{ ttk::combobox::Press "s" %W %x %y }
bind TCombobox <Double-Button-1> 	{ ttk::combobox::Press "2" %W %x %y }
bind TCombobox <Triple-Button-1> 	{ ttk::combobox::Press "3" %W %x %y }
bind TCombobox <B1-Motion>		{ ttk::combobox::Drag %W %x }
bind TCombobox <Motion>			{ ttk::combobox::Motion %W %x %y }

ttk::bindMouseWheel TCombobox [list ttk::combobox::Scroll %W]










bind TCombobox <<TraverseIn>> 		{ ttk::combobox::TraverseIn %W }

### Combobox listbox bindings.
#
bind ComboboxListbox <ButtonRelease-1>	{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <Return>		{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <Escape>		{ ttk::combobox::LBCancel %W }
bind ComboboxListbox <Tab>		{ ttk::combobox::LBTab %W next }
bind ComboboxListbox <<PrevWindow>>	{ ttk::combobox::LBTab %W prev }
bind ComboboxListbox <Destroy>		{ ttk::combobox::LBCleanup %W }
bind ComboboxListbox <Motion>		{ ttk::combobox::LBHover %W %x %y }
bind ComboboxListbox <Map>		{ focus -force %W }

switch -- [tk windowingsystem] {
    win32 {
	# Dismiss listbox when user switches to a different application.
	# NB: *only* do this on Windows (see #1814778)
	bind ComboboxListbox <FocusOut>		{ ttk::combobox::LBCancel %W }
    }



}

### Combobox popdown window bindings.
#
bind ComboboxPopdown	<Map>		{ ttk::combobox::MapPopdown %W }
bind ComboboxPopdown	<Unmap>		{ ttk::combobox::UnmapPopdown %W }
bind ComboboxPopdown	<Button> \







|
>
>
|
>
>
>
>
>
>
>



















>
>
>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
bind TCombobox <Button-1> 		{ ttk::combobox::Press "" %W %x %y }
bind TCombobox <Shift-Button-1>		{ ttk::combobox::Press "s" %W %x %y }
bind TCombobox <Double-Button-1> 	{ ttk::combobox::Press "2" %W %x %y }
bind TCombobox <Triple-Button-1> 	{ ttk::combobox::Press "3" %W %x %y }
bind TCombobox <B1-Motion>		{ ttk::combobox::Drag %W %x }
bind TCombobox <Motion>			{ ttk::combobox::Motion %W %x %y }

ttk::bindMouseWheel TCombobox		{ ttk::combobox::Scroll %W }
bind TCombobox <Shift-MouseWheel> {
    # Ignore the event
}
bind TCombobox <TouchpadScroll> {
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    # TouchpadScroll events fire about 60 times per second.
    if {$deltaY != 0 && %# %% 15 == 0} {
	ttk::combobox::Scroll %W [expr {$deltaY > 0 ? -1 : 1}]
    }
}
bind TCombobox <<TraverseIn>> 		{ ttk::combobox::TraverseIn %W }

### Combobox listbox bindings.
#
bind ComboboxListbox <ButtonRelease-1>	{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <Return>		{ ttk::combobox::LBSelected %W }
bind ComboboxListbox <Escape>		{ ttk::combobox::LBCancel %W }
bind ComboboxListbox <Tab>		{ ttk::combobox::LBTab %W next }
bind ComboboxListbox <<PrevWindow>>	{ ttk::combobox::LBTab %W prev }
bind ComboboxListbox <Destroy>		{ ttk::combobox::LBCleanup %W }
bind ComboboxListbox <Motion>		{ ttk::combobox::LBHover %W %x %y }
bind ComboboxListbox <Map>		{ focus -force %W }

switch -- [tk windowingsystem] {
    win32 {
	# Dismiss listbox when user switches to a different application.
	# NB: *only* do this on Windows (see #1814778)
	bind ComboboxListbox <FocusOut>		{ ttk::combobox::LBCancel %W }
    }
    aqua {
	bind TCombobox <Destroy>		{ ttk::combobox::AquaCleanup %W }
    }
}

### Combobox popdown window bindings.
#
bind ComboboxPopdown	<Map>		{ ttk::combobox::MapPopdown %W }
bind ComboboxPopdown	<Unmap>		{ ttk::combobox::UnmapPopdown %W }
bind ComboboxPopdown	<Button> \
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

## Platform-specific settings.
#
switch -- [tk windowingsystem] {
    x11 {
	option add *TCombobox*Listbox.background white widgetDefault
    }
    aqua {
	option add *TCombobox*Listbox.borderWidth 0 widgetDefault
    }
}

### Binding procedures.
#

## Press $mode $x $y -- Button binding for comboboxes.
#	Either post/unpost the listbox, or perform Entry widget binding,







<
<
<







103
104
105
106
107
108
109



110
111
112
113
114
115
116

## Platform-specific settings.
#
switch -- [tk windowingsystem] {
    x11 {
	option add *TCombobox*Listbox.background white widgetDefault
    }



}

### Binding procedures.
#

## Press $mode $x $y -- Button binding for comboboxes.
#	Either post/unpost the listbox, or perform Entry widget binding,
182
183
184
185
186
187
188



189

190
191
192
193
194
195
196
197
198
199
200
201
202

## Scroll -- Mousewheel binding
#
proc ttk::combobox::Scroll {cb dir {factor 1.0}} {
    $cb instate disabled { return }
    set max [llength [$cb cget -values]]
    set current [$cb current]



    set d [expr {round($dir/factor)}]

    if {$d == 0 && $dir != 0} {
	if {$dir > 0} {set d 1} else {set d -1}
    }
    incr current $d
    if {$max != 0 && $current == $current % $max} {
	SelectEntry $cb $current
    }
}

## LBSelected $lb -- Activation binding for listbox
#	Set the combobox value to the currently-selected listbox value
#	and unpost the listbox.
#







>
>
>
|
>
|
|

<
|
|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211

## Scroll -- Mousewheel binding
#
proc ttk::combobox::Scroll {cb dir {factor 1.0}} {
    $cb instate disabled { return }
    set max [llength [$cb cget -values]]
    set current [$cb current]
    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.
#
257
258
259
260
261
262
263


264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
















292
293
294
295
296
297
298
    ttk::releaseGrab $w
}

## PopdownWindow --
#	Returns the popdown widget associated with a combobox,
#	creating it if necessary.
#


proc ttk::combobox::PopdownWindow {cb} {
    if {![winfo exists $cb.popdown]} {
	set poplevel [PopdownToplevel $cb.popdown]
	set popdown [ttk::frame $poplevel.f -style ComboboxPopdownFrame]

	ttk::scrollbar $popdown.sb \
	    -orient vertical -command [list $popdown.l yview]
	listbox $popdown.l \
	    -listvariable ttk::combobox::Values($cb) \
	    -yscrollcommand [list $popdown.sb set] \
	    -exportselection false \
	    -selectmode browse \
	    -activestyle none \
	    ;

	bindtags $popdown.l \
	    [list $popdown.l ComboboxListbox Listbox $popdown all]

	grid $popdown.l -row 0 -column 0 -padx {1 0} -pady 1 -sticky nsew
        grid $popdown.sb -row 0 -column 1 -padx {0 1} -pady 1 -sticky ns
	grid columnconfigure $popdown 0 -weight 1
	grid rowconfigure $popdown 0 -weight 1

        grid $popdown -sticky news -padx 0 -pady 0
        grid rowconfigure $poplevel 0 -weight 1
        grid columnconfigure $poplevel 0 -weight 1
    }
    return $cb.popdown
















}

## PopdownToplevel -- Create toplevel window for the combobox popdown
#
#	See also <<NOTE-WM-TRANSIENT>>
#
proc ttk::combobox::PopdownToplevel {w} {







>
>
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|

|
|
|
|

|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    ttk::releaseGrab $w
}

## PopdownWindow --
#	Returns the popdown widget associated with a combobox,
#	creating it if necessary.
#

if {[tk windowingsystem] ne "aqua"} {
    proc ttk::combobox::PopdownWindow {cb} {
	if {![winfo exists $cb.popdown]} {
	    set poplevel [PopdownToplevel $cb.popdown]
	    set popdown [ttk::frame $poplevel.f -style ComboboxPopdownFrame]

	    ttk::scrollbar $popdown.sb \
		-orient vertical -command [list $popdown.l yview]
	    listbox $popdown.l \
		-listvariable ttk::combobox::Values($cb) \
		-yscrollcommand [list $popdown.sb set] \
		-exportselection false \
		-selectmode browse \
		-activestyle none \
		;

	    bindtags $popdown.l \
		[list $popdown.l ComboboxListbox Listbox $popdown all]

	    grid $popdown.l -row 0 -column 0 -padx {1 0} -pady 1 -sticky nsew
	    grid $popdown.sb -row 0 -column 1 -padx {0 1} -pady 1 -sticky ns
	    grid columnconfigure $popdown 0 -weight 1
	    grid rowconfigure $popdown 0 -weight 1

	    grid $popdown -sticky news -padx 0 -pady 0
	    grid rowconfigure $poplevel 0 -weight 1
	    grid columnconfigure $poplevel 0 -weight 1
	}
	return $cb.popdown
    }
} else {
    proc ttk::combobox::PopdownWindow {cb} {
	if {![winfo exists $cb.popdown]} {
	    set poplevel [PopdownToplevel $cb.popdown]
	    # The menu should be (at least) the same length as the button.
	    # Since there is no direct way to control the width of a menu
	    # in Tk, we fake it by using an invisible image in a disabled
	    # menu item, adjusting the image size to make the menu be the
	    # correct width.
	    image create nsimage $cb.spacer -source NSStatusNone -as name \
		-alpha 0
	    set menu [menu $cb.popdown.menu -tearoff 0]
	}
	return $cb.popdown
    }
}

## PopdownToplevel -- Create toplevel window for the combobox popdown
#
#	See also <<NOTE-WM-TRANSIENT>>
#
proc ttk::combobox::PopdownToplevel {w} {
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
	}
	win32 {
	    $w configure -relief flat -borderwidth 0
	    wm overrideredirect $w true
	    wm attributes $w -topmost 1
	}
	aqua {
	    $w configure -relief solid -borderwidth 0
	    tk::unsupported::MacWindowStyle style $w \
	    	help {noActivates hideOnSuspend}
	    wm resizable $w 0 0
	}
    }
    return $w
}

## ConfigureListbox --
#	Set listbox values, selection, height, and scrollbar visibility







<
<
|
|







334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349
	}
	win32 {
	    $w configure -relief flat -borderwidth 0
	    wm overrideredirect $w true
	    wm attributes $w -topmost 1
	}
	aqua {


	    wm overrideredirect $w true
	    wm attributes $w -alpha 0
	}
    }
    return $w
}

## ConfigureListbox --
#	Set listbox values, selection, height, and scrollbar visibility
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

































352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380














381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408


























409
410
411
412
413
414
415
    $popdown.l selection clear 0 end
    $popdown.l selection set $current
    $popdown.l activate $current
    $popdown.l see $current
    set height [llength $values]
    if {$height > [$cb cget -height]} {
	set height [$cb cget -height]
    	grid $popdown.sb
        grid configure $popdown.l -padx {1 0}
    } else {
	grid remove $popdown.sb
        grid configure $popdown.l -padx 1
    }
    $popdown.l configure -height $height
}


































## PlacePopdown --
#	Set popdown window geometry.
#
# @@@TODO: factor with menubutton::PostPosition
#
proc ttk::combobox::PlacePopdown {cb popdown} {
    set x [winfo rootx $cb]
    set y [winfo rooty $cb]
    set w [winfo width $cb]
    set h [winfo height $cb]
    set style [$cb cget -style]
    if { $style eq {} } {
      set style TCombobox
    }
    set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}]
    foreach var {x y w h} delta $postoffset {
    	incr $var $delta
    }

    set H [winfo reqheight $popdown]
    if {$y + $h + $H > [winfo screenheight $popdown]} {
	set Y [expr {$y - $H}]
    } else {
	set Y [expr {$y + $h}]
    }
    wm geometry $popdown ${w}x${H}+${x}+${Y}
}















## Post $cb --
#	Pop down the associated listbox.
#

proc ttk::combobox::Post {cb} {
    # Don't do anything if disabled:
    #
    $cb instate disabled { return }

    # ASSERT: ![$cb instate pressed]

    # Run -postcommand callback:
    #
    uplevel #0 [$cb cget -postcommand]

    set popdown [PopdownWindow $cb]
    ConfigureListbox $cb
    update idletasks	;# needed for geometry propagation.
    PlacePopdown $cb $popdown
    # See <<NOTE-WM-TRANSIENT>>
    switch -- [tk windowingsystem] {
	x11 - win32 { wm transient $popdown [winfo toplevel $cb] }
    }

    # Post the listbox:
    #
    wm attribute $popdown -topmost 1
    wm deiconify $popdown
    raise $popdown


























}

## Unpost $cb --
#	Unpost the listbox.
#
proc ttk::combobox::Unpost {cb} {
    if {[winfo exists $cb.popdown]} {







|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















|











>
>
>
>
>
>
>
>
>
>
>
>
>
>

|

>
|
|
|
|

|

|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    $popdown.l selection clear 0 end
    $popdown.l selection set $current
    $popdown.l activate $current
    $popdown.l see $current
    set height [llength $values]
    if {$height > [$cb cget -height]} {
	set height [$cb cget -height]
	grid $popdown.sb
        grid configure $popdown.l -padx {1 0}
    } else {
	grid remove $popdown.sb
        grid configure $popdown.l -padx 1
    }
    $popdown.l configure -height $height
}

proc ttk::combobox::ConfigureAquaMenu {cb width} {
    set popdown [PopdownWindow $cb]
    set values [$cb cget -values]
    set current [$cb current]
    if {$current < 0} {
	set current 0 		;# no current entry, highlight first one
    }
    $cb.popdown.menu delete 0 end
    $cb.spacer configure -width [expr {$width - 40}] -height 1
    set i 0
    foreach item $values {
	if {$i == 0} {
	    # Add spaces to the first item to make the menu as long as cb
	    set menufont [$cb cget -font]
	    set stretch $item
	    while {[font measure $menufont $stretch] < [expr {$width - 32}]} {
		set stretch "$stretch "
	    }
	    $cb.popdown.menu add command -label "$stretch" \
		-command "ttk::combobox::SelectEntry $cb $i"
	} else {
	    $cb.popdown.menu add command -label "$item" \
		-command "ttk::combobox::SelectEntry $cb $i"
	}
	incr i
    }
    if { $i == 0 } {
	# There are no items.  To make an empty menu appear add a dummy item
	# containing a transparent image of the right width.
	$cb.popdown.menu add command -label {} -image $cb.spacer -state disabled
    }
}

## PlacePopdown --
#	Set popdown window geometry.
#
# @@@TODO: factor with menubutton::PostPosition
#
proc ttk::combobox::PlacePopdown {cb popdown} {
    set x [winfo rootx $cb]
    set y [winfo rooty $cb]
    set w [winfo width $cb]
    set h [winfo height $cb]
    set style [$cb cget -style]
    if { $style eq {} } {
      set style TCombobox
    }
    set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}]
    foreach var {x y w h} delta $postoffset {
	incr $var $delta
    }

    set H [winfo reqheight $popdown]
    if {$y + $h + $H > [winfo screenheight $popdown]} {
	set Y [expr {$y - $H}]
    } else {
	set Y [expr {$y + $h}]
    }
    wm geometry $popdown ${w}x${H}+${x}+${Y}
}

proc ttk::combobox::AquaPlacePopdown {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]
    set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}]
    foreach var {x y w h} delta $postoffset {
    	incr $var $delta
    }
    wm geometry $popdown ${w}x${h}+${x}+${y}
    return [list $x $y $w $h]
}

## Post $cb --
#	Pop down the associated listbox or menu.
#
if {[tk windowingsystem] ne "aqua"} {
    proc ttk::combobox::Post {cb} {
	# Don't do anything if disabled:
	#
	$cb instate disabled { return }

	# ASSERT: ![$cb instate pressed]

	# Run -postcommand callback:
	#
	uplevel #0 [$cb cget -postcommand]

	set popdown [PopdownWindow $cb]
	ConfigureListbox $cb
	update idletasks	;# needed for geometry propagation.
	PlacePopdown $cb $popdown
	# See <<NOTE-WM-TRANSIENT>>
	switch -- [tk windowingsystem] {
	    x11 - win32 { wm transient $popdown [winfo toplevel $cb] }
	}

	# Post the listbox:
	#
	wm attribute $popdown -topmost 1
	wm deiconify $popdown
	raise $popdown
    }
} else {
    proc ttk::combobox::Post {cb} {
	# Don't do anything if disabled:
	#
	$cb instate disabled { return }

	# ASSERT: ![$cb instate pressed]

	# Run -postcommand callback:
	#
	uplevel #0 [$cb cget -postcommand]

	set popdown [PopdownWindow $cb]

	# Configure the menu

	foreach {x y width height} [AquaPlacePopdown $cb $popdown] { break }
	ConfigureAquaMenu $cb [winfo width $cb]

	# Post the menu.  It will have a disclosure indicator if it is too
	# close to the bottom of the screen, and it may be posted above the
	# button if necessary to be visible.

	$popdown.menu post [expr {$x + 2}] [expr {$y + $height + 2}]
    }
}

## Unpost $cb --
#	Unpost the listbox.
#
proc ttk::combobox::Unpost {cb} {
    if {[winfo exists $cb.popdown]} {
444
445
446
447
448
449
450
451




452
#	because the widget command is already gone when this binding fires).
#	[winfo parent] still works, fortunately.
#
proc ttk::combobox::LBCleanup {lb} {
    variable Values
    unset Values([LBMain $lb])
}





#*EOF*








>
>
>
>

543
544
545
546
547
548
549
550
551
552
553
554
555
#	because the widget command is already gone when this binding fires).
#	[winfo parent] still works, fortunately.
#
proc ttk::combobox::LBCleanup {lb} {
    variable Values
    unset Values([LBMain $lb])
}

proc ttk::combobox::AquaCleanup {cb} {
    catch {image delete $cb.spacer}
}

#*EOF*

Changes to library/ttk/defaults.tcl.

1
2
3
4
5

6
7
8
9
10

11
12
13
14
15
16
17
18
19

20



























21
































22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69

70
71



72
73
74

75
76
77
78



79
80
81
82
83



84
85
86
87
88
89
90
91
92
93
94
95
96






97
98
99



100
101
102
103
104


105
106
107
108


109
110


111




112
113
114
115
116
117
118
#
# Settings for default theme.
#

namespace eval ttk::theme::default {

    variable colors
    array set colors {
	-frame			"#d9d9d9"
	-foreground		"#000000"
	-window			"#ffffff"

	-text   		"#000000"
	-activebg		"#ececec"
	-selectbg		"#4a6984"
	-selectfg		"#ffffff"
	-darker 		"#c3c3c3"
	-disabledfg		"#a3a3a3"
	-indicator		"#4a6984"
	-disabledindicator	"#a3a3a3"
	-altindicator		"#9fbdd8"

	-disabledaltindicator	"#c0c0c0"



























    }

































    ttk::style theme settings default {

	ttk::style configure "." \
	    -borderwidth 	1 \
	    -background 	$colors(-frame) \
	    -foreground 	$colors(-foreground) \
	    -troughcolor 	$colors(-darker) \
	    -font 		TkDefaultFont \
	    -selectborderwidth	1 \
	    -selectbackground	$colors(-selectbg) \
	    -selectforeground	$colors(-selectfg) \
	    -insertwidth 	1 \
	    -indicatordiameter	10 \
	    ;


	ttk::style map "." -background \
	    [list disabled $colors(-frame)  active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style configure TButton \
	    -anchor center -padding "3 3" -width -9 \
	    -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken]


	ttk::style configure TCheckbutton \
	    -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1
	ttk::style map TCheckbutton -indicatorcolor \
	    [list pressed $colors(-activebg)  \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			{!disabled selected} $colors(-indicator) \
			{disabled selected} $colors(-disabledindicator)]
	ttk::style map TCheckbutton -indicatorrelief \
	    [list alternate raised]

	ttk::style configure TRadiobutton \
	    -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1
	ttk::style map TRadiobutton -indicatorcolor \
	    [list pressed $colors(-activebg)  \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			{!disabled selected} $colors(-indicator) \

			{disabled selected} $colors(-disabledindicator)]
	ttk::style map TRadiobutton -indicatorrelief \
	    [list alternate raised]


	ttk::style configure TMenubutton \
	    -relief raised -padding "10 3"




	ttk::style configure TEntry \
	    -relief sunken -fieldbackground white -padding 1

	ttk::style map TEntry -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -arrowsize 12 -padding 1



	ttk::style map TCombobox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}



	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TLabelframe \
	    -relief groove -borderwidth 2

	ttk::style configure TScrollbar \
	    -width 12 -arrowsize 12
	ttk::style map TScrollbar \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TScale \






	    -sliderrelief raised
	ttk::style configure TProgressbar \
	    -background $colors(-selectbg)




	ttk::style configure TNotebook.Tab \
	    -padding {4 2} -background $colors(-darker)
	ttk::style map TNotebook.Tab \
	    -background [list selected $colors(-frame)]



	# Treeview.
	#
	ttk::style configure Heading -font TkHeadingFont -relief raised


	ttk::style configure Treeview \
	    -background $colors(-window) \


	    -foreground $colors(-text) ;




	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	# Combobox popdown frame





>





>








|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|



|
<
>







|



>
|
<
<
|
|
|
|
|
|
|
|
<
<
<
<
|
<
|
>
|
<
<
|
>

|
>
>
>


|
>



|
>
>
>




|
>
>
>








|




>
>
>
>
>
>
|

|
>
>
>


|

|
>
>




>
>


>
>
|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111


112
113
114
115
116
117
118
119




120

121
122
123


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#
# Settings for default theme.
#

namespace eval ttk::theme::default {

    variable colors
    array set colors {
	-frame			"#d9d9d9"
	-foreground		"#000000"
	-window			"#ffffff"
	-alternate		"#e8e8e8"
	-text   		"#000000"
	-activebg		"#ececec"
	-selectbg		"#4a6984"
	-selectfg		"#ffffff"
	-darker 		"#c3c3c3"
	-disabledfg		"#a3a3a3"
	-indicator		"#4a6984"
	-disabledindicator	"#a3a3a3"
	-pressedindicator	"#5895bc"
    }

    # On X11, if the user specifies their own choice of colour scheme via
    # X resources, then set the colour palette based on the user's choice.
    if {[tk windowingsystem] eq "x11"} {
	foreach \
		xResourceName {
		    {	background		Background		}
		    {	foreground		Foreground		}
		    {	background		Background		}
		    {	background		Background		}
		    {	foreground		Foreground		}
		    {	activeBackground	ActiveBackground	}
		    {	selectBackground	SelectBackground	}
		    {	selectForeground	SelectForeground	}
		    {	troughColor		TroughColor		}
		    {	disabledForeground	DisabledForeground	}
		    {	selectBackground	SelectBackground	}
		    {	disabledForeground	DisabledForeground	}
		    {	selectBackground	SelectBackground	}
		    {	windowColor		Background		} } \
		colorName {
		    -frame -foreground -window -alternate -text
		    -activebg -selectbg -selectfg
		    -darker -disabledfg -indicator
		    -disabledindicator -pressedindicator -window } {
	    set color [eval option get . $xResourceName]
	    if {$color ne ""} {
		set colors($colorName) $color
	    }
	}
    }

    # This array is used to match up the tk widget options with
    # the corresponding values in the 'colors' array.
    # This is used by tk_setPalette to apply the new palette
    # to the ttk widgets.
    variable colorOptionLookup
    array set colorOptionLookup {
	background		{-frame -window -alternate}
	foreground		{-foreground -text}
	activeBackground	-activebg
	selectBackground	{-selectbg -indicator -pressedindicator}
	selectForeground	-selectfg
	troughColor		-darker
	disabledForeground	{-disabledfg -disabledindicator}
    }
}

# ttk::theme::default::reconfigureDefaultTheme --
#
# This procedure contains the definition of the 'default' theme itself.
# The theme definition is in a procedure, so it can be re-called when
# required, enabling tk_setPalette to set the colours of the ttk widgets.
#
# Arguments:
# None.

proc ttk::theme::default::reconfigureDefaultTheme {} {
    upvar ttk::theme::default::colors colors

    # The definition of the 'default' theme.

    ttk::style theme settings default {

	ttk::style configure "." \
	    -borderwidth 	1 \
	    -background 	$colors(-frame) \
	    -foreground 	$colors(-foreground) \
	    -troughcolor 	$colors(-darker) \
	    -font 		TkDefaultFont \
	    -selectborderwidth	0 \
	    -selectbackground	$colors(-selectbg) \
	    -selectforeground	$colors(-selectfg) \
	    -insertwidth 	1 \
	    -insertcolor	$colors(-foreground) \

	    -focuscolor		$colors(-text)

	ttk::style map "." -background \
	    [list disabled $colors(-frame)  active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style configure TButton \
	    -anchor center -padding 2.25p -width -9 \
	    -relief raised -shiftrelief 1
	ttk::style map TButton -relief [list {!disabled pressed} sunken]

	foreach style {TCheckbutton TRadiobutton} {
	    ttk::style configure $style \


		-indicatorbackground $colors(-window) \
		-indicatorforeground $colors(-selectfg) \
		-indicatormargin {0 1.5p 3p 1.5p} -padding 0.75p
	    ttk::style map $style -indicatorbackground \
		[list {alternate disabled}	$colors(-disabledindicator) \
		      {alternate pressed}	$colors(-pressedindicator) \
		      alternate			$colors(-indicator) \
		      {selected disabled}	$colors(-disabledindicator) \




		      {selected pressed}	$colors(-pressedindicator) \

		      selected			$colors(-indicator) \
		      disabled			$colors(-frame) \
		      pressed			$colors(-darker)]


	}

	ttk::style configure TMenubutton \
	    -relief raised -arrowsize 3.75p -arrowpadding 2.25p \
	    -arrowcolor $colors(-text) -padding {7.5p 2.25p}
	ttk::style map TMenubutton \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TEntry \
	    -fieldbackground $colors(-window) -padding 1 \
	    -focuswidth 2 -focuscolor $colors(-selectbg)
	ttk::style map TEntry -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox \
	    -arrowsize 9p -arrowcolor $colors(-text) \
	    -fieldbackground $colors(-window) -padding 1 \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TCombobox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TSpinbox \
	    -arrowsize 7.5p -arrowcolor $colors(-text) \
	    -fieldbackground $colors(-window) -padding {1.5p 0 7.5p 0} \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TLabelframe \
	    -relief groove -borderwidth 2

	ttk::style configure TScrollbar \
	    -width 9p -arrowsize 9p -arrowcolor $colors(-text)
	ttk::style map TScrollbar \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TScale \
	    -innercolor $colors(-selectbg) \
	    -outercolor $colors(-window) \
	    -bordercolor $colors(-darker) \
	    -groovewidth 3p
	ttk::style map TScale \
	    -outercolor [list active $colors(-activebg)]

	ttk::style configure TProgressbar \
	    -background $colors(-selectbg) \
	    -borderwidth 0 \
	    -barsize 22.5p \
	    -thickness 3p

	ttk::style configure TNotebook.Tab \
	    -padding {3p 1.5p} -background $colors(-darker)
	ttk::style map TNotebook.Tab \
	    -background [list selected $colors(-frame)] \
	    -highlight [list selected 1] \
	    -highlightcolor [list selected $colors(-selectbg)]

	# Treeview.
	#
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Item -indicatorsize 9p \
	    -indicatormargins {1.5p 1.5p 3p 1.5p}
	ttk::style configure Treeview \
	    -background $colors(-window) \
	    -stripedbackground $colors(-alternate) \
	    -fieldbackground $colors(-window) \
	    -foreground $colors(-text) \
	    -indent 15p
	ttk::setTreeviewRowHeight
	ttk::style configure Treeview.Separator \
	    -background $colors(-alternate)
	ttk::style map Treeview \
	    -background [list disabled $colors(-frame)\
				selected $colors(-selectbg)] \
	    -foreground [list disabled $colors(-disabledfg) \
				selected $colors(-selectfg)]

	# Combobox popdown frame
130
131
132
133
134
135
136
137
138
139
140
141
142
143


		Toolbutton.padding -children {
		    Toolbutton.label
		}
	    }
	}

	ttk::style configure Toolbutton \
	    -padding 2 -relief flat
	ttk::style map Toolbutton -relief \
	    [list disabled flat selected sunken pressed sunken active raised]
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-darker)  active $colors(-activebg)]
    }
}









|






>
>
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
		Toolbutton.padding -children {
		    Toolbutton.label
		}
	    }
	}

	ttk::style configure Toolbutton \
	    -padding 1.5p -relief flat
	ttk::style map Toolbutton -relief \
	    [list disabled flat selected sunken pressed sunken active raised]
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-darker)  active $colors(-activebg)]
    }
}

ttk::theme::default::reconfigureDefaultTheme

Changes to library/ttk/entry.tcl.

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
bind TEntry <<NextWord>>		{ ttk::entry::Move %W nextword }
bind TEntry <<LineStart>>		{ ttk::entry::Move %W home }
bind TEntry <<LineEnd>>			{ ttk::entry::Move %W end }

bind TEntry <<SelectPrevChar>> 		{ ttk::entry::Extend %W prevchar }
bind TEntry <<SelectNextChar>>		{ ttk::entry::Extend %W nextchar }
bind TEntry <<SelectPrevWord>>		{ ttk::entry::Extend %W prevword }
bind TEntry <<SelectNextWord>>		{ ttk::entry::Extend %W nextword }
bind TEntry <<SelectLineStart>>		{ ttk::entry::Extend %W home }
bind TEntry <<SelectLineEnd>>		{ ttk::entry::Extend %W end }

bind TEntry <<SelectAll>> 		{ %W selection range 0 end }
bind TEntry <<SelectNone>> 		{ %W selection clear }

bind TEntry <<TraverseIn>> 	{ %W selection range 0 end; %W icursor end }

## Edit bindings:
#
bind TEntry <Key> 			{ ttk::entry::Insert %W %A }
bind TEntry <Delete>			{ ttk::entry::Delete %W }
bind TEntry <BackSpace> 		{ ttk::entry::Backspace %W }

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Otherwise, the <Key> class binding will fire and insert the character.
# Ditto for Escape, Return, and Tab.
#
bind TEntry <Alt-Key>			{# nothing}
bind TEntry <Meta-Key>			{# nothing}
bind TEntry <Control-Key> 		{# nothing}
bind TEntry <Escape> 			{# nothing}
bind TEntry <Return> 			{# nothing}
bind TEntry <KP_Enter> 			{# nothing}
bind TEntry <Tab> 			{# nothing}

# Argh.  Apparently on Windows, the NumLock modifier is interpreted
# as a Command modifier.
if {[tk windowingsystem] eq "aqua"} {
    bind TEntry <Command-Key>		{# nothing}

}
# Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
bind TEntry <<PrevLine>>		{# nothing}
bind TEntry <<NextLine>>		{# nothing}

## Additional emacs-like bindings:
#
bind TEntry <Control-d>			{ ttk::entry::Delete %W }







|














|










<
<
<
<
|
>
|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132




133
134
135
136
137
138
139
140
141
142
bind TEntry <<NextWord>>		{ ttk::entry::Move %W nextword }
bind TEntry <<LineStart>>		{ ttk::entry::Move %W home }
bind TEntry <<LineEnd>>			{ ttk::entry::Move %W end }

bind TEntry <<SelectPrevChar>> 		{ ttk::entry::Extend %W prevchar }
bind TEntry <<SelectNextChar>>		{ ttk::entry::Extend %W nextchar }
bind TEntry <<SelectPrevWord>>		{ ttk::entry::Extend %W prevword }
bind TEntry <<SelectNextWord>>		{ ttk::entry::Extend %W selectnextword }
bind TEntry <<SelectLineStart>>		{ ttk::entry::Extend %W home }
bind TEntry <<SelectLineEnd>>		{ ttk::entry::Extend %W end }

bind TEntry <<SelectAll>> 		{ %W selection range 0 end }
bind TEntry <<SelectNone>> 		{ %W selection clear }

bind TEntry <<TraverseIn>> 	{ %W selection range 0 end; %W icursor end }

## Edit bindings:
#
bind TEntry <Key> 			{ ttk::entry::Insert %W %A }
bind TEntry <Delete>			{ ttk::entry::Delete %W }
bind TEntry <BackSpace> 		{ ttk::entry::Backspace %W }

# Ignore all Alt, Meta, Control, Command, and Fn keypresses unless explicitly bound.
# Otherwise, the <Key> class binding will fire and insert the character.
# Ditto for Escape, Return, and Tab.
#
bind TEntry <Alt-Key>			{# nothing}
bind TEntry <Meta-Key>			{# nothing}
bind TEntry <Control-Key> 		{# nothing}
bind TEntry <Escape> 			{# nothing}
bind TEntry <Return> 			{# nothing}
bind TEntry <KP_Enter> 			{# nothing}
bind TEntry <Tab> 			{# nothing}




bind TEntry <Command-Key>		{# nothing}
bind TEntry <Fn-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 }
160
161
162
163
164
165
166













167
168
169
170
171
172
173
}
bind TEntry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind TEntry <<TkAccentBackspace>> {
    ttk::entry::Backspace %W
}














### Clipboard procedures.
#

## EntrySelection -- Return the selected text of the entry.
#	Raises an error if there is no selection.
#







>
>
>
>
>
>
>
>
>
>
>
>
>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
}
bind TEntry <<TkClearIMEMarkedText>> {
    %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
bind TEntry <<TkAccentBackspace>> {
    ttk::entry::Backspace %W
}

## EndIMEMarkedText -- Handle the end of input method selection.
#
proc ::ttk::entry::EndIMEMarkedText {w} {
    variable ::tk::Priv
    if {[catch {
	set mark [dict get $Priv(IMETextMark) $w]
    }]} {
	bell
	return
    }
    $w selection range $mark insert
}

### Clipboard procedures.
#

## EntrySelection -- Return the selected text of the entry.
#	Raises an error if there is no selection.
#
234
235
236
237
238
239
240
241
242
243
244
245
246

247

248
249
250
251
252
253
254
















255
256
257
258
259
260
261
262
263




264





















265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
    set c [$w index $index]
    # @@@ OR: check [$w index left] / [$w index right]
    if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} {
	$w xview $c
    }
}

## NextWord -- Find the next word position.
#	Note: The "next word position" follows platform conventions:
#	either the next end-of-word position, or the start-of-word
#	position following the next end-of-word position.
#
set ::ttk::entry::State(startNext) \

	[string equal [tk windowingsystem] "win32"]


proc ttk::entry::NextWord {w start} {
    variable State
    set pos [tcl_endOfWord [$w get] [$w index $start]]
    if {$pos >= 0 && $State(startNext)} {
	set pos [tcl_startOfNextWord [$w get] $pos]
    }
















    if {$pos < 0} {
	return end
    }
    return $pos
}

## PrevWord -- Find the previous word position.
#
proc ttk::entry::PrevWord {w start} {




    set pos [tcl_startOfPreviousWord [$w get] [$w index $start]]





















    if {$pos < 0} {
	return 0
    }
    return $pos
}

## RelIndex -- Compute character/word/line-relative index.
#
proc ttk::entry::RelIndex {w where {index insert}} {
    switch -- $where {
	prevchar	{ expr {[$w index $index] - 1} }
    	nextchar	{ expr {[$w index $index] + 1} }
	prevword	{ PrevWord $w $index }
	nextword	{ NextWord $w $index }

	home		{ return 0 }
	end		{ $w index end }
	default		{ error "Bad relative index $index" }
    }
}

## Move -- Move insert cursor to relative location.







|
<
|
|

|
>
|
>
|
<
<
|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
|


>







244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    set c [$w index $index]
    # @@@ OR: check [$w index left] / [$w index right]
    if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} {
	$w xview $c
    }
}

## NextWord --

# Returns the index of the next start-of-word position after the next
# end-of-word position after a given position in the text.
#
proc ttk::entry::NextWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return end
    }


    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos >= 0} {
	set pos [tk::startOfNextWord [$w get] $pos]
    }
    if {$pos < 0} {
	return end
    }
    return $pos
}

## SelectNextWord --
# Returns the index of the next end-of-word position after a given
# position in the text.
#
proc ttk::entry::SelectNextWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return end
    }
    set pos [tk::endOfWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return end
    }
    return $pos
}

## PrevWord -- Find the previous word position.
#
proc ttk::entry::PrevWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return 0
    }
    set pos [tk::startOfPreviousWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return 0
    }
    return $pos
}

## NextChar -- Find the next char position.
#
proc ttk::entry::NextChar {w start} {
    variable State
    set pos [tk::endOfCluster [$w get] [$w index $start]]
    if {$pos < 0} {
	return end
    }
    return $pos
}

## PrevChar -- Find the previous char position.
#
proc ttk::entry::PrevChar {w start} {
    set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}]]
    if {$pos < 0} {
	return 0
    }
    return $pos
}

## RelIndex -- Compute character/word/line-relative index.
#
proc ttk::entry::RelIndex {w where {index insert}} {
    switch -- $where {
	prevchar	{ PrevChar $w $index }
    	nextchar	{ NextChar $w $index }
	prevword	{ PrevWord $w $index }
	nextword	{ NextWord $w $index }
	selectnextword	{ SelectNextWord $w $index }
	home		{ return 0 }
	end		{ $w index end }
	default		{ error "Bad relative index $index" }
    }
}

## Move -- Move insert cursor to relative location.
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#
proc ttk::entry::ExtendTo {w index} {
    set index [$w index $index]
    set insert [$w index insert]

    # Figure out selection anchor:
    if {![$w selection present]} {
    	set anchor $insert
    } else {
    	set selfirst [$w index sel.first]
	set sellast  [$w index sel.last]

	if {   ($index < $selfirst)
	    || ($insert == $selfirst && $index <= $sellast)
	} {
	    set anchor $sellast
	} else {
	    set anchor $selfirst
	}
    }

    # Extend selection:
    if {$anchor < $index} {
	$w selection range $anchor $index
    } else {
    	$w selection range $index $anchor
    }

    $w icursor $index
    return $anchor
}

## Extend -- Extend the selection to a relative position, show insert cursor







|

|















|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
#
proc ttk::entry::ExtendTo {w index} {
    set index [$w index $index]
    set insert [$w index insert]

    # Figure out selection anchor:
    if {![$w selection present]} {
	set anchor $insert
    } else {
	set selfirst [$w index sel.first]
	set sellast  [$w index sel.last]

	if {   ($index < $selfirst)
	    || ($insert == $selfirst && $index <= $sellast)
	} {
	    set anchor $sellast
	} else {
	    set anchor $selfirst
	}
    }

    # Extend selection:
    if {$anchor < $index} {
	$w selection range $anchor $index
    } else {
	$w selection range $index $anchor
    }

    $w icursor $index
    return $anchor
}

## Extend -- Extend the selection to a relative position, show insert cursor
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
#	and sets the selection mode for subsequent drag operations.
#
proc ttk::entry::Select {w x mode} {
    variable State
    set cur [ClosestGap $w $x]

    switch -- $mode {
    	word	{ WordSelect $w $cur $cur }
    	line	{ LineSelect $w $cur $cur }
	char	{ # no-op }
    }

    set State(anchor) $cur
    set State(selectMode) $mode
}








|
|







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
#	and sets the selection mode for subsequent drag operations.
#
proc ttk::entry::Select {w x mode} {
    variable State
    set cur [ClosestGap $w $x]

    switch -- $mode {
	word	{ WordSelect $w $cur $cur }
	line	{ LineSelect $w $cur $cur }
	char	{ # no-op }
    }

    set State(anchor) $cur
    set State(selectMode) $mode
}

494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
	$w icursor $last
    }
    $w selection range $first $last
}

## WordBack, WordForward -- helper routines for WordSelect.
#
proc ttk::entry::WordBack {text index} {
    if {[set pos [tcl_wordBreakBefore $text $index]] < 0} { return 0 }
    return $pos
}
proc ttk::entry::WordForward {text index} {
    if {[set pos [tcl_wordBreakAfter $text $index]] < 0} { return end }
    return $pos
}

## LineSelect -- Select the entire line.
#
proc ttk::entry::LineSelect {w _ _} {
    variable State







|
|


|
|







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
	$w icursor $last
    }
    $w selection range $first $last
}

## WordBack, WordForward -- helper routines for WordSelect.
#
proc ttk::entry::WordBack {text index {locale {}}} {
    if {[set pos [tk::wordBreakBefore $text $index $locale]] < 0} { return 0 }
    return $pos
}
proc ttk::entry::WordForward {text index {locale {}}} {
    if {[set pos [tk::wordBreakAfter $text $index $locale]] < 0} { return end }
    return $pos
}

## LineSelect -- Select the entire line.
#
proc ttk::entry::LineSelect {w _ _} {
    variable State
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
    if {abs($dx) > $State(deadband)} {
	set State(scanMoved) 1
    }
    set left [expr {$State(scanIndex) + ($dx*$State(scanNum))/$State(scanDen)}]
    $w xview $left

    if {$left != [set newLeft [$w index @0]]} {
    	# We've scanned past one end of the entry;
	# reset the mark so that the text will start dragging again
	# as soon as the mouse reverses direction.
	#
	set State(scanX) $x
	set State(scanIndex) $newLeft
    }
}







|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    if {abs($dx) > $State(deadband)} {
	set State(scanMoved) 1
    }
    set left [expr {$State(scanIndex) + ($dx*$State(scanNum))/$State(scanDen)}]
    $w xview $left

    if {$left != [set newLeft [$w index @0]]} {
	# We've scanned past one end of the entry;
	# reset the mark so that the text will start dragging again
	# as soon as the mouse reverses direction.
	#
	set State(scanX) $x
	set State(scanIndex) $newLeft
    }
}
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625
626
## Backspace -- Backspace over the character just before the insert cursor.
#	If there is a selection, delete that instead.
#	If the new insert position is offscreen to the left,
#	scroll to place the cursor at about the middle of the window.
#
proc ttk::entry::Backspace {w} {
    if {[PendingDelete $w]} {
    	See $w
	return
    }
    set x [expr {[$w index insert] - 1}]
    if {$x < 0} { return }

    $w delete $x

    if {[$w index @0] >= [$w index insert]} {
	set range [$w xview]
	set left [lindex $range 0]
	set right [lindex $range 1]
	$w xview moveto [expr {$left - ($right - $left)/2.0}]
    }
}

## Delete -- Delete the character after the insert cursor.
#	If there is a selection, delete that instead.
#
proc ttk::entry::Delete {w} {
    if {![PendingDelete $w]} {
	$w delete insert

    }
}

#*EOF*







|





|














|
>




645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
## Backspace -- Backspace over the character just before the insert cursor.
#	If there is a selection, delete that instead.
#	If the new insert position is offscreen to the left,
#	scroll to place the cursor at about the middle of the window.
#
proc ttk::entry::Backspace {w} {
    if {[PendingDelete $w]} {
	See $w
	return
    }
    set x [expr {[$w index insert] - 1}]
    if {$x < 0} { return }

    $w delete [tk::startOfCluster [$w get] $x] [tk::endOfCluster [$w get] $x]

    if {[$w index @0] >= [$w index insert]} {
	set range [$w xview]
	set left [lindex $range 0]
	set right [lindex $range 1]
	$w xview moveto [expr {$left - ($right - $left)/2.0}]
    }
}

## Delete -- Delete the character after the insert cursor.
#	If there is a selection, delete that instead.
#
proc ttk::entry::Delete {w} {
    if {![PendingDelete $w]} {
	$w delete [tk::startOfCluster [$w get] [$w index insert]] \
		[tk::endOfCluster [$w get] [$w index insert]]
    }
}

#*EOF*

Changes to library/ttk/fonts.tcl.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133





134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#
#	Note that the font for column headings (TkHeadingFont) is
#	_smaller_ than the default font.
#
#	There does not appear to be any recommendations for fixed-width fonts.
#
# X11:
#	Need a way to tell if Xft is enabled or not.
#	For now, assume patch #971980 applied.
#
#	"Classic" look used Helvetica bold for everything except
#	for entry widgets, which use Helvetica medium.
#	Most other toolkits use medium weight for all UI elements,
#	which is what we do now.
#

namespace eval ttk {

variable tip145 [catch {font create TkDefaultFont}]
catch {font create TkTextFont}
catch {font create TkHeadingFont}
catch {font create TkCaptionFont}
catch {font create TkTooltipFont}
catch {font create TkFixedFont}
catch {font create TkIconFont}
catch {font create TkMenuFont}
catch {font create TkSmallCaptionFont}

if {!$tip145} {
variable F	;# miscellaneous platform-specific font parameters
switch -- [tk windowingsystem] {
    win32 {
        # In safe interps there is no osVersion element.
	if {[info exists tcl_platform(osVersion)]} {
            if {$tcl_platform(osVersion) >= 5.0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        } else {
            if {[lsearch -exact [font families] Tahoma] >= 0} {
                set F(family) "Tahoma"
            } else {
                set F(family) "MS Sans Serif"
            }
        }
	set F(size) 8

	font configure TkDefaultFont -family $F(family) -size $F(size)
	font configure TkTextFont    -family $F(family) -size $F(size)
	font configure TkHeadingFont -family $F(family) -size $F(size)
	font configure TkCaptionFont -family $F(family) -size $F(size) \
	    -weight bold
	font configure TkTooltipFont -family $F(family) -size $F(size)
	font configure TkFixedFont   -family Courier -size 10
	font configure TkIconFont    -family $F(family) -size $F(size)
	font configure TkMenuFont    -family $F(family) -size $F(size)
	font configure TkSmallCaptionFont -family $F(family) -size $F(size)
    }
    aqua {
	set F(family) "Lucida Grande"
	set F(fixed) "Monaco"
	set F(menusize) 14
	set F(size) 13
	set F(viewsize) 12
	set F(smallsize) 11
	set F(labelsize) 10
	set F(fixedsize) 11

	font configure TkDefaultFont -family $F(family) -size $F(size)
	font configure TkTextFont    -family $F(family) -size $F(size)
	font configure TkHeadingFont -family $F(family) -size $F(smallsize)
	font configure TkCaptionFont -family $F(family) -size $F(size) \
					-weight bold
	font configure TkTooltipFont -family $F(family) -size $F(smallsize)
	font configure TkFixedFont   -family $F(fixed)  -size $F(fixedsize)
	font configure TkIconFont    -family $F(family) -size $F(size)
	font configure TkMenuFont    -family $F(family) -size $F(menusize)
	font configure TkSmallCaptionFont -family $F(family) -size $F(labelsize)
    }
    default -
    x11 {
	if {![catch {tk::pkgconfig get fontsystem} F(fs)] && $F(fs) eq "xft"} {
	    set F(family) "sans-serif"
	    set F(fixed)  "monospace"
	} else {
	    set F(family) "Helvetica"
	    set F(fixed)  "courier"
	}

	set F(size) 10
	set F(ttsize) 9
	set F(capsize) 12
	set F(fixedsize) 10







	font configure TkDefaultFont -family $F(family) -size $F(size)
	font configure TkTextFont    -family $F(family) -size $F(size)
	font configure TkHeadingFont -family $F(family) -size $F(size) \
			-weight bold
	font configure TkCaptionFont -family $F(family) -size $F(capsize) \
			-weight bold
	font configure TkTooltipFont -family $F(family) -size $F(ttsize)
	font configure TkFixedFont   -family $F(fixed)  -size $F(fixedsize)
	font configure TkIconFont    -family $F(family) -size $F(size)
	font configure TkMenuFont    -family $F(family) -size $F(size)
	font configure TkSmallCaptionFont -family $F(family) -size $F(ttsize)
    }
}
unset -nocomplain F
}

}

#*EOF*







<
<
<


















|
|





|

|



|

|


|

|
|
|
|
<
|

|
|
|


|
|
|
|
|
|
|
|

|
|
|
|
<
|
|
|
|
|



|
|
|

|
|

>
|
|
|
|
>
>
>
>
>
|
>
|
|
|
<
|
<
|
|
|
|
|


<
|




41
42
43
44
45
46
47



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140

141
142
143
144
145
146
147

148
149
150
151
152
#
#	Note that the font for column headings (TkHeadingFont) is
#	_smaller_ than the default font.
#
#	There does not appear to be any recommendations for fixed-width fonts.
#
# X11:



#	"Classic" look used Helvetica bold for everything except
#	for entry widgets, which use Helvetica medium.
#	Most other toolkits use medium weight for all UI elements,
#	which is what we do now.
#

namespace eval ttk {

variable tip145 [catch {font create TkDefaultFont}]
catch {font create TkTextFont}
catch {font create TkHeadingFont}
catch {font create TkCaptionFont}
catch {font create TkTooltipFont}
catch {font create TkFixedFont}
catch {font create TkIconFont}
catch {font create TkMenuFont}
catch {font create TkSmallCaptionFont}

if {!$tip145} {apply {{} {
global tcl_platform
switch -- [tk windowingsystem] {
    win32 {
        # In safe interps there is no osVersion element.
	if {[info exists tcl_platform(osVersion)]} {
            if {$tcl_platform(osVersion) >= 5.0} {
                set family "Tahoma"
            } else {
                set family "MS Sans Serif"
            }
        } else {
            if {[lsearch -exact [font families] Tahoma] >= 0} {
                set family "Tahoma"
            } else {
                set family "MS Sans Serif"
            }
        }
	set size 8

	font configure TkDefaultFont -family $family -size $size
	font configure TkTextFont    -family $family -size $size
	font configure TkHeadingFont -family $family -size $size
	font configure TkCaptionFont -family $family -size $size -weight bold

	font configure TkTooltipFont -family $family -size $size
	font configure TkFixedFont   -family Courier -size 10
	font configure TkIconFont    -family $family -size $size
	font configure TkMenuFont    -family $family -size $size
	font configure TkSmallCaptionFont -family $family -size $size
    }
    aqua {
	set family "Lucida Grande"
	set fixed "Monaco"
	set menusize 14
	set size 13
	set viewsize 12
	set smallsize 11
	set labelsize 10
	set fixedsize 11

	font configure TkDefaultFont -family $family -size $size
	font configure TkTextFont    -family $family -size $size
	font configure TkHeadingFont -family $family -size $smallsize
	font configure TkCaptionFont -family $family -size $size -weight bold

	font configure TkTooltipFont -family $family -size $smallsize
	font configure TkFixedFont   -family $fixed  -size $fixedsize
	font configure TkIconFont    -family $family -size $size
	font configure TkMenuFont    -family $family -size $menusize
	font configure TkSmallCaptionFont -family $family -size $labelsize
    }
    default -
    x11 {
	if {![catch {tk::pkgconfig get fontsystem} fs] && $fs eq "xft"} {
	    set family "sans-serif"
	    set fixed  "monospace"
	} else {
	    set family "Helvetica"
	    set fixed  "courier"
	}
	if {[::tk::FontScalingFactor] == 1} {
	    set size 10
	    set ttsize 9
	    set capsize 12
	    set fixedsize 10
	} else {
	    set size 20
	    set ttsize 18
	    set capsize 24
	    set fixedsize 20
	}

	font configure TkDefaultFont -family $family -size $size
	font configure TkTextFont    -family $family -size $size
	font configure TkHeadingFont -family $family -size $size    -weight bold

	font configure TkCaptionFont -family $family -size $capsize -weight bold

	font configure TkTooltipFont -family $family -size $ttsize
	font configure TkFixedFont   -family $fixed  -size $fixedsize
	font configure TkIconFont    -family $family -size $size
	font configure TkMenuFont    -family $family -size $size
	font configure TkSmallCaptionFont -family $family -size $ttsize
    }
}

} ::ttk}}

}

#*EOF*

Changes to library/ttk/menubutton.tcl.

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    bind TMenubutton <Button-1>  	{ ttk::menubutton::Pulldown %W }
    bind TMenubutton <ButtonRelease-1>	{ ttk::menubutton::TransferGrab %W }
    bind TMenubutton <B1-Leave> 	{ ttk::menubutton::TransferGrab %W }
} else {
    bind TMenubutton <Button-1>  \
	{ %W state pressed ; ttk::menubutton::Popdown %W }
    bind TMenubutton <ButtonRelease-1>  \
	{ if {[winfo exists %W]} { %W state !pressed } }
}

# PostPosition --
#	Returns x and y coordinates and a menu item index.
#       If the index is not an empty string the menu should
#       be posted so that the upper left corner of the indexed
#       menu item is located at the point (x, y).  Otherwise
#       the top left corner of the menu itself should be located
#       at that point.
#
# TODO: adjust menu width to be at least as wide as the button
#	for -direction above, below.
#

if {[tk windowingsystem] eq "aqua"} {
    proc ::ttk::menubutton::PostPosition {mb menu} {
	set menuPad 5
	set buttonPad 1
	set bevelPad 4

	set mh [winfo reqheight $menu]
	set bh [expr {[winfo height $mb]} + $buttonPad]
	set bbh [expr {[winfo height $mb]} + $bevelPad]
	set mw [winfo reqwidth $menu]
	set bw [winfo width $mb]
	set dF [expr {[winfo width $mb] - [winfo reqwidth $menu] - $menuPad}]
	set entry ""
	set entry [::tk::MenuFindName $menu [$mb cget -text]]
	if {$entry eq ""} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry ""







|



















>





<
<

|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85


86
87
88
89
90
91
92
93
94
    bind TMenubutton <Button-1>  	{ ttk::menubutton::Pulldown %W }
    bind TMenubutton <ButtonRelease-1>	{ ttk::menubutton::TransferGrab %W }
    bind TMenubutton <B1-Leave> 	{ ttk::menubutton::TransferGrab %W }
} else {
    bind TMenubutton <Button-1>  \
	{ %W state pressed ; ttk::menubutton::Popdown %W }
    bind TMenubutton <ButtonRelease-1>  \
	{ if {[winfo exists %W]} { %W state {!pressed}} }
}

# PostPosition --
#	Returns x and y coordinates and a menu item index.
#       If the index is not an empty string the menu should
#       be posted so that the upper left corner of the indexed
#       menu item is located at the point (x, y).  Otherwise
#       the top left corner of the menu itself should be located
#       at that point.
#
# TODO: adjust menu width to be at least as wide as the button
#	for -direction above, below.
#

if {[tk windowingsystem] eq "aqua"} {
    proc ::ttk::menubutton::PostPosition {mb menu} {
	set menuPad 5
	set buttonPad 1
	set bevelPad 4
	set flushPad 4
	set mh [winfo reqheight $menu]
	set bh [expr {[winfo height $mb]} + $buttonPad]
	set bbh [expr {[winfo height $mb]} + $bevelPad]
	set mw [winfo reqwidth $menu]
	set bw [winfo width $mb]


	set entry [::tk::MenuFindName $menu [$mb cget -text]]
	if {$entry < 0} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry ""
103
104
105
106
107
108
109




110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
		incr y $menuPad
		incr x -$mw
	    }
	    right {
		incr y $menuPad
		incr x $bw
	    }




	    default {
		incr y $bbh
	    }
	}
	return [list $x $y $entry]
    }
} else {
    proc ::ttk::menubutton::PostPosition {mb menu} {
	set mh [expr {[winfo reqheight $menu]}]
	set bh [expr {[winfo height $mb]}]
	set mw [expr {[winfo reqwidth $menu]}]
	set bw [expr {[winfo width $mb]}]
	set dF [expr {[winfo width $mb] - [winfo reqwidth $menu]}]
	if {[tk windowingsystem] eq "win32"} {
	    incr mh 6
	    incr mw 16
	}
	set entry {}
	set entry [::tk::MenuFindName $menu [$mb cget -text]]
	if {$entry eq {}} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry {}
		incr y -$mh
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $mb]} {
		    set y [expr {[winfo vrooty $mb] + [winfo rooty $mb]\
                           + [winfo reqheight $mb]}]
		}
	    }
	    below {
		set entry {}
		incr y $bh
		# if we go offscreen to the bottom, show as 'above'
		if {($y + $mh) > ([winfo vrooty $mb] + [winfo vrootheight $mb])} {
		    set y [expr {[winfo vrooty $mb] + [winfo vrootheight $mb] \
			   + [winfo rooty $mb] - $mh}]
		}
	    }
	    left {
		incr x -$mw
	    }
	    right {
		incr x $bw
	    }
	    default {
		if {[$mb cget -style] eq ""} {
		    incr x [expr {([winfo width $mb] - \
				   [winfo reqwidth $menu])/ 2}]
		} else {
		    incr y $bh
		}
	    }
	}
	return [list $x $y $entry]
    }
}

# Popdown --







>
>
>
>

<










<




<

|






|








|



|
<








|
<
|
<
<
<
<







102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123

124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158

159




160
161
162
163
164
165
166
		incr y $menuPad
		incr x -$mw
	    }
	    right {
		incr y $menuPad
		incr x $bw
	    }
	    flush {
		incr y $flushPad
		incr x -$flushPad
	    }
	    default {

	    }
	}
	return [list $x $y $entry]
    }
} else {
    proc ::ttk::menubutton::PostPosition {mb menu} {
	set mh [expr {[winfo reqheight $menu]}]
	set bh [expr {[winfo height $mb]}]
	set mw [expr {[winfo reqwidth $menu]}]
	set bw [expr {[winfo width $mb]}]

	if {[tk windowingsystem] eq "win32"} {
	    incr mh 6
	    incr mw 16
	}

	set entry [::tk::MenuFindName $menu [$mb cget -text]]
	if {$entry < 0} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry ""
		incr y -$mh
		# if we go offscreen to the top, show as 'below'
		if {$y < [winfo vrooty $mb]} {
		    set y [expr {[winfo vrooty $mb] + [winfo rooty $mb]\
                           + [winfo reqheight $mb]}]
		}
	    }
	    below {
		set entry ""
		incr y $bh
		# if we go offscreen to the bottom, show as 'above'
		if {($y + $mh) > ([winfo vrooty $mb] + [winfo vrootheight $mb])} {
		    set y [expr {[winfo vrooty $mb] + [winfo rooty $mb] - $mh}]

		}
	    }
	    left {
		incr x -$mw
	    }
	    right {
		incr x $bw
	    }
	    default {  # flush

		incr x [expr {([winfo width $mb] - [winfo reqwidth $menu])/ 2}]




	    }
	}
	return [list $x $y $entry]
    }
}

# Popdown --
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    }
    set State(pulldown) 1
    set State(oldcursor) [$mb cget -cursor]

    $mb state pressed
    $mb configure -cursor [$menu cget -cursor]
    foreach {x y entry} [PostPosition $mb $menu] { break }
    if {$entry ne {}} {
	$menu post $x $y $entry
    } else {
	$menu post $x $y
    }
    tk_menuSetFocus $menu
}

# TransferGrab (X11 only) --
#	Switch from pulldown mode (menubutton has an implicit grab)
#	to popdown mode (menu has an explicit grab).
#
proc ttk::menubutton::TransferGrab {mb} {
    variable State
    if {$State(pulldown)} {
	$mb configure -cursor $State(oldcursor)
	$mb state {!pressed !active}
	set State(pulldown) 0

	set menu [$mb cget -menu]
	foreach {x y entry} [PostPosition $mb $menu] { break }
    	tk_popup $menu [winfo rootx $menu] [winfo rooty $menu]
    }
}

# FindMenuEntry --
#	Hack to support tk_optionMenus.
#	Returns the index of the menu entry with a matching -label,
#	"" if not found.
#
proc ttk::menubutton::FindMenuEntry {menu s} {
    set last [$menu index last]
    if {$last eq "none" || $last eq ""} {
	return ""
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]
	    && ($label eq $s)} {
	    return $i
	}
    }
    return ""
}

#*EOF*







|




















|










|












186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    }
    set State(pulldown) 1
    set State(oldcursor) [$mb cget -cursor]

    $mb state pressed
    $mb configure -cursor [$menu cget -cursor]
    foreach {x y entry} [PostPosition $mb $menu] { break }
    if {$entry >= 0} {
	$menu post $x $y $entry
    } else {
	$menu post $x $y
    }
    tk_menuSetFocus $menu
}

# TransferGrab (X11 only) --
#	Switch from pulldown mode (menubutton has an implicit grab)
#	to popdown mode (menu has an explicit grab).
#
proc ttk::menubutton::TransferGrab {mb} {
    variable State
    if {$State(pulldown)} {
	$mb configure -cursor $State(oldcursor)
	$mb state {!pressed !active}
	set State(pulldown) 0

	set menu [$mb cget -menu]
	foreach {x y entry} [PostPosition $mb $menu] { break }
	tk_popup $menu [winfo rootx $menu] [winfo rooty $menu]
    }
}

# FindMenuEntry --
#	Hack to support tk_optionMenus.
#	Returns the index of the menu entry with a matching -label,
#	"" if not found.
#
proc ttk::menubutton::FindMenuEntry {menu s} {
    set last [$menu index last]
    if {$last < 0} {
	return ""
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]
	    && ($label eq $s)} {
	    return $i
	}
    }
    return ""
}

#*EOF*

Changes to library/ttk/notebook.tcl.

11
12
13
14
15
16
17






















18
19
20
21
22
23
24
bind TNotebook <Left>			{ ttk::notebook::CycleTab %W -1; break }
bind TNotebook <Control-Tab>		{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Control-Shift-Tab>	{ ttk::notebook::CycleTab %W -1; break }
catch {
bind TNotebook <Control-ISO_Left_Tab>	{ ttk::notebook::CycleTab %W -1; break }
}
bind TNotebook <Destroy>		{ ttk::notebook::Cleanup %W }























# ActivateTab $nb $tab --
#	Select the specified tab and set focus.
#
#  Desired behavior:
#	+ take focus when reselecting the currently-selected tab;
#	+ keep focus if the notebook already has it;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
bind TNotebook <Left>			{ ttk::notebook::CycleTab %W -1; break }
bind TNotebook <Control-Tab>		{ ttk::notebook::CycleTab %W  1; break }
bind TNotebook <Control-Shift-Tab>	{ ttk::notebook::CycleTab %W -1; break }
catch {
bind TNotebook <Control-ISO_Left_Tab>	{ ttk::notebook::CycleTab %W -1; break }
}
bind TNotebook <Destroy>		{ ttk::notebook::Cleanup %W }

bind TNotebook <Enter> {
    set tk::Priv(xEvents) 0; set tk::Priv(yEvents) 0
}
bind TNotebook <MouseWheel> {
    ttk::notebook::CondCycleTab1 %W y %D -120.0
}
bind TNotebook <Option-MouseWheel> {
    ttk::notebook::CondCycleTab1 %W y %D -12.0
}
bind TNotebook <Shift-MouseWheel> {
    ttk::notebook::CondCycleTab1 %W x %D -120.0
}
bind TNotebook <Shift-Option-MouseWheel> {
    ttk::notebook::CondCycleTab1 %W x %D -12.0
}
bind TNotebook <TouchpadScroll> {
    # TouchpadScroll events fire about 60 times per second.
    if {%# %% 15 == 0} {
	ttk::notebook::CondCycleTab2 %W %D
    }
}

# 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;
52
53
54
55
56
57
58
59
60
61




62

63
64
65
66
67
68
69
70



































71
72
73
74
75
76
77
78
79
80
81

82
83
84

85
86
87
88
89
90
91
	ActivateTab $w $index
    }
}

# CycleTab --
#	Select the next/previous tab in the list.
#
proc ttk::notebook::CycleTab {w dir} {
    if {[$w index end] != 0} {
	set current [$w index current]




	set select [expr {($current + $dir) % [$w index end]}]

	while {[$w tab $select -state] != "normal" && ($select != $current)} {
	    set select [expr {($select + $dir) % [$w index end]}]
	}
	if {$select != $current} {
	    ActivateTab $w $select
	}
    }
}




































# MnemonicTab $nb $key --
#	Scan all tabs in the specified notebook for one with the
#	specified mnemonic. If found, returns path name of tab;
#	otherwise returns ""
#
proc ttk::notebook::MnemonicTab {nb key} {
    set key [string toupper $key]
    foreach tab [$nb tabs] {
	set label [$nb tab $tab -text]
	set underline [$nb tab $tab -underline]

	set mnemonic [string toupper [string index $label $underline]]
	if {$mnemonic ne "" && $mnemonic eq $key} {
	    return $tab

	}
    }
    return ""
}

# +++ Toplevel keyboard traversal.
#







|
<
|
>
>
>
>
|
>
|
|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











>
|
|
|
>







74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
	ActivateTab $w $index
    }
}

# CycleTab --
#	Select the next/previous tab in the list.
#
proc ttk::notebook::CycleTab {w dir {factor 1.0}} {

    set current [$w index current]
    if {$current >= 0} {
	set tabCount [$w index end]
	set d [expr {$dir/$factor}]
	set d [expr {int($d > 0 ? ceil($d) : floor($d))}]
	set select [expr {($current + $d) % $tabCount}]
	set step [expr {$d > 0 ? 1 : -1}]
	while {[$w tab $select -state] ne "normal" && ($select != $current)} {
	    set select [expr {($select + $step) % $tabCount}]
	}
	if {$select != $current} {
	    ActivateTab $w $select
	}
    }
}

# CondCycleTab1 --
#	Conditionally invoke the ttk::notebook::CycleTab proc.
#
proc ttk::notebook::CondCycleTab1 {w axis dir {factor 1.0}} {
    # Count both the <MouseWheel> and <Shift-MouseWheel>
    # events, and ignore the non-dominant ones

    variable ::tk::Priv
    incr Priv(${axis}Events)
    if {($Priv(xEvents) + $Priv(yEvents) > 10) &&
	    ($axis eq "x" && $Priv(xEvents) < $Priv(yEvents) ||
	     $axis eq "y" && $Priv(yEvents) < $Priv(xEvents))} {
	return
    }

    CycleTab $w $dir $factor
}

# CondCycleTab2 --
#	Conditionally invoke the ttk::notebook::CycleTab proc.
#
proc ttk::notebook::CondCycleTab2 {w dxdy} {
    if {[set style [$w cget -style]] eq ""} {
	set style TNotebook
    }
    set tabSide [string index [ttk::style lookup $style -tabposition {} nw] 0]

    lassign [tk::PreciseScrollDeltas $dxdy] deltaX deltaY
    if {$tabSide in {n s} && $deltaX != 0} {
	CycleTab $w [expr {$deltaX < 0 ? -1 : 1}]
    } elseif {$tabSide in {w e} && $deltaY != 0} {
	CycleTab $w [expr {$deltaY < 0 ? -1 : 1}]
    }
}

# MnemonicTab $nb $key --
#	Scan all tabs in the specified notebook for one with the
#	specified mnemonic. If found, returns path name of tab;
#	otherwise returns ""
#
proc ttk::notebook::MnemonicTab {nb key} {
    set key [string toupper $key]
    foreach tab [$nb tabs] {
	set label [$nb tab $tab -text]
	set underline [$nb tab $tab -underline]
	if {$underline >= 0} {
	    set mnemonic [string toupper [string index $label $underline]]
	    if {$mnemonic ne "" && $mnemonic eq $key} {
		return $tab
	    }
	}
    }
    return ""
}

# +++ Toplevel keyboard traversal.
#
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
	bind $top <Control-Next>             {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Prior>            {+ttk::notebook::TLCycleTab %W -1}
	bind $top <Control-Tab> 	     {+ttk::notebook::TLCycleTab %W  1}
	bind $top <Control-Shift-Tab>        {+ttk::notebook::TLCycleTab %W -1}
	catch {
	bind $top <Control-ISO_Left_Tab>     {+ttk::notebook::TLCycleTab %W -1}
	}
	if {[tk windowingsystem] eq "aqua"} {
	    bind $top <Option-Key> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	} else {
	    bind $top <Alt-Key> \
		+[list ttk::notebook::MnemonicActivation $top %K]
	}
	bind $top <Destroy> {+ttk::notebook::TLCleanup %W}
    }

    lappend TLNotebooks($top) $nb
}

# TLCleanup -- <Destroy> binding for traversal-enabled toplevels







<
|
|
<
<
<
<







171
172
173
174
175
176
177

178
179




180
181
182
183
184
185
186
	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}
	}

	bind $top <Option-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/panedwindow.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
#
# Bindings for ttk::panedwindow widget.
#

namespace eval ttk::panedwindow {
    variable State
    array set State {
	pressed 0
    	pressX	-
	pressY	-
	sash 	-
	sashPos -
    }
}

## Bindings:
#
bind TPanedwindow <Button-1> 		{ ttk::panedwindow::Press %W %x %y }
bind TPanedwindow <B1-Motion>		{ ttk::panedwindow::Drag %W %x %y }
bind TPanedwindow <ButtonRelease-1> 	{ ttk::panedwindow::Release %W %x %y }

bind TPanedwindow <Motion> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Enter> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Leave> 		{ ttk::panedwindow::ResetCursor %W }
# See <<NOTE-PW-LEAVE-NOTIFYINFERIOR>>
bind TPanedwindow <<EnteredChild>>	{ ttk::panedwindow::ResetCursor %W }

## Sash movement:
#
proc ttk::panedwindow::Press {w x y} {
    variable State

    set sash [$w identify $x $y]
    if {$sash eq ""} {
    	set State(pressed) 0
	return
    }
    set State(pressed) 	1
    set State(pressX) 	$x
    set State(pressY) 	$y
    set State(sash) 	$sash
    set State(sashPos)	[$w sashpos $sash]
}

proc ttk::panedwindow::Drag {w x y} {
    variable State
    if {!$State(pressed)} { return }
    switch -- [$w cget -orient] {
    	horizontal 	{ set delta [expr {$x - $State(pressX)}] }
    	vertical 	{ set delta [expr {$y - $State(pressY)}] }
    }
    $w sashpos $State(sash) [expr {$State(sashPos) + $delta}]
}

proc ttk::panedwindow::Release {w x y} {
    variable State
    set State(pressed) 0








|















<
<








|












|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#
# Bindings for ttk::panedwindow widget.
#

namespace eval ttk::panedwindow {
    variable State
    array set State {
	pressed 0
	pressX	-
	pressY	-
	sash 	-
	sashPos -
    }
}

## Bindings:
#
bind TPanedwindow <Button-1> 		{ ttk::panedwindow::Press %W %x %y }
bind TPanedwindow <B1-Motion>		{ ttk::panedwindow::Drag %W %x %y }
bind TPanedwindow <ButtonRelease-1> 	{ ttk::panedwindow::Release %W %x %y }

bind TPanedwindow <Motion> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Enter> 		{ ttk::panedwindow::SetCursor %W %x %y }
bind TPanedwindow <Leave> 		{ ttk::panedwindow::ResetCursor %W }



## Sash movement:
#
proc ttk::panedwindow::Press {w x y} {
    variable State

    set sash [$w identify $x $y]
    if {$sash eq ""} {
	set State(pressed) 0
	return
    }
    set State(pressed) 	1
    set State(pressX) 	$x
    set State(pressY) 	$y
    set State(sash) 	$sash
    set State(sashPos)	[$w sashpos $sash]
}

proc ttk::panedwindow::Drag {w x y} {
    variable State
    if {!$State(pressed)} { return }
    switch -glob -- [$w cget -orient] {
    	h*  { set delta [expr {$x - $State(pressX)}] }
    	v*  { set delta [expr {$y - $State(pressY)}] }
    }
    $w sashpos $State(sash) [expr {$State(sashPos) + $delta}]
}

proc ttk::panedwindow::Release {w x y} {
    variable State
    set State(pressed) 0
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    variable State

    ttk::saveCursor $w State(userConfCursor) \
            [list [ttk::cursor hresize] [ttk::cursor vresize]]

    set cursor $State(userConfCursor)
    if {[llength [$w identify $x $y]]} {
    	# Assume we're over a sash.
	switch -- [$w cget -orient] {
	    horizontal 	{ set cursor hresize }
	    vertical 	{ set cursor vresize }
	}
    }
    ttk::setCursor $w $cursor
}

#*EOF*







|
|
|
|






73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    variable State

    ttk::saveCursor $w State(userConfCursor) \
            [list [ttk::cursor hresize] [ttk::cursor vresize]]

    set cursor $State(userConfCursor)
    if {[llength [$w identify $x $y]]} {
	# Assume we're over a sash.
	switch -glob -- [$w cget -orient] {
	    h*  { set cursor hresize }
	    v*  { set cursor vresize }
	}
    }
    ttk::setCursor $w $cursor
}

#*EOF*

Changes to library/ttk/progress.tcl.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33



34
35
36
37
38
39
40
41
42
43
44
45
46



47
48
49
# Autoincrement --
#	Periodic callback procedure for autoincrement mode
#
proc ttk::progressbar::Autoincrement {pb steptime stepsize} {
    variable Timers

    if {![winfo exists $pb]} {
    	# widget has been destroyed -- cancel timer
	unset -nocomplain Timers($pb)
	return
    }

    set Timers($pb) [after $steptime \
    	[list ttk::progressbar::Autoincrement $pb $steptime $stepsize] ]

    $pb step $stepsize
}

# ttk::progressbar::start --
#	Start autoincrement mode.  Invoked by [$pb start] widget code.
#
proc ttk::progressbar::start {pb {steptime 50} {stepsize 1}} {
    variable Timers
    if {![info exists Timers($pb)]} {
	Autoincrement $pb $steptime $stepsize



    }
}

# ttk::progressbar::stop --
#	Cancel autoincrement mode. Invoked by [$pb stop] widget code.
#
proc ttk::progressbar::stop {pb} {
    variable Timers
    if {[info exists Timers($pb)]} {
	after cancel $Timers($pb)
	unset Timers($pb)
    }
    $pb configure -value 0



}









|





|











>
>
>













>
>
>



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# Autoincrement --
#	Periodic callback procedure for autoincrement mode
#
proc ttk::progressbar::Autoincrement {pb steptime stepsize} {
    variable Timers

    if {![winfo exists $pb]} {
	# widget has been destroyed -- cancel timer
	unset -nocomplain Timers($pb)
	return
    }

    set Timers($pb) [after $steptime \
	[list ttk::progressbar::Autoincrement $pb $steptime $stepsize] ]

    $pb step $stepsize
}

# ttk::progressbar::start --
#	Start autoincrement mode.  Invoked by [$pb start] widget code.
#
proc ttk::progressbar::start {pb {steptime 50} {stepsize 1}} {
    variable Timers
    if {![info exists Timers($pb)]} {
	Autoincrement $pb $steptime $stepsize
    }
    if {[tk windowingsystem] eq "aqua"} {
	$pb state selected
    }
}

# ttk::progressbar::stop --
#	Cancel autoincrement mode. Invoked by [$pb stop] widget code.
#
proc ttk::progressbar::stop {pb} {
    variable Timers
    if {[info exists Timers($pb)]} {
	after cancel $Timers($pb)
	unset Timers($pb)
    }
    $pb configure -value 0
    if {[tk windowingsystem] eq "aqua"} {
	$pb state !selected
    }
}


Changes to library/ttk/scale.tcl.

1
2
3
4
5
6
7
8
# scale.tcl - Copyright (C) 2004 Pat Thoyts <[email protected]>
#
# Bindings for the TScale widget

namespace eval ttk::scale {
    variable State
    array set State  {
	dragging 0
|







1
2
3
4
5
6
7
8
# 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.

13
14
15
16
17
18
19
20
21
22


23





24
25
26
27
28
29
30
bind TScrollbar <B1-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-1>	{ ttk::scrollbar::Release %W %x %y }

bind TScrollbar <Button-2> 		{ ttk::scrollbar::Jump %W %x %y }
bind TScrollbar <B2-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-2>	{ ttk::scrollbar::Release %W %x %y }

# Redirect scrollwheel bindings to the scrollbar widget
#
bind TScrollbar <MouseWheel> [bind Scrollbar <MouseWheel>]


bind TScrollbar <Option-MouseWheel> [bind Scrollbar <Option-MouseWheel>]






proc ttk::scrollbar::Scroll {w n units} {
    set cmd [$w cget -command]
    if {$cmd ne ""} {
	uplevel #0 $cmd scroll $n $units
    }
}







|

|
>
>
|
>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
bind TScrollbar <B1-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-1>	{ ttk::scrollbar::Release %W %x %y }

bind TScrollbar <Button-2> 		{ ttk::scrollbar::Jump %W %x %y }
bind TScrollbar <B2-Motion>		{ ttk::scrollbar::Drag %W %x %y }
bind TScrollbar <ButtonRelease-2>	{ ttk::scrollbar::Release %W %x %y }

# Copy the mouse wheel event bindings from Scrollbar to TScrollbar
#
bind TScrollbar <Enter> {
    set tk::Priv(xEvents) 0; set tk::Priv(yEvents) 0
}
foreach event {<MouseWheel> <Option-MouseWheel>
	       <Shift-MouseWheel> <Shift-Option-MouseWheel>
	       <TouchpadScroll>} {
    bind TScrollbar $event [bind Scrollbar $event]
}
unset event

proc ttk::scrollbar::Scroll {w n units} {
    set cmd [$w cget -command]
    if {$cmd ne ""} {
	uplevel #0 $cmd scroll $n $units
    }
}
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
	}
    }
}

proc ttk::scrollbar::Drag {w x y} {
    variable State
    if {![info exists State(first)]} {
    	# Initial buttonpress was not on the thumb,
	# or something screwy has happened.  In either case, ignore:
	return;
    }
    set xDelta [expr {$x - $State(xPress)}]
    set yDelta [expr {$y - $State(yPress)}]
    Moveto $w [expr {$State(first) + [$w delta $xDelta $yDelta]}]
}







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	}
    }
}

proc ttk::scrollbar::Drag {w x y} {
    variable State
    if {![info exists State(first)]} {
	# Initial buttonpress was not on the thumb,
	# or something screwy has happened.  In either case, ignore:
	return;
    }
    set xDelta [expr {$x - $State(xPress)}]
    set yDelta [expr {$y - $State(yPress)}]
    Moveto $w [expr {$State(first) + [$w delta $xDelta $yDelta]}]
}

Changes to library/ttk/sizegrip.tcl.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

switch -- [tk windowingsystem] {
    x11 -
    win32 {
	option add *TSizegrip.cursor [ttk::cursor seresize] widgetDefault
    }
    aqua {
    	# Aqua sizegrips use default Arrow cursor.
    }
}

namespace eval ttk::sizegrip {
    variable State
    array set State {
	pressed 	0







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

switch -- [tk windowingsystem] {
    x11 -
    win32 {
	option add *TSizegrip.cursor [ttk::cursor seresize] widgetDefault
    }
    aqua {
	# Aqua sizegrips use default Arrow cursor.
    }
}

namespace eval ttk::sizegrip {
    variable State
    array set State {
	pressed 	0

Changes to library/ttk/spinbox.tcl.

19
20
21
22
23
24
25
26










27
28
29
30
31
32
33

bind TSpinbox <Up>			{ event generate %W <<Increment>> }
bind TSpinbox <Down> 			{ event generate %W <<Decrement>> }

bind TSpinbox <<Increment>>		{ ttk::spinbox::Spin %W +1 }
bind TSpinbox <<Decrement>> 		{ ttk::spinbox::Spin %W -1 }

ttk::bindMouseWheel TSpinbox 		[list ttk::spinbox::MouseWheel %W]











## Motion --
#	Sets cursor.
#
proc ttk::spinbox::Motion {w x y} {
    variable State
    ttk::saveCursor $w State(userConfCursor) [ttk::cursor text]







|
>
>
>
>
>
>
>
>
>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

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 		{ ttk::spinbox::Spin %W }
bind TSpinbox <Shift-MouseWheel> {
    # Ignore the event
}
bind TSpinbox <TouchpadScroll> {
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    # TouchpadScroll events fire about 60 times per second.
    if {$deltaY != 0 && %# %% 12 == 0} {
	ttk::spinbox::Spin %W [expr {$deltaY > 0 ? -1 : 1}]
    }
}

## Motion --
#	Sets cursor.
#
proc ttk::spinbox::Motion {w x y} {
    variable State
    ttk::saveCursor $w State(userConfCursor) [ttk::cursor text]
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

proc ttk::spinbox::Release {w} {
    ttk::CancelRepeat
}

## MouseWheel --
#	Mousewheel callback.  Turn these into <<Increment>> (-1, up)
# 	or <<Decrement> (+1, down) events.
#
proc ttk::spinbox::MouseWheel {w dir {factor 1}} {
    if {[$w instate disabled]} { return }
    if {($dir < 0) ^ ($factor < 0)} {
	event generate $w <<Increment>>
    } elseif {$dir > 0} {
	event generate $w <<Decrement>>
    }
}

## SelectAll --
#	Select widget contents.
#







|

|



|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

proc ttk::spinbox::Release {w} {
    ttk::CancelRepeat
}

## MouseWheel --
#	Mousewheel callback.  Turn these into <<Increment>> (-1, up)
# 	or <<Decrement> (+1, down) events. Not used any more.
#
proc ttk::spinbox::MouseWheel {w dir {factor 1.0}} {
    if {[$w instate disabled]} { return }
    if {($dir < 0) ^ ($factor < 0)} {
	event generate $w <<Increment>>
    } elseif {$dir != 0} {
	event generate $w <<Decrement>>
    }
}

## SelectAll --
#	Select widget contents.
#
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

## Spin --
#	Handle <<Increment>> and <<Decrement>> events.
#	If -values is specified, cycle through the list.
#	Otherwise cycle through numeric range based on
#	-from, -to, and -increment.
#
proc ttk::spinbox::Spin {w dir} {
    variable State

    if {[$w instate disabled]} { return }

    if {![info exists State($w,values.length)]} {
	set State($w,values.index) -1
	set State($w,values.last) {}
    }
    set State($w,values) [$w cget -values]
    set State($w,values.length) [llength $State($w,values)]



    if {$State($w,values.length) > 0} {
	set value [$w get]
	set current $State($w,values.index)
	if {$value ne $State($w,values.last)} {
	    set current [lsearch -exact $State($w,values) $value]
	    if {$current < 0} {set current -1}
	}
	set State($w,values.index) [Adjust $w [expr {$current + $dir}] 0 \
		[expr {$State($w,values.length) - 1}]]
	set State($w,values.last) [lindex $State($w,values) $State($w,values.index)]
	$w set $State($w,values.last)
    } else {
	if {[catch {
	    set v [expr {[scan [$w get] %f] + $dir * [$w cget -increment]}]
	}]} {
	    set v [$w cget -from]
	}
	$w set [FormatValue $w [Adjust $w $v [$w cget -from] [$w cget -to]]]
    }
    SelectAll $w
    uplevel #0 [$w cget -command]







|











>
>







|





|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

## 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 {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) [$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]
	    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] + $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]

Changes to library/ttk/treeview.tcl.

16
17
18
19
20
21
22



23
24
25
26
27
28
29
    set State(pressX)		0

    # For pressMode == "resize"
    set State(resizeColumn)	#0

    # For pressmode == "heading"
    set State(heading)  	{}



}

### Widget bindings.
#

bind Treeview	<Motion> 		{ ttk::treeview::Motion %W %x %y }
bind Treeview	<B1-Leave>		{ #nothing }







>
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    set State(pressX)		0

    # For pressMode == "resize"
    set State(resizeColumn)	#0

    # For pressmode == "heading"
    set State(heading)  	{}

    set State(cellAnchor)	{}
    set State(cellAnchorOp)	"set"
}

### Widget bindings.
#

bind Treeview	<Motion> 		{ ttk::treeview::Motion %W %x %y }
bind Treeview	<B1-Leave>		{ #nothing }
52
53
54
55
56
57
58

59
60










61
62
63
64
65
66
67
#

## Keynav -- Keyboard navigation
#
# @@@ TODO: verify/rewrite up and down code.
#
proc ttk::treeview::Keynav {w dir} {

    set focus [$w focus]
    if {$focus eq ""} { return }











    switch -- $dir {
	up {
	    if {[set up [$w prev $focus]] eq ""} {
	        set focus [$w parent $focus]
	    } else {
		while {[$w item $up -open] && [llength [$w children $up]]} {







>


>
>
>
>
>
>
>
>
>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#

## Keynav -- Keyboard navigation
#
# @@@ TODO: verify/rewrite up and down code.
#
proc ttk::treeview::Keynav {w dir} {
    variable State
    set focus [$w focus]
    if {$focus eq ""} { return }

    set cells [expr {[$w cget -selecttype] eq "cell"}]

    if {$cells} {
        lassign $State(cellAnchor) _ colAnchor
        # Just in case, give it a valid value
        if {$colAnchor eq ""} {
            set colAnchor "#1"
        }
    }

    switch -- $dir {
	up {
	    if {[set up [$w prev $focus]] eq ""} {
	        set focus [$w parent $focus]
	    } else {
		while {[$w item $up -open] && [llength [$w children $up]]} {
78
79
80
81
82
83
84








85
86
87
88
89
90
91













92

93
94
95
96


97



98
99
100
101
102
103
104
		while {$up ne "" && [set down [$w next $up]] eq ""} {
		    set up [$w parent $up]
		}
		set focus $down
	    }
	}
	left {








	    if {[$w item $focus -open] && [llength [$w children $focus]]} {
	    	CloseItem $w $focus
	    } else {
	    	set focus [$w parent $focus]
	    }
	}
	right {













	    OpenItem $w $focus

	}
    }

    if {$focus != {}} {


	SelectOp $w $focus choose



    }
}

## Motion -- pointer motion binding.
#	Sets cursor, active element ...
#
proc ttk::treeview::Motion {w x y} {







>
>
>
>
>
>
>
>
|
|

|



>
>
>
>
>
>
>
>
>
>
>
>
>
|
>




>
>
|
>
>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
		while {$up ne "" && [set down [$w next $up]] eq ""} {
		    set up [$w parent $up]
		}
		set focus $down
	    }
	}
	left {
            if {$cells} {
                # This assumes that colAnchor is of the "#N" format.
                set colNo [string range $colAnchor 1 end]
                set firstCol [expr {"tree" ni [$w cget -show]}]
                if {$colNo >  $firstCol} {
                    incr colNo -1
                    set colAnchor "#$colNo"
                }
            } elseif {[$w item $focus -open] && [llength [$w children $focus]]} {
		CloseItem $w $focus
	    } else {
		set focus [$w parent $focus]
	    }
	}
	right {
            if {$cells} {
                set colNo [string range $colAnchor 1 end]
                set dispCol [$w cget -displaycolumns]
                if {$dispCol eq "#all"} {
                    set lastCol [llength [$w cget -columns]]
                } else {
                    set lastCol [llength $dispCol]
                }
                if {$colNo < ($lastCol - 1)} {
                    incr colNo
                    set colAnchor "#$colNo"
                }
            } else {
                OpenItem $w $focus
            }
	}
    }

    if {$focus != {}} {
        if {$cells} {
            set cell [list $focus $colAnchor]
            SelectOp $w $focus $cell choose
        } else {
            SelectOp $w $focus "" choose
        }
    }
}

## Motion -- pointer motion binding.
#	Sets cursor, active element ...
#
proc ttk::treeview::Motion {w x y} {
140
141
142
143
144
145
146













147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w
    }
}














## Select $w $x $y $selectop
#	Binding procedure for selection operations.
#	See "Selection modes", below.
#
proc ttk::treeview::Select {w x y op} {
    if {[set item [$w identify row $x $y]] ne "" } {

	SelectOp $w $item $op
    }
}

## DoubleClick -- Double-Button-1 binding.
#
proc ttk::treeview::DoubleClick {w x y} {
    if {[set row [$w identify row $x $y]] ne ""} {







>
>
>
>
>
>
>
>
>
>
>
>
>







>
|







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w
    }
}

## IndentifyCell -- Locate the cell at coordinate
#	Only active when -selecttype is "cell", and leaves cell empty otherwise.
#       Down the call chain it is enough to check cell to know the selecttype.
proc ttk::treeview::IdentifyCell {w x y} {
    set cell {}
    if {[$w cget -selecttype] eq "cell"} {
        # Later handling assumes that the column in the cell ID is of the
        # format #N, which is always the case from "identify cell"
        set cell [$w identify cell $x $y]
    }
    return $cell
}

## Select $w $x $y $selectop
#	Binding procedure for selection operations.
#	See "Selection modes", below.
#
proc ttk::treeview::Select {w x y op} {
    if {[set item [$w identify row $x $y]] ne "" } {
        set cell [IdentifyCell $w $x $y]
	SelectOp $w $item $cell $op
    }
}

## DoubleClick -- Double-Button-1 binding.
#
proc ttk::treeview::DoubleClick {w x y} {
    if {[set row [$w identify row $x $y]] ne ""} {
172
173
174
175
176
177
178


179
180
181
182
183
184
185
186
    switch -- [$w identify region $x $y] {
	nothing { }
	heading { heading.press $w $x $y }
	separator { resize.press $w $x $y }
	tree -
	cell {
	    set item [$w identify item $x $y]


	    SelectOp $w $item choose
	    switch -glob -- [$w identify element $x $y] {
		*indicator -
		*disclosure { Toggle $w $item }
	    }
	}
    }
}







>
>
|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    switch -- [$w identify region $x $y] {
	nothing { }
	heading { heading.press $w $x $y }
	separator { resize.press $w $x $y }
	tree -
	cell {
	    set item [$w identify item $x $y]
            set cell [IdentifyCell $w $x $y]

	    SelectOp $w $item $cell choose
	    switch -glob -- [$w identify element $x $y] {
		*indicator -
		*disclosure { Toggle $w $item }
	    }
	}
    }
}
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283






284
285

286








287
288
289
290

291
292
293
294
295
296
297
}

proc ttk::treeview::heading.drag {w x y} {
    variable State
    if {   [$w identify region $x $y] eq "heading"
        && [$w identify column $x $y] eq $State(heading)
    } {
    	$w heading $State(heading) state pressed
    } else {
    	$w heading $State(heading) state !pressed
    }
}

proc ttk::treeview::heading.release {w} {
    variable State
    if {[lsearch -exact [$w heading $State(heading) state] pressed] >= 0} {
	after 0 [$w heading $State(heading) -command]
    }
    $w heading $State(heading) state !pressed
}

### Selection modes.
#

## SelectOp $w $item [ choose | extend | toggle ] --
#	Dispatch to appropriate selection operation
#	depending on current value of -selectmode.
#
proc ttk::treeview::SelectOp {w item op} {
    select.$op.[$w cget -selectmode] $w $item
}

## -selectmode none:
#
proc ttk::treeview::select.choose.none {w item} { $w focus $item; $w see $item }
proc ttk::treeview::select.toggle.none {w item} { $w focus $item; $w see $item }
proc ttk::treeview::select.extend.none {w item} { $w focus $item; $w see $item }

## -selectmode browse:
#
proc ttk::treeview::select.choose.browse {w item} { BrowseTo $w $item }
proc ttk::treeview::select.toggle.browse {w item} { BrowseTo $w $item }
proc ttk::treeview::select.extend.browse {w item} { BrowseTo $w $item }

## -selectmode multiple:
#
proc ttk::treeview::select.choose.extended {w item} {
    BrowseTo $w $item
}
proc ttk::treeview::select.toggle.extended {w item} {






    $w selection toggle [list $item]
}

proc ttk::treeview::select.extend.extended {w item} {








    if {[set anchor [$w focus]] ne ""} {
	$w selection set [between $w $anchor $item]
    } else {
    	BrowseTo $w $item

    }
}

### Tree structure utilities.
#

## between $tv $item1 $item2 --







|

|


















|
|




|
|
|



|
|
|



|
|

|
>
>
>
>
>
>
|
|
>
|
>
>
>
>
>
>
>
>
|
|
|
|
>







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
}

proc ttk::treeview::heading.drag {w x y} {
    variable State
    if {   [$w identify region $x $y] eq "heading"
        && [$w identify column $x $y] eq $State(heading)
    } {
	$w heading $State(heading) state pressed
    } else {
	$w heading $State(heading) state !pressed
    }
}

proc ttk::treeview::heading.release {w} {
    variable State
    if {[lsearch -exact [$w heading $State(heading) state] pressed] >= 0} {
	after 0 [$w heading $State(heading) -command]
    }
    $w heading $State(heading) state !pressed
}

### Selection modes.
#

## SelectOp $w $item [ choose | extend | toggle ] --
#	Dispatch to appropriate selection operation
#	depending on current value of -selectmode.
#
proc ttk::treeview::SelectOp {w item cell op} {
    select.$op.[$w cget -selectmode] $w $item $cell
}

## -selectmode none:
#
proc ttk::treeview::select.choose.none {w item cell} { $w focus $item; $w see $item }
proc ttk::treeview::select.toggle.none {w item cell} { $w focus $item; $w see $item }
proc ttk::treeview::select.extend.none {w item cell} { $w focus $item; $w see $item }

## -selectmode browse:
#
proc ttk::treeview::select.choose.browse {w item cell} { BrowseTo $w $item $cell }
proc ttk::treeview::select.toggle.browse {w item cell} { BrowseTo $w $item $cell }
proc ttk::treeview::select.extend.browse {w item cell} { BrowseTo $w $item $cell }

## -selectmode multiple:
#
proc ttk::treeview::select.choose.extended {w item cell} {
    BrowseTo $w $item $cell
}
proc ttk::treeview::select.toggle.extended {w item cell} {
    variable State
    if {$cell ne ""} {
        $w cellselection toggle [list $cell]
        set State(cellAnchor) $cell
        set State(cellAnchorOp) add
    } else {
        $w selection toggle [list $item]
    }
}
proc ttk::treeview::select.extend.extended {w item cell} {
    variable State
    if {$cell ne ""} {
        if {$State(cellAnchor) ne ""} {
            $w cellselection $State(cellAnchorOp) $State(cellAnchor) $cell
        } else {
            BrowseTo $w $item $cell
        }
    } else {
        if {[set anchor [$w focus]] ne ""} {
            $w selection set [between $w $anchor $item]
        } else {
            BrowseTo $w $item $cell
        }
    }
}

### Tree structure utilities.
#

## between $tv $item1 $item2 --
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#	Recursive worker routine for ttk::treeview::between
#
proc ttk::treeview::ScanBetween {tv item1 item2 item} {
    variable between
    variable selectingBetween

    if {$item eq $item1 || $item eq $item2} {
    	lappend between $item
	set selectingBetween [expr {!$selectingBetween}]
    } elseif {$selectingBetween} {
    	lappend between $item
    }
    foreach child [$tv children $item] {
	ScanBetween $tv $item1 $item2 $child
    }
}

### User interaction utilities.







|


|







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
#	Recursive worker routine for ttk::treeview::between
#
proc ttk::treeview::ScanBetween {tv item1 item2 item} {
    variable between
    variable selectingBetween

    if {$item eq $item1 || $item eq $item2} {
	lappend between $item
	set selectingBetween [expr {!$selectingBetween}]
    } elseif {$selectingBetween} {
	lappend between $item
    }
    foreach child [$tv children $item] {
	ScanBetween $tv $item1 $item2 $child
    }
}

### User interaction utilities.
364
365
366
367
368
369
370
371
372
373
374
375
376
377


378
379





380

381
382
383
}

## ToggleFocus -- toggle opened/closed state of focus item
#
proc ttk::treeview::ToggleFocus {w} {
    set item [$w focus]
    if {$item ne ""} {
    	Toggle $w $item
    }
}

## BrowseTo -- navigate to specified item; set focus and selection
#
proc ttk::treeview::BrowseTo {w item} {


    $w see $item
    $w focus $item





    $w selection set [list $item]

}

#*EOF*







|





|
>
>


>
>
>
>
>
|
>



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
}

## ToggleFocus -- toggle opened/closed state of focus item
#
proc ttk::treeview::ToggleFocus {w} {
    set item [$w focus]
    if {$item ne ""} {
	Toggle $w $item
    }
}

## BrowseTo -- navigate to specified item; set focus and selection
#
proc ttk::treeview::BrowseTo {w item cell} {
    variable State

    $w see $item
    $w focus $item
    set State(cellAnchor) $cell
    set State(cellAnchorOp) set
    if {$cell ne ""} {
        $w cellselection set [list $cell]
    } else {
        $w selection set [list $item]
    }
}

#*EOF*

Changes to library/ttk/ttk.tcl.

90
91
92
93
94
95
96




























97
98
99
100
101
102
103
    variable currentTheme ;# @@@ Temp -- [::ttk::style theme use] doesn't work
    if {$theme ni [::ttk::style theme names]} {
	package require ttk::theme::$theme
    }
    ::ttk::style theme use $theme
    set currentTheme $theme
}





























### Load widget bindings.
#
source -encoding utf-8 [file join $::ttk::library button.tcl]
source -encoding utf-8 [file join $::ttk::library menubutton.tcl]
source -encoding utf-8 [file join $::ttk::library scrollbar.tcl]
source -encoding utf-8 [file join $::ttk::library scale.tcl]







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    variable currentTheme ;# @@@ Temp -- [::ttk::style theme use] doesn't work
    if {$theme ni [::ttk::style theme names]} {
	package require ttk::theme::$theme
    }
    ::ttk::style theme use $theme
    set currentTheme $theme
}

## ttk::setTreeviewRowHeight --
#	Sets the default height of the ttk::treeview rows for the current theme.
#	To be invoked from within the library files for the built-in themes.
#
proc ::ttk::setTreeviewRowHeight {} {
    set font [::ttk::style lookup Treeview -font]
    if {$font eq {}} {
	set font TkDefaultFont
    }

    ::ttk::style configure Treeview -rowheight \
	    [expr {[font metrics $font -linespace] + 2}]
}

# Applications should make sure that the ttk::setTreeviewRowHeight
# procedure will be invoked whenever the virtual event <<ThemeChanged>>
# is received (e.g., because the value of the Treeview style's -font
# option has changed), or the virtual event <<TkWorldChanged>> with
# the user_data field (%d) set to "FontChanged" is received.  Example:
#
# bindtags . [linsert [bindtags .] 1 MyMainWin]
# bind MyMainWin <<ThemeChanged>> ttk::setTreeviewRowHeight
# bind MyMainWin <<TkWorldChanged>> {
#     if {"%d" eq "FontChanged"} {
#         ttk::setTreeviewRowHeight
#     }
# }

### Load widget bindings.
#
source -encoding utf-8 [file join $::ttk::library button.tcl]
source -encoding utf-8 [file join $::ttk::library menubutton.tcl]
source -encoding utf-8 [file join $::ttk::library scrollbar.tcl]
source -encoding utf-8 [file join $::ttk::library scale.tcl]
168
169
170
171
172
173
174
175




176
	    return $theme
	}
    }
    return "default"
}

ttk::setTheme [ttk::DefaultTheme] ; rename ttk::DefaultTheme {}





#*EOF*








>
>
>
>

196
197
198
199
200
201
202
203
204
205
206
207
208
	    return $theme
	}
    }
    return "default"
}

ttk::setTheme [ttk::DefaultTheme] ; rename ttk::DefaultTheme {}

# Scale the default ttk::scale and ttk::progressbar length
option add *TScale.length	75p widgetDefault
option add *TProgressbar.length	75p widgetDefault

#*EOF*

Changes to library/ttk/utils.tcl.

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#	Test if the widget can take keyboard focus.
#
#	See the description of the -takefocus option in options(n)
#	for details.
#
proc ttk::takesFocus {w} {
    if {![winfo viewable $w]} {
    	return 0
    } elseif {[catch {$w cget -takefocus} takefocus]} {
	return [GuessTakeFocus $w]
    } else {
	switch -- $takefocus {
	    "" { return [GuessTakeFocus $w] }
	    0  { return 0 }
	    1  { return 1 }







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#	Test if the widget can take keyboard focus.
#
#	See the description of the -takefocus option in options(n)
#	for details.
#
proc ttk::takesFocus {w} {
    if {![winfo viewable $w]} {
	return 0
    } elseif {[catch {$w cget -takefocus} takefocus]} {
	return [GuessTakeFocus $w]
    } else {
	switch -- $takefocus {
	    "" { return [GuessTakeFocus $w] }
	    0  { return 0 }
	    1  { return 1 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	return
    }

    set restoreGrab [set restoreFocus ""]

    set grabbed [grab current $w]
    if {[winfo exists $grabbed]} {
    	switch [grab status $grabbed] {
	    global { set restoreGrab [list grab -global $grabbed] }
	    local  { set restoreGrab [list grab $grabbed] }
	    none   { ;# grab window is really in a different interp }
	}
    }

    set focus [focus]
    if {$focus ne ""} {
    	set restoreFocus [list focus -force $focus]
    }

    set Grab($w) [list $restoreGrab $restoreFocus]
}

## RestoreGrab --
#	Restore previous grab and focus windows.







|








|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	return
    }

    set restoreGrab [set restoreFocus ""]

    set grabbed [grab current $w]
    if {[winfo exists $grabbed]} {
	switch [grab status $grabbed] {
	    global { set restoreGrab [list grab -global $grabbed] }
	    local  { set restoreGrab [list grab $grabbed] }
	    none   { ;# grab window is really in a different interp }
	}
    }

    set focus [focus]
    if {$focus ne ""} {
	set restoreFocus [list focus -force $focus]
    }

    set Grab($w) [list $restoreGrab $restoreFocus]
}

## RestoreGrab --
#	Restore previous grab and focus windows.
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
#	Begin auto-repeat.
#
proc ttk::Repeatedly {args} {
    variable Repeat
    after cancel $Repeat(timer)
    set script [uplevel 1 [list namespace code $args]]
    set Repeat(script) $script
    uplevel #0 $script
    set Repeat(timer) [after $Repeat(delay) ttk::Repeat]

}

## Repeat --
#	Continue auto-repeat
#
proc ttk::Repeat {} {
    variable Repeat
    uplevel #0 $Repeat(script)
    set Repeat(timer) [after $Repeat(interval) ttk::Repeat]

}

## ttk::CancelRepeat --
#	Halt auto-repeat.
#
proc ttk::CancelRepeat {} {
    variable Repeat







<

>







<

>







232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256
#	Begin auto-repeat.
#
proc ttk::Repeatedly {args} {
    variable Repeat
    after cancel $Repeat(timer)
    set script [uplevel 1 [list namespace code $args]]
    set Repeat(script) $script

    set Repeat(timer) [after $Repeat(delay) ttk::Repeat]
    uplevel #0 $script
}

## Repeat --
#	Continue auto-repeat
#
proc ttk::Repeat {} {
    variable Repeat

    set Repeat(timer) [after $Repeat(interval) ttk::Repeat]
    uplevel #0 $Repeat(script)
}

## ttk::CancelRepeat --
#	Halt auto-repeat.
#
proc ttk::CancelRepeat {} {
    variable Repeat
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308














309
# MouseWheel scrolling is accelerated on X11, which is conventional
# for Tk and appears to be conventional for other toolkits (although
# Gtk+ and Qt do not appear to use as large a factor).
#

## ttk::bindMouseWheel $bindtag $command...
#	Adds basic mousewheel support to $bindtag.
#	$command will be passed one additional argument
#	specifying the mousewheel direction (-1: up, +1: down).
#

proc ttk::bindMouseWheel {bindtag callback} {
    bind $bindtag <MouseWheel> [append callback { %D -120.0}]
    bind $bindtag <Option-MouseWheel> [append callback { %D -12.0}]
}

## Mousewheel bindings for standard scrollable widgets.
#
# Usage: [ttk::copyBindings TtkScrollable $bindtag]
#
# $bindtag should be for a widget that supports the
# standard scrollbar protocol.
#

bind TtkScrollable <MouseWheel> \
	{ tk::MouseWheel %W y %D }
bind TtkScrollable <Option-MouseWheel> \
	{ tk::MouseWheel %W y %D -12.0 }
bind TtkScrollable <Shift-MouseWheel> \
	{ tk::MouseWheel %W x %D }
bind TtkScrollable <Shift-Option-MouseWheel> \
	{ tk::MouseWheel %W x %D -12.0 }















#*EOF*







|
|



|
|




<
|
<
<
<
<

|



|



>
>
>
>
>
>
>
>
>
>
>
>
>
>

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294




295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# 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 two additional arguments
#	specifying the mousewheel change and a factor.
#

proc ttk::bindMouseWheel {bindtag callback} {
    bind $bindtag <MouseWheel> "$callback %D -120.0"
    bind $bindtag <Option-MouseWheel> "$callback %D -12.0"
}

## Mousewheel bindings for standard scrollable widgets.
#






bind TtkScrollable <MouseWheel> \
	{ tk::MouseWheel %W y %D -40.0 }
bind TtkScrollable <Option-MouseWheel> \
	{ tk::MouseWheel %W y %D -12.0 }
bind TtkScrollable <Shift-MouseWheel> \
	{ tk::MouseWheel %W x %D -40.0 }
bind TtkScrollable <Shift-Option-MouseWheel> \
	{ tk::MouseWheel %W x %D -12.0 }

## Touchpad scrolling
#
bind TtkScrollable <TouchpadScroll> {
    if {%# %% 5 != 0} {
        return
    }
    lassign [tk::PreciseScrollDeltas %D] deltaX deltaY
    if {$deltaX != 0} {
 	%W xview scroll [expr {-$deltaX}] units
    }
    if {$deltaY != 0} {
	%W yview scroll [expr {-$deltaY}] units
    }
}
#*EOF*

Changes to library/ttk/vistaTheme.tcl.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

	ttk::style configure TButton -anchor center -padding {1 1} -width -11
	ttk::style configure TRadiobutton -padding 2
	ttk::style configure TCheckbutton -padding 2
	ttk::style configure TMenubutton -padding {8 4}

	ttk::style element create Menubutton.dropdown vsapi \
	    TOOLBAR 4 {{selected active} 6 {selected !active} 5
		disabled 4 pressed 3 active 2 {} 1} \
	    -syssize {SM_CXVSCROLL SM_CYVSCROLL}

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style map TNotebook.Tab \
	    -expand [list selected {2 2 2 2}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont
	ttk::style configure Treeview -background SystemWindow



	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        # Label and Toolbutton
	ttk::style configure TLabelframe.Label -foreground SystemButtonText

	ttk::style configure Toolbutton -padding {4 4}

        # Combobox
	ttk::style configure TCombobox -padding 2
        ttk::style element create Combobox.border vsapi \
            COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1}
        ttk::style element create Combobox.background vsapi \
            EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1}
        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}







|
|
<
|
<
|
<
|
|
|
|







|
<



|
>
>
>









|


|







18
19
20
21
22
23
24
25
26

27

28

29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont


	ttk::style map "." -foreground {disabled SystemGrayText}



	ttk::style configure TButton -anchor center -padding 0.75p -width -11
	ttk::style configure TRadiobutton -padding 1.5p
	ttk::style configure TCheckbutton -padding 1.5p
	ttk::style configure TMenubutton -padding {6p 3p}

	ttk::style element create Menubutton.dropdown vsapi \
	    TOOLBAR 4 {{selected active} 6 {selected !active} 5
		disabled 4 pressed 3 active 2 {} 1} \
	    -syssize {SM_CXVSCROLL SM_CYVSCROLL}

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style map TNotebook.Tab -expand {selected {2 2 2 2}}


	# Treeview:
	ttk::style configure Heading -font TkHeadingFont
	ttk::style configure Treeview -background SystemWindow \
                -stripedbackground System3dLight
	ttk::style configure Treeview.Separator \
                -background System3dLight
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        # Label and Toolbutton
	ttk::style configure TLabelframe.Label -foreground SystemButtonText

	ttk::style configure Toolbutton -padding 3p

        # Combobox
	ttk::style configure TCombobox -padding 1.5p
        ttk::style element create Combobox.border vsapi \
            COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1}
        ttk::style element create Combobox.background vsapi \
            EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1}
        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
            }
        }
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -foreground	[list \
		disabled		SystemGrayText \
	    	{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight] \
	    ;

        # Entry
        ttk::style configure TEntry -padding {1 1 1 1} ;# Needs lookup
        ttk::style element create Entry.field vsapi \
            EDIT 6 {disabled 4 focus 3 hover 2 {} 1} -padding {2 2 2 2}
        ttk::style element create Entry.background vsapi \
            EDIT 3 {disabled 3 readonly 3 focus 4 hover 2 {} 1}
        ttk::style layout TEntry {
            Entry.field -sticky news -border 0 -children {
                Entry.background -sticky news -children {
                    Entry.padding -sticky news -children {
                        Entry.textarea -sticky news
                    }
                }
            }
        }
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;

        # Spinbox
        ttk::style configure TSpinbox -padding 0
        ttk::style element create Spinbox.field vsapi \
            EDIT 9 {disabled 4 focus 3 hover 2 {} 1} -padding {1 1 1 2}
        ttk::style element create Spinbox.background vsapi \
            EDIT 3 {disabled 3 readonly 3 focus 4 hover 2 {} 1}







|

|
<


















|
<







86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
            }
        }
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -foreground	[list \
		disabled		SystemGrayText \
		{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight]


        # Entry
        ttk::style configure TEntry -padding {1 1 1 1} ;# Needs lookup
        ttk::style element create Entry.field vsapi \
            EDIT 6 {disabled 4 focus 3 hover 2 {} 1} -padding {2 2 2 2}
        ttk::style element create Entry.background vsapi \
            EDIT 3 {disabled 3 readonly 3 focus 4 hover 2 {} 1}
        ttk::style layout TEntry {
            Entry.field -sticky news -border 0 -children {
                Entry.background -sticky news -children {
                    Entry.padding -sticky news -children {
                        Entry.textarea -sticky news
                    }
                }
            }
        }
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText]


        # Spinbox
        ttk::style configure TSpinbox -padding 0
        ttk::style element create Spinbox.field vsapi \
            EDIT 9 {disabled 4 focus 3 hover 2 {} 1} -padding {1 1 1 2}
        ttk::style element create Spinbox.background vsapi \
            EDIT 3 {disabled 3 readonly 3 focus 4 hover 2 {} 1}
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
                    Spinbox.uparrow -side top -sticky ens
                    Spinbox.downarrow -side bottom -sticky ens
                }
            }
        }
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;


        # SCROLLBAR elements (Vista includes a state for 'hover')
        ttk::style element create Vertical.Scrollbar.uparrow vsapi \
            SCROLLBAR 1 {disabled 4 pressed 3 active 2 hover 17 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style element create Vertical.Scrollbar.downarrow vsapi \







|
<







141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
                    Spinbox.uparrow -side top -sticky ens
                    Spinbox.downarrow -side bottom -sticky ens
                }
            }
        }
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText]



        # SCROLLBAR elements (Vista includes a state for 'hover')
        ttk::style element create Vertical.Scrollbar.uparrow vsapi \
            SCROLLBAR 1 {disabled 4 pressed 3 active 2 hover 17 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style element create Vertical.Scrollbar.downarrow vsapi \
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

        # Progressbar
        ttk::style element create Horizontal.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Horizontal.TProgressbar {
            Horizontal.Progressbar.trough -sticky nswe -children {
                Horizontal.Progressbar.pbar -side left -sticky ns
                Horizontal.Progressbar.text -sticky nesw
            }
        }
        ttk::style element create Vertical.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Vertical.TProgressbar {
            Vertical.Progressbar.trough -sticky nswe -children {
                Vertical.Progressbar.pbar -side bottom -sticky we







|







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

        # Progressbar
        ttk::style element create Horizontal.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Horizontal.TProgressbar {
            Horizontal.Progressbar.trough -sticky nswe -children {
                Horizontal.Progressbar.pbar -side left -sticky ns
                Horizontal.Progressbar.ctext -sticky nesw
            }
        }
        ttk::style element create Vertical.Progressbar.pbar vsapi \
            PROGRESS 3 {{} 1} -padding 8
        ttk::style layout Vertical.TProgressbar {
            Vertical.Progressbar.trough -sticky nswe -children {
                Vertical.Progressbar.pbar -side bottom -sticky we
219
220
221
222
223
224
225
226


227
228
229
230
                    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
    }
}







|
>
>




215
216
217
218
219
220
221
222
223
224
225
226
227
228
                    Vertical.Scale.track -sticky ns
                    Vertical.Scale.slider -side top -sticky {}
                }
            }
        }

        # Treeview
        ttk::style configure Item -padding {3p 0 0 0}
	ttk::style configure Treeview -indent 15p
	ttk::setTreeviewRowHeight

        package provide ttk::theme::vista 1.0
    }
}

Changes to library/ttk/winTheme.tcl.

1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73


74


75
76
77
78
79
80
81
82

83
84
#
# Settings for 'winnative' theme.
#

namespace eval ttk::theme::winnative {

    ttk::style theme settings winnative {

	ttk::style configure "." \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -fieldbackground SystemWindow \
	    -insertcolor SystemWindowText \
	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." -foreground [list disabled SystemGrayText] ;
        ttk::style map "." -embossed [list disabled 1] ;

	ttk::style configure TButton \
	    -anchor center -width -11 -relief raised -shiftrelief 1


	ttk::style configure TCheckbutton -padding "2 4"
	ttk::style configure TRadiobutton -padding "2 4"

	ttk::style configure TMenubutton \
	    -padding "8 4" -arrowsize 3 -relief raised

	ttk::style map TButton -relief {{!disabled pressed} sunken}

	ttk::style configure TEntry \
	    -padding 2 -selectborderwidth 0 -insertwidth 1
	ttk::style map TEntry \
	    -fieldbackground \
	    	[list readonly SystemButtonFace disabled SystemButtonFace] \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;

	ttk::style configure TCombobox -padding 2
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -fieldbackground [list \
	    	readonly SystemButtonFace \
		disabled SystemButtonFace] \
	    -foreground	[list \
		disabled		SystemGrayText \
	    	{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight] \
	    ;

	ttk::style element create ComboboxPopdownFrame.border from default
	ttk::style configure ComboboxPopdownFrame \
	    -borderwidth 1 -relief solid

        ttk::style configure TSpinbox -padding {2 0 16 0}

	ttk::style configure TLabelframe -borderwidth 2 -relief groove

	ttk::style configure Toolbutton -relief flat -padding {8 4}
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken  pressed sunken  active raised}

	ttk::style configure TScale -groovewidth 4

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style configure TNotebook.Tab -padding {3 1} -borderwidth 1
	ttk::style map TNotebook.Tab -expand [list selected {2 2 2 0}]

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised


	ttk::style configure Treeview -background SystemWindow


	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        ttk::style configure TProgressbar \
	    -background SystemHighlight -borderwidth 0 ;

    }
}





>










|
|
<
|
|



>
>
|
|
>

<
|
<





|
|
|
|
<
|




|



|

|
<





|



|

|

|


|
|



>
>
|
>
>







|
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29

30

31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#
# Settings for 'winnative' theme.
#

namespace eval ttk::theme::winnative {

    ttk::style theme settings winnative {

	ttk::style configure "." \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -fieldbackground SystemWindow \
	    -insertcolor SystemWindowText \
	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont


	ttk::style map "." -foreground {disabled SystemGrayText}
        ttk::style map "." -embossed {disabled 1}

	ttk::style configure TButton \
	    -anchor center -width -11 -relief raised -shiftrelief 1
	ttk::style map TButton -relief {{!disabled pressed} sunken}

	ttk::style configure TCheckbutton -padding {1.5p 3p}
	ttk::style configure TRadiobutton -padding {1.5p 3p}

	ttk::style configure TMenubutton \

	    -padding {6p 3p} -arrowsize 2.25p -relief raised


	ttk::style configure TEntry \
	    -padding 2 -selectborderwidth 0 -insertwidth 1
	ttk::style map TEntry \
	    -fieldbackground \
		{readonly SystemButtonFace disabled SystemButtonFace} \
	    -selectbackground {!focus SystemWindow} \
	    -selectforeground {!focus SystemWindowText}


	ttk::style configure TCombobox -padding 1.5p
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -fieldbackground [list \
		readonly SystemButtonFace \
		disabled SystemButtonFace] \
	    -foreground	[list \
		disabled		SystemGrayText \
		{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill {{readonly focus} SystemHighlight}


	ttk::style element create ComboboxPopdownFrame.border from default
	ttk::style configure ComboboxPopdownFrame \
	    -borderwidth 1 -relief solid

	ttk::style configure TSpinbox -padding {1.5p 0 12p 0}

	ttk::style configure TLabelframe -borderwidth 2 -relief groove

	ttk::style configure Toolbutton -relief flat -padding {6p 3p}
	ttk::style map Toolbutton -relief \
	    {disabled flat  selected sunken  pressed sunken  active raised}

	ttk::style configure TScale -groovewidth 3p

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style configure TNotebook.Tab -padding {2.25p 0.75p} -borderwidth 1
	ttk::style map TNotebook.Tab -expand {selected {2 2 2 0}}

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Item \
	    -indicatormargins {1.5p 1.5p 3p 1.5p}
	ttk::style configure Treeview -background SystemWindow \
	    -stripedbackground System3dLight -indent 15p
	ttk::setTreeviewRowHeight
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        ttk::style configure TProgressbar \
	    -background SystemHighlight -borderwidth 0 \
	    -barsize 22.5p -thickness 11.25p
    }
}

Changes to library/ttk/xpTheme.tcl.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59


60


61
62
63
64
65
66
67

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

	ttk::style configure TButton -anchor center -padding {1 1} -width -11
	ttk::style configure TRadiobutton -padding 2
	ttk::style configure TCheckbutton -padding 2
	ttk::style configure TMenubutton -padding {8 4}

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style map TNotebook.Tab \
	    -expand [list selected {2 2 2 2}]

	ttk::style configure TLabelframe.Label -foreground "#0046d5"

	# OR: -padding {3 3 3 6}, which some apps seem to use.
	ttk::style configure TEntry -padding {2 2 2 4}
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;
	ttk::style configure TCombobox -padding 2
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -foreground	[list \
		disabled		SystemGrayText \
	    	{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight] \
	    ;

	ttk::style configure TSpinbox -padding {2 0 14 0}
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    ;

	ttk::style configure Toolbutton -padding {4 4}

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised


	ttk::style configure Treeview -background SystemWindow


	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText];
    }
}







|
|
<
<
|
|
<
|
|
|
|


|
<







|
<
|





|

|
|
<
|


|
|
<
|



>
>
|
>
>




|


8
9
10
11
12
13
14
15
16


17
18

19
20
21
22
23
24
25

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43

44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont



	ttk::style map "." -foreground [list disabled SystemGrayText]


	ttk::style configure TButton -anchor center -padding 0.75p -width -11
	ttk::style configure TRadiobutton -padding 1.5p
	ttk::style configure TCheckbutton -padding 1.5p
	ttk::style configure TMenubutton -padding {6p 3p}

	ttk::style configure TNotebook -tabmargins {2 2 2 0}
	ttk::style map TNotebook.Tab -expand {selected {2 2 2 2}}


	ttk::style configure TLabelframe.Label -foreground "#0046d5"

	# OR: -padding {3 3 3 6}, which some apps seem to use.
	ttk::style configure TEntry -padding {2 2 2 4}
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText]

	ttk::style configure TCombobox -padding 1.5p
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -foreground	[list \
		disabled		SystemGrayText \
		{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight]


	ttk::style configure TSpinbox -padding {1.5p 0 10.5p 0}
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText]


	ttk::style configure Toolbutton -padding 3p

	# Treeview:
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Item \
	    -indicatormargins {1.5p 1.5p 3p 1.5p}
	ttk::style configure Treeview -background SystemWindow \
	    -stripedbackground System3dLight -indent 15p
	ttk::setTreeviewRowHeight
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]
    }
}

Deleted library/unsupported.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
# unsupported.tcl --
#
# Commands provided by Tk without official support.  Use them at your
# own risk.  They may change or go away without notice.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

# ----------------------------------------------------------------------
# Unsupported compatibility interface for folks accessing Tk's private
# commands and variable against recommended usage.
# ----------------------------------------------------------------------

namespace eval ::tk::unsupported {

    # Map from the old global names of Tk private commands to their
    # new namespace-encapsulated names.

    variable PrivateCommands
    array set PrivateCommands {
	tkButtonAutoInvoke		::tk::ButtonAutoInvoke
	tkButtonDown			::tk::ButtonDown
	tkButtonEnter			::tk::ButtonEnter
	tkButtonInvoke			::tk::ButtonInvoke
	tkButtonLeave			::tk::ButtonLeave
	tkButtonUp			::tk::ButtonUp
	tkCancelRepeat			::tk::CancelRepeat
	tkCheckRadioDown		::tk::CheckRadioDown
	tkCheckRadioEnter		::tk::CheckRadioEnter
	tkCheckRadioInvoke		::tk::CheckRadioInvoke
	tkColorDialog			::tk::dialog::color::
	tkColorDialog_BuildDialog	::tk::dialog::color::BuildDialog
	tkColorDialog_CancelCmd		::tk::dialog::color::CancelCmd
	tkColorDialog_Config		::tk::dialog::color::Config
	tkColorDialog_CreateSelector	::tk::dialog::color::CreateSelector
	tkColorDialog_DrawColorScale	::tk::dialog::color::DrawColorScale
	tkColorDialog_EnterColorBar	::tk::dialog::color::EnterColorBar
	tkColorDialog_InitValues	::tk::dialog::color::InitValues
	tkColorDialog_HandleRGBEntry	::tk::dialog::color::HandleRGBEntry
	tkColorDialog_HandleSelEntry	::tk::dialog::color::HandleSelEntry
	tkColorDialog_LeaveColorBar	::tk::dialog::color::LeaveColorBar
	tkColorDialog_MoveSelector	::tk::dialog::color::MoveSelector
	tkColorDialog_OkCmd		::tk::dialog::color::OkCmd
	tkColorDialog_RedrawColorBars	::tk::dialog::color::RedrawColorBars
	tkColorDialog_RedrawFinalColor	::tk::dialog::color::RedrawFinalColor
	tkColorDialog_ReleaseMouse	::tk::dialog::color::ReleaseMouse
	tkColorDialog_ResizeColorBars	::tk::dialog::color::ResizeColorBars
	tkColorDialog_RgbToX		::tk::dialog::color::RgbToX
	tkColorDialog_SetRGBValue	::tk::dialog::color::SetRGBValue
	tkColorDialog_StartMove		::tk::dialog::color::StartMove
	tkColorDialog_XToRgb		::tk::dialog::color::XToRGB
	tkConsoleAbout			::tk::ConsoleAbout
	tkConsoleBind			::tk::ConsoleBind
	tkConsoleExit			::tk::ConsoleExit
	tkConsoleHistory		::tk::ConsoleHistory
	tkConsoleInit			::tk::ConsoleInit
	tkConsoleInsert			::tk::ConsoleInsert
	tkConsoleInvoke			::tk::ConsoleInvoke
	tkConsoleOutput			::tk::ConsoleOutput
	tkConsolePrompt			::tk::ConsolePrompt
	tkConsoleSource			::tk::ConsoleSource
	tkDarken			::tk::Darken
	tkEntryAutoScan			::tk::EntryAutoScan
	tkEntryBackspace		::tk::EntryBackspace
	tkEntryButton1			::tk::EntryButton1
	tkEntryClosestGap		::tk::EntryClosestGap
	tkEntryGetSelection		::tk::EntryGetSelection
	tkEntryInsert			::tk::EntryInsert
	tkEntryKeySelect		::tk::EntryKeySelect
	tkEntryMouseSelect		::tk::EntryMouseSelect
	tkEntryNextWord			::tk::EntryNextWord
	tkEntryPaste			::tk::EntryPaste
	tkEntryPreviousWord		::tk::EntryPreviousWord
	tkEntrySeeInsert		::tk::EntrySeeInsert
	tkEntrySetCursor		::tk::EntrySetCursor
	tkEntryTranspose		::tk::EntryTranspose
	tkEventMotifBindings		::tk::EventMotifBindings
	tkFDGetFileTypes		::tk::FDGetFileTypes
	tkFirstMenu			::tk::FirstMenu
	tkFocusGroup_BindIn		::tk::FocusGroup_BindIn
	tkFocusGroup_BindOut		::tk::FocusGroup_BindOut
	tkFocusGroup_Create		::tk::FocusGroup_Create
	tkFocusGroup_Destroy		::tk::FocusGroup_Destroy
	tkFocusGroup_In			::tk::FocusGroup_In
	tkFocusGroup_Out		::tk::FocusGroup_Out
	tkFocusOK			::tk::FocusOK
	tkGenerateMenuSelect		::tk::GenerateMenuSelect
	tkIconList			::tk::IconList
	tkListbox			::tk::Listbox
	tkListboxAutoScan		::tk::ListboxAutoScan
	tkListboxBeginExtend		::tk::ListboxBeginExtend
	tkListboxBeginSelect		::tk::ListboxBeginSelect
	tkListboxBeginToggle		::tk::ListboxBeginToggle
	tkListboxCancel			::tk::ListboxCancel
	tkListboxDataExtend		::tk::ListboxDataExtend
	tkListboxExtendUpDown		::tk::ListboxExtendUpDown
	tkListboxKeyAccel_Goto		::tk::ListboxKeyAccel_Goto
	tkListboxKeyAccel_Key		::tk::ListboxKeyAccel_Key
	tkListboxKeyAccel_Reset		::tk::ListboxKeyAccel_Reset
	tkListboxKeyAccel_Set		::tk::ListboxKeyAccel_Set
	tkListboxKeyAccel_Unset		::tk::ListboxKeyAccel_Unxet
	tkListboxMotion			::tk::ListboxMotion
	tkListboxSelectAll		::tk::ListboxSelectAll
	tkListboxUpDown			::tk::ListboxUpDown
	tkListboxBeginToggle		::tk::ListboxBeginToggle
	tkMbButtonUp			::tk::MbButtonUp
	tkMbEnter			::tk::MbEnter
	tkMbLeave			::tk::MbLeave
	tkMbMotion			::tk::MbMotion
	tkMbPost			::tk::MbPost
	tkMenuButtonDown		::tk::MenuButtonDown
	tkMenuDownArrow			::tk::MenuDownArrow
	tkMenuDup			::tk::MenuDup
	tkMenuEscape			::tk::MenuEscape
	tkMenuFind			::tk::MenuFind
	tkMenuFindName			::tk::MenuFindName
	tkMenuFirstEntry		::tk::MenuFirstEntry
	tkMenuInvoke			::tk::MenuInvoke
	tkMenuLeave			::tk::MenuLeave
	tkMenuLeftArrow			::tk::MenuLeftArrow
	tkMenuMotion			::tk::MenuMotion
	tkMenuNextEntry			::tk::MenuNextEntry
	tkMenuNextMenu			::tk::MenuNextMenu
	tkMenuRightArrow		::tk::MenuRightArrow
	tkMenuUnpost			::tk::MenuUnpost
	tkMenuUpArrow			::tk::MenuUpArrow
	tkMessageBox			::tk::MessageBox
	tkMotifFDialog			::tk::MotifFDialog
	tkMotifFDialog_ActivateDList	::tk::MotifFDialog_ActivateDList
	tkMotifFDialog_ActivateFList	::tk::MotifFDialog_ActivateFList
	tkMotifFDialog_ActivateFEnt	::tk::MotifFDialog_ActivateFEnt
	tkMotifFDialog_ActivateSEnt	::tk::MotifFDialog_ActivateSEnt
	tkMotifFDialog			::tk::MotifFDialog
	tkMotifFDialog_BrowseDList	::tk::MotifFDialog_BrowseDList
	tkMotifFDialog_BrowseFList	::tk::MotifFDialog_BrowseFList
	tkMotifFDialog_BuildUI		::tk::MotifFDialog_BuildUI
	tkMotifFDialog_CancelCmd	::tk::MotifFDialog_CancelCmd
	tkMotifFDialog_Config		::tk::MotifFDialog_Config
	tkMotifFDialog_Create		::tk::MotifFDialog_Create
	tkMotifFDialog_FileTypes	::tk::MotifFDialog_FileTypes
	tkMotifFDialog_FilterCmd	::tk::MotifFDialog_FilterCmd
	tkMotifFDialog_InterpFilter	::tk::MotifFDialog_InterpFilter
	tkMotifFDialog_LoadFiles	::tk::MotifFDialog_LoadFiles
	tkMotifFDialog_MakeSList	::tk::MotifFDialog_MakeSList
	tkMotifFDialog_OkCmd		::tk::MotifFDialog_OkCmd
	tkMotifFDialog_SetFilter	::tk::MotifFDialog_SetFilter
	tkMotifFDialog_SetListMode	::tk::MotifFDialog_SetListMode
	tkMotifFDialog_Update		::tk::MotifFDialog_Update
	tkPostOverPoint			::tk::PostOverPoint
	tkRecolorTree			::tk::RecolorTree
	tkRestoreOldGrab		::tk::RestoreOldGrab
	tkSaveGrabInfo			::tk::SaveGrabInfo
	tkScaleActivate			::tk::ScaleActivate
	tkScaleButtonDown		::tk::ScaleButtonDown
	tkScaleButton2Down		::tk::ScaleButton2Down
	tkScaleControlPress		::tk::ScaleControlPress
	tkScaleDrag			::tk::ScaleDrag
	tkScaleEndDrag			::tk::ScaleEndDrag
	tkScaleIncrement		::tk::ScaleIncrement
	tkScreenChanged			::tk::ScreenChanged
	tkScrollButtonDown		::tk::ScrollButtonDown
	tkScrollButton2Down		::tk::ScrollButton2Down
	tkScrollButtonDrag		::tk::ScrollButtonDrag
	tkScrollButtonUp		::tk::ScrollButtonUp
	tkScrollByPages			::tk::ScrollByPages
	tkScrollByUnits			::tk::ScrollByUnits
	tkScrollEndDrag			::tk::ScrollEndDrag
	tkScrollSelect			::tk::ScrollSelect
	tkScrollStartDrag		::tk::ScrollStartDrag
	tkScrollTopBottom		::tk::ScrollTopBottom
	tkScrollToPos			::tk::ScrollToPos
	tkTabToWindow			::tk::TabToWindow
	tkTearOffMenu			::tk::TearOffMenu
	tkTextAutoScan			::tk::TextAutoScan
	tkTextButton1			::tk::TextButton1
	tkTextClosestGap		::tk::TextClosestGap
	tkTextInsert			::tk::TextInsert
	tkTextKeyExtend			::tk::TextKeyExtend
	tkTextKeySelect			::tk::TextKeySelect
	tkTextNextPara			::tk::TextNextPara
	tkTextNextPos			::tk::TextNextPos
	tkTextNextWord			::tk::TextNextWord
	tkTextPaste			::tk::TextPaste
	tkTextPrevPara			::tk::TextPrevPara
	tkTextPrevPos			::tk::TextPrevPos
	tkTextPrevWord			::tk::TextPrevWord
	tkTextResetAnchor		::tk::TextResetAnchor
	tkTextScrollPages		::tk::TextScrollPages
	tkTextSelectTo			::tk::TextSelectTo
	tkTextSetCursor			::tk::TextSetCursor
	tkTextTranspose			::tk::TextTranspose
	tkTextUpDownLine		::tk::TextUpDownLine
	tkTraverseToMenu		::tk::TraverseToMenu
	tkTraverseWithinMenu		::tk::TraverseWithinMenu
	unsupported1			::tk::unsupported::MacWindowStyle
    }

    # Map from the old global names of Tk private variable to their
    # new namespace-encapsulated names.

    variable PrivateVariables
    array set PrivateVariables {
	droped_to_start		::tk::mac::Droped_to_start
	histNum			::tk::HistNum
	stub_location		::tk::mac::Stub_location
	tkFocusIn		::tk::FocusIn
	tkFocusOut		::tk::FocusOut
	tkPalette		::tk::Palette
	tkPriv			::tk::Priv
	tkPrivMsgBox		::tk::PrivMsgBox
    }
}

# ::tk::unsupported::ExposePrivateCommand --
#
#	Expose one of Tk's private commands to be visible under its
#	old global name
#
# Arguments:
#	cmd	Global name by which the command was once known,
#               or a glob-style pattern.
#
# Results:
#	None.
#
# Side effects:
#	The old command name in the global namespace is aliased to the
#	new private name.

proc ::tk::unsupported::ExposePrivateCommand {cmd} {
    variable PrivateCommands
    set cmds [array get PrivateCommands $cmd]
    if {[llength $cmds] == 0} {
	return -code error -errorcode {TK EXPOSE_PRIVATE_COMMAND} \
	    "No compatibility support for \[$cmd]"
    }
    foreach {old new} $cmds {
	namespace eval :: [list interp alias {} $old {}] $new
    }
}

# ::tk::unsupported::ExposePrivateVariable --
#
#	Expose one of Tk's private variables to be visible under its
#	old global name
#
# Arguments:
#	var	Global name by which the variable was once known,
#               or a glob-style pattern.
#
# Results:
#	None.
#
# Side effects:
#	The old variable name in the global namespace is aliased to the
#	new private name.

proc ::tk::unsupported::ExposePrivateVariable {var} {
    variable PrivateVariables
    set vars [array get PrivateVariables $var]
    if {[llength $vars] == 0} {
	return -code error -errorcode {TK EXPOSE_PRIVATE_VARIABLE} \
	    "No compatibility support for \$$var"
    }
    namespace eval ::tk::mac {}
    foreach {old new} $vars {
	namespace eval :: [list upvar "#0" $new $old]
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































Changes to library/xmfbox.tcl.

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

proc ::tk::MotifFDialog_Create {dataName type argList} {
    upvar ::tk::dialog::file::$dataName data

    MotifFDialog_Config $dataName $type $argList

    if {$data(-parent) eq "."} {
        set w .$dataName
    } else {
        set w $data(-parent).$dataName
    }

    # (re)create the dialog box if necessary
    #
    if {![winfo exists $w]} {
	MotifFDialog_BuildUI $w
    } elseif {[winfo class $w] ne "TkMotifFDialog"} {







|

|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

proc ::tk::MotifFDialog_Create {dataName type argList} {
    upvar ::tk::dialog::file::$dataName data

    MotifFDialog_Config $dataName $type $argList

    if {$data(-parent) eq "."} {
	set w .$dataName
    } else {
	set w $data(-parent).$dataName
    }

    # (re)create the dialog box if necessary
    #
    if {![winfo exists $w]} {
	MotifFDialog_BuildUI $w
    } elseif {[winfo class $w] ne "TkMotifFDialog"} {
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    pack $f1 -side top    -fill x
    pack $f3 -side bottom -fill x
    pack $f2 -expand yes -fill both

    set f2a [frame $f2.a]
    set f2b [frame $f2.b]

    grid $f2a -row 0 -column 0 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \
	-sticky news
    grid $f2b -row 0 -column 1 -rowspan 1 -columnspan 1 -padx 4 -pady 4 \
	-sticky news
    grid rowconfigure $f2 0    -minsize 0   -weight 1
    grid columnconfigure $f2 0 -minsize 0   -weight 1
    grid columnconfigure $f2 1 -minsize 150 -weight 2

    # The Filter box
    #
    bind [::tk::AmpWidget label $f1.lab -text [mc "Fil&ter:"] -anchor w] \
	<<AltUnderlined>> [list focus $f1.ent]
    entry $f1.ent
    pack $f1.lab -side top -fill x -padx 6 -pady 4
    pack $f1.ent -side top -fill x -padx 4 -pady 0
    set data(fEnt) $f1.ent

    # The file and directory lists
    #
    set data(dList) [MotifFDialog_MakeSList $w $f2a \
	    [mc "&Directory:"] DList]
    set data(fList) [MotifFDialog_MakeSList $w $f2b \
	    [mc "Fi&les:"]     FList]

    # The Selection box
    #
    bind [::tk::AmpWidget label $f3.lab -text [mc "&Selection:"] -anchor w] \
	<<AltUnderlined>> [list focus $f3.ent]
    entry $f3.ent
    pack $f3.lab -side top -fill x -padx 6 -pady 0
    pack $f3.ent -side top -fill x -padx 4 -pady 4
    set data(sEnt) $f3.ent

    # The buttons
    #
    set maxWidth [::tk::mcmaxamp &OK &Filter &Cancel]
    set maxWidth [expr {$maxWidth<6?6:$maxWidth}]
    set data(okBtn) [::tk::AmpWidget button $bot.ok -text [mc "&OK"] \
	    -width $maxWidth \
	    -command [list tk::MotifFDialog_OkCmd $w]]
    set data(filterBtn) [::tk::AmpWidget button $bot.filter -text [mc "&Filter"] \
	    -width $maxWidth \
	    -command [list tk::MotifFDialog_FilterCmd $w]]
    set data(cancelBtn) [::tk::AmpWidget button $bot.cancel -text [mc "&Cancel"] \
	    -width $maxWidth \
	    -command [list tk::MotifFDialog_CancelCmd $w]]

    pack $bot.ok $bot.filter $bot.cancel -padx 10 -pady 10 -expand yes \
	-side left

    # Create the bindings:
    #
    bind $w <Alt-Key> [list ::tk::AltKeyInDialog $w %A]

    bind $data(fEnt) <Return> [list tk::MotifFDialog_ActivateFEnt $w]







|

|










|
|














|
|
















|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    pack $f1 -side top    -fill x
    pack $f3 -side bottom -fill x
    pack $f2 -expand yes -fill both

    set f2a [frame $f2.a]
    set f2b [frame $f2.b]

    grid $f2a -row 0 -column 0 -rowspan 1 -columnspan 1 -padx 3p -pady 3p \
	-sticky news
    grid $f2b -row 0 -column 1 -rowspan 1 -columnspan 1 -padx 3p -pady 3p \
	-sticky news
    grid rowconfigure $f2 0    -minsize 0   -weight 1
    grid columnconfigure $f2 0 -minsize 0   -weight 1
    grid columnconfigure $f2 1 -minsize 150 -weight 2

    # The Filter box
    #
    bind [::tk::AmpWidget label $f1.lab -text [mc "Fil&ter:"] -anchor w] \
	<<AltUnderlined>> [list focus $f1.ent]
    entry $f1.ent
    pack $f1.lab -side top -fill x -padx 4.5p -pady 3p
    pack $f1.ent -side top -fill x -padx 3p -pady 0
    set data(fEnt) $f1.ent

    # The file and directory lists
    #
    set data(dList) [MotifFDialog_MakeSList $w $f2a \
	    [mc "&Directory:"] DList]
    set data(fList) [MotifFDialog_MakeSList $w $f2b \
	    [mc "Fi&les:"]     FList]

    # The Selection box
    #
    bind [::tk::AmpWidget label $f3.lab -text [mc "&Selection:"] -anchor w] \
	<<AltUnderlined>> [list focus $f3.ent]
    entry $f3.ent
    pack $f3.lab -side top -fill x -padx 4.5p -pady 0
    pack $f3.ent -side top -fill x -padx 3p -pady 3p
    set data(sEnt) $f3.ent

    # The buttons
    #
    set maxWidth [::tk::mcmaxamp &OK &Filter &Cancel]
    set maxWidth [expr {$maxWidth<6?6:$maxWidth}]
    set data(okBtn) [::tk::AmpWidget button $bot.ok -text [mc "&OK"] \
	    -width $maxWidth \
	    -command [list tk::MotifFDialog_OkCmd $w]]
    set data(filterBtn) [::tk::AmpWidget button $bot.filter -text [mc "&Filter"] \
	    -width $maxWidth \
	    -command [list tk::MotifFDialog_FilterCmd $w]]
    set data(cancelBtn) [::tk::AmpWidget button $bot.cancel -text [mc "&Cancel"] \
	    -width $maxWidth \
	    -command [list tk::MotifFDialog_CancelCmd $w]]

    pack $bot.ok $bot.filter $bot.cancel -padx 7.5p -pady 7.5p -expand yes \
	-side left

    # Create the bindings:
    #
    bind $w <Alt-Key> [list ::tk::AltKeyInDialog $w %A]

    bind $data(fEnt) <Return> [list tk::MotifFDialog_ActivateFEnt $w]
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
    bind [::tk::AmpWidget label $f.lab -text $label -anchor w] \
	<<AltUnderlined>> [list focus $f.l]
    listbox $f.l -width 12 -height 5 -exportselection 0\
	-xscrollcommand [list $f.h set]	-yscrollcommand [list $f.v set]
    scrollbar $f.v -orient vertical   -takefocus 0 -command [list $f.l yview]
    scrollbar $f.h -orient horizontal -takefocus 0 -command [list $f.l xview]
    grid $f.lab -row 0 -column 0 -sticky news -rowspan 1 -columnspan 2 \
	-padx 2 -pady 2
    grid $f.l -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
    grid $f.v -row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news
    grid $f.h -row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news

    grid rowconfigure    $f 0 -weight 0 -minsize 0
    grid rowconfigure    $f 1 -weight 1 -minsize 0
    grid columnconfigure $f 0 -weight 1 -minsize 0







|







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
    bind [::tk::AmpWidget label $f.lab -text $label -anchor w] \
	<<AltUnderlined>> [list focus $f.l]
    listbox $f.l -width 12 -height 5 -exportselection 0\
	-xscrollcommand [list $f.h set]	-yscrollcommand [list $f.v set]
    scrollbar $f.v -orient vertical   -takefocus 0 -command [list $f.l yview]
    scrollbar $f.h -orient horizontal -takefocus 0 -command [list $f.l xview]
    grid $f.lab -row 0 -column 0 -sticky news -rowspan 1 -columnspan 2 \
	-padx 1.5p -pady 1.5p
    grid $f.l -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
    grid $f.v -row 1 -column 1 -rowspan 1 -columnspan 1 -sticky news
    grid $f.h -row 2 -column 0 -rowspan 1 -columnspan 1 -sticky news

    grid rowconfigure    $f 0 -weight 0 -minsize 0
    grid rowconfigure    $f 1 -weight 1 -minsize 0
    grid columnconfigure $f 0 -weight 1 -minsize 0
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
#	None.

proc ::tk::MotifFDialog_Update {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 \
            [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
    $data(sEnt) delete 0 end
    $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
	    $data(selectFile)]

    MotifFDialog_LoadFiles $w
}








|







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
#	None.

proc ::tk::MotifFDialog_Update {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 \
	    [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
    $data(sEnt) delete 0 end
    $data(sEnt) insert 0 [::tk::dialog::file::JoinFile $data(selectPath) \
	    $data(selectFile)]

    MotifFDialog_LoadFiles $w
}

592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
    set top 0
    set dlist ""
    set flist ""
    foreach f [glob -nocomplain .* *] {
	if {[file isdir ./$f]} {
	    lappend dlist $f
	} else {
            foreach pat $data(filter) {
                if {[string match $pat $f]} {
		    if {[string match .* $f]} {
			incr top
		    }
		    lappend flist $f
                    break
		}
            }
	}
    }
    eval [list $data(dList) insert end] [lsort -dictionary $dlist]
    eval [list $data(fList) insert end] [lsort -dictionary $flist]

    # The user probably doesn't want to see the . files. We adjust the view
    # so that the listbox displays all the non-dot files







|
|




|

|







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
    set top 0
    set dlist ""
    set flist ""
    foreach f [glob -nocomplain .* *] {
	if {[file isdir ./$f]} {
	    lappend dlist $f
	} else {
	    foreach pat $data(filter) {
		if {[string match $pat $f]} {
		    if {[string match .* $f]} {
			incr top
		    }
		    lappend flist $f
		    break
		}
	    }
	}
    }
    eval [list $data(dList) insert end] [lsort -dictionary $dlist]
    eval [list $data(fList) insert end] [lsort -dictionary $flist]

    # The user probably doesn't want to see the . files. We adjust the view
    # so that the listbox displays all the non-dot files

Added macosx/Credits.html.in.

















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!doctype htmL>
<html>
<head>
</head>
<body style="font-size:120%;font-family:Arial,sans-serif;">
<p>
Tcl and Tk are distributed under a modified BSD license:<br>
<a href="https://www.tcl-lang.org/software/tcltk/license.html">
  https://www.tcl-lang.org/software/tcltk/license.html
</a>
</p>
<ul style="list-style-type:none;">
<li>&copy; 1987-@TK_YEAR@ Tcl Core Team and Contributers.</li>
<li>&copy; 2011-@TK_YEAR@ Kevin Walzer/WordTech Communications LLC.</li>
<li>&copy; 2014-@TK_YEAR@ Marc Culler.</li>
<li>&copy; 2002-2012 Daniel A. Steffen.</li>
<li>&copy; 2001-2009 Apple Inc.</li>
<li>&copy; 2001-2002 Jim Ingham &amp; Ian Reid.</li>
<li>&copy; 1998-2000 Jim Ingham &amp; Ray Johnson.</li>
<li>&copy; 1998-2000 Scriptics Inc.</li>
<li>&copy; 1996-1997 Sun Microsystems Inc.</li>
</ul>
</body>
</html>

Changes to macosx/GNUmakefile.

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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








<
<
<
<
<
<







42
43
44
45
46
47
48






49
50
51
52
53
54
55
INSTALL_MANPAGES	?=

# set to non-empty value to build TkX11 instead of TkAqua:
TK_X11			?=

# Checks and overrides for subframework builds
ifeq (${SUBFRAMEWORK}_${TK_X11},1_)






override BUILD_DIR = ${DESTDIR}/build
override INSTALL_PATH = /Frameworks
endif

#-------------------------------------------------------------------------------------------------------
# meta targets

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
else
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-xft
VERSION			:= ${VERSION}-X11
wish			:= ${wish}-X11
override EMBEDDED_BUILD :=
endif

INSTALL_TARGETS		= install-binaries install-libraries
ifeq (${EMBEDDED_BUILD},)
INSTALL_TARGETS		+= install-private-headers install-headers install-demos
endif
ifeq (${INSTALL_BUILD}_${EMBEDDED_BUILD}_${BUILD_STYLE},1__Deployment)
INSTALL_TARGETS		+= html-tk
ifneq (${INSTALL_MANPAGES},)
INSTALL_TARGETS		+= install-doc
endif
endif







|

|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
else
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-xft
VERSION			:= ${VERSION}-X11
wish			:= ${wish}-X11
override EMBEDDED_BUILD :=
endif

INSTALL_TARGETS		= install-binaries install-libraries install-headers
ifeq (${EMBEDDED_BUILD},)
INSTALL_TARGETS		+= install-private-headers install-demos
endif
ifeq (${INSTALL_BUILD}_${EMBEDDED_BUILD}_${BUILD_STYLE},1__Deployment)
INSTALL_TARGETS		+= html-tk
ifneq (${INSTALL_MANPAGES},)
INSTALL_TARGETS		+= install-doc
endif
endif
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	${MAKE} install-${PROJECT} INSTALL_ROOT="${OBJ_DIR}/"

${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \
		     ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in
	mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \
	if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \
	--prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \
	--mandir="${MANDIR}" --enable-framework \
	--with-tcl="${TCL_DIR}" \
	${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi
ifneq (${VERSION},${TCL_VERSION})
	@cd "${OBJ_DIR}" && sed -e 's#/Versions/${TCL_VERSION}#/Versions/${VERSION}#' \
	tkConfig.sh > tkConfig.sh.1 && mv -f tkConfig.sh.1 tkConfig.sh
endif








|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	${MAKE} install-${PROJECT} INSTALL_ROOT="${OBJ_DIR}/"

${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \
		     ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in
	mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \
	if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \
	--prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \
	--mandir="${MANDIR}" --enable-framework --disable-zipfs \
	--with-tcl="${TCL_DIR}" \
	${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi
ifneq (${VERSION},${TCL_VERSION})
	@cd "${OBJ_DIR}" && sed -e 's#/Versions/${TCL_VERSION}#/Versions/${VERSION}#' \
	tkConfig.sh > tkConfig.sh.1 && mv -f tkConfig.sh.1 tkConfig.sh
endif

Changes to macosx/README.

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
other unix platform (indeed, the GNUmakefiles are just wrappers around the unix
buildsystem).
The macOS specific configure flags are --enable-aqua, --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
select based notifier). Note that --enable-aqua is incompatible with
--disable-corefoundation (for both Tcl and Tk configure).

- It was once possible to build with the Xcode IDE via the projects in
tk/macosx, but this has not been tested recently. Take care to use the
project matching your DevTools and OS version:
	Tk.xcode: 		    for Xcode 3.1 on 10.5
	Tk.xcodeproj:		    for Xcode 3.2 on 10.6
These have the following targets:
	Tk:			    calls through to tk/macosx/GNUMakefile,
				    requires a corresponding build of the Tcl
				    target of tcl/macosx/Tcl.xcode.
	tktest:			    static build of TkAqua tktest for debugging.
	tktest-X11:		    static build of TkX11 tktest for debugging.
The following build configurations are available:
	Debug:			    debug build for the active architecture,
				    with Fix & Continue enabled.
	Debug clang:		    use clang compiler.
	Debug llvm-gcc:		    use llvm-gcc compiler.
	Debug gcc40:		    use gcc 4.0 compiler.
	DebugNoGC:		    disable Objective-C garbage collection.
	DebugNoFixAndContinue:      disable Fix & Continue.
	DebugUnthreaded:	    disable threading.
	DebugNoCF:		    disable corefoundation (X11 only).
	DebugNoCFUnthreaded:	    disable corefoundation an threading.
	DebugMemCompile:	    enable memory and bytecode debugging.
	DebugLeaks:		    define PURIFY.
	DebugGCov:		    enable generation of gcov data files.
	Debug64bit:		    configure with --enable-64bit (requires
				    building on a 64bit capable processor).
	Release:		    release build for the active architecture.
	ReleaseUniversal:	    32/64-bit universal build.
	ReleaseUniversal clang:	    use clang compiler.
	ReleaseUniversal llvm-gcc:  use llvm-gcc compiler.
	ReleaseUniversal gcc40:	    use gcc 4.0 compiler.
	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
				    deployment target).
	Note that the non-SDK configurations have their deployment target set to
	10.5 (Tk.xcode) resp. 10.6 (Tk.xcodeproj).
The Xcode projects refer to the toplevel tcl and tk source directories via the
the TCL_SRCROOT and TK_SRCROOT user build settings, by default these are set to
the project-relative paths '../../tcl' and '../../tk', if your source
directories are named differently, e.g. '../../tcl8.6' and '../../tk8.6', you
need to manually change the TCL_SRCROOT and TK_SRCROOT settings by editing your
${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a
text editor.

- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
to the minimal OS version the binaries should be able to run on, e.g:
	export MACOSX_DEPLOYMENT_TARGET=10.6







|


<















<

<



<
<








|



|







323
324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348

349
350
351


352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
other unix platform (indeed, the GNUmakefiles are just wrappers around the unix
buildsystem).
The macOS specific configure flags are --enable-aqua, --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
select based notifier). Note that --enable-aqua is incompatible with
--disable-corefoundation (for both Tcl and Tk configure).

- It was once possible to build with the Xcode IDE via the project in
tk/macosx, but this has not been tested recently. Take care to use the
project matching your DevTools and OS version:

	Tk.xcodeproj:		    for Xcode 3.2 on 10.6
These have the following targets:
	Tk:			    calls through to tk/macosx/GNUMakefile,
				    requires a corresponding build of the Tcl
				    target of tcl/macosx/Tcl.xcode.
	tktest:			    static build of TkAqua tktest for debugging.
	tktest-X11:		    static build of TkX11 tktest for debugging.
The following build configurations are available:
	Debug:			    debug build for the active architecture,
				    with Fix & Continue enabled.
	Debug clang:		    use clang compiler.
	Debug llvm-gcc:		    use llvm-gcc compiler.
	Debug gcc40:		    use gcc 4.0 compiler.
	DebugNoGC:		    disable Objective-C garbage collection.
	DebugNoFixAndContinue:      disable Fix & Continue.

	DebugNoCF:		    disable corefoundation (X11 only).

	DebugMemCompile:	    enable memory and bytecode debugging.
	DebugLeaks:		    define PURIFY.
	DebugGCov:		    enable generation of gcov data files.


	Release:		    release build for the active architecture.
	ReleaseUniversal:	    32/64-bit universal build.
	ReleaseUniversal clang:	    use clang compiler.
	ReleaseUniversal llvm-gcc:  use llvm-gcc compiler.
	ReleaseUniversal gcc40:	    use gcc 4.0 compiler.
	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
				    deployment target).
	Note that the non-SDK configurations have their deployment target set to
	10.6 (Tk.xcodeproj).
The Xcode projects refer to the toplevel tcl and tk source directories via the
the TCL_SRCROOT and TK_SRCROOT user build settings, by default these are set to
the project-relative paths '../../tcl' and '../../tk', if your source
directories are named differently, e.g. '../../tcl8.7' and '../../tk8.7', you
need to manually change the TCL_SRCROOT and TK_SRCROOT settings by editing your
${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a
text editor.

- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
to the minimal OS version the binaries should be able to run on, e.g:
	export MACOSX_DEPLOYMENT_TARGET=10.6
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
[ create the following symbolic link for the build to work as setup by default ]
[      ln -fs /path_to_tcl/build /path_to_tk/build			       ]
[ (where /path_to_{tcl,tk} is the directory containing the tcl resp. tk tree)  ]
[ or you can pass an argument of BUILD_DIR=/somewhere to the tcl and tk make.  ]

- The following instructions assume the Tcl and Tk source trees are named
"tcl${ver}" and "tk${ver}" (where ${ver} is a shell variable containing the
Tcl/Tk version number, e.g. '8.6').
Setup this shell variable as follows:
	ver="8.6"
If you are building from CVS, omit this step (CVS source tree names usually do
not contain a version number).

- Setup environment variables as desired, e.g. for a universal build on 10.5:
	CFLAGS="-arch i386 -arch x86_64 -arch ppc -mmacosx-version-min=10.5"
	export CFLAGS

- Change to the directory containing the Tcl and Tk source trees and build:
	make -C tcl${ver}/macosx
	make -C tk${ver}/macosx

- Install Tcl and Tk onto the root volume (admin password required):







|

|
<
<


|







382
383
384
385
386
387
388
389
390
391


392
393
394
395
396
397
398
399
400
401
[ create the following symbolic link for the build to work as setup by default ]
[      ln -fs /path_to_tcl/build /path_to_tk/build			       ]
[ (where /path_to_{tcl,tk} is the directory containing the tcl resp. tk tree)  ]
[ or you can pass an argument of BUILD_DIR=/somewhere to the tcl and tk make.  ]

- The following instructions assume the Tcl and Tk source trees are named
"tcl${ver}" and "tk${ver}" (where ${ver} is a shell variable containing the
Tcl/Tk version number, e.g. '8.7').
Setup this shell variable as follows:
	ver="8.7"



- Setup environment variables as desired, e.g. for a universal build on 10.5:
	CFLAGS="-arch x86_64 -arch arm64 -mmacosx-version-min=10.5"
	export CFLAGS

- Change to the directory containing the Tcl and Tk source trees and build:
	make -C tcl${ver}/macosx
	make -C tk${ver}/macosx

- Install Tcl and Tk onto the root volume (admin password required):
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
- 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.







|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
- 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.7/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.
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
starting the event loop.

Since the CheckProc function gets called for every Tk event, it is an
appropriate place to drain the main NSAutoreleasePool and replace it
with a new pool.  This is done by calling the method [NSApp
_resetAutoreleasePool], where _resetAutoreleasePool is a method which
we define for the subclass.  Unfortunately, by itself this is not
sufficient for safe memory managememt because, as was made painfully
evident with the release of OS X 10.13, it is possible for calls to
TclDoOneEvent, and hence to CheckProc, to be nested.  Draining the
autorelease pool in a nested call leads to crashes as objects in use
by the outer call can get freed by the inner call and then reused later.
One particular situation where this happens is when a modal dialogue
gets posted by a Tk Application.  To address this, the NSApp object
also implements a semaphore to prevent draining the autorelease pool







|







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
starting the event loop.

Since the CheckProc function gets called for every Tk event, it is an
appropriate place to drain the main NSAutoreleasePool and replace it
with a new pool.  This is done by calling the method [NSApp
_resetAutoreleasePool], where _resetAutoreleasePool is a method which
we define for the subclass.  Unfortunately, by itself this is not
sufficient for safe memory management because, as was made painfully
evident with the release of OS X 10.13, it is possible for calls to
TclDoOneEvent, and hence to CheckProc, to be nested.  Draining the
autorelease pool in a nested call leads to crashes as objects in use
by the outer call can get freed by the inner call and then reused later.
One particular situation where this happens is when a modal dialogue
gets posted by a Tk Application.  To address this, the NSApp object
also implements a semaphore to prevent draining the autorelease pool
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
occurred when scrolling a Text widget which contained embedded
subwindows.  It involved some specific differences between the
low-level behavior of Apple's window manager versus those of the other
platforms, and the fix ultimately required changes in the generic Tk
implementation (documented in the comments in the DisplayText
function).

The Text widget attempts to improve perfomance when scrolling by
minimizing the number of text lines which need to be redisplayed.  It
does this by calling the platform-specific TkScrollWindow function
which uses a low-level routine to map one rectangle of the window to
another.  The TkScrollWindow function returns a damage region which is
then used by the Text widget's DisplayText function to determine which
text lines need to be redrawn.  On the unix and win platforms, this
damage region includes bounding rectangles for all embedded windows
inside the Text widget.  The way that this works is system dependent.
On unix, the low level scrolling is done by XCopyRegion, which
generates a GraphicsExpose event for each embedded window.  These
GraphicsExposed events are processsed within TkScrollWindow, using a
special handler which adds the bounding rectangle of each subwindow to
the damage region.  On the win platform the damage region is built by
the low level function ScrollWindowEx, and it also includes bounding
rectangles for all embedded windows.  This is possible because on X11
and Windows every Tk widget is also known to the window manager as a







|








|







634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
occurred when scrolling a Text widget which contained embedded
subwindows.  It involved some specific differences between the
low-level behavior of Apple's window manager versus those of the other
platforms, and the fix ultimately required changes in the generic Tk
implementation (documented in the comments in the DisplayText
function).

The Text widget attempts to improve performance when scrolling by
minimizing the number of text lines which need to be redisplayed.  It
does this by calling the platform-specific TkScrollWindow function
which uses a low-level routine to map one rectangle of the window to
another.  The TkScrollWindow function returns a damage region which is
then used by the Text widget's DisplayText function to determine which
text lines need to be redrawn.  On the unix and win platforms, this
damage region includes bounding rectangles for all embedded windows
inside the Text widget.  The way that this works is system dependent.
On unix, the low level scrolling is done by XCopyArea, which
generates a GraphicsExpose event for each embedded window.  These
GraphicsExposed events are processsed within TkScrollWindow, using a
special handler which adds the bounding rectangle of each subwindow to
the damage region.  On the win platform the damage region is built by
the low level function ScrollWindowEx, and it also includes bounding
rectangles for all embedded windows.  This is possible because on X11
and Windows every Tk widget is also known to the window manager as a
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
conditional code which is only used for macOS.

6.0 Virtual events on macOS 10.14 and later
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 10.14 release added support for system appearance changes,
including a "Dark Mode" that renders all window frames and menus in
dark colors. Tk 8.6.11 provides three virtual events <<LightAqua>>,
<<DarkAqua>> and <<AppearanceChanged>>, to allow you to update your Tk
app's appearance when the system appearance changes.  These events are
generated in [NSView effectiveAppearanceChanged], which is called by
the Apple window manager when the General Preferences is changed
either by switching between Light Mode and Dark Mode or by changing
the Accent Color or Highlight Color.








|







674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
conditional code which is only used for macOS.

6.0 Virtual events on macOS 10.14 and later
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 10.14 release added support for system appearance changes,
including a "Dark Mode" that renders all window frames and menus in
dark colors. Tk 8.7 provides three virtual events <<LightAqua>>,
<<DarkAqua>> and <<AppearanceChanged>>, to allow you to update your Tk
app's appearance when the system appearance changes.  These events are
generated in [NSView effectiveAppearanceChanged], which is called by
the Apple window manager when the General Preferences is changed
either by switching between Light Mode and Dark Mode or by changing
the Accent Color or Highlight Color.

Changes to macosx/Tk-Common.xcconfig.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
BINDIR = $(PREFIX)/bin
CFLAGS = $(CFLAGS)
CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
FRAMEWORK_INSTALL_PATH = /Library/Frameworks
INCLUDEDIR = $(PREFIX)/include
LIBDIR = $(PREFIX)/lib
MANDIR = $(PREFIX)/man
PER_ARCH_CFLAGS_ppc = -mcpu=G3 -mtune=G4 $(PER_ARCH_CFLAGS_ppc)
PREFIX = /usr/local
TCL_BUILD_DIR = $(OBJROOT)/../tcl/Tcl.build/$(CONFIGURATION)/Tcl.build/Objects
TCL_CONFIGURE_ARGS = --enable-dtrace
TCL_FRAMEWORK_DIR = $(SYMROOT)/../tcl/$(CONFIGURATION)
TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
TCL_PACKAGE_PATH = "$(LIBDIR)"
TCL_DEFS = HAVE_TCL_CONFIG_H
TK_LIBRARY = $(LIBDIR)/tk$(VERSION)
TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED
VERSION = 8.7







<








|

29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
BINDIR = $(PREFIX)/bin
CFLAGS = $(CFLAGS)
CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
FRAMEWORK_INSTALL_PATH = /Library/Frameworks
INCLUDEDIR = $(PREFIX)/include
LIBDIR = $(PREFIX)/lib
MANDIR = $(PREFIX)/man

PREFIX = /usr/local
TCL_BUILD_DIR = $(OBJROOT)/../tcl/Tcl.build/$(CONFIGURATION)/Tcl.build/Objects
TCL_CONFIGURE_ARGS = --enable-dtrace
TCL_FRAMEWORK_DIR = $(SYMROOT)/../tcl/$(CONFIGURATION)
TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
TCL_PACKAGE_PATH = "$(LIBDIR)"
TCL_DEFS = HAVE_TCL_CONFIG_H
TK_LIBRARY = $(LIBDIR)/tk$(VERSION)
TK_DEFS = HAVE_TK_CONFIG_H
VERSION = 8.7

Changes to macosx/Tk-Release.xcconfig.

9
10
11
12
13
14
15
16
17
18
19
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#include "Tk-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
// DEPLOYMENT_POSTPROCESSING = YES
GCC_OPTIMIZATION_LEVEL = s
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = deploy







|



9
10
11
12
13
14
15
16
17
18
19
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#include "Tk-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
// DEPLOYMENT_POSTPROCESSING = YES
GCC_OPTIMIZATION_LEVEL = 2
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = deploy

Deleted macosx/Tk.xcode/default.pbxuser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
// !$*UTF8*$!
{
	08FB7793FE84155DC02AAC07 /* Project object */ = {
		activeBuildConfigurationName = Debug;
		activeExecutable = F9E61D1C090A4282002B3151 /* Wish */;
		activeTarget = F9E61D16090A3E94002B3151 /* Tk */;
		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
			F944EB8F08F798100049FDD4 /* tktest */,
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
		perUserDictionary = {
			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f75708692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a0b707265666572656e63657386928497960892849a9a07666e6d617463688692849a9a008692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a0572656765788692849a9a065c2e286329248692849a9a097265637572736976658692848484084e534e756d626572008484074e5356616c7565009584012a849696018692849a9a0669734c656166869284b09db296008692849a9a0763616e536176658692af92849a9a1250425850726f6a65637453636f70654b65798692849a9a03594553868692849a9a08676c6f62616c49448692849a9a18314343304541343030343335304546393030343434313042868686>;
		};
		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
		userBuildSettings = {
			SYMROOT = "${SRCROOT}/../../build/tk";
			TCL_SRCROOT = "${SRCROOT}/../../tcl";
			TK_SRCROOT = "${SRCROOT}/../../tk";
		};
	};
	8DD76FA90486AB0100D96B5E /* tktest */ = {
		activeExec = 0;
		executables = (
			F944EB8F08F798100049FDD4 /* tktest */,
		);
	};
	F944EB8F08F798100049FDD4 /* tktest */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = TK_SRCROOT;
				value = "${TK_SRCROOT}";
			},
			{
				active = NO;
				name = TK_CONSOLE;
				value = 1;
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = NSTraceEvents;
				value = YES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
			{
				active = NO;
				name = NSZombieEnabled;
				value = YES;
			},
			{
				active = NO;
				name = NSDeallocateZombies;
				value = YES;
			},
			{
				active = NO;
				name = NSAutoreleaseFreedObjectCheckEnabled;
				value = YES;
			},
			{
				active = NO;
				name = NSEnableAutoreleasePool;
				value = NO;
			},
			{
				active = NO;
				name = AUTO_LOG_ALL;
				value = YES;
			},
			{
				active = NO;
				name = AUTO_LOG_NOISY;
				value = YES;
			},
			{
				active = NO;
				name = AUTO_REFERENCE_COUNT_LOGGING;
				value = YES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tktest;
		sourceDirectories = (
		);
	};
	F944EB9C08F798180049FDD4 /* Source Control */ = {
		isa = PBXSourceControlManager;
		fallbackIsa = XCSourceControlManager;
		isSCMEnabled = 0;
		scmConfiguration = {
			CVSToolPath = /usr/bin/cvs;
			CVSUseSSH = NO;
			SubversionToolPath = /usr/bin/svn;
			repositoryNamesForRoots = {
				.. = "";
			};
		};
		scmType = scm.cvs;
	};
	F944EB9D08F798180049FDD4 /* Code sense */ = {
		isa = PBXCodeSenseManager;
		indexTemplatePath = "";
	};
	F97258A50A86873C00096C78 /* tktest-X11 */ = {
		activeExec = 0;
		executables = (
			F9FD31F50CC1AD070073837D /* tktest-X11 */,
		);
	};
	F9E61D16090A3E94002B3151 /* Tk */ = {
		activeExec = 0;
		executables = (
			F9E61D1C090A4282002B3151 /* Wish */,
		);
	};
	F9E61D1C090A4282002B3151 /* Wish */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = Wish;
		sourceDirectories = (
		);
	};
	F9FD31F50CC1AD070073837D /* tktest-X11 */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			YES,
			NO,
			NO,
			NO,
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TK_SRCROOT}/library/demos/widget",
			"${TK_SRCROOT}/tests/all.tcl",
			"${TK_SRCROOT}/tests/ttk/all.tcl",
			"-geometry +0+0",
			"-singleproc 1",
			"-verbose \"bet\"",
			"-skip window-2.9",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TK_LIBRARY;
				value = "${TK_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = YES;
				name = DISPLAY;
				value = ":0";
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = "tktest-X11";
		sourceDirectories = (
		);
	};
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































Deleted macosx/Tk.xcode/project.pbxproj.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 45;
	objects = {

/* Begin PBXBuildFile section */
		F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
		F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F94523A10E6FC2AC00C1D987 /* Cocoa.framework */; };
		F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437CB0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437E70EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F96437E80EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F966BDD308F27A3F005CB29B /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F966BDD508F27A3F005CB29B /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F966BDE508F27A3F005CB29B /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F966BDED08F27A3F005CB29B /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F966BDF208F27A3F005CB29B /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F966BDF508F27A3F005CB29B /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F966BDF708F27A3F005CB29B /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F966BE0908F27A3F005CB29B /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F966BE1008F27A3F005CB29B /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F966BE1208F27A3F005CB29B /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F966BE1308F27A3F005CB29B /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF408F27A39005CB29B /* tkPointer.c */; };
		F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F966BE2008F27A40005CB29B /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F966BE2408F27A40005CB29B /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F966BE2508F27A40005CB29B /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F966BE2608F27A40005CB29B /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F966BE3008F27A40005CB29B /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F966BE3108F27A40005CB29B /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F966BE3308F27A40005CB29B /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F966BE3408F27A40005CB29B /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F966BE3508F27A40005CB29B /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */; };
		F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */; };
		F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */; };
		F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */; };
		F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */; };
		F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */; };
		F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */; };
		F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */; };
		F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */; };
		F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */; };
		F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */; };
		F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */; };
		F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */; };
		F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */; };
		F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */; settings = {COMPILER_FLAGS = "-DTK_LIBRARY=\\\"$(TK_LIBRARY)\\\""; }; };
		F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */; };
		F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */; };
		F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */; };
		F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */; };
		F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */; };
		F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */; };
		F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */; };
		F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */; };
		F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */; };
		F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */; };
		F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */; };
		F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */; };
		F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */; };
		F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */; };
		F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */; };
		F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F966C02A08F27A42005CB29B /* xcolors.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2408F27A3F005CB29B /* xcolors.c */; };
		F966C02B08F27A42005CB29B /* xdraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2508F27A3F005CB29B /* xdraw.c */; };
		F966C02C08F27A42005CB29B /* xgc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2608F27A3F005CB29B /* xgc.c */; };
		F966C02D08F27A42005CB29B /* ximage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2708F27A3F005CB29B /* ximage.c */; };
		F966C02E08F27A42005CB29B /* xutil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BD2808F27A3F005CB29B /* xutil.c */; };
		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07608F2821B005CB29B /* Carbon.framework */; };
		F966C07908F28233005CB29B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07808F28233005CB29B /* IOKit.framework */; };
		F96888050AF786D5000797B5 /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F96888060AF786D5000797B5 /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F96888070AF786D5000797B5 /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F968880B0AF786D5000797B5 /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F968880E0AF786D5000797B5 /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F968880F0AF786D5000797B5 /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F96888100AF786D5000797B5 /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F96888110AF786D5000797B5 /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F96888120AF786D5000797B5 /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F96888150AF786D5000797B5 /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F96888160AF786D5000797B5 /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F96888170AF786D5000797B5 /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F968881B0AF786D5000797B5 /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F96888200AF786D5000797B5 /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F96888210AF786D5000797B5 /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F96888230AF786D5000797B5 /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888840AF78938000797B5 /* ttkMacOSXTheme.c */; };
		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */; };
		F9DD99BD0F07DF850018B2E4 /* tkImgPNG.c in Sources */ = {isa = PBXBuildFile; fileRef = F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */; };
		F9DD99BE0F07DF850018B2E4 /* tkImgPNG.c in Sources */ = {isa = PBXBuildFile; fileRef = F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */; };
		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F9FD30BD0CC1AD070073837D /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F9FD30BE0CC1AD070073837D /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F9FD30BF0CC1AD070073837D /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F9FD30C50CC1AD070073837D /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F9FD30D50CC1AD070073837D /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F9FD30D60CC1AD070073837D /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F9FD30E00CC1AD070073837D /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F9FD30E40CC1AD070073837D /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F9FD30E70CC1AD070073837D /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F9FD30E90CC1AD070073837D /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F9FD30F00CC1AD070073837D /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F9FD30F30CC1AD070073837D /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F9FD30F40CC1AD070073837D /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F9FD30F90CC1AD070073837D /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F9FD31000CC1AD070073837D /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F9FD31010CC1AD070073837D /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F9FD31020CC1AD070073837D /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
		F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
		F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
		F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
		F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
		F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
		F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
		F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F9FD313F0CC1AD070073837D /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
		F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
		F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9FD314F0CC1AD070073837D /* tk3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAC08F27A39005CB29B /* tk3d.c */; };
		F9FD31500CC1AD070073837D /* tkArgv.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAE08F27A39005CB29B /* tkArgv.c */; };
		F9FD31510CC1AD070073837D /* tkAtom.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAAF08F27A39005CB29B /* tkAtom.c */; };
		F9FD31520CC1AD070073837D /* tkBind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB008F27A39005CB29B /* tkBind.c */; };
		F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB108F27A39005CB29B /* tkBitmap.c */; };
		F9FD31540CC1AD070073837D /* tkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB208F27A39005CB29B /* tkButton.c */; };
		F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB408F27A39005CB29B /* tkCanvArc.c */; };
		F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB508F27A39005CB29B /* tkCanvas.c */; };
		F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB708F27A39005CB29B /* tkCanvBmap.c */; };
		F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB808F27A39005CB29B /* tkCanvImg.c */; };
		F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAB908F27A39005CB29B /* tkCanvLine.c */; };
		F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABA08F27A39005CB29B /* tkCanvPoly.c */; };
		F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABB08F27A39005CB29B /* tkCanvPs.c */; };
		F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABD08F27A39005CB29B /* tkCanvText.c */; };
		F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABE08F27A39005CB29B /* tkCanvUtil.c */; };
		F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BABF08F27A39005CB29B /* tkCanvWind.c */; };
		F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC008F27A39005CB29B /* tkClipboard.c */; };
		F9FD31600CC1AD070073837D /* tkCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC108F27A39005CB29B /* tkCmds.c */; };
		F9FD31610CC1AD070073837D /* tkColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC208F27A39005CB29B /* tkColor.c */; };
		F9FD31620CC1AD070073837D /* tkConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC408F27A39005CB29B /* tkConfig.c */; };
		F9FD31630CC1AD070073837D /* tkConsole.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC508F27A39005CB29B /* tkConsole.c */; };
		F9FD31640CC1AD070073837D /* tkCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC608F27A39005CB29B /* tkCursor.c */; };
		F9FD31650CC1AD070073837D /* tkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAC808F27A39005CB29B /* tkEntry.c */; };
		F9FD31660CC1AD070073837D /* tkError.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACA08F27A39005CB29B /* tkError.c */; };
		F9FD31670CC1AD070073837D /* tkEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACB08F27A39005CB29B /* tkEvent.c */; };
		F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACC08F27A39005CB29B /* tkFileFilter.c */; };
		F9FD31690CC1AD070073837D /* tkFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACE08F27A39005CB29B /* tkFocus.c */; };
		F9FD316A0CC1AD070073837D /* tkFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BACF08F27A39005CB29B /* tkFont.c */; };
		F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD108F27A39005CB29B /* tkFrame.c */; };
		F9FD316C0CC1AD070073837D /* tkGC.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD208F27A39005CB29B /* tkGC.c */; };
		F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD308F27A39005CB29B /* tkGeometry.c */; };
		F9FD316E0CC1AD070073837D /* tkGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD408F27A39005CB29B /* tkGet.c */; };
		F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD508F27A39005CB29B /* tkGrab.c */; };
		F9FD31700CC1AD070073837D /* tkGrid.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD608F27A39005CB29B /* tkGrid.c */; };
		F9FD31710CC1AD070073837D /* tkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD708F27A39005CB29B /* tkImage.c */; };
		F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD808F27A39005CB29B /* tkImgBmap.c */; };
		F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAD908F27A39005CB29B /* tkImgGIF.c */; };
		F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADA08F27A39005CB29B /* tkImgPhoto.c */; };
		F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BADB08F27A39005CB29B /* tkImgPPM.c */; };
		F9FD31760CC1AD070073837D /* tkListbox.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE408F27A39005CB29B /* tkListbox.c */; };
		F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE508F27A39005CB29B /* tkMacWinMenu.c */; };
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
		F9FD31880CC1AD070073837D /* tkSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFB08F27A39005CB29B /* tkSelect.c */; };
		F9FD31890CC1AD070073837D /* tkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFD08F27A39005CB29B /* tkSquare.c */; };
		F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFF08F27A39005CB29B /* tkStubInit.c */; };
		F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0008F27A39005CB29B /* tkStubLib.c */; };
		F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0108F27A39005CB29B /* tkStyle.c */; };
		F9FD318D0CC1AD070073837D /* tkTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0208F27A39005CB29B /* tkTest.c */; };
		F9FD318E0CC1AD070073837D /* tkText.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0308F27A39005CB29B /* tkText.c */; };
		F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0508F27A39005CB29B /* tkTextBTree.c */; };
		F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0608F27A39005CB29B /* tkTextDisp.c */; };
		F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0808F27A39005CB29B /* tkTextImage.c */; };
		F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0908F27A39005CB29B /* tkTextIndex.c */; };
		F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0A08F27A39005CB29B /* tkTextMark.c */; };
		F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0B08F27A39005CB29B /* tkTextTag.c */; };
		F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0C08F27A39005CB29B /* tkTextWind.c */; };
		F9FD31960CC1AD070073837D /* tkTrig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0D08F27A39005CB29B /* tkTrig.c */; };
		F9FD31970CC1AD070073837D /* tkUndo.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB0E08F27A39005CB29B /* tkUndo.c */; };
		F9FD31980CC1AD070073837D /* tkUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1008F27A39005CB29B /* tkUtil.c */; };
		F9FD31990CC1AD070073837D /* tkVisual.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1108F27A39005CB29B /* tkVisual.c */; };
		F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BB1208F27A39005CB29B /* tkWindow.c */; };
		F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E10AF786D5000797B5 /* ttkBlink.c */; };
		F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E20AF786D5000797B5 /* ttkButton.c */; };
		F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E30AF786D5000797B5 /* ttkCache.c */; };
		F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E40AF786D5000797B5 /* ttkClamTheme.c */; };
		F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E50AF786D5000797B5 /* ttkClassicTheme.c */; };
		F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */; };
		F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E80AF786D5000797B5 /* ttkElements.c */; };
		F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887E90AF786D5000797B5 /* ttkEntry.c */; };
		F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EA0AF786D5000797B5 /* ttkFrame.c */; };
		F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EB0AF786D5000797B5 /* ttkImage.c */; };
		F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EC0AF786D5000797B5 /* ttkInit.c */; };
		F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887ED0AF786D5000797B5 /* ttkLabel.c */; };
		F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EE0AF786D5000797B5 /* ttkLayout.c */; };
		F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887EF0AF786D5000797B5 /* ttkManager.c */; };
		F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F10AF786D5000797B5 /* ttkNotebook.c */; };
		F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F20AF786D5000797B5 /* ttkPanedwindow.c */; };
		F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F30AF786D5000797B5 /* ttkProgress.c */; };
		F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F40AF786D5000797B5 /* ttkScale.c */; };
		F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F50AF786D5000797B5 /* ttkScroll.c */; };
		F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F60AF786D5000797B5 /* ttkScrollbar.c */; };
		F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F70AF786D5000797B5 /* ttkSeparator.c */; };
		F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F80AF786D5000797B5 /* ttkSquare.c */; };
		F9FD31B10CC1AD070073837D /* ttkState.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887F90AF786D5000797B5 /* ttkState.c */; };
		F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FA0AF786D5000797B5 /* ttkStubInit.c */; };
		F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FB0AF786D5000797B5 /* ttkStubLib.c */; };
		F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FC0AF786D5000797B5 /* ttkTagSet.c */; };
		F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */ = {isa = PBXBuildFile; fileRef = F96887FD0AF786D5000797B5 /* ttkTheme.c */; };
		F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888000AF786D5000797B5 /* ttkTrace.c */; };
		F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888010AF786D5000797B5 /* ttkTrack.c */; };
		F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888020AF786D5000797B5 /* ttkTreeview.c */; };
		F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */ = {isa = PBXBuildFile; fileRef = F96888030AF786D5000797B5 /* ttkWidget.c */; };
		F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7508F27A3D005CB29B /* tkAppInit.c */; settings = {COMPILER_FLAGS = "-DTK_TEST"; }; };
		F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7908F27A3D005CB29B /* tkUnix3d.c */; };
		F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8C08F27A3D005CB29B /* tkUnixScale.c */; };
		F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */; };
		F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8708F27A3D005CB29B /* tkUnixKey.c */; };
		F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9108F27A3D005CB29B /* tkUnixXId.c */; };
		F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8508F27A3D005CB29B /* tkUnixInit.c */; };
		F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */; };
		F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8F08F27A3D005CB29B /* tkUnixSend.c */; };
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };
		F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */; };
		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };
		F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32150CC1AF170073837D /* libXext.dylib */; };
		F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32160CC1AF170073837D /* libXss.dylib */; };
		F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34990CC1BB0D0073837D /* libfreetype.dylib */; };
		F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD349A0CC1BB0D0073837D /* libXft.dylib */; };
		F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */; };
		F9FFAF1D0DFDDB26007F8A6A /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F9FFAF1F0DFDDB2F007F8A6A /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F9FFAF200DFDDB32007F8A6A /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F9FFAF210DFDDB32007F8A6A /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F9FFAF220DFDDB34007F8A6A /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F9FFAF230DFDDB35007F8A6A /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F9FFAF240DFDDB36007F8A6A /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F9FFAF250DFDDB37007F8A6A /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F9FFAF260DFDDB38007F8A6A /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		8DD76FB20486AB0100D96B5E /* tktest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tktest; sourceTree = BUILT_PRODUCTS_DIR; };
		F9099B8A0CC67D30005A9580 /* textpeer.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textpeer.tcl; sourceTree = "<group>"; };
		F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkbut.tcl; sourceTree = "<group>"; };
		F9152B080EAF8A5000CD5C7B /* tkBusy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBusy.c; sourceTree = "<group>"; };
		F91543270EF201A90032D1E8 /* fontchoose.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchoose.tcl; sourceTree = "<group>"; };
		F915432A0EF201CF0032D1E8 /* zlib.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = zlib.test; sourceTree = "<group>"; };
		F915432D0EF201EE0032D1E8 /* zlib.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = zlib.n; sourceTree = "<group>"; };
		F9183E640EFC80CD0030B814 /* throw.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = throw.n; sourceTree = "<group>"; };
		F9183E650EFC80D70030B814 /* try.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = try.n; sourceTree = "<group>"; };
		F9183E6A0EFC81560030B814 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F9183E8F0EFC817B0030B814 /* tdbc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tdbc; sourceTree = "<group>"; };
		F91DC23C0E44C51B002CB8D1 /* nre.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = nre.test; sourceTree = "<group>"; };
		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
		F92240290D7C620F005EC715 /* knightstour.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = knightstour.tcl; sourceTree = "<group>"; };
		F92D7F100DE777240033A13A /* tsdPerf.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tsdPerf.tcl; sourceTree = "<group>"; };
		F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhInstance.c; sourceTree = "<group>"; };
		F93599B20DF1F75400E04F67 /* tclOO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOO.c; sourceTree = "<group>"; };
		F93599B40DF1F75900E04F67 /* tclOO.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclOO.decls; sourceTree = "<group>"; };
		F93599B50DF1F75D00E04F67 /* tclOO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOO.h; sourceTree = "<group>"; };
		F93599B60DF1F76100E04F67 /* tclOOBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOBasic.c; sourceTree = "<group>"; };
		F93599B80DF1F76600E04F67 /* tclOOCall.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOCall.c; sourceTree = "<group>"; };
		F93599BA0DF1F76A00E04F67 /* tclOODecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOODecls.h; sourceTree = "<group>"; };
		F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOODefineCmds.c; sourceTree = "<group>"; };
		F93599BD0DF1F77400E04F67 /* tclOOInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOInfo.c; sourceTree = "<group>"; };
		F93599BF0DF1F77900E04F67 /* tclOOInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOInt.h; sourceTree = "<group>"; };
		F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOIntDecls.h; sourceTree = "<group>"; };
		F93599C10DF1F78300E04F67 /* tclOOMethod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOMethod.c; sourceTree = "<group>"; };
		F93599C30DF1F78800E04F67 /* tclOOStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubInit.c; sourceTree = "<group>"; };
		F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubLib.c; sourceTree = "<group>"; };
		F93599C80DF1F81900E04F67 /* oo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oo.test; sourceTree = "<group>"; };
		F93599CF0DF1F87F00E04F67 /* Class.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Class.3; sourceTree = "<group>"; };
		F93599D00DF1F89E00E04F67 /* class.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = class.n; sourceTree = "<group>"; };
		F93599D20DF1F8DF00E04F67 /* copy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = copy.n; sourceTree = "<group>"; };
		F93599D30DF1F8F500E04F67 /* define.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = define.n; sourceTree = "<group>"; };
		F93599D40DF1F91900E04F67 /* Method.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Method.3; sourceTree = "<group>"; };
		F93599D50DF1F93700E04F67 /* my.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = my.n; sourceTree = "<group>"; };
		F93599D60DF1F95000E04F67 /* next.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = next.n; sourceTree = "<group>"; };
		F93599D70DF1F96800E04F67 /* object.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = object.n; sourceTree = "<group>"; };
		F93599D80DF1F98300E04F67 /* self.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = self.n; sourceTree = "<group>"; };
		F936FCD70CCD984500716967 /* ttkprogress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttkprogress.tcl; sourceTree = "<group>"; };
		F936FCD80CCD984600716967 /* tree.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tree.tcl; sourceTree = "<group>"; };
		F936FCD90CCD984600716967 /* toolbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = toolbar.tcl; sourceTree = "<group>"; };
		F936FCDA0CCD984600716967 /* ttknote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttknote.tcl; sourceTree = "<group>"; };
		F936FCDB0CCD984600716967 /* combo.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combo.tcl; sourceTree = "<group>"; };
		F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXFont.h; sourceTree = "<group>"; };
		F94523A10E6FC2AC00C1D987 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
		F946FB8B0FBE3AED00CD6495 /* itcl */ = {isa = PBXFileReference; lastKnownFileType = folder; path = itcl; sourceTree = "<group>"; };
		F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORTrans.c; sourceTree = "<group>"; };
		F95D8D4B0F1715610006B020 /* Tk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Tk.icns; sourceTree = "<group>"; };
		F95D8D4C0F1715610006B020 /* Tk.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Tk.tiff; sourceTree = "<group>"; };
		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
		F962F7C60DADC26200648DB8 /* vsapi.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vsapi.test; sourceTree = "<group>"; };
		F96437C90EF0D4B2003F468E /* tclZlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclZlib.c; sourceTree = "<group>"; };
		F96437E60EF0D652003F468E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
		F966BA0408F27A37005CB29B /* error.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = error.xbm; sourceTree = "<group>"; };
		F966BA0508F27A37005CB29B /* gray12.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray12.xbm; sourceTree = "<group>"; };
		F966BA0608F27A37005CB29B /* gray25.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray25.xbm; sourceTree = "<group>"; };
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };
		F966BA0E08F27A37005CB29B /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F966BA0F08F27A37005CB29B /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };
		F966BA1808F27A37005CB29B /* button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = button.n; sourceTree = "<group>"; };
		F966BA1908F27A37005CB29B /* canvas.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = canvas.n; sourceTree = "<group>"; };
		F966BA1A08F27A37005CB29B /* CanvPsY.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvPsY.3; sourceTree = "<group>"; };
		F966BA1B08F27A37005CB29B /* CanvTkwin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTkwin.3; sourceTree = "<group>"; };
		F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CanvTxtInfo.3; sourceTree = "<group>"; };
		F966BA1D08F27A37005CB29B /* checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = checkbutton.n; sourceTree = "<group>"; };
		F966BA1E08F27A37005CB29B /* chooseColor.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseColor.n; sourceTree = "<group>"; };
		F966BA1F08F27A37005CB29B /* chooseDirectory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chooseDirectory.n; sourceTree = "<group>"; };
		F966BA2008F27A37005CB29B /* Clipboard.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Clipboard.3; sourceTree = "<group>"; };
		F966BA2108F27A37005CB29B /* clipboard.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clipboard.n; sourceTree = "<group>"; };
		F966BA2208F27A37005CB29B /* ClrSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ClrSelect.3; sourceTree = "<group>"; };
		F966BA2308F27A37005CB29B /* colors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = colors.n; sourceTree = "<group>"; };
		F966BA2408F27A37005CB29B /* ConfigWidg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWidg.3; sourceTree = "<group>"; };
		F966BA2508F27A37005CB29B /* ConfigWind.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ConfigWind.3; sourceTree = "<group>"; };
		F966BA2608F27A37005CB29B /* console.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = console.n; sourceTree = "<group>"; };
		F966BA2708F27A37005CB29B /* CoordToWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CoordToWin.3; sourceTree = "<group>"; };
		F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCmHdlr.3; sourceTree = "<group>"; };
		F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtErrHdlr.3; sourceTree = "<group>"; };
		F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtGenHdlr.3; sourceTree = "<group>"; };
		F966BA2B08F27A37005CB29B /* CrtImgType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtImgType.3; sourceTree = "<group>"; };
		F966BA2C08F27A37005CB29B /* CrtItemType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtItemType.3; sourceTree = "<group>"; };
		F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtPhImgFmt.3; sourceTree = "<group>"; };
		F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSelHdlr.3; sourceTree = "<group>"; };
		F966BA2F08F27A37005CB29B /* CrtWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtWindow.3; sourceTree = "<group>"; };
		F966BA3008F27A37005CB29B /* cursors.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cursors.n; sourceTree = "<group>"; };
		F966BA3108F27A37005CB29B /* DeleteImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DeleteImg.3; sourceTree = "<group>"; };
		F966BA3208F27A37005CB29B /* destroy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = destroy.n; sourceTree = "<group>"; };
		F966BA3308F27A37005CB29B /* dialog.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dialog.n; sourceTree = "<group>"; };
		F966BA3408F27A37005CB29B /* DrawFocHlt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DrawFocHlt.3; sourceTree = "<group>"; };
		F966BA3508F27A37005CB29B /* entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = entry.n; sourceTree = "<group>"; };
		F966BA3608F27A37005CB29B /* event.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = event.n; sourceTree = "<group>"; };
		F966BA3708F27A37005CB29B /* EventHndlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = EventHndlr.3; sourceTree = "<group>"; };
		F966BA3808F27A37005CB29B /* FindPhoto.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindPhoto.3; sourceTree = "<group>"; };
		F966BA3908F27A37005CB29B /* focus.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focus.n; sourceTree = "<group>"; };
		F966BA3A08F27A37005CB29B /* focusNext.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = focusNext.n; sourceTree = "<group>"; };
		F966BA3B08F27A37005CB29B /* font.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = font.n; sourceTree = "<group>"; };
		F966BA3C08F27A37005CB29B /* FontId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FontId.3; sourceTree = "<group>"; };
		F966BA3D08F27A37005CB29B /* frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = frame.n; sourceTree = "<group>"; };
		F966BA3E08F27A37005CB29B /* FreeXId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FreeXId.3; sourceTree = "<group>"; };
		F966BA3F08F27A37005CB29B /* GeomReq.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GeomReq.3; sourceTree = "<group>"; };
		F966BA4008F27A37005CB29B /* GetAnchor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetAnchor.3; sourceTree = "<group>"; };
		F966BA4108F27A37005CB29B /* GetBitmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetBitmap.3; sourceTree = "<group>"; };
		F966BA4208F27A37005CB29B /* GetCapStyl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCapStyl.3; sourceTree = "<group>"; };
		F966BA4308F27A37005CB29B /* GetClrmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetClrmap.3; sourceTree = "<group>"; };
		F966BA4408F27A37005CB29B /* GetColor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetColor.3; sourceTree = "<group>"; };
		F966BA4508F27A37005CB29B /* GetCursor.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCursor.3; sourceTree = "<group>"; };
		F966BA4608F27A37005CB29B /* GetDash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetDash.3; sourceTree = "<group>"; };
		F966BA4708F27A37005CB29B /* GetFont.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetFont.3; sourceTree = "<group>"; };
		F966BA4808F27A37005CB29B /* GetGC.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetGC.3; sourceTree = "<group>"; };
		F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHINSTANCE.3; sourceTree = "<group>"; };
		F966BA4A08F27A37005CB29B /* GetHWND.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHWND.3; sourceTree = "<group>"; };
		F966BA4B08F27A37005CB29B /* GetImage.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetImage.3; sourceTree = "<group>"; };
		F966BA4C08F27A37005CB29B /* GetJoinStl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJoinStl.3; sourceTree = "<group>"; };
		F966BA4D08F27A37005CB29B /* GetJustify.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetJustify.3; sourceTree = "<group>"; };
		F966BA4E08F27A37005CB29B /* getOpenFile.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = getOpenFile.n; sourceTree = "<group>"; };
		F966BA4F08F27A37005CB29B /* GetOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOption.3; sourceTree = "<group>"; };
		F966BA5008F27A38005CB29B /* GetPixels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixels.3; sourceTree = "<group>"; };
		F966BA5108F27A38005CB29B /* GetPixmap.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetPixmap.3; sourceTree = "<group>"; };
		F966BA5208F27A38005CB29B /* GetRelief.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRelief.3; sourceTree = "<group>"; };
		F966BA5308F27A38005CB29B /* GetRootCrd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetRootCrd.3; sourceTree = "<group>"; };
		F966BA5408F27A38005CB29B /* GetScroll.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetScroll.3; sourceTree = "<group>"; };
		F966BA5508F27A38005CB29B /* GetSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetSelect.3; sourceTree = "<group>"; };
		F966BA5608F27A38005CB29B /* GetUid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetUid.3; sourceTree = "<group>"; };
		F966BA5708F27A38005CB29B /* GetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVisual.3; sourceTree = "<group>"; };
		F966BA5808F27A38005CB29B /* GetVRoot.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVRoot.3; sourceTree = "<group>"; };
		F966BA5908F27A38005CB29B /* Grab.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Grab.3; sourceTree = "<group>"; };
		F966BA5A08F27A38005CB29B /* grab.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grab.n; sourceTree = "<group>"; };
		F966BA5B08F27A38005CB29B /* grid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = grid.n; sourceTree = "<group>"; };
		F966BA5C08F27A38005CB29B /* HandleEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HandleEvent.3; sourceTree = "<group>"; };
		F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = HWNDToWindow.3; sourceTree = "<group>"; };
		F966BA5E08F27A38005CB29B /* IdToWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IdToWindow.3; sourceTree = "<group>"; };
		F966BA5F08F27A38005CB29B /* image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = image.n; sourceTree = "<group>"; };
		F966BA6008F27A38005CB29B /* ImgChanged.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ImgChanged.3; sourceTree = "<group>"; };
		F966BA6108F27A38005CB29B /* Inactive.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Inactive.3; sourceTree = "<group>"; };
		F966BA6208F27A38005CB29B /* InternAtom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InternAtom.3; sourceTree = "<group>"; };
		F966BA6308F27A38005CB29B /* keysyms.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = keysyms.n; sourceTree = "<group>"; };
		F966BA6408F27A38005CB29B /* label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = label.n; sourceTree = "<group>"; };
		F966BA6508F27A38005CB29B /* labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = labelframe.n; sourceTree = "<group>"; };
		F966BA6608F27A38005CB29B /* listbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = listbox.n; sourceTree = "<group>"; };
		F966BA6708F27A38005CB29B /* loadTk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = loadTk.n; sourceTree = "<group>"; };
		F966BA6808F27A38005CB29B /* lower.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lower.n; sourceTree = "<group>"; };
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };
		F966BA7108F27A38005CB29B /* menubar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubar.n; sourceTree = "<group>"; };
		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };
		F966BA7C08F27A38005CB29B /* pack-old.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = "pack-old.n"; sourceTree = "<group>"; };
		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };
		F966BA8408F27A38005CB29B /* QWinEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = QWinEvent.3; sourceTree = "<group>"; };
		F966BA8508F27A38005CB29B /* radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = radiobutton.n; sourceTree = "<group>"; };
		F966BA8608F27A38005CB29B /* raise.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = raise.n; sourceTree = "<group>"; };
		F966BA8708F27A38005CB29B /* Restack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Restack.3; sourceTree = "<group>"; };
		F966BA8808F27A38005CB29B /* RestrictEv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RestrictEv.3; sourceTree = "<group>"; };
		F966BA8908F27A38005CB29B /* scale.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scale.n; sourceTree = "<group>"; };
		F966BA8A08F27A38005CB29B /* scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scrollbar.n; sourceTree = "<group>"; };
		F966BA8B08F27A38005CB29B /* selection.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = selection.n; sourceTree = "<group>"; };
		F966BA8C08F27A38005CB29B /* send.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = send.n; sourceTree = "<group>"; };
		F966BA8D08F27A38005CB29B /* SetAppName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetAppName.3; sourceTree = "<group>"; };
		F966BA8E08F27A38005CB29B /* SetCaret.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetCaret.3; sourceTree = "<group>"; };
		F966BA8F08F27A38005CB29B /* SetClass.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClass.3; sourceTree = "<group>"; };
		F966BA9008F27A38005CB29B /* SetClassProcs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetClassProcs.3; sourceTree = "<group>"; };
		F966BA9108F27A38005CB29B /* SetGrid.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetGrid.3; sourceTree = "<group>"; };
		F966BA9208F27A38005CB29B /* SetOptions.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetOptions.3; sourceTree = "<group>"; };
		F966BA9308F27A38005CB29B /* SetVisual.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVisual.3; sourceTree = "<group>"; };
		F966BA9408F27A38005CB29B /* spinbox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = spinbox.n; sourceTree = "<group>"; };
		F966BA9508F27A38005CB29B /* StrictMotif.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrictMotif.3; sourceTree = "<group>"; };
		F966BA9608F27A38005CB29B /* text.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = text.n; sourceTree = "<group>"; };
		F966BA9708F27A38005CB29B /* TextLayout.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TextLayout.3; sourceTree = "<group>"; };
		F966BA9808F27A38005CB29B /* tk.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tk.n; sourceTree = "<group>"; };
		F966BA9A08F27A38005CB29B /* Tk_Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Init.3; sourceTree = "<group>"; };
		F966BA9B08F27A38005CB29B /* Tk_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tk_Main.3; sourceTree = "<group>"; };
		F966BA9C08F27A38005CB29B /* tkerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkerror.n; sourceTree = "<group>"; };
		F966BA9D08F27A38005CB29B /* TkInitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TkInitStubs.3; sourceTree = "<group>"; };
		F966BA9E08F27A38005CB29B /* tkvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkvars.n; sourceTree = "<group>"; };
		F966BA9F08F27A38005CB29B /* tkwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tkwait.n; sourceTree = "<group>"; };
		F966BAA008F27A38005CB29B /* toplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = toplevel.n; sourceTree = "<group>"; };
		F966BAA108F27A38005CB29B /* WindowId.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WindowId.3; sourceTree = "<group>"; };
		F966BAA208F27A38005CB29B /* winfo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = winfo.n; sourceTree = "<group>"; };
		F966BAA308F27A38005CB29B /* wish.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wish.1; sourceTree = "<group>"; };
		F966BAA408F27A38005CB29B /* wm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = wm.n; sourceTree = "<group>"; };
		F966BAA608F27A38005CB29B /* default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default.h; sourceTree = "<group>"; };
		F966BAA708F27A38005CB29B /* ks_names.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ks_names.h; sourceTree = "<group>"; };
		F966BAA908F27A39005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BAAA08F27A39005CB29B /* tk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.decls; sourceTree = "<group>"; };
		F966BAAB08F27A39005CB29B /* tk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk.h; sourceTree = "<group>"; };
		F966BAAC08F27A39005CB29B /* tk3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tk3d.c; sourceTree = "<group>"; };
		F966BAAD08F27A39005CB29B /* tk3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk3d.h; sourceTree = "<group>"; };
		F966BAAE08F27A39005CB29B /* tkArgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkArgv.c; sourceTree = "<group>"; };
		F966BAAF08F27A39005CB29B /* tkAtom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAtom.c; sourceTree = "<group>"; };
		F966BAB008F27A39005CB29B /* tkBind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBind.c; sourceTree = "<group>"; };
		F966BAB108F27A39005CB29B /* tkBitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkBitmap.c; sourceTree = "<group>"; };
		F966BAB208F27A39005CB29B /* tkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkButton.c; sourceTree = "<group>"; };
		F966BAB308F27A39005CB29B /* tkButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkButton.h; sourceTree = "<group>"; };
		F966BAB408F27A39005CB29B /* tkCanvArc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvArc.c; sourceTree = "<group>"; };
		F966BAB508F27A39005CB29B /* tkCanvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvas.c; sourceTree = "<group>"; };
		F966BAB608F27A39005CB29B /* tkCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkCanvas.h; sourceTree = "<group>"; };
		F966BAB708F27A39005CB29B /* tkCanvBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvBmap.c; sourceTree = "<group>"; };
		F966BAB808F27A39005CB29B /* tkCanvImg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvImg.c; sourceTree = "<group>"; };
		F966BAB908F27A39005CB29B /* tkCanvLine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvLine.c; sourceTree = "<group>"; };
		F966BABA08F27A39005CB29B /* tkCanvPoly.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPoly.c; sourceTree = "<group>"; };
		F966BABB08F27A39005CB29B /* tkCanvPs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvPs.c; sourceTree = "<group>"; };
		F966BABD08F27A39005CB29B /* tkCanvText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvText.c; sourceTree = "<group>"; };
		F966BABE08F27A39005CB29B /* tkCanvUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvUtil.c; sourceTree = "<group>"; };
		F966BABF08F27A39005CB29B /* tkCanvWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCanvWind.c; sourceTree = "<group>"; };
		F966BAC008F27A39005CB29B /* tkClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkClipboard.c; sourceTree = "<group>"; };
		F966BAC108F27A39005CB29B /* tkCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCmds.c; sourceTree = "<group>"; };
		F966BAC208F27A39005CB29B /* tkColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkColor.c; sourceTree = "<group>"; };
		F966BAC308F27A39005CB29B /* tkColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkColor.h; sourceTree = "<group>"; };
		F966BAC408F27A39005CB29B /* tkConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConfig.c; sourceTree = "<group>"; };
		F966BAC508F27A39005CB29B /* tkConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkConsole.c; sourceTree = "<group>"; };
		F966BAC608F27A39005CB29B /* tkCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkCursor.c; sourceTree = "<group>"; };
		F966BAC708F27A39005CB29B /* tkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkDecls.h; sourceTree = "<group>"; };
		F966BAC808F27A39005CB29B /* tkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEntry.c; sourceTree = "<group>"; };
		F966BAC908F27A39005CB29B /* tkEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkEntry.h; sourceTree = "<group>"; };
		F966BACA08F27A39005CB29B /* tkError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkError.c; sourceTree = "<group>"; };
		F966BACB08F27A39005CB29B /* tkEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkEvent.c; sourceTree = "<group>"; };
		F966BACC08F27A39005CB29B /* tkFileFilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFileFilter.c; sourceTree = "<group>"; };
		F966BACD08F27A39005CB29B /* tkFileFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFileFilter.h; sourceTree = "<group>"; };
		F966BACE08F27A39005CB29B /* tkFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFocus.c; sourceTree = "<group>"; };
		F966BACF08F27A39005CB29B /* tkFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFont.c; sourceTree = "<group>"; };
		F966BAD008F27A39005CB29B /* tkFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkFont.h; sourceTree = "<group>"; };
		F966BAD108F27A39005CB29B /* tkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkFrame.c; sourceTree = "<group>"; };
		F966BAD208F27A39005CB29B /* tkGC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGC.c; sourceTree = "<group>"; };
		F966BAD308F27A39005CB29B /* tkGeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGeometry.c; sourceTree = "<group>"; };
		F966BAD408F27A39005CB29B /* tkGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGet.c; sourceTree = "<group>"; };
		F966BAD508F27A39005CB29B /* tkGrab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrab.c; sourceTree = "<group>"; };
		F966BAD608F27A39005CB29B /* tkGrid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkGrid.c; sourceTree = "<group>"; };
		F966BAD708F27A39005CB29B /* tkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImage.c; sourceTree = "<group>"; };
		F966BAD808F27A39005CB29B /* tkImgBmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgBmap.c; sourceTree = "<group>"; };
		F966BAD908F27A39005CB29B /* tkImgGIF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgGIF.c; sourceTree = "<group>"; };
		F966BADA08F27A39005CB29B /* tkImgPhoto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPhoto.c; sourceTree = "<group>"; };
		F966BADB08F27A39005CB29B /* tkImgPPM.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPPM.c; sourceTree = "<group>"; };
		F966BADC08F27A39005CB29B /* tkImgUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgUtil.c; sourceTree = "<group>"; };
		F966BADE08F27A39005CB29B /* tkInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkInt.decls; sourceTree = "<group>"; };
		F966BADF08F27A39005CB29B /* tkInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkInt.h; sourceTree = "<group>"; };
		F966BAE108F27A39005CB29B /* tkIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntDecls.h; sourceTree = "<group>"; };
		F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntPlatDecls.h; sourceTree = "<group>"; };
		F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkIntXlibDecls.h; sourceTree = "<group>"; };
		F966BAE408F27A39005CB29B /* tkListbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkListbox.c; sourceTree = "<group>"; };
		F966BAE508F27A39005CB29B /* tkMacWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMacWinMenu.c; sourceTree = "<group>"; };
		F966BAE608F27A39005CB29B /* tkMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMain.c; sourceTree = "<group>"; };
		F966BAE708F27A39005CB29B /* tkMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenu.c; sourceTree = "<group>"; };
		F966BAE808F27A39005CB29B /* tkMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenu.h; sourceTree = "<group>"; };
		F966BAE908F27A39005CB29B /* tkMenubutton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenubutton.c; sourceTree = "<group>"; };
		F966BAEA08F27A39005CB29B /* tkMenubutton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMenubutton.h; sourceTree = "<group>"; };
		F966BAEB08F27A39005CB29B /* tkMenuDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMenuDraw.c; sourceTree = "<group>"; };
		F966BAEC08F27A39005CB29B /* tkMessage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkMessage.c; sourceTree = "<group>"; };
		F966BAED08F27A39005CB29B /* tkObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkObj.c; sourceTree = "<group>"; };
		F966BAEE08F27A39005CB29B /* tkOldConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldConfig.c; sourceTree = "<group>"; };
		F966BAEF08F27A39005CB29B /* tkOption.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOption.c; sourceTree = "<group>"; };
		F966BAF008F27A39005CB29B /* tkPack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPack.c; sourceTree = "<group>"; };
		F966BAF108F27A39005CB29B /* tkPanedWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPanedWindow.c; sourceTree = "<group>"; };
		F966BAF208F27A39005CB29B /* tkPlace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPlace.c; sourceTree = "<group>"; };
		F966BAF308F27A39005CB29B /* tkPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPlatDecls.h; sourceTree = "<group>"; };
		F966BAF408F27A39005CB29B /* tkPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkPointer.c; sourceTree = "<group>"; };
		F966BAF508F27A39005CB29B /* tkPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkPort.h; sourceTree = "<group>"; };
		F966BAF608F27A39005CB29B /* tkRectOval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkRectOval.c; sourceTree = "<group>"; };
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };
		F966BAFE08F27A39005CB29B /* tkOldTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldTest.c; sourceTree = "<group>"; };
		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };
		F966BB0608F27A39005CB29B /* tkTextDisp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextDisp.c; sourceTree = "<group>"; };
		F966BB0808F27A39005CB29B /* tkTextImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextImage.c; sourceTree = "<group>"; };
		F966BB0908F27A39005CB29B /* tkTextIndex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextIndex.c; sourceTree = "<group>"; };
		F966BB0A08F27A39005CB29B /* tkTextMark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextMark.c; sourceTree = "<group>"; };
		F966BB0B08F27A39005CB29B /* tkTextTag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextTag.c; sourceTree = "<group>"; };
		F966BB0C08F27A39005CB29B /* tkTextWind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextWind.c; sourceTree = "<group>"; };
		F966BB0D08F27A39005CB29B /* tkTrig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTrig.c; sourceTree = "<group>"; };
		F966BB0E08F27A39005CB29B /* tkUndo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUndo.c; sourceTree = "<group>"; };
		F966BB0F08F27A39005CB29B /* tkUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUndo.h; sourceTree = "<group>"; };
		F966BB1008F27A39005CB29B /* tkUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUtil.c; sourceTree = "<group>"; };
		F966BB1108F27A39005CB29B /* tkVisual.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkVisual.c; sourceTree = "<group>"; };
		F966BB1208F27A39005CB29B /* tkWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWindow.c; sourceTree = "<group>"; };
		F966BB1408F27A39005CB29B /* bgerror.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.tcl; sourceTree = "<group>"; };
		F966BB1508F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB1608F27A39005CB29B /* choosedir.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.tcl; sourceTree = "<group>"; };
		F966BB1708F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB1808F27A39005CB29B /* comdlg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = comdlg.tcl; sourceTree = "<group>"; };
		F966BB1908F27A39005CB29B /* console.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = console.tcl; sourceTree = "<group>"; };
		F966BB1B08F27A39005CB29B /* anilabel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = anilabel.tcl; sourceTree = "<group>"; };
		F966BB1C08F27A39005CB29B /* aniwave.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aniwave.tcl; sourceTree = "<group>"; };
		F966BB1D08F27A39005CB29B /* arrow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arrow.tcl; sourceTree = "<group>"; };
		F966BB1E08F27A39005CB29B /* bind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.tcl; sourceTree = "<group>"; };
		F966BB1F08F27A39005CB29B /* bitmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.tcl; sourceTree = "<group>"; };
		F966BB2008F27A39005CB29B /* browse */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = browse; sourceTree = "<group>"; };
		F966BB2108F27A39005CB29B /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F966BB2208F27A39005CB29B /* check.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = check.tcl; sourceTree = "<group>"; };
		F966BB2308F27A39005CB29B /* clrpick.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.tcl; sourceTree = "<group>"; };
		F966BB2408F27A39005CB29B /* colors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = colors.tcl; sourceTree = "<group>"; };
		F966BB2508F27A39005CB29B /* cscroll.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cscroll.tcl; sourceTree = "<group>"; };
		F966BB2608F27A39005CB29B /* ctext.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ctext.tcl; sourceTree = "<group>"; };
		F966BB2708F27A39005CB29B /* dialog1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog1.tcl; sourceTree = "<group>"; };
		F966BB2808F27A39005CB29B /* dialog2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog2.tcl; sourceTree = "<group>"; };
		F966BB2A08F27A39005CB29B /* entry1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry1.tcl; sourceTree = "<group>"; };
		F966BB2B08F27A39005CB29B /* entry2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry2.tcl; sourceTree = "<group>"; };
		F966BB2C08F27A39005CB29B /* entry3.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry3.tcl; sourceTree = "<group>"; };
		F966BB2D08F27A39005CB29B /* filebox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.tcl; sourceTree = "<group>"; };
		F966BB2E08F27A39005CB29B /* floor.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = floor.tcl; sourceTree = "<group>"; };
		F966BB2F08F27A39005CB29B /* form.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = form.tcl; sourceTree = "<group>"; };
		F966BB3008F27A39005CB29B /* goldberg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = goldberg.tcl; sourceTree = "<group>"; };
		F966BB3108F27A39005CB29B /* hello */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = hello; sourceTree = "<group>"; };
		F966BB3208F27A39005CB29B /* hscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = hscale.tcl; sourceTree = "<group>"; };
		F966BB3308F27A39005CB29B /* icon.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icon.tcl; sourceTree = "<group>"; };
		F966BB3408F27A39005CB29B /* image1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image1.tcl; sourceTree = "<group>"; };
		F966BB3508F27A39005CB29B /* image2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image2.tcl; sourceTree = "<group>"; };
		F966BB4208F27A3A005CB29B /* items.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = items.tcl; sourceTree = "<group>"; };
		F966BB4308F27A3A005CB29B /* ixset */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ixset; sourceTree = "<group>"; };
		F966BB4408F27A3A005CB29B /* label.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = label.tcl; sourceTree = "<group>"; };
		F966BB4508F27A3A005CB29B /* labelframe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.tcl; sourceTree = "<group>"; };
		F966BB4608F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB4708F27A3A005CB29B /* menubu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubu.tcl; sourceTree = "<group>"; };
		F966BB4808F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB4A08F27A3A005CB29B /* paned1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned1.tcl; sourceTree = "<group>"; };
		F966BB4B08F27A3A005CB29B /* paned2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = paned2.tcl; sourceTree = "<group>"; };
		F966BB4C08F27A3A005CB29B /* pendulum.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pendulum.tcl; sourceTree = "<group>"; };
		F966BB4D08F27A3A005CB29B /* plot.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = plot.tcl; sourceTree = "<group>"; };
		F966BB4E08F27A3A005CB29B /* puzzle.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = puzzle.tcl; sourceTree = "<group>"; };
		F966BB4F08F27A3A005CB29B /* radio.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radio.tcl; sourceTree = "<group>"; };
		F966BB5008F27A3A005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BB5108F27A3A005CB29B /* rmt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rmt; sourceTree = "<group>"; };
		F966BB5208F27A3A005CB29B /* rolodex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = rolodex; sourceTree = "<group>"; };
		F966BB5308F27A3A005CB29B /* ruler.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ruler.tcl; sourceTree = "<group>"; };
		F966BB5408F27A3A005CB29B /* sayings.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sayings.tcl; sourceTree = "<group>"; };
		F966BB5508F27A3A005CB29B /* search.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = search.tcl; sourceTree = "<group>"; };
		F966BB5608F27A3A005CB29B /* spin.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spin.tcl; sourceTree = "<group>"; };
		F966BB5708F27A3A005CB29B /* square */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = square; sourceTree = "<group>"; };
		F966BB5808F27A3A005CB29B /* states.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = states.tcl; sourceTree = "<group>"; };
		F966BB5908F27A3A005CB29B /* style.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = style.tcl; sourceTree = "<group>"; };
		F966BB5A08F27A3A005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB5B08F27A3A005CB29B /* tcolor */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = tcolor; sourceTree = "<group>"; };
		F966BB5C08F27A3A005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB5D08F27A3A005CB29B /* timer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = timer; sourceTree = "<group>"; };
		F966BB5E08F27A3A005CB29B /* twind.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = twind.tcl; sourceTree = "<group>"; };
		F966BB5F08F27A3A005CB29B /* unicodeout.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unicodeout.tcl; sourceTree = "<group>"; };
		F966BB6008F27A3A005CB29B /* vscale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vscale.tcl; sourceTree = "<group>"; };
		F966BB6108F27A3A005CB29B /* widget */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = widget; sourceTree = "<group>"; };
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB8608F27A3A005CB29B /* obsolete.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obsolete.tcl; sourceTree = "<group>"; };
		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };
		F966BB9408F27A3B005CB29B /* unsupported.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unsupported.tcl; sourceTree = "<group>"; };
		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };
		F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXBitmap.c; sourceTree = "<group>"; };
		F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXButton.c; sourceTree = "<group>"; };
		F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXClipboard.c; sourceTree = "<group>"; };
		F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXColor.c; sourceTree = "<group>"; };
		F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXConfig.c; sourceTree = "<group>"; };
		F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXCursor.c; sourceTree = "<group>"; };
		F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXCursors.h; sourceTree = "<group>"; };
		F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDebug.c; sourceTree = "<group>"; };
		F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDebug.h; sourceTree = "<group>"; };
		F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXDefault.h; sourceTree = "<group>"; };
		F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDialog.c; sourceTree = "<group>"; };
		F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXDraw.c; sourceTree = "<group>"; };
		F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEmbed.c; sourceTree = "<group>"; };
		F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEntry.c; sourceTree = "<group>"; };
		F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXEvent.c; sourceTree = "<group>"; };
		F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXFont.c; sourceTree = "<group>"; };
		F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXHLEvents.c; sourceTree = "<group>"; };
		F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXInit.c; sourceTree = "<group>"; };
		F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXInt.h; sourceTree = "<group>"; };
		F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyboard.c; sourceTree = "<group>"; };
		F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXKeyEvent.c; sourceTree = "<group>"; };
		F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenu.c; sourceTree = "<group>"; };
		F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenubutton.c; sourceTree = "<group>"; };
		F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMenus.c; sourceTree = "<group>"; };
		F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXMouseEvent.c; sourceTree = "<group>"; };
		F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXNotify.c; sourceTree = "<group>"; };
		F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPort.h; sourceTree = "<group>"; };
		F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXRegion.c; sourceTree = "<group>"; };
		F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScale.c; sourceTree = "<group>"; };
		F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXScrlbr.c; sourceTree = "<group>"; };
		F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSend.c; sourceTree = "<group>"; };
		F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXSubwindows.c; sourceTree = "<group>"; };
		F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXTest.c; sourceTree = "<group>"; };
		F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWindowEvent.c; sourceTree = "<group>"; };
		F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXWm.c; sourceTree = "<group>"; };
		F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXWm.h; sourceTree = "<group>"; };
		F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXXCursors.h; sourceTree = "<group>"; };
		F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = tkMacOSXXStubs.c; sourceTree = "<group>"; };
		F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Wish-Info.plist.in"; sourceTree = "<group>"; };
		F966BC0308F27A3C005CB29B /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F966BC0508F27A3C005CB29B /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F966BC0608F27A3C005CB29B /* arc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = arc.tcl; sourceTree = "<group>"; };
		F966BC0708F27A3C005CB29B /* bell.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bell.test; sourceTree = "<group>"; };
		F966BC0808F27A3C005CB29B /* bevel.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bevel.tcl; sourceTree = "<group>"; };
		F966BC0908F27A3C005CB29B /* bgerror.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bgerror.test; sourceTree = "<group>"; };
		F966BC0A08F27A3C005CB29B /* bind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bind.test; sourceTree = "<group>"; };
		F966BC0B08F27A3C005CB29B /* bitmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bitmap.test; sourceTree = "<group>"; };
		F966BC0C08F27A3C005CB29B /* border.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = border.test; sourceTree = "<group>"; };
		F966BC0D08F27A3C005CB29B /* bugs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = bugs.tcl; sourceTree = "<group>"; };
		F966BC0E08F27A3C005CB29B /* butGeom.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom.tcl; sourceTree = "<group>"; };
		F966BC0F08F27A3C005CB29B /* butGeom2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = butGeom2.tcl; sourceTree = "<group>"; };
		F966BC1008F27A3C005CB29B /* button.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.test; sourceTree = "<group>"; };
		F966BC1108F27A3C005CB29B /* canvas.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvas.test; sourceTree = "<group>"; };
		F966BC1208F27A3C005CB29B /* canvImg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvImg.test; sourceTree = "<group>"; };
		F966BC1308F27A3C005CB29B /* canvPs.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPs.test; sourceTree = "<group>"; };
		F966BC1408F27A3C005CB29B /* canvPsArc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsArc.tcl; sourceTree = "<group>"; };
		F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsBmap.tcl; sourceTree = "<group>"; };
		F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsGrph.tcl; sourceTree = "<group>"; };
		F966BC1708F27A3C005CB29B /* canvPsImg.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsImg.tcl; sourceTree = "<group>"; };
		F966BC1808F27A3C005CB29B /* canvPsText.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvPsText.tcl; sourceTree = "<group>"; };
		F966BC1908F27A3C005CB29B /* canvRect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvRect.test; sourceTree = "<group>"; };
		F966BC1A08F27A3C005CB29B /* canvText.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvText.test; sourceTree = "<group>"; };
		F966BC1B08F27A3C005CB29B /* canvWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = canvWind.test; sourceTree = "<group>"; };
		F966BC1C08F27A3C005CB29B /* choosedir.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = choosedir.test; sourceTree = "<group>"; };
		F966BC1D08F27A3C005CB29B /* clipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clipboard.test; sourceTree = "<group>"; };
		F966BC1E08F27A3C005CB29B /* clrpick.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clrpick.test; sourceTree = "<group>"; };
		F966BC1F08F27A3C005CB29B /* cmap.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmap.tcl; sourceTree = "<group>"; };
		F966BC2008F27A3C005CB29B /* cmds.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmds.test; sourceTree = "<group>"; };
		F966BC2108F27A3C005CB29B /* color.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = color.test; sourceTree = "<group>"; };
		F966BC2208F27A3C005CB29B /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F966BC2308F27A3C005CB29B /* constraints.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = constraints.tcl; sourceTree = "<group>"; };
		F966BC2408F27A3C005CB29B /* cursor.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursor.test; sourceTree = "<group>"; };
		F966BC2508F27A3C005CB29B /* dialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.test; sourceTree = "<group>"; };
		F966BC2608F27A3C005CB29B /* embed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = embed.test; sourceTree = "<group>"; };
		F966BC2708F27A3C005CB29B /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F966BC2808F27A3C005CB29B /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F966BC2908F27A3C005CB29B /* filebox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = filebox.test; sourceTree = "<group>"; };
		F966BC2A08F27A3C005CB29B /* focus.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.test; sourceTree = "<group>"; };
		F966BC2B08F27A3C005CB29B /* focusTcl.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focusTcl.test; sourceTree = "<group>"; };
		F966BC2C08F27A3C005CB29B /* font.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = font.test; sourceTree = "<group>"; };
		F966BC2D08F27A3C005CB29B /* frame.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = frame.test; sourceTree = "<group>"; };
		F966BC2E08F27A3C005CB29B /* geometry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = geometry.test; sourceTree = "<group>"; };
		F966BC2F08F27A3C005CB29B /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F966BC3008F27A3C005CB29B /* grab.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grab.test; sourceTree = "<group>"; };
		F966BC3108F27A3C005CB29B /* grid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = grid.test; sourceTree = "<group>"; };
		F966BC3308F27A3C005CB29B /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F966BC3408F27A3C005CB29B /* imgBmap.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgBmap.test; sourceTree = "<group>"; };
		F966BC3508F27A3C005CB29B /* imgPhoto.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPhoto.test; sourceTree = "<group>"; };
		F966BC3608F27A3C005CB29B /* imgPPM.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPPM.test; sourceTree = "<group>"; };
		F966BC3708F27A3C005CB29B /* listbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.test; sourceTree = "<group>"; };
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F966BC3F08F27A3C005CB29B /* oldpack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oldpack.test; sourceTree = "<group>"; };
		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };
		F966BC4708F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC4808F27A3D005CB29B /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F966BC4908F27A3D005CB29B /* scale.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.test; sourceTree = "<group>"; };
		F966BC4A08F27A3D005CB29B /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F966BC4B08F27A3D005CB29B /* select.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = select.test; sourceTree = "<group>"; };
		F966BC4C08F27A3D005CB29B /* send.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = send.test; sourceTree = "<group>"; };
		F966BC4D08F27A3D005CB29B /* spinbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.test; sourceTree = "<group>"; };
		F966BC4E08F27A3D005CB29B /* text.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.test; sourceTree = "<group>"; };
		F966BC4F08F27A3D005CB29B /* textBTree.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textBTree.test; sourceTree = "<group>"; };
		F966BC5008F27A3D005CB29B /* textDisp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textDisp.test; sourceTree = "<group>"; };
		F966BC5108F27A3D005CB29B /* textImage.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textImage.test; sourceTree = "<group>"; };
		F966BC5208F27A3D005CB29B /* textIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textIndex.test; sourceTree = "<group>"; };
		F966BC5308F27A3D005CB29B /* textMark.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textMark.test; sourceTree = "<group>"; };
		F966BC5408F27A3D005CB29B /* textTag.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textTag.test; sourceTree = "<group>"; };
		F966BC5508F27A3D005CB29B /* textWind.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = textWind.test; sourceTree = "<group>"; };
		F966BC5608F27A3D005CB29B /* tk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.test; sourceTree = "<group>"; };
		F966BC5708F27A3D005CB29B /* unixButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixButton.test; sourceTree = "<group>"; };
		F966BC5808F27A3D005CB29B /* unixEmbed.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixEmbed.test; sourceTree = "<group>"; };
		F966BC5908F27A3D005CB29B /* unixFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFont.test; sourceTree = "<group>"; };
		F966BC5A08F27A3D005CB29B /* unixMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixMenu.test; sourceTree = "<group>"; };
		F966BC5B08F27A3D005CB29B /* unixSelect.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixSelect.test; sourceTree = "<group>"; };
		F966BC5C08F27A3D005CB29B /* unixWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixWm.test; sourceTree = "<group>"; };
		F966BC5D08F27A3D005CB29B /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F966BC5E08F27A3D005CB29B /* visual.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual.test; sourceTree = "<group>"; };
		F966BC5F08F27A3D005CB29B /* visual_bb.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = visual_bb.test; sourceTree = "<group>"; };
		F966BC6008F27A3D005CB29B /* winButton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winButton.test; sourceTree = "<group>"; };
		F966BC6108F27A3D005CB29B /* winClipboard.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winClipboard.test; sourceTree = "<group>"; };
		F966BC6208F27A3D005CB29B /* winDialog.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDialog.test; sourceTree = "<group>"; };
		F966BC6308F27A3D005CB29B /* window.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = window.test; sourceTree = "<group>"; };
		F966BC6408F27A3D005CB29B /* winfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winfo.test; sourceTree = "<group>"; };
		F966BC6508F27A3D005CB29B /* winFont.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFont.test; sourceTree = "<group>"; };
		F966BC6608F27A3D005CB29B /* winMenu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winMenu.test; sourceTree = "<group>"; };
		F966BC6708F27A3D005CB29B /* winSend.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winSend.test; sourceTree = "<group>"; };
		F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = "<group>"; };
		F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = "<group>"; };
		F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = "<group>"; };
		F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BC7408F27A3D005CB29B /* tk.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.spec; sourceTree = "<group>"; };
		F966BC7508F27A3D005CB29B /* tkAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkAppInit.c; sourceTree = "<group>"; };
		F966BC7608F27A3D005CB29B /* tkConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tkConfig.h.in; sourceTree = "<group>"; };
		F966BC7708F27A3D005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };
		F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDialog.c; sourceTree = "<group>"; };
		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };
		F966BC8708F27A3D005CB29B /* tkUnixKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixKey.c; sourceTree = "<group>"; };
		F966BC8808F27A3D005CB29B /* tkUnixMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenu.c; sourceTree = "<group>"; };
		F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixMenubu.c; sourceTree = "<group>"; };
		F966BC8A08F27A3D005CB29B /* tkUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixPort.h; sourceTree = "<group>"; };
		F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixRFont.c; sourceTree = "<group>"; };
		F966BC8C08F27A3D005CB29B /* tkUnixScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScale.c; sourceTree = "<group>"; };
		F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixScrlbr.c; sourceTree = "<group>"; };
		F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSelect.c; sourceTree = "<group>"; };
		F966BC8F08F27A3D005CB29B /* tkUnixSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixSend.c; sourceTree = "<group>"; };
		F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = "<group>"; };
		F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = "<group>"; };
		F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = "<group>"; };
		F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = "<group>"; };
		F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = "<group>"; };
		F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = "<group>"; };
		F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = "<group>"; };
		F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = "<group>"; };
		F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin32Dll.c; sourceTree = "<group>"; };
		F966BCFB08F27A3F005CB29B /* tkWin3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWin3d.c; sourceTree = "<group>"; };
		F966BCFC08F27A3F005CB29B /* tkWinButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinButton.c; sourceTree = "<group>"; };
		F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinClipboard.c; sourceTree = "<group>"; };
		F966BCFE08F27A3F005CB29B /* tkWinColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinColor.c; sourceTree = "<group>"; };
		F966BCFF08F27A3F005CB29B /* tkWinConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinConfig.c; sourceTree = "<group>"; };
		F966BD0008F27A3F005CB29B /* tkWinCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinCursor.c; sourceTree = "<group>"; };
		F966BD0108F27A3F005CB29B /* tkWinDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinDefault.h; sourceTree = "<group>"; };
		F966BD0208F27A3F005CB29B /* tkWinDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDialog.c; sourceTree = "<group>"; };
		F966BD0308F27A3F005CB29B /* tkWinDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinDraw.c; sourceTree = "<group>"; };
		F966BD0408F27A3F005CB29B /* tkWinEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinEmbed.c; sourceTree = "<group>"; };
		F966BD0508F27A3F005CB29B /* tkWinFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinFont.c; sourceTree = "<group>"; };
		F966BD0708F27A3F005CB29B /* tkWinImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinImage.c; sourceTree = "<group>"; };
		F966BD0808F27A3F005CB29B /* tkWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinInit.c; sourceTree = "<group>"; };
		F966BD0908F27A3F005CB29B /* tkWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinInt.h; sourceTree = "<group>"; };
		F966BD0A08F27A3F005CB29B /* tkWinKey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinKey.c; sourceTree = "<group>"; };
		F966BD0B08F27A3F005CB29B /* tkWinMenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinMenu.c; sourceTree = "<group>"; };
		F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPixmap.c; sourceTree = "<group>"; };
		F966BD0D08F27A3F005CB29B /* tkWinPointer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinPointer.c; sourceTree = "<group>"; };
		F966BD0E08F27A3F005CB29B /* tkWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinPort.h; sourceTree = "<group>"; };
		F966BD0F08F27A3F005CB29B /* tkWinRegion.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinRegion.c; sourceTree = "<group>"; };
		F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinScrlbr.c; sourceTree = "<group>"; };
		F966BD1108F27A3F005CB29B /* tkWinSend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSend.c; sourceTree = "<group>"; };
		F966BD1208F27A3F005CB29B /* tkWinSendCom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinSendCom.c; sourceTree = "<group>"; };
		F966BD1308F27A3F005CB29B /* tkWinSendCom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWinSendCom.h; sourceTree = "<group>"; };
		F966BD1408F27A3F005CB29B /* tkWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinTest.c; sourceTree = "<group>"; };
		F966BD1508F27A3F005CB29B /* tkWinWindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWindow.c; sourceTree = "<group>"; };
		F966BD1608F27A3F005CB29B /* tkWinWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinWm.c; sourceTree = "<group>"; };
		F966BD1708F27A3F005CB29B /* tkWinX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkWinX.c; sourceTree = "<group>"; };
		F966BD1808F27A3F005CB29B /* winMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = winMain.c; sourceTree = "<group>"; };
		F966BD1B08F27A3F005CB29B /* cursorfont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorfont.h; sourceTree = "<group>"; };
		F966BD1C08F27A3F005CB29B /* keysym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysym.h; sourceTree = "<group>"; };
		F966BD1D08F27A3F005CB29B /* keysymdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keysymdef.h; sourceTree = "<group>"; };
		F966BD1E08F27A3F005CB29B /* X.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X.h; sourceTree = "<group>"; };
		F966BD1F08F27A3F005CB29B /* Xatom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xatom.h; sourceTree = "<group>"; };
		F966BD2008F27A3F005CB29B /* Xfuncproto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xfuncproto.h; sourceTree = "<group>"; };
		F966BD2108F27A3F005CB29B /* Xlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xlib.h; sourceTree = "<group>"; };
		F966BD2208F27A3F005CB29B /* Xutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xutil.h; sourceTree = "<group>"; };
		F966BD2308F27A3F005CB29B /* xbytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbytes.h; sourceTree = "<group>"; };
		F966BD2408F27A3F005CB29B /* xcolors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xcolors.c; sourceTree = "<group>"; };
		F966BD2508F27A3F005CB29B /* xdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdraw.c; sourceTree = "<group>"; };
		F966BD2608F27A3F005CB29B /* xgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xgc.c; sourceTree = "<group>"; };
		F966BD2708F27A3F005CB29B /* ximage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ximage.c; sourceTree = "<group>"; };
		F966BD2808F27A3F005CB29B /* xutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xutil.c; sourceTree = "<group>"; };
		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
		F966C07608F2821B005CB29B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
		F966C07808F28233005CB29B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
		F96887E00AF786D5000797B5 /* ttk.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.decls; sourceTree = "<group>"; };
		F96887E10AF786D5000797B5 /* ttkBlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkBlink.c; sourceTree = "<group>"; };
		F96887E20AF786D5000797B5 /* ttkButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkButton.c; sourceTree = "<group>"; };
		F96887E30AF786D5000797B5 /* ttkCache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkCache.c; sourceTree = "<group>"; };
		F96887E40AF786D5000797B5 /* ttkClamTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClamTheme.c; sourceTree = "<group>"; };
		F96887E50AF786D5000797B5 /* ttkClassicTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkClassicTheme.c; sourceTree = "<group>"; };
		F96887E60AF786D5000797B5 /* ttkDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkDecls.h; sourceTree = "<group>"; };
		F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkDefaultTheme.c; sourceTree = "<group>"; };
		F96887E80AF786D5000797B5 /* ttkElements.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkElements.c; sourceTree = "<group>"; };
		F96887E90AF786D5000797B5 /* ttkEntry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkEntry.c; sourceTree = "<group>"; };
		F96887EA0AF786D5000797B5 /* ttkFrame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkFrame.c; sourceTree = "<group>"; };
		F96887EB0AF786D5000797B5 /* ttkImage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkImage.c; sourceTree = "<group>"; };
		F96887EC0AF786D5000797B5 /* ttkInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkInit.c; sourceTree = "<group>"; };
		F96887ED0AF786D5000797B5 /* ttkLabel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLabel.c; sourceTree = "<group>"; };
		F96887EE0AF786D5000797B5 /* ttkLayout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkLayout.c; sourceTree = "<group>"; };
		F96887EF0AF786D5000797B5 /* ttkManager.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkManager.c; sourceTree = "<group>"; };
		F96887F00AF786D5000797B5 /* ttkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkManager.h; sourceTree = "<group>"; };
		F96887F10AF786D5000797B5 /* ttkNotebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkNotebook.c; sourceTree = "<group>"; };
		F96887F20AF786D5000797B5 /* ttkPanedwindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkPanedwindow.c; sourceTree = "<group>"; };
		F96887F30AF786D5000797B5 /* ttkProgress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkProgress.c; sourceTree = "<group>"; };
		F96887F40AF786D5000797B5 /* ttkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScale.c; sourceTree = "<group>"; };
		F96887F50AF786D5000797B5 /* ttkScroll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScroll.c; sourceTree = "<group>"; };
		F96887F60AF786D5000797B5 /* ttkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkScrollbar.c; sourceTree = "<group>"; };
		F96887F70AF786D5000797B5 /* ttkSeparator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSeparator.c; sourceTree = "<group>"; };
		F96887F80AF786D5000797B5 /* ttkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkSquare.c; sourceTree = "<group>"; };
		F96887F90AF786D5000797B5 /* ttkState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkState.c; sourceTree = "<group>"; };
		F96887FA0AF786D5000797B5 /* ttkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubInit.c; sourceTree = "<group>"; };
		F96887FB0AF786D5000797B5 /* ttkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkStubLib.c; sourceTree = "<group>"; };
		F96887FC0AF786D5000797B5 /* ttkTagSet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTagSet.c; sourceTree = "<group>"; };
		F96887FD0AF786D5000797B5 /* ttkTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTheme.c; sourceTree = "<group>"; };
		F96887FE0AF786D5000797B5 /* ttkTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkTheme.h; sourceTree = "<group>"; };
		F96887FF0AF786D5000797B5 /* ttkThemeInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkThemeInt.h; sourceTree = "<group>"; };
		F96888000AF786D5000797B5 /* ttkTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrace.c; sourceTree = "<group>"; };
		F96888010AF786D5000797B5 /* ttkTrack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTrack.c; sourceTree = "<group>"; };
		F96888020AF786D5000797B5 /* ttkTreeview.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkTreeview.c; sourceTree = "<group>"; };
		F96888030AF786D5000797B5 /* ttkWidget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWidget.c; sourceTree = "<group>"; };
		F96888040AF786D5000797B5 /* ttkWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttkWidget.h; sourceTree = "<group>"; };
		F96888370AF787B3000797B5 /* altTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = altTheme.tcl; sourceTree = "<group>"; };
		F96888380AF787B3000797B5 /* aquaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = aquaTheme.tcl; sourceTree = "<group>"; };
		F96888390AF787B3000797B5 /* button.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = button.tcl; sourceTree = "<group>"; };
		F968883A0AF787B3000797B5 /* clamTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clamTheme.tcl; sourceTree = "<group>"; };
		F968883B0AF787B3000797B5 /* classicTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = classicTheme.tcl; sourceTree = "<group>"; };
		F968883C0AF787B3000797B5 /* combobox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.tcl; sourceTree = "<group>"; };
		F968883D0AF787B3000797B5 /* cursors.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cursors.tcl; sourceTree = "<group>"; };
		F968883E0AF787B3000797B5 /* defaults.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = defaults.tcl; sourceTree = "<group>"; };
		F96888400AF787B3000797B5 /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F96888410AF787B3000797B5 /* fonts.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fonts.tcl; sourceTree = "<group>"; };
		F96888440AF787B3000797B5 /* menubutton.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubutton.tcl; sourceTree = "<group>"; };
		F96888450AF787B3000797B5 /* notebook.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.tcl; sourceTree = "<group>"; };
		F96888460AF787B3000797B5 /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F96888470AF787B3000797B5 /* progress.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progress.tcl; sourceTree = "<group>"; };
		F96888480AF787B3000797B5 /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F96888490AF787B3000797B5 /* scrollbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.tcl; sourceTree = "<group>"; };
		F968884A0AF787B3000797B5 /* sizegrip.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = sizegrip.tcl; sourceTree = "<group>"; };
		F968884B0AF787B3000797B5 /* treeview.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.tcl; sourceTree = "<group>"; };
		F968884C0AF787B3000797B5 /* ttk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.tcl; sourceTree = "<group>"; };
		F968884D0AF787B3000797B5 /* utils.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utils.tcl; sourceTree = "<group>"; };
		F968884E0AF787B3000797B5 /* winTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTheme.tcl; sourceTree = "<group>"; };
		F968884F0AF787B3000797B5 /* xpTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xpTheme.tcl; sourceTree = "<group>"; };
		F96888540AF7880C000797B5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96888560AF7880C000797B5 /* combobox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = combobox.test; sourceTree = "<group>"; };
		F96888570AF7880C000797B5 /* entry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.test; sourceTree = "<group>"; };
		F96888580AF7880C000797B5 /* image.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = image.test; sourceTree = "<group>"; };
		F96888590AF7880C000797B5 /* labelframe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = labelframe.test; sourceTree = "<group>"; };
		F968885A0AF7880C000797B5 /* layout.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = layout.test; sourceTree = "<group>"; };
		F968885C0AF7880C000797B5 /* notebook.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notebook.test; sourceTree = "<group>"; };
		F968885D0AF7880C000797B5 /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F968885E0AF7880C000797B5 /* progressbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = progressbar.test; sourceTree = "<group>"; };
		F968885F0AF7880C000797B5 /* scrollbar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrollbar.test; sourceTree = "<group>"; };
		F96888600AF7880C000797B5 /* treetags.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treetags.test; sourceTree = "<group>"; };
		F96888610AF7880C000797B5 /* treeview.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = treeview.test; sourceTree = "<group>"; };
		F96888620AF7880C000797B5 /* ttk.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ttk.test; sourceTree = "<group>"; };
		F96888630AF7880C000797B5 /* validate.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = validate.test; sourceTree = "<group>"; };
		F968886B0AF788F6000797B5 /* ttk_button.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_button.n; sourceTree = "<group>"; };
		F968886C0AF788F6000797B5 /* ttk_checkbutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_checkbutton.n; sourceTree = "<group>"; };
		F968886D0AF788F6000797B5 /* ttk_combobox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_combobox.n; sourceTree = "<group>"; };
		F968886F0AF788F6000797B5 /* ttk_entry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_entry.n; sourceTree = "<group>"; };
		F96888700AF788F6000797B5 /* ttk_frame.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_frame.n; sourceTree = "<group>"; };
		F96888710AF788F6000797B5 /* ttk_Geometry.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Geometry.3; sourceTree = "<group>"; };
		F96888720AF788F6000797B5 /* ttk_image.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_image.n; sourceTree = "<group>"; };
		F96888730AF788F6000797B5 /* ttk_intro.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_intro.n; sourceTree = "<group>"; };
		F96888740AF788F6000797B5 /* ttk_label.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_label.n; sourceTree = "<group>"; };
		F96888750AF788F6000797B5 /* ttk_labelframe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_labelframe.n; sourceTree = "<group>"; };
		F96888760AF788F6000797B5 /* ttk_menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_menubutton.n; sourceTree = "<group>"; };
		F96888770AF788F6000797B5 /* ttk_notebook.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_notebook.n; sourceTree = "<group>"; };
		F96888780AF788F6000797B5 /* ttk_panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_panedwindow.n; sourceTree = "<group>"; };
		F96888790AF788F6000797B5 /* ttk_progressbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_progressbar.n; sourceTree = "<group>"; };
		F968887A0AF788F6000797B5 /* ttk_radiobutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_radiobutton.n; sourceTree = "<group>"; };
		F968887B0AF788F6000797B5 /* ttk_scrollbar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_scrollbar.n; sourceTree = "<group>"; };
		F968887C0AF788F6000797B5 /* ttk_separator.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_separator.n; sourceTree = "<group>"; };
		F968887D0AF788F6000797B5 /* ttk_sizegrip.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_sizegrip.n; sourceTree = "<group>"; };
		F968887E0AF788F6000797B5 /* ttk_style.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_style.n; sourceTree = "<group>"; };
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };
		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd; sourceTree = "<group>"; };
		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = "<group>"; };
		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D443608F272B8004A47F5 /* tcl.wse.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.wse.in; sourceTree = "<group>"; };
		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
		F973E5960EE99384001A648E /* vistaTheme.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = vistaTheme.tcl; sourceTree = "<group>"; };
		F974D56C0FBE7D6300BF728B /* http11.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http11.test; sourceTree = "<group>"; };
		F974D56D0FBE7D6300BF728B /* httpd11.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd11.tcl; sourceTree = "<group>"; };
		F974D5720FBE7DC600BF728B /* coroutine.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = coroutine.n; sourceTree = "<group>"; };
		F974D5760FBE7E1900BF728B /* tailcall.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tailcall.n; sourceTree = "<group>"; };
		F974D5770FBE7E6100BF728B /* coroutine.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = coroutine.test; sourceTree = "<group>"; };
		F974D5780FBE7E6100BF728B /* tailcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tailcall.test; sourceTree = "<group>"; };
		F974D5790FBE7E9C00BF728B /* tcl.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.pc.in; sourceTree = "<group>"; };
		F974D57B0FBE7EC000BF728B /* tk.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.pc.in; sourceTree = "<group>"; };
		F974D57C0FBE7EFF00BF728B /* iconlist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iconlist.tcl; sourceTree = "<group>"; };
		F974D57D0FBE7EFF00BF728B /* icons.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = icons.tcl; sourceTree = "<group>"; };
		F97590AE1039A96200558A9A /* Wish.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.sdef; path = Wish.sdef; sourceTree = "<group>"; };
		F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSXPrivate.h; sourceTree = "<group>"; };
		F97AE7F10B65C1E900310EA2 /* Tk-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Common.xcconfig"; sourceTree = "<group>"; };
		F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Release.xcconfig"; sourceTree = "<group>"; };
		F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tk-Debug.xcconfig"; sourceTree = "<group>"; };
		F98383650F0FA43900171CA6 /* checkbutton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkbutton.test; sourceTree = "<group>"; };
		F98383680F0FA44700171CA6 /* radiobutton.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = radiobutton.test; sourceTree = "<group>"; };
		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
		F99388380EE0114B0065FE6B /* fontchooser.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchooser.tcl; sourceTree = "<group>"; };
		F99388950EE02D980065FE6B /* fontchooser.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fontchooser.test; sourceTree = "<group>"; };
		F99D61180EF5573A00BBFE01 /* TclZlib.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TclZlib.3; sourceTree = "<group>"; };
		F9A3082D08F2D4AB00BAE1AB /* Tk.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084B08F2D4CE00BAE1AB /* Wish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Wish.app; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
		F9C888C20EEF6571003F63AD /* fontchooser.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fontchooser.n; sourceTree = "<group>"; };
		F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
		F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mclist.tcl; sourceTree = "<group>"; };
		F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkImgPNG.c; sourceTree = "<group>"; };
		F9DD99BF0F07DFCD0018B2E4 /* imgPNG.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = imgPNG.test; sourceTree = "<group>"; };
		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
		F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkpane.tcl; sourceTree = "<group>"; };
		F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; languageSpecificationIdentifier = shell; path = ttkmenu.tcl; sourceTree = "<group>"; };
		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
		F9FD31F40CC1AD070073837D /* tktest-X11 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "tktest-X11"; sourceTree = BUILT_PRODUCTS_DIR; };
		F9FD32140CC1AF170073837D /* libX11.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libX11.dylib; path = /usr/X11R6/lib/libX11.dylib; sourceTree = "<absolute>"; };
		F9FD32150CC1AF170073837D /* libXext.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXext.dylib; path = /usr/X11R6/lib/libXext.dylib; sourceTree = "<absolute>"; };
		F9FD32160CC1AF170073837D /* libXss.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXss.dylib; path = /usr/X11R6/lib/libXss.dylib; sourceTree = "<absolute>"; };
		F9FD34990CC1BB0D0073837D /* libfreetype.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfreetype.dylib; path = /usr/X11R6/lib/libfreetype.dylib; sourceTree = "<absolute>"; };
		F9FD349A0CC1BB0D0073837D /* libXft.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libXft.dylib; path = /usr/X11R6/lib/libXft.dylib; sourceTree = "<absolute>"; };
		F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfontconfig.dylib; path = /usr/X11R6/lib/libfontconfig.dylib; sourceTree = "<absolute>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
				F96437E70EF0D652003F468E /* libz.dylib in Frameworks */,
				F966C07708F2821B005CB29B /* Carbon.framework in Frameworks */,
				F966C07908F28233005CB29B /* IOKit.framework in Frameworks */,
				F94523A20E6FC2AC00C1D987 /* Cocoa.framework in Frameworks */,
				F9C9CC000E84059800E00935 /* ApplicationServices.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD31E30CC1AD070073837D /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD31E40CC1AD070073837D /* CoreFoundation.framework in Frameworks */,
				F96437E80EF0D652003F468E /* libz.dylib in Frameworks */,
				F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */,
				F9FD32180CC1AF170073837D /* libXext.dylib in Frameworks */,
				F9FD32190CC1AF170073837D /* libXss.dylib in Frameworks */,
				F9FD349C0CC1BB0D0073837D /* libXft.dylib in Frameworks */,
				F9FD349B0CC1BB0D0073837D /* libfreetype.dylib in Frameworks */,
				F9FD34C40CC1BBD70073837D /* libfontconfig.dylib in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		08FB7794FE84155DC02AAC07 /* Tk */ = {
			isa = PBXGroup;
			children = (
				F96D3DF708F271BE004A47F5 /* Tk Sources */,
				F96D3DF608F27169004A47F5 /* Tcl Sources */,
				F966C06F08F281DC005CB29B /* Frameworks */,
				1AB674ADFE9D54B511CA2CBB /* Products */,
			);
			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <[email protected]>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n";
			name = Tk;
			path = .;
			sourceTree = SOURCE_ROOT;
		};
		1AB674ADFE9D54B511CA2CBB /* Products */ = {
			isa = PBXGroup;
			children = (
				F9A3084B08F2D4CE00BAE1AB /* Wish.app */,
				F9A3082D08F2D4AB00BAE1AB /* Tk.framework */,
				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
				8DD76FB20486AB0100D96B5E /* tktest */,
				F9FD31F40CC1AD070073837D /* tktest-X11 */,
			);
			includeInIndex = 0;
			name = Products;
			sourceTree = "<group>";
		};
		F9183E690EFC81560030B814 /* pkgs */ = {
			isa = PBXGroup;
			children = (
				F9183E6A0EFC81560030B814 /* README */,
				F946FB8B0FBE3AED00CD6495 /* itcl */,
				F9183E8F0EFC817B0030B814 /* tdbc */,
			);
			path = pkgs;
			sourceTree = "<group>";
		};
		F966BA0308F27A37005CB29B /* bitmaps */ = {
			isa = PBXGroup;
			children = (
				F966BA0408F27A37005CB29B /* error.xbm */,
				F966BA0508F27A37005CB29B /* gray12.xbm */,
				F966BA0608F27A37005CB29B /* gray25.xbm */,
				F966BA0708F27A37005CB29B /* gray50.xbm */,
				F966BA0808F27A37005CB29B /* gray75.xbm */,
				F966BA0908F27A37005CB29B /* hourglass.xbm */,
				F966BA0A08F27A37005CB29B /* info.xbm */,
				F966BA0B08F27A37005CB29B /* questhead.xbm */,
				F966BA0C08F27A37005CB29B /* question.xbm */,
				F966BA0D08F27A37005CB29B /* warning.xbm */,
			);
			path = bitmaps;
			sourceTree = "<group>";
		};
		F966BA1008F27A37005CB29B /* doc */ = {
			isa = PBXGroup;
			children = (
				F966BA1108F27A37005CB29B /* 3DBorder.3 */,
				F966BA1208F27A37005CB29B /* AddOption.3 */,
				F966BA1308F27A37005CB29B /* bell.n */,
				F966BA1408F27A37005CB29B /* bind.n */,
				F966BA1508F27A37005CB29B /* BindTable.3 */,
				F966BA1608F27A37005CB29B /* bindtags.n */,
				F966BA1708F27A37005CB29B /* bitmap.n */,
				F966BA1808F27A37005CB29B /* button.n */,
				F966BA1908F27A37005CB29B /* canvas.n */,
				F966BA1A08F27A37005CB29B /* CanvPsY.3 */,
				F966BA1B08F27A37005CB29B /* CanvTkwin.3 */,
				F966BA1C08F27A37005CB29B /* CanvTxtInfo.3 */,
				F966BA1D08F27A37005CB29B /* checkbutton.n */,
				F966BA1E08F27A37005CB29B /* chooseColor.n */,
				F966BA1F08F27A37005CB29B /* chooseDirectory.n */,
				F966BA2008F27A37005CB29B /* Clipboard.3 */,
				F966BA2108F27A37005CB29B /* clipboard.n */,
				F966BA2208F27A37005CB29B /* ClrSelect.3 */,
				F966BA2308F27A37005CB29B /* colors.n */,
				F966BA2408F27A37005CB29B /* ConfigWidg.3 */,
				F966BA2508F27A37005CB29B /* ConfigWind.3 */,
				F966BA2608F27A37005CB29B /* console.n */,
				F966BA2708F27A37005CB29B /* CoordToWin.3 */,
				F966BA2808F27A37005CB29B /* CrtCmHdlr.3 */,
				F966BA2908F27A37005CB29B /* CrtErrHdlr.3 */,
				F966BA2A08F27A37005CB29B /* CrtGenHdlr.3 */,
				F966BA2B08F27A37005CB29B /* CrtImgType.3 */,
				F966BA2C08F27A37005CB29B /* CrtItemType.3 */,
				F966BA2D08F27A37005CB29B /* CrtPhImgFmt.3 */,
				F966BA2E08F27A37005CB29B /* CrtSelHdlr.3 */,
				F966BA2F08F27A37005CB29B /* CrtWindow.3 */,
				F966BA3008F27A37005CB29B /* cursors.n */,
				F966BA3108F27A37005CB29B /* DeleteImg.3 */,
				F966BA3208F27A37005CB29B /* destroy.n */,
				F966BA3308F27A37005CB29B /* dialog.n */,
				F966BA3408F27A37005CB29B /* DrawFocHlt.3 */,
				F966BA3508F27A37005CB29B /* entry.n */,
				F966BA3608F27A37005CB29B /* event.n */,
				F966BA3708F27A37005CB29B /* EventHndlr.3 */,
				F966BA3808F27A37005CB29B /* FindPhoto.3 */,
				F966BA3908F27A37005CB29B /* focus.n */,
				F966BA3A08F27A37005CB29B /* focusNext.n */,
				F966BA3B08F27A37005CB29B /* font.n */,
				F9C888C20EEF6571003F63AD /* fontchooser.n */,
				F966BA3C08F27A37005CB29B /* FontId.3 */,
				F966BA3D08F27A37005CB29B /* frame.n */,
				F966BA3E08F27A37005CB29B /* FreeXId.3 */,
				F966BA3F08F27A37005CB29B /* GeomReq.3 */,
				F966BA4008F27A37005CB29B /* GetAnchor.3 */,
				F966BA4108F27A37005CB29B /* GetBitmap.3 */,
				F966BA4208F27A37005CB29B /* GetCapStyl.3 */,
				F966BA4308F27A37005CB29B /* GetClrmap.3 */,
				F966BA4408F27A37005CB29B /* GetColor.3 */,
				F966BA4508F27A37005CB29B /* GetCursor.3 */,
				F966BA4608F27A37005CB29B /* GetDash.3 */,
				F966BA4708F27A37005CB29B /* GetFont.3 */,
				F966BA4808F27A37005CB29B /* GetGC.3 */,
				F966BA4908F27A37005CB29B /* GetHINSTANCE.3 */,
				F966BA4A08F27A37005CB29B /* GetHWND.3 */,
				F966BA4B08F27A37005CB29B /* GetImage.3 */,
				F966BA4C08F27A37005CB29B /* GetJoinStl.3 */,
				F966BA4D08F27A37005CB29B /* GetJustify.3 */,
				F966BA4E08F27A37005CB29B /* getOpenFile.n */,
				F966BA4F08F27A37005CB29B /* GetOption.3 */,
				F966BA5008F27A38005CB29B /* GetPixels.3 */,
				F966BA5108F27A38005CB29B /* GetPixmap.3 */,
				F966BA5208F27A38005CB29B /* GetRelief.3 */,
				F966BA5308F27A38005CB29B /* GetRootCrd.3 */,
				F966BA5408F27A38005CB29B /* GetScroll.3 */,
				F966BA5508F27A38005CB29B /* GetSelect.3 */,
				F966BA5608F27A38005CB29B /* GetUid.3 */,
				F966BA5708F27A38005CB29B /* GetVisual.3 */,
				F966BA5808F27A38005CB29B /* GetVRoot.3 */,
				F966BA5908F27A38005CB29B /* Grab.3 */,
				F966BA5A08F27A38005CB29B /* grab.n */,
				F966BA5B08F27A38005CB29B /* grid.n */,
				F966BA5C08F27A38005CB29B /* HandleEvent.3 */,
				F966BA5D08F27A38005CB29B /* HWNDToWindow.3 */,
				F966BA5E08F27A38005CB29B /* IdToWindow.3 */,
				F966BA5F08F27A38005CB29B /* image.n */,
				F966BA6008F27A38005CB29B /* ImgChanged.3 */,
				F966BA6108F27A38005CB29B /* Inactive.3 */,
				F966BA6208F27A38005CB29B /* InternAtom.3 */,
				F966BA6308F27A38005CB29B /* keysyms.n */,
				F966BA6408F27A38005CB29B /* label.n */,
				F966BA6508F27A38005CB29B /* labelframe.n */,
				F966BA6608F27A38005CB29B /* listbox.n */,
				F966BA6708F27A38005CB29B /* loadTk.n */,
				F966BA6808F27A38005CB29B /* lower.n */,
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,
				F966BA7108F27A38005CB29B /* menubar.n */,
				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,
				F966BA7C08F27A38005CB29B /* pack-old.n */,
				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,
				F966BA8408F27A38005CB29B /* QWinEvent.3 */,
				F966BA8508F27A38005CB29B /* radiobutton.n */,
				F966BA8608F27A38005CB29B /* raise.n */,
				F966BA8708F27A38005CB29B /* Restack.3 */,
				F966BA8808F27A38005CB29B /* RestrictEv.3 */,
				F966BA8908F27A38005CB29B /* scale.n */,
				F966BA8A08F27A38005CB29B /* scrollbar.n */,
				F966BA8B08F27A38005CB29B /* selection.n */,
				F966BA8C08F27A38005CB29B /* send.n */,
				F966BA8D08F27A38005CB29B /* SetAppName.3 */,
				F966BA8E08F27A38005CB29B /* SetCaret.3 */,
				F966BA8F08F27A38005CB29B /* SetClass.3 */,
				F966BA9008F27A38005CB29B /* SetClassProcs.3 */,
				F966BA9108F27A38005CB29B /* SetGrid.3 */,
				F966BA9208F27A38005CB29B /* SetOptions.3 */,
				F966BA9308F27A38005CB29B /* SetVisual.3 */,
				F966BA9408F27A38005CB29B /* spinbox.n */,
				F966BA9508F27A38005CB29B /* StrictMotif.3 */,
				F966BA9608F27A38005CB29B /* text.n */,
				F966BA9708F27A38005CB29B /* TextLayout.3 */,
				F966BA9808F27A38005CB29B /* tk.n */,
				F966BA9A08F27A38005CB29B /* Tk_Init.3 */,
				F966BA9B08F27A38005CB29B /* Tk_Main.3 */,
				F966BA9C08F27A38005CB29B /* tkerror.n */,
				F966BA9D08F27A38005CB29B /* TkInitStubs.3 */,
				F966BA9E08F27A38005CB29B /* tkvars.n */,
				F966BA9F08F27A38005CB29B /* tkwait.n */,
				F966BAA008F27A38005CB29B /* toplevel.n */,
				F968886B0AF788F6000797B5 /* ttk_button.n */,
				F968886C0AF788F6000797B5 /* ttk_checkbutton.n */,
				F968886D0AF788F6000797B5 /* ttk_combobox.n */,
				F968886F0AF788F6000797B5 /* ttk_entry.n */,
				F96888700AF788F6000797B5 /* ttk_frame.n */,
				F96888710AF788F6000797B5 /* ttk_Geometry.3 */,
				F96888720AF788F6000797B5 /* ttk_image.n */,
				F96888730AF788F6000797B5 /* ttk_intro.n */,
				F96888740AF788F6000797B5 /* ttk_label.n */,
				F96888750AF788F6000797B5 /* ttk_labelframe.n */,
				F96888760AF788F6000797B5 /* ttk_menubutton.n */,
				F96888770AF788F6000797B5 /* ttk_notebook.n */,
				F96888780AF788F6000797B5 /* ttk_panedwindow.n */,
				F96888790AF788F6000797B5 /* ttk_progressbar.n */,
				F968887A0AF788F6000797B5 /* ttk_radiobutton.n */,
				F968887B0AF788F6000797B5 /* ttk_scrollbar.n */,
				F968887C0AF788F6000797B5 /* ttk_separator.n */,
				F968887D0AF788F6000797B5 /* ttk_sizegrip.n */,
				F968887E0AF788F6000797B5 /* ttk_style.n */,
				F968887F0AF788F6000797B5 /* ttk_Theme.3 */,
				F96888800AF788F6000797B5 /* ttk_treeview.n */,
				F96888810AF788F6000797B5 /* ttk_widget.n */,
				F966BAA108F27A38005CB29B /* WindowId.3 */,
				F966BAA208F27A38005CB29B /* winfo.n */,
				F966BAA308F27A38005CB29B /* wish.1 */,
				F966BAA408F27A38005CB29B /* wm.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F966BAA508F27A38005CB29B /* generic */ = {
			isa = PBXGroup;
			children = (
				F966BAA608F27A38005CB29B /* default.h */,
				F966BAA708F27A38005CB29B /* ks_names.h */,
				F966BAA908F27A39005CB29B /* README */,
				F966BAAA08F27A39005CB29B /* tk.decls */,
				F966BAAB08F27A39005CB29B /* tk.h */,
				F966BAAC08F27A39005CB29B /* tk3d.c */,
				F966BAAD08F27A39005CB29B /* tk3d.h */,
				F966BAAE08F27A39005CB29B /* tkArgv.c */,
				F966BAAF08F27A39005CB29B /* tkAtom.c */,
				F966BAB008F27A39005CB29B /* tkBind.c */,
				F966BAB108F27A39005CB29B /* tkBitmap.c */,
				F9152B080EAF8A5000CD5C7B /* tkBusy.c */,
				F966BAB208F27A39005CB29B /* tkButton.c */,
				F966BAB308F27A39005CB29B /* tkButton.h */,
				F966BAB408F27A39005CB29B /* tkCanvArc.c */,
				F966BAB508F27A39005CB29B /* tkCanvas.c */,
				F966BAB608F27A39005CB29B /* tkCanvas.h */,
				F966BAB708F27A39005CB29B /* tkCanvBmap.c */,
				F966BAB808F27A39005CB29B /* tkCanvImg.c */,
				F966BAB908F27A39005CB29B /* tkCanvLine.c */,
				F966BABA08F27A39005CB29B /* tkCanvPoly.c */,
				F966BABB08F27A39005CB29B /* tkCanvPs.c */,
				F966BABD08F27A39005CB29B /* tkCanvText.c */,
				F966BABE08F27A39005CB29B /* tkCanvUtil.c */,
				F966BABF08F27A39005CB29B /* tkCanvWind.c */,
				F966BAC008F27A39005CB29B /* tkClipboard.c */,
				F966BAC108F27A39005CB29B /* tkCmds.c */,
				F966BAC208F27A39005CB29B /* tkColor.c */,
				F966BAC308F27A39005CB29B /* tkColor.h */,
				F966BAC408F27A39005CB29B /* tkConfig.c */,
				F966BAC508F27A39005CB29B /* tkConsole.c */,
				F966BAC608F27A39005CB29B /* tkCursor.c */,
				F966BAC708F27A39005CB29B /* tkDecls.h */,
				F966BAC808F27A39005CB29B /* tkEntry.c */,
				F966BAC908F27A39005CB29B /* tkEntry.h */,
				F966BACA08F27A39005CB29B /* tkError.c */,
				F966BACB08F27A39005CB29B /* tkEvent.c */,
				F966BACC08F27A39005CB29B /* tkFileFilter.c */,
				F966BACD08F27A39005CB29B /* tkFileFilter.h */,
				F966BACE08F27A39005CB29B /* tkFocus.c */,
				F966BACF08F27A39005CB29B /* tkFont.c */,
				F966BAD008F27A39005CB29B /* tkFont.h */,
				F966BAD108F27A39005CB29B /* tkFrame.c */,
				F966BAD208F27A39005CB29B /* tkGC.c */,
				F966BAD308F27A39005CB29B /* tkGeometry.c */,
				F966BAD408F27A39005CB29B /* tkGet.c */,
				F966BAD508F27A39005CB29B /* tkGrab.c */,
				F966BAD608F27A39005CB29B /* tkGrid.c */,
				F966BAD708F27A39005CB29B /* tkImage.c */,
				F966BAD808F27A39005CB29B /* tkImgBmap.c */,
				F966BAD908F27A39005CB29B /* tkImgGIF.c */,
				F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */,
				F966BADA08F27A39005CB29B /* tkImgPhoto.c */,
				F9DD99BC0F07DF850018B2E4 /* tkImgPNG.c */,
				F966BADB08F27A39005CB29B /* tkImgPPM.c */,
				F966BADC08F27A39005CB29B /* tkImgUtil.c */,
				F966BADE08F27A39005CB29B /* tkInt.decls */,
				F966BADF08F27A39005CB29B /* tkInt.h */,
				F966BAE108F27A39005CB29B /* tkIntDecls.h */,
				F966BAE208F27A39005CB29B /* tkIntPlatDecls.h */,
				F966BAE308F27A39005CB29B /* tkIntXlibDecls.h */,
				F966BAE408F27A39005CB29B /* tkListbox.c */,
				F966BAE508F27A39005CB29B /* tkMacWinMenu.c */,
				F966BAE608F27A39005CB29B /* tkMain.c */,
				F966BAE708F27A39005CB29B /* tkMenu.c */,
				F966BAE808F27A39005CB29B /* tkMenu.h */,
				F966BAE908F27A39005CB29B /* tkMenubutton.c */,
				F966BAEA08F27A39005CB29B /* tkMenubutton.h */,
				F966BAEB08F27A39005CB29B /* tkMenuDraw.c */,
				F966BAEC08F27A39005CB29B /* tkMessage.c */,
				F966BAED08F27A39005CB29B /* tkObj.c */,
				F966BAEE08F27A39005CB29B /* tkOldConfig.c */,
				F966BAEF08F27A39005CB29B /* tkOption.c */,
				F966BAF008F27A39005CB29B /* tkPack.c */,
				F966BAF108F27A39005CB29B /* tkPanedWindow.c */,
				F966BAF208F27A39005CB29B /* tkPlace.c */,
				F966BAF308F27A39005CB29B /* tkPlatDecls.h */,
				F966BAF408F27A39005CB29B /* tkPointer.c */,
				F966BAF508F27A39005CB29B /* tkPort.h */,
				F966BAF608F27A39005CB29B /* tkRectOval.c */,
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,
				F966BAFE08F27A39005CB29B /* tkOldTest.c */,
				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,
				F966BB0608F27A39005CB29B /* tkTextDisp.c */,
				F966BB0808F27A39005CB29B /* tkTextImage.c */,
				F966BB0908F27A39005CB29B /* tkTextIndex.c */,
				F966BB0A08F27A39005CB29B /* tkTextMark.c */,
				F966BB0B08F27A39005CB29B /* tkTextTag.c */,
				F966BB0C08F27A39005CB29B /* tkTextWind.c */,
				F966BB0D08F27A39005CB29B /* tkTrig.c */,
				F966BB0E08F27A39005CB29B /* tkUndo.c */,
				F966BB0F08F27A39005CB29B /* tkUndo.h */,
				F966BB1008F27A39005CB29B /* tkUtil.c */,
				F966BB1108F27A39005CB29B /* tkVisual.c */,
				F966BB1208F27A39005CB29B /* tkWindow.c */,
				F96887DF0AF786D5000797B5 /* ttk */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F966BB1308F27A39005CB29B /* library */ = {
			isa = PBXGroup;
			children = (
				F966BB1408F27A39005CB29B /* bgerror.tcl */,
				F966BB1508F27A39005CB29B /* button.tcl */,
				F966BB1608F27A39005CB29B /* choosedir.tcl */,
				F966BB1708F27A39005CB29B /* clrpick.tcl */,
				F966BB1808F27A39005CB29B /* comdlg.tcl */,
				F966BB1908F27A39005CB29B /* console.tcl */,
				F966BB1A08F27A39005CB29B /* demos */,
				F966BB6208F27A3A005CB29B /* dialog.tcl */,
				F966BB6308F27A3A005CB29B /* entry.tcl */,
				F966BB6408F27A3A005CB29B /* focus.tcl */,
				F99388380EE0114B0065FE6B /* fontchooser.tcl */,
				F974D57C0FBE7EFF00BF728B /* iconlist.tcl */,
				F974D57D0FBE7EFF00BF728B /* icons.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,
				F966BB8608F27A3A005CB29B /* obsolete.tcl */,
				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,
				F966BB9408F27A3B005CB29B /* unsupported.tcl */,
				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;
			children = (
				F966BB1B08F27A39005CB29B /* anilabel.tcl */,
				F966BB1C08F27A39005CB29B /* aniwave.tcl */,
				F966BB1D08F27A39005CB29B /* arrow.tcl */,
				F966BB1E08F27A39005CB29B /* bind.tcl */,
				F966BB1F08F27A39005CB29B /* bitmap.tcl */,
				F966BB2008F27A39005CB29B /* browse */,
				F966BB2108F27A39005CB29B /* button.tcl */,
				F966BB2208F27A39005CB29B /* check.tcl */,
				F966BB2308F27A39005CB29B /* clrpick.tcl */,
				F966BB2408F27A39005CB29B /* colors.tcl */,
				F936FCDB0CCD984600716967 /* combo.tcl */,
				F966BB2508F27A39005CB29B /* cscroll.tcl */,
				F966BB2608F27A39005CB29B /* ctext.tcl */,
				F966BB2708F27A39005CB29B /* dialog1.tcl */,
				F966BB2808F27A39005CB29B /* dialog2.tcl */,
				F966BB2A08F27A39005CB29B /* entry1.tcl */,
				F966BB2B08F27A39005CB29B /* entry2.tcl */,
				F966BB2C08F27A39005CB29B /* entry3.tcl */,
				F966BB2D08F27A39005CB29B /* filebox.tcl */,
				F966BB2E08F27A39005CB29B /* floor.tcl */,
				F91543270EF201A90032D1E8 /* fontchoose.tcl */,
				F966BB2F08F27A39005CB29B /* form.tcl */,
				F966BB3008F27A39005CB29B /* goldberg.tcl */,
				F966BB3108F27A39005CB29B /* hello */,
				F966BB3208F27A39005CB29B /* hscale.tcl */,
				F966BB3308F27A39005CB29B /* icon.tcl */,
				F966BB3408F27A39005CB29B /* image1.tcl */,
				F966BB3508F27A39005CB29B /* image2.tcl */,
				F966BB4208F27A3A005CB29B /* items.tcl */,
				F966BB4308F27A3A005CB29B /* ixset */,
				F92240290D7C620F005EC715 /* knightstour.tcl */,
				F966BB4408F27A3A005CB29B /* label.tcl */,
				F966BB4508F27A3A005CB29B /* labelframe.tcl */,
				F9D1360A0CDC252C00DBE0B5 /* mclist.tcl */,
				F966BB4608F27A3A005CB29B /* menu.tcl */,
				F966BB4708F27A3A005CB29B /* menubu.tcl */,
				F966BB4808F27A3A005CB29B /* msgbox.tcl */,
				F966BB4A08F27A3A005CB29B /* paned1.tcl */,
				F966BB4B08F27A3A005CB29B /* paned2.tcl */,
				F966BB4C08F27A3A005CB29B /* pendulum.tcl */,
				F966BB4D08F27A3A005CB29B /* plot.tcl */,
				F966BB4E08F27A3A005CB29B /* puzzle.tcl */,
				F966BB4F08F27A3A005CB29B /* radio.tcl */,
				F966BB5008F27A3A005CB29B /* README */,
				F966BB5108F27A3A005CB29B /* rmt */,
				F966BB5208F27A3A005CB29B /* rolodex */,
				F966BB5308F27A3A005CB29B /* ruler.tcl */,
				F966BB5408F27A3A005CB29B /* sayings.tcl */,
				F966BB5508F27A3A005CB29B /* search.tcl */,
				F966BB5608F27A3A005CB29B /* spin.tcl */,
				F966BB5708F27A3A005CB29B /* square */,
				F966BB5808F27A3A005CB29B /* states.tcl */,
				F966BB5908F27A3A005CB29B /* style.tcl */,
				F966BB5A08F27A3A005CB29B /* tclIndex */,
				F966BB5B08F27A3A005CB29B /* tcolor */,
				F966BB5C08F27A3A005CB29B /* text.tcl */,
				F9099B8A0CC67D30005A9580 /* textpeer.tcl */,
				F966BB5D08F27A3A005CB29B /* timer */,
				F936FCD90CCD984600716967 /* toolbar.tcl */,
				F936FCD80CCD984600716967 /* tree.tcl */,
				F9099B8B0CC67D3E005A9580 /* ttkbut.tcl */,
				F9F4EFDD0CC7B3CB00378A27 /* ttkmenu.tcl */,
				F936FCDA0CCD984600716967 /* ttknote.tcl */,
				F9F4EFDC0CC7B3CA00378A27 /* ttkpane.tcl */,
				F936FCD70CCD984500716967 /* ttkprogress.tcl */,
				F966BB5E08F27A3A005CB29B /* twind.tcl */,
				F966BB5F08F27A3A005CB29B /* unicodeout.tcl */,
				F966BB6008F27A3A005CB29B /* vscale.tcl */,
				F966BB6108F27A3A005CB29B /* widget */,
			);
			path = demos;
			sourceTree = "<group>";
		};
		F966BB9708F27A3B005CB29B /* macosx */ = {
			isa = PBXGroup;
			children = (
				F966BBBA08F27A3B005CB29B /* configure.ac */,
				F966BBBB08F27A3B005CB29B /* GNUmakefile */,
				F966BBBE08F27A3B005CB29B /* README */,
				F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */,
				F966BBC208F27A3B005CB29B /* tkMacOSX.h */,
				F966BBC508F27A3B005CB29B /* tkMacOSXBitmap.c */,
				F966BBC608F27A3B005CB29B /* tkMacOSXButton.c */,
				F966BBC808F27A3B005CB29B /* tkMacOSXClipboard.c */,
				F966BBC908F27A3B005CB29B /* tkMacOSXColor.c */,
				F966BBCA08F27A3B005CB29B /* tkMacOSXConfig.c */,
				F966BBCB08F27A3B005CB29B /* tkMacOSXCursor.c */,
				F966BBCC08F27A3B005CB29B /* tkMacOSXCursors.h */,
				F966BBCD08F27A3B005CB29B /* tkMacOSXDebug.c */,
				F966BBCE08F27A3B005CB29B /* tkMacOSXDebug.h */,
				F966BBCF08F27A3B005CB29B /* tkMacOSXDefault.h */,
				F966BBD008F27A3B005CB29B /* tkMacOSXDialog.c */,
				F966BBD108F27A3B005CB29B /* tkMacOSXDraw.c */,
				F966BBD208F27A3B005CB29B /* tkMacOSXEmbed.c */,
				F966BBD308F27A3B005CB29B /* tkMacOSXEntry.c */,
				F966BBD408F27A3B005CB29B /* tkMacOSXEvent.c */,
				F966BBD608F27A3B005CB29B /* tkMacOSXFont.c */,
				F93E5EFD09CF8711008FA367 /* tkMacOSXFont.h */,
				F966BBD708F27A3B005CB29B /* tkMacOSXHLEvents.c */,
				F966BBD808F27A3B005CB29B /* tkMacOSXInit.c */,
				F966BBDA08F27A3B005CB29B /* tkMacOSXInt.h */,
				F966BBDB08F27A3B005CB29B /* tkMacOSXKeyboard.c */,
				F966BBDC08F27A3B005CB29B /* tkMacOSXKeyEvent.c */,
				F966BBDD08F27A3B005CB29B /* tkMacOSXMenu.c */,
				F966BBE008F27A3B005CB29B /* tkMacOSXMenubutton.c */,
				F966BBE108F27A3B005CB29B /* tkMacOSXMenus.c */,
				F966BBE208F27A3B005CB29B /* tkMacOSXMouseEvent.c */,
				F966BBE308F27A3B005CB29B /* tkMacOSXNotify.c */,
				F966BBEA08F27A3C005CB29B /* tkMacOSXPort.h */,
				F976F6A70C325FB6005066D9 /* tkMacOSXPrivate.h */,
				F966BBEB08F27A3C005CB29B /* tkMacOSXRegion.c */,
				F966BBEC08F27A3C005CB29B /* tkMacOSXScale.c */,
				F966BBED08F27A3C005CB29B /* tkMacOSXScrlbr.c */,
				F966BBEE08F27A3C005CB29B /* tkMacOSXSend.c */,
				F966BBEF08F27A3C005CB29B /* tkMacOSXSubwindows.c */,
				F966BBF008F27A3C005CB29B /* tkMacOSXTest.c */,
				F966BBF108F27A3C005CB29B /* tkMacOSXWindowEvent.c */,
				F966BBF208F27A3C005CB29B /* tkMacOSXWm.c */,
				F966BBF308F27A3C005CB29B /* tkMacOSXWm.h */,
				F966BBF408F27A3C005CB29B /* tkMacOSXXCursors.h */,
				F966BBF508F27A3C005CB29B /* tkMacOSXXStubs.c */,
				F96888840AF78938000797B5 /* ttkMacOSXTheme.c */,
				F95D8D4B0F1715610006B020 /* Tk.icns */,
				F95D8D4C0F1715610006B020 /* Tk.tiff */,
				F966BBF708F27A3C005CB29B /* Wish-Info.plist.in */,
				F97590AE1039A96200558A9A /* Wish.sdef */,
				F97AE7F10B65C1E900310EA2 /* Tk-Common.xcconfig */,
				F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */,
				F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F966BC0408F27A3C005CB29B /* tests */ = {
			isa = PBXGroup;
			children = (
				F966BC0508F27A3C005CB29B /* all.tcl */,
				F966BC0608F27A3C005CB29B /* arc.tcl */,
				F966BC0708F27A3C005CB29B /* bell.test */,
				F966BC0808F27A3C005CB29B /* bevel.tcl */,
				F966BC0908F27A3C005CB29B /* bgerror.test */,
				F966BC0A08F27A3C005CB29B /* bind.test */,
				F966BC0B08F27A3C005CB29B /* bitmap.test */,
				F966BC0C08F27A3C005CB29B /* border.test */,
				F966BC0D08F27A3C005CB29B /* bugs.tcl */,
				F966BC0E08F27A3C005CB29B /* butGeom.tcl */,
				F966BC0F08F27A3C005CB29B /* butGeom2.tcl */,
				F966BC1008F27A3C005CB29B /* button.test */,
				F966BC1108F27A3C005CB29B /* canvas.test */,
				F966BC1208F27A3C005CB29B /* canvImg.test */,
				F966BC1308F27A3C005CB29B /* canvPs.test */,
				F966BC1408F27A3C005CB29B /* canvPsArc.tcl */,
				F966BC1508F27A3C005CB29B /* canvPsBmap.tcl */,
				F966BC1608F27A3C005CB29B /* canvPsGrph.tcl */,
				F966BC1708F27A3C005CB29B /* canvPsImg.tcl */,
				F966BC1808F27A3C005CB29B /* canvPsText.tcl */,
				F966BC1908F27A3C005CB29B /* canvRect.test */,
				F966BC1A08F27A3C005CB29B /* canvText.test */,
				F966BC1B08F27A3C005CB29B /* canvWind.test */,
				F966BC1C08F27A3C005CB29B /* choosedir.test */,
				F966BC1D08F27A3C005CB29B /* clipboard.test */,
				F966BC1E08F27A3C005CB29B /* clrpick.test */,
				F966BC1F08F27A3C005CB29B /* cmap.tcl */,
				F966BC2008F27A3C005CB29B /* cmds.test */,
				F966BC2108F27A3C005CB29B /* color.test */,
				F966BC2208F27A3C005CB29B /* config.test */,
				F966BC2308F27A3C005CB29B /* constraints.tcl */,
				F966BC2408F27A3C005CB29B /* cursor.test */,
				F966BC2508F27A3C005CB29B /* dialog.test */,
				F966BC2608F27A3C005CB29B /* embed.test */,
				F966BC2708F27A3C005CB29B /* entry.test */,
				F966BC2808F27A3C005CB29B /* event.test */,
				F966BC2908F27A3C005CB29B /* filebox.test */,
				F966BC2A08F27A3C005CB29B /* focus.test */,
				F966BC2B08F27A3C005CB29B /* focusTcl.test */,
				F966BC2C08F27A3C005CB29B /* font.test */,
				F99388950EE02D980065FE6B /* fontchooser.test */,
				F966BC2D08F27A3C005CB29B /* frame.test */,
				F966BC2E08F27A3C005CB29B /* geometry.test */,
				F966BC2F08F27A3C005CB29B /* get.test */,
				F966BC3008F27A3C005CB29B /* grab.test */,
				F966BC3108F27A3C005CB29B /* grid.test */,
				F966BC3308F27A3C005CB29B /* image.test */,
				F966BC3408F27A3C005CB29B /* imgBmap.test */,
				F966BC3508F27A3C005CB29B /* imgPhoto.test */,
				F9DD99BF0F07DFCD0018B2E4 /* imgPNG.test */,
				F966BC3608F27A3C005CB29B /* imgPPM.test */,
				F966BC3708F27A3C005CB29B /* listbox.test */,
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,
				F966BC3F08F27A3C005CB29B /* oldpack.test */,
				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,
				F966BC4708F27A3D005CB29B /* README */,
				F966BC4808F27A3D005CB29B /* safe.test */,
				F966BC4908F27A3D005CB29B /* scale.test */,
				F966BC4A08F27A3D005CB29B /* scrollbar.test */,
				F966BC4B08F27A3D005CB29B /* select.test */,
				F966BC4C08F27A3D005CB29B /* send.test */,
				F966BC4D08F27A3D005CB29B /* spinbox.test */,
				F966BC4E08F27A3D005CB29B /* text.test */,
				F966BC4F08F27A3D005CB29B /* textBTree.test */,
				F966BC5008F27A3D005CB29B /* textDisp.test */,
				F966BC5108F27A3D005CB29B /* textImage.test */,
				F966BC5208F27A3D005CB29B /* textIndex.test */,
				F966BC5308F27A3D005CB29B /* textMark.test */,
				F966BC5408F27A3D005CB29B /* textTag.test */,
				F966BC5508F27A3D005CB29B /* textWind.test */,
				F966BC5608F27A3D005CB29B /* tk.test */,
				F96888530AF7880C000797B5 /* ttk */,
				F966BC5708F27A3D005CB29B /* unixButton.test */,
				F966BC5808F27A3D005CB29B /* unixEmbed.test */,
				F966BC5908F27A3D005CB29B /* unixFont.test */,
				F966BC5A08F27A3D005CB29B /* unixMenu.test */,
				F966BC5B08F27A3D005CB29B /* unixSelect.test */,
				F966BC5C08F27A3D005CB29B /* unixWm.test */,
				F966BC5D08F27A3D005CB29B /* util.test */,
				F966BC5E08F27A3D005CB29B /* visual.test */,
				F966BC5F08F27A3D005CB29B /* visual_bb.test */,
				F966BC6008F27A3D005CB29B /* winButton.test */,
				F966BC6108F27A3D005CB29B /* winClipboard.test */,
				F966BC6208F27A3D005CB29B /* winDialog.test */,
				F966BC6308F27A3D005CB29B /* window.test */,
				F966BC6408F27A3D005CB29B /* winfo.test */,
				F966BC6508F27A3D005CB29B /* winFont.test */,
				F966BC6608F27A3D005CB29B /* winMenu.test */,
				F966BC6708F27A3D005CB29B /* winSend.test */,
				F966BC6808F27A3D005CB29B /* winWm.test */,
				F966BC6908F27A3D005CB29B /* wm.test */,
				F966BC6A08F27A3D005CB29B /* xmfbox.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.ac */,
				F966BC6F08F27A3D005CB29B /* install-sh */,
				F966BC7008F27A3D005CB29B /* installManPage */,
				F966BC7108F27A3D005CB29B /* Makefile.in */,
				F966BC7208F27A3D005CB29B /* README */,
				F966BC7308F27A3D005CB29B /* tcl.m4 */,
				F974D57B0FBE7EC000BF728B /* tk.pc.in */,
				F966BC7408F27A3D005CB29B /* tk.spec */,
				F966BC7508F27A3D005CB29B /* tkAppInit.c */,
				F966BC7608F27A3D005CB29B /* tkConfig.h.in */,
				F966BC7708F27A3D005CB29B /* tkConfig.sh.in */,
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,
				F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */,
				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,
				F966BC8708F27A3D005CB29B /* tkUnixKey.c */,
				F966BC8808F27A3D005CB29B /* tkUnixMenu.c */,
				F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */,
				F966BC8A08F27A3D005CB29B /* tkUnixPort.h */,
				F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */,
				F966BC8C08F27A3D005CB29B /* tkUnixScale.c */,
				F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */,
				F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */,
				F966BC8F08F27A3D005CB29B /* tkUnixSend.c */,
				F966BC9008F27A3D005CB29B /* tkUnixWm.c */,
				F966BC9108F27A3D005CB29B /* tkUnixXId.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.ac */,
				F966BC9908F27A3E005CB29B /* Makefile.in */,
				F966BC9A08F27A3E005CB29B /* makefile.vc */,
				F966BC9C08F27A3E005CB29B /* nmakehlp.c */,
				F966BC9D08F27A3E005CB29B /* rc */,
				F966BCF308F27A3E005CB29B /* README */,
				F966BCF408F27A3E005CB29B /* rmd.bat */,
				F966BCF508F27A3F005CB29B /* rules.vc */,
				F966BCF608F27A3F005CB29B /* stubs.c */,
				F966BCF708F27A3F005CB29B /* tcl.m4 */,
				F966BCF808F27A3F005CB29B /* tkConfig.sh.in */,
				F966BCF908F27A3F005CB29B /* tkWin.h */,
				F966BCFA08F27A3F005CB29B /* tkWin32Dll.c */,
				F966BCFB08F27A3F005CB29B /* tkWin3d.c */,
				F966BCFC08F27A3F005CB29B /* tkWinButton.c */,
				F966BCFD08F27A3F005CB29B /* tkWinClipboard.c */,
				F966BCFE08F27A3F005CB29B /* tkWinColor.c */,
				F966BCFF08F27A3F005CB29B /* tkWinConfig.c */,
				F966BD0008F27A3F005CB29B /* tkWinCursor.c */,
				F966BD0108F27A3F005CB29B /* tkWinDefault.h */,
				F966BD0208F27A3F005CB29B /* tkWinDialog.c */,
				F966BD0308F27A3F005CB29B /* tkWinDraw.c */,
				F966BD0408F27A3F005CB29B /* tkWinEmbed.c */,
				F966BD0508F27A3F005CB29B /* tkWinFont.c */,
				F966BD0708F27A3F005CB29B /* tkWinImage.c */,
				F966BD0808F27A3F005CB29B /* tkWinInit.c */,
				F966BD0908F27A3F005CB29B /* tkWinInt.h */,
				F966BD0A08F27A3F005CB29B /* tkWinKey.c */,
				F966BD0B08F27A3F005CB29B /* tkWinMenu.c */,
				F966BD0C08F27A3F005CB29B /* tkWinPixmap.c */,
				F966BD0D08F27A3F005CB29B /* tkWinPointer.c */,
				F966BD0E08F27A3F005CB29B /* tkWinPort.h */,
				F966BD0F08F27A3F005CB29B /* tkWinRegion.c */,
				F966BD1008F27A3F005CB29B /* tkWinScrlbr.c */,
				F966BD1108F27A3F005CB29B /* tkWinSend.c */,
				F966BD1208F27A3F005CB29B /* tkWinSendCom.c */,
				F966BD1308F27A3F005CB29B /* tkWinSendCom.h */,
				F966BD1408F27A3F005CB29B /* tkWinTest.c */,
				F966BD1508F27A3F005CB29B /* tkWinWindow.c */,
				F966BD1608F27A3F005CB29B /* tkWinWm.c */,
				F966BD1708F27A3F005CB29B /* tkWinX.c */,
				F96888860AF78953000797B5 /* ttkWinMonitor.c */,
				F96888870AF78953000797B5 /* ttkWinTheme.c */,
				F96888880AF78953000797B5 /* ttkWinXPTheme.c */,
				F966BD1808F27A3F005CB29B /* winMain.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F966BC9D08F27A3E005CB29B /* rc */ = {
			isa = PBXGroup;
			children = (
				F966BCEE08F27A3E005CB29B /* tk.rc */,
				F966BCEF08F27A3E005CB29B /* tk_base.rc */,
				F966BCF208F27A3E005CB29B /* wish.rc */,
			);
			path = rc;
			sourceTree = "<group>";
		};
		F966BD1908F27A3F005CB29B /* xlib */ = {
			isa = PBXGroup;
			children = (
				F966BD1A08F27A3F005CB29B /* X11 */,
				F966BD2308F27A3F005CB29B /* xbytes.h */,
				F966BD2408F27A3F005CB29B /* xcolors.c */,
				F966BD2508F27A3F005CB29B /* xdraw.c */,
				F966BD2608F27A3F005CB29B /* xgc.c */,
				F966BD2708F27A3F005CB29B /* ximage.c */,
				F966BD2808F27A3F005CB29B /* xutil.c */,
			);
			path = xlib;
			sourceTree = "<group>";
		};
		F966BD1A08F27A3F005CB29B /* X11 */ = {
			isa = PBXGroup;
			children = (
				F966BD1B08F27A3F005CB29B /* cursorfont.h */,
				F966BD1C08F27A3F005CB29B /* keysym.h */,
				F966BD1D08F27A3F005CB29B /* keysymdef.h */,
				F966BD1E08F27A3F005CB29B /* X.h */,
				F966BD1F08F27A3F005CB29B /* Xatom.h */,
				F966BD2008F27A3F005CB29B /* Xfuncproto.h */,
				F966BD2108F27A3F005CB29B /* Xlib.h */,
				F966BD2208F27A3F005CB29B /* Xutil.h */,
			);
			path = X11;
			sourceTree = "<group>";
		};
		F966C06F08F281DC005CB29B /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				F9C9CBFF0E84059800E00935 /* ApplicationServices.framework */,
				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
				F96437E60EF0D652003F468E /* libz.dylib */,
				F966C07608F2821B005CB29B /* Carbon.framework */,
				F94523A10E6FC2AC00C1D987 /* Cocoa.framework */,
				F966C07808F28233005CB29B /* IOKit.framework */,
				F9FD32140CC1AF170073837D /* libX11.dylib */,
				F9FD32150CC1AF170073837D /* libXext.dylib */,
				F9FD32160CC1AF170073837D /* libXss.dylib */,
				F9FD349A0CC1BB0D0073837D /* libXft.dylib */,
				F9FD34990CC1BB0D0073837D /* libfreetype.dylib */,
				F9FD34C30CC1BBD70073837D /* libfontconfig.dylib */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		F96887DF0AF786D5000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96887E00AF786D5000797B5 /* ttk.decls */,
				F96887E10AF786D5000797B5 /* ttkBlink.c */,
				F96887E20AF786D5000797B5 /* ttkButton.c */,
				F96887E30AF786D5000797B5 /* ttkCache.c */,
				F96887E40AF786D5000797B5 /* ttkClamTheme.c */,
				F96887E50AF786D5000797B5 /* ttkClassicTheme.c */,
				F96887E60AF786D5000797B5 /* ttkDecls.h */,
				F96887E70AF786D5000797B5 /* ttkDefaultTheme.c */,
				F96887E80AF786D5000797B5 /* ttkElements.c */,
				F96887E90AF786D5000797B5 /* ttkEntry.c */,
				F96887EA0AF786D5000797B5 /* ttkFrame.c */,
				F96887EB0AF786D5000797B5 /* ttkImage.c */,
				F96887EC0AF786D5000797B5 /* ttkInit.c */,
				F96887ED0AF786D5000797B5 /* ttkLabel.c */,
				F96887EE0AF786D5000797B5 /* ttkLayout.c */,
				F96887EF0AF786D5000797B5 /* ttkManager.c */,
				F96887F00AF786D5000797B5 /* ttkManager.h */,
				F96887F10AF786D5000797B5 /* ttkNotebook.c */,
				F96887F20AF786D5000797B5 /* ttkPanedwindow.c */,
				F96887F30AF786D5000797B5 /* ttkProgress.c */,
				F96887F40AF786D5000797B5 /* ttkScale.c */,
				F96887F50AF786D5000797B5 /* ttkScroll.c */,
				F96887F60AF786D5000797B5 /* ttkScrollbar.c */,
				F96887F70AF786D5000797B5 /* ttkSeparator.c */,
				F96887F80AF786D5000797B5 /* ttkSquare.c */,
				F96887F90AF786D5000797B5 /* ttkState.c */,
				F96887FA0AF786D5000797B5 /* ttkStubInit.c */,
				F96887FB0AF786D5000797B5 /* ttkStubLib.c */,
				F96887FC0AF786D5000797B5 /* ttkTagSet.c */,
				F96887FD0AF786D5000797B5 /* ttkTheme.c */,
				F96887FE0AF786D5000797B5 /* ttkTheme.h */,
				F96887FF0AF786D5000797B5 /* ttkThemeInt.h */,
				F96888000AF786D5000797B5 /* ttkTrace.c */,
				F96888010AF786D5000797B5 /* ttkTrack.c */,
				F96888020AF786D5000797B5 /* ttkTreeview.c */,
				F96888030AF786D5000797B5 /* ttkWidget.c */,
				F96888040AF786D5000797B5 /* ttkWidget.h */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888360AF787B3000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888370AF787B3000797B5 /* altTheme.tcl */,
				F96888380AF787B3000797B5 /* aquaTheme.tcl */,
				F96888390AF787B3000797B5 /* button.tcl */,
				F968883A0AF787B3000797B5 /* clamTheme.tcl */,
				F968883B0AF787B3000797B5 /* classicTheme.tcl */,
				F968883C0AF787B3000797B5 /* combobox.tcl */,
				F968883D0AF787B3000797B5 /* cursors.tcl */,
				F968883E0AF787B3000797B5 /* defaults.tcl */,
				F96888400AF787B3000797B5 /* entry.tcl */,
				F96888410AF787B3000797B5 /* fonts.tcl */,
				F96888440AF787B3000797B5 /* menubutton.tcl */,
				F96888450AF787B3000797B5 /* notebook.tcl */,
				F96888460AF787B3000797B5 /* panedwindow.tcl */,
				F96888470AF787B3000797B5 /* progress.tcl */,
				F96888480AF787B3000797B5 /* scale.tcl */,
				F96888490AF787B3000797B5 /* scrollbar.tcl */,
				F968884A0AF787B3000797B5 /* sizegrip.tcl */,
				F968884B0AF787B3000797B5 /* treeview.tcl */,
				F968884C0AF787B3000797B5 /* ttk.tcl */,
				F968884D0AF787B3000797B5 /* utils.tcl */,
				F968884E0AF787B3000797B5 /* winTheme.tcl */,
				F973E5960EE99384001A648E /* vistaTheme.tcl */,
				F968884F0AF787B3000797B5 /* xpTheme.tcl */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96888530AF7880C000797B5 /* ttk */ = {
			isa = PBXGroup;
			children = (
				F96888540AF7880C000797B5 /* all.tcl */,
				F98383650F0FA43900171CA6 /* checkbutton.test */,
				F96888560AF7880C000797B5 /* combobox.test */,
				F96888570AF7880C000797B5 /* entry.test */,
				F96888580AF7880C000797B5 /* image.test */,
				F96888590AF7880C000797B5 /* labelframe.test */,
				F968885A0AF7880C000797B5 /* layout.test */,
				F968885C0AF7880C000797B5 /* notebook.test */,
				F968885D0AF7880C000797B5 /* panedwindow.test */,
				F968885E0AF7880C000797B5 /* progressbar.test */,
				F98383680F0FA44700171CA6 /* radiobutton.test */,
				F968885F0AF7880C000797B5 /* scrollbar.test */,
				F96888600AF7880C000797B5 /* treetags.test */,
				F96888610AF7880C000797B5 /* treeview.test */,
				F96888620AF7880C000797B5 /* ttk.test */,
				F96888630AF7880C000797B5 /* validate.test */,
				F962F7C60DADC26200648DB8 /* vsapi.test */,
			);
			path = ttk;
			sourceTree = "<group>";
		};
		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
			isa = PBXGroup;
			children = (
				F96D3EC908F272A7004A47F5 /* generic */,
				F96D432C08F272B4004A47F5 /* macosx */,
				F96D443E08F272B9004A47F5 /* unix */,
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F9183E690EFC81560030B814 /* pkgs */,
				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
				F96D3DFB08F272A4004A47F5 /* changes */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,
				F966BA0E08F27A37005CB29B /* ChangeLog */,
				F966BA0F08F27A37005CB29B /* changes */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
			isa = PBXGroup;
			children = (
				F96D3DFD08F272A4004A47F5 /* Access.3 */,
				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
				F96D3DFF08F272A4004A47F5 /* after.n */,
				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
				F96D3E0208F272A4004A47F5 /* append.n */,
				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
				F96D3E0408F272A5004A47F5 /* array.n */,
				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
				F96D3E0608F272A5004A47F5 /* Async.3 */,
				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
				F96D3E0908F272A5004A47F5 /* bgerror.n */,
				F96D3E0A08F272A5004A47F5 /* binary.n */,
				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
				F96D3E0C08F272A5004A47F5 /* break.n */,
				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
				F96D3E0F08F272A5004A47F5 /* case.n */,
				F96D3E1008F272A5004A47F5 /* catch.n */,
				F96D3E1108F272A5004A47F5 /* cd.n */,
				F96D3E1208F272A5004A47F5 /* chan.n */,
				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
				F93599CF0DF1F87F00E04F67 /* Class.3 */,
				F93599D00DF1F89E00E04F67 /* class.n */,
				F96D3E1408F272A5004A47F5 /* clock.n */,
				F96D3E1508F272A5004A47F5 /* close.n */,
				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
				F96D3E1708F272A5004A47F5 /* Concat.3 */,
				F96D3E1808F272A5004A47F5 /* concat.n */,
				F96D3E1908F272A5004A47F5 /* continue.n */,
				F93599D20DF1F8DF00E04F67 /* copy.n */,
				F974D5720FBE7DC600BF728B /* coroutine.n */,
				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F93599D30DF1F8F500E04F67 /* define.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
				F96D3E2C08F272A5004A47F5 /* DString.3 */,
				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
				F96D3E2F08F272A5004A47F5 /* encoding.n */,
				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
				F96D3E3108F272A5004A47F5 /* Environment.3 */,
				F96D3E3208F272A5004A47F5 /* eof.n */,
				F96D3E3308F272A5004A47F5 /* error.n */,
				F96D3E3408F272A5004A47F5 /* Eval.3 */,
				F96D3E3508F272A5004A47F5 /* eval.n */,
				F96D3E3608F272A5004A47F5 /* exec.n */,
				F96D3E3708F272A5004A47F5 /* Exit.3 */,
				F96D3E3808F272A5004A47F5 /* exit.n */,
				F96D3E3908F272A5004A47F5 /* expr.n */,
				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
				F96D3E3F08F272A5004A47F5 /* file.n */,
				F96D3E4008F272A5004A47F5 /* fileevent.n */,
				F96D3E4108F272A5004A47F5 /* filename.n */,
				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
				F96D3E4408F272A5004A47F5 /* flush.n */,
				F96D3E4508F272A5004A47F5 /* for.n */,
				F96D3E4608F272A5004A47F5 /* foreach.n */,
				F96D3E4708F272A5004A47F5 /* format.n */,
				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
				F96D3E4D08F272A5004A47F5 /* gets.n */,
				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
				F96D3E5108F272A5004A47F5 /* glob.n */,
				F96D3E5208F272A6004A47F5 /* global.n */,
				F96D3E5308F272A6004A47F5 /* Hash.3 */,
				F96D3E5408F272A6004A47F5 /* history.n */,
				F96D3E5508F272A6004A47F5 /* http.n */,
				F96D3E5608F272A6004A47F5 /* if.n */,
				F96D3E5708F272A6004A47F5 /* incr.n */,
				F96D3E5808F272A6004A47F5 /* info.n */,
				F96D3E5908F272A6004A47F5 /* Init.3 */,
				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
				F96D3E5C08F272A6004A47F5 /* interp.n */,
				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
				F96D3E5E08F272A6004A47F5 /* join.n */,
				F96D3E5F08F272A6004A47F5 /* lappend.n */,
				F96D3E6008F272A6004A47F5 /* lassign.n */,
				F96D3E6108F272A6004A47F5 /* library.n */,
				F96D3E6208F272A6004A47F5 /* Limit.3 */,
				F96D3E6308F272A6004A47F5 /* lindex.n */,
				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
				F96D3E6508F272A6004A47F5 /* linsert.n */,
				F96D3E6608F272A6004A47F5 /* list.n */,
				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
				F96D3E6808F272A6004A47F5 /* llength.n */,
				F96D3E6908F272A6004A47F5 /* load.n */,
				F96D3E6A08F272A6004A47F5 /* lrange.n */,
				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
				F96D3E6E08F272A6004A47F5 /* lset.n */,
				F96D3E6F08F272A6004A47F5 /* lsort.n */,
				F96D3E7008F272A6004A47F5 /* man.macros */,
				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
				F96D3E7208F272A6004A47F5 /* memory.n */,
				F93599D40DF1F91900E04F67 /* Method.3 */,
				F96D3E7308F272A6004A47F5 /* msgcat.n */,
				F93599D50DF1F93700E04F67 /* my.n */,
				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
				F96D3E7508F272A6004A47F5 /* namespace.n */,
				F93599D60DF1F95000E04F67 /* next.n */,
				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
				F96D3E7708F272A6004A47F5 /* Object.3 */,
				F93599D70DF1F96800E04F67 /* object.n */,
				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
				F96D3E7908F272A6004A47F5 /* open.n */,
				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
				F96D3E7C08F272A6004A47F5 /* package.n */,
				F96D3E7D08F272A6004A47F5 /* packagens.n */,
				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
				F96D3E8008F272A6004A47F5 /* pid.n */,
				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
				F9ECB1E20B26543C00A28025 /* platform.n */,
				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
				F96D3E8508F272A6004A47F5 /* proc.n */,
				F96D3E8608F272A6004A47F5 /* puts.n */,
				F96D3E8708F272A6004A47F5 /* pwd.n */,
				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
				F96D3E8908F272A6004A47F5 /* read.n */,
				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
				F96D3E8E08F272A6004A47F5 /* regexp.n */,
				F96D3E8F08F272A6004A47F5 /* registry.n */,
				F96D3E9008F272A6004A47F5 /* regsub.n */,
				F96D3E9108F272A6004A47F5 /* rename.n */,
				F96D3E9208F272A6004A47F5 /* return.n */,
				F96D3E9308F272A6004A47F5 /* safe.n */,
				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
				F96D3E9508F272A6004A47F5 /* scan.n */,
				F96D3E9608F272A6004A47F5 /* seek.n */,
				F93599D80DF1F98300E04F67 /* self.n */,
				F96D3E9708F272A6004A47F5 /* set.n */,
				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
				F96D3E9F08F272A7004A47F5 /* socket.n */,
				F96D3EA008F272A7004A47F5 /* source.n */,
				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
				F96D3EA208F272A7004A47F5 /* split.n */,
				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
				F96D3EA708F272A7004A47F5 /* string.n */,
				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
				F96D3EAA08F272A7004A47F5 /* subst.n */,
				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
				F96D3EAC08F272A7004A47F5 /* switch.n */,
				F974D5760FBE7E1900BF728B /* tailcall.n */,
				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
				F99D61180EF5573A00BBFE01 /* TclZlib.3 */,
				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
				F96D3EB108F272A7004A47F5 /* tcltest.n */,
				F96D3EB208F272A7004A47F5 /* tclvars.n */,
				F96D3EB308F272A7004A47F5 /* tell.n */,
				F96D3EB408F272A7004A47F5 /* Thread.3 */,
				F9183E640EFC80CD0030B814 /* throw.n */,
				F96D3EB508F272A7004A47F5 /* time.n */,
				F96D3EB608F272A7004A47F5 /* tm.n */,
				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
				F96D3EB808F272A7004A47F5 /* trace.n */,
				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
				F9183E650EFC80D70030B814 /* try.n */,
				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
				F96D3EBD08F272A7004A47F5 /* unknown.n */,
				F96D3EBE08F272A7004A47F5 /* unload.n */,
				F96D3EBF08F272A7004A47F5 /* unset.n */,
				F96D3EC008F272A7004A47F5 /* update.n */,
				F96D3EC108F272A7004A47F5 /* uplevel.n */,
				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
				F96D3EC308F272A7004A47F5 /* upvar.n */,
				F96D3EC408F272A7004A47F5 /* Utf.3 */,
				F96D3EC508F272A7004A47F5 /* variable.n */,
				F96D3EC608F272A7004A47F5 /* vwait.n */,
				F96D3EC708F272A7004A47F5 /* while.n */,
				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
				F915432D0EF201EE0032D1E8 /* zlib.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F96D3EC908F272A7004A47F5 /* generic */ = {
			isa = PBXGroup;
			children = (
				F96D3ECA08F272A7004A47F5 /* README */,
				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
				F96D3ED008F272A7004A47F5 /* regcomp.c */,
				F96D3ED108F272A7004A47F5 /* regcustom.h */,
				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
				F96D3ED308F272A7004A47F5 /* regerror.c */,
				F96D3ED408F272A7004A47F5 /* regerrs.h */,
				F96D3ED508F272A7004A47F5 /* regex.h */,
				F96D3ED608F272A7004A47F5 /* regexec.c */,
				F96D3ED708F272A7004A47F5 /* regfree.c */,
				F96D3ED808F272A7004A47F5 /* regfronts.c */,
				F96D3ED908F272A7004A47F5 /* regguts.h */,
				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
				F96D3EDB08F272A7004A47F5 /* tcl.h */,
				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
				F96D3EE108F272A7004A47F5 /* tclClock.c */,
				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
				F96D3EF408F272A7004A47F5 /* tclGet.c */,
				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
				F96D3EF608F272A7004A47F5 /* tclHash.c */,
				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
				F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */,
				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
				F96D3F0508F272A7004A47F5 /* tclLink.c */,
				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
				F93599B20DF1F75400E04F67 /* tclOO.c */,
				F93599B40DF1F75900E04F67 /* tclOO.decls */,
				F93599B50DF1F75D00E04F67 /* tclOO.h */,
				F93599B60DF1F76100E04F67 /* tclOOBasic.c */,
				F93599B80DF1F76600E04F67 /* tclOOCall.c */,
				F93599BA0DF1F76A00E04F67 /* tclOODecls.h */,
				F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */,
				F93599BD0DF1F77400E04F67 /* tclOOInfo.c */,
				F93599BF0DF1F77900E04F67 /* tclOOInt.h */,
				F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */,
				F93599C10DF1F78300E04F67 /* tclOOMethod.c */,
				F93599C30DF1F78800E04F67 /* tclOOStubInit.c */,
				F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */,
				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
				F96D3F1608F272A7004A47F5 /* tclPort.h */,
				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
				F96D3F1908F272A7004A47F5 /* tclProc.c */,
				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
				F96D3F2708F272A7004A47F5 /* tclTest.c */,
				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
				F96D3F3608F272A7004A47F5 /* tclVar.c */,
				F96437C90EF0D4B2003F468E /* tclZlib.c */,
				F96D3F3708F272A7004A47F5 /* tommath.h */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F96D3F3808F272A7004A47F5 /* library */ = {
			isa = PBXGroup;
			children = (
				F96D3F3908F272A8004A47F5 /* auto.tcl */,
				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
				F96D3F3B08F272A8004A47F5 /* dde */,
				F96D3F8C08F272A8004A47F5 /* history.tcl */,
				F96D3F8D08F272A8004A47F5 /* http */,
				F96D3F9008F272A8004A47F5 /* http1.0 */,
				F96D3F9308F272A8004A47F5 /* init.tcl */,
				F96D3F9408F272A8004A47F5 /* msgcat */,
				F96D401708F272AA004A47F5 /* opt */,
				F96D401A08F272AA004A47F5 /* package.tcl */,
				F96D401B08F272AA004A47F5 /* parray.tcl */,
				F9ECB1110B26521500A28025 /* platform */,
				F96D401C08F272AA004A47F5 /* reg */,
				F96D401E08F272AA004A47F5 /* safe.tcl */,
				F96D401F08F272AA004A47F5 /* tclIndex */,
				F96D402008F272AA004A47F5 /* tcltest */,
				F96D402308F272AA004A47F5 /* tm.tcl */,
				F96D425B08F272B2004A47F5 /* word.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F96D3F3B08F272A8004A47F5 /* dde */ = {
			isa = PBXGroup;
			children = (
				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = dde;
			sourceTree = "<group>";
		};
		F96D3F8D08F272A8004A47F5 /* http */ = {
			isa = PBXGroup;
			children = (
				F96D3F8E08F272A8004A47F5 /* http.tcl */,
				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http;
			sourceTree = "<group>";
		};
		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
			isa = PBXGroup;
			children = (
				F96D3F9108F272A8004A47F5 /* http.tcl */,
				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http1.0;
			sourceTree = "<group>";
		};
		F96D3F9408F272A8004A47F5 /* msgcat */ = {
			isa = PBXGroup;
			children = (
				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = msgcat;
			sourceTree = "<group>";
		};
		F96D401708F272AA004A47F5 /* opt */ = {
			isa = PBXGroup;
			children = (
				F96D401808F272AA004A47F5 /* optparse.tcl */,
				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = opt;
			sourceTree = "<group>";
		};
		F96D401C08F272AA004A47F5 /* reg */ = {
			isa = PBXGroup;
			children = (
				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = reg;
			sourceTree = "<group>";
		};
		F96D402008F272AA004A47F5 /* tcltest */ = {
			isa = PBXGroup;
			children = (
				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
				F96D402208F272AA004A47F5 /* tcltest.tcl */,
			);
			path = tcltest;
			sourceTree = "<group>";
		};
		F96D425C08F272B2004A47F5 /* libtommath */ = {
			isa = PBXGroup;
			children = (
				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
				F96D42D708F272B3004A47F5 /* bncore.c */,
				F96D432908F272B4004A47F5 /* tommath_class.h */,
				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
			);
			path = libtommath;
			sourceTree = "<group>";
		};
		F96D432C08F272B4004A47F5 /* macosx */ = {
			isa = PBXGroup;
			children = (
				F96D432E08F272B5004A47F5 /* configure.ac */,
				F96D432F08F272B5004A47F5 /* GNUmakefile */,
				F96D433108F272B5004A47F5 /* README */,
				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F96D434408F272B5004A47F5 /* tests */ = {
			isa = PBXGroup;
			children = (
				F96D434508F272B5004A47F5 /* all.tcl */,
				F96D434608F272B5004A47F5 /* append.test */,
				F96D434708F272B5004A47F5 /* appendComp.test */,
				F9ECB1CA0B2652D300A28025 /* apply.test */,
				F96D434808F272B5004A47F5 /* assocd.test */,
				F96D434908F272B5004A47F5 /* async.test */,
				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
				F96D434B08F272B5004A47F5 /* basic.test */,
				F96D434C08F272B5004A47F5 /* binary.test */,
				F96D434D08F272B5004A47F5 /* case.test */,
				F96D434E08F272B5004A47F5 /* chan.test */,
				F9A493240CEBF38300B78AE2 /* chanio.test */,
				F96D434F08F272B5004A47F5 /* clock.test */,
				F96D435008F272B5004A47F5 /* cmdAH.test */,
				F96D435108F272B5004A47F5 /* cmdIL.test */,
				F96D435208F272B5004A47F5 /* cmdInfo.test */,
				F96D435308F272B5004A47F5 /* cmdMZ.test */,
				F96D435408F272B5004A47F5 /* compExpr-old.test */,
				F96D435508F272B5004A47F5 /* compExpr.test */,
				F96D435608F272B5004A47F5 /* compile.test */,
				F96D435708F272B5004A47F5 /* concat.test */,
				F96D435808F272B5004A47F5 /* config.test */,
				F974D5770FBE7E6100BF728B /* coroutine.test */,
				F96D435908F272B5004A47F5 /* dcall.test */,
				F96D435A08F272B5004A47F5 /* dict.test */,
				F96D435C08F272B5004A47F5 /* dstring.test */,
				F96D435E08F272B5004A47F5 /* encoding.test */,
				F96D435F08F272B5004A47F5 /* env.test */,
				F96D436008F272B5004A47F5 /* error.test */,
				F96D436108F272B5004A47F5 /* eval.test */,
				F96D436208F272B5004A47F5 /* event.test */,
				F96D436308F272B5004A47F5 /* exec.test */,
				F96D436408F272B5004A47F5 /* execute.test */,
				F96D436508F272B5004A47F5 /* expr-old.test */,
				F96D436608F272B5004A47F5 /* expr.test */,
				F96D436708F272B6004A47F5 /* fCmd.test */,
				F96D436808F272B6004A47F5 /* fileName.test */,
				F96D436908F272B6004A47F5 /* fileSystem.test */,
				F96D436A08F272B6004A47F5 /* for-old.test */,
				F96D436B08F272B6004A47F5 /* for.test */,
				F96D436C08F272B6004A47F5 /* foreach.test */,
				F96D436D08F272B6004A47F5 /* format.test */,
				F96D436E08F272B6004A47F5 /* get.test */,
				F96D436F08F272B6004A47F5 /* history.test */,
				F96D437008F272B6004A47F5 /* http.test */,
				F974D56C0FBE7D6300BF728B /* http11.test */,
				F96D437108F272B6004A47F5 /* httpd */,
				F974D56D0FBE7D6300BF728B /* httpd11.tcl */,
				F96D437208F272B6004A47F5 /* httpold.test */,
				F96D437308F272B6004A47F5 /* if-old.test */,
				F96D437408F272B6004A47F5 /* if.test */,
				F96D437508F272B6004A47F5 /* incr-old.test */,
				F96D437608F272B6004A47F5 /* incr.test */,
				F96D437708F272B6004A47F5 /* indexObj.test */,
				F96D437808F272B6004A47F5 /* info.test */,
				F96D437908F272B6004A47F5 /* init.test */,
				F96D437A08F272B6004A47F5 /* interp.test */,
				F96D437B08F272B6004A47F5 /* io.test */,
				F96D437C08F272B6004A47F5 /* ioCmd.test */,
				F96D437D08F272B6004A47F5 /* iogt.test */,
				F96D437F08F272B6004A47F5 /* join.test */,
				F96D438008F272B6004A47F5 /* lindex.test */,
				F96D438108F272B6004A47F5 /* link.test */,
				F96D438208F272B6004A47F5 /* linsert.test */,
				F96D438308F272B6004A47F5 /* list.test */,
				F96D438408F272B6004A47F5 /* listObj.test */,
				F96D438508F272B6004A47F5 /* llength.test */,
				F96D438608F272B6004A47F5 /* load.test */,
				F96D438708F272B6004A47F5 /* lrange.test */,
				F96D438808F272B6004A47F5 /* lrepeat.test */,
				F96D438908F272B6004A47F5 /* lreplace.test */,
				F96D438A08F272B6004A47F5 /* lsearch.test */,
				F96D438B08F272B6004A47F5 /* lset.test */,
				F96D438C08F272B6004A47F5 /* lsetComp.test */,
				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
				F96D438E08F272B6004A47F5 /* main.test */,
				F9ECB1CB0B26534C00A28025 /* mathop.test */,
				F96D438F08F272B6004A47F5 /* misc.test */,
				F96D439008F272B6004A47F5 /* msgcat.test */,
				F96D439108F272B6004A47F5 /* namespace-old.test */,
				F96D439208F272B7004A47F5 /* namespace.test */,
				F96D439308F272B7004A47F5 /* notify.test */,
				F91DC23C0E44C51B002CB8D1 /* nre.test */,
				F96D439408F272B7004A47F5 /* obj.test */,
				F93599C80DF1F81900E04F67 /* oo.test */,
				F96D439508F272B7004A47F5 /* opt.test */,
				F96D439608F272B7004A47F5 /* package.test */,
				F96D439708F272B7004A47F5 /* parse.test */,
				F96D439808F272B7004A47F5 /* parseExpr.test */,
				F96D439908F272B7004A47F5 /* parseOld.test */,
				F96D439A08F272B7004A47F5 /* pid.test */,
				F96D439B08F272B7004A47F5 /* pkg.test */,
				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
				F96D439D08F272B7004A47F5 /* platform.test */,
				F96D439E08F272B7004A47F5 /* proc-old.test */,
				F96D439F08F272B7004A47F5 /* proc.test */,
				F96D43A008F272B7004A47F5 /* pwd.test */,
				F96D43A108F272B7004A47F5 /* README */,
				F96D43A208F272B7004A47F5 /* reg.test */,
				F96D43A308F272B7004A47F5 /* regexp.test */,
				F96D43A408F272B7004A47F5 /* regexpComp.test */,
				F96D43A508F272B7004A47F5 /* registry.test */,
				F96D43A608F272B7004A47F5 /* remote.tcl */,
				F96D43A708F272B7004A47F5 /* rename.test */,
				F96D43A808F272B7004A47F5 /* result.test */,
				F96D43A908F272B7004A47F5 /* safe.test */,
				F96D43AA08F272B7004A47F5 /* scan.test */,
				F96D43AB08F272B7004A47F5 /* security.test */,
				F96D43AC08F272B7004A47F5 /* set-old.test */,
				F96D43AD08F272B7004A47F5 /* set.test */,
				F96D43AE08F272B7004A47F5 /* socket.test */,
				F96D43AF08F272B7004A47F5 /* source.test */,
				F96D43B008F272B7004A47F5 /* split.test */,
				F96D43B108F272B7004A47F5 /* stack.test */,
				F96D43B208F272B7004A47F5 /* string.test */,
				F96D43B308F272B7004A47F5 /* stringComp.test */,
				F96D43B408F272B7004A47F5 /* stringObj.test */,
				F96D43B508F272B7004A47F5 /* subst.test */,
				F96D43B608F272B7004A47F5 /* switch.test */,
				F974D5780FBE7E6100BF728B /* tailcall.test */,
				F96D43B708F272B7004A47F5 /* tcltest.test */,
				F96D43B808F272B7004A47F5 /* thread.test */,
				F96D43B908F272B7004A47F5 /* timer.test */,
				F96D43BA08F272B7004A47F5 /* tm.test */,
				F96D43BB08F272B7004A47F5 /* trace.test */,
				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
				F96D43BD08F272B7004A47F5 /* unixFile.test */,
				F96D43BE08F272B7004A47F5 /* unixInit.test */,
				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
				F96D43C008F272B7004A47F5 /* unknown.test */,
				F96D43C108F272B7004A47F5 /* unload.test */,
				F96D43C208F272B7004A47F5 /* uplevel.test */,
				F96D43C308F272B7004A47F5 /* upvar.test */,
				F96D43C408F272B7004A47F5 /* utf.test */,
				F96D43C508F272B7004A47F5 /* util.test */,
				F96D43C608F272B7004A47F5 /* var.test */,
				F96D43C708F272B7004A47F5 /* while-old.test */,
				F96D43C808F272B7004A47F5 /* while.test */,
				F96D43C908F272B7004A47F5 /* winConsole.test */,
				F96D43CA08F272B7004A47F5 /* winDde.test */,
				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
				F96D43CC08F272B7004A47F5 /* winFile.test */,
				F96D43CD08F272B7004A47F5 /* winNotify.test */,
				F96D43CE08F272B7004A47F5 /* winPipe.test */,
				F96D43CF08F272B7004A47F5 /* winTime.test */,
				F915432A0EF201CF0032D1E8 /* zlib.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.ac */,
				F96D442208F272B8004A47F5 /* eolFix.tcl */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
				F96D442C08F272B8004A47F5 /* man2help.tcl */,
				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
				F96D442E08F272B8004A47F5 /* man2html.tcl */,
				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
				F96D443008F272B8004A47F5 /* man2html2.tcl */,
				F96D443108F272B8004A47F5 /* man2tcl.c */,
				F96D443208F272B8004A47F5 /* README */,
				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
				F96D443608F272B8004A47F5 /* tcl.wse.in */,
				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
				F92D7F100DE777240033A13A /* tsdPerf.tcl */,
				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.ac */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
				F974D5790FBE7E9C00BF728B /* tcl.pc.in */,
				F96D445408F272B9004A47F5 /* tcl.spec */,
				F96D445508F272B9004A47F5 /* tclAppInit.c */,
				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
				F96D446A08F272B9004A47F5 /* tclUnixThrd.h */,
				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F96D444308F272B9004A47F5 /* dltest */ = {
			isa = PBXGroup;
			children = (
				F96D444408F272B9004A47F5 /* Makefile.in */,
				F96D444508F272B9004A47F5 /* pkga.c */,
				F96D444608F272B9004A47F5 /* pkgb.c */,
				F96D444708F272B9004A47F5 /* pkgc.c */,
				F96D444808F272B9004A47F5 /* pkgd.c */,
				F96D444908F272B9004A47F5 /* pkge.c */,
				F96D444B08F272B9004A47F5 /* pkgua.c */,
				F96D444C08F272B9004A47F5 /* README */,
			);
			path = dltest;
			sourceTree = "<group>";
		};
		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.ac */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
				F96D447F08F272BA004A47F5 /* tcl.dsw */,
				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
				F96D448108F272BA004A47F5 /* tcl.m4 */,
				F96D448208F272BA004A47F5 /* tcl.rc */,
				F96D448308F272BA004A47F5 /* tclAppInit.c */,
				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
				F96D448608F272BA004A47F5 /* tclsh.rc */,
				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
				F96D448808F272BA004A47F5 /* tclWinChan.c */,
				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
				F96D448B08F272BA004A47F5 /* tclWinError.c */,
				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
				F96D449308F272BA004A47F5 /* tclWinPort.h */,
				F96D449408F272BA004A47F5 /* tclWinReg.c */,
				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
				F96D449608F272BA004A47F5 /* tclWinSock.c */,
				F96D449708F272BA004A47F5 /* tclWinTest.c */,
				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F9ECB1110B26521500A28025 /* platform */ = {
			isa = PBXGroup;
			children = (
				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
				F9ECB1130B26521500A28025 /* platform.tcl */,
				F9ECB1140B26521500A28025 /* shell.tcl */,
			);
			path = platform;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8DD76FA90486AB0100D96B5E /* tktest */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */;
			buildPhases = (
				F9A5C5F508F651A2008AE941 /* Configure Tcl */,
				F9A5C5F608F651AB008AE941 /* Configure Tk */,
				8DD76FAB0486AB0100D96B5E /* Sources */,
				8DD76FAD0486AB0100D96B5E /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = tktest;
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = 8DD76FB20486AB0100D96B5E /* tktest */;
			productType = "com.apple.product-type.tool";
		};
		F97258A50A86873C00096C78 /* tktest-X11 */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */;
			buildPhases = (
				F9FD30B40CC1AD070073837D /* Configure Tcl */,
				F9FD30B50CC1AD070073837D /* Configure Tk */,
				F9FD30BB0CC1AD070073837D /* Sources */,
				F9FD31E30CC1AD070073837D /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = "tktest-X11";
			productInstallPath = "$(BINDIR)";
			productName = tktest;
			productReference = F9FD31F40CC1AD070073837D /* tktest-X11 */;
			productType = "com.apple.product-type.tool";
		};
		F9E61D16090A3E94002B3151 /* Tk */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */;
			buildPhases = (
				F97AF02F0B665DA900310EA2 /* Build Tk */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Tk;
			productName = Wish;
			productReference = F9A3084B08F2D4CE00BAE1AB /* Wish.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		08FB7793FE84155DC02AAC07 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				BuildIndependentTargetsInParallel = YES;
			};
			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */;
			compatibilityVersion = "Xcode 3.1";
			hasScannedForEncodings = 1;
			mainGroup = 08FB7794FE84155DC02AAC07 /* Tk */;
			projectDirPath = "";
			projectRoot = ..;
			targets = (
				F9E61D16090A3E94002B3151 /* Tk */,
				8DD76FA90486AB0100D96B5E /* tktest */,
				F97258A50A86873C00096C78 /* tktest-X11 */,
			);
		};
/* End PBXProject section */

/* Begin PBXShellScriptBuildPhase section */
		F97AF02F0B665DA900310EA2 /* Build Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"${TARGET_TEMP_DIR}/.none",
			);
			name = "Build Tk";
			outputPaths = (
				"${TARGET_BUILD_DIR}/${WRAPPER_NAME}",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "export CC=$(xcrun -find ${GCC} || echo ${GCC}); export LD=${CC}\ngnumake -C \"${TK_SRCROOT}/macosx\"  -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" APPLICATION_INSTALL_PATH=\"${APPLICATION_INSTALL_PATH}\" TCL_BUILD_DIR=\"${TCL_BUILD_DIR}\" TCL_FRAMEWORK_DIR=\"${TCL_FRAMEWORK_DIR}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${BUILT_PRODUCTS_DIR}/tktest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tktest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F608F651AB008AE941 /* Configure Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.ac",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			name = "Configure Tk";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B40CC1AD070073837D /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
		F9FD30B50CC1AD070073837D /* Configure Tk */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TK_SRCROOT)/macosx/configure.ac",
				"$(TK_SRCROOT)/unix/configure.ac",
				"$(TK_SRCROOT)/unix/tcl.m4",
				"$(TK_SRCROOT)/unix/aclocal.m4",
				"$(TK_SRCROOT)/unix/tkConfig.sh.in",
			);
			name = "Configure Tk";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tk/tkConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tk/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tk\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8DD76FAB0486AB0100D96B5E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
				F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */,
				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
				F93599B30DF1F75400E04F67 /* tclOO.c in Sources */,
				F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */,
				F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */,
				F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */,
				F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */,
				F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */,
				F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */,
				F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */,
				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
				F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
				F966BDCF08F27A3F005CB29B /* tk3d.c in Sources */,
				F966BDD108F27A3F005CB29B /* tkArgv.c in Sources */,
				F966BDD208F27A3F005CB29B /* tkAtom.c in Sources */,
				F966BDD308F27A3F005CB29B /* tkBind.c in Sources */,
				F966BDD408F27A3F005CB29B /* tkBitmap.c in Sources */,
				F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */,
				F966BDD508F27A3F005CB29B /* tkButton.c in Sources */,
				F966BDD708F27A3F005CB29B /* tkCanvArc.c in Sources */,
				F966BDD808F27A3F005CB29B /* tkCanvas.c in Sources */,
				F966BDDA08F27A3F005CB29B /* tkCanvBmap.c in Sources */,
				F966BDDB08F27A3F005CB29B /* tkCanvImg.c in Sources */,
				F966BDDC08F27A3F005CB29B /* tkCanvLine.c in Sources */,
				F966BDDD08F27A3F005CB29B /* tkCanvPoly.c in Sources */,
				F966BDDE08F27A3F005CB29B /* tkCanvPs.c in Sources */,
				F966BDE008F27A3F005CB29B /* tkCanvText.c in Sources */,
				F966BDE108F27A3F005CB29B /* tkCanvUtil.c in Sources */,
				F966BDE208F27A3F005CB29B /* tkCanvWind.c in Sources */,
				F966BDE308F27A3F005CB29B /* tkClipboard.c in Sources */,
				F966BDE408F27A3F005CB29B /* tkCmds.c in Sources */,
				F966BDE508F27A3F005CB29B /* tkColor.c in Sources */,
				F966BDE708F27A3F005CB29B /* tkConfig.c in Sources */,
				F966BDE808F27A3F005CB29B /* tkConsole.c in Sources */,
				F966BDE908F27A3F005CB29B /* tkCursor.c in Sources */,
				F966BDEB08F27A3F005CB29B /* tkEntry.c in Sources */,
				F966BDED08F27A3F005CB29B /* tkError.c in Sources */,
				F966BDEE08F27A3F005CB29B /* tkEvent.c in Sources */,
				F966BDEF08F27A3F005CB29B /* tkFileFilter.c in Sources */,
				F966BDF108F27A3F005CB29B /* tkFocus.c in Sources */,
				F966BDF208F27A3F005CB29B /* tkFont.c in Sources */,
				F966BDF408F27A3F005CB29B /* tkFrame.c in Sources */,
				F966BDF508F27A3F005CB29B /* tkGC.c in Sources */,
				F966BDF608F27A3F005CB29B /* tkGeometry.c in Sources */,
				F966BDF708F27A3F005CB29B /* tkGet.c in Sources */,
				F966BDF808F27A3F005CB29B /* tkGrab.c in Sources */,
				F966BDF908F27A3F005CB29B /* tkGrid.c in Sources */,
				F966BDFA08F27A3F005CB29B /* tkImage.c in Sources */,
				F966BDFB08F27A3F005CB29B /* tkImgBmap.c in Sources */,
				F966BDFC08F27A3F005CB29B /* tkImgGIF.c in Sources */,
				F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */,
				F966BDFD08F27A3F005CB29B /* tkImgPhoto.c in Sources */,
				F9DD99BD0F07DF850018B2E4 /* tkImgPNG.c in Sources */,
				F966BDFE08F27A3F005CB29B /* tkImgPPM.c in Sources */,
				F966BE0708F27A3F005CB29B /* tkListbox.c in Sources */,
				F966BE0808F27A3F005CB29B /* tkMacWinMenu.c in Sources */,
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,
				F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */,
				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,
				F966BE1C08F27A40005CB29B /* tkScrollbar.c in Sources */,
				F966BE1E08F27A40005CB29B /* tkSelect.c in Sources */,
				F966BE2008F27A40005CB29B /* tkSquare.c in Sources */,
				F966BE2208F27A40005CB29B /* tkStubInit.c in Sources */,
				F966BE2308F27A40005CB29B /* tkStubLib.c in Sources */,
				F966BE2408F27A40005CB29B /* tkStyle.c in Sources */,
				F966BE2508F27A40005CB29B /* tkTest.c in Sources */,
				F966BE2608F27A40005CB29B /* tkText.c in Sources */,
				F966BE2808F27A40005CB29B /* tkTextBTree.c in Sources */,
				F966BE2908F27A40005CB29B /* tkTextDisp.c in Sources */,
				F966BE2B08F27A40005CB29B /* tkTextImage.c in Sources */,
				F966BE2C08F27A40005CB29B /* tkTextIndex.c in Sources */,
				F966BE2D08F27A40005CB29B /* tkTextMark.c in Sources */,
				F966BE2E08F27A40005CB29B /* tkTextTag.c in Sources */,
				F966BE2F08F27A40005CB29B /* tkTextWind.c in Sources */,
				F966BE3008F27A40005CB29B /* tkTrig.c in Sources */,
				F966BE3108F27A40005CB29B /* tkUndo.c in Sources */,
				F966BE3308F27A40005CB29B /* tkUtil.c in Sources */,
				F966BE3408F27A40005CB29B /* tkVisual.c in Sources */,
				F966BE3508F27A40005CB29B /* tkWindow.c in Sources */,
				F96888050AF786D5000797B5 /* ttkBlink.c in Sources */,
				F96888060AF786D5000797B5 /* ttkButton.c in Sources */,
				F96888070AF786D5000797B5 /* ttkCache.c in Sources */,
				F96888080AF786D5000797B5 /* ttkClamTheme.c in Sources */,
				F96888090AF786D5000797B5 /* ttkClassicTheme.c in Sources */,
				F968880A0AF786D5000797B5 /* ttkDefaultTheme.c in Sources */,
				F968880B0AF786D5000797B5 /* ttkElements.c in Sources */,
				F968880C0AF786D5000797B5 /* ttkEntry.c in Sources */,
				F968880D0AF786D5000797B5 /* ttkFrame.c in Sources */,
				F968880E0AF786D5000797B5 /* ttkImage.c in Sources */,
				F968880F0AF786D5000797B5 /* ttkInit.c in Sources */,
				F96888100AF786D5000797B5 /* ttkLabel.c in Sources */,
				F96888110AF786D5000797B5 /* ttkLayout.c in Sources */,
				F96888120AF786D5000797B5 /* ttkManager.c in Sources */,
				F96888130AF786D5000797B5 /* ttkNotebook.c in Sources */,
				F96888140AF786D5000797B5 /* ttkPanedwindow.c in Sources */,
				F96888150AF786D5000797B5 /* ttkProgress.c in Sources */,
				F96888160AF786D5000797B5 /* ttkScale.c in Sources */,
				F96888170AF786D5000797B5 /* ttkScroll.c in Sources */,
				F96888180AF786D5000797B5 /* ttkScrollbar.c in Sources */,
				F96888190AF786D5000797B5 /* ttkSeparator.c in Sources */,
				F968881A0AF786D5000797B5 /* ttkSquare.c in Sources */,
				F968881B0AF786D5000797B5 /* ttkState.c in Sources */,
				F968881C0AF786D5000797B5 /* ttkStubInit.c in Sources */,
				F968881D0AF786D5000797B5 /* ttkStubLib.c in Sources */,
				F968881E0AF786D5000797B5 /* ttkTagSet.c in Sources */,
				F968881F0AF786D5000797B5 /* ttkTheme.c in Sources */,
				F96888200AF786D5000797B5 /* ttkTrace.c in Sources */,
				F96888210AF786D5000797B5 /* ttkTrack.c in Sources */,
				F96888220AF786D5000797B5 /* ttkTreeview.c in Sources */,
				F96888230AF786D5000797B5 /* ttkWidget.c in Sources */,
				F966BEDB08F27A40005CB29B /* tkMacOSXBitmap.c in Sources */,
				F966BEDC08F27A40005CB29B /* tkMacOSXButton.c in Sources */,
				F966BEDE08F27A40005CB29B /* tkMacOSXClipboard.c in Sources */,
				F966BEDF08F27A40005CB29B /* tkMacOSXColor.c in Sources */,
				F966BEE008F27A40005CB29B /* tkMacOSXConfig.c in Sources */,
				F966BEE108F27A40005CB29B /* tkMacOSXCursor.c in Sources */,
				F966BEE308F27A40005CB29B /* tkMacOSXDebug.c in Sources */,
				F966BEE608F27A40005CB29B /* tkMacOSXDialog.c in Sources */,
				F966BEE708F27A40005CB29B /* tkMacOSXDraw.c in Sources */,
				F966BEE808F27A40005CB29B /* tkMacOSXEmbed.c in Sources */,
				F966BEE908F27A40005CB29B /* tkMacOSXEntry.c in Sources */,
				F966BEEA08F27A40005CB29B /* tkMacOSXEvent.c in Sources */,
				F966BEEC08F27A40005CB29B /* tkMacOSXFont.c in Sources */,
				F966BEED08F27A40005CB29B /* tkMacOSXHLEvents.c in Sources */,
				F966BEEE08F27A40005CB29B /* tkMacOSXInit.c in Sources */,
				F966BEF108F27A40005CB29B /* tkMacOSXKeyboard.c in Sources */,
				F966BEF208F27A40005CB29B /* tkMacOSXKeyEvent.c in Sources */,
				F966BEF308F27A40005CB29B /* tkMacOSXMenu.c in Sources */,
				F966BEF608F27A40005CB29B /* tkMacOSXMenubutton.c in Sources */,
				F966BEF708F27A40005CB29B /* tkMacOSXMenus.c in Sources */,
				F966BEF808F27A40005CB29B /* tkMacOSXMouseEvent.c in Sources */,
				F966BEF908F27A40005CB29B /* tkMacOSXNotify.c in Sources */,
				F966BF0108F27A40005CB29B /* tkMacOSXRegion.c in Sources */,
				F966BF0308F27A40005CB29B /* tkMacOSXScrlbr.c in Sources */,
				F966BF0408F27A40005CB29B /* tkMacOSXSend.c in Sources */,
				F966BF0508F27A40005CB29B /* tkMacOSXSubwindows.c in Sources */,
				F966BF0608F27A40005CB29B /* tkMacOSXTest.c in Sources */,
				F966BF0708F27A40005CB29B /* tkMacOSXWindowEvent.c in Sources */,
				F966BF0808F27A40005CB29B /* tkMacOSXWm.c in Sources */,
				F966BF0B08F27A40005CB29B /* tkMacOSXXStubs.c in Sources */,
				F96888850AF78938000797B5 /* ttkMacOSXTheme.c in Sources */,
				F966BF7F08F27A41005CB29B /* tkAppInit.c in Sources */,
				F966BF8308F27A41005CB29B /* tkUnix3d.c in Sources */,
				F966BF9608F27A41005CB29B /* tkUnixScale.c in Sources */,
				F966C02A08F27A42005CB29B /* xcolors.c in Sources */,
				F966C02B08F27A42005CB29B /* xdraw.c in Sources */,
				F966C02C08F27A42005CB29B /* xgc.c in Sources */,
				F966C02D08F27A42005CB29B /* ximage.c in Sources */,
				F966C02E08F27A42005CB29B /* xutil.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		F9FD30BB0CC1AD070073837D /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F9FD30BC0CC1AD070073837D /* regcomp.c in Sources */,
				F9FD30BD0CC1AD070073837D /* regerror.c in Sources */,
				F9FD30BE0CC1AD070073837D /* regexec.c in Sources */,
				F9FD30BF0CC1AD070073837D /* regfree.c in Sources */,
				F9FD30C00CC1AD070073837D /* tclAlloc.c in Sources */,
				F9FD30C10CC1AD070073837D /* tclAsync.c in Sources */,
				F9FD30C20CC1AD070073837D /* tclBasic.c in Sources */,
				F9FD30C30CC1AD070073837D /* tclBinary.c in Sources */,
				F9FD30C40CC1AD070073837D /* tclCkalloc.c in Sources */,
				F9FD30C50CC1AD070073837D /* tclClock.c in Sources */,
				F9FD30C60CC1AD070073837D /* tclCmdAH.c in Sources */,
				F9FD30C70CC1AD070073837D /* tclCmdIL.c in Sources */,
				F9FD30C80CC1AD070073837D /* tclCmdMZ.c in Sources */,
				F9FD30C90CC1AD070073837D /* tclCompCmds.c in Sources */,
				F9FD30CA0CC1AD070073837D /* tclCompExpr.c in Sources */,
				F9FD30CB0CC1AD070073837D /* tclCompile.c in Sources */,
				F9FD30CC0CC1AD070073837D /* tclConfig.c in Sources */,
				F9FD30CD0CC1AD070073837D /* tclDate.c in Sources */,
				F9FD30CE0CC1AD070073837D /* tclDictObj.c in Sources */,
				F9FD30CF0CC1AD070073837D /* tclEncoding.c in Sources */,
				F9FD30D00CC1AD070073837D /* tclEnv.c in Sources */,
				F9FD30D10CC1AD070073837D /* tclEvent.c in Sources */,
				F9FD30D20CC1AD070073837D /* tclExecute.c in Sources */,
				F9FD30D30CC1AD070073837D /* tclFCmd.c in Sources */,
				F9FD30D40CC1AD070073837D /* tclFileName.c in Sources */,
				F9FD30D50CC1AD070073837D /* tclGet.c in Sources */,
				F9FD30D60CC1AD070073837D /* tclHash.c in Sources */,
				F9FD30D70CC1AD070073837D /* tclHistory.c in Sources */,
				F9FD30D80CC1AD070073837D /* tclIndexObj.c in Sources */,
				F9FD30D90CC1AD070073837D /* tclInterp.c in Sources */,
				F9FD30DA0CC1AD070073837D /* tclIO.c in Sources */,
				F9FD30DB0CC1AD070073837D /* tclIOCmd.c in Sources */,
				F9FD30DC0CC1AD070073837D /* tclIOGT.c in Sources */,
				F9FD30DD0CC1AD070073837D /* tclIORChan.c in Sources */,
				F9FFAF1D0DFDDB26007F8A6A /* tclIORTrans.c in Sources */,
				F9FD30DE0CC1AD070073837D /* tclIOSock.c in Sources */,
				F9FD30DF0CC1AD070073837D /* tclIOUtil.c in Sources */,
				F9FD30E00CC1AD070073837D /* tclLink.c in Sources */,
				F9FD30E10CC1AD070073837D /* tclListObj.c in Sources */,
				F9FD30E20CC1AD070073837D /* tclLiteral.c in Sources */,
				F9FD30E30CC1AD070073837D /* tclLoad.c in Sources */,
				F9FD30E40CC1AD070073837D /* tclMain.c in Sources */,
				F9FD30E50CC1AD070073837D /* tclNamesp.c in Sources */,
				F9FD30E60CC1AD070073837D /* tclNotify.c in Sources */,
				F9FD30E70CC1AD070073837D /* tclObj.c in Sources */,
				F9FFAF1F0DFDDB2F007F8A6A /* tclOO.c in Sources */,
				F9FFAF200DFDDB32007F8A6A /* tclOOBasic.c in Sources */,
				F9FFAF210DFDDB32007F8A6A /* tclOOCall.c in Sources */,
				F9FFAF220DFDDB34007F8A6A /* tclOODefineCmds.c in Sources */,
				F9FFAF230DFDDB35007F8A6A /* tclOOInfo.c in Sources */,
				F9FFAF240DFDDB36007F8A6A /* tclOOMethod.c in Sources */,
				F9FFAF250DFDDB37007F8A6A /* tclOOStubInit.c in Sources */,
				F9FFAF260DFDDB38007F8A6A /* tclOOStubLib.c in Sources */,
				F9FD30E80CC1AD070073837D /* tclPanic.c in Sources */,
				F9FD30E90CC1AD070073837D /* tclParse.c in Sources */,
				F9FD30EA0CC1AD070073837D /* tclPathObj.c in Sources */,
				F9FD30EB0CC1AD070073837D /* tclPipe.c in Sources */,
				F9FD30EC0CC1AD070073837D /* tclPkg.c in Sources */,
				F9FD30ED0CC1AD070073837D /* tclPkgConfig.c in Sources */,
				F9FD30EE0CC1AD070073837D /* tclPosixStr.c in Sources */,
				F9FD30EF0CC1AD070073837D /* tclPreserve.c in Sources */,
				F9FD30F00CC1AD070073837D /* tclProc.c in Sources */,
				F9FD30F10CC1AD070073837D /* tclRegexp.c in Sources */,
				F9FD30F20CC1AD070073837D /* tclResolve.c in Sources */,
				F9FD30F30CC1AD070073837D /* tclResult.c in Sources */,
				F9FD30F40CC1AD070073837D /* tclScan.c in Sources */,
				F9FD30F50CC1AD070073837D /* tclStringObj.c in Sources */,
				F9FD30F60CC1AD070073837D /* tclStrToD.c in Sources */,
				F9FD30F70CC1AD070073837D /* tclStubInit.c in Sources */,
				F9FD30F80CC1AD070073837D /* tclStubLib.c in Sources */,
				F9FD30F90CC1AD070073837D /* tclThread.c in Sources */,
				F9FD30FA0CC1AD070073837D /* tclThreadAlloc.c in Sources */,
				F9FD30FB0CC1AD070073837D /* tclThreadJoin.c in Sources */,
				F9FD30FC0CC1AD070073837D /* tclThreadStorage.c in Sources */,
				F9FD30FD0CC1AD070073837D /* tclTimer.c in Sources */,
				F9FD30FE0CC1AD070073837D /* tclTomMathInterface.c in Sources */,
				F9FD30FF0CC1AD070073837D /* tclTrace.c in Sources */,
				F9FD31000CC1AD070073837D /* tclUtf.c in Sources */,
				F9FD31010CC1AD070073837D /* tclUtil.c in Sources */,
				F9FD31020CC1AD070073837D /* tclVar.c in Sources */,
				F96437CB0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F9FD31030CC1AD070073837D /* bn_fast_s_mp_mul_digs.c in Sources */,
				F9FD31040CC1AD070073837D /* bn_fast_s_mp_sqr.c in Sources */,
				F9FD31050CC1AD070073837D /* bn_mp_add.c in Sources */,
				F9FD31060CC1AD070073837D /* bn_mp_add_d.c in Sources */,
				F9FD31070CC1AD070073837D /* bn_mp_and.c in Sources */,
				F9FD31080CC1AD070073837D /* bn_mp_clamp.c in Sources */,
				F9FD31090CC1AD070073837D /* bn_mp_clear.c in Sources */,
				F9FD310A0CC1AD070073837D /* bn_mp_clear_multi.c in Sources */,
				F9FD310B0CC1AD070073837D /* bn_mp_cmp.c in Sources */,
				F9FD310C0CC1AD070073837D /* bn_mp_cmp_d.c in Sources */,
				F9FD310D0CC1AD070073837D /* bn_mp_cmp_mag.c in Sources */,
				F9FD310E0CC1AD070073837D /* bn_mp_copy.c in Sources */,
				F9FD310F0CC1AD070073837D /* bn_mp_count_bits.c in Sources */,
				F9FD31100CC1AD070073837D /* bn_mp_div.c in Sources */,
				F9FD31110CC1AD070073837D /* bn_mp_div_2.c in Sources */,
				F9FD31120CC1AD070073837D /* bn_mp_div_2d.c in Sources */,
				F9FD31130CC1AD070073837D /* bn_mp_div_3.c in Sources */,
				F9FD31140CC1AD070073837D /* bn_mp_div_d.c in Sources */,
				F9FD31150CC1AD070073837D /* bn_mp_exch.c in Sources */,
				F9FD31160CC1AD070073837D /* bn_mp_expt_d.c in Sources */,
				F9FD31170CC1AD070073837D /* bn_mp_grow.c in Sources */,
				F9FD31180CC1AD070073837D /* bn_mp_init.c in Sources */,
				F9FD31190CC1AD070073837D /* bn_mp_init_copy.c in Sources */,
				F9FD311A0CC1AD070073837D /* bn_mp_init_multi.c in Sources */,
				F9FD311B0CC1AD070073837D /* bn_mp_init_set.c in Sources */,
				F9FD311C0CC1AD070073837D /* bn_mp_init_size.c in Sources */,
				F9FD311D0CC1AD070073837D /* bn_mp_karatsuba_mul.c in Sources */,
				F9FD311E0CC1AD070073837D /* bn_mp_karatsuba_sqr.c in Sources */,
				F9FD311F0CC1AD070073837D /* bn_mp_lshd.c in Sources */,
				F9FD31200CC1AD070073837D /* bn_mp_mod.c in Sources */,
				F9FD31210CC1AD070073837D /* bn_mp_mod_2d.c in Sources */,
				F9FD31220CC1AD070073837D /* bn_mp_mul.c in Sources */,
				F9FD31230CC1AD070073837D /* bn_mp_mul_2.c in Sources */,
				F9FD31240CC1AD070073837D /* bn_mp_mul_2d.c in Sources */,
				F9FD31250CC1AD070073837D /* bn_mp_mul_d.c in Sources */,
				F9FD31260CC1AD070073837D /* bn_mp_neg.c in Sources */,
				F9FD31270CC1AD070073837D /* bn_mp_or.c in Sources */,
				F9FD31280CC1AD070073837D /* bn_mp_radix_size.c in Sources */,
				F9FD31290CC1AD070073837D /* bn_mp_radix_smap.c in Sources */,
				F9FD312A0CC1AD070073837D /* bn_mp_read_radix.c in Sources */,
				F9FD312B0CC1AD070073837D /* bn_mp_rshd.c in Sources */,
				F9FD312C0CC1AD070073837D /* bn_mp_set.c in Sources */,
				F9FD312D0CC1AD070073837D /* bn_mp_shrink.c in Sources */,
				F9FD312E0CC1AD070073837D /* bn_mp_sqr.c in Sources */,
				F9FD312F0CC1AD070073837D /* bn_mp_sqrt.c in Sources */,
				F9FD31300CC1AD070073837D /* bn_mp_sub.c in Sources */,
				F9FD31310CC1AD070073837D /* bn_mp_sub_d.c in Sources */,
				F9FD31320CC1AD070073837D /* bn_mp_to_unsigned_bin_n.c in Sources */,
				F9FD31330CC1AD070073837D /* bn_mp_to_unsigned_bin.c in Sources */,
				F9FD31340CC1AD070073837D /* bn_mp_toom_mul.c in Sources */,
				F9FD31350CC1AD070073837D /* bn_mp_toom_sqr.c in Sources */,
				F9FD31360CC1AD070073837D /* bn_mp_toradix_n.c in Sources */,
				F9FD31370CC1AD070073837D /* bn_mp_unsigned_bin_size.c in Sources */,
				F9FD31380CC1AD070073837D /* bn_mp_xor.c in Sources */,
				F9FD31390CC1AD070073837D /* bn_mp_zero.c in Sources */,
				F9FD313A0CC1AD070073837D /* bn_reverse.c in Sources */,
				F9FD313B0CC1AD070073837D /* bn_s_mp_add.c in Sources */,
				F9FD313C0CC1AD070073837D /* bn_s_mp_mul_digs.c in Sources */,
				F9FD313D0CC1AD070073837D /* bn_s_mp_sqr.c in Sources */,
				F9FD313E0CC1AD070073837D /* bn_s_mp_sub.c in Sources */,
				F9FD313F0CC1AD070073837D /* bncore.c in Sources */,
				F9FD31400CC1AD070073837D /* tclMacOSXBundle.c in Sources */,
				F9FD31410CC1AD070073837D /* tclMacOSXFCmd.c in Sources */,
				F9FD31420CC1AD070073837D /* tclMacOSXNotify.c in Sources */,
				F9FD31430CC1AD070073837D /* tclLoadDyld.c in Sources */,
				F9FD31440CC1AD070073837D /* tclUnixChan.c in Sources */,
				F9FD31450CC1AD070073837D /* tclUnixCompat.c in Sources */,
				F9FD31460CC1AD070073837D /* tclUnixEvent.c in Sources */,
				F9FD31470CC1AD070073837D /* tclUnixFCmd.c in Sources */,
				F9FD31480CC1AD070073837D /* tclUnixFile.c in Sources */,
				F9FD31490CC1AD070073837D /* tclUnixInit.c in Sources */,
				F9FD314A0CC1AD070073837D /* tclUnixNotfy.c in Sources */,
				F9FD314B0CC1AD070073837D /* tclUnixPipe.c in Sources */,
				F9FD314C0CC1AD070073837D /* tclUnixSock.c in Sources */,
				F9FD314D0CC1AD070073837D /* tclUnixThrd.c in Sources */,
				F9FD314E0CC1AD070073837D /* tclUnixTime.c in Sources */,
				F9FD31E20CC1AD070073837D /* tclDTrace.d in Sources */,
				F9FD314F0CC1AD070073837D /* tk3d.c in Sources */,
				F9FD31500CC1AD070073837D /* tkArgv.c in Sources */,
				F9FD31510CC1AD070073837D /* tkAtom.c in Sources */,
				F9FD31520CC1AD070073837D /* tkBind.c in Sources */,
				F9FD31530CC1AD070073837D /* tkBitmap.c in Sources */,
				F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */,
				F9FD31540CC1AD070073837D /* tkButton.c in Sources */,
				F9FD31550CC1AD070073837D /* tkCanvArc.c in Sources */,
				F9FD31560CC1AD070073837D /* tkCanvas.c in Sources */,
				F9FD31570CC1AD070073837D /* tkCanvBmap.c in Sources */,
				F9FD31580CC1AD070073837D /* tkCanvImg.c in Sources */,
				F9FD31590CC1AD070073837D /* tkCanvLine.c in Sources */,
				F9FD315A0CC1AD070073837D /* tkCanvPoly.c in Sources */,
				F9FD315B0CC1AD070073837D /* tkCanvPs.c in Sources */,
				F9FD315C0CC1AD070073837D /* tkCanvText.c in Sources */,
				F9FD315D0CC1AD070073837D /* tkCanvUtil.c in Sources */,
				F9FD315E0CC1AD070073837D /* tkCanvWind.c in Sources */,
				F9FD315F0CC1AD070073837D /* tkClipboard.c in Sources */,
				F9FD31600CC1AD070073837D /* tkCmds.c in Sources */,
				F9FD31610CC1AD070073837D /* tkColor.c in Sources */,
				F9FD31620CC1AD070073837D /* tkConfig.c in Sources */,
				F9FD31630CC1AD070073837D /* tkConsole.c in Sources */,
				F9FD31640CC1AD070073837D /* tkCursor.c in Sources */,
				F9FD31650CC1AD070073837D /* tkEntry.c in Sources */,
				F9FD31660CC1AD070073837D /* tkError.c in Sources */,
				F9FD31670CC1AD070073837D /* tkEvent.c in Sources */,
				F9FD31680CC1AD070073837D /* tkFileFilter.c in Sources */,
				F9FD31690CC1AD070073837D /* tkFocus.c in Sources */,
				F9FD316A0CC1AD070073837D /* tkFont.c in Sources */,
				F9FD316B0CC1AD070073837D /* tkFrame.c in Sources */,
				F9FD316C0CC1AD070073837D /* tkGC.c in Sources */,
				F9FD316D0CC1AD070073837D /* tkGeometry.c in Sources */,
				F9FD316E0CC1AD070073837D /* tkGet.c in Sources */,
				F9FD316F0CC1AD070073837D /* tkGrab.c in Sources */,
				F9FD31700CC1AD070073837D /* tkGrid.c in Sources */,
				F9FD31710CC1AD070073837D /* tkImage.c in Sources */,
				F9FD31720CC1AD070073837D /* tkImgBmap.c in Sources */,
				F9FD31730CC1AD070073837D /* tkImgGIF.c in Sources */,
				F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */,
				F9FD31740CC1AD070073837D /* tkImgPhoto.c in Sources */,
				F9DD99BE0F07DF850018B2E4 /* tkImgPNG.c in Sources */,
				F9FD31750CC1AD070073837D /* tkImgPPM.c in Sources */,
				F9FD31760CC1AD070073837D /* tkListbox.c in Sources */,
				F9FD31770CC1AD070073837D /* tkMacWinMenu.c in Sources */,
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,
				F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */,
				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,
				F9FD31880CC1AD070073837D /* tkSelect.c in Sources */,
				F9FD31890CC1AD070073837D /* tkSquare.c in Sources */,
				F9FD318A0CC1AD070073837D /* tkStubInit.c in Sources */,
				F9FD318B0CC1AD070073837D /* tkStubLib.c in Sources */,
				F9FD318C0CC1AD070073837D /* tkStyle.c in Sources */,
				F9FD318D0CC1AD070073837D /* tkTest.c in Sources */,
				F9FD318E0CC1AD070073837D /* tkText.c in Sources */,
				F9FD318F0CC1AD070073837D /* tkTextBTree.c in Sources */,
				F9FD31900CC1AD070073837D /* tkTextDisp.c in Sources */,
				F9FD31910CC1AD070073837D /* tkTextImage.c in Sources */,
				F9FD31920CC1AD070073837D /* tkTextIndex.c in Sources */,
				F9FD31930CC1AD070073837D /* tkTextMark.c in Sources */,
				F9FD31940CC1AD070073837D /* tkTextTag.c in Sources */,
				F9FD31950CC1AD070073837D /* tkTextWind.c in Sources */,
				F9FD31960CC1AD070073837D /* tkTrig.c in Sources */,
				F9FD31970CC1AD070073837D /* tkUndo.c in Sources */,
				F9FD31980CC1AD070073837D /* tkUtil.c in Sources */,
				F9FD31990CC1AD070073837D /* tkVisual.c in Sources */,
				F9FD319A0CC1AD070073837D /* tkWindow.c in Sources */,
				F9FD319B0CC1AD070073837D /* ttkBlink.c in Sources */,
				F9FD319C0CC1AD070073837D /* ttkButton.c in Sources */,
				F9FD319D0CC1AD070073837D /* ttkCache.c in Sources */,
				F9FD319E0CC1AD070073837D /* ttkClamTheme.c in Sources */,
				F9FD319F0CC1AD070073837D /* ttkClassicTheme.c in Sources */,
				F9FD31A00CC1AD070073837D /* ttkDefaultTheme.c in Sources */,
				F9FD31A10CC1AD070073837D /* ttkElements.c in Sources */,
				F9FD31A20CC1AD070073837D /* ttkEntry.c in Sources */,
				F9FD31A30CC1AD070073837D /* ttkFrame.c in Sources */,
				F9FD31A40CC1AD070073837D /* ttkImage.c in Sources */,
				F9FD31A50CC1AD070073837D /* ttkInit.c in Sources */,
				F9FD31A60CC1AD070073837D /* ttkLabel.c in Sources */,
				F9FD31A70CC1AD070073837D /* ttkLayout.c in Sources */,
				F9FD31A80CC1AD070073837D /* ttkManager.c in Sources */,
				F9FD31A90CC1AD070073837D /* ttkNotebook.c in Sources */,
				F9FD31AA0CC1AD070073837D /* ttkPanedwindow.c in Sources */,
				F9FD31AB0CC1AD070073837D /* ttkProgress.c in Sources */,
				F9FD31AC0CC1AD070073837D /* ttkScale.c in Sources */,
				F9FD31AD0CC1AD070073837D /* ttkScroll.c in Sources */,
				F9FD31AE0CC1AD070073837D /* ttkScrollbar.c in Sources */,
				F9FD31AF0CC1AD070073837D /* ttkSeparator.c in Sources */,
				F9FD31B00CC1AD070073837D /* ttkSquare.c in Sources */,
				F9FD31B10CC1AD070073837D /* ttkState.c in Sources */,
				F9FD31B20CC1AD070073837D /* ttkStubInit.c in Sources */,
				F9FD31B30CC1AD070073837D /* ttkStubLib.c in Sources */,
				F9FD31B40CC1AD070073837D /* ttkTagSet.c in Sources */,
				F9FD31B50CC1AD070073837D /* ttkTheme.c in Sources */,
				F9FD31B60CC1AD070073837D /* ttkTrace.c in Sources */,
				F9FD31B70CC1AD070073837D /* ttkTrack.c in Sources */,
				F9FD31B80CC1AD070073837D /* ttkTreeview.c in Sources */,
				F9FD31B90CC1AD070073837D /* ttkWidget.c in Sources */,
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,
				F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */,
				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,
				F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */,
				F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */,
				F9FD31DC0CC1AD070073837D /* tkUnixScale.c in Sources */,
				F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */,
				F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */,
				F9FD31FE0CC1ADB70073837D /* tkUnixSend.c in Sources */,
				F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */,
				F9FD31FB0CC1ADB70073837D /* tkUnixXId.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		F90E36D50F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoGC;
		};
		F90E36D60F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoGC;
		};
		F90E36D70F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoGC;
		};
		F90E36D80F3B5C8400810A10 /* DebugNoGC */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoGC;
		};
		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal;
		};
		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = ReleaseUniversal;
		};
		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugMemCompile;
		};
		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugMemCompile;
		};
		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugMemCompile;
		};
		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugMemCompile;
		};
		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS)",
					"-lgcov",
				);
				PREBINDING = NO;
			};
			name = DebugGCov;
		};
		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugGCov;
		};
		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugGCov;
		};
		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugGCov;
		};
		F95CC8AC09158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug;
		};
		F95CC8AD09158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Release;
		};
		F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B109158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug;
		};
		F95CC8B209158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Release;
		};
		F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B609158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Debug;
		};
		F95CC8B709158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Release;
		};
		F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F97258A90A86873D00096C78 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug;
		};
		F97258AA0A86873D00096C78 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Release;
		};
		F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixAndContinue;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};
		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug64bit;
		};
		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug64bit;
		};
		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug64bit;
		};
		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_64_BIT)";
				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = Debug64bit;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCF;
		};
		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCF;
		};
		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCF;
		};
		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};
		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCFUnthreaded;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB20D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB30D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug gcc40";
		};
		F9988AB40D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug gcc40";
		};
		F9988AB50D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB60D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB70D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB80D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "Debug llvm-gcc";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugUnthreaded;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};
		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugUnthreaded;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};
		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (
					PURIFY,
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugLeaks;
		};
		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				SDKROOT = macosx10.5;
			};
			name = ReleaseUniversal10.5SDK;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
				F90E36D60F3B5C8400810A10 /* DebugNoGC */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F97AED1B0B660B2100310EA2 /* Debug64bit */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
				F90E36D70F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F97AED1C0B660B2100310EA2 /* Debug64bit */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
				F90E36D50F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F97AED1E0B660B2100310EA2 /* Debug64bit */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
				F90E36D80F3B5C8400810A10 /* DebugNoGC */,
				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97AED1D0B660B2100310EA2 /* Debug64bit */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
/* End XCConfigurationList section */
	};
	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to macosx/Tk.xcodeproj/project.pbxproj.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };









<







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */

		F9152B090EAF8A5000CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F9152B0A0EAF8A5700CD5C7B /* tkBusy.c in Sources */ = {isa = PBXBuildFile; fileRef = F9152B080EAF8A5000CD5C7B /* tkBusy.c */; };
		F92EE8BF0E62F846001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F92EE8D30E62F939001A6E80 /* tkImgPhInstance.c in Sources */ = {isa = PBXBuildFile; fileRef = F92EE8BE0E62F846001A6E80 /* tkImgPhInstance.c */; };
		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };
		F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAFE08F27A39005CB29B /* tkOldTest.c */; };
		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };







<







515
516
517
518
519
520
521

522
523
524
525
526
527
528
		F9FD31780CC1AD070073837D /* tkMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE608F27A39005CB29B /* tkMain.c */; };
		F9FD31790CC1AD070073837D /* tkMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE708F27A39005CB29B /* tkMenu.c */; };
		F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAE908F27A39005CB29B /* tkMenubutton.c */; };
		F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEB08F27A39005CB29B /* tkMenuDraw.c */; };
		F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEC08F27A39005CB29B /* tkMessage.c */; };
		F9FD317D0CC1AD070073837D /* tkObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAED08F27A39005CB29B /* tkObj.c */; };
		F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEE08F27A39005CB29B /* tkOldConfig.c */; };

		F9FD31800CC1AD070073837D /* tkOption.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAEF08F27A39005CB29B /* tkOption.c */; };
		F9FD31810CC1AD070073837D /* tkPack.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF008F27A39005CB29B /* tkPack.c */; };
		F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF108F27A39005CB29B /* tkPanedWindow.c */; };
		F9FD31830CC1AD070073837D /* tkPlace.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF208F27A39005CB29B /* tkPlace.c */; };
		F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF608F27A39005CB29B /* tkRectOval.c */; };
		F9FD31860CC1AD070073837D /* tkScale.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF708F27A39005CB29B /* tkScale.c */; };
		F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BAF908F27A39005CB29B /* tkScrollbar.c */; };
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };
		F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */; };
		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };







<







590
591
592
593
594
595
596

597
598
599
600
601
602
603
		F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8308F27A3D005CB29B /* tkUnixFocus.c */; };
		F9FD32000CC1ADB70073837D /* tkUnixWm.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC9008F27A3D005CB29B /* tkUnixWm.c */; };
		F9FD32010CC1ADB70073837D /* tkUnixRFont.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8B08F27A3D005CB29B /* tkUnixRFont.c */; };
		F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7808F27A3D005CB29B /* tkUnix.c */; };
		F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8808F27A3D005CB29B /* tkUnixMenu.c */; };
		F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */; };
		F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8008F27A3D005CB29B /* tkUnixDraw.c */; };

		F9FD32070CC1ADB70073837D /* tkUnixSelect.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8E08F27A3D005CB29B /* tkUnixSelect.c */; };
		F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8208F27A3D005CB29B /* tkUnixEvent.c */; };
		F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7B08F27A3D005CB29B /* tkUnixColor.c */; };
		F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC7A08F27A3D005CB29B /* tkUnixButton.c */; };
		F9FD320B0CC1ADB70073837D /* tkUnixMenubu.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8908F27A3D005CB29B /* tkUnixMenubu.c */; };
		F9FD320C0CC1ADB70073837D /* tkUnixScrlbr.c in Sources */ = {isa = PBXBuildFile; fileRef = F966BC8D08F27A3D005CB29B /* tkUnixScrlbr.c */; };
		F9FD32170CC1AF170073837D /* libX11.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F9FD32140CC1AF170073837D /* libX11.dylib */; };
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };
		F966BA0E08F27A37005CB29B /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F966BA0F08F27A37005CB29B /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };







<
|







678
679
680
681
682
683
684

685
686
687
688
689
690
691
692
		F966BA0708F27A37005CB29B /* gray50.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray50.xbm; sourceTree = "<group>"; };
		F966BA0808F27A37005CB29B /* gray75.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = gray75.xbm; sourceTree = "<group>"; };
		F966BA0908F27A37005CB29B /* hourglass.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = hourglass.xbm; sourceTree = "<group>"; };
		F966BA0A08F27A37005CB29B /* info.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = info.xbm; sourceTree = "<group>"; };
		F966BA0B08F27A37005CB29B /* questhead.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = questhead.xbm; sourceTree = "<group>"; };
		F966BA0C08F27A37005CB29B /* question.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = question.xbm; sourceTree = "<group>"; };
		F966BA0D08F27A37005CB29B /* warning.xbm */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = warning.xbm; sourceTree = "<group>"; };

		F966BA0F08F27A37005CB29B /* changes.md */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes.md; sourceTree = "<group>"; };
		F966BA1108F27A37005CB29B /* 3DBorder.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = 3DBorder.3; sourceTree = "<group>"; };
		F966BA1208F27A37005CB29B /* AddOption.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddOption.3; sourceTree = "<group>"; };
		F966BA1308F27A37005CB29B /* bell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bell.n; sourceTree = "<group>"; };
		F966BA1408F27A37005CB29B /* bind.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bind.n; sourceTree = "<group>"; };
		F966BA1508F27A37005CB29B /* BindTable.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BindTable.3; sourceTree = "<group>"; };
		F966BA1608F27A37005CB29B /* bindtags.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bindtags.n; sourceTree = "<group>"; };
		F966BA1708F27A37005CB29B /* bitmap.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bitmap.n; sourceTree = "<group>"; };
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };
		F966BA7108F27A38005CB29B /* menubar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubar.n; sourceTree = "<group>"; };
		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };
		F966BA7C08F27A38005CB29B /* pack-old.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = "pack-old.n"; sourceTree = "<group>"; };
		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };







<










<







774
775
776
777
778
779
780

781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
		F966BA6908F27A38005CB29B /* MainLoop.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainLoop.3; sourceTree = "<group>"; };
		F966BA6A08F27A38005CB29B /* MaintGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MaintGeom.3; sourceTree = "<group>"; };
		F966BA6B08F27A38005CB29B /* MainWin.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MainWin.3; sourceTree = "<group>"; };
		F966BA6D08F27A38005CB29B /* ManageGeom.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ManageGeom.3; sourceTree = "<group>"; };
		F966BA6E08F27A38005CB29B /* MapWindow.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MapWindow.3; sourceTree = "<group>"; };
		F966BA6F08F27A38005CB29B /* MeasureChar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MeasureChar.3; sourceTree = "<group>"; };
		F966BA7008F27A38005CB29B /* menu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menu.n; sourceTree = "<group>"; };

		F966BA7208F27A38005CB29B /* menubutton.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = menubutton.n; sourceTree = "<group>"; };
		F966BA7308F27A38005CB29B /* message.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = message.n; sourceTree = "<group>"; };
		F966BA7408F27A38005CB29B /* messageBox.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = messageBox.n; sourceTree = "<group>"; };
		F966BA7508F27A38005CB29B /* MoveToplev.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = MoveToplev.3; sourceTree = "<group>"; };
		F966BA7608F27A38005CB29B /* Name.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Name.3; sourceTree = "<group>"; };
		F966BA7708F27A38005CB29B /* NameOfImg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = NameOfImg.3; sourceTree = "<group>"; };
		F966BA7808F27A38005CB29B /* option.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = option.n; sourceTree = "<group>"; };
		F966BA7908F27A38005CB29B /* optionMenu.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = optionMenu.n; sourceTree = "<group>"; };
		F966BA7A08F27A38005CB29B /* options.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = options.n; sourceTree = "<group>"; };
		F966BA7B08F27A38005CB29B /* OwnSelect.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OwnSelect.3; sourceTree = "<group>"; };

		F966BA7D08F27A38005CB29B /* pack.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pack.n; sourceTree = "<group>"; };
		F966BA7E08F27A38005CB29B /* palette.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = palette.n; sourceTree = "<group>"; };
		F966BA7F08F27A38005CB29B /* panedwindow.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = panedwindow.n; sourceTree = "<group>"; };
		F966BA8008F27A38005CB29B /* ParseArgv.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseArgv.3; sourceTree = "<group>"; };
		F966BA8108F27A38005CB29B /* photo.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = photo.n; sourceTree = "<group>"; };
		F966BA8208F27A38005CB29B /* place.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = place.n; sourceTree = "<group>"; };
		F966BA8308F27A38005CB29B /* popup.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = popup.n; sourceTree = "<group>"; };
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };
		F966BAFE08F27A39005CB29B /* tkOldTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkOldTest.c; sourceTree = "<group>"; };
		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };







<







907
908
909
910
911
912
913

914
915
916
917
918
919
920
		F966BAF708F27A39005CB29B /* tkScale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScale.c; sourceTree = "<group>"; };
		F966BAF808F27A39005CB29B /* tkScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScale.h; sourceTree = "<group>"; };
		F966BAF908F27A39005CB29B /* tkScrollbar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkScrollbar.c; sourceTree = "<group>"; };
		F966BAFA08F27A39005CB29B /* tkScrollbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkScrollbar.h; sourceTree = "<group>"; };
		F966BAFB08F27A39005CB29B /* tkSelect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSelect.c; sourceTree = "<group>"; };
		F966BAFC08F27A39005CB29B /* tkSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkSelect.h; sourceTree = "<group>"; };
		F966BAFD08F27A39005CB29B /* tkSquare.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkSquare.c; sourceTree = "<group>"; };

		F966BAFF08F27A39005CB29B /* tkStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubInit.c; sourceTree = "<group>"; };
		F966BB0008F27A39005CB29B /* tkStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStubLib.c; sourceTree = "<group>"; };
		F966BB0108F27A39005CB29B /* tkStyle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkStyle.c; sourceTree = "<group>"; };
		F966BB0208F27A39005CB29B /* tkTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTest.c; sourceTree = "<group>"; };
		F966BB0308F27A39005CB29B /* tkText.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkText.c; sourceTree = "<group>"; };
		F966BB0408F27A39005CB29B /* tkText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkText.h; sourceTree = "<group>"; };
		F966BB0508F27A39005CB29B /* tkTextBTree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkTextBTree.c; sourceTree = "<group>"; };
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
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };
		F966BB8608F27A3A005CB29B /* obsolete.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obsolete.tcl; sourceTree = "<group>"; };
		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };
		F966BB9408F27A3B005CB29B /* unsupported.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unsupported.tcl; sourceTree = "<group>"; };
		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };







<












<







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
		F966BB6208F27A3A005CB29B /* dialog.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dialog.tcl; sourceTree = "<group>"; };
		F966BB6308F27A3A005CB29B /* entry.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = entry.tcl; sourceTree = "<group>"; };
		F966BB6408F27A3A005CB29B /* focus.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = focus.tcl; sourceTree = "<group>"; };
		F966BB7308F27A3A005CB29B /* listbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listbox.tcl; sourceTree = "<group>"; };
		F966BB7408F27A3A005CB29B /* menu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.tcl; sourceTree = "<group>"; };
		F966BB7508F27A3A005CB29B /* mkpsenc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mkpsenc.tcl; sourceTree = "<group>"; };
		F966BB7608F27A3A005CB29B /* msgbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.tcl; sourceTree = "<group>"; };

		F966BB8708F27A3A005CB29B /* optMenu.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optMenu.tcl; sourceTree = "<group>"; };
		F966BB8808F27A3A005CB29B /* palette.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = palette.tcl; sourceTree = "<group>"; };
		F966BB8908F27A3B005CB29B /* panedwindow.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.tcl; sourceTree = "<group>"; };
		F966BB8B08F27A3B005CB29B /* safetk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safetk.tcl; sourceTree = "<group>"; };
		F966BB8C08F27A3B005CB29B /* scale.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scale.tcl; sourceTree = "<group>"; };
		F966BB8D08F27A3B005CB29B /* scrlbar.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scrlbar.tcl; sourceTree = "<group>"; };
		F966BB8E08F27A3B005CB29B /* spinbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = spinbox.tcl; sourceTree = "<group>"; };
		F966BB8F08F27A3B005CB29B /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F966BB9008F27A3B005CB29B /* tearoff.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tearoff.tcl; sourceTree = "<group>"; };
		F966BB9108F27A3B005CB29B /* text.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = text.tcl; sourceTree = "<group>"; };
		F966BB9208F27A3B005CB29B /* tk.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tk.tcl; sourceTree = "<group>"; };
		F966BB9308F27A3B005CB29B /* tkfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tkfbox.tcl; sourceTree = "<group>"; };

		F966BB9508F27A3B005CB29B /* xmfbox.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.tcl; sourceTree = "<group>"; };
		F966BB9608F27A3B005CB29B /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F966BBBA08F27A3B005CB29B /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F966BBBB08F27A3B005CB29B /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F966BBBE08F27A3B005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F966BBC008F27A3B005CB29B /* Tk-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tk-Info.plist.in"; sourceTree = "<group>"; };
		F966BBC208F27A3B005CB29B /* tkMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkMacOSX.h; sourceTree = "<group>"; };
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F966BC3F08F27A3C005CB29B /* oldpack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oldpack.test; sourceTree = "<group>"; };
		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };







<







1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
		F966BC3808F27A3C005CB29B /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F966BC3908F27A3C005CB29B /* menu.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menu.test; sourceTree = "<group>"; };
		F966BC3A08F27A3C005CB29B /* menubut.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menubut.test; sourceTree = "<group>"; };
		F966BC3B08F27A3C005CB29B /* menuDraw.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = menuDraw.test; sourceTree = "<group>"; };
		F966BC3C08F27A3C005CB29B /* message.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = message.test; sourceTree = "<group>"; };
		F966BC3D08F27A3C005CB29B /* msgbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgbox.test; sourceTree = "<group>"; };
		F966BC3E08F27A3C005CB29B /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };

		F966BC4008F27A3C005CB29B /* option.file1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file1; sourceTree = "<group>"; };
		F966BC4108F27A3C005CB29B /* option.file2 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = option.file2; sourceTree = "<group>"; };
		F966BC4208F27A3C005CB29B /* option.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = option.test; sourceTree = "<group>"; };
		F966BC4308F27A3C005CB29B /* pack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pack.test; sourceTree = "<group>"; };
		F966BC4408F27A3C005CB29B /* panedwindow.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = panedwindow.test; sourceTree = "<group>"; };
		F966BC4508F27A3D005CB29B /* place.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = place.test; sourceTree = "<group>"; };
		F966BC4608F27A3D005CB29B /* raise.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = raise.test; sourceTree = "<group>"; };
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };
		F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDialog.c; sourceTree = "<group>"; };
		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };







<







1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184
1185
1186
1187
		F966BC7808F27A3D005CB29B /* tkUnix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix.c; sourceTree = "<group>"; };
		F966BC7908F27A3D005CB29B /* tkUnix3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnix3d.c; sourceTree = "<group>"; };
		F966BC7A08F27A3D005CB29B /* tkUnixButton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixButton.c; sourceTree = "<group>"; };
		F966BC7B08F27A3D005CB29B /* tkUnixColor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixColor.c; sourceTree = "<group>"; };
		F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixConfig.c; sourceTree = "<group>"; };
		F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixCursor.c; sourceTree = "<group>"; };
		F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixDefault.h; sourceTree = "<group>"; };

		F966BC8008F27A3D005CB29B /* tkUnixDraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixDraw.c; sourceTree = "<group>"; };
		F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEmbed.c; sourceTree = "<group>"; };
		F966BC8208F27A3D005CB29B /* tkUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixEvent.c; sourceTree = "<group>"; };
		F966BC8308F27A3D005CB29B /* tkUnixFocus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFocus.c; sourceTree = "<group>"; };
		F966BC8408F27A3D005CB29B /* tkUnixFont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixFont.c; sourceTree = "<group>"; };
		F966BC8508F27A3D005CB29B /* tkUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixInit.c; sourceTree = "<group>"; };
		F966BC8608F27A3D005CB29B /* tkUnixInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkUnixInt.h; sourceTree = "<group>"; };
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };
		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };







<
|







1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1368
		F968887F0AF788F6000797B5 /* ttk_Theme.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_Theme.3; sourceTree = "<group>"; };
		F96888800AF788F6000797B5 /* ttk_treeview.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_treeview.n; sourceTree = "<group>"; };
		F96888810AF788F6000797B5 /* ttk_widget.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ttk_widget.n; sourceTree = "<group>"; };
		F96888840AF78938000797B5 /* ttkMacOSXTheme.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = ttkMacOSXTheme.c; sourceTree = "<group>"; };
		F96888860AF78953000797B5 /* ttkWinMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinMonitor.c; sourceTree = "<group>"; };
		F96888870AF78953000797B5 /* ttkWinTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinTheme.c; sourceTree = "<group>"; };
		F96888880AF78953000797B5 /* ttkWinXPTheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttkWinXPTheme.c; sourceTree = "<group>"; };

		F96D3DFB08F272A4004A47F5 /* changes.md */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes.md; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
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
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,
				F966BA7108F27A38005CB29B /* menubar.n */,
				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,
				F966BA7C08F27A38005CB29B /* pack-old.n */,
				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,







<










<







2236
2237
2238
2239
2240
2241
2242

2243
2244
2245
2246
2247
2248
2249
2250
2251
2252

2253
2254
2255
2256
2257
2258
2259
				F966BA6908F27A38005CB29B /* MainLoop.3 */,
				F966BA6A08F27A38005CB29B /* MaintGeom.3 */,
				F966BA6B08F27A38005CB29B /* MainWin.3 */,
				F966BA6D08F27A38005CB29B /* ManageGeom.3 */,
				F966BA6E08F27A38005CB29B /* MapWindow.3 */,
				F966BA6F08F27A38005CB29B /* MeasureChar.3 */,
				F966BA7008F27A38005CB29B /* menu.n */,

				F966BA7208F27A38005CB29B /* menubutton.n */,
				F966BA7308F27A38005CB29B /* message.n */,
				F966BA7408F27A38005CB29B /* messageBox.n */,
				F966BA7508F27A38005CB29B /* MoveToplev.3 */,
				F966BA7608F27A38005CB29B /* Name.3 */,
				F966BA7708F27A38005CB29B /* NameOfImg.3 */,
				F966BA7808F27A38005CB29B /* option.n */,
				F966BA7908F27A38005CB29B /* optionMenu.n */,
				F966BA7A08F27A38005CB29B /* options.n */,
				F966BA7B08F27A38005CB29B /* OwnSelect.3 */,

				F966BA7D08F27A38005CB29B /* pack.n */,
				F966BA7E08F27A38005CB29B /* palette.n */,
				F966BA7F08F27A38005CB29B /* panedwindow.n */,
				F966BA8008F27A38005CB29B /* ParseArgv.3 */,
				F966BA8108F27A38005CB29B /* photo.n */,
				F966BA8208F27A38005CB29B /* place.n */,
				F966BA8308F27A38005CB29B /* popup.n */,
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,
				F966BAFE08F27A39005CB29B /* tkOldTest.c */,
				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,







<







2401
2402
2403
2404
2405
2406
2407

2408
2409
2410
2411
2412
2413
2414
				F966BAF708F27A39005CB29B /* tkScale.c */,
				F966BAF808F27A39005CB29B /* tkScale.h */,
				F966BAF908F27A39005CB29B /* tkScrollbar.c */,
				F966BAFA08F27A39005CB29B /* tkScrollbar.h */,
				F966BAFB08F27A39005CB29B /* tkSelect.c */,
				F966BAFC08F27A39005CB29B /* tkSelect.h */,
				F966BAFD08F27A39005CB29B /* tkSquare.c */,

				F966BAFF08F27A39005CB29B /* tkStubInit.c */,
				F966BB0008F27A39005CB29B /* tkStubLib.c */,
				F966BB0108F27A39005CB29B /* tkStyle.c */,
				F966BB0208F27A39005CB29B /* tkTest.c */,
				F966BB0308F27A39005CB29B /* tkText.c */,
				F966BB0408F27A39005CB29B /* tkText.h */,
				F966BB0508F27A39005CB29B /* tkTextBTree.c */,
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
				F99388380EE0114B0065FE6B /* fontchooser.tcl */,
				F974D57C0FBE7EFF00BF728B /* iconlist.tcl */,
				F974D57D0FBE7EFF00BF728B /* icons.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,
				F966BB8608F27A3A005CB29B /* obsolete.tcl */,
				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,
				F966BB9408F27A3B005CB29B /* unsupported.tcl */,
				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;







<













<







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
				F99388380EE0114B0065FE6B /* fontchooser.tcl */,
				F974D57C0FBE7EFF00BF728B /* iconlist.tcl */,
				F974D57D0FBE7EFF00BF728B /* icons.tcl */,
				F966BB7308F27A3A005CB29B /* listbox.tcl */,
				F966BB7408F27A3A005CB29B /* menu.tcl */,
				F966BB7508F27A3A005CB29B /* mkpsenc.tcl */,
				F966BB7608F27A3A005CB29B /* msgbox.tcl */,

				F966BB8708F27A3A005CB29B /* optMenu.tcl */,
				F966BB8808F27A3A005CB29B /* palette.tcl */,
				F966BB8908F27A3B005CB29B /* panedwindow.tcl */,
				F966BB8B08F27A3B005CB29B /* safetk.tcl */,
				F966BB8C08F27A3B005CB29B /* scale.tcl */,
				F966BB8D08F27A3B005CB29B /* scrlbar.tcl */,
				F966BB8E08F27A3B005CB29B /* spinbox.tcl */,
				F966BB8F08F27A3B005CB29B /* tclIndex */,
				F966BB9008F27A3B005CB29B /* tearoff.tcl */,
				F966BB9108F27A3B005CB29B /* text.tcl */,
				F966BB9208F27A3B005CB29B /* tk.tcl */,
				F966BB9308F27A3B005CB29B /* tkfbox.tcl */,
				F96888360AF787B3000797B5 /* ttk */,

				F966BB9508F27A3B005CB29B /* xmfbox.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F966BB1A08F27A39005CB29B /* demos */ = {
			isa = PBXGroup;
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,
				F966BC3F08F27A3C005CB29B /* oldpack.test */,
				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,







<







2661
2662
2663
2664
2665
2666
2667

2668
2669
2670
2671
2672
2673
2674
				F966BC3808F27A3C005CB29B /* main.test */,
				F966BC3908F27A3C005CB29B /* menu.test */,
				F966BC3A08F27A3C005CB29B /* menubut.test */,
				F966BC3B08F27A3C005CB29B /* menuDraw.test */,
				F966BC3C08F27A3C005CB29B /* message.test */,
				F966BC3D08F27A3C005CB29B /* msgbox.test */,
				F966BC3E08F27A3C005CB29B /* obj.test */,

				F966BC4008F27A3C005CB29B /* option.file1 */,
				F966BC4108F27A3C005CB29B /* option.file2 */,
				F966BC4208F27A3C005CB29B /* option.test */,
				F966BC4308F27A3C005CB29B /* pack.test */,
				F966BC4408F27A3C005CB29B /* panedwindow.test */,
				F966BC4508F27A3D005CB29B /* place.test */,
				F966BC4608F27A3D005CB29B /* raise.test */,
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,
				F966BC7F08F27A3D005CB29B /* tkUnixDialog.c */,
				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,







<







2732
2733
2734
2735
2736
2737
2738

2739
2740
2741
2742
2743
2744
2745
				F966BC7808F27A3D005CB29B /* tkUnix.c */,
				F966BC7908F27A3D005CB29B /* tkUnix3d.c */,
				F966BC7A08F27A3D005CB29B /* tkUnixButton.c */,
				F966BC7B08F27A3D005CB29B /* tkUnixColor.c */,
				F966BC7C08F27A3D005CB29B /* tkUnixConfig.c */,
				F966BC7D08F27A3D005CB29B /* tkUnixCursor.c */,
				F966BC7E08F27A3D005CB29B /* tkUnixDefault.h */,

				F966BC8008F27A3D005CB29B /* tkUnixDraw.c */,
				F966BC8108F27A3D005CB29B /* tkUnixEmbed.c */,
				F966BC8208F27A3D005CB29B /* tkUnixEvent.c */,
				F966BC8308F27A3D005CB29B /* tkUnixFocus.c */,
				F966BC8408F27A3D005CB29B /* tkUnixFont.c */,
				F966BC8508F27A3D005CB29B /* tkUnixInit.c */,
				F966BC8608F27A3D005CB29B /* tkUnixInt.h */,
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
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F9183E690EFC81560030B814 /* pkgs */,
				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
				F96D3DFB08F272A4004A47F5 /* changes */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,
				F966BA0E08F27A37005CB29B /* ChangeLog */,
				F966BA0F08F27A37005CB29B /* changes */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {







<
|


















<
|







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
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F9183E690EFC81560030B814 /* pkgs */,

				F96D3DFB08F272A4004A47F5 /* changes.md */,
				F96D434308F272B5004A47F5 /* README */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DF708F271BE004A47F5 /* Tk Sources */ = {
			isa = PBXGroup;
			children = (
				F966BAA508F27A38005CB29B /* generic */,
				F966BB9708F27A3B005CB29B /* macosx */,
				F966BC6B08F27A3D005CB29B /* unix */,
				F966BD1908F27A3F005CB29B /* xlib */,
				F966BA0308F27A37005CB29B /* bitmaps */,
				F966BC9208F27A3D005CB29B /* win */,
				F966BB1308F27A39005CB29B /* library */,
				F966BC0408F27A3C005CB29B /* tests */,
				F966BA1008F27A37005CB29B /* doc */,

				F966BA0F08F27A37005CB29B /* changes.md */,
				F966BC0308F27A3C005CB29B /* README */,
				F966BB9608F27A3B005CB29B /* license.terms */,
			);
			name = "Tk Sources";
			sourceTree = TK_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,
				F9067BCD0BFBA2900074F726 /* tkOldTest.c in Sources */,
				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,







<







4237
4238
4239
4240
4241
4242
4243

4244
4245
4246
4247
4248
4249
4250
				F966BE0908F27A3F005CB29B /* tkMain.c in Sources */,
				F966BE0A08F27A3F005CB29B /* tkMenu.c in Sources */,
				F966BE0C08F27A3F005CB29B /* tkMenubutton.c in Sources */,
				F966BE0E08F27A3F005CB29B /* tkMenuDraw.c in Sources */,
				F966BE0F08F27A3F005CB29B /* tkMessage.c in Sources */,
				F966BE1008F27A3F005CB29B /* tkObj.c in Sources */,
				F966BE1108F27A3F005CB29B /* tkOldConfig.c in Sources */,

				F966BE1208F27A3F005CB29B /* tkOption.c in Sources */,
				F966BE1308F27A3F005CB29B /* tkPack.c in Sources */,
				F966BE1408F27A3F005CB29B /* tkPanedWindow.c in Sources */,
				F966BE1508F27A3F005CB29B /* tkPlace.c in Sources */,
				F966BE1708F27A3F005CB29B /* tkPointer.c in Sources */,
				F966BE1908F27A3F005CB29B /* tkRectOval.c in Sources */,
				F966BE1A08F27A3F005CB29B /* tkScale.c in Sources */,
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,
				F9FD317F0CC1AD070073837D /* tkOldTest.c in Sources */,
				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,







<







4550
4551
4552
4553
4554
4555
4556

4557
4558
4559
4560
4561
4562
4563
				F9FD31780CC1AD070073837D /* tkMain.c in Sources */,
				F9FD31790CC1AD070073837D /* tkMenu.c in Sources */,
				F9FD317A0CC1AD070073837D /* tkMenubutton.c in Sources */,
				F9FD317B0CC1AD070073837D /* tkMenuDraw.c in Sources */,
				F9FD317C0CC1AD070073837D /* tkMessage.c in Sources */,
				F9FD317D0CC1AD070073837D /* tkObj.c in Sources */,
				F9FD317E0CC1AD070073837D /* tkOldConfig.c in Sources */,

				F9FD31800CC1AD070073837D /* tkOption.c in Sources */,
				F9FD31810CC1AD070073837D /* tkPack.c in Sources */,
				F9FD31820CC1AD070073837D /* tkPanedWindow.c in Sources */,
				F9FD31830CC1AD070073837D /* tkPlace.c in Sources */,
				F9FD31850CC1AD070073837D /* tkRectOval.c in Sources */,
				F9FD31860CC1AD070073837D /* tkScale.c in Sources */,
				F9FD31870CC1AD070073837D /* tkScrollbar.c in Sources */,
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,
				F9FD32060CC1ADB70073837D /* tkUnixDialog.c in Sources */,
				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,







<







4614
4615
4616
4617
4618
4619
4620

4621
4622
4623
4624
4625
4626
4627
				F9FD31DA0CC1AD070073837D /* tkAppInit.c in Sources */,
				F9FD32020CC1ADB70073837D /* tkUnix.c in Sources */,
				F9FD31DB0CC1AD070073837D /* tkUnix3d.c in Sources */,
				F9FD320A0CC1ADB70073837D /* tkUnixButton.c in Sources */,
				F9FD32090CC1ADB70073837D /* tkUnixColor.c in Sources */,
				F9FD32040CC1ADB70073837D /* tkUnixConfig.c in Sources */,
				F9FD31F80CC1ADB70073837D /* tkUnixCursor.c in Sources */,

				F9FD32050CC1ADB70073837D /* tkUnixDraw.c in Sources */,
				F9FD31FD0CC1ADB70073837D /* tkUnixEmbed.c in Sources */,
				F9FD32080CC1ADB70073837D /* tkUnixEvent.c in Sources */,
				F9FD31FF0CC1ADB70073837D /* tkUnixFocus.c in Sources */,
				F9FD31FC0CC1ADB70073837D /* tkUnixInit.c in Sources */,
				F9FD31FA0CC1ADB70073837D /* tkUnixKey.c in Sources */,
				F9FD32030CC1ADB70073837D /* tkUnixMenu.c in Sources */,
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};







|
|







4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
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
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixAndContinue;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};
		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = Debug64bit;
		};
		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = Debug64bit;
		};
		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = Debug64bit;
		};
		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = "$(NATIVE_ARCH_64_BIT)";
				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = Debug64bit;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",







|
|














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoFixAndContinue;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal;
		};




















































		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
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
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};
		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-corefoundation";
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugNoCFUnthreaded;
		};
		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCFUnthreaded;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







5107
5108
5109
5110
5111
5112
5113


























































5114
5115
5116
5117
5118
5119
5120
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugNoCF;
		};


























































		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
			};
			name = "Debug llvm-gcc";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;







|
|







5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
			};
			name = "Debug llvm-gcc";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
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
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;







|
|


















|
|







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
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = "llvm-gcc";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
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
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugUnthreaded;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};
		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugUnthreaded;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};
		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugUnthreaded;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (







|
|














<
<
<
<
<
<
<
<








<
<
<
<
<
<
<
<
<
<
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<







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
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = "ReleaseUniversal llvm-gcc";
		};








		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = Wish;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};











		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS_AQUA)",
					"$(OTHER_LDFLAGS)",
				);
				PRODUCT_NAME = tktest;
			};
			name = DebugLeaks;
		};

















		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = DebugLeaks;
		};




















		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tk-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",

				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = unsupported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_PREPROCESSOR_DEFINITIONS = (
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
		};
		F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CFLAGS = "-arch i386 -arch x86_64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = clang;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;







<

|







5501
5502
5503
5504
5505
5506
5507

5508
5509
5510
5511
5512
5513
5514
5515
5516
		};
		F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",

				);
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = clang;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				GCC_OPTIMIZATION_LEVEL = 4;
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,







|
|







5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
				PRODUCT_NAME = tktest;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
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
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;







|
|


















|
|







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
				PRODUCT_NAME = tktest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_INPUT_FILETYPE = sourcecode.c.c;
				HEADER_SEARCH_PATHS = (
					/usr/X11R6/include,
					/usr/X11R6/include/freetype2,
					"$(HEADER_SEARCH_PATHS)",
				);
				LIBRARY_SEARCH_PATHS = (
					/usr/X11R6/lib,
					"$(LIBRARY_SEARCH_PATHS)",
				);
				PRODUCT_NAME = "tktest-X11";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tk-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_ENABLE_OBJC_GC = supported;
				GCC_ENABLE_PASCAL_STRINGS = NO;
				GCC_INPUT_FILETYPE = sourcecode.c.objc;
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9A9D1F00FC77787002A2BE3 /* Debug clang */,
				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
				F90E36D60F3B5C8400810A10 /* DebugNoGC */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F97AED1B0B660B2100310EA2 /* Debug64bit */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9A9D1F10FC77787002A2BE3 /* Debug clang */,
				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
				F90E36D70F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F97AED1C0B660B2100310EA2 /* Debug64bit */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9A9D1EF0FC77787002A2BE3 /* Debug clang */,
				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
				F90E36D50F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F97AED1E0B660B2100310EA2 /* Debug64bit */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9A9D1F20FC77787002A2BE3 /* Debug clang */,
				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
				F90E36D80F3B5C8400810A10 /* DebugNoGC */,
				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97AED1D0B660B2100310EA2 /* Debug64bit */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);







<

<



<



















<

<



<



















<

<



<



















<

<



<







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
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9A9D1F00FC77787002A2BE3 /* Debug clang */,
				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
				F90E36D60F3B5C8400810A10 /* DebugNoGC */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,

				F98751300DE7B57E00B1C9EC /* DebugNoCF */,

				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,

				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tktest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9A9D1F10FC77787002A2BE3 /* Debug clang */,
				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
				F90E36D70F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,

				F98751310DE7B57E00B1C9EC /* DebugNoCF */,

				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,

				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tk" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9A9D1EF0FC77787002A2BE3 /* Debug clang */,
				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
				F90E36D50F3B5C8400810A10 /* DebugNoGC */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,

				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,

				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,

				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tktest-X11" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9A9D1F20FC77787002A2BE3 /* Debug clang */,
				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
				F90E36D80F3B5C8400810A10 /* DebugNoGC */,
				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,

				F98751320DE7B57E00B1C9EC /* DebugNoCF */,

				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,

				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);

Changes to macosx/tkMacOSXBitmap.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * 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]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"

/*
 * This structure holds information about native bitmaps.
 */

typedef struct {
    const char *name;		/* Name of icon. */
    OSType iconType;		/* OSType of icon. */
} BuiltInIcon;

/*
 * This array mapps a string name to the supported builtin icons
 * on the Macintosh.
 */

static BuiltInIcon builtInIcons[] = {
    {"document",	kGenericDocumentIcon},
    {"stationery",	kGenericStationeryIcon},
    {"edition",		kGenericEditionFileIcon},





|
|
|







>










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * tkMacOSXBitmap.c --
 *
 *	This file handles the implementation of native bitmaps.
 *
 * Copyright © 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"

/*
 * This structure holds information about native bitmaps.
 */

typedef struct {
    const char *name;		/* Name of icon. */
    OSType iconType;		/* OSType of icon. */
} BuiltInIcon;

/*
 * This array maps a string name to the supported builtin icons
 * on the Macintosh.
 */

static BuiltInIcon builtInIcons[] = {
    {"document",	kGenericDocumentIcon},
    {"stationery",	kGenericStationeryIcon},
    {"edition",		kGenericEditionFileIcon},
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    {"note",		kAlertNoteIcon},
    {"caution",		kAlertCautionIcon},
    {NULL,			0}
};

#define builtInIconSize 32

#define OSTYPE_TO_UTI(x) (NSString *)UTTypeCreatePreferredIdentifierForTag( \
     kUTTagClassOSType, UTCreateStringForOSType(x), nil)

static Tcl_HashTable iconBitmapTable = {};
typedef struct {
    int kind, width, height;
    char *value;
} IconBitmap;

static const char *const iconBitmapOptionStrings[] = {
    "-file", "-fileType", "-osType", "-systemType", "-namedImage",
    "-imageFile", NULL
};
enum iconBitmapOptions {
    ICON_FILE, ICON_FILETYPE, ICON_OSTYPE, ICON_SYSTEMTYPE, ICON_NAMEDIMAGE,
    ICON_IMAGEFILE,
};


/*
 *----------------------------------------------------------------------
 *
 * TkpDefineNativeBitmaps --







<
<
<







|
|


|
|







46
47
48
49
50
51
52



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    {"note",		kAlertNoteIcon},
    {"caution",		kAlertCautionIcon},
    {NULL,			0}
};

#define builtInIconSize 32




static Tcl_HashTable iconBitmapTable = {};
typedef struct {
    int kind, width, height;
    char *value;
} IconBitmap;

static const char *const iconBitmapOptionStrings[] = {
    "-file", "-fileType", "-imageFile", "-namedImage", "-osType",
    "-systemType", NULL
};
enum iconBitmapOptions {
    ICON_FILE, ICON_FILETYPE, ICON_IMAGEFILE, ICON_NAMEDIMAGE, ICON_OSTYPE,
    ICON_SYSTEMTYPE
};


/*
 *----------------------------------------------------------------------
 *
 * TkpDefineNativeBitmaps --
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    Display *display,
    NSImage* image,
    CGSize size)
{
    TkMacOSXDrawingContext dc;
    Pixmap pixmap;

    pixmap = Tk_GetPixmap(display, None, size.width, size.height, 0);
    if (TkMacOSXSetupDrawingContext(pixmap, NULL, &dc)) {
	if (dc.context) {
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1,
				    .tx = 0, .ty = size.height};
	    CGContextConcatCTM(dc.context, t);
	    [NSGraphicsContext saveGraphicsState];
	    [NSGraphicsContext setCurrentContext:GET_NSCONTEXT(dc.context, NO)];







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    Display *display,
    NSImage* image,
    CGSize size)
{
    TkMacOSXDrawingContext dc;
    Pixmap pixmap;

    pixmap = Tk_GetPixmap(display, None, (int)size.width, (int)size.height, 0);
    if (TkMacOSXSetupDrawingContext(pixmap, NULL, &dc)) {
	if (dc.context) {
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1,
				    .tx = 0, .ty = size.height};
	    CGContextConcatCTM(dc.context, t);
	    [NSGraphicsContext saveGraphicsState];
	    [NSGraphicsContext setCurrentContext:GET_NSCONTEXT(dc.context, NO)];
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 */

Pixmap
TkpCreateNativeBitmap(
    Display *display,
    const void *source)		/* Info about the icon to build. */
{
    NSString *iconUTI = OSTYPE_TO_UTI(PTR2UINT(source));
    NSImage *iconImage = [[NSWorkspace sharedWorkspace]
			     iconForFileType: iconUTI];
    CGSize size = CGSizeMake(builtInIconSize, builtInIconSize);
    Pixmap pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
    return pixmap;
}


/*
 *----------------------------------------------------------------------
 *







|
|
<

|







168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
 */

Pixmap
TkpCreateNativeBitmap(
    Display *display,
    const void *source)		/* Info about the icon to build. */
{
    NSString *filetype = TkMacOSXOSTypeToUTI(PTR2UINT(source));
    NSImage *iconImage = TkMacOSXIconForFileType(filetype);

    CGSize size = CGSizeMake(builtInIconSize, builtInIconSize);
    Pixmap pixmap = PixmapFromImage(display, iconImage, size);
    return pixmap;
}


/*
 *----------------------------------------------------------------------
 *
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

static int
OSTypeFromString(const char *s, OSType *t) {
    int result = TCL_ERROR;
    Tcl_DString ds;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

    Tcl_UtfToExternalDString(encoding, s, -1, &ds);
    if (Tcl_DStringLength(&ds) <= 4) {
	char string[4] = {};
	memcpy(string, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	*t = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
	     (OSType) string[2] <<  8 | (OSType) string[3];
	result = TCL_OK;
    }







|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

static int
OSTypeFromString(const char *s, OSType *t) {
    int result = TCL_ERROR;
    Tcl_DString ds;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

    (void)Tcl_UtfToExternalDString(encoding, s, TCL_INDEX_NONE, &ds);
    if (Tcl_DStringLength(&ds) <= 4) {
	char string[4] = {};
	memcpy(string, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	*t = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
	     (OSType) string[2] <<  8 | (OSType) string[3];
	result = TCL_OK;
    }
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
    int *height)
{
    Tcl_HashEntry *hPtr;
    Pixmap pixmap = None;
    NSString *string;
    NSImage *image = nil;
    NSSize size = { .width = builtInIconSize, .height = builtInIconSize };

    if (iconBitmapTable.buckets &&
	    (hPtr = Tcl_FindHashEntry(&iconBitmapTable, name))) {
	OSType type;
	IconBitmap *iconBitmap = Tcl_GetHashValue(hPtr);
	name = NULL;
	size = NSMakeSize(iconBitmap->width, iconBitmap->height);
	switch (iconBitmap->kind) {
	case ICON_FILE:
	    string = [[NSString stringWithUTF8String:iconBitmap->value]
		    stringByExpandingTildeInPath];
	    image = [[NSWorkspace sharedWorkspace] iconForFile:string];
	    break;
	case ICON_FILETYPE:
	    string = [NSString stringWithUTF8String:iconBitmap->value];
	    image = [[NSWorkspace sharedWorkspace] iconForFileType:string];
	    break;
	case ICON_OSTYPE:
	    if (OSTypeFromString(iconBitmap->value, &type) == TCL_OK) {
		string = NSFileTypeForHFSTypeCode(type);
		image = [[NSWorkspace sharedWorkspace] iconForFileType:string];
	    }
	    break;
	case ICON_SYSTEMTYPE:
	    name = iconBitmap->value;
	    break;
	case ICON_NAMEDIMAGE:
	    string = [NSString stringWithUTF8String:iconBitmap->value];







<



|










|



|
|







246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    int *height)
{
    Tcl_HashEntry *hPtr;
    Pixmap pixmap = None;
    NSString *string;
    NSImage *image = nil;
    NSSize size = { .width = builtInIconSize, .height = builtInIconSize };

    if (iconBitmapTable.buckets &&
	    (hPtr = Tcl_FindHashEntry(&iconBitmapTable, name))) {
	OSType type;
	IconBitmap *iconBitmap = (IconBitmap *)Tcl_GetHashValue(hPtr);
	name = NULL;
	size = NSMakeSize(iconBitmap->width, iconBitmap->height);
	switch (iconBitmap->kind) {
	case ICON_FILE:
	    string = [[NSString stringWithUTF8String:iconBitmap->value]
		    stringByExpandingTildeInPath];
	    image = [[NSWorkspace sharedWorkspace] iconForFile:string];
	    break;
	case ICON_FILETYPE:
	    string = [NSString stringWithUTF8String:iconBitmap->value];
	    image = TkMacOSXIconForFileType(string);
	    break;
	case ICON_OSTYPE:
	    if (OSTypeFromString(iconBitmap->value, &type) == TCL_OK) {
		string = [NSString stringWithUTF8String:iconBitmap->value];
		image = TkMacOSXIconForFileType(string);
	    }
	    break;
	case ICON_SYSTEMTYPE:
	    name = iconBitmap->value;
	    break;
	case ICON_NAMEDIMAGE:
	    string = [NSString stringWithUTF8String:iconBitmap->value];
304
305
306
307
308
309
310
311
312
313
314





315
316
317
318
319
320
321
322


323
324
325
326
327
328
329
	    }
	}
	if (image) {
	    size = [image size];
	}
    }
    if (image) {
	*width = size.width;
	*height = size.height;
	pixmap = PixmapFromImage(display, image, NSSizeToCGSize(size));
    } else if (name) {





	OSType iconType;
	if (OSTypeFromString(name, &iconType) == TCL_OK) {
	    NSString *iconUTI = OSTYPE_TO_UTI(iconType);
	    NSImage *iconImage = [[NSWorkspace sharedWorkspace]
				     iconForFileType: iconUTI];
	    pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
	}
    }


    return pixmap;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIconBitmapObjCmd --







<
<


>
>
>
>
>


|
|
<



>
>







300
301
302
303
304
305
306


307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
	    }
	}
	if (image) {
	    size = [image size];
	}
    }
    if (image) {


	pixmap = PixmapFromImage(display, image, NSSizeToCGSize(size));
    } else if (name) {
	/*
	 * As a last resort, try to interpret the name as an OSType.
	 * It would probably be better to just return None at this
	 * point.
	 */
	OSType iconType;
	if (OSTypeFromString(name, &iconType) == TCL_OK) {
	    NSString *iconUTI = TkMacOSXOSTypeToUTI(iconType);
	    NSImage *iconImage = TkMacOSXIconForFileType(iconUTI);

	    pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
	}
    }
    *width = (int)size.width;
    *height = (int)size.height;
    return pixmap;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIconBitmapObjCmd --
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
TkMacOSXIconBitmapObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_HashEntry *hPtr;
    int i = 1, len, isNew, result = TCL_ERROR;

    const char *name, *value;
    IconBitmap ib, *iconBitmap;

    if (objc != 6) {
	Tcl_WrongNumArgs(interp, 1, objv, "name width height "
		"-file|-fileType|-osType|-systemType|-namedImage|-imageFile "
		"value");
	goto end;
    }
    name = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty bitmap name", -1));
	Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "BAD", NULL);
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.width) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.height) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[i++], iconBitmapOptionStrings,
	    sizeof(char *), "kind", TCL_EXACT, &ib.kind) != TCL_OK) {
	goto end;
    }
    value = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty bitmap value", -1));
	Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "EMPTY", NULL);
	goto end;
    }
#if 0
    if ((kind == ICON_TYPE || kind == ICON_SYSTEM)) {
	Tcl_DString ds;
 	Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

	Tcl_UtfToExternalDString(encoding, value, -1, &ds);
	len = Tcl_DStringLength(&ds);
	Tcl_DStringFree(&ds);
	Tcl_FreeEncoding(encoding);
	if (len > 4) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid bitmap value", -1));
	    Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "INVALID", NULL);
	    goto end;
	}
    }
#endif
    ib.value = (char *)ckalloc(len + 1);
    strcpy(ib.value, value);
    if (!iconBitmapTable.buckets) {
	Tcl_InitHashTable(&iconBitmapTable, TCL_STRING_KEYS);
    }
    hPtr = Tcl_CreateHashEntry(&iconBitmapTable, name, &isNew);
    if (!isNew) {
	iconBitmap = Tcl_GetHashValue(hPtr);
	ckfree(iconBitmap->value);
    } else {
	iconBitmap = (IconBitmap *)ckalloc(sizeof(IconBitmap));
	Tcl_SetHashValue(hPtr, iconBitmap);
    }
    *iconBitmap = ib;
    result = TCL_OK;







|
>











|















|








|





|












|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
TkMacOSXIconBitmapObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_HashEntry *hPtr;
    int isNew, result = TCL_ERROR;
    Tcl_Size i = 1, len;
    const char *name, *value;
    IconBitmap ib, *iconBitmap;

    if (objc != 6) {
	Tcl_WrongNumArgs(interp, 1, objv, "name width height "
		"-file|-fileType|-osType|-systemType|-namedImage|-imageFile "
		"value");
	goto end;
    }
    name = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty bitmap name", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "BAD", NULL);
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.width) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIntFromObj(interp, objv[i++], &ib.height) != TCL_OK) {
	goto end;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[i++], iconBitmapOptionStrings,
	    sizeof(char *), "kind", TCL_EXACT, &ib.kind) != TCL_OK) {
	goto end;
    }
    value = Tcl_GetStringFromObj(objv[i++], &len);
    if (!len) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty bitmap value", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "EMPTY", NULL);
	goto end;
    }
#if 0
    if ((kind == ICON_TYPE || kind == ICON_SYSTEM)) {
	Tcl_DString ds;
 	Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

	(void)Tcl_UtfToExternalDString(encoding, value, TCL_INDEX_NONE, &ds);
	len = Tcl_DStringLength(&ds);
	Tcl_DStringFree(&ds);
	Tcl_FreeEncoding(encoding);
	if (len > 4) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid bitmap value", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "MACBITMAP", "INVALID", NULL);
	    goto end;
	}
    }
#endif
    ib.value = (char *)ckalloc(len + 1);
    strcpy(ib.value, value);
    if (!iconBitmapTable.buckets) {
	Tcl_InitHashTable(&iconBitmapTable, TCL_STRING_KEYS);
    }
    hPtr = Tcl_CreateHashEntry(&iconBitmapTable, name, &isNew);
    if (!isNew) {
	iconBitmap = (IconBitmap *)Tcl_GetHashValue(hPtr);
	ckfree(iconBitmap->value);
    } else {
	iconBitmap = (IconBitmap *)ckalloc(sizeof(IconBitmap));
	Tcl_SetHashValue(hPtr, iconBitmap);
    }
    *iconBitmap = ib;
    result = TCL_OK;

Changes to macosx/tkMacOSXButton.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include "tkMacOSXPrivate.h"






|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tkMacOSXButton.c --
 *
 *	This file implements the Macintosh specific portion of the button
 *	widgets.
 *
 * 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"
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

static void	ButtonBackgroundDrawCB(const HIRect *btnbounds,
		    MacButton *ptr, SInt16 depth, Boolean isColorDev);
static void	ButtonContentDrawCB(const HIRect *bounds,
		    ThemeButtonKind kind,
		    const HIThemeButtonDrawInfo *info, MacButton *ptr,
		    SInt16 depth, Boolean isColorDev);
static void	ButtonEventProc(ClientData clientData,
		    XEvent *eventPtr);
static void	TkMacOSXComputeButtonParams(TkButton *butPtr,
		    ThemeButtonKind *btnkind,
		    HIThemeButtonDrawInfo *drawinfo);
static int	TkMacOSXComputeButtonDrawParams(TkButton *butPtr,
		    DrawParams * dpPtr);
static void	TkMacOSXDrawButton(MacButton *butPtr, GC gc,
		    Pixmap pixmap);
static void	DrawButtonImageAndText(TkButton *butPtr);
static void	PulseDefaultButtonProc(ClientData clientData);

/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */







|









|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

static void	ButtonBackgroundDrawCB(const HIRect *btnbounds,
		    MacButton *ptr, SInt16 depth, Boolean isColorDev);
static void	ButtonContentDrawCB(const HIRect *bounds,
		    ThemeButtonKind kind,
		    const HIThemeButtonDrawInfo *info, MacButton *ptr,
		    SInt16 depth, Boolean isColorDev);
static void	ButtonEventProc(void *clientData,
		    XEvent *eventPtr);
static void	TkMacOSXComputeButtonParams(TkButton *butPtr,
		    ThemeButtonKind *btnkind,
		    HIThemeButtonDrawInfo *drawinfo);
static int	TkMacOSXComputeButtonDrawParams(TkButton *butPtr,
		    DrawParams * dpPtr);
static void	TkMacOSXDrawButton(MacButton *butPtr, GC gc,
		    Pixmap pixmap);
static void	DrawButtonImageAndText(TkButton *butPtr);
static void	PulseDefaultButtonProc(void *clientData);

/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
 *	REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    MacButton *macButtonPtr = clientData;
    TkButton *butPtr = clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams* dpPtr = &macButtonPtr->drawParams;
    int needhighlight = 0;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {







|

|
|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
 *	REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    void *clientData)	/* Information about widget. */
{
    MacButton *macButtonPtr = (MacButton *)clientData;
    TkButton *butPtr = (TkButton *)clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams* dpPtr = &macButtonPtr->drawParams;
    int needhighlight = 0;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		text, -1, butPtr->wrapLength, butPtr->justify, 0,
		&butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth + 2*butPtr->padX;
	txtHeight = butPtr->textHeight + 2*butPtr->padY;
	haveText = 1;
    }








|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
	Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		text, TCL_INDEX_NONE, butPtr->wrapLength, butPtr->justify, 0,
		&butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth + 2*butPtr->padX;
	txtHeight = butPtr->textHeight + 2*butPtr->padY;
	haveText = 1;
    }

405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
	 * Pushbutton whose overall size is our content size expanded by the
	 * standard padding.
	 */

	tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY);
        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
        if (height < contBounds.size.height) {
	    height = contBounds.size.height;
        }
        if (width < contBounds.size.width) {
	    width = contBounds.size.width;
        }
	height += 2*HI_PADY;
	width += 2*HI_PADX;
    }
    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}







|


|







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
	 * Pushbutton whose overall size is our content size expanded by the
	 * standard padding.
	 */

	tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY);
        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
        if (height < contBounds.size.height) {
	    height = (int)contBounds.size.height;
        }
        if (width < contBounds.size.width) {
	    width = (int)contBounds.size.width;
        }
	height += 2*HI_PADY;
	width += 2*HI_PADX;
    }
    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
761
762
763
764
765
766
767

768
769
770
771

772
773
774
775
776
777
778
	/*
	 * To avoid buttons with white text on a white background, we set the
	 * state to inactive in Dark Mode unless the button is pressed or is a
	 * -default active button.  This isn't perfect but it is mostly usable.
	 * Using a ttk::button would be a much better choice, however.
	 */


	if (TkMacOSXInDarkMode(butPtr->tkwin) &&
	    mbPtr->drawinfo.state != kThemeStatePressed &&
	    !(mbPtr->drawinfo.adornment & kThemeAdornmentDefault)) {
	    hiinfo.state = kThemeStateInactive;

	}
	HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
		kHIThemeOrientationNormal, &contHIRec);

	TkMacOSXRestoreDrawingContext(&dc);
        ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
		(MacButton *) mbPtr, 32, true);







>
|
|
|
|
>







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
	/*
	 * To avoid buttons with white text on a white background, we set the
	 * state to inactive in Dark Mode unless the button is pressed or is a
	 * -default active button.  This isn't perfect but it is mostly usable.
	 * Using a ttk::button would be a much better choice, however.
	 */

	if ([NSApp macOSVersion] < 101500) {
	    if (TkMacOSXInDarkMode(butPtr->tkwin) &&
		mbPtr->drawinfo.state != kThemeStatePressed &&
		!(mbPtr->drawinfo.adornment & kThemeAdornmentDefault)) {
		hiinfo.state = kThemeStateInactive;
	    }
	}
	HIThemeDrawButton(&cntrRect, &hiinfo, dc.context,
		kHIThemeOrientationNormal, &contHIRec);

	TkMacOSXRestoreDrawingContext(&dc);
        ButtonContentDrawCB(&contHIRec, mbPtr->btnkind, &mbPtr->drawinfo,
		(MacButton *) mbPtr, 32, true);
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *buttonPtr = clientData;
    MacButton *mbPtr = clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {







|


|
|







896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ButtonEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *buttonPtr = (TkButton *)clientData;
    MacButton *mbPtr = (MacButton *)clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
        *btnkind = kThemeBevelButton;
    } else if (butPtr->borderWidth == 4) {
        *btnkind = kThemeRoundedBevelButton;
    } else {
        *btnkind = kThemePushButton;
    }

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
        switch (butPtr->type) {
	case TYPE_BUTTON:
	    *btnkind = kThemePushButton;
	    break;
	case TYPE_RADIO_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallRadioButton;







|







955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
        *btnkind = kThemeBevelButton;
    } else if (butPtr->borderWidth == 4) {
        *btnkind = kThemeRoundedBevelButton;
    } else {
        *btnkind = kThemePushButton;
    }

    if ((butPtr->image == NULL) && (butPtr->bitmap == None)) {
        switch (butPtr->type) {
	case TYPE_BUTTON:
	    *btnkind = kThemePushButton;
	    break;
	case TYPE_RADIO_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallRadioButton;
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
 * Side effects:
 *     Sets a timer to run itself again.
 *
 *--------------------------------------------------------------
 */

static void
PulseDefaultButtonProc(ClientData clientData)
{
    MacButton *mbPtr = clientData;

    TkpDisplayButton(clientData);
    /*
     * Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled
     * in case the button is destroyed and has its data freed before the idle
     * event is handled (DestroyButton only cancels calls when REDRAW_PENDING
     * is set, which is not the case after calling TkpDisplayButton directly).







|

|







1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
 * Side effects:
 *     Sets a timer to run itself again.
 *
 *--------------------------------------------------------------
 */

static void
PulseDefaultButtonProc(void *clientData)
{
    MacButton *mbPtr = (MacButton *)clientData;

    TkpDisplayButton(clientData);
    /*
     * Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled
     * in case the button is destroyed and has its data freed before the idle
     * event is handled (DestroyButton only cancels calls when REDRAW_PENDING
     * is set, which is not the case after calling TkpDisplayButton directly).

Changes to macosx/tkMacOSXClipboard.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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]>
 *
 * 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"





|
|
|







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 © 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"
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
		targetPtr = targetPtr->nextPtr) {
	    if (targetPtr->type == XA_STRING ||
		    targetPtr->type == dispPtr->utf8Atom) {
		for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr;
			cbPtr; cbPtr = cbPtr->nextPtr) {
		    NSString *s = [[TKNSString alloc]
				      initWithTclUtfBytes:cbPtr->buffer
						   length:cbPtr->length];
		    [string appendString:s];
		    [s release];
		}
		break;
	    }
	}
    }







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
		targetPtr = targetPtr->nextPtr) {
	    if (targetPtr->type == XA_STRING ||
		    targetPtr->type == dispPtr->utf8Atom) {
		for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr;
			cbPtr; cbPtr = cbPtr->nextPtr) {
		    NSString *s = [[TKNSString alloc]
				      initWithTclUtfBytes:cbPtr->buffer
						   length:(NSUInteger)cbPtr->length];
		    [string appendString:s];
		    [s release];
		}
		break;
	    }
	}
    }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    int result = TCL_ERROR;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int haveExternalClip =
	    ([[NSPasteboard generalPasteboard] changeCount] != changeCount);

    if (dispPtr && (haveExternalClip || dispPtr->clipboardActive)
	        && selection == dispPtr->clipboardAtom
	        && (target == XA_STRING || target == dispPtr->utf8Atom)) {
	NSString *string = nil;
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
		NSStringPboardType]];

	if (type) {
	    string = [pb stringForType:type];
	}
	if (string) {
	    if (target == dispPtr->utf8Atom) {
		result = proc(clientData, interp, string.UTF8String);
	    } else if (target == XA_STRING) {
		const char *latin1 = [string
		    cStringUsingEncoding:NSISOLatin1StringEncoding];
		result = proc(clientData, interp, latin1);
	    }
	}
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	     "%s selection doesn't exist or form \"%s\" not defined",
	     Tk_GetAtomName(tkwin, selection),
	     Tk_GetAtomName(tkwin, target)));
	Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);







|


















<
|
<
<
<
<
<







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140





141
142
143
144
145
146
147
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    void *clientData)	/* Arbitrary value to pass to proc. */
{
    int result = TCL_ERROR;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int haveExternalClip =
	    ([[NSPasteboard generalPasteboard] changeCount] != changeCount);

    if (dispPtr && (haveExternalClip || dispPtr->clipboardActive)
	        && selection == dispPtr->clipboardAtom
	        && (target == XA_STRING || target == dispPtr->utf8Atom)) {
	NSString *string = nil;
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
		NSStringPboardType]];

	if (type) {
	    string = [pb stringForType:type];
	}
	if (string) {

	    result = proc(clientData, interp, string.UTF8String);





	}
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	     "%s selection doesn't exist or form \"%s\" not defined",
	     Tk_GetAtomName(tkwin, selection),
	     Tk_GetAtomName(tkwin, target)));
	Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL);
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
XSetSelectionOwner(
    Display *display,		/* X Display. */
    Atom selection,		/* What selection to own. */
    Window owner,		/* Window to be the owner. */
    TCL_UNUSED(Time))			/* The current time? */
{
    TkDisplay *dispPtr = TkGetDisplayList();
    (void)time;

    if (dispPtr && selection == dispPtr->clipboardAtom) {
	clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL;
	if (!dispPtr->clipboardActive) {
	    NSPasteboard *pb = [NSPasteboard generalPasteboard];

	    changeCount = [pb declareTypes:[NSArray array] owner:NSApp];







<







170
171
172
173
174
175
176

177
178
179
180
181
182
183
XSetSelectionOwner(
    Display *display,		/* X Display. */
    Atom selection,		/* What selection to own. */
    Window owner,		/* Window to be the owner. */
    TCL_UNUSED(Time))			/* The current time? */
{
    TkDisplay *dispPtr = TkGetDisplayList();


    if (dispPtr && selection == dispPtr->clipboardAtom) {
	clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL;
	if (!dispPtr->clipboardActive) {
	    NSPasteboard *pb = [NSPasteboard generalPasteboard];

	    changeCount = [pb declareTypes:[NSArray array] owner:NSApp];

Changes to macosx/tkMacOSXColor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26

27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
/*
 * 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 (c) 2020 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkColor.h"
#include "tkMacOSXColor.h"

static Tcl_HashTable systemColors;
static int numSystemColors;
static int rgbColorIndex;
static int controlAccentIndex;

static int selectedTabTextIndex;

static Bool useFakeAccentColor = NO;
static SystemColorDatum **systemColorIndex;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
static NSAppearance *lightAqua = nil;
static NSAppearance *darkAqua = nil;
#endif

static NSColorSpace* sRGB = NULL;
static const CGFloat WINDOWBACKGROUND[4] =
    {236.0 / 255, 236.0 / 255, 236.0 / 255, 1.0};

void initColorTable()
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    Tcl_InitHashTable(&systemColors, TCL_STRING_KEYS);
    SystemColorDatum *entry, *oldEntry;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    int newPtr, index = 0;

    NSColorList *systemColorList = [NSColorList colorListNamed:@"System"];
    NSString *key;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    if (@available(macOS 10.14, *)) {
	darkAqua = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
        lightAqua = [NSAppearance appearanceNamed:NSAppearanceNameAqua];







|
|
|
|
|










|
|
|
>
|
>






>











|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*
 * TkMacOSXColor.c --
 *
 *	This file maintains a database of color values for the Tk
 *	toolkit, in order to avoid round-trips to the server to
 *	map color names to pixel values.
 *
 * Copyright © 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"

static Tcl_HashTable systemColors;
static size_t numSystemColors;
static size_t rgbColorIndex;
static size_t controlAccentIndex;
static size_t controlAlternatingRowIndex;
static size_t selectedTabTextIndex;
static size_t pressedButtonTextIndex;
static Bool useFakeAccentColor = NO;
static SystemColorDatum **systemColorIndex;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
static NSAppearance *lightAqua = nil;
static NSAppearance *darkAqua = nil;
#endif

static NSColorSpace* sRGB = NULL;
static const CGFloat WINDOWBACKGROUND[4] =
    {236.0 / 255, 236.0 / 255, 236.0 / 255, 1.0};

void initColorTable()
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    Tcl_InitHashTable(&systemColors, TCL_STRING_KEYS);
    SystemColorDatum *entry, *oldEntry;
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    int newPtr;
    size_t index = 0;
    NSColorList *systemColorList = [NSColorList colorListNamed:@"System"];
    NSString *key;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    if (@available(macOS 10.14, *)) {
	darkAqua = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
        lightAqua = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
	    NSString *colorName = [[NSString alloc]
				   initWithCString:entry->macName
					  encoding:NSUTF8StringEncoding];
	    SEL colorSelector = NSSelectorFromString(colorName);
	    if (![NSColor respondsToSelector:colorSelector]) {
		if ([colorName isEqualToString:@"controlAccentColor"]) {
		    useFakeAccentColor = YES;
		} else if (![colorName isEqualToString:@"selectedTabTextColor"]) {


		    /* Uncomment to print all unsupported colors:              */
		    /* printf("Unsupported color %s\n", colorName.UTF8String); */
		    continue;
		}
	    }
	    entry->selector = [colorName retain];
	}







|
>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	    NSString *colorName = [[NSString alloc]
				   initWithCString:entry->macName
					  encoding:NSUTF8StringEncoding];
	    SEL colorSelector = NSSelectorFromString(colorName);
	    if (![NSColor respondsToSelector:colorSelector]) {
		if ([colorName isEqualToString:@"controlAccentColor"]) {
		    useFakeAccentColor = YES;
		} else if (   ![colorName isEqualToString:@"selectedTabTextColor"]
			   && ![colorName isEqualToString:@"controlAlternatingRowColor"]
			   && ![colorName isEqualToString:@"pressedButtonTextColor"]) {
		    /* Uncomment to print all unsupported colors:              */
		    /* printf("Unsupported color %s\n", colorName.UTF8String); */
		    continue;
		}
	    }
	    entry->selector = [colorName retain];
	}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    }

    /*
     * Add all of the colors in the System ColorList.
     */

    for (key in [systemColorList allKeys]) {
	int length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
	char *name;
	entry = (SystemColorDatum *)ckalloc(sizeof(SystemColorDatum));
	bzero(entry, sizeof(SystemColorDatum));
	name = (char *)ckalloc(length + 1);
	strcpy(name, key.UTF8String);
	name[0] = toupper(name[0]);
        if (!strcmp(name, "WindowBackgroundColor")) {

	    /*
	     * Avoid black windows on old systems.
	     */

	    continue;







|





|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    }

    /*
     * Add all of the colors in the System ColorList.
     */

    for (key in [systemColorList allKeys]) {
	NSUInteger length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
	char *name;
	entry = (SystemColorDatum *)ckalloc(sizeof(SystemColorDatum));
	bzero(entry, sizeof(SystemColorDatum));
	name = (char *)ckalloc(length + 1);
	strcpy(name, key.UTF8String);
	name[0] = (char)toupper(UCHAR(name[0]));
        if (!strcmp(name, "WindowBackgroundColor")) {

	    /*
	     * Avoid black windows on old systems.
	     */

	    continue;
140
141
142
143
144
145
146



147
148
149



150
151
152
153
154
155
156

    hPtr = Tcl_FindHashEntry(&systemColors, "Pixel");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    rgbColorIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "ControlAccentColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    controlAccentIndex = entry->index;



    hPtr = Tcl_FindHashEntry(&systemColors, "SelectedTabTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    selectedTabTextIndex = entry->index;



    [pool drain];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRGBPixel --







>
>
>



>
>
>







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

    hPtr = Tcl_FindHashEntry(&systemColors, "Pixel");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    rgbColorIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "ControlAccentColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    controlAccentIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "ControlAlternatingRowColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    controlAlternatingRowIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "SelectedTabTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    selectedTabTextIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "PressedButtonTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    pressedButtonTextIndex = entry->index;
    [pool drain];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRGBPixel --
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
MODULE_SCOPE
unsigned long
TkMacOSXRGBPixel(
    unsigned long red,
    unsigned long green,
    unsigned long blue)
{
    MacPixel p;
    p.pixel.colortype = rgbColor;
    p.pixel.value = ((red & 0xff) << 16)  |
	            ((green & 0xff) << 8) |
	            (blue & 0xff);
    return p.ulong;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXClearPixel --







|

|

|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
MODULE_SCOPE
unsigned long
TkMacOSXRGBPixel(
    unsigned long red,
    unsigned long green,
    unsigned long blue)
{
    MacPixel p = {0};
    p.pixel.colortype = rgbColor;
    p.pixel.value = (unsigned int)(((red & 0xff) << 16)  |
	            ((green & 0xff) << 8) |
	            (blue & 0xff));
    return p.ulong;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXClearPixel --
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long TkMacOSXClearPixel(
    void)
{
    MacPixel p;
    p.pixel.value = 0;
    p.pixel.colortype = clearColor;
    return p.ulong;
}


/*







|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long TkMacOSXClearPixel(
    void)
{
    MacPixel p = {0};
    p.pixel.value = 0;
    p.pixel.colortype = clearColor;
    return p.ulong;
}


/*
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
 *----------------------------------------------------------------------
 */

SystemColorDatum*
GetEntryFromPixel(
    unsigned long pixel)
{
    MacPixel p;
    int index = rgbColorIndex;

    p.ulong = pixel;
    if (p.pixel.colortype != rgbColor) {
	index = p.pixel.value;
    }
    if (index < numSystemColors) {
	return systemColorIndex[index];







|
|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
 *----------------------------------------------------------------------
 */

SystemColorDatum*
GetEntryFromPixel(
    unsigned long pixel)
{
    MacPixel p = {0};
    size_t index = rgbColorIndex;

    p.ulong = pixel;
    if (p.pixel.colortype != rgbColor) {
	index = p.pixel.value;
    }
    if (index < numSystemColors) {
	return systemColorIndex[index];
274
275
276
277
278
279
280

281
282
283
284

285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314




315
316
317
318
319
320
321









322
323
324
325








326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
static void
GetRGBA(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGFloat *rgba)
{
    NSColor *bgColor, *color = nil;


    if (!sRGB) {
	sRGB = [NSColorSpace sRGBColorSpace];
    }

    switch (entry->type) {
    case rgbColor:
	rgba[0] = ((pixel >> 16) & 0xff) / 255.0;
	rgba[1] = ((pixel >>  8) & 0xff) / 255.0;
	rgba[2] = ((pixel      ) & 0xff) / 255.0;
	break;
    case ttkBackground:

	/*
	 * Prior to OSX 10.14, getComponents returns black when applied to
	 * windowBackGroundColor.
	 */

	if ([NSApp macOSVersion] < 101400) {
	    for (int i = 0; i < 3; i++) {
		rgba[i] = WINDOWBACKGROUND[i];
	    }
	} else {
	    bgColor = [[NSColor windowBackgroundColor] colorUsingColorSpace:sRGB];
	    [bgColor getComponents: rgba];
	}
	if (rgba[0] + rgba[1] + rgba[2] < 1.5) {
	    for (int i=0; i<3; i++) {
		rgba[i] += entry->value*8.0 / 255.0;
	    }
	} else {
	    for (int i=0; i<3; i++) {
		rgba[i] -= entry->value*8.0 / 255.0;
	    }
	}




	break;
    case semantic:
	if (entry->index == controlAccentIndex && useFakeAccentColor) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
	    color = [[NSColor colorForControlTint: [NSColor currentControlTint]]
			      colorUsingColorSpace:sRGB];
#endif









	} else if (entry->index == selectedTabTextIndex) {
	    int OSVersion = [NSApp macOSVersion];
	    if (OSVersion > 100600 && OSVersion < 110000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];








	    }
	} else {
	    color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
	}
	[color getComponents: rgba];
	break;
    case clearColor:
	rgba[3] = 0;
    default:
	break;
    }
}

/*
 *----------------------------------------------------------------------







>




>










|



















>
>
>
>







>
>
>
>
>
>
>
>
>

<


>
>
>
>
>
>
>
>






<
<







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
static void
GetRGBA(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGFloat *rgba)
{
    NSColor *bgColor, *color = nil;
    int OSVersion = [NSApp macOSVersion];

    if (!sRGB) {
	sRGB = [NSColorSpace sRGBColorSpace];
    }

    switch (entry->type) {
    case rgbColor:
	rgba[0] = ((pixel >> 16) & 0xff) / 255.0;
	rgba[1] = ((pixel >>  8) & 0xff) / 255.0;
	rgba[2] = ((pixel      ) & 0xff) / 255.0;
	break;
    case ttkBackground:

	/*
	 * Prior to OSX 10.14, getComponents returns black when applied to
	 * windowBackgroundColor.
	 */

	if ([NSApp macOSVersion] < 101400) {
	    for (int i = 0; i < 3; i++) {
		rgba[i] = WINDOWBACKGROUND[i];
	    }
	} else {
	    bgColor = [[NSColor windowBackgroundColor] colorUsingColorSpace:sRGB];
	    [bgColor getComponents: rgba];
	}
	if (rgba[0] + rgba[1] + rgba[2] < 1.5) {
	    for (int i=0; i<3; i++) {
		rgba[i] += entry->value*8.0 / 255.0;
	    }
	} else {
	    for (int i=0; i<3; i++) {
		rgba[i] -= entry->value*8.0 / 255.0;
	    }
	}
	break;
    case clearColor:
	rgba[0] = rgba[1] = rgba[2] = 1.0;
	rgba[3] = 0;
	break;
    case semantic:
	if (entry->index == controlAccentIndex && useFakeAccentColor) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
	    color = [[NSColor colorForControlTint: [NSColor currentControlTint]]
			      colorUsingColorSpace:sRGB];
#endif
	} else if (entry->index == controlAlternatingRowIndex) {
	    /*
	     * Color which is now called alternatingContentBackgroundColor on 10.14.
	     * Taken from NSColor.controlAlternatingRowBackgroundColors (which was
	     * replaced by NSColor.alternatingContentBackgroundColors on 10.14).
	     */
	    color = [[NSColor colorWithCatalogName:@"System"
					 colorName:@"controlAlternatingRowColor"]
			colorUsingColorSpace:sRGB];
	} else if (entry->index == selectedTabTextIndex) {

	    if (OSVersion > 100600 && OSVersion < 110000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
	    } else {
		color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	    }
	} else if (entry->index == pressedButtonTextIndex) {
	    if (OSVersion < 120000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
	    } else {
		color = [[NSColor blackColor] colorUsingColorSpace:sRGB];
	    }
	} else {
	    color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
	}
	[color getComponents: rgba];
	break;


    default:
	break;
    }
}

/*
 *----------------------------------------------------------------------
359
360
361
362
363
364
365





366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
static Bool
SetCGColorComponents(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGColorRef *c)
{
    CGFloat rgba[4] = {0, 0, 0, 1};






    /*
     * This function is called before our autorelease pool is set up,
     * so it needs its own pool.
     */

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (entry->type == HIBrush) {
     	OSStatus err = ChkErr(HIThemeBrushCreateCGColor, entry->value, c);
     	return err == noErr;
    }
    GetRGBA(entry, pixel, rgba);
    *c = CGColorCreate(sRGB.CGColorSpace, rgba);
    [pool drain];
    return true;
}

/*







>
>
>
>
>








<
<
<
<







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410




411
412
413
414
415
416
417
static Bool
SetCGColorComponents(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGColorRef *c)
{
    CGFloat rgba[4] = {0, 0, 0, 1};

    if (entry->type == HIBrush) {
     	OSStatus err = ChkErr(HIThemeBrushCreateCGColor, entry->value, c);
     	return err == noErr;
    }

    /*
     * This function is called before our autorelease pool is set up,
     * so it needs its own pool.
     */

    NSAutoreleasePool *pool = [NSAutoreleasePool new];





    GetRGBA(entry, pixel, rgba);
    *c = CGColorCreate(sRGB.CGColorSpace, rgba);
    [pool drain];
    return true;
}

/*
408
409
410
411
412
413
414
415
416
417
418


419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
	NSView *view = nil;
	if (winPtr && winPtr->privatePtr) {
	    view = TkMacOSXGetNSViewForDrawable((Drawable)winPtr->privatePtr);
	}
	if (view) {
	    name = [[view effectiveAppearance] name];
	} else {
	    name = [[NSAppearance currentAppearance] name];
	}
	return (name == NSAppearanceNameDarkAqua);
    }


#endif
    return false;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetMacColor --
 *
 *	Sets the components of a CGColorRef from an XColor pixel value.  The
 *      pixel value is used to look up the color in the system color table, and
 *      then SetCGColorComponents is called with the table entry and the pixel
 *      value.
 *
 * Results:
 *      Returns false if the color is not found, true otherwise.
 *
 * Side effects:
 *	The variable macColor is set to a new CGColorRef, the caller is
 *	responsible for releasing it!
 *
 *----------------------------------------------------------------------
 */

int
TkSetMacColor(
    unsigned long pixel,		/* Pixel value to convert. */
    void *macColor)			/* CGColorRef to modify. */
{
    CGColorRef *color = (CGColorRef*)macColor;
    SystemColorDatum *entry = GetEntryFromPixel(pixel);

    if (entry) {
	return SetCGColorComponents(entry, pixel, color);
    } else {
	return false;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpInitGCCache, TkpFreeGCCache, CopyCachedColor, SetCachedColor --
 *
 *	Maintain a per-GC cache of previously converted CGColorRefs
 *
 * Results:
 *	None resp. retained CGColorRef for CopyCachedColor()
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpInitGCCache(
    GC gc)
{
    bzero(TkpGetGCCache(gc), sizeof(TkpGCCache));
}

void
TkpFreeGCCache(
    GC gc)
{
    TkpGCCache *gcCache = TkpGetGCCache(gc);

    if (gcCache->cachedForegroundColor) {
	CFRelease(gcCache->cachedForegroundColor);
    }
    if (gcCache->cachedBackgroundColor) {
	CFRelease(gcCache->cachedBackgroundColor);
    }
}

static CGColorRef
CopyCachedColor(
    GC gc,
    unsigned long pixel)
{
    TkpGCCache *gcCache = TkpGetGCCache(gc);
    CGColorRef cgColor = NULL;

    if (gcCache) {
	if (gcCache->cachedForeground == pixel) {
	    cgColor = gcCache->cachedForegroundColor;
	} else if (gcCache->cachedBackground == pixel) {
	    cgColor = gcCache->cachedBackgroundColor;
	}
	if (cgColor) {
	    CFRetain(cgColor);
	}
    }
    return cgColor;
}

static void
SetCachedColor(
    GC gc,
    unsigned long pixel,
    CGColorRef cgColor)
{
    TkpGCCache *gcCache = TkpGetGCCache(gc);

    if (gcCache && cgColor) {
	if (gc->foreground == pixel) {
	    if (gcCache->cachedForegroundColor) {
		CFRelease(gcCache->cachedForegroundColor);
	    }
	    gcCache->cachedForegroundColor = (CGColorRef) CFRetain(cgColor);
	    gcCache->cachedForeground = pixel;
	} else if (gc->background == pixel) {
	    if (gcCache->cachedBackgroundColor) {
		CFRelease(gcCache->cachedBackgroundColor);
	    }
	    gcCache->cachedBackgroundColor = (CGColorRef) CFRetain(cgColor);
	    gcCache->cachedBackground = pixel;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGColor --
 *
 *	Creates a CGColorRef from a X style pixel value.
 *
 * Results:
 *	Returns NULL if not a real pixel, CGColorRef otherwise.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

CGColorRef
TkMacOSXCreateCGColor(
    GC gc,
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = CopyCachedColor(gc, pixel);

    if (!cgColor && TkSetMacColor(pixel, &cgColor)) {
	SetCachedColor(gc, pixel, cgColor);
    }
    return cgColor;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSColor --
 *
 *	Creates an autoreleased NSColor from a X style pixel value.
 *      The return value is nil if the pixel value is invalid.
 *
 * Results:
 *	A possibly nil pointer to an NSColor.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

NSColor*
TkMacOSXGetNSColor(
    GC gc,
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = TkMacOSXCreateCGColor(gc, pixel);
    NSColor *nsColor = nil;


    if (cgColor) {
	NSColorSpace *colorSpace = [[NSColorSpace alloc]
		initWithCGColorSpace:CGColorGetColorSpace(cgColor)];

	nsColor = [NSColor colorWithColorSpace:colorSpace
		components:CGColorGetComponents(cgColor)
		count:CGColorGetNumberOfComponents(cgColor)];
	[colorSpace release];
	CFRelease(cgColor);
    }
    return nsColor;
}

/*
 *----------------------------------------------------------------------
 *







|



>
>












|





|
<






|
|










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|


|


>

<
<
<
|
|
|
<
|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
















































































































491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518



519
520
521

522
523
524
525
526
527
528
529
	NSView *view = nil;
	if (winPtr && winPtr->privatePtr) {
	    view = TkMacOSXGetNSViewForDrawable((Drawable)winPtr->privatePtr);
	}
	if (view) {
	    name = [[view effectiveAppearance] name];
	} else {
	    name = [[NSApp effectiveAppearance] name];
	}
	return (name == NSAppearanceNameDarkAqua);
    }
#else
    (void) tkwin;
#endif
    return false;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetMacColor --
 *
 *	Sets the components of a CGColorRef from an XColor pixel value.  The
 *      pixel value is used to look up the color in the system color table, and
 *      then SetCGColorComponents is called with the table entry and the pixel
 *      value.  The parameter macColor should be a pointer to a CGColorRef.
 *
 * Results:
 *      Returns false if the color is not found, true otherwise.
 *
 * Side effects:
 *	The CGColorRef referenced by the variable macColor may be modified.

 *
 *----------------------------------------------------------------------
 */

int
TkSetMacColor(
    unsigned long pixel,	/* Pixel value to convert. */
    void *macColor)		/* CGColorRef to modify. */
{
    CGColorRef *color = (CGColorRef*)macColor;
    SystemColorDatum *entry = GetEntryFromPixel(pixel);

    if (entry) {
	return SetCGColorComponents(entry, pixel, color);
    } else {
	return false;
    }
}

















































































































/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSColor --
 *
 *	Creates an autoreleased NSColor from a X style pixel value.
 *      The return value is nil if the pixel value is invalid.
 *
 * Results:
 *	A possibly nil pointer to an NSColor.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

NSColor*
TkMacOSXGetNSColor(
    TCL_UNUSED(GC),
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = NULL;
    NSColor *nsColor = nil;

    TkSetMacColor(pixel, &cgColor);
    if (cgColor) {



	nsColor = [NSColor colorWithColorSpace:sRGB
			components:CGColorGetComponents(cgColor)
			count:(NSInteger)CGColorGetNumberOfComponents(cgColor)];

	CGColorRelease(cgColor);
    }
    return nsColor;
}

/*
 *----------------------------------------------------------------------
 *
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetColorInContext(
    GC gc,
    unsigned long pixel,
    CGContextRef context)
{
    OSStatus err = noErr;
    CGColorRef cgColor = nil;
    SystemColorDatum *entry = GetEntryFromPixel(pixel);

    if (entry) {
	switch (entry->type) {
	case HIBrush:
	    err = ChkErr(HIThemeSetFill, entry->value, NULL, context,
		    kHIThemeOrientationNormal);
	    if (err == noErr) {
		err = ChkErr(HIThemeSetStroke, entry->value, NULL, context,
			kHIThemeOrientationNormal);
	    }
	    break;
	default:
	    if (SetCGColorComponents(entry, pixel, &cgColor)){
		SetCachedColor(gc, pixel, cgColor);
	    }
	    break;
	}
    }
    if (cgColor) {
	CGContextSetFillColorWithColor(context, cgColor);
	CGContextSetStrokeColorWithColor(context, cgColor);
	CGColorRelease(cgColor);







|




|













|
<
<







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566


567
568
569
570
571
572
573
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetColorInContext(
    TCL_UNUSED(GC),
    unsigned long pixel,
    CGContextRef context)
{
    OSStatus err = noErr;
    CGColorRef cgColor = NULL;
    SystemColorDatum *entry = GetEntryFromPixel(pixel);

    if (entry) {
	switch (entry->type) {
	case HIBrush:
	    err = ChkErr(HIThemeSetFill, entry->value, NULL, context,
		    kHIThemeOrientationNormal);
	    if (err == noErr) {
		err = ChkErr(HIThemeSetStroke, entry->value, NULL, context,
			kHIThemeOrientationNormal);
	    }
	    break;
	default:
	    SetCGColorComponents(entry, pixel, &cgColor);


	    break;
	}
    }
    if (cgColor) {
	CGContextSetFillColorWithColor(context, cgColor);
	CGContextSetStrokeColorWithColor(context, cgColor);
	CGColorRelease(cgColor);
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733


734
735
736
737
738
739










740
741
742


743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
{
    Display *display = NULL;
    TkColor *tkColPtr;
    XColor color;
    Colormap colormap = tkwin ? Tk_Colormap(tkwin) : noColormap;
    NSView *view = nil;
    static Bool initialized = NO;
    static NSColorSpace* sRGB = NULL;

    if (!initialized) {
	initialized = YES;
	sRGB = [NSColorSpace sRGBColorSpace];
	initColorTable();
    }
    if (tkwin) {
	display = Tk_Display(tkwin);
	Drawable d = Tk_WindowId(tkwin);
	view = TkMacOSXGetNSViewForDrawable(d);
    }

    /*
     * Check to see if this is a system color. If not, just call XParseColor.
     */

    if (strncasecmp(name, "system", 6) == 0) {
	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&systemColors, name + 6);
	MacPixel p;

	if (hPtr != NULL) {
	    SystemColorDatum *entry = (SystemColorDatum *)Tcl_GetHashValue(hPtr);
	    CGColorRef c;

	    p.pixel.colortype = entry->type;
	    p.pixel.value = entry->index;
	    color.pixel = p.ulong;
	    if (entry->type == semantic) {
		CGFloat rgba[4];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
		if (@available(macOS 10.14, *)) {
		    NSAppearance *savedAppearance = [NSAppearance currentAppearance];
		    NSAppearance *windowAppearance = savedAppearance;
		    if (view) {
			windowAppearance = [view effectiveAppearance];


		    }
		    if ([windowAppearance name] == NSAppearanceNameDarkAqua) {
			colormap = darkColormap;
		    } else {
			colormap = lightColormap;
		    }










		    [NSAppearance setCurrentAppearance:windowAppearance];
		    GetRGBA(entry, p.ulong, rgba);
		    [NSAppearance setCurrentAppearance:savedAppearance];


		} else {
		    GetRGBA(entry, p.ulong, rgba);
		}
#else
		GetRGBA(entry, p.ulong, rgba);
#endif
		color.red   = rgba[0] * 65535.0;
		color.green = rgba[1] * 65535.0;
		color.blue  = rgba[2] * 65535.0;
		goto validXColor;
	    } else if (SetCGColorComponents(entry, 0, &c)) {
		const size_t n = CGColorGetNumberOfComponents(c);
		const CGFloat *rgba = CGColorGetComponents(c);

		switch (n) {
		case 4:
		    color.red   = rgba[0] * 65535.0;
		    color.green = rgba[1] * 65535.0;
		    color.blue  = rgba[2] * 65535.0;
		    break;
		case 2:
		    color.red = color.green = color.blue = rgba[0] * 65535.0;
		    break;
		default:
		    Tcl_Panic("CGColor with %d components", (int) n);
		}
		CGColorRelease(c);
		goto validXColor;
	    }







<



<














|



|


|





<
|


>
>






>
>
>
>
>
>
>
>
>
>
|
|
|
>
>






|
|
|







|
|
|


|







608
609
610
611
612
613
614

615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
{
    Display *display = NULL;
    TkColor *tkColPtr;
    XColor color;
    Colormap colormap = tkwin ? Tk_Colormap(tkwin) : noColormap;
    NSView *view = nil;
    static Bool initialized = NO;


    if (!initialized) {
	initialized = YES;

	initColorTable();
    }
    if (tkwin) {
	display = Tk_Display(tkwin);
	Drawable d = Tk_WindowId(tkwin);
	view = TkMacOSXGetNSViewForDrawable(d);
    }

    /*
     * Check to see if this is a system color. If not, just call XParseColor.
     */

    if (strncasecmp(name, "system", 6) == 0) {
	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&systemColors, name + 6);
	MacPixel p = {0};

	if (hPtr != NULL) {
	    SystemColorDatum *entry = (SystemColorDatum *)Tcl_GetHashValue(hPtr);
	    CGColorRef c = NULL;

	    p.pixel.colortype = entry->type;
	    p.pixel.value = (unsigned int)entry->index;
	    color.pixel = p.ulong;
	    if (entry->type == semantic) {
		CGFloat rgba[4];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
		if (@available(macOS 10.14, *)) {

		    NSAppearance *windowAppearance;
		    if (view) {
			windowAppearance = [view effectiveAppearance];
		    } else {
			windowAppearance = [NSApp effectiveAppearance];
		    }
		    if ([windowAppearance name] == NSAppearanceNameDarkAqua) {
			colormap = darkColormap;
		    } else {
			colormap = lightColormap;
		    }
		    if (@available(macOS 11.0, *)) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
			CGFloat *rgbaPtr = rgba;
			[windowAppearance performAsCurrentDrawingAppearance:^{
				GetRGBA(entry, p.ulong, rgbaPtr);
			    }];
#endif
		    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
			NSAppearance *savedAppearance = [NSAppearance currentAppearance];
			[NSAppearance setCurrentAppearance:windowAppearance];
			GetRGBA(entry, p.ulong, rgba);
			[NSAppearance setCurrentAppearance:savedAppearance];
#endif
		    }
		} else {
		    GetRGBA(entry, p.ulong, rgba);
		}
#else
		GetRGBA(entry, p.ulong, rgba);
#endif
		color.red   = (unsigned short)(rgba[0] * 65535.0);
		color.green = (unsigned short)(rgba[1] * 65535.0);
		color.blue  = (unsigned short)(rgba[2] * 65535.0);
		goto validXColor;
	    } else if (SetCGColorComponents(entry, 0, &c)) {
		const size_t n = CGColorGetNumberOfComponents(c);
		const CGFloat *rgba = CGColorGetComponents(c);

		switch (n) {
		case 4:
		    color.red   = (unsigned short)(rgba[0] * 65535.0);
		    color.green = (unsigned short)(rgba[1] * 65535.0);
		    color.blue  = (unsigned short)(rgba[2] * 65535.0);
		    break;
		case 2:
		    color.red = color.green = color.blue = (unsigned short)(rgba[0] * 65535.0);
		    break;
		default:
		    Tcl_Panic("CGColor with %d components", (int) n);
		}
		CGColorRelease(c);
		goto validXColor;
	    }
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852

Status
XAllocColor(
    Display *display,		/* Display. */
    TCL_UNUSED(Colormap),		/* Not used. */
    XColor *colorPtr)		/* XColor struct to modify. */
{
    display->request++;
    colorPtr->pixel = TkpGetPixel(colorPtr);
    return 1;
}

Colormap
XCreateColormap(
    TCL_UNUSED(Display *),		/* Display. */







|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

Status
XAllocColor(
    Display *display,		/* Display. */
    TCL_UNUSED(Colormap),		/* Not used. */
    XColor *colorPtr)		/* XColor struct to modify. */
{
    LastKnownRequestProcessed(display)++;
    colorPtr->pixel = TkpGetPixel(colorPtr);
    return 1;
}

Colormap
XCreateColormap(
    TCL_UNUSED(Display *),		/* Display. */

Changes to macosx/tkMacOSXColor.h.

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 * 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 },







|


|












|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 * 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;
    ThemeBrush value;
    const char *macName;
    /* Fields below are filled in after or during construction of the hash table. */
    size_t 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 },
171
172
173
174
175
176
177
178
179


180
181
182
183
184
185
186



187
188
189
190
191
192
193
194
195
196
197
198
{"WindowBackgroundColor3",	    ttkBackground, 3, NULL, 0, NULL },
{"WindowBackgroundColor4",	    ttkBackground, 4, NULL, 0, NULL },
{"WindowBackgroundColor5",	    ttkBackground, 5, NULL, 0, NULL },
{"WindowBackgroundColor6",	    ttkBackground, 6, NULL, 0, NULL },
{"WindowBackgroundColor7",	    ttkBackground, 7, NULL, 0, NULL },
/* Apple's SecondaryLabelColor is the same as their LabelColor so we roll our own. */
{"SecondaryLabelColor",		    ttkBackground, 14, NULL, 0, NULL },
/* Color to use for notebook tab labels -- depends on OS version. */
{"SelectedTabTextColor",	    semantic, 0, "textColor", 0, NULL },


/* Semantic colors that we simulate on older systems which don't supoort them. */
{"SelectedMenuItemTextColor",       semantic, 0, "selectedMenuItemTextColor", 0, NULL },
{"ControlAccentColor",		    semantic, 0, "controlAccentColor", 0, NULL },
{"LabelColor",                      semantic, 0, "blackColor", 0, NULL },
{"LinkColor",			    semantic, 0, "blueColor", 0, NULL },
{"PlaceholderTextColor",	    semantic, 0, "grayColor", 0, NULL },
{"SeparatorColor",		    semantic, 0, "grayColor", 0, NULL },



{NULL,				    0, 0, NULL, 0, NULL }
};

#endif
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

>
>







>
>
>
|











171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
{"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 label text -- depends on OS version. */
{"SelectedTabTextColor",	    semantic, 0, "textColor", 0, NULL },
/* Color to use for selected button labels -- depends on OS version. */
{"PressedButtonTextColor",	    semantic, 0, "textColor", 0, NULL },
/* Semantic colors that we simulate on older systems which don't supoort them. */
{"SelectedMenuItemTextColor",       semantic, 0, "selectedMenuItemTextColor", 0, NULL },
{"ControlAccentColor",		    semantic, 0, "controlAccentColor", 0, NULL },
{"LabelColor",                      semantic, 0, "blackColor", 0, NULL },
{"LinkColor",			    semantic, 0, "blueColor", 0, NULL },
{"PlaceholderTextColor",	    semantic, 0, "grayColor", 0, NULL },
{"SeparatorColor",		    semantic, 0, "grayColor", 0, NULL },
{"UnemphasizedSelectedTextBackgroundColor", semantic, 0, "grayColor", 0, NULL },
/* This color is available since 10.3, so the fallback is unused */
{"ControlAlternatingRowColor",	    semantic, 0, "grayColor" , 0, NULL },
{NULL,				    rgbColor, 0, NULL, 0, NULL }
};

#endif
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXConfig.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * tkMacOSXConfig.c --
 *
 *	This module implements the Macintosh system defaults for
 *	the configuration package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"


/*
 *----------------------------------------------------------------------
 *
 * TkpGetSystemDefault --
 *
 *	Given a dbName and className for a configuration option,
 *	return a string representation of the option.
 *
 * Results:
 *	Returns a Tk_Uid that is the string identifier that identifies
 *	this option. Returns NULL if there are no system defaults
 *	that match this pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,			/* A window to use. */
    const char *dbName,			/* The option database name. */
    const char *className)		/* The name of the option class. */
{
    (void)tkwin;
    (void)dbName;
    (void)className;

    return NULL;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4






|
|











|





|










|
|
|
|

<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41




42
43
44
45
46
47
48
/*
 * tkMacOSXConfig.c --
 *
 *	This module implements the Macintosh system defaults for
 *	the configuration package.
 *
 * 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"


/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSystemDefault --
 *
 *	Given a dbName and className for a configuration option,
 *	return a string representation of the option.
 *
 * Results:
 *	Returns a Tcl_Obj* with the string identifier that identifies
 *	this option. Returns NULL if there are no system defaults
 *	that match this pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_GetSystemDefault(
    TCL_UNUSED(Tk_Window),			/* A window to use. */
    TCL_UNUSED(const char *),			/* The option database name. */
    TCL_UNUSED(const char *))		/* The name of the option class. */
{




    return NULL;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4

Changes to macosx/tkMacOSXConstants.h.

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
 *
 * 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








|







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 © 2017 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMACCONSTANTS
#define _TKMACCONSTANTS
75
76
77
78
79
80
81



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98





99
100
101
102
103
104
105
#define NSAlternateKeyMask NSEventModifierFlagOption
#define NSControlKeyMask NSEventModifierFlagControl
#define NSNumericPadKeyMask NSEventModifierFlagNumericPad
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSCursorUpdate NSEventTypeCursorUpdate
#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSCompositeCopy NSCompositingOperationCopy



#define NSWarningAlertStyle NSAlertStyleWarning
#define NSInformationalAlertStyle NSAlertStyleInformational
#define NSCriticalAlertStyle NSAlertStyleCritical
#define NSCenterTextAlignment NSTextAlignmentCenter
#define NSAnyEventMask NSEventMaskAny
#define NSApplicationDefinedMask NSEventMaskApplicationDefined
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen





#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
#endif







>
>
>




<












>
>
>
>
>







75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#define NSAlternateKeyMask NSEventModifierFlagOption
#define NSControlKeyMask NSEventModifierFlagControl
#define NSNumericPadKeyMask NSEventModifierFlagNumericPad
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSCursorUpdate NSEventTypeCursorUpdate
#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSCompositeCopy NSCompositingOperationCopy
#define NSCompositeSourceOver NSCompositingOperationSourceOver
#define NSCompositeSourceAtop NSCompositingOperationSourceAtop
#define NSCompositeDestinationIn NSCompositingOperationDestinationIn
#define NSWarningAlertStyle NSAlertStyleWarning
#define NSInformationalAlertStyle NSAlertStyleInformational
#define NSCriticalAlertStyle NSAlertStyleCritical
#define NSCenterTextAlignment NSTextAlignmentCenter

#define NSApplicationDefinedMask NSEventMaskApplicationDefined
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen
#define NSAlphaFirstBitmapFormat NSBitmapFormatAlphaFirst
#define NSAnyEventMask NSEventMaskAny
#define NSLeftMouseDownMask NSEventMaskLeftMouseDown
#define NSMouseMovedMask NSEventMaskMouseMoved
#define NSLeftMouseDraggedMask NSEventMaskLeftMouseDragged
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
#endif

Changes to macosx/tkMacOSXCursor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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]>
 *
 * 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"





|
|
|







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 © 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"
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	/*
	 * System cursor of type @filename
	 */

	macCursorPtr->type = IMAGEPATH;
	path = [NSString stringWithUTF8String:&name[1]];
    } else {
	Tcl_Obj *strPtr = Tcl_NewStringObj(name, -1);
	int idx;

	result = Tcl_GetIndexFromObjStruct(NULL, strPtr, cursorNames,
		    sizeof(struct CursorName), NULL, TCL_EXACT, &idx);
	Tcl_DecrRefCount(strPtr);
	if (result == TCL_OK) {
	    macCursorPtr->type = cursorNames[idx].kind;







|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
	/*
	 * System cursor of type @filename
	 */

	macCursorPtr->type = IMAGEPATH;
	path = [NSString stringWithUTF8String:&name[1]];
    } else {
	Tcl_Obj *strPtr = Tcl_NewStringObj(name, TCL_INDEX_NONE);
	int idx;

	result = Tcl_GetIndexFromObjStruct(NULL, strPtr, cursorNames,
		    sizeof(struct CursorName), NULL, TCL_EXACT, &idx);
	Tcl_DecrRefCount(strPtr);
	if (result == TCL_OK) {
	    macCursorPtr->type = cursorNames[idx].kind;
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;
		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);








|







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 = 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);

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry
				 * for details on legal syntax. */
{
    TkMacOSXCursor *macCursorPtr = NULL;
    const char **argv = NULL;
    int argc;

    /*
     * All cursor names are valid lists of one element (for
     * TkX11-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {







|







368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry
				 * for details on legal syntax. */
{
    TkMacOSXCursor *macCursorPtr = NULL;
    const char **argv = NULL;
    Tcl_Size argc;

    /*
     * All cursor names are valid lists of one element (for
     * TkX11-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {
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;
    if (macCursorPtr == gCurrentCursor) {
	gCurrentCursor = NULL;
    }
}

/*
 *----------------------------------------------------------------------







|







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 = nil;
    if (macCursorPtr == gCurrentCursor) {
	gCurrentCursor = NULL;
    }
}

/*
 *----------------------------------------------------------------------
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

void
TkpSetCursor(
    TkpCursor cursor)
{
    int cursorChanged = 1;

    if (cursor == None) {
	/*
	 * This is a little tricky. We can't really tell whether
	 * gCurrentCursor is NULL because it was NULL last time around or
	 * because we just freed the current cursor. So if the input cursor is
	 * NULL, we always need to reset it, we can't trust the cursorChanged
	 * logic.
	 */







|







532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

void
TkpSetCursor(
    TkpCursor cursor)
{
    int cursorChanged = 1;

    if (cursor == NULL) {
	/*
	 * This is a little tricky. We can't really tell whether
	 * gCurrentCursor is NULL because it was NULL last time around or
	 * because we just freed the current cursor. So if the input cursor is
	 * NULL, we always need to reset it, we can't trust the cursorChanged
	 * logic.
	 */

Changes to macosx/tkMacOSXCursors.h.

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]>
 *
 * 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] = {







|
|
|







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 © 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
/*
 * 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]>
 *
 * 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"






|
|







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 © 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
/*
 * 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]>
 *
 * 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






|
|







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 © 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#define NORMAL_BG		"systemWindowBackgroundColor"
#define TEXT_BG                 "systemTextBackgroundColor"
#define NORMAL_FG		"systemTextColor"
#define ACTIVE_BG		"systemWindowBackgroundColor"
#define ACTIVE_FG		"systemTextColor"
#define SELECT_BG		"systemSelectedTextBackgroundColor"
#define SELECT_FG		"systemSelectedTextColor"
#define INACTIVE_SELECT_BG	"systemSelectedTextBackgroundColor"

#define TROUGH			"#c3c3c3"
#define INDICATOR		"#b03060"
#define DISABLED		"systemDisabledControlTextColor"


/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
 */

#define DEF_BUTTON_ANCHOR		"center"
#define DEF_BUTTON_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_BUTTON_ACTIVE_BG_MONO	BLACK
#define DEF_BUTTON_ACTIVE_FG_COLOR	WHITE
#define DEF_CHKRAD_ACTIVE_FG_COLOR	ACTIVE_FG
#define DEF_BUTTON_ACTIVE_FG_MONO	WHITE
#define DEF_BUTTON_BG_COLOR		NORMAL_BG
#define DEF_BUTTON_BG_MONO		WHITE
#define DEF_BUTTON_BITMAP		""
#define DEF_BUTTON_BORDER_WIDTH		"2"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_BUTTON_FG			NORMAL_FG

#define DEF_CHKRAD_FG			DEF_BUTTON_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		"systemButtonFrame"
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define DEF_BUTTON_HIGHLIGHT_WIDTH	"4"
//#define DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM	"1"
//#else
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
//#endif
#define DEF_BUTTON_IMAGE		NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_OVER_RELIEF		""
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#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
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
#define DEF_CHECKBUTTON_VARIABLE	""

/*
 * Defaults for canvases:
 */

#define DEF_CANVAS_BG_COLOR		NORMAL_BG
#define DEF_CANVAS_BG_MONO		WHITE
#define DEF_CANVAS_BORDER_WIDTH		"0"
#define DEF_CANVAS_CLOSE_ENOUGH		"1"
#define DEF_CANVAS_CONFINE		"1"
#define DEF_CANVAS_CURSOR		""
#define DEF_CANVAS_HEIGHT		"7c"
#define DEF_CANVAS_HIGHLIGHT_BG		NORMAL_BG
#define DEF_CANVAS_HIGHLIGHT		BLACK
#define DEF_CANVAS_HIGHLIGHT_WIDTH	"3"
#define DEF_CANVAS_INSERT_BG		BLACK
#define DEF_CANVAS_INSERT_BD_COLOR	"0"
#define DEF_CANVAS_INSERT_BD_MONO	"0"
#define DEF_CANVAS_INSERT_OFF_TIME	"300"
#define DEF_CANVAS_INSERT_ON_TIME	"600"
#define DEF_CANVAS_INSERT_WIDTH		"2"







|
>



>








|












|
>
|




|














<
<
<
<

<

<
<
<
<

<













<


















|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93




94

95




96

97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#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	"systemUnemphasizedSelectedTextBackgroundColor"
#define INACTIVE_SELECT_FG	"systemSelectedTextColor"
#define TROUGH			"#c3c3c3"
#define INDICATOR		"#b03060"
#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
#define DEF_BUTTON_ACTIVE_BG_MONO	BLACK
#define DEF_BUTTON_ACTIVE_FG_COLOR	"systemPressedButtonTextColor"
#define DEF_CHKRAD_ACTIVE_FG_COLOR	ACTIVE_FG
#define DEF_BUTTON_ACTIVE_FG_MONO	WHITE
#define DEF_BUTTON_BG_COLOR		NORMAL_BG
#define DEF_BUTTON_BG_MONO		WHITE
#define DEF_BUTTON_BITMAP		""
#define DEF_BUTTON_BORDER_WIDTH		"2"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_BUTTON_FG			BLACK
#define DEF_LABEL_FG			NORMAL_FG
#define DEF_CHKRAD_FG			DEF_LABEL_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		NORMAL_FG
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define DEF_BUTTON_HIGHLIGHT_WIDTH	"4"
//#define DEF_BUTTON_HIGHLIGHT_WIDTH_NOCM	"1"
//#else
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
//#endif
#define DEF_BUTTON_IMAGE		NULL
#define DEF_BUTTON_INDICATOR		"1"
#define DEF_BUTTON_JUSTIFY		"center"
#define DEF_BUTTON_OFF_VALUE		"0"
#define DEF_BUTTON_ON_VALUE		"1"
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_OVER_RELIEF		""




#define DEF_BUTTON_PADX			"1"

#define DEF_LABCHKRAD_PADX		"1"




#define DEF_BUTTON_PADY			"1"

#define DEF_LABCHKRAD_PADY		"1"
#define DEF_BUTTON_RELIEF		"flat"
#define DEF_LABCHKRAD_RELIEF		"flat"
#define DEF_BUTTON_REPEAT_DELAY		"0"
#define DEF_BUTTON_REPEAT_INTERVAL	"0"
#define DEF_BUTTON_SELECT_COLOR		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""

#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
#define DEF_CHECKBUTTON_VARIABLE	""

/*
 * Defaults for canvases:
 */

#define DEF_CANVAS_BG_COLOR		NORMAL_BG
#define DEF_CANVAS_BG_MONO		WHITE
#define DEF_CANVAS_BORDER_WIDTH		"0"
#define DEF_CANVAS_CLOSE_ENOUGH		"1"
#define DEF_CANVAS_CONFINE		"1"
#define DEF_CANVAS_CURSOR		""
#define DEF_CANVAS_HEIGHT		"7c"
#define DEF_CANVAS_HIGHLIGHT_BG		NORMAL_BG
#define DEF_CANVAS_HIGHLIGHT		NORMAL_FG
#define DEF_CANVAS_HIGHLIGHT_WIDTH	"3"
#define DEF_CANVAS_INSERT_BG		BLACK
#define DEF_CANVAS_INSERT_BD_COLOR	"0"
#define DEF_CANVAS_INSERT_BD_MONO	"0"
#define DEF_CANVAS_INSERT_OFF_TIME	"300"
#define DEF_CANVAS_INSERT_ON_TIME	"600"
#define DEF_CANVAS_INSERT_WIDTH		"2"
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#define DEF_ENTRY_DISABLED_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_DISABLED_BG_MONO	WHITE
#define DEF_ENTRY_DISABLED_FG		DISABLED
#define DEF_ENTRY_EXPORT_SELECTION	"1"
#define DEF_ENTRY_FONT			"TkTextFont"
#define DEF_ENTRY_FG			NORMAL_FG
#define DEF_ENTRY_HIGHLIGHT_BG		NORMAL_BG
#define DEF_ENTRY_HIGHLIGHT		BLACK
#define DEF_ENTRY_HIGHLIGHT_WIDTH	"3"
#define DEF_ENTRY_INSERT_BG		NORMAL_FG
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"1"







|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#define DEF_ENTRY_DISABLED_BG_COLOR	NORMAL_BG
#define DEF_ENTRY_DISABLED_BG_MONO	WHITE
#define DEF_ENTRY_DISABLED_FG		DISABLED
#define DEF_ENTRY_EXPORT_SELECTION	"1"
#define DEF_ENTRY_FONT			"TkTextFont"
#define DEF_ENTRY_FG			NORMAL_FG
#define DEF_ENTRY_HIGHLIGHT_BG		NORMAL_BG
#define DEF_ENTRY_HIGHLIGHT		NORMAL_FG
#define DEF_ENTRY_HIGHLIGHT_WIDTH	"3"
#define DEF_ENTRY_INSERT_BG		NORMAL_FG
#define DEF_ENTRY_INSERT_BD_COLOR	"0"
#define DEF_ENTRY_INSERT_BD_MONO	"0"
#define DEF_ENTRY_INSERT_OFF_TIME	"300"
#define DEF_ENTRY_INSERT_ON_TIME	"600"
#define DEF_ENTRY_INSERT_WIDTH		"1"
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG
#define DEF_FRAME_HIGHLIGHT		BLACK
#define DEF_FRAME_HIGHLIGHT_WIDTH	"0"
#define DEF_FRAME_PADX			"0"
#define DEF_FRAME_PADY			"0"
#define DEF_FRAME_RELIEF		"flat"
#define DEF_FRAME_TAKE_FOCUS		"0"
#define DEF_FRAME_VISUAL		""
#define DEF_FRAME_WIDTH			"0"







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#define DEF_FRAME_BORDER_WIDTH		"0"
#define DEF_FRAME_CLASS			"Frame"
#define DEF_FRAME_COLORMAP		""
#define DEF_FRAME_CONTAINER		"0"
#define DEF_FRAME_CURSOR		""
#define DEF_FRAME_HEIGHT		"0"
#define DEF_FRAME_HIGHLIGHT_BG		NORMAL_BG
#define DEF_FRAME_HIGHLIGHT		NORMAL_FG
#define DEF_FRAME_HIGHLIGHT_WIDTH	"0"
#define DEF_FRAME_PADX			"0"
#define DEF_FRAME_PADY			"0"
#define DEF_FRAME_RELIEF		"flat"
#define DEF_FRAME_TAKE_FOCUS		"0"
#define DEF_FRAME_VISUAL		""
#define DEF_FRAME_WIDTH			"0"
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#define DEF_LISTBOX_CURSOR		""
#define DEF_LISTBOX_DISABLED_FG		DISABLED
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkTextFont"
#define DEF_LISTBOX_FG			NORMAL_FG
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		BLACK
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"0"
#define DEF_LISTBOX_JUSTIFY		"left"
#define DEF_LISTBOX_RELIEF		"solid"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK







|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#define DEF_LISTBOX_CURSOR		""
#define DEF_LISTBOX_DISABLED_FG		DISABLED
#define DEF_LISTBOX_EXPORT_SELECTION	"1"
#define DEF_LISTBOX_FONT		"TkTextFont"
#define DEF_LISTBOX_FG			NORMAL_FG
#define DEF_LISTBOX_HEIGHT		"10"
#define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
#define DEF_LISTBOX_HIGHLIGHT		NORMAL_FG
#define DEF_LISTBOX_HIGHLIGHT_WIDTH	"0"
#define DEF_LISTBOX_JUSTIFY		"left"
#define DEF_LISTBOX_RELIEF		"solid"
#define DEF_LISTBOX_SCROLL_COMMAND	""
#define DEF_LISTBOX_LIST_VARIABLE	""
#define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
#define DEF_LISTBOX_SELECT_MONO		BLACK
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	NORMAL_BG /*ignored*/
#define DEF_MENU_ACTIVE_BG_MONO		NORMAL_BG /*ignored*/
#define DEF_MENU_ACTIVE_BORDER_WIDTH	"0"
#define DEF_MENU_ACTIVE_FG_COLOR	NORMAL_FG
#define DEF_MENU_ACTIVE_FG_MONO		NORMAL_FG
#define DEF_MENU_ACTIVE_RELIEF		"flat"
#define DEF_MENU_BG_COLOR		NORMAL_BG /*ignored*/
#define DEF_MENU_BG_MONO		NORMAL_BG /*ignored*/
#define DEF_MENU_BORDER_WIDTH		"0"
#define DEF_MENU_CURSOR			"arrow"
#define DEF_MENU_DISABLED_FG_COLOR	DISABLED
#define DEF_MENU_DISABLED_FG_MONO	DISABLED
#define DEF_MENU_FONT			"menu" /* special: see tkMacOSXMenu.c */
#define DEF_MENU_FG			NORMAL_FG
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#define DEF_MENU_SELECT_COLOR		"systemSelectedMenuItemTextColor"
#define DEF_MENU_SELECT_MONO		"systemSelectedMenuItemTextColor"
#define DEF_MENU_TAKE_FOCUS		"0"
#define DEF_MENU_TEAROFF		"0"
#define DEF_MENU_TEAROFF_CMD		NULL
#define DEF_MENU_TITLE			""
#define DEF_MENU_TYPE			"normal"

/*







<





|
|

|
|

|
|


|
|

|


|
|







293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL


/*
 * Defaults for menus overall:
 */

#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	IGNORED
#define DEF_MENU_ACTIVE_FG_MONO		IGNORED
#define DEF_MENU_ACTIVE_RELIEF		"flat"
#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	IGNORED
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"menu" /* special: see tkMacOSXMenu.c */
#define DEF_MENU_FG			"#010000"  /* Detects custom fg. */
#define DEF_MENU_POST_COMMAND		""
#define DEF_MENU_RELIEF			"flat"
#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"

/*
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_MENUBUTTON_DISABLED_FG_MONO	""
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		NORMAL_FG
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	NORMAL_BG
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		NULL
#define DEF_MENUBUTTON_INDICATOR	"1"
#define DEF_MENUBUTTON_JUSTIFY		"left"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"0"
#define DEF_MENUBUTTON_PADY		"0"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""
#define DEF_MENUBUTTON_UNDERLINE	"-1"
#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			NORMAL_FG
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		BLACK
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		"-1"
#define DEF_MESSAGE_PADY		"-1"
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
#define DEF_MESSAGE_TEXT_VARIABLE	""
#define DEF_MESSAGE_WIDTH		"0"
/*
 * Defaults for panedwindows







|












<
















|


|
|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
#define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
#define DEF_MENUBUTTON_DISABLED_FG_MONO	""
#define DEF_MENUBUTTON_FONT		"TkDefaultFont"
#define DEF_MENUBUTTON_FG		NORMAL_FG
#define DEF_MENUBUTTON_HEIGHT		"0"
#define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
#define DEF_MENUBUTTON_HIGHLIGHT_BG_MONO  DEF_MENUBUTTON_BG_MONO
#define DEF_MENUBUTTON_HIGHLIGHT	NORMAL_FG
#define DEF_MENUBUTTON_HIGHLIGHT_WIDTH	"0"
#define DEF_MENUBUTTON_IMAGE		NULL
#define DEF_MENUBUTTON_INDICATOR	"1"
#define DEF_MENUBUTTON_JUSTIFY		"left"
#define DEF_MENUBUTTON_MENU		""
#define DEF_MENUBUTTON_PADX		"0"
#define DEF_MENUBUTTON_PADY		"0"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""

#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			NORMAL_FG
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		NORMAL_FG
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		NULL
#define DEF_MESSAGE_PADY		NULL
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
#define DEF_MESSAGE_TEXT_VARIABLE	""
#define DEF_MESSAGE_WIDTH		"0"
/*
 * Defaults for panedwindows
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
 * Defaults for scales:
 */

#define DEF_SCALE_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO	BLACK
#define DEF_SCALE_BG_COLOR		NORMAL_BG
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		NORMAL_FG
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"0"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY	"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
 */

#define DEF_SCROLLBAR_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCROLLBAR_ACTIVE_BG_MONO	BLACK
#define DEF_SCROLLBAR_ACTIVE_RELIEF	"raised"
#define DEF_SCROLLBAR_BG_COLOR		NORMAL_BG
#define DEF_SCROLLBAR_BG_MONO		WHITE
#define DEF_SCROLLBAR_BORDER_WIDTH	"0"
#define DEF_SCROLLBAR_COMMAND		""
#define DEF_SCROLLBAR_CURSOR		""
#define DEF_SCROLLBAR_EL_BORDER_WIDTH	"-1"
#define DEF_SCROLLBAR_HIGHLIGHT_BG	NORMAL_BG
#define DEF_SCROLLBAR_HIGHLIGHT		BLACK
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"flat"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	NULL







|







|


|







|







|
|

















|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
 * Defaults for scales:
 */

#define DEF_SCALE_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO	BLACK
#define DEF_SCALE_BG_COLOR		NORMAL_BG
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0.0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		NORMAL_FG
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0.0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		NORMAL_FG
#define DEF_SCALE_HIGHLIGHT_WIDTH	"0"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY	"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1.0"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0.0"
#define DEF_SCALE_TO			"100.0"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
 */

#define DEF_SCROLLBAR_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCROLLBAR_ACTIVE_BG_MONO	BLACK
#define DEF_SCROLLBAR_ACTIVE_RELIEF	"raised"
#define DEF_SCROLLBAR_BG_COLOR		NORMAL_BG
#define DEF_SCROLLBAR_BG_MONO		WHITE
#define DEF_SCROLLBAR_BORDER_WIDTH	"0"
#define DEF_SCROLLBAR_COMMAND		""
#define DEF_SCROLLBAR_CURSOR		""
#define DEF_SCROLLBAR_EL_BORDER_WIDTH	"-1"
#define DEF_SCROLLBAR_HIGHLIGHT_BG	NORMAL_BG
#define DEF_SCROLLBAR_HIGHLIGHT		NORMAL_FG
#define DEF_SCROLLBAR_HIGHLIGHT_WIDTH	"0"
#define DEF_SCROLLBAR_JUMP		"0"
#define DEF_SCROLLBAR_ORIENT		"vertical"
#define DEF_SCROLLBAR_RELIEF		"flat"
#define DEF_SCROLLBAR_REPEAT_DELAY	"300"
#define DEF_SCROLLBAR_REPEAT_INTERVAL	"100"
#define DEF_SCROLLBAR_TAKE_FOCUS	NULL
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531

532
533
534
535
536
537
538
#define DEF_TEXT_BORDER_WIDTH		"0"
#define DEF_TEXT_CURSOR			"xterm"
#define DEF_TEXT_FG			NORMAL_FG
#define DEF_TEXT_EXPORT_SELECTION	"1"
#define DEF_TEXT_FONT			"TkFixedFont"
#define DEF_TEXT_HEIGHT			"24"
#define DEF_TEXT_HIGHLIGHT_BG		NORMAL_BG
#define DEF_TEXT_HIGHLIGHT		BLACK
#define DEF_TEXT_HIGHLIGHT_WIDTH	"3"
#define DEF_TEXT_INSERT_BG		NORMAL_FG
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"1"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"flat"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	INACTIVE_SELECT_BG

#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"1"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"







|












|
>







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
#define DEF_TEXT_BORDER_WIDTH		"0"
#define DEF_TEXT_CURSOR			"xterm"
#define DEF_TEXT_FG			NORMAL_FG
#define DEF_TEXT_EXPORT_SELECTION	"1"
#define DEF_TEXT_FONT			"TkFixedFont"
#define DEF_TEXT_HEIGHT			"24"
#define DEF_TEXT_HIGHLIGHT_BG		NORMAL_BG
#define DEF_TEXT_HIGHLIGHT		NORMAL_FG
#define DEF_TEXT_HIGHLIGHT_WIDTH	"3"
#define DEF_TEXT_INSERT_BG		NORMAL_FG
#define DEF_TEXT_INSERT_BD_COLOR	"0"
#define DEF_TEXT_INSERT_BD_MONO		"0"
#define DEF_TEXT_INSERT_OFF_TIME	"300"
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"1"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"flat"
#define DEF_TEXT_INACTIVE_SELECT_BG_COLOR INACTIVE_SELECT_BG
#define DEF_TEXT_INACTIVE_SELECT_FG_COLOR INACTIVE_SELECT_FG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"1"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"

Changes to macosx/tkMacOSXDialog.c.

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
























28
29
30
31
32
33
34
/*
 * 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.

 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"
#include "tkMacOSXConstants.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOK     NSOKButton
#define modalCancel NSCancelButton
#else
#define modalOK     NSModalResponseOK
#define modalCancel NSModalResponseCancel
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOther  -1 // indicates that the -command option was used. 
#define modalError  -2

























/*
 * Vars for filtering in "open file" and "save file" dialogs.
 */

typedef struct {
    bool doFileTypes;			/* Show the accessory view which





|
|
|
|
>
















|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
 * tkMacOSXDialog.c --
 *
 *	Contains the Mac implementation of the common dialog boxes.
 *
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright © 2017 Christian Gollwitzer
 * Copyright © 2022 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkFileFilter.h"
#include "tkMacOSXConstants.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOK     NSOKButton
#define modalCancel NSCancelButton
#else
#define modalOK     NSModalResponseOK
#define modalCancel NSModalResponseCancel
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < 1090
#define modalOther  -1 // indicates that the -command option was used.
#define modalError  -2

static void setAllowedFileTypes(
    NSSavePanel *panel,
    NSMutableArray *extensions)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
/* UTType exists in the SDK */
    if (@available(macOS 11.0, *)) {
	NSMutableArray<UTType *> *allowedTypes = [NSMutableArray array];
	for (NSString *ext in extensions) {
	    UTType *uttype = [UTType typeWithFilenameExtension: ext];
	    [allowedTypes addObject:uttype];
	}
	[panel setAllowedContentTypes:allowedTypes];
    } else {
# if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
/* setAllowedFileTypes is not deprecated */
	[panel setAllowedFileTypes:extensions];
#endif
    }
#else
    [panel setAllowedFileTypes:extensions];
#endif
}

/*
 * Vars for filtering in "open file" and "save file" dialogs.
 */

typedef struct {
    bool doFileTypes;			/* Show the accessory view which
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    "-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
    COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};

static const char *const openOptionStrings[] = {
    "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
    "-message", "-multiple", "-parent", "-title", "-typevariable",
    "-command", NULL
};
enum openOptions {
    OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR, OPEN_INITFILE,
    OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE,
    OPEN_TYPEVARIABLE, OPEN_COMMAND,
};
static const char *const saveOptionStrings[] = {
    "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
    "-message", "-parent", "-title", "-typevariable", "-command",
    "-confirmoverwrite", NULL
};
enum saveOptions {
    SAVE_DEFAULT, SAVE_FILETYPES, SAVE_INITDIR, SAVE_INITFILE,
    SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE, SAVE_TYPEVARIABLE, SAVE_COMMAND,
    SAVE_CONFIRMOW
};
static const char *const chooseOptionStrings[] = {
    "-initialdir", "-message", "-mustexist", "-parent", "-title", "-command",
    NULL
};
enum chooseOptions {
    CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, CHOOSE_PARENT,
    CHOOSE_TITLE, CHOOSE_COMMAND,
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int multiple;
} FilePanelCallbackInfo;

static const char *const alertOptionStrings[] = {
    "-default", "-detail", "-icon", "-message", "-parent", "-title",
    "-type", "-command", NULL
};
enum alertOptions {
    ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT,
    ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND,
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int typeIndex;
} AlertCallbackInfo;
static const char *const alertTypeStrings[] = {







|
|
|


|
|
|


|
|
|


|
|
|


|



|
|













|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    "-initialcolor", "-parent", "-title", NULL
};
enum colorOptions {
    COLOR_INITIAL, COLOR_PARENT, COLOR_TITLE
};

static const char *const openOptionStrings[] = {
    "-command", "-defaultextension", "-filetypes", "-initialdir",
    "-initialfile", "-message", "-multiple", "-parent", "-title",
    "-typevariable", NULL
};
enum openOptions {
    OPEN_COMMAND, OPEN_DEFAULT, OPEN_FILETYPES, OPEN_INITDIR,
    OPEN_INITFILE, OPEN_MESSAGE, OPEN_MULTIPLE, OPEN_PARENT, OPEN_TITLE,
    OPEN_TYPEVARIABLE
};
static const char *const saveOptionStrings[] = {
    "-command", "-confirmoverwrite", "-defaultextension", "-filetypes",
    "-initialdir", "-initialfile", "-message", "-parent", "-title",
    "-typevariable", NULL
};
enum saveOptions {
    SAVE_COMMAND, SAVE_CONFIRMOW, SAVE_DEFAULT, SAVE_FILETYPES,
    SAVE_INITDIR, SAVE_INITFILE, SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE,
    SAVE_TYPEVARIABLE
};
static const char *const chooseOptionStrings[] = {
    "-command", "-initialdir", "-message", "-mustexist", "-parent", "-title",
    NULL
};
enum chooseOptions {
    CHOOSE_COMMAND, CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST,
    CHOOSE_PARENT, CHOOSE_TITLE
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int multiple;
} FilePanelCallbackInfo;

static const char *const alertOptionStrings[] = {
    "-default", "-detail", "-icon", "-message", "-parent", "-title",
    "-type", "-command", NULL
};
enum alertOptions {
    ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT,
    ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int typeIndex;
} AlertCallbackInfo;
static const char *const alertTypeStrings[] = {
204
205
206
207
208
209
210
211

212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351

352
353






354
355

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

372
373

374
375



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
	(void)sender;
	(void)url;
    return YES;
}

- (void)panel:(id)sender didChangeToDirectoryURL:(NSURL *)url {
    (void)sender; (void)url;

}

- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError {
    (void)sender; (void)url;

    *outError = nil;
    return YES;
}

- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
		returnCode: (NSModalResponse) returnCode
	       contextInfo: (void *) contextInfo
{
    FilePanelCallbackInfo *callbackInfo = contextInfo;

    if (returnCode == modalOK) {
	Tcl_Obj *resultObj;

	if (callbackInfo->multiple) {
	    resultObj = Tcl_NewListObj(0, NULL);
	    for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
			Tcl_NewStringObj([[url path] UTF8String], -1));
	    }
	} else {
	    resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], -1);
	}
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;

	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree(tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    } else if (returnCode == modalCancel) {
	Tcl_ResetResult(callbackInfo->interp);
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
    }
    if (callbackInfo) {
	ckfree(callbackInfo);
    }
    [NSApp stopModalWithCode:returnCode];
}

- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
	contextInfo: (void *) contextInfo
{
    AlertCallbackInfo *callbackInfo = contextInfo;

    if (returnCode >= NSAlertFirstButtonReturn) {
	Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
		alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
		typeIndex][returnCode - NSAlertFirstButtonReturn]], -1);

	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;

	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree(tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    }
    if ([alert window] == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }
    if (callbackInfo->cmdObj) {
	Tcl_DecrRefCount(callbackInfo->cmdObj);
	ckfree(callbackInfo);
    }
}

- (void)selectFormat:(id)sender  {
    NSPopUpButton *button      = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex   = [button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[openpanel setAllowsOtherFileTypes:YES];

	/*
	 * setAllowsOtherFileTypes might have no effect; it's inherited from
	 * the NSSavePanel, where it has the effect that it does not append an
	 * extension. Setting the allowed file types to nil allows selecting
	 * any file.
	 */

	[openpanel setAllowedFileTypes:nil];
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	[openpanel setAllowedFileTypes:allowedtypes];
	[openpanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

- (void)saveFormat:(id)sender  {
    NSPopUpButton *button     = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex  = [button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[savepanel setAllowsOtherFileTypes:YES];
	[savepanel setAllowedFileTypes:nil];
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	[savepanel setAllowedFileTypes:allowedtypes];
	[savepanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

@end

#pragma mark -

static NSInteger showOpenSavePanel(
    NSSavePanel *panel,
    NSWindow *parent,

    FilePanelCallbackInfo *callbackInfo)

{
    NSInteger modalReturnCode;







    if (parent && ![parent attachedSheet]) {

	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ];
	    }];

	/*
	 * The sheet has been prepared, so now we have to run it as a modal
	 * window.  Using [NSApp runModalForWindow:] on macOS 10.15 or later
	 * generates warnings on stderr.  But using [NSOpenPanel runModal] or
	 * [NSSavePanel runModal] on 10.14 or earler does not cause the
	 * completion handler to run when the panel is closed.
	 */

	if ([NSApp macOSVersion] > 101400) {

	    modalReturnCode = [panel runModal];
	} else {

	    modalReturnCode = [NSApp runModalForWindow:panel];
	}



    } else {

	/* 
	 * For the standalone file dialog, completion handlers do not work
	 * at all on macOS 10.14 and earlier.
	 */

	if ([NSApp macOSVersion] > 101400) {
	    [panel beginWithCompletionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
			          returnCode:returnCode
			         contextInfo:callbackInfo ];
	    }];
	    modalReturnCode = [panel runModal];
	} else {
	    modalReturnCode = [panel runModal];
	    [NSApp tkFilePanelDidEnd:panel
		   	  returnCode:modalReturnCode
		         contextInfo:callbackInfo ];
	    [panel close];
	}
    }
    return callbackInfo->cmdObj ? modalOther : modalReturnCode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *







|
>



|
>






|

|








|


|



>
|
















<
<
<
<
<
<




|

|




|



>
|

















<
<
<
<




|
<










|



|








|



|



|













>
|
>


>
>
>
>
>
>


>
|
|
|
|
|
|
|
<
|
|
|
|
|
<
|
<
>


>
|
<
>
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
|
<
|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284






285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318




319
320
321
322
323

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

390
391
392
393
394

395

396
397
398
399
400

401
402
403
404
405












406
407
408
409
410

411

412
413
414
415
416
417
418
419
- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
	(void)sender;
	(void)url;
    return YES;
}

- (void)panel:(id)sender didChangeToDirectoryURL:(NSURL *)url {
    (void)sender;
    (void)url;
}

- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError {
    (void)sender;
    (void)url;
    *outError = nil;
    return YES;
}

- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
		returnCode: (NSModalResponse) returnCode
	       contextInfo: (const void *) contextInfo
{
    const FilePanelCallbackInfo *callbackInfo = (const FilePanelCallbackInfo *)contextInfo;

    if (returnCode == modalOK) {
	Tcl_Obj *resultObj;

	if (callbackInfo->multiple) {
	    resultObj = Tcl_NewListObj(0, NULL);
	    for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
			Tcl_NewStringObj([[url path] UTF8String], TCL_INDEX_NONE));
	    }
	} else {
	    resultObj = Tcl_NewStringObj([[[panel URL]path] UTF8String], TCL_INDEX_NONE);
	}
	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    Tcl_Size objc;
	    int result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree(tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    } else if (returnCode == modalCancel) {
	Tcl_ResetResult(callbackInfo->interp);
    }






    [NSApp stopModalWithCode:returnCode];
}

- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
	contextInfo: (const void *) contextInfo
{
    AlertCallbackInfo *callbackInfo = (AlertCallbackInfo *)contextInfo;

    if (returnCode >= NSAlertFirstButtonReturn) {
	Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
		alertNativeButtonIndexAndTypeToButtonIndex[callbackInfo->
		typeIndex][returnCode - NSAlertFirstButtonReturn]], TCL_INDEX_NONE);

	if (callbackInfo->cmdObj) {
	    Tcl_Obj **objv, **tmpv;
	    Tcl_Size objc;
	    int result = Tcl_ListObjGetElements(callbackInfo->interp,
		    callbackInfo->cmdObj, &objc, &objv);

	    if (result == TCL_OK && objc) {
		tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
		tmpv[objc] = resultObj;
		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
			TCL_EVAL_GLOBAL);
		ckfree(tmpv);
	    }
	} else {
	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
	}
    }
    if ([alert window] == [NSApp modalWindow]) {
	[NSApp stopModalWithCode:returnCode];
    }




}

- (void)selectFormat:(id)sender  {
    NSPopUpButton *button      = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex   = (NSUInteger)[button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[openpanel setAllowsOtherFileTypes:YES];

	/*
	 * setAllowsOtherFileTypes might have no effect; it's inherited from
	 * the NSSavePanel, where it has the effect that it does not append an
	 * extension. Setting the allowed file types to nil allows selecting
	 * any file.
	 */

	setAllowedFileTypes(openpanel, nil);
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	setAllowedFileTypes(openpanel, allowedtypes);
	[openpanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

- (void)saveFormat:(id)sender  {
    NSPopUpButton *button     = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex  = (NSUInteger)[button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[savepanel setAllowsOtherFileTypes:YES];
	setAllowedFileTypes(savepanel, nil);
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	setAllowedFileTypes(savepanel, allowedtypes);
	[savepanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

@end

#pragma mark -

static NSInteger showOpenSavePanel(
    NSSavePanel *panel,
    NSWindow *parent,
    Tcl_Interp *interp,
    Tcl_Obj *cmdObj,
    int multiple)
{
    NSInteger modalReturnCode;
    int OSVersion = [NSApp macOSVersion];
    const FilePanelCallbackInfo callbackInfo = {interp, cmdObj, multiple};

    /*
     * Use a sheet if -parent is specified (unless there is already a sheet).
     */

    if (parent && ![parent attachedSheet]) {
	if (OSVersion < 101500) {
	    [panel beginSheetModalForWindow:parent
			  completionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
				  returnCode:returnCode
				 contextInfo:&callbackInfo ];
		}];
	    modalReturnCode = [NSApp runModalForWindow:panel];

	} else if (OSVersion < 110000) {
	    [panel beginSheetModalForWindow:parent
			  completionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
				  returnCode:returnCode

				 contextInfo:&callbackInfo ];

		}];
	    modalReturnCode = [panel runModal];
	} else {
	    [parent beginSheet: panel completionHandler:nil];
	    modalReturnCode = [panel runModal];

	    [NSApp tkFilePanelDidEnd:panel
			  returnCode:modalReturnCode
			 contextInfo:&callbackInfo ];
	    [parent endSheet:panel];
	}












    } else {
	modalReturnCode = [panel runModal];
	[NSApp tkFilePanelDidEnd:panel
		      returnCode:modalReturnCode
		     contextInfo:&callbackInfo ];

    }

    return cmdObj ? modalOther : modalReturnCode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseColorObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int result = TCL_ERROR;
    Tk_Window parent, tkwin = clientData;
    const char *title = NULL;
    int i;
    NSColor *color = nil, *initialColor = nil;
    NSColorPanel *colorPanel;
    NSInteger returnCode, numberOfComponents = 0;

    for (i = 1; i < objc; i += 2) {







|





|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseColorObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int result = TCL_ERROR;
    Tk_Window parent, tkwin = (Tk_Window)clientData;
    const char *title = NULL;
    int i;
    NSColor *color = nil, *initialColor = nil;
    NSColorPanel *colorPanel;
    NSInteger returnCode, numberOfComponents = 0;

    for (i = 1; i < objc; i += 2) {
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
    colorPanel = [NSColorPanel sharedColorPanel];
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[NSString alloc] initWithUTF8String:title];

	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }







|







486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
    colorPanel = [NSColorPanel sharedColorPanel];
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[TKNSString alloc] initWithTclUtfBytes:title length:TCL_INDEX_NONE];

	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

    filterInfo.allowedExtensions = [NSMutableArray array];
    filterInfo.allowedExtensionsAllowAll = NO;

    if (filterInfo.doFileTypes) {
	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {
	    NSString *name = [[NSString alloc] initWithUTF8String: filterPtr->name];

	    [filterInfo.fileTypeNames addObject:name];
	    [name release];
	    NSMutableArray *clauseextensions = [NSMutableArray array];
	    NSMutableArray *displayextensions = [NSMutableArray array];
	    bool allowsAll = NO;

	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
		    clausePtr = clausePtr->next) {

		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
			globPtr = globPtr->next) {
		    const char *str = globPtr->pattern;
		    while (*str && (*str == '*' || *str == '.')) {
		    	str++;
		    }
		    if (*str) {
			NSString *extension = [[NSString alloc] initWithUTF8String:str];
			if (![filterInfo.allowedExtensions containsObject:extension]) {
			    [filterInfo.allowedExtensions addObject:extension];
			}

			[clauseextensions addObject:extension];
			[displayextensions addObject:[@"." stringByAppendingString:extension]];








|

















|







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

    filterInfo.allowedExtensions = [NSMutableArray array];
    filterInfo.allowedExtensionsAllowAll = NO;

    if (filterInfo.doFileTypes) {
	for (FileFilter *filterPtr = fl.filters; filterPtr;
		filterPtr = filterPtr->next) {
	    NSString *name = [[TKNSString alloc] initWithTclUtfBytes: filterPtr->name length:TCL_INDEX_NONE];

	    [filterInfo.fileTypeNames addObject:name];
	    [name release];
	    NSMutableArray *clauseextensions = [NSMutableArray array];
	    NSMutableArray *displayextensions = [NSMutableArray array];
	    bool allowsAll = NO;

	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
		    clausePtr = clausePtr->next) {

		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
			globPtr = globPtr->next) {
		    const char *str = globPtr->pattern;
		    while (*str && (*str == '*' || *str == '.')) {
		    	str++;
		    }
		    if (*str) {
			NSString *extension = [[TKNSString alloc] initWithTclUtfBytes:str length:TCL_INDEX_NONE];
			if (![filterInfo.allowedExtensions containsObject:extension]) {
			    [filterInfo.allowedExtensions addObject:extension];
			}

			[clauseextensions addObject:extension];
			[displayextensions addObject:[@"." stringByAppendingString:extension]];

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
	     * Check that the typevariable exists.
	     */

	    if (selectedFileTypeObj != NULL) {
		const char *selectedFileType =
			Tcl_GetString(selectedFileTypeObj);
		NSString *selectedFileTypeStr =
			[[NSString alloc] initWithUTF8String:selectedFileType];
		NSUInteger index =
			[filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr];

		if (index != NSNotFound) {
		    filterInfo.fileTypeIndex = index;
		    filterInfo.preselectFilter = true;
		}
	    }
	}

    }

    TkFreeFileFilters(&fl);
    return TCL_OK;
}

static bool
filterCompatible(
    NSString *extension,
    int filterIndex)
{
    NSMutableArray *allowedExtensions =
	    [filterInfo.fileTypeExtensions objectAtIndex: filterIndex];

    /*
     * If this contains the all pattern, accept any extension.
     */







|



















|







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
	     * Check that the typevariable exists.
	     */

	    if (selectedFileTypeObj != NULL) {
		const char *selectedFileType =
			Tcl_GetString(selectedFileTypeObj);
		NSString *selectedFileTypeStr =
			[[TKNSString alloc] initWithTclUtfBytes:selectedFileType length:TCL_INDEX_NONE];
		NSUInteger index =
			[filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr];

		if (index != NSNotFound) {
		    filterInfo.fileTypeIndex = index;
		    filterInfo.preselectFilter = true;
		}
	    }
	}

    }

    TkFreeFileFilters(&fl);
    return TCL_OK;
}

static bool
filterCompatible(
    NSString *extension,
	NSUInteger filterIndex)
{
    NSMutableArray *allowedExtensions =
	    [filterInfo.fileTypeExtensions objectAtIndex: filterIndex];

    /*
     * If this contains the all pattern, accept any extension.
     */
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
692
693
694
 * Side effects:
 *	See user documentation.
 *----------------------------------------------------------------------
 */

int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, multiple = 0;

    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil;
    NSString *message = nil, *title = nil;
    NSWindow *parent;
    openpanel =  [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;








|




|


|
>

<
<







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700


701
702
703
704
705
706
707
 * Side effects:
 *	See user documentation.
 *----------------------------------------------------------------------
 */

int
Tk_GetOpenFileObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, multiple = 0;
    Tcl_Size len;
    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;


    NSString *directory = nil, *filename = nil;
    NSString *message = nil, *title = nil;
    NSWindow *parent;
    openpanel =  [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744

745
746

747
748
749
750
751
752
753
	    break;
	case OPEN_FILETYPES:
	    fileTypesPtr = objv[i + 1];
	    break;
	case OPEN_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case OPEN_INITFILE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		filename = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case OPEN_MESSAGE:

	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];

	    break;
	case OPEN_MULTIPLE:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &multiple) != TCL_OK) {
		goto end;
	    }
	    break;
	case OPEN_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case OPEN_TITLE:

	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];

	    break;
	case OPEN_TYPEVARIABLE:
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;







|






|




>
|
<
>
















>
|
<
>







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768
	    break;
	case OPEN_FILETYPES:
	    fileTypesPtr = objv[i + 1];
	    break;
	case OPEN_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			autorelease];
	    }
	    break;
	case OPEN_INITFILE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		filename = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			autorelease];
	    }
	    break;
	case OPEN_MESSAGE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    message = [[TKNSString alloc] initWithTclUtfBytes:

		    str length:len];
	    break;
	case OPEN_MULTIPLE:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &multiple) != TCL_OK) {
		goto end;
	    }
	    break;
	case OPEN_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case OPEN_TITLE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    title = [[TKNSString alloc] initWithTclUtfBytes:

		    str length:len];
	    break;
	case OPEN_TYPEVARIABLE:
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859



860
861
862
863
864
865
866
    }

    if (message) {
	[openpanel setMessage:message];
	[message release];
    }

    [openpanel setAllowsMultipleSelection:multiple];

    if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
	goto end;
    }

    if (filterInfo.doFileTypes) {
	NSTextField *label = [[NSTextField alloc]
		initWithFrame:NSMakeRect(0, 0, 60, 22)];
	NSPopUpButton *popupButton = [[NSPopUpButton alloc]
		initWithFrame:NSMakeRect(50.0, 2, 240, 22.0) pullsDown:NO];
	NSView *accessoryView = [[NSView alloc]
		initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];

	[label setEditable:NO];
	[label setStringValue:@"Filter:"];
	[label setBordered:NO];
	[label setBezeled:NO];
	[label setDrawsBackground:NO];
	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];

	[popupButton setAction:@selector(selectFormat:)];
	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];
	if (filterInfo.preselectFilter) {

	    /*
	     * A specific filter was selected from the typevariable. Select it
	     * and open the accessory view.
	     */

	    [popupButton selectItemAtIndex:filterInfo.fileTypeIndex];

	    /*
	     * On OSX > 10.11, the options are not visible by default. Ergo
	     * allow all file types
	    [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
	    */

	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
	} else {
	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
	}
	if (filterInfo.allowedExtensionsAllowAll) {
	    [openpanel setAllowsOtherFileTypes:YES];
	} else {
	    [openpanel setAllowsOtherFileTypes:NO];
	}
	[openpanel setAccessoryView:accessoryView];
    } else {
	/*
	 * No filters are given. Allow picking all files.
	 */

	[openpanel setAllowsOtherFileTypes:YES];
    }
    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = multiple;
    if (directory || filename) {
	NSURL *fileURL = getFileURL(directory, filename);

	[openpanel setDirectoryURL:fileURL];
    }
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(openpanel, parent, callbackInfo);



    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    if ((typeVariablePtr && (modalReturnCode == NSOKButton))
	    && filterInfo.doFileTypes) {
	/*







|



















>










|







|

|




















<
<
<
<












|
>
>
>







790
791
792
793
794
795
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
    }

    if (message) {
	[openpanel setMessage:message];
	[message release];
    }

    [openpanel setAllowsMultipleSelection:multiple != 0];

    if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
	goto end;
    }

    if (filterInfo.doFileTypes) {
	NSTextField *label = [[NSTextField alloc]
		initWithFrame:NSMakeRect(0, 0, 60, 22)];
	NSPopUpButton *popupButton = [[NSPopUpButton alloc]
		initWithFrame:NSMakeRect(50.0, 2, 240, 22.0) pullsDown:NO];
	NSView *accessoryView = [[NSView alloc]
		initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];

	[label setEditable:NO];
	[label setStringValue:@"Filter:"];
	[label setBordered:NO];
	[label setBezeled:NO];
	[label setDrawsBackground:NO];
	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
	[popupButton setTarget:NSApp];
	[popupButton setAction:@selector(selectFormat:)];
	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];
	if (filterInfo.preselectFilter) {

	    /*
	     * A specific filter was selected from the typevariable. Select it
	     * and open the accessory view.
	     */

	    [popupButton selectItemAtIndex:(NSInteger)filterInfo.fileTypeIndex];

	    /*
	     * On OSX > 10.11, the options are not visible by default. Ergo
	     * allow all file types
	    [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
	    */

	    setAllowedFileTypes(openpanel, filterInfo.allowedExtensions);
	} else {
	    setAllowedFileTypes(openpanel, filterInfo.allowedExtensions);
	}
	if (filterInfo.allowedExtensionsAllowAll) {
	    [openpanel setAllowsOtherFileTypes:YES];
	} else {
	    [openpanel setAllowsOtherFileTypes:NO];
	}
	[openpanel setAccessoryView:accessoryView];
    } else {
	/*
	 * No filters are given. Allow picking all files.
	 */

	[openpanel setAllowsOtherFileTypes:YES];
    }
    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }




    if (directory || filename) {
	NSURL *fileURL = getFileURL(directory, filename);

	[openpanel setDirectoryURL:fileURL];
    }
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(openpanel, parent, interp, cmdObj, multiple);
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    if ((typeVariablePtr && (modalReturnCode == NSOKButton))
	    && filterInfo.doFileTypes) {
	/*
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
		    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
		} else {
		    selectedFilter = @"";
		}
	    }
	}
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
		Tcl_NewStringObj([selectedFilter UTF8String], -1),
		TCL_GLOBAL_ONLY);
    }
 end:
    return result;
}

/*







|







929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
		    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
		} else {
		    selectedFilter = @"";
		}
	    }
	}
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
		Tcl_NewStringObj([selectedFilter UTF8String], TCL_INDEX_NONE),
		TCL_GLOBAL_ONLY);
    }
 end:
    return result;
}

/*
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
 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int confirmOverwrite = 1;
    int index, len;

    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil, *filename = nil, *defaultType = nil;
    NSString *message = nil, *title = nil;
    NSWindow *parent;
    savepanel = [NSSavePanel savePanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;








|








|
>

<
<







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
 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int confirmOverwrite = 1;
    int index;
    Tcl_Size len;
    Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL;


    NSString *directory = nil, *filename = nil, *defaultType = nil;
    NSString *message = nil, *title = nil;
    NSWindow *parent;
    savepanel = [NSSavePanel savePanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009

1010
1011
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021

1022
1023
1024
1025
1026
1027
1028
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	    case SAVE_DEFAULT:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		while (*str && (*str == '*' || *str == '.')) {
		    str++;
		}
		if (*str) {
		    defaultType = [[[NSString alloc] initWithUTF8String:str]
			    autorelease];
		}
		break;
	    case SAVE_FILETYPES:
		fileTypesPtr = objv[i + 1];
		break;
	    case SAVE_INITDIR:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    directory = [[[NSString alloc] initWithUTF8String:str]
			    autorelease];
		}
		break;
	    case SAVE_INITFILE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    filename = [[[NSString alloc] initWithUTF8String:str]
			    autorelease];
		    [savepanel setNameFieldStringValue:filename];
		}
		break;
	    case SAVE_MESSAGE:

		message = [[NSString alloc] initWithUTF8String:
			Tcl_GetString(objv[i + 1])];

		break;
	    case SAVE_PARENT:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		tkwin = Tk_NameToWindow(interp, str, tkwin);
		if (!tkwin) {
		    goto end;
		}
		haveParentOption = 1;
		break;
	    case SAVE_TITLE:

		title = [[NSString alloc] initWithUTF8String:
			Tcl_GetString(objv[i + 1])];

		break;
	    case SAVE_TYPEVARIABLE:
		typeVariablePtr = objv[i + 1];
		break;
	    case SAVE_COMMAND:
		cmdObj = objv[i+1];
		break;







|


|









|






|





>
|
<
>










>
|
<
>







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
	    Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	    case SAVE_DEFAULT:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		while (*str && (*str == '*' || *str == '.')) {
		    str++; len--;
		}
		if (*str) {
		    defaultType = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			    autorelease];
		}
		break;
	    case SAVE_FILETYPES:
		fileTypesPtr = objv[i + 1];
		break;
	    case SAVE_INITDIR:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    directory = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			    autorelease];
		}
		break;
	    case SAVE_INITFILE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    filename = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			    autorelease];
		    [savepanel setNameFieldStringValue:filename];
		}
		break;
	    case SAVE_MESSAGE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		message = [[TKNSString alloc] initWithTclUtfBytes:

			str length:len];
		break;
	    case SAVE_PARENT:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		tkwin = Tk_NameToWindow(interp, str, tkwin);
		if (!tkwin) {
		    goto end;
		}
		haveParentOption = 1;
		break;
	    case SAVE_TITLE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		title = [[TKNSString alloc] initWithTclUtfBytes:

			str length:len];
		break;
	    case SAVE_TYPEVARIABLE:
		typeVariablePtr = objv[i + 1];
		break;
	    case SAVE_COMMAND:
		cmdObj = objv[i+1];
		break;
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
	[label setBezeled:NO];
	[label setDrawsBackground:NO];

	NSPopUpButton *popupButton = [[NSPopUpButton alloc]
		initWithFrame:NSMakeRect(50.0, 2, 340, 22.0) pullsDown:NO];

	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
	[popupButton selectItemAtIndex:filterInfo.fileTypeIndex];

	[popupButton setAction:@selector(saveFormat:)];

	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];

	[savepanel setAccessoryView:accessoryView];


	[savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]];
	[savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll];
    } else if (defaultType) {
	/*
	 * If no filetypes are given, defaultextension is an alternative way to
	 * specify the attached extension. Just propose this extension, but
	 * don't display an accessory view.
	 */

	NSMutableArray *AllowedFileTypes = [NSMutableArray array];

	[AllowedFileTypes addObject:defaultType];
	[savepanel setAllowedFileTypes:AllowedFileTypes];
	[savepanel setAllowsOtherFileTypes:YES];
    }

    [savepanel setCanSelectHiddenExtension:YES];
    [savepanel setExtensionHidden:NO];

    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;

    if (directory) {
	[savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    }

    /*
     * Check for file name and set to the empty string if nil. This prevents a crash







|
>

<





>
|











|












<
<
<
<







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
	[label setBezeled:NO];
	[label setDrawsBackground:NO];

	NSPopUpButton *popupButton = [[NSPopUpButton alloc]
		initWithFrame:NSMakeRect(50.0, 2, 340, 22.0) pullsDown:NO];

	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
	[popupButton selectItemAtIndex:(NSInteger)filterInfo.fileTypeIndex];
	[popupButton setTarget:NSApp];
	[popupButton setAction:@selector(saveFormat:)];

	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];

	[savepanel setAccessoryView:accessoryView];

	setAllowedFileTypes(savepanel,
	    [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]);
	[savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll];
    } else if (defaultType) {
	/*
	 * If no filetypes are given, defaultextension is an alternative way to
	 * specify the attached extension. Just propose this extension, but
	 * don't display an accessory view.
	 */

	NSMutableArray *AllowedFileTypes = [NSMutableArray array];

	[AllowedFileTypes addObject:defaultType];
	setAllowedFileTypes(savepanel, AllowedFileTypes);
	[savepanel setAllowsOtherFileTypes:YES];
    }

    [savepanel setCanSelectHiddenExtension:YES];
    [savepanel setExtensionHidden:NO];

    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }





    if (directory) {
	[savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    }

    /*
     * Check for file name and set to the empty string if nil. This prevents a crash
1138
1139
1140
1141
1142
1143
1144
1145



1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(savepanel, parent, callbackInfo);



    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }

    if (typeVariablePtr && (modalReturnCode == NSOKButton)
	    && filterInfo.doFileTypes) {
	/*
	 * The -typevariable must be set to the selected file type, if the
	 * dialog was not cancelled.
	 */

	NSString *selectedFilter =
	    [filterInfo.fileTypeNames objectAtIndex:filterInfo.fileTypeIndex];
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
		Tcl_NewStringObj([selectedFilter UTF8String], -1),
		TCL_GLOBAL_ONLY);
    }

  end:
    return result;
}








|
>
>
>















|







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
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(savepanel, parent, interp, cmdObj, 0);
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }

    if (typeVariablePtr && (modalReturnCode == NSOKButton)
	    && filterInfo.doFileTypes) {
	/*
	 * The -typevariable must be set to the selected file type, if the
	 * dialog was not cancelled.
	 */

	NSString *selectedFilter =
	    [filterInfo.fileTypeNames objectAtIndex:filterInfo.fileTypeIndex];
	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
		Tcl_NewStringObj([selectedFilter UTF8String], TCL_INDEX_NONE),
		TCL_GLOBAL_ONLY);
    }

  end:
    return result;
}

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
 *	A modal dialog window is created.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseDirectoryObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, mustexist = 0;

    Tcl_Obj *cmdObj = NULL;
    FilePanelCallbackInfo callbackInfoStruct;
    FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct;
    NSString *directory = nil;
    NSString *message, *title;
    NSWindow *parent;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;








|







|
>

<
<







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
 *	A modal dialog window is created.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseDirectoryObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, mustexist = 0;
    Tcl_Size len;
    Tcl_Obj *cmdObj = NULL;


    NSString *directory = nil;
    NSString *message, *title;
    NSWindow *parent;
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    NSInteger modalReturnCode = modalError;
    BOOL parentIsKey = NO;

1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227

1228
1229

1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249

1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290



1291
1292
1293
1294
1295
1296
1297
	    Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case CHOOSE_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
			autorelease];
	    }
	    break;
	case CHOOSE_MESSAGE:

	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];

	    [panel setMessage:message];
	    [message release];
	    break;
	case CHOOSE_MUSTEXIST:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &mustexist) != TCL_OK) {
		goto end;
	    }
	    break;
	case CHOOSE_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case CHOOSE_TITLE:

	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];

	    [panel setTitle:title];
	    [title release];
	    break;
	case CHOOSE_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    [panel setPrompt:@"Choose"];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setCanCreateDirectories:!mustexist];
    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (FilePanelCallbackInfo *)ckalloc(sizeof(FilePanelCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->multiple = 0;

    /*
     * Check for directory value, set to root if not specified; otherwise
     * crashes with exception because of nil string parameter.
     */

    if (!directory) {
	directory = @"/";
    }
    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
    [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(panel, parent, callbackInfo);



    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
  end:
    return result;
}







|




>
|
<
>


















>
|
<
>


















<
<
<
<


















|
>
>
>







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
	    Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case CHOOSE_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			autorelease];
	    }
	    break;
	case CHOOSE_MESSAGE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    message = [[TKNSString alloc] initWithTclUtfBytes:

		    str length:len];
	    [panel setMessage:message];
	    [message release];
	    break;
	case CHOOSE_MUSTEXIST:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &mustexist) != TCL_OK) {
		goto end;
	    }
	    break;
	case CHOOSE_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case CHOOSE_TITLE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    title = [[TKNSString alloc] initWithTclUtfBytes:

		    str length:len];
	    [panel setTitle:title];
	    [title release];
	    break;
	case CHOOSE_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    [panel setPrompt:@"Choose"];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setCanCreateDirectories:!mustexist];
    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }





    /*
     * Check for directory value, set to root if not specified; otherwise
     * crashes with exception because of nil string parameter.
     */

    if (!directory) {
	directory = @"/";
    }
    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
    [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(panel, parent, interp, cmdObj, 0);
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
  end:
    return result;
}
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
 *
 *----------------------------------------------------------------------
 */

void
TkAboutDlg(void)
{
    NSImage *image;
    NSString *path = [NSApp tkFrameworkImagePath: @"Tk.tiff"];

    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.
 *







<
<
|
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1327
1328
1329
1330
1331
1332
1333


1334




1335
1336

















































1337
1338
1339
1340
1341
1342
1343
 *
 *----------------------------------------------------------------------
 */

void
TkAboutDlg(void)
{


    [NSApp orderFrontStandardAboutPanel:nil];




}


















































/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
 *	Implements the ::tk::mac::standardAboutPanel command.
 *
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    TkAboutDlg();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --







|







1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    [NSApp orderFrontStandardAboutPanel:nil];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
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
 *	none
 *
 *----------------------------------------------------------------------
 */

int
Tk_MessageBoxObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, typeIndex, iconIndex, indexDefaultOption = 0;
    int defaultNativeButtonIndex = 1; /* 1, 2, 3: right to left */
    Tcl_Obj *cmdObj = NULL;
    AlertCallbackInfo callbackInfoStruct, *callbackInfo = &callbackInfoStruct;
    NSString *message, *title;
    NSWindow *parent;
    NSArray *buttons;
    NSAlert *alert = [NSAlert new];
    NSInteger modalReturnCode = 1;
    BOOL parentIsKey = NO;








|










|







1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
 *	none
 *
 *----------------------------------------------------------------------
 */

int
Tk_MessageBoxObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    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 callbackInfo;
    NSString *message, *title;
    NSWindow *parent;
    NSArray *buttons;
    NSAlert *alert = [NSAlert new];
    NSInteger modalReturnCode = 1;
    BOOL parentIsKey = NO;

1461
1462
1463
1464
1465
1466
1467
1468
1469


1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483


1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499


1500
1501
1502
1503
1504
1505
1506
	     * know the '-type' as well.
	     */

	    indexDefaultOption = i;
	    break;

	case ALERT_DETAIL:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];


	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "-icon value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];


	    [alert setMessageText:message];
	    [message release];
	    break;

	case ALERT_PARENT:
	    str = Tcl_GetString(objv[i + 1]);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;

	case ALERT_TITLE:
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];


	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "-type value", TCL_EXACT, &typeIndex) != TCL_OK) {







<
|
>
>












<
|
>
>














<
|
>
>







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
	     * know the '-type' as well.
	     */

	    indexDefaultOption = i;
	    break;

	case ALERT_DETAIL:

	    str = Tcl_GetString(objv[i + 1]);
	    message = [[TKNSString alloc] initWithTclUtfBytes:
		    str length:TCL_INDEX_NONE];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "-icon value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:

	    str = Tcl_GetString(objv[i + 1]);
	    message = [[TKNSString alloc] initWithTclUtfBytes:
		    str length:TCL_INDEX_NONE];
	    [alert setMessageText:message];
	    [message release];
	    break;

	case ALERT_PARENT:
	    str = Tcl_GetString(objv[i + 1]);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;

	case ALERT_TITLE:

	    str = Tcl_GetString(objv[i + 1]);
	    title = [[TKNSString alloc] initWithTclUtfBytes:
		    str length:TCL_INDEX_NONE];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "-type value", TCL_EXACT, &typeIndex) != TCL_OK) {
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
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

	defaultNativeButtonIndex =
		alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index];
	if (!defaultNativeButtonIndex) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("Illegal default option", -1));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
	    goto end;
	}
    }
    [alert setIcon:[NSApp applicationIconImage]];
    [alert setAlertStyle:alertStyles[iconIndex]];
    i = 0;
    while (i < 3 && alertButtonNames[typeIndex][i]) {
	[alert addButtonWithTitle:(NSString*) alertButtonNames[typeIndex][i++]];
    }
    buttons = [alert buttons];
    for (NSButton *b in buttons) {
	NSString *ke = [b keyEquivalent];

	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }
    [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
    [[buttons objectAtIndex: defaultNativeButtonIndex-1]
	    setKeyEquivalent: @"\r"];
    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }
    callbackInfo = (AlertCallbackInfo *)ckalloc(sizeof(AlertCallbackInfo));
    callbackInfo->cmdObj = cmdObj;
    callbackInfo->interp = interp;
    callbackInfo->typeIndex = typeIndex;
    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
	parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 	[alert beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkAlertDidEnd:alert
		    returnCode:returnCode
		    contextInfo:callbackInfo];
	}];
#else
	[alert beginSheetModalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
#endif
	modalReturnCode = cmdObj ? 0 :
	    [alert runModal];
    } else {
	modalReturnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
		contextInfo:callbackInfo];



    }
    result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR;
  end:
    [alert release];
    if (parentIsKey) {
	[parent makeKeyWindow];
    }







|




















|







<
|
|
|








|





|






|
>
>
>







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
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

	defaultNativeButtonIndex =
		alertButtonIndexAndTypeToNativeButtonIndex[typeIndex][index];
	if (!defaultNativeButtonIndex) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("Illegal default option", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "DEFAULT", NULL);
	    goto end;
	}
    }
    [alert setIcon:[NSApp applicationIconImage]];
    [alert setAlertStyle:alertStyles[iconIndex]];
    i = 0;
    while (i < 3 && alertButtonNames[typeIndex][i]) {
	[alert addButtonWithTitle:(NSString*) alertButtonNames[typeIndex][i++]];
    }
    buttons = [alert buttons];
    for (NSButton *b in buttons) {
	NSString *ke = [b keyEquivalent];

	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }
    [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
    [[buttons objectAtIndex: (NSUInteger)(defaultNativeButtonIndex-1)]
	    setKeyEquivalent: @"\r"];
    if (cmdObj) {
	if (Tcl_IsShared(cmdObj)) {
	    cmdObj = Tcl_DuplicateObj(cmdObj);
	}
	Tcl_IncrRefCount(cmdObj);
    }

    callbackInfo.cmdObj = cmdObj;
    callbackInfo.interp = interp;
    callbackInfo.typeIndex = typeIndex;
    parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
    if (haveParentOption && parent && ![parent attachedSheet]) {
	parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 	[alert beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkAlertDidEnd:alert
		    returnCode:returnCode
		    contextInfo:&callbackInfo];
	}];
#else
	[alert beginSheetModalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
	       contextInfo:&callbackInfo];
#endif
	modalReturnCode = cmdObj ? 0 :
	    [alert runModal];
    } else {
	modalReturnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
		contextInfo:&callbackInfo];
    }
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR;
  end:
    [alert release];
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
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
    FontchooserClosed,
    FontchooserSelection
};

static void		FontchooserEvent(int kind);
static Tcl_Obj *	FontchooserCget(FontchooserData *fcdPtr,
			    int optionIndex);
static int		FontchooserConfigureCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		FontchooserShowCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		FontchooserHideCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		FontchooserParentEventHandler(ClientData clientData,
			    XEvent *eventPtr);
static void		DeleteFontchooserData(ClientData clientData,
			    Tcl_Interp *interp);

MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
const TkEnsemble tkFontchooserEnsemble[] = {
    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

static Tcl_Interp *fontchooserInterp = NULL;
static NSFont *fontPanelFont = nil;
static NSMutableDictionary *fontPanelFontAttributes = nil;

static const char *const fontchooserOptionStrings[] = {
    "-parent", "-title", "-font", "-command",
    "-visible", NULL
};
enum FontchooserOption {
    FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd,
    FontchooserVisible
};

@implementation TKApplication(TKFontPanel)

- (void) changeFont: (id) sender
{







|
<
<
|
<
<
|
<
<
|

|















|



|







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
    FontchooserClosed,
    FontchooserSelection
};

static void		FontchooserEvent(int kind);
static Tcl_Obj *	FontchooserCget(FontchooserData *fcdPtr,
			    int optionIndex);
static Tcl_ObjCmdProc2 FontchooserConfigureCmd;


static Tcl_ObjCmdProc2 FontchooserShowCmd;


static Tcl_ObjCmdProc2 FontchooserHideCmd;


static void		FontchooserParentEventHandler(void *clientData,
			    XEvent *eventPtr);
static void		DeleteFontchooserData(void *clientData,
			    Tcl_Interp *interp);

MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
const TkEnsemble tkFontchooserEnsemble[] = {
    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

static Tcl_Interp *fontchooserInterp = NULL;
static NSFont *fontPanelFont = nil;
static NSMutableDictionary *fontPanelFontAttributes = nil;

static const char *const fontchooserOptionStrings[] = {
    "-command", "-font", "-parent", "-title",
    "-visible", NULL
};
enum FontchooserOption {
    FontchooserCmd, FontchooserFont, FontchooserParent, FontchooserTitle,
    FontchooserVisible
};

@implementation TKApplication(TKFontPanel)

- (void) changeFont: (id) sender
{
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
	    NSFontPanelUnderlineEffectModeMask |
	    NSFontPanelStrikethroughEffectModeMask;
}

- (void) windowDidOrderOffScreen: (NSNotification *)notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if ([[notification object] isEqual:[[NSFontManager sharedFontManager]
	    fontPanel:NO]]) {
	FontchooserEvent(FontchooserClosed);
    }
}
@end







|







1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
	    NSFontPanelUnderlineEffectModeMask |
	    NSFontPanelStrikethroughEffectModeMask;
}

- (void) windowDidOrderOffScreen: (NSNotification *)notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if ([[notification object] isEqual:[[NSFontManager sharedFontManager]
	    fontPanel:NO]]) {
	FontchooserEvent(FontchooserClosed);
    }
}
@end
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753
1754
1755
1756
1757
{
    FontchooserData *fcdPtr;
    Tcl_Obj *fontObj;

    if (!fontchooserInterp) {
	return;
    }
    fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
    switch (kind) {
    case FontchooserClosed:
	if (fcdPtr->parent != None) {
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	    fontchooserInterp = NULL;
	}
	break;
    case FontchooserSelection:
	fontObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
		fontPanelFont, fontPanelFontAttributes);
	if (fontObj) {
	    if (fcdPtr->cmdObj) {

		int objc, result;
		Tcl_Obj **objv, **tmpv;

		result = Tcl_ListObjGetElements(fontchooserInterp,
			fcdPtr->cmdObj, &objc, &objv);
		if (result == TCL_OK) {
		    tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);







|


|









>
|







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
{
    FontchooserData *fcdPtr;
    Tcl_Obj *fontObj;

    if (!fontchooserInterp) {
	return;
    }
    fcdPtr = (FontchooserData *)Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
    switch (kind) {
    case FontchooserClosed:
	if (fcdPtr->parent != NULL) {
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	    fontchooserInterp = NULL;
	}
	break;
    case FontchooserSelection:
	fontObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
		fontPanelFont, fontPanelFontAttributes);
	if (fontObj) {
	    if (fcdPtr->cmdObj) {
		Tcl_Size objc;
		int result;
		Tcl_Obj **objv, **tmpv;

		result = Tcl_ListObjGetElements(fontchooserInterp,
			fcdPtr->cmdObj, &objc, &objv);
		if (result == TCL_OK) {
		    tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
		    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
    FontchooserData *fcdPtr,
    int optionIndex)
{
    Tcl_Obj *resObj = NULL;

    switch(optionIndex) {
    case FontchooserParent:
	if (fcdPtr->parent != None) {
	    resObj = Tcl_NewStringObj(
		    ((TkWindow *)fcdPtr->parent)->pathName, -1);
	} else {
	    resObj = Tcl_NewStringObj(".", 1);
	}
	break;
    case FontchooserTitle:
	if (fcdPtr->titleObj) {
	    resObj = fcdPtr->titleObj;







|

|







1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
    FontchooserData *fcdPtr,
    int optionIndex)
{
    Tcl_Obj *resObj = NULL;

    switch(optionIndex) {
    case FontchooserParent:
	if (fcdPtr->parent != NULL) {
	    resObj = Tcl_NewStringObj(
		    ((TkWindow *)fcdPtr->parent)->pathName, TCL_INDEX_NONE);
	} else {
	    resObj = Tcl_NewStringObj(".", 1);
	}
	break;
    case FontchooserTitle:
	if (fcdPtr->titleObj) {
	    resObj = fcdPtr->titleObj;
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
	if (fcdPtr->cmdObj) {
	    resObj = fcdPtr->cmdObj;
	} else {
	    resObj = Tcl_NewObj();
	}
	break;
    case FontchooserVisible:
	resObj = Tcl_NewWideIntObj([[[NSFontManager sharedFontManager]
		fontPanel:NO] isVisible] != 0);
	break;
    default:
	resObj = Tcl_NewObj();
    }
    return resObj;
}








|
|







1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
	if (fcdPtr->cmdObj) {
	    resObj = fcdPtr->cmdObj;
	} else {
	    resObj = Tcl_NewObj();
	}
	break;
    case FontchooserVisible:
	resObj = Tcl_NewBooleanObj([[[NSFontManager sharedFontManager]
		fontPanel:NO] isVisible]);
	break;
    default:
	resObj = Tcl_NewObj();
    }
    return resObj;
}

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
 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);

    int i, r = TCL_OK;

    /*
     * With no arguments we return all the options in a dict
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
	Tcl_Obj *dictObj = Tcl_NewDictObj();

	for (i = 0; r == TCL_OK && fontchooserOptionStrings[i] != NULL; ++i) {
	    keyObj = Tcl_NewStringObj(fontchooserOptionStrings[i], -1);
	    valueObj = FontchooserCget(fcdPtr, i);
	    r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj);
	}
	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex, len;


	if (Tcl_GetIndexFromObjStruct(interp, objv[i], fontchooserOptionStrings,
		sizeof(char *), "option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*







|

|



|

>
|










|
|









|
>







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
 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    void *clientData,	/* Main window */
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);
    Tcl_Size i;
    int r = TCL_OK;

    /*
     * With no arguments we return all the options in a dict
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
	Tcl_Obj *dictObj = Tcl_NewDictObj();

	for (i = 0; r == TCL_OK && fontchooserOptionStrings[i] != NULL; ++i) {
	    keyObj = Tcl_NewStringObj(fontchooserOptionStrings[i], TCL_INDEX_NONE);
	    valueObj = FontchooserCget(fcdPtr, (int)i);
	    r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj);
	}
	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex;
	Tcl_Size len;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], fontchooserOptionStrings,
		sizeof(char *), "option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
	    return TCL_ERROR;
	}
	switch (optionIndex) {
	case FontchooserVisible: {
	    const char *msg = "cannot change read-only option "
		    "\"-visible\": use the show or hide command";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL);
	    return TCL_ERROR;
	}
	case FontchooserParent: {
	    Tk_Window parent = Tk_NameToWindow(interp,
		    Tcl_GetString(objv[i+1]), tkwin);

	    if (parent == None) {
		return TCL_ERROR;
	    }
	    if (fcdPtr->parent) {
		Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
			FontchooserParentEventHandler, fcdPtr);
	    }
	    fcdPtr->parent = parent;







|







|







1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
	    return TCL_ERROR;
	}
	switch (optionIndex) {
	case FontchooserVisible: {
	    const char *msg = "cannot change read-only option "
		    "\"-visible\": use the show or hide command";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL);
	    return TCL_ERROR;
	}
	case FontchooserParent: {
	    Tk_Window parent = Tk_NameToWindow(interp,
		    Tcl_GetString(objv[i+1]), tkwin);

	    if (parent == NULL) {
		return TCL_ERROR;
	    }
	    if (fcdPtr->parent) {
		Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
			FontchooserParentEventHandler, fcdPtr);
	    }
	    fcdPtr->parent = parent;
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
		    fcdPtr->titleObj = Tcl_DuplicateObj(fcdPtr->titleObj);
		}
		Tcl_IncrRefCount(fcdPtr->titleObj);
	    } else {
		fcdPtr->titleObj = NULL;
	    }
	    break;
	case FontchooserFont:
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, objv[i+1]);

		if (!f) {
		    return TCL_ERROR;
		}







|







1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
		    fcdPtr->titleObj = Tcl_DuplicateObj(fcdPtr->titleObj);
		}
		Tcl_IncrRefCount(fcdPtr->titleObj);
	    } else {
		fcdPtr->titleObj = NULL;
	    }
	    break;
	case FontchooserFont: {
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, objv[i+1]);

		if (!f) {
		    return TCL_ERROR;
		}
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
	    [fm setSelectedAttributes:fontPanelFontAttributes
		    isMultiple:NO];
	    if ([fp isVisible]) {
		Tk_SendVirtualEvent(fcdPtr->parent,
			"TkFontchooserFontChanged", NULL);
	    }
	    break;

	case FontchooserCmd:
	    if (fcdPtr->cmdObj) {
		Tcl_DecrRefCount(fcdPtr->cmdObj);
	    }
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		fcdPtr->cmdObj = objv[i+1];







>







1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
	    [fm setSelectedAttributes:fontPanelFontAttributes
		    isMultiple:NO];
	    if ([fp isVisible]) {
		Tk_SendVirtualEvent(fcdPtr->parent,
			"TkFontchooserFontChanged", NULL);
	    }
	    break;
	}
	case FontchooserCmd:
	    if (fcdPtr->cmdObj) {
		Tcl_DecrRefCount(fcdPtr->cmdObj);
	    }
	    Tcl_GetStringFromObj(objv[i+1], &len);
	    if (len) {
		fcdPtr->cmdObj = objv[i+1];
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
 *	Font Panel may be shown.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);

    if (fcdPtr->parent == None) {
	fcdPtr->parent = (Tk_Window)clientData;
	Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
    }

    NSFontManager *fm = [NSFontManager sharedFontManager];
    NSFontPanel *fp = [fm fontPanel:YES];







|

|


|


|







1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
 *	Font Panel may be shown.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    void *clientData,	/* Main window */
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Size),
    TCL_UNUSED(Tcl_Obj *const *))
{
    FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);

    if (fcdPtr->parent == NULL) {
	fcdPtr->parent = (Tk_Window)clientData;
	Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
    }

    NSFontManager *fm = [NSFontManager sharedFontManager];
    NSFontPanel *fp = [fm fontPanel:YES];
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    TCL_UNUSED(void *),	/* Main window */
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    NSFontPanel *fp = [[NSFontManager sharedFontManager] fontPanel:NO];

    if ([fp isVisible]) {
	[fp orderOut:NSApp];
    }







|







2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    TCL_UNUSED(void *),	/* Main window */
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(Tcl_Size),
    TCL_UNUSED(Tcl_Obj *const *))
{
    NSFontPanel *fp = [[NSFontManager sharedFontManager] fontPanel:NO];

    if ([fp isVisible]) {
	[fp orderOut:NSApp];
    }
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
 *	Font chooser parent info is cleared and font panel is hidden.
 *
 * ----------------------------------------------------------------------
 */

static void
FontchooserParentEventHandler(
    ClientData clientData,
    XEvent *eventPtr)
{
    FontchooserData *fcdPtr = clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
	fcdPtr->parent = NULL;
	FontchooserHideCmd(NULL, NULL, 0, NULL);
    }







|


|







2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
 *	Font chooser parent info is cleared and font panel is hidden.
 *
 * ----------------------------------------------------------------------
 */

static void
FontchooserParentEventHandler(
    void *clientData,
    XEvent *eventPtr)
{
    FontchooserData *fcdPtr = (FontchooserData *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
	fcdPtr->parent = NULL;
	FontchooserHideCmd(NULL, NULL, 0, NULL);
    }
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
 *	per-interp configuration data is destroyed.
 *
 * ----------------------------------------------------------------------
 */

static void
DeleteFontchooserData(
    ClientData clientData,
    Tcl_Interp *interp)
{
    FontchooserData *fcdPtr = clientData;

    if (fcdPtr->titleObj) {
	Tcl_DecrRefCount(fcdPtr->titleObj);
    }
    if (fcdPtr->cmdObj) {
	Tcl_DecrRefCount(fcdPtr->cmdObj);
    }







|


|







2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
 *	per-interp configuration data is destroyed.
 *
 * ----------------------------------------------------------------------
 */

static void
DeleteFontchooserData(
    void *clientData,
    Tcl_Interp *interp)
{
    FontchooserData *fcdPtr = (FontchooserData *)clientData;

    if (fcdPtr->titleObj) {
	Tcl_DecrRefCount(fcdPtr->titleObj);
    }
    if (fcdPtr->cmdObj) {
	Tcl_DecrRefCount(fcdPtr->cmdObj);
    }

Changes to macosx/tkMacOSXDraw.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
/*
 * tkMacOSXDraw.c --
 *
 *	This file contains functions that draw to windows. Many of thees
 *	functions emulate Xlib functions.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 2001-2009 Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
 * Copyright (c) 2014-2020 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkButton.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] CGContext]
#else
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] graphicsPort]
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING

#endif
*/

#define radians(d)	((d) * (M_PI/180.0))

/*
 * Non-antialiased CG drawing looks better and more like X11 drawing when using






|
|
|
|



















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
 * tkMacOSXDraw.c --
 *
 *	This file contains functions that draw to windows. Many of thees
 *	functions emulate Xlib functions.
 *
 * Copyright © 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 >= 101000
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] CGContext]
#else
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] graphicsPort]
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#define TK_MAC_DEBUG_CG
#endif
*/

#define radians(d)	((d) * (M_PI/180.0))

/*
 * Non-antialiased CG drawing looks better and more like X11 drawing when using
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}

	if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit",
		(char *)&cgAntiAliasLimit, TCL_LINK_INT) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	cgAntiAliasLimit = limit;

	/*
	 * Piggy-back the themed drawing var init here.
	 */

	if (Tcl_LinkVar(interp, "::tk::mac::useThemedToplevel",
		(char *)&useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame",
		(char *)&useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	transparentColor = TkMacOSXClearPixel();
    }
    return TCL_OK;
}








|









|



|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}

	if (Tcl_LinkVar(interp, "::tk::mac::CGAntialiasLimit",
		&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",
		&useThemedToplevel, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::useThemedFrame",
		&useThemedFrame, TCL_LINK_BOOLEAN) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
	transparentColor = TkMacOSXClearPixel();
    }
    return TCL_OK;
}

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap;
    NSImage *nsImage;
    if (width == 0 || height == 0) {
	return nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0,0)];
    }
    pixmap = Tk_GetPixmap(display, None, width, height, 0);
    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);








|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap;
    NSImage *nsImage;
    if (width <= 0 || height <= 0) {
	return nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0,0)];
    }
    pixmap = Tk_GetPixmap(display, None, width, height, 0);
    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    NSImage *nsImage;

    unsigned long origBackground = gc->background;

    gc->background = transparentColor;
    XSetClipOrigin(display, gc, 0, 0);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, width, height, 0, 0, 1);
    gc->background = origBackground;
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}








|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    NSImage *nsImage;

    unsigned long origBackground = gc->background;

    gc->background = transparentColor;
    XSetClipOrigin(display, gc, 0, 0);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, (unsigned)width, (unsigned)height, 0, 0, 1);
    gc->background = origBackground;
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
Tk_MacOSXGetCGContextForDrawable(
    Drawable drawable)
{
    MacDrawable *macDraw = (MacDrawable *)drawable;

    if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) {
	const size_t bitsPerComponent = 8;
	size_t bitsPerPixel, bytesPerRow, len;
	CGColorSpaceRef colorspace = NULL;
	CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
		kCGBitmapByteOrder32Host;
#else
		kCGBitmapByteOrderDefault;
#endif
	char *data;
	CGRect bounds = CGRectMake(0, 0,
		macDraw->size.width, macDraw->size.height);

	if (macDraw->flags & TK_IS_BW_PIXMAP) {
	    bitsPerPixel = 8;
	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateDeviceRGB();
	    bitsPerPixel = 32;
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}
	bytesPerRow = ((size_t)
		macDraw->size.width * bitsPerPixel + 127) >> 3 & ~15;
	len = macDraw->size.height * bytesPerRow;
	data = (char *)ckalloc(len);
	bzero(data, len);
	macDraw->context = CGBitmapContextCreate(data, macDraw->size.width,
		macDraw->size.height, bitsPerComponent, bytesPerRow,
		colorspace, bitmapInfo);
	if (macDraw->context) {
	    CGContextClearRect(macDraw->context, bounds);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}







<







<




<



<


<
<
<
<
<
|
|







244
245
246
247
248
249
250

251
252
253
254
255
256
257

258
259
260
261

262
263
264

265
266





267
268
269
270
271
272
273
274
275
Tk_MacOSXGetCGContextForDrawable(
    Drawable drawable)
{
    MacDrawable *macDraw = (MacDrawable *)drawable;

    if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) {
	const size_t bitsPerComponent = 8;

	CGColorSpaceRef colorspace = NULL;
	CGBitmapInfo bitmapInfo =
#ifdef __LITTLE_ENDIAN__
		kCGBitmapByteOrder32Host;
#else
		kCGBitmapByteOrderDefault;
#endif

	CGRect bounds = CGRectMake(0, 0,
		macDraw->size.width, macDraw->size.height);

	if (macDraw->flags & TK_IS_BW_PIXMAP) {

	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
	} else {
	    colorspace = CGColorSpaceCreateDeviceRGB();

	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	}





	macDraw->context = CGBitmapContextCreate(NULL, (unsigned)macDraw->size.width,
		(unsigned)macDraw->size.height, bitsPerComponent, 0,
		colorspace, bitmapInfo);
	if (macDraw->context) {
	    CGContextClearRect(macDraw->context, bounds);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    if (npoints < 2) {
	return BadValue;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (lw % 2) ? .5 : 0;








|







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    if (npoints < 2) {
	return BadValue;
    }

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (lw % 2) ? .5 : 0;

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
    XSegment *segments,
    int nsegments)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double o = (lw % 2) ? .5 : 0;

	for (i = 0; i < nsegments; i++) {







|







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
    XSegment *segments,
    int nsegments)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double o = (lw % 2) ? .5 : 0;

	for (i = 0; i < nsegments; i++) {
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
int
XFillPolygon(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint *points,		/* Array of points. */
    int npoints,		/* Number of points. */
    TCL_UNUSED(int),	/* Shape to draw. */
    int mode)			/* Drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (gc->line_width % 2) ? .5 : 0;








|






|







519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
int
XFillPolygon(
    Display *display,		/* Display. */
    Drawable d,			/* Draw on this. */
    GC gc,			/* Use this GC. */
    XPoint *points,		/* Array of points. */
    int npoints,		/* Number of points. */
    TCL_UNUSED(int),		/* Shape to draw. */
    int mode)			/* Drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i;

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (gc->line_width % 2) ? .5 : 0;

557
558
559
560
561
562
563

564

565
566
567
568
569
570
571
			macWin->yOff + points[i].y + o);
	    } else {
		prevx += points[i].x;
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}

	CGContextEOFillPath(dc.context);

    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------







>
|
>







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
			macWin->yOff + points[i].y + o);
	    } else {
		prevx += points[i].x;
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}
	(gc->fill_rule == EvenOddRule)
		? CGContextEOFillPath(dc.context)
		: CGContextFillPath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;








|







590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0) {
	return BadDrawable;
    }

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
    int nRects)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;








|







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
    int nRects)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i, lw = gc->line_width;

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
    int n_rectangles)		/* Number of rectangles. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;

	for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {







|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
    int n_rectangles)		/* Number of rectangles. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i;

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;

	for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;








|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc *arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;








|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc *arcPtr;
    int i, lw = gc->line_width;

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;








|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc * arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;








|







1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc * arcPtr;
    int i, lw = gc->line_width;

    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

1087
1088
1089
1090
1091
1092
1093

























1094
1095
1096
1097
1098
1099
1100
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *

























 * TkScrollWindow --
 *
 *	Scroll a rectangle of the specified window and accumulate a damage
 *	region.
 *
 * Results:
 *	Returns 0 if the scroll generated no additional damage. Otherwise, sets







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawingIsDisabled --
 *
 *	Query whether the given window is disabled, in this case drawing
 *	is also disabled.
 *
 * Results:
 *	Whether the drawing is disabled.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpDrawingIsDisabled(
   Tk_Window tkwin)
{
    MacDrawable *macWin = ((TkWindow *) tkwin)->privatePtr;
    return macWin && !!(macWin->flags & TK_DO_NOT_DRAW);
}

/*
 *----------------------------------------------------------------------
 *
 * TkScrollWindow --
 *
 *	Scroll a rectangle of the specified window and accumulate a damage
 *	region.
 *
 * Results:
 *	Returns 0 if the scroll generated no additional damage. Otherwise, sets
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
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *)drawable;
    TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(macDraw);
    CGRect srcRect, dstRect;
    HIShapeRef dmgRgn = NULL, extraRgn = NULL;
    NSRect bounds, visRect, scrollSrc, scrollDst;
    int result = 0;

    if (view) {

  	/*
	 * Get the scroll area in NSView coordinates (origin at bottom left).
	 */

  	bounds = [view bounds];
 	scrollSrc = NSMakeRect(macDraw->xOff + x,
		bounds.size.height - height - (macDraw->yOff + y),
		width, height);
 	scrollDst = NSOffsetRect(scrollSrc, dx, -dy);

  	/*
	 * Limit scrolling to the window content area.
	 */

 	visRect = [view visibleRect];
 	scrollSrc = NSIntersectionRect(scrollSrc, visRect);
 	scrollDst = NSIntersectionRect(scrollDst, visRect);
 	if (!NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst)) {
  	    /*
  	     * Mark the difference between source and destination as damaged.
	     * This region is described in NSView coordinates (y=0 at the
	     * bottom) and converted to Tk coordinates later.
  	     */

	    srcRect = CGRectMake(x, y, width, height);
	    dstRect = CGRectOffset(srcRect, dx, dy);

	    /*
	     * Compute the damage.
	     */

  	    dmgRgn = HIShapeCreateMutableWithRect(&srcRect);
 	    extraRgn = HIShapeCreateWithRect(&dstRect);
 	    ChkErr(HIShapeDifference, dmgRgn, extraRgn,
		    (HIMutableShapeRef) dmgRgn);
	    result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;

	    /*
	     * Convert to Tk coordinates, offset by the window origin.
	     */

	    TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
	    if (extraRgn) {
		CFRelease(extraRgn);
	    }

 	    /*
	     * Scroll the rectangle.
	     */

 	    [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)];
  	}



    } else {


	dmgRgn = HIShapeCreateEmpty();

	TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);



    }

    if (dmgRgn) {



	CFRelease(dmgRgn);

    }

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpGraphicsPort --







|
|
|



>





|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
|

|
|
>
>
>
|
>
>
|
>
|
>
>
>
|
|
|
>
>
>
|
>
|
>







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
    int width, int height,
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Drawable drawable = Tk_WindowId(tkwin);
    MacDrawable *macDraw = (MacDrawable *)drawable;
    TKContentView *view = (TKContentView *)TkMacOSXGetNSViewForDrawable(macDraw);
    HIShapeRef srcRgn, dstRgn;
    HIMutableShapeRef dmgRgn = HIShapeCreateMutable();
    NSRect bounds, viewSrcRect, srcRect, dstRect;
    int result = 0;

    if (view) {

  	/*
	 * Get the scroll area in NSView coordinates (origin at bottom left).
	 */

  	bounds = [view bounds];
 	viewSrcRect = NSMakeRect(macDraw->xOff + x,
		bounds.size.height - height - (macDraw->yOff + y),
		width, height);






































	/*
	 * Scroll the rectangle.
	 */

	[view scrollRect:viewSrcRect by:NSMakeSize(dx, -dy)];

	/*
	 * Compute the damage region, using Tk coordinates (origin at top left).
	 */

	srcRect = CGRectMake(x, y, width, height);
	dstRect = CGRectOffset(srcRect, dx, dy);
	srcRgn = HIShapeCreateWithRect(&srcRect);
	dstRgn = HIShapeCreateWithRect(&dstRect);
	ChkErr(HIShapeDifference, srcRgn, dstRgn, dmgRgn);
	CFRelease(dstRgn);
	CFRelease(srcRgn);
	result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;

    }

    /*
     * Convert the HIShape dmgRgn into a TkRegion and store it.
     */

    TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);

    CFRelease(dmgRgn);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpGraphicsPort --
1238
1239
1240
1241
1242
1243
1244






1245
1246
1247
1248
1249
1250
1251
    GC gc,
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = (MacDrawable *)d;
    Bool canDraw = true;
    TKContentView *view = nil;
    TkMacOSXDrawingContext dc = {};







    /*
     * If the drawable is not a pixmap, get the associated NSView.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	view = (TKContentView *)TkMacOSXGetNSViewForDrawable(d);







>
>
>
>
>
>







1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
    GC gc,
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = (MacDrawable *)d;
    Bool canDraw = true;
    TKContentView *view = nil;
    TkMacOSXDrawingContext dc = {};
    CGFloat drawingHeight;

#ifdef TK_MAC_DEBUG_CG
    fprintf(stderr, "TkMacOSXSetupDrawingContext: %s\n",
	    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
#endif

    /*
     * If the drawable is not a pixmap, get the associated NSView.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	view = (TKContentView *)TkMacOSXGetNSViewForDrawable(d);
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290

    /*
     * If the drawable already has a CGContext, use it.  Otherwise, we must be
     * drawing to a window and we use the current context of its ContentView.
     */

    dc.context = TkMacOSXGetCGContextForDrawable(d);
    if (dc.context) {
	dc.portBounds = CGContextGetClipBoundingBox(dc.context);
    } else {
	NSRect drawingBounds, currentBounds;

	dc.view = view;
	dc.context = GET_CGCONTEXT;
	dc.portBounds = NSRectToCGRect([view bounds]);
	if (dc.clipRgn) {
	    CGRect clipBounds;
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
				    .ty = [view bounds].size.height};
	    HIShapeGetBounds(dc.clipRgn, &clipBounds);
	    clipBounds = CGRectApplyAffineTransform(clipBounds, t);
	    drawingBounds = NSRectFromCGRect(clipBounds);







|
<
<

<


<







1272
1273
1274
1275
1276
1277
1278
1279


1280

1281
1282

1283
1284
1285
1286
1287
1288
1289

    /*
     * 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) {


	NSRect drawingBounds, currentBounds;

	dc.view = view;
	dc.context = GET_CGCONTEXT;

	if (dc.clipRgn) {
	    CGRect clipBounds;
	    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
				    .ty = [view bounds].size.height};
	    HIShapeGetBounds(dc.clipRgn, &clipBounds);
	    clipBounds = CGRectApplyAffineTransform(clipBounds, t);
	    drawingBounds = NSRectFromCGRect(clipBounds);
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334










1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346

1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361









1362







1363













1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
	 * the clipping rectangle set by drawRect does not contain the clipping
	 * region of our drawing context.  (See bug [2a61eca3a8].)  If part of
	 * the drawing bounds will be clipped then we draw whatever we can, but
	 * we also add the drawing bounds to the view's dirty rectangle so it
	 * will get redrawn in the next call to its drawRect method.
	 */

	currentBounds = CGContextGetClipBoundingBox(dc.context);
	if (!NSContainsRect(currentBounds, drawingBounds)) {
	    [view addTkDirtyRect:drawingBounds];
	}
    }

    /*
     * Finish configuring the drawing context.
     */











    CGAffineTransform t = {
	.a = 1, .b = 0,
	.c = 0, .d = -1,
	.tx = 0,
	.ty = dc.portBounds.size.height
    };

    dc.portBounds.origin.x += macDraw->xOff;
    dc.portBounds.origin.y += macDraw->yOff;
    CGContextSaveGState(dc.context);
    CGContextSetTextDrawingMode(dc.context, kCGTextFill);
    CGContextConcatCTM(dc.context, t);

    if (dc.clipRgn) {

#ifdef TK_MAC_DEBUG_DRAWING
	CGContextSaveGState(dc.context);
	ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
	CGContextEOFillPath(dc.context);
	CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */

	CGRect r;
	CGRect b = CGRectApplyAffineTransform(
	    CGContextGetClipBoundingBox(dc.context), t);
	if (!HIShapeIsRectangular(dc.clipRgn) ||
	    !CGRectContainsRect(*HIShapeGetBounds(dc.clipRgn, &r), b)) {









	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);







	    CGContextEOClip(dc.context);













	}
    }
    if (gc) {
	static const CGLineCap cgCap[] = {
	    [CapNotLast] = kCGLineCapButt,
	    [CapButt] = kCGLineCapButt,
	    [CapRound] = kCGLineCapRound,
	    [CapProjecting] = kCGLineCapSquare,
	};
	static const CGLineJoin cgJoin[] = {
	    [JoinMiter] = kCGLineJoinMiter,
	    [JoinRound] = kCGLineJoinRound,
	    [JoinBevel] = kCGLineJoinBevel,
	};
	bool shouldAntialias = !notAA(gc->line_width);
	double w = gc->line_width;

	TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	if (view) {

	    CGContextSetPatternPhase(dc.context, CGSizeMake(
	        dc.portBounds.size.width, dc.portBounds.size.height));
	}
	if (gc->function != GXcopy) {
	    TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			   "not supported for CG drawing!");
	}
	if (!shouldAntialias) {

	    /*
	     * Make non-antialiased CG drawing look more like X11.
	     */

	    w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
	}
	CGContextSetShouldAntialias(dc.context, shouldAntialias);
	CGContextSetLineWidth(dc.context, w);
	if (gc->line_style != LineSolid) {
	    int num = 0;
	    char *p = &gc->dashes;
	    CGFloat dashOffset = gc->dash_offset;
	    dashOffset -= (gc->line_width % 2) ? 0.5 : 0.0;
	    CGFloat lengths[10];

	    while (p[num] != '\0' && num < 10) {
		lengths[num] = p[num];







|









>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
<
<
<
<
<
|
>










<
<
<
|
|
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>



















>
|
<
















|







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
	 * 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];
	}
    }

    /*
     * Finish configuring the drawing context.
     */

#ifdef TK_MAC_DEBUG_CG
    fprintf(stderr, "TkMacOSXSetupDrawingContext: pushing GState for %s\n",
	    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
#endif

    CGContextSaveGState(dc.context);
    CGContextSetTextDrawingMode(dc.context, kCGTextFill);
    { /* Restricted scope for t needed for C++ */
	drawingHeight = view ? [view bounds].size.height :
	    CGContextGetClipBoundingBox(dc.context).size.height;
	CGAffineTransform t = {
	    .a = 1, .b = 0,
	    .c = 0, .d = -1,
	    .tx = 0,
	    .ty = drawingHeight
	};





	CGContextConcatCTM(dc.context, t);
    }
    if (dc.clipRgn) {

#ifdef TK_MAC_DEBUG_DRAWING
	CGContextSaveGState(dc.context);
	ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
	CGContextEOFillPath(dc.context);
	CGContextRestoreGState(dc.context);
#endif /* TK_MAC_DEBUG_DRAWING */




	if (!HIShapeIsRectangular(dc.clipRgn)) {

	    /*
	     * We expect the clipping path dc.clipRgn to consist of the
	     * bounding rectangle of the drawable window, together with
	     * disjoint smaller rectangles inside of it which bound its
	     * geometric children.  In that case the even-odd rule will
	     * clip to the region inside the large rectangle and outside
	     * of the smaller rectangles.
	     */

	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);

#ifdef TK_MAC_DEBUG_CG
	    fprintf(stderr, "Setting complex clip for %s to:\n",
		    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
	    TkMacOSXPrintRectsInRegion(dc.clipRgn);
#endif

	    CGContextEOClip(dc.context);
	} else {
	    CGRect r;
	    HIShapeGetBounds(dc.clipRgn, &r);

#ifdef TK_MAC_DEBUG_CG
	    fprintf(stderr, "Current clip BBox is %s\n",
		    NSStringFromRect(CGContextGetClipBoundingBox(GET_CGCONTEXT)).UTF8String);
	    fprintf(stderr, "Setting clip for %s to rect %s:\n",
		    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None",
		    NSStringFromRect(r).UTF8String);
#endif

	    CGContextClipToRect(dc.context, r);
	}
    }
    if (gc) {
	static const CGLineCap cgCap[] = {
	    [CapNotLast] = kCGLineCapButt,
	    [CapButt] = kCGLineCapButt,
	    [CapRound] = kCGLineCapRound,
	    [CapProjecting] = kCGLineCapSquare,
	};
	static const CGLineJoin cgJoin[] = {
	    [JoinMiter] = kCGLineJoinMiter,
	    [JoinRound] = kCGLineJoinRound,
	    [JoinBevel] = kCGLineJoinBevel,
	};
	bool shouldAntialias = !notAA(gc->line_width);
	double w = gc->line_width;

	TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	if (view) {
	    CGSize size = NSSizeToCGSize([view bounds].size);
	    CGContextSetPatternPhase(dc.context, size);

	}
	if (gc->function != GXcopy) {
	    TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			   "not supported for CG drawing!");
	}
	if (!shouldAntialias) {

	    /*
	     * Make non-antialiased CG drawing look more like X11.
	     */

	    w -= (gc->line_width ? NON_AA_CG_OFFSET : 0);
	}
	CGContextSetShouldAntialias(dc.context, shouldAntialias);
	CGContextSetLineWidth(dc.context, w);
	if (gc->line_style != LineSolid) {
	    size_t 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];
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
	    CGContextSetLineJoin(dc.context, cgJoin[(unsigned) gc->join_style]);
	}
    }

end:

#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && win != NULL) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);

	if (winPtr) {
	    fprintf(stderr, "Cannot draw in %s - postponing.\n",
		    Tk_PathName(winPtr));
	}
    }
#endif

    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }







|
<
<
<
|
|
<







1448
1449
1450
1451
1452
1453
1454
1455



1456
1457

1458
1459
1460
1461
1462
1463
1464
	    CGContextSetLineJoin(dc.context, cgJoin[(unsigned) gc->join_style]);
	}
    }

end:

#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && macDraw->winPtr != NULL) {



	fprintf(stderr, "Cannot draw in %s - postponing.\n",
		Tk_PathName(macDraw->winPtr));

    }
#endif

    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
1458
1459
1460
1461
1462
1463
1464





1465
1466
1467

1468

1469
1470
1471

1472
1473
1474
1475
1476
1477
1478
void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);
	CGContextRestoreGState(dcPtr->context);





    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);

    }

#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetClipRgn --
 *







>
>
>
>
>



>

>


|
>







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
void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);
	CGContextRestoreGState(dcPtr->context);

#ifdef TK_MAC_DEBUG_CG
	fprintf(stderr, "TkMacOSXRestoreDrawingContext: popped GState\n");
#endif

    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
	dcPtr->clipRgn = NULL;
    }

#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetClipRgn --
 *
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
    }
    return clipRgn;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClipDrawableToRect --
 *
 *	Clip all drawing into the drawable d to the given rectangle. If width
 *	or height are negative, reset to no clipping.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Subsequent drawing into d is offset and clipped as specified.
 *
 *----------------------------------------------------------------------
 */

void
TkpClipDrawableToRect(
    TCL_UNUSED(Display *),
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *)d;








|














|







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
    }
    return clipRgn;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ClipDrawableToRect --
 *
 *	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
Tk_ClipDrawableToRect(
    TCL_UNUSED(Display *),
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *)d;

1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --
 *
 *	This procedure draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *	On the Macintosh, this puts a 1 pixel border in the bgGC color between
 *	the widget and the focus ring, except in the case where highlightWidth
 *	is 1, in which case the border is left out.







|







1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DrawHighlightBorder --
 *
 *	This procedure draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *	On the Macintosh, this puts a 1 pixel border in the bgGC color between
 *	the widget and the focus ring, except in the case where highlightWidth
 *	is 1, in which case the border is left out.
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawHighlightBorder (
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    if (highlightWidth == 1) {







|







1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
Tk_DrawHighlightBorder (
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    if (highlightWidth == 1) {

Changes to macosx/tkMacOSXEmbed.c.

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]>
 *
 * 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"









|
|
|







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 © 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"
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
				/* First in list of all containers managed by
				 * this process. */

/*
 * Prototypes for static procedures defined in this file:
 */

static void	ContainerEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbeddedEventProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedActivateProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedFocusProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedGeometryRequest(Container *containerPtr, int width,
		    int height);
static void	EmbedSendConfigure(Container *containerPtr);
static void	EmbedStructureProc(ClientData clientData, XEvent *eventPtr);
static void	EmbedWindowDeleted(TkWindow *winPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeWindow --
 *
 *	Creates an X Window (Mac subwindow).
 *
 * Results:
 *	The window id is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Window
TkpMakeWindow(
    TkWindow *winPtr,
    Window parent)
{
    MacDrawable *macWin;
    (void)parent;

    /*
     * If this window is marked as embedded then the window structure should
     * have already been created in the TkpUseWindow function.
     */

    if (Tk_IsEmbedded(winPtr)) {
	macWin = winPtr->privatePtr;
    } else {
	/*
	 * Allocate sub window







|
|
|
|



|





|













|
|
|


|



|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
				/* First in list of all containers managed by
				 * this process. */

/*
 * Prototypes for static procedures defined in this file:
 */

static void	ContainerEventProc(void *clientData, XEvent *eventPtr);
static void	EmbeddedEventProc(void *clientData, XEvent *eventPtr);
static void	EmbedActivateProc(void *clientData, XEvent *eventPtr);
static void	EmbedFocusProc(void *clientData, XEvent *eventPtr);
static void	EmbedGeometryRequest(Container *containerPtr, int width,
		    int height);
static void	EmbedSendConfigure(Container *containerPtr);
static void	EmbedStructureProc(void *clientData, XEvent *eventPtr);
static void	EmbedWindowDeleted(TkWindow *winPtr);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MakeWindow --
 *
 *	Creates an X Window (Mac subwindow).
 *
 * Results:
 *	The window id is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Window
Tk_MakeWindow(
    Tk_Window tkwin,
    TCL_UNUSED(Window))
{
    MacDrawable *macWin;
    TkWindow *winPtr = (TkWindow *)tkwin;

    /*
     * If this window is marked as embedded then the window structure should
     * have already been created in the Tk_UseWindow function.
     */

    if (Tk_IsEmbedded(winPtr)) {
	macWin = winPtr->privatePtr;
    } else {
	/*
	 * Allocate sub window
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *
 *	This procedure causes a Tk window to use a given X window as its
 *	parent window, rather than the root window for the screen. It is
 *	invoked by an embedded application to specify the window in which it
 *	is embedded.
 *
 * Results:
 *	The return value is normally TCL_OK. If an error occurs (such as
 *	string not being a valid window spec), then the return value is
 *	TCL_ERROR and an error message is left in the interp's result if
 *	interp is non-NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    MacDrawable *parent, *macWin;
    Container *containerPtr;

    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }

    /*
     * Decode the container window ID, and look for it among the list of
     * available containers.







|



















|














|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_UseWindow --
 *
 *	This procedure causes a Tk window to use a given X window as its
 *	parent window, rather than the root window for the screen. It is
 *	invoked by an embedded application to specify the window in which it
 *	is embedded.
 *
 * Results:
 *	The return value is normally TCL_OK. If an error occurs (such as
 *	string not being a valid window spec), then the return value is
 *	TCL_ERROR and an error message is left in the interp's result if
 *	interp is non-NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tk_UseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    MacDrawable *parent, *macWin;
    Container *containerPtr;

    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }

    /*
     * Decode the container window ID, and look for it among the list of
     * available containers.
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeContainer --
 *
 *	This procedure is called to indicate that a particular window will be
 *	a container for an embedded application. This changes certain aspects
 *	of the window's behavior, such as whether it will receive events
 *	anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeContainer(
    Tk_Window tkwin)		/* Token for a window that is about to become
				 * a container. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;

    /*







|
















|







318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MakeContainer --
 *
 *	This procedure is called to indicate that a particular window will be
 *	a container for an embedded application. This changes certain aspects
 *	of the window's behavior, such as whether it will receive events
 *	anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MakeContainer(
    Tk_Window tkwin)		/* Token for a window that is about to become
				 * a container. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;

    /*
431
432
433
434
435
436
437




438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
 */

MacDrawable *
TkMacOSXGetHostToplevel(
    TkWindow *winPtr)		/* Tk's structure for a window. */
{
    TkWindow *contWinPtr, *topWinPtr;





    topWinPtr = winPtr->privatePtr->toplevel->winPtr;
    if (!Tk_IsEmbedded(topWinPtr)) {
	return winPtr->privatePtr->toplevel;
    }
    contWinPtr = TkpGetOtherWindow(topWinPtr);

    /*
     * TODO: Here we should handle out of process embedding.
     */

    if (!contWinPtr) {
	return NULL;
    }
    return TkMacOSXGetHostToplevel(contWinPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClaimFocus --







>
>
>
>





|





<
<
<







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452



453
454
455
456
457
458
459
 */

MacDrawable *
TkMacOSXGetHostToplevel(
    TkWindow *winPtr)		/* Tk's structure for a window. */
{
    TkWindow *contWinPtr, *topWinPtr;

    if (!(winPtr && winPtr->privatePtr)) {
	return NULL;
    }

    topWinPtr = winPtr->privatePtr->toplevel->winPtr;
    if (!Tk_IsEmbedded(topWinPtr)) {
	return winPtr->privatePtr->toplevel;
    }
    contWinPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)topWinPtr);

    /*
     * TODO: Here we should handle out of process embedding.
     */




    return TkMacOSXGetHostToplevel(contWinPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClaimFocus --
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];
    Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;
    (void)dummy;

    if ((objc > 1) && (strcmp(Tcl_GetString(objv[1]), "all") == 0)) {
	all = 1;
    } else {
	all = 0;
    }
    Tcl_DStringInit(&dString);







|

|







<







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];
    Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;


    if ((objc > 1) && (strcmp(Tcl_GetString(objv[1]), "all") == 0)) {
	all = 1;
    } else {
	all = 0;
    }
    Tcl_DStringInit(&dString);
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
	/*
	 * Parent id
	 */

	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x",
		    (size_t) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}

	/*







|







553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
	/*
	 * Parent id
	 */

	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    snprintf(buffer, sizeof(buffer), "0x%" TCL_Z_MODIFIER "x",
		    (size_t) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}

	/*
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
 *	The event may get sent to a different application.
 *
 *----------------------------------------------------------------------
 */

void
TkpRedirectKeyEvent(
    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{
    (void)winPtr;
    (void)eventPtr;

    /* TODO: Implement this or decide it definitely needs no implementation */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this procedure will return either one, given the other.
 *
 * Results:
 *	If winPtr is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow *
TkpGetOtherWindow(
    TkWindow *winPtr)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;

    /*
     * TkpGetOtherWindow returns NULL if both windows are not in the same
     * process...
     */

    if (!(winPtr->flags & TK_BOTH_HALVES)) {
	return NULL;
    }

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parentPtr;
	} else if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







|

|


<
<
<






|





|









|
|
|





|



|





|
|
|
|







619
620
621
622
623
624
625
626
627
628
629
630



631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
 *	The event may get sent to a different application.
 *
 *----------------------------------------------------------------------
 */

void
TkpRedirectKeyEvent(
    TCL_UNUSED(TkWindow *),		/* Window to which the event was originally
				 * reported. */
    TCL_UNUSED(XEvent *))		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{



    /* TODO: Implement this or decide it definitely needs no implementation */
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this procedure will return either one, given the other.
 *
 * Results:
 *	If tkwin is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
Tk_GetOtherWindow(
    Tk_Window tkwin)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;

    /*
     * Tk_GetOtherWindow returns NULL if both windows are not in the same
     * process...
     */

    if (!(tkwin && (((TkWindow*)tkwin)->flags & TK_BOTH_HALVES))) {
	return NULL;
    }

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if ((Tk_Window)containerPtr->embeddedPtr == tkwin) {
	    return (Tk_Window)containerPtr->parentPtr;
	} else if ((Tk_Window)containerPtr->parentPtr == tkwin) {
	    return (Tk_Window)containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
 *	destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
}

/*







|


|







694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
 *	destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EmbeddedEventProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
}

/*
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;

    if (!firstContainerPtr) {
	/*
	 * When the interpreter is being dismantled this can be nil.
	 */







|


|







729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;

    if (!firstContainerPtr) {
	/*
	 * When the interpreter is being dismantled this can be nil.
	 */
840
841
842
843
844
845
846
847
848
849
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
 *	The embedded window gets resized to match the container.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedStructureProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {

	/*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != None) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }
	if (containerPtr->embedded != None) {
	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    Tk_MoveResizeWindow((Tk_Window)containerPtr->embeddedPtr, 0, 0,
		    (unsigned) Tk_Width((Tk_Window)containerPtr->parentPtr),
		    (unsigned) Tk_Height((Tk_Window)containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}








|


|








|











|
|







837
838
839
840
841
842
843
844
845
846
847
848
849
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
 *	The embedded window gets resized to match the container.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedStructureProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {

	/*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != NULL) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }
	if (containerPtr->embedded != None) {
	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */

	    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,
		    -1, -1, NULL, NULL);
	    Tk_MoveResizeWindow((Tk_Window)containerPtr->embeddedPtr, 0, 0,
		    Tk_Width((Tk_Window)containerPtr->parentPtr),
		    Tk_Height((Tk_Window)containerPtr->parentPtr));
	    Tk_DeleteErrorHandler(errHandler);
	}
    } else if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
 *	The X focus may change.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedActivateProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;

    if (containerPtr->embeddedPtr != NULL) {
	if (eventPtr->type == ActivateNotify) {
	    TkGenerateActivateEvents(containerPtr->embeddedPtr,1);
	} else if (eventPtr->type == DeactivateNotify) {
	    TkGenerateActivateEvents(containerPtr->embeddedPtr,0);
	}







|


|







891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
 *	The X focus may change.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedActivateProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;

    if (containerPtr->embeddedPtr != NULL) {
	if (eventPtr->type == ActivateNotify) {
	    TkGenerateActivateEvents(containerPtr->embeddedPtr,1);
	} else if (eventPtr->type == DeactivateNotify) {
	    TkGenerateActivateEvents(containerPtr->embeddedPtr,0);
	}
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
 *	The X focus may change.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedFocusProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Display *display;
    XEvent event;

    if (containerPtr->embeddedPtr != NULL) {
	display = Tk_Display(containerPtr->parentPtr);
	event.xfocus.serial = LastKnownRequestProcessed(display);
	event.xfocus.send_event = false;







|


|







926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
 *	The X focus may change.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedFocusProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Display *display;
    XEvent event;

    if (containerPtr->embeddedPtr != NULL) {
	display = Tk_Display(containerPtr->parentPtr);
	event.xfocus.serial = LastKnownRequestProcessed(display);
	event.xfocus.send_event = false;
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedSendConfigure(
    Container *containerPtr)	/* Information about the embedding. */
{
    (void)containerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
 *







|

<







1037
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedSendConfigure(
    TCL_UNUSED(Container *))	/* Information about the embedding. */
{

}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
 *
1078
1079
1080
1081
1082
1083
1084



1085
1086
1087
1088
1089
1090
1091
     * Find the Container structure for this window. Delete the information
     * about the embedded application and free the container's record.
     */

    prevPtr = NULL;
    containerPtr = firstContainerPtr;
    while (1) {



	if (containerPtr->embeddedPtr == winPtr) {
	    /*
	     * We also have to destroy our parent, to clean up the container.
	     * Fabricate an event to do this.
	     */

	    if (containerPtr->parentPtr != NULL &&







>
>
>







1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
     * Find the Container structure for this window. Delete the information
     * about the embedded application and free the container's record.
     */

    prevPtr = NULL;
    containerPtr = firstContainerPtr;
    while (1) {
	if (containerPtr == NULL) {
	    return;
	}
	if (containerPtr->embeddedPtr == winPtr) {
	    /*
	     * We also have to destroy our parent, to clean up the container.
	     * Fabricate an event to do this.
	     */

	    if (containerPtr->parentPtr != NULL &&
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
 *	Creates the platform-specific part of a busy window structure.
 *
 *----------------------------------------------------------------------
 */

void
TkpShowBusyWindow(
    TkBusy busy)
{
    (void)busy;
}

void
TkpHideBusyWindow(
    TkBusy busy)
{
    (void)busy;
}

void
TkpMakeTransparentWindowExist(
    Tk_Window tkwin,		/* Token for window. */
    Window parent)		/* Parent window. */
{
    (void)tkwin;
    (void)parent;
}

void
TkpCreateBusy(
    Tk_FakeWin *winPtr,
    Tk_Window tkRef,
    Window* parentPtr,
    Tk_Window tkParent,
    TkBusy busy)
{
    (void)winPtr;
    (void)tkRef;
    (void)parentPtr;
    (void)tkParent;
    (void)busy;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

<




|

<




|
|

<
<




|
|
|
|
|

<
<
<
<
<










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
 *	Creates the platform-specific part of a busy window structure.
 *
 *----------------------------------------------------------------------
 */

void
TkpShowBusyWindow(
    TCL_UNUSED(TkBusy))
{

}

void
TkpHideBusyWindow(
    TCL_UNUSED(TkBusy))
{

}

void
TkpMakeTransparentWindowExist(
    TCL_UNUSED(Tk_Window),		/* Token for window. */
    TCL_UNUSED(Window))		/* Parent window. */
{


}

void
TkpCreateBusy(
    TCL_UNUSED(Tk_FakeWin *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(Window *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(TkBusy))
{





}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXEntry.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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.
 *
 * 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"





|
|
|







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 © 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"
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    /*
     * We had to make the entry part of the window smaller so that we wouldn't
     * overdraw the spin buttons with the focus highlight. So now we have to
     * draw the highlightbackground.
     */

    bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d);
    rects[0].x = Tk_Width(tkwin) - incDecWidth - 1;
    rects[0].y = 0;
    rects[0].width = incDecWidth + 1;
    rects[0].height = Tk_Height(tkwin);
    XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);

    if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    TkMacOSXRestoreDrawingContext(&dc);







|

|
|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    /*
     * We had to make the entry part of the window smaller so that we wouldn't
     * overdraw the spin buttons with the focus highlight. So now we have to
     * draw the highlightbackground.
     */

    bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d);
    rects[0].x = (short)(Tk_Width(tkwin) - incDecWidth - 1);
    rects[0].y = 0;
    rects[0].width = (unsigned short)(incDecWidth + 1);
    rects[0].height = (unsigned short)Tk_Height(tkwin);
    XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1);

    if (!TkMacOSXSetupDrawingContext(d, NULL, &dc)) {
	return 0;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    TkMacOSXRestoreDrawingContext(&dc);

Changes to macosx/tkMacOSXEvent.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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]>
 *
 * 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"





|
|
|







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 © 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"
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
};

@implementation TKApplication(TKEvent)
/* TODO: replace by +[addLocalMonitorForEventsMatchingMask ? */
- (NSEvent *) tkProcessEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSEvent	    *processedEvent = theEvent;
    NSEventType	    type = [theEvent type];
    NSInteger	    subtype;

    switch ((NSInteger)type) {
    case NSAppKitDefined:







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
};

@implementation TKApplication(TKEvent)
/* TODO: replace by +[addLocalMonitorForEventsMatchingMask ? */
- (NSEvent *) tkProcessEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), theEvent);
#endif
    NSEvent	    *processedEvent = theEvent;
    NSEventType	    type = [theEvent type];
    NSInteger	    subtype;

    switch ((NSInteger)type) {
    case NSAppKitDefined:
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    default:
	break; /* return theEvent */
    }
    return processedEvent;
}
@end
#pragma mark -

int
XSync(
    Display *display,
    TCL_UNUSED(Bool))
{
    /*
     *  The main use of XSync is by the update command, which alternates
     *  between running an event loop to process all events without waiting and
     *  calling XSync on all displays until no events are left.  There is
     *  nothing for the mac to do with respect to syncing its one display but
     *  it can (and, during regression testing, frequently does) happen that
     *  timer events fire during the event loop. Processing those here seems
     *  to make the update command work in a way that is more consistent with



     *  its behavior on other platforms.
     */

    while (Tcl_DoOneEvent(TCL_TIMER_EVENTS|TCL_DONT_WAIT)){}
    display->request++;
    return 0;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







>








|
|
|
|
|
>
>
>
|


<
|











101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
    default:
	break; /* return theEvent */
    }
    return processedEvent;
}
@end
#pragma mark -

int
XSync(
    Display *display,
    TCL_UNUSED(Bool))
{
    /*
     *  The main use of XSync is by the update command, which alternates
     *  between running an event loop to process all events without waiting and
     *  calling XSync on all displays until no events are left.  On X11 the
     *  call to XSync might cause the window manager to generate more events
     *  which would then get processed. Apparently this process stabilizes on
     *  X11, leaving the window manager in a state where all events have been
     *  generated and no additional events can be genereated by updating widgets.
     *
     *  It is not clear what the Aqua port should do when XSync is called, but
     *  currently the best option seems to be to do nothing.  (See ticket
     *  [da5f2266df].)
     */


    LastKnownRequestProcessed(display)++;
    return 0;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Added macosx/tkMacOSXFileTypes.c.







































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
There are situations where a graphical user interface needs to know the file
type (i.e. data format) of a file.  The two main ones are when generating an
icon to represent a file, and when filtering the choice of files in a file
open or save dialog.

Early Macintosh systems used OSTypes as identifiers for file types.  An OSType
is a FourCC datatype - four bytes which can be packed into a 32 bit integer.  In
the HFS filesystem they were included in the file metadata.  The metadata also
included another OSType (the Creator Code) which identified the application
which created the file.

In OSX 10.4 the Uniform Type Identifier was introduced as an alternative way to
describe file types.  These are strings (NSStrings, actually) in a reverse DNS
format, such as "com.apple.application-bundle".  Apple provided a tool for
converting OSType codes to Uniform Type Identifiers, which they deprecated in
macOS 12.0 after introducing the UTType class in macOS 11.0.  An instance of the
UTType class has properties which give the Uniform Type Identifier as well as
the preferred file name extension for a given file type.

This module provides tools for working with file types which are meant to abstract
the many variants that Apple has used over the years, and which can be used
without generating deprecation warnings.
*/

#include "tkMacOSXPrivate.h"

#define CHARS_TO_OSTYPE(string) (OSType) string[0] << 24 | \
                                (OSType) string[1] << 16 | \
                                (OSType) string[2] <<  8 | \
                                (OSType) string[3]

MODULE_SCOPE NSString *TkMacOSXOSTypeToUTI(OSType ostype) {
    char string[5];
    string[4] = '\0';
    string[3] = ostype;
    string[2] = ostype >> 8;
    string[1] = ostype >> 16;
    string[0] = ostype >> 24;
    NSString *tag = [NSString stringWithCString:string encoding:NSMacOSRomanStringEncoding];
    if (tag == nil) {
	return nil;
    }
    NSString *result = nil;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
    if (@available(macOS 11.0, *)) {
	return [UTType typeWithTag:tag tagClass:@"com.apple.ostype" conformingToType:nil].identifier;
    }
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
    result = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, (CFStringRef)tag, NULL);
#endif
    return result;
}

/*
 * The NSWorkspace method iconForFileType, which was deprecated in macOS 12.0, would
 * accept an NSString which could be an encoding of an OSType, or a file extension,
 * or a Uniform Type Idenfier.  This function can serve as a replacement.
 */
MODULE_SCOPE NSImage *TkMacOSXIconForFileType(NSString *filetype) {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 110000
// We don't have UTType but iconForFileType is not deprecated, so use it.
    return [[NSWorkspace sharedWorkspace] iconForFileType:filetype];
#else
// We might have UTType but iconForFileType might be deprecated.
    if (@available(macOS 11.0, *)) {
	/* Yes, we do have UTType */
	if (filetype == nil) {
	    /*
	     * Bug 9be830f61b: match the behavior of
	     * [NSWorkspace.sharedWorkspace iconForFileType:nil]
	     */
	     filetype = @"public.data";
	}
	UTType *uttype = [UTType typeWithIdentifier: filetype];
	if (uttype == nil || !uttype.isDeclared) {
	    uttype = [UTType typeWithFilenameExtension: filetype];
	}
	if (uttype == nil || (!uttype.isDeclared && filetype.length == 4)) {
	    OSType ostype = CHARS_TO_OSTYPE(filetype.UTF8String);
	    NSString *UTI = TkMacOSXOSTypeToUTI(ostype);
	    if (UTI) {
		uttype = [UTType typeWithIdentifier:UTI];
	    }
	}
	if (uttype == nil || !uttype.isDeclared) {
	    return nil;
	}
	return [[NSWorkspace sharedWorkspace] iconForContentType:uttype];
    } else {
	/* No, we don't have UTType. */
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
	/* but iconForFileType is not deprecated, so we can use it. */
    return [[NSWorkspace sharedWorkspace] iconForFileType:filetype];
 #else
    /*
     * Cannot be reached: MIN_REQUIRED >= 110000 yet 11.0 is not available.
     * But the compiler can't figure that out, so it will warn about an
     * execution path with no return value unless we put a return here.
     */
    return nil;
 #endif
    }
#endif
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXFont.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28




















29
30
31
32
33
34
35
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXConstants.h"

#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation
#define fixedPitch kCTFontUserFixedPitchFontType

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/





















/*
 * The following structure represents our Macintosh-specific implementation
 * of a font object.
 */

typedef struct {
    TkFont font;		/* Stuff used by generic font package. Must be






|
|
|



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*
 * tkMacOSXFont.c --
 *
 *	Contains the Macintosh implementation of the platform-independent font
 *	package interface.
 *
 * 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"
#include "tkMacOSXConstants.h"

#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation
#define fixedPitch kCTFontUserFixedPitchFontType

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/

/*
 * TclNumUtfChars() is the same as Tcl_NumUtfChars(), but counting
 * in UTF-16 in stead of UTF-32. For Tcl 8.7 it's a little bit
 * tricky to get this function, because we are compiling with
 * TCL_UTF_MAX=4. Same for TclUtfAtIndex()
 */
#if TCL_MAJOR_VERSION < 9
#   undef TclNumUtfChars
#   undef TclUtfAtIndex
#   ifdef USE_TCL_STUBS
#	define TclNumUtfChars \
	    (tclStubsPtr->tcl_NumUtfChars) /* 312 */
#	define TclUtfAtIndex \
	    (tclStubsPtr->tcl_UtfAtIndex) /* 325 */
#   else
#	define TclNumUtfChars Tcl_NumUtfChars
#	define TclUtfAtIndex Tcl_UtfAtIndex
#   endif
#endif

/*
 * The following structure represents our Macintosh-specific implementation
 * of a font object.
 */

typedef struct {
    TkFont font;		/* Stuff used by generic font package. Must be
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 */

#define SYSTEMFONT_NAME		"system"
#define APPLFONT_NAME		"application"
#define MENUITEMFONT_NAME	"menu"

struct SystemFontMapEntry {
    const ThemeFontID id;
    const char *systemName;
    const char *tkName;
    const char *tkName1;
};

#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
static const struct SystemFontMapEntry systemFontMap[] = {







|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 */

#define SYSTEMFONT_NAME		"system"
#define APPLFONT_NAME		"application"
#define MENUITEMFONT_NAME	"menu"

struct SystemFontMapEntry {
    ThemeFontID id;
    const char *systemName;
    const char *tkName;
    const char *tkName1;
};

#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
static const struct SystemFontMapEntry systemFontMap[] = {
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    ThemeFont(PushButton, NULL, NULL),
    ThemeFont(UtilityWindowTitle, NULL, NULL),
    ThemeFont(AlertHeader, NULL, NULL),
    ThemeFont(Toolbar, NULL, NULL),
    ThemeFont(MiniSystem, NULL, NULL),
    { kThemeSystemFontDetail,		"systemDetailSystemFont", NULL, NULL },
    { kThemeSystemFontDetailEmphasized,	"systemDetailEmphasizedSystemFont", NULL, NULL },
    { -1, NULL, NULL, NULL }
};
#undef ThemeFont

static int antialiasedTextEnabled = -1;
static NSCharacterSet *whitespaceCharacterSet = nil;
static NSCharacterSet *lineendingCharacterSet = nil;








|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    ThemeFont(PushButton, NULL, NULL),
    ThemeFont(UtilityWindowTitle, NULL, NULL),
    ThemeFont(AlertHeader, NULL, NULL),
    ThemeFont(Toolbar, NULL, NULL),
    ThemeFont(MiniSystem, NULL, NULL),
    { kThemeSystemFontDetail,		"systemDetailSystemFont", NULL, NULL },
    { kThemeSystemFontDetailEmphasized,	"systemDetailEmphasizedSystemFont", NULL, NULL },
    { (ThemeFontID)-1, NULL, NULL, NULL }
};
#undef ThemeFont

static int antialiasedTextEnabled = -1;
static NSCharacterSet *whitespaceCharacterSet = nil;
static NSCharacterSet *lineendingCharacterSet = nil;

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

- (instancetype)initWithTclUtfBytes:(const void *)bytes
		       length:(NSUInteger)len
{
    self = [self init];
    if (self) {
	Tcl_DStringInit(&_ds);
	Tcl_UtfToChar16DString(bytes, len, &_ds);
	_string = [[NSString alloc]
	     initWithCharactersNoCopy:(unichar *)Tcl_DStringValue(&_ds)
			       length:Tcl_DStringLength(&_ds)>>1
			 freeWhenDone:NO];
	self.UTF8String = _string.UTF8String;
    }
    return self;
}

- (instancetype)initWithString:(NSString *)aString
{
    self = [self init];
    if (self) {
	_string = [[NSString alloc] initWithString:aString];
	self.UTF8String = _string.UTF8String;
    }
    return self;
}

- (void)dealloc
{
    Tcl_DStringFree(&_ds);







|














|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

- (instancetype)initWithTclUtfBytes:(const void *)bytes
		       length:(NSUInteger)len
{
    self = [self init];
    if (self) {
	Tcl_DStringInit(&_ds);
	Tcl_UtfToChar16DString((const char *)bytes, len, &_ds);
	_string = [[NSString alloc]
	     initWithCharactersNoCopy:(unichar *)Tcl_DStringValue(&_ds)
			       length:Tcl_DStringLength(&_ds)>>1
			 freeWhenDone:NO];
	self.UTF8String = _string.UTF8String;
    }
    return self;
}

- (instancetype)initWithString:(NSString *)aString
{
    self = [self init];
    if (self) {
	_string = [[NSString alloc] initWithString:aString];
	_UTF8String = _string.UTF8String;
    }
    return self;
}

- (void)dealloc
{
    Tcl_DStringFree(&_ds);
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
}

- (unichar)characterAtIndex:(NSUInteger)index
{
    return [_string characterAtIndex:index];
}

# ifndef __clang__
@synthesize DString = _ds;
#endif

- (Tcl_DString)DString
{
    if ( _ds.string == NULL) {

	/*
	 * The DString has not been initialized. Construct it from
	 * our string's unicode characters.
	 */
	char *p;
	NSUInteger index;

	Tcl_DStringInit(&_ds);
	Tcl_DStringSetLength(&_ds, 3 * [_string length]);
	p = Tcl_DStringValue(&_ds);
	for (index = 0; index < [_string length]; index++) {
	    p += Tcl_UniCharToUtf([_string characterAtIndex: index], p);
	}
	Tcl_DStringSetLength(&_ds, p - Tcl_DStringValue(&_ds));
    }
    return _ds;
}

#ifndef __clang__
@synthesize UTF8String = _UTF8String;
#endif

@end

#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
	((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
	((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)

/*







<
<
<
<















|

|




<

<
>







165
166
167
168
169
170
171




172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194

195
196
197
198
199
200
201
202
}

- (unichar)characterAtIndex:(NSUInteger)index
{
    return [_string characterAtIndex:index];
}





- (Tcl_DString)DString
{
    if ( _ds.string == NULL) {

	/*
	 * The DString has not been initialized. Construct it from
	 * our string's unicode characters.
	 */
	char *p;
	NSUInteger index;

	Tcl_DStringInit(&_ds);
	Tcl_DStringSetLength(&_ds, 3 * [_string length]);
	p = Tcl_DStringValue(&_ds);
	for (index = 0; index < [_string length]; index++) {
	    p += Tcl_UniCharToUtf([_string characterAtIndex: index]|TCL_COMBINE, p);
	}
	Tcl_DStringSetLength(&_ds, (Tcl_Size)(p - Tcl_DStringValue(&_ds)));
    }
    return _ds;
}


@synthesize UTF8String = _UTF8String;

@synthesize DString = _ds;
@end

#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
	((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
	((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)

/*
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
GetTkFontAttributesForNSFont(
    NSFont *nsFont,
    TkFontAttributes *faPtr)
{
    NSFontTraitMask traits = [[NSFontManager sharedFontManager]
	    traitsOfFont:nsFont];
    faPtr->family = Tk_GetUid([[nsFont familyName] UTF8String]);

    faPtr->size = [nsFont pointSize];
    faPtr->weight = (traits & NSBoldFontMask ? TK_FW_BOLD : TK_FW_NORMAL);
    faPtr->slant = (traits & NSItalicFontMask ? TK_FS_ITALIC : TK_FS_ROMAN);

}

/*
 *---------------------------------------------------------------------------







>
|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
GetTkFontAttributesForNSFont(
    NSFont *nsFont,
    TkFontAttributes *faPtr)
{
    NSFontTraitMask traits = [[NSFontManager sharedFontManager]
	    traitsOfFont:nsFont];
    faPtr->family = Tk_GetUid([[nsFont familyName] UTF8String]);
#define FACTOR 0.75
    faPtr->size = [nsFont pointSize] * FACTOR;
    faPtr->weight = (traits & NSBoldFontMask ? TK_FW_BOLD : TK_FW_NORMAL);
    faPtr->slant = (traits & NSItalicFontMask ? TK_FS_ITALIC : TK_FS_ROMAN);

}

/*
 *---------------------------------------------------------------------------
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
{
    NSFontManager *fm = [NSFontManager sharedFontManager];
    NSFont *nsFont, *dflt = nil;
    #define defaultFont (dflt ? dflt : (dflt = [NSFont systemFontOfSize:0]))
    NSString *family;

    if (familyName) {
	family = [[[NSString alloc] initWithUTF8String:familyName] autorelease];
    } else {
	family = [defaultFont familyName];
    }
    if (size == 0.0) {
	size = [defaultFont pointSize];
    }
    nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];

    /*
     * A second bug in NSFontManager that Apple created for the Catalina OS
     * causes requests as above to sometimes return fonts with additional
     * traits that were not requested, even though fonts without those unwanted







|




|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
{
    NSFontManager *fm = [NSFontManager sharedFontManager];
    NSFont *nsFont, *dflt = nil;
    #define defaultFont (dflt ? dflt : (dflt = [NSFont systemFontOfSize:0]))
    NSString *family;

    if (familyName) {
	family = [[[TKNSString alloc] initWithTclUtfBytes:familyName length:TCL_INDEX_NONE] autorelease];
    } else {
	family = [defaultFont familyName];
    }
    if (size == 0.0) {
	size = [defaultFont pointSize] * FACTOR;
    }
    nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];

    /*
     * A second bug in NSFontManager that Apple created for the Catalina OS
     * causes requests as above to sometimes return fonts with additional
     * traits that were not requested, even though fonts without those unwanted
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
	renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
		NSFontIntegerAdvancementsRenderingMode :
		NSFontAntialiasedRenderingMode;
    }
    nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
    GetTkFontAttributesForNSFont(nsFont, faPtr);
    fmPtr = &fontPtr->font.fm;
    fmPtr->ascent = floor([nsFont ascender] + [nsFont leading] + 0.5);
    fmPtr->descent = floor(-[nsFont descender] + 0.5);
    fmPtr->maxWidth = [nsFont maximumAdvancement].width;
    fmPtr->fixed = [nsFont isFixedPitch];   /* Does not work for all fonts */

    /*
     * The ascent, descent and fixed fields are not correct for all fonts, as
     * a workaround deduce that info from the metrics of some typical glyphs,
     * along with screenfont kerning (space advance difference to printer font)
     */

    bounds = [nsFont boundingRectForFont];
    if (CTFontGetGlyphsForCharacters((CTFontRef) nsFont, ch, glyphs, nCh)) {
	fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
		[nsFont advancementForGlyph:glyphs[1]].width;
	bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
		nsFont, defaultOrientation, ch, boundingRects, nCh));
	kern = [nsFont advancementForGlyph:glyphs[2]].width -
		[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
    }
    descent = floor(-bounds.origin.y + 0.5);
    ascent = floor(bounds.size.height + bounds.origin.y + 0.5);
    if (ascent > fmPtr->ascent) {
	fmPtr->ascent = ascent;
    }
    if (descent > fmPtr->descent) {
	fmPtr->descent = descent;
    }
    nsAttributes = [NSDictionary dictionaryWithObjectsAndKeys:







|
|
|

















|
|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
	renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
		NSFontIntegerAdvancementsRenderingMode :
		NSFontAntialiasedRenderingMode;
    }
    nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
    GetTkFontAttributesForNSFont(nsFont, faPtr);
    fmPtr = &fontPtr->font.fm;
    fmPtr->ascent = (int)floor([nsFont ascender] + [nsFont leading] + 0.5);
    fmPtr->descent = (int)floor(-[nsFont descender] + 0.5);
    fmPtr->maxWidth = (int)[nsFont maximumAdvancement].width;
    fmPtr->fixed = [nsFont isFixedPitch];   /* Does not work for all fonts */

    /*
     * The ascent, descent and fixed fields are not correct for all fonts, as
     * a workaround deduce that info from the metrics of some typical glyphs,
     * along with screenfont kerning (space advance difference to printer font)
     */

    bounds = [nsFont boundingRectForFont];
    if (CTFontGetGlyphsForCharacters((CTFontRef) nsFont, ch, glyphs, nCh)) {
	fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
		[nsFont advancementForGlyph:glyphs[1]].width;
	bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
		nsFont, defaultOrientation, ch, boundingRects, nCh));
	kern = [nsFont advancementForGlyph:glyphs[2]].width -
		[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
    }
    descent = (int)floor(-bounds.origin.y + 0.5);
    ascent = (int)floor(bounds.size.height + bounds.origin.y + 0.5);
    if (ascent > fmPtr->ascent) {
	fmPtr->ascent = ascent;
    }
    if (descent > fmPtr->descent) {
	fmPtr->descent = descent;
    }
    nsAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
419
420
421
422
423
424
425












































































































































426
427
428
429
430
431
432
    Tk_Window tkwin,
    const char* name,
    TkFontAttributes *faPtr)
{
    TkDeleteNamedFont(NULL, tkwin, name);
    return TkCreateNamedFont(interp, tkwin, name, faPtr);
}













































































































































#pragma mark -
#pragma mark Font handling:

/*
 *-------------------------------------------------------------------------
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
    Tk_Window tkwin,
    const char* name,
    TkFontAttributes *faPtr)
{
    TkDeleteNamedFont(NULL, tkwin, name);
    return TkCreateNamedFont(interp, tkwin, name, faPtr);
}

#pragma mark -

#pragma mark Grapheme Cluster indexing

/*
 *----------------------------------------------------------------------
 *
 * startOfClusterObjCmd --
 *
 *      This function is invoked to process the startOfCluster command.
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      None
 *
 *----------------------------------------------------------------------
 */

#if defined(USE_TCL_STUBS)
#   undef Tcl_GetCharLength
#   define Tcl_GetCharLength (((&tclStubsPtr->tcl_PkgProvideEx)[631]) ? \
		((Tcl_Size (*)(Tcl_Obj *))(void *)((&tclStubsPtr->tcl_PkgProvideEx)[670])) \
		: ((Tcl_Size (*)(Tcl_Obj *))(void *)((&tclStubsPtr->tcl_PkgProvideEx)[380])))
#endif

static int
startOfClusterObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,         /* Current interpreter. */
    int objc,                   /* Number of arguments. */
    Tcl_Obj *const objv[])      /* Argument objects. */
{
    TKNSString *S;
    const char *stringArg;
    Tcl_Size len, idx;
    if ((unsigned)(objc - 3) > 1) {
	Tcl_WrongNumArgs(interp, 1 , objv, "str start ?locale?");
	return TCL_ERROR;
    }
    stringArg = Tcl_GetStringFromObj(objv[1], &len);
    if (stringArg == NULL) {
	return TCL_ERROR;
    }
    Tcl_Size ulen = Tcl_GetCharLength(objv[1]);
    S = [[TKNSString alloc] initWithTclUtfBytes:stringArg length:len];
    len = [S length];
    if (TkGetIntForIndex(objv[2], ulen - 1, 0, &idx) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad index \"%s\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"",
		Tcl_GetString(objv[2])));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (idx > 0 && len != ulen) {
	/* The string contains codepoints > \uFFFF. Determine UTF-16 index */
	Tcl_Size newIdx = 0;
	for (Tcl_Size i = 0; i < idx; i++) {
	    newIdx += 1 + (((newIdx < len-1) && ([S characterAtIndex:newIdx]&0xFC00) == 0xD800) && (([S characterAtIndex:newIdx+1]&0xFC00) == 0xDC00));
	}
	idx = newIdx;
    }
    if (idx >= 0) {
	if (idx >= len) {
	    idx = len;
	} else {
	    NSRange range = [S rangeOfComposedCharacterSequenceAtIndex:idx];
	    idx = range.location;
	}
	if (idx > 0 && len != ulen) {
	    /* The string contains codepoints > \uFFFF. Determine UTF-32 index */
	    Tcl_Size newIdx = 1;
	    for (Tcl_Size i = 1; i < idx; i++) {
		if ((([S characterAtIndex:i-1]&0xFC00) != 0xD800) || (([S characterAtIndex:i]&0xFC00) != 0xDC00)) newIdx++;
	    }
	    idx = newIdx;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(idx));
    }
    return TCL_OK;
}

static int
endOfClusterObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,         /* Current interpreter. */
    int objc,                   /* Number of arguments. */
    Tcl_Obj *const objv[])      /* Argument objects. */
{
    TKNSString *S;
    char *stringArg;
    Tcl_Size idx, len;

    if ((unsigned)(objc - 3) > 1) {
	Tcl_WrongNumArgs(interp, 1 , objv, "str start ?locale?");
	return TCL_ERROR;
    }
    stringArg = Tcl_GetStringFromObj(objv[1], &len);
    if (stringArg == NULL) {
	return TCL_ERROR;
    }
    Tcl_Size ulen = Tcl_GetCharLength(objv[1]);
    S = [[TKNSString alloc] initWithTclUtfBytes:stringArg length:len];
    len = [S length];
    if (TkGetIntForIndex(objv[2], ulen - 1, 0, &idx) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad index \"%s\": must be integer?[+-]integer?, end?[+-]integer?, or \"\"",
		Tcl_GetString(objv[2])));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (idx > 0 && len != ulen) {
	/* The string contains codepoints > \uFFFF. Determine UTF-16 index */
	Tcl_Size newIdx = 0;
	for (Tcl_Size i = 0; i < idx; i++) {
	    newIdx += 1 + (((newIdx < len-1) && ([S characterAtIndex:newIdx]&0xFC00) == 0xD800) && (([S characterAtIndex:newIdx+1]&0xFC00) == 0xDC00));
	}
	idx = newIdx;
    }
    if (idx + 1 <= len) {
	if (idx < 0) {
	    idx = 0;
	} else {
	    NSRange range = [S rangeOfComposedCharacterSequenceAtIndex:idx];
	    idx = range.location + range.length;
	    if (idx > 0 && len != ulen) {
		/* The string contains codepoints > \uFFFF. Determine UTF-32 index */
		Tcl_Size newIdx = 1;
		for (Tcl_Size i = 1; i < idx; i++) {
		if ((([S characterAtIndex:i-1]&0xFC00) != 0xD800) || (([S characterAtIndex:i]&0xFC00) != 0xDC00)) newIdx++;
		}
		idx = newIdx;
	    }
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(idx));
    }
    return TCL_OK;
}

#pragma mark -
#pragma mark Font handling:

/*
 *-------------------------------------------------------------------------
 *
516
517
518
519
520
521
522


523
524
525
526
527
528
529
		whitespaceAndNewlineCharacterSet] retain];
	cs = [whitespaceCharacterSet mutableCopy];
	[cs removeCharactersInString:@" "];
	lineendingCharacterSet = [cs copy];
	[cs release];
    }
    [pool drain];


}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *







>
>







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
		whitespaceAndNewlineCharacterSet] retain];
	cs = [whitespaceCharacterSet mutableCopy];
	[cs removeCharactersInString:@" "];
	lineendingCharacterSet = [cs copy];
	[cs release];
    }
    [pool drain];
    Tcl_CreateObjCommand(interp, "::tk::startOfCluster", startOfClusterObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::endOfCluster", endOfClusterObjCmd, NULL, NULL);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
				 * released. If NULL, a new TkFont structure is
				 * allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    MacFont *fontPtr;
    int points = (int) (TkFontGetPoints(tkwin, faPtr->size) + 0.5);
    NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
    NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
    NSFont *nsFont;

    nsFont = FindNSFont(faPtr->family, traits, weight, points, 0);
    if (!nsFont) {
	const char *const *aliases = TkFontGetAliasList(faPtr->family);







|







771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
				 * released. If NULL, a new TkFont structure is
				 * allocated. */
    Tk_Window tkwin,		/* For display where font will be used. */
    const TkFontAttributes *faPtr)
				/* Set of attributes to match. */
{
    MacFont *fontPtr;
    CGFloat points = floor(TkFontGetPoints(tkwin, faPtr->size / FACTOR) + 0.5);
    NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr);
    NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5);
    NSFont *nsFont;

    nsFont = FindNSFont(faPtr->family, traits, weight, points, 0);
    if (!nsFont) {
	const char *const *aliases = TkFontGetAliasList(faPtr->family);
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
    }
    if (!nsFont) {
	Tcl_Panic("Could not determine NSFont from TkFontAttributes");
    }
    if (tkFontPtr == NULL) {
	fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
    } else {
	fontPtr = (MacFont *) tkFontPtr;
	TkpDeleteFont(tkFontPtr);
    }
    CFRetain(nsFont); /* Always needed to allow unconditional CFRelease below */
    InitFont(nsFont, faPtr, fontPtr);

    return (TkFont *) fontPtr;
}







|







793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
    }
    if (!nsFont) {
	Tcl_Panic("Could not determine NSFont from TkFontAttributes");
    }
    if (tkFontPtr == NULL) {
	fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
    } else {
	fontPtr = (MacFont *)tkFontPtr;
	TkpDeleteFont(tkFontPtr);
    }
    CFRetain(nsFont); /* Always needed to allow unconditional CFRelease below */
    InitFont(nsFont, faPtr, fontPtr);

    return (TkFont *) fontPtr;
}
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
    TCL_UNUSED(Tk_Window))		/* For display to query. */
{
    Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
    NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];

    for (NSString *family in list) {
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj([family UTF8String], -1));
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *-------------------------------------------------------------------------
 *







|







860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
    TCL_UNUSED(Tk_Window))		/* For display to query. */
{
    Tcl_Obj *resultPtr = Tcl_NewListObj(0, NULL);
    NSArray *list = [[NSFontManager sharedFontManager] availableFontFamilies];

    for (NSString *family in list) {
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj([family UTF8String], TCL_INDEX_NONE));
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *-------------------------------------------------------------------------
 *
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
		objectForKey:NSFontCascadeListAttribute];

	for (NSFontDescriptor *subFontDesc in list) {
	    NSString *family = [subFontDesc objectForKey:NSFontFamilyAttribute];

	    if (family) {
		Tcl_ListObjAppendElement(NULL, resultPtr,
			Tcl_NewStringObj([family UTF8String], -1));
	    }
	}
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*







|







900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
		objectForKey:NSFontCascadeListAttribute];

	for (NSFontDescriptor *subFontDesc in list) {
	    NSString *family = [subFontDesc objectForKey:NSFontFamilyAttribute];

	    if (family) {
		Tcl_ListObjAppendElement(NULL, resultPtr,
			Tcl_NewStringObj([family UTF8String], TCL_INDEX_NONE));
	    }
	}
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes* faPtr)	/* Output: Font attributes */
{
    MacFont *fontPtr = (MacFont *) tkfont;
    NSFont *nsFont = fontPtr->nsFont;
    *faPtr = fontPtr->font.fa;
    if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
	UTF16Char ch = (UTF16Char) c;







|







928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,	 		/* Character of interest */
    TkFontAttributes* faPtr)	/* Output: Font attributes */
{
    MacFont *fontPtr = (MacFont *) tkfont;
    NSFont *nsFont = fontPtr->nsFont;
    *faPtr = fontPtr->font.fa;
    if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) {
	UTF16Char ch = (UTF16Char) c;
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:







|







980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    Tcl_Size numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char







|

|
|







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    Tcl_Size numBytes,		/* Maximum number of bytes to consider from
				 * source string in all. */
    Tcl_Size rangeStart,		/* Index of first byte to measure. */
    Tcl_Size rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
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
	fit = rangeLength;
	goto done;
    }
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:fontPtr->nsAttributes];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    start = Tcl_NumUtfChars(source, rangeStart);
    len = Tcl_NumUtfChars(source + rangeStart, rangeLength);
    if (start > 0) {
	range.length = start;
	line = CTTypesetterCreateLine(typesetter, range);
	offset = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    }
    if (maxLength < 0) {
	index = len;
	range.length = len;
	line = CTTypesetterCreateLine(typesetter, range);
	width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    } else {
	double maxWidth = maxLength + offset;
	NSCharacterSet *cs;

        /*
         * Get a line breakpoint in the source string.
         */

	index = start;
	if (flags & TK_WHOLE_WORDS) {
	    index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
	    if (index <= start && (flags & TK_AT_LEAST_ONE)) {
		flags &= ~TK_WHOLE_WORDS;
	    }
	}
	if (index <= start && !(flags & TK_WHOLE_WORDS)) {
	    index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
	}

        /*
         * Trim right whitespace/lineending characters.
         */

	cs = (index <= len && (flags & TK_WHOLE_WORDS)) ?
		whitespaceCharacterSet : lineendingCharacterSet;
	while (index > start &&
		[cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
	    index--;
	}

        /*
         * If there is no line breakpoint in the source string between its
         * start and the index position that fits in maxWidth, then
         * CTTypesetterSuggestLineBreak() returns that very last index.
         * However if the TK_WHOLE_WORDS flag is set, we want to break at a
         * word boundary. In this situation, unless TK_AT_LEAST_ONE is set, we
         * must report that zero chars actually fit (in other words the
         * smallest word of the source string is still larger than maxWidth).
         */

        if ((index >= start) && (index < len) &&
                (flags & TK_WHOLE_WORDS) && !(flags & TK_AT_LEAST_ONE) &&
                ![cs characterIsMember:[string characterAtIndex:index]]) {
            index = start;
        }

	if (index <= start && (flags & TK_AT_LEAST_ONE)) {
	    index = start + 1;
	}

        /*
         * Now measure the string width in pixels.
         */

	if (index > 0) {
	    range.length = index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	} else {
	    width = 0;
	}
	if (width < maxWidth && (flags & TK_PARTIAL_OK) && index < len) {
	    range.length = ++index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

        /*
	 * The call to CTTypesetterSuggestClusterBreak above will always return
	 * at least one character regardless of whether it exceeded it or not.
	 * Clean that up now.
	 */

	while (width > maxWidth && !(flags & TK_PARTIAL_OK)
		&& index > start+(flags & TK_AT_LEAST_ONE)) {
	    range.length = --index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

    }
    CFRelease(typesetter);
    [attributedString release];
    [string release];
    length = ceil(width - offset);
    fit = (Tcl_UtfAtIndex(source, index) - source) - rangeStart;
done:
#ifdef TK_MAC_DEBUG_FONTS
    TkMacOSXDbgMsg("measure: source=\"%s\" range=\"%.*s\" maxLength=%d "
	    "flags='%s%s%s%s' -> width=%d bytesFit=%d\n", source, rangeLength,
	    source+rangeStart, maxLength,
	    flags & TK_PARTIAL_OK   ? "partialOk "  : "",
	    flags & TK_WHOLE_WORDS  ? "wholeWords " : "",







|
|
















|
|
|












|
|
|








|
|
|
|
|
|
|
|
|

|
|
|
|
|





|
|
|
















|


















|







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
	fit = rangeLength;
	goto done;
    }
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:fontPtr->nsAttributes];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    start = TclNumUtfChars(source, rangeStart);
    len = TclNumUtfChars(source + rangeStart, rangeLength);
    if (start > 0) {
	range.length = start;
	line = CTTypesetterCreateLine(typesetter, range);
	offset = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    }
    if (maxLength < 0) {
	index = len;
	range.length = len;
	line = CTTypesetterCreateLine(typesetter, range);
	width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    } else {
	double maxWidth = maxLength + offset;
	NSCharacterSet *cs;

	/*
	 * Get a line breakpoint in the source string.
	 */

	index = start;
	if (flags & TK_WHOLE_WORDS) {
	    index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
	    if (index <= start && (flags & TK_AT_LEAST_ONE)) {
		flags &= ~TK_WHOLE_WORDS;
	    }
	}
	if (index <= start && !(flags & TK_WHOLE_WORDS)) {
	    index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
	}

	/*
	 * Trim right whitespace/lineending characters.
	 */

	cs = (index <= len && (flags & TK_WHOLE_WORDS)) ?
		whitespaceCharacterSet : lineendingCharacterSet;
	while (index > start &&
		[cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
	    index--;
	}

	/*
	 * If there is no line breakpoint in the source string between its
	 * start and the index position that fits in maxWidth, then
	 * CTTypesetterSuggestLineBreak() returns that very last index.
	 * However if the TK_WHOLE_WORDS flag is set, we want to break at a
	 * word boundary. In this situation, unless TK_AT_LEAST_ONE is set, we
	 * must report that zero chars actually fit (in other words the
	 * smallest word of the source string is still larger than maxWidth).
	 */

	if ((index >= start) && (index < len) &&
		(flags & TK_WHOLE_WORDS) && !(flags & TK_AT_LEAST_ONE) &&
		![cs characterIsMember:[string characterAtIndex:index]]) {
	    index = start;
	}

	if (index <= start && (flags & TK_AT_LEAST_ONE)) {
	    index = start + 1;
	}

	/*
	 * Now measure the string width in pixels.
	 */

	if (index > 0) {
	    range.length = index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	} else {
	    width = 0;
	}
	if (width < maxWidth && (flags & TK_PARTIAL_OK) && index < len) {
	    range.length = ++index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

	/*
	 * The call to CTTypesetterSuggestClusterBreak above will always return
	 * at least one character regardless of whether it exceeded it or not.
	 * Clean that up now.
	 */

	while (width > maxWidth && !(flags & TK_PARTIAL_OK)
		&& index > start+(flags & TK_AT_LEAST_ONE)) {
	    range.length = --index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	}

    }
    CFRelease(typesetter);
    [attributedString release];
    [string release];
    length = ceil(width - offset);
    fit = (TclUtfAtIndex(source, index) - source) - rangeStart;
done:
#ifdef TK_MAC_DEBUG_FONTS
    TkMacOSXDbgMsg("measure: source=\"%s\" range=\"%.*s\" maxLength=%d "
	    "flags='%s%s%s%s' -> width=%d bytesFit=%d\n", source, rangeLength,
	    source+rangeStart, maxLength,
	    flags & TK_PARTIAL_OK   ? "partialOk "  : "",
	    flags & TK_WHOLE_WORDS  ? "wholeWords " : "",
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * string when drawing. */
{
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, 0.0);
}








|







1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * string when drawing. */
{
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, 0.0);
}

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, angle);
}







|







1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    0, numBytes, x, y, angle);
}
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
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    (void)display;
    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    rangeStart, rangeLength, x, y, 0.0);
}

void
TkpDrawAngledCharsInContext(
    TCL_UNUSED(Display *),		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const MacFont *fontPtr = (const MacFont *) tkfont;
    NSString *string;
    NSMutableDictionary *attributes;
    NSAttributedString *attributedString;
    CTTypesetterRef typesetter;
    CFIndex start, length;
    CTLineRef line, full=nil;
    MacDrawable *macWin = (MacDrawable *)drawable;
    TkMacOSXDrawingContext drawingContext;
    CGContextRef context;
    CGColorRef fg;
    NSFont *nsFont;
    CGAffineTransform t;
    CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y;

    if (rangeStart < 0 || rangeLength <= 0  ||
	rangeStart + rangeLength > numBytes ||
	!TkMacOSXSetupDrawingContext(drawable, gc, &drawingContext)) {
	return;
    }
    string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes];
    if (!string) {
	return;
    }

    context = drawingContext.context;
    fg = TkMacOSXCreateCGColor(gc, gc->foreground);
    attributes = [fontPtr->nsAttributes mutableCopy];

    [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
    CFRelease(fg);

    nsFont = [attributes objectForKey:NSFontAttributeName];
    [nsFont setInContext:GET_NSCONTEXT(context, NO)];
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:attributes];

    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    textX += (CGFloat) macWin->xOff;
    textY += (CGFloat) macWin->yOff;
    height = drawingContext.portBounds.size.height;
    textY = height - textY;
    t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height);
    if (angle != 0.0) {
	t = CGAffineTransformTranslate(
             CGAffineTransformRotate(
                 CGAffineTransformTranslate(t, textX, textY), angle*PI/180.0),
             -textX, -textY);
    }
    CGContextConcatCTM(context, t);
    start = Tcl_NumUtfChars(source, rangeStart);
    length = Tcl_NumUtfChars(source, rangeStart + rangeLength) - start;
    line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, length));
    if (start > 0) {

	/*
	 * We are only drawing part of the string.  To compute the x coordinate
	 * of the part we are drawing we subtract its typographical length from
	 * the typographical length of the full string.  This accounts for the
	 * kerning after the initial part of the string.
	 */

	full = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start + length));
	width = CTLineGetTypographicBounds(full, NULL, NULL, NULL);
	CFRelease(full);
	textX += (width - CTLineGetTypographicBounds(line, NULL, NULL, NULL));
    }
    CGContextSetTextPosition(context, textX, textY);
    CTLineDraw(line, context);
    CFRelease(line);
    CFRelease(typesetter);
    [attributedString release];
    [string release];
    [attributes release];
    TkMacOSXRestoreDrawingContext(&drawingContext);
}

#pragma mark -
#pragma mark Accessors:








|
|
|




<


















|
|
|















|




|
|
|








|

>
|
|
>





>




|




|
|
|


|
|




















<







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
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size 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. */
{

    TkpDrawAngledCharsInContext(display, drawable, gc, tkfont, source, numBytes,
	    rangeStart, rangeLength, x, y, 0.0);
}

void
TkpDrawAngledCharsInContext(
    TCL_UNUSED(Display *),		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size rangeLength,		/* Length of range to draw in bytes. */
    double x, double y,		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const MacFont *fontPtr = (const MacFont *) tkfont;
    NSString *string;
    NSMutableDictionary *attributes;
    NSAttributedString *attributedString;
    CTTypesetterRef typesetter;
    CFIndex start, length;
    CTLineRef line, full=nil;
    MacDrawable *macWin = (MacDrawable *)drawable;
    TkMacOSXDrawingContext drawingContext;
    CGContextRef context;
    CGColorRef fg = NULL;
    NSFont *nsFont;
    CGAffineTransform t;
    CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y;

    if (rangeStart < 0 || rangeLength <= 0
	    || rangeStart + rangeLength > numBytes
	    || !TkMacOSXSetupDrawingContext(drawable, gc, &drawingContext)) {
	return;
    }
    string = [[TKNSString alloc] initWithTclUtfBytes:source length:numBytes];
    if (!string) {
	return;
    }

    context = drawingContext.context;
    TkSetMacColor(gc->foreground, &fg);
    attributes = [fontPtr->nsAttributes mutableCopy];
    if (fg) {
	[attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
	CGColorRelease(fg);
    }
    nsFont = [attributes objectForKey:NSFontAttributeName];
    [nsFont setInContext:GET_NSCONTEXT(context, NO)];
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:attributes];
    [string release];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    textX += (CGFloat) macWin->xOff;
    textY += (CGFloat) macWin->yOff;
    height = [drawingContext.view bounds].size.height;
    textY = height - textY;
    t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height);
    if (angle != 0.0) {
	t = CGAffineTransformTranslate(
	     CGAffineTransformRotate(
		 CGAffineTransformTranslate(t, textX, textY), angle*PI/180.0),
	     -textX, -textY);
    }
    CGContextConcatCTM(context, t);
    start = TclNumUtfChars(source, rangeStart);
    length = TclNumUtfChars(source, rangeStart + rangeLength) - start;
    line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, length));
    if (start > 0) {

	/*
	 * We are only drawing part of the string.  To compute the x coordinate
	 * of the part we are drawing we subtract its typographical length from
	 * the typographical length of the full string.  This accounts for the
	 * kerning after the initial part of the string.
	 */

	full = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start + length));
	width = CTLineGetTypographicBounds(full, NULL, NULL, NULL);
	CFRelease(full);
	textX += (width - CTLineGetTypographicBounds(line, NULL, NULL, NULL));
    }
    CGContextSetTextPosition(context, textX, textY);
    CTLineDraw(line, context);
    CFRelease(line);
    CFRelease(typesetter);
    [attributedString release];

    [attributes release];
    TkMacOSXRestoreDrawingContext(&drawingContext);
}

#pragma mark -
#pragma mark Accessors:

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

MODULE_SCOPE NSDictionary*
TkMacOSXNSFontAttributesForFont(
    Tk_Font tkfont)
{
    return tkfont ? ((MacFont *)tkfont)->nsAttributes : nil;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkMacOSXIsCharacterMissing --
 *
 *	Given a tkFont and a character determine whether the character has
 *	a glyph defined in the font or not.
 *
 * Results:
 *	Returns a 1 if the character is missing, a 0 if it is not.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkMacOSXIsCharacterMissing(
    TCL_UNUSED(Tk_Font),		/* The font we are looking in. */
    TCL_UNUSED(unsigned int))	/* The character we are looking for. */
{
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFontDescriptionForNSFontAndNSFontAttributes --
 *
 *	Get text description of a font specified by NSFont and attributes.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1462
1463
1464
1465
1466
1467
1468

























1469
1470
1471
1472
1473
1474
1475

MODULE_SCOPE NSDictionary*
TkMacOSXNSFontAttributesForFont(
    Tk_Font tkfont)
{
    return tkfont ? ((MacFont *)tkfont)->nsAttributes : nil;
}


























/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFontDescriptionForNSFontAndNSFontAttributes --
 *
 *	Get text description of a font specified by NSFont and attributes.
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
	NSFontTraitMask traits = [[NSFontManager sharedFontManager]
		traitsOfFont:nsFont];
	id underline = [nsAttributes objectForKey:
		NSUnderlineStyleAttributeName];
	id strikethrough = [nsAttributes objectForKey:
		NSStrikethroughStyleAttributeName];

	objv[i++] = Tcl_NewStringObj(familyName, -1);
	objv[i++] = Tcl_NewWideIntObj([nsFont pointSize]);
#define S(s)    Tcl_NewStringObj(STRINGIFY(s), (sizeof(STRINGIFY(s))-1))
	objv[i++] = (traits & NSBoldFontMask)	? S(bold)   : S(normal);
	objv[i++] = (traits & NSItalicFontMask)	? S(italic) : S(roman);
	if ([underline respondsToSelector:@selector(intValue)] &&
		([underline intValue] & (NSUnderlineStyleSingle |
		NSUnderlineStyleThick | NSUnderlineStyleDouble))) {
	    objv[i++] = S(underline);







|
|







1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
	NSFontTraitMask traits = [[NSFontManager sharedFontManager]
		traitsOfFont:nsFont];
	id underline = [nsAttributes objectForKey:
		NSUnderlineStyleAttributeName];
	id strikethrough = [nsAttributes objectForKey:
		NSStrikethroughStyleAttributeName];

	objv[i++] = Tcl_NewStringObj(familyName, TCL_INDEX_NONE);
	objv[i++] = Tcl_NewWideIntObj((Tcl_WideInt)floor([nsFont pointSize] * FACTOR + 0.5));
#define S(s)    Tcl_NewStringObj(STRINGIFY(s), (sizeof(STRINGIFY(s))-1))
	objv[i++] = (traits & NSBoldFontMask)	? S(bold)   : S(normal);
	objv[i++] = (traits & NSItalicFontMask)	? S(italic) : S(roman);
	if ([underline respondsToSelector:@selector(intValue)] &&
		([underline intValue] & (NSUnderlineStyleSingle |
		NSUnderlineStyleThick | NSUnderlineStyleDouble))) {
	    objv[i++] = S(underline);
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
    if (!initialized) {
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext",
		(char *) &antialiasedTextEnabled,
		TCL_LINK_INT) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
    }
    antialiasedTextEnabled = enable;
    return TCL_OK;
}







|







1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
    if (!initialized) {
	initialized = TRUE;

	if (Tcl_CreateNamespace(interp, "::tk::mac", NULL, NULL) == NULL) {
	    Tcl_ResetResult(interp);
	}
	if (Tcl_LinkVar(interp, "::tk::mac::antialiasedtext",
		&antialiasedTextEnabled,
		TCL_LINK_INT) != TCL_OK) {
	    Tcl_ResetResult(interp);
	}
    }
    antialiasedTextEnabled = enable;
    return TCL_OK;
}

Changes to macosx/tkMacOSXFont.h.

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]>
 *
 * 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






|
|
|
|







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 © 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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include <sys/param.h>





|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * tkMacOSXHLEvents.c --
 *
 *	Implements high level event support for the Macintosh.
 *
 * 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>
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80

/*
 * Static functions used only in this file.
 */

static int  MissedAnyParameters(const AppleEvent *theEvent);
static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);
static void ProcessAppleEvent(ClientData clientData);

/*
 * Names of the procedures which can be used to process AppleEvents.
 */

static const char openDocumentProc[] = "::tk::mac::OpenDocument";
static const char launchURLProc[] = "::tk::mac::LaunchURL";
static const char printDocProc[] = "::tk::mac::PrintDocument";
static const char scriptFileProc[] = "::tk::mac::DoScriptFile";
static const char scriptTextProc[] = "::tk::mac::DoScriptText";


#pragma mark TKApplication(TKHLEvents)

@implementation TKApplication(TKHLEvents)
- (void) terminate: (id) sender
{
    (void)sender;
    [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}

- (void) superTerminate: (id) sender
{

    [super terminate:nil];
}

- (void) preferences: (id) sender
{
    (void)sender;
    [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];







|










>












>







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

/*
 * Static functions used only in this file.
 */

static int  MissedAnyParameters(const AppleEvent *theEvent);
static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);
static void ProcessAppleEvent(void *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 getSdefProc[] = "::tk::mac::GetDynamicSdef";

#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];
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
{
    (void)event;
    (void)replyEvent;

    if (_eventInterp &&
	Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    (void)event;
    (void)replyEvent;

    [NSApp activateIgnoringOtherApps: YES];
    if (_eventInterp && Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ReopenApplication", NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK){
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    (void)event;
    (void)replyEvent;

    if (_eventInterp &&
	    Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
			      -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event







|
















|















|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
{
    (void)event;
    (void)replyEvent;

    if (_eventInterp &&
	Tcl_FindCommand(_eventInterp, "::tk::mac::OpenApplication", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::OpenApplication",
			      TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleReopenApplicationEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    (void)event;
    (void)replyEvent;

    [NSApp activateIgnoringOtherApps: YES];
    if (_eventInterp && Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ReopenApplication", NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ReopenApplication",
			      TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	if (code != TCL_OK){
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleShowPreferencesEvent: (NSAppleEventDescriptor *)event
    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    (void)event;
    (void)replyEvent;

    if (_eventInterp &&
	    Tcl_FindCommand(_eventInterp, "::tk::mac::ShowPreferences", NULL, 0)){
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowPreferences",
			      TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
    }
}

- (void) handleOpenDocumentsEvent: (NSAppleEventDescriptor *)event
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
     * Construct a Tcl expression which calls the ::tk::mac::OpenDocument
     * procedure, passing the paths contained in the AppleEvent as arguments.
     */

    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *openCommand = &AEInfo->command;
    Tcl_DStringInit(openCommand);
    Tcl_DStringAppend(openCommand, openDocumentProc, -1);
    utf8 = Tcl_GetEncoding(NULL, "utf-8");

    for (index = 1; index <= count; index++) {
	if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
				 &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
	    continue;
	}
	if (type != typeFileURL) {
	    continue;
	}
	URLString[actual] = '\0';
	fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]];
	if (fileURL == nil) {
	    continue;
	}
	Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);

	Tcl_DStringAppendElement(openCommand, Tcl_DStringValue(&pathName));
	Tcl_DStringFree(&pathName);
    }

    Tcl_FreeEncoding(utf8);
    AEDisposeDesc(&contents);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = openDocumentProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;

    if (Tcl_FindCommand(_eventInterp, "::tk::mac::OpenDocuments", NULL, 0)){
	ProcessAppleEvent((ClientData)AEInfo);
    } else {
	Tcl_CreateTimerHandler(500, ProcessAppleEvent, (ClientData)AEInfo);
    }
}

- (void) handlePrintDocumentsEvent: (NSAppleEventDescriptor *)event
		    withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    NSString* file = [[event paramDescriptorForKeyword:keyDirectObject]
			 stringValue];
    const char *printFile = [file UTF8String];
    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *printCommand = &AEInfo->command;
    (void)replyEvent;

    Tcl_DStringInit(printCommand);
    Tcl_DStringAppend(printCommand, printDocProc, -1);
    Tcl_DStringAppendElement(printCommand, printFile);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = printDocProc;
    AEInfo->replyEvent = nil;
    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
    AEInfo->retryCount = 0;
    ProcessAppleEvent((ClientData)AEInfo);
}

- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
	      withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    OSStatus err;
    const AEDesc *theDesc = nil;







|















|
>









<

<

|

|














|




<

|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
     * Construct a Tcl expression which calls the ::tk::mac::OpenDocument
     * procedure, passing the paths contained in the AppleEvent as arguments.
     */

    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *openCommand = &AEInfo->command;
    Tcl_DStringInit(openCommand);
    Tcl_DStringAppend(openCommand, openDocumentProc, TCL_INDEX_NONE);
    utf8 = Tcl_GetEncoding(NULL, "utf-8");

    for (index = 1; index <= count; index++) {
	if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
				 &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
	    continue;
	}
	if (type != typeFileURL) {
	    continue;
	}
	URLString[actual] = '\0';
	fileURL = [NSURL URLWithString:[NSString stringWithUTF8String:(char*)URLString]];
	if (fileURL == nil) {
	    continue;
	}
	(void)Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], TCL_INDEX_NONE,
		&pathName);
	Tcl_DStringAppendElement(openCommand, Tcl_DStringValue(&pathName));
	Tcl_DStringFree(&pathName);
    }

    Tcl_FreeEncoding(utf8);
    AEDisposeDesc(&contents);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = openDocumentProc;
    AEInfo->replyEvent = nil;

    AEInfo->retryCount = 0;

    if (Tcl_FindCommand(_eventInterp, "::tk::mac::OpenDocuments", NULL, 0)){
	ProcessAppleEvent((void *)AEInfo);
    } else {
	Tcl_CreateTimerHandler(500, ProcessAppleEvent, (void *)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, TCL_INDEX_NONE);
    Tcl_DStringAppendElement(printCommand, printFile);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = printDocProc;
    AEInfo->replyEvent = nil;

    AEInfo->retryCount = 0;
    ProcessAppleEvent((void *)AEInfo);
}

- (void) handleDoScriptEvent: (NSAppleEventDescriptor *)event
	      withReplyEvent: (NSAppleEventDescriptor *)replyEvent
{
    OSStatus err;
    const AEDesc *theDesc = nil;
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
    if (theDesc == nil) {
	return;
    }

    err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
			NULL, 0, NULL);
    if (err != noErr) {
	sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar, errString, strlen(errString));
	return;
    }

    if (MissedAnyParameters((AppleEvent*)theDesc)) {
    	sprintf(errString, "AEDoScriptHandler: extra parameters");
    	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar,errString, strlen(errString));
    	return;
    }

    if (initialType == typeFileURL || initialType == typeAlias) {








|






|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
    if (theDesc == nil) {
	return;
    }

    err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
			NULL, 0, NULL);
    if (err != noErr) {
	snprintf(errString, sizeof(errString), "AEDoScriptHandler: GetParamDesc error %d", (int)err);
	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar, errString, strlen(errString));
	return;
    }

    if (MissedAnyParameters((AppleEvent*)theDesc)) {
    	snprintf(errString, sizeof(errString), "AEDoScriptHandler: extra parameters");
    	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar,errString, strlen(errString));
    	return;
    }

    if (initialType == typeFileURL || initialType == typeAlias) {

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

383













384
385

386
387
388
389
390
391
392
            if (actual > 0) {
                URLBuffer[actual] = '\0';
                NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
                NSURL *fileURL = [NSURL URLWithString:urlString];
                AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
                Tcl_DString *scriptFileCommand = &AEInfo->command;
                Tcl_DStringInit(scriptFileCommand);
                Tcl_DStringAppend(scriptFileCommand, scriptFileProc, -1);
                Tcl_DStringAppendElement(scriptFileCommand, [[fileURL path] UTF8String]);
                AEInfo->interp = _eventInterp;
                AEInfo->procedure = scriptFileProc;
                AEInfo->replyEvent = nil;
                Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);
		AEInfo->retryCount = 0;
                ProcessAppleEvent((ClientData)AEInfo);
            }
        }
    } else if (noErr == AEGetParamPtr(theDesc, keyDirectObject, typeUTF8Text, &type,
			       NULL, 0, &actual)) {
        /*
         * The descriptor cannot be coerced to a file URL but can be coerced to
         * text.  Construct a Tcl expression which passes the text as a string
         * argument to ::tk::mac::DoScriptText.
         */

	if (actual > 0) {
	    char *data = (char *)ckalloc(actual + 1);
	    if (noErr == AEGetParamPtr(theDesc, keyDirectObject,
				       typeUTF8Text, &type,
				       data, actual, NULL)) {
		data[actual] = '\0';
		AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
		Tcl_DString *scriptTextCommand = &AEInfo->command;
		Tcl_DStringInit(scriptTextCommand);
		Tcl_DStringAppend(scriptTextCommand, scriptTextProc, -1);
		Tcl_DStringAppendElement(scriptTextCommand, data);
		AEInfo->interp = _eventInterp;
		AEInfo->procedure = scriptTextProc;
		AEInfo->retryCount = 0;
                if (Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
                    AEInfo->replyEvent = replyEvent;
                    ProcessAppleEvent(AEInfo);
                } else {
                    AEInfo->replyEvent = nil;
                    Tcl_DoWhenIdle(ProcessAppleEvent, AEInfo);
                    ProcessAppleEvent(AEInfo);
                }
	    }
	}
    }
}

- (void)handleURLEvent:(NSAppleEventDescriptor*)event
        withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]
                        stringValue];
    const char *cURL=[url UTF8String];
    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *launchCommand = &AEInfo->command;
    (void)replyEvent;

    Tcl_DStringInit(launchCommand);
    Tcl_DStringAppend(launchCommand, launchURLProc, -1);
    Tcl_DStringAppendElement(launchCommand, cURL);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = launchURLProc;
    AEInfo->replyEvent = nil;

    Tcl_DoWhenIdle(ProcessAppleEvent, (ClientData)AEInfo);













    AEInfo->retryCount = 0;
    ProcessAppleEvent((ClientData)AEInfo);

}

@end

#pragma mark -

/*







|




<

|



















|









<


















|




>
|
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>







315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
            if (actual > 0) {
                URLBuffer[actual] = '\0';
                NSString *urlString = [NSString stringWithUTF8String:(char*)URLBuffer];
                NSURL *fileURL = [NSURL URLWithString:urlString];
                AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
                Tcl_DString *scriptFileCommand = &AEInfo->command;
                Tcl_DStringInit(scriptFileCommand);
                Tcl_DStringAppend(scriptFileCommand, scriptFileProc, TCL_INDEX_NONE);
                Tcl_DStringAppendElement(scriptFileCommand, [[fileURL path] UTF8String]);
                AEInfo->interp = _eventInterp;
                AEInfo->procedure = scriptFileProc;
                AEInfo->replyEvent = nil;

		AEInfo->retryCount = 0;
                ProcessAppleEvent((void *)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, TCL_INDEX_NONE);
		Tcl_DStringAppendElement(scriptTextCommand, data);
		AEInfo->interp = _eventInterp;
		AEInfo->procedure = scriptTextProc;
		AEInfo->retryCount = 0;
                if (Tcl_FindCommand(AEInfo->interp, AEInfo->procedure, NULL, 0)) {
                    AEInfo->replyEvent = replyEvent;
                    ProcessAppleEvent(AEInfo);
                } else {
                    AEInfo->replyEvent = nil;

                    ProcessAppleEvent(AEInfo);
                }
	    }
	}
    }
}

- (void)handleURLEvent:(NSAppleEventDescriptor*)event
        withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]
                        stringValue];
    const char *cURL=[url UTF8String];
    AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *launchCommand = &AEInfo->command;
    (void)replyEvent;

    Tcl_DStringInit(launchCommand);
    Tcl_DStringAppend(launchCommand, launchURLProc, TCL_INDEX_NONE);
    Tcl_DStringAppendElement(launchCommand, cURL);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure = launchURLProc;
    AEInfo->replyEvent = nil;
    AEInfo->retryCount = 0;
    ProcessAppleEvent((void *)AEInfo);
}

- (void)handleGetSDEFEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
     AppleEventInfo *AEInfo = (AppleEventInfo *)ckalloc(sizeof(AppleEventInfo));
    Tcl_DString *sdefCommand = &AEInfo->command;
    (void)event;
    (void)replyEvent;

    Tcl_DStringInit(sdefCommand);
    Tcl_DStringAppend(sdefCommand, getSdefProc, TCL_INDEX_NONE);
    AEInfo->interp = _eventInterp;
    AEInfo->procedure =  getSdefProc;
    AEInfo->replyEvent = nil;
    AEInfo->retryCount = 0;
    ProcessAppleEvent((void *)AEInfo);

}

@end

#pragma mark -

/*
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
 *      The replyEvent may be modified to contain the result of evaluating
 *      a Tcl expression.
 *
 *----------------------------------------------------------------------
 */

static void ProcessAppleEvent(
    ClientData clientData)
{
    int code;
    AppleEventInfo *AEInfo = (AppleEventInfo*) clientData;

    if (!AEInfo->interp) {
	return;
    }







|







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
 *      The replyEvent may be modified to contain the result of evaluating
 *      a Tcl expression.
 *
 *----------------------------------------------------------------------
 */

static void ProcessAppleEvent(
    void *clientData)
{
    int code;
    AppleEventInfo *AEInfo = (AppleEventInfo*) clientData;

    if (!AEInfo->interp) {
	return;
    }
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
	}
	return;
    }
    code = Tcl_EvalEx(AEInfo->interp, Tcl_DStringValue(&AEInfo->command),
	    Tcl_DStringLength(&AEInfo->command), TCL_EVAL_GLOBAL);

    if (AEInfo->replyEvent && code >= 0) {
        int reslen;
        const char *result = Tcl_GetStringFromObj(Tcl_GetObjResult(AEInfo->interp),
                                                  &reslen);
        if (code == TCL_OK) {
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],
                          keyDirectObject, typeChar, result, reslen);
        } else {
            AEPutParamPtr((AppleEvent*)[AEInfo->replyEvent aeDesc],







|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
	}
	return;
    }
    code = Tcl_EvalEx(AEInfo->interp, Tcl_DStringValue(&AEInfo->command),
	    Tcl_DStringLength(&AEInfo->command), TCL_EVAL_GLOBAL);

    if (AEInfo->replyEvent && code >= 0) {
        Tcl_Size 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],
518
519
520
521
522
523
524









525
526
527
528
529
530
531
	    andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
	    forEventClass:kAEMiscStandards andEventID:kAEDoScript];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleURLEvent:withReplyEvent:)
	    forEventClass:kInternetEventClass andEventID:kAEGetURL];










    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDoHLEvent --







>
>
>
>
>
>
>
>
>







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
	    andSelector:@selector(handleDoScriptEvent:withReplyEvent:)
	    forEventClass:kAEMiscStandards andEventID:kAEDoScript];

	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleURLEvent:withReplyEvent:)
	    forEventClass:kInternetEventClass andEventID:kAEGetURL];

	/*
	 * We do not load our sdef dynamically but this event handler
         * is required to silence error messages from inline execution
         * of AppleScript at the Objective-C level.
	 */
	[aeManager setEventHandler:NSApp
	    andSelector:@selector(handleGetSDEFEvent:withReplyEvent:)
	    forEventClass:'ascr' andEventID:'gsdf'];

    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDoHLEvent --
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
    int quit = Tcl_FindCommand(interp, "::tk::mac::Quit", NULL, 0)!=NULL;

    if (!quit) {
	Tcl_Exit(0);
    }

    int code = Tcl_EvalEx(interp, "::tk::mac::Quit", -1, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {

	/*
	 * Should be never reached...
	 */

	Tcl_BackgroundException(interp, code);







|







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
    int quit = Tcl_FindCommand(interp, "::tk::mac::Quit", NULL, 0)!=NULL;

    if (!quit) {
	Tcl_Exit(0);
    }

    int code = Tcl_EvalEx(interp, "::tk::mac::Quit", TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    if (code != TCL_OK) {

	/*
	 * Should be never reached...
	 */

	Tcl_BackgroundException(interp, code);

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
/*
 * 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 (c) 2017-2020 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"



#include "xbytes.h"


































static CGImageRef CreateCGImageFromPixmap(Drawable pixmap);




static CGImageRef CreateCGImageFromDrawableRect( Drawable drawable,





















	   int x, int y, unsigned int width, unsigned int height);




#pragma mark XImage handling

int
_XInitImageFuncPtrs(
    TCL_UNUSED(XImage *)) /* image */
{



|
>

|
|
|
|






>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * tkMacOSXImage.c --
 *
 *	The code in this file provides an interface for XImages, and
 *      implements the nsimage image type.
 *
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009, Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright © 2017-2021 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXImage.h"
#include "tkColor.h"
#include "xbytes.h"

/* Pixel formats
 *
 * Tk uses the XImage structure defined in Xlib.h for storing images.  The
 * image data in an XImage is a 32-bit aligned array of bytes.  Interpretation
 * of that data is not specified, but the structure includes parameters which
 * provide interpretation hints so that an application can use a family of
 * different data structures.
 *
 * The possible values for the XImage format field are XYBitmap, XYPixmap and
 * ZPixmap.  The macOS port does not support the XYPixmap format.  This means
 * that bitmap images are stored as a single bit plane (XYBitmap) and that
 * color images are stored as a sequence of pixel values (ZPixmap).
 *
 * For a ZPixmap, the number of bits allocated to each pixel is specified by
 * the bits_per_pixel field of the XImage structure.  The functions in this
 * module which convert between XImage and native CGImage or NSImage structures
 * only support XImages with 32 bits per pixel.  The ImageGetPixel and PutPixel
 * implementations in this file allow 1, 4, 8, 16 or 32 bits per pixel, however.
 *
 * In tkImgPhInstance.c the layout used for pixels is determined by the values
 * of the red_mask, blue_mask and green_mask fields in the XImage structure.
 * The Aqua port always sets red_mask = 0xFF0000, green_mask = 0xFF00, and
 * blue_mask = 0xFF. This means that a 32bpp ZPixmap XImage uses ARGB32 pixels,
 * with small-endian byte order BGRA. The data array for such an XImage can be
 * passed directly to construct a CGBitmapImageRep if one specifies the
 * bitmapInfo as kCGBitmapByteOrder32Big | kCGImageAlphaLast.
 *
 * The structures below describe the bitfields in two common 32 bpp pixel
 * layouts.  Note that bit field layouts are compiler dependent. The layouts
 * shown in the comments are those produced by clang and gcc.  Also note
 * that kCGBitmapByteOrder32Big is consistently set when creating CGImages or
 * CGImageBitmapReps.
 */

/* RGBA32 0xRRGGBBAA (Byte order is RGBA on big-endian systems.)
 * This is used by NSBitmapImageRep when the bitmapFormat property is 0,
 * the default value.
 */

typedef struct RGBA32pixel_t {
    unsigned red: 8;
    unsigned green: 8;
    unsigned blue: 8;
    unsigned alpha: 8;
} RGBA32pixel;

/*
 * ARGB32 0xAARRGGBB (Byte order is ARGB on big-endian systems.)
 * This is used by Aqua Tk for XImages and by NSBitmapImageReps whose
 * bitmapFormat property is NSAlphaFirstBitmapFormat.
 */

typedef struct ARGB32pixel_t {
    unsigned blue: 8;
    unsigned green: 8;
    unsigned red: 8;
    unsigned alpha: 8;
} ARGB32pixel;

typedef union pixel32_t {
    unsigned int uint;
    RGBA32pixel rgba;
    ARGB32pixel argb;
} pixel32;

#pragma mark XImage handling

int
_XInitImageFuncPtrs(
    TCL_UNUSED(XImage *)) /* image */
{
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


80
81
82
83
84
85
86
87
88
89
90
91
92
93


94
95
96
97
98

99
100

101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120

121
122


123
124
125
126
127
128
129
130
131
132
133
134
135
 *
 *----------------------------------------------------------------------
 */

static void ReleaseData(
    void *info,
    TCL_UNUSED(const void *), /* data */
    TCL_UNUSED(size_t))       /* size */
{
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image)

{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
    char *data = NULL;
    CGDataProviderReleaseDataCallback releaseData = ReleaseData;

    if (image->bits_per_pixel == 1) {
	/*
	 * BW image
	 */

	/* Reverses the sense of the bits */
	static const CGFloat decodeWB[2] = {1, 0};
	decode = decodeWB;

	bitsPerComponent = 1;
	bitsPerPixel = 1;


	if (image->bitmap_bit_order != MSBFirst) {
	    char *srcPtr = image->data + image->xoffset;
	    char *endPtr = srcPtr + len;
	    char *destPtr = (data = (char *)ckalloc(len));

	    while (srcPtr < endPtr) {
		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
	    }
	} else {
	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	}
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);


	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height,
		    bitsPerComponent, bitsPerPixel, image->bytes_per_line,
		    provider, decode, 0);

	}
    } else if ((image->format == ZPixmap) && (image->bits_per_pixel == 32)) {

	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

	if (image->width == 0 && image->height == 0) {
	    /*
	     * CGCreateImage complains on early macOS releases.
	     */

	    return NULL;
	}

	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);
	bitmapInfo |= kCGImageAlphaLast;
	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {

	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);


	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);
	    CFRelease(provider);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }







|




|

|
>





<















>
>
|
|
|
|

|
|
|
|
|
|
<


>
>
|
<



>


>




|

<






>


<
<
<
|

>


>
>
|
<



|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184



185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
 *
 *----------------------------------------------------------------------
 */

static void ReleaseData(
    void *info,
    TCL_UNUSED(const void *), /* data */
    TCL_UNUSED(size_t))        /* size */
{
    ckfree(info);
}

static CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image,
    uint32_t bitmapInfo)
{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;

    CGDataProviderRef provider = NULL;
    char *data = NULL;
    CGDataProviderReleaseDataCallback releaseData = ReleaseData;

    if (image->bits_per_pixel == 1) {
	/*
	 * BW image
	 */

	/* Reverses the sense of the bits */
	static const CGFloat decodeWB[2] = {1, 0};
	decode = decodeWB;

	bitsPerComponent = 1;
	bitsPerPixel = 1;
	data = (char *)ckalloc(len);
	if (data) {
	    if (image->bitmap_bit_order != MSBFirst) {
		char *srcPtr = image->data + image->xoffset;
		char *endPtr = srcPtr + len;
		char *destPtr = data;

		while (srcPtr < endPtr) {
		    *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
		}
	    } else {
		memcpy(data, image->data + image->xoffset, len);
	    }

	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);
	    if (!provider) {
		ckfree(data);
	    }

	    img = CGImageMaskCreate(image->width, image->height,
		    bitsPerComponent, bitsPerPixel, image->bytes_per_line,
		    provider, decode, 0);
	    CGDataProviderRelease(provider);
	}
    } else if ((image->format == ZPixmap) && (image->bits_per_pixel == 32)) {

	/*
	 * Color image
	 */

	if (image->width == 0 && image->height == 0) {


	    /*
	     * CGCreateImage complains on early macOS releases.
	     */

	    return NULL;
	}
	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
	bitsPerComponent = 8;
	bitsPerPixel = 32;



	data = (char *)ckalloc(len);
	if (data) {
	    memcpy(data, image->data + image->xoffset, len);
	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);
	    if (!provider) {
		ckfree(data);
	    }

	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);
	    CGDataProviderRelease(provider);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
    if (image && image->data) {
	unsigned char *srcPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	switch (image->bits_per_pixel) {
	case 32: /* 8 bits per channel */

	    r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
	    g = (*((unsigned int*) srcPtr) >>  8) & 0xff;
	    b = (*((unsigned int*) srcPtr)      ) & 0xff;
	    /*if (image->byte_order == LSBFirst) {
		r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
	    } else {
		r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
	    }*/

	    break;
	case 16: /* 5 bits per channel */
	    r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
	    g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
	    b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
	    break;
	case 8: /* 2 bits per channel */







>
|
<
<
<
|
|
|
<
>







269
270
271
272
273
274
275
276
277



278
279
280

281
282
283
284
285
286
287
288
    if (image && image->data) {
	unsigned char *srcPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	switch (image->bits_per_pixel) {
	case 32: /* 8 bits per channel */
	    {
		ARGB32pixel *pixel = (ARGB32pixel *)srcPtr;



		r = pixel->red;
		g = pixel->green;
		b = pixel->blue;

	    }
	    break;
	case 16: /* 5 bits per channel */
	    r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
	    g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
	    b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
	    break;
	case 8: /* 2 bits per channel */
245
246
247
248
249
250
251
252



253
254
255
256
257
258
259
}

/*
 *----------------------------------------------------------------------
 *
 * ImagePutPixel --
 *
 *	Set a single pixel in an image.



 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *







|
>
>
>







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
}

/*
 *----------------------------------------------------------------------
 *
 * ImagePutPixel --
 *
 *	Set a single pixel in an image.  The pixel is provided as an unsigned
 *      32-bit integer.  The value of that integer is interpreted by assuming
 *      that its low-order N bits have the format specified by the XImage,
 *      where N is equal to the bits_per_pixel field of the XImage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	unsigned char *dstPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	if (image->bits_per_pixel == 32) {
	    *((unsigned int*) dstPtr) = pixel;
	} else {
	    unsigned char r = ((pixel & image->red_mask)   >> 16) & 0xff;
	    unsigned char g = ((pixel & image->green_mask) >>  8) & 0xff;
	    unsigned char b = ((pixel & image->blue_mask)       ) & 0xff;
	    switch (image->bits_per_pixel) {
	    case 16:
		*((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
			((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
		break;
	    case 8:
		*dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
			((b & 0xc0) >> 6);
		break;
	    case 4: {
		unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
			((b & 0x80) >> 7);
		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
			((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
		break;
		}
	    case 1:
		*dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
			(*dstPtr & ~(0x80 >> (x % 8)));
		break;
	    }
	}
    }
    return 0;
}







<
<
<


|
<


|
<


<
<
|
|



|







340
341
342
343
344
345
346



347
348
349

350
351
352

353
354


355
356
357
358
359
360
361
362
363
364
365
366
367
	unsigned char *dstPtr = ((unsigned char*) image->data)
		+ (y * image->bytes_per_line)
		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);

	if (image->bits_per_pixel == 32) {
	    *((unsigned int*) dstPtr) = pixel;
	} else {



	    switch (image->bits_per_pixel) {
	    case 16:
		*((unsigned short*) dstPtr) = pixel & 0xffff;

		break;
	    case 8:
		*dstPtr = pixel & 0xff;

		break;
	    case 4: {


		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (pixel & 0x0f)) :
			((*dstPtr & 0x0f) | ((pixel << 4) & 0xf0));
		break;
		}
	    case 1:
		*dstPtr = pixel ? (*dstPtr | (0x80 >> (x % 8))) :
			(*dstPtr & ~(0x80 >> (x % 8)));
		break;
	    }
	}
    }
    return 0;
}
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display* display,
    TCL_UNUSED(Visual*),  /* visual */
    unsigned int depth,
    int format,
    int offset,
    char* data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage *ximage;

    display->request++;
    ximage = ckalloc(sizeof(XImage));

    ximage->height = height;
    ximage->width = width;
    ximage->depth = depth;
    ximage->xoffset = offset;
    ximage->format = format;
    ximage->data = data;
    ximage->obdata = NULL;

    if (format == ZPixmap) {
	ximage->bits_per_pixel = 32;
	ximage->bitmap_unit = 32;
    } else {
	ximage->bits_per_pixel = 1;
	ximage->bitmap_unit = 8;
    }
    if (bitmap_pad) {
	ximage->bitmap_pad = bitmap_pad;
    } else {
	/*
	 * Use 16 byte alignment for best Quartz perfomance.
	 */

	ximage->bitmap_pad = 128;
    }
    if (bytes_per_line) {
	ximage->bytes_per_line = bytes_per_line;
    } else {







|











|
|




















|







381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display* display,
    TCL_UNUSED(Visual*), /* visual */
    unsigned int depth,
    int format,
    int offset,
    char* data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage *ximage;

    LastKnownRequestProcessed(display)++;
    ximage = (XImage *)ckalloc(sizeof(XImage));

    ximage->height = height;
    ximage->width = width;
    ximage->depth = depth;
    ximage->xoffset = offset;
    ximage->format = format;
    ximage->data = data;
    ximage->obdata = NULL;

    if (format == ZPixmap) {
	ximage->bits_per_pixel = 32;
	ximage->bitmap_unit = 32;
    } else {
	ximage->bits_per_pixel = 1;
	ximage->bitmap_unit = 8;
    }
    if (bitmap_pad) {
	ximage->bitmap_pad = bitmap_pad;
    } else {
	/*
	 * Use 16 byte alignment for best Quartz performance.
	 */

	ximage->bitmap_pad = 128;
    }
    if (bytes_per_line) {
	ximage->bytes_per_line = bytes_per_line;
    } else {
388
389
390
391
392
393
394
395
396

397
398







399
400




401
402

403
404
405
406
407
408
409



410
411

412
413
414
415
416
417
418
419
420
421
422
423
424

425



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
454

455
456
457
458































459
460
461
462
463
464
465


466
467
468


469
470
471
472
473

474
475

476
477
478
479
480
481
482
483
484

485
486

487
488
489
490

491


492
493
494
495
496
497
498

    return ximage;
}

/*
 *----------------------------------------------------------------------
 *
 * XPutImage --
 *

 *	Copies a rectangular subimage of an XImage into a drawable.  Currently
 *      this is only called by TkImgPhotoDisplay, using a Window as the







 *      drawable.
 *




 * Results:
 *	None.

 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
 *----------------------------------------------------------------------
 */




int
XPutImage(

    Display* display,		/* Display. */
    Drawable drawable,		/* Drawable to place image on. */
    GC gc,			/* GC to use. */
    XImage* image,		/* Image to place. */
    int src_x,			/* Source X & Y. */
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = (MacDrawable *)drawable;





    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);

	/*
	 * The CGContext for a pixmap is RGB only, with A = 0.
	 */

	if (!(macDraw->flags & TK_IS_PIXMAP)) {
	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
	}
	if (img) {

	    bounds = CGRectMake(0, 0, image->width, image->height);
	    srcRect = CGRectMake(src_x, src_y, width, height);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
				img, gc->foreground, gc->background,
				bounds, srcRect, dstRect);
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");

	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");

    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}
































/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromDrawableRect
 *
 *	Extract image data from a MacOSX drawable as a CGImage.


 *
 *      This is only called by XGetImage and XCopyArea.  The Tk core uses
 *      these functions on some platforms, but on macOS the core does not


 *      call them with a source drawable which is a window.  Such calls are
 *      used only for double-buffered drawing.  Since macOS defines the
 *      macro TK_NO_DOUBLE_BUFFERING, the generic code never calls XGetImage
 *      or XCopyArea on macOS.  Nonetheless, these function are in the stubs
 *      table and therefore could be used by extensions.

 *
 *      This implementation does not work correctly.  Originally it relied on

 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is what is being used here.  However, that method only works when the
 *      view has a valid CGContext, and a view is only guaranteed to have a
 *      valid context during a call to [NSView drawRect]. To further complicate
 *      matters, cacheDisplayInRect calls [NSView drawRect]. Essentially it is
 *      asking the view to draw a subrectangle of itself using a special

 *      graphics context which is linked to the BitmapImageRep. But our
 *      implementation of [NSView drawRect] does not allow recursive calls. If

 *      called recursively it returns immediately without doing any drawing.
 *      So the bottom line is that this function either returns a NULL pointer
 *      or a black image. To make it useful would require a significant amount
 *      of rewriting of the drawRect method. Perhaps the next release of OSX

 *      will include some more helpful ways of doing this.


 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given rectangle of
 *      the given drawable. This object is retained. The caller is responsible
 *      for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system







|

>
|
|
>
>
>
>
>
>
>
|

>
>
>
>

<
>







>
>
>
|
|
>









|



>

>
>
>
|





|









<









>



>


|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
>
>

|
|
>
>
|
|
|
|
|
>

|
>




|
<
|
<
|
>
|
<
>
|
|
|
<
>
|
>
>







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

601

602
603
604

605
606
607
608

609
610
611
612
613
614
615
616
617
618
619

    return ximage;
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage, XPutImage, TkpPutRGBAImage --
 *
 *	These functions, which all have the same signature, copy a rectangular
 *      subimage of an XImage into a drawable.  TkPutImage is an alias for
 *      XPutImage, which assumes that the XImage data has the structure of a
 *      32bpp ZPixmap in which the image data is an array of 32bit integers
 *      packed with 8 bit values for the Red Green and Blue channels.  The
 *      fourth byte is ignored.  The function TkpPutRGBAImage assumes that the
 *      XImage data has been extended by using the fourth byte to store an
 *      8-bit Alpha value.  (The Alpha data is assumed not to pre-multiplied).
 *      The image is then drawn into the drawable using standard Porter-Duff
 *      Source Atop Composition (kCGBlendModeSourceAtop in Apple's Core
 *      Graphics).
 *
 *      The TkpPutRGBAImage function is used by TkImgPhotoDisplay to render photo
 *      images if the compile-time variable TK_CAN_RENDER_RGBA is defined in
 *      a platform's tkXXXXPort.h header, as is the case for the macOS Aqua port.
 *
 * Results:

 *	These functions return either BadDrawable or Success.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

#define USE_ALPHA (kCGImageAlphaLast | kCGBitmapByteOrder32Big)
#define IGNORE_ALPHA (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little)

static int
TkMacOSXPutImage(
    uint32_t pixelFormat,
    Display* display,		/* Display. */
    Drawable drawable,		/* Drawable to place image on. */
    GC gc,			/* GC to use. */
    XImage* image,		/* Image to place. */
    int src_x,			/* Source X & Y. */
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* destination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = (MacDrawable *)drawable;
    int result = Success;

    if (width <= 0 || height <= 0) {
	return Success; /* Is OK. Nothing to see here, literally. */
    }
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image, pixelFormat);

	/*
	 * The CGContext for a pixmap is RGB only, with A = 0.
	 */

	if (!(macDraw->flags & TK_IS_PIXMAP)) {
	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
	}
	if (img) {

	    bounds = CGRectMake(0, 0, image->width, image->height);
	    srcRect = CGRectMake(src_x, src_y, width, height);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
				img, gc->foreground, gc->background,
				bounds, srcRect, dstRect);
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	    result = BadDrawable;
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
	result = BadDrawable;
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return result;
}

int XPutImage(
    Display* display,
    Drawable drawable,
    GC gc,
    XImage* image,
    int src_x,
    int src_y,
    int dest_x,
    int dest_y,
    unsigned int width,
    unsigned int height) {
    return TkMacOSXPutImage(IGNORE_ALPHA, display, drawable, gc, image,
			    src_x, src_y, dest_x, dest_y, width, height);
}

int TkpPutRGBAImage(
    Display* display,
    Drawable drawable,
    GC gc,
    XImage* image,
    int src_x,
    int src_y,
    int dest_x,
    int dest_y,
    unsigned int width,
    unsigned int height) {
    return TkMacOSXPutImage(USE_ALPHA, display, drawable, gc, image,
		     src_x, src_y, dest_x, dest_y, width, height);
}


/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromDrawableRect
 *
 *	Extract image data from a MacOSX drawable as a CGImage.  The drawable
 *      may be either a pixmap or a window, but there issues in the case of
 *      a window.
 *
 *      CreateCGImageFromDrawableRect is called by XGetImage and XCopyArea.
 *      The Tk core uses these two functions on some platforms in order to
 *      implement explicit double-buffered drawing -- a pixmap is copied from a
 *      window, modified using CPU-based graphics composition, and then copied
 *      back to the window.  Platforms, such as macOS, on which the system
 *      provides double-buffered drawing and GPU-based composition operations
 *      can avoid calls to XGetImage and XCopyArea from the core by defining
 *      the compile-time variable TK_NO_DOUBLE_BUFFERING.  Nonetheless, these
 *      two functions are in the stubs table and therefore could be used by
 *      extensions.
 *
 *      The implementation here does not always work correctly when the source
 *      is a window.  The original version of this function relied on
 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is being used here.  However, cacheDisplayInRect works by calling

 *      [NSView drawRect] after setting the current graphics context to be one

 *      which draws to a bitmap.  There are situations in which this can be
 *      used, e.g. when taking a screenshot of a window.  But it cannot be used
 *      as part of a normal display procedure, using the copy-modify-paste

 *      paradigm that is the basis of the explicit double-buffering.  Since the
 *      copy operation will call the same display procedure that is calling
 *      this function via XGetImage or XCopyArea, this would create an infinite
 *      recursion.

 *
 *      An alternative to the copy-modify-paste paradigm is to use GPU-based
 *      graphics composition, clipping to the specified rectangle.  That is
 *      the approach that must be followed by display procedures on macOS.
 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given rectangle of
 *      the given drawable. This object is retained. The caller is responsible
 *      for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528





















529


530


531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

548



549

550

551
552
553
554
555

556
557
558



559


560








561

562













563
564

565
566
567
568
569
570
571
    int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *)drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image = NULL, result = NULL;
    NSBitmapImageRep *bitmapRep = NULL;
    NSView *view = NULL;
    if (mac_drawable->flags & TK_IS_PIXMAP) {
	/*
	 * This MacDrawable is a bitmap, so its view is NULL.
	 */

	CGRect image_rect = CGRectMake(x, y, width, height);

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);





















	cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);


	if (cg_image) {


	    result = CGImageCreateWithImageInRect(cg_image, image_rect);
	    CGImageRelease(cg_image);
	}
    } else if (TkMacOSXGetNSViewForDrawable(mac_drawable) != NULL) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
		view_height - height - y - mac_drawable->yOff,
		width, height);

	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory

	 * and make a big mess. So, in that case, we just return NULL.



	 */



	if (view == [NSView focusView]) {
	    bitmapRep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmapRep];
	    result = [bitmapRep CGImage];
	    CFRelease(bitmapRep);

	} else {
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    result = NULL;



	}


    } else {








	TkMacOSXDbgMsg("Invalid source drawable");

    }













    return result;
}


/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromPixmap --
 *
 *	Create a CGImage from an X Pixmap.







<
<

<
<
<
<
<
<

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
|
|
|
<
|
<
<
<
|
<
<
<
<

|
|
<
>
|
>
>
>
|
>
|
>
|
<
<
|
<
>
|
<
|
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>

>

>
>
>
>
>
>
>
>
>
>
>
>
>


>







633
634
635
636
637
638
639


640






641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671

672



673




674
675
676

677
678
679
680
681
682
683
684
685
686


687

688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
    int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *)drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image = NULL, result = NULL;


    if (mac_drawable->flags & TK_IS_PIXMAP) {






	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	CGContextRetain(cg_context);
    } else {
	NSView *view = TkMacOSXGetNSViewForDrawable(mac_drawable);
	if (view == nil) {
	    TkMacOSXDbgMsg("Invalid source drawable");
	    return NULL;
	}
	NSSize size = view.frame.size;
	NSUInteger view_width = size.width, view_height = size.height;
        NSUInteger bytesPerPixel = 4,
	    bytesPerRow = bytesPerPixel * view_width,
	    bitsPerComponent = 8;
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	cg_context = CGBitmapContextCreate(NULL, view_width, view_height,
			 bitsPerComponent, bytesPerRow, colorSpace,
			 kCGImageAlphaPremultipliedLast |
			 kCGBitmapByteOrder32Big);
	CFRelease(colorSpace);
	[view.layer renderInContext:cg_context];
    }
    if (cg_context) {
	cg_image = CGBitmapContextCreateImage(cg_context);
	CGContextRelease(cg_context);
    }
    if (cg_image) {
	CGRect rect = CGRectMake(x + mac_drawable->xOff, y + mac_drawable->yOff,
				 width, height);
	result = CGImageCreateWithImageInRect(cg_image, rect);
	CGImageRelease(cg_image);
    }

    return result;



}





/*
 *----------------------------------------------------------------------

 *
 * CreatePDFFromDrawableRect
 *
 *	Extract PDF data from a MacOSX drawable.
 *
 * Results:
 *	Returns a CFDataRef that can be written to a file.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system
 *      with origin at the bottom left as used by NSView,  not top left


 *      as used by XImage and CGImage.

 *
 * Side effects:

 *     None
 *
 *----------------------------------------------------------------------
 */

CFDataRef
CreatePDFFromDrawableRect(
			  Drawable drawable,
			  int x,
			  int y,
			  unsigned int width,
			  unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *)drawable;
    NSView *view = TkMacOSXGetNSViewForDrawable(mac_drawable);
    if (view == nil) {
	TkMacOSXDbgMsg("Invalid source drawable");
	return NULL;
    }
    NSRect bounds, viewSrcRect;

    /*
     * Get the child window area in NSView coordinates
     * (origin at bottom left).
     */

    bounds = [view bounds];
    viewSrcRect = NSMakeRect(mac_drawable->xOff + x,
			     bounds.size.height - height - (mac_drawable->yOff + y),
			     width, height);
    NSData *viewData = [view dataWithPDFInsideRect:viewSrcRect];
    CFDataRef result = (CFDataRef)viewData;
    return result;
}


/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromPixmap --
 *
 *	Create a CGImage from an X Pixmap.
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
 *	constructed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
struct pixel_fmt {int r; int g; int b; int a;};
static struct pixel_fmt bgra = {2, 1, 0, 3};
static struct pixel_fmt abgr = {3, 2, 1, 0};

XImage *
XGetImage(
    Display *display,
    Drawable drawable,
    int x,
    int y,
    unsigned int width,
    unsigned int height,
    TCL_UNUSED(unsigned long), /* plane_mask */
    int format)
{
    NSBitmapImageRep* bitmapRep = NULL;
    NSUInteger bitmap_fmt = 0;
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;

    if (format == ZPixmap) {
	CGImageRef cgImage;
	if (width == 0 || height == 0) {
	    return NULL;







<
<
<









|


|


|
<







770
771
772
773
774
775
776



777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799
 *	constructed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */




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;

    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;

    if (format == ZPixmap) {
	CGImageRef cgImage;
	if (width == 0 || height == 0) {
	    return NULL;
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

669
670
671





672
673
674
675
676
677
678
679
680
681


682
683
684
685
686
687
688
689
690
691
692
693
694
695

696
697
698
699
700

701
702
703
704
705
706
707
	} 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;
}

/*
 *----------------------------------------------------------------------







<
<
|
|
|
|
|

|


>

|

>
>
>
>
>
|
<
|
|

|
|
<
<
|
>
>
|
|
|
|
<
<
<
<






>





>







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
	} else {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct CGImage");
	    return NULL;
	}
	bitmap_fmt = [bitmapRep bitmapFormat];
	size = [bitmapRep bytesPerPlane];
	bytes_per_row = [bitmapRep bytesPerRow];


	if ((bitmap_fmt != 0 && bitmap_fmt != NSAlphaFirstBitmapFormat)
	    || [bitmapRep samplesPerPixel] != 4
	    || [bitmapRep isPlanar] != 0
	    || bytes_per_row < 4 * width
	    || size != bytes_per_row * height) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    [bitmapRep release];
	    return NULL;
	}
	bitmap = (char *)ckalloc(size);
	memcpy(bitmap, (char *)[bitmapRep bitmapData], size);
	[bitmapRep release];

	for (row = 0, n = 0; row < height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*width; m += 4) {
		pixel32 pixel = *((pixel32 *)(bitmap + m));
		if (bitmap_fmt == 0) { // default format

		    /*

		     * This pixel is in ARGB32 format.  We need RGBA32.
		     */

		    pixel32 flipped;
		    flipped.rgba.red = pixel.argb.red;


		    flipped.rgba.green = pixel.argb.green;
		    flipped.rgba.blue = pixel.argb.blue;
		    flipped.rgba.alpha = pixel.argb.alpha;
		    *((pixel32 *)(bitmap + m)) = flipped;
		} else { // bitmap_fmt = NSAlphaFirstBitmapFormat
		    *((pixel32 *)(bitmap + m)) = pixel;
		}




	    }
	}
	imagePtr = XCreateImage(display, NULL, depth, format, offset,
		(char*) bitmap, width, height,
		bitmap_pad, bytes_per_row);
    } else {

	/*
	 * There are some calls to XGetImage in the generic Tk code which pass
	 * an XYPixmap rather than a ZPixmap.  XYPixmaps should be handled
	 * here.
	 */

	TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment.");
    }
    return imagePtr;
}

/*
 *----------------------------------------------------------------------
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
    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;







|







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    LastKnownRequestProcessed(display)++;
    if (!width || !height) {
	return BadDrawable;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
	TkMacOSXDbgMsg("Failed to setup drawing context.");
	return BadDrawable;
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
    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");
    }







|







964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    MacDrawable *dstDraw = (MacDrawable *)dst;
    CGRect bounds, srcRect, dstRect;
    LastKnownRequestProcessed(display)++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return BadDrawable;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
900
901
902
903
904
905
906


































































































































































































































































































































































































































































































































































































































































































































907
908
909
910
911
912
913
914
915
	 * 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:
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
	 * Source drawable is a Window, not a Pixmap.
	 */

	return XCopyArea(display, src, dst, gc, src_x, src_y, width, height,
		dest_x, dest_y);
    }
}

/* ---------------------------------------------------------------------------*/

/*
 * Implementation of a Tk image type which provide access to NSImages
 * for use in buttons etc.
 */

/*
 * Forward declarations.
 */

typedef struct TkMacOSXNSImageInstance TkMacOSXNSImageInstance;
typedef struct TkMacOSXNSImageModel TkMacOSXNSImageModel;

/*
 * The following data structure represents a particular use of an nsimage
 * in a widget.
 */

struct TkMacOSXNSImageInstance {
    TkMacOSXNSImageModel *modelPtr;   /* Pointer to the model for the image. */
    NSImage *image;		  /* Pointer to an NSImage.*/
    TkMacOSXNSImageInstance *nextPtr;   /* First in the list of instances associated
				   * with this model. */
};

/*
 * The following data structure represents the model for an nsimage:
 */

struct TkMacOSXNSImageModel {
    Tk_ImageModel tkModel;	      /* Tk's token for image model. */
    Tcl_Interp *interp;		      /* Interpreter for application. */
    int width, height;		      /* Dimensions of the image. */
    int radius;                       /* Radius for rounded corners. */
    int ring;                         /* Thickness of the focus ring. */
    double alpha;                     /* Transparency, between 0.0 and 1.0*/
    char *imageName ;                 /* Malloc'ed image name. */
    char *source;       	      /* Malloc'ed string describing the image. */
    char *as;                         /* Malloc'ed interpretation of source */
    int	flags;			      /* Sundry flags, defined below. */
    bool pressed;                     /* Image is for use in a pressed button.*/
    bool templ;                       /* Image is for use as a template.*/
    TkMacOSXNSImageInstance *instancePtr;   /* Start of list of instances associated
				       * with this model. */
    NSImage *image;                   /* The underlying NSImage object. */
    NSImage *darkModeImage;           /* A modified image to use in Dark Mode. */
};

/*
 * Bit definitions for the flags field of a TkMacOSXNSImageModel.
 * IMAGE_CHANGED:		1 means that the instances of this image need
 *				to be redisplayed.
 */

#define IMAGE_CHANGED		1

/*
 * The type record for nsimage images:
 */

static int		TkMacOSXNSImageCreate(Tcl_Interp *interp,
			    const char *name, Tcl_Size objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    void **clientDataPtr);
static void *TkMacOSXNSImageGet(Tk_Window tkwin, void *clientData);
static void		TkMacOSXNSImageDisplay(void *clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width,
			    int height, int drawableX,
			    int drawableY);
static void		TkMacOSXNSImageFree(void *clientData, Display *display);
static void		TkMacOSXNSImageDelete(void *clientData);

static Tk_ImageType TkMacOSXNSImageType = {
    "nsimage",			/* name of image type */
    TkMacOSXNSImageCreate,		/* createProc */
    TkMacOSXNSImageGet,		/* getProc */
    TkMacOSXNSImageDisplay,		/* displayProc */
    TkMacOSXNSImageFree,		/* freeProc */
    TkMacOSXNSImageDelete,		/* deleteProc */
    NULL,			/* postscriptPtr */
    NULL,			/* nextPtr */
    NULL
};

/*
 * Default values used for parsing configuration specifications:
 */
#define DEF_SOURCE   ""
#define DEF_AS       "name"
#define DEF_HEIGHT   "0"
#define DEF_WIDTH    "0"
#define DEF_RADIUS   "0"
#define DEF_RING     "0"
#define DEF_ALPHA    "1.0"
#define DEF_PRESSED  "0"
#define DEF_TEMPLATE "0"

static const Tk_OptionSpec systemImageOptions[] = {
    {TK_OPTION_STRING, "-source", NULL, NULL, DEF_SOURCE,
     -1, offsetof(TkMacOSXNSImageModel, source), 0, NULL, 0},
    {TK_OPTION_STRING, "-as", NULL, NULL, DEF_AS,
     -1, offsetof(TkMacOSXNSImageModel, as), 0, NULL, 0},
    {TK_OPTION_INT, "-width", NULL, NULL, DEF_WIDTH,
     -1, offsetof(TkMacOSXNSImageModel, width), 0, NULL, 0},
    {TK_OPTION_INT, "-height", NULL, NULL, DEF_HEIGHT,
     -1, offsetof(TkMacOSXNSImageModel, height), 0, NULL, 0},
    {TK_OPTION_INT, "-radius", NULL, NULL, DEF_RADIUS,
     -1, offsetof(TkMacOSXNSImageModel, radius), 0, NULL, 0},
    {TK_OPTION_INT, "-ring", NULL, NULL, DEF_RING,
     -1, offsetof(TkMacOSXNSImageModel, ring), 0, NULL, 0},
    {TK_OPTION_DOUBLE, "-alpha", NULL, NULL, DEF_ALPHA,
     -1, offsetof(TkMacOSXNSImageModel, alpha), 0, NULL, 0},
    {TK_OPTION_BOOLEAN, "-pressed", NULL, NULL, DEF_PRESSED,
     -1, offsetof(TkMacOSXNSImageModel, pressed), TK_OPTION_VAR(bool), NULL, 0},
    {TK_OPTION_BOOLEAN, "-template", NULL, NULL, DEF_TEMPLATE,
     -1, offsetof(TkMacOSXNSImageModel, templ), TK_OPTION_VAR(bool), NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, NULL, 0}
};

/*
 * The -as option specifies how the string provided in the -source
 * option should be interpreted as a description of an NSImage.
 * Below are the possible values and their meanings.  (The last two
 * provide the macOS icon for a particular file type.)
 */

static const char *sourceInterpretations[] = {
    "name",       /* A name for a named NSImage. */
    "file",       /* A path to an image file. */
    "path",       /* A path to a file whose type should be examined. */
    "filetype",   /* A file extension or 4-byte OSCode. */
};

enum {NAME_SOURCE, FILE_SOURCE, PATH_SOURCE, FILETYPE_SOURCE};


/*
 *----------------------------------------------------------------------
 *
 * TintImage --
 *
 *      Modify an NSImage by blending it with a color.  The transparent part of
 *      the image remains transparent.  The opaque part of the image is painted
 *      with the color, using the specified alpha value for the transparency of
 *      the color.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The appearance of the NSImage changes.
 *
 *----------------------------------------------------------------------
 */

static void TintImage(
    NSImage *image,
    NSColor *color,
    double alpha)
{
    NSSize size = [image size];
    NSRect rect = {NSZeroPoint, size};
    NSImage *mask = [[[NSImage alloc] initWithSize:size] retain];
    [mask lockFocus];
    [color set];
    NSRectFillUsingOperation(rect, NSCompositeCopy);
    [image drawInRect:rect
	     fromRect:rect
	    operation:NSCompositeDestinationIn
	     fraction:1.0];
    [mask unlockFocus];
    [image lockFocus];
    [mask drawInRect:rect
	    fromRect:rect
	   operation:NSCompositeSourceOver
	    fraction:alpha];
    [image unlockFocus];
    [mask release];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageConfigureModel --
 *
 *	This function is called when an nsimage image is created or
 *	reconfigured.  It processes configuration options and resets any
 *	instances of the image.
 *
 * Results:
 *	A standard Tcl return value. If TCL_ERROR is returned then an error
 *	message is left in the modelPtr->interp's result.
 *
 * Side effects:
 *	Existing instances of the image will be redisplayed to match the new
 *	configuration options.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXNSImageConfigureModel(
    Tcl_Interp *interp,		   /* Interpreter to use for reporting errors. */
    TkMacOSXNSImageModel *modelPtr,    /* Pointer to data structure describing
				    * overall photo image to (re)configure. */
    Tcl_Size objc,			   /* Number of entries in objv. */
    Tcl_Obj *const objv[])	   /* Pairs of configuration options for image. */
{
    Tk_OptionTable optionTable = Tk_CreateOptionTable(interp, systemImageOptions);
    NSImage *newImage;
    Tcl_Obj *objPtr;
    static Tcl_Obj *asOption = NULL;
    int sourceInterpretation;
    NSString *source;
    int oldWidth = modelPtr->width, oldHeight = modelPtr->height;

    if (asOption == NULL) {
	asOption = Tcl_NewStringObj("-as", TCL_INDEX_NONE);
	Tcl_IncrRefCount(asOption);
    }

    modelPtr->width = 0;
    modelPtr->height = 0;
    if (Tk_SetOptions(interp, modelPtr, optionTable, objc, objv,
		      NULL, NULL, NULL) != TCL_OK){
	goto errorExit;
    }
    if (modelPtr->width == 0 && modelPtr->height == 0) {
	modelPtr->width = oldWidth;
	modelPtr->height = oldHeight;
    }

    if (modelPtr->source == NULL || modelPtr->source[0] == '0') {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("-source is required.", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SYSTEM", "BAD_VALUE", NULL);
	goto errorExit;
    }

    objPtr = Tk_GetOptionValue(interp, (char *) modelPtr, optionTable,
				asOption, NULL);
    if (Tcl_GetIndexFromObj(interp, objPtr, sourceInterpretations, "option",
			    0, &sourceInterpretation) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "Unknown interpretation for source in -as option.  "
	    "Should be name, file, path, or filetype.", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SYSTEM", "BAD_VALUE", NULL);
	goto errorExit;
    }

    source = [[NSString alloc] initWithUTF8String: modelPtr->source];
    switch (sourceInterpretation) {
    case NAME_SOURCE:
	newImage = [[NSImage imageNamed:source] copy];
	break;
    case FILE_SOURCE:
	newImage = [[NSImage alloc] initWithContentsOfFile:source];
	break;
    case PATH_SOURCE:
	newImage = [[NSWorkspace sharedWorkspace] iconForFile:source];
	break;
    case FILETYPE_SOURCE:
	newImage = TkMacOSXIconForFileType(source);
	break;
    default:
	newImage = NULL;
	break;
    }
    [source release];
    if (newImage) {
	NSSize size = NSMakeSize(modelPtr->width - 2*modelPtr->ring,
				 modelPtr->height - 2*modelPtr->ring);
	[modelPtr->image release];
	[modelPtr->darkModeImage release];
	newImage.size = size;
	modelPtr->image = [newImage retain];
	if (modelPtr->templ) {
	    newImage.template = YES;
	}
	modelPtr->darkModeImage = [[newImage copy] retain];
	if ([modelPtr->darkModeImage isTemplate]) {

	    /*
	     * For a template image the Dark Mode version should be white.
	     */

	    NSRect rect = {NSZeroPoint, size};
	    [modelPtr->darkModeImage lockFocus];
	    [[NSColor whiteColor] set];
	    NSRectFillUsingOperation(rect, NSCompositeSourceAtop);
	    [modelPtr->darkModeImage unlockFocus];
	} else if (modelPtr->pressed) {

	    /*
	     * Non-template pressed images are darker in Light Mode and lighter
	     * in Dark Mode.
	     */

	    TintImage(modelPtr->image, [NSColor blackColor], 0.2);
	    TintImage(modelPtr->darkModeImage, [NSColor whiteColor], 0.5);
	}
    } else {
	switch(sourceInterpretation) {
	case NAME_SOURCE:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("Unknown named NSImage.\n"
		"Try omitting ImageName, "
	        "e.g. use NSCaution for NSImageNameCaution.", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SYSTEM", "BAD_VALUE", NULL);
	    goto errorExit;
	case FILE_SOURCE:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Failed to load image file.\n", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SYSTEM", "BAD_VALUE", NULL);
	    goto errorExit;
	default:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Unrecognized file type.\n"
		"If using a filename extension, do not include the dot.\n", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SYSTEM", "BAD_VALUE", NULL);
	    goto errorExit;
	}
    }

    /*
     * Set the width and height.  If only one is specified, set the other one
     * so as to preserve the aspect ratio.  If neither is specified, match the
     * size of the image.
     */

    if (modelPtr->width == 0 && modelPtr->height == 0) {
	CGSize size = [modelPtr->image size];
	modelPtr->width = (int) size.width;
	modelPtr->height = (int) size.height;
    } else {
	CGSize size = [modelPtr->image size], newsize;
	CGFloat aspect = size.width && size.height ?
	     size.height / size.width : 1;
	if (modelPtr->width == 0) {
	    modelPtr->width = (int) ((CGFloat)(modelPtr->height) / aspect);
	} else if (modelPtr->height == 0) {
	    modelPtr->height = (int) ((CGFloat)(modelPtr->width) * aspect);
	}
	newsize = NSMakeSize(modelPtr->width, modelPtr->height);
	modelPtr->image.size = newsize;
	modelPtr->darkModeImage.size = newsize;
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    modelPtr->flags &= ~IMAGE_CHANGED;

    return TCL_OK;

  errorExit:
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageObjCmd --
 *
 *	This function implements the configure and cget commands for an
 *	nsimage instance.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The image may be reconfigured.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXNSImageObjCmd(
    void *clientData,	/* Information about the image model. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMacOSXNSImageModel *modelPtr = (TkMacOSXNSImageModel *)clientData;
    Tk_OptionTable optionTable = Tk_CreateOptionTable(interp, systemImageOptions);
    static const char *const options[] = {"cget", "configure", NULL};
    enum {CGET, CONFIGURE};
    Tcl_Obj *objPtr;
    int index;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(modelPtr);
    switch (index) {
    case CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	objPtr = Tk_GetOptionValue(interp, (char *)modelPtr, optionTable,
		objv[2], NULL);
	if (objPtr == NULL) {
            goto error;
        }
        Tcl_SetObjResult(interp, objPtr);
	break;
    case CONFIGURE:
	if (objc == 2) {
	    objPtr = Tk_GetOptionInfo(interp, (char *)modelPtr, optionTable,
				     NULL, NULL);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    break;
	} else if (objc == 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *)modelPtr, optionTable,
				     objv[2], NULL);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    break;
	} else {
	    TkMacOSXNSImageConfigureModel(interp, modelPtr, objc - 2, objv + 2);
	    break;
	}
    default:
	break;
    }

    Tcl_Release(modelPtr);
    return TCL_OK;

 error:
    Tcl_Release(modelPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageCreate --
 *
 *	Allocate and initialize an nsimage model.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The data structure for a new image is allocated.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXNSImageCreate(
    Tcl_Interp *interp,		 /* Interpreter for application using image. */
    const char *name,		 /* Name to use for image. */
    Tcl_Size objc,			 /* Number of arguments. */
    Tcl_Obj *const objv[],	 /* Argument strings for options (not
				  * including image name or type). */
    TCL_UNUSED(const Tk_ImageType *), /* typePtr */
    Tk_ImageModel model,	 /* Token for image, to be used in callbacks. */
    void **clientDataPtr)	 /* Store manager's token for image here; it
				  * will be returned in later callbacks. */
{
    TkMacOSXNSImageModel *modelPtr;
    Tk_OptionTable optionTable = Tk_CreateOptionTable(interp, systemImageOptions);

    modelPtr = (TkMacOSXNSImageModel *)ckalloc(sizeof(TkMacOSXNSImageModel));
    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    strcpy(modelPtr->imageName, name);
    modelPtr->flags = 0;
    modelPtr->instancePtr = NULL;
    modelPtr->image = NULL;
    modelPtr->darkModeImage = NULL;
    modelPtr->source = NULL;
    modelPtr->as = NULL;

    /*
     * Process configuration options given in the image create command.
     */

    if (Tk_InitOptions(interp, (char *) modelPtr, optionTable, NULL) != TCL_OK
	|| TkMacOSXNSImageConfigureModel(interp, modelPtr, objc, objv) != TCL_OK) {
	TkMacOSXNSImageDelete(modelPtr);
	return TCL_ERROR;
    }
    Tcl_CreateObjCommand(interp, name, TkMacOSXNSImageObjCmd, modelPtr, NULL);
    *clientDataPtr = modelPtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageGet --
 *
 *	Allocate and initialize an nsimage instance.
 *
 * Results:
 *	The return value is a token for the image instance, which is used in
 *	future callbacks to ImageDisplay and ImageFree.
 *
 * Side effects:
 *	A new new nsimage instance is created.
 *
 *----------------------------------------------------------------------
 */

static void *
TkMacOSXNSImageGet(
    TCL_UNUSED(Tk_Window),      /* tkwin */
    void *clientData)	/* Pointer to TkMacOSXNSImageModel for image. */
{
    TkMacOSXNSImageModel *modelPtr = (TkMacOSXNSImageModel *) clientData;
    TkMacOSXNSImageInstance *instPtr;

    instPtr = (TkMacOSXNSImageInstance *)ckalloc(sizeof(TkMacOSXNSImageInstance));
    instPtr->modelPtr = modelPtr;
    return instPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageDisplay --
 *
 *	Display or redisplay an nsimage in the given drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The image gets drawn.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNSImageDisplay(
    void *clientData,	/* Pointer to TkMacOSXNSImageInstance for image. */
    TCL_UNUSED(Display *),      /* display */
    Drawable drawable,		/* Where to draw or redraw image. */
    int imageX, int imageY,	/* Origin of area to redraw, relative to
				 * origin of image. */
    int width, int height,	/* Dimensions of area to redraw. */
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    MacDrawable *macWin = (MacDrawable *) drawable;
    Tk_Window tkwin = (Tk_Window) macWin->winPtr;
    TkMacOSXNSImageInstance *instPtr = (TkMacOSXNSImageInstance *) clientData;
    TkMacOSXNSImageModel *modelPtr = instPtr->modelPtr;
    TkMacOSXDrawingContext dc;
    NSRect dstRect = NSMakeRect(macWin->xOff + drawableX,
				 macWin->yOff + drawableY, width, height);
    NSRect srcRect = NSMakeRect(imageX, imageY, width, height);
    NSImage *image = TkMacOSXInDarkMode(tkwin) ? modelPtr->darkModeImage :
	modelPtr->image;
    int ring = modelPtr->ring;
    int radius = modelPtr->radius;

    if (TkMacOSXSetupDrawingContext(drawable, NULL, &dc)) {
	if (dc.context) {
	    CGRect clipRect = CGRectMake(
		dstRect.origin.x - srcRect.origin.x + ring,
		dstRect.origin.y - srcRect.origin.y + ring,
		modelPtr->width - 2*ring,
		modelPtr->height - 2*ring);
	    CGPathRef path = CGPathCreateWithRoundedRect(clipRect, radius, radius, NULL);
	    CGContextSaveGState(dc.context);
	    CGContextBeginPath(dc.context);
	    CGContextAddPath(dc.context, path);
	    CGContextClip(dc.context);
	    NSGraphicsContext *savedContext = NSGraphicsContext.currentContext;
	    NSGraphicsContext.currentContext = [NSGraphicsContext
		graphicsContextWithCGContext:dc.context flipped:YES];
	    [image drawInRect:clipRect
		     fromRect:srcRect
		    operation:NSCompositeSourceOver
		     fraction:modelPtr->alpha
	       respectFlipped:YES
			hints:nil];
	    CGContextRestoreGState(dc.context);

	    /*
	     * Draw the focus ring.
	     */

	    if (ring) {
		CGRect ringRect = CGRectInset(clipRect, -ring, -ring);
		CGPathRef ringPath = CGPathCreateWithRoundedRect(ringRect,
		    radius + ring, radius + ring, NULL);
		CGContextSaveGState(dc.context);
		CGContextAddPath(dc.context, path);
		CGContextAddPath(dc.context, ringPath);
		CGContextSetFillColorWithColor(dc.context,
					       controlAccentColor().CGColor);
		CGContextEOFillPath(dc.context);
		CGContextRestoreGState(dc.context);
		CFRelease(ringPath);
	    }
	    CFRelease(path);
	    NSGraphicsContext.currentContext = savedContext;
	}
	TkMacOSXRestoreDrawingContext(&dc);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageFree --
 *
 *	Deallocate an instance of an nsimage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information related to the instance is freed.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNSImageFree(
    void *clientData,	/* Pointer to TkMacOSXNSImageInstance for instance. */
    TCL_UNUSED(Display *))	/* display */
{
    TkMacOSXNSImageInstance *instPtr = (TkMacOSXNSImageInstance *) clientData;
    ckfree(instPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImageDelete --
 *
 *	Deallocate an nsimage model.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	 NSImages are released and memory is freed.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNSImageDelete(
    void *clientData)	/* Pointer to TkMacOSXNSImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TkMacOSXNSImageModel *modelPtr = (TkMacOSXNSImageModel *) clientData;

    Tcl_DeleteCommand(modelPtr->interp, modelPtr->imageName);
    ckfree(modelPtr->imageName);
    ckfree(modelPtr->source);
    ckfree(modelPtr->as);
    [modelPtr->image release];
    [modelPtr->darkModeImage release];
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXNSImage_Init --
 *
 *	Adds the TkMacOSXNSImage type to Tk.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error message in
 *	the interp's result if an error occurs.
 *
 * Side effects:
 *	Creates the image create nsrect ...  command.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXNSImage_Init(
    TCL_UNUSED(Tcl_Interp *))	 /* interp */
{
    Tk_CreateImageType(&TkMacOSXNSImageType);
    return 1;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Added macosx/tkMacOSXImage.h.













































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 *  tkMacOSXImage.h --
 *
 *
 *	The code in this file provides an interface for XImages, and
 *      implements the nsimage image type.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright (c) 2017-2021 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Function prototypes
 */

MODULE_SCOPE CFDataRef CreatePDFFromDrawableRect( Drawable drawable,
	   int x, int y, unsigned int width, unsigned int height);

Changes to macosx/tkMacOSXInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43






































44
45
46
47
48
49
50
/*
 * 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
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include <dlfcn.h>
#include <objc/objc-auto.h>
#include <sys/stat.h>


static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";

/*
 * Forward declarations...
 */

static int		TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip,
			    int objc, Tcl_Obj *const objv[]);

#pragma mark TKApplication(TKInit)

@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macOSVersion = _macOSVersion;
@synthesize isDrawing = _isDrawing;
@synthesize needsToDraw = _needsToDraw;






































@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK






|
|
|
|






>



>














|
|







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
 * tkMacOSXInit.c --
 *
 *	This file contains Mac OS X -specific interpreter initialization
 *	functions.
 *
 * 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 "tkMacOSXConstants.h"
#include <dlfcn.h>
#include <objc/objc-auto.h>
#include <sys/stat.h>
#include <sys/utsname.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";

/*
 * Forward declarations...
 */

static Tcl_ObjCmdProc TkMacOSXGetAppPathObjCmd;
static Tcl_ObjCmdProc TkMacOSVersionObjCmd;

#pragma mark TKApplication(TKInit)

@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macOSVersion = _macOSVersion;
@synthesize isDrawing = _isDrawing;
@synthesize isSigned = _isSigned;
@synthesize tkLiveResizeEnded = _tkLiveResizeEnded;
@synthesize tkPointerWindow = _tkPointerWindow;
- (void) setTkPointerWindow: (TkWindow *)winPtr
{
    if (winPtr) {
	Tcl_Preserve(winPtr);
    }
    if (_tkPointerWindow) {
	Tcl_Release(_tkPointerWindow);
    }
    _tkPointerWindow = winPtr;
    return;
}
@synthesize tkEventTarget = _tkEventTarget;
- (void) setTkEventTarget: (TkWindow *)winPtr
{
    if (winPtr) {
	Tcl_Preserve(winPtr);
    }
    if (_tkEventTarget) {
	Tcl_Release(_tkEventTarget);
    }
    _tkEventTarget = winPtr;
    return;
}
@synthesize tkDragTarget = _tkDragTarget;
- (void) setTkDragTarget: (TkWindow *)winPtr
{
    if (winPtr) {
	Tcl_Preserve(winPtr);
    }
    if (_tkDragTarget) {
	Tcl_Release(_tkDragTarget);
    }
    _tkDragTarget = winPtr;
    return;
}
@synthesize tkButtonState = _tkButtonState;
@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92










93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114




115
116
117
118
119
120
121
122
123

124
125
126
127
128
































129
130
131
132
133
134
135
136
137
138
139
140














141
142
143
144
145
146
147
- (void) _unlockAutoreleasePool
{
    [self setPoolLock:[self poolLock] - 1];
}
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void) _postedNotification: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}
#endif

- (void) _setupApplicationNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]
    observe(NSApplicationDidBecomeActiveNotification, applicationActivate:);
    observe(NSApplicationWillResignActiveNotification, applicationDeactivate:);
    observe(NSApplicationDidUnhideNotification, applicationShowHide:);
    observe(NSApplicationDidHideNotification, applicationShowHide:);
    observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:);
    observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:);
#undef observe
}











-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    (void)aNotification;

    /*
     * Initialize notifications.
     */
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    [[NSNotificationCenter defaultCenter] addObserver:self
	    selector:@selector(_postedNotification:) name:nil object:nil];
#endif
    [self _setupWindowNotifications];
    [self _setupApplicationNotifications];

    /*
     * Construct the menu bar.
     */
    _defaultMainMenu = nil;
    [self _setupMenus];


    /*
     * Initialize event processing.




     */

    TkMacOSXInitAppleEvents(_eventInterp);

    /*
     * Initialize the graphics context.
     */
    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);

}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
    (void)notification;

































    /*
     * It is not safe to force activation of the NSApp until this method is
     * called. Activating too early can cause the menu bar to be unresponsive.
     * The call to activateIgnoringOtherApps was moved here to avoid this.
     * However, with the release of macOS 10.15 (Catalina) that was no longer
     * sufficient.  (See ticket bf93d098d7.)  The call to setActivationPolicy
     * needed to be moved into this function as well.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    [NSApp activateIgnoringOtherApps: YES];















    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];







|

















>
>
>
>
>
>
>
>
>
>














<
<
<
<
<
>

|
|
>
>
>
>
|



<
<
<
<
<
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>
>
>
>
>
>
>
>
>
>
>
>
>
>







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156





157
158
159
160
161
162
163
164
165
166
167
168





169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
- (void) _unlockAutoreleasePool
{
    [self setPoolLock:[self poolLock] - 1];
}
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void) _postedNotification: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
}
#endif

- (void) _setupApplicationNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]
    observe(NSApplicationDidBecomeActiveNotification, applicationActivate:);
    observe(NSApplicationWillResignActiveNotification, applicationDeactivate:);
    observe(NSApplicationDidUnhideNotification, applicationShowHide:);
    observe(NSApplicationDidHideNotification, applicationShowHide:);
    observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:);
    observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:);
#undef observe
}


/*
 * Fix for 10b38a7a7c.
 */

- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app
{
    return YES;
}

-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    (void)aNotification;

    /*
     * Initialize notifications.
     */
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    [[NSNotificationCenter defaultCenter] addObserver:self
	    selector:@selector(_postedNotification:) name:nil object:nil];
#endif
    [self _setupWindowNotifications];
    [self _setupApplicationNotifications];






    if ([NSApp macOSVersion] >= 110000) {

   /*
    * Initialize Apple Event processing. Apple's docs (see
    * https://developer.apple.com/documentation/appkit/nsapplication)
    * recommend doing this here, although historically we have
    * done this in applicationWillFinishLaunching. In response to
    * bug 7bb246b072.
    */

    TkMacOSXInitAppleEvents(_eventInterp);






    }
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
    (void)notification;

   if ([NSApp macOSVersion] < 110000) {

   /*
    * Initialize Apple Event processing on macOS versions
    * older than Big Sur (11).
    */

    TkMacOSXInitAppleEvents(_eventInterp);

    }


    /*
     * Initialize the graphics context.
     */

    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);

    /*
     * Construct the menu bar.
     */

    _defaultMainMenu = nil;
    [self _setupMenus];

    /*
     * Run initialization routines that depend on the OS version.
     */

    Ttk_MacOSXInit();

    /*
     * It is not safe to force activation of the NSApp until this method is
     * called. Activating too early can cause the menu bar to be unresponsive.
     * The call to activateIgnoringOtherApps was moved here to avoid this.
     * However, with the release of macOS 10.15 (Catalina) that was no longer
     * sufficient.  (See ticket bf93d098d7.)  The call to setActivationPolicy
     * needed to be moved into this function as well.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    [NSApp activateIgnoringOtherApps: YES];

    /*
     * Add an event monitor so we continue to receive NSMouseMoved and
     * NSMouseDragged events when the mouse moves outside of the key
     * window. The handler simply returns the events it receives, so
     * they can be processed in the same way as for other events.
     */

    [NSEvent addLocalMonitorForEventsMatchingMask:(NSMouseMovedMask |
						   NSLeftMouseDraggedMask)
	 handler:^NSEvent *(NSEvent *event)
	 {
	     return event;
	 }];

    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178


















179
180
181
182
183
184
185
    [NSApp setPoolLock:0];

    /*
     * Record the OS version we are running on.
     */

    int minorVersion, majorVersion;

#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
    Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
    majorVersion = 10;
#else
    NSOperatingSystemVersion systemVersion;
    systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
    majorVersion = systemVersion.majorVersion;
    minorVersion = systemVersion.minorVersion;
#endif


















    [NSApp setMacOSVersion: 10000*majorVersion + 100*minorVersion];

    /*
     * We are not drawing right now.
     */

    [NSApp setIsDrawing:NO];







>






|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    [NSApp setPoolLock:0];

    /*
     * Record the OS version we are running on.
     */

    int minorVersion, majorVersion;

#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
    Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
    majorVersion = 10;
#else
    NSOperatingSystemVersion systemVersion;
    systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
    majorVersion = (int)systemVersion.majorVersion;
    minorVersion = (int)systemVersion.minorVersion;
#endif

    if (majorVersion == 10 && minorVersion == 16) {

	/*
	 * If a program compiled with a macOS 10.XX SDK is run on macOS 11.0 or
	 * later then it will report majorVersion 10 and minorVersion 16, no
	 * matter what the actual OS version of the host may be. And of course
	 * Apple never released macOS 10.16. To work around this we guess the
	 * OS version from the kernel release number, as reported by uname.
	 */

	struct utsname name;
	char *endptr;
	if (uname(&name) == 0) {
	    majorVersion = (int)strtol(name.release, &endptr, 10) - 9;
	    minorVersion = 0;
	}
    }
    [NSApp setMacOSVersion: 10000*majorVersion + 100*minorVersion];

    /*
     * We are not drawing right now.
     */

    [NSApp setIsDrawing:NO];
198
199
200
201
202
203
204

205
206
207
208
209
210
211
    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
						    @"CFBundleIconFile"];
    if (!iconFile) {
	NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
	if (path) {
	    NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
	    if (image) {

		[NSApp setApplicationIconImage:image];
		[image release];
	    }
	}
    }
}








>







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
						    @"CFBundleIconFile"];
    if (!iconFile) {
	NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
	if (path) {
	    NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
	    if (image) {
		[image setName:@"NSApplicationIcon"];
		[NSApp setApplicationIconImage:image];
		[image release];
	    }
	}
    }
}

322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
     * 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







|







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
     * 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((int)PTR2INT(clientdata)); /* Convince the compiler that we don't return. */
}
#endif

/*
 * This signal handler is installed for the SIGINT, SIGHUP and SIGTERM signals
 * so that normal finalization occurs when a Tk app is killed by one of these
 * signals (e.g when ^C is pressed while running Wish in the shell).  It calls
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
TkpInit(
    Tcl_Interp *interp)
{
    static int initialized = 0;

    /*
     * TkpInit can be called multiple times with different interpreters. But
     * The application initialization should only be done onece.
     */

    if (!initialized) {
	struct stat st;
	Bool shouldOpenConsole = NO;
        Bool stdinIsNullish = (!isatty(0) &&
	    (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)));







|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
TkpInit(
    Tcl_Interp *interp)
{
    static int initialized = 0;

    /*
     * TkpInit can be called multiple times with different interpreters. But
     * The application initialization should only be done once.
     */

    if (!initialized) {
	struct stat st;
	Bool shouldOpenConsole = NO;
        Bool stdinIsNullish = (!isatty(0) &&
	    (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)));
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
         * 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.







|







522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
         * 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
         * AppleEvent later, after the required procedure has been defined.
         */

	[NSApp _setup:interp];
	[NSApp finishLaunching];

        /*
         * Create a Tk event source based on the Appkit event queue.
497
498
499
500
501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516

	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.
	 */







|
|
|



>







609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

	if (getenv("XCNOSTDIN") != NULL) {
	    close(0);
	    close(1);
	}

	/*
	 * Now we can run initialization routines which require that both the
	 * NSApplication and the Tcl interpreter have been created and
	 * initialized.
	 */

	TkMacOSXServices_Init(interp);
	TkMacOSXNSImage_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.
	 */
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558

559
560
561
562
563


























564



























565
566
567
568
569
570
571
	 * application is killed with one of these signals.
	 */

	signal(SIGINT, TkMacOSXSignalHandler);
	signal(SIGHUP, TkMacOSXSignalHandler);
	signal(SIGTERM, TkMacOSXSignalHandler);
    }

    /*
     * Initialization steps that are needed for all interpreters.
     */

    if (tkLibPath[0] != '\0') {
	Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
    }

    if (scriptPath[0] != '\0') {
	Tcl_SetVar2(interp, "auto_path", NULL, scriptPath,
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
    }


    Tcl_CreateObjCommand(interp, "::tk::mac::standardAboutPanel",
	    TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
	    TkMacOSXIconBitmapObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath",


























	    TkMacOSXGetAppPathCmd, NULL, NULL);




























    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







<







<




|
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







651
652
653
654
655
656
657

658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
	 * 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, "nsimage",
	    TkMacOSXNSImageObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::standardAboutPanel",
	    TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
	    TkMacOSXIconBitmapObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath",
	    TkMacOSXGetAppPathObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::mac::macOSVersion",
           TkMacOSVersionObjCmd, NULL, NULL);
    MacSystrayInit(interp);
    MacPrint_Init(interp);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetAppPathObjCmd --
 *
 *	Returns the path of the Wish application bundle.
 *
 * Results:
 *	Returns the application path.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXGetAppPathObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }

    /*
     * Get the application path URL and convert it to a string path reference.
     */

    CFURLRef mainBundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef appPath =
	    CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);

    /*
     * Convert (and copy) the string reference into a Tcl result.
     */

    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    CFStringGetCStringPtr(appPath, CFStringGetSystemEncoding()), TCL_INDEX_NONE));

    CFRelease(mainBundleURL);
    CFRelease(appPath);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611


612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
    }
    Tcl_DStringAppend(namePtr, name, -1);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetAppPathCmd --
 *
 *	Returns the path of the Wish application bundle.


 *
 * Results:
 *	Returns the application path.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXGetAppPathCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }

    /*
     * Get the application path URL and convert it to a string path reference.
     */

    CFURLRef mainBundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef appPath =
	    CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);

    /*
     * Convert (and copy) the string reference into a Tcl result.
     */

    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    CFStringGetCStringPtr(appPath, CFStringGetSystemEncoding()), -1));

    CFRelease(mainBundleURL);
    CFRelease(appPath);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --







|





|

|
>
>


|






|

|





>
|



|
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
    }
    Tcl_DStringAppend(namePtr, name, TCL_INDEX_NONE);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSVersionObjCmd --
 *
 *	Tcl command which returns an integer encoding the major and minor
 *	version numbers of the currently running operating system in the
 *	form 10000*majorVersion + 100*minorVersion.
 *
 * Results:
 *	Returns the OS version.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSVersionObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    static char version[16] = "";
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    if (version[0] == '\0') {



	snprintf(version, 16, "%d", [NSApp macOSVersion]);



    }




    Tcl_SetResult(interp, version, NULL);




    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
TkpDisplayWarning(
    const char *msg,		/* Message to be displayed. */
    const char *title)		/* Title of warning. */
{
    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);

    if (errChannel) {
	Tcl_WriteChars(errChannel, title, -1);
	Tcl_WriteChars(errChannel, ": ", 2);
	Tcl_WriteChars(errChannel, msg, -1);
	Tcl_WriteChars(errChannel, "\n", 1);
    }
}

/*
 *----------------------------------------------------------------------
 *







|

|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
TkpDisplayWarning(
    const char *msg,		/* Message to be displayed. */
    const char *title)		/* Title of warning. */
{
    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);

    if (errChannel) {
	Tcl_WriteChars(errChannel, title, TCL_INDEX_NONE);
	Tcl_WriteChars(errChannel, ": ", 2);
	Tcl_WriteChars(errChannel, msg, TCL_INDEX_NONE);
	Tcl_WriteChars(errChannel, "\n", 1);
    }
}

/*
 *----------------------------------------------------------------------
 *
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

	if (appMainURL != NULL) {
	    CFURLRef scriptFldrURL;
	    char startupScript[PATH_MAX + 1];

	    if (CFURLGetFileSystemRepresentation(appMainURL, true,
		    (unsigned char *) startupScript, PATH_MAX)) {
		Tcl_SetStartupScript(Tcl_NewStringObj(startupScript,-1), NULL);
		scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent(NULL,
			appMainURL);
		if (scriptFldrURL != NULL) {
		    CFURLGetFileSystemRepresentation(scriptFldrURL, true,
			    (unsigned char *) scriptPath, PATH_MAX);
		    CFRelease(scriptFldrURL);
		}







|







869
870
871
872
873
874
875
876
877
878
879
880
881
882
883

	if (appMainURL != NULL) {
	    CFURLRef scriptFldrURL;
	    char startupScript[PATH_MAX + 1];

	    if (CFURLGetFileSystemRepresentation(appMainURL, true,
		    (unsigned char *) startupScript, PATH_MAX)) {
		Tcl_SetStartupScript(Tcl_NewStringObj(startupScript, TCL_INDEX_NONE), NULL);
		scriptFldrURL = CFURLCreateCopyDeletingLastPathComponent(NULL,
			appMainURL);
		if (scriptFldrURL != NULL) {
		    CFURLGetFileSystemRepresentation(scriptFldrURL, true,
			    (unsigned char *) scriptPath, PATH_MAX);
		    CFRelease(scriptFldrURL);
		}

Changes to macosx/tkMacOSXInt.h.

20
21
22
23
24
25
26

27

28
29
30
31
32
33
34

/*
 * Include platform specific public interfaces.
 */

#ifndef _TKMAC
#include "tkMacOSX.h"

#import <Cocoa/Cocoa.h>

#endif

/*
 * Define compatibility platform types used in the structures below so that
 * this header can be included without pulling in the platform headers.
 */








>

>







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
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
 */

/*
 * GC CGColorRef cache for tkMacOSXColor.c
 */

typedef struct {
    unsigned long cachedForeground;
    CGColorRef cachedForegroundColor;
    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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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.
 */
















/*
 * Undef compatibility platform types defined above.
 */

#ifndef _TKMACPRIV
#   ifndef CGGEOMETRY_H_
#	ifndef CGFLOAT_DEFINED
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#define TK_DRAW_IN_CONTEXT		1

/*
 * Prototypes of internal procs not in the stubs table.
 */

MODULE_SCOPE void TkMacOSXDefaultStartupScript(void);
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(Region r);
MODULE_SCOPE void TkpReleaseRegion(Region r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
MODULE_SCOPE Bool TkTestLogDisplay(Drawable drawable);

/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"







<
<
<
<
<







156
157
158
159
160
161
162





163
164
165
166
167
168
169
#define TK_DRAW_IN_CONTEXT		1

/*
 * Prototypes of internal procs not in the stubs table.
 */

MODULE_SCOPE void TkMacOSXDefaultStartupScript(void);





MODULE_SCOPE Bool TkTestLogDisplay(Drawable drawable);

/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

Changes to macosx/tkMacOSXKeyEvent.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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.
 *
 * 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"






|
|
|
|







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 © 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"
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72












73
74
75
76
77
78
79
80
81
82
83
84
85



86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111




112
113

114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
    NSWindow *w = [theEvent window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;
    NSEventType type = [theEvent type];
    NSUInteger virtual = [theEvent keyCode];
    NSUInteger modifiers = ([theEvent modifierFlags] &
			    NSDeviceIndependentModifierFlagsMask);
    XEvent xEvent;
    MacKeycode macKC;
    UniChar keychar = 0;
    Bool can_input_text, has_modifiers = NO, use_text_input = NO;
    static NSUInteger savedModifiers = 0;
    static NSMutableArray *nsEvArray = nil;

    if (nsEvArray == nil) {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
    }
    if (!winPtr) {
	return theEvent;
    }













    /*
     * If a local grab is in effect, key events for windows in the
     * grabber's application are redirected to the grabber.  Key events
     * for other applications are delivered normally.  If a global
     * grab is in effect all key events are redirected to the grabber.
     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr) {
	if (winPtr->dispPtr->grabFlags ||  /* global grab */
	    grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */
	    winPtr =winPtr->dispPtr->focusPtr;



	    tkwin = (Tk_Window)winPtr;
	}
    }

    /*
     * Extract the unicode character from KeyUp and KeyDown events.
     */

    if (type == NSKeyUp || type == NSKeyDown) {
	if ([[theEvent characters] length] > 0) {
	    keychar = [[theEvent characters] characterAtIndex:0];


	    /*
	     * Currently, real keys always send BMP characters, but who knows?
	     */

	    if (CFStringIsSurrogateHighCharacter(keychar)) {
		UniChar lowChar = [[theEvent characters] characterAtIndex:1];
		keychar = CFStringGetLongCharacterForSurrogatePair(
		    keychar, lowChar);
	    }
	} else {

	    /*
	     * This is a dead key, such as Option-e, so it should go to the
	     * TextInputClient.




	     */


	    use_text_input = YES;

	}

	/*
	 * Apple uses 0x10 for unrecognized keys.
	 */

	if (keychar == 0x10) {
	    keychar = UNKNOWN_KEYCHAR;
	}

#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	TKLog(@"-[%@(%p) %s] repeat=%d mods=%x char=%x code=%lu c=%d type=%d",
	      [self class], self, _cmd,
	      (type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar,
	      virtual, w, type);
#endif

    }

    /*
     * Build a skeleton XEvent.  We need to build it here, even if we will not
     * send it, so we can pass it to TkFocusKeyEvent to determine whether the







|





|
















>
>
>
>
>
>
>
>
>
>
>
>












|
>
>
>









|
|
>






|






|
|
>
>
>
>


>
|
>












|

|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), theEvent);
#endif
    NSWindow *w = [theEvent window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w), *grabWinPtr, *focusWinPtr;
    Tk_Window tkwin = (Tk_Window)winPtr;
    NSEventType type = [theEvent type];
    NSUInteger virt = [theEvent keyCode];
    NSUInteger modifiers = ([theEvent modifierFlags] &
			    NSDeviceIndependentModifierFlagsMask);
    XEvent xEvent;
    MacKeycode macKC;
    UniChar keychar = 0;
    Bool can_input_text, has_modifiers = NO, use_text_input = NO;
    static NSUInteger savedModifiers = 0;
    static NSMutableArray *nsEvArray = nil;

    if (nsEvArray == nil) {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
    }
    if (!winPtr) {
	return theEvent;
    }

    /*
     * Discard repeating KeyDown events if the repeat speed has been set to
     * "off" in System Preferences.  It is unclear why we get these, but we do.
     * See ticket [2ecb09d118].
     */

    if ([theEvent type] ==  NSKeyDown &&
	[theEvent isARepeat] &&
	[NSEvent keyRepeatDelay] < 0) {
            return theEvent;
	}

    /*
     * If a local grab is in effect, key events for windows in the
     * grabber's application are redirected to the grabber.  Key events
     * for other applications are delivered normally.  If a global
     * grab is in effect all key events are redirected to the grabber.
     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr) {
	if (winPtr->dispPtr->grabFlags ||  /* global grab */
	    grabWinPtr->mainPtr == winPtr->mainPtr){ /* same application */
	    winPtr = winPtr->dispPtr->focusPtr;
	    if (!winPtr) {
		return theEvent;
	    }
	    tkwin = (Tk_Window)winPtr;
	}
    }

    /*
     * Extract the unicode character from KeyUp and KeyDown events.
     */

    if (type == NSKeyUp || type == NSKeyDown) {
	NSString *characters = [theEvent characters];
	if (characters.length > 0) {
	    keychar = [characters characterAtIndex:0];

	    /*
	     * Currently, real keys always send BMP characters, but who knows?
	     */

	    if (CFStringIsSurrogateHighCharacter(keychar)) {
		UniChar lowChar = [characters characterAtIndex:1];
		keychar = CFStringGetLongCharacterForSurrogatePair(
		    keychar, lowChar);
	    }
	} else {

	    /*
	     * This is a dead key, such as Option-e, so it usually should get
	     * passed to the TextInputClient.  But if it has a Command modifier
	     * then it is not functioning as a dead key and should not be
	     * handled by the TextInputClient.  See ticket [1626ed65b8] and the
	     * method performKeyEquivalent which is implemented in
	     * tkMacOSXMenu.c.
	     */

	    if (!(modifiers & NSCommandKeyMask)) {
		use_text_input = YES;
	    }
	}

	/*
	 * Apple uses 0x10 for unrecognized keys.
	 */

	if (keychar == 0x10) {
	    keychar = UNKNOWN_KEYCHAR;
	}

#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	TKLog(@"-[%@(%p) %s] repeat=%d mods=%x char=%x code=%lu c=%d type=%d",
	      [self class], self, sel_getName(_cmd),
	      (type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar,
	      virt, w, type);
#endif

    }

    /*
     * Build a skeleton XEvent.  We need to build it here, even if we will not
     * send it, so we can pass it to TkFocusKeyEvent to determine whether the
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    /*
     * We are not handling this event as an NSTextInputClient, so we need to
     * finish constructing the XEvent and queue it.
     */

    macKC.v.o_s =  ((modifiers & NSShiftKeyMask ? INDEX_SHIFT : 0) |
		    (modifiers & NSAlternateKeyMask ? INDEX_OPTION : 0));
    macKC.v.virtual = virtual;
    switch (type) {
    case NSFlagsChanged:

	/*
	 * This XEvent is a simulated KeyPress or KeyRelease event for a
	 * modifier key.  To determine the type, note that the highest bit
	 * where the flags differ is 1 if and only if it is a KeyPress. The







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    /*
     * We are not handling this event as an NSTextInputClient, so we need to
     * finish constructing the XEvent and queue it.
     */

    macKC.v.o_s =  ((modifiers & NSShiftKeyMask ? INDEX_SHIFT : 0) |
		    (modifiers & NSAlternateKeyMask ? INDEX_OPTION : 0));
    macKC.v.virt = virt;
    switch (type) {
    case NSFlagsChanged:

	/*
	 * This XEvent is a simulated KeyPress or KeyRelease event for a
	 * modifier key.  To determine the type, note that the highest bit
	 * where the flags differ is 1 if and only if it is a KeyPress. The
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

    /*
     * Finally we can queue the XEvent, inserting a KeyRelease before a
     * repeated KeyPress.
     */

    if (type == NSKeyDown && [theEvent isARepeat]) {

	xEvent.xany.type = KeyRelease;
	Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	xEvent.xany.type = KeyPress;
    }
    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
    return theEvent;
}
@end


@implementation TKContentView
@synthesize tkDirtyRect = _tkDirtyRect;
@synthesize tkNeedsDisplay = _tkNeedsDisplay;;

/*
 * Implementation of the NSTextInputClient protocol.
 */

/* [NSTextInputClient inputText: replacementRange:] is called by
 * interpretKeyEvents when a composition sequence is complete.  It is also







<












|







273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

    /*
     * Finally we can queue the XEvent, inserting a KeyRelease before a
     * repeated KeyPress.
     */

    if (type == NSKeyDown && [theEvent isARepeat]) {

	xEvent.xany.type = KeyRelease;
	Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	xEvent.xany.type = KeyPress;
    }
    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
    return theEvent;
}
@end


@implementation TKContentView
@synthesize tkDirtyRect = _tkDirtyRect;
@synthesize tkNeedsDisplay = _tkNeedsDisplay;

/*
 * Implementation of the NSTextInputClient protocol.
 */

/* [NSTextInputClient inputText: replacementRange:] is called by
 * interpretKeyEvents when a composition sequence is complete.  It is also
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

	keychar = [str characterAtIndex:i];
	macKC.v.keychar = keychar;
	if (CFStringIsSurrogateHighCharacter(keychar)) {
	    UniChar lowChar = [str characterAtIndex:++i];
	    macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair(
				  (UniChar)keychar, lowChar);
	    macKC.v.virtual = NON_BMP_VIRTUAL;
	} else if (repRange.location == 0 || sendingIMEText) {
	    macKC.v.virtual = REPLACEMENT_VIRTUAL;
	} else {
	    macKC.uint = TkMacOSXAddVirtual(macKC.uint);
	    xEvent.xkey.state |= INDEX2STATE(macKC.x.xvirtual);
	}
	keystr = [[NSString alloc] initWithCharacters:&keychar length:1];
	lower = [keystr lowercaseString];
	if (![keystr isEqual: lower]) {







|

|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

	keychar = [str characterAtIndex:i];
	macKC.v.keychar = keychar;
	if (CFStringIsSurrogateHighCharacter(keychar)) {
	    UniChar lowChar = [str characterAtIndex:++i];
	    macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair(
				  (UniChar)keychar, lowChar);
	    macKC.v.virt = NON_BMP_VIRTUAL;
	} else if (repRange.location == 0 || sendingIMEText) {
	    macKC.v.virt = REPLACEMENT_VIRTUAL;
	} else {
	    macKC.uint = TkMacOSXAddVirtual(macKC.uint);
	    xEvent.xkey.state |= INDEX2STATE(macKC.x.xvirtual);
	}
	keystr = [[NSString alloc] initWithCharacters:&keychar length:1];
	lower = [keystr lowercaseString];
	if (![keystr isEqual: lower]) {
392
393
394
395
396
397
398



399
400
401
402
403
404
405
 */

- (void)setMarkedText: (id)aString
	selectedRange: (NSRange)selRange
     replacementRange: (NSRange)repRange
{
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);



    Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
    NSString *temp;
    NSString *str;
    (void)selRange;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;







>
>
>







413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
 */

- (void)setMarkedText: (id)aString
	selectedRange: (NSRange)selRange
     replacementRange: (NSRange)repRange
{
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    if (!winPtr) {
	return;
    }
    Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
    NSString *temp;
    NSString *str;
    (void)selRange;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;
600
601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
 * Set up basic fields in xevent for keyboard input.
 */

static void
setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers)
{
    unsigned int state = 0;
    Display *display = Tk_Display(tkwin);

    if (tkwin == NULL) {
	return;
    }

    if (modifiers) {
	state = (modifiers & NSAlphaShiftKeyMask ? LockMask    : 0) |
	        (modifiers & NSShiftKeyMask      ? ShiftMask   : 0) |
	        (modifiers & NSControlKeyMask    ? ControlMask : 0) |
	        (modifiers & NSCommandKeyMask    ? Mod1Mask    : 0) |
	        (modifiers & NSAlternateKeyMask  ? Mod2Mask    : 0) |
	        (modifiers & NSNumericPadKeyMask ? Mod3Mask    : 0) |







|




>







624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
 * Set up basic fields in xevent for keyboard input.
 */

static void
setupXEvent(XEvent *xEvent, Tk_Window tkwin, NSUInteger modifiers)
{
    unsigned int state = 0;
    Display *display;

    if (tkwin == NULL) {
	return;
    }
    display = Tk_Display(tkwin);
    if (modifiers) {
	state = (modifiers & NSAlphaShiftKeyMask ? LockMask    : 0) |
	        (modifiers & NSShiftKeyMask      ? ShiftMask   : 0) |
	        (modifiers & NSControlKeyMask    ? ControlMask : 0) |
	        (modifiers & NSCommandKeyMask    ? Mod1Mask    : 0) |
	        (modifiers & NSAlternateKeyMask  ? Mod2Mask    : 0) |
	        (modifiers & NSNumericPadKeyMask ? Mod3Mask    : 0) |
639
640
641
642
643
644
645
646
647
648
649
650


651
652
653

654
655
656
657
658
659
660
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    NSPoint local = [w  mouseLocationOutsideOfEventStream];
    NSPoint global = [w tkConvertPointToScreen: local];
    int win_x, win_y;

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = TkpGetOtherWindow(winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {


	    TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;
	    local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
	    local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);

	}
    } else if (winPtr->wmInfoPtr != NULL) {
	local.x -= winPtr->wmInfoPtr->xInParent;
	local.y -= winPtr->wmInfoPtr->yInParent;
    }
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    local.x = win_x;







|




>
>
|
|
|
>







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    NSPoint local = [w  mouseLocationOutsideOfEventStream];
    NSPoint global = [w tkConvertPointToScreen: local];
    int win_x, win_y;

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = (TkWindow *)Tk_GetOtherWindow(tkwin);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    MacDrawable *topMacWin = TkMacOSXGetHostToplevel(winPtr);
	    if (topMacWin) {
		TkWindow *topPtr = topMacWin->winPtr;
		local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
		local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	    }
	}
    } else if (winPtr->wmInfoPtr != NULL) {
	local.x -= winPtr->wmInfoPtr->xInParent;
	local.y -= winPtr->wmInfoPtr->yInParent;
    }
    tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    local.x = win_x;
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708



709

710
711
712
713
714
715
716
 *----------------------------------------------------------------------
 */

int
XGrabKeyboard(
    Display* display,
    Window grab_window,
    Bool owner_events,
    int pointer_mode,
    int keyboard_mode,
    Time time)
{
    keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
    TkWindow *captureWinPtr = (TkWindow *) TkpGetCapture();
    (void)owner_events;
    (void)pointer_mode;
    (void)keyboard_mode;
    (void)time;

    if (keyboardGrabWinPtr && captureWinPtr) {
	NSWindow *w = TkMacOSXGetNSWindowForDrawable(grab_window);
	MacDrawable *macWin = (MacDrawable *)grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow *) captureWinPtr) {
	    if (modalSession) {



		Tcl_Panic("XGrabKeyboard: already grabbed");

	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}
    }
    return GrabSuccess;







|
|
|
|



<
<
<
<






|
>
>
>
|
>







712
713
714
715
716
717
718
719
720
721
722
723
724
725




726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
 *----------------------------------------------------------------------
 */

int
XGrabKeyboard(
    Display* display,
    Window grab_window,
    TCL_UNUSED(Bool),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(Time))
{
    keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
    TkWindow *captureWinPtr = (TkWindow *) TkpGetCapture();





    if (keyboardGrabWinPtr && captureWinPtr) {
	NSWindow *w = TkMacOSXGetNSWindowForDrawable(grab_window);
	MacDrawable *macWin = (MacDrawable *)grab_window;

	if (w && macWin->toplevel->winPtr == (TkWindow *) captureWinPtr) {
	    if (modalSession ) {
		if (keyboardGrabNSWindow == w) {
		    return GrabSuccess;
		} else {
		    Tcl_Panic("XGrabKeyboard: already grabbed");
		}
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}
    }
    return GrabSuccess;
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
 *	Sets the keyboard focus back to the value before the grab.
 *
 *----------------------------------------------------------------------
 */

int
XUngrabKeyboard(
    Display* display,
    Time time)
{
    (void)display;
    (void)time;

    if (modalSession) {
	[NSApp endModalSession:modalSession];
	modalSession = nil;
    }
    if (keyboardGrabNSWindow) {
	[keyboardGrabNSWindow release];
	keyboardGrabNSWindow = nil;







|
|

<
<
<







758
759
760
761
762
763
764
765
766
767



768
769
770
771
772
773
774
 *	Sets the keyboard focus back to the value before the grab.
 *
 *----------------------------------------------------------------------
 */

int
XUngrabKeyboard(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Time))
{



    if (modalSession) {
	[NSApp endModalSession:modalSession];
	modalSession = nil;
    }
    if (keyboardGrabNSWindow) {
	[keyboardGrabNSWindow release];
	keyboardGrabNSWindow = nil;

Changes to macosx/tkMacOSXKeyboard.c.

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
 *
 * 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"





|
|
|
|







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 © 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"
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Prototypes for static functions used in this file.
 */

static void	InitHashTables(void);
static void     UpdateKeymaps(void);
static int	KeyDataToUnicode(UniChar *uniChars, int maxChars,
			UInt16 keyaction, UInt32 virtual, UInt32 modifiers,
			UInt32 * deadKeyStatePtr);

#pragma mark TKApplication(TKKeyboard)

@implementation TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    keyboardChanged = YES;
    UpdateKeymaps();
}
@end

#pragma mark -







|









|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Prototypes for static functions used in this file.
 */

static void	InitHashTables(void);
static void     UpdateKeymaps(void);
static int	KeyDataToUnicode(UniChar *uniChars, int maxChars,
			UInt16 keyaction, UInt32 virt, UInt32 modifiers,
			UInt32 * deadKeyStatePtr);

#pragma mark TKApplication(TKKeyboard)

@implementation TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    keyboardChanged = YES;
    UpdateKeymaps();
}
@end

#pragma mark -
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    Tcl_HashEntry *hPtr;
    const KeyInfo *kPtr;
    const KeysymInfo *ksPtr;
    int dummy, index;

    Tcl_InitHashTable(&special2keysym, TCL_ONE_WORD_KEYS);
    Tcl_InitHashTable(&keysym2keycode, TCL_ONE_WORD_KEYS);
    for (kPtr = keyArray; kPtr->virtual != 0; kPtr++) {
	MacKeycode macKC;
	macKC.v.o_s = 0;
	hPtr = Tcl_CreateHashEntry(&special2keysym, INT2PTR(kPtr->virtual),
				   &dummy);
	Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym));
	hPtr = Tcl_CreateHashEntry(&keysym2keycode, INT2PTR(kPtr->keysym),
				   &dummy);
	macKC.v.virtual = kPtr->virtual;
	macKC.v.keychar = kPtr->keychar;
	Tcl_SetHashValue(hPtr, INT2PTR(macKC.uint));

	/*
	 * The Carbon framework does not work for finding the unicode character
	 * of a special key.  But that does not depend on the keyboard layout,
	 * so we can record the information here.







|


|




|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    Tcl_HashEntry *hPtr;
    const KeyInfo *kPtr;
    const KeysymInfo *ksPtr;
    int dummy, index;

    Tcl_InitHashTable(&special2keysym, TCL_ONE_WORD_KEYS);
    Tcl_InitHashTable(&keysym2keycode, TCL_ONE_WORD_KEYS);
    for (kPtr = keyArray; kPtr->virt != 0; kPtr++) {
	MacKeycode macKC;
	macKC.v.o_s = 0;
	hPtr = Tcl_CreateHashEntry(&special2keysym, INT2PTR(kPtr->virt),
				   &dummy);
	Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym));
	hPtr = Tcl_CreateHashEntry(&keysym2keycode, INT2PTR(kPtr->keysym),
				   &dummy);
	macKC.v.virt = kPtr->virt;
	macKC.v.keychar = kPtr->keychar;
	Tcl_SetHashValue(hPtr, INT2PTR(macKC.uint));

	/*
	 * The Carbon framework does not work for finding the unicode character
	 * of a special key.  But that does not depend on the keyboard layout,
	 * so we can record the information here.
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
 */

static void
UpdateKeymaps()
{
    static Bool keymapInitialized = false;
    Tcl_HashEntry *hPtr;
    int virtual, index, dummy;

    if (!keymapInitialized) {
	Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS);
	keymapInitialized = true;
    } else {
	Tcl_DeleteHashTable(&unichar2xvirtual);
	Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS);
    }
    /*
     * This loop goes backwards so that a lookup by keychar will provide the
     * minimal modifier mask.  Simpler combinations will overwrite more complex
     * ones when constructing the table.
     */

    for (index = 3; index >= 0; index--) {
        for (virtual = 0; virtual < 128; virtual++) {
	    MacKeycode macKC;
	    macKC.v = (keycode_v) {.virtual = virtual, .o_s = index, .keychar = 0};
	    int modifiers = INDEX2CARBON(index), result;
	    UniChar keychar = 0;
	    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, virtual,
				      modifiers, NULL);
	    if (keychar == 0x10) {

		/*
		 * This is a special key, handled in InitHashTables.
		 */

		continue;
	    }
	    macKC.v.keychar = keychar;
	    if (! ON_KEYPAD(virtual)) {
		hPtr = Tcl_CreateHashEntry(&unichar2xvirtual,
					   INT2PTR(macKC.x.keychar), &dummy);
		Tcl_SetHashValue(hPtr, INT2PTR(macKC.x.xvirtual));
            }
	    xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar;
	}
    }







|















|

|
|

|










|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
 */

static void
UpdateKeymaps()
{
    static Bool keymapInitialized = false;
    Tcl_HashEntry *hPtr;
    int virt, index, dummy;

    if (!keymapInitialized) {
	Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS);
	keymapInitialized = true;
    } else {
	Tcl_DeleteHashTable(&unichar2xvirtual);
	Tcl_InitHashTable(&unichar2xvirtual, TCL_ONE_WORD_KEYS);
    }
    /*
     * This loop goes backwards so that a lookup by keychar will provide the
     * minimal modifier mask.  Simpler combinations will overwrite more complex
     * ones when constructing the table.
     */

    for (index = 3; index >= 0; index--) {
        for (virt = 0; virt < 128; virt++) {
	    MacKeycode macKC;
	    macKC.v = (keycode_v) {.virt = virt, .o_s = index, .keychar = 0};
	    int modifiers = INDEX2CARBON(index);
	    UniChar keychar = 0;
	    KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, virt,
				      modifiers, NULL);
	    if (keychar == 0x10) {

		/*
		 * This is a special key, handled in InitHashTables.
		 */

		continue;
	    }
	    macKC.v.keychar = keychar;
	    if (! ON_KEYPAD(virt)) {
		hPtr = Tcl_CreateHashEntry(&unichar2xvirtual,
					   INT2PTR(macKC.x.keychar), &dummy);
		Tcl_SetHashValue(hPtr, INT2PTR(macKC.x.xvirtual));
            }
	    xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar;
	}
    }
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336


static int
KeyDataToUnicode(
    UniChar *uniChars,
    int maxChars,
    UInt16 keyaction,
    UInt32 virtual,
    UInt32 modifiers,
    UInt32 *deadKeyStatePtr)
{
    static const void *layoutData = NULL;
    static UInt32 keyboardType = 0;
    UniCharCount actuallength = 0;








|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336


static int
KeyDataToUnicode(
    UniChar *uniChars,
    int maxChars,
    UInt16 keyaction,
    UInt32 virt,
    UInt32 modifiers,
    UInt32 *deadKeyStatePtr)
{
    static const void *layoutData = NULL;
    static UInt32 keyboardType = 0;
    UniCharCount actuallength = 0;

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
	keyboardChanged = 0;
    }
    if (layoutData) {
	OptionBits options = 0;
	UInt32 dummyState;
	OSStatus err;

	virtual &= 0xFF;
	modifiers = (modifiers >> 8) & 0xFF;
	if (!deadKeyStatePtr) {
	    options = kUCKeyTranslateNoDeadKeysMask;
	    dummyState = 0;
	    deadKeyStatePtr = &dummyState;
	}
	err = ChkErr(UCKeyTranslate, layoutData, virtual, keyaction, modifiers,
		keyboardType, options, deadKeyStatePtr, maxChars,
		&actuallength, uniChars);
	if (!actuallength && *deadKeyStatePtr) {

	    /*
	     * We are waiting for another key.
	     */







|






|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
	keyboardChanged = 0;
    }
    if (layoutData) {
	OptionBits options = 0;
	UInt32 dummyState;
	OSStatus err;

	virt &= 0xFF;
	modifiers = (modifiers >> 8) & 0xFF;
	if (!deadKeyStatePtr) {
	    options = kUCKeyTranslateNoDeadKeysMask;
	    dummyState = 0;
	    deadKeyStatePtr = &dummyState;
	}
	err = ChkErr(UCKeyTranslate, (const UCKeyboardLayout *)layoutData, virt, keyaction, modifiers,
		keyboardType, options, deadKeyStatePtr, maxChars,
		&actuallength, uniChars);
	if (!actuallength && *deadKeyStatePtr) {

	    /*
	     * We are waiting for another key.
	     */
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
    macKC.v.o_s = index;

    /*
     * First check if the virtual keycode corresponds to a special key, such as
     * an Fn function key or Tab, Backspace, Home, End, etc.
     */

    hPtr = Tcl_FindHashEntry(&special2keysym, INT2PTR(macKC.v.virtual));
    if (hPtr != NULL) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }

    /*
     * If the virtual value in this keycode does not correspond to an actual
     * key in the current keyboard layout, try using its keychar to look up a
     * keysym.
     */

    if (macKC.v.virtual > 127) {
	hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(macKC.v.keychar));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }

    /*
     * If the virtual keycode does belong to a key, use the virtual and the
     * Option-Shift from index to look up a keychar by using the Carbon
     * Framework; then translate the keychar to a keysym using the
     * unicode2keysym hash table.
     */

    modifiers = INDEX2CARBON(macKC.v.o_s);
    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, macKC.v.virtual,
			      modifiers, NULL);
    if (result) {
	hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(keychar));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }







|










|














|







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
    macKC.v.o_s = index;

    /*
     * First check if the virtual keycode corresponds to a special key, such as
     * an Fn function key or Tab, Backspace, Home, End, etc.
     */

    hPtr = Tcl_FindHashEntry(&special2keysym, INT2PTR(macKC.v.virt));
    if (hPtr != NULL) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }

    /*
     * If the virtual value in this keycode does not correspond to an actual
     * key in the current keyboard layout, try using its keychar to look up a
     * keysym.
     */

    if (macKC.v.virt > 127) {
	hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(macKC.v.keychar));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }

    /*
     * If the virtual keycode does belong to a key, use the virtual and the
     * Option-Shift from index to look up a keychar by using the Carbon
     * Framework; then translate the keychar to a keysym using the
     * unicode2keysym hash table.
     */

    modifiers = INDEX2CARBON(macKC.v.o_s);
    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, macKC.v.virt,
			      modifiers, NULL);
    if (result) {
	hPtr = Tcl_FindHashEntry(&unichar2keysym, INT2PTR(keychar));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
{
    MacKeycode macKC;
    char utfChars[8];
    int length = 0;

    macKC.uint = eventPtr->xkey.keycode;
    if (IS_PRINTABLE(macKC.v.keychar)) {
	length = TkUniCharToUtf(macKC.v.keychar, utfChars);
    }
    utfChars[length] = 0;

    Tcl_DStringInit(dsPtr);
    return Tcl_DStringAppend(dsPtr, utfChars, length);
}








|







497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
{
    MacKeycode macKC;
    char utfChars[8];
    int length = 0;

    macKC.uint = eventPtr->xkey.keycode;
    if (IS_PRINTABLE(macKC.v.keychar)) {
	length = Tcl_UniCharToUtf(macKC.v.keychar, utfChars);
    }
    utfChars[length] = 0;

    Tcl_DStringInit(dsPtr);
    return Tcl_DStringAppend(dsPtr, utfChars, length);
}

633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

    /*
     * First check for a special key.
     */

    hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym));
    if (hPtr != NULL) {
	return (KeyCode) Tcl_GetHashValue(hPtr);
    }

    /*
     * Initialize the keycode as if the keysym cannot be converted to anything
     * else.
     */

    macKC.v.virtual = NO_VIRTUAL;
    macKC.v.o_s = 0;
    macKC.v.keychar = 0;

    /*
     * If the keysym is recognized fill in the keychar.  Also fill in the
     * xvirtual field if the key exists on the current keyboard.
     */







|







|







633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

    /*
     * First check for a special key.
     */

    hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym));
    if (hPtr != NULL) {
	return (KeyCode) PTR2INT(Tcl_GetHashValue(hPtr));
    }

    /*
     * Initialize the keycode as if the keysym cannot be converted to anything
     * else.
     */

    macKC.v.virt = NO_VIRTUAL;
    macKC.v.o_s = 0;
    macKC.v.keychar = 0;

    /*
     * If the keysym is recognized fill in the keychar.  Also fill in the
     * xvirtual field if the key exists on the current keyboard.
     */
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

	if (macKC.v.o_s != eventIndex) {
	    macKC.v.o_s |= eventIndex;
	}
	if (macKC.v.keychar < 0xF700) {
	    UniChar keychar = macKC.v.keychar;
	    NSString *str, *lower, *upper;
	    if (macKC.v.virtual != NO_VIRTUAL) {
		macKC.x.keychar = xvirtual2unichar[macKC.x.xvirtual];
	    } else {
		str = [[NSString alloc] initWithCharacters:&keychar length:1];
		lower = [str lowercaseString];
		upper = [str uppercaseString];
		if (![str isEqual: lower]) {
		    macKC.v.o_s |= INDEX_SHIFT;







|







715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

	if (macKC.v.o_s != eventIndex) {
	    macKC.v.o_s |= eventIndex;
	}
	if (macKC.v.keychar < 0xF700) {
	    UniChar keychar = macKC.v.keychar;
	    NSString *str, *lower, *upper;
	    if (macKC.v.virt != NO_VIRTUAL) {
		macKC.x.keychar = xvirtual2unichar[macKC.x.xvirtual];
	    } else {
		str = [[NSString alloc] initWithCharacters:&keychar length:1];
		lower = [str lowercaseString];
		upper = [str uppercaseString];
		if (![str isEqual: lower]) {
		    macKC.v.o_s |= INDEX_SHIFT;
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
    }

    /*
     * Modifier key events have a special mac keycode (see tkProcessKeyEvent).
     */

    if (macKC.v.keychar == MOD_KEYCHAR) {
	switch (macKC.v.virtual) {
	case 54:
	    return XK_Meta_R;
	case 55:
	    return XK_Meta_L;
	case 56:
	    return XK_Shift_L;
	case 57:







|







777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
    }

    /*
     * Modifier key events have a special mac keycode (see tkProcessKeyEvent).
     */

    if (macKC.v.keychar == MOD_KEYCHAR) {
	switch (macKC.v.virt) {
	case 54:
	    return XK_Meta_R;
	case 55:
	    return XK_Meta_L;
	case 56:
	    return XK_Shift_L;
	case 57:
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

    hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&unichar2xvirtual,
					       INT2PTR(macKC.v.keychar));
    if (hPtr != NULL) {
	unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
	macKC.x.xvirtual = (unsigned int) data;
    } else {
	macKC.v.virtual = NO_VIRTUAL;
    }
    return macKC.uint;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|











949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

    hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&unichar2xvirtual,
					       INT2PTR(macKC.v.keychar));
    if (hPtr != NULL) {
	unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr);
	macKC.x.xvirtual = (unsigned int) data;
    } else {
	macKC.v.virt = NO_VIRTUAL;
    }
    return macKC.uint;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXKeysyms.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * 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
 *
 * 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






|
|
|
|
|







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 © 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 * The table includes every key listed in Apple's documentation of Function-Key
 * Unicodes which is not marked as "Not on most Macintosh keyboards", as well
 * as F20, which is reported to be usable in scripts even though it does not
 * appear on any Macintosh keyboard.
 */

typedef struct {
    int virtual;	/* value of [NSEvent keyCode] */
    KeySym keysym;	/* X11 keysym */
    KeyCode keychar;	/* XEvent keycode & 0xFFFF */
} KeyInfo;

static const KeyInfo keyArray[] = {
    {36,	XK_Return,	NSNewlineCharacter},
    {48,	XK_Tab,		NSTabCharacter},







|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 * The table includes every key listed in Apple's documentation of Function-Key
 * Unicodes which is not marked as "Not on most Macintosh keyboards", as well
 * as F20, which is reported to be usable in scripts even though it does not
 * appear on any Macintosh keyboard.
 */

typedef struct {
    int virt;	/* value of [NSEvent keyCode] */
    KeySym keysym;	/* X11 keysym */
    KeyCode keychar;	/* XEvent keycode & 0xFFFF */
} KeyInfo;

static const KeyInfo keyArray[] = {
    {36,	XK_Return,	NSNewlineCharacter},
    {48,	XK_Tab,		NSTabCharacter},

Changes to macosx/tkMacOSXMenu.c.

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.
 *
 * 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"





|
|
|
|







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 © 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"
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    ACCEL(Power,	0x233d),
    ACCEL(Eject,	0xf804),
    {NULL, 0, 0}
};
#undef ACCEL
#undef sl

static int inPostMenu = 0;
static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0;
static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0;
static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0;
static SInt16 menuSeparatorHeight = 0;

static void	CheckForSpecialMenu(TkMenu *menuPtr);
static NSString *ParseAccelerator(const char *accel, NSUInteger *maskPtr);







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    ACCEL(Power,	0x233d),
    ACCEL(Eject,	0xf804),
    {NULL, 0, 0}
};
#undef ACCEL
#undef sl

static Bool   inPostMenu = false;
static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0;
static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0;
static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0;
static SInt16 menuSeparatorHeight = 0;

static void	CheckForSpecialMenu(TkMenu *menuPtr);
static NSString *ParseAccelerator(const char *accel, NSUInteger *maskPtr);
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 * 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].
 */








|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 * 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 TKBackgroundLoop object below works around this problem, and allows a Tk
 * event loop to run while a menu is open.  It is a subclass of NSThread which
 * inserts requests to call [NSApp _runBackgroundLoop] onto the queue
 * associated with the NSEventTrackingRunLoopMode.  One of these threads gets
 * started in the callback [NSApp menuBeginTracking] and cancelled in [NSApp
 * menuEndTracking].
 */

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191







































192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    }
    [pool drain];
}
@end

TKBackgroundLoop *backgroundLoop = nil;


#pragma mark TKMenu

/*
 * This interface is not declared in tkMacOSXPrivate.h because it requires
 * tkMenu.h.
 */

@interface TKMenu(TKMenuPrivate)
- (id) initWithTkMenu: (TkMenu *) tkMenu;
- (TkMenu *) tkMenu;
- (int) tkIndexOfItem: (NSMenuItem *) menuItem;
- (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index;
@end

@implementation TKMenu
- (void) setSpecial: (NSUInteger) special
{
    NSAssert(!_tkSpecial, @"Cannot change specialness of a special menu");
    _tkSpecial = special;
}
- (BOOL) isSpecial: (NSUInteger) special
{
    return (_tkSpecial == special);
}







































@end

@implementation TKMenu(TKMenuPrivate)

- (id) initWithTitle: (NSString *) aTitle
{
    self = [super initWithTitle:aTitle];
    if (self) {
	_tkMenu = NULL;
	_tkOffset = 0;
	_tkItemCount = 0;
	_tkSpecial = 0;
	[self setDelegate:self];
    }
    return self;
}

- (id) initWithTkMenu: (TkMenu *) tkMenu
{
    NSString *title = [[NSString alloc] initWithUTF8String:
	    Tk_PathName(tkMenu->tkwin)];

    self = [self initWithTitle:title];
    [title release];
    if (self) {
	_tkMenu = tkMenu;
    }
    return self;







<










|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



















|
|







160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
    }
    [pool drain];
}
@end

TKBackgroundLoop *backgroundLoop = nil;


#pragma mark TKMenu

/*
 * This interface is not declared in tkMacOSXPrivate.h because it requires
 * tkMenu.h.
 */

@interface TKMenu(TKMenuPrivate)
- (id) initWithTkMenu: (TkMenu *) tkMenu;
- (TkMenu *) tkMenu;
- (Tcl_Size) tkIndexOfItem: (NSMenuItem *) menuItem;
- (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index;
@end

@implementation TKMenu
- (void) setSpecial: (NSUInteger) special
{
    NSAssert(!_tkSpecial, @"Cannot change specialness of a special menu");
    _tkSpecial = special;
}
- (BOOL) isSpecial: (NSUInteger) special
{
    return (_tkSpecial == special);
}

/*
 * There are cases where a KeyEquivalent (aka menu accelerator) is defined for
 * a "dead key", i.e. a key which does not have an associated character but is
 * only meant to be the start of a composition sequence.  For example, on a
 * Spanish keyboard both the ' and the ` keys are dead keys used to place
 * accents over letters.  But ⌘` is a standard KeyEquivalent which cycles
 * through the open windows of an application, changing the focus to the next
 * window. This caused a bug reported in [1626ed65b8].  When a dead key that is
 * also as a KeyEquivalent is pressed, a KeyDown event with no characters would
 * be passed to performKeyEquivalent.  The default implementation provided by
 * Apple would cause that event to be routed to some private methods of NSMenu
 * which raise NSInvalidArgumentException, causing an abort. Returning NO in
 * such a case prevents the abort.  So the override below returns NO when the
 * event has no characters.
 *
 * In fact, however, we never want to handle accelerators because they are
 * handled by Tk.  Hence this method could always return NO.  But if we did
 * that then we would not see the menu flash when an accelerator is pressed.
 * The flash is a useful visual indicator. It turns out that the flash is an
 * undocumented side effect of calling the super method for
 * performKeyEquivalent.  The super method also calls the NSMenuItem's action
 * method - tkMenuItemInvoke in our case.  This is also not documented.
 *
 * To enable the flash we set up a flag that tells the action method to do
 * nothing, because it is being called by an accelerator. The override below
 * sets the flag and then calls super. See ticket [ead70921a9].
 */

static Bool runMenuCommand = true;
- (BOOL)performKeyEquivalent:(NSEvent *)event
{
    if ([[event characters] length] == 0) {
	return NO;
    }
    runMenuCommand = false;
    /* Make the menu flash and call tkMenuItemInvoke. */
    return [super performKeyEquivalent: event];
}
@end

@implementation TKMenu(TKMenuPrivate)

- (id) initWithTitle: (NSString *) aTitle
{
    self = [super initWithTitle:aTitle];
    if (self) {
	_tkMenu = NULL;
	_tkOffset = 0;
	_tkItemCount = 0;
	_tkSpecial = 0;
	[self setDelegate:self];
    }
    return self;
}

- (id) initWithTkMenu: (TkMenu *) tkMenu
{
    NSString *title = [[TKNSString alloc] initWithTclUtfBytes:
	    Tk_PathName(tkMenu->tkwin) length:TCL_INDEX_NONE];

    self = [self initWithTitle:title];
    [title release];
    if (self) {
	_tkMenu = tkMenu;
    }
    return self;
229
230
231
232
233
234
235
236
237
238
239
240
241




242
243
244
245
246
247
248
249
250
251
252
253
    copy->_tkItemCount = _tkItemCount;
    copy->_tkSpecial = _tkSpecial;
    return copy;
}

- (TkMenu *) tkMenu
{
    return _tkMenu;
}

- (int) tkIndexOfItem: (NSMenuItem *) menuItem
{
    return [self indexOfItem:menuItem] - _tkOffset;




}

- (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index
{
    [super insertItem:newItem atIndex:index + _tkOffset];
    _tkItemCount++;
}

- (void) insertItem: (NSMenuItem *) newItem atIndex: (NSInteger) index
{
    if (_tkMenu && index >= 0) {
	if ((NSUInteger) index <= _tkOffset) {







|


|

|
>
>
>
>




|







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    copy->_tkItemCount = _tkItemCount;
    copy->_tkSpecial = _tkSpecial;
    return copy;
}

- (TkMenu *) tkMenu
{
    return (TkMenu *)_tkMenu;
}

- (Tcl_Size) tkIndexOfItem: (NSMenuItem *) menuItem
{
    NSInteger index = [self indexOfItem:menuItem];
    if (index < 0 || (NSUInteger) index < _tkOffset) {
	return TCL_INDEX_NONE;
    }
    return ((Tcl_Size)index - (Tcl_Size)_tkOffset);
}

- (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index
{
    [super insertItem:newItem atIndex:index + (NSInteger)_tkOffset];
    _tkItemCount++;
}

- (void) insertItem: (NSMenuItem *) newItem atIndex: (NSInteger) index
{
    if (_tkMenu && index >= 0) {
	if ((NSUInteger) index <= _tkOffset) {
297
298
299
300
301
302
303


304



305



306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
- (BOOL)worksWhenModal
{
    return YES;
}

- (void) tkMenuItemInvoke: (id) sender
{


    /*



     * With the delegate matching key equivalents, when a menu action is sent



     * in response to a key equivalent, the sender is the whole menu and not the

     * specific menu item.  We use this to ignore key equivalents for Tk
     * menus (as Tk handles them directly via bindings).
     */

    if ([sender isKindOfClass:[NSMenuItem class]]) {
	NSMenuItem *menuItem = (NSMenuItem *) sender;
	TkMenu *menuPtr = (TkMenu *) _tkMenu;
	TkMenuEntry *mePtr = (TkMenuEntry *) [menuItem tag];

	if (menuPtr && mePtr) {
	    Tcl_Interp *interp = menuPtr->interp;

	    /*
	     * Add time for errors to fire if necessary. This is sub-optimal
	     * but avoids issues with Tcl/Cocoa event loop integration.
	     */

	    //Tcl_Sleep(100);
	    Tcl_Preserve(interp);
	    Tcl_Preserve(menuPtr);

	    int result = TkInvokeMenu(interp, menuPtr, mePtr->index);

	    if (result != TCL_OK && result != TCL_CONTINUE &&
		    result != TCL_BREAK) {
		Tcl_AddErrorInfo(interp, "\n    (menu invoke)");
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(menuPtr);
	    Tcl_Release(interp);







>
>
|
>
>
>
|
>
>
>
|
>
|
<









<
<
<
<
<
<
<


<

<







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367







368
369

370

371
372
373
374
375
376
377
- (BOOL)worksWhenModal
{
    return YES;
}

- (void) tkMenuItemInvoke: (id) sender
{
    if (!runMenuCommand) {

    	/*
    	 * We are being called for a menu accelerator.  Tk will handle it.
    	 * Just update the runMenuCommand flag.
    	 */

    	runMenuCommand = true;
    	return;
    }

    /*
     * We are being called for an actual menu item selection; run the command.

     */

    if ([sender isKindOfClass:[NSMenuItem class]]) {
	NSMenuItem *menuItem = (NSMenuItem *) sender;
	TkMenu *menuPtr = (TkMenu *) _tkMenu;
	TkMenuEntry *mePtr = (TkMenuEntry *) [menuItem tag];

	if (menuPtr && mePtr) {
	    Tcl_Interp *interp = menuPtr->interp;







	    Tcl_Preserve(interp);
	    Tcl_Preserve(menuPtr);

	    int result = TkInvokeMenu(interp, menuPtr, mePtr->index);

	    if (result != TCL_OK && result != TCL_CONTINUE &&
		    result != TCL_BREAK) {
		Tcl_AddErrorInfo(interp, "\n    (menu invoke)");
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(menuPtr);
	    Tcl_Release(interp);
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
}

- (void) menuDidClose: (NSMenu *) menu
{
    (void)menu;

    if (_tkMenu) {
	RecursivelyClearActiveMenu(_tkMenu);
    }
}

- (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item
{
    (void)menu;








|







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
}

- (void) menuDidClose: (NSMenu *) menu
{
    (void)menu;

    if (_tkMenu) {
	RecursivelyClearActiveMenu((TkMenu *)_tkMenu);
    }
}

- (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item
{
    (void)menu;

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471




472

473
474
475
476
477
478
479
480
481
482
483
484
485
486

    if (menuPtr) {
	Tcl_Interp *interp = menuPtr->interp;

	Tcl_Preserve(interp);
	Tcl_Preserve(menuPtr);

	int result = TkPostCommand(_tkMenu);

	if (result!=TCL_OK && result!=TCL_CONTINUE && result!=TCL_BREAK) {
	      Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
	      Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(menuPtr);
	Tcl_Release(interp);
    }
}
@end

#pragma mark TKApplication(TKMenu)

@implementation TKApplication(TKMenu)

- (void) menuBeginTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
    }
    backgroundLoop = [[TKBackgroundLoop alloc] init];
    [backgroundLoop start];
    //TkMacOSXClearMenubarActive();




    //TkMacOSXPreprocessMenu();

}

- (void) menuEndTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
	backgroundLoop = nil;
    }
    if (!inPostMenu) {







|



















|







|
>
>
>
>
|
>






|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

    if (menuPtr) {
	Tcl_Interp *interp = menuPtr->interp;

	Tcl_Preserve(interp);
	Tcl_Preserve(menuPtr);

	int result = TkPostCommand(menuPtr);

	if (result!=TCL_OK && result!=TCL_CONTINUE && result!=TCL_BREAK) {
	      Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
	      Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(menuPtr);
	Tcl_Release(interp);
    }
}
@end

#pragma mark TKApplication(TKMenu)

@implementation TKApplication(TKMenu)

- (void) menuBeginTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
    }
    backgroundLoop = [[TKBackgroundLoop alloc] init];
    [backgroundLoop start];

    /*
     * Make sure that we can run commands when actually using a menu.
     * See [412b80fcaf].
     */

    runMenuCommand = true;
}

- (void) menuEndTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
	backgroundLoop = nil;
    }
    if (!inPostMenu) {
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733

734





735
736












737
738

739
740
741


742
743
744
745

746
747


748

749


750

751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    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);
    static unsigned long defaultBg, defaultFg;
    static int initialized = 0;

    if (!initialized) {
	TkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
	defaultBg = tkColPtr->color.pixel;
	ckfree(tkColPtr);
	tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
	defaultFg = tkColPtr->color.pixel;
	ckfree(tkColPtr);
    }

    if (mePtr->image) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	image = TkMacOSXGetNSImageFromTkImage(mePtr->menuPtr->display,
		mePtr->image, imageWidth, imageHeight);
    } else if (mePtr->bitmapPtr != None) {
	Pixmap bitmap = Tk_GetBitmapFromObj(mePtr->menuPtr->tkwin,
		mePtr->bitmapPtr);

	Tk_SizeOfBitmap(mePtr->menuPtr->display, bitmap, &imageWidth,
		&imageHeight);
	image = TkMacOSXGetNSImageFromBitmap(mePtr->menuPtr->display, bitmap,
		gc, imageWidth, imageHeight);
	if (gc->foreground == defaultFg) {
	    [image setTemplate:YES];
	}
    }
    [menuItem setImage:image];
    if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
	    mePtr->labelLength) {

	title = [[[NSString alloc] initWithBytes:Tcl_GetString(mePtr->labelPtr)
		length:mePtr->labelLength encoding:NSUTF8StringEncoding]
		autorelease];
	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);

	    attributes = [[attributes mutableCopy] autorelease];


	    [(NSMutableDictionary *) attributes setObject:color
		    forKey:NSForegroundColorAttributeName];
	}
	if (attributes) {

	    attributedTitle = [[[NSAttributedString alloc]
		    initWithString:title attributes:attributes] autorelease];


	}

    }


    [menuItem setAttributedTitle:attributedTitle];

    [menuItem setEnabled:!(mePtr->state == ENTRY_DISABLED)];
    [menuItem setState:((mePtr->type == CHECK_BUTTON_ENTRY ||
	    mePtr->type == RADIO_BUTTON_ENTRY) && mePtr->indicatorOn &&
	    (mePtr->entryFlags & ENTRY_SELECTED) ? NSOnState : NSOffState)];
    if (mePtr->type != CASCADE_ENTRY && mePtr->accelPtr && mePtr->accelLength) {
	keyEquivalent = ParseAccelerator(Tcl_GetString(mePtr->accelPtr),
		&modifierMask);
    }
    [menuItem setKeyEquivalent:keyEquivalent];
    [menuItem setKeyEquivalentModifierMask:modifierMask];
    if (mePtr->type == CASCADE_ENTRY && mePtr->namePtr) {
	TkMenuReferences *menuRefPtr;

	menuRefPtr = TkFindMenuReferencesObj(mePtr->menuPtr->interp,
		mePtr->namePtr);
	if (menuRefPtr && menuRefPtr->menuPtr) {
	    CheckForSpecialMenu(menuRefPtr->menuPtr);
	    submenu = (TKMenu *) menuRefPtr->menuPtr->platformData;
	    if ([submenu supermenu] && [menuItem submenu] != submenu) {
		/*
		 * This happens during a clone, where the parent menu is
		 * cloned before its children, so just ignore this temprary
		 * setting, it will be changed shortly (c.f. tkMenu.c
		 * CloneMenu())
		 */

		submenu = nil;
	    } else {
		[submenu setTitle:title];

    		if ([menuItem isEnabled]) {

		    /*
		     * This menuItem might have been previously disabled (XXX:
		     * track this), which would have disabled entries; we must
		     * re-enable the entries here.


		     */

		    int i = 0;
		    NSArray *itemArray = [submenu itemArray];

		    for (NSMenuItem *item in itemArray) {
			TkMenuEntry *submePtr = menuRefPtr->menuPtr->entries[i];

			/*
			 * Work around an apparent bug where itemArray can have
			 * more items than the menu's entries[] array.
			 */

			if (i >= (int) menuRefPtr->menuPtr->numEntries) {
			    break;
			}
			[item setEnabled: !(submePtr->state == ENTRY_DISABLED)];
			i++;
		    }
		}
	    }
	}
    }
    [menuItem setSubmenu:submenu];








<




<




<


<







|







<
|
<




>
|
|







|
>
|
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
|
|
<
>
>
|
|
|
|
>
|
<
>
>
|
>
|
>
>

>
|




















|











|
|
|
>
>


<
<
|
<

|
<
<
<
<
<
<
<
<
|
<







727
728
729
730
731
732
733

734
735
736
737

738
739
740
741

742
743

744
745
746
747
748
749
750
751
752
753
754
755
756
757
758

759

760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    NSMenuItem *menuItem = (NSMenuItem *) mePtr->platformEntryData;
    NSString *title = @"";
    NSAttributedString *attributedTitle = nil;
    NSImage *image = nil;
    NSString *keyEquivalent = @"";
    NSUInteger modifierMask = NSCommandKeyMask;
    NSMenu *submenu = nil;

    int imageWidth, imageHeight;
    GC gc = (mePtr->textGC ? mePtr->textGC : mePtr->menuPtr->textGC);
    Tcl_Obj *fontPtr = (mePtr->fontPtr ?
			mePtr->fontPtr : mePtr->menuPtr->fontPtr);

    static int initialized = 0;

    if (!initialized) {
	TkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);

	ckfree(tkColPtr);
	tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);

	ckfree(tkColPtr);
    }

    if (mePtr->image) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	image = TkMacOSXGetNSImageFromTkImage(mePtr->menuPtr->display,
		mePtr->image, imageWidth, imageHeight);
    } else if (mePtr->bitmapPtr != NULL) {
	Pixmap bitmap = Tk_GetBitmapFromObj(mePtr->menuPtr->tkwin,
		mePtr->bitmapPtr);

	Tk_SizeOfBitmap(mePtr->menuPtr->display, bitmap, &imageWidth,
		&imageHeight);
	image = TkMacOSXGetNSImageFromBitmap(mePtr->menuPtr->display, bitmap,
		gc, imageWidth, imageHeight);

	[image setTemplate:YES];

    }
    [menuItem setImage:image];
    if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
	    mePtr->labelLength) {
	title = [[[TKNSString alloc]
		    initWithTclUtfBytes:Tcl_GetString(mePtr->labelPtr)
				length:mePtr->labelLength]
		autorelease];
	if ([title hasSuffix:@"..."]) {
	    title = [NSString stringWithFormat:@"%@%C",
		    [title substringToIndex:[title length] - 3], 0x2026];
	}
    }
    [menuItem setTitle:title];

#if 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];
    }

    if (gc->background != defaultBg) {
	NSColor *bgcolor = TkMacOSXGetNSColor(gc, gc->background);
	[attributes setObject:bgcolor
	 	       forKey:NSBackgroundColorAttributeName];
    }

#else


    NSDictionary *attributes = TkMacOSXNSFontAttributesForFont(
	Tk_GetFontFromObj(mePtr->menuPtr->tkwin, fontPtr));

#endif

    attributedTitle = [[NSAttributedString alloc] initWithString:title
	attributes:attributes];
    [menuItem setAttributedTitle:attributedTitle];
    [attributedTitle release];
    [menuItem setEnabled:(mePtr->state != ENTRY_DISABLED)];
    [menuItem setState:((mePtr->type == CHECK_BUTTON_ENTRY ||
	    mePtr->type == RADIO_BUTTON_ENTRY) && mePtr->indicatorOn &&
	    (mePtr->entryFlags & ENTRY_SELECTED) ? NSOnState : NSOffState)];
    if (mePtr->type != CASCADE_ENTRY && mePtr->accelPtr && mePtr->accelLength) {
	keyEquivalent = ParseAccelerator(Tcl_GetString(mePtr->accelPtr),
		&modifierMask);
    }
    [menuItem setKeyEquivalent:keyEquivalent];
    [menuItem setKeyEquivalentModifierMask:modifierMask];
    if (mePtr->type == CASCADE_ENTRY && mePtr->namePtr) {
	TkMenuReferences *menuRefPtr;

	menuRefPtr = TkFindMenuReferencesObj(mePtr->menuPtr->interp,
		mePtr->namePtr);
	if (menuRefPtr && menuRefPtr->menuPtr) {
	    CheckForSpecialMenu(menuRefPtr->menuPtr);
	    submenu = (TKMenu *) menuRefPtr->menuPtr->platformData;
	    if ([submenu supermenu] && [menuItem submenu] != submenu) {
		/*
		 * This happens during a clone, where the parent menu is
		 * cloned before its children, so just ignore this temporary
		 * setting, it will be changed shortly (c.f. tkMenu.c
		 * CloneMenu())
		 */

		submenu = nil;
	    } else {
		[submenu setTitle:title];

    		if ([menuItem isEnabled]) {

		    /*
		     * This menuItem might have been previously disabled 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].
		     */



		    for (Tcl_Size i = 0; i < menuRefPtr->menuPtr->numEntries; i++) {

			TkMenuEntry *submePtr = menuRefPtr->menuPtr->entries[i];
			NSMenuItem *item = (NSMenuItem *) submePtr->platformEntryData;








			[item setEnabled:(submePtr->state != ENTRY_DISABLED)];

		    }
		}
	    }
	}
    }
    [menuItem setSubmenu:submenu];

832
833
834
835
836
837
838
839
840
841


842
843
844
845
846


847
848
849
850
851
852
853
TkpDestroyMenuEntry(
    TkMenuEntry *mePtr)
{
    NSMenuItem *menuItem;
    TKMenu *menu;
    NSInteger index;

    if (mePtr->platformEntryData && mePtr->menuPtr->platformData) {
	menu = (TKMenu *) mePtr->menuPtr->platformData;
	menuItem = (NSMenuItem *) mePtr->platformEntryData;


	index = [menu indexOfItem:menuItem];

	if (index > -1) {
	    [menu removeItemAtIndex:index];
	}


	[menuItem release];
	mePtr->platformEntryData = NULL;
    }
}

/*
 *----------------------------------------------------------------------







|
<

>
>
|

|
|
|
>
>







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
TkpDestroyMenuEntry(
    TkMenuEntry *mePtr)
{
    NSMenuItem *menuItem;
    TKMenu *menu;
    NSInteger index;

    if (mePtr->platformEntryData) {

	menuItem = (NSMenuItem *) mePtr->platformEntryData;
	if (mePtr->menuPtr->platformData) {
	    menu = (TKMenu *) mePtr->menuPtr->platformData;
	    index = [menu indexOfItem:menuItem];

	    if (index > -1) {
		[menu removeItemAtIndex:index];
	    }
	}
	[menuItem setTag:(NSInteger) NULL];
	[menuItem release];
	mePtr->platformEntryData = NULL;
    }
}

/*
 *----------------------------------------------------------------------
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
int
TkpPostMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y,		/* The screen coordinates where the top left
				 * corner of the menu, or of the specified
				 * entry, will be located. */
    int index)
{
    int result;
    Tk_Window realWin = menuPtr->tkwin;
    TkWindow *realWinPtr;
    NSView *realWinView;

    while (1) {







|







931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
int
TkpPostMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y,		/* The screen coordinates where the top left
				 * corner of the menu, or of the specified
				 * entry, will be located. */
    Tcl_Size index)
{
    int result;
    Tk_Window realWin = menuPtr->tkwin;
    TkWindow *realWinPtr;
    NSView *realWinView;

    while (1) {
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
    NSView *view = [win contentView];
    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSInteger itemIndex = index;
    NSInteger numItems = [menu numberOfItems];
    NSMenuItem *item = nil;
    NSPoint location = NSMakePoint(x, TkMacOSXZeroScreenHeight() - y);

    inPostMenu = 1;
    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
        inPostMenu = 0;
        return result;
    }
    if (itemIndex >= numItems) {
    	itemIndex = numItems - 1;
    }
    if (itemIndex >= 0) {
	item = [menu itemAtIndex:itemIndex];







|


|







964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
    NSView *view = [win contentView];
    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSInteger itemIndex = index;
    NSInteger numItems = [menu numberOfItems];
    NSMenuItem *item = nil;
    NSPoint location = NSMakePoint(x, TkMacOSXZeroScreenHeight() - y);

    inPostMenu = true;
    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
        inPostMenu = false;
        return result;
    }
    if (itemIndex >= numItems) {
    	itemIndex = numItems - 1;
    }
    if (itemIndex >= 0) {
	item = [menu itemAtIndex:itemIndex];
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    [menu popUpMenuPositioningItem:item
			atLocation:[win tkConvertPointFromScreen:location]
			    inView:view];
    inPostMenu = 0;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostTearoffMenu --







|







989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    [menu popUpMenuPositioningItem:item
			atLocation:[win tkConvertPointFromScreen:location]
			    inView:view];
    inPostMenu = false;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostTearoffMenu --
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
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),	/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, int index)	/* The screen coordinates where the top left
				 * corner of the menu, or of the specified
				 * entry, will be located. */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;

    if (index >= (int) menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }













    /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 1. If a virtual root window manager is being used then the coordinates
     *    are in the virtual root window of menuPtr's parent; since the menu







|






<
<
<
<
<
<
<
|














>
>
>
>
>
>
>
>
>
>
>
>







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
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),	/* The interpreter this menu lives in */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, Tcl_Size index)	/* The screen coordinates where the top left
				 * corner of the menu, or of the specified
				 * entry, will be located. */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;








    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*
     * Adjust the menu y position so that the specified entry will be located
     * at the given coordinates.
     */

    if (index < 0 || index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 1. If a virtual root window manager is being used then the coordinates
     *    are in the virtual root window of menuPtr's parent; since the menu
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
	winPtr->wmInfoPtr->menuPtr = menuPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetMainMenubar --
 *
 *	Puts the menu associated with a window into the menubar. Should only be
 *	called when the window is in front.
 *
 *      This is a no-op on all other platforms.  On OS X it is a no-op when
 *      passed a NULL menuName or a nonexistent menuName, with an exception for
 *      the first call in a new interpreter.  In that special case, passing a
 *      NULL menuName installs the default menu.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menubar may be changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    const char *menuName)	/* The name of the menu to put in front. */
{
    static Tcl_Interp *currentInterp = NULL;
    TKMenu *menu = nil;
    TkWindow *winPtr = (TkWindow *) tkwin;







|



















|







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
	winPtr->wmInfoPtr->menuPtr = menuPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetMainMenubar --
 *
 *	Puts the menu associated with a window into the menubar. Should only be
 *	called when the window is in front.
 *
 *      This is a no-op on all other platforms.  On OS X it is a no-op when
 *      passed a NULL menuName or a nonexistent menuName, with an exception for
 *      the first call in a new interpreter.  In that special case, passing a
 *      NULL menuName installs the default menu.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menubar may be changed.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    const char *menuName)	/* The name of the menu to put in front. */
{
    static Tcl_Interp *currentInterp = NULL;
    TKMenu *menu = nil;
    TkWindow *winPtr = (TkWindow *) tkwin;
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
	if (cascadeEntryPtr->menuPtr->menuType == MENUBAR
		&& cascadeEntryPtr->menuPtr->mainMenuPtr->tkwin) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->mainMenuPtr;
	    int i = 0;
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, Tk_PathName(mainMenuPtr->tkwin), -1);
	    while (specialMenus[i].name) {
		Tcl_DStringAppend(&ds, specialMenus[i].name,
			specialMenus[i].len);
		if (strcmp(Tcl_DStringValue(&ds),
			Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		    cascadeEntryPtr->entryFlags |= specialMenus[i].flag;
		} else {







|







1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
	if (cascadeEntryPtr->menuPtr->menuType == MENUBAR
		&& cascadeEntryPtr->menuPtr->mainMenuPtr->tkwin) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->mainMenuPtr;
	    int i = 0;
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, Tk_PathName(mainMenuPtr->tkwin), TCL_INDEX_NONE);
	    while (specialMenus[i].name) {
		Tcl_DStringAppend(&ds, specialMenus[i].name,
			specialMenus[i].len);
		if (strcmp(Tcl_DStringValue(&ds),
			Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		    cascadeEntryPtr->entryFlags |= specialMenus[i].flag;
		} else {
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
    size_t len;
    int i;

    *maskPtr = 0;
    while (1) {
	i = 0;
	while (allModifiers[i].name) {
	    int l = allModifiers[i].len;

	    if (!strncasecmp(accel, allModifiers[i].name, l) &&
		    (accel[l] == '-' || accel[l] == '+')) {
		*maskPtr |= allModifiers[i].mask;
		accel += l+1;
		break;
	    }







|







1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
    size_t len;
    int i;

    *maskPtr = 0;
    while (1) {
	i = 0;
	while (allModifiers[i].name) {
	    size_t l = allModifiers[i].len;

	    if (!strncasecmp(accel, allModifiers[i].name, l) &&
		    (accel[l] == '-' || accel[l] == '+')) {
		*maskPtr |= allModifiers[i].mask;
		accel += l+1;
		break;
	    }
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
	    }
	    i++;
	}
    }
    if (ch) {
	return [[[NSString alloc] initWithCharacters:&ch length:1] autorelease];
    } else {
	return [[[[NSString alloc] initWithUTF8String:accel] autorelease]
		lowercaseString];
    }
}

/*
 *--------------------------------------------------------------
 *
 * ModifierCharWidth --
 *
 *	Helper mesuring width of command char in given font.
 *
 * Results:
 *	Width of command char.
 *
 * Side effects:
 *	None.
 *







|









|







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
	    }
	    i++;
	}
    }
    if (ch) {
	return [[[NSString alloc] initWithCharacters:&ch length:1] autorelease];
    } else {
	return [[[[TKNSString alloc] initWithTclUtfBytes:accel length:TCL_INDEX_NONE] autorelease]
		lowercaseString];
    }
}

/*
 *--------------------------------------------------------------
 *
 * ModifierCharWidth --
 *
 *	Helper measuring width of command char in given font.
 *
 * Results:
 *	Width of command char.
 *
 * Side effects:
 *	None.
 *
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348

void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    NSSize menuSize;
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int modifierCharWidth, menuModifierCharWidth;
    int x, y, modifierWidth, labelWidth, indicatorSpace;
    int windowWidth, windowHeight, accelWidth;
    int i, maxWidth;
    int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
    TkMenuEntry *mePtr;
    int haveAccel = 0;

    /*
     * Do nothing if this menu is a clone.
     */







|


|
|







1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413

void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    NSSize menuSize;
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics;
    int modifierCharWidth, menuModifierCharWidth;
    int x, y, modifierWidth, labelWidth, indicatorSpace;
    int windowWidth, maxWidth, windowHeight, accelWidth;
    Tcl_Size i;
    int entryWidth, maxIndicatorSpace, borderWidth, activeBorderWidth;
    TkMenuEntry *mePtr;
    int haveAccel = 0;

    /*
     * Do nothing if this menu is a clone.
     */
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
     * give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    menuModifierCharWidth = ModifierCharWidth(menuFont);

    for (i = 0; i < (int) menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == CASCADE_ENTRY || mePtr->accelLength > 0) {
	    haveAccel = 1;
	    break;
	}
    }

    for (i = 0; i < (int) menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == TEAROFF_ENTRY) {
	    continue;
	}
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	    modifierCharWidth = menuModifierCharWidth;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
	    fmPtr = &entryMetrics;
	    modifierCharWidth = ModifierCharWidth(tkfont);
	}
	accelWidth = modifierWidth = indicatorSpace = 0;
	if (mePtr->type == SEPARATOR_ENTRY) {
	    mePtr->height = menuSeparatorHeight;
	} else {
	    /*







|







|






<




<







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
     * give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    menuModifierCharWidth = ModifierCharWidth(menuFont);

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == CASCADE_ENTRY || mePtr->accelLength > 0) {
	    haveAccel = 1;
	    break;
	}
    }

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->type == TEAROFF_ENTRY) {
	    continue;
	}
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;

	    modifierCharWidth = menuModifierCharWidth;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);

	    modifierCharWidth = ModifierCharWidth(tkfont);
	}
	accelWidth = modifierWidth = indicatorSpace = 0;
	if (mePtr->type == SEPARATOR_ENTRY) {
	    mePtr->height = menuSeparatorHeight;
	} else {
	    /*
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
GenerateMenuSelectEvent(
    TKMenu *menu,
    NSMenuItem *menuItem)
{
    TkMenu *menuPtr = [menu tkMenu];

    if (menuPtr) {
	int index = [menu tkIndexOfItem:menuItem];

	if (index < 0 || index >= (int) menuPtr->numEntries ||
		(menuPtr->entries[index])->state == ENTRY_DISABLED) {
	    TkActivateMenuEntry(menuPtr, -1);
	} else {
	    TkActivateMenuEntry(menuPtr, index);
	    MenuSelectEvent(menuPtr);
	    return true;
	}
    }
    return false;







|

|

|







1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
GenerateMenuSelectEvent(
    TKMenu *menu,
    NSMenuItem *menuItem)
{
    TkMenu *menuPtr = [menu tkMenu];

    if (menuPtr) {
	Tcl_Size index = [menu tkIndexOfItem:menuItem];

	if (index < 0 || index >= menuPtr->numEntries ||
		(menuPtr->entries[index])->state == ENTRY_DISABLED) {
	    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
	} else {
	    TkActivateMenuEntry(menuPtr, index);
	    MenuSelectEvent(menuPtr);
	    return true;
	}
    }
    return false;
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
 *----------------------------------------------------------------------
 */

void
MenuSelectEvent(
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    XVirtualEvent event;

    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(menuPtr->display);
    event.send_event = false;
    event.display = menuPtr->display;
    event.event = Tk_WindowId(menuPtr->tkwin);
    event.root = XRootWindow(menuPtr->display, 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, None, NULL, NULL, &event.x_root, &event.y_root, NULL,
	    NULL, &event.state);
    event.same_screen = true;
    event.name = Tk_GetUid("MenuSelect");
    Tk_MakeWindowExist(menuPtr->tkwin);
    if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
	Tk_HandleEvent((XEvent *) &event);
    } else {
	Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RecursivelyClearActiveMenu --







|

|
|
|
|
|
|
|
|
|
|
|
|
|


|

|







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
 *----------------------------------------------------------------------
 */

void
MenuSelectEvent(
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    union {XEvent general; XVirtualEvent virt;} event;

    bzero(&event, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(menuPtr->display);
    event.virt.send_event = false;
    event.virt.display = menuPtr->display;
    event.virt.event = Tk_WindowId(menuPtr->tkwin);
    event.virt.root = XRootWindow(menuPtr->display, 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();
    XQueryPointer(NULL, None, NULL, NULL, &event.virt.x_root, &event.virt.y_root, NULL,
	    NULL, &event.virt.state);
    event.virt.same_screen = true;
    event.virt.name = Tk_GetUid("MenuSelect");
    Tk_MakeWindowExist(menuPtr->tkwin);
    if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
	Tk_HandleEvent(&event.general);
    } else {
	Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RecursivelyClearActiveMenu --
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    int i;

    TkActivateMenuEntry(menuPtr, -1);
    for (i = 0; i < (int) menuPtr->numEntries; i++) {
	TkMenuEntry *mePtr = menuPtr->entries[i];

	if (mePtr->type == CASCADE_ENTRY
		&& (mePtr->childMenuRefPtr != NULL)
		&& (mePtr->childMenuRefPtr->menuPtr != NULL)) {
	    RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
	}







|

|
|







1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    Tcl_Size i;

    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
    for (i = 0; i < menuPtr->numEntries; i++) {
	TkMenuEntry *mePtr = menuPtr->entries[i];

	if (mePtr->type == CASCADE_ENTRY
		&& (mePtr->childMenuRefPtr != NULL)
		&& (mePtr->childMenuRefPtr->menuPtr != NULL)) {
	    RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
	}
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
 *
 *----------------------------------------------------------------------
 */

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







<
<







1733
1734
1735
1736
1737
1738
1739


1740
1741
1742
1743
1744
1745
1746
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuInit(void)
{


    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:NSApp selector:@selector(s) name:(n) object:nil]
    observe(NSMenuDidBeginTrackingNotification, menuBeginTracking:);
    observe(NSMenuDidEndTrackingNotification, menuEndTracking:);
#undef observe
1811
1812
1813
1814
1815
1816
1817
1818




1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawMenuEntry --
 *
 *	Draws the given menu entry at the given coordinates with the given
 *	attributes.




 *
 * Results:
 *	None.
 *
 * Side effects:
 *	X Server commands are executed to display the menu entry.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawMenuEntry(
    TCL_UNUSED(TkMenuEntry *),		/* The entry to draw */







|
>
>
>
>





|







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

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawMenuEntry --
 *
 *	Draws the given menu entry at the given coordinates with the given
 *	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:
 *	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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include "tkMacOSXPrivate.h"






|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkMacOSXMenubutton.c --
 *
 *	This file implements the Macintosh specific portion of the menubutton
 *	widget.
 *
 * Copyright © 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"
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    DrawParams drawParams;
} MacMenuButton;

/*
 * Forward declarations for static functions defined later in this file:
 */

static void		MenuButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		MenuButtonBackgroundDrawCB(MacMenuButton *ptr,
			    SInt16 depth, Boolean isColorDev);
static void		MenuButtonContentDrawCB(ThemeButtonKind kind,
			    const HIThemeButtonDrawInfo *info,
			    MacMenuButton *ptr, SInt16 depth,
			    Boolean isColorDev);
static void		MenuButtonEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		TkMacOSXComputeMenuButtonParams(TkMenuButton *butPtr,
			    ThemeButtonKind *btnkind,
			    HIThemeButtonDrawInfo *drawinfo);
static void		TkMacOSXComputeMenuButtonDrawParams(
			    TkMenuButton *butPtr, DrawParams *dpPtr);
static void		TkMacOSXDrawMenuButton(MacMenuButton *butPtr, GC gc,







|







|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    DrawParams drawParams;
} MacMenuButton;

/*
 * Forward declarations for static functions defined later in this file:
 */

static void		MenuButtonEventProc(void *clientData,
			    XEvent *eventPtr);
static void		MenuButtonBackgroundDrawCB(MacMenuButton *ptr,
			    SInt16 depth, Boolean isColorDev);
static void		MenuButtonContentDrawCB(ThemeButtonKind kind,
			    const HIThemeButtonDrawInfo *info,
			    MacMenuButton *ptr, SInt16 depth,
			    Boolean isColorDev);
static void		MenuButtonEventProc(void *clientData,
			    XEvent *eventPtr);
static void		TkMacOSXComputeMenuButtonParams(TkMenuButton *butPtr,
			    ThemeButtonKind *btnkind,
			    HIThemeButtonDrawInfo *drawinfo);
static void		TkMacOSXComputeMenuButtonDrawParams(
			    TkMenuButton *butPtr, DrawParams *dpPtr);
static void		TkMacOSXDrawMenuButton(MacMenuButton *butPtr, GC gc,
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 *	Commands are output to X to display the menubutton in its current mode.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    MacMenuButton *mbPtr = clientData;
    TkMenuButton *butPtr = clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams *dpPtr = &mbPtr->drawParams;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;







|

|
|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 *	Commands are output to X to display the menubutton in its current mode.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    void *clientData)	/* Information about widget. */
{
    MacMenuButton *mbPtr = (MacMenuButton *)clientData;
    TkMenuButton *butPtr = (TkMenuButton *)clientData;
    Tk_Window tkwin = butPtr->tkwin;
    Pixmap pixmap;
    DrawParams *dpPtr = &mbPtr->drawParams;

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
        return;
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 * Side effects:
 *	The menu button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeMenuButtonGeometry(butPtr)
    TkMenuButton *butPtr;	/* Widget record for menu button. */
{
    int width, height, avgWidth, haveImage = 0, haveText = 0;
    int txtWidth, txtHeight;
    Tk_FontMetrics fm;
    int highlightWidth = butPtr->highlightWidth > 0 ? butPtr->highlightWidth : 0;

    /*







|
|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 * Side effects:
 *	The menu button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeMenuButtonGeometry(
    TkMenuButton *butPtr)	/* Widget record for menu button. */
{
    int width, height, avgWidth, haveImage = 0, haveText = 0;
    int txtWidth, txtHeight;
    Tk_FontMetrics fm;
    int highlightWidth = butPtr->highlightWidth > 0 ? butPtr->highlightWidth : 0;

    /*
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
        haveImage = 1;
    }

    if (butPtr->text && strlen(butPtr->text) > 0) {
	haveText = 1;
        Tk_FreeTextLayout(butPtr->textLayout);
        butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
                butPtr->text, -1, butPtr->wrapLength,
                butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
        txtWidth = butPtr->textWidth;
        txtHeight = butPtr->textHeight;
        avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
        Tk_GetFontMetrics(butPtr->tkfont, &fm);
    }








|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
        haveImage = 1;
    }

    if (butPtr->text && strlen(butPtr->text) > 0) {
	haveText = 1;
        Tk_FreeTextLayout(butPtr->textLayout);
        butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
                butPtr->text, TCL_INDEX_NONE, butPtr->wrapLength,
                butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);
        txtWidth = butPtr->textWidth;
        txtHeight = butPtr->textHeight;
        avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
        Tk_GetFontMetrics(butPtr->tkfont, &fm);
    }

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
DrawMenuButtonImageAndText(
    TkMenuButton *butPtr)
{
    MacMenuButton *mbPtr = (MacMenuButton *) butPtr;
    Tk_Window tkwin  = butPtr->tkwin;
    Pixmap pixmap;
    int haveImage = 0, haveText = 0;
    int imageWidth = 0, imageHeight = 0;
    int imageXOffset = 0, imageYOffset = 0;
    int textXOffset = 0, textYOffset = 0;
    int width = 0, height = 0;
    int fullWidth = 0, fullHeight = 0;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    DrawParams *dpPtr = &mbPtr->drawParams;
    pixmap = (Pixmap) Tk_WindowId(tkwin);

    if (butPtr->image != NULL) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }

    imageWidth = width;
    imageHeight = height;

    haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
        int x = 0, y = 0;

        textXOffset = 0;
        textYOffset = 0;
        fullWidth = 0;







<




















<
<
<







371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397



398
399
400
401
402
403
404
DrawMenuButtonImageAndText(
    TkMenuButton *butPtr)
{
    MacMenuButton *mbPtr = (MacMenuButton *) butPtr;
    Tk_Window tkwin  = butPtr->tkwin;
    Pixmap pixmap;
    int haveImage = 0, haveText = 0;

    int imageXOffset = 0, imageYOffset = 0;
    int textXOffset = 0, textYOffset = 0;
    int width = 0, height = 0;
    int fullWidth = 0, fullHeight = 0;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    DrawParams *dpPtr = &mbPtr->drawParams;
    pixmap = (Pixmap) Tk_WindowId(tkwin);

    if (butPtr->image != NULL) {
        Tk_SizeOfImage(butPtr->image, &width, &height);
        haveImage = 1;
    } else if (butPtr->bitmap != None) {
        Tk_SizeOfBitmap(butPtr->display, butPtr->bitmap, &width, &height);
        haveImage = 1;
    }




    haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);
    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
        int x = 0, y = 0;

        textXOffset = 0;
        textYOffset = 0;
        fullWidth = 0;
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *buttonPtr = clientData;
    MacMenuButton *mbPtr = clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {







|


|
|







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MenuButtonEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *buttonPtr = (TkMenuButton *)clientData;
    MacMenuButton *mbPtr = (MacMenuButton *)clientData;

    if (eventPtr->type == ActivateNotify
	    || eventPtr->type == DeactivateNotify) {
	if ((buttonPtr->tkwin == NULL) || (!Tk_IsMapped(buttonPtr->tkwin))) {
	    return;
	}
	if (eventPtr->type == ActivateNotify) {

Changes to macosx/tkMacOSXMenus.c.

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]>
 *
 * 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"





|
|
|







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 © 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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

- (void) orderFrontStandardAboutPanel: (id) sender
{
    (void)sender;

    if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
	    NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
	TkAboutDlg();
    } else {
	int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) showHelp: (id) sender
{
    if (!_eventInterp || !Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ShowHelp", NULL, 0)) {
	[super showHelp:sender];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowHelp", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) tkSource: (id) sender
{
    (void)sender;

    if (_eventInterp) {
	if (Tcl_EvalEx(_eventInterp, "tk_getOpenFile -filetypes {"
		"{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
		-1, TCL_EVAL_GLOBAL) == TCL_OK) {
	    Tcl_Obj *path = Tcl_GetObjResult(_eventInterp);
	    int len;

	    Tcl_GetStringFromObj(path, &len);
	    if (len) {
		Tcl_IncrRefCount(path);

		int code = Tcl_FSEvalFileEx(_eventInterp, path, NULL);








|

|















|
















|

|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

- (void) orderFrontStandardAboutPanel: (id) sender
{
    (void)sender;

    if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
	    NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
	[super orderFrontStandardAboutPanel:nil];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", TCL_INDEX_NONE,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) showHelp: (id) sender
{
    if (!_eventInterp || !Tcl_FindCommand(_eventInterp,
	    "::tk::mac::ShowHelp", NULL, 0)) {
	[super showHelp:sender];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowHelp", TCL_INDEX_NONE,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) tkSource: (id) sender
{
    (void)sender;

    if (_eventInterp) {
	if (Tcl_EvalEx(_eventInterp, "tk_getOpenFile -filetypes {"
		"{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
		TCL_INDEX_NONE, TCL_EVAL_GLOBAL) == TCL_OK) {
	    Tcl_Obj *path = Tcl_GetObjResult(_eventInterp);
	    Tcl_Size len;

	    Tcl_GetStringFromObj(path, &len);
	    if (len) {
		Tcl_IncrRefCount(path);

		int code = Tcl_FSEvalFileEx(_eventInterp, path, NULL);

329
330
331
332
333
334
335
336
337
338
339
340

341

342
343
344
345
346
347
348
static Tcl_Obj *
GetWidgetDemoPath(
    Tcl_Interp *interp)
{
    Tcl_Obj *result = NULL;

    if (Tcl_EvalEx(interp, "::tk::pkgconfig get demodir,runtime",
		   -1, TCL_EVAL_GLOBAL) == TCL_OK) {
	Tcl_Obj *libpath, *demo[1] = { Tcl_NewStringObj("widget", 6) };

	libpath = Tcl_GetObjResult(interp);
	Tcl_IncrRefCount(libpath);

	result = Tcl_FSJoinToPath(libpath, 1, demo);

	Tcl_DecrRefCount(libpath);
    }
    Tcl_ResetResult(interp);
    return result;
}

/*







|




>

>







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
static Tcl_Obj *
GetWidgetDemoPath(
    Tcl_Interp *interp)
{
    Tcl_Obj *result = NULL;

    if (Tcl_EvalEx(interp, "::tk::pkgconfig get demodir,runtime",
		   TCL_INDEX_NONE, TCL_EVAL_GLOBAL) == TCL_OK) {
	Tcl_Obj *libpath, *demo[1] = { Tcl_NewStringObj("widget", 6) };

	libpath = Tcl_GetObjResult(interp);
	Tcl_IncrRefCount(libpath);
	Tcl_IncrRefCount(demo[0]);
	result = Tcl_FSJoinToPath(libpath, 1, demo);
	Tcl_DecrRefCount(demo[0]);
	Tcl_DecrRefCount(libpath);
    }
    Tcl_ResetResult(interp);
    return result;
}

/*
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
 *----------------------------------------------------------------------
 */

static void
GenerateEditEvent(
    const char *name)
{
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin;

    if (!winPtr) {
	return;
    }
    tkwin = (Tk_Window)winPtr->dispPtr->focusPtr;
    if (!tkwin) {
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid(name);
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

#pragma mark -

#pragma mark NSMenu & NSMenuItem Utilities

@implementation NSMenu(TKUtils)







|











|
|
|
|
|
|
|
|
|

|
|
|
|
|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
 *----------------------------------------------------------------------
 */

static void
GenerateEditEvent(
    const char *name)
{
    union {XEvent general; XVirtualEvent virt;} event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
    Tk_Window tkwin;

    if (!winPtr) {
	return;
    }
    tkwin = (Tk_Window)winPtr->dispPtr->focusPtr;
    if (!tkwin) {
	return;
    }
    bzero(&event, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.virt.send_event = false;
    event.virt.display = Tk_Display(tkwin);
    event.virt.event = Tk_WindowId(tkwin);
    event.virt.root = XRootWindow(Tk_Display(tkwin), 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.virt.x_root, &event.virt.y_root, &x, &y, &event.virt.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.virt.x, &event.virt.y);
    event.virt.same_screen = true;
    event.virt.name = Tk_GetUid(name);
    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

#pragma mark -

#pragma mark NSMenu & NSMenuItem Utilities

@implementation NSMenu(TKUtils)

Changes to macosx/tkMacOSXMouseEvent.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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]>
 *
 * 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"






|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkMacOSXMouseEvent.c --
 *
 *	This file implements functions that decode & handle mouse events on
 *	MacOS X.
 *
 * 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"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50



























51

52
53
54
55
56
57

58
59
60
61
62
63
64




65


66
67
68
69
70
71
72
73
74


75
76
77
78

79
80

81
82
83


84
85
86

87
88
89


90
91
92
93
94
95
96
97
98
99
100















101
102

103
104
105
106
107
108
109
110
111


112
113
114


115
116




117
118








119



























































































120





121










122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150


151
152
153


154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223


224
225
226


227

228
229





























230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254








255




256








257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    Point local;
} MouseEventData;

static Tk_Window captureWinPtr = NULL;	/* Current capture window; may be
					 * NULL. */

static int		GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int	ButtonModifiers2State(UInt32 buttonState,
			    UInt32 keyModifiers);

#pragma mark TKApplication(TKMouseEvent)

enum {
    NSWindowWillMoveEventType = 20
};

/*
 * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
 * window attribute pointing to the active window.  As of 10.8 this behavior
 * had changed.  The new behavior was that if the mouse were ever moved outside
 * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
 * attribute until the mouse returned to the window.  In 11.1 it changed again.
 * The window attribute can be non-nil, but referencing a window which does not
 * belong to the application.
 */




























@implementation TKApplication(TKMouseEvent)

- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    NSRect viewFrame = [[eventWindow contentView] frame];
    NSPoint location = [theEvent locationInWindow];

    TkWindow *winPtr = NULL, *grabWinPtr;
    Tk_Window tkwin = NULL, capture, target;
    NSPoint local, global;
    NSInteger button;
    Bool inTitleBar = NO;
    int win_x, win_y;
    unsigned int buttonState = 0;




    static int validPresses = 0, ignoredPresses = 0;



#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif

    /*
     * If this event is not for a Tk toplevel, it should just be passed up the
     * responder chain.  However, there is an exception for synthesized events,
     * which are used in testing.  Those events are recognized by having their


     * both the windowNumber and the eventNumber set to -1.
     */

    if (eventWindow && ![eventWindow isMemberOfClass:[TKWindow class]]) {

	if ([theEvent windowNumber] != -1 || [theEvent eventNumber] != -1)
	    return theEvent;

    }

    /*


     * Check if the event is located in the titlebar.
     */


    if (eventWindow) {
	inTitleBar = viewFrame.size.height < location.y;
    }



    button = [theEvent buttonNumber] + Button1;
    if ((button & -2) == Button2) {
	button ^= 1; /* Swap buttons 2/3 */
    }
    switch (eventType) {
    case NSRightMouseUp:
    case NSOtherMouseUp:
	buttonState &= ~Tk_GetButtonMask(button);
	break;
    case NSLeftMouseDragged:















    case NSRightMouseDragged:
    case NSOtherMouseDragged:

    case NSRightMouseDown:
    case NSOtherMouseDown:
	buttonState |= Tk_GetButtonMask(button);
	break;
    case NSMouseEntered:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    !inTitleBar) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:YES];
	}


	break;
    case NSMouseExited:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)]) {


	    [(TKWindow *)eventWindow setMouseInResizeArea:NO];
	    break;




	}
    case NSLeftMouseUp:








    case NSLeftMouseDown:



























































































    case NSMouseMoved:





    case NSScrollWheel:










#if 0
    case NSCursorUpdate:
    case NSTabletPoint:
    case NSTabletProximity:
#endif
	break;
    default: /* This type of event is ignored. */
	return theEvent;
    }

    /*
     * Update the button state.  We ignore left button presses that start a
     * resize or occur in the title bar.  See tickets [d72abe6b54] and
     * [39cbacb9e8].
     */

    if (eventType == NSLeftMouseDown) {
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    [(TKWindow *) eventWindow mouseInResizeArea]) {

	    /*
	     * When the left button is pressed in the resize area, we receive
	     * NSMouseDown, but when it is released we do not receive
	     * NSMouseUp.  So ignore the event and clear the button state but
	     * do not change the ignoredPresses count.
	     */

	    buttonState &= ~Tk_GetButtonMask(Button1);
	    return theEvent;


	}
	if (inTitleBar) {
	    ignoredPresses++;


	    return theEvent;
	}
	validPresses++;
	buttonState |= Tk_GetButtonMask(Button1);
    }
    if (eventType == NSLeftMouseUp) {
	if (ignoredPresses > 0) {
	    ignoredPresses--;
	} else if (validPresses > 0) {
	    validPresses--;
	}

	if (validPresses == 0) {
	    buttonState &= ~Tk_GetButtonMask(Button1);
	}
    }

    /*
     * Find an appropriate NSWindow to attach to this event, and its
     * associated Tk window.
     */

    capture = TkpGetCapture();
    if (capture) {
	winPtr = (TkWindow *) capture;
	eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
	if (!eventWindow) {
	    return theEvent;
	}
    } else {
	if (eventWindow) {
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
	if (!winPtr) {
	    eventWindow = [NSApp mainWindow];
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
    }
    if (!winPtr) {

	/*
	 * We couldn't find a Tk window for this event.  We have to ignore it.

	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TkMacOSXDbgMsg("Event received with no Tk window.");
#endif

	return theEvent;
    }
    tkwin = (Tk_Window) winPtr;

    /*
     * Compute the mouse position in local (window) and global (screen)
     * coordinates.  These are Tk coordinates, meaning that the local origin is
     * at the top left corner of the containing toplevel and the global origin
     * is at top left corner of the primary screen.
     */

    global = [NSEvent mouseLocation];
    local = [eventWindow tkConvertPointFromScreen: global];
    global.x = floor(global.x);
    global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
    local.x = floor(local.x);
    local.y = floor([eventWindow frame].size.height - local.y);
    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = TkpGetOtherWindow(winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;


	    local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
	    local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	}


    } else {

	local.x -= winPtr->wmInfoPtr->xInParent;
	local.y -= winPtr->wmInfoPtr->yInParent;





























    }

    /*
     * Use the local coordinates to find the Tk window which should receive
     * this event.  Also convert local into the coordinates of that window.
     * (The converted local coordinates are only needed for scrollwheel
     * events.)
     */

    target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);


    /*
     * Ignore the event if a local grab is in effect and the Tk window is
     * not in the grabber's subtree.
     */

    grabWinPtr = winPtr->dispPtr->grabWinPtr;
    if (grabWinPtr && /* There is a grab in effect ... */
	!winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
	grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
	Tk_Window tkwin2;
	if (!target) {
	    return theEvent;
	}
	for (tkwin2 = target;








	     !Tk_IsTopLevel(tkwin2);




	     tkwin2 = Tk_Parent(tkwin2)) {








	    if (tkwin2 == (Tk_Window)grabWinPtr) {
		break;
	    }
	}
	if (tkwin2 != (Tk_Window)grabWinPtr) {
	    return theEvent;

	}
    }

    /*
     *  Generate an XEvent for this mouse event.
     */

    unsigned int state = buttonState;
    NSUInteger modifiers = [theEvent modifierFlags];

    if (modifiers & NSAlphaShiftKeyMask) {
	state |= LockMask;
    }
    if (modifiers & NSShiftKeyMask) {
	state |= ShiftMask;
    }
    if (modifiers & NSControlKeyMask) {







<
<









|
|
|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>




|

>
|



|


>
>
>
>
|
>
>


|



|
|
|
>
>
|


|
>
|
|
>
|
|
<
>
>
|
<
|
>
|
<
|
>
>
|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>





|
<
|

>
>


|
>
>
|
|
>
>
>
>

|
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>

>
>
>
>
>
>
>
>
>
>











|
<
<


|
|
|
|
<
<
<
<
<
<
|
<
<
>
>

|
<
>
>

<
<
<
<
<
<
<
<
<

>
|
<
<
<
|
<
<
<
<
|
<
|
|
<
<
<
<

<
<
<
<
|
<
|
<



|
>





>





|










|

|




|
>
>
|
|
|
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
<
<
<
<

<
>






<



|



|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
|



|
|
>




|




<







25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122

123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309


310
311
312
313
314
315






316


317
318
319
320

321
322
323









324
325
326



327




328

329
330




331




332

333

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410






411

412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
    Point local;
} MouseEventData;

static Tk_Window captureWinPtr = NULL;	/* Current capture window; may be
					 * NULL. */

static int		GenerateButtonEvent(MouseEventData *medPtr);



#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 key window.  As of 10.8 this behavior had
 * changed.  The new behavior was that if the mouse were ever moved outside of
 * a window, all subsequent NSMouseMoved NSEvents would have a Nil window
 * attribute until the mouse returned to the window.  In 11.1 it changed again.
 * The window attribute can be non-nil, but referencing a window which does not
 * belong to the application.
 */

/* The basic job of tkProcessMouseEvent is to generate a call to
 * Tk_UpdatePointer.  That function receives a Tk_Window which (ignoring cases
 * when a grab is in effect) should be the highest window within the focused
 * toplevel that contains the pointer, as well as the pointer location in
 * screen coordinates and the current button state.  Tk maintains a cache of
 * these three values.  A change in any of these values causes Tk_UpdatePointer
 * to generate, respectively, Enter/Leave events, or Motion events, or
 * button Press/Release events. The Tk_Window value is allowed to be NULL,
 * which indicates that the pointer is not in the focused toplevel.
 *
 * Enter or Leave events for toplevel windows are generated when the Tk_Window
 * value changes to or from NULL.  This is problematic on macOS due to the fact
 * that Tk_UpdatePointer does not generate Motion events when the Tk_Window
 * value is NULL.  A consequence of this is that Tk_UpdatePointer will either
 * fail to generate correct Enter/Leave events for toplevels or else be unable
 * to generate Motion events when the pointer is outside of the focus window.
 * It is important to be able to generate such events because otherwise a
 * scrollbar on the edge of a toplevel becomes unusable.  Any time that the
 * pointer wanders out of the window during a scroll, the scroll will stop.
 * That is an extremely annoying and unexpected behavior.  Much of the code in
 * this module, including the trickiest parts, is devoted to working around
 * this problem.  The other tricky parts are related to transcribing Apple's
 * NSMouseEntered, NSMouseExited, and NSLeftMouseDragged events into a form
 * that makes sense to Tk.
 */


@implementation TKApplication(TKMouseEvent)

- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    TKContentView *contentView = [eventWindow contentView];
    NSPoint location = [theEvent locationInWindow];
    //NSPoint viewLocation = [contentView convertPoint:location fromView:nil];
    TkWindow *winPtr = NULL, *grabWinPtr, *scrollTarget = NULL;
    Tk_Window tkwin = NULL, capture, target;
    NSPoint local, global;
    NSInteger button;
    TkWindow *newFocus = NULL;
    int win_x, win_y;
    unsigned int buttonState = 0;
    Bool isTestingEvent = NO;
    Bool isMotionEvent = NO;
    Bool isOutside = NO;
    Bool firstDrag = NO;
    static Bool ignoreDrags = NO;
    static Bool ignoreUpDown = NO;
    static NSTimeInterval timestamp = 0;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), theEvent);
#endif

    /*
     * If this event is not for a Tk toplevel, it should normally just be
     * passed up the responder chain.  However, there is are two exceptions.
     * One is for synthesized events, which are used in testing.  Those events
     * are recognized by having their timestamp set to 0.  The other is for
     * motion events sent by the local event monitor, which will have their
     * window attribute set to nil.
     */

    if (![eventWindow isMemberOfClass:[TKWindow class]] &&
	![eventWindow isMemberOfClass:[TKPanel class]]) {
	if ([theEvent timestamp] == 0) {
	    isTestingEvent = YES;
	    eventWindow = [NSApp keyWindow];
	}
	if (eventType == NSLeftMouseDragged ||

	    eventType == NSMouseMoved) {
	    eventWindow = [NSApp keyWindow];
	    isMotionEvent = YES;

	}
	if (!isTestingEvent && !isMotionEvent) {
	    return theEvent;

	}
    } else if (!NSPointInRect(location, [contentView bounds])) {
	isOutside = YES;
    }
    button = [theEvent buttonNumber] + Button1;
    if ((button & -2) == Button2) {
	button ^= 1; /* Swap buttons 2/3 */
    }
    switch (eventType) {
    case NSRightMouseUp:
    case NSOtherMouseUp:
	buttonState &= ~Tk_GetButtonMask(button);
	break;
    case NSLeftMouseDragged:
	buttonState |= Tk_GetButtonMask(button);
	if (![NSApp tkDragTarget]) {
	    if (isOutside) {
		ignoreDrags = YES;
	    } else {
		firstDrag = YES;
	    }
	}
	if (ignoreDrags) {
	    return theEvent;
	}
	if (![NSApp tkDragTarget]) {
	    [NSApp setTkDragTarget: [NSApp tkEventTarget]];
	}
	break;
    case NSRightMouseDragged:
    case NSOtherMouseDragged:
	isMotionEvent = YES;
    case NSRightMouseDown:
    case NSOtherMouseDown:
	buttonState |= Tk_GetButtonMask(button);
	break;
    case NSMouseEntered:
	if (![eventWindow isKeyWindow] || isOutside) {

	    return theEvent;
	}
	[NSApp setTkLiveResizeEnded:NO];
	[NSApp setTkPointerWindow:[NSApp tkEventTarget]];
	break;
    case NSMouseExited:
	if (![eventWindow isKeyWindow] || !isOutside) {
	    return theEvent;
	}
	[NSApp setTkPointerWindow:nil];
	break;
    case NSLeftMouseUp:
	[NSApp setTkDragTarget: nil];
	if ([theEvent clickCount] == 2) {
	    ignoreUpDown = NO;
	}
	if (ignoreUpDown) {
	    return theEvent;
	}
	if (ignoreDrags) {
	    ignoreDrags = NO;
	    return theEvent;
	}
	buttonState &= ~Tk_GetButtonMask(Button1);
	break;
    case NSLeftMouseDown:

	/*
	 * There are situations where Apple does not send NSLeftMouseUp events
	 * even though the mouse button has been released.  One of these is
	 * whenever a menu is posted on the screen.  This causes Tk to have an
	 * inaccurate idea of the current button state and to behave strangely.
	 * (See ticket[a132b5507e].)  As a work-around we watch for NSButtonDown
	 * events that arrive when Tk thinks the button is already down and
	 * we attempt to correct Tk's cached button state by insering a call to
	 * Tk_UpdatePointer showing the button as up.
	 */

	if ([NSApp tkButtonState] & Tk_GetButtonMask(Button1)) {
	    int fakeState = [NSApp tkButtonState] & ~Tk_GetButtonMask(Button1);
	    int x = location.x;
	    int y = floor(TkMacOSXZeroScreenHeight() - location.y);
	    Tk_UpdatePointer((Tk_Window) [NSApp tkEventTarget], x, y, fakeState);
	}

	/*
	 * Ignore left mouse button events which are in an NSWindow but outside
	 * of its contentView (see tickets [d72abe6b54] and [39cbacb9e8]).
	 * Ignore the first left button press after a live resize ends. (Apple
	 * sends the button press event that started the resize after the
	 * resize ends.  It should not be seen by Tk.  See tickets [d72abe6b54]
	 * and [39cbacb9e8]).  Ignore button press events when ignoreUpDown is
	 * set.  These are extraneous events which appear when double-clicking
	 * in a window without focus, causing duplicate Double-1 events (see
	 * ticket [7bda9882cb]).  When a LeftMouseDown event with clickCount 2
	 * is received we set the ignoreUpDown flag and we clear it when the
	 * matching LeftMouseUp with click count 2 is received.
	 */

	/*
	 * Make sure we don't ignore LeftMouseUp and LeftMouseDown forever.
	 * Currently tkBind.c sets NEARBY_MS to 500 (the Windows default).
	 */

	if ([theEvent timestamp] - timestamp > 1) {
	    ignoreUpDown = NO;
	}
	if ([theEvent clickCount] == 2) {
	    if (ignoreUpDown == YES) {
		return theEvent;
	    } else {
		timestamp = [theEvent timestamp];
		ignoreUpDown = YES;
	    }
	}
	if (!isTestingEvent) {
	    NSRect bounds = [contentView bounds];
	    NSRect grip = NSMakeRect(bounds.size.width - 10, 0, 10, 10);
	    bounds = NSInsetRect(bounds, 2.0, 2.0);
	    if (!NSPointInRect(location, bounds)) {
		return theEvent;
	    }
	    if (NSPointInRect(location, grip)) {
		return theEvent;
	    }
	    if ([NSApp tkLiveResizeEnded]) {
		[NSApp setTkLiveResizeEnded:NO];
		return theEvent;
	    }
	}

	/*
	 * If this click will change the focus, the Tk event should
	 * be sent to the toplevel which will be receiving focus rather than to
	 * the current focus window.  So reset tkEventTarget.
	 */

	if (eventWindow != [NSApp keyWindow]) {
	    NSWindow *w;

	    if (eventWindow && isOutside) {
		return theEvent;
	    }
	    for (w in [NSApp orderedWindows]) {
		if (NSPointInRect([NSEvent mouseLocation], [w frame])) {
		    newFocus = TkMacOSXGetTkWindow(w);
		    break;
		}
	    }
	    if (newFocus) {
		[NSApp setTkEventTarget: newFocus];
		[NSApp setTkPointerWindow: newFocus];
		target = (Tk_Window) newFocus;
	    }
	}
	buttonState |= Tk_GetButtonMask(Button1);
	break;
    case NSMouseMoved:
	if (eventWindow && eventWindow != [NSApp keyWindow]) {
	    return theEvent;
	}
	isMotionEvent = YES;
	break;
    case NSScrollWheel:

	/*
	 * Scroll wheel events are sent to the window containing the pointer,
	 * or ignored if no window contains the pointer.  See TIP #171.  Note,
	 * however, that TIP #171 proposed sending scroll wheel events to the
	 * focus window when no window contains the pointer.  That proposal was
	 * ultimately rejected.
	 */

	scrollTarget = TkMacOSXGetTkWindow(eventWindow);
#if 0
    case NSCursorUpdate:
    case NSTabletPoint:
    case NSTabletProximity:
#endif
	break;
    default: /* This type of event is ignored. */
	return theEvent;
    }

    /*
     * Find the toplevel window for the event.


     */

    if ([NSApp tkDragTarget]) {
	TkWindow *dragPtr = (TkWindow *) [NSApp tkDragTarget];
	TKWindow *dragWindow = nil;
	MacDrawable *topMacWin;






	if (dragPtr) {


	    dragWindow = (TKWindow *)TkMacOSXGetNSWindowForDrawable(
			    dragPtr->window);
	}
	if (!dragWindow) {

	    [NSApp setTkDragTarget: nil];
	    target = NULL;
	    return theEvent;









	}
	topMacWin = TkMacOSXGetHostToplevel(dragPtr);
	if (topMacWin) {



	    winPtr = topMacWin->winPtr;




	}

    } else if (eventType == NSScrollWheel) {
	winPtr = scrollTarget;




    } else {




	winPtr = [NSApp tkEventTarget];

    }

    if (!winPtr) {

	/*
	 * If we couldn't find a toplevel for this event we have to ignore it.
	 * (But this should never happen.)
	 */

#ifdef TK_MAC_DEBUG_EVENTS
	TkMacOSXDbgMsg("Event received with no Tk window.");
#endif

	return theEvent;
    }
    tkwin = (Tk_Window) winPtr;

    /*
     * Compute the mouse position in local (toplevel) and global (screen)
     * coordinates.  These are Tk coordinates, meaning that the local origin is
     * at the top left corner of the containing toplevel and the global origin
     * is at top left corner of the primary screen.
     */

    global = [NSEvent mouseLocation];
    local = [eventWindow tkConvertPointFromScreen: global];
    global.x = floor(global.x);
    global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
    local.x = floor(local.x);
    local.y = floor(eventWindow.frame.size.height - local.y);
    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    MacDrawable *topMacWin = TkMacOSXGetHostToplevel(winPtr);
	    if (topMacWin) {
		TkWindow* topPtr = topMacWin->winPtr;
		local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
		local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	    }
	}
    }
    else {
    	if (winPtr && winPtr->wmInfoPtr) {
    	    local.x -= winPtr->wmInfoPtr->xInParent;
    	    local.y -= winPtr->wmInfoPtr->yInParent;
    	} else {
    	    return theEvent;
    	}
    }

    /*
     * Use the toplevel coordinates to decide which Tk window should receive
     * this event.  Also convert the toplevel coordinates into the coordinate
     * system of that window.  These converted coordinates are needed for
     * XEvents that we generate, namely ScrollWheel events and Motion events
     * when the mouse is outside of the focused toplevel.
     */

    if ([NSApp tkDragTarget]) {
	Tk_Window dragTarget = (Tk_Window) [NSApp tkDragTarget];
	Tk_Window dragWidget = NULL;
	int x, y;
	Tk_GetRootCoords(dragTarget, &x, &y);
	win_x = global.x - x;
	win_y = global.y - y;
	if (firstDrag) {
	    dragWidget = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &x, &y);
	    if (dragWidget) {
		[NSApp setTkDragTarget: (TkWindow *) dragWidget];
	    }
	}
	target = (Tk_Window) [NSApp tkDragTarget];
    } else {
	target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    }









    grabWinPtr = winPtr->dispPtr->grabWinPtr;

    /*
     * Ignore the event if a local grab is in effect and the Tk window is
     * not in the grabber's subtree.
     */


    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 w;
	if (!target) {
	    return theEvent;
	}
	for (w = target; !Tk_IsTopLevel(w); w = Tk_Parent(w)) {
	    if (w == (Tk_Window)grabWinPtr) {
		break;
	    }
	}
	if (w != (Tk_Window)grabWinPtr) {
	    return theEvent;
	}
    }

    /*
     * Ignore the event if a global grab is in effect and the Tk window is
     * not in the grabber's subtree.
     */

    if (grabWinPtr && /* There is a grab in effect ... */
	winPtr->dispPtr->grabFlags && /* and it is a global grab ... */
	grabWinPtr->mainPtr == winPtr->mainPtr) { /* in the same application. */
	Tk_Window w;
	if (!target) {
	    return theEvent;
	}
	for (w = target; !Tk_IsTopLevel(w); w = Tk_Parent(w)) {
	    if (w == (Tk_Window)grabWinPtr) {
		break;
	    }
	}
	if (w != (Tk_Window)grabWinPtr) {
	    /* Force the focus back to the grab window. */
	    TkpChangeFocus(grabWinPtr, 1);
	}
    }

    /*
     *  Translate the current button state into Tk's format.
     */

    unsigned int state = buttonState;
    NSUInteger modifiers = [theEvent modifierFlags];

    if (modifiers & NSAlphaShiftKeyMask) {
	state |= LockMask;
    }
    if (modifiers & NSShiftKeyMask) {
	state |= ShiftMask;
    }
    if (modifiers & NSControlKeyMask) {
287
288
289
290
291
292
293

294






295

296
297

298
299
300


301
302
303







304
305









306











307








308

309


310

311
312
313
314
315
316
317
318
319
320
321
322
323
324










325





326
327

328
329
330
331
332
333
334

335
336
337
338





















339
340
341
342
343
344
345
    }
    if (modifiers & NSNumericPadKeyMask) {
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }








    if (eventType != NSScrollWheel) {


	/*

	 * For normal mouse events, Tk_UpdatePointer will send the appropriate
	 * XEvents using its cached state information.  Unfortunately, it will
	 * also recompute the local coordinates.


	 */

#ifdef TK_MAC_DEBUG_EVENTS







	TKLog(@"UpdatePointer %p x %.1f y %.1f %d",
		target, global.x, global.y, state);









#endif




















	Tk_UpdatePointer(target, global.x, global.y, state);

    } else {


	CGFloat delta;

	XEvent xEvent;

	/*
	 * For scroll wheel events we need to send the XEvent here.
	 */

	xEvent.type = MouseWheelEvent;
	xEvent.xbutton.x = win_x;
	xEvent.xbutton.y = win_y;
	xEvent.xbutton.x_root = global.x;
	xEvent.xbutton.y_root = global.y;
	xEvent.xany.send_event = false;
	xEvent.xany.display = Tk_Display(target);
	xEvent.xany.window = Tk_WindowId(target);
















	delta = [theEvent deltaY] * 120;
	if (delta != 0.0) {

	    xEvent.xbutton.state = state;
	    xEvent.xkey.keycode = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX] * 120;
	if (delta != 0.0) {

	    xEvent.xbutton.state = state | ShiftMask;
	    xEvent.xkey.keycode = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);





















	}
    }
    return theEvent;
}
@end

#pragma mark -







>

>
>
>
>
>
>

>

|
>
|
<
<
>
>
|

<
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
|
>

>
>
|
>
|
<
<
<
<
<
<







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
|
>
|
|
|
|
|
|
|
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499


500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550






551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
    }
    if (modifiers & NSNumericPadKeyMask) {
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }
    [NSApp setTkButtonState:state];

    /*
     * Send XEvents.  We do this here for Motion events outside of the focused
     * toplevel and for MouseWheel events.  In other cases the XEvents will be
     * sent when we call Tk_UpdatePointer.
     */

    if (eventType != NSScrollWheel) {
	if ([NSApp tkDragTarget]) {

	    /*
	     * When dragging the mouse into the resize area Apple shows the
	     * left button to be up, which confuses Tk_UpdatePointer.  So


	     * we make sure that the button state appears the way that Tk
	     * expects.
	     */


	    state |= Tk_GetButtonMask(Button1);
	}
	if (eventType == NSMouseEntered) {
	    Tk_UpdatePointer((Tk_Window) [NSApp tkPointerWindow],
				 global.x, global.y, state);
	} else if (eventType == NSMouseExited) {
	    if ([NSApp tkDragTarget]) {
	    	Tk_UpdatePointer((Tk_Window) [NSApp tkDragTarget],
	    			 global.x, global.y, state);
	    } else {
	    Tk_UpdatePointer(NULL, global.x, global.y, state);
	    }
	} else if (eventType == NSMouseMoved ||
		   eventType == NSLeftMouseDragged) {
	    if ([NSApp tkPointerWindow]) {
		Tk_UpdatePointer(target, global.x, global.y, state);
	    } else {
		XEvent xEvent = {0};

		xEvent.type = MotionNotify;
		xEvent.xany.send_event = false;
		xEvent.xany.display = Tk_Display(target);
		xEvent.xany.window = Tk_WindowId(target);
		xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
		xEvent.xmotion.x = win_x;
		xEvent.xmotion.y = win_y;
		xEvent.xmotion.x_root = global.x;
		xEvent.xmotion.y_root = global.y;
		xEvent.xmotion.state = state;
		Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);

		/*
		 * Tk_UpdatePointer must not be called in this case.  Doing so
		 * will break scrollbars; dragging will stop when the mouse
		 * leaves the window.
		 */

	    }
	} else {
	    Tk_UpdatePointer(target, global.x, global.y, state);
	}
    } else {
	static unsigned long scrollCounter = 0;
	int delta;
	CGFloat Delta;
	Bool deltaIsPrecise = [theEvent hasPreciseScrollingDeltas];
	XEvent xEvent = {0};






	xEvent.xbutton.x = win_x;
	xEvent.xbutton.y = win_y;
	xEvent.xbutton.x_root = global.x;
	xEvent.xbutton.y_root = global.y;
	xEvent.xany.send_event = false;
	xEvent.xany.display = Tk_Display(target);
	xEvent.xany.window = Tk_WindowId(target);
	if (deltaIsPrecise) {
	    int deltaX = [theEvent scrollingDeltaX];
	    int deltaY = [theEvent scrollingDeltaY];
	    delta = (deltaX << 16) | (deltaY & 0xffff);
	    if (delta != 0) {
	     	xEvent.type = TouchpadScroll;
	     	xEvent.xbutton.state = state;
	     	xEvent.xkey.keycode = delta;
	     	xEvent.xany.serial = scrollCounter++;
	     	Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	    }
	} else {
	    /*
	     * A low precision scroll is 120 or -120 wheel units per click.
	     * Each click generates one event.
	     */
	    Delta = [theEvent scrollingDeltaY];
	    if (Delta != 0.0) {
		xEvent.type = MouseWheelEvent;
		xEvent.xbutton.state = state;
		xEvent.xkey.keycode = Delta > 0.0 ? 120 : -120;
		xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
		Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	    }
	    Delta = [theEvent scrollingDeltaX];
	    if (Delta != 0.0) {
		xEvent.type = MouseWheelEvent;
		xEvent.xbutton.state = state | ShiftMask;
		xEvent.xkey.keycode = Delta > 0 ? 120 : -120;
		xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
		Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	    }
	}
    }

    /*
     * If button events are being captured, and the target is not in the
     * subtree below the capturing window, then the NSEvent should not be sent
     * up the responder chain.  This avoids, for example, beeps when clicking
     * the mouse button outside of a posted combobox.  See ticket [eb26d4ec8e].
     */

    capture = TkpGetCapture();
    if (capture && eventType == NSLeftMouseDown) {
	Tk_Window w;
	for (w = target; w != NULL;  w = Tk_Parent(w)) {
	    if (w == capture) {
		break;
	    }
	}
	if (w != capture) {
	    return nil;
	}
    }
    return theEvent;
}
@end

#pragma mark -
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
 *
 *----------------------------------------------------------------------
 */

unsigned int
TkMacOSXButtonKeyState(void)
{
    UInt32 buttonState = 0, keyModifiers;
    int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront());

    buttonState = isFrontProcess ? GetCurrentEventButtonState() :
	    GetCurrentButtonState();
    keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
	    GetCurrentKeyModifiers();

    return ButtonModifiers2State(buttonState, keyModifiers);
}

/*
 *----------------------------------------------------------------------
 *
 * ButtonModifiers2State --
 *
 *	Converts Carbon mouse button state and modifier values into a Tk
 *	button/modifier state.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static unsigned int
ButtonModifiers2State(
    UInt32 buttonState,
    UInt32 keyModifiers)
{
    unsigned int state;

    /*
     * Tk on OSX supports at most 9 buttons.
     */

    state = (buttonState & 0x079) * Button1Mask;
	/* Handle swapped buttons 2/3 */
	if (buttonState & 0x02) {
	    state |= Button3Mask;
	}
	if (buttonState & 0x04) {
	    state |= Button2Mask;
	}
	/* Handle buttons 8/9 */
    state |= (buttonState & 0x180) * (Button8Mask >> 7);

    if (keyModifiers & alphaLock) {
	state |= LockMask;
    }
    if (keyModifiers & shiftKey) {
	state |= ShiftMask;
    }
    if (keyModifiers & controlKey) {
	state |= ControlMask;
    }
    if (keyModifiers & cmdKey) {
	state |= Mod1Mask;		/* command key */
    }
    if (keyModifiers & optionKey) {
	state |= Mod2Mask;		/* option key */
    }
    if (keyModifiers & kEventKeyModifierNumLockMask) {
	state |= Mod3Mask;
    }
    if (keyModifiers & kEventKeyModifierFnMask) {
	state |= Mod4Mask;
    }

    return state;
}

/*
 *----------------------------------------------------------------------
 *
 * XQueryPointer --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







631
632
633
634
635
636
637








































































638
639
640
641
642
643
644
645
 *
 *----------------------------------------------------------------------
 */

unsigned int
TkMacOSXButtonKeyState(void)
{








































































    return [NSApp tkButtonState];
}

/*
 *----------------------------------------------------------------------
 *
 * XQueryPointer --
 *
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
 *	None.
 *
 *----------------------------------------------------------------------
 */

Bool
XQueryPointer(
    Display *display,
    Window w,
    Window *root_return,
    Window *child_return,
    int *root_x_return,
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{
    int getGlobal = (root_x_return && root_y_return);
    int getLocal = (win_x_return && win_y_return && w != None);
    (void)display;
    (void)root_return;
    (void)child_return;

    if (getGlobal || getLocal) {
	NSPoint global = [NSEvent mouseLocation];

	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *)w;
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(w);







|

|
|








<
<
<







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673



674
675
676
677
678
679
680
 *	None.
 *
 *----------------------------------------------------------------------
 */

Bool
XQueryPointer(
    TCL_UNUSED(Display *),
    Window w,
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window *),
    int *root_x_return,
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{
    int getGlobal = (root_x_return && root_y_return);
    int getLocal = (win_x_return && win_y_return && w != None);




    if (getGlobal || getLocal) {
	NSPoint global = [NSEvent mouseLocation];

	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *)w;
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(w);
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (tkwin != NULL) {
	tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v,
		&dummy, &dummy);
    }

    Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state);
    return true;
}

/*
 *----------------------------------------------------------------------
 *







<







839
840
841
842
843
844
845

846
847
848
849
850
851
852
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);

    if (tkwin != NULL) {
	tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v,
		&dummy, &dummy);
    }

    Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state);
    return true;
}

/*
 *----------------------------------------------------------------------
 *
682
683
684
685
686
687
688






689
690
691
692
693
694
695
	pt.y = y + dispPtr->warpY;
    } else {
	pt.x = dispPtr->warpX;
	pt.y = dispPtr->warpY;
    }

    CGWarpMouseCursorPosition(pt);






}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *







>
>
>
>
>
>







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
	pt.y = y + dispPtr->warpY;
    } else {
	pt.x = dispPtr->warpX;
	pt.y = dispPtr->warpY;
    }

    CGWarpMouseCursorPosition(pt);

    if (dispPtr->warpWindow) {
        TkGenerateButtonEventForXPointer(Tk_WindowId(dispPtr->warpWindow));
    } else {
        TkGenerateButtonEventForXPointer(None);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *

Changes to macosx/tkMacOSXNotify.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <tclInt.h>
#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXConstants.h"
#import <objc/objc-auto.h>

/* This is not used for anything at the moment. */
typedef struct ThreadSpecificData {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

#define TSD_INIT() ThreadSpecificData *tsdPtr = \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);

#ifdef TK_MAC_DEBUG_EVENTS
static const char *Tk_EventName[39] = {
    "",
    "",
    "KeyPress",		/*2*/
    "KeyRelease",      	/*3*/






|
|
|
|





<











|


|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * tkMacOSXNotify.c --
 *
 *	This file contains the implementation of a tcl event source
 *	for the AppKit event loop.
 *
 * 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"
#import <objc/objc-auto.h>

/* This is not used for anything at the moment. */
typedef struct ThreadSpecificData {
    int initialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

#define TSD_INIT() ThreadSpecificData *tsdPtr = (ThreadSpecificData *) \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(void *clientData);
static void TkMacOSXEventsSetupProc(void *clientData, int flags);
static void TkMacOSXEventsCheckProc(void *clientData, int flags);

#ifdef TK_MAC_DEBUG_EVENTS
static const char *Tk_EventName[39] = {
    "",
    "",
    "KeyPress",		/*2*/
    "KeyRelease",      	/*3*/
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    "ActivateNotify",	/*36*/
    "DeactivateNotify",	/*37*/
    "MouseWheelEvent"	/*38*/
};

static Tk_RestrictAction
InspectQueueRestrictProc(
     ClientData arg,
     XEvent *eventPtr)
{
    XVirtualEvent* ve = (XVirtualEvent*) eventPtr;
    const char *name;
    long serial = ve->serial;
    long time = eventPtr->xkey.time;








|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    "ActivateNotify",	/*36*/
    "DeactivateNotify",	/*37*/
    "MouseWheelEvent"	/*38*/
};

static Tk_RestrictAction
InspectQueueRestrictProc(
     void *arg,
     XEvent *eventPtr)
{
    XVirtualEvent* ve = (XVirtualEvent*) eventPtr;
    const char *name;
    long serial = ve->serial;
    long time = eventPtr->xkey.time;

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

/*
 * Debugging tool which prints the current Tcl queue.
 */

void DebugPrintQueue(void)
{
    ClientData oldArg;
    Tk_RestrictProc *oldProc;

    oldProc = Tk_RestrictEvents(InspectQueueRestrictProc, NULL, &oldArg);
    fprintf(stderr, "Current queue:\n");
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {};
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

/*
 * Debugging tool which prints the current Tcl queue.
 */

void DebugPrintQueue(void)
{
    void *oldArg;
    Tk_RestrictProc *oldProc;

    oldProc = Tk_RestrictEvents(InspectQueueRestrictProc, NULL, &oldArg);
    fprintf(stderr, "Current queue:\n");
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {};
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

		Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s",
		    "first [load] of TkAqua has to occur in the main thread!");
	    }
	    Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
		    TkMacOSXEventsCheckProc, NULL);
	    TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);
	    TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
	    TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *







|
|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

		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_MacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
	    Tcl_MacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNotifyExitHandler(
    ClientData dummy)	/* Not used. */
{
    (void)dummy;
    TSD_INIT();

    Tcl_DeleteEventSource(TkMacOSXEventsSetupProc,
	    TkMacOSXEventsCheckProc, NULL);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawAllViews --
 *
 *       This static function is meant to be run as an idle task.  It attempts
 *       to redraw all views which have the tkNeedsDisplay property set to YES.
 *       This relies on a feature of [NSApp nextEventMatchingMask: ...] which
 *       is undocumented, namely that it sometimes blocks and calls drawRect
 *       for all views that need display before it returns.  We call it with
 *       deQueue=NO so that it will not change anything on the AppKit event
 *       queue, because we only want the side effect that it runs drawRect. The
 *       only time when any NSViews have the needsDisplay property set to YES
 *       is during execution of this function.

 *
 *       The reason for running this function as an idle task is to try to
 *       arrange that all widgets will be fully configured before they are
 *       drawn.  Any idle tasks that might reconfigure them should be higher on
 *       the idle queue, so they should be run before the display procs are run
 *       by drawRect.
 *
 *       If this function is called directly with non-NULL clientData parameter
 *       then the int which it references will be set to the number of windows
 *       that need display, but the needsDisplay property of those windows will
 *       not be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Parts of windows my get redrawn.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXDrawAllViews(
    ClientData clientData)
{
       int count = 0, *dirtyCount = (int *)clientData;

    for (NSWindow *window in [NSApp windows]) {
	if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
	    TKContentView *view = [window contentView];
	    if ([view tkNeedsDisplay]) {
		count++;
		if (dirtyCount) {
		   continue;
		}

		[view setNeedsDisplayInRect:[view tkDirtyRect]];
	    }
	} else {
	    [window displayIfNeeded];
	}
    }
    if (dirtyCount) {
    	*dirtyCount = count;







|

<



















|
|
>
















|






|











>
|







289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNotifyExitHandler(
    TCL_UNUSED(void *))	/* Not used. */
{

    TSD_INIT();

    Tcl_DeleteEventSource(TkMacOSXEventsSetupProc,
	    TkMacOSXEventsCheckProc, NULL);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXDrawAllViews --
 *
 *       This static function is meant to be run as an idle task.  It attempts
 *       to redraw all views which have the tkNeedsDisplay property set to YES.
 *       This relies on a feature of [NSApp nextEventMatchingMask: ...] which
 *       is undocumented, namely that it sometimes blocks and calls drawRect
 *       for all views that need display before it returns.  We call it with
 *       deQueue=NO so that it will not change anything on the AppKit event
 *       queue, because we only want the side effect that it runs drawRect. The
 *       only times when any NSViews have the needsDisplay property set to YES
 *       are during execution of this function or in the addTkDirtyRect method
 *       of TKContentView.
 *
 *       The reason for running this function as an idle task is to try to
 *       arrange that all widgets will be fully configured before they are
 *       drawn.  Any idle tasks that might reconfigure them should be higher on
 *       the idle queue, so they should be run before the display procs are run
 *       by drawRect.
 *
 *       If this function is called directly with non-NULL clientData parameter
 *       then the int which it references will be set to the number of windows
 *       that need display, but the needsDisplay property of those windows will
 *       not be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Parts of windows may get redrawn.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXDrawAllViews(
    void *clientData)
{
       int count = 0, *dirtyCount = (int *)clientData;

    for (NSWindow *window in [NSApp windows]) {
	if ([[window contentView] isMemberOfClass:[TKContentView class]]) {
	    TKContentView *view = [window contentView];
	    if ([view tkNeedsDisplay]) {
		count++;
		if (dirtyCount) {
		   continue;
		}
		[[view layer] setNeedsDisplayInRect:[view tkDirtyRect]];
		[view setNeedsDisplay:YES];
	    }
	} else {
	    [window displayIfNeeded];
	}
    }
    if (dirtyCount) {
    	*dirtyCount = count;
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 */

#define TICK 200
static Tcl_TimerToken ticker = NULL;

static void
Heartbeat(
    TCL_UNUSED(ClientData))
{

    if (ticker) {
	ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
    }
}

static const Tcl_Time zeroBlockTime = { 0, 0 };

static void
TkMacOSXEventsSetupProc(
    ClientData dummy,
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
    (void)dummy;

    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {

	[NSApp _resetAutoreleasePool];

 	/*
	 * After calling this setup proc, Tcl_DoOneEvent will call
 	 * Tcl_WaitForEvent.  Then it will call check proc to collect the
 	 * events and translate them into XEvents.
	 *
 	 * If we have any events waiting or if there is any drawing to be done
	 * we want Tcl_WaitForEvent to return immediately.  So we set the block
	 * time to 0 and stop the heatbeat.
  	 */

	NSEvent *currentEvent =
	        [NSApp nextEventMatchingMask:NSAnyEventMask
			untilDate:[NSDate distantPast]
			inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			dequeue:NO];







|











|



<
















|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
 */

#define TICK 200
static Tcl_TimerToken ticker = NULL;

static void
Heartbeat(
    TCL_UNUSED(void *))
{

    if (ticker) {
	ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
    }
}

static const Tcl_Time zeroBlockTime = { 0, 0 };

static void
TkMacOSXEventsSetupProc(
    TCL_UNUSED(void *),
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];


    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {

	[NSApp _resetAutoreleasePool];

 	/*
	 * After calling this setup proc, Tcl_DoOneEvent will call
 	 * Tcl_WaitForEvent.  Then it will call check proc to collect the
 	 * events and translate them into XEvents.
	 *
 	 * If we have any events waiting or if there is any drawing to be done
	 * we want Tcl_WaitForEvent to return immediately.  So we set the block
	 * time to 0 and stop the heartbeat.
  	 */

	NSEvent *currentEvent =
	        [NSApp nextEventMatchingMask:NSAnyEventMask
			untilDate:[NSDate distantPast]
			inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			dequeue:NO];
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
 *	NSevents are used to generate X events, which are added to the Tcl
 *      event queue.
 *
 *----------------------------------------------------------------------
 */
static void
TkMacOSXEventsCheckProc(
    TCL_UNUSED(ClientData),
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
    int eventsFound = 0;

    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
	NSEvent *currentEvent = nil;







|



<







486
487
488
489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
 *	NSevents are used to generate X events, which are added to the Tcl
 *      event queue.
 *
 *----------------------------------------------------------------------
 */
static void
TkMacOSXEventsCheckProc(
    TCL_UNUSED(void *),
    int flags)
{
    NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];


    /*
     * runloopMode will be nil if we are in a Tcl event loop.
     */

    if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
	NSEvent *currentEvent = nil;
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

		/*
		 * Generate Xevents.
		 */

		NSEvent *processedEvent = [NSApp tkProcessEvent:currentEvent];
		if (processedEvent) {
		    eventsFound++;

#ifdef TK_MAC_DEBUG_EVENTS
		    TKLog(@"   event: %@", currentEvent);
#endif

		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];







<







535
536
537
538
539
540
541

542
543
544
545
546
547
548

		/*
		 * Generate Xevents.
		 */

		NSEvent *processedEvent = [NSApp tkProcessEvent:currentEvent];
		if (processedEvent) {


#ifdef TK_MAC_DEBUG_EVENTS
		    TKLog(@"   event: %@", currentEvent);
#endif

		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];

Changes to macosx/tkMacOSXPort.h.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
#   include <tcl.h>
#endif
#if TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#   if HAVE_SYS_TIME_H
#	include <sys/time.h>
#   else
#	include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>







<









<
<
<
<
|

<
<
<

|
|
<







21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36




37
38



39
40
41

42
43
44
45
46
47
48
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
#   include <tcl.h>
#endif




#ifdef HAVE_SYS_TIME_H
#	include <sys/time.h>



#endif
#include <time.h>
#include <inttypes.h>

#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
73
74
75
76
77
78
79













80
81
82
83
84
85
86
#   if defined(_IBMR2)
#	define SELECT_MASK void
#   else
#	define SELECT_MASK int
#   endif
#endif














/*
 * The following macro defines the number of fd_masks in an fd_set:
 */

#ifndef FD_SETSIZE
#   ifdef OPEN_MAX
#	define FD_SETSIZE OPEN_MAX







>
>
>
>
>
>
>
>
>
>
>
>
>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#   if defined(_IBMR2)
#	define SELECT_MASK void
#   else
#	define SELECT_MASK int
#   endif
#endif

/*
 * Used to tag functions that are only to be visible within the module being
 * built and not outside it (where this is supported by the linker).
 */

#ifndef MODULE_SCOPE
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#	define MODULE_SCOPE extern
#   endif
#endif

/*
 * The following macro defines the number of fd_masks in an fd_set:
 */

#ifndef FD_SETSIZE
#   ifdef OPEN_MAX
#	define FD_SETSIZE OPEN_MAX
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142











143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#define TkpSync(display)

/*
 * This macro stores a representation of the window handle in a string.
 */

#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "0x%lx", (unsigned long) (w))

/*
 * Turn off Tk double-buffering as Aqua windows are already double-buffered.
 */

#define TK_NO_DOUBLE_BUFFERING 1
#define TK_HAS_DYNAMIC_COLORS 1
#define TK_DYNAMIC_COLORMAP 0x0fffffff

/*
 * Inform tkImgPhInstance.c that our tkPutImage can render an image with an
 * alpha channel directly into a window.
 */

#define TKPUTIMAGE_CAN_BLEND












/*
 * Used by xcolor.c
 */

MODULE_SCOPE unsigned long TkMacOSXRGBPixel(unsigned long red, unsigned long green,
					    unsigned long blue);
#define TkpGetPixel(p) (TkMacOSXRGBPixel(p->red >> 8, p->green >> 8, p->blue >> 8))

/*
 * Used by tkWindow.c
 */

MODULE_SCOPE void TkMacOSXHandleMapOrUnmap(Tk_Window tkwin, XEvent *event);

#define TkpHandleMapOrUnmap(tkwin, event)  TkMacOSXHandleMapOrUnmap(tkwin, event)

/*
 * Used by tkAppInit
 */

#define USE_CUSTOM_EXIT_PROC
EXTERN int TkpWantsExitProc(void);
EXTERN TCL_NORETURN void TkpExitProc(void *);

#endif /* _TKMACPORT */







|










|
|


|
>
>
>
>
>
>
>
>
>
>
>









<
<
<
<
<
<
<
<









124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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 TkpSync(display)

/*
 * This macro stores a representation of the window handle in a string.
 */

#define TkpPrintWindowId(buf,w) \
	snprintf((buf), TCL_INTEGER_SPACE, "0x%lx", (unsigned long) (w))

/*
 * Turn off Tk double-buffering as Aqua windows are already double-buffered.
 */

#define TK_NO_DOUBLE_BUFFERING 1
#define TK_HAS_DYNAMIC_COLORS 1
#define TK_DYNAMIC_COLORMAP 0x0fffffff

/*
 * Inform tkImgPhInstance.c that we implement TkpPutRGBAImage to render RGBA
 * images directly into a window.
 */

#define TK_CAN_RENDER_RGBA

MODULE_SCOPE int TkpPutRGBAImage(
		     Display* display, Drawable drawable, GC gc,XImage* image,
		     int src_x, int src_y, int dest_x, int dest_y,
		     unsigned int width, unsigned int height);

/*
 * Inform tkCanvas.c that our XGetImage returns a 32pp pixmap packed as 0xAABBGGRR
 */

#define TK_XGETIMAGE_USES_ABGR32

/*
 * Used by xcolor.c
 */

MODULE_SCOPE unsigned long TkMacOSXRGBPixel(unsigned long red, unsigned long green,
					    unsigned long blue);
#define TkpGetPixel(p) (TkMacOSXRGBPixel(p->red >> 8, p->green >> 8, p->blue >> 8))









/*
 * Used by tkAppInit
 */

#define USE_CUSTOM_EXIT_PROC
EXTERN int TkpWantsExitProc(void);
EXTERN TCL_NORETURN void TkpExitProc(void *);

#endif /* _TKMACPORT */

Added macosx/tkMacOSXPrint.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
/*
 * tkMacOSXPrint.c --
 *
 *      This module implements native printing dialogs for macOS.
 *
 * Copyright © 2006 Apple Inc.
 * Copyright © 2011-2021 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 <tcl.h>
#include <tk.h>
#include <tkInt.h>
#include <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <ApplicationServices/ApplicationServices.h>
#include <tkMacOSXInt.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include "tkMacOSXImage.h"
#include "tkMacOSXPrivate.h"

NSString * fileName = nil;
CFStringRef urlFile = NULL;

/*Forward declaration of functions.*/
static Tcl_ObjCmdProc StartPrint;
static OSStatus	FinishPrint(NSString *file, int buttonValue);
static Tcl_ObjCmdProc MakePDF;
int			MacPrint_Init(Tcl_Interp * interp);

/* Delegate class for print dialogs. */
@interface PrintDelegate: NSObject
    - (id) init;
    - (void) printPanelDidEnd: (NSPrintPanel *) printPanel
		   returnCode: (int) returnCode
		  contextInfo: (void *) contextInfo;
@end

@implementation PrintDelegate
- (id) init {
    self = [super init];
    return self;
}

- (void) printPanelDidEnd: (NSPrintPanel *) printPanel
	       returnCode: (int) returnCode
	      contextInfo: (void *) contextInfo {
    (void) printPanel;
    (void) contextInfo;

    /*
     * Pass returnCode to FinishPrint function to determine how to
     * handle.
     */

    FinishPrint(fileName, returnCode);
}
@end

/*
 *----------------------------------------------------------------------
 *
 * StartPrint --
 *
 * 	Launch native print dialog.
 *
 * Results:
 *	Configures values and starts print process.
 *
 *----------------------------------------------------------------------
 */

int
StartPrint(
    TCL_UNUSED(void *),
    Tcl_Interp * interp,
    int objc,
    Tcl_Obj *const objv[])
{
    NSPrintInfo * printInfo = [NSPrintInfo sharedPrintInfo];
    NSPrintPanel * printPanel = [NSPrintPanel printPanel];
    int accepted;
    PMPrintSession printSession;
    PMPrintSettings printSettings;
    OSStatus status = noErr;

    /* Check for proper number of arguments. */
    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "file");
        return TCL_ERROR;
    }

    fileName = [NSString stringWithUTF8String: Tcl_GetString(objv[1])];
    urlFile = (CFStringRef) fileName;
    CFRetain(urlFile);

    /* Initialize the delegate for the callback from the page panel. */
    PrintDelegate * printDelegate = [[PrintDelegate alloc] init];

    status = PMCreateSession( & printSession);
    if (status != noErr) {
        NSLog(@ "Error creating print session.");
        return TCL_ERROR;
    }

    status = PMCreatePrintSettings( & printSettings);
    if (status != noErr) {
        NSLog(@ "Error creating print settings.");
        return TCL_ERROR;
    }

    status = PMSessionDefaultPrintSettings(printSession, printSettings);
    if (status != noErr) {
        NSLog(@ "Error creating default print settings.");
        return TCL_ERROR;
    }

    printSession = (PMPrintSession)[printInfo PMPrintSession];
    (void)(PMPageFormat)[printInfo PMPageFormat];
    printSettings = (PMPrintSettings)[printInfo PMPrintSettings];

    accepted = (int)[printPanel runModalWithPrintInfo: printInfo];
    [printDelegate printPanelDidEnd: printPanel
			 returnCode: accepted
			contextInfo: printInfo];

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FinishPrint --
 *
 * 	Handles print process based on input from dialog.
 *
 * Results:
 *	Completes print process.
 *
 *----------------------------------------------------------------------
 */

OSStatus
FinishPrint(
    NSString *file,
    int buttonValue)
{
    NSPrintInfo * printInfo = [NSPrintInfo sharedPrintInfo];
    PMPrintSession printSession;
    PMPageFormat pageFormat;
    PMPrintSettings printSettings;
    OSStatus status = noErr;
    CFStringRef mimeType = NULL;

    /*
     * If value passed here is NSCancelButton, return noErr;
     * otherwise printing will occur regardless of value.
     */
    if (buttonValue == NSModalResponseCancel) {
        return noErr;
    }

    status = PMCreateSession( & printSession);
    if (status != noErr) {
        NSLog(@ "Error creating print session.");
        return status;
    }

    status = PMCreatePrintSettings( & printSettings);
    if (status != noErr) {
        NSLog(@ "Error creating print settings.");
        return status;
    }

    status = PMSessionDefaultPrintSettings(printSession, printSettings);
    if (status != noErr) {
        NSLog(@ "Error creating default print settings.");
        return status;
    }

    printSession = (PMPrintSession)[printInfo PMPrintSession];
    pageFormat = (PMPageFormat)[printInfo PMPageFormat];
    printSettings = (PMPrintSettings)[printInfo PMPrintSettings];

    /*Handle print operation.*/
    if (buttonValue == NSModalResponseOK) {

        if (urlFile == NULL) {
            NSLog(@ "Could not get file to print.");
            return noErr;
        }

        fileName = file;

        CFURLRef printURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlFile, kCFURLPOSIXPathStyle, false);

        PMPrinter currentPrinter;
        PMDestinationType printDestination;

        /*Get the intended destination.*/
        status = PMSessionGetDestinationType(printSession, printSettings, & printDestination);

        /*Destination is printer. Send file to printer.*/
        if (status == noErr && printDestination == kPMDestinationPrinter) {

            status = PMSessionGetCurrentPrinter(printSession, & currentPrinter);
            if (status == noErr) {
                CFArrayRef mimeTypes;
                status = PMPrinterGetMimeTypes(currentPrinter, printSettings, & mimeTypes);
                if (status == noErr && mimeTypes != NULL) {
                    mimeType = CFSTR("application/pdf");
                    if (CFArrayContainsValue(mimeTypes, CFRangeMake(0, CFArrayGetCount(mimeTypes)), mimeType)) {
                        status = PMPrinterPrintWithFile(currentPrinter, printSettings, pageFormat, mimeType, printURL);
                        CFRelease(urlFile);
                        return status;
                    }
                }
            }
        }

        /* Destination is file. Determine how to handle. */
        if (status == noErr && printDestination == kPMDestinationFile) {
            CFURLRef outputLocation = NULL;

            status = PMSessionCopyDestinationLocation(printSession, printSettings, & outputLocation);
            if (status == noErr) {
                /*Get the source file and target destination, convert to strings.*/
                CFStringRef sourceFile = CFURLCopyFileSystemPath(printURL, kCFURLPOSIXPathStyle);
                CFStringRef savePath = CFURLCopyFileSystemPath(outputLocation, kCFURLPOSIXPathStyle);
                NSString * sourcePath = (NSString * ) sourceFile;
                NSString * finalPath = (NSString * ) savePath;
                NSString * pathExtension = [finalPath pathExtension];
                NSFileManager * fileManager = [NSFileManager defaultManager];
		NSError * error = nil;

        /*
		 * Is the target file a PDF? If so, copy print file
		 * to output location.
		 */
                if ([pathExtension isEqualToString: @ "pdf"]) {

		    /*Make sure no file conflict exists.*/
		    if ([fileManager fileExistsAtPath: finalPath]) {
			[fileManager removeItemAtPath: finalPath error: &error];
		    }
                    if ([fileManager fileExistsAtPath: sourcePath]) {
                        error = nil;
                        [fileManager copyItemAtPath: sourcePath toPath: finalPath error: & error];
                    }
		    return status;
                }

                /*
                 * Is the target file PostScript? If so, run print file
                 * through CUPS filter to convert back to PostScript.
                 */

              if ([pathExtension isEqualToString: @ "ps"]) {
                    char source[5012];
                    char target[5012];
                    [sourcePath getCString: source maxLength: (sizeof source) encoding: NSUTF8StringEncoding];
                    [finalPath getCString: target maxLength: (sizeof target) encoding: NSUTF8StringEncoding];
		    /*Make sure no file conflict exists.*/
		    if ([fileManager fileExistsAtPath: finalPath]) {
			[fileManager removeItemAtPath: finalPath error: &error];
		    }

		    /*
		     *  Fork and start new process with command string. Thanks to Peter da Silva
		     *  for assistance.
		     */
  		    pid_t pid;
		    if ((pid = fork()) == -1) {
		      return -1;
		    } else if (pid == 0) {
		      /* Redirect output to file and silence debugging output.*/
		      dup2(open(target, O_RDWR | O_CREAT, 0777), 1);
		      dup2(open("/dev/null", O_WRONLY), 2);
		      execl("/usr/sbin/cupsfilter", "/usr/sbin/cupsfilter", "-m", "application/postscript", source, NULL);
		      exit(0);
		    }
	      return status;
	      }
	    }
	}

        /* Destination is preview. Open file in default application for PDF. */
        if ((status == noErr) && (printDestination == kPMDestinationPreview)) {
            CFStringRef urlpath = CFURLCopyFileSystemPath(printURL, kCFURLPOSIXPathStyle);
            NSString * path = (NSString * ) urlpath;
            NSURL * url = [NSURL fileURLWithPath: path];
            NSWorkspace * ws = [NSWorkspace sharedWorkspace];
            [ws openURL: url];
            status = noErr;
            return status;
        }

        /*
         * If destination is not printer, file or preview,
         * we do not support it. Display alert.
         */

	if (((status == noErr) && (printDestination != kPMDestinationPreview)) || ((status == noErr) && (printDestination != kPMDestinationFile)) || ((status == noErr) &&  (printDestination != kPMDestinationPrinter))) {

            NSAlert * alert = [[[NSAlert alloc] init] autorelease];
            [alert addButtonWithTitle: @ "OK"];

            [alert setMessageText: @ "Unsupported Printing Operation"];
            [alert setInformativeText: @ "This printing operation is not supported."];
            [alert setAlertStyle: NSAlertStyleInformational];
            [alert runModal];
            return status;
        }
    }

    /* Return because cancel button was clicked. */
    if (buttonValue == NSModalResponseCancel) {
        PMRelease(printSession);
        return status;
    }

    return status;
}


/*
 *----------------------------------------------------------------------
 *
 * MakePDF--
 *
 * 	Converts a Tk canvas to PDF data.
 *
 * Results:
 *	Outputs PDF file.
 *
 *----------------------------------------------------------------------
 */

int MakePDF(
 TCL_UNUSED(void *),
 Tcl_Interp *ip,
 int objc,
 Tcl_Obj *const objv[])
{
    Tk_Window path;
    Drawable d;
    unsigned int width, height;
    CFDataRef pdfData;

    if (objc != 2) {
	Tcl_WrongNumArgs(ip, 1, objv, "path?");
	return TCL_ERROR;
    }

    /*Get window and render to PDF.*/

    path = Tk_NameToWindow(ip, Tcl_GetString(objv[1]), Tk_MainWindow(ip));
    if (path == NULL) {
	return TCL_ERROR;
    }

    Tk_MakeWindowExist(path);
    Tk_MapWindow(path);
    d = Tk_WindowId(path);
    width = Tk_Width(path);
    height = Tk_Height(path);

    pdfData = CreatePDFFromDrawableRect(d, 0, 0, width, height);

    NSData *viewData = (NSData*)pdfData;
    [viewData writeToFile:@"/tmp/tk_canvas.pdf" atomically:YES];
    return TCL_OK;

}

/*
 *----------------------------------------------------------------------
 *
 * MacPrint_Init--
 *
 * 	Initializes the printing module.
 *
 * Results:
 *	Printing module initialized.
 *
 *----------------------------------------------------------------------
 */

int MacPrint_Init(Tcl_Interp * interp) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    Tcl_CreateObjCommand(interp, "::tk::print::_print", StartPrint, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_printcanvas", MakePDF, NULL, NULL);
    [pool release];
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

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
35
36
/*
 * tkMacOSXPrivate.h --
 *
 *	Macros and declarations that are purely internal & private to TkAqua.
 *
 * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
 * Copyright (c) 2008-2009 Apple Inc.
 * Copyright (c) 2020 Marc Culler
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id$
 */

#ifndef _TKMACPRIV
#define _TKMACPRIV

#if !__OBJC__
#error Objective-C compiler required
#endif

#ifndef __clang__
#define instancetype id
#endif

#define TextStyle MacTextStyle

#import <ApplicationServices/ApplicationServices.h>

#import <Cocoa/Cocoa.h>




#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
#undef TextStyle
#import <objc/runtime.h> /* for sel_isEqual() */

#ifndef _TKMACINT





|
|
|



















>

>

>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
 * tkMacOSXPrivate.h --
 *
 *	Macros and declarations that are purely internal & private to TkAqua.
 *
 * 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>
#import <QuartzCore/QuartzCore.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#endif
#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
#undef TextStyle
#import <objc/runtime.h> /* for sel_isEqual() */

#ifndef _TKMACINT
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
 *  The structure of a 32-bit XEvent keycode on macOS. It may be viewed as
 *  an unsigned int or as having either two or three bitfields.
 */

typedef struct keycode_v_t {
    unsigned keychar: 22;    /* UCS-32 character */
    unsigned o_s: 2;         /* State of Option and Shift keys. */
    unsigned virtual: 8;     /* 8-bit virtual keycode - identifies a key. */
} keycode_v;

typedef struct keycode_x_t {
    unsigned keychar: 22;     /* UCS-32 character */
    unsigned xvirtual: 10;    /* Combines o_s and virtual. This 10-bit integer
			       * is used as a key for looking up the character
			       * produced when pressing a key with a particular







|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 *  The structure of a 32-bit XEvent keycode on macOS. It may be viewed as
 *  an unsigned int or as having either two or three bitfields.
 */

typedef struct keycode_v_t {
    unsigned keychar: 22;    /* UCS-32 character */
    unsigned o_s: 2;         /* State of Option and Shift keys. */
    unsigned virt: 8;     /* 8-bit virtual keycode - identifies a key. */
} keycode_v;

typedef struct keycode_x_t {
    unsigned keychar: 22;     /* UCS-32 character */
    unsigned xvirtual: 10;    /* Combines o_s and virtual. This 10-bit integer
			       * is used as a key for looking up the character
			       * produced when pressing a key with a particular
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
} MacKeycode;

/*
 * Macros used in tkMacOSXKeyboard.c and tkMacOSXKeyEvent.c.
 * Note that 0x7f is del and 0xF8FF is the Apple Logo character.
 */

#define ON_KEYPAD(virtual) ((virtual >= 0x41) && (virtual <= 0x5C))
#define IS_PRINTABLE(keychar) ((keychar >= 0x20) && (keychar != 0x7f) && \
                               ((keychar < 0xF700) || keychar >= 0xF8FF))

/*
 * An "index" is 2-bit bitfield showing the state of the Option and Shift
 * keys.  It is used as an index when building the keymaps and it
 * is the value of the o_s bitfield of a keycode_v.







|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
} MacKeycode;

/*
 * Macros used in tkMacOSXKeyboard.c and tkMacOSXKeyEvent.c.
 * Note that 0x7f is del and 0xF8FF is the Apple Logo character.
 */

#define ON_KEYPAD(virt) ((virt >= 0x41) && (virt <= 0x5C))
#define IS_PRINTABLE(keychar) ((keychar >= 0x20) && (keychar != 0x7f) && \
                               ((keychar < 0xF700) || keychar >= 0xF8FF))

/*
 * An "index" is 2-bit bitfield showing the state of the Option and Shift
 * keys.  It is used as an index when building the keymaps and it
 * is the value of the o_s bitfield of a keycode_v.
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
 * Structure encapsulating current drawing environment.
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;
} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */

MODULE_SCOPE long tkMacOSXMacOSXVersion;

/*
 * Prototypes for TkMacOSXRegion.c.
 */

MODULE_SCOPE HIShapeRef	TkMacOSXGetNativeRegion(Region r);
MODULE_SCOPE void	TkMacOSXSetWithNativeRegion(Region r,
			    HIShapeRef rgn);
MODULE_SCOPE HIShapeRef	TkMacOSXHIShapeCreateEmpty(void);
MODULE_SCOPE HIMutableShapeRef TkMacOSXHIShapeCreateMutableWithRect(
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSXHIShapeSetWithShape(
			    HIMutableShapeRef inDestShape,
			    HIShapeRef inSrcShape);
MODULE_SCOPE OSStatus	TkMacOSHIShapeDifferenceWithRect(
			    HIMutableShapeRef inShape, const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape,
			    const CGRect *inRect);
MODULE_SCOPE OSStatus	TkMacOSHIShapeUnion(HIShapeRef inShape1,
			    HIShapeRef inShape2, HIMutableShapeRef outResult);

/*
 * Prototypes of TkAqua internal procs.
 */

MODULE_SCOPE void *	TkMacOSXGetNamedSymbol(const char *module,
			    const char *symbol);
MODULE_SCOPE void	TkMacOSXDisplayChanged(Display *display);







<


<
<
<
<
<
<







<
<
<
<
<
<


<
<
|
<
|







206
207
208
209
210
211
212

213
214






215
216
217
218
219
220
221






222
223


224

225
226
227
228
229
230
231
232
 * Structure encapsulating current drawing environment.
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;

} TkMacOSXDrawingContext;







/*
 * Prototypes for TkMacOSXRegion.c.
 */

MODULE_SCOPE HIShapeRef	TkMacOSXGetNativeRegion(Region r);
MODULE_SCOPE void	TkMacOSXSetWithNativeRegion(Region r,
			    HIShapeRef rgn);






MODULE_SCOPE OSStatus	TkMacOSHIShapeDifferenceWithRect(
			    HIMutableShapeRef inShape, const CGRect *inRect);


MODULE_SCOPE int	TkMacOSXCountRectsInRegion(HIShapeRef shape);

MODULE_SCOPE void       TkMacOSXPrintRectsInRegion(HIShapeRef shape);
/*
 * Prototypes of TkAqua internal procs.
 */

MODULE_SCOPE void *	TkMacOSXGetNamedSymbol(const char *module,
			    const char *symbol);
MODULE_SCOPE void	TkMacOSXDisplayChanged(Display *display);
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296


297




298
299
300
301
302
303
304
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
			    CGContextRef context);
#define TkMacOSXGetTkWindow(window) (TkWindow *)Tk_MacOSXGetTkWindow(window)
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow *)Tk_MacOSXGetNSWindowForDrawable(drawable))
#define TkMacOSXGetNSViewForDrawable(macWin) ((NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin)))
#define TkMacOSXGetCGContextForDrawable(drawable) ((CGContextRef)Tk_MacOSXGetCGContextForDrawable(drawable))
MODULE_SCOPE void	TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
MODULE_SCOPE HIShapeRef	TkMacOSXGetClipRgn(Drawable drawable);
MODULE_SCOPE void	TkMacOSXInvalidateViewRegion(NSView *view,
			    HIShapeRef rgn);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromTkImage(Display *display,
			    Tk_Image image, int width, int height);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromBitmap(Display *display,
			    Pixmap bitmap, GC gc, int width, int height);
MODULE_SCOPE CGColorRef	TkMacOSXCreateCGColor(GC gc, unsigned long pixel);
MODULE_SCOPE NSColor*	TkMacOSXGetNSColor(GC gc, unsigned long pixel);
MODULE_SCOPE NSFont*	TkMacOSXNSFontForFont(Tk_Font tkfont);
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
MODULE_SCOPE NSModalSession TkMacOSXGetModalSession(void);
MODULE_SCOPE void	TkMacOSXSelDeadWindow(TkWindow *winPtr);
MODULE_SCOPE void	TkMacOSXApplyWindowAttributes(TkWindow *winPtr,
			    NSWindow *macWindow);
MODULE_SCOPE int	TkMacOSXStandardAboutPanelObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE void       TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc,
			    int inset, int thickness);
MODULE_SCOPE int 	TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE int	TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE unsigned   TkMacOSXAddVirtual(unsigned int keycode);

MODULE_SCOPE void       TkMacOSXWinNSBounds(TkWindow *winPtr, NSView *view,
					    NSRect *bounds);
MODULE_SCOPE Bool       TkMacOSXInDarkMode(Tk_Window tkwin);
MODULE_SCOPE void	TkMacOSXDrawAllViews(ClientData clientData);


MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);





#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};








|











<







|
<
<
|
<
|



|
<

>



|
>
>

>
>
>
>







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270


271

272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
			    TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
			    CGContextRef context);
#define TkMacOSXGetTkWindow(window) ((TkWindow *)Tk_MacOSXGetTkWindow(window))
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow *)Tk_MacOSXGetNSWindowForDrawable(drawable))
#define TkMacOSXGetNSViewForDrawable(macWin) ((NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin)))
#define TkMacOSXGetCGContextForDrawable(drawable) ((CGContextRef)Tk_MacOSXGetCGContextForDrawable(drawable))
MODULE_SCOPE void	TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
MODULE_SCOPE HIShapeRef	TkMacOSXGetClipRgn(Drawable drawable);
MODULE_SCOPE void	TkMacOSXInvalidateViewRegion(NSView *view,
			    HIShapeRef rgn);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromTkImage(Display *display,
			    Tk_Image image, int width, int height);
MODULE_SCOPE NSImage*	TkMacOSXGetNSImageFromBitmap(Display *display,
			    Pixmap bitmap, GC gc, int width, int height);

MODULE_SCOPE NSColor*	TkMacOSXGetNSColor(GC gc, unsigned long pixel);
MODULE_SCOPE NSFont*	TkMacOSXNSFontForFont(Tk_Font tkfont);
MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont);
MODULE_SCOPE NSModalSession TkMacOSXGetModalSession(void);
MODULE_SCOPE void	TkMacOSXSelDeadWindow(TkWindow *winPtr);
MODULE_SCOPE void	TkMacOSXApplyWindowAttributes(TkWindow *winPtr,
			    NSWindow *macWindow);
MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXStandardAboutPanelObjCmd;


MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXIconBitmapObjCmd;

MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXNSImageObjCmd;
MODULE_SCOPE void       TkMacOSXDrawSolidBorder(Tk_Window tkwin, GC gc,
			    int inset, int thickness);
MODULE_SCOPE int 	TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXRegisterServiceWidgetObjCmd;

MODULE_SCOPE unsigned   TkMacOSXAddVirtual(unsigned int keycode);
MODULE_SCOPE int 	TkMacOSXNSImage_Init(Tcl_Interp *interp);
MODULE_SCOPE void       TkMacOSXWinNSBounds(TkWindow *winPtr, NSView *view,
					    NSRect *bounds);
MODULE_SCOPE Bool       TkMacOSXInDarkMode(Tk_Window tkwin);
MODULE_SCOPE void	TkMacOSXDrawAllViews(void *clientData);
MODULE_SCOPE NSColor*   controlAccentColor(void);
MODULE_SCOPE void       Ttk_MacOSXInit(void);
MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);
MODULE_SCOPE int MacSystrayInit(Tcl_Interp *);
MODULE_SCOPE int MacPrint_Init(Tcl_Interp *);
MODULE_SCOPE NSString*  TkMacOSXOSTypeToUTI(OSType ostype);
MODULE_SCOPE NSImage*   TkMacOSXIconForFileType(NSString *filetype);

#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342











343
344
345
346
347
348
349
    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
    NSMenuItem *_demoMenuItem;
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems, *_defaultFileMenuItems;
    NSAutoreleasePool *_mainPool;
    NSThread *_backgoundLoop;

#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;
    int _macOSVersion;  /* 10000 * major + 100*minor */
    Bool _isDrawing;
    Bool _needsToDraw;
#endif

}
@property int poolLock;
@property int macOSVersion;
@property Bool isDrawing;
@property Bool needsToDraw;












@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;







<
<
<
<
<
<
<
<
<
<





>
>
>
>
>
>
>
>
>
>
>







313
314
315
316
317
318
319










320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
    Tcl_Interp *_eventInterp;
    NSMenu *_servicesMenu;
    TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
    NSMenuItem *_demoMenuItem;
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems, *_defaultFileMenuItems;
    NSAutoreleasePool *_mainPool;










}
@property int poolLock;
@property int macOSVersion;
@property Bool isDrawing;
@property Bool needsToDraw;
@property Bool isSigned;
@property Bool tkLiveResizeEnded;

/*
 * Persistent state variables used by processMouseEvent.
 */

@property(nonatomic) TkWindow *tkPointerWindow;
@property(nonatomic) TkWindow *tkEventTarget;
@property(nonatomic) TkWindow *tkDragTarget;
@property unsigned int tkButtonState;

@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
410
411
412
413
414
415
416

417
418
419
420
421
422
423

@interface TKContentView : NSView <NSTextInputClient>
{
@private
    NSString *privateWorkingText;
    Bool _tkNeedsDisplay;
    NSRect _tkDirtyRect;

}
@property Bool tkNeedsDisplay;
@property NSRect tkDirtyRect;
@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;







>







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

@interface TKContentView : NSView <NSTextInputClient>
{
@private
    NSString *privateWorkingText;
    Bool _tkNeedsDisplay;
    NSRect _tkDirtyRect;
    NSTrackingArea *trackingArea;
}
@property Bool tkNeedsDisplay;
@property NSRect tkDirtyRect;
@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476



477
478
479
480
481
482
483
- (NSPoint) tkConvertPointToScreen:(NSPoint)point;
- (NSPoint) tkConvertPointFromScreen:(NSPoint)point;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
{
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Bool _mouseInResizeArea;
    Window _tkWindow;
#endif
}
@property Bool mouseInResizeArea;
@property Window tkWindow;
@end

@interface TKWindow(TKWm)
- (void)    tkLayoutChanged;
@end

@interface TKDrawerWindow : NSWindow
{
    id _i1, _i2;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Window _tkWindow;
#endif
}
@property Window tkWindow;
@end

@interface TKPanel : NSPanel
{
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    Window _tkWindow;
#endif
}
@property Window tkWindow;
@end




#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;
+ (id)menuWithTitle:(NSString *)title submenus:(NSArray *)submenus;
- (NSMenuItem *)itemWithSubmenu:(NSMenu *)submenu;







<
<
<
<
<

<










<
<
<
<






<
<
<
<




>
>
>







429
430
431
432
433
434
435





436

437
438
439
440
441
442
443
444
445
446




447
448
449
450
451
452




453
454
455
456
457
458
459
460
461
462
463
464
465
466
- (NSPoint) tkConvertPointToScreen:(NSPoint)point;
- (NSPoint) tkConvertPointFromScreen:(NSPoint)point;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
{





}

@property Window tkWindow;
@end

@interface TKWindow(TKWm)
- (void)    tkLayoutChanged;
@end

@interface TKDrawerWindow : NSWindow
{
    id _i1, _i2;




}
@property Window tkWindow;
@end

@interface TKPanel : NSPanel
{




}
@property Window tkWindow;
@end

@interface TKPanel(TKWm)
- (void)    tkLayoutChanged;
@end
#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;
+ (id)menuWithTitle:(NSString *)title submenus:(NSArray *)submenus;
- (NSMenuItem *)itemWithSubmenu:(NSMenu *)submenu;
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568


/*
 *---------------------------------------------------------------------------
 *
 * TKNSString --
 *
 * When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot
 * deal directly with UTF-8 encoded non-BMP characters, since their UTF-8
 * encoding requires 4 bytes. Instead, when using these versions of Tcl, Tk
 * uses the CESU-8 encoding internally.  This encoding is similar to UTF-8
 * except that it allows encoding surrogate characters as 3-byte sequences
 * using the same algorithm which UTF-8 uses for non-surrogates.  This means
 * that a non-BMP character is encoded as a string of length 6.  Apple's
 * NSString class does not provide a constructor which accepts a CESU-8 encoded
 * byte sequence as initial data.  So we add a new class which does provide
 * such a constructor.  It also has a DString property which is a DString whose
 * string pointer is a byte sequence encoding the NSString with the current Tk
 * encoding, namely UTF-8 if TCL_UTF_MAX >= 4 or CESU-8 if TCL_UTF_MAX = 3.
 *
 *---------------------------------------------------------------------------
 */

@interface TKNSString:NSString {
@private
    Tcl_DString _ds;
    NSString *_string;

}
@property const char *UTF8String;
@property (readonly) Tcl_DString DString;
- (instancetype)initWithTclUtfBytes:(const void *)bytes
			     length:(NSUInteger)len;
@end








<
<
<
<
<
<
|
|


|
<








>







518
519
520
521
522
523
524






525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545


/*
 *---------------------------------------------------------------------------
 *
 * TKNSString --
 *






 * Tcl uses modified UTF-8 as internal encoding.  Apple's NSString class
 * does not provide a constructor which accepts a modified UTF-8 encoded
 * byte sequence as initial data.  So we add a new class which does provide
 * such a constructor.  It also has a DString property which is a DString whose
 * string pointer is a byte sequence encoding the NSString with modified UTF-8.

 *
 *---------------------------------------------------------------------------
 */

@interface TKNSString:NSString {
@private
    Tcl_DString _ds;
    NSString *_string;
    const char *_UTF8String;
}
@property const char *UTF8String;
@property (readonly) Tcl_DString DString;
- (instancetype)initWithTclUtfBytes:(const void *)bytes
			     length:(NSUInteger)len;
@end

Changes to macosx/tkMacOSXRegion.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * 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]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
static void RetainRegion(TkRegion r);
static void ReleaseRegion(TkRegion r);

#ifdef DEBUG
static int totalRegions = 0;
static int totalRegionRetainCount = 0;
#define DebugLog(msg, ...) fprintf(stderr, (msg), ##__VA_ARGS__)
#else
#define DebugLog(msg, ...)
#endif


/*
 *----------------------------------------------------------------------
 *
 * XCreateRegion --
 *
 *	Implements the equivelent of the X window function XCreateRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns an allocated region handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Region
XCreateRegion(void)
{
    Region region = (Region) HIShapeCreateMutable();
    DebugLog("Created region: total regions = %d\n", ++totalRegions);
    RetainRegion(region);
    return region;
}

/*
 *----------------------------------------------------------------------
 *
 * XDestroyRegion --
 *
 *	Implements the equivelent of the X window function XDestroyRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.





|
|
|






<
















|















|
|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * tkMacOSXRegion.c --
 *
 *	Implements X window calls for manipulating regions
 *
 * 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 ReleaseRegion(TkRegion r);

#ifdef DEBUG
static int totalRegions = 0;
static int totalRegionRetainCount = 0;
#define DebugLog(msg, ...) fprintf(stderr, (msg), ##__VA_ARGS__)
#else
#define DebugLog(msg, ...)
#endif


/*
 *----------------------------------------------------------------------
 *
 * XCreateRegion --
 *
 *	Implements the equivalent of the X window function XCreateRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns an allocated region handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Region
XCreateRegion(void)
{
    Region region = (Region) HIShapeCreateMutable();
    DebugLog("Created region: total regions = %d, total count is %d\n",
	++totalRegions, ++totalRegionRetainCount);
    return region;
}

/*
 *----------------------------------------------------------------------
 *
 * XDestroyRegion --
 *
 *	Implements the equivalent of the X window function XDestroyRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
}

/*
 *----------------------------------------------------------------------
 *
 * XUnionRectWithRegion --
 *
 *	Implements the equivelent of the X window function
 *	XUnionRectWithRegion. See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
}

/*
 *----------------------------------------------------------------------
 *
 * XUnionRectWithRegion --
 *
 *	Implements the equivalent of the X window function
 *	XUnionRectWithRegion. See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    Region src_region,
    Region dest_region_return)
{
    const CGRect r = CGRectMake(rectangle->x, rectangle->y,
	    rectangle->width, rectangle->height);

    if (src_region == dest_region_return) {
	ChkErr(TkMacOSHIShapeUnionWithRect,
		(HIMutableShapeRef) dest_region_return, &r);
    } else {
	HIShapeRef rectRgn = HIShapeCreateWithRect(&r);

	ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
		(HIMutableShapeRef) dest_region_return);
	CFRelease(rectRgn);
    }
    return Success;
}

/*







|




|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    Region src_region,
    Region dest_region_return)
{
    const CGRect r = CGRectMake(rectangle->x, rectangle->y,
	    rectangle->width, rectangle->height);

    if (src_region == dest_region_return) {
	ChkErr(HIShapeUnionWithRect,
		(HIMutableShapeRef) dest_region_return, &r);
    } else {
	HIShapeRef rectRgn = HIShapeCreateWithRect(&r);

	ChkErr(HIShapeUnion, rectRgn, (HIShapeRef) src_region,
		(HIMutableShapeRef) dest_region_return);
	CFRelease(rectRgn);
    }
    return Success;
}

/*
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
}

/*
 *----------------------------------------------------------------------
 *
 * XRectInRegion --
 *
 *	Implements the equivelent of the X window function XRectInRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns RectanglePart or RectangleOut. Note that this is not a complete
 *	implementation since it doesn't test for RectangleIn.
 *
 * Side effects:







|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
}

/*
 *----------------------------------------------------------------------
 *
 * XRectInRegion --
 *
 *	Implements the equivalent of the X window function XRectInRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns RectanglePart or RectangleOut. Note that this is not a complete
 *	implementation since it doesn't test for RectangleIn.
 *
 * Side effects:
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
}

/*
 *----------------------------------------------------------------------
 *
 * XClipBox --
 *
 *	Implements the equivelent of the X window function XClipBox. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
}

/*
 *----------------------------------------------------------------------
 *
 * XClipBox --
 *
 *	Implements the equivalent of the X window function XClipBox. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
	dataPtr += lineStride;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RetainRegion --
 *
 *	Increases reference count of region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
RetainRegion(
    Region r)
{
    CFRetain(r);
    DebugLog("Retained region: total count is %d\n", ++totalRegionRetainCount);
}

/*
 *----------------------------------------------------------------------
 *
 * ReleaseRegion --
 *
 *	Decreases reference count of region.
 *
 * Results:
 *	None.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







329
330
331
332
333
334
335
























336
337
338
339
340
341
342
	dataPtr += lineStride;
    }
}

/*
 *----------------------------------------------------------------------
 *
























 * ReleaseRegion --
 *
 *	Decreases reference count of region.
 *
 * Results:
 *	None.
 *
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
 */

void
TkMacOSXSetWithNativeRegion(
    Region r,
    HIShapeRef rgn)
{
    ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
}

/*
 *----------------------------------------------------------------------
 *
 * XOffsetRegion --
 *







|







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
 */

void
TkMacOSXSetWithNativeRegion(
    Region r,
    HIShapeRef rgn)
{
    ChkErr(HIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
}

/*
 *----------------------------------------------------------------------
 *
 * XOffsetRegion --
 *
474
475
476
477
478
479
480












481





482

483



484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

537
538

539





540





541
542


543
544
545
546

547
548
549
550
551
552




553
554
555
556
557











558
559
560
561
562
563
564
565
    ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *












 * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,





 * TkMacOSXHIShapeSetWithShape,

 * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,



 * TkMacOSHIShapeUnion --
 *
 *	Wrapper functions for missing/buggy HIShape API
 *
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXHIShapeCreateEmpty(void)
{
    HIShapeRef result;

    result = HIShapeCreateEmpty();
    return result;
}

HIMutableShapeRef
TkMacOSXHIShapeCreateMutableWithRect(
    const CGRect *inRect)
{
    HIMutableShapeRef result;

    result = HIShapeCreateMutableWithRect(inRect);
    return result;
}

OSStatus
TkMacOSXHIShapeSetWithShape(
    HIMutableShapeRef inDestShape,
    HIShapeRef inSrcShape)
{
    OSStatus result;

    result = HIShapeSetWithShape(inDestShape, inSrcShape);
    return result;
}

OSStatus
TkMacOSHIShapeDifferenceWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

    result = HIShapeDifference(inShape, rgn, inShape);
    CFRelease(rgn);

    return result;
}

OSStatus
TkMacOSHIShapeUnionWithRect(

    HIMutableShapeRef inShape,
    const CGRect *inRect)

{





    OSStatus result;






    result = HIShapeUnionWithRect(inShape, inRect);


    return result;
}

OSStatus

TkMacOSHIShapeUnion(
    HIShapeRef inShape1,
    HIShapeRef inShape2,
    HIMutableShapeRef outResult)
{
    OSStatus result;





    result = HIShapeUnion(inShape1, inShape2, outResult);
    return result;
}












/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
|
>
>
>
|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|
|
|
>
|
|
>

>
>
>
>
>
|
>
>
>
>
>
|
|
>
>
|


<
>
|
|
<
<

|
>
>
>
>
|
<
|

|
>
>
>
>
>
>
>
>
>
>
>








449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486






























487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528


529
530
531
532
533
534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCopyRegion --
 *
 *  Makes the destination region a copy of the source region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpCopyRegion(
    TkRegion dst,
    TkRegion src)
{
    ChkErr(HIShapeSetWithShape, (HIMutableShapeRef)dst, (HIShapeRef)src);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSHIShapeDifferenceWithRect --
 *
 *	Wrapper functions for missing/buggy HIShape API
 *
 *----------------------------------------------------------------------
 */































OSStatus
TkMacOSHIShapeDifferenceWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

    result = HIShapeDifference(inShape, rgn, inShape);
    CFRelease(rgn);

    return result;
}

static OSStatus
rectCounter(
    TCL_UNUSED(int),
    TCL_UNUSED(HIShapeRef),
    TCL_UNUSED(const CGRect *),
    void *ref)
{
    int *count = (int *)ref;
    (*count)++;
    return noErr;
}

static OSStatus
rectPrinter(
    TCL_UNUSED(int),
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    TCL_UNUSED(void *))
{
    if (rect) {
	fprintf(stderr, "    %s\n", NSStringFromRect(*rect).UTF8String);
    }
    return noErr;
}


int
TkMacOSXCountRectsInRegion(
    HIShapeRef shape)


{
    int rect_count = 0;
    if (!HIShapeIsEmpty(shape)) {
	HIShapeEnumerate(shape,
	    kHIShapeParseFromBottom|kHIShapeParseFromLeft,
	    (HIShapeEnumerateProcPtr) rectCounter, (void *) &rect_count);
    }

    return rect_count;
}

void
TkMacOSXPrintRectsInRegion(
    HIShapeRef shape)
{
    if (!HIShapeIsEmpty(shape)) {
	HIShapeEnumerate( shape,
	    kHIShapeParseFromBottom|kHIShapeParseFromLeft,
	    (HIShapeEnumerateProcPtr) rectPrinter, NULL);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXScale.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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.
 *
 * 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"






|
|
|
|







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 © 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"
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 */
static ControlActionUPP scaleActionProc = NULL; /* Pointer to func. */

/*
 * Forward declarations for procedures defined later in this file:
 */

static void		MacScaleEventProc(ClientData clientData,
			    XEvent *eventPtr);
static pascal void	ScaleActionProc(ControlRef theControl,
			    ControlPartCode partCode);

/*
 *----------------------------------------------------------------------
 *







|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 */
static ControlActionUPP scaleActionProc = NULL; /* Pointer to func. */

/*
 * Forward declarations for procedures defined later in this file:
 */

static void		MacScaleEventProc(void *clientData,
			    XEvent *eventPtr);
static pascal void	ScaleActionProc(ControlRef theControl,
			    ControlPartCode partCode);

/*
 *----------------------------------------------------------------------
 *
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
 *	The scale gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    int result;
    char string[TCL_DOUBLE_SPACE];
    MacScale *macScalePtr = clientData;







|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
 *	The scale gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    void *clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    int result;
    char string[TCL_DOUBLE_SPACE];
    MacScale *macScalePtr = clientData;
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
                scalePtr->value) < 0) {
            string[TCL_DOUBLE_SPACE - 1] = '\0';
        }
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, string, -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }







|
|
|
|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
                scalePtr->value) < 0) {
            string[TCL_DOUBLE_SPACE - 1] = '\0';
        }
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, string, TCL_INDEX_NONE);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MacScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    MacScale *macScalePtr = (MacScale *) clientData;
    Point where;
    Rect bounds;
    int part;








|







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
MacScaleEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    MacScale *macScalePtr = (MacScale *) clientData;
    Point where;
    Rect bounds;
    int part;

Changes to macosx/tkMacOSXScrlbr.c.

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
 *
 * 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"






|
|
|
|
|







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 © 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"
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    15, MIN_SLIDER_LENGTH, 26, 14, 14, kControlSizeNormal
};

/*
 * Declarations of static functions defined later in this file:
 */

static void		ScrollbarEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ScrollbarEvent(TkScrollbar *scrollPtr,
			    XEvent *eventPtr);
static void		UpdateControlValues(TkScrollbar *scrollPtr);

/*
 *----------------------------------------------------------------------







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    15, MIN_SLIDER_LENGTH, 26, 14, 14, kControlSizeNormal
};

/*
 * Declarations of static functions defined later in this file:
 */

static void		ScrollbarEventProc(void *clientData,
			    XEvent *eventPtr);
static int		ScrollbarEvent(TkScrollbar *scrollPtr,
			    XEvent *eventPtr);
static void		UpdateControlValues(TkScrollbar *scrollPtr);

/*
 *----------------------------------------------------------------------
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	CFRelease(path);
    }
}
#endif

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;








|

|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
	CFRelease(path);
    }
}
#endif

void
TkpDisplayScrollbar(
    void *clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
    	    fgGC = bgGC;
    	}
    	TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
    		(Pixmap) macWin);
    }

    Tk_Draw3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
	    scrollPtr->highlightWidth, scrollPtr->highlightWidth,
	    Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
	    Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,







|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
    	    fgGC = bgGC;
    	}
    	Tk_DrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
    		(Pixmap) macWin);
    }

    Tk_Draw3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
	    scrollPtr->highlightWidth, scrollPtr->highlightWidth,
	    Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
	    Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

void
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }
}

/*
 *----------------------------------------------------------------------
 *







|


|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

void
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;

    if (macScrollPtr->troughGC != NULL) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != NULL) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }
}

/*
 *----------------------------------------------------------------------
 *
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 *	Currently, none.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TkScrollbar *scrollPtr)
{
    (void)scrollPtr;
    /* empty */
}

/*
 *--------------------------------------------------------------
 *
 * TkpScrollbarPosition --







|

<







480
481
482
483
484
485
486
487
488

489
490
491
492
493
494
495
 *	Currently, none.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TCL_UNUSED(TkScrollbar *))
{

    /* empty */
}

/*
 *--------------------------------------------------------------
 *
 * TkpScrollbarPosition --
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *)Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect contrlRect;
    short width, height;

    NSView *view = TkMacOSXGetNSViewForDrawable(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    NSRect frame;

    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
	    Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height - scrollPtr->arrowLength;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */








|













<







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *)Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect contrlRect;
    short height;

    NSView *view = TkMacOSXGetNSViewForDrawable(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    NSRect frame;

    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
	    Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;


    height = contrlRect.size.height - scrollPtr->arrowLength;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ScrollbarEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = clientData;

    switch (eventPtr->type) {
    case UnmapNotify:
	TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
	break;
    case ActivateNotify:
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarEvent(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|


|













|


|











761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
 *	it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
ScrollbarEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;

    switch (eventPtr->type) {
    case UnmapNotify:
	TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
	break;
    case ActivateNotify:
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarEvent(scrollPtr, eventPtr);
	break;
    default:
	TkScrollbarEventProc(scrollPtr, eventPtr);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXSend.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *	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]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXInt.h"








|
|
|
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *	interps in one wish app, and you need to send it to the right one.
 *
 *	Implementing this has been on our list of things to do, but what with
 *	the demise of Tcl at Sun, and the lack of resources at Scriptics it
 *	may not get done for awhile. So this sketch is offered for the brave
 *	to attempt if they need the functionality...
 *
 * Copyright © 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"

205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
				 * application and the display. */
    const char *name)		/* The name that will be used to refer to the
				 * interpreter in later "send" commands. Must
				 * be globally unique. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Tcl_Interp *interp = winPtr->mainPtr->interp;
    int i, suffix, offset, result;

    RegisteredInterp *riPtr, *prevPtr;
    const char *actualName;
    Tcl_DString dString;
    Tcl_Obj *resultObjPtr, *interpNamePtr;
    char *interpName;

    if (!initialized) {







|
>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
				 * application and the display. */
    const char *name)		/* The name that will be used to refer to the
				 * interpreter in later "send" commands. Must
				 * be globally unique. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Tcl_Interp *interp = winPtr->mainPtr->interp;
    int suffix, result;
    Tcl_Size i, offset;
    RegisteredInterp *riPtr, *prevPtr;
    const char *actualName;
    Tcl_DString dString;
    Tcl_Obj *resultObjPtr, *interpNamePtr;
    char *interpName;

    if (!initialized) {
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
	result = Tcl_ListObjIndex(NULL, resultObjPtr, i, &interpNamePtr);
	if (result != TCL_OK || interpNamePtr == NULL) {
	    break;
	}
	interpName = Tcl_GetString(interpNamePtr);
	if (strcmp(actualName, interpName) == 0) {
	    if (suffix == 1) {
		Tcl_DStringAppend(&dString, name, -1);
		Tcl_DStringAppend(&dString, " #", 2);
		offset = Tcl_DStringLength(&dString);
		Tcl_DStringSetLength(&dString, offset + 10);
		actualName = Tcl_DStringValue(&dString);
	    }
	    suffix++;
	    sprintf(Tcl_DStringValue(&dString) + offset, "%d", suffix);
	    i = 0;
	} else {
	    i++;
	}
    }

    Tcl_DecrRefCount(resultObjPtr);







|


|



|







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
	result = Tcl_ListObjIndex(NULL, resultObjPtr, i, &interpNamePtr);
	if (result != TCL_OK || interpNamePtr == NULL) {
	    break;
	}
	interpName = Tcl_GetString(interpNamePtr);
	if (strcmp(actualName, interpName) == 0) {
	    if (suffix == 1) {
		Tcl_DStringAppend(&dString, name, TCL_INDEX_NONE);
		Tcl_DStringAppend(&dString, " #", 2);
		offset = Tcl_DStringLength(&dString);
		Tcl_DStringSetLength(&dString, offset + TCL_INTEGER_SPACE);
		actualName = Tcl_DStringValue(&dString);
	    }
	    suffix++;
	    snprintf(Tcl_DStringValue(&dString) + offset, TCL_INTEGER_SPACE, "%d", suffix);
	    i = 0;
	} else {
	    i++;
	}
    }

    Tcl_DecrRefCount(resultObjPtr);
316
317
318
319
320
321
322
323
324
325
326
327



328


329
330
331
332
333
334
335



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    ClientData dummy,	/* Not used */
    Tcl_Interp *interp,		/* The interp we are sending from */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* The arguments */
{



    const char *const sendOptions[] = {"-async", "-displayof", "--", NULL};


    char *stringRep, *destName;
    /*int async = 0;*/
    int i, index, firstArg;
    RegisteredInterp *riPtr;
    Tcl_Obj *listObjPtr;
    int result = TCL_OK;
    (void)dummy;




    for (i = 1; i < (objc - 1); ) {
	stringRep = Tcl_GetString(objv[i]);
	if (stringRep[0] == '-') {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index == 0) {
		/*async = 1;*/
		i++;
	    } else if (index == 1) {
		i += 2;
	    } else {
		i++;

	    }
	} else {
	    break;
	}
    }

    if (objc < (i + 2)) {







|




>
>
>
|
>
>
|

|



|
>
>
>

|






|

<
|
|
|

>







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    TCL_UNUSED(void *),	/* Not used */
    Tcl_Interp *interp,		/* The interp we are sending from */
    int objc,			/* Number of arguments */
    Tcl_Obj *const objv[])	/* The arguments */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };
    const char *stringRep, *destName;
    /*int async = 0;*/
    int i, firstArg, index;
    RegisteredInterp *riPtr;
    Tcl_Obj *listObjPtr;
    int result = TCL_OK;

    /*
     * Process the command options.
     */

    for (i = 1; i < (objc - 1); i++) {
	stringRep = Tcl_GetString(objv[i]);
	if (stringRep[0] == '-') {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index == SEND_ASYNC) {
		/*async = 1;*/

	    } else if (index == SEND_DISPLAYOF) {
		i++;
	    } else /* if (index == SEND_LAST) */ {
		i++;
		break;
	    }
	} else {
	    break;
	}
    }

    if (objc < (i + 2)) {
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 *
 *----------------------------------------------------------------------
 */

int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
    Tcl_Obj *listObjPtr;
    RegisteredInterp *riPtr;
    (void)tkwin;

    listObjPtr = Tcl_NewListObj(0, NULL);
    riPtr = interpListPtr;
    while (riPtr != NULL) {
	Tcl_ListObjAppendElement(interp, listObjPtr,
		Tcl_NewStringObj(riPtr->name, -1));
	riPtr = riPtr->nextPtr;
    }

    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}








|




<





|







467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487
488
489
490
491
 *
 *----------------------------------------------------------------------
 */

int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    TCL_UNUSED(Tk_Window))		/* Window whose display is to be used for the
				 * lookup. */
{
    Tcl_Obj *listObjPtr;
    RegisteredInterp *riPtr;


    listObjPtr = Tcl_NewListObj(0, NULL);
    riPtr = interpListPtr;
    while (riPtr != NULL) {
	Tcl_ListObjAppendElement(interp, listObjPtr,
		Tcl_NewStringObj(riPtr->name, TCL_INDEX_NONE));
	riPtr = riPtr->nextPtr;
    }

    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}

496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    Tcl_Interp *dummy)		/* Not used */
{
    (void)dummy;
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

<











504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    TCL_UNUSED(Tcl_Interp *))		/* Not used */
{

    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXServices.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkMacOSXServices.c --
 *\
 *	This file allows the integration of Tk and the Cocoa NSServices API.
 *
 * Copyright (c) 2010-2019 Kevin Walzer/WordTech Communications LLC.
 * Copyright (c) 2019 Marc Culler.
 * Copyright (c) 2010 Adrian Robert.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <tkInt.h>
#include <tkMacOSXInt.h>





|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkMacOSXServices.c --
 *\
 *	This file allows the integration of Tk and the Cocoa NSServices API.
 *
 * Copyright © 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>

Changes to macosx/tkMacOSXSubwindows.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkMacOSXSubwindows.c --
 *
 *	Implements subwindows for the macintosh version of Tk.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <[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"





|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkMacOSXSubwindows.c --
 *
 *	Implements subwindows for the macintosh version of Tk.
 *
 * Copyright © 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"
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
	    CFRelease(macWin->drawRgn);
            macWin->drawRgn = NULL;
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree(macWin->toplevel);
	}

	ckfree(macWin);
	return Success;
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);
        macWin->visRgn = NULL;
    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);
        macWin->aboveVisRgn = NULL;
    }
    if (macWin->drawRgn) {
	CFRelease(macWin->drawRgn);
        macWin->drawRgn = NULL;
    }
    macWin->view = nil;


    /*
     * Delay deletion of a toplevel data structure untill all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree(macWin->toplevel);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	This X11 stub maps the given X11 Window but does not update any of
 *      the Tk structures describing the window.  Tk applications should
 *	never call this directly, but it is called by Tk_MapWindow and
 *      Tk_WmMapWindow.
 *
 * Results:
 *	Returns Success or BadWindow.
 *
 * Side effects:
 *	The subwindow or toplevel may appear on the screen.  VisibilityNotify
 *      events are generated.
 *
 *
 *----------------------------------------------------------------------







>
















>


|




















|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	    CFRelease(macWin->drawRgn);
            macWin->drawRgn = NULL;
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree(macWin->toplevel);
	}
	macWin->winPtr->privatePtr = NULL;
	ckfree(macWin);
	return Success;
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);
        macWin->visRgn = NULL;
    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);
        macWin->aboveVisRgn = NULL;
    }
    if (macWin->drawRgn) {
	CFRelease(macWin->drawRgn);
        macWin->drawRgn = NULL;
    }
    macWin->view = nil;
    macWin->winPtr->privatePtr = NULL;

    /*
     * Delay deletion of a toplevel data structure until all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree(macWin->toplevel);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	This X11 stub maps the given X11 Window but does not update any of
 *      the Tk structures describing the window.  Tk applications should
 *	never call this directly, but it is called by Tk_MapWindow and
 *      Tk_WmMapWindow.
 *
 * Results:
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	The subwindow or toplevel may appear on the screen.  VisibilityNotify
 *      events are generated.
 *
 *
 *----------------------------------------------------------------------
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    if (!window) {
	return BadWindow;
    }
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    static Bool initialized = NO;



    /*
     * Under certain situations it's possible for this function to be called
     * before the toplevel window it's associated with has actually been
     * mapped. In that case we need to create the real Macintosh window now as
     * this function as well as other X functions assume that the portPtr is
     * valid.
     */

    if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
	TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
    }

    display->request++;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr)) {
	    TKContentView *view = [win contentView];

	    /*
	     * We want to activate Tk when a toplevel is mapped but we must not
	     * supply YES here.  This is because during Tk initialization the







>
>













|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    if (!window) {
	return BadWindow;
    }
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    static Bool initialized = NO;
    NSPoint mouse = [NSEvent mouseLocation];
    int x = mouse.x, y = TkMacOSXZeroScreenHeight() - mouse.y;

    /*
     * Under certain situations it's possible for this function to be called
     * before the toplevel window it's associated with has actually been
     * mapped. In that case we need to create the real Macintosh window now as
     * this function as well as other X functions assume that the portPtr is
     * valid.
     */

    if (!TkMacOSXHostToplevelExists(macWin->toplevel->winPtr)) {
	TkMacOSXMakeRealWindowExist(macWin->toplevel->winPtr);
    }

    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr)) {
	    TKContentView *view = [win contentView];

	    /*
	     * We want to activate Tk when a toplevel is mapped but we must not
	     * supply YES here.  This is because during Tk initialization the
181
182
183
184
185
186
187










188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	    if (initialized) {
		if ([win canBecomeKeyWindow]) {
		    [win makeKeyAndOrderFront:NSApp];
		} else {
		    [win orderFrontRegardless];
		}
	    }










	} else {
	    TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	    /*
	     * Rebuild the container's clipping region and display
	     * the window.
	     */

	    TkMacOSXInvalClipRgns((Tk_Window)contWinPtr);
	    TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	}
	TkMacOSXInvalClipRgns((Tk_Window)winPtr);
    } else {

	/*
	 * For non-toplevel windows, rebuild the parent's clipping region







>
>
>
>
>
>
>
>
>
>

|






|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	    if (initialized) {
		if ([win canBecomeKeyWindow]) {
		    [win makeKeyAndOrderFront:NSApp];
		} else {
		    [win orderFrontRegardless];
		}
	    }

	    /*
	     * Call Tk_UpdatePointer to tell Tk whether the pointer is in the
	     * new window.
	     */

	    NSPoint viewLocation = [view convertPoint:mouse fromView:nil];
	    if (NSPointInRect(viewLocation, NSInsetRect([view bounds], 2, 2))) {
		Tk_UpdatePointer((Tk_Window) winPtr, x, y, [NSApp tkButtonState]);
	    }
	} else {
	    Tk_Window contWinPtr = Tk_GetOtherWindow((Tk_Window)winPtr);

	    /*
	     * Rebuild the container's clipping region and display
	     * the window.
	     */

	    TkMacOSXInvalClipRgns(contWinPtr);
	    TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	}
	TkMacOSXInvalClipRgns((Tk_Window)winPtr);
    } else {

	/*
	 * For non-toplevel windows, rebuild the parent's clipping region
296
297
298
299
300
301
302
303
304
305
306

307

308







309



















310
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
    TkWindow *winPtr = macWin->winPtr;
    TkWindow *parentPtr = winPtr->parentPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);

    if (!window) {
	return BadWindow;
    }
    display->request++;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr) &&
		winPtr->wmInfoPtr->hints.initial_state!=IconicState) {

	    [win orderOut:nil];

	    [win setExcludedFromWindowsMenu:YES];







	}



















	TkMacOSXInvalClipRgns((Tk_Window)winPtr);
    } else {

	/*
	 * Rebuild the visRgn clip region for the parent so it will be allowed
	 * to draw in the space from which this subwindow was removed and then
	 * redraw the window.
	 */

	if (parentPtr && parentPtr->privatePtr->visRgn) {
	    TkMacOSXInvalidateViewRegion(
		    TkMacOSXGetNSViewForDrawable(parentPtr->privatePtr),
		    parentPtr->privatePtr->visRgn);
	}
	TkMacOSXInvalClipRgns((Tk_Window)parentPtr);
	TkMacOSXUpdateClipRgn(parentPtr);
    }
    TKContentView *view = [win contentView];
    if (view != [NSView focusView]) {







|


|
>
|
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>








|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    TkWindow *winPtr = macWin->winPtr;
    TkWindow *parentPtr = winPtr->parentPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);

    if (!window) {
	return BadWindow;
    }
    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr) &&
	    winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
	    [win setExcludedFromWindowsMenu:YES];
	    [win orderOut:NSApp];
	    if ([win isKeyWindow]) {

		/*
		 * If we are unmapping the key window then we need to make sure
		 * that a new key window is assigned, if possible.  This is
		 * supposed to happen when a key window is ordered out, but as
		 * noted in tkMacOSXWm.c this does not happen, in spite of
		 * Apple's claims to the contrary.
		 */

		for (NSWindow *w in [NSApp orderedWindows]) {
		    TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
		    WmInfo *wmInfoPtr;

		    BOOL isOnScreen;

		    if (!winPtr2 || !winPtr2->wmInfoPtr) {
			continue;
		    }
		    wmInfoPtr = winPtr2->wmInfoPtr;
		    isOnScreen = (wmInfoPtr->hints.initial_state != IconicState &&
				  wmInfoPtr->hints.initial_state != WithdrawnState);
		    if (w != win && isOnScreen && [w canBecomeKeyWindow]) {
			[w makeKeyAndOrderFront:NSApp];
			break;
		    }
		}
	    }
	}
	TkMacOSXInvalClipRgns((Tk_Window)winPtr);
    } else {

	/*
	 * Rebuild the visRgn clip region for the parent so it will be allowed
	 * to draw in the space from which this subwindow was removed and then
	 * redraw the window.
	 */

	if (parentPtr && parentPtr->privatePtr->visRgn) {
	    TkMacOSXInvalidateViewRegion(
		    TkMacOSXGetNSViewForDrawable(parentPtr->window),
		    parentPtr->privatePtr->visRgn);
	}
	TkMacOSXInvalClipRgns((Tk_Window)parentPtr);
	TkMacOSXUpdateClipRgn(parentPtr);
    }
    TKContentView *view = [win contentView];
    if (view != [NSView focusView]) {
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    Display *display,		/* Display. */
    Window window,		/* Window. */
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TKWindow *w = (TKWindow *)macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    if ([w styleMask] & NSFullScreenWindowMask) {
		[w tkLayoutChanged];
	    } else {
		NSRect r = [w contentRectForFrameRect:[w frame]];

		r.origin.y += r.size.height - height;
		r.size.width = width;
		r.size.height = height;
		[w setFrame:[w frameRectForContentRect:r] display:NO];







|





|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
    Display *display,		/* Display. */
    Window window,		/* Window. */
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TKWindow *w = (TKWindow *)macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    if ([w styleMask] & NSFullScreenWindowMask) {
		[(TKWindow *)w tkLayoutChanged];
	    } else {
		NSRect r = [w contentRectForFrameRect:[w frame]];

		r.origin.y += r.size.height - height;
		r.size.width = width;
		r.size.height = height;
		[w setFrame:[w frameRectForContentRect:r] display:NO];
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
    Window window,		/* Window. */
    int x, int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    /*
	     * We explicitly convert everything to doubles so we don't get
	     * surprised (again) by what happens when you do arithmetic with







|







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
    Window window,		/* Window. */
    int x, int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    /*
	     * We explicitly convert everything to doubles so we don't get
	     * surprised (again) by what happens when you do arithmetic with
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
XMoveWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    [w setFrameTopLeftPoint: NSMakePoint(
		    x, TkMacOSXZeroScreenHeight() - y)];
	}







|







497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
XMoveWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y)
{
    MacDrawable *macWin = (MacDrawable *)window;

    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    [w setFrameTopLeftPoint: NSMakePoint(
		    x, TkMacOSXZeroScreenHeight() - y)];
	}
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
    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);

	if (contWinPtr) {
	    macParent = contWinPtr->privatePtr;
	} else {
	    /*
	     * Here we should handle out of process embedding. At this point,
	     * we are assuming that the changes.x,y is not maintained, if you







|







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
    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 = (TkWindow *)Tk_GetOtherWindow((Tk_Window)macWin->winPtr);

	if (contWinPtr) {
	    macParent = contWinPtr->privatePtr;
	} else {
	    /*
	     * Here we should handle out of process embedding. At this point,
	     * we are assuming that the changes.x,y is not maintained, if you
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
int
XRaiseWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }







|







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
int
XRaiseWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
int
XLowerWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }







|







674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
int
XLowerWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
    Window w,			/* Window. */
    unsigned int value_mask,
    TCL_UNUSED(XWindowChanges *))
{
    MacDrawable *macWin = (MacDrawable *)w;
    TkWindow *winPtr = macWin->winPtr;

    display->request++;

    /*
     * Change the shape and/or position of the window.
     */

    if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
	XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,







|







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
    Window w,			/* Window. */
    unsigned int value_mask,
    TCL_UNUSED(XWindowChanges *))
{
    MacDrawable *macWin = (MacDrawable *)w;
    TkWindow *winPtr = macWin->winPtr;

    LastKnownRequestProcessed(display)++;

    /*
     * Change the shape and/or position of the window.
     */

    if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
	XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
    }

    /*
     * If the window is a container, set the flag for its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);

	if (childPtr) {
	    TkMacOSXSetDrawingEnabled(childPtr, flag);
	}
    }
}








|







798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
    }

    /*
     * If the window is a container, set the flag for its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);

	if (childPtr) {
	    TkMacOSXSetDrawingEnabled(childPtr, flag);
	}
    }
}

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
	    HIMutableShapeRef rgn;

	    /*
	     * Start with a region defined by the window bounds.
	     */

	    TkMacOSXWinCGBounds(winPtr, &bounds);
	    rgn = TkMacOSXHIShapeCreateMutableWithRect(&bounds);

	    /*
	     * Clip away the area of any windows that may obscure this window.
	     * For a non-toplevel window, first, clip to the parent's visible
	     * clip region. Second, clip away any siblings that are higher in
	     * the stacking order. For an embedded toplevel, just clip to the
	     * container's visible clip region. Remember, we only allow one







|







851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
	    HIMutableShapeRef rgn;

	    /*
	     * Start with a region defined by the window bounds.
	     */

	    TkMacOSXWinCGBounds(winPtr, &bounds);
	    rgn = HIShapeCreateMutableWithRect(&bounds);

	    /*
	     * Clip away the area of any windows that may obscure this window.
	     * For a non-toplevel window, first, clip to the parent's visible
	     * clip region. Second, clip away any siblings that are higher in
	     * the stacking order. For an embedded toplevel, just clip to the
	     * container's visible clip region. Remember, we only allow one
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
		    if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
			continue;
		    }
		    TkMacOSXWinCGBounds(win2Ptr, &bounds);
		    ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
		}
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		    ChkErr(HIShapeIntersect,
			    win2Ptr->privatePtr->aboveVisRgn, rgn, rgn);
		}

		/*







|







879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
		    if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
			continue;
		    }
		    TkMacOSXWinCGBounds(win2Ptr, &bounds);
		    ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
		}
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		    ChkErr(HIShapeIntersect,
			    win2Ptr->privatePtr->aboveVisRgn, rgn, rgn);
		}

		/*
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
		TkMacOSXWinCGBounds(win2Ptr, &bounds);
		ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
		rgnChanged = 1;
		win2Ptr = win2Ptr->nextPtr;
	    }

	    if (Tk_IsContainer(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    if (Tk_IsMapped(win2Ptr)) {
			TkMacOSXWinCGBounds(win2Ptr, &bounds);
			ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
			rgnChanged = 1;
		    }
		}







|







912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
		TkMacOSXWinCGBounds(win2Ptr, &bounds);
		ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
		rgnChanged = 1;
		win2Ptr = win2Ptr->nextPtr;
	    }

	    if (Tk_IsContainer(winPtr)) {
		win2Ptr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
		if (win2Ptr) {
		    if (Tk_IsMapped(win2Ptr)) {
			TkMacOSXWinCGBounds(win2Ptr, &bounds);
			ChkErr(TkMacOSHIShapeDifferenceWithRect, rgn, &bounds);
			rgnChanged = 1;
		    }
		}
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
	     * (erroneous) drawing into it or its children from becoming
	     * visible. [Bug 940117]
	     */

	    if (!Tk_IsTopLevel(winPtr)) {
		TkMacOSXUpdateClipRgn(winPtr->parentPtr);
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		}
	    }
	    macWin->aboveVisRgn = TkMacOSXHIShapeCreateEmpty();
	}
	if (!macWin->visRgn) {
	    macWin->visRgn = HIShapeCreateCopy(macWin->aboveVisRgn);
	}
	macWin->flags &= ~TK_CLIP_INVALID;
    }
}







|




|







946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
	     * (erroneous) drawing into it or its children from becoming
	     * visible. [Bug 940117]
	     */

	    if (!Tk_IsTopLevel(winPtr)) {
		TkMacOSXUpdateClipRgn(winPtr->parentPtr);
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		}
	    }
	    macWin->aboveVisRgn = HIShapeCreateEmpty();
	}
	if (!macWin->visRgn) {
	    macWin->visRgn = HIShapeCreateCopy(macWin->aboveVisRgn);
	}
	macWin->flags &= ~TK_CLIP_INVALID;
    }
}
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
InvalViewRect(
    int msg,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    static CGAffineTransform t;
    TKContentView *view = ref;
    NSRect dirtyRect;

    if (!view) {
	return paramErr;
    }
    switch (msg) {
    case kHIShapeEnumerateInit:







|







1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
InvalViewRect(
    int msg,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    static CGAffineTransform t;
    TKContentView *view = (TKContentView *)ref;
    NSRect dirtyRect;

    if (!view) {
	return paramErr;
    }
    switch (msg) {
    case kHIShapeEnumerateInit:
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
	    macWin->toplevel->winPtr->wmInfoPtr &&
	    macWin->toplevel->winPtr->wmInfoPtr->window) {
	result = macWin->toplevel->winPtr->wmInfoPtr->window;
    } else if (macWin->winPtr && macWin->winPtr->wmInfoPtr &&
	    macWin->winPtr->wmInfoPtr->window) {
	result = macWin->winPtr->wmInfoPtr->window;
    } else if (macWin->toplevel && (macWin->toplevel->flags & TK_EMBEDDED)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXGetNSWindowForDrawable((Drawable)contWinPtr->privatePtr);
	}
    }
    return result;
}







|







1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
	    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 = (TkWindow *)Tk_GetOtherWindow((Tk_Window)macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXGetNSWindowForDrawable((Drawable)contWinPtr->privatePtr);
	}
    }
    return result;
}
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
    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;
}







|







1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
    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 = (TkWindow *)Tk_GetOtherWindow((Tk_Window)macWin->toplevel->winPtr);

	if (contWinPtr) {
	    result = TkMacOSXGetRootControl((Drawable)contWinPtr->privatePtr);
	}
    }
    return result;
}
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
    }

    /*
     * Also, if the window is a container, mark its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);

	if (childPtr) {
	    TkMacOSXInvalClipRgns((Tk_Window)childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.







|







1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
    }

    /*
     * Also, if the window is a container, mark its embedded window.
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);

	if (childPtr) {
	    TkMacOSXInvalClipRgns((Tk_Window)childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
	if (!Tk_IsTopLevel(childPtr)) {
	    UpdateOffsets(childPtr, deltaX, deltaY);
	}
	childPtr = childPtr->nextPtr;
    }

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);
	if (childPtr != NULL) {
	    UpdateOffsets(childPtr,deltaX,deltaY);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */







|







1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
	if (!Tk_IsTopLevel(childPtr)) {
	    UpdateOffsets(childPtr, deltaX, deltaY);
	}
	childPtr = childPtr->nextPtr;
    }

    if (Tk_IsContainer(winPtr)) {
	childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
	if (childPtr != NULL) {
	    UpdateOffsets(childPtr,deltaX,deltaY);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
    int width,		/* Dimensions of pixmap. */
    int height,
    int depth)		/* Bits per pixel for pixmap. */
{
    MacDrawable *macPix;

    if (display != NULL) {
	display->request++;
    }
    macPix = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    macPix->winPtr = NULL;
    macPix->xOff = 0;
    macPix->yOff = 0;
    macPix->visRgn = NULL;
    macPix->aboveVisRgn = NULL;







|







1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
    int width,		/* Dimensions of pixmap. */
    int height,
    int depth)		/* Bits per pixel for pixmap. */
{
    MacDrawable *macPix;

    if (display != NULL) {
	LastKnownRequestProcessed(display)++;
    }
    macPix = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    macPix->winPtr = NULL;
    macPix->xOff = 0;
    macPix->yOff = 0;
    macPix->visRgn = NULL;
    macPix->aboveVisRgn = NULL;
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
void
Tk_FreePixmap(
    Display *display,		/* Display. */
    Pixmap pixmap)		/* Pixmap to destroy */
{
    MacDrawable *macPix = (MacDrawable *)pixmap;

    display->request++;
    if (macPix->context) {
	char *data = CGBitmapContextGetData(macPix->context);

	if (data) {
	    ckfree(data);
	}
	CFRelease(macPix->context);
    }
    ckfree(macPix);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|

<
<
<
<
<













1472
1473
1474
1475
1476
1477
1478
1479
1480





1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
void
Tk_FreePixmap(
    Display *display,		/* Display. */
    Pixmap pixmap)		/* Pixmap to destroy */
{
    MacDrawable *macPix = (MacDrawable *)pixmap;

    LastKnownRequestProcessed(display)++;
    if (macPix->context) {





	CFRelease(macPix->context);
    }
    ckfree(macPix);
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

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
/*
 * 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"

/*
 * 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 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;



/*
 *----------------------------------------------------------------------
 *
 * MacSystrayDestroy --
 *
 * 	Removes an intepreters icon from the status bar.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The icon is removed and memory is freed.
 *
 *----------------------------------------------------------------------
 */

static void
MacSystrayDestroy(
    void *clientData)
{
    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;
    }

    /*
     * Using NSAppleScript API here allows us to use a single API rather
     * than multiple, some deprecated, API's, and also allows notifications
     * to work correctly without requiring Wish to be code-signed - an
     * undocumented but apparently consistent requirement. And by calling
     * NSAppleScript inline rather than shelling to out osascript,
     * Wish shows correctly as the calling app rather than Script Editor.
     */

    NSString *title = [NSString stringWithUTF8String: Tcl_GetString(objv[1])];
    NSString *message = [NSString stringWithUTF8String: Tcl_GetString(objv[2])];
    NSMutableString *notify = [NSMutableString new];
    [notify appendString: @"display notification "];
    [notify appendString:@"\""];
    [notify appendString:message];
    [notify appendString:@"\""];
    [notify appendString:@" with title \""];
    [notify appendString:title];
    [notify appendString:@"\""];
    NSAppleScript *scpt = [[[NSAppleScript alloc] initWithSource:notify] autorelease];
    NSDictionary *errorInfo;
    NSAppleEventDescriptor *result = [scpt executeAndReturnError:&errorInfo];
    NSString *info = [result stringValue];
    const char* output = [info UTF8String];

    Tcl_AppendResult(interp,
		     output,
		     NULL);

    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * 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
 *
 *----------------------------------------------------------------------
 */

int
MacSystrayInit(Tcl_Interp *interp)
{

    /*
     * Initialize the TkStatusItem for this interpreter.
     */

    StatusItemInfo info = (StatusItemInfo) ckalloc(sizeof(StatusItemInfo));
    *info = 0;

    Tcl_CreateObjCommand(interp, "::tk::systray::_systray", MacSystrayObjCmd, info,
	    MacSystrayDestroy);
    Tcl_CreateObjCommand(interp, "::tk::sysnotify::_sysnotify", SysNotifyObjCmd, NULL, NULL);
    return TCL_OK;
}


/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXTest.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
 * 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]>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXWm.h"


/*
 * Forward declarations of procedures defined later in this file:
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int		DebuggerObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const objv[]);
#endif
static int		PressButtonObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);
static int		InjectKeyEventObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);
static int		MenuBarHeightObjCmd (ClientData dummy, Tcl_Interp *interp,
					int objc, Tcl_Obj *const *objv);


/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *






|
|
|














|
|
<

|
|
|
<
|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29

30

31
32
33
34
35
36
37
/*
 * tkMacOSXTest.c --
 *
 *	Contains commands for platform specific tests for
 *	the Macintosh platform.
 *
 * Copyright © 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 !defined(NDEBUG) && MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static Tcl_ObjCmdProc DebuggerObjCmd;

#endif
static Tcl_ObjCmdProc PressButtonObjCmd;
static Tcl_ObjCmdProc MoveMouseObjCmd;
static Tcl_ObjCmdProc InjectKeyEventObjCmd;

static Tcl_ObjCmdProc MenuBarHeightObjCmd;



/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
TkplatformtestInit(
    Tcl_Interp *interp)		/* Interpreter to add commands to. */
{
    /*
     * Add commands for platform specific tests on MacOS here.
     */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
    Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
#endif
    Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL);

    Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|



>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
TkplatformtestInit(
    Tcl_Interp *interp)		/* Interpreter to add commands to. */
{
    /*
     * Add commands for platform specific tests on MacOS here.
     */

#if !defined(NDEBUG) && MAC_OS_X_VERSION_MAX_ALLOWED < 1080
    Tcl_CreateObjCommand(interp, "debugger", DebuggerObjCmd, NULL, NULL);
#endif
    Tcl_CreateObjCommand(interp, "pressbutton", PressButtonObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "movemouse", MoveMouseObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int
DebuggerObjCmd(
    ClientData clientData,		/* Not used. */
    Tcl_Interp *interp,			/* Not used. */
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
{
    Debugger();
    return TCL_OK;
}
#endif

/*







|


|
|
|
|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if !defined(NDEBUG) && MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int
DebuggerObjCmd(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    Debugger();
    return TCL_OK;
}
#endif

/*
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
 *
 * PressButtonObjCmd --
 *
 *	This Tcl command simulates a button press at a specific screen
 *      location.  It injects NSEvents into the NSApplication event queue, as
 *      opposed to adding events to the Tcl queue as event generate would do.
 *      One application is for testing the grab command. These events have
 *      their unused context property set to 1 as a signal indicating that they
 *      should not be ignored by [NSApp tkProcessMouseEvent].
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PressButtonObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int x = 0, y = 0, i, value;
    NSInteger signal = -1;
    CGPoint pt;
    NSPoint loc;
    NSEvent *motion, *press, *release;
    NSArray *screens = [NSScreen screens];
    CGFloat ScreenHeight = 0;
    enum {X=1, Y};








|



















<







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
 *
 * PressButtonObjCmd --
 *
 *	This Tcl command simulates a button press at a specific screen
 *      location.  It injects NSEvents into the NSApplication event queue, as
 *      opposed to adding events to the Tcl queue as event generate would do.
 *      One application is for testing the grab command. These events have
 *      their timestamp property set to 0 as a signal indicating that they
 *      should not be ignored by [NSApp tkProcessMouseEvent].
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PressButtonObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int x = 0, y = 0, i, value;

    CGPoint pt;
    NSPoint loc;
    NSEvent *motion, *press, *release;
    NSArray *screens = [NSScreen screens];
    CGFloat ScreenHeight = 0;
    enum {X=1, Y};

230
231
232
233
234
235
236


237
































































































238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
	}
    }
    pt.x = loc.x = x;
    pt.y = y;
    loc.y = ScreenHeight - y;

    /*


     *  We set the window number and the eventNumber to -1 as a signal to
































































































     *  processMouseEvent.
     */

    CGWarpMouseCursorPosition(pt);
    motion = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	context:nil
	eventNumber:signal
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:motion atStart:NO];
    press = [NSEvent mouseEventWithType:NSLeftMouseDown
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	context:nil
	eventNumber:signal
	clickCount:1
	pressure:0.0];
    [NSApp postEvent:press atStart:NO];
    release = [NSEvent mouseEventWithType:NSLeftMouseUp
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	context:nil
	eventNumber:signal
	clickCount:1
	pressure:-1.0];
    [NSApp postEvent:release atStart:NO];
    return TCL_OK;
}

static int
InjectKeyEventObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    static const char *const optionStrings[] = {
	"press", "release", "flagschanged", NULL};
    NSUInteger types[3] = {NSKeyDown, NSKeyUp, NSFlagsChanged};
    static const char *const argStrings[] = {
	"-shift", "-control", "-option", "-command", "-function", "-x", "-y", NULL};
    enum args {KEYEVENT_SHIFT, KEYEVENT_CONTROL, KEYEVENT_OPTION, KEYEVENT_COMMAND,
	       KEYEVENT_FUNCTION, KEYEVENT_X, KEYEVENT_Y};
    int i, index, keysym, mods = 0, x = 0, y = 0;
    NSString *chars = nil, *unmod = nil, *upper, *lower;
    NSEvent *keyEvent;
    NSUInteger type;
    MacKeycode macKC;

    if (objc < 3) {
    wrongArgs:
        Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
            &index) != TCL_OK) {
        return TCL_ERROR;
    }
    type = types[index];
    if (Tcl_GetIntFromObj(interp, objv[2], &keysym) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			 "keysym must be an integer"));
	Tcl_SetErrorCode(interp, "TK", "TEST", "INJECT", "KEYSYM", NULL);







>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|






|
|

|

|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











|
|

|
|
|











|
|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346




















347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
	}
    }
    pt.x = loc.x = x;
    pt.y = y;
    loc.y = ScreenHeight - y;

    /*
     *  We set the timestamp to 0 as a signal to tkProcessMouseEvent.
     */

    CGWarpMouseCursorPosition(pt);
    motion = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:motion atStart:NO];
    press = [NSEvent mouseEventWithType:NSLeftMouseDown
	location:loc
	modifierFlags:0
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:press atStart:NO];
    release = [NSEvent mouseEventWithType:NSLeftMouseUp
	location:loc
	modifierFlags:0
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:release atStart:NO];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * MoveMouseObjCmd --
 *
 *	This Tcl command simulates a mouse motion to a specific screen
 *      location.  It injects an NSEvent into the NSApplication event queue,
 *      as opposed to adding events to the Tcl queue as event generate would
 *      do.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MoveMouseObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int x = 0, y = 0, i, value;
    CGPoint pt;
    NSPoint loc;
    NSEvent *motion;
    NSArray *screens = [NSScreen screens];
    CGFloat ScreenHeight = 0;
    enum {X=1, Y};

    if (screens && [screens count]) {
	ScreenHeight = [[screens objectAtIndex:0] frame].size.height;
    }

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "x y");
        return TCL_ERROR;
    }
    for (i = 1; i < objc; i++) {
	if (Tcl_GetIntFromObj(interp,objv[i],&value) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch (i) {
	case X:
	    x = value;
	    break;
	case Y:
	    y = value;
	    break;
	default:
	    break;
	}
    }
    pt.x = loc.x = x;
    pt.y = y;
    loc.y = ScreenHeight - y;

    /*
     *  We set the timestamp to 0 as a signal to tkProcessMouseEvent.
     */

    CGWarpMouseCursorPosition(pt);
    motion = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:motion atStart:NO];




















    return TCL_OK;
}

static int
InjectKeyEventObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    static const char *const optionStrings[] = {
	"flagschanged", "press", "release", NULL};
    NSUInteger types[3] = {NSFlagsChanged, NSKeyDown, NSKeyUp};
    static const char *const argStrings[] = {
	"-command", "-control", "-function", "-option", "-shift", "-x", "-y", NULL};
    enum args {KEYEVENT_COMMAND, KEYEVENT_CONTROL, KEYEVENT_FUNCTION, KEYEVENT_OPTION,
	       KEYEVENT_SHIFT, KEYEVENT_X, KEYEVENT_Y};
    int i, index, keysym, mods = 0, x = 0, y = 0;
    NSString *chars = nil, *unmod = nil, *upper, *lower;
    NSEvent *keyEvent;
    NSUInteger type;
    MacKeycode macKC;

    if (objc < 3) {
    wrongArgs:
        Tcl_WrongNumArgs(interp, 1, objv, "option keysym ?arg?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
            sizeof(char *), "option", 0, &index) != TCL_OK) {
        return TCL_ERROR;
    }
    type = types[index];
    if (Tcl_GetIntFromObj(interp, objv[2], &keysym) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			 "keysym must be an integer"));
	Tcl_SetErrorCode(interp, "TK", "TEST", "INJECT", "KEYSYM", NULL);
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
        modifierFlags:mods
	timestamp:GetCurrentEventTime()
	windowNumber:0
	context:nil
	characters:chars
	charactersIgnoringModifiers:unmod
	isARepeat:NO
	keyCode:macKC.v.virtual];
    [NSApp postEvent:keyEvent atStart:NO];
    return TCL_OK;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|











447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
        modifierFlags:mods
	timestamp:GetCurrentEventTime()
	windowNumber:0
	context:nil
	characters:chars
	charactersIgnoringModifiers:unmod
	isARepeat:NO
	keyCode:macKC.v.virt];
    [NSApp postEvent:keyEvent atStart:NO];
    return TCL_OK;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWindowEvent.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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.
 *
 * 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"






|
|
|
|







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 © 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"
46
47
48
49
50
51
52
53
54
55
56
57
58










59












60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75


@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    BOOL activate = [[notification name]
	    isEqualToString:NSWindowDidBecomeKeyNotification];
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);























    if (winPtr && Tk_IsMapped(winPtr)) {
	GenerateActivateEvents(winPtr, activate);
    }
}

- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    BOOL movedOnly = [[notification name]
	    isEqualToString:NSWindowDidMoveNotification];
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {







|

<
<


>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>

|






|







46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95


@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif


    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    NSString *name = [notification name];
    Bool flag = [name isEqualToString:NSWindowDidBecomeKeyNotification];
    if (winPtr && flag) {
	NSPoint location = [NSEvent mouseLocation];
	int x = location.x;
	int y = floor(TkMacOSXZeroScreenHeight() - location.y);
	/*
	 * The Tk event target persists when there is no key window but
	 * gets reset when a new window becomes the key window.
	 */

	[NSApp setTkEventTarget: winPtr];

	/*
	 * Call Tk_UpdatePointer if the pointer is in the window.
	 */

	NSView *view = [w contentView];
	NSPoint viewLocation = [view convertPoint:location fromView:nil];
	if (NSPointInRect(viewLocation, NSInsetRect([view bounds], 2, 2))) {
	    Tk_UpdatePointer((Tk_Window) winPtr, x, y, [NSApp tkButtonState]);
	}
    }
    if (winPtr && Tk_IsMapped(winPtr)) {
	GenerateActivateEvents(winPtr, flag);
    }
}

- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    BOOL movedOnly = [[notification name]
	    isEqualToString:NSWindowDidMoveNotification];
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    }

}

- (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;







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    }

}

- (void) windowExpanded: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
156
157
158
159
160
161
162
163
164



165
166
167
168
169
170
171
172



173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

    return proposedSize;
}

- (void) windowEnteredFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif



    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowExitedFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif



    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowCollapsed: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {

	Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

- (BOOL) windowShouldClose: (NSWindow *) w
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, w);
#endif
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	TkGenWMDestroyEvent((Tk_Window)winPtr);
    }








|

>
>
>






|

>
>
>






|





>







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

    return proposedSize;
}

- (void) windowEnteredFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (![[notification object] respondsToSelector: @selector (tkLayoutChanged)]) {
	return;
    }
    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowExitedFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (![[notification object] respondsToSelector: @selector (tkLayoutChanged)]) {
	return;
    }
    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowCollapsed: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state = IconicState;
	Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

- (BOOL) windowShouldClose: (NSWindow *) w
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), w);
#endif
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	TkGenWMDestroyEvent((Tk_Window)winPtr);
    }

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234











235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
- (void) windowBecameVisible: (NSNotification *) notification
{
    NSWindow *window = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
    if (winPtr) {
	TKContentView *view = [window contentView];

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
	if (@available(macOS 10.15, *)) {
	    [view viewDidChangeEffectiveAppearance];
	}
#endif
	[view addTkDirtyRect:[view bounds]];
	Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
	Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
    }
}

- (void) windowMapped: (NSNotification *) notification
{
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}












#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}

- (void) windowLiveResize: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    //BOOL start = [[notification name] isEqualToString:NSWindowWillStartLiveResizeNotification];
}

- (void) windowUnmapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window)winPtr);
    }
}







|
|


















>
>
>
>
>
>
>
>
>
>
>





|
<
<
<
<
<
<




|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278






279
280
281
282
283
284
285
286
287
288
289
290
- (void) windowBecameVisible: (NSNotification *) notification
{
    NSWindow *window = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
    if (winPtr) {
	TKContentView *view = [window contentView];

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	if (@available(macOS 10.14, *)) {
	    [view viewDidChangeEffectiveAppearance];
	}
#endif
	[view addTkDirtyRect:[view bounds]];
	Tcl_CancelIdleCall(TkMacOSXDrawAllViews, NULL);
	Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
    }
}

- (void) windowMapped: (NSNotification *) notification
{
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
}

- (void) windowLiveResize: (NSNotification *) notification
{
    NSString *name = [notification name];
    if ([name isEqualToString:NSWindowWillStartLiveResizeNotification]) {
	// printf("Starting live resize.\n");
    } else if ([name isEqualToString:NSWindowDidEndLiveResizeNotification]) {
	[self setTkLiveResizeEnded:YES];
	// printf("Ending live resize\n");
    }
}

#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);






}

- (void) windowUnmapped: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window)winPtr);
    }
}
270
271
272
273
274
275
276


277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293










294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310




311
312
313
314
315
316
317
318
319





320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);



#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
    observe(NSWindowDidEnterFullScreenNotification, windowEnteredFullScreen:);
    observe(NSWindowDidExitFullScreenNotification, windowExitedFullScreen:);
#endif

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    observe(NSWindowWillMoveNotification, windowDragStart:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end











#pragma mark TKApplication(TKApplicationEvent)

@implementation TKApplication(TKApplicationEvent)

- (void) applicationActivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    [NSApp tkCheckPasteboard];

    /*
     * When the application is activated with Command-Tab it will create a
     * zombie window for every Tk window which has been withdrawn.  So iterate
     * through the list of windows and order out any withdrawn window.




     */

    for (NSWindow *win in [NSApp windows]) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);
	if (!winPtr || !winPtr->wmInfoPtr) {
	    continue;
	}
	if (winPtr->wmInfoPtr->hints.initial_state == WithdrawnState) {
	    [win orderOut:nil];





	}
    }
}

- (void) applicationDeactivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif

    /*
     * To prevent zombie windows on systems with a TouchBar, set the key window
     * to nil if the current key window is not visible.  This allows a closed
     * Help or About window to be deallocated so it will not reappear as a
     * zombie when the app is reactivated.







>
>

|






<
<







>
>
>
>
>
>
>
>
>
>









|







>
>
>
>








|
>
>
>
>
>









|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318


319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
    observe(NSWindowDidEnterFullScreenNotification, windowEnteredFullScreen:);
    observe(NSWindowDidExitFullScreenNotification, windowExitedFullScreen:);
#endif

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    observe(NSWindowWillMoveNotification, windowDragStart:);


    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end


/*
 * Idle task which forces focus to a particular window.
 */

static void RefocusGrabWindow(void *data) {
    TkWindow *winPtr = (TkWindow *) data;
    TkpChangeFocus(winPtr, 1);
}

#pragma mark TKApplication(TKApplicationEvent)

@implementation TKApplication(TKApplicationEvent)

- (void) applicationActivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    [NSApp tkCheckPasteboard];

    /*
     * When the application is activated with Command-Tab it will create a
     * zombie window for every Tk window which has been withdrawn.  So iterate
     * through the list of windows and order out any withdrawn window.
     * If one of the windows is the grab window for its display we focus
     * it.  This is done as at idle, in case the app was reactivated by
     * clicking a different window.  In that case we need to wait until the
     * mouse event has been processed before focusing the grab window.
     */

    for (NSWindow *win in [NSApp windows]) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);
	if (!winPtr || !winPtr->wmInfoPtr) {
	    continue;
	}
	if (winPtr->wmInfoPtr->hints.initial_state == WithdrawnState) {
	    [win orderOut:NSApp];
	}
	if (winPtr->dispPtr->grabWinPtr == winPtr) {
	    Tcl_DoWhenIdle(RefocusGrabWindow, winPtr);
	} else {
	    [[self keyWindow] orderFront: self];
	}
    }
}

- (void) applicationDeactivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif

    /*
     * To prevent zombie windows on systems with a TouchBar, set the key window
     * to nil if the current key window is not visible.  This allows a closed
     * Help or About window to be deallocated so it will not reappear as a
     * zombie when the app is reactivated.
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
    return NO;
}


- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    const char *cmd = ([[notification name] isEqualToString:
	    NSApplicationDidUnhideNotification] ?
	    "::tk::mac::OnShow" : "::tk::mac::OnHide");

    if (_eventInterp && Tcl_FindCommand(_eventInterp, cmd, NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, cmd, -1, TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) displayChanged: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    TkDisplay *dispPtr = TkGetDisplayList();

    if (dispPtr) {
	TkMacOSXDisplayChanged(dispPtr->display);
    }
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkpWillDrawWidget --
 *
 *      A widget display procedure can call this to determine whether it is
 *      being run inside of the drawRect method. If not, it may be desirable
 *      for the display procedure to simply clear the REDRAW_PENDING flag
 *      and return.  The widget can be recorded in order to schedule a
 *      redraw, via and Expose event, from within drawRect.
 *
 *      This is also needed for some tests, especially of the Text widget,
 *      which record data in a global Tcl variable and assume that display
 *      procedures will be run in a predictable sequence as Tcl idle tasks.
 *
 * Results:
 *      True if called from the drawRect method of a TKContentView with







|






|













|




















|







411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    return NO;
}


- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    const char *cmd = ([[notification name] isEqualToString:
	    NSApplicationDidUnhideNotification] ?
	    "::tk::mac::OnShow" : "::tk::mac::OnHide");

    if (_eventInterp && Tcl_FindCommand(_eventInterp, cmd, NULL, 0)) {
	int code = Tcl_EvalEx(_eventInterp, cmd, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) displayChanged: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    TkDisplay *dispPtr = TkGetDisplayList();

    if (dispPtr) {
	TkMacOSXDisplayChanged(dispPtr->display);
    }
}
@end

#pragma mark -

/*
 *----------------------------------------------------------------------
 *
 * TkpWillDrawWidget --
 *
 *      A widget display procedure can call this to determine whether it is
 *      being run inside of the drawRect method. If not, it may be desirable
 *      for the display procedure to simply clear the REDRAW_PENDING flag
 *      and return.  The widget can be recorded in order to schedule a
 *      redraw, via an Expose event, from within drawRect.
 *
 *      This is also needed for some tests, especially of the Text widget,
 *      which record data in a global Tcl variable and assume that display
 *      procedures will be run in a predictable sequence as Tcl idle tasks.
 *
 * Results:
 *      True if called from the drawRect method of a TKContentView with
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    }

    /*
     * Generate updates for any contained windows
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = TkpGetOtherWindow(winPtr);
	if (childPtr != NULL && Tk_IsMapped(childPtr)) {
	    GenerateUpdates(updateBounds, childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */







|







568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
    }

    /*
     * Generate updates for any contained windows
     */

    if (Tk_IsContainer(winPtr)) {
	childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
	if (childPtr != NULL && Tk_IsMapped(childPtr)) {
	    GenerateUpdates(updateBounds, childPtr);
	}

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    protocol = (Atom) eventPtr->xclient.data.l[0];
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			Tk_GetAtomName((Tk_Window)winPtr, protocol)));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);







|







867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
    protocol = (Atom) eventPtr->xclient.data.l[0];
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			Tk_GetAtomName((Tk_Window)winPtr, protocol)));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
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

/*
 * Restrict event processing to Expose events.
 */

static Tk_RestrictAction
ExposeRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg)
	    ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

/*
 * Restrict event processing to ConfigureNotify events.
 */

static Tk_RestrictAction
ConfigureRestrictProc(
    TCL_UNUSED(void *),
    XEvent *eventPtr)
{
    return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

@implementation TKContentView(TKWindowEvent)



























































- (void) addTkDirtyRect: (NSRect) rect
{
    _tkNeedsDisplay = YES;
    _tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
    [NSApp setNeedsToDraw:YES];


}

- (void) clearTkDirtyRect
{
    _tkNeedsDisplay = NO;
    _tkDirtyRect = NSZeroRect;
    [NSApp setNeedsToDraw:NO];







|




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>







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

/*
 * Restrict event processing to Expose events.
 */

static Tk_RestrictAction
ExposeRestrictProc(
    void *arg,
    XEvent *eventPtr)
{
    return (eventPtr->type==Expose && eventPtr->xany.serial==PTR2UINT(arg)
	    ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

/*
 * Restrict event processing to ConfigureNotify events.
 */

static Tk_RestrictAction
ConfigureRestrictProc(
    TCL_UNUSED(void *),
    XEvent *eventPtr)
{
    return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

@implementation TKContentView(TKWindowEvent)

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
	/*
	 * The layer must exist before we set wantsLayer to YES.
	 */

	self.layer = [CALayer layer];
	self.wantsLayer = YES;
	self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
	self.layer.contentsGravity = self.layer.contentsAreFlipped ?
	    kCAGravityTopLeft : kCAGravityBottomLeft;

	/*
	 * Nothing gets drawn at all if the layer does not have a delegate.
	 * Currently, we do not implement any methods of the delegate, however.
	 */

	self.layer.delegate = (id) self;
	trackingArea = [[NSTrackingArea alloc]
			   initWithRect:[self bounds]
				options:(NSTrackingMouseEnteredAndExited |
					 NSTrackingMouseMoved |
					 NSTrackingEnabledDuringMouseDrag |
					 NSTrackingInVisibleRect |
					 NSTrackingActiveAlways)
				  owner:self
			       userInfo:nil];
        [self addTrackingArea:trackingArea];
    }
    return self;
}

/*
 * We will just use drawRect.
 */

- (BOOL) wantsUpdateLayer
{
    return NO;
}

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
- (void) viewDidChangeBackingProperties
{

    /*
     * Make sure that the layer uses a contentScale that matches the
     * backing scale factor of the screen.  This avoids blurry text when
     * the view is on a Retina display, as well as incorrect size when
     * the view is on a normal display.
     */

    self.layer.contentsScale = self.window.screen.backingScaleFactor;
}
#endif

- (void) addTkDirtyRect: (NSRect) rect
{
    _tkNeedsDisplay = YES;
    _tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
    [NSApp setNeedsToDraw:YES];
    [self setNeedsDisplay:YES];
    [[self layer] setNeedsDisplay];
}

- (void) clearTkDirtyRect
{
    _tkNeedsDisplay = NO;
    _tkDirtyRect = NSZeroRect;
    [NSApp setNeedsToDraw:NO];
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
	[w respondsToSelector: @selector (tkLayoutChanged)]) {
	[(TKWindow *)w tkLayoutChanged];
    }

    if (winPtr) {
	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;

	/*
	 * This can be called from outside the Tk event loop.  Since it calls
	 * Tcl_DoOneEvent, we need to make sure we don't clobber the
	 * AutoreleasePool set up by the caller.
	 */







|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
	[w respondsToSelector: @selector (tkLayoutChanged)]) {
	[(TKWindow *)w tkLayoutChanged];
    }

    if (winPtr) {
	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	void *oldArg;
    	Tk_RestrictProc *oldProc;

	/*
	 * This can be called from outside the Tk event loop.  Since it calls
	 * Tcl_DoOneEvent, we need to make sure we don't clobber the
	 * AutoreleasePool set up by the caller.
	 */
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053

- (void) generateExposeEvents: (NSRect) rect
{
    unsigned long serial;
    int updatesNeeded;
    CGRect updateBounds;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    if (!winPtr) {
	return;
    }

    /*
     * Generate Tk Expose events.  All of these events will share the same







|







1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

- (void) generateExposeEvents: (NSRect) rect
{
    unsigned long serial;
    int updatesNeeded;
    CGRect updateBounds;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    void *oldArg;
    Tk_RestrictProc *oldProc;
    if (!winPtr) {
	return;
    }

    /*
     * Generate Tk Expose events.  All of these events will share the same
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
    static const char *defaultColor = NULL;

    if (effectiveAppearanceName == NSAppearanceNameAqua) {
	Tk_SendVirtualEvent(tkwin, "LightAqua", NULL);
    } else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) {
	Tk_SendVirtualEvent(tkwin, "DarkAqua", NULL);
    }
    if ([NSApp macOSVersion] < 101500) {

	/*
	 * Mojave cannot handle the KVO shenanigans that we need for the
	 * highlight and accent color notifications.
	 */

	return;
    }
    if (!defaultColor) {
	defaultColor = [NSApp macOSVersion] < 110000 ? "Blue" : "Multicolor";
	preferences = [[NSUserDefaults standardUserDefaults] retain];

	/*
	 * AppKit calls this method when the user changes the Accent Color
	 * but not when the user changes the Highlight Color.  So we register
	 * to receive KVO notifications for Highlight Color as well.
	 */

	[preferences addObserver:self
		      forKeyPath:@"AppleHighlightColor"
			 options:NSKeyValueObservingOptionNew
			 context:NULL];
    }
    NSString *accent = [preferences stringForKey:@"AppleAccentColor"];
    NSArray *words = [[preferences stringForKey:@"AppleHighlightColor"]
			        componentsSeparatedByString: @" "];
    NSString *highlight = [words count] > 3 ? [words objectAtIndex:3] : nil;
    const char *accentName = accent ? accentNames[1 + accent.intValue] : defaultColor;
    const char *highlightName = highlight ? highlight.UTF8String: defaultColor;
    char data[256];
    snprintf(data, 256, "Appearance %s Accent %s Highlight %s",
	     effectiveAppearanceName.UTF8String, accentName,
	     highlightName);
    Tk_SendVirtualEvent(tkwin, "AppearanceChanged", Tcl_NewStringObj(data, -1));
}

- (void)observeValueForKeyPath:(NSString *)keyPath
		      ofObject:(id)object
			change:(NSDictionary *)change
		       context:(void *)context
{


    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    if (object == preferences && [keyPath isEqualToString:@"AppleHighlightColor"]) {
	if (@available(macOS 10.14, *)) {
	    [self viewDidChangeEffectiveAppearance];
	}
    }
}

#endif

/*
 * This is no-op on 10.7 and up because Apple has removed this widget, but we
 * are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window)winPtr;
    (void)sender;

    if (!winPtr){
	return;
    }
    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.send_event = false;
    event.display = Tk_Display(tkwin);
    event.event = Tk_WindowId(tkwin);
    event.root = XRootWindow(Tk_Display(tkwin), 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.x_root, &event.y_root, &x, &y, &event.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
    event.same_screen = true;
    event.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

/*
 * On Catalina this is never called and drawRect clips to the rect that
 * is passed to it by AppKit.
 */








<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<











|







>
>


















|

|








|
|
|
|
|
|
|
|
|

|
|
|
|
|







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
    static const char *defaultColor = NULL;

    if (effectiveAppearanceName == NSAppearanceNameAqua) {
	Tk_SendVirtualEvent(tkwin, "LightAqua", NULL);
    } else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) {
	Tk_SendVirtualEvent(tkwin, "DarkAqua", NULL);
    }









    if (!defaultColor) {
	defaultColor = [NSApp macOSVersion] < 110000 ? "Blue" : "Multicolor";












    }
    NSString *accent = [preferences stringForKey:@"AppleAccentColor"];
    NSArray *words = [[preferences stringForKey:@"AppleHighlightColor"]
			        componentsSeparatedByString: @" "];
    NSString *highlight = [words count] > 3 ? [words objectAtIndex:3] : nil;
    const char *accentName = accent ? accentNames[1 + accent.intValue] : defaultColor;
    const char *highlightName = highlight ? highlight.UTF8String: defaultColor;
    char data[256];
    snprintf(data, 256, "Appearance %s Accent %s Highlight %s",
	     effectiveAppearanceName.UTF8String, accentName,
	     highlightName);
    Tk_SendVirtualEvent(tkwin, "AppearanceChanged", Tcl_NewStringObj(data, TCL_INDEX_NONE));
}

- (void)observeValueForKeyPath:(NSString *)keyPath
		      ofObject:(id)object
			change:(NSDictionary *)change
		       context:(void *)context
{
    (void) change;
    (void) context;
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    if (object == preferences && [keyPath isEqualToString:@"AppleHighlightColor"]) {
	if (@available(macOS 10.14, *)) {
	    [self viewDidChangeEffectiveAppearance];
	}
    }
}

#endif

/*
 * This is no-op on 10.7 and up because Apple has removed this widget, but we
 * are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), sender);
#endif
    union {XEvent general; XVirtualEvent virt;} event;
    int x, y;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    Tk_Window tkwin = (Tk_Window)winPtr;
    (void)sender;

    if (!winPtr){
	return;
    }
    bzero(&event, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.virt.send_event = false;
    event.virt.display = Tk_Display(tkwin);
    event.virt.event = Tk_WindowId(tkwin);
    event.virt.root = XRootWindow(Tk_Display(tkwin), 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();
    XQueryPointer(NULL, winPtr->window, NULL, NULL,
	    &event.virt.x_root, &event.virt.y_root, &x, &y, &event.virt.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.virt.x, &event.virt.y);
    event.virt.same_screen = true;
    event.virt.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

/*
 * On Catalina this is never called and drawRect clips to the rect that
 * is passed to it by AppKit.
 */

1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
 */

- (void) keyDown: (NSEvent *) theEvent
{
    (void)theEvent;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
}

/*
 * When the services menu is opened this is called for each Responder in
 * the Responder chain until a service provider is found.  The TKContentView
 * should be the first (and generally only) Responder in the chain.  We







|







1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
 */

- (void) keyDown: (NSEvent *) theEvent
{
    (void)theEvent;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), theEvent);
#endif
}

/*
 * When the services menu is opened this is called for each Responder in
 * the Responder chain until a service provider is found.  The TKContentView
 * should be the first (and generally only) Responder in the chain.  We

Changes to macosx/tkMacOSXWm.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * 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.
 *
 * 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"







|
|
|
|
|







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 © 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"
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_WINDOWS
#endif
*/

/*
 * Window attributes and classes
 */

#define WM_NSMASK_SHIFT 36
#define tkWindowDoesNotHideAttribute \
	((UInt64) 1 << kHIWindowBitDoesNotHide)
#define tkCanJoinAllSpacesAttribute \
	((UInt64) NSWindowCollectionBehaviorCanJoinAllSpaces << 34)







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_WINDOWS
#endif
*/

/*
 * Carbon window attributes and classes.
 */

#define WM_NSMASK_SHIFT 36
#define tkWindowDoesNotHideAttribute \
	((UInt64) 1 << kHIWindowBitDoesNotHide)
#define tkCanJoinAllSpacesAttribute \
	((UInt64) NSWindowCollectionBehaviorCanJoinAllSpaces << 34)
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
	.forceOffAttrs = kWindowCollapseBoxAttribute,
	.flags = WM_TOPMOST,
	.styleMask = NSUtilityWindowMask, },
    [kHelpWindowClass] = {
	.defaultAttrs = kWindowHideOnSuspendAttribute,
	.forceOnAttrs = kWindowNoTitleBarAttribute |
		kWindowDoesNotCycleAttribute,
	.flags = WM_TOPMOST, },

    [kSheetWindowClass] = {
	.validAttrs = kWindowResizableAttribute,
	.forceOnAttrs = kWindowNoTitleBarAttribute |
		kWindowDoesNotCycleAttribute,
	.styleMask = NSDocModalWindowMask, },
    [kToolbarWindowClass] = {
	.defaultAttrs = kWindowHideOnSuspendAttribute,







|
>







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
	.forceOffAttrs = kWindowCollapseBoxAttribute,
	.flags = WM_TOPMOST,
	.styleMask = NSUtilityWindowMask, },
    [kHelpWindowClass] = {
	.defaultAttrs = kWindowHideOnSuspendAttribute,
	.forceOnAttrs = kWindowNoTitleBarAttribute |
		kWindowDoesNotCycleAttribute,
	.flags = WM_TOPMOST,
        .styleMask = 0},
    [kSheetWindowClass] = {
	.validAttrs = kWindowResizableAttribute,
	.forceOnAttrs = kWindowNoTitleBarAttribute |
		kWindowDoesNotCycleAttribute,
	.styleMask = NSDocModalWindowMask, },
    [kToolbarWindowClass] = {
	.defaultAttrs = kWindowHideOnSuspendAttribute,
146
147
148
149
150
151
152


153



















































154

















155







































































156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324




















































































325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357






358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
};

#define ForceAttributes(attributes, class) \
	((attributes) & (~macClassAttrs[(class)].forceOffAttrs | \
	(macClassAttrs[(class)].forceOnAttrs & ~kWindowResizableAttribute)))

/*


 * Data for [wm attributes] command:



















































 */

























































































typedef enum {
    WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY,
    WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT,

    WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-fullscreen", "-modified", "-notify",
    "-titlepath", "-topmost", "-transparent",
    "-type", NULL
};

/*
 * The variable below is used to enable or disable tracing in this module. If
 * tracing is enabled, then information is printed on standard output about
 * interesting interactions with the window manager.
 */

static int wmTracing = 0;

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};

/*
 * The following keeps state for Aqua dock icon bounce notification.
 */

static int tkMacOSXWmAttrNotifyVal = 0;

/*
 * Forward declarations for procedures defined in this file:
 */

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);
static int		ParseGeometry(Tcl_Interp *interp, char *string,
			    TkWindow *winPtr);
static void		TopLevelEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *table);
static void		UpdateGeometryInfo(ClientData clientData);
static void		UpdateSizeHints(TkWindow *winPtr);
static void		UpdateVRootGeometry(WmInfo *wmPtr);
static int		WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);



static int		WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
static int		WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		WmWinTabbingId(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		WmWinAppearance(Tcl_Interp *interp, TkWindow *winPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
			    NSWindow *macWindow, UInt64 oldAttributes,
			    int oldFlags, int create, int initial);
static void		ApplyContainerOverrideChanges(TkWindow *winPtr,
			    NSWindow *macWindow);
static void		GetMinSize(TkWindow *winPtr, int *minWidthPtr,
			    int *minHeightPtr);
static void		GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		RemapWindows(TkWindow *winPtr,
			    MacDrawable *parentWin);
static void             RemoveTransient(TkWindow *winPtr);





















































































#pragma mark NSWindow(TKWm)

@implementation NSWindow(TKWm)

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    NSRect pointrect = {point, {0,0}};
    return [self convertRectToScreen:pointrect].origin;
}

- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    NSRect pointrect = {point, {0,0}};
    return [self convertRectFromScreen:pointrect].origin;
}
#endif

@end

#pragma mark -

@implementation TKPanel: NSPanel
@synthesize tkWindow = _tkWindow;






@end

@implementation TKDrawerWindow: NSWindow
@synthesize tkWindow = _tkWindow;
@end

@implementation TKWindow: NSWindow
@synthesize mouseInResizeArea = _mouseInResizeArea;
@synthesize tkWindow = _tkWindow;
@end

#pragma mark TKWindow(TKWm)

@implementation TKWindow(TKWm)

/*
 * This method synchronizes Tk's understanding of the bounds of a contentView
 * with the window's.  It is needed because there are situations when the
 * window manager can change the layout of an NSWindow without having been
 * requested to do so by Tk.  Examples are when a window goes FullScreen or
 * shows a tab bar.  NSWindow methods which involve such layout changes should
 * be overridden or protected by methods which call this.
 */

- (void) tkLayoutChanged
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);

    if (winPtr) {
	NSRect frameRect;

	/*
	 * This avoids including the title bar for full screen windows
	 * but does include it for normal windows.
	 */

	if ([self styleMask] & NSFullScreenWindowMask) {
 	    frameRect = [NSWindow frameRectForContentRect:NSZeroRect
		    styleMask:[self styleMask]];
	} else {
	    frameRect = [self frameRectForContentRect:NSZeroRect];
	}

	WmInfo *wmPtr = winPtr->wmInfoPtr;

	wmPtr->xInParent = -frameRect.origin.x;
	wmPtr->yInParent = frameRect.origin.y + frameRect.size.height;
	wmPtr->parentWidth = winPtr->changes.width + frameRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + frameRect.size.height;
    }
}

#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 101200)
- (void)toggleTabBar:(id)sender
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    if (!winPtr) {
	return;
    }
    [super toggleTabBar:sender];







>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
>
|



|
|
|















|














|






|



|



|


|


|


|


|


|


|


|


|


|


|


|

>
>
>

|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|



|
<
<

|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















>






<






>
>
>
>
>
>







<







<
<
<
<
<
<
<
<
<


<
|
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454


455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605









606
607

608


609




610
















611
612
613
614
615
616
617
618
};

#define ForceAttributes(attributes, class) \
	((attributes) & (~macClassAttrs[(class)].forceOffAttrs | \
	(macClassAttrs[(class)].forceOnAttrs & ~kWindowResizableAttribute)))

/*
 * Structures and data for the wm attributes command (macOS 10.13 and later):
 */

/* Hash tables for attributes which can be set before a window exists */
static Tcl_HashTable pathnameToSubclass;
static Tcl_HashTable pathnameToTabbingId;
static Tcl_HashTable pathnameToTabbingMode;

enum NSWindowSubclass {
    subclassNSWindow = 0,
    subclassNSPanel = 1
};
/* This array must be indexed by the enum above.*/
static const char *subclassNames[] = {"nswindow", "nspanel", NULL};

typedef struct buttonField_t {
    unsigned zoom: 1;
    unsigned miniaturize: 1;
    unsigned close: 1;
} buttonField;

/* The order of these names must match the order of the bits above! */
static const char *buttonNames[] = {"zoom", "miniaturize", "close", NULL};

typedef union windowButtonState_t {
    int intvalue;
    buttonField bits;
} windowButtonState;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
enum NSWindowClass {
    NSWindowClass_any = 0,
    NSWindowClass_window = 1,
    NSWindowClass_panel = 2
};
typedef struct styleMaskBit_t {
    const char *bitname;
    unsigned long bitvalue;
    enum NSWindowClass allowed;
} styleMaskBit;

static const styleMaskBit styleMaskBits[] = {
    /* Make the titlebar visible and use round corners. */
    {"titled", NSWindowStyleMaskTitled, NSWindowClass_window},
    /* Enable the close button. */
    {"closable", NSWindowStyleMaskClosable, NSWindowClass_window},
    /* Enable the miniaturize button. */
    {"miniaturizable", NSWindowStyleMaskMiniaturizable, NSWindowClass_window},
    /* Allow the user to resize the window. */
    {"resizable", NSWindowStyleMaskResizable, NSWindowClass_window},
    /*
     * Make the content view extend under the titlebar.  We force
     * titlebarAppearsTransparent when this bit is set.  Otherwise it is
     * pretty useless.
     */
    {"fullsizecontentview", NSWindowStyleMaskFullSizeContentView, NSWindowClass_window},
    /* Rounded corners, cannot have a titlebar (overrides titled bit). */
    {"docmodal", NSWindowStyleMaskDocModalWindow, NSWindowClass_any},
    /* ============================================
     * The following bits are only valid for panels.
     */
    /* Make the title bar thinner. */
    {"utility", NSWindowStyleMaskUtilityWindow, NSWindowClass_panel},
    /* Do not activate the app when the window is activated. */
    {"nonactivatingpanel", NSWindowStyleMaskNonactivatingPanel, NSWindowClass_panel},
    /*
     * Requires utility.  Cannot be resizable.  Close button is an X; no other buttons.
     * Cannot be a docmodal.
     */
    {"HUDwindow", NSWindowStyleMaskHUDWindow, NSWindowClass_panel},
    {NULL, 0, NSWindowClass_any}
};

typedef struct tabbingMode_t {
    const char *modeName;
    long modeValue;
} tabbingMode;

static const tabbingMode tabbingModes[] = {
    {"auto",  NSWindowTabbingModeAutomatic},
    {"disallowed", NSWindowTabbingModeDisallowed},
    {"preferred", NSWindowTabbingModePreferred},
    {NULL, -1}
};

static const char *const appearanceStrings[] = {
    "aqua", "auto", "darkaqua", NULL
};
enum appearances {
    APPEARANCE_AQUA, APPEARANCE_AUTO, APPEARANCE_DARKAQUA
};

static Bool wantsToBeTab(NSWindow *macWindow) {
    Bool result;
    switch ([macWindow tabbingMode]) {
    case NSWindowTabbingModeDisallowed:
	result = False;
	break;
    case NSWindowTabbingModePreferred:
	result = True;
	break;
    case NSWindowTabbingModeAutomatic:
	result = ([NSWindow userTabbingPreference] ==
		NSWindowUserTabbingPreferenceAlways);
	break;
    default:
	result = False;
	break;
    }
    return result;
}

/*
 * Helper for the tkLayoutChanged methods.  Synchronizes Tk's understanding of
 * the bounds of a contentView with the window's.  It is needed because there
 * are situations when the window manager can change the layout of an NSWindow
 * without having been requested to do so by Tk.  Examples are when a window
 * goes FullScreen or shows a tab bar.  NSWindow methods which involve such
 * layout changes should be overridden or protected by methods which call this.
 */

static void syncLayout(NSWindow *macWindow)
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(macWindow);

    if (winPtr) {
	// Using screen coordinates with origin at bottom left.
	NSRect frameRect = [macWindow frame];
	// This accounts for the tab bar, if there is one.
	NSRect contentRect = [macWindow contentRectForFrameRect: frameRect];
	WmInfo *wmPtr = winPtr->wmInfoPtr;

	// The parent includes the title bar, tab bar and window frame.
	wmPtr->xInParent = frameRect.origin.x - contentRect.origin.x;
	wmPtr->yInParent = (frameRect.origin.y + frameRect.size.height -
	    contentRect.origin.y - contentRect.size.height);
	wmPtr->parentWidth = winPtr->changes.width + frameRect.size.width -
	    contentRect.size.width;
	wmPtr->parentHeight = winPtr->changes.height + frameRect.size.height -
	    contentRect.size.height;
    }
}
#endif

typedef enum {
    WMATT_ALPHA, WMATT_APPEARANCE, WMATT_BUTTONS, WMATT_FULLSCREEN,
    WMATT_ISDARK, WMATT_MODIFIED, WMATT_NOTIFY, WMATT_TITLEPATH, WMATT_TOPMOST,
    WMATT_TRANSPARENT, WMATT_STYLEMASK, WMATT_CLASS, WMATT_TABBINGID,
    WMATT_TABBINGMODE, WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-appearance", "-buttons", "-fullscreen", "-isdark", "-modified",
    "-notify", "-titlepath", "-topmost", "-transparent", "-stylemask", "-class",
    "-tabbingid", "-tabbingmode", "-type", NULL
};

/*
 * The variable below is used to enable or disable tracing in this module. If
 * tracing is enabled, then information is printed on standard output about
 * interesting interactions with the window manager.
 */

static int wmTracing = 0;

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void TopLevelReqProc(void *dummy, Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};

/*
 * The following keeps state for Aqua dock icon bounce notification.
 */

static int tkMacOSXWmAttrNotifyVal = 0;

/*
 * Declarations of static functions defined in this file:
 */

static NSRect		InitialWindowBounds(TkWindow *winPtr,
			    NSWindow *macWindow);
static int		ParseGeometry(Tcl_Interp *interp, char *string,
			    TkWindow *winPtr);
static void		TopLevelEventProc(void *clientData,
			    XEvent *eventPtr);
static void		WmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *table);
static void		UpdateGeometryInfo(void *clientData);
static void		UpdateSizeHints(TkWindow *winPtr);
static void		UpdateVRootGeometry(WmInfo *wmPtr);
static int		WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbadgeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
static int		WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);


static int		WmWinAppearance(Tcl_Interp *interp, TkWindow *winPtr,
			    Tcl_Size objc, Tcl_Obj *const objv[]);
static void		ApplyWindowAttributeFlagChanges(TkWindow *winPtr,
			    NSWindow *macWindow, UInt64 oldAttributes,
			    int oldFlags, int create, int initial);
static void		ApplyContainerOverrideChanges(TkWindow *winPtr,
			    NSWindow *macWindow);
static void		GetMinSize(TkWindow *winPtr, int *minWidthPtr,
			    int *minHeightPtr);
static void		GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		RemapWindows(TkWindow *winPtr,
			    MacDrawable *parentWin);
static void             RemoveTransient(TkWindow *winPtr);

#if MAC_OS_X_VERSION_MAX_ALLOWED > 101300

/*
 * Add a window as a tab in the group specified by its tabbingid, or
 * make it a standalone window if it is the only window with that
 * tabbingid.  Adjust the window size if a tab bar appeared or
 * disappeared.
 */

static void placeAsTab(TKWindow *macWindow) {
    TkWindow *winPtr = NULL, *winPtr2 = NULL;
    TKWindow *target = NULL, *sibling = NULL;
    NSString *identifier = [macWindow tabbingIdentifier];
    if (!wantsToBeTab(macWindow)) {
	[macWindow moveTabToNewWindow:NSApp];
	[(TKWindow *)target tkLayoutChanged];
	return;
    }
    for (NSWindow *window in [NSApp windows]) {
	if (window == macWindow) {
	    continue;
	}
	if ([identifier isEqualTo: [window tabbingIdentifier]] &&
	    wantsToBeTab(window)) {
	    target = (TKWindow*) window;
	    syncLayout(target);
	    break;
	}
    }
    syncLayout(macWindow);
    NSArray<NSWindow *> *tabs = [macWindow tabbedWindows];
    if ([tabs count] == 2) {
	sibling = tabs[0] == macWindow ? (TKWindow *)tabs[1] : (TKWindow *)tabs[0];
	syncLayout(sibling);
	winPtr2 = TkMacOSXGetTkWindow(sibling);
    }
    if (target) {
	CGFloat winHeight = [macWindow contentRectForFrameRect:
				[macWindow frame]].size.height;
	CGFloat winDelta = 0, targetHeight, targetDelta = 0;
	targetHeight =  [target contentRectForFrameRect:
			    [target frame]].size.height;
	[target addTabbedWindow:macWindow ordered:NSWindowAbove];
	targetDelta = targetHeight - [target contentRectForFrameRect:
					 [target frame]].size.height;
	winDelta = winHeight - [target contentRectForFrameRect:
				   [target frame]].size.height;
	if (winDelta) {
	    winPtr = TkMacOSXGetTkWindow(macWindow);
	    XMoveResizeWindow(winPtr->display, winPtr->window,
			      winPtr->changes.x, winPtr->changes.y,
			      winPtr->changes.width, winPtr->changes.height + winDelta );
	    if (sibling) {
		winPtr = TkMacOSXGetTkWindow(sibling);
		XMoveResizeWindow(winPtr->display, winPtr->window,
				  winPtr->changes.x, winPtr->changes.y,
				  winPtr->changes.width, winPtr->changes.height - winDelta );
	    }
	}
	if (targetDelta) {
	    winPtr = TkMacOSXGetTkWindow(target);
	    XMoveResizeWindow(winPtr->display, winPtr->window,
			      winPtr->changes.x, winPtr->changes.y,
			      winPtr->changes.width, winPtr->changes.height + targetDelta );
	}
    } else {
	CGFloat height = [macWindow contentRectForFrameRect:
			     [macWindow frame]].size.height;
	[macWindow moveTabToNewWindow:NSApp];
	CGFloat delta = height - [macWindow contentRectForFrameRect:
			    [macWindow frame]].size.height;
	winPtr = TkMacOSXGetTkWindow(macWindow);
	XMoveResizeWindow(winPtr->display, winPtr->window,
			  winPtr->changes.x, winPtr->changes.y,
			  winPtr->changes.width, winPtr->changes.height + delta);
	if (winPtr2) {
	    XMoveResizeWindow(winPtr2->display, winPtr2->window,
			      winPtr2->changes.x, winPtr2->changes.y,
			      winPtr2->changes.width, winPtr2->changes.height + delta );
	}
    }
}
#endif

#pragma mark NSWindow(TKWm)

@implementation NSWindow(TKWm)

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    NSRect pointrect = {point, {0,0}};
    return [self convertRectToScreen:pointrect].origin;
}

- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    NSRect pointrect = {point, {0,0}};
    return [self convertRectFromScreen:pointrect].origin;
}
#endif

@end

#pragma mark -

@implementation TKPanel: NSPanel
@synthesize tkWindow = _tkWindow;

- (void) tkLayoutChanged
{
    syncLayout(self);
}

@end

@implementation TKDrawerWindow: NSWindow
@synthesize tkWindow = _tkWindow;
@end

@implementation TKWindow: NSWindow

@synthesize tkWindow = _tkWindow;
@end

#pragma mark TKWindow(TKWm)

@implementation TKWindow(TKWm)










- (void) tkLayoutChanged
{

    syncLayout(self);


}





















#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
- (void)toggleTabBar:(id)sender
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    if (!winPtr) {
	return;
    }
    [super toggleTabBar:sender];
721
722
723
724
725
726
727


728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    wmPtr->macClass = kDocumentWindowClass;
    wmPtr->attributes = macClassAttrs[kDocumentWindowClass].defaultAttrs;
    wmPtr->scrollWinPtr = NULL;
    wmPtr->menuPtr = NULL;
    wmPtr->window = nil;
    winPtr->wmInfoPtr = wmPtr;



    UpdateVRootGeometry(wmPtr);

    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window)winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window)winPtr, &wmMgrType, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXHandleMapOrUnmap --
 *
 *      The mechanism used by a geometry manager to propogate the information
 *      about which of its content widgets are mapped is to call Tk_MapWindow
 *      or Tk_UnmapNotify.  Those functions generate MapNotify or UnmapNotify
 *      events and then handle them immediately.  Other platforms use
 *      Tk_HandleEvent to do this.  But that does not work correctly on macOS
 *      due to the fact that the calls to Tk_MapNotify or Tk_UnmapNotify can
 *      occur in display procedures which are being run in the drawRect method
 *      of a TKContentView. The events will be processed after drawRect
 *      returns, but they need to be processed immediately in some cases.

 *      This function operates as a macOS alternative to Tk_HandleEvent, for
 *      processing MapNotify or UnmapNotify events only.  It is called by
 *      Tk_MapWindow, Tk_UnmapWindow, TkWmMapWindow and TkWmUnmapWindow.
 *      Rather than using Tk_HandleEvent it installs a filter which restricts
 *      to the MapNotify or UnmapNotify events, it queues the event and then
 *      processes window events with the filter installed.  This allows the
 *      event to be handled immediately even from within the drawRect method.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Handles a MapNotify or UnMapNotify event.
 *
 *----------------------------------------------------------------------
 */
static Tk_RestrictAction
MapUnmapRestrictProc(
    TCL_UNUSED(void*),
    XEvent *eventPtr)
{
    return (eventPtr->type==MapNotify || eventPtr->type==UnmapNotify ?
	    TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

MODULE_SCOPE
void TkMacOSXHandleMapOrUnmap(
    Tk_Window tkwin,
    XEvent *event)
{
    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    TkWindow *winPtr = (TkWindow *) tkwin;
    const Tk_GeomMgr *geomMgrPtr = winPtr->geomMgrPtr;

    /*
     * Sadly, this approach does not work with the "text" geometry manager.
     * The mysterious unexplained crash elicited by textDisp-5.2 occurs.  So we
     * have to check for the "text" manager and revert to using Tk_HandleEvent
     * in that case.  Hopefully this can be removed when the revised text
     * widget is in place.
     */

    if (geomMgrPtr && strcmp(geomMgrPtr->name, "text") == 0) {
	Tk_HandleEvent(event);
	return;
    }
    oldProc = Tk_RestrictEvents(MapUnmapRestrictProc, NULL, &oldArg);
    Tk_QueueWindowEvent(event, TCL_QUEUE_TAIL);
    while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT)) {}
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmMapWindow --
 *
 *	This procedure is invoked to map a top-level window. This module gets







>
>

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
    wmPtr->macClass = kDocumentWindowClass;
    wmPtr->attributes = macClassAttrs[kDocumentWindowClass].defaultAttrs;
    wmPtr->scrollWinPtr = NULL;
    wmPtr->menuPtr = NULL;
    wmPtr->window = nil;
    winPtr->wmInfoPtr = wmPtr;

    // initialize wmPtr->NSWindowSubclass here

    UpdateVRootGeometry(wmPtr);

    /*
     * Tk must monitor structure events for top-level windows, in order to
     * detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window)winPtr, StructureNotifyMask,
	    TopLevelEventProc, winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window to the
     * window manager.
     */

    Tk_ManageGeometry((Tk_Window)winPtr, &wmMgrType, NULL);
}





































































/*
 *----------------------------------------------------------------------
 *
 * TkWmMapWindow --
 *
 *	This procedure is invoked to map a top-level window. This module gets
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
    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 --
 *







|







1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
    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;
    Tk_HandleEvent(&event);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
938
939
940
941
942
943
944



945
946
947
948
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963
 */

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 --
 *







>
>
>
|

|
|
|
|
|
|
|
<
<
|
>







1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091


1092
1093
1094
1095
1096
1097
1098
1099
1100
 */

void
TkWmUnmapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * unmapped. */
{
    winPtr->flags &= ~TK_MAPPED;
    if ((winPtr->window != None)
	    && (XUnmapWindow(winPtr->display, winPtr->window) == Success)) {
	XEvent event;

	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;


	Tk_HandleEvent(&event);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmDeadWindow --
 *
1046
1047
1048
1049
1050
1051
1052


























1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067

    while (wmPtr->transientPtr != NULL) {
	Transient *transientPtr = wmPtr->transientPtr;

	wmPtr->transientPtr = transientPtr->nextPtr;
	ckfree(transientPtr);
    }



























    /*
     * Unregister the NSWindow and remove all references to it from the Tk
     * data structures.  If the NSWindow is a child, disassociate it from
     * the parent.  Then close and release the NSWindow.
     */

    deadNSWindow = (TKWindow *)wmPtr->window;
    if (deadNSWindow && !Tk_IsEmbedded(winPtr)) {
	NSWindow *parent = [deadNSWindow parentWindow];
	[deadNSWindow setTkWindow:None];
        if (winPtr->window) {
            ((MacDrawable *)winPtr->window)->view = nil;
        }
	wmPtr->window = NULL;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







<







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

    while (wmPtr->transientPtr != NULL) {
	Transient *transientPtr = wmPtr->transientPtr;

	wmPtr->transientPtr = transientPtr->nextPtr;
	ckfree(transientPtr);
    }

    deadNSWindow = (TKWindow *)wmPtr->window;

    /*
     * Remove references to the Tk window from the mouse event processing
     * state which is recorded in the NSApplication object.
     */

    if (winPtr == [NSApp tkPointerWindow]) {
	NSWindow *w;
	NSPoint mouse = [NSEvent mouseLocation];
	[NSApp setTkPointerWindow:nil];
	for (w in [NSApp orderedWindows]) {
	    if (w == deadNSWindow) {
		continue;
	    }
	    if (NSPointInRect(mouse, [w frame])) {
		TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
		int x = mouse.x, y = TkMacOSXZeroScreenHeight() - mouse.y;
		[NSApp setTkPointerWindow:winPtr2];
		Tk_UpdatePointer((Tk_Window) winPtr2, x, y,
				 [NSApp tkButtonState]);
		break;
	    }
	}
    }

    /*
     * Unregister the NSWindow and remove all references to it from the Tk
     * data structures.  If the NSWindow is a child, disassociate it from
     * the parent.  Then close and release the NSWindow.
     */


    if (deadNSWindow && !Tk_IsEmbedded(winPtr)) {
	NSWindow *parent = [deadNSWindow parentWindow];
	[deadNSWindow setTkWindow:None];
        if (winPtr->window) {
            ((MacDrawable *)winPtr->window)->view = nil;
        }
	wmPtr->window = NULL;
1090
1091
1092
1093
1094
1095
1096







1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111


1112
1113
1114
1115
1116
1117
1118
1119
1120
1121





1122
1123
1124
1125
1126
1127
1128
1129
1130
	 * there is no choice for a new key window.  Moreover, if the host
	 * computer has a TouchBar then the TouchBar holds a reference to the
	 * key window which prevents it from being deallocated until it stops
	 * being the key window.  On these systems the only option for
	 * preventing zombies is to set the key window to nil.
	 */








	for (NSWindow *w in [NSApp orderedWindows]) {
	    TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
	    BOOL isOnScreen;

	    if (!winPtr2 || !winPtr2->wmInfoPtr) {
		continue;
	    }
	    wmPtr2 = winPtr2->wmInfoPtr;
	    isOnScreen = (wmPtr2->hints.initial_state != IconicState &&
			  wmPtr2->hints.initial_state != WithdrawnState);
	    if (w != deadNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
		[w makeKeyAndOrderFront:NSApp];

		break;
	    }
	}



	/*
	 * Prevent zombies on systems with a TouchBar.
	 */

	if (deadNSWindow == [NSApp keyWindow]) {
	    [NSApp _setKeyWindow:nil];
	    [NSApp _setMainWindow:nil];
	}
	[deadNSWindow close];





	[deadNSWindow release];
	[NSApp _resetAutoreleasePool];

#if DEBUG_ZOMBIES > 1
	fprintf(stderr, "================= Pool dump ===================\n");
	[NSAutoreleasePool showPools];
#endif

    }







>
>
>
>
>
>
>












>



>
>










>
>
>
>
>

<







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
	 * there is no choice for a new key window.  Moreover, if the host
	 * computer has a TouchBar then the TouchBar holds a reference to the
	 * key window which prevents it from being deallocated until it stops
	 * being the key window.  On these systems the only option for
	 * preventing zombies is to set the key window to nil.
	 */


	/*
	 * Fix bug 5692042764:
	 * set tkEventTarget to NULL when there is no window to send Tk events to.
	 */
	TkWindow *newTkEventTarget = NULL;

	for (NSWindow *w in [NSApp orderedWindows]) {
	    TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
	    BOOL isOnScreen;

	    if (!winPtr2 || !winPtr2->wmInfoPtr) {
		continue;
	    }
	    wmPtr2 = winPtr2->wmInfoPtr;
	    isOnScreen = (wmPtr2->hints.initial_state != IconicState &&
			  wmPtr2->hints.initial_state != WithdrawnState);
	    if (w != deadNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
		[w makeKeyAndOrderFront:NSApp];
		newTkEventTarget = TkMacOSXGetTkWindow(w);
		break;
	    }
	}

	[NSApp setTkEventTarget:newTkEventTarget];

	/*
	 * Prevent zombies on systems with a TouchBar.
	 */

	if (deadNSWindow == [NSApp keyWindow]) {
	    [NSApp _setKeyWindow:nil];
	    [NSApp _setMainWindow:nil];
	}
	[deadNSWindow close];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
	[preferences removeObserver:deadNSWindow.contentView
		      forKeyPath:@"AppleHighlightColor"];
#endif
	[deadNSWindow release];


#if DEBUG_ZOMBIES > 1
	fprintf(stderr, "================= Pool dump ===================\n");
	[NSAutoreleasePool showPools];
#endif

    }
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group",
	"iconbitmap", "iconify", "iconmask", "iconname",
	"iconphoto", "iconposition", "iconwindow",
	"manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,
	WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, WMOPT_ICONWINDOW,
	WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW };
    int index, length;

    char *argv1;
    TkWindow *winPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
	    && (length >= 3)) {
	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wmTracing != 0));
	    return TCL_OK;
	}
	return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

























    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
	!= TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr)
	    && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }







|








|









|






|
>

















|









<



>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|


|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group", "iconbadge",
	"iconbitmap", "iconify", "iconmask", "iconname",
	"iconphoto", "iconposition", "iconwindow",
	"manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,  WMOPT_ICONBADGE,
	WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, WMOPT_ICONWINDOW,
	WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW };
    int index;
    Tcl_Size length;
    char *argv1;
    TkWindow *winPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
	    && (length >= 3)) {
	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(wmTracing));
	    return TCL_OK;
	}
	return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }
    if (index == WMOPT_ATTRIBUTES && objc == 5 &&
	strcmp(Tcl_GetString(objv[3]), "-class") == 0) {
	if (TkGetWindowFromObj(NULL, tkwin, objv[2], (Tk_Window *) &winPtr)
	    == TCL_OK) {
	    if (winPtr->wmInfoPtr->window != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Cannot change the class after the mac window is created.",-1));
		Tcl_SetErrorCode(interp, "TK", "CLASS_CHANGE", NULL);
		return TCL_ERROR;
	    }
	} else {
		winPtr = NULL;
	}
    } else if (index == WMOPT_ATTRIBUTES && objc == 5 &&
	       strcmp(Tcl_GetString(objv[3]), "-tabbingid") == 0) {
	    if (TkGetWindowFromObj(NULL, tkwin, objv[2], (Tk_Window *) &winPtr)
		!= TCL_OK) {
		winPtr = NULL;
	    }
    } else if (index == WMOPT_ATTRIBUTES && objc == 5 &&
	       strcmp(Tcl_GetString(objv[3]), "-tabbingmode") == 0) {
	    if (TkGetWindowFromObj(NULL, tkwin, objv[2], (Tk_Window *) &winPtr)
		!= TCL_OK) {
		winPtr = NULL;
	    }
    } else if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
	       != TCL_OK) {
	return TCL_ERROR;
    }
    if (winPtr && !Tk_IsTopLevel(winPtr)
	    && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"window \"%s\" isn't a top-level window", winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName,
		NULL);
	return TCL_ERROR;
    }
1275
1276
1277
1278
1279
1280
1281


1282
1283
1284
1285
1286
1287
1288
	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GEOMETRY:
	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GRID:
	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GROUP:
	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);


    case WMOPT_ICONBITMAP:
	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONIFY:
	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONMASK:
	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONNAME:







>
>







1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GEOMETRY:
	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GRID:
	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GROUP:
	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONBADGE:
	return WmIconbadgeCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONBITMAP:
	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONIFY:
	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONMASK:
	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONNAME:
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,







|







1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;







|







1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
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
    TkWindow *winPtr,		/* Toplevel to work with */
    NSWindow *macWindow,
    Tcl_Interp *interp,		/* Current interpreter */
    WmAttribute attribute,	/* Code of attribute to set */
    Tcl_Obj *value)		/* New value */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int boolean;


    switch (attribute) {
    case WMATT_ALPHA: {
	double dval;

	if (Tcl_GetDoubleFromObj(interp, value, &dval) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * The user should give (transparent) 0 .. 1.0 (opaque)
	 */

	if (dval < 0.0) {
	    dval = 0.0;
	} else if (dval > 1.0) {
	    dval = 1.0;
	}
	[macWindow setAlphaValue:dval];
	break;
    }




















































    case WMATT_FULLSCREEN:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != (([macWindow styleMask] & NSFullScreenWindowMask) != 0)) {
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
	    [macWindow toggleFullScreen:macWindow];
#else
	    TKLog(@"The fullscreen attribute is ignored on this system.");
#endif
	}
	break;
    case WMATT_MODIFIED:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != [macWindow isDocumentEdited]) {
	    [macWindow setDocumentEdited:boolean];
	}
	break;
    case WMATT_NOTIFY:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean == !tkMacOSXWmAttrNotifyVal) {
	    static NSInteger request = -1;

	    if (request >= 0) {
		[NSApp cancelUserAttentionRequest:request];
		request = -1;
	    }
	    if (boolean) {
		request = [NSApp requestUserAttention:NSCriticalRequest];
	    }
	    tkMacOSXWmAttrNotifyVal = boolean;
	}
	break;



















































































































    case WMATT_TITLEPATH: {
	const char *path = Tcl_FSGetNativePath(value);
	NSString *filename = @"";

	if (path && *path) {
	    filename = [NSString stringWithUTF8String:path];
	}
	[macWindow setRepresentedFilename:filename];
	break;
    }
    case WMATT_TOPMOST:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != ((wmPtr->flags & WM_TOPMOST) != 0)) {
	    int oldFlags = wmPtr->flags;

	    if (boolean) {
		wmPtr->flags |= WM_TOPMOST;
	    } else {
		wmPtr->flags &= ~WM_TOPMOST;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow,
		    wmPtr->attributes, oldFlags, 1, 0);
	}
	break;
    case WMATT_TRANSPARENT:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean != ((wmPtr->flags & WM_TRANSPARENT) != 0)) {
	    UInt64 oldAttributes = wmPtr->attributes;
	    int oldFlags = wmPtr->flags;

	    if (boolean) {
		wmPtr->flags |= WM_TRANSPARENT;
		wmPtr->attributes |= kWindowNoShadowAttribute;
	    } else {
		wmPtr->flags &= ~WM_TRANSPARENT;
		wmPtr->attributes &= ~kWindowNoShadowAttribute;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		    oldFlags, 1, 0);
	    [macWindow setBackgroundColor:boolean ? [NSColor clearColor] : nil];
	    [macWindow setOpaque:!boolean];
	    TkMacOSXInvalidateWindow((MacDrawable *)winPtr->window,
		    TK_PARENT_WINDOW);
	    }


	break;
    case WMATT_TYPE:
	TKLog(@"The type attribute is ignored on macOS.");
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	return TCL_ERROR;







|
>





















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|


|
|







|


|
|



|


|






|


|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|









|


|


|









|


|



|








|
|



>
>







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
    TkWindow *winPtr,		/* Toplevel to work with */
    NSWindow *macWindow,
    Tcl_Interp *interp,		/* Current interpreter */
    WmAttribute attribute,	/* Code of attribute to set */
    Tcl_Obj *value)		/* New value */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int boolValue;
    NSString *identifier;

    switch (attribute) {
    case WMATT_ALPHA: {
	double dval;

	if (Tcl_GetDoubleFromObj(interp, value, &dval) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * The user should give (transparent) 0 .. 1.0 (opaque)
	 */

	if (dval < 0.0) {
	    dval = 0.0;
	} else if (dval > 1.0) {
	    dval = 1.0;
	}
	[macWindow setAlphaValue:dval];
	break;
    }
    case WMATT_APPEARANCE: {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp, value, appearanceStrings,
	    sizeof(char *), "appearancename", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum appearances) index) {
	case APPEARANCE_AQUA:
	    macWindow.appearance = [NSAppearance appearanceNamed:
		NSAppearanceNameAqua];
	    break;
	case APPEARANCE_DARKAQUA:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    if (@available(macOS 10.14, *)) {
		macWindow.appearance = [NSAppearance appearanceNamed:
		    NSAppearanceNameDarkAqua];
	    }
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    break;
	default:
	    macWindow.appearance = nil;
	}
	break;
    }
    case WMATT_BUTTONS: {
	windowButtonState state = {0};
	Tcl_Obj **elements;
	Tcl_Size nElements, i;
	if (Tcl_ListObjGetElements(interp, value, &nElements, &elements) == TCL_OK) {
	    int index = 0;
	    for (i = 0; i < nElements; i++) {
		if (Tcl_GetIndexFromObjStruct(interp, elements[i], buttonNames,
		       sizeof(char *), "window button name", 0, &index) != TCL_OK) {
		    return TCL_ERROR;
		} else {
		    state.intvalue |= (1 << index);
		}
	    }
	} else if (Tcl_GetIntFromObj(interp, value, &state.intvalue) != TCL_OK) {
	    return TCL_ERROR;
	}
	NSButton *closer = [macWindow standardWindowButton:
			       NSWindowCloseButton];
	NSButton *miniaturizer = [macWindow standardWindowButton:
				     NSWindowMiniaturizeButton];
	NSButton *zoomer = [macWindow standardWindowButton:
			      NSWindowZoomButton];
	closer.enabled = (state.bits.close != 0);
	miniaturizer.enabled = (state.bits.miniaturize != 0);
	zoomer.enabled = (state.bits.zoom != 0);
	break;
    }
    case WMATT_FULLSCREEN:
	if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolValue != (([macWindow styleMask] & NSFullScreenWindowMask) != 0)) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
	    [macWindow toggleFullScreen:macWindow];
#else
	    TKLog(@"The fullscreen attribute is ignored on this system.");
#endif
	}
	break;
    case WMATT_MODIFIED:
	if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolValue != [macWindow isDocumentEdited]) {
	    [macWindow setDocumentEdited:(BOOL)boolValue];
	}
	break;
    case WMATT_NOTIFY:
	if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolValue == !tkMacOSXWmAttrNotifyVal) {
	    static NSInteger request = -1;

	    if (request >= 0) {
		[NSApp cancelUserAttentionRequest:request];
		request = -1;
	    }
	    if (boolValue) {
		request = [NSApp requestUserAttention:NSCriticalRequest];
	    }
	    tkMacOSXWmAttrNotifyVal = boolValue;
	}
	break;
    case WMATT_STYLEMASK: {
	unsigned long styleMaskValue = 0;
	Tcl_Obj **elements;
	Tcl_Size nElements, i;
	if (Tcl_ListObjGetElements(interp, value, &nElements, &elements) == TCL_OK) {
	    int index;
	    for (i = 0; i < nElements; i++) {
		if (Tcl_GetIndexFromObjStruct(interp, elements[i], styleMaskBits,
		       sizeof(styleMaskBit), "styleMask bit", 0, &index) != TCL_OK) {
		    return TCL_ERROR;
		} else if (![macWindow isKindOfClass: [NSPanel class]] &&
			   styleMaskBits[index].allowed == NSWindowClass_panel) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		        "styleMask bit \"%s\" can only be used with an NSPanel",
			styleMaskBits[index].bitname));
		    Tcl_SetErrorCode(interp, "TK", "INVALID_STYLEMASK_BIT", NULL);
		    return TCL_ERROR;
		} else {
		    styleMaskValue |= styleMaskBits[index].bitvalue;
		}
		/*
		 * Be sure not to change the fullscreen bit.
		 */
		styleMaskValue |= (NSWindowStyleMaskFullScreen & macWindow.styleMask);
	    }
	    /*
	     * A resizable docmodal NSWindow or NSPanel does not work
	     * correctly.  It cannot be resized from the top edge.  Other bits,
	     * such as titled are ignored for docmodals.  To be safe, we clear
	     * all other bits when the docmodal bit is set.
	     */
	    if (styleMaskValue & NSDocModalWindowMask) {
		styleMaskValue &= ~NSWindowStyleMaskResizable;
	    }
	    if ([macWindow isKindOfClass: [NSPanel class]]) {
		/*
		 * We always make NSPanels titled, nonactivating utility windows,
		 * even if these bits are not requested in the command.
		 */
		if (!(styleMaskValue & NSWindowStyleMaskTitled) ) {
		    styleMaskValue |= NSWindowStyleMaskTitled;
		    styleMaskValue |= NSWindowStyleMaskUtilityWindow;
		    styleMaskValue |= NSWindowStyleMaskNonactivatingPanel;
		}
	    }
	    if (styleMaskValue & NSWindowStyleMaskFullSizeContentView) {
		macWindow.titlebarAppearsTransparent = YES;
	    } else {
		macWindow.titlebarAppearsTransparent = NO;
	    }
	} else {
	    return TCL_ERROR;
	}
	NSRect oldFrame = [macWindow frame];
#ifdef DEBUG
	fprintf(stderr, "Current styleMask: %lx\n", [macWindow styleMask]);
	fprintf(stderr, "Setting styleMask to %lx\n", styleMaskValue);
#endif
        macWindow.styleMask = (unsigned long) styleMaskValue;
	NSRect newFrame = [macWindow frame];
	int heightDiff = newFrame.size.height - oldFrame.size.height;
	int newHeight = heightDiff < 0 ? newFrame.size.height :
	    newFrame.size.height - heightDiff;
	[(TKWindow *)macWindow tkLayoutChanged];
	if (heightDiff) {
	    //Calling XMoveResizeWindow twice is a hack to force a relayout
	    //of the window.
	    XMoveResizeWindow(winPtr->display, winPtr->window,
	 		  winPtr->changes.x, winPtr->changes.y,
			  newFrame.size.width, newHeight - 1);
	    XMoveResizeWindow(winPtr->display, winPtr->window,
	 		  winPtr->changes.x, winPtr->changes.y,
			  newFrame.size.width, newHeight);
	}
	break;
    }
    case WMATT_TABBINGID: {
	NSString *oldId = [macWindow tabbingIdentifier];
	char *valueString;
	Tcl_Size length;
	if ([NSApp macOSVersion] < 101300) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		  "Tabbing identifiers require macOS 10.13", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TABBINGID", NULL);
	    return TCL_ERROR;
	}
	valueString = Tcl_GetStringFromObj(value, &length);
	identifier = [NSString stringWithUTF8String:valueString];
	[macWindow setTabbingIdentifier: identifier];

	/*
	 * If the tabbingIdentifier of a tab is changed we move it into
	 * the tab group with that identifier.
	 */

	if ([oldId compare:identifier] != NSOrderedSame) {
	    placeAsTab((TKWindow *)macWindow);
	}
	break;
    }
    case WMATT_TABBINGMODE: {
	int index;
	tabbingMode mode;
	if (Tcl_GetIndexFromObjStruct(interp, value, tabbingModes,
	   sizeof(tabbingMode), "NSWindow Tabbing Mode", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	mode = tabbingModes[index];
	[macWindow setTabbingMode: mode.modeValue];
	placeAsTab((TKWindow *)macWindow);
	break;
    }
    case WMATT_ISDARK: {
	break;
    }
    case WMATT_TITLEPATH: {
	const char *path = (const char *)Tcl_FSGetNativePath(value);
	NSString *filename = @"";

	if (path && *path) {
	    filename = [NSString stringWithUTF8String:path];
	}
	[macWindow setRepresentedFilename:filename];
	break;
    }
    case WMATT_TOPMOST:
	if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolValue != ((wmPtr->flags & WM_TOPMOST) != 0)) {
	    int oldFlags = wmPtr->flags;

	    if (boolValue) {
		wmPtr->flags |= WM_TOPMOST;
	    } else {
		wmPtr->flags &= ~WM_TOPMOST;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow,
		    wmPtr->attributes, oldFlags, 1, 0);
	}
	break;
    case WMATT_TRANSPARENT:
	if (Tcl_GetBooleanFromObj(interp, value, &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolValue != ((wmPtr->flags & WM_TRANSPARENT) != 0)) {
	    UInt64 oldAttributes = wmPtr->attributes;
	    int oldFlags = wmPtr->flags;

	    if (boolValue) {
		wmPtr->flags |= WM_TRANSPARENT;
		wmPtr->attributes |= kWindowNoShadowAttribute;
	    } else {
		wmPtr->flags &= ~WM_TRANSPARENT;
		wmPtr->attributes &= ~kWindowNoShadowAttribute;
	    }
	    ApplyWindowAttributeFlagChanges(winPtr, macWindow, oldAttributes,
		    oldFlags, 1, 0);
	    [macWindow setBackgroundColor:boolValue ? [NSColor clearColor] : nil];
	    [macWindow setOpaque:!boolValue];
	    TkMacOSXInvalidateWindow((MacDrawable *)winPtr->window,
		    TK_PARENT_WINDOW);
	    }
	break;
    case WMATT_CLASS:
	break;
    case WMATT_TYPE:
	TKLog(@"The type attribute is ignored on macOS.");
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	return TCL_ERROR;
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
{
    Tcl_Obj *result = NULL;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA:
	result = Tcl_NewDoubleObj([macWindow alphaValue]);
	break;










































    case WMATT_FULLSCREEN:
	result = Tcl_NewBooleanObj([macWindow styleMask] & NSFullScreenWindowMask);
	break;



    case WMATT_MODIFIED:
	result = Tcl_NewWideIntObj([macWindow isDocumentEdited] != 0);
	break;
    case WMATT_NOTIFY:
	result = Tcl_NewWideIntObj(tkMacOSXWmAttrNotifyVal != 0);
	break;












    case WMATT_TITLEPATH:
	result = Tcl_NewStringObj([[macWindow representedFilename] UTF8String],
		-1);
















	break;
    case WMATT_TOPMOST:
	result = Tcl_NewWideIntObj((wmPtr->flags & WM_TOPMOST) != 0);
	break;
    case WMATT_TRANSPARENT:
	result = Tcl_NewWideIntObj((wmPtr->flags & WM_TRANSPARENT) != 0);
	break;
    case WMATT_TYPE:
	result = Tcl_NewStringObj("unsupported", -1);
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	break;
    }
    return result;
}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>

|


|

>
>
>
>
>
>
>
>
>
>
>
>
|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|


|


|







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
{
    Tcl_Obj *result = NULL;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    switch (attribute) {
    case WMATT_ALPHA:
	result = Tcl_NewDoubleObj([macWindow alphaValue]);
	break;
    case WMATT_APPEARANCE: {
#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";
	appearance = macWindow.appearance.name;
	if (appearance == nil) {
	    resultString = appearanceStrings[APPEARANCE_AUTO];
	} else if (appearance == NSAppearanceNameAqua) {
	    resultString = appearanceStrings[APPEARANCE_AQUA];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	} else if (@available(macOS 10.14, *)) {
	    if (appearance == NSAppearanceNameDarkAqua) {
		resultString = appearanceStrings[APPEARANCE_DARKAQUA];
	    }
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	}
	result = Tcl_NewStringObj(resultString, TCL_INDEX_NONE);
	break;
    }
    case WMATT_BUTTONS: {
	result = Tcl_NewListObj(3, NULL);
	if ([macWindow standardWindowButton:NSWindowCloseButton].enabled) {
	    Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("close", TCL_INDEX_NONE));
	}
	if ([macWindow standardWindowButton:NSWindowMiniaturizeButton].enabled) {
	    Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("miniaturize", TCL_INDEX_NONE));
	}
	if ([macWindow standardWindowButton:NSWindowZoomButton].enabled) {
	    Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("zoom", TCL_INDEX_NONE));
	}
	break;
    }
    case WMATT_CLASS:
	if ([macWindow isKindOfClass:[NSPanel class]]) {
	    result = Tcl_NewStringObj(subclassNames[subclassNSPanel], TCL_INDEX_NONE);
	} else {
	    result = Tcl_NewStringObj(subclassNames[subclassNSWindow], TCL_INDEX_NONE);
	}
	break;
    case WMATT_FULLSCREEN:
	result = Tcl_NewBooleanObj([macWindow styleMask] & NSFullScreenWindowMask);
	break;
    case WMATT_ISDARK:
	result = Tcl_NewBooleanObj(TkMacOSXInDarkMode((Tk_Window)winPtr));
	break;
    case WMATT_MODIFIED:
	result = Tcl_NewBooleanObj([macWindow isDocumentEdited]);
	break;
    case WMATT_NOTIFY:
	result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal);
	break;
    case WMATT_STYLEMASK: {
	unsigned long styleMaskValue = [macWindow styleMask];
	const styleMaskBit *bit;
	result = Tcl_NewListObj(9, NULL);
	for (bit = styleMaskBits; bit->bitname != NULL; bit++) {
	    if (styleMaskValue & bit->bitvalue) {
		Tcl_ListObjAppendElement(NULL, result,
		    Tcl_NewStringObj(bit->bitname, TCL_INDEX_NONE));
	    }
	}
	break;
    }
    case WMATT_TABBINGID:
	result = Tcl_NewStringObj([[macWindow tabbingIdentifier] UTF8String],
		-1);
	break;
    case WMATT_TABBINGMODE: {
	long mode = [macWindow tabbingMode];
	const char *name = "unrecognized";
	for (const tabbingMode *m = tabbingModes; m->modeName != NULL; m++) {
	    if (m->modeValue == mode) {
		name = m->modeName;
		break;
	    }
	}
	result = Tcl_NewStringObj(name, TCL_INDEX_NONE);
	break;
    }
    case WMATT_TITLEPATH:
	result = Tcl_NewStringObj([[macWindow representedFilename] UTF8String],
		TCL_INDEX_NONE);
	break;
    case WMATT_TOPMOST:
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST);
	break;
    case WMATT_TRANSPARENT:
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT);
	break;
    case WMATT_TYPE:
	result = Tcl_NewStringObj("unsupported", TCL_INDEX_NONE);
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	break;
    }
    return result;
}
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622



1623
















































1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;
    NSWindow *macWindow;




















































    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window)winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewObj();

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(NULL, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
	    Tcl_ListObjAppendElement(NULL, result,
		    WmGetAttribute(winPtr, macWindow, attribute));
	}
	Tcl_SetObjResult(interp, result);
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], WmAttributeNames,
		sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, attribute));
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	int i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
		    sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr, macWindow, interp, attribute, objv[i+1])
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
	return TCL_ERROR;







|


|




>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|












|

|







|

|






|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;
    NSWindow *macWindow;
    if (winPtr == NULL && objc == 5) {
	int index, isNew = 0;
	Tcl_Size length;

	/*
	 * If we are setting an atttribute of a future window, save the value
	 * in a hash table so we can look it up when the window is actually
	 * created.
	 */

	if (strcmp(Tcl_GetString(objv[3]), "-class") == 0) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[4], subclassNames,
		    sizeof(char *), "NSWindow subclass", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&pathnameToSubclass,
		Tcl_GetString(objv[2]), &isNew);
	    if (hPtr) {
		Tcl_SetHashValue(hPtr, INT2PTR(index));
		return TCL_OK;
	    }
	} else if (strcmp(Tcl_GetString(objv[3]), "-tabbingid") == 0) {
	    char *identifier = Tcl_GetStringFromObj(objv[4], &length);
	    char *value = (char *)ckalloc(length + 1);
	    strncpy(value, identifier, length + 1);
	    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&pathnameToTabbingId,
				      Tcl_GetString(objv[2]), &isNew);
	    if (hPtr) {
		Tcl_SetHashValue(hPtr, value);
		return TCL_OK;
	    }
	} else if (strcmp(Tcl_GetString(objv[3]), "-tabbingmode") == 0) {
	    long value = NSWindowTabbingModeAutomatic;
	    int modeIndex;
	    if (Tcl_GetIndexFromObjStruct(interp, objv[4], tabbingModes,
	       sizeof(tabbingMode), "NSWindow Tabbing Mode", 0, &modeIndex) == TCL_OK) {
		value = tabbingModes[modeIndex].modeValue;
	    }
	    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&pathnameToTabbingMode,
		Tcl_GetString(objv[2]), &isNew);
	    if (hPtr) {
		Tcl_SetHashValue(hPtr, value);
		return TCL_OK;
	    }
	}
    }
    if (!winPtr) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	   "Only -class, -tabbingid, or -tabbingmode can be set before the window exists."));
	Tcl_SetErrorCode(interp, "TK", "NO_WINDOW", NULL);
	return TCL_ERROR;
    }
    if (winPtr && winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window)winPtr);
    }
    if (!TkMacOSXHostToplevelExists(winPtr)) {
	TkMacOSXMakeRealWindowExist(winPtr);
    }
    macWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewObj();

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(NULL, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(NULL, result,
		    WmGetAttribute(winPtr, macWindow, (WmAttribute)attribute));
	}
	Tcl_SetObjResult(interp, result);
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], WmAttributeNames,
		sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, (WmAttribute)attribute));
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	Tcl_Size i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
		    sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr, macWindow, interp, (WmAttribute)attribute, objv[i+1])
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
	return TCL_ERROR;
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
 */

static int
WmClientCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);







|




|








|







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
 */

static int
WmClientCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    Tcl_Size length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
 */

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList, *winPtr2;

    int i, windowObjc, gotToplevel = 0;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {







|




>
|







2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
 */

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList, *winPtr2;
    Tcl_Size i, windowObjc;
    int gotToplevel = 0;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
    if (wmPtr->cmapList != NULL) {
	ckfree(wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * On the Macintosh all of this is just an excercise in compatability as
     * we don't support colormaps. If we did they would be installed here.
     */

    return TCL_OK;
}

/*







|







2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
    if (wmPtr->cmapList != NULL) {
	ckfree(wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;

    /*
     * On the Macintosh all of this is just an excercise in compatibility as
     * we don't support colormaps. If we did they would be installed here.
     */

    return TCL_OK;
}

/*
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int len;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->commandObj != NULL) {







|



|







2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tcl_Size len;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->commandObj != NULL) {
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");







|







2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
1938
1939
1940
1941
1942
1943
1944


1945
1946
1947
1948
1949
1950
1951
		    ((transientPtr->flags & WITHDRAWN_BY_CONTAINER) != 0)) {
		TkpWmSetState(winPtr2, NormalState);
		transientPtr->flags &= ~WITHDRAWN_BY_CONTAINER;
	    }
	}
    }



    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFocusmodelCmd --







>
>







2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
		    ((transientPtr->flags & WITHDRAWN_BY_CONTAINER) != 0)) {
		TkpWmSetState(winPtr2, NormalState);
		transientPtr->flags &= ~WITHDRAWN_BY_CONTAINER;
	    }
	}
    }

    [[win contentView] setNeedsDisplay:YES];
    Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFocusmodelCmd --
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
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", -1));
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }







|















|







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
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", TCL_INDEX_NONE));
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
 */

static int
WmForgetCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),	/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window)winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin;








|







2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
 */

static int
WmForgetCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),	/* Current interpreter. */
    TCL_UNUSED(Tcl_Size),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window)winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin;

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
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window)winPtr);
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --







|














|
|







2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window)winPtr);
    }
    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    char xSign = '+', ySign = '+';
    int width, height, x = wmPtr->x, y= wmPtr->y;
    char *argv3;







|







2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    char xSign = '+', ySign = '+';
    int width, height, x = wmPtr->x, y= wmPtr->y;
    char *argv3;
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;
    const char *errorMsg;

    if ((objc != 3) && (objc != 7)) {







|







2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;
    const char *errorMsg;

    if ((objc != 3) && (objc != 7)) {
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
	 */

	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;







|







2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
	 */

	wmPtr->sizeHintsFlags &= ~PBaseSize;
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMsg, -1));
    Tcl_SetErrorCode(interp, "TK", "WM", "GRID", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







|







2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMsg, TCL_INDEX_NONE));
    Tcl_SetErrorCode(interp, "TK", "WM", "GRID", NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
 */

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
	}
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;







|





|







|







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
 */

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    char *argv3;
    Tcl_Size length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
2331
2332
2333
2334
2335
2336
2337




































































2338
2339
2340
2341
2342
2343
2344
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = (char *)ckalloc(length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    return TCL_OK;
}





































































/*
 *----------------------------------------------------------------------
 *
 * WmIconbitmapCmd --
 *
 *	This procedure is invoked to process the "wm iconbitmap" Tcl command.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = (char *)ckalloc(length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    return TCL_OK;
}

 /*----------------------------------------------------------------------
 *
 * WmIconbadgeCmd --
 *
 *	This procedure is invoked to process the "wm iconbadge" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbadgeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    (void) winPtr;
    NSString *label;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,"window badge");
	return TCL_ERROR;
    }

    label = [NSString stringWithUTF8String:Tcl_GetString(objv[3])];

    int number = [label intValue];
    NSDockTile *dockicon = [NSApp dockTile];

    /*
     * First, check that the label is not a decimal. If it is,
     * return an error.
     */

    if ([label containsString:@"."]) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use \"%s\" as icon badge", Tcl_GetString(objv[3])));
	return TCL_ERROR;
    }

    /*
     * Next, check that label is an int, empty string, or exclamation
     * point. If so, set the icon badge on the Dock icon. Otherwise,
     * return an error.
     */

    NSArray *array = @[@"", @"!"];
    if ([array containsObject: label]) {
	[dockicon setBadgeLabel:label];
    } else if (number > 0) {
	NSString *str = [@(number) stringValue];
	[dockicon setBadgeLabel:str];
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use \"%s\" as icon badge", Tcl_GetString(objv[3])));
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconbitmapCmd --
 *
 *	This procedure is invoked to process the "wm iconbitmap" Tcl command.
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *str;
    int len;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {







|





|







2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *str;
    Tcl_Size len;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }







|







2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
 */

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {







|







3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
 */

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1));
	}
	return TCL_OK;
    }

    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }







|




|







|







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
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    Tcl_Size length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }

    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
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
 */

static int
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Image tk_icon;
    int width, height, isDefault = 0;
    NSImage *newIcon = NULL;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
			 "window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }

    /*
     * Parse args.
     */

    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
	isDefault = 1;
	if (objc == 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "window ?-default? image1 ?image2 ...?");
	    return TCL_ERROR;
	}
    }








|



|













<







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
 */

static int
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Image tk_icon;
    int width, height;
    NSImage *newIcon = NULL;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
			 "window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }

    /*
     * Parse args.
     */

    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {

	if (objc == 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "window ?-default? image1 ?image2 ...?");
	    return TCL_ERROR;
	}
    }

2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");







|







3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
 */

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {







|







3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
 */

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
	    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;







|







3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(oldIcon->window);

	    /*
	     * The old icon should be withdrawn.
	     */

	    TkpWmSetState(oldIcon, WithdrawnState);
	    [win orderOut:NSApp];
    	    [win setExcludedFromWindowsMenu:YES];
	    wmPtr3->iconFor = NULL;
	}
	Tk_MakeWindowExist(tkwin2);
	wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= IconWindowHint;
	wmPtr->icon = tkwin2;
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890












2891
2892
2893
2894
2895
2896
2897
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,           /* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window)winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin = (MacDrawable *)winPtr->window;

	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a"
		    " frame, labelframe or toplevel",
		    Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);
	    return TCL_ERROR;
	}












	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    if (winPtr->window == None) {
		Tk_MakeWindowExist((Tk_Window)winPtr);
		macWin = (MacDrawable *)winPtr->window;







|
|
|
|
















>
>
>
>
>
>
>
>
>
>
>
>







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
 *	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(Tcl_Size),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window)winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	MacDrawable *macWin = (MacDrawable *)winPtr->window;

	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a"
		    " frame, labelframe or toplevel",
		    Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Draw the managed widget at the top left corner of its toplevel.
	 * See [4a40c6cace].
	 */

	if (macWin) {
	    winPtr->changes.x -= macWin->xOff;
	    winPtr->changes.y -= macWin->yOff;
	    XMoveWindow(winPtr->display, winPtr->window, 0, 0);
	}

	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    if (winPtr->window == None) {
		Tk_MakeWindowExist((Tk_Window)winPtr);
		macWin = (MacDrawable *)winPtr->window;
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;







|


|




















|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
	    || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMinSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;







|


|




















|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMinSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
	    || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068







3069

3070
3071
3072
3073
3074
3075
3076
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int flag;
    XSetWindowAttributes atts;
    TKWindow *win = (TKWindow *)TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		Tk_Attributes((Tk_Window) winPtr)->override_redirect));
	return TCL_OK;
    }

    if (Tcl_GetBooleanFromObj(interp, objv[3], &flag) != TCL_OK) {
	return TCL_ERROR;
    }
    atts.override_redirect = flag ? True : False;
    Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);







    ApplyContainerOverrideChanges(winPtr, win);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmPositionfromCmd --







|


|


|










|



|


|

>
>
>
>
>
>
>
|
>







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Bool boolValue;
    XSetWindowAttributes atts;
    TKWindow *win = (TKWindow *)TkMacOSXGetNSWindowForDrawable(winPtr->window);

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		Tk_Attributes((Tk_Window)winPtr)->override_redirect));
	return TCL_OK;
    }

    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
	return TCL_ERROR;
    }
    atts.override_redirect = boolValue;
    Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
    if ([NSApp macOSVersion] >= 101300) {
	if (boolValue) {
	    win.styleMask |= NSWindowStyleMaskDocModalWindow;
	} else {
	    win.styleMask &= ~NSWindowStyleMaskDocModalWindow;
	}
    } else {
	ApplyContainerOverrideChanges(winPtr, win);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmPositionfromCmd --
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
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1));
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {







|
















|

|







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
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("user", TCL_INDEX_NONE));
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("program", TCL_INDEX_NONE));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    char *cmd;
    int cmdLength;
    Tcl_Obj *resultObj;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }








|






|







3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    char *cmd;
    Tcl_Size cmdLength;
    Tcl_Obj *resultObj;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }

3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, -1));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*







|







3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, TCL_INDEX_NONE));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
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
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	results[0] = Tcl_NewWideIntObj(
		(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) == 0);
	results[1] = Tcl_NewWideIntObj(
		(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) == 0);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;







|















<
|
<
|







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
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    UInt64 oldAttributes = wmPtr->attributes;
    int oldFlags = wmPtr->flags;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];


	results[0] = Tcl_NewBooleanObj(!(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE));

	results[1] = Tcl_NewBooleanObj(!(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE));
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }

    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
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
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1));
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {







|
















|

|







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
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("user", TCL_INDEX_NONE));
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("program", TCL_INDEX_NONE));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
 */

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **windowPtr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {







|







3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
 */

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **windowPtr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "FAIL", NULL);
	    return TCL_ERROR;
	}

	for (windowPtr = windows; *windowPtr ; windowPtr++) {
	    if (*windowPtr == winPtr) {
		index1 = windowPtr - windows;







|







4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "FAIL", NULL);
	    return TCL_ERROR;
	}

	for (windowPtr = windows; *windowPtr ; windowPtr++) {
	    if (*windowPtr == winPtr) {
		index1 = windowPtr - windows;
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result != 0));
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *







|







4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }








|




|

|







4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"iconic", "normal", "withdrawn", "zoomed", NULL };
    enum options {
	OPT_ICONIC, OPT_NORMAL, OPT_WITHDRAWN, OPT_ZOOMED };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }

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
	    TkpWmSetState(winPtr, WithdrawnState);
	    break;
	default: /* OPT_ZOOMED */
	    TkpWmSetState(winPtr, ZoomState);
	    break;
	}
    } else if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", -1));
    } else {
	if (wmPtr->hints.initial_state == NormalState ||
		wmPtr->hints.initial_state == ZoomState) {
	    wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ?
		    ZoomState : NormalState);
	}
	switch (wmPtr->hints.initial_state) {
	case NormalState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("normal", -1));
	    break;
	case IconicState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("iconic", -1));
	    break;
	case WithdrawnState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("withdrawn", -1));
	    break;
	case ZoomState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("zoomed", -1));
	    break;
	}
    }
    return TCL_OK;
}

/*







|








|


|


|


|







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
	    TkpWmSetState(winPtr, WithdrawnState);
	    break;
	default: /* OPT_ZOOMED */
	    TkpWmSetState(winPtr, ZoomState);
	    break;
	}
    } else if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", TCL_INDEX_NONE));
    } else {
	if (wmPtr->hints.initial_state == NormalState ||
		wmPtr->hints.initial_state == ZoomState) {
	    wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ?
		    ZoomState : NormalState);
	}
	switch (wmPtr->hints.initial_state) {
	case NormalState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("normal", TCL_INDEX_NONE));
	    break;
	case IconicState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("iconic", TCL_INDEX_NONE));
	    break;
	case WithdrawnState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("withdrawn", TCL_INDEX_NONE));
	    break;
	case ZoomState:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("zoomed", TCL_INDEX_NONE));
	    break;
	}
    }
    return TCL_OK;
}

/*
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
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->titleUid ? wmPtr->titleUid : winPtr->nameUid, -1));
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    wmPtr->titleUid = Tk_GetUid(argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
	TkSetWMName(winPtr, wmPtr->titleUid);







|




|








|







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
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    Tcl_Size length;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->titleUid ? wmPtr->titleUid : winPtr->nameUid, TCL_INDEX_NONE));
	return TCL_OK;
    }

    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    wmPtr->titleUid = Tk_GetUid(argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
	TkSetWMName(winPtr, wmPtr->titleUid);
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
 */

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window container;
    TkWindow *containerPtr, *w;
    WmInfo *wmPtr2;
    Transient *transient;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->container != NULL) {
	    Tcl_SetObjResult(interp,
		Tcl_NewStringObj(Tk_PathName(wmPtr->container), -1));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	RemoveTransient(winPtr);
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &container) != TCL_OK) {
	    return TCL_ERROR;
	}

	containerPtr = (TkWindow*) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
            /*
             * Ensure that the container window is actually a Tk toplevel.
             */

            containerPtr = containerPtr->parentPtr;







|















|









>







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
 */

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window container;
    TkWindow *containerPtr, *w;
    WmInfo *wmPtr2;
    Transient *transient;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?window?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->container != NULL) {
	    Tcl_SetObjResult(interp,
		Tcl_NewStringObj(Tk_PathName(wmPtr->container), TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	RemoveTransient(winPtr);
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	RemoveTransient(winPtr);
	containerPtr = (TkWindow*) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
            /*
             * Ensure that the container window is actually a Tk toplevel.
             */

            containerPtr = containerPtr->parentPtr;
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
		w = (TkWindow *)w->wmInfoPtr->container) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }







|







4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	    w = (TkWindow *)w->wmInfoPtr->container) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;







|







4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
		    == (PBaseSize|PResizeInc))) {
	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel units
     * and there's no easy way to translate them to grid units since the new







|
<







4580
4581
4582
4583
4584
4585
4586
4587

4588
4589
4590
4591
4592
4593
4594
	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & PBaseSize) == PBaseSize)) {

	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel units
     * and there's no easy way to translate them to grid units since the new
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}








|







4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
    }
    wmPtr = winPtr->wmInfoPtr;
    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;







|







4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
    }
    wmPtr = winPtr->wmInfoPtr;
    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~PBaseSize;
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelEventProc(
    ClientData clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = clientData;

    winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE;
    if (eventPtr->type == DestroyNotify) {
	if (!(winPtr->flags & TK_ALREADY_DEAD)) {
	    /*
	     * A top-level window was deleted externally (e.g., by the window
	     * manager). This is probably not a good thing, but cleanup as







|


|







4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelEventProc(
    void *clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE;
    if (eventPtr->type == DestroyNotify) {
	if (!(winPtr->flags & TK_ALREADY_DEAD)) {
	    /*
	     * A top-level window was deleted externally (e.g., by the window
	     * manager). This is probably not a good thing, but cleanup as
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
 *	from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    TkWindow *winPtr = clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    if (wmPtr->flags & WM_FULLSCREEN) {
	return;







|

|







4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
 *	from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    void *clientData)	/* Pointer to the window's record. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    if (wmPtr->flags & WM_FULLSCREEN) {
	return;
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
     *    This is because of "features" in some window managers (e.g. twm, as
     *    of 4/24/91) where they don't interpret coordinates according to
     *    ICCCM. Moving a window to its current location may cause it to shift
     *    position on the screen.
     */

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	/*
	 * TODO: Here we should handle out of process embedding.
	 */

	if (contWinPtr != NULL) {
	    /*
	     * This window is embedded and the container is also in this
	     * process, so we don't need to do anything special about the
	     * geometry, except to make sure that the desired size is known by
	     * the container. Also, zero out any position information, since
	     * embedded windows are not allowed to move.
	     */

	    wmPtr->x = wmPtr->y = 0;
	    wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
	    Tk_GeometryRequest((Tk_Window)contWinPtr, width, height);
	}
	return;
    }
    if (wmPtr->flags & WM_MOVE_PENDING) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {







|
















|







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
     *    This is because of "features" in some window managers (e.g. twm, as
     *    of 4/24/91) where they don't interpret coordinates according to
     *    ICCCM. Moving a window to its current location may cause it to shift
     *    position on the screen.
     */

    if (Tk_IsEmbedded(winPtr)) {
	Tk_Window contWinPtr = Tk_GetOtherWindow((Tk_Window)winPtr);

	/*
	 * TODO: Here we should handle out of process embedding.
	 */

	if (contWinPtr != NULL) {
	    /*
	     * This window is embedded and the container is also in this
	     * process, so we don't need to do anything special about the
	     * 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(contWinPtr, width, height);
	}
	return;
    }
    if (wmPtr->flags & WM_MOVE_PENDING) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631

	    if (!(Tk_IsEmbedded(winPtr))) {
		x += winPtr->wmInfoPtr->xInParent;
		y += winPtr->wmInfoPtr->yInParent;
		break;
	    }

	    otherPtr = TkpGetOtherWindow(winPtr);
	    if (otherPtr == NULL) {
		break;
	    }

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.







|







5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215

	    if (!(Tk_IsEmbedded(winPtr))) {
		x += winPtr->wmInfoPtr->xInParent;
		y += winPtr->wmInfoPtr->yInParent;
		break;
	    }

	    otherPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
	    if (otherPtr == NULL) {
		break;
	    }

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714

	/*
	 * Container windows cannot have children. So if it is a container,
	 * look there, otherwise inspect the children.
	 */

	if (Tk_IsContainer(winPtr)) {
	    childPtr = TkpGetOtherWindow(winPtr);
	    if (childPtr != NULL) {
		if (Tk_IsMapped(childPtr)) {
		    tmpx = x - childPtr->changes.x;
		    tmpy = y - childPtr->changes.y;
		    bd = childPtr->changes.border_width;

		    if ((tmpx >= -bd) && (tmpy >= -bd)







|







5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298

	/*
	 * Container windows cannot have children. So if it is a container,
	 * look there, otherwise inspect the children.
	 */

	if (Tk_IsContainer(winPtr)) {
	    childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
	    if (childPtr != NULL) {
		if (Tk_IsMapped(childPtr)) {
		    tmpx = x - childPtr->changes.x;
		    tmpy = y - childPtr->changes.y;
		    bd = childPtr->changes.border_width;

		    if ((tmpx >= -bd) && (tmpy >= -bd)
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
    int *newX, int *newY)	/* Coordinates of point in the upperMost child
				 * of tkWin containing (rootX,rootY) */
{
    TkWindow *winPtr, *childPtr;
    TkWindow *nextPtr;		/* Coordinates of highest child found so far
				 * that contains point. */
    int x, y;			/* Coordinates in winPtr. */
    Window *children;		/* Children of winPtr, or NULL. */

    winPtr = (TkWindow *)tkwin;
    x = rootX;
    y = rootY;
    while (1) {
	nextPtr = NULL;
	children = NULL;

	/*
	 * Container windows cannot have children. So if it is a container,
	 * look there, otherwise inspect the children.
	 */

	if (Tk_IsContainer(winPtr)) {
	    childPtr = TkpGetOtherWindow(winPtr);
	    if (childPtr != NULL) {
		if (Tk_IsMapped(childPtr) &&
			x > childPtr->changes.x &&
			x < childPtr->changes.x + childPtr->changes.width &&
			y > childPtr->changes.y &&
			y < childPtr->changes.y + childPtr->changes.height) {
		    nextPtr = childPtr;







<






<







|







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
    int *newX, int *newY)	/* Coordinates of point in the upperMost child
				 * of tkWin containing (rootX,rootY) */
{
    TkWindow *winPtr, *childPtr;
    TkWindow *nextPtr;		/* Coordinates of highest child found so far
				 * that contains point. */
    int x, y;			/* Coordinates in winPtr. */


    winPtr = (TkWindow *)tkwin;
    x = rootX;
    y = rootY;
    while (1) {
	nextPtr = NULL;


	/*
	 * Container windows cannot have children. So if it is a container,
	 * look there, otherwise inspect the children.
	 */

	if (Tk_IsContainer(winPtr)) {
	    childPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);
	    if (childPtr != NULL) {
		if (Tk_IsMapped(childPtr) &&
			x > childPtr->changes.x &&
			x < childPtr->changes.x + childPtr->changes.width &&
			y > childPtr->changes.y &&
			y < childPtr->changes.y + childPtr->changes.height) {
		    nextPtr = childPtr;
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
	ckfree(oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * On the Macintosh all of this is just an excercise in compatability as
     * we don't support colormaps. If we did they would be installed here.
     */
}

/*
 *----------------------------------------------------------------------
 *







|







5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
	ckfree(oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * On the Macintosh all of this is just an excercise in compatibility as
     * we don't support colormaps. If we did they would be installed here.
     */
}

/*
 *----------------------------------------------------------------------
 *
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
    TkWindow *winPtr,
    Tk_Uid titleUid)
{
    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    NSString *title = [[NSString alloc] initWithUTF8String:titleUid];
    [TkMacOSXGetNSWindowForDrawable(winPtr->window) setTitle:title];
    [title release];
}

/*
 *----------------------------------------------------------------------
 *







|







5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
    TkWindow *winPtr,
    Tk_Uid titleUid)
{
    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    NSString *title = [[TKNSString alloc] initWithTclUtfBytes:titleUid length:TCL_INDEX_NONE];
    [TkMacOSXGetNSWindowForDrawable(winPtr->window) setTitle:title];
    [title release];
}

/*
 *----------------------------------------------------------------------
 *
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511

5512



5513
5514
5515
5516
5517
5518
5519
 */

Tk_Window
Tk_MacOSXGetTkWindow(
    void *w)
{
    Window window = None;
    TkDisplay *dispPtr = TkGetDisplayList();
    if ([(NSWindow *)w respondsToSelector: @selector (tkWindow)]) {
	window = [(TKWindow *)w tkWindow];
    }
    return (window != None ?

	    Tk_IdToWindow(dispPtr->display, window) : NULL);



}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsWindowZoomed --
 *







<



|
>
|
>
>
>







6082
6083
6084
6085
6086
6087
6088

6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
 */

Tk_Window
Tk_MacOSXGetTkWindow(
    void *w)
{
    Window window = None;

    if ([(NSWindow *)w respondsToSelector: @selector (tkWindow)]) {
	window = [(TKWindow *)w tkWindow];
    }
    if (window) {
	TkDisplay *dispPtr = TkGetDisplayList();
	return Tk_IdToWindow(dispPtr->display, window);
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsWindowZoomed --
 *
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
 */

int
TkMacOSXZoomToplevel(
    void *whichWindow,		/* The Macintosh window to zoom. */
    short zoomPart)		/* Either inZoomIn or inZoomOut */
{
    NSWindow *window = whichWindow;
    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
    WmInfo *wmPtr;

    if (!winPtr || !winPtr->wmInfoPtr) {
	return false;
    }
    wmPtr = winPtr->wmInfoPtr;
    if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&







|
|







6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
 */

int
TkMacOSXZoomToplevel(
    void *whichWindow,		/* The Macintosh window to zoom. */
    short zoomPart)		/* Either inZoomIn or inZoomOut */
{
    NSWindow *window = (NSWindow *)whichWindow;
    TkWindow *winPtr = (TkWindow *)TkMacOSXGetTkWindow(window);
    WmInfo *wmPtr;

    if (!winPtr || !winPtr->wmInfoPtr) {
	return false;
    }
    wmPtr = winPtr->wmInfoPtr;
    if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
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
 *	Changes the style of a new Mac window.
 *
 *----------------------------------------------------------------------
 */

int
TkUnsupported1ObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const subcmds[] = {
	"style", "tabbingid", "appearance", "isdark", NULL
    };
    enum SubCmds {
	TKMWS_STYLE, TKMWS_TABID, TKMWS_APPEARANCE, TKMWS_ISDARK
    };
    Tk_Window tkwin = clientData;
    TkWindow *winPtr;
    int index;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }







|





|


|

|







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
 *	Changes the style of a new Mac window.
 *
 *----------------------------------------------------------------------
 */

int
TkUnsupported1ObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const subcmds[] = {
	"appearance", "isdark", "style", NULL
    };
    enum SubCmds {
	TKMWS_APPEARANCE, TKMWS_ISDARK, TKMWS_STYLE
    };
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr;
    int index;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }
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
    switch((enum SubCmds) index) {
    case TKMWS_STYLE:
	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?");
	    return TCL_ERROR;
	}
	return WmWinStyle(interp, winPtr, objc, objv);
    case TKMWS_TABID:
	if ([NSApp macOSVersion] < 101200) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
                "Tabbing identifiers did not exist until OSX 10.12.", -1));
	    Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "TABBINGID", NULL);
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?newid?");
	    return TCL_ERROR;
	}
	return WmWinTabbingId(interp, winPtr, objc, objv);
    case TKMWS_APPEARANCE:
	if ([NSApp macOSVersion] < 100900) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
                "Window appearances did not exist until OSX 10.9.", -1));
	    Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "APPEARANCE", NULL);
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?appearancename?");
	    return TCL_ERROR;
	}







<
<
<
<
<
<
<
<
<
<
<
<



|







6233
6234
6235
6236
6237
6238
6239












6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
    switch((enum SubCmds) index) {
    case TKMWS_STYLE:
	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?");
	    return TCL_ERROR;
	}
	return WmWinStyle(interp, winPtr, objc, objv);












    case TKMWS_APPEARANCE:
	if ([NSApp macOSVersion] < 100900) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
                "Window appearances did not exist until OSX 10.9.", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "APPEARANCE", NULL);
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?appearancename?");
	    return TCL_ERROR;
	}
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
 *----------------------------------------------------------------------
 */

static int
WmWinStyle(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    struct StrIntMap {
	const char *strValue;
	UInt64 intValue;
    };
    static const struct StrIntMap classMap[] = {







|







6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
 *----------------------------------------------------------------------
 */

static int
WmWinStyle(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
    struct StrIntMap {
	const char *strValue;
	UInt64 intValue;
    };
    static const struct StrIntMap classMap[] = {
5785
5786
5787
5788
5789
5790
5791
5792

5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
	{ NULL, 0 }
    };

    int index, i;

    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {
	Tcl_Obj *attributeList, *newResult = NULL;
	UInt64 attributes;

	for (i = 0; classMap[i].strValue != NULL; i++) {
	    if (wmPtr->macClass == classMap[i].intValue) {
		newResult = Tcl_NewStringObj(classMap[i].strValue, -1);
		break;
	    }
	}
	if (newResult == NULL) {
	    Tcl_Panic("invalid class");
	}








|
>








|







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
	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
	{ NULL, 0 }
    };

    int index;
    Tcl_Size i;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {
	Tcl_Obj *attributeList, *newResult = NULL;
	UInt64 attributes;

	for (i = 0; classMap[i].strValue != NULL; i++) {
	    if (wmPtr->macClass == classMap[i].intValue) {
		newResult = Tcl_NewStringObj(classMap[i].strValue, TCL_INDEX_NONE);
		break;
	    }
	}
	if (newResult == NULL) {
	    Tcl_Panic("invalid class");
	}

5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
		attributes &= ~intValue;
		break;
	    }
	}
	for (i = 0; attrMap[i].strValue != NULL; i++) {
	    if (attributes & attrMap[i].intValue) {
		Tcl_ListObjAppendElement(NULL, attributeList,
			Tcl_NewStringObj(attrMap[i].strValue, -1));
	    }
	}
	Tcl_ListObjAppendElement(NULL, newResult, attributeList);
	Tcl_SetObjResult(interp, newResult);
    } else {
	int attrObjc;
	Tcl_Obj **attrObjv = NULL;
	WindowClass macClass;
	UInt64 oldAttributes = wmPtr->attributes;
	int oldFlags = wmPtr->flags;

	if (Tcl_GetIndexFromObjStruct(interp, objv[3], classMap,
		sizeof(struct StrIntMap), "class", 0, &index) != TCL_OK) {







|





|







6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
		attributes &= ~intValue;
		break;
	    }
	}
	for (i = 0; attrMap[i].strValue != NULL; i++) {
	    if (attributes & attrMap[i].intValue) {
		Tcl_ListObjAppendElement(NULL, attributeList,
			Tcl_NewStringObj(attrMap[i].strValue, TCL_INDEX_NONE));
	    }
	}
	Tcl_ListObjAppendElement(NULL, newResult, attributeList);
	Tcl_SetObjResult(interp, newResult);
    } else {
	Tcl_Size attrObjc;
	Tcl_Obj **attrObjv = NULL;
	WindowClass macClass;
	UInt64 oldAttributes = wmPtr->attributes;
	int oldFlags = wmPtr->flags;

	if (Tcl_GetIndexFromObjStruct(interp, objv[3], classMap,
		sizeof(struct StrIntMap), "class", 0, &index) != TCL_OK) {
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmWinTabbingId --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle tabbingid" subcommand. The command
 *	allows you to get or set the tabbingIdentifier for the NSWindow
 *	associated with a Tk Window.  The syntax is:
 *
 *	    tk::unsupported::MacWindowStyle tabbingid window ?newId?
 *
 * Results:
 *	Returns the tabbingIdentifier of the window prior to calling this
 *      function.  If the optional newId argument is omitted, the window's
 *      tabbingIdentifier is not changed.
 *
 * Side effects:
 *	Windows may only be grouped together as tabs if they all have the same
 *      tabbingIdentifier.  In particular, by giving a window a unique
 *      tabbingIdentifier one can prevent it from becoming a tab in any other
 *      window.  Changing the tabbingIdentifier of a window which is already
 *      a tab causes it to become a separate window.
 *
 *----------------------------------------------------------------------
 */

static int
WmWinTabbingId(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 101200)
    Tcl_Obj *result = NULL;
    NSString *idString;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (win) {
	idString = win.tabbingIdentifier;
	result = Tcl_NewStringObj(idString.UTF8String, [idString length]);
    }
    if (result == NULL) {
	NSLog(@"Failed to read tabbing identifier; try calling update idletasks"
	      " before getting/setting the tabbing identifier of the window.");
	return TCL_OK;
    }
    Tcl_SetObjResult(interp, result);
    if (objc == 3) {
	return TCL_OK;
    } else if (objc == 4) {
	int len;
	char *newId = Tcl_GetStringFromObj(objv[3], &len);
	NSString *newIdString = [NSString stringWithUTF8String:newId];
	[win setTabbingIdentifier: newIdString];

	/*
	 * If the tabbingIdentifier of a tab is changed we also turn it into a
	 * separate window so we don't violate the rule that all tabs in the
	 * same frame must have the same tabbingIdentifier.
	 */

	if ([idString compare:newIdString] != NSOrderedSame
#if MAC_OS_X_VERSION_MIN_REQUIRED > 101200
		&& [win tab]
#endif
		) {
	    [win moveTabToNewWindow:nil];
	}
	return TCL_OK;
    }
#endif
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * WmWinAppearance --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle appearance" subcommand. The command
 *	allows you to get or set the appearance for the NSWindow associated
 *	with a Tk Window.  The syntax is:
 *
 *	    tk::unsupported::MacWindowStyle tabbingid window ?newAppearance?
 *
 *      Allowed appearance names are "aqua", "darkaqua", and "auto".
 *
 * Results:
 *      Returns the appearance setting of the window prior to calling this
 *	function.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|







6452
6453
6454
6455
6456
6457
6458











































































6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *











































































 * WmWinAppearance --
 *
 *	This procedure is invoked to process the
 *	"::tk::unsupported::MacWindowStyle appearance" subcommand. The command
 *	allows you to get or set the appearance for the NSWindow associated
 *	with a Tk Window.  The syntax is:
 *
 *	    tk::unsupported::MacWindowStyle appearance window ?newAppearance?
 *
 *      Allowed appearance names are "aqua", "darkaqua", and "auto".
 *
 * Results:
 *      Returns the appearance setting of the window prior to calling this
 *	function.
 *
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998

5999
6000
6001

6002
6003
6004
6005
6006
6007
6008
 *----------------------------------------------------------------------
 */

static int
WmWinAppearance(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    int objc,			/* Number of arguments. */
    Tcl_Obj * const objv[])	/* Argument objects. */
{
#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
    static const char *const appearanceStrings[] = {
	"aqua", "darkaqua", "auto", NULL
    };

    enum appearances {
	APPEARANCE_AQUA, APPEARANCE_DARKAQUA, APPEARANCE_AUTO
    };

    Tcl_Obj *result = NULL;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
    NSAppearanceName appearance;
#else
    NSString *appearance;
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101300








|


|
|
|
<
>
|
|
<
>







6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496

6497
6498
6499

6500
6501
6502
6503
6504
6505
6506
6507
 *----------------------------------------------------------------------
 */

static int
WmWinAppearance(
    Tcl_Interp *interp,		/* Current interpreter. */
    TkWindow *winPtr,		/* Window to be manipulated. */
    Tcl_Size 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;

#else
    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

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
    if (result == NULL) {
	NSLog(@"Failed to read appearance name; try calling update idletasks before getting/setting the appearance of the window.");
	return TCL_OK;
    }
    if (objc == 4) {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], appearanceStrings,
                sizeof(char *), "appearancename", 0, &index) != TCL_OK) {
            return TCL_ERROR;
        }
	switch ((enum appearances) index) {
	case APPEARANCE_AQUA:
	    win.appearance = [NSAppearance appearanceNamed:
		NSAppearanceNameAqua];
	    break;
	case APPEARANCE_DARKAQUA:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    if (@available(macOS 10.14, *)) {
		win.appearance = [NSAppearance appearanceNamed:
		    NSAppearanceNameDarkAqua];
	    }
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    break;
	default:
	    win.appearance = nil;
	}
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
#else // MAC_OS_X_VERSION_MAX_ALLOWED > 1090
    return TCL_ERROR;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeMenuWindow --







|
|
|



















<
<







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
    if (result == NULL) {
	NSLog(@"Failed to read appearance name; try calling update idletasks before getting/setting the appearance of the window.");
	return TCL_OK;
    }
    if (objc == 4) {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], appearanceStrings,
		sizeof(char *), "appearancename", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum appearances) index) {
	case APPEARANCE_AQUA:
	    win.appearance = [NSAppearance appearanceNamed:
		NSAppearanceNameAqua];
	    break;
	case APPEARANCE_DARKAQUA:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    if (@available(macOS 10.14, *)) {
		win.appearance = [NSAppearance appearanceNamed:
		    NSAppearanceNameDarkAqua];
	    }
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	    break;
	default:
	    win.appearance = nil;
	}
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;


#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeMenuWindow --
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
void
TkMacOSXMakeRealWindowExist(
    TkWindow *winPtr)		/* Tk window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    MacDrawable *macWin;
    WindowClass macClass;

    Bool overrideRedirect = Tk_Attributes((Tk_Window)winPtr)->override_redirect;







    if (TkMacOSXHostToplevelExists(winPtr)) {
	return;
    }

    macWin = (MacDrawable *)winPtr->window;

    /*
     * If this is embedded, make sure its container's toplevel exists, then
     * return...
     */

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	if (contWinPtr != NULL) {
	    TkMacOSXMakeRealWindowExist(
		    contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	}

	Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
	return;

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }


    /*





















































     * If this is an override-redirect window, the NSWindow is created first as
     * a document window then converted to a simple window.
     */

    if (overrideRedirect) {
	wmPtr->macClass = kDocumentWindowClass;
    }
    macClass = wmPtr->macClass;
    wmPtr->attributes &= (tkAlwaysValidAttributes |
	    macClassAttrs[macClass].validAttrs);
    wmPtr->flags |= macClassAttrs[macClass].flags |
	    ((wmPtr->attributes & kWindowResizableAttribute) ? 0 :
	    WM_WIDTH_NOT_RESIZABLE|WM_HEIGHT_NOT_RESIZABLE);
    UInt64 attributes = (wmPtr->attributes &
	    ~macClassAttrs[macClass].forceOffAttrs) |
	    macClassAttrs[macClass].forceOnAttrs;
    NSUInteger styleMask = macClassAttrs[macClass].styleMask |
	((attributes & kWindowNoTitleBarAttribute) ? 0 : NSTitledWindowMask) |
	((attributes & kWindowCloseBoxAttribute) ? NSClosableWindowMask : 0) |
	((attributes & kWindowCollapseBoxAttribute) ?
		NSMiniaturizableWindowMask : 0) |
	((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
	((attributes & kWindowMetalAttribute) ?
		NSTexturedBackgroundWindowMask : 0) |
	((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
		NSUnifiedTitleAndToolbarWindowMask : 0) |
	((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
	(attributes >> WM_NSMASK_SHIFT);
    Class winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
	    (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
	    NSNonactivatingPanelMask|NSHUDWindowMask)) ? [TKPanel class] :
	    [TKWindow class]);

    NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
	    styleMask:styleMask];
    NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
	    TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
	    structureRect.origin.y + structureRect.size.height + 200), 200, 200);
    if (wmPtr->hints.initial_state == WithdrawnState) {

    }
    TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }












    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];















    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(TKPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*







>

>
>
>
>
>
>













|
















>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|

|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>






>






>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|







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
void
TkMacOSXMakeRealWindowExist(
    TkWindow *winPtr)		/* Tk window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    MacDrawable *macWin;
    WindowClass macClass;
    Class winClass = nil;
    Bool overrideRedirect = Tk_Attributes((Tk_Window)winPtr)->override_redirect;
    Tcl_HashEntry *hPtr = NULL;
    NSUInteger styleMask;
    NSString *identifier;
    char *tabbingId = NULL;
    long tabbingMode = NSWindowTabbingModeAutomatic;
    static int initialized = 0;

    if (TkMacOSXHostToplevelExists(winPtr)) {
	return;
    }

    macWin = (MacDrawable *)winPtr->window;

    /*
     * If this is embedded, make sure its container's toplevel exists, then
     * return...
     */

    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contWinPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)winPtr);

	if (contWinPtr != NULL) {
	    TkMacOSXMakeRealWindowExist(
		    contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	}

	Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
	return;

	/*
	 * TODO: Here we should handle out of process embedding.
	 */
    }

    if ([NSApp macOSVersion] >= 101300) {
	/*
	 * Prior to macOS 10.12 the styleMask was readonly.  From macOS 10.12
	 * onward, the styleMask can replace the Carbon window classes and
	 * attributes.
	 */
	int index;
	if (!initialized) {
	    Tcl_InitHashTable(&pathnameToSubclass, TCL_STRING_KEYS);
	    Tcl_InitHashTable(&pathnameToTabbingId, TCL_STRING_KEYS);
	    Tcl_InitHashTable(&pathnameToTabbingMode, TCL_STRING_KEYS);
	    initialized = 1;
	}
	hPtr = Tcl_FindHashEntry(&pathnameToSubclass, Tk_PathName(winPtr));
	index = hPtr ? PTR2INT(Tcl_GetHashValue(hPtr)) : subclassNSWindow;
	switch(index) {
	case subclassNSPanel:
	    winClass = [TKPanel class];
	    styleMask =  (NSWindowStyleMaskTitled        |
			  NSWindowStyleMaskClosable      |
			  NSWindowStyleMaskResizable     |
			  NSWindowStyleMaskUtilityWindow |
			  NSWindowStyleMaskNonactivatingPanel );
		break;
	default:
	    winClass = [TKWindow class];
	    styleMask =  (NSWindowStyleMaskTitled         |
			  NSWindowStyleMaskClosable       |
			  NSWindowStyleMaskMiniaturizable |
			  NSWindowStyleMaskResizable );
		break;
	}
	if (overrideRedirect) {
	    styleMask |= NSWindowStyleMaskDocModalWindow;
	}
	/* Help windows (used for tooltips) should have stylemask 0. */
	if (wmPtr->macClass == kHelpWindowClass) {
	    styleMask = 0;
	}
	if (hPtr) {
	    Tcl_DeleteHashEntry(hPtr);
	}
	hPtr = Tcl_FindHashEntry(&pathnameToTabbingId, Tk_PathName(winPtr));
	if (hPtr) {
	    tabbingId = (char *)Tcl_GetHashValue(hPtr);
	    Tcl_DeleteHashEntry(hPtr);
	}
	hPtr = Tcl_FindHashEntry(&pathnameToTabbingMode, Tk_PathName(winPtr));
	if (hPtr) {
	    tabbingMode = PTR2INT(Tcl_GetHashValue(hPtr));
	    Tcl_DeleteHashEntry(hPtr);
	}
    } else {

	/*
	 * If this is an override-redirect window, the NSWindow is created first as
	 * a document window then converted to a simple window.
	 */

	if (overrideRedirect) {
	    wmPtr->macClass = kDocumentWindowClass;
	}
	macClass = wmPtr->macClass;
	wmPtr->attributes &= (tkAlwaysValidAttributes |
			      macClassAttrs[macClass].validAttrs);
	wmPtr->flags |= macClassAttrs[macClass].flags |
	    ((wmPtr->attributes & kWindowResizableAttribute) ? 0 :
	     WM_WIDTH_NOT_RESIZABLE|WM_HEIGHT_NOT_RESIZABLE);
	UInt64 attributes = (wmPtr->attributes &
			     ~macClassAttrs[macClass].forceOffAttrs) |
	    macClassAttrs[macClass].forceOnAttrs;
	styleMask = macClassAttrs[macClass].styleMask |
	    ((attributes & kWindowNoTitleBarAttribute) ? 0 : NSTitledWindowMask) |
	    ((attributes & kWindowCloseBoxAttribute) ? NSClosableWindowMask : 0) |
	    ((attributes & kWindowCollapseBoxAttribute) ?
	     NSMiniaturizableWindowMask : 0) |
	    ((attributes & kWindowResizableAttribute) ? NSResizableWindowMask : 0) |
	    ((attributes & kWindowMetalAttribute) ?
	     NSTexturedBackgroundWindowMask : 0) |
	    ((attributes & kWindowUnifiedTitleAndToolbarAttribute) ?
	     NSUnifiedTitleAndToolbarWindowMask : 0) |
	    ((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
	    (attributes >> WM_NSMASK_SHIFT);
	winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
		    (styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
				  NSNonactivatingPanelMask|NSHUDWindowMask)) ?
		    [TKPanel class] : [TKWindow class]);
    }
    NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
	    styleMask:styleMask];
    NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
	    TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
	    structureRect.origin.y + structureRect.size.height + 200), 200, 200);
    if (wmPtr->hints.initial_state == WithdrawnState) {
	//// ???????
    }
    TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }
#if MAC_OS_X_VERSION_MAX_ALLOWED > 101200
    if (tabbingId) {
	identifier = [NSString stringWithUTF8String:tabbingId];
    } else {
	identifier = [NSString stringWithUTF8String:Tk_PathName(winPtr)];
    }
    [window setTabbingIdentifier: identifier];
    [window setTabbingMode: tabbingMode];
#endif
    if (tabbingId) {
	ckfree(tabbingId);
    }
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];

    /*
     * AppKit calls the viewDidChangeEffectiveAppearance method when the
     * user changes the Accent Color but not when the user changes the
     * Highlight Color.  So we register to receive KVO notifications for
     * Highlight Color as well.
     */

    [preferences addObserver:contentView
		  forKeyPath:@"AppleHighlightColor"
		     options:NSKeyValueObservingOptionNew
		     context:NULL];
#endif
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:NO];
    [window setReleasedWhenClosed:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(TKPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
6227
6228
6229
6230
6231
6232
6233



6234
6235


6236
6237
6238
6239
6240
6241
6242

    macWin->flags |= TK_HOST_EXISTS;
    if (overrideRedirect) {
    	XSetWindowAttributes atts;

    	atts.override_redirect = True;
    	Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);



    	ApplyContainerOverrideChanges(winPtr, NULL);
    }


}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedrawWidget --
 *







>
>
>
|
|
>
>







6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834

    macWin->flags |= TK_HOST_EXISTS;
    if (overrideRedirect) {
    	XSetWindowAttributes atts;

    	atts.override_redirect = True;
    	Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
	if ([NSApp macOSVersion] >= 101300) {
	    window.styleMask |= NSWindowStyleMaskDocModalWindow;
	} else {
	    ApplyContainerOverrideChanges(winPtr, NULL);
	}
    }
    [window display];
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedrawWidget --
 *
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
    if (w) {
	TKContentView *view = [w contentView];
	TkMacOSXWinBounds(winPtr, &tkBounds);
	bounds = NSMakeRect(tkBounds.left,
			    [view bounds].size.height - tkBounds.bottom,
			    tkBounds.right - tkBounds.left,
			    tkBounds.bottom - tkBounds.top);
	[view setTkNeedsDisplay:YES];
	[view setTkDirtyRect:bounds];
    }
}


/*
 *----------------------------------------------------------------------
 *







<
|







6859
6860
6861
6862
6863
6864
6865

6866
6867
6868
6869
6870
6871
6872
6873
    if (w) {
	TKContentView *view = [w contentView];
	TkMacOSXWinBounds(winPtr, &tkBounds);
	bounds = NSMakeRect(tkBounds.left,
			    [view bounds].size.height - tkBounds.bottom,
			    tkBounds.right - tkBounds.left,
			    tkBounds.bottom - tkBounds.top);

	[view addTkDirtyRect:bounds];
    }
}


/*
 *----------------------------------------------------------------------
 *
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
 *
 * Side effects:
 *	May maximize, minimize, restore, or withdraw a window.
 *
 *----------------------------------------------------------------------
 */

void
TkpWmSetState(
    TkWindow *winPtr,		/* Toplevel window to operate on. */
    int state)			/* One of IconicState, ZoomState, NormalState,
				 * or WithdrawnState. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *macWin;

    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    macWin = TkMacOSXGetNSWindowForDrawable(winPtr->window);














    if (state == WithdrawnState) {
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == IconicState) {

	/*
	 * The window always gets unmapped. If we can show the icon version of
	 * the window we also collapse it.
	 */

	if (macWin && ([macWin styleMask] & NSMiniaturizableWindowMask) &&
		![macWin isMiniaturized]) {
	    [macWin miniaturize:NSApp];
	}
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == NormalState || state == ZoomState) {
	Tk_MapWindow((Tk_Window)winPtr);
	[macWin deminiaturize:NSApp];
	[macWin orderFront:NSApp];
	TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn : inZoomOut);
    }

    /*
     * Make sure windows are updated after the state change.
     */

    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}


}

/*
 *----------------------------------------------------------------------
 *
 * TkpIsWindowFloating --
 *







|










|




>
>
>
>
>
>
>
>
>
>
>
>
>




















>

|



>
>







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
 *
 * Side effects:
 *	May maximize, minimize, restore, or withdraw a window.
 *
 *----------------------------------------------------------------------
 */

int
TkpWmSetState(
    TkWindow *winPtr,		/* Toplevel window to operate on. */
    int state)			/* One of IconicState, ZoomState, NormalState,
				 * or WithdrawnState. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSWindow *macWin;

    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	goto setStateEnd;
    }

    macWin = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    /*
     * Make sure windows are updated before the state change.  As an exception,
     * do not process idle tasks before withdrawing a window.  The purpose of
     * this is to support the common paradigm of immediately withdrawing the
     * root window.  Processing idle tasks before changing the state causes the
     * root to briefly flash on the screen, which users of this paradigm find
     * annoying.  Not processing the events does not guarantee that the window
     * will not appear but makes it more likely.
     */

    if (state != WithdrawnState) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {};
    }
    if (state == WithdrawnState) {
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == IconicState) {

	/*
	 * The window always gets unmapped. If we can show the icon version of
	 * the window we also collapse it.
	 */

	if (macWin && ([macWin styleMask] & NSMiniaturizableWindowMask) &&
		![macWin isMiniaturized]) {
	    [macWin miniaturize:NSApp];
	}
	Tk_UnmapWindow((Tk_Window)winPtr);
    } else if (state == NormalState || state == ZoomState) {
	Tk_MapWindow((Tk_Window)winPtr);
	[macWin deminiaturize:NSApp];
	[macWin orderFront:NSApp];
	TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn : inZoomOut);
    }

    /*
     * Make sure windows are updated after the state change too.
     */

    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
setStateEnd:
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpIsWindowFloating --
 *
6583
6584
6585
6586
6587
6588
6589

6590
6591
6592
6593
6594
6595
6596

    	TkWmRestackToplevel(winPtr, Above, NULL);
    	if (force) {
    	    [NSApp activateIgnoringOtherApps:YES];
    	}
	if (win && [win canBecomeKeyWindow]) {
	    [win makeKeyAndOrderFront:NSApp];

	}
    }

    /*
     * Remember the current serial number for the X server and issue a dummy
     * server request. This marks the position at which we changed the focus,
     * so we can distinguish FocusIn and FocusOut events on either side of the







>







7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204

    	TkWmRestackToplevel(winPtr, Above, NULL);
    	if (force) {
    	    [NSApp activateIgnoringOtherApps:YES];
    	}
	if (win && [win canBecomeKeyWindow]) {
	    [win makeKeyAndOrderFront:NSApp];
	    [NSApp setTkEventTarget:TkMacOSXGetTkWindow(win)];
	}
    }

    /*
     * Remember the current serial number for the X server and issue a dummy
     * server request. This marks the position at which we changed the focus,
     * so we can distinguish FocusIn and FocusOut events on either side of the
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
    windows = windowPtr = (TkWindow **)ckalloc((windowCount + 1) * sizeof(TkWindow *));
    if (windows != NULL) {
	Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
	WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
	for (NSWindow *w in backToFront) {
	    hPtr = Tcl_FindHashEntry(&table, (char*) w);
	    if (hPtr != NULL) {
		childWinPtr = Tcl_GetHashValue(hPtr);
		*windowPtr++ = childWinPtr;
	    }
	}
	*windowPtr = NULL;
	Tcl_DeleteHashTable(&table);
    }
    return windows;







|







7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
    windows = windowPtr = (TkWindow **)ckalloc((windowCount + 1) * sizeof(TkWindow *));
    if (windows != NULL) {
	Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
	WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
	for (NSWindow *w in backToFront) {
	    hPtr = Tcl_FindHashEntry(&table, (char*) w);
	    if (hPtr != NULL) {
		childWinPtr = (TkWindow *)Tcl_GetHashValue(hPtr);
		*windowPtr++ = childWinPtr;
	    }
	}
	*windowPtr = NULL;
	Tcl_DeleteHashTable(&table);
    }
    return windows;
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
		     * The default max size has height less than the screen
		     * height. This causes the window manager to refuse to
		     * allow the window to be resized when it is a split
		     * window. To work around this we make the max size equal
		     * to the screen size.  (For 10.11 and up, only)
		     */

		    if (@available(macOS 10.11, *)) {
			NSSize screenSize = [[macWindow screen] frame].size;
			[macWindow setMaxFullScreenContentSize:screenSize];
		    }
		}
	    }
#endif








|







7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
		     * 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] >= 101100) {
			NSSize screenSize = [[macWindow screen] frame].size;
			[macWindow setMaxFullScreenContentSize:screenSize];
		    }
		}
	    }
#endif

7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
		title = winPtr->nameUid;
	    }
	    [macWindow setStyleMask:styleMask];
	    [macWindow setTitle:[NSString stringWithUTF8String:title]];
	    [macWindow setExcludedFromWindowsMenu:NO];
	    wmPtr->flags &= ~WM_TOPMOST;
	}
	if (wmPtr->container != None) {
	    TkWindow *containerWinPtr = (TkWindow *)wmPtr->container;

	    if (containerWinPtr && (containerWinPtr->window != None)
		    && TkMacOSXHostToplevelExists(containerWinPtr)) {
		NSWindow *containerMacWin = TkMacOSXGetNSWindowForDrawable(
			containerWinPtr->window);








|







7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
		title = winPtr->nameUid;
	    }
	    [macWindow setStyleMask:styleMask];
	    [macWindow setTitle:[NSString stringWithUTF8String:title]];
	    [macWindow setExcludedFromWindowsMenu:NO];
	    wmPtr->flags &= ~WM_TOPMOST;
	}
	if (wmPtr->container != NULL) {
	    TkWindow *containerWinPtr = (TkWindow *)wmPtr->container;

	    if (containerWinPtr && (containerWinPtr->window != None)
		    && TkMacOSXHostToplevelExists(containerWinPtr)) {
		NSWindow *containerMacWin = TkMacOSXGetNSWindowForDrawable(
			containerWinPtr->window);

7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
    TkWindow *winPtr,		/* Toplevel window to operate on. */
    int *maxWidthPtr,		/* Where to store the current maximum width of
				 * the window. */
    int *maxHeightPtr)		/* Where to store the current maximum height
				 * of the window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSRect *maxBounds = (NSRect*)(winPtr->display->screens->ext_data);

    if (wmPtr->maxWidth > 0) {
	*maxWidthPtr = wmPtr->maxWidth;
    } else {
	int maxWidth = maxBounds->size.width - wmPtr->xInParent;

	if (wmPtr->gridWin != NULL) {







|







7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
    TkWindow *winPtr,		/* Toplevel window to operate on. */
    int *maxWidthPtr,		/* Where to store the current maximum width of
				 * the window. */
    int *maxHeightPtr)		/* Where to store the current maximum height
				 * of the window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSRect *maxBounds = (NSRect*)(ScreenOfDisplay(winPtr->display, 0)->ext_data);

    if (wmPtr->maxWidth > 0) {
	*maxWidthPtr = wmPtr->maxWidth;
    } else {
	int maxWidth = maxBounds->size.width - wmPtr->xInParent;

	if (wmPtr->gridWin != NULL) {

Changes to macosx/tkMacOSXWm.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkMacOSXWm.h --
 *
 *	Declarations of Macintosh specific window manager structures.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 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





|
|







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 © 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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
				 * be. */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    int cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */







|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
				 * be. */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    Tcl_Size cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */

Changes to macosx/tkMacOSXXCursors.h.

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]>
 *
 * 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] = {








|
|
|







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 © 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
20
21
22
23
24
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */


#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"

#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>

/*








|
|
|
|





>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * 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 © 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.
 */

#define XLIB_ILLEGAL_ACCESS
#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.h"

#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>

/*
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
TkMacOSXDisplayChanged(
    Display *display)
{
    Screen *screen;
    NSArray *nsScreens;


    if (display == NULL || display->screens == NULL) {
	return;
    }
    screen = display->screens;

    nsScreens = [NSScreen screens];
    if (nsScreens && [nsScreens count]) {
	NSScreen *s = [nsScreens objectAtIndex:0];
	NSRect bounds = [s frame];
	NSRect maxBounds = NSZeroRect;

	screen->root_depth = NSBitsPerPixelFromDepth([s depth]);
	screen->width = bounds.size.width;
	screen->height = bounds.size.height;
	screen->mwidth = (bounds.size.width * 254 + 360) / 720;
	screen->mheight = (bounds.size.height * 254 + 360) / 720;

	for (s in nsScreens) {
	    maxBounds = NSUnionRect(maxBounds, [s visibleFrame]);
	}
	*((NSRect *)screen->ext_data) = maxBounds;
    }
}







|


|







|
|
|
|
|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
TkMacOSXDisplayChanged(
    Display *display)
{
    Screen *screen;
    NSArray *nsScreens;


    if (display == NULL || (((_XPrivDisplay)(display))->screens) == NULL) {
	return;
    }
    screen = (((_XPrivDisplay)(display))->screens);

    nsScreens = [NSScreen screens];
    if (nsScreens && [nsScreens count]) {
	NSScreen *s = [nsScreens objectAtIndex:0];
	NSRect bounds = [s frame];
	NSRect maxBounds = NSZeroRect;

	DefaultDepthOfScreen(screen) = NSBitsPerPixelFromDepth([s depth]);
	WidthOfScreen(screen) = bounds.size.width;
	HeightOfScreen(screen) = bounds.size.height;
	WidthMMOfScreen(screen) = (bounds.size.width * 381 + 720) / 1440; /* = 3/4 * 254/720 */
	HeightMMOfScreen(screen) = (bounds.size.height * 381 + 720) / 1440; /* = 3/4 * 254/720 */

	for (s in nsScreens) {
	    maxBounds = NSUnionRect(maxBounds, [s visibleFrame]);
	}
	*((NSRect *)screen->ext_data) = maxBounds;
    }
}
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198


199
200
201
202
203
204
205
206
 */

TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{
    Display *display;
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (gMacDisplay != NULL) {
	if (strcmp(gMacDisplay->display->display_name, display_name) == 0) {
	    return gMacDisplay;
	} else {
	    return NULL;
	}
    }



    display = XkbOpenDisplay((char *)display_name, NULL, NULL, NULL, NULL, NULL);

    /*
     * Initialize screen bits that may change
     */

    TkMacOSXDisplayChanged(display);








<


|






>
>
|







183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
 */

TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{
    Display *display;


    if (gMacDisplay != NULL) {
	if (strcmp(DisplayString(gMacDisplay->display), display_name) == 0) {
	    return gMacDisplay;
	} else {
	    return NULL;
	}
    }

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    display = XkbOpenDisplay(display_name, NULL, NULL, NULL, NULL, NULL);

    /*
     * Initialize screen bits that may change
     */

    TkMacOSXDisplayChanged(display);

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    TCL_UNUSED(const char *),
	int *ev_rtrn,
	int *err_rtrn,
	int *major_rtrn,
	int *minor_rtrn,
	int *reason)
{
    Display *display = (Display *)ckalloc(sizeof(Display));
    Screen *screen = (Screen *)ckalloc(sizeof(Screen));
    int fd = 0;
    NSArray *cgVers;
    static char vendor[25] = "";
    static NSRect maxBounds = {{0, 0}, {0, 0}};

    bzero(display, sizeof(Display));
    bzero(screen, sizeof(Screen));

    display->resource_alloc = MacXIdAlloc;
    display->request	    = 0;
    display->qlen	    = 0;
    display->fd		    = fd;
    display->screens	    = screen;
    display->nscreens	    = 1;
    display->default_screen = 0;
    display->display_name   = (char *) macScreenName;








|










|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    TCL_UNUSED(const char *),
	int *ev_rtrn,
	int *err_rtrn,
	int *major_rtrn,
	int *minor_rtrn,
	int *reason)
{
    _XPrivDisplay display = (_XPrivDisplay)ckalloc(sizeof(Display));
    Screen *screen = (Screen *)ckalloc(sizeof(Screen));
    int fd = 0;
    NSArray *cgVers;
    static char vendor[25] = "";
    static NSRect maxBounds = {{0, 0}, {0, 0}};

    bzero(display, sizeof(Display));
    bzero(screen, sizeof(Screen));

    display->resource_alloc = MacXIdAlloc;
    LastKnownRequestProcessed(display) = 1;
    display->qlen	    = 0;
    display->fd		    = fd;
    display->screens	    = screen;
    display->nscreens	    = 1;
    display->default_screen = 0;
    display->display_name   = (char *) macScreenName;

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
	patch = systemVersion.patchVersion;
#endif
	display->release = major << 16 | minor << 8 | patch;
    }


    if (ev_rtrn) *ev_rtrn = 0;
    if (err_rtrn) *err_rtrn = 0;







|
|
|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = (int)systemVersion.majorVersion;
	minor = (int)systemVersion.minorVersion;
	patch = (int)systemVersion.patchVersion;
#endif
	display->release = major << 16 | minor << 8 | patch;
    }


    if (ev_rtrn) *ev_rtrn = 0;
    if (err_rtrn) *err_rtrn = 0;
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
 *----------------------------------------------------------------------
 */

void
TkpCloseDisplay(
    TkDisplay *displayPtr)
{
    Display *display = displayPtr->display;

    if (gMacDisplay != displayPtr) {
	Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display");
    }

    gMacDisplay = NULL;
    if (display->screens != NULL) {
	if (display->screens->root_visual != NULL) {
	    ckfree(display->screens->root_visual);
	}
	ckfree(display->screens);
    }
    ckfree(display);
}

/*







|







|
|







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
 *----------------------------------------------------------------------
 */

void
TkpCloseDisplay(
    TkDisplay *displayPtr)
{
    _XPrivDisplay display = (_XPrivDisplay)displayPtr->display;

    if (gMacDisplay != displayPtr) {
	Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on bad display");
    }

    gMacDisplay = NULL;
    if (display->screens != NULL) {
	if (DefaultVisualOfScreen(ScreenOfDisplay(display, 0)) != NULL) {
	    ckfree(DefaultVisualOfScreen(ScreenOfDisplay(display, 0)));
	}
	ckfree(display->screens);
    }
    ckfree(display);
}

/*
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
}

char *
XGetAtomName(
    Display *display,
    TCL_UNUSED(Atom))
{
    display->request++;
    return NULL;
}

XErrorHandler
XSetErrorHandler(
    TCL_UNUSED(XErrorHandler))
{
    return DefaultErrorHandler;
}

Window
XRootWindow(
    Display *display,
    TCL_UNUSED(int))
{
    display->request++;
    return ROOT_ID;
}

int
XGetGeometry(
    Display *display,
    Drawable d,
    Window *root_return,
    int *x_return,
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWindow *winPtr = ((MacDrawable *)d)->winPtr;

    display->request++;
    *root_return = ROOT_ID;
    if (winPtr) {
	*x_return = Tk_X(winPtr);
	*y_return = Tk_Y(winPtr);
	*width_return = Tk_Width(winPtr);
	*height_return = Tk_Height(winPtr);
	*border_width_return = winPtr->changes.border_width;







|















|

















|







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
}

char *
XGetAtomName(
    Display *display,
    TCL_UNUSED(Atom))
{
    LastKnownRequestProcessed(display)++;
    return NULL;
}

XErrorHandler
XSetErrorHandler(
    TCL_UNUSED(XErrorHandler))
{
    return DefaultErrorHandler;
}

Window
XRootWindow(
    Display *display,
    TCL_UNUSED(int))
{
    LastKnownRequestProcessed(display)++;
    return ROOT_ID;
}

int
XGetGeometry(
    Display *display,
    Drawable d,
    Window *root_return,
    int *x_return,
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWindow *winPtr = ((MacDrawable *)d)->winPtr;

    LastKnownRequestProcessed(display)++;
    *root_return = ROOT_ID;
    if (winPtr) {
	*x_return = Tk_X(winPtr);
	*y_return = Tk_Y(winPtr);
	*width_return = Tk_Width(winPtr);
	*height_return = Tk_Height(winPtr);
	*border_width_return = winPtr->changes.border_width;
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
    TCL_UNUSED(Atom),
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    TCL_UNUSED(unsigned char **))
{
    display->request++;
    *actual_type_return = None;
    *actual_format_return = *bytes_after_return = 0;
    *nitems_return = 0;
    return 0;
}

int







|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
    TCL_UNUSED(Atom),
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    TCL_UNUSED(unsigned char **))
{
    LastKnownRequestProcessed(display)++;
    *actual_type_return = None;
    *actual_format_return = *bytes_after_return = 0;
    *nitems_return = 0;
    return 0;
}

int
855
856
857
858
859
860
861
862
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
    Display* display,
    TCL_UNUSED(Window),
    TCL_UNUSED(const char *))
{
    /*
     * This is a no-op, no icon name for Macs.
     */
    display->request++;
    return Success;
}









int
XForceScreenSaver(
    Display* display,
    TCL_UNUSED(int))
{
    /*
     * This function is just a no-op. It is defined to reset the screen saver.
     * However, there is no real way to do this on a Mac. Let me know if there
     * is!
     */

    display->request++;
    return Success;
}

int
XSetClipRectangles(
    Display *d,
    GC gc,
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    TCL_UNUSED(int))
{
    TkRegion clipRgn = TkCreateRegion();

    while (n--) {
    	XRectangle rect = *rectangles;

    	rect.x += clip_x_origin;
    	rect.y += clip_y_origin;
    	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
    	rectangles++;
    }
    TkSetRegion(d, gc, clipRgn);
    TkDestroyRegion(clipRgn);
    return 1;
}
/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo







|


>
>
>
>
>
>
>
>












|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







857
858
859
860
861
862
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
    Display* display,
    TCL_UNUSED(Window),
    TCL_UNUSED(const char *))
{
    /*
     * This is a no-op, no icon name for Macs.
     */
    LastKnownRequestProcessed(display)++;
    return Success;
}

Bool
XFilterEvent(
    TCL_UNUSED(XEvent *),
    TCL_UNUSED(Window))
{
    return 0;
}

int
XForceScreenSaver(
    Display* display,
    TCL_UNUSED(int))
{
    /*
     * This function is just a no-op. It is defined to reset the screen saver.
     * However, there is no real way to do this on a Mac. Let me know if there
     * is!
     */

    LastKnownRequestProcessed(display)++;
    return Success;
}

























/*
 *----------------------------------------------------------------------
 *
 * TkGetServerInfo --
 *
 *	Given a window, this procedure returns information about the window
 *	server for that window. This procedure provides the guts of the "winfo
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

int
XGetInputFocus(
    Display *display,
    TCL_UNUSED(Window *),
    TCL_UNUSED(int *))
{
    display->request++;
    return Success;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

XAfterFunction
XSynchronize(
    Display *display,
    TCL_UNUSED(Bool))
{
    display->request++;
    return NULL;
}

int
XUngrabServer(
    TCL_UNUSED(Display *))
{







|















|







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

int
XGetInputFocus(
    Display *display,
    TCL_UNUSED(Window *),
    TCL_UNUSED(int *))
{
    LastKnownRequestProcessed(display)++;
    return Success;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

XAfterFunction
XSynchronize(
    Display *display,
    TCL_UNUSED(Bool))
{
    LastKnownRequestProcessed(display)++;
    return NULL;
}

int
XUngrabServer(
    TCL_UNUSED(Display *))
{
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
    return Success;
}

int
XNoOp(
    Display *display)
{
	display->request++;
    return 0;
}

int
XGrabServer(
    TCL_UNUSED(Display *))
{







|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
    return Success;
}

int
XNoOp(
    Display *display)
{
    LastKnownRequestProcessed(display)++;
    return 0;
}

int
XGrabServer(
    TCL_UNUSED(Display *))
{

Changes to macosx/ttkMacOSXTheme.c.

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
 *
 * 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/





|
|
|
|
|
|







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 © 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
50
51
52
53


54
55
56
57
58
59
60
61
62

63
64
65
66






67


68

69






70
71

72
73
74
75
76
77



78
79
80

81

82
83
84
85
86


87
88
89
90

91

92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112

113







114
115
116


117


118
119
120
121
122








123

124
125
126
127


128
129
130





131
132
133
134
135
136
137

138

139




140

141
142
143
144
145
146
147

148
149


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184


185


186
187
188
189






190
191
192
193



194
195
196
197
198
199
200
201

202

203
204
205
206

207

208
209
210
211
212










213


214













215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249



250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
















































































































































































































































































































304
305
306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321








322
323
324
325
326
327
328
329
330
331
332






333
334
335
336
337
338
339
340

341
342



343


344
345
346
347
348
349
350
351
352
353
354





















































355
356
357
358
359
360
361
 *
 *      The QuickDraw/Carbon coordinate system is relative to the top-level
 *      window, not to the Tk_Window.  BoxToRect() accounts for this.
 */

#include "tkMacOSXPrivate.h"
#include "ttk/ttkTheme.h"


#include <math.h>











/*

 * Macros for handling drawing contexts.
 */

#define BEGIN_DRAWING(d) {	   \
	TkMacOSXDrawingContext dc; \
	if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) {return;}
#define END_DRAWING \
    TkMacOSXRestoreDrawingContext(&dc);}

#define HIOrientation kHIThemeOrientationNormal
#define NoThemeMetric 0xFFFFFFFF

#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */



#define TTK_STATE_FIRST_TAB     TTK_STATE_USER1
#define TTK_STATE_LAST_TAB      TTK_STATE_USER2
#define TTK_TREEVIEW_STATE_SORTARROW    TTK_STATE_USER1

/*
 * Colors and gradients used in Dark Mode.
 */


static CGFloat darkButtonFace[4] = {
    112.0 / 255, 113.0 / 255, 115.0 / 255, 1.0
};
static CGFloat darkPressedBevelFace[4] = {






    135.0 / 255, 136.0 / 255, 138.0 / 255, 1.0


};

static CGFloat darkSelectedBevelFace[4] = {






    162.0 / 255, 163.0 / 255, 165.0 / 255, 1.0
};

static CGFloat darkDisabledButtonFace[4] = {
    86.0 / 255, 87.0 / 255, 89.0 / 255, 1.0
};
static CGFloat darkInactiveSelectedTab[4] = {
    159.0 / 255, 160.0 / 255, 161.0 / 255, 1.0
};



static CGFloat darkFocusRing[4] = {
    38.0 / 255, 113.0 / 255, 159.0 / 255, 1.0
};

static CGFloat darkFocusRingTop[4] = {

    50.0 / 255, 124.0 / 255, 171.0 / 255, 1.0
};
static CGFloat darkFocusRingBottom[4] = {
    57.0 / 255, 130.0 / 255, 176.0 / 255, 1.0
};


static CGFloat darkTabSeparator[4] = {0.0, 0.0, 0.0, 0.25};
static CGFloat darkTrack[4] = {1.0, 1.0, 1.0, 0.25};
static CGFloat darkFrameTop[4] = {1.0, 1.0, 1.0, 0.0625};
static CGFloat darkFrameBottom[4] = {1.0, 1.0, 1.0, 0.125};

static CGFloat darkFrameAccent[4] = {0.0, 0.0, 0.0, 0.0625};

static CGFloat darkTopGradient[8] = {
    1.0, 1.0, 1.0, 0.3,

    1.0, 1.0, 1.0, 0.0
};
static CGFloat darkBackgroundGradient[8] = {
    0.0, 0.0, 0.0, 0.1,
    0.0, 0.0, 0.0, 0.25
};
static CGFloat darkInactiveGradient[8] = {
    89.0 / 255, 90.0 / 255, 93.0 / 255, 1.0,
    119.0 / 255, 120.0 / 255, 122.0 / 255, 1.0
};
static CGFloat darkSelectedGradient[8] = {
    23.0 / 255, 111.0 / 255, 232.0 / 255, 1.0,
    20.0 / 255, 94.0 / 255,  206.0 / 255, 1.0
};
static CGFloat pressedPushButtonGradient[8] = {
    35.0 / 255, 123.0 / 255, 244.0 / 255, 1.0,
    30.0 / 255, 114.0 / 255, 235.0 / 255, 1.0
};



/*







 * When building on systems earlier than 10.8 there is no reasonable way to
 * convert an NSColor to a CGColor.  We do run-time checking of the OS version,
 * and never need the CGColor property on older systems, so we can use this


 * CGCOLOR macro, which evaluates to NULL without raising compiler warnings.


 * Similarly, we never draw rounded rectangles on older systems which did not
 * have CGPathCreateWithRoundedRect, so we just redefine it to return NULL.
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080








#define CGCOLOR(nscolor) nscolor.CGColor

#else
#define CGCOLOR(nscolor) (0 ? (CGColorRef) nscolor : NULL)
#define CGPathCreateWithRoundedRect(w, x, y, z) NULL
#endif



/*
 * If we try to draw a rounded rectangle with too large of a radius





 * CoreGraphics will raise a fatal exception.  This macro returns if
 * the width or height is less than twice the radius.  Presumably this
 * only happens when a widget has not yet been configured and has size
 * 1x1.
 */

#define CHECK_RADIUS(radius, bounds)                                         \

    if (radius > bounds.size.width / 2 || radius > bounds.size.height / 2) { \

        return;                                                              \




    }


/*----------------------------------------------------------------------
 * +++ Utilities.
 */

/*
 * BoxToRect --

 *    Convert a Ttk_Box in Tk coordinates relative to the given Drawable
 *    to a native Rect relative to the containing port.


 */

static inline CGRect BoxToRect(
    Drawable d,
    Ttk_Box b)
{
    MacDrawable *md = (MacDrawable *)d;
    CGRect rect;

    rect.origin.y       = b.y + md->yOff;
    rect.origin.x       = b.x + md->xOff;
    rect.size.height    = b.height;
    rect.size.width     = b.width;

    return rect;
}

/*
 * Table mapping Tk states to Appearance manager ThemeStates
 */


static Ttk_StateTable ThemeStateTable[] = {
    {kThemeStateActive, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeStateUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeStatePressed, TTK_STATE_PRESSED, 0},
    {kThemeStateInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeStateActive, 0, 0}

    /* Others: Not sure what these are supposed to mean.  Up/Down have
     * something to do with "little arrow" increment controls...  Dunno what
     * a "Rollover" is.
     * NEM: Rollover is TTK_STATE_ACTIVE... but we don't handle that yet, by
     * the looks of things
     *
     * {kThemeStateRollover, 0, 0},


     * {kThemeStateUnavailableInactive, 0, 0}


     * {kThemeStatePressedUp, 0, 0},
     * {kThemeStatePressedDown, 0, 0}
     */
};







/*----------------------------------------------------------------------
 * NormalizeButtonBounds --
 *



 *      Apple's Human Interface Guidelines only allow three specific heights
 *      for most buttons: Regular, small and mini. We always use the regular
 *      size.  However, Ttk may provide an arbitrary bounding rectangle.  We
 *      always draw the button centered vertically on the rectangle, and
 *      having the same width as the rectangle.  This function returns the
 *      actual bounding rectangle that will be used in drawing the button.
 *
 *      The BevelButton is allowed to have arbitrary size, and also has

 *      external padding.  This is handled separately here.

 */

static CGRect NormalizeButtonBounds(
    SInt32 heightMetric,

    CGRect bounds)

{
    SInt32 height;

    if (heightMetric != (SInt32) NoThemeMetric) {
	ChkErr(GetThemeMetric, heightMetric, &height);










	bounds.origin.y += (bounds.size.height - height) / 2;


	bounds.size.height = height;













    }
    return bounds;
}

/*----------------------------------------------------------------------
 * +++ Backgrounds
 *
 * Support for contrasting background colors when GroupBoxes or Tabbed
 * panes are nested inside each other.  Early versions of macOS used ridged
 * borders, so do not need contrasting backgrounds.
 */

/*
 * For systems older than 10.14, [NSColor windowBackGroundColor] generates
 * garbage when called from this function.  In 10.14 it works correctly, and
 * must be used in order to have a background color which responds to Dark
 * Mode.  So we use this hard-wired RGBA color on the older systems which don't
 * support Dark Mode anyway.
 */

static const CGFloat WINDOWBACKGROUND[4] = {
    235.0 / 255, 235.0 / 255, 235.0 / 255, 1.0
};
static const CGFloat WHITERGBA[4] = {1.0, 1.0, 1.0, 1.0};
static const CGFloat BLACKRGBA[4] = {0.0, 0.0, 0.0, 1.0};

/*----------------------------------------------------------------------
 * GetBackgroundColor --
 *
 *      Fills the array rgba with the color coordinates for a background color.
 *      Start with the background color of a window's geometry container, or
 *      the standard ttk window background if there is no container. If the
 *      contrast parameter is nonzero, modify this color to be darker, for the
 *      aqua appearance, or lighter for the DarkAqua appearance.  This is
 *      primarily used by the Fill and Background elements.



 */

static void GetBackgroundColor(
    TCL_UNUSED(CGContextRef),
    Tk_Window tkwin,
    int contrast,

    CGFloat *rgba)
{
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *containerPtr = (TkWindow *)TkGetContainer(tkwin);

    while (containerPtr && containerPtr->privatePtr) {
	if (containerPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) {
	    break;
	}
	containerPtr = (TkWindow *)TkGetContainer(containerPtr);
    }
    if (containerPtr && containerPtr->privatePtr) {
	for (int i = 0; i < 4; i++) {
	    rgba[i] = containerPtr->privatePtr->fillRGBA[i];
	}
    } else {
	if ([NSApp macOSVersion] > 101300) {
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *windowColor = [[NSColor windowBackgroundColor]
		colorUsingColorSpace: deviceRGB];
	    [windowColor getComponents: rgba];
	} else {
	    for (int i = 0; i < 4; i++) {
		rgba[i] = WINDOWBACKGROUND[i];
	    }
	}
    }

    if (contrast) {
	int isDark = (rgba[0] + rgba[1] + rgba[2] < 1.5);

	if (isDark) {
	    for (int i = 0; i < 3; i++) {
		rgba[i] += 8.0 / 255.0;
	    }
	} else {
	    for (int i = 0; i < 3; i++) {
		rgba[i] -= 8.0 / 255.0;
	    }
	}
        if (winPtr->privatePtr) {
            winPtr->privatePtr->flags |= TTK_HAS_CONTRASTING_BG;
            for (int i = 0; i < 4; i++) {
                winPtr->privatePtr->fillRGBA[i] = rgba[i];
            }
        }
    }
}


















































































































































































































































































































/*----------------------------------------------------------------------
 * +++ Single Arrow Images --
 *
 * Used in ListHeaders and Comboboxes as well as disclosure triangles in
 * macOS 11.
 */

static void DrawDownArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    const CGFloat *rgba)
{

    CGFloat x, y;

    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);








    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4}, {x + size / 2, y + size / 4},
	{x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}







static void DrawUpArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    const CGFloat *rgba)
{

    CGFloat x, y;




    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);


    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y + size / 4}, {x + size / 2, y - size / 4},
	{x + size, y + size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}






















































static void DrawClosedDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)







>
>


>
>
>
>
>
>
>
>
>
>

>
|


<
<
<
<
<
|
|
<

<
<
<
<
<
>
>
|
<
|
<
|
<
|


>
|
<
<
|
>
>
>
>
>
>
|
>
>
|
>
|
>
>
>
>
>
>
|
<
>
|
|
<
|
<
<
>
>
>
|
|
<
>
|
>
|
<
|
<
<
>
>
|
|
|
<
>
|
>
|
<
>
|
<
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
|
>
|
>

>
>
>
>
>
>
>
|
|
|
>
>
|
>
>
|
|



>
>
>
>
>
>
>
>
|
>
|
|
<
<
>
>
|
<
<
>
>
>
>
>
|
<
<
<
<
|
|
>
|
>
|
>
>
>
>
|
>





|

>
|
|
>
>

















|
<
|
|
>
|
<
<
<
<
<
|
<
<
<
<
<
|
|
>
>
|
>
>
|
|
<
<
>
>
>
>
>
>




>
>
>
|
|
|
|
|
|

<
>
|
>



<
>
|
>



|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>





|







|






<
|
<
<
<





|
|


|
>
>
>


|



>


|
|



















|



>





|



|


|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<
<
<







|

>


|
>
>
>
>
>
>
>
>


|








>
>
>
>
>
>






|

>


>
>
>
|
>
>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52





53
54

55





56
57
58

59

60

61
62
63
64
65


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88

89


90
91
92
93
94

95
96
97
98

99


100
101
102
103
104

105
106
107
108

109
110

111
112
113









114


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154


155
156
157
158
159
160




161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205
206





207





208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674



675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
 *
 *      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 "ttkMacOSXTheme.h"
#include "tkColor.h"
#include <math.h>

MODULE_SCOPE NSColor *controlAccentColor(void) {
    static int accentPixel = -1;
    if (accentPixel == -1) {
	TkColor *temp = TkpGetColor(NULL, "systemControlAccentColor");
	accentPixel = temp->color.pixel;
	ckfree(temp);
    }
    return TkMacOSXGetNSColor(NULL, accentPixel);
}

/*
 * Values which depend on the OS version.  These are initialized
 * in Ttk_MacOSXInit.
 */






static Ttk_Padding entryElementPadding;
static CGFloat Ttk_ContrastDelta;







/*----------------------------------------------------------------------
 * +++ ComputeButtonDrawInfo --
 *

 *      Fill in an appearance manager HIThemeButtonDrawInfo record

 *      from a Ttk state and the ThemeButtonParams used as the

 *      clientData.
 */

static inline HIThemeButtonDrawInfo ComputeButtonDrawInfo(
    ThemeButtonParams *params,


    Ttk_State state,
    TCL_UNUSED(Tk_Window))
{
    /*
     * See ButtonElementDraw for the explanation of why we always draw
     * some buttons in the active state.
     */

    SInt32 HIThemeState;
    int adornment = 0;

    HIThemeState = Ttk_StateTableLookup(ThemeStateTable, state);

    /*
     * HITheme uses the adornment to decide the direction of the
     * arrow on a Disclosure Button.  Also HITheme draws inactive
     * (TTK_STATE_BACKGROUND) buttons in a gray color but macOS
     * no longer does that.  So we adjust the HIThemeState.
     */


    switch (params->kind) {
    case kThemeArrowButton:
	adornment = kThemeAdornmentDrawIndicatorOnly;

	if (state & TTK_STATE_SELECTED) {


	    adornment |= kThemeAdornmentArrowUpArrow;
	}
	/* Fall through. */
    case kThemeRadioButton:
	/*

	 * The gray color is better than the blue color for a
	 * background selected Radio Button.
	 */


	if (state & TTK_STATE_SELECTED) {


	    break;
	}
    default:
	if (state & TTK_STATE_BACKGROUND) {
	    HIThemeState |= kThemeStateActive;

	}
	break;
    }


    const HIThemeButtonDrawInfo info = {
	.version = 0,

	.state = HIThemeState,
	.kind = params ? params->kind : 0,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),









	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state) | adornment,


    };
    return info;
}

/*
 * When we draw simulated Apple widgets we use the Core Graphics framework.
 * Core Graphics uses CGColorRefs, not NSColors.  A CGColorRef must be retained
 * and released explicitly while an NSColor is autoreleased.  In version 10.8
 * of macOS Apple introduced a CGColor property of an NSColor which is guaranteed
 * to be a valid CGColorRef for (approximately) the same color and is released
 * when the NSColor is autoreleased.
 *
 * When building on systems earlier than 10.8 there is no painless way to
 * convert an NSColor to a CGColor. On the other hand, on those systems we use
 * the HIToolbox to draw all widgets, so we never need to call Core Graphics
 * drawing routines directly.  This means that the functions and macros below
 * which construct CGColorRefs can be defined to return nil on systems before
 * 10.8.
 *
 * Similarly, those older systems did not have CGPathCreateWithRoundedRect, but
 * since we never need to draw rounded rectangles on those systems we can just
 * define it to return nil.
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
static CGColorRef
CGColorFromRGBA(
    CGFloat *rgba)
{
    NSColorSpace *colorSpace = [NSColorSpace sRGBColorSpace];
    NSColor *nscolor = [NSColor colorWithColorSpace: colorSpace
					 components: rgba
					      count: 4];
    return nscolor.CGColor;
}

static CGColorRef


CGColorFromGray(
    GrayColor g)
{


    CGFloat rgba[4] = {g.grayscale, g.grayscale, g.grayscale, g.alpha};
    NSColorSpace *colorSpace = [NSColorSpace sRGBColorSpace];
    NSColor *nscolor = [NSColor colorWithColorSpace: colorSpace
					 components: rgba
					      count: 4];
    return nscolor.CGColor;




}

#define CGCOLOR(nscolor) (nscolor).CGColor

#else

#define CGCOLOR(nscolor) NULL
#define CGColorFromRGBA(rgba) NULL
#define CGColorFromGray(gray) NULL
#define CGPathCreateWithRoundedRect(w, x, y, z) NULL

#endif

/*----------------------------------------------------------------------
 * +++ Utilities.
 */

/*----------------------------------------------------------------------
 * BoxToRect --
 *
 *    Convert a Ttk_Box in Tk coordinates relative to the given Drawable to a
 *    native CGRect relative to the containing NSView.  (The coordinate system
 *    is the one used by CGContextRef, which has origin at the upper left
 *    corner, and y increasing downward.)
 */

static inline CGRect BoxToRect(
    Drawable d,
    Ttk_Box b)
{
    MacDrawable *md = (MacDrawable *)d;
    CGRect rect;

    rect.origin.y       = b.y + md->yOff;
    rect.origin.x       = b.x + md->xOff;
    rect.size.height    = b.height;
    rect.size.width     = b.width;

    return rect;
}

/*----------------------------------------------------------------------

 * LookupGrayPalette
 *
 * Retrieves the palette of grayscale colors needed to draw a particular
 * type of button, in a particular state, in light or dark mode.





 *





 */

static GrayPalette LookupGrayPalette(
    const ButtonDesign *design,
    Ttk_State state,
    int isDark)
{
    const PaletteStateTable *entry = design->palettes;
    while ((state & entry->onBits) != entry->onBits ||


           (~state & entry->offBits) != entry->offBits)
    {
        ++entry;
    }
    return isDark ? entry->dark : entry->light;
}

/*----------------------------------------------------------------------
 * NormalizeButtonBounds --
 *
 *      This function returns the actual bounding rectangle that will be used
 *      in drawing the button.
 *
 *      Apple only allows three specific heights for most buttons: regular,
 *      small and mini. We always use the regular size.  However, Ttk may
 *      provide a bounding rectangle with arbitrary height.  We draw the Mac
 *      button centered vertically in the Ttk rectangle, with the same width as
 *      the rectangle.  (But we take care to produce an integer y coordinate,
 *      to avoid unexpected anti-aliasing.)
 *

 *      In addition, the button types which are not known to HIToolbox need some
 *      adjustments to their bounds.
 *
 */

static CGRect NormalizeButtonBounds(

    ThemeButtonParams *params,
    CGRect bounds,
    int isDark)
{
    SInt32 height;

    if (params->heightMetric != NoThemeMetric) {
	ChkErr(GetThemeMetric, params->heightMetric, &height);
	height += 2;
	bounds.origin.y += round(1 + (bounds.size.height - height) / 2);
	bounds.size.height = height;
    }
    switch (params->kind) {
    case TkRoundedRectButton:
	bounds.size.height -= 1;
	break;
    case TkInlineButton:
	bounds.size.height -= 4;
	bounds.origin.y += 1;
	break;
    case TkRecessedButton:
	bounds.size.height -= 2;
	break;
    case TkSidebarButton:
	bounds.size.height += 8;
	break;
    case kThemeRoundButtonHelp:
	if (isDark) {
	    bounds.size.height = bounds.size.width = 22;
	} else {
	    bounds.size.height = bounds.size.width = 22;
	}
	break;
    default:
	break;
    }
    return bounds;
}

/*----------------------------------------------------------------------
 * +++ Background Colors
 *
 * Support for contrasting background colors when GroupBoxes or Tabbed
 * panes are nested inside each other.  Early versions of macOS used ridged
 * borders, so do not need contrasting backgrounds.
 */

/*
 * For systems older than 10.14, [NSColor windowBackgroundColor] generates
 * garbage when called from this function.  In 10.14 it works correctly, and
 * must be used in order to have a background color which responds to Dark
 * Mode.  So we use this hard-wired RGBA color on the older systems which don't
 * support Dark Mode anyway.
 */


RGBACOLOR windowBackground[4] = RGBA256(235.0, 235.0, 235.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 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.  The save parameter
 *      is normally YES, so the contrasting color is saved in the private
 *      data of the widget.  This behavior can be disabled in special cases,
 *      such as when drawing notebook tabs in macOS 11.
 */

static void GetBackgroundColorRGBA(
    TCL_UNUSED(CGContextRef),
    Tk_Window tkwin,
    int contrast,
    Bool save,
    CGFloat *rgba)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *containerPtr = (TkWindow *) TkGetContainer(tkwin);

    while (containerPtr && containerPtr->privatePtr) {
	if (containerPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) {
	    break;
	}
	containerPtr = (TkWindow *)TkGetContainer(containerPtr);
    }
    if (containerPtr && containerPtr->privatePtr) {
	for (int i = 0; i < 4; i++) {
	    rgba[i] = containerPtr->privatePtr->fillRGBA[i];
	}
    } else {
	if ([NSApp macOSVersion] > 101300) {
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *windowColor = [[NSColor windowBackgroundColor]
		colorUsingColorSpace: deviceRGB];
	    [windowColor getComponents: rgba];
	} else {
	    for (int i = 0; i < 4; i++) {
		rgba[i] = windowBackground[i];
	    }
	}
    }

    if (contrast) {
	int isDark = (rgba[0] + rgba[1] + rgba[2] < 1.5);

	if (isDark) {
	    for (int i = 0; i < 3; i++) {
		rgba[i] += Ttk_ContrastDelta*contrast / 255.0;
	    }
	} else {
	    for (int i = 0; i < 3; i++) {
		rgba[i] -= Ttk_ContrastDelta*contrast / 255.0;
	    }
	}
        if (save && winPtr->privatePtr) {
            winPtr->privatePtr->flags |= TTK_HAS_CONTRASTING_BG;
            for (int i = 0; i < 4; i++) {
                winPtr->privatePtr->fillRGBA[i] = rgba[i];
            }
        }
    }
}

static CGColorRef GetBackgroundCGColor(
    CGContextRef context,
    Tk_Window tkwin,
    int contrast,
    Bool save)
{
    CGFloat rgba[4];
    GetBackgroundColorRGBA(context, tkwin, contrast, save, rgba);
    return CGColorFromRGBA(rgba);
}

/*----------------------------------------------------------------------
 * +++ Buttons
 */

/*----------------------------------------------------------------------
 * FillRoundedRectangle --
 *
 *      Fill a rounded rectangle with a specified solid color.
 */

static void FillRoundedRectangle(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius,
    CGColorRef color)
{
    CGPathRef path;
    CHECK_RADIUS(radius, bounds)

    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    if (!path) {
	return;
    }
    CGContextSetFillColorWithColor(context, color);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------
 * FillBorder --
 *
 *      Draw a 1-pixel border around a rounded rectangle using a 3-step
 *      gradient of shades of gray.
 */

static void FillBorder(
    CGContextRef context,
    CGRect bounds,
    GrayPalette palette,
    CGFloat radius)
{
    if (bounds.size.width < 2) {
	return;
    }
    NSColorSpace *sRGB = [NSColorSpace sRGBColorSpace];
    CGPoint end = CGPointMake(bounds.origin.x, bounds.origin.y + bounds.size.height);
    CGFloat corner = (radius > 0 ? radius : 2.0) / bounds.size.height;
    CGFloat locations[4] = {0.0, corner, 1.0 - corner, 1.0};
    CGPathRef path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    CGFloat colors[16];
    colors[0] = colors[1] = colors[2] = palette.top / 255.0;
    colors[4] = colors[5] = colors[6] = palette.side / 255.0;
    colors[8] = colors[9] = colors[10] = palette.side / 255.0;
    colors[12] = colors[13] = colors[14] = palette.bottom / 255.0;
    colors[3] = colors[7] = colors[11] = colors[15] = 1.0;
    CGGradientRef gradient = CGGradientCreateWithColorComponents(
	 sRGB.CGColorSpace, colors, locations, 4);
    if (!gradient) {
	return;
    }
    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, bounds.origin, end, 0.0);
    CGContextRestoreGState(context);
    CFRelease(path);
    CFRelease(gradient);
}

/*----------------------------------------------------------------------
 * DrawFocusRing --
 *
 *      Draw a 4-pixel wide rounded focus ring enclosing a rounded
 *      rectangle, using the current system accent color.
 */

static void DrawFocusRing(
    CGContextRef context,
    CGRect bounds,
    const ButtonDesign *design)
{
    CGColorRef highlightColor;
    CGFloat highlight[4] = {1.0, 1.0, 1.0, 0.2};
    CGColorRef focusColor;

    focusColor = CGCOLOR([controlAccentColor() colorWithAlphaComponent:0.6]);
    FillRoundedRectangle(context, bounds, design->radius, focusColor);
    bounds = CGRectInset(bounds, 3, 3);
    highlightColor = CGColorFromRGBA(highlight);
    CGContextSetFillColorWithColor(context, highlightColor);
    CGContextFillRect(context, bounds);
}

/*----------------------------------------------------------------------
 * DrawGrayButton --
 *
 *      Draw a button in normal gray colors.
 *
 *      Aqua buttons are normally drawn in a grayscale color.  The buttons,
 *      which are shaped as rounded rectangles have a 1-pixel border which is
 *      drawn in a 3-step gradient and a solid gray face.
 *
 *      Note that this will produce a round button if length = width =
 *      2*radius.
 */

static void DrawGrayButton(
    CGContextRef context,
    CGRect bounds,
    const ButtonDesign *design,
    Ttk_State state,
    Tk_Window tkwin)
{
    int isDark = TkMacOSXInDarkMode(tkwin);
    GrayPalette palette = LookupGrayPalette(design, state, isDark);
    GrayColor faceGray = {.grayscale = 0.0, .alpha = 1.0};
    CGFloat radius = 2 * design->radius <= bounds.size.height ?
	design->radius : bounds.size.height / 2;
    if (palette.top <= 255.0) {
	FillBorder(context, bounds, palette, radius);
    }
    if (palette.face <= 255.0) {
	faceGray.grayscale = palette.face / 255.0;
    } else {

	/*
	 * Color values > 255 are "transparent" which really means that we
	 * fill with the background color.
	 */

	CGFloat rgba[4], gray;
	GetBackgroundColorRGBA(context, tkwin, 0, NO, rgba);
	gray = (rgba[0] + rgba[1] + rgba[2]) / 3.0;
	faceGray.grayscale = gray;
    }
    FillRoundedRectangle(context, CGRectInset(bounds, 1, 1), radius - 1,
			 CGColorFromGray(faceGray));
}

/*----------------------------------------------------------------------
 * DrawAccentedButton --
 *
 *      The accent color is only used when drawing buttons in the active
 *      window.  Push Buttons and segmented Arrow Buttons are drawn in color
 *      when in the pressed state.  Selected Check Buttons, Radio Buttons and
 *      notebook Tabs are also drawn in color.  The color is based on the
 *      user's current choice for the controlAccentColor, but is actually a
 *      linear gradient with a 1-pixel darker line at the top and otherwise
 *      changing from lighter at the top to darker at the bottom.  This
 *      function draws a colored rounded rectangular button.
 */

static void DrawAccentedButton(
    CGContextRef context,
    CGRect bounds,
    const ButtonDesign *design,
    int state,
    int isDark)
{
    NSColorSpace *sRGB = [NSColorSpace sRGBColorSpace];
    CGColorRef faceColor = CGCOLOR(controlAccentColor());
    CGFloat radius = design->radius;
    CGPathRef path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    // This gradient should only be used for PushButtons and Tabs, and it needs
    // to be lighter at the top.
    static CGFloat components[12] = {1.0, 1.0, 1.0, 0.05,
				     1.0, 1.0, 1.0, 0.2,
				     1.0, 1.0, 1.0, 0.0};
    CGFloat locations[3] = {0.0, 0.05, 1.0};
    CGGradientRef gradient = CGGradientCreateWithColorComponents(
				 sRGB.CGColorSpace, components, locations, 3);
    CGPoint end;
    if (bounds.size.height > 2*radius) {
	bounds.size.height -= 1;
    }
    end = CGPointMake(bounds.origin.x, bounds.origin.y + bounds.size.height);
    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextClip(context);
    FillRoundedRectangle(context, bounds, radius, faceColor);
    CGContextDrawLinearGradient(context, gradient, bounds.origin, end, 0.0);
    if (state & TTK_STATE_PRESSED &&
	state & TTK_STATE_ALTERNATE) {
	CGColorRef color = isDark ?
	    CGColorFromGray(darkPressedDefaultButton) :
	    CGColorFromGray(pressedDefaultButton);
	FillRoundedRectangle(context, bounds, radius, color);
    }
    CGContextRestoreGState(context);
    CFRelease(path);
    CFRelease(gradient);
}

/*----------------------------------------------------------------------
 * DrawAccentedSegment --
 *
 *      Draw the colored ends of widgets like popup buttons and combo buttons.
 */

static void DrawAccentedSegment(
    CGContextRef context,
    CGRect bounds,
    const ButtonDesign *design,
    Ttk_State state,
    Tk_Window tkwin)
{
    /*
     * Clip to the bounds and then draw an accented button which is extended so
     * that the rounded corners on the left will be clipped off.  This assumes
     * that the bounds include room for the focus ring.
     */
    int isDark = TkMacOSXInDarkMode(tkwin);
    GrayColor sepGray = isDark ? darkComboSeparator : lightComboSeparator;
    CGColorRef sepColor = CGColorFromGray(sepGray);
    CGRect clip = bounds;
    clip.size.height += 10;
    bounds.origin.x -= 10;
    bounds.size.width += 10;
    CGPoint separator[2] = {
	CGPointMake(clip.origin.x - 1, bounds.origin.y + 5),
	CGPointMake(clip.origin.x - 1,
		    bounds.origin.y + bounds.size.height - 3)};
    CGContextSaveGState(context);
    CGContextSetStrokeColorWithColor(context, sepColor);
    CGContextSetShouldAntialias(context, false);
    CGContextSetLineWidth(context, 0.5);
    CGContextAddLines(context, separator, 2);
    CGContextStrokePath(context);
    CGContextSetShouldAntialias(context, true);
    if (state & TTK_STATE_FOCUS) {
	CGRect focusClip = clip;
	clip.size.width += 4;
	CGContextClipToRect(context, focusClip);
	bounds = CGRectInset(bounds, 0, 1);
	DrawFocusRing(context, bounds, design);
    }
    bounds = CGRectInset(bounds, 4, 4);
    if (state & TTK_STATE_BACKGROUND) {
	bounds.size.height += 2;
    } else {
	bounds.size.height += 1;
    }
    CGContextClipToRect(context, clip);
    if ((state & TTK_STATE_BACKGROUND) || (state & TTK_STATE_DISABLED)) {
	DrawGrayButton(context, bounds, design, state, tkwin);
    } else {
	DrawAccentedButton(context, bounds, design, state | TTK_STATE_ALTERNATE,
			   isDark);
    }
    CGContextRestoreGState(context);
}

/*----------------------------------------------------------------------
 * +++ Entry boxes
 */

static void DrawEntry(
    CGContextRef context,
    CGRect bounds,
    const ButtonDesign *design,
    int state,
    Tk_Window tkwin)
{
    int isDark = TkMacOSXInDarkMode(tkwin);
    GrayPalette palette = LookupGrayPalette(design, state, isDark);
    CGColorRef backgroundColor;
    CGFloat bgRGBA[4];
    if (isDark) {
    	GetBackgroundColorRGBA(context, tkwin, 0, NO, bgRGBA);

	/*
	 * Lighten the entry background to provide contrast.
	 */

	for (int i = 0; i < 3; i++) {
		bgRGBA[i] += 8.0 / 255.0;
	    }
	backgroundColor = CGColorFromRGBA(bgRGBA);
    } else {
	backgroundColor = CG_WHITE;
    }
    if (state & TTK_STATE_FOCUS) {
	DrawFocusRing(context, bounds, design);
    } else {
	FillBorder(context, CGRectInset(bounds,3,3), palette, design->radius);
    }
    bounds = CGRectInset(bounds, 4, 4);
    FillRoundedRectangle(context, bounds, design->radius, backgroundColor);
}

/*----------------------------------------------------------------------
 * +++ Chevrons, CheckMarks, etc. --



 */

static void DrawDownArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    int state)
{
    CGColorRef strokeColor;
    CGFloat x, y;


    if (state & TTK_STATE_DISABLED) {
	strokeColor = CGCOLOR([NSColor disabledControlTextColor]);
    } else if (state & TTK_STATE_IS_ACCENTED) {
	strokeColor = CG_WHITE;
    } else {
	strokeColor = CGCOLOR([NSColor controlTextColor]);
    }
    CGContextSetStrokeColorWithColor(context, strokeColor);
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2) + 1;
    CGContextBeginPath(context);
    CGPoint arrow[3] = {
	{x, y - size / 4}, {x + size / 2, y + size / 4},
	{x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

/*----------------------------------------------------------------------
 * DrawUpArrow --
 *
 * Draws a single upward pointing arrow for ListHeaders and Disclosure Buttons.
 */

static void DrawUpArrow(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    int state)
{
    NSColor *strokeColor;
    CGFloat x, y;

    if (state & TTK_STATE_DISABLED) {
	strokeColor = [NSColor disabledControlTextColor];
    } else {
	strokeColor = [NSColor controlTextColor];
    }
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    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);
}

/*----------------------------------------------------------------------
 * DrawUpDownArrows --
 *
 * Draws the double arrows used in menu buttons and spin buttons.
 */

static void DrawUpDownArrows(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat gap,
    int state,
    ThemeDrawState drawState)
{
    CGFloat x, y;
    NSColor *topStrokeColor, *bottomStrokeColor;
    if (drawState == BOTH_ARROWS && !(state & TTK_STATE_BACKGROUND)) {
	topStrokeColor = bottomStrokeColor = [NSColor whiteColor];
    } else if (drawState == kThemeStatePressedDown) {
	topStrokeColor = [NSColor controlTextColor];
	bottomStrokeColor = [NSColor whiteColor];
    } else if (drawState == kThemeStatePressedUp) {
	topStrokeColor = [NSColor whiteColor];
	bottomStrokeColor = [NSColor controlTextColor];
    } else if (state & TTK_STATE_DISABLED) {
	topStrokeColor = bottomStrokeColor = [NSColor disabledControlTextColor];
    } else {
	topStrokeColor = bottomStrokeColor = [NSColor controlTextColor];
    }
    CGContextSetLineWidth(context, 1.5);
    x = bounds.origin.x + inset;
    y = bounds.origin.y + trunc(bounds.size.height / 2);
    CGContextBeginPath(context);
    CGPoint bottomArrow[3] =
	{{x, y + gap}, {x + size / 2, y + gap + size / 2}, {x + size, y + gap}};
    CGContextAddLines(context, bottomArrow, 3);
    CGContextSetStrokeColorWithColor(context, CGCOLOR(bottomStrokeColor));
    CGContextStrokePath(context);
    CGContextBeginPath(context);
    CGPoint topArrow[3] =
	{{x, y - gap}, {x + size / 2, y - gap - size / 2}, {x + size, y - gap}};
    CGContextAddLines(context, topArrow, 3);
    CGContextSetStrokeColorWithColor(context, CGCOLOR(topStrokeColor));
    CGContextStrokePath(context);
}

/*----------------------------------------------------------------------
 * DrawClosedDisclosure --
 *
 * Draws a disclosure chevron in the Big Sur style, for Treeviews.
 */

static void DrawClosedDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
369
370
371
372
373
374
375






376
377
378
379
380
381
382
    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)







>
>
>
>
>
>







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
    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);
}

/*----------------------------------------------------------------------
 * DrawOpenDisclosure --
 *
 * Draws an open disclosure chevron in the Big Sur style, for Treeviews.
 */

static void DrawOpenDisclosure(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    CGFloat *rgba)
392
393
394
395
396
397
398



399

400















401




402
403
404
405
406
407
408
409
410
411















412

413





414






415

416








417


418
419


420

421
422

















423



424




425
426

427
428


429


430


431
432

433
434
435
436
437






















438


























439



440







441
442
443
444




445
446
447



448




449


450



451
452

453

454
455
456

457


458



459








460
461
462
463

464





465















466
467

468
469

470


471












472











473
474

475



476
477
478
479
480
481
482
483






484
485
486


487













488


489











































































































































































490
491
492
493
494
495




496
497
498
499
500
501


502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602

603





604


605



606
607
608
609
610

611
612
613
614

615

616
617
618
619
620
621

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	{x, y - size / 4}, {x + size / 2, y + size / 2}, {x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

/*----------------------------------------------------------------------



 * +++ Double Arrow Buttons --

 *















 * Used in MenuButtons and SpinButtons.




 */

static void DrawUpDownArrows(
    CGContextRef context,
    CGRect bounds,
    CGFloat inset,
    CGFloat size,
    const CGFloat *rgba)
{
    CGFloat x, y;

















    CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]);





    CGContextSetLineWidth(context, 1.5);






    x = bounds.origin.x + inset;

    y = bounds.origin.y + trunc(bounds.size.height / 2);








    CGContextBeginPath(context);


    CGPoint bottomArrow[3] =
    {{x, y + 2}, {x + size / 2, y + 2 + size / 2}, {x + size, y + 2}};


    CGContextAddLines(context, bottomArrow, 3);

    CGPoint topArrow[3] =
    {{x, y - 2}, {x + size / 2, y - 2 - size / 2}, {x + size, y - 2}};

















    CGContextAddLines(context, topArrow, 3);



    CGContextStrokePath(context);




}



/*----------------------------------------------------------------------


 * +++ FillButtonBackground --


 *


 *      Fills a rounded rectangle with a transparent black gradient.
 *      This is a no-op if building on 10.8 or older.

 */

static void FillButtonBackground(
    CGContextRef context,
    CGRect bounds,






















    CGFloat radius)


























{



    CHECK_RADIUS(radius, bounds)








    CGPathRef path;
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    CGGradientRef backgroundGradient = CGGradientCreateWithColorComponents(




	deviceRGB.CGColorSpace, darkBackgroundGradient, NULL, 2);
    CGPoint backgroundEnd = {
	bounds.origin.x,



	bounds.origin.y + bounds.size.height




    };


    CGContextBeginPath(context);



    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    CGContextAddPath(context, path);

    CGContextClip(context);

    CGContextDrawLinearGradient(context, backgroundGradient,
	bounds.origin, backgroundEnd, 0);
    CFRelease(path);

    CFRelease(backgroundGradient);


}












/*----------------------------------------------------------------------
 * +++ HighlightButtonBorder --
 *
 * Accent the top border of a rounded rectangle with a transparent

 * white gradient.





 */
















static void HighlightButtonBorder(

    CGContextRef context,
    CGRect bounds)

{


    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];












    CGPoint topEnd = {bounds.origin.x, bounds.origin.y + 3};











    CGGradientRef topGradient = CGGradientCreateWithColorComponents(
	deviceRGB.CGColorSpace, darkTopGradient, NULL, 2);





    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextAddArc(context, bounds.origin.x + 4, bounds.origin.y + 4,
	4, PI, 3 * PI / 2, 0);
    CGContextAddArc(context, bounds.origin.x + bounds.size.width - 4,
	bounds.origin.y + 4, 4, 3 * PI / 2, 0, 0);
    CGContextReplacePathWithStrokedPath(context);
    CGContextClip(context);






    CGContextDrawLinearGradient(context, topGradient, bounds.origin, topEnd,
	0.0);
    CGContextRestoreGState(context);


    CFRelease(topGradient);













}














































































































































































/*----------------------------------------------------------------------
 * DrawGroupBox --
 *
 *      This is a standalone drawing procedure which draws the contrasting
 *      rounded rectangular box for LabelFrames and Notebook panes used in
 *      more recent versions of macOS.




 */

static void DrawGroupBox(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin)


{
    CHECK_RADIUS(4, bounds)

    CGPathRef path;
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *borderColor, *bgColor;
    static CGFloat border[4] = {1.0, 1.0, 1.0, 0.25};
    CGFloat fill[4];

    GetBackgroundColor(context, tkwin, 1, fill);
    bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill
	count: 4];
    CGContextSetFillColorSpace(context, deviceRGB.CGColorSpace);
    CGContextSetFillColorWithColor(context, CGCOLOR(bgColor));
    path = CGPathCreateWithRoundedRect(bounds, 4, 4, NULL);
    CGContextClipToRect(context, bounds);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    borderColor = [NSColor colorWithColorSpace: deviceRGB components: border
	count: 4];
    CGContextSetFillColorWithColor(context, CGCOLOR(borderColor));
    [borderColor getComponents: fill];
    CGContextSetRGBFillColor(context, fill[0], fill[1], fill[2], fill[3]);

    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextReplacePathWithStrokedPath(context);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------
 * SolidFillRoundedRectangle --
 *
 *      Fill a rounded rectangle with a specified solid color.
 */

static void SolidFillRoundedRectangle(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius,
    NSColor *color)
{
    CGPathRef path;

    CHECK_RADIUS(radius, bounds)
    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    if (!path) {
	return;
    }
    CGContextSetFillColorWithColor(context, CGCOLOR(color));
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------
 * +++ DrawListHeader --
 *
 *      This is a standalone drawing procedure which draws column headers for
 *      a Treeview in the Aqua appearance.  The HITheme headers have not
 *      matched the native ones since OSX 10.8.  Note that the header image is
 *      ignored, but we draw arrows according to the state.
 */

static void DrawListHeader(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin,
    int state)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *strokeColor, *bgColor;
    static CGFloat borderRGBA[4] = {
	200.0 / 255, 200.0 / 255, 200.0 / 255, 1.0
    };
    static CGFloat separatorRGBA[4] = {
	220.0 / 255, 220.0 / 255, 220.0 / 255, 1.0
    };
    static CGFloat activeBgRGBA[4] = {
	238.0 / 255, 238.0 / 255, 238.0 / 255, 1.0
    };
    static CGFloat inactiveBgRGBA[4] = {
	246.0 / 255, 246.0 / 255, 246.0 / 255, 1.0
    };

    /*
     * Apple changes the background of a list header when the window is not
     * active.  But Ttk does not indicate that in the state of a TreeHeader.
     * So we have to query the Apple window manager.
     */

    NSWindow *win = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));
    CGFloat *bgRGBA = [win isKeyWindow] ? activeBgRGBA : inactiveBgRGBA;
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}};
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}};







    bgColor = [NSColor colorWithColorSpace: deviceRGB


	components: bgRGBA



	count: 4];
    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    CGContextSetFillColorSpace(context, deviceRGB.CGColorSpace);
    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);

    CGContextBeginPath(context);
    CGContextSetFillColorWithColor(context, CGCOLOR(bgColor));
    CGContextAddRect(context, bounds);
    CGContextFillPath(context);

    strokeColor = [NSColor colorWithColorSpace: deviceRGB

	components: separatorRGBA
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, separator, 2);
    CGContextStrokePath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB

	components: borderRGBA
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, top, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);

    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;
	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, BLACKRGBA);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, BLACKRGBA);
	}
    }
}

/*----------------------------------------------------------------------
 * +++ Drawing procedures for widgets in Apple's "Dark Mode" (10.14 and up).
 *
 *      The HIToolbox does not support Dark Mode, and apparently never will,
 *      so to make widgets look "native" we have to provide analogues of the
 *      HITheme drawing functions to be used in DarkAqua.  We continue to use
 *      HITheme in Aqua, since it understands earlier versions of the OS.
 *
 *      Drawing the dark widgets requires NSColors that were introduced in OSX
 *      10.14, so we make some of these functions be no-ops when building on
 *      systems older than 10.14.
 */

/*----------------------------------------------------------------------
 * GradientFillRoundedRectangle --
 *
 *      Fill a rounded rectangle with a specified gradient.
 */

static void GradientFillRoundedRectangle(
    CGContextRef context,
    CGRect bounds,
    CGFloat radius,
    CGFloat *colors,
    int numColors)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    CGPathRef path;
    CHECK_RADIUS(radius, bounds)

    CGPoint end = {
	bounds.origin.x,
	bounds.origin.y + bounds.size.height
    };
    CGGradientRef gradient = CGGradientCreateWithColorComponents(
	deviceRGB.CGColorSpace, colors, NULL, numColors);

    path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, bounds.origin, end, 0);
    CFRelease(path);
    CFRelease(gradient);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkButton --
 *
 *      This is a standalone drawing procedure which draws PushButtons and
 *      PopupButtons in the Dark Mode style.
 */

static void DrawDarkButton(
    CGRect bounds,
    ThemeButtonKind kind,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor;

    /*
     * To match the appearance of Apple's buttons we need to increase the
     * height by 1 pixel.
     */

    bounds.size.height += 1;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 5);

    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (kind == kThemePushButton && (state & TTK_STATE_PRESSED)) {
	GradientFillRoundedRectangle(context, bounds, 4,
	    pressedPushButtonGradient, 2);
    } else if (kind == kThemePushButton &&
	       (state & TTK_STATE_ALTERNATE) &&
	       !(state & TTK_STATE_BACKGROUND)) {
	GradientFillRoundedRectangle(context, bounds, 4,
	    darkSelectedGradient, 2);
    } else {
	if (state & TTK_STATE_DISABLED) {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkDisabledButtonFace
		count: 4];
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkButtonFace
		count: 4];
	}
	SolidFillRoundedRectangle(context, bounds, 4, faceColor);
    }

    /*
     * If this is a popup, draw the arrow button.
     */

    if ((kind == kThemePopupButton) | (kind == kThemeComboBox)) {
	CGRect arrowBounds = bounds;
	arrowBounds.size.width = 16;
	arrowBounds.origin.x += bounds.size.width - 16;

        /*
         * If the toplevel is front, paint the button blue.
         */

	if (!(state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    GradientFillRoundedRectangle(context, arrowBounds, 4,
		darkSelectedGradient, 2);
	}
	if (kind == kThemePopupButton) {
	    DrawUpDownArrows(context, arrowBounds, 3, 7, WHITERGBA);
	} else {
	    DrawDownArrow(context, arrowBounds, 4, 8, WHITERGBA);
	}
    }

    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkIncDecButton --
 *
 *      This is a standalone drawing procedure which draws an IncDecButton
 *      (as used in a Spinbox) in the Dark Mode style.
 */

static void DrawDarkIncDecButton(
    CGRect bounds,
    ThemeDrawState drawState,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor;

    bounds = CGRectInset(bounds, 0, -1);
    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 6);

    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (state & TTK_STATE_DISABLED) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkDisabledButtonFace
	    count: 4];
    } else {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkButtonFace
	    count: 4];
    }
    SolidFillRoundedRectangle(context, bounds, 4, faceColor);

    /*
     * If pressed, paint the appropriate half blue.
     */

    if (state & TTK_STATE_PRESSED) {
	CGRect clip = bounds;
	clip.size.height /= 2;
	CGContextSaveGState(context);
	if (drawState == kThemeStatePressedDown) {
	    clip.origin.y += clip.size.height;
	}
	CGContextClipToRect(context, clip);
	GradientFillRoundedRectangle(context, bounds, 5,
	    darkSelectedGradient, 2);
	CGContextRestoreGState(context);
    }
    DrawUpDownArrows(context, bounds, 3, 5, WHITERGBA);
    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkBevelButton --
 *
 *      This is a standalone drawing procedure which draws RoundedBevelButtons
 *      in the Dark Mode style.
 */

static void DrawDarkBevelButton(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 5);

    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (state & TTK_STATE_PRESSED) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkPressedBevelFace
	    count: 4];
    } else if ((state & TTK_STATE_DISABLED) ||
	(state & TTK_STATE_ALTERNATE)) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkDisabledButtonFace
	    count: 4];
    } else if (state & TTK_STATE_SELECTED) {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkSelectedBevelFace
	    count: 4];
    } else {
	faceColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkButtonFace
	    count: 4];
    }
    SolidFillRoundedRectangle(context, bounds, 4, faceColor);
    HighlightButtonBorder(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkCheckBox --
 *
 *      This is a standalone drawing procedure which draws Checkboxes in the
 *      Dark Mode style.
 */

static void DrawDarkCheckBox(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    CGRect checkbounds = {{0, bounds.size.height / 2 - 8}, {16, 16}};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;
    CGFloat x, y;

    bounds = CGRectOffset(checkbounds, bounds.origin.x, bounds.origin.y);
    x = bounds.origin.x;
    y = bounds.origin.y;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 4);
    bounds = CGRectInset(bounds, 1, 1);
    if (!(state & TTK_STATE_BACKGROUND) &&
	!(state & TTK_STATE_DISABLED) &&
	((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE))) {
	GradientFillRoundedRectangle(context, bounds, 3,
	    darkSelectedGradient, 2);
    } else {
	GradientFillRoundedRectangle(context, bounds, 3,
	    darkInactiveGradient, 2);
    }
    HighlightButtonBorder(context, bounds);
    if ((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE)) {
	CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
	if (state & TTK_STATE_DISABLED) {
	    stroke = [NSColor disabledControlTextColor];
	} else {
	    stroke = [NSColor controlTextColor];
	}
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
    }
    if (state & TTK_STATE_SELECTED) {
	CGContextSetLineWidth(context, 1.5);
	CGContextBeginPath(context);
	CGPoint check[3] = {{x + 4, y + 8}, {x + 7, y + 11}, {x + 11, y + 4}};
	CGContextAddLines(context, check, 3);
	CGContextStrokePath(context);
    } else if (state & TTK_STATE_ALTERNATE) {
	CGContextSetLineWidth(context, 2.0);
	CGContextBeginPath(context);
	CGPoint bar[2] = {{x + 4, y + 8}, {x + 12, y + 8}};
	CGContextAddLines(context, bar, 2);
	CGContextStrokePath(context);
    }
}

/*----------------------------------------------------------------------
 * +++ DrawDarkRadioButton --
 *
 *    This is a standalone drawing procedure which draws RadioButtons
 *    in the Dark Mode style.
 */

static void DrawDarkRadioButton(

    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    CGRect checkbounds = {{0, bounds.size.height / 2 - 9}, {18, 18}};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *fill;
    CGFloat x, y;

    bounds = CGRectOffset(checkbounds, bounds.origin.x, bounds.origin.y);
    x = bounds.origin.x;
    y = bounds.origin.y;

    CGContextClipToRect(context, bounds);
    FillButtonBackground(context, bounds, 9);
    bounds = CGRectInset(bounds, 1, 1);
    if (!(state & TTK_STATE_BACKGROUND) &&
	!(state & TTK_STATE_DISABLED) &&
	((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE))) {
	GradientFillRoundedRectangle(context, bounds, 8,
	    darkSelectedGradient, 2);
    } else {
	GradientFillRoundedRectangle(context, bounds, 8,
	    darkInactiveGradient, 2);
    }
    HighlightButtonBorder(context, bounds);
    if ((state & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE)) {
	CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
	if (state & TTK_STATE_DISABLED) {
	    fill = [NSColor disabledControlTextColor];
	} else {
	    fill = [NSColor controlTextColor];
	}
	CGContextSetFillColorWithColor(context, CGCOLOR(fill));
    }
    if (state & TTK_STATE_SELECTED) {
	CGContextBeginPath(context);
	CGRect dot = {{x + 6, y + 6}, {6, 6}};
	CGContextAddEllipseInRect(context, dot);
	CGContextFillPath(context);
    } else if (state & TTK_STATE_ALTERNATE) {
	CGRect bar = {{x + 5, y + 8}, {8, 2}};
	CGContextFillRect(context, bar);
    }
}

/*----------------------------------------------------------------------
 * +++ DrawDarkTab --
 *
 *      This is a standalone drawing procedure which draws Tabbed Pane
 *      Tabs in the Dark Mode style.
 */

static void DrawDarkTab(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor, *stroke;
    CGRect originalBounds = bounds;

    CGContextSetLineWidth(context, 1.0);
    CGContextClipToRect(context, bounds);


    /*
     * Extend the bounds to one or both sides so the rounded part will be
     * clipped off.

     */



    if (!(state & TTK_STATE_FIRST_TAB)) {
	bounds.origin.x -= 10;
	bounds.size.width += 10;
    }

    if (!(state & TTK_STATE_LAST_TAB)) {
	bounds.size.width += 10;
    }

    /*
     * Fill the tab face with the appropriate color or gradient.  Use a solid
     * color if the tab is not selected, otherwise use a blue or gray
     * gradient.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (!(state & TTK_STATE_SELECTED)) {
	if (state & TTK_STATE_DISABLED) {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkDisabledButtonFace
		count: 4];
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkButtonFace
		count: 4];
	}
	SolidFillRoundedRectangle(context, bounds, 4, faceColor);

        /*
         * Draw a separator line on the left side of the tab if it
         * not first.
         */

	if (!(state & TTK_STATE_FIRST_TAB)) {
	    CGContextSaveGState(context);
	    CGContextSetShouldAntialias(context, false);
	    stroke = [NSColor colorWithColorSpace: deviceRGB
		components: darkTabSeparator
		count: 4];
	    CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	    CGContextBeginPath(context);
	    CGContextMoveToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + 1);
	    CGContextAddLineToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + originalBounds.size.height - 1);
	    CGContextStrokePath(context);
	    CGContextRestoreGState(context);
	}
    } else {

        /*
         * This is the selected tab; paint it blue.  If it is first, cover up
         * the separator line drawn by the second one.  (The selected tab is
         * always drawn last.)
         */

	if ((state & TTK_STATE_FIRST_TAB) && !(state & TTK_STATE_LAST_TAB)) {
	    bounds.size.width += 1;
	}
	if (!(state & TTK_STATE_BACKGROUND)) {
	    GradientFillRoundedRectangle(context, bounds, 4,
		darkSelectedGradient, 2);
	} else {




	    faceColor = [NSColor colorWithColorSpace: deviceRGB







		components: darkInactiveSelectedTab



		count: 4];





	    SolidFillRoundedRectangle(context, bounds, 4, faceColor);




	}





	HighlightButtonBorder(context, bounds);


    }
}

/*----------------------------------------------------------------------
 * +++ DrawDarkSeparator --
 *
 *      This is a standalone drawing procedure which draws a separator widget
 *      in Dark Mode.
 */

static void DrawDarkSeparator(
    CGRect bounds,
    CGContextRef context,
    TCL_UNUSED(Tk_Window))
{
    static CGFloat fill[4] = {1.0, 1.0, 1.0, 0.3};
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *fillColor = [NSColor colorWithColorSpace: deviceRGB
	components: fill
	count:4];

    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGContextFillRect(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawDarkFocusRing --
 *
 *      This is a standalone drawing procedure which draws a focus ring around
 *      an Entry widget in Dark Mode.
 */

static void DrawDarkFocusRing(
    CGRect bounds,
    CGContextRef context)
{
    CGRect insetBounds = CGRectInset(bounds, -3, -3);
    CHECK_RADIUS(4, insetBounds)

    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *strokeColor;
    NSColor *fillColor = [NSColor colorWithColorSpace:deviceRGB
					   components:darkFocusRing
						count:4];
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h}, {x, y + 1}, {x + w - 1, y + 1}, {x + w - 1, y + h}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};

    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    CGContextBeginPath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingTop
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, topPart, 4);
    CGContextStrokePath(context);
    strokeColor = [NSColor colorWithColorSpace: deviceRGB
				    components: darkFocusRingBottom
					 count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(strokeColor));
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextSetShouldAntialias(context, true);
    CGContextSetFillColorWithColor(context, CGCOLOR(fillColor));
    CGPathRef path = CGPathCreateWithRoundedRect(insetBounds, 4, 4, NULL);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextAddRect(context, bounds);
    CGContextEOFillPath(context);
    CGContextRestoreGState(context);
}
/*----------------------------------------------------------------------
 * +++ DrawDarkFrame --
 *
 *      This is a standalone drawing procedure which draws various
 *      types of borders in Dark Mode.
 */

static void DrawDarkFrame(
    CGRect bounds,
    CGContextRef context,
    HIThemeFrameKind kind)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;

    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;
    CGPoint topPart[4] = {
	{x, y + h - 1}, {x, y + 1}, {x + w, y + 1}, {x + w, y + h - 1}
    };
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint accent[2] = {{x, y + 1}, {x + w, y + 1}};

    switch (kind) {
    case kHIThemeFrameTextFieldSquare:
	CGContextSaveGState(context);
	CGContextSetShouldAntialias(context, false);
	CGContextBeginPath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameTop
	    count: 4];
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	CGContextAddLines(context, topPart, 4);
	CGContextStrokePath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameBottom
	    count: 4];
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	CGContextAddLines(context, bottom, 2);
	CGContextStrokePath(context);
	stroke = [NSColor colorWithColorSpace: deviceRGB
	    components: darkFrameAccent
	    count: 4];
	CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
	CGContextAddLines(context, accent, 2);
	CGContextStrokePath(context);
	CGContextRestoreGState(context);
	break;
    default:
	break;

    }
}

/*----------------------------------------------------------------------
 * +++ DrawListHeader --
 *
 *      This is a standalone drawing procedure which draws column
 *      headers for a Treeview in the Dark Mode.
 */

static void DrawDarkListHeader(
    CGRect bounds,
    CGContextRef context,
    TCL_UNUSED(Tk_Window),
    int state)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *stroke;

    CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGFloat w = bounds.size.width, h = bounds.size.height;

    CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}};
    CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}};
    CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}};
    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);
    stroke = [NSColor colorWithColorSpace: deviceRGB
	components: darkFrameBottom
	count: 4];
    CGContextSetStrokeColorWithColor(context, CGCOLOR(stroke));
    CGContextBeginPath(context);
    CGContextAddLines(context, top, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, separator, 2);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);

    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;

	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, WHITERGBA);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, WHITERGBA);
	}
    }
}

/*----------------------------------------------------------------------
 * +++ Button element: Used for elements drawn with DrawThemeButton.
 */

/*
 * When Ttk draws the various types of buttons, a pointer to one of these
 * is passed as the clientData.
 */

typedef struct {
    ThemeButtonKind kind;
    ThemeMetric heightMetric;
} ThemeButtonParams;
static ThemeButtonParams
    PushButtonParams =  {kThemePushButton, kThemeMetricPushButtonHeight},
    CheckBoxParams =    {kThemeCheckBox, kThemeMetricCheckBoxHeight},
    RadioButtonParams = {kThemeRadioButton, kThemeMetricRadioButtonHeight},
    BevelButtonParams = {kThemeRoundedBevelButton, NoThemeMetric},
    PopupButtonParams = {kThemePopupButton, kThemeMetricPopupButtonHeight},
    DisclosureParams =  {
    kThemeDisclosureButton, kThemeMetricDisclosureTriangleHeight
},
    ListHeaderParams =
{kThemeListHeaderButton, kThemeMetricListHeaderHeight};
static Ttk_StateTable ButtonValueTable[] = {
    {kThemeButtonOff, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeButtonMixed, TTK_STATE_ALTERNATE, 0},
    {kThemeButtonOn, TTK_STATE_SELECTED, 0},
    {kThemeButtonOff, 0, 0}

    /*
     * Others: kThemeDisclosureRight, kThemeDisclosureDown,
     * kThemeDisclosureLeft
     */

};
static Ttk_StateTable ButtonAdornmentTable[] = {
    {kThemeAdornmentNone, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeAdornmentDefault | kThemeAdornmentFocus,
     TTK_STATE_ALTERNATE | TTK_STATE_FOCUS, 0},
    {kThemeAdornmentFocus, TTK_STATE_FOCUS, 0},
    {kThemeAdornmentDefault, TTK_STATE_ALTERNATE, 0},
    {kThemeAdornmentNone, 0, 0}
};

/*----------------------------------------------------------------------
 * +++ computeButtonDrawInfo --
 *
 *      Fill in an appearance manager HIThemeButtonDrawInfo record.
 */

static inline HIThemeButtonDrawInfo computeButtonDrawInfo(
    ThemeButtonParams *params,
    Ttk_State state,
    TCL_UNUSED(Tk_Window))
{

    /*
     * See ButtonElementDraw for the explanation of why we always draw
     * PushButtons in the active state.
     */

    SInt32 HIThemeState;

    HIThemeState = Ttk_StateTableLookup(ThemeStateTable, state);
    switch (params->kind) {
    case kThemePushButton:
	HIThemeState &= ~kThemeStateInactive;
	HIThemeState |= kThemeStateActive;
	break;
    default:
	break;
    }

    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = HIThemeState,
	.kind = params ? params->kind : 0,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };
    return info;

}

/*----------------------------------------------------------------------
 * +++ Button elements.
 */

static void ButtonElementMinSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;

    if (params->heightMetric != NoThemeMetric) {
	ChkErr(GetThemeMetric, params->heightMetric, minHeight);

        /*
         * The theme height does not include the 1-pixel border around
         * the button, although it does include the 1-pixel shadow at
         * the bottom.
         */

	*minHeight += 2;

        /*
         * The minwidth must be 0 to force the generic ttk code to compute the
         * correct text layout.  For example, a non-zero value will cause the
         * text to be left justified, no matter what -anchor setting is used in
         * the style.
         */






	*minWidth = 0;

    }
}

static void ButtonElementSize(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = clientData;
    const HIThemeButtonDrawInfo info =
	computeButtonDrawInfo(params, 0, tkwin);
    static const CGRect scratchBounds = {{0, 0}, {100, 100}};
    CGRect contentBounds, backgroundBounds;
    int verticalPad;

    ButtonElementMinSize(clientData, elementRecord, tkwin,





	minWidth, minHeight, paddingPtr);














    /*
     * Given a hypothetical bounding rectangle for a button, HIToolbox will
     * compute a bounding rectangle for the button contents and a bounding
     * rectangle for the button background.  The background bounds are large
     * enough to contain the image of the button in any state, which might
     * include highlight borders, shadows, etc.  The content rectangle is not
     * centered vertically within the background rectangle, presumably because
     * shadows only appear on the bottom.  Nonetheless, when HITools is asked
     * to draw a button with a certain bounding rectangle it draws the button
     * centered within the rectangle.
     *
     * To compute the effective padding around a button we request the
     * content and bounding rectangles for a 100x100 button and use the
     * padding between those.  However, we symmetrize the padding on the
     * top and bottom, because that is how the button will be drawn.
     */

    ChkErr(HIThemeGetButtonContentBounds,
	&scratchBounds, &info, &contentBounds);
    ChkErr(HIThemeGetButtonBackgroundBounds,
	&scratchBounds, &info, &backgroundBounds);
    paddingPtr->left = contentBounds.origin.x - backgroundBounds.origin.x;
    paddingPtr->right =
	CGRectGetMaxX(backgroundBounds) - CGRectGetMaxX(contentBounds);
    verticalPad = backgroundBounds.size.height - contentBounds.size.height;
    paddingPtr->top = paddingPtr->bottom = verticalPad / 2;




}

static void ButtonElementDraw(
    void *clientData,
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = clientData;
    CGRect bounds = BoxToRect(d, b);
    HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, state, tkwin);





























    bounds = NormalizeButtonBounds(params->heightMetric, bounds);







































    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	switch (info.kind) {
	case kThemePushButton:
	case kThemePopupButton:
	    DrawDarkButton(bounds, info.kind, state, dc.context);
	    break;
	case kThemeCheckBox:
	    DrawDarkCheckBox(bounds, state, dc.context);
	    break;
	case kThemeRadioButton:
	    DrawDarkRadioButton(bounds, state, dc.context);
	    break;
	case kThemeRoundedBevelButton:
	    DrawDarkBevelButton(bounds, state, dc.context);
	    break;
	default:
	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context,
		HIOrientation, NULL);
	}
    } else if (info.kind == kThemePushButton &&
	       (state & TTK_STATE_PRESSED)) {
	bounds.size.height += 2;
	if ([NSApp macOSVersion] > 100800) {
	    GradientFillRoundedRectangle(dc.context, bounds, 4,
					 pressedPushButtonGradient, 2);
	}
    } else {

        /*
         * Apple's PushButton and PopupButton do not change their fill color
         * when the window is inactive.  However, except in 10.7 (Lion), the
         * color of the arrow button on a PopupButton does change.  For some
         * reason HITheme fills inactive buttons with a transparent color that
         * allows the window background to show through, leading to
         * inconsistent behavior.  We work around this by filling behind an
         * inactive PopupButton with a text background color before asking
         * HIToolbox to draw it. For PushButtons, we simply draw them in the
         * active state.
         */

	if (info.kind == kThemePopupButton &&
	    (state & TTK_STATE_BACKGROUND)) {
	    CGRect innerBounds = CGRectInset(bounds, 1, 1);
	    NSColor *whiteRGBA = [NSColor whiteColor];
	    SolidFillRoundedRectangle(dc.context, innerBounds, 4, whiteRGBA);
	}

        /*
         * A BevelButton with mixed value is drawn borderless, which does make
         * much sense for us.
         */

	if (info.kind == kThemeRoundedBevelButton &&
	    info.value == kThemeButtonMixed) {
	    info.value = kThemeButtonOff;
	    info.state = kThemeStateInactive;
	}



	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec ButtonElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ButtonElementSize,
    ButtonElementDraw
};

/*----------------------------------------------------------------------
 * +++ Notebook elements.
 */

/* Tab position logic, c.f. ttkNotebook.c TabState() */
static Ttk_StateTable TabStyleTable[] = {
    {kThemeTabFrontInactive, TTK_STATE_SELECTED | TTK_STATE_BACKGROUND, 0},
    {kThemeTabNonFrontInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeTabFrontUnavailable, TTK_STATE_DISABLED | TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeTabFront, TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontPressed, TTK_STATE_PRESSED, 0},
    {kThemeTabNonFront, 0, 0}
};
static Ttk_StateTable TabAdornmentTable[] = {
    {kHIThemeTabAdornmentNone, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabAdornmentNone, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, 0, 0},
};
static Ttk_StateTable TabPositionTable[] = {
    {kHIThemeTabPositionOnly, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionFirst, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabPositionLast, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionMiddle, 0, 0},
};

/*







>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>


|


<
|
|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
|
>
>
|
<
>
>
|
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>


>
|

>
>
|
>
>

>
>
|
<
>


|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
|
<
|
|
>
>
>
>
|
|
<
>
>
>
|
>
>
>
>
|
>
>
|
>
>
>
|
|
>
|
>
|
|
|
>
|
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>

|
|
|
>
|
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
>
|
|
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
>
>
>

|
<
<
<
<
<
|
>
>
>
>
>
>
|
<

>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
|
|
>
>
>
>





|
>
>

|


<
<
|
<

|
|
<
<
|
|




<
<
|
<
<
<






|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
|
|
|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<





>

>
>
>
>
>
|
>
>
|
>
>
>
|


<
<
>
|
|
|
|
>
|
>
|
<
|


|
>
|
<
|











|

|



|

<
<
<
<
<
<
<
<
<
<
<
|
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>


|
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
>



|
>


>
>
|
|
|
|
<
|
|
|
|


|
|


<

<
<
<
<
<
<
<
<
<
|








<
<
|
<
|










|
|
|
|
|





|
<

>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
|
>
>
>
>

>
>
>
>
>
|
>
>




|

|
|







<
<
|
<
<

|




|

|
|


|

|
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
|
<
|
<
<
|
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
>








<
<

|
<















|





>
>
>
>
>
|
>





|





|
|
|




|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>








|


















>
>
>
>




|





|

|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
|
|

|
|
|
|

|
|
|
|
|
>
>
>
|
|
<
















|








|





|







837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923

924
925
926
927
928

929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036

1037
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152





1153
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374


1375

1376
1377
1378


1379
1380
1381
1382
1383
1384


1385



1386
1387
1388
1389
1390
1391
1392
1393


























1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407














1408








1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430


1431
1432
1433
1434
1435
1436
1437
1438
1439

1440
1441
1442
1443
1444
1445

1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465











1466


1467

































1468


1469












1470











































































































































































































1471






















1472
1473
1474
1475
1476





1477



1478















































1479
1480


1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1502
1503
1504

1505









1506
1507
1508
1509
1510
1511
1512
1513
1514


1515

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589


1590


1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605



1606

1607









1608




























1609

1610

1611


1612


1613








1614






1615




















1616
1617

1618






1619
1620







1621



1622























1623






1624



1625




1626
1627

1628











1629





1630




1631









1632





1633





1634




1635

1636









1637







1638
1639
1640
1641
1642
1643
1644
1645
1646
1647


1648
1649

1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829








































1830
1831
1832

1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850

1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
	{x, y - size / 4}, {x + size / 2, y + size / 2}, {x + size, y - size / 4}
    };
    CGContextAddLines(context, arrow, 3);
    CGContextStrokePath(context);
}

/*----------------------------------------------------------------------
 * IndicatorColor --
 *
 * Returns a CGColorRef of the appropriate shade for a check button or
 * radio button in a given state.
 */

static CGColorRef IndicatorColor(
   int state,
   int isDark)
{
    if (state & TTK_STATE_DISABLED) {
	return isDark ?
	    CGColorFromGray(darkDisabledIndicator) :
	    CGColorFromGray(lightDisabledIndicator);
    } else if ((state & TTK_STATE_SELECTED || state & TTK_STATE_ALTERNATE) &&
	       !(state & TTK_STATE_BACKGROUND)) {
	return CG_WHITE;
    } else {
	return CGCOLOR([NSColor controlTextColor]);
    }
}

/*----------------------------------------------------------------------
 * DrawCheckIndicator --
 *
 * Draws the checkmark or horizontal bar in a check box.
 */

static void DrawCheckIndicator(
    CGContextRef context,
    CGRect bounds,

    int state,
    int isDark)
{
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGColorRef strokeColor = IndicatorColor(state, isDark);

    CGContextSetStrokeColorWithColor(context, strokeColor);
    if (state & TTK_STATE_SELECTED) {
	CGContextSetLineWidth(context, 1.5);
	CGContextBeginPath(context);
	CGPoint check[3] = {{x + 3, y + 7}, {x + 6, y + 10}, {x + 10, y + 3}};
	CGContextAddLines(context, check, 3);
	CGContextStrokePath(context);
    } else if (state & TTK_STATE_ALTERNATE) {
	CGContextSetLineWidth(context, 2.0);
	CGContextBeginPath(context);
	CGPoint bar[2] = {{x + 3, y + 7}, {x + 11, y + 7}};
	CGContextAddLines(context, bar, 2);
	CGContextStrokePath(context);
    }
}

/*----------------------------------------------------------------------
 * DrawRadioIndicator --
 *
 * Draws the dot in the middle of a selected radio button.
 */

static void DrawRadioIndicator(
    CGContextRef context,
    CGRect bounds,
    int state,
    int isDark)
{
    CGFloat x = bounds.origin.x, y = bounds.origin.y;
    CGColorRef fillColor = IndicatorColor(state, isDark);

    CGContextSetFillColorWithColor(context, fillColor);
    if (state & TTK_STATE_SELECTED) {
	CGContextBeginPath(context);
	CGRect dot = {{x + 5, y + 5}, {6, 6}};
	CGContextAddEllipseInRect(context, dot);
	CGContextFillPath(context);
    } else if (state & TTK_STATE_ALTERNATE) {
	CGRect bar = {{x + 4, y + 7}, {8, 2}};
	CGContextFillRect(context, bar);
    }
}


static void
DrawHelpSymbol(
    CGContextRef context,
    CGRect bounds,
    int state)

{
    NSFont *font = [NSFont controlContentFontOfSize:15];
    NSColor *foreground = state & TTK_STATE_DISABLED ?
	[NSColor disabledControlTextColor] : [NSColor controlTextColor];
    NSDictionary *attrs = @{
        NSForegroundColorAttributeName : foreground,
        NSFontAttributeName : font
    };
    NSAttributedString *attributedString = [[NSAttributedString alloc]
						      initWithString:@"?"
							  attributes:attrs];
    CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(
	       (CFAttributedStringRef)attributedString);
    CTLineRef line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, 1));
    CGAffineTransform t = CGAffineTransformMake(
			      1.0, 0.0, 0.0, -1.0, 0.0, bounds.size.height);
    CGContextSaveGState(context);
    CGContextSetTextMatrix(context, t);
    CGContextSetTextPosition(context,
			     bounds.origin.x + 6.5,
			     bounds.origin.y + bounds.size.height - 5);
    CTLineDraw(line, context);
    CGContextRestoreGState(context);
    CFRelease(line);
    CFRelease(typesetter);
    [attributedString release];
}



/*----------------------------------------------------------------------
 * +++ Progress bars.
 */

/*----------------------------------------------------------------------
 * DrawProgressBar --
 *
 * Draws a progress bar, with parameters supplied by a HIThemeTrackDrawInfo
 * struct.  Draws a rounded rectangular track overlayed by a colored
 * rounded rectangular indicator.  An indeterminate progress bar is

 * animated.
 */

static void DrawProgressBar(
    CGContextRef context,
    CGRect bounds,
    HIThemeTrackDrawInfo info,
    int state,
    Tk_Window tkwin)
{
    CGRect colorBounds;
    CGFloat rgba[4];
    CGColorRef trackColor, highlightColor, fillColor;
    NSColor *accent;
    CGFloat ratio = (CGFloat) info.value / (CGFloat) (info.max - info.min);

    GetBackgroundColorRGBA(context, tkwin, 0, NO, rgba);

    /*
     * Compute the bounds for the track and indicator.  The track is 6 pixels
     * wide in the center of the widget bounds.
     */

    if (info.attributes & kThemeTrackHorizontal) {
	bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 3);
	colorBounds = bounds;
	if (info.kind == kThemeIndeterminateBar) {
	    CGFloat width = 0.25*bounds.size.width;
	    CGFloat travel = 0.75*bounds.size.width;
	    CGFloat center = bounds.origin.x + (width / 2) + ratio*travel;
	    colorBounds.origin.x = center - width / 2;
	    colorBounds.size.width = width;
	} else {
	    colorBounds.size.width = ratio*bounds.size.width;
	}
	if (colorBounds.size.width > 0 && colorBounds.size.width < 6) {
	    colorBounds.size.width = 6;
	}
    } else {
	bounds = CGRectInset(bounds, bounds.size.width / 2 - 3, 1);
	colorBounds = bounds;
	if (info.kind == kThemeIndeterminateBar) {
	    CGFloat height = 0.25*bounds.size.height;
	    CGFloat travel = 0.75*bounds.size.height;
	    CGFloat center = bounds.origin.y + (height / 2) + ratio*travel;
	    colorBounds.origin.y = center - height / 2;
	    colorBounds.size.height = height;
	} else {
	    colorBounds.size.height = ratio*(bounds.size.height);
	}
	if (colorBounds.size.height > 0 && colorBounds.size.height < 6) {
	    colorBounds.size.height = 6;
	}
	colorBounds.origin.y += bounds.size.height - colorBounds.size.height;
    }

    /*
     * Compute the colors for the track and indicator.
     */

    if (TkMacOSXInDarkMode(tkwin)) {
	for(int i=0; i < 3; i++) {
	    rgba[i] += 30.0 / 255.0;
	}
	trackColor = CGColorFromRGBA(rgba);
	for(int i=0; i < 3; i++) {
	    rgba[i] -= 5.0 / 255.0;
	}

	highlightColor = CGColorFromRGBA(rgba);
	FillRoundedRectangle(context, bounds, 3, trackColor);
    } else {
	for(int i=0; i < 3; i++) {
	    rgba[i] -= 14.0 / 255.0;
	}
	trackColor = CGColorFromRGBA(rgba);
	for(int i=0; i < 3; i++) {

	    rgba[i] += 3.0 / 255.0;
	}
	highlightColor = CGColorFromRGBA(rgba);
	bounds.size.height -= 1;
	bounds = CGRectInset(bounds, 0, -1);
    }
    if (state & TTK_STATE_BACKGROUND) {
	accent = [NSColor colorWithRed:0.72 green:0.72 blue:0.72 alpha:0.72];
    } else {
	accent = controlAccentColor();
    }

    /*
     * Draw the track, with highlighting around the edge.
     */

    FillRoundedRectangle(context, bounds, 3, trackColor);
    bounds = CGRectInset(bounds, 0, 0.5);
    FillRoundedRectangle(context, bounds, 2.5, highlightColor);
    bounds = CGRectInset(bounds, 0.5, 0.5);
    FillRoundedRectangle(context, bounds, 2, trackColor);
    bounds = CGRectInset(bounds, -0.5, -1);

    /*
     * Draw the indicator.  Make it slightly transparent around the
     * edge so the highlightng shows through.
     */

    if (info.kind == kThemeIndeterminateBar &&
	(state & TTK_STATE_SELECTED) == 0) {
	return;
    }

    fillColor = CGCOLOR([accent colorWithAlphaComponent:0.9]);
    FillRoundedRectangle(context, colorBounds, 3, fillColor);
    colorBounds = CGRectInset(colorBounds, 1, 1);
    fillColor = CGCOLOR([accent colorWithAlphaComponent:1.0]);
    FillRoundedRectangle(context, colorBounds, 2.5, fillColor);
}

/*----------------------------------------------------------------------
 * +++ Sliders.
 */

/*----------------------------------------------------------------------
 * DrawSlider --
 *
 * Draws a slider track and round thumb for a Ttk scale widget.  The accent
 * color is used on the left or top part of the track, so the fraction of
 * the track which is colored is equal to (value - from) / (to - from).
 *
 */

static void DrawSlider(
    CGContextRef context,
    CGRect bounds,
    HIThemeTrackDrawInfo info,
    int state,
    Tk_Window tkwin)
{
    CGColorRef trackColor;
    CGRect clipBounds, trackBounds, thumbBounds;
    CGPoint thumbPoint;
    CGFloat position;
    CGColorRef accentColor;
    Bool fromIsSmaller = info.reserved;
    double from = info.min, to = fabs((double) info.max), value = info.value;


    /*
     * info.min, info.max and info.value are integers.  When this is called
     * we will have arranged that min = 0 and max is a large positive integer.
     */

    double fraction = (from < to) ? (value - from) / (to - from) : 0.5;
    int isDark = TkMacOSXInDarkMode(tkwin);

    if (info.attributes & kThemeTrackHorizontal) {
	trackBounds = CGRectInset(bounds, 0, bounds.size.height / 2 - 3);
	trackBounds.size.height = 3;
	position = 8 + fraction * (trackBounds.size.width - 16);
	clipBounds = trackBounds;
	if (fromIsSmaller) {
	    clipBounds.size.width = position;
	} else {
	    clipBounds.origin.x += position;
	    clipBounds.size.width -= position;
	}
	thumbPoint = CGPointMake(trackBounds.origin.x + position,
				 trackBounds.origin.y + 1);
    } else {
	trackBounds = CGRectInset(bounds, bounds.size.width / 2 - 3, 0);
	trackBounds.size.width = 3;
	position = 8 + fraction * (trackBounds.size.height - 16);
	clipBounds = trackBounds;
	if (fromIsSmaller) {
	    clipBounds.size.height = position;
	} else {
	    clipBounds.origin.y += position;
	    clipBounds.size.height -= position;
	}
	thumbPoint = CGPointMake(trackBounds.origin.x + 1,

				 trackBounds.origin.y + position);
    }
    trackColor = isDark ? CGColorFromGray(darkTrack):
	CGColorFromGray(lightTrack);
    thumbBounds = CGRectMake(thumbPoint.x - 8, thumbPoint.y - 8, 17, 17);
    CGContextSaveGState(context);
    FillRoundedRectangle(context, trackBounds, 1.5, trackColor);





    CGContextClipToRect(context, clipBounds);
    if (state & (TTK_STATE_BACKGROUND | TTK_STATE_DISABLED)) {
	accentColor = isDark ? CGColorFromGray(darkInactiveTrack) :
	    CGColorFromGray(lightInactiveTrack);
    } else {
	accentColor = CGCOLOR(controlAccentColor());
    }
    FillRoundedRectangle(context, trackBounds, 1.5, accentColor);

    CGContextRestoreGState(context);
    DrawGrayButton(context, thumbBounds, &sliderDesign, state, tkwin);
}

/*----------------------------------------------------------------------
 * +++ Drawing procedures for native widgets.
 *
 *      The HIToolbox does not support Dark Mode, and apparently never will.
 *      It also draws some widgets in discontinued older styles even when used
 *      on new OS releases.  So to make widgets look "native" we have to provide
 *      analogues of the HIToolbox drawing functions to be used on newer systems.
 *      We continue to use NIToolbox for older versions of the OS.
 *
 *      Drawing the dark widgets requires NSColors that were introduced in OSX
 *      10.14, so we make some of these functions be no-ops when building on
 *      systems older than 10.14.
 */

/*----------------------------------------------------------------------
 * DrawButton --
 *
 * This is a standalone drawing procedure which draws most types of macOS
 * buttons for newer OS releases.  The button style is specified in the
 * "kind" field of a HIThemeButtonDrawInfo struct, although some of the
 * identifiers are not recognized by HIToolbox.
 */

static void DrawButton(
    CGRect bounds,
    HIThemeButtonDrawInfo info,
    Ttk_State state,
    CGContextRef context,
    Tk_Window tkwin)
{
    ThemeButtonKind kind = info.kind;
    ThemeDrawState drawState = info.state;
    CGRect arrowBounds = bounds = CGRectInset(bounds, 1, 1);
    int hasIndicator, isDark = TkMacOSXInDarkMode(tkwin);

    switch (kind) {
    case TkRoundedRectButton:
	DrawGrayButton(context, bounds, &roundedrectDesign, state, tkwin);
	break;
    case TkInlineButton:
	DrawGrayButton(context, bounds, &inlineDesign, state, tkwin);
	break;
    case TkRecessedButton:
	DrawGrayButton(context, bounds, &recessedDesign, state, tkwin);
	break;
    case TkSidebarButton:
	DrawGrayButton(context, bounds, &sidebarDesign, state, tkwin);
	break;
    case kThemeRoundedBevelButton:
	DrawGrayButton(context, bounds, &bevelDesign, state, tkwin);
	break;
    case kThemePushButton:

	/*
	 * The TTK_STATE_ALTERNATE bit means -default active.  Apple only
	 * indicates the default state (which means that the key equivalent is
	 * "\n") for Push Buttons.
	 */

	if ((state & TTK_STATE_PRESSED || state & TTK_STATE_ALTERNATE) &&
	    !(state & TTK_STATE_BACKGROUND)) {
	    DrawAccentedButton(context, bounds, &pushbuttonDesign, state, isDark);
	} else {
	    DrawGrayButton(context, bounds, &pushbuttonDesign, state, tkwin);
	}
	break;
    case kThemeRoundButtonHelp:
	DrawGrayButton(context, bounds, &helpDesign, state, tkwin);
	DrawHelpSymbol(context, bounds, state);
	break;
    case kThemePopupButton:
	drawState = 0;
	DrawGrayButton(context, bounds, &popupDesign, state, tkwin);
	arrowBounds.size.width = 17;
	arrowBounds.origin.x += bounds.size.width - 17;
	if (!(state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    CGRect popupBounds = arrowBounds;

	    /*
	     * Allow room for nonexistent focus ring.
	     */

	    popupBounds.size.width += 4;
	    popupBounds.origin.y -= 4;
	    popupBounds.size.height += 8;
	    DrawAccentedSegment(context, popupBounds, &popupDesign, state, tkwin);
	    drawState = BOTH_ARROWS;
	}
	arrowBounds.origin.x += 2;
	DrawUpDownArrows(context, arrowBounds, 3, 7, 2, state, drawState);
	break;
    case kThemeComboBox:
	if (state & TTK_STATE_DISABLED) {
	    // Need to add the disabled case to entryDesign.
	    DrawEntry(context, bounds, &entryDesign, state, tkwin);
	} else {
	    DrawEntry(context, bounds, &entryDesign, state, tkwin);
	}
	arrowBounds.size.width = 17;
	if (state & TTK_STATE_BACKGROUND) {
	    arrowBounds.origin.x += bounds.size.width - 20;
	    arrowBounds.size.width += 4;
	    arrowBounds.origin.y -= 1;
	} else {
	    arrowBounds.origin.y -= 1;
	    arrowBounds.origin.x += bounds.size.width - 20;
	    arrowBounds.size.width += 4;
	    arrowBounds.size.height += 2;
	}
	DrawAccentedSegment(context, arrowBounds, &comboDesign, state, tkwin);
	if (!(state & TTK_STATE_BACKGROUND)) {
	    state |= TTK_STATE_IS_ACCENTED;
	}
	DrawDownArrow(context, arrowBounds, 6, 6, state);
	break;
    case kThemeCheckBox:
	bounds = CGRectOffset(CGRectMake(0, bounds.size.height / 2 - 8, 16, 16),
			      bounds.origin.x, bounds.origin.y);
	bounds = CGRectInset(bounds, 1, 1);
	hasIndicator = state & TTK_STATE_SELECTED || state & TTK_STATE_ALTERNATE;
	if (hasIndicator &&
	    !(state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    DrawAccentedButton(context, bounds, &checkDesign, 0, isDark);
	} else {
	    DrawGrayButton(context, bounds, &checkDesign, state, tkwin);
	}
	if (hasIndicator) {
	    DrawCheckIndicator(context, bounds, state, isDark);
	}
	break;
    case kThemeRadioButton:
	bounds = CGRectOffset(CGRectMake(0, bounds.size.height / 2 - 9, 18, 18),
					 bounds.origin.x, bounds.origin.y);
	bounds = CGRectInset(bounds, 1, 1);
	hasIndicator = state & TTK_STATE_SELECTED || state & TTK_STATE_ALTERNATE;
	if (hasIndicator &&
	    !(state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    DrawAccentedButton(context, bounds, &radioDesign, 0, isDark);
	} else {
	    DrawGrayButton(context, bounds, &radioDesign, state, tkwin);
	}
	if (hasIndicator) {
	    DrawRadioIndicator(context, bounds, state, isDark);
	}
	break;
    case kThemeArrowButton:
	DrawGrayButton(context, bounds, &pushbuttonDesign, state, tkwin);
	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 17;
	arrowBounds.size.width = 16;
	arrowBounds.origin.y -= 1;
	if (state & TTK_STATE_SELECTED) {
	    DrawUpArrow(context, arrowBounds, 5, 6, state);
	} else {
	    DrawDownArrow(context, arrowBounds, 5, 6, state);
	}
	break;
    case kThemeIncDecButton:
	DrawGrayButton(context, bounds, &incdecDesign, state, tkwin);
	if (state & TTK_STATE_PRESSED) {
	    CGRect clip;
	    if (drawState == kThemeStatePressedDown) {
		clip = bounds;
		clip.size.height /= 2;
		clip.origin.y += clip.size.height;
		bounds.size.height += 1;
		clip.size.height += 1;
	    } else {
		clip = bounds;
		clip.size.height /= 2;
	    }
	    CGContextSaveGState(context);
	    CGContextClipToRect(context, clip);
	    DrawAccentedButton(context, bounds, &incdecDesign, 0, isDark);
	    CGContextRestoreGState(context);
	}
	{
	    CGFloat inset = (bounds.size.width - 5) / 2;
	    DrawUpDownArrows(context, bounds, inset, 5, 3, state, drawState);
	}
	break;
    default:
	break;
    }
}

/*----------------------------------------------------------------------
 * DrawGroupBox --
 *
 * This is a standalone drawing procedure which draws the contrasting rounded
 * rectangular box for LabelFrames and Notebook panes used in more recent
 * versions of macOS.  Normally the contrast is set to one, since the nesting
 * level of the Group Box is higher by 1 compared to its container.  But we
 * allow higher contrast for special cases, notably notebook tabs in macOS 11.
 * The save parameter is passed to GetBackgroundColor and should probably be
 * NO in such special cases.
 */

static void DrawGroupBox(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin,
    int contrast,
    Bool save)
{
    CHECK_RADIUS(5, bounds)

    CGPathRef path;


    CGColorRef backgroundColor, borderColor;


    backgroundColor = GetBackgroundCGColor(context, tkwin, contrast, save);
    borderColor = CGColorFromGray(boxBorder);


    CGContextSetFillColorWithColor(context, backgroundColor);
    path = CGPathCreateWithRoundedRect(bounds, 5, 5, NULL);
    CGContextClipToRect(context, bounds);
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextFillPath(context);


    CGContextSetFillColorWithColor(context, borderColor);



    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextReplacePathWithStrokedPath(context);
    CGContextFillPath(context);
    CFRelease(path);
}

/*----------------------------------------------------------------------


























 * DrawListHeader --
 *
 * This is a standalone drawing procedure which draws column headers for a
 * Treeview in the Aqua appearance.  (The HIToolbox headers have not matched the
 * native ones since OSX 10.8)  Note that the header image is ignored, but we
 * draw arrows according to the state.
 */

static void DrawListHeader(
    CGRect bounds,
    CGContextRef context,
    Tk_Window tkwin,
    int state)
{














    int isDark = TkMacOSXInDarkMode(tkwin);








    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}};
    CGColorRef strokeColor, backgroundColor;

    /*
     * Apple changes the background color of a list header when the window is
     * not active.  But Ttk does not indicate that in the state of a
     * TreeHeader.  So we have to query the Apple window manager.
     */

    NSWindow *win = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin));
    if (!isDark) {
	GrayColor bgGray = [win isKeyWindow] ?
	    listheaderActiveBG : listheaderInactiveBG;
	backgroundColor = CGColorFromGray(bgGray);
    }

    CGContextSaveGState(context);
    CGContextSetShouldAntialias(context, false);


    if (!isDark) {
	CGContextBeginPath(context);
	CGContextSetFillColorWithColor(context, backgroundColor);
	CGContextAddRect(context, bounds);
	CGContextFillPath(context);
    }
    strokeColor = isDark ?
	CGColorFromGray(darkListheaderBorder) :
	CGColorFromGray(listheaderSeparator);

    CGContextSetStrokeColorWithColor(context, strokeColor);
    CGContextAddLines(context, separator, 2);
    CGContextStrokePath(context);
    strokeColor = isDark ?
	CGColorFromGray(darkListheaderBorder) :
	CGColorFromGray(lightListheaderBorder);

    CGContextSetStrokeColorWithColor(context, strokeColor);
    CGContextAddLines(context, top, 2);
    CGContextStrokePath(context);
    CGContextAddLines(context, bottom, 2);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);

    if (state & TTK_TREEVIEW_STATE_SORTARROW) {
	CGRect arrowBounds = bounds;
	arrowBounds.origin.x = bounds.origin.x + bounds.size.width - 16;
	arrowBounds.size.width = 16;
	if (state & TTK_STATE_ALTERNATE) {
	    DrawUpArrow(context, arrowBounds, 3, 8, state);
	} else if (state & TTK_STATE_SELECTED) {
	    DrawDownArrow(context, arrowBounds, 3, 8, state);
	}
    }
}

/*----------------------------------------------------------------------











 * DrawTab --


 *

































 * This is a standalone drawing procedure which draws Tabbed Pane Tabs for the


 * notebook widget.












 */


































































































































































































































static void
DrawTab(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context,





    Tk_Window tkwin)



{















































    CGRect originalBounds = bounds;
    CGColorRef strokeColor;


    int OSVersion = [NSApp macOSVersion];

    /*
     * Extend the bounds to one or both sides so the rounded part will be
     * clipped off if the right of the left tab, the left of the right tab,
     * and both sides of the middle tabs.
     */

    CGContextClipToRect(context, bounds);
    if (OSVersion < 110000 || !(state & TTK_STATE_SELECTED)) {
	if (!(state & TTK_STATE_FIRST_TAB)) {
	    bounds.origin.x -= 10;
	    bounds.size.width += 10;
	}

	if (!(state & TTK_STATE_LAST_TAB)) {
	    bounds.size.width += 10;
	}
    }
    /*
     * Fill the tab face with the appropriate color or gradient.  Use a solid
     * color if the tab is not selected, otherwise use the accent color with
     * highlights
     */


    if (!(state & TTK_STATE_SELECTED)) {









	DrawGrayButton(context, bounds, &tabDesign, state, tkwin);

        /*
         * Draw a separator line on the left side of the tab if it
         * not first.
         */

	if (!(state & TTK_STATE_FIRST_TAB)) {
	    CGContextSaveGState(context);


	    strokeColor = CGColorFromGray(darkTabSeparator);

	    CGContextSetStrokeColorWithColor(context, strokeColor);
	    CGContextBeginPath(context);
	    CGContextMoveToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + 1);
	    CGContextAddLineToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + originalBounds.size.height - 1);
	    CGContextStrokePath(context);
	    CGContextRestoreGState(context);
	}
    } else {

	/*
	 * This is the selected tab; paint it with the current accent color.
	 * If it is first, cover up the separator line drawn by the second one.
	 * (The selected tab is always drawn last.)
	 */

	if ((state & TTK_STATE_FIRST_TAB) && !(state & TTK_STATE_LAST_TAB)) {
	    bounds.size.width += 1;
	}
	if (!(state & TTK_STATE_BACKGROUND)) {
	    DrawAccentedButton(context, bounds, &tabDesign, 0, 0);

	} else {
	    DrawGrayButton(context, bounds, &tabDesign, state, tkwin);
	}
    }
}

static void
DrawTab11(
    CGRect bounds,
    Ttk_State state,
    CGContextRef context,
    Tk_Window tkwin)
{

    if (state & TTK_STATE_SELECTED) {
	DrawGrayButton(context, bounds, &pushbuttonDesign, state, tkwin);
    } else {
	CGRect clipRect = bounds;
	/*
	 * Draw a segment of a Group Box as a background for non-selected tabs.
	 * Clip the Group Box so that the segments fit together to form a long
	 * rounded rectangle behind the entire tab bar.
	 */

	if (!(state & TTK_STATE_FIRST_TAB)) {
	    clipRect.origin.x -= 5;
	    bounds.origin.x -= 5;
	    bounds.size.width += 5;
	}
	if (!(state & TTK_STATE_LAST_TAB)) {
	    clipRect.size.width += 5;
	    bounds.size.width += 5;
	}
	CGContextSaveGState(context);
	CGContextClipToRect(context, clipRect);
	DrawGroupBox(bounds, context, tkwin, 3, NO);
	CGContextRestoreGState(context);
    }
}

/*----------------------------------------------------------------------
 * DrawDarkSeparator --
 *
 * This is a standalone drawing procedure which draws a separator widget
 * in Dark Mode.  HIToolbox is used in light mode.
 */

static void DrawDarkSeparator(
    CGRect bounds,
    CGContextRef context,
    TCL_UNUSED(Tk_Window))
{


    CGColorRef sepColor = CGColorFromGray(darkSeparator);



    CGContextSetFillColorWithColor(context, sepColor);
    CGContextFillRect(context, bounds);
}

/*----------------------------------------------------------------------
 * +++ DrawGradientButton --
 *
 *      This is a standalone drawing procedure which draws a
 *      a Gradient Button.
 */

static void DrawGradientBorder(
    CGRect bounds,
    CGContextRef context,



    Tk_Window tkwin,

    Ttk_State state)









{




























    CGColorRef faceColor, borderColor;

    GrayColor faceGray, borderGray;

    CGRect inside = CGRectInset(bounds, 1, 1);





    if (TkMacOSXInDarkMode(tkwin)) {








	if (state & TTK_STATE_DISABLED) {






	    faceGray = darkGradientDisabled;




















	    borderGray = darkGradientBorderDisabled;
	} else {

	    faceGray = state & TTK_STATE_PRESSED ?






		darkGradientPressed : darkGradientNormal;
	    borderGray = darkGradientBorder;







	}



    } else {























	if (state & TTK_STATE_DISABLED) {






	    faceGray = lightGradientDisabled;



	    borderGray = lightGradientBorderDisabled;




	} else {
	    faceGray = state & TTK_STATE_PRESSED ?

		lightGradientPressed : lightGradientNormal;











	    borderGray = lightGradientBorder;





	}




    }









    faceColor = CGColorFromGray(faceGray);





    borderColor = CGColorFromGray(borderGray);





    CGContextSetFillColorWithColor(context, faceColor);




    CGContextFillRect(context, inside);

    CGContextSetFillColorWithColor(context, borderColor);









    CGContextAddRect(context, bounds);







    CGContextAddRect(context, inside);
    CGContextEOFillPath(context);
}

/*----------------------------------------------------------------------
 * +++ Button elements.
 */

static void ButtonElementMinSize(
    void *clientData,


    int *minWidth,
    int *minHeight)

{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;

    if (params->heightMetric != NoThemeMetric) {
	ChkErr(GetThemeMetric, params->heightMetric, minHeight);

        /*
         * The theme height does not include the 1-pixel border around
         * the button, although it does include the 1-pixel shadow at
         * the bottom.
         */

	*minHeight += 2;

        /*
         * For buttons with labels the minwidth must be 0 to force the
         * correct text layout.  For example, a non-zero value will cause the
         * text to be left justified, no matter what -anchor setting is used in
         * the style.
         */

	if (params->widthMetric != NoThemeMetric) {
	    ChkErr(GetThemeMetric, params->widthMetric, minWidth);
	    *minWidth += 2;
	    *minHeight += 2;
	} else {
	    *minWidth = 0;
	}
    }
}

static void ButtonElementSize(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;
    HIThemeButtonDrawInfo info =
	ComputeButtonDrawInfo(params, 0, tkwin);
    static const CGRect scratchBounds = {{0, 0}, {100, 100}};
    CGRect contentBounds, backgroundBounds;
    int verticalPad;

    ButtonElementMinSize(clientData, minWidth, minHeight);
    switch (info.kind) {
    case TkSidebarButton:
	*paddingPtr = Ttk_MakePadding(30, 10, 30, 10);
	return;
    case TkGradientButton:
	*paddingPtr = Ttk_MakePadding(1, 1, 1, 1);
        /* Fall through. */
    case kThemeArrowButton:
    case kThemeRoundButtonHelp:
        return;
	/* Buttons which are sized like PushButtons but unknown to HITheme. */
    case TkRoundedRectButton:
    case TkRecessedButton:
    case TkInlineButton:
	info.kind = kThemePushButton;
	break;
    default:
        break;
    }

    /*
     * Given a hypothetical bounding rectangle for a button, HIToolbox will
     * compute a bounding rectangle for the button contents and a bounding
     * rectangle for the button background.  The background bounds are large
     * enough to contain the image of the button in any state, which might
     * include highlight borders, shadows, etc.  The content rectangle is not
     * centered vertically within the background rectangle, presumably because
     * shadows only appear on the bottom.  Nonetheless, when HIToolbox is asked
     * to draw a button with a certain bounding rectangle it draws the button
     * centered within the rectangle.
     *
     * To compute the effective padding around a button we request the
     * content and bounding rectangles for a 100x100 button and use the
     * padding between those.  However, we symmetrize the padding on the
     * top and bottom, because that is how the button will be drawn.
     */

    ChkErr(HIThemeGetButtonContentBounds,
	&scratchBounds, &info, &contentBounds);
    ChkErr(HIThemeGetButtonBackgroundBounds,
	&scratchBounds, &info, &backgroundBounds);
    paddingPtr->left = contentBounds.origin.x - backgroundBounds.origin.x;
    paddingPtr->right =
	CGRectGetMaxX(backgroundBounds) - CGRectGetMaxX(contentBounds);
    verticalPad = backgroundBounds.size.height - contentBounds.size.height;
    paddingPtr->top = paddingPtr->bottom = verticalPad / 2;
    if (info.kind == kThemePopupButton) {
	paddingPtr->top += 1;
	paddingPtr->bottom -= 1;
    }
}

static void ButtonElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;
    CGRect bounds = BoxToRect(d, b);
    HIThemeButtonDrawInfo info = ComputeButtonDrawInfo(params, state, tkwin);
    int isDark = TkMacOSXInDarkMode(tkwin);

    switch (info.kind) {

    /*
     * A Gradient Button should have an image and no text.  The size is set to
     * that of the image.  All we need to do is draw a 1-pixel border.
     */

    case TkGradientButton:
	BEGIN_DRAWING(d)
	    DrawGradientBorder(bounds, dc.context, tkwin, state);
	END_DRAWING
	return;
    /*
     * Buttons with no height restrictions are ready to draw.
     */

    case kThemeArrowButton:
    case kThemeCheckBox:
    case kThemeRadioButton:
    case TkSidebarButton:
    	break;

    /*
     * Other buttons have a maximum height.   We have to deal with that.
     */

    default:
	bounds = NormalizeButtonBounds(params, bounds, isDark);
	break;
    }

    /* We do our own drawing on new systems.*/

    if ([NSApp macOSVersion] > 100800) {
	BEGIN_DRAWING(d)
	DrawButton(bounds, info, state, dc.context, tkwin);
	END_DRAWING
	return;
    }

    /*
     * If execution reaches here it means we should use HIToolbox to draw the
     * button.  Buttons that HIToolbox doesn't know are rendered as
     * PushButtons.
     */

    switch (info.kind) {
    case TkRoundedRectButton:
    case TkRecessedButton:
	info.kind = kThemePushButton;
	break;
    default:
	break;
    }

    /*
     * Apple's PushButton and PopupButton do not change their fill color
     * when the window is inactive.  However, except in 10.7 (Lion), the
     * color of the arrow button on a PopupButton does change.  For some
     * reason HITheme fills inactive buttons with a transparent color that
     * allows the window background to show through, leading to
     * inconsistent behavior.  We work around this by filling behind an
     * inactive PopupButton with a text background color before asking
     * HIToolbox to draw it. For PushButtons, we simply draw them in the
     * active state.
     */

    BEGIN_DRAWING(d)








































    if (info.kind == kThemePopupButton  &&
	(state & TTK_STATE_BACKGROUND)) {
	CGRect innerBounds = CGRectInset(bounds, 1, 1);

	FillRoundedRectangle(dc.context, innerBounds, 4, CG_WHITE);
    }

    /*
     * A BevelButton with mixed value is drawn borderless, which does make
     * much sense for us.
     */

    if (info.kind == kThemeRoundedBevelButton &&
	info.value == kThemeButtonMixed) {
	info.value = kThemeButtonOff;
	info.state = kThemeStateInactive;
    }
    if (info.kind == kThemePushButton) {
	bounds.origin.y -= 2;
    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	   NULL);

    END_DRAWING
}

static Ttk_ElementSpec ButtonElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ButtonElementSize,
    ButtonElementDraw
};

/*----------------------------------------------------------------------
 * +++ Notebook elements.
 */

/* Tab position logic, c.f. ttkNotebook.c TabState() */
static const Ttk_StateTable TabStyleTable[] = {
    {kThemeTabFrontInactive, TTK_STATE_SELECTED | TTK_STATE_BACKGROUND, 0},
    {kThemeTabNonFrontInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeTabFrontUnavailable, TTK_STATE_DISABLED | TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeTabFront, TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontPressed, TTK_STATE_PRESSED, 0},
    {kThemeTabNonFront, 0, 0}
};
static const Ttk_StateTable TabAdornmentTable[] = {
    {kHIThemeTabAdornmentNone, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabAdornmentNone, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, 0, 0},
};
static const Ttk_StateTable TabPositionTable[] = {
    {kHIThemeTabPositionOnly, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionFirst, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabPositionLast, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionMiddle, 0, 0},
};

/*
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
 *
 * <URL: http://developer.apple.com/documentation/userexperience/Conceptual/
 *       AppleHIGuidelines/XHIGControls/XHIGControls.html#//apple_ref/doc/uid/
 *       TP30000359-TPXREF116>
 */

static void TabElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    GetThemeMetric(kThemeMetricLargeTabHeight, (SInt32 *) minHeight);
    *paddingPtr = Ttk_MakePadding(0, 0, 0, 2);

}

static void TabElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);






    HIThemeTabDrawInfo info = {
	.version = 1,
	.style = Ttk_StateTableLookup(TabStyleTable, state),
	.direction = kThemeTabNorth,
	.size = kHIThemeTabSizeNormal,
	.adornment = Ttk_StateTableLookup(TabAdornmentTable, state),
	.kind = kHIThemeTabKindNormal,
	.position = Ttk_StateTableLookup(TabPositionTable, state),
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkTab(bounds, state, dc.context);
    } else {
	ChkErr(HIThemeDrawTab, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TabElementSize,
    TabElementDraw
};

/*
 * Notebook panes:
 */

static void PaneElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(9, 5, 9, 9);
}

static void PaneElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    bounds.origin.y -= kThemeMetricTabFrameOverlap;
    bounds.size.height += kThemeMetricTabFrameOverlap;
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawGroupBox(bounds, dc.context, tkwin);
    } else {
	HIThemeTabPaneDrawInfo info = {
	    .version = 1,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .direction = kThemeTabNorth,
	    .size = kHIThemeTabSizeNormal,
	    .kind = kHIThemeTabKindNormal,







|
|
|
|
|


<
|
<



|
|






>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
<
<
<
<
<



















|
|
|
|
|






|
|











|







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
 *
 * <URL: http://developer.apple.com/documentation/userexperience/Conceptual/
 *       AppleHIGuidelines/XHIGControls/XHIGControls.html#//apple_ref/doc/uid/
 *       TP30000359-TPXREF116>
 */

static void TabElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{

    *paddingPtr = Ttk_MakePadding(0, -2, 0, 1);

}

static void TabElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] >= 110000) {
	DrawTab11(bounds, state, dc.context, tkwin);
    } else if ([NSApp macOSVersion] > 100800) {
	DrawTab(bounds, state, dc.context, tkwin);
    } else {
	HIThemeTabDrawInfo info = {
	    .version = 1,
	    .style = Ttk_StateTableLookup(TabStyleTable, state),
	    .direction = kThemeTabNorth,
	    .size = kHIThemeTabSizeNormal,
	    .adornment = Ttk_StateTableLookup(TabAdornmentTable, state),
	    .kind = kHIThemeTabKindNormal,
	    .position = Ttk_StateTableLookup(TabPositionTable, state),
	};





	ChkErr(HIThemeDrawTab, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TabElementSize,
    TabElementDraw
};

/*
 * Notebook panes:
 */

static void PaneElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(9, 5, 9, 9);
}

static void PaneElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    bounds.origin.y -= kThemeMetricTabFrameOverlap;
    bounds.size.height += kThemeMetricTabFrameOverlap;
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawGroupBox(bounds, dc.context, tkwin, 1, YES);
    } else {
	HIThemeTabPaneDrawInfo info = {
	    .version = 1,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .direction = kThemeTabNorth,
	    .size = kHIThemeTabSizeNormal,
	    .kind = kHIThemeTabKindNormal,
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
/*----------------------------------------------------------------------
 * +++ Labelframe elements --
 *
 * Labelframe borders: Use "primary group box ..."  Quoth
 * DrawThemePrimaryGroup reference: "The primary group box frame is drawn
 * inside the specified rectangle and is a maximum of 2 pixels thick."
 *
 * "Maximum of 2 pixels thick" is apparently a lie; looks more like 4 to me
 * with shading.
 */

static void GroupElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(4);
}

static void GroupElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawGroupBox(bounds, dc.context, tkwin);
    } else {
	const HIThemeGroupBoxDrawInfo info = {
	    .version = 0,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .kind = kHIThemeGroupBoxKindPrimaryOpaque,
	    };
	ChkErr(HIThemeDrawGroupBox, &bounds, &info, dc.context, HIOrientation);







<
<



|
|
|
|
|


|



|
|









|







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
/*----------------------------------------------------------------------
 * +++ Labelframe elements --
 *
 * Labelframe borders: Use "primary group box ..."  Quoth
 * DrawThemePrimaryGroup reference: "The primary group box frame is drawn
 * inside the specified rectangle and is a maximum of 2 pixels thick."
 *


 */

static void GroupElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(0, 0, 0, 0);
}

static void GroupElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawGroupBox(bounds, dc.context, tkwin, 1, YES);
    } else {
	const HIThemeGroupBoxDrawInfo info = {
	    .version = 0,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .kind = kHIThemeGroupBoxKindPrimaryOpaque,
	    };
	ChkErr(HIThemeDrawGroupBox, &bounds, &info, dc.context, HIOrientation);
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
     offsetof(EntryElement, backgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(EntryElement, fieldbackgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void EntryElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(7, 5, 7, 6);
}

static void EntryElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    EntryElement *e = elementRecord;
    Ttk_Box inner = Ttk_PadBox(b, Ttk_UniformPadding(3));


    CGRect bounds = BoxToRect(d, inner);
    NSColor *background;
    Tk_3DBorder backgroundPtr = NULL;
    static const char *defaultBG = ENTRY_DEFAULT_BACKGROUND;

    if (TkMacOSXInDarkMode(tkwin)) {
	BEGIN_DRAWING(d)
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	CGFloat fill[4];
	GetBackgroundColor(dc.context, tkwin, 1, fill);

	/*
	 * Lighten the background to provide contrast.
	 */

	for (int i = 0; i < 3; i++) {
		fill[i] += 9.0 / 255.0;
	    }
	background = [NSColor colorWithColorSpace: deviceRGB
	    components: fill
	    count: 4];
	CGContextSetFillColorWithColor(dc.context, CGCOLOR(background));
	CGContextFillRect(dc.context, bounds);
	if (state & TTK_STATE_FOCUS) {
	    DrawDarkFocusRing(bounds, dc.context);
	} else {
	    DrawDarkFrame(bounds, dc.context, kHIThemeFrameTextFieldSquare);




	}
	END_DRAWING
    } else {
	const HIThemeFrameDrawInfo info = {
	    .version = 0,
	    .kind = kHIThemeFrameTextFieldSquare,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .isFocused = state & TTK_STATE_FOCUS,
	};

        /*
         * Earlier versions of the Aqua theme ignored the -fieldbackground
         * option and used the -background as if it were -fieldbackground.







|
|
|
|
|


|



|






|
|
>
>
|
|



|

<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
|
<
<
|
|
>
>
>
>
|




|







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
     offsetof(EntryElement, backgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(EntryElement, fieldbackgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void EntryElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = entryElementPadding;
}

static void EntryElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    EntryElement *e = (EntryElement *)elementRecord;
    ThemeFrameParams *params = (ThemeFrameParams *)clientData;
    HIThemeFrameKind kind = params ? params->kind :
	kHIThemeFrameTextFieldSquare;
    CGRect bounds = BoxToRect(d, b);
    CGColorRef background;
    Tk_3DBorder backgroundPtr = NULL;
    static const char *defaultBG = ENTRY_DEFAULT_BACKGROUND;

    if ([NSApp macOSVersion] > 100800) {
	BEGIN_DRAWING(d)



	    switch(kind) {



	    case kHIThemeFrameTextFieldRound:







		DrawEntry(dc.context, bounds, &searchDesign, state, tkwin);


		break;
	    case kHIThemeFrameTextFieldSquare:
		DrawEntry(dc.context, bounds, &entryDesign, state, tkwin);
		break;
	    default:
		return;
	    }
	END_DRAWING
    } else {
	const HIThemeFrameDrawInfo info = {
	    .version = 0,
	    .kind = params->kind,
	    .state = Ttk_StateTableLookup(ThemeStateTable, state),
	    .isFocused = state & TTK_STATE_FOCUS,
	};

        /*
         * Earlier versions of the Aqua theme ignored the -fieldbackground
         * option and used the -background as if it were -fieldbackground.
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
		Tk_Get3DBorderFromObj(tkwin, e->fieldbackgroundObj);
	} else if (0 != strcmp(Tcl_GetString(e->backgroundObj), defaultBG)) {
	    backgroundPtr = Tk_Get3DBorderFromObj(tkwin, e->backgroundObj);
	}
	if (backgroundPtr != NULL) {
	    XFillRectangle(Tk_Display(tkwin), d,
		Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
		inner.x, inner.y, inner.width, inner.height);
	}
	BEGIN_DRAWING(d)
	if (backgroundPtr == NULL) {
	    if ([NSApp macOSVersion] > 100800) {
		background = [NSColor textBackgroundColor];
		CGContextSetFillColorWithColor(dc.context, CGCOLOR(background));
	    } else {
		CGContextSetRGBFillColor(dc.context, 1.0, 1.0, 1.0, 1.0);
	    }
	    CGContextFillRect(dc.context, bounds);
	}
	ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);
	END_DRAWING







|




|
|







2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
		Tk_Get3DBorderFromObj(tkwin, e->fieldbackgroundObj);
	} else if (0 != strcmp(Tcl_GetString(e->backgroundObj), defaultBG)) {
	    backgroundPtr = Tk_Get3DBorderFromObj(tkwin, e->backgroundObj);
	}
	if (backgroundPtr != NULL) {
	    XFillRectangle(Tk_Display(tkwin), d,
		Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
		b.x, b.y, b.width, b.height);
	}
	BEGIN_DRAWING(d)
	if (backgroundPtr == NULL) {
	    if ([NSApp macOSVersion] > 100800) {
		background = CGCOLOR([NSColor textBackgroundColor]);
		CGContextSetFillColorWithColor(dc.context, background);
	    } else {
		CGContextSetRGBFillColor(dc.context, 1.0, 1.0, 1.0, 1.0);
	    }
	    CGContextFillRect(dc.context, bounds);
	}
	ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation);
	END_DRAWING
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
 *      rectangle.  Measurement indicates that the arrow button has width 18.
 *
 *      With no help available from HIToolbox, we have to use hard-wired
 *      constants for the padding. We shift the bounding rectangle downward by
 *      1 pixel to account for the fact that the button is not centered.
 */


static Ttk_Padding ComboboxPadding = {4, 2, 20, 2};

static void ComboboxElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    *minWidth = 24;
    *minHeight = 23;
    *paddingPtr = ComboboxPadding;
}

static void ComboboxElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = kThemeComboBox,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };

    BEGIN_DRAWING(d)
    bounds.origin.y += 1;
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds.size.height += 1;
	DrawDarkButton(bounds, info.kind, state, dc.context);
    } else if ([NSApp macOSVersion] > 100800) {
	if ((state & TTK_STATE_BACKGROUND) &&
	    !(state & TTK_STATE_DISABLED)) {
	    NSColor *background = [NSColor textBackgroundColor];
	    CGRect innerBounds = CGRectInset(bounds, 1, 2);
	    SolidFillRoundedRectangle(dc.context, innerBounds, 4, background);
	}



    }
    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
    END_DRAWING
}

static Ttk_ElementSpec ComboboxElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,







>
|


|
|
|





|




|
|















<
<
<
<
|
<
<
<
|
|
|
>
>
>

<







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
 *      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.
 */

// OS dependent ???
static Ttk_Padding ComboboxPadding = {7, 5, 24, 5};

static void ComboboxElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    *minWidth = 24;
    *minHeight = 0;
    *paddingPtr = ComboboxPadding;
}

static void ComboboxElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = kThemeComboBox,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
    };

    BEGIN_DRAWING(d)




    if ([NSApp macOSVersion] > 100800) {



	bounds = CGRectInset(bounds, -1, -1);
	DrawButton(bounds, info, state, dc.context, tkwin);
    } else {
	bounds.origin.y += 1;
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }

    END_DRAWING
}

static Ttk_ElementSpec ComboboxElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
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
 *      pressed draws the IncDecButton in its "pressed up" state.  NOTE: This
 *      means that when the down button is pressed the IncDecButton will be
 *      drawn twice, first in unpressed state by the up arrow and then in
 *      "pressed down" state by the down button.  The drawing must be done in
 *      that order.  So the up button must be listed first in the layout.
 */

static Ttk_Padding SpinbuttonMargins = {0, 0, 2, 0};

static void SpinButtonUpElementSize(















    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s);
    *minWidth = s + Ttk_PaddingWidth(SpinbuttonMargins);
    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s);
    *minHeight = (s + Ttk_PaddingHeight(SpinbuttonMargins)) / 2;
}

static void SpinButtonUpElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState;


    bounds.size.height *= 2;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedUp;
    } else {
	infoState = Ttk_StateTableLookup(ThemeStateTable, state);
    }
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = infoState,
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };
    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkIncDecButton(bounds, infoState, state, dc.context);
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec SpinButtonUpElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonUpElementSize,
    SpinButtonUpElementDraw
};
static void SpinButtonDownElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s);
    *minWidth = s + Ttk_PaddingWidth(SpinbuttonMargins);
    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s);
    *minHeight = (s + Ttk_PaddingHeight(SpinbuttonMargins)) / 2;
}

static void SpinButtonDownElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState = 0;


    bounds.origin.y -= bounds.size.height;
    bounds.size.height *= 2;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedDown;
    } else {
	return;
    }
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = infoState,
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	DrawDarkIncDecButton(bounds, infoState, state, dc.context);
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec SpinButtonDownElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonDownElementSize,
    SpinButtonDownElementDraw
};

/*----------------------------------------------------------------------
 * +++ DrawThemeTrack-based elements --
 *
 *    Progress bars and scales. (See also: <<NOTE-TRACKS>>)
 */

/*
 * Apple does not change the appearance of a slider when the window becomes
 * inactive.  So we shouldn't either.
 */

static Ttk_StateTable ThemeTrackEnableTable[] = {
    {kThemeTrackDisabled, TTK_STATE_DISABLED, 0},
    {kThemeTrackActive, TTK_STATE_BACKGROUND, 0},
    {kThemeTrackActive, 0, 0}
    /* { kThemeTrackNothingToScroll, ?, ? }, */
};

typedef struct {        /* TrackElement client data */







|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|


|






|



|
|








>














|
|











|


<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<

|
|








>

|














|
|











|














|







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
 *      pressed draws the IncDecButton in its "pressed up" state.  NOTE: This
 *      means that when the down button is pressed the IncDecButton will be
 *      drawn twice, first in unpressed state by the up arrow and then in
 *      "pressed down" state by the down button.  The drawing must be done in
 *      that order.  So the up button must be listed first in the layout.
 */

static Ttk_Padding SpinbuttonMargins = {2, 0, 0, 0};

static void SpinButtonReBounds(
    Tk_Window tkwin,
    CGRect *bounds)
{
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds->origin.x -= 2;
	bounds->origin.y += 1;
	bounds->size.height -= 0.5;
    } else {
	bounds->origin.x -= 3;
	bounds->origin.y += 1;
	bounds->size.width += 1;
    }
}

static void SpinButtonElementSize(
    TCL_UNUSED(void *),       /* clientdata */
    TCL_UNUSED(void *),       /* elementRecord */
    TCL_UNUSED(Tk_Window),    /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* PaddingPtr */
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsWidth, &s);
    *minWidth = s + Ttk_PaddingWidth(SpinbuttonMargins);
    ChkErr(GetThemeMetric, kThemeMetricLittleArrowsHeight, &s);
    *minHeight = 2 + (s + Ttk_PaddingHeight(SpinbuttonMargins)) / 2;
}

static void SpinButtonUpElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState;

    SpinButtonReBounds(tkwin, &bounds);
    bounds.size.height *= 2;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedUp;
    } else {
	infoState = Ttk_StateTableLookup(ThemeStateTable, state);
    }
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = infoState,
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawButton(bounds, info, state, dc.context, tkwin);
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec SpinButtonUpElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonElementSize,
    SpinButtonUpElementDraw
};
















static void SpinButtonDownElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState = 0;

    SpinButtonReBounds(tkwin, &bounds);
    bounds.origin.y -= bounds.size.height;
    bounds.size.height += bounds.size.height;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedDown;
    } else {
	return;
    }
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = infoState,
	.kind = kThemeIncDecButton,
	.value = Ttk_StateTableLookup(ButtonValueTable, state),
	.adornment = kThemeAdornmentNone,
    };

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawButton(bounds, info, state, dc.context, tkwin);
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	       NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec SpinButtonDownElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonElementSize,
    SpinButtonDownElementDraw
};

/*----------------------------------------------------------------------
 * +++ DrawThemeTrack-based elements --
 *
 *    Progress bars and scales. (See also: <<NOTE-TRACKS>>)
 */

/*
 * Apple does not change the appearance of a slider when the window becomes
 * inactive.  So we shouldn't either.
 */

static const Ttk_StateTable ThemeTrackEnableTable[] = {
    {kThemeTrackDisabled, TTK_STATE_DISABLED, 0},
    {kThemeTrackActive, TTK_STATE_BACKGROUND, 0},
    {kThemeTrackActive, 0, 0}
    /* { kThemeTrackNothingToScroll, ?, ? }, */
};

typedef struct {        /* TrackElement client data */
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
    {"-to", TK_OPTION_DOUBLE, offsetof(TrackElement, toObj), NULL},
    {"-value", TK_OPTION_DOUBLE, offsetof(TrackElement, valueObj), NULL},
    {"-orient", TK_OPTION_STRING, offsetof(TrackElement, orientObj), NULL},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TrackElementSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    TrackElementData *data = (TrackElementData *)clientData;
    SInt32 size = 24;   /* reasonable default ... */

    ChkErr(GetThemeMetric, data->thicknessMetric, &size);
    *minWidth = *minHeight = size;
}

static void TrackElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    TrackElementData *data = clientData;
    TrackElement *elem = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    double from = 0, to = 100, value = 0, factor;
    CGRect bounds;

    TtkGetOrientFromObj(NULL, elem->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, elem->fromObj, &from);
    Tcl_GetDoubleFromObj(NULL, elem->toObj, &to);
    Tcl_GetDoubleFromObj(NULL, elem->valueObj, &value);
    factor = RangeToFactor(to);

    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
     * bounds variable avoids UBSan (-fsanitize=alignment) complaints.
     */

    bounds = BoxToRect(d, b);
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind = data->kind,
	.bounds = bounds,
	.min = from * factor,
	.max = to * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = 0,
    };

    if (info.kind == kThemeSlider) {
	info.trackInfo.slider.pressState = state & TTK_STATE_PRESSED ?
	    kThemeThumbPressed : 0;
	if (state & TTK_STATE_ALTERNATE) {
	    info.trackInfo.slider.thumbDir = kThemeThumbDownward;
	} else {
	    info.trackInfo.slider.thumbDir = kThemeThumbPlain;
	}
    }
    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];

	NSColor *trackColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkTrack
	    count: 4];
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 2);
	} else {
	    bounds = CGRectInset(bounds, bounds.size.width / 2 - 3, 2);

	}

	SolidFillRoundedRectangle(dc.context, bounds, 2, trackColor);
    }
    ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);

    END_DRAWING
}

static Ttk_ElementSpec TrackElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TrackElement),
    TrackElementOptions,







|
|


|
















|
|

|
|

|



<

<
<
<
<
|
|




|
|
|




|












|
|
<
>
|
|
<
<
<
|
<
>
|
>
|
|
|
>







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
    {"-to", TK_OPTION_DOUBLE, offsetof(TrackElement, toObj), NULL},
    {"-value", TK_OPTION_DOUBLE, offsetof(TrackElement, valueObj), NULL},
    {"-orient", TK_OPTION_STRING, offsetof(TrackElement, orientObj), NULL},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TrackElementSize(
    void *clientData,
    TCL_UNUSED(void *),       /* elementRecord */
    TCL_UNUSED(Tk_Window),    /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    TrackElementData *data = (TrackElementData *)clientData;
    SInt32 size = 24;   /* reasonable default ... */

    ChkErr(GetThemeMetric, data->thicknessMetric, &size);
    *minWidth = *minHeight = size;
}

static void TrackElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    TrackElementData *data = (TrackElementData *)clientData;
    TrackElement *elem = (TrackElement *)elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    double from = 0, to = 100, value = 0, fraction, max;
    CGRect bounds = BoxToRect(d, b);

    Ttk_GetOrientFromObj(NULL, elem->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, elem->fromObj, &from);
    Tcl_GetDoubleFromObj(NULL, elem->toObj, &to);
    Tcl_GetDoubleFromObj(NULL, elem->valueObj, &value);






    fraction = (value - from) / (to - from);
    max = RangeToFactor(fabs(to - from));
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind = data->kind,
	.bounds = bounds,
	.min = 0,
	.max = max,
	.value = fraction * max,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = 0
    };

    if (info.kind == kThemeSlider) {
	info.trackInfo.slider.pressState = state & TTK_STATE_PRESSED ?
	    kThemeThumbPressed : 0;
	if (state & TTK_STATE_ALTERNATE) {
	    info.trackInfo.slider.thumbDir = kThemeThumbDownward;
	} else {
	    info.trackInfo.slider.thumbDir = kThemeThumbPlain;
	}
    }
    BEGIN_DRAWING(d)
    if (([NSApp macOSVersion] > 100800) && !(state & TTK_STATE_ALTERNATE)) {


	/*
	 * We use the reserved field to indicate whether "from" is less than
	 * "to".  It should be 0 if passing the info to HIThemeDrawInfo, but



	 * we aren't doing that.

	 */

	info.reserved = (from < to);
	DrawSlider(dc.context, bounds, info, state, tkwin);
    } else {
	ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    }
    END_DRAWING
}

static Ttk_ElementSpec TrackElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TrackElement),
    TrackElementOptions,
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
 * Has geometry only. The Scale widget adjusts the position of this element,
 * and uses it for hit detection. In the Aqua theme, the slider is actually
 * drawn as part of the trough element.
 *
 */

static void SliderElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    *minWidth = *minHeight = 24;
}

static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),







|
|
|


|







2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
 * Has geometry only. The Scale widget adjusts the position of this element,
 * and uses it for hit detection. In the Aqua theme, the slider is actually
 * drawn as part of the trough element.
 *
 */

static void SliderElementSize(
    TCL_UNUSED(void *),        /* clientData */
    TCL_UNUSED(void *),        /* elementRecord */
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    *minWidth = *minHeight = 24;
}

static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
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
    Tcl_Obj *modeObj;           /* progress bar mode */
} PbarElement;

static Ttk_ElementOptionSpec PbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(PbarElement, orientObj), "horizontal"},
    {"-value", TK_OPTION_DOUBLE,
     offsetof(PbarElement, valueObj), "0"},
    {"-maximum", TK_OPTION_DOUBLE,
     offsetof(PbarElement, maximumObj), "100"},
    {"-phase", TK_OPTION_INT,
     offsetof(PbarElement, phaseObj), "0"},
    {"-mode", TK_OPTION_STRING,
     offsetof(PbarElement, modeObj), "determinate"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void PbarElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 size = 24;           /* @@@ Check HIG for correct default */

    ChkErr(GetThemeMetric, kThemeMetricLargeProgressBarThickness, &size);
    *minWidth = *minHeight = size;
}

static void PbarElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    PbarElement *pbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    int phase = 0;
    double value = 0, maximum = 100, factor;
    CGRect bounds;



    TtkGetOrientFromObj(NULL, pbar->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
    Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase);
    factor = RangeToFactor(maximum);


    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
     * bounds variable avoids UBSan (-fsanitize=alignment) complaints.



     */




    bounds = BoxToRect(d, b);
    HIThemeTrackDrawInfo info = {
	.version = 0,
	.kind =
	    (!strcmp("indeterminate",
	    Tcl_GetString(pbar->modeObj)) && value) ?
	    kThemeIndeterminateBar : kThemeProgressBar,
	.bounds = bounds,
	.min = 0,
	.max = maximum * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = phase,
    };

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
	bounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *trackColor = [NSColor colorWithColorSpace: deviceRGB
	    components: darkTrack
	    count: 4];
	if (orientation == TTK_ORIENT_HORIZONTAL) {
	    bounds = CGRectInset(bounds, 1, bounds.size.height / 2 - 3);
	} else {
	    bounds = CGRectInset(bounds, bounds.size.width / 2 - 3, 1);
	}
	SolidFillRoundedRectangle(dc.context, bounds, 3, trackColor);
    }
    ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    END_DRAWING
}

static Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(PbarElement),
    PbarElementOptions,







|

|







|
|
|


|








|






|

|

|
>
>

|



|
>

|
<
|
>
>
>
|

>
>
>
|


<
<
<
|












|
|
<
<
<
<
<
<
|
<
<
|

<







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
    Tcl_Obj *modeObj;           /* progress bar mode */
} PbarElement;

static Ttk_ElementOptionSpec PbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(PbarElement, orientObj), "horizontal"},
    {"-value", TK_OPTION_DOUBLE,
     offsetof(PbarElement, valueObj), "0.0"},
    {"-maximum", TK_OPTION_DOUBLE,
     offsetof(PbarElement, maximumObj), "100.0"},
    {"-phase", TK_OPTION_INT,
     offsetof(PbarElement, phaseObj), "0"},
    {"-mode", TK_OPTION_STRING,
     offsetof(PbarElement, modeObj), "determinate"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void PbarElementSize(
    TCL_UNUSED(void *),        /* clientData */
    TCL_UNUSED(void *),        /* elementRecord */
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    SInt32 size = 24;           /* @@@ Check HIG for correct default */

    ChkErr(GetThemeMetric, kThemeMetricLargeProgressBarThickness, &size);
    *minWidth = *minHeight = size;
}

static void PbarElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    int phase;
    double value = 0, maximum = 100, factor;
    CGRect bounds = BoxToRect(d, b);
    int isIndeterminate = !strcmp("indeterminate",
				  Tcl_GetString(pbar->modeObj));

    Ttk_GetOrientFromObj(NULL, pbar->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
    Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase);

    if (isIndeterminate) {

	/*

	 * When an indeterminate progress bar is animated the phase is
	 * (currently) always 0 and the value increases from min to max
	 * and then decreases back to min.  We scale the value by 3 to
	 * speed the animation up a bit.
	 */

	double remainder = fmod(3*value, 2*maximum);
	value = remainder > maximum ? 2*maximum - remainder : remainder;
    }
    factor = RangeToFactor(maximum);
    HIThemeTrackDrawInfo info = {
	.version = 0,



	.kind = isIndeterminate? kThemeIndeterminateBar : kThemeProgressBar,
	.bounds = bounds,
	.min = 0,
	.max = maximum * factor,
	.value = value * factor,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = phase,
    };

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	DrawProgressBar(dc.context, bounds, info, state, tkwin);






    } else {


	ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
    }

    END_DRAWING
}

static Ttk_ElementSpec PbarElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(PbarElement),
    PbarElementOptions,
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

static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(ScrollbarElement, orientObj), "horizontal"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TroughElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    SInt32 thickness = 15;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    ChkErr(GetThemeMetric, kThemeMetricScrollBarWidth, &thickness);
    if (orientation == TTK_ORIENT_HORIZONTAL) {
	*minHeight = thickness;
	if ([NSApp macOSVersion] > 100700) {
	    *paddingPtr = Ttk_MakePadding(4, 4, 4, 3);
	}
    } else {
	*minWidth = thickness;
	if ([NSApp macOSVersion] > 100700) {
	    *paddingPtr = Ttk_MakePadding(4, 4, 3, 4);
	}
    }
}

static CGFloat lightTrough[4] = {250.0 / 255, 250.0 / 255, 250.0 / 255, 1.0};
static CGFloat darkTrough[4] = {45.0 / 255, 46.0 / 255, 49.0 / 255, 1.0};
static CGFloat lightInactiveThumb[4] = {
    200.0 / 255, 200.0 / 255, 200.0 / 255, 1.0
};
static CGFloat lightActiveThumb[4] = {
    133.0 / 255, 133.0 / 255, 133.0 / 255, 1.0
};
static CGFloat darkInactiveThumb[4] = {
    116.0 / 255, 117.0 / 255, 118.0 / 255, 1.0
};
static CGFloat darkActiveThumb[4] = {
    158.0 / 255, 158.0 / 255, 159.0 / 255, 1.0
};
static void TroughElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    CGRect bounds = BoxToRect(d, b);
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *troughColor;
    CGFloat *rgba = TkMacOSXInDarkMode(tkwin) ? darkTrough : lightTrough;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_HORIZONTAL) {
	bounds = CGRectInset(bounds, 0, 1);
    } else {
	bounds = CGRectInset(bounds, 1, 0);
    }
    troughColor = [NSColor colorWithColorSpace: deviceRGB
	components: rgba
	count: 4];
    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {

	CGContextSetFillColorWithColor(dc.context, CGCOLOR(troughColor));
    } else {
	ChkErr(HIThemeSetFill, kThemeBrushDocumentWindowBackground, NULL,
	    dc.context, HIOrientation);
    }
    CGContextFillRect(dc.context, bounds);
    END_DRAWING
}

static Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TroughElementSize,
    TroughElementDraw
};
static void ThumbElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_VERTICAL) {
	*minHeight = 18;
	*minWidth = 8;
    } else {
	*minHeight = 8;
	*minWidth = 18;
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);

    /*
     * In order to make ttk scrollbars work correctly it is necessary to be
     * able to display the thumb element at the size and location which the ttk
     * scrollbar widget requests.  The algorithm that HIToolbox uses to
     * determine the thumb geometry from the input values of min, max, value
     * and viewSize is undocumented.  A seemingly natural algorithm is
     * implemented below.  This code uses that algorithm for older OS versions,
     * because using HITools also handles drawing the buttons and 3D thumb used
     * on those systems.  For newer systems the cleanest approach is to just
     * draw the thumb directly.
     */

    if ([NSApp macOSVersion] > 100800) {
	CGRect thumbBounds = BoxToRect(d, b);
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *thumbColor;

	CGFloat *rgba;




	if ((orientation == TTK_ORIENT_HORIZONTAL &&
	    thumbBounds.size.width >= Tk_Width(tkwin) - 8) ||
	    (orientation == TTK_ORIENT_VERTICAL &&
	    thumbBounds.size.height >= Tk_Height(tkwin) - 8)) {
	    return;
	}
	int isDark = TkMacOSXInDarkMode(tkwin);
	if ((state & TTK_STATE_PRESSED) ||
	    (state & TTK_STATE_HOVER)) {
	    rgba = isDark ? darkActiveThumb : lightActiveThumb;
	} else {
	    rgba = isDark ? darkInactiveThumb : lightInactiveThumb;
	}
	thumbColor = [NSColor colorWithColorSpace: deviceRGB
	    components: rgba
	    count: 4];
	BEGIN_DRAWING(d)
	SolidFillRoundedRectangle(dc.context, thumbBounds, 4, thumbColor);
	END_DRAWING
    } else {
	double thumbSize, trackSize, visibleSize, factor, fraction;
	MacDrawable *macWin = (MacDrawable *)Tk_WindowId(tkwin);
	CGRect troughBounds = {{macWin->xOff, macWin->yOff},
			       {Tk_Width(tkwin), Tk_Height(tkwin)}};








|

|




|



|














<
<
<
<
<
<
<
<
<
<
<
<
<
<

|




|

|


<
|
<

|





<
<
<


>
|
















|

|


|

|


|










|






|


|








|






<
|
>
|
>
>
>
>









|

|

|
<
<

|







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

static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(ScrollbarElement, orientObj), "horizontal"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TroughElementSize(
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    SInt32 thickness = 15;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    ChkErr(GetThemeMetric, kThemeMetricScrollBarWidth, &thickness);
    if (orientation == TTK_ORIENT_HORIZONTAL) {
	*minHeight = thickness;
	if ([NSApp macOSVersion] > 100700) {
	    *paddingPtr = Ttk_MakePadding(4, 4, 4, 3);
	}
    } else {
	*minWidth = thickness;
	if ([NSApp macOSVersion] > 100700) {
	    *paddingPtr = Ttk_MakePadding(4, 4, 3, 4);
	}
    }
}















static void TroughElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State)) /* state */
{
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    CGRect bounds = BoxToRect(d, b);

    GrayColor bgGray;


    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_HORIZONTAL) {
	bounds = CGRectInset(bounds, 0, 1);
    } else {
	bounds = CGRectInset(bounds, 1, 0);
    }



    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {
	bgGray = TkMacOSXInDarkMode(tkwin) ? darkTrough : lightTrough;
	CGContextSetFillColorWithColor(dc.context, CGColorFromGray(bgGray));
    } else {
	ChkErr(HIThemeSetFill, kThemeBrushDocumentWindowBackground, NULL,
	    dc.context, HIOrientation);
    }
    CGContextFillRect(dc.context, bounds);
    END_DRAWING
}

static Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TroughElementSize,
    TroughElementDraw
};
static void ThumbElementSize(
    TCL_UNUSED(void *),        /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_VERTICAL) {
	*minHeight = 18;
	*minWidth = 8;
    } else {
	*minHeight = 8;
	*minWidth = 18;
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *),        /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;

    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);

    /*
     * In order to make ttk scrollbars work correctly it is necessary to be
     * able to display the thumb element at the size and location which the ttk
     * scrollbar widget requests.  The algorithm that HIToolbox uses to
     * determine the thumb geometry from the input values of min, max, value
     * and viewSize is undocumented.  A seemingly natural algorithm is
     * implemented below.  This code uses that algorithm for older OS versions,
     * because using HIToolbox also handles drawing the buttons and 3D thumb used
     * on those systems.  For newer systems the cleanest approach is to just
     * draw the thumb directly.
     */

    if ([NSApp macOSVersion] > 100800) {
	CGRect thumbBounds = BoxToRect(d, b);

	CGColorRef thumbColor;
	GrayColor bgGray;

	/*
	 * Apple does not draw the thumb when scrolling is not possible.
	 */

	if ((orientation == TTK_ORIENT_HORIZONTAL &&
	    thumbBounds.size.width >= Tk_Width(tkwin) - 8) ||
	    (orientation == TTK_ORIENT_VERTICAL &&
	    thumbBounds.size.height >= Tk_Height(tkwin) - 8)) {
	    return;
	}
	int isDark = TkMacOSXInDarkMode(tkwin);
	if ((state & TTK_STATE_PRESSED) ||
	    (state & TTK_STATE_HOVER)) {
	    bgGray = isDark ? darkActiveThumb : lightActiveThumb;
	} else {
	    bgGray = isDark ? darkInactiveThumb : lightInactiveThumb;
	}
	thumbColor = CGColorFromGray(bgGray);


	BEGIN_DRAWING(d)
	FillRoundedRectangle(dc.context, thumbBounds, 4, thumbColor);
	END_DRAWING
    } else {
	double thumbSize, trackSize, visibleSize, factor, fraction;
	MacDrawable *macWin = (MacDrawable *)Tk_WindowId(tkwin);
	CGRect troughBounds = {{macWin->xOff, macWin->yOff},
			       {Tk_Width(tkwin), Tk_Height(tkwin)}};

2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};
static void ArrowElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    if ([NSApp macOSVersion] < 100800) {
	*minHeight = *minWidth = 14;
    } else {
	*minHeight = *minWidth = -1;
    }
}







|
|
|


|







2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};
static void ArrowElementSize(
    TCL_UNUSED(void *),        /* clientData */
    TCL_UNUSED(void *),        /* elementRecord */
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    if ([NSApp macOSVersion] < 100800) {
	*minHeight = *minWidth = 14;
    } else {
	*minHeight = *minWidth = -1;
    }
}
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
 *
 *    DrawThemeSeparator() guesses the orientation of the line from the width
 *    and height of the rectangle, so the same element can can be used for
 *    horizontal, vertical, and general separators.
 */

static void SeparatorElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    *minWidth = *minHeight = 1;
}

static void SeparatorElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeSeparatorDrawInfo info = {
	.version = 0,
        /* Separator only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable,
	    state & TTK_STATE_BACKGROUND),







|
|
|


|





|
|



|







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
 *
 *    DrawThemeSeparator() guesses the orientation of the line from the width
 *    and height of the rectangle, so the same element can can be used for
 *    horizontal, vertical, and general separators.
 */

static void SeparatorElementSize(
    TCL_UNUSED(void *),       /* clientData */
    TCL_UNUSED(void *),       /* elementRecord */
    TCL_UNUSED(Tk_Window),    /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    *minWidth = *minHeight = 1;
}

static void SeparatorElementDraw(
    TCL_UNUSED(void *),       /* clientData */
    TCL_UNUSED(void *),       /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeSeparatorDrawInfo info = {
	.version = 0,
        /* Separator only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable,
	    state & TTK_STATE_BACKGROUND),
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
 * +++ Size grip elements -- (obsolete)
 */

static const ThemeGrowDirection sizegripGrowDirection
    = kThemeGrowRight | kThemeGrowDown;

static void SizegripElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
	.state = kThemeStateActive,
	.kind = kHIThemeGrowBoxKindNormal,
	.direction = sizegripGrowDirection,
	.size = kHIThemeGrowBoxSizeNormal,
    };
    CGRect bounds = CGRectZero;

    ChkErr(HIThemeGetGrowBoxBounds, &bounds.origin, &info, &bounds);
    *minWidth = bounds.size.width;
    *minHeight = bounds.size.height;
}

static void SizegripElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    Drawable d,
    Ttk_Box b,
    unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
        /* Grow box only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable,
	    state & TTK_STATE_BACKGROUND),







|
|
|


|
















|
|
|


|







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
 * +++ Size grip elements -- (obsolete)
 */

static const ThemeGrowDirection sizegripGrowDirection
    = kThemeGrowRight | kThemeGrowDown;

static void SizegripElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
	.state = kThemeStateActive,
	.kind = kHIThemeGrowBoxKindNormal,
	.direction = sizegripGrowDirection,
	.size = kHIThemeGrowBoxSizeNormal,
    };
    CGRect bounds = CGRectZero;

    ChkErr(HIThemeGetGrowBoxBounds, &bounds.origin, &info, &bounds);
    *minWidth = bounds.size.width;
    *minHeight = bounds.size.height;
}

static void SizegripElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
        /* Grow box only supports kThemeStateActive, kThemeStateInactive */
	.state = Ttk_StateTableLookup(ThemeStateTable,
	    state & TTK_STATE_BACKGROUND),
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
 *      the coordinate system of the top-level window.  Apparently failing to
 *      do this used to cause graphics anomalies when drawing into an
 *      off-screen graphics port.  The code for handling this is currently
 *      commented out.
 */

static void FillElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    if ([NSApp macOSVersion] > 100800) {
	NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	NSColor *bgColor;
	CGFloat fill[4];
	BEGIN_DRAWING(d)
	GetBackgroundColor(dc.context, tkwin, 0, fill);
	bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill
					 count: 4];
	CGContextSetFillColorSpace(dc.context, deviceRGB.CGColorSpace);
	CGContextSetFillColorWithColor(dc.context, CGCOLOR(bgColor));
	CGContextFillRect(dc.context, bounds);
	END_DRAWING
    } else {
	ThemeBrush brush = (state & TTK_STATE_BACKGROUND)
	    ? kThemeBrushModelessDialogBackgroundInactive
	    : kThemeBrushModelessDialogBackgroundActive;
	BEGIN_DRAWING(d)
	ChkErr(HIThemeSetFill, brush, NULL, dc.context, HIOrientation);
	//QDSetPatternOrigin(PatternOrigin(tkwin, d));
	CGContextFillRect(dc.context, bounds);
	END_DRAWING
    }
}

static void BackgroundElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    unsigned int state)
{
    FillElementDraw(clientData, elementRecord, tkwin, d, Ttk_WinBox(tkwin),
	state);
}

static Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,







|
|








<
|
<

|
<
<
<
|








<











|







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
 *      the coordinate system of the top-level window.  Apparently failing to
 *      do this used to cause graphics anomalies when drawing into an
 *      off-screen graphics port.  The code for handling this is currently
 *      commented out.
 */

static void FillElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

    if ([NSApp macOSVersion] > 100800) {

	CGColorRef bgColor;

	BEGIN_DRAWING(d)
	bgColor = GetBackgroundCGColor(dc.context, tkwin, NO, 0);



	CGContextSetFillColorWithColor(dc.context, bgColor);
	CGContextFillRect(dc.context, bounds);
	END_DRAWING
    } else {
	ThemeBrush brush = (state & TTK_STATE_BACKGROUND)
	    ? kThemeBrushModelessDialogBackgroundInactive
	    : kThemeBrushModelessDialogBackgroundActive;
	BEGIN_DRAWING(d)
	ChkErr(HIThemeSetFill, brush, NULL, dc.context, HIOrientation);

	CGContextFillRect(dc.context, bounds);
	END_DRAWING
    }
}

static void BackgroundElementDraw(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    Ttk_State state)
{
    FillElementDraw(clientData, elementRecord, tkwin, d, Ttk_WinBox(tkwin),
	state);
}

static Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
 *    <URL: http://developer.apple.com/documentation/Carbon/Reference/
 *    Appearance_Manager/appearance_manager/constant_7.html#/
 *    /apple_ref/doc/uid/TP30000243/C005321>
 *
 */

static void ToolbarBackgroundElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{
    ThemeBrush brush = kThemeBrushToolbarBackground;
    CGRect bounds = BoxToRect(d, Ttk_WinBox(tkwin));







|
|







3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
 *    <URL: http://developer.apple.com/documentation/Carbon/Reference/
 *    Appearance_Manager/appearance_manager/constant_7.html#/
 *    /apple_ref/doc/uid/TP30000243/C005321>
 *
 */

static void ToolbarBackgroundElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{
    ThemeBrush brush = kThemeBrushToolbarBackground;
    CGRect bounds = BoxToRect(d, Ttk_WinBox(tkwin));
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
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
    ToolbarBackgroundElementDraw
};

/*----------------------------------------------------------------------
 * +++ Field elements --
 *
 *      Used for the Treeview widget. This is like the BackgroundElement
 *      except that the fieldbackground color is configureable.
 */

typedef struct {
    Tcl_Obj     *backgroundObj;
} FieldElement;

static Ttk_ElementOptionSpec FieldElementOptions[] = {
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(FieldElement, backgroundObj), "white"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void FieldElementDraw(
    TCL_UNUSED(void *),
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    FieldElement *e = elementRecord;
    Tk_3DBorder backgroundPtr =
	Tk_Get3DBorderFromObj(tkwin, e->backgroundObj);

    XFillRectangle(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
	b.x, b.y, b.width, b.height);
}

static Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    TtkNullElementSize,
    FieldElementDraw
};

/*----------------------------------------------------------------------
 * +++ Treeview headers --
 *
 *    On systems older than 10.9 The header is a kThemeListHeaderButton drawn
 *    by HIToolbox.  On newer systems those buttons do not match the Apple
 *    buttons, so we draw them from scratch.
 */

static Ttk_StateTable TreeHeaderValueTable[] = {
    {kThemeButtonOn, TTK_STATE_ALTERNATE, 0},
    {kThemeButtonOn, TTK_STATE_SELECTED, 0},
    {kThemeButtonOff, 0, 0}
};

static Ttk_StateTable TreeHeaderAdornmentTable[] = {
    {kThemeAdornmentHeaderButtonSortUp,
     TTK_STATE_ALTERNATE | TTK_TREEVIEW_STATE_SORTARROW, 0},
    {kThemeAdornmentDefault,
     TTK_STATE_SELECTED | TTK_TREEVIEW_STATE_SORTARROW, 0},
    {kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_ALTERNATE, 0},
    {kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_SELECTED, 0},
    {kThemeAdornmentFocus, TTK_STATE_FOCUS, 0},
    {kThemeAdornmentNone, 0, 0}
};

static void TreeAreaElementSize (
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    Ttk_Padding *paddingPtr)
{

    /*
     * Padding is needed to get the heading text to align correctly, since the
     * widget expects the heading to be the same height as a row.
     */

    if ([NSApp macOSVersion] > 100800) {
	paddingPtr->top = 4;
    }
}

static Ttk_ElementSpec TreeAreaElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,







|













|






|



















|




|





|











|
|
|
|
|









|







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
    ToolbarBackgroundElementDraw
};

/*----------------------------------------------------------------------
 * +++ Field elements --
 *
 *      Used for the Treeview widget. This is like the BackgroundElement
 *      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, TK_OPTION_BOOLEAN, 0, NULL}
};

static void FieldElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    FieldElement *e = (FieldElement *)elementRecord;
    Tk_3DBorder backgroundPtr =
	Tk_Get3DBorderFromObj(tkwin, e->backgroundObj);

    XFillRectangle(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
	b.x, b.y, b.width, b.height);
}

static Ttk_ElementSpec FieldElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FieldElement),
    FieldElementOptions,
    TtkNullElementSize,
    FieldElementDraw
};

/*----------------------------------------------------------------------
 * +++ Treeview headers --
 *
 *    On systems older than 10.9 the header is a kThemeListHeaderButton drawn
 *    by HIToolbox.  On newer systems those buttons do not match the Apple
 *    buttons, so we draw them from scratch.
 */

static const Ttk_StateTable TreeHeaderValueTable[] = {
    {kThemeButtonOn, TTK_STATE_ALTERNATE, 0},
    {kThemeButtonOn, TTK_STATE_SELECTED, 0},
    {kThemeButtonOff, 0, 0}
};

static const Ttk_StateTable TreeHeaderAdornmentTable[] = {
    {kThemeAdornmentHeaderButtonSortUp,
     TTK_STATE_ALTERNATE | TTK_TREEVIEW_STATE_SORTARROW, 0},
    {kThemeAdornmentDefault,
     TTK_STATE_SELECTED | TTK_TREEVIEW_STATE_SORTARROW, 0},
    {kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_ALTERNATE, 0},
    {kThemeAdornmentHeaderButtonNoSortArrow, TTK_STATE_SELECTED, 0},
    {kThemeAdornmentFocus, TTK_STATE_FOCUS, 0},
    {kThemeAdornmentNone, 0, 0}
};

static void TreeAreaElementSize (
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{

    /*
     * Padding is needed to get the heading text to align correctly, since the
     * widget expects the heading to be the same height as a row.
     */

    if ([NSApp macOSVersion] > 100800) {
	*paddingPtr = Ttk_MakePadding(0, 4, 0, 0);
    }
}

static Ttk_ElementSpec TreeAreaElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
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
	ButtonElementSize(clientData, elementRecord, tkwin, minWidth,
	    minHeight, paddingPtr);
    }
}

static void TreeHeaderElementDraw(
    void *clientData,
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = clientData;
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = params->kind,
	.value = Ttk_StateTableLookup(TreeHeaderValueTable, state),
	.adornment = Ttk_StateTableLookup(TreeHeaderAdornmentTable, state),
    };

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {

        /*
         * Compensate for the padding added in TreeHeaderElementSize, so
         * the larger heading will be drawn at the top of the widget.
         */

	bounds.origin.y -= 4;
	if (TkMacOSXInDarkMode(tkwin)) {
	    DrawDarkListHeader(bounds, dc.context, tkwin, state);
	} else {
	    DrawListHeader(bounds, dc.context, tkwin, state);
	}
    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}








|





|


















<
<
<
|
<







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
	ButtonElementSize(clientData, elementRecord, tkwin, minWidth,
	    minHeight, paddingPtr);
    }
}

static void TreeHeaderElementDraw(
    void *clientData,
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;
    CGRect bounds = BoxToRect(d, b);
    const HIThemeButtonDrawInfo info = {
	.version = 0,
	.state = Ttk_StateTableLookup(ThemeStateTable, state),
	.kind = params->kind,
	.value = Ttk_StateTableLookup(TreeHeaderValueTable, state),
	.adornment = Ttk_StateTableLookup(TreeHeaderAdornmentTable, state),
    };

    BEGIN_DRAWING(d)
    if ([NSApp macOSVersion] > 100800) {

        /*
         * Compensate for the padding added in TreeHeaderElementSize, so
         * the larger heading will be drawn at the top of the widget.
         */

	bounds.origin.y -= 4;



	DrawListHeader(bounds, dc.context, tkwin, state);

    } else {
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

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

/*----------------------------------------------------------------------
 * +++ Disclosure triangles --
 */

#define TTK_TREEVIEW_STATE_OPEN         TTK_STATE_USER1
#define TTK_TREEVIEW_STATE_LEAF         TTK_STATE_USER2
static Ttk_StateTable DisclosureValueTable[] = {
    {kThemeDisclosureDown, TTK_TREEVIEW_STATE_OPEN, 0},
    {kThemeDisclosureRight, 0, 0},
};
static void DisclosureElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleWidth, &s);
    *minWidth = s;
    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleHeight, &s);
    *minHeight = s;
}

static void DisclosureElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    if (!(state & TTK_TREEVIEW_STATE_LEAF)) {
	int triangleState = TkMacOSXInDarkMode(tkwin) ?







|




|
|
|


|










|
|







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

/*----------------------------------------------------------------------
 * +++ Disclosure triangles --
 */

#define TTK_TREEVIEW_STATE_OPEN         TTK_STATE_USER1
#define TTK_TREEVIEW_STATE_LEAF         TTK_STATE_USER2
static const Ttk_StateTable DisclosureValueTable[] = {
    {kThemeDisclosureDown, TTK_TREEVIEW_STATE_OPEN, 0},
    {kThemeDisclosureRight, 0, 0},
};
static void DisclosureElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleWidth, &s);
    *minWidth = s;
    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleHeight, &s);
    *minHeight = s;
}

static void DisclosureElementDraw(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    if (!(state & TTK_TREEVIEW_STATE_LEAF)) {
	int triangleState = TkMacOSXInDarkMode(tkwin) ?
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
    TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.button", TTK_FILL_BOTH,
    TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))














































/* Notebook tabs -- no focus ring */
TTK_LAYOUT("Tab",
    TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
    TTK_GROUP("Notebook.padding", TTK_FILL_BOTH,
    TTK_NODE("Notebook.label", TTK_FILL_BOTH))))

/* Spinbox -- buttons 2px to the right of the field. */
TTK_LAYOUT("TSpinbox",
    TTK_GROUP("Spinbox.buttons", TTK_PACK_RIGHT,
    TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP | TTK_STICK_E)
    TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM | TTK_STICK_E))
    TTK_GROUP("Spinbox.field", TTK_FILL_X,
    TTK_NODE("Spinbox.textarea", TTK_FILL_X)))












/* Progress bars -- track only */
TTK_LAYOUT("TProgressbar",
    TTK_NODE("Progressbar.track", TTK_FILL_BOTH))

/* Treeview -- no border. */
TTK_LAYOUT("Treeview",
    TTK_GROUP("Treeview.field", TTK_FILL_BOTH,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














>
>
>
>
>
>
>
>
>
>
>







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
    TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))

TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.button", TTK_FILL_BOTH,
    TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
    TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))

/* Image Button - no button */
TTK_LAYOUT("ImageButton",
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH)))

/* Inline Button */
TTK_LAYOUT("InlineButton",
    TTK_GROUP("InlineButton.button", TTK_FILL_BOTH,
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH))))

/* Rounded Rect Button -- transparent face */
TTK_LAYOUT("RoundedRectButton",
    TTK_GROUP("RoundedRectButton.button", TTK_FILL_BOTH,
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH))))

/* Gradient Button */
TTK_LAYOUT("GradientButton",
    TTK_GROUP("GradientButton.button", TTK_FILL_BOTH,
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH))))

/* Recessed Button - text only radio button */

TTK_LAYOUT("RecessedButton",
    TTK_GROUP("RecessedButton.button", TTK_FILL_BOTH,
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH))))

/* Sidebar Button - text only radio button for sidebars */

TTK_LAYOUT("SidebarButton",
    TTK_GROUP("SidebarButton.button", TTK_FILL_BOTH,
    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
    TTK_NODE("Button.label", TTK_FILL_BOTH))))

/* DisclosureButton (not a triangle) -- No label, no border*/
TTK_LAYOUT("DisclosureButton",
    TTK_NODE("DisclosureButton.button", TTK_FILL_BOTH))

/* HelpButton -- No label, no border*/
TTK_LAYOUT("HelpButton",
    TTK_NODE("HelpButton.button", TTK_FILL_BOTH))

/* Notebook tabs -- no focus ring */
TTK_LAYOUT("Tab",
    TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
    TTK_GROUP("Notebook.padding", TTK_FILL_BOTH,
    TTK_NODE("Notebook.label", TTK_FILL_BOTH))))

/* Spinbox -- buttons 2px to the right of the field. */
TTK_LAYOUT("TSpinbox",
    TTK_GROUP("Spinbox.buttons", TTK_PACK_RIGHT,
    TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP | TTK_STICK_E)
    TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM | TTK_STICK_E))
    TTK_GROUP("Spinbox.field", TTK_FILL_X,
    TTK_NODE("Spinbox.textarea", TTK_FILL_X)))

TTK_LAYOUT("TEntry",
    TTK_GROUP("Entry.field", TTK_FILL_BOTH|TTK_BORDER,
        TTK_GROUP("Entry.padding", TTK_FILL_BOTH,
	    TTK_NODE("Entry.textarea", TTK_FILL_BOTH))))

/* Searchbox */
TTK_LAYOUT("Searchbox",
    TTK_GROUP("Searchbox.field", TTK_FILL_BOTH|TTK_BORDER,
        TTK_GROUP("Entry.padding", TTK_FILL_BOTH,
	    TTK_NODE("Entry.textarea", TTK_FILL_BOTH))))

/* Progress bars -- track only */
TTK_LAYOUT("TProgressbar",
    TTK_NODE("Progressbar.track", TTK_FILL_BOTH))

/* Treeview -- no border. */
TTK_LAYOUT("Treeview",
    TTK_GROUP("Treeview.field", TTK_FILL_BOTH,
3172
3173
3174
3175
3176
3177
3178




























3179
3180
3181
3182
3183
3184
3185
    TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_RIGHT)))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ Initialization --
 */





























static int AquaTheme_Init(
    Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_CreateTheme(interp, "aqua", NULL);

    if (!themePtr) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_RIGHT)))

TTK_END_LAYOUT_TABLE

/*----------------------------------------------------------------------
 * +++ Initialization --
 */

/*----------------------------------------------------------------------
 * +++ Ttk_MacOSXInit --
 *
 *    Initialize variables which depend on [NSApp macOSVersion].  Called from
 *    [NSApp applicationDidFinishLaunching].
 */

MODULE_SCOPE
void Ttk_MacOSXInit(
    void)
{
    if ([NSApp macOSVersion] < 101400) {
	entryElementPadding = Ttk_MakePadding(7, 6, 7, 5);
    } else {
	entryElementPadding = Ttk_MakePadding(7, 5, 7, 6);
    }
    if ([NSApp macOSVersion] < 110000) {
	Ttk_ContrastDelta = 8.0;
    } else {

	/*
	 * The subtle contrast became event more subtle in 11.0.
	 */

	Ttk_ContrastDelta = 5.0;
    }
}

static int AquaTheme_Init(
    Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_CreateTheme(interp, "aqua", NULL);

    if (!themePtr) {
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
    Ttk_RegisterElementSpec(themePtr, "fill", &FillElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Toolbar.background",
	&ToolbarBackgroundElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Button.button",
	&ButtonElementSpec, &PushButtonParams);




    Ttk_RegisterElementSpec(themePtr, "Checkbutton.button",
	&ButtonElementSpec, &CheckBoxParams);
    Ttk_RegisterElementSpec(themePtr, "Radiobutton.button",
	&ButtonElementSpec, &RadioButtonParams);




    Ttk_RegisterElementSpec(themePtr, "Toolbutton.border",
	&ButtonElementSpec, &BevelButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Menubutton.button",
	&ButtonElementSpec, &PopupButtonParams);






    Ttk_RegisterElementSpec(themePtr, "Spinbox.uparrow",
	&SpinButtonUpElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.downarrow",
	&SpinButtonDownElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Combobox.button",
	&ComboboxElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Treeitem.indicator",
	&DisclosureElementSpec, &DisclosureParams);
    Ttk_RegisterElementSpec(themePtr, "Treeheading.cell",
	&TreeHeaderElementSpec, &ListHeaderParams);

    Ttk_RegisterElementSpec(themePtr, "Treeview.treearea",
	&TreeAreaElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.tab", &TabElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.client", &PaneElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Labelframe.border", &GroupElementSpec,
	0);
    Ttk_RegisterElementSpec(themePtr, "Entry.field", &EntryElementSpec, 0);



    Ttk_RegisterElementSpec(themePtr, "Spinbox.field", &EntryElementSpec, 0);


    Ttk_RegisterElementSpec(themePtr, "separator", &SeparatorElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "hseparator", &SeparatorElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "vseparator", &SeparatorElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "sizegrip", &SizegripElementSpec, 0);








>
>
>
>




>
>
>
>




>
>
>
>
>
>


















|
>
>
>
|
>







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
    Ttk_RegisterElementSpec(themePtr, "fill", &FillElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Toolbar.background",
	&ToolbarBackgroundElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Button.button",
	&ButtonElementSpec, &PushButtonParams);
    Ttk_RegisterElementSpec(themePtr, "InlineButton.button",
	&ButtonElementSpec, &InlineButtonParams);
    Ttk_RegisterElementSpec(themePtr, "RoundedRectButton.button",
	&ButtonElementSpec, &RoundedRectButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Checkbutton.button",
	&ButtonElementSpec, &CheckBoxParams);
    Ttk_RegisterElementSpec(themePtr, "Radiobutton.button",
	&ButtonElementSpec, &RadioButtonParams);
    Ttk_RegisterElementSpec(themePtr, "RecessedButton.button",
	&ButtonElementSpec, &RecessedButtonParams);
    Ttk_RegisterElementSpec(themePtr, "SidebarButton.button",
	&ButtonElementSpec, &SidebarButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Toolbutton.border",
	&ButtonElementSpec, &BevelButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Menubutton.button",
	&ButtonElementSpec, &PopupButtonParams);
    Ttk_RegisterElementSpec(themePtr, "DisclosureButton.button",
	&ButtonElementSpec, &DisclosureButtonParams);
    Ttk_RegisterElementSpec(themePtr, "HelpButton.button",
	&ButtonElementSpec, &HelpButtonParams);
    Ttk_RegisterElementSpec(themePtr, "GradientButton.button",
	&ButtonElementSpec, &GradientButtonParams);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.uparrow",
	&SpinButtonUpElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.downarrow",
	&SpinButtonDownElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Combobox.button",
	&ComboboxElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Treeitem.indicator",
	&DisclosureElementSpec, &DisclosureParams);
    Ttk_RegisterElementSpec(themePtr, "Treeheading.cell",
	&TreeHeaderElementSpec, &ListHeaderParams);

    Ttk_RegisterElementSpec(themePtr, "Treeview.treearea",
	&TreeAreaElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.tab", &TabElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "Notebook.client", &PaneElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "Labelframe.border", &GroupElementSpec,
	0);
    Ttk_RegisterElementSpec(themePtr, "Entry.field", &EntryElementSpec,
			    &EntryFieldParams);
    Ttk_RegisterElementSpec(themePtr, "Searchbox.field", &EntryElementSpec,
			    &SearchboxFieldParams);
    Ttk_RegisterElementSpec(themePtr, "Spinbox.field", &EntryElementSpec,
			    &EntryFieldParams);

    Ttk_RegisterElementSpec(themePtr, "separator", &SeparatorElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "hseparator", &SeparatorElementSpec, 0);
    Ttk_RegisterElementSpec(themePtr, "vseparator", &SeparatorElementSpec, 0);

    Ttk_RegisterElementSpec(themePtr, "sizegrip", &SizegripElementSpec, 0);

Added macosx/ttkMacOSXTheme.h.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
/*
 * ttkMacOSXTheme.h --
 *
 *      Static data and macros used in ttkMacOSXTheme.c
 *
 * 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.
 */

/*
 * Macros for handling drawing contexts.
 */

#define BEGIN_DRAWING(d) {				    \
    TkMacOSXDrawingContext dc;				    \
    if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) {	    \
	return;						    \
    }							    \

#define END_DRAWING				\
    TkMacOSXRestoreDrawingContext(&dc);}


#define HIOrientation kHIThemeOrientationNormal
#define NoThemeMetric 0xFFFFFFFF

/*
 *  A scale factor used to map a range of non-negative doubles into a large
 *  range of non-negative 32-bit integers without losing too much information.
 *  (Use 1073741824 == 2^30 so we don't get surprised by roundoff.)
 */

#define RangeToFactor(max) ((double) (1073741824.0) / (max < 1.0 ? 1.0 : max))

/*
 * Meanings of Ttk states represented by User1 and User2.
 */

#define TTK_STATE_FIRST_TAB     TTK_STATE_USER1
#define TTK_STATE_LAST_TAB      TTK_STATE_USER2
#define TTK_STATE_IS_ACCENTED   TTK_STATE_USER2
#define TTK_TREEVIEW_STATE_SORTARROW    TTK_STATE_USER1

/*
 * Colors and gradients used when drawing buttons.
 */

typedef struct GrayColor {
    CGFloat grayscale;
    CGFloat alpha;
} GrayColor;

#define RGBACOLOR static CGFloat
#define RGBA256(r, g, b, a) {r / 255.0, g / 255.0, b / 255.0, a}
#define GRAYCOLOR static GrayColor
#define GRAY256(grayscale) {grayscale / 255.0, 1.0}

/*
 * Opaque Grays used for Gradient Buttons, Scrollbars and List Headers
 */

GRAYCOLOR darkDisabledIndicator = GRAY256(122.0);
GRAYCOLOR lightDisabledIndicator = GRAY256(152.0);

GRAYCOLOR darkGradientNormal = GRAY256(95.0);
GRAYCOLOR darkGradientPressed = GRAY256(118.0);
GRAYCOLOR darkGradientDisabled = GRAY256(82.0);
GRAYCOLOR darkGradientBorder = GRAY256(118.0);
GRAYCOLOR darkGradientBorderDisabled = GRAY256(94.0);
GRAYCOLOR lightGradientNormal = GRAY256(244.0);
GRAYCOLOR lightGradientPressed = GRAY256(175.0);
GRAYCOLOR lightGradientDisabled = GRAY256(235.0);
GRAYCOLOR lightGradientBorder = GRAY256(165.0);
GRAYCOLOR lightGradientBorderDisabled = GRAY256(204.0);

GRAYCOLOR lightTrough = GRAY256(250.0);
GRAYCOLOR darkTrough = GRAY256(47.0);
GRAYCOLOR lightInactiveThumb = GRAY256(200.0);
GRAYCOLOR lightActiveThumb = GRAY256(133.0);
GRAYCOLOR darkInactiveThumb = GRAY256(117.0);
GRAYCOLOR darkActiveThumb = GRAY256(158.0);

GRAYCOLOR lightListheaderBorder = GRAY256(200.0);
GRAYCOLOR listheaderSeparator = GRAY256(220.0);
GRAYCOLOR listheaderActiveBG = GRAY256(238.0);
GRAYCOLOR listheaderInactiveBG = GRAY256(246.0);

GRAYCOLOR lightComboSeparator = GRAY256(236.0);
GRAYCOLOR darkComboSeparator = GRAY256(66.0);

GRAYCOLOR darkTrack = GRAY256(84.0);
GRAYCOLOR darkInactiveTrack = GRAY256(107.0);
GRAYCOLOR lightTrack = GRAY256(177.0);
GRAYCOLOR lightInactiveTrack = GRAY256(139.0);

/*
 * Transparent Grays
 */

GRAYCOLOR boxBorder = {1.0, 0.20};
GRAYCOLOR darkSeparator = {1.0, 0.3};
GRAYCOLOR darkTabSeparator = {0.0, 0.25};
GRAYCOLOR darkListheaderBorder = {1.0, 0.125};
GRAYCOLOR pressedDefaultButton = {0.0, 0.1};
GRAYCOLOR darkPressedDefaultButton = {1.0, 0.1};

#define CG_WHITE CGColorGetConstantColor(kCGColorWhite)


/*
 * Structures which comprise a database of corner radii and state-dependent
 * colors used when drawing various types of buttons or entry widgets.
 */

typedef struct GrayPalette {
    CGFloat face;
    CGFloat top;
    CGFloat side;
    CGFloat bottom;
} GrayPalette;

typedef struct PaletteStateTable {
    GrayPalette light;          /* Light palette to use if this entry matches */
    GrayPalette dark;           /* dark palette to use if this entry matches */
    unsigned int onBits;        /* Bits which must be set */
    unsigned int offBits;       /* Bits which must be cleared */
} PaletteStateTable;

typedef struct ButtonDesign {
    CGFloat radius;
    PaletteStateTable palettes[];
} ButtonDesign;

/*
 * The data.
 */

static const ButtonDesign pushbuttonDesign = {
  .radius = 4.0,
  .palettes = {
    {
      .light = {.face = 242.0, .top = 213.0, .side = 210.0, .bottom = 200.0},
      .dark =  {.face = 94.0,  .top = 98.0,  .side = 94.0,  .bottom = 58.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0},
    {
      .light = {.face = 205.0, .top = 215.0, .side = 211.0, .bottom = 173.0},
      .dark =  {.face = 140.0, .top = 150.0, .side = 140.0, .bottom = 42.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 198.0, .side = 192.0, .bottom = 173.0},
      .dark =  {.face = 118.0, .top = 132.0, .side = 118.0, .bottom = 48.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign helpDesign = {
  .radius = 11,
  .palettes = {
    {
      .light = {.face = 241.0, .top = 218.0, .side = 217.0, .bottom = 206.0},
      .dark =  {.face = 83.0,  .top = 89.0,  .side = 82.0,  .bottom = 82.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0},
    {
      .light = {.face = 240.0, .top = 208.0, .side = 205.0, .bottom = 188.0},
      .dark =  {.face = 129.0, .top = 121.0, .side = 106.0, .bottom = 106.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 208.0, .side = 205.0, .bottom = 188.0},
      .dark =  {.face = 107.0, .top = 121.0, .side = 106.0, .bottom = 106.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign inlineDesign = {
  .radius = 8.0,
  .palettes = {
    {
      .light = {.face = 170.0, .top = 170.0, .side = 170.0, .bottom = 170.0},
      .dark =  {.face = 106.0,  .top = 106.0,  .side = 106.0,  .bottom = 106.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0},
    {
      .light = {.face = 34.0, .top = 34.0, .side = 34.0, .bottom = 34.0},
      .dark =  {.face = 225.0, .top = 225.0, .side = 225.0, .bottom = 225.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 113.0, .top = 113.0, .side = 113.0, .bottom = 113.0},
      .dark =  {.face = 165.0, .top = 165.0, .side = 165.0, .bottom = 165.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign roundedrectDesign = {
  .radius = 3.0,
  .palettes = {
    {
      .light = {.face = 256.0, .top = 192.0, .side = 192.0, .bottom = 192.0},
      .dark =  {.face = 256.0, .top = 165.0, .side = 163.0, .bottom = 42.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 204.0, .top = 158.0, .side = 158.0, .bottom = 158.0},
      .dark =  {.face = 85.0,  .top = 115.0, .side = 115.0, .bottom = 115.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 205.0, .top = 215.0, .side = 211.0, .bottom = 173.0},
      .dark =  {.face = 140.0, .top = 150.0, .side = 140.0, .bottom = 42.0},
      .onBits = TTK_STATE_ALTERNATE, .offBits = TTK_STATE_BACKGROUND
    },

    /*
     * Gray values > 255 are replaced by the background color.
     */

    {
      .light = {.face = 256.0, .top = 158.0, .side = 158.0, .bottom = 158.0},
      .dark =  {.face = 256.0, .top = 115.0, .side = 115.0, .bottom = 115.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign popupDesign = {
  .radius = 4.0,
  .palettes = {
    {
      .light = {.face = 242.0, .top = 213.0, .side = 210.0, .bottom = 200.0},
      .dark =  {.face = 94.0,  .top = 98.0,  .side = 94.0,  .bottom = 58.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 198.0, .side = 192.0, .bottom = 173.0},
      .dark =  {.face = 118.0, .top = 132.0, .side = 118.0, .bottom = 48.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign checkDesign = {
  .radius = 4.0,
  .palettes = {
    {
      .light = {.face = 242.0, .top = 192.0, .side = 199.0, .bottom = 199.0},
      .dark =  {.face = 80.0,  .top = 90.0,  .side = 80.0,  .bottom = 49.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 165.0, .side = 184.0, .bottom = 184.0},
      .dark =  {.face = 118.0, .top = 132.0, .side = 118.0, .bottom = 48.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign radioDesign = {
  .radius = 8.0,
  .palettes = {
    {
      .light = {.face = 242.0, .top = 189.0, .side = 198.0, .bottom = 199.0},
      .dark =  {.face = 80.0,  .top = 84.0,  .side = 88.0,  .bottom = 60.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 165.0, .side = 184.0, .bottom = 184.0},
      .dark =  {.face = 118.0, .top = 132.0, .side = 118.0, .bottom = 48.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign recessedDesign = {
  .radius = 4.0,
  .palettes = {
    {
      .light = {.face = 117.0, .top = 117.0, .side = 117.0, .bottom = 117.0},
      .dark =  {.face = 129.0, .top = 129.0, .side = 129.0, .bottom = 129.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 182.0, .top = 182.0, .side = 182.0, .bottom = 182.0},
      .dark =  {.face = 105.0,  .top = 105.0, .side = 105.0, .bottom = 105.0},
      .onBits = TTK_STATE_ACTIVE, .offBits = TTK_STATE_SELECTED
    },
    {
      .light = {.face = 145.0, .top = 145.0, .side = 145.0, .bottom = 145.0},
      .dark =  {.face = 166.0, .top = 166.0, .side = 166.0, .bottom = 166.0},
      .onBits = TTK_STATE_SELECTED, .offBits = 0
    },
    {
      .light = {.face = 256.0, .top = 256.0, .side = 256.0, .bottom = 256.0},
      .dark =  {.face = 256.0, .top = 256.0, .side = 256.0, .bottom = 256.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign sidebarDesign = {
  .radius = 8.0,
  .palettes = {
    {
      .light = {.face = 210.0, .top = 210.0, .side = 210.0, .bottom = 210.0},
      .dark =  {.face = 129.0, .top = 129.0, .side = 129.0, .bottom = 129.0},
      .onBits = TTK_STATE_SELECTED, .offBits = 0
    },
    {
      .light = {.face = 210.0, .top = 210.0, .side = 210.0, .bottom = 210.0},
      .dark =  {.face = 129.0, .top = 129.0, .side = 129.0, .bottom = 129.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 256.0, .top = 256.0, .side = 256.0, .bottom = 256.0},
      .dark =  {.face = 256.0, .top = 256.0, .side = 256.0, .bottom = 256.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign incdecDesign = {
  .radius = 5.0,
  .palettes = {
    {
      .light = {.face = 246.0, .top = 236.0, .side = 227.0, .bottom = 213.0},
      .dark =  {.face = 80.0,  .top = 90.0,  .side = 80.0,  .bottom = 49.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 198.0, .side = 192.0, .bottom = 173.0},
      .dark =  {.face = 118.0, .top = 132.0, .side = 118.0, .bottom = 48.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign bevelDesign = {
  .radius = 4.0,
  .palettes = {
    {
      .light = {.face = 242.0, .top = 213.0, .side = 210.0, .bottom = 200.0},
      .dark =  {.face = 94.0,  .top = 98.0,  .side = 94.0,  .bottom = 58.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 205.0, .top = 215.0, .side = 211.0, .bottom = 173.0},
      .dark =  {.face = 140.0, .top = 150.0, .side = 140.0, .bottom = 42.0},
      .onBits = TTK_STATE_PRESSED, .offBits = 0
    },
    {
      .light = {.face = 228.0, .top = 215.0, .side = 211.0, .bottom = 173.0},
      .dark =  {.face = 163.0, .top = 150.0, .side = 140.0, .bottom = 42.0},
      .onBits = TTK_STATE_SELECTED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 198.0, .side = 192.0, .bottom = 173.0},
      .dark =  {.face = 118.0, .top = 132.0, .side = 118.0, .bottom = 48.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign tabDesign = {
  .radius = 4.0,
  .palettes = {

    /*
     * Apple does not have such a thing as a disabled tab.  If it is
     * disabled, it should be removed.  But we provide one based on the
     * disabled button.
     */

    {
      .light = {.face = 229.0, .top = 213.0, .side = 242.0, .bottom = 200.0},
      .dark =  {.face = 163.0,  .top = 90.0,  .side = 80.0,  .bottom = 49.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 229.0, .top = 205.0, .side = 211.0, .bottom = 183.0},
      .dark =  {.face = 163.0, .top = 165.0, .side = 163.0, .bottom = 42.0},
      .onBits = TTK_STATE_SELECTED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 215.0, .side = 211.0, .bottom = 183.0},
      .dark =  {.face = 108.0, .top = 129.0, .side = 108.0, .bottom = 47.0},
      .onBits = 0, .offBits = 0
    },
  }
};

static const ButtonDesign entryDesign = {
  .radius = 0.0,
  .palettes = {
    {
      .light = {.face = 256.0, .top = 198.0, .side = 198.0, .bottom = 198.0},
      .dark =  {.face = 256.0,  .top = 66.0,  .side = 66.0,  .bottom = 84.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign searchDesign = {
  .radius = 3.5,
  .palettes = {
    {
      .light = {.face = 256.0, .top = 198.0, .side = 198.0, .bottom = 198.0},
      .dark =  {.face = 256.0,  .top = 66.0,  .side = 66.0,  .bottom = 84.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign comboDesign = {
  .radius = 4.0,
  .palettes = {
    {
      .light = {.face = 256.0, .top = 190.0, .side = 190.0, .bottom = 190.0},
      .dark =  {.face = 256.0,  .top = 66.0,  .side = 66.0,  .bottom = 90.0},
      .onBits = 0, .offBits = 0
    }
  }
};

static const ButtonDesign sliderDesign = {
  .radius = 8.0,
  .palettes = {
    {
      .light = {.face = 242.0, .top = 189.0, .side = 198.0, .bottom = 199.0},
      .dark =  {.face = 80.0,  .top = 84.0,  .side = 88.0,  .bottom = 60.0},
      .onBits = TTK_STATE_DISABLED, .offBits = 0
    },
    {
      .light = {.face = 255.0, .top = 165.0, .side = 184.0, .bottom = 184.0},
      .dark =  {.face = 205.0, .top = 205.0, .side = 205.0, .bottom = 198.0},
      .onBits = 0, .offBits = 0
    }
  }
};


/*
 * Table mapping Tk states to Appearance manager ThemeStates
 */

static const Ttk_StateTable ThemeStateTable[] = {
    {kThemeStateActive, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeStateUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeStatePressed, TTK_STATE_PRESSED, 0},
    {kThemeStateInactive, TTK_STATE_BACKGROUND, 0},
    {kThemeStateUnavailableInactive, TTK_STATE_DISABLED | TTK_STATE_BACKGROUND, 0},
    {kThemeStateActive, 0, 0}

    /* Others:
     * The kThemeStatePressedUp and kThemeStatePressedDown bits indicate
     * which of the two segments of an IncDec button is being pressed.
     * We don't use these. kThemeStateRollover roughly corresponds to
     * TTK_STATE_ACTIVE, but does not do what we want with the help button.
     *
     * {kThemeStatePressedUp, 0, 0},
     * {kThemeStatePressedDown, 0, 0}
     * {kThemeStateRollover, TTK_STATE_ACTIVE, 0},
     */
};

/*
 * Translation between Ttk and HIToolbox.
 */

static const Ttk_StateTable ButtonValueTable[] = {
    {kThemeButtonOff, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeButtonMixed, TTK_STATE_ALTERNATE, 0},
    {kThemeButtonOn, TTK_STATE_SELECTED, 0},
    {kThemeButtonOff, 0, 0}
};

static const Ttk_StateTable ButtonAdornmentTable[] = {
    {kThemeAdornmentNone, TTK_STATE_ALTERNATE | TTK_STATE_BACKGROUND, 0},
    {kThemeAdornmentDefault | kThemeAdornmentFocus,
     TTK_STATE_ALTERNATE | TTK_STATE_FOCUS, 0},
    {kThemeAdornmentFocus, TTK_STATE_FOCUS, 0},
    {kThemeAdornmentDefault, TTK_STATE_ALTERNATE, 0},
    {kThemeAdornmentNone, 0, 0}
};

/*
 * Our enums for button styles not known to HIToolbox.
 */

#define TkGradientButton    0x8001
#define TkRoundedRectButton 0x8002
#define TkRecessedButton    0x8003
#define TkInlineButton      0x8004
#define TkSidebarButton     0x8005
/*
 * The struct passed as clientData when drawing Ttk buttons.
 */

typedef struct {
    ThemeButtonKind kind;
    ThemeMetric heightMetric;
    ThemeMetric widthMetric;
} ThemeButtonParams;

static ThemeButtonParams
    PushButtonParams =  {kThemePushButton, kThemeMetricPushButtonHeight,
			 NoThemeMetric},
    CheckBoxParams =    {kThemeCheckBox, kThemeMetricCheckBoxHeight,
			 NoThemeMetric},
    RadioButtonParams = {kThemeRadioButton, kThemeMetricRadioButtonHeight,
			 NoThemeMetric},
    BevelButtonParams = {kThemeRoundedBevelButton, NoThemeMetric, NoThemeMetric},
    PopupButtonParams = {kThemePopupButton, kThemeMetricPopupButtonHeight,
			 NoThemeMetric},
    DisclosureParams =  {kThemeDisclosureButton,
			 kThemeMetricDisclosureTriangleHeight,
			 kThemeMetricDisclosureTriangleWidth},
    DisclosureButtonParams = {kThemeArrowButton,
			      kThemeMetricSmallDisclosureButtonHeight,
			      kThemeMetricSmallDisclosureButtonWidth},
    HelpButtonParams = {kThemeRoundButtonHelp, kThemeMetricRoundButtonSize,
			kThemeMetricRoundButtonSize},
    ListHeaderParams = {kThemeListHeaderButton, kThemeMetricListHeaderHeight,
			NoThemeMetric},
    GradientButtonParams = {TkGradientButton, NoThemeMetric, NoThemeMetric},
    RoundedRectButtonParams = {TkRoundedRectButton, kThemeMetricPushButtonHeight,
			       NoThemeMetric},
    RecessedButtonParams = {TkRecessedButton, kThemeMetricPushButtonHeight,
 			    NoThemeMetric},
    SidebarButtonParams = {TkSidebarButton, NoThemeMetric, NoThemeMetric},
    InlineButtonParams = {TkInlineButton,  kThemeMetricPushButtonHeight, NoThemeMetric};

    /*
     * Others: kThemeDisclosureRight, kThemeDisclosureDown,
     * kThemeDisclosureLeft
     */

/*
 *  The struct passed as clientData when drawing Ttk Entry widgets.
 */

typedef struct {
    HIThemeFrameKind kind;
    ThemeMetric heightMetric;
    ThemeMetric widthMetric;
} ThemeFrameParams;

static ThemeFrameParams
    EntryFieldParams = {kHIThemeFrameTextFieldSquare, NoThemeMetric, NoThemeMetric},
    SearchboxFieldParams = {kHIThemeFrameTextFieldRound, NoThemeMetric, NoThemeMetric};

/*
 * If we try to draw a rounded rectangle with too large of a radius, the Core
 * Graphics library will sometimes raise a fatal exception.  This macro
 * protects against this by returning if the width or height is less than
 * twice the radius.  Presumably this only happens when a widget has not yet
 * been configured and has size 1x1, so there is nothing to draw anyway.
 */

#define CHECK_RADIUS(radius, bounds)                                                 \
    if ((radius) > (bounds).size.width / 2 || (radius) > (bounds).size.height / 2) { \
        return;                                                                      \
    }

/*
 * The spinbox widget needs to draw the two arrows in different colors when
 * one half or the other is being pressed, but the menubutton always draws
 * them in the same color.  This constant is used to distinguish those two
 * situations.
 */

#define BOTH_ARROWS 1 << 30

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to tests/all.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# all.tcl --
#
# This file contains a top-level script to run all of the Tk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright © 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [tcltest::testsDirectory] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]






|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# all.tcl --
#
# This file contains a top-level script to run all of the Tk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright © 1998-1999 Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [tcltest::testsDirectory] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]

Changes to tests/bell.test.

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 © 1994 The Regents of the University of California.
# Copyright © 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands





|







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 © 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

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

test bell-1.4 {bell command} -body {
    bell -nice -displayof
} -returnCodes {error} -result {wrong # args: should be "bell ?-displayof window? ?-nice?"}

test bell-1.5 {bell command} -body {
    bell -nice -nice -nice
} -returnCodes {ok} -result {}  ;#keep -result {} and -retutnCodes {ok} for clarity?

test bell-1.6 {bell command} -body {
    bell -displayof . -nice
} -returnCodes {ok} -result {}

test bell-1.7 {bell command} -body {
    bell -nice -displayof . -nice







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

test bell-1.4 {bell command} -body {
    bell -nice -displayof
} -returnCodes {error} -result {wrong # args: should be "bell ?-displayof window? ?-nice?"}

test bell-1.5 {bell command} -body {
    bell -nice -nice -nice
} -returnCodes {ok} -result {}  ;#keep -result {} and -returnCodes {ok} for clarity?

test bell-1.6 {bell command} -body {
    bell -displayof . -nice
} -returnCodes {ok} -result {}

test bell-1.7 {bell command} -body {
    bell -nice -displayof . -nice

Changes to tests/bgerror.test.

1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test the bgerror command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test the bgerror command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/bind.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# This file is a Tcl script to test out Tk's "bind" and "bindtags"
# commands plus the procedures in tkBind.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
tk useinputmethods 0

testConstraint nodeprecated [expr {"nodeprecated" ni [tk::pkgconfig list]}]


toplevel .t -width 100 -height 50
wm geom .t +0+0
update idletasks

foreach p [event info] {event delete $p}
foreach event [bind Test] {






|







<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14



15
16
17
18
19
20
21
# This file is a Tcl script to test out Tk's "bind" and "bindtags"
# commands plus the procedures in tkBind.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
tk useinputmethods 0




toplevel .t -width 100 -height 50
wm geom .t +0+0
update idletasks

foreach p [event info] {event delete $p}
foreach event [bind Test] {
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top
wm geometry .top 50x50-50-50
update
event generate .top <Button-1> -warp 1
update
destroy .top

test bind-1.1 {bind command} -body {
    bind
} -returnCodes error -result {wrong # args: should be "bind window ?pattern? ?command?"}
test bind-1.2 {bind command} -body {
    bind a b c d







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top
wm geometry .top 50x50-50-50
update
event generate .top <Button-1> -warp 1
controlPointerWarpTiming
destroy .top

test bind-1.1 {bind command} -body {
    bind
} -returnCodes error -result {wrong # args: should be "bind window ?pattern? ?command?"}
test bind-1.2 {bind command} -body {
    bind a b c d
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
    .t.c bind foo a
} -cleanup {
    destroy .t.c
} -result {Test}

test bind-11.1 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "! a \\\{ ~ <Delete> <space> <<Paste>> <Tab> <Linefeed> <less> <Meta-a> <Acircumflex>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {! <<Paste>> <Key-Acircumflex> <Key-Delete> <Key-Linefeed> <Key-Tab> <Key-less> <Key-space> <Meta-Key-a> a \{ ~}
test bind-11.2 {Tk_GetAllBindings procedure} -body {
    frame .t.f
    foreach i "<Double-Button-1> <Triple-Button-1> <Meta-Control-a> <Double-Alt-Enter> <Button-1>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {







|





|







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
    .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> <Key-<> <Meta-a> <Â>" {
        bind .t.f $i Test
    }
    lsort [bind .t.f]
} -cleanup {
    destroy .t.f
} -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 {
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
} -body {
    bind Test <Key> {lappend x "%W %K Test Key"}
    bind all <Key> {lappend x "%W %K all Key"}
    bind Test : {lappend x "%W %K Test :"}
    bind all  _ {lappend x "%W %K all _"}
    bind .t.f : {lappend x "%W %K .t.f :"}

    event generate .t.f <colon>
    event generate .t.f <plus>
    event generate .t.f <underscore>
    return $x
} -cleanup {
    destroy .t.f
    bind all <Key> {}
    bind Test <Key> {}
    bind all _ {}
    bind Test : {}
} -result {{.t.f colon .t.f :} {.t.f colon Test :} {.t.f colon all Key} {.t.f plus Test Key} {.t.f plus all Key} {.t.f underscore Test Key} {.t.f underscore all _}}

test bind-13.2 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test <Key> {lappend x "%W %K Test press any"; break}
    bind all <Key> {continue; lappend x "%W %K all press any"}
    bind .t.f : {lappend x "%W %K .t.f pressed colon"}

    event generate .t.f <colon>
    return $x
} -cleanup {
    destroy .t.f
    bind all <Key> {}
    bind Test <Key> {}
} -result {{.t.f colon .t.f pressed colon} {.t.f colon Test press any}}

test bind-13.3 {Tk_BindEvent procedure} -setup {
    proc bgerror args {}
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test <Key> {lappend x "%W %K Test press any"; error Test}
    bind .t.f : {lappend x "%W %K .t.f pressed colon"}
    event generate .t.f <colon>
    update
    list $x $errorInfo
} -cleanup {
    destroy .t.f
    bind Test <Key> {}
    rename bgerror {}
}  -result {{{.t.f colon .t.f pressed colon} {.t.f colon Test press any}} {Test
    while executing
"error Test"
    (command bound to event)}}
test bind-13.4 {Tk_BindEvent procedure} -setup {
    proc foo {} {
        set x 44
        event generate .t.f <colon>
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind Test : {lappend x "%W %K Test"}
    bind .t.f : {lappend x "%W %K .t.f"}
    foo
    return $x
} -cleanup {
    destroy .t.f
    bind Test : {}
} -result {{.t.f colon .t.f} {.t.f colon Test}}

test bind-13.5 {Tk_BindEvent procedure} -body {
    bind all <Destroy> {lappend x "%W destroyed"}
    set x {}
    frame .t.g -gorp foo
} -cleanup {
    bind all <Destroy> {}







|
|
|







|












|





|











|






|






|














|







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
} -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 <:>
    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 : .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 <:>
    return $x
} -cleanup {
    destroy .t.f
    bind all <Key> {}
    bind Test <Key> {}
} -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 <:>
    update
    list $x $errorInfo
} -cleanup {
    destroy .t.f
    bind Test <Key> {}
    rename bgerror {}
}  -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 <:>
    }
    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 : .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> {}
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f : {lappend x "%W (.t.f binding)"}
    bind Test : {lappend x "%W (Test binding)"}
    bind all : {bind .t.f : {}; lappend x "%W (all binding)"}
    event generate .t.f <colon>
    return $x
} -cleanup {
    bind Test : {}
    bind all : {}
    destroy .t.f
} -result {{.t.f (.t.f binding)} {.t.f (Test binding)} {.t.f (all binding)}}
test bind-13.8 {Tk_BindEvent procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f : {lappend x "%W (.t.f binding)"}
    bind Test : {lappend x "%W (Test binding)"}
    bind all : {destroy .t.f; lappend x "%W (all binding)"}
    event generate .t.f <colon>
    return $x
} -cleanup {
    bind Test : {}
    bind all : {}
    destroy .t.f
} -result {{.t.f (.t.f binding)} {.t.f (Test binding)} {.t.f (all binding)}}








|
















|







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f : {lappend x "%W (.t.f binding)"}
    bind Test : {lappend x "%W (Test binding)"}
    bind all : {bind .t.f : {}; lappend x "%W (all binding)"}
    event generate .t.f <:>
    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 <:>
    return $x
} -cleanup {
    bind Test : {}
    bind all : {}
    destroy .t.f
} -result {{.t.f (.t.f binding)} {.t.f (Test binding)} {.t.f (all binding)}}

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
    bind .t.f <Button> {lappend x "%W z (.t.f <Button> binding)"}
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
} -result {{.t.f z (.t.f <Button-1> binding)} {.t.f z (.t.f <Button> binding)}}
test bind-13.10 {Tk_BindEvent procedure: ignore NotifyInferior} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x Enter%#"
    bind .t.f <Leave> "lappend x Leave%#"
    event generate .t.f <Enter> -serial 100 -detail NotifyAncestor
    event generate .t.f <Enter> -serial 101 -detail NotifyInferior
    event generate .t.f <Leave> -serial 102 -detail NotifyAncestor
    event generate .t.f <Leave> -serial 103 -detail NotifyInferior
    return $x
} -cleanup {
    destroy .t.f
} -result {Enter100 Leave102}
test bind-13.11 {Tk_BindEvent procedure: collapse Motions} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {







|















|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
    bind .t.f <Button> {lappend x "%W z (.t.f <Button> binding)"}
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    return $x
} -cleanup {
    destroy .t.f
} -result {{.t.f z (.t.f <Button-1> binding)} {.t.f z (.t.f <Button> binding)}}
test bind-13.10 {Tk_BindEvent procedure: don't ignore NotifyInferior - bug 47d4f29159} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Enter> "lappend x Enter%#"
    bind .t.f <Leave> "lappend x Leave%#"
    event generate .t.f <Enter> -serial 100 -detail NotifyAncestor
    event generate .t.f <Enter> -serial 101 -detail NotifyInferior
    event generate .t.f <Leave> -serial 102 -detail NotifyAncestor
    event generate .t.f <Leave> -serial 103 -detail NotifyInferior
    return $x
} -cleanup {
    destroy .t.f
} -result {Enter100 Enter101 Leave102 Leave103}
test bind-13.11 {Tk_BindEvent procedure: collapse Motions} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x Key%K"
    bind .t.f <KeyRelease> "lappend x Release%K"
    event generate .t.f <Key> -keysym colon
    event generate .t.f <KeyRelease> -keysym colon
    return $x
} -cleanup {
    destroy .t.f
} -result {Keycolon Releasecolon}
test bind-13.14 {Tk_BindEvent procedure: invalid key detail} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {







|
|



|







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
    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 :
    event generate .t.f <KeyRelease> -keysym :
    return $x
} -cleanup {
    destroy .t.f
} -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 {
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
    bind Test <Button-2> {}
    proc bgerror args {}
} -result {b1 {invalid command name "blap"}}

test bind-15.1 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f

    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <KeyRelease-1>
    event generate .t.f <Key-2>
    event generate .t.f <KeyRelease-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.2 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f

    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <Enter>







>
















>







1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
    bind Test <Button-2> {}
    proc bgerror args {}
} -result {b1 {invalid command name "blap"}}

test bind-15.1 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update idletasks
    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <KeyRelease-1>
    event generate .t.f <Key-2>
    event generate .t.f <KeyRelease-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.2 {MatchPatterns procedure, ignoring type mismatches} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update idletasks
    focus -force .t.f
    update
} -body {
    bind .t.f 12 {set x 1}
    set x 0
    event generate .t.f <Key-1>
    event generate .t.f <Enter>
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
    event delete <<V1>> <Button>
    event delete <<V2>> <Button-1>
    event delete <<V3>> <Shift-Button-1>
} -result {V2102 V2103 V2105 Shift-Button-1}
test bind-15.27 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f

    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x 0}
    bind .t.f 1 {set x 1}
    set x none
    event generate .t.f <Key-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.28 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f

    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x 0}
    bind .t.f 1 {set x 1}
    set x none
    event generate .t.f <Key-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.29 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f

    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {lappend x 0}
    bind .t.f 1 {lappend x 1}
    bind .t.f 21 {lappend x 2}
    set x none







>














>














>







1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
    event delete <<V1>> <Button>
    event delete <<V2>> <Button-1>
    event delete <<V3>> <Shift-Button-1>
} -result {V2102 V2103 V2105 Shift-Button-1}
test bind-15.27 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update idletasks
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x 0}
    bind .t.f 1 {set x 1}
    set x none
    event generate .t.f <Key-1>
    return $x
} -cleanup {
    destroy .t.f
} -result 1
test bind-15.28 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update idletasks
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {set x 0}
    bind .t.f 1 {set x 1}
    set x none
    event generate .t.f <Key-2>
    return $x
} -cleanup {
    destroy .t.f
} -result 0
test bind-15.29 {MatchPatterns procedure, conflict resolution} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    update idletasks
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> {lappend x 0}
    bind .t.f 1 {lappend x 1}
    bind .t.f 21 {lappend x 2}
    set x none
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
    event generate .t.f <braceleft> -state 1
    event generate .t.f <Multi_key>
    event generate .t.f <e>
    event generate .t.f <apostrophe>
    set x
} -cleanup {
    destroy .t.f
} -result {a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} \xE9}
test bind-16.36 {ExpandPercents procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Configure> {set x "%B"}







|







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} {{}} {{}} { } {\$} \\\{ {{}} {{}} é}
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"}
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
    list $x $y $z
} -cleanup {
    destroy .t.e
    bind Entry <Key> $savedBind(Entry)
    bind all <Key> $savedBind(All)
    unset savedBind
} -result {0 1 2}














test bind-17.1 {event command} -body {
    event
} -returnCodes error -result {wrong # args: should be "event option ?arg?"}
test bind-17.2 {event command} -body {
    event xyz
} -returnCodes error -result {bad option "xyz": must be add, delete, generate, or info}
test bind-17.3 {event command: add} -body {
    event add
} -returnCodes error -result {wrong # args: should be "event add virtual sequence ?sequence ...?"}
test bind-17.4 {event command: add 1} -body {
    event delete <<Paste>>
    event add <<Paste>> <Control-v>
    event info <<Paste>>
} -cleanup {
    event delete <<Paste>> <Control-v>
} -result {<Control-Key-v>}
test bind-17.5 {event command: add 2} -body {
    event delete <<Paste>>
    event add <<Paste>> <Control-v> <Button-2>
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>> <Control-v> <Button-2>
} -result {<Button-2> <Control-Key-v>}







>
>
>
>
>
>
>
>
>
>
>
>
>
















|







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 -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>
test bind-17.5 {event command: add 2} -body {
    event delete <<Paste>>
    event add <<Paste>> <Control-v> <Button-2>
    lsort [event info <<Paste>>]
} -cleanup {
    event delete <<Paste>> <Control-v> <Button-2>
} -result {<Button-2> <Control-Key-v>}
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
} -returnCodes error -result {bad event type or keysym "Ctrl"}
test bind-18.3 {CreateVirtualEvent procedure: new physical} -body {
    event delete <<xyz>>
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
test bind-18.4 {CreateVirtualEvent procedure: duplicate physical} -body {
    event delete <<xyz>>
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
test bind-18.5 {CreateVirtualEvent procedure: existing physical} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<abc>> <Control-v>
    list [lsort [event info]] [event info <<xyz>>] [event info <<abc>>]
} -cleanup {
    event delete <<xyz>>







|







|







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>
test bind-18.4 {CreateVirtualEvent procedure: duplicate physical} -body {
    event delete <<xyz>>
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result <Control-Key-v>
test bind-18.5 {CreateVirtualEvent procedure: existing physical} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<abc>> <Control-v>
    list [lsort [event info]] [event info <<xyz>>] [event info <<abc>>]
} -cleanup {
    event delete <<xyz>>
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
} -result {}
test bind-19.4 {DeleteVirtualEvent procedure: delete 1, not owned} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <Button-1>
    event info <<xyz>>
} -result {<Control-Key-v>}
test bind-19.5 {DeleteVirtualEvent procedure: delete 1, badly formed} -body {
    event add <<xyz>> <Control-v>
    event delete <<xyz>> <xyz>
} -cleanup {
    event delete <<xyz>>
} -returnCodes error -result {bad event type or keysym "xyz"}
test bind-19.6 {DeleteVirtualEvent procedure: delete 1, badly formed} -body {







|







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>
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 {
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
test bind-20.3 {GetVirtualEvent procedure: owns 1} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
test bind-20.4 {GetVirtualEvent procedure: owns many} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v> <Button-2> spack
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v> <Button-2> spack}


test bind-21.1 {GetAllVirtualEvents procedure: no events} -body {
    foreach p [event info] {event delete $p}
    event info
} -result {}
test bind-21.2 {GetAllVirtualEvents procedure: 1 event} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event info
} -cleanup {
    event delete <<xyz>>
} -result {<<xyz>>}
test bind-21.3 {GetAllVirtualEvents procedure: many events} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-v>
    event add <<def>> <F6>
    lsort [event info]







|




















|







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>
test bind-20.4 {GetVirtualEvent procedure: owns many} -setup {
    event delete <<xyz>>
} -body {
    event add <<xyz>> <Control-v> <Button-2> spack
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v> <Button-2> spack}


test bind-21.1 {GetAllVirtualEvents procedure: no events} -body {
    foreach p [event info] {event delete $p}
    event info
} -result {}
test bind-21.2 {GetAllVirtualEvents procedure: 1 event} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event info
} -cleanup {
    event delete <<xyz>>
} -result <<xyz>>
test bind-21.3 {GetAllVirtualEvents procedure: many events} -body {
    foreach p [event info] {event delete $p}
    event add <<xyz>> <Control-v>
    event add <<xyz>> <Button-2>
    event add <<abc>> <Control-v>
    event add <<def>> <F6>
    lsort [event info]
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %B"
    event generate .t.f <Configure> -borderwidth xyz
    return $x
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.25 {HandleEventGenerate: options <Configure> -borderwidth 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
    set x {}
} -body {
    bind .t.f <Configure> "lappend x %B"
    event generate .t.f <Configure> -borderwidth xyz
    return $x
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.25 {HandleEventGenerate: options <Configure> -borderwidth 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %h"
    event generate .t.f <Expose> -height xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.42 {HandleEventGenerate: options <Expose> -height 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %h"
    event generate .t.f <Expose> -height xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.42 {HandleEventGenerate: options <Expose> -height 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %X"
    event generate .t.f <Key> -rootx xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.74 {HandleEventGenerate: options <Key> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %X"
    event generate .t.f <Key> -rootx xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.74 {HandleEventGenerate: options <Key> -rootx 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %Y"
    event generate .t.f <Key> -rooty xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.82 {HandleEventGenerate: options <Key> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %Y"
    event generate .t.f <Key> -rooty xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.82 {HandleEventGenerate: options <Key> -rooty 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %w"
    event generate .t.f <Expose> -width xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.125 {HandleEventGenerate: options <Expose> -width 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
    update
    set x {}
} -body {
    bind .t.f <Expose> "lappend x %w"
    event generate .t.f <Expose> -width xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.125 {HandleEventGenerate: options <Expose> -width 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %x"
    event generate .t.f <Key> -x xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.140 {HandleEventGenerate: options <Key> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %x"
    event generate .t.f <Key> -x xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.140 {HandleEventGenerate: options <Key> -x 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %y"
    event generate .t.f <Key> -y xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad screen distance "xyz"}

test bind-22.152 {HandleEventGenerate: options <Key> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}







|







4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
    update
    set x {}
} -body {
    bind .t.f <Key> "lappend x %y"
    event generate .t.f <Key> -y xyz
} -cleanup {
    destroy .t.f
} -returnCodes error -result {expected screen distance but got "xyz"}

test bind-22.152 {HandleEventGenerate: options <Key> -y 2i} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
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
} -cleanup {
    destroy .t.f
} -result test
test bind-25.2 {ParseEventDescription procedure: misinterpreted modifier} -setup {
    button .b
} -body {
    bind .b <Control-M> a
    bind .b <M-M> b
    lsort [bind .b]
} -cleanup {
    destroy .b
} -result {<Control-Key-M> <Meta-Key-M>}
test bind-25.3 {ParseEventDescription procedure} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <a---> {nothing}
    bind .t.f
} -cleanup {
    destroy .t.f
} -result a
test bind-25.4 {ParseEventDescription} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <<Shift-Paste>> {puts hi}
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<<Shift-Paste>>}

# Assorted error cases in event sequence parsing
test bind-25.5 {ParseEventDescription procedure error cases} -body {
    bind .t \x7 {puts hi}
} -returnCodes error -result {bad ASCII character 0x7}
test bind-25.6 {ParseEventDescription procedure error cases} -body {
    bind .t \x7f {puts hi}







|



















|







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 <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>>

# Assorted error cases in event sequence parsing
test bind-25.5 {ParseEventDescription procedure error cases} -body {
    bind .t \x7 {puts hi}
} -returnCodes error -result {bad ASCII character 0x7}
test bind-25.6 {ParseEventDescription procedure error cases} -body {
    bind .t \x7f {puts hi}
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
} -cleanup {
    destroy .t.f
} -result <Meta-Key-a>

test bind-25.22 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <M-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Meta-Key-a>

test bind-25.23 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100







|







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 <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
5474
5475
5476
5477
5478
5479
5480

















5481
5482
5483
5484
5485
5486
5487
} -body {
    bind .t.f <Button9-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B9-Key-a>




















test bind-26.1 {event names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <FocusIn> {nothing}
    bind .t.f







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
} -body {
    bind .t.f <Button9-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <B9-Key-a>

test bind-25.54 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Num-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod3-Key-a>

test bind-25.55 {modifier names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <Fn-a> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Mod4-Key-a>


test bind-26.1 {event names} -setup {
    frame .t.f -class Test -width 150 -height 100
} -body {
    bind .t.f <FocusIn> {nothing}
    bind .t.f
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
} -cleanup {
    destroy .t.f
} -result {{event Motion} <Motion>}

test bind-26.5 {event names: Button} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> "set x {event Button}"
    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Button} <Button>}

test bind-26.6 {event names: ButtonPress} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Button> "set x {event Button}"
    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]







<
<
<
<
<
<
<
<
<
<
<
<
<
<







5555
5556
5557
5558
5559
5560
5561














5562
5563
5564
5565
5566
5567
5568
} -cleanup {
    destroy .t.f
} -result {{event Motion} <Motion>}

test bind-26.5 {event names: Button} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f














    focus -force .t.f
    update
} -body {
    bind .t.f <Button> "set x {event Button}"
    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]
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
    set x xyzzy
    event generate .t.f <Key>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Key} <Key>}

test bind-26.13 {event names: KeyPress} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <Key> "set x {event KeyPress}"
    set x xyzzy
    event generate .t.f <Key>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event KeyPress} <Key>}

test bind-26.14 {event names: KeyRelease} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <KeyRelease> "set x {event KeyRelease}"







<
<
<
<
<
<
<
<
<
<
<
<
<
<







5650
5651
5652
5653
5654
5655
5656














5657
5658
5659
5660
5661
5662
5663
    set x xyzzy
    event generate .t.f <Key>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Key} <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}"
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976

test bind-28.5 {keysym names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
} -body {
    bind .t.f <colon> "lappend x \"keysym received\""
    bind .t.f <underscore> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <colon> ;# -state 0
    set x
} -cleanup {
    destroy .t.f
} -result {: _ {keysym received}}
test bind-28.6 {keysym names} -setup {
    frame .t.f -class Test -width 150 -height 100
    pack .t.f







|
|

|







5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980

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 <:> "lappend x \"keysym received\""
    bind .t.f <_> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    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
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
    bind .t.f <x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <X> -state 1
    set x
} -cleanup {
    destroy .t.f
} -result {X x {keysym X}}
test bind-28.9 {keysym names, Eth -> ETH} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Eth> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-ETH>}
test bind-28.10 {keysym names, Ooblique -> Oslash} -constraints nodeprecated -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Ooblique> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-Oslash>}
test bind-28.11 {keysym names, gcedilla} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <gcedilla> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-gcedilla>}
test bind-28.12 {keysym names, Greek_IOTAdiaeresis -> Greek_IOTAdieresis} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Greek_IOTAdiaeresis> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result {<Key-Greek_IOTAdieresis>}























test bind-29.1 {Tcl_BackgroundError procedure} -setup {
    proc bgerror msg {
        global x errorInfo
        set x [list $msg $errorInfo]
    }







|

|



|
|

|



|






|
|





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    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, Ð} -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.10 {keysym names, Ø} -constraints deprecated -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.11 {keysym names, gcedilla} -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <gcedilla> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Key-gcedilla>
test bind-28.12 {keysym names, Greek_IOTAdiaeresis -> Greek_IOTAdieresis} -constraints deprecated -body {
    frame .t.f -class Test -width 150 -height 100
    bind .t.f <Greek_IOTAdiaeresis> foo
    bind .t.f
} -cleanup {
    destroy .t.f
} -result <Key-Greek_IOTAdieresis>
test bind-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} -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]
    }
6236
6237
6238
6239
6240
6241
6242

6243
6244
6245
6246
6247
6248
6249
    #       since DoWarp no longer exist, not even as an idle callback
    frame .t.f
    pack .t.f
    focus -force .t.f
    update
} -body {
    event generate .t.f <Button-1> -warp 1

    event generate .t.f <ButtonRelease-1>
    destroy .t.f
    update  ;  # shall simply not crash
} -cleanup {
} -result {}
test bind-32.2 {detection of double click should not fail} -setup {
    pack [frame .t.f]







>







6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
    #       since DoWarp no longer exist, not even as an idle callback
    frame .t.f
    pack .t.f
    focus -force .t.f
    update
} -body {
    event generate .t.f <Button-1> -warp 1
    controlPointerWarpTiming
    event generate .t.f <ButtonRelease-1>
    destroy .t.f
    update  ;  # shall simply not crash
} -cleanup {
} -result {}
test bind-32.2 {detection of double click should not fail} -setup {
    pack [frame .t.f]
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
    bind .t.f <Double-Button-1> { lappend x "Double" }
    bind .t.f <Button-1><Button-1> { lappend x "11" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {Double}
test bind-33.3 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <a><Double-Button-1><a> { lappend x "Double" }
    bind .t.f <a><Button-1><Button-1><a> { lappend x "11" }
    event generate .t.f <a>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result {Double}
test bind-33.4 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-1> { lappend x "11" }







|















|







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
    bind .t.f <Double-Button-1> { lappend x "Double" }
    bind .t.f <Button-1><Button-1> { lappend x "11" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result Double
test bind-33.3 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <a><Double-Button-1><a> { lappend x "Double" }
    bind .t.f <a><Button-1><Button-1><a> { lappend x "11" }
    event generate .t.f <a>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <a>
    set x
} -cleanup {
    destroy .t.f
} -result Double
test bind-33.4 {prefer most specific event} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button-1> { lappend x "11" }
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
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.10 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Double-Button-2><Button-1><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Button-2><Button-2><Double-Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.11 {should prefer most specific} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2><Double-Button-1><Double-Button-2><Double-Button-1><Button-2><Button-2> { lappend x "first" }
    bind .t.f <Button-2><Button-1><Button-1><Button-2><Button-2><Double-Button-1><Double-Button-2> { lappend x "last" }
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    set x
} -cleanup {
    destroy .t.f
} -result {first}
test bind-33.12 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Control-Button-1><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Control-Button-1> { lappend x "last" }
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.13 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Control-1> { lappend x "first" }
    bind .t.f <Control-1><Button-1> { lappend x "last" }
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
    # Old implementation failed, and returned "first", but this was wrong,
    # because both bindings are homogeneous equal, so the most recently defined
    # must be preferred.
} -result {last}
test bind-33.14 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button><Button-1><Button> { lappend x "first" }
    bind .t.f <Button><Button-1><Button><Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result {last}
test bind-33.15 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button><Button-1><Button><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Button><Button-1><Button> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
    # Old implementation failed, and returned "first", but this was wrong,
    # because both bindings are homogeneous equal, so the most recently defined
    # must be preferred.
} -result {last}
test bind-33.16 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }







|
















|




















|













|






|
|








|















|


















|







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
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result last
test bind-33.10 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Double-Button-2><Button-1><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Button-2><Button-2><Double-Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result last
test bind-33.11 {should prefer most specific} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-2><Double-Button-1><Double-Button-2><Double-Button-1><Button-2><Button-2> { lappend x "first" }
    bind .t.f <Button-2><Button-1><Button-1><Button-2><Button-2><Double-Button-1><Double-Button-2> { lappend x "last" }
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-2>
    event generate .t.f <Button-2>
    set x
} -cleanup {
    destroy .t.f
} -result first
test bind-33.12 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Control-Button-1><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Control-Button-1> { lappend x "last" }
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result last
test bind-33.13 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Control-Button-1> { lappend x "first" }
    bind .t.f <Control-Button-1><Button-1> { lappend x "last" }
    event generate .t.f <Control-Button-1>
    event generate .t.f <Control-Button-1>
    set x
} -cleanup {
    destroy .t.f
    # Old implementation failed, and returned "first", but this was wrong,
    # because both bindings are homogeneous equal, so the most recently defined
    # must be preferred.
} -result last
test bind-33.14 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button-1><Button><Button-1><Button> { lappend x "first" }
    bind .t.f <Button><Button-1><Button><Button-1> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
} -result last
test bind-33.15 {prefer last in case of homogeneous equal patterns} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Button><Button-1><Button><Button-1> { lappend x "first" }
    bind .t.f <Button-1><Button><Button-1><Button> { lappend x "last" }
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    event generate .t.f <Button-1>
    set x
} -cleanup {
    destroy .t.f
    # Old implementation failed, and returned "first", but this was wrong,
    # because both bindings are homogeneous equal, so the most recently defined
    # must be preferred.
} -result last
test bind-33.16 {simulate use of the keyboard to trigger a pattern sequence with modifier - bug [16ef161925]} -setup {
    pack [frame .t.f]
    focus -force .t.f
    update
    set x {}
} -body {
    bind .t.f <Escape><Control-c> { lappend x "Esc_Control-c" }
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
} -cleanup {
    destroy .t.f
} -result {1_Button1 1_Button1_2}

test bind-34.1 {-warp works relatively to a window} -setup {
    toplevel .top
    wm geometry .top +100+100
    update
} -body {
    # In order to avoid platform-dependent coordinate results due to
    # decorations and borders, this test warps the pointer twice
    # relatively to a window that moved in the meantime, and checks
    # how much the pointer moved
    wm geometry .top +200+200
    update
    event generate .top <Motion> -x 20 -y 20 -warp 1

    set pointerPos1 [winfo pointerxy .top]
    wm geometry .top +600+600
    update
    event generate .top <Motion> -x 20 -y 20 -warp 1

    set pointerPos2 [winfo pointerxy .top]
    # from the first warped position to the second one, the mouse
    # pointer should have moved the same amount as the window moved
    set res 1
    foreach pos1 $pointerPos1 pos2 $pointerPos2 {
        if {$pos1 != [expr {$pos2 - 400}]} {
            set res [list $pointerPos1 $pointerPos2]
        }
    }
    set res
} -cleanup {
    destroy .top
} -result 1
test bind-34.2 {-warp works relatively to the screen} -setup {
} -body {
    # Contrary to bind-34.1, we're directly checking screen coordinates
    event generate {} <Motion> -x 20 -y 20 -warp 1

    set res [winfo pointerxy .]
    event generate {} <Motion> -x 200 -y 200 -warp 1

    lappend res {*}[winfo pointerxy .]
} -cleanup {
} -result {20 20 200 200}
test bind-34.3 {-warp works with null or negative coordinates} -setup {
    # On some OS/WM, at least Linux with KDE, the "Screen edges" feature
    # provides hot spots that can be associated with some action.
    # When activated, the WM will not allow warping to happen on top of
    # a hot spot (which would trigger the corresponding action as an
    # unwanted effect) but will warp the pointer to the hot spot limit only.
    if {[tk windowingsystem] eq "x11"} {
        set halo 1
    } else {
        set halo 0
    }
    set res {}
} -body {
    event generate {} <Motion> -x 0 -y 0 -warp 1

    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    event generate {} <Motion> -x 100 -y 100 -warp 1

    event generate {} <Motion> -x -1 -y -1 -warp 1

    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }







|






|

>


|

>

















>


>

















>








>

>







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
} -cleanup {
    destroy .t.f
} -result {1_Button1 1_Button1_2}

test bind-34.1 {-warp works relatively to a window} -setup {
    toplevel .top
    wm geometry .top +100+100
    after 10 ; update
} -body {
    # In order to avoid platform-dependent coordinate results due to
    # decorations and borders, this test warps the pointer twice
    # relatively to a window that moved in the meantime, and checks
    # how much the pointer moved
    wm geometry .top +200+200
    after 10 ; update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    controlPointerWarpTiming
    set pointerPos1 [winfo pointerxy .top]
    wm geometry .top +600+600
    after 10 ; update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    controlPointerWarpTiming
    set pointerPos2 [winfo pointerxy .top]
    # from the first warped position to the second one, the mouse
    # pointer should have moved the same amount as the window moved
    set res 1
    foreach pos1 $pointerPos1 pos2 $pointerPos2 {
        if {$pos1 != [expr {$pos2 - 400}]} {
            set res [list $pointerPos1 $pointerPos2]
        }
    }
    set res
} -cleanup {
    destroy .top
} -result 1
test bind-34.2 {-warp works relatively to the screen} -setup {
} -body {
    # Contrary to bind-34.1, we're directly checking screen coordinates
    event generate {} <Motion> -x 20 -y 20 -warp 1
    controlPointerWarpTiming
    set res [winfo pointerxy .]
    event generate {} <Motion> -x 200 -y 200 -warp 1
    controlPointerWarpTiming
    lappend res {*}[winfo pointerxy .]
} -cleanup {
} -result {20 20 200 200}
test bind-34.3 {-warp works with null or negative coordinates} -setup {
    # On some OS/WM, at least Linux with KDE, the "Screen edges" feature
    # provides hot spots that can be associated with some action.
    # When activated, the WM will not allow warping to happen on top of
    # a hot spot (which would trigger the corresponding action as an
    # unwanted effect) but will warp the pointer to the hot spot limit only.
    if {[tk windowingsystem] eq "x11"} {
        set halo 1
    } else {
        set halo 0
    }
    set res {}
} -body {
    event generate {} <Motion> -x 0 -y 0 -warp 1
    controlPointerWarpTiming
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    event generate {} <Motion> -x 100 -y 100 -warp 1
    controlPointerWarpTiming
    event generate {} <Motion> -x -1 -y -1 -warp 1
    controlPointerWarpTiming
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
} -result {F2 F2}

test bind-35.3 {Events agree for modifier keys} -constraints {aqua} -setup {
} -body {
    global keyInfo numericalKeysym
    set result {}
    bind . <Key> {
    	set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k]
    	set numericalKeysym [format "0x%x" %N]
    }
    foreach event {
	{<Control_L> -control}
	{<Control_R> -control}
	{<Alt_L> -option}
	{<Alt_R> -option}
	{<Meta_L> -command}







|
|







7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
} -result {F2 F2}

test bind-35.3 {Events agree for modifier keys} -constraints {aqua} -setup {
} -body {
    global keyInfo numericalKeysym
    set result {}
    bind . <Key> {
	set keyInfo [format "%K,0x%%X,0x%%X,%A" %N %k]
	set numericalKeysym [format "0x%x" %N]
    }
    foreach event {
	{<Control_L> -control}
	{<Control_R> -control}
	{<Alt_L> -option}
	{<Alt_R> -option}
	{<Meta_L> -command}
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
    }
    return pass
} -cleanup {
} -result pass

test bind-36.1 {pointer warp with grab on toplevel, bug [e3888d5820]} -setup {
    event generate {} <Motion> -warp 1 -x 50 -y 50

    toplevel .top
    grab release .top
    wm geometry .top 200x200+300+300
    label .top.l -height 5 -width 20 -highlightthickness 2 \
            -highlightbackground black -bg yellow -text "My label"
    pack .top.l -side bottom
    update
    # On KDE/Plasma _with_the_Aurorae_theme_ (at least), setting up the toplevel
    # and the label will not be finished after the above 'update'. The WM still
    # needs some time before the window is fully ready. For me 50 ms is enough,
    # but let's wait more (it depends on computer performance).
    after 100 ; update
} -body {
    grab .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10

    foreach {x1 y1} [winfo pointerxy .top.l] {}
    event generate {} <Motion> -warp 1 -x 50 -y 50

    grab release .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10

    foreach {x2 y2} [winfo pointerxy .top.l] {}
    # success if the coords are the same with or without the grab, and if they
    # are at (10,10) inside the label widget as requested by the warping
    expr {$x1==$x2 && $y1==$y2 && $x1==[winfo rootx .top.l]+10 \
                               && $y1==[winfo rooty .top.l]+10}
} -cleanup {
    destroy .top
    unset x1 y1 x2 y2
} -result 1






















# cleanup
cleanupTests
return

# vi:set ts=4 sw=4 et:
# Local Variables:
# mode: tcl
# End:







>















>


>


>









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









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
    }
    return pass
} -cleanup {
} -result pass

test bind-36.1 {pointer warp with grab on toplevel, bug [e3888d5820]} -setup {
    event generate {} <Motion> -warp 1 -x 50 -y 50
    controlPointerWarpTiming
    toplevel .top
    grab release .top
    wm geometry .top 200x200+300+300
    label .top.l -height 5 -width 20 -highlightthickness 2 \
            -highlightbackground black -bg yellow -text "My label"
    pack .top.l -side bottom
    update
    # On KDE/Plasma _with_the_Aurorae_theme_ (at least), setting up the toplevel
    # and the label will not be finished after the above 'update'. The WM still
    # needs some time before the window is fully ready. For me 50 ms is enough,
    # but let's wait more (it depends on computer performance).
    after 100 ; update
} -body {
    grab .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10
    controlPointerWarpTiming
    foreach {x1 y1} [winfo pointerxy .top.l] {}
    event generate {} <Motion> -warp 1 -x 50 -y 50
    controlPointerWarpTiming
    grab release .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10
    controlPointerWarpTiming
    foreach {x2 y2} [winfo pointerxy .top.l] {}
    # success if the coords are the same with or without the grab, and if they
    # are at (10,10) inside the label widget as requested by the warping
    expr {$x1==$x2 && $y1==$y2 && $x1==[winfo rootx .top.l]+10 \
                               && $y1==[winfo rooty .top.l]+10}
} -cleanup {
    destroy .top
    unset x1 y1 x2 y2
} -result 1

test bind-37.1 {Promotion tables do not contain duplicate sequences, bug [43573999ca]} -body {
    proc A {} {
       bind .c <B1-Motion><Enter> {}
       set myv(a) 1
       set b [array get myv]
       bind .c <B1-Motion><Enter> "puts Trigger"
    }
    pack [canvas .c]
    bind .c <ButtonRelease-1>  "A"
    A
    update
    event generate .c <Button-1>
    event generate .c <B1-Motion>
    event generate .c <B1-Motion>
    event generate .c <B1-Motion>
    event generate .c <ButtonRelease-1>
    event generate .c <B1-Motion>
} -cleanup {
    destroy .c
} -returnCodes ok -result {}  ; # shall not crash (assertion failed)

# cleanup
cleanupTests
return

# vi:set ts=4 sw=4 et:
# Local Variables:
# mode: tcl
# End:

Changes to tests/bitmap.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkBitmap.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkBitmap.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# This file is a Tcl script to test out the procedures in the file
# tkBorder.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out the procedures in the file
# tkBorder.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# Tests for the tk busy command.
#
# This file contains a collection of tests for one or more of the Tk built-in
# commands. Sourcing this file runs the tests and generates output for errors.
# No output means no errors were found.
#
# Copyright © 1998-2000 by Jos Decoster. All rights reserved.

package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# There's currently no way to test the actual grab effect, per se, in an






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Tests for the tk busy command.
#
# This file contains a collection of tests for one or more of the Tk built-in
# commands. Sourcing this file runs the tests and generates output for errors.
# No output means no errors were found.
#
# Copyright © 1998-2000 Jos Decoster. All rights reserved.

package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# There's currently no way to test the actual grab effect, per se, in an

Changes to tests/butGeom2.tcl.

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
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 {} {










|







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 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
# This file is a Tcl script to test labels, buttons, checkbuttons, and
# radiobuttons in Tk (i.e., all the widgets defined in tkButton.c).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test labels, buttons, checkbuttons, and
# radiobuttons in Tk (i.e., all the widgets defined in tkButton.c).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bd badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.35 {configuration option: "bd" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bd 4
    .b cget -bd
} -cleanup {
    destroy .b
} -result 4
test button-1.36 {configuration option: "bd" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bd badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.37 {configuration option: "bd" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bd 4
    .c cget -bd
} -cleanup {
    destroy .c
} -result 4
test button-1.38 {configuration option: "bd" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bd badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.39 {configuration option: "bd" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bd 4
    .r cget -bd
} -cleanup {
    destroy .r
} -result 4
test button-1.40 {configuration option: "bd" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bd badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "badValue"}

test button-1.41 {configuration option: "bg" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bg #ff0000







|


















|


















|


















|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bd badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.35 {configuration option: "bd" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bd 4
    .b cget -bd
} -cleanup {
    destroy .b
} -result 4
test button-1.36 {configuration option: "bd" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -bd badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.37 {configuration option: "bd" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bd 4
    .c cget -bd
} -cleanup {
    destroy .c
} -result 4
test button-1.38 {configuration option: "bd" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -bd badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.39 {configuration option: "bd" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bd 4
    .r cget -bd
} -cleanup {
    destroy .r
} -result 4
test button-1.40 {configuration option: "bd" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -bd badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test button-1.41 {configuration option: "bg" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -bg #ff0000
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -borderwidth badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.59 {configuration option: "borderwidth" for button} -setup {
    button .b -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -borderwidth 1.3
    .b cget -borderwidth
} -cleanup {
    destroy .b
} -result {1.3}
test button-1.60 {configuration option: "borderwidth" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -borderwidth badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.61 {configuration option: "borderwidth" for checkbutton} -setup {
    checkbutton .c -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -borderwidth 1.3
    .c cget -borderwidth
} -cleanup {
    destroy .c
} -result {1.3}
test button-1.62 {configuration option: "borderwidth" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -borderwidth badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.63 {configuration option: "borderwidth" for radiobutton} -setup {
    radiobutton .r -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -borderwidth 1.3
    .r cget -borderwidth
} -cleanup {
    destroy .r
} -result {1.3}
test button-1.64 {configuration option: "borderwidth" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -borderwidth badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "badValue"}

test button-1.65 {configuration option: "command" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -command {set x}







|


















|


















|


















|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -borderwidth badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.59 {configuration option: "borderwidth" for button} -setup {
    button .b -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -borderwidth 1.3
    .b cget -borderwidth
} -cleanup {
    destroy .b
} -result {1.3}
test button-1.60 {configuration option: "borderwidth" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -borderwidth badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.61 {configuration option: "borderwidth" for checkbutton} -setup {
    checkbutton .c -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -borderwidth 1.3
    .c cget -borderwidth
} -cleanup {
    destroy .c
} -result {1.3}
test button-1.62 {configuration option: "borderwidth" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -borderwidth badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.63 {configuration option: "borderwidth" for radiobutton} -setup {
    radiobutton .r -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -borderwidth 1.3
    .r cget -borderwidth
} -cleanup {
    destroy .r
} -result {1.3}
test button-1.64 {configuration option: "borderwidth" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -borderwidth badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test button-1.65 {configuration option: "command" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -command {set x}
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightthickness badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.145 {configuration option: "highlightthickness" for button} -setup {
    button .b -borderwidth 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightthickness 6m
    .b cget -highlightthickness
} -cleanup {
    destroy .b
} -result {6m}
test button-1.146 {configuration option: "highlightthickness" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightthickness badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.147 {configuration option: "highlightthickness" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightthickness 6m
    .c cget -highlightthickness
} -cleanup {
    destroy .c
} -result {6m}
test button-1.148 {configuration option: "highlightthickness" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightthickness badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "badValue"}
test button-1.149 {configuration option: "highlightthickness" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightthickness 6m
    .r cget -highlightthickness
} -cleanup {
    destroy .r
} -result {6m}
test button-1.150 {configuration option: "highlightthickness" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightthickness badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "badValue"}

test button-1.151 {configuration option: "image" for label} -constraints {
    testImageType
} -setup {
    image create test image1
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l







|


















|


















|


















|







1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -highlightthickness badValue
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.145 {configuration option: "highlightthickness" for button} -setup {
    button .b -borderwidth 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightthickness 6m
    .b cget -highlightthickness
} -cleanup {
    destroy .b
} -result {6m}
test button-1.146 {configuration option: "highlightthickness" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -highlightthickness badValue
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.147 {configuration option: "highlightthickness" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightthickness 6m
    .c cget -highlightthickness
} -cleanup {
    destroy .c
} -result {6m}
test button-1.148 {configuration option: "highlightthickness" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -highlightthickness badValue
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected screen distance but got "badValue"}
test button-1.149 {configuration option: "highlightthickness" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightthickness 6m
    .r cget -highlightthickness
} -cleanup {
    destroy .r
} -result {6m}
test button-1.150 {configuration option: "highlightthickness" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -highlightthickness badValue
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test button-1.151 {configuration option: "image" for label} -constraints {
    testImageType
} -setup {
    image create test image1
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
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
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -overrelief 1.5
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.179 {configuration option: "overrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -overrelief ""
    .c cget -overrelief
} -cleanup {
    destroy .c
} -result {}
test button-1.180 {configuration option: "overrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -overrelief 1.5
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test button-1.181 {configuration option: "overrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -overrelief ""
    .r cget -overrelief
} -cleanup {
    destroy .r
} -result {}
test button-1.182 {configuration option: "overrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -overrelief 1.5
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}

test button-1.183 {configuration option: "padx" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -padx 12m
    .l cget -padx
} -cleanup {
    destroy .l
} -result {12m}
test button-1.184 {configuration option: "padx" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -padx 420x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.185 {configuration option: "padx" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -padx 12m
    .b cget -padx
} -cleanup {
    destroy .b
} -result {12m}
test button-1.186 {configuration option: "padx" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -padx 420x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.187 {configuration option: "padx" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -padx 12m
    .c cget -padx
} -cleanup {
    destroy .c
} -result {12m}
test button-1.188 {configuration option: "padx" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -padx 420x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.189 {configuration option: "padx" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -padx 12m
    .r cget -padx
} -cleanup {
    destroy .r
} -result {12m}
test button-1.190 {configuration option: "padx" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -padx 420x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "420x"}

test button-1.191 {configuration option: "pady" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -pady 12m
    .l cget -pady
} -cleanup {
    destroy .l
} -result {12m}
test button-1.192 {configuration option: "pady" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -pady 420x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.193 {configuration option: "pady" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -pady 12m
    .b cget -pady
} -cleanup {
    destroy .b
} -result {12m}
test button-1.194 {configuration option: "pady" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -pady 420x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.195 {configuration option: "pady" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -pady 12m
    .c cget -pady
} -cleanup {
    destroy .c
} -result {12m}
test button-1.196 {configuration option: "pady" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -pady 420x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "420x"}
test button-1.197 {configuration option: "pady" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -pady 12m
    .r cget -pady
} -cleanup {
    destroy .r
} -result {12m}
test button-1.198 {configuration option: "pady" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -pady 420x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "420x"}

test button-1.199 {configuration option: "repeatdelay" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -repeatdelay 100







|


















|


















|



















|


















|


















|


















|



















|


















|


















|


















|







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
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -overrelief 1.5
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, sunken, or ""}
test button-1.179 {configuration option: "overrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -overrelief ""
    .c cget -overrelief
} -cleanup {
    destroy .c
} -result {}
test button-1.180 {configuration option: "overrelief" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -overrelief 1.5
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, sunken, or ""}
test button-1.181 {configuration option: "overrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -overrelief ""
    .r cget -overrelief
} -cleanup {
    destroy .r
} -result {}
test button-1.182 {configuration option: "overrelief" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -overrelief 1.5
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, sunken, or ""}

test button-1.183 {configuration option: "padx" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -padx 12m
    .l cget -padx
} -cleanup {
    destroy .l
} -result {12m}
test button-1.184 {configuration option: "padx" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -padx 420x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected screen distance but got "420x"}
test button-1.185 {configuration option: "padx" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -padx 12m
    .b cget -padx
} -cleanup {
    destroy .b
} -result {12m}
test button-1.186 {configuration option: "padx" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -padx 420x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected screen distance but got "420x"}
test button-1.187 {configuration option: "padx" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -padx 12m
    .c cget -padx
} -cleanup {
    destroy .c
} -result {12m}
test button-1.188 {configuration option: "padx" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -padx 420x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected screen distance but got "420x"}
test button-1.189 {configuration option: "padx" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -padx 12m
    .r cget -padx
} -cleanup {
    destroy .r
} -result {12m}
test button-1.190 {configuration option: "padx" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -padx 420x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected screen distance but got "420x"}

test button-1.191 {configuration option: "pady" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -pady 12m
    .l cget -pady
} -cleanup {
    destroy .l
} -result {12m}
test button-1.192 {configuration option: "pady" for label} -setup {
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -pady 420x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected screen distance but got "420x"}
test button-1.193 {configuration option: "pady" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -pady 12m
    .b cget -pady
} -cleanup {
    destroy .b
} -result {12m}
test button-1.194 {configuration option: "pady" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -pady 420x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected screen distance but got "420x"}
test button-1.195 {configuration option: "pady" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -pady 12m
    .c cget -pady
} -cleanup {
    destroy .c
} -result {12m}
test button-1.196 {configuration option: "pady" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -pady 420x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected screen distance but got "420x"}
test button-1.197 {configuration option: "pady" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -pady 12m
    .r cget -pady
} -cleanup {
    destroy .r
} -result {12m}
test button-1.198 {configuration option: "pady" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -pady 420x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected screen distance but got "420x"}

test button-1.199 {configuration option: "repeatdelay" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -repeatdelay 100
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
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -underline 3p
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.245 {configuration option: "underline" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -underline 5
    .b cget -underline
} -cleanup {
    destroy .b
} -result 5
test button-1.246 {configuration option: "underline" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -underline 3p
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.247 {configuration option: "underline" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -underline 5
    .c cget -underline
} -cleanup {
    destroy .c
} -result 5
test button-1.248 {configuration option: "underline" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -underline 3p
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected integer but got "3p"}
test button-1.249 {configuration option: "underline" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -underline 5
    .r cget -underline
} -cleanup {
    destroy .r
} -result 5
test button-1.250 {configuration option: "underline" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -underline 3p
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected integer but got "3p"}

test button-1.251 {configuration option: "tristatevalue" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -tristatevalue unknowable







|


















|


















|


















|







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
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -underline 3p
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}
test button-1.245 {configuration option: "underline" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -underline 5
    .b cget -underline
} -cleanup {
    destroy .b
} -result 5
test button-1.246 {configuration option: "underline" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -underline 3p
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}
test button-1.247 {configuration option: "underline" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -underline 5
    .c cget -underline
} -cleanup {
    destroy .c
} -result 5
test button-1.248 {configuration option: "underline" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -underline 3p
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}
test button-1.249 {configuration option: "underline" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -underline 5
    .r cget -underline
} -cleanup {
    destroy .r
} -result 5
test button-1.250 {configuration option: "underline" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -underline 3p
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}

test button-1.251 {configuration option: "tristatevalue" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -tristatevalue unknowable
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
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -wraplength 6x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {bad screen distance "6x"}
test button-1.264 {configuration option: "wraplength" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -wraplength 100
    .b cget -wraplength
} -cleanup {
    destroy .b
} -result 100
test button-1.265 {configuration option: "wraplength" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -wraplength 6x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {bad screen distance "6x"}
test button-1.266 {configuration option: "wraplength" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -wraplength 100
    .c cget -wraplength
} -cleanup {
    destroy .c
} -result 100
test button-1.267 {configuration option: "wraplength" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -wraplength 6x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {bad screen distance "6x"}
test button-1.268 {configuration option: "wraplength" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -wraplength 100
    .r cget -wraplength
} -cleanup {
    destroy .r
} -result 100
test button-1.269 {configuration option: "wraplength" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -wraplength 6x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {bad screen distance "6x"}

test button-1.270 {configuration options} -body {
# Additional check to make sure that -selectcolor may be empty in
# checkbox widgets
    checkbutton .c
    .c configure -selectcolor {}
} -cleanup {







|


















|


















|


















|







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
    label .l -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .l
    update
} -body {
    .l configure -wraplength 6x
} -cleanup {
    destroy .l
} -returnCodes {error} -result {expected screen distance but got "6x"}
test button-1.264 {configuration option: "wraplength" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -wraplength 100
    .b cget -wraplength
} -cleanup {
    destroy .b
} -result 100
test button-1.265 {configuration option: "wraplength" for button} -setup {
    button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .b
    update
} -body {
    .b configure -wraplength 6x
} -cleanup {
    destroy .b
} -returnCodes {error} -result {expected screen distance but got "6x"}
test button-1.266 {configuration option: "wraplength" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -wraplength 100
    .c cget -wraplength
} -cleanup {
    destroy .c
} -result 100
test button-1.267 {configuration option: "wraplength" for checkbutton} -setup {
    checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .c
    update
} -body {
    .c configure -wraplength 6x
} -cleanup {
    destroy .c
} -returnCodes {error} -result {expected screen distance but got "6x"}
test button-1.268 {configuration option: "wraplength" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -wraplength 100
    .r cget -wraplength
} -cleanup {
    destroy .r
} -result 100
test button-1.269 {configuration option: "wraplength" for radiobutton} -setup {
    radiobutton .r -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .r
    update
} -body {
    .r configure -wraplength 6x
} -cleanup {
    destroy .r
} -returnCodes {error} -result {expected screen distance but got "6x"}

test button-1.270 {configuration options} -body {
# Additional check to make sure that -selectcolor may be empty in
# checkbox widgets
    checkbutton .c
    .c configure -selectcolor {}
} -cleanup {
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
} -cleanup {
    destroy .r
} -result {}

test button-3.24 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    trace variable checkvar w bogusTrace
    .c deselect
} -cleanup {
    destroy .c
    trace vdelete checkvar w bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.25 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    trace variable checkvar w bogusTrace
    catch {.c deselect}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c deselect"} 0}
test button-3.26 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    trace variable radiovar w bogusTrace
    .r deselect
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match {glob} -returnCodes {error} -result {can't set "radiovar": trace aborted}
test button-3.27 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    trace variable radiovar w bogusTrace
    catch {.r deselect}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match glob -result {{*trace aborted
    while executing
*
".r deselect"} {}}

test button-3.28 {ButtonWidgetCmd procedure, "flash" option} -body {
    button .b







|



|




|



|








|



|




|




|







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
} -cleanup {
    destroy .r
} -result {}

test button-3.24 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    trace add variable checkvar write bogusTrace
    .c deselect
} -cleanup {
    destroy .c
    trace remove variable checkvar write bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.25 {ButtonWidgetCmd procedure, "deselect" option} -body {
    checkbutton .c -variable checkvar -onvalue 1 -offvalue 0
    set checkvar 1
    trace add variable checkvar write bogusTrace
    catch {.c deselect}
    list $errorInfo $checkvar
} -cleanup {
    trace remove variable checkvar write bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c deselect"} 0}
test button-3.26 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    trace add variable radiovar write bogusTrace
    .r deselect
} -cleanup {
    destroy .r
    trace remove variable radiovar write bogusTrace
} -match {glob} -returnCodes {error} -result {can't set "radiovar": trace aborted}
test button-3.27 {ButtonWidgetCmd procedure, "deselect" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar red
    trace add variable radiovar write bogusTrace
    catch {.r deselect}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace remove variable radiovar write bogusTrace
} -match glob -result {{*trace aborted
    while executing
*
".r deselect"} {}}

test button-3.28 {ButtonWidgetCmd procedure, "flash" option} -body {
    button .b
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
    return $radiovar
} -cleanup {
    destroy .r
} -result  {red}
test button-3.44 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar yellow
    trace variable radiovar w bogusTrace
    .r select
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -returnCodes {error} -result {can't set "radiovar": trace aborted}
test button-3.45 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar yellow
    trace variable radiovar w bogusTrace
    catch {.r select}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match {glob} -result {{*trace aborted
    while executing
*
".r select"} red}

# ex 4.43
test button-3.46 {ButtonWidgetCmd procedure, "toggle" option} -body {







|



|




|




|







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
    return $radiovar
} -cleanup {
    destroy .r
} -result  {red}
test button-3.44 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar yellow
    trace add variable radiovar write bogusTrace
    .r select
} -cleanup {
    destroy .r
    trace remove variable radiovar write bogusTrace
} -returnCodes {error} -result {can't set "radiovar": trace aborted}
test button-3.45 {ButtonWidgetCmd procedure, "select" option} -body {
    radiobutton .r -variable radiovar -value red
    set radiovar yellow
    trace add variable radiovar write bogusTrace
    catch {.r select}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace remove variable radiovar write bogusTrace
} -match {glob} -result {{*trace aborted
    while executing
*
".r select"} red}

# ex 4.43
test button-3.46 {ButtonWidgetCmd procedure, "toggle" option} -body {
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
    return $result
} -cleanup {
    destroy .c
} -result {sunshine rain sunshine}
test button-3.51 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar xyz
    trace variable checkvar w bogusTrace
    .c toggle
} -cleanup {
    destroy .c
    trace vdelete checkvar w bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.52 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar xyz
    trace variable checkvar w bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c toggle"} abc}
test button-3.53 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar abc
    trace variable checkvar w bogusTrace
    .c toggle
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.54 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar abc
    trace variable checkvar w bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c toggle"} xyz}
test button-3.55 {ButtonWidgetCmd procedure, "toggle" option} -setup {
    unset -nocomplain checkvar







|



|




|



|








|


|





|



|







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
    return $result
} -cleanup {
    destroy .c
} -result {sunshine rain sunshine}
test button-3.51 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar xyz
    trace add variable checkvar write bogusTrace
    .c toggle
} -cleanup {
    destroy .c
    trace remove variable checkvar write bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.52 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar xyz
    trace add variable checkvar write bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace remove variable checkvar write bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c toggle"} abc}
test button-3.53 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar abc
    trace add variable checkvar write bogusTrace
    .c toggle
} -cleanup {
    trace remove variable checkvar write bogusTrace
    destroy .c
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
test button-3.54 {ButtonWidgetCmd procedure, "toggle" option} -body {
    checkbutton .c -variable checkvar -onvalue xyz -offvalue abc
    set checkvar abc
    trace add variable checkvar write bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace remove variable checkvar write bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
    while executing
*
".c toggle"} xyz}
test button-3.55 {ButtonWidgetCmd procedure, "toggle" option} -setup {
    unset -nocomplain checkvar
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
} -cleanup {
    destroy .r
} -result {}

test button-5.10 {ConfigureButton - error in setting variable} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    radiobutton .r -variable x
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}

test button-5.11 {ConfigureButton - bad image name} -body {
    button .b -image bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {image "bogus" doesn't exist}







|



|







3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
} -cleanup {
    destroy .r
} -result {}

test button-5.10 {ConfigureButton - error in setting variable} -setup {
    unset -nocomplain x
} -body {
    trace add variable x write bogusTrace
    radiobutton .r -variable x
} -cleanup {
    destroy .r
    trace remove variable x write bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}

test button-5.11 {ConfigureButton - bad image name} -body {
    button .b -image bogus
} -cleanup {
    destroy .b
} -returnCodes {error} -result {image "bogus" doesn't exist}
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
} -cleanup {
    destroy .b
} -result {Override}

test button-5.14 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    radiobutton .r -text foo -textvariable x
} -cleanup {
    trace vdelete x w bogusTrace
    destroy .r
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-5.15 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    catch {radiobutton .r -text foo -textvariable x}
	return $x
} -cleanup {
    trace vdelete x w bogusTrace
    destroy .r
} -result {foo}

#ex 6.14
test button-5.16 {ConfigureButton - -width option} -body {
    button .b -text "Button 1"
    .b configure -width 1i







|


|





|



|







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
} -cleanup {
    destroy .b
} -result {Override}

test button-5.14 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace add variable x write bogusTrace
    radiobutton .r -text foo -textvariable x
} -cleanup {
    trace remove variable x write bogusTrace
    destroy .r
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-5.15 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace add variable x write bogusTrace
    catch {radiobutton .r -text foo -textvariable x}
	return $x
} -cleanup {
    trace remove variable x write bogusTrace
    destroy .r
} -result {foo}

#ex 6.14
test button-5.16 {ConfigureButton - -width option} -body {
    button .b -text "Button 1"
    .b configure -width 1i
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
".b configure -height 0.5c"}
#ex 6.16
test button-5.20 {ConfigureButton - -width option} -body {
    button .b -bitmap questhead
    .b configure -width abc
} -cleanup {
    destroy .b
} -returnCodes {error} -result  {bad screen distance "abc"}
test button-5.21 {ConfigureButton - -width option} -body {
    button .b -bitmap questhead
    catch {.b configure -width abc}
    return $errorInfo
} -cleanup {
    destroy .b
} -result {bad screen distance "abc"
    (processing -width option)
    invoked from within
".b configure -width abc"}
test button-5.22 {ConfigureButton - -height option} -constraints {
    testImageType
} -setup {
    image create test image1
} -body {
    button .b -image image1
    .b configure -height 0.5x
} -cleanup {
    destroy .b
    image delete image1
} -returnCodes {error} -result {bad screen distance "0.5x"}
test button-5.23 {ConfigureButton - -height option} -constraints {
    testImageType
} -setup {
    image create test image1
} -body {
#ztestImageType
    button .b -image image1
    catch {.b configure -height 0.5x}
    return $errorInfo
} -cleanup {
    destroy .b
    image delete image1
} -result  {bad screen distance "0.5x"
    (processing -height option)
    invoked from within
".b configure -height 0.5x"}
#ex 6.18
test button-5.24 {ConfigureButton - computing geometry} -constraints {
    fonts
} -body {







|






|













|












|







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
".b configure -height 0.5c"}
#ex 6.16
test button-5.20 {ConfigureButton - -width option} -body {
    button .b -bitmap questhead
    .b configure -width abc
} -cleanup {
    destroy .b
} -returnCodes {error} -result  {expected screen distance but got "abc"}
test button-5.21 {ConfigureButton - -width option} -body {
    button .b -bitmap questhead
    catch {.b configure -width abc}
    return $errorInfo
} -cleanup {
    destroy .b
} -result {expected screen distance but got "abc"
    (processing -width option)
    invoked from within
".b configure -width abc"}
test button-5.22 {ConfigureButton - -height option} -constraints {
    testImageType
} -setup {
    image create test image1
} -body {
    button .b -image image1
    .b configure -height 0.5x
} -cleanup {
    destroy .b
    image delete image1
} -returnCodes {error} -result {expected screen distance but got "0.5x"}
test button-5.23 {ConfigureButton - -height option} -constraints {
    testImageType
} -setup {
    image create test image1
} -body {
#ztestImageType
    button .b -image image1
    catch {.b configure -height 0.5x}
    return $errorInfo
} -cleanup {
    destroy .b
    image delete image1
} -result  {expected screen distance but got "0.5x"
    (processing -height option)
    invoked from within
".b configure -height 0.5x"}
#ex 6.18
test button-5.24 {ConfigureButton - computing geometry} -constraints {
    fonts
} -body {
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
    destroy .c
} -result {0 1 0}

test button-8.2 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.3 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -result 1
test button-8.4 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.5 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -result 0

test button-8.6 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    radiobutton .r -variable x -value red
    set result $x
    .r invoke
    lappend result $x
    .r invoke
    lappend result $x
} -cleanup {
    destroy .r
} -result {0 red red}

test button-8.7 {TkInvokeButton procedure} -body {
    radiobutton .r -variable x -value red
    set x green
    trace variable x w bogusTrace
    .r invoke
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.8 {TkInvokeButton procedure} -body {
    radiobutton .r -variable x -value red
    set x green
    trace variable x w bogusTrace
    catch {.r invoke}
    list $errorInfo $x
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -match {glob} -result {{*trace aborted
    while executing
*
".r invoke"} red}

#ex 9.6
test button-8.9 {TkInvokeButton procedure} -setup {







|



|





|




|





|



|





|




|


















|



|




|




|







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
    destroy .c
} -result {0 1 0}

test button-8.2 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    checkbutton .c -variable x
    trace add variable x write bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace remove variable x write bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.3 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    checkbutton .c -variable x
    trace add variable x write bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace remove variable x write bogusTrace
} -result 1
test button-8.4 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace add variable x write bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace remove variable x write bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.5 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace add variable x write bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace remove variable x write bogusTrace
} -result 0

test button-8.6 {TkInvokeButton procedure} -setup {
    set x 0
} -body {
    radiobutton .r -variable x -value red
    set result $x
    .r invoke
    lappend result $x
    .r invoke
    lappend result $x
} -cleanup {
    destroy .r
} -result {0 red red}

test button-8.7 {TkInvokeButton procedure} -body {
    radiobutton .r -variable x -value red
    set x green
    trace add variable x write bogusTrace
    .r invoke
} -cleanup {
    destroy .r
    trace remove variable x write bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
test button-8.8 {TkInvokeButton procedure} -body {
    radiobutton .r -variable x -value red
    set x green
    trace add variable x write bogusTrace
    catch {.r invoke}
    list $errorInfo $x
} -cleanup {
    destroy .r
    trace remove variable x write bogusTrace
} -match {glob} -result {{*trace aborted
    while executing
*
".r invoke"} red}

#ex 9.6
test button-8.9 {TkInvokeButton procedure} -setup {

Changes to tests/canvImg.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the procedures in tkCanvImg.c,
# which implement canvas "image" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the procedures in tkCanvImg.c,
# which implement canvas "image" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
} -cleanup {
    .c delete all
} -result {center {} {}}
test canvImg-2.4 {CreateImage procedure} -body {
    .c create image xyz 40
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvImg-2.5 {CreateImage procedure} -body {
    .c create image 50 qrs
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "qrs"}
test canvImg-2.6 {CreateImage procedure} -constraints testImageType -body {
    .c create image 50 50 -gorp foo
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "-gorp"}









|




|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
} -cleanup {
    .c delete all
} -result {center {} {}}
test canvImg-2.4 {CreateImage procedure} -body {
    .c create image xyz 40
} -cleanup {
    .c delete all
} -returnCodes {error} -result {expected screen distance but got "xyz"}
test canvImg-2.5 {CreateImage procedure} -body {
    .c create image 50 qrs
} -cleanup {
    .c delete all
} -returnCodes {error} -result {expected screen distance but got "qrs"}
test canvImg-2.6 {CreateImage procedure} -constraints testImageType -body {
    .c create image 50 50 -gorp foo
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "-gorp"}


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
	image create test foo
} -body {
    .c create image 50 100 -image foo -tags i1
    .c coords i1 dumb 100
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {bad screen distance "dumb"}
test canvImg-3.3 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250 dumb0
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {bad screen distance "dumb0"}
test canvImg-3.4 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250
} -cleanup {







|









|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
	image create test foo
} -body {
    .c create image 50 100 -image foo -tags i1
    .c coords i1 dumb 100
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {expected screen distance but got "dumb"}
test canvImg-3.3 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250 dumb0
} -cleanup {
	.c delete all
	image delete foo
} -returnCodes {error} -result {expected screen distance but got "dumb0"}
test canvImg-3.4 {ImageCoords procedure} -constraints testImageType -setup {
	image create test foo
} -body {
    .c delete all
    .c create image 50 100 -image foo -tags i1
    .c coords i1 250
} -cleanup {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}
    set timer [after 300 {lappend y "timed out"}]
    .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
    }







|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}
    set timer [after 500 {lappend y "timed out"}]
    .c itemconfigure i1 -image foo2
    update idletasks
    update
    # On MacOS we need to wait for the test image display procedure to run.
    while {"timed out" ni $y && [lindex $y end 1] ne "display"} {
        vwait y
    }
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    .c create image 20 30 -image foo -tags i1 -anchor center
    .c bbox i1
} -cleanup {
    .c delete all
    image delete foo
} -result {5 23 35 38}

# The following test is non-portable because of differences in
# coordinate rounding on some machines (does 0.5 round  up?).

test canvImg-7.1 {DisplayImage procedure} -constraints {
	nonPortable testImageType
} -setup {
    .c delete all
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
    set x
} -result {{foo display 4 9 12 6 30 30}}
test canvImg-7.2 {DisplayImage procedure, no image} -body {
    .c delete all
    .c create image 50 100 -tags i1
    update
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
} -result {}







<
<
<

|










|







357
358
359
360
361
362
363



364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
    .c create image 20 30 -image foo -tags i1 -anchor center
    .c bbox i1
} -cleanup {
    .c delete all
    image delete foo
} -result {5 23 35 38}




test canvImg-7.1 {DisplayImage procedure} -constraints {
    testImageType
} -setup {
    .c delete all
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
    set x
} -result {{foo display 4 9 12 6}}
test canvImg-7.2 {DisplayImage procedure, no image} -body {
    .c delete all
    .c create image 50 100 -tags i1
    update
    .c create rect 55 110 65 115 -width 1 -outline black -fill white
    update
} -result {}

Changes to tests/canvMoveto.test.

1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out the canvas "moveto" command. It is
# derived from canvRect.test.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2004 Neil McKay.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out the canvas "moveto" command. It is
# derived from canvRect.test.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 2004 Neil McKay.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    .c moveto rect
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.3 {Bad args handling for "moveto" command} -body {
    .c moveto test 12
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.4 {Bad args handling for "moveto" command} -body {
    .c moveto test 12 y
} -returnCodes error -result {bad screen distance "y"}
test canvMoveto-1.5 {Bad args handling for "moveto" command} -body {
    .c moveto test 12 20 -anchor
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}

test canvMoveto-2.1 {Canvas "moveto" command coordinates} {
    .c moveto test 200 150
    .c bbox test







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    .c moveto rect
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.3 {Bad args handling for "moveto" command} -body {
    .c moveto test 12
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}
test canvMoveto-1.4 {Bad args handling for "moveto" command} -body {
    .c moveto test 12 y
} -returnCodes error -result {expected screen distance but got "y"}
test canvMoveto-1.5 {Bad args handling for "moveto" command} -body {
    .c moveto test 12 20 -anchor
} -returnCodes error -result {wrong # args: should be ".c moveto tagOrId x y"}

test canvMoveto-2.1 {Canvas "moveto" command coordinates} {
    .c moveto test 200 150
    .c bbox test

Changes to tests/canvPs.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out procedures to write postscript
# for canvases to files and channels. It exercises the procedure
# TkCanvPostscriptCmd in generic/tkCanvPs.c
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out procedures to write postscript
# for canvases to files and channels. It exercises the procedure
# TkCanvPostscriptCmd in generic/tkCanvPs.c
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
destroy .c


test canvPs-3.1 {test ps generation with an embedded window} -constraints {
    notAqua
} -setup {
    set bar [makeFile {} bar.ps]
    file delete $bar
} -body {
    pack [canvas .c -width 200 -height 200 -background white]
    .c create rect 20 20 150 150 -tags rect0 -dash . -width 2
    .c create arc 0 50 200 200 -tags arc0 \
	    -dash {4 4} -stipple question -outline red -fill green







|
<
<







129
130
131
132
133
134
135
136


137
138
139
140
141
142
143
} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
destroy .c


test canvPs-3.1 {test ps generation with an embedded window} -setup {


    set bar [makeFile {} bar.ps]
    file delete $bar
} -body {
    pack [canvas .c -width 200 -height 200 -background white]
    .c create rect 20 20 150 150 -tags rect0 -dash . -width 2
    .c create arc 0 50 200 200 -tags arc0 \
	    -dash {4 4} -stipple question -outline red -fill green
176
177
178
179
180
181
182


















183
184
185
186
187
188
189


test canvPs-4.1 {test ps generation with single-point uncolored poly, bug 734498} -body {
    pack [canvas .c]
    .c create poly 10 20 10 20
    .c postscript
} -cleanup {


















    destroy .c
} -returnCodes ok -match glob -result *


# cleanup
unset -nocomplain foo bar
imageFinish







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


test canvPs-4.1 {test ps generation with single-point uncolored poly, bug 734498} -body {
    pack [canvas .c]
    .c create poly 10 20 10 20
    .c postscript
} -cleanup {
    destroy .c
} -returnCodes ok -match glob -result *


test canvPs-5.1 {test ps generation with bitmap, bug 424773a00c} -body {
    pack [canvas .c]
    update
    .c create bitmap 50 50 -bitmap questhead
    .c postscript  ; # was crashing on macOS
} -cleanup {
    destroy .c
} -returnCodes ok -match glob -result *
test canvPs-5.2 {test ps generation with image} -body {
    pack [canvas .c]
    update
    .c create image 50 50 -image ::tk::icons::information
    .c postscript
} -cleanup {
    destroy .c
} -returnCodes ok -match glob -result *


# cleanup
unset -nocomplain foo bar
imageFinish

Changes to tests/canvRect.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in tkRectOval.c,
# which implement canvas "rectangle" and "oval" items.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in tkRectOval.c,
# which implement canvas "rectangle" and "oval" items.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
} -result {test xyz}
test canvRect-1.9 {configuration options: good value for -width} -body {
    .c itemconfigure test -width 6.0
    list [.c itemcget test -width] [lindex [.c itemconfigure test -width] 4]
} -result {6.0 6.0}
test canvRect-1.10 {configuration options: bad value for -width} -body {
    .c itemconfigure test -width abc
} -returnCodes error -result {bad screen distance "abc"}
.c delete withtag all


test canvRect-2.1 {CreateRectOval procedure} -body {
    .c create rect
} -returnCodes error -result {wrong # args: should be ".c create rect coords ?arg ...?"}
test canvRect-2.2 {CreateRectOval procedure} -body {
    .c create oval x y z
} -returnCodes error -result {wrong # coordinates: expected 0 or 4, got 3}
test canvRect-2.3 {CreateRectOval procedure} -body {
    .c create rectangle x 2 3 4
} -returnCodes error -result {bad screen distance "x"}
test canvRect-2.4 {CreateRectOval procedure} -body {
    .c create rectangle 1 y 3 4
} -returnCodes error -result {bad screen distance "y"}
test canvRect-2.5 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 z 4
} -returnCodes error -result {bad screen distance "z"}
test canvRect-2.6 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 q
} -returnCodes error -result {bad screen distance "q"}
test canvRect-2.7 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 4 -tags x
    set result {}
    foreach element [.c coords x] {
	    lappend result [format %.1f $element]
    }
    set result







|











|


|


|


|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
} -result {test xyz}
test canvRect-1.9 {configuration options: good value for -width} -body {
    .c itemconfigure test -width 6.0
    list [.c itemcget test -width] [lindex [.c itemconfigure test -width] 4]
} -result {6.0 6.0}
test canvRect-1.10 {configuration options: bad value for -width} -body {
    .c itemconfigure test -width abc
} -returnCodes error -result {expected screen distance but got "abc"}
.c delete withtag all


test canvRect-2.1 {CreateRectOval procedure} -body {
    .c create rect
} -returnCodes error -result {wrong # args: should be ".c create rect coords ?arg ...?"}
test canvRect-2.2 {CreateRectOval procedure} -body {
    .c create oval x y z
} -returnCodes error -result {wrong # coordinates: expected 0 or 4, got 3}
test canvRect-2.3 {CreateRectOval procedure} -body {
    .c create rectangle x 2 3 4
} -returnCodes error -result {expected screen distance but got "x"}
test canvRect-2.4 {CreateRectOval procedure} -body {
    .c create rectangle 1 y 3 4
} -returnCodes error -result {expected screen distance but got "y"}
test canvRect-2.5 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 z 4
} -returnCodes error -result {expected screen distance but got "z"}
test canvRect-2.6 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 q
} -returnCodes error -result {expected screen distance but got "q"}
test canvRect-2.7 {CreateRectOval procedure} -body {
    .c create rectangle 1 2 3 4 -tags x
    set result {}
    foreach element [.c coords x] {
	    lappend result [format %.1f $element]
    }
    set result
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    .c delete withtag all
} -result {10.0 20.0 30.0 40.0}
test canvRect-3.2 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x a 2 3 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "a"}
test canvRect-3.3 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 b 3 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "b"}
test canvRect-3.4 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 c 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "c"}
test canvRect-3.5 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 3 d
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "d"}
test canvRect-3.6 {RectOvalCoords procedure} -constraints {
    nonPortable
} -body {
    .c create rectangle 10 20 30 40 -tags x
    # Non-portable due to rounding differences.
    .c coords x 10 25 15 40
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 24 16 41}
test canvRect-3.7 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 3 4 5
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {wrong # coordinates: expected 0 or 4, got 5}


test canvRect-4.1 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width abc
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "abc"}
test canvRect-4.2 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    catch {.c itemconfigure x -width abc}
	.c itemcget x -width
} -cleanup {
    .c delete withtag all
} -result {1.0}
test canvRect-4.3 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width -5
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {bad screen distance "-5"}
test canvRect-4.4 {ConfigureRectOval procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width 10
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {5 15 35 45}

# I can't come up with any good tests for DeleteRectOval.








test canvRect-5.1 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 20 15 10 5
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {10 5 20 15}
test canvRect-5.2 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 1 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 9 31 21}
test canvRect-5.3 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 2 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 9 31 21}
test canvRect-5.4 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
    # Non-portable due to rounding differences:
    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 3 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {8 8 32 22}







|





|





|





|
|
<
<

<


















|












|
|
<









>
>
>
>
>
>
>
|
<





|
|
<







|
<







|
<







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126


127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184

185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
    .c delete withtag all
} -result {10.0 20.0 30.0 40.0}
test canvRect-3.2 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x a 2 3 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {expected screen distance but got "a"}
test canvRect-3.3 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 b 3 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {expected screen distance but got "b"}
test canvRect-3.4 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 c 4
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {expected screen distance but got "c"}
test canvRect-3.5 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 3 d
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {expected screen distance but got "d"}
test canvRect-3.6 {RectOvalCoords procedure} -body {


    .c create rectangle 10 20 30 40 -tags x

    .c coords x 10 25 15 40
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 24 16 41}
test canvRect-3.7 {RectOvalCoords procedure} -body {
    .c create rectangle 10 20 30 40 -tags x
    .c coords x 1 2 3 4 5
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {wrong # coordinates: expected 0 or 4, got 5}


test canvRect-4.1 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width abc
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {expected screen distance but got "abc"}
test canvRect-4.2 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    catch {.c itemconfigure x -width abc}
	.c itemcget x -width
} -cleanup {
    .c delete withtag all
} -result {1.0}
test canvRect-4.3 {ConfigureRectOval procedure} -body {
    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width -5
} -cleanup {
    .c delete withtag all
} -returnCodes error -result {expected screen distance but got "-5"}
test canvRect-4.4 {ConfigureRectOval procedure} -body {

    .c create rectangle 10 20 30 40 -tags x -width 1
    .c itemconfigure x -width 10
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {5 15 35 45}

# I can't come up with any good tests for DeleteRectOval.

# On Windows the bbox of rectangle items is 1 pixel larger at each border due
# to the "bloat" implemented in ComputeRectOvalBbox() in case -outline is {}
if {[tk windowingsystem] eq "win32"} {
    set result_5_1 {9 4 21 16}
} else {
    set result_5_1 {10 5 20 15}
}
test canvRect-5.1 {ComputeRectOvalBbox procedure} -body {

    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 20 15 10 5
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result $result_5_1
test canvRect-5.2 {ComputeRectOvalBbox procedure} -body {

    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 1 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 9 31 21}
test canvRect-5.3 {ComputeRectOvalBbox procedure} -body {

    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 2 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {9 9 31 21}
test canvRect-5.4 {ComputeRectOvalBbox procedure} -body {

    .c create rectangle 10 20 30 40 -tags x -width 1 -outline {}
    .c coords x 10 20 30 10
    .c itemconfigure x -width 3 -outline red
    .c bbox x
} -cleanup {
    .c delete withtag all
} -result {8 8 32 22}
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
    .c create rect 100 300 200 350 -tags x
    .c move x 100 -10
    format {%.6g %.6g %.6g %.6g} {*}[.c coords x]
} -result {200 290 300 340}


test canvRect-11.1 {RectOvalToPostscript procedure} -constraints {
     nonPortable macCrash
} -setup {
    .c delete withtag all
} -body {
    # Crashes on Mac because the XGetImage() call isn't implemented, causing a
    # dereference of NULL.
    # This test is non-portable because different color information
	# will get generated on different displays (e.g. mono displays
	# vs. color).
    .c configure -bd 0 -highlightthickness 0
    .c create rect 50 60 90 80 -fill black -stipple gray50 -outline {}
    .c create oval 100 150 200 200 -fill {} -outline #ff0000 -width 5
    update
    set x [.c postscript]
    string range $x [string first "-200 -150 translate" $x] end
} -result {-200 -150 translate







|



<
<

|
|







423
424
425
426
427
428
429
430
431
432
433


434
435
436
437
438
439
440
441
442
443
    .c create rect 100 300 200 350 -tags x
    .c move x 100 -10
    format {%.6g %.6g %.6g %.6g} {*}[.c coords x]
} -result {200 290 300 340}


test canvRect-11.1 {RectOvalToPostscript procedure} -constraints {
    nonPortable
} -setup {
    .c delete withtag all
} -body {


    # This test is non-portable because different color information
    # will get generated on different displays (e.g. mono displays
    # vs. color).
    .c configure -bd 0 -highlightthickness 0
    .c create rect 50 60 90 80 -fill black -stipple gray50 -outline {}
    .c create oval 100 150 200 200 -fill {} -outline #ff0000 -width 5
    update
    set x [.c postscript]
    string range $x [string first "-200 -150 translate" $x] end
} -result {-200 -150 translate

Changes to tests/canvText.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# This file is a Tcl script to test out the procedures in tkCanvText.c,
# which implement canvas "text" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Canvas used in 1.* - 17.* tests
canvas .c -width 400 -height 300 -bd 2 -relief sunken
pack .c
update

# Item used in 1.*  tests
.c create text 20 20 -tag test





|







<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13



14
15
16
17
18
19
20
# This file is a Tcl script to test out the procedures in tkCanvText.c,
# which implement canvas "text" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands




# Canvas used in 1.* - 17.* tests
canvas .c -width 400 -height 300 -bd 2 -relief sunken
pack .c
update

# Item used in 1.*  tests
.c create text 20 20 -tag test
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
} -returnCodes error -result {bitmap "abcxyz" not defined}
test canvText-1.12 {configuration options: good value for "underline"} -body {
    .c itemconfigure test -underline 0
    list [lindex [.c itemconfigure test -underline] 4] [.c itemcget test -underline]
} -result {0 0}
test canvasText-1.13 {configuration options: bad value for "underline"} -body {
    .c itemconfigure test -underline xyz
} -returnCodes error -result {expected integer but got "xyz"}
test canvText-1.14 {configuration options: good value for "width"} -body {
    .c itemconfigure test -width 6
    list [lindex [.c itemconfigure test -width] 4] [.c itemcget test -width]
} -result {6 6}
test canvasText-1.15 {configuration options: bad value for "width"} -body {
    .c itemconfigure test -width xyz
} -returnCodes error -result {bad screen distance "xyz"}
test canvText-1.16 {configuration options: good value for "tags"} -body {
    .c itemconfigure test -tags {test a b c}
    list [lindex [.c itemconfigure test -tags] 4] [.c itemcget test -tags]
} -result {{test a b c} {test a b c}}
test canvasText-1.17 {configuration options: bad value for "angle"} -body {
    .c itemconfigure test -angle xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}







|






|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
} -returnCodes error -result {bitmap "abcxyz" not defined}
test canvText-1.12 {configuration options: good value for "underline"} -body {
    .c itemconfigure test -underline 0
    list [lindex [.c itemconfigure test -underline] 4] [.c itemcget test -underline]
} -result {0 0}
test canvasText-1.13 {configuration options: bad value for "underline"} -body {
    .c itemconfigure test -underline xyz
} -returnCodes error -result {bad index "xyz": must be integer?[+-]integer?, end?[+-]integer?, or ""}
test canvText-1.14 {configuration options: good value for "width"} -body {
    .c itemconfigure test -width 6
    list [lindex [.c itemconfigure test -width] 4] [.c itemcget test -width]
} -result {6 6}
test canvasText-1.15 {configuration options: bad value for "width"} -body {
    .c itemconfigure test -width xyz
} -returnCodes error -result {expected screen distance but got "xyz"}
test canvText-1.16 {configuration options: good value for "tags"} -body {
    .c itemconfigure test -tags {test a b c}
    list [lindex [.c itemconfigure test -tags] 4] [.c itemcget test -tags]
} -result {{test a b c} {test a b c}}
test canvasText-1.17 {configuration options: bad value for "angle"} -body {
    .c itemconfigure test -angle xyz
} -returnCodes error -result {expected floating-point number but got "xyz"}
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
test canvText-2.1 {CreateText procedure: args} -body {
    .c create text
} -returnCodes {error} -result {wrong # args: should be ".c create text coords ?arg ...?"}
test canvText-2.2 {CreateText procedure: args} -body {
    .c create text xyz 0
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-2.3 {CreateText procedure: args} -body {
    .c create text 0 xyz
} -cleanup {
    .c delete all
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-2.4 {CreateText procedure: args} -body {
    .c create text 0 0 -xyz xyz
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "-xyz"}
test canvText-2.5 {CreateText procedure} -body {
    .c create text 0 0 -tags x







|




|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
test canvText-2.1 {CreateText procedure: args} -body {
    .c create text
} -returnCodes {error} -result {wrong # args: should be ".c create text coords ?arg ...?"}
test canvText-2.2 {CreateText procedure: args} -body {
    .c create text xyz 0
} -cleanup {
    .c delete all
} -returnCodes {error} -result {expected screen distance but got "xyz"}
test canvText-2.3 {CreateText procedure: args} -body {
    .c create text 0 xyz
} -cleanup {
    .c delete all
} -returnCodes {error} -result {expected screen distance but got "xyz"}
test canvText-2.4 {CreateText procedure: args} -body {
    .c create text 0 0 -xyz xyz
} -cleanup {
    .c delete all
} -returnCodes {error} -result {unknown option "-xyz"}
test canvText-2.5 {CreateText procedure} -body {
    .c create text 0 0 -tags x
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
} -result {0.0 0.0}
test canvText-3.2 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test xyz 0
} -cleanup {
    .c delete test
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-3.3 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 0 xyz
} -cleanup {
    .c delete test
} -returnCodes {error} -result {bad screen distance "xyz"}
test canvText-3.4 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 10 10
    set result {}
    foreach element [.c coords test] {
	lappend result [format %.1f $element]







|






|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
} -result {0.0 0.0}
test canvText-3.2 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test xyz 0
} -cleanup {
    .c delete test
} -returnCodes {error} -result {expected screen distance but got "xyz"}
test canvText-3.3 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 0 xyz
} -cleanup {
    .c delete test
} -returnCodes {error} -result {expected screen distance but got "xyz"}
test canvText-3.4 {TextCoords procedure} -setup {
    .c create text 20 20 -tag test
} -body {
    .c coords test 10 10
    set result {}
    foreach element [.c coords test] {
	lappend result [format %.1f $element]
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
    .c select from test 5
    .c select to test 8
    .c icursor test 12
    .c coords test 0 0
    list [.c index test end] [.c index test insert] \
	[.c index test sel.first] [.c index test sel.last] \
	[.c index test @0,0] \
	[.c index test -1] [.c index test 10] [.c index test 100]
} -cleanup {
    .c delete test
} -result {15 12 5 8 0 0 10 15}
test canvText-14.2 {GetTextIndex procedure: select error} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test







|







749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
    .c select from test 5
    .c select to test 8
    .c icursor test 12
    .c coords test 0 0
    list [.c index test end] [.c index test insert] \
	[.c index test sel.first] [.c index test sel.last] \
	[.c index test @0,0] \
	[.c index test {}] [.c index test 10] [.c index test 100]
} -cleanup {
    .c delete test
} -result {15 12 5 8 0 0 10 15}
test canvText-14.2 {GetTextIndex procedure: select error} -setup {
    .c create text 0 0 -tag test
    focus .c
    .c focus test
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
    set y2 [expr {160 + ($metrics(-linespace) / 2)}]
    lappend results [$c index tbox1 @$x,$y1]
    lappend results [$c index tbox2 @$x,$y2]
} -cleanup {
    destroy .c
} -result {{Yeah } Yeah- 4 4}

test canvText-20.1 {angled text bounding box} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    destroy .c
    canvas .c
    proc transpose {bbox} {
	lassign $bbox a b c d
	list $b $a $d $c
    }






} -body {
    .c create text 2 2 -tag t -anchor center -text 0 -font {Helvetica 24}
    set bb0 [.c bbox t]
    .c itemconf t -angle 90
    set bb1 [.c bbox t]
    .c itemconf t -angle 180
    set bb2 [.c bbox t]
    .c itemconf t -angle 270
    set bb3 [.c bbox t]

    list [expr {$bb0 eq $bb2 ? "ok" : "$bb0,$bb2"}] \
	[expr {$bb1 eq $bb3 ? "ok" : "$bb1,$bb3"}] \
	[expr {$bb0 eq [transpose $bb1] ? "ok" : "$bb0,$bb1"}] \
} -cleanup {
    destroy .c
    rename transpose {}
} -result {ok ok ok}

test canvText-20.2 {crash on angled text selection (X11, without xft) - bug 2712f43f6e} -setup {
    destroy .c







|






>
>
>
>
>
>

|







>
|
|
|







936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
    set y2 [expr {160 + ($metrics(-linespace) / 2)}]
    lappend results [$c index tbox1 @$x,$y1]
    lappend results [$c index tbox2 @$x,$y2]
} -cleanup {
    destroy .c
} -result {{Yeah } Yeah- 4 4}

test canvText-20.1 {angled text bounding box} -setup {
    destroy .c
    canvas .c
    proc transpose {bbox} {
	lassign $bbox a b c d
	list $b $a $d $c
    }
    proc almosteq {b1 b2} {
        # check whether the two boxes are equal, with 1 unit tolerance on each x y w h
        lassign $b1 a b c d
        lassign $b2 e f g h
        expr {($e-$a)<=1 && ($f-$b)<=1 && ($g-$c)<=1 && ($h-$d)<=1}
    }
} -body {
    .c create text 2 2 -tag t -anchor center -text 0 -font {TkDefaultFont 24}
    set bb0 [.c bbox t]
    .c itemconf t -angle 90
    set bb1 [.c bbox t]
    .c itemconf t -angle 180
    set bb2 [.c bbox t]
    .c itemconf t -angle 270
    set bb3 [.c bbox t]
    # bboxes should be the same, possibly with a small (platform-specific) rounding difference
    list [expr {[almosteq $bb0 $bb2] ? "ok" : "$bb0,$bb2"}] \
	[expr {[almosteq $bb1 $bb3] ? "ok" : "$bb1,$bb3"}] \
	[expr {[almosteq $bb0 [transpose $bb1]] ? "ok" : "$bb0,$bb1"}]
} -cleanup {
    destroy .c
    rename transpose {}
} -result {ok ok ok}

test canvText-20.2 {crash on angled text selection (X11, without xft) - bug 2712f43f6e} -setup {
    destroy .c

Changes to tests/canvWind.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in tkCanvWind.c,
# which implement canvas "window" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in tkCanvWind.c,
# which implement canvas "window" items.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

134
135
136
137
138
139
140
















141
142
143
144
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
} -cleanup {
    destroy .t
} -result {{1 3} {1 -79} {0 -79} {1 255} {0 255}}

















# cleanup
cleanupTests
return







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    lappend x [list [winfo ismapped $f] [winfo x $f]]
    .t.c xview scroll -1 units
    update
    lappend x [list [winfo ismapped $f] [winfo x $f]]
} -cleanup {
    destroy .t
} -result {{1 3} {1 -79} {0 -79} {1 255} {0 255}}

test canvWind-2.1 {DisplayWinItem, window gets destroyed during <Configure>} -setup {
    destroy .t
} -body {
    toplevel .t
    canvas .t.c
    pack .t.c
    frame .t.c.f -width 50 -height 50 -background red
    set id [.t.c create window 50 50 -window .t.c.f]
    update
    bind .t.c.f <Configure> {destroy .t.c.f}
    .t.c coords $id 60 60 ;  # was crashing
    update
} -cleanup {
    destroy .t
} -result {}

# cleanup
cleanupTests
return

Changes to tests/canvas.test.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
} -returnCodes error -result {unknown color name "non-existent"}
test canvas-1.5 {configuration options: good value for "bd"} -body {
    .c configure -bd 4
    .c cget -bd
} -result 4
test canvas-1.6 {configuration options: bad value for "bd"} -body {
    .c configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.7 {configuration options: good value for "borderwidth"} -body {
    .c configure -borderwidth 1.3
    .c cget -borderwidth
} -result 1
test canvas-1.8 {configuration options: bad value for "borderwidth"} -body {
    .c configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.9 {configuration options: good value for "closeenough"} -body {
    .c configure -closeenough 24
    .c cget -closeenough
} -result {24.0}
test canvas-1.10 {configuration options: bad value for "closeenough"} -body {
    .c configure -closeenough bogus
} -returnCodes error -result {expected floating-point number but got "bogus"}







|






|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
} -returnCodes error -result {unknown color name "non-existent"}
test canvas-1.5 {configuration options: good value for "bd"} -body {
    .c configure -bd 4
    .c cget -bd
} -result 4
test canvas-1.6 {configuration options: bad value for "bd"} -body {
    .c configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test canvas-1.7 {configuration options: good value for "borderwidth"} -body {
    .c configure -borderwidth 1.3
    .c cget -borderwidth
} -result 1
test canvas-1.8 {configuration options: bad value for "borderwidth"} -body {
    .c configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test canvas-1.9 {configuration options: good value for "closeenough"} -body {
    .c configure -closeenough 24
    .c cget -closeenough
} -result {24.0}
test canvas-1.10 {configuration options: bad value for "closeenough"} -body {
    .c configure -closeenough bogus
} -returnCodes error -result {expected floating-point number but got "bogus"}
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
} -returnCodes error -result {bad cursor spec "badValue"}
test canvas-1.15 {configuration options: good value for "height"} -body {
    .c configure -height 2.1
    .c cget -height
} -result 2
test canvas-1.16 {configuration options: bad value for "height"} -body {
    .c configure -height x42
} -returnCodes error -result {bad screen distance "x42"}
test canvas-1.17 {configuration options: good value for "highlightbackground"} -body {
    .c configure -highlightbackground #112233
    .c cget -highlightbackground
} -result {#112233}
test canvas-1.18 {configuration options: bad value for "highlightbackground"} -body {
    .c configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test canvas-1.19 {configuration options: good value for "highlightcolor"} -body {
    .c configure -highlightcolor #110022
    .c cget -highlightcolor
} -result {#110022}
test canvas-1.20 {configuration options: bad value for "highlightcolor"} -body {
    .c configure -highlightcolor bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.21 {configuration options: good value for "highlightthickness"} -body {
    .c configure -highlightthickness 18
    .c cget -highlightthickness
} -result 18
test canvas-1.22 {configuration options: bad value for "highlightthickness"} -body {
    .c configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.23 {configuration options: good value for "insertbackground"} -body {
    .c configure -insertbackground #110022
    .c cget -insertbackground
} -result {#110022}
test canvas-1.24 {configuration options: bad value for "insertbackground"} -body {
    .c configure -insertbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.25 {configuration options: good value for "insertborderwidth"} -body {
    .c configure -insertborderwidth 1.3
    .c cget -insertborderwidth
} -result 1
test canvas-1.26 {configuration options: bad value for "insertborderwidth"} -body {
    .c configure -insertborderwidth 2.6x
} -returnCodes error -result {bad screen distance "2.6x"}
test canvas-1.27 {configuration options: good value for "insertofftime"} -body {
    .c configure -insertofftime 100
    .c cget -insertofftime
} -result 100
test canvas-1.28 {configuration options: bad value for "insertofftime"} -body {
    .c configure -insertofftime 3.2
} -returnCodes error -result {expected integer but got "3.2"}
test canvas-1.29 {configuration options: good value for "insertontime"} -body {
    .c configure -insertontime 100
    .c cget -insertontime
} -result 100
test canvas-1.30 {configuration options: bad value for "insertontime"} -body {
    .c configure -insertontime 3.2
} -returnCodes error -result {expected integer but got "3.2"}
test canvas-1.31 {configuration options: good value for "insertwidth"} -body {
    .c configure -insertwidth 1.3
    .c cget -insertwidth
} -result 1
test canvas-1.32 {configuration options: bad value for "insertwidth"} -body {
    .c configure -insertwidth 6x
} -returnCodes error -result {bad screen distance "6x"}
test canvas-1.33 {configuration options: good value for "relief"} -body {
    .c configure -relief groove
    .c cget -relief
} -result {groove}
test canvas-1.34 {configuration options: bad value for "relief"} -body {
    .c configure -relief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test canvas-1.35 {configuration options: good value for "selectbackground"} -body {
    .c configure -selectbackground #110022
    .c cget -selectbackground
} -result {#110022}
test canvas-1.36 {configuration options: bad value for "selectbackground"} -body {
    .c configure -selectbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.37 {configuration options: good value for "selectborderwidth"} -body {
    .c configure -selectborderwidth 1.3
    .c cget -selectborderwidth
} -result 1
test canvas-1.38 {configuration options: bad value for "selectborderwidth"} -body {
    .c configure -selectborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test canvas-1.39 {configuration options: good value for "selectforeground"} -body {
    .c configure -selectforeground #654321
    .c cget -selectforeground
} -result {#654321}
test canvas-1.40 {configuration options: bad value for "selectforeground"} -body {
    .c configure -selectforeground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.41 {configuration options: good value for "takefocus"} -body {
    .c configure -takefocus "any string"
    .c cget -takefocus
} -result {any string}
test canvas-1.42 {configuration options: good value for "width"} -body {
    .c configure -width 402
    .c cget -width
} -result 402
test canvas-1.43 {configuration options: bad value for "width"} -body {
    .c configure -width xyz
} -returnCodes error -result {bad screen distance "xyz"}
test canvas-1.44 {configuration options: good value for "xscrollcommand"} -body {
    .c configure -xscrollcommand {Some command}
    .c cget -xscrollcommand
} -result {Some command}
test canvas-1.45 {configuration options: good value for "yscrollcommand"} -body {
    .c configure -yscrollcommand {Another command}
    .c cget -yscrollcommand







|




















|













|




















|

|



|
|













|

















|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
} -returnCodes error -result {bad cursor spec "badValue"}
test canvas-1.15 {configuration options: good value for "height"} -body {
    .c configure -height 2.1
    .c cget -height
} -result 2
test canvas-1.16 {configuration options: bad value for "height"} -body {
    .c configure -height x42
} -returnCodes error -result {expected screen distance but got "x42"}
test canvas-1.17 {configuration options: good value for "highlightbackground"} -body {
    .c configure -highlightbackground #112233
    .c cget -highlightbackground
} -result {#112233}
test canvas-1.18 {configuration options: bad value for "highlightbackground"} -body {
    .c configure -highlightbackground ugly
} -returnCodes error -result {unknown color name "ugly"}
test canvas-1.19 {configuration options: good value for "highlightcolor"} -body {
    .c configure -highlightcolor #110022
    .c cget -highlightcolor
} -result {#110022}
test canvas-1.20 {configuration options: bad value for "highlightcolor"} -body {
    .c configure -highlightcolor bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.21 {configuration options: good value for "highlightthickness"} -body {
    .c configure -highlightthickness 18
    .c cget -highlightthickness
} -result 18
test canvas-1.22 {configuration options: bad value for "highlightthickness"} -body {
    .c configure -highlightthickness badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test canvas-1.23 {configuration options: good value for "insertbackground"} -body {
    .c configure -insertbackground #110022
    .c cget -insertbackground
} -result {#110022}
test canvas-1.24 {configuration options: bad value for "insertbackground"} -body {
    .c configure -insertbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.25 {configuration options: good value for "insertborderwidth"} -body {
    .c configure -insertborderwidth 1.3
    .c cget -insertborderwidth
} -result 1
test canvas-1.26 {configuration options: bad value for "insertborderwidth"} -body {
    .c configure -insertborderwidth 2.6x
} -returnCodes error -result {expected screen distance but got "2.6x"}
test canvas-1.27 {configuration options: good value for "insertofftime"} -body {
    .c configure -insertofftime 100
    .c cget -insertofftime
} -result 100
test canvas-1.28 {configuration options: bad value for "insertofftime"} -body {
    .c configure -insertofftime 3.2
} -returnCodes error -result {expected integer but got "3.2"}
test canvas-1.29 {configuration options: good value for "insertontime"} -body {
    .c configure -insertontime 100
    .c cget -insertontime
} -result 100
test canvas-1.30 {configuration options: bad value for "insertontime"} -body {
    .c configure -insertontime 3.2
} -returnCodes error -result {expected integer but got "3.2"}
test canvas-1.31 {configuration options: good value for "insertwidth"} -body {
    .c configure -insertwidth 1.3
    .c cget -insertwidth
} -result 1
test canvas-1.32 {configuration options: bad value for "insertwidth"} -body {
    .c configure -insertwidth 6x
} -returnCodes error -result {expected screen distance but got "6x"}
test canvas-1.33 {configuration options: good value for "relief"} -body {
    .c configure -relief g
    .c cget -relief
} -result {groove}
test canvas-1.34 {configuration options: bad value for "relief"} -body {
    .c configure -relief r
} -returnCodes error -result {bad relief "r": must be flat, groove, raised, ridge, solid, or sunken}
test canvas-1.35 {configuration options: good value for "selectbackground"} -body {
    .c configure -selectbackground #110022
    .c cget -selectbackground
} -result {#110022}
test canvas-1.36 {configuration options: bad value for "selectbackground"} -body {
    .c configure -selectbackground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.37 {configuration options: good value for "selectborderwidth"} -body {
    .c configure -selectborderwidth 1.3
    .c cget -selectborderwidth
} -result 1
test canvas-1.38 {configuration options: bad value for "selectborderwidth"} -body {
    .c configure -selectborderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test canvas-1.39 {configuration options: good value for "selectforeground"} -body {
    .c configure -selectforeground #654321
    .c cget -selectforeground
} -result {#654321}
test canvas-1.40 {configuration options: bad value for "selectforeground"} -body {
    .c configure -selectforeground bogus
} -returnCodes error -result {unknown color name "bogus"}
test canvas-1.41 {configuration options: good value for "takefocus"} -body {
    .c configure -takefocus "any string"
    .c cget -takefocus
} -result {any string}
test canvas-1.42 {configuration options: good value for "width"} -body {
    .c configure -width 402
    .c cget -width
} -result 402
test canvas-1.43 {configuration options: bad value for "width"} -body {
    .c configure -width xyz
} -returnCodes error -result {expected screen distance but got "xyz"}
test canvas-1.44 {configuration options: good value for "xscrollcommand"} -body {
    .c configure -xscrollcommand {Some command}
    .c cget -xscrollcommand
} -result {Some command}
test canvas-1.45 {configuration options: good value for "yscrollcommand"} -body {
    .c configure -yscrollcommand {Another command}
    .c cget -yscrollcommand
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    .c xview moveto 0
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
} -result {{0.0 0.3} {0.4 0.7}}
test canvas-2.4 {CanvasWidgetCmd, xview option} -constraints nonPortable -body {
    # This test gives slightly different results on platforms such as NetBSD.
    # I don't know why...
    .c configure -xscrollincrement 0 -yscrollincrement 5
    .c xview moveto 0.6
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]







|
<
<







212
213
214
215
216
217
218
219


220
221
222
223
224
225
226
    .c xview moveto 0
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
} -result {{0.0 0.3} {0.4 0.7}}
test canvas-2.4 {CanvasWidgetCmd, xview option} -body {


    .c configure -xscrollincrement 0 -yscrollincrement 5
    .c xview moveto 0.6
    update
    set x [list [.c xview]]
    .c xview scroll 2 units
    update
    lappend x [.c xview]
751
752
753
754
755
756
757
758
759
760
















761
762
763
764
765
766
767
} -returnCodes error -body {
    .c create window 0
} -result {wrong # coordinates: expected 2, got 1}
test canvas-15.19 "basic coords check: centimeters are larger than pixels" -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create rect 0 0 1cm 1cm]
    expr {[lindex [.c coords $id] 2]>1}
} -result 1
















destroy .c

test canvas-16.1 {arc coords check} -setup {
    canvas .c
} -body {
    set id [.c create arc {0 10 20 30} -start 33]
    .c itemcget $id -start







|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
} -returnCodes error -body {
    .c create window 0
} -result {wrong # coordinates: expected 2, got 1}
test canvas-15.19 "basic coords check: centimeters are larger than pixels" -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create rect 0 0 1c 1c]
    expr {[lindex [.c coords $id] 2]>1}
} -result 1
test canvas-15.20 {bug [237971ce]} -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create line {0 0 50 50 100 50}]
    .c insert $id end {200 200}
    .c coords $id
} -result {0.0 0.0 50.0 50.0 100.0 50.0 200.0 200.0}
test canvas-15.21 {bug [237971ce]} -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create poly {0 0 50 50 100 50}]
    .c insert $id end {200 200}
    .c coords $id
} -result {0.0 0.0 50.0 50.0 100.0 50.0 200.0 200.0}
destroy .c

test canvas-16.1 {arc coords check} -setup {
    canvas .c
} -body {
    set id [.c create arc {0 10 20 30} -start 33]
    .c itemcget $id -start
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
test canvas-18.10 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 foobar 4
} -cleanup {
    destroy .c
} -returnCodes error -result {bad screen distance "foobar"}
test canvas-18.11 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 4 foobar
} -cleanup {
    destroy .c
} -returnCodes error -result {bad screen distance "foobar"}

test canvas-19.1 {rchars method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {4 4}
    .c coords $id







|







|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
test canvas-18.10 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 foobar 4
} -cleanup {
    destroy .c
} -returnCodes error -result {expected screen distance but got "foobar"}
test canvas-18.11 {imove method - errors} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c imove $id 0 4 foobar
} -cleanup {
    destroy .c
} -returnCodes error -result {expected screen distance but got "foobar"}

test canvas-19.1 {rchars method - lines} -setup {
    canvas .c
} -body {
    set id [.c create line 0 0 1 1 2 2 3 3]
    .c rchars $id 2 4 {4 4}
    .c coords $id
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
} -result {missing tag in tag search expression}
test canvas-21.6 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all x 1 1
} -returnCodes error -cleanup {
    destroy .c
} -result {bad screen distance "x"}
test canvas-21.7 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 1 x 1
} -returnCodes error -cleanup {
    destroy .c
} -result {bad screen distance "x"}
test canvas-21.8 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 1 1 x
} -returnCodes error -cleanup {
    destroy .c
} -result {expected floating-point number but got "x"}







|






|







1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
} -result {missing tag in tag search expression}
test canvas-21.6 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all x 1 1
} -returnCodes error -cleanup {
    destroy .c
} -result {expected screen distance but got "x"}
test canvas-21.7 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 1 x 1
} -returnCodes error -cleanup {
    destroy .c
} -result {expected screen distance but got "x"}
test canvas-21.8 {canvas rotate: syntax} -setup {
    pack [canvas .c]
} -body {
    .c rotate all 1 1 x
} -returnCodes error -cleanup {
    destroy .c
} -result {expected floating-point number but got "x"}

Changes to tests/choosedir.test.

1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out Tk's "tk_chooseDir" and
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out Tk's "tk_chooseDir" and
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    tk_chooseDirectory -title
} -returnCodes error -result {value for "-title" missing}
test choosedir-1.5.1 {tk_chooseDirectory command} -constraints notAqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test choosedir-1.5.2 {tk_chooseDirectory command} -constraints aqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -message, -mustexist, -parent, -title, or -command}
test choosedir-1.6 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


test choosedir-2.1 {tk_chooseDirectory command, cancel gives null} -constraints {
	unix notAqua







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    tk_chooseDirectory -title
} -returnCodes error -result {value for "-title" missing}
test choosedir-1.5.1 {tk_chooseDirectory command} -constraints notAqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test choosedir-1.5.2 {tk_chooseDirectory command} -constraints aqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -command, -initialdir, -message, -mustexist, -parent, or -title}
test choosedir-1.6 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


test choosedir-2.1 {tk_chooseDirectory command, cancel gives null} -constraints {
	unix notAqua

Changes to tests/clipboard.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# This file is a Tcl script to test out Tk's clipboard management code,
# especially the "clipboard" command.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

#
# Note: Multiple display clipboard handling will only be tested if the
# environment variable TK_ALT_DISPLAY is set to an alternate display.
#

#################################################################
# Note that some of these tests may fail if another application #
# is grabbing the clipboard (e.g. an X server, or a VNC viewer) #
#################################################################

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# set up a very large buffer to test INCR retrievals
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}






|

















<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


24
25
26
27
28
29
30
# This file is a Tcl script to test out Tk's clipboard management code,
# especially the "clipboard" command.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 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



# set up a very large buffer to test INCR retrievals
set longValue ""
foreach i {a b c d e f g j h i j k l m o p q r s t u v w x y z} {
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    clipboard append "first chunk"
    selection own -s CLIPBOARD .
	clipboard append " second chunk"
	clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes ok -result {first chunk second chunk}
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints {x11 failsOnXQuarz} -setup {
    clipboard clear
} -body {
    setupbg
    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]
    return $result
} -cleanup {







|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    clipboard append "first chunk"
    selection own -s CLIPBOARD .
	clipboard append " second chunk"
	clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes ok -result {first chunk second chunk}
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints x11 -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
# This file is a Tcl script to test out Tk's "tk_chooseColor" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out Tk's "tk_chooseColor" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	    }
	}
	.c delete $i
	incr i
    }
    destroy .c
} else {
    testConstraint colorsLeftover 0
}

test clrpick-1.1 {tk_chooseColor command} -body {
    tk_chooseColor -foo
} -returnCodes error -result {bad option "-foo": must be -initialcolor, -parent, or -title}

test clrpick-1.2 {tk_chooseColor command } -body {







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	    }
	}
	.c delete $i
	incr i
    }
    destroy .c
} else {
    testConstraint colorsLeftover 1
}

test clrpick-1.1 {tk_chooseColor command} -body {
    tk_chooseColor -foo
} -returnCodes error -result {bad option "-foo": must be -initialcolor, -parent, or -title}

test clrpick-1.2 {tk_chooseColor command } -body {
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
test clrpick-1.7 {tk_chooseColor command} -body {
    tk_chooseColor -initialcolor ##badbadbaadcolor
} -returnCodes error -result {invalid color name "##badbadbaadcolor"}


# tests 3.1 and 3.2 fail when individually run
# if there is no catch {tk_chooseColor -foo 1} msg
# before settin isNative
catch {tk_chooseColor -foo 1} msg
set isNative [expr {[info commands tk::dialog::color::] eq ""}]

proc ToPressButton {parent btn} {
    global isNative
    if {!$isNative} {
	after 200 "SendButtonPress . $btn mouse"







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
test clrpick-1.7 {tk_chooseColor command} -body {
    tk_chooseColor -initialcolor ##badbadbaadcolor
} -returnCodes error -result {invalid color name "##badbadbaadcolor"}


# tests 3.1 and 3.2 fail when individually run
# if there is no catch {tk_chooseColor -foo 1} msg
# before setting isNative
catch {tk_chooseColor -foo 1} msg
set isNative [expr {[info commands tk::dialog::color::] eq ""}]

proc ToPressButton {parent btn} {
    global isNative
    if {!$isNative} {
	after 200 "SendButtonPress . $btn mouse"
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
    }
}



test clrpick-2.1 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -setup {
    set verylongstring longstring:
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
    # Interesting thing...when this is too long, the
    # delay caused in processing it kills the automated testing,
    # and makes a lot of the test cases fail.
    #set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
    #set verylongstring $verylongstring$verylongstring
} -body {
    ToPressButton . ok
    tk_chooseColor -title "Press Ok $verylongstring" -initialcolor #404040 \
        -parent .
} -result {#404040}
test clrpick-2.2 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover







<



|
<
<
<
<
<
<
<
<
<
<
<
<







138
139
140
141
142
143
144

145
146
147
148












149
150
151
152
153
154
155
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
    }
}



test clrpick-2.1 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -setup {
    set verylongstring [string repeat longstring: 100]












} -body {
    ToPressButton . ok
    tk_chooseColor -title "Press Ok $verylongstring" -initialcolor #404040 \
        -parent .
} -result {#404040}
test clrpick-2.2 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover

Added tests/cluster.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
# This file is a Tcl script to test the [::tk::startOf|endOf]* functions in
# tk.tcl and tkIcu.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint needsICU [expr {[catch {info body ::tk::startOfCluster}]}]


test cluster-1.0 {::tk::startOfCluster} -body {
    ::tk::startOfCluster é -1
} -result {}
test cluster-1.1 {::tk::startOfCluster} -body {
    ::tk::startOfCluster é 0
} -result 0
test cluster-1.2 {::tk::startOfCluster} -constraints needsICU -body {
    ::tk::startOfCluster é 1
} -result 0
test cluster-1.3 {::tk::startOfCluster} -constraints needsICU -body {
    ::tk::startOfCluster é 2
} -result 2
test cluster-1.4 {::tk::startOfCluster} -constraints needsICU -body {
    ::tk::startOfCluster é 3
} -result 2
test cluster-1.5 {::tk::startOfCluster} -constraints needsICU -body {
    ::tk::startOfCluster é end
} -result 0
test cluster-1.6 {::tk::startOfCluster} -body {
    ::tk::startOfCluster é {}
} -result {}
test cluster-1.7 {::tk::startOfCluster} -constraints needsICU -body {
    ::tk::startOfCluster é end-1
} -result 0

test cluster-2.0 {::tk::endOfCluster} -body {
    ::tk::endOfCluster é -1
} -result 0
test cluster-2.1 {::tk::endOfCluster} -constraints needsICU -body {
    ::tk::endOfCluster é 0
} -result 2
test cluster-2.2 {::tk::endOfCluster} -constraints needsICU -body {
    ::tk::endOfCluster é 1
} -result 2
test cluster-2.3 {::tk::endOfCluster} -body {
    ::tk::endOfCluster é 2
} -result {}
test cluster-2.4 {::tk::endOfCluster} -body {
    ::tk::endOfCluster é 3
} -result {}
test cluster-2.5 {::tk::endOfCluster} -constraints needsICU -body {
    ::tk::endOfCluster é end
} -result 2
test cluster-2.6 {::tk::endOfCluster} -body {
    ::tk::endOfCluster é {}
} -result 0
test cluster-2.7 {::tk::endOfCluster} -constraints needsICU -body {
    ::tk::endOfCluster é end-1
} -result 2

test cluster-3.0 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" -1
} -result 2
test cluster-3.1 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" 0
} -result 2
test cluster-3.2 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" 1
} -result 2
test cluster-3.3 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" 2
} -result {}
test cluster-3.4 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" 3
} -result {}
test cluster-3.5 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" 4
} -result {}
test cluster-3.6 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" 5
} -result {}
test cluster-3.7 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" end
} -result {}
test cluster-3.8 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" {}
} -result 2
test cluster-3.9 {::tk::endOfWord} -body {
    ::tk::endOfWord "ab cd" end-1
} -result {}

test cluster-4.0 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" -1
} -result {}
test cluster-4.1 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" 0
} -result {}
test cluster-4.2 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" 1
} -result 0
test cluster-4.3 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" 2
} -result 0
test cluster-4.4 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" 3
} -result 0
test cluster-4.5 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" 4
} -result 3
test cluster-4.6 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" 5
} -result 3
test cluster-4.7 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" end
} -result 3
test cluster-4.8 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" {}
} -result {}
test cluster-4.9 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord "ab cd" end-1
} -result 0

test cluster-5.0 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" -1
} -result 3
test cluster-5.1 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" 0
} -result 3
test cluster-5.2 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" 1
} -result 3
test cluster-5.3 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" 2
} -result 3
test cluster-5.4 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" 3
} -result {}
test cluster-5.5 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" 4
} -result {}
test cluster-5.6 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" 5
} -result {}
test cluster-5.7 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" end
} -result {}
test cluster-5.8 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" {}
} -result 3
test cluster-5.9 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord "ab cd" end-1
} -result {}

test cluster-6.0 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" -1
} -result {}
test cluster-6.1 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" 0
} -result {}
test cluster-6.2 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" 1
} -result {}
test cluster-6.3 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" 2
} -result 2
test cluster-6.4 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" 3
} -result 3
test cluster-6.5 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" 4
} -result 3
test cluster-6.6 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" 5
} -result 3
test cluster-6.7 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" end
} -result 3
test cluster-6.8 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore "ab cd" {}
} -result {}
test cluster-6.9 {::tk::wordBreakBefore} -body {
    ::tk::startOfNextWord "ab cd" end-1
} -result {}

test cluster-7.0 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" -1
} -result 2
test cluster-7.1 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" 0
} -result 2
test cluster-7.2 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" 1
} -result 2
test cluster-7.3 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" 2
} -result 3
test cluster-7.4 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" 3
} -result {}
test cluster-7.5 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" 4
} -result {}
test cluster-7.6 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" 5
} -result {}
test cluster-7.7 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" end
} -result {}
test cluster-7.8 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" {}
} -result 2
test cluster-7.9 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter "ab cd" end-1
} -result {}


test cluster-8.0 {::tk::startOfCluster} -body {
    ::tk::startOfCluster a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::startOfCluster str start ?locale?"}
test cluster-8.1 {::tk::endOfCluster} -body {
    ::tk::endOfCluster a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::endOfCluster str start ?locale?"}
test cluster-8.2 {::tk::startOfPreviousWord} -body {
    ::tk::startOfPreviousWord a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::startOfPreviousWord str start ?locale?"}
test cluster-8.3 {::tk::startOfNextWord} -body {
    ::tk::startOfNextWord a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::startOfNextWord str start ?locale?"}
test cluster-8.4 {::tk::endOfWord} -body {
    ::tk::endOfWord a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::endOfWord str start ?locale?"}
test cluster-8.5 {::tk::wordBreakBefore} -body {
    ::tk::wordBreakBefore a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::wordBreakBefore str start ?locale?"}
test cluster-8.6 {::tk::wordBreakAfter} -body {
    ::tk::wordBreakAfter a b c d
} -returnCodes 1 -result {wrong # args: should be "::tk::wordBreakAfter str start ?locale?"}

cleanupTests
return

Changes to tests/cmds.test.

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 © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test





|







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 © 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
# This file is a Tcl script to test out the procedures in the file
# tkColor.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1995-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# cname --




|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out the procedures in the file
# tkColor.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1995-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# cname --
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    pack .b2 -side top
    lappend result [testcolor purple]
} {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}
test color-1.5 {Color table} nonPortable {
    set fd [open ../xlib/rgb.txt]
    set result {}
    while {[gets $fd line] >= 0} {
    	if {[string index $line 0] == "!"} continue
	set rgb [c255 [winfo rgb . [lrange $line 3 end]]]
	if {$rgb != [lrange $line 0 2] } {
		append result $line\n
	}

    }
    return $result







|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    pack .b2 -side top
    lappend result [testcolor purple]
} {{{1 1}} {{1 1} {1 0}} {{1 0} {2 1}}}
test color-1.5 {Color table} nonPortable {
    set fd [open ../xlib/rgb.txt]
    set result {}
    while {[gets $fd line] >= 0} {
	if {[string index $line 0] == "!"} continue
	set rgb [c255 [winfo rgb . [lrange $line 3 end]]]
	if {$rgb != [lrange $line 0 2] } {
		append result $line\n
	}

    }
    return $result
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
    winfo rgb . #abz
} -returnCodes error -result {invalid color name "#abz"}
test color-2.11 {Tk_GetColor, 6 hex digits, last one invalid} -body {
    winfo rgb . #12345g
} -returnCodes error -result {invalid color name "#12345g"}

test color-3.1 {Tk_FreeColor procedure, reference counting} colorsFree {
    eval destroy [winfo child .t]
    mkColors .t.c 40 6 0 240 240 0 -6 0 0 0 -40
    pack .t.c
    mkColors .t.c2 20 1 250 0 0 -10 0 0 0 0 0
    pack .t.c2
    update
    set last [.t.c2 create rectangle 50 50 70 60 -outline {} \
	    -fill [cname 0 240 240]]
    .t.c delete 1
    set result [colorsFree .t]
    .t.c2 delete $last
    lappend result [colorsFree .t]
} {0 1}
test color-3.2 {Tk_FreeColor procedure, flushing stressed cmap information} colorsFree {
    eval destroy [winfo child .t]
    mkColors .t.c 40 6 0 240 240 0 -6 0 0 0 -40
    pack .t.c
    mkColors .t.c2 20 1 250 0 0 -10 0 0 0 0 0
    mkColors .t.c2 20 1 250 250 0 -10 -10 0 0 0 0
    pack .t.c2
    update
    closest .t 241 241 1







|













|







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
    winfo rgb . #abz
} -returnCodes error -result {invalid color name "#abz"}
test color-2.11 {Tk_GetColor, 6 hex digits, last one invalid} -body {
    winfo rgb . #12345g
} -returnCodes error -result {invalid color name "#12345g"}

test color-3.1 {Tk_FreeColor procedure, reference counting} colorsFree {
    destroy {*}[winfo children .t]
    mkColors .t.c 40 6 0 240 240 0 -6 0 0 0 -40
    pack .t.c
    mkColors .t.c2 20 1 250 0 0 -10 0 0 0 0 0
    pack .t.c2
    update
    set last [.t.c2 create rectangle 50 50 70 60 -outline {} \
	    -fill [cname 0 240 240]]
    .t.c delete 1
    set result [colorsFree .t]
    .t.c2 delete $last
    lappend result [colorsFree .t]
} {0 1}
test color-3.2 {Tk_FreeColor procedure, flushing stressed cmap information} colorsFree {
    destroy {*}[winfo children .t]
    mkColors .t.c 40 6 0 240 240 0 -6 0 0 0 -40
    pack .t.c
    mkColors .t.c2 20 1 250 0 0 -10 0 0 0 0 0
    mkColors .t.c2 20 1 250 250 0 -10 -10 0 0 0 0
    pack .t.c2
    update
    closest .t 241 241 1

Changes to tests/config.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the procedures in tkConfig.c,
# which comprise the new new option configuration system.  It is
# organized in the standard "white-box" fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the procedures in tkConfig.c,
# which comprise the new new option configuration system.  It is
# organized in the standard "white-box" fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    testobjconfig alltypes .a
    lappend x [testobjconfig info alltypes]
    testobjconfig alltypes .b
    lappend x [testobjconfig info alltypes]
    set x
} -cleanup {
    killTables
} -result {{1 16 -boolean} {2 16 -boolean}}
test config-1.2 {Tk_CreateOptionTable - synonym initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a -synonym green
    .a cget -color
} -cleanup {
    killTables
} -result {green}
test config-1.3 {Tk_CreateOptionTable - option database initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    option add *b.string different
    testobjconfig alltypes .b
    list [.a cget -string] [.b cget -string]







|







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    testobjconfig alltypes .a
    lappend x [testobjconfig info alltypes]
    testobjconfig alltypes .b
    lappend x [testobjconfig info alltypes]
    set x
} -cleanup {
    killTables
} -result {{1 17 -boolean} {2 17 -boolean}}
test config-1.2 {Tk_CreateOptionTable - synonym initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a -synonym green
    .a cget -color
} -cleanup {
    killTables
} -result green
test config-1.3 {Tk_CreateOptionTable - option database initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    option add *b.string different
    testobjconfig alltypes .b
    list [.a cget -string] [.b cget -string]
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    killTables
    option clear
} -result {foo bar}
test config-1.5 {Tk_CreateOptionTable - default initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -relief
} -cleanup {
    killTables
} -result {raised}
test config-1.6 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig info chain2
} -cleanup {







|


|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    killTables
    option clear
} -result {foo bar}
test config-1.5 {Tk_CreateOptionTable - default initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -anchor
} -cleanup {
    killTables
} -result center
test config-1.6 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig info chain2
} -cleanup {
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
} -body {
    option add *a.color blue
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
    option clear
} -result {blue}
test config-3.3 {Tk_InitOptions - initialize from database} -constraints {
    testobjconfig
} -body {
    option add *a.justify bogus
    testobjconfig alltypes .a
    list [.a cget -justify]
} -cleanup {
    killTables
    option clear
} -result {left}
test config-3.4 {Tk_InitOptions - initialize from widget class} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
} -result {red}
test config-3.5 {Tk_InitOptions - no initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -anchor
} -cleanup {
    killTables
} -result {}
test config-3.6 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    option add *a.color non-existent







|









|







|




|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
} -body {
    option add *a.color blue
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
    option clear
} -result blue
test config-3.3 {Tk_InitOptions - initialize from database} -constraints {
    testobjconfig
} -body {
    option add *a.justify bogus
    testobjconfig alltypes .a
    list [.a cget -justify]
} -cleanup {
    killTables
    option clear
} -result left
test config-3.4 {Tk_InitOptions - initialize from widget class} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
} -result red
test config-3.5 {Tk_InitOptions - no initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -relief
} -cleanup {
    killTables
} -result {}
test config-3.6 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    option add *a.color non-existent
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    invoked from within
"testobjconfig alltypes .a"}

test config-3.8 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig configerror
} -returnCodes error -result {expected integer but got "bogus"}
test config-3.9 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    catch {testobjconfig configerror}
    return $errorInfo
} -result {expected integer but got "bogus"
    (default value for "-int")
    invoked from within
"testobjconfig configerror"}

test config-4.1 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.2 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
    .foo cget -boolean
} -cleanup {
    killTables







|





|










|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    invoked from within
"testobjconfig alltypes .a"}

test config-3.8 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig configerror
} -returnCodes error -result {expected integer or "" but got "bogus"}
test config-3.9 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    catch {testobjconfig configerror}
    return $errorInfo
} -result {expected integer or "" but got "bogus"
    (default value for "-int")
    invoked from within
"testobjconfig configerror"}

test config-4.1 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.2 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
    .foo cget -boolean
} -cleanup {
    killTables
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
} -returnCodes ok
test config-4.4 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.5 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
    .foo cget -boolean
} -cleanup {
    killTables







|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
} -returnCodes ok
test config-4.4 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.5 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 1
    .foo cget -boolean
} -cleanup {
    killTables
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
    killTables
} -returnCodes ok
test config-4.7 {DoObjConfig - invalid boolean} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean {}
} -cleanup {
    killTables
} -returnCodes error -result {expected boolean value but got ""}
test config-4.8 {DoObjConfig - boolean internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -boolean 0
    .foo cget -boolean
} -cleanup {
    killTables
} -result 0

test config-4.9 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.10 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
    .foo cget -integer
} -cleanup {
    killTables







|


|

















|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
    killTables
} -returnCodes ok
test config-4.7 {DoObjConfig - invalid boolean} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean foo
} -cleanup {
    killTables
} -returnCodes error -result {expected boolean value or "" but got "foo"}
test config-4.8 {DoObjConfig - boolean internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -boolean 0
    .foo cget -boolean
} -cleanup {
    killTables
} -result 0

test config-4.9 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.10 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
    .foo cget -integer
} -cleanup {
    killTables
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

test config-4.14 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.15 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
    .foo cget -double
} -cleanup {
    killTables
} -returnCodes ok -result {3.14}
test config-4.16 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
    .foo cget -double
    rename .foo {}
} -cleanup {







|







|







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

test config-4.14 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.15 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
    .foo cget -double
} -cleanup {
    killTables
} -returnCodes ok -result 3.14
test config-4.16 {DoObjConfig - double} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -double 3.14
    .foo cget -double
    rename .foo {}
} -cleanup {
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -double 62.75
    .foo cget -double
} -cleanup {
    killTables
} -result {62.75}

test config-4.19 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.20 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
    .foo cget -string
} -cleanup {
    killTables
} -returnCodes ok -result {test}
test config-4.21 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
    .foo cget -string
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.22 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.23 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
    .foo cget -string
} -cleanup {
    killTables







|







|







|















|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -double 62.75
    .foo cget -double
} -cleanup {
    killTables
} -result 62.75

test config-4.19 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.20 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
    .foo cget -string
} -cleanup {
    killTables
} -returnCodes ok -result test
test config-4.21 {DoObjConfig - string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string test
    .foo cget -string
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.22 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.23 {DoObjConfig - null string} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -string {}
    .foo cget -string
} -cleanup {
    killTables
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467






468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
    killTables
} -result {this is a test}

test config-4.26 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.27 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
    .foo cget -stringtable
} -cleanup {
    killTables
} -returnCodes ok -result {two}
test config-4.28 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
    .foo cget -stringtable
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.29 {DoObjConfig - invalid string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable foo
} -cleanup {
    killTables
} -returnCodes error -result {bad stringtable "foo": must be one, two, three, or four}







test config-4.30 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
} -cleanup {
    killTables
} -returnCodes ok -result 16
test config-4.31 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
    .foo cget -stringtable
} -cleanup {
    killTables
} -returnCodes ok -result {three}
test config-4.32 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
    .foo cget -stringtable
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.33 {DoObjConfig - stringtable internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -stringtable "four"
    .foo cget -stringtable
} -cleanup {
    killTables
} -result {four}

test config-4.34 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.35 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result {blue}
test config-4.36 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
    .foo cget -color
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok







|





|













|
|
>
>
>
>
>
>
















|



















|





|





|







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
    killTables
} -result {this is a test}

test config-4.26 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.27 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
    .foo cget -stringtable
} -cleanup {
    killTables
} -returnCodes ok -result two
test config-4.28 {DoObjConfig - string table} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -stringtable two
    .foo cget -stringtable
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.29 {DoObjConfig - invalid string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable foo
} -cleanup {
    killTables
} -returnCodes error -result {bad stringtable "foo": must be one, two, three, four, or ""}
test config-4.29a {DoObjConfig - invalid string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable2 foo
} -cleanup {
    killTables
} -returnCodes error -result {bad stringtable2 "foo": must be one, two, or ""}
test config-4.30 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
} -cleanup {
    killTables
} -returnCodes ok -result 16
test config-4.31 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
    .foo cget -stringtable
} -cleanup {
    killTables
} -returnCodes ok -result three
test config-4.32 {DoObjConfig - new string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable two
    .foo configure -stringtable three
    .foo cget -stringtable
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
test config-4.33 {DoObjConfig - stringtable internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -stringtable "four"
    .foo cget -stringtable
} -cleanup {
    killTables
} -result four

test config-4.34 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.35 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result blue
test config-4.36 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
    .foo cget -color
    rename .foo {}
} -cleanup {
    killTables
} -returnCodes ok
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -color purple
    .foo cget -color
} -cleanup {
    killTables
} -result {purple}

test config-4.39 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.40 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.41 {DoObjConfig - null color} -constraints testobjconfig -body {







|





|







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -color purple
    .foo cget -color
} -cleanup {
    killTables
} -result purple

test config-4.39 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.40 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
    .foo cget -color
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.41 {DoObjConfig - null color} -constraints testobjconfig -body {
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601

test config-4.45 {DoObjConfig - font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 72}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.46 {DoObjConfig - font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 72}
    .foo cget -font
} -cleanup {
    killTables







|







593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

test config-4.45 {DoObjConfig - font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 72}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.46 {DoObjConfig - font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {Helvetica 72}
    .foo cget -font
} -cleanup {
    killTables
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
} -returnCodes error -result {unknown font style "foo"}
test config-4.50 {DoObjConfig - null font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.51 {DoObjConfig - null font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {}
    .foo cget -font
} -cleanup {
    killTables







|







634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
} -returnCodes error -result {unknown font style "foo"}
test config-4.50 {DoObjConfig - null font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.51 {DoObjConfig - null font} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -font {}
    .foo cget -font
} -cleanup {
    killTables
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
    killTables
} -result {Times 16}

test config-4.53 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.54 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {gray75}
test config-4.55 {DoObjConfig - new bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo configure -bitmap gray50
} -cleanup {
    killTables
} -returnCodes ok -result 128
test config-4.56 {DoObjConfig - new bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo configure -bitmap gray50
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {gray50}
test config-4.57 {DoObjConfig - invalid bitmap} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -bitmap foobar
} -cleanup {
    killTables
} -returnCodes error -result {bitmap "foobar" not defined}
test config-4.58 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.59 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.60 {DoObjConfig - bitmap internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -bitmap gray25
    .foo cget -bitmap
} -cleanup {
    killTables
} -result {gray25}

test config-4.61 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.62 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result {green}
test config-4.63 {DoObjConfig - invalid border} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -border xxx
} -cleanup {
    killTables
} -returnCodes error -result {unknown color name "xxx"}
test config-4.64 {DoObjConfig - null border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.65 {DoObjConfig - null border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border {}
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.66 {DoObjConfig - border internal value} -constraints {







|





|












|











|















|





|





|











|







658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
    killTables
} -result {Times 16}

test config-4.53 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.54 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result gray75
test config-4.55 {DoObjConfig - new bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo configure -bitmap gray50
} -cleanup {
    killTables
} -returnCodes ok -result 128
test config-4.56 {DoObjConfig - new bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
    .foo configure -bitmap gray50
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result gray50
test config-4.57 {DoObjConfig - invalid bitmap} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -bitmap foobar
} -cleanup {
    killTables
} -returnCodes error -result {bitmap "foobar" not defined}
test config-4.58 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.59 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.60 {DoObjConfig - bitmap internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -bitmap gray25
    .foo cget -bitmap
} -cleanup {
    killTables
} -result gray25

test config-4.61 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.62 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result green
test config-4.63 {DoObjConfig - invalid border} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -border xxx
} -cleanup {
    killTables
} -returnCodes error -result {unknown color name "xxx"}
test config-4.64 {DoObjConfig - null border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.65 {DoObjConfig - null border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border {}
    .foo cget -border
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.66 {DoObjConfig - border internal value} -constraints {
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    killTables
} -returnCodes ok -result {#444444}

test config-4.69 {DoObjConfig - relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief flat
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.70 {DoObjConfig - relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief flat
    .foo cget -relief
} -cleanup {
    killTables
} -returnCodes ok -result {flat}
test config-4.71 {DoObjConfig - invalid relief} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -relief foo
} -cleanup {
    killTables
} -returnCodes error -result {bad relief "foo": must be flat, groove, raised, ridge, solid, or sunken}
test config-4.72 {DoObjConfig - relief internal value} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -relief ridge
    .foo cget -relief
} -cleanup {
    killTables
} -result {ridge}
test config-4.73 {DoObjConfig - new relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief raised
    .foo configure -relief flat
} -cleanup {
    killTables
} -returnCodes ok -result 512
test config-4.74 {DoObjConfig - new relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief raised
    .foo configure -relief flat
    .foo cget -relief
} -cleanup {
    killTables
} -returnCodes ok -result {flat}

test config-4.75 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.76 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {arrow}
test config-4.77 {DoObjConfig - invalid cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor foo
} -cleanup {
    killTables
} -returnCodes error -result {bad cursor spec "foo"}
test config-4.78 {DoObjConfig - null cursor} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -cursor {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.79 {DoObjConfig - null cursor} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -cursor {}
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.80 {DoObjConfig - new cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor xterm
    .foo configure -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result 1024
test config-4.81 {DoObjConfig - new cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor xterm
    .foo configure -cursor arrow
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {arrow}
test config-4.82 {DoObjConfig - cursor internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -cursor watch
    .foo cget -cursor
} -cleanup {
    killTables
} -result {watch}

test config-4.83 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.84 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
    .foo cget -justify
} -cleanup {
    killTables
} -returnCodes ok -result {center}
test config-4.85 {DoObjConfig - invalid justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify foo
} -cleanup {
    killTables
} -returnCodes error -result {bad justification "foo": must be left, right, or center}
test config-4.86 {DoObjConfig - new justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify left
    .foo configure -justify right
} -cleanup {
    killTables
} -returnCodes ok -result 2048
test config-4.87 {DoObjConfig - new justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify left
    .foo configure -justify right
    .foo cget -justify
} -cleanup {
    killTables
} -returnCodes ok -result {right}
test config-4.88 {DoObjConfig - justify internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -justify center
    .foo cget -justify
} -cleanup {
    killTables
} -result {center}

test config-4.89 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.90 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
    .foo cget -anchor
} -cleanup {
    killTables
} -returnCodes ok -result {center}
test config-4.91 {DoObjConfig - invalid anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor foo
} -cleanup {
    killTables
} -returnCodes error -result {bad anchor "foo": must be n, ne, e, se, s, sw, w, nw, or center}
test config-4.92 {DoObjConfig - new anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor e
    .foo configure -anchor n
} -cleanup {
    killTables
} -returnCodes ok -result 4096
test config-4.93 {DoObjConfig - new anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor e
    .foo configure -anchor n
    .foo cget -anchor
} -cleanup {
    killTables
} -returnCodes ok -result {n}
test config-4.94 {DoObjConfig - anchor internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -anchor sw
    .foo cget -anchor
} -cleanup {
    killTables
} -result {sw}
test config-4.95 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.96 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
    .foo cget -pixel
} -cleanup {
    killTables
} -returnCodes ok -result 42
test config-4.97 {DoObjConfig - invalid pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel foo
} -cleanup {
    killTables
} -returnCodes error -result {bad screen distance "foo"}
test config-4.98 {DoObjConfig - new pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42m
    .foo configure -pixel 3c
} -cleanup {
    killTables
} -returnCodes ok -result 8192
test config-4.99 {DoObjConfig - new pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42m
    .foo configure -pixel 3c
    .foo cget -pixel
} -cleanup {
    killTables
} -returnCodes ok -result {3c}
test config-4.100 {DoObjConfig - pixel internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -pixel [winfo screenmmwidth .]m
    set screenW [winfo screenwidth .]
    set result [.foo cget -pixel]
    expr {$screenW eq $result}
} -cleanup {
    killTables
} -result 1

test config-4.101 {DoObjConfig - window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window .bar
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.102 {DoObjConfig - window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window .bar
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {.bar}
test config-4.103 {DoObjConfig - invalid window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window foo
} -cleanup {
    killTables
} -returnCodes error -result {bad window path name "foo"}
test config-4.104 {DoObjConfig - null window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.105 {DoObjConfig - null window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window {}
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {}







|





|






|







|












|





|





|











|




















|









|





|





|




|












|









|





|





|




|












|









|




|










|












|


















|






|











|







768
769
770
771
772
773
774
775
776
777
778
779
780
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
    killTables
} -returnCodes ok -result {#444444}

test config-4.69 {DoObjConfig - relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief flat
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.70 {DoObjConfig - relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief flat
    .foo cget -relief
} -cleanup {
    killTables
} -returnCodes ok -result flat
test config-4.71 {DoObjConfig - invalid relief} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -relief foo
} -cleanup {
    killTables
} -returnCodes error -result {bad relief "foo": must be flat, groove, raised, ridge, solid, sunken, or ""}
test config-4.72 {DoObjConfig - relief internal value} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -relief ridge
    .foo cget -relief
} -cleanup {
    killTables
} -result ridge
test config-4.73 {DoObjConfig - new relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief raised
    .foo configure -relief flat
} -cleanup {
    killTables
} -returnCodes ok -result 512
test config-4.74 {DoObjConfig - new relief} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -relief raised
    .foo configure -relief flat
    .foo cget -relief
} -cleanup {
    killTables
} -returnCodes ok -result flat

test config-4.75 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.76 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result arrow
test config-4.77 {DoObjConfig - invalid cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor foo
} -cleanup {
    killTables
} -returnCodes error -result {bad cursor spec "foo"}
test config-4.78 {DoObjConfig - null cursor} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -cursor {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.79 {DoObjConfig - null cursor} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -cursor {}
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.80 {DoObjConfig - new cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor xterm
    .foo configure -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result 1024
test config-4.81 {DoObjConfig - new cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor xterm
    .foo configure -cursor arrow
    .foo cget -cursor
} -cleanup {
    killTables
} -returnCodes ok -result arrow
test config-4.82 {DoObjConfig - cursor internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -cursor watch
    .foo cget -cursor
} -cleanup {
    killTables
} -result watch

test config-4.83 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.84 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
    .foo cget -justify
} -cleanup {
    killTables
} -returnCodes ok -result center
test config-4.85 {DoObjConfig - invalid justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify foo
} -cleanup {
    killTables
} -returnCodes error -result {bad justification "foo": must be left, right, center, or ""}
test config-4.86 {DoObjConfig - new justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify left
    .foo configure -justify right
} -cleanup {
    killTables
} -returnCodes ok -result 2048
test config-4.87 {DoObjConfig - new justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify left
    .foo configure -justify right
    .foo cget -justify
} -cleanup {
    killTables
} -returnCodes ok -result right
test config-4.88 {DoObjConfig - justify internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -justify center
    .foo cget -justify
} -cleanup {
    killTables
} -result center

test config-4.89 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.90 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
    .foo cget -anchor
} -cleanup {
    killTables
} -returnCodes ok -result center
test config-4.91 {DoObjConfig - invalid anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor foo
} -cleanup {
    killTables
} -returnCodes error -result {bad anchor "foo": must be n, ne, e, se, s, sw, w, nw, center, or ""}
test config-4.92 {DoObjConfig - new anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor e
    .foo configure -anchor n
} -cleanup {
    killTables
} -returnCodes ok -result 4096
test config-4.93 {DoObjConfig - new anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor e
    .foo configure -anchor n
    .foo cget -anchor
} -cleanup {
    killTables
} -returnCodes ok -result n
test config-4.94 {DoObjConfig - anchor internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -anchor sw
    .foo cget -anchor
} -cleanup {
    killTables
} -result sw
test config-4.95 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.96 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
    .foo cget -pixel
} -cleanup {
    killTables
} -returnCodes ok -result 42
test config-4.97 {DoObjConfig - invalid pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel foo
} -cleanup {
    killTables
} -returnCodes error -result {expected screen distance or "" but got "foo"}
test config-4.98 {DoObjConfig - new pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42m
    .foo configure -pixel 3c
} -cleanup {
    killTables
} -returnCodes ok -result 8192
test config-4.99 {DoObjConfig - new pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42m
    .foo configure -pixel 3c
    .foo cget -pixel
} -cleanup {
    killTables
} -returnCodes ok -result 3c
test config-4.100 {DoObjConfig - pixel internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -pixel [winfo screenmmwidth .]m
    set screenW [winfo screenwidth .]
    set result [.foo cget -pixel]
    expr {$screenW eq $result}
} -cleanup {
    killTables
} -result 1

test config-4.101 {DoObjConfig - window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window .bar
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.102 {DoObjConfig - window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window .bar
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result .bar
test config-4.103 {DoObjConfig - invalid window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window foo
} -cleanup {
    killTables
} -returnCodes error -result {bad window path name "foo"}
test config-4.104 {DoObjConfig - null window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.105 {DoObjConfig - null window} -constraints testobjconfig -body {
    toplevel .bar
    testobjconfig twowindows .foo -window {}
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {}
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
    toplevel .bar
    toplevel .blamph
    testobjconfig twowindows .foo -window .bar
    .foo configure -window .blamph
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {.blamph}
test config-4.108 {DoObjConfig - window internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -window .
    .foo cget -window
} -cleanup {
    killTables
} -result {.}

test config-4.109 {DoObjConfig - releasing old values} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    # This test doesn't generate a useful value to check; if an







|









|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
    toplevel .bar
    toplevel .blamph
    testobjconfig twowindows .foo -window .bar
    .foo configure -window .blamph
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result .blamph
test config-4.108 {DoObjConfig - window internal value} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -window .
    .foo cget -window
} -cleanup {
    killTables
} -result .

test config-4.109 {DoObjConfig - releasing old values} -constraints {
    testobjconfig
} -setup {
    catch {rename .foo {}}
} -body {
    # This test doesn't generate a useful value to check; if an
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
    killTables
} -result {}

test config-4.111 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.112 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
    .foo cget -custom
} -cleanup {
    killTables
} -returnCodes ok -result {TEST}
test config-4.113 {DoObjConfig - null custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.114 {DoObjConfig - null custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom {}
    .foo cget -custom
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.115 {DoObjConfig - custom internal value} -constraints {







|





|




|







1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
    killTables
} -result {}

test config-4.111 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.112 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
    .foo cget -custom
} -cleanup {
    killTables
} -returnCodes ok -result TEST
test config-4.113 {DoObjConfig - null custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom {}
} -cleanup {
    killTables
} -returnCodes ok -result .foo
test config-4.114 {DoObjConfig - null custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom {}
    .foo cget -custom
} -cleanup {
    killTables
} -returnCodes ok -result {}
test config-4.115 {DoObjConfig - custom internal value} -constraints {
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
test config-6.2 {GetOptionFromObj - exact match} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -one
} -cleanup {
    killTables
} -result {one}
test config-6.3 {GetOptionFromObj - abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -fo
} -cleanup {
    killTables
} -result {four}
test config-6.4 {GetOptionFromObj - ambiguous abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -on
} -cleanup {
    killTables







|







|







1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
test config-6.2 {GetOptionFromObj - exact match} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -one
} -cleanup {
    killTables
} -result one
test config-6.3 {GetOptionFromObj - abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -fo
} -cleanup {
    killTables
} -result four
test config-6.4 {GetOptionFromObj - ambiguous abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -on
} -cleanup {
    killTables
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
    killTables
} -result {two and a half}
test config-6.6 {GetOptionFromObj - synonym} -constraints testobjconfig -body {
    testobjconfig alltypes .b
    .b cget -synonym
} -cleanup {
    killTables
} -result {red}


if {[testConstraint testobjconfig]} {
    testobjconfig alltypes .a
}
test config-7.1 {Tk_SetOptions - basics} -constraints testobjconfig -body {
    .a configure -color green -rel sunken
     list [.a cget -color] [.a cget -relief]
} -result {green sunken}
test config-7.2 {Tk_SetOptions - bogus option name} -constraints {
    testobjconfig
} -body {
    .a configure -bogus
} -returnCodes error -result {unknown option "-bogus"}
test config-7.3 {Tk_SetOptions - synonym} -constraints testobjconfig -body {
    .a configure -synonym blue
    .a cget -color
} -result {blue}
test config-7.4 {Tk_SetOptions - missing value} -constraints {
    testobjconfig
} -body {
    .a configure -color green -relief
} -returnCodes error -result {value for "-relief" missing}
test config-7.5 {Tk_SetOptions - missing value} -constraints {
    testobjconfig
} -body {
    catch {.a configure -color green -relief}
    .a cget -color
} -result {green}
test config-7.6 {Tk_SetOptions - saving old values} -constraints {
    testobjconfig
} -body {
    .a configure -color red -int 7 -relief raised -double 3.14159
    .a csave -color green -int 432 -relief sunken -double 2.0 -color bogus
} -returnCodes error -result {unknown color name "bogus"}
test config-7.7 {Tk_SetOptions - saving old values} -constraints {







|

















|










|







1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
    killTables
} -result {two and a half}
test config-6.6 {GetOptionFromObj - synonym} -constraints testobjconfig -body {
    testobjconfig alltypes .b
    .b cget -synonym
} -cleanup {
    killTables
} -result red


if {[testConstraint testobjconfig]} {
    testobjconfig alltypes .a
}
test config-7.1 {Tk_SetOptions - basics} -constraints testobjconfig -body {
    .a configure -color green -rel sunken
     list [.a cget -color] [.a cget -relief]
} -result {green sunken}
test config-7.2 {Tk_SetOptions - bogus option name} -constraints {
    testobjconfig
} -body {
    .a configure -bogus
} -returnCodes error -result {unknown option "-bogus"}
test config-7.3 {Tk_SetOptions - synonym} -constraints testobjconfig -body {
    .a configure -synonym blue
    .a cget -color
} -result blue
test config-7.4 {Tk_SetOptions - missing value} -constraints {
    testobjconfig
} -body {
    .a configure -color green -relief
} -returnCodes error -result {value for "-relief" missing}
test config-7.5 {Tk_SetOptions - missing value} -constraints {
    testobjconfig
} -body {
    catch {.a configure -color green -relief}
    .a cget -color
} -result green
test config-7.6 {Tk_SetOptions - saving old values} -constraints {
    testobjconfig
} -body {
    .a configure -color red -int 7 -relief raised -double 3.14159
    .a csave -color green -int 432 -relief sunken -double 2.0 -color bogus
} -returnCodes error -result {unknown color name "bogus"}
test config-7.7 {Tk_SetOptions - saving old values} -constraints {
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
} -body {
    testobjconfig alltypes .a
    catch {.a csave -color green -color black -color blue \
	    -color #ffff00 -color #ff00ff -color bogus}
	.a cget -color
} -cleanup {
    killTables
} -result {red}
test config-8.3 {Tk_RestoreSavedOptions - freeing object memory} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a csave -color green -color black -color blue -color #ffff00 -color #ff00ff
} -cleanup {
    killTables







|







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
} -body {
    testobjconfig alltypes .a
    catch {.a csave -color green -color black -color blue \
	    -color #ffff00 -color #ff00ff -color bogus}
	.a cget -color
} -cleanup {
    killTables
} -result red
test config-8.3 {Tk_RestoreSavedOptions - freeing object memory} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a csave -color green -color black -color blue -color #ffff00 -color #ff00ff
} -cleanup {
    killTables
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -double 62.4 -color bogus}
    .a cget -double
} -cleanup {
    killTables
} -result {3.14159}
test config-8.9 {Tk_RestoreSavedOptions - string internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -string "A long string" -color bogus}
	.a cget -string
} -cleanup {
    killTables
} -result {foo}
test config-8.10 {Tk_RestoreSavedOptions - string table internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -stringtable three -color bogus}
	.a cget -stringtable
} -cleanup {
    killTables
} -result {one}
test config-8.11 {Tk_RestoreSavedOptions - color internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -color green -color bogus}
    .a cget -color
} -cleanup {
    killTables
} -result {red}
test config-8.12 {Tk_RestoreSavedOptions - font internal form} -constraints {
    testobjconfig nonPortable
} -body {
    testobjconfig internal .a
    catch {.a csave -font {Times 12} -color bogus}
    .a cget -font
} -cleanup {
    killTables
} -result {Helvetica 12}
test config-8.13 {Tk_RestoreSavedOptions - bitmap internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -bitmap questhead -color bogus}
    .a cget -bitmap
} -cleanup {
    killTables
} -result {gray50}
test config-8.14 {Tk_RestoreSavedOptions - border internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -border brown -color bogus}
    .a cget -border
} -cleanup {
    killTables
} -result {blue}
test config-8.15 {Tk_RestoreSavedOptions - relief internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -relief sunken -color bogus}
    .a cget -relief
} -cleanup {
    killTables
} -result {raised}
test config-8.16 {Tk_RestoreSavedOptions - cursor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -cursor watch -color bogus}
    .a cget -cursor
} -cleanup {
    killTables
} -result {xterm}
test config-8.17 {Tk_RestoreSavedOptions - justify internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -justify right -color bogus}
    .a cget -justify
} -cleanup {
    killTables
} -result {left}
test config-8.18 {Tk_RestoreSavedOptions - anchor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -anchor center -color bogus}
    .a cget -anchor
} -cleanup {
    killTables
} -result {n}
test config-8.19 {Tk_RestoreSavedOptions - window internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a -window .a
    catch {.a csave -window .a -color bogus}
    .a cget -window
} -cleanup {
    killTables
} -result {.a}
test config-8.20 {Tk_RestoreSavedOptions - custom internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a -custom "foobar"
    catch {.a csave -custom "barbaz" -color bogus}
    .a cget -custom
} -cleanup {
    killTables
} -result {FOOBAR}

# Most of the tests below will cause memory leakage if there is a
# problem.  This may not be evident unless the tests are run in
# conjunction with a memory usage analyzer such as Purify.

test config-9.1 {Tk_FreeConfigOptions/FreeResources - string internal form} -constraints {
    testobjconfig







|








|








|








|

















|








|
|



|
|


|








|








|




|



|








|








|







1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -double 62.4 -color bogus}
    .a cget -double
} -cleanup {
    killTables
} -result 3.14159
test config-8.9 {Tk_RestoreSavedOptions - string internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -string "A long string" -color bogus}
	.a cget -string
} -cleanup {
    killTables
} -result foo
test config-8.10 {Tk_RestoreSavedOptions - string table internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -stringtable three -color bogus}
	.a cget -stringtable
} -cleanup {
    killTables
} -result one
test config-8.11 {Tk_RestoreSavedOptions - color internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -color green -color bogus}
    .a cget -color
} -cleanup {
    killTables
} -result red
test config-8.12 {Tk_RestoreSavedOptions - font internal form} -constraints {
    testobjconfig nonPortable
} -body {
    testobjconfig internal .a
    catch {.a csave -font {Times 12} -color bogus}
    .a cget -font
} -cleanup {
    killTables
} -result {Helvetica 12}
test config-8.13 {Tk_RestoreSavedOptions - bitmap internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -bitmap questhead -color bogus}
    .a cget -bitmap
} -cleanup {
    killTables
} -result gray50
test config-8.14 {Tk_RestoreSavedOptions - border internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -border brown -color bogus}
    .a cget -border
} -cleanup {
    killTables
} -result blue
test config-8.15 {Tk_RestoreSavedOptions - anchor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -anchor e -color bogus}
    .a cget -anchor
} -cleanup {
    killTables
} -result center
test config-8.16 {Tk_RestoreSavedOptions - cursor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -cursor watch -color bogus}
    .a cget -cursor
} -cleanup {
    killTables
} -result xterm
test config-8.17 {Tk_RestoreSavedOptions - justify internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -justify right -color bogus}
    .a cget -justify
} -cleanup {
    killTables
} -result left
test config-8.18 {Tk_RestoreSavedOptions - anchor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -anchor n -color bogus}
    .a cget -anchor
} -cleanup {
    killTables
} -result center
test config-8.19 {Tk_RestoreSavedOptions - window internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a -window .a
    catch {.a csave -window .a -color bogus}
    .a cget -window
} -cleanup {
    killTables
} -result .a
test config-8.20 {Tk_RestoreSavedOptions - custom internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a -custom "foobar"
    catch {.a csave -custom "barbaz" -color bogus}
    .a cget -custom
} -cleanup {
    killTables
} -result FOOBAR

# Most of the tests below will cause memory leakage if there is a
# problem.  This may not be evident unless the tests are run in
# conjunction with a memory usage analyzer such as Purify.

test config-9.1 {Tk_FreeConfigOptions/FreeResources - string internal form} -constraints {
    testobjconfig
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
if {[testConstraint testobjconfig]} {
    killTables
}


test config-10.1 {Tk_GetOptionInfo - one item} -constraints testobjconfig -body {
    testobjconfig alltypes .foo
    .foo configure -relief groove
    .foo configure -relief
} -cleanup {
    destroy .foo
} -result {-relief relief Relief raised groove}
test config-10.2 {Tk_GetOptionInfo - one item, synonym} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -color black
    .foo configure -synonym
} -cleanup {
    destroy .foo
} -result {-color color Color red black}
test config-10.3 {Tk_GetOptionInfo - all items} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -font {Helvetica 18} -integer 13563
    .foo configure
} -cleanup {
    destroy .foo
} -result {{-boolean boolean Boolean 1 1} {-integer integer Integer 7 13563} {-double double Double 3.14159 3.14159} {-string string String foo foo} {-stringtable StringTable stringTable one one} {-color color Color red red} {-font font Font {Helvetica 12} {Helvetica 18}} {-bitmap bitmap Bitmap gray50 gray50} {-border border Border blue blue} {-relief relief Relief raised raised} {-cursor cursor Cursor xterm xterm} {-justify {} {} left left} {-anchor anchor Anchor {} {}} {-pixel pixel Pixel 1 1} {-custom {} {} {} {}} {-synonym -color}}
test config-10.4 {Tk_GetOptionInfo - chaining through tables} -constraints testobjconfig -body {
    testobjconfig chain2 .foo -one asdf -three xyzzy
    .foo configure
} -cleanup {
    destroy .foo
} -result {{-three three Three three xyzzy} {-four four Four four four} {-two two Two {two and a half} {two and a half}} {-oneAgain oneAgain OneAgain {one again} {one again}} {-one one One one asdf} {-two two Two two {two and a half}}}
if {[testConstraint testobjconfig]} {







|
|


|
















|







1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
if {[testConstraint testobjconfig]} {
    killTables
}


test config-10.1 {Tk_GetOptionInfo - one item} -constraints testobjconfig -body {
    testobjconfig alltypes .foo
    .foo configure -anchor e
    .foo configure -anchor
} -cleanup {
    destroy .foo
} -result {-anchor anchor Anchor center e}
test config-10.2 {Tk_GetOptionInfo - one item, synonym} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo
    .foo configure -color black
    .foo configure -synonym
} -cleanup {
    destroy .foo
} -result {-color color Color red black}
test config-10.3 {Tk_GetOptionInfo - all items} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -font {Helvetica 18} -integer 13563
    .foo configure
} -cleanup {
    destroy .foo
} -result {{-boolean boolean Boolean {} {}} {-integer integer Integer 7 13563} {-double double Double 3.14159 3.14159} {-string string String foo foo} {-stringtable StringTable stringTable one one} {-stringtable2 StringTable2 stringTable2 two two} {-color color Color red red} {-font font Font {Helvetica 12} {Helvetica 18}} {-bitmap bitmap Bitmap gray50 gray50} {-border border Border blue blue} {-relief relief Relief {} {}} {-cursor cursor Cursor xterm xterm} {-justify {} {} left left} {-anchor anchor Anchor center center} {-pixel pixel Pixel 1 1} {-custom {} {} {} {}} {-synonym -color}}
test config-10.4 {Tk_GetOptionInfo - chaining through tables} -constraints testobjconfig -body {
    testobjconfig chain2 .foo -one asdf -three xyzzy
    .foo configure
} -cleanup {
    destroy .foo
} -result {{-three three Three three xyzzy} {-four four Four four four} {-two two Two {two and a half} {two and a half}} {-oneAgain oneAgain OneAgain {one again} {one again}} {-one one One one asdf} {-two two Two two {two and a half}}}
if {[testConstraint testobjconfig]} {
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
    testobjconfig
} -body {
    .a configure -justify
} -result {-justify {} {} left left}
test config-11.3 {GetConfigList - null default and current value} -constraints {
    testobjconfig
} -body {
    .a configure -anchor
} -result {-anchor anchor Anchor {} {}}
if {[testConstraint testobjconfig]} {
    killTables
}


if {[testConstraint testobjconfig]} {
    testobjconfig internal .a







|
|







1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
    testobjconfig
} -body {
    .a configure -justify
} -result {-justify {} {} left left}
test config-11.3 {GetConfigList - null default and current value} -constraints {
    testobjconfig
} -body {
    .a configure -relief
} -result {-relief relief Relief {} {}}
if {[testConstraint testobjconfig]} {
    killTables
}


if {[testConstraint testobjconfig]} {
    testobjconfig internal .a
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
    .a cget -string
} -result {test value}
test config-12.5 {GetObjectForOption - stringTable} -constraints {
    testobjconfig
} -body {
    .a configure -stringtable "two"
    .a cget -stringtable
} -result {two}
test config-12.6 {GetObjectForOption - color} -constraints testobjconfig -body {
    .a configure -color "green"
    .a cget -color
} -result {green}
test config-12.7 {GetObjectForOption - font} -constraints testobjconfig -body {
    .a configure -font {Times 36}
    .a cget -font
} -result {Times 36}
test config-12.8 {GetObjectForOption - bitmap} -constraints testobjconfig -body {
    .a configure -bitmap "questhead"
    .a cget -bitmap
} -result {questhead}
test config-12.9 {GetObjectForOption - border} -constraints testobjconfig -body {
    .a configure -border #33217c
    .a cget -border
} -result {#33217c}
test config-12.10 {GetObjectForOption - relief} -constraints {
    testobjconfig
} -body {
    .a configure -relief groove
    .a cget -relief
} -result {groove}
test config-12.11 {GetObjectForOption - cursor} -constraints {
    testobjconfig
} -body {
    .a configure -cursor watch
    .a cget -cursor
} -result {watch}
test config-12.12 {GetObjectForOption - justify} -constraints {
    testobjconfig
} -body {
    .a configure -justify right
    .a cget -justify
} -result {right}
test config-12.13 {GetObjectForOption - anchor} -constraints testobjconfig -body {
    .a configure -anchor e
    .a cget -anchor
} -result {e}
test config-12.14 {GetObjectForOption - pixels} -constraints testobjconfig -body {
    .a configure -pixel 193.2
    .a cget -pixel
} -result 193
test config-12.15 {GetObjectForOption - window} -constraints testobjconfig -body {
    .a configure -window .a
    .a cget -window
} -result {.a}
test config-12.16 {GetObjectForOption -custom} -constraints testobjconfig -body {
    .a configure -custom foobar
    .a cget -custom
} -result {FOOBAR}
test config-12.17 {GetObjectForOption - null values} -constraints {
    testobjconfig
} -body {
    .a configure -string {} -color {} -font {} -bitmap {} -border {} \
	    -cursor {} -window {} -custom {}
    list [.a cget -string] [.a cget -color] [.a cget -font] \
	    [.a cget -bitmap] [.a cget -border] [.a cget -cursor] \







|



|







|









|





|





|



|







|



|







1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
    .a cget -string
} -result {test value}
test config-12.5 {GetObjectForOption - stringTable} -constraints {
    testobjconfig
} -body {
    .a configure -stringtable "two"
    .a cget -stringtable
} -result two
test config-12.6 {GetObjectForOption - color} -constraints testobjconfig -body {
    .a configure -color "green"
    .a cget -color
} -result green
test config-12.7 {GetObjectForOption - font} -constraints testobjconfig -body {
    .a configure -font {Times 36}
    .a cget -font
} -result {Times 36}
test config-12.8 {GetObjectForOption - bitmap} -constraints testobjconfig -body {
    .a configure -bitmap "questhead"
    .a cget -bitmap
} -result questhead
test config-12.9 {GetObjectForOption - border} -constraints testobjconfig -body {
    .a configure -border #33217c
    .a cget -border
} -result {#33217c}
test config-12.10 {GetObjectForOption - relief} -constraints {
    testobjconfig
} -body {
    .a configure -relief groove
    .a cget -relief
} -result groove
test config-12.11 {GetObjectForOption - cursor} -constraints {
    testobjconfig
} -body {
    .a configure -cursor watch
    .a cget -cursor
} -result watch
test config-12.12 {GetObjectForOption - justify} -constraints {
    testobjconfig
} -body {
    .a configure -justify right
    .a cget -justify
} -result right
test config-12.13 {GetObjectForOption - anchor} -constraints testobjconfig -body {
    .a configure -anchor e
    .a cget -anchor
} -result e
test config-12.14 {GetObjectForOption - pixels} -constraints testobjconfig -body {
    .a configure -pixel 193.2
    .a cget -pixel
} -result 193
test config-12.15 {GetObjectForOption - window} -constraints testobjconfig -body {
    .a configure -window .a
    .a cget -window
} -result .a
test config-12.16 {GetObjectForOption -custom} -constraints testobjconfig -body {
    .a configure -custom foobar
    .a cget -custom
} -result FOOBAR
test config-12.17 {GetObjectForOption - null values} -constraints {
    testobjconfig
} -body {
    .a configure -string {} -color {} -font {} -bitmap {} -border {} \
	    -cursor {} -window {} -custom {}
    list [.a cget -string] [.a cget -color] [.a cget -font] \
	    [.a cget -bitmap] [.a cget -border] [.a cget -cursor] \

Changes to tests/constraints.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if {[namespace exists tk::test]} {
    deleteWindows
    wm geometry . {}
    raise .
    return
}

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 .]} {







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if {[namespace exists tk::test]} {
    deleteWindows
    wm geometry . {}
    raise .
    return
}

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 .]} {
117
118
119
120
121
122
123
124






125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174































































175
176
177
178
179
180
181
	}
	Export bg::setup as setupbg
	Export bg::cleanup as cleanupbg
	Export bg::do as dobg

	namespace export deleteWindows
	proc deleteWindows {} {
	    eval destroy [winfo children .]






	}

	namespace export fixfocus
	proc fixfocus {} {
            catch {destroy .focus}
            toplevel .focus
            wm geometry .focus +0+0
            entry .focus.e
            .focus.e insert 0 "fixfocus"
            pack .focus.e
            update
            focus -force .focus.e
            destroy .focus
	}


        namespace export imageInit imageFinish imageCleanup imageNames
        variable ImageNames
        proc imageInit {} {
            variable ImageNames
            if {![info exists ImageNames]} {
                set ImageNames [lsort [image names]]
            }
            imageCleanup
            if {[lsort [image names]] ne $ImageNames} {
                return -code error "IMAGE NAMES mismatch: [image names] != $ImageNames"
            }
        }
        proc imageFinish {} {
            variable ImageNames

            if {[lsort [image names]] ne $ImageNames} {
                return -code error "images remaining: [image names] != $ImageNames"
            }
            imageCleanup
        }
        proc imageCleanup {} {
            variable ImageNames
            foreach img [image names] {
                if {$img ni $ImageNames} {image delete $img}
            }
        }
        proc imageNames {} {
            variable ImageNames
            set r {}
            foreach img [image names] {
                if {$img ni $ImageNames} {lappend r $img}
            }
            return $r
        }
































































    }
}

namespace import -force tk::test::*

namespace import -force tcltest::testConstraint
testConstraint notAqua [expr {[tk windowingsystem] ne "aqua"}]







|
>
>
>
>
>
>















<





|








>
|



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
	}
	Export bg::setup as setupbg
	Export bg::cleanup as cleanupbg
	Export bg::do as dobg

	namespace export deleteWindows
	proc deleteWindows {} {
	    destroy {*}[winfo children .]
	    # This update is needed to avoid intermittent failures on macOS in unixEmbed.test
	    # with the (GitHub Actions) CI runner.
	    # Reason for the failures is unclear but could have to do with window ids being deleted
	    # after the destroy command returns. The detailed mechanism of such delayed deletions
	    # is not understood, but it appears that this update prevents the test failures.
	    update
	}

	namespace export fixfocus
	proc fixfocus {} {
            catch {destroy .focus}
            toplevel .focus
            wm geometry .focus +0+0
            entry .focus.e
            .focus.e insert 0 "fixfocus"
            pack .focus.e
            update
            focus -force .focus.e
            destroy .focus
	}


        namespace export imageInit imageFinish imageCleanup imageNames
        variable ImageNames
        proc imageInit {} {
            variable ImageNames
            if {![info exists ImageNames]} {
                set ImageNames [lsearch -all -inline -glob -not [lsort [image names]] ::tk::icons::indicator*]
            }
            imageCleanup
            if {[lsort [image names]] ne $ImageNames} {
                return -code error "IMAGE NAMES mismatch: [image names] != $ImageNames"
            }
        }
        proc imageFinish {} {
            variable ImageNames
	    set imgs [lsearch -all -inline -glob -not [lsort [image names]] ::tk::icons::indicator*]
            if {$imgs ne $ImageNames} {
                return -code error "images remaining: [image names] != $ImageNames"
            }
            imageCleanup
        }
        proc imageCleanup {} {
            variable ImageNames
            foreach img [image names] {
                if {$img ni $ImageNames} {image delete $img}
            }
        }
        proc imageNames {} {
            variable ImageNames
            set r {}
            foreach img [image names] {
                if {$img ni $ImageNames} {lappend r $img}
            }
            return $r
        }

	#
	#  CONTROL TIMING ASPECTS OF POINTER WARPING
	#
	# The proc [controlPointerWarpTiming] is intended to ensure that the (mouse)
	# pointer has actually been moved to its new position after a Tk test issued:
	#
	#    [event generate $w $event -warp 1 ...]
	#
	# It takes care of the following timing details of pointer warping:
	#
	# a. Allow pointer warping to happen if it was scheduled for execution at
	#    idle time. This happens synchronously if $w refers to the
	#    whole screen or if the -when option to [event generate] is "now".
	#
	# b. Work around a race condition associated with OS notification of
	#    mouse motion on Windows.
	#
	#    When calling [event generate $w $event -warp 1 ...], the following
	#    sequence occurs:
	#    - At some point in the processing of this command, either via a
	#      synchronous execution path, or asynchronously at idle time, Tk calls
	#      an OS function* to carry out the mouse cursor motion.
	#    - Tk has previously registered a callback function** with the OS, for
	#      the OS to call in order to notify Tk when a mouse move is completed.
	#    - Tk doesn't wait for the callback function to receive the notification
	#      from the OS, but continues processing. This suits most use cases
	#      because usually the notification arrives fast enough (within a few tens
	#      of microseconds). However ...
	#    - A problem arises if Tk performs some processing, immediately following
	#      up on [event generate $w $event -warp 1 ...], and that processing
	#      relies on the mouse pointer having actually moved. If such processing
	#      happens just before the notification from the OS has been received,
	#      Tk will be using not yet updated info (e.g. mouse coordinates).
	#
	#         Hickup, choke etc ... !
	#
	#            *  the function SendInput() of the Win32 API
	#            ** the callback function is TkWinChildProc()
	#
	#    This timing issue can be addressed by putting the Tk process on hold
	#    (do nothing at all) for a somewhat extended amount of time, while
	#    letting the OS complete its job in the meantime. This is what is
	#    accomplished by calling [after ms].
	#
	#    ----
	#    For the history of this issue please refer to Tk ticket [69b48f427e],
	#    specifically the comment on 2019-10-27 14:24:26.
	#
	#
	# Beware: there are cases, not (yet) exercised by the Tk test suite, where
	# [controlPointerWarpTiming] doesn't ensure the new position of the pointer.
	# For example, when issued under Tk8.7+, if the value for the -when option
	# to [event generate $w] is not "now", and $w refers to a Tk window, i.e. not
	# the whole screen.
	#
	proc controlPointerWarpTiming {{duration 50}} {
		update idletasks ;# see a. above
		if {[tk windowingsystem] eq "win32"} {
			after $duration ;# see b. above
		}
	}
	namespace export controlPointerWarpTiming

    }
}

namespace import -force tk::test::*

namespace import -force tcltest::testConstraint
testConstraint notAqua [expr {[tk windowingsystem] ne "aqua"}]
191
192
193
194
195
196
197





198
199
200
201
202
203
204
    ([testConstraint unix] && [testConstraint notAqua])
}]
testConstraint haveDISPLAY [expr {[info exists env(DISPLAY)] && [testConstraint x11]}]
testConstraint altDisplay  [info exists env(TK_ALT_DISPLAY)]
testConstraint noExceed [expr {
    ![testConstraint unix] || [catch {font actual "\{xyz"}]
}]






# constraints for testing facilities defined in the tktest executable...
testConstraint testImageType [expr {"test" in [image types]}]
testConstraint testOldImageType [expr {"oldtest" in [image types]}]
testConstraint testbitmap    [llength [info commands testbitmap]]
testConstraint testborder    [llength [info commands testborder]]
testConstraint testcbind     [llength [info commands testcbind]]







>
>
>
>
>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    ([testConstraint unix] && [testConstraint notAqua])
}]
testConstraint haveDISPLAY [expr {[info exists env(DISPLAY)] && [testConstraint x11]}]
testConstraint altDisplay  [info exists env(TK_ALT_DISPLAY)]
testConstraint noExceed [expr {
    ![testConstraint unix] || [catch {font actual "\{xyz"}]
}]
testConstraint deprecated [expr {![::tk::build-info no-deprecate]}]

# constraint for running a test on all windowing system except aqua
# where the test fails due to a known bug
testConstraint aquaKnownBug [expr {[testConstraint notAqua] || [testConstraint knownBug]}]

# constraints for testing facilities defined in the tktest executable...
testConstraint testImageType [expr {"test" in [image types]}]
testConstraint testOldImageType [expr {"oldtest" in [image types]}]
testConstraint testbitmap    [llength [info commands testbitmap]]
testConstraint testborder    [llength [info commands testborder]]
testConstraint testcbind     [llength [info commands testcbind]]
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237












238


239

240
















241
242
243
244
245
246
247
248
249
testConstraint testmetrics   [llength [info commands testmetrics]]
testConstraint testobjconfig [llength [info commands testobjconfig]]
testConstraint testsend      [llength [info commands testsend]]
testConstraint testtext      [llength [info commands testtext]]
testConstraint testwinevent  [llength [info commands testwinevent]]
testConstraint testwrapper   [llength [info commands testwrapper]]

# constraint to see what sort of fonts are available
testConstraint fonts 1
destroy .e
entry .e -width 0 -font {Helvetica -12} -bd 1 -highlightthickness 1
.e insert end a.bcd
if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
    testConstraint fonts 0
}
destroy .e
destroy .t
text .t -width 80 -height 20 -font {Times -14} -bd 1
pack .t
.t insert end "This is\na dot."
update
set x [list [.t bbox 1.3] [.t bbox 2.5]]
destroy .t
if {![string match {{22 3 6 15} {31 18 [34] 15}} $x]} {
    testConstraint fonts 0
}












testConstraint textfonts [expr {


    [testConstraint fonts] || [tk windowingsystem] eq "win32"

}]

















# constraints for the visuals available..
testConstraint pseudocolor8 [expr {
    ([catch {
	toplevel .t -visual {pseudocolor 8} -colormap new
    }] == 0) && ([winfo depth .t] == 8)
}]
destroy .t
testConstraint haveTruecolor24 [expr {







|


















>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
testConstraint testmetrics   [llength [info commands testmetrics]]
testConstraint testobjconfig [llength [info commands testobjconfig]]
testConstraint testsend      [llength [info commands testsend]]
testConstraint testtext      [llength [info commands testtext]]
testConstraint testwinevent  [llength [info commands testwinevent]]
testConstraint testwrapper   [llength [info commands testwrapper]]

# constraints about what sort of fonts are available
testConstraint fonts 1
destroy .e
entry .e -width 0 -font {Helvetica -12} -bd 1 -highlightthickness 1
.e insert end a.bcd
if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
    testConstraint fonts 0
}
destroy .e
destroy .t
text .t -width 80 -height 20 -font {Times -14} -bd 1
pack .t
.t insert end "This is\na dot."
update
set x [list [.t bbox 1.3] [.t bbox 2.5]]
destroy .t
if {![string match {{22 3 6 15} {31 18 [34] 15}} $x]} {
    testConstraint fonts 0
}
# Although unexpected, some systems may have a very limited set of fonts available.
# The following constraints happen to evaluate to false at least on one system: the
# Github CI runner for Linux with --disable-xft, which has exactly ONE single font
# ([font families] returns a single element: "fixed"), for which [font actual]
# returns:
#    -family fixed -size 9 -weight normal -slant roman -underline 0
# and [font metrics] returns:
#    -ascent 11 -descent 2 -linespace 13 -fixed 1
# The following constraints are hence tailored to check exactly what is needed in the
# tests they constrain (that is: availability of any font having the given font
# attributes), so that these constrained tests will in fact run on all systems having
# reasonable font dotation.
testConstraint haveTimes12Font [expr {
    [font actual {times 12} -size] == 12
}]
testConstraint haveCourier37Font [expr {
    [font actual {-family courier -size 37} -size] == 37
}]
testConstraint haveTimes14BoldFont [expr {
    ([font actual {times 14 bold} -size] == 14) &&
    ([font actual {times 14 bold} -weight] eq "bold")
}]
testConstraint haveTimes12BoldItalicUnderlineOverstrikeFont [expr {
    ([font actual {times 12 bold italic overstrike underline} -weight] eq "bold") &&
    ([font actual {times 12 bold italic overstrike underline} -slant] eq "italic") &&
    ([font actual {times 12 bold italic overstrike underline} -underline] eq "1") &&
    ([font actual {times 12 bold italic overstrike underline} -overstrike] eq "1")
}]
set fixedFont {Courier 12}   ; # warning: must be consistent with the files using the constraint below!
set bigFont   {Helvetica 24} ; # ditto
testConstraint haveBigFontTwiceLargerThanTextFont [expr {
    [font actual $fixedFont -size] * 2 <= [font actual $bigFont -size]
}]
unset fixedFont bigFont

# constraints for the visuals available
testConstraint pseudocolor8 [expr {
    ([catch {
	toplevel .t -visual {pseudocolor 8} -colormap new
    }] == 0) && ([winfo depth .t] == 8)
}]
destroy .t
testConstraint haveTruecolor24 [expr {
279
280
281
282
283
284
285
286
namespace import -force tcltest::interpreter
namespace import -force tcltest::testsDirectory
namespace import -force tcltest::cleanupTests

deleteWindows
wm geometry . {}
raise .








<
384
385
386
387
388
389
390

namespace import -force tcltest::interpreter
namespace import -force tcltest::testsDirectory
namespace import -force tcltest::cleanupTests

deleteWindows
wm geometry . {}
raise .

Changes to tests/cursor.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkCursor.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkCursor.c.  It is organized in the standard white-box fashion for
# Tcl tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/earth.gif.

cannot compute difference between binary files

Changes to tests/embed.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# This file is a Tcl script to test out embedded Windows.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands


test embed-1.1 {TkpUseWindow procedure, bad window identifier} -setup {
    deleteWindows
} -body {
    toplevel .t -use xyz
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "xyz"}




|








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# This file is a Tcl script to test out embedded Windows.
#
# 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


test embed-1.1 {Tk_UseWindow procedure, bad window identifier} -setup {
    deleteWindows
} -body {
    toplevel .t -use xyz
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "xyz"}

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    toplevel .container -container 1
    toplevel .t -use [winfo id .container] -container 1
} -cleanup {
    deleteWindows
} -returnCodes error -result {windows cannot have both the -use and the -container option set}

# testing window embedding for win platforms
test embed-1.4.win {TkpUseWindow procedure, -container must be set} -constraints {
	win
} -setup {
    deleteWindows
} -body {
    toplevel .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {the window to use is not a Tk container}
# testing window embedding for win platforms
test embed-1.5.win {TkpUseWindow procedure, -container must be set} -constraints {
	win
} -setup {
    deleteWindows
} -body {
    frame .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {the window to use is not a Tk container}

# testing window embedding for other than win platforms
test embed-1.4.nonwin {TkpUseWindow procedure, -container must be set} -constraints {
	nonwin
} -setup {
    deleteWindows
} -body {
    toplevel .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {window ".container" doesn't have -container option set}
# testing window embedding for other than win platforms
test embed-1.5.nonwin {TkpUseWindow procedure, -container must be set} -constraints {
	nonwin
} -setup {
    deleteWindows
} -body {
    frame .container
    toplevel .embd -use [winfo id .container]
} -cleanup {







|










|











|










|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    toplevel .container -container 1
    toplevel .t -use [winfo id .container] -container 1
} -cleanup {
    deleteWindows
} -returnCodes error -result {windows cannot have both the -use and the -container option set}

# testing window embedding for win platforms
test embed-1.4.win {Tk_UseWindow procedure, -container must be set} -constraints {
	win
} -setup {
    deleteWindows
} -body {
    toplevel .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {the window to use is not a Tk container}
# testing window embedding for win platforms
test embed-1.5.win {Tk_UseWindow procedure, -container must be set} -constraints {
	win
} -setup {
    deleteWindows
} -body {
    frame .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {the window to use is not a Tk container}

# testing window embedding for other than win platforms
test embed-1.4.nonwin {Tk_UseWindow procedure, -container must be set} -constraints {
	nonwin
} -setup {
    deleteWindows
} -body {
    toplevel .container
    toplevel .embd -use [winfo id .container]
} -cleanup {
    deleteWindows
} -returnCodes error -result {window ".container" doesn't have -container option set}
# testing window embedding for other than win platforms
test embed-1.5.nonwin {Tk_UseWindow procedure, -container must be set} -constraints {
	nonwin
} -setup {
    deleteWindows
} -body {
    frame .container
    toplevel .embd -use [winfo id .container]
} -cleanup {

Changes to tests/entry.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace variable
proc override args {
        global x
        set x 12345
}

# Procedures used in widget VALIDATION tests
proc doval {W d i P s S v V} {





|







<
<
<
<






|







1
2
3
4
5
6
7
8
9
10
11
12
13




14
15
16
17
18
19
20
21
22
23
24
25
26
27
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands





# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace add variable
proc override args {
        global x
        set x 12345
}

# Procedures used in widget VALIDATION tests
proc doval {W d i P s S v V} {
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
}

set cy [font metrics {Courier -12} -linespace]


test entry-1.1 {configuration option: "background" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -background #ff0000
    .e cget -background
} -cleanup {
    destroy .e
} -result {#ff0000}
test entry-1.2 {configuration option: "background" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -background non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.3 {configuration option: "bd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test entry-1.4 {configuration option: "bd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.5 {configuration option: "bg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bg #ff0000
    .e cget -bg
} -cleanup {
    destroy .e
} -result {#ff0000}
test entry-1.6 {configuration option: "bg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -bg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.7 {configuration option: "borderwidth" for entry} -setup {
    entry .e -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -borderwidth 1.3
    .e cget -borderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.8 {configuration option: "borderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.9 {configuration option: "cursor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -cursor arrow
    .e cget -cursor
} -cleanup {
    destroy .e
} -result {arrow}
test entry-1.10 {configuration option: "cursor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -cursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}

test entry-1.11 {configuration option: "disabledbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledbackground green
    .e cget -disabledbackground
} -cleanup {
    destroy .e
} -result {green}
test entry-1.12 {configuration option: "disabledbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.13 {configuration option: "disabledforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledforeground blue
    .e cget -disabledforeground
} -cleanup {
    destroy .e
} -result {blue}
test entry-1.14 {configuration option: "disabledforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -disabledforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.15 {configuration option: "exportselection" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -exportselection yes
    .e cget -exportselection
} -cleanup {
    destroy .e
} -result 1
test entry-1.16 {configuration option: "exportselection" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -exportselection xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}

test entry-1.17 {configuration option: "fg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -fg #110022
    .e cget -fg
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.18 {configuration option: "fg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -fg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.19 {configuration option: "font" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e configure -font {Helvetica -12}
    .e cget -font
} -cleanup {
    destroy .e
} -result {Helvetica -12}
test entry-1.20 {configuration option: "font" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e configure -font {}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {font "" doesn't exist}

test entry-1.21 {configuration option: "foreground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -foreground #110022
    .e cget -foreground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.22 {configuration option: "foreground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -foreground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.23 {configuration option: "highlightbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightbackground #110022
    .e cget -highlightbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.24 {configuration option: "highlightbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.25 {configuration option: "highlightcolor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightcolor #110022
    .e cget -highlightcolor
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.26 {configuration option: "highlightcolor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightcolor non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.27 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightthickness 6
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 6
test entry-1.28 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightthickness -2
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 0
test entry-1.29 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -highlightthickness badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.30 {configuration option: "insertbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertbackground #110022
    .e cget -insertbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.31 {configuration option: "insertbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.32 {configuration option: "insertborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -insertwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertborderwidth 1.3
    .e cget -insertborderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.33 {configuration option: "insertborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "2.6x"}

test entry-1.34 {configuration option: "insertofftime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertofftime 100
    .e cget -insertofftime
} -cleanup {
    destroy .e
} -result 100
test entry-1.35 {configuration option: "insertofftime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertofftime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test entry-1.36 {configuration option: "insertontime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertontime 100
    .e cget -insertontime
} -cleanup {
    destroy .e
} -result 100
test entry-1.37 {configuration option: "insertontime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -insertontime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test entry-1.38 {configuration option: "invalidcommand" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -invalidcommand "any string"
    .e cget -invalidcommand
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.39 {configuration option: "invcmd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -invcmd "any string"
    .e cget -invcmd
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.40 {configuration option: "justify" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -justify right
    .e cget -justify
} -cleanup {
    destroy .e
} -result {right}
test entry-1.41 {configuration option: "justify" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -justify bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}

test entry-1.42 {configuration option: "readonlybackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -readonlybackground green
    .e cget -readonlybackground
} -cleanup {
    destroy .e
} -result {green}
test entry-1.43 {configuration option: "readonlybackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -readonlybackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.44 {configuration option: "relief" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -relief flat
    .e cget -relief
} -cleanup {
    destroy .e
} -result {flat}

test entry-1.45 {configuration option: "selectbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectbackground #110022
    .e cget -selectbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.46 {configuration option: "selectbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.47 {configuration option: "selectborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectborderwidth 1.3
    .e cget -selectborderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.48 {configuration option: "selectborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test entry-1.49 {configuration option: "selectforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectforeground #110022
    .e cget -selectforeground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.50 {configuration option: "selectforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -selectforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.51 {configuration option: "show" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -show *
    .e cget -show
} -cleanup {
    destroy .e
} -result {*}

test entry-1.52 {configuration option: "state" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -state n
    .e cget -state
} -cleanup {
    destroy .e
} -result {normal}
test entry-1.53 {configuration option: "state" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -state bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad state "bogus": must be disabled, normal, or readonly}

test entry-1.54 {configuration option: "takefocus" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -takefocus "any string"
    .e cget -takefocus
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.55 {configuration option: "textvariable" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -textvariable i
    .e cget -textvariable
} -cleanup {
    destroy .e
} -result {i}

test entry-1.56 {configuration option: "width" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -width 402
    .e cget -width
} -cleanup {
    destroy .e
} -result 402
test entry-1.57 {configuration option: "width" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -width 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}

test entry-1.58 {configuration option: "xscrollcommand" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e
    update
} -body {
    .e configure -xscrollcommand {Some command}
    .e cget -xscrollcommand
} -cleanup {
    destroy .e
} -result {Some command}







|









|









|









|





|



|









|









|









|





|



|









|









|









|









|









|









|









|









|









|









|









|









|









|









|









|









|









|









|









|









|





|



|









|









|









|





|



|









|









|









|









|










|










|









|









|









|









|










|









|









|









|





|



|









|









|










|









|









|










|










|









|









|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
}

set cy [font metrics {Courier -12} -linespace]


test entry-1.1 {configuration option: "background" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -background #ff0000
    .e cget -background
} -cleanup {
    destroy .e
} -result {#ff0000}
test entry-1.2 {configuration option: "background" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -background non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.3 {configuration option: "bd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test entry-1.4 {configuration option: "bd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test entry-1.5 {configuration option: "bg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -bg #ff0000
    .e cget -bg
} -cleanup {
    destroy .e
} -result {#ff0000}
test entry-1.6 {configuration option: "bg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -bg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.7 {configuration option: "borderwidth" for entry} -setup {
    entry .e -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -borderwidth 1.3
    .e cget -borderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.8 {configuration option: "borderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test entry-1.9 {configuration option: "cursor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -cursor arrow
    .e cget -cursor
} -cleanup {
    destroy .e
} -result {arrow}
test entry-1.10 {configuration option: "cursor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -cursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}

test entry-1.11 {configuration option: "disabledbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -disabledbackground green
    .e cget -disabledbackground
} -cleanup {
    destroy .e
} -result {green}
test entry-1.12 {configuration option: "disabledbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -disabledbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.13 {configuration option: "disabledforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -disabledforeground blue
    .e cget -disabledforeground
} -cleanup {
    destroy .e
} -result {blue}
test entry-1.14 {configuration option: "disabledforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -disabledforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.15 {configuration option: "exportselection" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -exportselection yes
    .e cget -exportselection
} -cleanup {
    destroy .e
} -result 1
test entry-1.16 {configuration option: "exportselection" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -exportselection xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}

test entry-1.17 {configuration option: "fg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -fg #110022
    .e cget -fg
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.18 {configuration option: "fg" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -fg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.19 {configuration option: "font" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e configure -font {Helvetica -12}
    .e cget -font
} -cleanup {
    destroy .e
} -result {Helvetica -12}
test entry-1.20 {configuration option: "font" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e configure -font {}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {font "" doesn't exist}

test entry-1.21 {configuration option: "foreground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -foreground #110022
    .e cget -foreground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.22 {configuration option: "foreground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -foreground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.23 {configuration option: "highlightbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightbackground #110022
    .e cget -highlightbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.24 {configuration option: "highlightbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.25 {configuration option: "highlightcolor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightcolor #110022
    .e cget -highlightcolor
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.26 {configuration option: "highlightcolor" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightcolor non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.27 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightthickness 6
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 6
test entry-1.28 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightthickness -2
    .e cget -highlightthickness
} -cleanup {
    destroy .e
} -result 0
test entry-1.29 {configuration option: "highlightthickness" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightthickness badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test entry-1.30 {configuration option: "insertbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertbackground #110022
    .e cget -insertbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.31 {configuration option: "insertbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.32 {configuration option: "insertborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -insertwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertborderwidth 1.3
    .e cget -insertborderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.33 {configuration option: "insertborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "2.6x"}

test entry-1.34 {configuration option: "insertofftime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertofftime 100
    .e cget -insertofftime
} -cleanup {
    destroy .e
} -result 100
test entry-1.35 {configuration option: "insertofftime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertofftime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test entry-1.36 {configuration option: "insertontime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertontime 100
    .e cget -insertontime
} -cleanup {
    destroy .e
} -result 100
test entry-1.37 {configuration option: "insertontime" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertontime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}

test entry-1.38 {configuration option: "invalidcommand" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -invalidcommand "any string"
    .e cget -invalidcommand
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.39 {configuration option: "invcmd" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -invcmd "any string"
    .e cget -invcmd
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.40 {configuration option: "justify" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -justify right
    .e cget -justify
} -cleanup {
    destroy .e
} -result {right}
test entry-1.41 {configuration option: "justify" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -justify bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}

test entry-1.42 {configuration option: "readonlybackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -readonlybackground green
    .e cget -readonlybackground
} -cleanup {
    destroy .e
} -result {green}
test entry-1.43 {configuration option: "readonlybackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -readonlybackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.44 {configuration option: "relief" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -relief flat
    .e cget -relief
} -cleanup {
    destroy .e
} -result {flat}

test entry-1.45 {configuration option: "selectbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectbackground #110022
    .e cget -selectbackground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.46 {configuration option: "selectbackground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.47 {configuration option: "selectborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectborderwidth 1.3
    .e cget -selectborderwidth
} -cleanup {
    destroy .e
} -result 1
test entry-1.48 {configuration option: "selectborderwidth" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test entry-1.49 {configuration option: "selectforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectforeground #110022
    .e cget -selectforeground
} -cleanup {
    destroy .e
} -result {#110022}
test entry-1.50 {configuration option: "selectforeground" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}

test entry-1.51 {configuration option: "show" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -show *
    .e cget -show
} -cleanup {
    destroy .e
} -result {*}

test entry-1.52 {configuration option: "state" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -state n
    .e cget -state
} -cleanup {
    destroy .e
} -result {normal}
test entry-1.53 {configuration option: "state" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -state bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad state "bogus": must be disabled, normal, or readonly}

test entry-1.54 {configuration option: "takefocus" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -takefocus "any string"
    .e cget -takefocus
} -cleanup {
    destroy .e
} -result {any string}

test entry-1.55 {configuration option: "textvariable" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -textvariable i
    .e cget -textvariable
} -cleanup {
    destroy .e
} -result {i}

test entry-1.56 {configuration option: "width" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -width 402
    .e cget -width
} -cleanup {
    destroy .e
} -result 402
test entry-1.57 {configuration option: "width" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -width 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}

test entry-1.58 {configuration option: "xscrollcommand" for entry} -setup {
    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .e ; update idletasks
    update
} -body {
    .e configure -xscrollcommand {Some command}
    .e cget -xscrollcommand
} -cleanup {
    destroy .e
} -result {Some command}
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
    entry
} -returnCodes error -result {wrong # args: should be "entry pathName ?-option value ...?"}
test entry-2.2 {Tk_EntryCmd procedure} -body {
    entry gorp
} -returnCodes error -result {bad window path name "gorp"}
test entry-2.3 {Tk_EntryCmd procedure} -body {
    entry .e
    pack .e
    update
    list [winfo exists .e] [winfo class .e] [info commands .e]
} -cleanup {
    destroy .e
} -result {1 Entry .e}
test entry-2.4 {Tk_EntryCmd procedure} -body {
    entry .e -gorp foo







|







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    entry
} -returnCodes error -result {wrong # args: should be "entry pathName ?-option value ...?"}
test entry-2.2 {Tk_EntryCmd procedure} -body {
    entry gorp
} -returnCodes error -result {bad window path name "gorp"}
test entry-2.3 {Tk_EntryCmd procedure} -body {
    entry .e
    pack .e ; update idletasks
    update
    list [winfo exists .e] [winfo class .e] [info commands .e]
} -cleanup {
    destroy .e
} -result {1 Entry .e}
test entry-2.4 {Tk_EntryCmd procedure} -body {
    entry .e -gorp foo
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
} -cleanup {
    destroy .e
} -result {.e}


test entry-3.1 {EntryWidgetCmd procedure} -setup {
    entry .e
    pack .e
    update
} -body {
    .e
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e option ?arg ...?"}
test entry-3.2 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e bbox
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test entry-3.3 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e bbox a b
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test entry-3.4 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e bbox bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bogus"}
test entry-3.5 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
   .e bbox 0
} -cleanup {
    destroy .e
} -result [list 5 5 0 $cy]

# Previously the result was count using previousli counted font measurements
# and metrics. It was changed to less verbose solution - the result is the one
# that passes fonts constraint (this concerns tests 3.6, 3.7, 3.8, 3.10)
test entry-3.6 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): no utf chars
    .e insert 0 "abc"
    list [.e bbox 3] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{19 5 7 13} {19 5 7 13}}
test entry-3.7 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab乎"
    .e bbox end
} -cleanup {
    destroy .e
} -result {19 5 12 13}
test entry-3.8 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "ab乎c"
    .e bbox 3
} -cleanup {
    destroy .e
} -result {31 5 7 13}
test entry-3.9 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
# Tcl_UtfAtIndex(): no chars
    .e bbox end
} -cleanup {
    destroy .e
} -result "5 5 0 $cy"
test entry-3.10 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert 0 "abcdefghij乎klmnop"
    list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{5 5 7 13} {12 5 7 13} {75 5 12 13} {122 5 7 13}}







|








|








|








|








|














|












|












|










|











|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
} -cleanup {
    destroy .e
} -result {.e}


test entry-3.1 {EntryWidgetCmd procedure} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e option ?arg ...?"}
test entry-3.2 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e bbox
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test entry-3.3 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e bbox a b
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e bbox index"}
test entry-3.4 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e bbox bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bogus"}
test entry-3.5 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
   .e bbox 0
} -cleanup {
    destroy .e
} -result [list 5 5 0 $cy]

# Previously the result was count using previousli counted font measurements
# and metrics. It was changed to less verbose solution - the result is the one
# that passes fonts constraint (this concerns tests 3.6, 3.7, 3.8, 3.10)
test entry-3.6 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
# Tcl_UtfAtIndex(): no utf chars
    .e insert 0 "abc"
    list [.e bbox 3] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{19 5 7 13} {19 5 7 13}}
test entry-3.7 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab乎"
    .e bbox end
} -cleanup {
    destroy .e
} -result {19 5 12 13}
test entry-3.8 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "ab乎c"
    .e bbox 3
} -cleanup {
    destroy .e
} -result {31 5 7 13}
test entry-3.9 {EntryWidgetCmd procedure, "bbox" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
# Tcl_UtfAtIndex(): no chars
    .e bbox end
} -cleanup {
    destroy .e
} -result "5 5 0 $cy"
test entry-3.10 {EntryWidgetCmd procedure, "bbox" widget command} -constraints {
	fonts
} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert 0 "abcdefghij乎klmnop"
    list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]
} -cleanup {
    destroy .e
} -result {{5 5 7 13} {12 5 7 13} {75 5 12 13} {122 5 7 13}}
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test entry-3.15 {EntryWidgetCmd procedure, "configure" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    llength [.e configure]
} -cleanup {
    destroy .e
} -result 38
test entry-3.16 {EntryWidgetCmd procedure, "configure" widget command} -setup {







|







816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    .e configure -bd 4
    .e cget -bd
} -cleanup {
    destroy .e
} -result 4
test entry-3.15 {EntryWidgetCmd procedure, "configure" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    llength [.e configure]
} -cleanup {
    destroy .e
} -result 38
test entry-3.16 {EntryWidgetCmd procedure, "configure" widget command} -setup {
873
874
875
876
877
878
879
880
881
882
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
} -body {
    .e delete 0 bar
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bar"}
test entry-3.22 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 2 4
    .e get
} -cleanup {
    destroy .e
} -result 014567890
test entry-3.23 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e insert end "01234567890"
    .e delete 6
    .e get
} -cleanup {
    destroy .e
} -result 0123457890
test entry-3.24 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
    set x {}
} -body {
# UTF
    .e insert end "01234乎67890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "012345乎7890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456乎890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "01234乎7890" "0123457890" "012345乎890"]
test entry-3.25 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.26 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e delete 2 8
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.26a {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e delete 2 8
    .e configure -state normal
    .e get







|



















|




















|










|












|







869
870
871
872
873
874
875
876
877
878
879
880
881
882
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
} -body {
    .e delete 0 bar
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bar"}
test entry-3.22 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e delete 2 4
    .e get
} -cleanup {
    destroy .e
} -result 014567890
test entry-3.23 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
} -body {
    .e insert end "01234567890"
    .e delete 6
    .e get
} -cleanup {
    destroy .e
} -result 0123457890
test entry-3.24 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
    set x {}
} -body {
# UTF
    .e insert end "01234乎67890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "012345乎7890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456乎890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "01234乎7890" "0123457890" "012345乎890"]
test entry-3.25 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.26 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e delete 2 8
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.26a {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e delete 2 8
    .e configure -state normal
    .e get
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
} -body {
    .e index foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.34 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e index 0
} -cleanup {
    destroy .e
} -returnCodes {ok} -match glob -result {*}
test entry-3.35 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
# UTF
    .e insert 0 abc乎œdef
    list [.e index 3] [.e index 4] [.e index end]
} -cleanup {
    destroy .e







|








|







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
} -body {
    .e index foo
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.34 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e index 0
} -cleanup {
    destroy .e
} -returnCodes {ok} -match glob -result {*}
test entry-3.35 {EntryWidgetCmd procedure, "index" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
# UTF
    .e insert 0 abc乎œdef
    list [.e index 3] [.e index 4] [.e index end]
} -cleanup {
    destroy .e
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
} -body {
    .e insert foo Text
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.39 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e insert 3 xxx
    .e get
} -cleanup {
    destroy .e
} -result {012xxx34567890}
test entry-3.40 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.40a {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.41 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {
    .e insert a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test entry-3.42 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan a
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test entry-3.43 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test entry-3.44 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan foobar 20
} -cleanup {
    destroy .e
} -returnCodes error -result {bad scan option "foobar": must be mark or dragto}
test entry-3.45 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e scan mark 20.1
} -cleanup {
    destroy .e
} -returnCodes error -result {expected integer but got "20.1"}

# This test is non-portable because character sizes vary.
test entry-3.46 {EntryWidgetCmd procedure, "scan" widget command} -constraints {
    fonts
} -setup {
    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long string, in fact a "
    .e insert end "very very long string"
    .e scan mark 30
    .e scan dragto 28
    .e index @0







|










|












|



















|








|








|





|


|












|







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
} -body {
    .e insert foo Text
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "foo"}
test entry-3.39 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e insert 3 xxx
    .e get
} -cleanup {
    destroy .e
} -result {012xxx34567890}
test entry-3.40 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e configure -state disabled
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.40a {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e insert 3 xxx
    .e configure -state normal
    .e get
} -cleanup {
    destroy .e
} -result 01234567890
test entry-3.41 {EntryWidgetCmd procedure, "insert" widget command} -setup {
    entry .e
} -body {
    .e insert a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e insert index text"}
test entry-3.42 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e scan a
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test entry-3.43 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e scan a b c
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e scan mark|dragto x"}
test entry-3.44 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e scan foobar 20
} -cleanup {
    destroy .e
} -returnCodes error -result {bad scan option "foobar": must be dragto or mark}
test entry-3.45 {EntryWidgetCmd procedure, "scan" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e scan mark 20.1
} -cleanup {
    destroy .e
} -returnCodes error -result {expected integer but got "20.1"}

# This test is non-portable because character sizes vary.
test entry-3.46 {EntryWidgetCmd procedure, "scan" widget command} -constraints {
    fonts
} -setup {
    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long string, in fact a "
    .e insert end "very very long string"
    .e scan mark 30
    .e scan dragto 28
    .e index @0
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
    .e select clear
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test entry-3.50.1 {EntryWidgetCmd procedure, "select clear" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear







|







1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
    .e select clear
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test entry-3.50.1 {EntryWidgetCmd procedure, "select clear" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
} -body {
    .e selection present foo
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection present"}
test entry-3.52 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test entry-3.53 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e configure -exportselection false
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test entry-3.54 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present







|











|












|







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
} -body {
    .e selection present foo
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection present"}
test entry-3.52 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test entry-3.53 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e configure -exportselection false
    .e selection present
} -cleanup {
    destroy .e
} -result 1
test entry-3.54 {EntryWidgetCmd procedure, "selection present" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
} -body {
    .e select adjust 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection adjust index"}
test entry-3.57 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 4
    selection get
} -cleanup {
    destroy .e
} -result 123
test entry-3.58 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2







|













|







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
} -body {
    .e select adjust 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection adjust index"}
test entry-3.57 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 4
    selection get
} -cleanup {
    destroy .e
} -result 123
test entry-3.58 {EntryWidgetCmd procedure, "selection adjust" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
    .e select range 4 4
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-3.63 {EntryWidgetCmd procedure, "selection range" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 7
    .e select range 2 9
    list [.e index sel.first] [.e index sel.last] [.e index anchor]
} -cleanup {
    destroy .e
} -result {2 9 3}
test entry-3.64 {EntryWidgetCmd procedure, "selection" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state disabled
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {0 10}
test entry-3.64a {EntryWidgetCmd procedure, "selection" widget command} -setup {
    entry .e
    pack .e
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state readonly
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 4}
test entry-3.64b {EntryWidgetCmd procedure, "selection to" widget command} -setup {
    entry .e
    pack .e
    update
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
} -body {
    .e select to 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection to index"}

test entry-3.65 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 5
    format {%.7f %.7f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.0537634 0.2688172}
test entry-3.66 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "gorp"}
test entry-3.67 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    .e icursor 10
    .e xview insert
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.107527 0.322581}
test entry-3.68 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview moveto foo bar
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview moveto fraction"}
test entry-3.69 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e xview moveto foo
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "foo"}
test entry-3.70 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto 0.5
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.505376 0.720430}
test entry-3.71 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview scroll 24
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview scroll number pages|units"}
test entry-3.72 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll gorp units
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "gorp"}
test entry-3.73 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview moveto 0
    .e xview scroll 1 pages
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.193548 0.408602}
test entry-3.74 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto .9
    update
    .e xview scroll -2 p
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.397849 0.612903}
test entry-3.75 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll 2 units
    .e index @0
} -cleanup {
    destroy .e
} -result 32
test entry-3.76 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll -1 units
    .e index @0
} -cleanup {
    destroy .e
} -result 29
test entry-3.77 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll 23 foobars
} -cleanup {
    destroy .e
} -returnCodes error -result {bad argument "foobars": must be pages or units}
test entry-3.78 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview eat 23 hamburgers
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "eat": must be moveto or scroll}
test entry-3.79 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    update
    .e xview -1
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test entry-3.80 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 300
    .e index @0
} -cleanup {
    destroy .e
} -result 73
test entry-3.86 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e insert 10 乎
    update
# UTF
# If Tcl_NumUtfChars wasn't used, wrong answer would be:







|












|













|













|











|











|








|













|








|








|











|










|










|












|













|













|













|










|










|






|






|











|







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
    .e select range 4 4
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-3.63 {EntryWidgetCmd procedure, "selection range" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 7
    .e select range 2 9
    list [.e index sel.first] [.e index sel.last] [.e index anchor]
} -cleanup {
    destroy .e
} -result {2 9 3}
test entry-3.64 {EntryWidgetCmd procedure, "selection" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state disabled
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {0 10}
test entry-3.64a {EntryWidgetCmd procedure, "selection" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e selection range 0 end
    .e configure -state readonly
    .e selection range 2 4
    .e configure -state normal
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 4}
test entry-3.64b {EntryWidgetCmd procedure, "selection to" widget command} -setup {
    entry .e
    pack .e ; update idletasks
    update
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
} -body {
    .e select to 2 3
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e selection to index"}

test entry-3.65 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 5
    format {%.7f %.7f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.0537634 0.2688172}
test entry-3.66 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e xview gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "gorp"}
test entry-3.67 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    .e icursor 10
    .e xview insert
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.107527 0.322581}
test entry-3.68 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e xview moveto foo bar
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview moveto fraction"}
test entry-3.69 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e xview moveto foo
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "foo"}
test entry-3.70 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto 0.5
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.505376 0.720430}
test entry-3.71 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview scroll 24
} -cleanup {
    destroy .e
} -returnCodes error -result {wrong # args: should be ".e xview scroll number pages|units"}
test entry-3.72 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll gorp units
} -cleanup {
    destroy .e
} -returnCodes error -result {expected floating-point number but got "gorp"}
test entry-3.73 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview moveto 0
    .e xview scroll 1 pages
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.193548 0.408602}
test entry-3.74 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview moveto .9
    update
    .e xview scroll -2 p
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.397849 0.612903}
test entry-3.75 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll 2 units
    .e index @0
} -cleanup {
    destroy .e
} -result 32
test entry-3.76 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 30
    update
    .e xview scroll -1 units
    .e index @0
} -cleanup {
    destroy .e
} -result 29
test entry-3.77 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview scroll 23 foobars
} -cleanup {
    destroy .e
} -returnCodes error -result {bad argument "foobars": must be pages or units}
test entry-3.78 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview eat 23 hamburgers
} -cleanup {
    destroy .e
} -returnCodes error -result {unknown option "eat": must be moveto or scroll}
test entry-3.79 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e xview 0
    update
    .e xview {}
    .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 ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    update
    .e xview 300
    .e index @0
} -cleanup {
    destroy .e
} -result 73
test entry-3.86 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e insert end "This is quite a long text string, so long that it "
    .e insert end "runs off the end of the window quite a bit."
    .e insert 10 乎
    update
# UTF
# If Tcl_NumUtfChars wasn't used, wrong answer would be:
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
    lappend x [format {%.6f} [lindex [.e xview] 0]]
} -cleanup {
    destroy .e
} -result {0.095745 0.106383 0.117021}

test entry-3.82 {EntryWidgetCmd procedure} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    update
} -body {
    .e gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, validate, or xview}

# The test below doesn't actually check anything directly, but if run
# with Purify or some other memory-allocation-checking program it will
# ensure that resources get properly freed.

test entry-4.1 {DestroyEntry procedure} -body {
    entry .e -textvariable x -show *
    pack .e
    .e insert end "Sample text"
    update
    destroy .e
} -result {}

test entry-5.1 {ConfigureEntry procedure, -textvariable} -body {
    set x 12345







|













|







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
    lappend x [format {%.6f} [lindex [.e xview] 0]]
} -cleanup {
    destroy .e
} -result {0.095745 0.106383 0.117021}

test entry-3.82 {EntryWidgetCmd procedure} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
    update
} -body {
    .e gorp
} -cleanup {
    destroy .e
} -returnCodes error -result {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, validate, or xview}

# The test below doesn't actually check anything directly, but if run
# with Purify or some other memory-allocation-checking program it will
# ensure that resources get properly freed.

test entry-4.1 {DestroyEntry procedure} -body {
    entry .e -textvariable x -show *
    pack .e ; update idletasks
    .e insert end "Sample text"
    update
    destroy .e
} -result {}

test entry-5.1 {ConfigureEntry procedure, -textvariable} -body {
    set x 12345
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
} -cleanup {
    destroy .e
} -result {Some text}
test entry-5.4 {ConfigureEntry procedure, -textvariable} -setup {
    unset -nocomplain x
    entry .e
} -body {
    trace variable x w override
    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    unset x;
} -result {12345 12345}

test entry-5.5 {ConfigureEntry procedure} -setup {
    set x {}
    entry .e1
    entry .e2
} -body {
    .e2 insert end "This is some sample text"
    .e1 configure -exportselection false
    .e1 insert end "0123456789"
    pack .e1 .e2
    .e2 select from 0
    .e2 select to 10
    lappend x [selection get]
    .e1 select from 1
    .e1 select to 5
    lappend x [selection get]
    .e1 configure -exportselection 1
    lappend x [selection get]
    set x
} -cleanup {
    destroy .e1 .e2
} -result {{This is so} {This is so} 1234}
test entry-5.6 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test entry-5.6.1 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    catch {selection get}
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5}

test entry-5.7 {ConfigureEntry procedure} -setup {
    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e configure -width 5
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}


test entry-5.8 {ConfigureEntry procedure} -constraints {
    fonts failsOnXQuarz
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -width 0 -font {Helvetica -12}
    .e insert end "0123"
    update
    .e configure -font {Helvetica -24}
    update
    winfo geom .e
} -cleanup {
    destroy .e
} -result {62x37+0+0}
test entry-5.9 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test entry-5.10 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief flat
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test entry-5.11 {ConfigureEntry procedure} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
# If "0" in selected font had 0 width, caused divide-by-zero error.
    .e configure -font {{open look glyph}}
    .e scan dragto 30
    update
} -cleanup {
    destroy .e
} -result {}

# No tests for DisplayEntry.

test entry-6.1 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @61] [.e index @62]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.2 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -justify center -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @96] [.e index @97]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.3 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -justify right -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @131] [.e index @132]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.4 {EntryComputeGeometry procedure} -setup {
    entry .e
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 6
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test entry-6.5 {EntryComputeGeometry procedure} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 7
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test entry-6.6 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 10
    .e insert end "01234\t67890"
    update
    .e xview 3
    list [.e index @39] [.e index @40]
} -cleanup {
    destroy .e
} -result {5 6}
test entry-6.7 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 5
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {77 39}
test entry-6.8 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {116 39}
test entry-6.9 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {25 39}
test entry-6.10 {EntryComputeGeometry procedure} -constraints {
    unix fonts
} -setup {
    entry .e -highlightthickness 2 -font {Helvetica -12}
    pack .e
} -body {
    .e configure -bd 1 -relief raised -width 0 -show .
    .e insert 0 12345
    update
    set x [winfo reqwidth .e]
    .e configure -show X
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {23 53 43}
test entry-6.11 {EntryComputeGeometry procedure} -constraints {
    win
} -setup {
    entry .e -highlightthickness 2
    pack .e
} -body {
    .e configure -bd 1 -relief raised -width 0 -show . -font {helvetica 12}
    .e insert 0 12345
    update
    set x1 [winfo reqwidth .e]
	set x2 [expr {8+5*[font measure {helvetica 12} .]}]
	set x [expr {$x1 eq $x2}]







|





|











|














|











|













|



|
|

|



<
|



|


|














|












|










|















|













|













|











|











|













|













|












|












|











|
















|







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
} -cleanup {
    destroy .e
} -result {Some text}
test entry-5.4 {ConfigureEntry procedure, -textvariable} -setup {
    unset -nocomplain x
    entry .e
} -body {
    trace add variable x write override
    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace remove variable x write override
    unset x;
} -result {12345 12345}

test entry-5.5 {ConfigureEntry procedure} -setup {
    set x {}
    entry .e1
    entry .e2
} -body {
    .e2 insert end "This is some sample text"
    .e1 configure -exportselection false
    .e1 insert end "0123456789"
    pack .e1 .e2 ; update idletasks
    .e2 select from 0
    .e2 select to 10
    lappend x [selection get]
    .e1 select from 1
    .e1 select to 5
    lappend x [selection get]
    .e1 configure -exportselection 1
    lappend x [selection get]
    set x
} -cleanup {
    destroy .e1 .e2
} -result {{This is so} {This is so} 1234}
test entry-5.6 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e ; update idletasks
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -result {PRIMARY selection doesn't exist or form "STRING" not defined}
test entry-5.6.1 {ConfigureEntry procedure} -setup {
    entry .e
    pack .e ; update idletasks
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    .e configure -exportselection 0
    catch {selection get}
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5}

test entry-5.7 {ConfigureEntry procedure} -setup {
    entry .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update
    set scrollInfo wrong
    .e configure -width 5
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.000000 0.454545}


test entry-5.8 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -width 0 -font {Helvetica -12}
    .e insert end "0123"
    update
    .e configure -font {Helvetica -24}
    update
    winfo geom .e
} -cleanup {
    destroy .e
} -result {62x37+0+0}
test entry-5.9 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test entry-5.10 {ConfigureEntry procedure} -constraints {
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief flat
    .e insert end "0123"
    update
    list [.e index @10] [.e index @11] [.e index @12] [.e index @13]
} -cleanup {
    destroy .e
} -result {0 0 1 1}
test entry-5.11 {ConfigureEntry procedure} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e ; update idletasks
} -body {
# If "0" in selected font had 0 width, caused divide-by-zero error.
    .e configure -font {{open look glyph}}
    .e scan dragto 30
    update
} -cleanup {
    destroy .e
} -result {}

# No tests for DisplayEntry.

test entry-6.1 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @61] [.e index @62]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.2 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -justify center -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @96] [.e index @97]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.3 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 20 \
        -justify right -highlightthickness 3
    .e insert end 012\t45
    update
    list [.e index @131] [.e index @132]
} -cleanup {
    destroy .e
} -result {3 4}
test entry-6.4 {EntryComputeGeometry procedure} -setup {
    entry .e
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 6
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test entry-6.5 {EntryComputeGeometry procedure} -setup {
    entry .e -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 5
    .e insert end "01234567890"
    update
    .e xview 7
    .e index @0
} -cleanup {
    destroy .e
} -result 6
test entry-6.6 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -bd 2 -relief raised -width 10
    .e insert end "01234\t67890"
    update
    .e xview 3
    list [.e index @39] [.e index @40]
} -cleanup {
    destroy .e
} -result {5 6}
test entry-6.7 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 5
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {77 39}
test entry-6.8 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    .e insert end "01234567"
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {116 39}
test entry-6.9 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    entry .e -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -font {Helvetica -24} -bd 3 -relief raised -width 0
    update
    list [winfo reqwidth .e] [winfo reqheight .e]
} -cleanup {
    destroy .e
} -result {25 39}
test entry-6.10 {EntryComputeGeometry procedure} -constraints {
    unix fonts
} -setup {
    entry .e -highlightthickness 2 -font {Helvetica -12}
    pack .e ; update idletasks
} -body {
    .e configure -bd 1 -relief raised -width 0 -show .
    .e insert 0 12345
    update
    set x [winfo reqwidth .e]
    .e configure -show X
    lappend x [winfo reqwidth .e]
    .e configure -show ""
    lappend x [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {23 53 43}
test entry-6.11 {EntryComputeGeometry procedure} -constraints {
    win
} -setup {
    entry .e -highlightthickness 2
    pack .e ; update idletasks
} -body {
    .e configure -bd 1 -relief raised -width 0 -show . -font {helvetica 12}
    .e insert 0 12345
    update
    set x1 [winfo reqwidth .e]
	set x2 [expr {8+5*[font measure {helvetica 12} .]}]
	set x [expr {$x1 eq $x2}]
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941

1942
1943
1944
1945

1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958

1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092

2093
2094
2095
2096

2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108

2109
2110
2111
2112

2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127
2128

2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
    destroy .e
} -result {1 1 1}
test entry-6.12 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    catch {destroy .e}
    entry .e -font {Courier -12} -bd 2 -relief raised -width 20
    pack .e
} -body {
    .e insert end "012\t456\t"
    update
    list [.e index @80] [.e index @81] [.e index @115] [.e index @116]
} -cleanup {
    destroy .e
} -result {6 7 7 8}


test entry-7.1 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e insert 2 XXX
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abXXXcde abXXXcde {0.000000 1.000000}}

test entry-7.2 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e insert 500 XXX
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test entry-7.3 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 2 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {5 9 5 8}
test entry-7.4 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 3 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test entry-7.5 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 5 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test entry-7.6 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 6 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 6 2 5}
test entry-7.7 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -xscrollcommand scroll
    .e insert 0 0123456789
    .e icursor 4
    .e insert 4 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 7
test entry-7.8 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e icursor 4
    .e insert 5 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-7.9 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 3 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 7
test entry-7.10 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 4 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 4

test entry-7.11 {InsertChars procedure} -constraints {
    fonts
} -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e insert 2 00
    winfo reqwidth .e
} -cleanup {
    destroy .e
} -result 59

test entry-8.1 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete 2 4
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abe abe {0.000000 1.000000}}
test entry-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete -1 2
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {cde cde {0.000000 1.000000}}
test entry-8.3 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcde
    .e delete 3 1000
    vwait scrollInfo

    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abc abc {0.000000 1.000000}}
test entry-8.4 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 3
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 6 1 5}
test entry-8.5 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 4
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5 1 4}
test entry-8.6 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 2 1 5}
test entry-8.7 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-8.8 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 4 3 8}
test entry-8.9 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-8.10 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 5 8
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 5 5 8}
test entry-8.11 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 8 10
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 8 4 8}
test entry-8.12 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 4
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test entry-8.13 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 5
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test entry-8.14 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 4 6
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-8.15 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 4
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test entry-8.16 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 5
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test entry-8.17 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test entry-8.18 {DeleteChars procedure} -constraints failsOnUbuntuNoXft -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
    # To check that deletion actually happened we measure the new width
    # of the widget, based on the measuring width of the remaining text ("xyy")
    # in the widget. For that purpose we have to mirror the code in tkEntry.c
    # for computation of the reqwidth
    # note: XPAD corresponds to the hardcoded    #define XPAD 1
    set XPAD 1
    set expected [expr { [font measure [.e cget -font] "xyy"] \
                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) } ]
    expr {[winfo reqwidth .e] == $expected}
} -cleanup {
    destroy .e
    unset XPAD expected
} -result 1

test entry-9.1 {EntryValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace variable x w override
    entry .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    unset x
} -result {12345 12345}


test entry-10.1 {EntrySetValue procedure} -constraints fonts -body {
    set x abcde
    set y ab
    entry .e  -font {Helvetica -12} -highlightthickness 2 -bd 2  -width 0
    pack .e
    .e configure -textvariable x
    .e configure -textvariable y
    update
    list [.e get] [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {ab 24}
test entry-10.2 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "a"
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-10.3 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefg"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 7}
test entry-10.4 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefghijklmn"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 10}
test entry-10.5 {EntrySetValue procedure, updating display position} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "abcdefg"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test entry-10.6 {EntrySetValue procedure, updating display position} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "1234567890123456789012"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 10
test entry-10.7 {EntrySetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
    update
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123"
    .e index insert
} -cleanup {
    destroy .e
} -result 3
test entry-10.8 {EntrySetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123456"
    .e index insert
} -cleanup {
    destroy .e
} -result 5

test entry-11.1 {EntryEventProc procedure} -setup {
    entry .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    pack .e
} -body {
    .e insert 0 abcdefg
    destroy .e
    update
} -cleanup {
    destroy .e
} -result {}







|












|



>
|


<
>



<





|



>
|


<
>



<



|













|













|













|













|











|










|











|














|












|



>
|


<
>



<




|



>
|

|
<
>



<




|



>
|


<
>



<



|















|















|















|













|















|












|















|















|












|












|












|












|












|










|

|


















|




|





|








|










|












|












|












|














|


|












|



|










|


|










|







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
    destroy .e
} -result {1 1 1}
test entry-6.12 {EntryComputeGeometry procedure} -constraints {
    fonts
} -setup {
    catch {destroy .e}
    entry .e -font {Courier -12} -bd 2 -relief raised -width 20
    pack .e ; update idletasks
} -body {
    .e insert end "012\t456\t"
    update
    list [.e index @80] [.e index @81] [.e index @115] [.e index @116]
} -cleanup {
    destroy .e
} -result {6 7 7 8}


test entry-7.1 {InsertChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set scrollInfo wrong
    .e insert 0 abcde
    .e insert 2 XXX

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -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 ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set scrollInfo wrong
    .e insert 0 abcde
    .e insert 500 XXX

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test entry-7.3 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 2 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {5 9 5 8}
test entry-7.4 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 3 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test entry-7.5 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 5 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 9 2 8}
test entry-7.6 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 0123456789
    .e select from 2
    .e select to 6
    .e insert 6 XXX
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {2 6 2 5}
test entry-7.7 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -xscrollcommand scroll
    .e insert 0 0123456789
    .e icursor 4
    .e insert 4 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 7
test entry-7.8 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 0123456789
    .e icursor 4
    .e insert 5 XXX
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-7.9 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 3 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 7
test entry-7.10 {InsertChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 "This is a very long string"
    update
    .e xview 4
    .e insert 4 XXX
    .e index @0
} -cleanup {
    destroy .e
} -result 4

test entry-7.11 {InsertChars procedure} -constraints {
    fonts
} -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 "xyzzy"
    update
    .e insert 2 00
    winfo reqwidth .e
} -cleanup {
    destroy .e
} -result 59

test entry-8.1 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set scrollInfo wrong
    .e insert 0 abcde
    .e delete 2 4

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -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 ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set scrollInfo wrong
    .e insert 0 abcde
    .e delete {} 2

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -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 ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set scrollInfo wrong
    .e insert 0 abcde
    .e delete 3 1000

    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -result {abc abc {0.000000 1.000000}}
test entry-8.4 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 3
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 6 1 5}
test entry-8.5 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 4
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 5 1 4}
test entry-8.6 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 5
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {1 2 1 5}
test entry-8.7 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 1 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-8.8 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 7
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 4 3 8}
test entry-8.9 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e insert 0 0123456789abcde
    .e select from 3
    .e select to 8
    .e delete 3 8
    update
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-8.10 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 5 8
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 8
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 5 5 8}
test entry-8.11 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e select from 8
    .e select to 3
    .e delete 8 10
    update
    set x "[.e index sel.first] [.e index sel.last]"
    .e select to 4
    lappend x [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {3 8 4 8}
test entry-8.12 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 4
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test entry-8.13 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 1 5
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 1
test entry-8.14 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 0123456789abcde
    .e icursor 4
    .e delete 4 6
    update
    .e index insert
} -cleanup {
    destroy .e
} -result 4
test entry-8.15 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 4
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test entry-8.16 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 1 5
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 1
test entry-8.17 {DeleteChars procedure} -setup {
    entry .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 "This is a very long string"
    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test entry-8.18 {DeleteChars procedure} -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
    # To check that deletion actually happened we measure the new width
    # of the widget, based on the measuring width of the remaining text ("xyy")
    # in the widget. For that purpose we have to mirror the code in tkEntry.c
    # for computation of the reqwidth
    # note: XPAD corresponds to the hardcoded    #define XPAD 1
    set XPAD 1
    set expected [expr { [font measure [.e cget -font] "xyy"] \
                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) } ]
    expr {[winfo reqwidth .e] == $expected}
} -cleanup {
    destroy .e
    unset XPAD expected
} -result {1}

test entry-9.1 {EntryValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace add variable x write override
    entry .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace remove variable x write override
    unset x
} -result {12345 12345}


test entry-10.1 {EntrySetValue procedure} -constraints fonts -body {
    set x abcde
    set y ab
    entry .e  -font {Helvetica -12} -highlightthickness 2 -bd 2  -width 0
    pack .e ; update idletasks
    .e configure -textvariable x
    .e configure -textvariable y
    update
    list [.e get] [winfo reqwidth .e]
} -cleanup {
    destroy .e
} -result {ab 24}
test entry-10.2 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "a"
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}
test entry-10.3 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefg"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 7}
test entry-10.4 {EntrySetValue procedure, updating selection} -setup {
    unset -nocomplain x
    entry .e -font {Helvetica -12} -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -textvariable x
    .e insert 0 "abcdefghjklmnopqrstu"
    .e selection range 4 10
    set x "abcdefghijklmn"
    list [.e index sel.first] [.e index sel.last]
} -cleanup {
    destroy .e
} -result {4 10}
test entry-10.5 {EntrySetValue procedure, updating display position} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "abcdefg"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 0
test entry-10.6 {EntrySetValue procedure, updating display position} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e ; update idletasks
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e xview 10
    update
    set x "1234567890123456789012"
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 10
test entry-10.7 {EntrySetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e ; update idletasks
    update
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e ; update idletasks
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123"
    .e index insert
} -cleanup {
    destroy .e
} -result 3
test entry-10.8 {EntrySetValue procedure, updating insertion cursor} -setup {
    unset -nocomplain x
    entry .e -highlightthickness 2 -bd 2
    pack .e ; update idletasks
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e ; update idletasks
    .e insert 0 "abcdefghjklmnopqrstuvwxyz"
    .e icursor 5
    set x "123456"
    .e index insert
} -cleanup {
    destroy .e
} -result 5

test entry-11.1 {EntryEventProc procedure} -setup {
    entry .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    pack .e ; update idletasks
} -body {
    .e insert 0 abcdefg
    destroy .e
    update
} -cleanup {
    destroy .e
} -result {}
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
} -cleanup {
    destroy .b
} -result {{} {}}


test entry-13.1 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index end
} -cleanup {
    destroy .e
} -result 21
test entry-13.2 {GetEntryIndex procedure} -body {
    entry .e
    .e index abogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "abogus"}
test entry-13.3 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    .e index anchor
} -cleanup {
    destroy .e
} -result 1
test entry-13.4 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 4
    .e select to 1
    .e index anchor
} -cleanup {
    destroy .e
} -result 4
test entry-13.5 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 3
    .e select to 15
    .e select adjust 4
    .e index anchor
} -cleanup {
    destroy .e
} -result 15
test entry-13.6 {GetEntryIndex procedure} -setup {
    entry .e
} -body {
    .e index ebogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "ebogus"}
test entry-13.7 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e icursor 2
    .e index insert
} -cleanup {
    destroy .e
} -result 2
test entry-13.8 {GetEntryIndex procedure} -setup {
    entry .e
} -body {
    .e index ibogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "ibogus"}
test entry-13.9 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]







|
















|












|












|




















|


















|







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
} -cleanup {
    destroy .b
} -result {{} {}}


test entry-13.1 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e ; update idletasks
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index end
} -cleanup {
    destroy .e
} -result 21
test entry-13.2 {GetEntryIndex procedure} -body {
    entry .e
    .e index abogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "abogus"}
test entry-13.3 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e ; update idletasks
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    .e index anchor
} -cleanup {
    destroy .e
} -result 1
test entry-13.4 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e ; update idletasks
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 4
    .e select to 1
    .e index anchor
} -cleanup {
    destroy .e
} -result 4
test entry-13.5 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e ; update idletasks
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 3
    .e select to 15
    .e select adjust 4
    .e index anchor
} -cleanup {
    destroy .e
} -result 15
test entry-13.6 {GetEntryIndex procedure} -setup {
    entry .e
} -body {
    .e index ebogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "ebogus"}
test entry-13.7 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e ; update idletasks
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e icursor 2
    .e index insert
} -cleanup {
    destroy .e
} -result 2
test entry-13.8 {GetEntryIndex procedure} -setup {
    entry .e
} -body {
    .e index ibogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "ibogus"}
test entry-13.9 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e ; update idletasks
} -body {
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744


test entry-13.10 {GetEntryIndex procedure} -constraints x11 -body {
# On unix, when selection is cleared, entry widget's internal
# selection range is reset.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

test entry-13.11 {GetEntryIndex procedure} -constraints aquaOrWin32 -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    catch {selection get}
    .e index sel.first
} -cleanup {
    destroy .e
} -result 1

test entry-13.12 {GetEntryIndex procedure} -constraints x11 -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

# why when string in .e index changed to not beginning with s,
# it behaves differently?
test entry-13.12.1 {GetEntryIndex procedure} -constraints unix -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bogus"}

test entry-13.13 {GetEntryIndex procedure} -constraints win -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "sbogus"}

test entry-13.14 {GetEntryIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -match glob -result {*}

test entry-13.14.1 {GetEntryIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:







|



















|

















|


















|
















|



















|



















|







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


test entry-13.10 {GetEntryIndex procedure} -constraints x11 -body {
# On unix, when selection is cleared, entry widget's internal
# selection range is reset.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sel.first
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

test entry-13.11 {GetEntryIndex procedure} -constraints aquaOrWin32 -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    catch {selection get}
    .e index sel.first
} -cleanup {
    destroy .e
} -result 1

test entry-13.12 {GetEntryIndex procedure} -constraints x11 -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {selection isn't in widget .e}

# why when string in .e index changed to not beginning with s,
# it behaves differently?
test entry-13.12.1 {GetEntryIndex procedure} -constraints unix -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index bogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "bogus"}

test entry-13.13 {GetEntryIndex procedure} -constraints win -body {
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    .e index sbogus
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "sbogus"}

test entry-13.14 {GetEntryIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
    selection clear .e
    selection get
} -cleanup {
    destroy .e
} -returnCodes error -match glob -result {*}

test entry-13.14.1 {GetEntryIndex procedure} -constraints win -body {
# On mac and pc, when selection is cleared, entry widget remembers
# last selected range.  When selection ownership is restored to
# entry, the old range will be rehighlighted.
# Previous settings:
	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
	pack .e ; update idletasks
	.e insert 0 012345678901234567890
	.e xview 4
	update
    .e select from 1
    .e select to 6
    list [.e index sel.first] [.e index sel.last]
# Testing:
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "@xyz"}

test entry-13.16 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @4
} -cleanup {
    destroy .e
} -result 4
test entry-13.17 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @11
} -cleanup {
    destroy .e
} -result 4
test entry-13.18 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @12
} -cleanup {
    destroy .e
} -result 5
test entry-13.19 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 6}]
} -cleanup {
    destroy .e
} -result 8
test entry-13.20 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 5}]
} -cleanup {
    destroy .e
} -result 9
test entry-13.21 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @1000
} -cleanup {
    destroy .e
} -result 9
test entry-13.22 {GetEntryIndex procedure} -setup {
    entry .e
    pack .e
    update
} -body {
    .e index 1xyz
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "1xyz"}
test entry-13.23 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index -1
} -cleanup {
    destroy .e
} -result 0
test entry-13.24 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 12
} -cleanup {
    destroy .e
} -result 12
test entry-13.25 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 49
} -cleanup {
    destroy .e
} -result 21
test entry-13.26 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    selection clear .e
    .e configure -show .
    .e insert 0 XXXYZZY
    pack .e
    update
    list [.e index @7] [.e index @8]
} -cleanup {
    destroy .e
} -result {0 1}

# XXX Still need to write tests for EntryScanTo and EntrySelectTo.







|










|










|










|










|










|









|









|



|






|










|












|







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
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "@xyz"}

test entry-13.16 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @4
} -cleanup {
    destroy .e
} -result 4
test entry-13.17 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @11
} -cleanup {
    destroy .e
} -result 4
test entry-13.18 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @12
} -cleanup {
    destroy .e
} -result 5
test entry-13.19 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 6}]
} -cleanup {
    destroy .e
} -result 8
test entry-13.20 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @[expr {[winfo width .e] - 5}]
} -cleanup {
    destroy .e
} -result 9
test entry-13.21 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index @1000
} -cleanup {
    destroy .e
} -result 9
test entry-13.22 {GetEntryIndex procedure} -setup {
    entry .e
    pack .e ; update idletasks
    update
} -body {
    .e index 1xyz
} -cleanup {
    destroy .e
} -returnCodes error -result {bad entry index "1xyz"}
test entry-13.23 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index {}
} -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 ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 12
} -cleanup {
    destroy .e
} -result 12
test entry-13.25 {GetEntryIndex procedure} -body {
    entry .e -width 5 -relief sunken -highlightthickness 2 -bd 2\
        -font {Courier -12}
    pack .e ; update idletasks
    .e insert 0 012345678901234567890
    .e xview 4
    update
    .e index 49
} -cleanup {
    destroy .e
} -result 21
test entry-13.26 {GetEntryIndex procedure} -constraints fonts -body {
    entry .e -highlightthickness 2 -bd 2 -font {Helvetica -12}
    selection clear .e
    .e configure -show .
    .e insert 0 XXXYZZY
    pack .e ; update idletasks
    update
    list [.e index @7] [.e index @8]
} -cleanup {
    destroy .e
} -result {0 1}

# XXX Still need to write tests for EntryScanTo and EntrySelectTo.
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985

2986
2987
2988
2989

2990
2991
2992
2993
2994
2995
2996
2997

2998
2999
3000
3001

3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015

3016
3017
3018
3019
3020
3021
3022
3023
3024
} -cleanup {
    destroy .e
} -result {Text Text}

# is scrollcommand needed here??
test entry-16.1 {EntryVisibleRange procedure} -constraints fonts  -body {
    entry .e -width 10 -font {Helvetica -12}
    pack .e
    update
    .e insert 0 "............................."
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}
test entry-16.2 {EntryVisibleRange procedure} -constraints {
    unix fonts
} -body {
    entry .e -show X -width 10  -font {Helvetica -12}
    pack .e
    update
    .e insert 0 "............................."
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.275862}
test entry-16.3 {EntryVisibleRange procedure} -constraints {
    win
} -body {
    entry .e -show . -width 10  -font {Helvetica -12}
	pack .e
    update
    .e insert 0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}
test entry-16.4 {EntryVisibleRange procedure} -body {
    entry .e -show ""
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 1.000000}


test entry-17.1 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 0 end
    .e insert 0 123
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 1.000000}
test entry-17.2 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 0123456789abcdef
    .e xview 3
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.187500 0.812500}
test entry-17.3 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e

    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcdefghijklmnopqrs
    .e xview 6
    vwait scrollInfo

    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.315789 0.842105}
test entry-17.4 {EntryUpdateScrollbar procedure} -setup {
    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    entry .e -width 5
    pack .e
    update idletasks

    .e configure -xscrollcommand thisisnotacommand
    vwait x
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"







|










|










|

















|
|


|



<




>
|


<
>



<




>
|


<
>



<









|
>

|







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
} -cleanup {
    destroy .e
} -result {Text Text}

# is scrollcommand needed here??
test entry-16.1 {EntryVisibleRange procedure} -constraints fonts  -body {
    entry .e -width 10 -font {Helvetica -12}
    pack .e ; update idletasks
    update
    .e insert 0 "............................."
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}
test entry-16.2 {EntryVisibleRange procedure} -constraints {
    unix fonts
} -body {
    entry .e -show X -width 10  -font {Helvetica -12}
    pack .e ; update idletasks
    update
    .e insert 0 "............................."
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.275862}
test entry-16.3 {EntryVisibleRange procedure} -constraints {
    win
} -body {
    entry .e -show . -width 10  -font {Helvetica -12}
	pack .e ; update idletasks
    update
    .e insert 0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 0.827586}
test entry-16.4 {EntryVisibleRange procedure} -body {
    entry .e -show ""
    format {%.6f %.6f} {*}[.e xview]
} -cleanup {
    destroy .e
} -result {0.000000 1.000000}


test entry-17.1 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update
    set scrollInfo wrong
    .e delete 0 end
    .e insert 0 123
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.000000 1.000000}
test entry-17.2 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update
    set scrollInfo wrong
    .e insert 0 0123456789abcdef
    .e xview 3

    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.187500 0.812500}
test entry-17.3 {EntryUpdateScrollbar procedure} -body {
    entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update
    set scrollInfo wrong
    .e insert 0 abcdefghijklmnopqrs
    .e xview 6

    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.315789 0.842105}
test entry-17.4 {EntryUpdateScrollbar procedure} -setup {
    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    entry .e -width 5
    pack .e
    update
    set scrollInfo wrong
    .e configure -xscrollcommand thisisnotacommand
    update
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 0 a {} a all key}

test entry-19.2 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a   ;# previous settings
    .e insert 1 b
    return $::vVals
} -cleanup {
    destroy .e
} -result {.e 1 1 ab a b all key}

test entry-19.3 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 ab   ;# previous settings
    .e insert end c
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 2 abc ab c all key}

test entry-19.4 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abc   ;# previous settings
    .e insert 1 123
    list $::vVals $::e
} -cleanup {
    destroy .e
} -result {{.e 1 1 a123bc abc 123 all key} a123bc}

test entry-19.5 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a123bc   ;# previous settings
    .e delete 2
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 2 a13bc a123bc 2 all key}

test entry-19.6 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 a13bc   ;# previous settings
    .e configure -validate key
    .e delete 1 3
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 1 abc a13bc 13 key key}

test entry-19.7 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abc                 ;# previous settings
    set ::vVals {}
    .e insert end d
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.8 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e configure -validate focus    ;# previous settings
    .e insert end abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusin}

test entry-19.9 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd      ;# previous settings
    focus -force .e         ;# previous settings
    update                  ;# previous settings
# update necessary to process FocusIn event
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusout}

test entry-19.10 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusin}

test entry-19.11 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd          ;# previous settings
    focus -force .e             ;# previous settings
# update necessary to process FocusIn event
    update                      ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusout}

test entry-19.12 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert 0 abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test entry-19.13 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.14 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.15 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event







|














|















|















|















|















|
















|
















|


















|




















|

















|




















|

















|


















|


















|







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
    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 ; update idletasks
    .e insert 0 a
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 0 a {} a all key}

test entry-19.2 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert 0 a   ;# previous settings
    .e insert 1 b
    return $::vVals
} -cleanup {
    destroy .e
} -result {.e 1 1 ab a b all key}

test entry-19.3 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert 0 ab   ;# previous settings
    .e insert end c
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 1 2 abc ab c all key}

test entry-19.4 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert 0 abc   ;# previous settings
    .e insert 1 123
    list $::vVals $::e
} -cleanup {
    destroy .e
} -result {{.e 1 1 a123bc abc 123 all key} a123bc}

test entry-19.5 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert 0 a123bc   ;# previous settings
    .e delete 2
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 2 a13bc a123bc 2 all key}

test entry-19.6 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert 0 a13bc   ;# previous settings
    .e configure -validate key
    .e delete 1 3
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e 0 1 abc a13bc 13 key key}

test entry-19.7 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abc                 ;# previous settings
    set ::vVals {}
    .e insert end d
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.8 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e configure -validate focus    ;# previous settings
    .e insert end abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusin}

test entry-19.9 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focus \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abcd      ;# previous settings
    focus -force .e         ;# previous settings
    update                  ;# previous settings
# update necessary to process FocusIn event
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focus focusout}

test entry-19.10 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abcd          ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusin}

test entry-19.11 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abcd          ;# previous settings
    focus -force .e             ;# previous settings
# update necessary to process FocusIn event
    update                      ;# previous settings
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} all focusout}

test entry-19.12 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert 0 abcd              ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test entry-19.13 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focusin \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abcd              ;# previous settings
    set ::vVals {}
    focus -force .
# update necessary to process FocusOut event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.14 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e
# update necessary to process FocusIn event
    update
    set ::vVals
} -cleanup {
    destroy .e
} -result {}

test entry-19.15 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event







|







3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
    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 ; update idletasks
    .e insert end abcd              ;# previous settings
    set ::vVals {}                  ;# previous settings
    focus -force .e                 ;# previous settings
# update necessary to process FocusIn event
    update                          ;# previous settings
    focus -force .
# update necessary to process FocusOut event
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate focuso \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    .e insert end abcd              ;# previous settings
    set ::e newdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {focusout {.e -1 -1 newdata abcd {} focusout forced}}


# proc doval changed - returns 0
test entry-19.18 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e newdata                 ;# previous settings
    .e configure -validate all
    set ::e nextdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {none {.e -1 -1 nextdata newdata {} all forced}}

## This sets validate to none because it shows that we prevent a possible
## loop condition in the validation, when the entry textvar is also set
# proc doval2 used
test entry-19.19 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e nextdata                 ;# previous settings

    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V]
    .e validate
    list [.e cget -validate] [.e get] $::vVals
} -cleanup {
    destroy .e







|

















|



















|







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
    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 ; update idletasks
    .e insert end abcd              ;# previous settings
    set ::e newdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {focusout {.e -1 -1 newdata abcd {} focusout forced}}


# proc doval changed - returns 0
test entry-19.18 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    set ::e newdata                 ;# previous settings
    .e configure -validate all
    set ::e nextdata
    list [.e cget -validate] $::vVals
} -cleanup {
    destroy .e
} -result {none {.e -1 -1 nextdata newdata {} all forced}}

## This sets validate to none because it shows that we prevent a possible
## loop condition in the validation, when the entry textvar is also set
# proc doval2 used
test entry-19.19 {entry widget validation} -setup {
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval3 %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e ; update idletasks
    set ::e nextdata                 ;# previous settings

    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V]
    .e validate
    list [.e cget -validate] [.e get] $::vVals
} -cleanup {
    destroy .e
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
    unset -nocomplain ::e ::vVals
} -body {
    entry .e -validate all \
        -validatecommand [list doval %W %d %i %P %s %S %v %V] \
        -invalidcommand bell \
        -textvariable ::e \
        -background red -foreground white
    pack .e
    set ::e nextdata                 ;# previous settings
    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V] ;# prev
    .e validate                     ;# previous settings

    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals







|







3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
    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 ; update idletasks
    set ::e nextdata                 ;# previous settings
    .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V] ;# prev
    .e validate                     ;# previous settings

    .e configure -validate all
    set ::e testdata
    list [.e cget -validate] [.e get] $::e $::vVals
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
## 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}}








|







3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
## 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 ; update idletasks
    set ::e origdata
    .e insert 0 A
    list [.e cget -validate] [.e get] $::e $::vVals
} -cleanup {
    destroy .e
} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}}

3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
    destroy .e
} -result 0

test entry-20.7 {widget deletion with textvariable active} -body {
# SF bugs 607390 and 617446
    set FOO init
    entry .e -textvariable FOO -validate all \
	    -vcmd {%W configure -bg white; format 1}
    bind .e <Destroy> { set FOO hello }
    destroy .e
    winfo exists .e
} -cleanup {
    destroy .e
} -result 0








|







3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
    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 \
	    -validatecommand {%W configure -bg white; format 1}
    bind .e <Destroy> { set FOO hello }
    destroy .e
    winfo exists .e
} -cleanup {
    destroy .e
} -result 0

3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't read "::test::foo": no such variable}]

test entry-23.1 {error in trace proc attached to the textvariable} -setup {
    destroy .e
} -body {
    trace variable myvar w traceit
    proc traceit args {error "Intentional error here!"}
    entry .e -textvariable myvar
    catch {.e insert end mystring} result1
    catch {.e delete 0} result2
    list $result1 $result2
} -cleanup {
    destroy .e







|







3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't set "::test::foo": parent namespace doesn't exist} \
	{can't read "::test::foo": no such variable}]

test entry-23.1 {error in trace proc attached to the textvariable} -setup {
    destroy .e
} -body {
    trace add variable myvar write traceit
    proc traceit args {error "Intentional error here!"}
    entry .e -textvariable myvar
    catch {.e insert end mystring} result1
    catch {.e delete 0} result2
    list $result1 $result2
} -cleanup {
    destroy .e
3598
3599
3600
3601
3602
3603
3604



















3605
3606
3607
3608
3609
3610
3611
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}





















# Gathered comments about lacks
# XXX Still need to write tests for EntryBlinkProc, EntryFocusProc,
# and EntryTextVarProc.
# No tests for DisplayEntry.
# XXX Still need to write tests for EntryScanTo and EntrySelectTo.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}
test entry-25.3 {Bug [2a32225cd1] - Navigation in a password made of several words} -setup {
    destroy .e
    pack [entry .e -show *]
    update
    set res {}
} -body {
    .e insert end "A sample password made of several words"
    .e icursor end
    event generate .e <<PrevWord>>  ; # shall move insert to index 0
    .e delete insert end
    lappend res [.e get]
    .e insert end "A sample password made of several words"
    .e icursor 2
    event generate .e <<NextWord>>  ; # shall move insert to index end
    .e delete 0 insert
    lappend res [.e get]
} -cleanup {
    destroy .e
} -result {{} {}}


# Gathered comments about lacks
# XXX Still need to write tests for EntryBlinkProc, EntryFocusProc,
# and EntryTextVarProc.
# No tests for DisplayEntry.
# XXX Still need to write tests for EntryScanTo and EntrySelectTo.

Changes to tests/event.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# This file is a Tcl script to test the code in tkEvent.c.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# XXX This test file is woefully incomplete.  Right now it only tests
# a few of the procedures in tkEvent.c.  Please add more tests whenever
# possible.

# Setup table used to query key events.

proc _init_keypress_lookup {} {
    global keypress_lookup

    scan A %c start
    scan Z %c finish

    for {set i $start} {$i <= $finish} {incr i} {
        set l [format %c $i]
        set keypress_lookup($l) $l
    }

    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 {
        ! exclam
        % percent
        & ampersand
        ( parenleft
        ) parenright
        * asterisk
        + plus
        , comma
        - minus
        . period
        / slash
        : colon
        < less
        = equal
        > 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 \

	    "\n" Return \
	    "\t" Tab]
}

# Lookup an event in the keypress table.
# For example:
# Q -> Q
# . -> period
# / -> slash
# Delete -> Delete
# Escape -> Escape

proc _keypress_lookup {char} {
    global keypress_lookup

    if {! [info exists keypress_lookup]} {





|
















<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<










>







|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


23






















24








25





26










27
28
29
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 © 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



    # Characters with meaning to Tcl...






















    array set keypress_lookup [list \








	    -    minus \





	    >    greater \










	    \"   quotedbl \
	    \#   numbersign \
	    \$   dollar \
	    \;   semicolon \
	    \[   bracketleft \
	    \\   backslash \
	    \]   bracketright \
	    \{   braceleft \
	    \}   braceright \
	    " "  space \
	    \xA0 nobreakspace \
	    "\n" Return \
	    "\t" Tab]
}

# Lookup an event in the keypress table.
# For example:
# Q -> Q
# ; -> semicolon
# > -> greater
# Delete -> Delete
# Escape -> Escape

proc _keypress_lookup {char} {
    global keypress_lookup

    if {! [info exists keypress_lookup]} {
752
753
754
755
756
757
758

759
760
761
762
763
764
765

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows

} -result {1.3 A 1.3 A}
test event-7.2(double-click) {A double click on a lone character
    in an entry widget should select that character} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]







>







706
707
708
709
710
711
712
713
714
715
716
717
718
719
720

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
    unset x1 y1 width height middle_y left_x left_y right_x right_y
} -result {1.3 A 1.3 A}
test event-7.2(double-click) {A double click on a lone character
    in an entry widget should select that character} -setup {
	deleteWindows
} -body {
    set t [toplevel .t]
    set e [entry $t.e]
818
819
820
821
822
823
824

825
826
827
828
829
830
831

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows

} -result {4 A 4 A}

test event-8 {event generate with keysyms corresponding to
              multi-byte virtual keycodes - bug
              e36963bfe8df9f5e528134707a91b9c0051de723} -constraints nonPortable -setup {
    deleteWindows
    set res [list ]







>







773
774
775
776
777
778
779
780
781
782
783
784
785
786
787

    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
    unset x1 y1 width height middle_y left_x left_y right_x right_y
} -result {4 A 4 A}

test event-8 {event generate with keysyms corresponding to
              multi-byte virtual keycodes - bug
              e36963bfe8df9f5e528134707a91b9c0051de723} -constraints nonPortable -setup {
    deleteWindows
    set res [list ]
854
855
856
857
858
859
860



























































861
862
863
864
865
866
867
        return "Test failed, unless the keyboard tied to the system \
                on which this test is run does NOT have a diaeresis \
                physical key - in this case, test is actually void."
    }
} -cleanup {
    deleteWindows
} -result {OK}




























































# cleanup
update
unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}
rename _keypress_lookup {}
rename _keypress {}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
        return "Test failed, unless the keyboard tied to the system \
                on which this test is run does NOT have a diaeresis \
                physical key - in this case, test is actually void."
    }
} -cleanup {
    deleteWindows
} -result {OK}

test event-9.1 {enter . window by destroying a toplevel - bug b1d115fa60} -setup {
    set EnterBind [bind . <Enter>]
} -body {
    wm geometry . 200x200+300+300
    wm deiconify .
    _pause 200
    toplevel .top2 -width 200 -height 200
    wm geometry .top2 +[expr {[winfo rootx .]+50}]+[expr {[winfo rooty .]+50}]
    update idletasks
    wm deiconify .top2
    update idletasks
    raise .top2
    _pause 400
    event generate .top2 <Motion> -warp 1 -x 50 -y 50
    _pause 100
    bind . <Enter> {lappend res %W}
    set res [list ]
    destroy .top2
    update idletasks
    _pause 200
    set res
} -cleanup {
    deleteWindows
    bind . <Enter> $EnterBind
} -result {.}
test event-9.2 {enter toplevel window by destroying a toplevel - bug b1d115fa60} -setup {
    set iconified false
    if {[winfo ismapped .]} {
        wm iconify .
        update
        set iconified true
    }
} -body {
    toplevel .top1
    wm geometry .top1 200x200+300+300
    wm deiconify .top1
    _pause 200
    toplevel .top2 -width 200 -height 200
    wm geometry .top2 +[expr {[winfo rootx .top1]+50}]+[expr {[winfo rooty .top1]+50}]
    _pause 200
    wm deiconify .top2
    update idletasks
    raise .top2
    _pause 400
    event generate .top2 <Motion> -warp 1 -x 50 -y 50
    _pause 100
    bind .top1 <Enter> {lappend res %W}
    set res [list ]
    destroy .top2
    _pause 200
    set res
} -cleanup {
    deleteWindows ; # destroy all children of ".", this already includes .top1
    if {$iconified} {
        wm deiconify .
        update
    }
} -result {.top1}

# cleanup
update
unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}
rename _keypress_lookup {}
rename _keypress {}

Changes to tests/filebox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out Tk's "tk_getOpenFile" and
# "tk_getSaveFile" commands. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

test fileDialog-0.1 {GetFileName: file types: MakeFilter() fails} {





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out Tk's "tk_getOpenFile" and
# "tk_getSaveFile" commands. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

test fileDialog-0.1 {GetFileName: file types: MakeFilter() fails} {
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    }

    update
    SendButtonPress $parent ok mouse
}

proc SendButtonPress {parent btn type} {
    global tk_strictMotif
    if {$parent == "."} {
	set w .__tk_filedialog
    } else {
	set w $parent.__tk_filedialog
    }
    upvar ::tk::dialog::file::__tk_filedialog data








<







70
71
72
73
74
75
76

77
78
79
80
81
82
83
    }

    update
    SendButtonPress $parent ok mouse
}

proc SendButtonPress {parent btn type} {

    if {$parent == "."} {
	set w .__tk_filedialog
    } else {
	set w $parent.__tk_filedialog
    }
    upvar ::tk::dialog::file::__tk_filedialog data

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
if {$tcl_platform(platform) == "unix"} {
    set modes "0 1"
} else {
    set modes 1
}

set unknownOptionsMsg(tk_getOpenFile,notAqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getOpenFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -multiple, -parent, -title, -typevariable, or -command}
set unknownOptionsMsg(tk_getSaveFile,notAqua) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getSaveFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -parent, -title, -typevariable, -command, or -confirmoverwrite}

set tmpFile "filebox.tmp"
makeFile {
    # this file can be empty!
} $tmpFile

array set filters {







|

|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
if {$tcl_platform(platform) == "unix"} {
    set modes "0 1"
} else {
    set modes 1
}

set unknownOptionsMsg(tk_getOpenFile,notAqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getOpenFile,aqua) {bad option "-foo": must be -command, -defaultextension, -filetypes, -initialdir, -initialfile, -message, -multiple, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getSaveFile,notAqua) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getSaveFile,aqua) {bad option "-foo": must be -command, -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -message, -parent, -title, or -typevariable}

set tmpFile "filebox.tmp"
makeFile {
    # this file can be empty!
} $tmpFile

array set filters {
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring

    set color #404040
    test filebox-2.1-$mode "tk_getOpenFile command" nonUnixUserInteraction {
        ToPressButton $parent cancel
        tk_getOpenFile -title "Press Cancel ($verylongstring)" -parent $parent
    } ""

    set fileName $tmpFile
    set fileDir [tcltest::temporaryDirectory]







<







205
206
207
208
209
210
211

212
213
214
215
216
217
218
    set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring


    test filebox-2.1-$mode "tk_getOpenFile command" nonUnixUserInteraction {
        ToPressButton $parent cancel
        tk_getOpenFile -title "Press Cancel ($verylongstring)" -parent $parent
    } ""

    set fileName $tmpFile
    set fileDir [tcltest::temporaryDirectory]
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    }
    foreach {x res} [list 1 "-unset-" 2 "Text files"] {
	set t [expr {$x + [llength [array names filters]]}]
        test filebox-3.$t-$mode "tk_getOpenFile command" nonUnixUserInteraction {
	    catch {unset tv}
	    catch {unset typeName}
	    ToPressButton $parent ok
	    if {[info exists tv]} {
	    } else {
	    }
	    set choice [tk_getOpenFile -title "Press Ok" \
		    -filetypes $filters($x) -parent $parent \
		    -initialfile $fileName -initialdir $fileDir \
		    -typevariable tv]
	    if {[info exists tv]} {
		set typeName $tv
	    } else {







<
<
<







275
276
277
278
279
280
281



282
283
284
285
286
287
288
    }
    foreach {x res} [list 1 "-unset-" 2 "Text files"] {
	set t [expr {$x + [llength [array names filters]]}]
        test filebox-3.$t-$mode "tk_getOpenFile command" nonUnixUserInteraction {
	    catch {unset tv}
	    catch {unset typeName}
	    ToPressButton $parent ok



	    set choice [tk_getOpenFile -title "Press Ok" \
		    -filetypes $filters($x) -parent $parent \
		    -initialfile $fileName -initialdir $fileDir \
		    -typevariable tv]
	    if {[info exists tv]} {
		set typeName $tv
	    } else {
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
    } -returnCodes error -result {bad file type "Foo", should be "typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?"}

    set isNative [expr {
	[info commands ::tk::MotifFDialog] eq "" &&
	[info commands ::tk::dialog::file::] eq ""
    }]

    set parent .

    set verylongstring longstring:
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring

    set color #404040
    test filebox-5.1-$mode "tk_getSaveFile command" nonUnixUserInteraction {
	ToPressButton $parent cancel
	tk_getSaveFile -title "Press Cancel ($verylongstring)" -parent $parent
    } ""

    set fileName "12x 455"
    set fileDir [pwd]







<
<
<
<
<
<
<
<
<
<
<
<
<
<







328
329
330
331
332
333
334














335
336
337
338
339
340
341
    } -returnCodes error -result {bad file type "Foo", should be "typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?"}

    set isNative [expr {
	[info commands ::tk::MotifFDialog] eq "" &&
	[info commands ::tk::dialog::file::] eq ""
    }]















    test filebox-5.1-$mode "tk_getSaveFile command" nonUnixUserInteraction {
	ToPressButton $parent cancel
	tk_getSaveFile -title "Press Cancel ($verylongstring)" -parent $parent
    } ""

    set fileName "12x 455"
    set fileDir [pwd]

Changes to tests/focus.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is a Tcl script to test out the "focus" command and the
# other procedures in the file tkFocus.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

proc focusSetup {} {
    destroy .t
    toplevel .t
    wm geom .t +0+0
    foreach i {b1 b2 b3 b4} {





|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is a Tcl script to test out the "focus" command and the
# other procedures in the file tkFocus.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 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} {
74
75
76
77
78
79
80

81
82
83
84
85
86
87
if {[testConstraint altDisplay]} {
    focusSetupAlt
}


test focus-1.1 {Tk_FocusCmd procedure} -constraints unix -body {
    focusClear

    focus
} -result {}
test focus-1.2 {Tk_FocusCmd procedure} -constraints {
	unix altDisplay
} -body {
    focus .alt.b
    focus







>







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
if {[testConstraint altDisplay]} {
    focusSetupAlt
}


test focus-1.1 {Tk_FocusCmd procedure} -constraints unix -body {
    focusClear
    after 100
    focus
} -result {}
test focus-1.2 {Tk_FocusCmd procedure} -constraints {
	unix altDisplay
} -body {
    focus .alt.b
    focus
750
751
752
753
754
755
756























757
758
759
760
761
762
    focus -force .top.s3
    update
    focus
} -cleanup {
    destroy .top
} -result {.top.s3}

























deleteWindows

# cleanup
cleanupTests
return







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
    focus -force .top.s3
    update
    focus
} -cleanup {
    destroy .top
} -result {.top.s3}

test focus-8.1 {fdc0ed342d - segfault on focus -force} -body {
    pack [button .b0]
    toplevel .one
    update
    event generate .one <Motion> -warp 1 -x 175 -y 175
    update idletasks
    destroy {*}[winfo children .]
    toplevel .t
    pack [canvas .t.c]
    update
    destroy .t.c
    pack [label .t.l]
    update
    destroy .t.l
    destroy {*}[winfo children .]
    proc crashit {} {
	pack [listbox .l]
	update
	focus -force .l;  # This line segfaulted *with xvfb*
	set res Reached
    }
    crashit
} -result {Reached}

deleteWindows

# cleanup
cleanupTests
return

Changes to tests/focusTcl.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the features of the script
# file focus.tcl, which includes the procedures tk_focusNext and
# tk_focusPrev, among other things.  This file is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the features of the script
# file focus.tcl, which includes the procedures tk_focusNext and
# tk_focusPrev, among other things.  This file is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

Changes to tests/font.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# This file is a Tcl script to test out Tk's "font" command
# plus the procedures in tkFont.c.  It is organized in the
# standard white-box fashion for Tcl tests.
#
# Copyright © 1996-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Some tests require support for 4-byte UTF-8 sequences
testConstraint fullutf [expr {[format %c 0x010000] != "\uFFFD"}]
testConstraint utfcompat [expr {([string length "\U10000"] == 2) && [package vsatisfies [package provide Tcl] 8]}]
testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

set defaultfontlist [font names]

proc getnondefaultfonts {} {
    global defaultfontlist
    set nondeffonts [list ]
    foreach afont [font names] {





|










|
<







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 Tk's "font" command
# plus the procedures in tkFont.c.  It is organized in the
# standard white-box fashion for Tcl tests.
#
# Copyright © 1996-1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 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)]}]


set defaultfontlist [font names]

proc getnondefaultfonts {} {
    global defaultfontlist
    set nondeffonts [list ]
    foreach afont [font names] {
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
} -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-4.12 {font command: actual} -body {
    font actual {-family times} -- \uD800
} -match glob -result {*}
test font-4.13 {font command: actual} -body {
    font actual {-family times} -- \uDC00
} -match glob -result {*}
test font-4.14 {font command: actual} -constraints {utfcompat win} -body {
    font actual {-family times} -family -- \uD800\uDC00
} -result {times}
test font-4.15 {font command: actual} -body {
    font actual {-family times} -- \uDC00\uD800
} -returnCodes 1 -match glob -result {expected a single character but got "*"}
test font-4.16 {font command: actual} -constraints {fullutf win} -body {
    font actual {-family times} -family -- \U10000
} -result {times}


test font-5.1 {font command: configure} -body {
    # (objc < 3)
    font configure







|





|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
} -returnCodes error -result {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}
test font-4.12 {font command: actual} -body {
    font actual {-family times} -- \uD800
} -match glob -result {*}
test font-4.13 {font command: actual} -body {
    font actual {-family times} -- \uDC00
} -match glob -result {*}
test font-4.14 {font command: actual} -constraints {utfcompat win knownBug} -body {
    font actual {-family times} -family -- \uD800\uDC00
} -result {times}
test font-4.15 {font command: actual} -body {
    font actual {-family times} -- \uDC00\uD800
} -returnCodes 1 -match glob -result {expected a single character but got "*"}
test font-4.16 {font command: actual} -constraints {fullutf win knownBug} -body {
    font actual {-family times} -family -- \U10000
} -result {times}


test font-5.1 {font command: configure} -body {
    # (objc < 3)
    font configure
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
test font-10.4 {font command: metrics: arguments} -body {
    # (objc - skip) > 4) when skip == 0
    font metrics xyz abc def
} -returnCodes error -result {wrong # args: should be "font metrics font ?-displayof window? ?-option?"}
test font-10.5 {font command: metrics: arguments} -body {
    # (objc - skip) > 4) when skip == 2
    font metrics xyz -displayof . abc
} -returnCodes error -result {bad metric "abc": must be -ascent, -descent, -linespace, or -fixed}
test font-10.6 {font command: metrics: bad font} -constraints noExceed -body {
    # (tkfont == NULL)
    font metrics "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-10.7 {font command: metrics: get all metrics} -setup {
    catch {unset a}
} -body {
    # (objc == 3)
    array set a [font metrics {-family xyz}]
    lsort [array names a]
} -cleanup {
    unset a
} -result {-ascent -descent -fixed -linespace}
test font-10.8 {font command: metrics: bad metric} -body {
    # (Tcl_GetIndexFromObj() != TCL_OK)
    font metrics $fixed -xyz
} -returnCodes error -result {bad metric "-xyz": must be -ascent, -descent, -linespace, or -fixed}
test font-10.9 {font command: metrics: get individual metrics} -body {
    font metrics $fixed -ascent
    font metrics $fixed -descent
    font metrics $fixed -linespace
    font metrics $fixed -fixed
} -result 1








|
















|







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
test font-10.4 {font command: metrics: arguments} -body {
    # (objc - skip) > 4) when skip == 0
    font metrics xyz abc def
} -returnCodes error -result {wrong # args: should be "font metrics font ?-displayof window? ?-option?"}
test font-10.5 {font command: metrics: arguments} -body {
    # (objc - skip) > 4) when skip == 2
    font metrics xyz -displayof . abc
} -returnCodes error -result {bad metric "abc": must be -ascent, -descent, -fixed, or -linespace}
test font-10.6 {font command: metrics: bad font} -constraints noExceed -body {
    # (tkfont == NULL)
    font metrics "\{xyz"
} -returnCodes error -result "font \"{xyz\" doesn't exist"
test font-10.7 {font command: metrics: get all metrics} -setup {
    catch {unset a}
} -body {
    # (objc == 3)
    array set a [font metrics {-family xyz}]
    lsort [array names a]
} -cleanup {
    unset a
} -result {-ascent -descent -fixed -linespace}
test font-10.8 {font command: metrics: bad metric} -body {
    # (Tcl_GetIndexFromObj() != TCL_OK)
    font metrics $fixed -xyz
} -returnCodes error -result {bad metric "-xyz": must be -ascent, -descent, -fixed, or -linespace}
test font-10.9 {font command: metrics: get individual metrics} -body {
    font metrics $fixed -ascent
    font metrics $fixed -descent
    font metrics $fixed -linespace
    font metrics $fixed -fixed
} -result 1

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
} -cleanup {
    font delete xyz
} -result {}
test font-12.2 {UpdateDependantFonts procedure: pings the widgets} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update
} -body {
    font create xyz -family times -size 20
    .t.f config -font xyz -text "abcd" -padx 0 -bd 0 -highlightthickness 0
    set a1 [font measure xyz "abcd"]
    update
    set b1 [winfo reqwidth .t.f]
    font configure xyz -family helvetica -size 20
    set a2 [font measure xyz "abcd"]
    update
    set b2 [winfo reqwidth .t.f]
    expr {$a1==$b1 && $a2==$b2}
} -cleanup {
    destroy .t.f
    font delete xyz
} -result 1








|




|



|







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
} -cleanup {
    font delete xyz
} -result {}
test font-12.2 {UpdateDependantFonts procedure: pings the widgets} -setup {
    destroy .t.f
    catch {font delete xyz}
    pack [label .t.f]
    update idletasks
} -body {
    font create xyz -family times -size 20
    .t.f config -font xyz -text "abcd" -padx 0 -bd 0 -highlightthickness 0
    set a1 [font measure xyz "abcd"]
    update idletasks
    set b1 [winfo reqwidth .t.f]
    font configure xyz -family helvetica -size 20
    set a2 [font measure xyz "abcd"]
    update idletasks
    set b2 [winfo reqwidth .t.f]
    expr {$a1==$b1 && $a2==$b2}
} -cleanup {
    destroy .t.f
    font delete xyz
} -result 1

593
594
595
596
597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

636
637
638
639
640
641
642


test font-15.1 {Tk_AllocFontFromObj - converting internal reps} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
} -body {
    set x {Times 16}
    lindex $x 0
    button .b1 -font $x
    lindex $x 0
    testfont counts {Times 16}
} -cleanup {

    destroy .b1 .b2
} -result {{1 0}}
test font-15.2 {Tk_AllocFontFromObj - discard stale font} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x {Times 16}
    button .b1 -font $x
    destroy .b1
    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    lappend result [testfont counts {Times 16}]
} -cleanup {

    destroy .b2
} -result {{} {{1 1}}}
test font-15.3 {Tk_AllocFontFromObj - reuse existing font} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x {Times 16}
    button .b1 -font $x
    lappend result [testfont counts {Times 16}]
    button .b2 -font $x
    pack .b1 .b2 -side top
    lappend result [testfont counts {Times 16}]
} -cleanup {

    destroy .b1 .b2
} -result {{{1 1}} {{2 1}}}
test font-15.4 {Tk_AllocFontFromObj procedure: bump ref count} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {







|



|

>








|


|

|

>








|

|


|

>







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644


test font-15.1 {Tk_AllocFontFromObj - converting internal reps} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
} -body {
    set x [font create font-15.1_font -family Times -size 16]
    lindex $x 0
    button .b1 -font $x
    lindex $x 0
    testfont counts $x
} -cleanup {
    font delete font-15.1_font
    destroy .b1 .b2
} -result {{1 0}}
test font-15.2 {Tk_AllocFontFromObj - discard stale font} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x [font create font-15.2_font -family Times -size 16]
    button .b1 -font $x
    destroy .b1
    lappend result [testfont counts $x]
    button .b2 -font $x
    lappend result [testfont counts $x]
} -cleanup {
    font delete font-15.2_font
    destroy .b2
} -result {{} {{1 1}}}
test font-15.3 {Tk_AllocFontFromObj - reuse existing font} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
    set result {}
} -body {
    set x [font create font-15.3_font -family Times -size 16]
    button .b1 -font $x
    lappend result [testfont counts $x]
    button .b2 -font $x
    pack .b1 .b2 -side top
    lappend result [testfont counts $x]
} -cleanup {
    font delete font-15.3_font
    destroy .b1 .b2
} -result {{{1 1}} {{2 1}}}
test font-15.4 {Tk_AllocFontFromObj procedure: bump ref count} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766


767
768
769
770
771
772
773
    .t.f cget -font
} -cleanup {
    destroy .t.f
} -result {-family fixed}


test font-17.1 {Tk_FreeFontFromObj - reference counts} -constraints {
	testfont
} -setup {
    destroy .b1 .b2 .b3
    set result {}
} -body {
    set x {Courier 12}
    button .b1 -font $x
    button .b3 -font $x
    button .b2 -font $x
    lappend result [testfont counts {Courier 12}]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    destroy .b2
    lappend result [testfont counts {Courier 12}]
    destroy .b3
    lappend result [testfont counts {Courier 12}]


} -result {{{3 1}} {{2 1}} {{1 1}} {}}
test font-17.2 {Tk_FreeFont procedure: one ref} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (fontPtr->refCount == 0)







|




|



|

|

|

|
>
>







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
    .t.f cget -font
} -cleanup {
    destroy .t.f
} -result {-family fixed}


test font-17.1 {Tk_FreeFontFromObj - reference counts} -constraints {
    testfont
} -setup {
    destroy .b1 .b2 .b3
    set result {}
} -body {
    set x [font create font-17.1_font -family Courier -size 12]
    button .b1 -font $x
    button .b3 -font $x
    button .b2 -font $x
    lappend result [testfont counts $x]
    destroy .b1
    lappend result [testfont counts $x]
    destroy .b2
    lappend result [testfont counts $x]
    destroy .b3
    lappend result [testfont counts $x]
} -cleanup {
    font delete font-17.1_font
} -result {{{3 1}} {{2 1}} {{1 1}} {}}
test font-17.2 {Tk_FreeFont procedure: one ref} -setup {
    destroy .t.f
    pack [label .t.f]
    update
} -body {
    # (fontPtr->refCount == 0)
831
832
833
834
835
836
837

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852


853
854
855
856
857
858
859
} -result {-family -family}


test font-18.1 {FreeFontObjProc} -constraints testfont -setup {
    destroy .b1
    set result {}
} -body {

    set x [join {Courier 12} { }]
    button .b1 -font $x
    set y [join {Courier 12} { }]
    .b1 configure -font $y
    set z [join {Courier 12} { }]
    .b1 configure -font $z
    lappend result [testfont counts {Courier 12}]
    set x red
    lappend result [testfont counts {Courier 12}]
    set z 32
    lappend result [testfont counts {Courier 12}]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    set y bogus
    return $result


} -result {{{1 3}} {{1 2}} {{1 1}} {}}


test font-19.1 {Tk_FontId} -setup {
    destroy .t.f
    pack [label .t.f]
    update







>
|

|

|

|

|

|

|


>
>







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
} -result {-family -family}


test font-18.1 {FreeFontObjProc} -constraints testfont -setup {
    destroy .b1
    set result {}
} -body {
    set f [font create font-18.1_font -family Courier -size 12]
    set x [join [list $f 50] { }]
    button .b1 -font $x
    set y [join [list $f 50] { }]
    .b1 configure -font $y
    set z [join [list $f 50] { }]
    .b1 configure -font $z
    lappend result [testfont counts [list $f 50]]
    set x red
    lappend result [testfont counts [list $f 50]]
    set z 32
    lappend result [testfont counts [list $f 50]]
    destroy .b1
    lappend result [testfont counts [list $f 50]]
    set y bogus
    return $result
} -cleanup {
    font delete font-18.1_font
} -result {{{1 3}} {{1 2}} {{1 1}} {}}


test font-19.1 {Tk_FontId} -setup {
    destroy .t.f
    pack [label .t.f]
    update
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" -underline -1
} -result {}
test font-27.2 {Tk_UnderlineTextLayout procedure: underline not visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 10
} -result {}
test font-27.3 {Tk_UnderlineTextLayout procedure: underline is visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 5
    .t.f config -wrap -1 -underline -1
} -result {}
destroy .t.f



# Canvas created for tests: 28.*
destroy .t.c







|






|







1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
destroy .t.c

#  Label used in 27.* tests
destroy .t.f
pack [label .t.f]
update
test font-27.1 {Tk_UnderlineTextLayout procedure: no underline chosen} -body {
    .t.f config -text "foo" -underline {}
} -result {}
test font-27.2 {Tk_UnderlineTextLayout procedure: underline not visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 10
} -result {}
test font-27.3 {Tk_UnderlineTextLayout procedure: underline is visible} -body {
    .t.f config -text "000          00000" -wrap [expr $ax*7] -under 5
    .t.f config -wrap -1 -underline {}
} -result {}
destroy .t.f



# Canvas created for tests: 28.*
destroy .t.c
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775


#  Label used in 29.* tests
destroy .t.f
pack [label .t.f]
update
test font-29.1 {Tk_CharBBox procedure: index < 0} -body {
    .t.f config -text "000" -underline -1
} -result {}
test font-29.2 {Tk_CharBBox procedure: loop} -body {
    .t.f config -text "000\t000\t000\t000" -underline 9
} -result {}
test font-29.3 {Tk_CharBBox procedure: special char} -body {
    .t.f config -text "000\t000\t000" -underline 7
} -result {}







|







1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782


#  Label used in 29.* tests
destroy .t.f
pack [label .t.f]
update
test font-29.1 {Tk_CharBBox procedure: index < 0} -body {
    .t.f config -text "000" -underline {}
} -result {}
test font-29.2 {Tk_CharBBox procedure: loop} -body {
    .t.f config -text "000\t000\t000\t000" -underline 9
} -result {}
test font-29.3 {Tk_CharBBox procedure: special char} -body {
    .t.f config -text "000\t000\t000" -underline 7
} -result {}
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 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 {







|







2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
test font-38.9 {ParseFontNameObj procedure: arguments} -body {
    font actual {times 20 xyz xyz}
} -returnCodes error -result {unknown font style "xyz"}
test font-38.10 {ParseFontNameObj procedure: arguments} -body {
    font actual {times xyz xyz}
} -returnCodes error -result {expected integer but got "xyz"}
test font-38.11 {ParseFontNameObj procedure: stylelist loop} -constraints {
    unixOrWin haveTimes12BoldItalicUnderlineOverstrikeFont
} -body {
    lrange [font actual {times 12 bold italic overstrike underline}] 4 end
} -result {-weight bold -slant italic -underline 1 -overstrike 1}
test font-38.12 {ParseFontNameObj procedure: stylelist error} -body {
    font actual {times 12 bold xyz}
} -returnCodes error -result {unknown font style "xyz"}
test font-38.13 "ParseFontNameObj: options with hyphenated family: bug #2791352" -body {
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
    font actual -xyz--*-*-*-*-*-*-*-*-*-*-*-*
    font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*
    font actual -xyz-?-*-*-*-*-*-*-*-*-*-*-*-*
    lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1
} -result [font actual {times 0} -family]


test font-44.1 {TkFontGetPixels: size < 0} -constraints failsOnUbuntuNoXft -setup {
    set oldscale [tk scaling]
} -body {

    tk scaling 0.5
    font actual {times -12} -size
} -cleanup {
    tk scaling $oldscale
} -result 24
test font-44.2 {TkFontGetPoints: size >= 0} -constraints {noExceed failsOnUbuntuNoXft} -setup {
    set oldscale [tk scaling]
} -body {
    tk scaling 0.5
    font actual {times 12} -size
} -cleanup {
    tk scaling $oldscale
} -result 12


test font-45.1 {TkFontGetAliasList: no match} -body {
    font actual {snarky 10} -family
} -result [font actual {-size 10} -family]
test font-45.2 {TkFontGetAliasList: match} -constraints win -body {
    font actual {times 10} -family
} -result {times}
test font-45.3 {TkFontGetAliasList: match} -constraints {noExceed} -body {
    if {[font actual {{times new roman} 10} -family] eq "Times New Roman"} {
        # avoid test failure on systems that have a real "times new roman" font
        set res 1
    } else {
        set res [expr {[font actual {{times new roman} 10} -family] eq \
                       [font actual {times 10} -family]} ]
    }







|


>

|


|
|















|







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
    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]
} -body {
    set oldsize [expr {-(-12.0 / $oldscale)}]
    tk scaling 0.5
    expr {round([font actual {times -12} -size] / $oldscale * 0.5) - round($oldsize) == 0}
} -cleanup {
    tk scaling $oldscale
} -result 1
test font-44.2 {TkFontGetPoints: size >= 0} -constraints {noExceed haveTimes12Font} -setup {
    set oldscale [tk scaling]
} -body {
    tk scaling 0.5
    font actual {times 12} -size
} -cleanup {
    tk scaling $oldscale
} -result 12


test font-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 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]} ]
    }
2403
2404
2405
2406
2407
2408
2409
2410












































































































































2411
2412
2413
2414
2415
2416
2417
    load {} Tk one
    load {} Tk two
    one eval menu .menubar
    two eval menu .menubar
    interp delete one
    interp delete two
} -result {}













































































































































# cleanup
cleanupTests
return












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    load {} Tk one
    load {} Tk two
    one eval menu .menubar
    two eval menu .menubar
    interp delete one
    interp delete two
} -result {}

test font-47.2 {Bug 3049518 - Canvas} -body {
    if {"MyFont" ni [font names]} {
	font create MyFont -family "Liberation Sans" -size 13
    }
    set text Hello!
    destroy .t.c
    set c [canvas .t.c]
    set textid [$c create text 20 20 -font MyFont -text $text -anchor nw]
    set twidth [font measure MyFont $text]
    set theight [font metrics MyFont -linespace]
    set circid [$c create polygon \
		    15                    15 \
		    [expr {15 + $twidth}] 15 \
		    [expr {15 + $twidth}] [expr {15 + $theight}] \
		    15                    [expr {15 + $theight}] \
		    -width 1 -joinstyle round -smooth true -fill {} -outline blue]
    pack $c -fill both -expand 1 -side top
    update

    # Lamda test functions
    set circle_text {{w user_data text circ} {
	if {[winfo class $w] ne "Canvas"} {
	    puts "Wrong widget type: $w"
	    return
	}
	if {$user_data ne "FontChanged"} {
	    return
	}
	lappend ::results called-$w
	lassign [$w bbox $text] x0 y0 x1 y1
	set offset 5
	set coord [lmap expr {
			      $x0-$offset $y0-$offset $x1+$offset $y0-$offset
			      $x1+$offset $y1+$offset $x0-$offset $y1+$offset
			  } {expr $expr}]
	if {[catch {$w coord $circ $coord} err]} {
	    puts Error:$err
	}
    }}
    set enclosed {{can id} {$can find enclosed {*}[$can bbox $id]}}

    set results {}
    apply $circle_text $c FontChanged $textid $circid
    update
    bind $c <<TkWorldChanged>> [list apply $circle_text %W %d $textid $circid]

    # Begin test:
    set results {}
    lappend results [apply $enclosed $c $circid]
    font configure MyFont -size 26
    update  ; # services the "TheWorldHasChanged" event, queues "TkWorldChanged" events
    update  ; # services the queued "TkWorldChanged" events
    lappend results [apply $enclosed $c $circid]
    font configure MyFont -size 9
    update idletasks
    update
    lappend results [apply $enclosed $c $circid]
    font configure MyFont -size 12
    update idletasks
    update
    lappend results [apply $enclosed $c $circid]
} -cleanup {
    destroy $c
    unset -nocomplain ::results
} -result {{1 2} called-.t.c {1 2} called-.t.c {1 2} called-.t.c {1 2}}

test font-47.3 {Bug 3049518 - Label} -body {
    if {"MyFont" ni [font names]} {
	font create MyFont -family "Liberation Sans" -size 13
    }
    set text "Label Test"
    destroy .t.l

    set make-img {{size} {
	set img [image create photo -width $size -height $size]
	$img blank
	set max [expr {$size - 1}]
	for {set x 0} {$x < $size} {incr x} {
	    $img put red -to $x $x
	    $img put black -to 0 $x
	    $img put black -to $x 0
	    $img put black -to $max $x
	    $img put black -to $x $max
	}
	return $img
    }}

    set testWorldChanged {{w user_data} {
	global make-img
	if {$user_data ne "FontChanged"} {
	    return
	}
	if {![winfo exists $w] || [winfo class $w] ne "Label"} {
	    return
	}
	if {[$w cget -image] ne ""} {
	    image delete [$w cget -image]
	}
	set size [font metrics [$w cget -font] -linespace]
	set img [apply ${make-img} $size]
	$w configure -image $img
    }}

    set check {{w} {
	global results
	set f [$w cget -font]
	set i [$w cget -image]
	set fs [font metrics $f -linespace]
	set ish [image height $i]
	set isw [image width $i]
	lappend results [list [expr {$fs == $ish ? 1 : [list $fs $ish]}] [expr {$fs == $isw ? 1 : [list $fs $isw]}]]
    }}

    set size [font metrics MyFont -linespace]
    set img [apply ${make-img} $size]
    set l [label .t.l -compound left -image $img -text $text -font MyFont]
    pack $l -side top -fill both -expand 1
    update
    bind $l <<TkWorldChanged>> [list apply $testWorldChanged %W %d]
    set ::results {}

    apply $check $l
    font configure MyFont -size 26
    update  ; # services the "TheWorldHasChanged" event, queues "TkWorldChanged" events
    update  ; # services the queued "TkWorldChanged" events
    apply $check $l
    font configure MyFont -size 9
    update idletasks
    update
    apply $check $l
    font configure MyFont -size 13
    update idletasks
    update
    apply $check $l
    set results
} -cleanup {
    destroy $l
    unset -nocomplain ::results
} -result {{1 1} {1 1} {1 1} {1 1}}

# cleanup
cleanupTests
return




Changes to tests/fontchooser.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Test the "tk::fontchooser" command
#
# Copyright © 2008 Pat Thoyts

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

# the following helper functions are related to the functions used
# in winDialog.test where they are used to send messages to the win32
# dialog (hence the wierdness).

proc start {cmd} {
    set ::tk_dialog {}
    set ::iter_after 0
    after 1 $cmd
}
proc then {cmd} {








<
<
<


|







1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
16
17
18
# Test the "tk::fontchooser" command
#
# Copyright © 2008 Pat Thoyts

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands




# 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 weirdness).

proc start {cmd} {
    set ::tk_dialog {}
    set ::iter_after 0
    after 1 $cmd
}
proc then {cmd} {
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194






195
196
197
198
199
200
201
202
203
204
    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.4 {fontchooser -font} -constraints {scriptImpl failsOnUbuntuNoXft} -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font {times 14 bold}
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    lrange $::testfont 1 end
} -result {14 bold}







# -------------------------------------------------------------------------

cleanupTests
return

# Local Variables:
# mode: tcl
# indent-tabs-mode: nil
# End:







|









>
>
>
>
>
>










175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.4 {fontchooser -font} -constraints {scriptImpl haveTimes14BoldFont} -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font {times 14 bold}
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    lrange $::testfont 1 end
} -result {14 bold}

test fontchooser-5.1 {fontchooser multiple configure} -constraints {scriptImpl} -body {
    tk fontchooser configure -title TestTitle -command foo
    tk fontchooser configure -command bar
    tk fontchooser configure -title
} -result {TestTitle}

# -------------------------------------------------------------------------

cleanupTests
return

# Local Variables:
# mode: tcl
# indent-tabs-mode: nil
# End:

Changes to tests/frame.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "frame", "labelframe" and
# "toplevel" commands of Tk.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands







|







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 © 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

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Returns the option names out of a list of option details.
#
# Arguments:
# options -		The option detail list.
proc optnames {options} {
    lsort [lmap desc $options {lindex $desc 0}]
}

test frame-1.1 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -class NewFrame
    .f configure -class
} -cleanup {
    deleteWindows







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Returns the option names out of a list of option details.
#
# Arguments:
# options -		The option detail list.
proc optnames {options} {
    lsort [lmap desc $options {lindex $desc 0}]
}

test frame-1.1 {frame configuration options} -setup {
    deleteWindows
} -body {
    frame .f -class NewFrame
    .f configure -class
} -cleanup {
    deleteWindows
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    .f configure -bd 4
    lindex [.f configure -bd] 4
} -cleanup {
    .f configure -bd [lindex [.f configure -bd] 3]
} -result 4
test frame-1.16 {frame configuration options} -body {
    .f configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.17 {frame configuration options} -body {
    .f configure -bg #00ff00
    lindex [.f configure -bg] 4
} -cleanup {
    .f configure -bg [lindex [.f configure -bg] 3]
} -result "#00ff00"
test frame-1.18 {frame configuration options} -body {
    .f configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-1.19 {frame configuration options} -body {
    .f configure -borderwidth 1.3
    lindex [.f configure -borderwidth] 4
} -cleanup {
    .f configure -borderwidth [lindex [.f configure -borderwidth] 3]
} -result 1
test frame-1.20 {frame configuration options} -body {
    .f configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.21 {frame configuration options} -body {
    .f configure -cursor arrow
    lindex [.f configure -cursor] 4
} -cleanup {
    .f configure -cursor [lindex [.f configure -cursor] 3]
} -result {arrow}
test frame-1.22 {frame configuration options} -body {
    .f configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-1.23 {frame configuration options} -body {
    .f configure -height 100
    lindex [.f configure -height] 4
} -cleanup {
    .f configure -height [lindex [.f configure -height] 3]
} -result 100
test frame-1.24 {frame configuration options} -body {
    .f configure -height not_a_number
} -returnCodes error -result {bad screen distance "not_a_number"}
test frame-1.25 {frame configuration options} -body {
    .f configure -highlightbackground #112233
    lindex [.f configure -highlightbackground] 4
} -cleanup {
    .f configure -highlightbackground [lindex [.f configure -highlightbackground] 3]
} -result "#112233"
test frame-1.26 {frame configuration options} -body {







|

















|

















|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    .f configure -bd 4
    lindex [.f configure -bd] 4
} -cleanup {
    .f configure -bd [lindex [.f configure -bd] 3]
} -result 4
test frame-1.16 {frame configuration options} -body {
    .f configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-1.17 {frame configuration options} -body {
    .f configure -bg #00ff00
    lindex [.f configure -bg] 4
} -cleanup {
    .f configure -bg [lindex [.f configure -bg] 3]
} -result "#00ff00"
test frame-1.18 {frame configuration options} -body {
    .f configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-1.19 {frame configuration options} -body {
    .f configure -borderwidth 1.3
    lindex [.f configure -borderwidth] 4
} -cleanup {
    .f configure -borderwidth [lindex [.f configure -borderwidth] 3]
} -result 1
test frame-1.20 {frame configuration options} -body {
    .f configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-1.21 {frame configuration options} -body {
    .f configure -cursor arrow
    lindex [.f configure -cursor] 4
} -cleanup {
    .f configure -cursor [lindex [.f configure -cursor] 3]
} -result {arrow}
test frame-1.22 {frame configuration options} -body {
    .f configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-1.23 {frame configuration options} -body {
    .f configure -height 100
    lindex [.f configure -height] 4
} -cleanup {
    .f configure -height [lindex [.f configure -height] 3]
} -result 100
test frame-1.24 {frame configuration options} -body {
    .f configure -height not_a_number
} -returnCodes error -result {expected screen distance but got "not_a_number"}
test frame-1.25 {frame configuration options} -body {
    .f configure -highlightbackground #112233
    lindex [.f configure -highlightbackground] 4
} -cleanup {
    .f configure -highlightbackground [lindex [.f configure -highlightbackground] 3]
} -result "#112233"
test frame-1.26 {frame configuration options} -body {
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    .f configure -highlightthickness 6
    lindex [.f configure -highlightthickness] 4
} -cleanup {
    .f configure -highlightthickness [lindex [.f configure -highlightthickness] 3]
} -result 6
test frame-1.30 {frame configuration options} -body {
    .f configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.31 {frame configuration options} -body {
    .f configure -padx 3
    lindex [.f configure -padx] 4
} -cleanup {
    .f configure -padx [lindex [.f configure -padx] 3]
} -result 3
test frame-1.32 {frame configuration options} -body {
    .f configure -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.33 {frame configuration options} -body {
    .f configure -pady 4
    lindex [.f configure -pady] 4
} -cleanup {
    .f configure -pady [lindex [.f configure -pady] 3]
} -result 4
test frame-1.34 {frame configuration options} -body {
    .f configure -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-1.35 {frame configuration options} -body {
    .f configure -relief ridge
    lindex [.f configure -relief] 4
} -cleanup {
    .f configure -relief [lindex [.f configure -relief] 3]
} -result {ridge}
test frame-1.36 {frame configuration options} -returnCodes error -body {







|








|








|







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    .f configure -highlightthickness 6
    lindex [.f configure -highlightthickness] 4
} -cleanup {
    .f configure -highlightthickness [lindex [.f configure -highlightthickness] 3]
} -result 6
test frame-1.30 {frame configuration options} -body {
    .f configure -highlightthickness badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-1.31 {frame configuration options} -body {
    .f configure -padx 3
    lindex [.f configure -padx] 4
} -cleanup {
    .f configure -padx [lindex [.f configure -padx] 3]
} -result 3
test frame-1.32 {frame configuration options} -body {
    .f configure -padx badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-1.33 {frame configuration options} -body {
    .f configure -pady 4
    lindex [.f configure -pady] 4
} -cleanup {
    .f configure -pady [lindex [.f configure -pady] 3]
} -result 4
test frame-1.34 {frame configuration options} -body {
    .f configure -pady badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-1.35 {frame configuration options} -body {
    .f configure -relief ridge
    lindex [.f configure -relief] 4
} -cleanup {
    .f configure -relief [lindex [.f configure -relief] 3]
} -result {ridge}
test frame-1.36 {frame configuration options} -returnCodes error -body {
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
    .f configure -width 32
    lindex [.f configure -width] 4
} -cleanup {
    .f configure -width [lindex [.f configure -width] 3]
} -result 32
test frame-1.39 {frame configuration options} -body {
    .f configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
destroy .f

test frame-2.1 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -class NewClass
    wm geometry .t +0+0







|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
    .f configure -width 32
    lindex [.f configure -width] 4
} -cleanup {
    .f configure -width [lindex [.f configure -width] 3]
} -result 32
test frame-1.39 {frame configuration options} -body {
    .f configure -width badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
destroy .f

test frame-2.1 {toplevel configuration options} -setup {
    deleteWindows
} -body {
    toplevel .t -width 200 -height 100 -class NewClass
    wm geometry .t +0+0
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.22 {toplevel configuration options} -body {
    .t configure -bd 4
    lindex [.t configure -bd] 4
} -result 4
test frame-2.23 {toplevel configuration options} -body {
    .t configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.24 {toplevel configuration options} -body {
    .t configure -bg #00ff00
    lindex [.t configure -bg] 4
} -result "#00ff00"
test frame-2.25 {toplevel configuration options} -body {
    .t configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.26 {toplevel configuration options} -body {
    .t configure -borderwidth 1.3
    lindex [.t configure -borderwidth] 4
} -result 1
test frame-2.27 {toplevel configuration options} -body {
    .t configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.28 {toplevel configuration options} -body {
    .t configure -cursor arrow
    lindex [.t configure -cursor] 4
} -result {arrow}
test frame-2.29 {toplevel configuration options} -body {
    .t configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-2.30 {toplevel configuration options} -body {
    .t configure -height 100
    lindex [.t configure -height] 4
} -result 100
test frame-2.31 {toplevel configuration options} -body {
    .t configure -height not_a_number
} -returnCodes error -result {bad screen distance "not_a_number"}
test frame-2.32 {toplevel configuration options} -body {
    .t configure -highlightcolor #123456
    lindex [.t configure -highlightcolor] 4
} -result "#123456"
test frame-2.33 {toplevel configuration options} -body {
    .t configure -highlightcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.34 {toplevel configuration options} -body {
    .t configure -highlightthickness 3
    lindex [.t configure -highlightthickness] 4
} -result 3
test frame-2.35 {toplevel configuration options} -body {
    .t configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.36 {toplevel configuration options} -body {
    .t configure -padx 3
    lindex [.t configure -padx] 4
} -result 3
test frame-2.37 {toplevel configuration options} -body {
    .t configure -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.38 {toplevel configuration options} -body {
    .t configure -pady 4
    lindex [.t configure -pady] 4
} -result 4
test frame-2.39 {toplevel configuration options} -body {
    .t configure -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-2.40 {toplevel configuration options} -body {
    .t configure -relief ridge
    lindex [.t configure -relief] 4
} -result {ridge}
test frame-2.41 {toplevel configuration options} -returnCodes error -body {
    .t configure -relief badValue
} -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test frame-2.42 {toplevel configuration options} -body {
    .t configure -width 32
    lindex [.t configure -width] 4
} -result 32
test frame-2.43 {toplevel configuration options} -body {
    .t configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
destroy .t

test frame-3.1 {TkCreateFrame procedure} -returnCodes error -body {
    frame
} -result {wrong # args: should be "frame pathName ?-option value ...?"}
test frame-3.2 {TkCreateFrame procedure} -setup {
    deleteWindows







|













|













|













|






|






|













|







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.22 {toplevel configuration options} -body {
    .t configure -bd 4
    lindex [.t configure -bd] 4
} -result 4
test frame-2.23 {toplevel configuration options} -body {
    .t configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-2.24 {toplevel configuration options} -body {
    .t configure -bg #00ff00
    lindex [.t configure -bg] 4
} -result "#00ff00"
test frame-2.25 {toplevel configuration options} -body {
    .t configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.26 {toplevel configuration options} -body {
    .t configure -borderwidth 1.3
    lindex [.t configure -borderwidth] 4
} -result 1
test frame-2.27 {toplevel configuration options} -body {
    .t configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-2.28 {toplevel configuration options} -body {
    .t configure -cursor arrow
    lindex [.t configure -cursor] 4
} -result {arrow}
test frame-2.29 {toplevel configuration options} -body {
    .t configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test frame-2.30 {toplevel configuration options} -body {
    .t configure -height 100
    lindex [.t configure -height] 4
} -result 100
test frame-2.31 {toplevel configuration options} -body {
    .t configure -height not_a_number
} -returnCodes error -result {expected screen distance but got "not_a_number"}
test frame-2.32 {toplevel configuration options} -body {
    .t configure -highlightcolor #123456
    lindex [.t configure -highlightcolor] 4
} -result "#123456"
test frame-2.33 {toplevel configuration options} -body {
    .t configure -highlightcolor non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-2.34 {toplevel configuration options} -body {
    .t configure -highlightthickness 3
    lindex [.t configure -highlightthickness] 4
} -result 3
test frame-2.35 {toplevel configuration options} -body {
    .t configure -highlightthickness badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-2.36 {toplevel configuration options} -body {
    .t configure -padx 3
    lindex [.t configure -padx] 4
} -result 3
test frame-2.37 {toplevel configuration options} -body {
    .t configure -padx badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-2.38 {toplevel configuration options} -body {
    .t configure -pady 4
    lindex [.t configure -pady] 4
} -result 4
test frame-2.39 {toplevel configuration options} -body {
    .t configure -pady badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-2.40 {toplevel configuration options} -body {
    .t configure -relief ridge
    lindex [.t configure -relief] 4
} -result {ridge}
test frame-2.41 {toplevel configuration options} -returnCodes error -body {
    .t configure -relief badValue
} -result {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}
test frame-2.42 {toplevel configuration options} -body {
    .t configure -width 32
    lindex [.t configure -width] 4
} -result 32
test frame-2.43 {toplevel configuration options} -body {
    .t configure -width badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
destroy .t

test frame-3.1 {TkCreateFrame procedure} -returnCodes error -body {
    frame
} -result {wrong # args: should be "frame pathName ?-option value ...?"}
test frame-3.2 {TkCreateFrame procedure} -setup {
    deleteWindows
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    wm geometry .t +0+0
    toplevel .x -width 140 -height 300 -use [winfo id .t] -bg green
    tkwait visibility .x
    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {
    # This call to update idletasks was added to prevent a crash that was
    # observed on OSX 10.12 (Sierra) only.  Any change, such as using the
    # Development version to make debugging symbols available, adding a print
    # statement, or calling update idletasks here, would make the test pass
    # with no segfault.
    update idletasks
    deleteWindows
} -result {0 0 140 300}
test frame-3.10 {TkCreateFrame procedure, -use option} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	update
    }
    option add *x.use [winfo id .t]
    toplevel .x -width 140 -height 300 -bg green
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	tkwait visibility .x
	update
    }
    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {
    destroy .t
    option clear
} -result {0 0 140 300}







<
<
<
<
<
<









<
<
<
|
<


<
<
<
|
|
<







651
652
653
654
655
656
657






658
659
660
661
662
663
664
665
666



667

668
669



670
671

672
673
674
675
676
677
678
    wm geometry .t +0+0
    toplevel .x -width 140 -height 300 -use [winfo id .t] -bg green
    tkwait visibility .x
    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {






    deleteWindows
} -result {0 0 140 300}
test frame-3.10 {TkCreateFrame procedure, -use option} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t -container 1 -width 300 -height 120
    wm geometry .t +0+0



    update

    option add *x.use [winfo id .t]
    toplevel .x -width 140 -height 300 -bg green



    tkwait visibility .x
    update

    list [expr {[winfo rootx .x] - [winfo rootx .t]}] \
	    [expr {[winfo rooty .x] - [winfo rooty .t]}] \
	    [winfo width .t] [winfo height .t]
} -cleanup {
    destroy .t
    option clear
} -result {0 0 140 300}
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038

test frame-9.1 {MapFrame procedure} -setup {
    deleteWindows
} -body {
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    set result [winfo ismapped .t]
    update idletasks
    lappend result [winfo ismapped .t]
} -cleanup {
    deleteWindows
} -result {0 1}
test frame-9.2 {MapFrame procedure} -setup {
    deleteWindows
} -body {







|







1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024

test frame-9.1 {MapFrame procedure} -setup {
    deleteWindows
} -body {
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    set result [winfo ismapped .t]
    update
    lappend result [winfo ismapped .t]
} -cleanup {
    deleteWindows
} -result {0 1}
test frame-9.2 {MapFrame procedure} -setup {
    deleteWindows
} -body {
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
    wm geometry .t2 +0+0
    tkwait visibility .t2
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    frame .t2.f -width 50 -height 50
    bind .t2.f <Configure> {destroy .t}
    pack .t2.f -side top
    update idletasks
    winfo exists .t
} -cleanup {
    deleteWindows
} -result 0

test frame-10.1 {frame widget vs hidden commands} -setup {
    deleteWindows







|







1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
    wm geometry .t2 +0+0
    tkwait visibility .t2
    toplevel .t -width 100 -height 400
    wm geometry .t +0+0
    frame .t2.f -width 50 -height 50
    bind .t2.f <Configure> {destroy .t}
    pack .t2.f -side top
    update
    winfo exists .t
} -cleanup {
    deleteWindows
} -result 0

test frame-10.1 {frame widget vs hidden commands} -setup {
    deleteWindows
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
    }
    return $result
} -cleanup {
    deleteWindows
} -result {1 1 1 1 1 1 1 1 1 1 1 1}
test frame-12.3 {FrameWorldChanged procedure} -setup {
    deleteWindows
	update idletasks
} -body {
    # Check reaction on font change
    font create myfont -family courier -size 10
    labelframe .f -font myfont -text Mupp
    place .f -x 0 -y 0 -width 40 -height 40
    pack [frame .f.f] -fill both -expand 1
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	update
    }
    set h1 [font metrics myfont -linespace]
    set y1 [winfo y .f.f]
    font configure myfont -size 20
    if {[tk windowingsystem] eq "aqua"} {
	update idletasks
    } else {
	update
    }
    set h2 [font metrics myfont -linespace]
    set y2 [winfo y .f.f]
    expr {($h2 - $h1) - ($y2 - $y1)}
} -cleanup {
    deleteWindows
    font delete myfont
} -result 0







<






<
<
<
|
<



<
|
<
|
<







1123
1124
1125
1126
1127
1128
1129

1130
1131
1132
1133
1134
1135



1136

1137
1138
1139

1140

1141

1142
1143
1144
1145
1146
1147
1148
    }
    return $result
} -cleanup {
    deleteWindows
} -result {1 1 1 1 1 1 1 1 1 1 1 1}
test frame-12.3 {FrameWorldChanged procedure} -setup {
    deleteWindows

} -body {
    # Check reaction on font change
    font create myfont -family courier -size 10
    labelframe .f -font myfont -text Mupp
    place .f -x 0 -y 0 -width 40 -height 40
    pack [frame .f.f] -fill both -expand 1



    update

    set h1 [font metrics myfont -linespace]
    set y1 [winfo y .f.f]
    font configure myfont -size 20

    update  ; # services the "TheWorldHasChanged" event, queues "TkWorldChanged" events

    update  ; # services the queued "TkWorldChanged" events

    set h2 [font metrics myfont -linespace]
    set y2 [winfo y .f.f]
    expr {($h2 - $h1) - ($y2 - $y1)}
} -cleanup {
    deleteWindows
    font delete myfont
} -result 0
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
    .f configure -bd 4
    lindex [.f configure -bd] 4
} -cleanup {
    .f configure -bd [lindex [.f configure -bd] 3]
} -result 4
test frame-13.13 {labelframe configuration options} -body {
    .f configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.14 {labelframe configuration options} -body {
    .f configure -bg #00ff00
    lindex [.f configure -bg] 4
} -cleanup {
    .f configure -bg [lindex [.f configure -bg] 3]
} -result "#00ff00"
test frame-13.15 {labelframe configuration options} -body {
    .f configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.16 {labelframe configuration options} -body {
    .f configure -borderwidth 1.3
    lindex [.f configure -borderwidth] 4
} -cleanup {
    .f configure -borderwidth [lindex [.f configure -borderwidth] 3]
} -result 1
test frame-13.17 {labelframe configuration options} -body {
    .f configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.18 {labelframe configuration options} -body {
    .f configure -cursor arrow
    lindex [.f configure -cursor] 4
} -cleanup {
    .f configure -cursor [lindex [.f configure -cursor] 3]
} -result {arrow}
test frame-13.19 {labelframe configuration options} -body {







|

















|







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
    .f configure -bd 4
    lindex [.f configure -bd] 4
} -cleanup {
    .f configure -bd [lindex [.f configure -bd] 3]
} -result 4
test frame-13.13 {labelframe configuration options} -body {
    .f configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-13.14 {labelframe configuration options} -body {
    .f configure -bg #00ff00
    lindex [.f configure -bg] 4
} -cleanup {
    .f configure -bg [lindex [.f configure -bg] 3]
} -result "#00ff00"
test frame-13.15 {labelframe configuration options} -body {
    .f configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test frame-13.16 {labelframe configuration options} -body {
    .f configure -borderwidth 1.3
    lindex [.f configure -borderwidth] 4
} -cleanup {
    .f configure -borderwidth [lindex [.f configure -borderwidth] 3]
} -result 1
test frame-13.17 {labelframe configuration options} -body {
    .f configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-13.18 {labelframe configuration options} -body {
    .f configure -cursor arrow
    lindex [.f configure -cursor] 4
} -cleanup {
    .f configure -cursor [lindex [.f configure -cursor] 3]
} -result {arrow}
test frame-13.19 {labelframe configuration options} -body {
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
    .f configure -height 100
    lindex [.f configure -height] 4
} -cleanup {
    .f configure -height [lindex [.f configure -height] 3]
} -result 100
test frame-13.26 {labelframe configuration options} -body {
    .f configure -height not_a_number
} -returnCodes error -result {bad screen distance "not_a_number"}
test frame-13.27 {labelframe configuration options} -body {
    .f configure -highlightbackground #112233
    lindex [.f configure -highlightbackground] 4
} -cleanup {
    .f configure -highlightbackground [lindex [.f configure -highlightbackground] 3]
} -result "#112233"
test frame-13.28 {labelframe configuration options} -body {







|







1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
    .f configure -height 100
    lindex [.f configure -height] 4
} -cleanup {
    .f configure -height [lindex [.f configure -height] 3]
} -result 100
test frame-13.26 {labelframe configuration options} -body {
    .f configure -height not_a_number
} -returnCodes error -result {expected screen distance but got "not_a_number"}
test frame-13.27 {labelframe configuration options} -body {
    .f configure -highlightbackground #112233
    lindex [.f configure -highlightbackground] 4
} -cleanup {
    .f configure -highlightbackground [lindex [.f configure -highlightbackground] 3]
} -result "#112233"
test frame-13.28 {labelframe configuration options} -body {
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
    .f configure -highlightthickness 6
    lindex [.f configure -highlightthickness] 4
} -cleanup {
    .f configure -highlightthickness [lindex [.f configure -highlightthickness] 3]
} -result 6
test frame-13.32 {labelframe configuration options} -body {
    .f configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.33 {labelframe configuration options} -body {
    .f configure -labelanchor se
    lindex [.f configure -labelanchor] 4
} -cleanup {
    .f configure -labelanchor [lindex [.f configure -labelanchor] 3]
} -result {se}
test frame-13.34 {labelframe configuration options} -returnCodes error -body {
    .f configure -labelanchor badValue
} -result {bad labelanchor "badValue": must be e, en, es, n, ne, nw, s, se, sw, w, wn, or ws}
test frame-13.35 {labelframe configuration options} -body {
    .f configure -padx 3
    lindex [.f configure -padx] 4
} -cleanup {
    .f configure -padx [lindex [.f configure -padx] 3]
} -result 3
test frame-13.36 {labelframe configuration options} -body {
    .f configure -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.37 {labelframe configuration options} -body {
    .f configure -pady 4
    lindex [.f configure -pady] 4
} -cleanup {
    .f configure -pady [lindex [.f configure -pady] 3]
} -result 4
test frame-13.38 {labelframe configuration options} -body {
    .f configure -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test frame-13.39 {labelframe configuration options} -body {
    .f configure -relief ridge
    lindex [.f configure -relief] 4
} -cleanup {
    .f configure -relief [lindex [.f configure -relief] 3]
} -result {ridge}
test frame-13.40 {labelframe configuration options} -returnCodes error -body {







|

















|








|







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
    .f configure -highlightthickness 6
    lindex [.f configure -highlightthickness] 4
} -cleanup {
    .f configure -highlightthickness [lindex [.f configure -highlightthickness] 3]
} -result 6
test frame-13.32 {labelframe configuration options} -body {
    .f configure -highlightthickness badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-13.33 {labelframe configuration options} -body {
    .f configure -labelanchor se
    lindex [.f configure -labelanchor] 4
} -cleanup {
    .f configure -labelanchor [lindex [.f configure -labelanchor] 3]
} -result {se}
test frame-13.34 {labelframe configuration options} -returnCodes error -body {
    .f configure -labelanchor badValue
} -result {bad labelanchor "badValue": must be e, en, es, n, ne, nw, s, se, sw, w, wn, or ws}
test frame-13.35 {labelframe configuration options} -body {
    .f configure -padx 3
    lindex [.f configure -padx] 4
} -cleanup {
    .f configure -padx [lindex [.f configure -padx] 3]
} -result 3
test frame-13.36 {labelframe configuration options} -body {
    .f configure -padx badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-13.37 {labelframe configuration options} -body {
    .f configure -pady 4
    lindex [.f configure -pady] 4
} -cleanup {
    .f configure -pady [lindex [.f configure -pady] 3]
} -result 4
test frame-13.38 {labelframe configuration options} -body {
    .f configure -pady badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test frame-13.39 {labelframe configuration options} -body {
    .f configure -relief ridge
    lindex [.f configure -relief] 4
} -cleanup {
    .f configure -relief [lindex [.f configure -relief] 3]
} -result {ridge}
test frame-13.40 {labelframe configuration options} -returnCodes error -body {
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
    .f configure -width 32
    lindex [.f configure -width] 4
} -cleanup {
    .f configure -width [lindex [.f configure -width] 3]
} -result 32
test frame-13.44 {labelframe configuration options} -body {
    .f configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
destroy .f

test frame-14.1 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test that label is moved in stacking order
    label .l -text Mupp -font {helvetica 8}







|







1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
    .f configure -width 32
    lindex [.f configure -width] 4
} -cleanup {
    .f configure -width [lindex [.f configure -width] 3]
} -result 32
test frame-13.44 {labelframe configuration options} -body {
    .f configure -width badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
destroy .f

test frame-14.1 {labelframe labelwidget option} -setup {
    deleteWindows
} -body {
    # Test that label is moved in stacking order
    label .l -text Mupp -font {helvetica 8}

Changes to tests/geometry.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test the procedures in the file
# tkGeometry.c (generic support for geometry managers).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

proc getsize w {
    regexp {(^[^+-]*)} [wm geometry $w] foo x
    return $x
}







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test the procedures in the file
# tkGeometry.c (generic support for geometry managers).  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# This file is a Tcl script to test out the procedures in the file
# tkGet.c.  It is organized in the standard fashion for Tcl
# white-box tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkGet.c.  It is organized in the standard fashion for Tcl
# white-box tests.
#
# Copyright © 1998 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# Tests for the grab command.
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1998-2000 by Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Tests for the grab command.
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1998-2000 Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

Changes to tests/grid.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# This file is a Tcl script to test out the *NEW* "grid" command of Tk. It is
# (almost) organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# helper routine to return "." to a sane state after a test.
# The variable GRID_VERBOSE can be used to "look" at the result of one or all
# of the tests

proc grid_reset {{test ?} {top .}} {
    global GRID_VERBOSE
    if {[info exists GRID_VERBOSE]} {
	if {$GRID_VERBOSE eq "" || $GRID_VERBOSE eq $test} {
	    puts -nonewline "grid test $test: "
	    flush stdout
	    gets stdin
	}
    }
    eval destroy [winfo children $top]
    update
    foreach {cols rows} [grid size .] {}
    for {set i 0} {$i <= $cols} {incr i} {
	grid columnconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
    }
    for {set i 0} {$i <= $rows} {incr i} {
	grid rowconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""




|




















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# This file is a Tcl script to test out the *NEW* "grid" command of Tk. It is
# (almost) organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# helper routine to return "." to a sane state after a test.
# The variable GRID_VERBOSE can be used to "look" at the result of one or all
# of the tests

proc grid_reset {{test ?} {top .}} {
    global GRID_VERBOSE
    if {[info exists GRID_VERBOSE]} {
	if {$GRID_VERBOSE eq "" || $GRID_VERBOSE eq $test} {
	    puts -nonewline "grid test $test: "
	    flush stdout
	    gets stdin
	}
    }
    destroy {*}[winfo children $top]
    update
    foreach {cols rows} [grid size .] {}
    for {set i 0} {$i <= $cols} {incr i} {
	grid columnconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
    }
    for {set i 0} {$i <= $rows} {incr i} {
	grid rowconfigure . $i -weight 0 -minsize 0 -pad 0 -uniform ""
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    grid location .
} -returnCodes error -result {wrong # args: should be "grid location window x y"}
test grid-6.2 {location: basic argument checking} -body {
    grid location .bad 0 0
} -returnCodes error -result {bad window path name ".bad"}
test grid-6.3 {location: basic argument checking} -body {
    grid location . x y
} -returnCodes error -result {bad screen distance "x"}
test grid-6.4 {location: basic argument checking} -body {
    grid location . 1c y
} -returnCodes error -result {bad screen distance "y"}
test grid-6.5 {location: basic argument checking} -body {
    frame .f
    grid location .f 10 10
} -cleanup {
    grid_reset 6.5
} -result {-1 -1}
test grid-6.6 {location (x)} -body {







|


|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    grid location .
} -returnCodes error -result {wrong # args: should be "grid location window x y"}
test grid-6.2 {location: basic argument checking} -body {
    grid location .bad 0 0
} -returnCodes error -result {bad window path name ".bad"}
test grid-6.3 {location: basic argument checking} -body {
    grid location . x y
} -returnCodes error -result {expected screen distance but got "x"}
test grid-6.4 {location: basic argument checking} -body {
    grid location . 1c y
} -returnCodes error -result {expected screen distance but got "y"}
test grid-6.5 {location: basic argument checking} -body {
    frame .f
    grid location .f 10 10
} -cleanup {
    grid_reset 6.5
} -result {-1 -1}
test grid-6.6 {location (x)} -body {
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
	    set got $a
	}
    }
    return $result
} -cleanup {
    grid_reset 6.8
} -result {{-10->-1 -1} {0->0 0} {16->0 1} {201->1 1}}
test grid-6.9 {location: check updates pending} -constraints {
    nonPortable
} -body {
    set a ""
    foreach i {0 1 2} {
	frame .$i -width 120 -height 75 -bg red
	lappend a [grid location . 150 90]
	grid .$i -row $i -column $i
    }
    return $a







|
<
<







362
363
364
365
366
367
368
369


370
371
372
373
374
375
376
	    set got $a
	}
    }
    return $result
} -cleanup {
    grid_reset 6.8
} -result {{-10->-1 -1} {0->0 0} {16->0 1} {201->1 1}}
test grid-6.9 {location: check updates pending} -body {


    set a ""
    foreach i {0 1 2} {
	frame .$i -width 120 -height 75 -bg red
	lappend a [grid location . 150 90]
	grid .$i -row $i -column $i
    }
    return $a
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
} -cleanup {
    grid_reset 10.7
} -returnCodes error -result {bad option "-foo": must be -minsize, -pad, -uniform, or -weight}
test grid-10.8 {column/row configure} -body {
    grid columnconfigure . 0 -minsize foo
} -cleanup {
    grid_reset 10.8
} -returnCodes error -result {bad screen distance "foo"}
test grid-10.9 {column/row configure} -body {
    grid columnconfigure . 0 -minsize foo
} -cleanup {
    grid_reset 10.9
} -returnCodes error -result {bad screen distance "foo"}
test grid-10.10 {column/row configure} -body {
    grid columnconfigure . 0 -minsize 10
    grid columnconfigure . 0 -minsize
} -cleanup {
    grid_reset 10.10
} -result 10
test grid-10.11 {column/row configure} -body {







|




|







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
} -cleanup {
    grid_reset 10.7
} -returnCodes error -result {bad option "-foo": must be -minsize, -pad, -uniform, or -weight}
test grid-10.8 {column/row configure} -body {
    grid columnconfigure . 0 -minsize foo
} -cleanup {
    grid_reset 10.8
} -returnCodes error -result {expected screen distance but got "foo"}
test grid-10.9 {column/row configure} -body {
    grid columnconfigure . 0 -minsize foo
} -cleanup {
    grid_reset 10.9
} -returnCodes error -result {expected screen distance but got "foo"}
test grid-10.10 {column/row configure} -body {
    grid columnconfigure . 0 -minsize 10
    grid columnconfigure . 0 -minsize
} -cleanup {
    grid_reset 10.10
} -result 10
test grid-10.11 {column/row configure} -body {
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
} -cleanup {
    grid_reset 10.13
} -result 3
test grid-10.14 {column/row configure} -body {
    grid columnconfigure . 0 -pad foo
} -cleanup {
    grid_reset 10.14
} -returnCodes error -result {bad screen distance "foo"}
test grid-10.15 {column/row configure} -body {
    grid columnconfigure . 0 -pad -3
} -cleanup {
    grid_reset 10.15
} -returnCodes error -result {invalid arg "-pad": should be non-negative}
test grid-10.16 {column/row configure} -body {
    grid columnconfigure . 0 -pad 3







|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
} -cleanup {
    grid_reset 10.13
} -result 3
test grid-10.14 {column/row configure} -body {
    grid columnconfigure . 0 -pad foo
} -cleanup {
    grid_reset 10.14
} -returnCodes error -result {expected screen distance but got "foo"}
test grid-10.15 {column/row configure} -body {
    grid columnconfigure . 0 -pad -3
} -cleanup {
    grid_reset 10.15
} -returnCodes error -result {invalid arg "-pad": should be non-negative}
test grid-10.16 {column/row configure} -body {
    grid columnconfigure . 0 -pad 3

Changes to tests/image.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "image" command and the
# other procedures in the file tkImage.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "image" command and the
# other procedures in the file tkImage.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/imgBmap.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out images of type "bitmap" (i.e.,
# the procedures in the file tkImgBmap.c).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out images of type "bitmap" (i.e.,
# the procedures in the file tkImgBmap.c).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
    destroy .c
} -result {}


test imageBmap-5.1 {GetBitmapData procedure} -body {
    list [catch {image create bitmap -file ~bad_user/a/b} msg] \
	    [string tolower $msg]
} -result {1 {user "bad_user" doesn't exist}}
test imageBmap-5.2 {GetBitmapData procedure} -body {
    list [catch {image create bitmap -file bad_name} msg] [string tolower $msg]
} -result {1 {couldn't read bitmap file "bad_name": no such file or directory}}
test imageBmap-5.3 {GetBitmapData procedure} -setup {imageCleanup} -body {
    image create bitmap -data { }
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.4 {GetBitmapData procedure} -setup {imageCleanup} -body {







|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
    destroy .c
} -result {}


test imageBmap-5.1 {GetBitmapData procedure} -body {
    list [catch {image create bitmap -file ~bad_user/a/b} msg] \
	    [string tolower $msg]
} -result {1 {couldn't read bitmap file "~bad_user/a/b": no such file or directory}}
test imageBmap-5.2 {GetBitmapData procedure} -body {
    list [catch {image create bitmap -file bad_name} msg] [string tolower $msg]
} -result {1 {couldn't read bitmap file "bad_name": no such file or directory}}
test imageBmap-5.3 {GetBitmapData procedure} -setup {imageCleanup} -body {
    image create bitmap -data { }
} -returnCodes error -result {format error in bitmap data}
test imageBmap-5.4 {GetBitmapData procedure} -setup {imageCleanup} -body {

Changes to tests/imgPNG.test.

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 tkImgFmtPNG.c, which reads
# and write PNG-format image files for photo widgets. The files is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 1998 Willem van Schaik (images only)
# Copyright © 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv





|







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 tkImgFmtPNG.c, which reads
# and write PNG-format image files for photo widgets. The files is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
1052
1053
1054
1055
1056
1057
1058



1059
1060
1061
1062
1063
1064
1065
1066
PmSgZc0hPNhvYAruYN27V8n2gtXV8fOShnq5O9t+492kG9n2LQv65KWAaWAMUDPhEaG0oIFyOMgkhy
YOaz2HKRVHc4lqQbf3LMisUrWjrl9XhhBCkwnWnNLiFDVCParR5BeeRJE47aungOASE1gueu+OTh76
0dt3Gzx47dvzRUnHNQ8Cf2yQZE7mg+XtslqVWi5XocjlDu7K0pgS+dfbs2V8tFotPlUqlr+ZyuXNO+
duFtaSrZF3pfCpiGjN2imToJJ39m6BjG1XZRwrkAI8YUKSZWlEZQDAIrNArHnyvpXtmM/B7wJeAbwO
fBcxKuQMrzfLdBoz29fX9led5v6u1XnBJW7vnr/YlrXEoNo22LRYOYlxZ1S6rkOfDcLvPAY/hGmWC7
H68uFI+x0oSPg2MAN/L5/M/vtqSED/T5cMu9J4Wf7HMGsB/4TEv/DFwe3Y/NPN57VXh+5BWApwFLlh
r661tV1eju/ne8YJrkWtES0tmRe2VOviv2j2aBp5nHihiRaz/A4oCnsAsje/+AAAAAElFTkSuQmCC"



    }

# $encoded(basn0g08), $encoded(basn2c08), $encoded(basn3p08), $encoded(basn6a08)
test imgPNG-1.1 {reading basic images; grayscale} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $encoded(basn0g08)
    list [image width foo] [image height foo]







>
>
>
|







1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
PmSgZc0hPNhvYAruYN27V8n2gtXV8fOShnq5O9t+492kG9n2LQv65KWAaWAMUDPhEaG0oIFyOMgkhy
YOaz2HKRVHc4lqQbf3LMisUrWjrl9XhhBCkwnWnNLiFDVCParR5BeeRJE47aungOASE1gueu+OTh76
0dt3Gzx47dvzRUnHNQ8Cf2yQZE7mg+XtslqVWi5XocjlDu7K0pgS+dfbs2V8tFotPlUqlr+ZyuXNO+
duFtaSrZF3pfCpiGjN2imToJJ39m6BjG1XZRwrkAI8YUKSZWlEZQDAIrNArHnyvpXtmM/B7wJeAbwO
fBcxKuQMrzfLdBoz29fX9led5v6u1XnBJW7vnr/YlrXEoNo22LRYOYlxZ1S6rkOfDcLvPAY/hGmWC7
H68uFI+x0oSPg2MAN/L5/M/vtqSED/T5cMu9J4Wf7HMGsB/4TEv/DFwe3Y/NPN57VXh+5BWApwFLlh
r661tV1eju/ne8YJrkWtES0tmRe2VOviv2j2aBp5nHihiRaz/A4oCnsAsje/+AAAAAElFTkSuQmCC"
    dpi100aspect2
"iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAAA9hAAAewgEw8YEEAAAA
FklEQVR4nGP4+vXrP11lJgYGhj9xSQAzOwXsETZ69QAAAABJRU5ErkJggg=="
	}

# $encoded(basn0g08), $encoded(basn2c08), $encoded(basn3p08), $encoded(basn6a08)
test imgPNG-1.1 {reading basic images; grayscale} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $encoded(basn0g08)
    list [image width foo] [image height foo]
1110
1111
1112
1113
1114
1115
1116
1117






1118







































1119
1120
1121
1122
1123
1124
1125
1126
1127
    # the image contains an unknown chunk iDOT
    # since the name of this chunk starts with a lowercase letter,
    # it's an ancillary chunk that shall not trigger an error
    catch {set i [image create photo -file $fileName]}
} -cleanup {
    image delete $i
} -result 0







}







































namespace delete png
imageFinish
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









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
    # the image contains an unknown chunk iDOT
    # since the name of this chunk starts with a lowercase letter,
    # it's an ancillary chunk that shall not trigger an error
    catch {set i [image create photo -file $fileName]}
} -cleanup {
    image delete $i
} -result 0

test imgPNG-4.1 {data image with metadata} -body {
    image create photo i1 -data $encoded(dpi100aspect2)
    i1 cget -metadata
} -cleanup {
    image delete i1
} -result {DPI 99.9998 aspect 2.0}

test imgPNG-4.2 {file image with metadata} -setup {
    set path [file join [configure -tmpdir] test.png]
    set h [open $path "WRONLY BINARY CREAT"]
    puts -nonewline $h [binary decode base64 $encoded(dpi100aspect2)]
    close $h
} -body {
    image create photo i1 -file $path
    i1 cget -metadata
} -cleanup {
    image delete i1
    file delete $path
} -result {DPI 99.9998 aspect 2.0}

test imgPNG-4.3 {data output with metadata} -setup {
    image create photo i1 -data $encoded(dpi100aspect2)
} -body {
    set imgData [i1 data -format png]
    image delete i1
    image create photo i1 -data $imgData
    i1 cget -metadata
} -cleanup {
    image delete i1
} -result {DPI 99.9998 aspect 2.0}

test imgPNG-4.4 {file output with metadata} -setup {
    image create photo i1 -data $encoded(dpi100aspect2)
    set path [file join [configure -tmpdir] test.png]
} -body {
    i1 write $path -format png
    image delete i1
    image create photo i1 -file $path
    i1 cget -metadata
} -cleanup {
    image delete i1
    file delete $path
} -result {DPI 99.9998 aspect 2.0}

}

namespace delete png
imageFinish
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:

Changes to tests/imgPPM.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the code in tkImgFmtPPM.c,
# which reads and write PPM-format image files for photo widgets.
# The files is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the code in tkImgFmtPPM.c,
# which reads and write PPM-format image files for photo widgets.
# The files is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# This file is a Tcl script to test out the "photo" image type and the other
# procedures in the file tkImgPhoto.c. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1994 The Australian National University
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2002-2008 Donal K. Fellows
# All rights reserved.
#
# Author: Paul Mackerras ([email protected])

#
# This file is somewhat caothic: the order of the tests does not






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "photo" image type and the other
# procedures in the file tkImgPhoto.c. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1994 The Australian National University
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Tk_PhotoExpand:                       no tests
# Tk_PhotoGetSize:                      no tests
# Tk_PhotoSetSize:                      no tests
# TkGetPhotoValidRegion:                no tests
# ImgGetPhoto:                          no tests
# Tk_PhotoGetImage                      no tests
# ImgPostscriptPhoto                    no tests
# Tk_PhotoPutBlock_NoComposite          no tests, probably none needed
# Tk_PhotoPutZoomedBlock_NoComposite    no tests, probably none needed
# Tk_PhotoExpand_Panic                  no tests, probably none needed
# Tk_PhotoPutBlock_Panic                no tests, probably none needed
# Tk_PhotoPutZoomedBlock_Panic          no tests, probably none needed
# Tk_PhotoSetSize_Panic                 no tests, probably none needed
#--------------------------------------------------------------------------
#

#
# Some tests are not specific to a function in tkImgPhoto.c. They are:
#








|
<
<
<
<
|







47
48
49
50
51
52
53
54




55
56
57
58
59
60
61
62
# Tk_PhotoExpand:                       no tests
# Tk_PhotoGetSize:                      no tests
# Tk_PhotoSetSize:                      no tests
# TkGetPhotoValidRegion:                no tests
# ImgGetPhoto:                          no tests
# Tk_PhotoGetImage                      no tests
# ImgPostscriptPhoto                    no tests
# Tk_PhotoGetMetadata:                  imgPhoto-21.*




# Tk_PhotoSetMetadata:                  imgPhoto-22.*
#--------------------------------------------------------------------------
#

#
# Some tests are not specific to a function in tkImgPhoto.c. They are:
#

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#                       - which does not exist.
#

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

#
# Used for imgPhoto-4.65 - imgPhoto-4.73
#
proc foreachPixel {img xVar yVar script} {
    upvar 1 $xVar x $yVar y
    set width [image width $img]
    set height [image height $img]







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#                       - which does not exist.
#

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

#
# Used for imgPhoto-4.65 - imgPhoto-4.73
#
proc foreachPixel {img xVar yVar script} {
    upvar 1 $xVar x $yVar y
    set width [image width $img]
    set height [image height $img]
192
193
194
195
196
197
198



199
200
201
202
203
204
205
    image create photo photo1
} -body {
    photo1 put {{blue green}}
    photo1 get 1 0 -withalpha
} -cleanup {
    imageCleanup
} -result {0 128 0 255}




test imgPhoto-2.1 {ImgPhotoCreate procedure} -setup {
    imageCleanup
} -body {
    catch {image create photo -blah blah}
    imageNames
} -result {}







>
>
>







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    image create photo photo1
} -body {
    photo1 put {{blue green}}
    photo1 get 1 0 -withalpha
} -cleanup {
    imageCleanup
} -result {0 128 0 255}
test imgPhoto-1.14 {options for photo images - error case} -body {
    image create photo photo1 -metadata
} -returnCodes error -result {value for "-metadata" missing}

test imgPhoto-2.1 {ImgPhotoCreate procedure} -setup {
    imageCleanup
} -body {
    catch {image create photo -blah blah}
    imageNames
} -result {}
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# test imgPhoto-2.3 {ImgPhotoCreate procedure: creation failure} {
#     image create photo photo1
#     image create photo photo2 -width 10 -height 10
#     catch {image create photo photo2 -file bogus.img} msg
#     photo1 copy photo2
#     set msg
# } {couldn't open "bogus.img": no such file or directory}

test imgPhoto-3.1 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    photo1 configure -file $teapotPhotoFile
} -cleanup {
    image delete photo1







|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# test imgPhoto-2.3 {ImgPhotoCreate procedure: creation failure} {
#     image create photo photo1
#     image create photo photo2 -width 10 -height 10
#     catch {image create photo photo2 -file bogus.img} msg
#     photo1 copy photo2
#     set msg
# } {couldn't open "bogus.img": no such file or directory}

test imgPhoto-3.1 {ImgPhotoConfigureModel procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    photo1 configure -file $teapotPhotoFile
} -cleanup {
    image delete photo1
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
} -result {25 30}
test imgPhoto-4.6 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    llength [photo1 configure]
} -cleanup {
    image delete photo1
} -result 7
test imgPhoto-4.7 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    photo1 conf -palette 3/4/2
    photo1 configure -palette
} -cleanup {
    image delete photo1







|







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
} -result {25 30}
test imgPhoto-4.6 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    llength [photo1 configure]
} -cleanup {
    image delete photo1
} -result 8
test imgPhoto-4.7 {ImgPhotoCmd procedure: configure option} -setup {
    image create photo photo1
} -body {
    photo1 conf -palette 3/4/2
    photo1 configure -palette
} -cleanup {
    image delete photo1
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
    hasTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $teapotPhotoFile -zoom 2
} -returnCodes error -cleanup {
    image delete photo1
} -result {unrecognized option "-zoom": must be -format, -from, -shrink, or -to}
test imgPhoto-4.32 {ImgPhotoCmd procedure: read option} -setup {
    image create photo photo1
} -body {
    list [catch {photo1 read bogus} err] [string tolower $err]
} -cleanup {
    image delete photo1
} -result {1 {couldn't open "bogus": no such file or directory}}







|







569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
    hasTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $teapotPhotoFile -zoom 2
} -returnCodes error -cleanup {
    image delete photo1
} -result {unrecognized option "-zoom": must be -format, -from, -metadata, -shrink, or -to}
test imgPhoto-4.32 {ImgPhotoCmd procedure: read option} -setup {
    image create photo photo1
} -body {
    list [catch {photo1 read bogus} err] [string tolower $err]
} -cleanup {
    image delete photo1
} -result {1 {couldn't open "bogus": no such file or directory}}
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
test imgPhoto-4.90 {ImgPhotoCmd put: existing but not allowed opt} -setup {
    image create photo photo1
} -body {
    photo1 put yellow -from 0 0 1 1
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {unrecognized option "-from": must be -format, or -to}
test imgPhoto-4.91 {ImgPhotoCmd put: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 put {{0 1 2 3}} -bogus x
} -returnCodes error -result \
    {unrecognized option "-bogus": must be -format, or -to}
test imgPhoto-4.92 {ImgPhotocmd put: missing data} -setup {
    image create photo photo1
} -body {
    photo1 put -to 0 0
} -returnCodes error -result \
    {wrong # args: should be "photo1 put data ?-option value ...?"}
test imgPhoto-4.93 {ImgPhotoCmd put: data in ppm format} -constraints {







|





|







1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
test imgPhoto-4.90 {ImgPhotoCmd put: existing but not allowed opt} -setup {
    image create photo photo1
} -body {
    photo1 put yellow -from 0 0 1 1
} -cleanup {
    imageCleanup
} -returnCodes error -result \
    {unrecognized option "-from": must be -format, -metadata, or -to}
test imgPhoto-4.91 {ImgPhotoCmd put: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 put {{0 1 2 3}} -bogus x
} -returnCodes error -result \
    {unrecognized option "-bogus": must be -format, -metadata, or -to}
test imgPhoto-4.92 {ImgPhotocmd put: missing data} -setup {
    image create photo photo1
} -body {
    photo1 put -to 0 0
} -returnCodes error -result \
    {wrong # args: should be "photo1 put data ?-option value ...?"}
test imgPhoto-4.93 {ImgPhotoCmd put: data in ppm format} -constraints {
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
test imgPhoto-4.104 {ImgPhotoCmd data: existing but not accepted opt} -setup {
    image create photo photo1
} -body {
    photo1 data -to
} -cleanup {
    imageCleanup
} -returnCodes error -result \
{unrecognized option "-to": must be -background, -format, -from, or -grayscale}
test imgPhoto-4.105 {ImgPhotoCmd data: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 data -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
{unrecognized option "-bogus": must be -background, -format, -from, or -grayscale}
test imgPhoto-4.106 {ImgPhotoCmd data: extra arg before options} -setup {
    image create photo photo1
} -body {
    photo1 data bogus -grayscale
} -cleanup {
    imageCleanup
} -returnCodes error -result \







|







|







1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
test imgPhoto-4.104 {ImgPhotoCmd data: existing but not accepted opt} -setup {
    image create photo photo1
} -body {
    photo1 data -to
} -cleanup {
    imageCleanup
} -returnCodes error -result \
{unrecognized option "-to": must be -background, -format, -from, -grayscale, or -metadata}
test imgPhoto-4.105 {ImgPhotoCmd data: invalid option} -setup {
    image create photo photo1
} -body {
    photo1 data -bogus
} -cleanup {
    imageCleanup
} -returnCodes error -result \
{unrecognized option "-bogus": must be -background, -format, -from, -grayscale, or -metadata}
test imgPhoto-4.106 {ImgPhotoCmd data: extra arg before options} -setup {
    image create photo photo1
} -body {
    photo1 data bogus -grayscale
} -cleanup {
    imageCleanup
} -returnCodes error -result \
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
    .c delete i1.2
    photo1 configure -height 1
    update
    image delete photo1
} -cleanup {
    destroy .c
} -result {}

test imgPhoto-6.1 {ImgPhotoDisplay procedure, blank display} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {
    image create photo photo1 -width 10 -height 10
    photo1 blank
    .c create image 10 10 -image photo1
    update
} -cleanup {
    destroy .c
    image delete photo1
} -result {}

test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} -constraints {
    hasTeapotPhoto
} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {







|













|







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
    .c delete i1.2
    photo1 configure -height 1
    update
    image delete photo1
} -cleanup {
    destroy .c
} -result {}

test imgPhoto-6.1 {ImgPhotoDisplay procedure, blank display} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {
    image create photo photo1 -width 10 -height 10
    photo1 blank
    .c create image 10 10 -image photo1
    update
} -cleanup {
    destroy .c
    image delete photo1
} -result {}

test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} -constraints {
    hasTeapotPhoto
} -setup {
    destroy .c
    pack [canvas .c]
    imageCleanup
} -body {
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
    destroy .b1
    update
    .f.b2 configure -image {}
    update
    destroy .f
    image delete photo1
} -result {}

test imgPhoto-8.1 {ImgPhotoDelete procedure} -constraints hasTeapotPhoto -body {
    image create photo photo2 -file $teapotPhotoFile
    image delete photo2
} -result {}
test imgPhoto-8.2 {ImgPhotoDelete procedure} -constraints {
    hasTeapotPhoto
} -setup {







|







1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
    destroy .b1
    update
    .f.b2 configure -image {}
    update
    destroy .f
    image delete photo1
} -result {}

test imgPhoto-8.1 {ImgPhotoDelete procedure} -constraints hasTeapotPhoto -body {
    image create photo photo2 -file $teapotPhotoFile
    image delete photo2
} -result {}
test imgPhoto-8.2 {ImgPhotoDelete procedure} -constraints {
    hasTeapotPhoto
} -setup {
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
    image create photo photo1
    image create photo photo2 -width 10 -height 10
    image delete photo2
    photo1 copy photo2
} -returnCodes error -cleanup {
    imageCleanup
} -result {image "photo2" doesn't exist or is not a photo image}

test imgPhoto-9.1 {ImgPhotoCmdDeletedProc procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo2 -file $teapotPhotoFile
    rename photo2 {}
    list [expr {"photo2" in [imageNames]}] [catch {photo2 foo} msg] $msg
} -result {0 1 {invalid command name "photo2"}}

test imgPhoto-10.1 {Tk_ImgPhotoPutBlock procedure} -setup {
    imageCleanup
} -body {
    image create photo photo1
    photo1 put "{#ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000}" -to 0 0
    photo1 put "{#00ff00 #00ff00}" -to 2 0
    list [photo1 get 2 0] [photo1 get 3 0] [photo1 get 4 0]







|







|







1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
    image create photo photo1
    image create photo photo2 -width 10 -height 10
    image delete photo2
    photo1 copy photo2
} -returnCodes error -cleanup {
    imageCleanup
} -result {image "photo2" doesn't exist or is not a photo image}

test imgPhoto-9.1 {ImgPhotoCmdDeletedProc procedure} -constraints {
    hasTeapotPhoto
} -body {
    image create photo photo2 -file $teapotPhotoFile
    rename photo2 {}
    list [expr {"photo2" in [imageNames]}] [catch {photo2 foo} msg] $msg
} -result {0 1 {invalid command name "photo2"}}

test imgPhoto-10.1 {Tk_ImgPhotoPutBlock procedure} -setup {
    imageCleanup
} -body {
    image create photo photo1
    photo1 put "{#ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000 #ff0000}" -to 0 0
    photo1 put "{#00ff00 #00ff00}" -to 2 0
    list [photo1 get 2 0] [photo1 get 3 0] [photo1 get 4 0]
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
} -body {
    image create photo photo1
    photo1 copy photo1 -to 0 5 10 20
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {0 0}

test imgPhoto-11.1 {Tk_FindPhoto} -setup {
    imageCleanup
} -body {
    image create bitmap i1
    image create photo photo1
    photo1 copy i1
} -cleanup {
    imageCleanup
} -returnCodes error -result {image "i1" doesn't exist or is not a photo image}

test imgPhoto-12.1 {Tk_PhotoPutZoomedBlock} -constraints hasTeapotPhoto -body {
    image create photo p3 -file $teapotPhotoFile
    set result [list [p3 get 50 50] [p3 get 100 100]]
    p3 copy p3 -zoom 2
    lappend result [image width p3] [image height p3] [p3 get 100 100]
} -cleanup {
    image delete p3







<









|







1541
1542
1543
1544
1545
1546
1547

1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
} -body {
    image create photo photo1
    photo1 copy photo1 -to 0 5 10 20
    list [image width photo1] [image height photo1]
} -cleanup {
    imageCleanup
} -result {0 0}

test imgPhoto-11.1 {Tk_FindPhoto} -setup {
    imageCleanup
} -body {
    image create bitmap i1
    image create photo photo1
    photo1 copy i1
} -cleanup {
    imageCleanup
} -returnCodes error -result {image "i1" doesn't exist or is not a photo image}

test imgPhoto-12.1 {Tk_PhotoPutZoomedBlock} -constraints hasTeapotPhoto -body {
    image create photo p3 -file $teapotPhotoFile
    set result [list [p3 get 50 50] [p3 get 100 100]]
    p3 copy p3 -zoom 2
    lappend result [image width p3] [image height p3] [p3 get 100 100]
} -cleanup {
    image delete p3
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
} -body {
    x1 eval [list image create photo T1_data -data $data]
    x2 eval [list image create photo T1_data -data $data]
} -cleanup {
    interp delete x1
    interp delete x2
} -result T1_data

test imgPhoto-14.1 {GIF writes work correctly} -setup {
    set data {
	R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM
	hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA







|







1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
} -body {
    x1 eval [list image create photo T1_data -data $data]
    x2 eval [list image create photo T1_data -data $data]
} -cleanup {
    interp delete x1
    interp delete x2
} -result T1_data

test imgPhoto-14.1 {GIF writes work correctly} -setup {
    set data {
	R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM
	hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints {
    nonPortable
} -body {
    # This is not portable to very large machines with more than around 3GB of
    # free memory available...
    image create photo -width 32000 -height 32000
} -returnCodes error -result {not enough free memory for image buffer}

test imgPhoto-16.1 {copying to self doesn't access freed memory} -setup {
    set i [image create photo]
} -body {
    # Bug 877950 makes this crash when trying to copy out of a deallocated
    # area.
    $i put red -to 0 0 1000 1000
    $i copy $i -from 0 0 1000 1000 -to 500 0
} -cleanup {
    image delete $i
} -result {}

# Check that we can guess our supported output formats [Bug 2983824]
test imgPhoto-17.1 {photo write: format guessing from filename} -setup {
    set i [image create photo -width 3 -height 3]
} -body {
    set f [makeFile {} test.png]
    $i write $f
    set fd [open $f]







|










|







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
test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints {
    nonPortable
} -body {
    # This is not portable to very large machines with more than around 3GB of
    # free memory available...
    image create photo -width 32000 -height 32000
} -returnCodes error -result {not enough free memory for image buffer}

test imgPhoto-16.1 {copying to self doesn't access freed memory} -setup {
    set i [image create photo]
} -body {
    # Bug 877950 makes this crash when trying to copy out of a deallocated
    # area.
    $i put red -to 0 0 1000 1000
    $i copy $i -from 0 0 1000 1000 -to 500 0
} -cleanup {
    image delete $i
} -result {}

# Check that we can guess our supported output formats [Bug 2983824]
test imgPhoto-17.1 {photo write: format guessing from filename} -setup {
    set i [image create photo -width 3 -height 3]
} -body {
    set f [makeFile {} test.png]
    $i write $f
    set fd [open $f]
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
    photo1 write $f
} -cleanup {
    imageCleanup
    catch {removeFile $f}
    unset f
} -returnCodes error -result \
    {image file format "default" has no file writing capability}

test imgPhoto-18.1 {MatchFileFormat: "default" format not supported} -setup {
    image create photo photo1
    set f [makeFile {} test.txt]
} -body {
    photo1 read $f -format default
} -cleanup {
    imageCleanup







|







1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
    photo1 write $f
} -cleanup {
    imageCleanup
    catch {removeFile $f}
    unset f
} -returnCodes error -result \
    {image file format "default" has no file writing capability}

test imgPhoto-18.1 {MatchFileFormat: "default" format not supported} -setup {
    image create photo photo1
    set f [makeFile {} test.txt]
} -body {
    photo1 read $f -format default
} -cleanup {
    imageCleanup
2069
2070
2071
2072
2073
2074
2075


































































































































































































































































































































































































































































































































































































2076
2077
2078
2079
2080
2081
2082
test imgPhoto-20.12 {Valid GIF (file)} -setup {
    set fileName [file join [file dirname [info script]] red.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -result gif1



































































































































































































































































































































































































































































































































































































catch {rename foreachPixel {}}
catch {rename checkImgTrans {}}
catch {rename checkImgTransLoop {}}
imageFinish

# cleanup







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
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

# imgPhoto-21.x : Tk_PhotoGetMetadata

test imgPhoto-21.1 {option -metadata, get configure list} -setup {
    image create photo photo1 -metadata {dpi 100}
} -body {
    photo1 configure -metadata
} -cleanup {
    catch {image delete photo1}
} -result {-metadata {} {} {} {dpi 100}}

test imgPhoto-21.2 {option -metadata, get value} -setup {
    image create photo photo1 -metadata {dpi 100}
} -body {
    photo1 cget -metadata
} -cleanup {
    catch {image delete photo1}
} -result {dpi 100}

test imgPhoto-21.3 {option -metadata, get default value} -setup {
    image create photo photo1
} -body {
    photo1 cget -metadata
} -cleanup {
    catch {image delete photo1}
} -result {}

test imgPhoto-21.4 {bug daa10097: only 3 metadata list items on configure} -setup {
    image create photo photo1
} -body {
    set a {}
    foreach line [photo1 configure] {
        if {[lindex $line 0] eq {-metadata}} {
            set a $line
        }
    }
    set a
} -cleanup {
    catch {image delete photo1}
} -result {-metadata {} {} {} {}}


# imgPhoto-22.x : Tk_PhotoSetMetadata

test imgPhoto-22.1 {option -metadata, set value} -setup {
    image create photo photo1
} -body {
    photo1 configure -metadata {dpi 100}
    photo1 cget -metadata
} -cleanup {
    catch {image delete photo1}
} -result {dpi 100}

test imgPhoto-22.2 {option -metadata, change value} -setup {
    image create photo photo1 -metadata {dpi 200}
} -body {
    photo1 configure -metadata {dpi 100}
    photo1 cget -metadata
} -cleanup {
    catch {image delete photo1}
} -result {dpi 100}

test imgPhoto-22.3 {option -metadata, clear value} -setup {
    image create photo photo1 -metadata {dpi 200}
} -body {
    photo1 configure -metadata {}
    photo1 cget -metadata
} -cleanup {
    catch {image delete photo1}
} -result {}

# 23.x GIF images with metadata

# The following gif core data is used by the following data.
# N.B. this is the same image as test imgPhoto-18.10

# size 16x16, global color table size: 8
set gifstart "GIF89a\x10\x00\x10\x00\xc2\x07\x00"
# color table
append gifstart "\x00\x00\x00\x33\x33\xff\xff\x33\x33\xff\x33\xff\x33\xff\x33\x33\xff\xff\xff\xff\x33\xff\xff\xff"
# Graphic control extension: Transparent color index: 7 (not needed here)
# append gifdata "\x21\xf9\x04\x01\x0a\x00\x07\x00"
# Image descriptor: 16x16, no local color table
set gifdata "\x2c\x00\x00\x00\x00\x10\x00\x10\x00\x00"
# Image data
append gifdata "\x03\x21\x78\xba\xdc\x2d\x30\x42\x77\xa4\x15\xef\xda\xa5\xb5\xea\xd7\x07\x4a\xe2\x38\x55\xe6\x99\xaa\x6b\x69\x72\x2f\x33\x52\x1d\x65\x37\x09\x00"
set gifend "\x3b"

test imgPhoto-23.1 {GIF comment before image data (-data)} -setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {comment ABCD}

test imgPhoto-23.2 {GIF file comment before image data (-file)} -setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts -nonewline $h $data
    close $h
} -body {
    image create photo gif1 -file $path
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {comment ABCD}

test imgPhoto-23.3 {GIF comment after image data (-data)} -setup {
    set data $::gifstart
    append data $::gifdata
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {comment ABCD}

test imgPhoto-23.4 {GIF comment after image data (-file)} -setup {
    set data $::gifstart
    append data $::gifdata
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifend
    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts $h $data
    close $h
} -body {
    image create photo gif1 -file $path
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {comment ABCD}

test imgPhoto-23.5 {Two GIF comment blocks (-data)} -setup {
    set data $::gifstart
    # Append a comment extension block with data "1234"
    append data "\x21\xfe\x04" "1234" "\x0"
    append data $::gifdata
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {comment ABCD}

test imgPhoto-23.6 {Two GIF comment blocks (-file)} -setup {
    set data $::gifstart
    # Append a comment extension block with data "1234"
    append data "\x21\xfe\x04" "1234" "\x0"
    append data $::gifdata
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifend
    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts $h $data
    close $h
} -body {
    image create photo gif1 -file $path
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {comment ABCD}

test imgPhoto-23.7 {create: test if shared metadata object is not preserved\
	(-data)}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    image create photo gif1 -data $data -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.8 {create: test if shared metadata object is not preserved\
	(-file)}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend

    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts $h $data
    close $h
} -body {
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    image create photo gif1 -file $path -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.9 {configure: test if shared metadata object is not\
	preserved (empty image, -data)}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    gif1 configure -data $data -format gif -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.10 {configure: test if shared metadata object is not preserved\
	(empty image, -file)}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend

    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts $h $data
    close $h
} -body {
    image create photo gif1
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    gif1 configure -file $path -format gif -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.11 {configure: test if shared metadata object is not preserved\
	(metadata replace, -data}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data "$::gifstart$::gifdata$::gifend"
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    gif1 configure -data $data -format gif -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.12 {configure: test if shared metadata object is not preserved\
	(metadata replace, -file}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend

    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts $h $data
    close $h
} -body {
    image create photo gif1 -data "$::gifstart$::gifdata$::gifend"
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    gif1 configure -file $path -format gif -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.13 {configure: test if shared metadata object is not preserved\
	(-data)}\
-setup {
    set data $::gifstart$::gifdata$::gifend
} -body {
    image create photo gif1 -data $data
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
    gif1 configure -data $data -format gif -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.14 {configure: test if shared metadata object is not preserved\
	(-file)}\
-setup {
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend

    set path [file join [configure -tmpdir] test.gif]
    set h [open $path "WRONLY BINARY CREAT"]
    puts $h $data
    close $h
} -body {
    image create photo gif1 -data "$::gifstart$::gifdata$::gifend"
    set metadataDict [dict create A 1]
    set metadataDict2 $metadataDict
    gif1 configure -file $path -format gif -metadata $metadataDict
    list [dict get [gif1 cget -metadata]] $metadataDict $metadataDict2
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {{A 1 comment ABCD} {A 1} {A 1}}

test imgPhoto-23.15 {output data with comment (from -metadata argument)}\
-setup {
    set data $::gifstart$::gifdata$::gifend
} -body {
    image create photo gif1 -data $data
    set gifData [gif1 data -format gif -metadata [dict create comment ABCD]]
} -cleanup {
    catch {image delete gif1}
} -match glob -result {*ABCD*}

test imgPhoto-23.16 {output data with comment (from -metadata property)}\
-setup {
    set data $::gifstart$::gifdata$::gifend
} -body {
    image create photo gif1 -data $data
    gif1 configure -metadata [dict create comment ABCD]
    set gifData [gif1 data -format gif]
} -cleanup {
    catch {image delete gif1}
} -match glob -result {*ABCD*}

test imgPhoto-23.17 {output file with comment (from -metadata property)}\
-setup {
    set data $::gifstart$::gifdata$::gifend
    set path [file join [configure -tmpdir] test.gif]
} -body {
    image create photo gif1 -data $data
    gif1 configure -metadata [dict create comment ABCD]
    gif1 write $path -format gif
    image delete gif1
    image create photo gif1 -file $path
    dict get [gif1 cget -metadata] comment
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {ABCD}

test imgPhoto-23.18 {configure: empty metadata parameter overwrites image metadata} -setup {
    image create photo gif1 -data $::gifstart$::gifdata$::gifend\
	    -metadata {foo bar}
    set data $::gifstart
    # Append a comment extension block with data "ABCD"
    append data "\x21\xfe\x04" "ABCD" "\x0"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    gif1 configure -data $data -metadata {}
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {comment ABCD}

test imgPhoto-23.19 {write: empty metadata parameter overwrites image metadata} -setup {
    image create photo gif1 -data $::gifstart$::gifdata$::gifend\
	    -metadata {comment bar}
    set path [file join [configure -tmpdir] test.gif]
} -body {
    gif1 write $path -format gif -metadata {}
    image delete gif1
    image create photo gif1 -file $path
    dict size [gif1 cget -metadata]
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {0}

test imgPhoto-23.20 {data: empty metadata parameter overwrites image metadata} -setup {
    image create photo gif1 -data $::gifstart$::gifdata$::gifend\
	    -metadata {comment bar}
} -body {
    set data [gif1 data -format gif -metadata {}]
    image delete gif1
    image create photo gif1 -data $data
    dict size [gif1 cget -metadata]
} -cleanup {
    catch {image delete gif1}
    file delete $path
} -result {0}

test imgPhoto-23.21 {GIF delay time metadata} -setup {
    set data $::gifstart
    # Graphic control extension: 10 1/100s delay time
    append data "\x21\xf9\x04\x00\x0a\x00\x00\x00"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{delay time} 10}

test imgPhoto-23.22 {GIF disposal method "do not dispose" metadata} -setup {
    set data $::gifstart
    # Graphic control extension: disposdal method:
    append data "\x21\xf9\x04\x04\x00\x00\x00\x00"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{disposal method} {do not dispose}}

test imgPhoto-23.23 {GIF disposal method "restore to background color" metadata} -setup {
    set data $::gifstart
    # Graphic control extension: disposdal method:
    append data "\x21\xf9\x04\x08\x00\x00\x00\x00"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{disposal method} {restore to background color}}

test imgPhoto-23.24 {GIF disposal method "restore to previous" metadata} -setup {
    set data $::gifstart
    # Graphic control extension: disposdal method:
    append data "\x21\xf9\x04\x0C\x00\x00\x00\x00"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{disposal method} {restore to previous}}

test imgPhoto-23.25 {GIF user input flag metadata} -setup {
    set data $::gifstart
    # Graphic control extension: disposdal method:
    append data "\x21\xf9\x04\x02\x00\x00\x00\x00"
    # Trailer
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{user interaction} 1}

test imgPhoto-23.26 {GIF update region metadata} -setup {
    # size 32x32, global color table size: 8
    set data "GIF89a\x20\x00\x20\x00\xc2\x07\x00"
    # color table
    append data "\x00\x00\x00\x33\x33\xff\xff\x33\x33\xff\x33\xff\x33\xff\x33\x33\xff\xff\xff\xff\x33\xff\xff\xff"
    # Trailer
    # As this is 16x16, we will get an update region setting
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{update region} {0 0 16 16}}

test imgPhoto-23.27 {GIF multiple options metadata} -setup {
    # size 32x32, global color table size: 8
    set data "GIF89a\x20\x00\x20\x00\xc2\x07\x00"
    # color table
    append data "\x00\x00\x00\x33\x33\xff\xff\x33\x33\xff\x33\xff\x33\xff\x33\x33\xff\xff\xff\xff\x33\xff\xff\xff"
    # Graphic control extension: do not dispose, user interaction, transparent color, delay time 10
    append data "\x21\xf9\x04\x07\x0a\x00\x01\x00"
    # Image data and trailer
    # As this is 16x16, we will get an update region setting
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{update region} {0 0 16 16} {delay time} 10 {disposal method} {do not dispose} {user interaction} 1}

test imgPhoto-23.28 {GIF multiple options metadata in -index 0} -setup {
    # size 32x32, global color table size: 8
    set data "GIF89a\x20\x00\x20\x00\xc2\x07\x00"
    # color table
    append data "\x00\x00\x00\x33\x33\xff\xff\x33\x33\xff\x33\xff\x33\xff\x33\x33\xff\xff\xff\xff\x33\xff\xff\xff"
    # Graphic control extension: do not dispose, user interaction, transparent color, delay time 4096
    append data "\x21\xf9\x04\x07\x00\x10\x01\x00"
    # Image data
    # As this is 16x16, we will get an update region setting
    append data $::gifdata
    # Graphic control extension: restore to background, delay time 1
    append data "\x21\xf9\x04\x08\x01\x00\x02\x00"
    # Image data and trailer
    # As this is 16x16, we will get an update region setting
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data -format "gif -index 0"
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{update region} {0 0 16 16} {delay time} 4096 {disposal method} {do not dispose} {user interaction} 1}

test imgPhoto-23.29 {GIF multiple options metadata in -index 1} -setup {
    # size 32x32, global color table size: 8
    set data "GIF89a\x20\x00\x20\x00\xc2\x07\x00"
    # color table
    append data "\x00\x00\x00\x33\x33\xff\xff\x33\x33\xff\x33\xff\x33\xff\x33\x33\xff\xff\xff\xff\x33\xff\xff\xff"
    # Graphic control extension: restore to background, delay time 1
    append data "\x21\xf9\x04\x08\x01\x00\x02\x00"
    # Image data
    # As this is 16x16, we will get an update region setting
    append data $::gifdata
    # Graphic control extension: do not dispose, user interaction, transparent color, delay time 4096
    append data "\x21\xf9\x04\x07\x00\x10\x01\x00"
    # Image data and trailer
    # As this is 16x16, we will get an update region setting
    append data $::gifdata $::gifend
} -body {
    image create photo gif1 -data $data -format "gif -index 1"
    gif1 cget -metadata
} -cleanup {
    catch {image delete gif1}
} -result {{update region} {0 0 16 16} {delay time} 4096 {disposal method} {do not dispose} {user interaction} 1}

unset -nocomplain gifstart gifdata gifend


catch {rename foreachPixel {}}
catch {rename checkImgTrans {}}
catch {rename checkImgTransLoop {}}
imageFinish

# cleanup

Changes to tests/imgSVGnano.test.

8
9
10
11
12
13
14

15


16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34

35
36
37
38
39
40
41
package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

namespace eval svgnano {

    variable data


    set data(plus) {<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<path fill="none" stroke="#000000" d="M0 0 h16 v16 h-16 z"/>
<path fill="none" stroke="#000000" d="M8 4 v 8 M4 8 h 8"/>
<circle fill="yellow" stroke="red" cx="10" cy="80" r="10" />
<ellipse fill="none" stroke="blue" stroke-width="3" cx="60" cy="60" rx="10" ry="20" />
<line x1="10" y1="90" x2="50" y2="99"/>
<rect fill="none" stroke="green"  x="20" y="20" width="60" height="50" rx="3" ry="3"/>
<polyline fill="red" stroke="purple" points="80,10 90,20 85,40"/>
<polygon fill ="yellow" points="80,80 70,85 90,90"/>
</svg>}
    set data(bad) {<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0:w
">
</svg>}


    tcltest::makeFile $data(plus) plus.svg
    set data(plusFilePath) [file join [tcltest::configure -tmpdir] plus.svg]

    tcltest::makeFile $data(bad) bad.svg
    set data(badFilePath) [file join [tcltest::configure -tmpdir] bad.svg]


test imgSVGnano-1.1 {reading simple image} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $data(plus)
    list [image width foo] [image height foo]
} -cleanup {







>

>
>
|
|
|
|
|
|
|
|
|
|
|
<
|
>






>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

namespace eval svgnano {

    variable data

    set data(plus) {\
            <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
                <path fill="none" stroke="#000000" d="M0 0 h16 v16 h-16 z"/>
                <path fill="none" stroke="#000000" d="M8 4 v 8 M4 8 h 8"/>
                <circle fill="yellow" stroke="red" cx="10" cy="80" r="10" />
                <ellipse fill="none" stroke="blue" stroke-width="3" cx="60" cy="60" rx="10" ry="20" />
                <line x1="10" y1="90" x2="50" y2="99"/>
                <rect fill="none" stroke="green"  x="20" y="20" width="60" height="50" rx="3" ry="3"/>
                <polyline fill="red" stroke="purple" points="80,10 90,20 85,40"/>
                <polygon fill ="yellow" points="80,80 70,85 90,90"/>
                </svg>}
                set data(bad) {<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0:w">

            </svg>\
    }

    tcltest::makeFile $data(plus) plus.svg
    set data(plusFilePath) [file join [tcltest::configure -tmpdir] plus.svg]

    tcltest::makeFile $data(bad) bad.svg
    set data(badFilePath) [file join [tcltest::configure -tmpdir] bad.svg]


test imgSVGnano-1.1 {reading simple image} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -data $data(plus)
    list [image width foo] [image height foo]
} -cleanup {
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    image create photo foo -data $data(plus)
    foo configure -format {svg -scale 2}
    foo configure -format {svg -dpi 600}
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {100 100}

test imgSVGnano-1.5 {reading simple image from file} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -file $data(plusFilePath)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {100 100}

test imgSVGnano-1.6 {simple image with options} -setup {
    catch {rename foo ""}
} -body {
    image create photo foo -file $data(plusFilePath) -format {svg -dpi 100 -scale 3}
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {300 300}

test imgSVGnano-1.7 {Very small scale gives 1x1 image} -body {
    image create photo foo -format "svg -scale 0.000001"\
	    -data $data(plus)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {1 1}
test imgSVGnano-1.8 {Very small scale gives 1x1 image from file} -body {
    image create photo foo -format "svg -scale 0.000001"\
	    -file $data(plusFilePath)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {1 1}








>








<
|







>
|






|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

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 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 {
    image create photo foo -format "svg -scale 0.000001"\
	    -data $data(plus)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {1 1}
test imgSVGnano-1.8 {very small scale gives 1x1 image, from file} -body {
    image create photo foo -format "svg -scale 0.000001"\
	    -file $data(plusFilePath)
    list [image width foo] [image height foo]
} -cleanup {
    rename foo ""
} -result {1 1}

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
} -returnCodes error -result {-scaletoheight value must be positive}

test imgSVGnano-3.6 {no number parameter to -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight invalid"\
	    -data $data(plus)
} -returnCodes error -result {expected integer but got "invalid"}

test imgSVGnano-3.7 {Option -scaletowidth} -body {
    image create photo foo -format "svg -scaletowidth 20"\
	    -data $data(plus)
    image width foo
} -cleanup {
    rename foo ""
} -result 20

test imgSVGnano-3.8 {Option -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight 20"\
	    -data $data(plus)
    image height foo
} -cleanup {
    rename foo ""
} -result 20








|







|







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 {
    image create photo foo -format "svg -scaletowidth 20"\
	    -data $data(plus)
    image width foo
} -cleanup {
    rename foo ""
} -result 20

test imgSVGnano-3.8 {option -scaletoheight} -body {
    image create photo foo -format "svg -scaletoheight 20"\
	    -data $data(plus)
    image height foo
} -cleanup {
    rename foo ""
} -result 20

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
    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\"\







<









<







195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
    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 ""

} -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\"\
230
231
232
233
234
235
236













237
238
239
240
241
242
243
244
245
246
247
248
			"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\
			<svg xmlns="http://www.w3.org/2000/svg">\
			<circle cx="6.5cm" cy="2cm" r="100" transform="skewX(1 1)"/>\
			</g></svg>}
} -cleanup {
    rename foo ""
} -result {foo}














};# end of namespace svgnano

namespace delete svgnano
imageFinish
cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







>
>
>
>
>
>
>
>
>
>
>
>
>












233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
			"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}

    tcltest::removeFile plus.svg
    tcltest::removeFile bad.svg

};# 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
# This file is a Tcl script to test out the "listbox" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the "listbox" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    .l configure -bd 4
    list [lindex [.l configure -bd] 4] [.l cget -bd]
} -cleanup {
    .l configure -bd [lindex [.l configure -bd] 3]
} -result {4 4}
test listbox-1.6 {configuration options} -body {
    .l configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test listbox-1.7 {configuration options} -body {
    .l configure -bg #ff0000
    list [lindex [.l configure -bg] 4] [.l cget -bg]
} -cleanup {
    .l configure -bg [lindex [.l configure -bg] 3]
} -result {{#ff0000} #ff0000}
test listbox-1.8 {configuration options} -body {
    .l configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test listbox-1.9 {configuration options} -body {
    .l configure -borderwidth 1.3
    list [lindex [.l configure -borderwidth] 4] [.l cget -borderwidth]
} -cleanup {
    .l configure -borderwidth [lindex [.l configure -borderwidth] 3]
} -result {1 1}
test listbox-1.10 {configuration options} -body {
    .l configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test listbox-1.11 {configuration options} -body {
    .l configure -cursor arrow
    list [lindex [.l configure -cursor] 4] [.l cget -cursor]
} -cleanup {
    .l configure -cursor [lindex [.l configure -cursor] 3]
} -result {arrow arrow}
test listbox-1.12 {configuration options} -body {







|

















|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    .l configure -bd 4
    list [lindex [.l configure -bd] 4] [.l cget -bd]
} -cleanup {
    .l configure -bd [lindex [.l configure -bd] 3]
} -result {4 4}
test listbox-1.6 {configuration options} -body {
    .l configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test listbox-1.7 {configuration options} -body {
    .l configure -bg #ff0000
    list [lindex [.l configure -bg] 4] [.l cget -bg]
} -cleanup {
    .l configure -bg [lindex [.l configure -bg] 3]
} -result {{#ff0000} #ff0000}
test listbox-1.8 {configuration options} -body {
    .l configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test listbox-1.9 {configuration options} -body {
    .l configure -borderwidth 1.3
    list [lindex [.l configure -borderwidth] 4] [.l cget -borderwidth]
} -cleanup {
    .l configure -borderwidth [lindex [.l configure -borderwidth] 3]
} -result {1 1}
test listbox-1.10 {configuration options} -body {
    .l configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test listbox-1.11 {configuration options} -body {
    .l configure -cursor arrow
    list [lindex [.l configure -cursor] 4] [.l cget -cursor]
} -cleanup {
    .l configure -cursor [lindex [.l configure -cursor] 3]
} -result {arrow arrow}
test listbox-1.12 {configuration options} -body {
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    .l configure -highlightthickness 6
    list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
} -cleanup {
    .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
} -result {6 6}
test listbox-1.30 {configuration options} -body {
    .l configure -highlightthickness bogus
} -returnCodes error -result {bad screen distance "bogus"}
test listbox-1.31 {configuration options} -body {
    .l configure -highlightthickness -2
    list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
} -cleanup {
    .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
} -result {0 0}
test listbox-1.32.1 {configuration options} -setup {







|







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    .l configure -highlightthickness 6
    list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
} -cleanup {
    .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
} -result {6 6}
test listbox-1.30 {configuration options} -body {
    .l configure -highlightthickness bogus
} -returnCodes error -result {expected screen distance but got "bogus"}
test listbox-1.31 {configuration options} -body {
    .l configure -highlightthickness -2
    list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
} -cleanup {
    .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
} -result {0 0}
test listbox-1.32.1 {configuration options} -setup {
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    .l configure -selectborderwidth 1.3
    list [lindex [.l configure -selectborderwidth] 4] [.l cget -selectborderwidth]
} -cleanup {
    .l configure -selectborderwidth [lindex [.l configure -selectborderwidth] 3]
} -result {1 1}
test listbox-1.38 {configuration options} -body {
    .l configure -selectborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test listbox-1.39 {configuration options} -body {
    .l configure -selectforeground #654321
    list [lindex [.l configure -selectforeground] 4] [.l cget -selectforeground]
} -cleanup {
    .l configure -selectforeground [lindex [.l configure -selectforeground] 3]
} -result {{#654321} #654321}
test listbox-1.40 {configuration options} -body {







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    .l configure -selectborderwidth 1.3
    list [lindex [.l configure -selectborderwidth] 4] [.l cget -selectborderwidth]
} -cleanup {
    .l configure -selectborderwidth [lindex [.l configure -selectborderwidth] 3]
} -result {1 1}
test listbox-1.38 {configuration options} -body {
    .l configure -selectborderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test listbox-1.39 {configuration options} -body {
    .l configure -selectforeground #654321
    list [lindex [.l configure -selectforeground] 4] [.l cget -selectforeground]
} -cleanup {
    .l configure -selectforeground [lindex [.l configure -selectforeground] 3]
} -result {{#654321} #654321}
test listbox-1.40 {configuration options} -body {
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
    .l activate
} -returnCodes error -result {wrong # args: should be ".l activate index"}
test listbox-3.3 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate a b
} -returnCodes error -result {wrong # args: should be ".l activate index"}
test listbox-3.4 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate fooey
} -returnCodes error -result {bad listbox index "fooey": must be active, anchor, end, @x,y, or a number}
test listbox-3.5 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate 3
    .l index active
} -result 3
test listbox-3.6 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate -1
    .l index active
} -result 0
test listbox-3.7 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate 30
    .l index active
} -result 17
test listbox-3.8 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate end
    .l index active
} -result 17
test listbox-3.9 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox
} -returnCodes error -result {wrong # args: should be ".l bbox index"}
test listbox-3.10 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox a b
} -returnCodes error -result {wrong # args: should be ".l bbox index"}
test listbox-3.11 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox fooey
} -returnCodes error -result {bad listbox index "fooey": must be active, anchor, end, @x,y, or a number}
test listbox-3.12 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l yview 3
    update
    list [.l bbox 2] [.l bbox 8]
} -result {{} {}}
test listbox-3.13 {ListboxWidgetCmd procedure, "bbox" option} -cleanup {
    destroy .l2







|





|


















|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
    .l activate
} -returnCodes error -result {wrong # args: should be ".l activate index"}
test listbox-3.3 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate a b
} -returnCodes error -result {wrong # args: should be ".l activate index"}
test listbox-3.4 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate fooey
} -returnCodes error -result {bad listbox index "fooey": must be active, anchor, end, @x,y, or an index}
test listbox-3.5 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate 3
    .l index active
} -result 3
test listbox-3.6 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate {}
    .l index active
} -result 0
test listbox-3.7 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate 30
    .l index active
} -result 17
test listbox-3.8 {ListboxWidgetCmd procedure, "activate" option} -body {
    .l activate end
    .l index active
} -result 17
test listbox-3.9 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox
} -returnCodes error -result {wrong # args: should be ".l bbox index"}
test listbox-3.10 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox a b
} -returnCodes error -result {wrong # args: should be ".l bbox index"}
test listbox-3.11 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l bbox fooey
} -returnCodes error -result {bad listbox index "fooey": must be active, anchor, end, @x,y, or an index}
test listbox-3.12 {ListboxWidgetCmd procedure, "bbox" option} -body {
    .l yview 3
    update
    list [.l bbox 2] [.l bbox 8]
} -result {{} {}}
test listbox-3.13 {ListboxWidgetCmd procedure, "bbox" option} -cleanup {
    destroy .l2
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    list [.l bbox 3] [.l bbox 4]
} -result {{7 7 17 14} {7 26 17 14}}
test listbox-3.15 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview 0
    update
    list [.l bbox -1] [.l bbox 0]
} -result {{} {7 7 17 14}}
test listbox-3.16 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview end
    update
    list [.l bbox 17] [.l bbox end] [.l bbox 18]







|







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    list [.l bbox 3] [.l bbox 4]
} -result {{7 7 17 14} {7 26 17 14}}
test listbox-3.15 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview 0
    update
    list [.l bbox {}] [.l bbox 0]
} -result {{} {7 7 17 14}}
test listbox-3.16 {ListboxWidgetCmd procedure, "bbox" option} -constraints {
	fonts
} -body {
    .l yview end
    update
    list [.l bbox 17] [.l bbox end] [.l bbox 18]
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
    .l delete
} -returnCodes error -result {wrong # args: should be ".l delete firstIndex ?lastIndex?"}
test listbox-3.31 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete a b c
} -returnCodes error -result {wrong # args: should be ".l delete firstIndex ?lastIndex?"}
test listbox-3.32 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete badIndex
} -returnCodes error -result {bad listbox index "badIndex": must be active, anchor, end, @x,y, or a number}
test listbox-3.33 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete 2 123ab
} -returnCodes error -result {bad listbox index "123ab": must be active, anchor, end, @x,y, or a number}
test listbox-3.34 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 3
    list [.l2 get 2] [.l2 get 3] [.l2 index end]







|


|







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
    .l delete
} -returnCodes error -result {wrong # args: should be ".l delete firstIndex ?lastIndex?"}
test listbox-3.31 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete a b c
} -returnCodes error -result {wrong # args: should be ".l delete firstIndex ?lastIndex?"}
test listbox-3.32 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete badIndex
} -returnCodes error -result {bad listbox index "badIndex": must be active, anchor, end, @x,y, or an index}
test listbox-3.33 {ListboxWidgetCmd procedure, "delete" option} -body {
    .l delete 2 123ab
} -returnCodes error -result {bad listbox index "123ab": must be active, anchor, end, @x,y, or an index}
test listbox-3.34 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete 3
    list [.l2 get 2] [.l2 get 3] [.l2 index end]
583
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 -1 2
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el3 el4 el5 el6 el7}
test listbox-3.37 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    .l2 delete -1 -1
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {el0 el1 el2 el3 el4 el5 el6 el7}
test listbox-3.38 {ListboxWidgetCmd procedure, "delete" option} -setup {
    destroy .l2
} -body {







|









|







583
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 {} 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 {} {}
    .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 {
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
    .l get
} -returnCodes error -result {wrong # args: should be ".l get firstIndex ?lastIndex?"}
test listbox-3.43 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get a b c
} -returnCodes error -result {wrong # args: should be ".l get firstIndex ?lastIndex?"}
test listbox-3.44 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 2.4
} -returnCodes error -result {bad listbox index "2.4": must be active, anchor, end, @x,y, or a number}
test listbox-3.45 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get end bogus
} -returnCodes error -result {bad listbox index "bogus": must be active, anchor, end, @x,y, or a number}
test listbox-3.46 {ListboxWidgetCmd procedure, "get" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    list [.l2 get 0] [.l2 get 3] [.l2 get end]
} -cleanup {







|


|







646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
    .l get
} -returnCodes error -result {wrong # args: should be ".l get firstIndex ?lastIndex?"}
test listbox-3.43 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get a b c
} -returnCodes error -result {wrong # args: should be ".l get firstIndex ?lastIndex?"}
test listbox-3.44 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 2.4
} -returnCodes error -result {bad listbox index "2.4": must be active, anchor, end, @x,y, or an index}
test listbox-3.45 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get end bogus
} -returnCodes error -result {bad listbox index "bogus": must be active, anchor, end, @x,y, or an index}
test listbox-3.46 {ListboxWidgetCmd procedure, "get" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert 0 el0 el1 el2 el3 el4 el5 el6 el7
    list [.l2 get 0] [.l2 get 3] [.l2 get end]
} -cleanup {
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
    listbox .l2
    .l2 insert 0 el0 el1 el2 "two words" el4 el5 el6 el7
    .l2 get 3 end
} -cleanup {
    destroy .l2
} -result {{two words} el4 el5 el6 el7}
test listbox-3.49 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1
} -result {}
test listbox-3.50 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1 -1
} -result {}
test listbox-3.51 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get -1 3
} -result {el0 el1 el2 el3}
test listbox-3.52 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 12 end
} -result {el12 el13 el14 el15 el16 el17}
test listbox-3.53 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get 12 20
} -result {el12 el13 el14 el15 el16 el17}







|


|


|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
    listbox .l2
    .l2 insert 0 el0 el1 el2 "two words" el4 el5 el6 el7
    .l2 get 3 end
} -cleanup {
    destroy .l2
} -result {{two words} el4 el5 el6 el7}
test listbox-3.49 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get {}
} -result {}
test listbox-3.50 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get {} {}
} -result {}
test listbox-3.51 {ListboxWidgetCmd procedure, "get" option} -body {
    .l get {} 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}
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
    .l index
} -returnCodes error -result {wrong # args: should be ".l index index"}
test listbox-3.58 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index a b
} -returnCodes error -result {wrong # args: should be ".l index index"}
test listbox-3.59 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index @
} -returnCodes error -result {bad listbox index "@": must be active, anchor, end, @x,y, or a number}
test listbox-3.60 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index 2
} -result 2
test listbox-3.61 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index -1
} -result -1
test listbox-3.62 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index end
} -result 18
test listbox-3.63 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index 34
} -result 18
test listbox-3.64 {ListboxWidgetCmd procedure, "insert" option} -body {
    .l insert
} -returnCodes error -result {wrong # args: should be ".l insert index ?element ...?"}
test listbox-3.65 {ListboxWidgetCmd procedure, "insert" option} -body {
    .l insert badIndex
} -returnCodes error -result {bad listbox index "badIndex": must be active, anchor, end, @x,y, or a number}
test listbox-3.66 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c d e
    .l2 insert 3 x y z
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {a b c x y z d e}
test listbox-3.67 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c
    .l2 insert -1 x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {x a b c}
test listbox-3.68 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {







|




|
|











|















|







708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
    .l index
} -returnCodes error -result {wrong # args: should be ".l index index"}
test listbox-3.58 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index a b
} -returnCodes error -result {wrong # args: should be ".l index index"}
test listbox-3.59 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index @
} -returnCodes error -result {bad listbox index "@": must be active, anchor, end, @x,y, or an index}
test listbox-3.60 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index 2
} -result 2
test listbox-3.61 {ListboxWidgetCmd procedure, "index" option} -body {
    expr {[.l index {}]<0}
} -result 1
test listbox-3.62 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index end
} -result 18
test listbox-3.63 {ListboxWidgetCmd procedure, "index" option} -body {
    .l index 34
} -result 18
test listbox-3.64 {ListboxWidgetCmd procedure, "insert" option} -body {
    .l insert
} -returnCodes error -result {wrong # args: should be ".l insert index ?element ...?"}
test listbox-3.65 {ListboxWidgetCmd procedure, "insert" option} -body {
    .l insert badIndex
} -returnCodes error -result {bad listbox index "badIndex": must be active, anchor, end, @x,y, or an index}
test listbox-3.66 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c d e
    .l2 insert 3 x y z
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {a b c x y z d e}
test listbox-3.67 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
    listbox .l2
    .l2 insert end a b c
    .l2 insert 0 x
    .l2 get 0 end
} -cleanup {
    destroy .l2
} -result {x a b c}
test listbox-3.68 {ListboxWidgetCmd procedure, "insert" option} -setup {
    destroy .l2
} -body {
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
    update
    list [format {%.6g %.6g} {*}[.t.l xview]] [format {%.6g %.6g} {*}[.t.l yview]]
} -cleanup {
    destroy .t
} -result {{0.249364 0.427481} {0.0714286 0.428571}}
test listbox-3.79 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan foo 2 4
} -returnCodes error -result {bad option "foo": must be mark or dragto}
test listbox-3.80 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see
} -returnCodes error -result {wrong # args: should be ".l see index"}
test listbox-3.81 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see a b
} -returnCodes error -result {wrong # args: should be ".l see index"}
test listbox-3.82 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see gorp
} -returnCodes error -result {bad listbox index "gorp": must be active, anchor, end, @x,y, or a number}
test listbox-3.83 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 7
    .l index @0,0
} -result 7
test listbox-3.84 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7







|








|







812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
    update
    list [format {%.6g %.6g} {*}[.t.l xview]] [format {%.6g %.6g} {*}[.t.l yview]]
} -cleanup {
    destroy .t
} -result {{0.249364 0.427481} {0.0714286 0.428571}}
test listbox-3.79 {ListboxWidgetCmd procedure, "scan" option} -body {
    .l scan foo 2 4
} -returnCodes error -result {bad option "foo": must be dragto or mark}
test listbox-3.80 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see
} -returnCodes error -result {wrong # args: should be ".l see index"}
test listbox-3.81 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see a b
} -returnCodes error -result {wrong # args: should be ".l see index"}
test listbox-3.82 {ListboxWidgetCmd procedure, "see" option} -body {
    .l see gorp
} -returnCodes error -result {bad listbox index "gorp": must be active, anchor, end, @x,y, or an index}
test listbox-3.83 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 7
    .l index @0,0
} -result 7
test listbox-3.84 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
test listbox-3.88 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 13
    .l index @0,0
} -result 11
test listbox-3.89 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see -1
    .l index @0,0
} -result 0
test listbox-3.90 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see end
    .l index @0,0
} -result 13







|







854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
test listbox-3.88 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see 13
    .l index @0,0
} -result 11
test listbox-3.89 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see {}
    .l index @0,0
} -result 0
test listbox-3.90 {ListboxWidgetCmd procedure, "see" option} -body {
    .l yview 7
    .l see end
    .l index @0,0
} -result 13
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    .l select a
} -returnCodes error -result {wrong # args: should be ".l selection option index ?index?"}
test listbox-3.94 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l select a b c d
} -returnCodes error -result {wrong # args: should be ".l selection option index ?index?"}
test listbox-3.95 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection a bogus
} -returnCodes error -result {bad listbox index "bogus": must be active, anchor, end, @x,y, or a number}
test listbox-3.96 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection a 0 lousy
} -returnCodes error -result {bad listbox index "lousy": must be active, anchor, end, @x,y, or a number}
test listbox-3.97 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor 0 0
} -returnCodes error -result {wrong # args: should be ".l selection anchor index"}
test listbox-3.98 {ListboxWidgetCmd procedure, "selection" option} -body {
    list [.l selection anchor 5; .l index anchor] \
	    [.l selection anchor 0; .l index anchor]
} -result {5 0}
test listbox-3.99 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor -1
    .l index anchor
} -result 0
test listbox-3.100 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor end
    .l index anchor
} -result 17
test listbox-3.101 {ListboxWidgetCmd procedure, "selection" option} -body {







|


|








|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    .l select a
} -returnCodes error -result {wrong # args: should be ".l selection option index ?index?"}
test listbox-3.94 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l select a b c d
} -returnCodes error -result {wrong # args: should be ".l selection option index ?index?"}
test listbox-3.95 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection a bogus
} -returnCodes error -result {bad listbox index "bogus": must be active, anchor, end, @x,y, or an index}
test listbox-3.96 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection a 0 lousy
} -returnCodes error -result {bad listbox index "lousy": must be active, anchor, end, @x,y, or an index}
test listbox-3.97 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor 0 0
} -returnCodes error -result {wrong # args: should be ".l selection anchor index"}
test listbox-3.98 {ListboxWidgetCmd procedure, "selection" option} -body {
    list [.l selection anchor 5; .l index anchor] \
	    [.l selection anchor 0; .l index anchor]
} -result {5 0}
test listbox-3.99 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor {}
    .l index anchor
} -result 0
test listbox-3.100 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection anchor end
    .l index anchor
} -result 17
test listbox-3.101 {ListboxWidgetCmd procedure, "selection" option} -body {
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
    .l selection set 2 8
    .l selection clear 4
    list [.l selection includes 3] [.l selection includes 4] \
	    [.l selection includes 5]
} -result {1 0 1}
test listbox-3.105 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection set 0 end
    .l selection includes -1
} -result 0
test listbox-3.106 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set end
    .l selection includes end
} -result 1
test listbox-3.107 {ListboxWidgetCmd procedure, "selection" option} -body {







|







921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
    .l selection set 2 8
    .l selection clear 4
    list [.l selection includes 3] [.l selection includes 4] \
	    [.l selection includes 5]
} -result {1 0 1}
test listbox-3.105 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection set 0 end
    .l selection includes {}
} -result 0
test listbox-3.106 {ListboxWidgetCmd procedure, "selection" option} -body {
    .l selection clear 0 end
    .l selection set end
    .l selection includes end
} -result 1
test listbox-3.107 {ListboxWidgetCmd procedure, "selection" option} -body {
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
listbox .l -width 20 -height 5 -bd 4 -highlightthickness 1 -selectborderwidth 2
pack .l
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11 el12 el13 el14 \
	el15 el16 el17
update
test listbox-3.127 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l yview foo
} -returnCodes error -result {bad listbox index "foo": must be active, anchor, end, @x,y, or a number}
test listbox-3.128 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l yview foo a b
} -returnCodes error -result {unknown option "foo": must be moveto or scroll}
test listbox-3.129 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2







|







1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
listbox .l -width 20 -height 5 -bd 4 -highlightthickness 1 -selectborderwidth 2
pack .l
.l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11 el12 el13 el14 \
	el15 el16 el17
update
test listbox-3.127 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l yview foo
} -returnCodes error -result {bad listbox index "foo": must be active, anchor, end, @x,y, or an index}
test listbox-3.128 {ListboxWidgetCmd procedure, "xview" option} -body {
    .l yview foo a b
} -returnCodes error -result {unknown option "foo": must be moveto or scroll}
test listbox-3.129 {ListboxWidgetCmd procedure, "xview" option} -setup {
    destroy .l2
    listbox .l2 -width 10 -height 5 -font $fixed
    pack .l2
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index a
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "a": must be active, anchor, end, @x,y, or a number}
test listbox-10.5 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index end







|







1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index a
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "a": must be active, anchor, end, @x,y, or an index}
test listbox-10.5 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index end
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
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@": must be active, anchor, end, @x,y, or a number}
test listbox-10.9 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @foo
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@foo": must be active, anchor, end, @x,y, or a number}
test listbox-10.10 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1x3
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1x3": must be active, anchor, end, @x,y, or a number}
test listbox-10.11 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,": must be active, anchor, end, @x,y, or a number}
test listbox-10.12 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,foo
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,foo": must be active, anchor, end, @x,y, or a number}
test listbox-10.13 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,2x
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,2x": must be active, anchor, end, @x,y, or a number}
test listbox-10.14 {GetListboxIndex procedure} -constraints {
    fonts
} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11







|









|









|









|









|









|







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
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@": must be active, anchor, end, @x,y, or an index}
test listbox-10.9 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @foo
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@foo": must be active, anchor, end, @x,y, or an index}
test listbox-10.10 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1x3
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1x3": must be active, anchor, end, @x,y, or an index}
test listbox-10.11 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,": must be active, anchor, end, @x,y, or an index}
test listbox-10.12 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,foo
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,foo": must be active, anchor, end, @x,y, or an index}
test listbox-10.13 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index @1,2x
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "@1,2x": must be active, anchor, end, @x,y, or an index}
test listbox-10.14 {GetListboxIndex procedure} -constraints {
    fonts
} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 1xy
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "1xy": must be active, anchor, end, @x,y, or a number}
test listbox-10.16 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 3







|







2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 1xy
} -cleanup {
    destroy .l
} -returnCodes error -result {bad listbox index "1xy": must be active, anchor, end, @x,y, or an index}
test listbox-10.16 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    update
    .l index 3
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 -1
} -cleanup {
    destroy .l
} -result -1
test listbox-10.20 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l delete 0 end
    update







|


|







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
    expr {[.l index {}]<0}
} -cleanup {
    destroy .l
} -result 1
test listbox-10.20 {GetListboxIndex procedure} -setup {
    destroy .l
} -body {
    pack [listbox .l]
    .l insert 0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11
    .l delete 0 end
    update
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
} -body {
    listbox .l -height 5
    pack .l
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set x [.l index @0,0]
    .l yview -1
    update
    lappend x [.l index @0,0]
} -cleanup {
    destroy .l
} -result {3 0}
test listbox-11.2 {ChangeListboxView procedure, boundary conditions for index} -setup {
    destroy .l







|







2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
} -body {
    listbox .l -height 5
    pack .l
    .l insert 0 a b c d e f g h i j
    .l yview 3
    update
    set x [.l index @0,0]
    .l yview {}
    update
    lappend x [.l index @0,0]
} -cleanup {
    destroy .l
} -result {3 0}
test listbox-11.2 {ChangeListboxView procedure, boundary conditions for index} -setup {
    destroy .l
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
    .l select set 0 end
    .l curselection
} -result {}
test listbox-15.4 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -1 -1
    .l curselection
} -result {}
test listbox-15.5 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set -1 3
    .l curselection
} -result {0 1 2 3}
test listbox-15.6 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 2 4







|






|







2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
    .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 {} {}
    .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 {} 3
    .l curselection
} -result {0 1 2 3}
test listbox-15.6 {ListboxSelect procedure, boundary conditions for indices} -body {
    .l delete 0 end
    .l insert 0 a b c d e f
    .l select clear 0 end
    .l select set 2 4
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
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemconfigure 0
} -cleanup {
    destroy .l
} -result [list {-background background Background {} {}} \
	{-bg -background} \
	{-fg -foreground} \
	{-foreground foreground Foreground {} {}} \
	{-selectbackground selectBackground Foreground {} {}} \
	{-selectforeground selectForeground Background {} {}}]
test listbox-23.3 {ConfigureListboxItem, itemco shortcut} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemco 0 -background
} -cleanup {
    destroy .l
} -result {-background background Background {} {}}
test listbox-23.4 {ConfigureListboxItem, wrong num args} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a
    catch {.l itemco} result
    set result







|


|
|
|








|







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
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemconfigure 0
} -cleanup {
    destroy .l
} -result [list {-background {} {} {} {}} \
	{-bg -background} \
	{-fg -foreground} \
	{-foreground {} {} {} {}} \
	{-selectbackground {} {} {} {}} \
	{-selectforeground {} {} {} {}}]
test listbox-23.3 {ConfigureListboxItem, itemco shortcut} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemco 0 -background
} -cleanup {
    destroy .l
} -result {-background {} {} {} {}}
test listbox-23.4 {ConfigureListboxItem, wrong num args} -setup {
    destroy .l
} -body {
    listbox .l
    .l insert end a
    catch {.l itemco} result
    set result

Changes to tests/main.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# This file contains tests for the tkMain.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands







|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# This file contains tests for the tkMain.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1997 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

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts $f {puts [string equal \u20AC €]; exit}
	close $f
	catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
} -body {
	read $f
} -cleanup {
	close $f
	removeFile script
} -result "script {} 0\n0\n"








|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	set script [makeFile {} script]
	file delete $script
	set f [open $script w]
	fconfigure $f -encoding utf-8
	puts $f {puts [list $argv0 $argv $tcl_interactive]}
	puts $f {puts [string equal \u20AC €]; exit}
	close $f
	catch {set f [open "|[list [interpreter] -encoding iso8859-1 script]" r]}
} -body {
	read $f
} -cleanup {
	close $f
	removeFile script
} -result "script {} 0\n0\n"

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	close $f
	removeFile script
} -returnCodes ok -result {-enc utf-8 script}

test main-3.1 {Tk_ParseArgv: -help option} -constraints unix -body {
    # Run only on unix as Win32 pops up native dialog
    exec [interpreter] -help
} -returnCodes error -match glob -result {% application-specific initialization failed: Command-specific options:*}

test main-3.2 {Tk_ParseArgv: -help option} -setup {
    set maininterp [interp create]
} -body {
    $maininterp eval { set argc 1 ; set argv -help }
    load {} Tk $maininterp
} -cleanup {







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	close $f
	removeFile script
} -returnCodes ok -result {-enc utf-8 script}

test main-3.1 {Tk_ParseArgv: -help option} -constraints unix -body {
    # Run only on unix as Win32 pops up native dialog
    exec [interpreter] -help
} -returnCodes error -match glob -result {*application-specific initialization failed: Command-specific options:*}

test main-3.2 {Tk_ParseArgv: -help option} -setup {
    set maininterp [interp create]
} -body {
    $maininterp eval { set argc 1 ; set argv -help }
    load {} Tk $maininterp
} -cleanup {

Changes to tests/menu.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1995-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# find the earth.gif file for use in these tests (tests 2.*)
set earthPhotoFile [file join [file dirname [info script]] earth.gif]
testConstraint hasEarthPhoto [file exists $earthPhotoFile]



test menu-1.1 {Tk_MenuCmd procedure} -body {
    menu
} -returnCodes error -result {wrong # args: should be "menu pathName ?-option value ...?"}
test menu-1.2 {Tk_MenuCmd procedure} -body {
    menu bogus
} -returnCodes error -result {bad window path name "bogus"}




|











>
>







1
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 menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# 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

# find the earth.gif file for use in these tests (tests 2.*)
set earthPhotoFile [file join [file dirname [info script]] earth.gif]
testConstraint hasEarthPhoto [file exists $earthPhotoFile]
testConstraint pressbutton [llength [info commands pressbutton]]
testConstraint movemouse [llength [info commands movemouse]]

test menu-1.1 {Tk_MenuCmd procedure} -body {
    menu
} -returnCodes error -result {wrong # args: should be "menu pathName ?-option value ...?"}
test menu-1.2 {Tk_MenuCmd procedure} -body {
    menu bogus
} -returnCodes error -result {bad window path name "bogus"}
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

test menu-2.3 {configuration options -activeborderwidth 1.3} -body {
    .m1 configure -activeborderwidth 1.3
    .m1 cget -activeborderwidth
} -result {1.3}
test menu-2.4 {configuration options -activeborderwidth badValue} -body {
    .m1 configure -activeborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}

test menu-2.5 {configuration options -activeforeground #ff0000} -body {
    .m1 configure -activeforeground #ff0000
    .m1 cget -activeforeground
} -result {#ff0000}
test menu-2.6 {configuration options -activeforeground non-existent} -body {
    .m1 configure -activeforeground non-existent







|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

test menu-2.3 {configuration options -activeborderwidth 1.3} -body {
    .m1 configure -activeborderwidth 1.3
    .m1 cget -activeborderwidth
} -result {1.3}
test menu-2.4 {configuration options -activeborderwidth badValue} -body {
    .m1 configure -activeborderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}

test menu-2.5 {configuration options -activeforeground #ff0000} -body {
    .m1 configure -activeforeground #ff0000
    .m1 cget -activeforeground
} -result {#ff0000}
test menu-2.6 {configuration options -activeforeground non-existent} -body {
    .m1 configure -activeforeground non-existent
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

test menu-2.11 {configuration options -borderwidth 1.3} -body {
    .m1 configure -borderwidth 1.3
    .m1 cget -borderwidth
} -result {1.3}
test menu-2.12 {configuration options -borderwidth badValue} -body {
    .m1 configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}

test menu-2.13 {configuration options -cursor arrow} -body {
    .m1 configure -cursor arrow
    .m1 cget -cursor
} -result {arrow}
test menu-2.14 {configuration options -cursor badValue} -body {
    .m1 configure -cursor badValue







|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

test menu-2.11 {configuration options -borderwidth 1.3} -body {
    .m1 configure -borderwidth 1.3
    .m1 cget -borderwidth
} -result {1.3}
test menu-2.12 {configuration options -borderwidth badValue} -body {
    .m1 configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}

test menu-2.13 {configuration options -cursor arrow} -body {
    .m1 configure -cursor arrow
    .m1 cget -cursor
} -result {arrow}
test menu-2.14 {configuration options -cursor badValue} -body {
    .m1 configure -cursor badValue
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829

test menu-2.223 {entry configuration options 0 -underline 3p tearoff} -body {
    .m1 entryconfigure 0 -underline 3p
} -returnCodes error -result {unknown option "-underline"}

test menu-2.224 {entry configuration options 1 -underline 3p command} -body {
    .m1 entryconfigure 1 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

test menu-2.225 {entry configuration options 2 -underline 3p cascade} -body {
    .m1 entryconfigure 2 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

test menu-2.226 {entry configuration options 3 -underline 3p separator} -body {
    .m1 entryconfigure 3 -underline 3p
} -returnCodes error -result {unknown option "-underline"}

test menu-2.227 {entry configuration options 4 -underline 3p checkbutton} -body {
    .m1 entryconfigure 4 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

test menu-2.228 {entry configuration options 5 -underline 3p radiobutton} -body {
    .m1 entryconfigure 5 -underline 3p
} -returnCodes error -result {expected integer but got "3p"}

deleteWindows
if {[testConstraint hasEarthPhoto]} {
    image delete image1
}



test menu-3.1 {MenuWidgetCmd procedure} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 option ?arg ...?"}
test menu-3.2 {MenuWidgetCmd, Tcl_Preserve and Tcl_Release} -constraints {
	nonUnixUserInteraction
} -setup {
    destroy .m1
} -body  {
    menu .m1 -postcommand "destroy .m1"
    .m1 add command -label "menu-3.2: Hit Escape"
    .m1 post 40 40
} -cleanup {
    destroy .m1
} -returnCodes ok -result {}
test menu-3.3 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 activate index"}
test menu-3.4 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 activate "foo"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.5 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add separator
    .m1 activate 2
} -cleanup {
	destroy .m1
} -result {}
test menu-3.6 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -state disabled
    .m1 activate 1
} -cleanup {
	destroy .m1
} -result {}
test menu-3.7 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate 1
} -cleanup {
	destroy .m1
} -result {}
test menu-3.8 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 add type ?-option value ...?"}
test menu-3.9 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry type "foo": must be cascade, checkbutton, command, radiobutton, or separator}
test menu-3.10 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
	destroy .m1
} -result {}
test menu-3.11 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 cget
} -returnCodes error -result {wrong # args: should be ".m1 cget option"}
test menu-3.12 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menu-3.13 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Some string"
    .m1 cget -postcommand
} -cleanup {
	destroy .m1
} -result {Some string}
test menu-3.14 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone
} -returnCodes error -result {wrong # args: should be ".m1 clone newMenuName ?menuType?"}
test menu-3.15 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone a b c d
} -returnCodes error -result {wrong # args: should be ".m1 clone newMenuName ?menuType?"}
test menu-3.16 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1
} -cleanup {
	destroy .m1
} -result {}
test menu-3.17 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1 tearoff
} -cleanup {
	destroy .m1
} -result {}
test menu-3.18 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    llength [.m1 configure]
} -cleanup {
	destroy .m1
} -result 21
test menu-3.19 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menu-3.20 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "A random String"
} -cleanup {
	destroy .m1
} -result {}
test menu-3.21 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Another string"
    lindex [.m1 configure -postcommand] 4
} -cleanup {
	destroy .m1
} -result {Another string}
test menu-3.22 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 delete
} -returnCodes error -result {wrong # args: should be ".m1 delete first ?last?"}
test menu-3.23 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 delete foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.24 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 delete 0 "foo"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.25 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 delete 0
} -cleanup {
	destroy .m1
} -result {}
test menu-3.26 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 delete 1 0
} -cleanup {
	destroy .m1
} -result {}
test menu-3.27 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 delete 1 3
} -cleanup {
	destroy .m1
} -result {}
test menu-3.28 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 2
    .m1 delete 1 3
} -cleanup {
	destroy .m1
} -result {}
test menu-3.29 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 3
    .m1 delete 1
} -cleanup {
	destroy .m1
} -result {}
test menu-3.29+1 {MenuWidgetCmd, "delete", Bug 220950} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "bogus"
    .m1 add command -label "ok"
    .m1 delete 10 20
    .m1 entrycget last -label
} -cleanup {
    destroy .m1
} -result ok
test menu-3.30 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entrycget
} -returnCodes error -result {wrong # args: should be ".m1 entrycget index option"}
test menu-3.31 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entrycget index option foo
} -returnCodes error -result {wrong # args: should be ".m1 entrycget index option"}
test menu-3.32 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entrycget foo -label
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.33 {MenuWidgetCmd procedure, "entrycget" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
	destroy .m1
} -result {test}
test menu-3.34 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entryconfigure
} -returnCodes error -result {wrong # args: should be ".m1 entryconfigure index ?-option value ...?"}
test menu-3.35 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 entryconfigure foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.36 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    llength [.m1 entryconfigure 1]
} -cleanup {
	destroy .m1
} -result 15
test menu-3.37 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
	destroy .m1
} -result {test}
test menu-3.38 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -label "changed"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
	destroy .m1
} -result {changed}
test menu-3.39 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 index
} -returnCodes error -result {wrong # args: should be ".m1 index string"}
test menu-3.40 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 index foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.41 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test"
    .m1 add command -label "3"
    .m1 add command -label "another label"
    .m1 add command -label "end"
    .m1 add command -label "3a"
    .m1 add command -label "final entry"
    list [.m1 index "test"] [.m1 index "3"] [.m1 index "3a"] [.m1 index "end"]
} -cleanup {
	destroy .m1
} -result {1 3 5 6}
test menu-3.42 {MenuWidgetCmd procedure, "insert" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 insert
} -returnCodes error -result {wrong # args: should be ".m1 insert index type ?-option value ...?"}
test menu-3.43 {MenuWidgetCmd procedure, "insert" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 insert 1 command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
	destroy .m1
} -result {test}
test menu-3.44 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 invoke
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 invoke index"}
test menu-3.45 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 invoke foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.46 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add command -label "set foo" -command "set foo hello"
    list [.m1 invoke 1] [set foo] [unset foo]
} -cleanup {
	destroy .m1
} -returnCodes ok -result {hello hello {}}
test menu-3.47 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "On Windows, hit Escape to get this menu to go away"
    .m1 post
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 post x y ?index?"}
test menu-3.48 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 post foo 40
} -cleanup {
	destroy .m1
} -returnCodes error -result {expected integer but got "foo"}
test menu-3.49 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 post 40 bar
} -cleanup {
	destroy .m1
} -returnCodes error -result {expected integer but got "bar"}
test menu-3.50 {MenuWidgetCmd procedure, "post" option} -constraints {
	nonUnixUserInteraction
} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.50: hit Escape" -command "puts hello"
    .m1 post 40 40
} -cleanup {
	destroy .m1
} -result {}
test menu-3.51 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 postcascade
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 postcascade index"}
test menu-3.52 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 postcascade foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.53 {MenuWidgetCmd procedure, "postcascade" option} -constraints {
	nonUnixUserInteraction
} -setup {
	destroy .m1 .m2
} -body {
    menu .m1
    .m1 add command -label "menu-3.53 - hit Escape"
    menu .m2
    .m1 post 40 40
    .m1 add cascade -menu .m2
    .m1 postcascade 1
} -cleanup {
	destroy .m1 .m2
} -result {}
test menu-3.54 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1 .m2
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2 -label "menu-3.57 - hit Escape"
    .m1 postcascade 1
    .m1 postcascade none
} -cleanup {
	destroy .m1 .m2
} -result {}
test menu-3.55 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 type
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 type index"}
test menu-3.56 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 type foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.57 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {command}
test menu-3.58 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add separator
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {separator}
test menu-3.59 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {checkbutton}
test menu-3.60 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {radiobutton}
test menu-3.61 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
} -result {cascade}
test menu-3.62 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 type 0
} -cleanup {
	destroy .m1
} -result {tearoff}
test menu-3.63 {MenuWidgetCmd procedure, "unpost" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 unpost foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 unpost"}
test menu-3.64 {MenuWidgetCmd procedure, "unpost" option} -constraints {
	nonUnixUserInteraction
} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.64 - hit Escape"
    .m1 post 40 40
    .m1 unpost
} -cleanup {
	destroy .m1
} -result {}
test menu-3.65 {MenuWidgetCmd procedure, "yposition" option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 yposition
} -cleanup {
	destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 yposition index"}
test menu-3.66a {MenuWidgetCmd procedure, "yposition" option, no tearoff} -setup {
	destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 yposition 1
} -cleanup {
	destroy .m1
} -result 0
test menu-3.66b {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    notAqua
} -setup {
	destroy .m1
} -body {
    # on Win or Linux, tearoff menus are supported
    # see menu-3.66c for aqua
    menu .m1 -tearoff 1
    .m1 yposition 1
} -cleanup {
	destroy .m1
} -result 1
test menu-3.66c {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    aqua
} -setup {
	destroy .m1
} -body {
    # on OS X, tearoff menus are not supported
    # see menu-3.66b for win or linux
    menu .m1 -tearoff 1
    .m1 yposition 1
} -cleanup {
	destroy .m1
} -result 0
test menu-3.67 {MenuWidgetCmd procedure, bad option} -setup {
	destroy .m1
} -body {
    menu .m1
    .m1 foo
} -cleanup {
	destroy .m1
} -returnCodes error -result {bad option "foo": must be activate, add, cget, clone, configure, delete, entrycget, entryconfigure, index, insert, invoke, post, postcascade, type, unpost, xposition, or yposition}
test menu-3.68 {MenuWidgetCmd procedure, fix for bug#508988} -setup {
    deleteWindows
} -body {
    set t .t
    set m1 .t.m1
    set c1 .t.c1
    set c2 .t.c2







|



|







|



|














|


|










|





|


|





|






|


|






|


|





|


|




|


|




|


|




|
|

|





|





|





|


|





|





|




|


|




|


|




|


|





|




|


|





|


|





|





|





|




|


|





|


|







|


|








|


|








|













|





|





|





|





|


|





|





|





|


|





|


|






|


|





|





|










|


|





|





|


|




|


|




|


|






|


|





|


|




|


|




|


|

|





|


|




|


|




|


|

|








|


|





|

|


|




|


|




|


|





|


|





|


|





|


|





|


|





|


|




|


|




|


|

|






|


|




|


|




|




|






|




|






|


|




|
|







1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831

test menu-2.223 {entry configuration options 0 -underline 3p tearoff} -body {
    .m1 entryconfigure 0 -underline 3p
} -returnCodes error -result {unknown option "-underline"}

test menu-2.224 {entry configuration options 1 -underline 3p command} -body {
    .m1 entryconfigure 1 -underline 3p
} -returnCodes error -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}

test menu-2.225 {entry configuration options 2 -underline 3p cascade} -body {
    .m1 entryconfigure 2 -underline 3p
} -returnCodes error -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}

test menu-2.226 {entry configuration options 3 -underline 3p separator} -body {
    .m1 entryconfigure 3 -underline 3p
} -returnCodes error -result {unknown option "-underline"}

test menu-2.227 {entry configuration options 4 -underline 3p checkbutton} -body {
    .m1 entryconfigure 4 -underline 3p
} -returnCodes error -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}

test menu-2.228 {entry configuration options 5 -underline 3p radiobutton} -body {
    .m1 entryconfigure 5 -underline 3p
} -returnCodes error -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}

deleteWindows
if {[testConstraint hasEarthPhoto]} {
    image delete image1
}



test menu-3.1 {MenuWidgetCmd procedure} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 option ?arg ...?"}
test menu-3.2 {MenuWidgetCmd, Tcl_Preserve and Tcl_Release} -constraints {
    nonUnixUserInteraction
} -setup {
    destroy .m1
} -body  {
    menu .m1 -postcommand "destroy .m1"
    .m1 add command -label "menu-3.2: Hit Escape"
    .m1 post 40 40
} -cleanup {
    destroy .m1
} -returnCodes ok -result {}
test menu-3.3 {MenuWidgetCmd procedure, "activate" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 activate index"}
test menu-3.4 {MenuWidgetCmd procedure, "activate" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 activate "foo"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.5 {MenuWidgetCmd procedure, "activate" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add separator
    .m1 activate 2
} -cleanup {
    destroy .m1
} -result {}
test menu-3.6 {MenuWidgetCmd procedure, "activate" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -state disabled
    .m1 activate 1
} -cleanup {
    destroy .m1
} -result {}
test menu-3.7 {MenuWidgetCmd procedure, "activate" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate 1
} -cleanup {
    destroy .m1
} -result {}
test menu-3.8 {MenuWidgetCmd procedure, "add" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 add type ?-option value ...?"}
test menu-3.9 {MenuWidgetCmd procedure, "add" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add foo
} -cleanup {
    destroy .m1
} -returnCodes error -result {bad menu entry type "foo": must be cascade, checkbutton, command, radiobutton, or separator}
test menu-3.10 {MenuWidgetCmd procedure, "add" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
    destroy .m1
} -result {e001}
test menu-3.11 {MenuWidgetCmd procedure, "cget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 cget
} -returnCodes error -result {wrong # args: should be ".m1 cget option"}
test menu-3.12 {MenuWidgetCmd procedure, "cget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 cget -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menu-3.13 {MenuWidgetCmd procedure, "cget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Some string"
    .m1 cget -postcommand
} -cleanup {
    destroy .m1
} -result {Some string}
test menu-3.14 {MenuWidgetCmd procedure, "clone" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 clone
} -returnCodes error -result {wrong # args: should be ".m1 clone newMenuName ?menuType?"}
test menu-3.15 {MenuWidgetCmd procedure, "clone" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 clone a b c d
} -returnCodes error -result {wrong # args: should be ".m1 clone newMenuName ?menuType?"}
test menu-3.16 {MenuWidgetCmd procedure, "clone" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1
} -cleanup {
    destroy .m1
} -result {}
test menu-3.17 {MenuWidgetCmd procedure, "clone" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1 tearoff
} -cleanup {
    destroy .m1
} -result {}
test menu-3.18 {MenuWidgetCmd procedure, "configure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    llength [.m1 configure]
} -cleanup {
    destroy .m1
} -result 21
test menu-3.19 {MenuWidgetCmd procedure, "configure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 configure -gorp
} -returnCodes error -result {unknown option "-gorp"}
test menu-3.20 {MenuWidgetCmd procedure, "configure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "A random String"
} -cleanup {
    destroy .m1
} -result {}
test menu-3.21 {MenuWidgetCmd procedure, "configure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Another string"
    lindex [.m1 configure -postcommand] 4
} -cleanup {
    destroy .m1
} -result {Another string}
test menu-3.22 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 delete
} -returnCodes error -result {wrong # args: should be ".m1 delete first ?last?"}
test menu-3.23 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 delete foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.24 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 delete 0 "foo"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.25 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 delete 0
} -cleanup {
    destroy .m1
} -result {}
test menu-3.26 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 delete 1 0
} -cleanup {
    destroy .m1
} -result {}
test menu-3.27 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 delete 1 3
} -cleanup {
    destroy .m1
} -result {}
test menu-3.28 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 2
    .m1 delete 1 3
} -cleanup {
    destroy .m1
} -result {}
test menu-3.29 {MenuWidgetCmd procedure, "delete" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "1"
    .m1 add command -label "2"
    .m1 add command -label "3"
    .m1 activate 3
    .m1 delete 1
} -cleanup {
    destroy .m1
} -result {}
test menu-3.29+1 {MenuWidgetCmd, "delete", Bug 220950} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "bogus"
    .m1 add command -label "ok"
    .m1 delete 10 20
    .m1 entrycget last -label
} -cleanup {
    destroy .m1
} -result ok
test menu-3.30 {MenuWidgetCmd procedure, "entrycget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 entrycget
} -returnCodes error -result {wrong # args: should be ".m1 entrycget index option"}
test menu-3.31 {MenuWidgetCmd procedure, "entrycget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 entrycget index option foo
} -returnCodes error -result {wrong # args: should be ".m1 entrycget index option"}
test menu-3.32 {MenuWidgetCmd procedure, "entrycget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 entrycget foo -label
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.33 {MenuWidgetCmd procedure, "entrycget" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
    destroy .m1
} -result {test}
test menu-3.34 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 entryconfigure
} -returnCodes error -result {wrong # args: should be ".m1 entryconfigure index ?-option value ...?"}
test menu-3.35 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 entryconfigure foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.36 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    llength [.m1 entryconfigure 1]
} -cleanup {
    destroy .m1
} -result 15
test menu-3.37 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
    destroy .m1
} -result {test}
test menu-3.38 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -label "changed"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
    destroy .m1
} -result {changed}
test menu-3.39 {MenuWidgetCmd procedure, "index" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 index
} -returnCodes error -result {wrong # args: should be ".m1 index string"}
test menu-3.40 {MenuWidgetCmd procedure, "index" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 index foo
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.41 {MenuWidgetCmd procedure, "index" option} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test"
    .m1 add command -label "3"
    .m1 add command -label "another label"
    .m1 add command -label "end"
    .m1 add command -label "3a"
    .m1 add command -label "final entry"
    list [.m1 index "test"] [.m1 index "3"] [.m1 index "3a"] [.m1 index "end"]
} -cleanup {
    destroy .m1
} -result {1 3 5 6}
test menu-3.42 {MenuWidgetCmd procedure, "insert" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 insert
} -returnCodes error -result {wrong # args: should be ".m1 insert index type ?-option value ...?"}
test menu-3.43 {MenuWidgetCmd procedure, "insert" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 insert 1 command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
    destroy .m1
} -result {test}
test menu-3.44 {MenuWidgetCmd procedure, "invoke" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 invoke
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 invoke index"}
test menu-3.45 {MenuWidgetCmd procedure, "invoke" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 invoke foo
} -cleanup {
    destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.46 {MenuWidgetCmd procedure, "invoke" option} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add command -label "set foo" -command "set foo hello"
    list [.m1 invoke 1] [set foo] [unset foo]
} -cleanup {
    destroy .m1
} -returnCodes ok -result {hello hello {}}
test menu-3.47 {MenuWidgetCmd procedure, "post" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "On Windows, hit Escape to get this menu to go away"
    .m1 post
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 post x y ?index?"}
test menu-3.48 {MenuWidgetCmd procedure, "post" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 post foo 40
} -cleanup {
    destroy .m1
} -returnCodes error -result {expected integer but got "foo"}
test menu-3.49 {MenuWidgetCmd procedure, "post" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 post 40 bar
} -cleanup {
    destroy .m1
} -returnCodes error -result {expected integer but got "bar"}
test menu-3.50 {MenuWidgetCmd procedure, "post" option} -constraints {
    nonUnixUserInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.50: hit Escape" -command "puts hello"
    .m1 post 40 40
} -cleanup {
    destroy .m1
} -result {}
test menu-3.51 {MenuWidgetCmd procedure, "postcascade" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 postcascade
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 postcascade index"}
test menu-3.52 {MenuWidgetCmd procedure, "postcascade" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 postcascade foo
} -cleanup {
    destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.53 {MenuWidgetCmd procedure, "postcascade" option} -constraints {
    nonUnixUserInteraction
} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    .m1 add command -label "menu-3.53 - hit Escape"
    menu .m2
    .m1 post 40 40
    .m1 add cascade -menu .m2
    .m1 postcascade 1
} -cleanup {
    destroy .m1 .m2
} -result {}
test menu-3.54 {MenuWidgetCmd procedure, "postcascade" option} -setup {
    destroy .m1 .m2
} -body {
    menu .m1
    menu .m2
    .m1 add cascade -menu .m2 -label "menu-3.57 - hit Escape"
    .m1 postcascade 1
    .m1 postcascade {}
} -cleanup {
    destroy .m1 .m2
} -result {}
test menu-3.55 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 type
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 type index"}
test menu-3.56 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 type foo
} -cleanup {
    destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.57 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 type 1
} -cleanup {
    destroy .m1
} -result {command}
test menu-3.58 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    .m1 type 1
} -cleanup {
    destroy .m1
} -result {separator}
test menu-3.59 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label "test"
    .m1 type 1
} -cleanup {
    destroy .m1
} -result {checkbutton}
test menu-3.60 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
    .m1 type 1
} -cleanup {
    destroy .m1
} -result {radiobutton}
test menu-3.61 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test"
    .m1 type 1
} -cleanup {
    destroy .m1
} -result {cascade}
test menu-3.62 {MenuWidgetCmd procedure, "type" option} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 type 0
} -cleanup {
    destroy .m1
} -result {tearoff}
test menu-3.63 {MenuWidgetCmd procedure, "unpost" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 unpost foo
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 unpost"}
test menu-3.64 {MenuWidgetCmd procedure, "unpost" option} -constraints {
    nonUnixUserInteraction
} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.64 - hit Escape"
    .m1 post 40 40
    .m1 unpost
} -cleanup {
    destroy .m1
} -result {}
test menu-3.65 {MenuWidgetCmd procedure, "yposition" option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 yposition
} -cleanup {
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 yposition index"}
test menu-3.66a {MenuWidgetCmd procedure, "yposition" option, no tearoff} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 yposition 1
} -cleanup {
    destroy .m1
} -result 0
test menu-3.66b {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    notAqua
} -setup {
    destroy .m1
} -body {
    # on Win or Linux, tearoff menus are supported
    # see menu-3.66c for aqua
    menu .m1 -tearoff 1
    .m1 yposition 1
} -cleanup {
    destroy .m1
} -result 1
test menu-3.66c {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    aqua
} -setup {
    destroy .m1
} -body {
    # on OS X, tearoff menus are not supported
    # see menu-3.66b for win or linux
    menu .m1 -tearoff 1
    .m1 yposition 1
} -cleanup {
    destroy .m1
} -result 0
test menu-3.67 {MenuWidgetCmd procedure, bad option} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 foo
} -cleanup {
    destroy .m1
} -returnCodes error -result {bad option "foo": must be activate, add, cget, clone, configure, delete, entrycget, entryconfigure, id, index, insert, invoke, post, postcascade, type, unpost, xposition, or yposition}
test menu-3.68 {MenuWidgetCmd procedure, fix for bug#508988} -setup {
    deleteWindows
} -body {
    set t .t
    set m1 .t.m1
    set c1 .t.c1
    set c2 .t.c2
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
} -cleanup {
    destroy .m1
} -result {}
test menu-3.71 {MenuWidgetCmd procedure, "index end" option, bug [f3cd942e9e]} -setup {
    destroy .m1
} -body {
    menu .m1
    list [.m1 index "end"]
} -cleanup {
    destroy .m1
} -result none


test menu-4.1 {TkInvokeMenu: disabled} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off \
	-state disabled
    list [catch {.m1 invoke 1} msg] $foo
} -cleanup {
    destroy .m1
} -result {0 off}
test menu-4.2 {TkInvokeMenu: tearoff} -setup {
    destroy .m1
} -body {
    menu .m1
	catch {.m1 invoke 0}
} -cleanup {
    deleteWindows
} -result 0
test menu-4.3 {TkInvokeMenu: checkbutton -on} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 \
		[catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 on 0 {}}
test menu-4.4 {TkInvokeMenu: checkbutton -off} -setup {
    destroy .m1
} -body {
    catch {unset foo}







|


|








|








|










|







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
} -cleanup {
    destroy .m1
} -result {}
test menu-3.71 {MenuWidgetCmd procedure, "index end" option, bug [f3cd942e9e]} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 index "end"
} -cleanup {
    destroy .m1
} -result {}


test menu-4.1 {TkInvokeMenu: disabled} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off \
    -state disabled
    list [catch {.m1 invoke 1} msg] $foo
} -cleanup {
    destroy .m1
} -result {0 off}
test menu-4.2 {TkInvokeMenu: tearoff} -setup {
    destroy .m1
} -body {
    menu .m1
    catch {.m1 invoke 0}
} -cleanup {
    deleteWindows
} -result 0
test menu-4.3 {TkInvokeMenu: checkbutton -on} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo -onvalue on -offvalue off
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 \
            [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 on 0 {}}
test menu-4.4 {TkInvokeMenu: checkbutton -off} -setup {
    destroy .m1
} -body {
    catch {unset foo}
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
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo(1) -onvalue on
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo(1)} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 on 0 {}}
test menu-4.6 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -tearoff 1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 one 0 {}}
test menu-4.7 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -tearoff 1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 2} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 two 0 {}}
test menu-4.8 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 three 0 {}}
test menu-4.9 {TkInvokeMenu: radiobutton array element} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo(2) -value one
    .m1 add radiobutton -label "2" -variable foo(2) -value two
    .m1 add radiobutton -label "3" -variable foo(2) -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo(2)} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 {} 0 three 0 {}}
test menu-4.10 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add command -label "test" -command "set menu_test menu-4.8"
    list [catch {.m1 invoke 1} msg] $msg [catch {set menu_test} msg2] $msg2 [catch {unset menu_test} msg3] $msg3
} -cleanup {
	destroy .m1
} -result {0 menu-4.8 0 menu-4.8 0 {}}
test menu-4.11 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test" -menu .m1.m2
    list [catch {.m1 invoke 1} msg] $msg
} -cleanup {
	destroy .m1
} -result {0 {}}
test menu-4.12 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test" -command ".m1 delete 1"
    list [catch {.m1 invoke 1} msg] $msg [catch {.m1 type "test"} msg2] $msg2
} -cleanup {
	destroy .m1
} -result {0 {} 1 {bad menu entry index "test"}}

test menu-5.1 {DestroyMenuInstance} -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1







|











|











|











|











|









|








|








|







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
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add checkbutton -label "test" -variable foo(1) -onvalue on
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo(1)} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 on 0 {}}
test menu-4.6 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -tearoff 1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 one 0 {}}
test menu-4.7 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1 -tearoff 1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 2} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 two 0 {}}
test menu-4.8 {TkInvokeMenu: radiobutton} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo -value one
    .m1 add radiobutton -label "2" -variable foo -value two
    .m1 add radiobutton -label "3" -variable foo -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 three 0 {}}
test menu-4.9 {TkInvokeMenu: radiobutton array element} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add radiobutton -label "1" -variable foo(2) -value one
    .m1 add radiobutton -label "2" -variable foo(2) -value two
    .m1 add radiobutton -label "3" -variable foo(2) -value three
    list [catch {.m1 invoke 3} msg] $msg [catch {set foo(2)} msg2] $msg2 [catch {unset foo} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 {} 0 three 0 {}}
test menu-4.10 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    catch {unset foo}
    menu .m1
    .m1 add command -label "test" -command "set menu_test menu-4.8"
    list [catch {.m1 invoke 1} msg] $msg [catch {set menu_test} msg2] $msg2 [catch {unset menu_test} msg3] $msg3
} -cleanup {
    destroy .m1
} -result {0 menu-4.8 0 menu-4.8 0 {}}
test menu-4.11 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test" -menu .m1.m2
    list [catch {.m1 invoke 1} msg] $msg
} -cleanup {
    destroy .m1
} -result {0 {}}
test menu-4.12 {TkInvokeMenu} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 add command -label "test" -command ".m1 delete 1"
    list [catch {.m1 invoke 1} msg] $msg [catch {.m1 type "test"} msg2] $msg2
} -cleanup {
    destroy .m1
} -result {0 {} 1 {bad menu entry index "test"}}

test menu-5.1 {DestroyMenuInstance} -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
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
} -result {0 0}
test menu-6.9 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
	list [destroy .m2] [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {} {}}
test menu-6.10 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
	list [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.11 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
	list [destroy .m2] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.12 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
	list [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.13 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
	list [destroy .m4] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.14 {TkDestroyMenu} -setup {
	destroy .m1
} -body {
    menu .m1
    . configure -menu .m1
    list [destroy .m1] [. configure -menu ""]
} -returnCodes ok -result {{} {}}
test menu-6.15 {TkDestroyMenu} -setup {
    deleteWindows







|







|








|








|








|


|







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
} -result {0 0}
test menu-6.9 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    list [destroy .m2] [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {} {}}
test menu-6.10 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    list [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.11 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
    list [destroy .m2] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.12 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
    list [destroy .m3] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.13 {TkDestroyMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m1 clone .m3
    .m1 clone .m4
    list [destroy .m4] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.14 {TkDestroyMenu} -setup {
    destroy .m1
} -body {
    menu .m1
    . configure -menu .m1
    list [destroy .m1] [. configure -menu ""]
} -returnCodes ok -result {{} {}}
test menu-6.15 {TkDestroyMenu} -setup {
    deleteWindows
2241
2242
2243
2244
2245
2246
2247








2248
2249
2250
2251
2252
2253
2254
    toplevel .t3
    wm geometry .t3 +0+0
    . configure -menu .m1
    .t2 configure -menu .m1
    .t3 configure -menu .m1
    list [destroy .m1] [destroy .t2] [destroy .t3] [. configure -menu ""]
} -result {{} {} {} {}}









test menu-7.1 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    destroy .m1







>
>
>
>
>
>
>
>







2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
    toplevel .t3
    wm geometry .t3 +0+0
    . configure -menu .m1
    .t2 configure -menu .m1
    .t3 configure -menu .m1
    list [destroy .m1] [destroy .t2] [destroy .t3] [. configure -menu ""]
} -result {{} {} {} {}}
test menu-6.17 {TkDestroyMenu - bug 14a9b62e1d} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -command {destroy .m1}
    .m1 invoke end
    winfo exists .m1
} -result {0}

test menu-7.1 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    destroy .m1
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
test menu-11.15 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    list [.m1 add checkbutton -label "test"] [.m1 entrycget 1 -variable]
} -cleanup {
    deleteWindows
} -result {{} test}
test menu-11.16 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
} -cleanup {
    deleteWindows
} -result {}
test menu-11.17 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
    list [.m1 entryconfigure 1 -onvalue "test"] [.m1 entrycget 1 -onvalue]
} -cleanup {







|







|







2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
test menu-11.15 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    list [.m1 add checkbutton -label "test"] [.m1 entrycget 1 -variable]
} -cleanup {
    deleteWindows
} -result {e001 test}
test menu-11.16 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
} -cleanup {
    deleteWindows
} -result {e001}
test menu-11.17 {ConfigureMenuEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
    list [.m1 entryconfigure 1 -onvalue "test"] [.m1 entrycget 1 -onvalue]
} -cleanup {
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
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 insert last command -label "test2"] [.m1 entrycget last -label]
} -cleanup {
    deleteWindows
} -result {{} test2}
test menu-13.5 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 insert end command -label "test2"] [.m1 entrycget end -label]
} -cleanup {
    deleteWindows
} -result {{} test2}
test menu-13.6 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    .m1 entrycget none -label
} -cleanup {
    deleteWindows
} -result {}
#test menu-13.7 - Need to add @test here.
test menu-13.7 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {







|








|








|







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
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 insert last command -label "test2"] [.m1 entrycget last -label]
} -cleanup {
    deleteWindows
} -result {e002 test2}
test menu-13.5 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    list [.m1 insert end command -label "test2"] [.m1 entrycget end -label]
} -cleanup {
    deleteWindows
} -result {e002 test2}
test menu-13.6 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "active"
    .m1 add command -label "test2"
    .m1 add command -label "test3"
    .m1 activate 2
    .m1 entrycget {} -label
} -cleanup {
    deleteWindows
} -result {}
#test menu-13.7 - Need to add @test here.
test menu-13.7 {TkGetMenuIndex} -setup {
    deleteWindows
} -body {
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
test menu-15.1 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
} -cleanup {
    deleteWindows
} -result {}
test menu-15.2 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test3"
    .m1 insert 2 command -label "test2"
} -cleanup {
    deleteWindows
} -result {}
test menu-15.3 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
} -cleanup {
    deleteWindows
} -result {}
test menu-15.4 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
} -cleanup {
    deleteWindows
} -result {}

test menu-16.1 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 insert foo command -label "test"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-16.2 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 insert test command -label "foo"
} -cleanup {
    deleteWindows
} -result {}
test menu-16.3 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 insert -1 command -label "test"
} -returnCodes error -result {bad menu entry index "-1"}
test menu-16.4 {MenuAddOrInsert} -setup {







|









|








|







|















|







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
test menu-15.1 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
} -cleanup {
    deleteWindows
} -result {e001}
test menu-15.2 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test3"
    .m1 insert 2 command -label "test2"
} -cleanup {
    deleteWindows
} -result {e003}
test menu-15.3 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add command -label "test2"
} -cleanup {
    deleteWindows
} -result {e002}
test menu-15.4 {MenuNewEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
} -cleanup {
    deleteWindows
} -result {e001}

test menu-16.1 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 insert foo command -label "test"
} -returnCodes error -result {bad menu entry index "foo"}
test menu-16.2 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 insert test command -label "foo"
} -cleanup {
    deleteWindows
} -result {e002}
test menu-16.3 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 insert -1 command -label "test"
} -returnCodes error -result {bad menu entry index "-1"}
test menu-16.4 {MenuAddOrInsert} -setup {
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
test menu-16.5 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade
} -cleanup {
    deleteWindows
} -result {}
test menu-16.6 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
} -cleanup {
    deleteWindows
} -result {}
test menu-16.7 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {}
test menu-16.8 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton
} -cleanup {
    deleteWindows
} -result {}
test menu-16.9 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
    deleteWindows
} -result {}
test menu-16.10 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add blork
} -returnCodes error -result {bad menu entry type "blork": must be cascade, checkbutton, command, radiobutton, or separator}
test menu-16.11 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {}
test menu-16.12 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [.m2 add command -label "test"] [.m1 entrycget 1 -label] [.m3 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test test}
test menu-16.13 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [.m3 add command -label "test"] [.m1 entrycget 1 -label] [.m2 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {{} test test}
test menu-16.14 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -blork
} -returnCodes error -result {unknown option "-blork"}
test menu-16.15 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "File"
    menu .container
    . configure -menu .container
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.16 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    set tearoff [tk::TearOffMenu .m2]
    list [.m2 add cascade -menu .m1] [$tearoff unpost]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.17 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .container
    . configure -menu .container
    set tearoff [tk::TearOffMenu .container]
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.18 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .container
    .container add cascade -menu .m1
    . configure -menu .container
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-16.19 {MenuAddOrInsert - Insert a cascade deep into the tree} -setup {
    deleteWindows
} -body {
    menu .menubar
    menu .menubar.test -tearoff 0
    .menubar add cascade -label Test -underline 0 -menu .menubar.test
    menu .menubar.test.cascade -tearoff 0
    .menubar.test.cascade add command -label SubItem -command "puts SubItemSelected"
    . configure -menu .menubar
    list [catch {.menubar.test add cascade -label SubMenu \
		-menu .menubar.test.cascade}] \
		[info commands .\#menubar.\#menubar\#test.\#menubar\#test\#cascade] \
		[. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {0 .#menubar.#menubar#test.#menubar#test#cascade {}}


test menu-17.1 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[unset foo]
} -cleanup {
    deleteWindows
} -result {{} {}}
# menu-17.2 - Don't know how to generate the flags in the if
test menu-17.2 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-17.3 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo "hello"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} hello {}}
test menu-17.4 {MenuVarProc} -setup {
    deleteWindows
} -body {
    menu .m1
    set foo "goodbye"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo "hello"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} hello {}}
test menu-17.5 {MenuVarProc} -setup {
    deleteWindows
} -body {
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
		[set foo "goodbye"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} goodbye {}}
test menu-17.6 {MenuVarProc [5d991b822e]} -setup {
    deleteWindows
} -body {
    # Want this not to crash
    menu .b
    set var INIT
    .b add checkbutton -variable var







|







|







|







|







|













|









|









|




|











|









|










|










|










|
|
|












|


|







|


|







|


|






|


|






|


|







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
test menu-16.5 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add cascade
} -cleanup {
    deleteWindows
} -result {e001}
test menu-16.6 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add checkbutton
} -cleanup {
    deleteWindows
} -result {e001}
test menu-16.7 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {e001}
test menu-16.8 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton
} -cleanup {
    deleteWindows
} -result {e001}
test menu-16.9 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
    deleteWindows
} -result {e001}
test menu-16.10 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add blork
} -returnCodes error -result {bad menu entry type "blork": must be cascade, checkbutton, command, radiobutton, or separator}
test menu-16.11 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {e001}
test menu-16.12 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [.m2 add command -label "test"] [.m1 entrycget 1 -label] [.m3 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {e001 test test}
test menu-16.13 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
    .m2 clone .m3
    list [.m3 add command -label "test"] [.m1 entrycget 1 -label] [.m2 entrycget 1 -label]
} -cleanup {
    deleteWindows
} -result {e001 test test}
test menu-16.14 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -blork fish
} -returnCodes error -result {unknown option "-blork"}
test menu-16.15 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "File"
    menu .container
    . configure -menu .container
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {e001 {}}
test menu-16.16 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    set tearoff [tk::TearOffMenu .m2]
    list [.m2 add cascade -menu .m1] [$tearoff unpost]
} -cleanup {
    deleteWindows
} -result {e001 {}}
test menu-16.17 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .container
    . configure -menu .container
    set tearoff [tk::TearOffMenu .container]
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {e001 {}}
test menu-16.18 {MenuAddOrInsert} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .container
    .container add cascade -menu .m1
    . configure -menu .container
    list [.container add cascade -label "File" -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {e002 {}}
test menu-16.19 {MenuAddOrInsert - Insert a cascade deep into the tree} -setup {
    deleteWindows
} -body {
    menu .menubar
    menu .menubar.test -tearoff 0
    .menubar add cascade -label Test -underline 0 -menu .menubar.test
    menu .menubar.test.cascade -tearoff 0
    .menubar.test.cascade add command -label SubItem -command "puts SubItemSelected"
    . configure -menu .menubar
    list [catch {.menubar.test add cascade -label SubMenu \
            -menu .menubar.test.cascade}] \
            [info commands .\#menubar.\#menubar\#test.\#menubar\#test\#cascade] \
            [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {0 .#menubar.#menubar#test.#menubar#test#cascade {}}


test menu-17.1 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
            [unset foo]
} -cleanup {
    deleteWindows
} -result {e001 {}}
# menu-17.2 - Don't know how to generate the flags in the if
test menu-17.2 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
            [set foo ""]
} -cleanup {
    deleteWindows
} -result {e001 {}}
test menu-17.3 {MenuVarProc} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
            [set foo "hello"] [unset foo]
} -cleanup {
    deleteWindows
} -result {e001 hello {}}
test menu-17.4 {MenuVarProc} -setup {
    deleteWindows
} -body {
    menu .m1
    set foo "goodbye"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
            [set foo "hello"] [unset foo]
} -cleanup {
    deleteWindows
} -result {e001 hello {}}
test menu-17.5 {MenuVarProc} -setup {
    deleteWindows
} -body {
    menu .m1
    set foo "hello"
    list [.m1 add checkbutton -variable foo -onvalue hello -offvalue goodbye] \
            [set foo "goodbye"] [unset foo]
} -cleanup {
    deleteWindows
} -result {e001 goodbye {}}
test menu-17.6 {MenuVarProc [5d991b822e]} -setup {
    deleteWindows
} -body {
    # Want this not to crash
    menu .b
    set var INIT
    .b add checkbutton -variable var
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
    deleteWindows
} -result {}
test menu-20.5 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 foo
} -returnCodes error -result {bad menu type "foo": must be normal, tearoff, or menubar}
test menu-20.6 {CloneMenu - hooking up bookeeping ptrs} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
} -cleanup {
    deleteWindows







|







3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
    deleteWindows
} -result {}
test menu-20.5 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2 foo
} -returnCodes error -result {bad menu type "foo": must be menubar, normal, or tearoff}
test menu-20.6 {CloneMenu - hooking up bookeeping ptrs} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
} -cleanup {
    deleteWindows
3353
3354
3355
3356
3357
3358
3359




















































3360
3361
3362
3363
3364
3365
3366
test menu-20.11 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 clone .m2
} -returnCodes error -result {window name "m2" already exists in parent}





















































test menu-21.1 {MenuDoYPosition} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 yposition glorp
} -returnCodes error -result {bad menu entry index "glorp"}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
test menu-20.11 {CloneMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    menu .m2
    .m1 clone .m2
} -returnCodes error -result {window name "m2" already exists in parent}
test menu-20.12 {CloneMenu - copied bindings on empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 0
    bind .m1 <<Test>> {append x <<Test>>}
    .m1 clone .m2 tearoff
    .m2 post 100 100
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.13 {CloneMenu - copied bindings on non-empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 1
    bind .m1 <<Test>> {append x <<Test>>}
    .m1 clone .m2 tearoff
    .m2 post 100 100
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.14 {CloneMenu - new binding on empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 0
    .m1 clone .m2 tearoff
    .m2 post 100 100
    bind .m1 <<Test>> {append x <<Test>>}
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.15 {CloneMenu - new binding on non-empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 1
    .m1 clone .m2 tearoff
    .m2 post 100 100
    bind .m1 <<Test>> {append x <<Test>>}
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.16 {CloneMenu - bindtags} -setup {
    deleteWindows
} -body {
    menu .m1
    bindtags .m1 [linsert [bindtags .m1] 1 .m1.sub1]
    .m1 clone .m2
    bindtags .m2
} -result {.m2 .m1 .m1.sub1 Menu all}

test menu-21.1 {MenuDoYPosition} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 yposition glorp
} -returnCodes error -result {bad menu entry index "glorp"}
3431
3432
3433
3434
3435
3436
3437


































































3438
3439
3440
3441
3442
3443
3444
    wm geometry .m1 200x100
    update
    set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
    .m1 index @$x,5
} -cleanup {
    deleteWindows
} -result 0



































































test menu-23.1 {RecursivelyDeleteMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    . configure -menu .m1
    . configure -menu ""







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    wm geometry .m1 200x100
    update
    set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
    .m1 index @$x,5
} -cleanup {
    deleteWindows
} -result 0
test menu-22.6 {GetIndexFromCoords: syntax error in @x,y indices} -setup {
    deleteWindows
} -body {
    menu .m
    .m add command -label "First entry"
    .m add command -label "Second entry"
    .m add command -label "Last entry"
    .m index @4bogus
} -cleanup {
    deleteWindows
}  -returnCodes error -result {bad menu entry index "@4bogus"}
test menu-22.7 {GetIndexFromCoords: syntax error in @x,y indices} -setup {
    deleteWindows
} -body {
    menu .m
    .m add command -label "First entry"
    .m add command -label "Second entry"
    .m add command -label "Last entry"
    .m index @10,4bogus
} -cleanup {
    deleteWindows
}  -returnCodes error -result {bad menu entry index "@10,4bogus"}
test menu-22.8 {GetIndexFromCoords: syntax error in @x,y indices} -setup {
    deleteWindows
} -body {
    menu .m
    .m add command -label "First entry"
    .m add command -label "Second entry"
    .m add command -label "Last entry"
    .m index @10,bogus
} -cleanup {
    deleteWindows
}  -returnCodes error -result {bad menu entry index "@10,bogus"}
test menu-22.9 {GetIndexFromCoords: index type pecedence} -setup {
    deleteWindows
} -body {
    menu .m -tearoff 0
    .m add command -label "First entry"
    .m add command -label "@42nd street"
    .m add command -label "Last entry"
    .m index "@42nd*"  ; # shall be interpreted as a pattern, not as @42
} -cleanup {
    deleteWindows
} -result {1}

test menu-22.10 {tk_popup on separator entry} -setup {
    deleteWindows
} -constraints {x11} -body {
    menu .m1
    label .l -text ClickMe!
    .m1 add command -label "Example 1" -command bell
    .m1 add command -label "Example 2" -command bell
    .m1 add separator
    .m1 add command -label "Example Other" -command "bell;bell"
    tk_popup .m1 100 100 2
    set waiting 0
    tkwait visibility .m1
    after 333 incr waiting
    vwait waiting
    .m1 invoke 4
    after 333 incr waiting
    vwait waiting
    destroy .m1
} -cleanup {
    deleteWindows
} -result {}

test menu-23.1 {RecursivelyDeleteMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    . configure -menu .m1
    . configure -menu ""
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
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
} -result {{} {}}
test menu-24.3 {TkNewMenuName} -setup {
    deleteWindows
} -body {
    menu .#m
    rename .#m hideme
    list [catch {. configure -menu [menu .m]}] [. configure -menu ""] [destroy .#m] \
		[destroy .m] [destroy hideme]
} -result {0 {} {} {} {}}


test menu-25.1 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.2 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.3 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    destroy .m1
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.4 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    menu .m2
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.5 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    .m1 clone .m2
    menu .m3
    list [. configure -menu .m3] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.6 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    .m1 clone .m2
    . configure -menu .m2
    menu .m3
    list [. configure -menu .m3] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.7 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    .t2 configure -menu .m1
    list [.t2 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.8 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    .t2 configure -menu .m1
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.9 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [.t3 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.10 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [.t2 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.11 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.12 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.13 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.14 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.15 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.16 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    list [toplevel .t2 -menu m1] [. configure -menu ""]
} -cleanup {







|



|







|







|









|










|











|











|












|













|














|














|














|








|







|








|







|







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
} -result {{} {}}
test menu-24.3 {TkNewMenuName} -setup {
    deleteWindows
} -body {
    menu .#m
    rename .#m hideme
    list [catch {. configure -menu [menu .m]}] [. configure -menu ""] [destroy .#m] \
            [destroy .m] [destroy hideme]
} -result {0 {} {} {} {}}


test menu-25.1 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.2 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.3 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    destroy .m1
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.4 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    menu .m2
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.5 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    .m1 clone .m2
    menu .m3
    list [. configure -menu .m3] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.6 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    .m1 clone .m2
    . configure -menu .m2
    menu .m3
    list [. configure -menu .m3] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.7 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    .t2 configure -menu .m1
    list [.t2 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.8 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2
    wm geometry .t2 +0+0
    .t2 configure -menu .m1
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.9 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [.t3 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.10 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [.t2 configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.11 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    menu .m2
    . configure -menu .m1
    toplevel .t2 -menu .m1
    wm geometry .t2 +0+0
    toplevel .t3 -menu .m1
    wm geometry .t3 +0+0
    list [. configure -menu .m2] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.12 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.13 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.14 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.15 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    list [. configure -menu .m1] [. configure -menu ""]
} -cleanup {
    deleteWindows
} -result {{} {}}
test menu-25.16 {Tk_SetWindowMenubar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
    menu .m1
    . configure -menu .m1
    list [toplevel .t2 -menu m1] [. configure -menu ""]
} -cleanup {
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
    deleteWindows
} -result {}
test menu-32.6 {DeleteMenuCloneEntries - reentrancy - crashes tk8.0} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test \
		-command ".m1 delete test ; .m1 add command -label test -command \".m1 delete test\"; .m1 delete test"
    .m1 invoke test
} -cleanup {
    deleteWindows
} -result {}
test menu-32.7 {DeleteMenuCloneEntries - one entry} -setup {
    deleteWindows
} -body {







|







3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
    deleteWindows
} -result {}
test menu-32.6 {DeleteMenuCloneEntries - reentrancy - crashes tk8.0} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label test \
            -command ".m1 delete test ; .m1 add command -label test -command \".m1 delete test\"; .m1 delete test"
    .m1 invoke test
} -cleanup {
    deleteWindows
} -result {}
test menu-32.7 {DeleteMenuCloneEntries - one entry} -setup {
    deleteWindows
} -body {
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
} -body {
    # SF bug #465324
    menu .menubar
    . configure -menu .menubar
    menu .menubar.test
    .menubar.test add command -label "hi"
    for {set i 0} {$i < 10} {incr i} {
		.menubar add cascade -menu .menubar.test -label "Test"
		.menubar delete Test
    }

    info commands .#menubar*test*
} -cleanup {
    deleteWindows
} -result {}
test menu-32.9 {Ensure deleting of clones doesn't corrupt menu refs} -setup {







|
|







3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
} -body {
    # SF bug #465324
    menu .menubar
    . configure -menu .menubar
    menu .menubar.test
    .menubar.test add command -label "hi"
    for {set i 0} {$i < 10} {incr i} {
        .menubar add cascade -menu .menubar.test -label "Test"
        .menubar delete Test
    }

    info commands .#menubar*test*
} -cleanup {
    deleteWindows
} -result {}
test menu-32.9 {Ensure deleting of clones doesn't corrupt menu refs} -setup {
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
    deleteWindows
} -result {.menubar.cascade .#menubar.#menubar#test.#menubar#cascade .menubar.cascade .#menubar.#menubar#test.#menubar#cascade}


test menu-33.1 {menu vs command hiding} -setup {
    deleteWindows
} -body {
	set l [interp hidden]
    menu .m
    interp hide {} .m
    destroy .m
    set result [list [winfo children .] [interp hidden]]
	expr {$result eq [list {} $l]}
} -result 1

# menu-34 MenuInit only called at boot time

# creating menus on two different screens then deleting the
# menu from the first screen crashes Tk8.3.1
#
test menu-34.1 {menus on multiple screens - crashes tk8.3.1, Bug 5454} -constraints {
	altDisplay
} -setup {
    deleteWindows
} -body {
    toplevel .one
    menu .one.m
    toplevel .two -screen $::env(TK_ALT_DISPLAY)
    menu .two.m







|




|








|







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
    deleteWindows
} -result {.menubar.cascade .#menubar.#menubar#test.#menubar#cascade .menubar.cascade .#menubar.#menubar#test.#menubar#cascade}


test menu-33.1 {menu vs command hiding} -setup {
    deleteWindows
} -body {
    set l [interp hidden]
    menu .m
    interp hide {} .m
    destroy .m
    set result [list [winfo children .] [interp hidden]]
    expr {$result eq [list {} $l]}
} -result 1

# menu-34 MenuInit only called at boot time

# creating menus on two different screens then deleting the
# menu from the first screen crashes Tk8.3.1
#
test menu-34.1 {menus on multiple screens - crashes tk8.3.1, Bug 5454} -constraints {
    altDisplay
} -setup {
    deleteWindows
} -body {
    toplevel .one
    menu .one.m
    toplevel .two -screen $::env(TK_ALT_DISPLAY)
    menu .two.m
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
    menu .m -type menubar
    list [catch ".m post 1 1" msg] $msg
} -cleanup {
    destroy .m
} -result {1 {a menubar menu cannot be posted}}

test menu-38.1 {Can't dismiss ttk::menubutton menu until mouse has hovered over it - bug fa32290898} -setup {
} -constraints {userInteraction} -body {
    toplevel .top
    ttk::menubutton .top.mb -text "Some menu";
    menu .top.mb.m;
    .top.mb.m add command -label "Item 1";
    .top.mb.m add command -label "Item 2";
    .top.mb configure -menu .top.mb.m;
    pack .top.mb
    update
    # simulate mouse click on the menubutton, which posts its menu
    event generate .top.mb <Button-1> -warp 1
    update
    after 50
    event generate .top.mb <ButtonRelease-1>
    update
    # simulate mouse click on the menu again, i.e. without
    # entering/leaving the posted menu
    event generate .top.mb <Button-1>
    update
    after 50
    event generate .top.mb <ButtonRelease-1>
    update
    # the menu shall have been unposted by the second click
    winfo ismapped .top.mb.m
} -cleanup {
    destroy .top.mb.m .top.m .top
} -result 0




















































































































































































































# cleanup
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:







|










<
|















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










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
    menu .m -type menubar
    list [catch ".m post 1 1" msg] $msg
} -cleanup {
    destroy .m
} -result {1 {a menubar menu cannot be posted}}

test menu-38.1 {Can't dismiss ttk::menubutton menu until mouse has hovered over it - bug fa32290898} -setup {
} -constraints {x11} -body {
    toplevel .top
    ttk::menubutton .top.mb -text "Some menu";
    menu .top.mb.m;
    .top.mb.m add command -label "Item 1";
    .top.mb.m add command -label "Item 2";
    .top.mb configure -menu .top.mb.m;
    pack .top.mb
    update
    # simulate mouse click on the menubutton, which posts its menu
    event generate .top.mb <Button-1> -warp 1

    controlPointerWarpTiming
    event generate .top.mb <ButtonRelease-1>
    update
    # simulate mouse click on the menu again, i.e. without
    # entering/leaving the posted menu
    event generate .top.mb <Button-1>
    update
    after 50
    event generate .top.mb <ButtonRelease-1>
    update
    # the menu shall have been unposted by the second click
    winfo ismapped .top.mb.m
} -cleanup {
    destroy .top.mb.m .top.m .top
} -result 0

test menu-39.1 {empty -type - bug be8f5b9fc2} -setup {
    catch {destroy .m}
} -body {
    menu .m -type {}
} -cleanup {
    destroy .m
} -returnCodes error -result {ambiguous type "": must be menubar, normal, or tearoff}

test menu-39.2 {use-after-free fix - bug 1797555fff} -setup {
    toplevel .t
    menu .t.menubar -type menubar
    menu .t.menubar.select -title Select
    menu .t.menubar.select.chain -title Chain
    .t.menubar.select insert 1 cascade -menu .t.menubar.select.chain -label Chain
    .t.menubar add cascade -menu .t.menubar.select -label Select
    .t configure -menu .t.menubar
    .t.menubar.select.chain insert 1 command
    update idletasks
} -body {
    # The following two lines caused Tk to read from and write to freed memory
    destroy .t.menubar.select.chain
    .t.menubar.select delete 1
} -cleanup {
    destroy .t
} -result {}

test menu-40.1 {Use-after-free if menu destroyed while posted - bug 09a11fb1228f} -setup {
} -constraints {pressbutton} -body {
    set done false
    event generate {} <Motion> -x 100 -y 100
    toplevel .t
    menu .t.m
    .t.m add command -command {puts Marco} -label Marco
    .t.m add command -command {puts Polo} -label Polo
    after 1000 {.t.m post 500 500}
    after 2000 {destroy .t}
    after 2500 {pressbutton 530 510}
    after 3000 {set done true}
    tkwait variable done
}

test menu-40.2 {Use-after-free if menu destroyed while posted - bug 09a11fb1228f} -setup {
} -constraints {movemouse} -body {
    set done false
    event generate {} <Motion> -x 100 -y 100
    toplevel .t
    menu .t.m
    .t.m add command -command {puts Marco} -label Marco
    .t.m add command -command {puts Polo} -label Polo
    after 1000 {.t.m post 500 500}
    after 2000 {movemouse 530 510}
    after 3000 {destroy .t}
    after 3500 {movemouse 530 530}
    after 4000 pressbutton 530 530
    after 4500 {set done true}
    tkwait variable done
    pressbutton 530 510
}

test menu-41.1 {identifiers - auto generated} -setup {
    destroy .m
} -body {
    menu .m
    list [.m add command -label 1] [.m add command -label 2] [.m add command -label 3]
} -cleanup {
    destroy .m
} -result {e001 e002 e003}
test menu-41.2 {identifiers - out of sequence} -setup {
    destroy .m
} -body {
    menu .m -tearoff 0
    .m add command -label 1
    .m insert 0 command -label 2
    .m add command -label 3
    list [.m index e001] [.m index e002] [.m index e003]
} -cleanup {
    destroy .m
} -result {1 0 2}
test menu-41.3 {identifiers - out of sequence with tearoff} -setup {
    destroy .m
} -body {
    menu .m -tearoff 1
    .m add command -label 1
    .m insert 0 command -label 2
    .m add command -label 3
    list [.m index e001] [.m index e002] [.m index e003]
} -cleanup {
    destroy .m
} -result {2 1 3}
test menu-41.4 {identifiers - entry id} -setup {
    destroy .m
} -body {
    menu .m -tearoff 1
    .m add command -label 1
    .m insert 0 command -label 2
    .m add command -label 3
    list [.m id 0] [.m id 1] [.m id 2] [.m id 3]
} -cleanup {
    destroy .m
} -result {{} e002 e001 e003}
test menu-41.5 {identifiers - assigned} -setup {
    destroy .m
} -body {
    menu .m
    list [.m add command cmd1 -label 1] [.m insert 0 command cmd2 -label 2] [.m add command cmd3 -label 3]
} -cleanup {
    destroy .m
} -result {cmd1 cmd2 cmd3}
test menu-41.6 {identifiers - mixed} -setup {
    destroy .m
} -body {
    menu .m
    list [.m add command -label 1] [.m insert 0 command cmd2 -label 2] [.m add command -label 3]
} -cleanup {
    destroy .m
} -result {e001 cmd2 e002}
test menu-41.7 {identifiers - conflict} -setup {
    destroy .m
} -body {
    menu .m
    list [.m add command e002 -label 1] [.m add command -label 2] [.m add command -label 3]
} -cleanup {
    destroy .m
} -result {e002 e001 e003}
test menu-41.8 {identifiers - clone of complete menu} -setup {
    destroy .m1 .m2
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label 1
    .m1 insert 0 command -label 2
    .m1 add command cmd3 -label 3
    .m1 clone .m2
    list [.m2 index e001] [.m2 index e002] [.m2 index cmd3]
} -cleanup {
    destroy .m1 .m2
} -result {1 0 2}
test menu-41.9 {identifiers - modify after cloning} -setup {
    destroy .m1 .m2
} -body {
    menu .m1 -tearoff 0
    .m1 clone .m2
    .m1 add command -label 1
    .m1 insert 0 command -label 2
    .m1 add command cmd3 -label 3
    list [.m2 index e001] [.m2 index e002] [.m2 index cmd3]
} -cleanup {
    destroy .m1 .m2
} -result {1 0 2}
test menu-41.10 {identifiers - modify clone} -setup {
    destroy .m1 .m2
} -body {
    menu .m1 -tearoff 0
    .m1 clone .m2
    .m2 add command -label 1
    .m2 insert 0 command -label 2
    .m2 add command cmd3 -label 3
    list [.m1 index e001] [.m1 index e002] [.m1 index cmd3]
} -cleanup {
    destroy .m1 .m2
} -result {1 0 2}
test menu-41.11 {identifiers - entrycget by id} -setup {
    destroy .m
} -body {
    menu .m
    .m add command -label 1
    .m add command -label 2
    .m add command cmd3 -label 3
    list [.m entrycget e001 -label] [.m entrycget e002 -label] [.m entrycget cmd3 -label]
} -cleanup {
    destroy .m
} -result {1 2 3}
test menu-41.12 {identifiers - delete by id} -setup {
    destroy .m
} -body {
    menu .m
    .m add command -label 1
    .m add command -label 2
    .m add command -label 3
    .m add command -label 4
    .m add command -label 5
    .m add command -label 6
    .m add command -label 7
    .m add command cmd8 -label 8
    .m add command cmd9 -label 9
    .m delete e003 cmd8
    list [.m id 0] [.m id 1] [.m id 2]
} -cleanup {
    destroy .m
} -result {e001 e002 cmd9}
test menu-41.13 {identifiers - duplicate} -setup {
    destroy .m
} -body {
    menu .m
    .m add command foo -label 1
    .m add command bar -label 2
    .m add command foo -label 3
} -cleanup {
    destroy .m
} -returnCodes error -result {entry "foo" already exists}
test menu-41.14 {identifiers - reserved word} -setup {
    destroy .m
} -body {
    menu .m -tearoff 0
    .m add command last -label 1
    .m add command -label 2
    .m add command -label 3
    .m index last
} -cleanup {
    destroy .m
} -result {2}

# cleanup
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/menuDraw.test.

1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test drawing of menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit




|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test drawing of menus in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
test menuDraw-2.1 {TkInitializeMenuEntryDrawingFields} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {}


test menuDraw-3.1 {TkMenuFreeDrawOptions} -setup {
    deleteWindows
} -body {
    menu .m1
    destroy .m1







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
test menuDraw-2.1 {TkInitializeMenuEntryDrawingFields} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command
} -cleanup {
    deleteWindows
} -result {e001}


test menuDraw-3.1 {TkMenuFreeDrawOptions} -setup {
    deleteWindows
} -body {
    menu .m1
    destroy .m1
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
test menuDraw-6.1 {TkMenuConfigureEntryDrawOptions - no tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.2 {TkMenuConfigureEntryDrawOptions - tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.3 {TkMenuConfigureEntryDrawOptions - active state - wrong entry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 entryconfigure 1 -state active
} -cleanup {







|







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
test menuDraw-6.1 {TkMenuConfigureEntryDrawOptions - no tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.2 {TkMenuConfigureEntryDrawOptions - tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.3 {TkMenuConfigureEntryDrawOptions - active state - wrong entry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 entryconfigure 1 -state active
} -cleanup {
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 entryconfigure 1 -state foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad state "foo": must be active, normal, or disabled}
test menuDraw-6.7 {TkMenuConfigureEntryDrawOptions - tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.8 {TkMenuConfigureEntryDrawOptions - border specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -background "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.9 {TkMenuConfigureEntryDrawOptions - foreground specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -foreground "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.10 {TkMenuConfigureEntryDrawOptions - activeBorder specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activebackground "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.11 {TkMenuConfigureEntryDrawOptions - activeforeground specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activeforeground "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.12 {TkMenuConfigureEntryDrawOptions - selectcolor specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "foo" -selectcolor "red"
} -cleanup {
    deleteWindows
} -result {}
test menuDraw-6.13 {TkMenuConfigureEntryDrawOptions - textGC disposal} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Helvetica 12"
    .m1 entryconfigure 1 -font "Courier 12"
} -cleanup {







|







|







|







|







|







|







|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 entryconfigure 1 -state foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad state "foo": must be active, disabled, or normal}
test menuDraw-6.7 {TkMenuConfigureEntryDrawOptions - tkfont specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Courier 12"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.8 {TkMenuConfigureEntryDrawOptions - border specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -background "red"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.9 {TkMenuConfigureEntryDrawOptions - foreground specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -foreground "red"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.10 {TkMenuConfigureEntryDrawOptions - activeBorder specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activebackground "red"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.11 {TkMenuConfigureEntryDrawOptions - activeforeground specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -activeforeground "red"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.12 {TkMenuConfigureEntryDrawOptions - selectcolor specified} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add radiobutton -label "foo" -selectcolor "red"
} -cleanup {
    deleteWindows
} -result {e001}
test menuDraw-6.13 {TkMenuConfigureEntryDrawOptions - textGC disposal} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -font "Helvetica 12"
    .m1 entryconfigure 1 -font "Courier 12"
} -cleanup {
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
} -returnCodes ok -match glob -result *
test menuDraw-15.2 {TkPostTearoffMenu - Deactivation} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -state active
    set tearoff [tk::TearOffMenu .m1 40 40]
    $tearoff index active
} -cleanup {
    deleteWindows
} -result none
test menuDraw-15.3 {TkPostTearoffMenu - post command} -setup {
    deleteWindows
} -body {
    catch {unset foo}
    menu .m1 -postcommand "set foo .m1"
    .m1 add command -label "foo"
    list [catch {tk::TearOffMenu .m1 40 40}] [set foo] [unset foo] [destroy .m1]







|


|







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
} -returnCodes ok -match glob -result *
test menuDraw-15.2 {TkPostTearoffMenu - Deactivation} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "foo" -state active
    set tearoff [tk::TearOffMenu .m1 40 40]
    expr {[$tearoff index active]<0}
} -cleanup {
    deleteWindows
} -result 1
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
# This file is a Tcl script to test menubuttons in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

# XXX This test file is woefully incomplete right now.  If any part
# XXX of a procedure has tests then the whole procedure has tests,
# XXX but many procedures have no tests.

package require tcltest 2.2





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test menubuttons in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    .mb configure -bd 4
    .mb cget -bd
} -cleanup {
    .mb configure -bd [lindex [.mb configure -bd] 3]
} -result 4
test menubutton-1.10 {configuration options} -body {
    .mb configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test menubutton-1.11 {configuration options} -body {
    .mb configure -bg #ff0000
    .mb cget -bg
} -cleanup {
    .mb configure -bg [lindex [.mb configure -bg] 3]
} -result {#ff0000}
test menubutton-1.12 {configuration options} -body {







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    .mb configure -bd 4
    .mb cget -bd
} -cleanup {
    .mb configure -bd [lindex [.mb configure -bd] 3]
} -result 4
test menubutton-1.10 {configuration options} -body {
    .mb configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test menubutton-1.11 {configuration options} -body {
    .mb configure -bg #ff0000
    .mb cget -bg
} -cleanup {
    .mb configure -bg [lindex [.mb configure -bg] 3]
} -result {#ff0000}
test menubutton-1.12 {configuration options} -body {
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    .mb configure -borderwidth 1.3
    .mb cget -borderwidth
} -cleanup {
    .mb configure -borderwidth [lindex [.mb configure -borderwidth] 3]
} -result 1
test menubutton-1.16 {configuration options} -body {
    .mb configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test menubutton-1.17 {configuration options} -body {
    .mb configure -cursor arrow
    .mb cget -cursor
} -cleanup {
    .mb configure -cursor [lindex [.mb configure -cursor] 3]
} -result {arrow}
test menubutton-1.18 {configuration options} -body {







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    .mb configure -borderwidth 1.3
    .mb cget -borderwidth
} -cleanup {
    .mb configure -borderwidth [lindex [.mb configure -borderwidth] 3]
} -result 1
test menubutton-1.16 {configuration options} -body {
    .mb configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test menubutton-1.17 {configuration options} -body {
    .mb configure -cursor arrow
    .mb cget -cursor
} -cleanup {
    .mb configure -cursor [lindex [.mb configure -cursor] 3]
} -result {arrow}
test menubutton-1.18 {configuration options} -body {
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    .mb configure -highlightthickness 18
    .mb cget -highlightthickness
} -cleanup {
    .mb configure -highlightthickness [lindex [.mb configure -highlightthickness] 3]
} -result 18
test menubutton-1.35 {configuration options} -body {
    .mb configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test menubutton-1.36 {configuration options} -constraints {
    testImageType
} -setup {
    catch {image delete image1}
    image create test image1
} -body {
    .mb configure -image image1







|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    .mb configure -highlightthickness 18
    .mb cget -highlightthickness
} -cleanup {
    .mb configure -highlightthickness [lindex [.mb configure -highlightthickness] 3]
} -result 18
test menubutton-1.35 {configuration options} -body {
    .mb configure -highlightthickness badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test menubutton-1.36 {configuration options} -constraints {
    testImageType
} -setup {
    catch {image delete image1}
    image create test image1
} -body {
    .mb configure -image image1
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    .mb configure -padx 12
    .mb cget -padx
} -cleanup {
    .mb configure -padx [lindex [.mb configure -padx] 3]
} -result 12
test menubutton-1.44 {configuration options} -body {
    .mb configure -padx 420x
} -returnCodes error -result {bad screen distance "420x"}
test menubutton-1.45 {configuration options} -body {
    .mb configure -pady 12
    .mb cget -pady
} -cleanup {
    .mb configure -pady [lindex [.mb configure -pady] 3]
} -result 12
test menubutton-1.46 {configuration options} -body {
    .mb configure -pady 420x
} -returnCodes error -result {bad screen distance "420x"}
test menubutton-1.47 {configuration options} -body {
    .mb configure -relief groove
    .mb cget -relief
} -cleanup {
    .mb configure -relief [lindex [.mb configure -relief] 3]
} -result {groove}
test menubutton-1.48 {configuration options} -body {







|








|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    .mb configure -padx 12
    .mb cget -padx
} -cleanup {
    .mb configure -padx [lindex [.mb configure -padx] 3]
} -result 12
test menubutton-1.44 {configuration options} -body {
    .mb configure -padx 420x
} -returnCodes error -result {expected screen distance but got "420x"}
test menubutton-1.45 {configuration options} -body {
    .mb configure -pady 12
    .mb cget -pady
} -cleanup {
    .mb configure -pady [lindex [.mb configure -pady] 3]
} -result 12
test menubutton-1.46 {configuration options} -body {
    .mb configure -pady 420x
} -returnCodes error -result {expected screen distance but got "420x"}
test menubutton-1.47 {configuration options} -body {
    .mb configure -relief groove
    .mb cget -relief
} -cleanup {
    .mb configure -relief [lindex [.mb configure -relief] 3]
} -result {groove}
test menubutton-1.48 {configuration options} -body {
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    .mb configure -underline 5
    .mb cget -underline
} -cleanup {
    .mb configure -underline [lindex [.mb configure -underline] 3]
} -result 5
test menubutton-1.55 {configuration options} -body {
    .mb configure -underline 3p
} -returnCodes error -result {expected integer but got "3p"}
test menubutton-1.56 {configuration options} -body {
    .mb configure -width 402
    .mb cget -width
} -cleanup {
    .mb configure -width [lindex [.mb configure -width] 3]
} -result 402
test menubutton-1.57 {configuration options} -body {
    .mb configure -width 3p
} -returnCodes error -result {expected integer but got "3p"}
test menubutton-1.58 {configuration options} -body {
    .mb configure -wraplength 100
    .mb cget -wraplength
} -cleanup {
    .mb configure -wraplength [lindex [.mb configure -wraplength] 3]
} -result 100
test menubutton-1.59 {configuration options} -body {
    .mb configure -wraplength 6x
} -returnCodes error -result {bad screen distance "6x"}


deleteWindows
menubutton .mb -text "Test"
pack .mb
update
test menubutton-2.1 {Tk_MenubuttonCmd procedure} -body {







|

















|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    .mb configure -underline 5
    .mb cget -underline
} -cleanup {
    .mb configure -underline [lindex [.mb configure -underline] 3]
} -result 5
test menubutton-1.55 {configuration options} -body {
    .mb configure -underline 3p
} -returnCodes error -result {bad index "3p": must be integer?[+-]integer?, end?[+-]integer?, or ""}
test menubutton-1.56 {configuration options} -body {
    .mb configure -width 402
    .mb cget -width
} -cleanup {
    .mb configure -width [lindex [.mb configure -width] 3]
} -result 402
test menubutton-1.57 {configuration options} -body {
    .mb configure -width 3p
} -returnCodes error -result {expected integer but got "3p"}
test menubutton-1.58 {configuration options} -body {
    .mb configure -wraplength 100
    .mb cget -wraplength
} -cleanup {
    .mb configure -wraplength [lindex [.mb configure -wraplength] 3]
} -result 100
test menubutton-1.59 {configuration options} -body {
    .mb configure -wraplength 6x
} -returnCodes error -result {expected screen distance but got "6x"}


deleteWindows
menubutton .mb -text "Test"
pack .mb
update
test menubutton-2.1 {Tk_MenubuttonCmd procedure} -body {
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
test menubutton-4.5 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -bitmap questhead
    .mb1 configure -width abc
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad screen distance "abc"}
test menubutton-4.6 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -bitmap questhead
    catch {.mb1 configure -width abc}
    return $errorInfo
} -cleanup {
    deleteWindows
} -result {bad screen distance "abc"
    (processing -width option)
    invoked from within
".mb1 configure -width abc"}

test menubutton-4.7 {ConfigureMenuButton procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    button .mb1 -image image1
    .mb1 configure -height 0.5x
} -cleanup {
    deleteWindows
    imageCleanup
} -returnCodes error -result {bad screen distance "0.5x"}
test menubutton-4.8 {ConfigureMenuButton procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    button .mb1 -image image1
    catch {.mb1 configure -height 0.5x}
    return $errorInfo
} -cleanup {
    deleteWindows
    imageCleanup
} -result {bad screen distance "0.5x"
    (processing -height option)
    invoked from within
".mb1 configure -height 0.5x"}

test menubutton-4.9 {ConfigureMenuButton procedure} -constraints {
    nonPortable fonts
} -setup {







|








|
















|













|







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
test menubutton-4.5 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -bitmap questhead
    .mb1 configure -width abc
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected screen distance but got "abc"}
test menubutton-4.6 {ConfigureMenuButton procedure} -setup {
    deleteWindows
} -body {
    button .mb1 -bitmap questhead
    catch {.mb1 configure -width abc}
    return $errorInfo
} -cleanup {
    deleteWindows
} -result {expected screen distance but got "abc"
    (processing -width option)
    invoked from within
".mb1 configure -width abc"}

test menubutton-4.7 {ConfigureMenuButton procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    button .mb1 -image image1
    .mb1 configure -height 0.5x
} -cleanup {
    deleteWindows
    imageCleanup
} -returnCodes error -result {expected screen distance but got "0.5x"}
test menubutton-4.8 {ConfigureMenuButton procedure} -constraints {
    testImageType
} -setup {
    deleteWindows
    imageCleanup
} -body {
    image create test image1
    button .mb1 -image image1
    catch {.mb1 configure -height 0.5x}
    return $errorInfo
} -cleanup {
    deleteWindows
    imageCleanup
} -result {expected screen distance but got "0.5x"
    (processing -height option)
    invoked from within
".mb1 configure -height 0.5x"}

test menubutton-4.9 {ConfigureMenuButton procedure} -constraints {
    nonPortable fonts
} -setup {
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    menubutton .mb1
    rename .mb1 {}
    list [info command .mb*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}

if {[tk windowingsystem] == "aqua"} {
    set extraWidth 36
} else {
    set extraWidth 0
}
test menubutton-7.1 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {







|







538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    menubutton .mb1
    rename .mb1 {}
    list [info command .mb*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}

if {[tk windowingsystem] eq "aqua"} {
    set extraWidth 36
} else {
    set extraWidth 0
}
test menubutton-7.1 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {

Changes to tests/message.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the "message" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 by Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::loadTestedCommands
eval tcltest::configure $argv






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the "message" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::loadTestedCommands
eval tcltest::configure $argv

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bd badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}

test message-1.9 {configuration option: "bg"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bg #ff0000







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bd badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test message-1.9 {configuration option: "bg"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -bg #ff0000
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    pack .m
    update
} -body {
    .m configure -borderwidth 1.3
    .m cget -borderwidth
} -cleanup {
    destroy .m
} -result 1
test message-1.12 {configuration option: "borderwidth"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -borderwidth badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}

test message-1.13 {configuration option: "cursor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -cursor arrow







|








|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    pack .m
    update
} -body {
    .m configure -borderwidth 1.3
    .m cget -borderwidth
} -cleanup {
    destroy .m
} -result 1.3
test message-1.12 {configuration option: "borderwidth"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -borderwidth badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test message-1.13 {configuration option: "cursor"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -cursor arrow
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightthickness  badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}

test message-1.27 {configuration option: "justify"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -justify  right







|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -highlightthickness  badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test message-1.27 {configuration option: "justify"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -justify  right
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -padx 420x
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "420x"}

test message-1.31 {configuration option: "pady"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -pady  12m
    .m cget -pady
} -cleanup {
    destroy .m
} -result {12m}
test message-1.32 {configuration option: "pady"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -pady 420x
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "420x"}

test message-1.33 {configuration option: "relief"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -relief ridge







|



















|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -padx 420x
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected screen distance or "" but got "420x"}

test message-1.31 {configuration option: "pady"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -pady  12m
    .m cget -pady
} -cleanup {
    destroy .m
} -result {12m}
test message-1.32 {configuration option: "pady"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -pady 420x
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected screen distance or "" but got "420x"}

test message-1.33 {configuration option: "relief"} -setup {
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -relief ridge
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -width badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {bad screen distance "badValue"}


test message-2.1 {Tk_MessageObjCmd procedure} -body {
    message
} -returnCodes {error} -result {wrong # args: should be "message pathName ?-option value ...?"}

test message-2.2 {Tk_MessageObjCmd procedure} -body {
    message foo
} -returnCodes {error} -result {bad window path name "foo"}
test message-2.3 {Tk_MessageObjCmd procedure} -body {
    catch {message foo}
    winfo child .
} -result {}

test message-2.4 {Tk_MessageObjCmd procedure} -body {
    message .s -gorp dump
} -returnCodes {error} -result {unknown option "-gorp"}
test message-2.5 {Tk_MessageObjCmd procedure} -body {
    catch {message .s -gorp dump}
    winfo child .
} -result {}


test message-3.1 {MessageWidgetObjCmd procedure} -setup {
    message .m
} -body {
    .m







|











|







|







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    message .m -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
    pack .m
    update
} -body {
    .m configure -width badValue
} -cleanup {
    destroy .m
} -returnCodes {error} -result {expected screen distance but got "badValue"}


test message-2.1 {Tk_MessageObjCmd procedure} -body {
    message
} -returnCodes {error} -result {wrong # args: should be "message pathName ?-option value ...?"}

test message-2.2 {Tk_MessageObjCmd procedure} -body {
    message foo
} -returnCodes {error} -result {bad window path name "foo"}
test message-2.3 {Tk_MessageObjCmd procedure} -body {
    catch {message foo}
    winfo children .
} -result {}

test message-2.4 {Tk_MessageObjCmd procedure} -body {
    message .s -gorp dump
} -returnCodes {error} -result {unknown option "-gorp"}
test message-2.5 {Tk_MessageObjCmd procedure} -body {
    catch {message .s -gorp dump}
    winfo children .
} -result {}


test message-3.1 {MessageWidgetObjCmd procedure} -setup {
    message .m
} -body {
    .m

Changes to tests/msgbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out Tk's "tk_messageBox" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test out Tk's "tk_messageBox" command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# This file is a Tcl script to test new object types in Tk.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands





|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test new object types in Tk.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Deleted tests/oldpack.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
# This file is a Tcl script to test out the old syntax of Tk's
# "pack" command (before release 3.3).  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1991-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# First, test a single window packed in various ways in a parent

destroy .pack
frame .pack
place .pack -width 100 -height 100
frame .pack.red -width 10 -height 20
label .pack.red.l -text R -bd 2 -relief raised
place .pack.red.l -relwidth 1.0 -relheight 1.0
frame .pack.green -width 30 -height 40
label .pack.green.l -text G -bd 2 -relief raised
place .pack.green.l -relwidth 1.0 -relheight 1.0
frame .pack.blue -width 40 -height 40
label .pack.blue.l -text B -bd 2 -relief raised
place .pack.blue.l -relwidth 1.0 -relheight 1.0
frame .pack.violet -width 80 -height 20
label .pack.violet.l -text P -bd 2 -relief raised
place .pack.violet.l -relwidth 1.0 -relheight 1.0

if {![catch {pack ap .pack .pack.red top}]} {

# Don't execute any of this file if Tk is compiled with -DTCL_NO_DEPRECATED


test oldpack-1.1 {basic positioning} -body {
    #pack ap .pack .pack.red top
    update
    winfo geometry .pack.red
} -result 10x20+45+0
test oldpack-1.2 {basic positioning} -body {
    pack append .pack .pack.red bottom
    update
    winfo geometry .pack.red
} -result 10x20+45+80
test oldpack-1.3 {basic positioning} -body {
    pack append .pack .pack.red left
    update
    winfo geometry .pack.red
} -result 10x20+0+40
test oldpack-1.4 {basic positioning} -body {
    pack append .pack .pack.red right
    update
    winfo geometry .pack.red
} -result 10x20+90+40

# Try adding padding around the window and make sure that the
# window gets a larger frame.

test oldpack-2.1 {padding} -body {
    pack append .pack .pack.red {t padx 20}
    update
    winfo geometry .pack.red
} -result 10x20+45+0
test oldpack-2.2 {padding} -body {
    pack append .pack .pack.red {top pady 20}
    update
    winfo geometry .pack.red
} -result 10x20+45+10
test oldpack-2.3 {padding} -body {
    pack append .pack .pack.red {l padx 20}
    update
    winfo geometry .pack.red
} -result 10x20+10+40
test oldpack-2.4 {padding} -body {
    pack append .pack .pack.red {left pady 20}
    update
    winfo geometry .pack.red
} -result 10x20+0+40

# Position the window at different positions in its frame to
# make sure they all work.  Try two differenet frame locations,
# to make sure that frame offsets are being added in correctly.

test oldpack-3.1 {framing} -body {
    pack append .pack .pack.red {b padx 20 pady 30}
    update
    winfo geometry .pack.red
} -result 10x20+45+65
test oldpack-3.2 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 fr n}
    update
    winfo geometry .pack.red
} -result 10x20+45+50
test oldpack-3.3 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame ne}
    update
    winfo geometry .pack.red
} -result 10x20+90+50
test oldpack-3.4 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame e}
    update
    winfo geometry .pack.red
} -result 10x20+90+65
test oldpack-3.5 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame se}
    update
    winfo geometry .pack.red
} -result 10x20+90+80
test oldpack-3.6 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame s}
    update
    winfo geometry .pack.red
} -result 10x20+45+80
test oldpack-3.7 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame sw}
    update
    winfo geometry .pack.red
} -result 10x20+0+80
test oldpack-3.8 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame w}
    update
    winfo geometry .pack.red
} -result 10x20+0+65
test oldpack-3.9 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame nw}
    update
    winfo geometry .pack.red
} -result 10x20+0+50
test oldpack-3.10 {framing} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 frame c}
    update
    winfo geometry .pack.red
} -result 10x20+45+65
test oldpack-3.11 {framing} -body {
    pack append .pack .pack.red {r padx 20 pady 30}
    update
    winfo geometry .pack.red
} -result 10x20+80+40
test oldpack-3.12 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame n}
    update
    winfo geometry .pack.red
} -result 10x20+80+0
test oldpack-3.13 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame ne}
    update
    winfo geometry .pack.red
} -result 10x20+90+0
test oldpack-3.14 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame e}
    update
    winfo geometry .pack.red
} -result 10x20+90+40
test oldpack-3.15 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame se}
    update
    winfo geometry .pack.red
} -result 10x20+90+80
test oldpack-3.16 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame s}
    update
    winfo geometry .pack.red
} -result 10x20+80+80
test oldpack-3.17 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame sw}
    update
    winfo geometry .pack.red
} -result 10x20+70+80
test oldpack-3.18 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame w}
    update
    winfo geometry .pack.red
} -result 10x20+70+40
test oldpack-3.19 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame nw}
    update
    winfo geometry .pack.red
} -result 10x20+70+0
test oldpack-3.20 {framing} -body {
    pack append .pack .pack.red {right padx 20 pady 30 frame center}
    update
    winfo geometry .pack.red
} -result 10x20+80+40

# Try out various filling combinations in a couple of different
# frame locations.

test oldpack-4.1 {filling} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 fillx}
    update
    winfo geometry .pack.red
} -result 100x20+0+65
test oldpack-4.2 {filling} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 filly}
    update
    winfo geometry .pack.red
} -result 10x50+45+50
test oldpack-4.3 {filling} -body {
    pack append .pack .pack.red {bottom padx 20 pady 30 fill}
    update
    winfo geometry .pack.red
} -result 100x50+0+50
test oldpack-4.4 {filling} -body {
    pack append .pack .pack.red {right padx 20 pady 30 fillx}
    update
    winfo geometry .pack.red
} -result 30x20+70+40
test oldpack-4.5 {filling} -body {
    pack append .pack .pack.red {right padx 20 pady 30 filly}
    update
    winfo geometry .pack.red
} -result 10x100+80+0
test oldpack-4.6 {filling} -body {
    pack append .pack .pack.red {right padx 20 pady 30 fill}
    update
    winfo geometry .pack.red
} -result 30x100+70+0

# Multiple windows:  make sure that space is properly subtracted
# from the cavity as windows are positioned inwards from all
# different sides.  Also make sure that windows get unmapped if
# there isn't enough space for them.

pack append .pack .pack.red top .pack.green top .pack.blue top \
    .pack.violet top
update
test oldpack-5.1 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+45+0
test oldpack-5.2 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+35+20
test oldpack-5.3 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+60
test oldpack-5.4 {multiple windows} -body {
    winfo ismapped .pack.violet
} -result 0

pack b .pack.blue .pack.violet top
update
test oldpack-5.5 {multiple windows} -body {
    winfo ismapped .pack.violet
} -result 1
test oldpack-5.6 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+10+60
test oldpack-5.7 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x20+30+80

pack after .pack.blue .pack.red top
update
test oldpack-5.8 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+35+0
test oldpack-5.9 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+10+40
test oldpack-5.10 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+60
test oldpack-5.11 {multiple windows} -body {
    winfo ismapped .pack.red
} -result 0

pack before .pack.green .pack.red right .pack.blue left
update
test oldpack-5.12 {multiple windows} -body {
    winfo ismapped .pack.red
} -result 1
test oldpack-5.13 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+90+40
test oldpack-5.14 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+0+30
test oldpack-5.15 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+50+0
test oldpack-5.16 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 50x20+40+40

pack append .pack .pack.violet left .pack.green bottom .pack.red bottom \
    .pack.blue bottom
update
test oldpack-5.17 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+0+40
test oldpack-5.18 {multiple windows} -body {
    winfo geometry .pack.green
} -result 20x40+80+60
test oldpack-5.19 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+85+40
test oldpack-5.20 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 20x40+80+0

pack after .pack.blue .pack.blue top .pack.red right .pack.green right \
    .pack.violet right
update
test oldpack-5.21 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+0
test oldpack-5.22 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+90+60
test oldpack-5.23 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+60+50
test oldpack-5.24 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 60x20+0+60

pack after .pack.blue .pack.red left .pack.green left .pack.violet left
update
test oldpack-5.25 {multiple windows} -body {
    winfo geometry .pack.blue
} -result 40x40+30+0
test oldpack-5.26 {multiple windows} -body {
    winfo geometry .pack.red
} -result 10x20+0+60
test oldpack-5.27 {multiple windows} -body {
    winfo geometry .pack.green
} -result 30x40+10+50
test oldpack-5.28 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 60x20+40+60

pack append .pack .pack.violet left .pack.green left .pack.blue left \
    .pack.red left
update
test oldpack-5.29 {multiple windows} -body {
    winfo geometry .pack.violet
} -result 80x20+0+40
test oldpack-5.30 {multiple windows} -body {
    winfo geometry .pack.green
} -result 20x40+80+30
test oldpack-5.31 {multiple windows} -body {
    winfo ismapped .pack.blue
} -result 0
test oldpack-5.32 {multiple windows} -body {
    winfo ismapped .pack.red
} -result 0


# Test the ability of the packer to propagate geometry information
# to its parent.  Make sure it computes the parent's needs both in
# the direction of packing (width for "left" and "right" windows,
# for example), and perpendicular to the pack direction (height for
# "left" and "right" windows).

pack append .pack .pack.red top .pack.green top .pack.blue top \
    .pack.violet top
update
test oldpack-6.1 {geometry propagation} -body {
    winfo reqwidth .pack} -result 80
test oldpack-6.2 {geometry propagation} -body {
    winfo reqheight .pack} -result 120
destroy .pack.violet
update
test oldpack-6.3 {geometry propagation} -body {
    winfo reqwidth .pack} -result 40
test oldpack-6.4 {geometry propagation} -body {
    winfo reqheight .pack} -result 100
frame .pack.violet -width 80 -height 20 -bg violet
label .pack.violet.l -text P -bd 2 -relief raised
place .pack.violet.l -relwidth 1.0 -relheight 1.0
pack append .pack .pack.red left .pack.green right .pack.blue bottom \
    .pack.violet top
update
test oldpack-6.5 {geometry propagation} -body {
    winfo reqwidth .pack} -result 120
test oldpack-6.6 {geometry propagation} -body {
    winfo reqheight .pack} -result 60
pack append .pack .pack.violet top .pack.green top .pack.blue left \
    .pack.red left
update
test oldpack-6.7 {geometry propagation} -body {
    winfo reqwidth .pack} -result 80
test oldpack-6.8 {geometry propagation} -body {
    winfo reqheight .pack} -result 100

# Test the "expand" option, and make sure space is evenly divided
# when several windows request expansion.

pack append .pack .pack.violet top .pack.green {left e} \
    .pack.blue {left expand} .pack.red {left expand}
update
test oldpack-7.1 {multiple expanded windows} -body {
    pack append .pack .pack.violet top .pack.green {left e} \
        .pack.blue {left expand} .pack.red {left expand}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.blue] \
        [winfo geometry .pack.red]
} -result {30x40+3+40 40x40+39+40 10x20+86+50}
test oldpack-7.2 {multiple expanded windows} -body {
    pack append .pack .pack.green left .pack.violet {bottom expand} \
        .pack.blue {bottom expand} .pack.red {bottom expand}
    update
    list [winfo geometry .pack.violet] [winfo geometry .pack.blue] \
        [winfo geometry .pack.red]
} -result {70x20+30+77 40x40+45+30 10x20+60+3}
test oldpack-7.3 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.green {left e fill} .pack.red {left expand fill} \
        .pack.blue {top fill}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.red] \
        [winfo geometry .pack.blue]
} -result {40x100+0+0 20x100+40+0 40x40+60+0}
test oldpack-7.4 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.red {top expand} .pack.violet {top expand} \
        .pack.blue {right fill}
    update
    list [winfo geometry .pack.red] [winfo geometry .pack.violet] \
        [winfo geometry .pack.blue]
} -result {10x20+45+5 80x20+10+35 40x40+60+60}
test oldpack-7.5 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.green {right frame s} .pack.red {top expand}
    update
    list [winfo geometry .pack.green] [winfo geometry .pack.red]
} -result {30x40+70+60 10x20+30+40}
test oldpack-7.6 {multiple expanded windows} -body {
    foreach i [winfo child .pack] {
    pack unpack $i
    }
    pack append .pack .pack.violet {bottom frame e} .pack.red {right expand}
    update
    list [winfo geometry .pack.violet] [winfo geometry .pack.red]
} -result {80x20+20+80 10x20+45+30}

# Need more bizarre tests with combinations of expanded windows and
# windows in opposing directions!  Also, include padding in expanded
# (and unexpanded) windows.

# Syntax errors on pack commands

test oldpack-8.1 {syntax errors} -body {
    pack
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test oldpack-8.2 {syntax errors} -body {
    pack append
} -returnCodes error -result {wrong # args: should be "pack option arg ?arg ...?"}
test oldpack-8.3 {syntax errors} -body {
    pack gorp foo
} -returnCodes error -result {bad option "gorp": must be configure, content, forget, info, or propagate}
test oldpack-8.4 {syntax errors} -body {
    pack a .pack
} -returnCodes error -result {bad option "a": must be configure, content, forget, info, or propagate}
test oldpack-8.5 {syntax errors} -body {
    pack after foobar
} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.6 {syntax errors} -setup {
    destroy .pack.yellow
} -body {
    frame .pack.yellow -bg yellow
    pack after .pack.yellow
} -cleanup {
    destroy .pack.yellow
} -returnCodes error -result {window ".pack.yellow" isn't packed}
test oldpack-8.7 {syntax errors} -body {
    pack append foobar
} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.8 {syntax errors} -body {
    pack before foobar
} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.9 {syntax errors} -setup {
    destroy .pack.yellow
} -body {
    frame .pack.yellow -bg yellow
    pack before .pack.yellow
} -cleanup {
    destroy .pack.yellow
} -returnCodes error -result {window ".pack.yellow" isn't packed}
test oldpack-8.10 {syntax errors} -body {
    pack info .pack help
} -returnCodes error -result {wrong # args: should be "pack info window"}
test oldpack-8.11 {syntax errors} -body {
    pack info foobar
} -returnCodes error -result {bad window path name "foobar"}
test oldpack-8.12 {syntax errors} -body {
    pack append .pack .pack.blue
} -returnCodes error -result {wrong # args: window ".pack.blue" should be followed by options}
test oldpack-8.13 {syntax errors} -body {
    pack append . .pack.blue top
} -returnCodes error -result {can't pack ".pack.blue" inside "."}
test oldpack-8.14 {syntax errors} -body {
    pack append .pack .pack.blue f
} -returnCodes error -result {bad option "f": should be top, bottom, left, right, expand, fill, fillx, filly, padx, pady, or frame}
test oldpack-8.15 {syntax errors} -body {
    pack append .pack .pack.blue pad
} -returnCodes error -result {bad option "pad": should be top, bottom, left, right, expand, fill, fillx, filly, padx, pady, or frame}
test oldpack-8.16 {syntax errors} -body {
    pack append .pack .pack.blue {frame south}
} -returnCodes error -result {bad anchor "south": must be n, ne, e, se, s, sw, w, nw, or center}
test oldpack-8.17 {syntax errors} -body {
    pack append .pack .pack.blue {padx -2}
} -returnCodes error -result {bad pad value "-2": must be positive screen distance}
test oldpack-8.18 {syntax errors} -body {
    pack append .pack .pack.blue {padx}
} -returnCodes error -result {wrong # args: "padx" option must be followed by screen distance}
test oldpack-8.19 {syntax errors} -body {
    pack append .pack .pack.blue {pady -2}
} -returnCodes error -result {bad pad value "-2": must be positive screen distance}
test oldpack-8.20 {syntax errors} -body {
    pack append .pack .pack.blue {pady}
} -returnCodes error -result {wrong # args: "pady" option must be followed by screen distance}
test oldpack-8.21 {syntax errors} -body {
    pack append .pack .pack.blue "\{abc"
} -returnCodes error -result {unmatched open brace in list}
test oldpack-8.22 {syntax errors} -body {
    pack append .pack .pack.blue frame
} -returnCodes error -result {wrong # args: "frame" option must be followed by anchor point}

# Test "pack info" command output.

test oldpack-9.1 {information output} -body {
    pack append .pack .pack.blue {top fillx frame n} \
    .pack.red {bottom filly frame s} .pack.green {left fill frame w} \
    .pack.violet {right expand frame e}
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor n -expand 0 -fill x -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor s -expand 0 -fill y -ipadx 0 -ipady 0 -padx 0 -pady 0 -side bottom} {-in .pack -anchor w -expand 0 -fill both -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left} {-in .pack -anchor e -expand 1 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side right}}
test oldpack-9.2 {information output} -body {
    pack append .pack .pack.blue {padx 10 frame nw} \
    .pack.red {pady 20 frame ne} .pack.green {frame se} \
    .pack.violet {frame sw}
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor nw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 5 -pady 0 -side top} {-in .pack -anchor ne -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 10 -side top} {-in .pack -anchor se -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor sw -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}
test oldpack-9.3 {information output} -body {
    pack append .pack .pack.blue {frame center} .pack.red {frame center} \
    .pack.green {frame c} .pack.violet {frame c}
    list [pack content .pack] [pack info .pack.blue] [pack info .pack.red] \
        [pack info .pack.green] [pack info .pack.violet]
} -result {{.pack.blue .pack.red .pack.green .pack.violet} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top} {-in .pack -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top}}

}
destroy .pack

# cleanup
cleanupTests
return

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to tests/option.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the option-handling facilities
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the option-handling facilities
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
test option-14.12 {error conditions} -body {
    option get .gorp.gorp a A
} -returnCodes error -result {bad window path name ".gorp.gorp"}


set option1 [file join [testsDirectory] option.file1]
test option-15.1 {database files} -body {
    option read non-existent
} -returnCodes error -result {couldn't open "non-existent": no such file or directory}
test option-15.2 {database files} -body {
    option read $option1
    option get . x1 color
} -result blue
test option-15.3 {database files} -constraints appNameIsTktest -body {
    option read $option1
    option get . x2 color







|
|







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
test option-14.12 {error conditions} -body {
    option get .gorp.gorp a A
} -returnCodes error -result {bad window path name ".gorp.gorp"}


set option1 [file join [testsDirectory] option.file1]
test option-15.1 {database files} -body {
    list [catch {option read non-existent} msg] [string tolower $msg]
} -result {1 {couldn't open "non-existent": no such file or directory}}
test option-15.2 {database files} -body {
    option read $option1
    option get . x1 color
} -result blue
test option-15.3 {database files} -constraints appNameIsTktest -body {
    option read $option1
    option get . x2 color
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431


432
433
434
435
436
437
438
439
440
441
    option read $option2
} -returnCodes error -result {missing colon on line 2}
set option3 [file join [testsDirectory] option.file3]
option read $option3
test option-15.11 {database files} {option get . {x 4} color} brówn

test option-16.1 {ReadOptionFile} -body {
    set option4 [makeFile {} option.file3]
    set file [open $option4 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4
} -result {true false}

set opt162val {label {
  foo bar
}
}
set opt162list [split $opt162val \n]

test option-16.2 {ticket 766ef52f3} {
    set option5 [makeFile {} option.file4]
    set file [open $option5 w]
    fconfigure $file -translation crlf
    puts $file "*notok: $opt162list"
    close $file
    option read $option5 userDefault
    option get . notok notok


} $opt162list

deleteWindows

# cleanup
cleanupTests
return










|
















|
|






>
>
|









400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    option read $option2
} -returnCodes error -result {missing colon on line 2}
set option3 [file join [testsDirectory] option.file3]
option read $option3
test option-15.11 {database files} {option get . {x 4} color} brówn

test option-16.1 {ReadOptionFile} -body {
    set option4 [makeFile {} option.file4]
    set file [open $option4 w]
    fconfigure $file -translation crlf
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4
} -result {true false}

set opt162val {label {
  foo bar
}
}
set opt162list [split $opt162val \n]

test option-16.2 {ticket 766ef52f3} -body {
    set option5 [makeFile {} option.file5]
    set file [open $option5 w]
    fconfigure $file -translation crlf
    puts $file "*notok: $opt162list"
    close $file
    option read $option5 userDefault
    option get . notok notok
} -cleanup {
    removeFile $option5
} -result $opt162list

deleteWindows

# cleanup
cleanupTests
return



Changes to tests/pack.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# This file is a Tcl script to test out the "pack" command of Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1993 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Create some test windows.

destroy .pack
toplevel .pack
wm geom .pack 300x200+0+0
wm minsize .pack 1 1
update idletasks
foreach i {a b c d} {
    frame .pack.$i
    label .pack.$i.label -text $i -relief raised
    place .pack.$i.label -relwidth 1.0 -relheight 1.0
}
.pack.a config -width 20 -height 40
.pack.b config -width 50 -height 30
.pack.c config -width 80 -height 80
.pack.d config -width 40 -height 30

test pack-1.1 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]





|







|


















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# This file is a Tcl script to test out the "pack" command of Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# 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
update idletasks
foreach i {a b c d} {
    frame .pack.$i
    label .pack.$i.label -text $i -relief raised
    place .pack.$i.label -relwidth 1.0 -relheight 1.0
}
.pack.a config -width 20 -height 40
.pack.b config -width 50 -height 30
.pack.c config -width 80 -height 80
.pack.d config -width 40 -height 30

test pack-1.1 {-side option} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side top
    pack .pack.b -expand yes -fill both
    update
    list [winfo geometry .pack.a] [winfo geometry .pack.b]
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
} -body {
    pack .pack.a -ipady {5 5}
} -returnCodes error -result {bad ipady value "5 5": must be positive screen distance}
test pack-12.29 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bac
} -returnCodes error -result {bad side "bac": must be top, bottom, left, or right}
test pack-12.30 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -lousy bac
} -returnCodes error -result {bad option "-lousy": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side}
test pack-12.31 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d







|







1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
} -body {
    pack .pack.a -ipady {5 5}
} -returnCodes error -result {bad ipady value "5 5": must be positive screen distance}
test pack-12.29 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -side bac
} -returnCodes error -result {bad side "bac": must be bottom, left, right, or top}
test pack-12.30 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
} -body {
    pack .pack.a -lousy bac
} -returnCodes error -result {bad option "-lousy": must be -after, -anchor, -before, -expand, -fill, -in, -ipadx, -ipady, -padx, -pady, or -side}
test pack-12.31 {command options and errors} -setup {
    pack forget .pack.a .pack.b .pack.c .pack.d
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
    place .pack.a -x 40 -y 10
    update
    winfo manager .pack.a
    winfo geometry .pack.a
    pack info .pack.a
} -returnCodes error -result {window ".pack.a" isn't packed}

if {[tk windowingsystem] == "win32"} {
    proc packUpdate {} {

	update
    }

} else {
    proc packUpdate {} {



    }
}









test pack-18.1 {unmap content when container unmapped} -constraints {
    tempNotPc failsOnUbuntu failsOnXQuarz
} -setup {
    eval destroy [winfo child .pack]




} -body {


















    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    # On the PC, when the width/height is configured while the window is
    # unmapped, the changes don't take effect until the window is remapped.
    # Who knows why?

    eval destroy [winfo child .pack]
    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update idletasks
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update idletasks
    lappend result [winfo width .pack.a ] [winfo height .pack.a] \
    [winfo ismapped .pack.a]
    wm deiconify .pack
    packUpdate

    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}

test pack-18.2 {unmap content when container unmapped} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    eval destroy [winfo child .pack]
} -body {
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100

    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
    pack .pack.a
    pack .pack.b -in .pack.a
    update idletasks
    set result [winfo ismapped .pack.b]
    wm iconify .pack
    lappend result [winfo ismapped .pack.b]
    .pack.b configure -width 100 -height 30
    update idletasks
    lappend result [winfo width .pack.b ] [winfo height .pack.b] \
    [winfo ismapped .pack.b]
    wm deiconify .pack
    packUpdate
    lappend result [winfo ismapped .pack.b]
} -result {1 0 100 30 0 1}

test pack-19.1 {test respect for internalborder} -setup {
    catch {eval pack forget [pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    pack .pack.lf.f -fill both -expand 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
} -cleanup {
    destroy .pack.l .pack.lf
} -result {196x188+2+10 177x186+5+7}
test pack-19.2 {test support for minreqsize} -setup {
    catch {eval pack forget [pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack {}
    frame .pack.l -width 150 -height 100
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f -width 20 -height 25







<
|
>
|
<
>
|
|
>
>
>
|
<
|
>
>
>
>
>
>
>
>
|
|

|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



<

|
<
<
<
<
<


|




|
<
<

|
>

|


|
<



<

>




|




|
|
|

|




|

















|







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
    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}


# Tests pack-18.1.1 and pack-18.2 are constrained with failsOnUbuntu
# because they are failing in the GitHub CI environment, using Linux Ubuntu.
# These tests are also constrained with failsOnXQuarz because they fail

# on macOS when building with clang --disable-aqua (which uses XQuartz)
# (this is the case both at GitHub CI and on a real Mac).
# Analysis shows that, on both cases, WaitForMapNotify is giving up on
# waiting for the MapNotify event that should show up when running
# 'wm iconify'. The timeout delay (2s) is exceeded without the unmapping
# having happened. The cause for this is unknown (see comments in WaitForMapNotify).


# Tests pack-18.1.* are constrained because on Windows, when the width/height
# is configured while the window is unmapped, the changes don't take
# effect until the window is remapped. This is apparently by design of the
# OS, and Tk accommodates this behavior (see UpdateGeometryInfo() and
# ConfigureTopLevel() in tkWinWm.c).
# pack-18.1.1 checks that, on Linux or macOS, width/height changes are taken
# into account while the window is unmapped.
# pack-18.1.2 checks that, on Windows, width/height changes are taken into
# account on window remapping.
test pack-18.1.1 {unmap content when container unmapped} -constraints {
    macOrUnix failsOnUbuntu failsOnXQuarz
} -setup {
    destroy {*}[winfo children .pack]
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).
    wm geometry .pack +100+100
} -body {
    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update
    lappend result [winfo width .pack.a] [winfo height .pack.a] \
            [winfo ismapped .pack.a]
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}
test pack-18.1.2 {unmap content when container unmapped} -constraints {
    win
} -setup {
    destroy {*}[winfo children .pack]
    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100
} -body {





    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update


    wm deiconify .pack
    update
    lappend result [winfo width .pack.a] [winfo height .pack.a]
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 1}

test pack-18.2 {unmap content when container unmapped} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    destroy {*}[winfo children .pack]

    # adjust the position of .pack before test to avoid a screen switch
    # that occurs with window managers that have desktops four times as big
    # as the screen (screen switch causes scale and other tests to fail).

    wm geometry .pack +100+100
} -body {
    frame .pack.a -relief raised -bd 2
    frame .pack.b -width 70 -height 30 -relief sunken -bd 2
    pack .pack.a
    pack .pack.b -in .pack.a
    update
    set result [winfo ismapped .pack.b]
    wm iconify .pack
    lappend result [winfo ismapped .pack.b]
    .pack.b configure -width 100 -height 30
    update
    lappend result [winfo width .pack.b] [winfo height .pack.b] \
            [winfo ismapped .pack.b]
    wm deiconify .pack
    update
    lappend result [winfo ismapped .pack.b]
} -result {1 0 100 30 0 1}

test pack-19.1 {test respect for internalborder} -setup {
    catch {pack forget {*}[pack content .pack]}
    destroy .pack.l .pack.lf
} -body {
    wm geometry .pack 200x200
    frame .pack.l -width 15 -height 10
    labelframe .pack.lf -labelwidget .pack.l
    pack .pack.lf -fill both -expand 1
    frame .pack.lf.f
    pack .pack.lf.f -fill both -expand 1
    update
    set res [list [winfo geometry .pack.lf.f]]
    .pack.lf configure -labelanchor e -padx 3 -pady 5
    update
    lappend res [winfo geometry .pack.lf.f]
} -cleanup {
    destroy .pack.l .pack.lf
} -result {196x188+2+10 177x186+5+7}
test pack-19.2 {test support for minreqsize} -setup {
    catch {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/panedwindow.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    .p configure -bd 4
    list [lindex [.p configure -bd] 4] [.p cget -bd]
} -cleanup {
    .p configure -bd [lindex [.p configure -bd] 3]
} -result {4 4}
test panedwindow-1.4 {configuration options: -bd (bad)} -body {
    .p configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.5 {configuration options: -bg (good)} -body {
    .p configure -bg #ff0000
    list [lindex [.p configure -bg] 4] [.p cget -bg]
} -cleanup {
    .p configure -bg [lindex [.p configure -bg] 3]
} -result {{#ff0000} #ff0000}
test panedwindow-1.6 {configuration options: -bg (bad)} -body {
    .p configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test panedwindow-1.7 {configuration options: -borderwidth (good)} -body {
    .p configure -borderwidth 1.3
    list [lindex [.p configure -borderwidth] 4] [.p cget -borderwidth]
} -cleanup {
    .p configure -borderwidth [lindex [.p configure -borderwidth] 3]
} -result {1 1}
test panedwindow-1.8 {configuration options: -borderwidth (bad)} -body {
    .p configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.9 {configuration options: -cursor (good)} -body {
    .p configure -cursor arrow
    list [lindex [.p configure -cursor] 4] [.p cget -cursor]
} -cleanup {
    .p configure -cursor [lindex [.p configure -cursor] 3]
} -result {arrow arrow}
test panedwindow-1.10 {configuration options: -cursor (bad)} -body {
    .p configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test panedwindow-1.11 {configuration options: -handlesize (good)} -body {
    .p configure -handlesize 20
    list [lindex [.p configure -handlesize] 4] [.p cget -handlesize]
} -cleanup {
    .p configure -handlesize [lindex [.p configure -handlesize] 3]
} -result {20 20}
test panedwindow-1.12 {configuration options: -handlesize (bad)} -body {
    .p configure -handlesize badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.13 {configuration options: -height (good)} -body {
    .p configure -height 20
    list [lindex [.p configure -height] 4] [.p cget -height]
} -cleanup {
    .p configure -height [lindex [.p configure -height] 3]
} -result {20 20}
test panedwindow-1.14 {configuration options: -height (bad)} -body {
    .p configure -height badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.15 {configuration options: -opaqueresize (good)} -body {
    .p configure -opaqueresize true
    list [lindex [.p configure -opaqueresize] 4] [.p cget -opaqueresize]
} -cleanup {
    .p configure -opaqueresize [lindex [.p configure -opaqueresize] 3]
} -result {1 1}
test panedwindow-1.16 {configuration options: -opaqueresize (bad)} -body {







|

















|

















|








|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    .p configure -bd 4
    list [lindex [.p configure -bd] 4] [.p cget -bd]
} -cleanup {
    .p configure -bd [lindex [.p configure -bd] 3]
} -result {4 4}
test panedwindow-1.4 {configuration options: -bd (bad)} -body {
    .p configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.5 {configuration options: -bg (good)} -body {
    .p configure -bg #ff0000
    list [lindex [.p configure -bg] 4] [.p cget -bg]
} -cleanup {
    .p configure -bg [lindex [.p configure -bg] 3]
} -result {{#ff0000} #ff0000}
test panedwindow-1.6 {configuration options: -bg (bad)} -body {
    .p configure -bg non-existent
} -returnCodes error -result {unknown color name "non-existent"}
test panedwindow-1.7 {configuration options: -borderwidth (good)} -body {
    .p configure -borderwidth 1.3
    list [lindex [.p configure -borderwidth] 4] [.p cget -borderwidth]
} -cleanup {
    .p configure -borderwidth [lindex [.p configure -borderwidth] 3]
} -result {1 1}
test panedwindow-1.8 {configuration options: -borderwidth (bad)} -body {
    .p configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.9 {configuration options: -cursor (good)} -body {
    .p configure -cursor arrow
    list [lindex [.p configure -cursor] 4] [.p cget -cursor]
} -cleanup {
    .p configure -cursor [lindex [.p configure -cursor] 3]
} -result {arrow arrow}
test panedwindow-1.10 {configuration options: -cursor (bad)} -body {
    .p configure -cursor badValue
} -returnCodes error -result {bad cursor spec "badValue"}
test panedwindow-1.11 {configuration options: -handlesize (good)} -body {
    .p configure -handlesize 20
    list [lindex [.p configure -handlesize] 4] [.p cget -handlesize]
} -cleanup {
    .p configure -handlesize [lindex [.p configure -handlesize] 3]
} -result {20 20}
test panedwindow-1.12 {configuration options: -handlesize (bad)} -body {
    .p configure -handlesize badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.13 {configuration options: -height (good)} -body {
    .p configure -height 20
    list [lindex [.p configure -height] 4] [.p cget -height]
} -cleanup {
    .p configure -height [lindex [.p configure -height] 3]
} -result {20 20}
test panedwindow-1.14 {configuration options: -height (bad)} -body {
    .p configure -height badValue
} -returnCodes error -result {expected screen distance or "" but got "badValue"}
test panedwindow-1.15 {configuration options: -opaqueresize (good)} -body {
    .p configure -opaqueresize true
    list [lindex [.p configure -opaqueresize] 4] [.p cget -opaqueresize]
} -cleanup {
    .p configure -opaqueresize [lindex [.p configure -opaqueresize] 3]
} -result {1 1}
test panedwindow-1.16 {configuration options: -opaqueresize (bad)} -body {
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    .p configure -proxyborderwidth 1.3
    list [lindex [.p configure -proxyborderwidth] 4] [.p cget -proxyborderwidth]
} -cleanup {
    .p configure -proxyborderwidth [lindex [.p configure -proxyborderwidth] 3]
} -result {1.3 1.3}
test panedwindow-1.22 {configuration options: -proxyborderwidth (bad)} -body {
    .p configure -proxyborderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.23 {configuration options: -proxyrelief (good)} -body {
    .p configure -proxyrelief groove
    list [lindex [.p configure -proxyrelief] 4] [.p cget -proxyrelief]
} -cleanup {
    .p configure -proxyrelief [lindex [.p configure -proxyrelief] 3]
} -result {groove groove}
test panedwindow-1.24 {configuration options: -proxyrelief (bad)} -body {
    .p configure -proxyrelief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test panedwindow-1.25 {configuration options: -relief (good)} -body {
    .p configure -relief groove
    list [lindex [.p configure -relief] 4] [.p cget -relief]
} -cleanup {
    .p configure -relief [lindex [.p configure -relief] 3]
} -result {groove groove}
test panedwindow-1.26 {configuration options: -relief (bad)} -body {







|








|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    .p configure -proxyborderwidth 1.3
    list [lindex [.p configure -proxyborderwidth] 4] [.p cget -proxyborderwidth]
} -cleanup {
    .p configure -proxyborderwidth [lindex [.p configure -proxyborderwidth] 3]
} -result {1.3 1.3}
test panedwindow-1.22 {configuration options: -proxyborderwidth (bad)} -body {
    .p configure -proxyborderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.23 {configuration options: -proxyrelief (good)} -body {
    .p configure -proxyrelief groove
    list [lindex [.p configure -proxyrelief] 4] [.p cget -proxyrelief]
} -cleanup {
    .p configure -proxyrelief [lindex [.p configure -proxyrelief] 3]
} -result {groove groove}
test panedwindow-1.24 {configuration options: -proxyrelief (bad)} -body {
    .p configure -proxyrelief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, sunken, or ""}
test panedwindow-1.25 {configuration options: -relief (good)} -body {
    .p configure -relief groove
    list [lindex [.p configure -relief] 4] [.p cget -relief]
} -cleanup {
    .p configure -relief [lindex [.p configure -relief] 3]
} -result {groove groove}
test panedwindow-1.26 {configuration options: -relief (bad)} -body {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    .p configure -sashpad 1.3
    list [lindex [.p configure -sashpad] 4] [.p cget -sashpad]
} -cleanup {
    .p configure -sashpad [lindex [.p configure -sashpad] 3]
} -result {1 1}
test panedwindow-1.30 {configuration options: -sashpad (bad)} -body {
    .p configure -sashpad badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.31 {configuration options: -sashrelief (good)} -body {
    .p configure -sashrelief groove
    list [lindex [.p configure -sashrelief] 4] [.p cget -sashrelief]
} -cleanup {
    .p configure -sashrelief [lindex [.p configure -sashrelief] 3]
} -result {groove groove}
test panedwindow-1.32 {configuration options: -sashrelief (bad)} -body {
    .p configure -sashrelief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test panedwindow-1.33 {configuration options: -sashwidth (good)} -body {
    .p configure -sashwidth 10
    list [lindex [.p configure -sashwidth] 4] [.p cget -sashwidth]
} -cleanup {
    .p configure -sashwidth [lindex [.p configure -sashwidth] 3]
} -result {10 10}
test panedwindow-1.34 {configuration options: -sashwidth (bad)} -body {
    .p configure -sashwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.35 {configuration options: -showhandle (good)} -body {
    .p configure -showhandle true
    list [lindex [.p configure -showhandle] 4] [.p cget -showhandle]
} -cleanup {
    .p configure -showhandle [lindex [.p configure -showhandle] 3]
} -result {1 1}
test panedwindow-1.36 {configuration options: -showhandle (bad)} -body {
    .p configure -showhandle foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.37 {configuration options: -width (good)} -body {
    .p configure -width 402
    list [lindex [.p configure -width] 4] [.p cget -width]
} -cleanup {
    .p configure -width [lindex [.p configure -width] 3]
} -result {402 402}
test panedwindow-1.38 {configuration options: -width (bad)} -body {
    .p configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}

test panedwindow-1.39 {configuration options: -after (good)} -body {
    .p paneconfigure .b -after .c
    list [lindex [.p paneconfigure .b -after] 4] \
        [.p panecget .b -after]
} -cleanup {
    .p paneconfig .b -after [lindex [.p paneconfig .b -after] 3]







|

















|

















|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    .p configure -sashpad 1.3
    list [lindex [.p configure -sashpad] 4] [.p cget -sashpad]
} -cleanup {
    .p configure -sashpad [lindex [.p configure -sashpad] 3]
} -result {1 1}
test panedwindow-1.30 {configuration options: -sashpad (bad)} -body {
    .p configure -sashpad badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.31 {configuration options: -sashrelief (good)} -body {
    .p configure -sashrelief groove
    list [lindex [.p configure -sashrelief] 4] [.p cget -sashrelief]
} -cleanup {
    .p configure -sashrelief [lindex [.p configure -sashrelief] 3]
} -result {groove groove}
test panedwindow-1.32 {configuration options: -sashrelief (bad)} -body {
    .p configure -sashrelief 1.5
} -returnCodes error -result {bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken}
test panedwindow-1.33 {configuration options: -sashwidth (good)} -body {
    .p configure -sashwidth 10
    list [lindex [.p configure -sashwidth] 4] [.p cget -sashwidth]
} -cleanup {
    .p configure -sashwidth [lindex [.p configure -sashwidth] 3]
} -result {10 10}
test panedwindow-1.34 {configuration options: -sashwidth (bad)} -body {
    .p configure -sashwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.35 {configuration options: -showhandle (good)} -body {
    .p configure -showhandle true
    list [lindex [.p configure -showhandle] 4] [.p cget -showhandle]
} -cleanup {
    .p configure -showhandle [lindex [.p configure -showhandle] 3]
} -result {1 1}
test panedwindow-1.36 {configuration options: -showhandle (bad)} -body {
    .p configure -showhandle foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.37 {configuration options: -width (good)} -body {
    .p configure -width 402
    list [lindex [.p configure -width] 4] [.p cget -width]
} -cleanup {
    .p configure -width [lindex [.p configure -width] 3]
} -result {402 402}
test panedwindow-1.38 {configuration options: -width (bad)} -body {
    .p configure -width badValue
} -returnCodes error -result {expected screen distance or "" but got "badValue"}

test panedwindow-1.39 {configuration options: -after (good)} -body {
    .p paneconfigure .b -after .c
    list [lindex [.p paneconfigure .b -after] 4] \
        [.p panecget .b -after]
} -cleanup {
    .p paneconfig .b -after [lindex [.p paneconfig .b -after] 3]
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    list [lindex [.p paneconfigure .b -height] 4] \
        [.p panecget .b -height]
} -cleanup {
    .p paneconfig .b -height [lindex [.p paneconfig .b -height] 3]
} -result {10 10}
test panedwindow-1.44 {configuration options: -height (bad)} -body {
    .p paneconfigure .b -height badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.45 {configuration options: -hide (good)} -body {
    .p paneconfigure .b -hide false
    list [lindex [.p paneconfigure .b -hide] 4] \
        [.p panecget .b -hide]
} -cleanup {
    .p paneconfig .b -hide [lindex [.p paneconfig .b -hide] 3]
} -result {0 0}
test panedwindow-1.46 {configuration options: -hide (bad)} -body {
    .p paneconfigure .b -hide foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.47 {configuration options: -minsize (good)} -body {
    .p paneconfigure .b -minsize 10
    list [lindex [.p paneconfigure .b -minsize] 4] \
        [.p panecget .b -minsize]
} -cleanup {
    .p paneconfig .b -minsize [lindex [.p paneconfig .b -minsize] 3]
} -result {10 10}
test panedwindow-1.48 {configuration options: -minsize (bad)} -body {
    .p paneconfigure .b -minsize badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.49 {configuration options: -padx (good)} -body {
    .p paneconfigure .b -padx 1.3
    list [lindex [.p paneconfigure .b -padx] 4] \
        [.p panecget .b -padx]
} -cleanup {
    .p paneconfig .b -padx [lindex [.p paneconfig .b -padx] 3]
} -result {1 1}
test panedwindow-1.50 {configuration options: -padx (bad)} -body {
    .p paneconfigure .b -padx badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.51 {configuration options: -pady (good)} -body {
    .p paneconfigure .b -pady 1.3
    list [lindex [.p paneconfigure .b -pady] 4] \
        [.p panecget .b -pady]
} -cleanup {
    .p paneconfig .b -pady [lindex [.p paneconfig .b -pady] 3]
} -result {1 1}
test panedwindow-1.52 {configuration options: -pady (bad)} -body {
    .p paneconfigure .b -pady badValue
} -returnCodes error -result {bad screen distance "badValue"}
test panedwindow-1.53 {configuration options: -sticky (good)} -body {
    .p paneconfigure .b -sticky nsew
    list [lindex [.p paneconfigure .b -sticky] 4] \
        [.p panecget .b -sticky]
} -cleanup {
    .p paneconfig .b -sticky [lindex [.p paneconfig .b -sticky] 3]
} -result {nesw nesw}







|



















|









|









|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    list [lindex [.p paneconfigure .b -height] 4] \
        [.p panecget .b -height]
} -cleanup {
    .p paneconfig .b -height [lindex [.p paneconfig .b -height] 3]
} -result {10 10}
test panedwindow-1.44 {configuration options: -height (bad)} -body {
    .p paneconfigure .b -height badValue
} -returnCodes error -result {expected screen distance or "" but got "badValue"}
test panedwindow-1.45 {configuration options: -hide (good)} -body {
    .p paneconfigure .b -hide false
    list [lindex [.p paneconfigure .b -hide] 4] \
        [.p panecget .b -hide]
} -cleanup {
    .p paneconfig .b -hide [lindex [.p paneconfig .b -hide] 3]
} -result {0 0}
test panedwindow-1.46 {configuration options: -hide (bad)} -body {
    .p paneconfigure .b -hide foo
} -returnCodes error -result {expected boolean value but got "foo"}
test panedwindow-1.47 {configuration options: -minsize (good)} -body {
    .p paneconfigure .b -minsize 10
    list [lindex [.p paneconfigure .b -minsize] 4] \
        [.p panecget .b -minsize]
} -cleanup {
    .p paneconfig .b -minsize [lindex [.p paneconfig .b -minsize] 3]
} -result {10 10}
test panedwindow-1.48 {configuration options: -minsize (bad)} -body {
    .p paneconfigure .b -minsize badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.49 {configuration options: -padx (good)} -body {
    .p paneconfigure .b -padx 1.3
    list [lindex [.p paneconfigure .b -padx] 4] \
        [.p panecget .b -padx]
} -cleanup {
    .p paneconfig .b -padx [lindex [.p paneconfig .b -padx] 3]
} -result {1 1}
test panedwindow-1.50 {configuration options: -padx (bad)} -body {
    .p paneconfigure .b -padx badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.51 {configuration options: -pady (good)} -body {
    .p paneconfigure .b -pady 1.3
    list [lindex [.p paneconfigure .b -pady] 4] \
        [.p panecget .b -pady]
} -cleanup {
    .p paneconfig .b -pady [lindex [.p paneconfig .b -pady] 3]
} -result {1 1}
test panedwindow-1.52 {configuration options: -pady (bad)} -body {
    .p paneconfigure .b -pady badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test panedwindow-1.53 {configuration options: -sticky (good)} -body {
    .p paneconfigure .b -sticky nsew
    list [lindex [.p paneconfigure .b -sticky] 4] \
        [.p panecget .b -sticky]
} -cleanup {
    .p paneconfig .b -sticky [lindex [.p paneconfig .b -sticky] 3]
} -result {nesw nesw}
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    list [lindex [.p paneconfigure .b -width] 4] \
        [.p panecget .b -width]
} -cleanup {
    .p paneconfig .b -width [lindex [.p paneconfig .b -width] 3]
} -result {10 10}
test panedwindow-1.58 {configuration options: -width (bad)} -body {
    .p paneconfigure .b -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
deleteWindows


test panedwindow-2.1 {panedwindow widget command} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p foo
} -cleanup {
	deleteWindows
} -returnCodes error -result {bad command "foo": must be add, cget, configure, forget, identify, panecget, paneconfigure, panes, proxy, or sash}


test panedwindow-3.1 {panedwindow panes subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list [list .b .c] [list .c]]


test panedwindow-4.1 {forget subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p forget
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p forget widget ?widget ...?"}
test panedwindow-4.2 {forget subcommand, forget one from start} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list {.b .c} .c]
test panedwindow-4.3 {forget subcommand, forget one from end} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .d
    update
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list {.b .c .d} {.b .c}]
test panedwindow-4.4 {forget subcommand, forget multiple} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .b .c
    update
    lappend result [.p panes]
} -cleanup {
	deleteWindows
} -result [list {.b .c .d} .d]
test panedwindow-4.5 {forget subcommand, panes are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    pack .p
    update
    set result [list [winfo ismapped .b] [winfo ismapped .c]]
    .p forget .b
    update
    lappend result [winfo ismapped .b] [winfo ismapped .c]
} -cleanup {
	deleteWindows
} -result [list 1 1 0 1]
test panedwindow-4.6 {forget subcommand, changes reqsize of panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [frame .g -width 20 -height 20]
    set result [list [winfo reqwidth .p]]
    .p forget .f
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result [list 44 20]


test panedwindow-5.1 {sash subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash option ?arg ...?"}
test panedwindow-5.2 {sash subcommand} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash foo
} -cleanup {
	deleteWindows
} -returnCodes error -result {bad option "foo": must be coord, dragto, mark, or place}


test panedwindow-6.1 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash coord
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash coord index"}
test panedwindow-6.2 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p sash coord 0
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-6.3 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash coord foo
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-6.4 {sash coord subcommand sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 22 0]
test panedwindow-6.5 {sash coord subcommand sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 50 0]
test panedwindow-6.6 {sash coord subcommand, sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 22]
test panedwindow-6.7 {sash coord subcommand, sashes correctly placed} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
	    [frame .p.f2 -width 20 -height 20] \
	    [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 50]
test panedwindow-6.8 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    list [catch {.p sash coord -1} msg] $msg \
        [catch {.p sash coord  0} msg] $msg \
        [catch {.p sash coord  1} msg] $msg
} -cleanup {
	deleteWindows
} -result [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.9 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f]
    list [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] $msg \
	    [catch {.p sash coord  1} msg] $msg
} -cleanup {
	deleteWindows
} -result [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.10 {sash coord subcommand, errors} -setup {
	deleteWindows
} -body {
    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f] [frame .p.f2]
    list [catch {.p sash coord -1} msg] $msg \
	    [catch {.p sash coord  0} msg] \
	    [catch {.p sash coord  1} msg] $msg \
	    [catch {.p sash coord  2} msg] $msg
} -cleanup {
	deleteWindows
} -result [list 1 "invalid sash index" 0 1 "invalid sash index" 1 "invalid sash index"]


test panedwindow-7.1 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash mark
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash mark index ?x y?"}
test panedwindow-7.2 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash mark foo
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.3 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash mark 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-7.4 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.5 {sash mark subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-7.6 {sash mark subcommand, mark defaults to 0 0} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0
} -cleanup {
	deleteWindows
} -result [list 0 0]
test panedwindow-7.7 {sash mark subcommand, set mark} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 10 10
    .p sash mark 0
} -cleanup {
	deleteWindows
} -result [list 10 10]


test panedwindow-8.1 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash dragto
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash dragto index x y"}
test panedwindow-8.2 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash dragto foo bar baz
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.3 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash dragto 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-8.4 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.5 {sash dragto subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}


test panedwindow-9.1 {sash mark/sash dragto interaction} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 20 10
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 30 0]
test panedwindow-9.2 {sash mark/sash dragto interaction} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] [button .p.c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 10 20
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 30]
test panedwindow-9.3 {sash mark/sash dragto, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash mark 0 20 10
    .p sash dragto 0 10 10
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 15 0]


test panedwindow-10.1 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash place
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash place index x y"}
test panedwindow-10.2 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash place foo bar baz
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.3 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p sash place 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-10.4 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.5 {sash place subcommand, errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-10.6 {sash place subcommand, moves sash} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 10 0
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 10 0]
test panedwindow-10.7 {sash place subcommand, moves sash} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 0 10
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 10]
test panedwindow-10.8 {sash place subcommand, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 15 0]
test panedwindow-10.9 {sash place subcommand, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg pink]
    .p sash place 0 2 0
} -cleanup {
	deleteWindows
} -returnCodes error -result {invalid sash index}


test panedwindow-11.1 {moving sash changes size of pane to left} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar] -sticky nsew
    .p sash place 0 30 0
    pack .p
    update
    winfo width .f
} -result 30
test panedwindow-11.2 {moving sash changes size of pane to right} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    pack .p
    update
    set result [winfo width .f2]
    .p sash place 0 30 0
    update
    lappend result [winfo width .f2]
} -cleanup {
	deleteWindows
} -result {20 10}
test panedwindow-11.3 {moving sash does not change reqsize of panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    .p sash place 0 30 0
    winfo reqwidth .p
} -result 44
test panedwindow-11.4 {moving sash changes size of pane above} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [button .c -text foobar] -sticky nsew
    .p sash place 0 0 20
    pack .p
    update
    set result [winfo height .f]
    set result
} -result 20
test panedwindow-11.5 {moving sash changes size of pane below} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    pack .p
    update
    set result [winfo height .f2]
    .p sash place 0 0 15
    update
    lappend result [winfo height .f2]
    set result
} -cleanup {
	deleteWindows
} -result {10 5}
test panedwindow-11.6 {moving sash does not change reqsize of panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .p]
    .p sash place 0 0 20
    lappend result [winfo reqheight .p]
    set result
} -cleanup {
	deleteWindows
} -result [list 24 24]
test panedwindow-11.7 {moving sash does not alter reqsize of widget} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .f]
    .p sash place 0 0 20
    lappend result [winfo reqheight .f]
} -cleanup {
	deleteWindows
} -result [list 10 10]
test panedwindow-11.8 {moving sash restricted to minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    pack .p
    update
    winfo width .f
} -result 15
test panedwindow-11.9 {moving sash restricted to minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 30] [button .c] -minsize 10
    .p sash place 0 0 5
    pack .p
    update
    winfo height .f
} -result 10
test panedwindow-11.10 {moving sash in unmapped window restricted to reqsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20]
    set result [list [.p sash coord 0]]
    .p sash place 0 100 0
    lappend result [.p sash coord 0]
} -cleanup {
	deleteWindows
} -result [list {20 0} {40 0}]
test panedwindow-11.11 {moving sash right pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    .p sash place 0 80 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result {{60 0} {64 0}}
test panedwindow-11.12 {moving sash left pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    .p sash place 1 0 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result {{0 0} {4 0}}
test panedwindow-11.13 {move sash in mapped window restricted to visible win} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 50
    update
    .p sash place 1 100 0
    update
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result {46 0}
test panedwindow-11.14 {move sash in mapped window restricted to visible win} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 100
    update
    .p sash place 1 200 0
    update
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result {96 0}
test panedwindow-11.15 {moving sash into "virtual" space on last pane increases reqsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
	    [frame .f3 -width 20 -height 30]
    place .p -width 100
    set result [winfo reqwidth .p]
    update
    .p sash place 1 200 0
    update
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {68 100}


test panedwindow-12.1 {horizontal panedwindow lays out widgets properly} -setup {
	deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update
    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}
    return $result
} -cleanup {
	deleteWindows
} -result [list 2 2 28 2 54 2]
test panedwindow-12.2 {vertical panedwindow lays out widgets properly} -setup {
	deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2 \
            -orient vertical
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update
    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}
    return $result
} -cleanup {
	deleteWindows
} -result [list 2 2 2 18 2 34]
test panedwindow-12.3 {horizontal panedwindow lays out widgets properly} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach {win color} {.p.f blue .p.f2 green} {
	    .p add [frame $win -width 20 -height 20 -bg $color] -padx 10 -pady 5 \
            -sticky ""




















    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    return $result
} -cleanup {
	deleteWindows
} -result [list 80 30 10 5 50 5 60 30 0 5 30 5]
test panedwindow-12.4 {vertical panedwindow lays out widgets properly} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach win {.p.f .p.f2} {
	.p add [frame $win -width 20 -height 20] -padx 10 -pady 5 -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    return $result
} -cleanup {
	deleteWindows
} -result [list 40 60 10 5 10 35 40 50 10 0 10 25]
test panedwindow-12.5 {panedwindow respects reqsize of panes when possible} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 30]
test panedwindow-12.6 {panedwindow takes explicit widget width over reqwidth} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -width 20 -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 20]
test panedwindow-12.7 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {20 40}
test panedwindow-12.8 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -height 15
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {20 20}
test panedwindow-12.9 {panedwindow pane width overrides widget width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 10 0
    pack .p
    update
    set result [winfo width .p.f]
    .p paneconfigure .p.f -width 30
    lappend result [winfo width .p.f]
} -cleanup {
	deleteWindows
} -result [list 10 10]
test panedwindow-12.10 {panedwindow respects reqsize of panes when possible} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 30]
test panedwindow-12.11 {panedwindow takes explicit height over reqheight} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -height 20 -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 20 20]
test panedwindow-12.12 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {20 40}
test panedwindow-12.13 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -width 15
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result {20 20}
test panedwindow-12.14 {panedwindow pane height overrides widget width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 0 10
    pack .p
    update
    set result [winfo height .p.f]
    .p paneconfigure .p.f -height 30
    lappend result [winfo height .p.f]
} -cleanup {
	deleteWindows
} -result [list 10 10]


test panedwindow-13.1 {PanestructureProc, widget yields managements} -setup {
	deleteWindows
} -body {
    # Check that the panedwindow correctly yields geometry management of
    # a pane when the pane is destroyed.

    # This test should not cause a core dump, and it should not cause
    # a memory leak.
    panedwindow .p
    .p add [button .b]
    destroy .p
    pack .b
    destroy .b
    set result ""
} -result {}
test panedwindow-13.2 {PanedWindowLostPaneProc, widget yields management} -setup {
	deleteWindows
} -body {
    # Check that the paned window correctly yields geometry management of
    # a pane when some other geometry manager steals the pane from us.

    # This test should not cause a core dump, and it should not cause a
    # memory leak.
    panedwindow .p







|




|




|




|








|




|




|


|








|


|










|


|










|


|











|


|







|




|




|


|




|




|




|


|




|


|




|


|



|
|


|


|



|
|


|


|




|
|


|


|




|
|


|


|






|


|





|
|

|


|





|
|
|

|




|




|


|




|


|




|


|





|


|





|


|





|


|






|




|




|


|




|


|




|


|





|


|





|




|







|


|








|


|







|




|




|


|




|


|




|


|





|


|





|


|






|


|






|


|






|


|





|




|









|










|


|







|











|












|


|









|


|








|


|









|










|







|


|



|



|


|



|



|


|



|






|


|



|






|


|



|







|




|









|


|










|


|



|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|










|


|










|


|







|


|








|


|










|


|










|


|










|


|








|


|









|


|











|




|














|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    list [lindex [.p paneconfigure .b -width] 4] \
        [.p panecget .b -width]
} -cleanup {
    .p paneconfig .b -width [lindex [.p paneconfig .b -width] 3]
} -result {10 10}
test panedwindow-1.58 {configuration options: -width (bad)} -body {
    .p paneconfigure .b -width badValue
} -returnCodes error -result {expected screen distance or "" but got "badValue"}
deleteWindows


test panedwindow-2.1 {panedwindow widget command} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad command "foo": must be add, cget, configure, forget, identify, panecget, paneconfigure, panes, proxy, or sash}


test panedwindow-3.1 {panedwindow panes subcommand} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]
} -cleanup {
    deleteWindows
} -result [list [list .b .c] [list .c]]


test panedwindow-4.1 {forget subcommand} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p forget
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p forget widget ?widget ...?"}
test panedwindow-4.2 {forget subcommand, forget one from start} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    set result [list [.p panes]]
    .p forget .b
    lappend result [.p panes]
} -cleanup {
    deleteWindows
} -result [list {.b .c} .c]
test panedwindow-4.3 {forget subcommand, forget one from end} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .d
    update
    lappend result [.p panes]
} -cleanup {
    deleteWindows
} -result [list {.b .c .d} {.b .c}]
test panedwindow-4.4 {forget subcommand, forget multiple} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    set result [list [.p panes]]
    .p forget .b .c
    update
    lappend result [.p panes]
} -cleanup {
    deleteWindows
} -result [list {.b .c .d} .d]
test panedwindow-4.5 {forget subcommand, panes are unmapped} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    pack .p
    update
    set result [list [winfo ismapped .b] [winfo ismapped .c]]
    .p forget .b
    update
    lappend result [winfo ismapped .b] [winfo ismapped .c]
} -cleanup {
    deleteWindows
} -result [list 1 1 0 1]
test panedwindow-4.6 {forget subcommand, changes reqsize of panedwindow} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [frame .g -width 20 -height 20]
    set result [list [winfo reqwidth .p]]
    .p forget .f
    lappend result [winfo reqwidth .p]
} -cleanup {
    deleteWindows
} -result [list 44 20]


test panedwindow-5.1 {sash subcommand} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash option ?arg ...?"}
test panedwindow-5.2 {sash subcommand} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad option "foo": must be coord, dragto, mark, or place}


test panedwindow-6.1 {sash coord subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash coord
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash coord index"}
test panedwindow-6.2 {sash coord subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p sash coord 0
} -cleanup {
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-6.3 {sash coord subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash coord foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-6.4 {sash coord subcommand sashes correctly placed} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 22 0]
test panedwindow-6.5 {sash coord subcommand sashes correctly placed} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 50 0]
test panedwindow-6.6 {sash coord subcommand, sashes correctly placed} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 22]
test panedwindow-6.7 {sash coord subcommand, sashes correctly placed} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] \
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 0 50]
test panedwindow-6.8 {sash coord subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    list [catch {.p sash coord -1} msg] $msg \
        [catch {.p sash coord  0} msg] $msg \
        [catch {.p sash coord  1} msg] $msg
} -cleanup {
    deleteWindows
} -result [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.9 {sash coord subcommand, errors} -setup {
    deleteWindows
} -body {
    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f]
    list [catch {.p sash coord -1} msg] $msg \
            [catch {.p sash coord  0} msg] $msg \
            [catch {.p sash coord  1} msg] $msg
} -cleanup {
    deleteWindows
} -result [list 1 "invalid sash index" 1 "invalid sash index" 1 "invalid sash index"]
test panedwindow-6.10 {sash coord subcommand, errors} -setup {
    deleteWindows
} -body {
    # There are no sashes until you have 2 panes
    panedwindow .p
    .p add [frame .p.f] [frame .p.f2]
    list [catch {.p sash coord -1} msg] $msg \
            [catch {.p sash coord  0} msg] \
            [catch {.p sash coord  1} msg] $msg \
            [catch {.p sash coord  2} msg] $msg
} -cleanup {
    deleteWindows
} -result [list 1 "invalid sash index" 0 1 "invalid sash index" 1 "invalid sash index"]


test panedwindow-7.1 {sash mark subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash mark
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash mark index ?x y?"}
test panedwindow-7.2 {sash mark subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash mark foo
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.3 {sash mark subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash mark 0 foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-7.4 {sash mark subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.5 {sash mark subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 0 bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-7.6 {sash mark subcommand, mark defaults to 0 0} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0
} -cleanup {
    deleteWindows
} -result [list 0 0]
test panedwindow-7.7 {sash mark subcommand, set mark} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 10 10
    .p sash mark 0
} -cleanup {
    deleteWindows
} -result [list 10 10]


test panedwindow-8.1 {sash dragto subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash dragto
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash dragto index x y"}
test panedwindow-8.2 {sash dragto subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash dragto foo bar baz
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.3 {sash dragto subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash dragto 0 foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-8.4 {sash dragto subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.5 {sash dragto subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 0 bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}


test panedwindow-9.1 {sash mark/sash dragto interaction} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 20 10
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 30 0]
test panedwindow-9.2 {sash mark/sash dragto interaction} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical \
            -showhandle false
    .p add [frame .p.f -width 20 -height 20] [button .p.c -text foobar]
    .p sash mark 0 10 10
    .p sash dragto 0 10 20
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 30]
test panedwindow-9.3 {sash mark/sash dragto, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash mark 0 20 10
    .p sash dragto 0 10 10
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 15 0]


test panedwindow-10.1 {sash place subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash place
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash place index x y"}
test panedwindow-10.2 {sash place subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash place foo bar baz
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.3 {sash place subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p sash place 0 foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-10.4 {sash place subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.5 {sash place subcommand, errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 0 bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-10.6 {sash place subcommand, moves sash} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 10 0
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 10 0]
test panedwindow-10.7 {sash place subcommand, moves sash} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -orient vertical
    .p add [frame .f -width 20 -height 20] [button .c]
    .p sash place 0 0 10
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 10]
test panedwindow-10.8 {sash place subcommand, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 15 0]
test panedwindow-10.9 {sash place subcommand, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg pink]
    .p sash place 0 2 0
} -cleanup {
    deleteWindows
} -returnCodes error -result {invalid sash index}


test panedwindow-11.1 {moving sash changes size of pane to left} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4 -showhandle false
    .p add [frame .f -width 20 -height 20] [button .c -text foobar] -sticky nsew
    .p sash place 0 30 0
    pack .p
    update
    winfo width .f
} -result 30
test panedwindow-11.2 {moving sash changes size of pane to right} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    pack .p
    update
    set result [winfo width .f2]
    .p sash place 0 30 0
    update
    lappend result [winfo width .f2]
} -cleanup {
    deleteWindows
} -result {20 10}
test panedwindow-11.3 {moving sash does not change reqsize of panedwindow} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [frame .f2 -width 20 -height 20]
    .p sash place 0 30 0
    winfo reqwidth .p
} -result 44
test panedwindow-11.4 {moving sash changes size of pane above} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [button .c -text foobar] -sticky nsew
    .p sash place 0 0 20
    pack .p
    update
    set result [winfo height .f]
    set result
} -result 20
test panedwindow-11.5 {moving sash changes size of pane below} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    pack .p
    update
    set result [winfo height .f2]
    .p sash place 0 0 15
    update
    lappend result [winfo height .f2]
    set result
} -cleanup {
    deleteWindows
} -result {10 5}
test panedwindow-11.6 {moving sash does not change reqsize of panedwindow} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .p]
    .p sash place 0 0 20
    lappend result [winfo reqheight .p]
    set result
} -cleanup {
    deleteWindows
} -result [list 24 24]
test panedwindow-11.7 {moving sash does not alter reqsize of widget} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 10] [frame .f2 -width 20 -height 10]
    set result [winfo reqheight .f]
    .p sash place 0 0 20
    lappend result [winfo reqheight .f]
} -cleanup {
    deleteWindows
} -result [list 10 10]
test panedwindow-11.8 {moving sash restricted to minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 20] [button .c] -minsize 15
    .p sash place 0 10 0
    pack .p
    update
    winfo width .f
} -result 15
test panedwindow-11.9 {moving sash restricted to minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .f -width 20 -height 30] [button .c] -minsize 10
    .p sash place 0 0 5
    pack .p
    update
    winfo height .f
} -result 10
test panedwindow-11.10 {moving sash in unmapped window restricted to reqsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20]
    set result [list [.p sash coord 0]]
    .p sash place 0 100 0
    lappend result [.p sash coord 0]
} -cleanup {
    deleteWindows
} -result [list {20 0} {40 0}]
test panedwindow-11.11 {moving sash right pushes other sashes} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
            [frame .f3 -width 20 -height 30]
    .p sash place 0 80 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{60 0} {64 0}}
test panedwindow-11.12 {moving sash left pushes other sashes} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
            [frame .f3 -width 20 -height 30]
    .p sash place 1 0 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result {{0 0} {4 0}}
test panedwindow-11.13 {move sash in mapped window restricted to visible win} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
            [frame .f3 -width 20 -height 30]
    place .p -width 50
    update
    .p sash place 1 100 0
    update
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result {46 0}
test panedwindow-11.14 {move sash in mapped window restricted to visible win} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
            [frame .f3 -width 20 -height 30]
    place .p -width 100
    update
    .p sash place 1 200 0
    update
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result {96 0}
test panedwindow-11.15 {moving sash into "virtual" space on last pane increases reqsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .f -width 20 -height 30] [frame .f2 -width 20 -height 20] \
            [frame .f3 -width 20 -height 30]
    place .p -width 100
    set result [winfo reqwidth .p]
    update
    .p sash place 1 200 0
    update
    lappend result [winfo reqwidth .p]
} -cleanup {
    deleteWindows
} -result {68 100}


test panedwindow-12.1 {horizontal panedwindow lays out widgets properly} -setup {
    deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update
    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}
    return $result
} -cleanup {
    deleteWindows
} -result [list 2 2 28 2 54 2]
test panedwindow-12.2 {vertical panedwindow lays out widgets properly} -setup {
    deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 2 -sashpad 2 -sashwidth 2 \
            -orient vertical
    foreach win {.p.f .p.f2 .p.f3} {.p add [frame $win -width 20 -height 10]}
    pack .p
    update
    foreach w [.p panes] {lappend result [winfo x $w] [winfo y $w]}
    return $result
} -cleanup {
    deleteWindows
} -result [list 2 2 2 18 2 34]
test panedwindow-12.3 {horizontal panedwindow lays out widgets properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach {win color} {.p.f blue .p.f2 green} {
        .p add [frame $win -width 20 -height 20 -bg $color] -padx 10 -pady 5 \
                -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    return $result
} -cleanup {
    deleteWindows
} -result [list 80 30 10 5 50 5 60 30 0 5 30 5]
test panedwindow-12.4 {vertical panedwindow lays out widgets properly} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach win {.p.f .p.f2} {
        .p add [frame $win -width 20 -height 20] -padx 10 -pady 5 -sticky ""
    }
    pack .p
    update
    set result [list [winfo reqwidth .p] [winfo reqheight .p]]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    .p paneconfigure .p.f -padx 0 -pady 0
    update
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    foreach win {.p.f .p.f2} {lappend result [winfo x $win] [winfo y $win]}
    return $result
} -cleanup {
    deleteWindows




















} -result [list 40 60 10 5 10 35 40 50 10 0 10 25]
test panedwindow-12.5 {panedwindow respects reqsize of panes when possible} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
    deleteWindows
} -result [list 20 30]
test panedwindow-12.6 {panedwindow takes explicit widget width over reqwidth} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -width 20 -sticky ""
    place .p -width 40
    update
    set result [list [winfo width .p.f]]
    .p.f configure -width 30
    update
    lappend result [winfo width .p.f]
} -cleanup {
    deleteWindows
} -result [list 20 20]
test panedwindow-12.7 {horizontal panedwindow reqheight is max pane height} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 40}
test panedwindow-12.8 {horizontal panedwindow reqheight is max pane height} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -height 15
    set result [winfo reqheight .p]
    .p.f config -height 40
    lappend result [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {20 20}
test panedwindow-12.9 {panedwindow pane width overrides widget width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 10 0
    pack .p
    update
    set result [winfo width .p.f]
    .p paneconfigure .p.f -width 30
    lappend result [winfo width .p.f]
} -cleanup {
    deleteWindows
} -result [list 10 10]
test panedwindow-12.10 {panedwindow respects reqsize of panes when possible} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result [list 20 30]
test panedwindow-12.11 {panedwindow takes explicit height over reqheight} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    .p add [frame .p.f -width 20 -height 20] -height 20 -sticky ""
    place .p -height 40
    update
    set result [list [winfo height .p.f]]
    .p.f configure -height 30
    update
    lappend result [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result [list 20 20]
test panedwindow-12.12 {vertical panedwindow reqwidth is max pane width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    .p add [frame .p.f -width 20 -height 20] [frame .p.f2 -width 20 -height 20]
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
    deleteWindows
} -result {20 40}
test panedwindow-12.13 {vertical panedwindow reqwidth is max pane width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p paneconfigure .p.f -width 15
    set result [winfo reqwidth .p]
    .p.f config -width 40
    lappend result [winfo reqwidth .p]
} -cleanup {
    deleteWindows
} -result {20 20}
test panedwindow-12.14 {panedwindow pane height overrides widget width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 4 \
            -orient vertical
    foreach win {.p.f .p.f2} {.p add [frame $win -width 20 -height 20]}
    .p sash place 0 0 10
    pack .p
    update
    set result [winfo height .p.f]
    .p paneconfigure .p.f -height 30
    lappend result [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result [list 10 10]


test panedwindow-13.1 {PanestructureProc, widget yields managements} -setup {
    deleteWindows
} -body {
    # Check that the panedwindow correctly yields geometry management of
    # a pane when the pane is destroyed.

    # This test should not cause a core dump, and it should not cause
    # a memory leak.
    panedwindow .p
    .p add [button .b]
    destroy .p
    pack .b
    destroy .b
    set result ""
} -result {}
test panedwindow-13.2 {PanedWindowLostPaneProc, widget yields management} -setup {
    deleteWindows
} -body {
    # Check that the paned window correctly yields geometry management of
    # a pane when some other geometry manager steals the pane from us.

    # This test should not cause a core dump, and it should not cause a
    # memory leak.
    panedwindow .p
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
















1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
















1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
    list news [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {news 0 0 40 40}


test panedwindow-16.1 {setting minsize when pane is too small snaps width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f -height 20 -width 20 -bg red]
    set result [winfo reqwidth .p]
    .p paneconfigure .p.f -minsize 40
    lappend result [winfo reqwidth .p]
} -cleanup {
	deleteWindows
} -result [list 20 40]


test panedwindow-17.1 {MoveSash, move right} -setup {
	deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 30 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
	deleteWindows
} -result [list 42 42 {30 0}]
test panedwindow-17.2 {MoveSash, move right (unmapped) clipped by reqwidth} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 40 0]
test panedwindow-17.3 {MoveSash, move right (mapped, width < reqwidth) clipped by width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width < reqwidth
    place .p -x 0 -y 0 -width 32
    update

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 30 0]
test panedwindow-17.4 {MoveSash, move right (mapped, width > reqwidth) clipped by width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -width 102
    update

    .p sash place 0 200 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 100 0]
test panedwindow-17.5 {MoveSash, move right respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 30 0]
test panedwindow-17.6 {MoveSash, move right respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 40 0]
test panedwindow-17.7 {MoveSash, move right pushes other sashes} -setup {
	deleteWindows
















} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 62 0]
test panedwindow-17.8 {MoveSash, move right pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 52 0]
test panedwindow-17.9 {MoveSash, move right respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -padx 5
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 50 0]
test panedwindow-17.10 {MoveSash, move right, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 0 50 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result [list [list 50 0] [list 52 0]]
test panedwindow-17.11 {MoveSash, move left} -setup {
	deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 10 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
	deleteWindows
} -result [list 42 42 {10 0}]
test panedwindow-17.12 {MoveSash, move left, can't move outside of window} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 -100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 0]
test panedwindow-17.13 {MoveSash, move left respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 10 0]
test panedwindow-17.14 {MoveSash, move left respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 22 0]
test panedwindow-17.15 {MoveSash, move left pushes other sashes} -setup {
	deleteWindows
















} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 0]
test panedwindow-17.16 {MoveSash, move left pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 10 0]
test panedwindow-17.17 {MoveSash, move left respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -padx 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 42 0]
test panedwindow-17.18 {MoveSash, move left, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue green} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 1 10 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result [list [list 8 0] [list 10 0]]


test panedwindow-18.1 {MoveSash, move down} -setup {
	deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 30

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
	deleteWindows
} -result [list 42 42 {0 30}]
test panedwindow-18.2 {MoveSash, move down (unmapped) clipped by reqheight} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the reqheight of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 40]
test panedwindow-18.3 {MoveSash, move down (mapped, height < reqheight) clipped by height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a height < reqheight
    place .p -x 0 -y 0 -height 32
    update

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the visible height of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 30]
test panedwindow-18.4 {MoveSash, move down (mapped, height > reqheight) clipped by height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -height 102
    update

    .p sash place 0 0 200

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 100]
test panedwindow-18.5 {MoveSash, move down respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 30]
test panedwindow-18.6 {MoveSash, move down respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 40]
test panedwindow-18.7 {MoveSash, move down pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 62]
test panedwindow-18.8 {MoveSash, move down pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 52]
test panedwindow-18.9 {MoveSash, move down respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -pady 5
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 50]
test panedwindow-18.10 {MoveSash, move right, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 0 0 50

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result [list [list 0 50] [list 0 52]]
test panedwindow-18.11 {MoveSash, move up} -setup {
	deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 10

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
	deleteWindows
} -result [list 42 42 {0 10}]
test panedwindow-18.12 {MoveSash, move up, can't move outside of window} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 -100

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 0]
test panedwindow-18.13 {MoveSash, move up respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 10]
test panedwindow-18.14 {MoveSash, move up respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 22]
test panedwindow-18.15 {MoveSash, move up pushes other sashes} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 0]
test panedwindow-18.16 {MoveSash, move up pushes other sashes, respects minsize} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
	deleteWindows
} -result [list 0 10]
test panedwindow-18.17 {MoveSash, move up respects minsize, exludes pad} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize 10 -pady 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
	deleteWindows
} -result [list 0 42]
test panedwindow-18.18 {MoveSash, move up, negative minsize becomes 0} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue green} {
	    .p add [frame $w -height 20 -width 20 -bg $c] \
		    -sticky nsew -minsize -50
    }

    .p sash place 1 0 10

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
} -result [list [list 0 8] [list 0 10]]


# The following tests check that the panedwindow is correctly computing its
# geometry based on the various configuration options that can affect the
# geometry.

test panedwindow-19.1 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	    .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.2 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	    .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.3 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
	    .p add [frame $w -width 20 -height 20 -bg blue] -pady 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 60] [list 60 80]]

test panedwindow-19.4 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.5 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.6 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
	.p add [frame $w -width 20 -height 20 -bg blue] -padx 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
	deleteWindows
} -result [list [list 60 60] [list 80 60]]

test panedwindow-19.7 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should







|







|




|




|













|


|



|








|


|



|












|


|



|












|


|



|








|


|



|







|


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|



|
|








|


|



|
|








|


|




|













|


|



|








|


|



|








|


|



|







|


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|



|
|








|


|



|
|








|




|





|













|


|




|








|


|




|












|


|




|












|


|




|








|


|




|








|


|




|








|


|




|








|


|




|
|








|


|




|
|








|


|





|













|


|




|








|


|




|








|


|




|







|


|




|








|


|




|








|


|




|
|








|


|




|
|








|








|



|





|



|



|





|



|



|





|



|




|





|



|




|





|



|




|





|







1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
















1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
















1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
    list news [winfo x .p.f] [winfo y .p.f]  [winfo width .p.f] [winfo height .p.f]
} -cleanup {
    deleteWindows
} -result {news 0 0 40 40}


test panedwindow-16.1 {setting minsize when pane is too small snaps width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f -height 20 -width 20 -bg red]
    set result [winfo reqwidth .p]
    .p paneconfigure .p.f -minsize 40
    lappend result [winfo reqwidth .p]
} -cleanup {
    deleteWindows
} -result [list 20 40]


test panedwindow-17.1 {MoveSash, move right} -setup {
    deleteWindows
    set result {}
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 30 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
    deleteWindows
} -result [list 42 42 {30 0}]
test panedwindow-17.2 {MoveSash, move right (unmapped) clipped by reqwidth} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 40 0]
test panedwindow-17.3 {MoveSash, move right (mapped, width < reqwidth) clipped by width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width < reqwidth
    place .p -x 0 -y 0 -width 32
    update

    .p sash place 0 100 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 30 0]
test panedwindow-17.4 {MoveSash, move right (mapped, width > reqwidth) clipped by width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -width 102
    update

    .p sash place 0 200 0

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 100 0]
test panedwindow-17.5 {MoveSash, move right respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 30 0]
test panedwindow-17.6 {MoveSash, move right respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 40 0]
test panedwindow-17.7 {MoveSash, move right pushes other sashes} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 62 0]
test panedwindow-17.8 {MoveSash, move right pushes other sashes, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
    deleteWindows
















} -result [list 52 0]
test panedwindow-17.9 {MoveSash, move right respects minsize, exludes pad} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize 10 -padx 5
    }

    .p sash place 0 100 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 50 0]
test panedwindow-17.10 {MoveSash, move right, negative minsize becomes 0} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize -50
    }

    .p sash place 0 50 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result [list [list 50 0] [list 52 0]]
test panedwindow-17.11 {MoveSash, move left} -setup {
    deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqwidth .p]

    .p sash place 0 10 0

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqwidth .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
    deleteWindows
} -result [list 42 42 {10 0}]
test panedwindow-17.12 {MoveSash, move left, can't move outside of window} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 -100 0

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 0]
test panedwindow-17.13 {MoveSash, move left respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 10 0]
test panedwindow-17.14 {MoveSash, move left respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 22 0]
test panedwindow-17.15 {MoveSash, move left pushes other sashes} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 0]
test panedwindow-17.16 {MoveSash, move left pushes other sashes, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
















} -result [list 10 0]
test panedwindow-17.17 {MoveSash, move left respects minsize, exludes pad} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize 10 -padx 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 42 0]
test panedwindow-17.18 {MoveSash, move left, negative minsize becomes 0} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    foreach w {.f1 .f2 .f3} c {red blue green} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize -50
    }

    .p sash place 1 10 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result [list [list 8 0] [list 10 0]]


test panedwindow-18.1 {MoveSash, move down} -setup {
    deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 30

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
    deleteWindows
} -result [list 42 42 {0 30}]
test panedwindow-18.2 {MoveSash, move down (unmapped) clipped by reqheight} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the reqheight of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 40]
test panedwindow-18.3 {MoveSash, move down (mapped, height < reqheight) clipped by height} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a height < reqheight
    place .p -x 0 -y 0 -height 32
    update

    .p sash place 0 0 100

    # Get the new sash coord; it should be clipped by the visible height of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 30]
test panedwindow-18.4 {MoveSash, move down (mapped, height > reqheight) clipped by height} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Put the panedwindow up on the display and give it a width > reqwidth
    place .p -x 0 -y 0 -height 102
    update

    .p sash place 0 0 200

    # Get the new sash coord; it should be clipped by the visible width of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 100]
test panedwindow-18.5 {MoveSash, move down respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 30]
test panedwindow-18.6 {MoveSash, move down respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 40]
test panedwindow-18.7 {MoveSash, move down pushes other sashes} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 0 62]
test panedwindow-18.8 {MoveSash, move down pushes other sashes, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 0 52]
test panedwindow-18.9 {MoveSash, move down respects minsize, exludes pad} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize 10 -pady 5
    }

    .p sash place 0 0 100

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 50]
test panedwindow-18.10 {MoveSash, move right, negative minsize becomes 0} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize -50
    }

    .p sash place 0 0 50

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result [list [list 0 50] [list 0 52]]
test panedwindow-18.11 {MoveSash, move up} -setup {
    deleteWindows
} -body {
    set result {}
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    # Get the requested width of the paned window
    lappend result [winfo reqheight .p]

    .p sash place 0 0 10

    # Get the reqwidth again, to make sure it hasn't changed
    lappend result [winfo reqheight .p]

    # Check that the sash moved
    lappend result [.p sash coord 0]
} -cleanup {
    deleteWindows
} -result [list 42 42 {0 10}]
test panedwindow-18.12 {MoveSash, move up, can't move outside of window} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 0 0 -100

    # Get the new sash coord; it should be clipped by the reqwidth of
    # the panedwindow.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 0]
test panedwindow-18.13 {MoveSash, move up respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 0 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 10]
test panedwindow-18.14 {MoveSash, move up respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 0 22]
test panedwindow-18.15 {MoveSash, move up pushes other sashes} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 0]
test panedwindow-18.16 {MoveSash, move up pushes other sashes, respects minsize} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] -sticky nsew -minsize 10
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible while
    # respecting minsizes.
    .p sash coord 0
} -cleanup {
    deleteWindows
} -result [list 0 10]
test panedwindow-18.17 {MoveSash, move up respects minsize, exludes pad} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize 10 -pady 5
    }

    .p sash place 1 0 0

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    .p sash coord 1
} -cleanup {
    deleteWindows
} -result [list 0 42]
test panedwindow-18.18 {MoveSash, move up, negative minsize becomes 0} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    foreach w {.f1 .f2 .f3} c {red blue green} {
        .p add [frame $w -height 20 -width 20 -bg $c] \
                -sticky nsew -minsize -50
    }

    .p sash place 1 0 10

    # Get the new sash coord; it should have moved as far as possible,
    # respecting minsizes.
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
    deleteWindows
} -result [list [list 0 8] [list 0 10]]


# The following tests check that the panedwindow is correctly computing its
# geometry based on the various configuration options that can affect the
# geometry.

test panedwindow-19.1 {ComputeGeometry, reqheight taken from widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
    deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.2 {ComputeGeometry, reqheight taken from widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
    deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.3 {ComputeGeometry, reqheight taken from widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -pady 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -height 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
    deleteWindows
} -result [list [list 60 60] [list 60 80]]

test panedwindow-19.4 {ComputeGeometry, reqwidth taken from widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .f3 configure -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
    deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.5 {ComputeGeometry, reqwidth taken from widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue]
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
    deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.6 {ComputeGeometry, reqwidth taken from widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 0 \
            -orient vertical
    foreach w {.f1 .f2 .f3} {
        .p add [frame $w -width 20 -height 20 -bg blue] -padx 20
    }
    set result [list [list [winfo reqwidth .p] [winfo reqheight .p]]]
    .p paneconfigure .f3 -width 40
    lappend result [list [winfo reqwidth .p] [winfo reqheight .p]]
} -cleanup {
    deleteWindows
} -result [list [list 60 60] [list 80 60]]

test panedwindow-19.7 {ComputeGeometry, one pane, reqsize set properly} -setup {
    deleteWindows
} -body {
    # With just one pane, sashpad and sashwidth should not
    # affect the panedwindow's geometry, since no sash should
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 71 20 20} {5 129 20 20}}


test panedwindow-20.1 {destroyed widgets are removed from panedwindow} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg blue]
    destroy .f
    .p panes
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-20.2 {destroyed pane causes geometry recomputation} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    destroy .f
    winfo reqwidth .p
} -cleanup {
    deleteWindows
} -result 20


test panedwindow-21.1 {ArrangePanes, extra space is given to the last pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 100 -x 0 -y 0
    update
    winfo width .f2
} -cleanup {
    deleteWindows
} -result 78
test panedwindow-21.2 {ArrangePanes, extra space is given to the last pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 100 -x 0 -y 0
    update
    winfo height .f2
} -cleanup {
    deleteWindows
} -result 78
test panedwindow-21.3 {ArrangePanes, explicit height/width are preferred} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky ""
    .p paneconfigure .f1 -width 10 -height 15
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
	deleteWindows
} -result {10 15}
test panedwindow-21.4 {ArrangePanes, panes clipped by size of pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 10 0
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
	deleteWindows
} -result {10 20}
test panedwindow-21.5 {ArrangePanes, panes clipped by size of pane} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 0 10
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
	deleteWindows
} -result {20 10}
test panedwindow-21.6 {ArrangePanes, height of pane taken from total height} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red] -sticky ""
    pack .p
    update
    winfo y .p.f1
} -cleanup {
    deleteWindows
} -result 10
test panedwindow-21.7 {ArrangePanes, width of pane taken from total width} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 40 -height 40 -bg red] -sticky ""
    pack .p
    update
    winfo x .p.f1
} -cleanup {
    deleteWindows
} -result 10
test panedwindow-21.8 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .f1]
} -cleanup {
	deleteWindows
} -result {1 0}
test panedwindow-21.9 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
} -cleanup {
	deleteWindows
} -result {1 0}
test panedwindow-21.10 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
	    [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
} -cleanup {
	deleteWindows
} -result {1 0}
test panedwindow-21.11 {ArrangePanes, last pane shrinks} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 40 -x 0 -y 0
    update
    winfo width .f2
} -cleanup {
    deleteWindows
} -result 18
test panedwindow-21.12 {ArrangePanes, last pane shrinks} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 40 -x 0 -y 0
    update
    winfo height .f2
} -cleanup {
    deleteWindows
} -result 18
test panedwindow-21.13 {ArrangePanes, panedwindow resizes} -setup {
	deleteWindows
} -body {
	panedwindow .p -width 200 -borderwidth 0
	frame .f1 -height 50 -bg blue
	set result [list]
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
	.p add .f1
	pack .p
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {200 1 200 50}
test panedwindow-21.14 {ArrangePanes, panedwindow resizes} -setup {
	deleteWindows
} -body {
	panedwindow .p -height 200 -borderwidth 0 -orient vertical
	frame .f1 -width 50 -bg blue
	set result [list]
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
	.p add .f1
	pack .p
	lappend result [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {1 200 50 200}
test panedwindow-21.15 {ArrangePanes, last pane grows} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 50
	.p add [frame .f1 -width 50 -bg red] [frame .f2 -width 50 -bg white] \
		[frame .f3 -width 50 -bg blue] [frame .f4 -width 50 -bg green]
	.p sash place 1 250 0
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p configure -width 300
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
} -cleanup {
    deleteWindows
} -result {50 150 1 1 211 50 150 1 89 300}


test panedwindow-22.1 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
} -body {
    # Basically just want to make sure that the PanedWindowReqProc is called
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
	    [frame .f2 -width 20 -height 40 -bg red]
    set result [winfo reqheight .p]
    .f1 configure -height 80
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
} -result {40 80}
test panedwindow-22.2 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
} -body {
    panedwindow .p -orient horizontal -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 10] [frame .f2 -width 10]
    set result [winfo reqwidth .p]
    .f1 configure -width 20
    lappend result [winfo reqwidth .p]
    destroy .p .f1 .f2
    expr {[lindex $result 1] - [lindex $result 0]}
} -cleanup {
	deleteWindows
} -result 10


test panedwindow-23.1 {ConfigurePanes, can't add panedwindow to itself} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add .p
} -cleanup {
	deleteWindows
} -returnCodes error -result {can't add .p to itself}
test panedwindow-23.2 {ConfigurePanes, bad window throws error} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add .b
} -cleanup {
	deleteWindows
} -returnCodes error -result {bad window path name ".b"}
test panedwindow-23.3 {ConfigurePanes, bad window aborts processing} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b .a}
    .p panes
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-23.4 {ConfigurePanes, bad option aborts processing} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b -sticky foobar}
    .p panes
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-23.5 {ConfigurePanes, after win isn't managed by panedwin} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -after .c
} -cleanup {
	deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.6 {ConfigurePanes, before win isn't managed by panedwin} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -before .c
} -cleanup {
	deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.7 {ConfigurePanes, -after {} is a no-op} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -after {}
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c}
test panedwindow-23.8 {ConfigurePanes, -before {} is a no-op} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -before {}
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c}
test panedwindow-23.9 {ConfigurePanes, new panes are added} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c}
test panedwindow-23.10 {ConfigurePanes, options applied to all panes} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c] -sticky ne -height 5 -width 5 -minsize 10
    set result {}
    foreach w {.b .c} {
        set val {}
        foreach option {-sticky -height -width -minsize} {
            lappend val $option [.p panecget $w $option]
        }
        lappend result $w $val
    }
    return $result
} -cleanup {
	deleteWindows
} -result {.b {-sticky ne -height 5 -width 5 -minsize 10} .c {-sticky ne -height 5 -width 5 -minsize 10}}

test panedwindow-23.11 {ConfigurePanes, existing panes are reconfigured} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] -sticky nw -height 10
    .p add .b [button .c] -sticky se -height 2
    list [.p panes] [.p panecget .b -sticky] [.p panecget .b -height] \
	    [.p panecget .c -sticky] [.p panecget .c -height]
} -cleanup {
	deleteWindows
} -result [list {.b .c} es 2 es 2]
test panedwindow-23.12 {ConfigurePanes, widgets added to end by default} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .c .d}
test panedwindow-23.13 {ConfigurePanes, -after, single addition} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .b
    .p add .c -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .c .b}
test panedwindow-23.14 {ConfigurePanes, -after, multiple additions} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b
    .p add .c .d -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .c .d .b}
test panedwindow-23.15 {ConfigurePanes, -after, relocates existing widget} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .d .b .c}
test panedwindow-23.16 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .b .d -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .d .c}
test panedwindow-23.17 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .b
    .p panes
} -cleanup {
	deleteWindows
} -result {.b .d .a .c}
test panedwindow-23.18 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.19 {ConfigurePanes, -after, after last window} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -after .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .c .d}
test panedwindow-23.20 {ConfigurePanes, -before, before first window} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -before .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.21 {ConfigurePanes, -before, relocate existing windows} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d .b -before .a
    .p panes
} -cleanup {
	deleteWindows
} -result {.d .b .a .c}
test panedwindow-23.22 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.a .b .c}
test panedwindow-23.23 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p add .a .b .a -after .c
    .p panes
} -cleanup {
	deleteWindows
} -result {.c .a .b}
test panedwindow-23.24 {ConfigurePanes, panedwindow cannot manage toplevels} -setup {
	deleteWindows
} -body {
    panedwindow .p
    toplevel .t
    .p add .t
} -cleanup {
	deleteWindows
} -returnCodes error -result {can't add toplevel .t to .p}
test panedwindow-23.25 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    panedwindow .p
    frame .f
    button .f.b
   .p add .f.b
} -cleanup {
	deleteWindows
} -returnCodes error -result {can't add .f.b to .p}
test panedwindow-23.26 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    frame .f
    panedwindow .f.p
    button .b
    .f.p add .b
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-23.27 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    panedwindow .p
    button .p.b
    .p add .p.b
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-23.28 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
} -body {
    frame .f
    frame .f.f
    frame .f.f.f
    panedwindow .f.f.f.p
    button .b
    .f.f.f.p add .b
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-23.29 {ConfigurePanes, -hide works} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false
	frame .f1 -width 40 -height 100 -bg red
	frame .f2 -width 40 -height 100 -bg white
	frame .f3 -width 40 -height 100 -bg blue
	frame .f4 -width 40 -height 100 -bg green
	.p add .f1 .f2 .f3 .f4
	pack .p
	update
	set result [list]
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
} -cleanup {
    deleteWindows
} -result {1 1 1 1 40 40 40 40 171 1 0 1 1 40 40 40 40 128}
test panedwindow-23.30 {ConfigurePanes, -hide works} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -width 130 -height 100
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4
	pack .p
	update
	set result [list]
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
		[winfo ismapped .f3] [winfo ismapped .f4]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4] [winfo width .p]
} -cleanup {
    deleteWindows
} -result {1 1 1 0 39 40 40 1 130 1 0 1 1 40 40 40 42 130}
test panedwindow-23.30a {ConfigurePanes, hidden panes are unmapped} -setup {
	deleteWindows
} -body {
    panedwindow .p1 -sashrelief raised
    panedwindow .p2 -sashrelief raised
    label .l1 -text Label1
    label .l2 -text Label2
    label .l3 -text Label3
    .p2 add .l2 -sticky nsew
    .p2 add .l3 -sticky nsew
    .p1 add .p2 -sticky nsew
    .p1 add .l1 -sticky nsew
    pack .p1 -side top -expand 1 -fill both
	update
	set result [list]
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p2 paneconfigure .l1 -hide 1
	update
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p1 paneconfigure .p2 -hide 1
	update
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p1 paneconfigure .p2 -hide 0
	update
	lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
		    [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
} -cleanup {
    deleteWindows
} -result {{1 1 1 1 1} {1 1 0 1 1} {1 0 0 0 0} {1 1 0 1 1}}
test panedwindow-23.31 {ConfigurePanes, -hide works, last pane stretches} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -width 200 -height 200 -borderwidth 0
	frame .f1 -width 50 -bg red
	frame .f2 -width 50 -bg green
	frame .f3 -width 50 -bg blue
	.p add .f1 .f2 .f3
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
	.p paneconfigure .f2 -hide 1
	update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
} -cleanup {
    deleteWindows
} -result {50 50 94 50 50 147}
test panedwindow-23.32 {ConfigurePanes, -hide works, last pane stretches} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -width 200 -height 200 \
		-borderwidth 0 -orient vertical
	frame .f1 -height 50 -bg red
	frame .f2 -height 50 -bg green
	frame .f3 -height 50 -bg blue
	.p add .f1 .f2 .f3
	pack .p
	update
	set result [list]
	lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
} -cleanup {
    deleteWindows
} -result {50 50 94 50 50 147}

test panedwindow-23.33 {ConfigurePanes, -stretch first} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch first
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
} -cleanup {
    deleteWindows
} -result {51 40 40 40 94 40 40 40}
test panedwindow-23.34 {ConfigurePanes, -stretch middle} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch middle
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
} -cleanup {
    deleteWindows
} -result {40 45 46 40 40 45 94 40}
test panedwindow-23.35 {ConfigurePanes, -stretch always} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch always
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
} -cleanup {
    deleteWindows
} -result {42 43 43 43 58 43 58 58}
test panedwindow-23.36 {ConfigurePanes, -stretch never} -setup {
	deleteWindows
} -body {
	panedwindow .p -showhandle false -height 100 -width 182
	frame .f1 -width 40 -bg red
	frame .f2 -width 40 -bg white
	frame .f3 -width 40 -bg blue
	frame .f4 -width 40 -bg green
	.p add .f1 .f2 .f3 .f4 -stretch never
	pack .p
	update
	set result [list]
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
	.p paneconfigure .f2 -hide 1
	update
	lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
		[winfo width .f4]
} -cleanup {
    deleteWindows
} -result {40 40 40 40 40 40 40 40}


test panedwindow-24.1 {Unlink, remove a paned with -before/-after refs} -setup {
	deleteWindows
} -body {
    # Bug 928413
    set result {}
    panedwindow .pw
    label .pw.l1 -text Label1
    label .pw.l2 -text Label2
    label .pw.l3 -text Label3
    .pw add .pw.l1
    .pw add .pw.l3
    .pw add .pw.l2 -before .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    destroy .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    .pw paneconfigure .pw.l2 -before .pw.l1
    lappend result [.pw panecget .pw.l2 -before]
} -cleanup {
	deleteWindows
} -result {.pw.l3 {} .pw.l1}


test panedwindow-25.1 {DestroyPanedWindow} -setup {
	deleteWindows
} -body {
    # This test should not result in any memory leaks.
    panedwindow .p
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .q .r .s .t} {
	    .p add [button $w]
    }
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .p .q .r .s .t} {
	    destroy $w
    }
    set result {}
} -result {}
test panedwindow-25.2 {UnmapNotify and MapNotify events are propagated to panes} -setup {
    deleteWindows
} -body {
    panedwindow .pw







|






|


|



|








|



|







|




|







|



|





|


|



|





|


|




|





|


|



|







|




|







|



|







|


|



|







|


|



|







|


|



|







|




|







|

|
|
|
|
|
|
|




|

|
|
|
|
|
|
|




|

|
|
|
|
|
|
|
|
|
|
|
|
|






|




|




|


|









|




|




|


|




|


|






|


|






|


|






|


|






|


|






|


|






|


|





|


|













|



|





|

|


|







|


|










|


|











|


|











|


|











|


|











|


|











|


|











|


|











|


|











|


|











|


|












|


|





|


|






|


|






|


|





|


|








|


|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|











|
|
|
|

|
|
|

|
|
|

|
|
|




|

|
|
|
|
|
|
|
|
|
|
|





|

|
|
|
|
|
|
|
|
|
|
|
|
|





|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






|
















|




|




|


|







4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
    return $result
} -cleanup {
    deleteWindows
} -result {{5 13 20 20} {5 71 20 20} {5 129 20 20}}


test panedwindow-20.1 {destroyed widgets are removed from panedwindow} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg blue]
    destroy .f
    .p panes
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-20.2 {destroyed pane causes geometry recomputation} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red]
    destroy .f
    winfo reqwidth .p
} -cleanup {
    deleteWindows
} -result 20


test panedwindow-21.1 {ArrangePanes, extra space is given to the last pane} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 100 -x 0 -y 0
    update
    winfo width .f2
} -cleanup {
    deleteWindows
} -result 78
test panedwindow-21.2 {ArrangePanes, extra space is given to the last pane} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 100 -x 0 -y 0
    update
    winfo height .f2
} -cleanup {
    deleteWindows
} -result 78
test panedwindow-21.3 {ArrangePanes, explicit height/width are preferred} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red] -sticky ""
    .p paneconfigure .f1 -width 10 -height 15
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
    deleteWindows
} -result {10 15}
test panedwindow-21.4 {ArrangePanes, panes clipped by size of pane} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 10 0
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
    deleteWindows
} -result {10 20}
test panedwindow-21.5 {ArrangePanes, panes clipped by size of pane} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red]
    .p sash place 0 0 10
    pack .p
    update
    list [winfo width .f1] [winfo height .f1]
} -cleanup {
    deleteWindows
} -result {20 10}
test panedwindow-21.6 {ArrangePanes, height of pane taken from total height} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
            [frame .p.f2 -width 20 -height 40 -bg red] -sticky ""
    pack .p
    update
    winfo y .p.f1
} -cleanup {
    deleteWindows
} -result 10
test panedwindow-21.7 {ArrangePanes, width of pane taken from total width} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
            [frame .p.f2 -width 40 -height 40 -bg red] -sticky ""
    pack .p
    update
    winfo x .p.f1
} -cleanup {
    deleteWindows
} -result 10
test panedwindow-21.8 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .f1]
} -cleanup {
    deleteWindows
} -result {1 0}
test panedwindow-21.9 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
            [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
} -cleanup {
    deleteWindows
} -result {1 0}
test panedwindow-21.10 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 -orient vertical
    .p add [frame .p.f1 -width 20 -height 20 -bg blue] \
            [frame .p.f2 -width 20 -height 40 -bg red]
    pack .p
    update
    set result [winfo ismapped .p.f1]
    .p sash place 0 0 0
    update
    lappend result [winfo ismapped .p.f1]
} -cleanup {
    deleteWindows
} -result {1 0}
test panedwindow-21.11 {ArrangePanes, last pane shrinks} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -width 40 -x 0 -y 0
    update
    winfo width .f2
} -cleanup {
    deleteWindows
} -result 18
test panedwindow-21.12 {ArrangePanes, last pane shrinks} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -borderwidth 0 -sashpad 0 -sashwidth 2 \
            -orient vertical
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 20 -bg red] -sticky nsew
    place .p -height 40 -x 0 -y 0
    update
    winfo height .f2
} -cleanup {
    deleteWindows
} -result 18
test panedwindow-21.13 {ArrangePanes, panedwindow resizes} -setup {
    deleteWindows
} -body {
    panedwindow .p -width 200 -borderwidth 0
    frame .f1 -height 50 -bg blue
    set result [list]
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    .p add .f1
    pack .p
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {200 1 200 50}
test panedwindow-21.14 {ArrangePanes, panedwindow resizes} -setup {
    deleteWindows
} -body {
    panedwindow .p -height 200 -borderwidth 0 -orient vertical
    frame .f1 -width 50 -bg blue
    set result [list]
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
    .p add .f1
    pack .p
    lappend result [winfo reqwidth .p] [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {1 200 50 200}
test panedwindow-21.15 {ArrangePanes, last pane grows} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -height 50
    .p add [frame .f1 -width 50 -bg red] [frame .f2 -width 50 -bg white] \
            [frame .f3 -width 50 -bg blue] [frame .f4 -width 50 -bg green]
    .p sash place 1 250 0
    pack .p
    update
    set result [list]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4] [winfo width .p]
    .p configure -width 300
    update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4] [winfo width .p]
} -cleanup {
    deleteWindows
} -result {50 150 1 1 211 50 150 1 89 300}


test panedwindow-22.1 {PanedWindowReqProc, react to pane geometry changes} -setup {
    deleteWindows
} -body {
    # Basically just want to make sure that the PanedWindowReqProc is called
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 20 -height 20 -bg blue] \
            [frame .f2 -width 20 -height 40 -bg red]
    set result [winfo reqheight .p]
    .f1 configure -height 80
    lappend result [winfo reqheight .p]
} -cleanup {
    deleteWindows
} -result {40 80}
test panedwindow-22.2 {PanedWindowReqProc, react to pane geometry changes} -setup {
    deleteWindows
} -body {
    panedwindow .p -orient horizontal -sashpad 0 -sashwidth 2
    .p add [frame .f1 -width 10] [frame .f2 -width 10]
    set result [winfo reqwidth .p]
    .f1 configure -width 20
    lappend result [winfo reqwidth .p]
    destroy .p .f1 .f2
    expr {[lindex $result 1] - [lindex $result 0]}
} -cleanup {
    deleteWindows
} -result 10


test panedwindow-23.1 {ConfigurePanes, can't add panedwindow to itself} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add .p
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't add .p to itself}
test panedwindow-23.2 {ConfigurePanes, bad window throws error} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add .b
} -cleanup {
    deleteWindows
} -returnCodes error -result {bad window path name ".b"}
test panedwindow-23.3 {ConfigurePanes, bad window aborts processing} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b .a}
    .p panes
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-23.4 {ConfigurePanes, bad option aborts processing} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b -sticky foobar}
    .p panes
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-23.5 {ConfigurePanes, after win isn't managed by panedwin} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -after .c
} -cleanup {
    deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.6 {ConfigurePanes, before win isn't managed by panedwin} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -before .c
} -cleanup {
    deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.7 {ConfigurePanes, -after {} is a no-op} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -after {}
    .p panes
} -cleanup {
    deleteWindows
} -result {.b .c}
test panedwindow-23.8 {ConfigurePanes, -before {} is a no-op} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -before {}
    .p panes
} -cleanup {
    deleteWindows
} -result {.b .c}
test panedwindow-23.9 {ConfigurePanes, new panes are added} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p panes
} -cleanup {
    deleteWindows
} -result {.b .c}
test panedwindow-23.10 {ConfigurePanes, options applied to all panes} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c] -sticky ne -height 5 -width 5 -minsize 10
    set result {}
    foreach w {.b .c} {
        set val {}
        foreach option {-sticky -height -width -minsize} {
            lappend val $option [.p panecget $w $option]
        }
        lappend result $w $val
    }
    return $result
} -cleanup {
    deleteWindows
} -result {.b {-sticky ne -height 5 -width 5 -minsize 10} .c {-sticky ne -height 5 -width 5 -minsize 10}}

test panedwindow-23.11 {ConfigurePanes, existing panes are reconfigured} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] -sticky nw -height 10
    .p add .b [button .c] -sticky se -height 2
    list [.p panes] [.p panecget .b -sticky] [.p panecget .b -height] \
            [.p panecget .c -sticky] [.p panecget .c -height]
} -cleanup {
    deleteWindows
} -result [list {.b .c} es 2 es 2]
test panedwindow-23.12 {ConfigurePanes, widgets added to end by default} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    .p panes
} -cleanup {
    deleteWindows
} -result {.b .c .d}
test panedwindow-23.13 {ConfigurePanes, -after, single addition} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .b
    .p add .c -after .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.a .c .b}
test panedwindow-23.14 {ConfigurePanes, -after, multiple additions} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b
    .p add .c .d -after .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.a .c .d .b}
test panedwindow-23.15 {ConfigurePanes, -after, relocates existing widget} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d -after .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.a .d .b .c}
test panedwindow-23.16 {ConfigurePanes, -after, relocates existing widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .b .d -after .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.a .b .d .c}
test panedwindow-23.17 {ConfigurePanes, -after, relocates existing widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .b
    .p panes
} -cleanup {
    deleteWindows
} -result {.b .d .a .c}
test panedwindow-23.18 {ConfigurePanes, -after, relocates existing widgets} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c .d
    .p add .d .a -after .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.19 {ConfigurePanes, -after, after last window} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -after .c
    .p panes
} -cleanup {
    deleteWindows
} -result {.a .b .c .d}
test panedwindow-23.20 {ConfigurePanes, -before, before first window} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d -before .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.21 {ConfigurePanes, -before, relocate existing windows} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c
    button .d

    .p add .a .b .c
    .p add .d .b -before .a
    .p panes
} -cleanup {
    deleteWindows
} -result {.d .b .a .c}
test panedwindow-23.22 {ConfigurePanes, pane specified multiple times} -setup {
    deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p panes
} -cleanup {
    deleteWindows
} -result {.a .b .c}
test panedwindow-23.23 {ConfigurePanes, pane specified multiple times} -setup {
    deleteWindows
} -body {
    # This test should not cause a core dump

    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .a .b .c
    .p add .a .b .a -after .c
    .p panes
} -cleanup {
    deleteWindows
} -result {.c .a .b}
test panedwindow-23.24 {ConfigurePanes, panedwindow cannot manage toplevels} -setup {
    deleteWindows
} -body {
    panedwindow .p
    toplevel .t
    .p add .t
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't add toplevel .t to .p}
test panedwindow-23.25 {ConfigurePanes, restrict possible panes} -setup {
    deleteWindows
} -body {
    panedwindow .p
    frame .f
    button .f.b
   .p add .f.b
} -cleanup {
    deleteWindows
} -returnCodes error -result {can't add .f.b to .p}
test panedwindow-23.26 {ConfigurePanes, restrict possible panes} -setup {
    deleteWindows
} -body {
    frame .f
    panedwindow .f.p
    button .b
    .f.p add .b
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-23.27 {ConfigurePanes, restrict possible panes} -setup {
    deleteWindows
} -body {
    panedwindow .p
    button .p.b
    .p add .p.b
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-23.28 {ConfigurePanes, restrict possible panes} -setup {
    deleteWindows
} -body {
    frame .f
    frame .f.f
    frame .f.f.f
    panedwindow .f.f.f.p
    button .b
    .f.f.f.p add .b
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-23.29 {ConfigurePanes, -hide works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false
    frame .f1 -width 40 -height 100 -bg red
    frame .f2 -width 40 -height 100 -bg white
    frame .f3 -width 40 -height 100 -bg blue
    frame .f4 -width 40 -height 100 -bg green
    .p add .f1 .f2 .f3 .f4
    pack .p
    update
    set result [list]
    lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
            [winfo ismapped .f3] [winfo ismapped .f4]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4] [winfo width .p]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
            [winfo ismapped .f3] [winfo ismapped .f4]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4] [winfo width .p]
} -cleanup {
    deleteWindows
} -result {1 1 1 1 40 40 40 40 171 1 0 1 1 40 40 40 40 128}
test panedwindow-23.30 {ConfigurePanes, -hide works} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -width 130 -height 100
    frame .f1 -width 40 -bg red
    frame .f2 -width 40 -bg white
    frame .f3 -width 40 -bg blue
    frame .f4 -width 40 -bg green
    .p add .f1 .f2 .f3 .f4
    pack .p
    update
    set result [list]
    lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
            [winfo ismapped .f3] [winfo ismapped .f4]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4] [winfo width .p]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo ismapped .f1] [winfo ismapped .f2] \
            [winfo ismapped .f3] [winfo ismapped .f4]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4] [winfo width .p]
} -cleanup {
    deleteWindows
} -result {1 1 1 0 39 40 40 1 130 1 0 1 1 40 40 40 42 130}
test panedwindow-23.30a {ConfigurePanes, hidden panes are unmapped} -setup {
    deleteWindows
} -body {
    panedwindow .p1 -sashrelief raised
    panedwindow .p2 -sashrelief raised
    label .l1 -text Label1
    label .l2 -text Label2
    label .l3 -text Label3
    .p2 add .l2 -sticky nsew
    .p2 add .l3 -sticky nsew
    .p1 add .p2 -sticky nsew
    .p1 add .l1 -sticky nsew
    pack .p1 -side top -expand 1 -fill both
    update
    set result [list]
    lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
            [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p2 paneconfigure .l1 -hide 1
    update
    lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
            [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p1 paneconfigure .p2 -hide 1
    update
    lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
            [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
    .p1 paneconfigure .p2 -hide 0
    update
    lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \
            [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]]
} -cleanup {
    deleteWindows
} -result {{1 1 1 1 1} {1 1 0 1 1} {1 0 0 0 0} {1 1 0 1 1}}
test panedwindow-23.31 {ConfigurePanes, -hide works, last pane stretches} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -width 200 -height 200 -borderwidth 0
    frame .f1 -width 50 -bg red
    frame .f2 -width 50 -bg green
    frame .f3 -width 50 -bg blue
    .p add .f1 .f2 .f3
    pack .p
    update
    set result [list]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3]
} -cleanup {
    deleteWindows
} -result {50 50 94 50 50 147}
test panedwindow-23.32 {ConfigurePanes, -hide works, last pane stretches} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -width 200 -height 200 \
            -borderwidth 0 -orient vertical
    frame .f1 -height 50 -bg red
    frame .f2 -height 50 -bg green
    frame .f3 -height 50 -bg blue
    .p add .f1 .f2 .f3
    pack .p
    update
    set result [list]
    lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo height .f1] [winfo height .f2] [winfo height .f3]
} -cleanup {
    deleteWindows
} -result {50 50 94 50 50 147}

test panedwindow-23.33 {ConfigurePanes, -stretch first} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -height 100 -width 182
    frame .f1 -width 40 -bg red
    frame .f2 -width 40 -bg white
    frame .f3 -width 40 -bg blue
    frame .f4 -width 40 -bg green
    .p add .f1 .f2 .f3 .f4 -stretch first
    pack .p
    update
    set result [list]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
} -cleanup {
    deleteWindows
} -result {51 40 40 40 94 40 40 40}
test panedwindow-23.34 {ConfigurePanes, -stretch middle} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -height 100 -width 182
    frame .f1 -width 40 -bg red
    frame .f2 -width 40 -bg white
    frame .f3 -width 40 -bg blue
    frame .f4 -width 40 -bg green
    .p add .f1 .f2 .f3 .f4 -stretch middle
    pack .p
    update
    set result [list]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
} -cleanup {
    deleteWindows
} -result {40 45 46 40 40 45 94 40}
test panedwindow-23.35 {ConfigurePanes, -stretch always} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -height 100 -width 182
    frame .f1 -width 40 -bg red
    frame .f2 -width 40 -bg white
    frame .f3 -width 40 -bg blue
    frame .f4 -width 40 -bg green
    .p add .f1 .f2 .f3 .f4 -stretch always
    pack .p
    update
    set result [list]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
} -cleanup {
    deleteWindows
} -result {42 43 43 43 58 43 58 58}
test panedwindow-23.36 {ConfigurePanes, -stretch never} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -height 100 -width 182
    frame .f1 -width 40 -bg red
    frame .f2 -width 40 -bg white
    frame .f3 -width 40 -bg blue
    frame .f4 -width 40 -bg green
    .p add .f1 .f2 .f3 .f4 -stretch never
    pack .p
    update
    set result [list]
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
    .p paneconfigure .f2 -hide 1
    update
    lappend result [winfo width .f1] [winfo width .f2] [winfo width .f3] \
            [winfo width .f4]
} -cleanup {
    deleteWindows
} -result {40 40 40 40 40 40 40 40}


test panedwindow-24.1 {Unlink, remove a paned with -before/-after refs} -setup {
    deleteWindows
} -body {
    # Bug 928413
    set result {}
    panedwindow .pw
    label .pw.l1 -text Label1
    label .pw.l2 -text Label2
    label .pw.l3 -text Label3
    .pw add .pw.l1
    .pw add .pw.l3
    .pw add .pw.l2 -before .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    destroy .pw.l3
    lappend result [.pw panecget .pw.l2 -before]
    .pw paneconfigure .pw.l2 -before .pw.l1
    lappend result [.pw panecget .pw.l2 -before]
} -cleanup {
    deleteWindows
} -result {.pw.l3 {} .pw.l1}


test panedwindow-25.1 {DestroyPanedWindow} -setup {
    deleteWindows
} -body {
    # This test should not result in any memory leaks.
    panedwindow .p
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .q .r .s .t} {
        .p add [button $w]
    }
    foreach w {.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o .p .q .r .s .t} {
        destroy $w
    }
    set result {}
} -result {}
test panedwindow-25.2 {UnmapNotify and MapNotify events are propagated to panes} -setup {
    deleteWindows
} -body {
    panedwindow .pw
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
    pack .pw
    update
    lappend result [winfo ismapped .pw]
    lappend result [winfo ismapped .pw.b]
    destroy .pw .pw.b
    set result
} -cleanup {
	deleteWindows
} -result {1 0 0 1 1}


test panedwindow-26.1 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-26.2 {PanedWindowIdentifyCoords, padding is included} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.3 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.4 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 24 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.5 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.6 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 -1
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-26.7 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 100
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-26.8 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 4
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.9 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 5
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.10 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 5
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.11 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.12 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20] \
	    [frame .f3 -bg green -width 20 -height 20]
    .p identify 48 0
} -cleanup {
	deleteWindows
} -result {1 sash}
test panedwindow-26.13 {identify subcommand errors} -setup {
	deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4
    .p identify
} -cleanup {
	deleteWindows
} -returnCodes error -result {wrong # args: should be ".p identify x y"}
test panedwindow-26.14 {identify subcommand errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p identify foo bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-26.15 {identify subcommand errors} -setup {
	deleteWindows
} -body {
    panedwindow .p
    .p identify 0 bar
} -cleanup {
	deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-26.16 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-26.17 {PanedWindowIdentifyCoords, padding is included} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.18 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 22
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.19 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 24
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.20 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 26
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.21 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify -1 26
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-26.22 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 100 26
} -cleanup {
	deleteWindows
} -result {}
test panedwindow-26.23 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 4 22
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.24 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 22
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.25 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 20
} -cleanup {
	deleteWindows
} -result {0 handle}
test panedwindow-26.26 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
	deleteWindows
} -result {0 sash}
test panedwindow-26.27 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
} -body {
    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20] \
	    [frame .f3 -bg green -width 20 -height 20]
    .p identify 0 48
} -cleanup {
	deleteWindows
} -result {1 sash}


test panedwindow-27.1 {destroy the window cleanly on error [Bug #616589]} -setup {
	deleteWindows
} -body {
    panedwindow .p -bogusopt bogus
} -cleanup {
	deleteWindows
} -returnCodes error -result {unknown option "-bogusopt"}
test panedwindow-27.2 {destroy the window cleanly on rename [Bug #616589]} -setup {
	deleteWindows
} -body {
    destroy .p
    panedwindow .p
    rename .p {}
    winfo exists .p
} -cleanup {
	deleteWindows
} -result 0


test panedwindow-28.1 {resizing width} -setup {
	deleteWindows
} -body {
    panedwindow .p -bd 5
    frame .f1 -width 100 -height 50 -bg blue
    frame .f2 -width 100 -height 50 -bg red

    .p add .f1 -sticky news
    .p add .f2 -sticky news







|




|



|


|


|



|


|


|



|


|


|



|


|


|



|


|


|



|


|


|



|


|


|


|

|


|


|


|

|


|


|


|

|


|


|


|

|


|


|



|
|


|


|




|


|




|


|




|


|



|


|


|



|


|


|



|


|


|



|


|


|



|


|


|



|


|


|



|


|


|


|

|


|


|


|

|


|


|


|

|


|


|


|

|


|


|



|
|


|




|



|


|






|




|







5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
    pack .pw
    update
    lappend result [winfo ismapped .pw]
    lappend result [winfo ismapped .pw.b]
    destroy .pw .pw.b
    set result
} -cleanup {
    deleteWindows
} -result {1 0 0 1 1}


test panedwindow-26.1 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-26.2 {PanedWindowIdentifyCoords, padding is included} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.3 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 0
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.4 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 24 0
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.5 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 0
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.6 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 -1
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-26.7 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 100
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-26.8 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 4
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.9 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 5
} -cleanup {
    deleteWindows
} -result {0 handle}
test panedwindow-26.10 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 5
} -cleanup {
    deleteWindows
} -result {0 handle}
test panedwindow-26.11 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.12 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20] \
            [frame .f3 -bg green -width 20 -height 20]
    .p identify 48 0
} -cleanup {
    deleteWindows
} -result {1 sash}
test panedwindow-26.13 {identify subcommand errors} -setup {
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4
    .p identify
} -cleanup {
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p identify x y"}
test panedwindow-26.14 {identify subcommand errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p identify foo bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-26.15 {identify subcommand errors} -setup {
    deleteWindows
} -body {
    panedwindow .p
    .p identify 0 bar
} -cleanup {
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-26.16 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-26.17 {PanedWindowIdentifyCoords, padding is included} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.18 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 22
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.19 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 24
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.20 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 26
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.21 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify -1 26
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-26.22 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 100 26
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-26.23 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 4 22
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.24 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 22
} -cleanup {
    deleteWindows
} -result {0 handle}
test panedwindow-26.25 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 20
} -cleanup {
    deleteWindows
} -result {0 handle}
test panedwindow-26.26 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
            -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
    deleteWindows
} -result {0 sash}
test panedwindow-26.27 {PanedWindowIdentifyCoords} -setup {
    deleteWindows
} -body {
    panedwindow .p -showhandle false -bd 0 -sashwidth 2 -sashpad 2 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
            [frame .f2 -bg blue -width 20 -height 20] \
            [frame .f3 -bg green -width 20 -height 20]
    .p identify 0 48
} -cleanup {
    deleteWindows
} -result {1 sash}


test panedwindow-27.1 {destroy the window cleanly on error [Bug #616589]} -setup {
    deleteWindows
} -body {
    panedwindow .p -bogusopt bogus
} -cleanup {
    deleteWindows
} -returnCodes error -result {unknown option "-bogusopt"}
test panedwindow-27.2 {destroy the window cleanly on rename [Bug #616589]} -setup {
    deleteWindows
} -body {
    destroy .p
    panedwindow .p
    rename .p {}
    winfo exists .p
} -cleanup {
    deleteWindows
} -result 0


test panedwindow-28.1 {resizing width} -setup {
    deleteWindows
} -body {
    panedwindow .p -bd 5
    frame .f1 -width 100 -height 50 -bg blue
    frame .f2 -width 100 -height 50 -bg red

    .p add .f1 -sticky news
    .p add .f2 -sticky news
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
    update
    set b "$a [winfo width .f2]"
} -cleanup {
    deleteWindows
} -result {100 110}

test panedwindow-28.2 {resizing height} -setup {
	deleteWindows
} -body {
    panedwindow .p -orient vertical -bd 5
    frame .f1 -width 50 -height 100 -bg blue
    frame .f2 -width 50 -height 100 -bg red

    .p add .f1 -sticky news
    .p add .f2 -sticky news







|







5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
    update
    set b "$a [winfo width .f2]"
} -cleanup {
    deleteWindows
} -result {100 110}

test panedwindow-28.2 {resizing height} -setup {
    deleteWindows
} -body {
    panedwindow .p -orient vertical -bd 5
    frame .f1 -width 50 -height 100 -bg blue
    frame .f2 -width 50 -height 100 -bg red

    .p add .f1 -sticky news
    .p add .f2 -sticky news
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
    deleteWindows
} -result {100 110}


test panedwindow-29.1 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
	deleteWindows
} -body {
	toplevel .t -visual {truecolor 24}
	pack [panedwindow .t.p]
	.t.p add [frame .t.p.f1] [frame .t.p.f2]
	update
	# If we got here, we didn't crash and that's good
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-29.2 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
    deleteWindows
} -body {
	toplevel .t -visual {pseudocolor 8}
	pack [frame .t.f -visual {truecolor 24}]
	pack [panedwindow .t.f.p]
	.t.f.p add [frame .t.f.p.f1 -width 5] [frame .t.f.p.f2 -width 5]
	update
	.t.f.p proxy place 1 1
	update
	.t.f.p proxy forget
	update
	# If we got here, we didn't crash and that's good
} -cleanup {
    deleteWindows
} -result {}


# cleanup
cleanupTests
return









|

|
|
|
|
|








|
|
|
|
|
|
|
|
|
|










5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
    deleteWindows
} -result {100 110}


test panedwindow-29.1 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
    deleteWindows
} -body {
    toplevel .t -visual {truecolor 24}
    pack [panedwindow .t.p]
    .t.p add [frame .t.p.f1] [frame .t.p.f2]
    update
    # If we got here, we didn't crash and that's good
} -cleanup {
    deleteWindows
} -result {}
test panedwindow-29.2 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
    deleteWindows
} -body {
    toplevel .t -visual {pseudocolor 8}
    pack [frame .t.f -visual {truecolor 24}]
    pack [panedwindow .t.f.p]
    .t.f.p add [frame .t.f.p.f1 -width 5] [frame .t.f.p.f2 -width 5]
    update
    .t.f.p proxy place 1 1
    update
    .t.f.p proxy forget
    update
    # If we got here, we didn't crash and that's good
} -cleanup {
    deleteWindows
} -result {}


# cleanup
cleanupTests
return


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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# -*- tcl -*-
# Commands covered:  pkgconfig
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file into Tk runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2017 Stuart Cassoff <[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} nodeprecated {
    lsort [::tk::pkgconfig list]
} [list \
    64bit bindir,install bindir,runtime debug demodir,install demodir,runtime \

    docdir,install docdir,runtime fontsystem includedir,install includedir,runtime \
    libdir,install libdir,runtime mem_debug optimized profiled \
    scriptdir,install scriptdir,runtime threaded \
]
test pkgconfig-1.2 {query keys multiple times} {
    string compare [::tk::pkgconfig list] [::tk::pkgconfig list]
} 0
test pkgconfig-1.3 {query value multiple times} {
    string compare \
	    [::tk::pkgconfig get 64bit] \
	    [::tk::pkgconfig get 64bit]
} 0


test pkgconfig-2.0 {error: missing subcommand} {
    catch {::tk::pkgconfig} msg
    set msg
} {wrong # args: should be "::tk::pkgconfig subcommand ?arg?"}









|










<
<
|

|
|
>
|
|
|






|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# -*- tcl -*-
# Commands covered:  pkgconfig
#
# This file contains a collection of tests for one or more of the Tk
# built-in commands.  Sourcing this file into Tk runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 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



test pkgconfig-1.1 {query keys} -constraints {nonwin} -body {
    lsort [::tk::pkgconfig list]
} -match glob -result [list \
    *bindir,install bindir,runtime *demodir,install \
    demodir,runtime*docdir,install docdir,runtime fontsystem \
    includedir,install includedir,runtime \
    libdir,install libdir,runtime*\
    scriptdir,install scriptdir,runtime*\
]
test pkgconfig-1.2 {query keys multiple times} {
    string compare [::tk::pkgconfig list] [::tk::pkgconfig list]
} 0
test pkgconfig-1.3 {query value multiple times} {
    string compare \
	    [::tk::pkgconfig get fontsystem] \
	    [::tk::pkgconfig get fontsystem]
} 0


test pkgconfig-2.0 {error: missing subcommand} {
    catch {::tk::pkgconfig} msg
    set msg
} {wrong # args: should be "::tk::pkgconfig subcommand ?arg?"}

Changes to tests/place.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# This file is a Tcl script to test out the "place" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# XXX - This test file is woefully incomplete.  At present, only a
# few of the features are tested.

# Widgets used in tests 1.* - 8.*
toplevel .t -width 300 -height 200 -bd 0




|










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# This file is a Tcl script to test out the "place" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
} -cleanup {
    destroy ".t.a.b"
} -result {-in {.t.a b} -x 1 -relx 0.2 -y 2 -rely 0.2 -width {} -relwidth 0.3 -height 4 -relheight {} -anchor w -bordermode ignore}


test place-2.1 {ConfigureContent procedure, -height option} -body {
    place .t.f2 -height abcd
} -returnCodes error -result {bad screen distance "abcd"}
test place-2.2 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 40
    update
    winfo height .t.f2
} -result 40
test place-2.3 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 120
    update
    place .t.f2 -height {}
    update
    winfo height .t.f2
} -result 60


test place-3.1 {ConfigureContent procedure, -relheight option} -body {
    place .t.f2 -relheight abcd
} -returnCodes error -result {expected floating-point number but got "abcd"}
test place-3.2 {ConfigureContent procedure, -relheight option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relheight .5
    update
    winfo height .t.f2
} -result 40







|




















|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
} -cleanup {
    destroy ".t.a.b"
} -result {-in {.t.a b} -x 1 -relx 0.2 -y 2 -rely 0.2 -width {} -relwidth 0.3 -height 4 -relheight {} -anchor w -bordermode ignore}


test place-2.1 {ConfigureContent procedure, -height option} -body {
    place .t.f2 -height abcd
} -returnCodes error -result {expected screen distance or "" but got "abcd"}
test place-2.2 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 40
    update
    winfo height .t.f2
} -result 40
test place-2.3 {ConfigureContent procedure, -height option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -height 120
    update
    place .t.f2 -height {}
    update
    winfo height .t.f2
} -result 60


test place-3.1 {ConfigureContent procedure, -relheight option} -body {
    place .t.f2 -relheight abcd
} -returnCodes error -result {expected floating-point number or "" but got "abcd"}
test place-3.2 {ConfigureContent procedure, -relheight option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relheight .5
    update
    winfo height .t.f2
} -result 40
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    place .t.f1 -in .t.f2
    place .t.f2 -in .t.f3
    place .t.f3 -in .t.f1
} -returnCodes error -result {can't put ".t.f3" inside ".t.f1": would cause management loop}

test place-5.1 {ConfigureContent procedure, -relwidth option} -body {
    place .t.f2 -relwidth abcd
} -returnCodes error -result {expected floating-point number but got "abcd"}
test place-5.2 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .5
    update
    winfo width .t.f2
} -result 75
test place-5.3 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .8
    update
    place .t.f2 -relwidth {}
    update
    winfo width .t.f2
} -result 30

test place-6.1 {ConfigureContent procedure, -width option} -body {
    place .t.f2 -width abcd
} -returnCodes error -result {bad screen distance "abcd"}
test place-6.2 {ConfigureContent procedure, -width option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 100
    update
    winfo width .t.f2
} -result 100







|



















|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    place .t.f1 -in .t.f2
    place .t.f2 -in .t.f3
    place .t.f3 -in .t.f1
} -returnCodes error -result {can't put ".t.f3" inside ".t.f1": would cause management loop}

test place-5.1 {ConfigureContent procedure, -relwidth option} -body {
    place .t.f2 -relwidth abcd
} -returnCodes error -result {expected floating-point number or "" but got "abcd"}
test place-5.2 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .5
    update
    winfo width .t.f2
} -result 75
test place-5.3 {ConfigureContent procedure, -relwidth option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -relwidth .8
    update
    place .t.f2 -relwidth {}
    update
    winfo width .t.f2
} -result 30

test place-6.1 {ConfigureContent procedure, -width option} -body {
    place .t.f2 -width abcd
} -returnCodes error -result {expected screen distance or "" but got "abcd"}
test place-6.2 {ConfigureContent procedure, -width option} -setup {
    place forget .t.f2
} -body {
    place .t.f2 -in .t.f -width 100
    update
    winfo width .t.f2
} -result 100
257
258
259
260
261
262
263
264
265

266
267

268
269
270
271



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
} -body {
    place .t.f2 -in .t.f -width 10 -relwidth .4 -height -4 -relheight .5
    place .t.f2 -width {} -relwidth {} -height {} -relheight {}
    update
    list [winfo width .t.f2] [winfo height .t.f2]
} -result {30 60}

if {[tk windowingsystem] == "win32"} {
    proc placeUpdate {} {

	update
    }

} else {
    proc placeUpdate {} {
    }
}




test place-8.1 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f
} -body {
    place .t.f2 -relx 1.0 -rely 1.0 -anchor sw
    update idletasks
    set result [winfo ismapped .t.f2]
    wm iconify .t
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update idletasks
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    placeUpdate
    lappend result [winfo ismapped .t.f2]
} -result {1 0 40 30 0 1}
test place-8.2 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f
    update idletasks
} -body {
    place .t.f -x 0 -y 0 -width 200 -height 100
    place .t.f2 -in .t.f -relx 1.0 -rely 1.0 -anchor sw -width 50 -height 20
    update idletasks
    set result [winfo ismapped .t.f2]
    wm iconify .t
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update idletasks
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    placeUpdate
    lappend result [winfo ismapped .t.f2]
} -result {1 0 42 32 0 1}
destroy .t


test place-9.1 {PlaceObjCmd} -body {
    place







<
|
>
|
<
>
|
|
<
<
>
>
>






|




|


|





<



|




|


|







257
258
259
260
261
262
263

264
265
266

267
268
269


270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
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}


# Tests place-8.1 and place-8.2 are constrained with failsOnUbuntu
# because they are failing in the GitHub CI environment, using Linux Ubuntu.
# These tests are also constrained with failsOnXQuarz because they fail

# on macOS when building with clang --disable-aqua (which uses XQuartz)
# (this is the case both at GitHub CI and on a real Mac).
# Analysis shows that, on both cases, WaitForMapNotify is giving up on


# waiting for the MapNotify event that should show up when running
# 'wm iconify'. The timeout delay (2s) is exceeded without the unmapping
# having happened. The cause for this is unknown (see comments in WaitForMapNotify).

test place-8.1 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f
} -body {
    place .t.f2 -relx 1.0 -rely 1.0 -anchor sw
    update
    set result [winfo ismapped .t.f2]
    wm iconify .t
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    lappend result [winfo ismapped .t.f2]
} -result {1 0 40 30 0 1}
test place-8.2 {PlaceStructureProc, mapping and unmapping content} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    place forget .t.f2
    place forget .t.f

} -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
    set result [winfo ismapped .t.f2]
    wm iconify .t
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    lappend result [winfo ismapped .t.f2]
} -result {1 0 42 32 0 1}
destroy .t


test place-9.1 {PlaceObjCmd} -body {
    place
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    destroy .foo
} -body {
    frame .foo
    place .foo -x 0 -y 0
    place configure .foo
} -cleanup {
    destroy .foo
} -result [list {-anchor {} {} nw nw} {-bordermode {} {} inside inside} {-height {} {} {} {}} {-in {} {} {} .} {-relheight {} {} {} {}} {-relwidth {} {} {} {}} {-relx {} {} 0 0.0} {-rely {} {} 0 0.0} {-width {} {} {} {}} {-x {} {} 0 0} {-y {} {} 0 0}]
test place-9.9 {PlaceObjCmd, configure} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -x 0 -y 0
    place configure .foo -x
} -cleanup {







|







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    destroy .foo
} -body {
    frame .foo
    place .foo -x 0 -y 0
    place configure .foo
} -cleanup {
    destroy .foo
} -result [list {-anchor {} {} nw nw} {-bordermode {} {} inside inside} {-height {} {} {} {}} {-in {} {} {} .} {-relheight {} {} {} {}} {-relwidth {} {} {} {}} {-relx {} {} 0.0 0.0} {-rely {} {} 0.0 0.0} {-width {} {} {} {}} {-x {} {} 0 0} {-y {} {} 0 0}]
test place-9.9 {PlaceObjCmd, configure} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -x 0 -y 0
    place configure .foo -x
} -cleanup {
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
test place-10.3 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place .foo -bordermode j
} -cleanup {
    destroy .foo
} -returnCodes error -result {bad bordermode "j": must be inside, outside, or ignore}
test place-10.4 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo -x 0 -y
} -cleanup {
    destroy .foo







|







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
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, ignore, or outside}
test place-10.4 {ConfigureContent} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo -x 0 -y
} -cleanup {
    destroy .foo
503
504
505
506
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524
525
526
        return $res
    }
} -body {
    # Test all manners of forgetting content
    frame .f
    frame .f.f
    stress {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        place forget .f.f
    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        pack .f.f

    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        destroy .f
        frame .f
        frame .f.f
    }
} -cleanup {
    destroy .f
    rename getbytes {}
    rename stress {}
} -result {0 0 0}








|
|

|
|
>

|
|
|
|







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
        return $res
    }
} -body {
    # Test all manners of forgetting content
    frame .f
    frame .f.f
    stress {
	place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
	place forget .f.f
    } {
	place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
	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
    }
} -cleanup {
    destroy .f
    rename getbytes {}
    rename stress {}
} -result {0 0 0}

Changes to tests/raise.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
# This file is a Tcl script to test out Tk's "raise" and
# "lower" commands, plus associated code to manage window
# stacking order.  It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# Procedure to create a bunch of overlapping windows, which should
# make it easy to detect differences in order.

proc raise_setup {} {
    foreach i [winfo child .raise] {
	        destroy $i
        }

    foreach i {a b c d e} {
	    label .raise.$i -text $i -relief raised -bd 2
    }
    place .raise.a -x 20 -y 60 -width 60 -height 80
    place .raise.b -x 60 -y 60 -width 60 -height 80
    place .raise.c -x 100 -y 60 -width 60 -height 80
    place .raise.d -x 40 -y 20 -width 100 -height 60







|











<
|
<
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20

21
22
23
24
25
26
27
28
# This file is a Tcl script to test out Tk's "raise" and
# "lower" commands, plus associated code to manage window
# stacking order.  It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1993-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# Procedure to create a bunch of overlapping windows, which should
# make it easy to detect differences in order.

proc raise_setup {} {

    destroy {*}[winfo children .raise]

    update idletasks
    foreach i {a b c d e} {
	    label .raise.$i -text $i -relief raised -bd 2
    }
    place .raise.a -x 20 -y 60 -width 60 -height 80
    place .raise.b -x 60 -y 60 -width 60 -height 80
    place .raise.c -x 100 -y 60 -width 60 -height 80
    place .raise.d -x 40 -y 20 -width 100 -height 60

Changes to tests/safe.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the Safe Tk facility. It is organized in
# the standard fashion for Tk tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the Safe Tk facility. It is organized in
# the standard fashion for Tk tests.
#
# Copyright © 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

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
} -result {ok {appname not accessible in a safe interpreter}}
test safe-2.4 {Unsafe subcommands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {tk scaling}} msg]} {
	set status ok
    }
    list $status $msg
} -cleanup {
    safe::interpDelete a
} -result {ok {scaling not accessible in a safe interpreter}}

test safe-3.1 {Unsafe commands are available hidden} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok







|





|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
} -result {ok {appname not accessible in a safe interpreter}}
test safe-2.4 {Unsafe subcommands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {tk scaling 1}} msg]} {
	set status ok
    }
    list $status $msg
} -cleanup {
    safe::interpDelete a
} -result {ok {setting the scaling not accessible in a safe interpreter}}

test safe-3.1 {Unsafe commands are available hidden} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok

Changes to tests/safePrimarySelection.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test entry widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
    namespace eval ::_test_tmp {}

    proc ::_test_tmp::getPrimarySelection {} {
        if {[catch {::tk::GetSelection . PRIMARY} sel]} {
            set sel {}
        }
        return $sel







|







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
    namespace eval ::_test_tmp {}

    proc ::_test_tmp::getPrimarySelection {} {
        if {[catch {::tk::GetSelection . PRIMARY} sel]} {
            set sel {}
        }
        return $sel

Changes to tests/scale.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the "scale" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the "scale" command
# of Tk.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    .s configure -bd 4
    .s cget -bd
} -cleanup {
    .s configure -bd [lindex [.s configure -bd] 3]
} -result 4
test scale-1.6 {configuration options} -body {
        .s configure -bd badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.7 {configuration options} -body {
    .s configure -bigincrement 12.5
    .s cget -bigincrement
} -cleanup {
    .s configure -bigincrement [lindex [.s configure -bigincrement] 3]
} -result {12.5}
test scale-1.8 {configuration options} -body {







|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    .s configure -bd 4
    .s cget -bd
} -cleanup {
    .s configure -bd [lindex [.s configure -bd] 3]
} -result 4
test scale-1.6 {configuration options} -body {
        .s configure -bd badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test scale-1.7 {configuration options} -body {
    .s configure -bigincrement 12.5
    .s cget -bigincrement
} -cleanup {
    .s configure -bigincrement [lindex [.s configure -bigincrement] 3]
} -result {12.5}
test scale-1.8 {configuration options} -body {
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    .s configure -borderwidth 1.3
    .s cget -borderwidth
} -cleanup {
    .s configure -borderwidth [lindex [.s configure -borderwidth] 3]
} -result 1
test scale-1.12 {configuration options} -body {
        .s configure -borderwidth badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.13 {configuration options} -body {
    .s configure -command {set x}
    .s cget -command
} -cleanup {
    .s configure -command [lindex [.s configure -command] 3]
} -result {set x}
test scale-1.15 {configuration options} -body {







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    .s configure -borderwidth 1.3
    .s cget -borderwidth
} -cleanup {
    .s configure -borderwidth [lindex [.s configure -borderwidth] 3]
} -result 1
test scale-1.12 {configuration options} -body {
        .s configure -borderwidth badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test scale-1.13 {configuration options} -body {
    .s configure -command {set x}
    .s cget -command
} -cleanup {
    .s configure -command [lindex [.s configure -command] 3]
} -result {set x}
test scale-1.15 {configuration options} -body {
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    .s configure -highlightthickness 2
    .s cget -highlightthickness
} -cleanup {
    .s configure -highlightthickness [lindex [.s configure -highlightthickness] 3]
} -result 2
test scale-1.32 {configuration options} -body {
        .s configure -highlightthickness badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.33 {configuration options} -body {
    .s configure -label {Some text}
    .s cget -label
} -cleanup {
    .s configure -label [lindex [.s configure -label] 3]
} -result {Some text}
test scale-1.35 {configuration options} -body {
    .s configure -length 130
    .s cget -length
} -cleanup {
    .s configure -length [lindex [.s configure -length] 3]
} -result 130
test scale-1.36 {configuration options} -body {
        .s configure -length badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.37 {configuration options} -body {
    .s configure -orient horizontal
    .s cget -orient
} -cleanup {
    .s configure -orient [lindex [.s configure -orient] 3]
} -result {horizontal}
test scale-1.38 {configuration options} -body {







|














|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    .s configure -highlightthickness 2
    .s cget -highlightthickness
} -cleanup {
    .s configure -highlightthickness [lindex [.s configure -highlightthickness] 3]
} -result 2
test scale-1.32 {configuration options} -body {
        .s configure -highlightthickness badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test scale-1.33 {configuration options} -body {
    .s configure -label {Some text}
    .s cget -label
} -cleanup {
    .s configure -label [lindex [.s configure -label] 3]
} -result {Some text}
test scale-1.35 {configuration options} -body {
    .s configure -length 130
    .s cget -length
} -cleanup {
    .s configure -length [lindex [.s configure -length] 3]
} -result 130
test scale-1.36 {configuration options} -body {
        .s configure -length badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test scale-1.37 {configuration options} -body {
    .s configure -orient horizontal
    .s cget -orient
} -cleanup {
    .s configure -orient [lindex [.s configure -orient] 3]
} -result {horizontal}
test scale-1.38 {configuration options} -body {
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    .s configure -sliderlength 86
    .s cget -sliderlength
} -cleanup {
    .s configure -sliderlength [lindex [.s configure -sliderlength] 3]
} -result 86
test scale-1.52 {configuration options} -body {
        .s configure -sliderlength badValue
} -returnCodes error -result {bad screen distance "badValue"}
test scale-1.53 {configuration options} -body {
    .s configure -sliderrelief raised
    .s cget -sliderrelief
} -cleanup {
    .s configure -sliderrelief [lindex [.s configure -sliderrelief] 3]
} -result {raised}
test scale-1.54 {configuration options} -body {







|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    .s configure -sliderlength 86
    .s cget -sliderlength
} -cleanup {
    .s configure -sliderlength [lindex [.s configure -sliderlength] 3]
} -result 86
test scale-1.52 {configuration options} -body {
        .s configure -sliderlength badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
test scale-1.53 {configuration options} -body {
    .s configure -sliderrelief raised
    .s cget -sliderrelief
} -cleanup {
    .s configure -sliderrelief [lindex [.s configure -sliderrelief] 3]
} -result {raised}
test scale-1.54 {configuration options} -body {
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
    .s configure -width 32
    .s cget -width
} -cleanup {
    .s configure -width [lindex [.s configure -width] 3]
} -result 32
test scale-1.70 {configuration options} -body {
        .s configure -width badValue
} -returnCodes error -result {bad screen distance "badValue"}
destroy .s


test scale-2.1 {Tk_ScaleCmd procedure} -body {
    scale
} -returnCodes error -result {wrong # args: should be "scale pathName ?-option value ...?"}
test scale-2.2 {Tk_ScaleCmd procedure} -body {
    scale foo
} -returnCodes error -result {bad window path name "foo"}
test scale-2.3 {Tk_ScaleCmd procedure} -body {
    catch {scale foo}
    winfo child .
} -result {}
test scale-2.4 {Tk_ScaleCmd procedure} -body {
    scale .s -gorp dumb
} -returnCodes error -result {unknown option "-gorp"}
test scale-2.5 {Tk_ScaleCmd procedure} -body {
    catch {scale .s -gorp dumb}
    winfo child .
} -result {}


# Widget used in 3.* tests
destroy .s
scale .s -from 100 -to 200
pack .s







|











|






|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
    .s configure -width 32
    .s cget -width
} -cleanup {
    .s configure -width [lindex [.s configure -width] 3]
} -result 32
test scale-1.70 {configuration options} -body {
        .s configure -width badValue
} -returnCodes error -result {expected screen distance but got "badValue"}
destroy .s


test scale-2.1 {Tk_ScaleCmd procedure} -body {
    scale
} -returnCodes error -result {wrong # args: should be "scale pathName ?-option value ...?"}
test scale-2.2 {Tk_ScaleCmd procedure} -body {
    scale foo
} -returnCodes error -result {bad window path name "foo"}
test scale-2.3 {Tk_ScaleCmd procedure} -body {
    catch {scale foo}
    winfo children .
} -result {}
test scale-2.4 {Tk_ScaleCmd procedure} -body {
    scale .s -gorp dumb
} -returnCodes error -result {unknown option "-gorp"}
test scale-2.5 {Tk_ScaleCmd procedure} -body {
    catch {scale .s -gorp dumb}
    winfo children .
} -result {}


# Widget used in 3.* tests
destroy .s
scale .s -from 100 -to 200
pack .s
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
        set traceInfo $args
    }
    .s configure -from 0 -to 100 -command {set x} -variable y
    update

    .s set 50
    update
    trace variable y w varTrace
    set traceInfo empty
    set x untouched
    .s set 50
    update
    list $x $traceInfo
} -result {untouched empty}








|







1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
        set traceInfo $args
    }
    .s configure -from 0 -to 100 -command {set x} -variable y
    update

    .s set 50
    update
    trace add variable y write varTrace
    set traceInfo empty
    set x untouched
    .s set 50
    update
    list $x $traceInfo
} -result {untouched empty}

1392
1393
1394
1395
1396
1397
1398



















1399
1400
1401
1402
1403
1404
1405
    } msg] $msg
} -cleanup {
    unset ::error
    rename bgerror {}
    destroy .s
} -result {0 {}}





















test scale-19 {Bug [3529885fff] - Click in through goes in wrong direction} \
    -setup {
        catch {destroy .s}
        catch {destroy .s1 .s2 .s3 .s4}
        unset -nocomplain x1 x2 x3 x4 x y
        scale .s1 -from 0 -to 100 -resolution 1  -variable x1 -digits 4 -orient horizontal -length 100







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    } msg] $msg
} -cleanup {
    unset ::error
    rename bgerror {}
    destroy .s
} -result {0 {}}

test scale-18.4 {Bug [415415ffff] - Long callback: One click -> Several steps} -setup {
    catch {destroy .s}
    scale .s -from 0 -to 5 -resolution 1 -variable x1 -orient horizontal -length 100 \
            -command longCmd -repeatdelay 300
    pack .s
    update
    proc longCmd {unused} {
      after 500  ; # larger than -repeatdelay
    }
} -body {
    foreach {x y} [.s coord 50] {}
    event generate .s <Button-1> -x $x -y $y
    update
    event generate .s <ButtonRelease-1> -x $x -y $y
    update
    set x1
} -cleanup {
    destroy .s
} -result {1}

test scale-19 {Bug [3529885fff] - Click in through goes in wrong direction} \
    -setup {
        catch {destroy .s}
        catch {destroy .s1 .s2 .s3 .s4}
        unset -nocomplain x1 x2 x3 x4 x y
        scale .s1 -from 0 -to 100 -resolution 1  -variable x1 -digits 4 -orient horizontal -length 100
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
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {10 -1}
test scale-20.4 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 4} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}
    .s set 10
    pack .s


    set timeout [after 500 {set $commandedVar "timeout"}]

    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout

} -result {10 10}
test scale-20.5 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 5} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    pack .s

    .s set 10
    .s configure -command {set commandedVar}
    update  ; # -command callback shall NOT fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {10 -1}
test scale-20.6 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 6} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    pack .s

    .s configure -command {set commandedVar}
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.7 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 7} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}
    pack .s

    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.8 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 8} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
    set scaleVar 7
} -body {
    scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar}
    pack .s

    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout







<


<

>
>

>



<

>








>














>
















>
















>







1488
1489
1490
1491
1492
1493
1494

1495
1496

1497
1498
1499
1500
1501
1502
1503
1504

1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {10 -1}
test scale-20.4 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 4} -setup {
    catch {destroy .s}
    set res {}

} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}

    pack .s
    update idletasks
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    set commandedVar -1
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {

    after cancel $timeout
    destroy .s
} -result {10 10}
test scale-20.5 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 5} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    pack .s
    update idletasks
    .s set 10
    .s configure -command {set commandedVar}
    update  ; # -command callback shall NOT fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
} -result {10 -1}
test scale-20.6 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 6} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50
    pack .s
    update idletasks
    .s configure -command {set commandedVar}
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.7 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 7} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
} -body {
    scale .s -from 1 -to 50 -command {set commandedVar}
    pack .s
    update idletasks
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
} -result {10 10}
test scale-20.8 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 8} -setup {
    catch {destroy .s}
    set res {}
    set commandedVar -1
    set scaleVar 7
} -body {
    scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar}
    pack .s
    update idletasks
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout

Changes to tests/scrollbar.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# This file is a Tcl script to test out scrollbar widgets and
# the "scrollbar" command of Tk.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]
testConstraint nodeprecated [expr {"nodeprecated" ni [tk::pkgconfig list]}]

proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

proc getTroughSize {w} {
    if {[testConstraint testmetrics]} {






|






<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13




14
15
16
17
18
19
20
# This file is a Tcl script to test out scrollbar widgets and
# the "scrollbar" command of Tk.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands





proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

proc getTroughSize {w} {
    if {[testConstraint testmetrics]} {
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
foreach test {
    {-activebackground #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-activerelief sunken sunken non-existent
	    {bad relief "non-existent": must be flat, groove, raised, ridge, solid, or sunken}}
    {-background #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-bd 4 4 badValue {bad screen distance "badValue"}}
    {-bg #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-borderwidth 1.3 1 badValue {bad screen distance "badValue"}}
    {-command "set x" {set x} {} {}}
    {-elementborderwidth 4 4 badValue {bad screen distance "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {bad screen distance "bogus"}}
    {-highlightthickness -2 0 {} {}}
    {-jump true 1 silly {expected boolean value but got "silly"}}
    {-orient horizontal horizontal badValue
	    {bad orientation "badValue": must be vertical or horizontal}}
    {-orient horizontal horizontal bogus {bad orientation "bogus": must be vertical or horizontal}}
    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-repeatdelay 140 140 129.3 {expected integer but got "129.3"}}
    {-repeatinterval 140 140 129.3 {expected integer but got "129.3"}}
    {-takefocus "any string" "any string" {} {}}
    {-troughcolor #432 #432 lousy {unknown color name "lousy"}}
    {-width 32 32 badValue {bad screen distance "badValue"}}
} {
    lassign $test name value okResult badValue badResult
    # Assume $name is plain; true of all our in-use options!
    test scrollbar-1.$i {configuration options} \
	".s configure $name [list $value]; .s cget $name" $okResult
    incr i
    if {$badValue ne ""} {







|


|

|



|










|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
foreach test {
    {-activebackground #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-activerelief sunken sunken non-existent
	    {bad relief "non-existent": must be flat, groove, raised, ridge, solid, or sunken}}
    {-background #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-bd 4 4 badValue {expected screen distance but got "badValue"}}
    {-bg #ff0000 #ff0000 non-existent
	    {unknown color name "non-existent"}}
    {-borderwidth 1.3 1 badValue {expected screen distance but got "badValue"}}
    {-command "set x" {set x} {} {}}
    {-elementborderwidth 4 4 badValue {expected screen distance but got "badValue"}}
    {-cursor arrow arrow badValue {bad cursor spec "badValue"}}
    {-highlightbackground #112233 #112233 ugly {unknown color name "ugly"}}
    {-highlightcolor #123456 #123456 bogus {unknown color name "bogus"}}
    {-highlightthickness 6 6 bogus {expected screen distance but got "bogus"}}
    {-highlightthickness -2 0 {} {}}
    {-jump true 1 silly {expected boolean value but got "silly"}}
    {-orient horizontal horizontal badValue
	    {bad orientation "badValue": must be vertical or horizontal}}
    {-orient horizontal horizontal bogus {bad orientation "bogus": must be vertical or horizontal}}
    {-relief ridge ridge badValue {bad relief "badValue": must be flat, groove, raised, ridge, solid, or sunken}}
    {-repeatdelay 140 140 129.3 {expected integer but got "129.3"}}
    {-repeatinterval 140 140 129.3 {expected integer but got "129.3"}}
    {-takefocus "any string" "any string" {} {}}
    {-troughcolor #432 #432 lousy {unknown color name "lousy"}}
    {-width 32 32 badValue {expected screen distance but got "badValue"}}
} {
    lassign $test name value okResult badValue badResult
    # Assume $name is plain; true of all our in-use options!
    test scrollbar-1.$i {configuration options} \
	".s configure $name [list $value]; .s cget $name" $okResult
    incr i
    if {$badValue ne ""} {
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285

286
287
288
289
290
291
292
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} 1
test scrollbar-3.35 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 21]
} [format %.6g [expr {(21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)}]]
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} {x11 failsOnUbuntu failsOnXQuarz} {
    format {%.6g} [.s fraction 4 179]

} 1
test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} {
    format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s]}]]
} 1
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} {x11 failsOnUbuntu failsOnXQuarz} {
    format {%.6g} [.s fraction 4 178]
} {0.993711}

test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr {
    [format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s] - 2}]]]
	== [format %g [expr {(200.0 - [testmetrics cyvscroll .s]*2 - 2)
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)}]]}
} 1








|

>
|



|

|
>







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} 1
test scrollbar-3.35 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 21]
} [format %.6g [expr {(21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)}]]
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 179]
} [format %.6g [expr {(179.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)}]]
test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} {
    format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s]}]]
} 1
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 178]
} [format %.6g [expr {(178.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)}]]
test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr {
    [format {%.6g} [.s fraction 4 [expr {200 - [testmetrics cyvscroll .s] - 2}]]]
	== [format %g [expr {(200.0 - [testmetrics cyvscroll .s]*2 - 2)
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)}]]}
} 1

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} 0
destroy .t
test scrollbar-3.43 {ScrollbarWidgetCmd procedure, "get" option} {
    list [catch {.s get a} msg] $msg
} {1 {wrong # args: should be ".s get"}}
test scrollbar-3.44 {ScrollbarWidgetCmd procedure, "get" option} nodeprecated {
    .s set 100 10 13 14
    .s get
} {100 10 13 14}
test scrollbar-3.45 {ScrollbarWidgetCmd procedure, "get" option} {
    .s set 0.6 0.8
    set result {}
    foreach element [.s get] {
	lappend result [format %.1f $element]
    }
    set result







<
<
<
<







312
313
314
315
316
317
318




319
320
321
322
323
324
325
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} 0
destroy .t
test scrollbar-3.43 {ScrollbarWidgetCmd procedure, "get" option} {
    list [catch {.s get a} msg] $msg
} {1 {wrong # args: should be ".s get"}}




test scrollbar-3.45 {ScrollbarWidgetCmd procedure, "get" option} {
    .s set 0.6 0.8
    set result {}
    foreach element [.s get] {
	lappend result [format %.1f $element]
    }
    set result
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 5
} {arrow1}
test scrollbar-3.50.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 5
} {trough1}
test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s set .3 .6
    .s identify 5 80
} {slider}
test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 145
} {trough2}
test scrollbar-3.54.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 195
} {arrow2}
test scrollbar-3.54.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 195
} {trough2}
test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix {
    .s identify 0 0
} {}
test scrollbar-3.57 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def} msg] $msg







|
















|







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 5
} {arrow1}
test scrollbar-3.50.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 5 5
} {trough1}
test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s set .3 .6
    .s identify 5 80
} {slider}
test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 145
} {trough2}
test scrollbar-3.54.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 195
} {arrow2}
test scrollbar-3.54.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 5 195
} {trough2}
test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix {
    .s identify 0 0
} {}
test scrollbar-3.57 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def} msg] $msg
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    .s set .4 .3
    set result {}
    foreach element [.s get] {
	lappend result [format %.1f $element]
    }
    set result
} {0.4 0.4}
test scrollbar-3.64 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set abc def ghi jkl} msg] $msg
} {1 {expected integer but got "abc"}}
test scrollbar-3.65 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 def ghi jkl} msg] $msg
} {1 {expected integer but got "def"}}
test scrollbar-3.66 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 2 ghi jkl} msg] $msg
} {1 {expected integer but got "ghi"}}
test scrollbar-3.67 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    list [catch {.s set 1 2 3 jkl} msg] $msg
} {1 {expected integer but got "jkl"}}
test scrollbar-3.68 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set -10 50 20 30
    .s get
} {0 50 0 0}
test scrollbar-3.69 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set 100 -10 20 30
    .s get
} {100 0 20 30}
test scrollbar-3.70 {ScrollbarWidgetCmd procedure, "set" option} nodeprecated {
    .s set 100 50 30 20
    .s get
} {100 50 30 30}
test scrollbar-3.71 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.72 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3 4 5} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.73 {ScrollbarWidgetCmd procedure} {







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







393
394
395
396
397
398
399
























400
401
402
403
404
405
406
    .s set .4 .3
    set result {}
    foreach element [.s get] {
	lappend result [format %.1f $element]
    }
    set result
} {0.4 0.4}
























test scrollbar-3.71 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.72 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set 1 2 3 4 5} msg] $msg
} {1 {wrong # args: should be ".s set firstFraction lastFraction"}}
test scrollbar-3.73 {ScrollbarWidgetCmd procedure} {
488
489
490
491
492
493
494
495
496
497
498


499
500
501
502
503
504
505
506
507
508
509
510
test scrollbar-6.10 {ScrollbarPosition procedure} {
    .s identify [winfo width .s] [expr {[winfo height .s] / 2}]
} {}
test scrollbar-6.11.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 4
} {arrow1}
test scrollbar-6.11.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 4
} {trough1}
test scrollbar-6.12.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {


    .s identify 8 19
} {arrow1}
test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 19
} {trough1}
test scrollbar-6.14 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] / 2}] 0
} {arrow1}
test scrollbar-6.15 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {[testmetrics cyvscroll .s] - 1}]
} {arrow1}







|


|
>
>
|


|
|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
test scrollbar-6.10 {ScrollbarPosition procedure} {
    .s identify [winfo width .s] [expr {[winfo height .s] / 2}]
} {}
test scrollbar-6.11.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 4
} {arrow1}
test scrollbar-6.11.2 {ScrollbarPosition procedure} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 4
} {trough1}
test scrollbar-6.12.1 {ScrollbarPosition procedure} x11 {
    # x11 scrollbars have arrows 19 pixels height,
    # but on XQuartz they are 15 pixels height
    .s identify 8 15
} {arrow1}
test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 15
} {trough1}
test scrollbar-6.14 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] / 2}] 0
} {arrow1}
test scrollbar-6.15 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {[testmetrics cyvscroll .s] - 1}]
} {arrow1}
549
550
551
552
553
554
555
556


557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580



581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619



620
621
622
623
624
625
626
627
    .s identify [expr {[winfo width .s] / 2}] [expr {int(.4 / [.s delta 0 1])
						 + [testmetrics cyvscroll .s]}]
} {trough2}
test scrollbar-6.28 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}] [expr {[winfo height .s]
						 - [testmetrics cyvscroll .s] - 1}]
} {trough2}
test scrollbar-6.29.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {


    .s identify 8 180
} {arrow2}
test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 180
} {trough2}
test scrollbar-6.30.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 195
} {arrow2}
test scrollbar-6.30.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 195
} {trough2}
test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}]  [expr {[winfo height .s]
						  - [testmetrics cyvscroll .s]}]
} {arrow2}
test scrollbar-6.33 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] / 2}] [expr {[winfo height .s] - 1}]
} {arrow2}
test scrollbar-6.34 {ScrollbarPosition procedure} unix {
    .s identify 4 100
} {trough2}
test scrollbar-6.35 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnXQuarz} {



    .s identify 18 100
} {trough2}
test scrollbar-6.37 {ScrollbarPosition procedure} win {
    .s identify 0 100
} {trough2}
test scrollbar-6.38 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] - 1}] 100
} {trough2}

catch {destroy .t}
toplevel .t -width 250 -height 150
wm geometry .t +0+0
scrollbar .t.s -orient horizontal -relief sunken -bd 2 -highlightthickness 2
place .t.s -width 200
.t.s set .2 .4
update

test scrollbar-6.39.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 4 8
} {arrow1}
test scrollbar-6.39.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .t.s identify 4 8
} {trough1}
test scrollbar-6.40 {ScrollbarPosition procedure} win {
    .t.s identify 0 [expr {[winfo height .t.s] / 2}]
} {arrow1}
test scrollbar-6.41.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 82 8
} {slider}
test scrollbar-6.41.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .t.s identify 82 8
} {trough2}
test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr {int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s]
		       - 1}] [expr {[winfo height .t.s] / 2}]
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} {unix failsOnUbuntu failsOnXQuarz} {



    .t.s identify 100 18
} {trough2}
test scrollbar-6.46 {ScrollbarPosition procedure} win {
    .t.s identify 100 [expr {[winfo height .t.s] - 1}]
} {trough2}

test scrollbar-7.1 {EventuallyRedraw} {
    .s configure -orient horizontal







|
>
>
|


|
|





|












|
>
>
>
|




















|









|






|
>
>
>
|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
    .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 {
    # x11 scrollbars have arrows at least 19 pixels height
    # but on XQuartz they are 15 pixels height
    .s identify 8 184
} {arrow2}
test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 184
} {trough2}
test scrollbar-6.30.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 195
} {arrow2}
test scrollbar-6.30.2 {ScrollbarPosition procedure} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 195
} {trough2}
test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr {[winfo width .s] / 2}]  [expr {[winfo height .s]
						  - [testmetrics cyvscroll .s]}]
} {arrow2}
test scrollbar-6.33 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] / 2}] [expr {[winfo height .s] - 1}]
} {arrow2}
test scrollbar-6.34 {ScrollbarPosition procedure} unix {
    .s identify 4 100
} {trough2}
test scrollbar-6.35 {ScrollbarPosition procedure} unix {
    # Linux x11 scrollbars have arrows 18 pixels width
    # macOS XQuartz scrollbars have arrows 14 pixels width
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 14 100
} {trough2}
test scrollbar-6.37 {ScrollbarPosition procedure} win {
    .s identify 0 100
} {trough2}
test scrollbar-6.38 {ScrollbarPosition procedure} win {
    .s identify [expr {[winfo width .s] - 1}] 100
} {trough2}

catch {destroy .t}
toplevel .t -width 250 -height 150
wm geometry .t +0+0
scrollbar .t.s -orient horizontal -relief sunken -bd 2 -highlightthickness 2
place .t.s -width 200
.t.s set .2 .4
update

test scrollbar-6.39.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 4 8
} {arrow1}
test scrollbar-6.39.2 {ScrollbarPosition procedure} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .t.s identify 4 8
} {trough1}
test scrollbar-6.40 {ScrollbarPosition procedure} win {
    .t.s identify 0 [expr {[winfo height .t.s] / 2}]
} {arrow1}
test scrollbar-6.41.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 82 8
} {slider}
test scrollbar-6.41.2 {ScrollbarPosition procedure} aqua {
    # macOS aqua scrollbars have no arrows nowadays
    .t.s identify 82 8
} {trough2}
test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr {int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s]
		       - 1}] [expr {[winfo height .t.s] / 2}]
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} unix {
    # Linux x11 scrollbars have arrows 18 pixels height
    # macOS XQuartz scrollbars have arrows 14 pixels height
    # macOS aqua scrollbars have no arrows nowadays
    .t.s identify 100 14
} {trough2}
test scrollbar-6.46 {ScrollbarPosition procedure} win {
    .t.s identify 100 [expr {[winfo height .t.s] - 1}]
} {trough2}

test scrollbar-7.1 {EventuallyRedraw} {
    .s configure -orient horizontal
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736
737
738
739
740
741
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s

    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}

test scrollbar-10.2 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s

    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
test scrollbar-10.2.3 {<MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s

    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}

test scrollbar-11.1 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body {
    proc destroy_scrollbar {} {
        if {[winfo exists .top.s]} {
            destroy .top.s
        }
    }







>





|









>





|
|







>





|







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
    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 <Enter>
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {4.0}

test scrollbar-10.2 {<MouseWheel> event on scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Enter>
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.3}
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 <Enter>
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.3}

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
33
# This file is a Tcl script to test out Tk's selection management code,
# especially the "selection" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

#
# Note: Multiple display selection handling will only be tested if the
# environment variable TK_ALT_DISPLAY is set to an alternate display.
#

package require tcltest 2.2
namespace import ::tcltest::*
namespace import ::tk::test:loadTkCommand
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint cliboardManagerPresent 0
if {![catch {selection get -selection CLIPBOARD_MANAGER -type TARGETS}]} {
    if {"SAVE_TARGETS" in [selection get -selection CLIPBOARD_MANAGER -type TARGETS]} {
        testConstraint cliboardManagerPresent 1
    }
}
testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {





|



















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# This file is a Tcl script to test out Tk's selection management code,
# especially the "selection" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 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} {

Changes to tests/send.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2001 by ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint xhost [llength [auto_execok xhost]]
testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]


# Compute a script that will load Tk into a child interpreter.

foreach pkg [info loaded] {
    if {[lindex $pkg 1] == "Tk"} {
	set loadTk "load $pkg"
	break






|
|









|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 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.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint xhost [llength [auto_execok xhost]]
testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Compute a script that will load Tk into a child interpreter.

foreach pkg [info loaded] {
    if {[lindex $pkg 1] == "Tk"} {
	set loadTk "load $pkg"
	break
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    set a altDisplay
    tk appname xyzgorp
    list \[send xyzgorp set a\] \[send -displayof .t xyzgorp set a\]
    "]
    cleanupbg
    set result
} {altDisplay homeDisplay}
# Since macOS has no registry of interpreters, 8.3, 8.4 and 8.10 will fail.
test send-8.3 {Tk_SendCmd procedure, options} {secureserver notAqua} {
    list [catch {send -- -async foo bar baz} msg] $msg
} {1 {no application named "-async"}}
test send-8.4 {Tk_SendCmd procedure, options} {secureserver notAqua} {
    list [catch {send -gorp foo bar baz} msg] $msg
} {1 {no application named "-gorp"}}
test send-8.5 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -async foo} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test send-8.6 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send foo} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test send-8.7 {Tk_SendCmd procedure, local execution} {secureserver} {







|



|

|







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
    set a altDisplay
    tk appname xyzgorp
    list \[send xyzgorp set a\] \[send -displayof .t xyzgorp set a\]
    "]
    cleanupbg
    set result
} {altDisplay homeDisplay}
# Since macOS has no registry of interpreters, 8.3 and 8.10 will fail.
test send-8.3 {Tk_SendCmd procedure, options} {secureserver notAqua} {
    list [catch {send -- -async foo bar baz} msg] $msg
} {1 {no application named "-async"}}
test send-8.4 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -gorp foo bar baz} msg] $msg
} {1 {bad option "-gorp": must be -async, -displayof, or --}}
test send-8.5 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send -async foo} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test send-8.6 {Tk_SendCmd procedure, options} {secureserver} {
    list [catch {send foo} msg] $msg
} {1 {wrong # args: should be "send ?-option value ...? interpName arg ?arg ...?"}}
test send-8.7 {Tk_SendCmd procedure, local execution} {secureserver} {
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
} {1 {couldn't open "bogus_file_name": no such file or directory} {couldn't open "bogus_file_name": no such file or directory
    while executing
"open bogus_file_name"
    invoked from within
"if 1 {open bogus_file_name}"
    invoked from within
"send t_s_1 {if 1 {open bogus_file_name}}"} {POSIX ENOENT {no such file or directory}}}
test send-8.16 {Tk_SendCmd procedure, bogusCommWindow} {secureserver testsend failsOnUbuntu} {
    testsend prop root InterpRegistry "10234 bogus\n"
    set result [list [catch {send bogus bogus command} msg] $msg]
    winfo interps
    tk appname tktest
    set result
} {1 {no application named "bogus"}}








|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
} {1 {couldn't open "bogus_file_name": no such file or directory} {couldn't open "bogus_file_name": no such file or directory
    while executing
"open bogus_file_name"
    invoked from within
"if 1 {open bogus_file_name}"
    invoked from within
"send t_s_1 {if 1 {open bogus_file_name}}"} {POSIX ENOENT {no such file or directory}}}
test send-8.16 {Tk_SendCmd procedure, bogusCommWindow} {secureserver testsend failsOnUbuntu failsOnXQuarz} {
    testsend prop root InterpRegistry "10234 bogus\n"
    set result [list [catch {send bogus bogus command} msg] $msg]
    winfo interps
    tk appname tktest
    set result
} {1 {no application named "bogus"}}

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
}
test send-10.8 {SendEventProc procedure, exceptional return} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-r $id 62\n-s break\n"
    update
    testsend prop [winfo id .f] Comm
} {
r
-s 62
-r 
-c 3
}
test send-10.9 {SendEventProc procedure, empty return} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-r $id 62\n-s concat\n"
    update
    testsend prop [winfo id .f] Comm
} {
r
-s 62
-r 
}
test send-10.10 {SendEventProc procedure, asynchronous calls} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-s foreach i {1 2 3} {error {test error} {Initial errorInfo} {test code}}\n"
    update
    testsend prop [winfo id .f] Comm
} {}







<
<
|
<
<
<






<
<
|
<
<







438
439
440
441
442
443
444


445



446
447
448
449
450
451


452


453
454
455
456
457
458
459
}
test send-10.8 {SendEventProc procedure, exceptional return} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-r $id 62\n-s break\n"
    update
    testsend prop [winfo id .f] Comm


} "\nr\n-s 62\n-r \n-c 3\n"



test send-10.9 {SendEventProc procedure, empty return} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-r $id 62\n-s concat\n"
    update
    testsend prop [winfo id .f] Comm


} "\nr\n-s 62\n-r \n"


test send-10.10 {SendEventProc procedure, asynchronous calls} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-s foreach i {1 2 3} {error {test error} {Initial errorInfo} {test code}}\n"
    update
    testsend prop [winfo id .f] Comm
} {}
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
    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} {
    testsend prop root InterpRegistry "0x21447 dummy\n"
    list [catch {send dummy foo} msg] $msg
} {1 {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







|

|
|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    setupbg
    dobg {tk appname t_s_3}
    set x [list [catch {send t_s_3 exit} msg] $msg]
    cleanupbg
    set x
} {1 {target application died}}

test send-11.1 {AppendPropCarefully and AppendErrorProc procedures} -constraints {secureserver testsend} -body {
    testsend prop root InterpRegistry "0x21447 dummy\n"
    send dummy foo
} -returnCodes 1 -match regexp -result {^(target application died|no application named "dummy")$}
test send-11.2 {AppendPropCarefully and AppendErrorProc procedures} {secureserver testsend} {
    testsend prop comm Comm "c\n-r0x123 44\n-n tktest\n-s concat a b c\n"
    update
} {}

winfo interps
tk appname tktest

Changes to tests/spinbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This file is a Tcl script to test spinbox widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace variable
proc override args {
        global x
        set x 12345
}

# Procedures used in widget VALIDATION tests
proc doval {W d i P s S v V} {





|







<
<
<






|







1
2
3
4
5
6
7
8
9
10
11
12
13



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# This file is a Tcl script to test spinbox widgets in Tk.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands




# For xscrollcommand
set scrollInfo {}
proc scroll args {
        global scrollInfo
        set scrollInfo $args
}
# For trace add variable
proc override args {
        global x
        set x 12345
}

# Procedures used in widget VALIDATION tests
proc doval {W d i P s S v V} {
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
        -relief sunken
    pack .e
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test spinbox-1.7 {configuration option: "bg"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {







|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
        -relief sunken
    pack .e
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test spinbox-1.7 {configuration option: "bg"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
        -relief sunken
    pack .e
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test spinbox-1.11 {configuration option: "buttonbackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {







|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
        -relief sunken
    pack .e
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test spinbox-1.11 {configuration option: "buttonbackground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightthickness bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "bogus"}

test spinbox-1.40 {configuration option: "highlightthickness"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {







|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightthickness bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "bogus"}

test spinbox-1.40 {configuration option: "highlightthickness"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "2.6x"}

test spinbox-1.47 {configuration option: "insertofftime"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {







|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "2.6x"}

test spinbox-1.47 {configuration option: "insertofftime"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}

test spinbox-1.67 {configuration option: "selectforeground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {







|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected screen distance but got "badValue"}

test spinbox-1.67 {configuration option: "selectforeground"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
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 {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -vcmd "a command"
    .e cget -vcmd
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.81 {configuration option: "width"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken







|





|
|







912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
    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: "validatecommand"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -validatecommand "a command"
    .e cget -validatecommand
} -cleanup {
    destroy .e
} -result {a command}

test spinbox-1.81 {configuration option: "width"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
    spinbox .e
    pack .e
    update
} -body {
    .e scan foobar 20
} -cleanup {
    destroy .e
} -returnCodes error -result {bad scan option "foobar": must be mark or dragto}
test spinbox-3.45 {SpinboxWidgetCmd procedure, "scan" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e scan mark 20.1
} -cleanup {







|







1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
    spinbox .e
    pack .e
    update
} -body {
    .e scan foobar 20
} -cleanup {
    destroy .e
} -returnCodes error -result {bad scan option "foobar": must be dragto or mark}
test spinbox-3.45 {SpinboxWidgetCmd procedure, "scan" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e scan mark 20.1
} -cleanup {
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 -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







|







1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
    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 {}
    .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
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
} -cleanup {
    destroy .e
} -result {Some text}
test spinbox-5.4 {ConfigureSpinbox procedure, -textvariable} -setup {
    unset -nocomplain x
    spinbox .e
} -body {
    trace variable x w override
    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
} -result {12345 12345}

test spinbox-5.5 {ConfigureSpinbox procedure} -setup {
    set x {}
    spinbox .e1
    spinbox .e2
} -body {







|





|







1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
} -cleanup {
    destroy .e
} -result {Some text}
test spinbox-5.4 {ConfigureSpinbox procedure, -textvariable} -setup {
    unset -nocomplain x
    spinbox .e
} -body {
    trace add variable x write override
    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace remove variable x write override
} -result {12345 12345}

test spinbox-5.5 {ConfigureSpinbox procedure} -setup {
    set x {}
    spinbox .e1
    spinbox .e2
} -body {
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035

test spinbox-5.7 {ConfigureSpinbox procedure} -setup {
    spinbox .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e configure -width 5
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}

test spinbox-5.8 {ConfigureSpinbox procedure} -constraints {
    fonts
} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {







|
|

|



<
|







2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023

2024
2025
2026
2027
2028
2029
2030
2031

test spinbox-5.7 {ConfigureSpinbox procedure} -setup {
    spinbox .e -font {Helvetica -12} -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update
    set scrollInfo wrong
    .e configure -width 5
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.000000 0.454545}

test spinbox-5.8 {ConfigureSpinbox procedure} -constraints {
    fonts
} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
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
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 2 XXX
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abXXXcde abXXXcde {0.000000 1.000000}}

test spinbox-7.2 {InsertChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 500 XXX
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test spinbox-7.3 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2







|
|

|



<










|
|

|



<







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
    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
    set scrollInfo wrong
    .e insert 2 XXX
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -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
    set scrollInfo wrong
    .e insert 500 XXX
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -result {abcdeXXX abcdeXXX {0.000000 1.000000}}
test spinbox-7.3 {InsertChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
} -body {
    .e insert 0 0123456789
    .e select from 2
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 2 4
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abe abe {0.000000 1.000000}}
test spinbox-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete -1 2
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {cde cde {0.000000 1.000000}}
test spinbox-8.3 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 3 1000
    vwait scrollInfo
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {abc abc {0.000000 1.000000}}
test spinbox-8.4 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde







|
|

|



<









|
|
|
|



<









|
|

|



<







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
    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
    set scrollInfo wrong
    .e delete 2 4
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -result {abe abe {0.000000 1.000000}}
test spinbox-8.2 {DeleteChars procedure} -setup {
    unset -nocomplain contents
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    .e insert 0 abcde
    update
    set scrollInfo wrong
    .e delete {} 2
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -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
    set scrollInfo wrong
    .e delete 3 1000
    update
    list [.e get] $contents [format {%.6f %.6f} {*}$scrollInfo]
} -cleanup {
    destroy .e

} -result {abc abc {0.000000 1.000000}}
test spinbox-8.4 {DeleteChars procedure} -setup {
    spinbox .e -width 10 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 0123456789abcde
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test spinbox-8.18 {DeleteChars procedure} -constraints failsOnUbuntuNoXft -setup {
    spinbox .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4







|







2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
    .e xview 4
    .e delete 4 6
    update
    .e index @0
} -cleanup {
    destroy .e
} -result 4
test spinbox-8.18 {DeleteChars procedure} -setup {
    spinbox .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    focus .e
} -body {
    .e insert 0 "xyzzy"
    update
    .e delete 2 4
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) \
                          + $buttonWidth } ]
    expr {[winfo reqwidth .e] == $expected}
} -cleanup {
    destroy .e
    unset XPAD buttonWidth expected
} -result 1

test spinbox-9.1 {SpinboxValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace variable x w override
    spinbox .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
} -result {12345 12345}


test spinbox-10.1 {SpinboxSetValue procedure} -constraints fonts -body {
    set x abcde
    set y ab
    spinbox .e  -font {Helvetica -12} -highlightthickness 2 -bd 2  -width 0







|




|





|







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
                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) \
                          + $buttonWidth } ]
    expr {[winfo reqwidth .e] == $expected}
} -cleanup {
    destroy .e
    unset XPAD buttonWidth expected
} -result {1}

test spinbox-9.1 {SpinboxValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace add variable x write override
    spinbox .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace remove variable x write override
} -result {12345 12345}


test spinbox-10.1 {SpinboxSetValue procedure} -constraints fonts -body {
    set x abcde
    set y ab
    spinbox .e  -font {Helvetica -12} -highlightthickness 2 -bd 2  -width 0
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 -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







|







3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
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 {}
} -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
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
    destroy .e
} -result {0.000000 1.000000}


test spinbox-17.1 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e delete 0 end
    .e insert 0 123
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 1.000000}
test spinbox-17.2 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    .e insert 0 0123456789abcdef
    update idletasks
    set timeout [after 500 {set $scrollInfo {-1000000 -1000000}}]
    .e xview 3
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.187500 0.812500}
test spinbox-17.3 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    .e insert 0 abcdefghijklmnopqrs
    .e xview
    vwait scrollInfo
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.526316}
test spinbox-17.4 {SpinboxUpdateScrollbar procedure} -setup {
    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    spinbox .e -width 5
    pack .e
    update idletasks

    .e configure -xscrollcommand thisisnotacommand
    vwait x
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"







|
|


|



<





|
|

|



<




|
|


|



<









|
>

|







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
    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
    set scrollInfo wrong
    .e delete 0 end
    .e insert 0 123
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.000000 1.000000}
test spinbox-17.2 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    .e insert 0 0123456789abcdef
    update
    set scrollInfo wrong
    .e xview 3
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.187500 0.812500}
test spinbox-17.3 {SpinboxUpdateScrollbar procedure} -body {
    spinbox .e -width 10 -xscrollcommand scroll -font {Courier -12}
    pack .e
    update
    set scrollInfo wrong
    .e insert 0 abcdefghijklmnopqrs
    .e xview
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e

} -result {0.000000 0.526316}
test spinbox-17.4 {SpinboxUpdateScrollbar procedure} -setup {
    proc bgerror msg {
	global x
	set x $msg
}
} -body {
    spinbox .e -width 5
    pack .e
    update
    set scrollInfo wrong
    .e configure -xscrollcommand thisisnotacommand
    update
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
} -cleanup {
    destroy .e
} -result {1 1 345}

test spinbox-24.1 {error in trace proc attached to the textvariable} -setup {
    destroy .s
} -body {
    trace variable myvar w traceit
    proc traceit args {error "Intentional error here!"}
    spinbox .s -textvariable myvar -from 1 -to 10
    catch {.s set mystring} result1
    catch {.s insert 0 mystring} result2
    catch {.s delete 0} result3
    catch {.s invoke buttonup} result4
    list $result1 $result2 $result3 $result4







|







3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
} -cleanup {
    destroy .e
} -result {1 1 345}

test spinbox-24.1 {error in trace proc attached to the textvariable} -setup {
    destroy .s
} -body {
    trace add variable myvar write traceit
    proc traceit args {error "Intentional error here!"}
    spinbox .s -textvariable myvar -from 1 -to 10
    catch {.s set mystring} result1
    catch {.s insert 0 mystring} result2
    catch {.s delete 0} result3
    catch {.s invoke buttonup} result4
    list $result1 $result2 $result3 $result4
3895
3896
3897
3898
3899
3900
3901




















3902
3903
3904
3905
3906
3907
3908
    destroy .s
} -body {
    catch {spinbox .s -textvariable thisnsdoesntexist::myvar} result1
    set result1
} -cleanup {
    destroy .s
} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}





















# Collected comments about lacks from the test
# XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc,
# and SpinboxTextVarProc.
# No tests for DisplaySpinbox.
# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.
# No tests for EventuallyRedraw







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    destroy .s
} -body {
    catch {spinbox .s -textvariable thisnsdoesntexist::myvar} result1
    set result1
} -cleanup {
    destroy .s
} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}
test spinbox-25.3 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [spinbox .s]
    update
    set res {}
} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    lappend res [.s get]
    .s delete 0 end
    .s insert end "A sample text"
    .s icursor 2
    event generate .s <<NextWord>>  ; # shall move insert to index 9
    .s delete 0 insert
    lappend res [.s get]
} -cleanup {
    destroy .s
} -result {{A sample } text}

# Collected comments about lacks from the test
# XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc,
# and SpinboxTextVarProc.
# No tests for DisplaySpinbox.
# XXX Still need to write tests for SpinboxScanTo and SpinboxSelectTo.
# No tests for EventuallyRedraw

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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# 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 systray-17 {systray icon existence check} -setup {
    catch {tk systray destroy}
} -body {
    tk systray exists
} -result {0}

test systray-18 {systray icon existence check} -setup {
    catch {tk systray destroy}
    image create photo _book -data R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAACwAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IMQCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc0yv+DVSEUuFxIAOw==
} -body {
    tk systray create -image _book -text "Systray test"
    tk systray exists
} -cleanup {
    tk systray destroy
    image delete _book
} -result {1}


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
14
15
16
17
18
19
20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
# This file is a Tcl script to test the code in the file tkText.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.
wm geometry . {}
wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .



test text-1.1 {configuration option: "autoseparators"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -autoseparators yes
    .t cget -autoseparators
} -cleanup {
    destroy .t
} -result 1
test text-1.1b {configuration option: "autoseparators", default} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t cget -autoseparators
} -cleanup {
    destroy .t
} -result 1
test text-1.2 {configuration option: "autoseparators"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -autoseparators nah
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.3 {configuration option: "background"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -background #ff00ff
    .t cget -background
} -cleanup {
    destroy .t
} -result {#ff00ff}
test text-1.4 {configuration option: "background"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -background <gorp>
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.5 {configuration option: "bd"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bd 4
    .t cget -bd
} -cleanup {
    destroy .t
} -result 4
test text-1.6 {configuration option: "bd"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bd foo
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.7 {configuration option: "bg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bg blue
    .t cget -bg
} -cleanup {
    destroy .t
} -result {blue}
test text-1.8 {configuration option: "bg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bg #xx
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.9 {configuration option: "blockcursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -blockcursor 0
    .t cget -blockcursor
} -cleanup {
    destroy .t
} -result 0
test text-1.10 {configuration option: "blockcursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -blockcursor xx
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.11 {configuration option: "borderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -borderwidth 7
    .t cget -borderwidth
} -cleanup {
    destroy .t
} -result 7
test text-1.12 {configuration option: "borderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -borderwidth ++
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.13 {configuration option: "cursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -cursor watch
    .t cget -cursor
} -cleanup {
    destroy .t
} -result {watch}
test text-1.14 {configuration option: "cursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -cursor lousy
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.15 {configuration option: "exportselection"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -exportselection no
    .t cget -exportselection
} -cleanup {
    destroy .t
} -result 0
test text-1.16 {configuration option: "exportselection"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -exportselection maybe
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.17 {configuration option: "fg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -fg red
    .t cget -fg
} -cleanup {
    destroy .t
} -result {red}
test text-1.18 {configuration option: "fg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -fg stupid
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.19 {configuration option: "font"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -font fixed
    .t cget -font
} -cleanup {
    destroy .t
} -result {fixed}
test text-1.20 {configuration option: "font"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -font {}
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.21 {configuration option: "foreground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -foreground #012
    .t cget -foreground
} -cleanup {
    destroy .t
} -result {#012}
test text-1.22 {configuration option: "foreground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -foreground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.23 {configuration option: "height"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -height 5
    .t cget -height
} -cleanup {
    destroy .t
} -result 5
test text-1.24 {configuration option: "height"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -height bad
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.25 {configuration option: "highlightbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightbackground #123
    .t cget -highlightbackground
} -cleanup {
    destroy .t
} -result {#123}
test text-1.26 {configuration option: "highlightbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.27 {configuration option: "highlightcolor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightcolor #234
    .t cget -highlightcolor
} -cleanup {
    destroy .t
} -result {#234}
test text-1.28 {configuration option: "highlightcolor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightcolor bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.29 {configuration option: "highlightthickness"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightthickness -2
    .t cget -highlightthickness
} -cleanup {
    destroy .t
} -result 0
test text-1.30 {configuration option: "highlightthickness"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightthickness bad
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.31 {configuration option: "inactiveselectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -inactiveselectbackground #ffff01234567
    .t cget -inactiveselectbackground
} -cleanup {
    destroy .t
} -result {#ffff01234567}
test text-1.32 {configuration option: "inactiveselectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -inactiveselectbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.33 {configuration option: "insertbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertbackground green
    .t cget -insertbackground
} -cleanup {
    destroy .t
} -result {green}
test text-1.34 {configuration option: "insertbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertbackground <bogus>
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.35 {configuration option: "insertborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertborderwidth 45
    .t cget -insertborderwidth
} -cleanup {
    destroy .t
} -result 45
test text-1.36 {configuration option: "insertborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertborderwidth bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.37 {configuration option: "insertofftime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertofftime 100
    .t cget -insertofftime
} -cleanup {
    destroy .t
} -result 100
test text-1.38 {configuration option: "insertofftime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertofftime 2.4
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.39 {configuration option: "insertontime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertontime 47
    .t cget -insertontime
} -cleanup {
    destroy .t
} -result 47
test text-1.40 {configuration option: "insertontime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertontime e1
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.41 {configuration option: "insertwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertwidth 2.3
    .t cget -insertwidth
} -cleanup {
    destroy .t
} -result 2
test text-1.42 {configuration option: "insertwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertwidth 47d
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.43 {configuration option: "maxundo"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -maxundo 5
    .t cget -maxundo
} -cleanup {
    destroy .t
} -result 5
test text-1.43b {configuration option: "maxundo", default} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t cget -maxundo
} -cleanup {
    destroy .t
} -result 0
test text-1.44 {configuration option: "maxundo"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -maxundo noway
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.45 {configuration option: "padx"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -padx 3.4
    .t cget -padx
} -cleanup {
    destroy .t
} -result 3
test text-1.46 {configuration option: "padx"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -padx 2.4.
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.47 {configuration option: "pady"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -pady 82
    .t cget -pady
} -cleanup {
    destroy .t
} -result 82
test text-1.48 {configuration option: "pady"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -pady bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.49 {configuration option: "relief"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -relief raised
    .t cget -relief
} -cleanup {
    destroy .t
} -result {raised}
test text-1.50 {configuration option: "relief"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -relief bumpy
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.51 {configuration option: "selectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectbackground #ffff01234567
    .t cget -selectbackground
} -cleanup {
    destroy .t
} -result {#ffff01234567}
test text-1.52 {configuration option: "selectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.53 {configuration option: "selectborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectborderwidth 21
    .t cget -selectborderwidth
} -cleanup {
    destroy .t
} -result 21
test text-1.54 {configuration option: "selectborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectborderwidth 3x
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.55 {configuration option: "selectforeground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectforeground yellow
    .t cget -selectforeground
} -cleanup {
    destroy .t
} -result {yellow}
test text-1.56 {configuration option: "selectforeground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectforeground #12345
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.57 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 20
    .t cget -spacing1
} -cleanup {
    destroy .t
} -result 20
test text-1.58 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 1.3x
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.59 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 -5
    .t cget -spacing1
} -cleanup {
    destroy .t
} -result 0
test text-1.60 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.61 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 5
    .t cget -spacing2
} -cleanup {
    destroy .t
} -result 5
test text-1.62 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.63 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 -1
    .t cget -spacing2
} -cleanup {
    destroy .t
} -result 0
test text-1.64 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.65 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 20
    .t cget -spacing3
} -cleanup {
    destroy .t
} -result 20
test text-1.66 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.67 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 -10
    .t cget -spacing3
} -cleanup {
    destroy .t
} -result 0
test text-1.68 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.69 {configuration option: "state"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -state d
    .t cget -state
} -cleanup {
    destroy .t
} -result {disabled}
test text-1.70 {configuration option: "state"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -state foo
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.71 {configuration option: "tabs"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabs {1i 2i 3i 4i}
    .t cget -tabs
} -cleanup {
    destroy .t
} -result {1i 2i 3i 4i}
test text-1.72 {configuration option: "tabs"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabs bad_tabs
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.73 {configuration option: "tabstyle"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabstyle wordprocessor
    .t cget -tabstyle
} -cleanup {
    destroy .t
} -result {wordprocessor}
test text-1.74 {configuration option: "tabstyle"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabstyle garbage
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.75 {configuration option: "undo"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -undo 1
    .t cget -undo
} -cleanup {
    destroy .t
} -result 1
test text-1.75b {configuration option: "undo", default} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t cget -undo
} -cleanup {
    destroy .t
} -result 0
test text-1.76 {configuration option: "undo"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -undo eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.77 {configuration option: "width"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -width 73
    .t cget -width
} -cleanup {
    destroy .t
} -result 73
test text-1.78 {configuration option: "width"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -width 2.4
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.79 {configuration option: "wrap"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -wrap w
    .t cget -wrap
} -cleanup {
    destroy .t
} -result {word}
test text-1.80 {configuration option: "wrap"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -wrap bad_wrap
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.81 {text options} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -takefocus "any old thing"
    .t cget -takefocus
} -cleanup {
    destroy .t
} -result {any old thing}
test text-1.82 {text options} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -xscrollcommand "x scroll command"
    .t configure -xscrollcommand
} -cleanup {
    destroy .t
} -result {-xscrollcommand xScrollCommand ScrollCommand {} {x scroll command}}
test text-1.83 {text options} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -yscrollcommand "test command"
    .t configure -yscrollcommand
} -cleanup {
    destroy .t
} -result {-yscrollcommand yScrollCommand ScrollCommand {} {test command}}
test text-1.83.1 {configuration option: "insertunfocussed"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertunfocussed none
    .t cget -insertunfocussed
} -cleanup {
    destroy .t
} -result none
test text-1.84 {configuration option: "insertunfocussed"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertunfocussed hollow
    .t cget -insertunfocussed
} -cleanup {
    destroy .t
} -result hollow
test text-1.85 {configuration option: "insertunfocussed"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertunfocussed solid
    .t cget -insertunfocussed
} -cleanup {
    destroy .t
} -result solid
test text-1.86 {configuration option: "insertunfocussed"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -returnCodes error -body {
    .t configure -insertunfocussed gorp
} -cleanup {
    destroy .t
} -result {bad insertunfocussed "gorp": must be hollow, none, or solid}




































































































































































































































test text-2.1 {Tk_TextCmd procedure} -body {
    text
} -returnCodes {error} -result {wrong # args: should be "text pathName ?-option value ...?"}
test text-2.2 {Tk_TextCmd procedure} -body {
    text foobar





|














|
>
>

|







|








|

|








|









|








|







|

|








|









|








|







|

|








|







|










|









|








|







|

|








|









|








|









|








|









|








|







|

|








|









|








|









|








|







|

|








|









|








|









|








|







|

|








|







|

|








|







|

|








|







|

|








|







|








|

|








|







|

|








|







|

|








|









|








|









|








|







|

|








|









|








|







|

|








|







|

|








|







|

|








|







|

|








|







|

|








|







|

|








|









|








|









|








|









|








|







|








|

|








|







|

|








|









|








|









|









|









|









|









|









|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
# This file is a Tcl script to test the code in the file tkText.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.
wm geometry . {}
wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

text .t; .t debug on; destroy .t

test text-1.1 {configuration option: "autoseparators"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -autoseparators yes
    .t cget -autoseparators
} -cleanup {
    destroy .t
} -result {1}
test text-1.1b {configuration option: "autoseparators", default} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t cget -autoseparators
} -cleanup {
    destroy .t
} -result {1}
test text-1.2 {configuration option: "autoseparators"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -autoseparators nah
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.3 {configuration option: "background"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -background #ff00ff
    .t cget -background
} -cleanup {
    destroy .t
} -result {#ff00ff}
test text-1.4 {configuration option: "background"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -background <gorp>
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.5 {configuration option: "bd"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -bd 4
    .t cget -bd
} -cleanup {
    destroy .t
} -result {4}
test text-1.6 {configuration option: "bd"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -bd foo
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.7 {configuration option: "bg"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -bg blue
    .t cget -bg
} -cleanup {
    destroy .t
} -result {blue}
test text-1.8 {configuration option: "bg"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -bg #xx
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.9 {configuration option: "blockcursor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -blockcursor 0
    .t cget -blockcursor
} -cleanup {
    destroy .t
} -result {0}
test text-1.10 {configuration option: "blockcursor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -blockcursor xx
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.11 {configuration option: "borderwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -borderwidth 7
    .t cget -borderwidth
} -cleanup {
    destroy .t
} -result {7}
test text-1.12 {configuration option: "borderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -borderwidth ++
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.13 {configuration option: "cursor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -cursor watch
    .t cget -cursor
} -cleanup {
    destroy .t
} -result {watch}
test text-1.14 {configuration option: "cursor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -cursor lousy
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.15 {configuration option: "exportselection"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -exportselection no
    .t cget -exportselection
} -cleanup {
    destroy .t
} -result {0}
test text-1.16 {configuration option: "exportselection"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -exportselection maybe
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.17 {configuration option: "fg"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -fg red
    .t cget -fg
} -cleanup {
    destroy .t
} -result {red}
test text-1.18 {configuration option: "fg"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -fg stupid
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.19 {configuration option: "font"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -font fixed
    .t cget -font
} -cleanup {
    destroy .t
} -result {fixed}
test text-1.20 {configuration option: "font"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -font {}
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.21 {configuration option: "foreground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -foreground #012
    .t cget -foreground
} -cleanup {
    destroy .t
} -result {#012}
test text-1.22 {configuration option: "foreground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -foreground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.23 {configuration option: "height"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -height 5
    .t cget -height
} -cleanup {
    destroy .t
} -result {5}
test text-1.24 {configuration option: "height"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -height bad
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.25 {configuration option: "highlightbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -highlightbackground #123
    .t cget -highlightbackground
} -cleanup {
    destroy .t
} -result {#123}
test text-1.26 {configuration option: "highlightbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -highlightbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.27 {configuration option: "highlightcolor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -highlightcolor #234
    .t cget -highlightcolor
} -cleanup {
    destroy .t
} -result {#234}
test text-1.28 {configuration option: "highlightcolor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -highlightcolor bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.29 {configuration option: "highlightthickness"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -highlightthickness -2
    .t cget -highlightthickness
} -cleanup {
    destroy .t
} -result {0}
test text-1.30 {configuration option: "highlightthickness"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -highlightthickness bad
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.31 {configuration option: "inactiveselectbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -inactiveselectbackground #ffff01234567
    .t cget -inactiveselectbackground
} -cleanup {
    destroy .t
} -result {#ffff01234567}
test text-1.32 {configuration option: "inactiveselectbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -inactiveselectbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.33 {configuration option: "insertbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertbackground green
    .t cget -insertbackground
} -cleanup {
    destroy .t
} -result {green}
test text-1.34 {configuration option: "insertbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertbackground <bogus>
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.35 {configuration option: "insertborderwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertborderwidth 45
    .t cget -insertborderwidth
} -cleanup {
    destroy .t
} -result {45}
test text-1.36 {configuration option: "insertborderwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertborderwidth bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.37 {configuration option: "insertofftime"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertofftime 100
    .t cget -insertofftime
} -cleanup {
    destroy .t
} -result {100}
test text-1.38 {configuration option: "insertofftime"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertofftime 2.4
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.39 {configuration option: "insertontime"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertontime 47
    .t cget -insertontime
} -cleanup {
    destroy .t
} -result {47}
test text-1.40 {configuration option: "insertontime"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertontime e1
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.41 {configuration option: "insertwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertwidth 2.3
    .t cget -insertwidth
} -cleanup {
    destroy .t
} -result {2}
test text-1.42 {configuration option: "insertwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertwidth 47d
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.43 {configuration option: "maxundo"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -maxundo 5
    .t cget -maxundo
} -cleanup {
    destroy .t
} -result {5}
test text-1.43b {configuration option: "maxundo", default} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t cget -maxundo
} -cleanup {
    destroy .t
} -result {0}
test text-1.44 {configuration option: "maxundo"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -maxundo noway
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.45 {configuration option: "padx"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -padx 3.4
    .t cget -padx
} -cleanup {
    destroy .t
} -result {3}
test text-1.46 {configuration option: "padx"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -padx 2.4.
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.47 {configuration option: "pady"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -pady 82
    .t cget -pady
} -cleanup {
    destroy .t
} -result {82}
test text-1.48 {configuration option: "pady"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -pady bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.49 {configuration option: "relief"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -relief raised
    .t cget -relief
} -cleanup {
    destroy .t
} -result {raised}
test text-1.50 {configuration option: "relief"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -relief bumpy
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.51 {configuration option: "selectbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -selectbackground #ffff01234567
    .t cget -selectbackground
} -cleanup {
    destroy .t
} -result {#ffff01234567}
test text-1.52 {configuration option: "selectbackground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -selectbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.53 {configuration option: "selectborderwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -selectborderwidth 21
    .t cget -selectborderwidth
} -cleanup {
    destroy .t
} -result {21}
test text-1.54 {configuration option: "selectborderwidth"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -selectborderwidth 3x
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.55 {configuration option: "selectforeground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -selectforeground yellow
    .t cget -selectforeground
} -cleanup {
    destroy .t
} -result {yellow}
test text-1.56 {configuration option: "selectforeground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -selectforeground #12345
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.57 {configuration option: "spacing1"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing1 20
    .t cget -spacing1
} -cleanup {
    destroy .t
} -result {20}
test text-1.58 {configuration option: "spacing1"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing1 1.3x
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.59 {configuration option: "spacing1"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing1 -5
    .t cget -spacing1
} -cleanup {
    destroy .t
} -result {0}
test text-1.60 {configuration option: "spacing1"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing1 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.61 {configuration option: "spacing2"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing2 5
    .t cget -spacing2
} -cleanup {
    destroy .t
} -result {5}
test text-1.62 {configuration option: "spacing2"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing2 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.63 {configuration option: "spacing2"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing2 -1
    .t cget -spacing2
} -cleanup {
    destroy .t
} -result {0}
test text-1.64 {configuration option: "spacing2"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing2 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.65 {configuration option: "spacing3"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing3 20
    .t cget -spacing3
} -cleanup {
    destroy .t
} -result {20}
test text-1.66 {configuration option: "spacing3"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing3 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.67 {configuration option: "spacing3"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing3 -10
    .t cget -spacing3
} -cleanup {
    destroy .t
} -result {0}
test text-1.68 {configuration option: "spacing3"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -spacing3 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.69 {configuration option: "state"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -state d
    .t cget -state
} -cleanup {
    destroy .t
} -result {disabled}
test text-1.70 {configuration option: "state"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -state foo
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.71 {configuration option: "tabs"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -tabs {1i 2i 3i 4i}
    .t cget -tabs
} -cleanup {
    destroy .t
} -result {1i 2i 3i 4i}
test text-1.72 {configuration option: "tabs"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -tabs bad_tabs
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.73 {configuration option: "tabstyle"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -tabstyle wordprocessor
    .t cget -tabstyle
} -cleanup {
    destroy .t
} -result {wordprocessor}
test text-1.74 {configuration option: "tabstyle"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -tabstyle garbage
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.75 {configuration option: "undo"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -undo 1
    .t cget -undo
} -cleanup {
    destroy .t
} -result {1}
test text-1.75b {configuration option: "undo", default} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t cget -undo
} -cleanup {
    destroy .t
} -result {0}
test text-1.76 {configuration option: "undo"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -undo eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.77 {configuration option: "width"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -width 73
    .t cget -width
} -cleanup {
    destroy .t
} -result {73}
test text-1.78 {configuration option: "width"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -width 2.4
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.79 {configuration option: "wrap"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -wrap w
    .t cget -wrap
} -cleanup {
    destroy .t
} -result {word}
test text-1.80 {configuration option: "wrap"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -wrap bad_wrap
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.81 {text options} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -takefocus "any old thing"
    .t cget -takefocus
} -cleanup {
    destroy .t
} -result {any old thing}
test text-1.82 {text options} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -xscrollcommand "x scroll command"
    .t configure -xscrollcommand
} -cleanup {
    destroy .t
} -result {-xscrollcommand xScrollCommand ScrollCommand {} {x scroll command}}
test text-1.83 {text options} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -yscrollcommand "test command"
    .t configure -yscrollcommand
} -cleanup {
    destroy .t
} -result {-yscrollcommand yScrollCommand ScrollCommand {} {test command}}
test text-1.83.1 {configuration option: "insertunfocussed"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertunfocussed none
    .t cget -insertunfocussed
} -cleanup {
    destroy .t
} -result none
test text-1.84 {configuration option: "insertunfocussed"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertunfocussed hollow
    .t cget -insertunfocussed
} -cleanup {
    destroy .t
} -result hollow
test text-1.85 {configuration option: "insertunfocussed"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -insertunfocussed solid
    .t cget -insertunfocussed
} -cleanup {
    destroy .t
} -result solid
test text-1.86 {configuration option: "insertunfocussed"} -setup {
    text .t
    pack .t
    update
} -returnCodes error -body {
    .t configure -insertunfocussed gorp
} -cleanup {
    destroy .t
} -result {bad insertunfocussed "gorp": must be hollow, none, or solid}
test text-1.87 {configuration option: "eolcolor"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -eolcolor yellow
    .t cget -eolcolor
} -cleanup {
    destroy .t
} -result yellow
test text-1.88 {configuration option: "eolcolor"} -setup {
    text .t
    pack .t
    update
} -returnCodes error -body {
    .t configure -eolcolor gorp
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.89 {configuration option: "hyphenrules"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -hyphenrules {ck trema}
    .t cget -hyphenrules
} -cleanup {
    destroy .t
} -result {ck trema}
test text-1.90 {configuration option: "hyphenrules"} -setup {
    text .t
    pack .t
    update
} -returnCodes error -body {
    .t configure -hyphenrules gorp
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.91 {configuration option: "hyphens"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -hyphens 1
    .t cget -hyphens
} -cleanup {
    destroy .t
} -result {1}
test text-1.92 {configuration option: "hyphens"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -hyphens eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.93 {configuration option: "lang"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -lang en
    .t cget -lang
} -cleanup {
    destroy .t
} -result {en}
test text-1.94 {configuration option: "lang"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -lang gorp
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.95 {configuration option: "maxundosize"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -maxundosize 1000
    .t cget -maxundosize
} -cleanup {
    destroy .t
} -result {1000}
test text-1.96 {configuration option: "maxundosize"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -maxundosize noway
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.97 {configuration option: "responsiveness"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -responsiveness 75
    .t cget -responsiveness
} -cleanup {
    destroy .t
} -result {75}
test text-1.98 {configuration option: "responsiveness"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -responsiveness noway
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.99 {configuration option: "showendofline"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -showendofline 1
    .t cget -showendofline
} -cleanup {
    destroy .t
} -result {1}
test text-1.100 {configuration option: "showendofline"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -showendofline eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.101 {configuration option: "showinsertforeground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -showinsertforeground 1
    .t cget -showinsertforeground
} -cleanup {
    destroy .t
} -result {1}
test text-1.102 {configuration option: "showinsertforeground"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -showinsertforeground eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.103 {configuration option: "steadymarks"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -steadymarks 1
    .t cget -steadymarks
} -cleanup {
    destroy .t
} -result {1}
test text-1.104 {configuration option: "steadymarks"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -steadymarks eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.105 {configuration option: "tagging"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -tagging none
    .t cget -tagging
} -cleanup {
    destroy .t
} -result {none}
test text-1.106 {configuration option: "tagging"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -tagging eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.107 {configuration option: "useunibreak"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -useunibreak 1
    .t cget -useunibreak
} -cleanup {
    destroy .t
} -result {1}
test text-1.108 {configuration option: "useunibreak"} -setup {
    text .t
    pack .t
    update
} -body {
    .t configure -useunibreak eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
test text-1.109 {configuration option: "undotagging"} -setup {
    text .t
    update
} -body {
    .t configure -undotagging 0
    .t cget -undotagging
} -cleanup {
    destroy .t
} -result {0}
test text-1.110 {configuration option: "undotagging"} -setup {
    text .t
    update
} -body {
    .t configure -undotagging eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}


test text-2.1 {Tk_TextCmd procedure} -body {
    text
} -returnCodes {error} -result {wrong # args: should be "text pathName ?-option value ...?"}
test text-2.2 {Tk_TextCmd procedure} -body {
    text foobar
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
} -returnCodes {error} -result {wrong # args: should be ".t option ?arg ...?"}
test text-3.2 {TextWidgetCmd procedure} -setup {
    text .t
} -body {
    .t gorp 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "gorp": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview}

test text-4.1 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t bbox index"}
test text-4.2 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t bbox index"}
test text-4.3 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox bad_mark
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "bad_mark"}







|







|






|







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
} -returnCodes {error} -result {wrong # args: should be ".t option ?arg ...?"}
test text-3.2 {TextWidgetCmd procedure} -setup {
    text .t
} -body {
    .t gorp 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "gorp": must be bbox, brks, checksum, cget, clear, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, inspect, isclean, isdead, isempty, lineno, load, mark, peer, pendingsync, replace, scan, search, see, sync, tag, watch, window, xview, or yview}

test text-4.1 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t bbox ?-extents? index"}
test text-4.2 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t bbox ?-extents? index"}
test text-4.3 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox bad_mark
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "bad_mark"}
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
test text-5.4 {TextWidgetCmd procedure, "cget" option} -setup {
    text .t
} -body {
    .t configure -bd 17
    .t cget -bd
} -cleanup {
    destroy .t
} -result 17


test text-6.1 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t compare a b
} -cleanup {







|







1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
test text-5.4 {TextWidgetCmd procedure, "cget" option} -setup {
    text .t
} -body {
    .t configure -bd 17
    .t cget -bd
} -cleanup {
    destroy .t
} -result {17}


test text-6.1 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t compare a b
} -cleanup {
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
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t co 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "co": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview}
# "configure" option is already covered above

test text-7.1 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug 0 1
} -cleanup {

    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t debug boolean"}
test text-7.2 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t de 0 1
} -cleanup {

    destroy .t
} -returnCodes {error} -result {ambiguous option "de": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview}
test text-7.3 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug true
    .t deb
} -cleanup {
    destroy .t
} -result 1
test text-7.4 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug false
    .t debug
} -cleanup {

    destroy .t
} -result 0


test text-8.1 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t delete index1 ?index2 ...?"}
test text-8.2 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete a b c
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}







|







>







>

|







|






>

|








|







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
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t co 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "co": must be bbox, brks, checksum, cget, clear, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, inspect, isclean, isdead, isempty, lineno, load, mark, peer, pendingsync, replace, scan, search, see, sync, tag, watch, window, xview, or yview}
# "configure" option is already covered above

test text-7.1 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug 0 1
} -cleanup {
    .t debug on
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t debug boolean"}
test text-7.2 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t de 0 1
} -cleanup {
    .t debug on
    destroy .t
} -returnCodes {error} -result {ambiguous option "de": must be bbox, brks, checksum, cget, clear, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, inspect, isclean, isdead, isempty, lineno, load, mark, peer, pendingsync, replace, scan, search, see, sync, tag, watch, window, xview, or yview}
test text-7.3 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug true
    .t deb
} -cleanup {
    destroy .t
} -result {1}
test text-7.4 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug false
    .t debug
} -cleanup {
    .t debug on
    destroy .t
} -result {0}


test text-8.1 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t delete ?-marks? ?-inclusive? index1 ?index2 ...?"}
test text-8.2 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete a b c
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
    .t configure -undo 1
    # Ensure it is treated as a single undo action
    .t replace 2.1 2.3 foo
    .t edit undo
    string equal [.t get 1.0 end-1c] $prevtext
} -cleanup {
    destroy .t
} -result 1
test text-8.22 {TextWidgetCmd procedure, "replace" option with undo} -setup {
    text .t
    set res {}
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345







|







1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
    .t configure -undo 1
    # Ensure it is treated as a single undo action
    .t replace 2.1 2.3 foo
    .t edit undo
    string equal [.t get 1.0 end-1c] $prevtext
} -cleanup {
    destroy .t
} -result {1}
test text-8.22 {TextWidgetCmd procedure, "replace" option with undo} -setup {
    text .t
    set res {}
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
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
    proc .t {args} { lappend ::res $args ; uplevel 1 test.t $args }
    .t edit undo
    return $res
} -cleanup {
    rename .t {}
    rename test.t .t
    destroy .t
} -result [list {edit undo} {delete 2.1 2.4} {mark set insert 2.1} {see insert} \
                {mark set tk::undoMarkL2 2.1} {mark set tk::undoMarkR2 2.4} \
                {mark gravity tk::undoMarkL2 left} {mark gravity tk::undoMarkR2 right} \
                {insert 2.1 ef} {mark set insert 2.3} {see insert} \
                {mark set tk::undoMarkL1 2.1} {mark set tk::undoMarkR1 2.3} \
                {mark gravity tk::undoMarkL1 left} {mark gravity tk::undoMarkR1 right} \
                {mark names} \
                {index tk::undoMarkL1} {index tk::undoMarkR1} \
                {mark unset tk::undoMarkL1 tk::undoMarkR1} \
                {index tk::undoMarkL2} {index tk::undoMarkR2} \
                {mark unset tk::undoMarkL2 tk::undoMarkR2} \
                {compare 2.1 > 2.3} {compare 2.6 > 2.3} ]

test text-8.23 {TextWidgetCmd procedure, "replace" option with undo} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
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 -startline 1 -endline 1
    .t edit undo
    .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
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    set prevtext [.t get 1.0 end-1c]
    .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 -startline 1 -endline 1
    destroy .tt
    .t edit undo
    .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
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    set prevtext [.t get 1.0 end-1c]
    .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
# which isn't showing everything.
    .tt replace 2.1 2.3 foo
    set res [.tt get 2.1 2.4]
    .tt configure -startline 1 -endline 1
    destroy .tt
    .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 -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 {







<
<
<
<
<
<
<
<
<
<
<
<
|
















|

|




|


















|


|




|




















|

|




|







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
    proc .t {args} { lappend ::res $args ; uplevel 1 test.t $args }
    .t edit undo
    return $res
} -cleanup {
    rename .t {}
    rename test.t .t
    destroy .t












} -result {{edit undo}}
test text-8.23 {TextWidgetCmd procedure, "replace" option with undo} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
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 edit undo
    .t configure -start {} -end {}
    .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
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    set prevtext [.t get 1.0 end-1c]
    .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
    destroy .tt
    .t edit undo
    .t configure -start {} -end {}
    .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
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    set prevtext [.t get 1.0 end-1c]
    .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
# 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
    destroy .tt
    .t configure -start 3 -end 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 {}
    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 {
1604
1605
1606
1607
1608
1609
1610










1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
} -body {
    .tt insert end "foo\n"
    .tt tag add sel 1.0 end
    .tt replace sel.first sel.last "bar"
} -cleanup {
    destroy .tt
} -result {}












test text-9.1 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t get ?-displaychars? ?--? index1 ?index2 ...?"}
test text-9.2 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get a b c
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}







>
>
>
>
>
>
>
>
>
>








|







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
} -body {
    .tt insert end "foo\n"
    .tt tag add sel 1.0 end
    .tt replace sel.first sel.last "bar"
} -cleanup {
    destroy .tt
} -result {}
test text-8.29 {"delete" tagged newline} -setup {
    text .tt
} -body {
    .tt insert end \n tag1
    .tt delete 2.0
    # wish8.6.5 returns empty list, this is a bug
    .tt tag ranges tag1
} -cleanup {
    destroy .tt
} -result {1.0 2.0}


test text-9.1 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t get ?-option? ?--? index1 ?index2 ...?"}
test text-9.2 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get a b c
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}
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}
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"}







|







2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
} -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, -displayhyphens, -displayindices, -displaylines, -displaytext, -hyphens, -indices, -lines, -text, -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"}
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
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.3 5.5
} -cleanup {
    destroy .t
} -result 2
test text-10.8 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t count 5.3 end
} -cleanup {
    destroy .t
} -result 29
test text-10.9 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 5.7
} -cleanup {
    destroy .t
} -result 5
test text-10.10 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 5.3
} -cleanup {
    destroy .t
} -result 1
test text-10.11 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 5.4
} -cleanup {
    destroy .t
} -result 2
test text-10.12 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz







|













|













|













|













|







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
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.3 5.5
} -cleanup {
    destroy .t
} -result {2}
test text-10.8 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t count 5.3 end
} -cleanup {
    destroy .t
} -result {29}
test text-10.9 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 5.7
} -cleanup {
    destroy .t
} -result {5}
test text-10.10 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 5.3
} -cleanup {
    destroy .t
} -result {1}
test text-10.11 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 5.4
} -cleanup {
    destroy .t
} -result {2}
test text-10.12 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
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
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t count -displayindices 2.0 3.0
} -cleanup {
    destroy .t
} -result 2
test text-10.14 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t count -displayindices 2.2 3.0
} -cleanup {
    destroy .t
} -result 0
test text-10.15 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t count -displayindices 2.0 4.2
} -cleanup {
    destroy .t
} -result 5
test text-10.16 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.0 3.0
} -cleanup {
    destroy .t
} -result 3
test text-10.17 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.2 3.0
} -cleanup {
    destroy .t
} -result 1
test text-10.18 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
    .t mark set a 2.2
# Creating this window here means that the elidden text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices a 3.0
} -cleanup {
    destroy .t
} -result 0
test text-10.19 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.0 4.2
} -cleanup {
    destroy .t
} -result 6
test text-10.20 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 3.0
} -cleanup {
    destroy .t
} -result 2
test text-10.21 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.2 3.0
} -cleanup {
    destroy .t
} -result 1
test text-10.22 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars a 3.0
} -cleanup {
    destroy .t
} -result 0
test text-10.23 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
} -cleanup {
    destroy .t
} -result 5
test text-10.24 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    list [.t count -indices 2.2 3.0] [.t count 2.2 3.0]
} -cleanup {
    destroy .t







|















|
















|















|






|















|






|

















|






|
















|






|
















|






|
















|






|

















|






|
















|






|
















|







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
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t count -displayindices 2.0 3.0
} -cleanup {
    destroy .t
} -result {2}
test text-10.14 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t count -displayindices 2.2 3.0
} -cleanup {
    destroy .t
} -result {0}
test text-10.15 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t count -displayindices 2.0 4.2
} -cleanup {
    destroy .t
} -result {5}
test text-10.16 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.0 3.0
} -cleanup {
    destroy .t
} -result {3}
test text-10.17 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.2 3.0
} -cleanup {
    destroy .t
} -result {1}
test text-10.18 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
    .t mark set a 2.2
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices a 3.0
} -cleanup {
    destroy .t
} -result {0}
test text-10.19 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.0 4.2
} -cleanup {
    destroy .t
} -result {6}
test text-10.20 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 3.0
} -cleanup {
    destroy .t
} -result {2}
test text-10.21 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.2 3.0
} -cleanup {
    destroy .t
} -result {1}
test text-10.22 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars a 3.0
} -cleanup {
    destroy .t
} -result {0}
test text-10.23 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
} -cleanup {
    destroy .t
} -result {5}
test text-10.24 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    list [.t count -indices 2.2 3.0] [.t count 2.2 3.0]
} -cleanup {
    destroy .t
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    list [.t count -indices a 3.0] [.t count a 3.0]
} -cleanup {
    destroy .t
} -result {9 9}







|







2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    list [.t count -indices a 3.0] [.t count a 3.0]
} -cleanup {
    destroy .t
} -result {9 9}
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
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
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -indices 2.0 4.2
} -cleanup {
    destroy .t
} -result 21
test text-10.27 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -chars 2.2 3.0
} -cleanup {
    destroy .t
} -result 10
test text-10.28 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -chars a 3.0
} -cleanup {
    destroy .t
} -result 9
test text-10.29 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -chars 2.0 4.2
} -cleanup {
    destroy .t
} -result 19
test text-10.30 {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 end
} -cleanup {
    destroy .t
} -result 3
test text-10.31 {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 1.0
} -cleanup {
    destroy .t
} -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}
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
} -cleanup {
    destroy .t
} -result 0
test text-10.34 {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.5 2.5
} -cleanup {
    destroy .t
} -result 1
test text-10.35 {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 2.5 "2.5 lineend"
} -cleanup {
    destroy .t
} -result 0
test text-10.36 {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 2.7 "1.0 lineend"
} -cleanup {
    destroy .t
} -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
    .t count -displaylines 1.0 end
} -cleanup {
    destroy .t
} -result 3
test text-10.38 {TextWidgetCmd procedure, "count" option} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .t -expand 1 -fill both
} -body {
    .t configure -width 20 -height 10
    update
    .t insert end [string repeat "abcde " 50]\n







|







|
















|







|

















|






|
















|







|









|



















|









|









|









|









|










|







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
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -indices 2.0 4.2
} -cleanup {
    destroy .t
} -result {21}
test text-10.27 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -chars 2.2 3.0
} -cleanup {
    destroy .t
} -result {10}
test text-10.28 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -chars a 3.0
} -cleanup {
    destroy .t
} -result {9}
test text-10.29 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -chars 2.0 4.2
} -cleanup {
    destroy .t
} -result {19}
test text-10.30 {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 end
} -cleanup {
    destroy .t
} -result {3}
test text-10.31 {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 1.0
} -cleanup {
    destroy .t
} -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, -displayhyphens, -displayindices, -displaylines, -displaytext, -hyphens, -indices, -lines, -text, -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
} -cleanup {
    destroy .t
} -result {0}
test text-10.34 {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.5 2.5
} -cleanup {
    destroy .t
} -result {1}
test text-10.35 {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 2.5 "2.5 lineend"
} -cleanup {
    destroy .t
} -result {0}
test text-10.36 {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 2.7 "1.0 lineend"
} -cleanup {
    destroy .t
} -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
    .t count -displaylines 1.0 end
} -cleanup {
    destroy .t
} -result {3}
test text-10.38 {TextWidgetCmd procedure, "count" option} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .t -expand 1 -fill both
} -body {
    .t configure -width 20 -height 10
    update
    .t insert end [string repeat "abcde " 50]\n
2731
2732
2733
2734
2735
2736
2737

2738
2739
2740

2741
2742
2743
2744
2745
2746
2747
} -result {1 3}
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"
    }

    .t tag configure hidden -elide true
    .t tag add hidden 5.7 11.0
    update
    # next line to be fully sure that asynchronous line heights calculation is
    # up-to-date otherwise this test may fail (depending on the computer
    # performance), especially when the . toplevel has small height
    .t sync







>

|

>







2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
} -result {1 3}
test text-10.42 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    pack .t
    update
    set res {}
} -body {
    set str ""
    for {set i 1} {$i < 25} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag configure hidden -elide true
    .t tag add hidden 5.7 11.0
    update
    # next line to be fully sure that asynchronous line heights calculation is
    # up-to-date otherwise this test may fail (depending on the computer
    # performance), especially when the . toplevel has small height
    .t sync
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
} -body {
    .t insert end "hello"
    .t tag configure elide1 -elide 0
    .t tag add elide1 1.2 1.4
    .t count -displaychars 1.0 1.5
} -cleanup {
    destroy .t
} -result 5
test text-11.3 {counting with tag priority eliding} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .t insert end "hello"
# Newer tags are higher priority
    .t tag configure elide1 -elide 0
    .t tag configure elide2 -elide 1
    .t tag add elide1 1.2 1.4
    .t tag add elide2 1.2 1.4
    .t count -displaychars 1.0 1.5
} -cleanup {
    destroy .t
} -result 3
test text-11.4 {counting with tag priority eliding}  -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
    set res {}
} -body {
    .t insert end "hello"
# Newer tags are higher priority
    .t tag configure elide1 -elide 0







|












|







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
} -body {
    .t insert end "hello"
    .t tag configure elide1 -elide 0
    .t tag add elide1 1.2 1.4
    .t count -displaychars 1.0 1.5
} -cleanup {
    destroy .t
} -result {5}
test text-11.3 {counting with tag priority eliding} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .t insert end "hello"
# Newer tags are higher priority
    .t tag configure elide1 -elide 0
    .t tag configure elide2 -elide 1
    .t tag add elide1 1.2 1.4
    .t tag add elide2 1.2 1.4
    .t count -displaychars 1.0 1.5
} -cleanup {
    destroy .t
} -result {3}
test text-11.4 {counting with tag priority eliding}  -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
    set res {}
} -body {
    .t insert end "hello"
# Newer tags are higher priority
    .t tag configure elide1 -elide 0
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
test text-11a.11 {TextWidgetCmd procedure, "sync" option} -setup {
    destroy .yt
} -body {
    text .yt
    list [catch {.yt sync mytext} msg] $msg
} -cleanup {
    destroy .yt
} -result {1 {wrong # args: should be ".yt sync ?-command command?"}}
test text-11a.12 {TextWidgetCmd procedure, "sync" option} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update
    set content {}







|







3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
test text-11a.11 {TextWidgetCmd procedure, "sync" option} -setup {
    destroy .yt
} -body {
    text .yt
    list [catch {.yt sync mytext} msg] $msg
} -cleanup {
    destroy .yt
} -result {1 {wrong # args: should be ".yt sync ?-command ?command??"}}
test text-11a.12 {TextWidgetCmd procedure, "sync" option} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update
    set content {}
3054
3055
3056
3057
3058
3059
3060

































































3061
3062
3063
3064
3065
3066
3067
    .top.yt sync -command [list set ::x 2]
    lappend res $::x                        ; # {1 0 0 1 1}
    vwait ::x
    lappend res $::x                        ; # {1 0 0 1 1 2}
} -cleanup {
    destroy .top.yt .top
} -result {1 0 0 1 1 2}


































































test text-11a.31 {"<<WidgetViewSync>>" event} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    .top.yt sync -command [list set ::x 2]
    lappend res $::x                        ; # {1 0 0 1 1}
    vwait ::x
    lappend res $::x                        ; # {1 0 0 1 1 2}
} -cleanup {
    destroy .top.yt .top
} -result {1 0 0 1 1 2}
test text-11a.23 {TextWidgetCmd procedure, "sync" with update} -setup {
    destroy .yt
} -body {
    # the original implementation gives no result
    text .yt
    .yt insert end "1"
    set res {}
    proc updateAction {} { set ::res 1 }
    .yt sync -command updateAction
    while {[.yt pendingsync]} {
	update
    }
    set res
} -cleanup {
    destroy .yt
} -result {1}
test text-11a.24 {TextWidgetCmd procedure, succeeding "sync"'s} -setup {
    destroy .yt
} -body {
    # the original implementation gives no result
    text .yt
    set res {}
    proc updateAction1 {} { lappend ::res 1 }
    proc updateAction2 {} { lappend ::res 2 }
    .yt sync -command updateAction1
    .yt sync -command +updateAction2
    while {[.yt pendingsync]} {
	update
    }
    set res
} -cleanup {
    destroy .yt
} -result {1 2}
test text-11a.25 {TextWidgetCmd procedure, nested "sync"'s} -setup {
    destroy .yt
} -body {
    # the original implementation gives no result
    text .yt
    set res {}
    proc secondaryUpdateAction {} { lappend ::res 2 }
    proc primaryUpdateaction {} {
	lappend ::res 1
	.yt sync -command secondaryUpdateAction
    }
    .yt sync -command primaryUpdateaction
    while {[.yt pendingsync]} {
	update
    }
    set res
} -cleanup {
    destroy .yt
} -result {1 2}
test text-11a.26 {TextWidgetCmd procedure, "sync -command"} -setup {
    destroy .yt
} -body {
    # the original implementation gives wrong result
    proc Sync {} { set ::res [.yt pendingsync] }
    text .yt
    after 1 [list .yt sync -command Sync]
    after 1 [list .yt insert end "a"]
    vwait ::res
    set res
} -cleanup {
    destroy .yt
} -result {0}

test text-11a.31 {"<<WidgetViewSync>>" event} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update
3086
3087
3088
3089
3090
3091
3092























3093
3094
3095
3096
3097
3098
3099
    lappend res $waited
    .top.yt yview moveto $fraction1
    set fraction2 [lindex [.top.yt yview] 0]
    lappend res [expr {$fraction1 == $fraction2}]
} -cleanup {
    destroy .top.yt .top
} -result {1 1 1}
























test text-11a.41 {"sync" "pendingsync" and <<WidgetViewSync>>} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    lappend res $waited
    .top.yt yview moveto $fraction1
    set fraction2 [lindex [.top.yt yview] 0]
    lappend res [expr {$fraction1 == $fraction2}]
} -cleanup {
    destroy .top.yt .top
} -result {1 1 1}
test text-11a.32 {"<<WidgetViewSync>>" event} -setup {
    destroy .yt
} -body {
    # The original implementation is crashing.
    pack [text .yt]
    bind .yt <<WidgetViewSync>> { destroy .yt }
    .yt sync -command update
} -cleanup {
    destroy .yt
} -result {}
test text-11a.33 {"<<WidgetViewSync>>" event after "sync"} -setup {
    destroy .yt
} -body {
    # The original implementation hangs.
    pack [text .yt]
    bind .yt <<WidgetViewSync>> { set res 1 }
    .yt insert end "test"
    update
    .yt sync
    vwait res
} -cleanup {
    destroy .yt
} -result {}

test text-11a.41 {"sync" "pendingsync" and <<WidgetViewSync>>} -setup {
    destroy .top.yt .top
} -body {
    toplevel .top
    pack [text .top.yt]
    update
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
                  NOT Tk_HandleEvent().
                  Bug [b362182e45704dd7bbd6aed91e48122035ea3d16]} -setup {
    destroy .top.t .top
} -body {
    set res {}
    toplevel .top
    pack [text .top.t]
    update
    for {set i 1} {$i < 10000} {incr i} {
        .top.t insert end "Hello world!\n"
    }
    bind .top.t <<WidgetViewSync>> {destroy .top.t}
    .top.t tag add mytag 1.5 8000.8    ; # shall not crash
    update
    set res "Still doing fine!"
} -cleanup {
    destroy .top.t .top
} -result {Still doing fine!}







<
<
|
<







3445
3446
3447
3448
3449
3450
3451


3452

3453
3454
3455
3456
3457
3458
3459
                  NOT Tk_HandleEvent().
                  Bug [b362182e45704dd7bbd6aed91e48122035ea3d16]} -setup {
    destroy .top.t .top
} -body {
    set res {}
    toplevel .top
    pack [text .top.t]


    .top.t insert end [string repeat "Hello world!\n" 10000]

    bind .top.t <<WidgetViewSync>> {destroy .top.t}
    .top.t tag add mytag 1.5 8000.8    ; # shall not crash
    update
    set res "Still doing fine!"
} -cleanup {
    destroy .top.t .top
} -result {Still doing fine!}
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
} -returnCodes {error} -result {wrong # args: should be ".t index index"}
test text-12.3 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t in a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "in": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview}
test text-12.4 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t index @xyz
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@xyz"}







|







3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
} -returnCodes {error} -result {wrong # args: should be ".t index index"}
test text-12.3 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t in a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "in": must be bbox, brks, checksum, cget, clear, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, inspect, isclean, isdead, isempty, lineno, load, mark, peer, pendingsync, replace, scan, search, see, sync, tag, watch, window, xview, or yview}
test text-12.4 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t index @xyz
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@xyz"}
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314

test text-14.1 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -state foobar
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad state "foobar": must be disabled or normal}
test text-14.2 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -spacing1 -2 -spacing2 1 -spacing3 1
    list [.t cget -spacing1] [.t cget -spacing2] [.t cget -spacing3]
} -cleanup {
    destroy .t







|







3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630

test text-14.1 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -state foobar
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad state "foobar": must be disabled, normal, or readonly}
test text-14.2 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -spacing1 -2 -spacing2 1 -spacing3 1
    list [.t cget -spacing1] [.t cget -spacing2] [.t cget -spacing3]
} -cleanup {
    destroy .t
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
} -result {}
test text-14.8 {ConfigureText procedure} -setup {
   text .t
} -body {
    .t configure -wrap bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad wrap "bogus": must be char, none, or word}
test text-14.9 {ConfigureText procedure} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .t configure -selectborderwidth 17 -selectforeground #332211 \
	    -selectbackground #abc
    list [lindex [.t tag config sel -borderwidth] 4] \
	   [lindex [.t tag config sel -foreground] 4] \







|







3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
} -result {}
test text-14.8 {ConfigureText procedure} -setup {
   text .t
} -body {
    .t configure -wrap bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad wrap "bogus": must be char, none, word, or codepoint}
test text-14.9 {ConfigureText procedure} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .t configure -selectborderwidth 17 -selectforeground #332211 \
	    -selectbackground #abc
    list [lindex [.t tag config sel -borderwidth] 4] \
	   [lindex [.t tag config sel -foreground] 4] \
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
} -result {}
test text-14.11 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -selectborderwidth foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad screen distance "foo"}
test text-14.12 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    .t.e select to 2
    text .t2 -exportselection 1







|







3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
} -result {}
test text-14.11 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -selectborderwidth foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {expected screen distance or "" but got "foo"}
test text-14.12 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    .t.e select to 2
    text .t2 -exportselection 1
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
    .t.e select to 1
    text .t2 -exportselection 1
    .t2 insert insert 1234657890
    .t2 tag add sel 1.0 1.4
    selection get
} -cleanup {
    destroy .t .t2
} -result 1234
test text-14.15 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    .t.e select to 1
    text .t2 -exportselection 0
    .t2 insert insert 1234657890
    .t2 tag add sel 1.0 1.4
    .t2 configure -exportselection 1
    selection get
} -cleanup {
    destroy .t2 .t
} -result 1234
test text-14.16 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    text .t2 -exportselection 1
    .t2 insert insert 1234657890







|













|







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
    .t.e select to 1
    text .t2 -exportselection 1
    .t2 insert insert 1234657890
    .t2 tag add sel 1.0 1.4
    selection get
} -cleanup {
    destroy .t .t2
} -result {1234}
test text-14.15 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    .t.e select to 1
    text .t2 -exportselection 0
    .t2 insert insert 1234657890
    .t2 tag add sel 1.0 1.4
    .t2 configure -exportselection 1
    selection get
} -cleanup {
    destroy .t2 .t
} -result {1234}
test text-14.16 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    text .t2 -exportselection 1
    .t2 insert insert 1234657890
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
    .t2 tag add sel 1.0 1.4
    set result [selection get]
    .t2 configure -exportselection 0
    catch {selection get}
    return $result
} -cleanup {
    destroy .t .t2
} -result 1234
test text-14.18 {ConfigureText procedure} -constraints fonts -setup {
    toplevel .top
    text .top.t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .top.t configure -width 20 -height 10
    pack .top.t
    update
    set geom [wm geometry .top]
    set x [string range $geom 0 [string first + $geom]]
} -cleanup {
    destroy .top
} -result {150x140+}
# This test was failing Windows because the title bar on .t was a certain
# minimum size and it was interfering with the size requested by the -setgrid.
# The "overrideredirect" gets rid of the titlebar so the toplevel can shrink
# to the appropriate size.
# On macOS, however, there is no way to make the window overlap the menubar.
if {[tk windowingsystem] == "aqua"} {
    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







|

















|







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
    .t2 tag add sel 1.0 1.4
    set result [selection get]
    .t2 configure -exportselection 0
    catch {selection get}
    return $result
} -cleanup {
    destroy .t .t2
} -result {1234}
test text-14.18 {ConfigureText procedure} -constraints fonts -setup {
    toplevel .top
    text .top.t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .top.t configure -width 20 -height 10
    pack .top.t
    update
    set geom [wm geometry .top]
    set x [string range $geom 0 [string first + $geom]]
} -cleanup {
    destroy .top
} -result {150x140+}
# This test was failing Windows because the title bar on .t was a certain
# minimum size and it was interfering with the size requested by the -setgrid.
# The "overrideredirect" gets rid of the titlebar so the toplevel can shrink
# to the appropriate size.
# On macOS, however, there is no way to make the window overlap the menubar.
if {[tk windowingsystem] eq "aqua"} {
    set minY [expr [menubarheight] + 1]
} else {
    set minY 0
}
test text-14.19 {ConfigureText procedure} -setup {
    toplevel .top
    text .top.t -font {Courier -12} -borderwidth 2 -highlightthickness 2
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774

3775
3776
3777
3778
3779
3780
3781
12345
Line 4"
    .t tag add sel 1.0 end
    .t delete 4.0 end
    list [.t tag ranges sel] [.t get 1.0 end]
} -cleanup {
    destroy .t
} -result {{1.0 3.5} {Line 1
abcde
12345

}}
test text-19.9 {DeleteChars procedure} -body {
    text .t
    .t insert 1.0 "Line 1
abcde
12345
Line 4"







|


>







4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
12345
Line 4"
    .t tag add sel 1.0 end
    .t delete 4.0 end
    list [.t tag ranges sel] [.t get 1.0 end]
} -cleanup {
    destroy .t
} -result {{1.0 4.0} {Line 1
abcde
12345

}}
test text-19.9 {DeleteChars procedure} -body {
    text .t
    .t insert 1.0 "Line 1
abcde
12345
Line 4"
3874
3875
3876
3877
3878
3879
3880


3881
3882
3883
3884
3885
3886
3887
3888





3889
3890
3891
3892
3893
3894
3895
    toplevel .top
    text .top.t -width 6 -height 10 -wrap word
    frame .top.f -width 200 -height 20 -relief raised -bd 2
    pack .top.f .top.t -side left
    wm geometry .top +0+0
    update
} -body {


    .top.t insert end "abc def\n01 2a345 678 9101112\nLine 3\nLine 4\nLine 5\n6\n7\n8\n"
    .top.t yview 2.4
    .top.t delete 2.5
    set x [.top.t index @0,0]
    .top.t delete 2.5
    list $x [.top.t index @0,0]
} -cleanup {
    destroy .top





} -result {2.3 2.0}


test text-20.1 {TextFetchSelection procedure} -setup {
    text .t -width 20 -height 10
    pack .t -expand 1 -fill both
    update







>
>
|



|



>
>
>
>
>







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
    toplevel .top
    text .top.t -width 6 -height 10 -wrap word
    frame .top.f -width 200 -height 20 -relief raised -bd 2
    pack .top.f .top.t -side left
    wm geometry .top +0+0
    update
} -body {
    # The revised version has a fixed wrapping algorithm, so "xx" has been inserted
    # into the next string to get the same result as before.
    .top.t insert end "abc def\n01 2345xx 678 9101112\nLine 3\nLine 4\nLine 5\n6\n7\n8\n"
    .top.t yview 2.4
    .top.t delete 2.5
    set x [.top.t index @0,0]
    .top.t delete 2.5 2.8
    list $x [.top.t index @0,0]
} -cleanup {
    destroy .top
# TODO: A result like {2.3 2.3} would be preferrable.
# This means that this test case should delete 2.2, in this case
# we expect 2.0 as new top index.
# When deleting 2.5 we don't need a new top index, because the deletion
# will be done at or below top index.
} -result {2.3 2.0}


test text-20.1 {TextFetchSelection procedure} -setup {
    text .t -width 20 -height 10
    pack .t -expand 1 -fill both
    update
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
        append x "This is line $i, padded to just about 53 characters.\n"
    }
    .t insert end $x
    .t tag add sel 1.0 end
    expr {[selection get] eq "$x\n"}
} -cleanup {
    destroy .t
} -result 1


test text-21.1 {TkTextLostSelection procedure} -constraints {x11} -setup {
    text .t
    .t insert 1.0 "Line 1"
    entry .t.e
    .t.e insert end "abcdefg"







|







4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
        append x "This is line $i, padded to just about 53 characters.\n"
    }
    .t insert end $x
    .t tag add sel 1.0 end
    expr {[selection get] eq "$x\n"}
} -cleanup {
    destroy .t
} -result {1}


test text-21.1 {TkTextLostSelection procedure} -constraints {x11} -setup {
    text .t
    .t insert 1.0 "Line 1"
    entry .t.e
    .t.e insert end "abcdefg"
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044


test text-22.1 {TextSearchCmd procedure, argument parsing} -body {
    text .t
    .t search -
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous switch "-": must be --, -all, -backwards, -count, -elide, -exact, -forwards, -nocase, -nolinestop, -overlap, -regexp, or -strictlimits}
test text-22.2 {TextSearchCmd procedure, -backwards option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -backwards xyz 1.4
} -cleanup {
    destroy .t
} -result {1.1}







|







4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368


test text-22.1 {TextSearchCmd procedure, argument parsing} -body {
    text .t
    .t search -
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous switch "-": must be --, -all, -backwards, -count, -discardhyphens, -elide, -exact, -forwards, -nocase, -nolinestop, -overlap, -regexp, or -strictlimits}
test text-22.2 {TextSearchCmd procedure, -backwards option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -backwards xyz 1.4
} -cleanup {
    destroy .t
} -result {1.1}
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
} -result {2.13 2.23}
test text-22.10 {TextSearchCmd procedure, -n ambiguous option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -n BaR 1.1
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous switch "-n": must be --, -all, -backwards, -count, -elide, -exact, -forwards, -nocase, -nolinestop, -overlap, -regexp, or -strictlimits}
test text-22.11 {TextSearchCmd procedure, -nocase option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -noc BaR 1.1
} -cleanup {
    destroy .t
} -result {2.13}







|







4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
} -result {2.13 2.23}
test text-22.10 {TextSearchCmd procedure, -n ambiguous option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -n BaR 1.1
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous switch "-n": must be --, -all, -backwards, -count, -discardhyphens, -elide, -exact, -forwards, -nocase, -nolinestop, -overlap, -regexp, or -strictlimits}
test text-22.11 {TextSearchCmd procedure, -nocase option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -noc BaR 1.1
} -cleanup {
    destroy .t
} -result {2.13}
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
    lappend res [.t search -backwards a end]       ; # works
    lappend res [.t search -backwards -all a end]  ; # used to hang
} -cleanup {
    destroy .t
} -result {1.1 1.0 1.0}

test text-23.1 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs "\{{}"
} -cleanup {
    destroy .t
} -returnCodes {error} -result {unmatched open brace in list}
test text-23.2 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs xyz
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad screen distance "xyz"}
test text-23.3 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 200}
    update idletasks
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0]
} -cleanup {
    destroy .t
} -result {100 200}
test text-23.4 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 right 200 left 300 center 400 numeric}
    update idletasks
    list [expr {[lindex [.t bbox 1.2] 0] + [lindex [.t bbox 1.2] 2]}] \
	    [lindex [.t bbox 1.4] 0] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]/2}] \
	    [lindex [.t bbox 1.10] 0]
} -cleanup {
    destroy .t
} -result {100 200 300 400}
test text-23.5 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {105 r 205 l 305 c 405 n}
    update idletasks
    list [expr {[lindex [.t bbox 1.2] 0] + [lindex [.t bbox 1.2] 2]}] \
	    [lindex [.t bbox 1.4] 0] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]/2}] \
	    [lindex [.t bbox 1.10] 0]
} -cleanup {
    destroy .t
} -result {105 205 305 405}
test text-23.6 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 left 200 lork}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad tab alignment "lork": must be left, right, center, or numeric}
test text-23.7 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 !44 200 lork}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad screen distance "!44"}


test text-24.1 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
test text-24.2 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -all
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
test text-24.3 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -command
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
test text-24.4 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "-bogus": must be -all, -command, -image, -mark, -tag, -text, or -window}
test text-24.5 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump bogus
} -cleanup {
    destroy .t







|








|






|

|










|













|













|








|






|









|







|







|







|







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
    lappend res [.t search -backwards a end]       ; # works
    lappend res [.t search -backwards -all a end]  ; # used to hang
} -cleanup {
    destroy .t
} -result {1.1 1.0 1.0}

test text-23.1 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs "\{{}"
} -cleanup {
    destroy .t
} -returnCodes {error} -result {unmatched open brace in list}
test text-23.2 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs xyz
} -cleanup {
    destroy .t
} -returnCodes {error} -result {expected screen distance but got "xyz"}
test text-23.3 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 200}
    update idletasks
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0]
} -cleanup {
    destroy .t
} -result {100 200}
test text-23.4 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 right 200 left 300 center 400 numeric}
    update idletasks
    list [expr {[lindex [.t bbox 1.2] 0] + [lindex [.t bbox 1.2] 2]}] \
	    [lindex [.t bbox 1.4] 0] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]/2}] \
	    [lindex [.t bbox 1.10] 0]
} -cleanup {
    destroy .t
} -result {100 200 300 400}
test text-23.5 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {105 r 205 l 305 c 405 n}
    update idletasks
    list [expr {[lindex [.t bbox 1.2] 0] + [lindex [.t bbox 1.2] 2]}] \
	    [lindex [.t bbox 1.4] 0] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]/2}] \
	    [lindex [.t bbox 1.10] 0]
} -cleanup {
    destroy .t
} -result {105 205 305 405}
test text-23.6 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 left 200 lork}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad tab alignment "lork": must be left, right, center, or numeric}
test text-23.7 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 !44 200 lork}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {expected screen distance but got "!44"}


test text-24.1 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -chars -image -mark -node -tag -text -window? ?-command script? index ?index2?}
test text-24.2 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -all
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -chars -image -mark -node -tag -text -window? ?-command script? index ?index2?}
test text-24.3 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -command
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -chars -image -mark -node -tag -text -window? ?-command script? index ?index2?}
test text-24.4 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "-bogus": must be -all, -chars, -command, -image, -mark, -node, -tag, -text, or -window}
test text-24.5 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump bogus
} -cleanup {
    destroy .t
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
    .t dump -mark 1.0 end
} -cleanup {
    destroy .t
} -result {mark current 1.0 mark insert 1.0 mark m 2.4 mark n 4.0 mark END 5.0}
test text-24.21 {TextDumpCmd procedure, windows only} -setup {
    pack [text .t]
    .t insert end "Line One\nLine Two\nLine Three\nLine Four"
    for {set i 0} {$i < 100} {incr i} {.t insert end "-\n"}
    button .hello -text Hello
} -body {
    .t window create 3.end -window .hello
    .t window create 100.0 -create { }
    .t dump -window 1.0 5.0
} -cleanup {
    destroy .t
} -result {window .hello 3.10}
test text-24.22 {TextDumpCmd procedure, windows only} -setup {
    pack [text .t]
    .t insert end "Line One\nLine Two\nLine Three\nLine Four"
    for {set i 0} {$i < 100} {incr i} {.t insert end "-\n"}
    button .hello -text Hello
} -body {
    .t window create 3.end -window .hello
    .t window create 100.0 -create { }
    .t dump -window 5.0 end
} -cleanup {
    destroy .t







|











|







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
    .t dump -mark 1.0 end
} -cleanup {
    destroy .t
} -result {mark current 1.0 mark insert 1.0 mark m 2.4 mark n 4.0 mark END 5.0}
test text-24.21 {TextDumpCmd procedure, windows only} -setup {
    pack [text .t]
    .t insert end "Line One\nLine Two\nLine Three\nLine Four"
    .t insert end [string repeat "-\n" 100]
    button .hello -text Hello
} -body {
    .t window create 3.end -window .hello
    .t window create 100.0 -create { }
    .t dump -window 1.0 5.0
} -cleanup {
    destroy .t
} -result {window .hello 3.10}
test text-24.22 {TextDumpCmd procedure, windows only} -setup {
    pack [text .t]
    .t insert end "Line One\nLine Two\nLine Three\nLine Four"
    .t insert end [string repeat "-\n" 100]
    button .hello -text Hello
} -body {
    .t window create 3.end -window .hello
    .t window create 100.0 -create { }
    .t dump -window 5.0 end
} -cleanup {
    destroy .t
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
} -result {mark 1.0 current mark 1.0 insert mark 2.4 m}
test text-24.25 {TextDumpCmd procedure, unicode characters} -body {
    text .t
    .t insert 1.0 ±±±
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text ±±± 1.0 mark insert 1.3 mark current 1.3 text {\n} 1.3"
test text-24.26 {TextDumpCmd procedure, unicode characters} -body {
    text .t
    .t delete 1.0 end
    .t insert 1.0 abc±±±
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text abc±±± 1.0 mark insert 1.6 mark current 1.6 text {\n} 1.6"
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"

test text-25.1 {text widget vs hidden commands} -body {
    text .t
    set y [list {} [interp hidden]]
    interp hide {} .t
    destroy .t
    set x [list [winfo children .] [interp hidden]]
    expr {$x eq $y}
} -result 1


test text-26.1 {bug fix - 1642} -body {
    pack [text .t]
    .t insert end "line 1\n"
    .t insert end "line 2\n"
    .t insert end "line 3\n"







|







|






|








|







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
} -result {mark 1.0 current mark 1.0 insert mark 2.4 m}
test text-24.25 {TextDumpCmd procedure, unicode characters} -body {
    text .t
    .t insert 1.0 ±±±
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text ±±± 1.0 mark current 1.3 mark insert 1.3 text {\n} 1.3"
test text-24.26 {TextDumpCmd procedure, unicode characters} -body {
    text .t
    .t delete 1.0 end
    .t insert 1.0 abc±±±
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text abc±±± 1.0 mark current 1.6 mark insert 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 current 1.0 mark insert 1.0 text {\n} 1.0"

test text-25.1 {text widget vs hidden commands} -body {
    text .t
    set y [list {} [interp hidden]]
    interp hide {} .t
    destroy .t
    set x [list [winfo children .] [interp hidden]]
    expr {$x eq $y}
} -result {1}


test text-26.1 {bug fix - 1642} -body {
    pack [text .t]
    .t insert end "line 1\n"
    .t insert end "line 2\n"
    .t insert end "line 3\n"
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t edit option ?arg ...?"}
test text-27.2 {TextEditCmd procedure, argument parsing} -body {
    pack [text .t]
    .t edit gorp
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad edit option "gorp": must be canundo, canredo, modified, redo, reset, separator, or undo}
test text-27.3 {TextEditUndo procedure, undoing changes} -body {
    text .t -undo 1
    pack .t
    .t insert end "line 1\n"
    .t delete 1.4 1.6
    .t insert end "should be gone after undo\n"
    .t edit undo







|







6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t edit option ?arg ...?"}
test text-27.2 {TextEditCmd procedure, argument parsing} -body {
    pack [text .t]
    .t edit gorp
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad edit option "gorp": must be altered, canredo, canundo, info, inspect, irreversible, modified, recover, redo, reset, separator, or undo}
test text-27.3 {TextEditUndo procedure, undoing changes} -body {
    text .t -undo 1
    pack .t
    .t insert end "line 1\n"
    .t delete 1.4 1.6
    .t insert end "should be gone after undo\n"
    .t edit undo
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
test text-27.8 {TextEditCmd procedure, modified flag} -body {
    text .t
    pack .t
    .t insert end "line 1\n"
    .t edit modified
} -cleanup {
    destroy .t
} -result 1
test text-27.9 {TextEditCmd procedure, reset modified flag} -body {
    text .t
    pack .t
    .t insert end "line 1\n"
    .t edit modified 0
    .t edit modified
} -cleanup {
    destroy .t
} -result 0
test text-27.10 {TextEditCmd procedure, set modified flag} -body {
    text .t
    pack .t
    .t edit modified 1
    .t edit modified
} -cleanup {
    destroy .t
} -result 1
test text-27.11 {TextEditCmd procedure, set modified flag repeat} -setup {
    text .t
    pack .t
# Make sure the Text is mapped before we start
    update
    set ::retval {}
    update
} -body {
    bind .t <<Modified>> "lappend ::retval modified"
# Shouldn't require [update idle] to trigger event [Bug 1809538]
    lappend ::retval [.t edit modified]
    .t edit modified 1
    update
    lappend ::retval [.t edit modified]







|








|







|






<







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
test text-27.8 {TextEditCmd procedure, modified flag} -body {
    text .t
    pack .t
    .t insert end "line 1\n"
    .t edit modified
} -cleanup {
    destroy .t
} -result {1}
test text-27.9 {TextEditCmd procedure, reset modified flag} -body {
    text .t
    pack .t
    .t insert end "line 1\n"
    .t edit modified 0
    .t edit modified
} -cleanup {
    destroy .t
} -result {0}
test text-27.10 {TextEditCmd procedure, set modified flag} -body {
    text .t
    pack .t
    .t edit modified 1
    .t edit modified
} -cleanup {
    destroy .t
} -result {1}
test text-27.11 {TextEditCmd procedure, set modified flag repeat} -setup {
    text .t
    pack .t
# Make sure the Text is mapped before we start
    update
    set ::retval {}

} -body {
    bind .t <<Modified>> "lappend ::retval modified"
# Shouldn't require [update idle] to trigger event [Bug 1809538]
    lappend ::retval [.t edit modified]
    .t edit modified 1
    update
    lappend ::retval [.t edit modified]
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
    bind .tt <<Modified>> {incr ::retval}
    .t insert end "This increments ::retval once for each peer, i.e. twice."
    .t edit modified 0  ; # shall increment twice as well, not just once
    update
    set ::retval
} -cleanup {
    destroy .t .tt
} -result 4
test text-27.15 {<<Selection>> virtual event on sel tagging} -body {
    set ::retval no_selection
    pack [text .t]
    bind .t <<Selection>> "set ::retval selection_changed"
    update idletasks
    .t insert end "nothing special\n"
    .t tag add sel 1.0 1.1







|







6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
    bind .tt <<Modified>> {incr ::retval}
    .t insert end "This increments ::retval once for each peer, i.e. twice."
    .t edit modified 0  ; # shall increment twice as well, not just once
    update
    set ::retval
} -cleanup {
    destroy .t .tt
} -result {4}
test text-27.15 {<<Selection>> virtual event on sel tagging} -body {
    set ::retval no_selection
    pack [text .t]
    bind .t <<Selection>> "set ::retval selection_changed"
    update idletasks
    .t insert end "nothing special\n"
    .t tag add sel 1.0 1.1
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
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <<PasteSelection>> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y 3
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {<<Selection>>_fired}
test text-27.15c {No <<Selection>> virtual event on <<PasteSelection>> outside widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "but it will not be impacted by the <<PasteSelection>> event received."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y 80
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.15d {<<Selection>> virtual event on <Delete> with cursor inside selection} -body {
    pack [text .t]







|













|







6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <<PasteSelection>> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y [lindex [.t dlineinfo 1.0] 1]
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {<<Selection>>_fired}
test text-27.15c {No <<Selection>> virtual event on <<PasteSelection>> outside widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "but it will not be impacted by the <<PasteSelection>> event received."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y [lindex [.t dlineinfo 2.0] 1]
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.15d {<<Selection>> virtual event on <Delete> with cursor inside selection} -body {
    pack [text .t]
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
    catch {.t edit undo}
    catch {.t edit undo}
    .t get 1.0 end
} -cleanup {
    destroy .t
} -result "line 1\n\n"
test text-27.16a {undo configuration options with peers} -body {
    text .t -undo 1 -autoseparators 0 -maxundo 100
    .t peer create .tt
    set res     [.t  cget -undo]
    lappend res [.tt cget -undo]
    lappend res [.t  cget -autoseparators]
    lappend res [.tt cget -autoseparators]
    lappend res [.t  cget -maxundo]
    lappend res [.tt cget -maxundo]




    .t insert end "The undo stack is common between peers"
    lappend res [.t  edit canundo]
    lappend res [.tt edit canundo]
} -cleanup {
    destroy .t .tt
} -result {1 1 0 0 100 100 1 1}
test text-27.16b {undo configuration options with peers, defaults} -body {
    text .t
    .t peer create .tt
    set res     [.t  cget -undo]
    lappend res [.tt cget -undo]
    lappend res [.t  cget -autoseparators]
    lappend res [.tt cget -autoseparators]
    lappend res [.t  cget -maxundo]
    lappend res [.tt cget -maxundo]




    .t insert end "The undo stack is common between peers"
    lappend res [.t  edit canundo]
    lappend res [.tt edit canundo]
} -cleanup {
    destroy .t .tt
} -result {0 0 1 1 0 0 0 0}
test text-27.17 {bug fix 1536735 - undo with empty text} -body {
    text .t -undo 1
    set r [.t edit modified]
    .t delete 1.0
    lappend r [.t edit modified]
    lappend r [catch {.t edit undo}]
    lappend r [.t edit modified]







|







>
>
>
>

|
|


|









>
>
>
>

|
|


|







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
    catch {.t edit undo}
    catch {.t edit undo}
    .t get 1.0 end
} -cleanup {
    destroy .t
} -result "line 1\n\n"
test text-27.16a {undo configuration options with peers} -body {
    text .t -undo 1 -autoseparators 0 -maxundo 200 -maxredo 100 -maxundosize 1000
    .t peer create .tt
    set res     [.t  cget -undo]
    lappend res [.tt cget -undo]
    lappend res [.t  cget -autoseparators]
    lappend res [.tt cget -autoseparators]
    lappend res [.t  cget -maxundo]
    lappend res [.tt cget -maxundo]
    lappend res [.t  cget -maxredo]
    lappend res [.tt cget -maxredo]
    lappend res [.t  cget -maxundosize]
    lappend res [.tt cget -maxundosize]
    .t insert end "The undo stack is common between peers"
    lappend res [llength [.t  edit info -undocommands]]
    lappend res [llength [.tt edit info -undocommands]]
} -cleanup {
    destroy .t .tt
} -result {1 1 0 0 200 200 100 100 1000 1000 1 1}
test text-27.16b {undo configuration options with peers, defaults} -body {
    text .t
    .t peer create .tt
    set res     [.t  cget -undo]
    lappend res [.tt cget -undo]
    lappend res [.t  cget -autoseparators]
    lappend res [.tt cget -autoseparators]
    lappend res [.t  cget -maxundo]
    lappend res [.tt cget -maxundo]
    lappend res [.t  cget -maxredo]
    lappend res [.tt cget -maxredo]
    lappend res [.t  cget -maxundosize]
    lappend res [.tt cget -maxundosize]
    .t insert end "The undo stack is common between peers"
    lappend res [llength [.t  edit info -undocommands]]
    lappend res [llength [.tt edit info -undocommands]]
} -cleanup {
    destroy .t .tt
} -result {0 0 1 1 0 0 -1 -1 0 0 0 0}
test text-27.17 {bug fix 1536735 - undo with empty text} -body {
    text .t -undo 1
    set r [.t edit modified]
    .t delete 1.0
    lappend r [.t edit modified]
    lappend r [catch {.t edit undo}]
    lappend r [.t edit modified]
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
    event generate .top.t <<Cut>>
    event generate .top.t <Delete>
    event generate .top.t <<Undo>>
    .top.t get 1.0 "1.0 lineend"
} -cleanup {
    destroy .top.t .top
} -result "This A an example text"
test text-27.24 {TextEditCmd procedure, canundo and canredo} -setup {
    destroy .t
    set res {}
} -body {
    text .t -undo false -autoseparators false
    lappend res [.t edit canundo] [.t edit canredo]
    .t configure -undo true
    lappend res [.t edit canundo] [.t edit canredo]
    .t insert end "DO\n"
    .t edit separator
    .t insert end "IT\n"
    .t insert end "YOURSELF\n"
    .t edit separator
    lappend res [.t edit canundo] [.t edit canredo]
    .t edit undo

    lappend res [.t edit canundo] [.t edit canredo]

    .t configure -undo false
    lappend res [.t edit canundo] [.t edit canredo]
    .t configure -undo true
    lappend res [.t edit canundo] [.t edit canredo]
    .t edit redo
    lappend res [.t edit canundo] [.t edit canredo]
} -cleanup {
    destroy .t
} -result {0 0 0 0 1 0 1 1 0 0 1 1 1 0}
test text-27.25 {<<UndoStack>> virtual event} -setup {
    destroy .t
    set res {}
    set nbUS 0
} -body {
    text .t -undo false -autoseparators false
    bind .t <<UndoStack>> {incr nbUS}







|




|

|





|

>
|
>

|

<
|
<


|







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
    event generate .top.t <<Cut>>
    event generate .top.t <Delete>
    event generate .top.t <<Undo>>
    .top.t get 1.0 "1.0 lineend"
} -cleanup {
    destroy .top.t .top
} -result "This A an example text"
test text-27.24 {TextEditCmd procedure, undo and redo stack depths} -setup {
    destroy .t
    set res {}
} -body {
    text .t -undo false -autoseparators false
    .t edit info; lappend res $(undodepth) $(redodepth)
    .t configure -undo true
    .t edit info; lappend res $(undodepth) $(redodepth)
    .t insert end "DO\n"
    .t edit separator
    .t insert end "IT\n"
    .t insert end "YOURSELF\n"
    .t edit separator
    .t edit info; lappend res $(undodepth) $(redodepth)
    .t edit undo
    .t edit info; lappend res $(undodepth) $(redodepth)
    .t edit redo
    .t edit info; lappend res $(undodepth) $(redodepth)
    .t configure -undo false
    .t edit info; lappend res $(undodepth) $(redodepth)
    .t configure -undo true

    .t edit info; lappend res $(undodepth) $(redodepth)

} -cleanup {
    destroy .t
} -result {0 0 0 0 2 0 1 1 2 0 0 0 0 0}
test text-27.25 {<<UndoStack>> virtual event} -setup {
    destroy .t
    set res {}
    set nbUS 0
} -body {
    text .t -undo false -autoseparators false
    bind .t <<UndoStack>> {incr nbUS}
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
    update ; lappend res $nbUS
    .t edit undo
    update ; lappend res $nbUS
    .t edit reset
    update ; lappend res $nbUS
} -cleanup {
    destroy .t
} -result {0 0 1 2 3 4 4 5 6 6 7 8 8 9}
test text-27.26 {edit undo and edit redo return ranges} -setup {
    destroy .t
    set res {}


} -body {











    text .t -undo true -autoseparators false

    .t insert end "Hello "
    .t edit separator
    .t insert end "World!\n"
    .t insert 1.6 "GREAT "
    .t insert end "Another edit here!!"
    lappend res [.t edit undo]
    lappend res [.t edit redo]
    .t edit separator
    .t delete 1.6
    .t delete 1.9 1.10
    .t insert 1.9 L
    lappend res [.t edit undo]
    lappend res [.t edit redo]
    .t replace 1.6 1.10 Tcl/Tk
    .t replace 2.8 2.12 "one bites the dust"


    lappend res [.t edit undo]
    lappend res [.t edit redo]
} -cleanup {
    destroy .t

} -result [list {1.6 2.0}           \
                {1.6 2.19}          \
                {1.6 1.7 1.10 1.12} \
                {1.6 1.7 1.9 1.11}  \
                {1.6 1.16 2.8 2.19} \
                {1.6 1.16 2.8 2.30} ]
test text-27.27 {edit undo and edit redo return ranges} -setup {
    destroy .t
    set res {}
} -body {
    text .t -undo true -autoseparators false
    for {set i 3} {$i >= 1} {incr i -1} {
        .t insert 1.0 "Line $i\n"
    }
    lappend res [.t edit undo]
    lappend res [.t edit redo]
} -cleanup {
    destroy .t
} -result [list {1.0 2.0} \
                {1.0 4.0} ]
test text-27.28 {edit undo and edit redo do not leave \
                 spurious temporary marks behind them} -setup {
    destroy .t
    set res {}
} -body {




    pack [text .t -undo true -autoseparators false]
    .t insert end "Hello World.\n"
    .t edit separator
    .t insert end "Again hello.\n"
    .t edit undo

    lappend res [expr {[lsearch [.t mark names] tk::undoMark*]<0}]
    .t edit redo
    lappend res [expr {[lsearch [.t mark names] tk::undoMark*]<0}]


} -cleanup {
    destroy .t






} -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







|
|


>
>

>
>
>
>
>
>
>
>
>
>
>

>





|
|




|
|


>
>
|
|


>
|
|
<
<
<
<
|
|
|
<
|
<
|
<
|
|


|
<
|
|
|
<

>
>
>
>
|
|

<

>
|
|
|
>
>


>
>
>
>
>
>
|
>
>
>
>
>







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
    update ; lappend res $nbUS
    .t edit undo
    update ; lappend res $nbUS
    .t edit reset
    update ; lappend res $nbUS
} -cleanup {
    destroy .t
} -result {0 0 4 5 6 7 8 9 10 11 12 13 14 15}
test text-27.26 {edit undo and edit redo provides ranges} -setup {
    destroy .t
    set res {}
    set undo {}
    set redo {}
} -body {
    proc watch {w op idx1 idx2 info userFlag} {
	switch $op {
	    undo - redo {
		::tk_mergeRange ::${op}_ [list $idx1 $idx2]
		if {[lindex $info 1]} { ;# last undo/redo action?
		    lappend ::${op} [set ::${op}_]
		    unset ::${op}_
		}
	    }
	}
    }
    text .t -undo true -autoseparators false
    .t watch watch
    .t insert end "Hello "
    .t edit separator
    .t insert end "World!\n"
    .t insert 1.6 "GREAT "
    .t insert end "Another edit here!!"
    .t edit undo
    .t edit redo
    .t edit separator
    .t delete 1.6
    .t delete 1.9 1.10
    .t insert 1.9 L
    .t edit undo
    .t edit redo
    .t replace 1.6 1.10 Tcl/Tk
    .t replace 2.8 2.12 "one bites the dust"
    .t edit undo
    .t edit redo
    lappend res $undo
    lappend res $redo
} -cleanup {
    destroy .t
    unset undo redo res
} -result {{{{1.6 2.19}} {{1.6 1.7} {1.9 1.10}} {{1.6 1.12} {2.8 2.26}}}\
           {{{1.6 2.19}} {{1.6 1.7} {1.9 1.10}} {{1.6 1.12} {2.8 2.26}}}}




test text-27.27 {undo with empty text, and tagged newline} -body {
    text .t
    .t tag add tag1 1.0

    .t configure -undo on

    .t delete 1.0

    .t edit undo
    .t tag ranges tag1
} -cleanup {
    destroy .t
} -result {1.0 2.0}

test text-27.28 {Bug e32292c454704f7defd1cb335b5663f9c4f245d4 \
                 undo is undoing too much} -setup {
    pack [text .t -undo 1]

} -body {
    .t insert end "Line 1\nLine 2\n"
    .t tag configure number -foreground red
    .t tag add number 1.5
    .t tag add number 2.5
    .t edit separator
    .t insert 1.0 "    "
    .t edit separator

    .t edit undo
    .t tag getrange number 2.5    ; # shall not be {}
} -cleanup {
    destroy .t
} -result {2.5 2.6}
test text-27.29 {"edit info" gives error when array name is starting with a minus sign} -body {
    [text .t] edit info -array
} -cleanup {
    destroy .t
} -returnCodes error -result {bad option "-array": must be -bytesize, -generatedmarks, -images, -lines, -linespernode, -marks, -redobytesize, -redocommands, -redodepth, -redostacksize, -tags, -totalbytesize, -totallines, -undobytesize, -undocommands, -undodepth, -undostacksize, -usedtags, -visibleimages, -visiblewindows, or -windows}
test text-27.30 {"edit info" works when array name is preceded by "--"} -body {
    [text .t] edit info -- -array
    set -array(generatedmarks)
} -cleanup {
    destroy .t
} -result {0}
test text-27.31 {"edit info" works w/o arguments} -body {
    set [[text .t] edit info](generatedmarks)
} -cleanup {
    destroy .t
} -result {0}


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
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
    .t insert end "a\tb\tc\td\te"
    catch {.t configure -tabs {10c 5c}}
    update ; update ; update
# This test must simply not go into an infinite loop to succeed
    set result 1
} -cleanup {
    destroy .t
} -result 1


test text-30.1 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview moveto 1
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result 1
test text-30.2 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview scroll 1 pages
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result 1
test text-30.3 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview scroll 100 pixels
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result 1
test text-30.4 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview scroll 10 units
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result 1


test text-31.1 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    pack [.t peer create .top.t]
    destroy .t .top







|












|










|










|










|







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
    .t insert end "a\tb\tc\td\te"
    catch {.t configure -tabs {10c 5c}}
    update ; update ; update
# This test must simply not go into an infinite loop to succeed
    set result 1
} -cleanup {
    destroy .t
} -result {1}


test text-30.1 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview moveto 1
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result {1}
test text-30.2 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview scroll 1 pages
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result {1}
test text-30.3 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview scroll 100 pixels
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result {1}
test text-30.4 {repeated insert and scroll} -body {
    pack [text .t]
    for {set i 0} {$i < 30} {incr i} {
        .t insert end "blabla\n"
        eval .t yview scroll 10 units
    }
# This test must simply not crash to succeed
    set result 1
} -cleanup {
    destroy .t
} -result {1}


test text-31.1 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    pack [.t peer create .top.t]
    destroy .t .top
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
    update
    destroy .t .top2
    update
} -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -startline 15 -endline 10}]
    lappend res [.t tag ranges sel]
    .t configure -startline 6 -endline 12
    lappend res [.t tag ranges sel]
    .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]
    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 index sel.first]
    lappend res [.t index sel.last]
    return $res
} -cleanup {
    destroy .t
} -result {1.0 11.0}
test text-31.19 {peer widgets} -body {
    pack [text .t]

    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }

    .t tag delete sel
    .t index sel.first
} -cleanup {
    destroy .t
} -returnCodes {error} -result {text doesn't contain any characters tagged with "sel"}









>

|

>
|






>

|

>
|










>

|

>
|
|









>

|

>
|






|



>

|

>
|









>

|

>
|









>
|
|

>
|





>
>
|




>

|

>


|









>

|

>


|









>

|

>


|










>

|

>


|















>

|

>

|















>

|

>

|















>

|

>


|

|

|









>

|

>









>

|

>







7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
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
    update
    destroy .t .top2
    update
} -result {}
test text-31.4 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
       append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 11]
    update
    destroy .t .top
} -result {}
test text-31.5 {peer widgets} -body {
    toplevel .top
    pack [text .t]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
       append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 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]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
       append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 11]
    pack [.top.t peer create .top.t2 -start {} -end {}]
    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]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
       append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 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]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 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]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 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]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    pack [.t peer create .top.t -start 5 -end 11]
    update ; update
    .t delete 3.0 13.0
    .top.t index end
} -cleanup {
    destroy .t .top
# NOTE: in revised implementation this peer cannot be empty,
# so the old result "1.0" has been changed to "2.0".
} -result {2.0}
test text-31.11 {peer widgets} -setup {
    pack [text .t]
    set res {}
} -body {
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag add sel 1.0 end-1c
    lappend res [.t tag ranges sel]
    .t configure -start 10 -end 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 {
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag add sel 1.0 end-1c
    lappend res [.t tag ranges sel]
    .t configure -start 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 {
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag add sel 1.0 end-1c
    lappend res [.t tag ranges sel]
    .t configure -end 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 {
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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
    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 {
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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
    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 {
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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
    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 {
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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 [.t tag ranges sel]
    .t configure -start 6 -end 12
    lappend res [.t tag ranges sel]
    .t configure -start {} -end {}
    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]
    set res {}
} -body {
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag add sel 1.0 11.0
    lappend res [.t index sel.first]
    lappend res [.t index sel.last]
    return $res
} -cleanup {
    destroy .t
} -result {1.0 11.0}
test text-31.19 {peer widgets} -body {
    pack [text .t]
    set str ""
    for {set i 1} {$i < 20} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag delete sel
    .t index sel.first
} -cleanup {
    destroy .t
} -returnCodes {error} -result {text doesn't contain any characters tagged with "sel"}


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
        pack $t -expand  yes -fill both
        scrollbar $w.scroll -command "$t yview"
        pack $w.scroll -side right -fill y
        pack $w.f -expand yes -fill both
        $t tag configure center -justify center -spacing1 5m -spacing3 5m
        $t tag configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c \
            -spacing1 3m -spacing2 0 -spacing3 0

        for {set i 0} {$i < 40} {incr i} {
            $t insert end "${i}word "
        }

        return $t
    }
} -body {
    set w [makeText]
    update ; after 1000 ; update
    set before [$w count -ypixels 1.0 2.0]
    $w insert 1.0 "a"
    update
    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, -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
    # 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, -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, -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







>

|

>













|
<
|





>

|

>



















|
<
|





>

|

>







|


|
<
|





>

|

>







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
        pack $t -expand  yes -fill both
        scrollbar $w.scroll -command "$t yview"
        pack $w.scroll -side right -fill y
        pack $w.f -expand yes -fill both
        $t tag configure center -justify center -spacing1 5m -spacing3 5m
        $t tag configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c \
            -spacing1 3m -spacing2 0 -spacing3 0
	set str ""
        for {set i 0} {$i < 40} {incr i} {
            append str "${i}word "
        }
	$t insert end $str
        return $t
    }
} -body {
    set w [makeText]
    update ; after 1000 ; update
    set before [$w count -ypixels 1.0 2.0]
    $w insert 1.0 "a"
    update
    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 {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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] [.t get @0,0 "@0,0 lineend"]
} -cleanup {
    destroy .pt
} -result {4 3 {Line 5}}

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
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .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
7534
7535
7536
7537
7538
7539
7540


7541
7542
7543
7544
7545
7546
7547
7548
7549
    .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-33.1 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer foo 1
} -cleanup {
    destroy .t







>
>
|
<







7929
7930
7931
7932
7933
7934
7935
7936
7937
7938

7939
7940
7941
7942
7943
7944
7945
    .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
# NOTE: The peer widget is empty, and in revised version always a last newline
# exists, so the last line index has been increased by 1 (57 -> 58).
} -result {5 11 8 10 5 8 6 8 22 27 38 44 55 60 57 58}


test text-33.1 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer foo 1
} -cleanup {
    destroy .t
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
    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 -startline 10 -endline 5]
    return $res
} -cleanup {
    destroy .t
} -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 -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 -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 -startline 5 -endline 10 -tab foo}]
    lappend res [.t index end]
    lappend res [catch {.t configure -tab foo -startline 15 -endline 20}]
    lappend res [.t index 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 -startline 5 -endline 15}]
    lappend res [.t index end]
    lappend res [catch {.t configure -startline 10 -endline 40}]
    lappend res [.t index 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, -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 -startline 5 -endline 30
    lappend res [.t tag ranges sel]
    .t configure -startline 5 -endline 15
    lappend res [.t tag ranges sel]
    .t configure -startline 15 -endline 30
    lappend res [.t tag ranges sel]
    .t configure -startline 15 -endline 16
    lappend res [.t tag ranges sel]
    .t configure -startline 25 -endline 30
    lappend res [.t tag ranges sel]
    .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 {







|






>

|

>
|





>

|

>
|





>

|

>

|

|

|







>

|

>

|

|

|






|



>

|

>


|

|

|

|

|

|







7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
    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]
    return $res
} -cleanup {
    destroy .t
} -returnCodes 2 -result {}
test text-33.8 {peer widget -start, -end} -body {
    text .t
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t configure -start 10 -end 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
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t configure -start 5 -end 10
} -cleanup {
    destroy .t
} -returnCodes {ok} -result {}
test text-33.10 {peer widget -start, -end} -body {
    text .t
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    set res [.t index end]
    lappend res [catch {.t configure -start 5 -end 10 -tab foo}]
    lappend res [.t index end]
    lappend res [catch {.t configure -tab foo -start 15 -end 20}]
    lappend res [.t index end]
    .t configure -start {} -end {}
    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
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    set res [.t index end]
    lappend res [catch {.t configure -start 5 -end 15}]
    lappend res [.t index end]
    lappend res [catch {.t configure -start 10 -end 40}]
    lappend res [.t index end]
    .t configure -start {} -end {}
    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 {
    text .t
    set res {}
} -body {
    set str ""
    for {set i 1} {$i < 100} {incr i} {
	append str "Line $i\n"
    }
    .t insert end $str
    .t tag add sel 10.0 20.0
    lappend res [.t tag ranges sel]
    .t configure -start 5 -end 30
    lappend res [.t tag ranges sel]
    .t configure -start 5 -end 15
    lappend res [.t tag ranges sel]
    .t configure -start 15 -end 30
    lappend res [.t tag ranges sel]
    .t configure -start 15 -end 16
    lappend res [.t tag ranges sel]
    .t configure -start 25 -end 30
    lappend res [.t tag ranges sel]
    .t configure -start {} -end {}
    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 {
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

    destroy $w
    rename returnerror-36.3 ""
    interp bgerror {} $save
    unset -nocomplain save ::my_error w
} -result {}



test text-37.1 "bug #dd9667635d: text anchor not set" -setup {
    set save [interp bgerror {}]
    interp bgerror {} returnerror-37.1
    proc returnerror-37.1 {m opts} {set ::my_error $m}
    destroy .t
    set ::my_error {}
    pack [text .t]
} -body {
    .t insert end "Hello world!"
    .t tag add sel 1.0 end
    # this line shall not trigger error:
    #     bad text index "tk::anchorN"
    event generate .t <<SelectPrevLine>>
    update
    set ::my_error
} -cleanup {
    destroy .t
    rename returnerror-37.1 ""
    interp bgerror {} $save
    unset -nocomplain save ::my_error
} -result {}









































































































































































































































































































































































































































































































# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:








>
|




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
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
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
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
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
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
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
    destroy $w
    rename returnerror-36.3 ""
    interp bgerror {} $save
    unset -nocomplain save ::my_error w
} -result {}


test text-37.1 "Bug dd9667635d4d286858b1237835502a1d8bd07a82 \
                text anchor not set" -setup {
    set save [interp bgerror {}]
    interp bgerror {} returnerror-37.1
    proc returnerror-37.1 {m opts} {set ::my_error $m}
    destroy .t
    set ::my_error {}
    pack [text .t]
} -body {
    .t insert end "Hello world!"
    .t tag add sel 1.0 end
    # this line shall not trigger error:
    #     bad text index "tk::anchorN"
    event generate .t <<SelectPrevLine>>
    update
    set ::my_error
} -cleanup {
    destroy .t
    rename returnerror-37.1 ""
    interp bgerror {} $save
    unset -nocomplain save ::my_error
} -result {}


test text-38.1 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{break {}}}}
test text-38.2 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
    set res {}
} -body {
    .t delete 2.0 end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {break {}}}}
test text-38.3 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
    set res {}
} -body {
    .t delete 1.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{text 1 {}} {break {}}}}
test text-38.4 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
    set res {}
} -body {
    .t delete 2.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}}
test text-38.5 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{break {}}}}
test text-38.6 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
    set res {}
} -body {
    .t delete 2.0 end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{text 1 {}} {break {n1}} {break {}}}}
test text-38.7 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
    set res {}
} -body {
    .t delete 1.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{text 1 {}} {break {}}}}
test text-38.8 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
    set res {}
} -body {
    .t delete 2.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}}
test text-38.9 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately
    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{break {n}}}\
    {{break {}}}}
test text-38.10 {deletion - clean widget} -setup {
    text .t -undo on
    set res {}
} -body {
    lappend res [.t inspect -chars -tag]
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    catch {
	.t edit undo
	lappend res [.t inspect -chars -tag]
    }
    set res
} -cleanup {
   destroy .t
   unset res
} -result {{{break {}}}\
    {{break {}}}}
test text-38.11 {deletion - test optimization} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately
} -body {
    .t delete begin end
    .t edit inspect
} -cleanup {
    destroy .t
} -result {{{{tag clear {n 0 1}}} {{tag add n}}} {}}
test text-38.12 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1"
    .t tag add n begin end
    .t edit separator -immediately
    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{text 1 {n}} {break {n}}}\
    {{break {}}}}
test text-38.13 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately
    .t insert end "1"
    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{text 1 {}} {break {n}}}\
    {{break {}}}}

# non-regression regarding miscellaneous bugs, especially crashes and failed assertions

test text-39.1 "Bug 83632316b9cc27a2bfc743e049f078419480871e \
                Crash with -showinsertforeground and -blockcursor" -setup {
} -body {
    set w [text .t \
        -showinsertforeground yes \
        -blockcursor on ]
    focus $w
    grid $w
    $w insert end "Bug"
    update                ; # this used to crash
} -cleanup {
    destroy $w
} -result {}
test text-39.2 "Bug 5cfd9dfe0d60f6a78fbdb07e1a0d385216160bd6 \
                -startindex and -endindex defaults cannot be re-eaten by the text widget" -setup {
    text .t
} -body {
    .t configure -startindex [.t cget -startindex]    ; # used to error:  bad text index ""
    .t configure -endindex [.t cget -endindex]        ; # used to error:  bad text index ""
} -cleanup {
    destroy .t
} -result {}
test text-39.3 "Bug ef14e354f51328157e9c553a731af5199cba2bee \
                Segfaults in revised_text - Case 1 (early measurements)" -setup {
    set message {    When wish is built with "--enable-symbols", this demo
                     causes wish to fail an assertion, and to segfault, at startup.

      The code tries to measure the text widget before it has been drawn.
      This may be unwise, but <Configure> bindings often use measurement code
      like this, and it is better if the widget returns default results than
      if it fails: then the first <Configure> event after Tk draws the window
      will do the calculation correctly.  The "traditional" text widget appears
      to work this way.
    }
    # This procedure measures things that may not be defined before
    # the widget is drawn.
    # Arguments:
    # textWidget -   text widget to be examined
    # index -        index in the logical line to be examined
    proc HowMuchIndent {textWidget index} {
        set newWrapRegexp   {[^[:space:]]}
        set lineStart [$textWidget index "$index linestart"]
        set secondDispLineStart [$textWidget index "$lineStart + 1 display line"]
        set indentTo  [$textWidget search -regexp -count matchLen -- \
        $newWrapRegexp $lineStart $secondDispLineStart]
        if {$indentTo eq {}} {
            set pix 0
        } else {
            set indentTo [$textWidget index "$indentTo + $matchLen chars - 1 char"]
            set pix [$textWidget count -xpixels $lineStart $indentTo]
        }
        return $pix
    }
    pack [text .t] -padx 2
} -body {
    .t configure -wrap word -undo 1
    .t configure -width 42 -height 26 -font {{Courier} -15} -bg white
    .t insert end $message
    # Either one of the following commands is OK. Both together used to cause a failed
    # assertion and a segfault.
    HowMuchIndent .t 1.0
    HowMuchIndent .t 2.0
} -cleanup {
    destroy .t
    unset message
} -result {0}
test text-39.4 "Bug ef14e354f51328157e9c553a731af5199cba2bee \
                Segfaults in revised_text - Case 2 (undo after tag lower)" -setup {
    pack [text .t] -padx 2
} -body {
    .t configure -wrap word -undo 1
    .t insert end "Line 1\nLine2"
    .t edit separator
    # Now add a tag, after the edit separator
    .t tag configure foo -undo 1
    .t tag add foo 1.0 2.0
    .t tag lower foo
    # The undo operation should remove the tag "foo" from the first line,
    # but instead the application used to segfault
    .t edit undo
} -cleanup {
    destroy .t
} -result {}
test text-39.5 "Bug 0d630132f2fb8043fc68e18cbb981a10ab27154c \
                Assertion failed in tkTextIndex.c" -setup {
    pack [text .t]
} -body {
    .t insert end "a\nb\n\n"
    .t mark set insert 1.0
    update
    for {set i 1} {$i <= 2} {incr i} {
        .t insert insert "\n"
        set winfoheight [winfo height .t]
        set curheight 1
        while {$curheight <= $winfoheight} {
            set pos [.t index "@0,$curheight linestart"]
            incr curheight 11
        }
    }
} -cleanup {
    destroy .t
} -result {}
test text-39.6 "Bug 3f1d48e263ee057743e98b7279bdbe0940515546 \
                Assertion failed in tkTextIndex.c" -setup {
    pack [text .t]
} -body {
    .t insert end "re"
    .t mark set inset 1.1
    update
    .t mark set p1 {insert linestart}  ; # assertion used to fail
} -cleanup {
    destroy .t
} -result {}
test text-39.7 "Bug c3e31d8f981a95a0d7c4d936134e27a9ae5160ed \
                Assertion failed in tkTextMark.c" -setup {
    pack [text .t -undo 1]
} -body {
    .t insert end "a\nb\nc\nd\ne\nf\ng\n"
    .t mark set unsavedmodifiedline1 5.0
    .t mark set unsavedmodifiedline2 6.0
    .t edit undo
    foreach amark [.t mark names] {
      if {[string match *savedmodifiedline* $amark]} {
        .t mark unset $amark
      }
    }
} -cleanup {
    destroy .t
} -result {}
test text-39.8 "Bug 73175271f22560fda74194bb5ca73daacb139c85 \
                Assertion failed in tkTextTagSetPriv.h" -setup {
    text .t
} -body {
    .t load {{text 0 {number}}}
} -cleanup {
    destroy .t
} -result {}
test text-39.9 "Bug 283d52f41f455ac383a95ba688a7e217e9b8755d \
                Assertion failed in tkTextMark.c" -setup {
    pack [text .t -undo 1]
} -body {
    .t insert end "a\nb\nc\nd\ne\nf\ng\n"
    .t mark set unsavedmodifiedline1 5.0
    .t mark set unsavedmodifiedline2 6.0
    .t edit undo
    foreach amark [.t mark names] {
      if {[string match *savedmodifiedline* $amark]} {
        .t mark unset $amark
      }
    }
    .t index unsavedmodifiedline2    ; # assertion used to fail
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "unsavedmodifiedline2"}
test text-39.10 "Bug 3cd0454c1d3b205157b5fa6bf226d3ad4c4bb8d2 \
                 Assertion failed in tkTextBTree.c" -setup {
    pack [text .t -undo 1]
} -body {
    .t tag configure t -foreground darkred
    for {set i 0} {$i < 2000} {incr i} {
        set c [expr {2*$i}]
        lappend ranges 1.$c
        lappend ranges 1.[incr c]
    }
    .t insert end [string repeat "a" 4000]
    .t tag add t {*}$ranges
    .t tag remove t begin end    ; # used to crash
} -cleanup {
    destroy .t
} -result {}
test text-39.11 "Bug 0bc9df5fe388558fa4f666799c631b9bfd4fc053 \
                 Assertion failed in tkTextMark.c" -setup {
    text .t -undo 1
} -body {
    .t load [list   {right stop} \
                    {break {}} \
                    {break {}} ]
    update
    .t delete 1.0 end
    .t edit reset
    .t mark next 1.0    ; # used to crash
 } -cleanup {
    destroy .t
} -result {stop}
test text-39.12 "Bug 2563b9689e415e496bcb86314cdb13387e919d92 \
                 inspect subcommand, option -complete" -setup {
    text .t
} -body {
    .t inspect -complete    ; # used to panic
} -cleanup {
    destroy .t
} -match glob -result {*}
test text-39.13 "Bug fc24165111709d5add5fb7532e30bb18233c0404 \
                 bbox does not return {} for off-screen characters" -setup {
    pack [text .t -width 10 -height 10 -wrap char]
} -body {
    .t insert 1.0 "abcd\nefg hijkl mnop qrstuv wxyz"
    .t tag configure y -wrap none
    update
    .t tag add y 1.end 2.2
    .t bbox 2.20
} -cleanup {
    destroy .t
} -result {}
test text-39.14 "Bug 9ffb79059bacafe3796bc3ab3ae701f402f4c813 \
                 Assertion failed in tkTextIndex.c" -setup {
    pack [text .t -undo 1]
} -body {
    .t insert end "Line 1\nLine 2\n"
    .t edit separator
    .t tag configure number -foreground red
    .t tag add number 1.5
    .t tag add number 2.5
    .t edit separator

    .t tag add sel 1.0 2.0
    .t mark set leftbound 1.0
    .t mark gravity leftbound left
    .t delete 1.0 1.6
    .t mark unset leftbound 1.6
    .t edit undo    ; # used to crash
} -cleanup {
    destroy .t
} -result {}
test text-39.15 "Bug 84b066a8ffd626f514348e598707ef126693423b \
                 crash with text tags operation and -undo 1" -setup {
    pack [text .t -undo 1]
    update
} -body {
    .t insert end "'Line1'"
    .t tag add operator 1.0 1.1
    .t tag add operator 1.3 1.4
    .t tag add operator 1.6 1.7
    .t tag remove operator 1.0 1.4    ; # used to crash
} -cleanup {
    destroy .t
} -result {}


test text-40.1 {Extending selection with mouse going outside the widget - Bug a9cf210a42} -setup {
    pack [text .t -width 40 -height 10]
    for {set n 1} {$n <= 5} {incr n} {
        .t insert end "This is line $i of text\n"
    }
    update
} -body {
    event generate .t <Button-1> -x 50 -y 50
    event generate .t <B1-Motion> -x 50 -y -50
    .t index sel.first
} -cleanup {
    destroy .t
} -result {1.0}


# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:
# vi:set ts=8 sw=4:

Changes to tests/textBTree.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# This file is a Tcl script to test out the B-tree facilities of
# Tk's text widget (the contents of the file "tkTextBTree.c".  There are
# several file with additional tests for other features of text widgets.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

proc setup {} {
    .t delete 1.0 100000.0
    .t tag delete x y
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1
    .t tag add x 1.5 1.13
    .t tag add x 2.2 2.6
    .t tag add y 1.5
}

# setup procedure for tests 10.*, 11.*, 12.*
proc msetup {} {
    .t delete 1.0 100000.0
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t mark set m1 1.2
    .t mark set l1 1.2
    .t mark gravity l1 left
    .t mark set next 1.6
    .t mark set x 1.6
    .t mark set m2 2.0







|








|










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# This file is a Tcl script to test out the B-tree facilities of
# Tk's text widget (the contents of the file "tkTextBTree.c".  There are
# several file with additional tests for other features of text widgets.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

proc setup {} {
    .t delete 1.0 end
    .t tag delete x y
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 1.1
    .t tag add x 1.5 1.13
    .t tag add x 2.2 2.6
    .t tag add y 1.5
}

# setup procedure for tests 10.*, 11.*, 12.*
proc msetup {} {
    .t delete 1.0 end
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t mark set m1 1.2
    .t mark set l1 1.2
    .t mark gravity l1 left
    .t mark set next 1.6
    .t mark set x 1.6
    .t mark set m2 2.0
253
254
255
256
257
258
259






























































260
261
262
263
264
265
266
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.21 {deleting with negative range} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.2
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
































































test btree-3.1 {inserting with tags} -body {
    setup
    .t insert 1.0 XXX
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.4 1.5 1.8 1.16 2.2 2.6} {1.8 1.9}}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.21 {deleting with negative range} -body {
    .t delete 1.0 100000.0
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    .t delete 3.2 3.2
    .t get 1.0 1000000.0
} -result "Line 1\nLine 2\nLine 3\n"
test btree-2.22 {deleting into beginning of elided range} -setup {
    .t delete 1.0 end
} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 end
    .t delete 5.0 "5.0 + 8 chars" ; # was deleting branch - see [a6a5985713]
    .t get 4.0 7.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 4\nine 6\nLine 7\n"
test btree-2.23 {deleting from within elided range} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 8.0
    .t delete 7.0 9.0 ; # was deleting link - see [a6a5985713]
    .t get 6.0 8.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 6\nLine 9\n"
test btree-2.24 {deleting whole elided range} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 8.0
    .t delete 5.0 9.0
    .t get 4.0 6.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 4\nLine 9\n"
test btree-2.25 {deleting several elided ranges} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 6.2 6.4 6.5 7.2 7.6
    .t delete 5.0 9.0
    .t get 4.0 7.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 4\nLine 9\nLine 10\n"
test btree-2.26 {deleting first char of elided range} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 end
    .t delete 6.0 6.1
    .t get 5.0 7.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 5\nine 6\n"


test btree-3.1 {inserting with tags} -body {
    setup
    .t insert 1.0 XXX
    list [.t tag ranges x] [.t tag ranges y]
} -result {{1.4 1.5 1.8 1.16 2.2 2.6} {1.8 1.9}}
780
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
} -result {1.2 1.11 1.5 1.5 1.9 1.9}


test btree-13.1 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag next x 2.2 2.1
} -result {}
test btree-13.2 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag next x 2.2 2.3
} -result {2.2 2.4}
test btree-13.3 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag next x 2.3 2.6
} -result {}
test btree-13.4 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.6
} -result {2.5 2.8}
test btree-13.5 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.5
} -result {}
test btree-13.6 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.1 2.4
    .t tag next x 2.5 2.8
} -result {}
test btree-13.7 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag next x 2.1 2.4
} -result {}
test btree-13.8 {tag searching} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    .t tag add x 190.3 191.2
    .t tag next x 3.5
} -result {190.3 191.2}
destroy .t


test btree-14.1 {check tag presence} -setup {
    destroy .t
    text .t







|






|






|






|






|






|






|










|







842
843
844
845
846
847
848
849
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
} -result {1.2 1.11 1.5 1.5 1.9 1.9}


test btree-13.1 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag nextrange x 2.2 2.1
} -result {}
test btree-13.2 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag nextrange x 2.2 2.3
} -result {2.2 2.4}
test btree-13.3 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.2 2.4
    .t tag nextrange x 2.3 2.6
} -result {}
test btree-13.4 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag nextrange x 2.1 2.6
} -result {2.5 2.8}
test btree-13.5 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag nextrange x 2.1 2.5
} -result {}
test btree-13.6 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.1 2.4
    .t tag nextrange x 2.5 2.8
} -result {}
test btree-13.7 {tag searching} -setup {
    .t delete 1.0 100000.0
} -body {
    .t insert 1.0 "Text for first line\nSecond line\n\nLast line of info"
    .t tag add x 2.5 2.8
    .t tag nextrange x 2.1 2.4
} -result {}
test btree-13.8 {tag searching} -setup {
    set bigText2 {}
    for {set i 0} {$i < 200} {incr i} {
        append bigText2 "Line $i\n"
    }
} -body {
    setup
    .t insert 1.2 $bigText2
    .t tag add x 190.3 191.2
    .t tag nextrange x 3.5
} -result {190.3 191.2}
destroy .t


test btree-14.1 {check tag presence} -setup {
    destroy .t
    text .t
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
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.3 1.4
    .t tag prevr x 2.0 1.4
} -cleanup {
    destroy .t
} -result {}
test btree-16.12 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.3 1.4
    .t tag prevr x 2.0 1.3
} -cleanup {
    destroy .t
} -result {1.3 1.4}
test btree-16.13 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.0 1.4
    .t tag prevr x 1.3
} -cleanup {
    destroy .t
} -result {1.0 1.4}


test btree-17.1 {remove tag does not push root down} -setup {
    destroy .t







|











|











|







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
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.3 1.4
    .t tag prevrange x 2.0 1.4
} -cleanup {
    destroy .t
} -result {}
test btree-16.12 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.3 1.4
    .t tag prevrange x 2.0 1.3
} -cleanup {
    destroy .t
} -result {1.3 1.4}
test btree-16.13 {StartSearchBack boundary case} -setup {
    destroy .t
    text .t
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i\n"
    }
} -body {
    .t tag add x 1.0 1.4
    .t tag prevrange x 1.3
} -cleanup {
    destroy .t
} -result {1.0 1.4}


test btree-17.1 {remove tag does not push root down} -setup {
    destroy .t
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







test btree-18.1 {tag search back, no tag} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag prev x 1.1 1.1
} -cleanup {
    destroy .t
} -result {}
test btree-18.2 {tag search back, start at existing range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.1
} -cleanup {
    destroy .t
} -result {}
test btree-18.3 {tag search back, end at existing range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.3 1.1
} -cleanup {
    destroy .t
} -result {1.1 1.4}
test btree-18.4 {tag search back, start within range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 1.10 1.0
} -cleanup {
    destroy .t
} -result {1.8 1.11}
test btree-18.5 {tag search back, start at end of range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    list [.t tag prev x 1.4 1.0] [.t tag prev x 1.11 1.0]
} -cleanup {
    destroy .t
} -result {{1.1 1.4} {1.8 1.11}}
test btree-18.6 {tag search back, start beyond range, same level 0 node} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prev x 3.0
} -cleanup {
    destroy .t
} -result {1.16 1.17}
test btree-18.7 {tag search back, outside any range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.16
    .t tag prev x 1.8 1.5
} -cleanup {
    destroy .t
} -result {}
test btree-18.8 {tag search back, start at start of node boundary} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 2.5 2.8
    .t tag prev x 19.0
} -cleanup {
    destroy .t
} -result {2.5 2.8}
test btree-18.9 {tag search back, large complex btree spans} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.3 1.end
    .t tag add x 200.0 220.0
    .t tag add x 500.0 520.0
    list [.t tag prev x end] [.t tag prev x 433.0]
} -cleanup {
    destroy .t
} -result {{500.0 520.0} {200.0 220.0}}





































































































































# cleanup
cleanupTests
return












|











|











|











|











|











|










|









|











|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
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


test btree-18.1 {tag search back, no tag} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag prevrange x 1.1 1.1
} -cleanup {
    destroy .t
} -result {}
test btree-18.2 {tag search back, start at existing range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prevrange x 1.1
} -cleanup {
    destroy .t
} -result {}
test btree-18.3 {tag search back, end at existing range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prevrange x 1.3 1.1
} -cleanup {
    destroy .t
} -result {1.1 1.4}
test btree-18.4 {tag search back, start within range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prevrange x 1.10 1.0
} -cleanup {
    destroy .t
} -result {1.8 1.11}
test btree-18.5 {tag search back, start at end of range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    list [.t tag prevrange x 1.4 1.0] [.t tag prevrange x 1.11 1.0]
} -cleanup {
    destroy .t
} -result {{1.1 1.4} {1.8 1.11}}
test btree-18.6 {tag search back, start beyond range, same level 0 node} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.8 1.11
    .t tag add x 1.16
    .t tag prevrange x 3.0
} -cleanup {
    destroy .t
} -result {1.16 1.17}
test btree-18.7 {tag search back, outside any range} -setup {
    destroy .t
    text .t
} -body {
    .t insert 1.0 "Line 1 abcd efgh ijkl\n"
    .t tag add x 1.1 1.4
    .t tag add x 1.16
    .t tag prevrange x 1.8 1.5
} -cleanup {
    destroy .t
} -result {}
test btree-18.8 {tag search back, start at start of node boundary} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 2.5 2.8
    .t tag prevrange x 19.0
} -cleanup {
    destroy .t
} -result {2.5 2.8}
test btree-18.9 {tag search back, large complex btree spans} -setup {
    destroy .t
    text .t
} -body {
    setupBig
    .t tag add x 1.3 1.end
    .t tag add x 200.0 220.0
    .t tag add x 500.0 520.0
    list [.t tag prevrange x end] [.t tag prevrange x 433.0]
} -cleanup {
    destroy .t
} -result {{500.0 520.0} {200.0 220.0}}


test btree-19.0 {test toggle chain 1} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag add x 1.15 1.17
} -cleanup {
    destroy .t
} -result {}
test btree-19.1 {test toggle chain 2} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag add x 1.13 1.17
} -cleanup {
    destroy .t
} -result {}
test btree-19.2 {test toggle chain 3} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag add x 1.11 1.17
} -cleanup {
    destroy .t
} -result {}
test btree-19.3 {test toggle chain 4} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag add x 1.6 1.17
} -cleanup {
    destroy .t
} -result {}
    text .t
test btree-19.4 {test toggle chain 5} -setup {
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag add x 1.6 1.21
} -cleanup {
    destroy .t
} -result {}
test btree-19.5 {test toggle chain 6} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.15 1.17
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag remove 1.11 1.16
} -cleanup {
    destroy .t
} -result {}
test btree-19.6 {test toggle chain 7} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.15 1.17
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag remove 1.6 1.16
} -cleanup {
    destroy .t
} -result {}
test btree-19.7 {test toggle chain 8} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.15 1.17
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag remove 1.6 1.20
} -cleanup {
    destroy .t
} -result {}
test btree-19.8 {test toggle chain 9} -setup {
    text .t
} -body {
    .t insert end "abcdefghijklmnopqrstuvwxyzabcdef"
    .t tag add x 1.0 1.2
    .t tag add x 1.5 1.7
    .t tag add x 1.10 1.12
    .t tag add x 1.15 1.17
    .t tag add x 1.20 1.22
    .t tag add x 1.25 1.28

    .t tag remove 1.4 1.23
} -cleanup {
    destroy .t
} -result {}

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:
# vi:set ts=8 sw=4:

Changes to tests/textDisp.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52















53
54
55
56
57
58


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98

99





















100
101
102
103

104





























105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# This file is a Tcl script to test the code in the file tkTextDisp.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Platform specific procedure for updating the text widget.

if {[tk windowingsystem] == "aqua"} {
    proc updateText {} {
	update idletasks
    }
    proc delay {} {
	update idletasks
	after 100
	update idletasks
    }
} else {
    proc updateText {} {
	update
    }
    proc delay {} {
	update
	after 100
	update
    }
}

# The procedure below is used as the scrolling command for the text;
# it just saves the scrolling information in a variable "scrollInfo".

proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

# The procedure below is used to generate errors during scrolling commands.

proc scrollError args {
    error "scrolling error"
}
















# Create entries in the option database to be sure that geometry options
# like border width have predictable values.
set twbw 2
set twht 2
option add *Text.borderWidth $twbw
option add *Text.highlightThickness $twht



# The frame .f is needed to make sure that the overall window is always
# fairly wide, even if the text window is very narrow.  This is needed
# because some window managers don't allow the overall width of a window
# to get very narrow.

catch {destroy .f .t}
frame .f -width 100 -height 20
pack .f -side left

# On macOS the font "Courier New" has different metrics than "Courier",
# and this causes tests 20.1 - 20.5 to fail.  So we use "Courier" as the
# fixed font for testing on Aqua.

if {[tk windowingsystem] eq "aqua"} {
   set fixedFont {Courier -12}
} else {
  set fixedFont {"Courier New" -12}
}
# 15 on XP, 13 on Solaris 8
set fixedHeight [font metrics $fixedFont -linespace]
# 7 on all platforms
set fixedWidth [font measure $fixedFont m]
# 12 on XP
set fixedAscent [font metrics $fixedFont -ascent]
set fixedDiff [expr {$fixedHeight - 13}] ;# 2 on XP

set varFont {Times -14}
# 16 on XP, 15 on Solaris 8
set varHeight [font metrics $varFont -linespace]
# 13 on XP
set varAscent [font metrics $varFont -ascent]
set varDiff [expr {$varHeight - 15}] ;# 1 on XP

set bigFont {Helvetica -24}
# 27 on XP, 27 on Solaris 8
set bigHeight [font metrics $bigFont -linespace]
# 21 on XP
set bigAscent [font metrics $bigFont -ascent]

set ascentDiff [expr {$bigAscent - $fixedAscent}]























text .t -font $fixedFont -width 20 -height 10 -yscrollcommand scroll
pack .t -expand 1 -fill both
.t tag configure big -font $bigFont
.t debug on

wm geometry . {}






























# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .
updateText

# Some window managers (like olwm under SunOS 4.1.3) misbehave in a way
# that tends to march windows off the top and left of the screen.  If
# this happens, some tests will fail because parts of the window will
# not need to be displayed (because they're off-screen).  To keep this
# from happening, move the window if it's getting near the left or top
# edges of the screen.





|







<
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
|
|
<
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<
<
|
|
>
>










<
<
<
<
<
|
<
<
<
<

<

<

<

<
<
<
<
<
<
<
|
<

<

>

>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|







1
2
3
4
5
6
7
8
9
10
11
12
13


14

15




16






17



18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
61
62
63
64
65
66





67




68

69

70

71







72

73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# This file is a Tcl script to test the code in the file tkTextDisp.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test



# The delay procedure needs to wait long enough for the asynchronous updates

# performed by the text widget to run.




proc delay {} {






    update



    after 100
    update

}

# The procedure below is used as the scrolling command for the text;
# it just saves the scrolling information in a variable "scrollInfo".

proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

# The procedure below is used to generate errors during scrolling commands.

proc scrollError args {
    error "scrolling error"
}

# Return 1 if the two given lists are the same, otherwise return the two lists.
# This is used to compare a test actual result with a test expected result.

proc lequal {res expected} {
    if {[llength $res] != [llength $expected]} {
        return [list "Lengths differ"  result: $res - expected: $expected]
    }
    for {set i 0} {$i < [llength $res]} {incr i} {
        if {[lindex $res $i] ne [lindex $expected $i]} {
	    return [list result: $res - expected: $expected]
	}
    }
    return 1
}

# Create entries in the option database to be sure that geometry options
# like border width have selected values.


option add *Text.borderWidth 2         ; # tests work with [1-2]
option add *Text.highlightThickness 2  ; # tests work with [1-4]
option add *Text.padX 1  ; # same padding in x and y, see proc bo; tests work with [0-3]
option add *Text.padY 1  ; # same padding in x and y, see proc bo; tests work with [0-3]

# The frame .f is needed to make sure that the overall window is always
# fairly wide, even if the text window is very narrow.  This is needed
# because some window managers don't allow the overall width of a window
# to get very narrow.

catch {destroy .f .t}
frame .f -width 100 -height 20
pack .f -side left






set fixedFont {Courier -12}




set fixedHeight [font metrics $fixedFont -linespace]

set fixedWidth [font measure $fixedFont m]

set fixedAscent [font metrics $fixedFont -ascent]









set bigFont {Helvetica -24}  ; # note: not a fixed-width font!

set bigHeight [font metrics $bigFont -linespace]

set bigAscent [font metrics $bigFont -ascent]

set ascentDiff [expr {$bigAscent - $fixedAscent}]
set heightDiff [expr {$bigHeight - $fixedHeight}]

# On Windows at least, the tests do work with {Courier -8}, {Courier -10}, {Courier -12} or {Courier -14} as fixedFont.
# Warn the user if the actual font is too different from what was requested.
if {[font metrics [font actual $fixedFont] -fixed] != 1} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
does not seem to be a fixed-width font as expected. If this is really the case, many upcoming\
tests will fail."
}
if {$fixedHeight < 12 || $fixedHeight > 15} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedHeight pixels height while the tests expect between 12 and 15 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}
if {$fixedWidth < 6 || $fixedWidth > 8} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedWidth pixels in width while the tests expect between 6 and 8 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}

# Option  -width 20  (characters) below is a fundamental assumption of many
# upcoming tests when wrapping enters in play
# Also  -height 10  (lines) is an important assumption
text .t -font $fixedFont -width 20 -height 10 -yscrollcommand scroll
pack .t -expand 1 -fill both
.t tag configure big -font $bigFont
.t debug on

wm geometry . {}

# full border size of the text widget, i.e. first x or y coordinate inside the text widget
# warning:  -padx  is supposed to be the same as  -pady  (same border size horizontally and
# vertically around the widget)
proc bo {{w .t}} {
    return [expr {[$w cget -borderwidth] + [$w cget -highlightthickness] + [$w cget -padx]}]
}
# x-width of $n chars, fixed width font
proc xw {n} {
    global fixedWidth
    return [expr {$n * $fixedWidth}]
}
# x-coordinate of the first pixel of $n-th char (count starts at zero), left justified
proc xchar {n {w .t}} {
    return [expr {[bo $w] + [xw $n]}]
}
# x-coordinate in widget $w of the first pixel of $n-th char counted from the right, right justified
proc xcharr {n {w .t}} {
    return [expr {[winfo width $w] - [bo $w] - [xw $n]}]
}
# y-coordinate of the first pixel of $l-th display line (count starts at 1)
proc yline {l {w .t}} {
    global fixedHeight
    return [expr {[bo $w] + ($l - 1) * $fixedHeight}]
}
# x-pixels of empty space in widget $w on a line containing $n chars
proc xe {n {w .t}} {
    return [expr {[winfo width $w] - (2 * [bo $w]) - [xw $n]}]
}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .
update

# Some window managers (like olwm under SunOS 4.1.3) misbehave in a way
# that tends to march windows off the top and left of the screen.  If
# this happens, some tests will fail because parts of the window will
# not need to be displayed (because they're off-screen).  To keep this
# from happening, move the window if it's getting near the left or top
# edges of the screen.
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258


259
260
261
262
263
264
265
266

267
268
269
270
271
272

273
274
275
276
277
278

279
280
281
282
283
284

285
286
287
288
289

290


291
292
293
294
295
296

297
298
299
300
301
302
303
304


305
306
307

308
309

310
311
312
313
314
315
316
317
318
319


320
321
322
323
324
325


326
327
328
329
330
331
332
333
334
335


336
337
338
339
340
341

342
343
344
345
346
347
348
349
350



351
352
353
354
355
356
357
358
359



360
361
362
363
364
365
366
367
368
369


370

371
372
373
374
375
376
377
378
379
380
381



382
383
384
385
386
387
388
389
390



391
392
393
394
395
396
397
398



399
400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416




417
418




419
420

421
422
423
424
425
426
427
428
429
430
431



432
433
434
435
436
437
438
439


440
441
442
443
444
445
446
447
448
449
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {TRAFFIC SYSTEM}
    updateText
    destroy .txt
} {}

test textDisp-0.4 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {SYSTEM TRAFFIC}
    # Crash was here.
    updateText
    destroy .txt
} {}

test textDisp-0.5 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    .txt tag configure WELCOME -elide 1
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1

    .txt insert end "\n" {SYSTEM TRAFFIC}
    .txt insert end "\n" WELCOME
    # Crash was here.
    updateText
    destroy .txt
} {}

test textDisp-1.1 {GetStyle procedure, priorities and tab stops} {
    .t delete 1.0 end
    .t insert 1.0 "x\ty"
    .t tag delete x y z
    .t tag configure x -tabs 50
    .t tag configure y -foreground black
    .t tag configure z -tabs 70
    .t tag add x 1.0 1.end
    .t tag add y 1.0 1.end
    .t tag add z 1.0 1.end
    update idletasks
    set x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {}
    lappend x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs 30
    .t tag raise x
    update idletasks
    lappend x [lindex [.t bbox 1.2] 0]
} [list 75 55 55]
.t tag delete x y z
test textDisp-1.2 {GetStyle procedure, wrapmode} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcd\nefg hijkl mnop qrstuv wxyz"
    .t tag configure x -wrap word
    .t tag configure y -wrap none
    .t tag raise y
    updateText
    set result [list [.t bbox 2.20]]
    .t tag add x 2.0 2.1
    lappend result [.t bbox 2.20]
    .t tag add y 1.end 2.2
    lappend result [.t bbox 2.20]
} [list [list 5 [expr {5+2*$fixedHeight}] 7 $fixedHeight] [list 40 [expr {5+2*$fixedHeight}] 7 $fixedHeight] {}]


.t tag delete x y

test textDisp-2.1 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [expr {5 + $fixedWidth * 19}] 5 $fixedWidth $fixedHeight] [list 5 [expr {5 + $fixedHeight}] $fixedWidth $fixedHeight]]

test textDisp-2.2 {LayoutDLine, basics} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-2.3 {LayoutDLine, basics} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-2.4 {LayoutDLine, word wrap} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-2.5 {LayoutDLine, word wrap} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.13] [.t bbox 1.19] [.t bbox 1.20] [.t bbox 1.21]

} [list [list 96 5 $fixedWidth $fixedHeight] [list 138 5 $fixedWidth $fixedHeight] [list 145 5 0  $fixedHeight] [list 5 [expr {$fixedDiff + 18}] $fixedWidth $fixedHeight]]


test textDisp-2.6 {LayoutDLine, word wrap} failsOnUbuntu {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.15] [.t bbox 1.16]
} [list [list 110 5 35 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-2.7 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    .t tag add foo 1.4 1.6
    .t mark set insert 1.8
    list [.t bbox 1.2] [.t bbox 1.5] [.t bbox 1.11]
} [list [list 19 5 7 $fixedHeight] [list 40 5 7 $fixedHeight] [list 82 5 7 $fixedHeight]]


foreach m [.t mark names] {
    catch {.t mark unset $m}
}

scan [wm geom .] %dx%d width height
test textDisp-2.8 {LayoutDLine, extra chunk at end of dline} {textfonts} {

    wm geom . [expr {$width+1}]x$height
    updateText
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxx some sample text for testing."
    .t mark set foo 1.20
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 138 5 8 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
wm geom . {}
updateText


test textDisp-2.9 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    list [.t bbox 1.9] [.t bbox 1.10] [.t bbox 1.25]
} [list [list 68 5 77 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 110 [expr {$fixedDiff + 18}] 7 $fixedHeight]]


test textDisp-2.10 {LayoutDLine, marks and tags} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    .t tag add foo 1.13
    .t tag add foo 1.15
    .t tag add foo 1.17
    .t tag add foo 1.19
    list [.t bbox 1.9] [.t bbox 1.10] [.t bbox 1.25]
} [list [list 68 5 77 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 110 [expr {$fixedDiff + 18}] 7 $fixedHeight]]


test textDisp-2.11 {LayoutDLine, newline width} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a\nbb\nccc\ndddd"
    list [.t bbox 2.2] [.t bbox 3.3]
} [list [list 19 [expr {$fixedDiff + 18}] 126 $fixedHeight] [list 26 [expr {2*$fixedDiff + 31}] 119 $fixedHeight]]

test textDisp-2.12 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 1.0 end
    .t tag add y 3.0 3.2
    list [.t bbox 1.0] [.t bbox 2.0] [.t bbox 4.0] [.t bbox 4.2]
} [list [list 75 5 70 $fixedHeight] [list 71 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 64 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] [list 78 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]



test textDisp-2.13 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify right
    .t tag add x 1.0 end
    .t tag add y 3.0 3.2
    list [.t bbox 1.0] [.t bbox 2.0] [.t bbox 4.0] [.t bbox 4.2]
} [list [list 145 5 0 $fixedHeight] [list 138 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 124 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] [list 138 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]



test textDisp-2.14 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 2.0 3.1
    .t tag configure y -justify right
    .t tag add y 3.0 4.0
    .t tag raise y
    list [.t bbox 2.0] [.t bbox 3.0] [.t bbox 3.end] [.t bbox 4.0]


} [list [list 71 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 131 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 145 [expr {2*$fixedDiff + 31}] 0 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]

test textDisp-2.15 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 2.0 3.1
    .t tag configure y -justify right
    .t tag add y 3.0 4.0
    .t tag lower y
    list [.t bbox 2.0] [.t bbox 3.0] [.t bbox 3.end] [.t bbox 4.0]
} [list [list 71 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 68 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 82 [expr {2*$fixedDiff + 31}] 63 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]



test textDisp-2.16 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.1 1.20
    .t tag add x 1.21 1.end
    list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.41] [.t bbox 2.0]
} [list [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 61 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]



test textDisp-2.17 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of very long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.18
    list [.t bbox 1.0] [.t bbox 1.18] [.t bbox 1.35] [.t bbox 2.0]
} [list [list 5 5 7 $fixedHeight] [list 15 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]



test textDisp-2.18 {LayoutDLine, justification} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to extend out of the window\n"
    .t insert end "Then\nmore lines\nThat are shorter"
    .t tag configure x -justify center
    .t tag configure y -justify right
    .t tag add x 2.0
    .t tag add y 3.0
    .t xview scroll 5 units
    list [.t bbox 2.0] [.t bbox 3.0]
} [list [list 26 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 40 [expr {2*$fixedDiff + 31}] 7 $fixedHeight]]

.t tag delete x
.t tag delete y
test textDisp-2.19 {LayoutDLine, margins} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"




    .t tag configure x -lmargin1 20 -lmargin2 40 -rmargin 15
    .t tag add x 1.0 end




    list [.t bbox 1.0] [.t bbox 1.12] [.t bbox 1.13] [.t bbox 2.0]
} [list [list 25 5 7 $fixedHeight] [list 109 5 36 $fixedHeight] [list 45 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 25 [expr {5*$fixedDiff + 70}] 7 $fixedHeight]]

test textDisp-2.20 {LayoutDLine, margins} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -lmargin1 20 -lmargin2 10 -rmargin 3
    .t tag configure y -lmargin1 15 -lmargin2 5 -rmargin 0
    .t tag raise y
    .t tag add x 1.0 end
    .t tag add y 1.13
    list [.t bbox 1.0] [.t bbox 1.13] [.t bbox 1.30] [.t bbox 2.0]
} [list [list 25 5 7 $fixedHeight] [list 10 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 15 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 25 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]



test textDisp-2.21 {LayoutDLine, margins} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text"
    .t tag configure x -lmargin1 80 -lmargin2 80 -rmargin 100
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list 85 5 60 $fixedHeight] [list 85 [expr {$fixedDiff + 18}] 60 $fixedHeight] [list 85 [expr {2*$fixedDiff + 31}] 60 $fixedHeight]]


.t tag delete x
.t tag delete y
test textDisp-2.22 {LayoutDLine, spacing options} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]







|












|













|







|

|







|



|

|






|





|
>
>







|
>
|




|
>
|




|
>
|




|
>
|




>
|
>
>
|




|
>
|






|
>
>



>
|
<
>

|





|
|
|
>
>
|




|
>
>
|








|
>
>
|




|
>
|







|
>
>
>
|







|
>
>
>
|









>
>
|
>
|









|
>
>
>
|







|
>
>
>
|






|
>
>
>
|










|
>


|



>
>
>
>
|

>
>
>
>
|
<
>
|









|
>
>
>
|






|
>
>


|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {TRAFFIC SYSTEM}
    update
    destroy .txt
} {}

test textDisp-0.4 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    # Note that TRAFFIC should have a higher priority than SYSTEM
    # in terms of the tag effects.
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1
    .txt insert end "\n" {SYSTEM TRAFFIC}
    # Crash was here.
    update
    destroy .txt
} {}

test textDisp-0.5 {double tag elide transition} {
    catch {destroy .txt}
    pack [text .txt]
    .txt tag configure WELCOME -elide 1
    .txt tag configure SYSTEM -elide 0
    .txt tag configure TRAFFIC -elide 1

    .txt insert end "\n" {SYSTEM TRAFFIC}
    .txt insert end "\n" WELCOME
    # Crash was here.
    update
    destroy .txt
} {}

test textDisp-1.1 {GetStyle procedure, priorities and tab stops} {
    .t delete 1.0 end
    .t insert 1.0 "x\ty"
    .t tag delete x y z
    .t tag configure x -tabs {50}
    .t tag configure y -foreground black
    .t tag configure z -tabs {70}
    .t tag add x 1.0 1.end
    .t tag add y 1.0 1.end
    .t tag add z 1.0 1.end
    update idletasks
    set x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {}
    lappend x [lindex [.t bbox 1.2] 0]
    .t tag configure z -tabs {30}
    .t tag raise x
    update idletasks
    lappend x [lindex [.t bbox 1.2] 0]
} [list [expr {[bo]+70}] [expr {[bo]+50}] [expr {[bo]+50}]]
.t tag delete x y z
test textDisp-1.2 {GetStyle procedure, wrapmode} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcd\nefg hijkl mnop qrstuv wxyz"
    .t tag configure x -wrap word
    .t tag configure y -wrap none
    .t tag raise y
    update
    set result [list [.t bbox 2.20]]
    .t tag add x 2.0 2.1
    lappend result [.t bbox 2.20]
    .t tag add y 1.end 2.2
    lappend result [.t bbox 2.20]
} [list [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 3] $fixedWidth $fixedHeight] \
	    {}]
.t tag delete x y

test textDisp-2.1 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.2 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.3 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.4 {LayoutDLine, word wrap} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is some sample text for testing."
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.5 {LayoutDLine, word wrap} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isx some sample text for testing."
    list [.t bbox 1.13] [.t bbox 1.19] [.t bbox 1.20] [.t bbox 1.21]
} [list [list [xchar 13] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
	    [list [xchar 20] [yline 1] 0  $fixedHeight] \
	    [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.6 {LayoutDLine, word wrap} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    list [.t bbox 1.15] [.t bbox 1.16]
} [list [list [xchar 15] [yline 1] [xe 15] $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.7 {LayoutDLine, marks and tags} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This isxxx some sample text for testing."
    .t tag add foo 1.4 1.6
    .t mark set insert 1.8
    list [.t bbox 1.2] [.t bbox 1.5] [.t bbox 1.11]
} [list [list [xchar 2] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 1] $fixedWidth $fixedHeight] \
	    [list [xchar 11] [yline 1] $fixedWidth $fixedHeight]]
foreach m [.t mark names] {
    catch {.t mark unset $m}
}
test textDisp-2.8 {LayoutDLine, extra chunk at end of dline} -setup {
    scan [wm geom .] %dx%d width height

} -body {
    wm geom . [expr {$width+1}]x$height
    update
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxx some sample text for testing."
    .t mark set foo 1.20
    list [.t bbox 1.19] [.t bbox 1.20]
} -cleanup {
    wm geom . {}
    update
} -result [list [list [xchar 19] [yline 1] [expr {$fixedWidth+1}] $fixedHeight] \
                [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.9 {LayoutDLine, marks and tags} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    list [.t bbox 1.9] [.t bbox 1.10] [.t bbox 1.25]
} [list [list [xchar 9] [yline 1] [xe 9] $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	    [list [xchar 15] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.10 {LayoutDLine, marks and tags} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    .t tag add foo 1.13
    .t tag add foo 1.15
    .t tag add foo 1.17
    .t tag add foo 1.19
    list [.t bbox 1.9] [.t bbox 1.10] [.t bbox 1.25]
} [list [list [xchar 9] [yline 1] [xe 9] $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	    [list [xchar 15] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.11 {LayoutDLine, newline width} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a\nbb\nccc\ndddd"
    list [.t bbox 2.2] [.t bbox 3.3]
} [list [list [xchar 2] [yline 2] [xe 2] $fixedHeight] \
        [list [xchar 3] [yline 3] [xe 3] $fixedHeight]]
test textDisp-2.12 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 1.0 end
    .t tag add y 3.0 3.2
    list [.t bbox 1.0] [.t bbox 2.0] [.t bbox 4.0] [.t bbox 4.2]
} [list [list [expr {[bo]+[xe 0]/2}] [yline 1] [expr {[xe 0]-[xe 0]/2}] $fixedHeight] \
        [list [expr {[bo]+[xe 1]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 3]/2}] [yline 4] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 3]/2+[xw 2]}] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.13 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify right
    .t tag add x 1.0 end
    .t tag add y 3.0 3.2
    list [.t bbox 1.0] [.t bbox 2.0] [.t bbox 4.0] [.t bbox 4.2]
} [list [list [xcharr 0] [yline 1] 0 $fixedHeight] \
        [list [xcharr 1] [yline 2] $fixedWidth $fixedHeight] \
        [list [xcharr 3] [yline 4] $fixedWidth $fixedHeight] \
        [list [xcharr 1] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.14 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 2.0 3.1
    .t tag configure y -justify right
    .t tag add y 3.0 4.0
    .t tag raise y
    list [.t bbox 2.0] [.t bbox 3.0] [.t bbox 3.end] [.t bbox 4.0]
} [list [list [expr {[bo]+[xe 1]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [xcharr 2] [yline 3] $fixedWidth $fixedHeight] \
        [list [xcharr 0] [yline 3] 0 $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.15 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 2.0 3.1
    .t tag configure y -justify right
    .t tag add y 3.0 4.0
    .t tag lower y
    list [.t bbox 2.0] [.t bbox 3.0] [.t bbox 3.end] [.t bbox 4.0]
} [list [list [expr {[bo]+[xe 1]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 2]/2}] [yline 3] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 2]/2+[xw 2]}] [yline 3] [expr {[xe 2]/2}] $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.16 {LayoutDLine, justification} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.1 1.20
    .t tag add x 1.21 1.end
    list [.t bbox 1.0] [.t bbox 1.20] [.t bbox 1.41] [.t bbox 2.0]
} [list [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 4]/2}] [yline 3] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.17 {LayoutDLine, justification} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of very long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -justify center
    .t tag add x 1.18
    list [.t bbox 1.0] [.t bbox 1.18] [.t bbox 1.35] [.t bbox 2.0]
} [list [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 17]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.18 {LayoutDLine, justification} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to extend out of the window\n"
    .t insert end "Then\nmore lines\nThat are shorter"
    .t tag configure x -justify center
    .t tag configure y -justify right
    .t tag add x 2.0
    .t tag add y 3.0
    .t xview scroll 5 units
    list [.t bbox 2.0] [.t bbox 3.0]
} [list [list [expr {[bo]+[xe 4]/2-[xw 5]}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[xcharr 10]-[xw 5]}] [yline 3] $fixedWidth $fixedHeight]]
.t tag delete x
.t tag delete y
test textDisp-2.19 {LayoutDLine, margins} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    # margins in pixels depend on the font width for more flexibility
    set lm1 [expr {3*$fixedWidth}]
    set lm2 [expr {2*$lm1}]
    set rm [expr {2*$fixedWidth}]
    .t tag configure x -lmargin1 $lm1 -lmargin2 $lm2 -rmargin $rm
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$lm1}] [yline 1] $fixedWidth $fixedHeight] \
                       [list [expr {[bo]+$lm1+[xw 12]}] [yline 1] [expr {[xe 12]-$lm1}] $fixedHeight] \
                       [list [expr {[bo]+$lm2}] [yline 2] $fixedWidth $fixedHeight] \
                       [list [expr {[bo]+$lm1}] [yline 6] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.0] [.t bbox 1.12] [.t bbox 1.13] [.t bbox 2.0]] $expected

} {1}
test textDisp-2.20 {LayoutDLine, margins} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Lots of long words, enough to force word wrap\nThen\nmore lines"
    .t tag configure x -lmargin1 20 -lmargin2 10 -rmargin 3
    .t tag configure y -lmargin1 15 -lmargin2 5 -rmargin 0
    .t tag raise y
    .t tag add x 1.0 end
    .t tag add y 1.13
    list [.t bbox 1.0] [.t bbox 1.13] [.t bbox 1.30] [.t bbox 2.0]
} [list [list [expr {[bo]+20}] [yline 1] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+5}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+10}] [yline 3] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+20}] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.21 {LayoutDLine, margins} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text"
    .t tag configure x -lmargin1 80 -lmargin2 80 -rmargin 100
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list [expr {[bo]+80}] [yline 1] [expr {[xe 0]-80}] $fixedHeight] \
        [list [expr {[bo]+80}] [yline 2] [expr {[xe 0]-80}] $fixedHeight] \
        [list [expr {[bo]+80}] [yline 3] [expr {[xe 0]-80}] $fixedHeight]]
.t tag delete x
.t tag delete y
test textDisp-2.22 {LayoutDLine, spacing options} {
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4] - $b3}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4] - $b4}]
    list $b1 $b2 $b3 $b4
} [list 2 7 10 15]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.23 {LayoutDLine, spacing options} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]







|







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4] - $b3}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4] - $b4}]
    list $b1 $b2 $b3 $b4
} [list 2 7 10 15]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.23 {LayoutDLine, spacing options} {
    .t configure -wrap word
    .t delete 1.0 end
    .t tag delete x y
    .t insert end "Short line\nLine 2 is long enough "
    .t insert end "to wrap around a couple of times"
    .t insert end "\nLine 3\nLine 4"
    set i [.t dlineinfo 1.0]
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513


514
515
516
517
518

519
520

521





522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566



567

568
569
570
571
572
573
574
575
576
577
578




579
580
581
582
583
584
585
586
587
588
589
590




591
592
593
594
595
596
597
598
599



600
601
602
603
604
605
606



607
608
609
610
611
612
613
614
615
616
617
618



619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646


647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
701


702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

747



748
749
750
751
752
753
754
755
756
757
758
759
760
761
762

763



764
765
766
767
768
769
770
771
772
773
774



775
776
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
792
793
794
795

796
797
798
799
800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837


838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856



857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921

922
923
924
925
926
927
928
929
930
931
932
933
934
935
936

937
938
939
940
941
942

943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036

1037
1038
1039
1040
1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053

1054
1055
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254


1255
1256
1257
1258
1259
1260
1261


1262
1263


1264
1265
1266
1267
1268
1269
1270


1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294


1295

1296
1297
1298
1299
1300
1301
1302
1303



1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326


1327
1328
1329
1330
1331
1332
1333
1334


1335
1336


1337
1338
1339
1340
1341
1342
1343
1344


1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365



1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4] - $b3}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4] - $b4}]
    list $b1 $b2 $b3 $b4
} [list 1 5 13 16]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.24 {LayoutDLine, tabs, saving from first chunk} {textfonts} {
    .t delete 1.0 end
    .t tag delete x y
    .t tag configure x -tabs 70
    .t tag configure y -tabs 80
    .t insert 1.0 "ab\tcde"
    .t tag add x 1.0 end
    .t tag add y 1.1 end
    lindex [.t bbox 1.3] 0
} 75
test textDisp-2.25 {LayoutDLine, tabs, breaking chunks at tabs} {textfonts} {
    .t delete 1.0 end
    .t tag delete x


    .t tag configure x -tabs [list 30 60 90 120]
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
    .t tag add x 1.0 end

    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	    [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]

} [list 35 65 95 125]





test textDisp-2.26 {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] -justify right
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	    [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]
} [list 117 124 131 138]
test textDisp-2.27 {LayoutDLine, tabs, calling AdjustForTab} {textfonts} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60]
    .t insert 1.0 "a\tb\tcd"
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0]
} [list 35 65]
test textDisp-2.28 {LayoutDLine, tabs, running out of space in dline} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "a\tb\tc\td"
    .t bbox 1.6
} [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-2.29 {LayoutDLine, tabs, running out of space in dline} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "a\tx\tabcd"
    .t bbox 1.4
} [list 117 5 7 $fixedHeight]
test textDisp-2.30 {LayoutDLine, tabs, running out of space in dline} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "a\tx\tabc"
    .t bbox 1.4
} [list 117 5 7 $fixedHeight]

test textDisp-3.1 {different character sizes} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert end "Some sample text, including both large\n"
    .t insert end "characters and\nsmall\n"
    .t insert end "abc\nd\ne\nfghij"
    .t tag add big 1.5 1.10
    .t tag add big 2.11 2.14
    list [.t bbox 1.1] [.t bbox 1.6] [.t dlineinfo 1.0] [.t dlineinfo 3.0]
} [list [list 12 [expr {5+$ascentDiff}] 7 $fixedHeight] [list 52 5 13 27] [list 5 5 114 27 [font metrics $bigFont -ascent]] [list 5 [expr {2* $fixedDiff + 85}] 35 $fixedHeight [expr {$fixedDiff + 10}]]]



.t configure -wrap char

test textDisp-4.1 {UpdateDisplayInfo, basic} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2\nLine 3\n"
    updateText
    .t delete 2.0 2.end
    updateText
    set res $tk_textRelayout
    .t insert 2.0 "New Line 2"
    updateText
    lappend res [.t bbox 1.0] [.t bbox 2.0] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 [list 5 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] 2.0]




test textDisp-4.2 {UpdateDisplayInfo, re-use tail of text line} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    .t mark set x 2.21
    .t delete 2.2
    updateText
    set res $tk_textRelayout
    .t insert 2.0 X
    updateText
    lappend res [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 2.20 [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 12 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] {2.0 2.20}]




test textDisp-4.3 {UpdateDisplayInfo, tail of text line shifts} {textfonts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    .t mark set x 2.21
    .t delete 2.2
    updateText
    list [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] {2.0 2.20}]



.t mark unset x
test textDisp-4.4 {UpdateDisplayInfo, wrap-mode "none"} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    list [.t bbox 2.0] [.t bbox 2.25] [.t bbox 3.0] $tk_textRelayout



} [list [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight] {} [list 5 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] {1.0 2.0 3.0}]
test textDisp-4.5 {UpdateDisplayInfo, tiny window} {textfonts} {
    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    wm geom . 103x$height
    updateText
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    list [.t bbox 2.0] [.t bbox 2.1] [.t bbox 3.0] $tk_textRelayout



} [list [list 5 [expr {$fixedDiff + 18}] 1 $fixedHeight] {} [list 5 [expr {2*$fixedDiff + 31}] 1 $fixedHeight] {1.0 2.0 3.0}]
if {$tcl_platform(platform) == "windows"} {
    wm overrideredirect . 0
}
test textDisp-4.6 {UpdateDisplayInfo, tiny window} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    frame .f2 -width 20 -height 100
    pack .f2 -before .f
    wm geom . 103x103
    updateText
    .t configure -wrap none -borderwidth 2
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    set x [list [.t bbox 1.0] [.t bbox 2.0] $tk_textRelayout]
    wm overrideredirect . 0
    updateText
    set x
} [list [list 5 5 1 1] {} 1.0]


catch {destroy .f2}
.t configure -borderwidth 0 -wrap char
wm geom . {}
updateText
set bw [.t cget -borderwidth]
set px [.t cget -padx]
set py [.t cget -pady]
set hlth [.t cget -highlightthickness]
test textDisp-4.7 {UpdateDisplayInfo, filling in extra vertical space} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 1.0
    updateText
    .t yview 16.0
    updateText
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
    wm overrideredirect . 0
    updateText
    set x
} {8.0 {16.0 17.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0} {8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0}}
test textDisp-4.8 {UpdateDisplayInfo, filling in extra vertical space} failsOnXQuarz {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    updateText
    .t delete 5.0 14.0
    updateText
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
} {1.0 {5.0 4.0 3.0 2.0 1.0} {1.0 2.0 3.0 4.0 5.0 eof}}
test textDisp-4.9 {UpdateDisplayInfo, filling in extra vertical space} {textfonts} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    updateText
    .t delete 15.0 end
    list [.t bbox 7.0] [.t bbox 12.0]
} [list [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 2 * $fixedHeight}] $fixedWidth $fixedHeight] [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 7 * $fixedHeight}] $fixedWidth $fixedHeight]]

test textDisp-4.10 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    updateText
    .t delete 13.0 end
    updateText
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw


} {5.0 {12.0 7.0 6.40 6.20 6.0 5.0} {5.0 6.0 6.20 6.40 7.0 12.0}}
test textDisp-4.11 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around, not once but really quite a few times.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    updateText
    .t delete 14.0 end
    updateText
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
} {6.40 {13.0 7.0 6.80 6.60 6.40} {6.40 6.60 6.80 7.0 13.0}}
test textDisp-4.12 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16"
    button .b -text "Test" -bd 2 -highlightthickness 2
    .t window create 3.end -window .b
    .t yview moveto 1
    updateText
    .t yview moveto 0
    updateText
    .t yview moveto 1
    updateText
    winfo ismapped .b
} 0
.t configure -wrap word
.t delete 1.0 end
.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"
.t insert end "Line 8\nLine 9\nLine 10\nLine 11\nLine 12\nLine 13\n"
.t insert end "Line 14\nLine 15\nLine 16"
.t tag delete x
.t tag configure x -relief raised -borderwidth 2 -background white
test textDisp-4.13 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 1.0
    updateText
    .t yview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {4.0 10.0 11.0 12.0 13.0}}
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} failsOnXQuarz {
    .t tag remove x 1.0 end
    .t yview 1.0
    updateText
    .t yview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw

} {{11.0 12.0 13.0} {11.0 12.0 13.0}}



test textDisp-4.15 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 4.0
    updateText
    .t yview scroll -2 units
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0 4.0 11.0}}
test textDisp-4.16 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 4.0
    updateText
    .t yview scroll -2 units
    updateText
    list $tk_textRelayout $tk_textRedraw

} {{2.0 3.0} {2.0 3.0}}



test textDisp-4.17 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    updateText
    .t xview scroll 3 units
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.0] [.t bbox 2.5] \
	    [.t bbox 2.23]
} [list {} {1.0 2.0 3.0 4.0} {} [list 17 [expr {$fixedDiff + 16}] 7 $fixedHeight] {}]



test textDisp-4.18 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    updateText
    .t xview scroll 100 units
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list {} {1.0 2.0 3.0 4.0} [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-4.19 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    updateText
    .t xview moveto 0
    .t xview scroll -10 units
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.5]
} [list {} {1.0 2.0 3.0 4.0} [list 38 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-4.20 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto 0.0
    .t xview scroll 100 units
    updateText
    .t delete 2.30 2.44
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list 2.0 {1.0 2.0 3.0 4.0} [list 108 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-4.21 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto .9
    updateText
    .t xview moveto .6
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {}}
test textDisp-4.22 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    updateText
    .t configure -wrap word
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 10 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]

test textDisp-4.23 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    updateText
    .t configure -wrap char
    list [.t bbox 2.0] [.t bbox 2.16]


} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 115 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-5.1 {DisplayDLine, handling of spacing} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijkl\nmnopqrstuvwzyz"
    .t tag configure spacing -spacing1 8 -spacing3 2
    .t tag add spacing 1.0 end
    frame .t.f1 -width 10 -height 4 -bg black
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    updateText
    list [winfo geometry .t.f1] [winfo geometry .t.f2] \
	    [winfo geometry .t.f3] [winfo geometry .t.f4]
} [list 10x4+24+11 10x4+55+[expr {$fixedDiff/2 + 15}] 10x4+10+[expr {2*$fixedDiff + 43}] 10x4+76+[expr {2*$fixedDiff + 40}]]



.t tag delete spacing

# Although the following test produces a useful result, its main
# effect is to produce a core dump if Tk doesn't handle display
# relayout that occurs during redisplay.

test textDisp-5.2 {DisplayDLine, line resizes during display} {
    .t delete 1.0 end
    frame .t.f -width 20 -height 20 -bd 2 -relief raised
    bind .t.f <Configure> {.t.f configure -width 30 -height 30}
    .t window create insert -window .t.f
    updateText
    list [winfo width .t.f] [winfo height .t.f]
} [list 30 30]

.t configure -wrap char
test textDisp-6.1 {scrolling in DisplayText, scroll up} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 10.0} {2.0 10.0}}
test textDisp-6.2 {scrolling in DisplayText, scroll down} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.0 "New Line 2\n"
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-6.3 {scrolling in DisplayText, multiple scrolls} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.end "is so long that it wraps"
    .t insert 4.end "is so long that it wraps"
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 4.0 4.20} {2.0 2.20 4.0 4.20}}
test textDisp-6.4 {scrolling in DisplayText, scrolls interfere} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.end "is so long that it wraps around, not once but three times"
    .t insert 4.end "is so long that it wraps"
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 2.40 2.60 4.0 4.20} {2.0 2.20 2.40 2.60 4.0 4.20 6.0}}
test textDisp-6.5 {scrolling in DisplayText, scroll source obscured} {nonPortable} {

    .t configure -wrap char
    frame .f2 -bg red
    place .f2 -in .t -relx 0.5 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.6 1.end
    updateText
    destroy .f2
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 4.0 5.0 9.0 10.0}}
test textDisp-6.6 {scrolling in DisplayText, Expose events after scroll} {unix nonPortable} {

    # this test depends on all of the expose events being handled at once
    .t configure -wrap char
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t configure -bd 2 -relief raised
    .t delete 1.0 end

    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.6 1.end
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {borders 1.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0}}
.t configure -bd 0
test textDisp-6.7 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-6.8 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    updateText
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    updateText
    .t count -update -ypixels 1.0 end ; update
    set scrollInfo
} [list 0.0 [expr {10.0/13}]]
.t configure -yscrollcommand {} -xscrollcommand scroll
test textDisp-6.9 {DisplayText, horizontal scrollbar updates} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    set scrollInfo unchanged
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-6.10 {DisplayText, redisplay embedded windows after scroll.} {aqua} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4} {
	.t insert end "\nLine $i"
    }
    .t insert end "\n"
    .t window create end -create {
	button %W.button_one -text "Button 1"}
    .t insert end "\nLine 6\n"
    .t window create end -create {
	button %W.button_two -text "Button 2"}
    .t insert end "\nLine 8\n"
    .t window create end -create {
	button %W.button_three -text "Button 3"}
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textEmbWinDisplay
} {{4.0 6.0}}


# The following group of tests is marked non-portable because
# they result in a lot of extra redisplay under Ultrix.  I don't
# know why this is so.

.t configure -bd 2 -relief raised -wrap char
.t delete 1.0 end
.t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
    .t insert end "\nLine $i"
}
test textDisp-7.1 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -relwidth 0.6 -rely 0.22 -relheight 0.55
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {1.40 2.0 3.0 4.0 5.0 6.0}}
test textDisp-7.2 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.5 -rely 0 -relheight 0.5
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20 1.40 2.0 3.0}}
test textDisp-7.3 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.5 -relwidth 0.5 -rely 0.5 -relheight 0.5
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 8.0}}
test textDisp-7.4 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 0 -relheight 0.2 \
	    -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20}}
test textDisp-7.5 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 1.0 -relheight 0.2 \
	    -anchor s -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 7.0 8.0}}
test textDisp-7.6 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor w -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.7 {TkTextRedrawRegion} {nonPortable} {

    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 1.0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor e -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.8 {TkTextRedrawRegion} {nonPortable} {

    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\n"
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.0 -relwidth 0.4 -rely 0.35 -relheight 0.4 \
	    -anchor nw -bordermode ignore
    updateText
    destroy .f2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 eof}}
.t configure -bd 0

test textDisp-8.1 {TkTextChanged: redisplay whole lines} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around, two times"
    foreach i {3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.36 2.38
    updateText
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.32]
} [list {2.0 2.18 2.38} {2.0 2.18 2.38} [list 101 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]
.t configure -wrap char
test textDisp-8.2 {TkTextChanged, redisplay whole lines} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 1.2 xx
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.3 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t insert 2.0 xx
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.4 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.5
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.5 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.40 1.44
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.6 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.41 1.44
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.7 {TkTextChanged} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 1.2 1.end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 9.0 10.0}}
test textDisp-8.8 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.2
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.9 {TkTextChanged} failsOnXQuarz {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    .t delete 2.0 3.0
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 8.0} {2.0 8.0}}
test textDisp-8.10 {TkTextChanged} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    updateText
    .t delete 2.19
    updateText
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-8.11 {TkTextChanged, scrollbar notification when changes are off-screen} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n"
    .t configure -yscrollcommand scroll
    updateText
    set scrollInfo ""
    .t insert end "a\nb\nc\n"
    # We need to wait for our asychronous callbacks to update the
    # scrollbar
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    .t configure -yscrollcommand ""
    set scrollInfo
} {0.0 0.625}
test textDisp-8.12 {TkTextChanged, moving the insert cursor redraws only past and new lines} {
    .t delete 1.0 end
    .t configure -wrap none
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i Line $i\n"
    }
    .t tag add hidden 5.0 8.0
    .t tag configure hidden -elide true
    .t mark set insert 9.0
    updateText
    .t mark set insert 8.0        ; # up one line
    updateText
    set res [list $tk_textRedraw]
    .t mark set insert 12.2       ; # in the visible text
    updateText
    lappend res $tk_textRedraw
    .t mark set insert 6.5        ; # in the hidden text
    updateText
    lappend res $tk_textRedraw
    .t mark set insert 3.5        ; # in the visible text again
    updateText
    lappend res $tk_textRedraw
    .t mark set insert 3.8        ; # within the same line
    updateText
    lappend res $tk_textRedraw
} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {3.0 4.0}}
test textDisp-8.13 {TkTextChanged, used to crash, see [06c1433906]} {
    .t delete 1.0 end
    .t insert 1.0 \nLine2\nLine3\n
    updateText
    .t insert 3.0 ""
    .t delete 1.0 2.0
    update idletasks
} {}

test textDisp-9.1 {TkTextRedrawTag} failsOnUbuntu {


    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.4
    updateText
    list $tk_textRelayout $tk_textRedraw


} {{2.0 2.18} {2.0 2.18}}
test textDisp-9.2 {TkTextRedrawTag} {textfonts} {


    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 1.2 2.4
    updateText
    list $tk_textRelayout $tk_textRedraw


} {{1.0 2.0 2.17} {1.0 2.0 2.17}}
test textDisp-9.3 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.4
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.4 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.20
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.5 {TkTextRedrawTag} {failsOnUbuntu failsOnXQuarz} {


    .t configure -wrap char

    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    .t tag add big 2.2 2.end
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw



} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap"
    updateText
    .t tag add big 2.2 3.5
    updateText
    .t tag remove big 1.0 end
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 3.0 3.20} {2.0 2.20 3.0 3.20 eof}}
test textDisp-9.7 {TkTextRedrawTag} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    updateText
    .t tag remove big 2.19
    updateText
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-9.8 {TkTextRedrawTag} {textfonts} {


    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    .t tag add big 2.0 2.5
    updateText
    set tk_textRedraw


} {2.0 2.17}
test textDisp-9.9 {TkTextRedrawTag} {textfonts} {


    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    .t tag add big 1.5 2.5
    updateText
    set tk_textRedraw


} {2.0 2.17}
test textDisp-9.10 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText
    set tk_textRedraw none
    .t tag add big 1.3 1.5
    updateText
    set tk_textRedraw
} none
test textDisp-9.11 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    updateText

    .t tag add big 1.0 2.0
    updateText
    set tk_textRedraw



} {}
test textDisp-9.12 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 5} {incr i} {
      .t insert end "Line $i+++Line $i\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 2.6 3.6
    updateText
    .t tag add hidden 3.11 4.6
    updateText
    list $tk_textRelayout $tk_textRedraw
} {2.0 {2.0 eof}}
test textDisp-9.13 {TkTextRedrawTag} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - This is Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 2.8 2.17
    .t tag add hidden 6.8 7.17
    .t tag configure hidden -background red
    .t tag configure hidden -elide true
    updateText
    .t tag configure hidden -elide false
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{2.0 6.0 7.0} {2.0 6.0 7.0}}
test textDisp-9.14 {TkTextRedrawTag} {
    pack [text .tnocrash]
    for {set i 1} {$i < 6} {incr i} {
        .tnocrash insert end \nfoo$i
    }
    .tnocrash tag configure mytag1 -relief raised
    .tnocrash tag configure mytag2 -relief solid
    updateText
    proc doit {} {
        .tnocrash tag add mytag1 4.0 5.0
        .tnocrash tag add mytag2 4.0 5.0
        after idle {
            .tnocrash tag remove mytag1 1.0 end
            .tnocrash tag remove mytag2 1.0 end
        }







|








|
|


>
>
|




>
|
|
>
|
>
>
>
>
>
|








|
|
|






|
|



|
|



|
|



|

|








|
>
>
>

>
|


|

|


|

|
>
>
>
>
|


|


|


|

|
>
>
>
>
|


|


|

|
>
>
>

|



|

>
>
>
|
|
|



|



|

>
>
>
|
|










|





|



|


|
<
|
>
>



|
<
<
<
<








|





|

|


|


|



|

|


|



|


|
>




|

|

>
>
|




|

|

|






|

|

|

|










|

|


|


|

|

>
|
>
>
>



|

|





|

|

>
|
>
>
>
|




|

|


|
>
>
>
|




|

|

|
>
|




|


|

|
>
|






|

|

|
>
|





|

|


|





|


|
>
|





|


>
>
|
|













|


|
>
>
>





<





|




|





|

|








|

|









|


|









|


|


|
>








|

|



|
>






>
|



|


|

|




|

|






|




|







|




|


|















|

|




<
<
<
<






|
>


|

|


|
>


|

|

|
|
>


|

|

|
|
>
|


|

|


|
>



|

|


|
>



|

|


|
>



|

|


|
>





|

|




|






|

|

|







|

|








|

|








|

|








|

|








|

|


|





|

|








|

|


|





|

|


|




|

|






|




|

|












|

|


|


|


|


|

|



|





|
>
>



|

|
|
>
>
|
|
>
>



|

|

>
>
|
|



|

|

|


|



|

|

|


|
>
>
|
>


|

|

|

>
>
>
|
|



|

|

|


|




|

|


|
>
>




|

|

>
>
|
|
>
>




|

|

>
>
|
|




|
|

|

|
|




|
>

|

>
>
>
|








|

|












|

|









|







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763




764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    set i [.t dlineinfo 2.end]
    set b3 [expr {[lindex $i 1] + [lindex $i 4] - $b3}]
    set i [.t dlineinfo 3.0]
    set b4 [expr {[lindex $i 1] + [lindex $i 4] - $b4}]
    list $b1 $b2 $b3 $b4
} [list 1 5 13 16]
.t configure -spacing1 0 -spacing2 0 -spacing3 0
test textDisp-2.24 {LayoutDLine, tabs, saving from first chunk} {
    .t delete 1.0 end
    .t tag delete x y
    .t tag configure x -tabs 70
    .t tag configure y -tabs 80
    .t insert 1.0 "ab\tcde"
    .t tag add x 1.0 end
    .t tag add y 1.1 end
    lindex [.t bbox 1.3] 0
} [expr {[bo]+70}]
test textDisp-2.25 {LayoutDLine, tabs, breaking chunks at tabs} {
    .t delete 1.0 end
    .t tag delete x
    # compute a tab width allowing to let 4 tab stops (followed by a single char) on a single line
    set tw [expr {([winfo width .t]-2*[bo]-$fixedWidth)/4}]
    .t tag configure x -tabs [list $tw [expr {$tw*2}] [expr {$tw*3}] [expr {$tw*4}]]
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
    .t tag add x 1.0 end
    set expected [list [expr {[bo]+$tw}] [expr {[bo]+2*$tw}] [expr {[bo]+3*$tw}] [expr {[bo]+4*$tw}]]
    set res [list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	          [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]]
    lequal $res $expected
} {1}
# Next test is currently constrained to not run on mac (aqua) because on
# aqua it fails due to wrong implementation of tabs with right justification
# (the text is not rendered at all). This is a bug.
# Moreover, this test does not pass on any platform at this point with the revised
# implementation (see [a34b49f8c6]), therefore the 'knownBug' constraint.
test textDisp-2.26 {LayoutDLine, tabs, breaking chunks at tabs} {knownBug} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60 90 120] -justify right
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	     [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]
} [list [xcharr 4] [xcharr 3] [xcharr 2] [xcharr 1]]
test textDisp-2.27 {LayoutDLine, tabs, calling AdjustForTab} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60]
    .t insert 1.0 "a\tb\tcd"
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0]
} [list [expr {[bo]+30}] [expr {[bo]+60}]]
test textDisp-2.28 {LayoutDLine, tabs, running out of space in dline} {
    .t delete 1.0 end
    .t insert 1.0 "a\tb\tc\td"
    .t bbox 1.6
} [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]
test textDisp-2.29 {LayoutDLine, tabs, running out of space in dline} {
    .t delete 1.0 end
    .t insert 1.0 "a\tx\tabcd"
    .t bbox 1.4
} [list [xchar [expr {2*8}]] [yline 1] $fixedWidth $fixedHeight]
test textDisp-2.30 {LayoutDLine, tabs, running out of space in dline} {
    .t delete 1.0 end
    .t insert 1.0 "a\tx\tabc"
    .t bbox 1.4
} [list [xchar [expr {2*8}]] [yline 1] $fixedWidth $fixedHeight]

test textDisp-3.1 {different character sizes} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert end "Some sample text, including both large\n"
    .t insert end "characters and\nsmall\n"
    .t insert end "abc\nd\ne\nfghij"
    .t tag add big 1.5 1.10
    .t tag add big 2.11 2.14
    list [.t bbox 1.1] [.t bbox 1.6] [.t dlineinfo 1.0] [.t dlineinfo 3.0]
} [list [list [xchar 1] [expr {[yline 1]+$ascentDiff}] $fixedWidth $fixedHeight] \
        [list [expr {[xchar 5]+[font measure $bigFont s]}] [yline 1] [font measure $bigFont a] $bigHeight] \
	[list [bo] [yline 1] [expr {[xw 5]+[font measure $bigFont sampl]+[xw 2]}] $bigHeight $bigAscent] \
	[list [bo] [expr {[bo]+2*$bigHeight+2*$fixedHeight}] [xw 5] $fixedHeight $fixedAscent]]
.t configure -wrap char

test textDisp-4.1 {UpdateDisplayInfo, basic} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2\nLine 3\n"
    update
    .t delete 2.0 2.end
    update
    set res $tk_textRelayout
    .t insert 2.0 "New Line 2"
    update
    lappend res [.t bbox 1.0] [.t bbox 2.0] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 \
        [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
	2.0]
test textDisp-4.2 {UpdateDisplayInfo, re-use tail of text line} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    .t mark set x 2.21
    .t delete 2.2
    update
    set res $tk_textRelayout
    .t insert 2.0 X
    update
    lappend res [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list 2.0 2.20 \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 1] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 4] $fixedWidth $fixedHeight] \
	{2.0 2.20}]
test textDisp-4.3 {UpdateDisplayInfo, tail of text line shifts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    .t mark set x 2.21
    .t delete 2.2
    update
    list [.t bbox 2.0] [.t bbox x] [.t bbox 3.0] $tk_textRelayout
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 4] $fixedWidth $fixedHeight] \
	{2.0 2.20}]
.t mark unset x
test textDisp-4.4 {UpdateDisplayInfo, wrap-mode "none"} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    list [.t bbox 2.0] [.t bbox 2.25] [.t bbox 3.0] $tk_textRelayout
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        {} \
	[list [xchar 0] [yline 3] $fixedWidth  $fixedHeight] \
	{1.0 2.0 3.0}]
test textDisp-4.5 {UpdateDisplayInfo, tiny window} {
    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    wm geom . 103x$height
    update
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    list [.t bbox 2.0] [.t bbox 2.1] [.t bbox 3.0] $tk_textRelayout
} [list [list [xchar 0] [yline 2] 1 $fixedHeight] \
        {} \
	[list [xchar 0] [yline 3] 1 $fixedHeight] \
	{1.0 2.0 3.0}]
if {[tk windowingsystem] eq "win32"} {
    wm overrideredirect . 0
}
test textDisp-4.6 {UpdateDisplayInfo, tiny window} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    frame .f2 -width 20 -height 100
    pack .f2 -before .f
    wm geom . 103x103
    update
    .t configure -wrap none -borderwidth 2
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    set x [list [.t bbox 1.0] [.t bbox 2.0] $tk_textRelayout]
    wm overrideredirect . 0
    update

    set expected [list [list [xchar 0] [yline 1] 1 1] {} 1.0]
    lequal $x $expected
} {1}
catch {destroy .f2}
.t configure -borderwidth 0 -wrap char
wm geom . {}
update




test textDisp-4.7 {UpdateDisplayInfo, filling in extra vertical space} {
    # This test was failing on Windows because the title bar on .
    # was a certain minimum size and it was interfering with the size
    # requested.  The "overrideredirect" gets rid of the titlebar so
    # the toplevel can shrink to the appropriate size.  On Unix, setting
    # the overrideredirect on "." confuses the window manager and
    # causes subsequent tests to fail.

    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 1.0
    update
    .t yview 16.0
    update
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
    wm overrideredirect . 0
    update
    set x
} {8.0 {16.0 17.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0} {8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0}}
test textDisp-4.8 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    update
    .t delete 5.0 14.0
    update
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
} {1.0 {5.0 4.0 3.0 2.0 1.0} {1.0 2.0 3.0 4.0 5.0 eof}}
test textDisp-4.9 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview 16.0
    update
    .t delete 15.0 end
    list [.t bbox 7.0] [.t bbox 12.0]
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 7] $fixedWidth $fixedHeight]]
test textDisp-4.10 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    update
    .t delete 13.0 end
    update
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
    # Note, the results of old text widget implementation are wrong, because it is
    # not deleting the last line, this is a bug, so the results have been changed.
} {6.0 {13.0 7.0 6.40 6.20 6.0} {6.0 6.20 6.40 7.0 13.0}}
test textDisp-4.11 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around, not once but really quite a few times.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17"
    .t yview end
    update
    .t delete 14.0 end
    update
    list [.t index @0,0] $tk_textRelayout $tk_textRedraw
} {6.60 {14.0 7.0 6.80 6.60} {6.60 6.80 7.0 14.0}}
test textDisp-4.12 {UpdateDisplayInfo, filling in extra vertical space} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16"
    button .b -text "Test" -bd 2 -highlightthickness 2
    .t window create 3.end -window .b
    .t yview moveto 1
    update
    .t yview moveto 0
    update
    .t yview moveto 1
    update
    winfo ismapped .b
} {0}
.t configure -wrap word
.t delete 1.0 end
.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"
.t insert end "Line 8\nLine 9\nLine 10\nLine 11\nLine 12\nLine 13\n"
.t insert end "Line 14\nLine 15\nLine 16"
.t tag delete x
.t tag configure x -relief raised -borderwidth 2 -background white
test textDisp-4.13 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 1.0
    update
    .t yview scroll 3 units
    update
    list $tk_textRelayout $tk_textRedraw
} {{11.0 12.0 13.0} {4.0 10.0 11.0 12.0 13.0}}
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 1.0
    update
    .t yview scroll 3 units
    update
    list $tk_textRelayout $tk_textRedraw
    # NOTE: old implementation gives the following result:
    #     {11.0 12.0 13.0} {11.0 12.0 13.0}
    # but revised implementation has a sophisticated line caching, so
    # the new result is empty.
} {{} {}}
test textDisp-4.15 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag add x 1.0 end
    .t yview 4.0
    update
    .t yview scroll -2 units
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0 4.0 11.0}}
test textDisp-4.16 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 4.0
    update
    .t yview scroll -2 units
    update
    list $tk_textRelayout $tk_textRedraw
    # NOTE: old implementation gives the following result:
    #     {2.0 3.0} {2.0 3.0}
    # but revised implementation has a sophisticated line caching, so
    # the new result is empty.
} {{} {}}
test textDisp-4.17 {UpdateDisplayInfo, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    update
    .t xview scroll 3 units
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.0] [.t bbox 2.5] \
	    [.t bbox 2.23]
} [list {} {1.0 2.0 3.0 4.0} \
        {} \
        [list [expr {[xchar 5]-[xw 3]}] [yline 2] $fixedWidth $fixedHeight] \
	{}]
test textDisp-4.18 {UpdateDisplayInfo, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    update
    .t xview scroll 100 units
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list {} {1.0 2.0 3.0 4.0} \
        [list [xcharr 19] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-4.19 {UpdateDisplayInfo, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    update
    .t xview moveto 0
    .t xview scroll -10 units
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.5]
} [list {} {1.0 2.0 3.0 4.0} \
	[list [xchar 5] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-4.20 {UpdateDisplayInfo, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto 0.0
    .t xview scroll 100 units
    update
    .t delete 2.30 2.44
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.25]
} [list 2.0 {1.0 2.0 3.0 4.0} \
        [list [xcharr 5] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-4.21 {UpdateDisplayInfo, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview moveto .9
    update
    .t xview moveto .6
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {}}
test textDisp-4.22 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    update
    .t configure -wrap word
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 1] [yline 3] $fixedWidth $fixedHeight]]
test textDisp-4.23 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "Short line 1\nLine 2 is long enough to scroll horizontally"
    .t insert end "\nLine 3\nLine 4"
    .t xview scroll 25 units
    update
    .t configure -wrap char
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 16] [yline 2] $fixedWidth $fixedHeight]]

test textDisp-5.1 {DisplayDLine, handling of spacing} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijkl\nmnopqrstuvwzyz"
    .t tag configure spacing -spacing1 8 -spacing3 2
    .t tag add spacing 1.0 end
    frame .t.f1 -width 10 -height 4 -bg black
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    update
    list [winfo geometry .t.f1] [winfo geometry .t.f2] \
	    [winfo geometry .t.f3] [winfo geometry .t.f4]
} [list 10x4+[xchar 3]+[expr {[yline 1]+8}] \
        10x4+[expr {[xchar 6]+10}]+[expr {[yline 1]+8+($fixedHeight-4)/2}] \
	10x4+[xchar 1]+[expr {[yline 2]+8+2+8+($fixedHeight-4)}] \
	10x4+[expr {[xchar 9]+10}]+[expr {[yline 2]+8+2+8+($fixedAscent-4)}]]
.t tag delete spacing

# Although the following test produces a useful result, its main
# effect is to produce a core dump if Tk doesn't handle display
# relayout that occurs during redisplay.

test textDisp-5.2 {DisplayDLine, line resizes during display} {
    .t delete 1.0 end
    frame .t.f -width 20 -height 20 -bd 2 -relief raised
    bind .t.f <Configure> {.t.f configure -width 30 -height 30}
    .t window create insert -window .t.f
    update
    list [winfo width .t.f] [winfo height .t.f]
} [list 30 30]

.t configure -wrap char
test textDisp-6.1 {scrolling in DisplayText, scroll up} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.0 3.0
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 10.0} {2.0 10.0}}
test textDisp-6.2 {scrolling in DisplayText, scroll down} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.0 "New Line 2\n"
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-6.3 {scrolling in DisplayText, multiple scrolls} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.end "is so long that it wraps"
    .t insert 4.end "is so long that it wraps"
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 4.0 4.20} {2.0 2.20 4.0 4.20}}
test textDisp-6.4 {scrolling in DisplayText, scrolls interfere} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.end "is so long that it wraps around, not once but three times"
    .t insert 4.end "is so long that it wraps"
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 2.40 2.60 4.0 4.20} {2.0 2.20 2.40 2.60 4.0 4.20 6.0}}
test textDisp-6.5 {scrolling in DisplayText, scroll source obscured} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    .t configure -wrap char
    frame .f2 -bg red
    place .f2 -in .t -relx 0.5 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.6 1.end
    update
    destroy .f2
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 4.0 5.0 9.0 10.0}}
test textDisp-6.6 {scrolling in DisplayText, Expose events after scroll} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    # this test depends on all of the expose events being handled at once
    .t configure -wrap char
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -rely 0.5 -relwidth 0.5 -relheight 0.5
    .t configure -bd 2 -relief raised
    .t delete 1.0 end
    # Line 1 must wrap exactly twice to get the expected result
    .t insert 1.0 "Line 1 is so long that it occupies 3 display lines"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.6 1.end
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0}}
.t configure -bd 0
test textDisp-6.7 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    update
    .t count -update -ypixels 1.0 end
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-6.8 {DisplayText, vertical scrollbar updates} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    update
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    update
    .t count -update -ypixels 1.0 end ; update
    set scrollInfo
} [list 0.0 [expr {10.0/13}]]
.t configure -yscrollcommand {} -xscrollcommand scroll
test textDisp-6.9 {DisplayText, horizontal scrollbar updates} {
    .t configure -wrap none
    .t delete 1.0 end
    update
    set scrollInfo unchanged
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-6.10 {DisplayText, redisplay embedded windows after scroll} {aqua} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4} {
	.t insert end "\nLine $i"
    }
    .t insert end "\n"
    .t window create end -create {
	button %W.button_one -text "Button 1"}
    .t insert end "\nLine 6\n"
    .t window create end -create {
	button %W.button_two -text "Button 2"}
    .t insert end "\nLine 8\n"
    .t window create end -create {
	button %W.button_three -text "Button 3"}
    update
    .t delete 2.0 3.0
    update
    list $tk_textEmbWinDisplay
} {{4.0 6.0}}






.t configure -bd 2 -relief raised -wrap char
.t delete 1.0 end
.t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
    .t insert end "\nLine $i"
}
test textDisp-7.1 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -relwidth 0.6 -rely 0.22 -relheight 0.55
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {1.40 2.0 3.0 4.0 5.0 6.0}}
test textDisp-7.2 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.5 -rely 0 -relheight 0.5
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {1.0 1.20 1.40 2.0 3.0}}
test textDisp-7.3 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.5 -relwidth 0.5 -rely 0.5 -relheight 0.5
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {4.0 5.0 6.0 7.0 8.0}}
test textDisp-7.4 {TkTextRedrawRegion} {aquaKnownBug} {
 # constrained by aquaKnownBug until ticket [aad0231f07] is fixed
   frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 0 -relheight 0.2 \
	    -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20}}
test textDisp-7.5 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 1.0 -relheight 0.2 \
	    -anchor s -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 7.0 8.0}}
test textDisp-7.6 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor w -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.7 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 1.0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor e -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.8 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\n"
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.0 -relwidth 0.4 -rely 0.35 -relheight 0.4 \
	    -anchor nw -bordermode ignore
    update
    destroy .f2
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 4.0 5.0 6.0 7.0 eof}}
.t configure -bd 0

test textDisp-8.1 {TkTextChanged: redisplay whole lines} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around, two times"
    foreach i {3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.36 2.38
    update
    list $tk_textRelayout $tk_textRedraw [.t bbox 2.32]
} [list {2.0 2.18 2.38} {2.0 2.18 2.38} [list [xchar 14] [yline 3] $fixedWidth $fixedHeight]]
.t configure -wrap char
test textDisp-8.2 {TkTextChanged, redisplay whole lines} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 1.2 xx
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.3 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t insert 2.0 xx
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.4 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.5
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.5 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.40 1.44
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.6 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.41 1.44
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.7 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 1.2 1.end
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 9.0 10.0} {1.0 9.0 10.0}}
test textDisp-8.8 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.2
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.9 {TkTextChanged} {
    .t delete 1.0 end
    .t insert 1.0 "Line 1 is so long that it wraps around, two times"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    update
    .t delete 2.0 3.0
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 8.0} {2.0 8.0}}
test textDisp-8.10 {TkTextChanged} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    update
    .t delete 2.19
    update
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-8.11 {TkTextChanged, scrollbar notification when changes are off-screen} {
    .t delete 1.0 end
    .t insert end "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n"
    .t configure -yscrollcommand scroll
    update
    set scrollInfo ""
    .t insert end "a\nb\nc\n"
    # We need to wait for our asychronous callbacks to update the
    # scrollbar
    update
    .t count -update -ypixels 1.0 end
    update
    .t configure -yscrollcommand ""
    set scrollInfo
} {0.0 0.625}
test textDisp-8.12 {TkTextChanged, moving the insert cursor redraws only past and new lines} {
    .t delete 1.0 end
    .t configure -wrap none
    for {set i 1} {$i < 25} {incr i} {
        .t insert end "Line $i Line $i\n"
    }
    .t tag add hidden 5.0 8.0
    .t tag configure hidden -elide true
    .t mark set insert 9.0
    update
    .t mark set insert 8.0        ; # up one line
    update
    set res [list $tk_textRedraw]
    .t mark set insert 12.2       ; # in the visible text
    update
    lappend res $tk_textRedraw
    .t mark set insert 6.5        ; # in the hidden text
    update
    lappend res $tk_textRedraw
    .t mark set insert 3.5        ; # in the visible text again
    update
    lappend res $tk_textRedraw
    .t mark set insert 3.8        ; # within the same line
    update
    lappend res $tk_textRedraw
} {{5.0 9.0} {5.0 12.0} {5.0 12.0} {3.0 5.0} 3.0}
test textDisp-8.13 {TkTextChanged, used to crash, see [06c1433906]} {
    .t delete 1.0 end
    .t insert 1.0 \nLine2\nLine3\n
    update
    .t insert 3.0 ""
    .t delete 1.0 2.0
    update idletasks
} {}

test textDisp-9.1 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.4
    update
   list $tk_textRelayout $tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} -match glob -result {{2.0 2.1[78]} {2.0 2.1[78]}}
test textDisp-9.2 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 1.2 2.4
    update
    list $tk_textRelayout $tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} -match glob -result {{1.0 2.0 2.1[678]} {1.0 2.0 2.1[678]}}
test textDisp-9.3 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.4
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.4 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.20
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.5 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -setup {
    .t configure -wrap char -height [expr {[.t cget -height]+10}]
} -body {
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    update
    .t tag add big 2.2 2.end
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} -cleanup {
    .t configure -height [expr {[.t cget -height]-10}]
    update
} -result {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap"
    update
    .t tag add big 2.2 3.5
    update
    .t tag remove big 1.0 end
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20 3.0 3.20} {2.0 2.20 3.0 3.20 eof}}
test textDisp-9.7 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 2.19
    update
    .t tag remove big 2.19
    update
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-9.8 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    .t tag add big 2.0 2.5
    update
    set tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} -match glob -result {2.0 2.1[678]}
test textDisp-9.9 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    .t tag add big 1.5 2.5
    update
    set tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} -match glob -result {2.0 2.1[678]}
test textDisp-9.10 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    set tk_textRedraw {none}
    .t tag add big 1.3 1.5
    update
    set tk_textRedraw
} {none}
test textDisp-9.11 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    .t tag add big 1.0 2.0
    update
    set tk_textRedraw {none}
    .t tag add big 1.0 2.0
    update
    set tk_textRedraw
    # The implementation is recognizing that the prior "tag add"
    # operation is not changing anything, so it won't do any redraw,
    # thus the result is "none".
} {none}
test textDisp-9.12 {TkTextRedrawTag} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 5} {incr i} {
      .t insert end "Line $i+++Line $i\n"
    }
    .t tag configure hidden -elide true
    .t tag add hidden 2.6 3.6
    update
    .t tag add hidden 3.11 4.6
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 {2.0 eof}}
test textDisp-9.13 {TkTextRedrawTag} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - This is Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 2.8 2.17
    .t tag add hidden 6.8 7.17
    .t tag configure hidden -background red
    .t tag configure hidden -elide true
    update
    .t tag configure hidden -elide false
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 6.0 7.0} {2.0 6.0 7.0}}
test textDisp-9.14 {TkTextRedrawTag} {
    pack [text .tnocrash]
    for {set i 1} {$i < 6} {incr i} {
        .tnocrash insert end \nfoo$i
    }
    .tnocrash tag configure mytag1 -relief raised
    .tnocrash tag configure mytag2 -relief solid
    update
    proc doit {} {
        .tnocrash tag add mytag1 4.0 5.0
        .tnocrash tag add mytag2 4.0 5.0
        after idle {
            .tnocrash tag remove mytag1 1.0 end
            .tnocrash tag remove mytag2 1.0 end
        }
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531

1532



1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
    vwait done
} {}

test textDisp-10.1 {TkTextRelayoutWindow} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    updateText
    .t configure -bg black
    updateText
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.20 3.0 3.20 4.0} {borders 1.0 2.0 2.20 3.0 3.20 4.0 eof}}
.t configure -bg [lindex [.t configure -bg] 3]
catch {destroy .top}
test textDisp-10.2 {TkTextRelayoutWindow} {
    toplevel .top -width 300 -height 200
    wm geometry .top +0+0
    text .top.t -font $fixedFont -width 20 -height 10 -relief raised -bd 2
    place .top.t -x 0 -y 0 -width 20 -height 20
    .top.t insert end "First line"
    .top.t see insert
    tkwait visibility .top.t
    place .top.t -width 150 -height 100
    updateText
    .top.t index @0,0
} {1.0}
catch {destroy .top}

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
updateText
test textDisp-11.1 {TkTextSetYView} {
    .t yview 30.0
    updateText
    .t index @0,0
} {30.0}
test textDisp-11.2 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    .t yview 32.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.3 {TkTextSetYView} {
    .t yview 30.0
    updateText
    .t yview 28.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.4 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    .t yview 31.4
    updateText
    list [.t index @0,0] $tk_textRedraw
} {31.0 40.0}
test textDisp-11.5 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 31.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {30.0 {}}
test textDisp-11.6 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 28.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.7 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 26.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {21.0 {21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0}}
test textDisp-11.8 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 41.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.9 {TkTextSetYView} failsOnXQuarz {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview -pickplace 43.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {38.0 {40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0}}
test textDisp-11.10 {TkTextSetYView} {
    .t yview 30.0
    updateText
    set tk_textRedraw {}
    .t yview 10000.0
    updateText
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0 197.0 198.0 199.0 200.0}}
test textDisp-11.11 {TkTextSetYView} {
    .t yview 195.0
    updateText
    set tk_textRedraw {}
    .t yview 197.0
    updateText
    list [.t index @0,0] $tk_textRedraw

} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0}}



test textDisp-11.12 {TkTextSetYView, wrapped line is off-screen} failsOnXQuarz {
    .t insert 10.0 "Long line with enough text to wrap\n"
    .t yview 1.0
    updateText
    set tk_textRedraw {}
    .t see 10.30
    updateText
    list [.t index @0,0] $tk_textRedraw
} {2.0 10.20}
.t delete 10.0 11.0
test textDisp-11.13 {TkTestSetYView, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 20 -height 5
    pack .top.t
    .top.t insert end "Line 1"
    for {set i 2} {$i <= 100} {incr i} {
	.top.t insert end "\nLine $i"
    }
    updateText
    scan [wm geometry .top] "%dx%d" w2 h2
    wm geometry .top ${w2}x[expr {$h2-2}]
    updateText
    .top.t yview 1.0
    updateText
    set tk_textRedraw {}
    .top.t see 5.0
    updateText
    # Note, with smooth scrolling, the results of this test
    # have changed, and the old '2.0 {5.0 6.0}' is quite wrong.
    list [.top.t index @0,0] $tk_textRedraw
} {1.0 5.0}
catch {destroy .top}
toplevel .top
wm geometry .top +0+0
text .top.t -width 30 -height 3
pack .top.t
.top.t insert end "Line 1"
for {set i 2} {$i <= 20} {incr i} {
    .top.t insert end "\nLine $i"
}
updateText
test textDisp-11.14 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    updateText
    .top.t see 10.0
    .top.t index @0,0
} {8.0}
test textDisp-11.15 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    updateText
    .top.t see 11.0
    .top.t index @0,0
    # The index 9.0 should be just visible by a couple of pixels
} {9.0}
test textDisp-11.16 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    updateText
    .top.t see 5.0
    .top.t index @0,0
} {5.0}
test textDisp-11.17 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    updateText
    .top.t see 4.0
    .top.t index @0,0
    # The index 2.0 should be just visible by a couple of pixels
} {2.0}
test textDisp-11.18 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 20} {incr i} {
        .top.t insert end [string repeat "Line $i" 10]
        .top.t insert end "\n"
    }
    .top.t yview 4.0
    .top.t tag add hidden 4.10 "4.10 lineend"
    .top.t tag add hidden 5.15 10.3
    .top.t tag configure hidden -elide true
    updateText
    .top.t see "8.0 lineend"
    # The index "8.0 lineend" is on screen despite elided -> no scroll
    .top.t index @0,0
} {4.0}
test textDisp-11.19 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 50} {incr i} {
        .top.t insert end "Line $i\n"
    }
    # button just for having a line with a larger height
    button .top.t.b -text "Test" -bd 2 -highlightthickness 2
    .top.t window create 21.0 -window .top.t.b
    .top.t tag add hidden 15.36 21.0
    .top.t tag configure hidden -elide true
    .top.t configure -height 15
    wm geometry .top 300x200+0+0
    # Indices 21.0, 17.0 and 15.0 are all on the same display line
    # therefore index @0,0 shall be the same for all of them
    .top.t see end
    updateText
    .top.t see 21.0
    updateText
    set ind1 [.top.t index @0,0]
    .top.t see end
    updateText
    .top.t see 17.0
    updateText
    set ind2 [.top.t index @0,0]
    .top.t see end
    updateText
    .top.t see 15.0
    updateText
    set ind3 [.top.t index @0,0]
    list [expr {$ind1 == $ind2}] [expr {$ind1 == $ind3}]
} {1 1}
test textDisp-11.20 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    .top.t configure -wrap none
    for {set i 1} {$i < 5} {incr i} {







|

|













|









|


|


|

|

|




|

|


|

|

|




|


|




|


|




|


|


|

|


|


|

|


|




|


|




|


|

>
|
>
>
>
|


|


|













|


|

|


|













|


|





|






|





|














|



















|

|


|

|


|

|







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
    vwait done
} {}

test textDisp-10.1 {TkTextRelayoutWindow} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap\nLine 3 is also long enough to wrap\nLine 4"
    update
    .t configure -bg black
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 2.0 2.20 3.0 3.20 4.0} {borders 1.0 2.0 2.20 3.0 3.20 4.0 eof}}
.t configure -bg [lindex [.t configure -bg] 3]
catch {destroy .top}
test textDisp-10.2 {TkTextRelayoutWindow} {
    toplevel .top -width 300 -height 200
    wm geometry .top +0+0
    text .top.t -font $fixedFont -width 20 -height 10 -relief raised -bd 2
    place .top.t -x 0 -y 0 -width 20 -height 20
    .top.t insert end "First line"
    .top.t see insert
    tkwait visibility .top.t
    place .top.t -width 150 -height 100
    update
    .top.t index @0,0
} {1.0}
catch {destroy .top}

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
update
test textDisp-11.1 {TkTextSetYView} {
    .t yview 30.0
    update
    .t index @0,0
} {30.0}
test textDisp-11.2 {TkTextSetYView} {
    .t yview 30.0
    update
    .t yview 32.0
    update
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.3 {TkTextSetYView} {
    .t yview 30.0
    update
    .t yview 28.0
    update
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.4 {TkTextSetYView} {
    .t yview 30.0
    update
    .t yview 31.4
    update
    list [.t index @0,0] $tk_textRedraw
} {31.0 40.0}
test textDisp-11.5 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 31.0
    update
    list [.t index @0,0] $tk_textRedraw
} {30.0 {}}
test textDisp-11.6 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 28.0
    update
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.7 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 26.0
    update
    list [.t index @0,0] $tk_textRedraw
} {21.0 {21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 29.0}}
test textDisp-11.8 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 41.0
    update
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.9 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview -pickplace 43.0
    update
    list [.t index @0,0] $tk_textRedraw
} {38.0 {40.0 41.0 42.0 43.0 44.0 45.0 46.0 47.0 48.0}}
test textDisp-11.10 {TkTextSetYView} {
    .t yview 30.0
    update
    set tk_textRedraw {}
    .t yview 10000.0
    update
    list [.t index @0,0] $tk_textRedraw
} {191.0 {191.0 192.0 193.0 194.0 195.0 196.0 197.0 198.0 199.0 200.0}}
test textDisp-11.11 {TkTextSetYView} {
    .t yview 195.0
    update
    set tk_textRedraw {}
    .t yview 197.0
    update
    list [.t index @0,0] $tk_textRedraw
# Due to a more intelligent layout algorithm the old result for $tk_textRedraw
#	{191.0 192.0 193.0 194.0 195.0 196.0}
# isn't valid anymore, the new result is an empty list. Now this test case is
# a proof that the 'intelligence' of the new layout algorithm is working.
} {191.0 {}}
test textDisp-11.12 {TkTextSetYView, wrapped line is off-screen} {
    .t insert 10.0 "Long line with enough text to wrap\n"
    .t yview 1.0
    update
    set tk_textRedraw {}
    .t see 10.30
    update
    list [.t index @0,0] $tk_textRedraw
} {2.0 10.20}
.t delete 10.0 11.0
test textDisp-11.13 {TkTestSetYView, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 20 -height 5
    pack .top.t
    .top.t insert end "Line 1"
    for {set i 2} {$i <= 100} {incr i} {
	.top.t insert end "\nLine $i"
    }
    update
    scan [wm geometry .top] "%dx%d" w2 h2
    wm geometry .top ${w2}x[expr {$h2-2}]
    update
    .top.t yview 1.0
    update
    set tk_textRedraw {}
    .top.t see 5.0
    update
    # Note, with smooth scrolling, the results of this test
    # have changed, and the old '2.0 {5.0 6.0}' is quite wrong.
    list [.top.t index @0,0] $tk_textRedraw
} {1.0 5.0}
catch {destroy .top}
toplevel .top
wm geometry .top +0+0
text .top.t -width 30 -height 3
pack .top.t
.top.t insert end "Line 1"
for {set i 2} {$i <= 20} {incr i} {
    .top.t insert end "\nLine $i"
}
update
test textDisp-11.14 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    update
    .top.t see 10.0
    .top.t index @0,0
} {8.0}
test textDisp-11.15 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    update
    .top.t see 11.0
    .top.t index @0,0
    # The index 9.0 should be just visible by a couple of pixels
} {9.0}
test textDisp-11.16 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    update
    .top.t see 5.0
    .top.t index @0,0
} {5.0}
test textDisp-11.17 {TkTextSetYView, only a few lines visible} {
    .top.t yview 8.0
    update
    .top.t see 4.0
    .top.t index @0,0
    # The index 2.0 should be just visible by a couple of pixels
} {2.0}
test textDisp-11.18 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 20} {incr i} {
        .top.t insert end [string repeat "Line $i" 10]
        .top.t insert end "\n"
    }
    .top.t yview 4.0
    .top.t tag add hidden 4.10 "4.10 lineend"
    .top.t tag add hidden 5.15 10.3
    .top.t tag configure hidden -elide true
    update
    .top.t see "8.0 lineend"
    # The index "8.0 lineend" is on screen despite elided -> no scroll
    .top.t index @0,0
} {4.0}
test textDisp-11.19 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    for {set i 1} {$i < 50} {incr i} {
        .top.t insert end "Line $i\n"
    }
    # button just for having a line with a larger height
    button .top.t.b -text "Test" -bd 2 -highlightthickness 2
    .top.t window create 21.0 -window .top.t.b
    .top.t tag add hidden 15.36 21.0
    .top.t tag configure hidden -elide true
    .top.t configure -height 15
    wm geometry .top 300x200+0+0
    # Indices 21.0, 17.0 and 15.0 are all on the same display line
    # therefore index @0,0 shall be the same for all of them
    .top.t see end
    update
    .top.t see 21.0
    update
    set ind1 [.top.t index @0,0]
    .top.t see end
    update
    .top.t see 17.0
    update
    set ind2 [.top.t index @0,0]
    .top.t see end
    update
    .top.t see 15.0
    update
    set ind3 [.top.t index @0,0]
    list [expr {$ind1 == $ind2}] [expr {$ind1 == $ind3}]
} {1 1}
test textDisp-11.20 {TkTextSetYView, see in elided lines} {
    .top.t delete 1.0 end
    .top.t configure -wrap none
    for {set i 1} {$i < 5} {incr i} {
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670















1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
test textDisp-11.21 {TkTextSetYView, window height smaller than the line height} {
    .top.t delete 1.0 end
    for {set i 1} {$i <= 10} {incr i} {
        .top.t insert end "Line $i\n"
    }
    set lineheight [font metrics [.top.t cget -font] -linespace]
    wm geometry .top 200x[expr {$lineheight / 2}]
    updateText
    .top.t see 1.0
    .top.t index @0,[expr {$lineheight - 2}]
} {1.0}
















.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-12.1 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 52.0
    updateText
    .t index @0,0
} {49.0}
test textDisp-12.2 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 53.0
    updateText
    .t index @0,0
} {50.0}
test textDisp-12.3 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 50.10
    updateText
    .t index @0,0
} {45.0}
.t configure -wrap none
test textDisp-12.4 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 53.0
    updateText
    .t index @0,0
} {48.0}
test textDisp-12.5 {MeasureUp} {
    .t yview 100.0
    updateText
    .t yview -pickplace 50.10
    updateText
    .t index @0,0
} {45.0}

.t configure -wrap none
.t delete 1.0 end
for {set i 1} {$i < 99} {incr i} {
    .t insert end "Line $i\n"







|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|

|




|

|




|

|





|

|




|

|







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
test textDisp-11.21 {TkTextSetYView, window height smaller than the line height} {
    .top.t delete 1.0 end
    for {set i 1} {$i <= 10} {incr i} {
        .top.t insert end "Line $i\n"
    }
    set lineheight [font metrics [.top.t cget -font] -linespace]
    wm geometry .top 200x[expr {$lineheight / 2}]
    update
    .top.t see 1.0
    .top.t index @0,[expr {$lineheight - 2}]
} {1.0}
test textDisp-11.22 {TkTextSetYView, peer has -startline} {
    .top.t delete 1.0 end
    for {set i 1} {$i <= 50} {incr i} {
        .top.t insert end "Line $i\n"
    }
    pack [.top.t peer create .top.p] -side left
    pack [scrollbar .top.sb -command {.top.p yview}] -side left -fill y
    .top.p configure -startline 5 -endline 35 -yscrollcommand {.top.sb set}
    update
    .top.p yview moveto 0
    update
    set res [.top.p get @0,0 "@0,0 lineend"]
    destroy .top.p
    set res
} {Line 5}

.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-12.1 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 52.0
    update
    .t index @0,0
} {49.0}
test textDisp-12.2 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 53.0
    update
    .t index @0,0
} {50.0}
test textDisp-12.3 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 50.10
    update
    .t index @0,0
} {45.0}
.t configure -wrap none
test textDisp-12.4 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 53.0
    update
    .t index @0,0
} {48.0}
test textDisp-12.5 {MeasureUp} {
    .t yview 100.0
    update
    .t yview -pickplace 50.10
    update
    .t index @0,0
} {45.0}

.t configure -wrap none
.t delete 1.0 end
for {set i 1} {$i < 99} {incr i} {
    .t insert end "Line $i\n"
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769



1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784








1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
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
} {1 {wrong # args: should be ".t see index"}}
test textDisp-13.3 {TkTextSeeCmd procedure} {
    list [catch {.t see badIndex} msg] $msg
} {1 {bad text index "badIndex"}}
test textDisp-13.4 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    updateText
    .t see 4.2
    .t index @0,0
} {1.0}
test textDisp-13.5 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    updateText
    .t see 12.1
    .t index @0,0
} {3.0}
test textDisp-13.6 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    updateText
    .t see 30.50
    set x [.t index @0,0]
    .t configure -wrap none
    set x
} {27.0}
test textDisp-13.7 {TkTextSeeCmd procedure} {textfonts} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.40
    updateText
    .t see 30.50
    .t yview 25.0
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.39
    lappend x [.t bbox 30.39]
    .t see 30.38
    lappend x [.t bbox 30.38]
    .t see 30.20
    lappend x [.t bbox 30.20]
} [list [list 73 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 3 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 3 [expr {5*$fixedDiff + 68}] 7 $fixedHeight] [list 73 [expr {5*$fixedDiff + 68}] 7 $fixedHeight]]



test textDisp-13.8 {TkTextSeeCmd procedure} {textfonts} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    updateText
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
    lappend x [.t bbox 30.90]
} [list [list 73 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight] [list 73 [expr {9*$fixedDiff/2 + 64}] 7 $fixedHeight]]








test textDisp-13.9 {TkTextSeeCmd procedure} {textfonts} {
    wm geom . [expr {$width-2}]x$height
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    updateText
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
    lappend x [.t bbox 30.90]
} [list [list 74 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 138 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 138 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 74 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight]]








test textDisp-13.10 {TkTextSeeCmd procedure} {} {
    # SF Bug 641778
    set w .tsee
    destroy $w
    text $w -font {Helvetica 8 normal} -bd 16
    $w insert end Hello
    $w see end
    set res [$w bbox end]
    destroy $w
    set res
} {}
test textDisp-13.11 {TkTextSeeCmd procedure} {} {
    # insertion of a character at end of a line containing multi-byte
    # characters and calling see at the line end shall actually show
    # this character
    toplevel .top2
    pack [text .top2.t2 -wrap none]
    for {set i 1} {$i < 5} {incr i} {
        .top2.t2 insert end [string repeat "Line $i: éèàçù" 5]\n

    }
    wm geometry .top2 300x200+0+0
    updateText
    .top2.t2 see "1.0 lineend"
    updateText
    set ref [.top2.t2 index @0,0]
    .top2.t2 insert "1.0 lineend" ç
    .top2.t2 see "1.0 lineend"
    updateText
    set new [.top2.t2 index @0,0]
    set res [.top2.t2 compare $ref == $new]
    destroy .top2
    set res
} 0
wm geom . {}

.t configure -wrap none
test textDisp-14.1 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto .5
    .t xview
} [list 0.5 [expr {6./7.}]]
.t configure -wrap char
test textDisp-14.2 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
.t configure -wrap none
test textDisp-14.3 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    updateText
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
test textDisp-14.4 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto} msg] $msg
} {1 {wrong # args: should be ".t xview moveto fraction"}}
test textDisp-14.5 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto a b} msg] $msg
} {1 {wrong # args: should be ".t xview moveto fraction"}}
test textDisp-14.6 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto a} msg] $msg
} {1 {expected floating-point number but got "a"}}
test textDisp-14.7 {TkTextXviewCmd procedure} failsOnUbuntu {
    .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}]]
test textDisp-14.8 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto -.4
    .t xview
} [list 0.0 [expr {5.0/14}]]
test textDisp-14.9 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview m 1.4
    .t xview
} [list [expr {9.0/14}] 1.0]
test textDisp-14.10 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
test textDisp-14.11 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
test textDisp-14.12 {TkTextXviewCmd procedure} {







|







|







|





|




|










|
>
>
>
|




|








|
>
>
>
>
>
>
>
>
|





|








|
>
>
>
>
>
>
>
>
|


















|
<

|

|



|




|





|









|








|














|


|



|



|



|



|



|







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
} {1 {wrong # args: should be ".t see index"}}
test textDisp-13.3 {TkTextSeeCmd procedure} {
    list [catch {.t see badIndex} msg] $msg
} {1 {bad text index "badIndex"}}
test textDisp-13.4 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    update
    .t see 4.2
    .t index @0,0
} {1.0}
test textDisp-13.5 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    update
    .t see 12.1
    .t index @0,0
} {3.0}
test textDisp-13.6 {TkTextSeeCmd procedure} {
    .t configure -wrap char
    .t xview moveto 0
    .t yview moveto 0
    update
    .t see 30.50
    set x [.t index @0,0]
    .t configure -wrap none
    set x
} {27.0}
test textDisp-13.7 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.40
    update
    .t see 30.50
    .t yview 25.0
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.39
    lappend x [.t bbox 30.39]
    .t see 30.38
    lappend x [.t bbox 30.38]
    .t see 30.20
    lappend x [.t bbox 30.20]
} [list [list [xchar 10] [yline 6] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 6] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 6] $fixedWidth $fixedHeight] \
	[list [xchar 10] [yline 6] $fixedWidth $fixedHeight]]
test textDisp-13.8 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    update
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
    lappend x [.t bbox 30.90]
    # contrary to textDisp-13.7 above there is no yview command in this test
    # therefore take into account that the top line is partially hidden
    set y [expr {[yline 6] + [lindex [.t bbox @0,0] 1] - [bo]}]
    set expected [list [list [xchar 10] $y $fixedWidth $fixedHeight] \
                       [list [xchar 19] $y $fixedWidth $fixedHeight] \
                       [list [xchar 19] $y $fixedWidth $fixedHeight] \
                       [list [xchar 10] $y $fixedWidth $fixedHeight]]
    lequal $x $expected
} {1}
test textDisp-13.9 {TkTextSeeCmd procedure} {
    wm geom . [expr {$width-2}]x$height
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    update
    .t see 30.50
    set x [list [.t bbox 30.50]]
    .t see 30.60
    lappend x [.t bbox 30.60]
    .t see 30.65
    lappend x [.t bbox 30.65]
    .t see 30.90
    lappend x [.t bbox 30.90]
    # contrary to textDisp-13.7 above there is no yview command in this test
    # therefore take into account that the top line is partially hidden
    set y [expr {[yline 6] + [lindex [.t bbox @0,0] 1] - [bo]}]
    set expected [list [list [expr {[bo]+round([winfo width .t]-2*[bo])/2}] $y $fixedWidth $fixedHeight] \
                       [list [xcharr 1] $y $fixedWidth $fixedHeight] \
                       [list [xcharr 1] $y $fixedWidth $fixedHeight] \
                       [list [expr {[bo]+round([winfo width .t]-2*[bo])/2}] $y $fixedWidth $fixedHeight]]
    lequal $x $expected
} {1}
test textDisp-13.10 {TkTextSeeCmd procedure} {
    # SF Bug 641778
    set w .tsee
    destroy $w
    text $w -font {Helvetica 8 normal} -bd 16
    $w insert end Hello
    $w see end
    set res [$w bbox end]
    destroy $w
    set res
} {}
test textDisp-13.11 {TkTextSeeCmd procedure} {} {
    # insertion of a character at end of a line containing multi-byte
    # characters and calling see at the line end shall actually show
    # this character
    toplevel .top2
    pack [text .top2.t2 -wrap none]
    for {set i 1} {$i < 5} {incr i} {
        .top2.t2 insert end [string repeat "Line $i: éèàçù" 5]\n
    }

    wm geometry .top2 300x200+0+0
    update
    .top2.t2 see "1.0 lineend"
    update
    set ref [.top2.t2 index @0,0]
    .top2.t2 insert "1.0 lineend" ç
    .top2.t2 see "1.0 lineend"
    update
    set new [.top2.t2 index @0,0]
    set res [.top2.t2 compare $ref == $new]
    destroy .top2
    set res
} {0}
wm geom . {}

.t configure -wrap none
test textDisp-14.1 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    update
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto .5
    .t xview
} [list 0.5 [expr {6./7.}]]
.t configure -wrap char
test textDisp-14.2 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    update
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
.t configure -wrap none
test textDisp-14.3 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    update
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx\n"
    .t insert end "xxxx"
    .t xview
} {0.0 1.0}
test textDisp-14.4 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto} msg] $msg
} {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} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n" ; # 56 chars on this line
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto .3
    .t xview
} [list [expr {round(0.3*(56*$fixedWidth))/(56.0*$fixedWidth)}] [expr {round(0.3*(56*$fixedWidth)+20*$fixedWidth)/(56.0*$fixedWidth)}]]
test textDisp-14.8 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n" ; # 56 chars on this line
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto -.4
    .t xview
} [list 0.0 [expr {20.0/56}]]
test textDisp-14.9 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n" ; # 56 chars on this line
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview m 1.4
    .t xview
} [list [expr {(56.0-20)/56}] 1.0]
test textDisp-14.10 {TkTextXviewCmd procedure} {
    list [catch {.t xview scroll a} msg] $msg
} {1 {wrong # args: should be ".t xview scroll number pages|pixels|units"}}
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} {
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
    .t insert end "Line $i\n"
}
.t insert end "Line 100"
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-15.1 {ScrollByLines procedure, scrolling backwards} {
    .t yview 45.0
    updateText
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-15.2 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    updateText
    .t yview scroll -2 units
    .t index @0,0
} {50.20}
test textDisp-15.3 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    updateText
    .t yview scroll -4 units
    .t index @0,0
} {49.0}
test textDisp-15.4 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.20
    updateText
    .t yview scroll -2 units
    .t index @0,0
} {49.0}
test textDisp-15.5 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.40
    updateText
    .t yview scroll -2 units
    .t index @0,0
} {50.0}
test textDisp-15.6 {ScrollByLines procedure, scrolling backwards} {
    .t yview 3.2
    updateText
    .t yview scroll -5 units
    .t index @0,0
} {1.0}
test textDisp-15.7 {ScrollByLines procedure, scrolling forwards} {
    .t yview 48.0
    updateText
    .t yview scroll 4 units
    .t index @0,0
} {50.40}

test textDisp-15.8 {Scrolling near end of window} {
    set textheight 12
    set textwidth 30







|





|





|





|





|





|





|







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
    .t insert end "Line $i\n"
}
.t insert end "Line 100"
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-15.1 {ScrollByLines procedure, scrolling backwards} {
    .t yview 45.0
    update
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-15.2 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    update
    .t yview scroll -2 units
    .t index @0,0
} {50.20}
test textDisp-15.3 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    update
    .t yview scroll -4 units
    .t index @0,0
} {49.0}
test textDisp-15.4 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.20
    update
    .t yview scroll -2 units
    .t index @0,0
} {49.0}
test textDisp-15.5 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.40
    update
    .t yview scroll -2 units
    .t index @0,0
} {50.0}
test textDisp-15.6 {ScrollByLines procedure, scrolling backwards} {
    .t yview 3.2
    update
    .t yview scroll -5 units
    .t index @0,0
} {1.0}
test textDisp-15.7 {ScrollByLines procedure, scrolling forwards} {
    .t yview 48.0
    update
    .t yview scroll 4 units
    .t index @0,0
} {50.40}

test textDisp-15.8 {Scrolling near end of window} {
    set textheight 12
    set textwidth 30
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035






2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
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
    .tf.f.t tag configure Header -font {Helvetica 14 bold italic} \
      -wrap word -spacing1 12 -spacing3 4

    .tf.f.t insert end "Foo" Header
    for {set i 1} {$i < $textheight} {incr i} {
	.tf.f.t insert end "\nLine $i"
    }
    updateText
    set refind [.tf.f.t index @0,[winfo height .tf.f.t]]
    # Should scroll and should not crash!
    .tf.f.t yview scroll 1 unit
    # Check that it has scrolled
    set newind [.tf.f.t index @0,[winfo height .tf.f.t]]
    set res [.tf.f.t compare $newind > $refind]
    destroy .tf
    set res
} 1

.t configure -wrap char
.t delete 1.0 end
.t insert insert "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t tag add big 100.0 105.0
.t insert 151.end { has a lot of extra text, so that it wraps around on the screen several times over.}
.t insert 153.end { also has enoug extra text to wrap.}
updateText
.t count -update -ypixels 1.0 end






test textDisp-16.1 {TkTextYviewCmd procedure} {
    .t yview 21.0
    set x [.t yview]
    .t yview 1.0
    list [expr {int([lindex $x 0]*100)}] [expr {int ([lindex $x 1] * 100)}]
} {9 14}
test textDisp-16.2 {TkTextYviewCmd procedure} {
    list [catch {.t yview 2 3} msg] $msg
} {1 {bad option "2": must be moveto or scroll}}
test textDisp-16.3 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.4 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace 2 3} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.5 {TkTextYviewCmd procedure} {
    list [catch {.t yview -bogus 2} msg] $msg
} {1 {bad option "-bogus": must be moveto or scroll}}
test textDisp-16.6 {TkTextYviewCmd procedure, integer position} {
    .t yview 100.0
    updateText
    .t yview 98
    .t index @0,0
} {99.0}
test textDisp-16.7 {TkTextYviewCmd procedure} {
    .t yview 2.0
    .t yv -pickplace 13.0
    .t index @0,0
} {4.0}
test textDisp-16.8 {TkTextYviewCmd procedure} {
    list [catch {.t yview bad_mark_name} msg] $msg
} {1 {bad text index "bad_mark_name"}}
test textDisp-16.9 {TkTextYviewCmd procedure, "moveto" option} {
    list [catch {.t yview moveto a b} msg] $msg
} {1 {wrong # args: should be ".t yview moveto fraction"}}
test textDisp-16.10 {TkTextYviewCmd procedure, "moveto" option} {
    list [catch {.t yview moveto gorp} msg] $msg
} {1 {expected floating-point number but got "gorp"}}
test textDisp-16.11 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {

    .t yview moveto 0.5
    .t index @0,0
} {103.0}
test textDisp-16.12 {TkTextYviewCmd procedure, "moveto" option} {
    .t yview moveto -1
    .t index @0,0
} {1.0}
test textDisp-16.13 {TkTextYviewCmd procedure, "moveto" option} {
    .t yview moveto 1.1
    .t index @0,0
} {191.0}
test textDisp-16.14 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {

    .t yview moveto .75








    .t index @0,0
} {151.60}
test textDisp-16.15 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {

    .t yview moveto .752










    .t index @0,0
} {151.60}
test textDisp-16.16 {TkTextYviewCmd procedure, "moveto" option} textfonts {
    set count [expr {5 * $bigHeight + 150 * $fixedHeight}]
    set extra [expr {0.04 * double($fixedDiff * 150) / double($count)}]

    .t yview moveto [expr {.753 - $extra}]










    .t index @0,0
} {151.60}
test textDisp-16.17 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {

    .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
    text .top1.t -height 3 -width 4 -wrap none -setgrid 1 -padx 6 \
	-spacing3 6
    pack .top1.t
    updateText
    .top1.t insert end "1\n2\n3\n4\n5\n6"
    .top1.t yview moveto 0.3333
    set result [.top1.t yview]
    destroy .top1
    set result
} [list [expr {1.0/3}] [expr {5.0/6}]]
test textDisp-16.19 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.20 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.21 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll bogus bogus} msg] $msg
} {1 {bad argument "bogus": must be pages, pixels, or units}}
test textDisp-16.21.2 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll bogus units} msg] $msg
} {1 {expected floating-point number but got "bogus"}}
test textDisp-16.22 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    updateText
    .t yview scroll -1 pages
    .t index @0,0
} {42.0}
test textDisp-16.22.1 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    list [catch {.t yview scroll -3 p} res] $res
} {1 {ambiguous argument "p": must be pages, pixels, or units}}
test textDisp-16.23 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    updateText
    .t yview scroll -3 pa
    .t index @0,0
} {26.0}
test textDisp-16.24 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 5.0
    updateText
    .t yview scroll -3 pa
    .t index @0,0
} {1.0}
test textDisp-16.25 {TkTextYviewCmd procedure, "scroll" option, back pages} {





    .t configure -height 1
    updateText
    .t yview 50.0
    updateText
    .t yview scroll -1 pages
    set x [.t index @0,0]
    .t configure -height 10
    updateText
    set x


} {49.0}
test textDisp-16.26 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    updateText
    .t yview scroll 1 pages
    .t index @0,0
} {58.0}
test textDisp-16.27 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    updateText
    .t yview scroll 2 pages
    .t index @0,0
} {66.0}
test textDisp-16.28 {TkTextYviewCmd procedure, "scroll" option, forward pages} {textfonts} {
    .t yview 98.0
    updateText





    .t yview scroll 1 page
    set res [expr {int([.t index @0,0])}]
    if {$fixedDiff > 1} {
	incr res -1
    }
    set res
} 102
test textDisp-16.29 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t configure -height 1
    updateText
    .t yview 50.0
    updateText
    .t yview scroll 1 pages
    set x [.t index @0,0]
    .t configure -height 10
    updateText
    set x
} {51.0}
test textDisp-16.30 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 45.0
    updateText
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-16.31 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 149.0
    updateText
    .t yview scroll 4 units
    .t index @0,0
} {151.40}
test textDisp-16.32 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 12 bogoids} msg] $msg
} {1 {bad argument "bogoids": must be pages, pixels, or units}}
test textDisp-16.33 {TkTextYviewCmd procedure} {







|
|



|



|









|
|
|
>
>
>
>
>
>




|















|

















|
>











|
>

>
>
>
>
>
>
>
>
|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
<
<
>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
>



|






|




















|








|





|



|
>
>
>
>
>

|

|



|

>
>
|


|





|



|

|
>
>
>
>
>

|
<
<
<
<
|


|

|



|




|





|







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
    .tf.f.t tag configure Header -font {Helvetica 14 bold italic} \
      -wrap word -spacing1 12 -spacing3 4

    .tf.f.t insert end "Foo" Header
    for {set i 1} {$i < $textheight} {incr i} {
	.tf.f.t insert end "\nLine $i"
    }
    update
    set refind [.tf.f.t index @0,last]
    # 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,last]
    set res [.tf.f.t compare $newind > $refind]
    destroy .tf
    set res
} {1}

.t configure -wrap char
.t delete 1.0 end
.t insert insert "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t tag add big 100.0 105.0
.t insert 151.end { has a lot of extra text, so that it wraps around on the screen several times over.}
.t insert 153.end { also has largely enough extra text to wrap.}
update
set totpix [.t count -update -ypixels 1.0 end]
# check that the wrapping lines wrap exactly 6 times in total (4 times for line 151, and twice for line 153),
# this is an assumption of the upcoming tests
if {[expr {double(($totpix-5*$heightDiff)/$fixedHeight)}] != 206.0} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual [.t cget -font]]\",\
is too different from the requested \"[.t cget -font]\". Some of the upcoming tests will probably fail."
}
test textDisp-16.1 {TkTextYviewCmd procedure} {
    .t yview 21.0
    set x [.t yview]
    .t yview 1.0
    list [expr {int([lindex $x 0]*100)}] [expr {int([lindex $x 1]*100)}]
} {9 14}
test textDisp-16.2 {TkTextYviewCmd procedure} {
    list [catch {.t yview 2 3} msg] $msg
} {1 {bad option "2": must be moveto or scroll}}
test textDisp-16.3 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.4 {TkTextYviewCmd procedure} {
    list [catch {.t yview -pickplace 2 3} msg] $msg
} {1 {wrong # args: should be ".t yview -pickplace lineNum|index"}}
test textDisp-16.5 {TkTextYviewCmd procedure} {
    list [catch {.t yview -bogus 2} msg] $msg
} {1 {bad option "-bogus": must be moveto or scroll}}
test textDisp-16.6 {TkTextYviewCmd procedure, integer position} {
    .t yview 100.0
    update
    .t yview 98
    .t index @0,0
} {99.0}
test textDisp-16.7 {TkTextYviewCmd procedure} {
    .t yview 2.0
    .t yv -pickplace 13.0
    .t index @0,0
} {4.0}
test textDisp-16.8 {TkTextYviewCmd procedure} {
    list [catch {.t yview bad_mark_name} msg] $msg
} {1 {bad text index "bad_mark_name"}}
test textDisp-16.9 {TkTextYviewCmd procedure, "moveto" option} {
    list [catch {.t yview moveto a b} msg] $msg
} {1 {wrong # args: should be ".t yview moveto fraction"}}
test textDisp-16.10 {TkTextYviewCmd procedure, "moveto" option} {
    list [catch {.t yview moveto gorp} msg] $msg
} {1 {expected floating-point number but got "gorp"}}
test textDisp-16.11 {TkTextYviewCmd procedure, "moveto" option} haveBigFontTwiceLargerThanTextFont {
# constrained because text tagged with the big font plays a role
    .t yview moveto 0.5
    .t index @0,0
} {103.0}
test textDisp-16.12 {TkTextYviewCmd procedure, "moveto" option} {
    .t yview moveto -1
    .t index @0,0
} {1.0}
test textDisp-16.13 {TkTextYviewCmd procedure, "moveto" option} {
    .t yview moveto 1.1
    .t index @0,0
} {191.0}
test textDisp-16.14 {TkTextYviewCmd procedure, "moveto" option} {
    # y move to 3/4 of text widget content height
    .t yview moveto .75
    # target y position is inside line 151, which wraps 4 times
    # exactly which display line depends on actual font size
    set ytargetline [expr {150*$fixedHeight+5*$heightDiff}]
    set expected 151.0
    while {[expr {$ytargetline+$fixedHeight}] <= [expr {round(0.75*$totpix)}]} {
        incr ytargetline $fixedHeight
	set expected [.t index "$expected + 1 display line"]
    }
    lequal [.t index @0,0] $expected
} {1}
test textDisp-16.15 {TkTextYviewCmd procedure, "moveto" option} {
    # y move to 3/4 of text widget content height plus just one line height minus one pixel
    .t yview moveto .75
    set pixtonextline [expr {-[bo] + [lindex [.t bbox @0,0] 1] + [lindex [.t bbox @0,0] 3]}]
    .t yview moveto [expr {0.75 + ($pixtonextline-1)/double($totpix)}]
    # target y position is inside line 151, which wraps 4 times
    # exactly which display line depends on actual font size
    set ytargetline [expr {150*$fixedHeight+5*$heightDiff}]
    set expected 151.0
    while {[expr {$ytargetline+$fixedHeight}] <= [expr {round(0.75*$totpix + ($pixtonextline-1))}]} {
        incr ytargetline $fixedHeight
	set expected [.t index "$expected + 1 display line"]
    }
    lequal [.t index @0,0] $expected
} {1}
test textDisp-16.16 {TkTextYviewCmd procedure, "moveto" option} {


    # y move to 3/4 of text widget content height plus exactly one line height
    .t yview moveto .75
    set pixtonextline [expr {-[bo] + [lindex [.t bbox @0,0] 1] + [lindex [.t bbox @0,0] 3]}]
    .t yview moveto [expr {0.75 + $pixtonextline/double($totpix)}]
    # target y position is inside line 151, which wraps 4 times
    # exactly which display line depends on actual font size
    set ytargetline [expr {150*$fixedHeight+5*$heightDiff}]
    set expected 151.0
    while {[expr {$ytargetline+$fixedHeight}] <= [expr {round(0.75*$totpix + $pixtonextline)}]} {
        incr ytargetline $fixedHeight
	set expected [.t index "$expected + 1 display line"]
    }
    lequal [.t index @0,0] $expected
} {1}
test textDisp-16.17 {TkTextYviewCmd procedure, "moveto" option} haveBigFontTwiceLargerThanTextFont {
# constrained because text tagged with the big font plays a role
    .t yview moveto .755
    .t index @0,0
} {151.80}
test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {
    catch {destroy .top1}
    toplevel .top1
    wm geometry .top1 +0+0
    text .top1.t -height 3 -width 4 -wrap none -setgrid 1 -padx 6 \
	-spacing3 6
    pack .top1.t
    update
    .top1.t insert end "1\n2\n3\n4\n5\n6"
    .top1.t yview moveto 0.3333
    set result [.top1.t yview]
    destroy .top1
    set result
} [list [expr {1.0/3}] [expr {5.0/6}]]
test textDisp-16.19 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.20 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll a b c} msg] $msg
} {1 {wrong # args: should be ".t yview scroll number pages|pixels|units"}}
test textDisp-16.21 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll bogus bogus} msg] $msg
} {1 {bad argument "bogus": must be pages, pixels, or units}}
test textDisp-16.21.2 {TkTextYviewCmd procedure, "scroll" option} {
    list [catch {.t yview scroll bogus units} msg] $msg
} {1 {expected floating-point number but got "bogus"}}
test textDisp-16.22 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    update
    .t yview scroll -1 pages
    .t index @0,0
} {42.0}
test textDisp-16.22.1 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    list [catch {.t yview scroll -3 p} res] $res
} {1 {ambiguous argument "p": must be pages, pixels, or units}}
test textDisp-16.23 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    update
    .t yview scroll -3 pa
    .t index @0,0
} {26.0}
test textDisp-16.24 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 5.0
    update
    .t yview scroll -3 pa
    .t index @0,0
} {1.0}
test textDisp-16.25 {TkTextYviewCmd procedure, "scroll" option, back pages} -setup {
    # this frame is needed because some window managers don't allow the overall
    # height of a window to get very narrow, triggering false test failure
    frame .f2 -height 20
    pack .f2 -side top
} -body {
    .t configure -height 1
    update
    .t yview 50.0
    update
    .t yview scroll -1 pages
    set x [.t index @0,0]
    .t configure -height 10
    update
    set x
} -cleanup {
    destroy .f2
} -result {49.0}
test textDisp-16.26 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    update
    .t yview scroll 1 pages
    .t index @0,0
} {58.0}
test textDisp-16.27 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    update
    .t yview scroll 2 pages
    .t index @0,0
} {66.0}
test textDisp-16.28 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 98.0
    update
    # The man page does not say it but the code does: scrolling 1 page actually uses the
    # window height minus two lines, so that there's some overlap between adjacent pages.
    # Note: it's a bit tricky but we only need to subtract one [bo] from [winfo height .t] here
    # because the origin of @x,y coordinates is at borderwidth start, not at text area start.
    set expected [.t index @0,[expr {[winfo height .t]-[bo]-2*$fixedHeight}]]
    .t yview scroll 1 page
    lequal [.t index @0,0] $expected




} {1}
test textDisp-16.29 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t configure -height 1
    update
    .t yview 50.0
    update
    .t yview scroll 1 pages
    set x [.t index @0,0]
    .t configure -height 10
    update
    set x
} {51.0}
test textDisp-16.30 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 45.0
    update
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-16.31 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 149.0
    update
    .t yview scroll 4 units
    .t index @0,0
} {151.40}
test textDisp-16.32 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 12 bogoids} msg] $msg
} {1 {bad argument "bogoids": must be pages, pixels, or units}}
test textDisp-16.33 {TkTextYviewCmd procedure} {
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
    lappend res [expr {[lindex [.t yview] 0] * [.t count -ypixels 1.0 end]}]
} {0.0 0.0}
test textDisp-16.37 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3 pixels} msg] $msg
} {0 {}}
test textDisp-16.38 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3blah pixels} msg] $msg
} {1 {bad screen distance "1.3blah"}}
test textDisp-16.39 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3i pixels} msg] $msg
} {0 {}}
test textDisp-16.40 {text count -xpixels} failsOnUbuntu {
    set res {}
    lappend res [.t count -xpixels 1.0 1.5] \
      [.t count -xpixels 1.5 1.0] \
      [.t count -xpixels 1.0 13.0] \
      [.t count -xpixels 1.0 "1.0 displaylineend"] \
      [.t count -xpixels 1.0 "1.0 lineend"] \
      [.t count -xpixels 1.0 "1.0 displaylineend"] \
      [.t count -xpixels 1.0 end]
} {35 -35 0 42 42 42 0}
test textDisp-16.41 {text count -xpixels with indices in elided lines} {
    set res {}
    .t delete 1.0 end
    for {set i 1} {$i < 40} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }







|



|








|







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
    lappend res [expr {[lindex [.t yview] 0] * [.t count -ypixels 1.0 end]}]
} {0.0 0.0}
test textDisp-16.37 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3 pixels} msg] $msg
} {0 {}}
test textDisp-16.38 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3blah pixels} msg] $msg
} {1 {expected screen distance but got "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} {
    set res {}
    lappend res [.t count -xpixels 1.0 1.5] \
      [.t count -xpixels 1.5 1.0] \
      [.t count -xpixels 1.0 13.0] \
      [.t count -xpixels 1.0 "1.0 displaylineend"] \
      [.t count -xpixels 1.0 "1.0 lineend"] \
      [.t count -xpixels 1.0 "1.0 displaylineend"] \
      [.t count -xpixels 1.0 end]
} [list [expr {5*$fixedWidth}] [expr {-5*$fixedWidth}] 0 [expr {6*$fixedWidth}] [expr {6*$fixedWidth}] [expr {6*$fixedWidth}] 0]
test textDisp-16.41 {text count -xpixels with indices in elided lines} {
    set res {}
    .t delete 1.0 end
    for {set i 1} {$i < 40} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    updateText
    .t index @0,0
} {5.0}
test textDisp-16.43 {TkTextYviewCmd procedure with indices in elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll -15 units
    updateText
    .t index @0,0
} {5.0}
test textDisp-16.44 {TkTextYviewCmd procedure, scroll down, with elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    foreach x [list 0 1 2 3 4 5 6 7 8 9 0] {
      .t insert end "$x aaa1\n$x bbb2\n$x ccc3\n$x ddd4\n$x eee5\n$x fff6"
      .t insert end "$x 1111\n$x 2222\n$x 3333\n$x 4444\n$x 5555\n$x 6666" hidden
    }
    .t tag configure hidden -elide true ; # 5 hidden lines
    updateText
    .t see [expr {5 + [winfo height .t] / $fixedHeight + 1}].0
    updateText
    .t index @0,0
} {2.0}

.t delete 1.0 end
foreach i {a b c d e f g h i j k l m n o p q r s t u v w x y z} {
    .t insert end "\nLine $i 11111 $i 22222 $i 33333 $i 44444 $i 55555"
    .t insert end " $i 66666 $i 77777 $i 88888 $i"







|













|










|

|







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
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    update
    .t index @0,0
} {5.0}
test textDisp-16.43 {TkTextYviewCmd procedure with indices in elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    .t yview scroll -15 units
    update
    .t index @0,0
} {5.0}
test textDisp-16.44 {TkTextYviewCmd procedure, scroll down, with elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    foreach x [list 0 1 2 3 4 5 6 7 8 9 0] {
      .t insert end "$x aaa1\n$x bbb2\n$x ccc3\n$x ddd4\n$x eee5\n$x fff6"
      .t insert end "$x 1111\n$x 2222\n$x 3333\n$x 4444\n$x 5555\n$x 6666" hidden
    }
    .t tag configure hidden -elide true ; # 5 hidden lines
    update
    .t see [expr {5 + [winfo height .t] / $fixedHeight + 1}].0
    update
    .t index @0,0
} {2.0}

.t delete 1.0 end
foreach i {a b c d e f g h i j k l m n o p q r s t u v w x y z} {
    .t insert end "\nLine $i 11111 $i 22222 $i 33333 $i 44444 $i 55555"
    .t insert end " $i 66666 $i 77777 $i 88888 $i"
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
    list [catch {.t scan stupid b 20} msg] $msg
} {1 {expected integer but got "b"}}
test textDisp-17.4 {TkTextScanCmd procedure} {
    list [catch {.t scan stupid -2 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test textDisp-17.5 {TkTextScanCmd procedure} {
    list [catch {.t scan stupid 123 456} msg] $msg
} {1 {bad scan option "stupid": must be mark or dragto}}
test textDisp-17.6 {TkTextScanCmd procedure} {textfonts} {
    .t yview 1.0
    .t xview moveto 0


    .t scan mark 40 60
    .t scan dragto 35 55

    .t index @0,0
} {4.7}
test textDisp-17.7 {TkTextScanCmd procedure} {textfonts} {

    .t yview 10.0
    .t xview moveto 0



    .t xview scroll 20 units

    .t scan mark -10 60
    .t scan dragto -5 65
    .t index @0,0
    set x [.t index @0,0]











    .t scan dragto 0 [expr {70 + $fixedDiff}]

    list $x [.t index @0,0]
} {6.12 2.5}
test textDisp-17.8 {TkTextScanCmd procedure} {textfonts} {
    .t yview 1.0
    .t xview moveto 0


    .t scan mark 0 60
    .t scan dragto 30 100

    .t scan dragto 25 95

    .t index @0,0
} {4.7}
test textDisp-17.9 {TkTextScanCmd procedure} {textfonts} {
    .t yview end
    .t xview moveto 0


    .t xview scroll 100 units


    .t scan mark 90 60
    .t scan dragto 10 0



    .t scan dragto 14 5

    .t index @0,0
} {18.44}
.t configure -wrap word
test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {textfonts} {
    .t yview 10.0



    .t scan mark -10 60
    .t scan dragto -5 65

    set x [.t index @0,0]

    .t scan dragto 0 [expr {70 + $fixedDiff}]

    list $x [.t index @0,0]
} {9.0 8.0}
.t configure -xscrollcommand scroll -yscrollcommand {}

test textDisp-18.1 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-18.2 {GetXView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-18.3 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-18.4 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxx
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-18.5 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    .t xview scroll 31 units
    updateText
    set scrollInfo
} [list [expr {31.0/55}] [expr {51.0/55}]]
test textDisp-18.6 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 31 units
    updateText
    set x {}
    lappend x $scrollInfo
    .t configure -wrap char
    updateText
    lappend x $scrollInfo
    .t configure -wrap word
    updateText
    lappend x $scrollInfo
    .t configure -wrap none
    updateText
    lappend x $scrollInfo
} [list [list [expr {31.0/56}] [expr {51.0/56}]] {0.0 1.0} {0.0 1.0} [list 0.0 [expr {5.0/14}]]]
test textDisp-18.7 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    set scrollInfo unchanged
    .t insert end xxxxxx\n
    .t insert end xxx
    updateText
    set scrollInfo
} {unchanged}
test textDisp-18.8 {GetXView procedure} {
    proc bgerror msg {
	global x errorInfo
	set x [list $msg $errorInfo]
    }
    proc bogus args {
	error "bogus scroll proc"
    }
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    updateText
    .t delete 1.0 end
    .t configure -xscrollcommand scrollError
    updateText
    set x
} {{scrolling error} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (horizontal scrolling command executed by text)}}
catch {rename bgerror {}}
catch {rename bogus {}}

.t configure -xscrollcommand {} -yscrollcommand scroll
test textDisp-19.1 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo
} {0.0 1.0}
test textDisp-19.2 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo "unchanged"
    .t insert 1.0 "Line1\nLine2"
    updateText
    set scrollInfo
} {unchanged}
test textDisp-19.3 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    set scrollInfo "unchanged"
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    set scrollInfo
} {unchanged}
test textDisp-19.4 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    updateText
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    updateText
    set scrollInfo
} [list 0.0 [expr {70.0/91}]]
test textDisp-19.5 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    updateText
    set x $scrollInfo
} {0.0 0.625}
test textDisp-19.6 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 4.0
    updateText
    set x $scrollInfo
} {0.375 1.0}
test textDisp-19.7 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.26
    updateText
    set x $scrollInfo
} {0.125 0.75}
test textDisp-19.8 {GetYView procedure} failsOnUbuntu {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 10.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.0
    updateText
    .t count -update -ypixels 1.0 end
    set x $scrollInfo
} {0.0625 0.6875}
test textDisp-19.9 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 3.0
    updateText
    set scrollInfo
} [list [expr {4.0/30}] 0.8]
test textDisp-19.10 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    updateText
    set scrollInfo
} [list [expr {1.0/3}] 1.0]
test textDisp-19.10.1 {Widget manipulation causes height miscount} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    updateText
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    .t yview insert
    updateText
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    .t yview insert
    updateText
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11.2 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.0 end
} 20
test textDisp-19.11.3 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines end 1.0
} -20
test textDisp-19.11.4 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.1 1.3
} 0
test textDisp-19.11.5 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.1
} 0
test textDisp-19.11.5.1 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.5
} 0
test textDisp-19.11.6 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.24
} 1
test textDisp-19.11.7 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.40
} 2
test textDisp-19.11.8 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 displaylineend +1c" "16.0 lineend"
} 3
test textDisp-19.11.9 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 lineend"
} 4
test textDisp-19.11.10 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.11 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +2displaylines"
} 2
test textDisp-19.11.12 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 +1displayline" "16.0 +2displaylines -1c"
} 0
.t tag configure elide -elide 1
test textDisp-19.11.13 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines +6c"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.14 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines displaylineend"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.15 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines -1c"
} 3
test textDisp-19.11.15a {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} 4
test textDisp-19.11.16 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    .t count -displaylines 12.0 16.0
} 2
test textDisp-19.11.17 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.1 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {15.5 16.0 15.0 16.0 16.21 16.39}
test textDisp-19.11.18 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "15.5 -2d lines"] \
      [.t index "16.0 -2d lines"] [.t index "15.0 -2d lines"] \
      [.t index "16.0 -3d lines"] [.t index "16.23 -4d lines"] \
      [.t index "16.42 -5d lines"]
} {11.5 14.0 11.0 11.0 11.2 11.3}
test textDisp-19.11.19 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    .t count -displaylines 12.0 17.0
} 4
test textDisp-19.11.20 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]







|
|


>
>


>
|
|
|
>
|

>
>
>

>


|

>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
|


>
>


>

>
|
|
|


>
>

>
>


>
>
>

>
|
|

|

>
>
>


>

>
|
>
|
|

>






|








|





|








|









|










|



|


|


|





|



|













|


|










>




|





|


|





|


|






|




|










|











|











|


|








|











|










|










|









|













|





|


|


|


|


|


|


|


|


|


|


|


|





|




|




|




|




|




















|







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
    list [catch {.t scan stupid b 20} msg] $msg
} {1 {expected integer but got "b"}}
test textDisp-17.4 {TkTextScanCmd procedure} {
    list [catch {.t scan stupid -2 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test textDisp-17.5 {TkTextScanCmd procedure} {
    list [catch {.t scan stupid 123 456} msg] $msg
} {1 {bad scan option "stupid": must be dragto or mark}}
test textDisp-17.6 {TkTextScanCmd procedure} {
    .t yview 1.0
    .t xview moveto 0
    update
    set expected [.t index @[expr {[bo]+50}],[expr {[bo]+50}]]
    .t scan mark 40 60
    .t scan dragto 35 55
    update
    lequal [.t index @0,0] $expected
} {1}
test textDisp-17.7 {TkTextScanCmd procedure} {
    # 1st result
    .t yview 1.0
    .t xview moveto 0
    update
    set expected [.t index @[expr {[bo]+20*$fixedWidth-50}],[expr {[bo]+9*$fixedHeight-50}]]
    .t yview 10.0
    .t xview scroll 20 units
    update
    .t scan mark -10 60
    .t scan dragto -5 65
    update
    set x [.t index @0,0]
    # 2nd result
    .t yview 1.0
    .t xview moveto 0
    update
    lappend expected [.t index @[expr {[bo]+20*$fixedWidth-50-50}],[expr {[bo]+9*$fixedHeight-50-70}]]
    .t yview 10.0
    .t xview scroll 20 units
    update
    .t scan mark -10 60
    .t scan dragto -5 65
    update
    .t scan dragto 0 72
    update
    lequal [list $x [.t index @0,0]] $expected
} {1}
test textDisp-17.8 {TkTextScanCmd procedure} {
    .t yview 1.0
    .t xview moveto 0
    update
    set expected [.t index @[expr {[bo]+50}],[expr {[bo]+50}]]
    .t scan mark 0 60
    .t scan dragto 30 100
    update
    .t scan dragto 25 95
    update
    lequal [.t index @0,0] $expected
} {1}
test textDisp-17.9 {TkTextScanCmd procedure} {
    .t yview end
    .t xview moveto 0
    update
    # this brings us at lower right corner of the text
    .t xview scroll 100 units
    update
    # this does not trigger any scroll, we're already at the corner
    .t scan mark 90 60
    .t scan dragto 10 0
    update
    set expected [.t index @[expr {[winfo width .t]-[bo]-40}],[expr {[winfo height .t]-[bo]-50}]]
    set expected [.t index "$expected - [.t cget -height] lines - [.t cget -width] chars"]
    .t scan dragto 14 5
    update
    lequal [.t index @0,0] $expected
} {1}
.t configure -wrap word
test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {
    .t yview 10.0
    update
    set origin [.t index @0,0]
    set expected [.t index "$origin - [expr {int(ceil(50.0/$fixedHeight))}] display lines"]
    .t scan mark -10 60
    .t scan dragto -5 65
    update
    set x [.t index @0,0]
    lappend expected [.t index "$origin - [expr {int(ceil((50.0+70.0)/$fixedHeight))}] display lines"]
    .t scan dragto 0 72
    update
    lequal [list $x [.t index @0,0]] $expected
} {1}
.t configure -xscrollcommand scroll -yscrollcommand {}

test textDisp-18.1 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-18.2 {GetXView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.3 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.4 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxx
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.5 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    .t xview scroll 31 units
    update
    set scrollInfo
} [list [expr {31.0/55}] [expr {51.0/55}]]
test textDisp-18.6 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto 0
    .t xview scroll 31 units
    update
    set x {}
    lappend x $scrollInfo
    .t configure -wrap char
    update
    lappend x $scrollInfo
    .t configure -wrap word
    update
    lappend x $scrollInfo
    .t configure -wrap none
    update
    lappend x $scrollInfo
} [list [list [expr {31.0/56}] [expr {51.0/56}]] {0.0 1.0} {0.0 1.0} [list 0.0 [expr {5.0/14}]]]
test textDisp-18.7 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    update
    set scrollInfo unchanged
    .t insert end xxxxxx\n
    .t insert end xxx
    update
    set scrollInfo
} {unchanged}
test textDisp-18.8 {GetXView procedure} {
    proc bgerror msg {
	global x errorInfo
	set x [list $msg $errorInfo]
    }
    proc bogus args {
	error "bogus scroll proc"
    }
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    update
    .t delete 1.0 end
    .t configure -xscrollcommand scrollError
    update
    set x
} {{scrolling error} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
    invoked from within
"scrollError 0.0 1.0"
    (horizontal scrolling command executed by text)}}
catch {rename bgerror {}}
catch {rename bogus {}}

.t configure -xscrollcommand {} -yscrollcommand scroll
test textDisp-19.1 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-19.2 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    update
    set scrollInfo "unchanged"
    .t insert 1.0 "Line1\nLine2"
    update
    set scrollInfo
} {unchanged}
test textDisp-19.3 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    update
    set scrollInfo "unchanged"
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    update
    set scrollInfo
} {unchanged}
test textDisp-19.4 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    update
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    update
    set scrollInfo
} [list 0.0 [expr {70.0/91}]]
test textDisp-19.5 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    update
    set x $scrollInfo
} {0.0 0.625}
test textDisp-19.6 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 4.0
    update
    set x $scrollInfo
} {0.375 1.0}
test textDisp-19.7 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 2.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.26
    update
    set x $scrollInfo
} {0.125 0.75}
test textDisp-19.8 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    .t insert 10.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.0
    update
    .t count -update -ypixels 1.0 end
    set x $scrollInfo
} {0.0625 0.6875}
test textDisp-19.9 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 3.0
    update
    set scrollInfo
} [list [expr {4.0/30}] 0.8]
test textDisp-19.10 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    update
    set scrollInfo
} [list [expr {1.0/3}] 1.0]
test textDisp-19.10.1 {Widget manipulation causes height miscount} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t yview 11.0
    update
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    .t yview insert
    update
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    .t yview insert
    update
    .t count -update -ypixels 1.0 end
    set scrollInfo
} {0.5 1.0}
test textDisp-19.11.2 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.0 end
} {20}
test textDisp-19.11.3 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines end 1.0
} {-20}
test textDisp-19.11.4 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 1.1 1.3
} {0}
test textDisp-19.11.5 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.1
} {0}
test textDisp-19.11.5.1 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.5
} {0}
test textDisp-19.11.6 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.24
} {1}
test textDisp-19.11.7 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 16.40
} {2}
test textDisp-19.11.8 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 displaylineend +1c" "16.0 lineend"
} {3}
test textDisp-19.11.9 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 lineend"
} {4}
test textDisp-19.11.10 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.11 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines 16.0 "16.0 +2displaylines"
} {2}
test textDisp-19.11.12 {TextWidgetCmd procedure, "count -displaylines"} {
    .t count -displaylines "16.0 +1displayline" "16.0 +2displaylines -1c"
} {0}
.t tag configure elide -elide 1
test textDisp-19.11.13 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines +6c"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.14 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +1displaylines displaylineend"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.15 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines -1c"
} {3}
test textDisp-19.11.15a {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "16.0 +1displaylines" "16.0 +2displaylines"
    .t count -displaylines 16.0 "16.0 +4displaylines"
} {4}
test textDisp-19.11.16 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    .t count -displaylines 12.0 16.0
} {2}
test textDisp-19.11.17 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.1 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {15.5 16.0 15.0 16.0 16.21 16.39}
test textDisp-19.11.18 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "14.0"
    list [.t index "15.5 -2d lines"] \
      [.t index "16.0 -2d lines"] [.t index "15.0 -2d lines"] \
      [.t index "16.0 -3d lines"] [.t index "16.23 -4d lines"] \
      [.t index "16.42 -5d lines"]
} {11.5 14.0 11.0 11.0 11.2 11.3}
test textDisp-19.11.19 {TextWidgetCmd procedure, "count -displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    .t count -displaylines 12.0 17.0
} {4}
test textDisp-19.11.20 {TextWidgetCmd procedure, "index +displaylines"} {
    .t tag remove elide 1.0 end
    .t tag add elide "12.0" "16.0 +1displaylines"
    list [.t index "11.5 +2d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
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
    .t tag remove elide 1.0 end
    .t tag add elide "12.3" "16.0 +1displaylines"
    list [.t index "11.5 +1d lines"] [.t index "11.5 +2d lines"] \
      [.t index "12.0 +1d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {16.23 16.44 16.39 16.57 16.39 16.60 16.77 16.79}
.t tag remove elide 1.0 end
test textDisp-19.11.24 {TextWidgetCmd procedure, "index +/-displaylines"} {
    list [.t index "11.5 + -1 display lines"] \
      [.t index "11.5 + +1 disp lines"] \
      [.t index "11.5 - -1 disp lines"] \
      [.t index "11.5 - +1 disp lines"] \
      [.t index "11.5 -1 disp lines"] \
      [.t index "11.5 +1 disp lines"] \
      [.t index "11.5 +0 disp lines"]
} {10.5 12.5 12.5 10.5 10.5 12.5 11.5}
.t tag remove elide 1.0 end
test textDisp-19.12 {GetYView procedure, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
    # Need to wait for asychronous calculations to complete.
    updateText
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    updateText
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
test textDisp-19.13 {GetYView procedure, partially visible last line} {textfonts} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4 has enough text to wrap around at least once"
    # Need to wait for asychronous calculations to complete.
    updateText
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    updateText
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
catch {destroy .top}
test textDisp-19.14 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    # Need to update so everything is calculated.
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    set scrollInfo "unchanged"
    .t mark set insert 3.0
    .t tag configure x -background red
    .t tag add x 1.0 5.0
    updateText
    .t tag delete x
    set scrollInfo
} {unchanged}
test textDisp-19.15 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit little left on the last line."
    updateText
    .t configure -yscrollcommand scrollError
    proc bgerror args {
	global x errorInfo errorCode
	set x [list $args $errorInfo $errorCode]
    }
    .t delete 1.0 end
    updateText
    rename bgerror {}
    .t configure -yscrollcommand scroll
    set x
} {{{scrolling error}} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)







|



















|


|


|







|


|













|

|




|












|






|







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
    .t tag remove elide 1.0 end
    .t tag add elide "12.3" "16.0 +1displaylines"
    list [.t index "11.5 +1d lines"] [.t index "11.5 +2d lines"] \
      [.t index "12.0 +1d lines"] \
      [.t index "12.0 +2d lines"] [.t index "11.0 +2d lines"] \
      [.t index "13.0 +2d lines"] [.t index "13.0 +3d lines"] \
      [.t index "13.0 +4d lines"]
} {16.23 16.44 16.39 16.57 16.39 16.60 16.77 17.0}
.t tag remove elide 1.0 end
test textDisp-19.11.24 {TextWidgetCmd procedure, "index +/-displaylines"} {
    list [.t index "11.5 + -1 display lines"] \
      [.t index "11.5 + +1 disp lines"] \
      [.t index "11.5 - -1 disp lines"] \
      [.t index "11.5 - +1 disp lines"] \
      [.t index "11.5 -1 disp lines"] \
      [.t index "11.5 +1 disp lines"] \
      [.t index "11.5 +0 disp lines"]
} {10.5 12.5 12.5 10.5 10.5 12.5 11.5}
.t tag remove elide 1.0 end
test textDisp-19.12 {GetYView procedure, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
    # Need to wait for asychronous calculations to complete.
    update
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    update
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
test textDisp-19.13 {GetYView procedure, partially visible last line} {
    catch {destroy .top}
    toplevel .top
    wm geometry .top +0+0
    text .top.t -width 40 -height 5 -font $fixedFont
    pack .top.t -expand yes -fill both
    .top.t insert end "Line 1\nLine 2\nLine 3\nLine 4 has enough text to wrap around at least once"
    # Need to wait for asychronous calculations to complete.
    update
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    update
    .top.t yview
} [list 0.0 [expr {(5.0 * $fixedHeight - 3.0)/ (5.0 * $fixedHeight)}]]
catch {destroy .top}
test textDisp-19.14 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    # Need to update so everything is calculated.
    update
    .t count -update -ypixels 1.0 end
    delay
    set scrollInfo "unchanged"
    .t mark set insert 3.0
    .t tag configure x -background red
    .t tag add x 1.0 5.0
    update
    .t tag delete x
    set scrollInfo
} {unchanged}
test textDisp-19.15 {GetYView procedure} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a bit little left on the last line."
    update
    .t configure -yscrollcommand scrollError
    proc bgerror args {
	global x errorInfo errorCode
	set x [list $args $errorInfo $errorCode]
    }
    .t delete 1.0 end
    update
    rename bgerror {}
    .t configure -yscrollcommand scroll
    set x
} {{{scrolling error}} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
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
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    # Need to update so everything is calculated.
    updateText
    .t count -update -ypixels 1.0 end
    updateText
    set res {}
    lappend res \
      [.t count -ypixels 1.0 end] \
      [.t count -update -ypixels 1.0 end] \
      [.t count -ypixels 15.0 16.0] \
      [.t count -ypixels 15.0 "16.0 displaylineend +1c"] \
      [.t count -ypixels 16.0 "16.0 displaylineend +1c"] \
      [.t count -ypixels "16.0 +1 displaylines" "16.0 +4 displaylines +3c"]



} [list [expr {260 + 20 * $fixedDiff}] [expr {260 + 20 * $fixedDiff}] $fixedHeight [expr {2*$fixedHeight}] $fixedHeight [expr {3*$fixedHeight}]]


test textDisp-19.17 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    set res {}

    update
    lappend res \
      [.t count -ypixels 1.0 6.0] \
      [.t count -ypixels 2.0 7.5] \
      [.t count -ypixels 5.0 8.5] \
      [.t count -ypixels 6.1 6.2] \
      [.t count -ypixels 6.1 18.8] \
      [.t count -ypixels 18.0 20.50] \
      [.t count -ypixels 5.2 20.60] \
      [.t count -ypixels 20.60 20.70] \
      [.t count -ypixels 5.0 25.0] \
      [.t count -ypixels 25.0 5.0] \
      [.t count -ypixels 25.4 27.50] \
      [.t count -ypixels 35.0 38.0]
    .t yview 35.0
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {4 * $fixedHeight}] [expr {3 * $fixedHeight}] 0 0 0 0 0 0 [expr {5 * $fixedHeight}] [expr {- 5 * $fixedHeight}] [expr {2 * $fixedHeight}] [expr {3 * $fixedHeight}] [expr {5 * $fixedHeight}]]







test textDisp-19.18 {count -ypixels with indices in elided lines} {failsOnUbuntu failsOnXQuarz} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    set res {}

    update
    lappend res [.t count -ypixels 5.0 25.0]
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    updateText
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {5 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.19 {count -ypixels with indices in elided lines} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 25} {incr i} {
        .t insert end [string repeat "Line $i -" 6]
        .t insert end "\n"
    }
    .t tag add hidden 5.27 11.0
    .t tag configure hidden -elide true
    .t yview 5.0
    updateText
    set res [list [.t count -ypixels 5.0 11.0] [.t count -ypixels 5.0 11.20]]
} [list [expr {1 * $fixedHeight}] [expr {2 * $fixedHeight}]]
.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-20.1 {FindDLine} failsOnUbuntu {
    .t yview 48.0
    list [.t dlineinfo 46.0] [.t dlineinfo 47.0] [.t dlineinfo 49.0] \
	    [.t dlineinfo 58.0]
} [list {} {} [list 3 [expr {$fixedDiff + 16}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]
test textDisp-20.2 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview -pickplace 53.0





    list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.21]
} [list [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {-1 - $fixedDiff/2}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {12 + $fixedDiff/2}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]


test textDisp-20.3 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 49.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 57.0]
} [list [list 3 [expr {$fixedDiff + 16}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {2*$fixedDiff + 29}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]


test textDisp-20.4 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 42.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 50.40]
} [list [list 3 [expr {8*$fixedDiff + 107}] 140 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 133 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]


.t config -wrap none
test textDisp-20.5 {FindDLine} failsOnUbuntu {
    .t yview 100.0
    .t yview 48.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40]
} [list [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {3+2*$fixedHeight}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]



.t config -wrap word
test textDisp-21.1 {TkTextPixelIndex} {textfonts} {
    .t yview 48.0

    list [.t index @-10,-10] [.t index @6,6] [.t index @22,6] \
	    [.t index @102,6] [.t index @38,[expr {$fixedHeight * 4 + 3}]] [.t index @44,67]
} {48.0 48.0 48.2 48.7 50.45 50.45}
.t insert end \n
test textDisp-21.2 {TkTextPixelIndex} {textfonts} {
    .t yview 195.0

    list [.t index @11,[expr {$fixedHeight * 5 + 5}]] [.t index @11,[expr {$fixedHeight * 6 + 5}]] [.t index @11,[expr {$fixedHeight * 7 + 5}]] \


	    [.t index @11,1002]
} {197.1 198.1 199.1 201.0}
test textDisp-21.3 {TkTextPixelIndex, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
    .t insert end "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    .t xview scroll 2 units

    list [.t index @-5,7] [.t index @5,7] [.t index @33,20]
} {1.2 1.2 2.6}
test textDisp-21.4 {count -displaylines regression} {
    set message {
   QOTW:  "C/C++, which is used by 16% of users, is the most popular programming language, but Tcl, used by 0%, seems to be the language of choice for the highest scoring users."
(new line)
Use the Up (cursor) key to scroll up one line at a time.  At the second press, the cursor either gets locked or jumps several lines.








|

|
|
<





|
>
>
>
|
>
>
|








|
>

|











|


|
>
>
>
>
>
>
>
|









|
>

|

|












|










|



|
|


>
>
>
>
>
|
<
>
>
|



|
>
>
|



|
>
>

|



|
>
>


|

>
|
|
|

|

>
|
>
>
|

|





>
|







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
    .t insert 1.0 "Line 1"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    .t insert end "\nThis last line wraps around four "
    .t insert end "times with a little bit left on the last line."
    # Need to update so everything is calculated.
    update
    .t count -update -ypixels 1.0 end
    update
    set res [list \

      [.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 {20 * $fixedHeight}] \
        [expr {20 * $fixedHeight}] \
	$fixedHeight \
	[expr {2*$fixedHeight}] \
	$fixedHeight \
	[expr {3*$fixedHeight}]]
test textDisp-19.17 {count -ypixels with indices in elided lines} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    update
    .t count -update -ypixels 1.0 end
    update
    set res [list \
      [.t count -ypixels 1.0 6.0] \
      [.t count -ypixels 2.0 7.5] \
      [.t count -ypixels 5.0 8.5] \
      [.t count -ypixels 6.1 6.2] \
      [.t count -ypixels 6.1 18.8] \
      [.t count -ypixels 18.0 20.50] \
      [.t count -ypixels 5.2 20.60] \
      [.t count -ypixels 20.60 20.70] \
      [.t count -ypixels 5.0 25.0] \
      [.t count -ypixels 25.0 5.0] \
      [.t count -ypixels 25.4 27.50] \
      [.t count -ypixels 35.0 38.0] ]
    .t 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} {
    .t configure -wrap none
    .t delete 1.0 end
    for {set i 1} {$i < 100} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
    .t tag add hidden 5.15 20.15
    .t tag configure hidden -elide true
    .t yview 35.0
    update
    .t count -update -ypixels 1.0 end
    update
    set res [.t count -ypixels 5.0 25.0]
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    update
    lappend res [.t count -ypixels 5.0 25.0]
} [list [expr {5 * $fixedHeight}] [expr {5 * $fixedHeight}]]
test textDisp-19.19 {count -ypixels with indices in elided lines} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 25} {incr i} {
        .t insert end [string repeat "Line $i -" 6]
        .t insert end "\n"
    }
    .t tag add hidden 5.27 11.0
    .t tag configure hidden -elide true
    .t yview 5.0
    update
    set res [list [.t count -ypixels 5.0 11.0] [.t count -ypixels 5.0 11.20]]
} [list [expr {1 * $fixedHeight}] [expr {2 * $fixedHeight}]]
.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
test textDisp-20.1 {FindDLine} {
    .t yview 48.0
    list [.t dlineinfo 46.0] [.t dlineinfo 47.0] [.t dlineinfo 49.0] \
	    [.t dlineinfo 58.0]
} [list {} {} [list [bo] [yline 2] [xw 7] $fixedHeight $fixedAscent] {}]
test textDisp-20.2 {FindDLine} {
    .t yview 100.0
    .t yview -pickplace 53.0
    set centlineY [lindex [.t bbox 53.0] 1]
    set expectedY [expr {$centlineY - int(($centlineY-[bo])/$fixedHeight)*$fixedHeight - $fixedHeight}]
    set expected [list [list [bo] $expectedY [xw 20] $fixedHeight $fixedAscent] \
                       [list [bo] $expectedY [xw 20] $fixedHeight $fixedAscent] \
	               [list [bo] [expr {$expectedY+$fixedHeight}] [xw 19] $fixedHeight $fixedAscent]]
    set res [list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.21]]

    lequal $res $expected
} {1}
test textDisp-20.3 {FindDLine} {
    .t yview 100.0
    .t yview 49.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 57.0]
} [list [list [bo] [yline 2] [xw 20] $fixedHeight $fixedAscent] \
        [list [bo] [yline 3] [xw 19] $fixedHeight $fixedAscent] \
	{}]
test textDisp-20.4 {FindDLine} {
    .t yview 100.0
    .t yview 42.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.24] [.t dlineinfo 50.40]
} [list [list [bo] [yline 9] [xw 20] $fixedHeight $fixedAscent] \
        [list [bo] [yline 10] [xw 19] $fixedHeight $fixedAscent] \
	{}]
.t config -wrap none
test textDisp-20.5 {FindDLine} {
    .t yview 100.0
    .t yview 48.0
    list [.t dlineinfo 50.0] [.t dlineinfo 50.20] [.t dlineinfo 50.40]
} [list [list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent] \
        [list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent] \
	[list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent]]

.t config -wrap word
test textDisp-21.1 {TkTextPixelIndex} {
    .t yview 48.0
    set off [expr {[bo]+3}]
    list [.t index @-10,-10] [.t index @$off,$off] [.t index @[expr {[xchar 2]+2}],$off] \
	    [.t index @[expr {[xchar 14]+1}],$off] [.t index @[xchar 5],[yline 5]]
} {48.0 48.0 48.2 48.7 50.45}
.t insert end \n
test textDisp-21.2 {TkTextPixelIndex} {
    .t yview 195.0
    set off [expr {[xchar 1]+1}]
    list [.t index @$off,[expr {[yline 6]+2}]] \
         [.t index @$off,[expr {[yline 7]+2}]] \
	 [.t index @$off,[expr {[yline 8]+2}]] \
	 [.t index @$off,1002]
} {197.1 198.1 199.1 201.0}
test textDisp-21.3 {TkTextPixelIndex, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
    .t insert end "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    .t xview scroll 2 units
    set off [expr {[yline 1]+4}]
    list [.t index @-5,$off] [.t index @[expr {[xchar 1]-2}],$off] [.t index @[expr {[xchar 4]+2}],[expr {[yline 2]+2}]]
} {1.2 1.2 2.6}
test textDisp-21.4 {count -displaylines regression} {
    set message {
   QOTW:  "C/C++, which is used by 16% of users, is the most popular programming language, but Tcl, used by 0%, seems to be the language of choice for the highest scoring users."
(new line)
Use the Up (cursor) key to scroll up one line at a time.  At the second press, the cursor either gets locked or jumps several lines.

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
.tt.u insert end $message
.tt.u mark set insert 3.10
tkwait visibility .tt.u
set res [.tt.u count -displaylines 3.10 2.173]
destroy .tt
unset message
set res
} -1

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
updateText
.t tag add x 50.1
test textDisp-22.1 {TkTextCharBbox} {textfonts} {
    .t config -wrap word
    .t yview 48.0
    list [.t bbox 47.2] [.t bbox 48.0] [.t bbox 50.5] [.t bbox 50.40] \
	    [.t bbox 58.0]
} [list {} [list 3 3 7 $fixedHeight] [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] [list 3 [expr {3+4*$fixedHeight}] 7 $fixedHeight] {}]




test textDisp-22.2 {TkTextCharBbox} {textfonts} {
    .t config -wrap none
    .t yview 48.0
    list [.t bbox 50.5] [.t bbox 50.40] [.t bbox 57.0]
} [list [list 38 [expr {3+2*$fixedHeight}] 7 $fixedHeight] {} [list 3 [expr {3+9*$fixedHeight}] 7 $fixedHeight]]


test textDisp-22.3 {TkTextCharBbox, cut-off lines} {textfonts} {



    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height-1}]
    updateText


    list [.t bbox 19.1] [.t bbox 20.1]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] [list 10 [expr {3+10*$fixedHeight}] 7 3]]

test textDisp-22.4 {TkTextCharBbox, cut-off lines} {textfonts} {



    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height+1}]
    updateText


    list [.t bbox 19.1] [.t bbox 20.1]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] [list 10 [expr {3+10*$fixedHeight}] 7 5]]

test textDisp-22.5 {TkTextCharBbox, cut-off char} {textfonts} {


    .t config -wrap none
    .t yview 10.0
    wm geom . [expr {$width-95}]x$height
    updateText
    .t bbox 15.6
} [list 45 [expr {3+5*$fixedHeight}] 7 $fixedHeight]
test textDisp-22.6 {TkTextCharBbox, line visible but not char} {textfonts} {



    .t config -wrap char
    .t yview 10.0
    .t tag add big 20.2 20.5
    wm geom . ${width}x[expr {$height+3}]
    updateText



    list [.t bbox 19.1] [.t bbox 20.1] [.t bbox 20.2]
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] {} [list 17 [expr {3+10*$fixedHeight}] 14 7]]

wm geom . {}
updateText
test textDisp-22.7 {TkTextCharBbox, different character sizes} {textfonts} {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 12.2 12.5
    updateText
    list [.t bbox 12.1] [.t bbox 12.2]
} [list [list 10 [expr {3 + 2*$fixedHeight + $ascentDiff}] 7 $fixedHeight] [list 17 [expr {3+ 2*$fixedHeight}] 14 27]]

.t tag remove big 1.0 end
test textDisp-22.8 {TkTextCharBbox, horizontal scrolling} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
    .t insert end "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    .t xview scroll 4 units
    list [.t bbox 1.3] [.t bbox 1.4] [.t bbox 2.3] [.t bbox 2.4] \
	    [.t bbox 2.23] [.t bbox 2.24]
} [list {} [list 3 3 7 $fixedHeight] {} [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 136 [expr {$fixedDiff + 16}] 7 $fixedHeight] {}]





test textDisp-22.9 {TkTextCharBbox, handling of spacing} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijkl\nmnopqrstuvwzyz"
    .t tag configure spacing -spacing1 8 -spacing3 2
    .t tag add spacing 1.0 end
    frame .t.f1 -width 10 -height 4 -bg black
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    updateText
    list [.t bbox .t.f1] [.t bbox .t.f2] [.t bbox .t.f3] [.t bbox .t.f4] \
	    [.t bbox 1.1] [.t bbox 2.9]
} [list [list 24 11 10 4] [list 55 [expr {$fixedDiff/2 + 15}] 10 4] [list 10 [expr {2*$fixedDiff + 43}] 10 4] [list 76 [expr {2*$fixedDiff + 40}] 10 4] [list 10 11 7 $fixedHeight] [list 69 [expr {$fixedDiff + 34}] 7 $fixedHeight]]





.t tag delete spacing
test textDisp-22.10 {TkTextCharBbox, handling of elided lines} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 2.8 2.13
    .t tag add hidden 6.8 7.13
    .t tag configure hidden -elide true
    updateText
    list \
        [expr {[lindex [.t bbox 2.9]  0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.10] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.13] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 6.9]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.10] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.13] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.14] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.15] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.0]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.1]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.12] 0] - [lindex [.t bbox 6.8] 0]}]
} [list 0 0 0 0 0 0 0 0 0 0 0]
test textDisp-22.11 {TkTextCharBbox, handling of wrapped elided lines} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line _$i - Lines .$i - Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 1.30 2.5
    .t tag configure hidden -elide true
    updateText
    list \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.4]  0]}] \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.5]  0]}]
} [list 0 0]

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
updateText
test textDisp-23.1 {TkTextDLineInfo} {textfonts} {
    .t config -wrap word
    .t yview 48.0
    list [.t dlineinfo 47.3] [.t dlineinfo 48.0] [.t dlineinfo 50.40] \
	    [.t dlineinfo 56.0]
} [list {} [list 3 3 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {4*$fixedDiff + 55}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] {}]




test textDisp-23.2 {TkTextDLineInfo} {textfonts} {
    .t config -bd 4 -wrap word
    updateText
    .t yview 48.0
    .t dlineinfo 50.40
} [list 7 [expr {4*$fixedDiff + 59}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]
.t config -bd 0
test textDisp-23.3 {TkTextDLineInfo} {textfonts} {
    .t config -wrap none
    updateText
    .t yview 48.0
    list [.t dlineinfo 50.40] [.t dlineinfo 57.3]
} [list [list 3 [expr {2*$fixedDiff + 29}] 371 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]

test textDisp-23.4 {TkTextDLineInfo, cut-off lines} {textfonts} {



    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height-1}]
    updateText


    list [.t dlineinfo 19.0] [.t dlineinfo 20.0]
} [list [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {10*$fixedDiff + 133}] 49 3 [expr {$fixedDiff + 10}]]]

test textDisp-23.5 {TkTextDLineInfo, cut-off lines} {textfonts} {



    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height+1}]
    updateText


    list [.t dlineinfo 19.0] [.t dlineinfo 20.0]
} [list [list 3 [expr {9*$fixedDiff + 120}] 49 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {10*$fixedDiff + 133}] 49 5 [expr {$fixedDiff + 10}]]]

wm geom . {}
updateText
test textDisp-23.6 {TkTextDLineInfo, horizontal scrolling} {textfonts} {
    .t config -wrap none
    .t delete 1.0 end
    .t insert end "First line\n"
    .t insert end "Second line is a very long one that doesn't all fit.\n"
    .t insert end "Third"
    .t xview scroll 6 units
    updateText
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list -39 3 70 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list -39 [expr {$fixedDiff + 16}] 364 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list -39 [expr {2*$fixedDiff + 29}] 35 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]


.t xview moveto 0
test textDisp-23.7 {TkTextDLineInfo, centering} {textfonts} {
    .t config -wrap word
    .t delete 1.0 end
    .t insert end "First line\n"
    .t insert end "Second line is a very long one that doesn't all fit.\n"
    .t insert end "Third"
    .t tag configure x -justify center
    .t tag configure y -justify right
    .t tag add x 1.0
    .t tag add y 3.0
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list 38 3 70 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {$fixedDiff + 16}] 119 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 108 [expr {4*$fixedDiff + 55}] 35 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]


.t tag delete x y

test textDisp-24.1 {TkTextCharLayoutProc} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.2 {TkTextCharLayoutProc} {textfonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"





    wm geom . [expr {$width+1}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.3 {TkTextCharLayoutProc} {textfonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width-1}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.4 {TkTextCharLayoutProc, newline not visible} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 01234567890123456789\n012345678901234567890
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20] [.t bbox 2.20]

} [list [list 136 3 7 $fixedHeight] [list 143 3 0 $fixedHeight] [list 3 [expr {2*$fixedDiff + 29}] 7 $fixedHeight]]

test textDisp-24.5 {TkTextCharLayoutProc, char doesn't fit, newline not visible} {unix textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 0\n1\n



    wm geom . 110x$height
    updateText
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 2.0]

} [list [list 3 3 4 $fixedHeight] [list 7 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 4 $fixedHeight]]

test textDisp-24.6 {TkTextCharLayoutProc, line ends with space} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.7 {TkTextCharLayoutProc, line ends with space} {textfonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"





    wm geom . [expr {$width+1}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.8 {TkTextCharLayoutProc, line ends with space} {textfonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-1}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.9 {TkTextCharLayoutProc, line ends with space} {textfonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-6}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 5 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.10 {TkTextCharLayoutProc, line ends with space} {textfonts} {



    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-7}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 4 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.11 {TkTextCharLayoutProc, line ends with space that doesn't quite fit} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "01234567890123456789 \nabcdefg"


    wm geom . [expr {$width-2}]x$height
    updateText
    set result {}
    lappend result [.t bbox 1.21] [.t bbox 2.0]
    .t mark set insert 1.21
    lappend result [.t bbox 1.21] [.t bbox 2.0]
} [list [list 145 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 145 3 0 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]





test textDisp-24.12 {TkTextCharLayoutProc, tab causes wrap} {textfonts} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghi"
    .t mark set insert 1.4
    .t insert insert \t\t\t


    list [.t bbox {insert -1c}] [.t bbox insert]
} [list [list 115 3 30 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.13 {TkTextCharLayoutProc, -wrap none} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] {}]
test textDisp-24.14 {TkTextCharLayoutProc, -wrap none} {textfonts} {



    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width+1}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 5 $fixedHeight]]

test textDisp-24.15 {TkTextCharLayoutProc, -wrap none} {textfonts} {



    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width-1}]x$height
    updateText


    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 143 3 3 $fixedHeight]]

test textDisp-24.16 {TkTextCharLayoutProc, no chars fit} {textfonts} {
    if {$tcl_platform(platform) == "windows"} {
	wm overrideredirect . 1
    }
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"


    wm geom . 103x$height
    updateText
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]

} [list [list 3 3 1 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 1 $fixedHeight] [list 3 [expr {2*$fixedDiff + 29}] 1 $fixedHeight]]

if {$tcl_platform(platform) == "windows"} {
    wm overrideredirect . 0
}
test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a line that wraps around"
    wm geom . {}
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]

test textDisp-24.18 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    updateText
    list [.t bbox 1.15] [.t bbox 1.16] [.t bbox 1.17]

} [list [list 108 3 7 $fixedHeight] [list 115 3 28 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]


test textDisp-24.19 {TkTextCharLayoutProc, -wrap word} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    updateText
    list [.t bbox 1.14] [.t bbox 1.15] [.t bbox 1.16]
} [list [list 101 3 7 $fixedHeight] [list 108 3 7 $fixedHeight] [list 115 3 28 $fixedHeight]]


test textDisp-24.20 {TkTextCharLayoutProc, vertical offset} {textfonts} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    set result {}
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure up -offset 6
    .t tag add up 2.1
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure  up -offset -2
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag delete up
    set result



} [list [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 10 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 19}] [expr {$fixedDiff + 16}]] [list 10 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 42 [expr {$fixedDiff + 15}] [expr {$fixedDiff + 10}]]]


.t configure -width 30
updateText
test textDisp-24.21 {TkTextCharLayoutProc, word breaks} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text xxxxxxx yyyyy zzzzzzz qqqqq rrrr ssss tt u vvvvv"
    frame .t.f -width 30 -height 20 -bg black
    .t window create 1.36 -window .t.f
    .t bbox 1.26
} [list 3 [expr {$fixedDiff/2 + 19}] 7 $fixedHeight]
test textDisp-24.22 {TkTextCharLayoutProc, word breaks} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    frame .t.f -width 30 -height 20 -bg black
    .t insert 1.0 "Sample text xxxxxxx yyyyyyy"
    .t window create end -window .t.f
    .t insert end "zzzzzzz qqqqq rrrr ssss tt u vvvvv"
    .t bbox 1.28
} [list 33 [expr {$fixedDiff/2 + 19}] 7 $fixedHeight]
test textDisp-24.23 {TkTextCharLayoutProc, word breaks} {textfonts} {
    .t configure -wrap word
    .t delete 1.0 end
    frame .t.f -width 30 -height 20 -bg black
    .t insert 1.0 "Sample text xxxxxxx yyyyyyy "
    .t insert end "zzzzzzz qqqqq rrrr ssss tt"
    .t window create end -window .t.f
    .t insert end "u vvvvv"
    .t bbox .t.f
} [list 3 [expr {2*$fixedDiff + 29}] 30 20]
catch {destroy .t.f}
.t configure -width 20
updateText





test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
    .t delete 1.0 end
    .t tag configure x -justify center
    .t insert 1.0 aa\tbb\tcc\tdd\t
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.10]
} [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]]

test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -constraints {textfonts failsOnXQuarz} -setup {
    text .tt -tabs {40 right} -wrap none -font $fixedFont
    pack .tt
} -body {
    .tt insert end \t9\n\t99\n\t999
    updateText



    list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3]
} -cleanup {
    destroy .tt
} -result [list [list 38 5 7 $fixedHeight] [list 38 20 7 $fixedHeight] [list 38 35 7 $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
    -tabs 100
updateText
test textDisp-25.1 {CharBboxProc procedure, check tab width} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\td\tfgh
    list [.t bbox 1.3] [.t bbox 1.5] [.t bbox 1.6]
} [list [list 21 1 79 $fixedHeight] [list 107 1 93 $fixedHeight] [list 200 1 7 $fixedHeight]]



.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
	-tabs {}
updateText
test textDisp-26.1 {AdjustForTab procedure, no tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
	    [lindex [.t bbox 1.14] 0]
} [list 56 126 168]


test textDisp-26.1.2 {AdjustForTab procedure, no tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    .t configure -tabstyle wordprocessor
    set res [list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
      [lindex [.t bbox 1.14] 0]]
    .t configure -tabstyle tabular
    set res
} [list 56 168 224]


test textDisp-26.2 {AdjustForTab procedure, not enough tabs specified} {
    .t delete 1.0 end
    .t insert 1.0 a\tb\tc\td
    .t tag delete x
    .t tag configure x -tabs 40
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \







|









|

|




|
>
>
>
>
|



|
>
>
|
>
>
>



|
>
>
|
<
>
|
>
>
>



|
>
>
|
<
>
|
>
>


|
|

|
|
>
>
>




|
>
>
>
|
<
>

|
|



|

|
>

|







|
>
>
>
>
>
|













|


|
>
>
>
>
>

|








|













|







|













|
|




|
>
>
>
>
|
|
|


|

|

|


|
>
|
>
>
>



|
>
>
|
<
>
|
>
>
>



|
>
>
|
<
>

|
|






|

|
>
>

|










|
>
>


|




|
>
|
>
>
>



>
>
>
>
>
|
|
>
>
|
<
>
|
>
>
>




|
>
>
|
<
>
|




|

>
|
>
|



>
>
>
|
|

>
|
>
|




|

|
>
|
>
>
>



>
>
>
>
>
|
|
>
>
|
<
>
|
>
>
>




|
>
>
|
<
>
|
>
>
>




|
>
>
|
<
>
|
>
>
>




|
>
>
|
<
>
|


|
>
>
|
|
<
|


|
>
>
>
>
>
|





>
>
|
<
>
|




|

|
|
>
>
>




|
>
>
|
<
>
|
>
>
>




|
>
>
|
<
>
|
|





>
>
|
|

>
|
>
|


|




|

|
>
|




|
|
>
|
>
>
|




|

|
>
>
|








|



>
>
>
|
>
>

|
|






|
|






|
|
|


|





|


|
>
>
>
>
>
|





|
>
|




|
>
>
>
|


|

|

|
|



|
>
>

|

|
|




|
>
>
|







|
>
>







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
.tt.u insert end $message
.tt.u mark set insert 3.10
tkwait visibility .tt.u
set res [.tt.u count -displaylines 3.10 2.173]
destroy .tt
unset message
set res
} {-1}

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
update
.t tag add x 50.1
test textDisp-22.1 {TkTextCharBbox} {
    .t config -wrap word
    .t yview 48.0
    list [.t bbox 47.2] [.t bbox 48.0] [.t bbox 50.5] [.t bbox 50.40] \
	    [.t bbox 58.0]
} [list {} \
        [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 5] $fixedWidth $fixedHeight] \
	{}]
test textDisp-22.2 {TkTextCharBbox} {
    .t config -wrap none
    .t yview 48.0
    list [.t bbox 50.5] [.t bbox 50.40] [.t bbox 57.0]
} [list [list [xchar 5] [yline 3] $fixedWidth $fixedHeight] \
        {} \
	[list [xchar 0] [yline 10] $fixedWidth $fixedHeight]]
test textDisp-22.3 {TkTextCharBbox, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height-1}]
    update
    set expected [list [list [xchar 1] [yline 10] $fixedWidth $fixedHeight] \
                       [list [xchar 1] [yline 11] $fixedWidth [expr {($height-1)-$oriHeight}]]]
    lequal [list [.t bbox 19.1] [.t bbox 20.1]] $expected

} {1}
test textDisp-22.4 {TkTextCharBbox, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height+1}]
    update
    set expected [list [list [xchar 1] [yline 10] $fixedWidth $fixedHeight] \
                       [list [xchar 1] [yline 11] $fixedWidth [expr {($height+1)-$oriHeight}]]]
    lequal [list [.t bbox 19.1] [.t bbox 20.1]] $expected

} {1}
test textDisp-22.5 {TkTextCharBbox, cut-off char} {
    wm geometry . {}
    update
    .t config -wrap none
    .t yview 10.0
    wm geom . [expr {$width-(20-7)*$fixedWidth}]x$height
    update
    .t bbox 15.6
} [list [xchar 6] [yline 6] $fixedWidth $fixedHeight]
test textDisp-22.6 {TkTextCharBbox, line visible but not char} haveBigFontTwiceLargerThanTextFont {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t config -wrap char
    .t yview 10.0
    .t tag add big 20.2 20.5
    wm geom . ${width}x[expr {$height+3}]
    update
    set expected [list [list [xchar 1] [yline 10] $fixedWidth $fixedHeight] \
                       {} \
	               [list [xchar 2] [yline 11] [font measure $bigFont "n"] [expr {($height+3)-$oriHeight}]]]
    lequal [list [.t bbox 19.1] [.t bbox 20.1] [.t bbox 20.2]] $expected

} {1}
wm geom . {}
update
test textDisp-22.7 {TkTextCharBbox, different character sizes} haveBigFontTwiceLargerThanTextFont {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 12.2 12.5
    update
    list [.t bbox 12.1] [.t bbox 12.2]
} [list [list [xchar 1] [expr {[yline 3]+$ascentDiff}] $fixedWidth $fixedHeight] \
        [list [xchar 2] [yline 3] [font measure $bigFont "n"] $bigHeight]]
.t tag remove big 1.0 end
test textDisp-22.8 {TkTextCharBbox, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
    .t insert end "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    .t xview scroll 4 units
    list [.t bbox 1.3] [.t bbox 1.4] [.t bbox 2.3] [.t bbox 2.4] \
	    [.t bbox 2.23] [.t bbox 2.24]
} [list {} \
        [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
	{} \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 19] [yline 2] $fixedWidth $fixedHeight] \
	{}]
test textDisp-22.9 {TkTextCharBbox, handling of spacing} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijkl\nmnopqrstuvwzyz"
    .t tag configure spacing -spacing1 8 -spacing3 2
    .t tag add spacing 1.0 end
    frame .t.f1 -width 10 -height 4 -bg black
    frame .t.f2 -width 10 -height 4 -bg black
    frame .t.f3 -width 10 -height 4 -bg black
    frame .t.f4 -width 10 -height 4 -bg black
    .t window create 1.3 -window .t.f1 -align top
    .t window create 1.7 -window .t.f2 -align center
    .t window create 2.1 -window .t.f3 -align bottom
    .t window create 2.10 -window .t.f4 -align baseline
    update
    list [.t bbox .t.f1] [.t bbox .t.f2] [.t bbox .t.f3] [.t bbox .t.f4] \
	    [.t bbox 1.1] [.t bbox 2.9]
} [list [list [xchar 3] [expr {[yline 1]+8}] 10 4] \
        [list [expr {[xchar 3]+10+[xw 3]}] [expr {[yline 1]+8+($fixedHeight-4)/2}] 10 4] \
	[list [xchar 1] [expr {[yline 2]+8+2+8+($fixedHeight-4)}] 10 4] \
	[list [expr {[xchar 1]+10+[xw 8]}] [expr {[yline 2]+8+2+8+($fixedAscent-4)}] 10 4] \
	[list [xchar 1] [expr {[yline 1]+8}] $fixedWidth $fixedHeight] \
	[list [expr {[xchar 1]+10+[xw 7]}] [expr {[yline 2]+8+2+8}] $fixedWidth $fixedHeight]]
.t tag delete spacing
test textDisp-22.10 {TkTextCharBbox, handling of elided lines} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 2.8 2.13
    .t tag add hidden 6.8 7.13
    .t tag configure hidden -elide true
    update
    list \
        [expr {[lindex [.t bbox 2.9]  0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.10] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 2.13] 0] - [lindex [.t bbox 2.8] 0]}] \
        [expr {[lindex [.t bbox 6.9]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.10] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.13] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.14] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 6.15] 0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.0]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.1]  0] - [lindex [.t bbox 6.8] 0]}] \
        [expr {[lindex [.t bbox 7.12] 0] - [lindex [.t bbox 6.8] 0]}]
} [list 0 0 0 0 0 0 0 0 0 0 0]
test textDisp-22.11 {TkTextCharBbox, handling of wrapped elided lines} {
    .t configure -wrap char
    .t delete 1.0 end
    for {set i 1} {$i < 10} {incr i} {
        .t insert end "Line $i - Line _$i - Lines .$i - Line [format %c [expr {64+$i}]]\n"
    }
    .t tag add hidden 1.30 2.5
    .t tag configure hidden -elide true
    update
    list \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.4]  0]}] \
        [expr {[lindex [.t bbox 1.30] 0] - [lindex [.t bbox 2.5]  0]}]
} [list 0 0]

.t delete 1.0 end
.t insert end "Line 1"
for {set i 2} {$i <= 200} {incr i} {
    .t insert end "\nLine $i"
}
.t configure -wrap word
.t delete 50.0 51.0
.t insert 50.0 "This is a long line, one that will wrap around twice.\n"
update
test textDisp-23.1 {TkTextDLineInfo} {
    .t config -wrap word
    .t yview 48.0
    list [.t dlineinfo 47.3] [.t dlineinfo 48.0] [.t dlineinfo 50.40] \
	    [.t dlineinfo 56.0]
} [list {} \
        [list [bo] [yline 1] [xw 7] $fixedHeight $fixedAscent] \
	[list [bo] [yline 5] [xw 13] $fixedHeight $fixedAscent] \
	{}]
.t config -bd 4
test textDisp-23.2 {TkTextDLineInfo} {
    .t config -wrap word
    update
    .t yview 48.0
    .t dlineinfo 50.40
} [list [bo] [yline 5] [xw 13] $fixedHeight $fixedAscent]
.t config -bd 0
test textDisp-23.3 {TkTextDLineInfo} {
    .t config -wrap none
    update
    .t yview 48.0
    list [.t dlineinfo 50.40] [.t dlineinfo 57.3]
} [list [list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent] \
        [list [bo] [yline 10] [xw 7] $fixedHeight $fixedAscent]]
test textDisp-23.4 {TkTextDLineInfo, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height-1}]
    update
    set expected [list [list [bo] [yline 10] [xw 7] $fixedHeight $fixedAscent] \
                       [list [bo] [yline 11] [xw 7] [expr {($height-1)-$oriHeight}] $fixedAscent]]
    lequal [list [.t dlineinfo 19.0] [.t dlineinfo 20.0]] $expected

} {1}
test textDisp-23.5 {TkTextDLineInfo, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t config -wrap char
    .t yview 10.0
    wm geom . ${width}x[expr {$height+1}]
    update
    set expected [list [list [bo] [yline 10] [xw 7] $fixedHeight $fixedAscent] \
                       [list [bo] [yline 11] [xw 7] [expr {($height+1)-$oriHeight}] $fixedAscent]]
    lequal [list [.t dlineinfo 19.0] [.t dlineinfo 20.0]] $expected

} {1}
wm geom . {}
update
test textDisp-23.6 {TkTextDLineInfo, horizontal scrolling} {
    .t config -wrap none
    .t delete 1.0 end
    .t insert end "First line\n"
    .t insert end "Second line is a very long one that doesn't all fit.\n"
    .t insert end "Third"
    .t xview scroll 6 units
    update
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list [expr {[xw -6]+[bo]}] [yline 1] [xw 10] $fixedHeight $fixedAscent] \
        [list [expr {[xw -6]+[bo]}] [yline 2] [xw 52] $fixedHeight $fixedAscent] \
	[list [expr {[xw -6]+[bo]}] [yline 3] [xw 5] $fixedHeight $fixedAscent]]
.t xview moveto 0
test textDisp-23.7 {TkTextDLineInfo, centering} {
    .t config -wrap word
    .t delete 1.0 end
    .t insert end "First line\n"
    .t insert end "Second line is a very long one that doesn't all fit.\n"
    .t insert end "Third"
    .t tag configure x -justify center
    .t tag configure y -justify right
    .t tag add x 1.0
    .t tag add y 3.0
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list [expr {[bo]+[xe 10]/2}] [yline 1] [xw 10] $fixedHeight $fixedAscent] \
        [list [bo] [yline 2] [xw 17] $fixedHeight $fixedAscent] \
	[list [xcharr 5] [yline 5] [xw 5] $fixedHeight $fixedAscent]]
.t tag delete x y

test textDisp-24.1 {TkTextCharLayoutProc} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.2 {TkTextCharLayoutProc} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    # be tolerant about borderwidth et al. - don't let another char fit on the line
    set wi $width
    while {$wi+1-$oriWidth >= $fixedWidth} {
        incr wi -$fixedWidth
    }
    wm geom . [expr {$wi+1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($wi+1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.3 {TkTextCharLayoutProc} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width-1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($width-1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.4 {TkTextCharLayoutProc, newline not visible} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 01234567890123456789\n012345678901234567890
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20] [.t bbox 2.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 20] [yline 1] 0 $fixedHeight] \
	[list [xchar 0] [yline 3] $fixedWidth $fixedHeight]]
test textDisp-24.5 {TkTextCharLayoutProc, char doesn't fit, newline not visible} {nonwin} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 0\n1\n
    # set text widget width to 1-char width minus [bo] pixels
    # note: windows refuses to shrink enough therefore the constraint
    set wi [expr {[winfo width .f]+[bo]+[xw 1]}]
    wm geom . ${wi}x$height
    update
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 2.0]
} [list [list [xchar 0] [yline 1] [expr {$fixedWidth-[bo]}] $fixedHeight] \
        [list [expr {[xchar 1]-[bo]}] [yline 1] 0 $fixedHeight] \
	[list [xchar 0] [yline 2] [expr {$fixedWidth-[bo]}] $fixedHeight]]
test textDisp-24.6 {TkTextCharLayoutProc, line ends with space} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.7 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    # be tolerant about borderwidth et al. - don't let another char fit on the line
    set wi $width
    while {$wi+1-$oriWidth >= $fixedWidth} {
        incr wi -$fixedWidth
    }
    wm geom . [expr {$wi+1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($wi+1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.8 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($width-1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.9 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-6}]x$height
    update
    set expected [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
                       [list [xchar 1] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.10 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a b c d e f g h i j k l m n o p"
    wm geom . [expr {$width-7}]x$height
    update
    set expected [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
                       [list [xchar 1] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.11 {TkTextCharLayoutProc, line ends with space that doesn't quite fit} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "0123456789012345678 \nabcdefg"
    # set text widget width to 2 pixels more than 20-char width
    set wi [expr {[winfo width .f]+2*[bo]+[xw 20]+2}]
    wm geom . ${wi}x$height
    update

    set result [list [.t bbox 1.21] [.t bbox 2.0]]
    .t mark set insert 1.21
    lappend result [.t bbox 1.21] [.t bbox 2.0]
} [list [list [xchar 20] [yline 1] 2 $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 20] [yline 1] 2 $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
wm geom . {}
update
test textDisp-24.12 {TkTextCharLayoutProc, tab causes wrap} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghi"
    .t mark set insert 1.4
    .t insert insert \t\t\t
    set expected [list [list [expr {[xchar 0]+2*8*$fixedWidth}] [yline 1] [expr {[winfo width .t]-([xchar 0]+2*8*$fixedWidth)-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox {insert -1c}] [.t bbox insert]] $expected

} {1}
test textDisp-24.13 {TkTextCharLayoutProc, -wrap none} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] {}]
test textDisp-24.14 {TkTextCharLayoutProc, -wrap none} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width+1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
                       [list [xchar 20] [yline 1] [expr {$width+1-$oriWidth}] $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.15 {TkTextCharLayoutProc, -wrap none} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . [expr {$width-1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
                       [list [xchar 20] [yline 1] [expr {$width-1-$oriWidth}] $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected

} {1}
test textDisp-24.16 {TkTextCharLayoutProc, no chars fit} {
    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    # set text widget width to [bo] pixels (no chars fit in the widget at all)
    set wi [expr {[winfo width .f]+[bo]}]
    wm geom . ${wi}x$height
    update
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list [xchar 0] [yline 1] 1 $fixedHeight] \
        [list [xchar 0] [yline 2] 1 $fixedHeight] \
	[list [xchar 0] [yline 3] 1 $fixedHeight]]
if {[tk windowingsystem] eq "win32"} {
    wm overrideredirect . 0
}
test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a line that wraps around"
    wm geom . {}
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.18 {TkTextCharLayoutProc, -wrap word} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    update
    list [.t bbox 1.15] [.t bbox 1.16] [.t bbox 1.17] [.t bbox 1.21]
} [list [list [xchar 15] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 16] [yline 1] [xe 16] $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 4] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.19 {TkTextCharLayoutProc, -wrap word} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    update
    list [.t bbox 1.14] [.t bbox 1.15] [.t bbox 1.16]
} [list [list [xchar 14] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 15] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar 16] [yline 1] [xe 16] $fixedHeight]]
test textDisp-24.20 {TkTextCharLayoutProc, vertical offset} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2\nLine 3"
    set result {}
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure up -offset 6
    .t tag add up 2.1
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag configure up -offset -2
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag delete up
    set result
} [list [list [xchar 1] [yline 2] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] [xw 6] $fixedHeight $fixedAscent] \
	[list [xchar 1] [yline 2] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] [xw 6] [expr {$fixedHeight+6}] [expr {$fixedAscent+6}]] \
	[list [xchar 1] [expr {[yline 2]+2}] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] [xw 6] [expr {$fixedHeight+2}] $fixedAscent]]
.t configure -width 30
update
test textDisp-24.21 {TkTextCharLayoutProc, word breaks} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text xxxxxxx yyyyy zzzzzzz qqqqq rrrr ssss tt u vvvvv"
    frame .t.f -width 30 -height 20 -bg black
    .t window create 1.36 -window .t.f
    .t bbox 1.26
} [list [xchar 0] [expr {[yline 2]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]
test textDisp-24.22 {TkTextCharLayoutProc, word breaks} {
    .t configure -wrap word
    .t delete 1.0 end
    frame .t.f -width 30 -height 20 -bg black
    .t insert 1.0 "Sample text xxxxxxx yyyyyyy"
    .t window create end -window .t.f
    .t insert end "zzzzzzz qqqqq rrrr ssss tt u vvvvv"
   .t bbox 1.28
} [list [expr {[bo]+30}] [expr {[yline 2]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]
test textDisp-24.23 {TkTextCharLayoutProc, word breaks} {
    .t configure -wrap word
    .t delete 1.0 end
    frame .t.f -width 50 -height 20 -bg black
    .t insert 1.0 "Sample text xxxxxxx yyyyyyy "
    .t insert end "zzzzzzz qqqqq rrrr ssss tt"
    .t window create end -window .t.f
    .t insert end "u vvvvv"
    .t bbox .t.f
} [list [xchar 0] [yline 3] 50 20]
catch {destroy .t.f}
.t configure -width 20
update
# Next test is currently constrained to not run on mac (aqua) because on
# aqua it fails due to wrong implementation of tabs with right justification
# (the text is not rendered at all). This is a bug.
# Moreover, this test does not pass on any platform at this point with the revised
# implementation (see [a34b49f8c6]), therefore the 'knownBug' constraint.
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {knownBug} {
    .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 [expr {[bo]+[xe 8]/2}] [yline 1] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 8]/2+[xw 7]}] [yline 1] $fixedWidth $fixedHeight]]
test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -setup {
    text .tt -tabs {40 right} -wrap none -font $fixedFont
    pack .tt
} -body {
    .tt insert end \t9\n\t99\n\t999
    update
    set expected [list [list [expr {[bo .tt]+40-$fixedWidth}] [yline 1 .tt] $fixedWidth $fixedHeight] \
                       [list [expr {[bo .tt]+40-$fixedWidth}] [yline 2 .tt] $fixedWidth $fixedHeight] \
                       [list [expr {[bo .tt]+40-$fixedWidth}] [yline 3 .tt] $fixedWidth $fixedHeight]]
    lequal [list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3]] $expected
} -cleanup {
    destroy .tt
} -result {1}

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 \
    -tabs 100
update
test textDisp-25.1 {CharBboxProc procedure, check tab width} {
    .t delete 1.0 end
    .t insert 1.0 abc\td\tfgh
    list [.t bbox 1.3] [.t bbox 1.5] [.t bbox 1.6]
} [list [list [xchar 3] [yline 1] [expr {100-3*$fixedWidth}] $fixedHeight] \
        [list [expr {[bo]+100+$fixedWidth}] [yline 1] [expr {200-(100+$fixedWidth)}] $fixedHeight] \
	[list [expr {[bo]+200}] [yline 1] $fixedWidth $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 -pady 0 \
	-tabs {}
update
test textDisp-26.1 {AdjustForTab procedure, no tabs} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
	    [lindex [.t bbox 1.14] 0]
} [list [expr {[bo]+8*$fixedWidth}] \
        [expr {[bo]+2*8*$fixedWidth+2*$fixedWidth}] \
	[expr {[bo]+3*8*$fixedWidth}]]
test textDisp-26.1.2 {AdjustForTab procedure, no tabs} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    .t configure -tabstyle wordprocessor
    set res [list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
      [lindex [.t bbox 1.14] 0]]
    .t configure -tabstyle tabular
    set res
} [list [expr {[bo]+8*$fixedWidth}] \
        [expr {[bo]+3*8*$fixedWidth}] \
	[expr {[bo]+4*8*$fixedWidth}]]
test textDisp-26.2 {AdjustForTab procedure, not enough tabs specified} {
    .t delete 1.0 end
    .t insert 1.0 a\tb\tc\td
    .t tag delete x
    .t tag configure x -tabs 40
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
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
    .t insert 1.0 a\t1.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} 120
test textDisp-26.6 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1,456.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.7] 0
} 120
test textDisp-26.7 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.456.234,7
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.11] 0
} 120
test textDisp-26.8 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\ttest
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} 120
test textDisp-26.9 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} 120
test textDisp-26.10 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} 120
test textDisp-26.11 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tx=1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    lindex [.t bbox 1.5] 0
} 120
test textDisp-26.12 {AdjustForTab procedure, adjusting chunks} {
    .t delete 1.0 end
    .t insert 1.0 a\tx1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    button .b -text "="
    .t window create 1.3 -window .b
    updateText
    lindex [.t bbox 1.5] 0
} 120
test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x




    .t tag configure x -tabs {10 30 center 50 right 120}
    .t tag add x 1.0 end

    list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
	    [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]

} [list 28 56 84 120]
test textDisp-26.13.2 {AdjustForTab procedure, not enough space} {textfonts} {
    .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} -tabstyle wordprocessor
    .t tag add x 1.0 end

    set res [list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
      [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]]
    .t tag configure x -tabstyle tabular
    set res
} [list 28 56 120 190]
test textDisp-26.14 {AdjustForTab procedure, not enough space} {textfonts} {
    .t delete 1.0 end
    .t insert end "a \tb \tc \td \te \tf \tg\n"
    .t insert end "Watch the \tX and the \t\t\tY\n"
    .t tag configure moop -tabs [expr {8*$fixedWidth}]
    .t insert end "Watch the \tX and the \t\t\tY\n" moop
    list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \
	    [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]
} [list 77 224 77 224]
test textDisp-26.14.2 {AdjustForTab procedure, not enough space} {textfonts} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    .t insert end "a \tb \tc \td \te \tf \tg\n"
    .t insert end "Watch the \tX and the \t\t\tY\n"
    .t tag configure moop -tabs [expr {8*$fixedWidth}]
    .t insert end "Watch the \tX and the \t\t\tY\n" moop
    set res [list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \
      [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]]
    .t configure -tabstyle tabular
    set res
} [list 112 56 112 56]

.t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \
	-wrap char
updateText
test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]
} [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 130 5 7 $fixedHeight]]


test textDisp-27.1.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    .t configure -tabstyle wordprocessor
    set res [list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]]
    .t configure -tabstyle tabular
    set res
} [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]


test textDisp-27.2 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcd
    .t tag delete x



    .t tag configure x -tabs 120
    .t tag add x 1.0 end


    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-27.3 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t\t\tbcd
    .t tag delete x



    .t tag configure x -tabs 40
    .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]]

test textDisp-27.4 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t\t\tbcd
    .t tag delete x



    .t tag configure x -tabs {20 center 70 left}
    .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]]

test textDisp-27.5 {SizeOfTab procedure, center alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x



    .t tag configure x -tabs {120 center}
    .t tag add x 1.0 end


    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 135 5 9 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-27.6 {SizeOfTab procedure, center alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {150 center}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 32 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 39 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} {
    .t delete 1.0 end
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with 4 for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {4 + int(0.5 + $tab + $cm)}]
    updateText
    set res [.t bbox 2.23]

    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
} [list -28 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with 4 for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {4 + int(0.5 + $tab + $cm)}]
    updateText
    set res [.t bbox 2.23]
    .t configure -tabstyle tabular
    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
} [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.2 {SizeOfTab procedure, fractional tab interpolation problem} {
    .t delete 1.0 end
    set interpolatetab {1c 2c}
    set precisetab {}
    for {set i 1} {$i < 20} {incr i} {
	lappend precisetab "${i}c"
    }
    .t configure -tabs $interpolatetab -wrap none -width 150
    .t insert 1.0 [string repeat "a\t" 20]
    updateText
    set res [.t bbox 1.20]
    # Now, Tk's interpolated tabs should be the same as
    # non-interpolated.
    .t configure -tabs $precisetab
    updateText
    expr {[lindex $res 0] - [lindex [.t bbox 1.20] 0]}
} 0

.t configure -wrap char -tabs {} -width 20
updateText
test textDisp-27.8 {SizeOfTab procedure, right alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {100 left 140 right}
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list 137 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-27.9 {SizeOfTab procedure, left alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs 120
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]



test textDisp-27.10 {SizeOfTab procedure, numeric alignment} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 a\t123.4
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list 117 5 27 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]

test textDisp-27.11 {SizeOfTab procedure, making tabs at least as wide as a space} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\tdefghijklmnopqrst
    .t tag delete x
    .t tag configure x -tabs 120
    .t tag add x 1.0 end
    list [.t bbox 1.5] [.t bbox 1.6]
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]


proc bizarre_scroll args {
    .t2.t delete 5.0 end
}
test textDisp-28.1 {"yview" option with bizarre scroll command} {
    catch {destroy .t2}

    toplevel .t2
    text .t2.t -width 40 -height 4
    .t2.t insert end "1\n2\n3\n4\n5\n6\n7\n8\n"
    pack .t2.t
    wm geometry .t2 +0+0
    updateText
    .t2.t configure -yscrollcommand bizarre_scroll
    .t2.t yview 100.0
    set result [.t2.t index @0,0]
    updateText
    lappend result [.t2.t index @0,0]


} {6.0 1.0}

test textDisp-29.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}























































































    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText





    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list 0.0 [expr {20.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]



test textDisp-29.2 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}

    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 1 unit
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {1.0*$fixedWidth/300}] [expr {21.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1 - $fixedWidth}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1 - $fixedWidth}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap none -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 1\n
    .t2.t insert end [string repeat "abc" 30]
    updateText
    .t2.t xview scroll 5 unit
    updateText
    .t2.t xview
} [list [expr {5.0/90}] [expr {25.0/90}]]
test textDisp-29.2.2 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 2 unit
    updateText

    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {2.0*$fixedWidth/300}] [expr {22.0*$fixedWidth/300}]] 300x50+[expr {$twbw + $twht + 1 - 2*$fixedWidth}]+[expr {$twbw + $twht + $fixedHeight + 1}] {}]
test textDisp-29.2.3 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 7 pixels
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {7.0/300}] [expr {(20.0*$fixedWidth + 7)/300}]] 300x50+[expr {$twbw + $twht + 1 - 7}]+[expr {$twbw + $twht + $fixedHeight + 1}] [list [expr {$twbw + $twht + $fixedWidth + 1 - 7}] [expr {$twbw + $twht + $fixedHeight + 50 + 1}] $fixedWidth $fixedHeight]]
test textDisp-29.2.4 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 17 pixels
    updateText
    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]
} [list [list [expr {17.0/300}] [expr {(20.0*$fixedWidth + 17)/300}]] 300x50+[expr {$twbw + $twht + 1 - 17}]+[expr {$twbw + $twht + $fixedHeight + 1}] {}]
test textDisp-29.2.5 {miscellaneous: can show last character} {
    catch {destroy .t2}

    toplevel .t2
    wm geometry .t2 121x141+200+200
    text .t2.t -width 5 -height 5 -font {Arial 10} \
      -wrap none -xscrollcommand ".t2.s set" \
      -bd 2 -highlightthickness 0 -padx 1
    .t2.t insert end "WWWWWWWWWWWWi"
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    grid .t2.t -row 0 -column 0 -sticky nsew
    grid .t2.s -row 1 -column 0 -sticky ew
    grid columnconfigure .t2 0 -weight 1
    grid rowconfigure .t2 0 -weight 1
    grid rowconfigure .t2 1 -weight 0
    updateText
    set xv [.t2.t xview]
    set xd [expr {[lindex $xv 1] - [lindex $xv 0]}]
    .t2.t xview moveto [expr {1.0-$xd}]
    set iWidth [lindex [.t2.t bbox end-2c] 2]
    .t2.t xview scroll 2 units
    set iWidth2 [lindex [.t2.t bbox end-2c] 2]

    if {($iWidth == $iWidth2) && $iWidth >= 2} {
	set result "correct"
    } else {
	set result "last character is not completely visible when it should be"
    }


} {correct}
test textDisp-29.3 {miscellaneous: lines wrap but are still too long} {textfonts} {
    catch {destroy .t2}

    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    updateText
    .t2.t xview scroll 200 units
    updateText



    list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]



} [list [list [expr {16.0/30}] 1.0] 300x50+-155+[expr {$fixedDiff + 18}] {}]
test textDisp-30.1 {elidden text joining multiple logical lines} {





    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 3.2

    .t2.t count -displaylines 1.0 end
} 1


test textDisp-30.2 {elidden text joining multiple logical lines} {





    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elidden -elide 1 -background red
    .t2.t tag add elidden 1.2 2.2

    .t2.t count -displaylines 1.0 end
} 2


catch {destroy .t2}

.t configure -height 1
updateText

test textDisp-31.1 {line embedded window height update} failsOnUbuntu {
    set res {}
    .t delete 1.0 end
    .t insert end "abcd\nefgh\nijkl\nmnop\nqrst\nuvwx\nyx"
    frame .t.f -background red -width 100 -height 100
    .t window create 3.0 -window .t.f
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]

test textDisp-31.2 {line update index shifting} failsOnUbuntu {
    set res {}
    .t.f configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res

} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]


test textDisp-31.3 {line update index shifting} failsOnUbuntu {
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    .t.f configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t.f configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res


} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]


test textDisp-31.4 {line embedded image height update} {
    set res {}
    image create photo textest -height 100 -width 10
    .t delete 3.0
    .t image create 3.0 -image textest
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 6}] [expr {$fixedHeight * 7}]]


test textDisp-31.5 {line update index shifting} failsOnUbuntu {
    set res {}
    textest configure -height 100
    updateText
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 100
    .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} 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]
    delay
    lappend res [.t count -ypixels 1.0 end]
    textest configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res


} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]


test textDisp-31.7 {line update index shifting, elided} {
    # The 'update' and 'delay' must be long enough to ensure all
    # asynchronous updates have been performed.
    set res {}
    .t delete 1.0 end
    lappend res [.t count -update -ypixels 1.0 end]
    .t insert 1.0 "abc\nabc"
    .t insert 1.0 "abc\n"
    lappend res [.t count -update -ypixels 1.0 end]
    .t tag configure elide -elide 1
    .t tag add elide 1.3 2.1
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {$fixedHeight * 1}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 3}] [expr {$fixedHeight * 2}] [expr {$fixedHeight * 1}] [expr {$fixedHeight * 1}]]






test textDisp-32.0 {everything elided} {
    # Must not crash
    pack [text .tt]
    .tt insert 0.0 HELLO
    .tt tag configure HIDE -elide 1
    .tt tag add HIDE 0.0 end
    updateText
    destroy .tt
} {}
test textDisp-32.1 {everything elided} {
    # Must not crash
    pack [text .tt]
    updateText
    .tt insert 0.0 HELLO
    updateText
    .tt tag configure HIDE -elide 1
    updateText
    .tt tag add HIDE 0.0 end
    updateText
    destroy .tt
} {}
test textDisp-32.2 {elide and tags} {
    pack [text .tt -height 30 -width 100 -bd 0 \
      -highlightthickness 0 -padx 0]
    .tt insert end \
      {test text using tags 1 and 3 } \
      {testtag1 testtag3} \
      {[this bit here uses tags 2 and 3]} \
      {testtag2 testtag3}
    updateText
    # indent left margin of tag 1 by 20 pixels
    # text should be indented
    .tt tag configure testtag1 -lmargin1 20
    updateText
    #1
    set res {}
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should not be indented, since
    # the indented tag and character is hidden.
    .tt tag configure testtag1 -elide 1
    updateText
    #2
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag1 -lmargin1 0
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 2 by 20 pixels
    # text should not be indented, since tag1 has lmargin1 of 0.
    .tt tag configure testtag2 -lmargin1 20
    updateText
    #3
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should now be indented, but
    # the bbox of 1.0 should have zero width and zero indent,
    # since it is elided at that position.
    .tt tag configure testtag1 -elide 1
    updateText
    #4
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag2 -lmargin1 {}
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 3 by 20 pixels
    # text should be indented, since this tag takes
    # precedence over testtag1, and is applied to the
    # start of the text.
    .tt tag configure testtag3 -lmargin1 20
    updateText
    #5
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should still be indented,
    # since it still has testtag3 on it.  Again the
    # bbox of 1.0 should have 0.
    .tt tag configure testtag1 -elide 1
    updateText
    #6
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    .tt tag configure testtag3 -lmargin1 {} -elide 0
    .tt tag configure testtag1 -elide 1 -lmargin1 20
    #7







|








|








|








|








|








|









|










|

|
|



>
>
>
>
|

>
|
|
>
|
|



>
>
>
>
|

>



|
|
|







|
|










|



|
|



|
>
>
|






|
>
>
|



>
>
>
|

>
>
|
<
>
|



>
>
>
|

>
>
|
<
>
|



>
>
>
|

>
>
|
<
>
|



>
>
>
|

>
>
|
<
>
|



|


|
>
|










|


|
|

>
|
|
<
|











|


|
|



<
|









|




|

|


|
|



|


|
>
|



|


|
>
>
>
|



|


|
>
|



|


|
>




|

>





|



|

>
>
|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
>
>
>
>
>
|
<
>
>
>
|

>










|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|

>












|






<





>
>
|
|

>










|

|
>
>
>
|
>
>
>
|
|
>
>
>
>
>


|
|
>
|
|
>
>
|
>
>
>
>
>


|
|
>
|
|
>
>



|

|



|





|
|
|
|


|










|
>
|
|
>
|







|













>
>
|
|
>





|





|
|
>
|


|











>
>
|
|
>
|




















>
>
|
|
>



















|
>
>
>
>
>







|





|

|

|

|










|



|








|










|








|












|








|







3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116

4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129

4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142

4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155

4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185

4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205

4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392

4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411

















4412






4413








4414
4415













4416





4417




4418










4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440

4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
    .t insert 1.0 a\t1.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} {120}
test textDisp-26.6 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1,456.234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.7] 0
} {120}
test textDisp-26.7 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.456.234,7
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.11] 0
} {120}
test textDisp-26.8 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\ttest
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} {120}
test textDisp-26.9 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1234
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.2
    lindex [.t bbox 1.6] 0
} {120}
test textDisp-26.10 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.5
    lindex [.t bbox 1.3] 0
} {120}
test textDisp-26.11 {AdjustForTab procedure, numeric alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tx=1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    lindex [.t bbox 1.5] 0
} {120}
test textDisp-26.12 {AdjustForTab procedure, adjusting chunks} {
    .t delete 1.0 end
    .t insert 1.0 a\tx1.234567
    .t tag delete x
    .t tag configure x -tabs {120 numeric}
    .t tag add x 1.0 end
    .t tag add y 1.7
    .t tag add y 1.9
    button .b -text "="
    .t window create 1.3 -window .b
    update
    lindex [.t bbox 1.5] 0
} {120}
test textDisp-26.13 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    set t1 [expr {   $fixedWidth+3}]
    set t2 [expr { 4*$fixedWidth+2}]
    set t3 [expr { 7*$fixedWidth+1}]
    set t4 [expr {17*$fixedWidth+1}]
    .t tag configure x -tabs "$t1 $t2 center $t3 right $t4"
    .t tag add x 1.0 end
    set expected [list [xchar 4] [xchar 8] [xchar 12] $t4]
    set res [list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
            [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]]
    lequal $res $expected
} {1}
test textDisp-26.13.2 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    set t1 [expr {   $fixedWidth+3}]
    set t2 [expr { 4*$fixedWidth+2}]
    set t3 [expr { 7*$fixedWidth+1}]
    set t4 [expr {17*$fixedWidth+1}]
    .t tag configure x -tabs "$t1 $t2 center $t3 right $t4" -tabstyle wordprocessor
    .t tag add x 1.0 end
    set expected [list [xchar 4] [xchar 8] $t4 [expr {$t4+($t4-$t3)}]]
    set res [list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
      [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]]
    .t tag configure x -tabstyle tabular
    lequal $res $expected
} {1}
test textDisp-26.14 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t insert end "a \tb \tc \td \te \tf \tg\n"
    .t insert end "Watch the \tX and the \t\t\tY\n"
    .t tag configure moop -tabs [expr {8*$fixedWidth}]
    .t insert end "Watch the \tX and the \t\t\tY\n" moop
    list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \
	    [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]
} [list [xchar 11] [xchar 32] [xchar 11] [xchar 32]]
test textDisp-26.14.2 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    .t insert end "a \tb \tc \td \te \tf \tg\n"
    .t insert end "Watch the \tX and the \t\t\tY\n"
    .t tag configure moop -tabs [expr {8*$fixedWidth}]
    .t insert end "Watch the \tX and the \t\t\tY\n" moop
    set res [list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \
      [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]]
    .t configure -tabstyle tabular
    set res
} [list [xchar 16] [xchar 8] [xchar 16] [xchar 8]]

.t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \
	-wrap char
update
test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]
} [list [list [xchar 8] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar [expr {8+8}]] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar [expr {8+8+1+1}]] [yline 1] $fixedWidth $fixedHeight]]
test textDisp-27.1.1 {SizeOfTab procedure, old-style tabs} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    .t configure -tabstyle wordprocessor
    set res [list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]]
    .t configure -tabstyle tabular
    set res
} [list [list [xchar 8] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar [expr {8+8}]] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.2 {SizeOfTab procedure, choosing tabX and alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcd
    .t tag delete x
    # compute a tab width such that the first display line is just not large enough
    # to show the last char 'd', which then wraps on display line 2
    set tw [expr {(20-2)*$fixedWidth-($fixedWidth-1)}]
    .t tag configure x -tabs $tw
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$tw+[xw 1]}] [yline 1] [expr {[winfo width .t]-([bo]+$tw+[xw 1])-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.3] [.t bbox 1.4]] $expected

} {1}
test textDisp-27.3 {SizeOfTab procedure, choosing tabX and alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t\t\tbcd
    .t tag delete x
    # compute a tab width such that the first display line is just not large enough
    # to show the last char 'd', which then wraps on display line 2
    set tw [expr {int(ceil(((20-2)*$fixedWidth-($fixedWidth-1))/3.0))}]
    .t tag configure x -tabs $tw
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+3*$tw+[xw 1]}] [yline 1] [expr {[winfo width .t]-([bo]+3*$tw+[xw 1])-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.5] [.t bbox 1.6]] $expected

} {1}
test textDisp-27.4 {SizeOfTab procedure, choosing tabX and alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t\t\tbcd
    .t tag delete x
    # compute a tab width such that the first display line is just not large enough
    # to show the last char 'd', which then wraps on display line 2
    set tw [expr {int(ceil(((20-2)*$fixedWidth-($fixedWidth-1) + 20)/2.0))}]
    .t tag configure x -tabs "20 center $tw left"
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$tw+($tw-20)+[xw 1]}] [yline 1] [expr {[winfo width .t]-([bo]+$tw+($tw-20)+[xw 1])-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.5] [.t bbox 1.6]] $expected

} {1}
test textDisp-27.5 {SizeOfTab procedure, center alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    # compute a tab width such that the last y on the first display line is the last displayed char
    # while 'xyzzyabc' is centered at the tab stop; the 'abc" part of the line wraps on display line 2
    set tw [expr {[winfo width .t]-2*[bo]-3*$fixedWidth+1}]
    .t tag configure x -tabs "$tw center"
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$tw+round(1.5*$fixedWidth)}] [yline 1] [expr {[winfo width .t]-([bo]+$tw+round(1.5*$fixedWidth))-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.6] [.t bbox 1.7]] $expected

} {1}
test textDisp-27.6 {SizeOfTab procedure, center alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs "[expr {round(21.4*$fixedWidth)}] center"
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list [xchar 4] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {
    .t delete 1.0 end
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with some pixels for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {[bo] + int(0.5 + $tab + $cm)}]
    update
    set res [.t bbox 2.23]
    set expected [list [expr {[xchar 23]-$tab}] [yline 2] $fixedWidth $fixedHeight]
    lequal [lset res 0 [expr {[lindex $res 0] - $tab}]] $expected
} {1}

test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    set cm [winfo fpixels .t 1c]
    .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40
    .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd
    set width [expr {$fixedWidth * 19}]
    set tab $cm
    while {$tab < $width} {
	set tab [expr {$tab + $cm}]
    }
    # Now we've calculated to the end of the tab after 'a', add one
    # more for 'bb\t' and we're there, with some pixels for the border.  Since
    # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding,
    # so must we.
    set tab [expr {[bo] + int(0.5 + $tab + $cm)}]
    update
    set res [.t bbox 2.23]
    .t configure -tabstyle tabular
    lset res 0 [expr {[lindex $res 0] - $tab}]

} [list 0 [yline 2] $fixedWidth $fixedHeight]
test textDisp-27.7.2 {SizeOfTab procedure, fractional tab interpolation problem} {
    .t delete 1.0 end
    set interpolatetab {1c 2c}
    set precisetab {}
    for {set i 1} {$i < 20} {incr i} {
	lappend precisetab "${i}c"
    }
    .t configure -tabs $interpolatetab -wrap none -width 150
    .t insert 1.0 [string repeat "a\t" 20]
    update
    set res [.t bbox 1.20]
    # Now, Tk's interpolated tabs should be the same as
    # non-interpolated.
    .t configure -tabs $precisetab
    update
    expr {[lindex $res 0] - [lindex [.t bbox 1.20] 0]}
} {0}

.t configure -wrap char -tabs {} -width 20
update
test textDisp-27.8 {SizeOfTab procedure, right alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs "[expr {14.3*$fixedWidth}] left [expr {[.t cget -width]*$fixedWidth}] right"
    .t tag add x 1.0 end
    list [.t bbox 1.6] [.t bbox 1.7]
} [list [list [xcharr 1] [yline 1] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.9 {SizeOfTab procedure, left alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs "[expr {17.14*$fixedWidth}]"
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list [expr {round([bo]+17.14*$fixedWidth+$fixedWidth)}] [yline 1] [expr {[winfo width .t]-round([bo]+17.14*$fixedWidth+$fixedWidth)-[bo]}] $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]
# This test does not pass on any platform at this point with the revised
# implementation (see [6a78781cc3]), therefore the 'knownBug' constraint.
test textDisp-27.10 {SizeOfTab procedure, numeric alignment} knownBug {
    .t delete 1.0 end
    .t insert 1.0 a\t123.4
    .t tag delete x
    .t tag configure x -tabs "[expr {17.14*$fixedWidth}] numeric"
    .t tag add x 1.0 end
    list [.t bbox 1.3] [.t bbox 1.4]
} [list [list [expr {round([bo]+17.14*$fixedWidth-$fixedWidth)}] [yline 1] [expr {[winfo width .t]-round([bo]+17.14*$fixedWidth-$fixedWidth)-[bo]}] $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.11 {SizeOfTab procedure, making tabs at least as wide as a space} {
    .t delete 1.0 end
    .t insert 1.0 abc\tdefghijklmnopqrst
    .t tag delete x
    .t tag configure x -tabs "[expr {17.14*$fixedWidth}]"
    .t tag add x 1.0 end
    list [.t bbox 1.5] [.t bbox 1.6]
} [list [list [expr {round([bo]+17.14*$fixedWidth+$fixedWidth)}] [yline 1] [expr {[winfo width .t]-round([bo]+17.14*$fixedWidth+$fixedWidth)-[bo]}] $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]

proc bizarre_scroll args {
    .t2.t delete 5.0 end
}
test textDisp-28.1 {"yview" option with bizarre scroll command} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    text .t2.t -width 40 -height 4
    .t2.t insert end "1\n2\n3\n4\n5\n6\n7\n8\n"
    pack .t2.t
    wm geometry .t2 +0+0
    update
    .t2.t configure -yscrollcommand bizarre_scroll
    .t2.t yview 100.0
    set result [.t2.t index @0,0]
    update
    lappend result [.t2.t index @0,0]
} -cleanup {
    destroy .t2
} -result {6.0 2.0}

test textDisp-29.1 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    set expected [list [list 0.0 [expr {20.0*$fixedWidth/300}]] \
                       300x50+[bo .t2.t]+[yline 2 .t2.t] \
	               [list [xchar 1 .t2.t] [expr {[yline 2 .t2.t]+50}] $fixedWidth $fixedHeight]]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 1 unit
    update
    set expected [list [list [expr {1.0*$fixedWidth/300}] [expr {21.0*$fixedWidth/300}]] \
                       300x50+[expr {[bo .t2.t]-$fixedWidth}]+[yline 2 .t2.t] \
	               [list [expr {[bo .t2.t]-$fixedWidth+$fixedWidth}] [expr {[yline 2 .t2.t]+50}] $fixedWidth $fixedHeight]]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2.1 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap none -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 1\n
    .t2.t insert end [string repeat "abc" 30]
    update
    .t2.t xview scroll 5 unit
    update
    .t2.t xview
} -cleanup {
    destroy .t2
} -result [list [expr {5.0/90}] [expr {25.0/90}]]
test textDisp-29.2.2 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 2 unit
    update
    set expected [list [list [expr {2.0*$fixedWidth/300}] [expr {22.0*$fixedWidth/300}]] \
                       300x50+[expr {[bo .t2.t]-2*$fixedWidth}]+[yline 2 .t2.t] \
	               {}]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2.3 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 7 pixels
    update
    set expected [list [list [expr {7.0/300}] [expr {(20.0*$fixedWidth+7)/300}]] \
                       300x50+[expr {[bo .t2.t]-7}]+[yline 2 .t2.t] \
	               [list [expr {[bo .t2.t]+$fixedWidth-7}] [expr {[yline 2 .t2.t]+50}] $fixedWidth $fixedHeight]]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected

} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2.4 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 17 pixels
    update

















    set expected [list [list [expr {17.0/300}] [expr {(20.0*$fixedWidth+17)/300}]] \






                       300x50+[expr {[bo .t2.t]-17}]+[yline 2 .t2.t] \








	               {}]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected













} -cleanup {





    destroy .t2




} -result {1}










test textDisp-29.2.5 {miscellaneous: can show last character} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 121x141+200+200
    text .t2.t -width 5 -height 5 -font {Arial 10} \
      -wrap none -xscrollcommand ".t2.s set" \
      -bd 2 -highlightthickness 0 -padx 1
    .t2.t insert end "WWWWWWWWWWWWi"
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    grid .t2.t -row 0 -column 0 -sticky nsew
    grid .t2.s -row 1 -column 0 -sticky ew
    grid columnconfigure .t2 0 -weight 1
    grid rowconfigure .t2 0 -weight 1
    grid rowconfigure .t2 1 -weight 0
    update
    set xv [.t2.t xview]
    set xd [expr {[lindex $xv 1] - [lindex $xv 0]}]
    .t2.t xview moveto [expr {1.0-$xd}]
    set iWidth [lindex [.t2.t bbox end-2c] 2]
    .t2.t xview scroll 2 units
    set iWidth2 [lindex [.t2.t bbox end-2c] 2]

    if {($iWidth == $iWidth2) && $iWidth >= 2} {
	set result "correct"
    } else {
	set result "last character is not completely visible when it should be"
    }
} -cleanup {
    destroy .t2
} -result {correct}
test textDisp-29.3 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    wm geometry .t2 +0+0
    text .t2.t -width 20 -height 10 -font $fixedFont \
	    -wrap char -xscrollcommand ".t2.s set"
    pack .t2.t -side top
    scrollbar .t2.s -orient horizontal -command ".t2.t xview"
    pack .t2.s -side bottom -fill x
    .t2.t insert end 123
    frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised
    .t2.t window create 1.1 -window .t2.t.f
    update
    .t2.t xview scroll 200 units
    update
    set expected [list [list [expr {double(300-20*$fixedWidth)/300}] 1.0] \
                       300x50+[expr {-(300-20*$fixedWidth-[bo .t2.t])}]+[yline 2 .t2.t] \
	               {}]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}

test textDisp-30.1 {elided text joining multiple logical lines} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    text .t2.t -width 20 -height 10 -font $fixedFont
    pack .t2.t -side top
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elided -elide 1 -background red
    .t2.t tag add elided 1.2 3.2
    update
    .t2.t count -update -displaylines 1.0 end
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-30.2 {elided text joining multiple logical lines} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    text .t2.t -width 20 -height 10 -font $fixedFont
    pack .t2.t -side top
    .t2.t delete 1.0 end
    .t2.t insert 1.0 "1111\n2222\n3333"
    .t2.t tag configure elided -elide 1 -background red
    .t2.t tag add elided 1.2 2.2
    update
    .t2.t count -update -displaylines 1.0 end
} -cleanup {
    destroy .t2
} -result {2}
catch {destroy .t2}

.t configure -height 1
update

test textDisp-31.1 {line embedded window height update} {
    set res {}
    .t delete 1.0 end
    .t insert end "abcd\nefgh\nijkl\nmnop\nqrst\nuvwx\nyx"
    frame .t.f -background red -width 50 -height 100
    .t window create 3.0 -window .t.f
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*6}] \
	[expr {$fixedHeight*7}]]
test textDisp-31.2 {line update index shifting} {
    set res {}
    .t.f configure -height 100
    update
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*8}] \
	[expr {$fixedHeight*9}] \
	[expr {$fixedHeight*7}] \
	[expr {100+$fixedHeight*6}]]
test textDisp-31.3 {line update index shifting} {
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    .t.f configure -height 100
    update
    lappend res [.t count -update -ypixels 1.0 end]
    .t.f configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t.f configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*8}] \
	[expr {$fixedHeight*9}] \
	[expr {$fixedHeight*7}] \
	[expr {100+$fixedHeight*6}]]
test textDisp-31.4 {line embedded image height update} {
    set res {}
    image create photo textest -height 100 -width 10
    .t delete 3.0
    .t image create 3.0 -image textest
    update
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*6}] \
	[expr {$fixedHeight*7}]]
test textDisp-31.5 {line update index shifting} {
    set res {}
    textest configure -height 100
    update
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    lappend res [.t count -update -ypixels 1.0 end]
    set res
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*8}] \
	[expr {$fixedHeight*9}] \
	[expr {$fixedHeight*7}] \
	[expr {100+$fixedHeight*6}]]
test textDisp-31.6 {line update index shifting} {
    # Should do exactly the same as the above, as long
    # as we are correctly tagging the correct lines for
    # recalculation.  The 'update' and 'delay' must be
    # long enough to ensure all asynchronous updates
    # have been performed.
    set res {}
    textest configure -height 100
    lappend res [.t count -update -ypixels 1.0 end]
    textest configure -height 10
    .t insert 1.0 "abc\n"
    .t insert 1.0 "abc\n"
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    textest configure -height 100
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*8}] \
	[expr {$fixedHeight*9}] \
	[expr {$fixedHeight*7}] \
	[expr {100+$fixedHeight*6}]]
test textDisp-31.7 {line update index shifting, elided} {
    # The 'update' and 'delay' must be long enough to ensure all
    # asynchronous updates have been performed.
    set res {}
    .t delete 1.0 end
    lappend res [.t count -update -ypixels 1.0 end]
    .t insert 1.0 "abc\nabc"
    .t insert 1.0 "abc\n"
    lappend res [.t count -update -ypixels 1.0 end]
    .t tag configure elide -elide 1
    .t tag add elide 1.3 2.1
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    .t delete 1.0 3.0
    lappend res [.t count -ypixels 1.0 end]
    delay
    lappend res [.t count -ypixels 1.0 end]
    set res
} [list [expr {$fixedHeight*1}] \
        [expr {$fixedHeight*3}] \
	[expr {$fixedHeight*3}] \
	[expr {$fixedHeight*2}] \
	[expr {$fixedHeight*1}] \
	[expr {$fixedHeight*1}]]

test textDisp-32.0 {everything elided} {
    # Must not crash
    pack [text .tt]
    .tt insert 0.0 HELLO
    .tt tag configure HIDE -elide 1
    .tt tag add HIDE 0.0 end
    update
    destroy .tt
} {}
test textDisp-32.1 {everything elided} {
    # Must not crash
    pack [text .tt]
    update
    .tt insert 0.0 HELLO
    update
    .tt tag configure HIDE -elide 1
    update
    .tt tag add HIDE 0.0 end
    update
    destroy .tt
} {}
test textDisp-32.2 {elide and tags} {
    pack [text .tt -height 30 -width 100 -bd 0 \
      -highlightthickness 0 -padx 0]
    .tt insert end \
      {test text using tags 1 and 3 } \
      {testtag1 testtag3} \
      {[this bit here uses tags 2 and 3]} \
      {testtag2 testtag3}
    update
    # indent left margin of tag 1 by 20 pixels
    # text should be indented
    .tt tag configure testtag1 -lmargin1 20
    update
    #1
    set res {}
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should not be indented, since
    # the indented tag and character is hidden.
    .tt tag configure testtag1 -elide 1
    update
    #2
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag1 -lmargin1 0
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 2 by 20 pixels
    # text should not be indented, since tag1 has lmargin1 of 0.
    .tt tag configure testtag2 -lmargin1 20
    update
    #3
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should now be indented, but
    # the bbox of 1.0 should have zero width and zero indent,
    # since it is elided at that position.
    .tt tag configure testtag1 -elide 1
    update
    #4
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # reset
    .tt tag configure testtag2 -lmargin1 {}
    .tt tag configure testtag1 -elide 0
    # indent left margin of tag 3 by 20 pixels
    # text should be indented, since this tag takes
    # precedence over testtag1, and is applied to the
    # start of the text.
    .tt tag configure testtag3 -lmargin1 20
    update
    #5
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    # hide tag 1, remaining text should still be indented,
    # since it still has testtag3 on it.  Again the
    # bbox of 1.0 should have 0.
    .tt tag configure testtag1 -elide 1
    update
    #6
    lappend res [list [.tt index "1.0 + 0 displaychars"] \
      [lindex [.tt bbox 1.0] 0] \
      [lindex [.tt bbox "1.0 + 0 displaychars"] 0]]
    .tt tag configure testtag3 -lmargin1 {} -elide 0
    .tt tag configure testtag1 -elide 1 -lmargin1 20
    #7
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193














4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209

4210
4211
4212
4213
4214
4215





4216
4217
4218
4219
4220
4221
4222
4223
4224
4225

4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
    .tt tag configure emoticon -elide 1
    .tt insert end X
    .tt mark set MSGLEFT "end - 1 char"
    .tt mark gravity MSGLEFT left
    .tt insert end ":)" emoticon
    .tt image create end -image $img
    pack .tt
    updateText
} -cleanup {
    image delete $img
    destroy .tt
}















test textDisp-33.0 {one line longer than fits in the widget} {
    pack [text .tt -wrap char]
    updateText
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt see 1.0
    lindex [.tt yview] 0
} {0.0}
test textDisp-33.1 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    updateText
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt yview "1.0 +1 displaylines"

    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
} {ok}





test textDisp-33.2 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    updateText
    set tk_textHeightCalc ""
    set timer [after 200 lappend tk_textHeightCalc "Timed out"]
    .tt insert 1.0 [string repeat "more wrap + " 1]
    vwait tk_textHeightCalc
    after cancel $timer

    set tk_textHeightCalc
} {1.0}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    .tt count -update -ypixels 1.0 end
    updateText
    # Each line should have been recalculated just once
    .tt debug 0
    expr {[llength $tk_textHeightCalc] == [.tt count -displaylines 1.0 end]}
} 1
test textDisp-33.4 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    .tt debug 1
    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    set idx [.tt index "1.0 + 1 displaylines"]
    .tt yview $idx
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
    set idx [.tt index "1.0 + 1 displaylines"]
    .tt debug 0
    set result
} {ok}
destroy .tt
test textDisp-33.5 {bold or italic fonts} win {
    destroy .tt
    pack [text .tt -wrap char -font {{MS Sans Serif} 15}]
    font create no -family [lindex [.tt cget -font] 0] -size 24
    font create bi -family [lindex [.tt cget -font] 0] -size 24
    font configure bi -weight bold -slant italic
    .tt tag configure bi -font bi
    .tt tag configure no -font no
    .tt insert end abcd no efgh bi ijkl\n no
    updateText
    set bb {}
    for {set i 0} {$i < 12} {incr i 4} {
	lappend bb [lindex [.tt bbox 1.$i] 0]
    }
    foreach {a b c} $bb {}
    unset bb
    if {($b - $a) * 1.5 < ($c - $b)} {







|




>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

|






|

|

>






>
>
>
>
>
|
|
|
<
<
|
<
|
<
|
>
|
|



<


<
|
<

<

|



<
<

|








<












|







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
    .tt tag configure emoticon -elide 1
    .tt insert end X
    .tt mark set MSGLEFT "end - 1 char"
    .tt mark gravity MSGLEFT left
    .tt insert end ":)" emoticon
    .tt image create end -image $img
    pack .tt
    update
} -cleanup {
    image delete $img
    destroy .tt
}
test textDisp-32.4 {Button-1 click with elided lines - Bug 18371b7ce7} -setup {
    pack [text .tt -borderwidth 0 -highlightthickness 0]
    for {set n 1} {$n <= 5} {incr n} {
	.tt insert end "Line $n\n"
    }
    .tt tag configure Elided -elide 1
    .tt tag add Elided 1.2 4.0
    update
} -body {
    event generate .tt <Button-1> -x 1 -y 1
    .tt index insert
} -cleanup {
    destroy .tt
} -result {1.0}

test textDisp-33.0 {one line longer than fits in the widget} {
    pack [text .tt -wrap char]
    update
    .tt insert 1.0 [string repeat "more wrap + " 300]
    update
    .tt see 1.0
    lindex [.tt yview] 0
} {0.0}
test textDisp-33.1 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]
    update
    .tt insert 1.0 [string repeat "more wrap + " 300]
    update
    .tt yview "1.0 +1 displaylines"
    update
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
} {ok}
# Test case 33.2 has been removed. The problem is that the revised
# implementation is also updating the line heights while computing
# the display lines for displaying the content, so we cannot
# distinguish anymore between the display process and the line
# height calculation.
#test textDisp-33.2 {one line longer than fits in the widget} {
#    destroy .tt
#    pack [text .tt -wrap char]


#    set tk_textHeightCalc ""

#    .tt insert 1.0 [string repeat "more wrap + " 1]

#    after 100 ; update idletasks
#    # Nothing should have been recalculated.
#    set tk_textHeightCalc
#} {}
test textDisp-33.3 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]

    set tk_textHeightCalc ""
    .tt insert 1.0 [string repeat "more wrap + " 300]

    .tt sync

    # Each line should have been recalculated just once

    expr {[llength $tk_textHeightCalc] == [.tt count -displaylines 1.0 end]}
} {1}
test textDisp-33.4 {one line longer than fits in the widget} {
    destroy .tt
    pack [text .tt -wrap char]


    .tt insert 1.0 [string repeat "more wrap + " 300]
    update
    set idx [.tt index "1.0 + 1 displaylines"]
    .tt yview $idx
    if {[lindex [.tt yview] 0] > 0.1} {
	set result "window should be scrolled to the top"
    } else {
	set result "ok"
    }
    set idx [.tt index "1.0 + 1 displaylines"]

    set result
} {ok}
destroy .tt
test textDisp-33.5 {bold or italic fonts} win {
    destroy .tt
    pack [text .tt -wrap char -font {{MS Sans Serif} 15}]
    font create no -family [lindex [.tt cget -font] 0] -size 24
    font create bi -family [lindex [.tt cget -font] 0] -size 24
    font configure bi -weight bold -slant italic
    .tt tag configure bi -font bi
    .tt tag configure no -font no
    .tt insert end abcd no efgh bi ijkl\n no
    update
    set bb {}
    for {set i 0} {$i < 12} {incr i 4} {
	lappend bb [lindex [.tt bbox 1.$i] 0]
    }
    foreach {a b c} $bb {}
    unset bb
    if {($b - $a) * 1.5 < ($c - $b)} {
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314





4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325

4326
4327
















4328
4329
4330
4331
4332
4333
4334
    set txt ""
    for {set i 1} {$i < 100} {incr i} {
        append txt "Line $i\n"
    }
    set result {}
} -body {
    .t1 insert end $txt
    .t1 debug 1
    set ge [winfo geometry .]
    scan $ge "%dx%d+%d+%d" width height left top
    updateText
    .t1 sync
    set negative 0
    bind .t1 <<WidgetViewSync>> { if {%d < 0} {set negative 1} }
    # Without the fix for bug 2677890, changing the width of the toplevel
    # will launch recomputation of the line heights, but will produce negative
    # number of still remaining outdated lines, which is obviously wrong.
    # Thus we use this way to check for regression regarding bug 2677890,
    # i.e. to check that the fix for this bug really is still in.
    wm geometry . "[expr {$width * 2}]x$height+$left+$top"
    updateText
    .t1 sync
    set negative
} -cleanup {
    destroy .t1
} -result 0

test textDisp-35.1 {Init value of charHeight - Dancing scrollbar bug 1499165} -setup {
    pack [text .t1] -fill both -expand y -side left





    .t insert end "[string repeat a\nb\nc\n 500000]THE END\n"
    set res {}
} -body {
    .t see 10000.0
    after 300 {set fr1 [.t yview] ; set done 1}
    vwait done
    after 300 {set fr2 [.t yview] ; set done 1}
    vwait done
    lappend res [expr {[lindex $fr1 0] == [lindex $fr2 0]}]
    lappend res [expr {[lindex $fr1 1] == [lindex $fr2 1]}]
} -cleanup {

    destroy .t1
} -result {1 1}

















deleteWindows
option clear

# cleanup
cleanupTests
return







<


|









|




|



>
>
>
>
>











>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    set txt ""
    for {set i 1} {$i < 100} {incr i} {
        append txt "Line $i\n"
    }
    set result {}
} -body {
    .t1 insert end $txt

    set ge [winfo geometry .]
    scan $ge "%dx%d+%d+%d" width height left top
    update
    .t1 sync
    set negative 0
    bind .t1 <<WidgetViewSync>> { if {%d < 0} {set negative 1} }
    # Without the fix for bug 2677890, changing the width of the toplevel
    # will launch recomputation of the line heights, but will produce negative
    # number of still remaining outdated lines, which is obviously wrong.
    # Thus we use this way to check for regression regarding bug 2677890,
    # i.e. to check that the fix for this bug really is still in.
    wm geometry . "[expr {$width * 2}]x$height+$left+$top"
    update
    .t1 sync
    set negative
} -cleanup {
    destroy .t1
} -result {0}

test textDisp-35.1 {Init value of charHeight - Dancing scrollbar bug 1499165} -setup {
    pack [text .t1] -fill both -expand y -side left
    # We don't want debug for this test case, because it takes some hours
    # if valgrind check is fully enabled. In this test case only the scrollbar
    # behavior is relevant, all other involved functions (insert, see, ...) are
    # already tested with debug mode in other test cases.
    .t debug off
    .t insert end "[string repeat a\nb\nc\n 500000]THE END\n"
    set res {}
} -body {
    .t see 10000.0
    after 300 {set fr1 [.t yview] ; set done 1}
    vwait done
    after 300 {set fr2 [.t yview] ; set done 1}
    vwait done
    lappend res [expr {[lindex $fr1 0] == [lindex $fr2 0]}]
    lappend res [expr {[lindex $fr1 1] == [lindex $fr2 1]}]
} -cleanup {
    .t debug on ;# re-enable debugging
    destroy .t1
} -result {1 1}

test textDisp-36.1 {Display bug with 'yview insert'} -setup {
   text .t1 -font $fixedFont -width 20 -height 3 -wrap word
   pack .t1
   .t1 delete 1.0 end
   .t1 tag configure elide -elide 1
   .t1 insert end "Line 1\nThis line is wrapping around two times."
} -body {
   .t1 tag add elide 1.3 2.0
   .t1 yview insert
   update
   # wish panicks with the legacy text widget
   .t1 yview scroll -1 pixels
} -cleanup {
    destroy .t1
} -result {}

deleteWindows
option clear

# cleanup
cleanupTests
return

Changes to tests/textImage.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20





21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# textImage.test -- test images embedded in text widgets
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# One time setup.  Create a font to insure the tests are font metric invariant.
destroy .t
font create test_font -family courier -size 14
text .t -font test_font

destroy .t






test textImage-1.1 {basic argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image option ?arg ...?"}

test textImage-1.2 {basic argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image c
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous option "c": must be cget, configure, create, or names}

test textImage-1.3 {cget argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image cget
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image cget index option"}

test textImage-1.4 {cget argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image cget blurf -flurp
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.5 {cget argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image cget 1.1 -flurp
} -cleanup {
    destroy .t
} -returnCodes error -result {no embedded image at index "1.1"}

test textImage-1.6 {configure argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image configure
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image configure index ?-option value ...?"}

test textImage-1.7 {configure argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image configure blurf
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.8 {configure argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image configure 1.1
} -cleanup {
    destroy .t
} -returnCodes error -result {no embedded image at index "1.1"}

test textImage-1.9 {create argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image create index ?-option value ...?"}

test textImage-1.10 {create argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create blurf
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.11 {basic argument checking} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create 1000.1000 -image small
} -cleanup {
    destroy .t
    image delete small
} -returnCodes ok -result {small}

test textImage-1.12 {names argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image names dates places
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image names"}


test textImage-1.13 {names argument checking} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    lappend result [.t image names]
    .t image create insert -image small
    lappend result [.t image names]
    .t image create insert -image small
    lappend result [lsort [.t image names]]
    .t image create insert -image small -name little
    lappend result [lsort [.t image names]]
} -cleanup {
    destroy .t
    image delete small
} -result {{} small {small small#1} {little small small#1}}

test textImage-1.14 {basic argument checking} -setup {
    destroy .t
} -body {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image huh
} -cleanup {
    destroy .t
} -returnCodes error -result {bad option "huh": must be cget, configure, create, or names}

test textImage-1.15 {align argument checking} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small -align wrong
} -cleanup {
    destroy .t
    image delete small
} -returnCodes error -result {bad align "wrong": must be baseline, bottom, center, or top}

test textImage-1.16 {configure} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small
    .t image configure small
} -cleanup {
    destroy .t
    image delete small
} -result {{-align {} {} center center} {-padx {} {} 0 0} {-pady {} {} 0 0} {-image {} {} {} small} {-name {} {} {} {}}}

test textImage-1.17 {basic cget options} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small
    foreach i {align padx pady image name} {
        lappend result $i:[.t image cget small -$i]
    }
    return $result
} -cleanup {
    destroy .t
    image delete small
} -result {align:center padx:0 pady:0 image:small name:}

test textImage-1.18 {basic configure options} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small
    foreach {option value}  {align top padx 5 pady 7 image large name none} {
        .t image configure small -$option $value
    }
    update
    .t image configure small
} -cleanup {
    destroy .t
    image delete small large
} -result {{-align {} {} center top} {-padx {} {} 0 5} {-pady {} {} 0 7} {-image {} {} {} large} {-name {} {} {} none}}

test textImage-1.19 {basic image naming} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image small
    .t image create end -image small -name small
    .t image create end -image small -name small#6342
    .t image create end -image small -name small
    lsort [.t image names]
} -cleanup {
    destroy .t
    image delete small
} -result {small small#1 small#6342 small#6343}

test textImage-2.1 {debug} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t debug 1
    .t insert end front
    .t image create end -image small
    .t insert end back
    .t delete small
    .t image names
    .t debug 0
} -cleanup {
    destroy .t
    image delete small
} -result {}


test textImage-3.1 {image change propagation} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo vary -width 5 -height 5
        vary put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image vary -align top
    update
    lappend result base:[.t bbox vary]
    foreach i {10 20 40} {
        vary configure -width $i -height $i
        update
        lappend result $i:[.t bbox vary]






|












>

>
>
>
>
>




<
|








<
|








<
|








<
|








<
|








<
|








<
|








<
|








<
|








<
|












<
|









<
|














<
|















<
|












<
|













<
|





|









<
|




















<
|

|







|








<
|








|








<
|
<





<














<
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

267

268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
# textImage.test -- test images embedded in text widgets
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

# One time setup.  Create a font to insure the tests are font metric invariant.
destroy .t
font create test_font -family courier -size 14
text .t -font test_font
.t debug on
destroy .t

proc setup {} {
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
}

test textImage-1.1 {basic argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image option ?arg ...?"}

test textImage-1.2 {basic argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image c
} -cleanup {
    destroy .t
} -returnCodes error -result {ambiguous option "c": must be cget, configure, create, or names}

test textImage-1.3 {cget argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image cget
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image cget index option"}

test textImage-1.4 {cget argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image cget blurf -flurp
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.5 {cget argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image cget 1.1 -flurp
} -cleanup {
    destroy .t
} -returnCodes error -result {no embedded image at index "1.1"}

test textImage-1.6 {configure argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image configure
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image configure index ?-option value ...?"}

test textImage-1.7 {configure argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image configure blurf
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.8 {configure argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image configure 1.1
} -cleanup {
    destroy .t
} -returnCodes error -result {no embedded image at index "1.1"}

test textImage-1.9 {create argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image create
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image create index ?-option value ...?"}

test textImage-1.10 {create argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image create blurf
} -cleanup {
    destroy .t
} -returnCodes error -result {bad text index "blurf"}

test textImage-1.11 {basic argument checking} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    .t image create 1000.1000 -image small
} -cleanup {
    destroy .t
    image delete small
} -returnCodes ok -result {small}

test textImage-1.12 {names argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image names dates places
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be ".t image names"}


test textImage-1.13 {names argument checking} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    lappend result [.t image names]
    .t image create insert -image small
    lappend result [.t image names]
    .t image create insert -image small
    lappend result [lsort [.t image names]]
    .t image create insert -image small -name little
    lappend result [lsort [.t image names]]
} -cleanup {
    destroy .t
    image delete small
} -result {{} small {small small#1} {little small small#1}}

test textImage-1.14 {basic argument checking} -setup {
    destroy .t
} -body {

    setup
    .t image huh
} -cleanup {
    destroy .t
} -returnCodes error -result {bad option "huh": must be cget, configure, create, or names}

test textImage-1.15 {align argument checking} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    .t image create end -image small -align wrong
} -cleanup {
    destroy .t
    image delete small
} -returnCodes error -result {bad align "wrong": must be baseline, bottom, center, or top}

test textImage-1.16 {configure} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    .t image create end -image small
    .t image configure small
} -cleanup {
    destroy .t
    image delete small
} -result {{-align {} {} center center} {-padx {} {} 0 0} {-pady {} {} 0 0} {-image {} {} {} small} {-name {} {} {} {}} {-tags {} {} {} {}}}

test textImage-1.17 {basic cget options} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    .t image create end -image small
    foreach i {align padx pady image name} {
        lappend result $i:[.t image cget small -$i]
    }
    return $result
} -cleanup {
    destroy .t
    image delete small
} -result {align:center padx:0 pady:0 image:small name:}

test textImage-1.18 {basic configure options} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    setup
    .t image create end -image small
    foreach {option value}  {align top padx 5 pady 7 image large name none tags {tag1 tag2}} {
        .t image configure small -$option $value
    }
    update
    .t image configure small
} -cleanup {
    destroy .t
    image delete small large
} -result {{-align {} {} center top} {-padx {} {} 0 5} {-pady {} {} 0 7} {-image {} {} {} large} {-name {} {} {} none} {-tags {} {} {} {tag1 tag2}}}

test textImage-1.19 {basic image naming} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    .t image create end -image small
    .t image create end -image small -name small
    .t image create end -image small -name small#6342
    .t image create end -image small -name small
    lsort [.t image names]
} -cleanup {
    destroy .t
    image delete small
} -result {small small#1 small#2 small#6342}

test textImage-2.1 {debug} -setup {
    destroy .t
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup

    .t insert end front
    .t image create end -image small
    .t insert end back
    .t delete small
    .t image names

} -cleanup {
    destroy .t
    image delete small
} -result {}


test textImage-3.1 {image change propagation} -setup {
    destroy .t
    set result ""
} -body {
    catch {
        image create photo vary -width 5 -height 5
        vary put red -to 0 0 4 4
    }

    setup
    .t image create end -image vary -align top
    update
    lappend result base:[.t bbox vary]
    foreach i {10 20 40} {
        vary configure -width $i -height $i
        update
        lappend result $i:[.t bbox vary]
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -name test
    update
    foreach {x1 y1 w1 h1} [.t bbox test] {}
    lappend result [list $x1 $w1 $h1]
    .t image configure test -image small -align top
    update
    foreach {x2 y2 w2 h2} [.t bbox test] {}







<
|







303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
    destroy .t
    set result ""
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
    }

    setup
    .t image create end -name test
    update
    foreach {x1 y1 w1 h1} [.t bbox test] {}
    lappend result [list $x1 $w1 $h1]
    .t image configure test -image small -align top
    update
    foreach {x2 y2 w2 h2} [.t bbox test] {}
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small
    .t insert end test
    update
    lappend result default:[.t bbox small]
    foreach i {top bottom center} {
        .t image configure small -align $i







<
|







330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    setup
    .t image create end -image large
    .t image create end -image small
    .t insert end test
    update
    lappend result default:[.t bbox small]
    foreach i {top bottom center} {
        .t image configure small -align $i
376
377
378
379
380
381
382

383
384
385
386
387
388

389
390
391
392
393

394
395
396
397
398
399
400
401
402
403
404
405
406
407
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    font create test_font2 -size 5
    text .t -font test_font2 -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small -align baseline
    .t insert end test

    # Sizes larger than 25 can be too big and lead to a negative 'norm',
    # at least on Windows XP with certain settings.
    foreach size {10 15 20 25} {
    font configure test_font2 -size $size
    array set Metrics [font metrics test_font2]

    update
    foreach {x y w h} [.t bbox small] {}
    set norm [expr {
            (([image height large] - $Metrics(-linespace))/2
            + $Metrics(-ascent) - [image height small] - $y)
        }]
            lappend result "$size $norm"
    }
    return $result
} -cleanup {
    destroy .t
    image delete small large
    font delete test_font2
    unset Metrics







>

|
<



>



|
|
>
|
|
|
|
|

|







357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }
	 setup
    font create test_font2 -size 5
    .t configure -font test_font2

    .t image create end -image large
    .t image create end -image small -align baseline
    .t insert end test
    update
    # Sizes larger than 25 can be too big and lead to a negative 'norm',
    # at least on Windows XP with certain settings.
    foreach size {10 15 20 25} {
        font configure test_font2 -size $size
        array set Metrics [font metrics test_font2]
        update  ; # services the idle "TheWorldHasChanged" event, queues "TkWorldChanged" events
        update  ; # services the queued "TkWorldChanged" events
        foreach {x y w h} [.t bbox small] {}
        set norm [expr {
                (([image height large] - $Metrics(-linespace))/2
                + $Metrics(-ascent) - [image height small] - $y)
        }]
        lappend result "$size $norm"
    }
    return $result
} -cleanup {
    destroy .t
    image delete small large
    font delete test_font2
    unset Metrics
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }
    text .t -font test_font -bd 0 -highlightthickness 0 -padx 0 -pady 0
    pack .t
    .t image create end -image large
    .t image create end -image small -padx 5 -pady 10
    .t insert end test
    update
    lappend result default:[.t bbox small]
    foreach i {top bottom center baseline} {
        .t image configure small -align $i







<
|







398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
} -body {
    catch {
        image create photo small -width 5 -height 5
        small put red -to 0 0 4 4
        image create photo large -width 50 -height 50
        large put green -to 0 0 50 50
    }

    setup
    .t image create end -image large
    .t image create end -image small -padx 5 -pady 10
    .t insert end test
    update
    lappend result default:[.t bbox small]
    foreach i {top bottom center baseline} {
        .t image configure small -align $i
467
468
469
470
471
472
473

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:








>
449
450
451
452
453
454
455
456
# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:
# vi:set ts=8 sw=4:

Changes to tests/textIndex.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the code in the file tkTextIndex.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the code in the file tkTextIndex.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

263
264
265
266
267
268
269

























270
271
272
273
274
275
276
277
278
} {1 {bad text index "x.last,"}}
test textIndex-4.8 {TkTextGetIndex, tags} {
    .t tag add z 1.0
    set result [list [.t index z.first] [.t index z.last]]
    .t tag delete z
    set result
} {1.0 1.1}


























test textIndex-5.1 {TkTextGetIndex, "@"} {nonPortable fonts} {
    .t index @12,9
} 1.1
test textIndex-5.2 {TkTextGetIndex, "@"} {fonts} {
    .t index @-2,7
} 1.0
test textIndex-5.3 {TkTextGetIndex, "@"} {fonts} {
    .t index @10,-7







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
} {1 {bad text index "x.last,"}}
test textIndex-4.8 {TkTextGetIndex, tags} {
    .t tag add z 1.0
    set result [list [.t index z.first] [.t index z.last]]
    .t tag delete z
    set result
} {1.0 1.1}
test textIndex-4.9 {TkTextGetIndex, tags} {
    .t tag add "" 1.0
    set result [.t index .first]
    .t tag delete ""
    set result
} {1.0}
test textIndex-4.10 {TkTextGetIndex, tags} {
    .t mark set current x.first
    .t index x.current.first
} {2.8}
test textIndex-4.11 {TkTextGetIndex, tags} {
    .t mark set current x.first
    .t index x.current.last
} {2.11}
test textIndex-4.12 {TkTextGetIndex, tags} {
    .t mark set current 1.0
    list [catch {.t index x.current.first} msg] $msg
} {1 {character near current position isn't tagged with "x"}}
test textIndex-4.13 {TkTextGetIndex, tags} {
    .t tag add "" 1.0
    .t mark set current 1.0
    set result [.t index .current.first]
    .t tag delete ""
    set result
} {1.0}

test textIndex-5.1 {TkTextGetIndex, "@"} {fonts} {
    .t index @12,9
} 1.1
test textIndex-5.2 {TkTextGetIndex, "@"} {fonts} {
    .t index @-2,7
} 1.0
test textIndex-5.3 {TkTextGetIndex, "@"} {fonts} {
    .t index @10,-7
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
test textIndex-8.5 {TkTextGetIndex, modifiers} {
    list [catch {.t index {2.1+foo bar}} msg] $msg
} {1 {bad text index "2.1+foo bar"}}
test textIndex-8.6 {TkTextGetIndex, modifiers} {
    list [catch {.t index {2.1 foo bar}} msg] $msg
} {1 {bad text index "2.1 foo bar"}}

test textIndex-9.1 {TkTextIndexCmp} {
    list [.t compare 3.1 < 3.2] [.t compare 3.1 == 3.2]
} {1 0}
test textIndex-9.2 {TkTextIndexCmp} {
    list [.t compare 3.2 < 3.2] [.t compare 3.2 == 3.2]
} {0 1}
test textIndex-9.3 {TkTextIndexCmp} {
    list [.t compare 3.3 < 3.2] [.t compare 3.3 == 3.2]
} {0 0}
test textIndex-9.4 {TkTextIndexCmp} {
    list [.t compare 2.1 < 3.2] [.t compare 2.1 == 3.2]
} {1 0}
test textIndex-9.5 {TkTextIndexCmp} {
    list [.t compare 4.1 < 3.2] [.t compare 4.1 == 3.2]
} {0 0}

test textIndex-10.1 {ForwBack} {
    list [catch {.t index {2.3 + x}} msg] $msg
} {1 {bad text index "2.3 + x"}}
test textIndex-10.2 {ForwBack} {







|


|


|


|


|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
test textIndex-8.5 {TkTextGetIndex, modifiers} {
    list [catch {.t index {2.1+foo bar}} msg] $msg
} {1 {bad text index "2.1+foo bar"}}
test textIndex-8.6 {TkTextGetIndex, modifiers} {
    list [catch {.t index {2.1 foo bar}} msg] $msg
} {1 {bad text index "2.1 foo bar"}}

test textIndex-9.1 {TkTextIndexCompare} {
    list [.t compare 3.1 < 3.2] [.t compare 3.1 == 3.2]
} {1 0}
test textIndex-9.2 {TkTextIndexCompare} {
    list [.t compare 3.2 < 3.2] [.t compare 3.2 == 3.2]
} {0 1}
test textIndex-9.3 {TkTextIndexCompare} {
    list [.t compare 3.3 < 3.2] [.t compare 3.3 == 3.2]
} {0 0}
test textIndex-9.4 {TkTextIndexCompare} {
    list [.t compare 2.1 < 3.2] [.t compare 2.1 == 3.2]
} {1 0}
test textIndex-9.5 {TkTextIndexCompare} {
    list [.t compare 4.1 < 3.2] [.t compare 4.1 == 3.2]
} {0 0}

test textIndex-10.1 {ForwBack} {
    list [catch {.t index {2.3 + x}} msg] $msg
} {1 {bad text index "2.3 + x"}}
test textIndex-10.2 {ForwBack} {
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

    .t index {2.3 + 2 chars}
} 2.5
test textIndex-12.9 {TkTextIndexForwChars: find index} {
    # not (segPtr->typePtr == &tkTextCharType)

    .t image create 2.4 -image textimage
    set x [.t get {2.3 + 3 chars}]
    .t delete 2.4
    set x
} "f"
test textIndex-12.10 {TkTextIndexForwChars: find index} {
    # dstPtr->byteIndex += segPtr->size - byteOffset
    # When moving to next segment, account for bytes in last segment.
    # Wrong answer would be 2.4







|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491

    .t index {2.3 + 2 chars}
} 2.5
test textIndex-12.9 {TkTextIndexForwChars: find index} {
    # not (segPtr->typePtr == &tkTextCharType)

    .t image create 2.4 -image textimage
    set x [.t get {2.3 + 3 indices}]
    .t delete 2.4
    set x
} "f"
test textIndex-12.10 {TkTextIndexForwChars: find index} {
    # dstPtr->byteIndex += segPtr->size - byteOffset
    # When moving to next segment, account for bytes in last segment.
    # Wrong answer would be 2.4
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
    .t index {3.4 - 2 chars}
} 3.2
test textIndex-14.8 {TkTextIndexBackChars: loop backwards over chars} {
    # (p == start)
    # Still more chars, but we reached beginning of segment

    .t image create 5.6 -image textimage
    set x [.t index {5.8 - 3 chars}]
    .t delete 5.6
    set x
} 5.5
test textIndex-14.9 {TkTextIndexBackChars: back over image} {
    # not (segPtr->typePtr == &tkTextCharType)

    .t image create 5.6 -image textimage
    set x [.t get {5.8 - 4 chars}]
    .t delete 5.6
    set x
} "G"
test textIndex-14.10 {TkTextIndexBackChars: move to previous segment} {
    # (segPtr != oldPtr)
    # More segments to go








|







|







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
    .t index {3.4 - 2 chars}
} 3.2
test textIndex-14.8 {TkTextIndexBackChars: loop backwards over chars} {
    # (p == start)
    # Still more chars, but we reached beginning of segment

    .t image create 5.6 -image textimage
    set x [.t index {5.8 - 3 indices}]
    .t delete 5.6
    set x
} 5.5
test textIndex-14.9 {TkTextIndexBackChars: back over image} {
    # not (segPtr->typePtr == &tkTextCharType)

    .t image create 5.6 -image textimage
    set x [.t get {5.8 - 4 indices}]
    .t delete 5.6
    set x
} "G"
test textIndex-14.10 {TkTextIndexBackChars: move to previous segment} {
    # (segPtr != oldPtr)
    # More segments to go

722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

set varFont {Times -14}
set bigFont {Helvetica -24}
destroy .t
text .t -font $fixedFont -width 20 -height 10 -wrap char
pack .t -expand 1 -fill both
.t tag configure big -font $bigFont
.t debug on
wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1







<







747
748
749
750
751
752
753

754
755
756
757
758
759
760

set varFont {Times -14}
set bigFont {Helvetica -24}
destroy .t
text .t -font $fixedFont -width 20 -height 10 -wrap char
pack .t -expand 1 -fill both
.t tag configure big -font $bigFont

wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
750
751
752
753
754
755
756

757
758
759
760
761
762
763
}

set str [string repeat "hello " 20]

.t insert end "$str one two three four five six seven height nine ten\n"
.t insert end "$str one two three four five six seven height nine ten\n"
.t insert end "$str one two three four five six seven height nine ten\n"


test textIndex-19.1 {Display lines} {
    .t index "2.7 displaylinestart"
} {2.0}

test textIndex-19.2 {Display lines} {
    .t index "2.7 displaylineend"







>







774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
}

set str [string repeat "hello " 20]

.t insert end "$str one two three four five six seven height nine ten\n"
.t insert end "$str one two three four five six seven height nine ten\n"
.t insert end "$str one two three four five six seven height nine ten\n"
update

test textIndex-19.1 {Display lines} {
    .t index "2.7 displaylinestart"
} {2.0}

test textIndex-19.2 {Display lines} {
    .t index "2.7 displaylineend"
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
} {2.20}

test textIndex-19.12.1 {Display lines} {
    .t index "2.50 - 100 displaylines"
} {1.0}

test textIndex-19.12.2 {Display lines} {
    .t compare [.t index "2.50 + 100 displaylines"] == "end - 1 c"
} 1

test textIndex-19.13 {Display lines} {
    destroy {*}[pack content .]
    text .txt -height 1 -wrap word -yscroll ".sbar set" -width 400
    scrollbar .sbar -command ".txt yview"
    grid .txt .sbar -sticky news







|







829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
} {2.20}

test textIndex-19.12.1 {Display lines} {
    .t index "2.50 - 100 displaylines"
} {1.0}

test textIndex-19.12.2 {Display lines} {
    .t compare [.t index "2.50 + 1000 displaylines"] == end
} 1

test textIndex-19.13 {Display lines} {
    destroy {*}[pack content .]
    text .txt -height 1 -wrap word -yscroll ".sbar set" -width 400
    scrollbar .sbar -command ".txt yview"
    grid .txt .sbar -sticky news
829
830
831
832
833
834
835























































836
837
838
839
840
841
842
    .txt insert HISTORY "\n" {NICK NICK-tick}
    .txt insert HISTORY {[23:51]	} STAMP
    .txt insert HISTORY "\n" {NICK NICK-tick}
    # Must not crash
    .txt index "2.0 - 2 display lines"
    destroy .txt .sbar
} {}
























































proc text_test_word {startend chars start} {
    destroy .t
    text .t
    .t insert end $chars
    if {[regexp {end} $start]} {
	set start [.t index "${start}chars -2c"]







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







854
855
856
857
858
859
860
861
862
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
    .txt insert HISTORY "\n" {NICK NICK-tick}
    .txt insert HISTORY {[23:51]	} STAMP
    .txt insert HISTORY "\n" {NICK NICK-tick}
    # Must not crash
    .txt index "2.0 - 2 display lines"
    destroy .txt .sbar
} {}

test textIndex-19.14 {Display lines + lines with Unicode text} {
    destroy .t
    pack [text .t -font {Courier -24} -borderwidth 0 -highlightthickness 0]
    update
    .t insert end "abcdefgh\n\u0430\u0431\u0432\u0433\u0491\u0434\u0435\u0454\n\u4E00\u4F0A\u4F9D\u533B\u54BF\u566B\u6B39\u6CC6"
    .t sync
    set res {}
    lappend res [.t index "1.4 +1lines"] [.t index "1.4 +2lines"]
    lappend res [.t index "1.4 +1displaylines"] [.t index "1.4 +2displaylines"]
    lappend res [.t index "3.4 -1lines"] [.t index "3.4 -2lines"]
    lappend res [.t index "3.4 -1displaylines"] [.t index "3.4 -2displaylines"]
    set fontlinespace [font metrics [.t cget -font] -linespace]
    set xat1.4 [expr {[.t count -xpixels 1.0 1.4] + 1}]
    set xat3.4 [expr {[.t count -xpixels 3.0 3.4] + 1}]
    set expected [list \
            2.4 3.4 \
            [.t index @${xat1.4},[expr {int($fontlinespace *1.5)}]]  [.t index @${xat1.4},[expr {int($fontlinespace *2.5)}]] \
            2.4 1.4 \
            [.t index @${xat3.4},[expr {int($fontlinespace *1.5)}]]  [.t index @${xat3.4},[expr {int($fontlinespace *0.5)}]] ]
    set checkedOK 1
    for {set i 0} {$i < 8} {incr i} {
        if {[.t compare [lindex $res $i] != [lindex $expected $i]]} {
	    set checkedOK [list result: $res - expected: $expected]
	    break
	}
    }
    set checkedOK
} {1}

test textIndex-19.15 {Display lines with elided lines} {
    catch {destroy .t}
    pack [text .t]
    for {set n 1} {$n <= 1000} {incr n} {
	.t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 951.0
    update
    .t sync
    set res [.t index "951.0 + 1 displaylines"]
    lappend res [.t index "951.0 + 7 displaylines"]
} {952.0 958.0}

test textIndex-19.16 {Display lines with elided lines} {
    catch {destroy .t}
    pack [text .t]
    for {set n 1} {$n <= 10} {incr n} {
	.t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 9.0
    update
    .t get -displaychars "6.6 linestart - 1i" 6.6 ;  # shall not crash
} "\n"

proc text_test_word {startend chars start} {
    destroy .t
    text .t
    .t insert end $chars
    if {[regexp {end} $start]} {
	set start [.t index "${start}chars -2c"]
924
925
926
927
928
929
930










931
932
933
934
935
936
937
    lappend res [.t index "2.16 wordstart"] [.t index "2.15 wordstart"]
} {1.18 2.13 2.13}
test textIndex-22.15 {text index display wordstart} {
    catch {destroy .t}
    text .t
    .t index "1.0 display wordstart"  ; # used to crash
} 1.0











test textIndex-23.1 {text paragraph start} {
    pack [text .t2]
    .t2 insert end " Text"
    set res 2.0
    for {set i 0} {$i < 2} {incr i} {
	lappend res [::tk::TextPrevPara .t2 [lindex $res end]]







>
>
>
>
>
>
>
>
>
>







1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
    lappend res [.t index "2.16 wordstart"] [.t index "2.15 wordstart"]
} {1.18 2.13 2.13}
test textIndex-22.15 {text index display wordstart} {
    catch {destroy .t}
    text .t
    .t index "1.0 display wordstart"  ; # used to crash
} 1.0
test textIndex-22.16 {text index wordstart, bug [57b821d2db]} {
    catch {destroy .t}
    text .t
    .t insert 1.0 " 123 5 789012  LINE-1\n\n 123 5 789000 LINE-3\n\n0123 5 789012  LINE-5"
    set res [.t index "1.1 wordstart"]
    lappend res [.t index "5.0 wordstart"]
    .t mark set insert 1.1
    lappend res [.t index "insert wordstart"]
    lappend res [.t index "5.1 wordstart"]
} {1.1 5.0 1.1 5.0}

test textIndex-23.1 {text paragraph start} {
    pack [text .t2]
    .t2 insert end " Text"
    set res 2.0
    for {set i 0} {$i < 2} {incr i} {
	lappend res [::tk::TextPrevPara .t2 [lindex $res end]]
960
961
962
963
964
965
966





















































967
968
969
970
971





    .t2 insert end "32\n33\n34\n36\n37\n38\n39" elided
    # then this used to crash Tk:
    .t2 see end
    focus -force .t2   ; # to see the cursor blink
    destroy .t2
} {}






















































# cleanup
rename textimage {}
catch {destroy .t}
cleanupTests
return












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
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
    .t2 insert end "32\n33\n34\n36\n37\n38\n39" elided
    # then this used to crash Tk:
    .t2 see end
    focus -force .t2   ; # to see the cursor blink
    destroy .t2
} {}

test textIndex-26.1 {GetIndex restricts the returned index to -startline/-endline in peers, bug [34db75c0ac]} {
    set res {}
    pack [text .t2]
    .t2 insert end "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n"
    pack [.t2 peer create .p2 -startline 2 -endline 3]
    lappend res [.p2 index "end"]
    lappend res [.p2 index "end lineend"]
    lappend res [.p2 index "end display lineend"]
    destroy .t2 .p2
    set res
} {2.0 2.0 2.0}
test textIndex-26.2 {GetIndex errors out if mark, image, window, or tag is outside peer -startline/-endline, bug [34db75c0ac]} {
    set res {}
    pack [text .t2]
    .t2 insert end "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n"
    pack [.t2 peer create .p2 -startline 2 -endline 3]
    .p2 configure -startline 3 -endline {}
    .t2 mark set mymark 1.0
    catch {.p2 index mymark} msg
    lappend res [.t2 index mymark] $msg
    image create photo redsquare -width 5 -height 5
    redsquare put red -to 0 0 4 4
    .t2 image create 1.0 -image redsquare
    catch {.p2 index redsquare} msg
    lappend res [.t2 index redsquare] $msg
    frame .f -width 10 -height 10 -bg blue
    .t2 window create 1.2 -window .f
    catch {.p2 index .f} msg
    lappend res [.t2 index .f] $msg
    .t2 tag add mytag 1.3
    catch {.p2 index mytag.first} msg
    lappend res [.t2 index mytag.first] $msg
    destroy .t2 .p2
    set res
} {1.0 {bad text index "mymark"} 1.0 {bad text index "redsquare"} 1.2\
   {bad text index ".f"} 1.3 {text doesn't contain any characters tagged with "mytag"}}

test textIndex-27.1 {TkTextGetIndex bug (wish8.6)} -body {
    catch {destroy .t}
    text .t
    .t insert current "Tes"
    .t mark set "end" 1.0
    .t insert end "t"
    .t get 1.0 "1.0 lineend"
} -result {Test}
test textIndex-27.2 {TkTextGetIndex bug (wish8.6)} -body {
    catch {destroy .t}
    text .t
    .t insert end "a"
    .t mark set 1.0 1.1
    .t index 1.0
} -result {1.0}

# cleanup
rename textimage {}
catch {destroy .t}
cleanupTests
return

# Local variables:
# mode: tcl
# End:
# vi:set ts=8 sw=4:

Changes to tests/textMark.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the code in the file tkTextMark.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test the code in the file tkTextMark.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87









88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105



106
107
108
109
110
111
112
test textMark-1.4 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {right 1.4}
test textMark-1.5 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t mark gr x left
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {left 1.3}
test textMark-1.6 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t mark gravity x right
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {right 1.4}
test textMark-1.7 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark set x 1.3
    .t mark gravity x gorp
} -result {bad mark gravity "gorp": must be left or right}
test textMark-1.8 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark gravity
} -result {wrong # args: should be ".t mark gravity markName ?gravity?"}

test textMark-2.1 {TkTextMarkCmd - "names" option} -body {
    .t mark names 2
} -returnCodes error -result {wrong # args: should be ".t mark names"}
test textMark-2.2 {TkTextMarkCmd - "names" option} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    lsort [.t mark na]
} -result {current insert}
test textMark-2.3 {TkTextMarkCmd - "names" option} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set a 1.1
    .t mark set "b c" 2.3
    lsort [.t mark names]
} -result {a {b c} current insert}










test textMark-3.1 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark set a
} -result {wrong # args: should be ".t mark set markName index"}
test textMark-3.2 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark s a b c
} -result {wrong # args: should be ".t mark set markName index"}
test textMark-3.3 {TkTextMarkCmd - "set" option} -body {
    .t mark set a @x
} -returnCodes error -result {bad text index "@x"}
test textMark-3.4 {TkTextMarkCmd - "set" option} -body {
    .t mark set a 1.2
    .t index a
} -result 1.2
test textMark-3.5 {TkTextMarkCmd - "set" option} -body {
    .t mark set a end
    .t index a
} -result {8.0}




test textMark-4.1 {TkTextMarkCmd - "unset" option} -body {
    .t mark unset
} -result {}
test textMark-4.2 {TkTextMarkCmd - "unset" option} -body {
    .t mark set a 1.2
    .t mark set b 2.3







|


















|
|












>
>
>
>
>
>
>
>
>



|

|
|











>
>
>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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 gravity x left
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {left 1.3}
test textMark-1.6 {TkTextMarkCmd - "gravity" option} -body {
    .t mark set x 1.3
    .t mark gravity x right
    .t insert 1.3 x
    list [.t mark gravity x] [.t index x]
} -result {right 1.4}
test textMark-1.7 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark set x 1.3
    .t mark gravity x gorp
} -result {bad mark gravity "gorp": must be left or right}
test textMark-1.8 {TkTextMarkCmd - "gravity" option} -returnCodes error -body {
    .t mark gravity
} -result {wrong # args: should be ".t mark gravity markName ?gravity?"}

test textMark-2.1 {TkTextMarkCmd - "names" option} -body {
    .t mark names 2 2
} -returnCodes error -result {wrong # args: should be ".t mark names ?-discardspecial? ?pattern?"}
test textMark-2.2 {TkTextMarkCmd - "names" option} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    lsort [.t mark na]
} -result {current insert}
test textMark-2.3 {TkTextMarkCmd - "names" option} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set a 1.1
    .t mark set "b c" 2.3
    lsort [.t mark names]
} -result {a {b c} current insert}
test textMark-2.4 {TkTextMarkCmd - "names" option} -body {
    .t mark names -discardspecial
} -result {}
test textMark-2.5 {TkTextMarkCmd - "names" option} -body {
    .t mark names ins*
} -result {insert}
test textMark-2.6 {TkTextMarkCmd - "names" option} -body {
    .t mark names -discardspecial ins*
} -result {}

test textMark-3.1 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark set a
} -result {wrong # args: should be ".t mark set markName index ?direction?"}
test textMark-3.2 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark s a b c d
} -result {wrong # args: should be ".t mark set markName index ?direction?"}
test textMark-3.3 {TkTextMarkCmd - "set" option} -body {
    .t mark set a @x
} -returnCodes error -result {bad text index "@x"}
test textMark-3.4 {TkTextMarkCmd - "set" option} -body {
    .t mark set a 1.2
    .t index a
} -result 1.2
test textMark-3.5 {TkTextMarkCmd - "set" option} -body {
    .t mark set a end
    .t index a
} -result {8.0}
test textMark-3.6 {TkTextMarkCmd - "set" option} -returnCodes error -body {
    .t mark s a b c
} -result {bad text index "b"}

test textMark-4.1 {TkTextMarkCmd - "unset" option} -body {
    .t mark unset
} -result {}
test textMark-4.2 {TkTextMarkCmd - "unset" option} -body {
    .t mark set a 1.2
    .t mark set b 2.3
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
} -result {current insert}

test textMark-5.1 {TkTextMarkCmd - miscellaneous} -returnCodes error -body {
    .t mark
} -result {wrong # args: should be ".t mark option ?arg ...?"}
test textMark-5.2 {TkTextMarkCmd - miscellaneous} -returnCodes error -body {
    .t mark foo
} -result {bad mark option "foo": must be gravity, names, next, previous, set, or unset}

test textMark-6.1 {TkTextMarkSegToIndex} -body {
    .t mark set a 1.2
    .t mark set b 1.2
    .t mark set c 1.2
    .t mark set d 1.4
    list [.t index a] [.t index b] [.t index c ] [.t index d]







|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
} -result {current insert}

test textMark-5.1 {TkTextMarkCmd - miscellaneous} -returnCodes error -body {
    .t mark
} -result {wrong # args: should be ".t mark option ?arg ...?"}
test textMark-5.2 {TkTextMarkCmd - miscellaneous} -returnCodes error -body {
    .t mark foo
} -result {bad mark option "foo": must be compare, exists, generate, gravity, names, next, previous, set, or unset}

test textMark-6.1 {TkTextMarkSegToIndex} -body {
    .t mark set a 1.2
    .t mark set b 1.2
    .t mark set c 1.2
    .t mark set d 1.4
    list [.t index a] [.t index b] [.t index c ] [.t index d]
173
174
175
176
177
178
179
180
181
182
183
184











185
186
187
188
189
190
191
} -cleanup {
  .t configure -startline {} -endline {}
  .pt configure -startline {} -endline {}
  .t mark unset mymark
} -result {1 {bad text index "mymark"} 1.0 1.0 1 {bad text index "mymark"} L 1 {bad text index "mymark"}}
test textMark-6.5 {insert and current marks in an empty peer - bug 3487407} -body {
  .t mark set insert 1.0
  .t configure -startline 5 -endline 5
  set res [.t index insert]
} -cleanup {
  .t configure -startline {} -endline {}
} -result {1.0}












test textMark-7.1 {MarkFindNext - invalid mark name} -body {
    .t mark next bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0







|




>
>
>
>
>
>
>
>
>
>
>







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
} -cleanup {
  .t configure -startline {} -endline {}
  .pt configure -startline {} -endline {}
  .t mark unset mymark
} -result {1 {bad text index "mymark"} 1.0 1.0 1 {bad text index "mymark"} L 1 {bad text index "mymark"}}
test textMark-6.5 {insert and current marks in an empty peer - bug 3487407} -body {
  .t mark set insert 1.0
  .t configure -start 5 -end 5
  set res [.t index insert]
} -cleanup {
  .t configure -startline {} -endline {}
} -result {1.0}
test textMark-6.6 {attempt to move the insert mark beyond peer -endline - bug 34db75c0ac} -body {
  .t peer create .p -startline 1 -endline 2
  pack .p
  update
  .p mark set insert 1.2
  focus -force .p
  event generate .p <<NextLine>>  ; # shall not error out
  set res [.p index insert]
} -cleanup {
  destroy .p
} -result {1.2}

test textMark-7.1 {MarkFindNext - invalid mark name} -body {
    .t mark next bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0
230
231
232
233
234
235
236
237
238





















239
240
241
242
243
244
245
    .t mark set insert 3.0
    .t mark next insert
} -result {}
test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next insert]]
} -result {current insert mymark}






















test textMark-8.1 {MarkFindPrev - invalid mark name} -body {
    .t mark prev bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-8.2 {MarkFindPrev - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0







|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    .t mark set insert 3.0
    .t mark next insert
} -result {}
test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next current]]
} -result {current insert mymark}
test textMark-7.10 {MarkFindNext - discard special marks} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark next -discardspecial begin
} -result {}
test textMark-7.11 {MarkFindNext - match pattern} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark next begin ins*
} -result {insert}
test textMark-7.12 {MarkFindNext - match pattern - discard special marks} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set current 1.0
    .t mark set insert 3.0
    .t mark next -discardspecial begin ins*
} -result {}

test textMark-8.1 {MarkFindPrev - invalid mark name} -body {
    .t mark prev bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-8.2 {MarkFindPrev - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0
289
290
291
292
293
294
295





















296
297
298
299
300
301
302
303
304
305
306

} -result {}
test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
} -result {current insert mymark}






















destroy .pt
destroy .t

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











>
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
} -result {}
test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
} -result {current insert mymark}
test textMark-8.10 {MarkFindPrev - discard special marks} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set insert 3.0
    .t mark set current end
    .t mark prev -discardspecial end
} -result {}
test textMark-8.11 {MarkFindPrev - match pattern} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set insert 3.0
    .t mark set current 2.0
    .t mark prev end ins*
} -result {insert}
test textMark-8.12 {MarkFindPrev - match pattern - discard special marks} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set insert 3.0
    .t mark set current 2.0
    .t mark prev -discardspecial end ins*
} -result {}

destroy .pt
destroy .t

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:
# vi:set ts=8 sw=4:

Changes to tests/textTag.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
35
36
37
38
39
40
# This file is a Tcl script to test the code in the file tkTextTag.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

set textWidgetFont {Courier 12}
set bigFont        {Courier 24}

# what is needed is a font that is both fixed-width and featuring a
# specific size because in some tests (that will be constrained by
# haveFontSizes), a tag applying the $bigFont will be set to some
# characters, which action has the effect of changing what character
# is under the mouse pointer, which is the purpose of the tests
testConstraint haveFontSizes [expr {
    [font metrics $textWidgetFont -fixed] &&
    [font actual  $textWidgetFont -size] == 12 &&
    [font metrics $bigFont -fixed] &&
    [font actual  $bigFont -size] == 24 }
]



testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]

destroy .t
text .t -width 20 -height 10

pack .t -expand 1 -fill both
update
.t debug on

wm geometry . {}






|







|
|

<
<
<
<
<
<
<
|
|
|
<
>
>
|
<
<


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16







17
18
19

20
21
22


23
24
25
26
27
28
29
30
31
32
# This file is a Tcl script to test the code in the file tkTextTag.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

set fixedFont {Courier 12}
set bigFont   {Helvetica 24}








# Warn the user if the actual font is too different from what was requested.
if {[font metrics [font actual $fixedFont] -fixed] != 1} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\

does not seem to be a fixed-width font as expected. If this is really the case, many upcoming\
tests will fail."
}



destroy .t
text .t -width 20 -height 10 -font $fixedFont

pack .t -expand 1 -fill both
update
.t debug on

wm geometry . {}

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    .t tag configure x -bgstipple [lindex [.t tag configure x -bgstipple] 3]
} -returnCodes error -result {bitmap "badStipple" not defined}
test textTag-1.5 {tag configuration options} -body {
    .t tag configure x -borderwidth 2
    .t tag cget x -borderwidth
} -cleanup {
    .t tag configure x -borderwidth [lindex [.t tag configure x -borderwidth] 3]
} -result 2
test textTag-1.6 {configuration options} -body {
    .t tag configure x -borderwidth 46q
} -cleanup {
    .t tag configure x -borderwidth [lindex [.t tag configure x -borderwidth] 3]
} -returnCodes error -result {bad screen distance "46q"}
test textTag-1.7 {tag configuration options} -body {
    .t tag configure x -fgstipple gray25
    .t tag cget x -fgstipple
} -cleanup {
    .t tag configure x -fgstipple [lindex [.t tag configure x -fgstipple] 3]
} -result {gray25}
test textTag-1.8 {configuration options} -body {







|




|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
    .t tag configure x -bgstipple [lindex [.t tag configure x -bgstipple] 3]
} -returnCodes error -result {bitmap "badStipple" not defined}
test textTag-1.5 {tag configuration options} -body {
    .t tag configure x -borderwidth 2
    .t tag cget x -borderwidth
} -cleanup {
    .t tag configure x -borderwidth [lindex [.t tag configure x -borderwidth] 3]
} -result {2}
test textTag-1.6 {configuration options} -body {
    .t tag configure x -borderwidth 46q
} -cleanup {
    .t tag configure x -borderwidth [lindex [.t tag configure x -borderwidth] 3]
} -returnCodes error -result {expected screen distance or "" but got "46q"}
test textTag-1.7 {tag configuration options} -body {
    .t tag configure x -fgstipple gray25
    .t tag cget x -fgstipple
} -cleanup {
    .t tag configure x -fgstipple [lindex [.t tag configure x -fgstipple] 3]
} -result {gray25}
test textTag-1.8 {configuration options} -body {
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
} -cleanup {
    .t tag configure x -justify [lindex [.t tag configure x -justify] 3]
} -result {left}
test textTag-1.13 {configuration options} -body {
    .t tag configure x -justify middle
} -cleanup {
    .t tag configure x -justify [lindex [.t tag configure x -justify] 3]
} -returnCodes error -result {bad justification "middle": must be left, right, or center}
test textTag-1.14 {tag configuration options} -body {
    .t tag configure x -lmargin1 10
    .t tag cget x -lmargin1
} -cleanup {
    .t tag configure x -lmargin1 [lindex [.t tag configure x -lmargin1] 3]
} -result 10
test textTag-1.15 {configuration options} -body {
    .t tag configure x -lmargin1 bad
} -cleanup {
    .t tag configure x -lmargin1 [lindex [.t tag configure x -lmargin1] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.16 {tag configuration options} -body {
    .t tag configure x -lmargin2 10
    .t tag cget x -lmargin2
} -cleanup {
    .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3]
} -result 10
test textTag-1.17 {configuration options} -body {
    .t tag configure x -lmargin2 bad
} -cleanup {
    .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.17a {tag configuration options} -body {
    .t tag configure x -lmargincolor lightgreen
    .t tag cget x -lmargincolor
} -cleanup {
    .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3]
} -result {lightgreen}
test textTag-1.17b {configuration options} -body {
    .t tag configure x -lmargincolor non-existent
} -cleanup {
    .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.18 {tag configuration options} -body {
    .t tag configure x -offset 2
    .t tag cget x -offset
} -cleanup {
    .t tag configure x -offset [lindex [.t tag configure x -offset] 3]
} -result 2
test textTag-1.19 {configuration options} -body {
    .t tag configure x -offset 100xyz
} -cleanup {
    .t tag configure x -offset [lindex [.t tag configure x -offset] 3]
} -returnCodes error -result {bad screen distance "100xyz"}
test textTag-1.20 {tag configuration options} -body {
    .t tag configure x -overstrike on
    .t tag cget x -overstrike
} -cleanup {
    .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3]
} -result {on}
test textTag-1.21 {configuration options} -body {
    .t tag configure x -overstrike stupid
} -cleanup {
    .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3]
} -returnCodes error -result {expected boolean value but got "stupid"}
test textTag-1.21a {tag configuration options} -body {
    .t tag configure x -overstrikefg red
    .t tag cget x -overstrikefg
} -cleanup {
    .t tag configure x -overstrikefg [lindex [.t tag configure x -overstrikefg] 3]
} -result {red}
test textTag-1.21b {configuration options} -body {
    .t tag configure x -overstrikefg stupid
} -cleanup {
    .t tag configure x -overstrikefg [lindex [.t tag configure x -overstrikefg] 3]
} -returnCodes error -result {unknown color name "stupid"}
test textTag-1.22 {tag configuration options} -body {
    .t tag configure x -relief raised
    .t tag cget x -relief
} -cleanup {
    .t tag configure x -relief [lindex [.t tag configure x -relief] 3]
} -result {raised}
test textTag-1.23 {configuration options} -body {
    .t tag configure x -relief stupid
} -cleanup {
    .t tag configure x -relief [lindex [.t tag configure x -relief] 3]
} -returnCodes error -result {bad relief "stupid": must be flat, groove, raised, ridge, solid, or sunken}
test textTag-1.24 {tag configuration options} -body {
    .t tag configure x -rmargin 10
    .t tag cget x -rmargin
} -cleanup {
    .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3]
} -result 10
test textTag-1.25 {configuration options} -body {
    .t tag configure x -rmargin bad
} -cleanup {
    .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.25a {tag configuration options} -body {
    .t tag configure x -rmargincolor darkblue
    .t tag cget x -rmargincolor
} -cleanup {
    .t tag configure x -rmargincolor [lindex [.t tag configure x -rmargincolor] 3]
} -result {darkblue}
test textTag-1.25b {configuration options} -body {







|





|




|





|




|
















|




|





|




|

|
|

|


|

|











|





|




|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
} -cleanup {
    .t tag configure x -justify [lindex [.t tag configure x -justify] 3]
} -result {left}
test textTag-1.13 {configuration options} -body {
    .t tag configure x -justify middle
} -cleanup {
    .t tag configure x -justify [lindex [.t tag configure x -justify] 3]
} -returnCodes error -result {bad justify "middle": must be left, right, center, full, or ""}
test textTag-1.14 {tag configuration options} -body {
    .t tag configure x -lmargin1 10
    .t tag cget x -lmargin1
} -cleanup {
    .t tag configure x -lmargin1 [lindex [.t tag configure x -lmargin1] 3]
} -result {10}
test textTag-1.15 {configuration options} -body {
    .t tag configure x -lmargin1 bad
} -cleanup {
    .t tag configure x -lmargin1 [lindex [.t tag configure x -lmargin1] 3]
} -returnCodes error -result {expected screen distance or "" but got "bad"}
test textTag-1.16 {tag configuration options} -body {
    .t tag configure x -lmargin2 10
    .t tag cget x -lmargin2
} -cleanup {
    .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3]
} -result {10}
test textTag-1.17 {configuration options} -body {
    .t tag configure x -lmargin2 bad
} -cleanup {
    .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3]
} -returnCodes error -result {expected screen distance or "" but got "bad"}
test textTag-1.17a {tag configuration options} -body {
    .t tag configure x -lmargincolor lightgreen
    .t tag cget x -lmargincolor
} -cleanup {
    .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3]
} -result {lightgreen}
test textTag-1.17b {configuration options} -body {
    .t tag configure x -lmargincolor non-existent
} -cleanup {
    .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.18 {tag configuration options} -body {
    .t tag configure x -offset 2
    .t tag cget x -offset
} -cleanup {
    .t tag configure x -offset [lindex [.t tag configure x -offset] 3]
} -result {2}
test textTag-1.19 {configuration options} -body {
    .t tag configure x -offset 100xyz
} -cleanup {
    .t tag configure x -offset [lindex [.t tag configure x -offset] 3]
} -returnCodes error -result {expected screen distance or "" but got "100xyz"}
test textTag-1.20 {tag configuration options} -body {
    .t tag configure x -overstrike on
    .t tag cget x -overstrike
} -cleanup {
    .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3]
} -result 1
test textTag-1.21 {configuration options} -body {
    .t tag configure x -overstrike stupid
} -cleanup {
    .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3]
} -returnCodes error -result {expected boolean value or "" but got "stupid"}
test textTag-1.21a {tag configuration options} -body {
    .t tag configure x -overstrikecolor red
    .t tag cget x -overstrikecolor
} -cleanup {
    .t tag configure x -overstrikecolor [lindex [.t tag configure x -overstrikecolor] 3]
} -result {red}
test textTag-1.21b {configuration options} -body {
    .t tag configure x -overstrikecolor stupid
} -cleanup {
    .t tag configure x -overstrikecolor [lindex [.t tag configure x -overstrikecolor] 3]
} -returnCodes error -result {unknown color name "stupid"}
test textTag-1.22 {tag configuration options} -body {
    .t tag configure x -relief raised
    .t tag cget x -relief
} -cleanup {
    .t tag configure x -relief [lindex [.t tag configure x -relief] 3]
} -result {raised}
test textTag-1.23 {configuration options} -body {
    .t tag configure x -relief stupid
} -cleanup {
    .t tag configure x -relief [lindex [.t tag configure x -relief] 3]
} -returnCodes error -result {bad relief "stupid": must be flat, groove, raised, ridge, solid, sunken, or ""}
test textTag-1.24 {tag configuration options} -body {
    .t tag configure x -rmargin 10
    .t tag cget x -rmargin
} -cleanup {
    .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3]
} -result {10}
test textTag-1.25 {configuration options} -body {
    .t tag configure x -rmargin bad
} -cleanup {
    .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3]
} -returnCodes error -result {expected screen distance or "" but got "bad"}
test textTag-1.25a {tag configuration options} -body {
    .t tag configure x -rmargincolor darkblue
    .t tag cget x -rmargincolor
} -cleanup {
    .t tag configure x -rmargincolor [lindex [.t tag configure x -rmargincolor] 3]
} -result {darkblue}
test textTag-1.25b {configuration options} -body {
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315



















316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    .t tag configure x -selectforeground [lindex [.t tag configure x -selectforeground] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.26 {tag configuration options} -body {
    .t tag configure x -spacing1 10
    .t tag cget x -spacing1
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3]
} -result 10
test textTag-1.27 {configuration options} -body {
    .t tag configure x -spacing1 bad
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.28 {tag configuration options} -body {
    .t tag configure x -spacing2 10
    .t tag cget x -spacing2
} -cleanup {
    .t tag configure x -spacing2 [lindex [.t tag configure x -spacing2] 3]
} -result 10
test textTag-1.29 {configuration options} -body {
    .t tag configure x -spacing2 bad

} -cleanup {
    .t tag configure x -spacing2 [lindex [.t tag configure x -spacing2] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.30 {tag configuration options} -body {
    .t tag configure x -spacing3 10
    .t tag cget x -spacing3
} -cleanup {
    .t tag configure x -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -result 10
test textTag-1.31 {configuration options} -body {
    .t tag configure x -spacing3 bad
} -cleanup {
    .t tag configure x -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -returnCodes error -result {bad screen distance "bad"}
test textTag-1.32 {tag configuration options} -body {
    .t tag configure x -tabs {10 20 30}
    .t tag cget x -tabs
} -cleanup {
    .t tag configure x -tabs [lindex [.t tag configure x -tabs] 3]
} -result {10 20 30}
test textTag-1.33 {configuration options} -body {
    .t tag configure x -tabs {10 fork}
} -cleanup {
    .t tag configure x -tabs [lindex [.t tag configure x -tabs] 3]
} -returnCodes error -result {bad tab alignment "fork": must be left, right, center, or numeric}
test textTag-1.34 {tag configuration options} -body {
    .t tag configure x -underline no
    .t tag cget x -underline
} -cleanup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -result {no}
test textTag-1.35 {configuration options} -body {
    .t tag configure x -underline stupid
} -cleanup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -returnCodes error -result {expected boolean value but got "stupid"}
test textTag-1.36 {tag configuration options} -body {
    .t tag configure x -underlinefg red
    .t tag cget x -underlinefg
} -cleanup {
    .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3]
} -result {red}
test textTag-1.37 {configuration options} -body {
    .t tag configure x -underlinefg stupid
} -cleanup {
    .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3]
} -returnCodes error -result {unknown color name "stupid"}





















test textTag-2.1 {TkTextTagCmd - "add" option} -body {
    .t tag
} -returnCodes error -result {wrong # args: should be ".t tag option ?arg ...?"}
test textTag-2.2 {TkTextTagCmd - "add" option} -body {
    .t tag gorp
} -returnCodes error -result {bad tag option "gorp": must be add, bind, cget, configure, delete, lower, names, nextrange, prevrange, raise, ranges, or remove}
test textTag-2.3 {TkTextTagCmd - "add" option} -body {
    .t tag add foo
} -returnCodes error -result {wrong # args: should be ".t tag add tagName index1 ?index2 index1 index2 ...?"}
test textTag-2.4 {TkTextTagCmd - "add" option} -body {
    .t tag add x gorp
} -returnCodes error -result {bad text index "gorp"}
test textTag-2.5 {TkTextTagCmd - "add" option} -body {







|




|





|
|
|
>

|
|





|




|
















|




|

|
|

|


|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
    .t tag configure x -selectforeground [lindex [.t tag configure x -selectforeground] 3]
} -returnCodes error -result {unknown color name "non-existent"}
test textTag-1.26 {tag configuration options} -body {
    .t tag configure x -spacing1 10
    .t tag cget x -spacing1
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3]
} -result {10}
test textTag-1.27 {configuration options} -body {
    .t tag configure x -spacing1 bad
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3]
} -returnCodes error -result {expected screen distance or "" but got "bad"}
test textTag-1.28 {tag configuration options} -body {
    .t tag configure x -spacing2 10
    .t tag cget x -spacing2
} -cleanup {
    .t tag configure x -spacing2 [lindex [.t tag configure x -spacing2] 3]
} -result {10}
test textTag-1.29 {configuration options, bug [026e2bb685]} -body {
    catch {.t tag configure x -spacing3 5 -spacing2 bad -spacing1 morebad} msg
    list $msg [.t tag configure x -spacing1] [.t tag configure x -spacing2] [.t tag configure x -spacing3]
} -cleanup {
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3] -spacing2 [lindex [.t tag configure x -spacing2] 3] -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -result {{expected screen distance or "" but got "bad"} {-spacing1 {} {} {} {}} {-spacing2 {} {} {} {}} {-spacing3 {} {} {} 5}}
test textTag-1.30 {tag configuration options} -body {
    .t tag configure x -spacing3 10
    .t tag cget x -spacing3
} -cleanup {
    .t tag configure x -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -result {10}
test textTag-1.31 {configuration options} -body {
    .t tag configure x -spacing3 bad
} -cleanup {
    .t tag configure x -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -returnCodes error -result {expected screen distance or "" but got "bad"}
test textTag-1.32 {tag configuration options} -body {
    .t tag configure x -tabs {10 20 30}
    .t tag cget x -tabs
} -cleanup {
    .t tag configure x -tabs [lindex [.t tag configure x -tabs] 3]
} -result {10 20 30}
test textTag-1.33 {configuration options} -body {
    .t tag configure x -tabs {10 fork}
} -cleanup {
    .t tag configure x -tabs [lindex [.t tag configure x -tabs] 3]
} -returnCodes error -result {bad tab alignment "fork": must be left, right, center, or numeric}
test textTag-1.34 {tag configuration options} -body {
    .t tag configure x -underline no
    .t tag cget x -underline
} -cleanup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -result 0
test textTag-1.35 {configuration options} -body {
    .t tag configure x -underline stupid
} -cleanup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -returnCodes error -result {expected boolean value or "" but got "stupid"}
test textTag-1.36 {tag configuration options} -body {
    .t tag configure x -underlinecolor red
    .t tag cget x -underlinecolor
} -cleanup {
    .t tag configure x -underlinecolor [lindex [.t tag configure x -underlinecolor] 3]
} -result {red}
test textTag-1.37 {configuration options} -body {
    .t tag configure x -underlinecolor stupid
} -cleanup {
    .t tag configure x -underlinecolor [lindex [.t tag configure x -underlinecolor] 3]
} -returnCodes error -result {unknown color name "stupid"}
test textTag-1.38 {configuration options} -body {
    .t tag configure x -undo eh
} -cleanup {
    .t tag configure x -undo 1
} -returnCodes error -result {expected boolean value but got "eh"}
test textTag-1.39 {configuration options} -setup {
    .t tag configure x -underline [lindex [.t tag configure x -underline] 3]
} -body {
    .t tag cget x -undo
} -result {1}
test textTag-1.40 {configuration options} -setup {
    text .u
} -body {
    .u configure -undotagging 0
    .u tag configure x -underline 0
    .u tag cget x -undo
} -cleanup {
    destroy .u
} -result {0}


test textTag-2.1 {TkTextTagCmd - "add" option} -body {
    .t tag
} -returnCodes error -result {wrong # args: should be ".t tag option ?arg ...?"}
test textTag-2.2 {TkTextTagCmd - "add" option} -body {
    .t tag gorp
} -returnCodes error -result {bad tag option "gorp": must be add, bind, cget, clear, configure, delete, findnext, findprev, getrange, lower, names, nextrange, prevrange, priority, raise, ranges, or remove}
test textTag-2.3 {TkTextTagCmd - "add" option} -body {
    .t tag add foo
} -returnCodes error -result {wrong # args: should be ".t tag add tagName index1 ?index2 index1 index2 ...?"}
test textTag-2.4 {TkTextTagCmd - "add" option} -body {
    .t tag add x gorp
} -returnCodes error -result {bad text index "gorp"}
test textTag-2.5 {TkTextTagCmd - "add" option} -body {
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
    .t tag remove sel 1.0 end
} -result {1.1 1.5 2.4 2.5}
test textTag-2.14 {tag add before -startline - Bug 1615425} -body {
    text .tt
    for {set i 1} {$i <10} {incr i} {
        .tt insert end "Line $i\n"
    }
    .tt tag configure mytag -font {Courier 12 bold}
    .tt peer create .ptt
    .ptt configure -startline 3 -endline 7
    # the test succeeds if next line does not crash
    .tt tag add mytag 1.0 1.end
    destroy .ptt .tt
    set res 1
} -result 1


test textTag-3.1 {TkTextTagCmd - "bind" option} -body {
    .t tag bind
} -returnCodes error -result {wrong # args: should be ".t tag bind tagName ?sequence? ?command?"}
test textTag-3.2 {TkTextTagCmd - "bind" option} -body {
    .t tag bind 1 2 3 4







|






|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
    .t tag remove sel 1.0 end
} -result {1.1 1.5 2.4 2.5}
test textTag-2.14 {tag add before -startline - Bug 1615425} -body {
    text .tt
    for {set i 1} {$i <10} {incr i} {
        .tt insert end "Line $i\n"
    }
    .tt tag configure mytag -offset 2
    .tt peer create .ptt
    .ptt configure -startline 3 -endline 7
    # the test succeeds if next line does not crash
    .tt tag add mytag 1.0 1.end
    destroy .ptt .tt
    set res 1
} -result {1}


test textTag-3.1 {TkTextTagCmd - "bind" option} -body {
    .t tag bind
} -returnCodes error -result {wrong # args: should be ".t tag bind tagName ?sequence? ?command?"}
test textTag-3.2 {TkTextTagCmd - "bind" option} -body {
    .t tag bind 1 2 3 4
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696


697












698
699




700
701
702



703
704
705
706
707
708
709
710
711
} -returnCodes error -result {value for "-underline" missing}
test textTag-5.4 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underline yes
    .t tag configure x -underline
} -cleanup {
    .t tag delete x
} -result {-underline {} {} {} yes}
test textTag-5.4a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underlinefg lightgreen
    .t tag configure x -underlinefg
} -cleanup {
    .t tag delete x
} -result {-underlinefg {} {} {} lightgreen}
test textTag-5.5 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -overstrike on
    .t tag cget x -overstrike
} -cleanup {
    .t tag delete x
} -result {on}
test textTag-5.5a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -overstrikefg lightgreen
    .t tag configure x -overstrikefg
} -cleanup {
    .t tag delete x
} -result {-overstrikefg {} {} {} lightgreen}
test textTag-5.6 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -overstrike foo
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected boolean value but got "foo"}
test textTag-5.7 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underline stupid
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected boolean value but got "stupid"}
test textTag-5.8 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify left
    .t tag configure x -justify
} -cleanup {
    .t tag delete x
} -result {-justify {} {} {} left}
test textTag-5.9 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify bogus
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justification "bogus": must be left, right, or center}
test textTag-5.10 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify fill
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justification "fill": must be left, right, or center}
test textTag-5.11 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -offset 2
    .t tag configure x -offset
} -cleanup {
    .t tag delete x
} -result {-offset {} {} {} 2}
test textTag-5.12 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -offset 1.0q
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "1.0q"}
test textTag-5.13 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin1 2 -lmargin2 4 -rmargin 5 \
        -lmargincolor darkblue -rmargincolor lightgreen
    list [.t tag configure x -lmargin1] [.t tag configure x -lmargin2] \
        [.t tag configure x -rmargin] [.t tag configure x -lmargincolor] \
        [.t tag configure x -rmargincolor]
} -cleanup {
    .t tag delete x
} -result [list {-lmargin1 {} {} {} 2} {-lmargin2 {} {} {} 4} \
                {-rmargin {} {} {} 5} \
                {-lmargincolor {} {} {} darkblue} {-rmargincolor {} {} {} lightgreen} \
          ]
test textTag-5.14 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin1 2.0x
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "2.0x"}
test textTag-5.15 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin2 gorp
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "gorp"}
test textTag-5.15a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargincolor rainbow
} -cleanup {
    .t tag delete x
} -returnCodes error -result {unknown color name "rainbow"}
test textTag-5.16 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -rmargin 140.1.1
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "140.1.1"}
test textTag-5.16a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -rmargincolor rainbow
} -cleanup {
    .t tag delete x
} -returnCodes error -result {unknown color name "rainbow"}
.t tag delete x
test textTag-5.17 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 2 -spacing2 4 -spacing3 6
    list [.t tag configure x -spacing1] [.t tag configure x -spacing2] \
        [.t tag configure x -spacing3]
} -cleanup {
    .t tag delete x
} -result {{-spacing1 {} {} {} 2} {-spacing2 {} {} {} 4} {-spacing3 {} {} {} 6}}
test textTag-5.18 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 2.0x
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "2.0x"}
test textTag-5.19 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 lousy
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "lousy"}
test textTag-5.20 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 4.2.3
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad screen distance "4.2.3"}
test textTag-5.21 {TkTextTagCmd - "configure" option} -body {
    .t configure -selectborderwidth 2 -selectforeground blue \
        -selectbackground black
    .t tag configure sel -borderwidth 4 -foreground green -background yellow
    set x {}
    foreach i {-selectborderwidth -selectforeground -selectbackground} {
        lappend x [lindex [.t configure $i] 4]
    }
    return $x
} -result {4 green yellow}
test textTag-5.22 {TkTextTagCmd - "configure" option} -body {
    .t configure -selectborderwidth 20
    .t tag configure sel -borderwidth {}
    .t cget -selectborderwidth
} -result {}
test textTag-5.23 {TkTextTagCmd - "configure" option} -body {
    set x {}
    # when [.t tag cget sel -selectbackground] == "", mirroring happens between
    #     the text widget option -selectbackground
    # and the tag         option -background
    .t tag configure sel -selectbackground {}
    .t configure -selectbackground black
    .t tag configure sel -background yellow
    lappend x [.t cget -selectbackground]
    .t tag configure sel -background orange
    .t configure -selectbackground blue
    lappend x [.t tag cget sel -background]
    # when [.t tag cget sel -selectbackground] != "", mirroring happens between
    #     the text widget option -selectbackground
    # and the tag         option -selectbackground
    .t tag configure sel -selectbackground green
    .t configure -selectbackground red
    lappend x [.t tag cget sel -selectbackground]
    .t configure -selectbackground black
    .t tag configure sel -selectbackground white
    lappend x [.t cget -selectbackground]
    return $x
} -result {yellow blue red white}
test textTag-5.24 {TkTextTagCmd - "configure" option} -body {
    set x {}
    # when [.t tag cget sel -selectforeground] == "", mirroring happens between
    #     the text widget option -selectforeground
    # and the tag         option -foreground
    .t tag configure sel -selectforeground {}
    .t configure -selectforeground black
    .t tag configure sel -foreground yellow
    lappend x [.t cget -selectforeground]
    .t tag configure sel -foreground orange
    .t configure -selectforeground blue
    lappend x [.t tag cget sel -foreground]
    # when [.t tag cget sel -selectforeground] != "", mirroring happens between
    #     the text widget option -selectforeground
    # and the tag         option -selectforeground


    .t tag configure sel -selectforeground green












    .t configure -selectforeground red
    lappend x [.t tag cget sel -selectforeground]




    .t configure -selectforeground black
    .t tag configure sel -selectforeground white
    lappend x [.t cget -selectforeground]



    return $x
} -result {yellow blue red white}

test textTag-6.1 {TkTextTagCmd - "delete" option} -body {
    .t tag delete
} -returnCodes error -result {wrong # args: should be ".t tag delete tagName ?tagName ...?"}
test textTag-6.2 {TkTextTagCmd - "delete" option} -body {
    .t tag delete zork
} -returnCodes ok -result {}







|


|
|


|






|


|
|


|




|





|












|





|












|


















|





|











|




















|





|





|

















|









|
<
<
<
<
<
<
<
<
<
<
<
<
<









|
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
|
|
|
>
>
>

|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683













684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
} -returnCodes error -result {value for "-underline" missing}
test textTag-5.4 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underline yes
    .t tag configure x -underline
} -cleanup {
    .t tag delete x
} -result {-underline {} {} {} 1}
test textTag-5.4a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underlinecolor lightgreen
    .t tag configure x -underlinecolor
} -cleanup {
    .t tag delete x
} -result {-underlinecolor {} {} {} lightgreen}
test textTag-5.5 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -overstrike on
    .t tag cget x -overstrike
} -cleanup {
    .t tag delete x
} -result 1
test textTag-5.5a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -overstrikecolor lightgreen
    .t tag configure x -overstrikecolor
} -cleanup {
    .t tag delete x
} -result {-overstrikecolor {} {} {} lightgreen}
test textTag-5.6 {TkTextTagCmd - "configure" option} -body {
    .t tag configure x -overstrike foo
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected boolean value or "" but got "foo"}
test textTag-5.7 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -underline stupid
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected boolean value or "" but got "stupid"}
test textTag-5.8 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify left
    .t tag configure x -justify
} -cleanup {
    .t tag delete x
} -result {-justify {} {} {} left}
test textTag-5.9 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify bogus
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justify "bogus": must be left, right, center, full, or ""}
test textTag-5.10 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -justify fill
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justify "fill": must be left, right, center, full, or ""}
test textTag-5.11 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -offset 2
    .t tag configure x -offset
} -cleanup {
    .t tag delete x
} -result {-offset {} {} {} 2}
test textTag-5.12 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -offset 1.0q
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "1.0q"}
test textTag-5.13 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin1 2 -lmargin2 4 -rmargin 5 \
        -lmargincolor darkblue -rmargincolor lightgreen
    list [.t tag configure x -lmargin1] [.t tag configure x -lmargin2] \
        [.t tag configure x -rmargin] [.t tag configure x -lmargincolor] \
        [.t tag configure x -rmargincolor]
} -cleanup {
    .t tag delete x
} -result [list {-lmargin1 {} {} {} 2} {-lmargin2 {} {} {} 4} \
                {-rmargin {} {} {} 5} \
                {-lmargincolor {} {} {} darkblue} {-rmargincolor {} {} {} lightgreen} \
          ]
test textTag-5.14 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin1 2.0x
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "2.0x"}
test textTag-5.15 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargin2 gorp
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "gorp"}
test textTag-5.15a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -lmargincolor rainbow
} -cleanup {
    .t tag delete x
} -returnCodes error -result {unknown color name "rainbow"}
test textTag-5.16 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -rmargin 140.1.1
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "140.1.1"}
test textTag-5.16a {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -rmargincolor rainbow
} -cleanup {
    .t tag delete x
} -returnCodes error -result {unknown color name "rainbow"}
.t tag delete x
test textTag-5.17 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 2 -spacing2 4 -spacing3 6
    list [.t tag configure x -spacing1] [.t tag configure x -spacing2] \
        [.t tag configure x -spacing3]
} -cleanup {
    .t tag delete x
} -result {{-spacing1 {} {} {} 2} {-spacing2 {} {} {} 4} {-spacing3 {} {} {} 6}}
test textTag-5.18 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 2.0x
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "2.0x"}
test textTag-5.19 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 lousy
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "lousy"}
test textTag-5.20 {TkTextTagCmd - "configure" option} -body {
    .t tag delete x
    .t tag configure x -spacing1 4.2.3
} -cleanup {
    .t tag delete x
} -returnCodes error -result {expected screen distance or "" but got "4.2.3"}
test textTag-5.21 {TkTextTagCmd - "configure" option} -body {
    .t configure -selectborderwidth 2 -selectforeground blue \
        -selectbackground black
    .t tag configure sel -borderwidth 4 -foreground green -background yellow
    set x {}
    foreach i {-selectborderwidth -selectforeground -selectbackground} {
        lappend x [lindex [.t configure $i] 4]
    }
    return $x
} -result {4 green yellow}
test textTag-5.22 {TkTextTagCmd - "configure" option} -body {
    .t configure -selectborderwidth 20
    .t tag configure sel -borderwidth {}
    .t cget -selectborderwidth
} -result {}
test textTag-5.23 {TkTextTagCmd - "configure" option} -body {
    set x {}
    # Mirroring happens between
    #     the text widget option -selectbackground
    # and the tag         option -background
    .t tag configure sel -selectbackground {}
    .t configure -selectbackground black
    .t tag configure sel -background yellow
    lappend x [.t cget -selectbackground]
    .t tag configure sel -background orange
    .t configure -selectbackground blue
    lappend x [.t tag cget sel -background]
    # Mirroring happens between













    #     the text widget option -selectforeground
    # and the tag         option -foreground
    .t tag configure sel -selectforeground {}
    .t configure -selectforeground black
    .t tag configure sel -foreground yellow
    lappend x [.t cget -selectforeground]
    .t tag configure sel -foreground orange
    .t configure -selectforeground blue
    lappend x [.t tag cget sel -foreground]
    # Mirroring happens between
    #     the text widget option -inactiveselectbackground
    # and the tag         option -inactivebackground
    .t tag configure sel -inactiveselectbackground {}
    .t configure -inactiveselectbackground black
    .t tag configure sel -inactivebackground yellow
    lappend x [.t cget -inactiveselectbackground]
    .t tag configure sel -inactivebackground orange
    .t configure -inactiveselectbackground blue
    lappend x [.t tag cget sel -inactivebackground]
    # Mirroring happens between
    #     the text widget option -inactiveselectforeground
    # and the tag         option -inactiveforeground
    .t tag configure sel -inactiveselectforeground {}
    .t configure -inactiveselectforeground black
    .t tag configure sel -inactiveforeground yellow
    lappend x [.t cget -inactiveselectforeground]
    .t tag configure sel -inactiveforeground orange
    .t configure -inactiveselectforeground blue
    lappend x [.t tag cget sel -inactiveforeground]
    # Mirroring happens between
    #     the text widget option -selectborderwidth
    # and the tag         option -borderwidth
    .t tag configure sel -borderwidth 0
    .t configure -selectborderwidth 1
    .t tag configure sel -borderwidth 2
    lappend x [.t cget -selectborderwidth]
    .t tag configure sel -borderwidth 3
    .t configure -selectborderwidth 4
    lappend x [.t tag cget sel -borderwidth]
    return $x
} -result {yellow blue yellow blue yellow blue yellow blue 2 4}

test textTag-6.1 {TkTextTagCmd - "delete" option} -body {
    .t tag delete
} -returnCodes error -result {wrong # args: should be ".t tag delete tagName ?tagName ...?"}
test textTag-6.2 {TkTextTagCmd - "delete" option} -body {
    .t tag delete zork
} -returnCodes ok -result {}
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
} -result {sel b a c d}


test textTag-8.1 {TkTextTagCmd - "names" option} -body {
    .t tag names a b
} -cleanup {
    .t tag delete {*}[.t tag names]
} -returnCodes error -result {wrong # args: should be ".t tag names ?index?"}
test textTag-8.2 {TkTextTagCmd - "names" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {







|







806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
} -result {sel b a c d}


test textTag-8.1 {TkTextTagCmd - "names" option} -body {
    .t tag names a b
} -cleanup {
    .t tag delete {*}[.t tag names]
} -returnCodes error -result {wrong # args: should be ".t tag names ?options? ?index?"}
test textTag-8.2 {TkTextTagCmd - "names" option} -setup {
    .t tag delete {*}[.t tag names]
    .t tag remove sel 1.0 end
    foreach i {a b c d} {
        .t tag configure $i -background black
    }
} -body {
1157
1158
1159
1160
1161
1162
1163

1164





1165







1166
1167
1168
1169
1170
1171
1172
    .t tag remove sel 1.0 end
    .t tag add sel 2.4 3.3
    .t.e select to 4
    .t tag remove sel 2.7 3.1
    selection get
} -cleanup {
    destroy .t.e

} -result {Text}














test textTag-14.1 {SortTags} -setup {
    .t tag delete a b c d
} -body {
    foreach i {a b c d} {
        .t tag add $i 2.0 2.2
    }







>

>
>
>
>
>
|
>
>
>
>
>
>
>







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
    .t tag remove sel 1.0 end
    .t tag add sel 2.4 3.3
    .t.e select to 4
    .t tag remove sel 2.7 3.1
    selection get
} -cleanup {
    destroy .t.e
    .t tag remove sel 1.0 end
} -result {Text}
test textTag-13.4 {TkTextTagCmd - "remove" option} -setup {
    text .tt
} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .tt insert end "Line $n\n"
    }
    .tt tag configure Elided -elide 1
    .tt tag add Elided 6.0 end
    .tt tag remove Elided 6.0 8.0 ;  # used to crash
    .tt tag ranges Elided
} -cleanup {
    destroy .tt
} -result {8.0 12.0}

test textTag-14.1 {SortTags} -setup {
    .t tag delete a b c d
} -body {
    foreach i {a b c d} {
        .t tag add $i 2.0 2.2
    }
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
    for {set i 29} {$i >= 0} {incr i -1} {
        .t tag add x$i 2.0 2.2
    }
    .t tag names 2.1
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29}


set curFont [.t cget -font]
set curWrap [.t cget -wrap]
set c [.t bbox 2.1]
set x1 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y1 [expr {[lindex $c 1] + [lindex $c 3]/2}]
set c [.t bbox 3.2]
set x2 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y2 [expr {[lindex $c 1] + [lindex $c 3]/2}]
set c [.t bbox 4.3]
set x3 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y3 [expr {[lindex $c 1] + [lindex $c 3]/2}]
.t configure -font $textWidgetFont -wrap none
update
set c [.t bbox 2.1]
set x4 [expr [lindex $c 0] + [lindex $c 2]/2]
set y4 [expr [lindex $c 1] + [lindex $c 3]/2]
set c [.t bbox 3.2]
set x5 [expr [lindex $c 0] + [lindex $c 2]/2]
set y5 [expr [lindex $c 1] + [lindex $c 3]/2]
.t configure -font $curFont -wrap $curWrap

test textTag-15.1 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    bind .t <ButtonRelease> {lappend x up}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind y <ButtonRelease> {lappend x y-up}
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3







<
<
<
<









<
<
<
<
<
<
<
<
<




|
>







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
    for {set i 29} {$i >= 0} {incr i -1} {
        .t tag add x$i 2.0 2.2
    }
    .t tag names 2.1
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29}




set c [.t bbox 2.1]
set x1 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y1 [expr {[lindex $c 1] + [lindex $c 3]/2}]
set c [.t bbox 3.2]
set x2 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y2 [expr {[lindex $c 1] + [lindex $c 3]/2}]
set c [.t bbox 4.3]
set x3 [expr {[lindex $c 0] + [lindex $c 2]/2}]
set y3 [expr {[lindex $c 1] + [lindex $c 3]/2}]










test textTag-15.1 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    bind .t <ButtonRelease> {lappend x up}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind y <ButtonRelease> {lappend x y-up}
    set x {}
    .t tag add x 2.0 2.4
    .t tag add y 4.3
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
    .t tag delete x y
    bind .t <ButtonRelease> {}
} -result {x-up up up y-up up}

test textTag-15.2 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button> {lappend x x-down}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Button> {lappend x y-down}







|
>







1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
    .t tag delete x y
    bind .t <ButtonRelease> {}
} -result {x-up up up y-up up}

test textTag-15.2 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button> {lappend x x-down}
    .t tag bind x <ButtonRelease> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Button> {lappend x y-down}
1288
1289
1290
1291
1292
1293
1294
1295

1296
1297
1298
1299
1300
1301
1302
} -cleanup {
    .t tag delete x y
} -result {x-enter | x-down | | x-up x-leave y-enter}

test textTag-15.3 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button-1> {lappend x x-down}
    .t tag bind x <ButtonRelease-1> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Button-1> {lappend x y-down}







|
>







1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
} -cleanup {
    .t tag delete x y
} -result {x-enter | x-down | | x-up x-leave y-enter}

test textTag-15.3 {TkTextBindProc} -setup {
    .t tag delete x y
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button-1> {lappend x x-down}
    .t tag bind x <ButtonRelease-1> {lappend x x-up}
    .t tag bind x <Leave> {lappend x x-leave}
    .t tag bind y <Enter> {lappend x y-enter}
    .t tag bind y <Button-1> {lappend x y-down}
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
    lappend x |
    event gen .t <ButtonRelease-2> -x $x3 -y $y3 -state 0x200
    return $x
} -cleanup {
    .t tag delete x y
} -result {x-enter | x-down | | | x-up | x-leave y-enter}




















test textTag-16.1 {TkTextPickCurrent procedure} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    event gen .t <ButtonRelease-1> -state 0x100 -x $x1 -y $y1
    set x [.t index current]
    event gen .t <Motion> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Button-1> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Motion> -x $x3 -y $y3 -state 0x100
    lappend x [.t index current]
    event gen .t <Button-3> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-3> -state 0x300 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-1> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
} -result {2.1 3.2 3.2 3.2 3.2 3.2 4.3}

test textTag-16.2 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont


    event gen .t <ButtonRelease-1> -state 0x100 -x $x4 -y $y4
    event gen .t <Motion> -x $x5 -y $y5
    set x [.t index current]
    .t tag add big 3.0
    update
    lappend x [.t index current]
} -cleanup {
    .t tag delete big
    .t configure -font $curFont -wrap $curWrap
} -result {3.2 3.1}

test textTag-16.3 {TkTextPickCurrent procedure} -setup {
    foreach i {a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    foreach i {a b c d} {
        .t tag bind $i <Enter> "lappend x enter-$i"
        .t tag bind $i <Leave> "lappend x leave-$i"
    }
    .t tag lower b
    .t tag lower a







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
>


















|



|
|


>
>
|
|






<







|
>







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
    lappend x |
    event gen .t <ButtonRelease-2> -x $x3 -y $y3 -state 0x200
    return $x
} -cleanup {
    .t tag delete x y
} -result {x-enter | x-down | | | x-up | x-leave y-enter}

test textTag-15.4 {TkTextBindProc, key event with mouse outside the widget} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
} -body {
    set res {}
    .t tag add tag1 1.0 end
    .t tag bind tag1 <Key> {lappend res %K}
    .t mark set insert 1.2
    update
    event generate .t <Motion> -warp 1 -x -50 -y -50
    controlPointerWarpTiming
    focus -force .t
    event generate .t <Key> -keysym a
    set res
} -cleanup {
    .t tag delete tag1
} -result {a}


test textTag-16.1 {TkTextPickCurrent procedure} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    event gen .t <ButtonRelease-1> -state 0x100 -x $x1 -y $y1
    set x [.t index current]
    event gen .t <Motion> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Button-1> -x $x2 -y $y2
    lappend x [.t index current]
    event gen .t <Motion> -x $x3 -y $y3 -state 0x100
    lappend x [.t index current]
    event gen .t <Button-3> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-3> -state 0x300 -x $x3 -y $y3
    lappend x [.t index current]
    event gen .t <ButtonRelease-1> -state 0x100 -x $x3 -y $y3
    lappend x [.t index current]
} -result {2.1 3.2 3.2 3.2 3.2 3.2 4.3}

test textTag-16.2 {TkTextPickCurrent procedure} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    # update needed here to stabilize the test
    update
    event gen .t <ButtonRelease-1> -state 0x100 -x $x1 -y $y1
    event gen .t <Motion> -x $x2 -y $y2
    set x [.t index current]
    .t tag add big 3.0
    update
    lappend x [.t index current]
} -cleanup {
    .t tag delete big

} -result {3.2 3.1}

test textTag-16.3 {TkTextPickCurrent procedure} -setup {
    foreach i {a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    foreach i {a b c d} {
        .t tag bind $i <Enter> "lappend x enter-$i"
        .t tag bind $i <Leave> "lappend x leave-$i"
    }
    .t tag lower b
    .t tag lower a
1393
1394
1395
1396
1397
1398
1399
1400

1401
1402
1403
1404
1405
1406
1407
} -result {enter-a enter-b | leave-b enter-c | leave-a leave-c}

test textTag-16.4 {TkTextPickCurrent procedure} -setup {
    foreach i {a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    foreach i {a b c d} {
        .t tag bind $i <Enter> "lappend x enter-$i"
        .t tag bind $i <Leave> "lappend x leave-$i"
    }
    .t tag lower b
    .t tag lower a







|
>







1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
} -result {enter-a enter-b | leave-b enter-c | leave-a leave-c}

test textTag-16.4 {TkTextPickCurrent procedure} -setup {
    foreach i {a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    foreach i {a b c d} {
        .t tag bind $i <Enter> "lappend x enter-$i"
        .t tag bind $i <Leave> "lappend x leave-$i"
    }
    .t tag lower b
    .t tag lower a
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430

1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505

1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521




1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532




















1533
1534
1535
1536
1537


    .t tag lower c
    event gen .t <Motion> -x $x2 -y $y2
    return $x
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {enter-a enter-b enter-c | leave-c leave-b}

test textTag-16.5 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none

} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x4 -y $y4
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x5 -y $y5
    .t index current
} -cleanup {
    .t tag delete a big
    .t configure -font $curFont -wrap $curWrap
} -result {3.2}

test textTag-16.6 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x4 -y $y4
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x5 -y $y5
    update
    .t index current
} -cleanup {
    .t tag delete a big
    .t configure -font $curFont -wrap $curWrap
} -result {3.1}

test textTag-16.7 {TkTextPickCurrent procedure} -constraints {
    haveFontSizes failsOnUbuntuNoXft
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50
    .t configure -font $textWidgetFont -wrap none
} -body {
    .t tag configure big -font $bigFont
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2

    event gen .t <Motion> -x $x4 -y $y4
    .t tag bind a <Leave> {.t tag add big 3.0 3.2}
    .t tag add a 2.1
    event gen .t <Motion> -x $x5 -y $y5
    update
    .t index current
} -cleanup {
    .t tag delete a big
    .t configure -font $curFont -wrap $curWrap
} -result {3.1}


test textTag-17.1 {insert procedure inserts tags} -setup {
    .t delete 1.0 end
} -body {
    # Objectification of the text widget had a problem
    # with inserting tags when using 'end'. Check that
    # bug has been fixed.
    .t insert end abcd {x} \n {} efgh {y} \n {}
    .t dump -tag 1.0 end
} -result {tagon x 1.0 tagoff x 1.4 tagon y 2.0 tagoff y 2.4}


test textTag-18.1 {TkTextPickCurrent tag bindings} -setup {
    destroy .t
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5 ; update idletasks ; after 50

} -body {
    text .t -width 30 -height 4 -relief sunken -borderwidth 10 \
      -highlightthickness 10 -pady 2
    pack .t
    update ; # map the window, otherwise -warp can't be done

    .t insert end " Tag here " TAG " no tag here"
    .t tag configure TAG -borderwidth 4 -relief raised
    .t tag bind TAG <Enter>  {lappend res "%x %y tag-Enter"}
    .t tag bind TAG <Leave>  {lappend res "%x %y tag-Leave"}
    bind .t <Enter> {lappend res Enter}
    bind .t <Leave> {lappend res Leave}

    set res {}
    # Bindings must not trigger on the widget border, only over
    # the actual tagged characters themselves.




    event gen .t <Motion> -warp 1 -x 0 -y 0 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    event gen .t <Motion> -warp 1 -x 20 -y 20 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    return $res
} -cleanup {
    destroy .t
} -result {Enter {25 25 tag-Enter} {20 20 tag-Leave} {25 25 tag-Enter}}





















destroy .t

# cleanup
cleanupTests
return









|
<
<




|
<
>


|


|



<



|





|
|


|


|




<



|





|
|





|


|




<

















|
>
















>
>
>
>






|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
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
    .t tag lower c
    event gen .t <Motion> -x $x2 -y $y2
    return $x
} -cleanup {
    .t tag delete {*}[.t tag names]
} -result {enter-a enter-b enter-c | leave-c leave-b}

test textTag-16.5 {TkTextPickCurrent procedure} -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

    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x1 -y $y1
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x2 -y $y2
    .t index current
} -cleanup {
    .t tag delete a big

} -result {3.2}

test textTag-16.6 {TkTextPickCurrent procedure} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x1 -y $y1
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2
    event gen .t <Motion> -x $x2 -y $y2
    update
    .t index current
} -cleanup {
    .t tag delete a big

} -result {3.1}

test textTag-16.7 {TkTextPickCurrent procedure} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -setup {
    foreach i {big a b c d} {
        .t tag remove $i 1.0 end
    }
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    .t tag bind a <Enter> {.t tag add big 3.0 3.2}
    .t tag add a 3.2

    event gen .t <Motion> -x $x1 -y $y1
    .t tag bind a <Leave> {.t tag add big 3.0 3.2}
    .t tag add a 2.1
    event gen .t <Motion> -x $x2 -y $y2
    update
    .t index current
} -cleanup {
    .t tag delete a big

} -result {3.1}


test textTag-17.1 {insert procedure inserts tags} -setup {
    .t delete 1.0 end
} -body {
    # Objectification of the text widget had a problem
    # with inserting tags when using 'end'. Check that
    # bug has been fixed.
    .t insert end abcd {x} \n {} efgh {y} \n {}
    .t dump -tag 1.0 end
} -result {tagon x 1.0 tagoff x 1.4 tagon y 2.0 tagoff y 2.4}


test textTag-18.1 {TkTextPickCurrent tag bindings} -setup {
    destroy .t
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    text .t -width 30 -height 4 -relief sunken -borderwidth 10 \
      -highlightthickness 10 -pady 2
    pack .t
    update ; # map the window, otherwise -warp can't be done

    .t insert end " Tag here " TAG " no tag here"
    .t tag configure TAG -borderwidth 4 -relief raised
    .t tag bind TAG <Enter>  {lappend res "%x %y tag-Enter"}
    .t tag bind TAG <Leave>  {lappend res "%x %y tag-Leave"}
    bind .t <Enter> {lappend res Enter}
    bind .t <Leave> {lappend res Leave}

    set res {}
    # Bindings must not trigger on the widget border, only over
    # the actual tagged characters themselves.
    # Note that we don't need to call controlPointerWarpTiming
    # in the following six calls because we're not checking that
    # the mouse pointer has actually moved but rather that the
    # tag binding mechanism of the text widget correctly triggers.
    event gen .t <Motion> -warp 1 -x 0 -y 0 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    event gen .t <Motion> -warp 1 -x 20 -y 20 ; update
    event gen .t <Motion> -warp 1 -x 10 -y 10 ; update
    event gen .t <Motion> -warp 1 -x 25 -y 25 ; update
    set res
} -cleanup {
    destroy .t
} -result {Enter {25 25 tag-Enter} {20 20 tag-Leave} {25 25 tag-Enter}}


test textTag-19.1 {Repick after tag add/remove} -setup {
    destroy .t
} -body {
    pack [text .t]
    .t insert end "123"
    .t tag bind x <Enter> { lappend res enter }
    .t tag bind x <Leave> { lappend res leave }
    update
    event generate .t <Motion> -x 5 -y 5
    set res {}
    .t tag add x begin end
    update
    .t tag remove x begin end
    update
    set res
} -cleanup {
    destroy .t
} -result {enter leave}

destroy .t

# cleanup
cleanupTests
return

# vi:set ts=8 sw=4:

Changes to tests/textWind.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


















23
24

25

26
27
28
29
30
31

32





33














34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# This file is a Tcl script to test the code in the file tkTextWind.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]

deleteWindows

set fixedFont {"Courier" -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]
set fixedAscent [font metrics $fixedFont -ascent]



















# Widget used in almost all tests
set tWidth 30

set tHeight 6

text .t -width $tWidth -height $tHeight -bd 2 -highlightthickness 2 \
        -font $fixedFont
pack .t -expand 1 -fill both
update
.t debug on


set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]




















wm geometry . {}


# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

# This update is needed on MacOS to make sure that the window is mapped
# when the tests begin.

update

set bw [.t cget -borderwidth]
set px [.t cget -padx]
set py [.t cget -pady]
set hlth [.t cget -highlightthickness]
set padx [expr {$bw+$px+$hlth}]
set pady [expr {$bw+$py+$hlth}]

# ----------------------------------------------------------------------

test textWind-1.1 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -window]
} -result [list \
    1 \
    3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] 3 3] \
    {-window {} {} {} .f}]

test textWind-1.2 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f -align top
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -align]
} -result [list \
    1 \
    3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 3 3] \
    {-align {} {} center top}]

test textWind-1.3 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"





|







<
<


|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>
|
>
|
|




>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>














<
<
<
<
<
<
<














|
|














|
|







1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# This file is a Tcl script to test the code in the file tkTextWind.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands



deleteWindows

set fixedFont {Courier -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]
set fixedAscent [font metrics $fixedFont -ascent]

# On Windows at least, the tests do work with {Courier -10}, {Courier -12} or {Courier -14} as fixedFont.
# Warn the user if the actual font is too different from what was requested.
if {[font metrics [font actual $fixedFont] -fixed] != 1} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
does not seem to be a fixed-width font as expected. If this is really the case, many upcoming\
tests will fail."
}
if {$fixedHeight < 12 || $fixedHeight > 17} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedHeight pixels height while the tests expect between 12 and 17 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}
if {$fixedWidth < 6 || $fixedWidth > 8} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedWidth pixels in width while the tests expect between 6 and 8 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}

# Widget used in almost all tests
# Option  -width 30  (characters) below is a fundamental assumption of many
# upcoming tests when wrapping enters in play
# Also  -height 6  (lines) is an important assumption
# Moreover the widget must have the same padding in x and y (see proc bo)
# However the tests are not sensitive to  -borderwidth  and  -highlightthickness
text .t -font $fixedFont -width 30 -height 6 -borderwidth 2 -highlightthickness 2
pack .t -expand 1 -fill both
update
.t debug on

wm geometry . {}

# full border size of the text widget, i.e. first x or y coordinate inside the text widget
# warning:  -padx  is supposed to be the same as  -pady  (same border size horizontally and
# vertically around the widget)
proc bo {{w .t}} {
    return [expr {[$w cget -borderwidth] + [$w cget -highlightthickness] + [$w cget -padx]}]
}
# x-width of $n chars, fixed width font
proc xw {n} {
    global fixedWidth
    return [expr {$n * $fixedWidth}]
}
# x-coordinate of the first pixel of $n-th char (count starts at zero), left justified
proc xchar {n {w .t}} {
    return [expr {[bo $w] + [xw $n]}]
}
# y-coordinate of the first pixel of $l-th display line (count starts at 1)
proc yline {l {w .t}} {
    global fixedHeight
    return [expr {[bo $w] + ($l - 1) * $fixedHeight}]
}

set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

# This update is needed on MacOS to make sure that the window is mapped
# when the tests begin.

update








# ----------------------------------------------------------------------

test textWind-1.1 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -window]
} -result [list \
    1 \
    3x3+[xchar 2]+[expr {[yline 2]+($fixedHeight-3)/2}] \
    [list [xchar 2] [expr {[yline 2]+($fixedHeight-3)/2}] 3 3] \
    {-window {} {} {} .f}]

test textWind-1.2 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f -align top
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -align]
} -result [list \
    1 \
    3x3+[xchar 2]+[yline 2] \
    [list [xchar 2] [yline 2] 3 3] \
    {-align {} {} center top}]

test textWind-1.3 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    .t insert end "\nAnd this is a second line, which wraps around"
    # the window .f should be wider than the fixed width
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -padx 5
    update
    list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3]
} -result [list \
    10x20+[expr {$padx+2*$fixedWidth+5}]+[expr {$pady+$fixedHeight}] \
    {-padx {} {} 0 5} \
    [list [expr {$padx+2*$fixedWidth+10+2*5}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-1.5 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -pady 4
    update
    list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31]
} -result [list \
    10x20+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+4}] \
    {-pady {} {} 0 4} \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+20+2*4}] $fixedWidth $fixedHeight]]

test textWind-1.6 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 5 -height 5 -bg $color
    .t window create 2.2 -window .f -stretch 1
    update
    list [winfo geom .f] [.t window configure .f -stretch]
} -result [list \
    5x$fixedHeight+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    {-stretch {} {} 0 1}]


.t delete 1.0 end
.t insert end "This is the first line"
test textWind-2.1 {TkTextWindowCmd procedure} -body {
    .t window
} -returnCodes error -result {wrong # args: should be ".t window option ?arg ...?"}
test textWind-2.2 {TkTextWindowCmd procedure, "cget" option} -body {







|

|











|

|











|

<







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
    .t insert end "\nAnd this is a second line, which wraps around"
    # the window .f should be wider than the fixed width
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -padx 5
    update
    list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3]
} -result [list \
    10x20+[expr {[xchar 2]+5}]+[yline 2] \
    {-padx {} {} 0 5} \
    [list [expr {[xchar 2]+10+2*5}] [expr {[yline 2]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]]

test textWind-1.5 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -pady 4
    update
    list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31]
} -result [list \
    10x20+[xchar 2]+[expr {[yline 2]+4}] \
    {-pady {} {} 0 4} \
    [list [xchar 2] [expr {[yline 2]+20+2*4}] $fixedWidth $fixedHeight]]

test textWind-1.6 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 5 -height 5 -bg $color
    .t window create 2.2 -window .f -stretch 1
    update
    list [winfo geom .f] [.t window configure .f -stretch]
} -result [list \
    5x$fixedHeight+[xchar 2]+[yline 2] \
    {-stretch {} {} 0 1}]


.t delete 1.0 end
.t insert end "This is the first line"
test textWind-2.1 {TkTextWindowCmd procedure} -body {
    .t window
} -returnCodes error -result {wrong # args: should be ".t window option ?arg ...?"}
test textWind-2.2 {TkTextWindowCmd procedure, "cget" option} -body {
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.3 -window .f -padx 1 -pady 2
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    .t window configure .f
} -cleanup {
    destroy .f
} -result  {{-align {} {} center baseline} {-create {} {} {} foo} {-padx {} {} 0 1} {-pady {} {} 0 2} {-stretch {} {} 0 0} {-window {} {} {} .f}}
test textWind-2.12 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    list [.t window configure .f -padx 33] [.t window configure .f -padx]
} -cleanup {
    destroy .f
} -result {{} {-padx {} {} 0 33}}
test textWind-2.13 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"







|




|

<















<







221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.3 -window .f -padx 1 -pady 2
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -tags tag1 -create foo
    update
    .t window configure .f
} -cleanup {
    destroy .f
} -result  {{-align {} {} center baseline} {-create {} {} {} foo} {-owner {} {} 1 1} {-padx {} {} 0 1} {-pady {} {} 0 2} {-stretch {} {} 0 0} {-tags {} {} {} tag1} {-window {} {} {} .f}}
test textWind-2.12 {TkTextWindowCmd procedure} -setup {

    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    update
    list [.t window configure .f -padx 33] [.t window configure .f -padx]
} -cleanup {
    destroy .f
} -result {{} {-padx {} {} 0 33}}
test textWind-2.13 {TkTextWindowCmd procedure} -setup {

    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2 -create foo
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
} -returnCodes error -result {wrong # args: should be ".t window create index ?-option value ...?"}
test textWind-2.15 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    .t window create gorp
} -returnCodes error -result {bad text index "gorp"}
test textWind-2.16 {TkTextWindowCmd procedure, don't insert after end} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2
    .t delete 1.0 end
} -body {
    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t index .f
} -result {2.6}
test textWind-2.17 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    list [catch {.t window create 1.0} msg] $msg [.t window configure 1.0]
} -result {0 {} {{-align {} {} center center} {-create {} {} {} {}} {-padx {} {} 0 0} {-pady {} {} 0 0} {-stretch {} {} 0 0} {-window {} {} {} {}}}}
test textWind-2.18 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t delete 1.0 end
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f -gorp stupid
} -returnCodes error -result {unknown option "-gorp"}
test textWind-2.19 {TkTextWindowCmd procedure} -setup {
# I kept this as it "influenced" the test case in previous releases
    destroy .f
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t delete 1.0 end
} -body {
    frame .f -width 10 -height 6 -bg $color
    catch {.t window create 1.0 -window .f -gorp stupid}







<














|

<









<







269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
} -returnCodes error -result {wrong # args: should be ".t window create index ?-option value ...?"}
test textWind-2.15 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    .t window create gorp
} -returnCodes error -result {bad text index "gorp"}
test textWind-2.16 {TkTextWindowCmd procedure, don't insert after end} -setup {

    destroy .f
    frame .f -width 10 -height 6 -bg $color
    .t window create 2.2 -window .f -align baseline -padx 1 -pady 2
    .t delete 1.0 end
} -body {
    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t index .f
} -result {2.6}
test textWind-2.17 {TkTextWindowCmd procedure} -setup {
    .t delete 1.0 end
} -body {
    list [catch {.t window create 1.0} msg] $msg [.t window configure 1.0]
} -result {0 {} {{-align {} {} center center} {-create {} {} {} {}} {-owner {} {} 1 1} {-padx {} {} 0 0} {-pady {} {} 0 0} {-stretch {} {} 0 0} {-tags {} {} {} {}} {-window {} {} {} {}}}}
test textWind-2.18 {TkTextWindowCmd procedure} -setup {

    destroy .f
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t delete 1.0 end
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f -gorp stupid
} -returnCodes error -result {unknown option "-gorp"}
test textWind-2.19 {TkTextWindowCmd procedure} -setup {

    destroy .f
    frame .f -width 20 -height 10 -bg $color
    .t window create end -window .f
    .t delete 1.0 end
} -body {
    frame .f -width 10 -height 6 -bg $color
    catch {.t window create 1.0 -window .f -gorp stupid}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
        .t window create end -window $i
    }
    lsort [.t window names]
} -cleanup {
    destroy .f .f2 .t.f .t.f2
} -result {.f .f2 .t.f .t.f2}


test textWind-3.1 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f
    .t window configure 1.0 -foo bar
} -cleanup {







<







347
348
349
350
351
352
353

354
355
356
357
358
359
360
        .t window create end -window $i
    }
    lsort [.t window names]
} -cleanup {
    destroy .f .f2 .t.f .t.f2
} -result {.f .f2 .t.f .t.f2}


test textWind-3.1 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f
    .t window configure 1.0 -foo bar
} -cleanup {
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
test textWind-3.3 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update

    .t window configure 1.3 -window {}
    update
    catch {.t index .f}
    list [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-3.4 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f







>


<
|


|
|







378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
test textWind-3.3 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    set res [winfo ismapped .f]
    .t window configure 1.3 -window {}
    update

    lappend res [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 1 0 \
    [list [xchar 3] [yline 1] $fixedWidth $fixedHeight]]

test textWind-3.4 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
test textWind-3.5 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update

    .t window configure 1.3 -window {}
    update
    catch {.t index .t.f}
    list [winfo ismapped .t.f] [.t bbox 1.4]
} -cleanup {
    destroy .t.f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-3.6 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3
    update
    .t window configure 1.3 -window .f
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 1.3 1 \
    [list [expr {$padx+3*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-3.7 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f
    frame .f.f -width 15 -height 20 -bg $color
    pack .f.f
    .t window create 1.3 -window .f.f
} -cleanup {
    destroy .f
} -returnCodes error -result {can't embed .f.f in .t}

test textWind-3.8 {EmbWinConfigure procedure} -setup {
    destroy .t2
} -body {
    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    .t window configure 1.3 -window .t2
} -cleanup {
    destroy .t2
} -returnCodes error -result {can't embed .t2 in .t}

test textWind-3.9 {EmbWinConfigure procedure} -setup {
    destroy .t2
} -body {
    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    catch {.t window configure 1.3 -window .t2}
    .t window configure 1.3 -window
} -cleanup {
    destroy .t2
} -result {-window {} {} {} {}}

test textWind-3.10 {EmbWinConfigure procedure} -setup {
    .t delete 1.0 end
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.3
    .t window configure 1.3 -window .t
} -returnCodes error -result {can't embed .t in .t}

test textWind-3.11 {EmbWinConfigure procedure} -setup {
    .t delete 1.0 end
} -body {
    # This test checks for various errors when the text claims
    # a window away from itself.
    .t insert 1.0 "Some sample text"
    button .t.b -text "Hello!"
    .t window create 1.4 -window .t.b
    .t window create 1.6 -window .t.b
    update
    .t index .t.b
} -result {1.6}


.t delete 1.0 end
frame .f -width 10 -height 20 -bg $color
.t window create 1.0 -window .f

test textWind-4.1 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align baseline
    .t window configure 1.0 -align
} -result {-align {} {} center baseline}
test textWind-4.2 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align bottom
    .t window configure 1.0 -align







>


<
|


|
|














|












>










>











>







>













<



>







408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
test textWind-3.5 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    set res [winfo ismapped .t.f]
    .t window configure 1.3 -window {}
    update

    lappend res [winfo ismapped .t.f] [.t bbox 1.4]
} -cleanup {
    destroy .t.f
} -result [list 1 0 \
    [list [xchar 3] [yline 1] $fixedWidth $fixedHeight]]

test textWind-3.6 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3
    update
    .t window configure 1.3 -window .f
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 1.3 1 \
    [list [expr {[xchar 3]+10}] [expr {[yline 1]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]]

test textWind-3.7 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f
    frame .f.f -width 15 -height 20 -bg $color
    pack .f.f
    .t window create 1.3 -window .f.f
} -cleanup {
    destroy .f
} -returnCodes error -result {can't embed .f.f in .t}

test textWind-3.8 {EmbWinConfigure procedure} -setup {
    destroy .t2
} -body {
    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    .t window configure 1.3 -window .t2
} -cleanup {
    destroy .t2
} -returnCodes error -result {can't embed .t2 in .t}

test textWind-3.9 {EmbWinConfigure procedure} -setup {
    destroy .t2
} -body {
    .t insert 1.0 "Some sample text"
    toplevel .t2 -width 20 -height 10 -bg $color
    .t window create 1.3
    catch {.t window configure 1.3 -window .t2}
    .t window configure 1.3 -window
} -cleanup {
    destroy .t2
} -result {-window {} {} {} {}}

test textWind-3.10 {EmbWinConfigure procedure} -setup {
    .t delete 1.0 end
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.3
    .t window configure 1.3 -window .t
} -returnCodes error -result {can't embed .t in .t}

test textWind-3.11 {EmbWinConfigure procedure} -setup {
    .t delete 1.0 end
} -body {
    # This test checks for various errors when the text claims
    # a window away from itself.
    .t insert 1.0 "Some sample text"
    button .t.b -text "Hello!"
    .t window create 1.4 -window .t.b
    .t window create 1.6 -window .t.b
    update
    .t index .t.b
} -result {1.6}


.t delete 1.0 end
frame .f -width 10 -height 20 -bg $color
.t window create 1.0 -window .f

test textWind-4.1 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align baseline
    .t window configure 1.0 -align
} -result {-align {} {} center baseline}
test textWind-4.2 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align bottom
    .t window configure 1.0 -align
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-5.3 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color







|
|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [xchar 2] [expr {[yline 1]+$fixedHeight/2}] 0 0] \
    [list [xchar 2] [yline 1] $fixedWidth $fixedHeight]]

test textWind-5.3 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 0 0] \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-5.5 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.2 -create {frame .f -width 10 -height 20 -bg $color}
    update
    .t window configure 1.2 -create {frame .f -width 20 -height 10 -bg $color}
    destroy .f
    update
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]
} -result [list 0 1.2 \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+(($fixedHeight-10)/2)}] 20 10] \
    [list [expr {$padx+2*$fixedWidth+20}] $pady $fixedWidth $fixedHeight]]


test textWind-6.1 {EmbWinRequestProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
    set result {}
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    lappend result [.t bbox 1.2] [.t bbox 1.3]
    .f configure -width 25 -height 30
    lappend result [.t bbox 1.2] [.t bbox 1.3]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] $pady 10 20] \
    [list [expr {$padx+2*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight] \
    [list [expr {$padx+2*$fixedWidth}] $pady 25 30] \
    [list [expr {$padx+2*$fixedWidth+25}] [expr {$pady+((30-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-7.1 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]
} -cleanup {
    destroy .f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-7.2 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    place .t.f -x 100 -y 50
    update
    list [winfo geom .t.f] [.t bbox 1.2]
} -cleanup {
    destroy .t.f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-8.1 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    list $x [.t bbox 1.2] [.t bbox 1.3] [winfo exists .f]
} -result [list destroyed \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight] \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight] \
    0]

test textWind-8.2 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    .t index .f
} -returnCodes error -result {bad text index ".f"}


test textWind-9.1 {EmbWinCleanupProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text\nA second line."
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.3 -window .f
    .t delete 1.5 2.1
    .t index .f
} -cleanup {
    destroy .f
} -result {1.7}


test textWind-10.1 {EmbWinLayoutProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {







|
|













|
|
<















|
|
|
<
|















|
|















|
|













|
|















<












<







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [xchar 2] [yline 2] 0 0] \
    [list [xchar 2] [yline 1] $fixedWidth $fixedHeight]]

test textWind-5.5 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.2 -create {frame .f -width 10 -height 20 -bg $color}
    update
    .t window configure 1.2 -create {frame .f -width 20 -height 10 -bg $color}
    destroy .f
    update
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]
} -result [list 0 1.2 \
    [list [xchar 2] [expr {[yline 1]+($fixedHeight-10)/2}] 20 10] \
    [list [expr {[xchar 2]+20}] [yline 1] $fixedWidth $fixedHeight]]


test textWind-6.1 {EmbWinRequestProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
    set result {}
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    lappend result [.t bbox 1.2] [.t bbox 1.3]
    .f configure -width 25 -height 30
    lappend result [.t bbox 1.2] [.t bbox 1.3]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 2] [yline 1] 10 20] \
    [list [expr {[xchar 2]+10}] [expr {[yline 1]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight] \
    [list [xchar 2] [yline 1] 25 30] \

    [list [expr {[xchar 2]+25}] [expr {[yline 1]+(30-$fixedHeight)/2}] $fixedWidth $fixedHeight]]

test textWind-7.1 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]
} -cleanup {
    destroy .f
} -result [list \
    10x20+[expr {[bo]+100}]+[expr {[bo]+50}] \
    [list [xchar 2] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-7.2 {EmbWinLostContentProc procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    place .t.f -x 100 -y 50
    update
    list [winfo geom .t.f] [.t bbox 1.2]
} -cleanup {
    destroy .t.f
} -result [list \
    10x20+[expr {[bo]+100}]+[expr {[bo]+50}] \
    [list [xchar 2] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-8.1 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    list $x [.t bbox 1.2] [.t bbox 1.3] [winfo exists .f]
} -result [list destroyed \
    [list [xchar 2] [yline 1] $fixedWidth $fixedHeight] \
    [list [xchar 3] [yline 1] $fixedWidth $fixedHeight] \
    0]

test textWind-8.2 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    .t index .f
} -returnCodes error -result {bad text index ".f"}


test textWind-9.1 {EmbWinCleanupProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text\nA second line."
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.3 -window .f
    .t delete 1.5 2.1
    .t index .f
} -cleanup {
    destroy .f
} -result {1.7}


test textWind-10.1 {EmbWinLayoutProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{couldn't create window}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        concat gorp
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{bad window path name "gorp"}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
	lappend msg $args







|



















|







715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{couldn't create window}} \
    [list [xchar 5] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        concat gorp
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{bad window path name "gorp"}} \
    [list [xchar 5] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
	lappend msg $args
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
        after 10
    }
    lappend msg [.t bbox 1.5] [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result [list \
    {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \
    1]

test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
        if {$msg == ""} {
	    lappend msg $args
	}
    }
} -body {
    .t insert 1.0 "Some sample text"
    set msg {}
    .t window create 1.5 -create {
        frame .t.f
        frame .t.f.f -width 10 -height 20 -bg $color
    }
    update idletasks
    lappend msg [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result {{{can't embed .t.f.f relative to .t}} 1}

test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] < 0} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    update
    .t window create 1.5 -create {
        concat .t
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t relative to .t}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -constraints failsOnUbuntu -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.8 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args







|
|


















|










<
|
<














|

|














|




|
|







765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
        after 10
    }
    lappend msg [.t bbox 1.5] [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result [list \
    {{can't embed .t.f.f relative to .t}} \
    [list [xchar 5] [expr {[yline 1]+$fixedHeight/2}] 0 0] \
    1]

test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
        if {$msg == ""} {
	    lappend msg $args
	}
    }
} -body {
    .t insert 1.0 "Some sample text"
    set msg {}
    .t window create 1.5 -create {
        frame .t.f
        frame .t.f.f -width 10 -height 20 -bg $color
    }
    update
    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

	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 [xchar 5] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
    }
    set msg {}
    update idletasks ; after 100 ; update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t2 relative to .t}} \
    [list [xchar 5] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-10.8 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
	lappend msg $args
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
    update
    set i 0
    while {[llength $msg] == 1 && [incr i] < 200} { update }
    return $msg
} -cleanup {
    destroy .t2
    rename bgerror {}
} -result {{{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}}}

test textWind-10.9 {EmbWinLayoutProc procedure, steal window from self} -setup {
    .t delete 1.0 end
    destroy .t.b
} -body {
    .t insert 1.0 ABCDEFGHIJKLMNOP
    button .t.b -text "Hello!"







|







858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
    update
    set i 0
    while {[llength $msg] == 1 && [incr i] < 200} { update }
    return $msg
} -cleanup {
    destroy .t2
    rename bgerror {}
} -result {{{can't embed .t2 relative to .t}}}

test textWind-10.9 {EmbWinLayoutProc procedure, steal window from self} -setup {
    .t delete 1.0 end
    destroy .t.b
} -body {
    .t insert 1.0 ABCDEFGHIJKLMNOP
    button .t.b -text "Hello!"
858
859
860
861
862
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

test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth-1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth+1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] [expr {($tWidth-12)*$fixedWidth+1}] 20] \
    [list [expr {$padx+($tWidth-12)*$fixedWidth+1}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth+5}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    {}]

test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {($tWidth-12)*$fixedWidth+5}] -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] [expr {$tHeight*$fixedHeight}]] \
    {}]

test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 250 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] [expr {$tWidth*$fixedWidth}] [expr {($tHeight-1)*$fixedHeight}]] \
    {}]

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50

    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update ; after 100 ; update
    winfo geom .f
} -cleanup {
    destroy .f
    place forget .t
} -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]]

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50

    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update ; after 100 ; update
    winfo geom .t.f
} -cleanup {
    destroy .t.f
    place forget .t
    pack .t
} -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady]

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
# Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    bind .f <Configure> {set x ".f configured"}







|





|
|







|






|
|







|






|
|







|






|








|






|















|







|





>


|




|






|





>


|





|






|







881
882
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

test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {([.t cget -width]-12)*$fixedWidth-1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] 20] \
    [list [xchar 0] [expr {[yline 1]+20}] $fixedWidth $fixedHeight]]

test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {([.t cget -width]-12)*$fixedWidth}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] 20] \
    [list [xchar 0] [expr {[yline 1]+20}] $fixedWidth $fixedHeight]]

test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {([.t cget -width]-12)*$fixedWidth+1}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 0] [yline 2] [expr {[xw [expr {[.t cget -width]-12}]]+1}] 20] \
    [list [expr {[xchar 0]+[expr {[xw [expr {[.t cget -width]-12}]]+1}]}] [expr {[yline 2]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]]

test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {([.t cget -width]-12)*$fixedWidth+5}] -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] 20] \
    {}]

test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width [expr {([.t cget -width]-12)*$fixedWidth+5}] -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] [expr {[.t cget -height]*$fixedHeight}]] \
    {}]

test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 250 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [xchar 0] [yline 2] [xw [.t cget -width]] [expr {([.t cget -height]-1)*$fixedHeight}]] \
    {}]

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
    # Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    update
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    winfo geom .f
} -cleanup {
    destroy .f
    place forget .t
} -result [list 30x20+[expr {[xchar 12]+30}]+[expr {[yline 1]+50}]]

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t
    # Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    pack forget .t
    place .t -x 30 -y 50
    update
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update
    winfo geom .t.f
} -cleanup {
    destroy .t.f
    place forget .t
    pack .t
} -result [list 30x20+[xchar 12]+[yline 1]]

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
    # Make sure the Text is mapped before we start
    update
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    bind .f <Configure> {set x ".f configured"}
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
    .t xview moveto 0
    .t xview scroll 5 units
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2]
} -cleanup {
    destroy .f .f2
} -result [list 1 \
    30x20+[expr {$padx+14*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    [list [expr {$padx+14*$fixedWidth}] [expr {$pady+$fixedHeight}] 30 20] \
    0]

test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "







|
|







1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
    .t xview moveto 0
    .t xview scroll 5 units
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2]
} -cleanup {
    destroy .f .f2
} -result [list 1 \
    30x20+[xchar 14]+[yline 2] \
    [list [xchar 14] [yline 2] 30 20] \
    0]

test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
    .t xview scroll 25 units
    update
    list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2]
} -cleanup {
  destroy .f .f2
  .t configure -wrap char
} -result [list 0 1 \
    40x10+[expr {$padx+37*$fixedWidth+30-25*$fixedWidth}]+[expr {$pady+$fixedHeight+((20-10)/2)}] \
    [list [expr {$padx+37*$fixedWidth+30-25*$fixedWidth}] [expr {$pady+$fixedHeight+((20-10)/2)}] 40 10]]

test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Map> {lappend x mapped}
    bind .f <Unmap> {lappend x unmapped}
    set x created
    update
    lappend x modified
    .t delete 1.0
    update
    lappend x replaced
    .t window configure .f -window {}
    .t delete 1.1

    .t window create 1.4 -window .f
    update
    lappend x off-screen
    .t configure -wrap none
    .t insert 1.0 "Enough text to make the line run off-screen"
    update
    return $x
} -cleanup {
    destroy .f
} -result {created mapped modified replaced unmapped mapped off-screen unmapped}


test textWind-13.1 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 5]]

test textWind-13.2 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+(($fixedHeight-7)/2)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+(($fixedHeight-7)/2)}] 5 5]]

test textWind-13.3 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedAscent-6)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedAscent-6)}] 5 5]]

test textWind-13.4 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedHeight-7)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedHeight-7)}] 5 5]]

test textWind-13.5 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.6 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.7 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedAscent-1}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedAscent-1}]]]

test textWind-13.8 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 5 -spacing3 2
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    .t configure -spacing1 0 -spacing3 0
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+5+(($fixedHeight-5)/2)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+5+(($fixedHeight-5)/2)}] 5 5]]


test textWind-14.1 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color







|
|


















>










<













|
|













|
|













|
|













|
|













|
|













|
|













|
|













|
|
















|
|
<







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
    .t xview scroll 25 units
    update
    list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2]
} -cleanup {
  destroy .f .f2
  .t configure -wrap char
} -result [list 0 1 \
    40x10+[expr {[xchar [expr {37-25}]]+30}]+[expr {[yline 2]+(20-10)/2}] \
    [list [expr {[xchar [expr {37-25}]]+30}] [expr {[yline 2]+(20-10)/2}] 40 10]]

test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Map> {lappend x mapped}
    bind .f <Unmap> {lappend x unmapped}
    set x created
    update
    lappend x modified
    .t delete 1.0
    update
    lappend x replaced
    .t window configure .f -window {}
    .t delete 1.1
    update
    .t window create 1.4 -window .f
    update
    lappend x off-screen
    .t configure -wrap none
    .t insert 1.0 "Enough text to make the line run off-screen"
    update
    return $x
} -cleanup {
    destroy .f
} -result {created mapped modified replaced unmapped mapped off-screen unmapped}


test textWind-13.1 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1}] 5 5]]

test textWind-13.2 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1+(($fixedHeight-7)/2)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1+(($fixedHeight-7)/2)}] 5 5]]

test textWind-13.3 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1+($fixedAscent-6)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1+($fixedAscent-6)}] 5 5]]

test textWind-13.4 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1+($fixedHeight-7)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1+($fixedHeight-7)}] 5 5]]

test textWind-13.5 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.6 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.7 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedAscent-1}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1}] 5 [expr {$fixedAscent-1}]]]

test textWind-13.8 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 5 -spacing3 2
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    .t configure -spacing1 0 -spacing3 0
    destroy .f
} -result [list \
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+5+(($fixedHeight-5)/2)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+5+(($fixedHeight-5)/2)}] 5 5]]


test textWind-14.1 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
    .t window create 1.6 -window .f
    .t tag add a 1.1
    .t tag add a 1.3
    list [.t index .f] [.t bbox 1.7]
} -cleanup {
    destroy .f
} -result [list 1.6 \
    [list [expr {$padx+6*$fixedWidth+30}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-16.1 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"







<
|







1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356
1357
1358
    .t window create 1.6 -window .f
    .t tag add a 1.1
    .t tag add a 1.3
    list [.t index .f] [.t bbox 1.7]
} -cleanup {
    destroy .f
} -result [list 1.6 \

    [list [expr {[xchar 6]+30}] [expr {[yline 1]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]]

test textWind-16.1 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
    frame .f2 -width 150 -height 30 -bd 2 -relief raised
    pack .f2 -before .t
    update
    lappend result [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f .f2
} -result [list \
    30x20+[expr {$padx+6*$fixedWidth}]+$pady \
    [list [expr {$padx+6*$fixedWidth}] $pady 30 20] \
    30x20+[expr {$padx+6*$fixedWidth}]+[expr {$pady+30}] \
    [list [expr {$padx+6*$fixedWidth}] $pady 30 20]]

test textWind-16.3 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    .t window create 1.6







|
|
|
|







1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
    frame .f2 -width 150 -height 30 -bd 2 -relief raised
    pack .f2 -before .t
    update
    lappend result [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f .f2
} -result [list \
    30x20+[expr {[xchar 6]}]+[yline 1] \
    [list [expr {[xchar 6]}] [yline 1] 30 20] \
    30x20+[expr {[xchar 6]}]+[expr {[yline 1]+30}] \
    [list [expr {[xchar 6]}] [yline 1] 30 20]]

test textWind-16.3 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    .t window create 1.6
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546
1547
1548

1549







1550
1551









1552


1553
1554

1555
1556

1557
1558
1559





1560


1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580

































1581
1582
1583
1584
1585
1586





    .t window create 1.6 -window .t.f
    update
    pack forget .t
    update
    list [winfo ismapped .t.f] [.t bbox .t.f]
} -cleanup {
    pack .t
} -result [list 1 [list [expr {$padx+6*$fixedWidth}] $pady 30 20]]


test textWind-17.1 {peer widgets and embedded windows} -setup {
    destroy .t .tt .f
} -body {
    pack [text .t]
    .t insert end "Line 1"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.3 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    destroy .t .tt
    winfo exists .f
} -result 0

test textWind-17.2 {peer widgets and embedded windows} -setup {
    destroy .t .f .tt
} -body {
    pack [text .t]
    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.4 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    destroy .t
    .tt.t insert 1.0 "foo"
    update
    destroy .tt
} -result {}

test textWind-17.3 {peer widget and -create} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    update ; update
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    destroy .t .tt
} -result {}

test textWind-17.4 {peer widget deleted one window shouldn't delete others} -setup {
    destroy .t .tt
    set res {}
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    destroy .tt
    lappend res [.t get 1.2]
    update
    lappend res [.t get 1.2]
} -cleanup {
    destroy .t
} -result {{} {}}

test textWind-17.5 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t
} -result {.t.f .tt.t.f}

test textWind-17.6 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update ; update
    list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.7 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {.t.f {}}

test textWind-17.8 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} .t.f} {-window {} {} {} {}}}

test textWind-17.9 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update ; update
    .tt.t window configure 1.2 -window [frame .tt.t.f -width 10 -height 20 -bg red]
    list [.t window configure 1.2 -window] [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.10 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {

    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]

    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]







    .tt.t window create 1.2 -window [frame .tt.t.f -width 25 -height 20 -bg blue]
    update ; update









    .t window configure 1.2 -create \


      {destroy %W.f ; frame %W.f -width 50 -height 7 -bg red}
    .tt.t window configure 1.2 -window {}

    .t window configure 1.2 -window {}
    set res [list [.t window configure 1.2 -window] \

        [.tt.t window configure 1.2 -window]]
    update
    lappend res [.t window configure 1.2 -window] \





        [.tt.t window configure 1.2 -window]


} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} {}} {-window {} {} {} {}} {-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-18.1 {embedded window deletion triggered by a script bound to <Map>} -setup {
    catch {destroy .t .f .f2}
} -body {
    pack [text .t]
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    .t window create end -window [frame .f -background red -width 80 -height 80]
    .t window create end -window [frame .f2 -background blue -width 80 -height 80]
    bind .f <Map> {.t delete .f}
    update
    # this shall not crash (bug 1501749)
    after 100 {.t yview end}
    tkwait visibility .f2

    update
} -cleanup {
    destroy .t .f .f2
} -result {}


































option clear

# cleanup
cleanupTests
return












|
<










|













|














|















|

















|














|















|














|















|









>





>

>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
|
|
>
|
|
>
|

|
>
>
>
>
>
|
>
>


|













>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
>
>
>
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
    .t window create 1.6 -window .t.f
    update
    pack forget .t
    update
    list [winfo ismapped .t.f] [.t bbox .t.f]
} -cleanup {
    pack .t
} -result [list 1 [list [expr {[xchar 6]}] [yline 1] 30 20]]


test textWind-17.1 {peer widgets and embedded windows} -setup {
    destroy .t .tt .f
} -body {
    pack [text .t]
    .t insert end "Line 1"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.3 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update
    destroy .t .tt
    winfo exists .f
} -result 0

test textWind-17.2 {peer widgets and embedded windows} -setup {
    destroy .t .f .tt
} -body {
    pack [text .t]
    .t insert end "Line 1\nLine 2"
    frame .f -width 20 -height 10 -bg blue
    .t window create 1.4 -window .f
    toplevel .tt
    pack [.t peer create .tt.t]
    update
    destroy .t
    .tt.t insert 1.0 "foo"
    update
    destroy .tt
} -result {}

test textWind-17.3 {peer widget and -create} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    update
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    destroy .t .tt
} -result {}

test textWind-17.4 {peer widget deleted one window shouldn't delete others} -setup {
    destroy .t .tt
    set res {}
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    destroy .tt
    lappend res [.t get 1.2]
    update
    lappend res [.t get 1.2]
} -cleanup {
    destroy .t
} -result {{} {}}

test textWind-17.5 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t
} -result {.t.f .tt.t.f}

test textWind-17.6 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -create {frame %W.f -width 10 -height 20 -bg blue}
    update
    list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.7 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update
    list [.t window cget 1.2 -window] [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {.t.f {}}

test textWind-17.8 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update
    list [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} .t.f} {-window {} {} {} {}}}

test textWind-17.9 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update
    .tt.t window configure 1.2 -window [frame .tt.t.f -width 10 -height 20 -bg red]
    list [.t window configure 1.2 -window] [.tt.t window configure 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}

test textWind-17.10 {peer widget window configuration} -setup {
    destroy .t .tt
} -body {
    set res {}
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    update
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update
    # There is a blue window in the main widget .t but not in the peer .tt.t
    lappend res [.t window cget 1.2 -window]
    lappend res [.tt.t window cget 1.2 -window]
    # Insert a green window in the peer. Warning: the blue window previously
    # inserted in .t at index 1.2 will now be found in .t at index 1.3
    # The underlying linked segments are common in a text widget and its peers.
    .tt.t window create 1.2 -window [frame .tt.t.f -width 25 -height 20 -bg green]
    update
    lappend res [.t window cget 1.2 -window]
    lappend res [.t window cget 1.3 -window]
    # In the peer, the green window still is at 1.2, and there is no window at 1.3
    lappend res [.tt.t window cget 1.2 -window]
    lappend res [.tt.t window cget 1.3 -window]
    # Insert a red window in .t at index 1.2. This replaces the blue window originally at 1.2
    # in .t, because the green window inserted in the peer is not visible from .t, therefore
    # the embedded window found at index 1.2 in .t is the one originally at 1.2 in .t, i.e.
    # the blue one
    .t window configure 1.2 -create {destroy %W.f ; update ; frame %W.f -width 50 -height 7 -bg red}
    update
    # The main widget .t still has a window named .t.f at 1.2. This is NOT the blue
    # frame but the red frame from the -create script, which bears the same name.
    lappend res [.t window cget 1.2 -window]
    # The peer still has its green .tt.t.f at 1.2
    lappend res [.tt.t window cget 1.2 -window]
    # When removing the -window option the create script plays, therefore .t still has
    # the red frame .t.f at 1.2
    .t window configure 1.2 -window {}
    update
    lappend res [.t window cget 1.2 -window]
    # The -create script associated to index 1.2 applies to all peers (that's the reason
    # why the manual states that "If multiple peer widgets are in use, it is usually simpler
    # to use the -create option if embedded windows are desired in each peer."). Therefore
    # when removing the -window option in the peer, the -create script is run, which replaces
    # the green frame by the red one named as per the -create script, i.e. .tt.t.f
    .tt.t window configure 1.2 -window {}
    update
    lappend res [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {.t.f {} {} .t.f .tt.t.f {} .t.f .tt.t.f .t.f .tt.t.f}

test textWind-18.1 {embedded window deletion triggered by a script bound to <Map>} -setup {
    catch {destroy .t .f .f2}
} -body {
    pack [text .t]
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    .t window create end -window [frame .f -background red -width 80 -height 80]
    .t window create end -window [frame .f2 -background blue -width 80 -height 80]
    bind .f <Map> {.t delete .f}
    update
    # this shall not crash (bug 1501749)
    after 100 {.t yview end}
    tkwait visibility .f2
    after 200
    update
} -cleanup {
    destroy .t .f .f2
} -result {}

test textWind-18.2 {text widget deletion triggered by a script bound to embedded window mapping} -setup {
    catch {destroy .t .f}
} -body {
    pack [text .t]
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    .t window create end -window [frame .f -background red -width 80 -height 80]
    bind .f <Map> {destroy .t}
    update
    # this shall not crash (bug 1501749)
    after 100 {.t yview end}
    tkwait window .t
} -cleanup {
    destroy .t .f
} -result {}

test textWind-18.3 {embedded window destruction in cascade} -setup {
    catch {destroy .t .f}
    set x 0
} -body {
    pack [text .t]
    button .t.b1
    .t window create 1.0 -window .t.b1
    bind .t.b1 <Destroy> {destroy .t.b2 ; set x 1}
    button .t.b2
    .t window create 2.0 -window .t.b2
    update
    # this shall not crash (bug 54fe7a5e71)
    after 100 {.t delete 1.0 end}
    tkwait variable x
} -cleanup {
    destroy .t .f
} -result {}

option clear

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:
# vi:set ts=8 sw=4:

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
# This file is a Tcl script to test the tk command.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2002 ActiveState Corporation.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint testprintf [llength [info command testprintf]]

test tk-1.1 {tk command: general} -body {
    tk
} -returnCodes error -result {wrong # args: should be "tk subcommand ?arg ...?"}
test tk-1.2 {tk command: general} -body {
    tk xyz
} -returnCodes error -result {unknown or ambiguous subcommand "xyz": must be appname, busy, caret, fontchooser, inactive, scaling, useinputmethods, or windowingsystem}

# Value stored to restore default settings after 2.* tests
set appname [tk appname]
test tk-2.1 {tk command: appname} -body {
    tk appname xyz abc
} -returnCodes error -result {wrong # args: should be "tk appname ?newName?"}
test tk-2.2 {tk command: appname} -body {




|














|







1
2
3
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 © 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, print, 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
    tk inactive reset foo
} -returnCodes 1 -result {wrong # args: should be "tk inactive ?-displayof window? ?reset?"}
test tk-6.5 {tk inactive} -body {
    tk inactive reset
    update
    after 100
    set i [tk inactive]
    expr {$i < 0 || ( $i > 90 && $i < 200 )}
} -result 1

test tk-7.1 {tk inactive in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive}







|







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 < 0 || ( $i > 90 && $i < 300 )}
} -result 1

test tk-7.1 {tk inactive in a safe interpreter} -body {
# tk inactive in safe interpreters
    safe::interpCreate foo
    safe::loadTk foo
    foo eval {tk inactive}

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
# all.tcl --
#
# This file contains a top-level script to run all of the ttk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright © 2007 by the Tk developers.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [file dirname [tcltest::testsDirectory]] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]






|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# all.tcl --
#
# This file contains a top-level script to run all of the ttk
# tests.  Execute it by invoking "source all.tcl" when running tktest
# in this directory.
#
# Copyright © 2007 the Tk developers.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tk ;# This is the Tk test suite; fail early if no Tk!
package require tcltest 2.2
tcltest::configure {*}$argv
tcltest::configure -testdir [file normalize [file dirname [info script]]]
tcltest::configure -loadfile \
    [file join [file dirname [tcltest::testsDirectory]] constraints.tcl]
tcltest::configure -singleproc 1
set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)]

Changes to tests/ttk/checkbutton.test.

1
2
3
4
5
6
7
8
9
10
11
12
#
# ttk::checkbutton widget tests.
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test checkbutton-1.1 "Checkbutton check" -body {
    pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb]
}




|







1
2
3
4
5
6
7
8
9
10
11
12
#
# ttk::checkbutton widget tests.
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test checkbutton-1.1 "Checkbutton check" -body {
    pack [ttk::checkbutton .cb -text "TCheckbutton" -variable cb]
}
67
68
69
70
71
72
73














74
    # shall simply not crash
    ttk::checkbutton .cbev -variable {}
    .cbev invoke
} -cleanup {
    destroy .cbev
} -result {}















tcltest::cleanupTests







>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56










57
58
59
60
61
62

63





64
65
66
67
68
69
70

71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88














89
#
# ttk::combobox widget tests
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test combobox-1.0 "Combobox tests -- setup" -body {
    ttk::combobox .cb
} -result .cb

test combobox-1.1 "Bad -values list" -body {
    .cb configure -values "bad \{list"
} -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]
    .cb current
} -result -1

test combobox-2.1 "current -- set index" -body {
    .cb current 5
    .cb get
} -result a

test combobox-2.2 "current -- change -values" -body {
    .cb configure -values [list c b a d e]
    .cb current
} -result 2

test combobox-2.3 "current -- change value" -body {
    .cb set "b"
    .cb current
} -result 1

test combobox-2.4 "current -- value not in list" -body {
    .cb set "z"
    .cb current
} -result -1

test combobox-2.5 "current -- set to end index" -body {
    .cb configure -values [list a b c d e thelastone]
    .cb current end
    .cb get
} -result thelastone

test combobox-2.6 "current -- set to unknown index" -body {
    .cb configure -values [list a b c d e]
    .cb current notanindex
} -returnCodes error -result {Incorrect index notanindex}











test combobox-2.end "Cleanup" -body { destroy .cb }

test combobox-3 "Read postoffset value dynamically from current style" -body {
    ttk::combobox .cb -values [list a b c] -style "DerivedStyle.TCombobox"
    pack .cb -expand true -fill both

    ttk::style configure DerivedStyle.TCombobox -postoffset [list 25 0 0 0]





    ttk::combobox::Post .cb
    expr {[winfo rootx .cb.popdown] - [winfo rootx .cb]}
} -result 25 -cleanup {
    destroy .cb
}

test combobox-1890211 "ComboboxSelected event after listbox unposted" -body {

    # whitebox test...
    pack [ttk::combobox .cb -values [list a b c]]

    set result [list]
    bind .cb <<ComboboxSelected>> {
    	lappend result Event [winfo ismapped .cb.popdown] [.cb get]
    }
    lappend result Start 0 [.cb get]
    ttk::combobox::Post .cb
    lappend result Post [winfo ismapped .cb.popdown] [.cb get]
    .cb.popdown.f.l selection clear 0 end; .cb.popdown.f.l selection set 1
    ttk::combobox::LBSelected .cb.popdown.f.l
    lappend result Select [winfo ismapped .cb.popdown] [.cb get]
    update
    set result
} -result [list Start 0 {} Post 1 {} Select 0 b Event 0 b] -cleanup {
    destroy .cb
}















tcltest::cleanupTests




|


















|
|


















|
|










|
>
>
>
>
>
>
>
>
>
>






>

>
>
>
>
>






|
>


>


|













>
>
>
>
>
>
>
>
>
>
>
>
>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#
# ttk::combobox widget tests
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test combobox-1.0 "Combobox tests -- setup" -body {
    ttk::combobox .cb
} -result .cb

test combobox-1.1 "Bad -values list" -body {
    .cb configure -values "bad \{list"
} -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]
    expr {[.cb current]<0}
} -result 1

test combobox-2.1 "current -- set index" -body {
    .cb current 5
    .cb get
} -result a

test combobox-2.2 "current -- change -values" -body {
    .cb configure -values [list c b a d e]
    .cb current
} -result 2

test combobox-2.3 "current -- change value" -body {
    .cb set "b"
    .cb current
} -result 1

test combobox-2.4 "current -- value not in list" -body {
    .cb set "z"
    expr {[.cb current]<0}
} -result 1

test combobox-2.5 "current -- set to end index" -body {
    .cb configure -values [list a b c d e thelastone]
    .cb current end
    .cb get
} -result thelastone

test combobox-2.6 "current -- set to unknown index" -body {
    .cb configure -values [list a b c d e]
    .cb current notanindex
} -returnCodes error -result {bad index "notanindex"}

test combobox-2.7 {current -- set to 0 index when empty [bug 924835c36d]} -body {
    .cb configure -values {}
    .cb current 0
} -returnCodes error -result {index "0" out of range}

test combobox-2.8 "current -- set to end index in an empty combobox" -body {
    .cb configure -values {}
    .cb current end
} -returnCodes error -result {index "end" out of range}

test combobox-2.end "Cleanup" -body { destroy .cb }

test combobox-3 "Read postoffset value dynamically from current style" -body {
    ttk::combobox .cb -values [list a b c] -style "DerivedStyle.TCombobox"
    pack .cb -expand true -fill both
    update idletasks
    ttk::style configure DerivedStyle.TCombobox -postoffset [list 25 0 0 0]
    if {[tk windowingsystem] == "aqua"} {
	after 500 {
	    pressbutton [expr {[winfo rootx .cb] + 25}] [expr {[winfo rooty .cb] + 25}]
	}
    }
    ttk::combobox::Post .cb
    expr {[winfo rootx .cb.popdown] - [winfo rootx .cb]}
} -result 25 -cleanup {
    destroy .cb
}

test combobox-1890211 "ComboboxSelected event after listbox unposted" \
    -constraints {notAqua} -body {
    # whitebox test...
    pack [ttk::combobox .cb -values [list a b c]]
    update idletasks
    set result [list]
    bind .cb <<ComboboxSelected>> {
	lappend result Event [winfo ismapped .cb.popdown] [.cb get]
    }
    lappend result Start 0 [.cb get]
    ttk::combobox::Post .cb
    lappend result Post [winfo ismapped .cb.popdown] [.cb get]
    .cb.popdown.f.l selection clear 0 end; .cb.popdown.f.l selection set 1
    ttk::combobox::LBSelected .cb.popdown.f.l
    lappend result Select [winfo ismapped .cb.popdown] [.cb get]
    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
15
16
17
#
# Tile package: entry widget tests
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]


variable scrollInfo
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}





|




|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#
# Tile package: entry widget tests
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

variable scrollInfo
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

61
62
63
64
65
66
67






68
69
70
71
72
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 entry-1.7 "Deletion - insert cursor in the middle " -body {
    .e insert end abcde
    .e icursor 3
    .e delete 0 end
    .e index insert
} -result 0







test entry-1.done "Cleanup" -body { destroy .e }

# Scrollbar tests.

test entry-2.1 "Create entry before scrollbar" -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
}  -cleanup {destroy .te .tsb}

test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -constraints failsOnUbuntu -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    .te insert end [string repeat "abc" 50]
    catch {update} ; # error triggers because the -xscrollcommand callback
                     # errors out: invalid command name ".tsb"
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
    update ; # no error
    lappend res [expr [lindex [.tsb get] 1] < 1] ; # scrollbar did update
} -result 1 -cleanup {destroy .te .tsb}

test entry-2.2 "Initial scroll position" -body {
    ttk::entry .e -font fixed -width 5 -xscrollcommand scroll
    .e insert end "0123456789"
    pack .e;
    set timeout [after 500 {set $scrollInfo "timeout"}]







>
>
>
>
>
>









|


|






|

|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

test entry-1.7 "Deletion - insert cursor in the middle " -body {
    .e insert end abcde
    .e icursor 3
    .e delete 0 end
    .e index insert
} -result 0

test entry-1.8 "Index is between 0 and end" -body {
    .e delete 0 end
    .e insert end abcde
    set res [list [.e index -1] [.e index -4] [.e index 999]]
} -result {0 0 5}

test entry-1.done "Cleanup" -body { destroy .e }

# Scrollbar tests.

test entry-2.1 "Create entry before scrollbar" -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
	-expand false -fill x
}  -cleanup {destroy .te .tsb}

test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -constraints {failsOnUbuntu failsOnXQuarz} -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
    .te insert end [string repeat "abc" 50]
    catch {update} ; # error triggers because the -xscrollcommand callback
                     # errors out: invalid command name ".tsb"
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
	-expand false -fill x
    update ; # no error
    set res [expr [lindex [.tsb get] 1] < 1] ; # scrollbar did update
} -result 1 -cleanup {destroy .te .tsb}

test entry-2.2 "Initial scroll position" -body {
    ttk::entry .e -font fixed -width 5 -xscrollcommand scroll
    .e insert end "0123456789"
    pack .e;
    set timeout [after 500 {set $scrollInfo "timeout"}]
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

# Bounding box / scrolling tests.
test entry-3.0 "Series 3 setup" -body {
    ttk::style theme use default
    variable fixed TkFixedFont
    variable cw [font measure $fixed a]
    variable ch [font metrics $fixed -linespace]
    variable bd 2	;# border + padding
    variable ux [font measure $fixed 乎]

    pack [ttk::entry .e -font $fixed -width 20]
    update
}

test entry-3.1 "bbox widget command" -body {







|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

# 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 3	;# border + padding + extra space for focus ring
    variable ux [font measure $fixed 乎]

    pack [ttk::entry .e -font $fixed -width 20]
    update
}

test entry-3.1 "bbox widget command" -body {
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
test entry-6.1 {Update linked variable in write trace} -body {
    proc override args {
	global x
	set x "Overridden!"
    }
    catch {destroy .e}
    set x ""
    trace variable x w override
    ttk::entry .e -textvariable x
    .e insert 0 "Some text"
    set result [list $x [.e get]]
    set result
} -result {Overridden! Overridden!} -cleanup {
    unset x
    rename override {}







|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
test entry-6.1 {Update linked variable in write trace} -body {
    proc override args {
	global x
	set x "Overridden!"
    }
    catch {destroy .e}
    set x ""
    trace add variable x write override
    ttk::entry .e -textvariable x
    .e insert 0 "Some text"
    set result [list $x [.e get]]
    set result
} -result {Overridden! Overridden!} -cleanup {
    unset x
    rename override {}
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
    .e cget -textvariable
} -result ::test::foo -cleanup { destroy .e }
# For 8.2a, -result {} would also be sensible.

test entry-9.1 "Index range invariants" -setup {
    # See bug#1721532 for discussion
    proc entry-9.1-trace {n1 n2 op} {
    	set ::V NO!
    }
    variable V
    trace add variable V write entry-9.1-trace
    ttk::entry .e -textvariable V
} -body {
    set result [list]
    .e insert insert a ; lappend result [.e index insert] [.e index end]







|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    .e cget -textvariable
} -result ::test::foo -cleanup { destroy .e }
# For 8.2a, -result {} would also be sensible.

test entry-9.1 "Index range invariants" -setup {
    # See bug#1721532 for discussion
    proc entry-9.1-trace {n1 n2 op} {
	set ::V NO!
    }
    variable V
    trace add variable V write entry-9.1-trace
    ttk::entry .e -textvariable V
} -body {
    set result [list]
    .e insert insert a ; lappend result [.e index insert] [.e index end]
364
365
366
367
368
369
370



















371














372
    .e state invalid
    set res [.e state]
    event generate .e <FocusOut>
    lappend res [.e state]
} -result {invalid invalid} -cleanup {
    destroy .e
}


































tcltest::cleanupTests







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
    .e state invalid
    set res [.e state]
    event generate .e <FocusOut>
    lappend res [.e state]
} -result {invalid invalid} -cleanup {
    destroy .e
}
test entry-11.2 {Bug [2a32225cd1] - Navigation in a password made of several words} -setup {
    destroy .e
    pack [ttk::entry .e -show *]
    update
    set res {}
} -body {
    .e insert end "A sample password made of several words"
    .e icursor end
    event generate .e <<PrevWord>>  ; # shall move insert to index 0
    .e delete insert end
    lappend res [.e get]
    .e insert end "A sample password made of several words"
    .e icursor 2
    event generate .e <<NextWord>>  ; # shall move insert to index end
    .e delete 0 insert
    lappend res [.e get]
} -cleanup {
    destroy .e
} -result {{} {}}

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
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}
|







1
2
3
4
5
6
7
8
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}

Changes to tests/ttk/labelframe.test.

1
2
3
4
5
6
7
8
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
}
|







1
2
3
4
5
6
7
8
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
}
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] [winfo manager .cb]
} -result [list 1 labelframe]

test labelframe-4.4 "Re-manage nonchild content" -body {
    pack .cb -side right
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-4.5 "Re-add nonchild content" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] \
    	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 labelframe .cb]

test labelframe-4.6 "Destroy nonchild content" -body {
    destroy .cb
    .lf cget -labelwidget
} -result {}







|






|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] [winfo manager .cb]
} -result [list 1 labelframe]

test labelframe-4.4 "Re-manage nonchild content" -body {
    pack .cb -side right
    list [update; winfo viewable .cb] \
	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 pack {}]

test labelframe-4.5 "Re-add nonchild content" -body {
    .lf configure -labelwidget .cb
    list [update; winfo viewable .cb] \
	[winfo manager .cb] \
	[.lf cget -labelwidget]
} -result [list 1 labelframe .cb]

test labelframe-4.6 "Destroy nonchild content" -body {
    destroy .cb
    .lf cget -labelwidget
} -result {}
124
125
126
127
128
129
130














131
    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]















tcltest::cleanupTests







>
>
>
>
>
>
>
>
>
>
>
>
>
>

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    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
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

|







1
2
3
4
5
6
7
8
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

Changes to tests/ttk/notebook.test.

1
2
3
4
5
6
7
8
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test notebook-1.0 "Setup" -body {
    ttk::notebook .nb
} -result .nb
|







1
2
3
4
5
6
7
8
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test notebook-1.0 "Setup" -body {
    ttk::notebook .nb
} -result .nb
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80

test notebook-2.4 "tab - set value" -body {
    .nb tab .nb.foo -text "Changed Foo"
    .nb tab .nb.foo -text
} -result "Changed Foo"

test notebook-2.5 "tab - get all options" -body {

    .nb tab .nb.foo
} -result [list \
    -padding 0 -sticky nsew \
    -state normal -text "Changed Foo" -image "" -compound {} -underline -1]

test notebook-4.1 "Test .nb index end" -body {
    .nb index end
} -result 2

test notebook-4.2 "'end' is not a selectable index" -body {
    .nb select end







>



|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

test notebook-2.4 "tab - set value" -body {
    .nb tab .nb.foo -text "Changed Foo"
    .nb tab .nb.foo -text
} -result "Changed Foo"

test notebook-2.5 "tab - get all options" -body {
    .nb tab .nb.foo -underline 0
    .nb tab .nb.foo
} -result [list \
    -padding 0 -sticky nsew \
    -state normal -text "Changed Foo" -image "" -compound {} -underline 0]

test notebook-4.1 "Test .nb index end" -body {
    .nb index end
} -result 2

test notebook-4.2 "'end' is not a selectable index" -body {
    .nb select end
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

test notebook-5.1 "Virtual events" -body {
    toplevel .t
    set ::events [list]
    bind .t <<NotebookTabChanged>> { lappend events changed %W }

    pack [set nb [ttk::notebook .t.nb]] -expand true -fill both; update
    $nb add [frame $nb.f1]
    $nb add [frame $nb.f2]
    $nb add [frame $nb.f3]

    $nb select $nb.f1
    update; set events
} -result [list changed .t.nb]

test notebook-5.2 "Virtual events, continued" -body {
    set events [list]
    $nb select $nb.f3
    update ; set events







|


|
|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

test notebook-5.1 "Virtual events" -body {
    toplevel .t
    set ::events [list]
    bind .t <<NotebookTabChanged>> { lappend events changed %W }

    pack [set nb [ttk::notebook .t.nb]] -expand true -fill both; update
    $nb add [frame $nb.f1] ;  # triggers <<NotebookTabChanged>> (first tab gets autoselected)
    $nb add [frame $nb.f2]
    $nb add [frame $nb.f3]
    update
    $nb select $nb.f1 ; # does not trigger <<NotebookTabChanged>> (tab to select is already selected)
    update; set events
} -result [list changed .t.nb]

test notebook-5.2 "Virtual events, continued" -body {
    set events [list]
    $nb select $nb.f3
    update ; set events
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f2

    lappend result [$nb index current] [winfo ismapped $nb.f2]
    update idletasks; lappend result [winfo ismapped $nb.f3]
} -result [list 1 1 2 0 1]

# See 1370833
test notebook-6.2 "Forget selected tab" -setup {
    ttk::notebook .n
    pack .n
    label .n.l -text abc







>

|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f2
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    lappend result [winfo ismapped $nb.f3]
} -result [list 1 1 2 0 1]

# See 1370833
test notebook-6.2 "Forget selected tab" -setup {
    ttk::notebook .n
    pack .n
    label .n.l -text abc
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326

327
328
329
330
331
332
333
    $nb select $nb.f1
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f1]
    $nb hide $nb.f1

    lappend result [$nb index current] [winfo ismapped $nb.f1]
} -result [list 0 1 1 0]

test notebook-6.4 "Forget first tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f1
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f1]
    $nb forget $nb.f1

    lappend result [$nb index current] [winfo ismapped $nb.f1]
} -result [list 0 1 0 0]

test notebook-6.5 "Hide last tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f3
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f3]
    $nb hide $nb.f3

    lappend result [$nb index current] [winfo ismapped $nb.f3]
} -result [list 2 1 1 0]

test notebook-6.6 "Forget a middle tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f2

    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 0]

test notebook-6.7 "Hide a middle tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f2

    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 2 0]

test notebook-6.8 "Forget a non-current tab < current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f1

    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 0 1]

test notebook-6.9 "Hide a non-current tab < current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f1

    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.10 "Forget a non-current tab > current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f3

    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.11 "Hide a non-current tab > current" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f3

    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.12 "Hide and re-add a tab" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
    $nb hide $nb.f2

    lappend result [$nb index current] [$nb tab $nb.f2 -state]
    $nb add $nb.f2

    lappend result [$nb index current] [$nb tab $nb.f2 -state]
} -result [list 1 normal 2 hidden 2 normal]

#
# Insert:
#
unset nb







>















>















>















>















>















>















>















>















>















>


>







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
    $nb select $nb.f1
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f1]
    $nb hide $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f1]
} -result [list 0 1 1 0]

test notebook-6.4 "Forget first tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f1
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f1]
    $nb forget $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f1]
} -result [list 0 1 0 0]

test notebook-6.5 "Hide last tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f3
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f3]
    $nb hide $nb.f3
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f3]
} -result [list 2 1 1 0]

test notebook-6.6 "Forget a middle tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f2
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 0]

test notebook-6.7 "Hide a middle tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f2
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 2 0]

test notebook-6.8 "Forget a non-current tab < current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 0 1]

test notebook-6.9 "Hide a non-current tab < current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.10 "Forget a non-current tab > current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f3
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.11 "Hide a non-current tab > current" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f3
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.12 "Hide and re-add a tab" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
    $nb hide $nb.f2
    update idletasks
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
    $nb add $nb.f2
    update idletasks
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
} -result [list 1 normal 2 hidden 2 normal]

#
# Insert:
#
unset nb
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
    .nb insert 1 3
    .nb index current
} -result 4

test notebook-7.8a "move tabs - current tab undisturbed - exhaustive" -body {
    .nb select .nb.f0
    foreach i {0 1 2 3 4} {
    	.nb insert $i .nb.f$i
    }

    foreach i {0 1 2 3 4} {
	.nb select .nb.f$i
	foreach j {0 1 2 3 4} {
	    foreach k {0 1 2 3 4} {
		.nb insert $j $k







|







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    .nb insert 1 3
    .nb index current
} -result 4

test notebook-7.8a "move tabs - current tab undisturbed - exhaustive" -body {
    .nb select .nb.f0
    foreach i {0 1 2 3 4} {
	.nb insert $i .nb.f$i
    }

    foreach i {0 1 2 3 4} {
	.nb select .nb.f$i
	foreach j {0 1 2 3 4} {
	    foreach k {0 1 2 3 4} {
		.nb insert $j $k
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
} -result [list "" .nb.l1] -cleanup { destroy .nb }

test notebook-1817596-2 "error in insert should have no effect" -body {
    pack [ttk::notebook .nb]
    .nb insert end [ttk::label .nb.l1]
    .nb insert end [ttk::label .nb.l2]
    list \
    	[catch { .nb insert .l2 0 -badoption badvalue } err] \
	[.nb tabs] \
} -result [list 1 [list .nb.l1 .nb.l2]] -cleanup { destroy .nb }

test notebook-1817596-3 "insert/configure" -body {
    pack [ttk::notebook .nb]
    .nb insert end [ttk::label .nb.l0] -text "L0"
    .nb insert end [ttk::label .nb.l1] -text "L1"







|







463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
} -result [list "" .nb.l1] -cleanup { destroy .nb }

test notebook-1817596-2 "error in insert should have no effect" -body {
    pack [ttk::notebook .nb]
    .nb insert end [ttk::label .nb.l1]
    .nb insert end [ttk::label .nb.l2]
    list \
	[catch { .nb insert .l2 0 -badoption badvalue } err] \
	[.nb tabs] \
} -result [list 1 [list .nb.l1 .nb.l2]] -cleanup { destroy .nb }

test notebook-1817596-3 "insert/configure" -body {
    pack [ttk::notebook .nb]
    .nb insert end [ttk::label .nb.l0] -text "L0"
    .nb insert end [ttk::label .nb.l1] -text "L1"
507
508
509
510
511
512
513
514




























515

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]





























tcltest::cleanupTests








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556

test notebook-1343984-2 "don't autoselect on destroy" -body {
    set ::history [list]
    destroy .nb
    update
    set ::history
} -result [list DESTROY .nb.frame1 DESTROY .nb.frame2 DESTROY .nb.frame3]

test notebook-198376af5a {moving tab position to a different edge} -body {
    destroy .nb
    ttk::notebook .nb -width 200 -height 100 -padding 0
    ttk::frame .nb.f1
    ttk::frame .nb.f2
    .nb add .nb.f1 -text "One"
    .nb add .nb.f2 -text "Two"
    pack .nb
    update
    ttk::style configure TNotebook -tabposition s
    update
    expr {[winfo y .nb.f1] < 10}
} -result 1

test notebook-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
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

proc propagate-geometry {} { update idletasks }

# Basic sanity checks:
|







1
2
3
4
5
6
7
8
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

proc propagate-geometry {} { update idletasks }

# Basic sanity checks:
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# checkorder $winlist --
#	Ensure that Y coordinates windows in $winlist are strictly increasing.
#
proc checkorder {winlist} {
    set pos -1
    set positions [list]
    foreach win $winlist {
    	lappend positions [set nextpos [winfo y $win]]
	if {$nextpos <= $pos} {
	    error "window $win out of order ($positions)"
	}
	set pos $nextpos
    }
}








|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# checkorder $winlist --
#	Ensure that Y coordinates windows in $winlist are strictly increasing.
#
proc checkorder {winlist} {
    set pos -1
    set positions [list]
    foreach win $winlist {
	lappend positions [set nextpos [winfo y $win]]
	if {$nextpos <= $pos} {
	    error "window $win out of order ($positions)"
	}
	set pos $nextpos
    }
}

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

### sashpos tests.
#
proc sashpositions {pw} {
    set positions [list]
    set npanes [llength [winfo children $pw]]
    for {set i 0} {$i < $npanes - 1} {incr i} {
    	lappend positions [$pw sashpos $i]
    }
    return $positions
}

test paned-sashpos-setup "Setup for sash position test" -body {
    ttk::style theme use default
    ttk::style configure -sashthickness 5







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

### sashpos tests.
#
proc sashpositions {pw} {
    set positions [list]
    set npanes [llength [winfo children $pw]]
    for {set i 0} {$i < $npanes - 1} {incr i} {
	lappend positions [$pw sashpos $i]
    }
    return $positions
}

test paned-sashpos-setup "Setup for sash position test" -body {
    ttk::style theme use default
    ttk::style configure -sashthickness 5
285
286
287
288
289
290
291


















292
    .pw.f1 configure -height 50 ;# should be denied
    propagate-geometry
    list [winfo reqwidth .pw] [winfo reqheight .pw] [.pw sashpos 0]
} -result [list 100 155 100]

test paned-propagation-cleanup "Clean up." -body { destroy .pw }



















tcltest::cleanupTests







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    .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

Added tests/ttk/pb_image.svg.

























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="30"
   height="14"
   viewBox="0 0 30 14"
   version="1.1"
   id="svg8"
   sodipodi:docname="slider-hn.svg"
   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
   style="shape-rendering:crispEdges">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="24.766586"
     inkscape:cx="15.000049"
     inkscape:cy="7.0000477"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1315"
     inkscape:window-height="617"
     inkscape:window-x="155"
     inkscape:window-y="185"
     inkscape:window-maximized="0"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0"
     units="px"
     showguides="false"
     showborder="false"
     inkscape:pagecheckerboard="true" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(-97.353746,-141.48839)">
    <rect
       style="opacity:1;fill:#0044ff;fill-opacity:1;stroke:#222222;stroke-width:0.7;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect815"
       width="13.3"
       height="29.3"
       x="141.98839"
       y="-126.85384"
       ry="0"
       transform="rotate(90)" />
  </g>
</svg>

Changes to tests/ttk/progressbar.test.

1
2
3
4
5
6
7
8
package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands


test progressbar-1.1 "Setup" -body {
    ttk::progressbar .pb
|







1
2
3
4
5
6
7
8
package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands


test progressbar-1.1 "Setup" -body {
    ttk::progressbar .pb
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    .pb configure -variable PB		;# @@@
    set PB 5
    .pb step
    set PB
} -result 6.0

test progressbar-2.5 "error in write trace" -body {
    trace variable PB w { error "YIPES!" ;# }
    .pb step
    set PB		;# NOTREACHED
} -cleanup { unset PB } -returnCodes error -match glob -result "*YIPES!"

test progressbar-end "Cleanup" -body {
    destroy .pb
}







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    .pb configure -variable PB		;# @@@
    set PB 5
    .pb step
    set PB
} -result 6.0

test progressbar-2.5 "error in write trace" -body {
    trace add variable PB write { error "YIPES!" ;# }
    .pb step
    set PB		;# NOTREACHED
} -cleanup { unset PB } -returnCodes error -match glob -result "*YIPES!"

test progressbar-end "Cleanup" -body {
    destroy .pb
}
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
                    -length -maximum -mode -orient -phase -value -variable} {
        lappend res [.defaultpb cget $option]
    }
    set res
} -cleanup {
    unset res
    destroy .defaultpb
} -result {w black left {} {} 0 100 100 determinate horizontal 0 0.0 {}}

test progressbar-3.2 "TIP #442 options are taken into account" -setup {
    set res {}
    pack [ttk::progressbar .p -value 0 -maximum 50 -orient horizontal -mode determinate -length 500]
    set thefont [font actual {Arial 10}]
} -body {
    .p configure -anchor c -foreground blue -justify right \







|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
                    -length -maximum -mode -orient -phase -value -variable} {
        lappend res [.defaultpb cget $option]
    }
    set res
} -cleanup {
    unset res
    destroy .defaultpb
} -result {w black left {} {} 0 75p 100.0 determinate horizontal 0 0.0 {}}

test progressbar-3.2 "TIP #442 options are taken into account" -setup {
    set res {}
    pack [ttk::progressbar .p -value 0 -maximum 50 -orient horizontal -mode determinate -length 500]
    set thefont [font actual {Arial 10}]
} -body {
    .p configure -anchor c -foreground blue -justify right \
117
118
119
120
121
122
123
124






































125
        lappend res [list $option [.p cget $option]]
    }
    set res
} -cleanup {
    unset res thefont
    destroy .p
} -result {{-anchor e} {-foreground green} {-justify center} {-text {Cannot be seen}} {-wraplength 250}}







































tcltest::cleanupTests








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
        lappend res [list $option [.p cget $option]]
    }
    set res
} -cleanup {
    unset res thefont
    destroy .p
} -result {{-anchor e} {-foreground green} {-justify center} {-text {Cannot be seen}} {-wraplength 250}}

test progressbar-3.3 {horizontal progressbar height with no -text (TIP #442) specified - Bug [8bee4b2009]} -setup {
    set res {}
    set oldTheme [ttk::style theme use]
} -body {
    ttk::style theme use default
    set imga [image create photo -file [file join [file dirname [info script]] pb_image.svg] -format {svg -scale 0.8}]
    ::ttk::style element create Horizontal.Progressbar.pbar image $imga
    # -text "": progressbar height does not depend on font height
    pack [ttk::progressbar .p -orient horizontal -font {TkDefaultFont 24}]
    .p step 25
    update
    set res [expr {[winfo reqheight .p] == [image height $imga] + 2}]
    # -text "something": progressbar height adjusts to contain the font height
    .p configure -text Hello -font {TkDefaultFont 24}
    update
    lappend res [expr {[winfo reqheight .p] == [font metrics [.p cget -font] -linespace] + 2}]
} -cleanup {
    destroy .p
    ttk::style theme use $oldTheme
    # there's no way I know to undo  '::ttk::style element create...'
} -result {1 1}

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
14
15
16
17
18
19
#
# ttk::radiobutton widget tests.
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test radiobutton-1.1 "Radiobutton check" -body {
    pack \
    	[ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \
	[ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \
	[ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \
	;
}
test radiobutton-1.2 "Radiobutton invoke" -body {
    .rb1 invoke
    set ::choice




|






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
# ttk::radiobutton widget tests.
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test radiobutton-1.1 "Radiobutton check" -body {
    pack \
	[ttk::radiobutton .rb1 -text "One" -variable choice -value 1] \
	[ttk::radiobutton .rb2 -text "Two" -variable choice -value 2] \
	[ttk::radiobutton .rb3 -text "Three" -variable choice -value 3] \
	;
}
test radiobutton-1.2 "Radiobutton invoke" -body {
    .rb1 invoke
    set ::choice
42
43
44
45
46
47
48














49
} -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}















tcltest::cleanupTests







>
>
>
>
>
>
>
>
>
>
>
>
>
>

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 add variable v write { destroy .s ;# }
    ttk::scale .s -variable v
    pack .s ; update
    .s set 1 ; update
} -returnCodes error -match glob -result "*"

test scale-2.1 "-state option" -setup {
    ttk::scale .s
    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
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
|







1
2
3
4
5
6
7
8
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
}

test scrollbar-swapout-2 "... regardless of whether -style ..." \
-constraints {
    coreScrollbar
} -body {
    ttk::style layout Vertical.Custom.TScrollbar \
    	[ttk::style layout Vertical.TScrollbar] ; # See #1833339
    ttk::scrollbar .sb -command "yadda" -style Custom.TScrollbar
    list [winfo class .sb] [.sb cget -command] [.sb cget -style]
} -result [list TScrollbar yadda Custom.TScrollbar] -cleanup {
    destroy .sb
}

test scrollbar-swapout-3 "... or -class is specified." -constraints {







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
}

test scrollbar-swapout-2 "... regardless of whether -style ..." \
-constraints {
    coreScrollbar
} -body {
    ttk::style layout Vertical.Custom.TScrollbar \
	[ttk::style layout Vertical.TScrollbar] ; # See #1833339
    ttk::scrollbar .sb -command "yadda" -style Custom.TScrollbar
    list [winfo class .sb] [.sb cget -command] [.sb cget -style]
} -result [list TScrollbar yadda Custom.TScrollbar] -cleanup {
    destroy .sb
}

test scrollbar-swapout-3 "... or -class is specified." -constraints {
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [ttk::scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s

    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}

test scrollbar-10.2.1 {<Shift-MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [ttk::scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s

    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
test scrollbar-10.2.2 {<MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [ttk::scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s

    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}

#
# Scale tests:
#

test scale-1.0 "Self-destruction" -body {
    trace variable v w { destroy .s ;# }
    ttk::scale .s -variable v
    pack .s ; update
    .s set 1 ; update
} -returnCodes error -match glob -result "*"


test scale-2.1 "-state option" -setup {
    ttk::scale .s
    set res ""

} -body {
    # defaults
    lappend res [.s instate disabled] [.s cget -state]
    # set -state: instate returns accordingly
    .s configure -state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # back to normal
    .s configure -state normal
    lappend res [.s instate disabled] [.s cget -state]
    # use state command: -state does NOT reflect it
    .s state disabled
    lappend res [.s instate disabled] [.s cget -state]
    # further use state command
    .s state readonly

    lappend res [.s state] [.s cget -state]
} -cleanup {
    destroy .s
    unset -nocomplain res
} -result {0 normal 1 disabled 0 normal 1 normal {disabled readonly} normal}

tcltest::cleanupTests








>





|









>





|








>





|

<
|
<
|
<
<
|
<
<
<
|
>
|
<
|
>
|
<
<
<
<
<
<
|
<
<
<
<
<
<
>
|

|
<
|



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

121

122


123



124
125
126

127
128
129






130






131
132
133
134

135
136
137
138
    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 <Enter>
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {4.0}

test scrollbar-10.2.1 {<Shift-MouseWheel> event on horizontal scrollbar} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [ttk::scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Enter>
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.3}
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 <Enter>
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.3}


test scrollbar-11.1 "style command" -body {

    ttk::scrollbar .wv  ; # default is  -orient vertical


    ttk::scrollbar .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 {{} Vertical.TScrollbar TScrollbar {} Horizontal.TScrollbar TScrollbar}
test scrollbar-11.2 "style command" -body {






    ttk::style configure customStyle.Horizontal.TScrollbar






    ttk::scrollbar .w -orient horizontal -style customStyle.Horizontal.TScrollbar
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w

} -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
#
# ttk::spinbox widget tests
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test spinbox-1.0 "Spinbox tests -- setup" -body {
    ttk::spinbox .sb
} -cleanup { destroy .sb } -result .sb




|







1
2
3
4
5
6
7
8
9
10
11
12
#
# ttk::spinbox widget tests
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

test spinbox-1.0 "Spinbox tests -- setup" -body {
    ttk::spinbox .sb
} -cleanup { destroy .sb } -result .sb
134
135
136
137
138
139
140
141
142

143
144
145

146
147


148

149
150
151
152
153
154
155
} -body {
    .sb configure -validate bogus
} -cleanup {
    destroy .sb
} -returnCodes error -result {bad validate "bogus": must be all, key, focus, focusin, focusout, or none}

test spinbox-1.8.4 "-validate option: " -setup {
    set ::spinbox_test {}
    ttk::spinbox .sb -from 0 -to 100

} -body {
    .sb configure -validate all -validatecommand {lappend ::spinbox_test %P}
    pack .sb

    .sb set 50
    focus -force .sb


    after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait

    set ::spinbox_test
} -cleanup {
    destroy .sb
} -result 50


test spinbox-2.0 "current command -- unset should be 0" -constraints nyi -setup {







<

>

|

>


>
>
|
>







134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
} -body {
    .sb configure -validate bogus
} -cleanup {
    destroy .sb
} -returnCodes error -result {bad validate "bogus": must be all, key, focus, focusin, focusout, or none}

test spinbox-1.8.4 "-validate option: " -setup {

    ttk::spinbox .sb -from 0 -to 100
    set ::spinbox_test {}
} -body {
    .sb configure -validate all -validatecommand {set ::spinbox_test %P}
    pack .sb
    update idletasks
    .sb set 50
    focus -force .sb
    set ::spinbox_wait 0
    set timer [after 100 {set ::spinbox_wait 1}]
    vwait ::spinbox_wait
    after cancel $timer
    set ::spinbox_test
} -cleanup {
    destroy .sb
} -result 50


test spinbox-2.0 "current command -- unset should be 0" -constraints nyi -setup {
279
280
281
282
283
284
285





















286
287
288
289
290
291
292
    }
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test max
} -result {one two three 4 5 two six six six two 5 4 three two one one one one}























# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox;
# see also #1439266
#
test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body {
    set SBV 55
    ttk::spinbox .sb -textvariable SBV -from 0 -to 100 -increment 5







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    }
    set ::spinbox_test
} -cleanup {
    destroy .sb
    unset -nocomplain ::spinbox_test max
} -result {one two three 4 5 two six six six two 5 4 three two one one one one}

test spinbox-11.2 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [ttk::spinbox .s]
    update
    set res {}
} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    lappend res [.s get]
    .s delete 0 end
    .s insert end "A sample text"
    .s icursor 2
    event generate .s <<NextWord>>  ; # shall move insert to index 9
    .s delete 0 insert
    lappend res [.s get]
} -cleanup {
    destroy .s
} -result {{A sample } text}


# nostomp: NB intentional difference between ttk::spinbox and tk::spinbox;
# see also #1439266
#
test spinbox-nostomp-1 "don't stomp on -variable (init; -from/to)" -body {
    set SBV 55
    ttk::spinbox .sb -textvariable SBV -from 0 -to 100 -increment 5
354
355
356
357
358
359
360














361
362
363
364
365
    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
}















tcltest::cleanupTests

# Local variables:
# mode: tcl
# End:







>
>
>
>
>
>
>
>
>
>
>
>
>
>





379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    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

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

### treeview tag invariants:
#


|







1
2
3
4
5
6
7
8
9

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

### treeview tag invariants:
#

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

    itemConstraints $tv {}
}
#
###

test treetags-1.0 "Setup" -body {
    set tv [ttk::treeview .tv]
    .tv insert {} end -id item1 -text "Item 1"
    pack .tv
} -cleanup {
    treeConstraints $tv
}

test treetags-1.1 "Bad tag list" -body {







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

    itemConstraints $tv {}
}
#
###

test treetags-1.0 "Setup" -body {
    set tv [ttk::treeview .tv -columns "A B C"]
    .tv insert {} end -id item1 -text "Item 1"
    pack .tv
} -cleanup {
    treeConstraints $tv
}

test treetags-1.1 "Bad tag list" -body {
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    treeConstraints $tv
} -result [list tag1]

test treetags-1.3 "tag has - test" -body {
    $tv insert {} end -id item2 -text "Item 2" -tags tag2
    set result [list]
    foreach item {item1 item2} {
    	foreach tag {tag1 tag2 tag3} {
	    lappend result $item $tag [$tv tag has $tag $item]
	}
    }
    set result
} -cleanup {
    treeConstraints $tv
} -result [list \







|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    treeConstraints $tv
} -result [list tag1]

test treetags-1.3 "tag has - test" -body {
    $tv insert {} end -id item2 -text "Item 2" -tags tag2
    set result [list]
    foreach item {item1 item2} {
	foreach tag {tag1 tag2 tag3} {
	    lappend result $item $tag [$tv tag has $tag $item]
	}
    }
    set result
} -cleanup {
    treeConstraints $tv
} -result [list \
187
188
189
190
191
192
193





194




195











































196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

# @@@ fragile test
test treetags-3.2 "tag configure - enumerate" -body {
    $tv tag configure tag1
} -cleanup {
    treeConstraints $tv
} -result [list \





    -text {} -image {} -anchor {} -background red -foreground blue -font {} \




]












































# The next test exercises tag resource management.
# If options are not properly freed, the message:
# Test file error: "Font times 20 still in cache."
# will show up on stderr at program exit.
#
test treetags-3.3 "tag configure - set font" -body {
    $tv tag configure tag2 -font {times 20}
}

test treetags-3.4 "stomp tags in tag binding procedure" -body {
    set result [list]
    $tv tag bind rm1 <<Remove>> { lappend ::result rm1 [%W focus] <<Remove>> }
    $tv tag bind rm2 <<Remove>> {
    	lappend ::result rm2 [%W focus] <<Remove>>
	%W item [%W focus] -tags {tag1}
    }
    $tv tag bind rm3 <<Remove>> { lappend ::result rm3 [%W focus] <<Remove>> }

    $tv item item1 -tags {rm1 rm2 rm3}
    $tv focus item1
    event generate $tv <<Remove>>







>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

# @@@ fragile test
test treetags-3.2 "tag configure - enumerate" -body {
    $tv tag configure tag1
} -cleanup {
    treeConstraints $tv
} -result [list \
    -image {} -imageanchor {} -background red -stripedbackground {} -foreground blue -font {} -padding {} \
                  ]
test treetags-4.1 "tag cell add" -body {
    $tv tag cell add _thetag
} -returnCodes 1 -result {wrong # args: should be ".tv tag cell add tagName cells"}

test treetags-4.2 "tag cell remove" -body {
    $tv tag cell remove _thetag
    $tv tag cell remove
} -returnCodes 1 -result {wrong # args: should be ".tv tag cell remove tagName ?cells?"}

test treetags-4.3 "tag cell has" -body {
    $tv tag cell has _thetag
    $tv tag cell has
} -returnCodes 1 -result {wrong # args: should be ".tv tag cell has tagName ?cell?"}

test treetags-4.3.1 "tag cell has" -body {
    $tv tag cell add tag1 "item1 #2"
    set res [$tv tag cell has tag1 "item1 #2"]
    lappend res [$tv tag cell has tag1 "item1 #1"]
    lappend res [$tv tag cell has tag1 "item1 #3"]
    lappend res {*}[$tv tag cell has tag1]
    $tv tag cell remove tag1 "item1 B"
    lappend res {*}[$tv tag cell has tag1]
    lappend res [$tv tag cell has tag1 "item1 #2"]
} -result {1 0 0 {item1 B} 0}

test treetags-4.4 "tag cell add" -body {
    $tv tag cell add tag1 "item1 A"
    $tv tag cell add tag1 "item1 #3"
    $tv tag cell has tag1
} -result {{item1 A} {item1 C}}

test treetags-4.5 "tag cell add" -body {
    $tv tag cell add tag2 "item1 A"
    $tv tag cell add tag2 "item1 #2"
    $tv tag cell has tag2
} -result {{item1 A} {item1 B}}

test treetags-4.6 "tag cell remove" -body {
    $tv tag cell remove tag1 "item1 A"
    $tv tag cell has tag1
} -result {{item1 C}}

test treetags-4.7 "tag cell remove" -body {
    $tv tag cell remove tag2
    $tv tag cell has tag2
} -result {}

test treetags-4.8 "tag delete with tagged cells" -body {
    $tv tag cell add tag6 "item1 A"
    $tv tag delete tag6
    $tv tag cell has tag6
} -result {}

# The next test exercises tag resource management.
# If options are not properly freed, the message:
# Test file error: "Font times 20 still in cache."
# will show up on stderr at program exit.
#
test treetags-3.3 "tag configure - set font" -body {
    $tv tag configure tag2 -font {times 20}
}

test treetags-3.4 "stomp tags in tag binding procedure" -body {
    set result [list]
    $tv tag bind rm1 <<Remove>> { lappend ::result rm1 [%W focus] <<Remove>> }
    $tv tag bind rm2 <<Remove>> {
	lappend ::result rm2 [%W focus] <<Remove>>
	%W item [%W focus] -tags {tag1}
    }
    $tv tag bind rm3 <<Remove>> { lappend ::result rm3 [%W focus] <<Remove>> }

    $tv item item1 -tags {rm1 rm2 rm3}
    $tv focus item1
    event generate $tv <<Remove>>

Changes to tests/ttk/treeview.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38






39

















40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#
# [7Jun2005] TO CHECK: [$tv see {}] -- shouldn't work (at least, shouldn't do
# what it currently does)
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

# consistencyCheck --
#	Traverse the tree to make sure the item data structures
#	are properly linked.
#
#	Since [$tv children] follows ->next links and [$tv index]
#	follows ->prev links, this should cover all invariants.
#
proc consistencyCheck {tv {item {}}} {
    set i 0;
    foreach child [$tv children $item] {
	assert {[$tv parent $child] == $item} "parent $child = $item"
	assert {[$tv index $child] == $i} "index $child [$tv index $child]=$i"
	incr i
	consistencyCheck $tv $child
    }
}

proc assert {expr {message ""}} {
    if {![uplevel 1 [list expr $expr]]} {
        set error "PANIC! PANIC! PANIC: $message ($expr failed)"
    	puts stderr $error
	error $error
    }
}

test treeview-0 "treeview test - setup" -body {

    ttk::treeview .tv -columns {a b c}
    pack .tv -expand true -fill both






    update

















}

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 error -result "list element in quotes followed by*" -match glob

test treeview-1.3 "bad displaycolumns" -body {
    .tv configure -displaycolumns {a b d}
} -returnCodes error -result "Invalid column index d"

test treeview-1.4 "more bad displaycolumns" -body {
    .tv configure -displaycolumns {1 2 3}
} -returnCodes error -result "Column index 3 out of bounds"

test treeview-1.5 "Don't forget to check negative numbers" -body {
    .tv configure -displaycolumns {1 -2 3}
} -returnCodes error -result "Column index -2 out of bounds"

# Item creation.
#
test treeview-2.1 "insert -- not enough args" -body {
    .tv insert
} -returnCodes error -result "wrong # args: *" -match 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#
# [7Jun2005] TO CHECK: [$tv see {}] -- shouldn't work (at least, shouldn't do
# what it currently does)
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

# consistencyCheck --
#	Traverse the tree to make sure the item data structures
#	are properly linked.
#
#	Since [$tv children] follows ->next links and [$tv index]
#	follows ->prev links, this should cover all invariants.
#
proc consistencyCheck {tv {item {}}} {
    set i 0
    foreach child [$tv children $item] {
	assert {[$tv parent $child] == $item} "parent $child = $item"
	assert {[$tv index $child] == $i} "index $child [$tv index $child]=$i"
	incr i
	consistencyCheck $tv $child
    }
}

proc assert {expr {message ""}} {
    if {![uplevel 1 [list expr $expr]]} {
        set error "PANIC! PANIC! PANIC: $message ($expr failed)"
	puts stderr $error
	error $error
    }
}

proc tvSetup {} {
    destroy .tv
    ttk::treeview .tv -columns {a b c}
    pack .tv -expand true -fill both
    .tv column #0 -width 50
    .tv column a -width 50
    .tv column b -width 50
    .tv column c -width 50
    # Make sure everything is created and updated
    tkwait visibility .tv
    update
    after 10
    update
}
proc tvSetupWithItems {} {
    tvSetup
    .tv insert {} end -id nn -text "nn"
    .tv insert nn end -id nn.n1 -text "nn.1"
    .tv insert nn end -id nn.n2 -text "nn.3"
    .tv insert nn end -id nn.n3 -text "nn.3"
    for {set t 2} {$t < 100} {incr t} {
        .tv insert {} end -id nn$t -text "nn$t"
        if {$t % 3 == 0} {
            .tv insert nn$t end -id nn$t.n1 -text "nn$t.n1"
            .tv insert nn$t end -id nn$t.n2 -text "nn$t.n2"
            .tv insert nn$t end -id nn$t.n3 -text "nn$t.n3"
        }
    }
}

test treeview-1.1 "columns" -body {
    tvSetup
    .tv configure -columns {a b c}
}

test treeview-1.2 "Bad columns" -body {
    #.tv configure -columns {illegal "list"value}
    ttk::treeview .badtv -columns {illegal "list"value}
} -returnCodes error -result "list element in quotes followed by*" -match glob

test treeview-1.3 "bad displaycolumns" -body {
    .tv configure -displaycolumns {a b d}
} -returnCodes error -result "Invalid column index d"

test treeview-1.4 "more bad displaycolumns" -body {
    .tv configure -displaycolumns {1 2 3}
} -returnCodes error -result {Column index "3" out of bounds}

test treeview-1.5 "Don't forget to check negative numbers" -body {
    .tv configure -displaycolumns {1 {} 3}
} -returnCodes error -result {Column index "" out of bounds}

# Item creation.
#
test treeview-2.1 "insert -- not enough args" -body {
    .tv insert
} -returnCodes error -result "wrong # args: *" -match glob

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

test treeview-2.8 "insert -- new node at end" -body {
    .tv insert {} end -id lastnode
    consistencyCheck .tv
    .tv children {}
} -result [list newnode lastnode]

consistencyCheck .tv

test treeview-2.9 "insert -- new node at beginning" -body {
    .tv insert {} 0 -id firstnode
    consistencyCheck .tv
    .tv children {}
} -result [list firstnode newnode lastnode]

test treeview-2.10 "insert -- one more node" -body {







<
<







113
114
115
116
117
118
119


120
121
122
123
124
125
126

test treeview-2.8 "insert -- new node at end" -body {
    .tv insert {} end -id lastnode
    consistencyCheck .tv
    .tv children {}
} -result [list newnode lastnode]



test treeview-2.9 "insert -- new node at beginning" -body {
    .tv insert {} 0 -id firstnode
    consistencyCheck .tv
    .tv children {}
} -result [list firstnode newnode lastnode]

test treeview-2.10 "insert -- one more node" -body {
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
    foreach item [.tv children {}] {
	lappend result [.tv index $item]
    }
    set result
} -result [list 0 1 2 3 4 5 6]

test treeview-3.6 "detach" -body {

    .tv detach newnode
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone]
# XREF: treeview-2.13

test treeview-3.7 "detach didn't screw up internal links" -body {
    consistencyCheck .tv
    set result [list]
    foreach item [.tv children {}] {
	lappend result [.tv index $item]







>


|
|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    foreach item [.tv children {}] {
	lappend result [.tv index $item]
    }
    set result
} -result [list 0 1 2 3 4 5 6]

test treeview-3.6 "detach" -body {
    set before [.tv detached newnode]
    .tv detach newnode
    consistencyCheck .tv
    list [.tv children {}] [.tv detached] $before [.tv detached newnode]
} -result {{newfirstone firstnode anotherone onemore lastnode newlastone} newnode 0 1}
# XREF: treeview-2.13

test treeview-3.7 "detach didn't screw up internal links" -body {
    consistencyCheck .tv
    set result [list]
    foreach item [.tv children {}] {
	lappend result [.tv index $item]
196
197
198
199
200
201
202

203
204
205
206
207
208

209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
    .tv detach newnode
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone]

test treeview-3.11 "Can't detach root item" -body {
    .tv detach [list {}]

    update
    consistencyCheck .tv
} -returnCodes error -result "Cannot detach root item"
consistencyCheck .tv

test treeview-3.12 "Reattach" -body {

    .tv move newnode {} end
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone newnode]

# Bug # ?????
test treeview-3.13 "Re-reattach" -body {

    .tv move newnode {} end
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone newnode]

catch {
    .tv insert newfirstone end -id x1
    .tv insert newfirstone end -id x2
    .tv insert newfirstone end -id x3
}








>



<


>


|
|



>


|
|







220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    .tv detach newnode
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone]

test treeview-3.11 "Can't detach root item" -body {
    .tv detach [list {}]
} -cleanup {
    update
    consistencyCheck .tv
} -returnCodes error -result "Cannot detach root item"


test treeview-3.12 "Reattach" -body {
    set before [.tv detached newnode]
    .tv move newnode {} end
    consistencyCheck .tv
    list [.tv children {}] $before [.tv detached newnode] [.tv detached]
} -result {{newfirstone firstnode anotherone onemore lastnode newlastone newnode} 1 0 {}}

# Bug # ?????
test treeview-3.13 "Re-reattach" -body {
    set before [.tv detached newnode]
    .tv move newnode {} end
    consistencyCheck .tv
    list [.tv children {}] $before [.tv detached newnode]
} -result {{newfirstone firstnode anotherone onemore lastnode newlastone newnode} 0 0}

catch {
    .tv insert newfirstone end -id x1
    .tv insert newfirstone end -id x2
    .tv insert newfirstone end -id x3
}

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

test treeview-5.6 "set illegal cell" -body {
    .tv set newnode #0 YYY
} -returnCodes error -result "Display column #0 cannot be set"

test treeview-5.7 "set illegal cell" -body {
    .tv set newnode 3 YY	;# 3 == current #columns
} -returnCodes error -result "Column index 3 out of bounds"

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







|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

test treeview-5.6 "set illegal cell" -body {
    .tv set newnode #0 YYY
} -returnCodes error -result "Display column #0 cannot be set"

test treeview-5.7 "set illegal cell" -body {
    .tv set newnode 3 YY	;# 3 == current #columns
} -returnCodes error -result {Column index "3" out of bounds}

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
331
332
333
334
335
336
337












338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
test treeview-5.13 "get, no value" -body {
    set newitem [.tv insert {} end]
    set result [.tv set $newitem #1]
    .tv delete $newitem
    set result
} -result {}














test treeview-6.1 "deletion - setup" -body {
    .tv insert {} end -id dtest
    foreach id [list a b c d e] {
	.tv insert dtest end -id $id
    }
    .tv children dtest
} -result [list a b c d e]

test treeview-6.1.1 "delete" -body {
    .tv delete b
    consistencyCheck .tv
    list [.tv exists b] [.tv children dtest]
} -result [list 0 [list a c d e]]

consistencyCheck .tv

test treeview-6.2 "delete - duplicate items in list" -body {
    .tv delete [list a e a e]
    consistencyCheck .tv
    .tv children dtest
} -result [list c d]

test treeview-6.3 "delete - descendants removed" -body {







>
>
>
>
>
>
>
>
>
>
>
>















<
<







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390


391
392
393
394
395
396
397
test treeview-5.13 "get, no value" -body {
    set newitem [.tv insert {} end]
    set result [.tv set $newitem #1]
    .tv delete $newitem
    set result
} -result {}

test treeview-5.14 "set illegal height" -body {
    # For now, -height can only be integer
    .tv item newnode -height 1.5
} -returnCodes 1 -result {expected integer but got "1.5"}

test treeview-5.15 "set illegal height" -body {
    .tv item newnode -height 0
} -returnCodes 1 -result "Invalid item height 0"

test treeview-5.16 "no change after illegal attempt" -body {
    .tv item newnode -height
} -result 1

test treeview-6.1 "deletion - setup" -body {
    .tv insert {} end -id dtest
    foreach id [list a b c d e] {
	.tv insert dtest end -id $id
    }
    .tv children dtest
} -result [list a b c d e]

test treeview-6.1.1 "delete" -body {
    .tv delete b
    consistencyCheck .tv
    list [.tv exists b] [.tv children dtest]
} -result [list 0 [list a c d e]]



test treeview-6.2 "delete - duplicate items in list" -body {
    .tv delete [list a e a e]
    consistencyCheck .tv
    .tv children dtest
} -result [list c d]

test treeview-6.3 "delete - descendants removed" -body {
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
    # Just check to make sure the test suite so far has left
    # us in the state we expect to be in:
    list [.tv parent newnode] [.tv children newnode]
} -result [list {} [list newnode.n1 newnode.n2 newnode.n3]]

test treeview-7.6 "Replace children - illegal move" -body {
    .tv children newnode.n1 [list newnode.n1 newnode.n2 newnode.n3]
} -returnCodes error -result "Cannot insert newnode.n1 as descendant of newnode.n1"

consistencyCheck .tv


test treeview-8.0 "Selection set" -body {
    .tv selection set [list newnode.n1 newnode.n3 newnode.n2]
    .tv selection
} -result [list newnode.n1 newnode.n2 newnode.n3]

test treeview-8.1 "Selection add" -body {
    .tv selection add [list newnode]







<
|
|
>








459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
    # 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]

} -cleanup {
    consistencyCheck .tv
} -returnCodes error -result "Cannot insert newnode.n1 as descendant of newnode.n1"

test treeview-8.0 "Selection set" -body {
    .tv selection set [list newnode.n1 newnode.n3 newnode.n2]
    .tv selection
} -result [list newnode.n1 newnode.n2 newnode.n3]

test treeview-8.1 "Selection add" -body {
    .tv selection add [list newnode]
456
457
458
459
460
461
462
463



464

465
466










































467
468











469


470
471
472
473
474
475
476
477
478
479















480



481

482

483
484









485


486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501
502
503
504
505
506



507
508
509
510
511
512
513
514
    .tv selection
} -result {}

test treeview-8.5 "Selection - bad operation" -body {
    .tv selection badop foo
} -returnCodes error -match glob -result {bad selection operation "badop": must be *}

test treeview-8.6 "Selection - <<TreeviewSelect>> on selection add" -body {



    .tv selection set {}

    bind .tv <<TreeviewSelect>> {set res 1}
    set res 0










































    .tv selection add newnode.n1
    update











    set res


} -result 1

test treeview-8.7 "<<TreeviewSelect>> on selected item deletion" -body {
    .tv selection set {}
    .tv insert "" end -id selectedDoomed -text DeadItem
    .tv insert "" end -id doomed -text AlsoDead
    .tv selection add selectedDoomed
    update
    bind .tv <<TreeviewSelect>> {lappend res 1}
    set res 0















    .tv delete doomed



    update

    set res [expr {$res == 0}]

    .tv delete selectedDoomed
    update









    set res


} -result {1 1}

### NEED: more tests for see/yview/scrolling

proc scrollcallback {args} {
    set ::scrolldata $args
}
test treeview-9.0 "scroll callback - empty tree" -body {

    .tv configure -yscrollcommand scrollcallback
    .tv delete [.tv children {}]
    update
    set ::scrolldata
} -result [list 0.0 1.0]

test treeview-9.1 "scrolling" -setup {
    pack [ttk::treeview .tree -show tree] -fill y
    for {set i 1} {$i < 100} {incr i} {
        .tree insert {} end -text $i
    }
} -body {
    .tree yview scroll 5 units



    .tree identify item 2 2
} -cleanup {
    destroy .tree
} -result {I006}

test treeview-9.2 {scrolling on see command - bug [14188104c3]} -setup {
    toplevel .top
    ttk::treeview .top.tree -show {} -height 10 -columns {label} \







|
>
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>
>
>
>
>
>
>
>
>
>
>

>
>
|

|
|
|
|
|

|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>

>
|
>
|

>
>
>
>
>
>
>
>
>

>
>
|







>













>
>
>
|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
    .tv selection
} -result {}

test treeview-8.5 "Selection - bad operation" -body {
    .tv selection badop foo
} -returnCodes error -match glob -result {bad selection operation "badop": must be *}

test treeview-8.7 "<<TreeviewSelect>> when deleting items" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    .tv selection add myItem1
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv delete myItem2  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv delete myItem1  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2}

test treeview-8.8 "<<TreeviewSelect>> when setting the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection set ""       ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv selection set myItem1  ; # <<TreeviewSelect>> triggers
    update
    # Current implementation generates an event for this case
    set val 3
    .tv selection set myItem1  ; # (already selected)
    update
    set val 4
    .tv selection set {myItem1 myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set val 5
    .tv selection set {myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2 3 4 5}

test treeview-8.9 "<<TreeviewSelect>> when removing items from the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv selection set myItem1
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection remove ""       ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv selection remove myItem1  ; # <<TreeviewSelect>> triggers
    update
    set val 3
    .tv selection remove myItem1  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2}

test treeview-8.10 "<<TreeviewSelect>> when adding items in the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    .tv insert "" end -id myItem3 -text ThirdItem
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection add myItem2  ; # <<TreeviewSelect>> triggers
    update
    set val 2
    .tv selection add myItem2  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 3
    .tv selection add myItem3  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {1 3}

test treeview-8.11 "<<TreeviewSelect>> when toggling" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    .tv insert "" end -id myItem3 -text ThirdItem
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection toggle ""  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv selection toggle {myItem1 myItem3}  ; # <<TreeviewSelect>> triggers
    update
    set val 3
    .tv selection toggle {myItem3 myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set val 4
    .tv selection toggle {myItem3 myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2 3 4}

### NEED: more tests for see/yview/scrolling

proc scrollcallback {args} {
    set ::scrolldata $args
}
test treeview-9.0 "scroll callback - empty tree" -body {
    tvSetup
    .tv configure -yscrollcommand scrollcallback
    .tv delete [.tv children {}]
    update
    set ::scrolldata
} -result [list 0.0 1.0]

test treeview-9.1 "scrolling" -setup {
    pack [ttk::treeview .tree -show tree] -fill y
    for {set i 1} {$i < 100} {incr i} {
        .tree insert {} end -text $i
    }
} -body {
    .tree yview scroll 5 units
    # This is sensitive to the exact layout of a tree.
    # It assumes that (8,8) should be far enough in to be in the tree,
    # while still being in the first item.
    .tree identify item 8 8
} -cleanup {
    destroy .tree
} -result {I006}

test treeview-9.2 {scrolling on see command - bug [14188104c3]} -setup {
    toplevel .top
    ttk::treeview .top.tree -show {} -height 10 -columns {label} \
558
559
560
561
562
563
564
















































































































































































































565
566
567
568
569
570
571
    .top.tree see e
    update idletasks
    set after [lindex [.top.vs get] 1]
    expr $after < $before
} -cleanup {
    destroy .top
} -result 1

















































































































































































































### identify tests:
#
proc identify* {tv comps args} {
    foreach {x y} $args {
	foreach comp $comps {
	    lappend result [$tv identify $comp $x $y]







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    .top.tree see e
    update idletasks
    set after [lindex [.top.vs get] 1]
    expr $after < $before
} -cleanup {
    destroy .top
} -result 1

test treeview-10.0 "See command" -setup {
    # Setup common for all 10.* tests
    ttk::style configure Treeview -rowheight 20
    tvSetupWithItems
    set ::baseBbY [lindex [.tv bbox nn "#1"] 1]
    proc bbY {item} {
        set bb [.tv bbox $item "#1"]
        set y [lindex $bb 1]
        if {$y eq ""} {return "_"}
        return [expr {$y - $::baseBbY}]
    }
} -body {
    set res ""
    lappend res [bbY nn99]
    .tv see nn99
    lappend res [bbY nn99]
    set res
} -result {_ 180}

test treeview-10.1 "See command, auto-open" -body {
    set res ""
    lappend res [bbY nn96]
    # Not yet visible
    lappend res [bbY nn96.n1]
    .tv see nn96.n1
    lappend res [bbY nn96.n1]
    # Pushed out by the opening, not visible
    lappend res [bbY nn99]
    set res
} -result {120 _ 140 _}

test treeview-10.2 "See command, height" -setup {
    .tv item nn34 -height 4
    .tv item nn55 -height 30
    .tv item nn76 -height 5
} -body {
    set res ""
    lappend res [bbY nn34]
    .tv see nn34
    lappend res [bbY nn34]
    .tv see nn33
    lappend res [bbY nn34]

    lappend res [bbY nn76]
    .tv see nn76
    lappend res [bbY nn76]

    .tv see nn53
    lappend res [bbY nn53]
    # Partly visible
    lappend res [bbY nn55]
    .tv see nn55
    # Scrolled to top
    lappend res [bbY nn55]
    set res
} -result {_ 0 20 _ 100 0 40 0}

test treeview-11.0 "Cellselection set rectangle" -setup {
    # Setup common for all 11.* tests
    tvSetupWithItems
    .tv configure -columns {a b c d}
    .tv configure -displaycolumns {a b c}
} -body {
    .tv cellselection set "nn.n3 #2" "nn.n1 a"
    .tv cellselection
} -result [list "nn.n1 a" "nn.n1 b" "nn.n2 a" "nn.n2 b" "nn.n3 a" "nn.n3 b"]

test treeview-11.1 "Cellselection set" -body {
    .tv cellselection set [list "nn.n1 a" "nn.n2 a" "nn.n3 #2" "nn.n2 d"]
    .tv cellselection
} -result [list "nn.n1 a" "nn.n2 a" "nn.n2 d" "nn.n3 b"]

test treeview-11.2 "Cellselection add" -body {
    .tv cellselection add "nn b"
    .tv cellselection
} -result [list "nn b" "nn.n1 a" "nn.n2 a" "nn.n2 d" "nn.n3 b"]

test treeview-11.3 "Cellselection toggle" -body {
    .tv cellselection toggle [list "nn.n2 a" "nn2 b" "nn2 #0"]
    .tv cellselection
} -result [list "nn b" "nn.n1 a" "nn.n2 d" "nn.n3 b" "nn2 b" "nn2 #0"]

test treeview-11.4 "Cellselection remove" -body {
    .tv cellselection remove [list "nn.n2 d" "nn b" "nn2 #0"]
    .tv cellselection
} -result [list "nn.n1 a" "nn.n3 b" "nn2 b"]

test treeview-11.5 "Cellselection add rectangle" -body {
    .tv cellselection add "nn a" "nn.n1 c"
    .tv cellselection
} -result [list \
                   "nn a" "nn b" "nn c" \
                   "nn.n1 a" "nn.n1 b" "nn.n1 c" \
                   "nn.n3 b" \
                   "nn2 b"]

test treeview-11.6 "Cellselection toggle rectangle" -body {
    .tv cellselection toggle "nn.n1 b" "nn.n3 c"
    .tv cellselection
} -result [list \
                   "nn a" "nn b" "nn c" \
                   "nn.n1 a" \
                   "nn.n2 b" "nn.n2 c" \
                   "nn.n3 c" \
                   "nn2 b"]

test treeview-11.7 "Cellselection remove rectangle" -body {
    .tv cellselection remove "nn.n1 a" "nn.n3 b"
    .tv cellselection
} -result [list \
                   "nn a" "nn b" "nn c" \
                   "nn.n2 c" \
                   "nn.n3 c" \
                   "nn2 b"]

test treeview-11.8 "Cellselection set rectangle" -body {
    # This tests that "set" clears out all old selections
    .tv cellselection set "nn b" "nn.n1 c"
    .tv cellselection
} -result [list "nn b" "nn c" "nn.n1 b" "nn.n1 c"]

test treeview-11.9 "Cellselection - clear" -body {
    .tv cellselection set {}
    .tv cellselection
} -result {}

test treeview-11.10 "Cellselection - bad operation" -body {
    .tv cellselection badop foo
} -returnCodes 1 -match glob -result {bad cellselection operation "badop": must be *}

test treeview-11.11 "Cellselection - <<TreeviewSelect>> on cellselection add" -body {
    .tv cellselection set {}
    bind .tv <<TreeviewSelect>> {set res 1}
    set res 0
    .tv cellselection add {"nn.n1 b"}
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result 1

test treeview-11.12 "<<TreeviewSelect>> on selected cell deletion" -body {
    .tv cellselection set {}
    .tv insert "" end -id selectedDoomed -text DeadItem
    .tv insert "" end -id doomed -text AlsoDead
    .tv cellselection add {"selectedDoomed c"}
    .tv cellselection add {"doomed c"}
    .tv cellselection remove {"doomed c"}
    update
    bind .tv <<TreeviewSelect>> {lappend res 1}
    set res 0
    .tv delete doomed
    update
    set res [expr {$res == 0}]
    .tv delete selectedDoomed
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {1 1}

test treeview-11.13 "Cellselection - error" -body {
    .tv cellselection set [list "apa a"]
} -returnCodes 1 -match glob -result {Item apa not found}

test treeview-11.14 "Cellselection - error" -body {
    .tv cellselection set [list "nn xx "]
} -returnCodes 1 -match glob -result {Invalid column index xx}

test treeview-11.15 "Cellselection - error" -body {
    .tv cellselection set "nn c" "nn d"
} -returnCodes 1 -match glob -result {Cell id must be in a visible column}

test treeview-11.16 "Cellselection - non visible" -body {
    .tv cellselection set [list "nn d"]
    .tv cellselection
} -result {{nn d}}

# Same as 8.8, but for cell selection
test treeview-11.17 "<<TreeviewSelect>> when setting the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv cellselection set ""   ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv cellselection set "myItem1 a"  ; # <<TreeviewSelect>> triggers
    update
    # Current implementation generates an event for this case
    set val 3
    .tv cellselection set "myItem1 a"  ; # (already selected)
    update
    set val 4
    .tv cellselection set {{myItem1 a} {myItem2 a}} ; # <<TreeviewSelect>>
    update
    set val 5
    .tv cellselection set {myItem2 a}  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2 3 4 5}


### identify tests:
#
proc identify* {tv comps args} {
    foreach {x y} $args {
	foreach comp $comps {
	    lappend result [$tv identify $comp $x $y]
587
588
589
590
591
592
593

594
595
596
597
598

599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663







664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682






























































































683
684
685
686








































































687
688
689
690
691
692
693
694
695
696
697
698
699
    }
    return $result
}

test treeview-identify-setup "identify series - setup" -body {
    destroy .tv
    ttk::setTheme default

    ttk::treeview .tv -columns [list A B C]
    .tv insert {} end -id branch -text branch -open true
    .tv insert branch end -id item1 -text item1
    .tv insert branch end -id item2 -text item2
    .tv insert branch end -id item3 -text item3


    .tv column #0 -width 50	;# 0-50
    .tv column A -width 50	;# 50-100
    .tv column B -width 50	;# 100-150
    .tv column C -width 50	;# 150-200 (plus slop for margins)

    wm geometry . {} ; pack .tv ; update
}

test treeview-identify-1 "identify heading" -body {
    .tv configure -show {headings tree}
    update idletasks
    identify* .tv {region column} 10 10
} -result [list heading #0]

test treeview-identify-2 "identify columns" -body {
    .tv configure -displaycolumns #all
    update idletasks
    columnids .tv [identify* .tv column 25 10  75 10  125 10  175 10]
} -result [list {} A B C]

test treeview-identify-3 "reordered columns" -body {
    .tv configure -displaycolumns {B A C}
    update idletasks
    columnids .tv [identify* .tv column 25 10  75 10  125 10  175 10]
} -result [list {} B A C]

test treeview-identify-4 "no tree column" -body {
    .tv configure -displaycolumns #all -show {headings}
    update idletasks
    identify* .tv {region column} 25 10  75 10  125 10  175 10
} -result [list heading #1 heading #2 heading #3 nothing {}]

# Item height in default theme is 20px
test treeview-identify-5 "vertical scan - no headings" -body {
    .tv configure -displaycolumns #all -show {tree}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 70  25 90
} -result [list tree branch tree item1 tree item2 tree item3 nothing {}]

test treeview-identify-6 "vertical scan - with headings" -body {
    .tv configure -displaycolumns #all -show {tree headings}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 70  25 90
} -result [list heading {} tree branch tree item1 tree item2 tree item3]

test treeview-identify-7 "vertical scan - headings, no tree" -body {
    .tv configure -displaycolumns #all -show {headings}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 70  25 90
} -result [list heading {} cell branch cell item1 cell item2 cell item3]

# In default theme, -indent and -itemheight both 20px
# Disclosure element name is "Treeitem.indicator"
set disclosure "*.indicator"
test treeview-identify-8 "identify element" -body {
    .tv configure -show {tree}
    .tv insert branch  0 -id branch2 -open true
    .tv insert branch2 0 -id branch3 -open true
    .tv insert branch3 0 -id leaf3
    update idletasks;
    identify* .tv {item element} 10 10  30 30  50 50
} -match glob -result [list \
	branch $disclosure branch2 $disclosure branch3 $disclosure]








# See #2381555
test treeview-identify-9 "identify works when horizontally scrolled" -setup {
    .tv configure -show {tree headings}
    foreach column {#0 A B C} {
	.tv column $column -stretch 0 -width 50
    }

    place .tv -x 0 -y 0 -width 100
} -body {
    set result [list]
    foreach xoffs {0 50 100} {
	.tv xview $xoffs ; update
	lappend result [identify* .tv {region column} 10 10 60 10]
    }
    set result
} -result [list \
	[list heading #0 heading #1] \
	[list heading #1 heading #2] \
	[list heading #2 heading #3] ]































































































test treeview-identify-cleanup "identify - cleanup" -body {
    destroy .tv
}









































































### NEED: tests for focus item, selection

### Misc. tests:

destroy .tv
test treeview-10.1 "Root node properly initialized (#1541739)" -setup {
    ttk::treeview .tv
    .tv insert {} end -id a
    .tv see a
} -cleanup {
    destroy .tv
}








>


|


>



















|





|











|
|




|





|
|














>
>
>
>
>
>
>






>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|







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
    }
    return $result
}

test treeview-identify-setup "identify series - setup" -body {
    destroy .tv
    ttk::setTheme default
    ttk::style configure Treeview -rowheight 20
    ttk::treeview .tv -columns [list A B C]
    .tv insert {} end -id branch -text branch -open true
    .tv insert branch end -id item1 -text item1 -height 2
    .tv insert branch end -id item2 -text item2
    .tv insert branch end -id item3 -text item3
    .tv insert {} end -id item4 -text item4

    .tv column #0 -width 50	;# 0-50
    .tv column A -width 50	;# 50-100
    .tv column B -width 50	;# 100-150
    .tv column C -width 50	;# 150-200 (plus slop for margins)

    wm geometry . {} ; pack .tv ; update
}

test treeview-identify-1 "identify heading" -body {
    .tv configure -show {headings tree}
    update idletasks
    identify* .tv {region column} 10 10
} -result [list heading #0]

test treeview-identify-2 "identify columns" -body {
    .tv configure -displaycolumns #all
    update idletasks
    columnids .tv [identify* .tv column 25 10  75 10  125 10  175 10]
} -result [list \#0 A B C]

test treeview-identify-3 "reordered columns" -body {
    .tv configure -displaycolumns {B A C}
    update idletasks
    columnids .tv [identify* .tv column 25 10  75 10  125 10  175 10]
} -result [list \#0 B A C]

test treeview-identify-4 "no tree column" -body {
    .tv configure -displaycolumns #all -show {headings}
    update idletasks
    identify* .tv {region column} 25 10  75 10  125 10  175 10
} -result [list heading #1 heading #2 heading #3 nothing {}]

# Item height in default theme is 20px
test treeview-identify-5 "vertical scan - no headings" -body {
    .tv configure -displaycolumns #all -show {tree}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 70  25 90  25 110  25 130
} -result [list tree branch tree item1 tree item2 tree item3 tree item4 nothing {}]

test treeview-identify-6 "vertical scan - with headings" -body {
    .tv configure -displaycolumns #all -show {tree headings}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 90  25 110
} -result [list heading {} tree branch tree item1 tree item2 tree item3]

test treeview-identify-7 "vertical scan - headings, no tree" -body {
    .tv configure -displaycolumns #all -show {headings}
    update idletasks
    identify* .tv {region item cell} 25 10  25 30  25 50  75 90  25 110
} -result [list heading {} {} cell branch {branch #1} cell item1 {item1 #1} cell item2 {item2 #2} cell item3 {item3 #1}]

# In default theme, -indent and -itemheight both 20px
# Disclosure element name is "Treeitem.indicator"
set disclosure "*.indicator"
test treeview-identify-8 "identify element" -body {
    .tv configure -show {tree}
    .tv insert branch  0 -id branch2 -open true
    .tv insert branch2 0 -id branch3 -open true
    .tv insert branch3 0 -id leaf3
    update idletasks;
    identify* .tv {item element} 10 10  30 30  50 50
} -match glob -result [list \
	branch $disclosure branch2 $disclosure branch3 $disclosure]

test treeview-identify-8.1 "identify element" -body {
    .tv configure -show {tree headings}
    update
    identify* .tv element 1 1  10 10  25 25
    # Heading elements are currently not reported
} -result [list {} {} text]

# See #2381555
test treeview-identify-9 "identify works when horizontally scrolled" -setup {
    .tv configure -show {tree headings}
    foreach column {#0 A B C} {
	.tv column $column -stretch 0 -width 50
    }
    # Scrollable area is 200, visible is 100
    place .tv -x 0 -y 0 -width 100
} -body {
    set result [list]
    foreach xoffs {0 50 100} {
	.tv xview $xoffs ; update
	lappend result [identify* .tv {region column} 10 10 60 10]
    }
    set result
} -result [list \
	[list heading #0 heading #1] \
	[list heading #1 heading #2] \
	[list heading #2 heading #3] ]

test treeview-identify-10 "identify works when horizontally scrolled" -setup {
    .tv configure -show {tree headings}
    .tv configure -titlecolumns 1
    foreach column {"#0" A B C} {
	.tv column $column -stretch 0 -width 50
    }
    # Scrollable area is 200, visible is 150
    place .tv -x 0 -y 0 -width 150
} -body {
    set result [list]
    foreach xoffs {0 25 50} {
	.tv xview $xoffs
        update
	lappend result [identify* .tv {region column} 10 10 60 10]
	lappend result [identify* .tv {region column} 10 50 60 50]
    }
    set result
} -result [list \
	[list heading #0 heading #1] [list tree #0 cell #1] \
	[list heading #0 heading #1] [list tree #0 cell #1] \
	[list heading #0 heading #2] [list tree #0 cell #2] ]

# Hijack the setup above to check bbox too
test treeview-identify-10b "bbox works when horizontally scrolled" -body {
    # Establish a point of reference
    .tv configure -titlecolumns 0
    .tv xview 0
    update
    set base [lindex [.tv bbox branch "#0"] 0]
    set result [list]
    foreach tc {0 1 2 3} {
        .tv configure -titlecolumns $tc
        foreach xoffs {0 25 50} {
            .tv xview $xoffs
            update
            # Extract x coordinate for each column
            lappend result [expr {[lindex [.tv bbox branch "#0"] 0] - $base}]
            lappend result [expr {[lindex [.tv bbox branch A   ] 0] - $base}]
            lappend result [expr {[lindex [.tv bbox branch B   ] 0] - $base}]
            lappend result [expr {[lindex [.tv bbox branch C   ] 0] - $base}]
        }
    }
    set result
} -result [list 0 50 100 150  -25 25  75 125   -50  0  50 100 \
                0 50 100 150    0 25  75 125     0  0  50 100 \
                0 50 100 150    0 50  75 125     0 50  50 100 \
                0 50 100 150    0 50 100 125     0 50 100 101]

# Followup to trigger crash that happened when title > display
test treeview-identify-10c "title more than display" -body {
    .tv configure -titlecolumns 10
    .tv xview 0
    update
    set x1 [.tv xview]
    # It shouldn't be possible to scroll
    .tv xview 50
    update
    set x2 [.tv xview]
    set result [list $x1 $x2]
} -result {{0.0 1.0} {0.0 1.0}}


test treeview-identify-11 "bbox supporting -height" -body {
    .tv configure -titlecolumns 0
    .tv xview 0
    .tv item branch2 -open false
    # Add extra items to make sure it scrolls
    .tv insert {} end -id item5 -text item5
    .tv insert {} end -id item6 -text item6
    # Height needs to be big enough to show the items we measure
    # and small enough to make scrolling happen.
    .tv configure -height 6
    pack .tv -side top
    update
    set base [lindex [.tv bbox branch A] 1]
    set result {}
    foreach yv {0 1} {
        .tv yview $yv
        update
        foreach item {item1 item2 item3} {
            set bb [.tv bbox $item A]
            set y [lindex $bb 1]
            if {$y eq ""} {
                # This is to get a clearer error if this goes wrong
                lappend result {}
            } else {
                lappend result [expr {$y - $base}]
            }
            lappend result [lindex $bb 3]
        }
    }
    set result
} -result [list 40 40 80 20 100 20  20 40 60 20 80 20]

test treeview-identify-cleanup "identify - cleanup" -body {
    destroy .tv
}


test treeview-rowheight-1 "rowheight - setup" -body {
    destroy .tv
    ttk::setTheme default
    # Test that style rowheight is in control
    ttk::style configure Treeview -rowheight 73
    tvSetupWithItems
    lindex [.tv bbox nn a] 3
} -result 73

test treeview-rowheight-2 "rowheight change" -body {
    # Reacts to style changes
    ttk::style configure Treeview -rowheight 25
    update
    lindex [.tv bbox nn a] 3
} -cleanup {
    ttk::style configure Treeview -rowheight {}
} -result 25

test treeview-rowheight-3 "rowheight adapts to font" -constraints haveBigFontTwiceLargerThanTextFont -body {
    ttk::style configure Treeview -font "Courier 12"
    update
    set baseline [lindex [.tv bbox nn a] 3]
    ttk::style configure Treeview -font "Helvetica 24"
    update
    set after [lindex [.tv bbox nn a] 3]
    set diff [expr {$after - $baseline}]
    # We only want to check there is an increase,
    # its exact magnitude does not matter
    expr {0 < $diff ? "OK" : $diff}
} -result OK

test treeview-rowheight-3b "rowheight adapts to named font" -constraints haveBigFontTwiceLargerThanTextFont -body {
    font create __tf -family Courier -size 12
    ttk::style configure Treeview -font __tf
    update
    set baseline [lindex [.tv bbox nn a] 3]
    font configure __tf -family Helvetica -size 24
    update
    set after [lindex [.tv bbox nn a] 3]
    set diff [expr {$after - $baseline}]
    # We only want to check there is an increase,
    # its exact magnitude does not matter
    expr {0 < $diff ? "OK" : $diff}
} -result OK

test treeview-rowheight-4 "rowheight adapts to item padding" -body {
    # Test that things from Item style is picked up.
    ttk::style configure Item -padding "2 2 2 2"
    update
    set baseline [lindex [.tv bbox nn a] 3]
    ttk::style configure Item -padding "2 3 2 5"
    update
    set after [lindex [.tv bbox nn a] 3]
    set diff [expr {$after - $baseline}]
} -cleanup {
    ttk::style configure Item -padding {}
} -result [expr {3-2 + 5-2}]

test treeview-rowheight-5 "rowheight adapts to cell padding" -body {
    # Test that things from Cell style is picked up.
    ttk::style configure Cell -padding "2 5 2 5"
    update
    set baseline [lindex [.tv bbox nn a] 3]
    ttk::style configure Cell -padding "2 8 2 9"
    update
    set after [lindex [.tv bbox nn a] 3]
    set diff [expr {$after - $baseline}]
} -cleanup {
    ttk::style configure Cell -padding {}
} -result [expr {8-5 + 9-5}]

### NEED: tests for focus item, selection

### Misc. tests:

destroy .tv
test treeview-1541739 "Root node properly initialized (#1541739)" -setup {
    ttk::treeview .tv
    .tv insert {} end -id a
    .tv see a
} -cleanup {
    destroy .tv
}

830
831
832
833
834
835
836
837


























































































































838
    .tv configure -displaycolumns {bar colC colA colB}
    update idletasks ; # no slack anymore because the widget resizes (shrinks)
    lappend res [.tv column bar -width] [.tv column colA -width] \
                [expr {[winfo width .tv] < $origTreeWidth}]
} -cleanup {
    destroy .tv
} -result {60 50 60 50 60 50 1}



























































































































tcltest::cleanupTests








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
    .tv configure -displaycolumns {bar colC colA colB}
    update idletasks ; # no slack anymore because the widget resizes (shrinks)
    lappend res [.tv column bar -width] [.tv column colA -width] \
                [expr {[winfo width .tv] < $origTreeWidth}]
} -cleanup {
    destroy .tv
} -result {60 50 60 50 60 50 1}

test treeview-bc602049ab "treeview with custom background does not change size when switching themes" -setup {
    image create photo tvbg -data {
	iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAnXAAAJ1wG
	xbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAACJJREFUOI
	1jPLF9+38GKgImaho2auCogaMGjho4auBQMhAAyR0DXUEyypsAAAAASUVORK5CYII=
    }
    ttk::style theme create foo-bc602049ab -parent clam -settings {
      ttk::style element create Treeview.field image tvbg -width 0 -height 0
    }
    ttk::style theme use foo-bc602049ab
    pack [ttk::treeview .tv]
    update idletasks
} -body {
    set g1 [winfo geometry .tv]
    ttk::style theme use foo-bc602049ab
    update idletasks
    set g2 [winfo geometry .tv]
    expr {$g1 eq $g2 ? 1 : "$g1 --> $g2"}
} -cleanup {
    destroy .tv
    image delete tvbg
} -result {1}

test treeview-6ee162c3d9 "style configure Treeview -rowheight 0" -setup {
    tvSetupWithItems
} -body {
    ttk::style configure Treeview -rowheight 0  ; # shall not crash
    update
} -result {}

test treeview-column0-leak "Test for leak in tree column" -setup {
    destroy .ttt
    set heading [string range _Hej_ 1 3]
} -body {
    for {set t 0} {$t < 3} {incr t} {
        ttk::treeview .tapa -columns "hej hopp"
        .tapa heading #0 -text $heading
        destroy .tapa
    }
    tcl::unsupported::representation $heading
} -match glob -result {*refcount of 3,*}

test treeview-21.1 "style command" -body {
    ttk::treeview .w
    list [.w cget -style] [.w style] [winfo class .w]
} -cleanup {
    destroy .w
} -result {{} Treeview Treeview}
test treeview-21.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}

test treeview-22.1 "tag bindings" -setup {
    tvSetupWithItems
    .tv tag configure t1 -background red
    .tv tag configure t2 -background blue
    .tv item nn -open 1
    # Tags on item and cell to spot the difference
    .tv tag add t1 "nn.n1"
    .tv tag cell add t2 "nn.n1 a"
    .tv tag cell add t2 "nn.n2 c"
    update
    proc cellEvent {item col} {
        # Find midpoint of cell
        lassign [.tv bbox $item $col] aX aY aW aH
        set aX [expr {$aX + $aW / 2}]
        set aY [expr {$aY + $aH / 2}]
        event generate .tv <Button-1> -x $aX -y $aY
    }
} -body {
    .tv tag bind t1 <Button-1> {lappend ::tagtest t1}
    .tv tag bind t2 <Button-1> {lappend ::tagtest t2}
    # Cell with both binds
    set ::tagtest a
    cellEvent nn.n1 a
    # Cell with just item tag
    lappend ::tagtest b
    cellEvent nn.n1 b
    # Cell with just cell tag
    lappend ::tagtest c
    cellEvent nn.n2 c
    # Same tag on both cell and item should fire once
    .tv tag cell add t1 "nn.n1 b"
    lappend ::tagtest b
    cellEvent nn.n1 b
    # Break in first bind
    .tv tag bind t1 <Button-1> {lappend ::tagtest t1;break}
    lappend ::tagtest a
    cellEvent nn.n1 a
    set ::tagtest
} -cleanup {
    rename cellEvent {}
    destroy .tv
} -result {a t1 t2 b t1 c t2 b t1 a t1}
test treeview-12.2 "tag bindings deletion on tag delete" -setup {
    tvSetupWithItems
    .tv tag bind nn.n1 <Button-1> {puts Triggered}
} -body {
    .tv tag delete nn.n1
    .tv tag bind nn.n1
} -cleanup {
    destroy .tv
} -result {}

test treeview-23.1 "cell padding" -setup {
    tvSetupWithItems
} -body {
    .tv tag cell add mytag "nn b"
    set redcross [image create photo -format gif -data {R0lGODlhBwAHAIABAP8AAP///
            yH5BAEKAAEALAAAAAAHAAcAAAIMBIKmsWrIXnLxuDMLADs=}]
    .tv tag configure mytag -image $redcross
    .tv tag configure mytag -imageanchor nw
    .tv tag configure mytag -padding {2 4 6 8}
    .tv tag configure mytag -padding
} -cleanup {
    destroy .tv
} -result {2 4 6 8}

tcltest::cleanupTests

Changes to tests/ttk/ttk.test.

1
2
3
4
5
6
7
8
9

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

proc skip args {}
proc ok {} { return }


|







1
2
3
4
5
6
7
8
9

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

proc skip args {}
proc ok {} { return }

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# Do these early, so any memory corruption has a longer time to cause a crash.
#
proc selfdestruct {w args} {
    destroy $w
}
test ttk-6.1 "Self-destructing checkbutton" -body {
    pack [ttk::checkbutton .sd -text "Self-destruction" -variable ::sd]
    trace variable sd w [list selfdestruct .sd]
    update
    .sd invoke
} -returnCodes error
test ttk-6.2 "Checkbutton self-destructed" -body {
    winfo exists .sd
} -result 0

# test ttk-6.3 not applicable [see #2175411]

test ttk-6.4 "Destroy widget in configure" -setup {
    set OUCH ouch
    trace variable OUCH r { kill.b }
    proc kill.b {args} { destroy .b }
} -cleanup {
    unset OUCH
} -body {
    pack [ttk::checkbutton .b]
    set rc [catch { .b configure -variable OUCH } msg]
    list $rc $msg [winfo exists .b] [info commands .b]







|











|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# Do these early, so any memory corruption has a longer time to cause a crash.
#
proc selfdestruct {w args} {
    destroy $w
}
test ttk-6.1 "Self-destructing checkbutton" -body {
    pack [ttk::checkbutton .sd -text "Self-destruction" -variable ::sd]
    trace add variable sd write [list selfdestruct .sd]
    update
    .sd invoke
} -returnCodes error
test ttk-6.2 "Checkbutton self-destructed" -body {
    winfo exists .sd
} -result 0

# test ttk-6.3 not applicable [see #2175411]

test ttk-6.4 "Destroy widget in configure" -setup {
    set OUCH ouch
    trace add variable OUCH read { kill.b }
    proc kill.b {args} { destroy .b }
} -cleanup {
    unset OUCH
} -body {
    pack [ttk::checkbutton .b]
    set rc [catch { .b configure -variable OUCH } msg]
    list $rc $msg [winfo exists .b] [info commands .b]
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    .b invoke
    destroy .b
    set ::A
} -result {it worked}

test ttk-6.9 "Bad font spec in styles" -setup {
    ttk::style theme create badfont -settings {
    	ttk::style configure . -font {Helvetica 12 Bogus}
    }
    ttk::style theme use badfont
} -cleanup {
    ttk::style theme use default
} -body {
    pack [ttk::label .l -text Hi! -font {}]
    event generate .l <Expose>







|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    .b invoke
    destroy .b
    set ::A
} -result {it worked}

test ttk-6.9 "Bad font spec in styles" -setup {
    ttk::style theme create badfont -settings {
	ttk::style configure . -font {Helvetica 12 Bogus}
    }
    ttk::style theme use badfont
} -cleanup {
    ttk::style theme use default
} -body {
    pack [ttk::label .l -text Hi! -font {}]
    event generate .l <Expose>
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
} -body {
    catch {ttk::label .l} errmsg
    list $errmsg [info commands .l] [winfo exists .l]
} -result [list {bad cursor spec "badCursor"} {} 0]

test ttk-construction-failure-2 "Destroy widget in constructor" -setup {
    set OUCH ouch
    trace variable OUCH r { kill.b }
    proc kill.b {args} { destroy .b }
} -cleanup {
    unset OUCH
} -body {
    list \
	[catch { ttk::checkbutton .b -variable OUCH } msg] \
	$msg \
    	[winfo exists .b] \
	[info commands .b] \
	;
} -result [list 1 "widget has been destroyed" 0 {}]

test ttk-selfdestruct-ok-1 "Intentional self-destruction" -body {
    # see #2298720
    toplevel .t







|







|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
} -body {
    catch {ttk::label .l} errmsg
    list $errmsg [info commands .l] [winfo exists .l]
} -result [list {bad cursor spec "badCursor"} {} 0]

test ttk-construction-failure-2 "Destroy widget in constructor" -setup {
    set OUCH ouch
    trace add variable OUCH read { kill.b }
    proc kill.b {args} { destroy .b }
} -cleanup {
    unset OUCH
} -body {
    list \
	[catch { ttk::checkbutton .b -variable OUCH } msg] \
	$msg \
	[winfo exists .b] \
	[info commands .b] \
	;
} -result [list 1 "widget has been destroyed" 0 {}]

test ttk-selfdestruct-ok-1 "Intentional self-destruction" -body {
    # see #2298720
    toplevel .t
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

proc checkstate {w} {
    foreach statespec {
	{!active !disabled}
	{!active disabled}
	{active !disabled}
	{active disabled}
    	active
	disabled
    } {
    	lappend result [$w instate $statespec]
    }
    set result
}

# NB: this will fail if the top-level window pops up underneath the cursor
test ttk-2.0 "Check state" -body {
    checkstate .t







|


|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

proc checkstate {w} {
    foreach statespec {
	{!active !disabled}
	{!active disabled}
	{active !disabled}
	{active disabled}
	active
	disabled
    } {
	lappend result [$w instate $statespec]
    }
    set result
}

# NB: this will fail if the top-level window pops up underneath the cursor
test ttk-2.0 "Check state" -body {
    checkstate .t
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    destroy .b
    set ttk28 {}
    pack [ttk::button .b -command {set ::ttk28 failed}]
    update
} -body {
    bind .b <Button-1> {after 0 {.b configure -state disabled}}
    after 1 {event generate .b <Button-1>}
    after 20 {event generate .b <ButtonRelease-1>}
    set aid [after 100 {set ::ttk28 [.b instate {disabled !pressed}]}]
    vwait ::ttk28
    after cancel $aid
    set ttk28
} -cleanup {
    destroy .b
    unset -nocomplain ttk28 aid







|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    destroy .b
    set ttk28 {}
    pack [ttk::button .b -command {set ::ttk28 failed}]
    update
} -body {
    bind .b <Button-1> {after 0 {.b configure -state disabled}}
    after 1 {event generate .b <Button-1>}
    after 50 {event generate .b <ButtonRelease-1>}
    set aid [after 100 {set ::ttk28 [.b instate {disabled !pressed}]}]
    vwait ::ttk28
    after cancel $aid
    set ttk28
} -cleanup {
    destroy .b
    unset -nocomplain ttk28 aid
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
	# @@@ but that's not really feasible in the current framework.
    }
    pack [ttk::button .tb1 -text "Ouch"]
    ttk::style theme use alt
    update;
    # As long as we haven't crashed, everything's OK
    ttk::style theme settings alt {
    	ttk::style configure TButton -font TkDefaultFont
    }
    ttk::style theme use default
    destroy .tb1
}

#
# -compound tests:







|







293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
	# @@@ but that's not really feasible in the current framework.
    }
    pack [ttk::button .tb1 -text "Ouch"]
    ttk::style theme use alt
    update;
    # As long as we haven't crashed, everything's OK
    ttk::style theme settings alt {
	ttk::style configure TButton -font TkDefaultFont
    }
    ttk::style theme use default
    destroy .tb1
}

#
# -compound tests:
436
437
438
439
440
441
442









443
444
445
446
447
448
449
test ttk-9.8 "-textvariable overrides -text" -body {
    ttk::label .tl -textvariable TV
    set TV Foo
    .tl configure -text Bar
    .tl cget -text
} -cleanup { destroy .tl } -result "Foo"










#
# Frame widget tests:
#

test ttk-10.1 "ttk::frame -class resource" -body {
    ttk::frame .f -class Foo
} -result .f







>
>
>
>
>
>
>
>
>







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
test ttk-9.8 "-textvariable overrides -text" -body {
    ttk::label .tl -textvariable TV
    set TV Foo
    .tl configure -text Bar
    .tl cget -text
} -cleanup { destroy .tl } -result "Foo"

test ttk-9.9 "default for -justify" -body {
    ttk::label .tl
    .tl cget -justify
} -cleanup { destroy .tl } -result "left"
test ttk-9.10 "default for -anchor" -body {
    ttk::label .tl
    .tl cget -anchor
} -cleanup { destroy .tl } -result "w"

#
# Frame widget tests:
#

test ttk-10.1 "ttk::frame -class resource" -body {
    ttk::frame .f -class Foo
} -result .f
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
    .tb1 configure -style badstyle
} -cleanup {
    destroy .tb1
} -returnCodes error -result "*badstyle not found*" -match glob

test ttk-13.5 "Custom layouts -- missing element definition" -body {
    ttk::style layout badstyle {
    	NoSuchElement
    }
    ttk::button .tb1 -style badstyle
} -cleanup {
    destroy .tb1
} -result .tb1
# @@@ Should: signal an error, possibly a background error.








|







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
    .tb1 configure -style badstyle
} -cleanup {
    destroy .tb1
} -returnCodes error -result "*badstyle not found*" -match glob

test ttk-13.5 "Custom layouts -- missing element definition" -body {
    ttk::style layout badstyle {
	NoSuchElement
    }
    ttk::button .tb1 -style badstyle
} -cleanup {
    destroy .tb1
} -result .tb1
# @@@ Should: signal an error, possibly a background error.

587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
  -match glob -cleanup { destroy .tw }

test ttk-15.1 {Bug 3062331} -setup {
    destroy .b
} -body {
    set Y {}
    ttk::button .b -textvariable Y
    trace variable Y u "destroy .b; #"
    unset Y
} -cleanup {
    destroy .b
} -result {}

test ttk-15.2 {Bug 3341056} -setup {
    proc foo {} {







|







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  -match glob -cleanup { destroy .tw }

test ttk-15.1 {Bug 3062331} -setup {
    destroy .b
} -body {
    set Y {}
    ttk::button .b -textvariable Y
    trace add variable Y unset "destroy .b; #"
    unset Y
} -cleanup {
    destroy .b
} -result {}

test ttk-15.2 {Bug 3341056} -setup {
    proc foo {} {
651
652
653
654
655
656
657











658
659
660
661
662
     ttk::style element create plain.background from
} -returnCodes error -result [wrong#args theme ?element?]

test ttk-ensemble-5 "style element create: valid" -body {
     ttk::style element create plain.background from default
} -returnCodes 0 -result ""












eval destroy [winfo children .]

tcltest::cleanupTests

#*EOF*







>
>
>
>
>
>
>
>
>
>
>
|




660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
     ttk::style element create plain.background from
} -returnCodes error -result [wrong#args theme ?element?]

test ttk-ensemble-5 "style element create: valid" -body {
     ttk::style element create plain.background from default
} -returnCodes 0 -result ""

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


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
##
## Entry widget validation tests
## Derived from core test suite entry-19.1 through entry-19.20
##

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*

loadTestedCommands

testConstraint ttkEntry 1
testConstraint coreEntry [expr {![testConstraint ttkEntry]}]





|







1
2
3
4
5
6
7
8
9
10
11
12
13
##
## Entry widget validation tests
## Derived from core test suite entry-19.1 through entry-19.20
##

package require tk
package require tcltest 2.2
namespace import -force tcltest::*

loadTestedCommands

testConstraint ttkEntry 1
testConstraint coreEntry [expr {![testConstraint ttkEntry]}]
74
75
76
77
78
79
80


81
82

83
84
85
86
87


88
89

90
91
92
93
94
95


96
97

98
99
100
101
102


103
104

105
106
107
108
109
110


111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
    set ::vVals {}
    .e configure -validate focus
    .e insert end d
    set ::vVals
} -result {}

test validate-1.8 {entry widget validation - vmode focus} -body {


    focus -force .e
    # update necessary to process FocusIn event

    update
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focus focusin}

test validate-1.9 {entry widget validation - vmode focus} -body {


    focus -force .
    # update necessary to process FocusOut event

    update
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focus focusout}

.e configure -validate all
test validate-1.10 {entry widget validation - vmode all} -body {


    focus -force .e
    # update necessary to process FocusIn event

    update
    set ::vVals
} -result {.e -1 -1 abcd abcd {} all focusin}

test validate-1.11 {entry widget validation} -body {


    focus -force .
    # update necessary to process FocusOut event

    update
    set ::vVals
} -result {.e -1 -1 abcd abcd {} all focusout}
.e configure -validate focusin

test validate-1.12 {entry widget validation} -body {


    focus -force .e
    # update necessary to process FocusIn event

    update
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test validate-1.13 {entry widget validation} -body {
    set ::vVals {}
    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals
} -result {}
.e configure -validate focuso

test validate-1.14 {entry widget validation} -body {

    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals
} -result {}

test validate-1.15 {entry widget validation} -body {
    focus -force .
    # update necessary to process FocusOut event







>
>

<
>
|




>
>

<
>
|





>
>

<
>
|




>
>

<
>
|





>
>

<
>
|






<






>

<







74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
    set ::vVals {}
    .e configure -validate focus
    .e insert end d
    set ::vVals
} -result {}

test validate-1.8 {entry widget validation - vmode focus} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .e

    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focus focusin}

test validate-1.9 {entry widget validation - vmode focus} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .

    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focus focusout}

.e configure -validate all
test validate-1.10 {entry widget validation - vmode all} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .e

    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} all focusin}

test validate-1.11 {entry widget validation} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .

    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} all focusout}
.e configure -validate focusin

test validate-1.12 {entry widget validation} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .e

    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test validate-1.13 {entry widget validation} -body {
    set ::vVals {}
    focus -force .

    update
    set ::vVals
} -result {}
.e configure -validate focuso

test validate-1.14 {entry widget validation} -body {
    set ::vVals {}
    focus -force .e

    update
    set ::vVals
} -result {}

test validate-1.15 {entry widget validation} -body {
    focus -force .
    # update necessary to process FocusOut event
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

### invalid state behavior
#

test validate-3.0 "Setup" -body {
    set ::E "123"
    ttk::entry .e \
    	-validatecommand {string is integer -strict %P} \
	-validate all \
	-textvariable ::E \
	;
    return [list [.e get] [.e state]]
} -result [list 123 {}]

test validate-3.1 "insert - valid" -body {







|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

### invalid state behavior
#

test validate-3.0 "Setup" -body {
    set ::E "123"
    ttk::entry .e \
	-validatecommand {string is integer -strict %P} \
	-validate all \
	-textvariable ::E \
	;
    return [list [.e get] [.e state]]
} -result [list 123 {}]

test validate-3.1 "insert - valid" -body {

Changes to tests/ttk/vsapi.test.

1
2
3
4
5
6
7
8
9
10
11
# -*- tcl -*-
#

package require Tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint xpnative \
    [expr {"xpnative" in [ttk::style theme names]}]




|







1
2
3
4
5
6
7
8
9
10
11
# -*- tcl -*-
#

package require tk
package require tcltest 2.2
namespace import -force tcltest::*
loadTestedCommands

testConstraint xpnative \
    [expr {"xpnative" in [ttk::style theme names]}]

Changes to tests/unixButton.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# This file is a Tcl script to test the Unix specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkUnixButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# This file is a Tcl script to test the Unix specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkUnixButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# This file is a Tcl script to test out the procedures in the file
# tkUnixEmbed.c.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

namespace eval ::_test_tmp {}

# ------------------------------------------------------------------------------
#  Proc ::_test_tmp::testInterp
# ------------------------------------------------------------------------------





|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is a Tcl script to test out the procedures in the file
# tkUnixEmbed.c.  It is organized in the standard fashion for Tcl
# tests.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# ------------------------------------------------------------------------------
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771

772
773
774
775
776
777
778
779
780
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
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]
    expr ([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green) \
	    && ([lindex $vals 2]/256 == $blue)
}

testConstraint pressbutton [llength [info commands pressbutton]]

test unixEmbed-1.1 {TkpUseWindow procedure, bad window identifier} -constraints {
	unix
} -setup {
	deleteWindows
} -body {
    toplevel .t -use xyz
} -returnCodes error -result {expected integer but got "xyz"}
test unixEmbed-1.2 {TkpUseWindow procedure, bad window identifier} -constraints {
	unix
} -setup {
	deleteWindows
} -body {
    toplevel .t -use 47
} -returnCodes error -result {couldn't create child of window "47"}
test unixEmbed-1.3 {TkpUseWindow procedure, inheriting colormap} -constraints {
	unix nonPortable
} -setup {
	deleteWindows
} -body {
    toplevel .t -colormap new
    wm geometry .t +0+0
    eatColors .t.t
    frame .t.f -container 1
    toplevel .x -use [winfo id .t.f]
    colorsFree .x
} -cleanup {
	deleteWindows
} -result 0
test unixEmbed-1.4 {TkpUseWindow procedure, inheriting colormap} -constraints {
	unix nonPortable
} -setup {
	deleteWindows
} -body {
    toplevel .t -container 1 -colormap new
    wm geometry .t +0+0
    eatColors .t2
    toplevel .x -use [winfo id .t]
    colorsFree .x
} -cleanup {
	deleteWindows
} -result 1

test unixEmbed-1.5 {TkpUseWindow procedure, creating Container records} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t -use $w
	list [testembed] [expr [lindex [lindex [testembed all] 0] 0] - $w]
    }
} -cleanup {
	deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.5a {TkpUseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    child alias w winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t -use [w]
        list [testembed] [expr {[lindex [lindex [testembed all] 0] 0] - [w]}]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.6 {TkpUseWindow procedure, creating Container records} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg "set w2 [winfo id .f2]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    toplevel .t2 -use $w2
	    testembed
    }
} -cleanup {
	deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.6a {TkpUseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    child alias w1 winfo id .f1
    child alias w2 winfo id .f2
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        toplevel .t2 -use [w2]
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.7 {TkpUseWindow procedure, container and embedded in same app} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    toplevel .t1 -use [winfo id .f1]
    toplevel .t2 -use [winfo id .f2]
    testembed
} -cleanup {
	deleteWindows
} -result {{XXX .f2 {} .t2} {XXX .f1 {} .t1}}

# Can't think of any way to test the procedures TkpMakeWindow,
# TkpMakeContainer, or EmbedErrorProc.


test unixEmbed-2.1 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    testembed
    }
    destroy .f1
    update
    dobg {
	    testembed
    }
} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-2.1a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        testembed
    }
    destroy .f1
    update
    child eval {
        testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    testembed
	    destroy .t1
	    testembed
    }
} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-2.2a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        testembed
        destroy .t1
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-2.3 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    toplevel .t1 -use [winfo id .f1]
    update
    destroy .f1
    testembed
} -result {}
test unixEmbed-2.4 {EmbeddedEventProc procedure} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
    pack [frame .f1 -container 1 -width 200 -height 50]
    toplevel .t1 -use [winfo id .f1]
    set x [testembed]
    update
    destroy .t1
    update
    list $x [winfo exists .t1] [winfo exists .f1] [testembed]
} -cleanup {
	deleteWindows
} -result "{{XXX .f1 {} .t1}} 0 0 {}"


test unixEmbed-3.1 {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed nonPortable
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    set x [testembed]
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
	deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 XXX {}}}}
test unixEmbed-3.1a {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed
} -setup {
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    set x [testembed]
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 {} {}}}}
test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} -constraints {
	unix
} -setup {
	deleteWindows
    update
} -body {
    toplevel .t1 -container 1
    wm geometry .t1 +0+0
    toplevel .t2 -use [winfo id .t1] -bg red
    update
    wm geometry .t2
} -cleanup {
	deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1 -bd 2 -relief raised
	    update
	    wm geometry .t1 +30+40
    }
    update
    dobg {
	    wm geometry .t1
    }
} -cleanup {
	deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -bd 2 -relief raised
        update
        wm geometry .t1 +30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.4 {ContainerEventProc procedure, disallow position changes} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    update
	    wm geometry .t1 300x100+30+40
    }
    update
    dobg {
	    wm geometry .t1
    }
} -cleanup {
	deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.4a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        wm geometry .t1 300x100+30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.5 {ContainerEventProc procedure, geometry requests} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    dobg {
	    .t1 configure -width 300 -height 80
    }
    update
    list [winfo width .f1] [winfo height .f1] [dobg {wm geometry .t1}]
} -cleanup {
	deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.5a {ContainerEventProc procedure, geometry requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        .t1 configure -width 300 -height 80
        update
    }
    list [winfo width .f1] [winfo height .f1] [child eval {wm geometry .t1}]
} -cleanup {
    interp delete child
    deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.6 {ContainerEventProc procedure, map requests} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    set x unmapped
	    bind .t1 <Map> {set x mapped}
    }
    update
    dobg {
	    after 100
	    update
	    set x
    }
} -cleanup {
	deleteWindows
} -result {mapped}
test unixEmbed-3.6a {ContainerEventProc procedure, map requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        set x unmapped
        bind .t1 <Map> {set x mapped}
        update
        after 100
        update
        set x
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {mapped}
test unixEmbed-3.7 {ContainerEventProc procedure, destroy events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    bind .f1 <Destroy> {set x dead}
    set x alive
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    dobg {
	    destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
	deleteWindows
} -result {dead 0}
test unixEmbed-3.7a {ContainerEventProc procedure, destroy events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    bind .f1 <Destroy> {set x dead}
    set x alive
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
    interp delete child
    deleteWindows
} -result {dead 0}

test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    dobg {
	    .t1 configure -width 180 -height 100
    }
    update
    dobg {
	    winfo geometry .t1
    }
} -cleanup {
	deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.1a {EmbedStructureProc procedure, configure events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        .t1 configure -width 180 -height 100
        update
        winfo geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} -constraints {
	unix testembed notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    set x [testembed]
    destroy .f1
    update
    list $x [testembed]
} -cleanup {
	deleteWindows
} -result {{{XXX .f1 XXX {}}} {}}
test unixEmbed-4.2a {EmbedStructureProc procedure, destroy events} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    set x [testembed]
    destroy .f1
    list $x [testembed]
} -cleanup {
    interp delete child
    deleteWindows
} -result "{{XXX .f1 {} {}}} {}"


test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    bind .t1 <FocusIn> {lappend x "focus in %W"}
	    bind .t1 <FocusOut> {lappend x "focus out %W"}
	    set x {}
    }
    focus -force .f1
    update
    dobg {set x}
} -cleanup {
	deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.1a {EmbedFocusProc procedure, FocusIn events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
        set x {}
    }
    focus -force .f1
    update
    child eval {set x}
} -cleanup {
    interp delete child
    deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	    after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
	deleteWindows
} -result {}
test unixEmbed-5.2a {EmbedFocusProc procedure, focusing on dead window} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
	    bind .t1 <FocusIn> {lappend x "focus in %W"}
	    bind .t1 <FocusOut> {lappend x "focus out %W"}
	    set x {}
    }
    focus -force .f1
    update
    set x [dobg {update; set x}]
    focus .
    update
    list $x [dobg {update; set x}]
} -cleanup {
	deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}
test unixEmbed-5.3a {EmbedFocusProc procedure, FocusOut events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        set x {}
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
    }
    focus -force .f1
    update
    set x [child eval {update; set x }]
    focus .
    update
    list $x [child eval {update; set x}]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}


test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
            update
	    bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	    set x {}
	    .t1 configure -width 300 -height 120
	    update
	    list $x [winfo geom .t1]
    }
} -cleanup {
	deleteWindows
} -result {{{configure .t1 300 120}} 300x120+0+0}
test unixEmbed-6.1a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
        set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{configure .t1 300 120} 300x120+0+0}
test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
            update
	    bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	    set x {}
	    .t1 configure -width 300 -height 120
            update
	    list $x [winfo geom .t1]
    }
} -cleanup {
	deleteWindows
} -result {{{configure .t1 200 200}} 200x200+0+0}
test unixEmbed-6.2a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
	set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{configure .t1 200 200} 200x200+0+0}

# Can't think up any tests for TkpGetOtherWindow procedure.

test unixEmbed-7.1 {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [dobg {
	    update
	    bind .t1 <Key> {lappend y {key %A}}
	    set y {}
	    event generate .t1 <Key> -keysym a
	    set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
# TkpRedirectKeyEvent is not implemented in win or aqua.  If someone
# implements it they should change the constraints for this test.
test unixEmbed-7.1a {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
    unix notAqua failsOnXQuarz
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym a
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete child
    deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
	unix notAqua
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}
    set y [dobg {
	    update
	    bind .t1 <Key> {lappend y {key %A}}
	    set y {}
	    event generate .t1 <Key> -keysym b
	    set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}
test unixEmbed-7.2a {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1]
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}







|
|

|



|
|

|



|
|

|








|

|
|

|







|


|
|

|






|




|

|












|







|
|

|







|
|
|
|


|

|













|








|
|

|








|


|
|



|

|





|
|
|




|


|













|












|

|





|
|
|
|
|


|













|










|

|









|

|









|











|
|
|



|













|









|

|








|


|

|





|
|
|
|



|


|













|











|

|





|
|
|
|



|


|













|











|

|





|
|



|




|













|










|

|





|
|
|
|



|
|
|


|













|













|

|







|
|



|




|















|












|

|





|
|



|



|


|













|











|

|





|
|







|














|












|

|



>


|
|
|
|
|





|











>


|














|

|



>


|




|





|











>


|












|

|



>


|
|
|
|
|








|











>


|



















|

|





|
|
|
|
|
|
|
|


|













|













|

|





|
|
|
|
|
|
|
|


|














|













|


|

|






|
|





|
|
|
|
|




|

















|




















|

|





|
|







|
|
|
|
|




|














|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
    set vals [winfo rgb $w [format #%02x%02x%02x $red $green $blue]]
    expr ([lindex $vals 0]/256 == $red) && ([lindex $vals 1]/256 == $green) \
	    && ([lindex $vals 2]/256 == $blue)
}

testConstraint pressbutton [llength [info commands pressbutton]]

test unixEmbed-1.1 {Tk_UseWindow procedure, bad window identifier} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t -use xyz
} -returnCodes error -result {expected integer but got "xyz"}
test unixEmbed-1.2 {Tk_UseWindow procedure, bad window identifier} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t -use 47
} -returnCodes error -result {couldn't create child of window "47"}
test unixEmbed-1.3 {Tk_UseWindow procedure, inheriting colormap} -constraints {
    unix nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t -colormap new
    wm geometry .t +0+0
    eatColors .t.t
    frame .t.f -container 1
    toplevel .x -use [winfo id .t.f]
    colorsFree .x
} -cleanup {
    deleteWindows
} -result 0
test unixEmbed-1.4 {Tk_UseWindow procedure, inheriting colormap} -constraints {
    unix nonPortable
} -setup {
    deleteWindows
} -body {
    toplevel .t -container 1 -colormap new
    wm geometry .t +0+0
    eatColors .t2
    toplevel .x -use [winfo id .t]
    colorsFree .x
} -cleanup {
    deleteWindows
} -result 1

test unixEmbed-1.5 {Tk_UseWindow procedure, creating Container records} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t -use $w
	list [testembed] [expr [lindex [lindex [testembed all] 0] 0] - $w]
    }
} -cleanup {
    deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.5a {Tk_UseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    child alias w winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t -use [w]
        list [testembed] [expr {[lindex [lindex [testembed all] 0] 0] - [w]}]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t}} 0}
test unixEmbed-1.6 {Tk_UseWindow procedure, creating Container records} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg "set w2 [winfo id .f2]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	toplevel .t2 -use $w2
	testembed
    }
} -cleanup {
    deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.6a {Tk_UseWindow procedure, creating Container records} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    child alias w1 winfo id .f1
    child alias w2 winfo id .f2
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        toplevel .t2 -use [w2]
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{XXX {} {} .t2} {XXX {} {} .t1}}
test unixEmbed-1.7 {Tk_UseWindow procedure, container and embedded in same app} -constraints {
    unix testembed
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    pack .f1 .f2
    toplevel .t1 -use [winfo id .f1]
    toplevel .t2 -use [winfo id .f2]
    testembed
} -cleanup {
    deleteWindows
} -result {{XXX .f2 {} .t2} {XXX .f1 {} .t1}}

# Can't think of any way to test the procedures Tk_MakeWindow,
# Tk_MakeContainer, or EmbedErrorProc.


test unixEmbed-2.1 {EmbeddedEventProc procedure} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	testembed
    }
    destroy .f1
    update
    dobg {
	testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.1a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        testembed
    }
    destroy .f1
    update
    child eval {
        testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	testembed
	destroy .t1
	testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.2a {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        testembed
        destroy .t1
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-2.3 {EmbeddedEventProc procedure} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    toplevel .t1 -use [winfo id .f1]
    update
    destroy .f1
    testembed
} -result {}
test unixEmbed-2.4 {EmbeddedEventProc procedure} -constraints {
    unix testembed
} -setup {
    deleteWindows
} -body {
    pack [frame .f1 -container 1 -width 200 -height 50]
    toplevel .t1 -use [winfo id .f1]
    set x [testembed]
    update
    destroy .t1
    update
    list $x [winfo exists .t1] [winfo exists .f1] [testembed]
} -cleanup {
    deleteWindows
} -result "{{XXX .f1 {} .t1}} 0 0 {}"


test unixEmbed-3.1 {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed nonPortable
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    set x [testembed]
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
    deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 XXX {}}}}
test unixEmbed-3.1a {ContainerEventProc procedure, detect creation} -constraints {
    unix testembed
} -setup {
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    set x [testembed]
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX .f1 {} {}}} {{XXX .f1 {} {}}}}
test unixEmbed-3.2 {ContainerEventProc procedure, set size on creation} -constraints {
    unix
} -setup {
    deleteWindows
    update
} -body {
    toplevel .t1 -container 1
    wm geometry .t1 +0+0
    toplevel .t2 -use [winfo id .t1] -bg red
    update
    wm geometry .t2
} -cleanup {
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1 -bd 2 -relief raised
	update
	wm geometry .t1 +30+40
    }
    update
    dobg {
        wm geometry .t1
    }
} -cleanup {
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1] -bd 2 -relief raised
        update
        wm geometry .t1 +30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.4 {ContainerEventProc procedure, disallow position changes} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	update
	wm geometry .t1 300x100+30+40
    }
    update
    dobg {
        wm geometry .t1
    }
} -cleanup {
    deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.4a {ContainerEventProc procedure, disallow position changes} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        update
        wm geometry .t1 300x100+30+40
        update
        wm geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {300x100+0+0}
test unixEmbed-3.5 {ContainerEventProc procedure, geometry requests} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	.t1 configure -width 300 -height 80
    }
    update
    list [winfo width .f1] [winfo height .f1] [dobg {wm geometry .t1}]
} -cleanup {
    deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.5a {ContainerEventProc procedure, geometry requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        .t1 configure -width 300 -height 80
        update
    }
    list [winfo width .f1] [winfo height .f1] [child eval {wm geometry .t1}]
} -cleanup {
    interp delete child
    deleteWindows
} -result {300 80 300x80+0+0}
test unixEmbed-3.6 {ContainerEventProc procedure, map requests} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	set x unmapped
	bind .t1 <Map> {set x mapped}
    }
    update
    dobg {
	after 100
	update
	set x
    }
} -cleanup {
    deleteWindows
} -result {mapped}
test unixEmbed-3.6a {ContainerEventProc procedure, map requests} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        set x unmapped
        bind .t1 <Map> {set x mapped}
        update
        after 100
        update
        set x
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {mapped}
test unixEmbed-3.7 {ContainerEventProc procedure, destroy events} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    bind .f1 <Destroy> {set x dead}
    set x alive
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
    deleteWindows
} -result {dead 0}
test unixEmbed-3.7a {ContainerEventProc procedure, destroy events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    bind .f1 <Destroy> {set x dead}
    set x alive
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        update
        destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
    interp delete child
    deleteWindows
} -result {dead 0}

test unixEmbed-4.1 {EmbedStructureProc procedure, configure events} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	.t1 configure -width 180 -height 100
    }
    update
    dobg {
	winfo geometry .t1
    }
} -cleanup {
    deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.1a {EmbedStructureProc procedure, configure events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        update
        .t1 configure -width 180 -height 100
        update
        winfo geometry .t1
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {180x100+0+0}
test unixEmbed-4.2 {EmbedStructureProc procedure, destroy events} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    set x [testembed]
    destroy .f1
    update
    list $x [testembed]
} -cleanup {
    deleteWindows
} -result {{{XXX .f1 XXX {}}} {}}
test unixEmbed-4.2a {EmbedStructureProc procedure, destroy events} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
    }
    set x [testembed]
    destroy .f1
    list $x [testembed]
} -cleanup {
    interp delete child
    deleteWindows
} -result "{{XXX .f1 {} {}}} {}"


test unixEmbed-5.1 {EmbedFocusProc procedure, FocusIn events} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	bind .t1 <FocusIn> {lappend x "focus in %W"}
	bind .t1 <FocusOut> {lappend x "focus out %W"}
	set x {}
    }
    focus -force .f1
    update
    dobg {set x}
} -cleanup {
    deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.1a {EmbedFocusProc procedure, FocusIn events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
        set x {}
    }
    focus -force .f1
    update
    child eval {set x}
} -cleanup {
    interp delete child
    deleteWindows
} -result {{focus in .t1}}
test unixEmbed-5.2 {EmbedFocusProc procedure, focusing on dead window} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-5.2a {EmbedFocusProc procedure, focusing on dead window} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        update
        after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-5.3 {EmbedFocusProc procedure, FocusOut events} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	bind .t1 <FocusIn> {lappend x "focus in %W"}
	bind .t1 <FocusOut> {lappend x "focus out %W"}
	set x {}
    }
    focus -force .f1
    update
    set x [dobg {update; set x}]
    focus .
    update
    list $x [dobg {update; set x}]
} -cleanup {
    deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}
test unixEmbed-5.3a {EmbedFocusProc procedure, FocusOut events} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        set x {}
        bind .t1 <FocusIn> {lappend x "focus in %W"}
        bind .t1 <FocusOut> {lappend x "focus out %W"}
        update
    }
    focus -force .f1
    update
    set x [child eval {update; set x }]
    focus .
    update
    list $x [child eval {update; set x}]
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{focus in .t1}} {{focus in .t1} {focus out .t1}}}


test unixEmbed-6.1 {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	update
	bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	set x {}
	.t1 configure -width 300 -height 120
	update
	list $x [winfo geom .t1]
    }
} -cleanup {
    deleteWindows
} -result {{{configure .t1 300 120}} 300x120+0+0}
test unixEmbed-6.1a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
        set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{configure .t1 300 120} 300x120+0+0}
test unixEmbed-6.2 {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	update
	bind .t1 <Configure> {lappend x {configure .t1 %w %h}}
	set x {}
	.t1 configure -width 300 -height 120
	update
	list $x [winfo geom .t1]
    }
} -cleanup {
    deleteWindows
} -result {{{configure .t1 200 200}} 200x200+0+0}
test unixEmbed-6.2a {EmbedGeometryRequest procedure, window changes size} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    place .f1 -width 200 -height 200
    update
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        update
        bind .t1 <Configure> {set x {configure .t1 %w %h}}
	set x {}
        .t1 configure -width 300 -height 120
        update
        list $x [winfo geom .t1]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{configure .t1 200 200} 200x200+0+0}

# Can't think up any tests for Tk_GetOtherWindow procedure.

test unixEmbed-7.1 {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [dobg {
	update
	bind .t1 <Key> {lappend y {key %A}}
	set y {}
	event generate .t1 <Key> -keysym a
	set y
    }]
    update
    list $x $y
} -cleanup {
    deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
# TkpRedirectKeyEvent is not implemented in win or aqua.  If someone
# implements it they should change the constraints for this test.
test unixEmbed-7.1a {TkpRedirectKeyEvent procedure, forward keystroke} -constraints {
    unix notAqua failsOnXQuarz
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    deleteWindows
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    set x {}
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym a
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete child
    deleteWindows
    bind . <Key> {}
} -result {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
    unix notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}
    set y [dobg {
	update
	bind .t1 <Key> {lappend y {key %A}}
	set y {}
	event generate .t1 <Key> -keysym b
	set y
    }]
    update
    list $x $y
} -cleanup {
    deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}
test unixEmbed-7.2a {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
    unix
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    set x {}
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
    deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}

test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints {
    unix notAqua failsOnUbuntu failsOnXQuarz
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
    }
    focus -force .f2
    update
    list [dobg {
	    focus .t1
	    set x [list [focus]]
	    update
	    after 500
	    update
	    lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
} -result {{{} .t1} .f1}
test unixEmbed-8.1a {TkpClaimFocus procedure} -constraints unix -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
    }
    # This should clear focus from the application embedded in .f1
    focus -force .f2
    update
    list [child eval {
        set x [list [focus]]







|






|
|




|
|
|
|
|
|


|













|







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
    deleteWindows
    bind . <Key> {}
} -result {{} {{key b}}}

test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints {
    unix notAqua failsOnUbuntu failsOnXQuarz
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
    }
    focus -force .f2
    update
    list [dobg {
	focus .t1
	set x [list [focus]]
	update
	after 500
	update
	lappend x [focus]
    }] [focus]
} -cleanup {
    deleteWindows
} -result {{{} .t1} .f1}
test unixEmbed-8.1a {TkpClaimFocus procedure} -constraints unix -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    update
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
    }
    # This should clear focus from the application embedded in .f1
    focus -force .f2
    update
    list [child eval {
        set x [list [focus]]
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291

1292
1293

1294


1295
1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309

1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    update
    set w1 [winfo id .f1]
    child eval "set argv {-use [winfo id .f1]}"
    load {} Tk child
    child eval {
	    . configure -bd 2 -highlightthickness 2 -relief sunken
    }
    focus -force .f2
    update
    list [child eval {
	    focus .
	    set x [list [focus]]
	    update
	    lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
} -result {{{} .} .f1}
catch {interp delete child}

test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} -constraints {
	unix testembed
} -setup {
	deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    frame .f3 -container 1 -width 200 -height 50
    frame .f4 -container 1 -width 200 -height 50
    pack .f1 .f2 .f3 .f4
    set x {}
    lappend x [testembed]
    foreach w {.f3 .f4 .f1 .f2} {
	    destroy $w
	    lappend x [testembed]
    }
    set x
} -cleanup {
	deleteWindows
} -result {{{XXX .f4 {} {}} {XXX .f3 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f4 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}}} {}}
test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	    eval destroy [winfo child .]
	    toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
	    set x {}
	    lappend x [testembed]
	    destroy .t1
	    lappend x [testembed]
    }
} -cleanup {
	deleteWindows
} -result {{{XXX {} {} .t1}} {}}
test unixEmbed-9.2a {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
        set x {}
        lappend x [testembed]
        destroy .t1
        lappend x [testembed]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t1}} {}}


test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix failsOnUbuntu failsOnXQuarz
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update idletasks
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update idletasks
    wm geometry .t1 +40+50
    update idletasks
    wm geometry .t1
} -cleanup {
	deleteWindows
} -result {150x80+0+0}
test unixEmbed-10.2 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix failsOnUbuntu failsOnXQuarz
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update idletasks
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update idletasks
    wm geometry .t1 70x300+10+20
    update idletasks
    wm geometry .t1
} -cleanup {
	deleteWindows
} -result {70x300+0+0}

test unixEmbed-11.1 {focus -force works for embedded toplevels} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t
    pack [frame .t.f -container 1 -width 200 -height 200] -fill both
    update idletasks
    toplevel .embed -use [winfo id .t.f] -bg green
    update idletasks
    focus -force .t
    focus -force .embed
    focus
} -cleanup {
    deleteWindows
} -result .embed
test unixEmbed-11.2 {mouse coordinates in embedded toplevels} -constraints {
    unix pressbutton
} -setup {
    deleteWindows
} -body {

    toplevel .main
    set result {}

    pack [button .main.b -text "Main Button" \


	      -command {lappend result ".main.b"}] -padx 30 -pady 30
    pack [frame .main.f -container 1 -width 200 -height 200] -fill both
    update idletasks
    toplevel .embed -use [winfo id .main.f] -bg green
    pack [button .embed.b -text "Emb Button" \
	      -command {lappend result ".embed.b"}] -padx 30 -pady 30
    wm geometry .main 200x400+100+100
    update idletasks
    focus -force .main

    set x [expr {[winfo x .main ] + [winfo x .main.b] + 40}]
    set y [expr {[winfo y .main ] + [winfo y .main.b] + 38}]
    lappend result [winfo containing $x $y]
    after 200
    pressbutton $x $y
    update

    set y [expr {$y + 80}]
    lappend result [winfo containing $x $y]
    after 200
    pressbutton $x $y
    update
    set result
} -cleanup {
    deleteWindows
} -result {.main.b .main.b .embed.b .embed.b}


# cleanup
deleteWindows
cleanupbg
cleanupTests
return







|




|
|
|
|


|




|

|









|
|



|











|
|
|
|
|
|


|













|













|





<

|

|


|


|





|

|

|


|









|

|











>

|
>
|
>
>
|
<
|

|
|
<
|

>
|
|

<


>
|

<





|







1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304

1305
1306
1307
1308

1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319

1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
    frame .f2 -width 200 -height 50
    pack .f1 .f2
    update
    set w1 [winfo id .f1]
    child eval "set argv {-use [winfo id .f1]}"
    load {} Tk child
    child eval {
	. configure -bd 2 -highlightthickness 2 -relief sunken
    }
    focus -force .f2
    update
    list [child eval {
	focus .
	set x [list [focus]]
	update
	lappend x [focus]
    }] [focus]
} -cleanup {
    deleteWindows
} -result {{{} .} .f1}
catch {interp delete child}

test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} -constraints {
    unix testembed
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    frame .f2 -container 1 -width 200 -height 50
    frame .f3 -container 1 -width 200 -height 50
    frame .f4 -container 1 -width 200 -height 50
    pack .f1 .f2 .f3 .f4
    set x {}
    lappend x [testembed]
    foreach w {.f3 .f4 .f1 .f2} {
	destroy $w
	lappend x [testembed]
    }
    set x
} -cleanup {
    deleteWindows
} -result {{{XXX .f4 {} {}} {XXX .f3 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f4 {} {}} {XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}} {XXX .f1 {} {}}} {{XXX .f2 {} {}}} {}}
test unixEmbed-9.2 {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed notAqua
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
	set x {}
	lappend x [testembed]
	destroy .t1
	lappend x [testembed]
    }
} -cleanup {
    deleteWindows
} -result {{{XXX {} {} .t1}} {}}
test unixEmbed-9.2a {EmbedWindowDeleted procedure, check embeddedPtr} -constraints {
    unix testembed
} -setup {
    deleteWindows
    catch {interp delete child}
    ::_test_tmp::testInterp child
    load {} Tktest child
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    child alias w1 winfo id .f1
    child eval {
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1] -highlightthickness 2 -bd 2 -relief sunken
        set x {}
        lappend x [testembed]
        destroy .t1
        lappend x [testembed]
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {{{XXX {} {} .t1}} {}}


test unixEmbed-10.1 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1

    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update
    wm geometry .t1 +40+50
    update
    wm geometry .t1
} -cleanup {
    deleteWindows
} -result {150x80+0+0}
test unixEmbed-10.2 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update
    wm geometry .t1 70x300+10+20
    update
    wm geometry .t1
} -cleanup {
    deleteWindows
} -result {70x300+0+0}

test unixEmbed-11.1 {focus -force works for embedded toplevels} -constraints {
    unix
} -setup {
    deleteWindows
} -body {
    toplevel .t
    pack [frame .t.f -container 1 -width 200 -height 200] -fill both
    update
    toplevel .embed -use [winfo id .t.f] -bg green
    update
    focus -force .t
    focus -force .embed
    focus
} -cleanup {
    deleteWindows
} -result .embed
test unixEmbed-11.2 {mouse coordinates in embedded toplevels} -constraints {
    unix pressbutton
} -setup {
    deleteWindows
} -body {
    set result {}
    toplevel .main
    update
    frame .main.f -container 1 -width 200 -height 200
    button .main.b -text "Main Button" -command {lappend result "pushed .main.b"}
    wm geometry .main 200x400+100+100
    pack .main.f -fill both
    pack .main.b -padx 30 -pady 30

    update
    toplevel .embed -use [winfo id .main.f] -bg green
    button .embed.b -text "Emb Button" -command {lappend result "pushed .embed.b"}
    pack .embed.b -padx 30 -pady 30

    update
    focus -force .main
    update
    set x [expr {[winfo rootx .main.b] + [winfo width .main.b]/2}]
    set y [expr {[winfo rooty .main.b] + [winfo height .main.b]/2}]
    lappend result [winfo containing $x $y]

    pressbutton $x $y
    update
    set x [expr {[winfo rootx .embed.b] + [winfo width .embed.b]/2}]
    set y [expr {[winfo rooty .embed.b] + [winfo height .embed.b]/2}]
    lappend result [winfo containing $x $y]

    pressbutton $x $y
    update
    set result
} -cleanup {
    deleteWindows
} -result {.main.b {pushed .main.b} .embed.b {pushed .embed.b}}


# cleanup
deleteWindows
cleanupbg
cleanupTests
return

Changes to tests/unixFont.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# This file is a Tcl script to test out the procedures in tkUnixFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.  Some tests depend on the
# fonts having or not having certain properties, which may not be valid
# at all sites.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnUbuntuNoXft [expr {[testConstraint failsOnUbuntu] || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

if {[tk windowingsystem] eq "x11"} {
    set xlsf [auto_execok xlsfonts]
}
foreach {constraint font} {
    hasArial	arial











|






|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
# This file is a Tcl script to test out the procedures in tkUnixFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.  Some tests depend on the
# fonts having or not having certain properties, which may not be valid
# at all sites.
#
# Copyright © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

testConstraint 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
} {}
test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} {x11 failsOnUbuntu} {
    lindex [font actual {-family fixed -size 31}] 1
} {fixed}
test unixfont-2.9 {TkpGetFontFromAttributes: reject adobe courier if possible} {x11 noExceed failsOnUbuntu} {
    lindex [font actual {-family courier}] 1
} {courier}
test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} {x11 failsOnUbuntuNoXft} {
    lindex [font actual {-family courier -size 37}] 3
} 37
test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} x11 {
    # On Linux, XListFonts() was returning names for fonts that do not
    # actually exist, causing the subsequent XLoadQueryFont() to fail
    # unexpectedly.  Now falls back to another font if that happens.








|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
} {}
test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} {x11 failsOnUbuntu} {
    lindex [font actual {-family fixed -size 31}] 1
} {fixed}
test unixfont-2.9 {TkpGetFontFromAttributes: reject adobe courier if possible} {x11 noExceed failsOnUbuntu} {
    lindex [font actual {-family courier}] 1
} {courier}
test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} {x11 haveCourier37Font} {
    lindex [font actual {-family courier -size 37}] 3
} 37
test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} x11 {
    # On Linux, XListFonts() was returning names for fonts that do not
    # actually exist, causing the subsequent XLoadQueryFont() to fail
    # unexpectedly.  Now falls back to another font if that happens.

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
test unixfont-7.3 {DrawChars procedure: overstrike} x11 {
    set f [.b.l cget -font]
    .b.l config -text "abc" -font "courier 10 overstrike"
    update
    .b.l config -font $f
} {}

test unixfont-8.1 {AllocFont procedure: use old font} x11 {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} {}
test unixfont-8.2 {AllocFont procedure: parse information from XLFD} x11 {
    expr {[lindex [font actual {-family times -size 0}] 3] == 0}
} 0
test unixfont-8.3 {AllocFont procedure: can't parse info from name} x11 {
    catch {unset fontArray}
    # check that font actual returns the correct attributes.
    # the values of those attributes are system dependent.
    array set fontArray [font actual a12biluc]
    set result [lsort [array names fontArray]]
    catch {unset fontArray}
    set result
} {-family -overstrike -size -slant -underline -weight}
test unixfont-8.4 {AllocFont procedure: classify characters} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "䀀"]   ;# 6
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    incr x [font measure $courier "\101"]   ;# 1
    set x
} [expr $cx*13]
test unixfont-8.5 {AllocFont procedure: setup widths of normal chars} x11 {
    font metrics $courier -fixed
} 1
test unixfont-8.6 {AllocFont procedure: setup widths of special chars} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "\001"]   ;# 4
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    set x
} [expr $cx*10]
test unixfont-8.7 {AllocFont procedure: XA_UNDERLINE_POSITION} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.8 {AllocFont procedure: no XA_UNDERLINE_POSITION} x11 {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.9 {AllocFont procedure: XA_UNDERLINE_THICKNESS} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.10 {AllocFont procedure: no XA_UNDERLINE_THICKNESS} x11 {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.11 {AllocFont procedure: XA_UNDERLINE_POSITION was 0} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}

test unixfont-9.1 {GetControlCharSubst procedure: 2 chars subst} {x11 failsOnUbuntu failsOnXQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\a0"







|







|


|








|







|


|






|



|



|



|



|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
test unixfont-7.3 {DrawChars procedure: overstrike} x11 {
    set f [.b.l cget -font]
    .b.l config -text "abc" -font "courier 10 overstrike"
    update
    .b.l config -font $f
} {}

test unixfont-8.1 {InitFont procedure: use old font} x11 {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} {}
test unixfont-8.2 {InitFont procedure: parse information from XLFD} x11 {
    expr {[lindex [font actual {-family times -size 0}] 3] == 0}
} 0
test unixfont-8.3 {InitFont procedure: can't parse info from name} x11 {
    catch {unset fontArray}
    # check that font actual returns the correct attributes.
    # the values of those attributes are system dependent.
    array set fontArray [font actual a12biluc]
    set result [lsort [array names fontArray]]
    catch {unset fontArray}
    set result
} {-family -overstrike -size -slant -underline -weight}
test unixfont-8.4 {InitFont procedure: classify characters} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "䀀"]   ;# 6
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    incr x [font measure $courier "\101"]   ;# 1
    set x
} [expr $cx*13]
test unixfont-8.5 {InitFont procedure: setup widths of normal chars} x11 {
    font metrics $courier -fixed
} 1
test unixfont-8.6 {InitFont procedure: setup widths of special chars} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "\001"]   ;# 4
    incr x [font measure $courier "\002"]   ;# 4
    incr x [font measure $courier "\012"]   ;# 2
    set x
} [expr $cx*10]
test unixfont-8.7 {InitFont procedure: XA_UNDERLINE_POSITION} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.8 {InitFont procedure: no XA_UNDERLINE_POSITION} x11 {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.9 {InitFont procedure: XA_UNDERLINE_THICKNESS} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}
test unixfont-8.10 {InitFont procedure: no XA_UNDERLINE_THICKNESS} x11 {
    catch {font actual --symbol-medium-r-normal--0-0-0-0-p-0-sun-fontspecific}
    set x {}
} {}
test unixfont-8.11 {InitFont procedure: XA_UNDERLINE_POSITION was 0} x11 {
    catch {font actual -adobe-courier-bold-i-normal--0-0-0-0-m-0-iso8859-1}
    set x {}
} {}

test unixfont-9.1 {GetControlCharSubst procedure: 2 chars subst} {x11 failsOnUbuntu failsOnXQuarz} {
    .b.c dchars $t 0 end
    .b.c insert $t 0 "0\a0"

Changes to tests/unixMenu.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
} -body {
    menu .m1
    .m1 add cascade -label foo
    list [. configure -menu .m1] [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {{} {} {}}


test unixMenu-7.1 {TkpSetMainMenubar - nothing to do} -constraints unix -body {}


test unixMenu-8.1 {GetMenuIndicatorGeometry - indicator off} -constraints {
    unix
} -setup {
    destroy .m1
} -body {







|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
} -body {
    menu .m1
    .m1 add cascade -label foo
    list [. configure -menu .m1] [. configure -menu ""] [destroy .m1]
} -returnCodes ok -result {{} {} {}}


test unixMenu-7.1 {Tk_SetMainMenubar - nothing to do} -constraints unix -body {}


test unixMenu-8.1 {GetMenuIndicatorGeometry - indicator off} -constraints {
    unix
} -setup {
    destroy .m1
} -body {

Changes to tests/unixSelect.test.

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 © 1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv






|







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 © 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

Changes to tests/unixWm.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17












18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42

43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
# This file is a Tcl script to test out Tk's interactions with
# the window manager, including the "wm" command.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

namespace import -force ::tk::test:loadTkCommand

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]













proc sleep ms {
    global x
    after $ms {set x 1}
    vwait x
}

# Procedure to set up a collection of top-level windows

proc makeToplevels {} {
    deleteWindows
    foreach i {.raise1 .raise2 .raise3} {
	toplevel $i
	wm geom $i 150x100+0+0
	update
    }
}

# On macOS windows are not allowed to overlap the menubar at the top
# of the screen.  So tests which move a window and then check whether
# it got moved to the requested location should use a y coordinate
# larger than the height of the menubar (normally 23 pixels).


if {[tk windowingsystem] eq "aqua"} {
    set mb [expr [menubarheight] + 1]

    set Y0 $mb
    set Y2 [expr $mb + 2]
    set Y5 [expr $mb + 5]
} else {

    set Y0 0
    set Y2 2
    set Y5 5
}

set i 1
foreach geom "+$Y0+80 +80+$Y0 +0+$Y0" {
    destroy .t
    test unixWm-1.$i {initial window position} unix {
	toplevel .t -width 200 -height 150
	wm geom .t $geom
	update
	wm geom .t
    } 200x150$geom






|








|

>
>
>
>
>
>
>
>
>
>
>
>


















|
|
|
|
>



>




>






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# This file is a Tcl script to test out Tk's interactions with
# the window manager, including the "wm" command.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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" }]

# Starting with macOS Ventura it became necessary to wait for windows to be restacked
# or to be raised after creation.

if {[tk windowingsystem] eq "aqua"} {
    proc restackDelay {} {
	after 200;
	update idletasks
    }
} else {
    proc restackDelay {} {}
}

proc sleep ms {
    global x
    after $ms {set x 1}
    vwait x
}

# Procedure to set up a collection of top-level windows

proc makeToplevels {} {
    deleteWindows
    foreach i {.raise1 .raise2 .raise3} {
	toplevel $i
	wm geom $i 150x100+0+0
	update
    }
}

# On macOS windows are not allowed to overlap the menubar at the top of the
# screen or the dock.  So tests which move a window and then check whether it
# got moved to the requested location should use a y coordinate larger than the
# height of the menubar (normally 23 pixels) and an x coordinate larger than the
# width of the dock, if it happens to be on the left.

if {[tk windowingsystem] eq "aqua"} {
    set mb [expr [menubarheight] + 1]
    set X  100
    set Y0 $mb
    set Y2 [expr $mb + 2]
    set Y5 [expr $mb + 5]
} else {
    set X  20
    set Y0 0
    set Y2 2
    set Y5 5
}

set i 1
foreach geom "+$X+80 +80+$Y0 +$X+$Y0" {
    destroy .t
    test unixWm-1.$i {initial window position} unix {
	toplevel .t -width 200 -height 150
	wm geom .t $geom
	update
	wm geom .t
    } 200x150$geom
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom "+20+80 +100+40 +0+$Y0" {
    test unixWm-4.$i {moving window while withdrawn} unix {
	wm withdraw .t
	update idletasks
	wm geom .t $geom
	update idletasks
	wm deiconify .t
	update idletasks
	wm geom .t
    } 100x150$geom
    incr i
}

test unixWm-5.1 {compounded state changes} {unix nonPortable} {
    destroy .t







|


|



|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
	format "%s%d%s%d" $xsign [eval expr $x$xsign$xerr] $ysign \
		[eval expr $y$ysign$yerr]
    } $geom
    incr i
}

set i 1
foreach geom "+$X+80 +$X+40 +$X+$Y0" {
    test unixWm-4.$i {moving window while withdrawn} unix {
	wm withdraw .t
	sleep 10
	wm geom .t $geom
	update idletasks
	wm deiconify .t
	sleep 10
	wm geom .t
    } 100x150$geom
    incr i
}

test unixWm-5.1 {compounded state changes} {unix nonPortable} {
    destroy .t
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    wm withdraw .t
    wm iconify .t
    list [winfo ismapped .t] [wm state .t]
} {0 iconic}

destroy .t
toplevel .t -width 200 -height 100
wm geom .t +10+$Y0
wm minsize .t 1 1
update
test unixWm-6.1 {size changes} unix {
    .t config -width 180 -height 150
    update
    wm geom .t
} 180x150+10+$Y0
test unixWm-6.2 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    update
    wm geom .t
} 250x60+10+$Y0
test unixWm-6.3 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    wm geom .t {}
    update
    wm geom .t
} 170x140+10+$Y0
test unixWm-6.4 {size changes} {unix nonPortable userInteraction} {
    wm minsize .t 1 1
    update
    puts stdout "Please resize window \"t\" with the mouse (but don't move it!),"
    puts -nonewline stdout "then hit return: "
    flush stdout
    gets stdin







|






|





|






|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
    wm withdraw .t
    wm iconify .t
    list [winfo ismapped .t] [wm state .t]
} {0 iconic}

destroy .t
toplevel .t -width 200 -height 100
wm geom .t +100+$Y0
wm minsize .t 1 1
update
test unixWm-6.1 {size changes} unix {
    .t config -width 180 -height 150
    update
    wm geom .t
} 180x150+100+$Y0
test unixWm-6.2 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    update
    wm geom .t
} 250x60+100+$Y0
test unixWm-6.3 {size changes} unix {
    wm geom .t 250x60
    .t config -width 170 -height 140
    wm geom .t {}
    update
    wm geom .t
} 170x140+100+$Y0
test unixWm-6.4 {size changes} {unix nonPortable userInteraction} {
    wm minsize .t 1 1
    update
    puts stdout "Please resize window \"t\" with the mouse (but don't move it!),"
    puts -nonewline stdout "then hit return: "
    flush stdout
    gets stdin
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    set w2 [winfo width .t]
    set h2 [winfo height .t]
    .t config -width 114 -height 261
    update
    list $width $height $w2 $h2 [wm geom .t]
} {0 0 230 110 114x261+10+10}

# I don't know why the wait below is needed, but without it the test
# fails under twm.
sleep 200

test unixWm-6.5 {window initially iconic} {unix nonPortable} {
    destroy .t
    toplevel .t -width 100 -height 30
    wm geometry .t +0+0
    wm title .t 2
    wm iconify .t
    update idletasks







<
<
<
<







243
244
245
246
247
248
249




250
251
252
253
254
255
256
    set w2 [winfo width .t]
    set h2 [winfo height .t]
    .t config -width 114 -height 261
    update
    list $width $height $w2 $h2 [wm geom .t]
} {0 0 230 110 114x261+10+10}





test unixWm-6.5 {window initially iconic} {unix nonPortable} {
    destroy .t
    toplevel .t -width 100 -height 30
    wm geometry .t +0+0
    wm title .t 2
    wm iconify .t
    update idletasks
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
    list [catch {wm iconwindow} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}
test unixWm-8.3 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t b c} msg] $msg
} {1 {wrong # args: should be "wm iconwindow window ?pathName?"}}
test unixWm-8.4 {icon windows} {unix failsOnUbuntu} {
    destroy .t
    destroy .icon
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    update idletasks
    set result [wm iconwindow .t]
    toplevel .icon -width 50 -height 50 -bg red







|







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
    list [catch {wm iconwindow} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}
test unixWm-8.3 {icon windows} unix {
    destroy .t
    toplevel .t -width 100 -height 30
    list [catch {wm iconwindow .t b c} msg] $msg
} {1 {wrong # args: should be "wm iconwindow window ?pathName?"}}
test unixWm-8.4 {icon windows} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t
    destroy .icon
    toplevel .t -width 100 -height 30
    wm geom .t +0+0
    update idletasks
    set result [wm iconwindow .t]
    toplevel .icon -width 50 -height 50 -bg red
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
    destroy .icon
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    set result [list [catch {wm deiconify .icon} msg] $msg]
    destroy .icon
    set result
} {1 {can't deiconify .icon: it is an icon for .t}}
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} {unix failsOnUbuntu} {
    wm iconify .t
    set result {}
    lappend result [winfo ismapped .t] [wm state .t]
    wm deiconify .t
    lappend result [winfo ismapped .t] [wm state .t]
} {0 iconic 1 normal}








|







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
    destroy .icon
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    set result [list [catch {wm deiconify .icon} msg] $msg]
    destroy .icon
    set result
} {1 {can't deiconify .icon: it is an icon for .t}}
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} {unix failsOnUbuntu failsOnXQuarz} {
    wm iconify .t
    set result {}
    lappend result [winfo ismapped .t] [wm state .t]
    wm deiconify .t
    lappend result [winfo ismapped .t] [wm state .t]
} {0 iconic 1 normal}

811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
    wm iconbitmap .t {}
    set bit [format 0x%x [expr 0x4 & [lindex [testprop [testwrapper .t] \
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
} {{} questhead 0x4 {} 0x0}
if {[tk windowingsystem] == "aqua"} {
    set result_22_3 {0 {}}
} else {
    set result_22_3 {1 {bitmap "bad-bitmap" not defined}}
}
test unixWm-22.3 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \
unix {
    list [catch {wm iconbitmap .t bad-bitmap} msg] $msg







|







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
    wm iconbitmap .t {}
    set bit [format 0x%x [expr 0x4 & [lindex [testprop [testwrapper .t] \
	    WM_HINTS] 0]]]
    lappend result [wm iconbitmap .t] $bit
} {{} questhead 0x4 {} 0x0}
if {[tk windowingsystem] eq "aqua"} {
    set result_22_3 {0 {}}
} else {
    set result_22_3 {1 {bitmap "bad-bitmap" not defined}}
}
test unixWm-22.3 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \
unix {
    list [catch {wm iconbitmap .t bad-bitmap} msg] $msg
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
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify ".t2": it is an icon for ".t"}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    update idletasks
    wm iconify .t2
    update idletasks
    set result [winfo ismapped .t2]
    destroy .t2
    set result
} 0
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu} {
    destroy .t2
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks







|










|







861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify ".t2": it is an icon for ".t"}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t2
    toplevel .t2
    wm geom .t2 +0+0
    update idletasks
    wm iconify .t2
    update idletasks
    set result [winfo ismapped .t2]
    destroy .t2
    set result
} 0
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t2
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
} {{} questhead 0x20 {} 0x0}
test unixWm-24.3 {Tk_WmCmd procedure, "iconmask" option} unix {
    list [catch {wm iconmask .t bogus} msg] $msg
} {1 {bitmap "bogus" not defined}}

test unixWm-25.1 {Tk_WmCmd procedure, "iconname" option} unix {
    list [catch {wm icon .t} msg] $msg
} {1 {ambiguous option "icon": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}}
test unixWm-25.2 {Tk_WmCmd procedure, "iconname" option} unix {
    list [catch {wm iconname .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm iconname window ?newName?"}}
test unixWm-25.3 {Tk_WmCmd procedure, "iconname" option} {unix testwrapper} {
    set result {}
    lappend result [wm iconname .t]
    wm iconname .t test_name







|







906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
} {{} questhead 0x20 {} 0x0}
test unixWm-24.3 {Tk_WmCmd procedure, "iconmask" option} unix {
    list [catch {wm iconmask .t bogus} msg] $msg
} {1 {bitmap "bogus" not defined}}

test unixWm-25.1 {Tk_WmCmd procedure, "iconname" option} unix {
    list [catch {wm icon .t} msg] $msg
} {1 {ambiguous option "icon": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbadge, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}}
test unixWm-25.2 {Tk_WmCmd procedure, "iconname" option} unix {
    list [catch {wm iconname .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm iconname window ?newName?"}}
test unixWm-25.3 {Tk_WmCmd procedure, "iconname" option} {unix testwrapper} {
    set result {}
    lappend result [wm iconname .t]
    wm iconname .t test_name
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
    set bit [format 0x%x [expr 0xa & [lindex [testprop [testwrapper .t] \
	    WM_NORMAL_HINTS] 0]]]
    lappend result [wm sizefrom .t] $bit
} {{} program 0x8 user 0x2}
test unixWm-34.3 {Tk_WmCmd procedure, "sizefrom" option} unix {
    list [catch {wm sizefrom .t none} msg]  $msg
} {1 {bad argument "none": must be program or user}}
if {[tk windowingsystem] == "aqua"} {
    set result_35_1 {1 {bad argument "1": must be normal, iconic, withdrawn, or zoomed}}
} else {
    set result_35_1 {1 {bad argument "1": must be normal, iconic, or withdrawn}}
}
test unixWm-35.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} {
    list [catch {wm state .t 1} msg]  $msg
} $result_35_1
test unixWm-35.2 {Tk_WmCmd procedure, "state" option} unix {
    list [catch {wm state .t iconic 1} msg]  $msg
} {1 {wrong # args: should be "wm state window ?state?"}}







|
|

|







1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
    set bit [format 0x%x [expr 0xa & [lindex [testprop [testwrapper .t] \
	    WM_NORMAL_HINTS] 0]]]
    lappend result [wm sizefrom .t] $bit
} {{} program 0x8 user 0x2}
test unixWm-34.3 {Tk_WmCmd procedure, "sizefrom" option} unix {
    list [catch {wm sizefrom .t none} msg]  $msg
} {1 {bad argument "none": must be program or user}}
if {[tk windowingsystem] eq "aqua"} {
    set result_35_1 {1 {bad argument "1": must be iconic, normal, withdrawn, or zoomed}}
} else {
    set result_35_1 {1 {bad argument "1": must be iconic, normal, or withdrawn}}
}
test unixWm-35.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} {
    list [catch {wm state .t 1} msg]  $msg
} $result_35_1
test unixWm-35.2 {Tk_WmCmd procedure, "state" option} unix {
    list [catch {wm state .t iconic 1} msg]  $msg
} {1 {wrong # args: should be "wm state window ?state?"}}
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
    lappend result [wm state .t] [winfo ismapped .t]
    wm deiconify .t
    lappend result [wm state .t] [winfo ismapped .t]
} {withdrawn 0 normal 1}

test unixWm-39.1 {Tk_WmCmd procedure, miscellaneous} unix {
    list [catch {wm unknown .t} msg] $msg
} {1 {bad option "unknown": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}}

destroy .t .icon

test unixWm-40.1 {Tk_SetGrid procedure, set grid dimensions before turning on grid} {unix nonPortable} {
    destroy .t
    toplevel .t
    wm geometry .t 30x10+0+0
    listbox .t.l -height 20 -width 20 -setgrid 1
    pack .t.l -fill both -expand 1
    update
    wm geometry .t
} {30x10+0+0}
test unixWm-40.2 {Tk_SetGrid procedure, turning on grid when dimensions already set} unix {
    destroy .t
    toplevel .t
    wm geometry .t 200x100+0+$Y0
    listbox .t.l -height 20 -width 20
    pack .t.l -fill both -expand 1
    update
    .t.l configure -setgrid 1
    update
    wm geometry .t
} "20x20+0+$Y0"

test unixWm-41.1 {ConfigureEvent procedure, internally generated size changes} unix {
    destroy .t
    toplevel .t -width 400 -height 150
    tkwait visibility .t
    wm geometry .t +0+0
    update idletasks







|















|






|







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
    lappend result [wm state .t] [winfo ismapped .t]
    wm deiconify .t
    lappend result [wm state .t] [winfo ismapped .t]
} {withdrawn 0 normal 1}

test unixWm-39.1 {Tk_WmCmd procedure, miscellaneous} unix {
    list [catch {wm unknown .t} msg] $msg
} {1 {bad option "unknown": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbadge, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}}

destroy .t .icon

test unixWm-40.1 {Tk_SetGrid procedure, set grid dimensions before turning on grid} {unix nonPortable} {
    destroy .t
    toplevel .t
    wm geometry .t 30x10+0+0
    listbox .t.l -height 20 -width 20 -setgrid 1
    pack .t.l -fill both -expand 1
    update
    wm geometry .t
} {30x10+0+0}
test unixWm-40.2 {Tk_SetGrid procedure, turning on grid when dimensions already set} unix {
    destroy .t
    toplevel .t
    wm geometry .t 200x100+100+$Y0
    listbox .t.l -height 20 -width 20
    pack .t.l -fill both -expand 1
    update
    .t.l configure -setgrid 1
    update
    wm geometry .t
} "20x20+100+$Y0"

test unixWm-41.1 {ConfigureEvent procedure, internally generated size changes} unix {
    destroy .t
    toplevel .t -width 400 -height 150
    tkwait visibility .t
    wm geometry .t +0+0
    update idletasks
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
    update
    set result
} {configured: 130 200}

# No tests for ReparentEvent or ComputeReparentGeometry; I can't figure
# out how to exercise these procedures reliably.

test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} {unix failsOnUbuntu} {
    destroy .t
    toplevel .t -width 400 -height 150
    wm geometry .t +0+0
    tkwait visibility .t
    set result {}
    bind .t <Map> {set x "mapped"}
    bind .t <Unmap> {set x "unmapped"}







|







1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
    update
    set result
} {configured: 130 200}

# No tests for ReparentEvent or ComputeReparentGeometry; I can't figure
# out how to exercise these procedures reliably.

test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 400 -height 150
    wm geometry .t +0+0
    tkwait visibility .t
    set result {}
    bind .t <Map> {set x "mapped"}
    bind .t <Unmap> {set x "unmapped"}
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

1559
1560
1561
1562
1563
1564
1565
1566
1567
1568

1569
1570
1571
1572
1573
1574
1575
    tkwait visibility .t
    wm geometry .t 20x1
    update
    list [winfo width .t] [winfo height .t]
} {100 1}
destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.7 {UpdateGeometryInfo procedure, computing position} {unix failsOnXQuarz} {
    tkwait visibility .t
    wm overrideredirect .t 1

    update
    wm geometry .t +5-10
    update
    list [winfo x .t] [winfo y .t]
} [list 5 [expr [winfo screenheight .t] - 70]]
destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} {unix failsOnXQuarz} {
    tkwait visibility .t
    wm overrideredirect .t 1

    update
    wm geometry .t -30+$Y2
    update
    list [winfo x .t] [winfo y .t]
} [list [expr [winfo screenwidth .t] - 110] $Y2]
destroy .t








|
<

>







|
<

>







1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581
1582
1583
1584
1585
1586
    tkwait visibility .t
    wm geometry .t 20x1
    update
    list [winfo width .t] [winfo height .t]
} {100 1}
destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.7 {UpdateGeometryInfo procedure, computing position} {unix} {

    wm overrideredirect .t 1
    tkwait visibility .t
    update
    wm geometry .t +5-10
    update
    list [winfo x .t] [winfo y .t]
} [list 5 [expr [winfo screenheight .t] - 70]]
destroy .t
toplevel .t -width 80 -height 60
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} {unix} {

    wm overrideredirect .t 1
    tkwait visibility .t
    update
    wm geometry .t -30+$Y2
    update
    list [winfo x .t] [winfo y .t]
} [list [expr [winfo screenwidth .t] - 110] $Y2]
destroy .t

1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {40 30 320 210 10 5}
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm minsize .t 30 40
    wm maxsize .t 200 500
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]







|







1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {40 30 320 210 10 5}
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper} {
    destroy .t
    toplevel .t -width 80 -height 60
    wm minsize .t 30 40
    wm maxsize .t 200 500
    wm geometry .t +0+0
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [winfo height .t] \
	    [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {60 40 53 320 233 10 5}
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper failsOnUbuntu failsOnXQuarz} {
    destroy .t
    toplevel .t -width 80 -height 60
    frame .t.menu -height 23 -width 50
    testmenubar window .t .t.menu
    wm resizable .t 0 0
    wm geometry .t +0+0
    tkwait visibility .t







|







1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
    tkwait visibility .t
    set property [testprop [testwrapper .t] WM_NORMAL_HINTS]
    list [winfo height .t] \
	    [expr [lindex $property 5]] [expr [lindex $property 6]] \
	    [expr [lindex $property 7]] [expr [lindex $property 8]] \
	    [expr [lindex $property 9]] [expr [lindex $property 10]]
} {60 40 53 320 233 10 5}
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper} {
    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
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
    update
    list [expr [winfo rootx .t.m.f] - $x] [expr [winfo rooty .t.m.f] - $y] \
	    [expr [winfo rootx .t.f] - $x] [expr [winfo rooty .t.f] - $y]
} {52 7 12 62}

deleteWindows
wm withdraw .
if {[tk windowingsystem] == "aqua"} {
    # Modern mac windows have no border.
    set result_50_1 {{} {} .t .t .t2 {} .t2 .t .t}
} else {
    # Windows are assumed to have a border (invisible in Gnome 3).
    set result_50_1 {{} {} .t {} .t2 {} .t2 {} .t}
}
test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} {unix failsOnUbuntu failsOnXQuarz} {







|







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
    update
    list [expr [winfo rootx .t.m.f] - $x] [expr [winfo rooty .t.m.f] - $y] \
	    [expr [winfo rootx .t.f] - $x] [expr [winfo rooty .t.f] - $y]
} {52 7 12 62}

deleteWindows
wm withdraw .
if {[tk windowingsystem] eq "aqua"} {
    # Modern mac windows have no border.
    set result_50_1 {{} {} .t .t .t2 {} .t2 .t .t}
} else {
    # Windows are assumed to have a border (invisible in Gnome 3).
    set result_50_1 {{} {} .t {} .t2 {} .t2 {} .t}
}
test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} {unix failsOnUbuntu failsOnXQuarz} {
1816
1817
1818
1819
1820
1821
1822
1823
1824



1825
1826
1827
1828


1829

1830
1831
1832
1833
1834
1835
1836
	 [winfo containing [expr $x + 199] [expr $y + 250]] \
	 [winfo containing [expr $x + 200] [expr $y + 250]] \
	 [winfo containing [expr $x + 220] [expr $y + 250]] \
} $result_50_1
test unixWm-50.2 {Tk_CoordsToWindow procedure, finding a toplevel, y-coords and overrideredirect} unix {
    deleteWindows
    toplevel .t -width 400 -height 300 -bg yellow
    wm geom .t +100+100
    tkwait visibility .t



    toplevel .t2 -width 200 -height 100 -bg blue
    wm overrideredirect .t2 1
    wm geom .t2 +200+200
    tkwait visibility .t2


    raise .t2

    set x [winfo rootx .t]
    set y [winfo rooty .t]
    set y2 [winfo rooty .t2]
    list [winfo containing [expr $x +200] [expr $y - 30]] \
	 [winfo containing [expr $x +200] [expr $y - 1]] \
	 [winfo containing [expr $x +200] $y] \
	 [winfo containing [expr $x +200] [expr $y2 - 1]] \







<

>
>
>


<

>
>

>







1827
1828
1829
1830
1831
1832
1833

1834
1835
1836
1837
1838
1839

1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
	 [winfo containing [expr $x + 199] [expr $y + 250]] \
	 [winfo containing [expr $x + 200] [expr $y + 250]] \
	 [winfo containing [expr $x + 220] [expr $y + 250]] \
} $result_50_1
test unixWm-50.2 {Tk_CoordsToWindow procedure, finding a toplevel, y-coords and overrideredirect} unix {
    deleteWindows
    toplevel .t -width 400 -height 300 -bg yellow

    tkwait visibility .t
    wm geom .t +100+100
    update
    restackDelay
    toplevel .t2 -width 200 -height 100 -bg blue
    wm overrideredirect .t2 1

    tkwait visibility .t2
    wm geom .t2 +200+200
    update
    raise .t2
    restackDelay
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    set y2 [winfo rooty .t2]
    list [winfo containing [expr $x +200] [expr $y - 30]] \
	 [winfo containing [expr $x +200] [expr $y - 1]] \
	 [winfo containing [expr $x +200] $y] \
	 [winfo containing [expr $x +200] [expr $y2 - 1]] \
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880

1881
1882
1883
1884

1885
1886
1887
1888
1889
1890
1891
        toplevel .x -width 100 -height 80 -use [frameid] -bg yellow
        tkwait visibility .x
        update
        set x [winfo rootx .x]
        set y [winfo rooty .x]
    }
    set result [list [child eval {winfo containing [expr $x - 1]  [expr $y + 50]}] \
	       	     [child eval {winfo containing $x [expr $y + 50]}]]
    interp delete child
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \
	[winfo containing [expr $x + 200] [expr $y +50]]
    set result
} {{} .x .t .t.f}
test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix {
    destroy .t

    catch {interp delete child}
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +100+100
    tkwait visibility .t

    update
    interp create child
    load {} Tk child
    child eval {wm geometry . 200x200+100+100; tkwait visibility . ; update}

    set result [list [winfo containing 200 200] \
	    [child eval {winfo containing 200 200}]]
    interp delete child
    set result
} {{} .}
test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenubar} {
    deleteWindows







|












<

>



|
>







1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893

1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
        toplevel .x -width 100 -height 80 -use [frameid] -bg yellow
        tkwait visibility .x
        update
        set x [winfo rootx .x]
        set y [winfo rooty .x]
    }
    set result [list [child eval {winfo containing [expr $x - 1]  [expr $y + 50]}] \
	[child eval {winfo containing $x [expr $y + 50]}]]
    interp delete child
    set x [winfo rootx .t]
    set y [winfo rooty .t]
    lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \
	[winfo containing [expr $x + 200] [expr $y +50]]
    set result
} {{} .x .t .t.f}
test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix {
    destroy .t

    catch {interp delete child}
    toplevel .t -width 200 -height 200 -bg green

    tkwait visibility .t
    wm geometry .t +100+100
    update
    interp create child
    load {} Tk child
    child eval {wm geometry . 200x200+100+100; update}
    restackDelay
    set result [list [winfo containing 200 200] \
	    [child eval {winfo containing 200 200}]]
    interp delete child
    set result
} {{} .}
test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenubar} {
    deleteWindows
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968



1969
1970
1971




1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
    set y [expr [winfo rooty .t] + 150]
    list [winfo containing [expr $x + 50] $y] \
	    [winfo containing [expr $x + 150] $y] \
	    [winfo containing [expr $x + 250] $y] \
	    [winfo containing [expr $x + 350] $y] \
	    [winfo containing [expr $x + 450] $y]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} {unix failsOnUbuntu} {
    destroy .t
    destroy .t2
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t



    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    tkwait visibility .t2




    set result [list [winfo containing 100 100]]
    wm iconify .t2
    update idletasks
    lappend result [winfo containing 100 100]
} {.t2 .t}
test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    frame .t.f -width 150 -height 150 -bd 2 -relief raised







|



<

>
>
>

<

>
>
>
>


|







1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987

1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
    set y [expr [winfo rooty .t] + 150]
    list [winfo containing [expr $x + 50] $y] \
	    [winfo containing [expr $x + 150] $y] \
	    [winfo containing [expr $x + 250] $y] \
	    [winfo containing [expr $x + 350] $y] \
	    [winfo containing [expr $x + 450] $y]
} {.t .t.f .t.f.f .t {}}
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t
    destroy .t2
    toplevel .t -width 200 -height 200 -bg green

    tkwait visibility .t
    update
    wm geometry .t +0+0
    update
    toplevel .t2 -width 200 -height 200 -bg red

    tkwait visibility .t2
    update
    wm geometry .t2 +0+0
    update
    restackDelay
    set result [list [winfo containing 100 100]]
    wm iconify .t2
    update
    lappend result [winfo containing 100 100]
} {.t2 .t}
test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    frame .t.f -width 150 -height 150 -bd 2 -relief raised
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
	    [winfo rooty .raise1]]
    destroy .raise1
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}
deleteWindows
test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapped} unix {

    destroy .t

    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t



    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0

    winfo containing 100 100
} {.t}
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} {unix failsOnXQuarz} {
    foreach w {.t .t2 .t3} {
	destroy $w
	update
	toplevel $w -width 200 -height 200 -bg green

	wm geometry $w +0+0

    }
    raise .t .t2

    update
    set result [list [winfo containing 100 100]]
    lower .t3


    lappend result [winfo containing 100 100]
} {.t3 .t}
test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm overrideredirect .t 1
    wm geometry .t +0+0
    tkwait visibility .t
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm overrideredirect .t2 1
    wm geometry .t2 +0+0
    tkwait visibility .t2


    # Need to use vrootx and vrooty to make tests work correctly with
    # virtual root window measures managers: overrideredirect windows
    # come up at (0,0) in display coordinates, not virtual root
    # coordinates.

    set x [expr 100-[winfo vrootx .]]
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    raise .t

    lappend result [winfo containing $x $y]
    raise .t2

    lappend result [winfo containing $x $y]
} {.t2 .t .t2}
# The mac won't put an overrideredirect window above the root,
if {[tk windowingsystem] == "aqua"} {
    wm withdraw .
}
test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} unix {
    foreach w {.t .t2 .t3} {
	destroy $w
	update
	toplevel $w -width 200 -height 200 -bg green
	wm overrideredirect $w 1
	wm geometry $w +0+0
	tkwait visibility $w
	update
    }
    lower .t3 .t2

    update

    # Need to use vrootx and vrooty to make tests work correctly with
    # virtual root window measures managers: overrideredirect windows
    # come up at (0,0) in display coordinates, not virtual root
    # coordinates.

    set x [expr 100-[winfo vrootx .]]
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    lower .t2

    lappend result [winfo containing $x $y]
} {.t2 .t3}
if {[tk windowingsystem] == "aqua"} {
    wm deiconify .
}
test unixWm-51.10 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {
    makeToplevels
    raise .raise1
    set time [lindex [time {raise .raise1}] 0]
    expr {$time < 2000000}







>

>

<

>
>
>


<
>





<

>
|
>


>

|

>
>
|












>










>


>



|













>











>


|







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
	    [winfo rooty .raise1]]
    destroy .raise1
    list $result [winfo containing [winfo rootx .raise2] \
	    [winfo rooty .raise2]]
} {.raise1 .raise3}
deleteWindows
test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapped} unix {
    wm geometry . +300+300
    destroy .t
    update idletasks
    toplevel .t -width 200 -height 200 -bg green

    tkwait visibility .t
    wm geometry .t +0+0
    update
    restackDelay
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red

    # This test assumes that .t2 is not mapped yet, but that is not really guaranteed.
    winfo containing 100 100
} {.t}
test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} {unix failsOnXQuarz} {
    foreach w {.t .t2 .t3} {
	destroy $w

	toplevel $w -width 200 -height 200 -bg green
	tkwait visibility $w
	wm geometry $w +100+100
	update
    }
    raise .t .t2
    restackDelay
    update
    set result [list [winfo containing 200 200]]
    lower .t3
    restackDelay
    sleep 10
    lappend result [winfo containing 200 200]
} {.t3 .t}
test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix {
    destroy .t
    toplevel .t -width 200 -height 200 -bg green
    wm overrideredirect .t 1
    wm geometry .t +0+0
    tkwait visibility .t
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm overrideredirect .t2 1
    wm geometry .t2 +0+0
    tkwait visibility .t2
    restackDelay

    # Need to use vrootx and vrooty to make tests work correctly with
    # virtual root window measures managers: overrideredirect windows
    # come up at (0,0) in display coordinates, not virtual root
    # coordinates.

    set x [expr 100-[winfo vrootx .]]
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    raise .t
    restackDelay
    lappend result [winfo containing $x $y]
    raise .t2
    restackDelay
    lappend result [winfo containing $x $y]
} {.t2 .t .t2}
# The mac won't put an overrideredirect window above the root,
if {[tk windowingsystem] eq "aqua"} {
    wm withdraw .
}
test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} unix {
    foreach w {.t .t2 .t3} {
	destroy $w
	update
	toplevel $w -width 200 -height 200 -bg green
	wm overrideredirect $w 1
	wm geometry $w +0+0
	tkwait visibility $w
	update
    }
    lower .t3 .t2
    restackDelay
    update

    # Need to use vrootx and vrooty to make tests work correctly with
    # virtual root window measures managers: overrideredirect windows
    # come up at (0,0) in display coordinates, not virtual root
    # coordinates.

    set x [expr 100-[winfo vrootx .]]
    set y [expr 100-[winfo vrooty .]]
    set result [list [winfo containing $x $y]]
    lower .t2
    restackDelay
    lappend result [winfo containing $x $y]
} {.t2 .t3}
if {[tk windowingsystem] eq "aqua"} {
    wm deiconify .
}
test unixWm-51.10 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix {
    makeToplevels
    raise .raise1
    set time [lindex [time {raise .raise1}] 0]
    expr {$time < 2000000}
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517

#
# wm attributes tests:
#
# NOTE: since [wm attributes] is not guaranteed to have any effect,
# the only thing we can really test here is the syntax.
#
if {[tk windowingsystem] == "aqua"} {
    set result_60_1 {-alpha 1.0 -fullscreen 0 -modified 0 -notify 0\
			 -titlepath {} -topmost 0 -transparent 0\
			 -type unsupported}
} else {

    set result_60_1 {-alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}}
}
test unixWm-60.1 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t
} -result $result_60_1

test unixWm-60.2 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t -topmost
} -result 0








|
|
|
<

>
|





|







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

#
# wm attributes tests:
#
# NOTE: since [wm attributes] is not guaranteed to have any effect,
# the only thing we can really test here is the syntax.
#
if {[tk windowingsystem] eq "aqua"} {
    set match_60_1 glob
    set result_60_1 {-alpha 1.0 -appearance auto -buttons {close miniaturize zoom} -fullscreen 0 -isdark [01] -modified 0 -notify 0 -titlepath {} -topmost 0 -transparent 0 -stylemask {titled closable miniaturizable resizable} -class nswindow -tabbingid .t -tabbingmode auto -type unsupported}

} else {
    set match_60_1 exact
    set result_60_1 {-alpha 1.0 -fullscreen 0 -topmost 0 -type {} -zoomed 0}
}
test unixWm-60.1 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t
} -match $match_60_1 -result $result_60_1

test unixWm-60.2 {wm attributes - test} -constraints unix -body {
    destroy .t
    toplevel .t
    wm attributes .t -topmost
} -result 0

Changes to tests/util.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkUtil.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test






|







1
2
3
4
5
6
7
8
9
10
11
12
13
# This file is a Tcl script to test out the procedures in the file
# tkUtil.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

Changes to tests/visual.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test the visual- and colormap-handling
# procedures in the file tkVisual.c.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test the visual- and colormap-handling
# procedures in the file tkVisual.c.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 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

# Each menu entry invokes a visual test file

proc runTest {file} {
    global testNum

    test "2.$testNum" "testing $file" {userInteraction} {
    uplevel #0 [list source -encoding utf-8 [file join [testsDirectory] $file]]
    concat ""
    } {}
    incr testNum
}

# The following procedure is invoked to print the contents of a canvas:








|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# Each menu entry invokes a visual test file

proc runTest {file} {
    global testNum

    test "2.$testNum" "testing $file" {userInteraction} {
    uplevel #0 [list source [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
# This file is a Tcl script to test the Windows specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkWinButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands
imageInit







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# This file is a Tcl script to test the Windows specific behavior of
# labels, buttons, checkbuttons, and radiobuttons in Tk (i.e., all the
# widgets defined in tkWinButton.c).  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
# This file is a Tcl script to test out Tk's Windows specific
# clipboard code.  It is organized in the standard fashion for Tcl
# tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1997 by Sun Microsystems, Inc.
# Copyright © 1998-2000 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test









|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# This file is a Tcl script to test out Tk's Windows specific
# clipboard code.  It is organized in the standard fashion for Tcl
# tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1997 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

Changes to tests/winDialog.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24
# -*- tcl -*-
# This file is a Tcl script to test the Windows specific behavior of
# the common dialog boxes.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 1998-1999 ActiveState Corporation.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 1}
}



# Locale identifier LANG_ENGLISH is 0x09
testConstraint english [expr {
    [llength [info commands testwinlocale]]
    && (([testwinlocale] & 0xff) == 9)
}]







|










>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- tcl -*-
# This file is a Tcl script to test the Windows specific behavior of
# the common dialog boxes.  It is organized in the standard
# fashion for Tcl tests.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# Copyright © 1998-1999 ActiveState Corporation.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

if {[testConstraint testwinevent]} {
    catch {testwinevent debug 1}
}

testConstraint tcl8 [package vsatisfies [package provide Tcl] 8]

# Locale identifier LANG_ENGLISH is 0x09
testConstraint english [expr {
    [llength [info commands testwinlocale]]
    && (([testwinlocale] & 0xff) == 9)
}]

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "12x 455"]

test winDialog-5.12 {GetFileName: initial directory: Tcl_TranslateFilename()} -constraints {
    nt
} -body {
#        if (Tcl_TranslateFileName(interp, string, &ds) == NULL)

    tk_getOpenFile -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}

test winDialog-5.12.1 {tk_getSaveFile: initial directory: ~} -constraints {
    nt testwinevent
} -body {
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir ~ \
                      -initialfile "5 12 1" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file normalize [file join ~ "5 12 1"]]

test winDialog-5.12.2 {tk_getSaveFile: initial directory: ~user} -constraints {
    nt testwinevent
} -body {

    # Note: this test will fail on Tcl versions 8.6.4 and earlier due
    # to a bug in file normalize for names of the form ~xxx that
    # returns the wrong dir on Windows.  In particular (in Win8 at
    # least) it returned /users/Default instead of /users/USERNAME...








|

<
<




|












|







479
480
481
482
483
484
485
486
487


488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    then {
        Click ok
    }
    return $x
} -result [file join [initialdir] "12x 455"]

test winDialog-5.12 {GetFileName: initial directory: Tcl_TranslateFilename()} -constraints {
    nt tcl8
} -body {


    tk_getOpenFile -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}

test winDialog-5.12.1 {tk_getSaveFile: initial directory: ~} -constraints {
    nt testwinevent tcl8
} -body {
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir ~ \
                      -initialfile "5 12 1" -title Foo]}
    then {
        Click ok
    }
    return $x
} -result [file normalize [file join ~ "5 12 1"]]

test winDialog-5.12.2 {tk_getSaveFile: initial directory: ~user} -constraints {
    nt testwinevent tcl8
} -body {

    # Note: this test will fail on Tcl versions 8.6.4 and earlier due
    # to a bug in file normalize for names of the form ~xxx that
    # returns the wrong dir on Windows.  In particular (in Win8 at
    # least) it returned /users/Default instead of /users/USERNAME...

587
588
589
590
591
592
593
594











595
596
597
598
599
600
601
602
603
604
605




606
607
608
609
610
611
612
        }
    } finally {
        cd $cur
    }
    string equal $x [file join $dir testfile]
} -result 1

test winDialog-5.12.7 {tk_getOpenFile: initial directory: ~} -constraints {











    nt testwinevent
} -body {
    set fn [file tail [lindex [glob -types f ~/*] 0]]
    unset -nocomplain x
    start {set x [tk_getOpenFile \
                      -initialdir ~ \
                      -initialfile $fn -title Foo]}
    then {
        Click ok
    }
    string equal $x [file normalize [file join ~ $fn]]




} -result 1

test winDialog-5.12.8 {tk_getOpenFile: initial directory: .} -constraints {
    nt testwinevent
} -body {
    # Windows remembers dirs from previous selections so use
    # a subdir for this test, not [initialdir] itself







|
>
>
>
>
>
>
>
>
>
>
>
|










>
>
>
>







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
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: ~} -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 tcl8
} -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
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
    start {set x [tk_getSaveFile -initialfile "12x 456" -title Foo]}
    then {
        Click ok
    }
    file tail $x
} -result "12x 456"
test winDialog-5.14 {GetFileName: initial file: Tcl_TranslateFileName()} -constraints {
    nt
} -body {
#        if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
    tk_getOpenFile -initialfile ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}
if {![vista?]} {
    # XXX - disabled for Vista because the new dialogs allow long file
    # names to be specified but force the user to change it.







|







703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
    start {set x [tk_getSaveFile -initialfile "12x 456" -title Foo]}
    then {
        Click ok
    }
    file tail $x
} -result "12x 456"
test winDialog-5.14 {GetFileName: initial file: Tcl_TranslateFileName()} -constraints {
    nt tcl8
} -body {
#        if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
    tk_getOpenFile -initialfile ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}
if {![vista?]} {
    # XXX - disabled for Vista because the new dialogs allow long file
    # names to be specified but force the user to change it.
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
    start {set x [tk_chooseDirectory -initialdir [initialdir] -title Foo]}
    then {
        Click ok
    }
    string tolower [set x]
} -result [string tolower [initialdir]]
test winDialog-9.8 {Tk_ChooseDirectoryObjCmd: initial directory: Tcl_TranslateFilename()} -constraints {
    nt
} -body {
#        if (Tcl_TranslateFileName(interp, string,
#            &utfDirString) == NULL)

    tk_chooseDirectory -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}








|







934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
    start {set x [tk_chooseDirectory -initialdir [initialdir] -title Foo]}
    then {
        Click ok
    }
    string tolower [set x]
} -result [string tolower [initialdir]]
test winDialog-9.8 {Tk_ChooseDirectoryObjCmd: initial directory: Tcl_TranslateFilename()} -constraints {
    nt tcl8
} -body {
#        if (Tcl_TranslateFileName(interp, string,
#            &utfDirString) == NULL)

    tk_chooseDirectory -initialdir ~12x/455
} -returnCodes error -result {user "12x" doesn't exist}

Changes to tests/winFont.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# This file is a Tcl script to test out the procedures in tkWinFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# This file is a Tcl script to test out the procedures in tkWinFont.c.
# It is organized in the standard fashion for Tcl tests.
#
# Many of these tests are visually oriented and cannot be checked
# programmatically (such as "does an underlined font appear to be
# underlined?"); these tests attempt to exercise the code in question,
# but there are no results that can be checked.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
    .t.l config -text "a"
    update
} -cleanup {
    destroy .t.l
} -result {}


test winfont-7.1 {AllocFont procedure: use old font} -constraints win -setup {
    destroy .c
} -setup {
    catch {font delete xyz}
} -body {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} -result {}
test winfont-7.2 {AllocFont procedure: extract info from logfont} -constraints {
    win
} -body {
    font actual {arial 10 bold italic underline overstrike}
} -result {-family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1}
test winfont-7.3 {AllocFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric {arial 10 bold italic underline overstrike} -fixed
} -result 0
test winfont-7.4 {AllocFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric systemfixed -fixed
} -result 1

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:








|











|




|




|













350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
    .t.l config -text "a"
    update
} -cleanup {
    destroy .t.l
} -result {}


test winfont-7.1 {InitFont procedure: use old font} -constraints win -setup {
    destroy .c
} -setup {
    catch {font delete xyz}
} -body {
    font create xyz
    button .c -font xyz
    font configure xyz -family times
    update
    destroy .c
    font delete xyz
} -result {}
test winfont-7.2 {InitFont procedure: extract info from logfont} -constraints {
    win
} -body {
    font actual {arial 10 bold italic underline overstrike}
} -result {-family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1}
test winfont-7.3 {InitFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric {arial 10 bold italic underline overstrike} -fixed
} -result 0
test winfont-7.4 {InitFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric systemfixed -fixed
} -result 1

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/winMenu.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test menus in Tk.  It is
# organized in the standard fashion for Tcl tests. This
# file tests the Macintosh-specific features of the menu
# system.
#
# Copyright © 1995-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
} -setup {
    destroy .m1
} -body {
    catch {image delete image1}
    menu .m1
    image create test image1
    list [catch {.m1 add command -image image1} msg] $msg [destroy .m1] [image delete image1]
} -result {0 {} {} {}}
test winMenu-6.3 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -bitmap questhead} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.4 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.5 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.6 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.7 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.8 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.9 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo" -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.10 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.11 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.12 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.13 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo" -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.14 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.15 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-6.16 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 {} {}}

test winMenu-7.1 {ReconfigureWindowsMenu - system menu item removal} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1







|





|





|





|





|





|





|





|





|





|





|





|





|





|





|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
} -setup {
    destroy .m1
} -body {
    catch {image delete image1}
    menu .m1
    image create test image1
    list [catch {.m1 add command -image image1} msg] $msg [destroy .m1] [image delete image1]
} -result {0 e001 {} {}}
test winMenu-6.3 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -bitmap questhead} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.4 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.5 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.6 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.7 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.8 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.9 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo" -accel "bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.10 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.11 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.12 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.13 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "foo" -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.14 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "This string has one & in it" -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.15 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The & should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}
test winMenu-6.16 {GetEntryText} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command -label "The * should be underlined." -underline 4 -accel "&bar"} msg] $msg [destroy .m1]
} -result {0 e001 {}}

test winMenu-7.1 {ReconfigureWindowsMenu - system menu item removal} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437


test winMenu-9.1 {TkpMenuNewEntry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-10.1 {TkwinMenuProc} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {







|







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437


test winMenu-9.1 {TkpMenuNewEntry} -constraints win -setup {
    destroy .m1
} -body {
    menu .m1
    list [catch {.m1 add command} msg] $msg [destroy .m1]
} -result {0 e001 {}}


test winMenu-10.1 {TkwinMenuProc} -constraints {
    win userInteraction
} -setup {
    destroy .m1
} -body {
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    menu .m1 -tearoff 0
    .m1 add command -label foo
    update idletasks
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}


test winMenu-13.1 {TkpSetMainMenubar - nothing to do} -constraints {
    emptyTest win
} -body {}


test winMenu-14.1 {GetMenuIndicatorGeometry} -constraints win -setup {
    destroy .m1
} -body {







|







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    menu .m1 -tearoff 0
    .m1 add command -label foo
    update idletasks
    list [catch {. configure -menu .m1} msg] $msg [. configure -menu ""] [destroy .m1]
} -result {0 {} {} {}}


test winMenu-13.1 {Tk_SetMainMenubar - nothing to do} -constraints {
    emptyTest win
} -body {}


test winMenu-14.1 {GetMenuIndicatorGeometry} -constraints win -setup {
    destroy .m1
} -body {
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} -result {0 {} {}}
test winMenu-28.2 {TkpConfigureMenuEntry - update not pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label One
    update idletasks
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} -result {0 {} {}}


test winMenu-29.1 {TkpDrawMenuEntry - gc for active and not strict motif} -constraints {
    win
} -setup {
    destroy .m1
} -body {







|









|







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label Hello
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} -result {0 e002 {}}
test winMenu-28.2 {TkpConfigureMenuEntry - update not pending} -constraints {
    win
} -setup {
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 add command -label One
    update idletasks
    list [catch {.m1 add command -label Two} msg] $msg [destroy .m1]
} -result {0 e002 {}}


test winMenu-29.1 {TkpDrawMenuEntry - gc for active and not strict motif} -constraints {
    win
} -setup {
    destroy .m1
} -body {

Changes to tests/winSend.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# Compute a script that will load Tk into a child interpreter.






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is a Tcl script to test out the "send" command and the
# other procedures in the file tkSend.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994 Sun Microsystems, Inc.
# 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

# Compute a script that will load Tk into a child interpreter.

Changes to tests/winWm.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
# This file tests  is a Tcl script to test the procedures in the file
# tkWinWm.c.  It is organized in the standard fashion for Tcl tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1996 by Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]


test winWm-1.1 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm override .t 1
    wm geometry .t +0+0







|
|







|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# This file tests  is a Tcl script to test the procedures in the file
# tkWinWm.c.  It is organized in the standard fashion for Tcl tests.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1996 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" }]

test winWm-1.1 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm override .t 1
    wm geometry .t +0+0
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    wm attributes .t -disabled
} -cleanup {
    destroy .t
} -result 0
test winWm-6.3 {wm attributes} -constraints win -setup {
    destroy .t
} -body {
    # This isn't quite the correct error message yet, but it works.
    toplevel .t
    wm attributes .t -foo
} -cleanup {
    destroy .t
} -returnCodes error -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}

test winWm-6.4 {wm attributes -alpha} -constraints win -setup {
    destroy .t
} -body {
    # Expect this to return all 1.0 {} on pre-2K/XP
    toplevel .t
    set res [wm attributes .t -alpha]







<




|







276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
    wm attributes .t -disabled
} -cleanup {
    destroy .t
} -result 0
test winWm-6.3 {wm attributes} -constraints win -setup {
    destroy .t
} -body {

    toplevel .t
    wm attributes .t -foo
} -cleanup {
    destroy .t
} -returnCodes error -result {bad attribute "-foo": must be -alpha, -disabled, -fullscreen, -toolwindow, -topmost, or -transparentcolor}

test winWm-6.4 {wm attributes -alpha} -constraints win -setup {
    destroy .t
} -body {
    # Expect this to return all 1.0 {} on pre-2K/XP
    toplevel .t
    set res [wm attributes .t -alpha]
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
} -cleanup {
    foreach cmd {proc1 proc2 proc3 click} {
        rename winwm91$cmd {}
    }
    destroy .tx .t .sd
} -result ok

test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -constraints failsOnUbuntu -setup {
    destroy .t
    toplevel .t
    set winwm92 {}
    frame .t.f -background blue -height 200 -width 200
    frame .t.f.x -background red -height 100 -width 100
} -body {
    pack .t.f.x







|







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
} -cleanup {
    foreach cmd {proc1 proc2 proc3 click} {
        rename winwm91$cmd {}
    }
    destroy .tx .t .sd
} -result ok

test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    destroy .t
    toplevel .t
    set winwm92 {}
    frame .t.f -background blue -height 200 -width 200
    frame .t.f.x -background red -height 100 -width 100
} -body {
    pack .t.f.x

Changes to tests/window.test.

1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test the procedures in the file
# tkWindow.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands
namespace import ::tk::test::loadTkCommand




|







1
2
3
4
5
6
7
8
9
10
11
12
# This file is a Tcl script to test the procedures in the file
# tkWindow.c.  It is organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands
namespace import ::tk::test::loadTkCommand
259
260
261
262
263
264
265
































266
267
268
269
270
271
272
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 YES}


































test window-3.1 {Tk_MakeWindowExist procedure, stacking order and menubars} -constraints {
    unix testmenubar
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 YES}

test window-2.12 {Test for ticket [9b6065d1fd] - restore Tcl [update] command} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
	after 1000 {set forever 1}
	after 100 {destroy .}
	after 200 {catch bell msg; puts "ringing the bell -> $msg"}
	after 250 {update idletasks}
	after 300 {update}
	puts "waiting"
	vwait forever
	puts "done waiting"
	catch {bell} msg
	puts "bell -> $msg"
	catch update msg
	puts "update -> $msg"
    }
    set script [makeFile $code script]
    if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} {
        set error 1
    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 {waiting
ringing the bell -> can't invoke "bell" command: application has been destroyed
done waiting
bell -> can't invoke "bell" command: application has been destroyed
update -> }}


test window-3.1 {Tk_MakeWindowExist procedure, stacking order and menubars} -constraints {
    unix testmenubar
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351
    update
    lower .t.e2 .t.f
    update
    # If stacking order isn't handled properly, generates an X error.
} -cleanup {
    destroy .t
} -result {}



# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:







>









368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    update
    lower .t.e2 .t.f
    update
    # If stacking order isn't handled properly, generates an X error.
} -cleanup {
    destroy .t
} -result {}



# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/winfo.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is a Tcl script to test out the "winfo" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint failsOnUbuntu [expr {![info exists ::env(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# eatColors --
# Creates a toplevel window and allocates enough colors in it to
# use up all the slots in the colormap.
#
# Arguments:





|







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is a Tcl script to test out the "winfo" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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:
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
} -returnCodes error -result {wrong # args: should be "winfo viewable window"}
test winfo-9.2 {"winfo viewable" command} -body {
    winfo viewable foo
} -returnCodes error -result {bad window path name "foo"}
test winfo-9.3 {"winfo viewable" command} -body {
    winfo viewable .
} -result 1
test winfo-9.4 {"winfo viewable" command} -constraints failsOnUbuntu -body {
    wm iconify .
    winfo viewable .
} -cleanup {
    wm deiconify .
} -result 0
test winfo-9.5 {"winfo viewable" command} -setup {
    deleteWindows







|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
} -returnCodes error -result {wrong # args: should be "winfo viewable window"}
test winfo-9.2 {"winfo viewable" command} -body {
    winfo viewable foo
} -returnCodes error -result {bad window path name "foo"}
test winfo-9.3 {"winfo viewable" command} -body {
    winfo viewable .
} -result 1
test winfo-9.4 {"winfo viewable" command} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    wm iconify .
    winfo viewable .
} -cleanup {
    wm deiconify .
} -result 0
test winfo-9.5 {"winfo viewable" command} -setup {
    deleteWindows
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
        rooty [expr {[winfo rooty .emb] == [winfo rooty .con]}]
} -cleanup {
    deleteWindows
} -result {rootx 1 rooty 1}

# Windows does not destroy the container when an embedded window is
# destroyed.  Unix and macOS do destroy it.  See ticket [67384bce7d].
if {[tk windowingsystem] == "win32"} {
   set result_13_2 {embedded 0 container 1}
} else {
   set result_13_2 {embedded 0 container 0}
}
test winfo-13.2 {destroying embedded toplevel} -setup {
    deleteWindows
} -body {







|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
        rooty [expr {[winfo rooty .emb] == [winfo rooty .con]}]
} -cleanup {
    deleteWindows
} -result {rootx 1 rooty 1}

# Windows does not destroy the container when an embedded window is
# destroyed.  Unix and macOS do destroy it.  See ticket [67384bce7d].
if {[tk windowingsystem] eq "win32"} {
   set result_13_2 {embedded 0 container 1}
} else {
   set result_13_2 {embedded 0 container 0}
}
test winfo-13.2 {destroying embedded toplevel} -setup {
    deleteWindows
} -body {

Changes to tests/wm.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

































































17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# This file is a Tcl script to test out Tk's interactions with the window
# manager, including the "wm" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# All rights reserved.

# This file tests window manager interactions that work across platforms.
# Window manager tests that only work on a specific platform should be placed
# in unixWm.test or winWm.test.

package require tcltest 2.2
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(TRAVIS_OS_NAME)] || ![string match linux $::env(TRAVIS_OS_NAME)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# [raise] and [lower] may return before the window manager has completed the
# operation. The raiseDelay procedure idles for a while to give the operation
# a chance to complete.
#

proc raiseDelay {} {
    after 100;
    update
    update idletasks
}

# How to carry out a small delay while processing events

proc eventDelay {{delay 200}} {
    after $delay "set done 1" ; vwait done
}

deleteWindows

##############################################################################

stdWindow

test wm-1.1 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm
} -result {wrong # args: should be "wm option window ?arg ...?"}
# Next test will fail every time set of subcommands is changed
test wm-1.2 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm foo
} -result {bad option "foo": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}
test wm-1.3 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm command
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-1.4 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm aspect bogus
} -result {bad window path name "bogus"}
test wm-1.5 {Tk_WmObjCmd procedure, miscellaneous errors} -body {






|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|








|
|
|




















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# This file is a Tcl script to test out Tk's interactions with the window
# manager, including the "wm" command. It is organized in the standard fashion
# for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

# This file tests window manager interactions that work across platforms.
# Window manager tests that only work on a specific platform should be placed
# in unixWm.test or winWm.test.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

image create photo icon -data {
    iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAA
    CBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/w
    D/AP+gvaeTAAAACXBIWXMAArQNAAK0DQEdFIm+AAAJQElEQVRYw+WXW2xdV5nHf/ty7lc
    f2/FxYsdOnMSNC0HTpDiRKJWAQjWCEQNUSEAFfUOiQqrEC2+IxwpemDLSzNBBCCQeQEKq
    RJgBSikiuGlN22TqhsR27OPL8eWc43Pdt7X22osHHydOm4FBPM6Slr69paX9/32Xtb614
    f/7MP6vC3O5f8L3G7HJyZPHBwfz5wrF7HQ6nRwxLTOhQuU4PW+z3eq9Xa+33rq9cms7k8
    pHjvfS3w8wOfk52u1u8oHpiUff897JJ8+dO/nI6LHho6OjQ3ahkMYwTTZ2O2zXutS3G/7
    ayubq7Vtr/7Ve2f7RytLam4ViXq1t/vRvB0ilPsjzz3+LZ5/9j7MzM5Nf/8hj5//5H97/
    YNbK5hkfTFLMxAEQQvD766v0yBGIEBEEuPUGi9dv7lx77cb3Vm9vfqc0WNi9evUKWr/xL
    h3rfuLj45+l0bjM7m768U98/OJ/fulLH/3wiemxeCafxRcKw7TJxKC+12RpbYdAx7HsOC
    rSRNpg+sQQj1w8nS0N5h8JAvm+rWr99ZmZB2qWdZq9vWt/GWBm5im+9rUn6HRGPv7EE4/
    ++2P/eOFkV0FkJTDQgCaXTbO1tcV2R2EmCxBJQixs2+R9EwV00MFAceJE2ZiZOT7VaTsP
    LyxU5orFTK1cfphq9bX7A8zOfoV8Ps3c3NsXPvWpD37vc5//0ETNt8gNjDAzlsdAE0vli
    TCRxEhnC2CaRIZNMmZiaonv9mh1PcrDJQZzCfK5OGNjQ8e2tvZO37y5+ctk0naq1fn7A4
    yOnmd5uVp4/PGHn/vylz8xe+zoEIP5JAMpA0OHeK6DG4TEk2li8ThaQxRpIg0q6DGUNjg
    6UuLYSInhYoYoigiCgHQ6TrGYnlpd3Q1ffvk3L128+ITe2Hj1XoBLl55menqcbDb1haee
    evyrDz102tJaE7ctLBMqG1X23Ag7kcKOJzAADSilCVWEZdmMDaXJJCxSiRimaaK1RkqJ7
    /uUSlk6Hed0oxG9HI9bm+Pjs2xsvIp5AKC15oUX/lA8f/7MF2dnz8YADMNASslypYqrUx
    SHyqSy+f31hzaRZRpMDKVYr+7y4usVri1WWavWCWSIZZkYhoFSIRcuTI1MTAw9OTf33Tu
    7zz54SCRinD17/Pzs7AMPFQqZPlTE8vo2DlmGhgbo12BffD/8SmukitiuNxHKoDwyzPJG
    nTdXmtiWwdnRNCN5GxWGDA/nOH26/NGpqSfHgPU7AJcuPc0nP/kBrl698YGZmYmMEIJmx
    6Hn+my0DUZGC6gIzEOnhu4Lh2GEbRocGyxRSO/7c3QgiRuEVOtdEvEQrSN8IVEq5MSJ4Y
    lSKX3OMKJ14G4KnnnmM9bkZPk92VyKy3M3eentJjd3FUYyjxuEeELt7/NoP+eBVAipCFX
    EsYE4xcydYFIeSHKynOXhUwM0mh32egH1tsdL16oo007kcskHs7kYly49fRcALqby+fQo
    pklkZ4jHY3g6gQgjHF/QcgQdV+7DHJoGmnzSQuvD0QGlIsJQkU4luLXR4kgxxcRgjM1mQ
    CyZHrv0sUe4JwKFXMmu7/VSXV9xaXqI0YzC8328QOJ4gq4raHQDGt2AtitwfIEbSAwibO
    vdJ7pSCiElR3IxGh2X5Y0GV66v0wnAsq3MN5759L1FqKMoCkQoX19u0QkkD47lKSYiTh1
    NoSLYafu0ehrTNNBaE2mNUop2z+DEUJKBbPxecSEIgoAoUjwwmmZpdZPlmuL4oIFWkbx8
    rXIvQMfZ9p2e1xBCstOJcFe6nB1NcWokhW1ZHMkazK90qXXDfZFII0NFIBW/XQiZHraoN
    bsU81mmjhbxfZ8gCAiCgELKQitJGCoIQ6SQO//2ze/fm4Kf/Px50dzr3Aoch1Ap2o4kn8
    tgW/sHynAxzcVTBQYzFp4v6boBjidwfcFCpcmPf7/Oz+ZrvPBalb12D9/370DUGk1evr6
    NacWIfD/yveDmXq3F3NxzdwH+5dkfUq8155rb9dA2QcqQcjFx57DRGgaySR47d4RHZ0pY
    eh/C9QSOJ3EECGWw3fJZ323j+x6e5xH4Pgu3d6g0FMWUjdvu7bo9/5oK1d0IzM09hwhCG
    rvNubXFylI2pum4AZXtDqEURFGE1hoNxGMW5ZyB22nS8wQ9r1+QvsDzBc1uQGW7jee6eN
    4+RMfxMdHkYgatWmtur9ZaOnD8TgQMA27c+uH68s3KT8O9BoYBv3pjkxuVGo7Tw+1/MAh
    83lreYm1P9r3fT4XjSVxf4voC1/NwHAfXdXFcB891KGVjhO2e16q3fzR2cjQwDPPeZrSx
    8SqXL2/RqDU2EnH7I8dPjQ8v7Tqs1RwmSzEsQoQQSBHw1lKVha0AEUb4IiQQIb4I8YUkk
    CHTQwa5WIjne9xY2mT+VouRfI7NxfVfrK8sfTuRSAavXP3Xd7fjavWPRq1+3TeiQTVcGn
    h0oHwktlZzmBq0SNsRQgiuXLvNL/+nQU/aBFL1xSW+kAghEb5PEkE5q3Bdl7dv72LGCrT
    Xdzf+9Nb8N5dXfrG6Wf1jeNDP3nkjigOFWm2xpvx0+tjI8LnMYMnMxQT5eIjruVye36LS
    TRAqRSD3vZdCIqUgEj5R4CEDj2O5kMZei3rHoLXV6Sy88cp3Fhf/ew6IAAGE9wOIARmtw
    9Tu7vKa1yY+Wiqeee+ZYdsi4HdvrjK/HiKUiZQhoZREQhDJAC18tPSIhEfouwSuQ9cx2V
    xpNK/PX/n+4uKvXwQdAAHgA/J+AAaQABJRJOydnVsrzZ1O13eMcSuezC61LJzQRgY+KvC
    JhI+WPpH0IAywIkEhaVIupAhdHS0t3F66Nv/iD9bW/nAFtAM4QA9wAXX3RnEvQBoYODSL
    +fzEmalTsx+emjl3YWjsaMlMpcwg0ggZEimFoSNsI8JSCtF1wtpmdWt1aeGVSuW133leY
    wNoA01gr297BzVwv/8CA0gBBaDYtzkw87ns6PhI+czM0JHjp/PFUjmZSmUM07RCKUPP6X
    Vae/Vqfbdys1ZbvOX5ja2+ULcP0Opbt18H/G8Ah+shDWQPzVQ/RSnLTGRsO5U0TMuMVKj
    C0PUjLd1+fgPAOxTybl9YcvdC9VcBDobV3x0JINm3MfYbmdX/hu57FfZFDgot6Fe8eqfw
    3wLwzvVmX9jsvx8AHEAcnn91/BlySEFKTpuCtgAAABN0RVh0QXV0aG9yAHdhcnN6YXdpY
    W5rYQy+S5cAAABYdEVYdENvcHlyaWdodABDQzAgUHVibGljIERvbWFpbiBEZWRpY2F0aW
    9uIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL3B1YmxpY2RvbWFpbi96ZXJvLzEuMC/
    G4735AAAAIXRFWHRDcmVhdGlvbiBUaW1lADIwMTAtMDMtMjlUMDg6MDg6MzD47LxwAAAA
    JXRFWHRkYXRlOmNyZWF0ZQAyMDIxLTA4LTE1VDIwOjU0OjM5LTA0OjAwNBT3DQAAACV0R
    Vh0ZGF0ZTptb2RpZnkAMjAyMS0wOC0xNVQyMDo1NDoxMS0wNDowMDSDBqsAAADIelRYdE
    Rlc2NyaXB0aW9uAAAY042OwQqCQBCGn6B3GOy+Cl0qTAjEc1HRJVhWHXUrd2pmLXr7tDr
    VpcMP838w/F+wxxxyprsgB2ALclAxtRAbaBirRdB4f5mHoTeuJlUxYoly8nRRxHW4HahO
    30SvmI5Y+CCBF4dPhzg0CYwOLs45GdKfG+sKhBuy2H4xUlM1i76+BhcBwwirLj/bAlJqj
    XXzP9UyxmuHzp8feiknLPW6Q/H9moy3yK1oqvROUE2yH99suX45PwEyf2MTOoCNrQAAAB
    l0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABWdEVYdFNvdXJjZQBodHR
    wczovL29wZW5jbGlwYXJ0Lm9yZy9kZXRhaWwvMzUyMzMvdGFuZ28taW5ldHJuZXQtd2Vi
    LWJyb3dzZXItYnktd2Fyc3phd2lhbmth5nAuRgAAACB0RVh0VGl0bGUAdGFuZ28gaW5ld
    HJuZXQgd2ViIGJyb3dzZXLyr62TAAAAAElFTkSuQmCC
}

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 250;
    update idletasks
    update
}

# How to carry out a small delay while processing events

proc eventDelay {{delay 200}} {
    after $delay "set done 1" ; vwait done
}

deleteWindows

##############################################################################

stdWindow

test wm-1.1 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm
} -result {wrong # args: should be "wm option window ?arg ...?"}
# Next test will fail every time set of subcommands is changed
test wm-1.2 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm foo
} -result {bad option "foo": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbadge, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}
test wm-1.3 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm command
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-1.4 {Tk_WmObjCmd procedure, miscellaneous errors} -returnCodes error -body {
    wm aspect bogus
} -result {bad window path name "bogus"}
test wm-1.5 {Tk_WmObjCmd procedure, miscellaneous errors} -body {
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142

143
144
145



146
147
148
149
150
151
152
153
154
155
156


### wm attributes ###
test wm-attributes-1.1 {usage} -returnCodes error -body {
    wm attributes
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-attributes-1.2.1 {usage} -constraints win -returnCodes error -body {
    # This is the wrong error to output - unix has it right, but it's
    # not critical.
    wm attributes . _
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}

test wm-attributes-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm attributes . -alpha 1.0 -disabled
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
test wm-attributes-1.2.3 {usage} -constraints win -returnCodes error -body {
    # This is the wrong error to output - unix has it right, but it's
    # not critical.
    wm attributes . -to
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}

test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type}



test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, -transparent, or -type}


### wm client ###
test wm-client-1.1 {usage} -returnCodes error -body {
    wm client
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-client-1.2 {usage} -returnCodes error -body {
    wm client . _ _







<
<

<
>




<
<

<
>


|
>
>
>


<
|







189
190
191
192
193
194
195


196

197
198
199
200
201


202

203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219


### wm attributes ###
test wm-attributes-1.1 {usage} -returnCodes error -body {
    wm attributes
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-attributes-1.2.1 {usage} -constraints win -returnCodes error -body {


    wm attributes . _

} -result {bad attribute "_": must be -alpha, -disabled, -fullscreen, -toolwindow, -topmost, or -transparentcolor}
test wm-attributes-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm attributes . -alpha 1.0 -disabled
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
test wm-attributes-1.2.3 {usage} -constraints win -returnCodes error -body {


    wm attributes . -to

} -result {bad attribute "-to": must be -alpha, -disabled, -fullscreen, -toolwindow, -topmost, or -transparentcolor}
test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -fullscreen, -topmost, -type, or -zoomed}
if {[tk windowingsystem] eq "aqua"} {
    set result_1_2_5 {bad attribute "_": must be -alpha, -appearance, -buttons, -fullscreen, -isdark, -modified, -notify, -titlepath, -topmost, -transparent, -stylemask, -class, -tabbingid, -tabbingmode, or -type}
} else {set result_1_2_5 {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, -transparent, or -type}}
test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
    wm attributes . _

} -result $result_1_2_5

### wm client ###
test wm-client-1.1 {usage} -returnCodes error -body {
    wm client
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-client-1.2 {usage} -returnCodes error -body {
    wm client . _ _
724
725
726
727
728
729
730









































































731
732
733
734
735
736
737
    lappend result [wm group .t]
    wm group .t .
    lappend result [wm group .t]
    wm group .t {}
    lappend result [wm group .t]
} -result [list {} . {}]











































































### wm iconbitmap ###
test wm-iconbitmap-1.1 {usage} -returnCodes error -body {
    wm iconbitmap
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-iconbitmap-1.2.1 {usage} -constraints unix -returnCodes error -body {
    wm iconbitmap .t 12 13







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







787
788
789
790
791
792
793
794
795
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
    lappend result [wm group .t]
    wm group .t .
    lappend result [wm group .t]
    wm group .t {}
    lappend result [wm group .t]
} -result [list {} . {}]


### wm iconbadge ###
test wm-iconbadge-1.1 {usage} -body {
    wm iconbadge
} -returnCodes error -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-iconbadge-1.2 {usage} -body {
    frame .f
    set ::tk::icons::base_icon(.f) icon
    wm iconbadge .f icon
} -cleanup {
    destroy .f
    unset ::tk::icons::base_icon(.f)
} -returnCodes error -result {window ".f" isn't a top-level window}
test wm-iconbadge-1.3 {::tk::icons::base_icon($win) must be set on X11} -constraints {
    x11
} -setup {
    unset -nocomplain ::tk::icons::base_icon(.)
} -body {
    wm iconbadge . !
} -returnCodes error -result {::tk::icons::base_icon(.) must be set on X11}
test wm-iconbadge-1.4 {::tk::icons::base_icon($win) must be a Tk photo on X11} -constraints {
    x11
} -setup {
    catch {image delete book}
} -body {
    set ::tk::icons::base_icon(.) book
    wm iconbadge . 27
} -returnCodes error -result {can't use "book" as iconphoto: not a photo image}
test wm-iconbadge-1.5 {illegal badge number} -body {
    image create photo book -data {
        R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAAC
        wAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IM
        QCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc
        0yv+DVSEUuFxIAOw==
    }
    set ::tk::icons::base_icon(.) book
    wm iconbadge . illegal
} -cleanup {
    image delete book
} -returnCodes error -result {can't use "illegal" as icon badge}
test wm-iconbadge-1.6 {non-integer badge number} -body {
    image create photo book -data {
        R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAAC
        wAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IM
        QCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc
        0yv+DVSEUuFxIAOw==
    }
    set ::tk::icons::base_icon(.) book
    wm iconbadge . 3.2
} -cleanup {
    image delete book
} -returnCodes error -result {can't use "3.2" as icon badge}
test wm-iconbadge-1.7 {negative or zero badge number} -body {
    image create photo book -data {
        R0lGODlhDwAPAKIAAP//////AP8AAMDAwICAgAAAAAAAAAAAAC
        wAAAAADwAPAAADSQhA2u5ksPeKABKSCaya29d4WKgERFF0l1IM
        QCAKatvBJ0OTdzzXI1xMB3TBZAvATtB6NSLKleXi3OBoLqrVgc
        0yv+DVSEUuFxIAOw==
    }
    set ::tk::icons::base_icon(.) book
    wm iconbadge . 0
} -cleanup {
    image delete book
} -returnCodes error -result {can't use "0" as icon badge}
test wm-iconbadge-1.8 {usage, no need to call iconphoto on aqua or win32} -constraints {
    aquaOrWin32
} -body {
    wm iconbadge . 3
    wm iconbadge . 5000
    wm iconbadge . !
    wm iconbadge . ""
} -result {}


### wm iconbitmap ###
test wm-iconbitmap-1.1 {usage} -returnCodes error -body {
    wm iconbitmap
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-iconbitmap-1.2.1 {usage} -constraints unix -returnCodes error -body {
    wm iconbitmap .t 12 13
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2 .r.f
} -result {can't iconify ".t2": it is an embedded window}

test wm-iconify-3.1 {iconify behavior} -constraints failsOnUbuntu -body {
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks
    lappend result [winfo ismapped .t2]







|







942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    wm iconify .t2
} -returnCodes error -cleanup {
    destroy .t2 .r.f
} -result {can't iconify ".t2": it is an embedded window}

test wm-iconify-3.1 {iconify behavior} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks
    lappend result [winfo ismapped .t2]
880
881
882
883
884
885
886

887
888
889
890
891
892
893
} -result {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}
test wm-iconphoto-1.5.1 {usage} -constraints aquaOrWin32 -returnCodes error -body {
    wm iconphoto . -default [image create photo -file {}]
} -match {glob} -result {failed to create an iconphoto with image *}
test wm-iconphoto-1.5.2 {usage} -constraints x11 -body {
    wm iconphoto . -default [image create photo -file {}]
} -result {}


# All other iconphoto tests are platform specific


### wm iconposition ###
test wm-iconposition-1.1 {usage} -returnCodes error -body {
    wm iconposition







>







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
} -result {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}
test wm-iconphoto-1.5.1 {usage} -constraints aquaOrWin32 -returnCodes error -body {
    wm iconphoto . -default [image create photo -file {}]
} -match {glob} -result {failed to create an iconphoto with image *}
test wm-iconphoto-1.5.2 {usage} -constraints x11 -body {
    wm iconphoto . -default [image create photo -file {}]
} -result {}


# All other iconphoto tests are platform specific


### wm iconposition ###
test wm-iconposition-1.1 {usage} -returnCodes error -body {
    wm iconposition
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
    wm maxsize . a
} -result {wrong # args: should be "wm maxsize window ?width height?"}
test wm-maxsize-1.3 {usage} -returnCodes error -body {
    wm maxsize . a b c
} -result {wrong # args: should be "wm maxsize window ?width height?"}
test wm-maxsize-1.4 {usage} -returnCodes error -body {
    wm maxsize . x 100
} -result {expected integer but got "x"}
test wm-maxsize-1.5 {usage} -returnCodes error -body {
    wm maxsize . 100 bogus
} -result {expected integer but got "bogus"}
test wm-maxsize-1.6 {usage} -setup {
    destroy .t2
} -body {
    toplevel .t2
    wm maxsize .t2 300 200
    wm maxsize .t2
} -cleanup {







|


|







1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
    wm maxsize . a
} -result {wrong # args: should be "wm maxsize window ?width height?"}
test wm-maxsize-1.3 {usage} -returnCodes error -body {
    wm maxsize . a b c
} -result {wrong # args: should be "wm maxsize window ?width height?"}
test wm-maxsize-1.4 {usage} -returnCodes error -body {
    wm maxsize . x 100
} -result {expected screen distance but got "x"}
test wm-maxsize-1.5 {usage} -returnCodes error -body {
    wm maxsize . 100 bogus
} -result {expected screen distance but got "bogus"}
test wm-maxsize-1.6 {usage} -setup {
    destroy .t2
} -body {
    toplevel .t2
    wm maxsize .t2 300 200
    wm maxsize .t2
} -cleanup {
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
    wm minsize . a
} -result {wrong # args: should be "wm minsize window ?width height?"}
test wm-minsize-1.3 {usage} -returnCodes error -body {
    wm minsize . a b c
} -result {wrong # args: should be "wm minsize window ?width height?"}
test wm-minsize-1.4 {usage} -returnCodes error -body {
    wm minsize . x 100
} -result {expected integer but got "x"}
test wm-minsize-1.5 {usage} -returnCodes error -body {
    wm minsize . 100 bogus
} -result {expected integer but got "bogus"}
test wm-minsize-1.6 {usage} -setup {
    destroy .t2
} -body {
    toplevel .t2
    wm minsize .t2 300 200
    wm minsize .t2
} -cleanup {







|


|







1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
    wm minsize . a
} -result {wrong # args: should be "wm minsize window ?width height?"}
test wm-minsize-1.3 {usage} -returnCodes error -body {
    wm minsize . a b c
} -result {wrong # args: should be "wm minsize window ?width height?"}
test wm-minsize-1.4 {usage} -returnCodes error -body {
    wm minsize . x 100
} -result {expected screen distance but got "x"}
test wm-minsize-1.5 {usage} -returnCodes error -body {
    wm minsize . 100 bogus
} -result {expected screen distance but got "bogus"}
test wm-minsize-1.6 {usage} -setup {
    destroy .t2
} -body {
    toplevel .t2
    wm minsize .t2 300 200
    wm minsize .t2
} -cleanup {
1347
1348
1349
1350
1351
1352
1353

1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367

1368

1369
1370
1371
1372
1373
1374
1375
} -cleanup {
    destroy .t
} -returnCodes error -result {window ".t" isn't mapped}
deleteWindows

test wm-stackorder-2.1 {stacking order} -body {
    toplevel .t ; update

    wm stackorder .
} -cleanup {
    destroy .t
} -result {. .t}
test wm-stackorder-2.2 {stacking order} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-2.3 {stacking order} -body {
    toplevel .t ; update

    toplevel .t2 ; update

    raise .
    raiseDelay
    raise .t2
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t .t2







>













|
>
|
>







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
} -cleanup {
    destroy .t
} -returnCodes error -result {window ".t" isn't mapped}
deleteWindows

test wm-stackorder-2.1 {stacking order} -body {
    toplevel .t ; update
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {. .t}
test wm-stackorder-2.2 {stacking order} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-2.3 {stacking order} -body {
    toplevel .t
    tkwait visibility .t
    toplevel .t2
    tkwait visibility .t2
    raise .
    raiseDelay
    raise .t2
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t .t2
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
    raiseDelay
    wm stackorder .parent
} -cleanup {
    deleteWindows
} -result {.parent.child2 .parent.child1 .parent}
test wm-stackorder-2.6 {stacking order: non-toplevel widgets ignored} -body {
    toplevel .t1

    button .t1.b
    pack .t1.b
    update
    wm stackorder .
} -cleanup {
    destroy .t1
} -result {. .t1}
test wm-stackorder-2.7 {stacking order: no children returns self} -setup {
    deleteWindows
} -body {
    wm stackorder .
} -result {.}

deleteWindows

test wm-stackorder-3.1 {unmapped toplevel} -constraints failsOnUbuntu -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm iconify .t1

    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t2}
test wm-stackorder-3.2 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm withdraw .t2

    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t1}
test wm-stackorder-3.3 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update







>















|



>








>







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
    raiseDelay
    wm stackorder .parent
} -cleanup {
    deleteWindows
} -result {.parent.child2 .parent.child1 .parent}
test wm-stackorder-2.6 {stacking order: non-toplevel widgets ignored} -body {
    toplevel .t1
    raiseDelay
    button .t1.b
    pack .t1.b
    update
    wm stackorder .
} -cleanup {
    destroy .t1
} -result {. .t1}
test wm-stackorder-2.7 {stacking order: no children returns self} -setup {
    deleteWindows
} -body {
    wm stackorder .
} -result {.}

deleteWindows

test wm-stackorder-3.1 {unmapped toplevel} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm iconify .t1
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t2}
test wm-stackorder-3.2 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm withdraw .t2
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t1}
test wm-stackorder-3.3 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
1455
1456
1457
1458
1459
1460
1461
1462

1463

1464

1465

1466
1467
1468
1469
1470
1471
1472
    toplevel .t1.t2 ; update
    wm withdraw .t1
    wm stackorder .t1
} -cleanup {
    destroy .t1
} -result {.t1.t2}
test wm-stackorder-3.6 {unmapped toplevel} -body {
    toplevel .t1 ; update

    toplevel .t1.t2 ; update

    toplevel .t1.t2.t3 ; update

    wm withdraw .t1.t2

    wm stackorder .t1
} -cleanup {
    destroy .t1
} -result {.t1 .t1.t2.t3}
test wm-stackorder-3.7 {unmapped toplevel, mapped children returned} -body {
    toplevel .t1 ; update
    toplevel .t1.t2 ; update







|
>
|
>
|
>

>







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
    toplevel .t1.t2 ; update
    wm withdraw .t1
    wm stackorder .t1
} -cleanup {
    destroy .t1
} -result {.t1.t2}
test wm-stackorder-3.6 {unmapped toplevel} -body {
    toplevel .t1
    tkwait visibility .t1
    toplevel .t1.t2
    tkwait visibility .t1.t2
    toplevel .t1.t2.t3
    tkwait visibility .t1.t2.t3
    wm withdraw .t1.t2
    raiseDelay
    wm stackorder .t1
} -cleanup {
    destroy .t1
} -result {.t1 .t1.t2.t3}
test wm-stackorder-3.7 {unmapped toplevel, mapped children returned} -body {
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
    toplevel .t ; update
    raise .t
    wm stackorder . isbelow .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-4.3 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update

    raise .
    raiseDelay
    wm stackorder .t isa .
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-4.4 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay







|
>


|







1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
    toplevel .t ; update
    raise .t
    wm stackorder . isbelow .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-4.3 {wm stackorder isabove|isbelow} -body {
    toplevel .t
    tkwait visibility .t
    raise .
    raiseDelay
    wm stackorder .t isabove .
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-4.4 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay
1526
1527
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569

1570
1571
1572
1573
1574
1575
1576
1577
1578
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-5.2 {A normal toplevel can't be raised above an \
    overrideredirect toplevel on unix} -constraints {x11 failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1

    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-5.2.1 {A normal toplevel can be raised above an \
    overrideredirect toplevel on macOS or win} -constraints aquaOrWin32 -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1

    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-5.3 {An overrideredirect window\
        can be explicitly lowered} -constraints failsOnXQuarz -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1

    lower .t
    update
    raiseDelay
    wm stackorder .t isbelow .
} -cleanup {
    destroy .t
} -result 1

test wm-stackorder-6.1 {An embedded toplevel does not appear in the \
	stacking order} -body {
    toplevel .real -container 1

    toplevel .embd -bg blue -use [winfo id .real]
    update
    wm stackorder .
} -cleanup {
    deleteWindows
} -result {. .real}

stdWindow








<

>










<

>








|

<

>









|

>

|







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
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-5.2 {A normal toplevel can't be raised above an \
    overrideredirect toplevel on unix} -constraints {x11 failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t

    wm overrideredirect .t 1
    tkwait visibility .t
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-5.2.1 {A normal toplevel can be raised above an \
    overrideredirect toplevel on macOS or win} -constraints aquaOrWin32 -body {
    toplevel .t

    wm overrideredirect .t 1
    tkwait visibility .t
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} -cleanup {
    destroy .t
} -result 1
test wm-stackorder-5.3 {An overrideredirect window\
        can be explicitly lowered} -body {
    toplevel .t

    wm overrideredirect .t 1
    tkwait visibility .t
    lower .t
    update
    raiseDelay
    wm stackorder .t isbelow .
} -cleanup {
    destroy .t
} -result 1

test wm-stackorder-6.1 {An embedded toplevel does not appear in the \
	 stacking order} -body {
    toplevel .real -container 1
    raiseDelay
    toplevel .embd -bg blue -use [winfo id .real]
    raiseDelay
    wm stackorder .
} -cleanup {
    deleteWindows
} -result {. .real}

stdWindow

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
    wm transient .subject .top
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.2 {already mapped transient toplevel
        is withdrawn if toplevel is iconic} -constraints failsOnUbuntu -body {
    toplevel .top
    raiseDelay
    wm iconify .top
    update idletasks
    toplevel .subject
    update idletasks
    wm transient .subject .top
    update idletasks
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.3 {iconify/deiconify on the toplevel
        does a withdraw/deiconify on the transient} -constraints failsOnUbuntu -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update idletasks
    wm transient .subject .top
    wm iconify .top







|













|







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
    wm transient .subject .top
    update
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.2 {already mapped transient toplevel
        is withdrawn if toplevel is iconic} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .top
    raiseDelay
    wm iconify .top
    update idletasks
    toplevel .subject
    update idletasks
    wm transient .subject .top
    update idletasks
    list [wm state .subject] [winfo ismapped .subject]
} -cleanup {
    deleteWindows
} -result {withdrawn 0}
test wm-transient-4.3 {iconify/deiconify on the toplevel
        does a withdraw/deiconify on the transient} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update idletasks
    wm transient .subject .top
    wm iconify .top
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
    # 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?"]
} -cleanup {
    deleteWindows
} -result {0 0 1 1 {.t1 .t2}}


### wm state ###







|







2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
    # 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; raiseDelay; update
    lappend result [lsearch -all -inline -glob [wm stackorder .] ".t?"]
} -cleanup {
    deleteWindows
} -result {0 0 1 1 {.t1 .t2}}


### wm state ###
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
test wm-state-2.7 {state change before map} -body {
    toplevel .t
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.8 {state change after map} -constraints failsOnUbuntu -body {
    toplevel .t
    update
    wm state .t iconic
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.9 {state change after map} -constraints failsOnUbuntu -body {
    toplevel .t
    update
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}







|







|







2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
test wm-state-2.7 {state change before map} -body {
    toplevel .t
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.8 {state change after map} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t
    update
    wm state .t iconic
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
test wm-state-2.9 {state change after map} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t
    update
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
} -cleanup {
    deleteWindows
} -result {}

test wm-forget-2 {bug [e9112ef96e] - [wm forget] doesn't completely} -setup {
    catch {destroy .l .f.b .f}
    set res {}
    if {[tk windowingsystem] == "aqua"} {
	proc doUpdate {} {update idletasks}
    } else {
	proc doUpdate {} {update}
    }
} -body {
    label .l -text "Top Dot"
    frame .f
    button .f.b -text Hello -command "puts Hello!"
    pack .l -side top
    pack .f.b
    pack .f -side bottom
    set res [winfo manager .f]
    pack forget .f
    doUpdate
    lappend res [winfo manager .f]
    wm manage .f
    doUpdate
    lappend res [winfo manager .f]
    wm forget .f
    doUpdate
    lappend res [winfo manager .f]
} -cleanup {
    destroy .l .f.b .f
    unset res
} -result {pack {} wm {}}

# FIXME:







<
<
<
<
<









|


|


|







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
} -cleanup {
    deleteWindows
} -result {}

test wm-forget-2 {bug [e9112ef96e] - [wm forget] doesn't completely} -setup {
    catch {destroy .l .f.b .f}
    set res {}





} -body {
    label .l -text "Top Dot"
    frame .f
    button .f.b -text Hello -command "puts Hello!"
    pack .l -side top
    pack .f.b
    pack .f -side bottom
    set res [winfo manager .f]
    pack forget .f
    update
    lappend res [winfo manager .f]
    wm manage .f
    update
    lappend res [winfo manager .f]
    wm forget .f
    update
    lappend res [winfo manager .f]
} -cleanup {
    destroy .l .f.b .f
    unset res
} -result {pack {} wm {}}

# FIXME:

Changes to tests/xmfbox.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# xmfbox.test --
#
#	This file is a Tcl script to test the file dialog that's used
#	when the tk_strictMotif flag is set. Because the file dialog
#	runs in a modal loop, the only way to test it sufficiently is
#	to call the internal Tcl procedures in xmfbox.tcl directly.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Contributions from Don Porter, NIST, 2002.  (not subject to US copyright)
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# xmfbox.test --
#
#	This file is a Tcl script to test the file dialog that's used
#	when the tk_strictMotif flag is set. Because the file dialog
#	runs in a modal loop, the only way to test it sufficiently is
#	to call the internal Tcl procedures in xmfbox.tcl directly.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    unix
} -body {
    cleanup
    file mkdir ./~nosuchuser1
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    set kk [tk::MotifFDialog_InterpFilter $x]
} -result "$testPWD/~nosuchuser1 *"

test xmfbox-2.2 {tk::MotifFDialog_InterpFilter, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    set kk [tk::MotifFDialog_InterpFilter $x]
} -result "$testPWD ./~nosuchuser1"

test xmfbox-2.3 {tk::MotifFDialog_Update, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]







|
|









|
|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    unix
} -body {
    cleanup
    file mkdir ./~nosuchuser1
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    file normalize [file join {*}[tk::MotifFDialog_InterpFilter $x]]
} -result "$testPWD/~nosuchuser1/*"

test xmfbox-2.2 {tk::MotifFDialog_InterpFilter, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    $::tk::dialog::file::foo(fEnt) delete 0 end
    $::tk::dialog::file::foo(fEnt) insert 0 [pwd]/~nosuchuser1
    file normalize [file join {*}[tk::MotifFDialog_InterpFilter $x]]
} -result "$testPWD/~nosuchuser1"

test xmfbox-2.3 {tk::MotifFDialog_Update, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    $::tk::dialog::file::foo(sEnt) get
} -result "$testPWD/~nosuchuser1"

test xmfbox-2.6 {tk::MotifFDialog_ActivateFList, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    tk::MotifFDialog_ActivateFList $x
    list $::tk::dialog::file::foo(selectPath) \
	    $::tk::dialog::file::foo(selectFile) $tk::Priv(selectFilePath)
} -result "$testPWD ~nosuchuser1 $testPWD/~nosuchuser1"

# cleanup
cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:







|














|










134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    file normalize [$::tk::dialog::file::foo(sEnt) get]
} -result "$testPWD/~nosuchuser1"

test xmfbox-2.6 {tk::MotifFDialog_ActivateFList, ~ in file names} -constraints {
    unix
} -body {
    cleanup
    close [open ./~nosuchuser1 {CREAT TRUNC WRONLY}]
    set x [tk::MotifFDialog_Create foo open {}]
    set i [lsearch [$::tk::dialog::file::foo(fList) get 0 end] ~nosuchuser1]
    $::tk::dialog::file::foo(fList) selection clear 0 end
    $::tk::dialog::file::foo(fList) selection set $i
    tk::MotifFDialog_BrowseFList $x
    tk::MotifFDialog_ActivateFList $x
    list $::tk::dialog::file::foo(selectPath) \
	    $::tk::dialog::file::foo(selectFile) [file normalize $tk::Priv(selectFilePath)]
} -result "$testPWD ~nosuchuser1 $testPWD/~nosuchuser1"

# cleanup
cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to unix/Makefile.in.

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# appropriate for this version of Tk:
TCL_PLATFORM_DIR	= $(TCLDIR)/unix

# The directory containing the Tcl library archive file appropriate
# for this version of Tk:
TCL_BIN_DIR		= @TCL_BIN_DIR@

# The linker flags needed to link in the Tcl library (ex: -ltcl8.2)
TCL_LIB_FLAG		= @TCL_LIB_FLAG@

# Flag, 1: we're building a shared lib, 0 we're not
TK_SHARED_BUILD		= @TK_SHARED_BUILD@

# Subdirectory of $(libdir) containing the pkgIndex.tcl file for loadable Tk
TK_PKG_DIR		= @TK_PKG_DIR@







|







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# appropriate for this version of Tk:
TCL_PLATFORM_DIR	= $(TCLDIR)/unix

# The directory containing the Tcl library archive file appropriate
# for this version of Tk:
TCL_BIN_DIR		= @TCL_BIN_DIR@

# The linker flags needed to link in the Tcl library (ex: -ltcl9.0)
TCL_LIB_FLAG		= @TCL_LIB_FLAG@

# Flag, 1: we're building a shared lib, 0 we're not
TK_SHARED_BUILD		= @TK_SHARED_BUILD@

# Subdirectory of $(libdir) containing the pkgIndex.tcl file for loadable Tk
TK_PKG_DIR		= @TK_PKG_DIR@
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# XStringToKeysym is plenty fast, so you needn't define REDO_KEYSYM_LOOKUP.
KEYSYM_FLAGS		=
#KEYSYM_FLAGS		= -DREDO_KEYSYM_LOOKUP

# Tk does not used deprecated Tcl constructs so it should
# compile fine with -DTCL_NO_DEPRECATED. To remove its own
# set of deprecated code uncomment the second line.
NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# Some versions of make, like SGI's, use the following variable to
# determine which shell to use for executing commands:
SHELL			= @SHELL@

# BUILD_TCLSH is the fully qualified path name of the tclsh shell







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# XStringToKeysym is plenty fast, so you needn't define REDO_KEYSYM_LOOKUP.
KEYSYM_FLAGS		=
#KEYSYM_FLAGS		= -DREDO_KEYSYM_LOOKUP

# Tk does not used deprecated Tcl constructs so it should
# compile fine with -DTCL_NO_DEPRECATED. To remove its own
# set of deprecated code uncomment the second line.
NO_DEPRECATED_FLAGS	=
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# Some versions of make, like SGI's, use the following variable to
# determine which shell to use for executing commands:
SHELL			= @SHELL@

# BUILD_TCLSH is the fully qualified path name of the tclsh shell
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
TKTEST_EXE		= tktest${EXE_SUFFIX}

# Tk used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
# "install" around;  better to use the install-sh script that comes
# with the distribution, which is slower but guaranteed to work.

INSTALL_STRIP_PROGRAM   = -s
INSTALL_STRIP_LIBRARY   = -S -x

INSTALL			= $(SHELL) $(UNIX_DIR)/install-sh -c
INSTALL_PROGRAM		= ${INSTALL}
INSTALL_LIBRARY		= ${INSTALL}
INSTALL_DATA		= ${INSTALL} -m 644
INSTALL_DATA_DIR	= ${INSTALL} -d -m 755








|
|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
TKTEST_EXE		= tktest${EXE_SUFFIX}

# Tk used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
# "install" around;  better to use the install-sh script that comes
# with the distribution, which is slower but guaranteed to work.

INSTALL_STRIP_PROGRAM	= strip
INSTALL_STRIP_LIBRARY	= strip -x

INSTALL			= $(SHELL) $(UNIX_DIR)/install-sh -c
INSTALL_PROGRAM		= ${INSTALL}
INSTALL_LIBRARY		= ${INSTALL}
INSTALL_DATA		= ${INSTALL} -m 644
INSTALL_DATA_DIR	= ${INSTALL} -d -m 755

243
244
245
246
247
248
249


250
251
252
253
254
255
256
# Generic stub lib name used in rules that apply to tcl and tk
STUB_LIB_FILE		= ${TK_STUB_LIB_FILE}

TK_STUB_LIB_FLAG	= @TK_STUB_LIB_FLAG@
#TK_STUB_LIB_FLAG	= -ltkstub

TK_LIB_FILE		= @TK_LIB_FILE@


#TK_LIB_FILE		= libtk.a

# Generic lib name used in rules that apply to tcl and tk
LIB_FILE		= ${TK_LIB_FILE}

TK_LIB_FLAG		= @TK_LIB_FLAG@
#TK_LIB_FLAG		= -ltk







>
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# Generic stub lib name used in rules that apply to tcl and tk
STUB_LIB_FILE		= ${TK_STUB_LIB_FILE}

TK_STUB_LIB_FLAG	= @TK_STUB_LIB_FLAG@
#TK_STUB_LIB_FLAG	= -ltkstub

TK_LIB_FILE		= @TK_LIB_FILE@
TK_LIB_FILE_TCL8	= @TK_LIB_FILE_TCL8@
TK_LIB_FILE_TCL9	= @TK_LIB_FILE_TCL9@
#TK_LIB_FILE		= libtk.a

# Generic lib name used in rules that apply to tcl and tk
LIB_FILE		= ${TK_LIB_FILE}

TK_LIB_FLAG		= @TK_LIB_FLAG@
#TK_LIB_FLAG		= -ltk
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# Additional search flags needed to find the various shared libraries
# at run-time.  The first symbol is for use when creating a binary
# with cc, and the second is for use when running ld directly.
CC_SEARCH_FLAGS	= @CC_SEARCH_FLAGS@
LD_SEARCH_FLAGS	= @LD_SEARCH_FLAGS@

# support for embedded libraries on Darwin / Mac OS X
DYLIB_INSTALL_DIR	= ${LIB_RUNTIME_DIR}

# support for building the Aqua resource file
TK_RSRC_FILE		= @TK_RSRC_FILE@
WISH_RSRC_FILE		= @WISH_RSRC_FILE@
REZ			= @REZ@
REZ_SWITCHES = @REZ_FLAGS@ -i $(GENERIC_DIR) -i $(TCL_GENERIC_DIR)








|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# Additional search flags needed to find the various shared libraries
# at run-time.  The first symbol is for use when creating a binary
# with cc, and the second is for use when running ld directly.
CC_SEARCH_FLAGS	= @CC_SEARCH_FLAGS@
LD_SEARCH_FLAGS	= @LD_SEARCH_FLAGS@

# support for embedded libraries on Darwin / Mac OS X
DYLIB_INSTALL_DIR	= $(libdir)

# support for building the Aqua resource file
TK_RSRC_FILE		= @TK_RSRC_FILE@
WISH_RSRC_FILE		= @WISH_RSRC_FILE@
REZ			= @REZ@
REZ_SWITCHES = @REZ_FLAGS@ -i $(GENERIC_DIR) -i $(TCL_GENERIC_DIR)

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462


463
464
465
466
467
468
469
470
471

CC			= @CC@

CC_SWITCHES_NO_STUBS = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} ${CFLAGS_WARNING} \
${SHLIB_CFLAGS} -I${TCL_GENERIC_DIR} -I${TCL_PLATFORM_DIR} ${AC_FLAGS} \
${PROTO_FLAGS} ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \
${NO_DEPRECATED_FLAGS} @EXTRA_CC_SWITCHES@

CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @TCL_STUB_FLAGS@

APP_CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @EXTRA_APP_CC_SWITCHES@

DEPEND_SWITCHES = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} -I${TCL_GENERIC_DIR} \
-I${TCL_PLATFORM_DIR} ${AC_FLAGS} ${PROTO_FLAGS} ${SECURITY_FLAGS} \
${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} @EXTRA_CC_SWITCHES@

WISH_OBJS = tkAppInit.o

TKTEST_OBJS = tkTestInit.o tkTest.o tkSquare.o tkOldTest.o \
	$(@TK_WINDOWINGSYSTEM@_TKTEST_OBJS)

WIDG_OBJS = tkButton.o tkEntry.o tkFrame.o tkListbox.o \
	tkMenu.o tkMenubutton.o tkMenuDraw.o tkMessage.o \
	tkPanedWindow.o tkScale.o tkScrollbar.o

CANV_OBJS = tkCanvas.o tkCanvArc.o tkCanvBmap.o tkCanvImg.o \
	tkCanvLine.o tkCanvPoly.o tkCanvPs.o tkCanvText.o \
	tkCanvUtil.o tkCanvWind.o tkRectOval.o tkTrig.o

IMAGE_OBJS = tkImage.o tkImgBmap.o tkImgGIF.o tkImgPNG.o tkImgPPM.o \
	tkImgPhoto.o tkImgPhInstance.o tkImgListFormat.o tkImgSVGnano.o

TEXT_OBJS = tkText.o tkTextBTree.o tkTextDisp.o tkTextImage.o tkTextIndex.o \
	tkTextMark.o tkTextTag.o tkTextWind.o


# either tkUnixFont.o (default) or tkUnixRFont.o (if --enable-xft)
#
FONT_OBJS = @UNIX_FONT_OBJS@

GENERIC_OBJS = tk3d.o tkArgv.o tkAtom.o tkBind.o tkBitmap.o tkBusy.o \
	tkClipboard.o \
	tkCmds.o tkColor.o tkConfig.o tkConsole.o tkCursor.o tkError.o \
	tkEvent.o tkFocus.o tkFont.o tkGet.o tkGC.o tkGeometry.o tkGrab.o \
	tkGrid.o tkMain.o tkObj.o tkOldConfig.o tkOption.o tkPack.o \
	tkPkgConfig.o tkPlace.o	tkSelect.o tkStyle.o tkUndo.o tkUtil.o \
	tkVisual.o tkWindow.o

TTK_OBJS = \
	ttkBlink.o ttkButton.o ttkCache.o ttkClamTheme.o ttkClassicTheme.o \
	ttkDefaultTheme.o ttkElements.o ttkEntry.o ttkFrame.o ttkImage.o \
	ttkInit.o ttkLabel.o ttkLayout.o ttkManager.o ttkNotebook.o \
	ttkPanedwindow.o ttkProgress.o ttkScale.o ttkScrollbar.o ttkScroll.o \
	ttkSeparator.o ttkSquare.o ttkState.o \
	ttkTagSet.o ttkTheme.o ttkTrace.o ttkTrack.o ttkTreeview.o \
	ttkWidget.o ttkStubInit.o

STUB_OBJS = tkStubInit.o

STUB_LIB_OBJS = tkStubLib.o ttkStubLib.o

X11_OBJS = tkUnix.o tkUnix3d.o tkUnixButton.o tkUnixColor.o tkUnixConfig.o \
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o \
	tkUnixFocus.o  $(FONT_OBJS) tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.o \
	tkUnixSend.o tkUnixWm.o tkUnixXId.o

AQUA_OBJS = tkMacOSXBitmap.o tkMacOSXButton.o tkMacOSXClipboard.o \
	tkMacOSXColor.o tkMacOSXConfig.o tkMacOSXCursor.o tkMacOSXDebug.o \
	tkMacOSXDialog.o tkMacOSXDraw.o tkMacOSXEmbed.o tkMacOSXEntry.o \
	tkMacOSXEvent.o tkMacOSXFont.o tkMacOSXHLEvents.o tkMacOSXImage.o \
	tkMacOSXInit.o tkMacOSXKeyboard.o tkMacOSXKeyEvent.o \
	tkMacOSXMenu.o \
	tkMacOSXMenubutton.o tkMacOSXMenus.o tkMacOSXMouseEvent.o \
	tkMacOSXNotify.o tkMacOSXRegion.o tkMacOSXScrlbr.o tkMacOSXSend.o \
	tkMacOSXServices.o tkMacOSXSubwindows.o tkMacOSXWindowEvent.o \
	tkMacOSXWm.o tkMacOSXXStubs.o \
	tkFileFilter.o tkMacWinMenu.o tkPointer.o tkUnix3d.o tkUnixScale.o \
	xcolors.o xdraw.o xgc.o ximage.o xutil.o \
	ttkMacOSXTheme.o

AQUA_TKTEST_OBJS = tkMacOSXTest.o

OBJS =  $(GENERIC_OBJS) $(WIDG_OBJS) $(CANV_OBJS) $(IMAGE_OBJS) $(TEXT_OBJS) \
	$(STUB_OBJS) $(TTK_OBJS) \
	$(@TK_WINDOWINGSYSTEM@_OBJS) @PLAT_OBJS@

TK_DECLS = \
	$(GENERIC_DIR)/tk.decls \
	$(GENERIC_DIR)/tkInt.decls

TTK_DECLS = \
	$(TTK_DIR)/ttk.decls

GENERIC_SRCS = \
	$(GENERIC_DIR)/tk3d.c $(GENERIC_DIR)/tkArgv.c \
	$(GENERIC_DIR)/tkAtom.c $(GENERIC_DIR)/tkBind.c	\
	$(GENERIC_DIR)/tkBitmap.c $(GENERIC_DIR)/tkBusy.c \
	$(GENERIC_DIR)/tkClipboard.c \
	$(GENERIC_DIR)/tkCmds.c $(GENERIC_DIR)/tkColor.c \
	$(GENERIC_DIR)/tkConfig.c $(GENERIC_DIR)/tkCursor.c \
	$(GENERIC_DIR)/tkError.c $(GENERIC_DIR)/tkEvent.c \
	$(GENERIC_DIR)/tkFocus.c $(GENERIC_DIR)/tkFont.c \
	$(GENERIC_DIR)/tkGet.c $(GENERIC_DIR)/tkGC.c \
	$(GENERIC_DIR)/tkGeometry.c $(GENERIC_DIR)/tkGrab.c \
	$(GENERIC_DIR)/tkGrid.c $(GENERIC_DIR)/tkConsole.c \

	$(GENERIC_DIR)/tkMain.c $(GENERIC_DIR)/tkOption.c \
	$(GENERIC_DIR)/tkPack.c $(GENERIC_DIR)/tkPlace.c \
	$(GENERIC_DIR)/tkPkgConfig.c \
	$(GENERIC_DIR)/tkSelect.c $(GENERIC_DIR)/tkStyle.c \
	$(GENERIC_DIR)/tkUndo.c $(GENERIC_DIR)/tkUtil.c \
	$(GENERIC_DIR)/tkVisual.c $(GENERIC_DIR)/tkWindow.c \
	$(GENERIC_DIR)/tkButton.c $(GENERIC_DIR)/tkObj.c \
	$(GENERIC_DIR)/tkEntry.c $(GENERIC_DIR)/tkFrame.c \
	$(GENERIC_DIR)/tkListbox.c $(GENERIC_DIR)/tkMenu.c \
	$(GENERIC_DIR)/tkMenubutton.c $(GENERIC_DIR)/tkMenuDraw.c \
	$(GENERIC_DIR)/tkMessage.c $(GENERIC_DIR)/tkPanedWindow.c \
	$(GENERIC_DIR)/tkScale.c $(GENERIC_DIR)/tkScrollbar.c \
	$(GENERIC_DIR)/tkCanvas.c $(GENERIC_DIR)/tkCanvArc.c \
	$(GENERIC_DIR)/tkCanvBmap.c $(GENERIC_DIR)/tkCanvImg.c \
	$(GENERIC_DIR)/tkCanvLine.c $(GENERIC_DIR)/tkCanvPoly.c \
	$(GENERIC_DIR)/tkCanvPs.c $(GENERIC_DIR)/tkCanvText.c \
	$(GENERIC_DIR)/tkCanvUtil.c \
	$(GENERIC_DIR)/tkCanvWind.c $(GENERIC_DIR)/tkRectOval.c \
	$(GENERIC_DIR)/tkTrig.c $(GENERIC_DIR)/tkImage.c \
	$(GENERIC_DIR)/tkImgBmap.c $(GENERIC_DIR)/tkImgGIF.c \
	$(GENERIC_DIR)/tkImgPNG.c $(GENERIC_DIR)/tkImgPPM.c \
	$(GENERIC_DIR)/tkImgSVGnano.c $(GENERIC_DIR)/tkImgSVGnano.c \
	$(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkImgPhInstance.c \
	$(GENERIC_DIR)/tkImgListFormat.c $(GENERIC_DIR)/tkText.c \
	$(GENERIC_DIR)/tkTextBTree.c $(GENERIC_DIR)/tkTextDisp.c \
	$(GENERIC_DIR)/tkTextImage.c \
	$(GENERIC_DIR)/tkTextIndex.c $(GENERIC_DIR)/tkTextMark.c \


	$(GENERIC_DIR)/tkTextTag.c $(GENERIC_DIR)/tkTextWind.c \
	$(GENERIC_DIR)/tkOldConfig.c $(GENERIC_DIR)/tkOldTest.c \
	$(GENERIC_DIR)/tkSquare.c $(GENERIC_DIR)/tkTest.c \
	$(GENERIC_DIR)/tkStubInit.c

TTK_SRCS = \
	$(TTK_DIR)/ttkBlink.c \
	$(TTK_DIR)/ttkButton.c \
	$(TTK_DIR)/ttkCache.c \







|












|













|
|
>





|
<
|
|
|
|
|















|


|




|
|
|
|
|
|
<
|
|


















|
|







>




|


















|
|
|
|
>
>
|
|







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

CC			= @CC@

CC_SWITCHES_NO_STUBS = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} ${CFLAGS_WARNING} \
${SHLIB_CFLAGS} -I${TCL_GENERIC_DIR} -I${TCL_PLATFORM_DIR} ${AC_FLAGS} \
${PROTO_FLAGS} ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \
${NO_DEPRECATED_FLAGS} -DTCL_UTF_MAX=4 @EXTRA_CC_SWITCHES@

CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @TCL_STUB_FLAGS@

APP_CC_SWITCHES = $(CC_SWITCHES_NO_STUBS) @EXTRA_APP_CC_SWITCHES@

DEPEND_SWITCHES = -I${UNIX_DIR} -I${GENERIC_DIR} -I${BMAP_DIR} \
${@TK_WINDOWINGSYSTEM@_INCLUDES} ${CFLAGS} -I${TCL_GENERIC_DIR} \
-I${TCL_PLATFORM_DIR} ${AC_FLAGS} ${PROTO_FLAGS} ${SECURITY_FLAGS} \
${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} @EXTRA_CC_SWITCHES@

WISH_OBJS = tkAppInit.o

TKTEST_OBJS = tkTestInit.o tkTest.o tkSquare.o \
	$(@TK_WINDOWINGSYSTEM@_TKTEST_OBJS)

WIDG_OBJS = tkButton.o tkEntry.o tkFrame.o tkListbox.o \
	tkMenu.o tkMenubutton.o tkMenuDraw.o tkMessage.o \
	tkPanedWindow.o tkScale.o tkScrollbar.o

CANV_OBJS = tkCanvas.o tkCanvArc.o tkCanvBmap.o tkCanvImg.o \
	tkCanvLine.o tkCanvPoly.o tkCanvPs.o tkCanvText.o \
	tkCanvUtil.o tkCanvWind.o tkRectOval.o tkTrig.o

IMAGE_OBJS = tkImage.o tkImgBmap.o tkImgGIF.o tkImgPNG.o tkImgPPM.o \
	tkImgPhoto.o tkImgPhInstance.o tkImgListFormat.o tkImgSVGnano.o

TEXT_OBJS = tkText.o tkTextBTree.o tkTextDisp.o tkTextImage.o \
	tkTextIndex.o tkTextLineBreak.o tkTextMark.o tkTextTag.o \
	tkTextTagSet.o tkTextUndo.o tkTextWind.o

# either tkUnixFont.o (default) or tkUnixRFont.o (if --enable-xft)
#
FONT_OBJS = @UNIX_FONT_OBJS@

GENERIC_OBJS = tk3d.o tkArgv.o tkAtom.o tkBind.o tkBitmap.o tkBitField.o \

	tkBusy.o tkClipboard.o tkCmds.o tkColor.o tkConfig.o tkConsole.o \
	tkCursor.o tkError.o tkEvent.o tkFocus.o tkFont.o tkGet.o tkGC.o \
	tkGeometry.o tkGrab.o tkGrid.o tkIntSet.o tkMain.o tkObj.o tkOldConfig.o \
	tkOption.o tkPack.o tkPkgConfig.o tkPlace.o tkRangeList.o tkSelect.o \
	tkStyle.o tkUtil.o tkVisual.o tkWindow.o

TTK_OBJS = \
	ttkBlink.o ttkButton.o ttkCache.o ttkClamTheme.o ttkClassicTheme.o \
	ttkDefaultTheme.o ttkElements.o ttkEntry.o ttkFrame.o ttkImage.o \
	ttkInit.o ttkLabel.o ttkLayout.o ttkManager.o ttkNotebook.o \
	ttkPanedwindow.o ttkProgress.o ttkScale.o ttkScrollbar.o ttkScroll.o \
	ttkSeparator.o ttkSquare.o ttkState.o \
	ttkTagSet.o ttkTheme.o ttkTrace.o ttkTrack.o ttkTreeview.o \
	ttkWidget.o ttkStubInit.o

STUB_OBJS = tkStubInit.o

STUB_LIB_OBJS = tkStubLib.o ttkStubLib.o

X11_OBJS = tkUnix.o tkUnix3d.o tkUnixButton.o tkUnixColor.o tkUnixConfig.o \
	tkUnixCursor.o tkUnixDraw.o tkUnixEmbed.o tkUnixEvent.o tkIcu.o \
	tkUnixFocus.o  $(FONT_OBJS) tkUnixInit.o tkUnixKey.o tkUnixMenu.o \
	tkUnixMenubu.o tkUnixScale.o tkUnixScrlbr.o tkUnixSelect.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 tkMacOSXFileTypes.o tkMacOSXFont.o tkMacOSXHLEvents.o \
        tkMacOSXImage.o tkMacOSXInit.o tkMacOSXKeyboard.o tkMacOSXKeyEvent.o \
	tkMacOSXMenu.o tkMacOSXMenubutton.o tkMacOSXMenus.o \
        tkMacOSXMouseEvent.o tkMacOSXNotify.o tkMacOSXPrint.o tkMacOSXRegion.o \
	tkMacOSXScrlbr.o tkMacOSXSend.o tkMacOSXServices.o \
	tkMacOSXSubwindows.o tkMacOSXSysTray.o tkMacOSXWindowEvent.o tkMacOSXWm.o \

	tkMacOSXXStubs.o tkFileFilter.o tkMacWinMenu.o tkPointer.o tkUnix3d.o \
	tkUnixScale.o xcolors.o xdraw.o xgc.o ximage.o xutil.o \
	ttkMacOSXTheme.o

AQUA_TKTEST_OBJS = tkMacOSXTest.o

OBJS =  $(GENERIC_OBJS) $(WIDG_OBJS) $(CANV_OBJS) $(IMAGE_OBJS) $(TEXT_OBJS) \
	$(STUB_OBJS) $(TTK_OBJS) \
	$(@TK_WINDOWINGSYSTEM@_OBJS) @PLAT_OBJS@

TK_DECLS = \
	$(GENERIC_DIR)/tk.decls \
	$(GENERIC_DIR)/tkInt.decls

TTK_DECLS = \
	$(TTK_DIR)/ttk.decls

GENERIC_SRCS = \
	$(GENERIC_DIR)/tk3d.c $(GENERIC_DIR)/tkArgv.c \
	$(GENERIC_DIR)/tkAtom.c $(GENERIC_DIR)/tkBind.c	\
	$(GENERIC_DIR)/tkBitField.c $(GENERIC_DIR)/tkBitmap.c \
	$(GENERIC_DIR)/tkBusy.c $(GENERIC_DIR)/tkClipboard.c \
	$(GENERIC_DIR)/tkCmds.c $(GENERIC_DIR)/tkColor.c \
	$(GENERIC_DIR)/tkConfig.c $(GENERIC_DIR)/tkCursor.c \
	$(GENERIC_DIR)/tkError.c $(GENERIC_DIR)/tkEvent.c \
	$(GENERIC_DIR)/tkFocus.c $(GENERIC_DIR)/tkFont.c \
	$(GENERIC_DIR)/tkGet.c $(GENERIC_DIR)/tkGC.c \
	$(GENERIC_DIR)/tkGeometry.c $(GENERIC_DIR)/tkGrab.c \
	$(GENERIC_DIR)/tkGrid.c $(GENERIC_DIR)/tkConsole.c \
	$(GENERIC_DIR)/tkIntSet.c \
	$(GENERIC_DIR)/tkMain.c $(GENERIC_DIR)/tkOption.c \
	$(GENERIC_DIR)/tkPack.c $(GENERIC_DIR)/tkPlace.c \
	$(GENERIC_DIR)/tkPkgConfig.c \
	$(GENERIC_DIR)/tkSelect.c $(GENERIC_DIR)/tkStyle.c \
	$(GENERIC_DIR)/tkUtil.c \
	$(GENERIC_DIR)/tkVisual.c $(GENERIC_DIR)/tkWindow.c \
	$(GENERIC_DIR)/tkButton.c $(GENERIC_DIR)/tkObj.c \
	$(GENERIC_DIR)/tkEntry.c $(GENERIC_DIR)/tkFrame.c \
	$(GENERIC_DIR)/tkListbox.c $(GENERIC_DIR)/tkMenu.c \
	$(GENERIC_DIR)/tkMenubutton.c $(GENERIC_DIR)/tkMenuDraw.c \
	$(GENERIC_DIR)/tkMessage.c $(GENERIC_DIR)/tkPanedWindow.c \
	$(GENERIC_DIR)/tkScale.c $(GENERIC_DIR)/tkScrollbar.c \
	$(GENERIC_DIR)/tkCanvas.c $(GENERIC_DIR)/tkCanvArc.c \
	$(GENERIC_DIR)/tkCanvBmap.c $(GENERIC_DIR)/tkCanvImg.c \
	$(GENERIC_DIR)/tkCanvLine.c $(GENERIC_DIR)/tkCanvPoly.c \
	$(GENERIC_DIR)/tkCanvPs.c $(GENERIC_DIR)/tkCanvText.c \
	$(GENERIC_DIR)/tkCanvUtil.c \
	$(GENERIC_DIR)/tkCanvWind.c $(GENERIC_DIR)/tkRectOval.c \
	$(GENERIC_DIR)/tkTrig.c $(GENERIC_DIR)/tkImage.c \
	$(GENERIC_DIR)/tkImgBmap.c $(GENERIC_DIR)/tkImgGIF.c \
	$(GENERIC_DIR)/tkImgPNG.c $(GENERIC_DIR)/tkImgPPM.c \
	$(GENERIC_DIR)/tkImgSVGnano.c $(GENERIC_DIR)/tkImgSVGnano.c \
	$(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkImgPhInstance.c \
	$(GENERIC_DIR)/tkImgListFormat.c $(GENERIC_DIR)/tkRangeList.c \
	$(GENERIC_DIR)/tkText.c $(GENERIC_DIR)/tkTextBTree.c \
	$(GENERIC_DIR)/tkTextDisp.c $(GENERIC_DIR)/tkTextImage.c \
	$(GENERIC_DIR)/tkTextIndex.c $(GENERIC_DIR)/tkTextLineBreak.c \
	$(GENERIC_DIR)/tkTextMark.c $(GENERIC_DIR)/tkTextTag.c \
	$(GENERIC_DIR)/tkTextTagSet.c $(GENERIC_DIR)/tkTextUndo.c \
	$(GENERIC_DIR)/tkTextWind.c \
	$(GENERIC_DIR)/tkOldConfig.c \
	$(GENERIC_DIR)/tkSquare.c $(GENERIC_DIR)/tkTest.c \
	$(GENERIC_DIR)/tkStubInit.c

TTK_SRCS = \
	$(TTK_DIR)/ttkBlink.c \
	$(TTK_DIR)/ttkButton.c \
	$(TTK_DIR)/ttkCache.c \
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545






















546
547
548
549
550
551
552
553
554
555
556
557
558
559

560
561
562
563
564
565
566
	$(UNIX_DIR)/tkAppInit.c $(UNIX_DIR)/tkUnix.c \
	$(UNIX_DIR)/tkUnix3d.c \
	$(UNIX_DIR)/tkUnixButton.c $(UNIX_DIR)/tkUnixColor.c \
	$(UNIX_DIR)/tkUnixConfig.c \
	$(UNIX_DIR)/tkUnixCursor.c \
	$(UNIX_DIR)/tkUnixDraw.c \
	$(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

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)/tkMacOSXSend.c $(MAC_OSX_DIR)/tkMacOSXSubwindows.c \
	$(MAC_OSX_DIR)/tkMacOSXTest.c $(MAC_OSX_DIR)/tkMacOSXWindowEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXWm.c $(MAC_OSX_DIR)/tkMacOSXXStubs.c \
	$(GENERIC_DIR)/tkFileFilter.c $(GENERIC_DIR)/tkMacWinMenu.c \
	$(GENERIC_DIR)/tkPointer.c $(UNIX_DIR)/tkUnix3d.c \
	$(UNIX_DIR)/tkUnixScale.c $(XLIB_DIR)/xcolors.c $(XLIB_DIR)/xdraw.c \
	$(XLIB_DIR)/xgc.c $(XLIB_DIR)/ximage.c $(XLIB_DIR)/xutil.c \
	$(TTK_DIR)/ttkMacOSXTheme.c

SRCS = $(GENERIC_SRCS) $(@TK_WINDOWINGSYSTEM@_SRCS) @PLAT_SRCS@























AQUA_RESOURCES = \
	$(MAC_OSX_DIR)/tkAboutDlg.r $(MAC_OSX_DIR)/tkMacOSXCursors.r \
	$(MAC_OSX_DIR)/tkMacOSXXCursors.r

AQUA_WISH_RESOURCES = $(MAC_OSX_DIR)/tkMacOSXAETE.r

AQUA_HDRS = $(MAC_OSX_DIR)/tkMacOSX.h $(GENERIC_DIR)/tkIntXlibDecls.h

AQUA_XLIB_HDRS = $(XLIB_DIR)/X11/*.h $(XLIB_DIR)/xbytes.h

AQUA_PRIVATE_HDRS = $(MAC_OSX_DIR)/tkMacOSXPort.h $(MAC_OSX_DIR)/tkMacOSXInt.h

X11_PRIVATE_HDRS = $(UNIX_DIR)/tkUnixPort.h $(UNIX_DIR)/tkUnixInt.h $(GENERIC_DIR)/tkIntXlibDecls.h


# Currently private, eventually public
TTK_HDRS = $(TTK_DIR)/ttkTheme.h $(TTK_DIR)/ttkDecls.h

PUBLIC_HDRS = $(GENERIC_DIR)/tk.h $(GENERIC_DIR)/tkDecls.h \
	$(GENERIC_DIR)/tkPlatDecls.h $(@TK_WINDOWINGSYSTEM@_HDRS)








|





|
|
|








|
|






|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|
>







507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
	$(UNIX_DIR)/tkAppInit.c $(UNIX_DIR)/tkUnix.c \
	$(UNIX_DIR)/tkUnix3d.c \
	$(UNIX_DIR)/tkUnixButton.c $(UNIX_DIR)/tkUnixColor.c \
	$(UNIX_DIR)/tkUnixConfig.c \
	$(UNIX_DIR)/tkUnixCursor.c \
	$(UNIX_DIR)/tkUnixDraw.c \
	$(UNIX_DIR)/tkUnixEmbed.c $(UNIX_DIR)/tkUnixEvent.c \
	$(UNIX_DIR)/tkUnixFocus.c $(GENERIC_DIR)/tkIcu.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)/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)/tkMacOSXFileTypes.c\
	$(MAC_OSX_DIR)/tkMacOSXHLEvents.c $(MAC_OSX_DIR)/tkMacOSXImage.c \
	$(MAC_OSX_DIR)/tkMacOSXInit.c $(MAC_OSX_DIR)/tkMacOSXKeyboard.c \
	$(MAC_OSX_DIR)/tkMacOSXKeyEvent.c \
	$(MAC_OSX_DIR)/tkMacOSXMenu.c \
	$(MAC_OSX_DIR)/tkMacOSXMenubutton.c $(MAC_OSX_DIR)/tkMacOSXMenus.c \
	$(MAC_OSX_DIR)/tkMacOSXMouseEvent.c $(MAC_OSX_DIR)/tkMacOSXNotify.c \
	$(MAC_OSX_DIR)/tkMacOSXRegion.c $(MAC_OSX_DIR)/tkMacOSXScrlbr.c \
	$(MAC_OSX_DIR)/tkMacOSXServices.c $(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 \
	$(TTK_DIR)/ttkMacOSXTheme.c

SRCS = $(GENERIC_SRCS) $(@TK_WINDOWINGSYSTEM@_SRCS) @PLAT_SRCS@

###
# Tip 430 - ZipFS Modifications
###

TK_ZIP_FILE		= @TK_ZIP_FILE@
TK_VFS_ROOT		= libtk.vfs
TK_VFS_PATH		= ${TK_VFS_ROOT}/tk_library

HOST_CC			= @CC_FOR_BUILD@
HOST_EXEEXT		= @EXEEXT_FOR_BUILD@
HOST_OBJEXT		= @OBJEXT_FOR_BUILD@
ZIPFS_BUILD		= @ZIPFS_BUILD@
NATIVE_ZIP		= @ZIP_PROG@
ZIP_PROG_OPTIONS	= @ZIP_PROG_OPTIONS@
ZIP_PROG_VFSSEARCH	= @ZIP_PROG_VFSSEARCH@
SHARED_BUILD		= @SHARED_BUILD@
INSTALL_LIBRARIES	= @INSTALL_LIBRARIES@
INSTALL_MSGS		= @INSTALL_MSGS@

ZIP_INSTALL_OBJS	= @ZIP_INSTALL_OBJS@


AQUA_RESOURCES = \
	$(MAC_OSX_DIR)/tkAboutDlg.r $(MAC_OSX_DIR)/tkMacOSXCursors.r \
	$(MAC_OSX_DIR)/tkMacOSXXCursors.r

AQUA_WISH_RESOURCES = $(MAC_OSX_DIR)/tkMacOSXAETE.r

AQUA_HDRS = $(MAC_OSX_DIR)/tkMacOSX.h $(GENERIC_DIR)/tkIntXlibDecls.h

AQUA_XLIB_HDRS = $(XLIB_DIR)/X11/*.h $(XLIB_DIR)/xbytes.h

AQUA_PRIVATE_HDRS = $(MAC_OSX_DIR)/tkMacOSXPort.h $(MAC_OSX_DIR)/tkMacOSXInt.h

X11_PRIVATE_HDRS = $(UNIX_DIR)/tkUnixPort.h $(UNIX_DIR)/tkUnixInt.h $(GENERIC_DIR)/tkIntXlibDecls.h \
	$(UNIX_DIR)/tkUnixDefault.h

# Currently private, eventually public
TTK_HDRS = $(TTK_DIR)/ttkTheme.h $(TTK_DIR)/ttkDecls.h

PUBLIC_HDRS = $(GENERIC_DIR)/tk.h $(GENERIC_DIR)/tkDecls.h \
	$(GENERIC_DIR)/tkPlatDecls.h $(@TK_WINDOWINGSYSTEM@_HDRS)

579
580
581
582
583
584
585


























586
587
588
589
590









591
592
593
594
595
596
597
598
599
600
601
602

all: binaries libraries

binaries: ${LIB_FILE} ${WISH_EXE}

libraries:



























# The following target is configured by autoconf to generate either
# a shared library or non-shared library for Tk.
${LIB_FILE}: ${STUB_LIB_FILE} @LIB_RSRC_FILE@ ${OBJS}
	rm -f $@
	@MAKE_LIB@










${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
	@if test "x${LIB_FILE}" = "xlibtk${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
	    (cd ${TOP_DIR}/win; ${MAKE} tk${MAJOR_VERSION}${MINOR_VERSION}.dll); \
	    cp "${TOP_DIR}/win/tk${MAJOR_VERSION}${MINOR_VERSION}.dll" .; \
	fi
	rm -f $@
	@MAKE_STUB_LIB@

# Build Aqua resource files
${TK_RSRC_FILE}: $(AQUA_RESOURCES)
	rm -f $@







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|


>
>
>
>
>
>
>
>
>


|
|
|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

all: binaries libraries

binaries: ${LIB_FILE} ${WISH_EXE}

libraries:

tkzipfile: ${TK_ZIP_FILE}

${TK_ZIP_FILE}: ${ZIP_INSTALL_OBJS}
	@rm -rf ${TK_VFS_ROOT}
	@mkdir -p ${TK_VFS_PATH}
	@echo "creating ${TK_VFS_PATH} (prepare compression)"
	@if \
	    ln -s $(TOP_DIR)/library/* ${TK_VFS_PATH}/; \
	then : ; else \
	    cp -a $(TOP_DIR)/library/* ${TK_VFS_PATH}; \
	fi
	rm -rf ${TK_VFS_PATH}/demos
	@find ${TK_VFS_ROOT} -type d -empty -delete
	@echo "creating ${TK_ZIP_FILE} from ${TK_VFS_PATH}"
	-@if test "${ZIPFS_BUILD}" = "2" ; then \
	    cp ${TCL_BIN_DIR}/tclsh ${TK_VFS_ROOT}/../${TK_ZIP_FILE} || cp ${TCL_BIN_DIR}/../bin/tclsh${TCLVERSION} ${TK_VFS_ROOT}/../${TK_ZIP_FILE}; \
	    (zip=`(realpath '${NATIVE_ZIP}' || readlink -m '${NATIVE_ZIP}') 2>/dev/null || \
		(echo '${NATIVE_ZIP}' | sed "s?^\./?$$(pwd)/?")`; \
		cd ${TK_VFS_ROOT} && $$zip -J ../${TK_ZIP_FILE}) \
	fi
	@(zip=`(realpath '${NATIVE_ZIP}' || readlink -m '${NATIVE_ZIP}' || \
	    echo '${NATIVE_ZIP}' | sed "s?^\./?$$(pwd)/?")  2>/dev/null`; \
	    echo 'cd ${TK_VFS_ROOT} &&' $$zip '${ZIP_PROG_OPTIONS} ../${TK_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}'; \
	    cd ${TK_VFS_ROOT} && \
	    $$zip ${ZIP_PROG_OPTIONS} ../${TK_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} >/dev/null)

# The following target is configured by autoconf to generate either
# a shared library or non-shared library for Tk.
${LIB_FILE}: ${STUB_LIB_FILE} @LIB_RSRC_FILE@ ${OBJS} ${TK_ZIP_FILE}
	rm -f $@
	@MAKE_LIB@
	@if test "${ZIPFS_BUILD}" = "1" ; then \
	    if test "x$(MACHER)" = "x" ; then \
		cat ${TK_ZIP_FILE} >> ${LIB_FILE}; \
	    else $(MACHER) append ${LIB_FILE} ${TK_ZIP_FILE} /tmp/macher_output; \
	         mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE}; \
	    fi; \
	    ${NATIVE_ZIP} -A ${LIB_FILE} \
	    || echo 'ignore zip-error by adjust sfx process (not executable?)'; \
	fi

${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
	@if test "x${LIB_FILE}" = "xlibtcl9tk${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
	    (cd ${TOP_DIR}/win; ${MAKE} tcl9tk${MAJOR_VERSION}${MINOR_VERSION}.dll); \
	    cp "${TOP_DIR}/win/tcl9tk${MAJOR_VERSION}${MINOR_VERSION}.dll" .; \
	fi
	rm -f $@
	@MAKE_STUB_LIB@

# Build Aqua resource files
${TK_RSRC_FILE}: $(AQUA_RESOURCES)
	rm -f $@
615
616
617
618
619
620
621
622
623









624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
	@echo ${OBJS}
# This targets actually build the objects needed for the lib in the above
# case
objs: ${OBJS}


${WISH_EXE}: $(TK_STUB_LIB_FILE) $(WISH_OBJS) $(TK_LIB_FILE) @APP_RSRC_FILE@
	${CC} ${CFLAGS} ${LDFLAGS} $(WISH_OBJS) @TK_BUILD_LIB_SPEC@ \
		$(WISH_LIBS) $(CC_SEARCH_FLAGS) -o ${WISH_EXE}










# Resetting the LIB_RUNTIME_DIR below is required so that
# the generated tktest executable gets the build directory
# burned into its ld search path. This keeps tktest from
# picking up an already installed version of the Tcl or
# Tk shared libraries.

$(TKTEST_EXE): $(TKTEST_OBJS) $(TK_LIB_FILE)
	$(MAKE) tktest-real LIB_RUNTIME_DIR="`pwd`:$(TCL_BIN_DIR)"

tktest-real: ${TK_STUB_LIB_FILE}
	${CC} ${CFLAGS} ${LDFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ $(WISH_LIBS) \
		${TK_STUB_LIB_FILE} ${TCL_STUB_LIB_SPEC} $(CC_SEARCH_FLAGS) -o $(TKTEST_EXE)

# # FIXME: This xttest rule seems to be broken in a number of ways.  It should
# # use CC_SEARCH_FLAGS, it does not include the shared lib location logic from
# # tktest, and it is not clear where this test.o object file comes from.
#
# xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE) ${TK_STUB_LIB_FILE}
# 	${CC} ${CFLAGS} ${LDFLAGS} test.o tkTest.o tkSquare.o \
# 		@TK_BUILD_LIB_SPEC@ ${TK_STUB_LIB_FILE}  ${TCL_STUB_LIB_SPEC} \
# 		$(WISH_LIBS) $(LD_SEARCH_FLAGS) -lXt -o xttest

# Note, in the target below TCL_LIBRARY needs to be set or else
# "make test" won't work in the case where the compilation directory
# isn't the same as the source directory.
# Specifying TESTFLAGS on the command line is the standard way to pass
# args to tcltest, ie:







|

>
>
>
>
>
>
>
>
>











|







|
|







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
	@echo ${OBJS}
# This targets actually build the objects needed for the lib in the above
# case
objs: ${OBJS}


${WISH_EXE}: $(TK_STUB_LIB_FILE) $(WISH_OBJS) $(TK_LIB_FILE) @APP_RSRC_FILE@
	${CC} ${CFLAGS} $(WISH_OBJS) @TK_BUILD_LIB_SPEC@ ${LDFLAGS} \
		$(WISH_LIBS) $(CC_SEARCH_FLAGS) -o ${WISH_EXE}
	@if test "${ZIPFS_BUILD}" = "2" ; then \
	    if test "x$(MACHER)" = "x" ; then \
		cat ${TK_ZIP_FILE} >> ${WISH_EXE}; \
	    else $(MACHER) append ${WISH_EXE} ${TK_ZIP_FILE} /tmp/macher_output; \
	         mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE}; \
	    fi; \
	    ${NATIVE_ZIP} -A ${WISH_EXE} \
	    || echo 'ignore zip-error by adjust sfx process (not executable?)'; \
	fi

# Resetting the LIB_RUNTIME_DIR below is required so that
# the generated tktest executable gets the build directory
# burned into its ld search path. This keeps tktest from
# picking up an already installed version of the Tcl or
# Tk shared libraries.

$(TKTEST_EXE): $(TKTEST_OBJS) $(TK_LIB_FILE)
	$(MAKE) tktest-real LIB_RUNTIME_DIR="`pwd`:$(TCL_BIN_DIR)"

tktest-real: ${TK_STUB_LIB_FILE}
	${CC} ${CFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ ${LDFLAGS} $(WISH_LIBS) \
		${TK_STUB_LIB_FILE} ${TCL_STUB_LIB_SPEC} $(CC_SEARCH_FLAGS) -o $(TKTEST_EXE)

# # FIXME: This xttest rule seems to be broken in a number of ways.  It should
# # use CC_SEARCH_FLAGS, it does not include the shared lib location logic from
# # tktest, and it is not clear where this test.o object file comes from.
#
# xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE) ${TK_STUB_LIB_FILE}
# 	${CC} ${CFLAGS} test.o tkTest.o tkSquare.o \
# 		@TK_BUILD_LIB_SPEC@ ${LDFLAGS} ${TK_STUB_LIB_FILE}  ${TCL_STUB_LIB_SPEC} \
# 		$(WISH_LIBS) $(LD_SEARCH_FLAGS) -lXt -o xttest

# Note, in the target below TCL_LIBRARY needs to be set or else
# "make test" won't work in the case where the compilation directory
# isn't the same as the source directory.
# Specifying TESTFLAGS on the command line is the standard way to pass
# args to tcltest, ie:
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732

733



734
735
736

737



738



739

740
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758

valgrind: $(TKTEST_EXE)
	$(SHELL_ENV) valgrind $(VALGRINDARGS) ./$(TKTEST_EXE) $(TEST_DIR)/all.tcl -geometry +0+0 -singleproc 1 $(TESTFLAGS)

valgrindshell: $(TKTEST_EXE)
	$(SHELL_ENV) valgrind $(VALGRINDARGS) ./$(TKTEST_EXE) $(SCRIPT)

INSTALL_BASE_TARGETS = install-binaries install-libraries
INSTALL_DOC_TARGETS = install-doc
INSTALL_DEV_TARGETS = install-headers
INSTALL_DEMO_TARGETS = install-demos
INSTALL_EXTRA_TARGETS = @EXTRA_INSTALL@
INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \
		$(INSTALL_DEMO_TARGETS) $(INSTALL_EXTRA_TARGETS)

install: $(INSTALL_TARGETS)

install-strip:
	$(MAKE) $(INSTALL_TARGETS) \
		INSTALL_PROGRAM="$(INSTALL_PROGRAM) ${INSTALL_STRIP_PROGRAM}" \
		INSTALL_LIBRARY="$(INSTALL_LIBRARY) ${INSTALL_STRIP_LIBRARY}"

install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}
	@for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \
	    "$(PKG_INSTALL_DIR)" "$(CONFIG_INSTALL_DIR)" ; \
	    do \
	    if [ ! -d "$$i" ] ; then \
		echo "Making directory $$i"; \
		$(INSTALL_DATA_DIR) "$$i"; \
		else true; \
		fi; \
	    done;
	@if test "x$(TK_SHARED_BUILD)" = "x1"; then \
	    echo "Creating package index $(PKG_INDEX)"; \
	    rm -f "$(PKG_INDEX)"; \
	    (\
	    echo "if {[catch {package present Tcl 8.6-}]} return";\
	    relative=`echo | awk '{ORS=" "; split("$(TK_PKG_DIR)",a,"/"); for (f in a) {print ".."}}'`;\
	    if test "x$(DLL_INSTALL_DIR)" != "x$(BIN_INSTALL_DIR)"; then \

	    echo "package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}$(TK_LIB_FILE)]] Tk]";\



	    else \
	    echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	    echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\

	    echo "    package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin $(TK_LIB_FILE)]] Tk]";\



	    echo "} else {";\



	    echo "    package ifneeded Tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin tk${MAJOR_VERSION}${MINOR_VERSION}.dll]] Tk]";\

	    echo "}";\
	    fi \

	    ) > "$(PKG_INDEX)"; \
	    fi
	@echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/"
	@@INSTALL_LIB@
	@chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)"
	@if test -f "tk${MAJOR_VERSION}${MINOR_VERSION}.dll"; then \
	    $(INSTALL_LIBRARY) "tk${MAJOR_VERSION}${MINOR_VERSION}.dll" "$(DLL_INSTALL_DIR)";\
	    chmod 555 "$(DLL_INSTALL_DIR)/tk${MAJOR_VERSION}${MINOR_VERSION}.dll";\
	    $(INSTALL_LIBRARY) "../win/libtk${MAJOR_VERSION}${MINOR_VERSION}.a" "$(LIB_INSTALL_DIR)";\
	    chmod 555 "$(LIB_INSTALL_DIR)/libtk${MAJOR_VERSION}${MINOR_VERSION}.a";\
	fi
	@echo "Installing ${WISH_EXE} as $(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@$(INSTALL_PROGRAM) ${WISH_EXE} "$(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@echo "Installing tkConfig.sh to $(CONFIG_INSTALL_DIR)/"
	@$(INSTALL_DATA) tkConfig.sh "$(CONFIG_INSTALL_DIR)/tkConfig.sh"
	@if test "$(STUB_LIB_FILE)" != "" ; then \
	    echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \







|











|
|















|


>
|
>
>
>



>
|
>
>
>

>
>
>
|
>

|
>








<
<







765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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

valgrind: $(TKTEST_EXE)
	$(SHELL_ENV) valgrind $(VALGRINDARGS) ./$(TKTEST_EXE) $(TEST_DIR)/all.tcl -geometry +0+0 -singleproc 1 $(TESTFLAGS)

valgrindshell: $(TKTEST_EXE)
	$(SHELL_ENV) valgrind $(VALGRINDARGS) ./$(TKTEST_EXE) $(SCRIPT)

INSTALL_BASE_TARGETS = install-binaries ${INSTALL_LIBRARIES}
INSTALL_DOC_TARGETS = install-doc
INSTALL_DEV_TARGETS = install-headers
INSTALL_DEMO_TARGETS = install-demos
INSTALL_EXTRA_TARGETS = @EXTRA_INSTALL@
INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \
		$(INSTALL_DEMO_TARGETS) $(INSTALL_EXTRA_TARGETS)

install: $(INSTALL_TARGETS)

install-strip:
	$(MAKE) $(INSTALL_TARGETS) \
		INSTALL_PROGRAM="STRIPPROG='${INSTALL_STRIP_PROGRAM}' $(INSTALL_PROGRAM) -s" \
		INSTALL_LIBRARY="STRIPPROG='${INSTALL_STRIP_LIBRARY}' $(INSTALL_LIBRARY) -s"

install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}
	@for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \
	    "$(PKG_INSTALL_DIR)" "$(CONFIG_INSTALL_DIR)" ; \
	    do \
	    if [ ! -d "$$i" ] ; then \
		echo "Making directory $$i"; \
		$(INSTALL_DATA_DIR) "$$i"; \
		else true; \
		fi; \
	    done;
	@if test "x$(TK_SHARED_BUILD)" = "x1"; then \
	    echo "Creating package index $(PKG_INDEX)"; \
	    rm -f "$(PKG_INDEX)"; \
	    (\
	    echo "if {![package vsatisfies [package provide Tcl] 8.7-]} 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 "if {[package vsatisfies [package provide Tcl] 9.0]} {";\
	    echo "    package ifneeded tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}$(TK_LIB_FILE_TCL9)]]]";\
	    echo "} else {";\
	    echo "    package ifneeded tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}$(TK_LIB_FILE_TCL8)]]]";\
	    echo "}";\
	    else \
	    echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	    echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	    echo "    if {[package vsatisfies [package provide Tcl] 9.0]} {";\
	    echo "	package ifneeded tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin $(TK_LIB_FILE_TCL9)]]]";\
	    echo "    } else {";\
	    echo "	package ifneeded tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin $(TK_LIB_FILE_TCL8)]]]";\
	    echo "    }";\
	    echo "} else {";\
	    echo "    if {[package vsatisfies [package provide Tcl] 9.0]} {";\
	    echo "	package ifneeded tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin tcl9tk${MAJOR_VERSION}${MINOR_VERSION}.dll]]]";\
	    echo "    } else {";\
	    echo "	package ifneeded tk $(MAJOR_VERSION).$(MINOR_VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir $${relative}.. bin tk${MAJOR_VERSION}${MINOR_VERSION}.dll]]]";\
	    echo "    }";\
	    echo "}";\
	    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";\


	fi
	@echo "Installing ${WISH_EXE} as $(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@$(INSTALL_PROGRAM) ${WISH_EXE} "$(BIN_INSTALL_DIR)/wish$(VERSION)${EXE_SUFFIX}"
	@echo "Installing tkConfig.sh to $(CONFIG_INSTALL_DIR)/"
	@$(INSTALL_DATA) tkConfig.sh "$(CONFIG_INSTALL_DIR)/tkConfig.sh"
	@if test "$(STUB_LIB_FILE)" != "" ; then \
	    echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \
898
899
900
901
902
903
904

905
906

907
908
909
910
911
912
913
914
915
916
917

Makefile: $(UNIX_DIR)/Makefile.in
	$(SHELL) config.status
#tkConfig.h: $(UNIX_DIR)/tkConfig.h.in
#	$(SHELL) config.status

clean:

	rm -f *.a *.o libtk* core errs *~ \#* TAGS *.E a.out \
		errors ${WISH_EXE} $(TKTEST_EXE) lib.exp Tk *.rsrc


distclean: clean
	rm -rf Makefile config.status config.cache config.log tkConfig.sh \
		tkConfig.h *.plist Tk.framework tk.pc

depend:
	makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)

# Test binaries.  The rule for tkTestInit.o is complicated because
# it is is compiled from tkAppInit.c.  Can't use the "-o" option
# because this doesn't work on some strange compilers (e.g. UnixWare).







>
|
|
>



|







980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001

Makefile: $(UNIX_DIR)/Makefile.in
	$(SHELL) config.status
#tkConfig.h: $(UNIX_DIR)/tkConfig.h.in
#	$(SHELL) config.status

clean:
	rm -rf *.vfs
	rm -f *.a *.o libtk* libtcl9tk* core errs *~ \#* TAGS *.E a.out \
		errors ${WISH_EXE} $(TKTEST_EXE) lib.exp Tk *.rsrc \
		 *.zip

distclean: clean
	rm -rf Makefile config.status config.cache config.log tkConfig.sh \
		tkConfig.h *.plist Tk.framework tk.pc tkUuid.h

depend:
	makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)

# Test binaries.  The rule for tkTestInit.o is complicated because
# it is is compiled from tkAppInit.c.  Can't use the "-o" option
# because this doesn't work on some strange compilers (e.g. UnixWare).
943
944
945
946
947
948
949



950
951
952
953
954
955
956

tkAtom.o: $(GENERIC_DIR)/tkAtom.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkAtom.c

tkBind.o: $(GENERIC_DIR)/tkBind.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBind.c




tkBitmap.o: $(GENERIC_DIR)/tkBitmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitmap.c

tkBusy.o: $(GENERIC_DIR)/tkBusy.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBusy.c

tkClipboard.o: $(GENERIC_DIR)/tkClipboard.c







>
>
>







1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043

tkAtom.o: $(GENERIC_DIR)/tkAtom.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkAtom.c

tkBind.o: $(GENERIC_DIR)/tkBind.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBind.c

tkBitField.o: $(GENERIC_DIR)/tkBitField.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitField.c

tkBitmap.o: $(GENERIC_DIR)/tkBitmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBitmap.c

tkBusy.o: $(GENERIC_DIR)/tkBusy.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkBusy.c

tkClipboard.o: $(GENERIC_DIR)/tkClipboard.c
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
		-DCFG_INSTALL_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \
		\
		-DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \
		-DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \
		-DCFG_RUNTIME_SCRDIR="\"$(TK_LIBRARY)\"" \
		-DCFG_RUNTIME_INCDIR="\"$(includedir)\"" \
		-DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \

		-DCFG_RUNTIME_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \
		\
		$(GENERIC_DIR)/tkPkgConfig.c

tkPlace.o: $(GENERIC_DIR)/tkPlace.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPlace.c

tkSelect.o: $(GENERIC_DIR)/tkSelect.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkSelect.c

tkStyle.o: $(GENERIC_DIR)/tkStyle.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkStyle.c

tkUtil.o: $(GENERIC_DIR)/tkUtil.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkUtil.c

tkVisual.o: $(GENERIC_DIR)/tkVisual.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkVisual.c

tkWindow.o: $(GENERIC_DIR)/tkWindow.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkWindow.c

tkButton.o: $(GENERIC_DIR)/tkButton.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkButton.c

tkEntry.o: $(GENERIC_DIR)/tkEntry.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkEntry.c








>



















|
|







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
		-DCFG_INSTALL_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \
		\
		-DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \
		-DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \
		-DCFG_RUNTIME_SCRDIR="\"$(TK_LIBRARY)\"" \
		-DCFG_RUNTIME_INCDIR="\"$(includedir)\"" \
		-DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \
		-DCFG_RUNTIME_DLLFILE="\"$(TK_LIB_FILE)\"" \
		-DCFG_RUNTIME_DEMODIR="\"$(DEMO_INSTALL_DIR)\"" \
		\
		$(GENERIC_DIR)/tkPkgConfig.c

tkPlace.o: $(GENERIC_DIR)/tkPlace.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkPlace.c

tkSelect.o: $(GENERIC_DIR)/tkSelect.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkSelect.c

tkStyle.o: $(GENERIC_DIR)/tkStyle.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkStyle.c

tkUtil.o: $(GENERIC_DIR)/tkUtil.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkUtil.c

tkVisual.o: $(GENERIC_DIR)/tkVisual.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkVisual.c

tkWindow.o: $(GENERIC_DIR)/tkWindow.c tkUuid.h
	$(CC) -c $(CC_SWITCHES) -I. $(GENERIC_DIR)/tkWindow.c

tkButton.o: $(GENERIC_DIR)/tkButton.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkButton.c

tkEntry.o: $(GENERIC_DIR)/tkEntry.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkEntry.c

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
tkScale.o: $(GENERIC_DIR)/tkScale.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkScale.c

tkScrollbar.o: $(GENERIC_DIR)/tkScrollbar.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkScrollbar.c

tkSquare.o: $(GENERIC_DIR)/tkSquare.c
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkSquare.c

tkCanvas.o: $(GENERIC_DIR)/tkCanvas.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCanvas.c

tkCanvArc.o: $(GENERIC_DIR)/tkCanvArc.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCanvArc.c








|







1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
tkScale.o: $(GENERIC_DIR)/tkScale.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkScale.c

tkScrollbar.o: $(GENERIC_DIR)/tkScrollbar.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkScrollbar.c

tkSquare.o: $(GENERIC_DIR)/tkSquare.c
	$(CC) -c $(CC_SWITCHES) -DUSE_TK_STUBS $(GENERIC_DIR)/tkSquare.c

tkCanvas.o: $(GENERIC_DIR)/tkCanvas.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCanvas.c

tkCanvArc.o: $(GENERIC_DIR)/tkCanvArc.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCanvArc.c

1125
1126
1127
1128
1129
1130
1131



1132
1133
1134
1135
1136
1137
1138

tkRectOval.o: $(GENERIC_DIR)/tkRectOval.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkRectOval.c

tkTrig.o: $(GENERIC_DIR)/tkTrig.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTrig.c




tkImage.o: $(GENERIC_DIR)/tkImage.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImage.c

tkImgBmap.o: $(GENERIC_DIR)/tkImgBmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgBmap.c

tkImgListFormat.o: $(GENERIC_DIR)/tkImgListFormat.c







>
>
>







1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229

tkRectOval.o: $(GENERIC_DIR)/tkRectOval.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkRectOval.c

tkTrig.o: $(GENERIC_DIR)/tkTrig.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTrig.c

tkIcu.o: $(GENERIC_DIR)/tkIcu.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkIcu.c

tkImage.o: $(GENERIC_DIR)/tkImage.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImage.c

tkImgBmap.o: $(GENERIC_DIR)/tkImgBmap.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgBmap.c

tkImgListFormat.o: $(GENERIC_DIR)/tkImgListFormat.c
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

tkImgPhoto.o: $(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkImgPhoto.h
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhoto.c

tkImgPhInstance.o: $(GENERIC_DIR)/tkImgPhInstance.c $(GENERIC_DIR)/tkImgPhoto.h
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhInstance.c

tkOldTest.o: $(GENERIC_DIR)/tkOldTest.c



	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkOldTest.c

tkTest.o: $(GENERIC_DIR)/tkTest.c
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkTest.c

tkText.o: $(GENERIC_DIR)/tkText.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkText.c

tkTextBTree.o: $(GENERIC_DIR)/tkTextBTree.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextBTree.c

tkTextDisp.o: $(GENERIC_DIR)/tkTextDisp.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextDisp.c

tkTextImage.o: $(GENERIC_DIR)/tkTextImage.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextImage.c

tkTextIndex.o: $(GENERIC_DIR)/tkTextIndex.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextIndex.c




tkTextMark.o: $(GENERIC_DIR)/tkTextMark.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextMark.c

tkTextTag.o: $(GENERIC_DIR)/tkTextTag.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextTag.c







tkTextWind.o: $(GENERIC_DIR)/tkTextWind.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextWind.c

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

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








|
>
>
>
|

|
|
















>
>
>






>
>
>
>
>
>










|







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

tkImgPhoto.o: $(GENERIC_DIR)/tkImgPhoto.c $(GENERIC_DIR)/tkImgPhoto.h
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhoto.c

tkImgPhInstance.o: $(GENERIC_DIR)/tkImgPhInstance.c $(GENERIC_DIR)/tkImgPhoto.h
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhInstance.c

tkRangeList.o: $(GENERIC_DIR)/tkRangeList.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkRangeList.c

tkIntSet.o: $(GENERIC_DIR)/tkIntSet.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkIntSet.c

tkTest.o: $(GENERIC_DIR)/tkTest.c tkUuid.h
	$(CC) -c $(CC_SWITCHES) -DUSE_TK_STUBS $(GENERIC_DIR)/tkTest.c

tkText.o: $(GENERIC_DIR)/tkText.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkText.c

tkTextBTree.o: $(GENERIC_DIR)/tkTextBTree.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextBTree.c

tkTextDisp.o: $(GENERIC_DIR)/tkTextDisp.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextDisp.c

tkTextImage.o: $(GENERIC_DIR)/tkTextImage.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextImage.c

tkTextIndex.o: $(GENERIC_DIR)/tkTextIndex.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextIndex.c

tkTextLineBreak.o: $(GENERIC_DIR)/tkTextLineBreak.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextLineBreak.c

tkTextMark.o: $(GENERIC_DIR)/tkTextMark.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextMark.c

tkTextTag.o: $(GENERIC_DIR)/tkTextTag.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextTag.c

tkTextTagSet.o: $(GENERIC_DIR)/tkTextTagSet.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextTagSet.c

tkTextUndo.o: $(GENERIC_DIR)/tkTextUndo.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextUndo.c

tkTextWind.o: $(GENERIC_DIR)/tkTextWind.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextWind.c

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) @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

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







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







>
>
>
>
>
>







1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378

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
1298
1299
1300
1301
1302
1303
1304



1305
1306
1307
1308
1309
1310
1311

tkMacOSXEntry.o: $(MAC_OSX_DIR)/tkMacOSXEntry.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXEntry.c

tkMacOSXEvent.o: $(MAC_OSX_DIR)/tkMacOSXEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXEvent.c




tkMacOSXFont.o: $(MAC_OSX_DIR)/tkMacOSXFont.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXFont.c

tkMacOSXHLEvents.o: $(MAC_OSX_DIR)/tkMacOSXHLEvents.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXHLEvents.c

tkMacOSXImage.o: $(MAC_OSX_DIR)/tkMacOSXImage.c







>
>
>







1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423

tkMacOSXEntry.o: $(MAC_OSX_DIR)/tkMacOSXEntry.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXEntry.c

tkMacOSXEvent.o: $(MAC_OSX_DIR)/tkMacOSXEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXEvent.c

tkMacOSXFileTypes.o: $(MAC_OSX_DIR)/tkMacOSXFileTypes.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXFileTypes.c

tkMacOSXFont.o: $(MAC_OSX_DIR)/tkMacOSXFont.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXFont.c

tkMacOSXHLEvents.o: $(MAC_OSX_DIR)/tkMacOSXHLEvents.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXHLEvents.c

tkMacOSXImage.o: $(MAC_OSX_DIR)/tkMacOSXImage.c
1332
1333
1334
1335
1336
1337
1338



1339
1340
1341
1342
1343
1344
1345

tkMacOSXMouseEvent.o: $(MAC_OSX_DIR)/tkMacOSXMouseEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXMouseEvent.c

tkMacOSXNotify.o: $(MAC_OSX_DIR)/tkMacOSXNotify.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXNotify.c




tkMacOSXRegion.o: $(MAC_OSX_DIR)/tkMacOSXRegion.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXRegion.c

tkMacOSXScale.o: $(MAC_OSX_DIR)/tkMacOSXScale.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXScale.c

tkMacOSXScrlbr.o: $(MAC_OSX_DIR)/tkMacOSXScrlbr.c







>
>
>







1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460

tkMacOSXMouseEvent.o: $(MAC_OSX_DIR)/tkMacOSXMouseEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXMouseEvent.c

tkMacOSXNotify.o: $(MAC_OSX_DIR)/tkMacOSXNotify.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXNotify.c

tkMacOSXPrint.o: $(MAC_OSX_DIR)/tkMacOSXPrint.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXPrint.c

tkMacOSXRegion.o: $(MAC_OSX_DIR)/tkMacOSXRegion.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXRegion.c

tkMacOSXScale.o: $(MAC_OSX_DIR)/tkMacOSXScale.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXScale.c

tkMacOSXScrlbr.o: $(MAC_OSX_DIR)/tkMacOSXScrlbr.c
1362
1363
1364
1365
1366
1367
1368



1369
1370
1371
1372
1373
1374
1375

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




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







>
>
>







1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493

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
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

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








|







1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
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) @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

1481
1482
1483
1484
1485
1486
1487





1488
1489
1490
1491
1492
1493
1494
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkTreeview.c

ttkWidget.o: $(TTK_DIR)/ttkWidget.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkWidget.c

ttkMacOSXTheme.o: $(MAC_OSX_DIR)/ttkMacOSXTheme.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/ttkMacOSXTheme.c






.c.o:
	$(CC) -c $(CC_SWITCHES) $<

#
# Target to regenerate header files and stub files from the *.decls tables.
#







>
>
>
>
>







1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkTreeview.c

ttkWidget.o: $(TTK_DIR)/ttkWidget.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkWidget.c

ttkMacOSXTheme.o: $(MAC_OSX_DIR)/ttkMacOSXTheme.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/ttkMacOSXTheme.c

tkUuid.h: $(TOP_DIR)/manifest.uuid
	echo "#define TK_VERSION_UUID \\" >$@
	cat $(TOP_DIR)/manifest.uuid >>$@
	echo "" >>$@

.c.o:
	$(CC) -c $(CC_SWITCHES) $<

#
# Target to regenerate header files and stub files from the *.decls tables.
#
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
# to put the distribution.  DISTDIR must be an absolute path name.
#

DISTROOT = /tmp/dist
DISTNAME = tk${VERSION}${PATCH_LEVEL}
ZIPNAME	 = tk${MAJOR_VERSION}${MINOR_VERSION}${PATCH_LEVEL}-src.zip
DISTDIR	 = $(DISTROOT)/$(DISTNAME)
DIST_INSTALL_DATA   = CPPROG='cp -p' $(INSTALL) -m 644
DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755

$(UNIX_DIR)/configure: $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tcl.m4 \
		$(UNIX_DIR)/aclocal.m4
	cd $(UNIX_DIR); autoconf
$(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
	cd $(MAC_OSX_DIR); autoconf
$(UNIX_DIR)/tkConfig.h.in: $(MAC_OSX_DIR)/configure
	cd $(MAC_OSX_DIR); autoheader; touch $@

$(TOP_DIR)/manifest.uuid:
	printf "git." >$(TOP_DIR)/manifest.uuid
	git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid

dist:	$(UNIX_DIR)/configure $(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(MAC_OSX_DIR)/configure $(TOP_DIR)/doc/man.macros $(TOP_DIR)/manifest.uuid
	rm -rf $(DISTDIR)
	$(INSTALL_DATA_DIR) $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/manifest.uuid $(DISTDIR)
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tk.spec \
		$(UNIX_DIR)/aclocal.m4 $(UNIX_DIR)/tcl.m4 \







|
|










|
|

|







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
# to put the distribution.  DISTDIR must be an absolute path name.
#

DISTROOT = /tmp/dist
DISTNAME = tk${VERSION}${PATCH_LEVEL}
ZIPNAME	 = tk${MAJOR_VERSION}${MINOR_VERSION}${PATCH_LEVEL}-src.zip
DISTDIR	 = $(DISTROOT)/$(DISTNAME)
DIST_INSTALL_DATA   = $(INSTALL) -p -m 644
DIST_INSTALL_SCRIPT = $(INSTALL) -p -m 755

$(UNIX_DIR)/configure: $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tcl.m4 \
		$(UNIX_DIR)/aclocal.m4
	cd $(UNIX_DIR); autoconf
$(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
	cd $(MAC_OSX_DIR); autoconf
$(UNIX_DIR)/tkConfig.h.in: $(MAC_OSX_DIR)/configure
	cd $(MAC_OSX_DIR); autoheader; touch $@

$(TOP_DIR)/manifest.uuid:
	printf "git-" >$(TOP_DIR)/manifest.uuid
	(cd $(TOP_DIR); git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid || printf "unknown" >$(TOP_DIR)/manifest.uuid)

dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tkConfig.h.in $(UNIX_DIR)/tk.pc.in $(MAC_OSX_DIR)/configure $(TOP_DIR)/doc/man.macros $(TOP_DIR)/manifest.uuid
	rm -rf $(DISTDIR)
	$(INSTALL_DATA_DIR) $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/manifest.uuid $(DISTDIR)
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tk.spec \
		$(UNIX_DIR)/aclocal.m4 $(UNIX_DIR)/tcl.m4 \
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
		       $$i > $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/*.[ch] $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/README $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog \
		$(TOP_DIR)/ChangeLog.2??? $(TOP_DIR)/README.md \
		$(TOP_DIR)/license.terms $(DISTDIR)
	rm -f $(DISTDIR)/generic/blt*.[ch]
	$(INSTALL_DATA_DIR) $(DISTDIR)/generic/ttk
	$(DIST_INSTALL_DATA) $(TTK_DIR)/*.[ch] $(TTK_DIR)/ttk.decls \
		$(DISTDIR)/generic/ttk
	$(INSTALL_DATA_DIR) $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/Makefile.in $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/configure.ac \
		$(TOP_DIR)/win/tkConfig.sh.in \
		$(TOP_DIR)/win/aclocal.m4 $(TOP_DIR)/win/tcl.m4 \



		$(DISTDIR)/win
	$(DIST_INSTALL_SCRIPT) $(TOP_DIR)/win/configure $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.bat $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.vc $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/README $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/win
	$(INSTALL_DATA_DIR) $(DISTDIR)/win/rc
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/wish.exe.manifest.in $(DISTDIR)/win/
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/rc/*.{rc,cur,ico,bmp} $(DISTDIR)/win/rc
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
		$(MAC_OSX_DIR)/*.icns $(MAC_OSX_DIR)/*.tiff \
		$(MAC_OSX_DIR)/*.[ch] $(MAC_OSX_DIR)/*.in \
		$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
		$(MAC_OSX_DIR)/*.sdef \
		$(DISTDIR)/macosx
	$(DIST_INSTALL_SCRIPT) $(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/macosx
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx/Tk.xcode
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/Tk.xcode/project.pbxproj \
		$(MAC_OSX_DIR)/Tk.xcode/default.pbxuser \
		$(DISTDIR)/macosx/Tk.xcode
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx/Tk.xcodeproj
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/Tk.xcodeproj/project.pbxproj \
		$(MAC_OSX_DIR)/Tk.xcodeproj/default.pbxuser \
		$(DISTDIR)/macosx/Tk.xcodeproj
	$(INSTALL_DATA_DIR) $(DISTDIR)/compat
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/compat/stdint.h \
		$(TOP_DIR)/compat/stdbool.h $(DISTDIR)/compat
	$(INSTALL_DATA_DIR) $(DISTDIR)/xlib
	$(DIST_INSTALL_DATA) $(XLIB_DIR)/*.[ch] $(DISTDIR)/xlib
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/xlib
	$(INSTALL_DATA_DIR) $(DISTDIR)/xlib/X11
	$(DIST_INSTALL_DATA) $(XLIB_DIR)/X11/*.h $(DISTDIR)/xlib/X11
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/xlib/X11







|
<






|

<

>
>
>


<
<
<
<

<
|









<
<
<
<





|







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
		       $$i > $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/*.[ch] $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(GENERIC_DIR)/README $(DISTDIR)/generic
	$(DIST_INSTALL_DATA) $(TOP_DIR)/changes.md $(TOP_DIR)/README.md \

		$(TOP_DIR)/license.terms $(DISTDIR)
	rm -f $(DISTDIR)/generic/blt*.[ch]
	$(INSTALL_DATA_DIR) $(DISTDIR)/generic/ttk
	$(DIST_INSTALL_DATA) $(TTK_DIR)/*.[ch] $(TTK_DIR)/ttk.decls \
		$(DISTDIR)/generic/ttk
	$(INSTALL_DATA_DIR) $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.in $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/configure.ac \

		$(TOP_DIR)/win/aclocal.m4 $(TOP_DIR)/win/tcl.m4 \
		$(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.bat \
		$(TOP_DIR)/win/*.vc $(TOP_DIR)/win/README \
		$(TOP_DIR)/license.terms \
		$(DISTDIR)/win
	$(DIST_INSTALL_SCRIPT) $(TOP_DIR)/win/configure $(DISTDIR)/win




	$(INSTALL_DATA_DIR) $(DISTDIR)/win/rc

	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/rc/*.{rc,cur,ico} $(DISTDIR)/win/rc
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
		$(MAC_OSX_DIR)/*.icns $(MAC_OSX_DIR)/*.tiff \
		$(MAC_OSX_DIR)/*.[ch] $(MAC_OSX_DIR)/*.in \
		$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
		$(MAC_OSX_DIR)/*.sdef \
		$(DISTDIR)/macosx
	$(DIST_INSTALL_SCRIPT) $(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/macosx




	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx/Tk.xcodeproj
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/Tk.xcodeproj/project.pbxproj \
		$(MAC_OSX_DIR)/Tk.xcodeproj/default.pbxuser \
		$(DISTDIR)/macosx/Tk.xcodeproj
	$(INSTALL_DATA_DIR) $(DISTDIR)/compat
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms \
		$(TOP_DIR)/compat/stdbool.h $(DISTDIR)/compat
	$(INSTALL_DATA_DIR) $(DISTDIR)/xlib
	$(DIST_INSTALL_DATA) $(XLIB_DIR)/*.[ch] $(DISTDIR)/xlib
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/xlib
	$(INSTALL_DATA_DIR) $(DISTDIR)/xlib/X11
	$(DIST_INSTALL_DATA) $(XLIB_DIR)/X11/*.h $(DISTDIR)/xlib/X11
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/xlib/X11
1695
1696
1697
1698
1699
1700
1701
1702


1703
1704
1705
1706
1707
1708
1709
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TEST_DIR)/*.{test,tcl} \
		$(TEST_DIR)/README $(TEST_DIR)/*.{gif,png,ppm,xbm} \
		$(TEST_DIR)/option.file* $(DISTDIR)/tests
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests/ttk
	$(DIST_INSTALL_DATA) $(TEST_DIR)/ttk/*.{test,tcl} $(DISTDIR)/tests/ttk



alldist: dist
	rm -f $(DISTROOT)/$(DISTNAME)-src.tar.gz $(DISTROOT)/$(ZIPNAME)
	cd $(DISTROOT); tar cf $(DISTNAME)-src.tar $(DISTNAME); \
		gzip -9 $(DISTNAME)-src.tar; zip -qr8 $(ZIPNAME) $(DISTNAME)

#







|
>
>







1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TEST_DIR)/*.{test,tcl} \
		$(TEST_DIR)/README $(TEST_DIR)/*.{gif,png,ppm,xbm} \
		$(TEST_DIR)/option.file* $(DISTDIR)/tests
	$(INSTALL_DATA_DIR) $(DISTDIR)/tests/ttk
	$(DIST_INSTALL_DATA) $(TEST_DIR)/ttk/*.{svg,test,tcl} $(DISTDIR)/tests/ttk
	mkdir -p $(DISTDIR)/.github/workflows
	cp -p $(TOP_DIR)/.github/workflows/*.yml $(DISTDIR)/.github/workflows

alldist: dist
	rm -f $(DISTROOT)/$(DISTNAME)-src.tar.gz $(DISTROOT)/$(ZIPNAME)
	cd $(DISTROOT); tar cf $(DISTNAME)-src.tar $(DISTNAME); \
		gzip -9 $(DISTNAME)-src.tar; zip -qr8 $(ZIPNAME) $(DISTNAME)

#

Changes to unix/README.

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	--with-tcl=DIR		Specifies the directory containing the Tcl
				binaries and Tcl's platform-dependent
				configuration information. By default the Tcl
				directory is assumed to be in the location
				given by (a) above.
	--with-x=DIR		Tells configure where to find an installation
				of the X Window System. Not normally needed.
	--enable-threads	If this switch is set, Tk will compile itself
				with multithreading support.
	--enable-shared		If this switch is specified, Tk will compile
				itself as a shared library if it can figure
				out how to do that on this platform. This is
				the default on platforms where we know how to
				build shared libraries.
	--disable-shared	If this switch is specified, Tk will compile
				itself as a static library.







<
<







47
48
49
50
51
52
53


54
55
56
57
58
59
60
	--with-tcl=DIR		Specifies the directory containing the Tcl
				binaries and Tcl's platform-dependent
				configuration information. By default the Tcl
				directory is assumed to be in the location
				given by (a) above.
	--with-x=DIR		Tells configure where to find an installation
				of the X Window System. Not normally needed.


	--enable-shared		If this switch is specified, Tk will compile
				itself as a shared library if it can figure
				out how to do that on this platform. This is
				the default on platforms where we know how to
				build shared libraries.
	--disable-shared	If this switch is specified, Tk will compile
				itself as a static library.

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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191

192
193


194
195
196
197
198
199
200

201
202
203

204
205

206
207
208
209
210
211
212

213



214
215
216
217
218
219
220
221

222
223

224
225
226
227
228
229
230





231
232

233


234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for tk 8.7.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.

#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :

  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;

esac
fi










as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '


    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi

  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'









fi





# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
  fi
  # We don't want this to propagate to other subprocesses.
          { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :

  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '\${1+\"\$@\"}'='\"\$@\"'
  setopt NO_GLOB_SUBST
else
  case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;

esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :


else
  exitcode=1; echo positional parameters were not saved.

fi
test x\$exitcode = x0 || exit 1


test -x / || exit 1"
  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
test \$(( 1 + 1 )) = 2 || exit 1"
  if (eval "$as_required") 2>/dev/null; then :

  as_have_required=yes
else
  as_have_required=no

fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :


else
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



  as_found=:
  case $as_dir in #(
	 /*)
	   for as_base in sh bash ksh sh5; do
	     # Try only shells that exist, to save several forks.
	     as_shell=$as_dir/$as_base
	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :

  CONFIG_SHELL=$as_shell as_have_required=yes
		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :

  break 2
fi
fi
	   done;;
       esac
  as_found=false
done





$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :

  CONFIG_SHELL=$SHELL as_have_required=yes


fi; }
IFS=$as_save_IFS


      if test "x$CONFIG_SHELL" != x; then :

  export CONFIG_SHELL
             # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi

    if test x$as_have_required = xno; then :

  $as_echo "$0: This script requires a shell more modern than all"
  $as_echo "$0: the shells that I found on your system."
  if test x${ZSH_VERSION+set} = xset ; then
    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
  else
    $as_echo "$0: Please tell [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
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1


|


|
>










|
>






|
|




>




>
>
>
>
>
>
>
>



<
<
<
<
<
<
<
<
|
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
>
>
|
<
<
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>


|








<
<
<
<
<
<
<








>
|
>
>
>
|





|





|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|
|
|




|
>






|
|




>














|
>

|
|
>


>
>






|
>

|
|
>

|
>

|
|




>
|
>
>
>





|

|
>

|
>







>
>
>
>
>
|
|
>

>
>
|
<


|
>
















|
|



|
>
|
|
|
|
|

|





|
>



















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47








48
49

50
51






52







53
54
55
56


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113




















114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for tk 9.0.
#
#
# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
# Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test ${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 case e in #(
  e) case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac ;;
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








IFS=" ""	$as_nl"


PS1='$ '
PS2='> '






PS4='+ '








# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL


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 ${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









# 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 #(((
    '') 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
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi






















# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed 'exec'.
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 \${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 case e in #(
  e) case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac ;;
esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" )
then :

else case e in #(
  e) exitcode=1; echo positional parameters were not saved. ;;
esac
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 :
  as_have_required=yes
else case e in #(
  e) as_have_required=no ;;
esac
fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
then :

else case e in #(
  e) 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 #(((
    '') 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
	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
		    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_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 case e in #(
  e) 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 ;;
esac
fi



      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'.
printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi

    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
    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 ;;
esac
fi
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|








|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  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=`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 ||
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
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :

  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }

fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :

  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }

fi # as_fn_arith


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error

if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else







|
>




|
|


|
>







|
>




|
|


|
>













|

|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else case e in #(
  e) as_fn_append ()
  {
    eval $1=\$$1\$2
  } ;;
esac
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else case e in #(
  e) as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  } ;;
esac
fi # as_fn_arith


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  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
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q







|







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
468
469
470
471
472
473
474


475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499




500
501
502
503
504
505
506
507
508
509
510
511






512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
  sed -n '
    p
    /[$]LINENO/=
  ' <$as_myself |
    sed '


      s/[$]LINENO.*/&-/
      t lineno
      b
      :lineno
      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }

  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
  # already done that, so ensure we don't try to do so again and fall
  # in an infinite loop.  This has already happened in practice.
  _as_can_reexec=no; export _as_can_reexec
  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensitive to this).
  . "./$as_me.lineno"
  # Exit status is that of the last command.
  exit
}





ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac







rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi







>
>











|













>
>
>
>












>
>
>
>
>
>












|
|
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
  sed -n '
    p
    /[$]LINENO/=
  ' <$as_myself |
    sed '
      t clear
      :clear
      s/[$]LINENO.*/&-/
      t lineno
      b
      :lineno
      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { 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
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
    # In both cases, we have to default to 'cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi
544
545
546
547
548
549
550
551

552
553
554

555
556
557
558
559
560
561
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"


# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"



test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1

# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,







|
>


|
>







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated

# Sed expression to map a string onto a valid variable name.
as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
as_tr_sh="eval sed '$as_sed_sh'" # deprecated


test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1

# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616









617
618
619
620

621
622
623
624
625
626
627
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='tk'
PACKAGE_TARNAME='tk'
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>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif









#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif"


ac_subst_vars='LTLIBOBJS
REZ_FLAGS
REZ
APP_RSRC_FILE
LIB_RSRC_FILE
WISH_RSRC_FILE
TK_RSRC_FILE







|
|





|
|
|

|
<
<
<

<
<
<
<
<


<
<
<


<
<
<






>
>
>
>
>
>
>
>
>




>







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615



616





617
618



619
620



621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='tk'
PACKAGE_TARNAME='tk'
PACKAGE_VERSION='9.0'
PACKAGE_STRING='tk 9.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stddef.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H



# include <stdlib.h>





#endif
#ifdef HAVE_STRING_H



# include <string.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
651
652
653
654
655
656
657


658
659
660
661
662
663
664
665











666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
TK_INCLUDE_SPEC
TK_STUB_LIB_PATH
TK_STUB_LIB_SPEC
TK_STUB_LIB_FLAG
TK_STUB_LIB_FILE
TK_LIB_SPEC
TK_LIB_FLAG


TK_LIB_FILE
TK_YEAR
TK_PATCH_LEVEL
TK_MINOR_VERSION
TK_MAJOR_VERSION
TK_VERSION
TK_DEMO_DIR
DEMO_DIR











UNIX_FONT_OBJS
XFT_LIBS
XFT_CFLAGS
XMKMF

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_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







>
>








>
>
>
>
>
>
>
>
>
>
>




>


















>









<
<
<







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731



732
733
734
735
736
737
738
TK_INCLUDE_SPEC
TK_STUB_LIB_PATH
TK_STUB_LIB_SPEC
TK_STUB_LIB_FLAG
TK_STUB_LIB_FILE
TK_LIB_SPEC
TK_LIB_FLAG
TK_LIB_FILE_TCL9
TK_LIB_FILE_TCL8
TK_LIB_FILE
TK_YEAR
TK_PATCH_LEVEL
TK_MINOR_VERSION
TK_MAJOR_VERSION
TK_VERSION
TK_DEMO_DIR
DEMO_DIR
INSTALL_MSGS
INSTALL_LIBRARIES
TK_ZIP_FILE
ZIPFS_BUILD
ZIP_INSTALL_OBJS
ZIP_PROG_VFSSEARCH
ZIP_PROG_OPTIONS
ZIP_PROG
MACHER_PROG
EXEEXT_FOR_BUILD
CC_FOR_BUILD
UNIX_FONT_OBJS
XFT_LIBS
XFT_CFLAGS
XMKMF
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



LIBOBJS
AR
RANLIB
SHARED_BUILD
OBJEXT
EXEEXT
ac_ct_CC
736
737
738
739
740
741
742

743
744
745
746
747
748
749
pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir

localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir







>







768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
776
777
778
779
780
781
782

783
784
785
786
787
788
789
enable_load
enable_symbols
enable_aqua
with_x
enable_xft
enable_xss
enable_framework

'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS







>







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
enable_load
enable_symbols
enable_aqua
with_x
enable_xft
enable_xss
enable_framework
enable_zipfs
'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS
825
826
827
828
829
830
831

832
833
834
835
836
837
838
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'

includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'







>







859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
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

  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=*)







<
<







889
890
891
892
893
894
895


896
897
898
899
900
901
902

  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac



  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
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac







|

|







929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: '$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`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
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac







|

|







955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: '$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`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
    ac_prev=psdir ;;
  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
    psdir=$ac_optarg ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;










  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir=$ac_optarg ;;








>
>
>
>
>
>
>
>
>







1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
    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
  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=\$ac_optarg ;;

  -without-* | --without-*)
    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac







|

|













|

|







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
  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: '$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`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'"
    ac_useropt_orig=$ac_useropt
    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
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
  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) as_fn_error $? "unrecognized option: \`$ac_option'
Try \`$0 --help' for more information"
    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  as_fn_error $? "missing argument to $ac_option"
fi

if test -n "$ac_unrecognized_opts"; then
  case $enable_option_checking in
    no) ;;
    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
  esac
fi

# Check all directory arguments for consistency.
for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
  esac
  # Be sure to have absolute directory names.
  case $ac_val in
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
  esac
  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done

# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias

# FIXME: To remove some day.







|
|







|






|

|















|







|
















|







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
  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) as_fn_error $? "unrecognized option: '$ac_option'
Try '$0 --help' for more information"
    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: '$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      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" ;;
    *)     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 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;;
  esac
  # Be sure to have absolute directory names.
  case $ac_val in
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
  esac
  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done

# There might be people who depend on the old broken behavior: '$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias

# FIXME: To remove some day.
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then the parent directory.
  ac_confdir=`$as_dirname -- "$as_myself" ||
$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_myself" : 'X\(//\)[^/]' \| \
	 X"$as_myself" : 'X\(//\)$' \| \
	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|







1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
  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 ||
printf "%s\n" X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
else
  ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
	pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
  srcdir=.
fi







|







1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
else
  ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work"
ac_abs_confdir=`(
	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
	pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
  srcdir=.
fi
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
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures tk 8.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.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print \`checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for \`--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or \`..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]

  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]







|













|

|

|







|
|
|
|










>







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
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
'configure' configures tk 9.0 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print 'checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for '--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or '..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, 'make install' will install all the files in
'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than '$ac_default_prefix' using '--prefix',
for instance '--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --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]
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
  --x-includes=DIR    X include files are in DIR
  --x-libraries=DIR   X library files are in DIR
_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]







|







1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
  --x-includes=DIR    X include files are in DIR
  --x-libraries=DIR   X library files are in DIR
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of tk 9.0:";;
   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]
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
                          on)
  --enable-symbols        build with debugging symbols (default: off)
  --enable-aqua=yes|no    use Aqua windowingsystem on Mac OS X (default: no)
  --enable-xft            use freetype/fontconfig/xft (default: on)
  --enable-xss            use XScreenSaver for activity timer (default: on)
  --enable-framework      package shared libraries in MacOSX frameworks
                          (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:
                          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>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  XMKMF       Path to xmkmf, Makefile generator for X Window System

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.
_ACEOF
ac_status=$?
fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.
  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
    test -d "$ac_dir" ||
      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix







>






|
<













|


















|

|







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
                          on)
  --enable-symbols        build with debugging symbols (default: off)
  --enable-aqua=yes|no    use Aqua windowingsystem on Mac OS X (default: no)
  --enable-xft            use freetype/fontconfig/xft (default: on)
  --enable-xss            use XScreenSaver for activity timer (default: on)
  --enable-framework      package shared libraries in MacOSX frameworks
                          (default: off)
  --enable-zipfs          build with Zipfs support (default: on)

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: utf-8)

  --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>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  XMKMF       Path to xmkmf, Makefile generator for X Window System

Use these variables to override the choices made by 'configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.
_ACEOF
ac_status=$?
fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.
  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
    test -d "$ac_dir" ||
      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  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
    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix

    cd "$ac_dir" || { ac_status=$?; continue; }
    # Check for guested configure.

    if test -f "$ac_srcdir/configure.gnu"; then
      echo &&
      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
    elif test -f "$ac_srcdir/configure"; then
      echo &&
      $SHELL "$ac_srcdir/configure" --help=recursive
    else
      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
tk configure 8.7
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi

## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##

# ac_fn_c_try_compile LINENO
# --------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext
  if { { ac_try="$ac_compile"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && {
	 test -z "$ac_c_werror_flag" ||
	 test ! -s conftest.err
       } && test -s conftest.$ac_objext; then :

  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1

fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_compile

# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_link ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext conftest$ac_exeext
  if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && {
	 test -z "$ac_c_werror_flag" ||
	 test ! -s conftest.err
       } && test -s conftest$ac_exeext && {
	 test "$cross_compiling" = yes ||
	 test -x conftest$ac_exeext

       }; then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1

fi
  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
  # interfere with the next link command; also delete a directory that is
  # left behind by Apple's compiler.  We do this before executing the actions.
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_link
















































































































































# 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
  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

# 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
  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.
    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    <limits.h> exists even on freestanding compilers.  */

#ifdef __STDC__
# 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 ()
{
return $2 ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
  eval "$3=yes"
else
  eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext \
    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; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_func

# 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
  eval "$3=no"
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
int
main ()
{
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 ()
{
if (sizeof (($2)))
	    return 0;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :


else
  eval "$3=yes"

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
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_type




















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

  $ $0 $@

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##







|
>







|








|
|

|
















|






|







|



|
>

|
|


|
>












|






|







|






>
|

|
|


|
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|







|



>
|

|
|


|
>






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|
>
|
|
|
|




|







|
>




|







|
>

|
|
>

|

|
>


|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|

|







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
    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 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
      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 9.0
generated by GNU Autoconf 2.72

Copyright (C) 2023 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 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\""
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
  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 :
  ac_retval=0
else case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1 ;;
esac
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.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\""
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
  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 :
  ac_retval=0
else case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1 ;;
esac
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_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 case e in #(
  e) 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 case e in #(
  e) eval "$3=no" ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
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_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
  { 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 case e in #(
  e) 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 (void); below.  */

#include <limits.h>
#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 (void);
/* 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 (void)
{
return $2 ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  eval "$3=yes"
else case e in #(
  e) eval "$3=no" ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext ;;
esac
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_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 case e in #(
  e) 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 ;;
esac
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 case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

    ac_retval=1 ;;
esac
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
  { 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 case e in #(
  e) 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 case e in #(
  e) eval "$3=yes" ;;
esac
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 ;;
esac
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_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 9.0, which was
generated by GNU Autoconf 2.72.  Invocation command line was

  $ $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

_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    $as_echo "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF








>
|
>
>
>
|







1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972

_ASUNAME

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
    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
  do
    case $ac_arg in
    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
    | -silent | --silent | --silen | --sile | --sil)
      continue ;;
    *\'*)
      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.







|







1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
  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=`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

# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?


  # Save into config.log some information that might help in debugging.
  {
    echo

    $as_echo "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
    echo
    # The following way of writing the cache mishandles newlines in values,
(
  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac







>
>




|










|
|







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

# 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

    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_*) { 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
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
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    echo

    $as_echo "## ----------------- ##
## Output variables. ##
## ----------------- ##"
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      $as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      $as_echo "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
_ACEOF


# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
  # We do not want a PATH search for config.site.
  case $CONFIG_SITE in #((
    -*)  ac_site_file1=./$CONFIG_SITE;;
    */*) ac_site_file1=$CONFIG_SITE;;
    *)   ac_site_file1=./$CONFIG_SITE;;
  esac
elif test "x$prefix" != xNONE; then
  ac_site_file1=$prefix/share/config.site
  ac_site_file2=$prefix/etc/config.site
else
  ac_site_file1=$ac_default_prefix/share/config.site
  ac_site_file2=$ac_default_prefix/etc/config.site
fi

for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
  test "x$ac_site_file" = xNONE && continue





  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file" \
      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5; }
  fi
done

if test -r "$cache_file"; then
  # Some versions of bash will fail to source /dev/null (special files
  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                      . "./$cache_file";;
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi
















































































































































































































































































































































# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do
  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val=\$ac_cv_env_${ac_var}_value
  eval ac_new_val=\$ac_env_${ac_var}_value
  case $ac_old_set,$ac_new_set in
    set,)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,set)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,);;
    *)
      if test "x$ac_old_val" != "x$ac_new_val"; then
	# differences in whitespace do not lead to failure.
	ac_old_val_w=`echo x $ac_old_val`
	ac_new_val_w=`echo x $ac_new_val`
	if test "$ac_old_val_w" != "$ac_new_val_w"; then
	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
	  ac_cache_corrupted=:
	else
	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
	  eval $ac_var=\$ac_old_val
	fi
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in
    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}

  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu






TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------


    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true

# Check whether --with-tcl was given.
if test "${with_tcl+set}" = set; then :

  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
$as_echo_n "checking for Tcl configuration... " >&6; }
	if ${ac_cv_c_tclconfig+:} false; then :

  $as_echo_n "(cached) " >&6
else


	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
			if test -f "${with_tclconfig}"; then
			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else
		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5







|







|

|




|







|

|





|







|
|













|



<
|
<

<
|
<

<
|
<

<
|
<

<
|
<

<
|
<




<
<

<
|
<
<
<
<

|
<

|
<

>
|

|
>
>
>
>
>
|
|
|


|
|

|







|
|






|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
|


|
|








|
|


|
|


|
|
|
|





|









|
|
|
|
>
|
















|
|
|
|



















|
>



|
|
|
>
|
|
|






|
|







2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134

2135

2136

2137

2138

2139

2140

2141

2142

2143

2144

2145

2146
2147
2148
2149


2150

2151




2152
2153

2154
2155

2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    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=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      printf "%s\n" "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      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=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	printf "%s\n" "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      printf "%s\n" "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      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

printf "%s\n" "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.


printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h



# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.


if test -n "$CONFIG_SITE"; then

  ac_site_files="$CONFIG_SITE"




elif test "x$prefix" != xNONE; then
  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"

else
  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"

fi

for ac_site_file in $ac_site_files
do
  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" \
      || { { 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
    { 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
  { 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 (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;
}

/* C89 style stringification. */
#define noexpand_stringify(a) #a
const char *stringified = noexpand_stringify(arbitrary+token=sequence);

/* C89 style token pasting.  Exercises some of the corner cases that
   e.g. old MSVC gets wrong, but not very hard. */
#define noexpand_concat(a,b) a##b
#define expand_concat(a,b) noexpand_concat(a,b)
extern int vA;
extern int vbee;
#define aye A
#define bee B
int *pvA = &expand_concat(v,aye);
int *pvbee = &noexpand_concat(v,bee);

/* 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

// See if C++-style comments work.

#include <stdbool.h>
extern int puts (const char *);
extern int printf (const char *, ...);
extern int dprintf (int, const char *, ...);
extern void *malloc (size_t);
extern void free (void *);

// 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)
{
  // 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;
  // Work around memory leak warnings.
  free (ia);

  // 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,)
      { 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)
      { 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
	  { 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
	  { 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
	{ 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=`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
  { 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






TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------


    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true

# Check whether --with-tcl was given.
if test ${with_tcl+y}
then :
  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ 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 case e in #(
  e)

	    # 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
			    { 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
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tcl8.7 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.7 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.7 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi







|


|
|







2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tcl9.0 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl9.0 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl9.0 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
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
			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi


fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
	fi
    fi


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
    fi

    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an







|
>









|
|




|
|


|
|


|
|







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
			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi
	 ;;
esac
fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { 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


    { 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
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: loading" >&5
printf "%s\n" "loading" >&6; }
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        { 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
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






if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
    as_fn_error $? "${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}" "$LINENO" 5
fi
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

	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; }
    else
	# It is not an error if an installed version of Tcl can't be located.
	TCLSH_PROG=""
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
$as_echo "No tclsh found on PATH" >&6; }
    fi



    { $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
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
$as_echo "$BUILD_TCLSH" >&6; }



#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------








<
<
<
<
|
|





|
|
|
>
|
|
|












|
>





|
|



|
|




|
|

|
|







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






if test "${TCL_MAJOR_VERSION}" -lt 9 ; then




if test "${TCL_MINOR_VERSION}" -lt 7 ; then
    as_fn_error $? "${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.7+
Found config for Tcl ${TCL_VERSION}" "$LINENO" 5
fi
fi


    { 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 case e in #(
  e)
	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
     ;;
esac
fi


    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG="$ac_cv_path_tclsh"
	{ 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=""
	{ 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



    { 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
    { 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
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; }
    # Check whether --enable-man-symlinks was given.
if test "${enable_man_symlinks+set}" = set; then :

  enableval=$enable_man_symlinks; test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"
else
  enableval="no"

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
$as_echo "$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; }
    # Check whether --enable-man-compression was given.
if test "${enable_man_compression+set}" = set; 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
  enableval="no"

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
$as_echo "$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; }
	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; }
    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; }
    # Check whether --enable-man-suffix was given.
if test "${enable_man_suffix+set}" = set; 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
  enableval="no"

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
$as_echo "$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
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

if test -z "$CC"; then
          if test -n "$ac_tool_prefix"; then
    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


  fi
fi
if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# != 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
  fi
fi
fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  for ac_prog in cl.exe
  do
    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


    test -n "$CC" && break
  done
fi
if test -z "$CC"; then
  ac_ct_CC=$CC
  for ac_prog in cl.exe
do
  # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


  test -n "$ac_ct_CC" && break
done

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi










































































































fi

fi


test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }

# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
  { { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    sed '10a\
... rest of stderr output deleted ...
         10q' conftest.err >conftest.er1
    cat conftest.er1 >&5
  fi
  rm -f conftest.er1 conftest.err
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
done

cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`

# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"

ac_rmfiles=
for ac_file in $ac_files
do
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
  esac
done
rm -f $ac_rmfiles

if { { ac_try="$ac_link_default"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :

  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile.  We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
for ac_file in $ac_files ''
do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
	;;
    [ab].out )
	# We found the default executable, but exeext='' is most
	# certainly right.
	break;;
    *.* )
	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
	then :; else
	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	fi
	# We set ac_cv_exeext here because the later test for it is not
	# safe: cross compilers may not add the suffix if given an `-o'
	# argument, so we may need to know it at that point already.
	# Even if this section looks crufty: it has the advantage of
	# actually working.
	break;;
    * )
	break;;
  esac
done
test "$ac_cv_exeext" = no && ac_cv_exeext=

else
  ac_file=''

fi
if test -z "$ac_file"; then :

  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
See \`config.log' for more details" "$LINENO" 5; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
$as_echo_n "checking for C compiler default output file name... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext

rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :

  # If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	  break;;
    * ) break;;
  esac
done
else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }

fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }

rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdio.h>
int
main ()
{
FILE *f = fopen ("conftest.out", "w");


 return ferror (f) || fclose (f) != 0;

  ;
  return 0;
}
_ACEOF
ac_clean_files="$ac_clean_files conftest.out"
# Check that the compiler produces executables we can run.  If not, either
# the compiler is broken, or we cross compile.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
$as_echo_n "checking whether we are cross compiling... " >&6; }
if test "$cross_compiling" != yes; then
  { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
  if { ac_try='./conftest$ac_cv_exeext'
  { { case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }; then
    cross_compiling=no
  else
    if test "$cross_compiling" = maybe; then
	cross_compiling=yes
    else
	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details" "$LINENO" 5; }
    fi
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
$as_echo "$cross_compiling" >&6; }

rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out

ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if ${ac_cv_objext+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { { ac_try="$ac_compile"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :

  for ac_file in conftest.o conftest.obj conftest.*; do
  test -f "$ac_file" || continue;
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }

fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
if ${ac_cv_c_compiler_gnu+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_compiler_gnu=yes
else
  ac_compiler_gnu=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
$as_echo "$ac_cv_c_compiler_gnu" >&6; }


if test $ac_compiler_gnu = yes; then
  GCC=yes
else
  GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
if ${ac_cv_prog_cc_g+:} false; then :

  $as_echo_n "(cached) " >&6
else
  ac_save_c_werror_flag=$ac_c_werror_flag
   ac_c_werror_flag=yes
   ac_cv_prog_cc_g=no
   CFLAGS="-g"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_prog_cc_g=yes
else
  CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :


else
  ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
  CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi



{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }


































































































if ${ac_cv_prog_cc_c89+:} false; then :

  $as_echo_n "(cached) " >&6
else
  ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdarg.h>
#include <stdio.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
  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 don't provoke an error unfortunately, instead are silently treated
   as 'x'.  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
   array size at least.  It's necessary to write '\x00'==0 to get something
   that's true only with -std.  */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
  ;
  return 0;
}
_ACEOF
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c89" in
  x)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
  xno)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
  *)

    CC="$CC $ac_cv_prog_cc_c89"




    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;

esac

if test "x$ac_cv_prog_cc_c89" != xno; then :



fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
if ${ac_cv_c_inline+:} false; then :

  $as_echo_n "(cached) " >&6
else
  ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifndef __cplusplus
typedef int foo_t;
static $ac_kw foo_t static_foo () {return 0; }
$ac_kw foo_t foo () {return 0; }
#endif

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_c_inline=$ac_kw
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  test "$ac_cv_c_inline" != no && break
done


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
$as_echo "$ac_cv_c_inline" >&6; }

case $ac_cv_c_inline in
  inline | yes) ;;
  *)
    case $ac_cv_c_inline in
      no) ac_val=;;
      *) ac_val=$ac_cv_c_inline;;







|
|

|
>

|
|
>


|
|

|
|

|
>





|
|
>


|
|

|
|





|
|


|
|

|
>





|
|
>


|
|













>
>
>
>
>
>
>
>
>









|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|












|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|







>
|
>
>
>

|
|




|















|


|
>



|
|

|
|










|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|












|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|











|
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|

|


|


|






|









|







|











|
|
|




















|


|
|
>
|
|














|




|










|
|
>

|
>
|
|
|


|
|

|
|
|
|
>

|
|
|
|




|
|






|


|
|
>
|
|
|
|









|
|
|

|
>


|
|








|


>
>









|
|







|


|







|


|






|
|
|
|
|



|
|

|
>

|
|
|
>
|
|
|



|













|


|
|
>








|
|


|
|

|
>

|
>

|
|


|
|
|
>
|
|
|



|









|
>

|
|
>

|

|
>

|
|
>
>





|

|
|
|
>
|
|
|







|






|
>

|
|




|






|
>

|
|





|






|
>


|
>

|
>

|
|
>

|
|
|














>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<


|
>


|



|
|

|
|
<
<
<
|
|
|
<
>
|
>
>
>
>
|
|
>

>
|
|
>
>









|
|
|
>
|
|
|





|
|



|
>


|


|
>

|
|







2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927





















3928



























3929
3930

3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945



3946
3947
3948

3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
TK_SRC_DIR="`cd "$srcdir"/..; pwd`"

#------------------------------------------------------------------------
# Compress and/or soft link the manpages?
#------------------------------------------------------------------------


    { 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+y}
then :
  enableval=$enable_man_symlinks; test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"
else case e in #(
  e) enableval="no" ;;
esac
fi

    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
printf "%s\n" "$enableval" >&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+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 case e in #(
  e) enableval="no" ;;
esac
fi

    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
printf "%s\n" "$enableval" >&6; }
    if test "$enableval" != "no"; then
	{ 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"
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $Z" >&5
printf "%s\n" "$Z" >&6; }
    fi

    { 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+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 case e in #(
  e) enableval="no" ;;
esac
fi

    { 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
{ 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 case e in #(
  e) 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}gcc"
    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 ;;
esac
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 "gcc", so it can be a program name with args.
set dummy gcc; 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 case e in #(
  e) 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="gcc"
    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 ;;
esac
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

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
{ 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 case e in #(
  e) 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}cc"
    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 ;;
esac
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
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
{ 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 case e in #(
  e) 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 #(((
    '') 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
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    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+' '}$@"
  fi
fi
fi ;;
esac
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 "$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
{ 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 case e in #(
  e) 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$ac_prog"
    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 ;;
esac
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


    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
{ 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 case e in #(
  e) 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="$ac_prog"
    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 ;;
esac
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


  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:)
{ 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 case e in #(
  e) 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 ;;
esac
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 case e in #(
  e) 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 ;;
esac
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" && { { 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.
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 -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\""
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
  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 (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.
{ 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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  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+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 case e in #(
  e) ac_file='' ;;
esac
fi
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

{ { 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 case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; } ;;
esac
fi
{ 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
{ 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\""
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; }
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 case e in #(
  e) { { 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; } ;;
esac
fi
rm -f conftest conftest$ac_cv_exeext
{ 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 (void)
{
FILE *f = fopen ("conftest.out", "w");
 if (!f)
  return 1;
 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.
{ 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\""
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; }
  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\""
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
    cross_compiling=no
  else
    if test "$cross_compiling" = maybe; then
	cross_compiling=yes
    else
	{ { 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
{ 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.o conftest.obj conftest.out
ac_clean_files=$ac_clean_files_save
{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  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 case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { 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; } ;;
esac
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext ;;
esac
fi
{ 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
{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_compiler_gnu=yes
else case e in #(
  e) ac_compiler_gnu=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
 ;;
esac
fi
{ 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+y}
ac_save_CFLAGS=$CFLAGS
{ 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 case e in #(
  e) 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 (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_g=yes
else case e in #(
  e) CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :

else case e in #(
  e) ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 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_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag ;;
esac
fi
{ 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
ac_prog_cc_stdc=no
if test x$ac_prog_cc_stdc = xno
then :
  { 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 case e in #(
  e) 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 ;;
esac
fi

if test "x$ac_cv_prog_cc_c11" = xno
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
else case e in #(
  e) if test "x$ac_cv_prog_cc_c11" = x
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
else case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
     CC="$CC $ac_cv_prog_cc_c11" ;;
esac
fi
  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
  ac_prog_cc_stdc=c11 ;;
esac
fi
fi
if test x$ac_prog_cc_stdc = xno
then :
  { 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 case e in #(
  e) ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_c_conftest_c99_program
_ACEOF
for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
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 ;;
esac
fi

if test "x$ac_cv_prog_cc_c99" = xno
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
else case e in #(
  e) if test "x$ac_cv_prog_cc_c99" = x
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
else case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
     CC="$CC $ac_cv_prog_cc_c99" ;;
esac
fi
  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
  ac_prog_cc_stdc=c99 ;;
esac
fi
fi
if test x$ac_prog_cc_stdc = xno
then :
  { 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 case e in #(
  e) ac_cv_prog_cc_c89=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 '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"

do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC ;;
esac
fi

if test "x$ac_cv_prog_cc_c89" = xno



then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }

else case e in #(
  e) if test "x$ac_cv_prog_cc_c89" = x
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
else case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
     CC="$CC $ac_cv_prog_cc_c89" ;;
esac
fi
  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
  ac_prog_cc_stdc=c89 ;;
esac
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


{ 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 case e in #(
  e) 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 (void) {return 0; }
$ac_kw foo_t foo (void) {return 0; }
#endif

_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_inline=$ac_kw
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
  test "$ac_cv_c_inline" != no && break
done
 ;;
esac
fi
{ 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
4223

#------------------------------------------------------------------------
# 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

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_cc_pipe=yes
else
  tcl_cv_cc_pipe=no

fi
rm -f core conftest.err conftest.$ac_objext 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; }
    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 :

  withval=$with_encoding; with_tcencoding=${withval}
fi


    if test x"${with_tcencoding}" != x ; then

cat >>confdefs.h <<_ACEOF
#define TCL_CFGVAL_ENCODING "${with_tcencoding}"
_ACEOF

    else

$as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>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; }
    # Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :

  enableval=$enable_shared; tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
$as_echo "shared" >&6; }
	SHARED_BUILD=1
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
	SHARED_BUILD=0

$as_echo "#define STATIC_BUILD 1" >>confdefs.h

    fi



#--------------------------------------------------------------------
# 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
  if test -n "$RANLIB"; then
  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
$as_echo "$RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RANLIB"; then
  ac_ct_RANLIB=$RANLIB
  # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_RANLIB"; then
  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RANLIB="ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
$as_echo "$ac_ct_RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_RANLIB" = x; then
    RANLIB=":"
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RANLIB=$ac_ct_RANLIB
  fi
else
  RANLIB="$ac_cv_prog_RANLIB"
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
$as_echo_n "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
  if ${ac_cv_prog_CPP+:} false; then :
  $as_echo_n "(cached) " >&6
else
      # Double quotes because CPP needs to be expanded
    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
    do
      ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :

else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -z "$GREP"; then
  ac_path_GREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in grep ggrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
  # Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
$as_echo "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if ${ac_cv_path_EGREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
   then ac_cv_path_EGREP="$GREP -E"
   else
     if test -z "$EGREP"; then
  ac_path_EGREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in egrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
  # Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
*GNU*)
  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'EGREP' >> "conftest.nl"
    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP="$ac_path_EGREP"
      ac_path_EGREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_EGREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP"; then
    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_EGREP=$EGREP
fi

   fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
$as_echo "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_header_stdc=yes
else
  ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

if test $ac_cv_header_stdc = yes; then
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <string.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "free" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  if test "$cross_compiling" = yes; then :
  :
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ctype.h>
#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# 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

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; }
    # Check whether --enable-64bit was given.
if test "${enable_64bit+set}" = set; then :

  enableval=$enable_64bit; do64bit=$enableval
else
  do64bit=no

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
$as_echo "$do64bit" >&6; }

    # 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; }
    # Check whether --enable-64bit-vis was given.
if test "${enable_64bit_vis+set}" = set; then :

  enableval=$enable_64bit_vis; do64bitVIS=$enableval
else
  do64bitVIS=no

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
$as_echo "$do64bitVIS" >&6; }
    # Force 64bit on with VIS
    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

	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 ()
{
f();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_cc_visibility_hidden=yes
else
  tcl_cv_cc_visibility_hidden=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :



$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h


$as_echo "#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; }
    # Check whether --enable-rpath was given.
if test "${enable_rpath+set}" = set; then :

  enableval=$enable_rpath; doRpath=$enableval
else
  doRpath=yes

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
$as_echo "$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

	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;}
		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; }
    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
  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 ()
{
return dlopen ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_dl_dlopen=yes
else
  ac_cv_lib_dl_dlopen=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  have_dl=yes
else
  have_dl=no

fi


    # Require ranlib early so we can override it in special cases below.










|
|
|
>
|
|
|





|






|
>

|
|
>

|
|
>

|
|












|
>






<
|
<



|





|
|

|
>

|
|
<
|
<
<
<
<
<
<
|


|
|


|
|


|














|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
|
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|
|

|
>

|
|
>


|
|



|
|

|
>

|
|
>


|
|

|
>






|
|
|
>
|
|
|







|






|
>

|
|
>

|

|
>

|
|
|
>


|


|






|
|

|
>

|
|
>


|
|





|
|
|
>
|
|
|





|
|










|
>

|
|






|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>

|
|
>







4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076

4077

4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094

4095






4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223


















4224
4225












4226


4227
4228


4229
4230

















4231






4232


4233


4234
4235
4236












































4237















































































4238
4239















































4240











4241





4242
4243











4244




















4245











4246




4247



4248






















































4249
4250
4251


















4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451

#------------------------------------------------------------------------
# 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
    { 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 case e in #(
  e)
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cc_pipe=yes
else case e in #(
  e) tcl_cv_cc_pipe=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	CFLAGS=$hold_cflags ;;
esac
fi
{ 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+y}
then :
  withval=$with_encoding; with_tcencoding=${withval}
fi


    if test x"${with_tcencoding}" != x ; then


printf "%s\n" "#define TCL_CFGVAL_ENCODING \"${with_tcencoding}\"" >>confdefs.h


    else

printf "%s\n" "#define TCL_CFGVAL_ENCODING \"utf-8\"" >>confdefs.h

    fi



    { 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+y}
then :
  enableval=$enable_shared; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=yes ;;

esac






fi

    if test "$tcl_ok" = "yes" ; then
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared" >&5
printf "%s\n" "shared" >&6; }
	SHARED_BUILD=1
    else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static" >&5
printf "%s\n" "static" >&6; }
	SHARED_BUILD=0

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
{ 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 case e in #(
  e) 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 #(((
    '') 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_RANLIB="${ac_tool_prefix}ranlib"
    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 ;;
esac
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
printf "%s\n" "$RANLIB" >&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_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
{ 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 case e in #(
  e) 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 #(((
    '') 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_RANLIB="ranlib"
    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 ;;
esac
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
printf "%s\n" "$ac_ct_RANLIB" >&6; }
else
  { 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:)
{ 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_header= ac_cache=


















for ac_item in $ac_header_c_list
do












  if test $ac_cache; 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


      printf "%s\n" "#define $ac_item 1" >> confdefs.h
    fi

















    ac_header= ac_cache=






  elif test $ac_header; then


    ac_cache=$ac_item


  else
    ac_header=$ac_item
  fi












































done
































































































































































































if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes




then :


























































printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h

fi




















    # Step 0.a: Enable 64 bit support?

    { 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+y}
then :
  enableval=$enable_64bit; do64bit=$enableval
else case e in #(
  e) do64bit=no ;;
esac
fi

    { 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?

    { 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+y}
then :
  enableval=$enable_64bit_vis; do64bitVIS=$enableval
else case e in #(
  e) do64bitVIS=no ;;
esac
fi

    { 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 :
  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.

    { 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 case e in #(
  e)
	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 (void)
{
f();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_visibility_hidden=yes
else case e in #(
  e) tcl_cv_cc_visibility_hidden=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	CFLAGS=$hold_cflags ;;
esac
fi
{ 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 :


printf "%s\n" "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h


printf "%s\n" "#define HAVE_HIDDEN 1" >>confdefs.h


fi

    # Step 0.d: Disable -rpath support?

    { 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+y}
then :
  enableval=$enable_rpath; doRpath=$enableval
else case e in #(
  e) doRpath=yes ;;
esac
fi

    { 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.


    { 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 case e in #(
  e)
	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
		{ 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
     ;;
esac
fi
{ 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.

    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char dlopen (void);
int
main (void)
{
return dlopen ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_dl_dlopen=yes
else case e in #(
  e) ac_cv_lib_dl_dlopen=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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 case e in #(
  e) have_dl=no ;;
esac
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
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
    # 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 :


	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac


else

	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
  if test -n "$AR"; then
  ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_AR="${ac_tool_prefix}ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_AR"; then
  ac_ct_AR=$AR
  # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_AR"; then
  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_AR="ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_AR" = x; then
    AR=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    AR=$ac_ct_AR
  fi
else
  AR="$ac_cv_prog_AR"
fi

    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    PLAT_OBJS=""
    PLAT_SRCS=""
    LDAIX_SRC=""
    if test "x${SHLIB_VERSION}" = x; then :

  SHLIB_VERSION="1.0"
fi
    case $system in
	AIX-*)
	    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; }

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 "$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;}

else

		    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 :


		# 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 :


		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'

else

		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'


fi
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'

else

		if test "$GCC" = yes; then :


		    SHLIB_LD='${CC} -shared -Wl,-bexpall'

else

		    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"
		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}


fi
	    ;;
	BeOS*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} -nostart'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    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
  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 ()
{
return inet_ntoa ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_bind_inet_ntoa=yes
else
  ac_cv_lib_bind_inet_ntoa=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  LIBS="$LIBS -lbind -lsocket"
fi

	    ;;
	BSD/OS-2.1*|BSD/OS-3*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="shlicc -r"







|
>







|




|
|


|
>




|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|













|
>




|
>











|
|














|
>

|
>

|
|

|
|






|
>




|
>





|
>



|
|

|
>



|
|
|
>



|
|


|
>





|
>














|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>







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
    # 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 :

	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
		;;
	esac


else case e in #(
  e)
	CFLAGS_OPTIMIZE=-O
	CFLAGS_WARNING=""
     ;;
esac
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
{ 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 case e in #(
  e) 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 #(((
    '') 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_AR="${ac_tool_prefix}ar"
    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 ;;
esac
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
printf "%s\n" "$AR" >&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_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
{ 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 case e in #(
  e) 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 #(((
    '') 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_AR="ar"
    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 ;;
esac
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
printf "%s\n" "$ac_ct_AR" >&6; }
else
  { 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:)
{ 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 :
  SHLIB_VERSION="1.0"
fi
    case $system in
	AIX-*)
	    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
		{ 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 "$GCC" = yes
then :

		    { 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 case e in #(
  e)
		    do64bit_ok=yes
		    CFLAGS="$CFLAGS -q64"
		    LDFLAGS_ARCH="-q64"
		    RANLIB="${RANLIB} -X64"
		    AR="${AR} -X64"
		    SHLIB_LD_FLAGS="-b64"
		 ;;
esac
fi

fi

	    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 :

		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'

else case e in #(
  e)
		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
		 ;;
esac
fi
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'

else case e in #(
  e)
		if test "$GCC" = yes
then :

		    SHLIB_LD='${CC} -shared -Wl,-bexpall'

else case e in #(
  e)
		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
		    LDFLAGS="$LDFLAGS -brtl"
		 ;;
esac
fi
		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
		DL_LIBS="-ldl"
		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	     ;;
esac
fi
	    ;;
	BeOS*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} -nostart'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    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.
	    #-----------------------------------------------------------
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char inet_ntoa (void);
int
main (void)
{
return inet_ntoa ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_bind_inet_ntoa=yes
else case e in #(
  e) ac_cv_lib_bind_inet_ntoa=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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
4566
4567
4568
4569
4570
4571
4572
4573
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*)
	    SHLIB_CFLAGS="-fno-common"
	    SHLIB_LD='${CC} -shared'
	    SHLIB_SUFFIX=".dll"
	    DL_OBJS="tclLoadDl.o"
	    PLAT_OBJS='${CYGWIN_OBJS}'
	    PLAT_SRCS='${CYGWIN_SRCS}'
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    TCL_NEEDS_EXP_FILE=1
	    TCL_EXPORT_FILE_SUFFIX='${VERSION}.dll.a'
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\[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
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#ifdef __CYGWIN__
		    #error cygwin
		#endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_cygwin=no
else
  ac_cv_cygwin=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cygwin" >&5
$as_echo "$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.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
		then :
		else
		    { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
		fi
	    fi
	    ;;
	dgux*)







|









<
<
<
|
|
|
>
|
|
|







|






|
>

|
|
>

|
|
>

|
|





|

|







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
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*|MINGW32_*|MSYS_*)
	    SHLIB_CFLAGS="-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=""



	    { 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#ifdef __CYGWIN__
		    #error cygwin
		#endif

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_cygwin=no
else case e in #(
  e) ac_cv_cygwin=yes ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	     ;;
esac
fi
{ 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 --enable-64bit --host=x86_64-w64-mingw32"
		# The eval makes quoting arguments work.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32; cd ../unix
		then :
		else
		    { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
		fi
	    fi
	    ;;
	dgux*)
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
	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
  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 ()
{
return inet_ntoa ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_network_inet_ntoa=yes
else
  ac_cv_lib_network_inet_ntoa=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  LIBS="$LIBS -lnetwork"
fi

	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible

$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h


$as_echo "#define _XOPEN_SOURCE 1" >>confdefs.h

	    LIBS="$LIBS -lxnet"               # Use the XOPEN network library

	    if test "`uname -m`" = ia64; then :


		SHLIB_SUFFIX=".so"

else

		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
  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 ()
{
return shl_load ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_dld_shl_load=yes
else
  ac_cv_lib_dld_shl_load=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  tcl_ok=yes
else
  tcl_ok=no

fi

	    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 :


		SHLIB_LD='${CC} -shared'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

else

		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 "$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 :


				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;}
			    ;;
		    esac

else

		    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
  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 ()
{
return shl_load ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_dld_shl_load=yes
else
  ac_cv_lib_dld_shl_load=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  tcl_ok=yes
else
  tcl_ok=no

fi

	    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"







|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>







|


|



|
>



|
|

|
>

|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>

|
|
>


|
>











|
>




|
|

|
>






|
>

|
>






|
>






|
|



|
|



|
>





|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>

|
|
>


|
>







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
	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"
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char inet_ntoa (void);
int
main (void)
{
return inet_ntoa ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_network_inet_ntoa=yes
else case e in #(
  e) ac_cv_lib_network_inet_ntoa=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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

printf "%s\n" "#define _XOPEN_SOURCE_EXTENDED 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 :

		SHLIB_SUFFIX=".so"

else case e in #(
  e)
		SHLIB_SUFFIX=".sl"
	     ;;
esac
fi
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char shl_load (void);
int
main (void)
{
return shl_load ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_dld_shl_load=yes
else case e in #(
  e) ac_cv_lib_dld_shl_load=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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 case e in #(
  e) tcl_ok=no ;;
esac
fi

	    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 :

		SHLIB_LD='${CC} -shared'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

else case e in #(
  e)
		CFLAGS="$CFLAGS -z"
	     ;;
esac
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 "$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 :

				CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
fi
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    { 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 case e in #(
  e)
		    do64bit_ok=yes
		    CFLAGS="$CFLAGS +DD64"
		    LDFLAGS_ARCH="+DD64"
		 ;;
esac
fi

fi ;;
	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
	    SHLIB_SUFFIX=".sl"
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char shl_load (void);
int
main (void)
{
return shl_load ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_dld_shl_load=yes
else case e in #(
  e) ac_cv_lib_dld_shl_load=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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 case e in #(
  e) tcl_ok=no ;;
esac
fi

	    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
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
	    DL_LIBS=""
	    case " $LIBOBJS " in
  *" mkstemp.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
 ;;
esac

	    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 :


		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
	    if test "$GCC" = yes; then :


		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"

else

		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
			;;
		    *)
			CFLAGS="$CFLAGS -n32"
			;;
		esac
		LDFLAGS="$LDFLAGS -n32"


fi
	    ;;
	IRIX64-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 :


		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 "$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;}

else

	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"


fi

fi
	    ;;
	Linux*|GNU*|NetBSD-Debian)
	    SHLIB_CFLAGS="-fPIC -fno-common"
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"










	    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 :

  CFLAGS="$CFLAGS -mieee"
fi
	    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

		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_cc_m64=yes
else
  tcl_cv_cc_m64=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		    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 :

  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 :


		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 :


		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"







|
>

















|
>




|
>




|
|










|
>














|
>







|
>

|
>

|
|

|
|




|
>




|













>
>
>
>
>
>
>
>
>
>
|
>




|
>


|
>

|
|
|
>
|
|
|






|






|
>

|
|
>

|

|
>

|
|
|
>














|
>











|
>



















|
>







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
	    DL_LIBS=""
	    case " $LIBOBJS " in
  *" mkstemp.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
 ;;
esac

	    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 :

		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
	    if test "$GCC" = yes
then :

		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"

else case e in #(
  e)
		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
			;;
		    *)
			CFLAGS="$CFLAGS -n32"
			;;
		esac
		LDFLAGS="$LDFLAGS -n32"
	     ;;
esac
fi
	    ;;
	IRIX64-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 :

		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 "$GCC" = yes
then :

	            { 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 case e in #(
  e)
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	         ;;
esac
fi

fi
	    ;;
	Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*)
	    SHLIB_CFLAGS="-fPIC -fno-common"
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"

	    case $system in
	    DragonFly-*|FreeBSD-*)
		# The -pthread needs to go in the LDFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
	    ;;
	    esac

	    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 :
  CFLAGS="$CFLAGS -mieee"
fi
	    if test $do64bit = yes
then :

		{ 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 case e in #(
  e)
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_m64=yes
else case e in #(
  e) tcl_cv_cc_m64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		    CFLAGS=$hold_cflags ;;
esac
fi
{ 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 :
  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 :

		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 :

		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
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072

5073
5074
5075
5076
5077
5078

5079
5080





5081





































5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095

5096
5097
5098

5099
5100
5101
5102

5103
5104
5105
5106

5107
5108
5109
5110
5111
5112
5113
5114
5115

5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132

5133
5134
5135

5136
5137
5138
5139

5140
5141
5142
5143

5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158

5159
5160
5161
5162

5163
5164
5165
5166
5167

5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184

5185
5186
5187

5188
5189
5190
5191

5192
5193
5194
5195

5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206

5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223

5224
5225
5226

5227
5228
5229
5230

5231
5232
5233
5234

5235
5236
5237
5238
5239

5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258

5259
5260
5261

5262
5263
5264
5265
5266

5267
5268
5269
5270

5271
5272
5273
5274
5275

5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297

5298
5299
5300

5301
5302
5303
5304

5305
5306
5307
5308
5309
5310

5311
5312
5313
5314

5315
5316
5317
5318
5319
5320
5321
5322

5323
5324

5325
5326
5327
5328

5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346

5347
5348
5349

5350
5351
5352
5353
5354
5355

5356
5357
5358
5359

5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382

5383
5384
5385
5386
5387
5388
5389

5390
5391
5392
5393
5394

5395
5396
5397
5398
5399

5400
5401
5402
5403

5404
5405
5406
5407
5408
5409

5410
5411
5412
5413
5414
5415
5416
5417

5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436

5437
5438
5439
5440
5441
5442
5443
5444
5445

5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472

5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483

5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500

5501
5502
5503

5504
5505

5506
5507

5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518

5519
5520
5521
5522
5523
5524

5525
5526
5527
5528
5529
5530
5531
5532
5533

5534
5535
5536
5537

5538
5539
5540
5541

5542
5543

5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566

5567
5568
5569
5570
5571

5572

5573
5574
5575
5576
5577
5578
5579
5580
5581

5582
5583
5584
5585
5586
5587
5588

5589
5590
5591
5592
5593
5594

5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606

5607
5608

5609
5610
5611
5612
5613

5614
5615
5616
5617
5618

5619
5620

5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631

5632
5633
5634
5635

5636
5637
5638
5639
5640
5641
5642

5643
5644
5645

5646
5647
5648
5649
5650
5651
5652
5653
5654
5655

5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669

5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686

5687
5688
5689

5690
5691
5692
5693

5694
5695
5696
5697

5698
5699
5700
5701
5702
5703
5704
5705
5706
5707

5708
5709
5710
5711
5712
5713
5714

5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727

5728
5729
5730

5731
5732
5733

5734
5735
5736
5737

5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752

5753
5754
5755
5756
5757
5758
5759
5760

5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777

5778
5779
5780
5781
5782
5783
5784
5785

5786
5787
5788
5789

5790
5791
5792
5793
5794
5795

5796
5797
5798
5799

5800
5801
5802
5803
5804
5805
5806
5807

5808
5809
5810
5811
5812
5813
5814

5815
5816
5817
5818
5819
5820
5821

5822
5823
5824

5825
5826
5827
5828

5829
5830
5831
5832
5833
5834
5835

5836
5837
5838
5839
5840
5841
5842

5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854

5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871

5872
5873
5874

5875
5876
5877

5878
5879
5880
5881



















































5882



5883
5884









5885









5886
5887
5888

5889
5890
5891
5892
5893


























5894
5895
5896
5897
5898
5899
5900
	    # 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 :


		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 :

		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"
	    LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
	    case $system in
	    FreeBSD-3.*)
		# Version numbers are dot-stripped by system policy.
		TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
		TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	Darwin-*)
	    CFLAGS_OPTIMIZE="-Os"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
	    # preprocessing tests and compiling tests, move any -isysroot and
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
	    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











































			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_cc_arch_ppc64=yes
else
  tcl_cv_cc_arch_ppc64=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


			    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

			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_cc_arch_x86_64=yes
else
  tcl_cv_cc_arch_x86_64=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


			    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;};;
		esac

else

		# 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 :


		    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

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_ld_single_module=yes
else
  tcl_cv_ld_single_module=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		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

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_ld_search_paths_first=yes
else
  tcl_cv_ld_search_paths_first=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"

fi
	    if test "$tcl_cv_cc_visibility_hidden" != yes; then :



$as_echo "#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

	    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; }
	    # Check whether --enable-corefoundation was given.
if test "${enable_corefoundation+set}" = set; then :

  enableval=$enable_corefoundation; tcl_corefoundation=$enableval
else
  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 :


		{ $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

		    hold_libs=$LIBS
		    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 ()
{
CFBundleRef b = CFBundleGetMainBundle();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_lib_corefoundation=yes
else
  tcl_cv_lib_corefoundation=no

fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
		    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 :


		    LIBS="$LIBS -framework CoreFoundation"

$as_echo "#define HAVE_COREFOUNDATION 1" >>confdefs.h


else
  tcl_corefoundation=no

fi
		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

			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 ()
{
CFBundleRef b = CFBundleGetMainBundle();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_lib_corefoundation_64=yes
else
  tcl_cv_lib_corefoundation_64=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :



$as_echo "#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

	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    if test "$SHARED_BUILD" = 1; then :


	        SHLIB_LD='ld -shared -expect_unresolved "*"'

else

	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'


fi
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    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 :

  CFLAGS="$CFLAGS -mieee"
else

		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 :


		LIBS="$LIBS -lpthread -lmach -lexc"

else

		CFLAGS="$CFLAGS -pthread"
		LDFLAGS="$LDFLAGS -pthread"


fi
	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    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 :


		SHLIB_CFLAGS="-fPIC -melf"
		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"

else

		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


$as_echo "#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 :


		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

else

		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


$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h


	    SHLIB_CFLAGS="-KPIC"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = yes; then :


		arch=`isainfo`
		if test "$arch" = "sparcv9 sparc"; then :


		    if test "$GCC" = yes; 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;}

else

			    do64bit_ok=yes
			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
			    SHLIB_CFLAGS="-fPIC"


fi

else

			do64bit_ok=yes
			if test "$do64bitVIS" = yes; then :


			    CFLAGS="$CFLAGS -xarch=v9a"
			    LDFLAGS_ARCH="-xarch=v9a"

else

			    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 :


		    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;};;
			esac

else

			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;}

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 :

  use_sunmath=no
else

		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 :


			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "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 :


fi


			use_sunmath=yes

else

			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
			use_sunmath=no


fi


fi
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    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 "$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 :


			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"

fi

fi

fi

else

		if test "$use_sunmath" = yes; then :

  textmode=textoff
else
  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";;
		esac
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'


fi
	    ;;
	UNIX_SV* | UnixWare-5*)
	    SHLIB_CFLAGS="-KPIC"
	    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

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_ld_Bexport=yes
else
  tcl_cv_ld_Bexport=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		LDFLAGS="$LDFLAGS -Wl,-Bexport"

fi
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
    esac

    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;}

fi

    if test "$do64bit" = yes -a "$do64bit_ok" = yes; then :



$as_echo "#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 :

  enableval=$enable_load; tcl_ok=$enableval
else
  tcl_ok=yes

fi

    if test "$tcl_ok" = no; then :

  DL_OBJS=""
fi

    if test "x$DL_OBJS" != x; then :

  BUILD_DLTEST="\$(DLTEST_TARGETS)"
else

	{ $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;}
	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 :


	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    HP_UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    OSF1-V*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi

    if test "$tcl_cv_cc_visibility_hidden" != yes; then :



$as_echo "#define MODULE_SCOPE extern" >>confdefs.h


fi

    if test "$SHARED_LIB_SUFFIX" = ""; then :


	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
fi
    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 :


        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 :


            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

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'


fi

else

        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

        if test "$RANLIB" = ""; then :


            MAKE_LIB='$(STLIB_LD) $@ ${OBJS}'

else

            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 :


        MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}'

else

        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 :


        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
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_cast_to_union=yes
else
  tcl_cv_cast_to_union=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
$as_echo "$tcl_cv_cast_to_union" >&6; }
	if test "$tcl_cv_cast_to_union" = "yes"; then























































$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h










	fi










    ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
if test "x$ac_cv_header_stdbool_h" = xyes; then :


$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h

fi





























    # 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.









|
>









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|










|
>



|
|
|
>
|
|
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|




|






|
>
|
|
|
>

|

|
>

|
|
|
>

|



|
|
|
|
>
|
|
|

|




|






|
>
|
|
|
>

|

|
>

|
|
|
>

|




|
|


|
|

|
|
>



|
>


|
|
|
>
|
|
|






|






|
>

|
|
>

|

|
>

|
|
|
>








|
|
|
>
|
|
|






|






|
>

|
|
>

|

|
>

|
|
|
>




|
>


|






|

|



|
|

|
>

|
|
>


|
|
|
>

|
|
|
>
|
|
|

|
>














|






|
>

|
|
>

|

|
>





|
>

|
|
|
>



|


|
|
>

|
>

|
|
|
>
|
|
|







|






|
>

|
|
>

|



|
>

|
|
|
>


|













|





|
>

|

|
|
|
|
>




|
>




|
>

|
|
|
>





|
>



|
|


|
>


















|
>




|
|


|
>
















|


|






|
>





|
|



|
>







|


|





|
>


|
>

|
>

|
>

|
|

|
|




|
>


|
|

|
>




|
|


|
>



|
>


|
|
>

|
>







|
|


|
|









|
>


|
|
|
>
|
>








|
>

|
|

|
|
|
>

|
|

|
|
>


<



|
|
|
|

|
>

|
>




|
>




|
>

|
>









|
|
>



|
>




|
|
|
>

|
|
>









|
>











|
|
|
>
|
|
|






|






|
>

|
|
>

|

|
>

|
|
|
>









|
>

|
|



|
>


|









|
>

|
|
>


|
>



|
>

|
|
|
|









|
>







|
>




|
|




|





|
>


|




|
>



|
>





|
>



|
>

|


|
|

|
>


|
|


|
>



|
|

|
>


|
>



|
>



|
|

|
>






|
>





|
|
|

|
|
|
>
|
|
|



|


|
|





|
>

|
|
>

|
|
>

|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>

|
|
>

|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361


























5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008

6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
	    # 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 :

		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"
	    ;;


























	Darwin-*)
	    CFLAGS_OPTIMIZE="-O2"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
	    # preprocessing tests and compiling tests, move any -isysroot and
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
	    if test $do64bit = yes
then :

		case `arch` in
		    ppc)
			{ 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 case e in #(
  e)
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_arch_ppc64=yes
else case e in #(
  e) tcl_cv_cc_arch_ppc64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
			    CFLAGS=$hold_cflags ;;
esac
fi
{ 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|x86_64)
			{ 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 case e in #(
  e)
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_arch_x86_64=yes
else case e in #(
  e) tcl_cv_cc_arch_x86_64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
			    CFLAGS=$hold_cflags ;;
esac
fi
{ 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;;
		    arm64)
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch arm64 flag" >&5
printf %s "checking if compiler accepts -arch arm64 flag... " >&6; }
if test ${tcl_cv_cc_arch_arm64+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch arm64"
			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_arch_arm64=yes
else case e in #(
  e) tcl_cv_cc_arch_arm64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
			    CFLAGS=$hold_cflags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_arm64" >&5
printf "%s\n" "$tcl_cv_cc_arch_arm64" >&6; }
			if test $tcl_cv_cc_arch_arm64 = yes
then :

			    CFLAGS="$CFLAGS -arch arm64"
			    do64bit_ok=yes

fi;;
		    *)
			{ 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 case e in #(
  e)
		# Check for combined 32-bit and 64-bit fat build
		if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '
then :

		    fat_32_64=yes
fi
	     ;;
esac
fi
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    { 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 case e in #(
  e)
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_single_module=yes
else case e in #(
  e) tcl_cv_ld_single_module=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		LDFLAGS=$hold_ldflags ;;
esac
fi
{ 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"
	    { 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 case e in #(
  e)
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_search_paths_first=yes
else case e in #(
  e) tcl_cv_ld_search_paths_first=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		LDFLAGS=$hold_ldflags ;;
esac
fi
{ 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 :


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_FALLBACK_LIBRARY_PATH"

printf "%s\n" "#define MAC_OSX_TCL 1" >>confdefs.h

	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    { 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+y}
then :
  enableval=$enable_corefoundation; tcl_corefoundation=$enableval
else case e in #(
  e) tcl_corefoundation=yes ;;
esac
fi

	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_corefoundation" >&5
printf "%s\n" "$tcl_corefoundation" >&6; }
	    if test $tcl_corefoundation = yes
then :

		{ 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 case e in #(
  e)
		    hold_libs=$LIBS
		    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 (void)
{
CFBundleRef b = CFBundleGetMainBundle();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_lib_corefoundation=yes
else case e in #(
  e) tcl_cv_lib_corefoundation=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		    if test "$fat_32_64" = yes
then :

			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
		        done
fi
		    LIBS=$hold_libs ;;
esac
fi
{ 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"

printf "%s\n" "#define HAVE_COREFOUNDATION 1" >>confdefs.h


else case e in #(
  e) tcl_corefoundation=no ;;
esac
fi
		if test "$fat_32_64" = yes -a $tcl_corefoundation = yes
then :

		    { 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 case e in #(
  e)
			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 (void)
{
CFBundleRef b = CFBundleGetMainBundle();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_lib_corefoundation_64=yes
else case e in #(
  e) tcl_cv_lib_corefoundation_64=no ;;
esac
fi
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 ;;
esac
fi
{ 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 :


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

printf "%s\n" "#define _OE_SOCKETS 1" >>confdefs.h

	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    if test "$SHARED_BUILD" = 1
then :

	        SHLIB_LD='${CC} -shared'

else case e in #(
  e)
	        SHLIB_LD='${CC} -non_shared'
	     ;;
esac
fi
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    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 :
  CFLAGS="$CFLAGS -mieee"
else case e in #(
  e)
		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" ;;
esac
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 :

		LIBS="$LIBS -lpthread -lmach -lexc"

else case e in #(
  e)
		CFLAGS="$CFLAGS -pthread"
		LDFLAGS="$LDFLAGS -pthread"
	     ;;
esac
fi
	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    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 :

		SHLIB_CFLAGS="-fPIC -melf"
		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"

else case e in #(
  e)
		SHLIB_CFLAGS="-Kpic -belf"
		LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
	     ;;
esac
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.


printf "%s\n" "#define _REENTRANT 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 :

		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

else case e in #(
  e)
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	     ;;
esac
fi
	    ;;
	SunOS-5*)
	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.


printf "%s\n" "#define _REENTRANT 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 :

		arch=`isainfo`
		if test "$arch" = "sparcv9 sparc"
then :

		    if test "$GCC" = yes
then :

			if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3
then :

			    { 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 case e in #(
  e)
			    do64bit_ok=yes
			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
			    SHLIB_CFLAGS="-fPIC"
			 ;;
esac
fi

else case e in #(
  e)
			do64bit_ok=yes
			if test "$do64bitVIS" = yes
then :

			    CFLAGS="$CFLAGS -xarch=v9a"
			    LDFLAGS_ARCH="-xarch=v9a"

else case e in #(
  e)
			    CFLAGS="$CFLAGS -xarch=v9"
			    LDFLAGS_ARCH="-xarch=v9"
			 ;;
esac
fi
			# Solaris 64 uses this as well
			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
		     ;;
esac
fi

else case e in #(
  e) if test "$arch" = "amd64 i386"
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";;
			    *)
				{ 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 case e in #(
  e)
			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
		     ;;
esac
fi

else case e in #(
  e) { 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;} ;;
esac
fi ;;
esac
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 :
  use_sunmath=no
else case e in #(
  e)
		arch=`isainfo`
		{ 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 :

			{ 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_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 case e in #(
  e)
			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
			use_sunmath=no
		 ;;
esac
fi
	     ;;
esac
fi
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    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 "$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 case e in #(
  e) if test "$arch" = "amd64 i386"
then :

			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"

fi ;;
esac
fi

fi

else case e in #(
  e)
		if test "$use_sunmath" = yes
then :
  textmode=textoff
else case e in #(
  e) textmode=text ;;
esac
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";;
		esac
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	     ;;
esac
fi
	    ;;
	UNIX_SV* | UnixWare-5*)
	    SHLIB_CFLAGS="-KPIC"
	    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.
	    { 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 case e in #(
  e)
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_Bexport=yes
else case e in #(
  e) tcl_cv_ld_Bexport=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	        LDFLAGS=$hold_ldflags ;;
esac
fi
{ 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 :

	{ 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 :


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+y}
then :
  enableval=$enable_load; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=yes ;;
esac
fi

    if test "$tcl_ok" = no
then :
  DL_OBJS=""
fi

    if test "x$DL_OBJS" != x
then :
  BUILD_DLTEST="\$(DLTEST_TARGETS)"
else case e in #(
  e)
	{ 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=""
     ;;
esac
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 :

	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*|MSYS_*) ;;
	    HP-UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    OSF1-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi

    if test "$tcl_cv_cc_visibility_hidden" != yes
then :


printf "%s\n" "#define MODULE_SCOPE extern" >>confdefs.h


fi

    if test "$SHARED_LIB_SUFFIX" = ""
then :

	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
fi
    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 :

        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 :

            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"

else case e in #(
  e)
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
         ;;
esac
fi

else case e in #(
  e)
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

        if test "$RANLIB" = ""
then :

            MAKE_LIB='$(STLIB_LD) $@ ${OBJS}'

else case e in #(
  e)
            MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@'
         ;;
esac
fi
        INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
     ;;
esac
fi

    # Stub lib does not depend on shared/static configuration
    if test "$RANLIB" = ""
then :

        MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}'

else case e in #(
  e)
        MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS} ; ${RANLIB} $@'
     ;;
esac
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 :

        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.

    { 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
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 :
  tcl_cv_cast_to_union=yes
else case e in #(
  e) tcl_cv_cast_to_union=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     ;;
esac
fi
{ 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

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 case e in #(
  e) 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 case e in #(
  e) ac_cv_nolto=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     ;;
esac
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
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -finput-charset" >&5
printf %s "checking if the compiler understands -finput-charset... " >&6; }
if test ${tcl_cv_cc_input_charset+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8"
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cc_input_charset=yes
else case e in #(
  e) tcl_cv_cc_input_charset=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	CFLAGS=$hold_cflags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_input_charset" >&5
printf "%s\n" "$tcl_cv_cc_input_charset" >&6; }
    if test $tcl_cv_cc_input_charset = yes; then
	CFLAGS="$CFLAGS -finput-charset=UTF-8"
    fi

    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 :

printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h

fi


    # Check for vfork, posix_spawnp() and friends unconditionally
    ac_fn_c_check_func "$LINENO" "vfork" "ac_cv_func_vfork"
if test "x$ac_cv_func_vfork" = xyes
then :
  printf "%s\n" "#define HAVE_VFORK 1" >>confdefs.h

fi
ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp"
if test "x$ac_cv_func_posix_spawnp" = xyes
then :
  printf "%s\n" "#define HAVE_POSIX_SPAWNP 1" >>confdefs.h

fi
ac_fn_c_check_func "$LINENO" "posix_spawn_file_actions_adddup2" "ac_cv_func_posix_spawn_file_actions_adddup2"
if test "x$ac_cv_func_posix_spawn_file_actions_adddup2" = xyes
then :
  printf "%s\n" "#define HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 1" >>confdefs.h

fi
ac_fn_c_check_func "$LINENO" "posix_spawnattr_setflags" "ac_cv_func_posix_spawnattr_setflags"
if test "x$ac_cv_func_posix_spawnattr_setflags" = xyes
then :
  printf "%s\n" "#define HAVE_POSIX_SPAWNATTR_SETFLAGS 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







cat >>confdefs.h <<_ACEOF
#define TCL_SHLIB_EXT "${SHLIB_SUFFIX}"
_ACEOF











    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
$as_echo_n "checking for build with symbols... " >&6; }
    # Check whether --enable-symbols was given.
if test "${enable_symbols+set}" = set; then :

  enableval=$enable_symbols; tcl_ok=$enableval
else
  tcl_ok=no

fi

# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'

$as_echo "#define NDEBUG 1" >>confdefs.h

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }

$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h

    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	if test "$tcl_ok" = "yes"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
$as_echo "yes (standard debugging)" >&6; }
	fi
    fi



    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then

$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h

    fi



    if test "$tcl_ok" != "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; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
$as_echo "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; }
    tcl_flags=""

    if ${tcl_cv_flag__isoc99_source+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
int
main ()
{
char *p = (char *)strtoll; char *q = (char *)strtoull;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_flag__isoc99_source=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _ISOC99_SOURCE 1
#include <stdlib.h>
int
main ()
{
char *p = (char *)strtoll; char *q = (char *)strtoull;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_flag__isoc99_source=yes
else
  tcl_cv_flag__isoc99_source=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi

    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then

$as_echo "#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
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main ()
{
struct stat64 buf; int i = stat64("/", &buf);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_flag__largefile64_source=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _LARGEFILE64_SOURCE 1
#include <sys/stat.h>
int
main ()
{
struct stat64 buf; int i = stat64("/", &buf);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_flag__largefile64_source=yes
else
  tcl_cv_flag__largefile64_source=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi

    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then

$as_echo "#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
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main ()
{
char *p = (char *)open64;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_cv_flag__largefile_source64=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _LARGEFILE_SOURCE64 1
#include <sys/stat.h>
int
main ()
{
char *p = (char *)open64;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_cv_flag__largefile_source64=yes
else
  tcl_cv_flag__largefile_source64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi

    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then

$as_echo "#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; }
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
$as_echo "${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

	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 ()
{
switch (0) {
            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
        }
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_type_64bit=${tcl_type_64bit}
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi

    if test "${tcl_cv_type_64bit}" = none ; then

$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "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

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
main ()
{
struct dirent64 p;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_struct_dirent64=yes
else
  tcl_cv_struct_dirent64=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
$as_echo "$tcl_cv_struct_dirent64" >&6; }
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then

$as_echo "#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

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
main ()
{
struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_DIR64=yes
else
  tcl_cv_DIR64=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5
$as_echo "$tcl_cv_DIR64" >&6; }
	if test "x${tcl_cv_DIR64}" = "xyes" ; then

$as_echo "#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

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main ()
{
struct stat64 p;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_cv_struct_stat64=yes
else
  tcl_cv_struct_stat64=no
fi




rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
$as_echo "$tcl_cv_struct_stat64" >&6; }
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then

$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h

	fi

	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
#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

	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main ()
{
off64_t offset;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_type_off64_t=yes
else
  tcl_cv_type_off64_t=no

fi
rm -f core conftest.err conftest.$ac_objext 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

	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "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
  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 :


	# 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







|
|
<











|
|

|
>

|
|
>







|

|
|

|





|
|







|







|
|

|
|









|
|


|
>
|
|
|



|






|
>

|
|




|






|
>

|
|
>

|
>

|
>




|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
|



|






|
>

|
|




|






|
>

|
|
>

|
>

|
>




|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
|

|
|




|
|
|
>
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|


|





|
>
|

|
>




|

|
|

<
<
<
<
<
|
<
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
|
|
|





|






|
>

|
|
>

|
>

|
|


|



|
|
|
>
|
|
|





|







|
>

|
|
>

|
>

|
|


|



|
<
<
<
<
|
<
<
<
<
|
<
<
|
|
<
<
<
<
<
<
<

>
>
>
>
<
<
<
<
<

<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
>
|
|
|




|







|
>

|
|
>

|
>






|

|
|

|
|








|
|
|
>
|
|
|









|
>







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








printf "%s\n" "#define TCL_SHLIB_EXT \"${SHLIB_SUFFIX}\"" >>confdefs.h












    { 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+y}
then :
  enableval=$enable_symbols; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=no ;;
esac
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)'

printf "%s\n" "#define NDEBUG 1" >>confdefs.h

	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }

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
	    { 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

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
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem debugging" >&5
printf "%s\n" "enabled symbols mem debugging" >&6; }
	else
	    { 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.
#--------------------------------------------------------------------


    { 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 test ${tcl_cv_flag__isoc99_source+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
int
main (void)
{
char *p = (char *)strtoll; char *q = (char *)strtoull;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__isoc99_source=no
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _ISOC99_SOURCE 1
#include <stdlib.h>
int
main (void)
{
char *p = (char *)strtoll; char *q = (char *)strtoull;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__isoc99_source=yes
else case e in #(
  e) tcl_cv_flag__isoc99_source=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi

    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then

printf "%s\n" "#define _ISOC99_SOURCE 1" >>confdefs.h

	tcl_flags="$tcl_flags _ISOC99_SOURCE"
    fi


    if test ${tcl_cv_flag__file_offset_bits+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main (void)
{
switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__file_offset_bits=no
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _FILE_OFFSET_BITS 64
#include <sys/stat.h>
int
main (void)
{
switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__file_offset_bits=yes
else case e in #(
  e) tcl_cv_flag__file_offset_bits=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi

    if test "x${tcl_cv_flag__file_offset_bits}" = "xyes" ; then

printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h

	tcl_flags="$tcl_flags _FILE_OFFSET_BITS"
    fi


    if test ${tcl_cv_flag__largefile64_source+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/stat.h>
int
main (void)
{
struct stat64 buf; int i = stat64("/", &buf);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__largefile64_source=no
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _LARGEFILE64_SOURCE 1
#include <sys/stat.h>
int
main (void)
{
struct stat64 buf; int i = stat64("/", &buf);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_flag__largefile64_source=yes
else case e in #(
  e) tcl_cv_flag__largefile64_source=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi

    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then

printf "%s\n" "#define _LARGEFILE64_SOURCE 1" >>confdefs.h

	tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
    fi
















































    if test "x${tcl_flags}" = "x" ; then
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
printf "%s\n" "none" >&6; }
    else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
printf "%s\n" "${tcl_flags}" >&6; }
    fi



    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if 'long' and 'long long' have the same size (64-bit)?" >&5
printf %s "checking if 'long' and 'long long' have the same size (64-bit)?... " >&6; }
    if test ${tcl_cv_type_64bit+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
	tcl_cv_type_64bit=none


















	# 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 (void)
{
switch (0) {
            case 1: case (sizeof(long long)==sizeof(long)): ;
        }
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_type_64bit="long long"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi

    if test "${tcl_cv_type_64bit}" = none ; then

printf "%s\n" "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h

	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
    else





	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5

printf "%s\n" "no" >&6; }
	# Now check for auxiliary declarations
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit time_t" >&5
printf %s "checking for 64-bit time_t... " >&6; }
if test ${tcl_cv_time_t_64+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main (void)
{
switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_time_t_64=yes
else case e in #(
  e) tcl_cv_time_t_64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_time_t_64" >&5
printf "%s\n" "$tcl_cv_time_t_64" >&6; }
	if test "x${tcl_cv_time_t_64}" = "xno" ; then
	    # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64
	    # which SC_TCL_EARLY_FLAGS has defined if necessary.
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if _TIME_BITS=64 enables 64-bit time_t" >&5
printf %s "checking if _TIME_BITS=64 enables 64-bit time_t... " >&6; }
if test ${tcl_cv__time_bits+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#define _TIME_BITS 64
#include <sys/types.h>
int
main (void)
{
switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv__time_bits=yes
else case e in #(
  e) tcl_cv__time_bits=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv__time_bits" >&5
printf "%s\n" "$tcl_cv__time_bits" >&6; }
	    if test "x${tcl_cv__time_bits}" = "xyes" ; then

printf "%s\n" "#define _TIME_BITS 64" >>confdefs.h

	    fi
	fi

	{ 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 case e in #(
  e)
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
main (void)
{
struct dirent64 p;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_struct_dirent64=yes
else case e in #(
  e) tcl_cv_struct_dirent64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ 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

printf "%s\n" "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h

	fi

	{ 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 case e in #(
  e)
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
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 :
  tcl_cv_DIR64=yes
else case e in #(
  e) tcl_cv_DIR64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ 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

printf "%s\n" "#define HAVE_DIR64 1" >>confdefs.h

	fi

	ac_fn_c_check_func "$LINENO" "open64" "ac_cv_func_open64"




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








fi













	{ 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 case e in #(
  e)
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main (void)
{
off64_t offset;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_type_off64_t=yes
else case e in #(
  e) tcl_cv_type_off64_t=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
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

printf "%s\n" "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h

	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
	else
	    { 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
#--------------------------------------------------------------------

 { 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 case e in #(
  e) 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 :

	# 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
	   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
    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 ()
{
#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 :

  # 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 ()
{
#if BYTE_ORDER != BIG_ENDIAN
		 not big endian
		#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_c_bigendian=yes
else
  ac_cv_c_bigendian=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    fi
    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 ()
{
#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
	      bogus endian macros
	     #endif

  ;
  return 0;
}
_ACEOF
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 ()
{
#ifndef _BIG_ENDIAN
		 not big endian
		#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_c_bigendian=yes
else
  ac_cv_c_bigendian=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    fi
    if test $ac_cv_c_bigendian = unknown; then
      # Compile a test program.
      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[] =
		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
		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[] =
		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
		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 ()
{



return use_ascii (foo) == use_ebcdic (foo);
  ;

  return 0;
}
_ACEOF
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
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{

	     /* 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 :

  ac_cv_c_bigendian=no
else
  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; }
 case $ac_cv_c_bigendian in #(
   yes)
     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
;; #(
   no)
      ;; #(
   universal)

$as_echo "#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:
        Different --prefix selected for Tk and Tcl!
        [package require Tk] may not work correctly in tclsh." >&5
$as_echo "$as_me: WARNING:
        Different --prefix selected for Tk and Tcl!
        [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

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main ()
{
fd_set readMask, writeMask;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_type_fd_set=yes
else
  tcl_cv_type_fd_set=no

fi
rm -f core conftest.err conftest.$ac_objext 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; }
tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then





    { $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





















































































































else


















	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 :

  tcl_cv_grep_fd_mask=present
else
  tcl_cv_grep_fd_mask=missing

fi
rm -f conftest*


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_fd_mask" >&5
$as_echo "$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

	tk_ok=yes
    fi
fi
if test $tk_ok = no; then

$as_echo "#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 :


else

cat >>confdefs.h <<_ACEOF
#define mode_t int
_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 :


else






cat >>confdefs.h <<_ACEOF



#define pid_t int




_ACEOF













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 :

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
  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*

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"
if test "x$ac_cv_type_intptr_t" = xyes; then :


$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h

else

    { $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

    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
#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"
if test "x$ac_cv_type_uintptr_t" = xyes; then :


$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h

else

    { $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

    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];

  ;
  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

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <pwd.h>
int
main ()
{
struct passwd pwd; (void)pwd.pw_gecos;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_pwd_pw_gecos=yes
else
  tcl_cv_pwd_pw_gecos=no

fi
rm -f core conftest.err conftest.$ac_objext 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; }
if test $tcl_cv_pwd_pw_gecos = yes; then

$as_echo "#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; }
    # Check whether --enable-aqua was given.
if test "${enable_aqua+set}" = set; then :

  enableval=$enable_aqua; tk_aqua=$enableval
else
  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;}
	    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;}
	    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;}
	    tk_aqua=no
	fi
    fi
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tk_aqua" >&5
$as_echo "$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

		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 ()
{
XrmInitialize();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
  tcl_cv_lib_x11_64=yes
else
  tcl_cv_lib_x11_64=no
fi
rm -f core conftest.err conftest.$ac_objext \
    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; }
	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;}
	    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

	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <math.h>
int
main ()
{
double f = sin(1.0);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_ld_weak_l=yes
else
  tcl_cv_ld_weak_l=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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; }
    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 :
  cat >>confdefs.h <<_ACEOF

#define HAVE_AVAILABILITYMACROS_H 1
_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

	    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 ()
{
rand();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_cc_weak_import=yes
else
  tcl_cv_cc_weak_import=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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; }
	if test $tcl_cv_cc_weak_import = yes; then

$as_echo "#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

	    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 ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_cc_darwin_c_source=yes
else
  tcl_cv_cc_darwin_c_source=no

fi
rm -f core conftest.err conftest.$ac_objext 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; }
	if test $tcl_cv_cc_darwin_c_source = yes; then

$as_echo "#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

    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"






    EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then

$as_echo "#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; }


# Check whether --with-x was given.
if test "${with_x+set}" = set; 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
  # 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
if mkdir conftest.dir; then
  cd conftest.dir
  cat >Imakefile <<'_ACEOF'
incroot:
	@echo incroot='${INCROOT}'
usrlibdir:
	@echo usrlibdir='${USRLIBDIR}'







|








|

|
|








|
>







|









|
>

|
|
>

|

|








|









|
>






|









|
>

|
|
>

|

|



|
>



|

|




|

|




<
<
|
|
|
>
>
>
|
<
>
|
|

|
>
|


|








|
>
|
|



|















|
>

|
|
>


|
>


|
>

|
|


|




|
<
<



















|

|
|

|












|
|
|
>
|
|
|




|






|
>

|
|
>

|
>

|
|


>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>






|
>

|
|
>

|
|
>

|
|


|






|







<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
>

|
|
<
|
<
|
>


>
|
>
|
>

|
>
>

>
>
>
|
>
>
>
|
>
>
>
>

>
>
>
>
>
>
>
>

>
>
>
>

>


|
|
<

<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
|
<
<
<



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
|
<
<
<
<
<
|
|

|

<
<
<
<
<
<
<

|
<
|
<
<
|
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|

|
<
<

<








|
|
|
>
|
|
|




|






|
>

|
|
>

|
>

|
|


|








|
|

|
>

|
|
>





|
|



|
|



|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
|
|
|
<
<
<
<
<
<
<
<
<
<
<


|
|
|
>
|
|
|






|






|
>

|
|
>

|

|
>

|
|

<
<
|
|
<
>
|
<



<
<

|
|
|
>
|
|
|














|






|
>

|
|
>

|

|
>

|
|


|


|
|
|
>
|
|
|















|






|
>

|
|
>

|
|
>

|
|


|









|

|
>
>
>
>
>
>
|



|













|
|



|
>



|






|
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







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
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
































7748
7749





7750
7751
7752











7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789


7790
7791

7792
7793

7794
7795
7796


7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
	   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.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 (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 :
  # 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 (void)
{
#if BYTE_ORDER != BIG_ENDIAN
		 not big endian
		#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_bigendian=yes
else case e in #(
  e) ac_cv_c_bigendian=no ;;
esac
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
    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 (void)
{
#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
	      bogus endian macros
	     #endif

  ;
  return 0;
}
_ACEOF
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 (void)
{
#ifndef _BIG_ENDIAN
		 not big endian
		#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_bigendian=yes
else case e in #(
  e) ac_cv_c_bigendian=no ;;
esac
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
    if test $ac_cv_c_bigendian = unknown; then
      # Compile a test program.
      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.  */
unsigned short int ascii_mm[] =
		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
		unsigned short int ascii_ii[] =
		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
		int use_ascii (int i) {
		  return ascii_mm[i] + ascii_ii[i];
		}
		unsigned short int ebcdic_ii[] =
		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
		unsigned short int ebcdic_mm[] =
		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
		int use_ebcdic (int i) {
		  return ebcdic_mm[i] + ebcdic_ii[i];
		}


		int
		main (int argc, char **argv)
		{
		  /* Intimidate the compiler so that it does not
		     optimize the arrays away.  */
		  char *p = argv[0];
		  ascii_mm[1] = *p++; ebcdic_mm[1] = *p++;

		  ascii_ii[1] = *p++; ebcdic_ii[1] = *p++;
		  return use_ascii (argc) == use_ebcdic (*p);
		}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  if grep BIGenDianSyS conftest$ac_exeext >/dev/null; then
	      ac_cv_c_bigendian=yes
	    fi
	    if grep LiTTleEnDian conftest$ac_exeext >/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.beam \
    conftest$ac_exeext conftest.$ac_ext
else case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
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 :
  ac_cv_c_bigendian=no
else case e in #(
  e) ac_cv_c_bigendian=yes ;;
esac
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi

    fi ;;
esac
fi
{ 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)
     printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h
;; #(
   no)
      ;; #(
   universal)
     #


     ;; #(
   *)
     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
    { 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
printf "%s\n" "$as_me: WARNING:
        Different --prefix selected for Tk and Tcl!
        [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.
#--------------------------------------------------------------------

{ 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 case e in #(
  e)
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <sys/types.h>
int
main (void)
{
fd_set readMask, writeMask;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_type_fd_set=yes
else case e in #(
  e) tcl_cv_type_fd_set=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ 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 case e in #(
  e)     # 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 case e in #(
  e) # Broken: fails on valid input.
continue ;;
esac
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 case e in #(
  e) # Passes both tests.
ac_preproc_ok=:
break ;;
esac
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
   ;;
esac
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 case e in #(
  e) # Broken: fails on valid input.
continue ;;
esac
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 case e in #(
  e) # Passes both tests.
ac_preproc_ok=:
break ;;
esac
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 case e in #(
  e) { { 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; } ;;
esac
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 egrep -e" >&5
printf %s "checking for egrep -e... " >&6; }
if test ${ac_cv_path_EGREP_TRADITIONAL+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) if test -z "$EGREP_TRADITIONAL"; then
  ac_path_EGREP_TRADITIONAL_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_EGREP_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue
# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found.
  # Check for GNU $ac_path_EGREP_TRADITIONAL
case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #(
*GNU*)
  ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_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_TRADITIONAL' >> "conftest.nl"
    "$ac_path_EGREP_TRADITIONAL" -E 'EGR(EP|AC)_TRADITIONAL$' < "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_TRADITIONAL_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL"
      ac_path_EGREP_TRADITIONAL_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_TRADITIONAL_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP_TRADITIONAL"; then
    :
  fi
else
  ac_cv_path_EGREP_TRADITIONAL=$EGREP_TRADITIONAL
fi

    if test "$ac_cv_path_EGREP_TRADITIONAL"
then :
  ac_cv_path_EGREP_TRADITIONAL="$ac_cv_path_EGREP_TRADITIONAL -E"
else case e in #(
  e) if test -z "$EGREP_TRADITIONAL"; then
  ac_path_EGREP_TRADITIONAL_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_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue
# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found.
  # Check for GNU $ac_path_EGREP_TRADITIONAL
case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #(
*GNU*)
  ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_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_TRADITIONAL' >> "conftest.nl"
    "$ac_path_EGREP_TRADITIONAL" 'EGR(EP|AC)_TRADITIONAL$' < "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_TRADITIONAL_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL"
      ac_path_EGREP_TRADITIONAL_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_TRADITIONAL_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP_TRADITIONAL"; 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_TRADITIONAL=$EGREP_TRADITIONAL
fi
 ;;
esac
fi ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP_TRADITIONAL" >&5
printf "%s\n" "$ac_cv_path_EGREP_TRADITIONAL" >&6; }
 EGREP_TRADITIONAL=$ac_cv_path_EGREP_TRADITIONAL

{ 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 case e in #(
  e)
	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_TRADITIONAL "fd_mask" >/dev/null 2>&1
then :
  tcl_cv_grep_fd_mask=present
else case e in #(
  e) tcl_cv_grep_fd_mask=missing ;;
esac
fi
rm -rf conftest*
 ;;
esac
fi
{ 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

printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h

	tk_ok=yes
    fi
fi
if test $tk_ok = no; then

printf "%s\n" "#define NO_FD_SET 1" >>confdefs.h

fi

#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

















































#--------------------------------------------------------------------
#	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 :

else case e in #(
  e)

printf "%s\n" "#define mode_t int" >>confdefs.h

 ;;
esac
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 :

else case e in #(
  e)                                         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

          #if defined _WIN64 && !defined __CYGWIN__
          LLP64
          #endif

int
main (void)
{

  ;
  return 0;
}

_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_pid_type='int'
else case e in #(
  e) ac_pid_type='__int64' ;;
esac
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

     ;;
esac
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 :












else case e in #(



  e)








printf "%s\n" "#define size_t unsigned int" >>confdefs.h




 ;;

esac



fi


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


#-------------------------------------------
#     In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------

{ 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 case e in #(
  e)
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <pwd.h>
int
main (void)
{
struct passwd pwd; (void)pwd.pw_gecos;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_pwd_pw_gecos=yes
else case e in #(
  e) tcl_cv_pwd_pw_gecos=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ 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

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
    { 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+y}
then :
  enableval=$enable_aqua; tk_aqua=$enableval
else case e in #(
  e) tk_aqua=no ;;
esac
fi

    if test $tk_aqua = yes -o $tk_aqua = cocoa; then
	tk_aqua=yes
	if test $tcl_corefoundation = no; then
	    { 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
	    { 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
	    { 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
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tk_aqua" >&5
printf "%s\n" "$tk_aqua" >&6; }











    if test $tk_aqua = no; then
	# check if weak linking whole libraries is possible.
	{ 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 case e in #(
  e)
	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <math.h>
int
main (void)
{
double f = sin(1.0);
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_weak_l=yes
else case e in #(
  e) tcl_cv_ld_weak_l=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	    LDFLAGS=$hold_ldflags ;;
esac
fi
{ 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


    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

then :
  printf "%s\n" "#define HAVE_AVAILABILITYMACROS_H 1" >>confdefs.h


fi



    if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
	{ 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 case e in #(
  e)
	    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 (void)
{
rand();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_cc_weak_import=yes
else case e in #(
  e) tcl_cv_cc_weak_import=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	    CFLAGS=$hold_cflags ;;
esac
fi
{ 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

printf "%s\n" "#define HAVE_WEAK_IMPORT 1" >>confdefs.h

	fi
	{ 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 case e in #(
  e)
	    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 (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cc_darwin_c_source=yes
else case e in #(
  e) tcl_cv_cc_darwin_c_source=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    CFLAGS=$hold_cflags ;;
esac
fi
{ 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

printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h

	fi
    fi
else
    tk_aqua=no
fi

if test $tk_aqua = yes; then

printf "%s\n" "#define MAC_OSX_TK 1" >>confdefs.h

    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore -framework Security -framework CoreGraphics"
    if test -d /System/Library/Frameworks/UserNotifications.framework; then
        LIBS="$LIBS -framework UserNotifications"
    fi
    if test -d "/System/Library/Frameworks/UniformTypeIdentifiers.framework"; then
        LIBS="$LIBS -weak_framework UniformTypeIdentifiers"
    fi
    EXTRA_CC_SWITCHES='-x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then

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.
    #--------------------------------------------------------------------


    { 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+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 test ${ac_cv_have_x+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) # One or both of the vars are not set, and there is no cached value.
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
	*) 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.
# 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







|







8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
	*) 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.
# 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
/usr/local/X11R4/include

/usr/local/include/X11
/usr/local/include/X11R7
/usr/local/include/X11R6
/usr/local/include/X11R5
/usr/local/include/X11R4



/usr/X386/include
/usr/x386/include
/usr/XFree86/include/X11

/usr/include
/usr/local/include







>
>







8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
/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
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 :

  # We can compile using X headers with no special include directory.
ac_x_includes=
else
  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 ()
{
XrmInitialize ()
  ;
  return 0;
}
_ACEOF
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
  LIBS=$ac_save_LIBS
for ac_dir in `$as_echo "$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 \
    conftest$ac_exeext conftest.$ac_ext
fi # $ac_x_libraries = no



case $ac_x_includes,$ac_x_libraries in #(
  no,* | *,no | *\'*)
    # Didn't find X, or a directory has "'" in its name.
    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'"

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; }
  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; }
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 :


else
  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; }
	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 :

  found_xincludes="yes"
else
  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; }
		    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; }
    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; }
	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; }
		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
  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 ()
{
return XCreateWindow ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_Xwindow_XCreateWindow=yes
else
  ac_cv_lib_Xwindow_XCreateWindow=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  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; }
	XLIBSW=-lX11
    fi

    TK_WINDOWINGSYSTEM=X11
fi

#--------------------------------------------------------------------







|
>


|
|




|
>














|






|
>



|
|
|








|
>

|



>
>

|

|
|



|
>









|
|









|
|









|
>

|
|
>









|
|





|
>

|
|
>






|
|













|
|



|
|




|
|













|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>





|
|







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
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 :
  # We can compile using X headers with no special include directory.
ac_x_includes=
else case e in #(
  e) 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 ;;
esac
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 (void)
{
XrmInitialize ()
  ;
  return 0;
}
_ACEOF
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 case e in #(
  e) LIBS=$ac_save_LIBS
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 ;;
esac
fi
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 | *\'*) :
    # Didn't find X, or a directory has "'" in its name.
    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'" ;;
esac ;;
esac
fi
;; #(
    *) have_x=yes;;
  esac
  eval "$ac_cv_have_x"
fi # $with_x != no

if test "$have_x" != yes; then
  { 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'"
  { 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 :

else case e in #(
  e) not_really_there="yes" ;;
esac
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
	{ 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 :
  found_xincludes="yes"
else case e in #(
  e) found_xincludes="no" ;;
esac
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
		    { 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
	{ 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
	{ 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
		{ 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
	{ 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char XCreateWindow (void);
int
main (void)
{
return XCreateWindow ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xwindow_XCreateWindow=yes
else case e in #(
  e) ac_cv_lib_Xwindow_XCreateWindow=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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
	{ 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
#	   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
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lXbsd  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */


int
main ()
{
return main ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_Xbsd_main=yes
else
  ac_cv_lib_Xbsd_main=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :

  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; }
    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 ()
{

	XOpenDisplay(0);

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :


	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "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; }

fi
rm -f core conftest.err conftest.$ac_objext \
    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; }
    # Check whether --enable-xft was given.
if test "${enable_xft+set}" = set; then :

  enableval=$enable_xft; enable_xft=$enableval
else
  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; }
    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; }
		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 :


else

		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
  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 ()
{
return XftFontOpen ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_Xft_XftFontOpen=yes
else
  ac_cv_lib_Xft_XftFontOpen=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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
_ACEOF

  LIBS="-lXft $LIBS"

else

		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
  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 ()
{
return FcFontSort ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_fontconfig_FcFontSort=yes
else
  ac_cv_lib_fontconfig_FcFontSort=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		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;}
	    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

    else
	UNIX_FONT_OBJS=tkUnixFont.o
    fi










|
|
|
>
|
|
|






|






|
>

|
|
>

|

|
>

|
|
|
>

















|
|










|








|
>

|
|



|
|
|
>

|










|
|

|
>

|
|
>





|
|









|
|







|
>

|
|

|
>

<









|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
<
>
|
<



|
|

|
>










|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>










|
|











|







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
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
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
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
#	   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
    { 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 case e in #(
  e) ac_check_lib_save_LIBS=$LIBS
LIBS="-lXbsd  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */


int
main (void)
{
return main ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xbsd_main=yes
else case e in #(
  e) ac_cv_lib_Xbsd_main=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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
    { 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 (void)
{

	XOpenDisplay(0);

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :

	{ 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 case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; } ;;
esac
fi
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
    { 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+y}
then :
  enableval=$enable_xft; enable_xft=$enableval
else case e in #(
  e) enable_xft="default" ;;
esac
fi

    XFT_CFLAGS=""
    XFT_LIBS=""
    if test "$enable_xft" = "no" ; then
	{ 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
	{ 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 :

else case e in #(
  e)
		found_xft=no
	     ;;
esac
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"
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char XftFontOpen (void);
int
main (void)
{
return XftFontOpen ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xft_XftFontOpen=yes
else case e in #(
  e) ac_cv_lib_Xft_XftFontOpen=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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


  LIBS="-lXft $LIBS"

else case e in #(
  e)
		found_xft=no
	     ;;
esac
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"
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char FcFontSort (void);
int
main (void)
{
return FcFontSort ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_fontconfig_FcFontSort=yes
else case e in #(
  e) ac_cv_lib_fontconfig_FcFontSort=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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
		{ 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

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
7951
7952
7953
7954
7955
7956

7957
7958
7959

7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979

7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996

7997
7998
7999

8000
8001

8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017


8018




8019
8020
8021
8022
8023
8024
8025
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; }
    # Check whether --enable-xss was given.
if test "${enable_xss+set}" = set; then :

  enableval=$enable_xss; enable_xss=$enableval
else
  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; }
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_xss" >&5
$as_echo "$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 :


	    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 :


else

	    { $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
  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 ()
{
return XScreenSaverQueryInfo ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_Xext_XScreenSaverQueryInfo=yes
else
  ac_cv_lib_Xext_XScreenSaverQueryInfo=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		XLIBSW="$XLIBSW -lXext"
		xss_lib_found=yes

else

		{ $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
  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 ()
{
return XScreenSaverQueryInfo ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_lib_Xss_XScreenSaverQueryInfo=yes
else
  ac_cv_lib_Xss_XScreenSaverQueryInfo=no

fi
rm -f core conftest.err conftest.$ac_objext \
    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 :


		    if test "$tcl_cv_ld_weak_l" = yes; then
			# On Darwin, weak link libXss if possible,
			# as it is only available on Tiger or later.
			XLIBSW="$XLIBSW -Wl,-weak-lXss -lXext"
		    else
			XLIBSW="$XLIBSW -lXss -lXext"
		    fi
		    xss_lib_found=yes

fi



fi



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

    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
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{
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 :

  ac_cv_c_char_unsigned=no
else
  ac_cv_c_char_unsigned=yes

fi
rm -f core conftest.err conftest.$ac_objext 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

fi


#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"


eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"





# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then







|
|

|
>

|
|
>



|
|

|
|


|
>





<

|
>

|
|
|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>




|
|
|
|
|
>
|
|
|






|
>
>
>



|

|






|
>

|
|
>

|

|
>

|
|
|
>












|
>


|
>





|











|
|
|
>
|
|
|



|









|
>

|
|
>

|
>

|
|
|
|











>
>

>
>
>
>







8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673

8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
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
    { 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+y}
then :
  enableval=$enable_xss; enable_xss=$enableval
else case e in #(
  e) enable_xss=yes ;;
esac
fi

    if test "$enable_xss" = "no" ; then
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_xss" >&5
printf "%s\n" "$enable_xss" >&6; }
    else
	{ 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 :

	    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 :

else case e in #(
  e)
	    { 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char XScreenSaverQueryInfo (void);
int
main (void)
{
return XScreenSaverQueryInfo ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xext_XScreenSaverQueryInfo=yes
else case e in #(
  e) ac_cv_lib_Xext_XScreenSaverQueryInfo=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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 case e in #(
  e)
		{ 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 case e in #(
  e) 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.
   The 'extern "C"' is for builds by C++ compilers;
   although this is not generally supported in C code supporting it here
   has little cost and some practical benefit (sr 110532).  */
#ifdef __cplusplus
extern "C"
#endif
char XScreenSaverQueryInfo (void);
int
main (void)
{
return XScreenSaverQueryInfo ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_lib_Xss_XScreenSaverQueryInfo=yes
else case e in #(
  e) ac_cv_lib_Xss_XScreenSaverQueryInfo=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS ;;
esac
fi
{ 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"
		    fi
		    xss_lib_found=yes

fi

	     ;;
esac
fi

	 ;;
esac
fi

    fi
    if test $enable_xss = yes -a $xss_lib_found = yes -a $xss_header_found = yes; then

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__.
#--------------------------------------------------------------------

{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
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 :
  ac_cv_c_char_unsigned=no
else case e in #(
  e) ac_cv_c_char_unsigned=yes ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
{ 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.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE_TCL8=libtk${LIB_SUFFIX}"
if test ${TCL_MAJOR_VERSION} = 8 ; then
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"
else
eval "TK_LIB_FILE=libtcl9tk${LIB_SUFFIX}"
fi
eval "TK_LIB_FILE_TCL9=libtcl9tk${LIB_SUFFIX}"

# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
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
# 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; }
	# Check whether --enable-framework was given.
if test "${enable_framework+set}" = set; then :

  enableval=$enable_framework; enable_framework=$enableval
else
  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;}
		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;}
		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; }
	    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; }
	    else
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static library" >&5
$as_echo "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_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"

    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

    # 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
        # override libdir default
        libdir="/Library/Frameworks"
    fi

    TK_LIB_FILE="Tk"





    TK_LIB_FLAG="-framework Tk"
    TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
    TK_LIB_SPEC="-F${libdir} -framework Tk"
    libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
    TK_LIBRARY="${libdir}/Resources/Scripts"
    TK_PKG_DIR="Resources/Scripts"
    TK_RSRC_FILE="Tk.rsrc"
    WISH_RSRC_FILE="Wish.rsrc"
    includedir="${libdir}/Headers"
    PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
    HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
    EXTRA_INSTALL="install-private-headers html-tk"
    EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
    EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'

    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
    if test $tk_aqua = yes; then
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'/" && $(INSTALL_DATA_DIR) "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
	bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'

    fi
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
    # Don't use AC_DEFINE for the following as the framework version define
    # needs to go into the Makefile even when using autoheader, so that we
    # can pick up a potential make override of VERSION. Also, don't put this
    # into CFLAGS as it should not go into tkConfig.sh
    EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    if test $tk_aqua = yes; then
        EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
    fi
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"




    if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
	TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
    else
	if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	    TK_LIB_FLAG="-ltk${TK_VERSION}"
	else
	    TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	fi
	TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
    fi
    TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi














































































































































































































#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tk
#       stub support.
#--------------------------------------------------------------------

# Replace ${VERSION} with contents of ${TK_VERSION}
eval "TK_STUB_LIB_FILE=libtkstub${TK_UNSHARED_LIB_SUFFIX}"
eval "TK_STUB_LIB_DIR=${libdir}"

if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
    TK_STUB_LIB_FLAG="-ltkstub${TK_VERSION}"
else
    TK_STUB_LIB_FLAG="-ltkstub`echo ${TK_VERSION} | tr -d .`"
fi

TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"
TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}"

# Install time header dir can be set via --includedir
eval "TK_INCLUDE_SPEC=\"-I${includedir}\""

#------------------------------------------------------------------------
# Demo dir
#------------------------------------------------------------------------

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 '()' '{}'`\""










|
|

|
>

|
|
>




|
|



|
|




|
|



|
|

|
|










>
>
|
>
|







|










>
|
>
>
>
>
>














>









>













>
>
>
>

|



|

|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
<
<
<
|
<
|
<













|
>







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
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
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
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
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
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
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
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
# 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
	{ 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+y}
then :
  enableval=$enable_framework; enable_framework=$enableval
else case e in #(
  e) enable_framework=no ;;
esac
fi

	if test $enable_framework = yes; then
	    if test $SHARED_BUILD = 0; then
		{ 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
		{ 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
	    { 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
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared library" >&5
printf "%s\n" "shared library" >&6; }
	    else
		{ 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
    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

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
        # override libdir default
        libdir="/Library/Frameworks"
    fi
    if test ${TCL_MAJOR_VERSION} = 8 ; then
	TK_LIB_FILE="Tk"
    else
	TK_LIB_FILE="Tk"
    fi
    TK_LIB_FILE_TCL8="Tk"
    TK_LIB_FILE_TCL9="Tk"
    TK_LIB_FLAG="-framework Tk"
    TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
    TK_LIB_SPEC="-F${libdir} -framework Tk"
    libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
    TK_LIBRARY="${libdir}/Resources/Scripts"
    TK_PKG_DIR="Resources/Scripts"
    TK_RSRC_FILE="Tk.rsrc"
    WISH_RSRC_FILE="Wish.rsrc"
    includedir="${libdir}/Headers"
    PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
    HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
    EXTRA_INSTALL="install-private-headers html-tk"
    EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
    EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Credits.html "$(LIB_INSTALL_DIR)/Resources"'
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
    if test $tk_aqua = yes; then
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'/" && $(INSTALL_DATA_DIR) "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
	bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) Credits.html "$(BIN_INSTALL_DIR)/../Resources"'
    fi
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
    # Don't use AC_DEFINE for the following as the framework version define
    # needs to go into the Makefile even when using autoheader, so that we
    # can pick up a potential make override of VERSION. Also, don't put this
    # into CFLAGS as it should not go into tkConfig.sh
    EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    if test $tk_aqua = yes; then
        EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
    fi
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    TK_LIB_FLAG="-l"
    if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
	TK_LIB_FLAG="${TK_LIB_FLAG}tcl9"
    fi
    if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
	TK_LIB_FLAG="${TK_LIB_FLAG}tk`echo ${TK_VERSION} | tr -d .`"
	TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
    else
	if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	    TK_LIB_FLAG="${TK_LIB_FLAG}tk${TK_VERSION}"
	else
	    TK_LIB_FLAG="${TK_LIB_FLAG}tk`echo ${TK_VERSION} | tr -d .`"
	fi
	TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
    fi
    TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi

#--------------------------------------------------------------------
#	Zipfs support - Tip 430
#--------------------------------------------------------------------
# Check whether --enable-zipfs was given.
if test ${enable_zipfs+y}
then :
  enableval=$enable_zipfs; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=yes ;;
esac
fi

if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then
    #
    # Find a native compiler
    #
    # Put a plausible default for CC_FOR_BUILD in Makefile.
    if test -z "$CC_FOR_BUILD"; then
      if test "x$cross_compiling" = "xno"; then
        CC_FOR_BUILD='$(CC)'
      else
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5
printf %s "checking for gcc... " >&6; }
        if test ${ac_cv_path_cc+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
            search_path=`echo ${PATH} | sed -e 's/:/ /g'`
            for dir in $search_path ; do
                for j in `ls -r $dir/gcc 2> /dev/null` \
                        `ls -r $dir/gcc 2> /dev/null` ; do
                    if test x"$ac_cv_path_cc" = x ; then
                        if test -f "$j" ; then
                            ac_cv_path_cc=$j
                            break
                        fi
                    fi
                done
            done
         ;;
esac
fi

      fi
    fi

    # Also set EXEEXT_FOR_BUILD.
    if test "x$cross_compiling" = "xno"; then
      EXEEXT_FOR_BUILD='$(EXEEXT)'
      OBJEXT_FOR_BUILD='$(OBJEXT)'
    else
      OBJEXT_FOR_BUILD='.no'
      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5
printf %s "checking for build system executable suffix... " >&6; }
if test ${bfd_cv_build_exeext+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) rm -f conftest*
         echo 'int main () { return 0; }' > conftest.c
         bfd_cv_build_exeext=
         ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
         for file in conftest.*; do
           case $file in
           *.c | *.o | *.obj | *.ilk | *.pdb) ;;
           *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
           esac
         done
         rm -f conftest*
         test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5
printf "%s\n" "$bfd_cv_build_exeext" >&6; }
      EXEEXT_FOR_BUILD=""
      test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
    fi

    #
    # Find a native zip implementation
    #

    MACHER_PROG=""
    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    ZIP_INSTALL_OBJS=""

    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for macher" >&5
printf %s "checking for macher... " >&6; }
    if test ${ac_cv_path_macher+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/macher 2> /dev/null` \
            `ls -r $dir/macher 2> /dev/null` ; do
        if test x"$ac_cv_path_macher" = x ; then
            if test -f "$j" ; then
            ac_cv_path_macher=$j
            break
            fi
        fi
        done
    done
     ;;
esac
fi

    if test -f "$ac_cv_path_macher" ; then
        MACHER_PROG="$ac_cv_path_macher"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MACHER_PROG" >&5
printf "%s\n" "$MACHER_PROG" >&6; }
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found macher in environment" >&5
printf "%s\n" "Found macher in environment" >&6; }
    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zip" >&5
printf %s "checking for zip... " >&6; }
    if test ${ac_cv_path_zip+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/zip 2> /dev/null` \
            `ls -r $dir/zip 2> /dev/null` ; do
        if test x"$ac_cv_path_zip" = x ; then
            if test -f "$j" ; then
            ac_cv_path_zip=$j
            break
            fi
        fi
        done
    done
     ;;
esac
fi

    if test -f "$ac_cv_path_zip" ; then
        ZIP_PROG="$ac_cv_path_zip"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5
printf "%s\n" "$ZIP_PROG" >&6; }
        ZIP_PROG_OPTIONS="-rq"
        ZIP_PROG_VFSSEARCH="*"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5
printf "%s\n" "Found INFO Zip in environment" >&6; }
        # Use standard arguments for zip
    else
        # It is not an error if an installed version of Zip can't be located.
        # We can use the locally distributed minizip instead
        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
        ZIP_PROG_OPTIONS="-o -r"
        ZIP_PROG_VFSSEARCH="*"
        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH. Building minizip" >&5
printf "%s\n" "No zip found on PATH. Building minizip" >&6; }
    fi






	ZIPFS_BUILD=1
	TK_ZIP_FILE=libtk${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_PATCH_LEVEL}.zip
else
	ZIPFS_BUILD=0
	TK_ZIP_FILE=
fi
# Do checking message here to not mess up interleaved configure output
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5
printf %s "checking for building with zipfs... " >&6; }
if test "${ZIPFS_BUILD}" = 1; then
    if test "${SHARED_BUILD}" = 0; then
       ZIPFS_BUILD=2;

printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h

       INSTALL_LIBRARIES=install-demos
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
     else

printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h
\
       INSTALL_LIBRARIES=install-demos
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
    fi
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
INSTALL_LIBRARIES=install-libraries
INSTALL_MSGS=install-msgs
fi






#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tk
#       stub support.
#--------------------------------------------------------------------

# Replace ${VERSION} with contents of ${TK_VERSION}
    TK_STUB_LIB_FILE="libtkstub.a"



    TK_STUB_LIB_FLAG="-ltkstub"

eval "TK_STUB_LIB_DIR=\"${libdir}\""


TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"
TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}"

# Install time header dir can be set via --includedir
eval "TK_INCLUDE_SPEC=\"-I${includedir}\""

#------------------------------------------------------------------------
# Demo dir
#------------------------------------------------------------------------

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 '()' '{}'`\""



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
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










ac_config_files="$ac_config_files Makefile:../unix/Makefile.in tkConfig.sh:../unix/tkConfig.sh.in tk.pc:../unix/tk.pc.in"

cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac
  done

  (set) 2>&1 |
    case $as_nl`(ac_space=' '; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      # `set' does not quote correctly, so add quotes: double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \.
      sed -n \
	"s/'/'\\\\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;; #(
    *)
      # `set' quotes correctly as required by POSIX, so do not add quotes.
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     t end
     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     :end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
  if test -w "$cache_file"; then
    if test "x$cache_file" != "x/dev/null"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
      if test ! -f "$cache_file" || test -h "$cache_file"; then
	cat confcache >"$cache_file"
      else
        case $cache_file in #(
        */* | ?:*)
	  mv -f confcache "$cache_file"$$ &&
	  mv -f "$cache_file"$$ "$cache_file" ;; #(
        *)
	  mv -f confcache "$cache_file" ;;
	esac
      fi
    fi
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
  fi
fi
rm -f confcache

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'







>
>













|
|















|
|












|






|









|






|
|













|
|







9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
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
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404










ac_config_files="$ac_config_files Makefile:../unix/Makefile.in tkConfig.sh:../unix/tkConfig.sh.in tk.pc:../unix/tk.pc.in"

cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# 'ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* 'ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { 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
  done

  (set) 2>&1 |
    case $as_nl`(ac_space=' '; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      # 'set' does not quote correctly, so add quotes: double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \.
      sed -n \
	"s/'/'\\\\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;; #(
    *)
      # 'set' quotes correctly as required by POSIX, so do not add quotes.
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+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
      { 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
    { 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}'
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
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
t quote
b any
:quote
s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
s/\[/\\&/g
s/\]/\\&/g
s/\$/$$/g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
}
'
DEFS=`sed -n "$ac_script" confdefs.h`


ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
  #    will be set to the directory where LIBOBJS objects are built.
  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs


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;}
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.







|
<
<



















|












<




|
|







9421
9422
9423
9424
9425
9426
9427
9428


9429
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
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
t quote
b any
:quote
s/[][	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g


s/\$/$$/g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
}
'
DEFS=`sed -n "$ac_script" confdefs.h`


ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`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"
{ 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
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :

  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;

esac
fi










as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '


    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi

  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'









fi





# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.







|
>






|
|




>




>
>
>
>
>
>
>
>



<
<
<
<
<
<
<
<
|
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
>
>
|
<
<
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>


|








<
<
<
<
<
<
<








>
|
>
>
>
|





|





|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












|

|







9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518








9519
9520

9521
9522






9523







9524
9525
9526
9527


9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555







9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584




















9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
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 case e in #(
  e) case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac ;;
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








IFS=" ""	$as_nl"


PS1='$ '
PS2='> '






PS4='+ '








# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL


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 ${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









# 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 #(((
    '') 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
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi























# 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
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  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.
8583
8584
8585
8586
8587
8588
8589

8590
8591
8592
8593
8594
8595
8596

8597
8598
8599
8600
8601
8602
8603
8604
8605

8606
8607
8608
8609
8610
8611
8612
8613

8614
8615
8616
8617
8618
8619
8620
8621
8622

8623
8624
8625
8626
8627
8628
8629
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset

# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :

  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }

fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :

  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }

fi # as_fn_arith


if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else







>






|
>




|
|


|
>







|
>




|
|


|
>







9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset

# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else case e in #(
  e) as_fn_append ()
  {
    eval $1=\$$1\$2
  } ;;
esac
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else case e in #(
  e) as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  } ;;
esac
fi # as_fn_arith


if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q







|







9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
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
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits





ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac







rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi







>
>
>
>












>
>
>
>
>
>












|
|
|







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
9759
# 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
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
    # In both cases, we have to default to 'cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|








|







9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
  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=`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 ||
printf "%s\n" X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
8771
8772
8773
8774
8775
8776
8777
8778

8779
8780
8781

8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"


# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"



exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by tk $as_me 8.7, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@








|
>


|
>














|
|







9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated

# Sed expression to map a string onto a valid variable name.
as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
as_tr_sh="eval sed '$as_sed_sh'" # deprecated


exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by tk $as_me 9.0, which was
generated by GNU Autoconf 2.72.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@

8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
config_files="$ac_config_files"
config_commands="$ac_config_commands"

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration.  Unless the files
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit







|







9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
config_files="$ac_config_files"
config_commands="$ac_config_commands"

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
'$as_me' instantiates files and other configuration actions
from templates according to the current configuration.  Unless the files
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit
8843
8844
8845
8846
8847
8848
8849


8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864

Configuration commands:
$config_commands

Report bugs to the package provider."

_ACEOF


cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
tk config.status 8.7
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
test -n "\$AWK" || AWK=awk
_ACEOF







>
>

|

|
|


|







9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923

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='$ac_cs_config_escaped'
ac_cs_version="\\
tk config.status 9.0
configured by $0, generated by GNU Autoconf 2.72,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2023 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
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
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
  esac

  case $ac_option in
  # Handling of the options.
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
    $as_echo "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    $as_echo "$ac_cs_config"; exit ;;
  --debug | --debu | --deb | --de | --d | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    case $ac_optarg in
    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    '') as_fn_error $? "missing file argument" ;;
    esac
    as_fn_append CONFIG_FILES " '$ac_optarg'"
    ac_need_defaults=false;;
  --he | --h |  --help | --hel | -h )
    $as_echo "$ac_cs_usage"; exit ;;
  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.
  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;

  *) as_fn_append ac_config_targets " $1"
     ac_need_defaults=false ;;

  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
  CONFIG_SHELL='$SHELL'
  export CONFIG_SHELL
  exec "\$@"
fi

_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
exec 5>>config.log
{
  echo
  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
  $as_echo "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
# 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" ;;

    "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
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
  tmp= ac_tmp=
  trap 'exit_status=$?
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0







|

|





|





|





|
|




















|













|



















>





|









|
|







|







9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
  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 )
    printf "%s\n" "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    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=`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 )
    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." ;;

  *) as_fn_append ac_config_targets " $1"
     ac_need_defaults=false ;;

  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \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
  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+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:
# after its creation but before its name has been assigned to '$tmp'.
$debug ||
{
  tmp= ac_tmp=
  trap 'exit_status=$?
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp

# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then


ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.







|







10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp

# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with './config.status config.h'.
if test -n "$CONFIG_FILES"; then


ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
for ac_tag
do
  case $ac_tag in
  :[FHLC]) ac_mode=$ac_tag; continue;;
  esac
  case $ac_mode$ac_tag in
  :[FHL]*:*);;
  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
  :[FH]-) ac_tag=-:-;;
  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
  esac
  ac_save_IFS=$IFS
  IFS=:
  set x $ac_tag
  IFS=$ac_save_IFS







|







10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
for ac_tag
do
  case $ac_tag in
  :[FHLC]) ac_mode=$ac_tag; continue;;
  esac
  case $ac_mode$ac_tag in
  :[FHL]*:*);;
  :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;;
  :[FH]-) ac_tag=-:-;;
  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
  esac
  ac_save_IFS=$IFS
  IFS=:
  set x $ac_tag
  IFS=$ac_save_IFS
9199
9200
9201
9202
9203
9204
9205
9206
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
    ac_file_inputs=
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
      *) # Look for the file first in the build tree, then in the source tree
	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
	 # because $ac_f cannot contain `:'.
	 test -f "$ac_f" ||
	   case $ac_f in
	   [\\/$]*) false;;
	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
	   esac ||
	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
      esac
      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
      as_fn_append ac_file_inputs " '$ac_f'"
    done

    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
    configure_input='Generated from '`
	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
    fi
    # Neutralize special characters interpreted by sed in replacement strings.
    case $configure_input in #(
    *\&* | *\|* | *\\* )
       ac_sed_conf_input=`$as_echo "$configure_input" |
       sed 's/[\\\\&|]/\\\\&/g'`;; #(
    *) ac_sed_conf_input=$configure_input;;
    esac

    case $ac_tag in
    *:-:* | *:-) cat >"$ac_tmp/stdin" \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
    esac
    ;;
  esac

  ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|





|

|



|



|



|
|




|
















|







10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
    ac_file_inputs=
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
      *) # Look for the file first in the build tree, then in the source tree
	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
	 # because $ac_f cannot contain ':'.
	 test -f "$ac_f" ||
	   case $ac_f in
	   [\\/$]*) false;;
	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
	   esac ||
	   as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;;
      esac
      case $ac_f in *\'*) ac_f=`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 '`
	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { 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=`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 ||
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
	  s/.*/./; q'`
  as_dir="$ac_dir"; as_fn_mkdir_p
  ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix







|

|







10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
	  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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  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
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  ac_datarootdir_hack='
  s&@datadir@&$datadir&g
  s&@docdir@&$docdir&g
  s&@infodir@&$infodir&g
  s&@localedir@&$localedir&g
  s&@mandir@&$mandir&g
  s&\\\${datarootdir}&$datarootdir&g' ;;
esac
_ACEOF

# Neutralize VPATH when `$srcdir' = `.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1







|
|












|







10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
/@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@*)
  { 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
  s&@mandir@&$mandir&g
  s&\\\${datarootdir}&$datarootdir&g' ;;
esac
_ACEOF

# Neutralize VPATH when '$srcdir' = '.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
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
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
      "$ac_tmp/out"`; test -z "$ac_out"; } &&
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&2;}

  rm -f "$ac_tmp/stdin"
  case $ac_file in
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \
  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 ;;


  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
$as_echo "$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 &&







|

|











|
|







10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
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"; } &&
  { 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
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)  { 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

  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi










|
|



>
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
  $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
  { 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#! /bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tk installation
dnl	to configure the system for the local environment.

AC_INIT([tk],[8.7])
AC_PREREQ(2.69)

dnl This is only used when included from macosx/configure.ac
m4_ifdef([SC_USE_CONFIG_HEADERS], [
    AC_CONFIG_HEADERS([tkConfig.h:../unix/tkConfig.h.in])
    AC_CONFIG_COMMANDS_PRE([DEFS="-DHAVE_TK_CONFIG_H  -imacros tkConfig.h"])
    AH_TOP([
    #ifndef _TKCONFIG
    #define _TKCONFIG])
    AH_BOTTOM([
    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_STRING
    /* override */ #undef PACKAGE_TARNAME

    #endif /* _TKCONFIG */])
])

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}])
fi
if test "${TCL_MINOR_VERSION}" -lt 6 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.6+
Found config for Tcl ${TCL_VERSION}])
fi
fi

SC_PROG_TCLSH
SC_BUILD_TCLSH

|




|
|












|
|
>



|
|
|
|











<
<
<
<
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40




41
42
43
44
45
46
47
48
49
! /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],[9.0])
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_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */])
])

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -lt 9 ; then




if test "${TCL_MINOR_VERSION}" -lt 7 ; then
    AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 8.7+
Found config for Tcl ${TCL_VERSION}])
fi
fi

SC_PROG_TCLSH
SC_BUILD_TCLSH

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# It makes compiling go faster.  (This is only a performance feature.)
#------------------------------------------------------------------------

if test -z "$no_pipe" && test -n "$GCC"; then
    AC_CACHE_CHECK([if the compiler understands -pipe],
	tcl_cv_cc_pipe, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
	CFLAGS=$hold_cflags])
    if test $tcl_cv_cc_pipe = yes; then
	CFLAGS="$CFLAGS -pipe"
    fi
fi

#------------------------------------------------------------------------







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# It makes compiling go faster.  (This is only a performance feature.)
#------------------------------------------------------------------------

if test -z "$no_pipe" && test -n "$GCC"; then
    AC_CACHE_CHECK([if the compiler understands -pipe],
	tcl_cv_cc_pipe, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_pipe=yes],[tcl_cv_cc_pipe=no])
	CFLAGS=$hold_cflags])
    if test $tcl_cv_cc_pipe = yes; then
	CFLAGS="$CFLAGS -pipe"
    fi
fi

#------------------------------------------------------------------------
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342






343
344
345
346
347
348
349
350

SC_TCL_64BIT_FLAGS

#--------------------------------------------------------------------
#	Check endianness because we can optimize some operations
#--------------------------------------------------------------------

AC_C_BIGENDIAN

#------------------------------------------------------------------------
# If Tcl and Tk are installed in different places, adjust the library
# search path to reflect this.
#------------------------------------------------------------------------

LIB_RUNTIME_DIR='$(libdir)'

if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
    LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib"
fi

if test "$TCL_PREFIX" != "$prefix"; then
    AC_MSG_WARN([
        Different --prefix selected for Tk and Tcl!
        [[package require Tk]] may not work correctly in tclsh.])
fi

#--------------------------------------------------------------------
#	Include sys/select.h if it exists and if it supplies things
#	that appear to be useful and aren't already in sys/types.h.
#	This appears to be true only on the RS/6000 under AIX.  Some
#	systems like OSF/1 have a sys/select.h that's of no use, and
#	other systems like SCO UNIX have a sys/select.h that's
#	pernicious.  If "fd_set" isn't defined anywhere then set a
#	special flag.
#--------------------------------------------------------------------

AC_CACHE_CHECK([for fd_set in sys/types], tcl_cv_type_fd_set, [
    AC_TRY_COMPILE([#include <sys/types.h>],[fd_set readMask, writeMask;],
	tcl_cv_type_fd_set=yes, tcl_cv_type_fd_set=no)])
tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then
    AC_CACHE_CHECK([for fd_mask in sys/select], tcl_cv_grep_fd_mask, [
	AC_EGREP_HEADER(fd_mask, sys/select.h,
	     tcl_cv_grep_fd_mask=present, tcl_cv_grep_fd_mask=missing)])
    if test $tcl_cv_grep_fd_mask = present; then
	AC_DEFINE(HAVE_SYS_SELECT_H, 1, [Should we include <sys/select.h>?])
	tk_ok=yes
    fi
fi
if test $tk_ok = no; then
    AC_DEFINE(NO_FD_SET, 1, [Do we have fd_set?])
fi

#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T

AC_CHECK_TYPE([intptr_t], [
    AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
    for tcl_cv_intptr_t in "int" "long" "long long" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_intptr_t" != none; then
	AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer
	   type wide enough to hold a pointer.])
    fi
])
AC_CHECK_TYPE([uintptr_t], [
    AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [
    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_uintptr_t" != none; then
	AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer
	   type wide enough to hold a pointer.])
    fi
])

#-------------------------------------------
#     In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------

AC_CACHE_CHECK([pw_gecos in struct pwd], tcl_cv_pwd_pw_gecos, [
    AC_TRY_COMPILE([#include <pwd.h>],
	    [struct passwd pwd; (void)pwd.pw_gecos;],
	    tcl_cv_pwd_pw_gecos=yes, tcl_cv_pwd_pw_gecos=no)])
if test $tcl_cv_pwd_pw_gecos = yes; then
    AC_DEFINE(HAVE_PW_GECOS, 1, [Does struct password have a pw_gecos field?])
fi

#--------------------------------------------------------------------
#	On Mac OS X, we can build either with X11 or with Aqua
#--------------------------------------------------------------------

if test "`uname -s`" = "Darwin" ; then
    AC_MSG_CHECKING([whether to use Aqua])
    AC_ARG_ENABLE(aqua,
	AC_HELP_STRING([--enable-aqua=yes|no],
	    [use Aqua windowingsystem on Mac OS X (default: no)]),
	[tk_aqua=$enableval], [tk_aqua=no])
    if test $tk_aqua = yes -o $tk_aqua = cocoa; then
	tk_aqua=yes
	if test $tcl_corefoundation = no; then
	    AC_MSG_WARN([Aqua can only be used when CoreFoundation is available])
	    tk_aqua=no
	fi
	if test ! -d /System/Library/Frameworks/Cocoa.framework; then
	    AC_MSG_WARN([Aqua can only be used when Cocoa is available])
	    tk_aqua=no
	fi
	if test "`uname -r | awk -F. '{print [$]1}'`" -lt 9; then
	    AC_MSG_WARN([Aqua requires Mac OS X 10.5 or later])
	    tk_aqua=no
	fi
    fi
    AC_MSG_RESULT([$tk_aqua])
    if test "$fat_32_64" = yes; then
	if test $tk_aqua = no; then
	    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
		done
		CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
		LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
		AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
		    tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
		for v in CFLAGS CPPFLAGS LDFLAGS; do
		    eval $v'="$hold_'$v'"'
		done])
	fi
	# remove 64-bit arch flags from CFLAGS et al. for combined 32 & 64 bit
	# fat builds if configuration does not support 64-bit.
	if test "$tcl_cv_lib_x11_64" = no; then
	    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
	    for v in CFLAGS CPPFLAGS LDFLAGS; do
		eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
	    done
	fi
    fi
    if test $tk_aqua = no; then
	# check if weak linking whole libraries is possible.
	AC_CACHE_CHECK([if ld accepts -weak-l flag], tcl_cv_ld_weak_l, [
	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    AC_TRY_LINK([#include <math.h>], [double f = sin(1.0);],
		tcl_cv_ld_weak_l=yes, tcl_cv_ld_weak_l=no)
	    LDFLAGS=$hold_ldflags])
    fi
    AC_CHECK_HEADERS(AvailabilityMacros.h)
    if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
	AC_CACHE_CHECK([if weak import is available], tcl_cv_cc_weak_import, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_TRY_LINK([
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #endif
		    int rand(void) __attribute__((weak_import));
		], [rand();],
		tcl_cv_cc_weak_import=yes, tcl_cv_cc_weak_import=no)
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_weak_import = yes; then
	    AC_DEFINE(HAVE_WEAK_IMPORT, 1, [Is weak import available?])
	fi
	AC_CACHE_CHECK([if Darwin SUSv3 extensions are available],
	    tcl_cv_cc_darwin_c_source, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_TRY_COMPILE([
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #endif
		    #define _DARWIN_C_SOURCE 1
		    #include <sys/cdefs.h>
		],,tcl_cv_cc_darwin_c_source=yes, tcl_cv_cc_darwin_c_source=no)
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_darwin_c_source = yes; then
	    AC_DEFINE(_DARWIN_C_SOURCE, 1,
		    [Are Darwin SUSv3 extensions available?])
	fi
    fi
else
    tk_aqua=no
fi

if test $tk_aqua = yes; then
    AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?])
    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"






    EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then
        AC_DEFINE(TK_MAC_DEBUG, 1, [Are TkAqua debug messages enabled?])
    fi
else
    #--------------------------------------------------------------------
    #	Locate the X11 header files and the X11 library archive.  Try







|















|













|
<


















|
<









<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|






<
|
<











|


















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|
|






|








|
|







|









|












|
>
>
>
>
>
>
|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187

188
189














190














191
192
193
194
195
196
197

198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228























229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

SC_TCL_64BIT_FLAGS

#--------------------------------------------------------------------
#	Check endianness because we can optimize some operations
#--------------------------------------------------------------------

AC_C_BIGENDIAN(,,,[#])

#------------------------------------------------------------------------
# If Tcl and Tk are installed in different places, adjust the library
# search path to reflect this.
#------------------------------------------------------------------------

LIB_RUNTIME_DIR='$(libdir)'

if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
    LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib"
fi

if test "$TCL_PREFIX" != "$prefix"; then
    AC_MSG_WARN([
        Different --prefix selected for Tk and Tcl!
        [[package require tk]] may not work correctly in tclsh.])
fi

#--------------------------------------------------------------------
#	Include sys/select.h if it exists and if it supplies things
#	that appear to be useful and aren't already in sys/types.h.
#	This appears to be true only on the RS/6000 under AIX.  Some
#	systems like OSF/1 have a sys/select.h that's of no use, and
#	other systems like SCO UNIX have a sys/select.h that's
#	pernicious.  If "fd_set" isn't defined anywhere then set a
#	special flag.
#--------------------------------------------------------------------

AC_CACHE_CHECK([for fd_set in sys/types], tcl_cv_type_fd_set, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]], [[fd_set readMask, writeMask;]])],[tcl_cv_type_fd_set=yes],[tcl_cv_type_fd_set=no])])

tk_ok=$tcl_cv_type_fd_set
if test $tk_ok = no; then
    AC_CACHE_CHECK([for fd_mask in sys/select], tcl_cv_grep_fd_mask, [
	AC_EGREP_HEADER(fd_mask, sys/select.h,
	     tcl_cv_grep_fd_mask=present, tcl_cv_grep_fd_mask=missing)])
    if test $tcl_cv_grep_fd_mask = present; then
	AC_DEFINE(HAVE_SYS_SELECT_H, 1, [Should we include <sys/select.h>?])
	tk_ok=yes
    fi
fi
if test $tk_ok = no; then
    AC_DEFINE(NO_FD_SET, 1, [Do we have fd_set?])
fi

#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS_ONCE([sys/time.h])


#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T


AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[














#include <stdint.h>














]])

#-------------------------------------------
#     In OS/390 struct pwd has no pw_gecos field
#-------------------------------------------

AC_CACHE_CHECK([pw_gecos in struct pwd], tcl_cv_pwd_pw_gecos, [

    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <pwd.h>]], [[struct passwd pwd; (void)pwd.pw_gecos;]])],[tcl_cv_pwd_pw_gecos=yes],[tcl_cv_pwd_pw_gecos=no])])

if test $tcl_cv_pwd_pw_gecos = yes; then
    AC_DEFINE(HAVE_PW_GECOS, 1, [Does struct password have a pw_gecos field?])
fi

#--------------------------------------------------------------------
#	On Mac OS X, we can build either with X11 or with Aqua
#--------------------------------------------------------------------

if test "`uname -s`" = "Darwin" ; then
    AC_MSG_CHECKING([whether to use Aqua])
    AC_ARG_ENABLE(aqua,
	AS_HELP_STRING([--enable-aqua=yes|no],
	    [use Aqua windowingsystem on Mac OS X (default: no)]),
	[tk_aqua=$enableval], [tk_aqua=no])
    if test $tk_aqua = yes -o $tk_aqua = cocoa; then
	tk_aqua=yes
	if test $tcl_corefoundation = no; then
	    AC_MSG_WARN([Aqua can only be used when CoreFoundation is available])
	    tk_aqua=no
	fi
	if test ! -d /System/Library/Frameworks/Cocoa.framework; then
	    AC_MSG_WARN([Aqua can only be used when Cocoa is available])
	    tk_aqua=no
	fi
	if test "`uname -r | awk -F. '{print [$]1}'`" -lt 9; then
	    AC_MSG_WARN([Aqua requires Mac OS X 10.5 or later])
	    tk_aqua=no
	fi
    fi
    AC_MSG_RESULT([$tk_aqua])























    if test $tk_aqua = no; then
	# check if weak linking whole libraries is possible.
	AC_CACHE_CHECK([if ld accepts -weak-l flag], tcl_cv_ld_weak_l, [
	    hold_ldflags=$LDFLAGS
	    LDFLAGS="$LDFLAGS -Wl,-weak-lm"
	    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]], [[double f = sin(1.0);]])],
	    [tcl_cv_ld_weak_l=yes],[tcl_cv_ld_weak_l=no])
	    LDFLAGS=$hold_ldflags])
    fi
    AC_CHECK_HEADERS(AvailabilityMacros.h)
    if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
	AC_CACHE_CHECK([if weak import is available], tcl_cv_cc_weak_import, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1020
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1020
		    #endif
		    int rand(void) __attribute__((weak_import));
		]], [[rand();]])],
		[tcl_cv_cc_weak_import=yes],[tcl_cv_cc_weak_import=no])
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_weak_import = yes; then
	    AC_DEFINE(HAVE_WEAK_IMPORT, 1, [Is weak import available?])
	fi
	AC_CACHE_CHECK([if Darwin SUSv3 extensions are available],
	    tcl_cv_cc_darwin_c_source, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		    #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
		    #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #error __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
		    #endif
		    #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #error MAC_OS_X_VERSION_MIN_REQUIRED < 1050
		    #endif
		    #define _DARWIN_C_SOURCE 1
		    #include <sys/cdefs.h>
		]], [[]])],[tcl_cv_cc_darwin_c_source=yes],[tcl_cv_cc_darwin_c_source=no])
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_darwin_c_source = yes; then
	    AC_DEFINE(_DARWIN_C_SOURCE, 1,
		    [Are Darwin SUSv3 extensions available?])
	fi
    fi
else
    tk_aqua=no
fi

if test $tk_aqua = yes; then
    AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?])
    LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore -framework Security -framework CoreGraphics"
    if test -d /System/Library/Frameworks/UserNotifications.framework; then
        LIBS="$LIBS -framework UserNotifications"
    fi
    if test -d "/System/Library/Frameworks/UniformTypeIdentifiers.framework"; then
        LIBS="$LIBS -weak_framework UniformTypeIdentifiers"
    fi
    EXTRA_CC_SWITCHES='-x objective-c'
    TK_WINDOWINGSYSTEM=AQUA
    if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then
        AC_DEFINE(TK_MAC_DEBUG, 1, [Are TkAqua debug messages enabled?])
    fi
else
    #--------------------------------------------------------------------
    #	Locate the X11 header files and the X11 library archive.  Try
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

if test -d /usr/include/mit -a $tk_aqua = no; then
    AC_MSG_CHECKING([MIT X libraries])
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS -I/usr/include/mit"
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lX11-mit"
    AC_TRY_LINK([
	#include <X11/Xlib.h>
    ], [
	XOpenDisplay(0);
    ], [
	AC_MSG_RESULT([yes])
	XLIBSW="-lX11-mit"
	XINCLUDES="-I/usr/include/mit"
    ], AC_MSG_RESULT([no]))
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    AC_MSG_CHECKING([whether to use xft])
    AC_ARG_ENABLE(xft,
	AC_HELP_STRING([--enable-xft],
	    [use freetype/fontconfig/xft (default: on)]),
	[enable_xft=$enableval], [enable_xft="default"])
    XFT_CFLAGS=""
    XFT_LIBS=""
    if test "$enable_xft" = "no" ; then
	AC_MSG_RESULT([$enable_xft])
    else







|

|

|



|











|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

if test -d /usr/include/mit -a $tk_aqua = no; then
    AC_MSG_CHECKING([MIT X libraries])
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS -I/usr/include/mit"
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lX11-mit"
    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
	#include <X11/Xlib.h>
    ]], [[
	XOpenDisplay(0);
    ]])],[
	AC_MSG_RESULT([yes])
	XLIBSW="-lX11-mit"
	XINCLUDES="-I/usr/include/mit"
    ],[AC_MSG_RESULT(no)])
    CFLAGS=$tk_oldCFlags
    LIBS=$tk_oldLibs
fi

#--------------------------------------------------------------------
#	Check for freetype / fontconfig / Xft support.
#--------------------------------------------------------------------

if test $tk_aqua = no; then
    AC_MSG_CHECKING([whether to use xft])
    AC_ARG_ENABLE(xft,
	AS_HELP_STRING([--enable-xft],
	    [use freetype/fontconfig/xft (default: on)]),
	[enable_xft=$enableval], [enable_xft="default"])
    XFT_CFLAGS=""
    XFT_LIBS=""
    if test "$enable_xft" = "no" ; then
	AC_MSG_RESULT([$enable_xft])
    else
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
    CFLAGS="$CFLAGS $XINCLUDES"
    tk_oldLibs=$LIBS
    LIBS="$tk_oldLibs $XLIBSW"
    xss_header_found=no
    xss_lib_found=no
    AC_MSG_CHECKING([whether to try to use XScreenSaver])
    AC_ARG_ENABLE(xss,
	AC_HELP_STRING([--enable-xss],
	    [use XScreenSaver for activity timer (default: on)]),
	[enable_xss=$enableval], [enable_xss=yes])
    if test "$enable_xss" = "no" ; then
	AC_MSG_RESULT([$enable_xss])
    else
	AC_MSG_RESULT([$enable_xss])
	AC_CHECK_HEADER(X11/extensions/scrnsaver.h, [







|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    CFLAGS="$CFLAGS $XINCLUDES"
    tk_oldLibs=$LIBS
    LIBS="$tk_oldLibs $XLIBSW"
    xss_header_found=no
    xss_lib_found=no
    AC_MSG_CHECKING([whether to try to use XScreenSaver])
    AC_ARG_ENABLE(xss,
	AS_HELP_STRING([--enable-xss],
	    [use XScreenSaver for activity timer (default: on)]),
	[enable_xss=$enableval], [enable_xss=yes])
    if test "$enable_xss" = "no" ; then
	AC_MSG_RESULT([$enable_xss])
    else
	AC_MSG_RESULT([$enable_xss])
	AC_CHECK_HEADER(X11/extensions/scrnsaver.h, [
582
583
584
585
586
587
588


589




590
591
592
593
594
595
596
#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"


eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"





# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then







>
>

>
>
>
>







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE_TCL8=libtk${LIB_SUFFIX}"
if test ${TCL_MAJOR_VERSION} = 8 ; then
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"
else
eval "TK_LIB_FILE=libtcl9tk${LIB_SUFFIX}"
fi
eval "TK_LIB_FILE_TCL9=libtcl9tk${LIB_SUFFIX}"

# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
613
614
615
616
617
618
619


620

621
622
623
624
625
626
627
628
if test "`uname -s`" = "Darwin" ; then
    SC_ENABLE_FRAMEWORK
    TK_SHLIB_LD_EXTRAS="-compatibility_version ${TK_VERSION} -current_version ${TK_VERSION}`echo ${TK_PATCH_LEVEL} | awk ['{match($0, "\\\.[0-9]+"); print substr($0,RSTART,RLENGTH)}']`"
    TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -install_name "${DYLIB_INSTALL_DIR}/${TK_LIB_FILE}" -unexported_symbols_list $$(f=$(TK_LIB_FILE).E && nm -gp tkMacOSX*.o 2>/dev/null | awk "/^[[0-9a-f]]+ . \.objc/ {print \$$3}" > $$f && nm -gjp "$(TCL_BIN_DIR)"/$(TCL_STUB_LIB_FILE) | grep ^_[[^_]] >> $$f && echo $$f)'
    echo "$LDFLAGS " | grep -q -- '-prebind ' && TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -seg1addr 0xb000000'
    TK_SHLIB_LD_EXTRAS="${TK_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tk-Info.plist'
    EXTRA_WISH_LIBS='-sectcreate __TEXT __info_plist Wish-Info.plist'


    EXTRA_APP_CC_SWITCHES="${EXTRA_APP_CC_SWITCHES}"' -mdynamic-no-pic'

    AC_CONFIG_FILES([Tk-Info.plist:../macosx/Tk-Info.plist.in Wish-Info.plist:../macosx/Wish-Info.plist.in])
    for l in ${LOCALES}; do CFBUNDLELOCALIZATIONS="${CFBUNDLELOCALIZATIONS}<string>$l</string>"; done
    TK_YEAR="`date +%Y`"
fi

if test "$FRAMEWORK_BUILD" = "1" ; then
    AC_DEFINE(TK_FRAMEWORK, 1, [Is Tk built as a framework?])
    # Construct a fake local framework structure to make linking with







>
>
|
>
|







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
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
    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
636
637
638
639
640
641
642

643





644
645
646
647
648
649
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675
676
677
678
679




680
681
682
683
684
685
686
687
688
689
690
691
692













































693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
        unset n f v
    ], VERSION=${TK_VERSION} && tk_aqua=${tk_aqua})
    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    if test "${libdir}" = '${exec_prefix}/lib'; then
        # override libdir default
        libdir="/Library/Frameworks"
    fi

    TK_LIB_FILE="Tk"





    TK_LIB_FLAG="-framework Tk"
    TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
    TK_LIB_SPEC="-F${libdir} -framework Tk"
    libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
    TK_LIBRARY="${libdir}/Resources/Scripts"
    TK_PKG_DIR="Resources/Scripts"
    TK_RSRC_FILE="Tk.rsrc"
    WISH_RSRC_FILE="Wish.rsrc"
    includedir="${libdir}/Headers"
    PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
    HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
    EXTRA_INSTALL="install-private-headers html-tk"
    EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
    EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'

    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
    if test $tk_aqua = yes; then
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'/" && $(INSTALL_DATA_DIR) "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
	bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'

    fi
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
    # Don't use AC_DEFINE for the following as the framework version define
    # needs to go into the Makefile even when using autoheader, so that we
    # can pick up a potential make override of VERSION. Also, don't put this
    # into CFLAGS as it should not go into tkConfig.sh
    EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    if test $tk_aqua = yes; then
        EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
    fi
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"




    if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
	TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
    else
	if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	    TK_LIB_FLAG="-ltk${TK_VERSION}"
	else
	    TK_LIB_FLAG="-ltk`echo ${TK_VERSION} | tr -d .`"
	fi
	TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
    fi
    TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi














































#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tk
#       stub support.
#--------------------------------------------------------------------

# Replace ${VERSION} with contents of ${TK_VERSION}
eval "TK_STUB_LIB_FILE=libtkstub${TK_UNSHARED_LIB_SUFFIX}"
eval "TK_STUB_LIB_DIR=${libdir}"

if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
    TK_STUB_LIB_FLAG="-ltkstub${TK_VERSION}"
else
    TK_STUB_LIB_FLAG="-ltkstub`echo ${TK_VERSION} | tr -d .`"
fi

TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"
TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}"

# Install time header dir can be set via --includedir







>
|
>
>
>
>
>














>









>













>
>
>
>

|



|

|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
<
<
<
|
<
|
<







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713



714

715

716
717
718
719
720
721
722
        unset n f v
    ], VERSION=${TK_VERSION} && tk_aqua=${tk_aqua})
    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    if test "${libdir}" = '${exec_prefix}/lib'; then
        # override libdir default
        libdir="/Library/Frameworks"
    fi
    if test ${TCL_MAJOR_VERSION} = 8 ; then
	TK_LIB_FILE="Tk"
    else
	TK_LIB_FILE="Tk"
    fi
    TK_LIB_FILE_TCL8="Tk"
    TK_LIB_FILE_TCL9="Tk"
    TK_LIB_FLAG="-framework Tk"
    TK_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tk"
    TK_LIB_SPEC="-F${libdir} -framework Tk"
    libdir="${libdir}/Tk.framework/Versions/\${VERSION}"
    TK_LIBRARY="${libdir}/Resources/Scripts"
    TK_PKG_DIR="Resources/Scripts"
    TK_RSRC_FILE="Tk.rsrc"
    WISH_RSRC_FILE="Wish.rsrc"
    includedir="${libdir}/Headers"
    PRIVATE_INCLUDE_DIR="${libdir}/PrivateHeaders"
    HTML_DIR="${libdir}/Resources/Documentation/Reference/Tk"
    EXTRA_INSTALL="install-private-headers html-tk"
    EXTRA_BUILD_HTML='@ln -fs contents.htm "$(HTML_INSTALL_DIR)"/TkTOC.html'
    EXTRA_INSTALL_BINARIES='@echo "Installing Info.plist to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Tk-Info.plist "$(LIB_INSTALL_DIR)/Resources/Info.plist"'
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Credits.html "$(LIB_INSTALL_DIR)/Resources"'
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing license.terms to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA) "$(TOP_DIR)/license.terms" "$(LIB_INSTALL_DIR)/Resources"'
    if test $tk_aqua = yes; then
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Images to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)/Resources"; done'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing wish$(VERSION) script to $(INSTALL_ROOT)/'"${bindir}"'/" && $(INSTALL_DATA_DIR) "$(INSTALL_ROOT)/'"${bindir}"'" && printf > "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)" "#!/bin/sh\n\"\$$(dirname \$$0)'"`eval d="${bindir}"; echo "$d" | sed -e 's#/[^/][^/]*#/..#g'`"'$(bindir)/Wish\" \"\$$@\"" && chmod +x "$(INSTALL_ROOT)/'"${bindir}"'/wish$(VERSION)"'
	bindir="${libdir}/Resources/Wish.app/Contents/MacOS"
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Info.plist to $(BIN_INSTALL_DIR)/.." && $(INSTALL_DATA) Wish-Info.plist "$(BIN_INSTALL_DIR)/../Info.plist" && mv -f "$(BIN_INSTALL_DIR)/wish$(VERSION)" "$(BIN_INSTALL_DIR)/Wish"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.icns to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA_DIR) "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Tk.icns" "$(BIN_INSTALL_DIR)/../Resources/Wish.icns"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Wish.sdef to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) "$(MAC_OSX_DIR)/Wish.sdef" "$(BIN_INSTALL_DIR)/../Resources"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) Credits.html "$(BIN_INSTALL_DIR)/../Resources"'
    fi
    EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Finalizing Tk.framework" && rm -f "$(LIB_INSTALL_DIR)/../Current" && ln -s "$(VERSION)" "$(LIB_INSTALL_DIR)/../Current" && for f in "$(LIB_FILE)" tkConfig.sh Resources Headers PrivateHeaders; do rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/Current/$$f" "$(LIB_INSTALL_DIR)/../.."; done && f="$(STUB_LIB_FILE)" && rm -f "$(LIB_INSTALL_DIR)/../../$$f" && ln -s "Versions/$(VERSION)/$$f" "$(LIB_INSTALL_DIR)/../.."'
    # Don't use AC_DEFINE for the following as the framework version define
    # needs to go into the Makefile even when using autoheader, so that we
    # can pick up a potential make override of VERSION. Also, don't put this
    # into CFLAGS as it should not go into tkConfig.sh
    EXTRA_CC_SWITCHES="$EXTRA_CC_SWITCHES"' -DTK_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    if test $tk_aqua = yes; then
        EXTRA_INSTALL_BINARIES='@echo "Installing Images to $(LIB_INSTALL_DIR)/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)" && for i in Tk.tiff Tk.icns; do $(INSTALL_DATA) "$(MAC_OSX_DIR)/$$i" "$(LIB_INSTALL_DIR)"; done'
    fi
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    TK_LIB_FLAG="-l"
    if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
	TK_LIB_FLAG="${TK_LIB_FLAG}tcl9"
    fi
    if test "${ac_cv_cygwin}" = "yes" -a "$SHARED_BUILD" = "1"; then
	TK_LIB_FLAG="${TK_LIB_FLAG}tk`echo ${TK_VERSION} | tr -d .`"
	TK_BUILD_LIB_SPEC="-L\$(TOP_DIR)/win ${TK_LIB_FLAG}"
    else
	if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	    TK_LIB_FLAG="${TK_LIB_FLAG}tk${TK_VERSION}"
	else
	    TK_LIB_FLAG="${TK_LIB_FLAG}tk`echo ${TK_VERSION} | tr -d .`"
	fi
	TK_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_LIB_FLAG}"
    fi
    TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
fi

#--------------------------------------------------------------------
#	Zipfs support - Tip 430
#--------------------------------------------------------------------
AC_ARG_ENABLE(zipfs,
    AS_HELP_STRING([--enable-zipfs],[build with Zipfs support (default: on)]),
    [tcl_ok=$enableval], [tcl_ok=yes])
if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then
    #
    # Find a native compiler
    #
    AX_CC_FOR_BUILD
    #
    # Find a native zip implementation
    #
    SC_ZIPFS_SUPPORT
	ZIPFS_BUILD=1
	TK_ZIP_FILE=libtk${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_PATCH_LEVEL}.zip
else
	ZIPFS_BUILD=0
	TK_ZIP_FILE=
fi
# Do checking message here to not mess up interleaved configure output
AC_MSG_CHECKING([for building with zipfs])
if test "${ZIPFS_BUILD}" = 1; then
    if test "${SHARED_BUILD}" = 0; then
       ZIPFS_BUILD=2;
       AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?])
       INSTALL_LIBRARIES=install-demos
       AC_MSG_RESULT([yes])
     else
       AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\
       INSTALL_LIBRARIES=install-demos
       AC_MSG_RESULT([yes])
    fi
else
AC_MSG_RESULT([no])
INSTALL_LIBRARIES=install-libraries
INSTALL_MSGS=install-msgs
fi
AC_SUBST(ZIPFS_BUILD)
AC_SUBST(TK_ZIP_FILE)
AC_SUBST(INSTALL_LIBRARIES)
AC_SUBST(INSTALL_MSGS)


#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tk
#       stub support.
#--------------------------------------------------------------------

# Replace ${VERSION} with contents of ${TK_VERSION}
    TK_STUB_LIB_FILE="libtkstub.a"



    TK_STUB_LIB_FLAG="-ltkstub"

eval "TK_STUB_LIB_DIR=\"${libdir}\""


TK_BUILD_STUB_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_SPEC="-L${TK_STUB_LIB_DIR} ${TK_STUB_LIB_FLAG}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"
TK_STUB_LIB_PATH="${TK_STUB_LIB_DIR}/${TK_STUB_LIB_FILE}"

# Install time header dir can be set via --includedir
733
734
735
736
737
738
739


740
741
742
743
744
745
746
AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_YEAR)

AC_SUBST(TK_LIB_FILE)


AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_INCLUDE_SPEC)







>
>







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_YEAR)

AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_LIB_FILE_TCL8)
AC_SUBST(TK_LIB_FILE_TCL9)
AC_SUBST(TK_LIB_FLAG)
AC_SUBST(TK_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_STUB_LIB_SPEC)
AC_SUBST(TK_STUB_LIB_PATH)
AC_SUBST(TK_INCLUDE_SPEC)

Changes to unix/install-sh.

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2020-07-26.22; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#



|







1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2020-11-14.01; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
69
70
71
72
73
74
75

76
77
78
79
80
81
82
# 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=








>







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Desired mode of installed file.
mode=0755

# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22

backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

99
100
101
102
103
104
105
106
107
108
109
110

111
112

113
114
115
116
117
118








119
120
121
122
123
124
125
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.

  -s            $stripprog installed files.
  -S OPTION     $stripprog installed files using OPTION.

  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG








"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;







|




>

<
>






>
>
>
>
>
>
>
>







100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -p            pass -p to $cpprog.
  -s            $stripprog installed files.

  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG

By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.

If -S is not specified, no backups are attempted.

Email bug reports to [email protected].
Automake home page: https://www.gnu.org/software/automake/
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152
153
154
            exit 1;;
        esac
        shift;;

    -o) chowncmd="$chownprog $2"
        shift;;



    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
        shift;;

    -t)
        is_target_a_directory=always
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in







>
>


|







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
            exit 1;;
        esac
        shift;;

    -o) chowncmd="$chownprog $2"
        shift;;

    -p) cpprog="$cpprog -p";;

    -s) stripcmd=$stripprog;;

    -S) backupsuffix="$2"
        shift;;

    -t)
        is_target_a_directory=always
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in
259
260
261
262
263
264
265




266
267
268
269
270
271
272
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?




  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2







>
>
>
>







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
    # Don't chown directories that already exist.
    if test $dstdir_status = 0; then
      chowncmd=""
    fi
  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
473
474
475
476
477
478
479







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
       set X $new && new=:$2:$4:$5:$6 &&
       set +f &&
       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else







      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
        # Now remove or move aside any old file at destination location.
        # We try this two ways since rm can't unlink itself on some
        # systems and the destination file might be busy for other
        # reasons.  In this case, the final cleanup might fail but the new
        # file should still install successfully.
        {
          test ! -f "$dst" ||
          $doit $rmcmd -f "$dst" 2>/dev/null ||
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&

        # Now rename the file to the real destination.







>
>
>
>
>
>
>














|

|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
       set X $new && new=:$2:$4:$5:$6 &&
       set +f &&
       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # If $backupsuffix is set, and the file being installed
      # already exists, attempt a backup.  Don't worry if it fails,
      # e.g., if mv doesn't support -f.
      if test -n "$backupsuffix" && test -f "$dst"; then
        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
      fi

      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
        # Now remove or move aside any old file at destination location.
        # We try this two ways since rm can't unlink itself on some
        # systems and the destination file might be busy for other
        # reasons.  In this case, the final cleanup might fail but the new
        # file should still install successfully.
        {
          test ! -f "$dst" ||
          $doit $rmcmd "$dst" 2>/dev/null ||
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&

        # Now rename the file to the real destination.

Changes to unix/installManPage.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/sh

########################################################################
### Parse Options
###

Gzip=:

SymOrLoc=""
Gz=""
Suffix=""

while true; do
    case $1 in
        -s | --symlinks  ) SymOrLoc="-s "      ;;
        -z | --compress  )     Gzip=$2;  shift ;;
	-e | --extension )       Gz=$2;  shift ;;
	-x | --suffix    )   Suffix=$2;  shift ;;
	-*) cat <<EOF
Unknown option "$1". Supported options:
    -s         Use symbolic links for manpages with multiple names.
    -z PROG    Use PROG to compress manual pages.







>
|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/sh

########################################################################
### Parse Options
###

Gzip=:
Sym=""
Loc=""
Gz=""
Suffix=""

while true; do
    case $1 in
        -s | --symlinks  )      Sym="-s "      ;;
        -z | --compress  )     Gzip=$2;  shift ;;
	-e | --extension )       Gz=$2;  shift ;;
	-x | --suffix    )   Suffix=$2;  shift ;;
	-*) cat <<EOF
Unknown option "$1". Supported options:
    -s         Use symbolic links for manpages with multiple names.
    -z PROG    Use PROG to compress manual pages.
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    echo "source manual page file must exist"
    exit 1
fi
if test -d "$Dir" ; then : ; else
    echo "target directory must exist"
    exit 1
fi
test -z "$SymOrLoc" && SymOrLoc="$Dir/"

########################################################################
### Extract Target Names from Manual Page
###

# A sed script to parse the alternative names out of a man page.
#







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    echo "source manual page file must exist"
    exit 1
fi
if test -d "$Dir" ; then : ; else
    echo "target directory must exist"
    exit 1
fi
test -z "$Sym" && Loc="$Dir/"

########################################################################
### Extract Target Names from Manual Page
###

# A sed script to parse the alternative names out of a man page.
#
113
114
115
116
117
118
119
120
121
122
123
124
125
    if test -z "$First" ; then
	First=$Target
	sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
	    $ManPage > "$Dir/$First"
	chmod 644 "$Dir/$First"
	$Gzip "$Dir/$First"
    else
	ln "$SymOrLoc$First$Gz" "$Dir/$Target$Gz"
    fi
done

########################################################################
exit 0







|





114
115
116
117
118
119
120
121
122
123
124
125
126
    if test -z "$First" ; then
	First=$Target
	sed -e "/man\.macros/r $SrcDir/man.macros" -e "/man\.macros/d" \
	    $ManPage > "$Dir/$First"
	chmod 644 "$Dir/$First"
	$Gzip "$Dir/$First"
    else
	ln $Sym"$Loc$First$Gz" "$Dir/$Target$Gz"
    fi
done

########################################################################
exit 0

Changes to unix/tcl.m4.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )







|

|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AS_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    [with_tclconfig="${withval}"])
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tcl8.7 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.7 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.7 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi







|


|
|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tcl9.0 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl9.0 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl9.0 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )







|

|







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,
	    AS_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    [with_tkconfig="${withval}"])
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tk8.7 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tk8.7 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.7 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi







|


|
|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib/tk9.0 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tk9.0 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk9.0 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
#	Sets the following vars:
#		SHARED_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	AC_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])







|


<
<
<
<
<
<
<
<







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,
	AS_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])








    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
#		FRAMEWORK_BUILD	Value of 1 or 0
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_FRAMEWORK], [
    if test "`uname -s`" = "Darwin" ; then
	AC_MSG_CHECKING([how to package libraries])
	AC_ARG_ENABLE(framework,
	    AC_HELP_STRING([--enable-framework],
		[package shared libraries in MacOSX frameworks (default: off)]),
	    [enable_framework=$enableval], [enable_framework=no])
	if test $enable_framework = yes; then
	    if test $SHARED_BUILD = 0; then
		AC_MSG_WARN([Frameworks can only be built if --enable-shared is yes])
		enable_framework=no
	    fi







|







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,
	    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
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SYMBOLS], [
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols,
	AC_HELP_STRING([--enable-symbols],
	    [build with debugging symbols (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])







|







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,
	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
#
#	Defines the following vars:
#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_LANGINFO], [
    AC_ARG_ENABLE(langinfo,
	AC_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])

    HAVE_LANGINFO=0
    if test "$langinfo_ok" = "yes"; then
	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
    fi
    AC_MSG_CHECKING([whether to use nl_langinfo])
    if test "$langinfo_ok" = "yes"; then
	AC_CACHE_VAL(tcl_cv_langinfo_h, [
	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else
	AC_MSG_RESULT([$langinfo_ok])
    fi







|










|
|







656
657
658
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,
	AS_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])

    HAVE_LANGINFO=0
    if test "$langinfo_ok" = "yes"; then
	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
    fi
    AC_MSG_CHECKING([whether to use nl_langinfo])
    if test "$langinfo_ok" = "yes"; then
	AC_CACHE_VAL(tcl_cv_langinfo_h, [
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <langinfo.h>]], [[nl_langinfo(CODESET);]])],
		    [tcl_cv_langinfo_h=yes], [tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else
	AC_MSG_RESULT([$langinfo_ok])
    fi
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
#			according to the user's selection.
#
#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_MANPAGES], [
    AC_MSG_CHECKING([whether to use symlinks for manpages])
    AC_ARG_ENABLE(man-symlinks,
	AC_HELP_STRING([--enable-man-symlinks],
	    [use symlinks for the manpages (default: off)]),
	test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks",
	enableval="no")
    AC_MSG_RESULT([$enableval])

    AC_MSG_CHECKING([whether to compress the manpages])
    AC_ARG_ENABLE(man-compression,
	AC_HELP_STRING([--enable-man-compression=PROG],
	    [compress the manpages with PROG (default: off)]),
	[case $enableval in
	    yes) AC_MSG_ERROR([missing argument to --enable-man-compression]);;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
	esac],
	enableval="no")
    AC_MSG_RESULT([$enableval])
    if test "$enableval" != "no"; then
	AC_MSG_CHECKING([for compressed file suffix])
	touch TeST
	$enableval TeST
	Z=`ls TeST* | sed 's/^....//'`
	rm -f TeST*
	MAN_FLAGS="$MAN_FLAGS --extension $Z"
	AC_MSG_RESULT([$Z])
    fi

    AC_MSG_CHECKING([whether to add a package name suffix for the manpages])
    AC_ARG_ENABLE(man-suffix,
	AC_HELP_STRING([--enable-man-suffix=STRING],
	    [use STRING as a suffix to manpage file names (default: no, AC_PACKAGE_NAME if enabled without specifying STRING)]),
	[case $enableval in
	    yes) enableval="AC_PACKAGE_NAME" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	esac],
	enableval="no")
    AC_MSG_RESULT([$enableval])

    AC_SUBST(MAN_FLAGS)
])

#--------------------------------------------------------------------
# SC_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command.
#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.

#--------------------------------------------------------------------

AC_DEFUN([SC_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
	if test "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows
	else







|

|
|




|






|













|






|



















>







708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
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,
	AS_HELP_STRING([--enable-man-symlinks],
	    [use symlinks for the manpages (default: off)]),
	[test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"],
	[enableval="no"])
    AC_MSG_RESULT([$enableval])

    AC_MSG_CHECKING([whether to compress the manpages])
    AC_ARG_ENABLE(man-compression,
	AS_HELP_STRING([--enable-man-compression=PROG],
	    [compress the manpages with PROG (default: off)]),
	[case $enableval in
	    yes) AC_MSG_ERROR([missing argument to --enable-man-compression]);;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
	esac],
	[enableval="no"])
    AC_MSG_RESULT([$enableval])
    if test "$enableval" != "no"; then
	AC_MSG_CHECKING([for compressed file suffix])
	touch TeST
	$enableval TeST
	Z=`ls TeST* | sed 's/^....//'`
	rm -f TeST*
	MAN_FLAGS="$MAN_FLAGS --extension $Z"
	AC_MSG_RESULT([$Z])
    fi

    AC_MSG_CHECKING([whether to add a package name suffix for the manpages])
    AC_ARG_ENABLE(man-suffix,
	AS_HELP_STRING([--enable-man-suffix=STRING],
	    [use STRING as a suffix to manpage file names (default: no, AC_PACKAGE_NAME if enabled without specifying STRING)]),
	[case $enableval in
	    yes) enableval="AC_PACKAGE_NAME" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	    no)  ;;
	    *)   MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
	esac],
	[enableval="no"])
    AC_MSG_RESULT([$enableval])

    AC_SUBST(MAN_FLAGS)
])

#--------------------------------------------------------------------
# SC_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command.
#
# 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

AC_DEFUN([SC_CONFIG_CFLAGS], [

    # Step 0.a: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,
	AC_HELP_STRING([--enable-64bit],
	    [enable 64bit support (default: off)]),
	[do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT([$do64bit])

    # Step 0.b: Enable Solaris 64 bit VIS support?

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AC_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])
    # Force 64bit on with VIS
    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
	tcl_cv_cc_visibility_hidden, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	AC_TRY_LINK([
	    extern __attribute__((__visibility__("hidden"))) void f(void);

	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	CFLAGS=$hold_cflags])
    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	AC_DEFINE(MODULE_SCOPE,
	    [extern __attribute__((__visibility__("hidden")))],
	    [Compiler support for module scope symbols])
	AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
    ])

    # Step 0.d: Disable -rpath support?

    AC_MSG_CHECKING([if rpath support is requested])
    AC_ARG_ENABLE(rpath,
	AC_HELP_STRING([--disable-rpath],
	    [disable rpath support (default: on)]),
	[doRpath=$enableval], [doRpath=yes])
    AC_MSG_RESULT([$doRpath])

    # Step 1: set the variable "system" to hold the name and version number
    # for the system.








|








|












|

>
|
|












|







881
882
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,
	AS_HELP_STRING([--enable-64bit],
	    [enable 64bit support (default: off)]),
	[do64bit=$enableval], [do64bit=no])
    AC_MSG_RESULT([$do64bit])

    # Step 0.b: Enable Solaris 64 bit VIS support?

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AS_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])
    # Force 64bit on with VIS
    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
	tcl_cv_cc_visibility_hidden, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
	    extern __attribute__((__visibility__("hidden"))) void f(void);
	    void f(void) {}]], [[f();]])],
	    [tcl_cv_cc_visibility_hidden=yes],
	    [tcl_cv_cc_visibility_hidden=no])
	CFLAGS=$hold_cflags])
    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	AC_DEFINE(MODULE_SCOPE,
	    [extern __attribute__((__visibility__("hidden")))],
	    [Compiler support for module scope symbols])
	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,
	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.

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
    AS_IF([test "$GCC" = yes], [
	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac

    ], [
	CFLAGS_OPTIMIZE=-O
	CFLAGS_WARNING=""
    ])







|







961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
    AS_IF([test "$GCC" = yes], [
	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	case "${CC}" in
	    *++|*++-*)
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -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
1115
1116
1117
1118
1119
1120
1121
1122
1123
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*)
	    SHLIB_CFLAGS="-fno-common"
	    SHLIB_LD='${CC} -shared'
	    SHLIB_SUFFIX=".dll"
	    DL_OBJS="tclLoadDl.o"
	    PLAT_OBJS='${CYGWIN_OBJS}'
	    PLAT_SRCS='${CYGWIN_SRCS}'
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    TCL_NEEDS_EXP_FILE=1
	    TCL_EXPORT_FILE_SUFFIX='${VERSION}.dll.a'
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a"
	    AC_CACHE_CHECK(for Cygwin version of gcc,
		ac_cv_cygwin,
		AC_TRY_COMPILE([
		#ifdef __CYGWIN__
		    #error cygwin
		#endif
		], [],
		ac_cv_cygwin=no,
		ac_cv_cygwin=yes)
	    )
	    if test "$ac_cv_cygwin" = "no"; then
		AC_MSG_ERROR([${CC} is not a cygwin compiler.])
	    fi
	    do64bit_ok=yes
	    if test "x${SHARED_BUILD}" = "x1"; then
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
		# The eval makes quoting arguments work.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
		then :
		else
		    { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
		fi
	    fi
	    ;;
	dgux*)







|









<
<
<


|



|
|
|






|

|







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
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*|MINGW32_*|MSYS_*)
	    SHLIB_CFLAGS="-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=""



	    AC_CACHE_CHECK(for Cygwin version of gcc,
		ac_cv_cygwin,
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#ifdef __CYGWIN__
		    #error cygwin
		#endif
		]], [[]])],
		[ac_cv_cygwin=no],
		[ac_cv_cygwin=yes])
	    )
	    if test "$ac_cv_cygwin" = "no"; then
		AC_MSG_ERROR([${CC} is not a cygwin compiler.])
	    fi
	    do64bit_ok=yes
	    if test "x${SHARED_BUILD}" = "x1"; then
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32"
		# The eval makes quoting arguments work.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32; cd ../unix
		then :
		else
		    { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
		fi
	    fi
	    ;;
	dgux*)
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
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	        ])
	    ])
	    ;;
	Linux*|GNU*|NetBSD-Debian)
	    SHLIB_CFLAGS="-fPIC -fno-common"
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"










	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
	    AS_IF([test $do64bit = yes], [
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"

		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
		    CFLAGS=$hold_cflags])
		AS_IF([test $tcl_cv_cc_m64 = yes], [
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes
		])
	   ])








|













>
>
>
>
>
>
>
>
>
>








>
|







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
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	        ])
	    ])
	    ;;
	Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*)
	    SHLIB_CFLAGS="-fPIC -fno-common"
	    SHLIB_SUFFIX=".so"

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"

	    case $system in
	    DragonFly-*|FreeBSD-*)
		# The -pthread needs to go in the LDFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
	    ;;
	    esac

	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
	    AS_IF([test $do64bit = yes], [
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
			    [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
		])
	   ])

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
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    # The -pthread needs to go in the LDFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
	    LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
	    case $system in
	    FreeBSD-3.*)
		# Version numbers are dot-stripped by system policy.
		TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
		TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	Darwin-*)
	    CFLAGS_OPTIMIZE="-Os"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
	    # preprocessing tests and compiling tests, move any -isysroot and
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
	    AS_IF([test $do64bit = yes], [
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
				    tcl_cv_cc_arch_ppc64=no)
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			]);;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
				    tcl_cv_cc_arch_x86_64=no)
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			]);;












		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"

		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_single_module = yes], [
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
	    ])
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
		    tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"

		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
			tcl_cv_ld_search_paths_first=no)
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
	    ])
	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
		    [Compiler support for module scope symbols])
		tcl_cv_cc_visibility_hidden=yes
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
	    AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?])
	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    AC_MSG_CHECKING([whether to use CoreFoundation])
	    AC_ARG_ENABLE(corefoundation,
		AC_HELP_STRING([--enable-corefoundation],
		    [use CoreFoundation API on MacOSX (default: on)]),
		[tcl_corefoundation=$enableval], [tcl_corefoundation=yes])
	    AC_MSG_RESULT([$tcl_corefoundation])
	    AS_IF([test $tcl_corefoundation = yes], [
		AC_CACHE_CHECK([for CoreFoundation.framework],
			tcl_cv_lib_corefoundation, [
		    hold_libs=$LIBS
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    # On Tiger there is no 64-bit CF, so remove 64-bit
			    # archs from CFLAGS et al. while testing for
			    # presence of CF. 64-bit CF is disabled in
			    # tclUnixPort.h if necessary.
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
			done])
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>],
			[CFBundleRef b = CFBundleGetMainBundle();],
			tcl_cv_lib_corefoundation=yes,
			tcl_cv_lib_corefoundation=no)
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
		        done])
		    LIBS=$hold_libs])
		AS_IF([test $tcl_cv_lib_corefoundation = yes], [
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_DEFINE(HAVE_COREFOUNDATION, 1,
			[Do we have access to Darwin CoreFoundation.framework?])
		], [tcl_corefoundation=no])
		AS_IF([test "$fat_32_64" = yes -a $tcl_corefoundation = yes],[
		    AC_CACHE_CHECK([for 64-bit CoreFoundation],
			    tcl_cv_lib_corefoundation_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			AC_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>],
			    [CFBundleRef b = CFBundleGetMainBundle();],
			    tcl_cv_lib_corefoundation_64=yes,
			    tcl_cv_lib_corefoundation_64=no)
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		    AS_IF([test $tcl_cv_lib_corefoundation_64 = no], [
			AC_DEFINE(NO_COREFOUNDATION_64, 1,
			    [Is Darwin CoreFoundation unavailable for 64-bit?])
                        LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|

















|
|





|




|
|





>
>
>
>
>
>
>
>
>
>
>
>





|







>
|












>
|
|











|





|
















|
|
|
|
















|
|
|
|







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
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    # The -pthread needs to go in the CFLAGS, not LIBS
	    LIBS=`echo $LIBS | sed s/-pthread//`
	    CFLAGS="$CFLAGS -pthread"
	    LDFLAGS="$LDFLAGS -pthread"
	    ;;
























	Darwin-*)
	    CFLAGS_OPTIMIZE="-O2"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
	    # preprocessing tests and compiling tests, move any -isysroot and
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
	    AS_IF([test $do64bit = yes], [
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
				    [tcl_cv_cc_arch_ppc64=yes],[tcl_cv_cc_arch_ppc64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			]);;
		    i386|x86_64)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
				    [tcl_cv_cc_arch_x86_64=yes],[tcl_cv_cc_arch_x86_64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			]);;
		    arm64)
			AC_CACHE_CHECK([if compiler accepts -arch arm64 flag],
				tcl_cv_cc_arch_arm64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch arm64"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
				    [tcl_cv_cc_arch_arm64=yes],[tcl_cv_cc_arch_arm64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_arm64 = yes], [
			    CFLAGS="$CFLAGS -arch arm64"
			    do64bit_ok=yes
			]);;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_single_module=yes],
		    [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;]])],
			[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_FALLBACK_LIBRARY_PATH"
	    AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?])
	    PLAT_OBJS='${MAC_OSX_OBJS}'
	    PLAT_SRCS='${MAC_OSX_SRCS}'
	    AC_MSG_CHECKING([whether to use CoreFoundation])
	    AC_ARG_ENABLE(corefoundation,
		AS_HELP_STRING([--enable-corefoundation],
		    [use CoreFoundation API on MacOSX (default: on)]),
		[tcl_corefoundation=$enableval], [tcl_corefoundation=yes])
	    AC_MSG_RESULT([$tcl_corefoundation])
	    AS_IF([test $tcl_corefoundation = yes], [
		AC_CACHE_CHECK([for CoreFoundation.framework],
			tcl_cv_lib_corefoundation, [
		    hold_libs=$LIBS
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    # On Tiger there is no 64-bit CF, so remove 64-bit
			    # archs from CFLAGS et al. while testing for
			    # presence of CF. 64-bit CF is disabled in
			    # tclUnixPort.h if necessary.
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
			done])
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <CoreFoundation/CoreFoundation.h>]],
			[[CFBundleRef b = CFBundleGetMainBundle();]])],
			[tcl_cv_lib_corefoundation=yes],
			[tcl_cv_lib_corefoundation=no])
		    AS_IF([test "$fat_32_64" = yes], [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
		        done])
		    LIBS=$hold_libs])
		AS_IF([test $tcl_cv_lib_corefoundation = yes], [
		    LIBS="$LIBS -framework CoreFoundation"
		    AC_DEFINE(HAVE_COREFOUNDATION, 1,
			[Do we have access to Darwin CoreFoundation.framework?])
		], [tcl_corefoundation=no])
		AS_IF([test "$fat_32_64" = yes -a $tcl_corefoundation = yes],[
		    AC_CACHE_CHECK([for 64-bit CoreFoundation],
			    tcl_cv_lib_corefoundation_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <CoreFoundation/CoreFoundation.h>]],
			    [[CFBundleRef b = CFBundleGetMainBundle();]])],
			    [tcl_cv_lib_corefoundation_64=yes],
			    [tcl_cv_lib_corefoundation_64=no])
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		    AS_IF([test $tcl_cv_lib_corefoundation_64 = no], [
			AC_DEFINE(NO_COREFOUNDATION_64, 1,
			    [Is Darwin CoreFoundation unavailable for 64-bit?])
                        LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])
	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    AS_IF([test "$SHARED_BUILD" = 1], [
	        SHLIB_LD='ld -shared -expect_unresolved "*"'
	    ], [
	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
	    ])
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])







|

|







1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])
	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    AS_IF([test "$SHARED_BUILD" = 1], [
	        SHLIB_LD='${CC} -shared'
	    ], [
	        SHLIB_LD='${CC} -non_shared'
	    ])
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
	        LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;







|







1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no])
	        LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Step 4: disable dynamic loading if requested via a command-line switch.

    AC_ARG_ENABLE(load,
	AC_HELP_STRING([--enable-load],
	    [allow dynamic loading and "load" command (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])
    AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])

    AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
	AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
	SHLIB_CFLAGS=""







|







1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Step 4: disable dynamic loading if requested via a command-line switch.

    AC_ARG_ENABLE(load,
	AS_HELP_STRING([--enable-load],
	    [allow dynamic loading and "load" command (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])
    AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])

    AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
	AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
	SHLIB_CFLAGS=""
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*) ;;
	    HP_UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    OSF1-V*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
	    [No Compiler support for module scope symbols])
    ])

    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'])
    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${LDFLAGS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)";if test -f $(LIB_FILE).a; then $(INSTALL_DATA) $(LIB_FILE).a "$(LIB_INSTALL_DIR)"; fi;'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
        ], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}








|
|




|



















|







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
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*|MSYS_*) ;;
	    HP-UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    OSF1-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
	    [No Compiler support for module scope symbols])
    ])

    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'])
    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"

    AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [
        LIB_SUFFIX=${SHARED_LIB_SUFFIX}
        MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${LDFLAGS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
        AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"'
            DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
        ], [
            INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
        ])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}

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
    # Define TCL_LIBS now that we know what DL_LIBS is.
    # The trick here is that we don't want to change the value of TCL_LIBS if
    # it is already set when tclConfig.sh had been loaded by Tk.
    AS_IF([test "x${TCL_LIBS}" = x], [
        TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"])
    AC_SUBST(TCL_LIBS)

	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_TRY_COMPILE([],
	    [
		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ],
	    tcl_cv_cast_to_union=yes,
	    tcl_cv_cast_to_union=no)
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi






















    AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)




    # FIXME: This subst was left in only because the TCL_DL_LIBS
    # entry in tclConfig.sh uses it. It is not clear why someone
    # would use TCL_DL_LIBS instead of TCL_LIBS.
    AC_SUBST(DL_LIBS)

    AC_SUBST(DL_OBJS)
    AC_SUBST(PLAT_OBJS)
    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(LDFLAGS)
    AC_SUBST(LDFLAGS_DEBUG)
    AC_SUBST(LDFLAGS_OPTIMIZE)
    AC_SUBST(CC_SEARCH_FLAGS)
    AC_SUBST(LD_SEARCH_FLAGS)








|
|
|

|
|
|
<
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>













>







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
    # Define TCL_LIBS now that we know what DL_LIBS is.
    # The trick here is that we don't want to change the value of TCL_LIBS if
    # it is already set when tclConfig.sh had been loaded by Tk.
    AS_IF([test "x${TCL_LIBS}" = x], [
        TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"])
    AC_SUBST(TCL_LIBS)

    # See if the compiler supports casting to a union type.
    # This is used to stop gcc from printing a compiler
    # warning when initializing a union member.

    AC_CACHE_CHECK(for cast to union support,
	tcl_cv_cast_to_union,
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[

		union foo { int i; double d; };
		union foo f = (union foo) (int) 0;
	]])],
	[tcl_cv_cast_to_union=yes],
	[tcl_cv_cast_to_union=no])
    )
    if test "$tcl_cv_cast_to_union" = "yes"; then
	AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		[Defined when compiler supports casting to union type.])
    fi
    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_CACHE_CHECK([if the compiler understands -finput-charset],
	tcl_cv_cc_input_charset, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8"
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_input_charset=yes],[tcl_cv_cc_input_charset=no])
	CFLAGS=$hold_cflags])
    if test $tcl_cv_cc_input_charset = yes; then
	CFLAGS="$CFLAGS -finput-charset=UTF-8"
    fi

    AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)

    # Check for vfork, posix_spawnp() and friends unconditionally
    AC_CHECK_FUNCS(vfork posix_spawnp posix_spawn_file_actions_adddup2 posix_spawnattr_setflags)

    # 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)

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
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:
#		NO_DIRENT_H
#		NO_STDLIB_H
#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
    AC_TRY_LINK([#include <sys/types.h>
#include <dirent.h>], [
#ifndef _POSIX_SOURCE
#   ifdef __Lynx__
	/*
	 * Generate compilation error to make the test fail:  Lynx headers
	 * are only valid if really in the POSIX environment.
	 */

	missing_procedure();
#   endif
#endif
DIR *d;
struct dirent *entryPtr;
char *p;
d = opendir("foobar");
entryPtr = readdir(d);
p = entryPtr->d_name;
closedir(d);
], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])

    if test $tcl_cv_dirent_h = no; then
	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
    fi

    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
    fi
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_HAVE_HEADERS(sys/param.h)
])

#--------------------------------------------------------------------
# SC_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff







<
<









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















|







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
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:


#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
































    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_CHECK_HEADERS([sys/param.h])
])

#--------------------------------------------------------------------
# SC_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
#--------------------------------------------------------------------

AC_DEFUN([SC_PATH_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
	else
	    if test ! -r $x_includes/X11/Xlib.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Xlib.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"







|









|







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
#--------------------------------------------------------------------

AC_DEFUN([SC_PATH_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <X11/Xlib.h>]])],[],[not_really_there="yes"])
	else
	    if test ! -r $x_includes/X11/Xlib.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <X11/Xlib.h>]])],[found_xincludes="yes"],[found_xincludes="no"])
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Xlib.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"
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
#		HAVE_TM_TZADJ
#		HAVE_TIMEZONE_VAR
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME

    AC_CHECK_FUNCS(gmtime_r localtime_r mktime)

    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
	    tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])

    if test $tcl_cv_member_tm_tzadj = yes ; then
	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
    fi

    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; (void)tm.tm_gmtoff;],
	    tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])

    if test $tcl_cv_member_tm_gmtoff = yes ; then
	AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
    fi

    #
    # Its important to include time.h in this check, as some systems
    # (like convex) have timezone functions, etc.
    #
    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
	AC_TRY_COMPILE([#include <time.h>],

	    [extern long timezone;
	    timezone += 1;
	    exit (0);],
	    tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
    if test $tcl_cv_timezone_long = yes ; then
	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
    else
	#
	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
	#
	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
	    AC_TRY_COMPILE([#include <time.h>],

		[extern time_t timezone;
		timezone += 1;
		exit (0);],
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.

#	-lnsl) or thread library (-lpthread) are dealt with here.
#
# Arguments:
#	None.
#
# Results:
#
#	Sets the following vars:







|




|
|
>





|
|
>









|
>
|

|
|







|
>
|

|
|










|
>
|







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
#		HAVE_TM_TZADJ
#		HAVE_TIMEZONE_VAR
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    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_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_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_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
#include <stdlib.h>]],
	[[extern long timezone;
	    timezone += 1;
	    exit (0);]])],
	    [tcl_cv_timezone_long=yes], [tcl_cv_timezone_long=no])])
    if test $tcl_cv_timezone_long = yes ; then
	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
    else
	#
	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
	#
	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
#include <stdlib.h>]],
	    [[extern time_t timezone;
		timezone += 1;
		exit (0);]])],
		[tcl_cv_timezone_time=yes], [tcl_cv_timezone_time=no])])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm), 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:
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
# Arguments:
#	None
#
# Results:
#
#	Might define the following vars:
#		_ISOC99_SOURCE
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),

	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    AC_TRY_COMPILE([[#define ]$1[ 1
]$2], $3,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
	AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[
    AC_MSG_CHECKING([for required early compiler flags])
    tcl_flags=""
    SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
	[char *p = (char *)strtoll; char *q = (char *)strtoull;])


    SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
	[struct stat64 buf; int i = stat64("/", &buf);])
    SC_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
	[char *p = (char *)open64;])
    if test "x${tcl_flags}" = "x" ; then
	AC_MSG_RESULT([none])
    else
	AC_MSG_RESULT([${tcl_flags}])
    fi
])

#--------------------------------------------------------------------
# SC_TCL_64BIT_FLAGS
#
#	Check for what is defined in the way of 64-bit features.
#
# 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})])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Do 'long' and 'long long' have the same size (64-bit)?])
	AC_MSG_RESULT([yes])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations

















	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);],
		tcl_cv_DIR64=yes,tcl_cv_DIR64=no)])
	if test "x${tcl_cv_DIR64}" = "xyes" ; then
	    AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
	fi

	AC_CHECK_FUNCS(open64 lseek64)
	AC_MSG_CHECKING([for off64_t])
	AC_CACHE_VAL(tcl_cv_type_off64_t,[
	    AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
],
		tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
	dnl functions lseek64 and open64 are defined.
	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
	        test "x${ac_cv_func_lseek64}" = "xyes" && \
	        test "x${ac_cv_func_open64}" = "xyes" ; then
	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
	    AC_MSG_RESULT([yes])







|
|





>
|
<
|
|
|

|









>
>


<
<



















<

<

>




|


<
<
<



|
|
|




<
<
|
<

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
|





|
|
|
|




<
<
<
<
<
<
<
<



|
|
|







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
# Arguments:
#	None
#
# Results:
#
#	Might define the following vars:
#		_ISOC99_SOURCE
#		_FILE_OFFSET_BITS
#		_LARGEFILE64_SOURCE
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])],
	    [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[

]$2]], [[$3]])],
	[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
	[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)]))
    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
	AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[
    AC_MSG_CHECKING([for required early compiler flags])
    tcl_flags=""
    SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
	[char *p = (char *)strtoll; char *q = (char *)strtoull;])
    SC_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include <sys/stat.h>],
	[switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64)
    SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
	[struct stat64 buf; int i = stat64("/", &buf);])


    if test "x${tcl_flags}" = "x" ; then
	AC_MSG_RESULT([none])
    else
	AC_MSG_RESULT([${tcl_flags}])
    fi
])

#--------------------------------------------------------------------
# SC_TCL_64BIT_FLAGS
#
#	Check for what is defined in the way of 64-bit features.
#
# Arguments:
#	None
#
# Results:
#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG

#		HAVE_STRUCT_DIRENT64, HAVE_DIR64

#		HAVE_TYPE_OFF64_T
#		_TIME_BITS
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([if 'long' and 'long long' have the same size (64-bit)?])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none



	# 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_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_MSG_RESULT([no])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for 64-bit time_t], tcl_cv_time_t_64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]],
		[[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
		[tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])])
	if test "x${tcl_cv_time_t_64}" = "xno" ; then
	    # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64
	    # which SC_TCL_EARLY_FLAGS has defined if necessary.
	    AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64
#include <sys/types.h>]],
		    [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
		    [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])])
	    if test "x${tcl_cv__time_bits}" = "xyes" ; then
		AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.])
	    fi
	fi

	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <dirent.h>]], [[struct dirent64 p;]])],
		[tcl_cv_struct_dirent64=yes],[tcl_cv_struct_dirent64=no])])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <dirent.h>]], [[struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);]])],
		[tcl_cv_DIR64=yes], [tcl_cv_DIR64=no])])
	if test "x${tcl_cv_DIR64}" = "xyes" ; then
	    AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
	fi









	AC_CHECK_FUNCS(open64 lseek64)
	AC_MSG_CHECKING([for off64_t])
	AC_CACHE_VAL(tcl_cv_type_off64_t,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]], [[off64_t offset;
]])],
		[tcl_cv_type_off64_t=yes], [tcl_cv_type_off64_t=no])])
	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
	dnl functions lseek64 and open64 are defined.
	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
	        test "x${ac_cv_func_lseek64}" = "xyes" && \
	        test "x${ac_cv_func_open64}" = "xyes" ; then
	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
	    AC_MSG_RESULT([yes])
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AC_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: iso8859-1)]),
	with_tcencoding=${withval})

    if test x"${with_tcencoding}" != x ; then
	AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}",
	    [What encoding should be used for embedded configuration info?])
    else
	AC_DEFINE(TCL_CFGVAL_ENCODING,"iso8859-1",
	    [What encoding should be used for embedded configuration info?])
    fi
])

#--------------------------------------------------------------------
# SC_TCL_CHECK_BROKEN_FUNC
#







|
|
|





|







2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AS_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: 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,"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
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],
	    AC_TRY_RUN([[
#include <stdlib.h>
#include <string.h>
int main() {]$2[}]],[tcl_cv_]$1[_unbroken]=ok,
		[tcl_cv_]$1[_unbroken]=broken,[tcl_cv_]$1[_unbroken]=unknown))
	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi
    if test ["$tcl_ok"] = 0; then







|


|
|







2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],
	    AC_RUN_IFELSE([AC_LANG_SOURCE([[[
#include <stdlib.h>
#include <string.h>
int main() {]$2[}]]])],[tcl_cv_$1_unbroken=ok],
		[tcl_cv_$1_unbroken=broken],[tcl_cv_$1_unbroken=unknown]))
	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi
    if test ["$tcl_ok"] = 0; then
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_DECL], [AC_CHECK_DECLS(gethostbyaddr_r, [
    tcl_cv_api_gethostbyaddr_r=yes],[tcl_cv_api_gethostbyaddr_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_TYPE], [AC_CHECK_FUNC(gethostbyaddr_r, [
    AC_CACHE_CHECK([for gethostbyaddr_r with 7 args], tcl_cv_api_gethostbyaddr_r_7, [
    AC_TRY_COMPILE([
	#include <netdb.h>
    ], [
	char *addr;
	int length;
	int type;
	struct hostent *result;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
			       &h_errnop);
    ], tcl_cv_api_gethostbyaddr_r_7=yes, tcl_cv_api_gethostbyaddr_r_7=no)])
    tcl_ok=$tcl_cv_api_gethostbyaddr_r_7
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYADDR_R_7, 1,
	    [Define to 1 if gethostbyaddr_r takes 7 args.])
    else
	AC_CACHE_CHECK([for gethostbyaddr_r with 8 args], tcl_cv_api_gethostbyaddr_r_8, [
	AC_TRY_COMPILE([
	    #include <netdb.h>
	], [
	    char *addr;
	    int length;
	    int type;
	    struct hostent *result, *resultp;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
				   &resultp, &h_errnop);
	], tcl_cv_api_gethostbyaddr_r_8=yes, tcl_cv_api_gethostbyaddr_r_8=no)])
	tcl_ok=$tcl_cv_api_gethostbyaddr_r_8
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYADDR_R_8, 1,
		[Define to 1 if gethostbyaddr_r takes 8 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|

|










|






|

|










|







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

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_DECL], [AC_CHECK_DECLS(gethostbyaddr_r, [
    tcl_cv_api_gethostbyaddr_r=yes],[tcl_cv_api_gethostbyaddr_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_TYPE], [AC_CHECK_FUNC(gethostbyaddr_r, [
    AC_CACHE_CHECK([for gethostbyaddr_r with 7 args], tcl_cv_api_gethostbyaddr_r_7, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <netdb.h>
    ]], [[
	char *addr;
	int length;
	int type;
	struct hostent *result;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
			       &h_errnop);
    ]])],[tcl_cv_api_gethostbyaddr_r_7=yes],[tcl_cv_api_gethostbyaddr_r_7=no])])
    tcl_ok=$tcl_cv_api_gethostbyaddr_r_7
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYADDR_R_7, 1,
	    [Define to 1 if gethostbyaddr_r takes 7 args.])
    else
	AC_CACHE_CHECK([for gethostbyaddr_r with 8 args], tcl_cv_api_gethostbyaddr_r_8, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <netdb.h>
	]], [[
	    char *addr;
	    int length;
	    int type;
	    struct hostent *result, *resultp;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen,
				   &resultp, &h_errnop);
	]])],[tcl_cv_api_gethostbyaddr_r_8=yes],[tcl_cv_api_gethostbyaddr_r_8=no])])
	tcl_ok=$tcl_cv_api_gethostbyaddr_r_8
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYADDR_R_8, 1,
		[Define to 1 if gethostbyaddr_r takes 8 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_DECL], [AC_CHECK_DECLS(gethostbyname_r, [
    tcl_cv_api_gethostbyname_r=yes],[tcl_cv_api_gethostbyname_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_TYPE], [AC_CHECK_FUNC(gethostbyname_r, [
    AC_CACHE_CHECK([for gethostbyname_r with 6 args], tcl_cv_api_gethostbyname_r_6, [
    AC_TRY_COMPILE([
	#include <netdb.h>
    ], [
	char *name;
	struct hostent *he, *res;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop);
    ], tcl_cv_api_gethostbyname_r_6=yes, tcl_cv_api_gethostbyname_r_6=no)])
    tcl_ok=$tcl_cv_api_gethostbyname_r_6
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R_6, 1,
	    [Define to 1 if gethostbyname_r takes 6 args.])
    else
	AC_CACHE_CHECK([for gethostbyname_r with 5 args], tcl_cv_api_gethostbyname_r_5, [
	AC_TRY_COMPILE([
	    #include <netdb.h>
	], [
	    char *name;
	    struct hostent *he;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop);
	], tcl_cv_api_gethostbyname_r_5=yes, tcl_cv_api_gethostbyname_r_5=no)])
	tcl_ok=$tcl_cv_api_gethostbyname_r_5
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_5, 1,
		[Define to 1 if gethostbyname_r takes 5 args.])
	else
	    AC_CACHE_CHECK([for gethostbyname_r with 3 args], tcl_cv_api_gethostbyname_r_3, [
	    AC_TRY_COMPILE([
		#include <netdb.h>
	    ], [
		char *name;
		struct hostent *he;
		struct hostent_data data;

		(void) gethostbyname_r(name, he, &data);
	    ], tcl_cv_api_gethostbyname_r_3=yes, tcl_cv_api_gethostbyname_r_3=no)])
	    tcl_ok=$tcl_cv_api_gethostbyname_r_3
	    if test "$tcl_ok" = yes; then
		AC_DEFINE(HAVE_GETHOSTBYNAME_R_3, 1,
		    [Define to 1 if gethostbyname_r takes 3 args.])
	    fi
	fi
    fi







|

|







|






|

|







|






|

|





|







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

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_DECL], [AC_CHECK_DECLS(gethostbyname_r, [
    tcl_cv_api_gethostbyname_r=yes],[tcl_cv_api_gethostbyname_r=no],[#include <netdb.h>])
])

AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_TYPE], [AC_CHECK_FUNC(gethostbyname_r, [
    AC_CACHE_CHECK([for gethostbyname_r with 6 args], tcl_cv_api_gethostbyname_r_6, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <netdb.h>
    ]], [[
	char *name;
	struct hostent *he, *res;
	char buffer[2048];
	int buflen = 2048;
	int h_errnop;

	(void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop);
    ]])],[tcl_cv_api_gethostbyname_r_6=yes],[tcl_cv_api_gethostbyname_r_6=no])])
    tcl_ok=$tcl_cv_api_gethostbyname_r_6
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETHOSTBYNAME_R_6, 1,
	    [Define to 1 if gethostbyname_r takes 6 args.])
    else
	AC_CACHE_CHECK([for gethostbyname_r with 5 args], tcl_cv_api_gethostbyname_r_5, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <netdb.h>
	]], [[
	    char *name;
	    struct hostent *he;
	    char buffer[2048];
	    int buflen = 2048;
	    int h_errnop;

	    (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop);
	]])],[tcl_cv_api_gethostbyname_r_5=yes],[tcl_cv_api_gethostbyname_r_5=no])])
	tcl_ok=$tcl_cv_api_gethostbyname_r_5
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETHOSTBYNAME_R_5, 1,
		[Define to 1 if gethostbyname_r takes 5 args.])
	else
	    AC_CACHE_CHECK([for gethostbyname_r with 3 args], tcl_cv_api_gethostbyname_r_3, [
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#include <netdb.h>
	    ]], [[
		char *name;
		struct hostent *he;
		struct hostent_data data;

		(void) gethostbyname_r(name, he, &data);
	    ]])],[tcl_cv_api_gethostbyname_r_3=yes],[tcl_cv_api_gethostbyname_r_3=no])])
	    tcl_ok=$tcl_cv_api_gethostbyname_r_3
	    if test "$tcl_ok" = yes; then
		AC_DEFINE(HAVE_GETHOSTBYNAME_R_3, 1,
		    [Define to 1 if gethostbyname_r takes 3 args.])
	    fi
	fi
    fi
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
#		HAVE_GETPWUID_R_4
#		HAVE_GETPWUID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWUID_R], [AC_CHECK_FUNC(getpwuid_r, [
    AC_CACHE_CHECK([for getpwuid_r with 5 args], tcl_cv_api_getpwuid_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <pwd.h>
    ], [
	uid_t uid;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwuid_r(uid, &pw, buf, buflen, &pwp);
    ], tcl_cv_api_getpwuid_r_5=yes, tcl_cv_api_getpwuid_r_5=no)])
    tcl_ok=$tcl_cv_api_getpwuid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWUID_R_5, 1,
	    [Define to 1 if getpwuid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwuid_r with 4 args], tcl_cv_api_getpwuid_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <pwd.h>
	], [
	    uid_t uid;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(uid, &pw, buf, buflen);
	], tcl_cv_api_getpwuid_r_4=yes, tcl_cv_api_getpwuid_r_4=no)])
	tcl_ok=$tcl_cv_api_getpwuid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWUID_R_4, 1,
		[Define to 1 if getpwuid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







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
#		HAVE_GETPWUID_R_4
#		HAVE_GETPWUID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWUID_R], [AC_CHECK_FUNC(getpwuid_r, [
    AC_CACHE_CHECK([for getpwuid_r with 5 args], tcl_cv_api_getpwuid_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <pwd.h>
    ]], [[
	uid_t uid;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwuid_r(uid, &pw, buf, buflen, &pwp);
    ]])],[tcl_cv_api_getpwuid_r_5=yes],[tcl_cv_api_getpwuid_r_5=no])])
    tcl_ok=$tcl_cv_api_getpwuid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWUID_R_5, 1,
	    [Define to 1 if getpwuid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwuid_r with 4 args], tcl_cv_api_getpwuid_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <pwd.h>
	]], [[
	    uid_t uid;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(uid, &pw, buf, buflen);
	]])],[tcl_cv_api_getpwuid_r_4=yes],[tcl_cv_api_getpwuid_r_4=no])])
	tcl_ok=$tcl_cv_api_getpwuid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWUID_R_4, 1,
		[Define to 1 if getpwuid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
#		HAVE_GETPWNAM_R_4
#		HAVE_GETPWNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWNAM_R], [AC_CHECK_FUNC(getpwnam_r, [
    AC_CACHE_CHECK([for getpwnam_r with 5 args], tcl_cv_api_getpwnam_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <pwd.h>
    ], [
	char *name;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwnam_r(name, &pw, buf, buflen, &pwp);
    ], tcl_cv_api_getpwnam_r_5=yes, tcl_cv_api_getpwnam_r_5=no)])
    tcl_ok=$tcl_cv_api_getpwnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWNAM_R_5, 1,
	    [Define to 1 if getpwnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwnam_r with 4 args], tcl_cv_api_getpwnam_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <pwd.h>
	], [
	    char *name;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(name, &pw, buf, buflen);
	], tcl_cv_api_getpwnam_r_4=yes, tcl_cv_api_getpwnam_r_4=no)])
	tcl_ok=$tcl_cv_api_getpwnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWNAM_R_4, 1,
		[Define to 1 if getpwnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







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
#		HAVE_GETPWNAM_R_4
#		HAVE_GETPWNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETPWNAM_R], [AC_CHECK_FUNC(getpwnam_r, [
    AC_CACHE_CHECK([for getpwnam_r with 5 args], tcl_cv_api_getpwnam_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <pwd.h>
    ]], [[
	char *name;
	struct passwd pw, *pwp;
	char buf[512];
	int buflen = 512;

	(void) getpwnam_r(name, &pw, buf, buflen, &pwp);
    ]])],[tcl_cv_api_getpwnam_r_5=yes],[tcl_cv_api_getpwnam_r_5=no])])
    tcl_ok=$tcl_cv_api_getpwnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETPWNAM_R_5, 1,
	    [Define to 1 if getpwnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getpwnam_r with 4 args], tcl_cv_api_getpwnam_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <pwd.h>
	]], [[
	    char *name;
	    struct passwd pw;
	    char buf[512];
	    int buflen = 512;

	    (void)getpwnam_r(name, &pw, buf, buflen);
	]])],[tcl_cv_api_getpwnam_r_4=yes],[tcl_cv_api_getpwnam_r_4=no])])
	tcl_ok=$tcl_cv_api_getpwnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETPWNAM_R_4, 1,
		[Define to 1 if getpwnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
#		HAVE_GETGRGID_R_4
#		HAVE_GETGRGID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRGID_R], [AC_CHECK_FUNC(getgrgid_r, [
    AC_CACHE_CHECK([for getgrgid_r with 5 args], tcl_cv_api_getgrgid_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <grp.h>
    ], [
	gid_t gid;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrgid_r(gid, &gr, buf, buflen, &grp);
    ], tcl_cv_api_getgrgid_r_5=yes, tcl_cv_api_getgrgid_r_5=no)])
    tcl_ok=$tcl_cv_api_getgrgid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRGID_R_5, 1,
	    [Define to 1 if getgrgid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrgid_r with 4 args], tcl_cv_api_getgrgid_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <grp.h>
	], [
	    gid_t gid;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrgid_r(gid, &gr, buf, buflen);
	], tcl_cv_api_getgrgid_r_4=yes, tcl_cv_api_getgrgid_r_4=no)])
	tcl_ok=$tcl_cv_api_getgrgid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRGID_R_4, 1,
		[Define to 1 if getgrgid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







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
#		HAVE_GETGRGID_R_4
#		HAVE_GETGRGID_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRGID_R], [AC_CHECK_FUNC(getgrgid_r, [
    AC_CACHE_CHECK([for getgrgid_r with 5 args], tcl_cv_api_getgrgid_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <grp.h>
    ]], [[
	gid_t gid;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrgid_r(gid, &gr, buf, buflen, &grp);
    ]])],[tcl_cv_api_getgrgid_r_5=yes],[tcl_cv_api_getgrgid_r_5=no])])
    tcl_ok=$tcl_cv_api_getgrgid_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRGID_R_5, 1,
	    [Define to 1 if getgrgid_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrgid_r with 4 args], tcl_cv_api_getgrgid_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <grp.h>
	]], [[
	    gid_t gid;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrgid_r(gid, &gr, buf, buflen);
	]])],[tcl_cv_api_getgrgid_r_4=yes],[tcl_cv_api_getgrgid_r_4=no])])
	tcl_ok=$tcl_cv_api_getgrgid_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRGID_R_4, 1,
		[Define to 1 if getgrgid_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
#		HAVE_GETGRNAM_R_4
#		HAVE_GETGRNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRNAM_R], [AC_CHECK_FUNC(getgrnam_r, [
    AC_CACHE_CHECK([for getgrnam_r with 5 args], tcl_cv_api_getgrnam_r_5, [
    AC_TRY_COMPILE([
	#include <sys/types.h>
	#include <grp.h>
    ], [
	char *name;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrnam_r(name, &gr, buf, buflen, &grp);
    ], tcl_cv_api_getgrnam_r_5=yes, tcl_cv_api_getgrnam_r_5=no)])
    tcl_ok=$tcl_cv_api_getgrnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R_5, 1,
	    [Define to 1 if getgrnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrnam_r with 4 args], tcl_cv_api_getgrnam_r_4, [
	AC_TRY_COMPILE([
	    #include <sys/types.h>
	    #include <grp.h>
	], [
	    char *name;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrnam_r(name, &gr, buf, buflen);
	], tcl_cv_api_getgrnam_r_4=yes, tcl_cv_api_getgrnam_r_4=no)])
	tcl_ok=$tcl_cv_api_getgrnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRNAM_R_4, 1,
		[Define to 1 if getgrnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then







|


|






|






|


|






|







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
#		HAVE_GETGRNAM_R_4
#		HAVE_GETGRNAM_R_5
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_GETGRNAM_R], [AC_CHECK_FUNC(getgrnam_r, [
    AC_CACHE_CHECK([for getgrnam_r with 5 args], tcl_cv_api_getgrnam_r_5, [
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	#include <sys/types.h>
	#include <grp.h>
    ]], [[
	char *name;
	struct group gr, *grp;
	char buf[512];
	int buflen = 512;

	(void) getgrnam_r(name, &gr, buf, buflen, &grp);
    ]])],[tcl_cv_api_getgrnam_r_5=yes],[tcl_cv_api_getgrnam_r_5=no])])
    tcl_ok=$tcl_cv_api_getgrnam_r_5
    if test "$tcl_ok" = yes; then
	AC_DEFINE(HAVE_GETGRNAM_R_5, 1,
	    [Define to 1 if getgrnam_r takes 5 args.])
    else
	AC_CACHE_CHECK([for getgrnam_r with 4 args], tcl_cv_api_getgrnam_r_4, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #include <sys/types.h>
	    #include <grp.h>
	]], [[
	    char *name;
	    struct group gr;
	    char buf[512];
	    int buflen = 512;

	    (void)getgrnam_r(name, &gr, buf, buflen);
	]])],[tcl_cv_api_getgrnam_r_4=yes],[tcl_cv_api_getgrnam_r_4=no])])
	tcl_ok=$tcl_cv_api_getgrnam_r_4
	if test "$tcl_ok" = yes; then
	    AC_DEFINE(HAVE_GETGRNAM_R_4, 1,
		[Define to 1 if getgrnam_r takes 4 args.])
	fi
    fi
    if test "$tcl_ok" = yes; then
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
#	Locate a zip encoder installed on the system path, or none.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:

#		ZIP_PROG
#       ZIP_PROG_OPTIONS
#       ZIP_PROG_VFSSEARCH
#       ZIP_INSTALL_OBJS
#------------------------------------------------------------------------

AC_DEFUN([SC_ZIPFS_SUPPORT], [

    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    ZIP_INSTALL_OBJS=""





















    AC_MSG_CHECKING([for zip])
    AC_CACHE_VAL(ac_cv_path_zip, [
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/zip 2> /dev/null` \
            `ls -r $dir/zip 2> /dev/null` ; do
        if test x"$ac_cv_path_zip" = x ; then







>
|






>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
#	Locate a zip encoder installed on the system path, or none.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#       MACHER_PROG
#       ZIP_PROG
#       ZIP_PROG_OPTIONS
#       ZIP_PROG_VFSSEARCH
#       ZIP_INSTALL_OBJS
#------------------------------------------------------------------------

AC_DEFUN([SC_ZIPFS_SUPPORT], [
    MACHER_PROG=""
    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    ZIP_INSTALL_OBJS=""

    AC_MSG_CHECKING([for macher])
    AC_CACHE_VAL(ac_cv_path_macher, [
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/macher 2> /dev/null` \
            `ls -r $dir/macher 2> /dev/null` ; do
        if test x"$ac_cv_path_macher" = x ; then
            if test -f "$j" ; then
            ac_cv_path_macher=$j
            break
            fi
        fi
        done
    done
    ])
    if test -f "$ac_cv_path_macher" ; then
        MACHER_PROG="$ac_cv_path_macher"
        AC_MSG_RESULT([$MACHER_PROG])
        AC_MSG_RESULT([Found macher in environment])
    fi
    AC_MSG_CHECKING([for zip])
    AC_CACHE_VAL(ac_cv_path_zip, [
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/zip 2> /dev/null` \
            `ls -r $dir/zip 2> /dev/null` ; do
        if test x"$ac_cv_path_zip" = x ; then
3036
3037
3038
3039
3040
3041
3042

3043
3044
3045
3046
3047
3048
3049
3050
3051
        # We can use the locally distributed minizip instead
        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
        ZIP_PROG_OPTIONS="-o -r"
        ZIP_PROG_VFSSEARCH="*"
        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
        AC_MSG_RESULT([No zip found on PATH. Building minizip])
    fi

    AC_SUBST(ZIP_PROG)
    AC_SUBST(ZIP_PROG_OPTIONS)
    AC_SUBST(ZIP_PROG_VFSSEARCH)
    AC_SUBST(ZIP_INSTALL_OBJS)
])

# Local Variables:
# mode: autoconf
# End:







>









3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
        # We can use the locally distributed minizip instead
        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
        ZIP_PROG_OPTIONS="-o -r"
        ZIP_PROG_VFSSEARCH="*"
        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
        AC_MSG_RESULT([No zip found on PATH. Building minizip])
    fi
    AC_SUBST(MACHER_PROG)
    AC_SUBST(ZIP_PROG)
    AC_SUBST(ZIP_PROG_OPTIONS)
    AC_SUBST(ZIP_PROG_VFSSEARCH)
    AC_SUBST(ZIP_INSTALL_OBJS)
])

# Local Variables:
# mode: autoconf
# End:

Changes to unix/tk.spec.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This file is the basis for a binary Tk Linux RPM.

%{!?directory:%define directory /usr/local}

Name:          tk
Summary:       Tk graphical toolkit for the Tcl scripting language.
Version:       8.7a4
Release:       2
License:       BSD
Group:         Development/Languages
Source:        http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL:           https://www.tcl-lang.org/
Buildroot:     /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= 8.6.0
Requires:      tcl >= 8.6.0

%description
The Tcl (Tool Command Language) provides a powerful platform for
creating integration applications that tie together diverse
applications, protocols, devices, and frameworks.  When paired with
the Tk toolkit, Tcl provides the fastest and most powerful way to
create GUI applications that run on PCs, Unix, and Mac OS X.  Tcl






|






|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This file is the basis for a binary Tk Linux RPM.

%{!?directory:%define directory /usr/local}

Name:          tk
Summary:       Tk graphical toolkit for the Tcl scripting language.
Version:       9.0b2
Release:       2
License:       BSD
Group:         Development/Languages
Source:        http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL:           https://www.tcl-lang.org/
Buildroot:     /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= 8.7.0
Requires:      tcl >= 8.7.0

%description
The Tcl (Tool Command Language) provides a powerful platform for
creating integration applications that tie together diverse
applications, protocols, devices, and frameworks.  When paired with
the Tk toolkit, Tcl provides the fastest and most powerful way to
create GUI applications that run on PCs, Unix, and Mac OS X.  Tcl

Changes to unix/tkAppInit.c.

8
9
10
11
12
13
14



















15
16
17
18




19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39



40

41
42
43
44
45
46
47
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */




















#undef BUILD_tk
#undef STATIC_BUILD
#include "tk.h"
#include "tkPort.h"





#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
#ifdef __cplusplus
}
#endif
#endif /* TK_TEST */

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE



#   define MODULE_SCOPE extern

#endif
MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *);
MODULE_SCOPE int main(int, char **);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>





|















>
>
>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Explanation on following undef USE_TCL_STUBS by JN 2023-12-19 on the core list:
 * What's going on is related to TIP #596:
 *  Stubs support for Embedding Tcl in other applications
 *
 * If an application using Tcl_Main() is compiled with USE_TCL_STUBS,
 * Tcl_Main() will be replaced by a stub function, which loads
 * libtcl9.0.so/tcl90.dll and then calls its Tcl_MainEx(). If
 * libtcl9.0.so/tcl90.dll is not present (at runtime), a crash is what happens.
 *
 * So ... tkAppInit.c should not be compiled with USE_TCL_STUBS
 * (unless you want to use the TIP #596 functionality)
 *
 * The proper solution is to make sure that Makefile.in doesn't use
 * TCL_USE_STUBS when compiling tkAppInit.c. But that's a
 * quite big re-organization just before a b1 release. Simpler
 * is just to #undef'ine USE_TCL_STUBS, it has the same effect.
 */
#undef USE_TCL_STUBS
#undef BUILD_tk
#undef STATIC_BUILD
#include "tk.h"
#include "tkPort.h"
#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
#   define Tcl_LibraryInitProc Tcl_PackageInitProc
#   define Tcl_StaticLibrary Tcl_StaticPackage
#endif

#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_LibraryInitProc Tktest_Init;
#ifdef __cplusplus
}
#endif
#endif /* TK_TEST */

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#	define MODULE_SCOPE extern
#   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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);

#if defined(USE_CUSTOM_EXIT_PROC)
    if (TkpWantsExitProc()) {
	/* The cast below avoids warnings from old gcc compilers. */
	Tcl_SetExitProc((void *)TkpExitProc);
    }
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {







|



<
|







|







142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Tk", Tk_Init, Tk_SafeInit);

#if defined(USE_CUSTOM_EXIT_PROC)
    if (TkpWantsExitProc()) {

	Tcl_SetExitProc(TkpExitProc);
    }
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {

Changes to unix/tkConfig.h.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39



40
41



42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86



87
88
89
90
91
92
93
/* ../unix/tkConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TKCONFIG
    #define _TKCONFIG

/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD

/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H

/* Defined when compiler supports casting to union type. */
#undef HAVE_CAST_TO_UNION

/* Do we have access to Darwin CoreFoundation.framework? */
#undef HAVE_COREFOUNDATION

/* Is 'DIR64' in <sys/types.h>? */
#undef HAVE_DIR64

/* Compiler support for module scope symbols */
#undef HAVE_HIDDEN

/* Do we have the intptr_t type? */
#undef HAVE_INTPTR_T

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the `Xft' library (-lXft). */
#undef HAVE_LIBXFT

/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H




/* Define to 1 if you have the `open64' function. */
#undef HAVE_OPEN64




/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS

/* Do we have <stdbool.h>? */
#undef HAVE_STDBOOL_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H




/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Is 'struct dirent64' in <sys/types.h>? */
#undef HAVE_STRUCT_DIRENT64

/* Is 'struct stat64' in <sys/stat.h>? */
#undef HAVE_STRUCT_STAT64

/* Should we include <sys/select.h>? */
#undef HAVE_SYS_SELECT_H

/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Is off64_t in <sys/types.h>? */
#undef HAVE_TYPE_OFF64_T

/* Do we have the uintptr_t type? */
#undef HAVE_UINTPTR_T

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H




/* Is weak import available? */
#undef HAVE_WEAK_IMPORT

/* Have we turned on XFT (antialiased fonts)? */
#undef HAVE_XFT







<
<
<















|











|
|

>
>
>
|
|
>
>
>









>
>
>













<
<
<















|




>
>
>







1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* ../unix/tkConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TKCONFIG
    #define _TKCONFIG




/* 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

/* 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 `open64' function. */
#undef HAVE_OPEN64

/* Define to 1 if you have the `posix_spawnattr_setflags' function. */
#undef HAVE_POSIX_SPAWNATTR_SETFLAGS

/* Define to 1 if you have the `posix_spawnp' function. */
#undef HAVE_POSIX_SPAWNP

/* Define to 1 if you have the `posix_spawn_file_actions_adddup2' function. */
#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2

/* Does struct password have a pw_gecos field? */
#undef HAVE_PW_GECOS

/* Do we have <stdbool.h>? */
#undef HAVE_STDBOOL_H

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <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

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Is 'struct dirent64' in <sys/types.h>? */
#undef HAVE_STRUCT_DIRENT64




/* Should we include <sys/select.h>? */
#undef HAVE_SYS_SELECT_H

/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Is off64_t in <sys/types.h>? */
#undef HAVE_TYPE_OFF64_T

/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK

/* Is weak import available? */
#undef HAVE_WEAK_IMPORT

/* Have we turned on XFT (antialiased fonts)? */
#undef HAVE_XFT

129
130
131
132
133
134
135
136


137
138
139
140
141
142
143

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

/* Define to 1 if you have the ANSI C header files. */


#undef STDC_HEADERS

/* What encoding should be used for embedded configuration info? */
#undef TCL_CFGVAL_ENCODING

/* Is this a 64-bit build? */
#undef TCL_CFG_DO64BIT







|
>
>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

/* 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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185



186
187
188



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206



207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252

/* What is the default extension for shared libraries? */
#undef TCL_SHLIB_EXT

/* Do 'long' and 'long long' have the same size (64-bit)? */
#undef TCL_WIDE_INT_IS_LONG

/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

/* Is Tk built as a framework? */
#undef TK_FRAMEWORK

/* Are TkAqua debug messages enabled? */
#undef TK_MAC_DEBUG

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
   significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
#  define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
#  undef WORDS_BIGENDIAN
# endif
#endif




/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE




/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE

/* Add the _LARGEFILE64_SOURCE flag when building */
#undef _LARGEFILE64_SOURCE

/* Add the _LARGEFILE_SOURCE64 flag when building */
#undef _LARGEFILE_SOURCE64

/* # needed in sys/socket.h Should OS/390 do the right thing with sockets? */
#undef _OE_SOCKETS

/* Do we really want to follow the standard? Yes we do! */
#undef _POSIX_PTHREAD_SEMANTICS

/* Do we want the reentrant OS API? */
#undef _REENTRANT




/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE_EXTENDED

/* Define to 1 if type `char' is unsigned and you are not using gcc.  */

#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif

/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
#undef inline
#endif

/* Signed integer type wide enough to hold a pointer. */
#undef intptr_t

/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t

/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t

/* Unsigned integer type wide enough to hold a pointer. */
#undef uintptr_t


    /* Undef unused package specific autoheader defines so that we can
     * include both tclConfig.h and tkConfig.h at the same time: */
    /* override */ #undef PACKAGE_NAME
    /* override */ #undef PACKAGE_STRING
    /* override */ #undef PACKAGE_TARNAME

    #endif /* _TKCONFIG */







<
<
<
<
<
<

















>
>
>



>
>
>







<
<
<








>
>
>







|
>




<
<
<






<
<
<



|





<
<
<
<
<
<




|
|
>

164
165
166
167
168
169
170






171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227



228
229
230
231
232
233



234
235
236
237
238
239
240
241
242






243
244
245
246
247
248
249
250

/* What is the default extension for shared libraries? */
#undef TCL_SHLIB_EXT

/* Do 'long' and 'long long' have the same size (64-bit)? */
#undef TCL_WIDE_INT_IS_LONG







/* Is Tk built as a framework? */
#undef TK_FRAMEWORK

/* Are TkAqua debug messages enabled? */
#undef TK_MAC_DEBUG

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
   significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
#  define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
#  undef WORDS_BIGENDIAN
# endif
#endif

/* Are we building with zipfs enabled? */
#undef ZIPFS_BUILD

/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

/* Add the _FILE_OFFSET_BITS flag when building */
#undef _FILE_OFFSET_BITS

/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE

/* Add the _LARGEFILE64_SOURCE flag when building */
#undef _LARGEFILE64_SOURCE




/* # needed in sys/socket.h Should OS/390 do the right thing with sockets? */
#undef _OE_SOCKETS

/* Do we really want to follow the standard? Yes we do! */
#undef _POSIX_PTHREAD_SEMANTICS

/* Do we want the reentrant OS API? */
#undef _REENTRANT

/* _TIME_BITS=64 enables 64-bit time_t. */
#undef _TIME_BITS

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE

/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE_EXTENDED

/* Define to 1 if type `char' is unsigned and your compiler does not
   predefine this macro.  */
#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif




/* 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




/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t

/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_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_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */

Changes to unix/tkConfig.sh.in.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
TK_PATCH_LEVEL='@TK_PATCH_LEVEL@'

# -D flags for use with the C compiler.
TK_DEFS='@DEFS@'

# Flag, 1: we built a shared lib, 0 we didn't
TK_SHARED_BUILD=@TK_SHARED_BUILD@


# TK_DBGX used to be used to distinguish debug vs. non-debug builds.
# This was a righteous pain so the core doesn't do that any more.
TK_DBGX=

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'







<







18
19
20
21
22
23
24

25
26
27
28
29
30
31
TK_PATCH_LEVEL='@TK_PATCH_LEVEL@'

# -D flags for use with the C compiler.
TK_DEFS='@DEFS@'

# Flag, 1: we built a shared lib, 0 we didn't
TK_SHARED_BUILD=@TK_SHARED_BUILD@


# TK_DBGX used to be used to distinguish debug vs. non-debug builds.
# This was a righteous pain so the core doesn't do that any more.
TK_DBGX=

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'

Changes to unix/tkUnix.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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.
 *
 * 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







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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 © 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
117
118
119
120
121
122
123


























124
125
126
127
128
129
130
   * This function intentionally left blank
   */
}

/*
 *----------------------------------------------------------------------
 *


























 * TkpBuildRegionFromAlphaData --
 *
 *	Set up a rectangle of the given region based on the supplied alpha
 *	data.
 *
 * Results:
 *	None







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
   * This function intentionally left blank
   */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCopyRegion --
 *
 *	Makes the destination region a copy of the source region.
 *	Currently unused on X11.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpCopyRegion(
    TkRegion dst,
    TkRegion src)
{
    /* XUnionRegion() in Xlib is optimized to detect copying */
    XUnionRegion((Region)src, (Region)src, (Region)dst);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpBuildRegionFromAlphaData --
 *
 *	Set up a rectangle of the given region based on the supplied alpha
 *	data.
 *
 * Results:
 *	None
200
201
202
203
204
205
206

207
208



209
210
211
212
213
214
215
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(

    Display *dpy)		/* The display for which to query the inactive
				 * time. */



{
    long inactiveTime = -1;
#ifdef HAVE_XSS
    int eventBase, errorBase, major, minor;

    /*
     * Calling XScreenSaverQueryVersion seems to be needed to prevent a crash







>
|

>
>
>







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
 #ifdef HAVE_XSS
   Display *dpy)		/* The display for which to query the inactive
				 * time. */
#else
  TCL_UNUSED(Display *))
#endif /* HAVE_XSS */
{
    long inactiveTime = -1;
#ifdef HAVE_XSS
    int eventBase, errorBase, major, minor;

    /*
     * Calling XScreenSaverQueryVersion seems to be needed to prevent a crash

Changes to unix/tkUnix3d.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
/*
 * tkUnix3d.c --
 *
 *	This file contains the platform specific routines for drawing 3d
 *	borders in the Motif style.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tk3d.h"

#if !(defined(_WIN32) || defined(MAC_OSX_TK))


#include "tkUnixInt.h"
#endif

/*
 * This structure is used to keep track of the extra colors used by Unix 3D
 * borders.
 */






|








|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * tkUnix3d.c --
 *
 *	This file contains the platform specific routines for drawing 3d
 *	borders in the Motif style.
 *
 * Copyright © 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tk3d.h"

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * This structure is used to keep track of the extra colors used by Unix 3D
 * borders.
 */

Changes to unix/tkUnixButton.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkUnixButton.c --
 *
 *	This file implements the Unix specific portion of the button widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkButton.h"





|







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 © 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"
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130



































































131
132
133
134
135
136
137
138
139
140
141
142
143
144
145





















146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169





170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

258

259
260
261

262


263
264
265


266
267
268
269
270

271
272
273
274

275




276









277
278


279
280
281
282
283
284




285


286
287
288
289
290
291
292
293
294

295


296









297



298




299



300





301



302
303

304
305
306


307
308
309
310
311
312
313
314
315
/*
 * The class function table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * The button image.
 * The header info here is ignored, it's the image that's important. The
 * colors will be applied as follows:
 *   A = Background
 *   B = Background
 *   C = 3D light
 *   D = selectColor
 *   E = 3D dark
 *   F = Background
 *   G = Indicator Color
 *   H = disabled Indicator Color
 */

/* XPM */
static const char *const button_images[] = {
    /* width height ncolors chars_per_pixel */
    "52 26 7 1",
    /* colors */
    "A c #808000000000",
    "B c #000080800000",
    "C c #808080800000",
    "D c #000000008080",
    "E c #808000008080",
    "F c #000080808080",
    "G c #000000000000",
    "H c #000080800000",
    /* pixels */
    "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB",
    "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB",
    "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
    "AEDDDDDDDDDCBAEDDDDDDDGDCBAEFFFFFFFFFCBAEFFFFFFFHFCB",
    "AEDDDDDDDDDCBAEDDDDDDGGDCBAEFFFFFFFFFCBAEFFFFFFHHFCB",
    "AEDDDDDDDDDCBAEDGDDDGGGDCBAEFFFFFFFFFCBAEFHFFFHHHFCB",
    "AEDDDDDDDDDCBAEDGGDGGGDDCBAEFFFFFFFFFCBAEFHHFHHHFFCB",
    "AEDDDDDDDDDCBAEDGGGGGDDDCBAEFFFFFFFFFCBAEFHHHHHFFFCB",
    "AEDDDDDDDDDCBAEDDGGGDDDDCBAEFFFFFFFFFCBAEFFHHHFFFFCB",
    "AEDDDDDDDDDCBAEDDDGDDDDDCBAEFFFFFFFFFCBAEFFFHFFFFFCB",
    "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
    "ACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCB",
    "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
    "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF",
    "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF",
    "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF",
    "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
    "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
    "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
    "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
    "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
    "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
    "FACCDDDDCCBFFFACCDDDDCCBFFFACCFFFFCCBFFFACCFFFFCCBFF",
    "FFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFF",
    "FFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFF",
    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
};

/*
 * Sizes and offsets into above XPM file.
 */

#define CHECK_BUTTON_DIM    13
#define CHECK_MENU_DIM       9
#define CHECK_START          9
#define CHECK_ON_OFFSET     13
#define CHECK_OFF_OFFSET     0
#define CHECK_DISON_OFFSET  39
#define CHECK_DISOFF_OFFSET 26
#define RADIO_BUTTON_DIM    12
#define RADIO_MENU_DIM       6
#define RADIO_WIDTH         13
#define RADIO_START         22
#define RADIO_ON_OFFSET     13
#define RADIO_OFF_OFFSET     0
#define RADIO_DISON_OFFSET  39
#define RADIO_DISOFF_OFFSET 26

/*
 * Indicator Draw Modes
 */

#define CHECK_BUTTON 0
#define CHECK_MENU   1
#define RADIO_BUTTON 2
#define RADIO_MENU   3

/*



































































 *----------------------------------------------------------------------
 *
 * TkpDrawCheckIndicator -
 *
 *	Draws the checkbox image in the drawable at the (x,y) location, value,
 *	and state given. This routine is use by the button and menu widgets
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An image is drawn in the drawable at the location given.
 *
 *----------------------------------------------------------------------
 */






















void
TkpDrawCheckIndicator(
    Tk_Window tkwin,		/* handle for resource alloc */
    Display *display,
    Drawable d,			/* what to draw on */
    int x, int y,		/* where to draw */
    Tk_3DBorder bgBorder,	/* colors of the border */
    XColor *indicatorColor,	/* color of the indicator */
    XColor *selectColor,	/* color when selected */
    XColor *disableColor,	/* color when disabled */
    int on,			/* are we on? */
    int disabled,		/* are we disabled? */
    int mode)			/* kind of indicator to draw */
{
    int ix, iy;
    int dim;
    int imgsel, imgstart;
    TkBorder *bg_brdr = (TkBorder*)bgBorder;
    XGCValues gcValues;
    GC copyGC;
    unsigned long imgColors[8];
    XImage *img;
    Pixmap pixmap;





    int depth;

    /*
     * Sanity check.
     */

    if (tkwin == NULL || display == NULL || d == None || bgBorder == NULL
	    || indicatorColor == NULL) {
	return;
    }

    if (disableColor == NULL) {
	disableColor = bg_brdr->bgColorPtr;
    }

    if (selectColor == NULL) {
	selectColor = bg_brdr->bgColorPtr;
    }

    depth = Tk_Depth(tkwin);

    /*
     * Compute starting point and dimensions of image inside button_images to
     * be used.

     */

    switch (mode) {
    default:
    case CHECK_BUTTON:
	imgsel = on == 2 ? CHECK_DISON_OFFSET :
		on == 1 ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
	imgsel += disabled && on != 2 ? CHECK_DISOFF_OFFSET : 0;
	imgstart = CHECK_START;
	dim = CHECK_BUTTON_DIM;
	break;

    case CHECK_MENU:
	imgsel = on == 2 ? CHECK_DISOFF_OFFSET :
		on == 1 ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
	imgsel += disabled && on != 2 ? CHECK_DISOFF_OFFSET : 0;
	imgstart = CHECK_START + 2;
	imgsel += 2;
	dim = CHECK_MENU_DIM;
	break;

    case RADIO_BUTTON:
	imgsel = on == 2 ? RADIO_DISON_OFFSET :
		on==1 ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
	imgsel += disabled && on != 2 ? RADIO_DISOFF_OFFSET : 0;
	imgstart = RADIO_START;
	dim = RADIO_BUTTON_DIM;
	break;

    case RADIO_MENU:
	imgsel = on == 2 ? RADIO_DISOFF_OFFSET :
		on==1 ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
	imgsel += disabled && on != 2 ? RADIO_DISOFF_OFFSET : 0;
	imgstart = RADIO_START + 3;
	imgsel += 3;
	dim = RADIO_MENU_DIM;
	break;
    }


    /*
     * Allocate the drawing areas to use. Note that we use double-buffering
     * here because not all code paths leading to this function do so.
     */

    pixmap = Tk_GetPixmap(display, d, dim, dim, depth);
    if (pixmap == None) {
	return;
    }

    x -= dim/2;
    y -= dim/2;

    img = XGetImage(display, pixmap, 0, 0,
	    (unsigned int)dim, (unsigned int)dim, AllPlanes, ZPixmap);
    if (img == NULL) {
	return;
    }

    /*
     * Set up the color mapping table.
     */

    TkpGetShadows(bg_brdr, tkwin);


    imgColors[0 /*A*/] =

	    Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
    imgColors[1 /*B*/] =
	    Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;

    imgColors[2 /*C*/] = (bg_brdr->lightColorPtr != NULL) ?


	    Tk_GetColorByValue(tkwin, bg_brdr->lightColorPtr)->pixel :
	    WhitePixelOfScreen(bg_brdr->screen);
    imgColors[3 /*D*/] =


	    Tk_GetColorByValue(tkwin, selectColor)->pixel;
    imgColors[4 /*E*/] = (bg_brdr->darkColorPtr != NULL) ?
	    Tk_GetColorByValue(tkwin, bg_brdr->darkColorPtr)->pixel :
	    BlackPixelOfScreen(bg_brdr->screen);
    imgColors[5 /*F*/] =

	    Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
    imgColors[6 /*G*/] =
	    Tk_GetColorByValue(tkwin, indicatorColor)->pixel;
    imgColors[7 /*H*/] =

	    Tk_GetColorByValue(tkwin, disableColor)->pixel;














    /*
     * Create the image, painting it into an XImage one pixel at a time.


     */

    for (iy=0 ; iy<dim ; iy++) {
	for (ix=0 ; ix<dim ; ix++) {
	    XPutPixel(img, ix, iy,
		    imgColors[button_images[imgstart+iy][imgsel+ix] - 'A']);




	}


    }

    /*
     * Copy onto our target drawable surface.
     */

    memset(&gcValues, 0, sizeof(gcValues));
    gcValues.background = bg_brdr->bgColorPtr->pixel;
    gcValues.graphics_exposures = False;

    copyGC = Tk_GetGC(tkwin, 0, &gcValues);












    XPutImage(display, pixmap, copyGC, img, 0, 0, 0, 0,



	    (unsigned)dim, (unsigned)dim);




    XCopyArea(display, pixmap, d, copyGC, 0, 0,



	    (unsigned)dim, (unsigned)dim, x, y);









    /*
     * Tidy up.

     */

    Tk_FreeGC(display, copyGC);


    XDestroyImage(img);
    Tk_FreePixmap(display, pixmap);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
 *







|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|






|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















|
|
|

|
|
|
|
|
>
>
>
>
>
|


|















<
<

<
|
>





|
<
<
|




|
<
<
|
<




|
<
<
|




|
<
<
|
<



>


<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<




>
|
>
|
|
<
>
|
>
>
|
<
|
>
>
|
|
|
<
|
>
|
|
|
|
>
|
>
>
>
>

>
>
>
>
>
>
>
>
>
|
<
>
>
|

<
<
<
<
>
>
>
>

>
>
|
<
|
|
|

|
|
|
>
|
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
|
>
>
>
|
>
>
>
>
>
|
>
>
>

<
>


|
>
>
|
<







34
35
36
37
38
39
40
41
42
43
44
45












































































46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


206

207
208
209
210
211
212
213
214


215
216
217
218
219
220


221

222
223
224
225
226


227
228
229
230
231
232


233

234
235
236
237
238
239



240




241











242
243
244
245
246
247
248
249
250

251
252
253
254
255

256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

285
286
287
288




289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348

349
350
351
352
353
354
355
/*
 * The class function table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    NULL,			/* createProc */
    NULL			/* modalProc */
};

/*












































































 * Indicator draw modes
 */

#define CHECK_BUTTON 0
#define CHECK_MENU   1
#define RADIO_BUTTON 2
#define RADIO_MENU   3

/*
 * Indicator sizes
 */

#define CHECK_BUTTON_DIM 16
#define CHECK_MENU_DIM    8
#define RADIO_BUTTON_DIM 16
#define RADIO_MENU_DIM    8

/*
 * Data of the SVG images used for drawing the indicators
 */

static const char checkbtnOffData[] =
    "<svg id='checkbutton' width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n"
    " <path id='borderdark' d='m0 0v16l1-1v-14h14l1-1h-16z' fill='#DARKKK'/>\n"
    " <path id='borderlight' d='m16 0-1 1v14h-14l-1 1h16v-16z' fill='#LIGHTT'/>\n"
    " <rect id='rectbackdrop' x='2' y='2' width='12' height='12' fill='#INTROR'/>\n"
    "</svg>";

static const char checkbtnOnData[] =
    "<svg id='checkbutton' width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n"
    " <path id='borderdark' d='m0 0v16l1-1v-14h14l1-1h-16z' fill='#DARKKK'/>\n"
    " <path id='borderlight' d='m16 0-1 1v14h-14l-1 1h16v-16z' fill='#LIGHTT'/>\n"
    " <rect id='rectbackdrop' x='2' y='2' width='12' height='12' fill='#INTROR'/>\n"
    " <path id='indicator' d='m4.5 8 3 3 4-6' fill='none' stroke='#INDCTR' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/>\n"
    "</svg>";

static const char radiobtnOffData[] =
    "<svg id='radiobutton' width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n"
    " <defs>\n"
    "  <linearGradient id='gradient' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n"
    "   <stop stop-color='#DARKKK' offset='0'/>\n"
    "   <stop stop-color='#LIGHTT' offset='1' stop-opacity='0'/>\n"
    "  </linearGradient>\n"
    " </defs>\n"
    " <circle cx='8' cy='8' r='8' fill='url(#gradient)'/>\n"
    " <circle cx='8' cy='8' r='6.5' fill='#INTROR'/>\n"
    "</svg>";

static const char radiobtnOnData[] =
    "<svg id='radiobutton' width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n"
    " <defs>\n"
    "  <linearGradient id='gradient' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n"
    "   <stop stop-color='#DARKKK' offset='0'/>\n"
    "   <stop stop-color='#LIGHTT' offset='1' stop-opacity='0'/>\n"
    "  </linearGradient>\n"
    " </defs>\n"
    " <circle cx='8' cy='8' r='8' fill='url(#gradient)'/>\n"
    " <circle cx='8' cy='8' r='7' fill='#INTROR'/>\n"
    " <circle cx='8' cy='8' r='4' fill='#INDCTR'/>\n"
    "</svg>";

static const char menuOffData[] =
    "<svg width='8' height='8' version='1.1' xmlns='http://www.w3.org/2000/svg'></svg>";

static const char checkmenuOnData[] =
    "<svg width='8' height='8' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n"
    " <path id='indicator' d='m1 3.5 2.5 3 3.5-5' fill='none' stroke='#INDCTR' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.975'/>\n"
    "</svg>";

static const char radiomenuOnData[] =
    "<svg width='8' height='8' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n"
    " <circle cx='4' cy='4' r='3' fill='#INDCTR'/>\n"
    "</svg>";


/*
 *----------------------------------------------------------------------
 *
 * TkpDrawCheckIndicator -
 *
 *	Draws the checkbox image in the drawable at the (x,y) location, value,
 *	and state given. This routine is used by the button and menu widgets.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An image is drawn in the drawable at the location given.
 *
 *----------------------------------------------------------------------
 */

static void
ColorToStr(
    const XColor *colorPtr,	/* specifies a color */
    char *colorStr)		/* memory area to which the color is to be
				   output in the format "RRGGBB" */
{
    snprintf(colorStr, 7, "%02x%02x%02x",
	     colorPtr->red >> 8, colorPtr->green >> 8, colorPtr->blue >> 8);
}

static void
ImageChanged(			/* to be passed to Tk_GetImage() */
    void *clientData,
    int x, int y, int width, int height,
    int imageWidth, int imageHeight)
{
    (void)clientData;
    (void)x; (void)y; (void)width; (void)height;
    (void)imageWidth; (void)imageHeight;
}

void
TkpDrawCheckIndicator(
    Tk_Window tkwin,		/* handle for resource alloc */
    Display *display,
    Drawable d,			/* what to draw on */
    int x, int y,		/* where to draw */
    Tk_3DBorder bgBorder,	/* colors of the border */
    XColor *indicatorColor,	/* color of the indicator */
    XColor *selectColor,	/* color when selected */
    XColor *disableColor,	/* color when disabled */
    int on,			/* are we on? */
    int disabled,		/* are we disabled? */
    int mode)			/* kind of indicator to draw */
{
    const char *svgDataPtr;
    int hasBorder, hasInterior, dim;
    double scalingLevel = TkScalingLevel(tkwin);
    TkBorder *bg_brdr = (TkBorder*)bgBorder;
    char darkColorStr[7], lightColorStr[7], interiorColorStr[7], indicatorColorStr[7];
    Tcl_Interp *interp = Tk_Interp(tkwin);
    char imgName[60];
    Tk_Image img;
    size_t svgDataLen;
    char *svgDataCopy;
    char *darkColorPtr, *lightColorPtr, *interiorColorPtr, *indicatorColorPtr;
    const char *cmdFmt;
    size_t scriptSize;
    char *script;
    int code;

    /*
     * Sanity check
     */

    if (tkwin == NULL || display == NULL || d == None || bgBorder == NULL
	    || indicatorColor == NULL) {
	return;
    }

    if (disableColor == NULL) {
	disableColor = bg_brdr->bgColorPtr;
    }

    if (selectColor == NULL) {
	selectColor = bg_brdr->bgColorPtr;
    }



    /*

     * Determine the SVG data to use for the
     * photo image and the latter's dimensions
     */

    switch (mode) {
    default:
    case CHECK_BUTTON:
	svgDataPtr = (on == 0 ? checkbtnOffData : checkbtnOnData);


	hasBorder = 1; hasInterior = 1;
	dim = CHECK_BUTTON_DIM;
	break;

    case CHECK_MENU:
	svgDataPtr = (on == 0 ? menuOffData : checkmenuOnData);


	hasBorder = 0; hasInterior = 0;

	dim = CHECK_MENU_DIM;
	break;

    case RADIO_BUTTON:
	svgDataPtr = (on == 0 ? radiobtnOffData : radiobtnOnData);


	hasBorder = 1; hasInterior = 1;
	dim = RADIO_BUTTON_DIM;
	break;

    case RADIO_MENU:
	svgDataPtr = (on == 0 ? menuOffData : radiomenuOnData);


	hasBorder = 0; hasInterior = 0;

	dim = RADIO_MENU_DIM;
	break;
    }
    dim = (int)(dim * scalingLevel);

    /*



     * Construct the color strings darkColorStr, lightColorStr,




     * interiorColorStr, and indicatorColorStr











     */

    TkpGetShadows(bg_brdr, tkwin);

    if (bg_brdr->darkColorPtr == NULL) {
	strcpy(darkColorStr, "000000");
    } else {
	ColorToStr(Tk_GetColorByValue(tkwin, bg_brdr->darkColorPtr),
		   darkColorStr);

    }
    if (bg_brdr->lightColorPtr == NULL) {
	strcpy(lightColorStr, "ffffff");
    } else {
	ColorToStr(Tk_GetColorByValue(tkwin, bg_brdr->lightColorPtr),

		   lightColorStr);
    }
    if (on == 2 || disabled) {			/* tri-state or disabled */
	ColorToStr(Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr),
		   interiorColorStr);
	ColorToStr(Tk_GetColorByValue(tkwin, disableColor),

		   indicatorColorStr);
    } else {
	ColorToStr(Tk_GetColorByValue(tkwin, selectColor),
		   interiorColorStr);
	ColorToStr(Tk_GetColorByValue(tkwin, indicatorColor),
		   indicatorColorStr);
    }

    /*
     * Check whether there is an SVG image of this size
     * for the value of mode and these color strings
     */

    snprintf(imgName, sizeof(imgName),
	     "::tk::icons::indicator%d_%d_%s_%s_%s_%s",
	     dim, mode,
	     hasBorder ? darkColorStr : "XXXXXX",
	     hasBorder ? lightColorStr : "XXXXXX",
	     hasInterior ? interiorColorStr : "XXXXXX",
	     on ? indicatorColorStr : "XXXXXX");
    img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    if (img == NULL) {
	/*

	 * Copy the string pointed to by svgDataPtr to
	 * a newly allocated memory area svgDataCopy
	 */





	svgDataLen = strlen(svgDataPtr);
	svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
	if (svgDataCopy == NULL) {
	    return;
	}
	memcpy(svgDataCopy, svgDataPtr, svgDataLen);
	svgDataCopy[svgDataLen] = '\0';


	/*
	 * Update the colors within svgDataCopy
	 */

	darkColorPtr =      strstr(svgDataCopy, "DARKKK");
	lightColorPtr =     strstr(svgDataCopy, "LIGHTT");
	interiorColorPtr =  strstr(svgDataCopy, "INTROR");
	indicatorColorPtr = strstr(svgDataCopy, "INDCTR");

	if (darkColorPtr != NULL) {
	    memcpy(darkColorPtr, darkColorStr, 6);
	}
	if (lightColorPtr != NULL) {
	    memcpy(lightColorPtr, lightColorStr, 6);
	}
	if (interiorColorPtr != NULL) {
	    memcpy(interiorColorPtr, interiorColorStr, 6);
	}
	if (indicatorColorPtr != NULL) {
	    memcpy(indicatorColorPtr, indicatorColorStr, 6);
	}

	/*
	 * Create an SVG photo image from svgDataCopy
	 */

	cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
	scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
	script = (char *)attemptckalloc(scriptSize);
	if (script == NULL) {
	    ckfree(svgDataCopy);
	    return;
	}
	snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
	ckfree(svgDataCopy);
	code = Tcl_EvalEx(interp, script, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	ckfree(script);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(interp, code);
	    return;
	}
	img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    }

    /*

     * Adjust the image's coordinates in the drawable and display the image
     */

    x -= dim/2;
    y -= dim/2;
    Tk_RedrawImage(img, 0, 0, dim, dim, d, x, y);
    Tk_FreeImage(img);

}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
 *
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
	*x += shiftX;
	*y += shiftY;
    }
}

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    TkButton *butPtr = (TkButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	*x += shiftX;
	*y += shiftY;
    }
}

void
TkpDisplayButton(
    void *clientData)	/* Information about widget. */
{
    TkButton *butPtr = (TkButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705


706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
    }

    /*
     * Draw the indicator for check buttons and radio buttons. At this point,
     * x and y refer to the top-left corner of the text or image or bitmap.
     */

    if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
	if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
	    TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
	    XColor *selColor = NULL;

	    if (selBorder != NULL) {
		selColor = selBorder->bgColorPtr;
	    }
	    x -= butPtr->indicatorSpace/2;
	    y = Tk_Height(tkwin)/2;
	    TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
		    border, butPtr->normalFg, selColor, butPtr->disabledFg,
		    ((butPtr->flags & SELECTED) ? 1 :
			    (butPtr->flags & TRISTATED) ? 2 : 0),
		    (butPtr->state == STATE_DISABLED), CHECK_BUTTON);
	}
    } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) {
	if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
	    TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
	    XColor *selColor = NULL;



	    if (selBorder != NULL) {
		selColor = selBorder->bgColorPtr;
	    }
	    x -= butPtr->indicatorSpace/2;
	    y = Tk_Height(tkwin)/2;
	    TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
		    border, butPtr->normalFg, selColor, butPtr->disabledFg,
		    ((butPtr->flags & SELECTED) ? 1 :
			    (butPtr->flags & TRISTATED) ? 2 : 0),
		    (butPtr->state == STATE_DISABLED), RADIO_BUTTON);
	}
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect. If the widget is
     * selected and we use a different background color when selected, must
     * temporarily modify the GC so the stippling is the right color.







|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
|
>
>

|
|
|
|
|
|
|
|
|
|
<







719
720
721
722
723
724
725
726







727








728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
    }

    /*
     * Draw the indicator for check buttons and radio buttons. At this point,
     * x and y refer to the top-left corner of the text or image or bitmap.
     */

    if ((butPtr->type == TYPE_CHECK_BUTTON || butPtr->type == TYPE_RADIO_BUTTON)







	    && butPtr->indicatorOn








	    && butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
	TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
	XColor *selColor = NULL;
	int btype = (butPtr->type == TYPE_CHECK_BUTTON ?
		     CHECK_BUTTON : RADIO_BUTTON);

	if (selBorder != NULL) {
	    selColor = selBorder->bgColorPtr;
	}
	x -= butPtr->indicatorSpace/2;
	y = Tk_Height(tkwin)/2;
	TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
		border, butPtr->normalFg, selColor, butPtr->disabledFg,
		((butPtr->flags & SELECTED) ? 1 :
		 (butPtr->flags & TRISTATED) ? 2 : 0),
		 (butPtr->state == STATE_DISABLED), btype);

    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect. If the widget is
     * selected and we use a different background color when selected, must
     * temporarily modify the GC so the stippling is the right color.
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);

	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);







|







913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
	haveImage = 1;
    }

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);

	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), TCL_INDEX_NONE, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
		width = butPtr->width * avgWidth;
	    }
	    if (butPtr->height > 0) {
		height = butPtr->height * fm.linespace;
	    }
	    if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
		butPtr->indicatorDiameter = fm.linespace;
		if (butPtr->type == TYPE_CHECK_BUTTON) {
		    butPtr->indicatorDiameter =
			(80*butPtr->indicatorDiameter)/100;
		}
		butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
	    }
	}
    }

    /*
     * When issuing the geometry request, add extra space for the indicator,







<
<
<
<







1008
1009
1010
1011
1012
1013
1014




1015
1016
1017
1018
1019
1020
1021
		width = butPtr->width * avgWidth;
	    }
	    if (butPtr->height > 0) {
		height = butPtr->height * fm.linespace;
	    }
	    if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
		butPtr->indicatorDiameter = fm.linespace;




		butPtr->indicatorSpace = butPtr->indicatorDiameter + avgWidth;
	    }
	}
    }

    /*
     * When issuing the geometry request, add extra space for the indicator,

Changes to unix/tkUnixColor.c.

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.
 *
 * 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"






|







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 © 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"
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &templ, &numFound);
	    if (numFound < 1) {
		Tcl_Panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree((char *) visInfoPtr);
	    stressPtr->colorPtr = (XColor *)
		    ckalloc(stressPtr->numColors * sizeof(XColor));
	    for (i = 0; i < stressPtr->numColors; i++) {
		stressPtr->colorPtr[i].pixel = (unsigned long) i;
	    }

	    XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
		    stressPtr->numColors);








|

|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &templ, &numFound);
	    if (numFound < 1) {
		Tcl_Panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree(visInfoPtr);
	    stressPtr->colorPtr = (XColor *)
		    ckalloc((size_t)stressPtr->numColors * sizeof(XColor));
	    for (i = 0; i < stressPtr->numColors; i++) {
		stressPtr->colorPtr[i].pixel = (unsigned long) i;
	    }

	    XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
		    stressPtr->numColors);

419
420
421
422
423
424
425

426
427
428
429
430
431
432
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


int
TkpCmapStressed(
    Tk_Window tkwin,		/* Window that identifies the display
				 * containing the colormap. */
    Colormap colormap)		/* Colormap to check for stress. */
{
    TkStressedCmap *stressPtr;







>







419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#undef TkpCmapStressed
int
TkpCmapStressed(
    Tk_Window tkwin,		/* Window that identifies the display
				 * containing the colormap. */
    Colormap colormap)		/* Colormap to check for stress. */
{
    TkStressedCmap *stressPtr;

Changes to unix/tkUnixConfig.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * tkUnixConfig.c --
 *
 *	This module implements the Unix system defaults for the configuration
 *	package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"


/*
 *----------------------------------------------------------------------
 *
 * TkpGetSystemDefault --
 *
 *	Given a dbName and className for a configuration option, return a
 *	string representation of the option.
 *
 * Results:
 *	Returns a Tk_Uid that is the string identifier that identifies this
 *	option. Returns NULL if there are no system defaults that match this
 *	pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    (void)tkwin;
    (void)dbName;
    (void)className;






|











|





|










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * tkUnixConfig.c --
 *
 *	This module implements the Unix system defaults for the configuration
 *	package.
 *
 * 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"


/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSystemDefault --
 *
 *	Given a dbName and className for a configuration option, return a
 *	string representation of the option.
 *
 * Results:
 *	Returns a Tcl_Obj* with the string identifier that identifies this
 *	option. Returns NULL if there are no system defaults that match this
 *	pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_GetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    (void)tkwin;
    (void)dbName;
    (void)className;

Changes to unix/tkUnixCursor.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkUnixCursor.c --
 *
 *	This file contains X specific cursor manipulation routines.
 *
 * 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"

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
 */

#ifndef CURSORFONT
#define CURSORFONT "cursor"
#endif

static Cursor		CreateCursorFromTableOrFile(Tcl_Interp *interp,
			    Tk_Window tkwin, int argc, const char **argv,
			    const struct TkCursorName *tkCursorPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkGetCursorByName --
 *







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
 */

#ifndef CURSORFONT
#define CURSORFONT "cursor"
#endif

static Cursor		CreateCursorFromTableOrFile(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Size argc, const char **argv,
			    const struct TkCursorName *tkCursorPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkGetCursorByName --
 *
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    TkUnixCursor *cursorPtr = NULL;
    Cursor cursor = None;
    int argc;
    const char **argv = NULL;
    Display *display = Tk_Display(tkwin);
    int inTkTable = 0;
    const struct TkCursorName *tkCursorPtr = NULL;

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;







|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    TkUnixCursor *cursorPtr = NULL;
    Cursor cursor = None;
    Tcl_Size argc;
    const char **argv = NULL;
    Display *display = Tk_Display(tkwin);
    int inTkTable = 0;
    const struct TkCursorName *tkCursorPtr = NULL;

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
	    }
	}
	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (dispPtr->cursorFont == None) {
	    dispPtr->cursorFont = XLoadFont(display, CURSORFONT);
	    if (dispPtr->cursorFont == None) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't load cursor font", -1));
		Tcl_SetErrorCode(interp, "TK", "CURSOR", "FONT", NULL);
		goto cleanup;
	    }
	}
	cursor = XCreateGlyphCursor(display, dispPtr->cursorFont,
		dispPtr->cursorFont, namePtr->shape, maskIndex,
		&fg, &bg);
    } else {
	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (!inTkTable && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get cursor from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
	    cursorPtr = NULL;
	    goto cleanup;
	}

	/*
	 * If the cursor is to be created from bitmap files, then there should







|















|







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
	    }
	}
	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (dispPtr->cursorFont == None) {
	    dispPtr->cursorFont = XLoadFont(display, CURSORFONT);
	    if (dispPtr->cursorFont == None) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't load cursor font", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "CURSOR", "FONT", NULL);
		goto cleanup;
	    }
	}
	cursor = XCreateGlyphCursor(display, dispPtr->cursorFont,
		dispPtr->cursorFont, namePtr->shape, maskIndex,
		&fg, &bg);
    } else {
	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (!inTkTable && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get cursor from a file in a safe interpreter",
		    TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
	    cursorPtr = NULL;
	    goto cleanup;
	}

	/*
	 * If the cursor is to be created from bitmap files, then there should
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
 *----------------------------------------------------------------------
 */

static Cursor
CreateCursorFromTableOrFile(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    int argc,
    const char **argv,		/* Cursor spec parsed into elements. */
    const struct TkCursorName *tkCursorPtr)
				/* Non-NULL when cursor is defined in Tk
				 * table. */
{
    Cursor cursor = None;








|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
 *----------------------------------------------------------------------
 */

static Cursor
CreateCursorFromTableOrFile(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tcl_Size argc,
    const char **argv,		/* Cursor spec parsed into elements. */
    const struct TkCursorName *tkCursorPtr)
				/* Non-NULL when cursor is defined in Tk
				 * table. */
{
    Cursor cursor = None;

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_DATA", NULL);
	    goto cleanup;
	}

	source = XCreateBitmapFromData(display, drawable, data, width,height);
	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, &argv[0][1],
		(unsigned *) &width, (unsigned *) &height,
		&source, &xHot, &yHot) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", &argv[0][1]));







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_DATA", NULL);
	    goto cleanup;
	}

	source = XCreateBitmapFromData(display, drawable, data, (unsigned)width, (unsigned)height);
	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, &argv[0][1],
		(unsigned *) &width, (unsigned *) &height,
		&source, &xHot, &yHot) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", &argv[0][1]));
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap mask data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_DATA", NULL);
	    goto cleanup;
	}

	mask = XCreateBitmapFromData(display, drawable, data, maskWidth,
		maskHeight);

	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, argv[1],
		(unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
		&mask, &dummy1, &dummy2) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", argv[1]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_FILE", NULL);
	    goto cleanup;
	}
    }

    if ((maskWidth != width) || (maskHeight != height)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"source and mask bitmaps have different sizes", -1));
	Tcl_SetErrorCode(interp, "TK", "CURSOR", "SIZE_MATCH", NULL);
	goto cleanup;
    }

    cursor = XCreatePixmapCursor(display, source, mask,
	    &fg, &bg, (unsigned) xHot, (unsigned) yHot);








|
|















|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap mask data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_DATA", NULL);
	    goto cleanup;
	}

	mask = XCreateBitmapFromData(display, drawable, data, (unsigned)maskWidth,
		(unsigned)maskHeight);

	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, argv[1],
		(unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
		&mask, &dummy1, &dummy2) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", argv[1]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_FILE", NULL);
	    goto cleanup;
	}
    }

    if ((maskWidth != width) || (maskHeight != height)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"source and mask bitmaps have different sizes", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "CURSOR", "SIZE_MATCH", NULL);
	goto cleanup;
    }

    cursor = XCreatePixmapCursor(display, source, mask,
	    &fg, &bg, (unsigned) xHot, (unsigned) yHot);

Changes to unix/tkUnixDefault.h.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
#define _TKUNIXDEFAULT

/*
 * 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:







>












>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#define _TKUNIXDEFAULT

/*
 * The definitions below provide symbolic names for the default colors.
 * NORMAL_BG -		Normal background color.
 * ACTIVE_BG -		Background color when widget is active.
 * SELECT_BG -		Background color for selected text.
 * SELECT_FG -		Foreground color for selected text.
 * TROUGH -		Background color for troughs in scales and scrollbars.
 * INDICATOR -		Color for indicator when button is selected.
 * DISABLED -		Foreground color when widget is disabled.
 * 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 SELECT_FG	BLACK
#define TROUGH		"#b3b3b3"
#define INDICATOR	WHITE
#define DISABLED	"#a3a3a3"
#define PLACEHOLDER_FG	"#b3b3b3"	/* grey70 */

/*
 * Defaults for labels, buttons, checkbuttons, and radiobuttons:
52
53
54
55
56
57
58

59
60
61
62
63
64
65
#define DEF_BUTTON_BORDER_WIDTH		"1"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""

#define DEF_BUTTON_FG			BLACK
#define DEF_CHKRAD_FG			DEF_BUTTON_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		BLACK







>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define DEF_BUTTON_BORDER_WIDTH		"1"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_LABEL_FG			BLACK
#define DEF_BUTTON_FG			BLACK
#define DEF_CHKRAD_FG			DEF_BUTTON_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		BLACK
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
#define DEF_CHECKBUTTON_VARIABLE	""

/*







<







87
88
89
90
91
92
93

94
95
96
97
98
99
100
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""

#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
#define DEF_CHECKBUTTON_VARIABLE	""

/*
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK







<







266
267
268
269
270
271
272

273
274
275
276
277
278
279
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL


/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""
#define DEF_MENUBUTTON_UNDERLINE	"-1"
#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			BLACK
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		BLACK
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		"-1"
#define DEF_MESSAGE_PADY		"-1"
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
#define DEF_MESSAGE_TEXT_VARIABLE	""
#define DEF_MESSAGE_WIDTH		"0"

/*







<



















|
|







330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""

#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			BLACK
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		BLACK
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		NULL
#define DEF_MESSAGE_PADY		NULL
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
#define DEF_MESSAGE_TEXT_VARIABLE	""
#define DEF_MESSAGE_WIDTH		"0"

/*
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
 * Defaults for scales:
 */

#define DEF_SCALE_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO	BLACK
#define DEF_SCALE_BG_COLOR		NORMAL_BG
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		BLACK
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"1"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY		"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
 */








|







|










|







|
|







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
 * Defaults for scales:
 */

#define DEF_SCALE_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO	BLACK
#define DEF_SCALE_BG_COLOR		NORMAL_BG
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0.0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		BLACK
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0.0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		BLACK
#define DEF_SCALE_HIGHLIGHT_WIDTH	"1"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY		"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1.0"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0.0"
#define DEF_SCALE_TO			"100.0"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
 */

488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	SELECT_BG

#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	BLACK
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"raised"







|
>







488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_BG_COLOR SELECT_BG
#define DEF_TEXT_INACTIVE_SELECT_FG_COLOR SELECT_FG
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	BLACK
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"raised"

Deleted unix/tkUnixDialog.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
 * tkUnixDialog.c --
 *
 *	Contains the Unix implementation of the common dialog boxes:
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"

/*
 * The wrapper code for Unix is actually set up in library/tk.tcl these days;
 * the procedure names used here are probably wrong too...
 */

#ifdef TK_OBSOLETE_UNIX_DIALOG_WRAPPERS

/*
 *----------------------------------------------------------------------
 *
 * EvalObjv --
 *
 *	Invokes the Tcl procedure with the arguments.
 *
 * Results:
 *	Returns the result of the evaluation of the command.
 *
 * Side effects:
 *	The command may be autoloaded.
 *
 *----------------------------------------------------------------------
 */

static int
EvalObjv(
    Tcl_Interp *interp,		/* Current interpreter. */
    char *cmdName,		/* Name of the TCL command to call */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    Tcl_Obj *cmdObj, **objs;
    int result;

    cmdObj = Tcl_NewStringObj(cmdName, -1);
    Tcl_IncrRefCount(cmdObj);
    objs = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc+1));
    objs[0] = cmdObj;
    memcpy(objs+1, objv, sizeof(Tcl_Obj *) * (unsigned)objc);

    result = Tcl_EvalObjv(interp, objc+1, objs, 0);

    Tcl_DecrRefCount(cmdObj);
    ckfree(objs);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
 *	This procedure implements the color dialog box for the Unix platform.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first time this procedure is called.
 *	This window is not destroyed and will be reused the next time the
 *	application invokes the "tk_chooseColor" command.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseColorObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    return EvalObjv(interp, "tk::ColorDialog", objc-1, objv+1);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileCmd --
 *
 *	This procedure implements the "open file" dialog box for the Unix
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first this procedure is called. This
 *	window is not destroyed and will be reused the next time the
 *	application invokes the "tk_getOpenFile" or "tk_getSaveFile" command.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    Tk_Window tkwin = clientData;

    if (Tk_StrictMotif(tkwin)) {
	return EvalObjv(interp, "tk::MotifOpenFDialog", objc-1, objv+1);
    } else {
	return EvalObjv(interp, "tk::OpenFDialog", objc-1, objv+1);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileCmd --
 *
 *	Same as Tk_GetOpenFileCmd but opens a "save file" dialog box instead.
 *
 * Results:
 *	Same as Tk_GetOpenFileCmd.
 *
 * Side effects:
 *	Same as Tk_GetOpenFileCmd.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    Tk_Window tkwin = clientData;

    if (Tk_StrictMotif(tkwin)) {
	return EvalObjv(interp, "tk::MotifSaveFDialog", objc-1, objv+1);
    } else {
	return EvalObjv(interp, "tk::SaveFDialog", objc-1, objv+1);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxCmd --
 *
 *	This procedure implements the MessageBox window for the Unix
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	None. The MessageBox window will be destroy before this procedure
 *	returns.
 *
 *----------------------------------------------------------------------
 */

int
Tk_MessageBoxCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const *objv)	/* Arguments. */
{
    return EvalObjv(interp, "tk::MessageBox", objc-1, objv+1);
}

#endif /* TK_OBSOLETE_UNIX_DIALOG_WRAPPERS */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































Changes to unix/tkUnixDraw.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkUnixDraw.c --
 *
 *	This file contains X specific drawing routines.
 *
 * 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"

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Tk_RestrictProc *prevProc;
    ClientData prevArg;
    ScrollInfo info;

    XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
	    x, y, (unsigned) width, (unsigned) height, x+dx, y+dy);

    info.done = 0;
    info.window = Tk_WindowId(tkwin);







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    Tk_RestrictProc *prevProc;
    void *prevArg;
    ScrollInfo info;

    XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
	    x, y, (unsigned) width, (unsigned) height, x+dx, y+dy);

    info.done = 0;
    info.window = Tk_WindowId(tkwin);
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 *	for a particular window.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
ScrollRestrictProc(
    ClientData arg,
    XEvent *eventPtr)
{
    ScrollInfo *info = (ScrollInfo *) arg;
    XRectangle rect;

    /*
     * Defer events which aren't for the specified window.







|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 *	for a particular window.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
ScrollRestrictProc(
    void *arg,
    XEvent *eventPtr)
{
    ScrollInfo *info = (ScrollInfo *) arg;
    XRectangle rect;

    /*
     * Defer events which aren't for the specified window.
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    }
    return TK_DISCARD_EVENT;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --
 *
 *	This function draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *      On Unix, we just draw the simple inset ring. On other sytems, e.g. the
 *      Mac, the focus ring is a little more complicated, so we need this
 *      abstraction.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    (void)bgGC;







|



















|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    }
    return TK_DISCARD_EVENT;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DrawHighlightBorder --
 *
 *	This function draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *      On Unix, we just draw the simple inset ring. On other sytems, e.g. the
 *      Mac, the focus ring is a little more complicated, so we need this
 *      abstraction.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
Tk_DrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    (void)bgGC;

Changes to unix/tkUnixEmbed.c.

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.
 *
 * 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"








|







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 © 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"
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for static functions defined in this file:
 */

static void		ContainerEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		EmbeddedEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		EmbedErrorProc(ClientData clientData,
			    XErrorEvent *errEventPtr);
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);

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *
 *	This function causes a Tk window to use a given X window as its parent
 *	window, rather than the root window for the screen. It is invoked by
 *	an embedded application to specify the window in which it is embedded.
 *
 * Results:
 *	The return value is normally TCL_OK. If an error occurs (such as
 *	string not being a valid window spec), then the return value is
 *	TCL_ERROR and an error message is left in the interp's result if
 *	interp is non-NULL.
 *
 * Side effects:
 *	Changes the colormap and other visual information to match that of the
 *	parent window given by "string".
 *
 *----------------------------------------------------------------------
 */

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }
    if (TkpScanWindowId(interp, string, &parent) != TCL_OK) {
	return TCL_ERROR;
    }








|

|

|

|




|






|



















|



















|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for static functions defined in this file:
 */

static void		ContainerEventProc(void *clientData,
			    XEvent *eventPtr);
static void		EmbeddedEventProc(void *clientData,
			    XEvent *eventPtr);
static int		EmbedErrorProc(void *clientData,
			    XErrorEvent *errEventPtr);
static void		EmbedFocusProc(void *clientData,
			    XEvent *eventPtr);
static void		EmbedGeometryRequest(Container *containerPtr,
			    int width, int height);
static void		EmbedSendConfigure(Container *containerPtr);
static void		EmbedStructureProc(void *clientData,
			    XEvent *eventPtr);
static void		EmbedWindowDeleted(TkWindow *winPtr);

/*
 *----------------------------------------------------------------------
 *
 * Tk_UseWindow --
 *
 *	This function causes a Tk window to use a given X window as its parent
 *	window, rather than the root window for the screen. It is invoked by
 *	an embedded application to specify the window in which it is embedded.
 *
 * Results:
 *	The return value is normally TCL_OK. If an error occurs (such as
 *	string not being a valid window spec), then the return value is
 *	TCL_ERROR and an error message is left in the interp's result if
 *	interp is non-NULL.
 *
 * Side effects:
 *	Changes the colormap and other visual information to match that of the
 *	parent window given by "string".
 *
 *----------------------------------------------------------------------
 */

int
Tk_UseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }
    if (TkpScanWindowId(interp, string, &parent) != TCL_OK) {
	return TCL_ERROR;
    }

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
    winPtr->flags |= TK_EMBEDDED;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeWindow --
 *
 *	Create an actual window system window object based on the current
 *	attributes of the specified TkWindow.
 *
 * Results:
 *	Returns the handle to the new window, or None on failure.
 *
 * Side effects:
 *	Creates a new X window.
 *
 *----------------------------------------------------------------------
 */

Window
TkpMakeWindow(
    TkWindow *winPtr,		/* Tk's information about the window that is
				 * to be instantiated. */
    Window parent)		/* Window system token for the parent in which
				 * the window is to be created. */
{
    Container *containerPtr;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->flags & TK_EMBEDDED) {
	/*
	 * This window is embedded. Don't create the new window in the given
	 * parent; instead, create it as a child of the root window of the







|














|
|





>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    winPtr->flags |= TK_EMBEDDED;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MakeWindow --
 *
 *	Create an actual window system window object based on the current
 *	attributes of the specified TkWindow.
 *
 * Results:
 *	Returns the handle to the new window, or None on failure.
 *
 * Side effects:
 *	Creates a new X window.
 *
 *----------------------------------------------------------------------
 */

Window
Tk_MakeWindow(
    Tk_Window tkwin,		/* Tk's information about the window that is
				 * to be instantiated. */
    Window parent)		/* Window system token for the parent in which
				 * the window is to be created. */
{
    Container *containerPtr;
    TkWindow *winPtr = (TkWindow *) tkwin;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->flags & TK_EMBEDDED) {
	/*
	 * This window is embedded. Don't create the new window in the given
	 * parent; instead, create it as a child of the root window of the
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
	    InputOutput, winPtr->visual, winPtr->dirtyAtts,
	    &winPtr->atts);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeContainer --
 *
 *	This function is called to indicate that a particular window will be a
 *	container for an embedded application. This changes certain aspects of
 *	the window's behavior, such as whether it will receive events anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeContainer(
    Tk_Window tkwin)		/* Token for a window that is about to become
				 * a container. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));







|















|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
	    InputOutput, winPtr->visual, winPtr->dirtyAtts,
	    &winPtr->atts);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MakeContainer --
 *
 *	This function is called to indicate that a particular window will be a
 *	container for an embedded application. This changes certain aspects of
 *	the window's behavior, such as whether it will receive events anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MakeContainer(
    Tk_Window tkwin)		/* Token for a window that is about to become
				 * a container. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
 *	The integer pointed to by the clientData argument is set to 1.
 *
 *----------------------------------------------------------------------
 */

static int
EmbedErrorProc(
    ClientData clientData,	/* Points to integer to set. */
    XErrorEvent *errEventPtr)	/* Points to information about error (not
				 * used). */
{
    int *iPtr = (int *)clientData;
    (void)errEventPtr;

    *iPtr = 1;







|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
 *	The integer pointed to by the clientData argument is set to 1.
 *
 *----------------------------------------------------------------------
 */

static int
EmbedErrorProc(
    void *clientData,	/* Points to integer to set. */
    XErrorEvent *errEventPtr)	/* Points to information about error (not
				 * used). */
{
    int *iPtr = (int *)clientData;
    (void)errEventPtr;

    *iPtr = 1;
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
 *	destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }







|







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
 *	destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EmbeddedEventProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));







|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
 *	The embedded window gets resized to match the container.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedStructureProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {
        /*







|







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
 *	The embedded window gets resized to match the container.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedStructureProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {
        /*
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
 *	The X focus may change.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedFocusProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;
    Display *display;

    display = Tk_Display(containerPtr->parentPtr);







|







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
 *	The X focus may change.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedFocusProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;
    Display *display;

    display = Tk_Display(containerPtr->parentPtr);
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
		(unsigned) winPtr->changes.height);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this function will return either one, given the other.
 *
 * Results:
 *	If winPtr is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow *
TkpGetOtherWindow(
    TkWindow *winPtr)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr;
            containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parentPtr;
	} else if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







|





|









|
|
|









|
|
|
|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
		(unsigned) winPtr->changes.height);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this function will return either one, given the other.
 *
 * Results:
 *	If tkwin is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
Tk_GetOtherWindow(
    Tk_Window tkwin)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr;
            containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if ((Tk_Window)containerPtr->embeddedPtr == tkwin) {
	    return (Tk_Window)containerPtr->parentPtr;
	} else if ((Tk_Window)containerPtr->parentPtr == tkwin) {
	    return (Tk_Window)containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];
    Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;







|

|







870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    void *dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    int all;
    Container *containerPtr;
    Tcl_DString dString;
    char buffer[50];
    Tcl_Interp *embeddedInterp = NULL, *parentInterp = NULL;
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
	    continue;
	}
	Tcl_DStringStartSublist(&dString);
	/* Parent id */
	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Parent pathName */
	if (containerPtr->parentPtr == NULL ||
	    parentInterp != interp) {
	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->parentPtr->pathName);
	}
        /* Wrapper */
	if (containerPtr->wrapper == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->wrapper);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Embedded window pathName */
	if (containerPtr->embeddedPtr == NULL ||
	    embeddedInterp != interp) {







|
















|







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
	    continue;
	}
	Tcl_DStringStartSublist(&dString);
	/* Parent id */
	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    snprintf(buffer, sizeof(buffer), "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Parent pathName */
	if (containerPtr->parentPtr == NULL ||
	    parentInterp != interp) {
	    Tcl_DStringAppendElement(&dString, "");
	} else {
	    Tcl_DStringAppendElement(&dString,
		    containerPtr->parentPtr->pathName);
	}
        /* Wrapper */
	if (containerPtr->wrapper == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    snprintf(buffer, sizeof(buffer), "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->wrapper);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Embedded window pathName */
	if (containerPtr->embeddedPtr == NULL ||
	    embeddedInterp != interp) {
977
978
979
980
981
982
983

984
985
986
987
988
989
990
     * information about the embedded application and free the container's
     * record.
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;
    while (1) {

	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->wrapper = None;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    containerPtr->parentPtr = NULL;







>







978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
     * information about the embedded application and free the container's
     * record.
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;
    while (1) {
	if (containerPtr == NULL) return;
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->wrapper = None;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    containerPtr->parentPtr = NULL;

Changes to unix/tkUnixEvent.c.

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.
 *
 * 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>






|







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 © 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>
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for functions that are referenced only in this file:
 */

static void		DisplayCheckProc(ClientData clientData, int flags);
static void		DisplayExitHandler(ClientData clientData);
static void		DisplayFileProc(ClientData clientData, int flags);
static void		DisplaySetupProc(ClientData clientData, int flags);
static void		TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS
static void		InstantiateIMCallback(Display *, XPointer client_data, XPointer call_data);
static void		DestroyIMCallback(XIM im, XPointer client_data, XPointer call_data);
static void		OpenIM(TkDisplay *dispPtr);
#endif








|
|
|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for functions that are referenced only in this file:
 */

static void		DisplayCheckProc(void *clientData, int flags);
static void		DisplayExitHandler(void *clientData);
static void		DisplayFileProc(void *clientData, int flags);
static void		DisplaySetupProc(void *clientData, int flags);
static void		TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS
static void		InstantiateIMCallback(Display *, XPointer client_data, XPointer call_data);
static void		DestroyIMCallback(XIM im, XPointer client_data, XPointer call_data);
static void		OpenIM(TkDisplay *dispPtr);
#endif

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayExitHandler(
    ClientData dummy)	/* Not used. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
    tsdPtr->initialized = 0;







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayExitHandler(
    void *dummy)	/* Not used. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
    tsdPtr->initialized = 0;
163
164
165
166
167
168
169

170
171
172
173
174
175
176
    if (display == NULL) {
	return NULL;
    }
    dispPtr = (TkDisplay *)ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;
#ifdef TK_USE_INPUT_METHODS

    OpenIM(dispPtr);
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, dispPtr);








>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    if (display == NULL) {
	return NULL;
    }
    dispPtr = (TkDisplay *)ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;
#ifdef TK_USE_INPUT_METHODS
    XSetLocaleModifiers("");
    OpenIM(dispPtr);
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, dispPtr);

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 *	Tcl even if there is no more data on the X connection.
 *
 *----------------------------------------------------------------------
 */

static void
DisplaySetupProc(
    ClientData dummy,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    static Tcl_Time blockTime = { 0, 0 };
    (void)dummy;

    if (!(flags & TCL_WINDOW_EVENTS)) {







|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
 *	Tcl even if there is no more data on the X connection.
 *
 *----------------------------------------------------------------------
 */

static void
DisplaySetupProc(
    void *dummy,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    static Tcl_Time blockTime = { 0, 0 };
    (void)dummy;

    if (!(flags & TCL_WINDOW_EVENTS)) {
361
362
363
364
365
366
367
368


369
370
371
372
373
374
375
     * until Tk_HandleEvent then many input methods actually cease to work
     * correctly. Most of the time, Tk processes its event queue fast enough
     * for this to not be an issue anyway. [Bug 1924761]
     */

    while (QLength(display) > 0) {
	XNextEvent(display, &event.x);
	if (event.type > MappingNotify) {


	    continue;
	}
	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;







|
>
>







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
     * until Tk_HandleEvent then many input methods actually cease to work
     * correctly. Most of the time, Tk processes its event queue fast enough
     * for this to not be an issue anyway. [Bug 1924761]
     */

    while (QLength(display) > 0) {
	XNextEvent(display, &event.x);
	if ((event.type >= VirtualEvent) && (event.type <= MouseWheelEvent)) {
	    /* See [fe87e9af39]. Those are internal Tk event types, if they come
	     * from an external source they most likely would be totally mis-interpreted */
	    continue;
	}
	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
 *	Moves queued events onto the Tcl event queue.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCheckProc(
    ClientData dummy,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    (void)dummy;

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;







|







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
 *	Moves queued events onto the Tcl event queue.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCheckProc(
    void *dummy,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    (void)dummy;

    if (!(flags & TCL_WINDOW_EVENTS)) {
	return;
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
 *	all the displays.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayFileProc(
    ClientData clientData,	/* The display pointer. */
    int flags)			/* Should be TCL_READABLE. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    Display *display = dispPtr->display;
    int numFound;
    (void)flags;








|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
 *	all the displays.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayFileProc(
    void *clientData,	/* The display pointer. */
    int flags)			/* Should be TCL_READABLE. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    Display *display = dispPtr->display;
    int numFound;
    (void)flags;

659
660
661
662
663
664
665

666
667
668
669
670
671
672
 *
 * Side effects:
 *	Places new events on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */


void
TkpSync(
    Display *display)		/* Display to sync. */
{
    XSync(display, False);

    /*







>







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
 *
 * Side effects:
 *	Places new events on the Tk event queue.
 *
 *----------------------------------------------------------------------
 */

#undef TkpSync
void
TkpSync(
    Display *display)		/* Display to sync. */
{
    XSync(display, False);

    /*
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
OpenIM(
    TkDisplay *dispPtr)		/* Tk's structure for the display. */
{
    int i;
    XIMStyles *stylePtr;
    XIMStyle bestStyle = 0;

    if (XSetLocaleModifiers("") == NULL) {
	return;
    }

    ++dispPtr->ximGeneration;
    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
    if (dispPtr->inputMethod == NULL) {
	return;
    }

    /* Require X11R6 */







<
<
<
<







735
736
737
738
739
740
741




742
743
744
745
746
747
748
OpenIM(
    TkDisplay *dispPtr)		/* Tk's structure for the display. */
{
    int i;
    XIMStyles *stylePtr;
    XIMStyle bestStyle = 0;





    ++dispPtr->ximGeneration;
    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
    if (dispPtr->inputMethod == NULL) {
	return;
    }

    /* Require X11R6 */

Changes to unix/tkUnixFocus.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"







|







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 © 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
/*
 * tkUnixFont.c --
 *
 *	Contains the Unix implementation of the platform-independent font
 *	package interface.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include "tkFont.h"






|







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 © 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"
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
				/* Builtin space for a limited number of
				 * SubFonts. */
    int numSubFonts;		/* Length of following array. */
    SubFont *subFontArray;	/* Array of SubFonts that have been loaded in
				 * order to draw/measure all the characters
				 * encountered by this font so far. All fonts
				 * start off with one SubFont initialized by
				 * AllocFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */
    SubFont controlSubFont;	/* Font to use to display control-character
				 * expansions. */

    Display *display;		/* Display that owns font. */







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
				/* Builtin space for a limited number of
				 * SubFonts. */
    int numSubFonts;		/* Length of following array. */
    SubFont *subFontArray;	/* Array of SubFonts that have been loaded in
				 * order to draw/measure all the characters
				 * encountered by this font so far. All fonts
				 * start off with one SubFont initialized by
				 * InitFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */
    SubFont controlSubFont;	/* Font to use to display control-character
				 * expansions. */

    Display *display;		/* Display that owns font. */
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
static char **		ListFontOrAlias(Display *display, const char*faceName,
			    int *numNamesPtr);
static unsigned		RankAttributes(FontAttributes *wantPtr,
			    FontAttributes *gotPtr);
static void		ReleaseFont(UnixFont *fontPtr);
static void		ReleaseSubFont(Display *display, SubFont *subFontPtr);
static int		SeenName(const char *name, Tcl_DString *dsPtr);
static int		Ucs2beToUtfProc(void *clientData, const char*src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);
static int		UtfToUcs2beProc(void *clientData, const char*src,
			    int srcLen, int flags, Tcl_EncodingState*statePtr,
			    char *dst, int dstLen, int *srcReadPtr,
			    int *dstWrotePtr, int *dstCharsPtr);

/*
 *-------------------------------------------------------------------------
 *
 * FontPkgCleanup --
 *
 *	This function is called when an application is created. It initializes







<
<
<
<
<
<
<
<







234
235
236
237
238
239
240








241
242
243
244
245
246
247
static char **		ListFontOrAlias(Display *display, const char*faceName,
			    int *numNamesPtr);
static unsigned		RankAttributes(FontAttributes *wantPtr,
			    FontAttributes *gotPtr);
static void		ReleaseFont(UnixFont *fontPtr);
static void		ReleaseSubFont(Display *display, SubFont *subFontPtr);
static int		SeenName(const char *name, Tcl_DString *dsPtr);









/*
 *-------------------------------------------------------------------------
 *
 * FontPkgCleanup --
 *
 *	This function is called when an application is created. It initializes
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
TkpFontPkgInit(
    TCL_UNUSED(TkMainInfo *))	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    SubFont dummy;
    int i;
    Tcl_Encoding ucs2;

    if (tsdPtr->controlFamily.encoding == NULL) {

	Tcl_EncodingType type = {"X11ControlChars", ControlUtfProc, ControlUtfProc, NULL, NULL, 0};
	tsdPtr->controlFamily.refCount = 2;
	tsdPtr->controlFamily.encoding = Tcl_CreateEncoding(&type);
	tsdPtr->controlFamily.isTwoByteFont = 0;

	dummy.familyPtr = &tsdPtr->controlFamily;
	dummy.fontMap = tsdPtr->controlFamily.fontMap;
	for (i = 0x00; i < 0x20; i++) {
	    FontMapInsert(&dummy, i);
	    FontMapInsert(&dummy, i + 0x80);
	}

	/*
	 * UCS-2BE is unicode (UCS-2) in big-endian format. Define this if
	 * if it doesn't exist yet. It is used in iso10646 fonts.
	 */

	ucs2 = Tcl_GetEncoding(NULL, "ucs-2be");
	if (ucs2 == NULL) {
	    Tcl_EncodingType ucs2type = {"ucs-2be", Ucs2beToUtfProc, UtfToUcs2beProc, NULL, NULL, 2};
	    Tcl_CreateEncoding(&ucs2type);
	} else {
	    Tcl_FreeEncoding(ucs2);
	}
	Tcl_CreateThreadExitHandler(FontPkgCleanup, NULL);
    }
}

/*
 *-------------------------------------------------------------------------
 *







<




















<
<
<
<
<
<
<







300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326







327
328
329
330
331
332
333
TkpFontPkgInit(
    TCL_UNUSED(TkMainInfo *))	/* The application being created. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    SubFont dummy;
    int i;


    if (tsdPtr->controlFamily.encoding == NULL) {

	Tcl_EncodingType type = {"X11ControlChars", ControlUtfProc, ControlUtfProc, NULL, NULL, 0};
	tsdPtr->controlFamily.refCount = 2;
	tsdPtr->controlFamily.encoding = Tcl_CreateEncoding(&type);
	tsdPtr->controlFamily.isTwoByteFont = 0;

	dummy.familyPtr = &tsdPtr->controlFamily;
	dummy.fontMap = tsdPtr->controlFamily.fontMap;
	for (i = 0x00; i < 0x20; i++) {
	    FontMapInsert(&dummy, i);
	    FontMapInsert(&dummy, i + 0x80);
	}

	/*
	 * UCS-2BE is unicode (UCS-2) in big-endian format. Define this if
	 * if it doesn't exist yet. It is used in iso10646 fonts.
	 */








	Tcl_CreateThreadExitHandler(FontPkgCleanup, NULL);
    }
}

/*
 *-------------------------------------------------------------------------
 *
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
    dstEnd = dst + dstLen - 6;

    for ( ; src < srcEnd; ) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += TkUtfToUniChar(src, &ch);
	dst[0] = '\\';
	if (((size_t)ch < sizeof(mapChars)) && (mapChars[ch] != 0)) {
	    dst[1] = mapChars[ch];
	    dst += 2;
	} else if ((size_t)ch < 256) {
	    dst[1] = 'x';
	    dst[2] = hexChars[(ch >> 4) & 0xF];







|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
    dstEnd = dst + dstLen - 6;

    for ( ; src < srcEnd; ) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += Tcl_UtfToUniChar(src, &ch);
	dst[0] = '\\';
	if (((size_t)ch < sizeof(mapChars)) && (mapChars[ch] != 0)) {
	    dst[1] = mapChars[ch];
	    dst += 2;
	} else if ((size_t)ch < 256) {
	    dst[1] = 'x';
	    dst[2] = hexChars[(ch >> 4) & 0xF];
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = dst - dstStart;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * Ucs2beToUtfProc --
 *
 *	Convert from UCS-2BE (big-endian 16-bit Unicode) to UTF-8.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
Ucs2beToUtfProc(
    TCL_UNUSED(void *),		/* Not used. */
    const char *src,		/* Source string in Unicode. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    TCL_UNUSED(Tcl_EncodingState *),/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    const char *dstEnd, *dstStart;
    int result, numChars, charLimit = INT_MAX;
    unsigned short ch;

    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    result = TCL_OK;

    /* check alignment with ucs-2 (2 == sizeof(UCS-2)) */
    if ((srcLen % 2) != 0) {
	result = TCL_CONVERT_MULTIBYTE;
	srcLen--;
    }
    /* If last code point is a high surrogate, we cannot handle that yet */
    if ((srcLen >= 2) && ((src[srcLen - 2] & 0xFC) == 0xD8)) {
	result = TCL_CONVERT_MULTIBYTE;
	srcLen -= 2;
    }

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - 4;

    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}

	ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF);
	src += 2 /* sizeof(UTF-16) */;

	/*
	 * Special case for 1-byte utf chars for speed. Make sure we work with
	 * unsigned short-size data.
	 */
	if (ch && ch < 0x80) {
	    *dst++ = (ch & 0xFF);
	} else {
	    dst += Tcl_UniCharToUtf(ch, dst);
	}
    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * UtfToUcs2beProc --
 *
 *	Convert from UTF-8 to UCS-2BE (fixed 2-byte encoding).
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
UtfToUcs2beProc(
    TCL_UNUSED(void *),	/* TableEncodingData that specifies
				 * encoding. */
    const char *src,		/* Source string in UTF-8. */
    int srcLen,			/* Source string length in bytes. */
    int flags,			/* Conversion control flags. */
    TCL_UNUSED(Tcl_EncodingState *),/* Place for conversion routine to store state
				 * information used during a piecewise
				 * conversion. Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst,			/* Output buffer in which converted string is
				 * stored. */
    int dstLen,			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr,		/* Filled with the number of bytes from the
				 * source string that were converted. This may
				 * be less than the original source length if
				 * there was a problem converting some source
				 * characters. */
    int *dstWrotePtr,		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
    int result, numChars;
    int ch;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if (!(flags & TCL_ENCODING_END)) {
	srcClose -= 6;
    }

    dstStart = dst;
    dstEnd = dst + dstLen - 2 /* sizeof(UCS-2) */;

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */
	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += TkUtfToUniChar(src, &ch);
	if (ch > 0xFFFF) {
	    ch = 0xFFFD;
	}

	/*
	 * Ensure big-endianness (store big bits first).
	 */

	*dst++ = (char)((ch >> 8) & 0xFF);
	*dst++ = (char)(ch & 0xFF);
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
 *	Map a platform-specific native font name to a TkFont.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







421
422
423
424
425
426
427


























































































































































































428
429
430
431
432
433
434
	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = dst - dstStart;
    return result;
}



























































































































































































/*
 *---------------------------------------------------------------------------
 *
 * TkpGetNativeFont --
 *
 *	Map a platform-specific native font name to a TkFont.
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
	Tcl_CreateHashEntry(&familyTable, family, &isNew);
    }
    XFreeFontNames(nameList);

    hPtr = Tcl_FirstHashEntry(&familyTable, &search);
    resultPtr = Tcl_NewObj();
    while (hPtr != NULL) {
	strPtr = Tcl_NewStringObj((const char *)Tcl_GetHashKey(&familyTable, hPtr), -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_SetObjResult(interp, resultPtr);

    Tcl_DeleteHashTable(&familyTable);
}







|







669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
	Tcl_CreateHashEntry(&familyTable, family, &isNew);
    }
    XFreeFontNames(nameList);

    hPtr = Tcl_FirstHashEntry(&familyTable, &search);
    resultPtr = Tcl_NewObj();
    while (hPtr != NULL) {
	strPtr = Tcl_NewStringObj((const char *)Tcl_GetHashKey(&familyTable, hPtr), TCL_INDEX_NONE);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_SetObjResult(interp, resultPtr);

    Tcl_DeleteHashTable(&familyTable);
}
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
    UnixFont *fontPtr;
    FontFamily *familyPtr;

    resultPtr = Tcl_NewObj();
    fontPtr = (UnixFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	objv[0] = Tcl_NewStringObj(familyPtr->faceName, -1);
	objv[1] = Tcl_NewStringObj(familyPtr->foundry, -1);
	objv[2] = Tcl_NewStringObj(
		Tcl_GetEncodingName(familyPtr->encoding), -1);
	listPtr = Tcl_NewListObj(3, objv);
	Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*







|
|

|







710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
    UnixFont *fontPtr;
    FontFamily *familyPtr;

    resultPtr = Tcl_NewObj();
    fontPtr = (UnixFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	objv[0] = Tcl_NewStringObj(familyPtr->faceName, TCL_INDEX_NONE);
	objv[1] = Tcl_NewStringObj(familyPtr->foundry, TCL_INDEX_NONE);
	objv[2] = Tcl_NewStringObj(
		Tcl_GetEncodingName(familyPtr->encoding), TCL_INDEX_NONE);
	listPtr = Tcl_NewListObj(3, objv);
	Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
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
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
				 * is unbounded and the flags argument is
				 * ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
				 * which only partially fit on this line.
				 * TK_WHOLE_WORDS means stop on a word
				 * boundary, if possible. TK_AT_LEAST_ONE
				 * means return at least one character even if
				 * no characters fit. */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFont *fontPtr;
    SubFont *lastSubFontPtr;

    int curX, curByte, ch;

    /*
     * Unix does not use kerning or fractional character widths when
     * displaying text on the screen. So that means we can safely measure
     * individual characters or spans of characters and add up the widths w/o
     * any "off-by-one-pixel" errors.
     */







|



















>
|







785
786
787
788
789
790
791
792
793
794
795
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
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    Tcl_Size numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
				 * is unbounded and the flags argument is
				 * ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
				 * which only partially fit on this line.
				 * TK_WHOLE_WORDS means stop on a word
				 * boundary, if possible. TK_AT_LEAST_ONE
				 * means return at least one character even if
				 * no characters fit. */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFont *fontPtr;
    SubFont *lastSubFontPtr;
    Tcl_Size curByte;
    int curX, ch;

    /*
     * Unix does not use kerning or fractional character widths when
     * displaying text on the screen. So that means we can safely measure
     * individual characters or spans of characters and add up the widths w/o
     * any "off-by-one-pixel" errors.
     */
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
	 * 2. Convert those chars to the encoding of that font.
	 * 3. Measure converted chars.
	 */

	curX = 0;
	end = source + numBytes;
	for (p = source; p < end; ) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    if (thisSubFontPtr != lastSubFontPtr) {
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (familyPtr->isTwoByteFont) {
		    curX += XTextWidth16(lastSubFontPtr->fontStructPtr,
			    (XChar2b *) Tcl_DStringValue(&runString),
			    Tcl_DStringLength(&runString) / 2);
		} else {
		    curX += XTextWidth(lastSubFontPtr->fontStructPtr,
			    Tcl_DStringValue(&runString),
			    Tcl_DStringLength(&runString));
		}
		Tcl_DStringFree(&runString);
		lastSubFontPtr = thisSubFontPtr;
		source = p;
	    }
	    p = next;
	}
	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_UtfToExternalDString(familyPtr->encoding, source, p - source,
		&runString);
	if (familyPtr->isTwoByteFont) {
	    curX += XTextWidth16(lastSubFontPtr->fontStructPtr,
		    (XChar2b *) Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> 1);
	} else {
	    curX += XTextWidth(lastSubFontPtr->fontStructPtr,







|



|

















|







839
840
841
842
843
844
845
846
847
848
849
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
	 * 2. Convert those chars to the encoding of that font.
	 * 3. Measure converted chars.
	 */

	curX = 0;
	end = source + numBytes;
	for (p = source; p < end; ) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	    if (thisSubFontPtr != lastSubFontPtr) {
		familyPtr = lastSubFontPtr->familyPtr;
		(void)Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (familyPtr->isTwoByteFont) {
		    curX += XTextWidth16(lastSubFontPtr->fontStructPtr,
			    (XChar2b *) Tcl_DStringValue(&runString),
			    Tcl_DStringLength(&runString) / 2);
		} else {
		    curX += XTextWidth(lastSubFontPtr->fontStructPtr,
			    Tcl_DStringValue(&runString),
			    Tcl_DStringLength(&runString));
		}
		Tcl_DStringFree(&runString);
		lastSubFontPtr = thisSubFontPtr;
		source = p;
	    }
	    p = next;
	}
	familyPtr = lastSubFontPtr->familyPtr;
	(void)Tcl_UtfToExternalDString(familyPtr->encoding, source, p - source,
		&runString);
	if (familyPtr->isTwoByteFont) {
	    curX += XTextWidth16(lastSubFontPtr->fontStructPtr,
		    (XChar2b *) Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> 1);
	} else {
	    curX += XTextWidth(lastSubFontPtr->fontStructPtr,
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

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + TkUtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
	for (p = source; ; ) {
	    if ((ch < BASE_CHARS) && (fontPtr->widths[ch] != 0)) {
		newX += fontPtr->widths[ch];
	    } else {
		lastSubFontPtr = FindSubFontForChar(fontPtr, ch, NULL);
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternal(NULL, familyPtr->encoding, p, next - p, 0, NULL,
			(char *)&buf[0].byte1, sizeof(buf), NULL, &dstWrote, NULL);
		if (familyPtr->isTwoByteFont) {
		    newX += XTextWidth16(lastSubFontPtr->fontStructPtr,
			    buf, dstWrote >> 1);
		} else {
		    newX += XTextWidth(lastSubFontPtr->fontStructPtr,
			    (char *)&buf[0].byte1, dstWrote);
		}
	    }
	    if (newX > maxLength) {
		break;
	    }
	    curX = newX;
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += TkUtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {







|













|




















|







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

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + Tcl_UtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
	for (p = source; ; ) {
	    if ((ch < BASE_CHARS) && (fontPtr->widths[ch] != 0)) {
		newX += fontPtr->widths[ch];
	    } else {
		lastSubFontPtr = FindSubFontForChar(fontPtr, ch, NULL);
		familyPtr = lastSubFontPtr->familyPtr;
		Tcl_UtfToExternal(NULL, familyPtr->encoding, p, next - p, TCL_ENCODING_PROFILE_TCL8, NULL,
			(char *)&buf[0].byte1, sizeof(buf), NULL, &dstWrote, NULL);
		if (familyPtr->isTwoByteFont) {
		    newX += XTextWidth16(lastSubFontPtr->fontStructPtr,
			    buf, dstWrote >> 1);
		} else {
		    newX += XTextWidth(lastSubFontPtr->fontStructPtr,
			    (char *)&buf[0].byte1, dstWrote);
		}
	    }
	    if (newX > maxLength) {
		break;
	    }
	    curX = newX;
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += Tcl_UtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += TkUtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += TkUtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}








|





|







946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += Tcl_UtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += Tcl_UtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}

1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    TCL_UNUSED(int),		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char







|

|
|







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    TCL_UNUSED(Tcl_Size),		/* Maximum number of bytes to consider from
				 * source string in all. */
    Tcl_Size rangeStart,		/* Index of first byte to measure. */
    Tcl_Size rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;







|







1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
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
    window_width = 32768;
#endif

    end = source + numBytes;
    needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {
	    if (p > source) {
		do_width = (needWidth || (p != end)) ? 1 : 0;
		familyPtr = lastSubFontPtr->familyPtr;

		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (familyPtr->isTwoByteFont) {
		    XDrawString16(display, drawable, gc, x, y,
			    (XChar2b *) Tcl_DStringValue(&runString),
			    Tcl_DStringLength(&runString) / 2);
		    if (do_width) {
			x += XTextWidth16(lastSubFontPtr->fontStructPtr,







|











|







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
    window_width = 32768;
#endif

    end = source + numBytes;
    needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {
	    if (p > source) {
		do_width = (needWidth || (p != end)) ? 1 : 0;
		familyPtr = lastSubFontPtr->familyPtr;

		(void)Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		if (familyPtr->isTwoByteFont) {
		    XDrawString16(display, drawable, gc, x, y,
			    (XChar2b *) Tcl_DStringValue(&runString),
			    Tcl_DStringLength(&runString) / 2);
		    if (do_width) {
			x += XTextWidth16(lastSubFontPtr->fontStructPtr,
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(int),		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);







|
|
|







1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(Tcl_Size),		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
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
    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);
}

/*
 *-------------------------------------------------------------------------







|
|
|





>



<
<







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
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(Tcl_Size),		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size rangeLength1,		/* 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 rangeLength = rangeLength1;
    int widthUntilStart;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);



    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

/*
 *-------------------------------------------------------------------------
2010
2011
2012
2013
2014
2015
2016




2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
    const char *const *const *fontFallbacks;
    SubFont *subFontPtr;
    Tcl_DString ds;

    if (ch < 0 || ch >= FONTMAP_NUMCHARS) {
	ch = 0xFFFD;
    }





    for (i = 0; i < fontPtr->numSubFonts; i++) {
	if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
	    return &fontPtr->subFontArray[i];
	}
    }

    if (FontMapLookup(&fontPtr->controlSubFont, ch)) {
	return &fontPtr->controlSubFont;
    }

    /*
     * Keep track of all face names that we check, so we don't check some name
     * multiple times if it can be reached by multiple paths.
     */

    Tcl_DStringInit(&ds);








>
>
>
>







<
<
<
<







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
    const char *const *const *fontFallbacks;
    SubFont *subFontPtr;
    Tcl_DString ds;

    if (ch < 0 || ch >= FONTMAP_NUMCHARS) {
	ch = 0xFFFD;
    }

    if (FontMapLookup(&fontPtr->controlSubFont, ch)) {
	return &fontPtr->controlSubFont;
    }

    for (i = 0; i < fontPtr->numSubFonts; i++) {
	if (FontMapLookup(&fontPtr->subFontArray[i], ch)) {
	    return &fontPtr->subFontArray[i];
	}
    }





    /*
     * Keep track of all face names that we check, so we don't check some name
     * multiple times if it can be reached by multiple paths.
     */

    Tcl_DStringInit(&ds);

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
    /*
     * Try all face names available in the whole system until we find one that
     * can be used.
     */

    nameList = ListFonts(fontPtr->display, "*", &numNames);
    for (i = 0; i < numNames; i++) {
	char *fallbck = strchr(nameList[i] + 1, '-') + 1;
	strchr(fallbck, '-')[0] = '\0';
	if (SeenName(fallbck, &ds) == 0) {
	    subFontPtr = CanUseFallback(fontPtr, fallbck, ch,
		    fixSubFontPtrPtr);
	    if (subFontPtr != NULL) {
		XFreeFontNames(nameList);
		goto end;
	    }
	}
    }







|
|
|
|







1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
    /*
     * Try all face names available in the whole system until we find one that
     * can be used.
     */

    nameList = ListFonts(fontPtr->display, "*", &numNames);
    for (i = 0; i < numNames; i++) {
	fallback = strchr(nameList[i] + 1, '-') + 1;
	strchr(fallback, '-')[0] = '\0';
	if (SeenName(fallback, &ds) == 0) {
	    subFontPtr = CanUseFallback(fontPtr, fallback, ch,
		    fixSubFontPtrPtr);
	    if (subFontPtr != NULL) {
		XFreeFontNames(nameList);
		goto end;
	    }
	}
    }
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
	}
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	int hi, lo;

	if (Tcl_UtfToExternal(NULL, encoding, src, TkUniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (isTwoByteFont) {
	    hi = ((unsigned char *) buf)[0];
	    lo = ((unsigned char *) buf)[1];
	} else {







|
|







2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
	}
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	int hi, lo;

	if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, src),
		TCL_ENCODING_PROFILE_STRICT, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (isTwoByteFont) {
	    hi = ((unsigned char *) buf)[0];
	    lo = ((unsigned char *) buf)[1];
	} else {
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
    display = fontPtr->display;
    nameList = ListFonts(display, faceName, &numNames);
    if (numNames == 0) {
	return NULL;
    }
    nameListOrig = nameList;

    srcLen = TkUniCharToUtf(ch, src);

    want.fa = fontPtr->font.fa;
    want.xa = fontPtr->xa;

    want.fa.family = Tk_GetUid(faceName);
    want.fa.size = (double)-fontPtr->pixelSize;








|







2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
    display = fontPtr->display;
    nameList = ListFonts(display, faceName, &numNames);
    if (numNames == 0) {
	return NULL;
    }
    nameListOrig = nameList;

    srcLen = Tcl_UniCharToUtf(ch, src);

    want.fa = fontPtr->font.fa;
    want.xa = fontPtr->xa;

    want.fa.family = Tk_GetUid(faceName);
    want.fa.size = (double)-fontPtr->pixelSize;

2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
	    }

	    Tcl_DStringAppend(&dsEncodings, (char *) &encoding,
		    sizeof(encoding));
	    numEncodings++;
	}
	Tcl_UtfToExternal(NULL, encoding, src, srcLen,
		TCL_ENCODING_STOPONERROR, NULL, dst, sizeof(dst), &srcRead,
		&dstWrote, NULL);
	if (dstWrote == 0) {
	    goto crossout;
	}

	/*
	 * D. Rank each name and pick the best match.







|







2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
	    }

	    Tcl_DStringAppend(&dsEncodings, (char *) &encoding,
		    sizeof(encoding));
	    numEncodings++;
	}
	Tcl_UtfToExternal(NULL, encoding, src, srcLen,
		TCL_ENCODING_PROFILE_STRICT, NULL, dst, sizeof(dst), &srcRead,
		&dstWrote, NULL);
	if (dstWrote == 0) {
	    goto crossout;
	}

	/*
	 * D. Rank each name and pick the best match.
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775

static XFontStruct *
GetScreenFont(
    Display *display,		/* Display for new XFontStruct. */
    FontAttributes *wantPtr,	/* Contains desired actual pixel-size if the
				 * best font was scalable. */
    char **nameList,		/* Array of XLFDs. */
    int bestIdx[2],		/* Indices into above array for XLFD of best
				 * bitmapped and best scalable font. */
    unsigned bestScore[2])	/* Scores of best bitmapped and best scalable
				 * font. XLFD corresponding to lowest score
				 * will be constructed. */
{
    XFontStruct *fontStructPtr;

    if ((bestIdx[0] < 0) && (bestIdx[1] < 0)) {
	return NULL;







|

|







2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573

static XFontStruct *
GetScreenFont(
    Display *display,		/* Display for new XFontStruct. */
    FontAttributes *wantPtr,	/* Contains desired actual pixel-size if the
				 * best font was scalable. */
    char **nameList,		/* Array of XLFDs. */
    int bestIdx[],		/* Indices into above array for XLFD of best
				 * bitmapped and best scalable font. */
    unsigned bestScore[])	/* Scores of best bitmapped and best scalable
				 * font. XLFD corresponding to lowest score
				 * will be constructed. */
{
    XFontStruct *fontStructPtr;

    if ((bestIdx[0] < 0) && (bestIdx[1] < 0)) {
	return NULL;
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
	    str = strchr(str + 1, '-');
	}
	rest = str;
	for (i = XLFD_PIXEL_SIZE; i < XLFD_CHARSET; i++) {
	    rest = strchr(rest + 1, '-');
	}
	*str = '\0';
	sprintf(buf, "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]],
		(int)(-wantPtr->fa.size+0.5), rest);
	*str = '-';
	fontStructPtr = XLoadQueryFont(display, buf);
	bestScore[1] = INT_MAX;
    }
    if (fontStructPtr == NULL) {
	fontStructPtr = XLoadQueryFont(display, nameList[bestIdx[0]]);







|







2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
	    str = strchr(str + 1, '-');
	}
	rest = str;
	for (i = XLFD_PIXEL_SIZE; i < XLFD_CHARSET; i++) {
	    rest = strchr(rest + 1, '-');
	}
	*str = '\0';
	snprintf(buf, sizeof(buf), "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]],
		(int)(-wantPtr->fa.size+0.5), rest);
	*str = '-';
	fontStructPtr = XLoadQueryFont(display, buf);
	bestScore[1] = INT_MAX;
    }
    if (fontStructPtr == NULL) {
	fontStructPtr = XLoadQueryFont(display, nameList[bestIdx[0]]);
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
    Display *display,		/* Display to query. */
    const char *faceName,	/* Desired face name, or "*" for all. */
    int *numNamesPtr)		/* Filled with length of returned array, or 0
				 * if no names were found. */
{
    char buf[256];

    sprintf(buf, "-*-%.80s-*-*-*-*-*-*-*-*-*-*-*-*", faceName);
    return XListFonts(display, buf, 10000, numNamesPtr);
}

static char **
ListFontOrAlias(
    Display *display,		/* Display to query. */
    const char *faceName,	/* Desired face name, or "*" for all. */







|







2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
    Display *display,		/* Display to query. */
    const char *faceName,	/* Desired face name, or "*" for all. */
    int *numNamesPtr)		/* Filled with length of returned array, or 0
				 * if no names were found. */
{
    char buf[256];

    snprintf(buf, sizeof(buf), "-*-%.80s-*-*-*-*-*-*-*-*-*-*-*-*", faceName);
    return XListFonts(display, buf, 10000, numNamesPtr);
}

static char **
ListFontOrAlias(
    Display *display,		/* Display to query. */
    const char *faceName,	/* Desired face name, or "*" for all. */
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int *realWidthPtr, int *realHeightPtr)
{
    int width, height;
    TkFont *fontPtr = (TkFont *) tkfont;
    Pixmap bitmap;
    GC bitmapGC;
    XGCValues values;







|







2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    int *realWidthPtr, int *realHeightPtr)
{
    int width, height;
    TkFont *fontPtr = (TkFont *) tkfont;
    Pixmap bitmap;
    GC bitmapGC;
    XGCValues values;
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,
    double angle)
{
    if (angle == 0.0) {
	Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y);
    } else {
	double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);







|







2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    double x, double y,
    double angle)
{
    if (angle == 0.0) {
	Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y);
    } else {
	double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

Changes to unix/tkUnixInit.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkUnixInit.c --
 *
 *	This file contains Unix-specific interpreter initialization functions.
 *
 * 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

int
TkpInit(
    Tcl_Interp *interp)
{
    TkCreateXEventSource();
    GetLibraryPath(interp);



    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetAppName --







>
>
>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

int
TkpInit(
    Tcl_Interp *interp)
{
    TkCreateXEventSource();
    GetLibraryPath(interp);
    Tktray_Init(interp);
    (void)SysNotify_Init (interp);
    Icu_Init(interp);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetAppName --
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
    }
    Tcl_DStringAppend(namePtr, name, -1);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --
 *







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	name = "tk";
    } else {
	p = strrchr(name, '/');
	if (p != NULL) {
	    name = p+1;
	}
    }
    Tcl_DStringAppend(namePtr, name, TCL_INDEX_NONE);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWarning --
 *
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
TkpDisplayWarning(
    const char *msg,		/* Message to be displayed. */
    const char *title)		/* Title of warning. */
{
    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);

    if (errChannel) {
	Tcl_WriteChars(errChannel, title, -1);
	Tcl_WriteChars(errChannel, ": ", 2);
	Tcl_WriteChars(errChannel, msg, -1);
	Tcl_WriteChars(errChannel, "\n", 1);
    }
}

#ifdef HAVE_COREFOUNDATION

/*







|

|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
TkpDisplayWarning(
    const char *msg,		/* Message to be displayed. */
    const char *title)		/* Title of warning. */
{
    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);

    if (errChannel) {
	Tcl_WriteChars(errChannel, title, TCL_INDEX_NONE);
	Tcl_WriteChars(errChannel, ": ", 2);
	Tcl_WriteChars(errChannel, msg, TCL_INDEX_NONE);
	Tcl_WriteChars(errChannel, "\n", 1);
    }
}

#ifdef HAVE_COREFOUNDATION

/*

Changes to unix/tkUnixInt.h.

20
21
22
23
24
25
26



27

28
29
30
31
32
33
34
/*
 * Prototypes for procedures that are referenced in files other than the ones
 * they're defined in.
 */

#include "tkIntPlatDecls.h"




#endif /* _TKUNIXINT */


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:







>
>
>

>







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
/*
 * tkUnixKey.c --
 *
 *	This file contains routines for dealing with international keyboard
 *	input.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|







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 © 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"

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Initialized, empty string to hold result. */
{
    TkSizeT len;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */








|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Initialized, empty string to hold result. */
{
    Tcl_Size len;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#ifdef TK_USE_INPUT_METHODS
    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (winPtr->inputContext != NULL)) {
	Status status;

#if X_HAVE_UTF8_STRING
	Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
	len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		&kePtr->keysym, &status);

	if (status == XBufferOverflow) {
	    /*
	     * Expand buffer and try again.
	     */

	    Tcl_DStringSetLength(dsPtr, len);
	    len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		    &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}
	Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */







|
|








|
|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#ifdef TK_USE_INPUT_METHODS
    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (winPtr->inputContext != NULL)) {
	Status status;

#if X_HAVE_UTF8_STRING
	Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
	len = (Tcl_Size)Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(dsPtr), (int)Tcl_DStringLength(dsPtr),
		&kePtr->keysym, &status);

	if (status == XBufferOverflow) {
	    /*
	     * Expand buffer and try again.
	     */

	    Tcl_DStringSetLength(dsPtr, len);
	    len =(Tcl_Size) Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(dsPtr), (int)Tcl_DStringLength(dsPtr),
		    &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}
	Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	 *
	 * Note: XLookupString() normally returns a single ISO Latin 1 or
	 * ASCII control character.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
		TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
	Tcl_DStringValue(&buf)[len] = '\0';

	if (len == 1) {
	    len = TkUniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
		    Tcl_DStringValue(dsPtr));
	    Tcl_DStringSetLength(dsPtr, len);
	} else {
	    /*
	     * len > 1 should only happen if someone has called XRebindKeysym.
	     * Assume UTF-8.
	     */







|




|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	 *
	 * Note: XLookupString() normally returns a single ISO Latin 1 or
	 * ASCII control character.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
	len = (Tcl_Size)XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
		TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
	Tcl_DStringValue(&buf)[len] = '\0';

	if (len == 1) {
	    len = Tcl_UniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
		    Tcl_DStringValue(dsPtr));
	    Tcl_DStringSetLength(dsPtr, len);
	} else {
	    /*
	     * len > 1 should only happen if someone has called XRebindKeysym.
	     * Assume UTF-8.
	     */
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    XModifierKeymap *modMapPtr;
    KeyCode *codePtr;
    KeySym keysym;
    int count, i, j, max, arraySize;

#define KEYCODE_ARRAY_SIZE 20

    dispPtr->bindInfoStale = 0;
    modMapPtr = XGetModifierMapping(dispPtr->display);

    /*
     * Check the keycodes associated with the Lock modifier. If any of them is







|
>







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    XModifierKeymap *modMapPtr;
    KeyCode *codePtr;
    KeySym keysym;
    int count, i, max;
    Tcl_Size j, arraySize;
#define KEYCODE_ARRAY_SIZE 20

    dispPtr->bindInfoStale = 0;
    modMapPtr = XGetModifierMapping(dispPtr->display);

    /*
     * Check the keycodes associated with the Lock modifier. If any of them is

Changes to unix/tkUnixMenu.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkUnixMenu.c --
 *
 *	This module implements the UNIX platform-specific features of menus.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"
#include "tkMenu.h"





|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkUnixMenu.c --
 *
 *	This module implements the UNIX platform-specific features of menus.
 *
 * 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"
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
 * Side effects:
 *	Recompute geometry of given window.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(const char *))
{
    /*
     * Nothing to do.
     */







|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
 * Side effects:
 *	Recompute geometry of given window.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetMainMenubar(
    TCL_UNUSED(Tcl_Interp *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(const char *))
{
    /*
     * Nothing to do.
     */
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing. */
    TkMenuEntry *mePtr,		/* The entry we are interested in. */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    int borderWidth;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (!mePtr->hideMargin && mePtr->indicatorOn) {
	    if ((mePtr->image != NULL) || (mePtr->bitmapPtr != NULL)) {







|
|

|
|
|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,			/* The menu we are drawing. */
    TkMenuEntry *mePtr,			/* The entry we are interested in. */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),	/* The precalculated metrics */
    int *widthPtr,			/* The resulting width */
    int *heightPtr)			/* The resulting height */
{
    int borderWidth;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (!mePtr->hideMargin && mePtr->indicatorOn) {
	    if ((mePtr->image != NULL) || (mePtr->bitmapPtr != NULL)) {
387
388
389
390
391
392
393


394
395
396
397
398
399
400
401
402
403
    TkMenu *menuPtr,		/* The menu was are drawing */
    TkMenuEntry *mePtr,		/* The entry we are getting the geometry for */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The width of the acclerator area */
    int *heightPtr)		/* The height of the accelerator area */
{


    *heightPtr = fmPtr->linespace;
    if (mePtr->type == CASCADE_ENTRY) {
    	*widthPtr = 2 * CASCADE_ARROW_WIDTH;
    } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accelPtr != NULL)) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);

	*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
    } else {
    	*widthPtr = 0;
    }







>
>


|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
    TkMenu *menuPtr,		/* The menu was are drawing */
    TkMenuEntry *mePtr,		/* The entry we are getting the geometry for */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The width of the acclerator area */
    int *heightPtr)		/* The height of the accelerator area */
{
    double scalingLevel = TkScalingLevel(menuPtr->tkwin);

    *heightPtr = fmPtr->linespace;
    if (mePtr->type == CASCADE_ENTRY) {
    	*widthPtr = 2 * CASCADE_ARROW_WIDTH * scalingLevel;
    } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accelPtr != NULL)) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);

	*widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength);
    } else {
    	*widthPtr = 0;
    }
484
485
486
487
488
489
490


491
492
493
494
495
496
497
498
499
500
501
502
503
504



505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
    int y,			/* Top coordinate of entry rect */
    int width,			/* Width of entry */
    int height,			/* Height of entry */
    int drawArrow)		/* Whether or not to draw arrow. */
{
    XPoint points[3];
    int borderWidth, activeBorderWidth;



    /*
     * Draw accelerator or cascade arrow.
     */

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    if ((mePtr->type == CASCADE_ENTRY) && drawArrow) {



    	points[0].x = x + width - borderWidth - activeBorderWidth
		- CASCADE_ARROW_WIDTH;
    	points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2;
    	points[1].x = points[0].x;
    	points[1].y = points[0].y + CASCADE_ARROW_HEIGHT;
    	points[2].x = points[0].x + CASCADE_ARROW_WIDTH;
    	points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2;
    	Tk_Fill3DPolygon(menuPtr->tkwin, d,
		(mePtr->state == ENTRY_ACTIVE) ? activeBorder : bgBorder,
		points, 3, DECORATION_BORDER_WIDTH,
	    	(menuPtr->postedCascade == mePtr)
	    	? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
    } else if (mePtr->accelPtr != NULL) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);
	int left = x + mePtr->labelWidth + activeBorderWidth
		+ mePtr->indicatorSpace;

	if (menuPtr->menuType == MENUBAR) {
	    left += 5;







>
>














>
>
>
|
<
|

|
|
|



|
|







486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
    int y,			/* Top coordinate of entry rect */
    int width,			/* Width of entry */
    int height,			/* Height of entry */
    int drawArrow)		/* Whether or not to draw arrow. */
{
    XPoint points[3];
    int borderWidth, activeBorderWidth;
    int arrowWidth = CASCADE_ARROW_WIDTH, arrowHeight = CASCADE_ARROW_HEIGHT;
    double scalingLevel = TkScalingLevel(menuPtr->tkwin);

    /*
     * Draw accelerator or cascade arrow.
     */

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
	    &activeBorderWidth);
    if ((mePtr->type == CASCADE_ENTRY) && drawArrow) {
	arrowWidth *= scalingLevel;
	arrowHeight *= scalingLevel;

    	points[0].x = x + width - borderWidth - activeBorderWidth - arrowWidth;

    	points[0].y = y + (height - arrowHeight)/2;
    	points[1].x = points[0].x;
    	points[1].y = points[0].y + arrowHeight;
    	points[2].x = points[0].x + arrowWidth;
    	points[2].y = points[0].y + arrowHeight/2;
    	Tk_Fill3DPolygon(menuPtr->tkwin, d,
		(mePtr->state == ENTRY_ACTIVE) ? activeBorder : bgBorder,
		points, 3, DECORATION_BORDER_WIDTH,
	    	(menuPtr->postedCascade == mePtr) ?
		TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
    } else if (mePtr->accelPtr != NULL) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);
	int left = x + mePtr->labelWidth + activeBorderWidth
		+ mePtr->indicatorSpace;

	if (menuPtr->menuType == MENUBAR) {
	    left += 5;
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DrawMenuEntryIndicator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable to draw into */
    Tk_3DBorder border,		/* The background color */
    XColor *indicatorColor,	/* The color to draw indicators with */
    XColor *disableColor,	/* The color use use when disabled */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The font metrics of the font */
    int x,			/* The left of the entry rect */
    int y,			/* The top of the entry rect */
    TCL_UNUSED(int),			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    /*
     * Draw check-button indicator.
     */

    if ((mePtr->type == CHECK_BUTTON_ENTRY) && mePtr->indicatorOn) {
	int top, left, activeBorderWidth;







|
|
|
|
|
|

|
|
|

|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DrawMenuEntryIndicator(
    TkMenu *menuPtr,			/* The menu we are drawing */
    TkMenuEntry *mePtr,			/* The entry we are drawing */
    Drawable d,				/* The drawable to draw into */
    Tk_3DBorder border,			/* The background color */
    XColor *indicatorColor,		/* The color to draw indicators with */
    XColor *disableColor,		/* The color use use when disabled */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),	/* The font metrics of the font */
    int x,				/* The left of the entry rect */
    int y,				/* The top of the entry rect */
    TCL_UNUSED(int),			/* Width of menu entry */
    int height)				/* Height of menu entry */
{
    /*
     * Draw check-button indicator.
     */

    if ((mePtr->type == CHECK_BUTTON_ENTRY) && mePtr->indicatorOn) {
	int top, left, activeBorderWidth;
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DrawMenuSeparator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* The drawable we are using */
    TCL_UNUSED(GC),			/* The gc to draw into */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The font metrics from the font */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    Tk_3DBorder border;
    if (menuPtr->menuType == MENUBAR) {
	return;







|

|


|







622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DrawMenuSeparator(
    TkMenu *menuPtr,			/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,				/* The drawable we are using */
    TCL_UNUSED(GC),			/* The gc to draw into */
    TCL_UNUSED(Tk_Font),		/* The font to draw with */
    TCL_UNUSED(const Tk_FontMetrics *),	/* The font metrics from the font */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    Tk_3DBorder border;
    if (menuPtr->menuType == MENUBAR) {
	return;
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x, int y,
    TCL_UNUSED(int), int height)
{
    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;

	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len) {
	    int activeBorderWidth, leftEdge, ch;
	    const char *label, *start, *end;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = start + TkUtfToUniChar(start, &ch);

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    leftEdge = x + mePtr->indicatorSpace + activeBorderWidth;
	    if (menuPtr->menuType == MENUBAR) {
		leftEdge += 5;
	    }







|



|




|
|







853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x, int y,
    TCL_UNUSED(int), int height)
{
    if (mePtr->labelPtr != NULL) {
	int len;

	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len && mePtr->underline >= -len) {
	    int activeBorderWidth, leftEdge, ch;
	    const char *label, *start, *end;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, (mePtr->underline < 0) ? mePtr->underline + len : mePtr->underline);
	    end = start + Tcl_UtfToUniChar(start, &ch);

	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    leftEdge = x + mePtr->indicatorSpace + activeBorderWidth;
	    if (menuPtr->menuType == MENUBAR) {
		leftEdge += 5;
	    }
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    int x, int y, int index)
{
    return TkpPostTearoffMenu(interp, menuPtr, x, y, index);
}

/*
 *----------------------------------------------------------------------
 *







|







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    int x, int y, Tcl_Size index)
{
    return TkpPostTearoffMenu(interp, menuPtr, x, y, index);
}

/*
 *----------------------------------------------------------------------
 *
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
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter of the menu */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, int index)	/* The root X,Y coordinates where the
				 * specified entry will be posted */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;

    if (index >= (int)menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }













    /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 1. If a virtual root window manager is being used then the coordinates
     *    are in the virtual root window of menuPtr's parent; since the menu







|

|





<
<
<
<
<
<
<
|














>
>
>
>
>
>
>
>
>
>
>
>







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
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),	/* The interpreter of the menu */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, Tcl_Size index)	/* The root X,Y coordinates where the
				 * specified entry will be posted */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;








    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*
     * Adjust the menu y position so that the specified entry will be located
     * at the given coordinates.
     */

    if (index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 1. If a virtual root window manager is being used then the coordinates
     *    are in the virtual root window of menuPtr's parent; since the menu
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
 */

static void
GetMenuSeparatorGeometry(
    TCL_UNUSED(TkMenu *),		/* The menu we are measuring */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    *widthPtr = 0;
    *heightPtr = fmPtr->linespace;
}

/*
 *----------------------------------------------------------------------







|
|
|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
 */

static void
GetMenuSeparatorGeometry(
    TCL_UNUSED(TkMenu *),		/* The menu we are measuring */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,	/* The precalcualted font metrics */
    int *widthPtr,			/* The resulting width */
    int *heightPtr)			/* The resulting height */
{
    *widthPtr = 0;
    *heightPtr = fmPtr->linespace;
}

/*
 *----------------------------------------------------------------------
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
	*widthPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
	*widthPtr = Tk_TextWidth(tkfont, "W", 1);







|

|
|
|
|







1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,			/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    Tk_Font tkfont,			/* The precalculated font */
    const Tk_FontMetrics *fmPtr,	/* The precalculated font metrics */
    int *widthPtr,			/* The resulting width */
    int *heightPtr)			/* The resulting height */
{
    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
	*widthPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
	*widthPtr = Tk_TextWidth(tkfont, "W", 1);
1083
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098

void
TkpComputeMenubarGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int width, height, i, j, x, y, currentRowHeight, maxWidth;

    int maxWindowWidth, lastRowBreak, lastEntry;
    int activeBorderWidth, helpMenuIndex = -1;
    TkMenuEntry *mePtr;

    if (menuPtr->tkwin == NULL) {
	return;
    }








|
>
|







1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110

void
TkpComputeMenubarGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int width, height, x, y, currentRowHeight, maxWidth;
    Tcl_Size i, j, lastRowBreak;
    int maxWindowWidth, lastEntry;
    int activeBorderWidth, helpMenuIndex = -1;
    TkMenuEntry *mePtr;

    if (menuPtr->tkwin == NULL) {
	return;
    }

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
	 * has a font set, we will measure it as we come to it, and then we
	 * decide which set to give the geometry routines.
	 */

	menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
	Tk_GetFontMetrics(menuFont, &menuMetrics);

	for (i = 0; i < (int)menuPtr->numEntries; i++) {
	    mePtr = menuPtr->entries[i];
	    mePtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    if (mePtr->fontPtr != NULL) {
		tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
		Tk_GetFontMetrics(tkfont, &entryMetrics);
		fmPtr = &entryMetrics;
	    } else {







|







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
	 * has a font set, we will measure it as we come to it, and then we
	 * decide which set to give the geometry routines.
	 */

	menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
	Tk_GetFontMetrics(menuFont, &menuMetrics);

	for (i = 0; i < menuPtr->numEntries; i++) {
	    mePtr = menuPtr->entries[i];
	    mePtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    if (mePtr->fontPtr != NULL) {
		tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
		Tk_GetFontMetrics(tkfont, &entryMetrics);
		fmPtr = &entryMetrics;
	    } else {
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
	    lastEntry--;
	}
	if ((lastEntry >= 0) && (x + menuPtr->entries[lastEntry]->width
		+ borderWidth > maxWidth)) {
	    maxWidth = x + menuPtr->entries[lastEntry]->width + borderWidth;
	}
	x = borderWidth;
	for (j = lastRowBreak; j < (int)menuPtr->numEntries; j++) {
	    if (j == helpMenuIndex) {
		continue;
	    }
	    menuPtr->entries[j]->y = y + currentRowHeight
		    - menuPtr->entries[j]->height;
	    menuPtr->entries[j]->x = x;
	    x += menuPtr->entries[j]->width;







|







1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
	    lastEntry--;
	}
	if ((lastEntry >= 0) && (x + menuPtr->entries[lastEntry]->width
		+ borderWidth > maxWidth)) {
	    maxWidth = x + menuPtr->entries[lastEntry]->width + borderWidth;
	}
	x = borderWidth;
	for (j = lastRowBreak; j < menuPtr->numEntries; j++) {
	    if (j == helpMenuIndex) {
		continue;
	    }
	    menuPtr->entries[j]->y = y + currentRowHeight
		    - menuPtr->entries[j]->height;
	    menuPtr->entries[j]->x = x;
	    x += menuPtr->entries[j]->width;
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DrawTearoffEntry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    TCL_UNUSED(GC),			/* The gc we are drawing with */
    TCL_UNUSED(Tk_Font),		/* The font we are drawing with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;








|

|


|







1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
 *	Commands are output to X to display the menu in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DrawTearoffEntry(
    TkMenu *menuPtr,			/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,				/* The drawable we are drawing into */
    TCL_UNUSED(GC),			/* The gc we are drawing with */
    TCL_UNUSED(Tk_Font),		/* The font we are drawing with */
    TCL_UNUSED(const Tk_FontMetrics *),	/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter to set. */
    TCL_UNUSED(Tk_BindingTable))
				/* The table to add to. */
{
    /*
     * Nothing to do.
     */
}

/*







|
<







1328
1329
1330
1331
1332
1333
1334
1335

1336
1337
1338
1339
1340
1341
1342
 *
 *--------------------------------------------------------------
 */

void
TkpInitializeMenuBindings(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter to set. */
    TCL_UNUSED(Tk_BindingTable))	/* The table to add to. */

{
    /*
     * Nothing to do.
     */
}

/*
1671
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681
1682
1683
1684
1685
void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int x, y, height, width, indicatorSpace, labelWidth, accelWidth;
    int windowWidth, windowHeight, accelSpace, i, j, lastColumnBreak = 0;

    TkMenuEntry *mePtr;
    int borderWidth, activeBorderWidth;

    if (menuPtr->tkwin == NULL) {
	return;
    }








|
>







1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int x, y, height, width, indicatorSpace, labelWidth, accelWidth;
    int windowWidth, windowHeight, accelSpace;
    Tcl_Size i, j, lastColumnBreak = 0;
    TkMenuEntry *mePtr;
    int borderWidth, activeBorderWidth;

    if (menuPtr->tkwin == NULL) {
	return;
    }

1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
     * and give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);

    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);







|







1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
     * and give all of the geometry/drawing the entry's font and metrics.
     */

    menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
    Tk_GetFontMetrics(menuFont, &menuMetrics);
    accelSpace = Tk_TextWidth(menuFont, "M", 1);

    for (i = 0; i < menuPtr->numEntries; i++) {
	mePtr = menuPtr->entries[i];
	if (mePtr->fontPtr == NULL) {
	    tkfont = menuFont;
	    fmPtr = &menuMetrics;
	} else {
	    tkfont = Tk_GetFontFromObj(menuPtr->tkwin, mePtr->fontPtr);
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < (int)menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }







|







1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < menuPtr->numEntries; j++) {
	menuPtr->entries[j]->indicatorSpace = indicatorSpace;
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }

Changes to unix/tkUnixMenubu.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkUnixMenubu.c --
 *
 *	This file implements the Unix specific portion of the menubutton
 *	widget.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 *
 * 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"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkUnixMenubu.c --
 *
 *	This file implements the Unix specific portion of the menubutton
 *	widget.
 *
 * Copyright © 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"
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 *	mode.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization needed only to stop compiler
				 * warning. */







|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 *	mode.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    void *clientData)	/* Information about widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization needed only to stop compiler
				 * warning. */
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
 *	Restores the default control state.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TkMenuButton *mbPtr)
{
    (void)mbPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --
 *







|

<







313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
 *	Restores the default control state.
 *
 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TCL_UNUSED(TkMenuButton *))
{

}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --
 *
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
	haveImage = 1;
    }

    if (haveImage == 0 || mbPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(mbPtr->textLayout);

	mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,
		-1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,
		&mbPtr->textHeight);
	txtWidth = mbPtr->textWidth;
	txtHeight = mbPtr->textHeight;
	avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(mbPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }







|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
	haveImage = 1;
    }

    if (haveImage == 0 || mbPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(mbPtr->textLayout);

	mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,
		TCL_INDEX_NONE, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,
		&mbPtr->textHeight);
	txtWidth = mbPtr->textWidth;
	txtHeight = mbPtr->textHeight;
	avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(mbPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

Changes to unix/tkUnixPort.h.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
#   include <tcl.h>
#endif
#if TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#   if HAVE_SYS_TIME_H
#	include <sys/time.h>
#   else
#	include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>







<









<
<
<
<
|

<
<
<

|
|
<







22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37




38
39



40
41
42

43
44
45
46
47
48
49
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#ifndef _TCL
#   include <tcl.h>
#endif




#ifdef HAVE_SYS_TIME_H
#	include <sys/time.h>



#endif
#include <time.h>
#include <inttypes.h>

#include <unistd.h>
#if defined(__GNUC__) && !defined(__cplusplus)
#   pragma GCC diagnostic ignored "-Wc++-compat"
#endif
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#define TkpButtonSetDefaults() {}
#define TkpDestroyButton(butPtr) {}
#define TkSelUpdateClipboard(a,b) {}
#ifndef __CYGWIN__
#define TkSetPixmapColormap(p,c) {}
#endif

/*
 * These calls implement native bitmaps which are not supported under
 * UNIX.  The macros eliminate the calls.
 */

#define TkpDefineNativeBitmaps()
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None

/*
 * This macro stores a representation of the window handle in a string.
 * This should perhaps use the real size of an XID.
 */

#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "%#08lx", (unsigned long) (w))
#endif

/*
 * Used by tkWindow.c
 */

#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)

#endif /* _UNIXPORT */







<
<
<
<
<
<
<
<
<







|


<
<
<
<
<
<

141
142
143
144
145
146
147









148
149
150
151
152
153
154
155
156
157






158
#define TkpButtonSetDefaults() {}
#define TkpDestroyButton(butPtr) {}
#define TkSelUpdateClipboard(a,b) {}
#ifndef __CYGWIN__
#define TkSetPixmapColormap(p,c) {}
#endif










/*
 * This macro stores a representation of the window handle in a string.
 * This should perhaps use the real size of an XID.
 */

#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
	snprintf((buf), TCL_INTEGER_SPACE, "0x%lx", (unsigned long) (w))
#endif







#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
/*
 * tkUnixRFont.c --
 *
 *	Alternate implementation of tkUnixFont.c using Xft.
 *
 * Copyright (c) 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;





|








<







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 © 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>


#define MAX_CACHED_COLORS 16

typedef struct {
    XftFont *ftFont;
    XftFont *ft0Font;
    FcPattern *source;
50
51
52
53
54
55
56




57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 * the information isn't retrievable from the GC.
 */

typedef struct {
    Region clipRegion;		/* The clipping region, or None. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;





/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --
 *
 *	This procedure is called when an application is created. It
 *	initializes all the structures that are used by the
 *	platform-dependant code on a per application basis.
 *	Note that this is called before TkpInit() !
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */


static int utf8ToUcs4(const char *source, FcChar32 *c, int numBytes)
{
    if (numBytes >= 6) {
    	return TkUtfToUniChar(source, (int *)c);
    }
    return FcUtf8ToUcs4((const FcChar8 *)source, c, numBytes);
}

void
TkpFontPkgInit(
    TkMainInfo *mainPtr)	/* The application being created. */
{
    (void)mainPtr;
}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4,
    double angle)







>
>
>
>




















<
|


|






|

<







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
 * the information isn't retrievable from the GC.
 */

typedef struct {
    Region clipRegion;		/* The clipping region, or None. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

TCL_DECLARE_MUTEX(xftMutex);
#define LOCK Tcl_MutexLock(&xftMutex)
#define UNLOCK Tcl_MutexUnlock(&xftMutex)

/*
 *-------------------------------------------------------------------------
 *
 * TkpFontPkgInit --
 *
 *	This procedure is called when an application is created. It
 *	initializes all the structures that are used by the
 *	platform-dependant code on a per application basis.
 *	Note that this is called before TkpInit() !
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */


static Tcl_Size utf8ToUcs4(const char *source, FcChar32 *c, Tcl_Size numBytes)
{
    if (numBytes >= 6) {
    	return Tcl_UtfToUniChar(source, (int *)c);
    }
    return FcUtf8ToUcs4((const FcChar8 *)source, c, numBytes);
}

void
TkpFontPkgInit(
    TCL_UNUSED(TkMainInfo *))	/* The application being created. */
{

}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4,
    double angle)
128
129
130
131
132
133
134

135

136
137
138
139
140
141
142
143

144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162

163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

	mat.xx = mat.yy = c;
	mat.xy = -(mat.yx = s);

	if (angle != 0.0) {
	    FcPatternAddMatrix(pat, FC_MATRIX, &mat);
	}

	ftFont = XftFontOpenPattern(fontPtr->display, pat);

	if (!ftFont) {
	    /*
	     * The previous call to XftFontOpenPattern() should not fail, but
	     * sometimes does anyway. Usual cause appears to be a
	     * misconfigured fontconfig installation; see [Bug 1090382]. Try a
	     * fallback:
	     */


	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
		    FC_FAMILY, FcTypeString, "sans",
		    FC_SIZE, FcTypeDouble, 12.0,
		    FC_MATRIX, FcTypeMatrix, &mat,
		    NULL);

	}
	if (!ftFont) {
	    /*
	     * The previous call should definitely not fail. Impossible to
	     * proceed at this point.
	     */

	    Tcl_Panic("Cannot find a usable font");
	}

	if (angle == 0.0) {
	    fontPtr->faces[i].ft0Font = ftFont;
	} else {
	    if (fontPtr->faces[i].ftFont) {

		XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);

	    }
	    fontPtr->faces[i].ftFont = ftFont;
	    fontPtr->faces[i].angle = angle;
	}
    }
    return (angle==0.0? fontPtr->faces[i].ft0Font : fontPtr->faces[i].ftFont);
}

/*
 *---------------------------------------------------------------------------
 *
 * GetTkFontAttributes --
 * 	Fill in TkFontAttributes from an XftFont.
 */

static void
GetTkFontAttributes(

    XftFont *ftFont,
    TkFontAttributes *faPtr)
{
    const char *family = "Unknown";
    const char *const *familyPtr = &family;
    int weight, slant, pxsize;
    double size, ptsize;

    (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
    if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = ptsize;
    } else if (XftPatternGetDouble(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = -ptsize;
    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &pxsize) == XftResultMatch) {
	size = (double)-pxsize;
    } else {
	size = 12.0;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,







>

>








>





>














>

>

















>









|

|
|

|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

	mat.xx = mat.yy = c;
	mat.xy = -(mat.yx = s);

	if (angle != 0.0) {
	    FcPatternAddMatrix(pat, FC_MATRIX, &mat);
	}
	LOCK;
	ftFont = XftFontOpenPattern(fontPtr->display, pat);
	UNLOCK;
	if (!ftFont) {
	    /*
	     * The previous call to XftFontOpenPattern() should not fail, but
	     * sometimes does anyway. Usual cause appears to be a
	     * misconfigured fontconfig installation; see [Bug 1090382]. Try a
	     * fallback:
	     */

	    LOCK;
	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
		    FC_FAMILY, FcTypeString, "sans",
		    FC_SIZE, FcTypeDouble, 12.0,
		    FC_MATRIX, FcTypeMatrix, &mat,
		    NULL);
	    UNLOCK;
	}
	if (!ftFont) {
	    /*
	     * The previous call should definitely not fail. Impossible to
	     * proceed at this point.
	     */

	    Tcl_Panic("Cannot find a usable font");
	}

	if (angle == 0.0) {
	    fontPtr->faces[i].ft0Font = ftFont;
	} else {
	    if (fontPtr->faces[i].ftFont) {
		LOCK;
		XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
		UNLOCK;
	    }
	    fontPtr->faces[i].ftFont = ftFont;
	    fontPtr->faces[i].angle = angle;
	}
    }
    return (angle==0.0? fontPtr->faces[i].ft0Font : fontPtr->faces[i].ftFont);
}

/*
 *---------------------------------------------------------------------------
 *
 * GetTkFontAttributes --
 * 	Fill in TkFontAttributes from an XftFont.
 */

static void
GetTkFontAttributes(
    Tk_Window tkwin,
    XftFont *ftFont,
    TkFontAttributes *faPtr)
{
    const char *family = "Unknown";
    const char *const *familyPtr = &family;
    int weight, slant, pxsize;
    double size, ptsize;

    (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
    if (XftPatternGetDouble(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = -ptsize;
    } else if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = ptsize;
    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &pxsize) == XftResultMatch) {
	size = (double)-pxsize;
    } else {
	size = 12.0;
    }
    if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

#ifdef DEBUG_FONTSEL
    printf("family %s size %d weight %d slant %d\n",
	    family, (int)size, weight, slant);
#endif /* DEBUG_FONTSEL */

    faPtr->family = Tk_GetUid(family);
    faPtr->size = size;
    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = 0;
    faPtr->overstrike = 0;
}

/*







|







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

#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 = TkFontGetPoints(tkwin, size);
    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
    faPtr->underline = 0;
    faPtr->overstrike = 0;
}

/*
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

static void
FinishedWithFont(
    UnixFtFont *fontPtr);

static int
InitFontErrorProc(
    ClientData clientData,
    TCL_UNUSED(XErrorEvent *))
{
    int *errorFlagPtr = (int *)clientData;

    if (errorFlagPtr != NULL) {
	*errorFlagPtr = 1;
    }







|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

static void
FinishedWithFont(
    UnixFtFont *fontPtr);

static int
InitFontErrorProc(
    void *clientData,
    TCL_UNUSED(XErrorEvent *))
{
    int *errorFlagPtr = (int *)clientData;

    if (errorFlagPtr != NULL) {
	*errorFlagPtr = 1;
    }
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

    /*
     * Fill in platform-specific fields of TkFont.
     */

    errorFlag = 0;
    handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
		    -1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
    ftFont = GetFont(fontPtr, 0, 0.0);
    if ((ftFont == NULL) || errorFlag) {
	Tk_DeleteErrorHandler(handler);
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);
    Tk_DeleteErrorHandler(handler);
    if (errorFlag) {
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }







|








|







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

    /*
     * Fill in platform-specific fields of TkFont.
     */

    errorFlag = 0;
    handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
		    -1, -1, -1, InitFontErrorProc, (void *) &errorFlag);
    ftFont = GetFont(fontPtr, 0, 0.0);
    if ((ftFont == NULL) || errorFlag) {
	Tk_DeleteErrorHandler(handler);
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }
    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
    GetTkFontAttributes(tkwin, ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);
    Tk_DeleteErrorHandler(handler);
    if (errorFlag) {
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
     */

    {
	TkFont *fPtr = &fontPtr->font;

	fPtr->underlinePos = fPtr->fm.descent / 2;
	handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
			-1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
	errorFlag = 0;
	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
	Tk_DeleteErrorHandler(handler);
	if (errorFlag) {
	    FinishedWithFont(fontPtr);
	    ckfree(fontPtr);
	    return NULL;







|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
     */

    {
	TkFont *fPtr = &fontPtr->font;

	fPtr->underlinePos = fPtr->fm.descent / 2;
	handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
			-1, -1, -1, InitFontErrorProc, (void *) &errorFlag);
	errorFlag = 0;
	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
	Tk_DeleteErrorHandler(handler);
	if (errorFlag) {
	    FinishedWithFont(fontPtr);
	    ckfree(fontPtr);
	    return NULL;
415
416
417
418
419
420
421

422

423
424

425

426
427
428
429
430
431
432
    Display *display = fontPtr->display;
    int i;
    Tk_ErrorHandler handler =
	    Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

    for (i = 0; i < fontPtr->nfaces; i++) {
	if (fontPtr->faces[i].ftFont) {

	    XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);

	}
	if (fontPtr->faces[i].ft0Font) {

	    XftFontClose(fontPtr->display, fontPtr->faces[i].ft0Font);

	}
	if (fontPtr->faces[i].charset) {
	    FcCharSetDestroy(fontPtr->faces[i].charset);
	}
    }
    if (fontPtr->faces) {
	ckfree(fontPtr->faces);







>

>


>

>







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
    Display *display = fontPtr->display;
    int i;
    Tk_ErrorHandler handler =
	    Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

    for (i = 0; i < fontPtr->nfaces; i++) {
	if (fontPtr->faces[i].ftFont) {
	    LOCK;
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
	    UNLOCK;
	}
	if (fontPtr->faces[i].ft0Font) {
	    LOCK;
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ft0Font);
	    UNLOCK;
	}
	if (fontPtr->faces[i].charset) {
	    FcCharSetDestroy(fontPtr->faces[i].charset);
	}
    }
    if (fontPtr->faces) {
	ckfree(fontPtr->faces);
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
{
    XftPattern *pattern;
    int weight, slant;
    UnixFtFont *fontPtr;

#ifdef DEBUG_FONTSEL
    printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
	    faPtr->size, faPtr->weight, faPtr->slant);
#endif /* DEBUG_FONTSEL */
    pattern = XftPatternCreate();
    if (faPtr->family) {
	XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
    }
    if (faPtr->size > 0.0) {
	XftPatternAddDouble(pattern, XFT_SIZE, faPtr->size);
    } else if (faPtr->size < 0.0) {
	XftPatternAddDouble(pattern, XFT_SIZE, TkFontGetPoints(tkwin, faPtr->size));
    } else {
	XftPatternAddDouble(pattern, XFT_SIZE, 12.0);
    }
    switch (faPtr->weight) {
    case TK_FW_NORMAL:
    default:
	weight = XFT_WEIGHT_MEDIUM;







|








|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
{
    XftPattern *pattern;
    int weight, slant;
    UnixFtFont *fontPtr;

#ifdef DEBUG_FONTSEL
    printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
	    (int)faPtr->size, faPtr->weight, faPtr->slant);
#endif /* DEBUG_FONTSEL */
    pattern = XftPatternCreate();
    if (faPtr->family) {
	XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
    }
    if (faPtr->size > 0.0) {
	XftPatternAddDouble(pattern, XFT_SIZE, faPtr->size);
    } else if (faPtr->size < 0.0) {
	XftPatternAddDouble(pattern, XFT_PIXEL_SIZE, -faPtr->size);
    } else {
	XftPatternAddDouble(pattern, XFT_SIZE, 12.0);
    }
    switch (faPtr->weight) {
    case TK_FW_NORMAL:
    default:
	weight = XFT_WEIGHT_MEDIUM;
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
		(char *) 0,		/* pattern elements */
		XFT_FAMILY, (char*) 0);	/* fields */
    for (i = 0; i < list->nfont; i++) {
	char *family, **familyPtr = &family;

	if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0, familyPtr)
		== XftResultMatch) {
	    Tcl_Obj *strPtr = Tcl_NewStringObj(family, -1);

	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
    }
    XftFontSetDestroy(list);

    Tcl_SetObjResult(interp, resultPtr);







|







609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
		(char *) 0,		/* pattern elements */
		XFT_FAMILY, (char*) 0);	/* fields */
    for (i = 0; i < list->nfont; i++) {
	char *family, **familyPtr = &family;

	if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0, familyPtr)
		== XftResultMatch) {
	    Tcl_Obj *strPtr = Tcl_NewStringObj(family, TCL_INDEX_NONE);

	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
    }
    XftFontSetDestroy(list);

    Tcl_SetObjResult(interp, resultPtr);
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
    for (i = 0; i < fontPtr->nfaces ; ++i) {
 	pattern = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);

	XftPatternGetString(pattern, XFT_FAMILY, 0, familyPtr);
	XftPatternGetString(pattern, XFT_FOUNDRY, 0, foundryPtr);
	XftPatternGetString(pattern, XFT_ENCODING, 0, encodingPtr);
	objv[0] = Tcl_NewStringObj(family, -1);
	objv[1] = Tcl_NewStringObj(foundry, -1);
	objv[2] = Tcl_NewStringObj(encoding, -1);
	listPtr = Tcl_NewListObj(3, objv);
	Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *
 *	Retrieve the font attributes of the actual font used to render a given
 *	character.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),	/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */
    FcChar32 ucs4 = (FcChar32) c;
				/* UCS-4 character to map */
    XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0);
				/* Actual font used to render the character */

    GetTkFontAttributes(ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
				 * is unbounded and the flags argument is
				 * ignored. */







|
|
|



















|











|









|







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    for (i = 0; i < fontPtr->nfaces ; ++i) {
 	pattern = FcFontRenderPrepare(0, fontPtr->pattern,
		fontPtr->faces[i].source);

	XftPatternGetString(pattern, XFT_FAMILY, 0, familyPtr);
	XftPatternGetString(pattern, XFT_FOUNDRY, 0, foundryPtr);
	XftPatternGetString(pattern, XFT_ENCODING, 0, encodingPtr);
	objv[0] = Tcl_NewStringObj(family, TCL_INDEX_NONE);
	objv[1] = Tcl_NewStringObj(foundry, TCL_INDEX_NONE);
	objv[2] = Tcl_NewStringObj(encoding, TCL_INDEX_NONE);
	listPtr = Tcl_NewListObj(3, objv);
	Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetFontAttrsForChar --
 *
 *	Retrieve the font attributes of the actual font used to render a given
 *	character.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
				/* Structure describing the logical font */
    FcChar32 ucs4 = (FcChar32) c;
				/* UCS-4 character to map */
    XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0);
				/* Actual font used to render the character */

    GetTkFontAttributes(tkwin, ftFont, faPtr);
    faPtr->underline = fontPtr->font.fa.underline;
    faPtr->overstrike = fontPtr->font.fa.overstrike;
}

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    Tcl_Size numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
				 * is unbounded and the flags argument is
				 * ignored. */
711
712
713
714
715
716
717

718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

764

765
766
767
768
769
770
771
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XftFont *ftFont;
    FcChar32 c;
    XGlyphInfo extents;

    int clen, curX, newX, curByte, newByte, sawNonSpace;
    int termByte = 0, termX = 0, errorFlag = 0;
    Tk_ErrorHandler handler;
#ifdef DEBUG_FONTSEL
    char string[256];
    int len = 0;
#endif /* DEBUG_FONTSEL */

    handler = Tk_CreateErrorHandler(fontPtr->display,
	    -1, -1, -1, InitFontErrorProc, &errorFlag);
    curX = 0;
    curByte = 0;
    sawNonSpace = 0;
    while (numBytes > 0) {
	int unichar;

	clen = TkUtfToUniChar(source, &unichar);
	c = (FcChar32) unichar;

	if (clen <= 0) {
	    /*
	     * This can't happen (but see #1185640)
	     */

	    *lengthPtr = curX;
	    return curByte;
	}

	source += clen;
	numBytes -= clen;
	if (c < 256 && isspace(c)) {		/* I18N: ??? */
	    if (sawNonSpace) {
		termByte = curByte;
		termX = curX;
		sawNonSpace = 0;
	    }
	} else {
	    sawNonSpace = 1;
	}

#ifdef DEBUG_FONTSEL
	string[len++] = (char) c;
#endif /* DEBUG_FONTSEL */
	ftFont = GetFont(fontPtr, c, 0.0);

	if (!errorFlag) {

	    XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);

	} else {
	    extents.xOff = 0;
	    errorFlag = 0;
	}

	newX = curX + extents.xOff;
	newByte = curByte + clen;







>
|















|







<
|




















>

>







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754

755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XftFont *ftFont;
    FcChar32 c;
    XGlyphInfo extents;
    Tcl_Size clen;
    int curX, newX, curByte, newByte, sawNonSpace;
    int termByte = 0, termX = 0, errorFlag = 0;
    Tk_ErrorHandler handler;
#ifdef DEBUG_FONTSEL
    char string[256];
    int len = 0;
#endif /* DEBUG_FONTSEL */

    handler = Tk_CreateErrorHandler(fontPtr->display,
	    -1, -1, -1, InitFontErrorProc, &errorFlag);
    curX = 0;
    curByte = 0;
    sawNonSpace = 0;
    while (numBytes > 0) {
	int unichar;

	clen = Tcl_UtfToUniChar(source, &unichar);
	c = (FcChar32) unichar;

	if (clen <= 0) {
	    /*
	     * This can't happen (but see #1185640)
	     */


	    goto measureCharsEnd;
	}

	source += clen;
	numBytes -= clen;
	if (c < 256 && isspace(c)) {		/* I18N: ??? */
	    if (sawNonSpace) {
		termByte = curByte;
		termX = curX;
		sawNonSpace = 0;
	    }
	} else {
	    sawNonSpace = 1;
	}

#ifdef DEBUG_FONTSEL
	string[len++] = (char) c;
#endif /* DEBUG_FONTSEL */
	ftFont = GetFont(fontPtr, c, 0.0);

	if (!errorFlag) {
	    LOCK;
	    XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
	    UNLOCK;
	} else {
	    extents.xOff = 0;
	    errorFlag = 0;
	}

	newX = curX + extents.xOff;
	newByte = curByte + clen;
790
791
792
793
794
795
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
	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }

    Tk_DeleteErrorHandler(handler);
#ifdef DEBUG_FONTSEL
    string[len] = '\0';
    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
#endif /* DEBUG_FONTSEL */
    *lengthPtr = curX;
    return curByte;
}

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,
    const char *source,
    int numBytes,
    int rangeStart,
    int rangeLength,
    int maxLength,
    int flags,
    int *lengthPtr)
{
    (void) numBytes; /*unused*/

    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *----------------------------------------------------------------------
 *







>













|
|
|




<
<







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
	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }
measureCharsEnd:
    Tk_DeleteErrorHandler(handler);
#ifdef DEBUG_FONTSEL
    string[len] = '\0';
    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
#endif /* DEBUG_FONTSEL */
    *lengthPtr = curX;
    return curByte;
}

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,
    const char *source,
    TCL_UNUSED(Tcl_Size),
    Tcl_Size rangeStart,
    Tcl_Size rangeLength,
    int maxLength,
    int flags,
    int *lengthPtr)
{


    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *----------------------------------------------------------------------
 *
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
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);







|
















|







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
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%lx\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
968
969
970
971
972
973
974

975
976

977
978
979
980
981
982
983
984
985
986
987
988

989
990

991
992
993
994
995
996
997
998

999

1000
1001
1002
1003
1004
1005
1006
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);

	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);


	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = x;
		specs[nspec].y = y;
		if (++nspec == NUM_SPEC) {

		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);

		    nspec = 0;
		}
	    }
	    x += metrics.xOff;
	    y += metrics.yOff;
	}
    }
    if (nspec) {

	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);

    }

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
    if (fontPtr->font.fa.underline != 0) {







>


>












>


>








>

>







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
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    LOCK;
	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);
	    UNLOCK;

	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = x;
		specs[nspec].y = y;
		if (++nspec == NUM_SPEC) {
		    LOCK;
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    UNLOCK;
		    nspec = 0;
		}
	    }
	    x += metrics.xOff;
	    y += metrics.yOff;
	}
    }
    if (nspec) {
	LOCK;
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
	UNLOCK;
    }

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
    if (fontPtr->font.fa.underline != 0) {
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;







|







1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
1119
1120
1121
1122
1123
1124
1125

1126
1127


1128
1129
1130
1131
1132
1133
1134
		/*
		 * We pass multiple glyphs at once to enable the code to
		 * perform better rendering of sub-pixel inter-glyph spacing.
		 * If only the current Xft implementation could make use of
		 * this information... but we'll be ready when it does!
		 */


		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);


		/*
		 * Draw glyph only when it fits entirely into 16 bit coords.
		 */

		if (x >= minCoord && y >= minCoord &&
		    x <= maxCoord - metrics.width &&
		    y <= maxCoord - metrics.height) {







>


>
>







1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
		/*
		 * We pass multiple glyphs at once to enable the code to
		 * perform better rendering of sub-pixel inter-glyph spacing.
		 * If only the current Xft implementation could make use of
		 * this information... but we'll be ready when it does!
		 */

		LOCK;
		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);
		UNLOCK;

		/*
		 * Draw glyph only when it fits entirely into 16 bit coords.
		 */

		if (x >= minCoord && y >= minCoord &&
		    x <= maxCoord - metrics.width &&
		    y <= maxCoord - metrics.height) {
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
		     * be divided until the maximal string will fit. (GC)
                     * Given the resolution of current displays though, this should
                     * not be a huge issue since NUM_SPEC is 1024 and thus able to
                     * cover about 6000 pixels for a 6 pixel wide font (which is
                     * a very small barely readable font)
		     */


		    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
			    originX, originY, glyphs, nglyph);

		}
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {

	XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
		nglyph, &metrics);


	/*
	 * Draw glyph only when it fits entirely into 16 bit coords.
	 */

	if (x >= minCoord && y >= minCoord &&
	    x <= maxCoord - metrics.width &&
	    y <= maxCoord - metrics.height) {

	    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
		    originX, originY, glyphs, nglyph);

	}
    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */

    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);







>


>









>


>








>


>



>
|






|







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
		     * be divided until the maximal string will fit. (GC)
                     * Given the resolution of current displays though, this should
                     * not be a huge issue since NUM_SPEC is 1024 and thus able to
                     * cover about 6000 pixels for a 6 pixel wide font (which is
                     * a very small barely readable font)
		     */

		    LOCK;
		    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
			    originX, originY, glyphs, nglyph);
		    UNLOCK;
		}
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {
	LOCK;
	XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
		nglyph, &metrics);
	UNLOCK;

	/*
	 * Draw glyph only when it fits entirely into 16 bit coords.
	 */

	if (x >= minCoord && y >= minCoord &&
	    x <= maxCoord - metrics.width &&
	    y <= maxCoord - metrics.height) {
	    LOCK;
	    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
		    originX, originY, glyphs, nglyph);
	    UNLOCK;
	}
    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    Tcl_Size clen;
    int nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%lx\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
1213
1214
1215
1216
1217
1218
1219

1220
1221

1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233

1234
1235

1236
1237
1238
1239
1240
1241
1242
1243

1244

1245
1246
1247
1248
1249
1250
1251
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);

	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);


	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = ROUND16(x);
		specs[nspec].y = ROUND16(y);
		if (++nspec == NUM_SPEC) {

		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);

		    nspec = 0;
		}
	    }
	    x += metrics.xOff*cosA + metrics.yOff*sinA;
	    y += metrics.yOff*cosA - metrics.xOff*sinA;
	}
    }
    if (nspec) {

	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);

    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }







>


>












>


>








>

>







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
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    LOCK;
	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);
	    UNLOCK;

	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = ROUND16(x);
		specs[nspec].y = ROUND16(y);
		if (++nspec == NUM_SPEC) {
		    LOCK;
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    UNLOCK;
		    nspec = 0;
		}
	    }
	    x += metrics.xOff*cosA + metrics.yOff*sinA;
	    y += metrics.yOff*cosA - metrics.xOff*sinA;
	}
    }
    if (nspec) {
	LOCK;
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
	UNLOCK;
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
    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(







|
|
|






<
<



















|
|
|








<
<







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
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(Tcl_Size),		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;



    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+widthUntilStart, y);
}

void
TkpDrawAngledCharsInContext(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn; must
				 * be the same as font used in GC. */
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(Tcl_Size),		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size 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);



    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(

Changes to unix/tkUnixScale.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScale.h"

#if defined(_WIN32)
#define snprintf _snprintf
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static void		DisplayHorizontalScale(TkScale *scalePtr,



|

|
|








|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * tkUnixScale.c --
 *
 *	This file implements the X specific portion of the scale widget.
 *
 * 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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static void		DisplayHorizontalScale(TkScale *scalePtr,
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int rightEdge,		/* X-coordinate of right edge of text,
				 * specified in pixels. */
    const char *format)		/* Format string to use for the value */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int y, width, length;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
    if (snprintf(valueString, TCL_DOUBLE_SPACE, format, value) < 0) {
	valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the y-coordinate if necessary to keep the text entirely inside
     * the window.
     */








|








|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int rightEdge,		/* X-coordinate of right edge of text,
				 * specified in pixels. */
    const char *format)		/* Format string to use for the value */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int y, width;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = TkScaleValueToPixel(scalePtr, value) + fm.ascent/2;
    if (snprintf(valueString, TCL_DOUBLE_SPACE, format, value) < 0) {
	valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    Tcl_Size length = strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the y-coordinate if necessary to keep the text entirely inside
     * the window.
     */

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int top,			/* Y-coordinate of top edge of text, specified
				 * in pixels. */
    const char *format)		/* Format string to use for the value */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int x, y, length, width;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    x = TkScaleValueToPixel(scalePtr, value);
    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = top + fm.ascent;
    if (snprintf(valueString, TCL_DOUBLE_SPACE, format, value) < 0) {
	valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    length = (int) strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the x-coordinate if necessary to keep the text entirely inside
     * the window.
     */








|









|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
				 * specified in application coords, not in
				 * pixels (we'll compute pixels). */
    int top,			/* Y-coordinate of top edge of text, specified
				 * in pixels. */
    const char *format)		/* Format string to use for the value */
{
    Tk_Window tkwin = scalePtr->tkwin;
    int x, y, width;
    char valueString[TCL_DOUBLE_SPACE];
    Tk_FontMetrics fm;

    x = TkScaleValueToPixel(scalePtr, value);
    Tk_GetFontMetrics(scalePtr->tkfont, &fm);
    y = top + fm.ascent;
    if (snprintf(valueString, TCL_DOUBLE_SPACE, format, value) < 0) {
	valueString[TCL_DOUBLE_SPACE - 1] = '\0';
    }
    Tcl_Size length = strlen(valueString);
    width = Tk_TextWidth(scalePtr->tkfont, valueString, length);

    /*
     * Adjust the x-coordinate if necessary to keep the text entirely inside
     * the window.
     */

540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
 *	The scale gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    Pixmap pixmap;
    int result;
    char string[TCL_DOUBLE_SPACE];







|







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
 *	The scale gets redisplayed.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayScale(
    void *clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    Pixmap pixmap;
    int result;
    char string[TCL_DOUBLE_SPACE];
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
	if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
		scalePtr->value) < 0) {
	    string[TCL_DOUBLE_SPACE - 1] = '\0';
	}
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, string, -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }







|
|
|
|







568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
	if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat,
		scalePtr->value) < 0) {
	    string[TCL_DOUBLE_SPACE - 1] = '\0';
	}
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
	Tcl_DStringAppend(&buf, string, TCL_INDEX_NONE);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	Tcl_DStringFree(&buf);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }

Changes to unix/tkUnixScrlbr.c.

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.
 *
 * 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"






|







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 © 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"
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->tkwin;
    XPoint points[7];
    Tk_3DBorder border;
    int relief, width, elementBorderWidth;
    Pixmap pixmap;







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    void *clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->tkwin;
    XPoint points[7];
    Tk_3DBorder border;
    int relief, width, elementBorderWidth;
    Pixmap pixmap;

Changes to unix/tkUnixSelect.c.

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.
 *
 * 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"





|







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 © 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"
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

/*
 * Forward declarations for functions defined in this file:
 */

static void		ConvertSelection(TkWindow *winPtr,
			    XSelectionRequestEvent *eventPtr);
static void		IncrTimeoutProc(ClientData clientData);
static void		SelCvtFromX32(long *propPtr, int numValues, Atom type,
			    Tk_Window tkwin, Tcl_DString *dsPtr);
static void		SelCvtFromX8(char *propPtr, int numValues, Atom type,
			    Tk_Window tkwin, Tcl_DString *dsPtr);
static long *		SelCvtToX(char *string, Atom type, Tk_Window tkwin,
			    int *numLongsPtr);
static int		SelectionSize(TkSelHandler *selPtr);
static void		SelRcvIncrProc(ClientData clientData,
			    XEvent *eventPtr);
static void		SelTimeoutProc(ClientData clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkSelGetSelection --
 *
 *	Retrieve the specified selection from another process.







|
|

|


|

|

|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

/*
 * Forward declarations for functions defined in this file:
 */

static void		ConvertSelection(TkWindow *winPtr,
			    XSelectionRequestEvent *eventPtr);
static void		IncrTimeoutProc(void *clientData);
static void		SelCvtFromX32(long *propPtr, unsigned long numValues, Atom type,
			    Tk_Window tkwin, Tcl_DString *dsPtr);
static void		SelCvtFromX8(char *propPtr, unsigned long numValues, Atom type,
			    Tk_Window tkwin, Tcl_DString *dsPtr);
static long *		SelCvtToX(char *string, Atom type, Tk_Window tkwin,
			    Tcl_Size *numLongsPtr);
static int		SelectionSize(TkSelHandler *selPtr);
static void		SelRcvIncrProc(void *clientData,
			    XEvent *eventPtr);
static void		SelTimeoutProc(void *clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkSelGetSelection --
 *
 *	Retrieve the specified selection from another process.
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Function to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    TkSelRetrievalInfo retr;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;

    /*
     * The selection is owned by some other process. To retrieve it, first







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Function to call to process the selection,
				 * once it has been retrieved. */
    void *clientData)	/* Arbitrary value to pass to proc. */
{
    TkSelRetrievalInfo retr;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkDisplay *dispPtr = winPtr->dispPtr;

    /*
     * The selection is owned by some other process. To retrieve it, first
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    IncrInfo *incrPtr;
    TkSelHandler *selPtr;
    int length, numItems;

    unsigned long i;
    Atom target, formatType;
    long buffer[TK_SEL_WORDS_AT_ONCE];
    TkDisplay *dispPtr = TkGetDisplay(eventPtr->xany.display);
    Tk_ErrorHandler errorHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));







|
>







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    IncrInfo *incrPtr;
    TkSelHandler *selPtr;
    int length;
    Tcl_Size numItems;
    unsigned long i;
    Atom target, formatType;
    long buffer[TK_SEL_WORDS_AT_ONCE];
    TkDisplay *dispPtr = TkGetDisplay(eventPtr->xany.display);
    Tk_ErrorHandler errorHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
		if (ip.selPtr == NULL) {
		    /*
		     * The selection handler deleted itself.
		     */

		    return;
		}
		if (numItems < 0) {
		    numItems = 0;
		}
		numItems += length;
		if (numItems > TK_SEL_BYTES_AT_ONCE) {
		    Tcl_Panic("selection handler returned too many bytes");
		}
	    }







|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
		if (ip.selPtr == NULL) {
		    /*
		     * The selection handler deleted itself.
		     */

		    return;
		}
		if (numItems == TCL_INDEX_NONE) {
		    numItems = 0;
		}
		numItems += length;
		if (numItems > TK_SEL_BYTES_AT_ONCE) {
		    Tcl_Panic("selection handler returned too many bytes");
		}
	    }
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
		Tcl_Encoding encoding;

		/*
		 * Set up the encoding state based on the format and whether
		 * this is the first and/or last chunk.
		 */

		encodingCvtFlags = 0;
		if (incrPtr->converts[i].offset == 0) {
		    encodingCvtFlags |= TCL_ENCODING_START;
		}
		if (numItems < TK_SEL_BYTES_AT_ONCE) {
		    encodingCvtFlags |= TCL_ENCODING_END;
		}
		if (formatType == XA_STRING) {







|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
		Tcl_Encoding encoding;

		/*
		 * Set up the encoding state based on the format and whether
		 * this is the first and/or last chunk.
		 */

		encodingCvtFlags = TCL_ENCODING_PROFILE_TCL8;
		if (incrPtr->converts[i].offset == 0) {
		    encodingCvtFlags |= TCL_ENCODING_START;
		}
		if (numItems < TK_SEL_BYTES_AT_ONCE) {
		    encodingCvtFlags |= TCL_ENCODING_END;
		}
		if (formatType == XA_STRING) {
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
	    /*
	     * Compute the next offset value. If this was the last chunk, then
	     * set the offset to -2. If this was an empty chunk, then set the
	     * offset to -1 to indicate we are done.
	     */

	    if (numItems < TK_SEL_BYTES_AT_ONCE) {
		if (numItems <= 0) {
		    incrPtr->converts[i].offset = -1;
		    incrPtr->numIncrs--;
		} else {
		    incrPtr->converts[i].offset = -2;
		}
	    } else {
		/*







|







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
	    /*
	     * Compute the next offset value. If this was the last chunk, then
	     * set the offset to -2. If this was an empty chunk, then set the
	     * offset to -1 to indicate we are done.
	     */

	    if (numItems < TK_SEL_BYTES_AT_ONCE) {
		if (numItems < 1) {
		    incrPtr->converts[i].offset = -1;
		    incrPtr->numIncrs--;
		} else {
		    incrPtr->converts[i].offset = -2;
		}
	    } else {
		/*
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
		&type, &format, &numItems, &bytesAfter,
		(unsigned char **) propInfoPtr);
	if ((result != Success) || (type == None)) {
	    return;
	}
	if (bytesAfter != 0) {
	    Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		    "selection property too large", -1));
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "SIZE",NULL);
	    retrPtr->result = TCL_ERROR;
	    XFree(propInfo);
	    return;
	}
	if ((type == XA_STRING) || (type == dispPtr->textAtom)
		|| (type == dispPtr->compoundTextAtom)) {







|







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
		&type, &format, &numItems, &bytesAfter,
		(unsigned char **) propInfoPtr);
	if ((result != Success) || (type == None)) {
	    return;
	}
	if (bytesAfter != 0) {
	    Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		    "selection property too large", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "SIZE",NULL);
	    retrPtr->result = TCL_ERROR;
	    XFree(propInfo);
	    return;
	}
	if ((type == XA_STRING) || (type == dispPtr->textAtom)
		|| (type == dispPtr->compoundTextAtom)) {
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	     */

	    if (type == dispPtr->compoundTextAtom) {
		encoding = Tcl_GetEncoding(NULL, "iso2022");
	    } else {
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    }
	    Tcl_ExternalToUtfDString(encoding, propInfo, (int)numItems, &ds);
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }

	    retrPtr->result = retrPtr->proc(retrPtr->clientData, interp,
		    Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	    Tcl_Release(interp);
	} else if (type == dispPtr->utf8Atom) {
	    /*
	     * The X selection data is in UTF-8 format already. We can't
	     * guarantee that propInfo is NULL-terminated, so we might have to
	     * copy the string.







|




|
<







617
618
619
620
621
622
623
624
625
626
627
628
629

630
631
632
633
634
635
636
	     */

	    if (type == dispPtr->compoundTextAtom) {
		encoding = Tcl_GetEncoding(NULL, "iso2022");
	    } else {
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    }
	    char *str = Tcl_ExternalToUtfDString(encoding, propInfo, numItems, &ds);
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }

	    retrPtr->result = retrPtr->proc(retrPtr->clientData, interp, str);

	    Tcl_DStringFree(&ds);
	    Tcl_Release(interp);
	} else if (type == dispPtr->utf8Atom) {
	    /*
	     * The X selection data is in UTF-8 format already. We can't
	     * guarantee that propInfo is NULL-terminated, so we might have to
	     * copy the string.
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
		Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
			NULL);
		retrPtr->result = TCL_ERROR;
		return;
	    }
	    Tcl_DStringInit(&ds);
	    if (format == 32) {
		SelCvtFromX32((long *) propInfo, (int) numItems, type,
			(Tk_Window) winPtr, &ds);
	    } else {
		SelCvtFromX8((char *) propInfo, (int) numItems, type,
			(Tk_Window) winPtr, &ds);
	    }
	    interp = retrPtr->interp;
	    Tcl_Preserve(interp);
	    retrPtr->result = retrPtr->proc(retrPtr->clientData,
		    interp, Tcl_DStringValue(&ds));
	    Tcl_Release(interp);







|


|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
		Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
			NULL);
		retrPtr->result = TCL_ERROR;
		return;
	    }
	    Tcl_DStringInit(&ds);
	    if (format == 32) {
		SelCvtFromX32((long *) propInfo, numItems, type,
			(Tk_Window) winPtr, &ds);
	    } else {
		SelCvtFromX8((char *) propInfo, numItems, type,
			(Tk_Window) winPtr, &ds);
	    }
	    interp = retrPtr->interp;
	    Tcl_Preserve(interp);
	    retrPtr->result = retrPtr->proc(retrPtr->clientData,
		    interp, Tcl_DStringValue(&ds));
	    Tcl_Release(interp);
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
 *	retrieval.
 *
 *----------------------------------------------------------------------
 */

static void
SelTimeoutProc(
    ClientData clientData)	/* Information about retrieval in progress. */
{
    TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *)clientData;

    /*
     * Make sure that the retrieval is still in progress. Then see how long
     * it's been since any sort of response was received from the other side.
     */

    if (retrPtr->result != -1) {
	return;
    }
    retrPtr->idleTime++;
    if (retrPtr->idleTime >= 5) {
	/*
	 * Use a careful function to store the error message, because the
	 * result could already be partially filled in with a partial
	 * selection return.
	 */

	Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		"selection owner didn't respond", -1));
	Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "IGNORED", NULL);
	retrPtr->result = TCL_ERROR;
    } else {
	retrPtr->timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,
		retrPtr);
    }
}







|




















|







736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
 *	retrieval.
 *
 *----------------------------------------------------------------------
 */

static void
SelTimeoutProc(
    void *clientData)	/* Information about retrieval in progress. */
{
    TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *)clientData;

    /*
     * Make sure that the retrieval is still in progress. Then see how long
     * it's been since any sort of response was received from the other side.
     */

    if (retrPtr->result != -1) {
	return;
    }
    retrPtr->idleTime++;
    if (retrPtr->idleTime >= 5) {
	/*
	 * Use a careful function to store the error message, because the
	 * result could already be partially filled in with a partial
	 * selection return.
	 */

	Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		"selection owner didn't respond", TCL_INDEX_NONE));
	Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "IGNORED", NULL);
	retrPtr->result = TCL_ERROR;
    } else {
	retrPtr->timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,
		retrPtr);
    }
}
875
876
877
878
879
880
881
882
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
		eventPtr->property, 0, MAX_PROP_WORDS, False,
		winPtr->dispPtr->atomPairAtom, &type, &format,
		&incr.numConversions, &bytesAfter,
		(unsigned char **) multAtomsPtr);
	if ((result != Success) || (bytesAfter != 0) || (format != 32)
		|| (type == None)) {
	    if (incr.multAtoms != NULL) {
		XFree((char *) incr.multAtoms);
	    }
	    goto refuse;
	}
	incr.numConversions /= 2;	/* Two atoms per conversion. */
    }

    /*
     * Loop through all of the requested conversions, and either return the
     * entire converted selection, if it can be returned in a single bunch, or
     * return INCR information only (the actual selection will be returned
     * below).
     */

    incr.converts = (ConvertInfo *)ckalloc(incr.numConversions * sizeof(ConvertInfo));
    incr.numIncrs = 0;
    for (i = 0; i < incr.numConversions; i++) {
	Atom target, property, type;
	long buffer[TK_SEL_WORDS_AT_ONCE];
	TkSelHandler *selPtr;

	int numItems, format;
	char *propPtr;

	target = incr.multAtoms[2*i];
	property = incr.multAtoms[2*i + 1];
	incr.converts[i].offset = -1;
	incr.converts[i].buffer[0] = '\0';








|



















>
|







875
876
877
878
879
880
881
882
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
		eventPtr->property, 0, MAX_PROP_WORDS, False,
		winPtr->dispPtr->atomPairAtom, &type, &format,
		&incr.numConversions, &bytesAfter,
		(unsigned char **) multAtomsPtr);
	if ((result != Success) || (bytesAfter != 0) || (format != 32)
		|| (type == None)) {
	    if (incr.multAtoms != NULL) {
		XFree(incr.multAtoms);
	    }
	    goto refuse;
	}
	incr.numConversions /= 2;	/* Two atoms per conversion. */
    }

    /*
     * Loop through all of the requested conversions, and either return the
     * entire converted selection, if it can be returned in a single bunch, or
     * return INCR information only (the actual selection will be returned
     * below).
     */

    incr.converts = (ConvertInfo *)ckalloc(incr.numConversions * sizeof(ConvertInfo));
    incr.numIncrs = 0;
    for (i = 0; i < incr.numConversions; i++) {
	Atom target, property, type;
	long buffer[TK_SEL_WORDS_AT_ONCE];
	TkSelHandler *selPtr;
	Tcl_Size numItems;
	int format;
	char *propPtr;

	target = incr.multAtoms[2*i];
	property = incr.multAtoms[2*i + 1];
	incr.converts[i].offset = -1;
	incr.converts[i].buffer[0] = '\0';

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
	     * Nobody seems to know about this kind of request. If it's of a
	     * sort that we can handle without any help, do it. Otherwise mark
	     * the request as an error.
	     */

	    numItems = TkSelDefaultSelection(infoPtr, target, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE, &type);
	    if (numItems < 0) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	} else {
	    ip.selPtr = selPtr;
	    ip.nextPtr = TkSelGetInProgress();
	    TkSelSetInProgress(&ip);
	    type = selPtr->format;
	    numItems = selPtr->proc(selPtr->clientData, 0, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE);
	    TkSelSetInProgress(ip.nextPtr);
	    if ((ip.selPtr == NULL) || (numItems < 0)) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	    if (numItems > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
	    }
	    ((char *) buffer)[numItems] = '\0';







|











|







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
	     * Nobody seems to know about this kind of request. If it's of a
	     * sort that we can handle without any help, do it. Otherwise mark
	     * the request as an error.
	     */

	    numItems = TkSelDefaultSelection(infoPtr, target, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE, &type);
	    if (numItems == TCL_INDEX_NONE) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	} else {
	    ip.selPtr = selPtr;
	    ip.nextPtr = TkSelGetInProgress();
	    TkSelSetInProgress(&ip);
	    type = selPtr->format;
	    numItems = selPtr->proc(selPtr->clientData, 0, (char *) buffer,
		    TK_SEL_BYTES_AT_ONCE);
	    TkSelSetInProgress(ip.nextPtr);
	    if ((ip.selPtr == NULL) || (numItems == TCL_INDEX_NONE)) {
		incr.multAtoms[2*i + 1] = None;
		continue;
	    }
	    if (numItems > TK_SEL_BYTES_AT_ONCE) {
		Tcl_Panic("selection handler returned too many bytes");
	    }
	    ((char *) buffer)[numItems] = '\0';
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006
1007
1008
	     */

	    if (type == XA_STRING) {
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    } else {
		encoding = Tcl_GetEncoding(NULL, "iso2022");
	    }
	    Tcl_UtfToExternalDString(encoding, (char *) buffer, -1, &ds);

	    XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		    property, type, 8, PropModeReplace,
		    (unsigned char *) Tcl_DStringValue(&ds),
		    Tcl_DStringLength(&ds));
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    Tcl_DStringFree(&ds);
	} else {
	    propPtr = (char *) SelCvtToX((char *) buffer,







|
>

|
<







992
993
994
995
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
	     */

	    if (type == XA_STRING) {
		encoding = Tcl_GetEncoding(NULL, "iso8859-1");
	    } else {
		encoding = Tcl_GetEncoding(NULL, "iso2022");
	    }
	    unsigned char *str = (unsigned char *)Tcl_UtfToExternalDString(encoding,
		    (char *) buffer, TCL_INDEX_NONE, &ds);
	    XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		    property, type, 8, PropModeReplace, str,

		    Tcl_DStringLength(&ds));
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    Tcl_DStringFree(&ds);
	} else {
	    propPtr = (char *) SelCvtToX((char *) buffer,
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
	incr.nextPtr = tsdPtr->pendingIncrs;
	tsdPtr->pendingIncrs = &incr;
    }
    if (multiple) {
	XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		reply.xsel.property, winPtr->dispPtr->atomPairAtom,
		32, PropModeReplace, (unsigned char *) incr.multAtoms,
		(int) incr.numConversions*2);
    } else {
	/*
	 * Not a MULTIPLE request. The first property in "multAtoms" got set
	 * to None if there was an error in conversion.
	 */

	reply.xsel.property = incr.multAtoms[1];







|







1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
	incr.nextPtr = tsdPtr->pendingIncrs;
	tsdPtr->pendingIncrs = &incr;
    }
    if (multiple) {
	XChangeProperty(reply.xsel.display, reply.xsel.requestor,
		reply.xsel.property, winPtr->dispPtr->atomPairAtom,
		32, PropModeReplace, (unsigned char *) incr.multAtoms,
		incr.numConversions*2);
    } else {
	/*
	 * Not a MULTIPLE request. The first property in "multAtoms" got set
	 * to None if there was an error in conversion.
	 */

	reply.xsel.property = incr.multAtoms[1];
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

    /*
     * All done. Cleanup and return.
     */

    ckfree(incr.converts);
    if (multiple) {
	XFree((char *) incr.multAtoms);
    }
    return;

    /*
     * An error occurred. Send back a refusal message.
     */








|







1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

    /*
     * All done. Cleanup and return.
     */

    ckfree(incr.converts);
    if (multiple) {
	XFree(incr.multAtoms);
    }
    return;

    /*
     * An error occurred. Send back a refusal message.
     */

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
 *	the higher-level function that initiated the selection retrieval.
 *
 *----------------------------------------------------------------------
 */

static void
SelRcvIncrProc(
    ClientData clientData,	/* Information about retrieval. */
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *)clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    Atom type;
    int format, result;
    unsigned long numItems, bytesAfter;







|







1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
 *	the higher-level function that initiated the selection retrieval.
 *
 *----------------------------------------------------------------------
 */

static void
SelRcvIncrProc(
    void *clientData,	/* Information about retrieval. */
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *)clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    Atom type;
    int format, result;
    unsigned long numItems, bytesAfter;
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
	    True, (Atom) AnyPropertyType, &type, &format, &numItems,
	    &bytesAfter, (unsigned char **) propInfoPtr);
    if ((result != Success) || (type == None)) {
	return;
    }
    if (bytesAfter != 0) {
	Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		"selection property too large", -1));
	Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "SIZE", NULL);
	retrPtr->result = TCL_ERROR;
	goto done;
    }
    if ((type == XA_STRING)
	    || (type == retrPtr->winPtr->dispPtr->textAtom)
	    || (type == retrPtr->winPtr->dispPtr->utf8Atom)







|







1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
	    True, (Atom) AnyPropertyType, &type, &format, &numItems,
	    &bytesAfter, (unsigned char **) propInfoPtr);
    if ((result != Success) || (type == None)) {
	return;
    }
    if (bytesAfter != 0) {
	Tcl_SetObjResult(retrPtr->interp, Tcl_NewStringObj(
		"selection property too large", TCL_INDEX_NONE));
	Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "SIZE", NULL);
	retrPtr->result = TCL_ERROR;
	goto done;
    }
    if ((type == XA_STRING)
	    || (type == retrPtr->winPtr->dispPtr->textAtom)
	    || (type == retrPtr->winPtr->dispPtr->utf8Atom)
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236

	/*
	 * Now convert the data, growing the destination buffer as needed.
	 */

	while (1) {
	    result = Tcl_ExternalToUtf(NULL, encoding, src, srcLen,
		    retrPtr->encFlags, &retrPtr->encState,
		    dst, dstLen, &srcRead, &dstWrote, NULL);
	    soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
	    retrPtr->encFlags &= ~TCL_ENCODING_START;
	    src += srcRead;
	    srcLen -= srcRead;
	    if (result != TCL_CONVERT_NOSPACE) {
		Tcl_DStringSetLength(dstPtr, soFar);
		break;







|
|







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237

	/*
	 * Now convert the data, growing the destination buffer as needed.
	 */

	while (1) {
	    result = Tcl_ExternalToUtf(NULL, encoding, src, srcLen,
		    TCL_ENCODING_PROFILE_TCL8|retrPtr->encFlags,
		    &retrPtr->encState, dst, dstLen, &srcRead, &dstWrote, NULL);
	    soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
	    retrPtr->encFlags &= ~TCL_ENCODING_START;
	    src += srcRead;
	    srcLen -= srcRead;
	    if (result != TCL_CONVERT_NOSPACE) {
		Tcl_DStringSetLength(dstPtr, soFar);
		break;
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
		    NULL);
	    retrPtr->result = TCL_ERROR;
	    goto done;
	}
	Tcl_DStringInit(&ds);
	if (format == 32) {
	    SelCvtFromX32((long *) propInfo, (int) numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	} else {
	    SelCvtFromX8((char *) propInfo, (int) numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	}
	interp = retrPtr->interp;
	Tcl_Preserve(interp);
	result = retrPtr->proc(retrPtr->clientData, interp,
		Tcl_DStringValue(&ds));
	Tcl_Release(interp);







|


|







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
	    Tcl_SetErrorCode(retrPtr->interp, "TK", "SELECTION", "FORMAT",
		    NULL);
	    retrPtr->result = TCL_ERROR;
	    goto done;
	}
	Tcl_DStringInit(&ds);
	if (format == 32) {
	    SelCvtFromX32((long *) propInfo, numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	} else {
	    SelCvtFromX8((char *) propInfo, numItems, type,
		    (Tk_Window) retrPtr->winPtr, &ds);
	}
	interp = retrPtr->interp;
	Tcl_Preserve(interp);
	result = retrPtr->proc(retrPtr->clientData, interp,
		Tcl_DStringValue(&ds));
	Tcl_Release(interp);
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
 *	incrPtr is marked as "all done".
 *
 *----------------------------------------------------------------------
 */

static void
IncrTimeoutProc(
    ClientData clientData)	/* Information about INCR-mode selection
				 * retrieval for which we are selection
				 * owner. */
{
    IncrInfo *incrPtr = (IncrInfo *)clientData;

    incrPtr->idleTime++;
    if (incrPtr->idleTime >= 5) {







|







1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
 *	incrPtr is marked as "all done".
 *
 *----------------------------------------------------------------------
 */

static void
IncrTimeoutProc(
    void *clientData)	/* Information about INCR-mode selection
				 * retrieval for which we are selection
				 * owner. */
{
    IncrInfo *incrPtr = (IncrInfo *)clientData;

    incrPtr->idleTime++;
    if (incrPtr->idleTime >= 5) {
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
SelCvtToX(
    char *string,		/* String representation of selection. */
    Atom type,			/* Atom specifying the X format that is
				 * desired for the selection. Should not be
				 * XA_STRING (if so, don't bother calling this
				 * function at all). */
    Tk_Window tkwin,		/* Window that governs atom conversion. */
    int *numLongsPtr)		/* Number of 32-bit words contained in the
				 * result. */
{
    const char **field;
    int numFields, i;
    long *propPtr;

    /*
     * The string is assumed to consist of fields separated by spaces. The
     * property gets generated by converting each field to an integer number,
     * in one of two ways:
     * 1. If type is XA_ATOM, convert each field to its corresponding atom.







|



|







1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
SelCvtToX(
    char *string,		/* String representation of selection. */
    Atom type,			/* Atom specifying the X format that is
				 * desired for the selection. Should not be
				 * XA_STRING (if so, don't bother calling this
				 * function at all). */
    Tk_Window tkwin,		/* Window that governs atom conversion. */
    Tcl_Size *numLongsPtr)		/* Number of 32-bit words contained in the
				 * result. */
{
    const char **field;
    Tcl_Size numFields, i;
    long *propPtr;

    /*
     * The string is assumed to consist of fields separated by spaces. The
     * property gets generated by converting each field to an integer number,
     * in one of two ways:
     * 1. If type is XA_ATOM, convert each field to its corresponding atom.
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
 *
 *----------------------------------------------------------------------
 */

static void
SelCvtFromX32(
    long *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 32-bit values in property. */
    Atom type,			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    Tk_Window tkwin,		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    /*







|







1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
 *
 *----------------------------------------------------------------------
 */

static void
SelCvtFromX32(
    long *propPtr,	/* Property value from X. */
    unsigned long numValues,		/* Number of 32-bit values in property. */
    Atom type,			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    Tk_Window tkwin,		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    /*
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
    for ( ; numValues > 0; propPtr++, numValues--) {
	if (type == XA_ATOM) {
	    Tcl_DStringAppendElement(dsPtr,
		    Tk_GetAtomName(tkwin, (Atom) *propPtr));
	} else {
	    char buf[12];

	    sprintf(buf, "0x%x", (unsigned int) *propPtr);
	    Tcl_DStringAppendElement(dsPtr, buf);
	}
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

static void
SelCvtFromX8(
    char *propPtr,	/* Property value from X. */
    int numValues,		/* Number of 8-bit values in property. */
    TCL_UNUSED(Atom),			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    TCL_UNUSED(Tk_Window),		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    /*
     * Convert each long in the property to a string value, which is a
     * hexadecimal string. We build the list in a Tcl_DString because this is
     * easier than trying to get the quoting correct ourselves.
     */

    for ( ; numValues > 0; propPtr++, numValues--) {
	char buf[12];

	sprintf(buf, "0x%x", (unsigned char) *propPtr);
	Tcl_DStringAppendElement(dsPtr, buf);
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|









|















|












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
    for ( ; numValues > 0; propPtr++, numValues--) {
	if (type == XA_ATOM) {
	    Tcl_DStringAppendElement(dsPtr,
		    Tk_GetAtomName(tkwin, (Atom) *propPtr));
	} else {
	    char buf[12];

	    snprintf(buf, sizeof(buf), "0x%x", (unsigned int) *propPtr);
	    Tcl_DStringAppendElement(dsPtr, buf);
	}
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

static void
SelCvtFromX8(
    char *propPtr,	/* Property value from X. */
    unsigned long numValues,		/* Number of 8-bit values in property. */
    TCL_UNUSED(Atom),			/* Type of property Should not be XA_STRING
				 * (if so, don't bother calling this function
				 * at all). */
    TCL_UNUSED(Tk_Window),		/* Window to use for atom conversion. */
    Tcl_DString *dsPtr)		/* Where to store the converted string. */
{
    /*
     * Convert each long in the property to a string value, which is a
     * hexadecimal string. We build the list in a Tcl_DString because this is
     * easier than trying to get the quoting correct ourselves.
     */

    for ( ; numValues > 0; propPtr++, numValues--) {
	char buf[12];

	snprintf(buf, sizeof(buf), "0x%x", (unsigned char) *propPtr);
	Tcl_DStringAppendElement(dsPtr, buf);
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to unix/tkUnixSend.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"







|
|
|







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 © 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"

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

#define MAX_PROP_WORDS 100000

/*
 * Forward declarations for functions defined later in this file:
 */

static int		AppendErrorProc(ClientData clientData,
			    XErrorEvent *errorPtr);
static void		AppendPropCarefully(Display *display,
			    Window window, Atom property, char *value,
			    int length, PendingCommand *pendingPtr);
static void		DeleteProc(ClientData clientData);
static void		RegAddName(NameRegistry *regPtr,
			    const char *name, Window commWindow);
static void		RegClose(NameRegistry *regPtr);
static void		RegDeleteName(NameRegistry *regPtr, const char *name);
static Window		RegFindName(NameRegistry *regPtr, const char *name);
static NameRegistry *	RegOpen(Tcl_Interp *interp,
			    TkDisplay *dispPtr, int lock);
static void		SendEventProc(ClientData clientData, XEvent *eventPtr);
static int		SendInit(Tcl_Interp *interp, TkDisplay *dispPtr);
static Tk_RestrictProc SendRestrictProc;
static int		ServerSecure(TkDisplay *dispPtr);
static void		UpdateCommWindow(TkDisplay *dispPtr);
static int		ValidateName(TkDisplay *dispPtr, const char *name,
			    Window commWindow, int oldOK);








|




|







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

#define MAX_PROP_WORDS 100000

/*
 * Forward declarations for functions defined later in this file:
 */

static int		AppendErrorProc(void *clientData,
			    XErrorEvent *errorPtr);
static void		AppendPropCarefully(Display *display,
			    Window window, Atom property, char *value,
			    int length, PendingCommand *pendingPtr);
static Tcl_CmdDeleteProc DeleteProc;
static void		RegAddName(NameRegistry *regPtr,
			    const char *name, Window commWindow);
static void		RegClose(NameRegistry *regPtr);
static void		RegDeleteName(NameRegistry *regPtr, const char *name);
static Window		RegFindName(NameRegistry *regPtr, const char *name);
static NameRegistry *	RegOpen(Tcl_Interp *interp,
			    TkDisplay *dispPtr, int lock);
static void		SendEventProc(void *clientData, XEvent *eventPtr);
static int		SendInit(Tcl_Interp *interp, TkDisplay *dispPtr);
static Tk_RestrictProc SendRestrictProc;
static int		ServerSecure(TkDisplay *dispPtr);
static void		UpdateCommWindow(TkDisplay *dispPtr);
static int		ValidateName(TkDisplay *dispPtr, const char *name,
			    Window commWindow, int oldOK);

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
				 * registered. */
    Window commWindow)		/* X identifier for comm. window of
				 * application. */
{
    char id[30], *newProp;
    int idLength, newBytes;

    sprintf(id, "%x ", (unsigned) commWindow);
    idLength = strlen(id);
    newBytes = idLength + strlen(name) + 1;
    newProp = (char *)ckalloc(regPtr->propLength + newBytes);
    strcpy(newProp, id);
    strcpy(newProp+idLength, name);
    if (regPtr->property != NULL) {
	memcpy(newProp + newBytes, regPtr->property, regPtr->propLength);







|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
				 * registered. */
    Window commWindow)		/* X identifier for comm. window of
				 * application. */
{
    char id[30], *newProp;
    int idLength, newBytes;

    snprintf(id, sizeof(id), "%x ", (unsigned) commWindow);
    idLength = strlen(id);
    newBytes = idLength + strlen(name) + 1;
    newProp = (char *)ckalloc(regPtr->propLength + newBytes);
    strcpy(newProp, id);
    strcpy(newProp+idLength, name);
    if (regPtr->property != NULL) {
	memcpy(newProp + newBytes, regPtr->property, regPtr->propLength);
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
    Window commWindow,		/* X identifier for the application's comm.
				 * window. */
    int oldOK)			/* Non-zero means that we should consider an
				 * application to be valid even if it looks
				 * like an old-style (pre-4.0) one; 0 means
				 * consider these invalid. */
{
    int result, actualFormat, argc, i;

    unsigned long length, bytesAfter;
    Atom actualType;
    char *property, **propertyPtr = &property;
    Tk_ErrorHandler handler;
    const char **argv;

    property = NULL;







|
>







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
    Window commWindow,		/* X identifier for the application's comm.
				 * window. */
    int oldOK)			/* Non-zero means that we should consider an
				 * application to be valid even if it looks
				 * like an old-style (pre-4.0) one; 0 means
				 * consider these invalid. */
{
    int result, actualFormat;
    Tcl_Size argc, i;
    unsigned long length, bytesAfter;
    Atom actualType;
    char *property, **propertyPtr = &property;
    Tk_ErrorHandler handler;
    const char **argv;

    property = NULL;
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
	 * the side of safety.
	 */

	secure = 0;
#endif /* FamilyServerInterpreted */
    }
    if (addrPtr != NULL) {
	XFree((char *) addrPtr);
    }
    return secure;
#endif /* TK_NO_SECURITY */
}

/*
 *----------------------------------------------------------------------







|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
	 * the side of safety.
	 */

	secure = 0;
#endif /* FamilyServerInterpreted */
    }
    if (addrPtr != NULL) {
	XFree(addrPtr);
    }
    return secure;
#endif /* TK_NO_SECURITY */
}

/*
 *----------------------------------------------------------------------
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
    actualName = name;
    offset = 0;				/* Needed only to avoid "used before
					 * set" compiler warnings. */
    for (i = 1; ; i++) {
	if (i > 1) {
	    if (i == 2) {
		Tcl_DStringInit(&dString);
		Tcl_DStringAppend(&dString, name, -1);
		Tcl_DStringAppend(&dString, " #", 2);
		offset = Tcl_DStringLength(&dString);
		Tcl_DStringSetLength(&dString, offset+TCL_INTEGER_SPACE);
		actualName = Tcl_DStringValue(&dString);
	    }
	    sprintf(Tcl_DStringValue(&dString) + offset, "%d", i);
	}
	w = RegFindName(regPtr, actualName);
	if (w == None) {
	    break;
	}

	/*







|





|







866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    actualName = name;
    offset = 0;				/* Needed only to avoid "used before
					 * set" compiler warnings. */
    for (i = 1; ; i++) {
	if (i > 1) {
	    if (i == 2) {
		Tcl_DStringInit(&dString);
		Tcl_DStringAppend(&dString, name, TCL_INDEX_NONE);
		Tcl_DStringAppend(&dString, " #", 2);
		offset = Tcl_DStringLength(&dString);
		Tcl_DStringSetLength(&dString, offset+TCL_INTEGER_SPACE);
		actualName = Tcl_DStringValue(&dString);
	    }
	    snprintf(Tcl_DStringValue(&dString) + offset, TCL_INTEGER_SPACE, "%d", i);
	}
	w = RegFindName(regPtr, actualName);
	if (w == None) {
	    break;
	}

	/*
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
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };

    TkWindow *winPtr;
    Window commWindow;
    PendingCommand pending;
    RegisteredInterp *riPtr;
    const char *destName;
    int result, index, async, i, firstArg;
    Tk_RestrictProc *prevProc;
    ClientData prevArg;
    TkDisplay *dispPtr;
    Tcl_Time timeout;
    NameRegistry *regPtr;
    Tcl_DString request;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Interp *localInterp;	/* Used when the interpreter to send the
				 * command to is within the same process. */

    /*
     * Process options, if any.
     */

    async = 0;
    winPtr = (TkWindow *) Tk_MainWindow(interp);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }





    for (i = 1; i < objc; i++) {


	if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    break;
	}
	if (index == SEND_ASYNC) {
	    ++async;
	} else if (index == SEND_DISPLAYOF) {
	    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[++i]),
		    (Tk_Window) winPtr);
	    if (winPtr == NULL) {
		return TCL_ERROR;
	    }
	} else if (index == SEND_LAST) {
	    i++;



	    break;
	}
    }

    if (objc < (i+2)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-option value ...? interpName arg ?arg ...?");
	return TCL_ERROR;
    }
    destName = Tcl_GetString(objv[i]);
    firstArg = i+1;








>




<
|

|


















>
>
>
>
>
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>




|







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
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };
    const char *stringRep, *destName;
    TkWindow *winPtr;
    Window commWindow;
    PendingCommand pending;
    RegisteredInterp *riPtr;

    int result, async, i, firstArg, index;
    Tk_RestrictProc *prevProc;
    void *prevArg;
    TkDisplay *dispPtr;
    Tcl_Time timeout;
    NameRegistry *regPtr;
    Tcl_DString request;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_Interp *localInterp;	/* Used when the interpreter to send the
				 * command to is within the same process. */

    /*
     * Process options, if any.
     */

    async = 0;
    winPtr = (TkWindow *) Tk_MainWindow(interp);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }

    /*
     * Process the command options.
     */

    for (i = 1; i < (objc - 1); i++) {
	stringRep = Tcl_GetString(objv[i]);
	if (stringRep[0] == '-') {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index == SEND_ASYNC) {
		++async;
	    } else if (index == SEND_DISPLAYOF) {
		winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[++i]),
			(Tk_Window) winPtr);
		if (winPtr == NULL) {
		    return TCL_ERROR;
		}
	    } else /* if (index == SEND_LAST) */ {
		i++;
		break;
	    }
	} else {
	    break;
	}
    }

    if (objc < (i + 2)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-option value ...? interpName arg ?arg ...?");
	return TCL_ERROR;
    }
    destName = Tcl_GetString(objv[i]);
    firstArg = i+1;

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
		|| (strcmp(riPtr->name, destName) != 0)) {
	    continue;
	}
	Tcl_Preserve(riPtr);
	localInterp = riPtr->interp;
	Tcl_Preserve(localInterp);
	if (firstArg == (objc-1)) {
	    result = Tcl_EvalEx(localInterp, Tcl_GetString(objv[firstArg]), -1, TCL_EVAL_GLOBAL);
	} else {
	    Tcl_DStringInit(&request);
	    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), -1);
	    for (i = firstArg+1; i < objc; i++) {
		Tcl_DStringAppend(&request, " ", 1);
		Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
	    }
	    result = Tcl_EvalEx(localInterp, Tcl_DStringValue(&request), -1, TCL_EVAL_GLOBAL);
	    Tcl_DStringFree(&request);
	}
	if (interp != localInterp) {
	    if (result == TCL_ERROR) {
		Tcl_Obj *errorObjPtr;

		/*







|


|


|

|







1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
		|| (strcmp(riPtr->name, destName) != 0)) {
	    continue;
	}
	Tcl_Preserve(riPtr);
	localInterp = riPtr->interp;
	Tcl_Preserve(localInterp);
	if (firstArg == (objc-1)) {
	    result = Tcl_EvalEx(localInterp, Tcl_GetString(objv[firstArg]), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	} else {
	    Tcl_DStringInit(&request);
	    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), TCL_INDEX_NONE);
	    for (i = firstArg+1; i < objc; i++) {
		Tcl_DStringAppend(&request, " ", 1);
		Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), TCL_INDEX_NONE);
	    }
	    result = Tcl_EvalEx(localInterp, Tcl_DStringValue(&request), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	    Tcl_DStringFree(&request);
	}
	if (interp != localInterp) {
	    if (result == TCL_ERROR) {
		Tcl_Obj *errorObjPtr;

		/*
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
     * Send the command to the target interpreter by appending it to the comm
     * window in the communication window.
     */

    localData.sendSerial++;
    Tcl_DStringInit(&request);
    Tcl_DStringAppend(&request, "\0c\0-n ", 6);
    Tcl_DStringAppend(&request, destName, -1);
    if (!async) {
	char buffer[TCL_INTEGER_SPACE * 2];

	sprintf(buffer, "%x %d",
		(unsigned) Tk_WindowId(dispPtr->commTkwin),
		localData.sendSerial);
	Tcl_DStringAppend(&request, "\0-r ", 4);
	Tcl_DStringAppend(&request, buffer, -1);
    }
    Tcl_DStringAppend(&request, "\0-s ", 4);
    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), -1);
    for (i = firstArg+1; i < objc; i++) {
	Tcl_DStringAppend(&request, " ", 1);
	Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
    }

    if (!async) {
	/*
	 * Register the fact that we're waiting for a command to complete
	 * (this is needed by SendEventProc and by AppendErrorProc to pass
	 * back the command's results). Set up a timeout handler so that







|



|



|


|


|







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
     * Send the command to the target interpreter by appending it to the comm
     * window in the communication window.
     */

    localData.sendSerial++;
    Tcl_DStringInit(&request);
    Tcl_DStringAppend(&request, "\0c\0-n ", 6);
    Tcl_DStringAppend(&request, destName, TCL_INDEX_NONE);
    if (!async) {
	char buffer[TCL_INTEGER_SPACE * 2];

	snprintf(buffer, sizeof(buffer), "%x %d",
		(unsigned) Tk_WindowId(dispPtr->commTkwin),
		localData.sendSerial);
	Tcl_DStringAppend(&request, "\0-r ", 4);
	Tcl_DStringAppend(&request, buffer, TCL_INDEX_NONE);
    }
    Tcl_DStringAppend(&request, "\0-s ", 4);
    Tcl_DStringAppend(&request, Tcl_GetString(objv[firstArg]), TCL_INDEX_NONE);
    for (i = firstArg+1; i < objc; i++) {
	Tcl_DStringAppend(&request, " ", 1);
	Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), TCL_INDEX_NONE);
    }

    if (!async) {
	/*
	 * Register the fact that we're waiting for a command to complete
	 * (this is needed by SendEventProc and by AppendErrorProc to pass
	 * back the command's results). Set up a timeout handler so that
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
	 */

	Tcl_ResetResult(interp);
	Tcl_AddErrorInfo(interp, pending.errorInfo);
	ckfree(pending.errorInfo);
    }
    if (pending.errorCode != NULL) {
	Tcl_SetObjErrorCode(interp, Tcl_NewStringObj(pending.errorCode, -1));
	ckfree(pending.errorCode);
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(pending.result, -1));
    ckfree(pending.result);
    return pending.code;
}

/*
 *----------------------------------------------------------------------
 *







|


|







1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
	 */

	Tcl_ResetResult(interp);
	Tcl_AddErrorInfo(interp, pending.errorInfo);
	ckfree(pending.errorInfo);
    }
    if (pending.errorCode != NULL) {
	Tcl_SetObjErrorCode(interp, Tcl_NewStringObj(pending.errorCode, TCL_INDEX_NONE));
	ckfree(pending.errorCode);
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(pending.result, TCL_INDEX_NONE));
    ckfree(pending.result);
    return pending.code;
}

/*
 *----------------------------------------------------------------------
 *
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
	p++;
	if (ValidateName(winPtr->dispPtr, entryName, commWindow, 1)) {
	    /*
	     * The application still exists; add its name to the result.
	     */

	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(entryName, -1));
	} else {
	    int count;

	    /*
	     * This name is bogus (perhaps the application died without
	     * cleaning up its entry in the registry?). Delete the name.
	     */







|







1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
	p++;
	if (ValidateName(winPtr->dispPtr, entryName, commWindow, 1)) {
	    /*
	     * The application still exists; add its name to the result.
	     */

	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(entryName, TCL_INDEX_NONE));
	} else {
	    int count;

	    /*
	     * This name is bogus (perhaps the application died without
	     * cleaning up its entry in the registry?). Delete the name.
	     */
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
 *	the (ostensibly waiting) "send" commands. The property is deleted.
 *
 *--------------------------------------------------------------
 */

static void
SendEventProc(
    ClientData clientData,	/* Display information. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    const char *p;
    int result, actualFormat;
    unsigned long numItems, bytesAfter;







|







1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
 *	the (ostensibly waiting) "send" commands. The property is deleted.
 *
 *--------------------------------------------------------------
 */

static void
SendEventProc(
    void *clientData,	/* Display information. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    char *propInfo, **propInfoPtr = &propInfo;
    const char *p;
    int result, actualFormat;
    unsigned long numItems, bytesAfter;
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
	     * Initialize the result property, so that we're ready at any time
	     * if we need to return an error.
	     */

	    if (commWindow != None) {
		Tcl_DStringInit(&reply);
		Tcl_DStringAppend(&reply, "\0r\0-s ", 6);
		Tcl_DStringAppend(&reply, serial, -1);
		Tcl_DStringAppend(&reply, "\0-r ", 4);
	    }

	    if (!ServerSecure(dispPtr)) {
		if (commWindow != None) {
		    Tcl_DStringAppend(&reply,
			    "X server insecure (must use xauth-style "
			    "authorization); command ignored", -1);
		}
		result = TCL_ERROR;
		goto returnResult;
	    }

	    /*
	     * Locate the application, then execute the script.
	     */

	    for (riPtr = tsdPtr->interpListPtr; ; riPtr = riPtr->nextPtr) {
		if (riPtr == NULL) {
		    if (commWindow != None) {
			Tcl_DStringAppend(&reply,
				"receiver never heard of interpreter \"", -1);
			Tcl_DStringAppend(&reply, interpName, -1);
			Tcl_DStringAppend(&reply, "\"", 1);
		    }
		    result = TCL_ERROR;
		    goto returnResult;
		}
		if (strcmp(riPtr->name, interpName) == 0) {
		    break;
		}
	    }
	    Tcl_Preserve(riPtr);

	    /*
	     * We must protect the interpreter because the script may enter
	     * another event loop, which might call Tcl_DeleteInterp.
	     */

	    remoteInterp = riPtr->interp;
	    Tcl_Preserve(remoteInterp);

	    result = Tcl_EvalEx(remoteInterp, script, -1, TCL_EVAL_GLOBAL);

	    /*
	     * The call to Tcl_Release may have released the interpreter which
	     * will cause the "send" command for that interpreter to be
	     * deleted. The command deletion callback will set the
	     * riPtr->interp field to NULL, hence the check below for NULL.
	     */

	    if (commWindow != None) {
		Tcl_DStringAppend(&reply, Tcl_GetString(Tcl_GetObjResult(remoteInterp)),
			-1);
		if (result == TCL_ERROR) {
		    const char *varValue;

		    varValue = Tcl_GetVar2(remoteInterp, "errorInfo",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-i ", 4);
			Tcl_DStringAppend(&reply, varValue, -1);
		    }
		    varValue = Tcl_GetVar2(remoteInterp, "errorCode",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-e ", 4);
			Tcl_DStringAppend(&reply, varValue, -1);
		    }
		}
	    }
	    Tcl_Release(remoteInterp);
	    Tcl_Release(riPtr);

	    /*
	     * Return the result to the sender if a commWindow was specified
	     * (if none was specified then this is an asynchronous call).
	     * Right now reply has everything but the completion code, but it
	     * needs the NULL to terminate the current option.
	     */

	returnResult:
	    if (commWindow != None) {
		if (result != TCL_OK) {
		    char buffer[TCL_INTEGER_SPACE];

		    sprintf(buffer, "%d", result);
		    Tcl_DStringAppend(&reply, "\0-c ", 4);
		    Tcl_DStringAppend(&reply, buffer, -1);
		}
		(void) AppendPropCarefully(dispPtr->display, commWindow,
			dispPtr->commProperty, Tcl_DStringValue(&reply),
			Tcl_DStringLength(&reply) + 1, NULL);
		XFlush(dispPtr->display);
		Tcl_DStringFree(&reply);
	    }







|







|













|
|



















|


















|





|


















|

|







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
	     * Initialize the result property, so that we're ready at any time
	     * if we need to return an error.
	     */

	    if (commWindow != None) {
		Tcl_DStringInit(&reply);
		Tcl_DStringAppend(&reply, "\0r\0-s ", 6);
		Tcl_DStringAppend(&reply, serial, TCL_INDEX_NONE);
		Tcl_DStringAppend(&reply, "\0-r ", 4);
	    }

	    if (!ServerSecure(dispPtr)) {
		if (commWindow != None) {
		    Tcl_DStringAppend(&reply,
			    "X server insecure (must use xauth-style "
			    "authorization); command ignored", TCL_INDEX_NONE);
		}
		result = TCL_ERROR;
		goto returnResult;
	    }

	    /*
	     * Locate the application, then execute the script.
	     */

	    for (riPtr = tsdPtr->interpListPtr; ; riPtr = riPtr->nextPtr) {
		if (riPtr == NULL) {
		    if (commWindow != None) {
			Tcl_DStringAppend(&reply,
				"receiver never heard of interpreter \"", TCL_INDEX_NONE);
			Tcl_DStringAppend(&reply, interpName, TCL_INDEX_NONE);
			Tcl_DStringAppend(&reply, "\"", 1);
		    }
		    result = TCL_ERROR;
		    goto returnResult;
		}
		if (strcmp(riPtr->name, interpName) == 0) {
		    break;
		}
	    }
	    Tcl_Preserve(riPtr);

	    /*
	     * We must protect the interpreter because the script may enter
	     * another event loop, which might call Tcl_DeleteInterp.
	     */

	    remoteInterp = riPtr->interp;
	    Tcl_Preserve(remoteInterp);

	    result = Tcl_EvalEx(remoteInterp, script, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);

	    /*
	     * The call to Tcl_Release may have released the interpreter which
	     * will cause the "send" command for that interpreter to be
	     * deleted. The command deletion callback will set the
	     * riPtr->interp field to NULL, hence the check below for NULL.
	     */

	    if (commWindow != None) {
		Tcl_DStringAppend(&reply, Tcl_GetString(Tcl_GetObjResult(remoteInterp)),
			-1);
		if (result == TCL_ERROR) {
		    const char *varValue;

		    varValue = Tcl_GetVar2(remoteInterp, "errorInfo",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-i ", 4);
			Tcl_DStringAppend(&reply, varValue, TCL_INDEX_NONE);
		    }
		    varValue = Tcl_GetVar2(remoteInterp, "errorCode",
			    NULL, TCL_GLOBAL_ONLY);
		    if (varValue != NULL) {
			Tcl_DStringAppend(&reply, "\0-e ", 4);
			Tcl_DStringAppend(&reply, varValue, TCL_INDEX_NONE);
		    }
		}
	    }
	    Tcl_Release(remoteInterp);
	    Tcl_Release(riPtr);

	    /*
	     * Return the result to the sender if a commWindow was specified
	     * (if none was specified then this is an asynchronous call).
	     * Right now reply has everything but the completion code, but it
	     * needs the NULL to terminate the current option.
	     */

	returnResult:
	    if (commWindow != None) {
		if (result != TCL_OK) {
		    char buffer[TCL_INTEGER_SPACE];

		    snprintf(buffer, sizeof(buffer), "%d", result);
		    Tcl_DStringAppend(&reply, "\0-c ", 4);
		    Tcl_DStringAppend(&reply, buffer, TCL_INDEX_NONE);
		}
		(void) AppendPropCarefully(dispPtr->display, commWindow,
			dispPtr->commProperty, Tcl_DStringValue(&reply),
			Tcl_DStringLength(&reply) + 1, NULL);
		XFlush(dispPtr->display);
		Tcl_DStringFree(&reply);
	    }
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
/*
 * The function below is invoked if an error occurs during the XChangeProperty
 * operation above.
 */

static int
AppendErrorProc(
    ClientData clientData,	/* Command to mark complete, or NULL. */
    TCL_UNUSED(XErrorEvent *))	/* Information about error. */
{
    PendingCommand *pendingPtr = (PendingCommand *)clientData;
    PendingCommand *pcPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (pendingPtr == NULL) {
	return 0;
    }

    /*
     * Make sure this command is still pending.
     */

    for (pcPtr = tsdPtr->pendingCommands; pcPtr != NULL;
	    pcPtr = pcPtr->nextPtr) {
	if ((pcPtr == pendingPtr) && (pcPtr->result == NULL)) {
	    pcPtr->result = (char *)ckalloc(strlen(pcPtr->target) + 50);
	    sprintf(pcPtr->result, "no application named \"%s\"",
		    pcPtr->target);
	    pcPtr->code = TCL_ERROR;
	    pcPtr->gotResponse = 1;
	    break;
	}
    }
    return 0;







|



















|







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
/*
 * The function below is invoked if an error occurs during the XChangeProperty
 * operation above.
 */

static int
AppendErrorProc(
    void *clientData,	/* Command to mark complete, or NULL. */
    TCL_UNUSED(XErrorEvent *))	/* Information about error. */
{
    PendingCommand *pendingPtr = (PendingCommand *)clientData;
    PendingCommand *pcPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (pendingPtr == NULL) {
	return 0;
    }

    /*
     * Make sure this command is still pending.
     */

    for (pcPtr = tsdPtr->pendingCommands; pcPtr != NULL;
	    pcPtr = pcPtr->nextPtr) {
	if ((pcPtr == pendingPtr) && (pcPtr->result == NULL)) {
	    pcPtr->result = (char *)ckalloc(strlen(pcPtr->target) + 50);
	    snprintf(pcPtr->result, strlen(pcPtr->target) + 50, "no application named \"%s\"",
		    pcPtr->target);
	    pcPtr->code = TCL_ERROR;
	    pcPtr->gotResponse = 1;
	    break;
	}
    }
    return 0;
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
 *	The interpreter given by riPtr is unregistered.
 *
 *--------------------------------------------------------------
 */

static void
DeleteProc(
    ClientData clientData)	/* Info about registration, passed as
				 * ClientData. */
{
    RegisteredInterp *riPtr = (RegisteredInterp *)clientData;
    RegisteredInterp *riPtr2;
    NameRegistry *regPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));








|
<







1832
1833
1834
1835
1836
1837
1838
1839

1840
1841
1842
1843
1844
1845
1846
 *	The interpreter given by riPtr is unregistered.
 *
 *--------------------------------------------------------------
 */

static void
DeleteProc(
    void *clientData)	/* Info about registration */

{
    RegisteredInterp *riPtr = (RegisteredInterp *)clientData;
    RegisteredInterp *riPtr2;
    NameRegistry *regPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
 *	Depends on option; see below.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestsendCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    enum {
	TESTSEND_BOGUS, TESTSEND_PROP, TESTSEND_SERIAL
    };
    static const char *const testsendOptions[] = {
	"bogus",   "prop",   "serial",  NULL







|

|







1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
 *	Depends on option; see below.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestsendCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    enum {
	TESTSEND_BOGUS, TESTSEND_PROP, TESTSEND_SERIAL
    };
    static const char *const testsendOptions[] = {
	"bogus",   "prop",   "serial",  NULL
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
	    if ((result == Success) && (actualType != None)
		    && (actualFormat == 8) && (actualType == XA_STRING)) {
		for (p = property; (unsigned long)(p-property) < length; p++) {
		    if (*p == 0) {
			*p = '\n';
		    }
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(property, -1));
	    }
	    if (property != NULL) {
		XFree(property);
	    }
	} else if (Tcl_GetString(objv[4])[0] == 0) {
            handler = Tk_CreateErrorHandler(winPtr->dispPtr->display,
                    -1, -1, -1, NULL, NULL);







|







2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
	    if ((result == Success) && (actualType != None)
		    && (actualFormat == 8) && (actualType == XA_STRING)) {
		for (p = property; (unsigned long)(p-property) < length; p++) {
		    if (*p == 0) {
			*p = '\n';
		    }
		}
		Tcl_SetObjResult(interp, Tcl_NewStringObj(property, TCL_INDEX_NONE));
	    }
	    if (property != NULL) {
		XFree(property);
	    }
	} else if (Tcl_GetString(objv[4])[0] == 0) {
            handler = Tk_CreateErrorHandler(winPtr->dispPtr->display,
                    -1, -1, -1, NULL, NULL);

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
222
223
224
225
226
227
228
229
230
231
232
233
/*
 * 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 Tcl_CmdDeleteProc SysNotifyDeleteCmd;
static Tcl_ObjCmdProc SysNotifyCmd;

/*
 *----------------------------------------------------------------------
 *
 * 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;
    const char *appname = "Wish";
    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";


    /* Use the appname for libnotify initialization
     * See bug f63c37be3a for a discussion whether this should be
     * allowed at all on safe interpreters
     */
    if (!Tcl_IsSafe(interp)) {
	appname = ((TkWindow *)Tk_MainWindow(interp))->nameUid;
    }

    /*
     * 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;

	Tcl_DStringInit(&dst);
	Tcl_DStringInit(&dsm);
	enc = Tcl_GetEncoding(NULL, "utf-8");
	char *dstStr = Tcl_UtfToExternalDString(enc, title, TCL_INDEX_NONE, &dst);
	char *dsmStr = Tcl_UtfToExternalDString(enc, message, TCL_INDEX_NONE, &dsm);
	notify_init(appname);
	notif = notify_notification_new(dstStr, dsmStr, 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], TCL_INDEX_NONE);
	    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);
    if (!notify_init) return TCL_OK;

    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
/*
 * 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 Tcl_ObjCmdProc TrayIconCreateCmd;
static Tcl_ObjCmdProc TrayIconObjectCmd;
static int TrayIconConfigureMethod(DockIcon *icon, Tcl_Interp *interp,
	Tcl_Size 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 Tcl_CmdDeleteProc TrayIconDeleteProc;
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(void *cd);

static void RetargetEvent(DockIcon *icon, XEvent *ev);

static void TrayIconEvent(void *cd, XEvent* ev);
static void UserIconEvent(void *cd, XEvent* ev);
static void TrayIconWrapperEvent(void *cd, XEvent* ev);
static int IconGenericHandler(void *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(
    void *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", TCL_INDEX_NONE));
	} else {
	    switch(QueryTrayOrientation(icon)) {
	    case 0:
		Tcl_SetObjResult(interp, Tcl_NewStringObj("horizontal", TCL_INDEX_NONE));
		break;
	    case 1:
		Tcl_SetObjResult(interp, Tcl_NewStringObj("vertical", TCL_INDEX_NONE));
		break;
	    default:
		Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown", TCL_INDEX_NONE));
		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];
    snprintf(buf,256,"_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];
	snprintf(numeric,256,"%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_InterpState saved;
    Tk_Window tkwin;
    Tk_Window wrapper;
    XSetWindowAttributes attr;

    saved = Tcl_SaveInterpState(icon->interp, TCL_OK);
    /* 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, 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, 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_RestoreInterpState(icon->interp, saved);
}

/*
 *----------------------------------------------------------------------
 *
 * 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",
	NULL, TCL_INDEX_NONE, offsetof(DockIcon, imageString),
	TK_OPTION_NULL_OK, NULL,
	ICON_CONF_IMAGE | ICON_CONF_REDISPLAY},
    {TK_OPTION_STRING,"-class","class","Class",
	"TrayIcon", TCL_INDEX_NONE, offsetof(DockIcon, classString),
	0, NULL, ICON_CONF_CLASS},
    {TK_OPTION_BOOLEAN,"-docked","docked","Docked",
	"1", TCL_INDEX_NONE, offsetof(DockIcon, docked), 0, NULL,
	ICON_CONF_XEMBED | ICON_CONF_REDISPLAY},
    {TK_OPTION_BOOLEAN,"-shape","shape","Shape",
	"0", TCL_INDEX_NONE, offsetof(DockIcon, useShapeExt), 0, NULL,
	ICON_CONF_IMAGE | ICON_CONF_REDISPLAY},
    {TK_OPTION_BOOLEAN,"-visible","visible","Visible",
	"1", TCL_INDEX_NONE, 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(
    void *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(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, icon);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 *  DisplayIcon --
 *
 * 	Main function for displaying icon.
 *
 * Results:
 *	Icon image is displayed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayIcon(
    void *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_InterpState saved
			= Tcl_SaveInterpState(icon->interp, TCL_OK);
		icon->imageVisualInstance = Tk_GetImage(icon->interp,icon->drawingWin,
                        icon->imageString, IgnoreImageChange, NULL);
		Tcl_RestoreInterpState(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(
    void *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(
    void *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, 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(
    void *cd,
    XEvent* ev)
{
    DockIcon *icon = (DockIcon*)cd;

    switch (ev->type) {

    case DestroyNotify:
	Tk_DeleteGenericHandler(IconGenericHandler, icon);
	if(icon->drawingWin) {
	    icon->visible = 0;
	    Tcl_CancelIdleCall(DisplayIcon, 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(
    void *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,
    Tcl_Size 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, 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, 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(
    void *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(
    void *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", TCL_INDEX_NONE));
	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, 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, 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, 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(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
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"









|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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 © 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"

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    double alpha;		/* Transparency; 0.0=transparent, 1.0=opaque */
    int topmost;		/* Flag: true=>stay-on-top */
    int zoomed;			/* Flag: true=>maximized */
    int fullscreen;		/* Flag: true=>fullscreen */
} WmAttributes;

typedef enum {
    WMATT_ALPHA, WMATT_TOPMOST, WMATT_ZOOMED, WMATT_FULLSCREEN,
    WMATT_TYPE, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-topmost", "-zoomed", "-fullscreen",
    "-type", NULL
};

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */








|
|



|
|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    double alpha;		/* Transparency; 0.0=transparent, 1.0=opaque */
    int topmost;		/* Flag: true=>stay-on-top */
    int zoomed;			/* Flag: true=>maximized */
    int fullscreen;		/* Flag: true=>fullscreen */
} WmAttributes;

typedef enum {
    WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_TOPMOST, WMATT_TYPE,
    WMATT_ZOOMED, _WMATT_LAST_ATTRIBUTE
} WmAttribute;

static const char *const WmAttributeNames[] = {
    "-alpha", "-fullscreen", "-topmost", "-type",
    "-zoomed", NULL
};

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
     * Miscellaneous information.
     */

    WmAttributes attributes;	/* Current state of [wm attributes] */
    WmAttributes reqState;	/* Requested state of [wm attributes] */
    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    int cmdArgc;		/* Number of elements in cmdArgv below. */
    const char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
				 * property. NULL means nothing available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */
    int numTransients;		/* number of transients on this window */
    int iconDataSize;		/* size of iconphoto image data */







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
     * Miscellaneous information.
     */

    WmAttributes attributes;	/* Current state of [wm attributes] */
    WmAttributes reqState;	/* Requested state of [wm attributes] */
    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    Tcl_Size cmdArgc;		/* Number of elements in cmdArgv below. */
    const char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
				 * property. NULL means nothing available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */
    int numTransients;		/* number of transients on this window */
    int iconDataSize;		/* size of iconphoto image data */
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
 */

/*
 * The following structures are the official type records for geometry
 * management of top-level and menubar windows.
 */

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
static void		MenubarReqProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};







|

|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
 */

/*
 * The following structures are the official type records for geometry
 * management of top-level and menubar windows.
 */

static void		TopLevelReqProc(void *dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
static void		MenubarReqProc(void *clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416



417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

static int		ComputeReparentGeometry(WmInfo *wmPtr);
static void		ConfigureEvent(WmInfo *wmPtr,
			    XConfigureEvent *eventPtr);
static void		CreateWrapper(WmInfo *wmPtr);
static void		GetMaxSize(WmInfo *wmPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		MenubarDestroyProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ParseGeometry(Tcl_Interp *interp, const char *string,
			    TkWindow *winPtr);
static void		ReparentEvent(WmInfo *wmPtr, XReparentEvent *eventPtr);
static void		PropertyEvent(WmInfo *wmPtr, XPropertyEvent *eventPtr);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *reparentTable);
static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
static void		UpdateCommand(TkWindow *winPtr);
static void		UpdateGeometryInfo(ClientData clientData);
static void		UpdateHints(TkWindow *winPtr);
static void		UpdateSizeHints(TkWindow *winPtr,
			    int newWidth, int newHeight);
static void		UpdateTitle(TkWindow *winPtr);
static void		UpdatePhotoIcon(TkWindow *winPtr);
static void		UpdateVRootGeometry(WmInfo *wmPtr);
static void		UpdateWmProtocols(WmInfo *wmPtr);
static int		SetNetWmType(TkWindow *winPtr, Tcl_Obj *typePtr);
static Tcl_Obj *	GetNetWmType(TkWindow *winPtr);
static void 		SetNetWmState(TkWindow*, const char *atomName, int on);
static void 		CheckNetWmState(WmInfo *, Atom *atoms, int numAtoms);
static void 		UpdateNetWmState(WmInfo *);
static void		WaitForConfigureNotify(TkWindow *winPtr,
			    unsigned long serial);
static int		WaitForEvent(Display *display,
			    WmInfo *wmInfoPtr, int type, XEvent *eventPtr);
static void		WaitForMapNotify(TkWindow *winPtr, int mapped);
static Tk_RestrictProc WaitRestrictProc;
static void		WrapperEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		WmWaitMapProc(ClientData clientData,
			    XEvent *eventPtr);
static int		WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);



static int		WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);

/*
 *--------------------------------------------------------------
 *
 * TkWmCleanup --







|







|


|


















|

|


|


|


|


|


|


|


|


|


|


|


|


|

>
>
>

|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

static int		ComputeReparentGeometry(WmInfo *wmPtr);
static void		ConfigureEvent(WmInfo *wmPtr,
			    XConfigureEvent *eventPtr);
static void		CreateWrapper(WmInfo *wmPtr);
static void		GetMaxSize(WmInfo *wmPtr, int *maxWidthPtr,
			    int *maxHeightPtr);
static void		MenubarDestroyProc(void *clientData,
			    XEvent *eventPtr);
static int		ParseGeometry(Tcl_Interp *interp, const char *string,
			    TkWindow *winPtr);
static void		ReparentEvent(WmInfo *wmPtr, XReparentEvent *eventPtr);
static void		PropertyEvent(WmInfo *wmPtr, XPropertyEvent *eventPtr);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *reparentTable);
static void		TopLevelReqProc(void *dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, TkWindow *parentPtr);
static void		UpdateCommand(TkWindow *winPtr);
static void		UpdateGeometryInfo(void *clientData);
static void		UpdateHints(TkWindow *winPtr);
static void		UpdateSizeHints(TkWindow *winPtr,
			    int newWidth, int newHeight);
static void		UpdateTitle(TkWindow *winPtr);
static void		UpdatePhotoIcon(TkWindow *winPtr);
static void		UpdateVRootGeometry(WmInfo *wmPtr);
static void		UpdateWmProtocols(WmInfo *wmPtr);
static int		SetNetWmType(TkWindow *winPtr, Tcl_Obj *typePtr);
static Tcl_Obj *	GetNetWmType(TkWindow *winPtr);
static void 		SetNetWmState(TkWindow*, const char *atomName, int on);
static void 		CheckNetWmState(WmInfo *, Atom *atoms, int numAtoms);
static void 		UpdateNetWmState(WmInfo *);
static void		WaitForConfigureNotify(TkWindow *winPtr,
			    unsigned long serial);
static int		WaitForEvent(Display *display,
			    WmInfo *wmInfoPtr, int type, XEvent *eventPtr);
static void		WaitForMapNotify(TkWindow *winPtr, int mapped);
static Tk_RestrictProc WaitRestrictProc;
static void		WrapperEventProc(void *clientData,
			    XEvent *eventPtr);
static void		WmWaitMapProc(void *clientData,
			    XEvent *eventPtr);
static int		WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbadgeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
			    Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);

/*
 *--------------------------------------------------------------
 *
 * TkWmCleanup --
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	UpdateHints(winPtr);
	UpdateWmProtocols(wmPtr);
	if (wmPtr->cmdArgv != NULL) {
	    UpdateCommand(winPtr);
	}
	if (wmPtr->clientMachine != NULL) {
	    Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, -1, &ds);
	    if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
		    &textProp) != 0) {
		unsigned long pid = (unsigned long) getpid();

		XSetWMClientMachine(winPtr->display,
			wmPtr->wrapperPtr->window, &textProp);
		XFree((char *) textProp.value);

		/*
		 * Inform the server (and more particularly any session
		 * manager) what our process ID is. We only do this when the
		 * CLIENT_MACHINE property is set since the spec for
		 * _NET_WM_PID requires that to be set too.
		 */







|






|







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	UpdateHints(winPtr);
	UpdateWmProtocols(wmPtr);
	if (wmPtr->cmdArgv != NULL) {
	    UpdateCommand(winPtr);
	}
	if (wmPtr->clientMachine != NULL) {
	    (void)Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, TCL_INDEX_NONE, &ds);
	    if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
		    &textProp) != 0) {
		unsigned long pid = (unsigned long) getpid();

		XSetWMClientMachine(winPtr->display,
			wmPtr->wrapperPtr->window, &textProp);
		XFree(textProp.value);

		/*
		 * Inform the server (and more particularly any session
		 * manager) what our process ID is. We only do this when the
		 * CLIENT_MACHINE property is set since the spec for
		 * _NET_WM_PID requires that to be set too.
		 */
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
	return;
    }

    if (winPtr->classUid != NULL) {
	XClassHint *classPtr;
	Tcl_DString name, ds;

	Tcl_UtfToExternalDString(NULL, winPtr->nameUid, -1, &name);
	Tcl_UtfToExternalDString(NULL, winPtr->classUid, -1, &ds);
	classPtr = XAllocClassHint();
	classPtr->res_name = Tcl_DStringValue(&name);
	classPtr->res_class = Tcl_DStringValue(&ds);
	XSetClassHint(winPtr->display, winPtr->wmInfoPtr->wrapperPtr->window,
		classPtr);
	XFree((char *) classPtr);
	Tcl_DStringFree(&name);
	Tcl_DStringFree(&ds);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WmObjCmd --
 *
 *	This function is invoked to process the "wm" Tcl command.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname", "iconphoto",
	"iconposition", "iconwindow", "manage", "maxsize",
	"minsize", "overrideredirect", "positionfrom",
	"protocol", "resizable", "sizefrom", "stackorder",
	"state", "title", "transient", "withdraw", NULL };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,
	WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPHOTO,
	WMOPT_ICONPOSITION, WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE,
	WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, WMOPT_POSITIONFROM,
	WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, WMOPT_STACKORDER,
	WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, WMOPT_WITHDRAW };
    int index;
    const char *argv1;







|
|





|

















|








|









|







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
	return;
    }

    if (winPtr->classUid != NULL) {
	XClassHint *classPtr;
	Tcl_DString name, ds;

	(void)Tcl_UtfToExternalDString(NULL, winPtr->nameUid, TCL_INDEX_NONE, &name);
	(void)Tcl_UtfToExternalDString(NULL, winPtr->classUid, TCL_INDEX_NONE, &ds);
	classPtr = XAllocClassHint();
	classPtr->res_name = Tcl_DStringValue(&name);
	classPtr->res_class = Tcl_DStringValue(&ds);
	XSetClassHint(winPtr->display, winPtr->wmInfoPtr->wrapperPtr->window,
		classPtr);
	XFree(classPtr);
	Tcl_DStringFree(&name);
	Tcl_DStringFree(&ds);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WmObjCmd --
 *
 *	This function is invoked to process the "wm" Tcl command.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget",
	"frame", "geometry", "grid", "group", "iconbadge", "iconbitmap",
	"iconify", "iconmask", "iconname", "iconphoto",
	"iconposition", "iconwindow", "manage", "maxsize",
	"minsize", "overrideredirect", "positionfrom",
	"protocol", "resizable", "sizefrom", "stackorder",
	"state", "title", "transient", "withdraw", NULL };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,
	WMOPT_ICONBADGE, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPHOTO,
	WMOPT_ICONPOSITION, WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE,
	WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, WMOPT_POSITIONFROM,
	WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, WMOPT_STACKORDER,
	WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, WMOPT_WITHDRAW };
    int index;
    const char *argv1;
1112
1113
1114
1115
1116
1117
1118


1119
1120
1121
1122
1123
1124
1125
	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GEOMETRY:
	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GRID:
	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GROUP:
	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);


    case WMOPT_ICONBITMAP:
	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONIFY:
	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONMASK:
	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONNAME:







>
>







1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GEOMETRY:
	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GRID:
	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GROUP:
	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONBADGE:
	return WmIconbadgeCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONBITMAP:
	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONIFY:
	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONMASK:
	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONNAME:
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,







|







1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;







|







1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
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
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewListObj(0,0);

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(interp, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
	    Tcl_ListObjAppendElement(interp, result,
		    WmGetAttribute(winPtr, (WmAttribute)attribute));
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], WmAttributeNames,
		sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, (WmAttribute)attribute));
	return TCL_OK;
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	int i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
		    sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr,interp,(WmAttribute)attribute,objv[i+1]) != TCL_OK) {







|









|













|







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
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int attribute = 0;

    if (objc == 3) {		/* wm attributes $win */
	Tcl_Obj *result = Tcl_NewListObj(0,0);

	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
	    Tcl_ListObjAppendElement(interp, result,
		    Tcl_NewStringObj(WmAttributeNames[attribute], TCL_INDEX_NONE));
	    Tcl_ListObjAppendElement(interp, result,
		    WmGetAttribute(winPtr, (WmAttribute)attribute));
	}
	Tcl_SetObjResult(interp, result);
	return TCL_OK;
    } else if (objc == 4) {	/* wm attributes $win -attribute */
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], WmAttributeNames,
		sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, (WmAttribute)attribute));
	return TCL_OK;
    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
	Tcl_Size i;

	for (i = 3; i < objc; i += 2) {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], WmAttributeNames,
		    sizeof(char *), "attribute", 0, &attribute) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (WmSetAttribute(winPtr,interp,(WmAttribute)attribute,objv[i+1]) != TCL_OK) {
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
WmClientCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);







|












|







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
 */

static int
WmClientCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
    }
    wmPtr->clientMachine = (char *)ckalloc(objv[3]->length + 1);
    strcpy(wmPtr->clientMachine, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;
	Tcl_DString ds;

	Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, -1, &ds);
	if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
		&textProp) != 0) {
	    unsigned long pid = (unsigned long) getpid();

	    XSetWMClientMachine(winPtr->display, wmPtr->wrapperPtr->window,
		    &textProp);
	    XFree((char *) textProp.value);

	    /*
	     * Inform the server (and more particularly any session manager)
	     * what our process ID is. We only do this when the CLIENT_MACHINE
	     * property is set since the spec for _NET_WM_PID requires that to
	     * be set too.
	     */







|






|







1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
    }
    wmPtr->clientMachine = (char *)ckalloc(objv[3]->length + 1);
    strcpy(wmPtr->clientMachine, argv3);
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;
	Tcl_DString ds;

	(void)Tcl_UtfToExternalDString(NULL, wmPtr->clientMachine, TCL_INDEX_NONE, &ds);
	if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
		&textProp) != 0) {
	    unsigned long pid = (unsigned long) getpid();

	    XSetWMClientMachine(winPtr->display, wmPtr->wrapperPtr->window,
		    &textProp);
	    XFree(textProp.value);

	    /*
	     * Inform the server (and more particularly any session manager)
	     * what our process ID is. We only do this when the CLIENT_MACHINE
	     * property is set since the spec for _NET_WM_PID requires that to
	     * be set too.
	     */
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
 */

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window *cmapList;
    TkWindow *winPtr2;
    int count, i, windowObjc, gotToplevel;

    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    Tk_MakeWindowExist((Tk_Window) winPtr);
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    if (objc == 3) {
	if (XGetWMColormapWindows(winPtr->display,
		wmPtr->wrapperPtr->window, &cmapList, &count) == 0) {
	    return TCL_OK;
	}
	resultObj = Tcl_NewObj();
	for (i = 0; i < count; i++) {
	    if ((i == (count-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    winPtr2 = (TkWindow *)
		   Tk_IdToWindow(winPtr->display, cmapList[i]);
	    if (winPtr2 == NULL) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_ObjPrintf("0x%lx", cmapList[i]));
	    } else {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(winPtr2->pathName, -1));
	    }
	}
	XFree((char *) cmapList);
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }







|





|
>
















|
|










|


|







1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
 */

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window *cmapList;
    TkWindow *winPtr2;
    Tcl_Size i, windowObjc;
    int count, gotToplevel;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    Tk_MakeWindowExist((Tk_Window) winPtr);
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    if (objc == 3) {
	if (XGetWMColormapWindows(winPtr->display,
		wmPtr->wrapperPtr->window, &cmapList, &count) == 0) {
	    return TCL_OK;
	}
	resultObj = Tcl_NewObj();
	for (i = 0; i < (Tcl_Size)count; i++) {
	    if ((i == ((Tcl_Size)count-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    winPtr2 = (TkWindow *)
		   Tk_IdToWindow(winPtr->display, cmapList[i]);
	    if (winPtr2 == NULL) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_ObjPrintf("0x%lx", cmapList[i]));
	    } else {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(winPtr2->pathName, TCL_INDEX_NONE));
	    }
	}
	XFree(cmapList);
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
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
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int cmdArgc;
    const char **cmdArgv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
	    char *arg = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, -1));
	    ckfree(arg);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {







|




|










|







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
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    Tcl_Size cmdArgc;
    const char **cmdArgv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
	    char *arg = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, TCL_INDEX_NONE));
	    ckfree(arg);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;







|







1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", -1));
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }







|















|







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
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", TCL_INDEX_NONE));
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
 */

static int
WmForgetCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	TkFocusJoin(winPtr);
	Tk_UnmapWindow(frameWin);







|







1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
 */

static int
WmForgetCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),		/* Current interpreter. */
    TCL_UNUSED(Tcl_Size),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;

    if (Tk_IsTopLevel(frameWin)) {
	TkFocusJoin(winPtr);
	Tk_UnmapWindow(frameWin);
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --







|














|
|







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
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Window window;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    const char *argv3;








|







1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    const char *argv3;

1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,







|







1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;

    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
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
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
	 */

	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
	wmPtr->heightInc = 1;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) !=TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseWidth can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseHeight can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "widthInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "heightInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;







|

















|





|





|





|







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
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
	 */

	wmPtr->sizeHintsFlags &= ~PBaseSize;
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
	wmPtr->heightInc = 1;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) !=TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseWidth can't be < 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseHeight can't be < 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "widthInc can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "heightInc can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
 */

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {







|













|







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
 */

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
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
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *










































 * WmIconbitmapCmd --
 *
 *	This function is invoked to process the "wm iconbitmap" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display,
			    wmPtr->hints.icon_pixmap), -1));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



















|














|







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
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconbadgeCmd --
 *
 *	This function is invoked to process the "wm iconbadge" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbadgeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *tkWin,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    (void) tkWin;
    char cmd[4096];

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window badge");
	return TCL_ERROR;
    }

    snprintf(cmd, sizeof(cmd), "::tk::icons::IconBadge {%s} {%s}",
	    Tcl_GetString(objv[2]),
	    Tcl_GetString(objv[3]));
    if (Tcl_EvalEx(interp, cmd, TCL_INDEX_NONE, TCL_EVAL_DIRECT) != TCL_OK) {
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconbitmapCmd --
 *
 *	This function is invoked to process the "wm iconbitmap" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tk_NameOfBitmap(winPtr->display,
			    wmPtr->hints.icon_pixmap), TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;







|







2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
		"can't iconify \"%s\": it is an embedded window",
		winPtr->pathName));
	Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
	return TCL_ERROR;
    }
    if (TkpWmSetState(winPtr, IconicState) == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't send iconify message to window manager", -1));
	Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
		"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", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
 */

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {







|







2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
 */

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
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
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1));
	}
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = Tcl_GetString(objv[3]);







|











|







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
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->iconName != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, TCL_INDEX_NONE));
	}
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = Tcl_GetString(objv[3]);
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386

2387
2388
2389
2390
2391
2392
2393
2394
 */

static int
WmIconphotoCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;

    int i, size = 0, width, height, index = 0, x, y, isDefault = 0;
    unsigned long *iconPropertyData;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }







|





>
|







2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
 */

static int
WmIconphotoCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    Tcl_Size i;
    int size = 0, width, height, index = 0, x, y, isDefault = 0;
    unsigned long *iconPropertyData;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
	return TCL_ERROR;
    }
    memset(iconPropertyData, 0, sizeof(unsigned long) * size);

    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    ckfree((char *) iconPropertyData);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	        "failed to create an iconphoto with image \"%s\"",
		Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);







|







2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
	return TCL_ERROR;
    }
    memset(iconPropertyData, 0, sizeof(unsigned long) * size);

    for (i = 3 + isDefault; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	if (photo == NULL) {
	    ckfree(iconPropertyData);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	        "failed to create an iconphoto with image \"%s\"",
		Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetSize(photo, &width, &height);
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");







|







2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
 */

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;








|







2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
 */

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;

2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
 */

static int
WmManageCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(int),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {







|







2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
 */

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(Tcl_Size),			/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;

    if (width <= 0 && height <= 0) {







|


|


















|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
	    || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;

    if (width <= 0 && height <= 0) {
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	results[0] = Tcl_NewWideIntObj(wmPtr->minWidth);
	results[1] = Tcl_NewWideIntObj(wmPtr->minHeight);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;







|


|

















|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	results[0] = Tcl_NewWideIntObj(wmPtr->minWidth);
	results[1] = Tcl_NewWideIntObj(wmPtr->minHeight);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
	    || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
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
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int boolean, curValue;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(curValue != 0));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	/*
	 * Only do this if we are really changing value, because it causes
	 * some funky stuff to occur
	 */

	atts.override_redirect = (boolean) ? True : False;
	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		&atts);
	if (winPtr->wmInfoPtr->wrapperPtr != NULL) {
	    Tk_ChangeWindowAttributes(
		    (Tk_Window) winPtr->wmInfoPtr->wrapperPtr,
		    CWOverrideRedirect, &atts);
	}







|


|











|


|





|







2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Bool boolValue, curValue;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(curValue != 0));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolValue) {
	/*
	 * Only do this if we are really changing value, because it causes
	 * some funky stuff to occur
	 */

	atts.override_redirect = boolValue;
	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		&atts);
	if (winPtr->wmInfoPtr->wrapperPtr != NULL) {
	    Tk_ChangeWindowAttributes(
		    (Tk_Window) winPtr->wmInfoPtr->wrapperPtr,
		    CWOverrideRedirect, &atts);
	}
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };







|







2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size 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 };
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USPosition) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {







|







3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USPosition) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, TCL_INDEX_NONE));
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    const char *cmd;
    TkSizeT cmdLength;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*







|






|







3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    const char *cmd;
    Tcl_Size cmdLength;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
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
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, -1));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Special case for _NET_WM_PING: that's always handled directly.
     */

    if (strcmp(Tcl_GetString(objv[3]), "_NET_WM_PING") == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not alter handling of that protocol", -1));
	Tcl_SetErrorCode(interp, "TK", "WM", "PROTOCOL", "RESERVED", NULL);
	return TCL_ERROR;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.







|












|







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
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, TCL_INDEX_NONE));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
     * Special case for _NET_WM_PING: that's always handled directly.
     */

    if (strcmp(Tcl_GetString(objv[3]), "_NET_WM_PING") == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not alter handling of that protocol", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "WM", "PROTOCOL", "RESERVED", NULL);
	return TCL_ERROR;
    }

    /*
     * Delete any current protocol handler, then create a new one with the
     * specified command, unless the command is empty.
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);
    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);







|







3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *)ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");







|







3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };







|







3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size 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 };
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USSize) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,







|







3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USSize) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, TCL_INDEX_NONE));
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
 */

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **window_ptr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW };







|







3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
 */

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **window_ptr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW };
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    /* ASSERT: true [Bug 1789819]*/
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj((*window_ptr)->pathName, -1));
	    }
	    ckfree(windows);
	    Tcl_SetObjResult(interp, resultObj);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}







|







3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
	windows = TkWmStackorderToplevel(winPtr);
	if (windows != NULL) {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    /* ASSERT: true [Bug 1789819]*/
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj((*window_ptr)->pathName, TCL_INDEX_NONE));
	    }
	    ckfree(windows);
	    Tcl_SetObjResult(interp, resultObj);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}

	for (window_ptr = windows; *window_ptr ; window_ptr++) {
	    if (*window_ptr == winPtr) {
		index1 = (window_ptr - windows);







|







3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}

	for (window_ptr = windows; *window_ptr ; window_ptr++) {
	    if (*window_ptr == winPtr) {
		index1 = (window_ptr - windows);
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {







|




|

|







3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"iconic", "normal", "withdrawn", NULL };
    enum options {
	OPT_ICONIC, OPT_NORMAL, OPT_WITHDRAWN };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
	} else if (Tk_IsMapped((Tk_Window) winPtr)
		|| ((wmPtr->flags & WM_NEVER_MAPPED)
			&& (wmPtr->hints.initial_state == NormalState))) {
	    state = "normal";
	} else {
	    state = "iconic";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(state, -1));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|







3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
	} else if (Tk_IsMapped((Tk_Window) winPtr)
		|| ((wmPtr->flags & WM_NEVER_MAPPED)
			&& (wmPtr->hints.initial_state == NormalState))) {
	    state = "normal";
	} else {
	    state = "iconic";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(state, TCL_INDEX_NONE));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
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
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->title) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->title, -1));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, -1));
	}
    } else {
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	argv3 = Tcl_GetString(objv[3]);
	wmPtr->title = (char *)ckalloc(objv[3]->length + 1);







|











|

|







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
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->title) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->title, TCL_INDEX_NONE));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, TCL_INDEX_NONE));
	}
    } else {
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	argv3 = Tcl_GetString(objv[3]);
	wmPtr->title = (char *)ckalloc(objv[3]->length + 1);
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
 */

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *containerPtr = wmPtr->containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {







|







3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
 */

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *containerPtr = wmPtr->containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }







|







3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	    w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
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
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }
    wmPtr->flags |= WM_WITHDRAWN;
    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't send withdraw message to window manager", -1));
	Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|


















|







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
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }
    wmPtr->flags |= WM_WITHDRAWN;
    if (TkpWmSetState(winPtr, WithdrawnState) == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"couldn't send withdraw message to window manager", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
/*
 * Invoked when a MapNotify or UnmapNotify event is delivered for a toplevel
 * that is the container of a transient toplevel.
 */

static void
WmWaitMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL) {
	return;







|







3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
/*
 * Invoked when a MapNotify or UnmapNotify event is delivered for a toplevel
 * that is the container of a transient toplevel.
 */

static void
WmWaitMapProc(
    void *clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL) {
	return;
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
		    == (PBaseSize|PResizeInc))) {
	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel
     * units and there's no easy way to translate them to grid units since the







|
<







3860
3861
3862
3863
3864
3865
3866
3867

3868
3869
3870
3871
3872
3873
3874
	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & PBaseSize) == PBaseSize)) {

	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel
     * units and there's no easy way to translate them to grid units since the
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}








|







3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
    }

    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;







|







3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
    }

    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~PBaseSize;
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
	if ((actualFormat == 32) && (numItems == 1)) {
	    vRoot = wmPtr->vRoot = *virtualRootPtr;
	} else if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	    printf("%s format %d numItems %ld\n",
		    "ReparentEvent got bogus VROOT property:", actualFormat,
		    numItems);
	}
	XFree((char *) virtualRootPtr);
    }
    Tk_DeleteErrorHandler(handler);

    if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	printf("ReparentEvent: %s (%p) reparented to 0x%x, vRoot = 0x%x\n",
		wmPtr->winPtr->pathName, wmPtr->winPtr,
		(unsigned) reparentEventPtr->parent, (unsigned) vRoot);







|







4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
	if ((actualFormat == 32) && (numItems == 1)) {
	    vRoot = wmPtr->vRoot = *virtualRootPtr;
	} else if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	    printf("%s format %d numItems %ld\n",
		    "ReparentEvent got bogus VROOT property:", actualFormat,
		    numItems);
	}
	XFree(virtualRootPtr);
    }
    Tk_DeleteErrorHandler(handler);

    if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
	printf("ReparentEvent: %s (%p) reparented to 0x%x, vRoot = 0x%x\n",
		wmPtr->winPtr->pathName, wmPtr->winPtr,
		(unsigned) reparentEventPtr->parent, (unsigned) vRoot);
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
    wmPtr->reparent = reparentEventPtr->parent;
    while (1) {
	if (XQueryTree(wrapperPtr->display, wmPtr->reparent, &dummy2,
		&ancestor, &children, &dummy) == 0) {
	    Tk_DeleteErrorHandler(handler);
	    goto noReparent;
	}
	XFree((char *) children);
	if ((ancestor == vRoot) ||
		(ancestor == RootWindow(wrapperPtr->display,
		wrapperPtr->screenNum))) {
	    break;
	}
	wmPtr->reparent = ancestor;
    }







|







4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
    wmPtr->reparent = reparentEventPtr->parent;
    while (1) {
	if (XQueryTree(wrapperPtr->display, wmPtr->reparent, &dummy2,
		&ancestor, &children, &dummy) == 0) {
	    Tk_DeleteErrorHandler(handler);
	    goto noReparent;
	}
	XFree(children);
	if ((ancestor == vRoot) ||
		(ancestor == RootWindow(wrapperPtr->display,
		wrapperPtr->screenNum))) {
	    break;
	}
	wmPtr->reparent = ancestor;
    }
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
 */

static const unsigned WrapperEventMask =
	(StructureNotifyMask | PropertyChangeMask);

static void
WrapperEventProc(
    ClientData clientData,	/* Information about toplevel window. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    WmInfo *wmPtr = (WmInfo *)clientData;
    XEvent mapEvent;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;

    wmPtr->flags |= WM_VROOT_OFFSET_STALE;







|







4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
 */

static const unsigned WrapperEventMask =
	(StructureNotifyMask | PropertyChangeMask);

static void
WrapperEventProc(
    void *clientData,	/* Information about toplevel window. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    WmInfo *wmPtr = (WmInfo *)clientData;
    XEvent mapEvent;
    TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;

    wmPtr->flags |= WM_VROOT_OFFSET_STALE;
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
 *	change, unless the WM prevents that from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;
    unsigned long serial;

    wmPtr->flags &= ~WM_UPDATE_PENDING;







|







4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
 *	change, unless the WM prevents that from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    void *clientData)	/* Pointer to the window's record. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;
    unsigned long serial;

    wmPtr->flags &= ~WM_UPDATE_PENDING;
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
     *	  of 4/24/91) where they don't interpret coordinates according to
     *	  ICCCM. Moving a window to its current location may cause it to shift
     *	  position on the screen.
     */

    if ((winPtr->flags & (TK_EMBEDDED|TK_BOTH_HALVES))
	    == (TK_EMBEDDED|TK_BOTH_HALVES)) {
	TkWindow *childPtr = TkpGetOtherWindow(winPtr);

	/*
	 * This window is embedded and the container is also in this process,
	 * so we don't need to do anything special about the 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);
	height += wmPtr->menuHeight;
	if (childPtr != NULL) {
	    Tk_GeometryRequest((Tk_Window) childPtr, width, height);
	}
	return;
    }
    serial = NextRequest(winPtr->display);
    height += wmPtr->menuHeight;
    if (wmPtr->flags & WM_MOVE_PENDING) {
	if ((x + wmPtr->xInParent == winPtr->changes.x) &&







|













|







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
     *	  of 4/24/91) where they don't interpret coordinates according to
     *	  ICCCM. Moving a window to its current location may cause it to shift
     *	  position on the screen.
     */

    if ((winPtr->flags & (TK_EMBEDDED|TK_BOTH_HALVES))
	    == (TK_EMBEDDED|TK_BOTH_HALVES)) {
	Tk_Window childPtr = Tk_GetOtherWindow((Tk_Window)winPtr);

	/*
	 * This window is embedded and the container is also in this process,
	 * so we don't need to do anything special about the 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);
	height += wmPtr->menuHeight;
	if (childPtr != NULL) {
	    Tk_GeometryRequest(childPtr, width, height);
	}
	return;
    }
    serial = NextRequest(winPtr->display);
    height += wmPtr->menuHeight;
    if (wmPtr->flags & WM_MOVE_PENDING) {
	if ((x + wmPtr->xInParent == winPtr->changes.x) &&
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
    hintsPtr->width_inc = wmPtr->widthInc;
    hintsPtr->height_inc = wmPtr->heightInc;
    hintsPtr->min_aspect.x = wmPtr->minAspect.x;
    hintsPtr->min_aspect.y = wmPtr->minAspect.y;
    hintsPtr->max_aspect.x = wmPtr->maxAspect.x;
    hintsPtr->max_aspect.y = wmPtr->maxAspect.y;
    hintsPtr->win_gravity = wmPtr->gravity;
    hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize;

    /*
     * If the window isn't supposed to be resizable, then set the minimum and
     * maximum dimensions to be the same.
     */

    if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
	hintsPtr->max_width = hintsPtr->min_width = newWidth;
	hintsPtr->flags |= PMaxSize;
    }
    if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
	hintsPtr->max_height = hintsPtr->min_height =
		newHeight + wmPtr->menuHeight;
	hintsPtr->flags |= PMaxSize;
    }

    XSetWMNormalHints(winPtr->display, wmPtr->wrapperPtr->window, hintsPtr);

    XFree((char *) hintsPtr);
}

/*
 *--------------------------------------------------------------
 *
 * UpdateTitle --
 *







|


















|







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
    hintsPtr->width_inc = wmPtr->widthInc;
    hintsPtr->height_inc = wmPtr->heightInc;
    hintsPtr->min_aspect.x = wmPtr->minAspect.x;
    hintsPtr->min_aspect.y = wmPtr->minAspect.y;
    hintsPtr->max_aspect.x = wmPtr->maxAspect.x;
    hintsPtr->max_aspect.y = wmPtr->maxAspect.y;
    hintsPtr->win_gravity = wmPtr->gravity;
    hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize | PResizeInc;

    /*
     * If the window isn't supposed to be resizable, then set the minimum and
     * maximum dimensions to be the same.
     */

    if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
	hintsPtr->max_width = hintsPtr->min_width = newWidth;
	hintsPtr->flags |= PMaxSize;
    }
    if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
	hintsPtr->max_height = hintsPtr->min_height =
		newHeight + wmPtr->menuHeight;
	hintsPtr->flags |= PMaxSize;
    }

    XSetWMNormalHints(winPtr->display, wmPtr->wrapperPtr->window, hintsPtr);

    XFree(hintsPtr);
}

/*
 *--------------------------------------------------------------
 *
 * UpdateTitle --
 *
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
    Tcl_DString ds;

    /*
     * Set window title:
     */

    string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid;
    Tcl_UtfToExternalDString(NULL, string, -1, &ds);
    XStoreName(winPtr->display, wmPtr->wrapperPtr->window,
	    Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);

    SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_NAME", XA_UTF8_STRING, 8,
	    string, strlen(string));

    /*
     * Set icon name:
     */

    if (wmPtr->iconName != NULL) {
	Tcl_UtfToExternalDString(NULL, wmPtr->iconName, -1, &ds);
	XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
		Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);

	SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_ICON_NAME",
		XA_UTF8_STRING, 8, wmPtr->iconName, strlen(wmPtr->iconName));
    }







|












|







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
    Tcl_DString ds;

    /*
     * Set window title:
     */

    string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid;
    (void)Tcl_UtfToExternalDString(NULL, string, TCL_INDEX_NONE, &ds);
    XStoreName(winPtr->display, wmPtr->wrapperPtr->window,
	    Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);

    SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_NAME", XA_UTF8_STRING, 8,
	    string, strlen(string));

    /*
     * Set icon name:
     */

    if (wmPtr->iconName != NULL) {
	(void)Tcl_UtfToExternalDString(NULL, wmPtr->iconName, TCL_INDEX_NONE, &ds);
	XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
		Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);

	SetWindowProperty(wmPtr->wrapperPtr, "_NET_WM_ICON_NAME",
		XA_UTF8_STRING, 8, wmPtr->iconName, strlen(wmPtr->iconName));
    }
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
    Display *display,		/* Display event is coming from. */
    WmInfo *wmInfoPtr,		/* Window for which event is desired. */
    int type,			/* Type of event that is wanted. */
    XEvent *eventPtr)		/* Place to store event. */
{
    WaitRestrictInfo info;
    Tk_RestrictProc *prevProc;
    ClientData prevArg;
    Tcl_Time timeout;

    /*
     * Set up an event filter to select just the events we want, and a timer
     * handler, then wait for events until we get the event we want or a
     * timeout happens.
     */







|







5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
    Display *display,		/* Display event is coming from. */
    WmInfo *wmInfoPtr,		/* Window for which event is desired. */
    int type,			/* Type of event that is wanted. */
    XEvent *eventPtr)		/* Place to store event. */
{
    WaitRestrictInfo info;
    Tk_RestrictProc *prevProc;
    void *prevArg;
    Tcl_Time timeout;

    /*
     * Set up an event filter to select just the events we want, and a timer
     * handler, then wait for events until we get the event we want or a
     * timeout happens.
     */
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
 *	WaitForEvent.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
WaitRestrictProc(
    ClientData clientData,	/* Pointer to WaitRestrictInfo structure. */
    XEvent *eventPtr)		/* Event that is about to be handled. */
{
    WaitRestrictInfo *infoPtr = (WaitRestrictInfo *)clientData;

    if (eventPtr->type == ReparentNotify) {
	return TK_PROCESS_EVENT;
    }







|







5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
 *	WaitForEvent.
 *
 *----------------------------------------------------------------------
 */

static Tk_RestrictAction
WaitRestrictProc(
    void *clientData,	/* Pointer to WaitRestrictInfo structure. */
    XEvent *eventPtr)		/* Event that is about to be handled. */
{
    WaitRestrictInfo *infoPtr = (WaitRestrictInfo *)clientData;

    if (eventPtr->type == ReparentNotify) {
	return TK_PROCESS_EVENT;
    }
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
SetNetWmType(
    TkWindow *winPtr,
    Tcl_Obj *typePtr)
{
    Atom *atoms = NULL;
    WmInfo *wmPtr;
    Tcl_Obj **objv;
    int objc, n;
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tcl_Interp *interp = Tk_Interp(tkwin);

    if (TCL_OK != Tcl_ListObjGetElements(interp, typePtr, &objc, &objv)) {
	return TCL_ERROR;
    }

    if (!Tk_HasWrapper(tkwin)) {
	return TCL_OK; /* error?? */
    }

    if (objc > 0) {
	atoms = (Atom *)ckalloc(sizeof(Atom) * objc);
    }

    for (n = 0; n < objc; ++n) {
	Tcl_DString ds, dsName;
	TkSizeT len;
	char *name = TkGetStringFromObj(objv[n], &len);

	Tcl_UtfToUpper(name);
	Tcl_UtfToExternalDString(NULL, name, len, &dsName);
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "_NET_WM_WINDOW_TYPE_", 20);
	Tcl_DStringAppend(&ds, Tcl_DStringValue(&dsName),
		Tcl_DStringLength(&dsName));
	Tcl_DStringFree(&dsName);
	atoms[n] = Tk_InternAtom(tkwin, Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);







|

















|
|


|







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
SetNetWmType(
    TkWindow *winPtr,
    Tcl_Obj *typePtr)
{
    Atom *atoms = NULL;
    WmInfo *wmPtr;
    Tcl_Obj **objv;
    Tcl_Size objc, n;
    Tk_Window tkwin = (Tk_Window) winPtr;
    Tcl_Interp *interp = Tk_Interp(tkwin);

    if (TCL_OK != Tcl_ListObjGetElements(interp, typePtr, &objc, &objv)) {
	return TCL_ERROR;
    }

    if (!Tk_HasWrapper(tkwin)) {
	return TCL_OK; /* error?? */
    }

    if (objc > 0) {
	atoms = (Atom *)ckalloc(sizeof(Atom) * objc);
    }

    for (n = 0; n < objc; ++n) {
	Tcl_DString ds, dsName;
	Tcl_Size len;
	char *name = Tcl_GetStringFromObj(objv[n], &len);

	Tcl_UtfToUpper(name);
	(void)Tcl_UtfToExternalDString(NULL, name, len, &dsName);
	Tcl_DStringInit(&ds);
	Tcl_DStringAppend(&ds, "_NET_WM_WINDOW_TYPE_", 20);
	Tcl_DStringAppend(&ds, Tcl_DStringValue(&dsName),
		Tcl_DStringLength(&dsName));
	Tcl_DStringFree(&dsName);
	atoms[n] = Tk_InternAtom(tkwin, Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
    if (GetWindowProperty(wrapperPtr, typeAtom, maxLength, XA_ATOM,
	    &actualType, &actualFormat, &count, &bytesAfter, &propertyValue)){
	atoms = (Atom *) propertyValue;
	for (n = 0; n < count; ++n) {
	    const char *name = Tk_GetAtomName(tkwin, atoms[n]);

	    if (strncmp("_NET_WM_WINDOW_TYPE_", name, 20) == 0) {
		Tcl_ExternalToUtfDString(NULL, name+20, -1, &ds);
		Tcl_UtfToLower(Tcl_DStringValue(&ds));
		Tcl_ListObjAppendElement(interp, typePtr,
			Tcl_NewStringObj(Tcl_DStringValue(&ds),
				Tcl_DStringLength(&ds)));
		Tcl_DStringFree(&ds);
	    }
	}







|







5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
    if (GetWindowProperty(wrapperPtr, typeAtom, maxLength, XA_ATOM,
	    &actualType, &actualFormat, &count, &bytesAfter, &propertyValue)){
	atoms = (Atom *) propertyValue;
	for (n = 0; n < count; ++n) {
	    const char *name = Tk_GetAtomName(tkwin, atoms[n]);

	    if (strncmp("_NET_WM_WINDOW_TYPE_", name, 20) == 0) {
		(void)Tcl_ExternalToUtfDString(NULL, name+20, TCL_INDEX_NONE, &ds);
		Tcl_UtfToLower(Tcl_DStringValue(&ds));
		Tcl_ListObjAppendElement(interp, typePtr,
			Tcl_NewStringObj(Tcl_DStringValue(&ds),
				Tcl_DStringLength(&ds)));
		Tcl_DStringFree(&ds);
	    }
	}
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
	     */

	    y -= winPtr->wmInfoPtr->menuHeight;
	    winPtr = winPtr->wmInfoPtr->winPtr;
	    continue;
	}
	if (winPtr->flags & TK_TOP_LEVEL) {
	    TkWindow *otherPtr;

	    if (!(winPtr->flags & TK_EMBEDDED)) {
		break;
	    }
	    otherPtr = TkpGetOtherWindow(winPtr);
	    if (otherPtr == NULL) {
		/*
		 * The container window is not in the same application. Query
		 * the X server.
		 */

		Window root, dummyChild;







|




|







5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
	     */

	    y -= winPtr->wmInfoPtr->menuHeight;
	    winPtr = winPtr->wmInfoPtr->winPtr;
	    continue;
	}
	if (winPtr->flags & TK_TOP_LEVEL) {
	    Tk_Window otherPtr;

	    if (!(winPtr->flags & TK_EMBEDDED)) {
		break;
	    }
	    otherPtr = Tk_GetOtherWindow((Tk_Window)winPtr);
	    if (otherPtr == NULL) {
		/*
		 * The container window is not in the same application. Query
		 * the X server.
		 */

		Window root, dummyChild;
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
		break;
	    } else {
		/*
		 * The container window is in the same application. Let's
		 * query its coordinates.
		 */

		winPtr = otherPtr;
		continue;
	    }
	}
	winPtr = winPtr->parentPtr;
	if (winPtr == NULL) {
	    break;
	}







|







5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
		break;
	    } else {
		/*
		 * The container window is in the same application. Let's
		 * query its coordinates.
		 */

		winPtr = (TkWindow *)otherPtr;
		continue;
	    }
	}
	winPtr = winPtr->parentPtr;
	if (winPtr == NULL) {
	    break;
	}
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
                    return NULL;
                }
	    }
	    if (wmPtr->wrapperPtr != NULL) {
		if (child == wmPtr->wrapperPtr->window) {
		    goto gotToplevel;
		} else if (wmPtr->winPtr->flags & TK_EMBEDDED &&
                           TkpGetOtherWindow(wmPtr->winPtr) == NULL) {

                    /*
                     * This toplevel is embedded in a window belonging to
                     * a different application.
                     */

                    int rx, ry;







|







5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
                    return NULL;
                }
	    }
	    if (wmPtr->wrapperPtr != NULL) {
		if (child == wmPtr->wrapperPtr->window) {
		    goto gotToplevel;
		} else if (wmPtr->winPtr->flags & TK_EMBEDDED &&
                           Tk_GetOtherWindow((Tk_Window)wmPtr->winPtr) == NULL) {

                    /*
                     * This toplevel is embedded in a window belonging to
                     * a different application.
                     */

                    int rx, ry;
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
		&& (nextPtr->flags & TK_BOTH_HALVES)) {
	    /*
	     * The window containing the point is a container, and the
	     * embedded application is in this same process. Switch over to
	     * the toplevel for the embedded application and start processing
	     * that toplevel from scratch.
	     */
	    winPtr = TkpGetOtherWindow(nextPtr);
	    if (winPtr == NULL) {
		return (Tk_Window) nextPtr;
	    }
	    wmPtr = winPtr->wmInfoPtr;
	    childX = x;
	    childY = y;
	    goto gotToplevel;







|







6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
		&& (nextPtr->flags & TK_BOTH_HALVES)) {
	    /*
	     * The window containing the point is a container, and the
	     * embedded application is in this same process. Switch over to
	     * the toplevel for the embedded application and start processing
	     * that toplevel from scratch.
	     */
	    winPtr = (TkWindow *)Tk_GetOtherWindow((Tk_Window)nextPtr);
	    if (winPtr == NULL) {
		return (Tk_Window) nextPtr;
	    }
	    wmPtr = winPtr->wmInfoPtr;
	    childX = x;
	    childY = y;
	    goto gotToplevel;
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
    protocolName = Tk_GetAtomName((Tk_Window) winPtr, protocol);
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			protocolName));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);







|







6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
    protocolName = Tk_GetAtomName((Tk_Window) winPtr, protocol);
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
	    protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			protocolName));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
	/*
	 * ASSERT: window_ptr - windows == table.numEntries
	 * (#matched toplevel windows == #children) [Bug 1789819]
	 */

	*window_ptr = NULL;
	if (numChildren) {
	    XFree((char *) children);
	}
    }

  done:
    Tcl_DeleteHashTable(&table);
    return windows;
}







|







6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
	/*
	 * ASSERT: window_ptr - windows == table.numEntries
	 * (#matched toplevel windows == #children) [Bug 1789819]
	 */

	*window_ptr = NULL;
	if (numChildren) {
	    XFree(children);
	}
    }

  done:
    Tcl_DeleteHashTable(&table);
    return windows;
}
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
    }
    newPtr[count-1] = winPtr->window;
    newPtr[count] = topPtr->window;
    XSetWMColormapWindows(topPtr->display, wrapperPtr->window, newPtr,
	    count+1);
    ckfree(newPtr);
    if (oldPtr != NULL) {
	XFree((char *) oldPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmRemoveFromColormapWindows --







|







6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
    }
    newPtr[count-1] = winPtr->window;
    newPtr[count] = topPtr->window;
    XSetWMColormapWindows(topPtr->display, wrapperPtr->window, newPtr,
	    count+1);
    ckfree(newPtr);
    if (oldPtr != NULL) {
	XFree(oldPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmRemoveFromColormapWindows --
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
		oldPtr[j] = oldPtr[j+1];
	    }
	    XSetWMColormapWindows(topPtr->display, wrapperPtr->window,
		    oldPtr, count-1);
	    break;
	}
    }
    XFree((char *) oldPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetPointerCoords --
 *







|







6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
		oldPtr[j] = oldPtr[j+1];
	    }
	    XSetWMColormapWindows(topPtr->display, wrapperPtr->window,
		    oldPtr, count-1);
	    break;
	}
    }
    XFree(oldPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetPointerCoords --
 *
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
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    wrapperPtr = wmPtr->wrapperPtr;
    if (typeFlag == TK_MAKE_MENU_TEAROFF) {
	atts.override_redirect = False;
	atts.save_under = False;
	typeObj = Tcl_NewStringObj("menu", -1);
	TkSetTransientFor(tkwin, NULL);
    } else {
	atts.override_redirect = True;
	atts.save_under = True;
	if (typeFlag == TK_MAKE_MENU_DROPDOWN) {
	    typeObj = Tcl_NewStringObj("dropdown_menu", -1);
	} else {
	    typeObj = Tcl_NewStringObj("popup_menu", -1);
	}
    }

    SetNetWmType((TkWindow *)tkwin, typeObj);


    /*
     * The override-redirect and save-under bits must be set on the wrapper
     * window in order to have the desired effect. However, also set the
     * override-redirect bit on the window itself, so that the "wm
     * overrideredirect" command will see it.
     */







|





|

|


>

>







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
    if (wmPtr->wrapperPtr == NULL) {
	CreateWrapper(wmPtr);
    }
    wrapperPtr = wmPtr->wrapperPtr;
    if (typeFlag == TK_MAKE_MENU_TEAROFF) {
	atts.override_redirect = False;
	atts.save_under = False;
	typeObj = Tcl_NewStringObj("menu", TCL_INDEX_NONE);
	TkSetTransientFor(tkwin, NULL);
    } else {
	atts.override_redirect = True;
	atts.save_under = True;
	if (typeFlag == TK_MAKE_MENU_DROPDOWN) {
	    typeObj = Tcl_NewStringObj("dropdown_menu", TCL_INDEX_NONE);
	} else {
	    typeObj = Tcl_NewStringObj("popup_menu", TCL_INDEX_NONE);
	}
    }
    Tcl_IncrRefCount(typeObj);
    SetNetWmType((TkWindow *)tkwin, typeObj);
    Tcl_DecrRefCount(typeObj);

    /*
     * The override-redirect and save-under bits must be set on the wrapper
     * window in order to have the desired effect. However, also set the
     * override-redirect bit on the window itself, so that the "wm
     * overrideredirect" command will see it.
     */
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
    winPtr = wmPtr->winPtr;
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }

    /*
     * The code below is copied from CreateTopLevelWindow, Tk_MakeWindowExist,
     * and TkpMakeWindow. The idea is to create an "official" Tk window (so
     * that we can get events on it), but to hide the window outside the
     * official Tk hierarchy so that it isn't visible to the application. See
     * the comments for the other functions if you have questions about this
     * code.
     */

    wmPtr->wrapperPtr = wrapperPtr = TkAllocWindow(winPtr->dispPtr,







|







7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
    winPtr = wmPtr->winPtr;
    if (winPtr->window == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }

    /*
     * The code below is copied from CreateTopLevelWindow, Tk_MakeWindowExist,
     * and Tk_MakeWindow. The idea is to create an "official" Tk window (so
     * that we can get events on it), but to hide the window outside the
     * official Tk hierarchy so that it isn't visible to the application. See
     * the comments for the other functions if you have questions about this
     * code.
     */

    wmPtr->wrapperPtr = wrapperPtr = TkAllocWindow(winPtr->dispPtr,
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
 *	the window is no longer considered to be a menubar.
 *
 *----------------------------------------------------------------------
 */

static void
MenubarDestroyProc(
    ClientData clientData,	/* TkWindow pointer for menubar. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WmInfo *wmPtr;

    if (eventPtr->type != DestroyNotify) {
	return;
    }







|







7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
 *	the window is no longer considered to be a menubar.
 *
 *----------------------------------------------------------------------
 */

static void
MenubarDestroyProc(
    void *clientData,	/* TkWindow pointer for menubar. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WmInfo *wmPtr;

    if (eventPtr->type != DestroyNotify) {
	return;
    }
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
MenubarReqProc(
    ClientData clientData,	/* Pointer to the window manager information
				 * for tkwin's toplevel. */
    Tk_Window tkwin)		/* Handle for menubar window. */
{
    WmInfo *wmPtr = (WmInfo *)clientData;

    wmPtr->menuHeight = Tk_ReqHeight(tkwin);
    if (wmPtr->menuHeight <= 0) {







|







7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
MenubarReqProc(
    void *clientData,	/* Pointer to the window manager information
				 * for tkwin's toplevel. */
    Tk_Window tkwin)		/* Handle for menubar window. */
{
    WmInfo *wmPtr = (WmInfo *)clientData;

    wmPtr->menuHeight = Tk_ReqHeight(tkwin);
    if (wmPtr->menuHeight <= 0) {
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

static void
UpdateCommand(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tcl_DString cmds, ds;

    int i, *offsets;
    char **cmdArgv;

    /*
     * Translate the argv strings into the external encoding. To avoid
     * allocating lots of memory, the strings are appended to a buffer with
     * nulls between each string.
     *
     * This code is tricky because we need to pass and array of pointers to
     * XSetCommand. However, we can't compute the pointers as we go because
     * the DString buffer space could get reallocated. So, store offsets for
     * each element as we go, then compute pointers from the offsets once the
     * entire DString is done.
     */

    cmdArgv = (char **)ckalloc(sizeof(char *) * wmPtr->cmdArgc);
    offsets = (int *)ckalloc(sizeof(int) * wmPtr->cmdArgc);
    Tcl_DStringInit(&cmds);
    for (i = 0; i < wmPtr->cmdArgc; i++) {
	Tcl_UtfToExternalDString(NULL, wmPtr->cmdArgv[i], -1, &ds);
	offsets[i] = Tcl_DStringLength(&cmds);
	Tcl_DStringAppend(&cmds, Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds)+1);
	Tcl_DStringFree(&ds);
    }
    cmdArgv[0] = Tcl_DStringValue(&cmds);
    for (i = 1; i < wmPtr->cmdArgc; i++) {







>
|


















|







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

static void
UpdateCommand(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tcl_DString cmds, ds;
    Tcl_Size i;
    int *offsets;
    char **cmdArgv;

    /*
     * Translate the argv strings into the external encoding. To avoid
     * allocating lots of memory, the strings are appended to a buffer with
     * nulls between each string.
     *
     * This code is tricky because we need to pass and array of pointers to
     * XSetCommand. However, we can't compute the pointers as we go because
     * the DString buffer space could get reallocated. So, store offsets for
     * each element as we go, then compute pointers from the offsets once the
     * entire DString is done.
     */

    cmdArgv = (char **)ckalloc(sizeof(char *) * wmPtr->cmdArgc);
    offsets = (int *)ckalloc(sizeof(int) * wmPtr->cmdArgc);
    Tcl_DStringInit(&cmds);
    for (i = 0; i < wmPtr->cmdArgc; i++) {
	(void)Tcl_UtfToExternalDString(NULL, wmPtr->cmdArgv[i], TCL_INDEX_NONE, &ds);
	offsets[i] = Tcl_DStringLength(&cmds);
	Tcl_DStringAppend(&cmds, Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds)+1);
	Tcl_DStringFree(&ds);
    }
    cmdArgv[0] = Tcl_DStringValue(&cmds);
    for (i = 1; i < wmPtr->cmdArgc; i++) {

Changes to unix/tkUnixXId.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkUnixInt.h"




|
|







1
2
3
4
5
6
7
8
9
10
11
12
/*
 * tkUnixXId.c --
 *
 * 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.

122
123
124
125
126
127
128







129
130
131
132


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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@








TK_STUB_LIB_FILE	= @TK_STUB_LIB_FILE@
TK_LIB_FILE		= @TK_LIB_FILE@
TK_DLL_FILE		= @TK_DLL_FILE@


TEST_DLL_FILE		= tktest$(VER)${DLLSUFFIX}
TEST_LIB_FILE		= @LIBPREFIX@tktest$(VER)${LIBSUFFIX}

SHARED_LIBRARIES 	= $(TK_DLL_FILE) $(TK_STUB_LIB_FILE)
STATIC_LIBRARIES	= $(TK_LIB_FILE)

WISH			= wish$(VER)${EXESUFFIX}
TKTEST			= tktest.exe
CAT32			= cat32.exe
MAN2TCL			= man2tcl.exe

@SET_MAKE@

# Setting the VPATH variable to a list of paths will cause the
# makefile to look into these paths when resolving .c to .obj
# dependencies.








>
>
>
>
>
>
>




>
>

|





|
|
|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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@
TCLVER			= @TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@
VER			= @TK_MAJOR_VERSION@@TK_MINOR_VERSION@
DOTVER			= @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@

TK_ZIP_FILE		= @TK_ZIP_FILE@
TK_VFS_PATH		= libtk.vfs/tk_library
TK_VFS_ROOT		= libtk.vfs

TK_STUB_LIB_FILE	= @TK_STUB_LIB_FILE@
TK_LIB_FILE		= @TK_LIB_FILE@
TK_DLL_FILE		= @TK_DLL_FILE@
TK_DLL_FILE_TCL8	= @TK_DLL_FILE_TCL8@
TK_DLL_FILE_TCL9	= @TK_DLL_FILE_TCL9@
TEST_DLL_FILE		= tktest$(VER)${DLLSUFFIX}
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${EXESUFFIX}
CAT32			= cat32${EXESUFFIX}
MAN2TCL			= man2tcl${EXESUFFIX}

@SET_MAKE@

# Setting the VPATH variable to a list of paths will cause the
# makefile to look into these paths when resolving .c to .obj
# dependencies.

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214







































215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@

# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS		= $(CFLAGS_DEBUG)
#CFLAGS		= $(CFLAGS_OPTIMIZE)
#CFLAGS		= $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS		= @CFLAGS@ @CFLAGS_DEFAULT@ -D_ATL_XP_TARGETING

# Special compiler flags to use when building man2tcl on Windows.
MAN2TCLFLAGS	= @MAN2TCLFLAGS@

AR		= @AR@
RANLIB		= @RANLIB@
CC		= @CC@
RC		= @RC@
RES		= @RES@
TK_RES		= @TK_RES@
AC_FLAGS	= @EXTRA_CFLAGS@ @DEFS@ @TCL_DEFS@
CPPFLAGS	= @CPPFLAGS@
LDFLAGS		= @LDFLAGS@ @LDFLAGS_DEFAULT@
LDFLAGS_CONSOLE	= @LDFLAGS_CONSOLE@
LDFLAGS_WINDOW	= @LDFLAGS_WINDOW@
OBJEXT		= @OBJEXT@
STLIB_LD	= @STLIB_LD@
SHLIB_LD	= @SHLIB_LD@
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_SUFFIX	= @SHLIB_SUFFIX@
VER		= @TK_MAJOR_VERSION@@TK_MINOR_VERSION@
DOTVER		= @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@
LIBS		= $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@
RMDIR		= rm -rf
MKDIR		= mkdir -p
SHELL		= @SHELL@
RM		= rm -f
COPY		= cp

BUILD_TCLSH	= @BUILD_TCLSH@

# Tk does not used deprecated Tcl constructs so it should
# compile fine with -DTCL_NO_DEPRECATED. To remove its own
# set of deprecated code uncomment the second line.
NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# TCL_EXE is the name of a tclsh executable that is available *BEFORE*
# running make for the first time. Certain build targets (make genstubs)
# need it to be available on the PATH. This executable should *NOT* be
# required just to do a normal build although it can be required to run
# make dist.
TCL_EXE			= @TCLSH_PROG@
WINE    		= @WINE@








































CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
-I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \
-I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \
-I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" \
${AC_FLAGS} $(NO_DEPRECATED_FLAGS) -DUSE_TCL_STUBS

CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@

# Tk used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
# "install" around;  better to use the install-sh script that comes
# with the distribution, which is slower but guaranteed to work.

INSTALL		= cp
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA	= ${INSTALL}

WISH_OBJS = \
	winMain.$(OBJEXT)

TKTEST_OBJS = \
	tkSquare.$(OBJEXT) \
	tkTest.$(OBJEXT) \
	tkOldTest.$(OBJEXT) \
	tkWinTest.$(OBJEXT)

XLIB_OBJS = \
	xcolors.$(OBJEXT) \
	xdraw.$(OBJEXT) \
	xgc.$(OBJEXT) \
	ximage.$(OBJEXT) \







|










|










<
<






|
<




|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|



















<







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198


199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@

# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS		= $(CFLAGS_DEBUG)
#CFLAGS		= $(CFLAGS_OPTIMIZE)
#CFLAGS		= $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS		= @CFLAGS@ @CFLAGS_DEFAULT@ -D_ATL_XP_TARGETING=1 -D__USE_MINGW_ANSI_STDIO=0

# Special compiler flags to use when building man2tcl on Windows.
MAN2TCLFLAGS	= @MAN2TCLFLAGS@

AR		= @AR@
RANLIB		= @RANLIB@
CC		= @CC@
RC		= @RC@
RES		= @RES@
TK_RES		= @TK_RES@
AC_FLAGS	= @EXTRA_CFLAGS@ @DEFS@
CPPFLAGS	= @CPPFLAGS@
LDFLAGS		= @LDFLAGS@ @LDFLAGS_DEFAULT@
LDFLAGS_CONSOLE	= @LDFLAGS_CONSOLE@
LDFLAGS_WINDOW	= @LDFLAGS_WINDOW@
OBJEXT		= @OBJEXT@
STLIB_LD	= @STLIB_LD@
SHLIB_LD	= @SHLIB_LD@
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_SUFFIX	= @SHLIB_SUFFIX@


LIBS		= $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@
RMDIR		= rm -rf
MKDIR		= mkdir -p
SHELL		= @SHELL@
RM		= rm -f
COPY		= cp
LN		= ln


# Tk does not used deprecated Tcl constructs so it should
# compile fine with -DTCL_NO_DEPRECATED. To remove its own
# set of deprecated code uncomment the second line.
NO_DEPRECATED_FLAGS	=
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# TCL_EXE is the name of a tclsh executable that is available *BEFORE*
# running make for the first time. Certain build targets (make genstubs)
# need it to be available on the PATH. This executable should *NOT* be
# required just to do a normal build although it can be required to run
# make dist.
TCL_EXE			= @TCLSH_PROG@
WINE    		= @WINE@

###
# Tip 430 - ZipFS Modifications
###

TK_ZIP_FILE		= @TK_ZIP_FILE@
TK_VFS_PATH		= libtk.vfs/tk_library
TK_VFS_ROOT		= libtk.vfs

HOST_CC		        = @CC_FOR_BUILD@
HOST_EXEEXT             = @EXEEXT_FOR_BUILD@
HOST_OBJEXT             = @OBJEXT_FOR_BUILD@
ZIPFS_BUILD	        = @ZIPFS_BUILD@
NATIVE_ZIP		= @ZIP_PROG@
ZIP_PROG_OPTIONS		= @ZIP_PROG_OPTIONS@
ZIP_PROG_VFSSEARCH  = @ZIP_PROG_VFSSEARCH@
SHARED_BUILD		= @SHARED_BUILD@
INSTALL_MSGS            = @INSTALL_MSGS@
INSTALL_LIBRARIES       = @INSTALL_LIBRARIES@

# Minizip
MINIZIP_OBJS = \
        adler32.$(HOST_OBJEXT) \
        compress.$(HOST_OBJEXT) \
        crc32.$(HOST_OBJEXT) \
        deflate.$(HOST_OBJEXT) \
        infback.$(HOST_OBJEXT) \
        inffast.$(HOST_OBJEXT) \
        inflate.$(HOST_OBJEXT) \
        inftrees.$(HOST_OBJEXT) \
        ioapi.$(HOST_OBJEXT) \
        iowin32.$(HOST_OBJEXT)  \
        trees.$(HOST_OBJEXT) \
        uncompr.$(HOST_OBJEXT) \
        zip.$(HOST_OBJEXT) \
        zutil.$(HOST_OBJEXT) \
        minizip.$(HOST_OBJEXT)

ZIP_INSTALL_OBJS =  @ZIP_INSTALL_OBJS@

CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
-I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \
-I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \
-I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" \
${AC_FLAGS} $(NO_DEPRECATED_FLAGS) -DTCL_UTF_MAX=4 -DUSE_TCL_STUBS

CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@

# Tk used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
# "install" around;  better to use the install-sh script that comes
# with the distribution, which is slower but guaranteed to work.

INSTALL		= cp
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA	= ${INSTALL}

WISH_OBJS = \
	winMain.$(OBJEXT)

TKTEST_OBJS = \
	tkSquare.$(OBJEXT) \
	tkTest.$(OBJEXT) \

	tkWinTest.$(OBJEXT)

XLIB_OBJS = \
	xcolors.$(OBJEXT) \
	xdraw.$(OBJEXT) \
	xgc.$(OBJEXT) \
	ximage.$(OBJEXT) \
258
259
260
261
262
263
264


265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
	tkWinColor.$(OBJEXT) \
	tkWinConfig.$(OBJEXT) \
	tkWinCursor.$(OBJEXT) \
	tkWinDialog.$(OBJEXT) \
	tkWinDraw.$(OBJEXT) \
	tkWinEmbed.$(OBJEXT) \
	tkWinFont.$(OBJEXT) \


	tkWinImage.$(OBJEXT) \
	tkWinInit.$(OBJEXT) \
	tkWinKey.$(OBJEXT) \
	tkWinMenu.$(OBJEXT) \
	tkWinPixmap.$(OBJEXT) \
	tkWinPointer.$(OBJEXT) \
	tkWinRegion.$(OBJEXT) \
	tkWinScrlbr.$(OBJEXT) \
	tkWinSend.$(OBJEXT) \
	tkWinSendCom.$(OBJEXT) \

	tkWinWindow.$(OBJEXT) \
	tkWinWm.$(OBJEXT) \
	tkWinX.$(OBJEXT) \
	stubs.$(OBJEXT) \
	tk3d.$(OBJEXT) \
	tkArgv.$(OBJEXT) \
	tkAtom.$(OBJEXT) \
	tkBind.$(OBJEXT) \

	tkBitmap.$(OBJEXT) \
	tkBusy.$(OBJEXT) \
	tkButton.$(OBJEXT) \
	tkCanvArc.$(OBJEXT) \
	tkCanvBmap.$(OBJEXT) \
	tkCanvImg.$(OBJEXT) \
	tkCanvLine.$(OBJEXT) \







>
>










>








>







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
	tkWinColor.$(OBJEXT) \
	tkWinConfig.$(OBJEXT) \
	tkWinCursor.$(OBJEXT) \
	tkWinDialog.$(OBJEXT) \
	tkWinDraw.$(OBJEXT) \
	tkWinEmbed.$(OBJEXT) \
	tkWinFont.$(OBJEXT) \
	tkWinGDI.$(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) \
	tkBind.$(OBJEXT) \
	tkBitField.$(OBJEXT) \
	tkBitmap.$(OBJEXT) \
	tkBusy.$(OBJEXT) \
	tkButton.$(OBJEXT) \
	tkCanvArc.$(OBJEXT) \
	tkCanvBmap.$(OBJEXT) \
	tkCanvImg.$(OBJEXT) \
	tkCanvLine.$(OBJEXT) \
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346
347
348

349
350


351
352
353
354
355
356
357
358
359
360
	tkFont.$(OBJEXT) \
	tkFrame.$(OBJEXT) \
	tkGC.$(OBJEXT) \
	tkGeometry.$(OBJEXT) \
	tkGet.$(OBJEXT) \
	tkGrab.$(OBJEXT) \
	tkGrid.$(OBJEXT) \

	tkImage.$(OBJEXT) \
	tkImgBmap.$(OBJEXT) \
	tkImgListFormat.$(OBJEXT) \
	tkImgGIF.$(OBJEXT) \
	tkImgPNG.$(OBJEXT) \
	tkImgPPM.$(OBJEXT) \
	tkImgSVGnano.$(OBJEXT) \
	tkImgPhoto.$(OBJEXT) \
	tkImgPhInstance.$(OBJEXT) \
	tkImgUtil.$(OBJEXT) \

	tkListbox.$(OBJEXT) \
	tkMacWinMenu.$(OBJEXT) \
	tkMain.$(OBJEXT) \
	tkMain2.$(OBJEXT) \
	tkMenu.$(OBJEXT) \
	tkMenubutton.$(OBJEXT) \
	tkMenuDraw.$(OBJEXT) \
	tkMessage.$(OBJEXT) \
	tkPanedWindow.$(OBJEXT) \
	tkObj.$(OBJEXT) \
	tkOldConfig.$(OBJEXT) \
	tkOption.$(OBJEXT) \
	tkPack.$(OBJEXT) \
	tkPkgConfig.$(OBJEXT) \
	tkPlace.$(OBJEXT) \
	tkPointer.$(OBJEXT) \

	tkRectOval.$(OBJEXT) \
	tkScale.$(OBJEXT) \
	tkScrollbar.$(OBJEXT) \
	tkSelect.$(OBJEXT) \
	tkStyle.$(OBJEXT) \
	tkText.$(OBJEXT) \
	tkTextBTree.$(OBJEXT) \
	tkTextDisp.$(OBJEXT) \
	tkTextImage.$(OBJEXT) \
	tkTextIndex.$(OBJEXT) \

	tkTextMark.$(OBJEXT) \
	tkTextTag.$(OBJEXT) \


	tkTextWind.$(OBJEXT) \
	tkTrig.$(OBJEXT) \
	tkUndo.$(OBJEXT) \
	tkUtil.$(OBJEXT) \
	tkVisual.$(OBJEXT) \
	tkStubInit.$(OBJEXT) \
	tkWindow.$(OBJEXT) \
	$(TTK_OBJS)

TTK_OBJS = \







>










>
















>










>


>
>


<







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
	tkFont.$(OBJEXT) \
	tkFrame.$(OBJEXT) \
	tkGC.$(OBJEXT) \
	tkGeometry.$(OBJEXT) \
	tkGet.$(OBJEXT) \
	tkGrab.$(OBJEXT) \
	tkGrid.$(OBJEXT) \
	tkIcu.$(OBJEXT) \
	tkImage.$(OBJEXT) \
	tkImgBmap.$(OBJEXT) \
	tkImgListFormat.$(OBJEXT) \
	tkImgGIF.$(OBJEXT) \
	tkImgPNG.$(OBJEXT) \
	tkImgPPM.$(OBJEXT) \
	tkImgSVGnano.$(OBJEXT) \
	tkImgPhoto.$(OBJEXT) \
	tkImgPhInstance.$(OBJEXT) \
	tkImgUtil.$(OBJEXT) \
	tkIntSet.$(OBJEXT) \
	tkListbox.$(OBJEXT) \
	tkMacWinMenu.$(OBJEXT) \
	tkMain.$(OBJEXT) \
	tkMain2.$(OBJEXT) \
	tkMenu.$(OBJEXT) \
	tkMenubutton.$(OBJEXT) \
	tkMenuDraw.$(OBJEXT) \
	tkMessage.$(OBJEXT) \
	tkPanedWindow.$(OBJEXT) \
	tkObj.$(OBJEXT) \
	tkOldConfig.$(OBJEXT) \
	tkOption.$(OBJEXT) \
	tkPack.$(OBJEXT) \
	tkPkgConfig.$(OBJEXT) \
	tkPlace.$(OBJEXT) \
	tkPointer.$(OBJEXT) \
	tkRangeList.$(OBJEXT) \
	tkRectOval.$(OBJEXT) \
	tkScale.$(OBJEXT) \
	tkScrollbar.$(OBJEXT) \
	tkSelect.$(OBJEXT) \
	tkStyle.$(OBJEXT) \
	tkText.$(OBJEXT) \
	tkTextBTree.$(OBJEXT) \
	tkTextDisp.$(OBJEXT) \
	tkTextImage.$(OBJEXT) \
	tkTextIndex.$(OBJEXT) \
	tkTextLineBreak.$(OBJEXT) \
	tkTextMark.$(OBJEXT) \
	tkTextTag.$(OBJEXT) \
	tkTextTagSet.$(OBJEXT) \
	tkTextUndo.$(OBJEXT) \
	tkTextWind.$(OBJEXT) \
	tkTrig.$(OBJEXT) \

	tkUtil.$(OBJEXT) \
	tkVisual.$(OBJEXT) \
	tkStubInit.$(OBJEXT) \
	tkWindow.$(OBJEXT) \
	$(TTK_OBJS)

TTK_OBJS = \
481
482
483
484
485
486
487
488
489
490



491

492

493



494

495
496
497
498
499
500
501
		echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \
		$(COPY) $$i "$(BIN_INSTALL_DIR)"; \
	    fi; \
	    done
	@echo "Creating package index $(PKG_INDEX)";
	@$(RM) $(PKG_INDEX);
	@(\
	echo "if {[catch {package present Tcl 8.6-}]} return";\
	echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\



	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]] Tk]";\

	echo "} else {";\

	echo "    package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE)]] Tk]";\



	echo "}";\

	) > $(PKG_INDEX);
	@for i in tkConfig.sh $(TK_LIB_FILE) $(TK_STUB_LIB_FILE); \
	    do \
	    if [ -f $$i ]; then \
		echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \
		$(COPY) $$i "$(LIB_INSTALL_DIR)"; \
	    fi; \







|


>
>
>
|
>

>
|
>
>
>

>







534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
		echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \
		$(COPY) $$i "$(BIN_INSTALL_DIR)"; \
	    fi; \
	    done
	@echo "Creating package index $(PKG_INDEX)";
	@$(RM) $(PKG_INDEX);
	@(\
	echo "if {![package vsatisfies [package provide Tcl] 8.7-]} return";\
	echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\
	echo "	|| ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\
	echo "    if {[package vsatisfies [package provide Tcl] 9.0]} {";\
	echo "	package ifneeded tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtcl9tk$(VERSION).dll]]]";\
	echo "    } else {";\
	echo "	package ifneeded tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]]]";\
	echo "    }";\
	echo "} else {";\
	echo "    if {[package vsatisfies [package provide Tcl] 9.0]} {";\
	echo "	package ifneeded tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE_TCL9)]]]";\
	echo "    } else {";\
	echo "	package ifneeded tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE_TCL8)]]]";\
	echo "    }";\
	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; \
605
606
607
608
609
610
611
612
613
614
615
616





617
618
619
620
621
622
623
624
625
626
627









628
629
630
631
632
633
634
635
636
























637
638
639
640
641
642
643
644
645
646
647
648
649





650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674



675
676
677
678
679
680
681
682
683
684









685
686
687
688
689
690
691
692
693
694
695
696
	@for i in "$(GENERIC_DIR)/tkInt.h" "$(GENERIC_DIR)/tkIntDecls.h" \
		"$(GENERIC_DIR)/tkIntPlatDecls.h" "$(GENERIC_DIR)/tkPort.h" \
		"$(WIN_DIR)/tkWinPort.h" "$(WIN_DIR)/tkWinInt.h" "$(WIN_DIR)/tkWin.h"; \
	    do \
	    $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \
	    done;

$(WISH): $(WISH_OBJS) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) $(WISH_OBJS) $(TK_LIB_FILE) \
	$(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@






tktest: $(TKTEST)

$(TKTEST): testMain.$(OBJEXT) $(TEST_DLL_FILE) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) testMain.$(OBJEXT) $(TEST_LIB_FILE) $(TK_LIB_FILE) \
	$(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@

${TEST_DLL_FILE}: ${TKTEST_OBJS} ${TK_STUB_LIB_FILE}
	@MAKE_DLL@ ${TKTEST_OBJS} $(TK_STUB_LIB_FILE) $(SHLIB_LD_LIBS)










# Msys make requires this next rule for some reason.
$(TCL_SRC_DIR)/win/cat.c:

cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c
	$(CC) -c $(CC_SWITCHES) -DUNICODE -D_UNICODE "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME)

$(CAT32): cat32.${OBJEXT}
	$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)

























# The following targets are configured by autoconf to generate either
# a shared library or static library

${TK_STUB_LIB_FILE}: ${STUB_OBJS}
	@$(RM) ${TK_STUB_LIB_FILE}
	@MAKE_STUB_LIB@ ${STUB_OBJS}
	@POST_MAKE_LIB@

${TK_DLL_FILE}: ${TK_OBJS} $(TK_RES)
	@$(RM) ${TK_DLL_FILE}
	@MAKE_DLL@ ${TK_OBJS} $(TK_RES) $(SHLIB_LD_LIBS)
	@VC_MANIFEST_EMBED_DLL@






${TK_LIB_FILE}: ${TK_OBJS}
	@$(RM) ${TK_LIB_FILE}
	@MAKE_LIB@ ${TK_OBJS}
	@POST_MAKE_LIB@

# Special case object file targets

winMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

testMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DTK_TEST -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

tkTest.$(OBJEXT): tkTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkOldTest.$(OBJEXT): tkOldTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkWinTest.$(OBJEXT): tkWinTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkSquare.$(OBJEXT): tkSquare.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)




tkMain2.$(OBJEXT): tkMain.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

tkUnixMenubu.$(OBJEXT): ${UNIX_DIR}/tkUnixMenubu.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

tkUnixScale.$(OBJEXT): ${UNIX_DIR}/tkUnixScale.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)










# Extra dependency info
tkConsole.$(OBJEXT): configure Makefile
tkMain.$(OBJEXT): configure Makefile
tkMain2.$(OBJEXT): configure Makefile
tkWindow.$(OBJEXT): configure Makefile

# Add the object extension to the implicit rules.  By default .obj is not
# automatically added.

.SUFFIXES: .${OBJEXT}
.SUFFIXES: .$(RES)
.SUFFIXES: .rc







|




>
>
>
>
>











>
>
>
>
>
>
>
>
>









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|



>
>
>
>
>















|

|
|

|
|

|
|
>
>
>










>
>
>
>
>
>
>
>
>




<







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
	@for i in "$(GENERIC_DIR)/tkInt.h" "$(GENERIC_DIR)/tkIntDecls.h" \
		"$(GENERIC_DIR)/tkIntPlatDecls.h" "$(GENERIC_DIR)/tkPort.h" \
		"$(WIN_DIR)/tkWinPort.h" "$(WIN_DIR)/tkWinInt.h" "$(WIN_DIR)/tkWin.h"; \
	    do \
	    $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \
	    done;

$(WISH): $(WISH_OBJS) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) ${TK_ZIP_FILE}
	$(CC) $(CFLAGS) $(WISH_OBJS) $(TK_LIB_FILE) \
	$(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@
	@if test "${ZIPFS_BUILD}" = "2" ; then \
		cat ${TK_ZIP_FILE} >> ${WISH}; \
		${NATIVE_ZIP} -A ${WISH} \
		  || echo 'ignore zip-error by adjust sfx process (not executable?)'; \
	fi

tktest: $(TKTEST)

$(TKTEST): testMain.$(OBJEXT) $(TEST_DLL_FILE) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES)
	$(CC) $(CFLAGS) testMain.$(OBJEXT) $(TEST_LIB_FILE) $(TK_LIB_FILE) \
	$(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \
	wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW)
	@VC_MANIFEST_EMBED_EXE@

${TEST_DLL_FILE}: ${TKTEST_OBJS} ${TK_STUB_LIB_FILE}
	@MAKE_DLL@ ${TKTEST_OBJS} $(TK_STUB_LIB_FILE) $(SHLIB_LD_LIBS)

$(TOP_DIR)/manifest.uuid:
	printf "git-" >$(TOP_DIR)/manifest.uuid
	(cd $(TOP_DIR); git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid || printf "unknown" >$(TOP_DIR)/manifest.uuid)

tkUuid.h:	$(TOP_DIR)/manifest.uuid
	echo "#define TK_VERSION_UUID \\" >$@
	cat $(TOP_DIR)/manifest.uuid >>$@
	echo "" >>$@

# Msys make requires this next rule for some reason.
$(TCL_SRC_DIR)/win/cat.c:

cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c
	$(CC) -c $(CC_SWITCHES) -DUNICODE -D_UNICODE "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME)

$(CAT32): cat32.${OBJEXT}
	$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)

tkzipfile: ${TK_ZIP_FILE}

${TK_ZIP_FILE}:  ${ZIP_INSTALL_OBJS}
	@$(RMDIR) ${TK_VFS_ROOT}
	@mkdir -p ${TK_VFS_PATH}
	@echo "creating ${TK_VFS_PATH} (prepare compression)"
	@( \
	  $(COPY) -a $(TOP_DIR)/library/* ${TK_VFS_PATH}; \
	)
	@$(RMDIR) $(TK_VFS_PATH)/demos
	-@if test "${ZIPFS_BUILD}" = "2" ; then \
	    cp ${TCL_BIN_DIR}/tclsh${TCLVER}s.exe ${TK_VFS_ROOT}/../${TK_ZIP_FILE} || cp ${TCL_BIN_DIR}/../bin/tclsh${TCLVER}s.exe ${TK_VFS_ROOT}/../${TK_ZIP_FILE}; \
	    (zip=`(realpath '${NATIVE_ZIP}' || readlink -m '${NATIVE_ZIP}') 2>/dev/null || \
		(echo '${NATIVE_ZIP}' | sed "s?^\./?$$(pwd)/?")`; \
		cd ${TK_VFS_ROOT} && $$zip -J ../${TK_ZIP_FILE}) \
	fi
	(zip=`(realpath '${NATIVE_ZIP}' || readlink -m '${NATIVE_ZIP}') 2>/dev/null || \
	  (echo '${NATIVE_ZIP}' | sed "s?^\./?$$(pwd)/?")`; \
	  cd ${TK_VFS_ROOT} && \
	  $$zip ${ZIP_PROG_OPTIONS} ../${TK_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} >/dev/null && \
	  echo "${TK_ZIP_FILE} successful created with $$zip" && \
	  cd ..)


# The following targets are configured by autoconf to generate either
# a shared library or static library

${TK_STUB_LIB_FILE}: ${STUB_OBJS}
	@$(RM) ${TK_STUB_LIB_FILE}
	@MAKE_STUB_LIB@ ${STUB_OBJS}
	@POST_MAKE_LIB@

${TK_DLL_FILE}: ${TK_OBJS} $(TK_RES) ${TK_ZIP_FILE}
	@$(RM) ${TK_DLL_FILE}
	@MAKE_DLL@ ${TK_OBJS} $(TK_RES) $(SHLIB_LD_LIBS)
	@VC_MANIFEST_EMBED_DLL@
	@if test "${ZIPFS_BUILD}" = "1" ; then \
		cat ${TK_ZIP_FILE} >> ${TK_DLL_FILE}; \
		${NATIVE_ZIP} -A ${TK_DLL_FILE} \
		  || echo 'ignore zip-error by adjust sfx process (not executable?)'; \
	fi

${TK_LIB_FILE}: ${TK_OBJS}
	@$(RM) ${TK_LIB_FILE}
	@MAKE_LIB@ ${TK_OBJS}
	@POST_MAKE_LIB@

# Special case object file targets

winMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

testMain.$(OBJEXT): winMain.c
	$(CC) -c $(CC_SWITCHES) -DTK_TEST -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

tkTest.$(OBJEXT): tkTest.c
	$(CC) -c $(CC_SWITCHES) -DUSE_TK_STUBS @DEPARG@ $(CC_OBJNAME)

tkWinTest.$(OBJEXT): tkWinTest.c
	$(CC) -c $(CC_SWITCHES) -DUSE_TK_STUBS @DEPARG@ $(CC_OBJNAME)

tkSquare.$(OBJEXT): tkSquare.c
	$(CC) -c $(CC_SWITCHES) -DUSE_TK_STUBS @DEPARG@ $(CC_OBJNAME)

tkStubLib.$(OBJEXT): tkStubLib.c
	$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ @DEPARG@ $(CC_OBJNAME)

ttkStubLib.$(OBJEXT): ${TTK_DIR}/ttkStubLib.c
	$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ @DEPARG@ $(CC_OBJNAME)

tkMain2.$(OBJEXT): tkMain.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DUNICODE=1 -D_UNICODE=1 @DEPARG@ $(CC_OBJNAME)

tkUnixMenubu.$(OBJEXT): ${UNIX_DIR}/tkUnixMenubu.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

tkUnixScale.$(OBJEXT): ${UNIX_DIR}/tkUnixScale.c
	$(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME)

tkPkgConfig.$(OBJEXT): $(GENERIC_DIR)/tkPkgConfig.c
	$(CC) -c $(CC_SWITCHES)	 -DBUILD_tk -DBUILD_ttk		\
		-DCFG_RUNTIME_DLLFILE="\"$(TK_DLL_FILE)\"" \
		@DEPARG@ $(CC_OBJNAME)


tkWindow.$(OBJEXT): ${GENERIC_DIR}/tkWindow.c configure Makefile tkUuid.h
	$(CC) -c $(CC_SWITCHES) -I. -DBUILD_tk @DEPARG@ $(CC_OBJNAME)

# Extra dependency info
tkConsole.$(OBJEXT): configure Makefile
tkMain.$(OBJEXT): configure Makefile
tkMain2.$(OBJEXT): configure Makefile


# Add the object extension to the implicit rules.  By default .obj is not
# automatically added.

.SUFFIXES: .${OBJEXT}
.SUFFIXES: .$(RES)
.SUFFIXES: .rc
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725

cleanhelp:
	$(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl.exe

clean: cleanhelp
	$(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(WISH) $(TKTEST) $(CAT32)
	$(RM) *.pch *.ilk *.pdb


distclean: clean
	$(RM) Makefile config.status config.cache config.log tkConfig.sh \
		wish.exe.manifest

Makefile: $(SRC_DIR)/Makefile.in
	./config.status

#
# Regenerate the stubs files.
#







|
>



|







823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842

cleanhelp:
	$(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl.exe

clean: cleanhelp
	$(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out
	$(RM) $(WISH) $(TKTEST) $(CAT32)
	$(RM) *.pch *.ilk *.pdb *.zip
	$(RMDIR) *.vfs

distclean: clean
	$(RM) Makefile config.status config.cache config.log tkConfig.sh \
		wish.exe.manifest tkUuid.h

Makefile: $(SRC_DIR)/Makefile.in
	./config.status

#
# Regenerate the stubs files.
#

Changes to win/README.

1
2
3
4
5
6
7
8
Tk 8.7 for Windows

Originally by Scott Stanton while at Sun Microsystems Labs

This is the directory where you configure and compile the Windows
version of Tk.  This directory also contains source files for Tk
that are specific to Microsoft Windows.  The rest of this file
contains information specific to the Windows version of Tk.
|







1
2
3
4
5
6
7
8
Tk 9.0 for Windows

Originally by Scott Stanton while at Sun Microsystems Labs

This is the directory where you configure and compile the Windows
version of Tk.  This directory also contains source files for Tk
that are specific to Microsoft Windows.  The rest of this file
contains information specific to the Windows version of Tk.

Changes to win/configure.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33








34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64


65
66
67

68
69









70




71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191

192
193


194
195
196
197
198
199
200

201
202
203

204
205

206
207
208
209
210
211
212

213



214
215
216
217
218
219
220
221

222
223

224
225
226
227
228
229
230





231
232

233


234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.

#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :

  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;

esac
fi










as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '


    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi

  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'









fi





# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
  fi
  # We don't want this to propagate to other subprocesses.
          { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :

  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '\${1+\"\$@\"}'='\"\$@\"'
  setopt NO_GLOB_SUBST
else
  case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;

esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :


else
  exitcode=1; echo positional parameters were not saved.

fi
test x\$exitcode = x0 || exit 1


test -x / || exit 1"
  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
test \$(( 1 + 1 )) = 2 || exit 1"
  if (eval "$as_required") 2>/dev/null; then :

  as_have_required=yes
else
  as_have_required=no

fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :


else
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



  as_found=:
  case $as_dir in #(
	 /*)
	   for as_base in sh bash ksh sh5; do
	     # Try only shells that exist, to save several forks.
	     as_shell=$as_dir/$as_base
	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :

  CONFIG_SHELL=$as_shell as_have_required=yes
		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :

  break 2
fi
fi
	   done;;
       esac
  as_found=false
done





$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :

  CONFIG_SHELL=$SHELL as_have_required=yes


fi; }
IFS=$as_save_IFS


      if test "x$CONFIG_SHELL" != x; then :

  export CONFIG_SHELL
             # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi

    if test x$as_have_required = xno; then :

  $as_echo "$0: This script requires a shell more modern than all"
  $as_echo "$0: the shells that I found on your system."
  if test x${ZSH_VERSION+set} = xset ; then
    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
  else
    $as_echo "$0: Please tell [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
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1


|


|
>










|
>






|
|




>




>
>
>
>
>
>
>
>



<
<
<
<
<
<
<
<
|
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
>
>
|
<
<
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>


|








<
<
<
<
<
<
<








>
|
>
>
>
|





|





|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|
|
|




|
>






|
|




>














|
>

|
|
>


>
>






|
>

|
|
>

|
>

|
|




>
|
>
>
>





|

|
>

|
>







>
>
>
>
>
|
|
>

>
>
|
<


|
>
















|
|



|
>
|
|
|
|
|

|





|
>



















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47








48
49

50
51






52







53
54
55
56


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113




















114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for tk 9.0.
#
#
# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
# Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test ${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 case e in #(
  e) case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac ;;
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








IFS=" ""	$as_nl"


PS1='$ '
PS2='> '






PS4='+ '








# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL


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 ${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









# 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 #(((
    '') 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
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi






















# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed 'exec'.
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 \${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 case e in #(
  e) case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac ;;
esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" )
then :

else case e in #(
  e) exitcode=1; echo positional parameters were not saved. ;;
esac
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 :
  as_have_required=yes
else case e in #(
  e) as_have_required=no ;;
esac
fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
then :

else case e in #(
  e) 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 #(((
    '') 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
	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
		    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_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 case e in #(
  e) 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 ;;
esac
fi



      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'.
printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi

    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
    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 ;;
esac
fi
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|








|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  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=`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 ||
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
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :

  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }

fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :

  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }

fi # as_fn_arith


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error

if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else







|
>




|
|


|
>







|
>




|
|


|
>













|

|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else case e in #(
  e) as_fn_append ()
  {
    eval $1=\$$1\$2
  } ;;
esac
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else case e in #(
  e) as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  } ;;
esac
fi # as_fn_arith


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  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
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q







|







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
468
469
470
471
472
473
474


475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499




500
501
502
503
504
505
506
507
508
509
510
511






512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
  sed -n '
    p
    /[$]LINENO/=
  ' <$as_myself |
    sed '


      s/[$]LINENO.*/&-/
      t lineno
      b
      :lineno
      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }

  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
  # already done that, so ensure we don't try to do so again and fall
  # in an infinite loop.  This has already happened in practice.
  _as_can_reexec=no; export _as_can_reexec
  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensitive to this).
  . "./$as_me.lineno"
  # Exit status is that of the last command.
  exit
}





ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac







rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi







>
>











|













>
>
>
>












>
>
>
>
>
>












|
|
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
  sed -n '
    p
    /[$]LINENO/=
  ' <$as_myself |
    sed '
      t clear
      :clear
      s/[$]LINENO.*/&-/
      t lineno
      b
      :lineno
      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { 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
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
    # In both cases, we have to default to 'cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi
544
545
546
547
548
549
550
551

552
553
554

555
556
557
558
559
560
561
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"


# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"



test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1

# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,







|
>


|
>







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated

# Sed expression to map a string onto a valid variable name.
as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
as_tr_sh="eval sed '$as_sed_sh'" # deprecated


test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1

# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617









618
619
620
621

622
623
624
625
626
627
628
LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME=
PACKAGE_TARNAME=
PACKAGE_VERSION=
PACKAGE_STRING=
PACKAGE_BUGREPORT=
PACKAGE_URL=

ac_unique_file="../generic/tk.h"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif









#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif"


ac_subst_vars='LTLIBOBJS
LIBOBJS
RES
RC_DEFINES
RC_DEFINE
RC_INCLUDE
RC_TYPE







|
|
|
|
|
|




|
|
|

|
<
<
<

<
<
<
<
<


<
<
<


<
<
<






>
>
>
>
>
>
>
>
>




>







595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616



617





618
619



620
621



622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='tk'
PACKAGE_TARNAME='tk'
PACKAGE_VERSION='9.0'
PACKAGE_STRING='tk 9.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

ac_unique_file="../generic/tk.h"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stddef.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H



# include <stdlib.h>





#endif
#ifdef HAVE_STRING_H



# include <string.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
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674


675
676
677
678
679
680
681
682










683
684
685
686

687
688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
LDFLAGS_CONSOLE
LDFLAGS_OPTIMIZE
LDFLAGS_DEBUG
CC_EXENAME
CC_OBJNAME
DEPARG
EXTRA_CFLAGS
CFG_TK_EXPORT_FILE_SUFFIX
CFG_TK_UNSHARED_LIB_SUFFIX
CFG_TK_SHARED_LIB_SUFFIX
TCL_PATCH_LEVEL
TCL_MINOR_VERSION
TCL_MAJOR_VERSION
TK_BIN_DIR
TK_SRC_DIR
TK_BUILD_STUB_LIB_SPEC
TK_STUB_LIB_FLAG
TK_STUB_LIB_FILE


TK_DLL_FILE
TK_LIB_FILE
TK_PATCH_LEVEL
TK_MINOR_VERSION
TK_MAJOR_VERSION
TK_VERSION
MACHINE
TK_WIN_VERSION










TCLSH_PROG
BUILD_TCLSH
VC_MANIFEST_EMBED_EXE
VC_MANIFEST_EMBED_DLL

LDFLAGS_DEFAULT
CFLAGS_DEFAULT
MAN2TCLFLAGS

CFLAGS_WARNING
CFLAGS_OPTIMIZE
CFLAGS_DEBUG
DL_LIBS
WINE
CYGPATH
TCL_DEFS
TCL_STUB_LIB_SPEC
TCL_STUB_LIB_FLAG
TCL_STUB_LIB_FILE
TCL_LIB_SPEC
TCL_LIB_FLAG
TCL_LIB_FILE
TCL_ZIP_FILE
TCL_SRC_DIR
TCL_BIN_DIR
TCL_VERSION
SHARED_BUILD
SET_MAKE
RC
RANLIB
AR
EGREP
GREP
CPP
OBJEXT
EXEEXT
ac_ct_CC
CPPFLAGS
LDFLAGS
CFLAGS
CC







<










>
>








>
>
>
>
>
>
>
>
>
>




>



>













<








<
<
<







677
678
679
680
681
682
683

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743



744
745
746
747
748
749
750
LDFLAGS_CONSOLE
LDFLAGS_OPTIMIZE
LDFLAGS_DEBUG
CC_EXENAME
CC_OBJNAME
DEPARG
EXTRA_CFLAGS

CFG_TK_UNSHARED_LIB_SUFFIX
CFG_TK_SHARED_LIB_SUFFIX
TCL_PATCH_LEVEL
TCL_MINOR_VERSION
TCL_MAJOR_VERSION
TK_BIN_DIR
TK_SRC_DIR
TK_BUILD_STUB_LIB_SPEC
TK_STUB_LIB_FLAG
TK_STUB_LIB_FILE
TK_DLL_FILE_TCL9
TK_DLL_FILE_TCL8
TK_DLL_FILE
TK_LIB_FILE
TK_PATCH_LEVEL
TK_MINOR_VERSION
TK_MAJOR_VERSION
TK_VERSION
MACHINE
TK_WIN_VERSION
INSTALL_MSGS
INSTALL_LIBRARIES
TK_ZIP_FILE
ZIPFS_BUILD
ZIP_INSTALL_OBJS
ZIP_PROG_VFSSEARCH
ZIP_PROG_OPTIONS
ZIP_PROG
EXEEXT_FOR_BUILD
CC_FOR_BUILD
TCLSH_PROG
BUILD_TCLSH
VC_MANIFEST_EMBED_EXE
VC_MANIFEST_EMBED_DLL
CPP
LDFLAGS_DEFAULT
CFLAGS_DEFAULT
MAN2TCLFLAGS
CFLAGS_NOLTO
CFLAGS_WARNING
CFLAGS_OPTIMIZE
CFLAGS_DEBUG
DL_LIBS
WINE
CYGPATH
TCL_DEFS
TCL_STUB_LIB_SPEC
TCL_STUB_LIB_FLAG
TCL_STUB_LIB_FILE
TCL_LIB_SPEC
TCL_LIB_FLAG
TCL_LIB_FILE

TCL_SRC_DIR
TCL_BIN_DIR
TCL_VERSION
SHARED_BUILD
SET_MAKE
RC
RANLIB
AR



OBJEXT
EXEEXT
ac_ct_CC
CPPFLAGS
LDFLAGS
CFLAGS
CC
734
735
736
737
738
739
740

741
742
743
744
745
746
747
pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir

localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir







>







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
762
763
764
765
766
767
768

769
770
771
772
773
774
775
ac_user_opts='
enable_option_checking
enable_shared
with_tcl
enable_64bit
enable_symbols
enable_embedded_manifest

'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS







>







792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
ac_user_opts='
enable_option_checking
enable_shared
with_tcl
enable_64bit
enable_symbols
enable_embedded_manifest
enable_zipfs
'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824
825
826
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'

includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'







>


|







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
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}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854

  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=*)







<
<







871
872
873
874
875
876
877


878
879
880
881
882
883
884

  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac



  case $ac_dashdash$ac_option in
  --)
    ac_dashdash=yes ;;

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac







|

|







911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: '$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`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
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac







|

|







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: '$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`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
1061
1062
1063
1064
1065
1066
1067









1068
1069
1070
1071
1072
1073
1074
    ac_prev=psdir ;;
  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
    psdir=$ac_optarg ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;










  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir=$ac_optarg ;;








>
>
>
>
>
>
>
>
>







1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
    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 ;;

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
  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=\$ac_optarg ;;

  -without-* | --without-*)
    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac







|

|













|

|







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
  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;

  -with-* | --with-*)
    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: '$ac_useropt'"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`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'"
    ac_useropt_orig=$ac_useropt
    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
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
  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) as_fn_error $? "unrecognized option: \`$ac_option'
Try \`$0 --help' for more information"
    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  as_fn_error $? "missing argument to $ac_option"
fi

if test -n "$ac_unrecognized_opts"; then
  case $enable_option_checking in
    no) ;;
    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
  esac
fi

# Check all directory arguments for consistency.
for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
  esac
  # Be sure to have absolute directory names.
  case $ac_val in
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
  esac
  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done

# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias

# FIXME: To remove some day.







|
|







|






|

|















|







|
















|







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
  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) as_fn_error $? "unrecognized option: '$ac_option'
Try '$0 --help' for more information"
    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: '$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)
    # FIXME: should be removed in autoconf 3.0.
    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      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" ;;
    *)     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 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;;
  esac
  # Be sure to have absolute directory names.
  case $ac_val in
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
  esac
  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done

# There might be people who depend on the old broken behavior: '$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias

# FIXME: To remove some day.
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then the parent directory.
  ac_confdir=`$as_dirname -- "$as_myself" ||
$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_myself" : 'X\(//\)[^/]' \| \
	 X"$as_myself" : 'X\(//\)$' \| \
	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
  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 ||
printf "%s\n" X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
else
  ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
	pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
  srcdir=.
fi







|







1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
else
  ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work"
ac_abs_confdir=`(
	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
	pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
  srcdir=.
fi
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
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures this package to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print \`checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for \`--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or \`..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]

  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]
_ACEOF

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then



  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-shared         build and link with shared libraries (default: on)
  --enable-64bit          enable 64bit support (where applicable)
  --enable-symbols        build with debugging symbols (default: off)
  --enable-embedded-manifest
                          embed manifest if possible (default: yes)


Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-tcl              directory containing tcl configuration
                          (tclConfig.sh)

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.
_ACEOF
ac_status=$?
fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.
  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
    test -d "$ac_dir" ||
      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix







|













|

|

|







|
|
|
|










>








|











|
>
>











>

















|


















|

|







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
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
'configure' configures tk 9.0 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print 'checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for '--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or '..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, 'make install' will install all the files in
'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than '$ac_default_prefix' using '--prefix',
for instance '--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --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/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 9.0:";;
   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)
  --enable-64bit          enable 64bit support (where applicable)
  --enable-symbols        build with debugging symbols (default: off)
  --enable-embedded-manifest
                          embed manifest if possible (default: yes)
  --enable-zipfs          build with Zipfs support (default: on)

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-tcl              directory containing tcl configuration
                          (tclConfig.sh)

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor

Use these variables to override the choices made by 'configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.
_ACEOF
ac_status=$?
fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.
  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
    test -d "$ac_dir" ||
      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  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
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
    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix

    cd "$ac_dir" || { ac_status=$?; continue; }
    # Check for guested configure.

    if test -f "$ac_srcdir/configure.gnu"; then
      echo &&
      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
    elif test -f "$ac_srcdir/configure"; then
      echo &&
      $SHELL "$ac_srcdir/configure" --help=recursive
    else
      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
configure
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi

## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##

# ac_fn_c_try_compile LINENO
# --------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext
  if { { ac_try="$ac_compile"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && {
	 test -z "$ac_c_werror_flag" ||
	 test ! -s conftest.err
       } && test -s conftest.$ac_objext; then :

  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1

fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_compile































































































# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_cpp ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if { { ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } > conftest.i && {
	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
	 test ! -s conftest.err

       }; then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

    ac_retval=1

fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_cpp

# ac_fn_c_try_run LINENO
# ----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
# that executables *can* be run.
ac_fn_c_try_run ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if { { ac_try="$ac_link"

case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5

  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
  { { case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }; then :
  ac_retval=0
else
  $as_echo "$as_me: program exited with status $ac_status" >&5
       $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

       ac_retval=$ac_status
fi
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_run

# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
# the include files in INCLUDES and setting the cache variable VAR
# accordingly.
ac_fn_c_check_header_mongrel ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  if eval \${$3+:} false; then :
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
else
  # Is the header compilable?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
$as_echo_n "checking $2 usability... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_header_compiler=yes
else
  ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
$as_echo "$ac_header_compiler" >&6; }

# Is the header present?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
$as_echo_n "checking $2 presence... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <$2>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  ac_header_preproc=yes
else
  ac_header_preproc=no
fi
rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }

# So?  What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
  yes:no: )
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
    ;;
  no:yes:* )
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
    ;;
esac
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
else
  eval "$3=\$ac_header_compiler"
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5

$as_echo "$ac_res" >&6; }
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_mongrel

# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
# INCLUDES, setting the cache variable VAR accordingly.
ac_fn_c_check_header_compile ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  eval "$3=yes"
else
  eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
eval ac_res=\$$3
	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_compile
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##







|
>







|








|
|

|
















|






|







|



|
>

|
|


|
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|







|



>
|

|
|


|
>





|
|
<
<
<
<
<
<
<
>
|
<
<
<
<
<
>
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<




|
|

|







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
    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 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
      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 9.0
generated by GNU Autoconf 2.72

Copyright (C) 2023 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 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\""
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
  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 :
  ac_retval=0
else case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1 ;;
esac
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 case e in #(
  e) 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 case e in #(
  e) eval "$3=no" ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
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 case e in #(
  e) 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 case e in #(
  e) eval "$3=yes" ;;
esac
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 ;;
esac
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\""
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 case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

    ac_retval=1 ;;
esac
fi
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_cpp
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 9.0, which was
generated by GNU Autoconf 2.72.  Invocation command line was

  $ $0$ac_configure_args_raw

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
1755
1756
1757
1758
1759
1760
1761

1762



1763
1764
1765
1766
1767
1768
1769
1770

_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    $as_echo "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF








>
|
>
>
>
|







1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776

_ASUNAME

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
    printf "%s\n" "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF

1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
  do
    case $ac_arg in
    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
    | -silent | --silent | --silen | --sile | --sil)
      continue ;;
    *\'*)
      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.







|







1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
  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=`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.
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

# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?


  # Save into config.log some information that might help in debugging.
  {
    echo

    $as_echo "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
    echo
    # The following way of writing the cache mishandles newlines in values,
(
  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac







>
>




|










|
|







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

# 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

    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_*) { 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
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
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    echo

    $as_echo "## ----------------- ##
## Output variables. ##
## ----------------- ##"
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      $as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      $as_echo "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
_ACEOF


# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
  # We do not want a PATH search for config.site.
  case $CONFIG_SITE in #((
    -*)  ac_site_file1=./$CONFIG_SITE;;
    */*) ac_site_file1=$CONFIG_SITE;;
    *)   ac_site_file1=./$CONFIG_SITE;;
  esac
elif test "x$prefix" != xNONE; then
  ac_site_file1=$prefix/share/config.site
  ac_site_file2=$prefix/etc/config.site
else
  ac_site_file1=$ac_default_prefix/share/config.site
  ac_site_file2=$ac_default_prefix/etc/config.site
fi

for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
  test "x$ac_site_file" = xNONE && continue





  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file" \
      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5; }
  fi
done

if test -r "$cache_file"; then
  # Some versions of bash will fail to source /dev/null (special files
  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                      . "./$cache_file";;
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi















































































































































































































































































































































# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do
  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val=\$ac_cv_env_${ac_var}_value
  eval ac_new_val=\$ac_env_${ac_var}_value
  case $ac_old_set,$ac_new_set in
    set,)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,set)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,);;
    *)
      if test "x$ac_old_val" != "x$ac_new_val"; then
	# differences in whitespace do not lead to failure.
	ac_old_val_w=`echo x $ac_old_val`
	ac_new_val_w=`echo x $ac_new_val`
	if test "$ac_old_val_w" != "$ac_new_val_w"; then
	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
	  ac_cache_corrupted=:
	else
	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
	  eval $ac_var=\$ac_old_val
	fi
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in
    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}

  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu





# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then







|







|

|




|







|

|





|







|
|













|



<
|
<

<
|
<

<
|
<

<
|
<

<
|
<

<
|
<




<
<

<
|
<
<
<
<

|
<

|
<

>
|

|
>
>
>
>
>
|
|
|


|
|

|







|
|






|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
|


|
|








|
|


|
|


|
|
|
|





|









|
|
|
|
>
|













>






|
|
|
|







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
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    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=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      printf "%s\n" "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      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=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	printf "%s\n" "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      printf "%s\n" "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      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

printf "%s\n" "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.


printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h



printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h



# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.


if test -n "$CONFIG_SITE"; then

  ac_site_files="$CONFIG_SITE"




elif test "x$prefix" != xNONE; then
  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"

else
  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"

fi

for ac_site_file in $ac_site_files
do
  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" \
      || { { 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
    { 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
  { 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 (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;
}

/* C89 style stringification. */
#define noexpand_stringify(a) #a
const char *stringified = noexpand_stringify(arbitrary+token=sequence);

/* C89 style token pasting.  Exercises some of the corner cases that
   e.g. old MSVC gets wrong, but not very hard. */
#define noexpand_concat(a,b) a##b
#define expand_concat(a,b) noexpand_concat(a,b)
extern int vA;
extern int vbee;
#define aye A
#define bee B
int *pvA = &expand_concat(v,aye);
int *pvbee = &noexpand_concat(v,bee);

/* 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

// See if C++-style comments work.

#include <stdbool.h>
extern int puts (const char *);
extern int printf (const char *, ...);
extern int dprintf (int, const char *, ...);
extern void *malloc (size_t);
extern void free (void *);

// 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)
{
  // 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;
  // Work around memory leak warnings.
  free (ia);

  // 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,)
      { 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)
      { 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
	  { 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
	  { 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
	{ 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=`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
  { 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.
SHELL=/bin/sh

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
2102
2103
2104
2105
2106
2107
2108









2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120

2121
2122
2123
2124
2125
2126
2127
2128
2129

2130



2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141

2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160

2161
2162
2163
2164
2165
2166
2167
2168
2169

2170



2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181

2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213

2214
2215
2216
2217
2218
2219
2220
2221
2222

2223



2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234

2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253

2254
2255
2256
2257
2258
2259
2260
2261
2262
2263

2264



2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291

2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312

2313
2314
2315
2316
2317
2318
2319
2320
2321

2322



2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356

2357
2358
2359
2360
2361
2362
2363
2364
2365

2366



2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377

2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402










































































































2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481

2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515

2516
2517

2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529

2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551

2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569

2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584


2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635

2636
2637
2638
2639

2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664

2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680

2681
2682

2683
2684
2685
2686
2687
2688
2689
2690

2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707

2708
2709
2710

2711
2712
2713
2714

2715
2716
2717


2718
2719
2720
2721
2722
2723
2724
2725
2726
2727

2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745

2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760

2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776

2777
2778
2779

2780
2781

2782
2783
2784

2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802



2803
2804


































































































2805

2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866

2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884

2885




2886
2887

2888

2889
2890


2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902

2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916

2917
2918
2919
2920
2921
2922

2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328

3329
3330
3331
3332
3333
3334
3335
3336
3337

3338



3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349

3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368

3369
3370
3371
3372
3373
3374
3375
3376
3377

3378



3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389

3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420

3421
3422
3423
3424
3425
3426
3427
3428
3429

3430



3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441

3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460

3461
3462
3463
3464
3465
3466
3467
3468
3469

3470



3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481

3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512

3513
3514
3515
3516
3517
3518
3519
3520
3521

3522



3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533

3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552

3553
3554
3555
3556
3557
3558
3559
3560
3561

3562



3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573

3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608

3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623

3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652

3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
#------------------------------------------------------------------------

# 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
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_CC"; then
  ac_ct_CC=$CC
  # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="gcc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi
else
  CC="$ac_cv_prog_CC"
fi

if test -z "$CC"; then
          if test -n "$ac_tool_prefix"; then
    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="${ac_tool_prefix}cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


  fi
fi
if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# != 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
  fi
fi
fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$CC"; then
  if test -n "$ac_tool_prefix"; then
  for ac_prog in cl.exe
  do
    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


    test -n "$CC" && break
  done
fi
if test -z "$CC"; then
  ac_ct_CC=$CC
  for ac_prog in cl.exe
do
  # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_CC"; then
  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_CC="$ac_prog"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


  test -n "$ac_ct_CC" && break
done

  if test "x$ac_ct_CC" = x; then
    CC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    CC=$ac_ct_CC
  fi










































































































fi

fi


test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }

# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
  { { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    sed '10a\
... rest of stderr output deleted ...
         10q' conftest.err >conftest.er1
    cat conftest.er1 >&5
  fi
  rm -f conftest.er1 conftest.err
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
done

cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`

# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"

ac_rmfiles=
for ac_file in $ac_files
do
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
  esac
done
rm -f $ac_rmfiles

if { { ac_try="$ac_link_default"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :

  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile.  We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
for ac_file in $ac_files ''
do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
	;;
    [ab].out )
	# We found the default executable, but exeext='' is most
	# certainly right.
	break;;
    *.* )
	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
	then :; else
	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	fi
	# We set ac_cv_exeext here because the later test for it is not
	# safe: cross compilers may not add the suffix if given an `-o'
	# argument, so we may need to know it at that point already.
	# Even if this section looks crufty: it has the advantage of
	# actually working.
	break;;
    * )
	break;;
  esac
done
test "$ac_cv_exeext" = no && ac_cv_exeext=

else
  ac_file=''

fi
if test -z "$ac_file"; then :

  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
See \`config.log' for more details" "$LINENO" 5; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
$as_echo_n "checking for C compiler default output file name... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext

rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :

  # If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
  test -f "$ac_file" || continue
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
	  break;;
    * ) break;;
  esac
done
else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }

fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }

rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdio.h>
int
main ()
{
FILE *f = fopen ("conftest.out", "w");


 return ferror (f) || fclose (f) != 0;

  ;
  return 0;
}
_ACEOF
ac_clean_files="$ac_clean_files conftest.out"
# Check that the compiler produces executables we can run.  If not, either
# the compiler is broken, or we cross compile.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
$as_echo_n "checking whether we are cross compiling... " >&6; }
if test "$cross_compiling" != yes; then
  { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }
  if { ac_try='./conftest$ac_cv_exeext'
  { { case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; }; then
    cross_compiling=no
  else
    if test "$cross_compiling" = maybe; then
	cross_compiling=yes
    else
	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details" "$LINENO" 5; }
    fi
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
$as_echo "$cross_compiling" >&6; }

rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out

ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if ${ac_cv_objext+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { { ac_try="$ac_compile"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :

  for ac_file in conftest.o conftest.obj conftest.*; do
  test -f "$ac_file" || continue;
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }

fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
if ${ac_cv_c_compiler_gnu+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_compiler_gnu=yes
else
  ac_compiler_gnu=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
$as_echo "$ac_cv_c_compiler_gnu" >&6; }


if test $ac_compiler_gnu = yes; then
  GCC=yes
else
  GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
if ${ac_cv_prog_cc_g+:} false; then :

  $as_echo_n "(cached) " >&6
else
  ac_save_c_werror_flag=$ac_c_werror_flag
   ac_c_werror_flag=yes
   ac_cv_prog_cc_g=no
   CFLAGS="-g"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_prog_cc_g=yes
else
  CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :


else
  ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
  CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi



{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }


































































































if ${ac_cv_prog_cc_c89+:} false; then :

  $as_echo_n "(cached) " >&6
else
  ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdarg.h>
#include <stdio.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
     char **p;
     int i;
{
  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 don't provoke an error unfortunately, instead are silently treated
   as 'x'.  The following induces an error, until -std is added to get
   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
   array size at least.  It's necessary to write '\x00'==0 to get something
   that's true only with -std.  */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];

/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
   inside strings and character constants.  */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];

int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
  ;
  return 0;
}
_ACEOF
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c89" in
  x)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
  xno)
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
  *)

    CC="$CC $ac_cv_prog_cc_c89"




    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;

esac

if test "x$ac_cv_prog_cc_c89" != xno; then :



fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
if ${ac_cv_c_inline+:} false; then :

  $as_echo_n "(cached) " >&6
else
  ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifndef __cplusplus
typedef int foo_t;
static $ac_kw foo_t static_foo () {return 0; }
$ac_kw foo_t foo () {return 0; }
#endif

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_c_inline=$ac_kw
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  test "$ac_cv_c_inline" != no && break
done


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
$as_echo "$ac_cv_c_inline" >&6; }

case $ac_cv_c_inline in
  inline | yes) ;;
  *)
    case $ac_cv_c_inline in
      no) ac_val=;;
      *) ac_val=$ac_cv_c_inline;;
    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 :

else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
  break
fi

    done
    ac_cv_prog_CPP=$CPP

fi
  CPP=$ac_cv_prog_CPP
else
  ac_cv_prog_CPP=$CPP
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
  # Use a header file that comes with gcc, so configuring glibc
  # with a fresh cross-compiler works.
  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
  # <limits.h> exists even on freestanding compilers.
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp. "Syntax error" is here to catch this case.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
		     Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :

else
  # Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ac_nonexistent.h>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
  # Broken: success on invalid input.
continue
else
  # Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext

done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :

else
  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi

ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if test -z "$GREP"; then
  ac_path_GREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in grep ggrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
  # Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'GREP' >> "conftest.nl"
    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_GREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_GREP="$ac_path_GREP"
      ac_path_GREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_GREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_GREP"; then
    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_GREP=$GREP
fi

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
$as_echo "$ac_cv_path_GREP" >&6; }
 GREP="$ac_cv_path_GREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if ${ac_cv_path_EGREP+:} false; then :
  $as_echo_n "(cached) " >&6
else
  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
   then ac_cv_path_EGREP="$GREP -E"
   else
     if test -z "$EGREP"; then
  ac_path_EGREP_found=false
  # Loop through the user's path and test for each of PROGNAME-LIST
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    for ac_prog in egrep; do
    for ac_exec_ext in '' $ac_executable_extensions; do
      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
  # Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
*GNU*)
  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
  ac_count=0
  $as_echo_n 0123456789 >"conftest.in"
  while :
  do
    cat "conftest.in" "conftest.in" >"conftest.tmp"
    mv "conftest.tmp" "conftest.in"
    cp "conftest.in" "conftest.nl"
    $as_echo 'EGREP' >> "conftest.nl"
    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
    as_fn_arith $ac_count + 1 && ac_count=$as_val
    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP="$ac_path_EGREP"
      ac_path_EGREP_max=$ac_count
    fi
    # 10*(2^10) chars as input seems more than enough
    test $ac_count -gt 10 && break
  done
  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac

      $ac_path_EGREP_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP"; then
    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  fi
else
  ac_cv_path_EGREP=$EGREP
fi

   fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
$as_echo "$ac_cv_path_EGREP" >&6; }
 EGREP="$ac_cv_path_EGREP"


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_header_stdc=yes
else
  ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

if test $ac_cv_header_stdc = yes; then
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <string.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "free" >/dev/null 2>&1; then :

else
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  if test "$cross_compiling" = yes; then :
  :
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <ctype.h>
#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# 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

fi


if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AR+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$AR"; then
  ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_AR="${ac_tool_prefix}ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
$as_echo "$AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_AR"; then
  ac_ct_AR=$AR
  # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_AR+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_AR"; then
  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_AR="ar"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
$as_echo "$ac_ct_AR" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_AR" = x; then
    AR=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    AR=$ac_ct_AR
  fi
else
  AR="$ac_cv_prog_AR"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RANLIB+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$RANLIB"; then
  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
$as_echo "$RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RANLIB"; then
  ac_ct_RANLIB=$RANLIB
  # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_RANLIB"; then
  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RANLIB="ranlib"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
$as_echo "$ac_ct_RANLIB" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_RANLIB" = x; then
    RANLIB=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RANLIB=$ac_ct_RANLIB
  fi
else
  RANLIB="$ac_cv_prog_RANLIB"
fi

if test -n "$ac_tool_prefix"; then
  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
set dummy ${ac_tool_prefix}windres; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_RC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$RC"; then
  ac_cv_prog_RC="$RC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_RC="${ac_tool_prefix}windres"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
RC=$ac_cv_prog_RC
if test -n "$RC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
$as_echo "$RC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


fi
if test -z "$ac_cv_prog_RC"; then
  ac_ct_RC=$RC
  # Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_RC+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$ac_ct_RC"; then
  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_ac_ct_RC="windres"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
ac_ct_RC=$ac_cv_prog_ac_ct_RC
if test -n "$ac_ct_RC"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
$as_echo "$ac_ct_RC" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

  if test "x$ac_ct_RC" = x; then
    RC=""
  else
    case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
    RC=$ac_ct_RC
  fi
else
  RC="$ac_cv_prog_RC"
fi


#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat >conftest.make <<\_ACEOF
SHELL = /bin/sh
all:
	@echo '@@@%%%=$(MAKE)=@@@%%%'
_ACEOF
# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
case `${MAKE-make} -f conftest.make 2>/dev/null` in
  *@@@%%%=?*=@@@%%%*)
    eval ac_cv_prog_make_${ac_make}_set=yes;;
  *)
    eval ac_cv_prog_make_${ac_make}_set=no;;
esac
rm -f conftest.make

fi
if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
  SET_MAKE=
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  SET_MAKE="MAKE=${MAKE-make}"
fi


#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------




#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
$as_echo_n "checking how to build libraries... " >&6; }
    # Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :

  enableval=$enable_shared; tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
$as_echo "shared" >&6; }
	SHARED_BUILD=1
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
	SHARED_BUILD=0

$as_echo "#define STATIC_BUILD 1" >>confdefs.h

    fi



#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.







>
>
>
>
>
>
>
>
>









|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|












|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|







>
|
>
>
>

|
|




|















|


|
>



|
|

|
|










|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|












|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|











|
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|

|


|


|






|









|







|











|
|
|




















|


|
|
>
|
|














|




|










|
|
>

|
>
|
|
|


|
|

|
|
|
|
>

|
|
|
|




|
|






|


|
|
>
|
|
|
|









|
|
|

|
>


|
|








|


>
>









|
|







|


|







|


|






|
|
|
|
|



|
|

|
>

|
|
|
>
|
|
|



|













|


|
|
>








|
|


|
|

|
>

|
>

|
|


|
|
|
>
|
|
|



|









|
>

|
|
>

|

|
>

|
|
>
>





|

|
|
|
>
|
|
|







|






|
>

|
|




|






|
>

|
|





|






|
>


|
>

|
>

|
|
>

|
|
|














>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<


|
>


|



|
|

|
|
<
<
<
|
|
|
<
>
|
>
>
>
>
|
|
>

>
|
|
>
>









|
|
|
>
|
|
|





|
|



|
>


|


|
>

|
|
















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
|
|
<
<
<
<
<
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<

<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
|
<
<
<
<
<
<
<

|
<
<
<
<
|
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


<




|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|











|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|











|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|








|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|
|













|
|

|
|
>
|
|
|











|
>


|
|


|
|

















|
|

|
>

|
|
<
|
<
<
<
<
<
<
|


|
|


|
|


|







2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419





















3420



























3421
3422

3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437



3438
3439
3440

3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509





































3510





3511



































3512
















3513





3514















3515




3516





3517
3518





3519
3520




3521







































3522







3523






















































3524


3525











3526





3527
3528











3529


3530



3531







3532
3533




3534



3535







































































3536
3537
3538

3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911

3912






3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
#------------------------------------------------------------------------

# 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
{ 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 case e in #(
  e) 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}gcc"
    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 ;;
esac
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 "gcc", so it can be a program name with args.
set dummy gcc; 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 case e in #(
  e) 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="gcc"
    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 ;;
esac
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

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
{ 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 case e in #(
  e) 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}cc"
    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 ;;
esac
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
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
{ 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 case e in #(
  e) 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 #(((
    '') 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
       ac_prog_rejected=yes
       continue
     fi
    ac_cv_prog_CC="cc"
    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+' '}$@"
  fi
fi
fi ;;
esac
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 "$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
{ 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 case e in #(
  e) 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$ac_prog"
    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 ;;
esac
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


    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
{ 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 case e in #(
  e) 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="$ac_prog"
    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 ;;
esac
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


  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:)
{ 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 case e in #(
  e) 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 ;;
esac
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 case e in #(
  e) 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 ;;
esac
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" && { { 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.
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 -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\""
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
  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 (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.
{ 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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_link_default") 2>&5
  ac_status=$?
  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+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 case e in #(
  e) ac_file='' ;;
esac
fi
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

{ { 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 case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; } ;;
esac
fi
{ 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
{ 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\""
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; }
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 case e in #(
  e) { { 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; } ;;
esac
fi
rm -f conftest conftest$ac_cv_exeext
{ 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 (void)
{
FILE *f = fopen ("conftest.out", "w");
 if (!f)
  return 1;
 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.
{ 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\""
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; }
  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\""
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
    cross_compiling=no
  else
    if test "$cross_compiling" = maybe; then
	cross_compiling=yes
    else
	{ { 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
{ 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.o conftest.obj conftest.out
ac_clean_files=$ac_clean_files_save
{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
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\""
printf "%s\n" "$ac_try_echo"; } >&5
  (eval "$ac_compile") 2>&5
  ac_status=$?
  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 case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

{ { 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; } ;;
esac
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext ;;
esac
fi
{ 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
{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_compiler_gnu=yes
else case e in #(
  e) ac_compiler_gnu=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
 ;;
esac
fi
{ 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+y}
ac_save_CFLAGS=$CFLAGS
{ 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 case e in #(
  e) 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 (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_g=yes
else case e in #(
  e) CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :

else case e in #(
  e) ac_c_werror_flag=$ac_save_c_werror_flag
	 CFLAGS="-g"
	 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_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   ac_c_werror_flag=$ac_save_c_werror_flag ;;
esac
fi
{ 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
ac_prog_cc_stdc=no
if test x$ac_prog_cc_stdc = xno
then :
  { 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 case e in #(
  e) 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 ;;
esac
fi

if test "x$ac_cv_prog_cc_c11" = xno
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
else case e in #(
  e) if test "x$ac_cv_prog_cc_c11" = x
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
else case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
     CC="$CC $ac_cv_prog_cc_c11" ;;
esac
fi
  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
  ac_prog_cc_stdc=c11 ;;
esac
fi
fi
if test x$ac_prog_cc_stdc = xno
then :
  { 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 case e in #(
  e) ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_c_conftest_c99_program
_ACEOF
for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
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 ;;
esac
fi

if test "x$ac_cv_prog_cc_c99" = xno
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }
else case e in #(
  e) if test "x$ac_cv_prog_cc_c99" = x
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
else case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
     CC="$CC $ac_cv_prog_cc_c99" ;;
esac
fi
  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
  ac_prog_cc_stdc=c99 ;;
esac
fi
fi
if test x$ac_prog_cc_stdc = xno
then :
  { 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 case e in #(
  e) ac_cv_prog_cc_c89=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 '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"

do
  CC="$ac_save_CC $ac_arg"
  if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC ;;
esac
fi

if test "x$ac_cv_prog_cc_c89" = xno



then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
printf "%s\n" "unsupported" >&6; }

else case e in #(
  e) if test "x$ac_cv_prog_cc_c89" = x
then :
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
printf "%s\n" "none needed" >&6; }
else case e in #(
  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
     CC="$CC $ac_cv_prog_cc_c89" ;;
esac
fi
  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
  ac_prog_cc_stdc=c89 ;;
esac
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


{ 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 case e in #(
  e) 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 (void) {return 0; }
$ac_kw foo_t foo (void) {return 0; }
#endif

_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_c_inline=$ac_kw
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
  test "$ac_cv_c_inline" != no && break
done
 ;;
esac
fi
{ 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_header= ac_cache=





for ac_item in $ac_header_c_list



































do
















  if test $ac_cache; 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




      printf "%s\n" "#define $ac_item 1" >> confdefs.h





    fi
    ac_header= ac_cache=





  elif test $ac_header; then
    ac_cache=$ac_item




  else







































    ac_header=$ac_item







  fi






















































done

















































if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes




then :











































































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
{ 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 case e in #(
  e) 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 #(((
    '') 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_AR="${ac_tool_prefix}ar"
    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 ;;
esac
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
printf "%s\n" "$AR" >&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_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
{ 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 case e in #(
  e) 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 #(((
    '') 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_AR="ar"
    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 ;;
esac
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
printf "%s\n" "$ac_ct_AR" >&6; }
else
  { 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:)
{ 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
{ 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 case e in #(
  e) 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 #(((
    '') 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_RANLIB="${ac_tool_prefix}ranlib"
    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 ;;
esac
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
printf "%s\n" "$RANLIB" >&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_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
{ 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 case e in #(
  e) 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 #(((
    '') 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_RANLIB="ranlib"
    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 ;;
esac
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
printf "%s\n" "$ac_ct_RANLIB" >&6; }
else
  { 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:)
{ 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
{ 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 case e in #(
  e) 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 #(((
    '') 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_RC="${ac_tool_prefix}windres"
    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 ;;
esac
fi
RC=$ac_cv_prog_RC
if test -n "$RC"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
printf "%s\n" "$RC" >&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_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
{ 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 case e in #(
  e) 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 #(((
    '') 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_RC="windres"
    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 ;;
esac
fi
ac_ct_RC=$ac_cv_prog_ac_ct_RC
if test -n "$ac_ct_RC"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
printf "%s\n" "$ac_ct_RC" >&6; }
else
  { 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:)
{ 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.
#--------------------------------------------------------------------

{ 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=`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 case e in #(
  e) 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 ;;
esac
fi
if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
  SET_MAKE=
else
  { 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.
#--------------------------------------------------------------------


    { 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+y}
then :
  enableval=$enable_shared; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=yes ;;

esac






fi

    if test "$tcl_ok" = "yes" ; then
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared" >&5
printf "%s\n" "shared" >&6; }
	SHARED_BUILD=1
    else
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static" >&5
printf "%s\n" "static" >&6; }
	SHARED_BUILD=0

printf "%s\n" "#define STATIC_BUILD 1" >>confdefs.h

    fi



#--------------------------------------------------------------------
# Locate and source the tclConfig.sh file.
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
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true

# Check whether --with-tcl was given.
if test "${with_tcl+set}" = set; then :

  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
$as_echo_n "checking for Tcl configuration... " >&6; }
	if ${ac_cv_c_tclconfig+:} false; then :

  $as_echo_n "(cached) " >&6
else


	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
			if test -f "${with_tclconfig}"; then
			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else
		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5







|
>



|
|
|
>
|
|
|






|
|







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
    #

    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+y}
then :
  withval=$with_tcl; with_tclconfig="${withval}"
fi

	{ 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 case e in #(
  e)

	    # 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
			    { 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
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
			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
		    if test -f "$i/win/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
		    break
		fi
		done
	    fi


fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
	fi
    fi


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
    fi

    #
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC







|
>









|
|




|
|


|
|


|
|







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
			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
		    if test -f "$i/win/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
		    break
		fi
		done
	    fi
	 ;;
esac
fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    { 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


    { 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
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: loading" >&5
printf "%s\n" "loading" >&6; }
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        { 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
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








if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then
    as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better." "$LINENO" 5
fi
if test "${TCL_MINOR_VERSION}" -lt 6; then
    as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better." "$LINENO" 5
fi
fi

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

# On IRIX 5.3, sys/types and inttypes.h are conflicting.
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
		  inttypes.h stdint.h unistd.h
do :
  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
  cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF

fi

done




    # Step 0: Enable 64 bit support?

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
$as_echo_n "checking if 64bit support is requested... " >&6; }
    # Check whether --enable-64bit was given.
if test "${enable_64bit+set}" = set; then :

  enableval=$enable_64bit; do64bit=$enableval
else
  do64bit=no

fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
$as_echo "$do64bit" >&6; }

    # Set some defaults (may get changed below)
    EXTRA_CFLAGS=""

$as_echo "#define MODULE_SCOPE extern" >>confdefs.h


    # Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CYGPATH+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$CYGPATH"; then
  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_CYGPATH="cygpath -m"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi

fi
CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
$as_echo "$CYGPATH" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


    # Extract the first word of "wine", so it can be a program name with args.
set dummy wine; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_WINE+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test -n "$WINE"; then
  ac_cv_prog_WINE="$WINE" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    for ac_exec_ext in '' $ac_executable_extensions; do
  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    ac_cv_prog_WINE="wine"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  done
IFS=$as_save_IFS

fi

fi
WINE=$ac_cv_prog_WINE
if test -n "$WINE"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5
$as_echo "$WINE" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi



    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
$as_echo_n "checking for cross-compile version of gcc... " >&6; }
if ${ac_cv_cross+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	    #ifndef _WIN32
		#error cross-compiler
	    #endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_cross=no
else
  ac_cv_cross=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
$as_echo "$ac_cv_cross" >&6; }

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-${CC}"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;







	    *)
		CC="i686-w64-mingw32-${CC}"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;







<

<
<
<
<
<
|

|
|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|
|

|
>

|
|
>


|
|




|




|
|
|
>
|
|
|






>
|
>
>
>

|

|







|
>



|
|

|
|





|
|
|
>
|
|
|






>
|
>
>
>

|

|






|
>



|
|

|
|







|




|
|
|
>
|
|
|







|






|
>

|
|
>

|
|
>

|
|










>
>
>
>
>
>
>







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








if test "${TCL_MAJOR_VERSION}" -lt 9 ; then





if test "${TCL_MINOR_VERSION}" -lt 7; then
    as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.7+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.7 or better." "$LINENO" 5
fi
fi

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------




















    # Step 0: Enable 64 bit support?

    { 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+y}
then :
  enableval=$enable_64bit; do64bit=$enableval
else case e in #(
  e) do64bit=no ;;
esac
fi

    { 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=""

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
{ 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 case e in #(
  e) 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 #(((
    '') 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_CYGPATH="cygpath -m"
    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 ;;
esac
fi
CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
printf "%s\n" "$CYGPATH" >&6; }
else
  { 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
{ 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 case e in #(
  e) 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 #(((
    '') 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_WINE="wine"
    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 ;;
esac
fi
WINE=$ac_cv_prog_WINE
if test -n "$WINE"; then
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5
printf "%s\n" "$WINE" >&6; }
else
  { 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|arm64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      { 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	    #ifndef _WIN32
		#error cross-compiler
	    #endif

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_cross=no
else case e in #(
  e) ac_cv_cross=yes ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
       ;;
esac
fi
{ 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"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;
	    arm64|aarch64)
		CC="aarch64-w64-mingw32-${CC}"
		LD="aarch64-w64-mingw32-ld"
		AR="aarch64-w64-mingw32-ar"
		RANLIB="aarch64-w64-mingw32-ranlib"
		RC="aarch64-w64-mingw32-windres"
	    ;;
	    *)
		CC="i686-w64-mingw32-${CC}"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081

4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099

4100
4101
4102

4103
4104
4105

4106
4107
4108
4109
4110
4111



4112
4113
4114
4115
4116

4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147

4148
4149
4150
4151
4152
4153
4154

4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179

4180
4181
4182

4183
4184
4185
4186

4187
4188
4189
4190
4191
4192
4193
4194
4195
























4196






















4197






























































4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275

    if test "$GCC" = "yes" && test "$CYGPATH" != "echo" ; then
	conftest=/tmp/conftest.rc
	echo "STRINGTABLE BEGIN" > $conftest
	echo "101 \"name\"" >> $conftest
	echo "END" >> $conftest

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows native path bug in windres" >&5
$as_echo_n "checking for Windows native path bug in windres... " >&6; }
	cyg_conftest=`$CYGPATH $conftest`
	if { ac_try='$RC -o conftest.res.o $cyg_conftest'
  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; } ; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	    CYGPATH=echo
	fi
	conftest=
	cyg_conftest=
    fi

    if test "$CYGPATH" = "echo"; then
        DEPARG='"$<"'
    else
        DEPARG='"$(shell $(CYGPATH) $<)"'
    fi

    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mingw32 version of gcc" >&5
$as_echo_n "checking for mingw32 version of gcc... " >&6; }
if ${ac_cv_win32+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#ifdef _WIN32
		    #error win32
		#endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  ac_cv_win32=no
else
  ac_cv_win32=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
$as_echo "$ac_cv_win32" >&6; }
	if test "$ac_cv_win32" != "yes"; then
	    as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
	fi




	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5
$as_echo_n "checking for working -municode linker flag... " >&6; }
if ${ac_cv_municode+:} false; then :

  $as_echo_n "(cached) " >&6
else

# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_link ()
{
  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  rm -f conftest.$ac_objext conftest$ac_exeext
  if { { ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
  (eval "$ac_link") 2>conftest.err
  ac_status=$?
  if test -s conftest.err; then
    grep -v '^ *+' conftest.err >conftest.er1
    cat conftest.er1 >&5
    mv -f conftest.er1 conftest.err
  fi
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; } && {
	 test -z "$ac_c_werror_flag" ||
	 test ! -s conftest.err
       } && test -s conftest$ac_exeext && {
	 test "$cross_compiling" = yes ||
	 test -x conftest$ac_exeext

       }; then :
  ac_retval=0
else
  $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1

fi
  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
  # interfere with the next link command; also delete a directory that is
  # left behind by Apple's compiler.  We do this before executing the actions.
  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  as_fn_set_status $ac_retval

} # ac_fn_c_try_link
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  ac_cv_municode=yes
else
  ac_cv_municode=no

fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_municode" >&5
$as_echo "$ac_cv_municode" >&6; }
	CFLAGS=$hold_cflags
	if test "$ac_cv_municode" = "yes" ; then
	    extra_ldflags="$extra_ldflags -municode"
	else
	    extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS"
	fi
























    fi





















































































    { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5
$as_echo_n "checking compiler flags... " >&6; }
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \$@"
	MAKE_STUB_LIB="\${STLIB_LD} \$@"
	POST_MAKE_LIB="\${RANLIB} \$@"
	MAKE_EXE="\${CC} -o \$@"
	LIBPREFIX="lib"

	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
$as_echo "using static flags" >&6; }
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }

	    # ad-hoc check to see if CC supports -shared.
	    if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
		as_fn_error $? "${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain." "$LINENO" 5
	    fi

	    runtime=
	    # Add SHLIB_LD_LIBS to the Make rule, not here.

	    EXESUFFIX=".exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\$@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \$@"
	CC_EXENAME="-o \$@"








|
|





|

|
|

|
|

















|
|
|
>
|
|
|







|






|
>

|
|
>

|
|
>

|
|



>
>
>


|
|
|
>
|
|
|






|






|







|






>
|

|
|


|
>

















|






|
>

|
|
>

|

|
>

|
|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|





|














|
|





|
|


















|




















|







4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650

    if test "$GCC" = "yes" && test "$CYGPATH" != "echo" ; then
	conftest=/tmp/conftest.rc
	echo "STRINGTABLE BEGIN" > $conftest
	echo "101 \"name\"" >> $conftest
	echo "END" >> $conftest

	{ 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=$?
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; } ; then
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
	else
	    { 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"
	{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#ifdef _WIN32
		    #error win32
		#endif

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  ac_cv_win32=no
else case e in #(
  e) ac_cv_win32=yes ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	 ;;
esac
fi
{ 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
	if test "$do64bit" != "arm64"; then
	    extra_cflags="$extra_cflags -DHAVE_CPUID=1"
	fi

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	{ 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 case e in #(
  e)
# 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.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\""
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
  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 :
  ac_retval=0
else case e in #(
  e) printf "%s\n" "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

	ac_retval=1 ;;
esac
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 (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  ac_cv_municode=yes
else case e in #(
  e) ac_cv_municode=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
	 ;;
esac
fi
{ 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
	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 case e in #(
  e) 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 case e in #(
  e) ac_cv_nolto=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	 ;;
esac
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
	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -finput-charset" >&5
printf %s "checking if the compiler understands -finput-charset... " >&6; }
if test ${tcl_cv_cc_input_charset+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8"
	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_cc_input_charset=yes
else case e in #(
  e) tcl_cv_cc_input_charset=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    CFLAGS=$hold_cflags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_input_charset" >&5
printf "%s\n" "$tcl_cv_cc_input_charset" >&6; }
	if test $tcl_cv_cc_input_charset = yes; then
	    extra_cflags="$extra_cflags -finput-charset=UTF-8"
	fi
    fi

    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--enable-auto-image-base"
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working --enable-auto-image-base" >&5
printf %s "checking for working --enable-auto-image-base... " >&6; }
if test ${ac_cv_enable_auto_image_base+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) 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_enable_auto_image_base=yes
else case e in #(
  e) ac_cv_enable_auto_image_base=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_auto_image_base" >&5
printf "%s\n" "$ac_cv_enable_auto_image_base" >&6; }
    CFLAGS=$hold_cflags
    if test "$ac_cv_enable_auto_image_base" == "yes" ; then
	extra_ldflags="$extra_ldflags -Wl,--enable-auto-image-base"
    fi

    { 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 -lwinspool"
	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
            { 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.exe"
	else
	    # dynamic
            { 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=".exe"
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \$@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\$@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \$@"
	CC_EXENAME="-o \$@"

4289
4290
4291
4292
4293
4294
4295
4296
4297





4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320

4321
4322
4323
4324

4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
	#LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}"
	LDFLAGS_CONSOLE="-mconsole ${extra_ldflags}"
	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"

	case "$do64bit" in
	    amd64|x64|yes)
		MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }





		;;
	    ia64)
		MACHINE="IA64"
		{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
		;;
	    *)
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		    #ifndef _WIN64
			#error 32-bit
		    #endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_win_64bit=yes
else
  tcl_win_64bit=no


fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
		if test "$tcl_win_64bit" = "yes" ; then
			do64bit=amd64
			MACHINE="AMD64"
			{ $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
$as_echo "using static flags" >&6; }
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX=".exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"







|
|
>
>
>
>
>



|
|










|






|
>

|
|
|
>

|

|
|
|
|






|
|





|
|







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
	#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
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
printf "%s\n" "   Using 64-bit $MACHINE mode" >&6; }
		;;
	    arm64|aarch64)
		MACHINE="ARM64"
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using ARM64 $MACHINE mode" >&5
printf "%s\n" "   Using ARM64 $MACHINE mode" >&6; }
		;;
	    ia64)
		MACHINE="IA64"
		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:    Using IA64 $MACHINE mode" >&5
printf "%s\n" "   Using IA64 $MACHINE mode" >&6; }
		;;
	    *)
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		    #ifndef _WIN64
			#error 32-bit
		    #endif

int
main (void)
{

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_win_64bit=yes
else case e in #(
  e) tcl_win_64bit=no
		 ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
		if test "$tcl_win_64bit" = "yes" ; then
		    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
            { 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.exe"
	else
	    # dynamic
            { 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=".exe"
	    case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    lflags="${lflags} -nodefaultlib:libucrt.lib"
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
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;



		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
$as_echo "   Using 64-bit $MACHINE mode" >&6; }
	fi

	LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[4-9]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;
	esac

	if test "$do64bit" != "no" ; then
	    RC="rc"
	    CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"
	    # Do not use -O2 for Win64 - this has proved buggy in code gen.
	    CFLAGS_OPTIMIZE="-nologo -O1 ${runtime}"
	    lflags="${lflags} -nologo -MACHINE:${MACHINE}"
	    LINKBIN="link"
	    # Avoid 'unresolved external symbol __security_cookie' errors.
	    # c.f. http://support.microsoft.com/?id=894573
	    LIBS="$LIBS bufferoverflowU.lib"
	else
	    RC="rc"
	    # -Od - no optimization
	    # -WX - warnings as errors
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi

	LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"

	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r







>
>
>




|
|















<
|
















|







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
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		arm64|aarch64)
		    MACHINE="ARM64"
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    { 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"
		    ;;
		*)
		    ;;
	esac

	if test "$do64bit" != "no" ; then
	    RC="rc"
	    CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"

	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo -MACHINE:${MACHINE}"
	    LINKBIN="link"
	    # Avoid 'unresolved external symbol __security_cookie' errors.
	    # c.f. http://support.microsoft.com/?id=894573
	    LIBS="$LIBS bufferoverflowU.lib"
	else
	    RC="rc"
	    # -Od - no optimization
	    # -WX - warnings as errors
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi

	LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib winspool.lib"

	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458

4459
4460
4461

4462
4463












































4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483

4484
4485
4486

4487
4488
4489

4490
4491
4492

4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510

4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530

4531
4532
4533

4534
4535
4536

4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592

4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606

4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623

4624
4625
4626

4627
4628
4629

4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645

























4646
4647
4648
4649
4650
4651
4652

4653
4654
4655

4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667

4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682

4683
4684
4685

4686
4687
4688

4689
4690
4691
4692
4693
4694
4695
4696
4697
4698


4699
4700
4701
4702

4703





4704














4705
4706






4707








4708


4709





4710
4711



4712
4713
4714

4715





4716















4717
4718









4719








4720






4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733

4734
4735
4736

4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791

































4792
















































































































































































































































4793
4794
4795
4796

4797
4798
4799

4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818

4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855

4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871

4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883




































































































































































4884









4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903



4904

4905











4906
4907
4908
4909
4910




4911
4912
4913
4914



4915

4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954

4955
4956
4957
4958
4959
4960
4961
	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then
	$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h

    fi

    if test "${GCC}" = "yes" ; then
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
$as_echo_n "checking for SEH support in compiler... " >&6; }
if ${tcl_cv_seh+:} false; then :

  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :

  tcl_cv_seh=no
else












































  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }

_ACEOF
if ac_fn_c_try_run "$LINENO"; then :

  tcl_cv_seh=yes
else
  tcl_cv_seh=no

fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext

fi



fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
$as_echo "$tcl_cv_seh" >&6; }
	if test "$tcl_cv_seh" = "no" ; then

$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h

	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
if ${tcl_cv_eh_disposition+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN

int
main ()
{

		EXCEPTION_DISPOSITION x;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_eh_disposition=yes
else
  tcl_cv_eh_disposition=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
$as_echo "$tcl_cv_eh_disposition" >&6; }
	if test "$tcl_cv_eh_disposition" = "no" ; then

$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h

	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
if ${tcl_cv_winnt_ignore_void+:} false; then :
  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN

int
main ()
{

		CHAR c;
		SHORT s;
		LONG l;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  tcl_cv_winnt_ignore_void=yes
else
  tcl_cv_winnt_ignore_void=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
$as_echo "$tcl_cv_winnt_ignore_void" >&6; }
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then

$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h

	fi

	ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
if test "x$ac_cv_header_stdbool_h" = xyes; then :


$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h

fi



	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
$as_echo_n "checking for cast to union support... " >&6; }
if ${tcl_cv_cast_to_union+:} false; then :

  $as_echo_n "(cached) " >&6
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
{

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  tcl_cv_cast_to_union=yes
else
  tcl_cv_cast_to_union=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext


fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
$as_echo "$tcl_cv_cast_to_union" >&6; }
	if test "$tcl_cv_cast_to_union" = "yes"; then

$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h

	fi
    fi

    # DL_LIBS is empty, but then we match the Unix version































#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
if test "x$ac_cv_header_errno_h" = xyes; then :


else
  MAN2TCLFLAGS="-DNO_ERRNO_H"

fi




#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking availability of _strtoi64" >&5
$as_echo_n "checking availability of _strtoi64... " >&6; }
if ${tcl_cv_strtoi64+:} false; then :

  $as_echo_n "(cached) " >&6
else

    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
int
main ()
{
_strtoi64(0,0,0)
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :

  tcl_cv_strtoi64=yes
else
  tcl_cv_strtoi64=no

fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtoi64" >&5
$as_echo "$tcl_cv_strtoi64" >&6; }
if test $tcl_cv_strtoi64 = no; then

$as_echo "#define NO_STRTOI64 1" >>confdefs.h

fi

#--------------------------------------------------------------------


# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------

ac_fn_c_check_header_compile "$LINENO" "uxtheme.h" "ac_cv_header_uxtheme_h" "#include <windows.h>

"





if test "x$ac_cv_header_uxtheme_h" = xyes; then :














  $as_echo "#define HAVE_UXTHEME_H 1" >>confdefs.h







else








  { $as_echo "$as_me:${as_lineno-$LINENO}: xpnative theme will be unavailable" >&5


$as_echo "$as_me: xpnative theme will be unavailable" >&6;}





fi





ac_fn_c_check_header_compile "$LINENO" "vssym32.h" "ac_cv_header_vssym32_h" "#include <windows.h>
#include <uxtheme.h>

"





if test "x$ac_cv_header_vssym32_h" = xyes; then :















  $as_echo "#define HAVE_VSSYM32_H 1" >>confdefs.h










fi

















#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------


    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
$as_echo_n "checking for build with symbols... " >&6; }
    # Check whether --enable-symbols was given.
if test "${enable_symbols+set}" = set; then :

  enableval=$enable_symbols; tcl_ok=$enableval
else
  tcl_ok=no

fi

# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'

$as_echo "#define NDEBUG 1" >>confdefs.h

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }

	$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h

    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	if test "$tcl_ok" = "yes"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
$as_echo "yes (standard debugging)" >&6; }
	fi
    fi



    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then

$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h

    fi

    if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then

$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h


$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h

    fi

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5
$as_echo "enabled symbols mem compile debugging" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
$as_echo "enabled $tcl_ok debugging" >&6; }
	fi
    fi


#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------



















































































































































































































































































    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to embed manifest" >&5
$as_echo_n "checking whether to embed manifest... " >&6; }
    # Check whether --enable-embedded-manifest was given.
if test "${enable_embedded_manifest+set}" = set; then :

  enableval=$enable_embedded_manifest; embed_ok=$enableval
else
  embed_ok=yes

fi


    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
       -a "$GCC" != "yes" ; then
	# Add the magic to embed the manifest into the dll/exe
	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

#if defined(_MSC_VER) && _MSC_VER >= 1400
print("manifest needed")
#endif

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "manifest needed" >/dev/null 2>&1; then :


	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
	# Could add 'if test -f' check, but manifest should be created
	# in this compiler case
	# Add in a manifest argument that may be specified
	# XXX Needs improvement so that the test for existence accounts
	# XXX for a provided (known) manifest
	VC_MANIFEST_EMBED_DLL="if test -f \[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*

    fi
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
$as_echo "$result" >&6; }





    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh in Tcl build directory" >&5
$as_echo_n "checking for tclsh in Tcl build directory... " >&6; }
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
$as_echo "$BUILD_TCLSH" >&6; }



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
$as_echo_n "checking for tclsh... " >&6; }

    if ${ac_cv_path_tclsh+:} false; then :

  $as_echo_n "(cached) " >&6
else

	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/tclsh[8-9]*.exe 2> /dev/null` \
		    `ls -r $dir/tclsh* 2> /dev/null` ; do
		if test x"$ac_cv_path_tclsh" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_tclsh=$j
			break
		    fi
		fi
	    done
	done


fi


    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG="$ac_cv_path_tclsh"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
$as_echo "$TCLSH_PROG" >&6; }
    else
	# It is not an error if an installed version of Tcl can't be located.
	TCLSH_PROG=""
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
$as_echo "No tclsh found on PATH" >&6; }




































































































































































    fi












#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

#--------------------------------------------------------------------
# Perform final evaluations of variables with possible substitutions.
#--------------------------------------------------------------------

TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""




eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"

eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}"












eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}"
# FIXME: All of this var junk needs to be done in tcl.m4 !!!!
# I left out the other vars that also need to get defined here.
# we also need to double check about spaces in path names




eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
TK_BUILD_LIB_SPEC="-L`pwd` ${TK_LIB_FLAG}"




eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""

TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}"

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"

eval "DLLSUFFIX=${DLLSUFFIX}"
eval "LIBPREFIX=${LIBPREFIX}"
eval "LIBSUFFIX=${LIBSUFFIX}"
eval "EXESUFFIX=${EXESUFFIX}"

CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX}
CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX}
CFG_TK_EXPORT_FILE_SUFFIX=${TK_EXPORT_FILE_SUFFIX}

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    TK_RES=""
else
    RC_DEFINES=""
    TK_RES='tk.$(RES)'
fi

# The wish.exe.manifest requires these
# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs
# the release level, and must account for interim release versioning
case "$TK_PATCH_LEVEL" in
     *a*) TK_RELEASE_LEVEL=0 ;;
     *b*) TK_RELEASE_LEVEL=1 ;;
     *)   TK_RELEASE_LEVEL=2 ;;
esac
TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.`"

# X86|AMD64|IA64 for manifest















|




|
|
|
>
|
|
|
>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


















|
>

|
|
>


|
>


|
>

|
|


|









|
|
|
>
|
|
|







|








|
>

|
|
>

|
|
>

|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<

<
<
<
<
<
<
<
<
|
<

<
<
<
<
<
<
<
<
<
|
|
>

|


<






|
|
|
>
|
|
|



|









|
>

|
|
>

|
|
>

|
|


|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|
>

|
|
>

<







|
|
|
>
|
|
|




|






|
>

|
|
>

|
|
>

|
|


|



<
>
>
|
|

<
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>


>
>
>

|
<
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>

>
>
>
>
>
>









|
|

|
>

|
|
>







|

|
|

|





|
|







|





|


|





|
|

|
|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|
>

|
|
>


















|
>















|


|
|





|
|
|
|
|



|
|

|
>
|
|
|












|
>





|
|



|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>















<

|

>
>
>

>
|
>
>
>
>
>
>
>
>
>
>
>

|



>
>
>
>
|

|

>
>
>
|
>
|



|








<






|


















>







4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
























4979
4980



4981








4982

4983









4984
4985
4986
4987
4988
4989
4990

4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080

5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124

5125
5126
5127
5128
5129

5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184

5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866

5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917

5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
	else
	    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
	    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
	fi
    fi

    if test "$do64bit" != "no" ; then
	printf "%s\n" "#define TCL_CFG_DO64BIT 1" >>confdefs.h

    fi

    if test "${GCC}" = "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 case e in #(
  e) if test "$cross_compiling" = yes
then :
  tcl_cv_seh=no
else case e in #(
  e)
# 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 case e in #(
  e) 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 ;;
esac
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 :
  tcl_cv_seh=yes
else case e in #(
  e) tcl_cv_seh=no ;;
esac
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
esac
fi

	 ;;
esac
fi
{ 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

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.
	#
	{ 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 case e in #(
  e) 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 (void)
{

		EXCEPTION_DISPOSITION x;

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
  tcl_cv_eh_disposition=yes
else case e in #(
  e) tcl_cv_eh_disposition=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	 ;;
esac
fi
{ 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

























printf "%s\n" "#define EXCEPTION_DISPOSITION int" >>confdefs.h












	fi











	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 :

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.

	{ 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 case e in #(
  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
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 :
  tcl_cv_cast_to_union=yes
else case e in #(
  e) tcl_cv_cast_to_union=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	 ;;
esac
fi
{ 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

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_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
if test "x$ac_cv_header_errno_h" = xyes
then :

else case e in #(
  e) MAN2TCLFLAGS="-DNO_ERRNO_H" ;;
esac
fi




#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

{ 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 case e in #(
  e)
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
#include <stdlib.h>
int
main (void)
{
_strtoi64(0,0,0)
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_strtoi64=yes
else case e in #(
  e) tcl_cv_strtoi64=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext ;;
esac
fi
{ 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

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 case e in #(
  e)
    { 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 case e in #(
  e)
    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 case e in #(
  e) tcl_ok=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done ;;
esac
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
 ;;
esac
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 case e in #(
  e)
    { 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 case e in #(
  e)
    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 case e in #(
  e) tcl_ok=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
	    test "$tcl_ok" = yes && break; fi
    done ;;
esac
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
 ;;
esac
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.
#--------------------------------------------------------------------


    { 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+y}
then :
  enableval=$enable_symbols; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=no ;;
esac
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)'

printf "%s\n" "#define NDEBUG 1" >>confdefs.h

	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }

	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
	    { 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

printf "%s\n" "#define TCL_MEM_DEBUG 1" >>confdefs.h

    fi

    if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then

printf "%s\n" "#define TCL_COMPILE_DEBUG 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
	    { 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
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
printf "%s\n" "enabled $tcl_ok debugging" >&6; }
	fi
    fi


#--------------------------------------------------------------------
# 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 case e in #(
  e)     # 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 case e in #(
  e) # Broken: fails on valid input.
continue ;;
esac
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 case e in #(
  e) # Passes both tests.
ac_preproc_ok=:
break ;;
esac
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
   ;;
esac
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 case e in #(
  e) # Broken: fails on valid input.
continue ;;
esac
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 case e in #(
  e) # Passes both tests.
ac_preproc_ok=:
break ;;
esac
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 case e in #(
  e) { { 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; } ;;
esac
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 egrep -e" >&5
printf %s "checking for egrep -e... " >&6; }
if test ${ac_cv_path_EGREP_TRADITIONAL+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) if test -z "$EGREP_TRADITIONAL"; then
  ac_path_EGREP_TRADITIONAL_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_EGREP_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue
# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found.
  # Check for GNU $ac_path_EGREP_TRADITIONAL
case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #(
*GNU*)
  ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_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_TRADITIONAL' >> "conftest.nl"
    "$ac_path_EGREP_TRADITIONAL" -E 'EGR(EP|AC)_TRADITIONAL$' < "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_TRADITIONAL_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL"
      ac_path_EGREP_TRADITIONAL_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_TRADITIONAL_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP_TRADITIONAL"; then
    :
  fi
else
  ac_cv_path_EGREP_TRADITIONAL=$EGREP_TRADITIONAL
fi

    if test "$ac_cv_path_EGREP_TRADITIONAL"
then :
  ac_cv_path_EGREP_TRADITIONAL="$ac_cv_path_EGREP_TRADITIONAL -E"
else case e in #(
  e) if test -z "$EGREP_TRADITIONAL"; then
  ac_path_EGREP_TRADITIONAL_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_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext"
      as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue
# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found.
  # Check for GNU $ac_path_EGREP_TRADITIONAL
case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #(
*GNU*)
  ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_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_TRADITIONAL' >> "conftest.nl"
    "$ac_path_EGREP_TRADITIONAL" 'EGR(EP|AC)_TRADITIONAL$' < "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_TRADITIONAL_max-0}; then
      # Best one so far, save it but keep looking for a better one
      ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL"
      ac_path_EGREP_TRADITIONAL_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_TRADITIONAL_found && break 3
    done
  done
  done
IFS=$as_save_IFS
  if test -z "$ac_cv_path_EGREP_TRADITIONAL"; 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_TRADITIONAL=$EGREP_TRADITIONAL
fi
 ;;
esac
fi ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP_TRADITIONAL" >&5
printf "%s\n" "$ac_cv_path_EGREP_TRADITIONAL" >&6; }
 EGREP_TRADITIONAL=$ac_cv_path_EGREP_TRADITIONAL


    { 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+y}
then :
  enableval=$enable_embedded_manifest; embed_ok=$enableval
else case e in #(
  e) embed_ok=yes ;;
esac
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_TRADITIONAL "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 -rf conftest*

    fi
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $result" >&5
printf "%s\n" "$result" >&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}\${EXESUFFIX}
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BUILD_TCLSH" >&5
printf "%s\n" "$BUILD_TCLSH" >&6; }



    { 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 case e in #(
  e)
	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
     ;;
esac
fi


    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG="$ac_cv_path_tclsh"
	{ 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=""
	{ 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



#--------------------------------------------------------------------
#	Zipfs support - Tip 430
#--------------------------------------------------------------------
# Check whether --enable-zipfs was given.
if test ${enable_zipfs+y}
then :
  enableval=$enable_zipfs; tcl_ok=$enableval
else case e in #(
  e) tcl_ok=yes ;;
esac
fi

if test "$tcl_ok" = "yes" ; then
    #
    # Find a native compiler
    #
    # Put a plausible default for CC_FOR_BUILD in Makefile.
if test -z "$CC_FOR_BUILD"; then
  if test "x$cross_compiling" = "xno"; then
    CC_FOR_BUILD='$(CC)'
  else
    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5
printf %s "checking for gcc... " >&6; }
    if test ${ac_cv_path_cc+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
	search_path=`echo ${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/gcc 2> /dev/null` \
		    `ls -r $dir/gcc 2> /dev/null` ; do
		if test x"$ac_cv_path_cc" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_cc=$j
			break
		    fi
		fi
	    done
	done
     ;;
esac
fi

  fi
fi

# Also set EXEEXT_FOR_BUILD.
if test "x$cross_compiling" = "xno"; then
  EXEEXT_FOR_BUILD='$(EXEEXT)'
  OBJEXT_FOR_BUILD='$(OBJEXT)'
else
  OBJEXT_FOR_BUILD='.no'
  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5
printf %s "checking for build system executable suffix... " >&6; }
if test ${bfd_cv_build_exeext+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e) rm -f conftest*
     echo 'int main () { return 0; }' > conftest.c
     bfd_cv_build_exeext=
     ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
     for file in conftest.*; do
       case $file in
       *.c | *.o | *.obj | *.ilk | *.pdb) ;;
       *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
     rm -f conftest*
     test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5
printf "%s\n" "$bfd_cv_build_exeext" >&6; }
  EXEEXT_FOR_BUILD=""
  test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
fi

    #
    # Find a native zip implementation
    #

    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    ZIP_INSTALL_OBJS=""

    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zip" >&5
printf %s "checking for zip... " >&6; }
    if test ${ac_cv_path_zip+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
    search_path=`echo ${PATH} | sed -e 's/:/ /g'`
    for dir in $search_path ; do
        for j in `ls -r $dir/zip 2> /dev/null` \
            `ls -r $dir/zip 2> /dev/null` ; do
        if test x"$ac_cv_path_zip" = x ; then
            if test -f "$j" ; then
            ac_cv_path_zip=$j
            break
            fi
        fi
        done
    done
     ;;
esac
fi

    if test -f "$ac_cv_path_zip" ; then
        ZIP_PROG="$ac_cv_path_zip"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5
printf "%s\n" "$ZIP_PROG" >&6; }
        ZIP_PROG_OPTIONS="-rq"
        ZIP_PROG_VFSSEARCH="*"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5
printf "%s\n" "Found INFO Zip in environment" >&6; }
        # Use standard arguments for zip
    else
        # It is not an error if an installed version of Zip can't be located.
        # We can use the locally distributed minizip instead
        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
        ZIP_PROG_OPTIONS="-o -r"
        ZIP_PROG_VFSSEARCH="*"
        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5
printf "%s\n" "No zip found on PATH building minizip" >&6; }
    fi





	ZIPFS_BUILD=1
	TK_ZIP_FILE=libtk${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_PATCH_LEVEL}.zip
else
	ZIPFS_BUILD=0
	TCL_ZIP_FILE=
fi
# Do checking message here to not mess up interleaved configure output
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5
printf %s "checking for building with zipfs... " >&6; }
if test "${ZIPFS_BUILD}" = 1; then
    if test "${SHARED_BUILD}" = 0; then
       ZIPFS_BUILD=2;

printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h

       INSTALL_LIBRARIES=install-libraries-zipfs-static
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
     else

printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h
\
       INSTALL_LIBRARIES=install-libraries-zipfs-shared
       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
    fi
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
INSTALL_LIBRARIES=install-libraries
INSTALL_MSGS=install-msgs
fi






#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

#--------------------------------------------------------------------
# Perform final evaluations of variables with possible substitutions.
#--------------------------------------------------------------------

TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"


eval "TK_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(pwd)`\""

eval "TK_DLL_FILE_TCL8=tk$VER${DLLSUFFIX}"
eval "TK_DLL_FILE_TCL9=tcl9tk$VER${DLLSUFFIX}"
if test ${TCL_MAJOR_VERSION} = 8 ; then
eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
 eval "TK_LIB_FILE=${LIBPREFIX}tk${VER}${LIBSUFFIX}"
else
 eval "TK_LIB_FILE=${LIBPREFIX}tk${VER}${DLLSUFFIX}.a"
fi
else
eval "TK_DLL_FILE=tcl9tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
 eval "TK_LIB_FILE=${LIBPREFIX}tcl9tk${VER}${LIBSUFFIX}"
else
 eval "TK_LIB_FILE=${LIBPREFIX}tcl9tk${VER}${DLLSUFFIX}.a"
fi
fi

eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${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
TK_LIB_FLAG="-l"
if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
    TK_LIB_FLAG="${TK_LIB_FLAG}tcl9"
fi
eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
eval "TK_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_LIB_FLAG}\""

if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
    eval "TK_STUB_LIB_FLAG=\"-ltkstub${LIBFLAGSUFFIX}\""
else
    eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""
fi
eval "TK_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_STUB_LIB_FLAG}\""

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
eval "TK_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(pwd)`/${TK_STUB_LIB_FILE}\""

eval "DLLSUFFIX=${DLLSUFFIX}"
eval "LIBPREFIX=${LIBPREFIX}"
eval "LIBSUFFIX=${LIBSUFFIX}"
eval "EXESUFFIX=${EXESUFFIX}"

CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX}
CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX}


#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0; then
    RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    TK_RES=""
else
    RC_DEFINES=""
    TK_RES='tk.$(RES)'
fi

# The wish.exe.manifest requires these
# TK_WIN_VERSION is the 4 dotted pair Windows version format which needs
# the release level, and must account for interim release versioning
case "$TK_PATCH_LEVEL" in
     *a*) TK_RELEASE_LEVEL=0 ;;
     *b*) TK_RELEASE_LEVEL=1 ;;
     *)   TK_RELEASE_LEVEL=2 ;;
esac
TK_WIN_VERSION="$TK_VERSION.$TK_RELEASE_LEVEL.`echo $TK_PATCH_LEVEL | tr -d ab.`"

# X86|AMD64|IA64 for manifest








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
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac
  done

  (set) 2>&1 |
    case $as_nl`(ac_space=' '; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      # `set' does not quote correctly, so add quotes: double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \.
      sed -n \
	"s/'/'\\\\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;; #(
    *)
      # `set' quotes correctly as required by POSIX, so do not add quotes.
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     t end
     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     :end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
  if test -w "$cache_file"; then
    if test "x$cache_file" != "x/dev/null"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
      if test ! -f "$cache_file" || test -h "$cache_file"; then
	cat confcache >"$cache_file"
      else
        case $cache_file in #(
        */* | ?:*)
	  mv -f confcache "$cache_file"$$ &&
	  mv -f "$cache_file"$$ "$cache_file" ;; #(
        *)
	  mv -f confcache "$cache_file" ;;
	esac
      fi
    fi
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
  fi
fi
rm -f confcache

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'







|
|















|
|












|






|









|






|
|













|
|







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
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# 'ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* 'ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { 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
  done

  (set) 2>&1 |
    case $as_nl`(ac_space=' '; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      # 'set' does not quote correctly, so add quotes: double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \.
      sed -n \
	"s/'/'\\\\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;; #(
    *)
      # 'set' quotes correctly as required by POSIX, so do not add quotes.
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+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
      { 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
    { 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}'
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
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
t quote
b any
:quote
s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
s/\[/\\&/g
s/\]/\\&/g
s/\$/$$/g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
}
'
DEFS=`sed -n "$ac_script" confdefs.h`


ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
  #    will be set to the directory where LIBOBJS objects are built.
  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs



: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.







|
<
<



















|















|
|







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
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
t quote
b any
:quote
s/[][	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g


s/\$/$$/g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
}
'
DEFS=`sed -n "$ac_script" confdefs.h`


ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`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"
{ 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.
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
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :

  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;

esac
fi










as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '


    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi

  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'









fi





# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS

  test -z "$as_dir" && as_dir=.



    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.







|
>






|
|




>




>
>
>
>
>
>
>
>



<
<
<
<
<
<
<
<
|
|
<
|
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
>
>
|
<
<
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>


|








<
<
<
<
<
<
<








>
|
>
>
>
|





|





|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












|

|







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
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
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 case e in #(
  e) case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac ;;
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








IFS=" ""	$as_nl"


PS1='$ '
PS2='> '






PS4='+ '








# Ensure predictable behavior from utilities with locale-dependent output.
LC_ALL=C
export LC_ALL


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 ${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









# 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 #(((
    '') 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
  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi























# 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
    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  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.
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
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset

# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :

  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }

fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :

  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }

fi # as_fn_arith


if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else







>






|
>




|
|


|
>







|
>




|
|


|
>







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
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset

# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else case e in #(
  e) as_fn_append ()
  {
    eval $1=\$$1\$2
  } ;;
esac
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else case e in #(
  e) as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  } ;;
esac
fi # as_fn_arith


if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q







|







6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
printf "%s\n" X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
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
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits





ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac







rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi







>
>
>
>












>
>
>
>
>
>












|
|
|







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
# 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
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
    # In both cases, we have to default to 'cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|








|







6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
  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=`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 ||
printf "%s\n" X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
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
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"


# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"



exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@








|
>


|
>














|
|







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
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated

# Sed expression to map a string onto a valid variable name.
as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
as_tr_sh="eval sed '$as_sed_sh'" # deprecated


exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by tk $as_me 9.0, which was
generated by GNU Autoconf 2.72.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@

5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
# Files that config.status was made for.
config_files="$ac_config_files"

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration.  Unless the files
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit







|







6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
# Files that config.status was made for.
config_files="$ac_config_files"

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
'$as_me' instantiates files and other configuration actions
from templates according to the current configuration.  Unless the files
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit
5623
5624
5625
5626
5627
5628
5629


5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644

Configuration files:
$config_files

Report bugs to the package provider."

_ACEOF


cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
config.status
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
test -n "\$AWK" || AWK=awk
_ACEOF







>
>

|

|
|


|







6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629

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='$ac_cs_config_escaped'
ac_cs_version="\\
tk config.status 9.0
configured by $0, generated by GNU Autoconf 2.72,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2023 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
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
  esac

  case $ac_option in
  # Handling of the options.
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
    $as_echo "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    $as_echo "$ac_cs_config"; exit ;;
  --debug | --debu | --deb | --de | --d | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    case $ac_optarg in
    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    '') as_fn_error $? "missing file argument" ;;
    esac
    as_fn_append CONFIG_FILES " '$ac_optarg'"
    ac_need_defaults=false;;
  --he | --h |  --help | --hel | -h )
    $as_echo "$ac_cs_usage"; exit ;;
  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.
  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;

  *) as_fn_append ac_config_targets " $1"
     ac_need_defaults=false ;;

  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
  CONFIG_SHELL='$SHELL'
  export CONFIG_SHELL
  exec "\$@"
fi

_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
exec 5>>config.log
{
  echo
  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
  $as_echo "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1

# Handling of arguments.
for ac_config_target in $ac_config_targets
do
  case $ac_config_target in
    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
    "tkConfig.sh") CONFIG_FILES="$CONFIG_FILES tkConfig.sh" ;;
    "wish.exe.manifest") CONFIG_FILES="$CONFIG_FILES wish.exe.manifest" ;;

  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
  esac
done


# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used.  Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
  tmp= ac_tmp=
  trap 'exit_status=$?
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0







|

|





|





|





|
|




















|













|
















|









|







|







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
  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 )
    printf "%s\n" "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    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=`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 )
    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." ;;

  *) as_fn_append ac_config_targets " $1"
     ac_need_defaults=false ;;

  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \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
  printf "%s\n" "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1

# Handling of arguments.
for ac_config_target in $ac_config_targets
do
  case $ac_config_target in
    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
    "tkConfig.sh") CONFIG_FILES="$CONFIG_FILES tkConfig.sh" ;;
    "wish.exe.manifest") CONFIG_FILES="$CONFIG_FILES wish.exe.manifest" ;;

  *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;;
  esac
done


# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used.  Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
  test ${CONFIG_FILES+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:
# after its creation but before its name has been assigned to '$tmp'.
$debug ||
{
  tmp= ac_tmp=
  trap 'exit_status=$?
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp

# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then


ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.







|







6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp

# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with './config.status config.h'.
if test -n "$CONFIG_FILES"; then


ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
for ac_tag
do
  case $ac_tag in
  :[FHLC]) ac_mode=$ac_tag; continue;;
  esac
  case $ac_mode$ac_tag in
  :[FHL]*:*);;
  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
  :[FH]-) ac_tag=-:-;;
  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
  esac
  ac_save_IFS=$IFS
  IFS=:
  set x $ac_tag
  IFS=$ac_save_IFS







|







6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
for ac_tag
do
  case $ac_tag in
  :[FHLC]) ac_mode=$ac_tag; continue;;
  esac
  case $ac_mode$ac_tag in
  :[FHL]*:*);;
  :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;;
  :[FH]-) ac_tag=-:-;;
  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
  esac
  ac_save_IFS=$IFS
  IFS=:
  set x $ac_tag
  IFS=$ac_save_IFS
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
    ac_file_inputs=
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
      *) # Look for the file first in the build tree, then in the source tree
	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
	 # because $ac_f cannot contain `:'.
	 test -f "$ac_f" ||
	   case $ac_f in
	   [\\/$]*) false;;
	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
	   esac ||
	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
      esac
      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
      as_fn_append ac_file_inputs " '$ac_f'"
    done

    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
    configure_input='Generated from '`
	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
    fi
    # Neutralize special characters interpreted by sed in replacement strings.
    case $configure_input in #(
    *\&* | *\|* | *\\* )
       ac_sed_conf_input=`$as_echo "$configure_input" |
       sed 's/[\\\\&|]/\\\\&/g'`;; #(
    *) ac_sed_conf_input=$configure_input;;
    esac

    case $ac_tag in
    *:-:* | *:-) cat >"$ac_tmp/stdin" \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
    esac
    ;;
  esac

  ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q







|





|

|



|



|



|
|




|
















|







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
    ac_file_inputs=
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
      *) # Look for the file first in the build tree, then in the source tree
	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
	 # because $ac_f cannot contain ':'.
	 test -f "$ac_f" ||
	   case $ac_f in
	   [\\/$]*) false;;
	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
	   esac ||
	   as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;;
      esac
      case $ac_f in *\'*) ac_f=`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 '`
	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { 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=`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 ||
printf "%s\n" X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
	  s/.*/./; q'`
  as_dir="$ac_dir"; as_fn_mkdir_p
  ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix







|

|







7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
	  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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  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
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
/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  ac_datarootdir_hack='
  s&@datadir@&$datadir&g
  s&@docdir@&$docdir&g
  s&@infodir@&$infodir&g
  s&@localedir@&$localedir&g
  s&@mandir@&$mandir&g
  s&\\\${datarootdir}&$datarootdir&g' ;;
esac
_ACEOF

# Neutralize VPATH when `$srcdir' = `.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1







|
|












|







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
/@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@*)
  { 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
  s&@mandir@&$mandir&g
  s&\\\${datarootdir}&$datarootdir&g' ;;
esac
_ACEOF

# Neutralize VPATH when '$srcdir' = '.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
      "$ac_tmp/out"`; test -z "$ac_out"; } &&
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&2;}

  rm -f "$ac_tmp/stdin"
  case $ac_file in
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \







|

|







7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
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"; } &&
  { 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
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 \
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195

  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi










|
|



>
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
  $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
  { 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
15
16
17
18
19
20
21
22
23
24
#! /bin/bash -norc
# This file is an input file used by the GNU "autoconf" program to
# generate the file "configure", which is run during Tk installation
# to configure the system for the local environment.


AC_INIT(../generic/tk.h)
AC_PREREQ(2.69)

# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=8.7
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then





>
|
|






|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#! /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],[9.0])
AC_CONFIG_SRCDIR([../generic/tk.h])
AC_PREREQ([2.69])

# The following define is needed when building with Cygwin since newer
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
    CFLAGS=""
fi

AC_PROG_CC
AC_C_INLINE
AC_HEADER_STDC

AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib)
AC_CHECK_TOOL(RC, windres)

#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.







|







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_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.
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97




98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118












119
120
121

122
123








124

125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144














































145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161



162

163











164
165
166
167
168




169
170
171
172



173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# Locate and source the tclConfig.sh file.
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG($TK_PATCH_LEVEL)
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then
    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better.])
fi
if test "${TCL_MINOR_VERSION}" -lt 6; then
    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.6+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.6 or better.])
fi
fi

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS





#--------------------------------------------------------------------
# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------

AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
AC_SUBST(MAN2TCLFLAGS)

#-------------------------------------------
#     Check for _strtoi64
#-------------------------------------------

AC_CACHE_CHECK([availability of _strtoi64], tcl_cv_strtoi64, [
    AC_TRY_LINK([#include <stdlib.h>],
	    [_strtoi64(0,0,0)],
	    tcl_cv_strtoi64=yes, tcl_cv_strtoi64=no)])
if test $tcl_cv_strtoi64 = no; then
    AC_DEFINE(NO_STRTOI64, 1, [Is _strtoi64 function available?])
fi

#--------------------------------------------------------------------












# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------


AC_CHECK_HEADER([uxtheme.h], [AC_DEFINE(HAVE_UXTHEME_H)],
	[AC_MSG_NOTICE([xpnative theme will be unavailable])],








	[#include <windows.h>])

AC_CHECK_HEADER([vssym32.h], [AC_DEFINE(HAVE_VSSYM32_H)], [],
	[#include <windows.h>

#include <uxtheme.h>])

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------

SC_ENABLE_SYMBOLS

#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------

SC_EMBED_MANIFEST(wish.exe.manifest)

SC_BUILD_TCLSH
SC_PROG_TCLSH















































#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

#--------------------------------------------------------------------
# Perform final evaluations of variables with possible substitutions.
#--------------------------------------------------------------------

TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TK_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; pwd`\""




eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"

eval "TK_LIB_FILE=${LIBPREFIX}tk$VER${LIBSUFFIX}"












eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${VER}${LIBSUFFIX}"
# FIXME: All of this var junk needs to be done in tcl.m4 !!!!
# I left out the other vars that also need to get defined here.
# we also need to double check about spaces in path names




eval "TK_LIB_FLAG=\"-ltk${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
TK_BUILD_LIB_SPEC="-L`pwd` ${TK_LIB_FLAG}"




eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""

TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}"

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
TK_BUILD_STUB_LIB_PATH="`pwd`/${TK_STUB_LIB_FILE}"

eval "DLLSUFFIX=${DLLSUFFIX}"
eval "LIBPREFIX=${LIBPREFIX}"
eval "LIBSUFFIX=${LIBSUFFIX}"
eval "EXESUFFIX=${EXESUFFIX}"

CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX}
CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX}
CFG_TK_EXPORT_FILE_SUFFIX=${TK_EXPORT_FILE_SUFFIX}

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0 -o "$TCL_NEEDS_EXP_FILE" = 0; then
    RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    TK_RES=""
else
    RC_DEFINES=""
    TK_RES='tk.$(RES)'
fi








<
<
<
<
<
|

|
|










>
>
>
>













|
|
<




<
>
>
>
>
>
>
>
>
>
>
>
>
|
<
|
>
|
|
>
>
>
>
>
>
>
>
|
>
|
|
>
|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













<

|

>
>
>

>
|
>
>
>
>
>
>
>
>
>
>
>

|



>
>
>
>
|

|

>
>
>
|
>
|



|








<






|







73
74
75
76
77
78
79





80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
# Locate and source the tclConfig.sh file.
#--------------------------------------------------------------------

SC_PATH_TCLCONFIG($TK_PATCH_LEVEL)
SC_LOAD_TCLCONFIG

if test "${TCL_MAJOR_VERSION}" -lt 9 ; then





if test "${TCL_MINOR_VERSION}" -lt 7; then
    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl 8.7+.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl 8.7 or better.])
fi
fi

#--------------------------------------------------------------------
# The statements below define a collection of compile flags.  This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------

SC_CONFIG_CFLAGS

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_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]],
    [[_strtoi64(0,0,0)]])],[tcl_cv_strtoi64=yes],[tcl_cv_strtoi64=no])])

if test $tcl_cv_strtoi64 = no; then
    AC_DEFINE(NO_STRTOI64, 1, [Is _strtoi64 function available?])
fi


AC_CHECK_TYPE([intptr_t], [
    AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
    for tcl_cv_intptr_t in "int" "long" "__int64" none; do
	if test "$tcl_cv_intptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_intptr_t" != none; then
	AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer
	   type wide enough to hold a pointer.])

    fi
])
AC_CHECK_TYPE([uintptr_t], [
    AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [
    for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned __int64" \
	    none; do
	if test "$tcl_cv_uintptr_t" != none; then
	    AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
		    [[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])],
		[tcl_ok=yes], [tcl_ok=no])
	    test "$tcl_ok" = yes && break; fi
    done])
    if test "$tcl_cv_uintptr_t" != none; then
	AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer
	   type wide enough to hold a pointer.])
    fi
])

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------

SC_ENABLE_SYMBOLS

#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------

SC_EMBED_MANIFEST(wish.exe.manifest)

SC_BUILD_TCLSH
SC_PROG_TCLSH

#--------------------------------------------------------------------
#	Zipfs support - Tip 430
#--------------------------------------------------------------------
AC_ARG_ENABLE(zipfs,
    AS_HELP_STRING([--enable-zipfs],
	[build with Zipfs support (default: on)]),
    [tcl_ok=$enableval], [tcl_ok=yes])
if test "$tcl_ok" = "yes" ; then
    #
    # Find a native compiler
    #
    AX_CC_FOR_BUILD
    #
    # Find a native zip implementation
    #
    SC_ZIPFS_SUPPORT
	ZIPFS_BUILD=1
	TK_ZIP_FILE=libtk${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_PATCH_LEVEL}.zip
else
	ZIPFS_BUILD=0
	TCL_ZIP_FILE=
fi
# Do checking message here to not mess up interleaved configure output
AC_MSG_CHECKING([for building with zipfs])
if test "${ZIPFS_BUILD}" = 1; then
    if test "${SHARED_BUILD}" = 0; then
       ZIPFS_BUILD=2;
       AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?])
       INSTALL_LIBRARIES=install-libraries-zipfs-static
       AC_MSG_RESULT([yes])
     else
       AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\
       INSTALL_LIBRARIES=install-libraries-zipfs-shared
       AC_MSG_RESULT([yes])
    fi
else
AC_MSG_RESULT([no])
INSTALL_LIBRARIES=install-libraries
INSTALL_MSGS=install-msgs
fi
AC_SUBST(ZIPFS_BUILD)
AC_SUBST(TK_ZIP_FILE)
AC_SUBST(INSTALL_LIBRARIES)
AC_SUBST(INSTALL_MSGS)


#------------------------------------------------------------------------
# tkConfig.sh refers to this by a different name
#------------------------------------------------------------------------

TK_SHARED_BUILD=${SHARED_BUILD}

#--------------------------------------------------------------------
# Perform final evaluations of variables with possible substitutions.
#--------------------------------------------------------------------

TK_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TK_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"


eval "TK_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(pwd)`\""

eval "TK_DLL_FILE_TCL8=tk$VER${DLLSUFFIX}"
eval "TK_DLL_FILE_TCL9=tcl9tk$VER${DLLSUFFIX}"
if test ${TCL_MAJOR_VERSION} = 8 ; then
eval "TK_DLL_FILE=tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
 eval "TK_LIB_FILE=${LIBPREFIX}tk${VER}${LIBSUFFIX}"
else
 eval "TK_LIB_FILE=${LIBPREFIX}tk${VER}${DLLSUFFIX}.a"
fi
else
eval "TK_DLL_FILE=tcl9tk$VER${DLLSUFFIX}"
if test ${SHARED_BUILD} = 0 -o "$GCC" != "yes" ; then
 eval "TK_LIB_FILE=${LIBPREFIX}tcl9tk${VER}${LIBSUFFIX}"
else
 eval "TK_LIB_FILE=${LIBPREFIX}tcl9tk${VER}${DLLSUFFIX}.a"
fi
fi

eval "TK_STUB_LIB_FILE=${LIBPREFIX}tkstub${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
TK_LIB_FLAG="-l"
if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
    TK_LIB_FLAG="${TK_LIB_FLAG}tcl9"
fi
eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}${VER}${LIBFLAGSUFFIX}\""
TK_LIB_SPEC="-L${libdir} ${TK_LIB_FLAG}"
eval "TK_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_LIB_FLAG}\""

if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
    eval "TK_STUB_LIB_FLAG=\"-ltkstub${LIBFLAGSUFFIX}\""
else
    eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""
fi
eval "TK_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_STUB_LIB_FLAG}\""

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
eval "TK_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(pwd)`/${TK_STUB_LIB_FILE}\""

eval "DLLSUFFIX=${DLLSUFFIX}"
eval "LIBPREFIX=${LIBPREFIX}"
eval "LIBSUFFIX=${LIBSUFFIX}"
eval "EXESUFFIX=${EXESUFFIX}"

CFG_TK_SHARED_LIB_SUFFIX=${TK_SHARED_LIB_SUFFIX}
CFG_TK_UNSHARED_LIB_SUFFIX=${TK_UNSHARED_LIB_SUFFIX}


#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 0; then
    RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
    TK_RES=""
else
    RC_DEFINES=""
    TK_RES='tk.$(RES)'
fi

214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_DLL_FILE)


AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_SRC_DIR)
AC_SUBST(TK_BIN_DIR)

AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)

AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_EXPORT_FILE_SUFFIX)

AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(CYGPATH)
AC_SUBST(DEPARG)
AC_SUBST(CC_OBJNAME)
AC_SUBST(CC_EXENAME)







>
>















<







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331

AC_SUBST(TK_VERSION)
AC_SUBST(TK_MAJOR_VERSION)
AC_SUBST(TK_MINOR_VERSION)
AC_SUBST(TK_PATCH_LEVEL)
AC_SUBST(TK_LIB_FILE)
AC_SUBST(TK_DLL_FILE)
AC_SUBST(TK_DLL_FILE_TCL8)
AC_SUBST(TK_DLL_FILE_TCL9)
AC_SUBST(TK_STUB_LIB_FILE)
AC_SUBST(TK_STUB_LIB_FLAG)
AC_SUBST(TK_BUILD_STUB_LIB_SPEC)
AC_SUBST(TK_SRC_DIR)
AC_SUBST(TK_BIN_DIR)

AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)

AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(CFG_TK_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TK_UNSHARED_LIB_SUFFIX)


AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(CYGPATH)
AC_SUBST(DEPARG)
AC_SUBST(CC_OBJNAME)
AC_SUBST(CC_EXENAME)
287
288
289
290
291
292
293
294

295
296
297
298
AC_SUBST(RC_OUT)
AC_SUBST(RC_TYPE)
AC_SUBST(RC_INCLUDE)
AC_SUBST(RC_DEFINE)
AC_SUBST(RC_DEFINES)
AC_SUBST(RES)

AC_OUTPUT(Makefile tkConfig.sh wish.exe.manifest)


dnl Local Variables:
dnl mode: autoconf;
dnl End:







|
>


|

375
376
377
378
379
380
381
382
383
384
385
386
387
AC_SUBST(RC_OUT)
AC_SUBST(RC_TYPE)
AC_SUBST(RC_INCLUDE)
AC_SUBST(RC_DEFINE)
AC_SUBST(RC_DEFINES)
AC_SUBST(RES)

AC_CONFIG_FILES([Makefile tkConfig.sh wish.exe.manifest])
AC_OUTPUT

dnl Local Variables:
dnl mode: autoconf
dnl End:

Added win/gitmanifest.in.



>
1
git-

Changes to win/makefile.vc.

13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Copyright (c) 2003-2008 Pat Thoyts.
# Copyright (c) 2017 Ashok P. Nadkarni
#------------------------------------------------------------------------------

# General usage:
#   nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]]
#
# For MACRODEF, see TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md)
# or examine Sections 6-8 in rules.vc. This makefile has the following
# values for the OPTS macro in addition to the ones described there.
#	noxp     = If you do not have the uxtheme.h header then you

#                  cannot include support for XP themeing.
#	square   = Include the demo square widget.
#
# Possible values for TARGET are:
#	release  -- Builds the core, the shell and the dlls. (default)
#	dlls     -- Just builds the windows extensions.
#	shell    -- Just builds the shell and the core.
#	core     -- Only builds the core [tkXX.(dll|lib)].
#	all      -- Builds everything.
#	test     -- Builds and runs the test suite.
#	tktest   -- Just builds the binaries for the test suite.
#	install  -- Installs the built binaries and libraries to $(INSTALLDIR)
#		    as the root of the install tree.
#	cwish    -- Builds a console version of wish.
#	tidy/clean/hose -- varying levels of cleaning.
#	genstubs -- Rebuilds the Stubs table and support files (dev only).
#	depend   -- Generates an accurate set of source dependancies for this
#		    makefile.  Helpful to avoid problems when the sources are







|
|

|
>
|









|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Copyright (c) 2003-2008 Pat Thoyts.
# Copyright (c) 2017 Ashok P. Nadkarni
#------------------------------------------------------------------------------

# General usage:
#   nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]]
#
# For MACRODEF, see TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md)
# or examine Sections 7-9 in rules.vc. This makefile has the following
# values for the OPTS macro in addition to the ones described there.
#       noembed  = Embeds Tcl scripts into the wish executable. Currently only
#                  applicable for static builds. Non-static builds currently
#                  never embed.
#	square   = Include the demo square widget.
#
# Possible values for TARGET are:
#	release  -- Builds the core, the shell and the dlls. (default)
#	dlls     -- Just builds the windows extensions.
#	shell    -- Just builds the shell and the core.
#	core     -- Only builds the core [tkXX.(dll|lib)].
#	all      -- Builds everything.
#	test     -- Builds and runs the test suite.
#	tktest   -- Just builds the test shell.
#	install  -- Installs the built binaries and libraries to $(INSTALLDIR)
#		    as the root of the install tree.
#	cwish    -- Builds a console version of wish.
#	tidy/clean/hose -- varying levels of cleaning.
#	genstubs -- Rebuilds the Stubs table and support files (dev only).
#	depend   -- Generates an accurate set of source dependancies for this
#		    makefile.  Helpful to avoid problems when the sources are
80
81
82
83
84
85
86
87
88
89
90
91






92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117











118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Default target to build if no target is specified. If unspecified, the
# rules.vc file will set up "all" as the target.
DEFAULT_BUILD_TARGET = release

# We have a custom resource file
RCFILE = tk.rc

USE_WIDECHAR_API  = 0

# The rules.vc file does much of the hard work in terms of defining
# the build configuration, macros, output directories etc.
!include "rules-ext.vc"







# TCLINSTALL is set to 1 by rules.vc to indicate we are building against
# an installed Tcl and 0 if building against Tcl source. Tk needs the latter.
!if $(TCLINSTALL)
!message *** Warning: Tk requires the source distribution of Tcl to build from,
!message ***    at this time, sorry.  Please set the TCLDIR macro to point to the
!message ***    Tcl sources.
!endif

# Extra makefile options processing for non-standard OPTS values ...
!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
HAVE_UXTHEME_H    = 1
TTK_SQUARE_WIDGET = 0
!else
!if [nmakehlp -f $(OPTS) "noxp"]
!message *** Exclude support for XP theme
HAVE_UXTHEME_H  = 0
!else
HAVE_UXTHEME_H  = 1
!endif
!if [nmakehlp -f "$(OPTS)" "square"]
!message *** Include ttk square demo widget
TTK_SQUARE_WIDGET   = 1
!else
TTK_SQUARE_WIDGET   = 0
!endif











!endif

TK_NO_DEPRECATED = 0
!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
!if [nmakehlp -f $(CHECKS) "nodep"]
TK_NO_DEPRECATED = 1
!endif
!endif

WISHC 		= "$(OUT_DIR)\$(WISHNAMEPREFIX)c$(VERSION)$(SUFX).exe"

TKTEST		= "$(OUT_DIR)\$(PROJECT)test.exe"
CAT32		= "$(OUT_DIR)\cat32.exe"

WISHOBJS = \
	$(TMP_DIR)\winMain.obj \
!if $(TCL_USE_STATIC_PACKAGES)
	$(TCLDDELIB) \
	$(TCLREGLIB) \
!endif
	$(TMP_DIR)\wish.res

TKTESTOBJS = \
	$(TMP_DIR)\testMain.obj \
	$(TMP_DIR)\tkSquare.obj \
	$(TMP_DIR)\tkTest.obj \
	$(TMP_DIR)\tkOldTest.obj \
	$(TMP_DIR)\tkWinTest.obj

XLIBOBJS = \
	$(TMP_DIR)\xcolors.obj \
	$(TMP_DIR)\xdraw.obj \
	$(TMP_DIR)\xgc.obj \
	$(TMP_DIR)\ximage.obj \
	$(TMP_DIR)\xutil.obj







<
<



>
>
>
>
>
>











<

<
<
<
|

<
<






>
>
>
>
>
>
>
>
>
>
>











|




|









|
|







81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108



109
110


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# Default target to build if no target is specified. If unspecified, the
# rules.vc file will set up "all" as the target.
DEFAULT_BUILD_TARGET = release

# We have a custom resource file
RCFILE = tk.rc



# The rules.vc file does much of the hard work in terms of defining
# the build configuration, macros, output directories etc.
!include "rules-ext.vc"

!if ($(TCL_MAJOR_VERSION) > 8) || ($(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) > 6)
USING_PRE87_TCL = 0
!else
USING_PRE87_TCL = 1
!endif

# TCLINSTALL is set to 1 by rules.vc to indicate we are building against
# an installed Tcl and 0 if building against Tcl source. Tk needs the latter.
!if $(TCLINSTALL)
!message *** Warning: Tk requires the source distribution of Tcl to build from,
!message ***    at this time, sorry.  Please set the TCLDIR macro to point to the
!message ***    Tcl sources.
!endif

# Extra makefile options processing for non-standard OPTS values ...
!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]

TTK_SQUARE_WIDGET = 0



TK_EMBED_SCRIPTS  = 1
!else


!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 = 1
!endif
!endif

!if $(USING_PRE87_TCL)
TK_EMBED_SCRIPTS = 0
!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$(VERSION)$(SUFX).exe"
CAT32		= "$(OUT_DIR)\cat32.exe"

WISHOBJS = \
	$(TMP_DIR)\winMain.obj \
!if $(STATIC_BUILD) && !$(STATIC_BUILD)
	$(TCLDDELIB) \
	$(TCLREGLIB) \
!endif
	$(TMP_DIR)\wish.res

TKTESTOBJS = \
	$(TMP_DIR)\testMain.obj \
	$(TMP_DIR)\tkSquare.obj \
	$(TMP_DIR)\tkTest.obj \
	$(TMP_DIR)\tkWinTest.obj \
	$(TMP_DIR)\tktest.res

XLIBOBJS = \
	$(TMP_DIR)\xcolors.obj \
	$(TMP_DIR)\xdraw.obj \
	$(TMP_DIR)\xgc.obj \
	$(TMP_DIR)\ximage.obj \
	$(TMP_DIR)\xutil.obj
163
164
165
166
167
168
169


170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
	$(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)\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)\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 \
	$(TMP_DIR)\tkBind.obj \

	$(TMP_DIR)\tkBitmap.obj \
	$(TMP_DIR)\tkBusy.obj \
	$(TMP_DIR)\tkButton.obj \
	$(TMP_DIR)\tkCanvArc.obj \
	$(TMP_DIR)\tkCanvBmap.obj \
	$(TMP_DIR)\tkCanvImg.obj \
	$(TMP_DIR)\tkCanvLine.obj \







>
>










>








>







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
	$(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)\tkWinGDI.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 \
	$(TMP_DIR)\tkBind.obj \
	$(TMP_DIR)\tkBitField.obj \
	$(TMP_DIR)\tkBitmap.obj \
	$(TMP_DIR)\tkBusy.obj \
	$(TMP_DIR)\tkButton.obj \
	$(TMP_DIR)\tkCanvArc.obj \
	$(TMP_DIR)\tkCanvBmap.obj \
	$(TMP_DIR)\tkCanvImg.obj \
	$(TMP_DIR)\tkCanvLine.obj \
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253

254
255

256
257
258
259
260
261
262
263
264
265
	$(TMP_DIR)\tkFont.obj \
	$(TMP_DIR)\tkFrame.obj \
	$(TMP_DIR)\tkGC.obj \
	$(TMP_DIR)\tkGeometry.obj \
	$(TMP_DIR)\tkGet.obj \
	$(TMP_DIR)\tkGrab.obj \
	$(TMP_DIR)\tkGrid.obj \

	$(TMP_DIR)\tkImage.obj \
	$(TMP_DIR)\tkImgBmap.obj \
	$(TMP_DIR)\tkImgListFormat.obj \
	$(TMP_DIR)\tkImgGIF.obj \
	$(TMP_DIR)\tkImgPNG.obj \
	$(TMP_DIR)\tkImgPPM.obj \
	$(TMP_DIR)\tkImgSVGnano.obj \
	$(TMP_DIR)\tkImgPhoto.obj \
	$(TMP_DIR)\tkImgPhInstance.obj \
	$(TMP_DIR)\tkImgUtil.obj \

	$(TMP_DIR)\tkListbox.obj \
	$(TMP_DIR)\tkMacWinMenu.obj \
	$(TMP_DIR)\tkMain.obj \
	$(TMP_DIR)\tkMain2.obj \
	$(TMP_DIR)\tkMenu.obj \
	$(TMP_DIR)\tkMenubutton.obj \
	$(TMP_DIR)\tkMenuDraw.obj \
	$(TMP_DIR)\tkMessage.obj \
	$(TMP_DIR)\tkPanedWindow.obj \
	$(TMP_DIR)\tkObj.obj \
	$(TMP_DIR)\tkOldConfig.obj \
	$(TMP_DIR)\tkOption.obj \
	$(TMP_DIR)\tkPack.obj \
	$(TMP_DIR)\tkPkgConfig.obj \
	$(TMP_DIR)\tkPlace.obj \
	$(TMP_DIR)\tkPointer.obj \

	$(TMP_DIR)\tkRectOval.obj \
	$(TMP_DIR)\tkScale.obj \
	$(TMP_DIR)\tkScrollbar.obj \
	$(TMP_DIR)\tkSelect.obj \
	$(TMP_DIR)\tkStyle.obj \
	$(TMP_DIR)\tkText.obj \
	$(TMP_DIR)\tkTextBTree.obj \
	$(TMP_DIR)\tkTextDisp.obj \
	$(TMP_DIR)\tkTextImage.obj \
	$(TMP_DIR)\tkTextIndex.obj \

	$(TMP_DIR)\tkTextMark.obj \
	$(TMP_DIR)\tkTextTag.obj \

	$(TMP_DIR)\tkTextWind.obj \
	$(TMP_DIR)\tkTrig.obj \
	$(TMP_DIR)\tkUndo.obj \
	$(TMP_DIR)\tkUtil.obj \
	$(TMP_DIR)\tkVisual.obj \
	$(TMP_DIR)\tkStubInit.obj \
	$(TMP_DIR)\tkWindow.obj \
	$(TTK_OBJS) \
!if !$(STATIC_BUILD)
	$(TMP_DIR)\tk.res







>










>
















>










>


>
|
|
|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
	$(TMP_DIR)\tkFont.obj \
	$(TMP_DIR)\tkFrame.obj \
	$(TMP_DIR)\tkGC.obj \
	$(TMP_DIR)\tkGeometry.obj \
	$(TMP_DIR)\tkGet.obj \
	$(TMP_DIR)\tkGrab.obj \
	$(TMP_DIR)\tkGrid.obj \
	$(TMP_DIR)\tkIcu.obj \
	$(TMP_DIR)\tkImage.obj \
	$(TMP_DIR)\tkImgBmap.obj \
	$(TMP_DIR)\tkImgListFormat.obj \
	$(TMP_DIR)\tkImgGIF.obj \
	$(TMP_DIR)\tkImgPNG.obj \
	$(TMP_DIR)\tkImgPPM.obj \
	$(TMP_DIR)\tkImgSVGnano.obj \
	$(TMP_DIR)\tkImgPhoto.obj \
	$(TMP_DIR)\tkImgPhInstance.obj \
	$(TMP_DIR)\tkImgUtil.obj \
	$(TMP_DIR)\tkIntSet.obj \
	$(TMP_DIR)\tkListbox.obj \
	$(TMP_DIR)\tkMacWinMenu.obj \
	$(TMP_DIR)\tkMain.obj \
	$(TMP_DIR)\tkMain2.obj \
	$(TMP_DIR)\tkMenu.obj \
	$(TMP_DIR)\tkMenubutton.obj \
	$(TMP_DIR)\tkMenuDraw.obj \
	$(TMP_DIR)\tkMessage.obj \
	$(TMP_DIR)\tkPanedWindow.obj \
	$(TMP_DIR)\tkObj.obj \
	$(TMP_DIR)\tkOldConfig.obj \
	$(TMP_DIR)\tkOption.obj \
	$(TMP_DIR)\tkPack.obj \
	$(TMP_DIR)\tkPkgConfig.obj \
	$(TMP_DIR)\tkPlace.obj \
	$(TMP_DIR)\tkPointer.obj \
	$(TMP_DIR)\tkRangeList.obj \
	$(TMP_DIR)\tkRectOval.obj \
	$(TMP_DIR)\tkScale.obj \
	$(TMP_DIR)\tkScrollbar.obj \
	$(TMP_DIR)\tkSelect.obj \
	$(TMP_DIR)\tkStyle.obj \
	$(TMP_DIR)\tkText.obj \
	$(TMP_DIR)\tkTextBTree.obj \
	$(TMP_DIR)\tkTextDisp.obj \
	$(TMP_DIR)\tkTextImage.obj \
	$(TMP_DIR)\tkTextIndex.obj \
	$(TMP_DIR)\tkTextLineBreak.obj \
	$(TMP_DIR)\tkTextMark.obj \
	$(TMP_DIR)\tkTextTag.obj \
	$(TMP_DIR)\tkTextTagSet.obj \
	$(TMP_DIR)\tkTextUndo.obj \
	$(TMP_DIR)\tkTextWind.obj \
	$(TMP_DIR)\tkTrig.obj \
	$(TMP_DIR)\tkUtil.obj \
	$(TMP_DIR)\tkVisual.obj \
	$(TMP_DIR)\tkStubInit.obj \
	$(TMP_DIR)\tkWindow.obj \
	$(TTK_OBJS) \
!if !$(STATIC_BUILD)
	$(TMP_DIR)\tk.res
305
306
307
308
309
310
311






312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349



350
351
352














353
354
355
356
357
358
359
	$(TMP_DIR)\ttkStubLib.obj

### The following paths CANNOT have spaces in them as they appear on
### the left side of implicit rules.
XLIBDIR		= $(ROOT)\xlib
TTKDIR		= $(ROOT)\generic\ttk
BITMAPDIR	= $(ROOT)\bitmaps







# Additional include and C macro definitions for the implicit rules
# defined in rules.vc
PRJ_INCLUDES	= -I"$(BITMAPDIR)" -I"$(XLIBDIR)"

CONFIG_DEFS     =/DSTDC_HEADERS=1 /DHAVE_SYS_TYPES_H=1 /DHAVE_SYS_STAT_H=1 \
		 /DHAVE_STRING_H=1 /DHAVE_MEMORY_H=1 \
		 /DHAVE_STRINGS_H=1 \
		 /DSUPPORT_CONFIG_EMBEDDED \
!if $(HAVE_UXTHEME_H)
		 /DHAVE_UXTHEME_H=1 \
!endif
!if $(TTK_SQUARE_WIDGET)
		 /DTTK_SQUARE_WIDGET=1 \
!endif
!if $(TK_NO_DEPRECATED)
		 /DTK_NO_DEPRECATED=1
!endif

PRJ_DEFINES	= /DBUILD_ttk $(CONFIG_DEFS) /Dinline=__inline /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE

# Additional Link libraries needed beyond those in rules.vc
PRJ_LIBS   = netapi32.lib gdi32.lib user32.lib userenv.lib


#---------------------------------------------------------------------
# TkTest flags
#---------------------------------------------------------------------

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif

#---------------------------------------------------------------------
# Project specific targets
#---------------------------------------------------------------------

release:  setup $(TKSTUBLIB) $(WISH)



all:	  release $(CAT32)
core:	  setup $(TKSTUBLIB) $(TKLIB)
cwish:	  $(WISHC)














install:  install-binaries install-libraries install-docs
!if $(SYMBOLS)
install:    install-pdbs
!endif
tktest:	  setup $(TKTEST) $(CAT32)

setup: default-setup







>
>
>
>
>
>





|

|
<
<
<
<










|
<














>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344




345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
	$(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     =/DHAVE_SYS_TYPES_H=1 /DHAVE_SYS_STAT_H=1 \
		 /DHAVE_STRING_H=1 /DHAVE_MEMORY_H=1 \
		 /DHAVE_STRINGS_H=1 /DTCL_UTF_MAX=4 \




!if $(TTK_SQUARE_WIDGET)
		 /DTTK_SQUARE_WIDGET=1 \
!endif
!if $(TK_NO_DEPRECATED)
		 /DTK_NO_DEPRECATED=1
!endif

PRJ_DEFINES	= /DBUILD_ttk $(CONFIG_DEFS) /Dinline=__inline /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE

# Additional Link libraries needed beyond those in rules.vc
PRJ_LIBS   = netapi32.lib gdi32.lib user32.lib userenv.lib winspool.lib shell32.lib ole32.lib uuid.lib


#---------------------------------------------------------------------
# TkTest flags
#---------------------------------------------------------------------

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif

#---------------------------------------------------------------------
# Project specific targets
#---------------------------------------------------------------------

release:  setup $(TKSTUBLIB) $(WISH)
!if !$(USING_PRE87_TCL)
release:  libtkzip embed
!endif
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
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
476
477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
	$(_VC_MANIFEST_EMBED_EXE)


$(TKTEST): $(TKTESTOBJS) $(TKSTUBLIB) $(TKIMPLIB)
	$(GUIEXECMD) -stack:2300000 $**
	$(_VC_MANIFEST_EMBED_EXE)




























$(CAT32): $(_TCLDIR)\win\cat.c
	$(cc32) $(cflags) $(crt) /D_CRT_NONSTDC_NO_DEPRECATE /DCONSOLE /DUNICODE /D_UNICODE -Fo$(TMP_DIR)\ $?
	$(CONEXECMD) /DCONSOLE -stack:16384 $(TMP_DIR)\cat.obj
	$(_VC_MANIFEST_EMBED_EXE)

#---------------------------------------------------------------------
# Regenerate the stubs files.  [Development use only]
#---------------------------------------------------------------------

genstubs:
!if !exist($(TCLSH))
	@echo Build tclsh first!
!else
	set TCL_LIBRARY=$(TCL_LIBRARY)
	$(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
		$(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls

!endif


#---------------------------------------------------------------------
# Build the Windows HTML help file.
#---------------------------------------------------------------------








>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>


|













>







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
	$(_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)"
	@$(TCLSH) <<
cd {$(OUT_DIR)}
file delete -force {$@}
zipfs mkzip {$@} {$(LIBTKVFS)} {$(LIBTKVFS)}
<<

!if $(STATIC_BUILD)
$(WISHSCRIPTZIP): $(TKSCRIPTZIP)
	@echo Building Wish Tcl+Tk library zip file
	@if exist "$(LIBTKVFS)\tcl_library" $(RMDIR) "$(LIBTKVFS)\tcl_library"
	@$(TCLSH) <<
cd {$(OUT_DIR)}
file delete -force {$@}
zipfs mount "$(TCLSCRIPTZIP:\=/)" mnt
file copy [file join [zipfs root] mnt tcl_library] "$(LIBTKVFS:\=/)"
zipfs mkzip {$@} {$(LIBTKVFS)} {$(LIBTKVFS)}
<<
!endif


$(CAT32): $(_TCLDIR)\win\cat.c
	$(cc32) $(cflags) $(crt) /D_CRT_NONSTDC_NO_DEPRECATE /DCONSOLE /DUNICODE /D_UNICODE -Fo$(TMP_DIR)\ $?
	$(CONEXECMD) -stack:16384 $(TMP_DIR)\cat.obj
	$(_VC_MANIFEST_EMBED_EXE)

#---------------------------------------------------------------------
# Regenerate the stubs files.  [Development use only]
#---------------------------------------------------------------------

genstubs:
!if !exist($(TCLSH))
	@echo Build tclsh first!
!else
	set TCL_LIBRARY=$(TCL_LIBRARY)
	$(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR) \
		$(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
	$(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR)\ttk $(GENERICDIR)\ttk\ttk.decls
!endif


#---------------------------------------------------------------------
# Build the Windows HTML help file.
#---------------------------------------------------------------------

539
540
541
542
543
544
545

546
547
548
549
550
551


552


553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569








570
571
572
573
574
575
576
	@$(CPY) "$(OUT_DIR)\*.pdb" "$(BIN_INSTALL_DIR)\"
# "emacs font-lock highlighting fix

#---------------------------------------------------------------------
# Special case object file targets
#---------------------------------------------------------------------


$(TMP_DIR)\testMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(appcflags_nostubs) /DTK_TEST /DUNICODE /D_UNICODE \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    -Fo$@ $?

$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c


	$(cc32) $(appcflags_nostubs) -Fo$@ $?



$(TMP_DIR)\tkOldTest.obj: $(GENERICDIR)\tkOldTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkWinTest.obj: $(WIN_DIR)\tkWinTest.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?

$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
	$(cc32) $(appcflags_nostubs) -Fo$@ $?


$(TMP_DIR)\winMain.obj: $(WIN_DIR)\winMain.c
	$(cc32) $(appcflags_nostubs) /DUNICODE /D_UNICODE \
	    /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
	    -Fo$@ $?

$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c
	$(cc32) $(pkgcflags) /DUNICODE /D_UNICODE -Fo$@ $?









# The following objects are part of the stub library and should not
# be built as DLL objects but none of the symbols should be exported
# and no reference made to a C runtime.

$(TMP_DIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c
	$(cc32) $(stubscflags) -Fo$@ $?







>


|


|
>
>
|
>
>

|
|


|


|

>


|




>
>
>
>
>
>
>
>







603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
	@$(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=$(STATIC_BUILD) \
	    -Fo$@ $?

$(ROOT)\manifest.uuid:
   copy $(WIN_DIR)\gitmanifest.in $(ROOT)\manifest.uuid
   git rev-parse HEAD >>$(ROOT)\manifest.uuid

$(TMP_DIR)\tkUuid.h:	$(ROOT)\manifest.uuid
	copy $(WIN_DIR)\tkUuid.h.in+$(ROOT)\manifest.uuid $(TMP_DIR)\tkUuid.h

$(TMP_DIR)\tkTest.obj: $(GENERICDIR)\tkTest.c
	$(cc32) $(stubscflags) /DUSE_TK_STUBS -Fo$@ $?

$(TMP_DIR)\tkWinTest.obj: $(WIN_DIR)\tkWinTest.c
	$(cc32) $(stubscflags) /DUSE_TK_STUBS -Fo$@ $?

$(TMP_DIR)\tkSquare.obj: $(GENERICDIR)\tkSquare.c
	$(cc32) $(stubscflags) /DUSE_TK_STUBS -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=$(STATIC_BUILD) \
	    -Fo$@ $?

$(TMP_DIR)\tkMain2.obj: $(GENERICDIR)\tkMain.c
	$(cc32) $(pkgcflags) /DUNICODE /D_UNICODE -Fo$@ $?

$(TMP_DIR)\tkPkgConfig.obj: $(GENERICDIR)\tkPkgConfig.c
	$(cc32) $(pkgcflags) 		\
		-DCFG_RUNTIME_DLLFILE="\"$(TKLIBNAME)\"" \
		-Fo$@ $?

$(TMP_DIR)\tkWindow.obj: $(GENERICDIR)\tkWindow.c $(TMP_DIR)\tkUuid.h
	$(cc32) $(pkgcflags) -I$(TMP_DIR) -Fo$@ $?

# The following objects are part of the stub library and should not
# be built as DLL objects but none of the symbols should be exported
# and no reference made to a C runtime.

$(TMP_DIR)\tkStubLib.obj : $(GENERICDIR)\tkStubLib.c
	$(cc32) $(stubscflags) -Fo$@ $?
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
!endif

#---------------------------------------------------------------------
# Dependency rules
#---------------------------------------------------------------------

$(TMP_DIR)\tk.res: \
    $(RCDIR)\buttons.bmp \
    $(RCDIR)\cursor*.cur \
    $(RCDIR)\tk.ico

!if exist("$(OUT_DIR)\depend.mk")
!include "$(OUT_DIR)\depend.mk"
!message *** Dependency rules in use.
!else







<







684
685
686
687
688
689
690

691
692
693
694
695
696
697
!endif

#---------------------------------------------------------------------
# Dependency rules
#---------------------------------------------------------------------

$(TMP_DIR)\tk.res: \

    $(RCDIR)\cursor*.cur \
    $(RCDIR)\tk.ico

!if exist("$(OUT_DIR)\depend.mk")
!include "$(OUT_DIR)\depend.mk"
!message *** Dependency rules in use.
!else
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670



671

672

673


674


675
676
677
678
679
680
681
682
683
684
685
686
687




688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
{$(ROOT)\unix}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest
$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest


.SUFFIXES:
.SUFFIXES:.c .rc


#---------------------------------------------------------------------
# Installation.
#---------------------------------------------------------------------

install-binaries:
	@echo installing binaries
	@$(CPY) "$(WISH)" "$(BIN_INSTALL_DIR)\"
!if "$(TKLIB)" != "$(TKIMPLIB)"
	@$(CPY) "$(TKLIB)" "$(BIN_INSTALL_DIR)\"
!endif
	@$(CPY) "$(TKIMPLIB)" "$(LIB_INSTALL_DIR)\"
	@$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\"
!if !$(STATIC_BUILD)
	@echo creating package index
	@type << > $(OUT_DIR)\pkgIndex.tcl
if {[catch {package present Tcl 8.6-}]} { return }
if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
	|| ([info exists ::argv] && ("-display" in $$::argv)))} {



    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(DOTVERSION).dll] Tk]

} else {

    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk]


}


<<
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
!endif

#"

install-libraries:
	@echo installing Tk headers
	@$(CPY) "$(GENERICDIR)\tk.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(GENERICDIR)\tkIntXlibDecls.h" "$(INCLUDE_INSTALL_DIR)\"
	@$(CPY) "$(XLIBDIR)\X11\*.h" "$(INCLUDE_INSTALL_DIR)\X11\"




	@echo installing script library
	@$(CPY) "$(LIBDIR)\*" "$(SCRIPT_INSTALL_DIR)\"
	@echo installing theme library
	@$(CPY) "$(LIBDIR)\ttk\*" "$(SCRIPT_INSTALL_DIR)\ttk\"
	@echo installing images
	@$(CPY) "$(LIBDIR)\images\*" "$(SCRIPT_INSTALL_DIR)\images\"
	@echo installing language files
	@$(CPY) "$(LIBDIR)\msgs\*" "$(SCRIPT_INSTALL_DIR)\msgs\"

	@echo installing demos
	@$(CPY) "$(DEMODIR)\*" "$(DEMO_INSTALL_DIR)\"
	@$(CPY) "$(DEMODIR)\images\*" "$(DEMO_INSTALL_DIR)\images\"

#"

#---------------------------------------------------------------------







>




















|


>
>
>
|
>

>
|
>
>
|
>
>













>
>
>
>








>







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
{$(ROOT)\unix}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

$(TMP_DIR)\tk.res: $(TMP_DIR)\wish.exe.manifest
$(TMP_DIR)\wish.res: $(TMP_DIR)\wish.exe.manifest
$(TMP_DIR)\tktest.res: $(TMP_DIR)\wish.exe.manifest

.SUFFIXES:
.SUFFIXES:.c .rc


#---------------------------------------------------------------------
# Installation.
#---------------------------------------------------------------------

install-binaries:
	@echo installing binaries
	@$(CPY) "$(WISH)" "$(BIN_INSTALL_DIR)\"
!if "$(TKLIB)" != "$(TKIMPLIB)"
	@$(CPY) "$(TKLIB)" "$(BIN_INSTALL_DIR)\"
!endif
	@$(CPY) "$(TKIMPLIB)" "$(LIB_INSTALL_DIR)\"
	@$(CPY) "$(TKSTUBLIB)" "$(LIB_INSTALL_DIR)\"
!if !$(STATIC_BUILD)
	@echo creating package index
	@type << > $(OUT_DIR)\pkgIndex.tcl
if {![package vsatisfies [package provide Tcl] 8.7-]} return
if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
	|| ([info exists ::argv] && ("-display" in $$::argv)))} {
    if {[package vsatisfies [package provide Tcl] 9.0]} {
	package ifneeded tk $(TK_PATCH_LEVEL) [list load [file normalize [file join $$dir .. .. bin libtcl9tk$(DOTVERSION).dll]]]
    } else {
	package ifneeded tk $(TK_PATCH_LEVEL) [list load [file normalize [file join $$dir .. .. bin libtk$(DOTVERSION).dll]]]
    }
} else {
    if {[package vsatisfies [package provide Tcl] 9.0]} {
	package ifneeded tk $(TK_PATCH_LEVEL) [list load [file normalize [file join $$dir .. .. bin $(TKLIBNAME9)]]]
    } else {
	package ifneeded tk $(TK_PATCH_LEVEL) [list load [file normalize [file join $$dir .. .. bin $(TKLIBNAME8)]]]
    }
}
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\"
!if !$(USING_PRE87_TCL)
	@$(CPY) "$(TKSCRIPTZIP)" "$(LIB_INSTALL_DIR)"
!endif
!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





	@echo Removing $(WISH) ...
	@if exist $(WISH) del $(WISH)
	@echo Removing $(TKTEST) ...
	@if exist $(TKTEST) del $(TKTEST)
	@echo Removing $(TKSTUBLIB) ...
	@if exist $(TKSTUBLIB) del $(TKSTUBLIB)













>
>
>
>
>
808
809
810
811
812
813
814
815
816
817
818
819
	@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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
 * ----------------------------------------------------------------------------
 * 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
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#define NO_SHLWAPI_GDI
#define NO_SHLWAPI_STREAM
#define NO_SHLWAPI_REG
#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>

/*
 * This library is required for x64 builds with _some_ versions of MSVC
 */
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif

/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define   snprintf	_snprintf
#endif


/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(const char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
    char buffer[STATICBUFFERSIZE];
} pipeinfo;

pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};

/*
 * exitcodes: 0 == no, 1 == yes, 2 == error
 */

int
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;
    char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);







|
|








|
<
<
<


|













|







|
















|
|













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * ----------------------------------------------------------------------------
 * nmakehlp.c --
 *
 *	This is used to fix limitations within nmake and the environment.
 *
 * Copyright (c) 2002 David Gravereaux.
 * Copyright (c) 2006 Pat Thoyts
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#ifdef _MSC_VER



#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#endif
#include <stdio.h>
#include <math.h>

/*
 * This library is required for x64 builds with _some_ versions of MSVC
 */
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif

/* ISO hack for dumb VC++ */
#if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1900
#define   snprintf	_snprintf
#endif


/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
    char buffer[STATICBUFFERSIZE];
} pipeinfo;

pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};

/*
 * exitcodes: 0 == no, 1 == yes, 2 == error
 */

int
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;
    const char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = FALSE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.







|
|




|





|





|







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];

    hProcess = GetCurrentProcess();

    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = FALSE;

    /*
     * Create a non-inheritable pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritable, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.







|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
}

static int
CheckForLinkerFeature(
    const char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    int i;
    char cmdline[255];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.







|














|
|




|











|







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
}

static int
CheckForLinkerFeature(
    char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    int i;
    char cmdline[255];

    hProcess = GetCurrentProcess();

    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritable, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.







|







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
{
    size_t cbBuffer = 100;
    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
	/*
	 * Read data until we see our match string.
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit after the match.
		 */

		p += strlen(match);
		while (*p && !isdigit(*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
			    && (!strchr("ab", q[-1])) || --numdots))) {
		    ++q;
		}

		memcpy(szBuffer, p, q - p);
		szBuffer[q-p] = 0;
		szResult = szBuffer;
		break;
	    }
	}
	fclose(fp);
    }
    return szResult;
}







<









|









|








|
|



<
|
|







501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
{

    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
	/*
	 * Read data until we see our match string.
	 */

	while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit after the match.
		 */

		p += strlen(match);
		while (*p && !isdigit((unsigned char)*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
			    && !strchr("ab", q[-1])) || --numdots))) {
		    ++q;
		}


		*q = 0;
		szResult = p;
		break;
	    }
	}
	fclose(fp);
    }
    return szResult;
}
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
    char * value;
} list_item_t;

/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
    list_item_t *itemPtr = malloc(sizeof(list_item_t));
    if (itemPtr) {
	itemPtr->key = strdup(key);
	itemPtr->value = strdup(value);
	itemPtr->nextPtr = NULL;

	while(*listPtrPtr) {
	    listPtrPtr = &(*listPtrPtr)->nextPtr;







|







558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    char * value;
} list_item_t;

/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
    list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
    if (itemPtr) {
	itemPtr->key = strdup(key);
	itemPtr->value = strdup(value);
	itemPtr->nextPtr = NULL;

	while(*listPtrPtr) {
	    listPtrPtr = &(*listPtrPtr)->nextPtr;
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690











691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

727
728
729
730
731
732
733
734
    }
}

/*
 * SubstituteFile --
 *	As windows doesn't provide anything useful like sed and it's unreliable
 *	to use the tclsh you are building against (consider x-platform builds -
 *	eg compiling AMD64 target from IX86) we provide a simple substitution
 *	option here to handle autoconf style substitutions.
 *	The substitution file is whitespace and line delimited. The file should
 *	consist of lines matching the regular expression:
 *	  \s*\S+\s+\S*$
 *
 *	Usage is something like:
 *	  nmakehlp -S << $** > $@
 *        @PACKAGE_NAME@ $(PACKAGE_NAME)
 *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *        <<
 */

static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    size_t cbBuffer = 1024;
    static char szBuffer[1024], szCopy[1024];
    char *szResult = NULL;
    list_item_t *substPtr = NULL;
    FILE *fp, *sp;

    fp = fopen(filename, "rt");
    if (fp != NULL) {

	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif

	/*
	 * Run the substitutions over each line of the input
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
		    op = szBuffer;
		    while (op != m) *cp++ = *op++;
		    sp = p->value;
		    while (sp && *sp) *cp++ = *sp++;
		    op += strlen(p->key);
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf(szBuffer);
	}

	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}












/*
 * QualifyPath --
 *
 *	This composes the current working directory with a provided path
 *	and returns the fully qualified and normalized path.
 *	Mostly needed to setup paths for testing.
 */

static int
QualifyPath(
    const char *szPath)
{
    char szCwd[MAX_PATH + 1];
    char szTmp[MAX_PATH + 1];
    char *p;
    GetCurrentDirectory(MAX_PATH, szCwd);
    while ((p = strchr(szPath, '/')) && *p)
	*p = '\\';
    PathCombine(szTmp, szCwd, szPath);
    PathCanonicalize(szCwd, szTmp);
    printf("%s\n", szCwd);
    return 0;
}

/*
 * Implements LocateDependency for a single directory. See that command
 * for an explanation.
 * Returns 0 if found after printing the directory.
 * Returns 1 if not found but no errors.
 * Returns 2 on any kind of error
 * Basically, these are used as exit codes for the process.
 */
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
    HANDLE hSearch;
    char path[MAX_PATH+1];

    int dirlen, keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
	return 2; /* Have no real error reporting mechanism into nmake */
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
	return 2;







|

















<

<







|




|
















|













|
















|








>
>
>
>
>
>
>
>
>
>
>













|
<
<
|
<
<
<
















>
|







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708


709



710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
    }
}

/*
 * SubstituteFile --
 *	As windows doesn't provide anything useful like sed and it's unreliable
 *	to use the tclsh you are building against (consider x-platform builds -
 *	e.g. compiling AMD64 target from IX86) we provide a simple substitution
 *	option here to handle autoconf style substitutions.
 *	The substitution file is whitespace and line delimited. The file should
 *	consist of lines matching the regular expression:
 *	  \s*\S+\s+\S*$
 *
 *	Usage is something like:
 *	  nmakehlp -S << $** > $@
 *        @PACKAGE_NAME@ $(PACKAGE_NAME)
 *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *        <<
 */

static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{

    static char szBuffer[1024], szCopy[1024];

    list_item_t *substPtr = NULL;
    FILE *fp, *sp;

    fp = fopen(filename, "rt");
    if (fp != NULL) {

	/*
	 * Build a list of substitutions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifndef NDEBUG
	{
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif

	/*
	 * Run the substitutions over each line of the input
	 */

	while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
		    op = szBuffer;
		    while (op != m) *cp++ = *op++;
		    sp = p->value;
		    while (sp && *sp) *cp++ = *sp++;
		    op += strlen(p->key);
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf("%s", szBuffer);
	}

	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}

BOOL FileExists(LPCTSTR szPath)
{
#ifndef INVALID_FILE_ATTRIBUTES
    #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
    DWORD pathAttr = GetFileAttributes(szPath);
    return (pathAttr != INVALID_FILE_ATTRIBUTES &&
	    !(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
}


/*
 * QualifyPath --
 *
 *	This composes the current working directory with a provided path
 *	and returns the fully qualified and normalized path.
 *	Mostly needed to setup paths for testing.
 */

static int
QualifyPath(
    const char *szPath)
{
    char szCwd[MAX_PATH + 1];



    GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);



    printf("%s\n", szCwd);
    return 0;
}

/*
 * Implements LocateDependency for a single directory. See that command
 * for an explanation.
 * Returns 0 if found after printing the directory.
 * Returns 1 if not found but no errors.
 * Returns 2 on any kind of error
 * Basically, these are used as exit codes for the process.
 */
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
    HANDLE hSearch;
    char path[MAX_PATH+1];
    size_t dirlen;
    int keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
	return 2; /* Have no real error reporting mechanism into nmake */
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
	return 2;
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
	strncpy(path+dirlen+1, finfo.cFileName, sublen);
	path[dirlen+1+sublen] = '\\';
	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
	if (PathFileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));







|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
	strncpy(path+dirlen+1, finfo.cFileName, sublen);
	path[dirlen+1+sublen] = '\\';
	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
	if (FileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));
787
788
789
790
791
792
793

794
795
796
797
798
799
800
801
802
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{

    int i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};

    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;







>
|
|







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{
    size_t i;
    int ret;
    static const char *paths[] = {"..", "..\\..", "..\\..\\.."};

    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;

Deleted win/rc/buttons.bmp.

cannot compute difference between binary files

Deleted win/rc/lamp.bmp.

cannot compute difference between binary files

Changes to win/rc/tk.rc.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tk DLL\0"
            VALUE "OriginalFilename", "tk" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".dll\0"
            VALUE "CompanyName", "ActiveState Corporation\0"
            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 2001 by ActiveState Corporation, et al\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200







<

|







32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tk DLL\0"
            VALUE "OriginalFilename", "tk" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".dll\0"

            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 1987-2022 Regents of the University of California and other parties\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200

Changes to win/rc/tk_base.rc.

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    COMBOBOX        cmb1,8,253,135,21,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED |
                    CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER |
                    WS_VSCROLL

END


//
// Bitmaps
//

buttons			BITMAP  DISCARDABLE	"buttons.bmp"

//
// Cursors
//

X_cursor                CURSOR  DISCARDABLE     "cursor00.cur"
arrow                   CURSOR  DISCARDABLE     "cursor02.cur"
based_arrow_down        CURSOR  DISCARDABLE     "cursor04.cur"







<
<
<
<
<
<







45
46
47
48
49
50
51






52
53
54
55
56
57
58
    COMBOBOX        cmb1,8,253,135,21,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED |
                    CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER |
                    WS_VSCROLL

END








//
// Cursors
//

X_cursor                CURSOR  DISCARDABLE     "cursor00.cur"
arrow                   CURSOR  DISCARDABLE     "cursor02.cur"
based_arrow_down        CURSOR  DISCARDABLE     "cursor04.cur"

Added win/rc/tktest.rc.

































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//
// Version Resource Script
//

#include <windows.h>
#include <tk.h>

//
// build-up the name suffix that defines the type of build this is.
//
#if STATIC_BUILD
#define SUFFIX_STATIC	    "s"
#else
#define SUFFIX_STATIC	    ""
#endif

#if DEBUG && !UNCHECKED
#define SUFFIX_DEBUG	    "g"
#else
#define SUFFIX_DEBUG	    ""
#endif

#define SUFFIX		    SUFFIX_STATIC SUFFIX_DEBUG


VS_VERSION_INFO VERSIONINFO
 FILEVERSION    TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 PRODUCTVERSION TK_MAJOR_VERSION,TK_MINOR_VERSION,TK_RELEASE_LEVEL,TK_RELEASE_SERIAL
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG
 FILEFLAGS	VS_FF_DEBUG
#else
 FILEFLAGS	0x0L
#endif
 FILEOS		VOS__WINDOWS32
 FILETYPE	VFT_APP
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tktest Application\0"
            VALUE "OriginalFilename", "tktest" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".exe\0"
            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 1987-2022 Regents of the University of California and other parties\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

//
// Icon
//
//   The icon whose name or resource ID is lexigraphically first, is used
//   as the application's icon.
//

app                      ICON    DISCARDABLE     "wish.ico"

#if STATIC_BUILD
#include "tk_base.rc"
#endif

//
// This enables themed scrollbars in XP by trying to use comctl32 v6.
//

#ifndef RT_MANIFEST
#define RT_MANIFEST     24
#endif
#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "wish.exe.manifest"

Changes to win/rc/wish.rc.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Wish Application\0"
            VALUE "OriginalFilename", "wish" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".exe\0"
            VALUE "CompanyName", "ActiveState Corporation\0"
            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 2000 by ActiveState Corporation, et al\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200







<

|







38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Wish Application\0"
            VALUE "OriginalFilename", "wish" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".exe\0"

            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 1987-2022 Regents of the University of California and other parties\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200

Changes to win/rules-ext.vc.

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]




!endif

# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""

_RULESDIR = $(TCLDIR:/=\)








>
|
>
>
>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif

# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
!endif
!else
!if [copy x86_64-w64-mingw32-nmakehlp.exe nmakehlp.exe >NUL]
!endif
!endif

# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""

_RULESDIR = $(TCLDIR:/=\)

Changes to win/rules.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#------------------------------------------------------------- -*- makefile -*-
# rules.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file does all the hard work in terms of parsing build options,
# compiler switches, defining common targets and macros. The Tcl makefile
# directly includes this. Extensions include it via "rules-ext.vc".
#
# See TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 2001-2003 David Gravereaux.
# Copyright (c) 2003-2008 Patrick Thoyts
# Copyright (c) 2017      Ashok P. Nadkarni
#------------------------------------------------------------------------------

!ifndef _RULES_VC
_RULES_VC = 1

# The following macros define the version of the rules.vc nmake build system
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
RULES_VERSION_MINOR = 6

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""








|

















|







1
2
3
4
5
6
7
8
9
10
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/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 = 11

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""
75
76
77
78
79
80
81


82
83
84
85
86
87
88
89
90
91
92
# 1. First define the external tools used for compiling, copying etc.
#    as this is independent of everything else.
# 2. Figure out our build structure in terms of the directory, whether
#    we are building Tcl or an extension, etc.
# 3. Determine the compiler and linker versions
# 4. Build the nmakehlp helper application
# 5. Determine the supported compiler options and features


# 6. Parse the OPTS macro value for user-specified build configuration
# 7. Parse the STATS macro value for statistics instrumentation
# 8. Parse the CHECKS macro for additional compilation checks
# 9. Extract Tcl, and possibly Tk, version numbers from the headers
# 10. Based on this selected configuration, construct the output
#     directory and file paths
# 11. Construct the paths where the package is to be installed
# 12. Set up the actual options passed to compiler and linker based
#     on the information gathered above.
# 13. Define some standard build targets and implicit rules. These may
#     be optionally disabled by the parent makefile.







>
>
|
|
|
<







75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
# 1. First define the external tools used for compiling, copying etc.
#    as this is independent of everything else.
# 2. Figure out our build structure in terms of the directory, whether
#    we are building Tcl or an extension, etc.
# 3. Determine the compiler and linker versions
# 4. Build the nmakehlp helper application
# 5. Determine the supported compiler options and features
# 6. Extract Tcl, Tk, and possibly extensions, version numbers from the
#    headers
# 7. Parse the OPTS macro value for user-specified build configuration
# 8. Parse the STATS macro value for statistics instrumentation
# 9. Parse the CHECKS macro for additional compilation checks

# 10. Based on this selected configuration, construct the output
#     directory and file paths
# 11. Construct the paths where the package is to be installed
# 12. Set up the actual options passed to compiler and linker based
#     on the information gathered above.
# 13. Define some standard build targets and implicit rules. These may
#     be optionally disabled by the parent makefile.
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# following macros:
# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
#     This is also printed by the compiler in dotted form 19.10 etc.
# VCVER - the "marketing version", for example Visual C++ 6 for internal
#     compiler version 1200. This is kept only for legacy reasons as it
#     does not make sense for recent Microsoft compilers. Only used for
#     output directory names.
# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
# MACHINE - same as $(ARCH) - legacy
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.







|
|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# following macros:
# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
#     This is also printed by the compiler in dotted form 19.10 etc.
# VCVER - the "marketing version", for example Visual C++ 6 for internal
#     compiler version 1200. This is kept only for legacy reasons as it
#     does not make sense for recent Microsoft compilers. Only used for
#     output directory names.
# ARCH - set to IX86, ARM64 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86, ARM64 or AMD64 for the host machine
# MACHINE - same as $(ARCH) - legacy
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.
431
432
433
434
435
436
437


438
439
440
441
442
443
444
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
    && ![echo ARCH=IX86 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
    && ![echo ARCH=AMD64 >> vercl.x] \


    && ![echo $(_HASH)endif >> vercl.x] \
    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
!include vercl.i
!if $(VCVERSION) < 1900
!if ![echo VCVER= ^\> vercl.vc] \
    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
!include vercl.vc







>
>







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
    && ![echo ARCH=IX86 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
    && ![echo ARCH=AMD64 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_ARM64) >> vercl.x] \
    && ![echo ARCH=ARM64 >> vercl.x] \
    && ![echo $(_HASH)endif >> vercl.x] \
    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
!include vercl.i
!if $(VCVERSION) < 1900
!if ![echo VCVER= ^\> vercl.vc] \
    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
!include vercl.vc
455
456
457
458
459
460
461



462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477


478
479
480
481
482
483
484
485
486
487
488
489
490
491
492


493
494
495
496
497
498
499

#----------------------------------------------------------------
# The MACHINE macro is used by legacy makefiles so set it as well
!ifdef MACHINE
!if "$(MACHINE)" == "x86"
!undef MACHINE
MACHINE = IX86



!elseif "$(MACHINE)" == "x64"
!undef MACHINE
MACHINE = AMD64
!endif
!if "$(MACHINE)" != "$(ARCH)"
!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
!endif
!else
MACHINE=$(ARCH)
!endif

#---------------------------------------------------------------
# The PLATFORM_IDENTIFY macro matches the values returned by
# the Tcl platform::identify command
!if "$(MACHINE)" == "AMD64"
PLATFORM_IDENTIFY = win32-x86_64


!else
PLATFORM_IDENTIFY = win32-ix86
!endif

# The MULTIPLATFORM macro controls whether binary extensions are installed
# in platform-specific directories. Intended to be set/used by extensions.
!ifndef MULTIPLATFORM_INSTALL
MULTIPLATFORM_INSTALL = 0
!endif

#------------------------------------------------------------
# Figure out the *host* architecture by reading the registry

!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
NATIVE_ARCH=IX86


!else
NATIVE_ARCH=AMD64
!endif

# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist [email protected] mt -nologo -manifest [email protected] -outputresource:$@;1







>
>
>
















>
>















>
>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509

#----------------------------------------------------------------
# The MACHINE macro is used by legacy makefiles so set it as well
!ifdef MACHINE
!if "$(MACHINE)" == "x86"
!undef MACHINE
MACHINE = IX86
!elseif "$(MACHINE)" == "arm64"
!undef MACHINE
MACHINE = ARM64
!elseif "$(MACHINE)" == "x64"
!undef MACHINE
MACHINE = AMD64
!endif
!if "$(MACHINE)" != "$(ARCH)"
!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
!endif
!else
MACHINE=$(ARCH)
!endif

#---------------------------------------------------------------
# The PLATFORM_IDENTIFY macro matches the values returned by
# the Tcl platform::identify command
!if "$(MACHINE)" == "AMD64"
PLATFORM_IDENTIFY = win32-x86_64
!elseif "$(MACHINE)" == "ARM64"
PLATFORM_IDENTIFY = win32-arm
!else
PLATFORM_IDENTIFY = win32-ix86
!endif

# The MULTIPLATFORM macro controls whether binary extensions are installed
# in platform-specific directories. Intended to be set/used by extensions.
!ifndef MULTIPLATFORM_INSTALL
MULTIPLATFORM_INSTALL = 0
!endif

#------------------------------------------------------------
# Figure out the *host* architecture by reading the registry

!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
NATIVE_ARCH=IX86
!elseif ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i ARM | findstr /i 64-bit]
NATIVE_ARCH=ARM64
!else
NATIVE_ARCH=AMD64
!endif

# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist [email protected] mt -nologo -manifest [email protected] -outputresource:$@;1
537
538
539
540
541
542
543

544
545




546
547
548
549
550
551
552
!endif # $(TCLINSTALL)
!endif # !$(DOING_TCL)

!endif # NMAKEHLPC

# We always build nmakehlp even if it exists since we do not know
# what source it was built from.

!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif





################################################################
# 5. Test for compiler features
# Visual C++ compiler options have changed over the years. Check
# which options are supported by the compiler in use.
#
# The following macros are set:







>


>
>
>
>







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
!endif # $(TCLINSTALL)
!endif # !$(DOING_TCL)

!endif # NMAKEHLPC

# We always build nmakehlp even if it exists since we do not know
# what source it was built from.
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif
!else
!if [copy $(NMAKEHLPC:nmakehlp.c=x86_64-w64-mingw32-nmakehlp.exe) nmakehlp.exe >NUL]
!endif
!endif

################################################################
# 5. Test for compiler features
# Visual C++ compiler options have changed over the years. Check
# which options are supported by the compiler in use.
#
# The following macros are set:
648
649
650
651
652
653
654


























































































































655
656
657
658
659
660
661
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
# If compiler has enabled link time optimization, linker must too with -ltcg
!ifdef CC_GL_OPT_ENABLED
!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS     = $(LINKERFLAGS) -ltcg
!endif
!endif



























































































































########################################################################
# 6. Parse the OPTS macro to work out the requested build configuration.
# Based on this, we will construct the actual switches to be passed to the
# compiler and linker using the macros defined in the previous section.
# The following macros are defined by this section based on OPTS
# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
#                1 -> build as a static library and shell
# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
# DEBUG - 1 -> debug build, 0 -> release builds
# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
# PROFILE - 1 -> generate profiling info, 0 -> no profiling
# PGO     - 1 -> profile based optimization, 0 -> no
# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
#           0 -> link to static C runtime for static Tcl build.
#           Does not impact shared Tcl builds (STATIC_BUILD == 0)

# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
#           in the Tcl shell. 0 -> keep them as shared libraries
#           Does not impact shared Tcl builds.
# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
#           0 -> Use the non-thread allocator.
# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
#           C runtime, 0 -> use the debug C runtime.
# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
# CONFIG_CHECK - 1 -> check current build configuration against Tcl
#           configuration (ignored for Tcl itself)
# _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build
#           (CRT library should support this, not needed for Tcl 9.x)
# TCL_UTF_MAX=4 - forces a build allowing 4-byte UTF-8 sequences internally.
#           (Not needed for Tcl 9.x)
# Further, LINKERFLAGS are modified based on above.

# Default values for all the above
STATIC_BUILD	= 0
TCL_THREADS	= 1
DEBUG		= 0
SYMBOLS		= 0







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|













>

|
|









<
<







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819


820
821
822
823
824
825
826
# If compiler has enabled link time optimization, linker must too with -ltcg
!ifdef CC_GL_OPT_ENABLED
!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS     = $(LINKERFLAGS) -ltcg
!endif
!endif


################################################################
# 6. Extract various version numbers from headers
# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
# respectively. For extensions, versions are extracted from the
# configure.in or configure.ac from the TEA configuration if it
# exists, and unset otherwise.
# Sets the following macros:
# TCL_MAJOR_VERSION
# TCL_MINOR_VERSION
# TCL_RELEASE_SERIAL
# TCL_PATCH_LEVEL
# TCL_PATCH_LETTER
# TCL_VERSION
# TK_MAJOR_VERSION
# TK_MINOR_VERSION
# TK_RELEASE_SERIAL
# TK_PATCH_LEVEL
# TK_PATCH_LETTER
# TK_VERSION
# DOTVERSION - set as (for example) 2.5
# VERSION - set as (for example 25)
#--------------------------------------------------------------

!if [echo REM = This file is generated from rules.vc > versions.vc]
!endif
!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" "define TCL_MAJOR_VERSION" >> versions.vc]
!endif
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
!endif
!if [echo TCL_RELEASE_SERIAL = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_RELEASE_SERIAL >> versions.vc]
!endif
!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
!endif

!if defined(_TK_H)
!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) "define TK_MAJOR_VERSION" >> versions.vc]
!endif
!if [echo TK_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
!endif
!if [echo TK_RELEASE_SERIAL = \>> versions.vc] \
   && [nmakehlp -V "$(_TK_H)" TK_RELEASE_SERIAL >> versions.vc]
!endif
!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
!endif
!endif # _TK_H

!include versions.vc

TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
!if [nmakehlp -f $(TCL_PATCH_LEVEL) "a"]
TCL_PATCH_LETTER = a
!elseif [nmakehlp -f $(TCL_PATCH_LEVEL) "b"]
TCL_PATCH_LETTER = b
!else
TCL_PATCH_LETTER = .
!endif

!if defined(_TK_H)

TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!if [nmakehlp -f $(TK_PATCH_LEVEL) "a"]
TK_PATCH_LETTER = a
!elseif [nmakehlp -f $(TK_PATCH_LEVEL) "b"]
TK_PATCH_LETTER = b
!else
TK_PATCH_LETTER = .
!endif

!endif

# Set DOTVERSION and VERSION
!if $(DOING_TCL)

DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
VERSION = $(TCL_VERSION)

!elseif $(DOING_TK)

DOTVERSION = $(TK_DOTVERSION)
VERSION = $(TK_VERSION)

!else # Doing a non-Tk extension

# If parent makefile has not defined DOTVERSION, try to get it from TEA
# first from a configure.in file, and then from configure.ac
!ifndef DOTVERSION
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
!endif
!endif
!include versions.vc
!endif # DOTVERSION
VERSION         = $(DOTVERSION:.=)

!endif # $(DOING_TCL) ... etc.

# Windows RC files have 3 version components. Ensure this irrespective
# of how many components the package has specified. Basically, ensure
# minimum 4 components by appending 4 0's and then pick out the first 4.
# Also take care of the fact that DOTVERSION may have "a" or "b" instead
# of "." separating the version components.
DOTSEPARATED=$(DOTVERSION:a=.)
DOTSEPARATED=$(DOTSEPARATED:b=.)
!if [echo RCCOMMAVERSION = \> versions.vc] \
  || [for /f "tokens=1,2,3,4,5* delims=." %a in ("$(DOTSEPARATED).0.0.0.0") do echo %a,%b,%c,%d >> versions.vc]
!error *** Could not generate RCCOMMAVERSION ***
!endif
!include versions.vc

########################################################################
# 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 and Wish shell. 0 -> keep them as shared libraries. Does
#           not impact shared Tcl builds. Implied by STATIC_BUILD since Tcl 8.7.
# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
#           0 -> Use the non-thread allocator.
# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
#           C runtime, 0 -> use the debug C runtime.
# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
# CONFIG_CHECK - 1 -> check current build configuration against Tcl
#           configuration (ignored for Tcl itself)
# _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build
#           (CRT library should support this, not needed for Tcl 9.x)


# Further, LINKERFLAGS are modified based on above.

# Default values for all the above
STATIC_BUILD	= 0
TCL_THREADS	= 1
DEBUG		= 0
SYMBOLS		= 0
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743





744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
!if [nmakehlp -f $(OPTS) "nomsvcrt"]
!message *** Doing nomsvcrt
MSVCRT		= 0
!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
!else
!if $(STATIC_BUILD)
MSVCRT		= 0
!endif
!endif
!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]

!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES	= 1
!endif

!if [nmakehlp -f $(OPTS) "nothreads"]
!message *** Compile explicitly for non-threaded tcl
TCL_THREADS = 0
USE_THREAD_ALLOC= 0
!endif






!if "$(TCL_MAJOR_VERSION)" == "8"
!if [nmakehlp -f $(OPTS) "time64bit"]
!message *** Force 64-bit time_t
_USE_64BIT_TIME_T = 1
!endif

!if [nmakehlp -f $(OPTS) "utfmax"]
!message *** Force allowing 4-byte UTF-8 sequences internally
TCL_UTF_MAX = 4
!endif
!endif

# Yes, it's weird that the "symbols" option controls DEBUG and
# the "pdbs" option controls SYMBOLS. That's historical.
!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1







|
















>
>
>
>
>
|




<
<
<
<
<







856
857
858
859
860
861
862
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
!if [nmakehlp -f $(OPTS) "nomsvcrt"]
!message *** Doing nomsvcrt
MSVCRT		= 0
!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
!else
!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 [nmakehlp -f $(OPTS) "tcl8"]
!message *** Build for Tcl8
TCL_BUILD_FOR = 8
!endif

!if $(TCL_MAJOR_VERSION) == 8
!if [nmakehlp -f $(OPTS) "time64bit"]
!message *** Force 64-bit time_t
_USE_64BIT_TIME_T = 1
!endif





!endif

# Yes, it's weird that the "symbols" option controls DEBUG and
# the "pdbs" option controls SYMBOLS. That's historical.
!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!endif

################################################################
# 7. Parse the STATS macro to configure code instrumentation
# The following macros are set by this section:
# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
#                 0 -> disables
# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
#                     0 -> disables

# Default both are off







|







968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!endif

################################################################
# 8. Parse the STATS macro to configure code instrumentation
# The following macros are set by this section:
# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
#                 0 -> disables
# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
#                     0 -> disables

# Default both are off
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
!else
TCL_COMPILE_DEBUG   = 0
!endif

!endif

####################################################################
# 8. Parse the CHECKS macro to configure additional compiler checks
# The following macros are set by this section:
# WARNINGS - compiler switches that control the warnings level
# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
#                     0 -> enable deprecated functions

# Defaults - Permit deprecated functions and warning level 3
TCL_NO_DEPRECATED	    = 0







|







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
!else
TCL_COMPILE_DEBUG   = 0
!endif

!endif

####################################################################
# 9. Parse the CHECKS macro to configure additional compiler checks
# The following macros are set by this section:
# WARNINGS - compiler switches that control the warnings level
# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
#                     0 -> enable deprecated functions

# Defaults - Permit deprecated functions and warning level 3
TCL_NO_DEPRECATED	    = 0
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
!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.,
#







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1030
1031
1032
1033
1034
1035
1036





























































































1037
1038
1039
1040
1041
1042
1043
!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
!message *** Doing 64bit portability warnings
WARNINGS		    = $(WARNINGS) -Wp64
!endif

!endif































































































################################################################
# 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.,
#
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
SUFX	    = $(SUFX:s=)
EXT	    = dll
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if !$(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
!endif

!if !$(TCL_THREADS) || $(TCL_VERSION) > 86
TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)







|







1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
SUFX	    = $(SUFX:s=)
EXT	    = dll
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if $(MSVCRT) && $(TCL_VERSION) > 86 || !$(MSVCRT) && $(TCL_VERSION) < 87
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
!endif

!if !$(TCL_THREADS) || $(TCL_VERSION) > 86
TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
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
!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
!endif
!include nmakehlp.out

# The name of the stubs library for the project being built
STUBPREFIX      = $(PROJECT)stub


# Set up paths to various Tcl executables and libraries needed by extensions

!if $(DOING_TCL)





TCLSHNAME       = $(PROJECT)sh$(VERSION)$(SUFX).exe
TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)



TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib



TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"

!else # !$(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl

# When building extensions, we need to locate tclsh. Depending on version
# of Tcl we are building against, this may or may not have a "t" suffix.
# Try various possibilities in turn.
TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!if !exist("$(TCLSH)")
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif


TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib



TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\lib
TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib

TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
TCL_INCLUDES    = -I"$(_TCLDIR)\include"

!else # Building against Tcl sources

TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!if !exist($(TCLSH))
TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif

TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib



TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\library
TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib

TCLTOOLSDIR	= $(_TCLDIR)\tools
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"

!endif # TCLINSTALL




tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"


!endif # $(DOING_TCL)

# We need a tclsh that will run on the host machine as part of the build.
# IX86 runs on all architectures.
!ifndef TCLSH_NATIVE
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
TCLSH_NATIVE	= $(TCLSH)
!else
!error You must explicitly set TCLSH_NATIVE for cross-compilation
!endif
!endif

# Do the same for Tk and Tk extensions that require the Tk libraries
!if $(DOING_TK) || $(NEED_TK)
WISHNAMEPREFIX = wish
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)









TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib

TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib


!if $(DOING_TK)
WISH 		= $(OUT_DIR)\$(WISHNAME)
TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
TK_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"


!else # effectively NEED_TK

!if $(TKINSTALL) # Building against installed Tk
WISH		= $(_TKDIR)\bin\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\include"


!else # Building against Tk sources

WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"


!endif # TKINSTALL

tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"

!endif # $(DOING_TK)
!endif # $(DOING_TK) || $(NEED_TK)

# Various output paths
PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)






PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)


PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib



PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

# If extension parent makefile has not defined a resource definition file,
# we will generate one from standard template.
!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
!ifdef RCFILE
RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)







>

>
|
>
>
>

>





>

>

>
>
>















>

>
>
>









>









>

>
>
>









>





>
>
>

>

















|
>
>
>
>
>
>
>
>
>

>
|
>






|
>














>
>

>










>
>

>







|
>
>
>
>
>
>


>

>
>
>







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
!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
#

# TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc
TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip

!if $(DOING_TCL)
TCLSHNAME       = $(PROJECT)sh$(VERSION)$(SUFX).exe
TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)
TCLSCRIPTZIP    = $(OUT_DIR)\$(TCLSCRIPTZIPNAME)

!if $(TCL_MAJOR_VERSION) == 8
TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
!else
TCLSTUBLIBNAME	= $(STUBPREFIX).lib
!endif
TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"

!else # !$(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl

# When building extensions, we need to locate tclsh. Depending on version
# of Tcl we are building against, this may or may not have a "t" suffix.
# Try various possibilities in turn.
TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!if !exist("$(TCLSH)")
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif

!if $(TCL_MAJOR_VERSION) == 8
TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
!else
TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub.lib
!endif
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\lib
TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
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
!if $(TCL_MAJOR_VERSION) == 8
TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
!else
TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub.lib
!endif
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

!if !$(STATIC_BUILD) && "$(TCL_BUILD_FOR)" == "8"
tcllibs = "$(TCLSTUBLIB)"
!else
tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
!endif

!endif # $(DOING_TCL)

# We need a tclsh that will run on the host machine as part of the build.
# IX86 runs on all architectures.
!ifndef TCLSH_NATIVE
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
TCLSH_NATIVE	= $(TCLSH)
!else
!error You must explicitly set TCLSH_NATIVE for cross-compilation
!endif
!endif

# Do the same for Tk and Tk extensions that require the Tk libraries
!if $(DOING_TK) || $(NEED_TK)
WISHNAMEPREFIX = wish
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
TKLIBNAME8	= tk$(TK_VERSION)$(SUFX).$(EXT)
TKLIBNAME9	= tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
TKLIBNAME	= tk$(TK_VERSION)$(SUFX).$(EXT)
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib
!else
TKLIBNAME	= tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
TKIMPLIBNAME	= tcl9tk$(TK_VERSION)$(SUFX).lib
!endif
!if $(TK_MAJOR_VERSION) == 8
TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
!else
TKSTUBLIBNAME	= tkstub.lib
!endif

!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)"
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
PRJLIBNAME8	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIBNAME9	= tcl9$(PROJECT)$(VERSION)$(SUFX).$(EXT)
!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
PRJLIBNAME	= $(PRJLIBNAME8)
!else
PRJLIBNAME	= $(PRJLIBNAME9)
!endif
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

!if $(TCL_MAJOR_VERSION) == 8
PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
!else
PRJSTUBLIBNAME	= $(STUBPREFIX).lib
!endif
PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

# If extension parent makefile has not defined a resource definition file,
# we will generate one from standard template.
!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
!ifdef RCFILE
RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
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
# 12. Set up actual options to be passed to the compiler and linker
# Now we have all the information we need, set up the actual flags and
# options that we will pass to the compiler and linker. The main
# makefile should use these in combination with whatever other flags
# and switches are specific to it.
# The following macros are defined, names are for historical compatibility:
# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
# crt - Compiler switch that selects the appropriate C runtime
# cdebug - Compiler switches related to debug AND optimizations
# cwarn - Compiler switches that set warning levels
# cflags - complete compiler switches (subsumes cdebug and cwarn)
# ldebug - Linker switches controlling debug information and optimization
# lflags - complete linker switches (subsumes ldebug) except subsystem type
# dlllflags - complete linker switches to build DLLs (subsumes lflags)
# conlflags - complete linker switches for console program (subsumes lflags)
# guilflags - complete linker switches for GUI program (subsumes lflags)
# baselibs - minimum Windows libraries required. Parent makefile can
#    define PRJ_LIBS before including rules.rc if additional libs are needed

OPTDEFINES	= /DSTDC_HEADERS
!if $(VCVERSION) >= 1600
OPTDEFINES	= $(OPTDEFINES) /DHAVE_STDINT_H=1
!else
OPTDEFINES	= $(OPTDEFINES) /DMP_NO_STDINT=1
!endif
!if $(VCVERSION) >= 1800
OPTDEFINES	= $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1
!endif







|












|
|







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
# 12. Set up actual options to be passed to the compiler and linker
# Now we have all the information we need, set up the actual flags and
# options that we will pass to the compiler and linker. The main
# makefile should use these in combination with whatever other flags
# and switches are specific to it.
# The following macros are defined, names are for historical compatibility:
# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration options
# crt - Compiler switch that selects the appropriate C runtime
# cdebug - Compiler switches related to debug AND optimizations
# cwarn - Compiler switches that set warning levels
# cflags - complete compiler switches (subsumes cdebug and cwarn)
# ldebug - Linker switches controlling debug information and optimization
# lflags - complete linker switches (subsumes ldebug) except subsystem type
# dlllflags - complete linker switches to build DLLs (subsumes lflags)
# conlflags - complete linker switches for console program (subsumes lflags)
# guilflags - complete linker switches for GUI program (subsumes lflags)
# baselibs - minimum Windows libraries required. Parent makefile can
#    define PRJ_LIBS before including rules.rc if additional libs are needed

OPTDEFINES	= /DSTDC_HEADERS /DUSE_NMAKE=1
!if $(VCVERSION) > 1600
OPTDEFINES	= $(OPTDEFINES) /DHAVE_STDINT_H=1
!else
OPTDEFINES	= $(OPTDEFINES) /DMP_NO_STDINT=1
!endif
!if $(VCVERSION) >= 1800
OPTDEFINES	= $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1
!endif
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
OPTDEFINES	= $(OPTDEFINES) /DUSE_THREAD_ALLOC=1
!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) /DSTATIC_BUILD
!elseif $(TCL_VERSION) > 86
OPTDEFINES	= $(OPTDEFINES) /DTCL_WITH_EXTERNAL_TOMMATH
!if "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) /DMP_64BIT
!endif
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) /DTCL_NO_DEPRECATED
!endif








|







1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
OPTDEFINES	= $(OPTDEFINES) /DUSE_THREAD_ALLOC=1
!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) /DSTATIC_BUILD
!elseif $(TCL_VERSION) > 86
OPTDEFINES	= $(OPTDEFINES) /DTCL_WITH_EXTERNAL_TOMMATH
!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
OPTDEFINES	= $(OPTDEFINES) /DMP_64BIT
!endif
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) /DTCL_NO_DEPRECATED
!endif

1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359



1360
1361
1362
1363
1364
1365
1366
!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) /DNO_STRTOI64=1
!endif

!if "$(TCL_MAJOR_VERSION)" == "8"
!if "$(_USE_64BIT_TIME_T)" == "1"
OPTDEFINES	= $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
!endif
!if "$(TCL_UTF_MAX)" == "4"
OPTDEFINES	= $(OPTDEFINES) /DTCL_UTF_MAX=4
!endif

# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
COMPILERFLAGS  = /D_ATL_XP_TARGETING
!endif




# Like the TEA system only set this non empty for non-Tk extensions
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \







|






|



<
<
<




>
>
>







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
!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) /DNO_STRTOI64=1
!endif

!if $(TCL_MAJOR_VERSION) == 8
!if "$(_USE_64BIT_TIME_T)" == "1"
OPTDEFINES	= $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
!endif




# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
COMPILERFLAGS  = /D_ATL_XP_TARGETING
!endif
!if "$(TCL_BUILD_FOR)" == "8"
OPTDEFINES	= $(OPTDEFINES) /DTCL_MAJOR_VERSION=8
!endif

# Like the TEA system only set this non empty for non-Tk extensions
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
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
cdebug = $(OPTIMIZATIONS)
!if $(SYMBOLS)
cdebug = $(cdebug) -Zi
!endif

!endif # $(DEBUG)

# cwarn includes default warning levels.
cwarn = $(WARNINGS)

!if "$(MACHINE)" == "AMD64"
# Disable pointer<->int warnings related to cast between different sizes
# There are a gadzillion of these due to use of ClientData and
# clutter up compiler
# output increasing chance of a real warning getting lost. So disable them.
# Eventually some day, Tcl will be 64-bit clean.
cwarn = $(cwarn) -wd4311 -wd4312
!endif

### Common compiler options that are architecture specific
!if "$(MACHINE)" == "ARM"
carch = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
!else
carch =
!endif






!if $(DEBUG)
# Turn warnings into errors
cwarn = $(cwarn) -WX
!endif

INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
!if !$(DOING_TCL) && !$(DOING_TK)
INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)"
!endif

# These flags are defined roughly in the order of the pre-reform
# rules.vc/makefile.vc to help visually compare that the pre- and
# post-reform build logs

# cflags contains generic flags used for building practically all object files
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)





# appcflags contains $(cflags) and flags for building the application
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
# flags used for building shared object files The two differ in the
# BUILD_$(PROJECT) macro which should be defined only for the shared
# library *implementation* and not for its caller interface








|
|

|














>
>
>
>
>

















>
>
>
>







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
cdebug = $(OPTIMIZATIONS)
!if $(SYMBOLS)
cdebug = $(cdebug) -Zi
!endif

!endif # $(DEBUG)

# cwarn includes default warning levels, also C4090 (buggy) and C4146 is useless.
cwarn = $(WARNINGS) -wd4090 -wd4146

!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
# Disable pointer<->int warnings related to cast between different sizes
# There are a gadzillion of these due to use of ClientData and
# clutter up compiler
# output increasing chance of a real warning getting lost. So disable them.
# Eventually some day, Tcl will be 64-bit clean.
cwarn = $(cwarn) -wd4311 -wd4312
!endif

### Common compiler options that are architecture specific
!if "$(MACHINE)" == "ARM"
carch = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
!else
carch =
!endif

# cpuid is only available on intel machines
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "AMD64"
carch = $(carch) /DHAVE_CPUID=1
!endif

!if $(DEBUG)
# Turn warnings into errors
cwarn = $(cwarn) -WX
!endif

INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
!if !$(DOING_TCL) && !$(DOING_TK)
INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)"
!endif

# These flags are defined roughly in the order of the pre-reform
# rules.vc/makefile.vc to help visually compare that the pre- and
# post-reform build logs

# cflags contains generic flags used for building practically all object files
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)

!if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7
cflags = $(cflags) -DTcl_Size=int
!endif

# appcflags contains $(cflags) and flags for building the application
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
# flags used for building shared object files The two differ in the
# BUILD_$(PROJECT) macro which should be defined only for the shared
# library *implementation* and not for its caller interface

1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
# here irrespective of the OPTS setting.
#
# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
# without stating why. Tcl itself compiled stubs libs with this flag.
# so we do not remove it from cflags. -GL may prevent extensions
# compiled with one VC version to fail to link against stubs library
# compiled with another VC version. Check for this and fix accordingly.
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS)

# Link flags

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else
ldebug	= -release -opt:ref -opt:icf,3







|







1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
# 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 /GL- /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS)

# Link flags

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else
ldebug	= -release -opt:ref -opt:icf,3
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
!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.







<
<
<
<
<
<
<
<
<
<
<
<







1580
1581
1582
1583
1584
1585
1586












1587
1588
1589
1590
1591
1592
1593
!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

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows

# Libraries that are required for every image.
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551

1552
1553




1554
1555

1556
1557




1558
1559
1560
1561
1562
1563
1564
1565


1566
1567
1568
1569
1570
1571
1572

LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)

CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
	    $(TCL_INCLUDES) \
	    /DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
	    /DCOMMAVERSION=$(RCCOMMAVERSION) \
	    /DDOTVERSION=\"$(DOTVERSION)\" \
	    /DVERSION=\"$(VERSION)\" \
	    /DSUFX=\"$(SUFX)\" \
	    /DPROJECT=\"$(PROJECT)\" \
	    /DPRJLIBNAME=\"$(PRJLIBNAME)\"

!ifndef DEFAULT_BUILD_TARGET
DEFAULT_BUILD_TARGET = $(PROJECT)
!endif

default-target: $(DEFAULT_BUILD_TARGET)

!if $(MULTIPLATFORM_INSTALL)
default-pkgindex:

	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl




!else
default-pkgindex:

	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl




!endif

default-pkgindex-tea:
	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
@PACKAGE_VERSION@    $(DOTVERSION)
@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
@PKG_LIB_FILE@       $(PRJLIBNAME)


<<

default-install: default-install-binaries default-install-libraries
!if $(SYMBOLS)
default-install: default-install-pdbs
!endif








|
















>

|
>
>
>
>


>

|
>
>
>
>








>
>







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

LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)

CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
	    $(TCL_INCLUDES) /DSTATIC_BUILD=$(STATIC_BUILD) \
	    /DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
	    /DCOMMAVERSION=$(RCCOMMAVERSION) \
	    /DDOTVERSION=\"$(DOTVERSION)\" \
	    /DVERSION=\"$(VERSION)\" \
	    /DSUFX=\"$(SUFX)\" \
	    /DPROJECT=\"$(PROJECT)\" \
	    /DPRJLIBNAME=\"$(PRJLIBNAME)\"

!ifndef DEFAULT_BUILD_TARGET
DEFAULT_BUILD_TARGET = $(PROJECT)
!endif

default-target: $(DEFAULT_BUILD_TARGET)

!if $(MULTIPLATFORM_INSTALL)
default-pkgindex:
	@echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } >> $(OUT_DIR)\pkgIndex.tcl
!else
default-pkgindex:
	@echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } >> $(OUT_DIR)\pkgIndex.tcl
!endif

default-pkgindex-tea:
	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
@PACKAGE_VERSION@    $(DOTVERSION)
@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
@PKG_LIB_FILE@       $(PRJLIBNAME)
@PKG_LIB_FILE8@      $(PRJLIBNAME8)
@PKG_LIB_FILE9@      $(PRJLIBNAME9)
<<

default-install: default-install-binaries default-install-libraries
!if $(SYMBOLS)
default-install: default-install-pdbs
!endif

1595
1596
1597
1598
1599
1600
1601


1602
1603
1604
1605
1606
1607
1608
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-pdbs:
	@echo Installing PDBs to '$(LIB_INSTALL_DIR)'
	@if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
	@$(CPY) "$(OUT_DIR)\*.pdb" "$(LIB_INSTALL_DIR)\"



default-install-docs-html:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-docs-n:







>
>







1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-pdbs:
	@echo Installing PDBs to '$(LIB_INSTALL_DIR)'
	@if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
	@$(CPY) "$(OUT_DIR)\*.pdb" "$(LIB_INSTALL_DIR)\"

# "emacs font-lock highlighting fix

default-install-docs-html:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-docs-n:
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
!if !$(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl
!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
!endif
!else # !$(TCLINSTALL) - building against Tcl source
!if exist("$(OUT_DIR)\tcl.nmake")
TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
!endif
!endif # TCLINSTALL

!if $(CONFIG_CHECK)
!ifdef TCLNMAKECONFIG
!include $(TCLNMAKECONFIG)








|
|







1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
!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("$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake")
TCLNMAKECONFIG	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake"
!endif
!endif # TCLINSTALL

!if $(CONFIG_CHECK)
!ifdef TCLNMAKECONFIG
!include $(TCLNMAKECONFIG)

Changes to win/stubs.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
#include "tkInt.h"

/*
 * Undocumented Xlib internal function
 */

int
_XInitImageFuncPtrs(
    XImage *image)
{
    (void)image;

    return Success;
}

/*
 * From Xutil.h
 */

void
XSetWMClientMachine(
    Display *display,
    Window w,
    XTextProperty *text_prop)
{
	(void)display;
	(void)w;
	(void)text_prop;
}

Status
XStringListToTextProperty(
    char **list,
    int count,
    XTextProperty *text_prop_return)
{
    (void)list;
    (void)count;
    (void)text_prop_return;

    return Success;
}

/*
 * From Xlib.h
 */

int
XChangeProperty(
    Display *display,
    Window w,
    Atom property,
    Atom type,
    int format,
    int mode,
    _Xconst unsigned char *data,
    int nelements)
{
    (void)display;
    (void)w;
    (void)property;
    (void)type;
    (void)format;
    (void)mode;
    (void)data;
    (void)nelements;

    return Success;
}

XIC
XCreateIC(XIM xim, ...)
{
    (void)xim;
    return NULL;
}

int
XDeleteProperty(
    Display *display,
    Window w,
    Atom property)
{
    (void)display;
    (void)w;
    (void)property;

    return Success;
}

Bool
XFilterEvent(
    XEvent *event,
    Window window)
{
    (void)event;
    (void)window;

    return 0;
}

int
XForceScreenSaver(
    Display *display,
    int mode)
{
    (void)display;
    (void)mode;

    return Success;
}

int
XFreeCursor(
    Display *display,
    Cursor cursor)
{
    (void)display;
    (void)cursor;

    return Success;
}

GContext
XGContextFromGC(
    GC gc)
{
    (void)gc;

    return (GContext) NULL;
}

char *
XGetAtomName(
    Display *display,
    Atom atom)
{
    (void)display;
    (void)atom;

    return NULL;
}

int
XGetWindowAttributes(
    Display *display,
    Window w,
    XWindowAttributes *window_attributes_return)
{
    (void)display;
    (void)w;
    (void)window_attributes_return;

    return Success;
}

Status
XGetWMColormapWindows(
    Display *display,
    Window w,
    Window **windows_return,
    int *count_return)
{
    (void)display;
    (void)w;
    (void)windows_return;
    (void)count_return;

    return Success;
}

int
XIconifyWindow(
    Display *display,
    Window w,
    int screen_number)
{
    (void)display;
    (void)w;
    (void)screen_number;

    return Success;
}

XHostAddress *
XListHosts(
    Display *display,
    int *nhosts_return,
    Bool *state_return)
{
    (void)display;
    (void)nhosts_return;
    (void)state_return;

    return NULL;
}

int
XLookupColor(
    Display *display,
    Colormap colormap,
    _Xconst char *color_name,
    XColor *exact_def_return,
    XColor *screen_def_return)
{
    (void)display;
    (void)colormap;
    (void)color_name;
    (void)exact_def_return;
    (void)screen_def_return;

    return Success;
}

int
XNextEvent(
    Display *display,
    XEvent *event_return)
{
    (void)display;
    (void)event_return;

    return Success;
}

int
XPutBackEvent(
    Display *display,
    XEvent *event)
{
    (void)display;
    (void)event;

    return Success;
}

int
XQueryColors(
    Display *display,
    Colormap colormap,
    XColor *defs_in_out,
    int ncolors)
{
    (void)display;
    (void)colormap;
    (void)defs_in_out;
    (void)ncolors;

    return Success;
}

int
XQueryTree(
    Display *display,
    Window w,
    Window *root_return,
    Window *parent_return,
    Window **children_return,
    unsigned int *nchildren_return)
{
    (void)display;
    (void)w;
    (void)root_return;
    (void)parent_return;
    (void)children_return;
    (void)nchildren_return;

    return Success;
}

int
XRefreshKeyboardMapping(
    XMappingEvent *event_map)
{
    (void)event_map;

    return Success;
}

Window
XRootWindow(
    Display *display,
    int screen_number)
{
    (void)display;
    (void)screen_number;

    return (Window) NULL;
}

int
XSelectInput(
    Display *display,
    Window w,
    long event_mask)
{
    (void)display;
    (void)w;
    (void)event_mask;

    return Success;
}

int
XSendEvent(
    Display *display,
    Window w,
    Bool propagate,
    long event_mask,
    XEvent *event_send)
{
    (void)display;
    (void)w;
    (void)propagate;
    (void)event_mask;
    (void)event_send;

    return Success;
}

int
XSetCommand(
    Display *display,
    Window w,
    char **argv,
    int argc)
{
    (void)display;
    (void)w;
    (void)argv;
    (void)argc;

    return Success;
}

XErrorHandler
XSetErrorHandler(
    XErrorHandler handler)
{
    (void)handler;

    return NULL;
}

int
XSetIconName(
    Display *display,
    Window w,
    _Xconst char *icon_name)
{
    (void)display;
    (void)w;
    (void)icon_name;

    return Success;
}

int
XSetWindowBackground(
    Display *display,
    Window w,
    unsigned long background_pixel)
{
    (void)display;
    (void)w;
    (void)background_pixel;

    return Success;
}

int
XSetWindowBackgroundPixmap(
    Display *display,
    Window w,
    Pixmap background_pixmap)
{
    (void)display;
    (void)w;
    (void)background_pixmap;

    return Success;
}

int
XSetWindowBorder(
    Display *display,
    Window w,
    unsigned long border_pixel)
{
    (void)display;
    (void)w;
    (void)border_pixel;

    return Success;
}

int
XSetWindowBorderPixmap(
    Display *display,
    Window w,
    Pixmap border_pixmap)
{
    (void)display;
    (void)w;
    (void)border_pixmap;

    return Success;
}

int
XSetWindowBorderWidth(
    Display *display,
    Window w,
    unsigned int width)
{
    (void)display;
    (void)w;
    (void)width;

    return Success;
}

int
XSetWindowColormap(
    Display *display,
    Window w,
    Colormap colormap)
{
    (void)display;
    (void)w;
    (void)colormap;

    return Success;
}

Bool
XTranslateCoordinates(
    Display *display,
    Window src_w,
    Window dest_w,
    int src_x,
    int src_y,
    int *dest_x_return,
    int *dest_y_return,
    Window *child_return)
{
    (void)display;
    (void)src_w;
    (void)dest_w;
    (void)src_x;
    (void)src_y;
    (void)dest_x_return;
    (void)dest_y_return;
    (void)child_return;

    return 0;
}

int
XWindowEvent(
    Display *display,
    Window w,
    long event_mask,
    XEvent *event_return)
{
    (void)display;
    (void)w;
    (void)event_mask;
    (void)event_return;

    return Success;
}

int
XWithdrawWindow(
    Display *display,
    Window w,
    int screen_number)
{
    (void)display;
    (void)w;
    (void)screen_number;

    return Success;
}

int
XmbLookupString(
    XIC ic,
    XKeyPressedEvent *event,
    char *buffer_return,
    int bytes_buffer,
    KeySym *keysym_return,
    Status *status_return)
{
    (void)ic;
    (void)event;
    (void)buffer_return;
    (void)bytes_buffer;
    (void)keysym_return;
    (void)status_return;

    return Success;
}

int
XGetWindowProperty(
    Display *display,
    Window w,
    Atom property,
    long long_offset,
    long long_length,
    Bool del,
    Atom req_type,
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    unsigned char **prop_return)
{
    (void)display;
    (void)w;
    (void)property;
    (void)long_offset;
    (void)long_length;
    (void)del;
    (void)req_type;

    *actual_type_return = None;
    *actual_format_return = 0;
    *nitems_return = 0;
    *bytes_after_return = 0;
    *prop_return = NULL;
    return BadValue;
}

/*
 * The following functions were implemented as macros under Windows.
 */

int
XFlush(
    Display *display)
{
    (void)display;

    return 0;
}

int
XGrabServer(
    Display *display)
{
    (void)display;

    return 0;
}

int
XUngrabServer(
    Display *display)
{
    (void)display;

    return 0;
}

int
XFree(
    void *data)
{
	if ((data) != NULL) {
		ckfree(data);
	}
    return 0;
}

int
XNoOp(
    Display *display)
{
    display->request++;
    return 0;
}

XAfterFunction
XSynchronize(
    Display *display,
    Bool onoff)
{
    (void)onoff;

    display->request++;
    return NULL;
}

int
XSync(
    Display *display,
    Bool discard)
{
    (void)discard;

    display->request++;
    return 0;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

int
XOffsetRegion(
    Region rgn,
	int dx,
	int dy)
{
    (void)rgn;
    (void)dx;
    (void)dy;

	return 0;
}








|

<
<









|
|
|

<
<
<




|
|
|

<
<
<
<









|
|
|
|
|
|
|
|

<
<
<
<
<
<
<
<
<




|

<





|
|
|

<
<
<
<





|
|

<
<
<





|
|

<
<
<





|
|

<
<
<





|

<
<





|
|

<
<
<





|
|
|

<
<
<
<





|
|
|
|

<
<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|
|
|

<
<
<
<
<
<





|
|

<
<
<





|
|

<
<
<





|
|
|
|

<
<
<
<
<





|
|
|
|
|
|

<
<
<
<
<
<
<





|

<
<





|
|

<
<
<





|
|
|

<
<
<
<





|
|
|
|
|

<
<
<
<
<
<





|
|
|
|

<
<
<
<
<





|

<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|
|
|
|
|
|

<
<
<
<
<
<
<
<
<





|
|
|
|

<
<
<
<
<





|
|
|

<
<
<
<





|
|
|
|
|
|

<
<
<
<
<
<
<





|
|
|
|
|
|
|






<
<
<
<
<
<
<
<














|

<
<





|

<
<





|

<
<







|









|






|

<
|
<






|

<
|
<












|
|
|

<
<
<
<


1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29
30
31




32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49









50
51
52
53
54
55

56
57
58
59
60
61
62
63
64




65
66
67
68
69
70
71
72



73
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88



89
90
91
92
93
94
95


96
97
98
99
100
101
102
103



104
105
106
107
108
109
110
111
112




113
114
115
116
117
118
119
120
121
122





123
124
125
126
127
128
129
130
131




132
133
134
135
136
137
138
139
140




141
142
143
144
145
146
147
148
149
150
151






152
153
154
155
156
157
158
159



160
161
162
163
164
165
166
167



168
169
170
171
172
173
174
175
176
177





178
179
180
181
182
183
184
185
186
187
188
189







190
191
192
193
194
195
196


197
198
199
200
201
202
203
204



205
206
207
208
209
210
211
212
213




214
215
216
217
218
219
220
221
222
223
224






225
226
227
228
229
230
231
232
233
234





235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250




251
252
253
254
255
256
257
258
259




260
261
262
263
264
265
266
267
268




269
270
271
272
273
274
275
276
277




278
279
280
281
282
283
284
285
286




287
288
289
290
291
292
293
294
295




296
297
298
299
300
301
302
303
304




305
306
307
308
309
310
311
312
313
314
315
316
317
318









319
320
321
322
323
324
325
326
327
328





329
330
331
332
333
334
335
336
337




338
339
340
341
342
343
344
345
346
347
348
349







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367








368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383


384
385
386
387
388
389
390


391
392
393
394
395
396
397


398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

424

425
426
427
428
429
430
431
432

433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449




450
451
#include "tkInt.h"

/*
 * Undocumented Xlib internal function
 */

int
_XInitImageFuncPtrs(
    TCL_UNUSED(XImage *))
{


    return Success;
}

/*
 * From Xutil.h
 */

void
XSetWMClientMachine(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(XTextProperty *))
{



}

Status
XStringListToTextProperty(
    TCL_UNUSED(char **),
    TCL_UNUSED(int),
    TCL_UNUSED(XTextProperty *))
{




    return Success;
}

/*
 * From Xlib.h
 */

int
XChangeProperty(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom),
    TCL_UNUSED(Atom),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(_Xconst unsigned char *),
    TCL_UNUSED(int))
{









    return Success;
}

XIC
XCreateIC(TCL_UNUSED(XIM), ...)
{

    return NULL;
}

int
XDeleteProperty(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom))
{




    return Success;
}

Bool
XFilterEvent(
    TCL_UNUSED(XEvent *),
    TCL_UNUSED(Window))
{



    return 0;
}

int
XForceScreenSaver(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int))
{



    return Success;
}

int
XFreeCursor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Cursor))
{



    return Success;
}

GContext
XGContextFromGC(
    TCL_UNUSED(GC))
{


    return (GContext) NULL;
}

char *
XGetAtomName(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Atom))
{



    return NULL;
}

int
XGetWindowAttributes(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(XWindowAttributes *))
{




    return Success;
}

Status
XGetWMColormapWindows(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window **),
    TCL_UNUSED(int *))
{





    return Success;
}

int
XIconifyWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int))
{




    return Success;
}

XHostAddress *
XListHosts(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int *),
    TCL_UNUSED(Bool *))
{




    return NULL;
}

int
XLookupColor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    TCL_UNUSED(_Xconst char *),
    TCL_UNUSED(XColor *),
    TCL_UNUSED(XColor *))
{






    return Success;
}

int
XNextEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XEvent *))
{



    return Success;
}

int
XPutBackEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XEvent *))
{



    return Success;
}

int
XQueryColors(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    TCL_UNUSED(XColor *),
    TCL_UNUSED(int))
{





    return Success;
}

int
XQueryTree(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window **),
    TCL_UNUSED(unsigned int *))
{







    return Success;
}

int
XRefreshKeyboardMapping(
    TCL_UNUSED(XMappingEvent *))
{


    return Success;
}

Window
XRootWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int))
{



    return (Window) NULL;
}

int
XSelectInput(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(long))
{




    return Success;
}

int
XSendEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Bool),
    TCL_UNUSED(long),
    TCL_UNUSED(XEvent *))
{






    return Success;
}

int
XSetCommand(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(char **),
    TCL_UNUSED(int))
{





    return Success;
}

XErrorHandler
XSetErrorHandler(
    TCL_UNUSED(XErrorHandler))
{


    return NULL;
}

int
XSetIconName(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(_Xconst char *))
{




    return Success;
}

int
XSetWindowBackground(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned long))
{




    return Success;
}

int
XSetWindowBackgroundPixmap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Pixmap))
{




    return Success;
}

int
XSetWindowBorder(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned long))
{




    return Success;
}

int
XSetWindowBorderPixmap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Pixmap))
{




    return Success;
}

int
XSetWindowBorderWidth(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(unsigned int))
{




    return Success;
}

int
XSetWindowColormap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Colormap))
{




    return Success;
}

Bool
XTranslateCoordinates(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    TCL_UNUSED(Window *))
{









    return 0;
}

int
XWindowEvent(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(long),
    TCL_UNUSED(XEvent *))
{





    return Success;
}

int
XWithdrawWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int))
{




    return Success;
}

int
XmbLookupString(
    TCL_UNUSED(XIC),
    TCL_UNUSED(XKeyPressedEvent *),
    TCL_UNUSED(char *),
    TCL_UNUSED(int),
    TCL_UNUSED(KeySym *),
    TCL_UNUSED(Status *))
{







    return Success;
}

int
XGetWindowProperty(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom),
    TCL_UNUSED(long),
    TCL_UNUSED(long),
    TCL_UNUSED(Bool),
    TCL_UNUSED(Atom),
    Atom *actual_type_return,
    int *actual_format_return,
    unsigned long *nitems_return,
    unsigned long *bytes_after_return,
    unsigned char **prop_return)
{








    *actual_type_return = None;
    *actual_format_return = 0;
    *nitems_return = 0;
    *bytes_after_return = 0;
    *prop_return = NULL;
    return BadValue;
}

/*
 * The following functions were implemented as macros under Windows.
 */

int
XFlush(
    TCL_UNUSED(Display *))
{


    return 0;
}

int
XGrabServer(
    TCL_UNUSED(Display *))
{


    return 0;
}

int
XUngrabServer(
    TCL_UNUSED(Display *))
{


    return 0;
}

int
XFree(
    void *data)
{
	if (data != NULL) {
		ckfree(data);
	}
    return 0;
}

int
XNoOp(
    Display *display)
{
    LastKnownRequestProcessed(display)++;
    return 0;
}

XAfterFunction
XSynchronize(
    Display *display,
    TCL_UNUSED(Bool))
{

    LastKnownRequestProcessed(display)++;

    return NULL;
}

int
XSync(
    Display *display,
    TCL_UNUSED(Bool))
{

    LastKnownRequestProcessed(display)++;

    return 0;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

int
XOffsetRegion(
    TCL_UNUSED(Region),
	TCL_UNUSED(int),
	TCL_UNUSED(int))
{




	return 0;
}

Added win/svnmanifest.in.



>
1
svn-r

Changes to win/targets.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/trunk/tip/477.md) for docs.

$(PROJECT): setup pkgindex $(PRJLIB)

!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
	$(LIBCMD) $**






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.

$(PROJECT): setup pkgindex $(PRJLIB)

!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
	$(LIBCMD) $**

Changes to win/tcl.m4.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )







|

|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AS_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    [with_tclconfig="${withval}"])
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )







|

|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    # the alternative search directory is invoked by --with-tk
    #

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AS_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    [with_tkconfig="${withval}"])
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#
# Results:
#
#	Substitutes the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE
#		TCL_ZIP_FILE
#
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then







<







247
248
249
250
251
252
253

254
255
256
257
258
259
260
#
# Results:
#
#	Substitutes the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE

#
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_ZIP_FILE)
    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)







<







283
284
285
286
287
288
289

290
291
292
293
294
295
296
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)


    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#------------------------------------------------------------------------

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?])







<
<
<
<
<
<
<
<







352
353
354
355
356
357
358








359
360
361
362
363
364
365
#------------------------------------------------------------------------

AC_DEFUN([SC_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	[  --enable-shared         build and link with shared libraries (default: on)],
	[tcl_ok=$enableval], [tcl_ok=yes])








    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
459
460
461
462
463
464
465

466
467
468
469
470
471
472
# Results:
#
#	Can the following vars:
#		EXTRA_CFLAGS
#		CFLAGS_DEBUG
#		CFLAGS_OPTIMIZE
#		CFLAGS_WARNING

#		LDFLAGS_DEBUG
#		LDFLAGS_OPTIMIZE
#		LDFLAGS_CONSOLE
#		LDFLAGS_WINDOW
#		CC_OBJNAME
#		CC_EXENAME
#		CYGPATH







>







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# 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
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537







538
539
540
541
542
543
544

    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
    AC_CHECK_PROG(WINE, wine, wine,)

    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      AC_CACHE_CHECK(for cross-compile version of gcc,
	ac_cv_cross,
	AC_TRY_COMPILE([
	    #ifndef _WIN32
		#error cross-compiler
	    #endif
	], [],
	ac_cv_cross=no,
	ac_cv_cross=yes)
      )

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-${CC}"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;







	    *)
		CC="i686-w64-mingw32-${CC}"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;







|






|



|
|
|











>
>
>
>
>
>
>







497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
    AC_CHECK_PROG(WINE, wine, wine,)

    SHLIB_SUFFIX=".dll"

    # MACHINE is IX86 for LINK, but this is used by the manifest,
    # which requires x86|amd64|arm64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      AC_CACHE_CHECK(for cross-compile version of gcc,
	ac_cv_cross,
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #ifndef _WIN32
		#error cross-compiler
	    #endif
	]], [[]])],
	[ac_cv_cross=no],
	[ac_cv_cross=yes])
      )

      if test "$ac_cv_cross" = "yes"; then
	case "$do64bit" in
	    amd64|x64|yes)
		CC="x86_64-w64-mingw32-${CC}"
		LD="x86_64-w64-mingw32-ld"
		AR="x86_64-w64-mingw32-ar"
		RANLIB="x86_64-w64-mingw32-ranlib"
		RC="x86_64-w64-mingw32-windres"
	    ;;
	    arm64|aarch64)
		CC="aarch64-w64-mingw32-${CC}"
		LD="aarch64-w64-mingw32-ld"
		AR="aarch64-w64-mingw32-ar"
		RANLIB="aarch64-w64-mingw32-ranlib"
		RC="aarch64-w64-mingw32-windres"
	    ;;
	    *)
		CC="i686-w64-mingw32-${CC}"
		LD="i686-w64-mingw32-ld"
		AR="i686-w64-mingw32-ar"
		RANLIB="i686-w64-mingw32-ranlib"
		RC="i686-w64-mingw32-windres"
	    ;;
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597



598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615

































616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	AC_CACHE_CHECK(for mingw32 version of gcc,
	    ac_cv_win32,
	    AC_TRY_COMPILE([
		#ifdef _WIN32
		    #error win32
		#endif
	    ], [],
	    ac_cv_win32=no,
	    ac_cv_win32=yes)
	)
	if test "$ac_cv_win32" != "yes"; then
	    AC_MSG_ERROR([${CC} cannot produce win32 executables.])
	fi




	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	AC_CACHE_CHECK(for working -municode linker flag,
	    ac_cv_municode,
	AC_TRY_LINK([
	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}
	],
	[],
	    ac_cv_municode=yes,
	    ac_cv_municode=no)
	)
	CFLAGS=$hold_cflags
	if test "$ac_cv_municode" = "yes" ; then
	    extra_ldflags="$extra_ldflags -municode"
	else
	    extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS"
	fi

































    fi

    AC_MSG_CHECKING([compiler flags])
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \[$]@"







|



|
|
|




>
>
>




|


|
<
|
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606

607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
    # set various compiler flags depending on whether we are using gcc or cl

    if test "${GCC}" = "yes" ; then
	extra_cflags="-pipe"
	extra_ldflags="-pipe -static-libgcc"
	AC_CACHE_CHECK(for mingw32 version of gcc,
	    ac_cv_win32,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#ifdef _WIN32
		    #error win32
		#endif
	    ]], [[]])],
	    [ac_cv_win32=no],
	    [ac_cv_win32=yes])
	)
	if test "$ac_cv_win32" != "yes"; then
	    AC_MSG_ERROR([${CC} cannot produce win32 executables.])
	fi
	if test "$do64bit" != "arm64"; then
	    extra_cflags="$extra_cflags -DHAVE_CPUID=1"
	fi

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	AC_CACHE_CHECK(for working -municode linker flag,
	    ac_cv_municode,
	AC_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])
	)
	CFLAGS=$hold_cflags
	if test "$ac_cv_municode" = "yes" ; then
	    extra_ldflags="$extra_ldflags -municode"
	else
	    extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS"
	fi
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto"
	AC_CACHE_CHECK(for working -fno-lto,
	    ac_cv_nolto,
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
	    [ac_cv_nolto=yes],
	    [ac_cv_nolto=no])
	)
	CFLAGS=$hold_cflags
	if test "$ac_cv_nolto" = "yes" ; then
	    CFLAGS_NOLTO="-fno-lto"
	else
	    CFLAGS_NOLTO=""
	fi
	AC_CACHE_CHECK([if the compiler understands -finput-charset],
	    tcl_cv_cc_input_charset, [
	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8"
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_input_charset=yes],[tcl_cv_cc_input_charset=no])
	    CFLAGS=$hold_cflags])
	if test $tcl_cv_cc_input_charset = yes; then
	    extra_cflags="$extra_cflags -finput-charset=UTF-8"
	fi
    fi

    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--enable-auto-image-base"
    AC_CACHE_CHECK(for working --enable-auto-image-base,
	ac_cv_enable_auto_image_base,
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
	[ac_cv_enable_auto_image_base=yes],
	[ac_cv_enable_auto_image_base=no])
    )
    CFLAGS=$hold_cflags
    if test "$ac_cv_enable_auto_image_base" == "yes" ; then
	extra_ldflags="$extra_ldflags -Wl,--enable-auto-image-base"
    fi

    AC_MSG_CHECKING([compiler flags])
    if test "${GCC}" = "yes" ; then
	SHLIB_LD=""
	SHLIB_LD_LIBS='${LIBS}'
	LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -lws2_32"
	# mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
	LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32 -lwinspool"
	STLIB_LD='${AR} cr'
	RC_OUT=-o
	RC_TYPE=
	RC_INCLUDE=--include
	RC_DEFINE=--define
	RES=res.o
	MAKE_LIB="\${STLIB_LD} \[$]@"
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.a,\[$]@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \[$]@"
	CC_EXENAME="-o \[$]@"








|




















|







690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
	    LIBRARIES="\${SHARED_LIBRARIES}"
	fi
	# Link with gcc since ld does not link to default libs like
	# -luser32 and -lmsvcrt by default.
	SHLIB_LD='${CC} -shared'
	SHLIB_LD_LIBS='${LIBS}'
	MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -o \[$]@ ${extra_ldflags} \
	    -Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\[$]@)"
	# DLLSUFFIX is separate because it is the building block for
	# users of tclConfig.sh that may build shared or static.
	DLLSUFFIX=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	SHLIB_SUFFIX=.dll

	EXTRA_CFLAGS="${extra_cflags}"

	CFLAGS_DEBUG=-g
	CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \[$]@"
	CC_EXENAME="-o \[$]@"

708
709
710
711
712
713
714




715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"

	case "$do64bit" in
	    amd64|x64|yes)
		MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;




	    ia64)
		MACHINE="IA64"
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    *)
		AC_TRY_COMPILE([
		    #ifndef _WIN64
			#error 32-bit
		    #endif
		], [],
			tcl_win_64bit=yes,
			tcl_win_64bit=no
		)
		if test "$tcl_win_64bit" = "yes" ; then
			do64bit=amd64
			MACHINE="AMD64"
			AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])







>
>
>
>


|


|



|
|
|


|
|
|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"

	case "$do64bit" in
	    amd64|x64|yes)
		MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    arm64|aarch64)
		MACHINE="ARM64"
		AC_MSG_RESULT([   Using ARM64 $MACHINE mode])
		;;
	    ia64)
		MACHINE="IA64"
		AC_MSG_RESULT([   Using IA64 $MACHINE mode])
		;;
	    *)
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		    #ifndef _WIN64
			#error 32-bit
		    #endif
		]], [[]])],
			[tcl_win_64bit=yes],
			[tcl_win_64bit=no]
		)
		if test "$tcl_win_64bit" = "yes" ; then
		    do64bit=amd64
		    MACHINE="AMD64"
		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		fi
		;;
	esac
    else
	if test "${SHARED_BUILD}" = "0" ; then
	    # static
            AC_MSG_RESULT([using static flags])
762
763
764
765
766
767
768



769
770
771
772
773
774
775
776
777
778
779
780
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
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;



		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
	fi

	LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;
	esac

	if test "$do64bit" != "no" ; then
	    RC="rc"
	    CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"
	    # Do not use -O2 for Win64 - this has proved buggy in code gen.
	    CFLAGS_OPTIMIZE="-nologo -O1 ${runtime}"
	    lflags="${lflags} -nologo -MACHINE:${MACHINE}"
	    LINKBIN="link"
	    # Avoid 'unresolved external symbol __security_cookie' errors.
	    # c.f. http://support.microsoft.com/?id=894573
	    LIBS="$LIBS bufferoverflowU.lib"
	else
	    RC="rc"
	    # -Od - no optimization
	    # -WX - warnings as errors
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi

	LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"

	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r







>
>
>




















<
|
















|







799
800
801
802
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
	LIBFLAGSUFFIX=""

	if test "$do64bit" != "no" ; then
	    case "$do64bit" in
		amd64|x64|yes)
		    MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		    ;;
		arm64|aarch64)
		    MACHINE="ARM64"
		    ;;
		ia64)
		    MACHINE="IA64"
		    ;;
	    esac
	    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
	fi

	LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib"

	case "x`echo \${VisualStudioVersion}`" in
		x1[[4-9]]*)
		    LIBS="$LIBS ucrt.lib"
		    ;;
		*)
		    ;;
	esac

	if test "$do64bit" != "no" ; then
	    RC="rc"
	    CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"

	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo -MACHINE:${MACHINE}"
	    LINKBIN="link"
	    # Avoid 'unresolved external symbol __security_cookie' errors.
	    # c.f. http://support.microsoft.com/?id=894573
	    LIBS="$LIBS bufferoverflowU.lib"
	else
	    RC="rc"
	    # -Od - no optimization
	    # -WX - warnings as errors
	    CFLAGS_DEBUG="-nologo -Z7 -Od -WX ${runtime}d"
	    # -O2 - create fast code (/Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy)
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo"
	    LINKBIN="link"
	fi

	LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib winspool.lib"

	SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
	SHLIB_LD_LIBS='${LIBS}'
	# link -lib only works when -lib is the first arg
	STLIB_LD="${LINKBIN} -lib ${lflags}"
	RC_OUT=-fo
	RC_TYPE=-r
847
848
849
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
    if test "$do64bit" != "no" ; then
	AC_DEFINE(TCL_CFG_DO64BIT)
    fi

    if test "${GCC}" = "yes" ; then
	AC_CACHE_CHECK(for SEH support in compiler,
	    tcl_cv_seh,
	AC_TRY_RUN([
	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }
	],
	    tcl_cv_seh=yes,
	    tcl_cv_seh=no,
	    tcl_cv_seh=no)
	)
	if test "$tcl_cv_seh" = "no" ; then
	    AC_DEFINE(HAVE_NO_SEH, 1,
		    [Defined when mingw does not support SEH])
	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
	    tcl_cv_eh_disposition,
	    AC_TRY_COMPILE([
#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN
	    ],[
		EXCEPTION_DISPOSITION x;
	    ],
		tcl_cv_eh_disposition=yes,
		tcl_cv_eh_disposition=no)
	)
	if test "$tcl_cv_eh_disposition" = "no" ; then
	AC_DEFINE(EXCEPTION_DISPOSITION, int,
		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
	    tcl_cv_winnt_ignore_void,
	    AC_TRY_COMPILE([
		#define VOID void
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
		#undef WIN32_LEAN_AND_MEAN
	    ], [
		CHAR c;
		SHORT s;
		LONG l;
	    ],
        tcl_cv_winnt_ignore_void=yes,
        tcl_cv_winnt_ignore_void=no)
	)
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
	fi

	AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)

	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_TRY_COMPILE([],
	    [
		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ],
	    tcl_cv_cast_to_union=yes,
	    tcl_cv_cast_to_union=no)
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi
    fi

    # 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)

])

#------------------------------------------------------------------------
# SC_WITH_TCL --
#
#	Location of the Tcl build directory.
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--with-tcl=...
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the tcl build dir.
#------------------------------------------------------------------------

AC_DEFUN([SC_WITH_TCL], [
    if test -d ../../tcl8.7$1/win;  then
	TCL_BIN_DEFAULT=../../tcl8.7$1/win
    else
	TCL_BIN_DEFAULT=../../tcl8.7/win
    fi

    AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.7 binaries from DIR],
	    TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`)
    if test ! -d $TCL_BIN_DIR; then
	AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
    fi
    if test ! -f $TCL_BIN_DIR/Makefile; then
	AC_MSG_ERROR(There is no Makefile in $TCL_BIN_DIR:  perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?)
    else







|














|
|
|
|














|



|

|
|
|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
<


|
|
|












>




















|
|

|


|







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
    if test "$do64bit" != "no" ; then
	AC_DEFINE(TCL_CFG_DO64BIT)
    fi

    if test "${GCC}" = "yes" ; then
	AC_CACHE_CHECK(for SEH support in compiler,
	    tcl_cv_seh,
	AC_RUN_IFELSE([AC_LANG_SOURCE([[
	    #define WIN32_LEAN_AND_MEAN
	    #include <windows.h>
	    #undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }
	]])],
	    [tcl_cv_seh=yes],
	    [tcl_cv_seh=no],
	    [tcl_cv_seh=no])
	)
	if test "$tcl_cv_seh" = "no" ; then
	    AC_DEFINE(HAVE_NO_SEH, 1,
		    [Defined when mingw does not support SEH])
	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
	    tcl_cv_eh_disposition,
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN
	    ]], [[
		EXCEPTION_DISPOSITION x;
	    ]])],
		[tcl_cv_eh_disposition=yes],
		[tcl_cv_eh_disposition=no])
	)
	if test "$tcl_cv_eh_disposition" = "no" ; then
	AC_DEFINE(EXCEPTION_DISPOSITION, int,
		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
	fi

























	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_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[

		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ]])],
	    [tcl_cv_cast_to_union=yes],
	    [tcl_cv_cast_to_union=no])
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi
    fi

    # DL_LIBS is empty, but then we match the Unix version
    AC_SUBST(DL_LIBS)
    AC_SUBST(CFLAGS_DEBUG)
    AC_SUBST(CFLAGS_OPTIMIZE)
    AC_SUBST(CFLAGS_WARNING)
    AC_SUBST(CFLAGS_NOLTO)
])

#------------------------------------------------------------------------
# SC_WITH_TCL --
#
#	Location of the Tcl build directory.
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--with-tcl=...
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the tcl build dir.
#------------------------------------------------------------------------

AC_DEFUN([SC_WITH_TCL], [
    if test -d ../../tcl9.0$1/win;  then
	TCL_BIN_DEFAULT=../../tcl9.0$1/win
    else
	TCL_BIN_DEFAULT=../../tcl9.0/win
    fi

    AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 9.0 binaries from DIR],
	    TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`)
    if test ! -d $TCL_BIN_DIR; then
	AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
    fi
    if test ! -f $TCL_BIN_DIR/Makefile; then
	AC_MSG_ERROR(There is no Makefile in $TCL_BIN_DIR:  perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?)
    else
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
#	extension can't assume that an executable Tcl shell exists at
#	build time.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#		TCLSH_PROG
#------------------------------------------------------------------------

AC_DEFUN([SC_PROG_TCLSH], [
    AC_MSG_CHECKING([for tclsh])

    AC_CACHE_VAL(ac_cv_path_tclsh, [







|







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
#	extension can't assume that an executable Tcl shell exists at
#	build time.
#
# Arguments
#	none
#
# Results
#	Substitutes the following values:
#		TCLSH_PROG
#------------------------------------------------------------------------

AC_DEFUN([SC_PROG_TCLSH], [
    AC_MSG_CHECKING([for tclsh])

    AC_CACHE_VAL(ac_cv_path_tclsh, [
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
#	when running tests from an extension build directory. It is not
#	correct to use the TCLSH_PROG in cases like this.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#		BUILD_TCLSH
#------------------------------------------------------------------------

AC_DEFUN([SC_BUILD_TCLSH], [
    AC_MSG_CHECKING([for tclsh in Tcl build directory])
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}
    AC_MSG_RESULT($BUILD_TCLSH)
    AC_SUBST(BUILD_TCLSH)
])

#--------------------------------------------------------------------
# SC_TCL_CFG_ENCODING	TIP #59
#







|





|







1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
#	when running tests from an extension build directory. It is not
#	correct to use the TCLSH_PROG in cases like this.
#
# Arguments
#	none
#
# Results
#	Substitutes the following values:
#		BUILD_TCLSH
#------------------------------------------------------------------------

AC_DEFUN([SC_BUILD_TCLSH], [
    AC_MSG_CHECKING([for tclsh in Tcl build directory])
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}\${EXESUFFIX}
    AC_MSG_RESULT($BUILD_TCLSH)
    AC_SUBST(BUILD_TCLSH)
])

#--------------------------------------------------------------------
# SC_TCL_CFG_ENCODING	TIP #59
#
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

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")
    fi
])

#--------------------------------------------------------------------
# SC_EMBED_MANIFEST
#
#	Figure out if we can embed the manifest where necessary







<
|







1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1110

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

	AC_DEFINE(TCL_CFGVAL_ENCODING,"utf-8")
    fi
])

#--------------------------------------------------------------------
# SC_EMBED_MANIFEST
#
#	Figure out if we can embed the manifest where necessary
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
#		VC_MANIFEST_EMBED_EXE
#
#--------------------------------------------------------------------

AC_DEFUN([SC_EMBED_MANIFEST], [
    AC_MSG_CHECKING(whether to embed manifest)
    AC_ARG_ENABLE(embedded-manifest,
	AC_HELP_STRING([--enable-embedded-manifest],
		[embed manifest if possible (default: yes)]),
	[embed_ok=$enableval], [embed_ok=yes])

    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \







|







1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
#		VC_MANIFEST_EMBED_EXE
#
#--------------------------------------------------------------------

AC_DEFUN([SC_EMBED_MANIFEST], [
    AC_MSG_CHECKING(whether to embed manifest)
    AC_ARG_ENABLE(embedded-manifest,
	AS_HELP_STRING([--enable-embedded-manifest],
		[embed manifest if possible (default: yes)]),
	[embed_ok=$enableval], [embed_ok=yes])

    VC_MANIFEST_EMBED_DLL=
    VC_MANIFEST_EMBED_EXE=
    result=no
    if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \

Changes to win/tkConfig.sh.in.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'

# Additional libraries to use when linking Tk.
TK_LIBS='@LIBS@ @LIBS_GUI@'

# Top-level directory in which Tcl's platform-independent files are
# installed.
TK_PREFIX='@prefix@'

# Top-level directory in which Tcl's platform-specific files (e.g.
# executables) are installed.
TK_EXEC_PREFIX='@exec_prefix@'

# -l flag to pass to the linker to pick up the Tcl library
TK_LIB_FLAG='@TK_LIB_FLAG@'

# String to pass to linker to pick up the Tk library from its
# build directory.
TK_BUILD_LIB_SPEC='@TK_BUILD_LIB_SPEC@'

# String to pass to linker to pick up the Tk library from its







|



|



|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# The name of the Tk library (may be either a .a file or a shared library):
TK_LIB_FILE='@TK_LIB_FILE@'

# Additional libraries to use when linking Tk.
TK_LIBS='@LIBS@ @LIBS_GUI@'

# Top-level directory in which Tk's platform-independent files are
# installed.
TK_PREFIX='@prefix@'

# Top-level directory in which Tk's platform-specific files (e.g.
# executables) are installed.
TK_EXEC_PREFIX='@exec_prefix@'

# -l flag to pass to the linker to pick up the Tk library
TK_LIB_FLAG='@TK_LIB_FLAG@'

# String to pass to linker to pick up the Tk library from its
# build directory.
TK_BUILD_LIB_SPEC='@TK_BUILD_LIB_SPEC@'

# String to pass to linker to pick up the Tk library from its

Added win/tkUuid.h.in.



>
1
#define TK_VERSION_UUID \

Changes to win/tkWin.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * tkWin.h --
 *
 *	Declarations of public types and interfaces that are only
 *	available under Windows.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKWIN
#define _TKWIN

/*
 * We must specify the lower version we intend to support. In particular
 * the SystemParametersInfo API doesn't like to receive structures that
 * are larger than it expects which affects the font assignments.
 *
 * WINVER = 0x0600 means Windows Vista and above. Even though we still
 * support Windows XP, but the Vista-specifics are tested at runtime.
 */

#ifndef WINVER
#   define WINVER 0x0600
#endif
#ifndef _WIN32_WINNT
#   define _WIN32_WINNT 0x0600
#endif
#ifndef _WIN32_IE
#   define _WIN32_IE 0x0700
#endif

#ifndef _TK
#include <tk.h>
#endif

#define WIN32_LEAN_AND_MEAN






|


















|


|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 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 0x0601
#endif
#ifndef _WIN32_WINNT
#   define _WIN32_WINNT 0x0601
#endif
#ifndef _WIN32_IE
#   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
/*
 * tkWin32Dll.c --
 *
 *	This file contains a stub dll entry point.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#ifndef STATIC_BUILD





|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkWin32Dll.c --
 *
 *	This file contains a stub dll entry point.
 *
 * 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

BOOL APIENTRY
DllMain(
    HINSTANCE hInstance,
    DWORD reason,
    LPVOID reserved)
{
#ifdef HAVE_NO_SEH
    TCLEXCEPTION_REGISTRATION registration;
#endif
    (void)reserved;

    /*
     * If we are attaching to the DLL from a new process, tell Tk about the
     * hInstance to use.
     */

    switch (reason) {
    case DLL_PROCESS_ATTACH:
	DisableThreadLibraryCalls(hInstance);
	TkWinSetHINSTANCE(hInstance);
	break;

    case DLL_PROCESS_DETACH:
	/*
	 * Protect the call to TkFinalize in an SEH block. We can't be
	 * guarenteed Tk is always being unloaded from a stable condition.
	 */

#ifdef HAVE_NO_SEH


#   ifdef __WIN64
	__asm__ __volatile__ (

	    /*
	     * Construct an TCLEXCEPTION_REGISTRATION to protect the call to
	     * TkFinalize
	     */

	    "leaq	%[registration], %%rdx"		"\n\t"
	    "movq	%%gs:0,		%%rax"		"\n\t"
	    "movq	%%rax,		0x0(%%rdx)"	"\n\t" /* link */
	    "leaq	1f,		%%rax"		"\n\t"
	    "movq	%%rax,		0x8(%%rdx)"	"\n\t" /* handler */
	    "movq	%%rbp,		0x10(%%rdx)"	"\n\t" /* rbp */
	    "movq	%%rsp,		0x18(%%rdx)"	"\n\t" /* rsp */
	    "movl	%[error],	0x20(%%rdx)"	"\n\t" /* status */

	    /*
	     * Link the TCLEXCEPTION_REGISTRATION on the chain







|


















|



>
>
|










|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

BOOL APIENTRY
DllMain(
    HINSTANCE hInstance,
    DWORD reason,
    LPVOID reserved)
{
#if defined(HAVE_NO_SEH) && !defined(__aarch64__)
    TCLEXCEPTION_REGISTRATION registration;
#endif
    (void)reserved;

    /*
     * If we are attaching to the DLL from a new process, tell Tk about the
     * hInstance to use.
     */

    switch (reason) {
    case DLL_PROCESS_ATTACH:
	DisableThreadLibraryCalls(hInstance);
	TkWinSetHINSTANCE(hInstance);
	break;

    case DLL_PROCESS_DETACH:
	/*
	 * Protect the call to TkFinalize in an SEH block. We can't be
	 * guaranteed Tk is always being unloaded from a stable condition.
	 */

#ifdef HAVE_NO_SEH
#   if defined(__aarch64__)
	/* Don't run TkFinalize(NULL) on mingw-w64 for ARM64, since we don't have corresponding assembler-code. */
#   elif defined(_WIN64)
	__asm__ __volatile__ (

	    /*
	     * Construct an TCLEXCEPTION_REGISTRATION to protect the call to
	     * TkFinalize
	     */

	    "leaq	%[registration], %%rdx"		"\n\t"
	    "movq	%%gs:0,		%%rax"		"\n\t"
	    "movq	%%rax,		0x0(%%rdx)"	"\n\t" /* link */
	    "leaq	1f(%%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
/*
 * 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.
 *
 * 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"






|







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 © 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
/*
 * tkWinButton.c --
 *
 *	This file implements the Windows specific portion of the button
 *	widgets.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#define OEMRESOURCE
#include "tkWinInt.h"






|







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 © 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"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75


























































76
77
78
79
80
81
82
83






84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    WNDPROC oldProc;		/* Old window procedure. */
    HWND hwnd;			/* Current window handle. */
    Pixmap pixmap;		/* Bitmap for rendering the button. */
    DWORD style;		/* Window style flags. */
} WinButton;

/*
 * The following macro reverses the order of RGB bytes to convert between
 * RGBQUAD and COLORREF values.
 */

#define FlipColor(rgb) (RGB(GetBValue(rgb),GetGValue(rgb),GetRValue(rgb)))

/*
 * The following enumeration defines the meaning of the palette entries in the
 * "buttons" image used to draw checkbox and radiobutton indicators.
 */

enum {
    PAL_CHECK = 0,
    PAL_TOP_OUTER = 1,
    PAL_BOTTOM_OUTER = 2,
    PAL_BOTTOM_INNER = 3,
    PAL_INTERIOR = 4,
    PAL_TOP_INNER = 5,
    PAL_BACKGROUND = 6
};

/*
 * Cached information about the boxes bitmap, and the default border width for
 * a button in string form for use in Tk_OptionSpec for the various button
 * widget classes.
 */

typedef struct {
    BITMAPINFOHEADER *boxesPtr;	/* Information about the bitmap. */
    DWORD *boxesPalette;	/* Pointer to color palette. */
    LPSTR boxesBits;		/* Pointer to bitmap data. */
    DWORD boxHeight;		/* Height of each sub-image. */

    DWORD boxWidth;		/* Width of each sub-image. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*


























































 * Declarations for functions defined in this file.
 */

static LRESULT CALLBACK	ButtonProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static Window		CreateProc(Tk_Window tkwin, Window parent,
			    ClientData instanceData);
static void		InitBoxes(void);







/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL					/* modalProc */
};


/*
 *----------------------------------------------------------------------
 *
 * InitBoxes --
 *
 *	This function load the Tk 3d button bitmap. "buttons" is a 16 color
 *	bitmap that is laid out such that the top row contains the 4 checkbox
 *	images, and the bottom row contains the radio button images. Note that
 *	the bitmap is stored in bottom-up format. Also, the first seven
 *	palette entries are used to identify the different parts of the
 *	bitmaps so we can do the appropriate color mappings based on the
 *	current button colors.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Loads the "buttons" resource.
 *
 *----------------------------------------------------------------------
 */

static void
InitBoxes(void)
{
    /*
     * For DLLs like Tk, the HINSTANCE is the same as the HMODULE.
     */

    HMODULE module = (HINSTANCE) Tk_GetHINSTANCE();
    HRSRC hrsrc;
    HGLOBAL hblk;
    LPBITMAPINFOHEADER newBitmap;
    size_t size;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    hrsrc = FindResourceW(module, L"buttons", (LPWSTR) RT_BITMAP);
    if (hrsrc == NULL) {
	Tcl_Panic("FindResourceW() failed for buttons bitmap resource, "
            "resources in tk_base.rc must be linked into Tk dll or static executable");
    } else {
	hblk = LoadResource(module, hrsrc);
	tsdPtr->boxesPtr = (LPBITMAPINFOHEADER)LockResource(hblk);
    }

    /*
     * Copy the DIBitmap into writable memory.
     */

    if (tsdPtr->boxesPtr != NULL && !(tsdPtr->boxesPtr->biWidth % 4)
	    && !(tsdPtr->boxesPtr->biHeight % 2)) {
	size = tsdPtr->boxesPtr->biSize
		+ (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount)
		+ tsdPtr->boxesPtr->biSizeImage;
	newBitmap = (LPBITMAPINFOHEADER)ckalloc(size);
	memcpy(newBitmap, tsdPtr->boxesPtr, size);
	tsdPtr->boxesPtr = newBitmap;
	tsdPtr->boxWidth = tsdPtr->boxesPtr->biWidth / 4;
	tsdPtr->boxHeight = tsdPtr->boxesPtr->biHeight / 2;
	tsdPtr->boxesPalette = (DWORD*) (((LPSTR) tsdPtr->boxesPtr)
		+ tsdPtr->boxesPtr->biSize);
	tsdPtr->boxesBits = ((LPSTR) tsdPtr->boxesPalette)
		+ (sizeof(RGBQUAD) << tsdPtr->boxesPtr->biBitCount);
    } else {
	tsdPtr->boxesPtr = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpButtonSetDefaults --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<



<
<
<
<
>
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|
>
>
>
>
>
>









|








|
|
<
<
<
<
<





|





|

<
<
<
<
<
<
<
<
<


|
<
<
<
<
<
<
<
|
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







32
33
34
35
36
37
38






















39


40
41
42




43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140





141
142
143
144
145
146
147
148
149
150
151
152
153









154
155
156







157
158



159

















160
161
162
163
164
165
166
    WNDPROC oldProc;		/* Old window procedure. */
    HWND hwnd;			/* Current window handle. */
    Pixmap pixmap;		/* Bitmap for rendering the button. */
    DWORD style;		/* Window style flags. */
} WinButton;

/*






















 * Cached information about the checkbutton and radiobutton indicator boxes


 */

typedef struct {




    BOOLEAN initialized;
    int boxSize;		/* Width & height of the box. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Data of the SVG images used for drawing the indicators
 */

static const char checkbtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <path d='m0 0v15h1v-14h14v-1z' fill='#a0a0a0'/>\n\
     <path d='m1 1v13h1v-12h12v-1z' fill='#696969'/>\n\
     <path d='m14 1v13h-13v1h14v-14z' fill='#e3e3e3'/>\n\
     <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
     <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
    </svg>";

static const char checkbtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <path d='m0 0v15h1v-14h14v-1z' fill='#a0a0a0'/>\n\
     <path d='m1 1v13h1v-12h12v-1z' fill='#696969'/>\n\
     <path d='m14 1v13h-13v1h14v-14z' fill='#e3e3e3'/>\n\
     <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
     <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
     <path d='m4.5 8 3 3 4-6' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/>\n\
    </svg>";

static const char radiobtnOffData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <defs>\n\
      <linearGradient id='linearGradientOuter' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#a0a0a0' offset='0'/>\n\
       <stop stop-color='#eeeeee' offset='1'/>\n\
      </linearGradient>\n\
      <linearGradient id='linearGradientInner' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#696969' offset='0'/>\n\
       <stop stop-color='#e3e3e3' offset='1'/>\n\
      </linearGradient>\n\
     </defs>\n\
     <circle cx='8' cy='8' r='8' fill='url(#linearGradientOuter)'/>\n\
     <circle cx='8' cy='8' r='7' fill='url(#linearGradientInner)'/>\n\
     <circle cx='8' cy='8' r='6' fill='#ffffff'/>\n\
    </svg>";

static const char radiobtnOnData[] = "\
    <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
     <defs>\n\
      <linearGradient id='linearGradientOuter' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#a0a0a0' offset='0'/>\n\
       <stop stop-color='#eeeeee' offset='1'/>\n\
      </linearGradient>\n\
      <linearGradient id='linearGradientInner' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
       <stop stop-color='#696969' offset='0'/>\n\
       <stop stop-color='#e3e3e3' offset='1'/>\n\
      </linearGradient>\n\
     </defs>\n\
     <circle cx='8' cy='8' r='8' fill='url(#linearGradientOuter)'/>\n\
     <circle cx='8' cy='8' r='7' fill='url(#linearGradientInner)'/>\n\
     <circle cx='8' cy='8' r='6' fill='#ffffff'/>\n\
     <circle cx='8' cy='8' r='3' fill='#000000'/>\n\
    </svg>";

/*
 * Declarations for functions defined in this file.
 */

static LRESULT CALLBACK	ButtonProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static Window		CreateProc(Tk_Window tkwin, Window parent,
			    void *instanceData);
static void		InitBoxes(Tk_Window tkwin);
static void		ColorToStr(COLORREF color, char *colorStr);
static void		ImageChanged(void *clientData,
			    int x, int y, int width, int height,
			    int imageWidth, int imageHeight);
static void		TkpDrawIndicator(TkButton *butPtr, Drawable d,
			    Tk_3DBorder border, GC gc, int dim, int x, int y);

/*
 * The class procedure table for the button widgets.
 */

const Tk_ClassProcs tkpButtonProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    TkButtonWorldChanged,	/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL			/* modalProc */
};


/*
 *----------------------------------------------------------------------
 *
 * InitBoxes --
 *
 *	This function computes the size of the checkbutton and radiobutton
 *	indicator boxes, according to the display's scaling percentage.





 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Populates the thread-private data.
 *
 *----------------------------------------------------------------------
 */

static void
InitBoxes(Tk_Window tkwin)
{









    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    double scalingLevel = TkScalingLevel(tkwin);








    tsdPtr->boxSize = (int)(16.0 * scalingLevel);



    tsdPtr->initialized = TRUE;

















}

/*
 *----------------------------------------------------------------------
 *
 * TkpButtonSetDefaults --
 *
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
 */

void
TkpButtonSetDefaults(void)
{
    int width = GetSystemMetrics(SM_CXEDGE);
	if (width > 0) {
	    sprintf(tkDefButtonBorderWidth, "%d", width);
	}
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --







|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
 */

void
TkpButtonSetDefaults(void)
{
    int width = GetSystemMetrics(SM_CXEDGE);
	if (width > 0) {
	    snprintf(tkDefButtonBorderWidth, sizeof(tkDefButtonBorderWidth), "%d", width);
	}
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
{
    WinButton *butPtr;
    (void)tkwin;

    butPtr = (WinButton *)ckalloc(sizeof(WinButton));
    butPtr->hwnd = NULL;
    return (TkButton *) butPtr;
}

/*







|


<







200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    TCL_UNUSED(Tk_Window))
{
    WinButton *butPtr;


    butPtr = (WinButton *)ckalloc(sizeof(WinButton));
    butPtr->hwnd = NULL;
    return (TkButton *) butPtr;
}

/*
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 *----------------------------------------------------------------------
 */

static Window
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    ClientData instanceData)	/* Button instance data. */
{
    Window window;
    HWND parent;
    LPCWSTR windowClass;
    WinButton *butPtr = (WinButton *)instanceData;

    parent = Tk_GetHWND(parentWin);







|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
 *----------------------------------------------------------------------
 */

static Window
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    void *instanceData)		/* Button instance data. */
{
    Window window;
    HWND parent;
    LPCWSTR windowClass;
    WinButton *butPtr = (WinButton *)instanceData;

    parent = Tk_GetHWND(parentWin);
293
294
295
296
297
298
299






























































































































































































































300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc);
    }
}

/*
 *----------------------------------------------------------------------
 *






























































































































































































































 * TkpDisplayButton --
 *
 *	This procedure is invoked to display a button widget. It is normally
 *	invoked as an idle handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information appears on the screen. The REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    TkWinDCState state;
    HDC dc;
    TkButton *butPtr = (TkButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ColorToStr --
 *
 *	Writes a given color to a string, in the format "RRGGBB".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the content of the memory area pointed to by the 2nd argument.
 *
 *----------------------------------------------------------------------
 */

static void
ColorToStr(
    COLORREF color,	/* specifies a color */
    char *colorStr)	/* memory area to which the color is to be
			   output in the format "RRGGBB" */
{
    snprintf(colorStr, 7, "%02x%02x%02x",
	     GetRValue(color), GetGValue(color), GetBValue(color));
}

/*
 *----------------------------------------------------------------------
 *
 * ImageChanged --
 *
 *	Dummy function to be passed to Tk_GetImage().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ImageChanged(
    void *clientData,
    int x, int y, int width, int height,
    int imageWidth, int imageHeight)
{
    (void)clientData;
    (void)x; (void)y; (void)width; (void)height;
    (void)imageWidth; (void)imageHeight;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawIndicator -
 *
 *      Draws the indicator image in the drawable at the (x,y) location.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      An image is drawn in the drawable at the given location.
 *
 *----------------------------------------------------------------------
 */

static void
TkpDrawIndicator(
    TkButton *butPtr,		/* checkbutton or radiobutton */
    Drawable d,			/* what to draw on */
    Tk_3DBorder border,		/* colors of the border */
    GC gc,			/* graphics context */
    int dim,			/* width & height of the indicator */
    int x, int y)		/* where to draw */
{
    Tk_Window tkwin = butPtr->tkwin;
    char topOuterColorStr[7], btmOuterColorStr[7], topInnerColorStr[7],
	 btmInnerColorStr[7], interiorColorStr[7], checkColorStr[7];
    Tcl_Interp *interp = Tk_Interp(tkwin);
    char imgName[80];
    Tk_Image img;
    const char *svgDataPtr;
    size_t svgDataLen;
    char *svgDataCopy;
    char *topOuterColorPtr, *btmOuterColorPtr, *topInnerColorPtr,
	 *btmInnerColorPtr, *interiorColorPtr, *checkColorPtr;
    const char *cmdFmt;
    size_t scriptSize;
    char *script;
    int code;

    /*
     * Construct the color strings topOuterColorStr, btmOuterColorStr,
     * topInnerColorStr, btmInnerColorStr, interiorColorStr, and checkColorStr
     */

    ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK_GC),
	       topOuterColorStr);
    ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT_GC),
	       btmOuterColorStr);
    ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK2),
	       topInnerColorStr);
    ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT2),
	       btmInnerColorStr);

    if (butPtr->state == STATE_ACTIVE) {
	ColorToStr(TkWinGetBorderPixels(tkwin, butPtr->activeBorder,
		   TK_3D_FLAT_GC), interiorColorStr);
    } else if (butPtr->state == STATE_DISABLED || (butPtr->flags & TRISTATED)) {
	ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_LIGHT2),
		   interiorColorStr);
    } else if (butPtr->selectBorder != NULL) {
	ColorToStr(TkWinGetBorderPixels(tkwin, butPtr->selectBorder,
		   TK_3D_FLAT_GC), interiorColorStr);
    } else {
	ColorToStr(GetSysColor(COLOR_WINDOW), interiorColorStr);
    }

    if (butPtr->state == STATE_DISABLED && butPtr->disabledFg == NULL) {
	ColorToStr(TkWinGetBorderPixels(tkwin, border, TK_3D_DARK_GC),
		   checkColorStr);
    } else {
	ColorToStr(gc->foreground, checkColorStr);
    }

    /*
    * Check whether there is an SVG image of this size for the indicator's
    * type (0 = checkbtn, 1 = radiobtn) and these color strings
    */

    snprintf(imgName, sizeof(imgName),
	     "::tk::icons::indicator%d_%d_%s_%s_%s_%s_%s_%s",
	     dim, butPtr->type == TYPE_RADIO_BUTTON,
	     topOuterColorStr, btmOuterColorStr, topInnerColorStr,
	     btmInnerColorStr, interiorColorStr,
	     (butPtr->flags & (SELECTED|TRISTATED)) ? checkColorStr : "XXXXXX");
    img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    if (img == NULL) {
	/*
	 * Determine the SVG data to use for the photo image
	 */

	if (butPtr->type == TYPE_CHECK_BUTTON) {
	    svgDataPtr = ((butPtr->flags & (SELECTED|TRISTATED)) ?
			  checkbtnOnData : checkbtnOffData);
	} else {
	    svgDataPtr = ((butPtr->flags & (SELECTED|TRISTATED)) ?
			  radiobtnOnData : radiobtnOffData);
	}

	/*
	 * Copy the string pointed to by svgDataPtr to
	 * a newly allocated memory area svgDataCopy
	 */

	svgDataLen = strlen(svgDataPtr);
	svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
	if (svgDataCopy == NULL) {
	    return;
	}
	memcpy(svgDataCopy, svgDataPtr, svgDataLen);
	svgDataCopy[svgDataLen] = '\0';

	/*
	 * Update the colors within svgDataCopy
	 */

	topOuterColorPtr = strstr(svgDataCopy, "a0a0a0");
	btmOuterColorPtr = strstr(svgDataCopy, "eeeeee");
	topInnerColorPtr = strstr(svgDataCopy, "696969");
	btmInnerColorPtr = strstr(svgDataCopy, "e3e3e3");
	interiorColorPtr = strstr(svgDataCopy, "ffffff");
	checkColorPtr =    strstr(svgDataCopy, "000000");

	assert(topOuterColorPtr);
	assert(btmOuterColorPtr);
	assert(topInnerColorPtr);
	assert(btmInnerColorPtr);
	assert(interiorColorPtr);

	memcpy(topOuterColorPtr, topOuterColorStr, 6);
	memcpy(btmOuterColorPtr, btmOuterColorStr, 6);
	memcpy(topInnerColorPtr, topInnerColorStr, 6);
	memcpy(btmInnerColorPtr, btmInnerColorStr, 6);
	memcpy(interiorColorPtr, interiorColorStr, 6);
	if (checkColorPtr != NULL) {
	    memcpy(checkColorPtr, checkColorStr, 6);
	}

	/*
	 * Create an SVG photo image from svgDataCopy
	 */

	cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
	scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
	script = (char *)attemptckalloc(scriptSize);
	if (script == NULL) {
	    ckfree(svgDataCopy);
	    return;
	}
	snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
	ckfree(svgDataCopy);
	code = Tcl_EvalEx(interp, script, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	ckfree(script);
	if (code != TCL_OK) {
	    Tcl_BackgroundException(interp, code);
	    return;
	}
	img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
    }

    /*
     * Display the image
     */

    Tk_RedrawImage(img, 0, 0, dim, dim, d, x, y);
    Tk_FreeImage(img);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
 *
 *	This procedure is invoked to display a button widget. It is normally
 *	invoked as an idle handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information appears on the screen. The REDRAW_PENDING flag is cleared.
 *
 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    void *clientData)	/* Information about widget. */
{
    TkWinDCState state;
    HDC dc;
    TkButton *butPtr = (TkButton *)clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    int textXOffset = 0, textYOffset = 0;
				/* Text offsets for use with compound buttons
				 * and focus ring. */
    int imageWidth, imageHeight;
    int imageXOffset = 0, imageYOffset = 0;
				/* Image information that will be used to
				 * restrict disabled pixmap as well. */
    DWORD *boxesPalette;

    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    boxesPalette= tsdPtr->boxesPalette;
    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {







<




<







552
553
554
555
556
557
558

559
560
561
562

563
564
565
566
567
568
569
    int textXOffset = 0, textYOffset = 0;
				/* Text offsets for use with compound buttons
				 * and focus ring. */
    int imageWidth, imageHeight;
    int imageXOffset = 0, imageYOffset = 0;
				/* Image information that will be used to
				 * restrict disabled pixmap as well. */


    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
	DrawFocusRect(dc, &rect);
	TkWinReleaseDrawableDC(pixmap, dc, &state);
    }

    y += height/2;

    /*
     * Draw the indicator for check buttons and radio buttons. At this point x
     * and y refer to the top-left corner of the text or image or bitmap.
     */

    if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn
	    && tsdPtr->boxesPtr) {
	int xSrc, ySrc;

	x -= butPtr->indicatorSpace;
	y -= butPtr->indicatorDiameter / 2;

	xSrc = (butPtr->flags & (SELECTED|TRISTATED)) ? tsdPtr->boxWidth : 0;
	if (butPtr->state == STATE_ACTIVE) {
	    xSrc += tsdPtr->boxWidth*2;
	}
	ySrc = (butPtr->type == TYPE_RADIO_BUTTON) ? 0 : tsdPtr->boxHeight;

	/*
	 * Update the palette in the boxes bitmap to reflect the current
	 * button colors. Note that this code relies on the layout of the
	 * bitmap's palette. Also, all of the colors used to draw the bitmap
	 * must be in the palette that is selected into the DC of the
	 * offscreen pixmap. This requires that the static colors be placed
	 * into the palette.
	 */

	if ((butPtr->state == STATE_DISABLED)
		&& (butPtr->disabledFg == NULL)) {
	    boxesPalette[PAL_CHECK] = FlipColor(TkWinGetBorderPixels(tkwin,
		    border, TK_3D_DARK_GC));
	} else {
	    boxesPalette[PAL_CHECK] = FlipColor(gc->foreground);
	}
	boxesPalette[PAL_TOP_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin,
		border, TK_3D_DARK_GC));
	boxesPalette[PAL_TOP_INNER] = FlipColor(TkWinGetBorderPixels(tkwin,
		border, TK_3D_DARK2));
	boxesPalette[PAL_BOTTOM_INNER] = FlipColor(TkWinGetBorderPixels(tkwin,
		border, TK_3D_LIGHT2));
	boxesPalette[PAL_BOTTOM_OUTER] = FlipColor(TkWinGetBorderPixels(tkwin,
		border, TK_3D_LIGHT_GC));
	if ((butPtr->state == STATE_DISABLED) || (butPtr->flags & TRISTATED)) {
	    boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin,
		border, TK_3D_LIGHT2));
	} else if (butPtr->selectBorder != NULL) {
	    boxesPalette[PAL_INTERIOR] = FlipColor(TkWinGetBorderPixels(tkwin,
		    butPtr->selectBorder, TK_3D_FLAT_GC));
	} else {
	    boxesPalette[PAL_INTERIOR] = FlipColor(GetSysColor(COLOR_WINDOW));
	}
	boxesPalette[PAL_BACKGROUND] = FlipColor(TkWinGetBorderPixels(tkwin,
		border, TK_3D_FLAT_GC));

	dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
	StretchDIBits(dc, x, y, (int)tsdPtr->boxWidth, (int)tsdPtr->boxHeight,
		xSrc, ySrc, (int)tsdPtr->boxWidth, (int)tsdPtr->boxHeight,
		tsdPtr->boxesBits, (LPBITMAPINFO) tsdPtr->boxesPtr,
		DIB_RGB_COLORS, SRCCOPY);
	TkWinReleaseDrawableDC(pixmap, dc, &state);
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect. If the widget is
     * selected and we use a different background color when selected, must
     * temporarily modify the GC so the stippling is the right color.







|
|



|
<
<



<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







865
866
867
868
869
870
871
872
873
874
875
876
877


878
879
880





881










































882
883
884
885
886
887
888
	DrawFocusRect(dc, &rect);
	TkWinReleaseDrawableDC(pixmap, dc, &state);
    }

    y += height/2;

    /*
     * Draw the indicator for check buttons and radio buttons. At this point
     * x and y refer to the top-left corner of the text or image or bitmap.
     */

    if ((butPtr->type >= TYPE_CHECK_BUTTON) && butPtr->indicatorOn
	    && tsdPtr->initialized) {


	x -= butPtr->indicatorSpace;
	y -= butPtr->indicatorDiameter / 2;






	TkpDrawIndicator(butPtr, pixmap, border, gc, tsdPtr->boxSize, x, y + 1);










































    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect. If the widget is
     * selected and we use a different background color when selected, must
     * temporarily modify the GC so the stippling is the right color.
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }
    butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;
    butPtr->indicatorSpace = 0;

    if (!tsdPtr->boxesPtr) {
	InitBoxes();
    }

    /*
     * Figure out image metrics.
     */

    if (butPtr->image != NULL) {







|
|







1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017

    if (butPtr->highlightWidth < 0) {
	butPtr->highlightWidth = 0;
    }
    butPtr->inset = butPtr->highlightWidth + butPtr->borderWidth;
    butPtr->indicatorSpace = 0;

    if (!tsdPtr->initialized) {
	InitBoxes(butPtr->tkwin);
    }

    /*
     * Figure out image metrics.
     */

    if (butPtr->image != NULL) {
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    /*
     * Figure out font metrics (even if we don't have text because we need
     * DLUs (based on font, not text) for some spacing calculations below).
     */

    Tk_FreeTextLayout(butPtr->textLayout);
    butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
	    Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
	    butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

    txtWidth = butPtr->textWidth;
    txtHeight = butPtr->textHeight;
    haveText = (*(Tcl_GetString(butPtr->textPtr)) != '\0');
    avgWidth = (Tk_TextWidth(butPtr->tkfont,
	    "abcdefghijklmnopqurstuvwzyABCDEFGHIJKLMNOPQURSTUVWZY",







|







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
    /*
     * Figure out font metrics (even if we don't have text because we need
     * DLUs (based on font, not text) for some spacing calculations below).
     */

    Tk_FreeTextLayout(butPtr->textLayout);
    butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
	    Tcl_GetString(butPtr->textPtr), TCL_INDEX_NONE, butPtr->wrapLength,
	    butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

    txtWidth = butPtr->textWidth;
    txtHeight = butPtr->textHeight;
    haveText = (*(Tcl_GetString(butPtr->textPtr)) != '\0');
    avgWidth = (Tk_TextWidth(butPtr->tkfont,
	    "abcdefghijklmnopqurstuvwzyABCDEFGHIJKLMNOPQURSTUVWZY",
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
    /*
     * Fix up width and height for indicator sizing and spacing.
     */

    if (butPtr->type == TYPE_RADIO_BUTTON
	    || butPtr->type == TYPE_CHECK_BUTTON) {
	if (butPtr->indicatorOn) {
	    butPtr->indicatorDiameter = tsdPtr->boxHeight;

	    /*
	     * Make sure we can see the whole indicator, even if the text or
	     * image is very small.
	     */

	    if (height < butPtr->indicatorDiameter) {







|







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
    /*
     * Fix up width and height for indicator sizing and spacing.
     */

    if (butPtr->type == TYPE_RADIO_BUTTON
	    || butPtr->type == TYPE_CHECK_BUTTON) {
	if (butPtr->indicatorOn) {
	    butPtr->indicatorDiameter = tsdPtr->boxSize;

	    /*
	     * Make sure we can see the whole indicator, even if the text or
	     * image is very small.
	     */

	    if (height < butPtr->indicatorDiameter) {
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
}

/*
 *----------------------------------------------------------------------
 *
 * ButtonProc --
 *
 *	This function is call by Windows whenever an event occurs on a button
 *	control created by Tk.
 *
 * Results:
 *	Standard Windows return value.
 *
 * Side effects:
 *	May generate events.
 *







|
|







1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
}

/*
 *----------------------------------------------------------------------
 *
 * ButtonProc --
 *
 *	This function is called by Windows whenever an event occurs on a
 *	button control created by Tk.
 *
 * Results:
 *	Standard Windows return value.
 *
 * Side effects:
 *	May generate events.
 *

Changes to win/tkWinClipboard.c.

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.
 *
 * 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"





|
|







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 © 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"
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57




58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    char *data, *destPtr;
    Tcl_DString ds;
    HGLOBAL handle;
    Tcl_Encoding encoding;
    int result, locale, noBackslash = 0;





    if (!OpenClipboard(NULL)) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	        "clipboard cannot be opened, another application grabbed it"));
        Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "BUSY", NULL);
        return TCL_ERROR;
    }
    if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
	    || (target != XA_STRING)) {
	goto error;
    }

    /*
     * Attempt to get the data in Unicode form if available as this is less
     * work that CF_TEXT.
     */

    result = TCL_ERROR;







|







>
>
>
>






<
<
<
<







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67




68
69
70
71
72
73
74
				 * selection (determines display from which to
				 * retrieve). */
    Atom selection,		/* Selection to retrieve. */
    Atom target,		/* Desired form in which selection is to be
				 * returned. */
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    void *clientData)	/* Arbitrary value to pass to proc. */
{
    char *data, *destPtr;
    Tcl_DString ds;
    HGLOBAL handle;
    Tcl_Encoding encoding;
    int result, locale, noBackslash = 0;

    if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
	    || (target != XA_STRING)) {
	goto error;
    }
    if (!OpenClipboard(NULL)) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	        "clipboard cannot be opened, another application grabbed it"));
        Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "BUSY", NULL);
        return TCL_ERROR;
    }





    /*
     * Attempt to get the data in Unicode form if available as this is less
     * work that CF_TEXT.
     */

    result = TCL_ERROR;
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

	    /*
	     * Get the locale identifier, determine the proper code page to
	     * use, and find the corresponding encoding.
	     */

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, "cp######", -1);
	    data = (char *)GlobalLock(handle);

	    /*
	     * Even though the documentation claims that GetLocaleInfo expects
	     * an LCID, on Windows 9x it really seems to expect a LanguageID.
	     */

	    locale = LANGIDFROMLCID(*((int*)data));
	    GetLocaleInfoA(locale, LOCALE_IDEFAULTANSICODEPAGE,
		    Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2);
	    GlobalUnlock(handle);

	    encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	} else {
	    encoding = NULL;
	}







|








|
|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

	    /*
	     * Get the locale identifier, determine the proper code page to
	     * use, and find the corresponding encoding.
	     */

	    Tcl_DStringInit(&ds);
	    Tcl_DStringAppend(&ds, "cp######", TCL_INDEX_NONE);
	    data = (char *)GlobalLock(handle);

	    /*
	     * Even though the documentation claims that GetLocaleInfo expects
	     * an LCID, on Windows 9x it really seems to expect a LanguageID.
	     */

	    locale = LANGIDFROMLCID(*((int*)data));
	    GetLocaleInfoA((ULONG)locale, LOCALE_IDEFAULTANSICODEPAGE,
		    Tcl_DStringValue(&ds)+2, (int)Tcl_DStringLength(&ds)-2);
	    GlobalUnlock(handle);

	    encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	} else {
	    encoding = NULL;
	}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    CloseClipboard();
	    goto error;
	}
	data = (char *)GlobalLock(handle);
	Tcl_ExternalToUtfDString(encoding, data, -1, &ds);
	GlobalUnlock(handle);
	if (encoding) {
	    Tcl_FreeEncoding(encoding);
	}
    } else if (IsClipboardFormatAvailable(CF_HDROP)) {
	DROPFILES *drop;








|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    CloseClipboard();
	    goto error;
	}
	data = (char *)GlobalLock(handle);
	(void)Tcl_ExternalToUtfDString(encoding, data, TCL_INDEX_NONE, &ds);
	GlobalUnlock(handle);
	if (encoding) {
	    Tcl_FreeEncoding(encoding);
	}
    } else if (IsClipboardFormatAvailable(CF_HDROP)) {
	DROPFILES *drop;

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
 *	Empties the system clipboard, and claims ownership.
 *
 *----------------------------------------------------------------------
 */

int
XSetSelectionOwner(
    Display *display,
    Atom selection,
    Window owner,
    Time time)
{
    HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
    Tk_Window tkwin;
    (void)display;
    (void)time;

    /*
     * This is a gross hack because the Tk_InternAtom interface is broken. It
     * expects a Tk_Window, even though it only needs a Tk_Display.
     */

    tkwin = (Tk_Window) TkGetMainInfoList()->winPtr;







|


|



<
<







223
224
225
226
227
228
229
230
231
232
233
234
235
236


237
238
239
240
241
242
243
 *	Empties the system clipboard, and claims ownership.
 *
 *----------------------------------------------------------------------
 */

int
XSetSelectionOwner(
    TCL_UNUSED(Display *),
    Atom selection,
    Window owner,
    TCL_UNUSED(Time))
{
    HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
    Tk_Window tkwin;



    /*
     * This is a gross hack because the Tk_InternAtom interface is broken. It
     * expects a Tk_Window, even though it only needs a Tk_Display.
     */

    tkwin = (Tk_Window) TkGetMainInfoList()->winPtr;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
 *
 *----------------------------------------------------------------------
 */

void
TkWinClipboardRender(
    TkDisplay *dispPtr,
    UINT format)
{
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;
    HGLOBAL handle;
    char *buffer, *p, *rawText, *endPtr;
    int length;
    Tcl_DString ds;
    (void)format;

    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == XA_STRING) {
	    break;
	}
    }







|





|

<







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
 *
 *----------------------------------------------------------------------
 */

void
TkWinClipboardRender(
    TkDisplay *dispPtr,
    TCL_UNUSED(UINT))
{
    TkClipboardTarget *targetPtr;
    TkClipboardBuffer *cbPtr;
    HGLOBAL handle;
    char *buffer, *p, *rawText, *endPtr;
    size_t length;
    Tcl_DString ds;


    for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
	    targetPtr = targetPtr->nextPtr) {
	if (targetPtr->type == XA_STRING) {
	    break;
	}
    }
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
		*buffer++ = *p;
	    }
	}
    }
    *buffer = '\0';

	Tcl_DStringInit(&ds);
	Tcl_UtfToWCharDString(rawText, -1, &ds);
	ckfree(rawText);
	handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
		(unsigned) Tcl_DStringLength(&ds) + 2);
	if (!handle) {
	    Tcl_DStringFree(&ds);
	    return;
	}
	buffer = (char *)GlobalLock(handle);
	memcpy(buffer, Tcl_DStringValue(&ds),
		(unsigned) Tcl_DStringLength(&ds) + 2);
	GlobalUnlock(handle);
	Tcl_DStringFree(&ds);
	SetClipboardData(CF_UNICODETEXT, handle);
}

/*
 *----------------------------------------------------------------------







|


|






|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
		*buffer++ = *p;
	    }
	}
    }
    *buffer = '\0';

	Tcl_DStringInit(&ds);
	Tcl_UtfToWCharDString(rawText, TCL_INDEX_NONE, &ds);
	ckfree(rawText);
	handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
		Tcl_DStringLength(&ds) + 2);
	if (!handle) {
	    Tcl_DStringFree(&ds);
	    return;
	}
	buffer = (char *)GlobalLock(handle);
	memcpy(buffer, Tcl_DStringValue(&ds),
		Tcl_DStringLength(&ds) + 2);
	GlobalUnlock(handle);
	Tcl_DStringFree(&ds);
	SetClipboardData(CF_UNICODETEXT, handle);
}

/*
 *----------------------------------------------------------------------
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
 *
 *----------------------------------------------------------------------
 */

void
TkSelUpdateClipboard(
    TkWindow *winPtr,
    TkClipboardTarget *targetPtr)
{
    HWND hwnd = TkWinGetHWND(winPtr->window);
    (void)targetPtr;

    UpdateClipboard(hwnd);
}

/*
 *----------------------------------------------------------------------
 *







|


<







362
363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
 *
 *----------------------------------------------------------------------
 */

void
TkSelUpdateClipboard(
    TkWindow *winPtr,
    TCL_UNUSED(TkClipboardTarget *))
{
    HWND hwnd = TkWinGetHWND(winPtr->window);


    UpdateClipboard(hwnd);
}

/*
 *----------------------------------------------------------------------
 *
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
{
    (void)eventPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

<









445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    TCL_UNUSED(XEvent *))	/* X PropertyChange event. */
{

}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinColor.c.

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.
 *
 * 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"





|
|







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 © 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"
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
 *	Allocates a new color in the palette.
 *
 *----------------------------------------------------------------------
 */

int
XAllocColor(
    Display *display,
    Colormap colormap,
    XColor *color)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    PALETTEENTRY entry, closeEntry;
    HDC dc = GetDC(NULL);
    (void)display;

    entry.peRed = (color->red) >> 8;
    entry.peGreen = (color->green) >> 8;
    entry.peBlue = (color->blue) >> 8;
    entry.peFlags = 0;

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE);
	UINT newPixel, closePixel;
	int isNew;
	size_t refCount;
	Tcl_HashEntry *entryPtr;
	UINT index;

	/*







|






<

|
|
|



|







297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 *	Allocates a new color in the palette.
 *
 *----------------------------------------------------------------------
 */

int
XAllocColor(
    TCL_UNUSED(Display *),
    Colormap colormap,
    XColor *color)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    PALETTEENTRY entry, closeEntry;
    HDC dc = GetDC(NULL);


    entry.peRed = (BYTE)((color->red) >> 8);
    entry.peGreen = (BYTE)((color->green) >> 8);
    entry.peBlue = (BYTE)((color->blue) >> 8);
    entry.peFlags = 0;

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	unsigned long sizePalette = (unsigned long)GetDeviceCaps(dc, SIZEPALETTE);
	UINT newPixel, closePixel;
	int isNew;
	size_t refCount;
	Tcl_HashEntry *entryPtr;
	UINT index;

	/*
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
 *	set.
 *
 *----------------------------------------------------------------------
 */

int
XFreeColors(
    Display *display,
    Colormap colormap,
    unsigned long *pixels,
    int npixels,
    unsigned long planes)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    COLORREF cref;
    UINT count, index;
    size_t refCount;
    int i;
    PALETTEENTRY entry, *entries;
    Tcl_HashEntry *entryPtr;
    HDC dc = GetDC(NULL);
    (void)display;
    (void)planes;

    /*
     * We don't have to do anything for non-palette devices.
     */

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	/*







|



|









<
<







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417


418
419
420
421
422
423
424
 *	set.
 *
 *----------------------------------------------------------------------
 */

int
XFreeColors(
    TCL_UNUSED(Display *),
    Colormap colormap,
    unsigned long *pixels,
    int npixels,
    TCL_UNUSED(unsigned long))
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    COLORREF cref;
    UINT count, index;
    size_t refCount;
    int i;
    PALETTEENTRY entry, *entries;
    Tcl_HashEntry *entryPtr;
    HDC dc = GetDC(NULL);



    /*
     * We don't have to do anything for non-palette devices.
     */

    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	/*
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
 *	Allocates an empty palette and color list.
 *
 *----------------------------------------------------------------------
 */

Colormap
XCreateColormap(
    Display *display,
    Window w,
    Visual *visual,
    int alloc)
{
    char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
    LOGPALETTE *logPalettePtr;
    PALETTEENTRY *entryPtr;
    TkWinColormap *cmap;
    Tcl_HashEntry *hashPtr;
    int isNew;
    UINT i;
    HPALETTE sysPal;
    (void)display;
    (void)w;
    (void)visual;
    (void)alloc;

    /*
     * Allocate a starting palette with all of the reserved colors.
     */

    logPalettePtr = (LOGPALETTE *) logPalBuf;
    logPalettePtr->palVersion = 0x300;







|
|
|
|









<
<
<
<







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488




489
490
491
492
493
494
495
 *	Allocates an empty palette and color list.
 *
 *----------------------------------------------------------------------
 */

Colormap
XCreateColormap(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Visual *),
    TCL_UNUSED(int))
{
    char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
    LOGPALETTE *logPalettePtr;
    PALETTEENTRY *entryPtr;
    TkWinColormap *cmap;
    Tcl_HashEntry *hashPtr;
    int isNew;
    UINT i;
    HPALETTE sysPal;





    /*
     * Allocate a starting palette with all of the reserved colors.
     */

    logPalettePtr = (LOGPALETTE *) logPalBuf;
    logPalettePtr->palVersion = 0x300;
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
 *	palette must not be selected into a device context when this occurs.
 *
 *----------------------------------------------------------------------
 */

int
XFreeColormap(
    Display *display,
    Colormap colormap)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;
    (void)display;

    if (!DeleteObject(cmap->palette)) {
	Tcl_Panic("Unable to free colormap, palette is still selected");
    }
    Tcl_DeleteHashTable(&cmap->refCounts);
    ckfree(cmap);
    return Success;







|



<







532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
 *	palette must not be selected into a device context when this occurs.
 *
 *----------------------------------------------------------------------
 */

int
XFreeColormap(
    TCL_UNUSED(Display *),
    Colormap colormap)
{
    TkWinColormap *cmap = (TkWinColormap *) colormap;


    if (!DeleteObject(cmap->palette)) {
	Tcl_Panic("Unable to free colormap, palette is still selected");
    }
    Tcl_DeleteHashTable(&cmap->refCounts);
    ckfree(cmap);
    return Success;

Changes to win/tkWinConfig.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * tkWinConfig.c --
 *
 *	This module implements the Windows system defaults for the
 *	configuration package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"


/*
 *----------------------------------------------------------------------
 *
 * TkpGetSystemDefault --
 *
 *	Given a dbName and className for a configuration option, return a
 *	string representation of the option.
 *
 * Results:
 *	Returns a Tk_Uid that is the string identifier that identifies this
 *	option. Returns NULL if there are no system defaults that match this
 *	pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkpGetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    Tcl_Obj *valueObjPtr;
    Tk_Uid classUid;







|











|





|










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * tkWinConfig.c --
 *
 *	This module implements the Windows system defaults for the
 *	configuration package.
 *
 * 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"


/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSystemDefault --
 *
 *	Given a dbName and className for a configuration option, return a
 *	string representation of the option.
 *
 * Results:
 *	Returns a Tcl_Obj* with the string identifier that identifies this
 *	option. Returns NULL if there are no system defaults that match this
 *	pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_GetSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    Tcl_Obj *valueObjPtr;
    Tk_Uid classUid;

Changes to win/tkWinCursor.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkWinCursor.c --
 *
 *	This file contains Win32 specific cursor related routines.
 *
 * 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"

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#endif

/*
 * The table below is used to map from the name of a predefined cursor to its
 * resource identifier.
 */

static struct CursorName {
    const char *name;
    LPCTSTR id;
} cursorNames[] = {
    {"starting",		IDC_APPSTARTING},
    {"arrow",			IDC_ARROW},
    {"ibeam",			IDC_IBEAM},
    {"icon",			IDC_ICON},







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#endif

/*
 * The table below is used to map from the name of a predefined cursor to its
 * resource identifier.
 */

static const struct CursorName {
    const char *name;
    LPCTSTR id;
} cursorNames[] = {
    {"starting",		IDC_APPSTARTING},
    {"arrow",			IDC_ARROW},
    {"ibeam",			IDC_IBEAM},
    {"icon",			IDC_ICON},
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
TkCursor *
TkGetCursorByName(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    struct CursorName *namePtr;
    TkWinCursor *cursorPtr;
    int argc;
    const char **argv = NULL;
    (void)tkwin;

    /*
     * All cursor names are valid lists of one element (for
     * Unix-compatability), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
    }
    if (argc == 0) {
	goto badCursorSpec;







|

|





|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
TkCursor *
TkGetCursorByName(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    Tk_Uid string)		/* Description of cursor. See manual entry for
				 * details on legal syntax. */
{
    const struct CursorName *namePtr;
    TkWinCursor *cursorPtr;
    Tcl_Size argc;
    const char **argv = NULL;
    (void)tkwin;

    /*
     * All cursor names are valid lists of one element (for
     * Unix-compatibility), even unadorned system cursor names.
     */

    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
	return NULL;
    }
    if (argc == 0) {
	goto badCursorSpec;
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	 *	-cursor {@C:/Program\ Files/Cursors/bart.ani}
	 *      -cursor {{@C:/Program Files/Cursors/bart.ani}}
	 *	-cursor [list @[file join "C:/Program Files" Cursors bart.ani]]
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get cursor from a file in a safe interpreter",-1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
	    ckfree(argv);
	    ckfree(cursorPtr);
	    return NULL;
	}
	cursorPtr->winCursor = LoadCursorFromFileA(&(argv[0][1]));
    } else {







|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	 *	-cursor {@C:/Program\ Files/Cursors/bart.ani}
	 *      -cursor {{@C:/Program Files/Cursors/bart.ani}}
	 *	-cursor [list @[file join "C:/Program Files" Cursors bart.ani]]
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get cursor from a file in a safe interpreter", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL);
	    ckfree(argv);
	    ckfree(cursorPtr);
	    return NULL;
	}
	cursorPtr->winCursor = LoadCursorFromFileA(&(argv[0][1]));
    } else {

Changes to win/tkWinDefault.h.

55
56
57
58
59
60
61

62
63
64
65
66
67
68
#define DEF_BUTTON_BORDER_WIDTH	"2"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""

#define DEF_BUTTON_FG			NORMAL_FG
#define DEF_CHKRAD_FG			TEXT_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		HIGHLIGHT







>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#define DEF_BUTTON_BORDER_WIDTH	"2"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_LABEL_FG			NORMAL_FG
#define DEF_BUTTON_FG			NORMAL_FG
#define DEF_CHKRAD_FG			TEXT_FG
#define DEF_BUTTON_FONT			"TkDefaultFont"
#define DEF_BUTTON_HEIGHT		"0"
#define DEF_BUTTON_HIGHLIGHT_BG_COLOR	DEF_BUTTON_BG_COLOR
#define DEF_BUTTON_HIGHLIGHT_BG_MONO	DEF_BUTTON_BG_MONO
#define DEF_BUTTON_HIGHLIGHT		HIGHLIGHT
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_TRISTATE_VALUE	""
#define DEF_BUTTON_UNDERLINE		"-1"
#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
#define DEF_CHECKBUTTON_VARIABLE	""

/*







<







88
89
90
91
92
93
94

95
96
97
98
99
100
101
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#define DEF_BUTTON_TEXT			""
#define DEF_BUTTON_TEXT_VARIABLE	""
#define DEF_BUTTON_TRISTATE_VALUE	""

#define DEF_BUTTON_VALUE		""
#define DEF_BUTTON_WIDTH		"0"
#define DEF_BUTTON_WRAP_LENGTH		"0"
#define DEF_RADIOBUTTON_VARIABLE	"selectedButton"
#define DEF_CHECKBUTTON_VARIABLE	""

/*
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL
#define DEF_MENU_ENTRY_UNDERLINE	"-1"

/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	SELECT_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK







<







266
267
268
269
270
271
272

273
274
275
276
277
278
279
#define DEF_MENU_ENTRY_ON_VALUE		"1"
#define DEF_MENU_ENTRY_SELECT_IMAGE	NULL
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#define DEF_MENU_ENTRY_RADIO_VARIABLE	"selectedButton"
#define DEF_MENU_ENTRY_SELECT		NULL


/*
 * Defaults for menus overall:
 */

#define DEF_MENU_ACTIVE_BG_COLOR	SELECT_BG
#define DEF_MENU_ACTIVE_BG_MONO		BLACK
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""
#define DEF_MENUBUTTON_UNDERLINE	"-1"
#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			NORMAL_FG
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		HIGHLIGHT
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		"-1"
#define DEF_MESSAGE_PADY		"-1"
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
#define DEF_MESSAGE_TEXT_VARIABLE	""
#define DEF_MESSAGE_WIDTH		"0"

/*







<



















|
|







330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#define DEF_MENUBUTTON_PADX		"4p"
#define DEF_MENUBUTTON_PADY		"3p"
#define DEF_MENUBUTTON_RELIEF		"flat"
#define DEF_MENUBUTTON_STATE		"normal"
#define DEF_MENUBUTTON_TAKE_FOCUS	"0"
#define DEF_MENUBUTTON_TEXT		""
#define DEF_MENUBUTTON_TEXT_VARIABLE	""

#define DEF_MENUBUTTON_WIDTH		"0"
#define DEF_MENUBUTTON_WRAP_LENGTH	"0"

/*
 * Defaults for messages:
 */

#define DEF_MESSAGE_ANCHOR		"center"
#define DEF_MESSAGE_ASPECT		"150"
#define DEF_MESSAGE_BG_COLOR		NORMAL_BG
#define DEF_MESSAGE_BG_MONO		WHITE
#define DEF_MESSAGE_BORDER_WIDTH	"1"
#define DEF_MESSAGE_CURSOR		""
#define DEF_MESSAGE_FG			NORMAL_FG
#define DEF_MESSAGE_FONT		"TkDefaultFont"
#define DEF_MESSAGE_HIGHLIGHT_BG	NORMAL_BG
#define DEF_MESSAGE_HIGHLIGHT		HIGHLIGHT
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		NULL
#define DEF_MESSAGE_PADY		NULL
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
#define DEF_MESSAGE_TEXT_VARIABLE	""
#define DEF_MESSAGE_WIDTH		"0"

/*
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
 * Defaults for scales:
 */

#define DEF_SCALE_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO	BLACK
#define DEF_SCALE_BG_COLOR		NORMAL_BG
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		NORMAL_FG
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		HIGHLIGHT
#define DEF_SCALE_HIGHLIGHT_WIDTH	"2"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY		"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0"
#define DEF_SCALE_TO			"100"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
 */








|







|










|







|
|







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
 * Defaults for scales:
 */

#define DEF_SCALE_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_SCALE_ACTIVE_BG_MONO	BLACK
#define DEF_SCALE_BG_COLOR		NORMAL_BG
#define DEF_SCALE_BG_MONO		WHITE
#define DEF_SCALE_BIG_INCREMENT		"0.0"
#define DEF_SCALE_BORDER_WIDTH		"1"
#define DEF_SCALE_COMMAND		""
#define DEF_SCALE_CURSOR		""
#define DEF_SCALE_DIGITS		"0"
#define DEF_SCALE_FONT			"TkDefaultFont"
#define DEF_SCALE_FG_COLOR		NORMAL_FG
#define DEF_SCALE_FG_MONO		BLACK
#define DEF_SCALE_FROM			"0.0"
#define DEF_SCALE_HIGHLIGHT_BG_COLOR	DEF_SCALE_BG_COLOR
#define DEF_SCALE_HIGHLIGHT_BG_MONO	DEF_SCALE_BG_MONO
#define DEF_SCALE_HIGHLIGHT		HIGHLIGHT
#define DEF_SCALE_HIGHLIGHT_WIDTH	"2"
#define DEF_SCALE_LABEL			""
#define DEF_SCALE_LENGTH		"100"
#define DEF_SCALE_ORIENT		"vertical"
#define DEF_SCALE_RELIEF		"flat"
#define DEF_SCALE_REPEAT_DELAY		"300"
#define DEF_SCALE_REPEAT_INTERVAL	"100"
#define DEF_SCALE_RESOLUTION		"1.0"
#define DEF_SCALE_TROUGH_COLOR		TROUGH
#define DEF_SCALE_TROUGH_MONO		WHITE
#define DEF_SCALE_SHOW_VALUE		"1"
#define DEF_SCALE_SLIDER_LENGTH		"30"
#define DEF_SCALE_SLIDER_RELIEF		"raised"
#define DEF_SCALE_STATE			"normal"
#define DEF_SCALE_TAKE_FOCUS		NULL
#define DEF_SCALE_TICK_INTERVAL		"0.0"
#define DEF_SCALE_TO			"100.0"
#define DEF_SCALE_VARIABLE		""
#define DEF_SCALE_WIDTH			"15"

/*
 * Defaults for scrollbars:
 */

490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_COLOR	NULL

#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"







|
>







488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
#define DEF_TEXT_INSERT_ON_TIME		"600"
#define DEF_TEXT_INSERT_UNFOCUSSED	"none"
#define DEF_TEXT_INSERT_WIDTH		"2"
#define DEF_TEXT_MAX_UNDO		"0"
#define DEF_TEXT_PADX			"1"
#define DEF_TEXT_PADY			"1"
#define DEF_TEXT_RELIEF			"sunken"
#define DEF_TEXT_INACTIVE_SELECT_BG_COLOR NULL
#define DEF_TEXT_INACTIVE_SELECT_FG_COLOR NULL
#define DEF_TEXT_SELECT_COLOR		SELECT_BG
#define DEF_TEXT_SELECT_MONO		BLACK
#define DEF_TEXT_SELECT_BD_COLOR	"0"
#define DEF_TEXT_SELECT_BD_MONO		"0"
#define DEF_TEXT_SELECT_FG_COLOR	SELECT_FG
#define DEF_TEXT_SELECT_FG_MONO		WHITE
#define DEF_TEXT_SELECT_RELIEF		"flat"

Changes to win/tkWinDialog.c.

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.
 *
 * 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"





|







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 © 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"
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
 */

static UINT APIENTRY	ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg,
			    LPARAM wParam, LPARAM lParam);
static UINT CALLBACK	ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static void             CleanupOFNOptions(OFNOpts *optsPtr);
static int              ParseOFNOptions(ClientData clientData,
                            Tcl_Interp *interp, int objc,
                            Tcl_Obj *const objv[], enum OFNOper oper, OFNOpts *optsPtr);
static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr,
                         enum OFNOper oper);
static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr,
                            enum OFNOper oper);
static int 		GetFileName(ClientData clientData,
                                    Tcl_Interp *interp, int objc,
                                    Tcl_Obj *const objv[], enum OFNOper oper);
static int MakeFilterVista(Tcl_Interp *interp, OFNOpts *optsPtr,
               DWORD *countPtr, TCLCOMDLG_FILTERSPEC **dlgFilterPtrPtr,
               DWORD *defaultFilterIndexPtr);
static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr);
static int 		MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr,
			    Tcl_DString *dsPtr, Tcl_Obj *initialPtr,
			    int *indexPtr);
static UINT APIENTRY	OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void		SetTkDialog(ClientData clientData);
static const char *ConvertExternalFilename(LPCWSTR, Tcl_DString *);
static void             LoadShellProcs(void);


/* Definitions of dynamically loaded Win32 calls */
typedef HRESULT (STDAPICALLTYPE SHCreateItemFromParsingNameProc)(
    PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
struct ShellProcPointers {
    SHCreateItemFromParsingNameProc *SHCreateItemFromParsingName;
} ShellProcs;


/*
 *-------------------------------------------------------------------------
 *
 * LoadShellProcs --
 *
 *     Some shell functions are not available on older versions of
 *     Windows. This function dynamically loads them and stores pointers
 *     to them in ShellProcs. Any function that is not available has
 *     the corresponding pointer set to NULL.
 *
 *     Note this call never fails. Unavailability of a function is not
 *     a reason for failure. Caller should check whether a particular
 *     function pointer is NULL or not. Once loaded a function stays
 *     forever loaded.
 *
 *     XXX - we load the function pointers into global memory. This implies
 *     there is a potential (however small) for race conditions between
 *     threads. However, Tk is in any case meant to be loaded in exactly
 *     one thread so this should not be an issue and saves us from
 *     unnecessary bookkeeping.
 *
 * Return value:
 *     None.
 *
 * Side effects:
 *     ShellProcs is populated.
 *-------------------------------------------------------------------------
 */
static void LoadShellProcs(void)
{
    static HMODULE shell32_handle = NULL;

    if (shell32_handle != NULL) {
	return; /* We have already been through here. */
    }

    shell32_handle = GetModuleHandleW(L"shell32.dll");
    if (shell32_handle == NULL) { /* Should never happen but check anyways. */
	return;
    }

    ShellProcs.SHCreateItemFromParsingName = (SHCreateItemFromParsingNameProc*)
	    (void *)GetProcAddress(shell32_handle, "SHCreateItemFromParsingName");
}


/*
 *-------------------------------------------------------------------------
 *
 * EatSpuriousMessageBugFix --
 *
 *	In the file open/save dialog, double clicking on a list item causes
 *	the dialog box to close, but an unwanted WM_LBUTTONUP message is sent







|






|












|

<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592

593























































594
595
596
597
598
599
600
 */

static UINT APIENTRY	ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg,
			    LPARAM wParam, LPARAM lParam);
static UINT CALLBACK	ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static void             CleanupOFNOptions(OFNOpts *optsPtr);
static int              ParseOFNOptions(void *clientData,
                            Tcl_Interp *interp, int objc,
                            Tcl_Obj *const objv[], enum OFNOper oper, OFNOpts *optsPtr);
static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr,
                         enum OFNOper oper);
static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr,
                            enum OFNOper oper);
static int 		GetFileName(void *clientData,
                                    Tcl_Interp *interp, int objc,
                                    Tcl_Obj *const objv[], enum OFNOper oper);
static int MakeFilterVista(Tcl_Interp *interp, OFNOpts *optsPtr,
               DWORD *countPtr, TCLCOMDLG_FILTERSPEC **dlgFilterPtrPtr,
               DWORD *defaultFilterIndexPtr);
static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr);
static int 		MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr,
			    Tcl_DString *dsPtr, Tcl_Obj *initialPtr,
			    int *indexPtr);
static UINT APIENTRY	OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void		SetTkDialog(void *clientData);
static const char *ConvertExternalFilename(LPCWSTR, Tcl_DString *);

























































/*
 *-------------------------------------------------------------------------
 *
 * 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
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
 *	application invokes the "tk_chooseColor" command.
 *
 *-------------------------------------------------------------------------
 */

int
Tk_ChooseColorObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    HWND hWnd;
    int i, oldMode, winCode, result;







|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
 *	application invokes the "tk_chooseColor" command.
 *
 *-------------------------------------------------------------------------
 */

int
Tk_ChooseColorObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    HWND hWnd;
    int i, oldMode, winCode, result;
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
	    dwCustColors[i] = RGB(255-i * 10, i, i * 10);
	}
	oldColor = RGB(0xa0, 0xa0, 0xa0);
	inited = 1;
    }

    parent			= tkwin;
    chooseColor.lStructSize	= sizeof(CHOOSECOLOR);
    chooseColor.hwndOwner	= NULL;
    chooseColor.hInstance	= NULL;
    chooseColor.rgbResult	= oldColor;
    chooseColor.lpCustColors	= dwCustColors;
    chooseColor.Flags		= CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK;
    chooseColor.lCustData	= (LPARAM) NULL;
    chooseColor.lpfnHook	= (LPOFNHOOKPROC)(void *)ColorDlgHookProc;
    chooseColor.lpTemplateName	= (LPWSTR) interp;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL);
	    return TCL_ERROR;







|

















|
|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
	    dwCustColors[i] = RGB(255-i * 10, i, i * 10);
	}
	oldColor = RGB(0xa0, 0xa0, 0xa0);
	inited = 1;
    }

    parent			= tkwin;
    chooseColor.lStructSize	= sizeof(CHOOSECOLORW);
    chooseColor.hwndOwner	= NULL;
    chooseColor.hInstance	= NULL;
    chooseColor.rgbResult	= oldColor;
    chooseColor.lpCustColors	= dwCustColors;
    chooseColor.Flags		= CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK;
    chooseColor.lCustData	= (LPARAM) NULL;
    chooseColor.lpfnHook	= (LPOFNHOOKPROC)(void *)ColorDlgHookProc;
    chooseColor.lpTemplateName	= (LPWSTR) interp;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings,
		"option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "COLORDIALOG", "VALUE", NULL);
	    return TCL_ERROR;
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
 *----------------------------------------------------------------------
 */

static UINT CALLBACK
ColorDlgHookProc(
    HWND hDlg,			/* Handle to the color dialog. */
    UINT uMsg,			/* Type of message. */
    WPARAM wParam,		/* First message parameter. */
    LPARAM lParam)		/* Second message parameter. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *title;
    CHOOSECOLOR *ccPtr;
    (void)wParam;

    if (WM_INITDIALOG == uMsg) {

	/*
	 * Set the title string of the dialog.
	 */

	ccPtr = (CHOOSECOLOR *) lParam;
	title = (const char *) ccPtr->lCustData;

	if ((title != NULL) && (title[0] != '\0')) {
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    SetWindowTextW(hDlg, Tcl_UtfToWCharDString(title, -1, &ds));
	    Tcl_DStringFree(&ds);
	}
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName;
	    Tcl_DoWhenIdle(SetTkDialog, hDlg);
	}
	return TRUE;
    }
    return FALSE;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileCmd --
 *
 *	This function implements the "open file" dialog box for the Windows
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first this function is called.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, OFN_FILE_OPEN);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileCmd --
 *
 *	Same as Tk_GetOpenFileCmd but opens a "save file" dialog box
 *	instead
 *
 * Results:
 *	Same as Tk_GetOpenFileCmd.
 *
 * Side effects:
 *	Same as Tk_GetOpenFileCmd.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, OFN_FILE_SAVE);
}








|





|
<







|






|














|















|










|

|



|


|






|







842
843
844
845
846
847
848
849
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
 *----------------------------------------------------------------------
 */

static UINT CALLBACK
ColorDlgHookProc(
    HWND hDlg,			/* Handle to the color dialog. */
    UINT uMsg,			/* Type of message. */
    TCL_UNUSED(WPARAM),	/* First message parameter. */
    LPARAM lParam)		/* Second message parameter. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *title;
    CHOOSECOLORW *ccPtr;


    if (WM_INITDIALOG == uMsg) {

	/*
	 * Set the title string of the dialog.
	 */

	ccPtr = (CHOOSECOLORW *) lParam;
	title = (const char *) ccPtr->lCustData;

	if ((title != NULL) && (title[0] != '\0')) {
	    Tcl_DString ds;

	    Tcl_DStringInit(&ds);
	    SetWindowTextW(hDlg, Tcl_UtfToWCharDString(title, TCL_INDEX_NONE, &ds));
	    Tcl_DStringFree(&ds);
	}
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName;
	    Tcl_DoWhenIdle(SetTkDialog, hDlg);
	}
	return TRUE;
    }
    return FALSE;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileObjCmd --
 *
 *	This function implements the "open file" dialog box for the Windows
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first this function is called.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetOpenFileObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, OFN_FILE_OPEN);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileObjCmd --
 *
 *	Same as Tk_GetOpenFileObjCmd but opens a "save file" dialog box
 *	instead
 *
 * Results:
 *	Same as Tk_GetOpenFileObjCmd.
 *
 * Side effects:
 *	Same as Tk_GetOpenFileObjCmd.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return GetFileName(clientData, interp, objc, objv, OFN_FILE_SAVE);
}

1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
 *	Returns option values in *optsPtr. Note these may include string
 *      pointers into objv[]
 *----------------------------------------------------------------------
 */

static int
ParseOFNOptions(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum OFNOper oper,			/* 1 for Open, 0 for Save */
    OFNOpts *optsPtr)           /* Output, uninitialized on entry */
{
    int i;







|







968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
 *	Returns option values in *optsPtr. Note these may include string
 *      pointers into objv[]
 *----------------------------------------------------------------------
 */

static int
ParseOFNOptions(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum OFNOper oper,			/* 1 for Open, 0 for Save */
    OFNOpts *optsPtr)           /* Output, uninitialized on entry */
{
    int i;
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
	{"-parent",		FILE_PARENT},
	{"-title",		FILE_TITLE},
	{"-typevariable",	FILE_TYPEVARIABLE},
	{NULL,			FILE_DEFAULT/*ignored*/ }
    };
    static const struct Options dirOptions[] = {
	{"-initialdir", FILE_INITDIR},
        {"-mustexist",  FILE_MUSTEXIST},
	{"-parent",	FILE_PARENT},
	{"-title",	FILE_TITLE},
	{NULL,		FILE_DEFAULT/*ignored*/ }
    };

    const struct Options *options = NULL;

    switch (oper) {
    case OFN_FILE_SAVE: options = saveOptions; break;
    case OFN_DIR_CHOOSE: options = dirOptions; break;
    case OFN_FILE_OPEN: options = openOptions; break;
    }

    ZeroMemory(optsPtr, sizeof(*optsPtr));
    // optsPtr->forceXPStyle = 1;
    optsPtr->tkwin = (Tk_Window)clientData;
    optsPtr->confirmOverwrite = 1; /* By default we ask for confirmation */
    Tcl_DStringInit(&optsPtr->utfDirString);
    optsPtr->file[0] = 0;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *valuePtr;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], options,
		sizeof(struct Options), "option", 0, &index) != TCL_OK) {
            /*
             * XXX -xpstyle is explicitly checked for as it is undocumented
             * and we do not want it to show in option error messages.
             */
            if (strcmp(Tcl_GetString(objv[i]), "-xpstyle"))
                goto error_return;
            if (i + 1 == objc) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj("value for \"-xpstyle\" missing", -1));
                Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
                goto error_return;
            }
	    if (Tcl_GetBooleanFromObj(interp, objv[i+1],
                                      &optsPtr->forceXPStyle) != TCL_OK)
                goto error_return;








|













|
|



















|







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
	{"-parent",		FILE_PARENT},
	{"-title",		FILE_TITLE},
	{"-typevariable",	FILE_TYPEVARIABLE},
	{NULL,			FILE_DEFAULT/*ignored*/ }
    };
    static const struct Options dirOptions[] = {
	{"-initialdir", FILE_INITDIR},
	{"-mustexist",  FILE_MUSTEXIST},
	{"-parent",	FILE_PARENT},
	{"-title",	FILE_TITLE},
	{NULL,		FILE_DEFAULT/*ignored*/ }
    };

    const struct Options *options = NULL;

    switch (oper) {
    case OFN_FILE_SAVE: options = saveOptions; break;
    case OFN_DIR_CHOOSE: options = dirOptions; break;
    case OFN_FILE_OPEN: options = openOptions; break;
    }

    memset(optsPtr, 0, sizeof(*optsPtr));
    /* optsPtr->forceXPStyle = 1; */
    optsPtr->tkwin = (Tk_Window)clientData;
    optsPtr->confirmOverwrite = 1; /* By default we ask for confirmation */
    Tcl_DStringInit(&optsPtr->utfDirString);
    optsPtr->file[0] = 0;

    for (i = 1; i < objc; i += 2) {
	int index;
	const char *string;
	Tcl_Obj *valuePtr;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], options,
		sizeof(struct Options), "option", 0, &index) != TCL_OK) {
            /*
             * XXX -xpstyle is explicitly checked for as it is undocumented
             * and we do not want it to show in option error messages.
             */
            if (strcmp(Tcl_GetString(objv[i]), "-xpstyle"))
                goto error_return;
            if (i + 1 == objc) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj("value for \"-xpstyle\" missing", TCL_INDEX_NONE));
                Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL);
                goto error_return;
            }
	    if (Tcl_GetBooleanFromObj(interp, objv[i+1],
                                      &optsPtr->forceXPStyle) != TCL_OK)
                goto error_return;

1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
                                      &optsPtr->utfDirString) == NULL)
		goto error_return;
	    break;
	case FILE_INITFILE:
	    if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
		goto error_return;
	    Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(),
                              Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0, NULL,
                              (char *) &optsPtr->file[0], sizeof(optsPtr->file),
                              NULL, NULL, NULL);
	    Tcl_DStringFree(&ds);
	    break;
	case FILE_PARENT:
	    optsPtr->tkwin = Tk_NameToWindow(interp, string, (Tk_Window)clientData);
	    if (optsPtr->tkwin == NULL)
		goto error_return;
	    break;







|
|
|







1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
                                      &optsPtr->utfDirString) == NULL)
		goto error_return;
	    break;
	case FILE_INITFILE:
	    if (Tcl_TranslateFileName(interp, string, &ds) == NULL)
		goto error_return;
	    Tcl_UtfToExternal(NULL, TkWinGetUnicodeEncoding(),
                              Tcl_DStringValue(&ds), Tcl_DStringLength(&ds),
                              TCL_ENCODING_PROFILE_TCL8, NULL, (char *)&optsPtr->file[0],
                              sizeof(optsPtr->file), NULL, NULL, NULL);
	    Tcl_DStringFree(&ds);
	    break;
	case FILE_PARENT:
	    optsPtr->tkwin = Tk_NameToWindow(interp, string, (Tk_Window)clientData);
	    if (optsPtr->tkwin == NULL)
		goto error_return;
	    break;
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
{
    HRESULT hr;
    IFileDialog *fdlgPtr = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
        Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->newFileDialogsState == FDLG_STATE_INIT) {
        tsdPtr->newFileDialogsState = FDLG_STATE_USE_OLD;
        LoadShellProcs();
        if (ShellProcs.SHCreateItemFromParsingName != NULL) {
            hr = CoInitialize(0);
            /* XXX - need we schedule CoUninitialize at thread shutdown ? */

            /* Ensure all COM interfaces we use are available */
            if (SUCCEEDED(hr)) {
                hr = CoCreateInstance(&ClsidFileOpenDialog, NULL,
                                      CLSCTX_INPROC_SERVER, &IIDIFileOpenDialog, (void **) &fdlgPtr);
                if (SUCCEEDED(hr)) {
                    fdlgPtr->lpVtbl->Release(fdlgPtr);
                    hr = CoCreateInstance(&ClsidFileSaveDialog, NULL,
                             CLSCTX_INPROC_SERVER, &IIDIFileSaveDialog,
                                          (void **) &fdlgPtr);
                    if (SUCCEEDED(hr)) {
                        fdlgPtr->lpVtbl->Release(fdlgPtr);

                        /* Looks like we have all we need */
                        tsdPtr->newFileDialogsState = FDLG_STATE_USE_NEW;
                    }
                }
            }
        }
    }

    return (tsdPtr->newFileDialogsState == FDLG_STATE_USE_NEW);
}

/*
 *----------------------------------------------------------------------







|
<
<
|
|

|
|
|
|
|
|
|
|
<
|
|

|
|
|
|
|
<







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
{
    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;


	hr = CoInitialize(0);
	/* XXX - need we schedule CoUninitialize at thread shutdown ? */

	/* Ensure all COM interfaces we use are available */
	if (SUCCEEDED(hr)) {
	    hr = CoCreateInstance(&ClsidFileOpenDialog, NULL,
		    CLSCTX_INPROC_SERVER, &IIDIFileOpenDialog, (void **) &fdlgPtr);
	    if (SUCCEEDED(hr)) {
		fdlgPtr->lpVtbl->Release(fdlgPtr);
		hr = CoCreateInstance(&ClsidFileSaveDialog, NULL,
			CLSCTX_INPROC_SERVER, &IIDIFileSaveDialog, (void **) &fdlgPtr);

		if (SUCCEEDED(hr)) {
		    fdlgPtr->lpVtbl->Release(fdlgPtr);

		    /* Looks like we have all we need */
		    tsdPtr->newFileDialogsState = FDLG_STATE_USE_NEW;
		}
	    }
	}

    }

    return (tsdPtr->newFileDialogsState == FDLG_STATE_USE_NEW);
}

/*
 *----------------------------------------------------------------------
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
        hr = fdlgIf->lpVtbl->SetFileName(fdlgIf, optsPtr->file);
        if (FAILED(hr))
            goto vamoose;
    }

    if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') {
        Tcl_Obj *normPath, *iniDirPath;
        iniDirPath = Tcl_NewStringObj(Tcl_DStringValue(&optsPtr->utfDirString), -1);
        Tcl_IncrRefCount(iniDirPath);
        normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath);
        /* XXX - Note on failures do not raise error, simply ignore ini dir */
        if (normPath) {
            LPCWSTR nativePath;
            Tcl_IncrRefCount(normPath);
            nativePath = (LPCWSTR)Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/
            if (nativePath) {
                hr = ShellProcs.SHCreateItemFromParsingName(
                    nativePath, NULL,
                    &IIDIShellItem, (void **) &dirIf);
                if (SUCCEEDED(hr)) {
                    /* Note we use SetFolder, not SetDefaultFolder - see MSDN */
                    fdlgIf->lpVtbl->SetFolder(fdlgIf, dirIf); /* Ignore errors */
                }
            }







|








|







1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
        hr = fdlgIf->lpVtbl->SetFileName(fdlgIf, optsPtr->file);
        if (FAILED(hr))
            goto vamoose;
    }

    if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') {
        Tcl_Obj *normPath, *iniDirPath;
        iniDirPath = Tcl_NewStringObj(Tcl_DStringValue(&optsPtr->utfDirString), TCL_INDEX_NONE);
        Tcl_IncrRefCount(iniDirPath);
        normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath);
        /* XXX - Note on failures do not raise error, simply ignore ini dir */
        if (normPath) {
            LPCWSTR nativePath;
            Tcl_IncrRefCount(normPath);
            nativePath = (LPCWSTR)Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/
            if (nativePath) {
                hr = SHCreateItemFromParsingName(
                    nativePath, NULL,
                    &IIDIShellItem, (void **) &dirIf);
                if (SUCCEEDED(hr)) {
                    /* Note we use SetFolder, not SetDefaultFolder - see MSDN */
                    fdlgIf->lpVtbl->SetFolder(fdlgIf, dirIf); /* Ignore errors */
                }
            }
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
    HWND hWnd;
    Tcl_DString utfFilterString, ds;
    Tcl_DString extString, filterString, dirString, titleString;
    const char *str;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
        Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    ZeroMemory(&ofnData, sizeof(OFNData));
    Tcl_DStringInit(&utfFilterString);
    Tcl_DStringInit(&dirString); /* XXX - original code was missing this
                                    leaving dirString uninitialized for
                                    the unlikely code path where cwd failed */

    if (MakeFilter(interp, optsPtr->filterObj, &utfFilterString,
                   optsPtr->initialTypeObj, &filterIndex) != TCL_OK) {
	goto end;
    }

    Tk_MakeWindowExist(optsPtr->tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(optsPtr->tkwin));

    ZeroMemory(&ofn, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = hWnd;
    ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner);
    ofn.lpstrFile = optsPtr->file;
    ofn.nMaxFile = TK_MULTI_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
	    | OFN_EXPLORER| OFN_ENABLEHOOK| OFN_ENABLESIZING;







|













|







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
    HWND hWnd;
    Tcl_DString utfFilterString, ds;
    Tcl_DString extString, filterString, dirString, titleString;
    const char *str;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
        Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    memset(&ofnData, 0, sizeof(OFNData));
    Tcl_DStringInit(&utfFilterString);
    Tcl_DStringInit(&dirString); /* XXX - original code was missing this
                                    leaving dirString uninitialized for
                                    the unlikely code path where cwd failed */

    if (MakeFilter(interp, optsPtr->filterObj, &utfFilterString,
                   optsPtr->initialTypeObj, &filterIndex) != TCL_OK) {
	goto end;
    }

    Tk_MakeWindowExist(optsPtr->tkwin);
    hWnd = Tk_GetHWND(Tk_WindowId(optsPtr->tkwin));

    memset(&ofn, 0, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = hWnd;
    ofn.hInstance = TkWinGetHInstance(ofn.hwndOwner);
    ofn.lpstrFile = optsPtr->file;
    ofn.nMaxFile = TK_MULTI_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
	    | OFN_EXPLORER| OFN_ENABLEHOOK| OFN_ENABLESIZING;
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642

    if (optsPtr->extObj != NULL) {
	str = Tcl_GetString(optsPtr->extObj);
	if (str[0] == '.') {
	    ++str;
	}
	Tcl_DStringInit(&extString);
	ofn.lpstrDefExt = Tcl_UtfToWCharDString(str, -1, &extString);
    }

    Tcl_DStringInit(&filterString);
    ofn.lpstrFilter = Tcl_UtfToWCharDString(Tcl_DStringValue(&utfFilterString),
	    Tcl_DStringLength(&utfFilterString), &filterString);
    ofn.nFilterIndex = filterIndex;








|







1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581

    if (optsPtr->extObj != NULL) {
	str = Tcl_GetString(optsPtr->extObj);
	if (str[0] == '.') {
	    ++str;
	}
	Tcl_DStringInit(&extString);
	ofn.lpstrDefExt = Tcl_UtfToWCharDString(str, TCL_INDEX_NONE, &extString);
    }

    Tcl_DStringInit(&filterString);
    ofn.lpstrFilter = Tcl_UtfToWCharDString(Tcl_DStringValue(&utfFilterString),
	    Tcl_DStringLength(&utfFilterString), &filterString);
    ofn.nFilterIndex = filterIndex;

1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
	}
	Tcl_DStringFree(&cwd);
    }
    ofn.lpstrInitialDir = (WCHAR *) Tcl_DStringValue(&dirString);

    if (optsPtr->titleObj != NULL) {
	Tcl_DStringInit(&titleString);
	ofn.lpstrTitle = Tcl_UtfToWCharDString(Tcl_GetString(optsPtr->titleObj), -1, &titleString);
    }

    /*
     * Popup the dialog.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);







|







1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
	}
	Tcl_DStringFree(&cwd);
    }
    ofn.lpstrInitialDir = (WCHAR *) Tcl_DStringValue(&dirString);

    if (optsPtr->titleObj != NULL) {
	Tcl_DStringInit(&titleString);
	ofn.lpstrTitle = Tcl_UtfToWCharDString(Tcl_GetString(optsPtr->titleObj), TCL_INDEX_NONE, &titleString);
    }

    /*
     * Popup the dialog.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
		    Tcl_DString filenameBuf;

		    count++;
		    ConvertExternalFilename(files, &filenameBuf);

		    fullnameObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
			    Tcl_DStringLength(&ds));
		    Tcl_AppendToObj(fullnameObj, "/", -1);
		    Tcl_AppendToObj(fullnameObj, Tcl_DStringValue(&filenameBuf),
			    Tcl_DStringLength(&filenameBuf));
		    gotFilename = 1;
		    Tcl_DStringFree(&filenameBuf);
		    Tcl_ListObjAppendElement(NULL, returnList, fullnameObj);
		}
	    }







|







1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
		    Tcl_DString filenameBuf;

		    count++;
		    ConvertExternalFilename(files, &filenameBuf);

		    fullnameObj = Tcl_NewStringObj(Tcl_DStringValue(&ds),
			    Tcl_DStringLength(&ds));
		    Tcl_AppendToObj(fullnameObj, "/", TCL_INDEX_NONE);
		    Tcl_AppendToObj(fullnameObj, Tcl_DStringValue(&filenameBuf),
			    Tcl_DStringLength(&filenameBuf));
		    gotFilename = 1;
		    Tcl_DStringFree(&filenameBuf);
		    Tcl_ListObjAppendElement(NULL, returnList, fullnameObj);
		}
	    }
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
				Tcl_DStringLength(&ds)));
		gotFilename |= (Tcl_DStringLength(&ds) > 0);
	    }
	    Tcl_SetObjResult(interp, returnList);
	    Tcl_DStringFree(&ds);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    ConvertExternalFilename(ofn.lpstrFile, &ds), -1));
	    gotFilename = (Tcl_DStringLength(&ds) > 0);
	    Tcl_DStringFree(&ds);
	}
	result = TCL_OK;
	if ((ofn.nFilterIndex > 0) && gotFilename && optsPtr->typeVariableObj
		&& optsPtr->filterObj) {
	    int listObjc, count;
	    Tcl_Obj **listObjv = NULL;
	    Tcl_Obj **typeInfo = NULL;

	    if (Tcl_ListObjGetElements(interp, optsPtr->filterObj,
		    &listObjc, &listObjv) != TCL_OK) {
		result = TCL_ERROR;
	    } else if (Tcl_ListObjGetElements(interp,







|






|







1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
				Tcl_DStringLength(&ds)));
		gotFilename |= (Tcl_DStringLength(&ds) > 0);
	    }
	    Tcl_SetObjResult(interp, returnList);
	    Tcl_DStringFree(&ds);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    ConvertExternalFilename(ofn.lpstrFile, &ds), TCL_INDEX_NONE));
	    gotFilename = (Tcl_DStringLength(&ds) > 0);
	    Tcl_DStringFree(&ds);
	}
	result = TCL_OK;
	if ((ofn.nFilterIndex > 0) && gotFilename && optsPtr->typeVariableObj
		&& optsPtr->filterObj) {
	    Tcl_Size listObjc, count;
	    Tcl_Obj **listObjv = NULL;
	    Tcl_Obj **typeInfo = NULL;

	    if (Tcl_ListObjGetElements(interp, optsPtr->filterObj,
		    &listObjc, &listObjv) != TCL_OK) {
		result = TCL_ERROR;
	    } else if (Tcl_ListObjGetElements(interp,
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
GetFileName(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum OFNOper oper)  	/* 1 to call GetOpenFileName(), 0 to call
				 * GetSaveFileName(). */
{
    OFNOpts ofnOpts;







|







1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
GetFileName(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum OFNOper oper)  	/* 1 to call GetOpenFileName(), 0 to call
				 * GetSaveFileName(). */
{
    OFNOpts ofnOpts;
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935


/*
 *-------------------------------------------------------------------------
 *
 * OFNHookProc --
 *
 *	Dialog box hook function. This is used to sets the "tk_dialog"
 *	variable for test/debugging when the dialog is ready to receive
 *	messages. When multiple file selection is enabled this function
 *	is used to process the list of names.
 *
 * Results:
 *	Returns 0 to allow default processing of messages to occur.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static UINT APIENTRY
OFNHookProc(
    HWND hdlg,			/* Handle to child dialog window. */
    UINT uMsg,			/* Message identifier */
    WPARAM wParam,		/* Message parameter */
    LPARAM lParam)		/* Message parameter */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    OPENFILENAME *ofnPtr;
    OFNData *ofnData;
    (void)wParam;

    if (uMsg == WM_INITDIALOG) {
	TkWinSetUserData(hdlg, lParam);
    } else if (uMsg == WM_NOTIFY) {
	OFNOTIFY *notifyPtr = (OFNOTIFY *) lParam;

	/*







|

















|






<







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


/*
 *-------------------------------------------------------------------------
 *
 * OFNHookProc --
 *
 *	Dialog box hook function. This is used to set the "tk_dialog"
 *	variable for test/debugging when the dialog is ready to receive
 *	messages. When multiple file selection is enabled this function
 *	is used to process the list of names.
 *
 * Results:
 *	Returns 0 to allow default processing of messages to occur.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static UINT APIENTRY
OFNHookProc(
    HWND hdlg,			/* Handle to child dialog window. */
    UINT uMsg,			/* Message identifier */
    TCL_UNUSED(WPARAM),	/* Message parameter */
    LPARAM lParam)		/* Message parameter */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    OPENFILENAME *ofnPtr;
    OFNData *ofnData;


    if (uMsg == WM_INITDIALOG) {
	TkWinSetUserData(hdlg, lParam);
    } else if (uMsg == WM_NOTIFY) {
	OFNOTIFY *notifyPtr = (OFNOTIFY *) lParam;

	/*
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
	*p++ = '.';
	*p++ = '*';
	*p++ = '\0';
	*p++ = '\0';
	*p = '\0';

    } else {
	TkSizeT len;

	if (valuePtr == NULL) {
	    len = 0;
	} else {
	    (void) TkGetStringFromObj(valuePtr, &len);
	}

	/*
	 * We format the filetype into a string understood by Windows: {"Text
	 * Documents" {.doc .txt} {TEXT}} becomes "Text Documents
	 * (*.doc,*.txt)\0*.doc;*.txt\0"
	 *







|




|







2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
	*p++ = '.';
	*p++ = '*';
	*p++ = '\0';
	*p++ = '\0';
	*p = '\0';

    } else {
	Tcl_Size len;

	if (valuePtr == NULL) {
	    len = 0;
	} else {
	    (void) Tcl_GetStringFromObj(valuePtr, &len);
	}

	/*
	 * We format the filetype into a string understood by Windows: {"Text
	 * Documents" {.doc .txt} {TEXT}} becomes "Text Documents
	 * (*.doc,*.txt)\0*.doc;*.txt\0"
	 *
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
	 * characters.
	 */

	*p++ = '\0';
	*p = '\0';
    }

    Tcl_DStringAppend(dsPtr, filterStr, (int) (p - filterStr));
    ckfree(filterStr);

    TkFreeFileFilters(&flist);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeFilterVista
 *
 *      Frees storage previously allocated by MakeFilterVista.
 *      count is the number of elements in dlgFilterPtr[]
 */
static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr)
{
    if (dlgFilterPtr != NULL) {
        DWORD dw;
        for (dw = 0; dw < count; ++dw) {
            if (dlgFilterPtr[dw].pszName != NULL)
                ckfree((char *)dlgFilterPtr[dw].pszName);
            if (dlgFilterPtr[dw].pszSpec != NULL)
                ckfree((char *)dlgFilterPtr[dw].pszSpec);
        }
        ckfree(dlgFilterPtr);
    }
}

/*
 *----------------------------------------------------------------------







|




















|

|







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
	 * characters.
	 */

	*p++ = '\0';
	*p = '\0';
    }

    Tcl_DStringAppend(dsPtr, filterStr, p - filterStr);
    ckfree(filterStr);

    TkFreeFileFilters(&flist);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeFilterVista
 *
 *      Frees storage previously allocated by MakeFilterVista.
 *      count is the number of elements in dlgFilterPtr[]
 */
static void FreeFilterVista(DWORD count, TCLCOMDLG_FILTERSPEC *dlgFilterPtr)
{
    if (dlgFilterPtr != NULL) {
        DWORD dw;
        for (dw = 0; dw < count; ++dw) {
            if (dlgFilterPtr[dw].pszName != NULL)
                ckfree((void *)dlgFilterPtr[dw].pszName);
            if (dlgFilterPtr[dw].pszSpec != NULL)
                ckfree((void *)dlgFilterPtr[dw].pszSpec);
        }
        ckfree(dlgFilterPtr);
    }
}

/*
 *----------------------------------------------------------------------
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
    dlgFilterPtr = (TCLCOMDLG_FILTERSPEC *)ckalloc(flist.numFilters * sizeof(*dlgFilterPtr));

    for (i = 0, filterPtr = flist.filters;
         filterPtr;
         filterPtr = filterPtr->next, ++i) {
	const char *sep;
	FileFilterClause *clausePtr;
	int nbytes;

	/* Check if this entry should be shown as the default */
	if (initial && strcmp(initial, filterPtr->name) == 0)
            initialIndex = i+1; /* Windows filter indices are 1-based */

	/* First stash away the text description of the pattern */
        Tcl_DStringInit(&ds);
        Tcl_UtfToWCharDString(filterPtr->name, -1, &ds);
	nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */
	nbytes += sizeof(WCHAR);         /* Terminating \0 */
	dlgFilterPtr[i].pszName = (LPCWSTR)ckalloc(nbytes);
	memmove((void *) dlgFilterPtr[i].pszName, Tcl_DStringValue(&ds), nbytes);
	Tcl_DStringFree(&ds);

	/*
	 * Loop through and join patterns with a ";" Each "clause"
	 * corresponds to a single textual description (called typename)
	 * in the tk_getOpenFile docs. Each such typename may occur
	 * multiple times and all these form a single filter entry
	 * with one clause per occurence. Further each clause may specify
	 * multiple patterns. Hence the nested loop here.
	 */
	sep = "";
	for (clausePtr=filterPtr->clauses ; clausePtr;
	     clausePtr=clausePtr->next) {
	    GlobPattern *globPtr;
	    for (globPtr = clausePtr->patterns; globPtr;
		    globPtr = globPtr->next) {
		Tcl_DStringAppend(&patterns, sep, -1);
		Tcl_DStringAppend(&patterns, globPtr->pattern, -1);
		sep = ";";
	    }
	}

	/* Again we need a Unicode form of the string */
        Tcl_DStringInit(&ds);
        Tcl_UtfToWCharDString(Tcl_DStringValue(&patterns), -1, &ds);
	nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */
	nbytes += sizeof(WCHAR);         /* Terminating \0 */
	dlgFilterPtr[i].pszSpec = (LPCWSTR)ckalloc(nbytes);
	memmove((void *)dlgFilterPtr[i].pszSpec, Tcl_DStringValue(&ds), nbytes);
	Tcl_DStringFree(&ds);
	Tcl_DStringSetLength(&patterns, 0);
    }







|







|




















|
|






|







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
    dlgFilterPtr = (TCLCOMDLG_FILTERSPEC *)ckalloc(flist.numFilters * sizeof(*dlgFilterPtr));

    for (i = 0, filterPtr = flist.filters;
         filterPtr;
         filterPtr = filterPtr->next, ++i) {
	const char *sep;
	FileFilterClause *clausePtr;
	size_t nbytes;

	/* Check if this entry should be shown as the default */
	if (initial && strcmp(initial, filterPtr->name) == 0)
            initialIndex = i+1; /* Windows filter indices are 1-based */

	/* First stash away the text description of the pattern */
        Tcl_DStringInit(&ds);
        Tcl_UtfToWCharDString(filterPtr->name, TCL_INDEX_NONE, &ds);
	nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */
	nbytes += sizeof(WCHAR);         /* Terminating \0 */
	dlgFilterPtr[i].pszName = (LPCWSTR)ckalloc(nbytes);
	memmove((void *) dlgFilterPtr[i].pszName, Tcl_DStringValue(&ds), nbytes);
	Tcl_DStringFree(&ds);

	/*
	 * Loop through and join patterns with a ";" Each "clause"
	 * corresponds to a single textual description (called typename)
	 * in the tk_getOpenFile docs. Each such typename may occur
	 * multiple times and all these form a single filter entry
	 * with one clause per occurence. Further each clause may specify
	 * multiple patterns. Hence the nested loop here.
	 */
	sep = "";
	for (clausePtr=filterPtr->clauses ; clausePtr;
	     clausePtr=clausePtr->next) {
	    GlobPattern *globPtr;
	    for (globPtr = clausePtr->patterns; globPtr;
		    globPtr = globPtr->next) {
		Tcl_DStringAppend(&patterns, sep, TCL_INDEX_NONE);
		Tcl_DStringAppend(&patterns, globPtr->pattern, TCL_INDEX_NONE);
		sep = ";";
	    }
	}

	/* Again we need a Unicode form of the string */
        Tcl_DStringInit(&ds);
        Tcl_UtfToWCharDString(Tcl_DStringValue(&patterns), TCL_INDEX_NONE, &ds);
	nbytes = Tcl_DStringLength(&ds); /* # bytes, not Unicode chars */
	nbytes += sizeof(WCHAR);         /* Terminating \0 */
	dlgFilterPtr[i].pszSpec = (LPCWSTR)ckalloc(nbytes);
	memmove((void *)dlgFilterPtr[i].pszSpec, Tcl_DStringValue(&ds), nbytes);
	Tcl_DStringFree(&ds);
	Tcl_DStringSetLength(&patterns, 0);
    }
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
 * - -title is really -message.
 *
 *----------------------------------------------------------------------
 */

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. */
{
    WCHAR path[MAX_PATH];
    int oldMode, result;
    LPCITEMIDLIST pidl;		/* Returned by browser */







|







2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
 * - -title is really -message.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseDirectoryObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WCHAR path[MAX_PATH];
    int oldMode, result;
    LPCITEMIDLIST pidl;		/* Returned by browser */
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
        CleanupOFNOptions(&ofnOpts);
        return result;
    }

    /* Older dialogs */

    path[0] = '\0';
    ZeroMemory(&cdCBData, sizeof(ChooseDir));
    cdCBData.interp = interp;
    cdCBData.mustExist = ofnOpts.mustExist;

    utfDir = Tcl_DStringValue(&ofnOpts.utfDirString);
    if (utfDir[0] != '\0') {
	LPCWSTR uniStr;

	Tcl_DStringInit(&tempString);
	Tcl_UtfToWCharDString(Tcl_DStringValue(&ofnOpts.utfDirString), -1,
                          &tempString);
        uniStr = (WCHAR *) Tcl_DStringValue(&tempString);

        /* Convert possible relative path to full path to keep dialog happy. */

        GetFullPathNameW(uniStr, MAX_PATH, saveDir, NULL);
        wcsncpy(cdCBData.initDir, saveDir, MAX_PATH);







|








|







2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
        CleanupOFNOptions(&ofnOpts);
        return result;
    }

    /* Older dialogs */

    path[0] = '\0';
    memset(&cdCBData, 0, sizeof(ChooseDir));
    cdCBData.interp = interp;
    cdCBData.mustExist = ofnOpts.mustExist;

    utfDir = Tcl_DStringValue(&ofnOpts.utfDirString);
    if (utfDir[0] != '\0') {
	LPCWSTR uniStr;

	Tcl_DStringInit(&tempString);
	Tcl_UtfToWCharDString(Tcl_DStringValue(&ofnOpts.utfDirString), TCL_INDEX_NONE,
                          &tempString);
        uniStr = (WCHAR *) Tcl_DStringValue(&tempString);

        /* Convert possible relative path to full path to keep dialog happy. */

        GetFullPathNameW(uniStr, MAX_PATH, saveDir, NULL);
        wcsncpy(cdCBData.initDir, saveDir, MAX_PATH);
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
    if (wcslen(cdCBData.initDir) == 0) {
	GetCurrentDirectoryW(MAX_PATH, cdCBData.initDir);
    }
    bInfo.lParam = (LPARAM) &cdCBData;

    if (ofnOpts.titleObj != NULL) {
	Tcl_DStringInit(&titleString);
	bInfo.lpszTitle = Tcl_UtfToWCharDString(Tcl_GetString(ofnOpts.titleObj), -1, &titleString);
    } else {
	bInfo.lpszTitle = L"Please choose a directory, then select OK.";
    }

    /*
     * Set flags to add edit box, status text line and use the new ui. Allow
     * override with magic variable (ignore errors in retrieval). See







|







2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
    if (wcslen(cdCBData.initDir) == 0) {
	GetCurrentDirectoryW(MAX_PATH, cdCBData.initDir);
    }
    bInfo.lParam = (LPARAM) &cdCBData;

    if (ofnOpts.titleObj != NULL) {
	Tcl_DStringInit(&titleString);
	bInfo.lpszTitle = Tcl_UtfToWCharDString(Tcl_GetString(ofnOpts.titleObj), TCL_INDEX_NONE, &titleString);
    } else {
	bInfo.lpszTitle = L"Please choose a directory, then select OK.";
    }

    /*
     * Set flags to add edit box, status text line and use the new ui. Allow
     * override with magic variable (ignore errors in retrieval). See
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
	/*
	 * Null for cancel button or invalid dir, otherwise valid.
	 */

	if (pidl != NULL) {
	    if (!SHGetPathFromIDListW(pidl, path)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error: not a file system folder", -1));
		Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "PSEUDO", NULL);
	    }
	    pMalloc->lpVtbl->Free(pMalloc, (void *) pidl);
	} else if (wcslen(cdCBData.retDir) > 0) {
	    wcscpy(path, cdCBData.retDir);
	}
	pMalloc->lpVtbl->Release(pMalloc);







|







2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
	/*
	 * Null for cancel button or invalid dir, otherwise valid.
	 */

	if (pidl != NULL) {
	    if (!SHGetPathFromIDListW(pidl, path)) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error: not a file system folder", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "PSEUDO", NULL);
	    }
	    pMalloc->lpVtbl->Free(pMalloc, (void *) pidl);
	} else if (wcslen(cdCBData.retDir) > 0) {
	    wcscpy(path, cdCBData.retDir);
	}
	pMalloc->lpVtbl->Release(pMalloc);
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
     */

    Tcl_ResetResult(interp);
    if (*path) {
	Tcl_DString ds;

	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		ConvertExternalFilename(path, &ds), -1));
	Tcl_DStringFree(&ds);
    }

    CleanupOFNOptions(&ofnOpts);
    return TCL_OK;
}








|







2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
     */

    Tcl_ResetResult(interp);
    if (*path) {
	Tcl_DString ds;

	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		ConvertExternalFilename(path, &ds), TCL_INDEX_NONE));
	Tcl_DStringFree(&ds);
    }

    CleanupOFNOptions(&ofnOpts);
    return TCL_OK;
}

2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
	     * at this point?
	     */

	    chooseDirSharedData->retDir[0] = '\0';
	    return 1;
	}
	Tcl_DStringSetLength(&initDirString, 0);
	wcsncpy(string, Tcl_UtfToWCharDString(Tcl_DStringValue(&tempString), -1, &initDirString),
		MAX_PATH);
	Tcl_DStringFree(&initDirString);
	Tcl_DStringFree(&tempString);

	if (SetCurrentDirectoryW(string) == 0) {

	    /*







|







2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
	     * at this point?
	     */

	    chooseDirSharedData->retDir[0] = '\0';
	    return 1;
	}
	Tcl_DStringSetLength(&initDirString, 0);
	wcsncpy(string, Tcl_UtfToWCharDString(Tcl_DStringValue(&tempString), TCL_INDEX_NONE, &initDirString),
		MAX_PATH);
	Tcl_DStringFree(&initDirString);
	Tcl_DStringFree(&tempString);

	if (SetCurrentDirectoryW(string) == 0) {

	    /*
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
	 * -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
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	} else {
	    // disable the OK button
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*







|


|







2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
	 * -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 */
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	} else {
	    /* disable the OK button */
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
 *	This function implements the MessageBox window for the Windows
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	None. The MessageBox window will be destroy before this function
 *	returns.
 *
 *----------------------------------------------------------------------
 */

int
Tk_MessageBoxObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    HWND hWnd;
    Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj;







|







|







2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
 *	This function implements the MessageBox window for the Windows
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	None. The MessageBox window will be destroyed before this function
 *	returns.
 *
 *----------------------------------------------------------------------
 */

int
Tk_MessageBoxObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    HWND hWnd;
    Tcl_Obj *messageObj, *titleObj, *detailObj, *tmpObj;
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
    for (i = 1; i < objc; i += 2) {
	int index;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, optionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL);
	    return TCL_ERROR;







|
|







2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
    for (i = 1; i < objc; i += 2) {
	int index;
	Tcl_Obj *optionPtr, *valuePtr;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings,
		"option", TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i + 1 == objc) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "MSGBOX", "VALUE", NULL);
	    return TCL_ERROR;
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
     * (Windows loses sync).
     */

    EnableWindow(hWnd, 1);

    Tcl_DecrRefCount(tmpObj);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    TkFindStateString(buttonMap, winCode), -1));
    return TCL_OK;
}

static LRESULT CALLBACK
MsgBoxCBTProc(
    int nCode,
    WPARAM wParam,







|







2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
     * (Windows loses sync).
     */

    EnableWindow(hWnd, 1);

    Tcl_DecrRefCount(tmpObj);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    TkFindStateString(buttonMap, winCode), TCL_INDEX_NONE));
    return TCL_OK;
}

static LRESULT CALLBACK
MsgBoxCBTProc(
    int nCode,
    WPARAM wParam,
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
 *	the test command 'tkwinevent debug 1'.
 *
 * ----------------------------------------------------------------------
 */

static void
SetTkDialog(
    ClientData clientData)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    char buf[32];

    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)clientData);
    Tcl_SetVar2(tsdPtr->debugInterp, "tk_dialog", NULL, buf, TCL_GLOBAL_ONLY);
}

/*
 * Factored out a common pattern in use in this file.
 */








|





|







2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
 *	the test command 'tkwinevent debug 1'.
 *
 * ----------------------------------------------------------------------
 */

static void
SetTkDialog(
    void *clientData)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    char buf[32];

    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)clientData);
    Tcl_SetVar2(tsdPtr->debugInterp, "tk_dialog", NULL, buf, TCL_GLOBAL_ONLY);
}

/*
 * Factored out a common pattern in use in this file.
 */

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
    Tcl_Obj *resObj;
    int pt = 0;

    resObj = Tcl_NewListObj(0, NULL);
    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(plf->lfFaceName, wcslen(plf->lfFaceName), &ds);
    Tcl_ListObjAppendElement(NULL, resObj,
	    Tcl_NewStringObj(Tcl_DStringValue(&ds), -1));
    Tcl_DStringFree(&ds);
    pt = -MulDiv(plf->lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
    Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewWideIntObj(pt));
    if (plf->lfWeight >= 700) {
	Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", -1));
    }
    if (plf->lfItalic) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("italic", -1));
    }
    if (plf->lfUnderline) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("underline", -1));
    }
    if (plf->lfStrikeOut) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("overstrike", -1));
    }
    return resObj;
}

static void
ApplyLogfont(
    Tcl_Interp *interp,
    Tcl_Obj *cmdObj,
    HDC hdc,
    LOGFONTW *logfontPtr)
{
    int objc;
    Tcl_Obj **objv, **tmpv;

    Tcl_ListObjGetElements(NULL, cmdObj, &objc, &objv);
    tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
    tmpv[objc] = GetFontObj(hdc, logfontPtr);
    TkBackgroundEvalObjv(interp, objc+1, tmpv, TCL_EVAL_GLOBAL);







|




|



|



|



|











|







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
    Tcl_Obj *resObj;
    int pt = 0;

    resObj = Tcl_NewListObj(0, NULL);
    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(plf->lfFaceName, wcslen(plf->lfFaceName), &ds);
    Tcl_ListObjAppendElement(NULL, resObj,
	    Tcl_NewStringObj(Tcl_DStringValue(&ds), TCL_INDEX_NONE));
    Tcl_DStringFree(&ds);
    pt = -MulDiv(plf->lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
    Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewWideIntObj(pt));
    if (plf->lfWeight >= 700) {
	Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", TCL_INDEX_NONE));
    }
    if (plf->lfItalic) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("italic", TCL_INDEX_NONE));
    }
    if (plf->lfUnderline) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("underline", TCL_INDEX_NONE));
    }
    if (plf->lfStrikeOut) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("overstrike", TCL_INDEX_NONE));
    }
    return resObj;
}

static void
ApplyLogfont(
    Tcl_Interp *interp,
    Tcl_Obj *cmdObj,
    HDC hdc,
    LOGFONTW *logfontPtr)
{
    Tcl_Size objc;
    Tcl_Obj **objv, **tmpv;

    Tcl_ListObjGetElements(NULL, cmdObj, &objc, &objv);
    tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
    memcpy(tmpv, objv, sizeof(Tcl_Obj *) * objc);
    tmpv[objc] = GetFontObj(hdc, logfontPtr);
    TkBackgroundEvalObjv(interp, objc+1, tmpv, TCL_EVAL_GLOBAL);
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
static UINT_PTR CALLBACK
HookProc(
    HWND hwndDlg,
    UINT msg,
    WPARAM wParam,
    LPARAM lParam)
{
    CHOOSEFONT *pcf = (CHOOSEFONT *) lParam;
    HWND hwndCtrl;
    static HookData *phd = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (WM_INITDIALOG == msg && lParam != 0) {
	phd = (HookData *) pcf->lCustData;
	phd->hwnd = hwndDlg;
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = phd->interp;
	    Tcl_DoWhenIdle(SetTkDialog, hwndDlg);
	}
	if (phd->titleObj != NULL) {
	    Tcl_DString title;

	    Tcl_DStringInit(&title);
	    Tcl_UtfToWCharDString(Tcl_GetString(phd->titleObj), -1, &title);
	    if (Tcl_DStringLength(&title) > 0) {
		SetWindowTextW(hwndDlg, (LPCWSTR) Tcl_DStringValue(&title));
	    }
	    Tcl_DStringFree(&title);
	}

	/*







|
















|







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
static UINT_PTR CALLBACK
HookProc(
    HWND hwndDlg,
    UINT msg,
    WPARAM wParam,
    LPARAM lParam)
{
    CHOOSEFONTW *pcf = (CHOOSEFONTW *) lParam;
    HWND hwndCtrl;
    static HookData *phd = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (WM_INITDIALOG == msg && lParam != 0) {
	phd = (HookData *) pcf->lCustData;
	phd->hwnd = hwndDlg;
	if (tsdPtr->debugFlag) {
	    tsdPtr->debugInterp = phd->interp;
	    Tcl_DoWhenIdle(SetTkDialog, hwndDlg);
	}
	if (phd->titleObj != NULL) {
	    Tcl_DString title;

	    Tcl_DStringInit(&title);
	    Tcl_UtfToWCharDString(Tcl_GetString(phd->titleObj), TCL_INDEX_NONE, &title);
	    if (Tcl_DStringLength(&title) > 0) {
		SetWindowTextW(hwndDlg, (LPCWSTR) Tcl_DStringValue(&title));
	    }
	    Tcl_DStringFree(&title);
	}

	/*
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234

/*
 * Helper for the FontchooserConfigure command to return the current value of
 * any of the options (which may be NULL in the structure)
 */

enum FontchooserOption {
    FontchooserParent, FontchooserTitle, FontchooserFont, FontchooserCmd,
    FontchooserVisible
};

static Tcl_Obj *
FontchooserCget(
    HookData *hdPtr,
    int optionIndex)







|







3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172

/*
 * Helper for the FontchooserConfigure command to return the current value of
 * any of the options (which may be NULL in the structure)
 */

enum FontchooserOption {
    FontchooserCmd, FontchooserFont, FontchooserParent, FontchooserTitle,
    FontchooserVisible
};

static Tcl_Obj *
FontchooserCget(
    HookData *hdPtr,
    int optionIndex)
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
 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    HookData *hdPtr = NULL;

    int i, r = TCL_OK;
    static const char *const optionStrings[] = {
	"-parent", "-title", "-font", "-command", "-visible", NULL
    };

    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    /*
     * With no arguments we return all the options in a dict.
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
	Tcl_Obj *dictObj = Tcl_NewDictObj();

	for (i = 0; r == TCL_OK && optionStrings[i] != NULL; ++i) {
	    keyObj = Tcl_NewStringObj(optionStrings[i], -1);
	    valueObj = FontchooserCget(hdPtr, i);
	    r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj);
	}
	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		sizeof(char *),  "option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
	     * If one option and no arg - return the current value.
	     */








|

|




>
|

|













|












|
|







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
 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    void *clientData,	/* Main window */
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    HookData *hdPtr = NULL;
    Tcl_Size i;
    int r = TCL_OK;
    static const char *const optionStrings[] = {
	"-command", "-font", "-parent", "-title", "-visible", NULL
    };

    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    /*
     * With no arguments we return all the options in a dict.
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
	Tcl_Obj *dictObj = Tcl_NewDictObj();

	for (i = 0; r == TCL_OK && optionStrings[i] != NULL; ++i) {
	    keyObj = Tcl_NewStringObj(optionStrings[i], TCL_INDEX_NONE);
	    valueObj = FontchooserCget(hdPtr, i);
	    r = Tcl_DictObjPut(interp, dictObj, keyObj, valueObj);
	}
	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex;

	if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		"option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
	     * If one option and no arg - return the current value.
	     */

3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
	    return TCL_ERROR;
	}
	switch (optionIndex) {
	case FontchooserVisible: {
	    static const char *msg = "cannot change read-only option "
		    "\"-visible\": use the show or hide command";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL);
	    return TCL_ERROR;
	}
	case FontchooserParent: {
	    Tk_Window parent = Tk_NameToWindow(interp,
		    Tcl_GetString(objv[i+1]), tkwin);








|







3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
	    return TCL_ERROR;
	}
	switch (optionIndex) {
	case FontchooserVisible: {
	    static const char *msg = "cannot change read-only option "
		    "\"-visible\": use the show or hide command";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "FONTDIALOG", "READONLY", NULL);
	    return TCL_ERROR;
	}
	case FontchooserParent: {
	    Tk_Window parent = Tk_NameToWindow(interp,
		    Tcl_GetString(objv[i+1]), tkwin);

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
 *	additional state.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    ClientData clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_DString ds;
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    CHOOSEFONTW cf;
    LOGFONTW lf;
    HDC hdc;
    HookData *hdPtr;
    int r = TCL_OK, oldMode = 0;
    (void)objc;
    (void)objv;

    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    parent = tkwin;
    if (hdPtr->parentObj) {
	parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj),
		tkwin);
	if (parent == NULL) {
	    return TCL_ERROR;
	}
    }

    Tk_MakeWindowExist(parent);

    ZeroMemory(&cf, sizeof(CHOOSEFONT));
    ZeroMemory(&lf, sizeof(LOGFONT));
    lf.lfCharSet = DEFAULT_CHARSET;
    cf.lStructSize = sizeof(CHOOSEFONT);
    cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent));
    cf.lpLogFont = &lf;
    cf.nFontType = SCREEN_FONTTYPE;
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK;
    cf.rgbColors = RGB(0,0,0);
    cf.lpfnHook = HookProc;
    cf.lCustData = (INT_PTR) hdPtr;







|

|
|








<
<














|
|

|







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
 *	additional state.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    void *clientData,	/* Main window */
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Size),
    TCL_UNUSED(Tcl_Obj *const *))
{
    Tcl_DString ds;
    Tk_Window tkwin = (Tk_Window)clientData, parent;
    CHOOSEFONTW cf;
    LOGFONTW lf;
    HDC hdc;
    HookData *hdPtr;
    int r = TCL_OK, oldMode = 0;



    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    parent = tkwin;
    if (hdPtr->parentObj) {
	parent = Tk_NameToWindow(interp, Tcl_GetString(hdPtr->parentObj),
		tkwin);
	if (parent == NULL) {
	    return TCL_ERROR;
	}
    }

    Tk_MakeWindowExist(parent);

    memset(&cf, 0, sizeof(CHOOSEFONTW));
    memset(&lf, 0, sizeof(LOGFONTW));
    lf.lfCharSet = DEFAULT_CHARSET;
    cf.lStructSize = sizeof(CHOOSEFONTW);
    cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent));
    cf.lpLogFont = &lf;
    cf.nFontType = SCREEN_FONTTYPE;
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK;
    cf.rgbColors = RGB(0,0,0);
    cf.lpfnHook = HookProc;
    cf.lCustData = (INT_PTR) hdPtr;
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

	if (f == NULL) {
	    return TCL_ERROR;
	}
	fontPtr = (TkFont *) f;
	cf.Flags |= CF_INITTOLOGFONTSTRUCT;
	Tcl_DStringInit(&ds);
	wcsncpy(lf.lfFaceName, Tcl_UtfToWCharDString(fontPtr->fa.family, -1, &ds),
		LF_FACESIZE-1);
	Tcl_DStringFree(&ds);
	lf.lfFaceName[LF_FACESIZE-1] = 0;
	lf.lfHeight = -MulDiv((int)(TkFontGetPoints(tkwin, fontPtr->fa.size) + 0.5),
	    GetDeviceCaps(hdc, LOGPIXELSY), 72);
	if (fontPtr->fa.weight == TK_FW_BOLD) {
	    lf.lfWeight = FW_BOLD;







|







3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435

	if (f == NULL) {
	    return TCL_ERROR;
	}
	fontPtr = (TkFont *) f;
	cf.Flags |= CF_INITTOLOGFONTSTRUCT;
	Tcl_DStringInit(&ds);
	wcsncpy(lf.lfFaceName, Tcl_UtfToWCharDString(fontPtr->fa.family, TCL_INDEX_NONE, &ds),
		LF_FACESIZE-1);
	Tcl_DStringFree(&ds);
	lf.lfFaceName[LF_FACESIZE-1] = 0;
	lf.lfHeight = -MulDiv((int)(TkFontGetPoints(tkwin, fontPtr->fa.size) + 0.5),
	    GetDeviceCaps(hdc, LOGPIXELSY), 72);
	if (fontPtr->fa.weight == TK_FW_BOLD) {
	    lf.lfWeight = FW_BOLD;
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
	if (fontPtr->fa.overstrike) {
	    lf.lfStrikeOut = TRUE;
	}
	Tk_FreeFont(f);
    }

    if (TCL_OK == r && hdPtr->cmdObj != NULL) {
	int len = 0;

	r = Tcl_ListObjLength(interp, hdPtr->cmdObj, &len);
	if (len > 0) {
	    cf.Flags |= CF_APPLY;
	}
    }








|







3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
	if (fontPtr->fa.overstrike) {
	    lf.lfStrikeOut = TRUE;
	}
	Tk_FreeFont(f);
    }

    if (TCL_OK == r && hdPtr->cmdObj != NULL) {
	Tcl_Size len = 0;

	r = Tcl_ListObjLength(interp, hdPtr->cmdObj, &len);
	if (len > 0) {
	    cf.Flags |= CF_APPLY;
	}
    }

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
 *	destroy the dialog
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    ClientData dummy,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    HookData *hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);
    (void)dummy;
    (void)objc;
    (void)objv;

    if (hdPtr->hwnd && IsWindow(hdPtr->hwnd)) {
	EndDialog(hdPtr->hwnd, 0);
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * DeleteHookData --
 *
 *	Clean up the font chooser configuration data when the interp is
 *	destroyed.
 *
 * ----------------------------------------------------------------------
 */

static void
DeleteHookData(ClientData clientData, Tcl_Interp *dummy)


{
    HookData *hdPtr = (HookData *)clientData;
    (void)dummy;

    if (hdPtr->parentObj) {
	Tcl_DecrRefCount(hdPtr->parentObj);
    }
    if (hdPtr->fontObj) {
	Tcl_DecrRefCount(hdPtr->fontObj);
    }







|

|
|


<
<
<



















|
>
>


<







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
 *	destroy the dialog
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(Tcl_Size),
    TCL_UNUSED(Tcl_Obj *const *))
{
    HookData *hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);




    if (hdPtr->hwnd && IsWindow(hdPtr->hwnd)) {
	EndDialog(hdPtr->hwnd, 0);
    }
    return TCL_OK;
}

/*
 * ----------------------------------------------------------------------
 *
 * DeleteHookData --
 *
 *	Clean up the font chooser configuration data when the interp is
 *	destroyed.
 *
 * ----------------------------------------------------------------------
 */

static void
DeleteHookData(
    void *clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    HookData *hdPtr = (HookData *)clientData;


    if (hdPtr->parentObj) {
	Tcl_DecrRefCount(hdPtr->parentObj);
    }
    if (hdPtr->fontObj) {
	Tcl_DecrRefCount(hdPtr->fontObj);
    }
3615
3616
3617
3618
3619
3620
3621
3622


3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

int
TkInitFontchooser(Tcl_Interp *interp, ClientData dummy)


{
    HookData *hdPtr = (HookData *)ckalloc(sizeof(HookData));
    (void)dummy;

    memset(hdPtr, 0, sizeof(HookData));
    Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteHookData, hdPtr);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
>
>


<













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
    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

int
TkInitFontchooser(
    Tcl_Interp *interp,
    TCL_UNUSED(void *))
{
    HookData *hdPtr = (HookData *)ckalloc(sizeof(HookData));


    memset(hdPtr, 0, sizeof(HookData));
    Tcl_SetAssocData(interp, "::tk::fontchooser", DeleteHookData, hdPtr);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinDraw.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"







|
|







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 © 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"

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
     * the last array if it is large enough.
     */

    if (npoints > tsdPtr->nWinPoints) {
	if (tsdPtr->winPoints != NULL) {
	    ckfree(tsdPtr->winPoints);
	}
	tsdPtr->winPoints = (POINT *)ckalloc(sizeof(POINT) * npoints);
	if (tsdPtr->winPoints == NULL) {
	    tsdPtr->nWinPoints = -1;
	    return NULL;
	}
	tsdPtr->nWinPoints = npoints;
    }








|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
     * the last array if it is large enough.
     */

    if (npoints > tsdPtr->nWinPoints) {
	if (tsdPtr->winPoints != NULL) {
	    ckfree(tsdPtr->winPoints);
	}
	tsdPtr->winPoints = (POINT *)ckalloc(sizeof(POINT) * (size_t)npoints);
	if (tsdPtr->winPoints == NULL) {
	    tsdPtr->nWinPoints = -1;
	    return NULL;
	}
	tsdPtr->nWinPoints = npoints;
    }

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
    unsigned long plane)
{
    HDC srcDC, destDC;
    TkWinDCState srcState, destState;
    HBRUSH bgBrush, fgBrush, oldBrush;
    TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask;

    display->request++;

    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }

    srcDC = TkWinGetDrawableDC(display, src, &srcState);








|







365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
    unsigned long plane)
{
    HDC srcDC, destDC;
    TkWinDCState srcState, destState;
    HBRUSH bgBrush, fgBrush, oldBrush;
    TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask;

    LastKnownRequestProcessed(display)++;

    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }

    srcDC = TkWinGetDrawableDC(display, src, &srcState);

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage, XPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of of the
 *	specified drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.







|







484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage, XPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of the
 *	specified drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
{
    HDC dc, dcMem;
    TkWinDCState state;
    BITMAPINFO *infoPtr;
    HBITMAP bitmap;
    char *data;

    display->request++;

    dc = TkWinGetDrawableDC(display, d, &state);
    SetROP2(dc, tkpWinRopModes[gc->function]);
    dcMem = CreateCompatibleDC(dc);

    if (image->bits_per_pixel == 1) {
	/*







|







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
{
    HDC dc, dcMem;
    TkWinDCState state;
    BITMAPINFO *infoPtr;
    HBITMAP bitmap;
    char *data;

    LastKnownRequestProcessed(display)++;

    dc = TkWinGetDrawableDC(display, d, &state);
    SetROP2(dc, tkpWinRopModes[gc->function]);
    dcMem = CreateCompatibleDC(dc);

    if (image->bits_per_pixel == 1) {
	/*
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
	 * Do not use a palette for TrueColor images.
	 */

	usePalette = (image->bits_per_pixel < 16);

	if (usePalette) {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER)
		    + sizeof(RGBQUAD)*ncolors);
	} else {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER));
	}

	infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	infoPtr->bmiHeader.biWidth = image->width;
	infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */
	infoPtr->bmiHeader.biPlanes = 1;
	infoPtr->bmiHeader.biBitCount = image->bits_per_pixel;
	infoPtr->bmiHeader.biCompression = BI_RGB;
	infoPtr->bmiHeader.biSizeImage = 0;
	infoPtr->bmiHeader.biXPelsPerMeter = 0;
	infoPtr->bmiHeader.biYPelsPerMeter = 0;
	infoPtr->bmiHeader.biClrImportant = 0;

	if (usePalette) {
	    infoPtr->bmiHeader.biClrUsed = ncolors;
	    for (i = 0; i < ncolors; i++) {
		infoPtr->bmiColors[i].rgbBlue = GetBValue(colors[i]);
		infoPtr->bmiColors[i].rgbGreen = GetGValue(colors[i]);
		infoPtr->bmiColors[i].rgbRed = GetRValue(colors[i]);
		infoPtr->bmiColors[i].rgbReserved = 0;
	    }
	} else {
	    infoPtr->bmiHeader.biClrUsed = 0;
	}
	bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT,
		image->data, infoPtr, DIB_RGB_COLORS);
	ckfree(infoPtr);
    }
    if (!bitmap) {
	Tcl_Panic("Fail to allocate bitmap");
	DeleteDC(dcMem);
    	TkWinReleaseDrawableDC(d, dc, &state);
	return BadValue;
    }
    bitmap = (HBITMAP)SelectObject(dcMem, bitmap);
    BitBlt(dc, dest_x, dest_y, (int) width, (int) height, dcMem, src_x, src_y,
	    SRCCOPY);
    DeleteObject(SelectObject(dcMem, bitmap));
    DeleteDC(dcMem);







|








|







|














<

|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
	 * Do not use a palette for TrueColor images.
	 */

	usePalette = (image->bits_per_pixel < 16);

	if (usePalette) {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER)
		    + sizeof(RGBQUAD)*(size_t)ncolors);
	} else {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER));
	}

	infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	infoPtr->bmiHeader.biWidth = image->width;
	infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */
	infoPtr->bmiHeader.biPlanes = 1;
	infoPtr->bmiHeader.biBitCount = (WORD)image->bits_per_pixel;
	infoPtr->bmiHeader.biCompression = BI_RGB;
	infoPtr->bmiHeader.biSizeImage = 0;
	infoPtr->bmiHeader.biXPelsPerMeter = 0;
	infoPtr->bmiHeader.biYPelsPerMeter = 0;
	infoPtr->bmiHeader.biClrImportant = 0;

	if (usePalette) {
	    infoPtr->bmiHeader.biClrUsed = (DWORD)ncolors;
	    for (i = 0; i < ncolors; i++) {
		infoPtr->bmiColors[i].rgbBlue = GetBValue(colors[i]);
		infoPtr->bmiColors[i].rgbGreen = GetGValue(colors[i]);
		infoPtr->bmiColors[i].rgbRed = GetRValue(colors[i]);
		infoPtr->bmiColors[i].rgbReserved = 0;
	    }
	} else {
	    infoPtr->bmiHeader.biClrUsed = 0;
	}
	bitmap = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT,
		image->data, infoPtr, DIB_RGB_COLORS);
	ckfree(infoPtr);
    }
    if (!bitmap) {

	DeleteDC(dcMem);
	TkWinReleaseDrawableDC(d, dc, &state);
	return BadValue;
    }
    bitmap = (HBITMAP)SelectObject(dcMem, bitmap);
    BitBlt(dc, dest_x, dest_y, (int) width, (int) height, dcMem, src_x, src_y,
	    SRCCOPY);
    DeleteObject(SelectObject(dcMem, bitmap));
    DeleteDC(dcMem);
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
    HDC dc,
    POINT *winPoints,
    int npoints,
    WinDrawFunc func)        /* Name of the Windows GDI drawing function:
                                this is either Polyline or Polygon. */
{
    BeginPath(dc);
    func(dc, winPoints, npoints);
    /*
     * In the case of closed polylines, the first and last points
     * are the same. We want miter or bevel join be rendered also
     * at this point, this needs telling the Windows GDI that the
     * path is closed.
     */
    if (func == Polyline) {







|







760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
    HDC dc,
    POINT *winPoints,
    int npoints,
    WinDrawFunc func)        /* Name of the Windows GDI drawing function:
                                this is either Polyline or Polygon. */
{
    BeginPath(dc);
    func(dc, winPoints, (int)npoints);
    /*
     * In the case of closed polylines, the first and last points
     * are the same. We want miter or bevel join be rendered also
     * at this point, this needs telling the Windows GDI that the
     * path is closed.
     */
    if (func == Polyline) {
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
int
XFillPolygon(
    Display *display,
    Drawable d,
    GC gc,
    XPoint *points,
    int npoints,
    int shape,
    int mode)
{
    HPEN pen;
    TkWinDCState state;
    HDC dc;
    (void)shape;

    if (d == None) {
	return BadDrawable;
    }

    dc = TkWinGetDrawableDC(display, d, &state);








|





<







976
977
978
979
980
981
982
983
984
985
986
987
988

989
990
991
992
993
994
995
int
XFillPolygon(
    Display *display,
    Drawable d,
    GC gc,
    XPoint *points,
    int npoints,
    TCL_UNUSED(int),
    int mode)
{
    HPEN pen;
    TkWinDCState state;
    HDC dc;


    if (d == None) {
	return BadDrawable;
    }

    dc = TkWinGetDrawableDC(display, d, &state);

1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053

    pen = SetUpGraphicsPort(gc);
    SetBkMode(dc, TRANSPARENT);
    oldPen = (HPEN)SelectObject(dc, pen);
    oldBrush = (HBRUSH)SelectObject(dc, GetStockObject(NULL_BRUSH));
    SetROP2(dc, tkpWinRopModes[gc->function]);

    Rectangle(dc, x, y, (int) x+width+1, (int) y+height+1);

    DeleteObject(SelectObject(dc, oldPen));
    SelectObject(dc, oldBrush);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}








|







1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051

    pen = SetUpGraphicsPort(gc);
    SetBkMode(dc, TRANSPARENT);
    oldPen = (HPEN)SelectObject(dc, pen);
    oldBrush = (HBRUSH)SelectObject(dc, GetStockObject(NULL_BRUSH));
    SetROP2(dc, tkpWinRopModes[gc->function]);

    Rectangle(dc, x, y, x + (int)width + 1, y + (int)height + 1);

    DeleteObject(SelectObject(dc, oldPen));
    SelectObject(dc, oldBrush);
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

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
    Display *display,
    Drawable d,
    GC gc,
    int x, int y,
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0);
}

int
XDrawArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcs,
    int narcs)
{
    int ret = Success;

    display->request++;

    while (narcs-- > 0) {
	ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y,
		    arcs[0].width, arcs[0].height,
		    arcs[0].angle1, arcs[0].angle2, 0);
	if (ret != Success) {
	    break;







|














|







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
    Display *display,
    Drawable d,
    GC gc,
    int x, int y,
    unsigned int width, unsigned int height,
    int start, int extent)
{
    LastKnownRequestProcessed(display)++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0);
}

int
XDrawArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcs,
    int narcs)
{
    int ret = Success;

    LastKnownRequestProcessed(display)++;

    while (narcs-- > 0) {
	ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y,
		    arcs[0].width, arcs[0].height,
		    arcs[0].angle1, arcs[0].angle2, 0);
	if (ret != Success) {
	    break;
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
    Display *display,
    Drawable d,
    GC gc,
    int x, int y,
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1);
}

int
XFillArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcs,
    int narcs)
{
    int ret = Success;

    display->request++;

    while (narcs-- > 0) {
	ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y,
		    arcs[0].width, arcs[0].height,
		    arcs[0].angle1, arcs[0].angle2, 1);
	if (ret != Success) {
	    break;







|














|







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
    Display *display,
    Drawable d,
    GC gc,
    int x, int y,
    unsigned int width, unsigned int height,
    int start, int extent)
{
    LastKnownRequestProcessed(display)++;

    return DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1);
}

int
XFillArcs(
    Display *display,
    Drawable d,
    GC gc,
    XArc *arcs,
    int narcs)
{
    int ret = Success;

    LastKnownRequestProcessed(display)++;

    while (narcs-- > 0) {
	ret = DrawOrFillArc(display, d, gc, arcs[0].x, arcs[0].y,
		    arcs[0].width, arcs[0].height,
		    arcs[0].angle1, arcs[0].angle2, 1);
	if (ret != Success) {
	    break;
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
	/*
	 * Note that this call will leave a gap of one pixel at the end of the
	 * arc for thin arcs. We can't use ArcTo because it's only supported
	 * under Windows NT.
	 */

	SetBkMode(dc, TRANSPARENT);
	Arc(dc, x, y, (int) (x+width+1), (int) (y+height+1), xstart, ystart,
		xend, yend);
    } else {
	brush = CreateSolidBrush(gc->foreground);
	oldBrush = (HBRUSH)SelectObject(dc, brush);
	if (gc->arc_mode == ArcChord) {
	    Chord(dc, x, y, (int) (x+width+1), (int) (y+height+1),
		    xstart, ystart, xend, yend);
	} else if (gc->arc_mode == ArcPieSlice) {
	    Pie(dc, x, y, (int) (x+width+1), (int) (y+height+1),
		    xstart, ystart, xend, yend);
	}
	DeleteObject(SelectObject(dc, oldBrush));
    }
    DeleteObject(SelectObject(dc, oldPen));
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;







|





|


|







1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
	/*
	 * Note that this call will leave a gap of one pixel at the end of the
	 * arc for thin arcs. We can't use ArcTo because it's only supported
	 * under Windows NT.
	 */

	SetBkMode(dc, TRANSPARENT);
	Arc(dc, x, y,  x + (int)width + 1, y + (int)height + 1, xstart, ystart,
		xend, yend);
    } else {
	brush = CreateSolidBrush(gc->foreground);
	oldBrush = (HBRUSH)SelectObject(dc, brush);
	if (gc->arc_mode == ArcChord) {
	    Chord(dc, x, y,  x + (int)width + 1, y + (int)height + 1,
		    xstart, ystart, xend, yend);
	} else if (gc->arc_mode == ArcPieSlice) {
	    Pie(dc, x, y,  x+(int)width+1, y + (int)height + 1,
		    xstart, ystart, xend, yend);
	}
	DeleteObject(SelectObject(dc, oldBrush));
    }
    DeleteObject(SelectObject(dc, oldPen));
    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
 *
 *----------------------------------------------------------------------
 */

int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    HWND hwnd = TkWinGetHWND(Tk_WindowId(tkwin));
    RECT scrollRect;
    (void)gc;

    scrollRect.left = x;
    scrollRect.top = y;
    scrollRect.right = x + width;
    scrollRect.bottom = y + height;
    return (ScrollWindowEx(hwnd, dx, dy, &scrollRect, NULL, (HRGN) damageRgn,
	    NULL, 0) == NULLREGION) ? 0 : 1;







|







<







1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
 *
 *----------------------------------------------------------------------
 */

int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    TCL_UNUSED(GC),			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    Region damageRgn)		/* Region to accumulate damage in. */
{
    HWND hwnd = TkWinGetHWND(Tk_WindowId(tkwin));
    RECT scrollRect;


    scrollRect.left = x;
    scrollRect.top = y;
    scrollRect.right = x + width;
    scrollRect.bottom = y + height;
    return (ScrollWindowEx(hwnd, dx, dy, &scrollRect, NULL, (HRGN) damageRgn,
	    NULL, 0) == NULLREGION) ? 0 : 1;
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
    ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    SetBkColor(dc, oldColor);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --
 *
 *	This function draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *      On Windows, we just draw the simple inset ring. On other sytems, e.g.
 *      the Mac, the focus ring is a little more complicated, so we need this
 *      abstraction.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    (void)bgGC;

    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --







|



















|


|



<
<







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
    ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    SetBkColor(dc, oldColor);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DrawHighlightBorder --
 *
 *	This function draws a rectangular ring around the outside of a widget
 *	to indicate that it has received the input focus.
 *
 *      On Windows, we just draw the simple inset ring. On other sytems, e.g.
 *      the Mac, the focus ring is a little more complicated, so we need this
 *      abstraction.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A rectangle "width" pixels wide is drawn in "drawable", corresponding
 *	to the outer area of "tkwin".
 *
 *----------------------------------------------------------------------
 */

void
Tk_DrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    TCL_UNUSED(GC),
    int highlightWidth,
    Drawable drawable)
{


    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --

Changes to win/tkWinEmbed.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"









|







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 © 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"

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
typedef struct {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		ContainerEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		EmbedGeometryRequest(Container *containerPtr,
			    int width, int height);
static void		EmbedWindowDeleted(TkWindow *winPtr);
static void		Tk_MapEmbeddedWindow(TkWindow* winPtr);
HWND			Tk_GetEmbeddedHWnd(TkWindow* winPtr);








|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
typedef struct {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		ContainerEventProc(void *clientData,
			    XEvent *eventPtr);
static void		EmbedGeometryRequest(Container *containerPtr,
			    int width, int height);
static void		EmbedWindowDeleted(TkWindow *winPtr);
static void		Tk_MapEmbeddedWindow(TkWindow* winPtr);
HWND			Tk_GetEmbeddedHWnd(TkWindow* winPtr);

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 *	Currently it does not do anything.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    (void)dummy;
    (void)interp;
    (void)objc;
    (void)objv;








|

|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 *	Currently it does not do anything.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    void *dummy,
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    (void)dummy;
    (void)interp;
    (void)objc;
    (void)objv;

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
static
void Tk_MapEmbeddedWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    if(!(winPtr->flags & TK_ALREADY_DEAD)) {
	HWND hwnd = (HWND)winPtr->privatePtr;
	int state = SendMessageW(hwnd, TK_STATE, -1, -1) - 1;

	if (state < 0 || state > 3) {
	    state = NormalState;
	}

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
	}

	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release(winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *
 *	This procedure causes a Tk window to use a given Windows handle for a
 *	window as its underlying window, rather than a new Windows window
 *	being created automatically. It is invoked by an embedded application
 *	to specify the window in which the application is embedded.
 *
 *	This procedure uses a simple attachment protocol by sending TK_INFO







|


















|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
static
void Tk_MapEmbeddedWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    if(!(winPtr->flags & TK_ALREADY_DEAD)) {
	HWND hwnd = (HWND)winPtr->privatePtr;
	int state = SendMessageW(hwnd, TK_STATE, -1, (WPARAM)-1) - 1;

	if (state < 0 || state > 3) {
	    state = NormalState;
	}

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
	}

	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release(winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_UseWindow --
 *
 *	This procedure causes a Tk window to use a given Windows handle for a
 *	window as its underlying window, rather than a new Windows window
 *	being created automatically. It is invoked by an embedded application
 *	to specify the window in which the application is embedded.
 *
 *	This procedure uses a simple attachment protocol by sending TK_INFO
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    int id;
    HWND hwnd;
/*
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
*/

/*
    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }
*/

    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {







|


















|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tk_UseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    int id;
    HWND hwnd;
/*
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
*/

/*
    if (winPtr->window != None) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't modify container after widget is created", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL);
	return TCL_ERROR;
    }
*/

    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	return TCL_ERROR;
    }

    id = SendMessageW(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == PTR2INT(hwnd)) {
	if (!SendMessageW(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "The container is already in use", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "IN_USE", NULL);
	    return TCL_ERROR;
	}
    } else if (id == -PTR2INT(hwnd)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"the window to use is not a Tk container", -1));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL);
	return TCL_ERROR;
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	WCHAR msg[256];

	wsprintfW(msg, L"Unable to get information of window \"%.40hs\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
	if (IDCANCEL == MessageBoxW(hwnd, msg, L"Tk Warning",
		MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Operation has been canceled", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "CANCEL", NULL);
	    return TCL_ERROR;
	}
    }

    Tk_DetachEmbeddedWindow(winPtr, FALSE);








|





|















|







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	return TCL_ERROR;
    }

    id = SendMessageW(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == PTR2INT(hwnd)) {
	if (!SendMessageW(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "The container is already in use", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "IN_USE", NULL);
	    return TCL_ERROR;
	}
    } else if (id == -PTR2INT(hwnd)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"the window to use is not a Tk container", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL);
	return TCL_ERROR;
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	WCHAR msg[256];

	wsprintfW(msg, L"Unable to get information of window \"%.40hs\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
	if (IDCANCEL == MessageBoxW(hwnd, msg, L"Tk Warning",
		MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Operation has been canceled", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "CANCEL", NULL);
	    return TCL_ERROR;
	}
    }

    Tk_DetachEmbeddedWindow(winPtr, FALSE);

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeContainer --
 *
 *	This procedure is called to indicate that a particular window will be
 *	a container for an embedded application. This changes certain aspects
 *	of the window's behavior, such as whether it will receive events
 *	anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeContainer(
    Tk_Window tkwin)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));








|
















|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MakeContainer --
 *
 *	This procedure is called to indicate that a particular window will be
 *	a container for an embedded application. This changes certain aspects
 *	of the window's behavior, such as whether it will receive events
 *	anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tk_MakeContainer(
    Tk_Window tkwin)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;

    if (eventPtr->type == ConfigureNotify) {








|







849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    void *clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;

    if (eventPtr->type == ConfigureNotify) {

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
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this procedure will return either one, given the other.
 *
 * Results:
 *	If winPtr is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow *
TkpGetOtherWindow(
    TkWindow *winPtr)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parentPtr;
	} else if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------







|





|









|
|
|








|
|
|
|







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
	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this procedure will return either one, given the other.
 *
 * Results:
 *	If tkwin is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
Tk_GetOtherWindow(
    Tk_Window tkwin)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if ((Tk_Window)containerPtr->embeddedPtr == tkwin) {
	    return (Tk_Window)containerPtr->parentPtr;
	} else if ((Tk_Window)containerPtr->parentPtr == tkwin) {
	    return (Tk_Window)containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
1090
1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105
     * Find the Container structure for this window work. Delete the
     * information about the embedded application and free the container's
     * record. The main container may be null. [Bug #476176]
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;
    if (containerPtr == NULL) return;
    while (1) {

	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessageW(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);







<

>







1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103
1104
1105
     * Find the Container structure for this window work. Delete the
     * information about the embedded application and free the container's
     * record. The main container may be null. [Bug #476176]
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;

    while (1) {
	if (containerPtr == NULL) return;
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessageW(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);

Changes to win/tkWinFont.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * tkWinFont.c --
 *
 *	Contains the Windows implementation of the platform-independent font
 *	package interface.
 *
 * Copyright (c) 1994 Software Research Associates, Inc.
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkFont.h"






|
|
|







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 © 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"
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
				/* Builtin space for a limited number of
				 * SubFonts. */
    int numSubFonts;		/* Length of following array. */
    SubFont *subFontArray;	/* Array of SubFonts that have been loaded in
				 * order to draw/measure all the characters
				 * encountered by this font so far. All fonts
				 * start off with one SubFont initialized by
				 * AllocFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */
    HWND hwnd;			/* Toplevel window of application that owns
				 * this font, used for getting HDC for
				 * offscreen measurements. */
    int pixelSize;		/* Original pixel size used when font was







|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
				/* Builtin space for a limited number of
				 * SubFonts. */
    int numSubFonts;		/* Length of following array. */
    SubFont *subFontArray;	/* Array of SubFonts that have been loaded in
				 * order to draw/measure all the characters
				 * encountered by this font so far. All fonts
				 * start off with one SubFont initialized by
				 * InitFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */
    HWND hwnd;			/* Toplevel window of application that owns
				 * this font, used for getting HDC for
				 * offscreen measurements. */
    int pixelSize;		/* Original pixel size used when font was
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
    /*
     * If this API call fails then we will fallback to setting these named
     * fonts from script in ttk/fonts.tcl. So far I've only seen it fail when
     * WINVER has been defined for a higher platform than we are running on.
     * (i.e. WINVER=0x0600 and running on XP).
     */

    ZeroMemory(&ncMetrics, sizeof(ncMetrics));
    ncMetrics.cbSize = sizeof(ncMetrics);
    if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
	    sizeof(ncMetrics), &ncMetrics, 0)) {
	CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont",
		&ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont",
		&ncMetrics.lfMessageFont);







|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
    /*
     * If this API call fails then we will fallback to setting these named
     * fonts from script in ttk/fonts.tcl. So far I've only seen it fail when
     * WINVER has been defined for a higher platform than we are running on.
     * (i.e. WINVER=0x0600 and running on XP).
     */

    memset(&ncMetrics, 0, sizeof(ncMetrics));
    ncMetrics.cbSize = sizeof(ncMetrics);
    if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
	    sizeof(ncMetrics), &ncMetrics, 0)) {
	CreateNamedSystemLogFont(interp, tkwin, "TkDefaultFont",
		&ncMetrics.lfMessageFont);
	CreateNamedSystemLogFont(interp, tkwin, "TkHeadingFont",
		&ncMetrics.lfMessageFont);
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    FontFamily *familyPtr;
    Tcl_Obj *resultPtr, *strPtr;

    resultPtr = Tcl_NewObj();
    fontPtr = (WinFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	strPtr = Tcl_NewStringObj(familyPtr->faceName, -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *----------------------------------------------------------------------







|







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    FontFamily *familyPtr;
    Tcl_Obj *resultPtr, *strPtr;

    resultPtr = Tcl_NewObj();
    fontPtr = (WinFont *) tkfont;
    for (i = 0; i < fontPtr->numSubFonts; i++) {
	familyPtr = fontPtr->subFontArray[i].familyPtr;
	strPtr = Tcl_NewStringObj(familyPtr->faceName, TCL_INDEX_NONE);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
}

/*
 *----------------------------------------------------------------------
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    int numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
				 * is unbounded and the flags argument is
				 * ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char







|

|







786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
 */

int
Tk_MeasureChars(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    Tcl_Size numBytes,		/* Maximum number of bytes to consider from
				 * source string. */
	int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length in pixels; don't
				 * consider any character that would cross
				 * this x-position. If < 0, then line length
				 * is unbounded and the flags argument is
				 * ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
     */

    moretomeasure = 0;
    curX = 0;
    start = source;
    end = start + numBytes;
    for (p = start; p < end; ) {
	next = p + TkUtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	if (thisSubFontPtr != lastSubFontPtr) {
	    familyPtr = lastSubFontPtr->familyPtr;
	    Tcl_UtfToExternalDString(familyPtr->encoding, start,
		    (int) (p - start), &runString);
	    size.cx = 0;
	    familyPtr->getTextExtentPoint32Proc(hdc,
		    (WCHAR *)Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
	    Tcl_DStringFree(&runString);
	    if (maxLength >= 0 && (curX+size.cx) > maxLength) {
		moretomeasure = 1;
		break;
	    }







|



|
|

|
<







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855

856
857
858
859
860
861
862
     */

    moretomeasure = 0;
    curX = 0;
    start = source;
    end = start + numBytes;
    for (p = start; p < end; ) {
	next = p + Tcl_UtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	if (thisSubFontPtr != lastSubFontPtr) {
	    familyPtr = lastSubFontPtr->familyPtr;
	    WCHAR *wstr = (WCHAR *)Tcl_UtfToExternalDString(familyPtr->encoding, start,
		    p - start, &runString);
	    size.cx = 0;
	    familyPtr->getTextExtentPoint32Proc(hdc, wstr,

		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
	    Tcl_DStringFree(&runString);
	    if (maxLength >= 0 && (curX+size.cx) > maxLength) {
		moretomeasure = 1;
		break;
	    }
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
    if (!moretomeasure) {
	/*
	 * We get here if the previous loop was just finished normally,
	 * without a break. Just measure the last run and that's it.
	 */

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_UtfToExternalDString(familyPtr->encoding, start,
		(int) (p - start), &runString);
	size.cx = 0;
	familyPtr->getTextExtentPoint32Proc(hdc, (WCHAR *) Tcl_DStringValue(&runString),
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		&size);
	Tcl_DStringFree(&runString);
	if (maxLength >= 0 && (curX+size.cx) > maxLength) {
	    moretomeasure = 1;
	} else {
	    curX += size.cx;







|
|

|







872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
    if (!moretomeasure) {
	/*
	 * We get here if the previous loop was just finished normally,
	 * without a break. Just measure the last run and that's it.
	 */

	familyPtr = lastSubFontPtr->familyPtr;
	WCHAR *wstr = (WCHAR *)Tcl_UtfToExternalDString(familyPtr->encoding, start,
		p - start, &runString);
	size.cx = 0;
	familyPtr->getTextExtentPoint32Proc(hdc, wstr,
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		&size);
	Tcl_DStringFree(&runString);
	if (maxLength >= 0 && (curX+size.cx) > maxLength) {
	    moretomeasure = 1;
	} else {
	    curX += size.cx;
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
	char buf[16];
	int dstWrote;
	int lastSize = 0;

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_DStringInit(&runString);
	for (p = start; p < end; ) {
	    next = p + TkUtfToUniChar(p, &ch);
	    Tcl_UtfToExternal(NULL, familyPtr->encoding, p,
		    (int) (next - p), 0, NULL, buf, sizeof(buf), NULL,
		    &dstWrote, NULL);
	    Tcl_DStringAppend(&runString,buf,dstWrote);
	    size.cx = 0;
	    familyPtr->getTextExtentPoint32Proc(hdc,
		    (WCHAR *) Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);







|

|







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
	char buf[16];
	int dstWrote;
	int lastSize = 0;

	familyPtr = lastSubFontPtr->familyPtr;
	Tcl_DStringInit(&runString);
	for (p = start; p < end; ) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    Tcl_UtfToExternal(NULL, familyPtr->encoding, p,
		    (int) (next - p), TCL_ENCODING_PROFILE_TCL8, NULL, buf, sizeof(buf), NULL,
		    &dstWrote, NULL);
	    Tcl_DStringAppend(&runString,buf,dstWrote);
	    size.cx = 0;
	    familyPtr->getTextExtentPoint32Proc(hdc,
		    (WCHAR *) Tcl_DStringValue(&runString),
		    Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
		    &size);
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
	const char *lastWordBreak = NULL;
	int ch2;

	end = p;
	p = source;
	ch = ' ';
	while (p < end) {
	    next = p + TkUtfToUniChar(p, &ch2);
	    if ((ch != ' ') && (ch2 == ' ')) {
		lastWordBreak = p;
	    }
	    p = next;
	    ch = ch2;
	}








|







957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
	const char *lastWordBreak = NULL;
	int ch2;

	end = p;
	p = source;
	ch = ' ';
	while (p < end) {
	    next = p + Tcl_UtfToUniChar(p, &ch2);
	    if ((ch != ' ') && (ch2 == ' ')) {
		lastWordBreak = p;
	    }
	    p = next;
	    ch = ch2;
	}

1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    TCL_UNUSED(int),		/* Maximum number of bytes to consider from
				 * source string in all. */
    int rangeStart,		/* Index of first byte to measure. */
    int rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char







|

|
|







1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
 */

int
TkpMeasureCharsInContext(
    Tk_Font tkfont,		/* Font in which characters will be drawn. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. */
    TCL_UNUSED(Tcl_Size),		/* Maximum number of bytes to consider from
				 * source string in all. */
    Tcl_Size rangeStart,		/* Index of first byte to measure. */
    Tcl_Size rangeLength,		/* Length of range to measure in bytes. */
    int maxLength,		/* If >= 0, maxLength specifies the longest
				 * permissible line length; don't consider any
				 * character that would cross this x-position.
				 * If < 0, then line length is unbounded and
				 * the flags argument is ignored. */
    int flags,			/* Various flag bits OR-ed together:
				 * TK_PARTIAL_OK means include the last char
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    display->request++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);








|








|







1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    LastKnownRequestProcessed(display)++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

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
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    display->request++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);








|









|







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
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    Tcl_Size numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    LastKnownRequestProcessed(display)++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(int),		/* Number of bytes in string. */
    int rangeStart,		/* Index of first byte to draw. */
    int rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);







|
|
|







1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(Tcl_Size),		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size rangeLength,		/* Length of range to draw in bytes. */
    int x, int y)		/* Coordinates at which to place origin of the
				 * whole (not just the range) string when
				 * drawing. */
{
    int widthUntilStart;

    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
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
    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);
}

/*







|
|
|







<







1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427

1428
1429
1430
1431
1432
1433
1434
    const char * source,	/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that is
				 * passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    TCL_UNUSED(Tcl_Size),		/* Number of bytes in string. */
    Tcl_Size rangeStart,		/* Index of first byte to draw. */
    Tcl_Size 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);


    Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart);
    TkDrawAngledChars(display, drawable, gc, tkfont, source + rangeStart,
	    rangeLength, x+cosA*widthUntilStart, y-sinA*widthUntilStart, angle);
}

/*
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

    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
    GetTextMetricsW(hdc, &tm);

    end = source + numBytes;
    for (p = source; p < end; ) {
	next = p + TkUtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);

	/*
	 * The drawing API has a limit of 32767 pixels in one go.
	 * To avoid spending time on a rare case we do not measure each char,
	 * instead we limit to drawing chunks of 200 bytes since that works
	 * well in practice.
	 */

	if ((thisSubFontPtr != lastSubFontPtr) || (p-source > 200)) {
	    if (p > source) {
		familyPtr = lastSubFontPtr->familyPtr;
 		Tcl_UtfToExternalDString(familyPtr->encoding, source,
			(int) (p - source), &runString);
		familyPtr->textOutProc(hdc, x-((double)tm.tmOverhang/2), y,
			(WCHAR *)Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
		familyPtr->getTextExtentPoint32Proc(hdc,
			(WCHAR *)Tcl_DStringValue(&runString),
			Tcl_DStringLength(&runString) >> familyPtr->isWideFont,
			&size);
		x += cosA*size.cx;
		y -= sinA*size.cx;
		Tcl_DStringFree(&runString);
	    }
	    lastSubFontPtr = thisSubFontPtr;
	    source = p;
	    SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
	    GetTextMetricsW(hdc, &tm);
	}
	p = next;
    }
    if (p > source) {
	familyPtr = lastSubFontPtr->familyPtr;
 	Tcl_UtfToExternalDString(familyPtr->encoding, source,
		(int) (p - source), &runString);
	familyPtr->textOutProc(hdc, x-((double)tm.tmOverhang/2), y,
		(WCHAR *)Tcl_DStringValue(&runString),
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
	Tcl_DStringFree(&runString);
    }
    SelectObject(hdc, oldFont);
}

static inline HFONT
SelectFont(







|












|
|
|
<
|

<
|














|
|
|
<
|







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

    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
    GetTextMetricsW(hdc, &tm);

    end = source + numBytes;
    for (p = source; p < end; ) {
	next = p + Tcl_UtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);

	/*
	 * The drawing API has a limit of 32767 pixels in one go.
	 * To avoid spending time on a rare case we do not measure each char,
	 * instead we limit to drawing chunks of 200 bytes since that works
	 * well in practice.
	 */

	if ((thisSubFontPtr != lastSubFontPtr) || (p-source > 200)) {
	    if (p > source) {
		familyPtr = lastSubFontPtr->familyPtr;
		WCHAR *wstr = (WCHAR *)Tcl_UtfToExternalDString(familyPtr->encoding, source,
			p - source, &runString);
		familyPtr->textOutProc(hdc, (int)(x-(double)tm.tmOverhang/2.0), y,

			wstr, Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
		familyPtr->getTextExtentPoint32Proc(hdc,

			wstr, 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;
	WCHAR *wstr = (WCHAR *)Tcl_UtfToExternalDString(familyPtr->encoding, source,
		p - source, &runString);
	familyPtr->textOutProc(hdc, (int)(x-(double)tm.tmOverhang/2.0), y,

		wstr, Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
	Tcl_DStringFree(&runString);
    }
    SelectObject(hdc, oldFont);
}

static inline HFONT
SelectFont(
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828

    familyPtr->refCount = 2;

    familyPtr->segCount = LoadFontRanges(hdc, hFont, &familyPtr->startCount,
	    &familyPtr->endCount, &familyPtr->isSymbolFont);

    encoding = NULL;
    if (familyPtr->isSymbolFont != 0) {
	/*
	 * Symbol fonts are handled specially. For instance, Unicode 0393
	 * (GREEK CAPITAL GAMMA) must be mapped to Symbol character 0047
	 * (GREEK CAPITAL GAMMA), because the Symbol font doesn't have a GREEK
	 * CAPITAL GAMMA at location 0393. If Tk interpreted the Symbol font
	 * using the Unicode encoding, it would decide that the Symbol font
	 * has no GREEK CAPITAL GAMMA, because the Symbol encoding (of course)







|







1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823

    familyPtr->refCount = 2;

    familyPtr->segCount = LoadFontRanges(hdc, hFont, &familyPtr->startCount,
	    &familyPtr->endCount, &familyPtr->isSymbolFont);

    encoding = NULL;
    if (familyPtr->isSymbolFont) {
	/*
	 * Symbol fonts are handled specially. For instance, Unicode 0393
	 * (GREEK CAPITAL GAMMA) must be mapped to Symbol character 0047
	 * (GREEK CAPITAL GAMMA), because the Symbol font doesn't have a GREEK
	 * CAPITAL GAMMA at location 0393. If Tk interpreted the Symbol font
	 * using the Unicode encoding, it would decide that the Symbol font
	 * has no GREEK CAPITAL GAMMA, because the Symbol encoding (of course)
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
	 * we don't know the proper Unicode -> symbol font mapping, we can
	 * install the symbol font as the base font and access its glyphs.
	 */

	end = (row + 1) << FONTMAP_SHIFT;
	for (i = row << FONTMAP_SHIFT; i < end; i++) {
	    if (Tcl_UtfToExternal(NULL, encoding, src,
		    TkUniCharToUtf(i, src), TCL_ENCODING_STOPONERROR, NULL,
		    buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK) {
		continue;
	    }
	    bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
	    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
	}
    }







|







2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
	 * we don't know the proper Unicode -> symbol font mapping, we can
	 * install the symbol font as the base font and access its glyphs.
	 */

	end = (row + 1) << FONTMAP_SHIFT;
	for (i = row << FONTMAP_SHIFT; i < end; i++) {
	    if (Tcl_UtfToExternal(NULL, encoding, src,
		    Tcl_UniCharToUtf(i, src), TCL_ENCODING_PROFILE_STRICT, NULL,
		    buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK) {
		continue;
	    }
	    bitOffset = i & (FONTMAP_BITSPERPAGE - 1);
	    subFontPtr->fontMap[row][bitOffset >> 3] |= 1 << (bitOffset & 7);
	}
    }
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
    HDC hdc,			/* HDC in which font family will be used. */
    const char *faceName)	/* Font family to query. */
{
    int result;
    Tcl_DString faceString;

    Tcl_DStringInit(&faceString);
    Tcl_UtfToWCharDString(faceName, -1, &faceString);

    /*
     * If the family exists, WinFontExistProc() will be called and
     * EnumFontFamilies() will return whatever WinFontExistProc() returns. If
     * the family doesn't exist, EnumFontFamilies() will just return a
     * non-zero value.
     */







|







2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
    HDC hdc,			/* HDC in which font family will be used. */
    const char *faceName)	/* Font family to query. */
{
    int result;
    Tcl_DString faceString;

    Tcl_DStringInit(&faceString);
    Tcl_UtfToWCharDString(faceName, TCL_INDEX_NONE, &faceString);

    /*
     * If the family exists, WinFontExistProc() will be called and
     * EnumFontFamilies() will return whatever WinFontExistProc() returns. If
     * the family doesn't exist, EnumFontFamilies() will just return a
     * non-zero value.
     */
2728
2729
2730
2731
2732
2733
2734

2735
2736
2737
2738
2739
2740
2741
2742
    HFONT hFont,		/* HFONT to query. */
    USHORT **startCountPtr,	/* Filled with malloced pointer to character
				 * range information. */
    USHORT **endCountPtr,	/* Filled with malloced pointer to character
				 * range information. */
    int *symbolPtr)
 {

    int n, i, swapped, offset, cbData, segCount;
    DWORD cmapKey;
    USHORT *startCount, *endCount;
    CMAPTABLE cmapTable;
    ENCODINGTABLE encTable;
    SUBTABLE subTable;
    char *s;








>
|







2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
    HFONT hFont,		/* HFONT to query. */
    USHORT **startCountPtr,	/* Filled with malloced pointer to character
				 * range information. */
    USHORT **endCountPtr,	/* Filled with malloced pointer to character
				 * range information. */
    int *symbolPtr)
 {
    int n, i, j, k, swapped, segCount;
    size_t cbData, offset;
    DWORD cmapKey;
    USHORT *startCount, *endCount;
    CMAPTABLE cmapTable;
    ENCODINGTABLE encTable;
    SUBTABLE subTable;
    char *s;

2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
		endCount = (USHORT *)ckalloc(cbData);

		offset = encTable.offset + sizeof(subTable.segment);
		GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData);
		offset += cbData + sizeof(USHORT);
		GetFontData(hdc, cmapKey, (DWORD) offset, startCount, cbData);
		if (swapped) {
		    for (i = 0; i < segCount; i++) {
			SwapShort(&endCount[i]);
			SwapShort(&startCount[i]);
		    }
		}
		if (*symbolPtr != 0) {
		    /*
		     * Empirically determined: When a symbol font is loaded,
		     * the character existence metrics obtained from the
		     * system are mildly wrong. If the real range of the
		     * symbol font is from 0020 to 00FE, then the metrics are
		     * reported as F020 to F0FE. When we load a symbol font,
		     * we must fix the character existence metrics.
		     *
		     * Symbol fonts should only use the symbol encoding for
		     * 8-bit characters [note Bug: 2406]
		     */

		    for (i = 0; i < segCount; i++) {
			if (((startCount[i] & 0xff00) == 0xf000)
				&& ((endCount[i] & 0xff00) == 0xf000)) {
			    startCount[i] &= 0xff;
			    endCount[i] &= 0xff;
			}
		    }
		}
	    }
	}
    } else if (GetTextCharset(hdc) == ANSI_CHARSET) {
	/*







|
|
|















|
|
|
|
|







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
		endCount = (USHORT *)ckalloc(cbData);

		offset = encTable.offset + sizeof(subTable.segment);
		GetFontData(hdc, cmapKey, (DWORD) offset, endCount, cbData);
		offset += cbData + sizeof(USHORT);
		GetFontData(hdc, cmapKey, (DWORD) offset, startCount, cbData);
		if (swapped) {
		    for (j = 0; j < segCount; j++) {
			SwapShort(&endCount[j]);
			SwapShort(&startCount[j]);
		    }
		}
		if (*symbolPtr != 0) {
		    /*
		     * Empirically determined: When a symbol font is loaded,
		     * the character existence metrics obtained from the
		     * system are mildly wrong. If the real range of the
		     * symbol font is from 0020 to 00FE, then the metrics are
		     * reported as F020 to F0FE. When we load a symbol font,
		     * we must fix the character existence metrics.
		     *
		     * Symbol fonts should only use the symbol encoding for
		     * 8-bit characters [note Bug: 2406]
		     */

		    for (k = 0; k < segCount; k++) {
			if (((startCount[k] & 0xff00) == 0xf000)
				&& ((endCount[k] & 0xff00) == 0xf000)) {
			    startCount[k] &= 0xff;
			    endCount[k] &= 0xff;
			}
		    }
		}
	    }
	}
    } else if (GetTextCharset(hdc) == ANSI_CHARSET) {
	/*

Added win/tkWinGDI.c.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
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
/*
 * tkWinGDI.c --
 *
 *      This module implements access to the Win32 GDI API.
 *
 * Copyright © 1991-2018 Microsoft Corp.
 * Copyright © 2009, Michael I. Schwartz.
 * Copyright © 1998-2019 Harald Oehlmann, Elmicron GmbH
 * Copyright © 2021 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 <windows.h>
#include <math.h>
#include <wtypes.h>
#include <winspool.h>
#include <commdlg.h>
#include <wingdi.h>

#include <tcl.h>

#include "tkWinInt.h"

/*
 * Create a standard "DrawFunc" to make this more workable....
 */
#ifdef _MSC_VER
typedef BOOL (WINAPI *DrawFunc) (
	HDC, int, int, int, int, int, int, int, int); /* Arc, Chord, Pie. */
#else
typedef BOOL WINAPI (*DrawFunc) (
	HDC, int, int, int, int, int, int, int, int); /* Arc, Chord, Pie. */
#endif

/* Real functions. */
static Tcl_ObjCmdProc GdiArc;
static Tcl_ObjCmdProc GdiBitmap;
static Tcl_ObjCmdProc GdiCharWidths;
static Tcl_ObjCmdProc GdiImage;
static Tcl_ObjCmdProc GdiPhoto;
static Tcl_ObjCmdProc GdiLine;
static Tcl_ObjCmdProc GdiOval;
static Tcl_ObjCmdProc GdiPolygon;
static Tcl_ObjCmdProc GdiRectangle;
static Tcl_ObjCmdProc GdiText;
static Tcl_ObjCmdProc GdiMap;
static Tcl_ObjCmdProc GdiCopyBits;

/* Local copies of similar routines elsewhere in Tcl/Tk. */
static int		GdiGetColor(Tcl_Obj *nameObj, COLORREF *color);

/*
 * Helper functions.
 */
static int		GdiMakeLogFont(Tcl_Interp *interp, const char *str,
			    LOGFONTW *lf, HDC hDC);
static int		GdiMakePen(Tcl_Interp *interp, int width,
			    int dashstyle, const char *dashstyledata,
			    int capstyle, int joinstyle,
			    int stipplestyle, const char *stippledata,
			    unsigned long color, HDC hDC, HGDIOBJ *oldPen);
static int		GdiFreePen(Tcl_Interp *interp, HDC hDC, HGDIOBJ oldPen);
static int		GdiMakeBrush(unsigned long color, long hatch,
			    LOGBRUSH *lb, HDC hDC, HBRUSH *oldBrush);
static void		GdiFreeBrush(Tcl_Interp *interp, HDC hDC,
			    HGDIOBJ oldBrush);
static int		GdiGetHdcInfo(HDC hdc,
			    LPPOINT worigin, LPSIZE wextent,
			    LPPOINT vorigin, LPSIZE vextent);

/* Helper functions for printing the window client area. */
enum PrintType { PTWindow = 0, PTClient = 1, PTScreen = 2 };

static HANDLE		CopyToDIB(HWND wnd, enum PrintType type);
static HBITMAP		CopyScreenToBitmap(LPRECT lpRect);
static HANDLE		BitmapToDIB(HBITMAP hb, HPALETTE hp);
static HANDLE		CopyScreenToDIB(LPRECT lpRect);
static int		DIBNumColors(LPBITMAPINFOHEADER lpDIB);
static int		PalEntriesOnDevice(HDC hDC);
static HPALETTE		GetSystemPalette(void);
static void		GetDisplaySize(LONG *width, LONG *height);
static int		GdiWordToWeight(const char *str);
static int		GdiParseFontWords(Tcl_Interp *interp, LOGFONTW *lf,
			    const char *str[], int numargs);
static Tcl_ObjCmdProc PrintSelectPrinter;
static Tcl_ObjCmdProc PrintOpenPrinter;
static Tcl_ObjCmdProc PrintClosePrinter;
static Tcl_ObjCmdProc PrintOpenDoc;
static Tcl_ObjCmdProc PrintCloseDoc;
static Tcl_ObjCmdProc PrintOpenPage;
static Tcl_ObjCmdProc PrintClosePage;

/*
 * Global state.
 */

static PRINTDLGW pd;
static DOCINFOW di;
static WCHAR *localPrinterName = NULL;
static int copies, paper_width, paper_height, dpi_x, dpi_y;
static LPDEVNAMES devnames;
static HDC printDC;

/*
 * To make the "subcommands" follow a standard convention, add them to this
 * array. The first element is the subcommand name, and the second a standard
 * Tcl command handler.
 */

static const struct gdi_command {
    const char *command_string;
    Tcl_ObjCmdProc *command;
} gdi_commands[] = {
    { "arc",        GdiArc },
    { "bitmap",     GdiBitmap },
    { "characters", GdiCharWidths },
    { "image",      GdiImage },
    { "line",       GdiLine },
    { "map",        GdiMap },
    { "oval",       GdiOval },
    { "photo",      GdiPhoto },
    { "polygon",    GdiPolygon },
    { "rectangle",  GdiRectangle },
    { "text",       GdiText },
    { "copybits",   GdiCopyBits },
};

/*
 *----------------------------------------------------------------------
 *
 * GdiArc --
 *
 * 	Map canvas arcs to GDI context.
 *
 * Results:
 *	Renders arcs.
 *
 *----------------------------------------------------------------------
 */

static int GdiArc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi arc hdc x1 y1 x2 y2 "
	"-extent angle -start angle -style arcstyle "
	"-fill color -outline color "
	"-width dimension -dash dashrule "
	"-outlinestipple ignored -stipple ignored\n" ;
    int x1, y1, x2, y2;
    int xr0, yr0, xr1, yr1;
    HDC hDC;
    double extent = 0.0, start = 0.0;
    DrawFunc drawfunc;
    int width = 0;
    HPEN hPen;
    COLORREF linecolor = 0, fillcolor = BS_NULL;
    int dolinecolor = 0, dofillcolor = 0;
    HBRUSH hBrush = NULL;
    LOGBRUSH lbrush;
    HGDIOBJ oldobj = NULL;
    int dodash = 0;
    const char *dashdata = 0;

    drawfunc = Pie;

    /* Verrrrrry simple for now.... */
    if (argc < 6) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hDC = printDC;

    if ((Tcl_GetIntFromObj(interp, objv[2], &x1) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[3], &y1) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &x2) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[5], &y2) != TCL_OK)) {
	return TCL_ERROR;
    }

    argc -= 6;
    objv += 6;
    while (argc >= 2) {
	if (strcmp(Tcl_GetString(objv[0]), "-extent") == 0) {
	    extent = atof(Tcl_GetString(objv[1]));
	} else if (strcmp(Tcl_GetString(objv[0]), "-start") == 0) {
	    start = atof(Tcl_GetString(objv[1]));
	} else if (strcmp(Tcl_GetString(objv[0]), "-style") == 0) {
	    if (strcmp(Tcl_GetString(objv[1]), "pieslice") == 0) {
		drawfunc = Pie;
	    } else if (strcmp(Tcl_GetString(objv[1]), "arc") == 0) {
		drawfunc = Arc;
	    } else if (strcmp(Tcl_GetString(objv[1]), "chord") == 0) {
		drawfunc = Chord;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-fill") == 0) {
	    /* Handle all args, even if we don't use them yet. */
	    if (GdiGetColor(objv[1], &fillcolor)) {
		dofillcolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-outline") == 0) {
	    if (GdiGetColor(objv[1], &linecolor)) {
		dolinecolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-outlinestipple") == 0) {
	    /* ignored */
	} else if (strcmp(Tcl_GetString(objv[0]), "-stipple") == 0) {
	    /* ignored */
	} else if (strcmp(Tcl_GetString(objv[0]), "-width") == 0) {
	    if (Tcl_GetIntFromObj(interp, objv[1], &width)) {
		return TCL_ERROR;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-dash") == 0) {
	    if (Tcl_GetString(objv[1])) {
		dodash = 1;
		dashdata = Tcl_GetString(objv[1]);
	    }
	} else {
	    /* Don't know that option! */
	    Tcl_AppendResult(interp, usage_message, (char *)NULL);
	    return TCL_ERROR;
	}
	argc -= 2;
	objv += 2;
    }
    xr0 = xr1 = (x1 + x2) / 2;
    yr0 = yr1 = (y1 + y2) / 2;

    /*
     * The angle used by the arc must be "warped" by the eccentricity of the
     * ellipse.  Thanks to Nigel Dodd <[email protected]> for bringing a
     * nice example.
     */

    xr0 += (int)(100.0 * (x2 - x1) * cos((start * 2.0 * 3.14159265) / 360.0));
    yr0 -= (int)(100.0 * (y2 - y1) * sin((start * 2.0 * 3.14159265) / 360.0));
    xr1 += (int)(100.0 * (x2 - x1) * cos(((start+extent) * 2.0 * 3.14159265) / 360.0));
    yr1 -= (int)(100.0 * (y2 - y1) * sin(((start+extent) * 2.0 * 3.14159265) / 360.0));

    /*
     * Under Win95, SetArcDirection isn't implemented--so we have to assume
     * that arcs are drawn counterclockwise (e.g., positive extent) So if it's
     * negative, switch the coordinates!
     */

    if (extent < 0) {
	int xr2 = xr0;
	int yr2 = yr0;

	xr0 = xr1;
	xr1 = xr2;
	yr0 = yr1;
	yr1 = yr2;
    }

    if (dofillcolor) {
	GdiMakeBrush(fillcolor, 0, &lbrush, hDC, &hBrush);
    } else {
	oldobj = SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));
    }

    if (width || dolinecolor) {
	GdiMakePen(interp, width, dodash, dashdata,
		0, 0, 0, 0, linecolor, hDC, (HGDIOBJ *)&hPen);
    }

    (*drawfunc)(hDC, x1, y1, x2, y2, xr0, yr0, xr1, yr1);

    if (width || dolinecolor) {
	GdiFreePen(interp, hDC, hPen);
    }
    if (hBrush) {
	GdiFreeBrush(interp, hDC, hBrush);
    } else {
	SelectObject(hDC, oldobj);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiBitmap --
 *
 * 	Unimplemented for now. Should use the same techniques as
 * 	CanvasPsBitmap (tkCanvPs.c).
 *
 * Results:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int GdiBitmap(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    Tcl_Obj *const *objv)
{
    /*
     * Skip this for now. Should be based on common code with the copybits
     * command.
     */

    Tcl_WrongNumArgs(interp, 1, objv, "hdc x y "
	    "-anchor [center|n|e|s|w] -background color "
	    "-bitmap bitmap -foreground color\n"
	    "Not implemented yet. Sorry!");
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiImage --
 *
 *	Unimplemented for now. Unimplemented for now. Should switch on image
 *	type and call either GdiPhoto or GdiBitmap. This code is similar to
 *	that in tkWinImage.c.
 *
 * Results:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int GdiImage(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    Tcl_Obj *const *objv)
{
    /* Skip this for now..... */
    /* Should be based on common code with the copybits command. */

    Tcl_WrongNumArgs(interp, 1, objv, "hdc x y -anchor [center|n|e|s|w] -image name\n"
	    "Not implemented yet. Sorry!");
    /* Normally, usage results in TCL_ERROR--but wait til' it's implemented. */
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiPhoto --
 *
 *	Contributed by Lukas Rosenthaler <[email protected]>
 *
 *	Note: The canvas doesn't directly support photos (only as images), so
 *	this is the first ::tk::print::_gdi command without an equivalent
 *	canvas command.  This code may be modified to support photo images on
 *	the canvas.
 *
 * Results:
 *	Renders a photo.
 *
 *----------------------------------------------------------------------
 */

static int GdiPhoto(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi photo hdc [-destination x y [w [h]]] -photo name\n";
    HDC dst;
    int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
    int nx, ny, sll;
    const char *photoname = 0;	/* For some reason Tk_FindPhoto takes a char *. */
    Tk_PhotoHandle photo_handle;
    Tk_PhotoImageBlock img_block;
    BITMAPINFO bitmapinfo;	/* Since we don't need the bmiColors table,
				 * there is no need for dynamic allocation. */
    int oldmode;		/* For saving the old stretch mode. */
    POINT pt;			/* For saving the brush org. */
    char *pbuf = NULL;
    int i, j, k;
    int retval = TCL_OK;

    /*
     * Parse the arguments.
     */

    /* HDC is required. */
    if (argc < 2) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    dst = printDC;

    /*
     * Next, check to see if 'dst' can support BitBlt.
     * If not, raise an error.
     */

    if ((GetDeviceCaps(dst, RASTERCAPS) & RC_STRETCHDIB) == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"::tk::print::_gdi photo not supported on device context (0x%s)",
		Tcl_GetString(objv[1])));
	return TCL_ERROR;
    }

    /* Parse the command line arguments. */
    for (j = 2; j < argc; j++) {
	if (strcmp(Tcl_GetString(objv[j]), "-destination") == 0) {
	    double x, y, w, h;
	    int count = 0;
	    char dummy;

	    if (j < argc) {
		count = sscanf(Tcl_GetString(objv[++j]), "%lf%lf%lf%lf%c",
			&x, &y, &w, &h, &dummy);
	    }

	    if (count < 2 || count > 4) {
		/* Destination must provide at least 2 arguments. */
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-destination requires a list of 2 to 4 numbers\n%s",
			usage_message));
		return TCL_ERROR;
	    }

	    dst_x = (int) x;
	    dst_y = (int) y;
	    if (count == 3) {
		dst_w = (int) w;
		dst_h = -1;
	    } else if (count == 4) {
		dst_w = (int) w;
		dst_h = (int) h;
	    }
	} else if (strcmp(Tcl_GetString(objv[j]), "-photo") == 0) {
	    photoname = Tcl_GetString(objv[++j]);
	}
    }

    if (photoname == 0) {	/* No photo provided. */
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"No photo name provided to ::tk::print::_gdi photo\n%s",
		usage_message));
	return TCL_ERROR;
    }

    photo_handle = Tk_FindPhoto(interp, photoname);
    if (photo_handle == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"::tk::print::_gdi photo: Photo name %s can't be located\n%s",
		photoname, usage_message));
	return TCL_ERROR;
    }
    Tk_PhotoGetImage(photo_handle, &img_block);

    nx  = img_block.width;
    ny  = img_block.height;
    sll = ((3*nx + 3) / 4)*4; /* Must be multiple of 4. */

    /*
     * Buffer is potentially large enough that failure to allocate might be
     * recoverable.
     */

    pbuf = (char *)attemptckalloc(sll * ny * sizeof(char));
    if (pbuf == 0) { /* Memory allocation failure. */
	Tcl_AppendResult(interp,
		"::tk::print::_gdi photo failed--out of memory", (char *)NULL);
	return TCL_ERROR;
    }

    /* After this, all returns must go through retval. */

    /* BITMAP expects BGR; photo provides RGB. */
    for (k = 0; k < ny; k++) {
	for (i = 0; i < nx; i++) {
	    pbuf[k*sll + 3*i] = img_block.pixelPtr[
		    k*img_block.pitch + i*img_block.pixelSize + img_block.offset[2]];
	    pbuf[k*sll + 3*i + 1] = img_block.pixelPtr[
		    k*img_block.pitch + i*img_block.pixelSize + img_block.offset[1]];
	    pbuf[k*sll + 3*i + 2] = img_block.pixelPtr[
		    k*img_block.pitch + i*img_block.pixelSize + img_block.offset[0]];
	}
    }

    memset(&bitmapinfo, 0L, sizeof(BITMAPINFO));

    bitmapinfo.bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
    bitmapinfo.bmiHeader.biWidth         = nx;
    bitmapinfo.bmiHeader.biHeight        = -ny;
    bitmapinfo.bmiHeader.biPlanes        = 1;
    bitmapinfo.bmiHeader.biBitCount      = 24;
    bitmapinfo.bmiHeader.biCompression   = BI_RGB;
    bitmapinfo.bmiHeader.biSizeImage     = 0; /* sll*ny;. */
    bitmapinfo.bmiHeader.biXPelsPerMeter = 0;
    bitmapinfo.bmiHeader.biYPelsPerMeter = 0;
    bitmapinfo.bmiHeader.biClrUsed       = 0;
    bitmapinfo.bmiHeader.biClrImportant  = 0;

    oldmode = SetStretchBltMode(dst, HALFTONE);
    /*
     * According to the Win32 Programmer's Manual, we have to set the brush
     * org, now.
     */
    SetBrushOrgEx(dst, 0, 0, &pt);

    if (dst_w <= 0) {
	dst_w = nx;
	dst_h = ny;
    } else if (dst_h <= 0) {
	dst_h = ny*dst_w / nx;
    }

    if (StretchDIBits(dst, dst_x, dst_y, dst_w, dst_h, 0, 0, nx, ny,
	    pbuf, &bitmapinfo, DIB_RGB_COLORS, SRCCOPY) == (int)GDI_ERROR) {
	int errcode = GetLastError();

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"::tk::print::_gdi photo internal failure: "
		"StretchDIBits error code %d", errcode));
	retval = TCL_ERROR;
    }

    /* Clean up the hDC. */
    if (oldmode != 0) {
	SetStretchBltMode(dst, oldmode);
	SetBrushOrgEx(dst, pt.x, pt.y, &pt);
    }

    ckfree(pbuf);

    if (retval == TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%d %d %d %d", dst_x, dst_y, dst_w, dst_h));
    }

    return retval;
}

/*
 *----------------------------------------------------------------------
 *
 * Bezierize --
 *
 *	Interface to Tk's line smoother, used for lines and pollies.
 *	Provided by Jasper Taylor <[email protected]>.
 *
 * Results:
 *	Smooths lines.
 *
 *----------------------------------------------------------------------
 */

static int Bezierize(
    POINT* polypoints,
    int npoly,
    int nStep,
    POINT* bpointptr)
{
    /* First, translate my points into a list of doubles. */
    double *inPointList, *outPointList;
    int n;
    int nbpoints = 0;
    POINT* bpoints;

    inPointList = (double *)attemptckalloc(2 * sizeof(double) * npoly);
    if (inPointList == 0) {
	/* TODO: unreachable */
        return nbpoints; /* 0. */
    }

    for (n=0; n<npoly; n++) {
        inPointList[2*n] = polypoints[n].x;
        inPointList[2*n + 1] = polypoints[n].y;
    }

    nbpoints = 1 + npoly * nStep; /* this is the upper limit. */
    outPointList = (double *)attemptckalloc(2 * sizeof(double) * nbpoints);
    if (outPointList == 0) {
	/* TODO: unreachable */
        ckfree(inPointList);
        return 0;
    }

    nbpoints = TkMakeBezierCurve(NULL, inPointList, npoly, nStep,
	    NULL, outPointList);

    ckfree(inPointList);
    bpoints = (POINT *)attemptckalloc(sizeof(POINT)*nbpoints);
    if (bpoints == 0) {
	/* TODO: unreachable */
        ckfree(outPointList);
        return 0;
    }

    for (n=0; n<nbpoints; n++) {
        bpoints[n].x = (long)outPointList[2*n];
        bpoints[n].y = (long)outPointList[2*n + 1];
    }
    ckfree(outPointList);
    *bpointptr = *bpoints;
    return nbpoints;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiLine --
 *
 *	Maps lines to GDI context.
 *
 * Results:
 *	Renders lines.
 *
 *----------------------------------------------------------------------
 */

static int GdiLine(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi line hdc x1 y1 ... xn yn "
	"-arrow [first|last|both|none] -arrowshape {d1 d2 d3} "
	"-dash dashlist "
	"-capstyle [butt|projecting|round] -fill color "
	"-joinstyle [bevel|miter|round] -smooth [true|false|bezier] "
	"-splinesteps number -stipple bitmap -width linewid";
    char *strend;
    POINT *polypoints;
    int npoly;
    int x, y;
    HDC hDC;
    HPEN hPen;

    LOGBRUSH lbrush;
    HBRUSH hBrush = NULL;

    int width          = 0;
    COLORREF linecolor = 0;
    int dolinecolor    = 0;
    int dosmooth       = 0;
    int doarrow        = 0; /* 0=none; 1=end; 2=start; 3=both. */
    int arrowshape[3];

    int nStep = 12;

    int dodash = 0;
    const char *dashdata = 0;

    arrowshape[0] = 8;
    arrowshape[1] = 10;
    arrowshape[2] = 3;

    /* Verrrrrry simple for now.... */
    if (argc < 6) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hDC = printDC;

    polypoints = (POINT *)attemptckalloc((argc - 1) * sizeof(POINT));
    if (polypoints == 0) {
	Tcl_AppendResult(interp, "Out of memory in GdiLine", (char *)NULL);
	return TCL_ERROR;
    }
    if ((Tcl_GetIntFromObj(interp, objv[2], (int *)&polypoints[0].x) != TCL_OK)
	|| 	(Tcl_GetIntFromObj(interp, objv[3], (int *)&polypoints[0].y) != TCL_OK)
	|| 	(Tcl_GetIntFromObj(interp, objv[4], (int *)&polypoints[1].x) != TCL_OK)
	|| 	(Tcl_GetIntFromObj(interp, objv[5], (int *)&polypoints[1].y) != TCL_OK)
    ) {
	return TCL_ERROR;
    }
    argc -= 6;
    objv += 6;
    npoly = 2;

    while (argc >= 2) {
	/* Check for a number. */
	x = strtoul(Tcl_GetString(objv[0]), &strend, 0);
	if (strend > Tcl_GetString(objv[0])) {
	    /* One number.... */
	    y = strtoul(Tcl_GetString(objv[1]), &strend, 0);
	    if (strend > Tcl_GetString(objv[1])) {
		/* TWO numbers!. */
		polypoints[npoly].x = x;
		polypoints[npoly].y = y;
		npoly++;
		argc -= 2;
		objv += 2;
	    } else {
		/* Only one number... Assume a usage error. */
		ckfree(polypoints);
		Tcl_AppendResult(interp, usage_message, (char *)NULL);
		return TCL_ERROR;
	    }
	} else {
	    if (strcmp(Tcl_GetString(*objv), "-arrow") == 0) {
		if (strcmp(Tcl_GetString(objv[1]), "none") == 0) {
		    doarrow = 0;
		} else if (strcmp(Tcl_GetString(objv[1]), "both") == 0) {
		    doarrow = 3;
		} else if (strcmp(Tcl_GetString(objv[1]), "first") == 0) {
		    doarrow = 2;
		} else if (strcmp(Tcl_GetString(objv[1]), "last") == 0) {
		    doarrow = 1;
		}
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-arrowshape") == 0) {
		/* List of 3 numbers--set arrowshape array. */
		int a1, a2, a3;
		char dummy;

		if (sscanf(Tcl_GetString(objv[1]), "%d%d%d%c", &a1, &a2, &a3, &dummy) == 3
			&& a1 > 0 && a2 > 0 && a3 > 0) {
		    arrowshape[0] = a1;
		    arrowshape[1] = a2;
		    arrowshape[2] = a3;
		}
		/* Else the argument was bad. */

		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-capstyle") == 0) {
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-fill") == 0) {
		if (GdiGetColor(objv[1], &linecolor)) {
		    dolinecolor = 1;
		}
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-joinstyle") == 0) {
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-smooth") == 0) {
		/* Argument is true/false or 1/0 or bezier. */
		if (Tcl_GetString(objv[1])) {
		    switch (Tcl_GetString(objv[1])[0]) {
		    case 't': case 'T':
		    case '1':
		    case 'b': case 'B': /* bezier. */
			dosmooth = 1;
			break;
		    default:
			dosmooth = 0;
			break;
		    }
		    objv += 2;
		    argc -= 2;
		}
	    } else if (strcmp(Tcl_GetString(*objv), "-splinesteps") == 0) {
		if (Tcl_GetIntFromObj(interp, objv[1], &nStep) != TCL_OK) {
		    return TCL_ERROR;
		}
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-dash") == 0) {
		if (Tcl_GetString(objv[1])) {
		    dodash = 1;
		    dashdata = Tcl_GetString(objv[1]);
		}
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-dashoffset") == 0) {
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-stipple") == 0) {
		objv += 2;
		argc -= 2;
	    } else if (strcmp(Tcl_GetString(*objv), "-width") == 0) {
		if (Tcl_GetIntFromObj(interp, objv[1], &width) != TCL_OK) {
		    return TCL_ERROR;
		}
		objv += 2;
		argc -= 2;
	    } else { /* It's an unknown argument!. */
		argc--;
		objv++;
	    }
	    /* Check for arguments
	     * Most of the arguments affect the "Pen"
	     */
	}
    }

    if (width || dolinecolor || dodash) {
	GdiMakePen(interp, width, dodash, dashdata,
		0, 0, 0, 0, linecolor, hDC, (HGDIOBJ *)&hPen);
    }
    if (doarrow != 0) {
	GdiMakeBrush(linecolor, 0, &lbrush, hDC, &hBrush);
    }

    if (dosmooth) { /* Use PolyBezier. */
	int nbpoints;
	POINT *bpoints = 0;

	nbpoints = Bezierize(polypoints,npoly,nStep,bpoints);
	if (nbpoints > 0) {
	    Polyline(hDC, bpoints, nbpoints);
	} else {
	    Polyline(hDC, polypoints, npoly); /* Out of memory? Just draw a regular line. */
	}
	if (bpoints != 0) {
	    ckfree(bpoints);
	}
    } else {
	Polyline(hDC, polypoints, npoly);
    }

    if (dodash && doarrow) {  /* Don't use dashed or thick pen for the arrows! */
	GdiFreePen(interp, hDC, hPen);
	GdiMakePen(interp, width, 0, 0, 0, 0, 0, 0,
		linecolor, hDC, (HGDIOBJ *)&hPen);
    }

    /* Now the arrowheads, if any. */
    if (doarrow & 1) {
	/* Arrowhead at end = polypoints[npoly-1].x, polypoints[npoly-1].y. */
	POINT ahead[6];
	double dx, dy, length;
	double sinTheta, cosTheta;
	double vertX, vertY, temp;
	double fracHeight;

	fracHeight = 2.0 / arrowshape[2];

	ahead[0].x = ahead[5].x = polypoints[npoly-1].x;
	ahead[0].y = ahead[5].y = polypoints[npoly-1].y;
	dx = ahead[0].x - polypoints[npoly-2].x;
	dy = ahead[0].y - polypoints[npoly-2].y;
	if ((length = hypot(dx, dy)) == 0) {
	    sinTheta = cosTheta = 0.0;
	} else {
	    sinTheta = dy / length;
	    cosTheta = dx / length;
	}
	vertX = ahead[0].x - arrowshape[0]*cosTheta;
	vertY = ahead[0].y - arrowshape[0]*sinTheta;
	temp = arrowshape[2]*sinTheta;
	ahead[1].x = (long)(ahead[0].x - arrowshape[1]*cosTheta + temp);
	ahead[4].x = (long)(ahead[1].x - 2 * temp);
	temp = arrowshape[2]*cosTheta;
	ahead[1].y = (long)(ahead[0].y - arrowshape[1]*sinTheta - temp);
	ahead[4].y = (long)(ahead[1].y + 2 * temp);
	ahead[2].x = (long)(ahead[1].x*fracHeight + vertX*(1.0-fracHeight));
	ahead[2].y = (long)(ahead[1].y*fracHeight + vertY*(1.0-fracHeight));
	ahead[3].x = (long)(ahead[4].x*fracHeight + vertX*(1.0-fracHeight));
	ahead[3].y = (long)(ahead[4].y*fracHeight + vertY*(1.0-fracHeight));

	Polygon(hDC, ahead, 6);
    }

    if (doarrow & 2) {
	/* Arrowhead at end = polypoints[0].x, polypoints[0].y. */
	POINT ahead[6];
	double dx, dy, length;
	double sinTheta, cosTheta;
	double vertX, vertY, temp;
	double fracHeight;

	fracHeight = 2.0 / arrowshape[2];

	ahead[0].x = ahead[5].x = polypoints[0].x;
	ahead[0].y = ahead[5].y = polypoints[0].y;
	dx = ahead[0].x - polypoints[1].x;
	dy = ahead[0].y - polypoints[1].y;
	if ((length = hypot(dx, dy)) == 0) {
	    sinTheta = cosTheta = 0.0;
	} else {
	    sinTheta = dy / length;
	    cosTheta = dx / length;
	}
	vertX = ahead[0].x - arrowshape[0]*cosTheta;
	vertY = ahead[0].y - arrowshape[0]*sinTheta;
	temp = arrowshape[2]*sinTheta;
	ahead[1].x = (long)(ahead[0].x - arrowshape[1]*cosTheta + temp);
	ahead[4].x = (long)(ahead[1].x - 2 * temp);
	temp = arrowshape[2]*cosTheta;
	ahead[1].y = (long)(ahead[0].y - arrowshape[1]*sinTheta - temp);
	ahead[4].y = (long)(ahead[1].y + 2 * temp);
	ahead[2].x = (long)(ahead[1].x*fracHeight + vertX*(1.0-fracHeight));
	ahead[2].y = (long)(ahead[1].y*fracHeight + vertY*(1.0-fracHeight));
	ahead[3].x = (long)(ahead[4].x*fracHeight + vertX*(1.0-fracHeight));
	ahead[3].y = (long)(ahead[4].y*fracHeight + vertY*(1.0-fracHeight));

	Polygon(hDC, ahead, 6);
    }

    if (width || dolinecolor || dodash) {
	GdiFreePen(interp, hDC, hPen);
    }
    if (hBrush) {
	GdiFreeBrush(interp, hDC, hBrush);
    }

    ckfree(polypoints);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiOval --
 *
 *	Maps ovals to GDI context.
 *
 * Results:
 *	Renders ovals.
 *
 *----------------------------------------------------------------------
 */

static int GdiOval(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi oval hdc x1 y1 x2 y2 -fill color -outline color "
	"-stipple bitmap -width linewid";
    int x1, y1, x2, y2;
    HDC hDC;
    HPEN hPen;
    int width = 0;
    COLORREF linecolor = 0, fillcolor = 0;
    int dolinecolor = 0, dofillcolor = 0;
    HBRUSH hBrush = NULL;
    LOGBRUSH lbrush;
    HGDIOBJ oldobj = NULL;

    int dodash = 0;
    const char *dashdata = 0;

    /* Verrrrrry simple for now.... */
    if (argc < 6) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hDC = printDC;

    if ((Tcl_GetIntFromObj(interp, objv[2], &x1) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[2], &y1) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[3], &x2) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &y2) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (x1 > x2) {
	int x3 = x1;
	x1 = x2;
	x2 = x3;
    }
    if (y1 > y2) {
	int y3 = y1;
	y1 = y2;
	y2 = y3;
    }
    argc -= 6;
    objv += 6;

    while (argc > 0) {
	/* Now handle any other arguments that occur. */
	if (strcmp(Tcl_GetString(objv[0]), "-fill") == 0) {
	    if (Tcl_GetString(objv[1]) && GdiGetColor(objv[1], &fillcolor)) {
		dofillcolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-outline") == 0) {
	    if (Tcl_GetString(objv[1]) && GdiGetColor(objv[1], &linecolor)) {
		dolinecolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-stipple") == 0) {
	    /* Not actually implemented */
	} else if (strcmp(Tcl_GetString(objv[0]), "-width") == 0) {
	    if (Tcl_GetString(objv[1])) {
		if (Tcl_GetIntFromObj(interp, objv[1], &width) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-dash") == 0) {
	    if (Tcl_GetString(objv[1])) {
		dodash = 1;
		dashdata = Tcl_GetString(objv[1]);
	    }
	}
	objv += 2;
	argc -= 2;
    }

    if (dofillcolor) {
	GdiMakeBrush(fillcolor, 0, &lbrush, hDC, &hBrush);
    } else {
	oldobj = SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));
    }

    if (width || dolinecolor) {
	GdiMakePen(interp, width, dodash, dashdata,
		0, 0, 0, 0, linecolor, hDC, (HGDIOBJ *)&hPen);
    }
    /*
     * Per Win32, Rectangle includes lower and right edges--per Tcl8.3.2 and
     * earlier documentation, canvas rectangle does not. Thus, add 1 to right
     * and lower bounds to get appropriate behavior.
     */
    Ellipse(hDC, x1, y1, x2+1, y2+1);

    if (width || dolinecolor) {
	GdiFreePen(interp, hDC, hPen);
    }
    if (hBrush) {
	GdiFreeBrush(interp, hDC, hBrush);
    } else {
	SelectObject(hDC, oldobj);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiPolygon --
 *
 *	Maps polygons to GDI context.
 *
 * Results:
 *	Renders polygons.
 *
 *----------------------------------------------------------------------
 */

static int GdiPolygon(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi polygon hdc x1 y1 ... xn yn "
	"-fill color -outline color -smooth [true|false|bezier] "
	"-splinesteps number -stipple bitmap -width linewid";

    char *strend;
    POINT *polypoints;
    int npoly;
    int dosmooth = 0;
    int nStep = 12;
    int x, y;
    HDC hDC;
    HPEN hPen;
    int width = 0;
    COLORREF linecolor = 0, fillcolor = BS_NULL;
    int dolinecolor = 0, dofillcolor = 0;
    LOGBRUSH lbrush;
    HBRUSH hBrush = NULL;
    HGDIOBJ oldobj = NULL;

    int dodash = 0;
    const char *dashdata = 0;

    /* Verrrrrry simple for now.... */
    if (argc < 6) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hDC = printDC;

    polypoints = (POINT *)attemptckalloc((argc - 1) * sizeof(POINT));
    if (polypoints == 0) {
	/* TODO: unreachable */
	Tcl_AppendResult(interp, "Out of memory in GdiLine", (char *)NULL);
	return TCL_ERROR;
    }
    if ((Tcl_GetIntFromObj(interp, objv[2], (int *)&polypoints[0].x) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[3], (int *)&polypoints[0].y) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], (int *)&polypoints[1].x) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[5], (int *)&polypoints[1].y) != TCL_OK)) {
	return TCL_ERROR;
    }
    argc -= 6;
    objv += 6;
    npoly = 2;

    while (argc >= 2) {
	/* Check for a number */
	x = strtoul(Tcl_GetString(objv[0]), &strend, 0);
	if (strend > Tcl_GetString(objv[0])) {
	    /* One number.... */
	    y = strtoul(Tcl_GetString(objv[1]), &strend, 0);
	    if (strend > Tcl_GetString(objv[1])) {
		/* TWO numbers!. */
		polypoints[npoly].x = x;
		polypoints[npoly].y = y;
		npoly++;
		argc -= 2;
		objv += 2;
	    } else {
		/* Only one number... Assume a usage error. */
		ckfree(polypoints);
		Tcl_AppendResult(interp, usage_message, (char *)NULL);
		return TCL_ERROR;
	    }
	} else {
	    /*
	     * Check for arguments.
	     * Most of the arguments affect the "Pen" and "Brush".
	     */
	    if (strcmp(Tcl_GetString(objv[0]), "-fill") == 0) {
		if (Tcl_GetString(objv[1]) && GdiGetColor(objv[1], &fillcolor)) {
		    dofillcolor = 1;
		}
	    } else if (strcmp(Tcl_GetString(objv[0]), "-outline") == 0) {
		if (GdiGetColor(objv[1], &linecolor)) {
		    dolinecolor = 0;
		}
	    } else if (strcmp(Tcl_GetString(objv[0]), "-smooth") == 0) {
		if (Tcl_GetString(objv[1])) {
		    switch (Tcl_GetString(objv[1])[0]) {
		    case 't': case 'T':
		    case '1':
		    case 'b': case 'B': /* bezier. */
			dosmooth = 1;
			break;
		    default:
			dosmooth = 0;
			break;
		    }
		}
	    } else if (strcmp(Tcl_GetString(objv[0]), "-splinesteps") == 0) {
		if (Tcl_GetString(objv[1])) {
		    if (Tcl_GetIntFromObj(interp, objv[1], &nStep) != TCL_OK) {
			return TCL_ERROR;
		    }
		}
	    } else if (strcmp(Tcl_GetString(objv[0]), "-stipple") == 0) {
		/* Not supported */
	    } else if (strcmp(Tcl_GetString(objv[0]), "-width") == 0) {
		if (Tcl_GetString(objv[1])) {
		    if (Tcl_GetIntFromObj(interp, objv[1], &width) != TCL_OK) {
			return TCL_ERROR;
		    }
		}
	    } else if (strcmp(Tcl_GetString(objv[0]), "-dash") == 0) {
		if (Tcl_GetString(objv[1])) {
		    dodash = 1;
		    dashdata = Tcl_GetString(objv[1]);
		}
	    }
	    argc -= 2;
	    objv += 2;
	}
    }

    if (dofillcolor) {
	GdiMakeBrush(fillcolor, 0, &lbrush, hDC, &hBrush);
    } else {
	oldobj = SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));
    }

    if (width || dolinecolor) {
	GdiMakePen(interp, width, dodash, dashdata, 0, 0, 0, 0,
		linecolor, hDC, (HGDIOBJ *)&hPen);
    }

    if (dosmooth) {
	int nbpoints;
	POINT *bpoints = 0;
	nbpoints = Bezierize(polypoints,npoly,nStep,bpoints);
	if (nbpoints > 0) {
	    Polygon(hDC, bpoints, nbpoints);
	} else {
	    Polygon(hDC, polypoints, npoly);
	}
	if (bpoints != 0) {
	    ckfree(bpoints);
	}
    } else {
	Polygon(hDC, polypoints, npoly);
    }

    if (width || dolinecolor) {
	GdiFreePen(interp, hDC, hPen);
    }
    if (hBrush) {
	GdiFreeBrush(interp, hDC, hBrush);
    } else {
	SelectObject(hDC, oldobj);
    }

    ckfree(polypoints);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiRectangle --
 *
 *	Maps rectangles to GDI context.
 *
 * Results:
 *	Renders rectangles.
 *
 *----------------------------------------------------------------------
 */

static int GdiRectangle(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi rectangle hdc x1 y1 x2 y2 "
	"-fill color -outline color "
	"-stipple bitmap -width linewid";

    int x1, y1, x2, y2;
    HDC hDC;
    HPEN hPen;
    int width = 0;
    COLORREF linecolor = 0, fillcolor = BS_NULL;
    int dolinecolor = 0, dofillcolor = 0;
    LOGBRUSH lbrush;
    HBRUSH hBrush = NULL;
    HGDIOBJ oldobj = NULL;

    int dodash = 0;
    const char *dashdata = 0;

    /* Verrrrrry simple for now.... */
    if (argc < 6) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hDC = printDC;

    if ((Tcl_GetIntFromObj(interp, objv[2], &x1) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[3], &y1) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &x2) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[5], &y2) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (x1 > x2) {
	int x3 = x1;
	x1 = x2;
	x2 = x3;
    }
    if (y1 > y2) {
	int y3 = y1;
	y1 = y2;
	y2 = y3;
    }
    argc -= 6;
    objv += 6;

    /* Now handle any other arguments that occur. */
    while (argc > 1) {
	if (strcmp(Tcl_GetString(objv[0]), "-fill") == 0) {
	    if (Tcl_GetString(objv[1]) && GdiGetColor(objv[1], &fillcolor)) {
		dofillcolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-outline") == 0) {
	    if (Tcl_GetString(objv[1]) && GdiGetColor(objv[1], &linecolor)) {
		dolinecolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-stipple") == 0) {
	    /* Not supported; ignored */
	} else if (strcmp(Tcl_GetString(objv[0]), "-width") == 0) {
	    if (Tcl_GetString(objv[1])) {
		if (Tcl_GetIntFromObj(interp, objv[1], &width) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-dash") == 0) {
	    if (Tcl_GetString(objv[1])) {
		dodash = 1;
		dashdata = Tcl_GetString(objv[1]);
	    }
	}

	argc -= 2;
	objv += 2;
    }

    /*
     * Note: If any fill is specified, the function must create a brush and
     * put the coordinates in a RECTANGLE structure, and call FillRect.
     * FillRect requires a BRUSH / color.
     * If not, the function Rectangle must be called.
     */
    if (dofillcolor) {
	GdiMakeBrush(fillcolor, 0, &lbrush, hDC, &hBrush);
    } else {
	oldobj = SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));
    }

    if (width || dolinecolor) {
	GdiMakePen(interp, width, dodash, dashdata,
		0, 0, 0, 0, linecolor, hDC, (HGDIOBJ *)&hPen);
    }
    /*
     * Per Win32, Rectangle includes lower and right edges--per Tcl8.3.2 and
     * earlier documentation, canvas rectangle does not. Thus, add 1 to
     * right and lower bounds to get appropriate behavior.
     */
    Rectangle(hDC, x1, y1, x2+1, y2+1);

    if (width || dolinecolor) {
	GdiFreePen(interp, hDC, hPen);
    }
    if (hBrush) {
	GdiFreeBrush(interp, hDC, hBrush);
    } else {
	SelectObject(hDC, oldobj);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiCharWidths --
 *
 *	Computes /character widths. This is completely inadequate for
 *	typesetting, but should work for simple text manipulation.
 *
 * Results:
 *	Returns character width.
 *
 *----------------------------------------------------------------------
 */


static int GdiCharWidths(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi characters hdc [-font fontname] [-array ary]";
    /*
     * Returns widths of characters from font in an associative array.
     * Font is currently selected font for HDC if not specified.
     * Array name is GdiCharWidths if not specified.
     * Widths should be in the same measures as all other values (1/1000 inch).
     */

    HDC hDC;
    LOGFONTW lf;
    HFONT hfont;
    HGDIOBJ oldfont;
    int made_font = 0;
    const char *aryvarname = "GdiCharWidths";
    /* For now, assume 256 characters in the font.... */
    int widths[256];
    int retval;

    if (argc < 2) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hDC = printDC;

    argc -= 2;
    objv += 2;

    while (argc > 0) {
	if (strcmp(Tcl_GetString(objv[0]), "-font") == 0) {
	    argc--;
	    objv++;
	    if (GdiMakeLogFont(interp, Tcl_GetString(objv[0]), &lf, hDC)) {
		if ((hfont = CreateFontIndirectW(&lf)) != NULL) {
		    made_font = 1;
		    oldfont = SelectObject(hDC, hfont);
		}
	    }
	    /* Else leave the font alone!. */
	} else if (strcmp(Tcl_GetString(objv[0]), "-array") == 0) {
	    objv++;
	    argc--;
	    if (argc > 0) {
		aryvarname = Tcl_GetString(objv[0]);
	    }
	}
	objv++;
	argc--;
    }

    /* Now, get the widths using the correct function for font type. */
    if ((retval = GetCharWidth32W(hDC, 0, 255, widths)) == FALSE) {
	retval = GetCharWidthW(hDC, 0, 255, widths);
    }

    /*
     * Retval should be 1 (TRUE) if the function succeeded. If the function
     * fails, get the "extended" error code and return. Be sure to deallocate
     * the font if necessary.
     */
    if (retval == FALSE) {
	DWORD val = GetLastError();

	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                "::tk::print::_gdi character failed with code %ld", val));
	if (made_font) {
	    SelectObject(hDC, oldfont);
	    DeleteObject(hfont);
	}
	return TCL_ERROR;
    }

    {
	int i;
	char ind[2];
	ind[1] = '\0';

	for (i = 0; i < 255; i++) {
	    /* TODO: use a bytearray for the index name so NUL works */
	    ind[0] = i;
	    Tcl_SetVar2Ex(interp, aryvarname, ind, Tcl_NewIntObj(widths[i]),
		    TCL_GLOBAL_ONLY);
	}
    }
    /* Now, remove the font if we created it only for this function. */
    if (made_font) {
	SelectObject(hDC, oldfont);
	DeleteObject(hfont);
    }

    /* The return value should be the array name(?). */
    Tcl_AppendResult(interp, aryvarname, (char *)NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiText --
 *
 *	Maps text to GDI context.
 *
 * Results:
 *	Renders text.
 *
 *----------------------------------------------------------------------
 */

int GdiText(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi text hdc x y -anchor [center|n|e|s|w] "
	"-fill color -font fontname "
	"-justify [left|right|center] "
	"-stipple bitmap -text string -width linelen "
	"-single -backfill";

    HDC hDC;
    int x, y;
    const char *string = 0;
    RECT sizerect;
    UINT format_flags = DT_EXPANDTABS|DT_NOPREFIX; /* Like the canvas. */
    Tk_Anchor anchor = TK_ANCHOR_N;
    LOGFONTW lf;
    HFONT hfont;
    HGDIOBJ oldfont;
    int made_font = 0;
    int retval;
    int dotextcolor = 0;
    int dobgmode = 0;
    int bgmode;
    COLORREF textcolor = 0;
    int usesingle = 0;
    WCHAR *wstring;
    Tcl_DString tds;

    if (argc < 4) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    /* Parse the command. */

    hDC = printDC;

    if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	return TCL_ERROR;
    }
    argc -= 4;
    objv += 4;

    sizerect.left = sizerect.right = x;
    sizerect.top = sizerect.bottom = y;

    while (argc > 0) {
	if (strcmp(Tcl_GetString(objv[0]), "-anchor") == 0) {
	    argc--;
	    objv++;
	    if (argc > 0) {
		Tk_GetAnchor(interp, Tcl_GetString(objv[0]), &anchor);
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-justify") == 0) {
	    argc--;
	    objv++;
	    if (argc > 0) {
		if (strcmp(Tcl_GetString(objv[0]), "left") == 0) {
		    format_flags |= DT_LEFT;
		} else if (strcmp(Tcl_GetString(objv[0]), "center") == 0) {
		    format_flags |= DT_CENTER;
		} else if (strcmp(Tcl_GetString(objv[0]), "right") == 0) {
		    format_flags |= DT_RIGHT;
		}
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-text") == 0) {
	    argc--;
	    objv++;
	    if (argc > 0) {
		string = Tcl_GetString(objv[0]);
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-font") == 0) {
	    argc--;
	    objv++;
	    if (GdiMakeLogFont(interp, Tcl_GetString(objv[0]), &lf, hDC)) {
		if ((hfont = CreateFontIndirectW(&lf)) != NULL) {
		    made_font = 1;
		    oldfont = SelectObject(hDC, hfont);
		}
	    }
	    /* Else leave the font alone! */
	} else if (strcmp(Tcl_GetString(objv[0]), "-stipple") == 0) {
	    argc--;
	    objv++;
	    /* Not implemented yet. */
	} else if (strcmp(Tcl_GetString(objv[0]), "-fill") == 0) {
	    argc--;
	    objv++;
	    /* Get text color. */
	    if (GdiGetColor(objv[0], &textcolor)) {
		dotextcolor = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[0]), "-width") == 0) {
	    argc--;
	    objv++;
	    if (argc > 0) {
		int value;
		if (Tcl_GetIntFromObj(interp, objv[0], &value) != TCL_OK) {
		    return TCL_ERROR;
		}
		sizerect.right += value;
	    }
	    /* If a width is specified, break at words. */
	    format_flags |= DT_WORDBREAK;
	} else if (strcmp(Tcl_GetString(objv[0]), "-single") == 0) {
	    usesingle = 1;
	} else if (strcmp(Tcl_GetString(objv[0]), "-backfill") == 0) {
	    dobgmode = 1;
	}

	argc--;
	objv++;
    }

    if (string == 0) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    /* Set the format flags for -single: Overrides -width. */
    if (usesingle == 1) {
	format_flags |= DT_SINGLELINE;
	format_flags |= DT_NOCLIP;
	format_flags &= ~DT_WORDBREAK;
    }

    Tcl_DStringInit(&tds);
    /* Just for fun, let's try translating string to Unicode. */
    wstring = Tcl_UtfToWCharDString(string, TCL_INDEX_NONE, &tds);
    DrawTextW(hDC, wstring, Tcl_DStringLength(&tds)/2, &sizerect,
	    format_flags | DT_CALCRECT);

    /* Adjust the rectangle according to the anchor. */
    x = y = 0;
    switch (anchor) {
    case TK_ANCHOR_N:
	x = (sizerect.right - sizerect.left) / 2;
	break;
    case TK_ANCHOR_S:
	x = (sizerect.right - sizerect.left) / 2;
	y = (sizerect.bottom - sizerect.top);
	break;
    case TK_ANCHOR_E:
	x = (sizerect.right - sizerect.left);
	y = (sizerect.bottom - sizerect.top) / 2;
	break;
    case TK_ANCHOR_W:
	y = (sizerect.bottom - sizerect.top) / 2;
	break;
    case TK_ANCHOR_NE:
	x = (sizerect.right - sizerect.left);
	break;
    case TK_ANCHOR_NW:
	break;
    case TK_ANCHOR_SE:
	x = (sizerect.right - sizerect.left);
	y = (sizerect.bottom - sizerect.top);
	break;
    case TK_ANCHOR_SW:
	y = (sizerect.bottom - sizerect.top);
	break;
    default:
	x = (sizerect.right - sizerect.left) / 2;
	y = (sizerect.bottom - sizerect.top) / 2;
	break;
    }
    sizerect.right  -= x;
    sizerect.left   -= x;
    sizerect.top    -= y;
    sizerect.bottom -= y;

    /* Get the color right. */
    if (dotextcolor) {
	textcolor = SetTextColor(hDC, textcolor);
    }

    if (dobgmode) {
	bgmode = SetBkMode(hDC, OPAQUE);
    } else {
	bgmode = SetBkMode(hDC, TRANSPARENT);
    }

    /* Print the text. */
    retval = DrawTextW(hDC, wstring,
	    Tcl_DStringLength(&tds)/2, &sizerect, format_flags);
    Tcl_DStringFree(&tds);

    /* Get the color set back. */
    if (dotextcolor) {
	textcolor = SetTextColor(hDC, textcolor);
    }
    SetBkMode(hDC, bgmode);
    if (made_font) {
	SelectObject(hDC, oldfont);
	DeleteObject(hfont);
    }

    /* In this case, the return value is the height of the text. */
    Tcl_SetObjResult(interp, Tcl_NewIntObj(retval));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiGetHdcInfo --
 *
 *	Gets salient characteristics of the CTM.
 *
 * Results:
 *	The return value is 0 if any failure occurs--in which case none of the
 *	other values are meaningful.  Otherwise the return value is the
 *	current mapping mode.
 *
 *----------------------------------------------------------------------
 */

static int GdiGetHdcInfo(
    HDC hdc,
    LPPOINT worigin,
    LPSIZE wextent,
    LPPOINT vorigin,
    LPSIZE vextent)
{
    int mapmode;
    int retval;

    memset(worigin, 0, sizeof(POINT));
    memset(vorigin, 0, sizeof(POINT));
    memset(wextent, 0, sizeof(SIZE));
    memset(vextent, 0, sizeof(SIZE));

    if ((mapmode = GetMapMode(hdc)) == 0) {
	/* Failed! */
	retval = 0;
    } else {
	retval = mapmode;
    }

    if (GetWindowExtEx(hdc, wextent) == FALSE) {
	/* Failed! */
	retval = 0;
    }
    if (GetViewportExtEx(hdc, vextent) == FALSE) {
	/* Failed! */
	retval = 0;
    }
    if (GetWindowOrgEx(hdc, worigin) == FALSE) {
	/* Failed! */
	retval = 0;
    }
    if (GetViewportOrgEx(hdc, vorigin) == FALSE) {
	/* Failed! */
	retval = 0;
    }

    return retval;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiNameToMode --
 *
 *	Converts Windows mapping mode names.
 *
 * Results:
 *	Mapping modes are delineated.
 *
 *----------------------------------------------------------------------
 */

static int GdiNameToMode(
    const char *name)
{
    static const struct gdimodes {
	int mode;
	const char *name;
    } modes[] = {
	{ MM_ANISOTROPIC, "MM_ANISOTROPIC" },
	{ MM_HIENGLISH,   "MM_HIENGLISH" },
	{ MM_HIMETRIC,    "MM_HIMETRIC" },
	{ MM_ISOTROPIC,   "MM_ISOTROPIC" },
	{ MM_LOENGLISH,   "MM_LOENGLISH" },
	{ MM_LOMETRIC,    "MM_LOMETRIC" },
	{ MM_TEXT,        "MM_TEXT" },
	{ MM_TWIPS,       "MM_TWIPS" }
    };

    size_t i;
    for (i=0; i < sizeof(modes) / sizeof(struct gdimodes); i++) {
	if (strcmp(modes[i].name, name) == 0) {
	    return modes[i].mode;
	}
    }
    return atoi(name);
}

/*
 *----------------------------------------------------------------------
 *
 * GdiModeToName --
 *
 *	Converts the mode number to a printable form.
 *
 * Results:
 *	Mapping numbers are delineated.
 *
 *----------------------------------------------------------------------
 */

static const char *GdiModeToName(
    int mode)
{
    static const struct gdi_modes {
	int mode;
	const char *name;
    } modes[] = {
	{ MM_ANISOTROPIC, "Anisotropic" },
	{ MM_HIENGLISH,   "1/1000 inch" },
	{ MM_HIMETRIC,    "1/100 mm" },
	{ MM_ISOTROPIC,   "Isotropic" },
	{ MM_LOENGLISH,   "1/100 inch" },
	{ MM_LOMETRIC,    "1/10 mm" },
	{ MM_TEXT,        "1 to 1" },
	{ MM_TWIPS,       "1/1440 inch" }
    };

    size_t i;
    for (i=0; i < sizeof(modes) / sizeof(struct gdi_modes); i++) {
	if (modes[i].mode == mode) {
	    return modes[i].name;
	}
    }
    return "Unknown";
}

/*
 *----------------------------------------------------------------------
 *
 * GdiMap --
 *
 *	Sets mapping mode between logical and physical device space.
 *
 * Results:
 *	Bridges map modes.
 *
 *----------------------------------------------------------------------
 */

static int GdiMap(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    static const char usage_message[] =
	"::tk::print::_gdi map hdc "
	"[-logical x[y]] [-physical x[y]] "
	"[-offset {x y} ] [-default] [-mode mode]";
    HDC hdc;
    int mapmode;	/* Mapping mode. */
    SIZE wextent;	/* Device extent. */
    SIZE vextent;	/* Viewport extent. */
    POINT worigin;	/* Device origin. */
    POINT vorigin;	/* Viewport origin. */
    int argno;

    /* Keep track of what parts of the function need to be executed. */
    int need_usage   = 0;
    int use_logical  = 0;
    int use_physical = 0;
    int use_offset   = 0;
    int use_default  = 0;
    int use_mode     = 0;

    /* Required parameter: HDC for printer. */
    if (argc < 2) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    hdc = printDC;

    if ((mapmode = GdiGetHdcInfo(hdc, &worigin, &wextent, &vorigin, &vextent)) == 0) {
	/* Failed!. */
	Tcl_AppendResult(interp, "Cannot get current HDC info", (char *)NULL);
	return TCL_ERROR;
    }

    /* Parse remaining arguments. */
    for (argno = 2; argno < argc; argno++) {
	if (strcmp(Tcl_GetString(objv[argno]), "-default") == 0) {
	    vextent.cx = vextent.cy = wextent.cx = wextent.cy = 1;
	    vorigin.x = vorigin.y = worigin.x = worigin.y = 0;
	    mapmode = MM_TEXT;
	    use_default = 1;
	} else if (strcmp(Tcl_GetString(objv[argno]), "-mode") == 0) {
	    if (argno + 1 >= argc) {
		need_usage = 1;
	    } else {
		mapmode = GdiNameToMode(Tcl_GetString(objv[argno + 1]));
		use_mode = 1;
		argno++;
	    }
	} else if (strcmp(Tcl_GetString(objv[argno]), "-offset") == 0) {
	    if (argno + 1 >= argc) {
		need_usage = 1;
	    } else {
		/* It would be nice if this parsed units as well.... */
		if (sscanf(Tcl_GetString(objv[argno + 1]), "%ld%ld",
			&vorigin.x, &vorigin.y) == 2) {
		    use_offset = 1;
		} else {
		    need_usage = 1;
		}
		argno++;
	    }
	} else if (strcmp(Tcl_GetString(objv[argno]), "-logical") == 0) {
	    if (argno + 1 >= argc) {
		need_usage = 1;
	    } else {
		int count;

		argno++;
		/* In "real-life", this should parse units as well.. */
		if ((count = sscanf(Tcl_GetString(objv[argno]), "%ld%ld",
			&wextent.cx, &wextent.cy)) != 2) {
		    if (count == 1) {
			mapmode = MM_ISOTROPIC;
			use_logical = 1;
			wextent.cy = wextent.cx;  /* Make them the same. */
		    } else {
			need_usage = 1;
		    }
		} else {
		    mapmode = MM_ANISOTROPIC;
		    use_logical = 2;
		}
	    }
	} else if (strcmp(Tcl_GetString(objv[argno]), "-physical") == 0) {
	    if (argno + 1 >= argc) {
		need_usage = 1;
	    } else {
		int count;

		argno++;
		/* In "real-life", this should parse units as well.. */
		if ((count = sscanf(Tcl_GetString(objv[argno]), "%ld%ld",
			&vextent.cx, &vextent.cy)) != 2) {
		    if (count == 1) {
			mapmode = MM_ISOTROPIC;
			use_physical = 1;
			vextent.cy = vextent.cx;  /* Make them the same. */
		    } else {
			need_usage = 1;
		    }
		} else {
		    mapmode = MM_ANISOTROPIC;
		    use_physical = 2;
		}
	    }
	}
    }

    /* Check for any impossible combinations. */
    if (use_logical != use_physical) {
	need_usage = 1;
    }
    if (use_default && (use_logical || use_offset || use_mode)) {
	need_usage = 1;
    }
    if (use_mode && use_logical &&
	    (mapmode != MM_ISOTROPIC && mapmode != MM_ANISOTROPIC)) {
	need_usage = 1;
    }

    if (need_usage) {
	Tcl_AppendResult(interp, usage_message, NULL);
	return TCL_ERROR;
    }

    /* Call Windows CTM functions. */
    if (use_logical || use_default || use_mode) { /* Don't call for offset only. */
	SetMapMode(hdc, mapmode);
    }

    if (use_offset || use_default) {
	POINT oldorg;
	SetViewportOrgEx(hdc, vorigin.x, vorigin.y, &oldorg);
	SetWindowOrgEx(hdc, worigin.x, worigin.y, &oldorg);
    }

    if (use_logical) {  /* Same as use_physical. */
	SIZE oldsiz;
	SetWindowExtEx(hdc, wextent.cx, wextent.cy, &oldsiz);
	SetViewportExtEx(hdc, vextent.cx, vextent.cy, &oldsiz);
    }

    /*
     * Since we may not have set up every parameter, get them again for the
     * report.
     */
    mapmode = GdiGetHdcInfo(hdc, &worigin, &wextent, &vorigin, &vextent);

    /*
     * Output current CTM info.
     * Note: This should really be in terms that can be used in a
     * ::tk::print::_gdi map command!
     */
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "Transform: \"(%ld, %ld) -> (%ld, %ld)\" "
	    "Origin: \"(%ld, %ld)\" "
	    "MappingMode: \"%s\"",
	    vextent.cx, vextent.cy, wextent.cx, wextent.cy,
	    vorigin.x, vorigin.y,
	    GdiModeToName(mapmode)));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiCopyBits --
 *
 *	Copies window bits from source to destination.
 *
 * Results:
 *	Copies window bits.
 *
 *----------------------------------------------------------------------
 */

static int GdiCopyBits(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int argc,
    Tcl_Obj *const *objv)
{
    /* Goal: get the Tk_Window from the top-level
     * convert it to an HWND
     * get the HDC
     * Do a bitblt to the given hdc
     * Use an optional parameter to point to an arbitrary window instead of
     * the main
     * Use optional parameters to map to the width and height required for the
     * dest.
     */
    static const char usage_message[] =
	"::tk::print::_gdi copybits hdc [-window w|-screen] [-client] "
	"[-source \"a b c d\"] "
	"[-destination \"a b c d\"] [-scale number] [-calc]";

    Tk_Window mainWin;
    Tk_Window workwin;
    Window wnd;
    HDC src;
    HDC dst;
    HWND hwnd = 0;

    HANDLE hDib;    /* Handle for device-independent bitmap. */
    LPBITMAPINFOHEADER lpDIBHdr;
    LPSTR lpBits;
    enum PrintType wintype = PTWindow;

    int hgt, wid;
    char *strend;
    long errcode;
    int k;

    /* Variables to remember what we saw in the arguments. */
    int do_window = 0;
    int do_screen = 0;
    int do_scale = 0;
    int do_print = 1;

    /* Variables to remember the values in the arguments. */
    const char *window_spec;
    double scale = 1.0;
    int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
    int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
    int is_toplevel = 0;

    /*
     * The following steps are peculiar to the top level window.
     * There is likely a clever way to do the mapping of a widget pathname to
     * the proper window, to support the idea of using a parameter for this
     * purpose.
     */
    if ((workwin = mainWin = Tk_MainWindow(interp)) == 0) {
	Tcl_AppendResult(interp, "Can't find main Tk window", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the arguments.
     */
    /* HDC is required. */
    if (argc < 2) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    dst = printDC;

    /*
     * Next, check to see if 'dst' can support BitBlt.  If not, raise an
     * error.
     */
    if ((GetDeviceCaps(dst, RASTERCAPS) & RC_BITBLT) == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Can't do bitmap operations on device context\n"));
	return TCL_ERROR;
    }

    /* Loop through the remaining arguments. */
    for (k=2; k<argc; k++) {
	if (strcmp(Tcl_GetString(objv[k]), "-window") == 0) {
	    if (Tcl_GetString(objv[k+1]) && Tcl_GetString(objv[k+1])[0] == '.') {
		do_window = 1;
		workwin = Tk_NameToWindow(interp, window_spec = Tcl_GetString(objv[++k]), mainWin);
		if (workwin == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "Can't find window %s in this application",
			    window_spec));
		    return TCL_ERROR;
		}
	    } else {
		/* Use strtoul() so octal or hex representations will be
		 * parsed. */
		hwnd = (HWND) INT2PTR(strtoul(Tcl_GetString(objv[++k]), &strend, 0));
		if (strend == 0 || strend == Tcl_GetString(objv[k])) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "Can't understand window id %s", Tcl_GetString(objv[k])));
		    return TCL_ERROR;
		}
	    }
	} else if (strcmp(Tcl_GetString(objv[k]), "-screen") == 0) {
	    do_screen = 1;
	    wintype = PTScreen;
	} else if (strcmp(Tcl_GetString(objv[k]), "-client") == 0) {
	    wintype = PTClient;
	} else if (strcmp(Tcl_GetString(objv[k]), "-source") == 0) {
	    float a, b, c, d;
	    int count = sscanf(Tcl_GetString(objv[++k]), "%f%f%f%f", &a, &b, &c, &d);

	    if (count < 2) { /* Can't make heads or tails of it.... */
		Tcl_AppendResult(interp, usage_message, (char *)NULL);
		return TCL_ERROR;
	    }
	    src_x = (int)a;
	    src_y = (int)b;
	    if (count == 4) {
		src_w = (int)c;
		src_h = (int)d;
	    }
	} else if (strcmp(Tcl_GetString(objv[k]), "-destination") == 0) {
	    float a, b, c, d;
	    int count;

	    count = sscanf(Tcl_GetString(objv[++k]), "%f%f%f%f", &a, &b, &c, &d);
	    if (count < 2) { /* Can't make heads or tails of it.... */
		Tcl_AppendResult(interp, usage_message, (char *)NULL);
		return TCL_ERROR;
	    }
	    dst_x = (int)a;
	    dst_y = (int)b;
	    if (count == 3) {
		dst_w = (int)c;
		dst_h = -1;
	    } else if (count == 4) {
		dst_w = (int)c;
		dst_h = (int)d;
	    }
	} else if (strcmp(Tcl_GetString(objv[k]), "-scale") == 0) {
	    if (Tcl_GetString(objv[++k])) {
		if (Tcl_GetDouble(interp, Tcl_GetString(objv[k]), &scale) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (scale <= 0.01 || scale >= 100.0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "Unreasonable scale specification %s", Tcl_GetString(objv[k])));
		    return TCL_ERROR;
		}
		do_scale = 1;
	    }
	} else if (strcmp(Tcl_GetString(objv[k]), "-noprint") == 0
		|| strncmp(Tcl_GetString(objv[k]), "-calc", 5) == 0) {
	    /* This option suggested by Pascal Bouvier to get sizes without
	     * printing. */
	    do_print = 0;
	}
    }

    /*
     * Check to ensure no incompatible arguments were used.
     */
    if (do_window && do_screen) {
	Tcl_AppendResult(interp, usage_message, (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Get the MS Window we want to copy.  Given the HDC, we can get the
     * "Window".
     */
    if (hwnd == 0) {
	if (Tk_IsTopLevel(workwin)) {
	    is_toplevel = 1;
	}

	if ((wnd = Tk_WindowId(workwin)) == 0) {
	    Tcl_AppendResult(interp, "Can't get id for Tk window", (char *)NULL);
	    return TCL_ERROR;
	}

	/* Given the "Window" we can get a Microsoft Windows HWND. */

	if ((hwnd = Tk_GetHWND(wnd)) == 0) {
	    Tcl_AppendResult(interp, "Can't get Windows handle for Tk window",
		    (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * If it's a toplevel, give it special treatment: Get the top-level
	 * window instead.  If the user only wanted the client, the -client
	 * flag will take care of it.  This uses "windows" tricks rather than
	 * Tk since the obvious method of getting the wrapper window didn't
	 * seem to work.
	 */
	if (is_toplevel) {
	    HWND tmpWnd = hwnd;
	    while ((tmpWnd = GetParent(tmpWnd)) != 0) {
		hwnd = tmpWnd;
	    }
	}
    }

    /* Given the HWND, we can get the window's device context. */
    if ((src = GetWindowDC(hwnd)) == 0) {
	Tcl_AppendResult(interp, "Can't get device context for Tk window", (char *)NULL);
	return TCL_ERROR;
    }

    if (do_screen) {
	LONG w, h;
	GetDisplaySize(&w, &h);
	wid = w;
	hgt = h;
    } else if (is_toplevel) {
	RECT tl;
	GetWindowRect(hwnd, &tl);
	wid = tl.right - tl.left;
	hgt = tl.bottom - tl.top;
    } else {
	if ((hgt = Tk_Height(workwin)) <= 0) {
	    Tcl_AppendResult(interp, "Can't get height of Tk window", (char *)NULL);
	    ReleaseDC(hwnd,src);
	    return TCL_ERROR;
	}

	if ((wid = Tk_Width(workwin)) <= 0) {
	    Tcl_AppendResult(interp, "Can't get width of Tk window", (char *)NULL);
	    ReleaseDC(hwnd,src);
	    return TCL_ERROR;
	}
    }

    /*
     * Ensure all the widths and heights are set up right
     * A: No dimensions are negative
     * B: No dimensions exceed the maximums
     * C: The dimensions don't lead to a 0 width or height image.
     */
    if (src_x < 0) {
	src_x = 0;
    }
    if (src_y < 0) {
	src_y = 0;
    }
    if (dst_x < 0) {
	dst_x = 0;
    }
    if (dst_y < 0) {
	dst_y = 0;
    }

    if (src_w > wid || src_w <= 0) {
	src_w = wid;
    }

    if (src_h > hgt || src_h <= 0) {
	src_h = hgt;
    }

    if (do_scale && dst_w == 0) {
	/* Calculate destination width and height based on scale. */
	dst_w = (int)(scale * src_w);
	dst_h = (int)(scale * src_h);
    }

    if (dst_h == -1) {
	dst_h = (int) (((long)src_h * dst_w) / (src_w + 1)) + 1;
    }

    if (dst_h == 0 || dst_w == 0) {
	dst_h = src_h;
	dst_w = src_w;
    }

    if (do_print) {
	/*
	 * Based on notes from Heiko Schock and Arndt Roger Schneider, create
	 * this as a DIBitmap, to allow output to a greater range of devices.
	 * This approach will also allow selection of
	 *   a) Whole screen
	 *   b) Whole window
	 *   c) Client window only
	 * for the "grab"
	 */
	hDib = CopyToDIB(hwnd, wintype);

	/* GdiFlush();. */

	if (!hDib) {
	    Tcl_AppendResult(interp, "Can't create DIB", (char *)NULL);
	    ReleaseDC(hwnd,src);
	    return TCL_ERROR;
	}

	lpDIBHdr = (LPBITMAPINFOHEADER) GlobalLock(hDib);
	if (!lpDIBHdr) {
	    Tcl_AppendResult(interp, "Can't get DIB header", (char *)NULL);
	    ReleaseDC(hwnd,src);
	    return TCL_ERROR;
	}

	lpBits = (LPSTR) lpDIBHdr + lpDIBHdr->biSize + DIBNumColors(lpDIBHdr) * sizeof(RGBQUAD);

	/* stretch the DIBbitmap directly in the target device. */

	if (StretchDIBits(dst,
		dst_x, dst_y, dst_w, dst_h,
		src_x, src_y, src_w, src_h,
		lpBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS,
		SRCCOPY) == (int)GDI_ERROR) {
	    errcode = GetLastError();
	    GlobalUnlock(hDib);
	    GlobalFree(hDib);
	    ReleaseDC(hwnd,src);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "StretchDIBits failed with code %ld", errcode));
	    return TCL_ERROR;
	}

	/* free allocated memory. */
	GlobalUnlock(hDib);
	GlobalFree(hDib);
    }

    ReleaseDC(hwnd,src);

    /*
     * The return value should relate to the size in the destination space.
     * At least the height should be returned (for page layout purposes).
     */
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "%d %d %d %d", dst_x, dst_y, dst_w, dst_h));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DIBNumColors --
 *
 *	Computes the number of colors required for a DIB palette.
 *
 * Results:
 *	Returns number of colors.

 *
 *----------------------------------------------------------------------
 */

static int DIBNumColors(
    LPBITMAPINFOHEADER lpDIB)
{
    WORD wBitCount;	/* DIB bit count. */
    DWORD dwClrUsed;

    /*
     * If this is a Windows-style DIB, the number of colors in the color table
     * can be less than the number of bits per pixel allows for (i.e.
     * lpbi->biClrUsed can be set to some value).  If this is the case, return
     * the appropriate value..
     */

    dwClrUsed = lpDIB->biClrUsed;
    if (dwClrUsed) {
	return (WORD) dwClrUsed;
    }

    /*
     * Calculate the number of colors in the color table based on.
     * The number of bits per pixel for the DIB.
     */

    wBitCount = lpDIB->biBitCount;

    /* Return number of colors based on bits per pixel. */

    switch (wBitCount) {
    case 1:
	return 2;
    case 4:
	return 16;
    case 8:
	return 256;
    default:
	return 0;
    }
}

/*
 * Helper functions
 */

/*
 * ParseFontWords converts various keywords to modifyers of a
 * font specification.
 * For all words, later occurrences override earlier occurrences.
 * Overstrike and underline cannot be "undone" by other words
 */

/*
 *----------------------------------------------------------------------
 *
 * GdiParseFontWords --
 *
 *	Converts various keywords to modifiers of a font specification.  For
 *	all words, later occurrences override earlier occurrences.  Overstrike
 *	and underline cannot be "undone" by other words
 *
 * Results:
 *	 Keywords converted to modifiers.
 *
 *----------------------------------------------------------------------
 */

static int GdiParseFontWords(
    TCL_UNUSED(Tcl_Interp *),
    LOGFONTW *lf,
    const char *str[],
    int numargs)
{
    int i;
    int retval = 0; /* Number of words that could not be parsed. */

    for (i=0; i<numargs; i++) {
	if (str[i]) {
	    int wt;
	    if ((wt = GdiWordToWeight(str[i])) != -1) {
		lf->lfWeight = wt;
	    } else if (strcmp(str[i], "roman") == 0) {
		lf->lfItalic = FALSE;
	    } else if (strcmp(str[i], "italic") == 0) {
		lf->lfItalic = TRUE;
	    } else if (strcmp(str[i], "underline") == 0) {
		lf->lfUnderline = TRUE;
	    } else if (strcmp(str[i], "overstrike") == 0) {
		lf->lfStrikeOut = TRUE;
	    } else {
		retval++;
	    }
	}
    }
    return retval;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiWordToWeight --
 *
 *	Converts keywords to font weights.
 *
 * Results:
 *	Helps set the proper font for GDI rendering.
 *
 *----------------------------------------------------------------------
 */

static int GdiWordToWeight(
    const char *str)
{
    int retval = -1;
    size_t i;
    static const struct font_weight {
	const char *name;
	int weight;
    } font_weights[] = {
	{ "thin", FW_THIN },
	{ "extralight", FW_EXTRALIGHT },
	{ "ultralight", FW_EXTRALIGHT },
	{ "light", FW_LIGHT },
	{ "normal", FW_NORMAL },
	{ "regular", FW_NORMAL },
	{ "medium", FW_MEDIUM },
	{ "semibold", FW_SEMIBOLD },
	{ "demibold", FW_SEMIBOLD },
	{ "bold", FW_BOLD },
	{ "extrabold", FW_EXTRABOLD },
	{ "ultrabold", FW_EXTRABOLD },
	{ "heavy", FW_HEAVY },
	{ "black", FW_HEAVY },
    };

    if (str == 0) {
	return -1;
    }

    for (i=0; i<sizeof(font_weights) / sizeof(struct font_weight); i++) {
	if (strcmp(str, font_weights[i].name) == 0) {
	    retval = font_weights[i].weight;
	    break;
	}
    }

    return retval;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeLogFont --
 *
 *	Takes the font description string and converts this into a logical
 *	font spec.
 *
 * Results:
 *	 Sets font weight.
 *
 *----------------------------------------------------------------------
 */

static int GdiMakeLogFont(
    Tcl_Interp *interp,
    const char *str,
    LOGFONTW *lf,
    HDC hDC)
{
    const char **list;
    Tcl_Size count;

    /* Set up defaults for logical font. */
    memset(lf, 0, sizeof(*lf));
    lf->lfWeight  = FW_NORMAL;
    lf->lfCharSet = DEFAULT_CHARSET;
    lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
    lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lf->lfQuality = DEFAULT_QUALITY;
    lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;

    /* The cast to (char *) is silly, based on prototype of Tcl_SplitList. */
    if (Tcl_SplitList(interp, str, &count, &list) != TCL_OK) {
	return 0;
    }

    /* Now we have the font structure broken into name, size, weight. */
    if (count >= 1) {
	Tcl_DString ds;

	Tcl_DStringInit(&ds);
	wcsncpy(lf->lfFaceName, Tcl_UtfToWCharDString(list[0], TCL_INDEX_NONE, &ds),
		LF_FACESIZE-1);
	Tcl_DStringFree(&ds);
	lf->lfFaceName[LF_FACESIZE-1] = 0;
    } else {
	return 0;
    }

    if (count >= 2) {
	int siz;
	char *strend;
	siz = strtol(list[1], &strend, 0);

	/*
	 * Assumptions:
	 * 1) Like canvas, if a positive number is specified, it's in points.
	 * 2) Like canvas, if a negative number is specified, it's in pixels.
	 */
	if (strend > list[1]) { /* If it looks like a number, it is a number.... */
	    if (siz > 0) {  /* Size is in points. */
		SIZE wextent, vextent;
		POINT worigin, vorigin;
		double factor;

		switch (GdiGetHdcInfo(hDC, &worigin, &wextent, &vorigin, &vextent)) {
		case MM_ISOTROPIC:
		    if (vextent.cy < -1 || vextent.cy > 1) {
			factor = (double)wextent.cy / vextent.cy;
			if (factor < 0.0) {
			    factor = -factor;
			}
			lf->lfHeight = (int)(-siz * GetDeviceCaps(hDC, LOGPIXELSY) * factor / 72.0);
		    } else if (vextent.cx < -1 || vextent.cx > 1) {
			factor = (double)wextent.cx / vextent.cx;
			if (factor < 0.0) {
			    factor = -factor;
			}
			lf->lfHeight = (int)(-siz * GetDeviceCaps(hDC, LOGPIXELSY) * factor / 72.0);
		    } else {
			lf->lfHeight = -siz; /* This is bad news.... */
		    }
		    break;
		case MM_ANISOTROPIC:
		    if (vextent.cy != 0) {
			factor = (double)wextent.cy / vextent.cy;
			if (factor < 0.0) {
			    factor = -factor;
			}
			lf->lfHeight = (int)(-siz * GetDeviceCaps(hDC, LOGPIXELSY) * factor / 72.0);
		    } else {
			lf->lfHeight = -siz; /* This is bad news.... */
		    }
		    break;
		case MM_TEXT:
		default:
		    /* If mapping mode is MM_TEXT, use the documented
		     * formula. */
		    lf->lfHeight = -MulDiv(siz, GetDeviceCaps(hDC, LOGPIXELSY), 72);
		    break;
		case MM_HIENGLISH:
		    lf->lfHeight = -MulDiv(siz, 1000, 72);
		    break;
		case MM_LOENGLISH:
		    lf->lfHeight = -MulDiv(siz, 100, 72);
		    break;
		case MM_HIMETRIC:
		    lf->lfHeight = -MulDiv(siz, (int)(1000*2.54), 72);
		    break;
		case MM_LOMETRIC:
		    lf->lfHeight = -MulDiv(siz, (int)(100*2.54), 72);
		    break;
		case MM_TWIPS:
		    lf->lfHeight = -MulDiv(siz, 1440, 72);
		    break;
		}
	    } else if (siz == 0) {   /* Use default size of 12 points. */
		lf->lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
	    } else {                 /* Use pixel size. */
		lf->lfHeight = siz;  /* Leave this negative. */
	    }
	} else {
	    GdiParseFontWords(interp, lf, list+1, count-1);
	}
    }

    if (count >= 3) {
	GdiParseFontWords(interp, lf, list+2, count-2);
    }

    ckfree(list);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiMakePen --
 *
 *	Creates a logical pen based on input parameters and selects it into
 *	the hDC.
 *
 * Results:
 *	Sets rendering pen.
 *
 *----------------------------------------------------------------------
 */

static int GdiMakePen(
    Tcl_Interp *interp,
    int width,
    int dashstyle,
    const char *dashstyledata,
    TCL_UNUSED(int),		/* Ignored for now. */
    TCL_UNUSED(int),		/* Ignored for now. */
    TCL_UNUSED(int),
    TCL_UNUSED(const char *),	/* Ignored for now. */
    unsigned long color,
    HDC hDC,
    HGDIOBJ *oldPen)
{
    /*
     * The LOGPEN structure takes the following dash options:
     * PS_SOLID: a solid pen
     * PS_DASH:  a dashed pen
     * PS_DOT:   a dotted pen
     * PS_DASHDOT: a pen with a dash followed by a dot
     * PS_DASHDOTDOT: a pen with a dash followed by 2 dots
     *
     * It seems that converting to ExtCreatePen may be more advantageous, as
     * it matches the Tk canvas pens much better--but not for Win95, which
     * does not support PS_USERSTYLE. An explicit test (or storage in a static
     * after first failure) may suffice for working around this. The
     * ExtCreatePen is not supported at all under Win32.
     */

    HPEN hPen;
    LOGBRUSH lBrush;
    DWORD pStyle = PS_SOLID;           /* -dash should override*/
    DWORD endStyle = PS_ENDCAP_ROUND;  /* -capstyle should override. */
    DWORD joinStyle = PS_JOIN_ROUND;   /* -joinstyle should override. */
    DWORD styleCount = 0;
    DWORD *styleArray = 0;

    /*
     * To limit the propagation of allocated memory, the dashes will have a
     * maximum here.  If one wishes to remove the static allocation, please be
     * sure to update GdiFreePen and ensure that the array is NOT freed if the
     * LOGPEN option is used.
     */
    static DWORD pStyleData[24];
    if (dashstyle != 0 && dashstyledata != 0) {
	const char *cp;
	size_t i;
	char *dup = (char *) ckalloc(strlen(dashstyledata) + 1);
	strcpy(dup, dashstyledata);
	/* DEBUG. */
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"DEBUG: Found a dash spec of |%s|\n",
		dashstyledata));

	/* Parse the dash spec. */
	if (isdigit(dashstyledata[0])) {
	    cp = strtok(dup, " \t,;");
	    for (i = 0; cp && i < sizeof(pStyleData) / sizeof(DWORD); i++) {
		pStyleData[styleCount++] = atoi(cp);
		cp = strtok(NULL, " \t,;");
	    }
	} else {
	    for (i=0; dashstyledata[i] != '\0' && i< sizeof(pStyleData) / sizeof(DWORD); i++) {
		switch (dashstyledata[i]) {
		case ' ':
		    pStyleData[styleCount++] = 8;
		    break;
		case ',':
		    pStyleData[styleCount++] = 4;
		    break;
		case '_':
		    pStyleData[styleCount++] = 6;
		    break;
		case '-':
		    pStyleData[styleCount++] = 4;
		    break;
		case '.':
		    pStyleData[styleCount++] = 2;
		    break;
		default:
		    break;
		}
	    }
	}
	if (styleCount > 0) {
	    styleArray = pStyleData;
	} else {
	    dashstyle = 0;
	}
	if (dup) {
	    ckfree(dup);
	}
    }

    if (dashstyle != 0) {
	pStyle = PS_USERSTYLE;
    }

    /* -stipple could affect this.... */
    lBrush.lbStyle = BS_SOLID;
    lBrush.lbColor = color;
    lBrush.lbHatch = 0;

    /* We only use geometric pens, even for 1-pixel drawing. */
    hPen = ExtCreatePen(PS_GEOMETRIC|pStyle|endStyle|joinStyle,
	    width, &lBrush, styleCount, styleArray);

    if (hPen == 0) { /* Failed for some reason...Fall back on CreatePenIndirect. */
	LOGPEN lf;
	lf.lopnWidth.x = width;
	lf.lopnWidth.y = 0;		/* Unused in LOGPEN. */
	if (dashstyle == 0) {
	    lf.lopnStyle = PS_SOLID;	/* For now...convert 'style' in the future. */
	} else {
	    lf.lopnStyle = PS_DASH;	/* REALLLLY simple for now. */
	}
	lf.lopnColor = color;		/* Assume we're getting a COLORREF. */
	/* Now we have a logical pen. Create the "real" pen and put it in the
	 * hDC. */
	hPen = CreatePenIndirect(&lf);
    }

    *oldPen = SelectObject(hDC, hPen);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiFreePen --
 *
 *	Wraps the protocol to delete a created pen.
 *
 * Results:
 *	Deletes pen.
 *
 *----------------------------------------------------------------------
 */

static int GdiFreePen(
    TCL_UNUSED(Tcl_Interp *),
    HDC hDC,
    HGDIOBJ oldPen)
{
    HGDIOBJ gonePen = SelectObject(hDC, oldPen);

    DeleteObject(gonePen);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiMakeBrush--
 *
 *	Creates a logical brush based on input parameters, and selects it into
 *	the hdc.
 *
 * Results:
 *	 Creates brush.
 *
 *----------------------------------------------------------------------
 */

static int GdiMakeBrush(
    unsigned long color,
    long hatch,
    LOGBRUSH *lb,
    HDC hDC,
	HBRUSH *oldBrush)
{
    HBRUSH hBrush;
    lb->lbStyle = BS_SOLID; /* Support other styles later. */
    lb->lbColor = color;    /* Assume this is a COLORREF. */
    lb->lbHatch = hatch;    /* Ignored for now, given BS_SOLID in the Style. */

    /* Now we have the logical brush. Create the "real" brush and put it in
     * the hDC. */
    hBrush = CreateBrushIndirect(lb);
    *oldBrush = (HBRUSH)SelectObject(hDC, hBrush);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GdiFreeBrush --
 *
 *	Wraps the protocol to delete a created brush.
 *
 * Results:
 *	 Deletes brush.
 *
 *----------------------------------------------------------------------
 */
static void GdiFreeBrush(
    TCL_UNUSED(Tcl_Interp *),
    HDC hDC,
    HGDIOBJ oldBrush)
{
    HGDIOBJ goneBrush;

    goneBrush = SelectObject(hDC, oldBrush);
    DeleteObject(goneBrush);
}

/*
 * Utility functions from elsewhere in Tcl.
 * Functions have removed reliance on X and Tk libraries, as well as removing
 * the need for TkWindows.
 * GdiGetColor is a copy of a TkpGetColor from tkWinColor.c
 */
typedef struct {
    const char *name;
    int index;
} SystemColorEntry;

static const SystemColorEntry sysColors[] = {
    {"3dDarkShadow",		COLOR_3DDKSHADOW},
    {"3dLight",			COLOR_3DLIGHT},
    {"ActiveBorder",		COLOR_ACTIVEBORDER},
    {"ActiveCaption",		COLOR_ACTIVECAPTION},
    {"AppWorkspace",		COLOR_APPWORKSPACE},
    {"Background",		COLOR_BACKGROUND},
    {"ButtonFace",		COLOR_BTNFACE},
    {"ButtonHighlight",		COLOR_BTNHIGHLIGHT},
    {"ButtonShadow",		COLOR_BTNSHADOW},
    {"ButtonText",		COLOR_BTNTEXT},
    {"CaptionText",		COLOR_CAPTIONTEXT},
    {"DisabledText",		COLOR_GRAYTEXT},
    {"GrayText",		COLOR_GRAYTEXT},
    {"Highlight",		COLOR_HIGHLIGHT},
    {"HighlightText",		COLOR_HIGHLIGHTTEXT},
    {"InactiveBorder",		COLOR_INACTIVEBORDER},
    {"InactiveCaption",		COLOR_INACTIVECAPTION},
    {"InactiveCaptionText",	COLOR_INACTIVECAPTIONTEXT},
    {"InfoBackground",		COLOR_INFOBK},
    {"InfoText",		COLOR_INFOTEXT},
    {"Menu",			COLOR_MENU},
    {"MenuText",		COLOR_MENUTEXT},
    {"Scrollbar",		COLOR_SCROLLBAR},
    {"Window",			COLOR_WINDOW},
    {"WindowFrame",		COLOR_WINDOWFRAME},
    {"WindowText",		COLOR_WINDOWTEXT}
};

static const size_t numsyscolors = sizeof(sysColors) / sizeof(SystemColorEntry);

/*
 *----------------------------------------------------------------------
 *
 * GdiGetColor --
 *
 *	Convert color name to color specification.
 *
 * Results:
 *	 Color name converted.
 *
 *----------------------------------------------------------------------
 */

static int GdiGetColor(
    Tcl_Obj *nameObj,
    COLORREF *color)
{
    const char *name = Tcl_GetString(nameObj);

    if (_strnicmp(name, "system", 6) == 0) {
	size_t i, l, u;
	int r;

	l = 0;
	u = numsyscolors;
	while (l <= u) {
	    i = (l + u) / 2;
	    if ((r = _strcmpi(name+6, sysColors[i].name)) == 0) {
		break;
	    }
	    if (r < 0) {
		u = i - 1;
	    } else {
		l = i + 1;
	    }
	}
	if (l > u) {
	    return 0;
	}
	*color = GetSysColor(sysColors[i].index);
	return 1;
    } else {
    int result;
    XColor xcolor;
	result = XParseColor(NULL, 0, name, &xcolor);
	*color = ((xcolor.red & 0xFF00)>>8) | (xcolor.green & 0xFF00)
		| ((xcolor.blue & 0xFF00)<<8);
    return result;
    }
}

/*
 * Beginning of functions for screen-to-dib translations.
 *
 * Several of these functions are based on those in the WINCAP32 program
 * provided as a sample by Microsoft on the VC++ 5.0 disk. The copyright on
 * these functions is retained, even for those with significant changes.
 */

/*
 *----------------------------------------------------------------------
 *
 * CopyToDIB --
 *
 *	Copy window bits to a DIB.
 *
 * Results:
 *	 Color specification converted.
 *
 *----------------------------------------------------------------------
 */

static HANDLE CopyToDIB(
    HWND hWnd,
    enum PrintType type)
{
    HANDLE hDIB;
    HBITMAP hBitmap;
    HPALETTE hPalette;

    /* Check for a valid window handle. */

    if (!hWnd) {
        return NULL;
    }

    switch (type) {
    case PTWindow: {	/* Copy entire window. */
	RECT rectWnd;

	/* Get the window rectangle. */

	GetWindowRect(hWnd, &rectWnd);

	/*
	 * Get the DIB of the window by calling CopyScreenToDIB and passing it
	 * the window rect.
	 */

	hDIB = CopyScreenToDIB(&rectWnd);
	break;
    }

    case PTClient: {	/* Copy client area. */
	RECT rectClient;
	POINT pt1, pt2;

	/* Get the client area dimensions. */

	GetClientRect(hWnd, &rectClient);

	/* Convert client coords to screen coords. */

	pt1.x = rectClient.left;
	pt1.y = rectClient.top;
	pt2.x = rectClient.right;
	pt2.y = rectClient.bottom;
	ClientToScreen(hWnd, &pt1);
	ClientToScreen(hWnd, &pt2);
	rectClient.left = pt1.x;
	rectClient.top = pt1.y;
	rectClient.right = pt2.x;
	rectClient.bottom = pt2.y;

	/*
	 * Get the DIB of the client area by calling CopyScreenToDIB and
	 * passing it the client rect.
	 */

	hDIB = CopyScreenToDIB(&rectClient);
	break;
    }

    case PTScreen: { /* Entire screen. */
	RECT Rect;

	/*
	 * Get the device-dependent bitmap in lpRect by calling
	 * CopyScreenToBitmap and passing it the rectangle to grab.
	 */
	Rect.top = Rect.left = 0;
	GetDisplaySize(&Rect.right, &Rect.bottom);

	hBitmap = CopyScreenToBitmap(&Rect);

	/* Check for a valid bitmap handle. */

	if (!hBitmap) {
	    return NULL;
	}

	/* Get the current palette. */

	hPalette = GetSystemPalette();

	/* Convert the bitmap to a DIB. */

	hDIB = BitmapToDIB(hBitmap, hPalette);

	/* Clean up. */

	DeleteObject(hPalette);
	DeleteObject(hBitmap);

	/* Return handle to the packed-DIB. */
	break;
    }
    default:	/* Invalid print area. */
	return NULL;
    }

    /* Return the handle to the DIB. */
    return hDIB;
}

/*
 *----------------------------------------------------------------------
 *
 * GetDisplaySize--
 *
 *	GetDisplaySize does just that.  There may be an easier way, but it is
 *	not apparent.
 *
 * Results:
 *	Returns display size.
 *
 *----------------------------------------------------------------------
 */

static void GetDisplaySize(
    LONG *width,
    LONG *height)
{
    HDC hDC;

    hDC = CreateDCW(L"DISPLAY", 0, 0, 0);
    *width = GetDeviceCaps(hDC, HORZRES);
    *height = GetDeviceCaps(hDC, VERTRES);
    DeleteDC(hDC);
}

/*
 *----------------------------------------------------------------------
 *
 * CopyScreenToBitmap--
 *
 *	Copies screen to bitmap.
 *
 * Results:
 *	Screen is copied.
 *
 *----------------------------------------------------------------------
 */

static HBITMAP CopyScreenToBitmap(
    LPRECT lpRect)
{
    HDC     hScrDC, hMemDC;	/* Screen DC and memory DC. */
    HGDIOBJ hBitmap, hOldBitmap; /* Handles to deice-dependent bitmaps. */
    int     nX, nY, nX2, nY2;	/* Coordinates of rectangle to grab. */
    int     nWidth, nHeight;	/* DIB width and height */
    int     xScrn, yScrn;	/* Screen resolution. */

    /* Check for an empty rectangle. */

    if (IsRectEmpty(lpRect)) {
	return NULL;
    }

    /*
     * Create a DC for the screen and create a memory DC compatible to screen
     * DC.
     */

    hScrDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
    hMemDC = CreateCompatibleDC(hScrDC);

    /* Get points of rectangle to grab. */

    nX = lpRect->left;
    nY = lpRect->top;
    nX2 = lpRect->right;
    nY2 = lpRect->bottom;

    /* Get screen resolution. */

    xScrn = GetDeviceCaps(hScrDC, HORZRES);
    yScrn = GetDeviceCaps(hScrDC, VERTRES);

    /* Make sure bitmap rectangle is visible. */

    if (nX < 0) {
        nX = 0;
    }
    if (nY < 0) {
        nY = 0;
    }
    if (nX2 > xScrn) {
        nX2 = xScrn;
    }
    if (nY2 > yScrn) {
        nY2 = yScrn;
    }

    nWidth = nX2 - nX;
    nHeight = nY2 - nY;

    /* Create a bitmap compatible with the screen DC. */
    hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);

    /* Select new bitmap into memory DC. */
    hOldBitmap = SelectObject(hMemDC, hBitmap);

    /* Bitblt screen DC to memory DC. */
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);

    /*
     * Select old bitmap back into memory DC and get handle to bitmap of the
     * screen.
     */

    hBitmap = SelectObject(hMemDC, hOldBitmap);

    /* Clean up. */

    DeleteDC(hScrDC);
    DeleteDC(hMemDC);

    /* Return handle to the bitmap. */

    return (HBITMAP)hBitmap;
}

/*
 *----------------------------------------------------------------------
 *
 * BitmapToDIB--
 *
 *	Converts bitmap to DIB.
 *
 * Results:
 *	Bitmap converted.
 *
 *----------------------------------------------------------------------
 */

static HANDLE BitmapToDIB(
    HBITMAP hBitmap,
    HPALETTE hPal)
{
    BITMAP              bm;
    BITMAPINFOHEADER    bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD               dwLen;
    HANDLE              hDIB;
    HANDLE              h;
    HDC                 hDC;
    WORD                biBits;

    /* Check if bitmap handle is valid. */

    if (!hBitmap) {
        return NULL;
    }

    /* Fill in BITMAP structure, return NULL if it didn't work. */

    if (!GetObjectW(hBitmap, sizeof(bm), (LPWSTR)&bm)) {
        return NULL;
    }

    /* Ff no palette is specified, use default palette. */

    if (hPal == NULL) {
        hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
    }

    /* Calculate bits per pixel. */

    biBits = bm.bmPlanes * bm.bmBitsPixel;

    /* Make sure bits per pixel is valid. */

    if (biBits <= 1) {
        biBits = 1;
    } else if (biBits <= 4) {
        biBits = 4;
    } else if (biBits <= 8) {
        biBits = 8;
    } else { /* If greater than 8-bit, force to 24-bit. */
        biBits = 24;
    }

    /* Initialize BITMAPINFOHEADER. */

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight = bm.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = biBits;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    /* Calculate size of memory block required to store BITMAPINFO. */

    dwLen = bi.biSize + DIBNumColors(&bi) * sizeof(RGBQUAD);

    /* Get a DC. */

    hDC = GetDC(NULL);

    /* Select and realize our palette. */

    hPal = SelectPalette(hDC, hPal, FALSE);
    RealizePalette(hDC);

    /* Alloc memory block to store our bitmap. */

    hDIB = GlobalAlloc(GHND, dwLen);

    /* If we couldn't get memory block. */

    if (!hDIB) {
	/* clean up and return NULL. */

	SelectPalette(hDC, hPal, TRUE);
	RealizePalette(hDC);
	ReleaseDC(NULL, hDC);
	return NULL;
    }

    /* Lock memory and get pointer to it. */

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

    /* Use our bitmap info. to fill BITMAPINFOHEADER. */

    *lpbi = bi;

    /* Call GetDIBits with a NULL lpBits param, so it will calculate the
     * biSizeImage field for us
     */

    GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi,
	    DIB_RGB_COLORS);

    /* get the info. returned by GetDIBits and unlock memory block. */

    bi = *lpbi;
    GlobalUnlock(hDIB);

    /* If the driver did not fill in the biSizeImage field, make one up. */
    if (bi.biSizeImage == 0) {
        bi.biSizeImage = (((((DWORD)bm.bmWidth * biBits) + 31) / 32) * 4)
		* bm.bmHeight;
    }

    /* Realloc the buffer big enough to hold all the bits. */

    dwLen = bi.biSize + DIBNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;

    if ((h = GlobalReAlloc(hDIB, dwLen, 0)) != 0) {
        hDIB = h;
    } else {
	/* Clean up and return NULL. */

	GlobalFree(hDIB);
	SelectPalette(hDC, hPal, TRUE);
	RealizePalette(hDC);
	ReleaseDC(NULL, hDC);
	return NULL;
    }

    /* Lock memory block and get pointer to it. */

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

    /* Call GetDIBits with a NON-NULL lpBits param, and actualy get the
     * bits this time.
     */

    if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi +
	    (WORD)lpbi->biSize + DIBNumColors(lpbi) * sizeof(RGBQUAD),
	    (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0) {
	/* Clean up and return NULL. */

	GlobalUnlock(hDIB);
	SelectPalette(hDC, hPal, TRUE);
	RealizePalette(hDC);
	ReleaseDC(NULL, hDC);
	return NULL;
    }

    bi = *lpbi;

    /* Clean up. */
    GlobalUnlock(hDIB);
    SelectPalette(hDC, hPal, TRUE);
    RealizePalette(hDC);
    ReleaseDC(NULL, hDC);

    /* Return handle to the DIB. */
    return hDIB;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyScreenToDIB--
 *
 *	Copies screen to DIB.
 *
 * Results:
 *	Screen copied.
 *
 *----------------------------------------------------------------------
 */

static HANDLE CopyScreenToDIB(
    LPRECT lpRect)
{
    HBITMAP     hBitmap;
    HPALETTE    hPalette;
    HANDLE      hDIB;

    /*
     * Get the device-dependent bitmap in lpRect by calling CopyScreenToBitmap
     * and passing it the rectangle to grab.
     */

    hBitmap = CopyScreenToBitmap(lpRect);

    /* Check for a valid bitmap handle. */

    if (!hBitmap) {
	return NULL;
    }

    /* Get the current palette. */

    hPalette = GetSystemPalette();

    /* convert the bitmap to a DIB. */

    hDIB = BitmapToDIB(hBitmap, hPalette);

    /* Clean up. */

    DeleteObject(hPalette);
    DeleteObject(hBitmap);

    /* Return handle to the packed-DIB. */
    return hDIB;
}

/*
 *----------------------------------------------------------------------
 *
 * GetSystemPalette--
 *
 *	Obtains the system palette.
 *
 * Results:
 *	Returns palette.
 *
 *----------------------------------------------------------------------
 */

static HPALETTE GetSystemPalette(void)
{
    HDC hDC;                /* Handle to a DC. */
    static HPALETTE hPal = NULL;   /* Handle to a palette. */
    HANDLE hLogPal;         /* Handle to a logical palette. */
    LPLOGPALETTE lpLogPal;  /* Pointer to a logical palette. */
    int nColors;            /* Number of colors. */

    /* Find out how many palette entries we want.. */

    hDC = GetDC(NULL);
    if (!hDC) {
        return NULL;
    }

    nColors = PalEntriesOnDevice(hDC);   /* Number of palette entries. */

    /* Allocate room for the palette and lock it.. */

    hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + nColors *
	    sizeof(PALETTEENTRY));
    if (!hLogPal) {
	/* If we didn't get a logical palette, return NULL. */

        return NULL;
    }

    /* get a pointer to the logical palette. */

    lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal);

    /* Set some important fields. */

    lpLogPal->palVersion = 0x300;
    lpLogPal->palNumEntries = nColors;

    /* Copy the current system palette into our logical palette. */

    GetSystemPaletteEntries(hDC, 0, nColors,
	    (LPPALETTEENTRY) lpLogPal->palPalEntry);

    /*
     * Go ahead and create the palette.  Once it's created, we no longer need
     * the LOGPALETTE, so free it.
     */

    hPal = CreatePalette(lpLogPal);

    /* Clean up. */

    GlobalUnlock(hLogPal);
    GlobalFree(hLogPal);
    ReleaseDC(NULL, hDC);

    return hPal;
}

/*
 *----------------------------------------------------------------------
 *
 * PalEntriesOnDevice--
 *
 *	Returns the palettes on the device.
 *
 * Results:
 *	Returns palettes.
 *
 *----------------------------------------------------------------------
 */

static int PalEntriesOnDevice(
    HDC hDC)
{
    return (1 << (GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES)));
}

/*
 * --------------------------------------------------------------------------
 *
 * Winprint_Init--
 *
 *	Initializes printing module on Windows.
 *
 * Results:
 *	Module initialized.
 *
 * -------------------------------------------------------------------------
 */

int Winprint_Init(
    Tcl_Interp * interp)
{
    size_t i;
    Tcl_Namespace *namespacePtr;
    static const char *gdiName = "::tk::print::_gdi";
    static const size_t numCommands =
	    sizeof(gdi_commands) / sizeof(struct gdi_command);

    /*
     * Set up the low-level [_gdi] command.
     */

    namespacePtr = Tcl_CreateNamespace(interp, gdiName,
	    NULL, (Tcl_NamespaceDeleteProc *) NULL);
    for (i=0; i<numCommands; i++) {
	char buffer[100];

	snprintf(buffer, sizeof(buffer), "%s::%s", gdiName, gdi_commands[i].command_string);
	Tcl_CreateObjCommand(interp, buffer, gdi_commands[i].command,
		NULL, (Tcl_CmdDeleteProc *) 0);
	Tcl_Export(interp, namespacePtr, gdi_commands[i].command_string, 0);
    }
    Tcl_CreateEnsemble(interp, gdiName, namespacePtr, 0);

    /*
     * The other printing-related commands.
     */

    Tcl_CreateObjCommand(interp, "::tk::print::_selectprinter",
	    PrintSelectPrinter, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_openprinter",
	    PrintOpenPrinter, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_closeprinter",
	    PrintClosePrinter, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_opendoc",
	    PrintOpenDoc, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_closedoc",
	    PrintCloseDoc, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_openpage",
	    PrintOpenPage, NULL, NULL);
    Tcl_CreateObjCommand(interp, "::tk::print::_closepage",
	    PrintClosePage, NULL, NULL);
    return TCL_OK;
}

/* Print API functions. */

/*----------------------------------------------------------------------
 *
 * PrintSelectPrinter--
 *
 *	Main dialog for selecting printer and initializing data for print job.
 *
 * Results:
 *	Printer selected.
 *
 *----------------------------------------------------------------------
 */

static int PrintSelectPrinter(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj* const*))
{
    LPCWSTR printerName = NULL;
    PDEVMODEW returnedDevmode = NULL;
    PDEVMODEW localDevmode = NULL;

    copies = 0;
    paper_width = 0;
    paper_height = 0;
    dpi_x = 0;
    dpi_y = 0;

    /* Set up print dialog and initalize property structure. */

    memset(&pd, 0, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.hwndOwner = GetDesktopWindow();
    pd.Flags = PD_HIDEPRINTTOFILE | PD_DISABLEPRINTTOFILE | PD_NOSELECTION;

    if (PrintDlgW(&pd) == TRUE) {

	/*Get document info.*/
	memset(&di, 0, sizeof(di));
	di.cbSize = sizeof(di);
	di.lpszDocName = L"Tk Print Output";

	/* Copy print attributes to local structure. */
	returnedDevmode = (PDEVMODEW) GlobalLock(pd.hDevMode);
	devnames = (LPDEVNAMES) GlobalLock(pd.hDevNames);
	printerName = (LPCWSTR) devnames + devnames->wDeviceOffset;
	localDevmode = (LPDEVMODEW) HeapAlloc(GetProcessHeap(),
		HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
		returnedDevmode->dmSize);

	if (localDevmode != NULL) {
	    memcpy((LPVOID)localDevmode, (LPVOID)returnedDevmode,
		    returnedDevmode->dmSize);

	    /* Get values from user-set and built-in properties. */
	    localPrinterName = localDevmode->dmDeviceName;
	    dpi_y = localDevmode->dmYResolution;
	    dpi_x = localDevmode->dmPrintQuality;
	    /* Convert height and width to logical points. */
	    paper_height = (int) localDevmode->dmPaperLength / 0.254;
	    paper_width = (int) localDevmode->dmPaperWidth / 0.254;
	    copies = pd.nCopies;
	    /* Set device context here for all GDI printing operations. */
	    printDC = CreateDCW(L"WINSPOOL", printerName, NULL, localDevmode);
	} else {
	    localDevmode = NULL;
	}
    }

    if (pd.hDevMode != NULL) {
	GlobalFree(pd.hDevMode);
    }

    /*
     * Store print properties and link variables so they can be accessed from
     * script level.
     */
    if (localPrinterName != NULL) {
        char* varlink1 = (char*)ckalloc(100 * sizeof(char));
        char** varlink2 = (char**)ckalloc(sizeof(char*));
        *varlink2 = varlink1;
        WideCharToMultiByte(CP_UTF8, 0, localPrinterName, -1, varlink1, 0, NULL, NULL);

        Tcl_LinkVar(interp, "::tk::print::printer_name", varlink2,
            TCL_LINK_STRING | TCL_LINK_READ_ONLY);
        Tcl_LinkVar(interp, "::tk::print::copies", &copies,
            TCL_LINK_INT | TCL_LINK_READ_ONLY);
        Tcl_LinkVar(interp, "::tk::print::dpi_x", &dpi_x,
            TCL_LINK_INT | TCL_LINK_READ_ONLY);
        Tcl_LinkVar(interp, "::tk::print::dpi_y", &dpi_y,
            TCL_LINK_INT | TCL_LINK_READ_ONLY);
        Tcl_LinkVar(interp, "::tk::print::paper_width", &paper_width,
            TCL_LINK_INT | TCL_LINK_READ_ONLY);
        Tcl_LinkVar(interp, "::tk::print::paper_height", &paper_height,
            TCL_LINK_INT | TCL_LINK_READ_ONLY);
    }

    return TCL_OK;
}

/*
 * --------------------------------------------------------------------------
 *
 * PrintOpenPrinter--
 *
 *	Open the given printer.
 *
 * Results:
 *	Opens the selected printer.
 *
 * -------------------------------------------------------------------------
 */

int PrintOpenPrinter(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_DString ds;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "printer");
	return TCL_ERROR;
    }

    /*Start an individual page.*/
    if (StartPage(printDC) <= 0) {
	return TCL_ERROR;
    }

    const char *printer = Tcl_GetString(objv[1]);

    if (printDC == NULL) {
	Tcl_AppendResult(interp, "unable to establish device context", (char *)NULL);
	return TCL_ERROR;
    }

    Tcl_DStringInit(&ds);
    if ((OpenPrinterW(Tcl_UtfToWCharDString(printer, -1, &ds),
	    (LPHANDLE)&printDC, NULL)) == FALSE) {
	Tcl_AppendResult(interp, "unable to open printer", (char *)NULL);
	Tcl_DStringFree(&ds);
	return TCL_ERROR;
    }

    Tcl_DStringFree(&ds);
    return TCL_OK;
}

/*
 * --------------------------------------------------------------------------
 *
 * PrintClosePrinter--
 *
 *	Closes the given printer.
 *
 * Results:
 *	Printer closed.
 *
 * -------------------------------------------------------------------------
 */

int PrintClosePrinter(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    if (printDC == NULL) {
	Tcl_AppendResult(interp, "unable to establish device context", (char *)NULL);
	return TCL_ERROR;
    }

    ClosePrinter(printDC);
    return TCL_OK;
}

/*
 * --------------------------------------------------------------------------
 *
 * PrintOpenDoc--
 *
 *     Opens the document for printing.
 *
 * Results:
 *      Opens the print document.
 *
 * -------------------------------------------------------------------------
 */

int PrintOpenDoc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    int output = 0;

    if (printDC == NULL) {
	Tcl_AppendResult(interp, "unable to establish device context", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Start printing.
     */
    output = StartDocW(printDC, &di);
    if (output <= 0) {
	Tcl_AppendResult(interp, "unable to start document", (char *)NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 * --------------------------------------------------------------------------
 *
 * PrintCloseDoc--
 *
 *	Closes the document for printing.
 *
 * Results:
 *	Closes the print document.
 *
 * -------------------------------------------------------------------------
 */

int PrintCloseDoc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    if (printDC == NULL) {
	Tcl_AppendResult(interp, "unable to establish device context", (char *)NULL);
	return TCL_ERROR;
    }

    if (EndDoc(printDC) <= 0) {
	Tcl_AppendResult(interp, "unable to establish close document", (char *)NULL);
	return TCL_ERROR;
    }
    DeleteDC(printDC);
    return TCL_OK;
}

/*
 * --------------------------------------------------------------------------
 *
 * PrintOpenPage--
 *
 *    Opens a page for printing.
 *
 * Results:
 *      Opens the print page.
 *
 * -------------------------------------------------------------------------
 */

int PrintOpenPage(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    if (printDC == NULL) {
	Tcl_AppendResult(interp, "unable to establish device context", (char *)NULL);
	return TCL_ERROR;
    }

    /*Start an individual page.*/
    if (StartPage(printDC) <= 0) {
	Tcl_AppendResult(interp, "unable to start page", (char *)NULL);
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 * --------------------------------------------------------------------------
 *
 * PrintClosePage--
 *
 *	Closes the printed page.
 *
 * Results:
 *	Closes the page.
 *
 * -------------------------------------------------------------------------
 */

int PrintClosePage(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    if (printDC == NULL) {
	Tcl_AppendResult(interp, "unable to establish device context", (char *)NULL);
	return TCL_ERROR;
    }

    if (EndPage(printDC) <= 0) {
	Tcl_AppendResult(interp, "unable to close page", (char *)NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

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.
     */

    memset(&iconInfo, 0, sizeof(iconInfo));
    iconInfo.fIcon = TRUE;

    /*
     * Create device-independent color bitmap.
     */

    memset(&bmInfo, 0, sizeof bmInfo);
    bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmInfo.bmiHeader.biWidth = width;
    bmInfo.bmiHeader.biHeight = -height;
    bmInfo.bmiHeader.biPlanes = 1;
    bmInfo.bmiHeader.biBitCount = 32;
    bmInfo.bmiHeader.biCompression = BI_RGB;

    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;
    }

    memset(bgraMask.ptr, 0, 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
/*
 * tkWinImage.c --
 *
 *	This file contains routines for manipulation full-color images.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"






|







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 © 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"

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
 *	None.
 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display *display,
    Visual *visual,
    unsigned int depth,
    int format,
    int offset,
    char *data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage* imagePtr = (XImage*)ckalloc(sizeof(XImage));
    (void)display;
    (void)visual;

    imagePtr->width = width;
    imagePtr->height = height;
    imagePtr->xoffset = offset;
    imagePtr->format = format;
    imagePtr->data = data;
    imagePtr->byte_order = LSBFirst;







|
|










<
<







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215


216
217
218
219
220
221
222
 *	None.
 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Visual *),
    unsigned int depth,
    int format,
    int offset,
    char *data,
    unsigned int width,
    unsigned int height,
    int bitmap_pad,
    int bytes_per_line)
{
    XImage* imagePtr = (XImage*)ckalloc(sizeof(XImage));



    imagePtr->width = width;
    imagePtr->height = height;
    imagePtr->xoffset = offset;
    imagePtr->format = format;
    imagePtr->data = data;
    imagePtr->byte_order = LSBFirst;
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
 *	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.
 *
 *----------------------------------------------------------------------
 */

static XImage *
XGetImageZPixmap(
    Display *display,
    Drawable d,
    int x, int y,
    unsigned int width, unsigned int height,
    unsigned long plane_mask,
    int	format)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *ret_image;
    HDC hdc, hdcMem;
    HBITMAP hbmp, hbmpPrev;
    BITMAPINFO *bmInfo = NULL;
    HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0;
    int size;
    unsigned int n;
    unsigned int depth;
    unsigned char *data;
    TkWinDCState state;
    BOOL ret;
    (void)plane_mask;

    if (format != ZPixmap) {
	TkpDisplayWarning("Only ZPixmap types are implemented",
		"XGetImageZPixmap Failure");
	return NULL;
    }








|










|














<







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
 *	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 © 1994 Software Research Associates, Inc.
 *
 *----------------------------------------------------------------------
 */

static XImage *
XGetImageZPixmap(
    Display *display,
    Drawable d,
    int x, int y,
    unsigned int width, unsigned int height,
    TCL_UNUSED(unsigned long),
    int	format)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *ret_image;
    HDC hdc, hdcMem;
    HBITMAP hbmp, hbmpPrev;
    BITMAPINFO *bmInfo = NULL;
    HPALETTE hPal, hPalPrev1 = 0, hPalPrev2 = 0;
    int size;
    unsigned int n;
    unsigned int depth;
    unsigned char *data;
    TkWinDCState state;
    BOOL ret;


    if (format != ZPixmap) {
	TkpDisplayWarning("Only ZPixmap types are implemented",
		"XGetImageZPixmap Failure");
	return NULL;
    }

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
    unsigned long plane_mask,
    int	format)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *imagePtr;
    HDC dc;

    display->request++;

    if (twdPtr == NULL) {
	/*
	 * Avoid unmapped windows or bad drawables
	 */

	return NULL;







|







582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
    unsigned long plane_mask,
    int	format)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *imagePtr;
    HDC dc;

    LastKnownRequestProcessed(display)++;

    if (twdPtr == NULL) {
	/*
	 * Avoid unmapped windows or bad drawables
	 */

	return NULL;
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

	dc = TkWinGetDrawableDC(display, d, &state);

	imagePtr = XCreateImage(display, NULL, 32, format, 0, NULL,
		width, height, 32, 0);
	size = imagePtr->bytes_per_line * imagePtr->height;
	imagePtr->data = (char *)ckalloc(size);
	ZeroMemory(imagePtr->data, size);

	for (yy = 0; yy < height; yy++) {
	    for (xx = 0; xx < width; xx++) {
		pixel = GetPixel(dc, x+(int)xx, y+(int)yy);
		if (pixel == CLR_INVALID) {
		    break;
		}







|







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

	dc = TkWinGetDrawableDC(display, d, &state);

	imagePtr = XCreateImage(display, NULL, 32, format, 0, NULL,
		width, height, 32, 0);
	size = imagePtr->bytes_per_line * imagePtr->height;
	imagePtr->data = (char *)ckalloc(size);
	memset(imagePtr->data, 0, size);

	for (yy = 0; yy < height; yy++) {
	    for (xx = 0; xx < width; xx++) {
		pixel = GetPixel(dc, x+(int)xx, y+(int)yy);
		if (pixel == CLR_INVALID) {
		    break;
		}

Changes to win/tkWinInit.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"







|







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 © 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"

31
32
33
34
35
36
37
38
39
40
41

42
43


44

45
46
47
48
49
50
51
 *----------------------------------------------------------------------
 */

int
TkpInit(
    Tcl_Interp *interp)
{
    (void)interp;
    /*
     * This is necessary for static initialization, and is ok otherwise
     * because TkWinXInit flips a static bit to do its work just once.

     */



    TkWinXInit(Tk_GetHINSTANCE());

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetAppName --







<


|
>


>
>

>







31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 *----------------------------------------------------------------------
 */

int
TkpInit(
    Tcl_Interp *interp)
{

    /*
     * This is necessary for static initialization, and is ok otherwise
     * because TkWinXInit flips a static bit to do its work just once. Also,
     * initialize printing and systray API's here.
     */

    WinIcoInit(interp);
    Winprint_Init(interp);
    TkWinXInit(Tk_GetHINSTANCE());
    Icu_Init(interp);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetAppName --
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 */

void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    int argc, namelength;
    const char **argv = NULL, *name, *p;

    name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY);
    namelength = -1;
    if (name != NULL) {
	Tcl_SplitPath(name, &argc, &argv);
	if (argc > 0) {







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 */

void
TkpGetAppName(
    Tcl_Interp *interp,
    Tcl_DString *namePtr)	/* A previously initialized Tcl_DString. */
{
    Tcl_Size argc, namelength;
    const char **argv = NULL, *name, *p;

    name = Tcl_GetVar2(interp, "argv0", NULL, TCL_GLOBAL_ONLY);
    namelength = -1;
    if (name != NULL) {
	Tcl_SplitPath(name, &argc, &argv);
	if (argc > 0) {
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#define TK_MAX_WARN_LEN 1024
    WCHAR titleString[TK_MAX_WARN_LEN];
    WCHAR *msgString; /* points to titleString, just after title, leaving space for ": " */
    int len; /* size of title, including terminating NULL */

    /* If running on Cygwin and we have a stderr channel, use it. */
#if !defined(STATIC_BUILD)
	if (tclStubsPtr->reserved9) {
	Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_WriteChars(errChannel, title, -1);
	    Tcl_WriteChars(errChannel, ": ", 2);
	    Tcl_WriteChars(errChannel, msg, -1);
	    Tcl_WriteChars(errChannel, "\n", 1);
	    return;
	}
    }
#endif /* !STATIC_BUILD */

    len = MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN);







|


|

|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#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->tcl_CreateFileHandler) {
	Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_WriteChars(errChannel, title, TCL_INDEX_NONE);
	    Tcl_WriteChars(errChannel, ": ", 2);
	    Tcl_WriteChars(errChannel, msg, TCL_INDEX_NONE);
	    Tcl_WriteChars(errChannel, "\n", 1);
	    return;
	}
    }
#endif /* !STATIC_BUILD */

    len = MultiByteToWideChar(CP_UTF8, 0, title, -1, titleString, TK_MAX_WARN_LEN);

Changes to win/tkWinInt.h.

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.
 *
 * 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







|







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 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

/*
 * The following is implemented in tkWinPointer.c and also used in tkWinWindow.c
 */

MODULE_SCOPE void		TkSetCursorPos(int x, int y);



















/*
 * Common routines used in Windows implementation
 */
MODULE_SCOPE Tcl_Obj *	        TkWin32ErrorObj(HRESULT hrError);


/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

/*
 * 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);

/*
 * The following is implemented in tkWinGDI.c
 */

MODULE_SCOPE  int       Winprint_Init(Tcl_Interp* interp);

/*
 * 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
/*
 * tkWinKey.c --
 *
 *	This file contains X emulation routines for keyboard related
 *	functions.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "X11/XF86keysym.h"






|







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 © 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
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*55 0x37*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*60 0x3C*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*65 0x41*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*70 0x46*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*75 0x4B*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*80 0x50*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*85 0x55*/
    NoSymbol, XK_Win_L, XK_Win_R, XK_App, NoSymbol, /*90 0x5A*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*95 0x5F*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*100 0x64*/
    NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, /*105 0x69*/
    NoSymbol, NoSymbol, XK_F1, XK_F2, XK_F3, /*110 0x6E*/
    XK_F4, XK_F5, XK_F6, XK_F7, XK_F8, /*115 0x73*/
    XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, /*120 0x78*/
    XK_F14, XK_F15, XK_F16, XK_F17, XK_F18, /*125 0x7D*/







|







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_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*/
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred: needed to get
				 * input context. */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Uninitialized or empty string to hold
				 * result. */
{
    XKeyEvent *keyEv = &eventPtr->xkey;
    int len;
    char buf[6];
    (void)winPtr;

    Tcl_DStringInit(dsPtr);
    if (keyEv->send_event == -1) {
	TkKeyEvent *ev = (TkKeyEvent *)keyEv;
	if (ev->nbytes > 0) {
	    Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
		    ev->trans_chars, ev->nbytes, dsPtr);
	}
    } else if (keyEv->send_event == -3) {

	/*
	 * Special case for WM_UNICHAR and win2000 multilingual IME input
	 */

	len = TkUniCharToUtf(keyEv->keycode, buf);
	Tcl_DStringAppend(dsPtr, buf, len);
    } else {
	/*
	 * This is an event generated from generic code. It has no nchars or
	 * trans_chars members.
	 */

	KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0);

	if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
		|| (keysym == XK_Return) || (keysym == XK_Tab)) {
	    len = TkUniCharToUtf(keysym & 255, buf);
	    Tcl_DStringAppend(dsPtr, buf, len);
	}
    }
    return Tcl_DStringValue(dsPtr);
}

/*







|








<





|








|











|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkpGetString(
    TCL_UNUSED(TkWindow *),		/* Window where event occurred: needed to get
				 * input context. */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Uninitialized or empty string to hold
				 * result. */
{
    XKeyEvent *keyEv = &eventPtr->xkey;
    int len;
    char buf[6];


    Tcl_DStringInit(dsPtr);
    if (keyEv->send_event == -1) {
	TkKeyEvent *ev = (TkKeyEvent *)keyEv;
	if (ev->nbytes > 0) {
	    (void)Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(),
		    ev->trans_chars, ev->nbytes, dsPtr);
	}
    } else if (keyEv->send_event == -3) {

	/*
	 * Special case for WM_UNICHAR and win2000 multilingual IME input
	 */

	len = Tcl_UniCharToUtf(keyEv->keycode, buf);
	Tcl_DStringAppend(dsPtr, buf, len);
    } else {
	/*
	 * This is an event generated from generic code. It has no nchars or
	 * trans_chars members.
	 */

	KeySym keysym = KeycodeToKeysym(keyEv->keycode, keyEv->state, 0);

	if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256))
		|| (keysym == XK_Return) || (keysym == XK_Tab)) {
	    len = Tcl_UniCharToUtf(keysym & 255, buf);
	    Tcl_DStringAppend(dsPtr, buf, len);
	}
    }
    return Tcl_DStringValue(dsPtr);
}

/*
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XKeycodeToKeysym(
    Display *display,
    unsigned int keycode,
    int index)
{
    int state = 0;
    (void)display;

    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}

KeySym
XkbKeycodeToKeysym(
    Display *display,
    unsigned int keycode,
    int group,
    int index)
{
    int state = 0;
    (void)display;
    (void)group;

    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}








|




<









|

|



<
<







147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173


174
175
176
177
178
179
180
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XKeycodeToKeysym(
    TCL_UNUSED(Display *),
    unsigned int keycode,
    int index)
{
    int state = 0;


    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}

KeySym
XkbKeycodeToKeysym(
    TCL_UNUSED(Display *),
    unsigned int keycode,
    TCL_UNUSED(int),
    int index)
{
    int state = 0;



    if (index & 0x01) {
	state |= ShiftMask;
    }
    return KeycodeToKeysym(keycode, state, 0);
}

455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    XModifierKeymap *modMapPtr;
    KeyCode *codePtr;
    KeySym keysym;
    int count, i, j, max, arraySize;

#define KEYCODE_ARRAY_SIZE 20

    dispPtr->bindInfoStale = 0;
    modMapPtr = XGetModifierMapping(dispPtr->display);

    /*
     * Check the keycodes associated with the Lock modifier. If any of them is







|
>







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    XModifierKeymap *modMapPtr;
    KeyCode *codePtr;
    KeySym keysym;
    int count, i, max;
    Tcl_Size j, arraySize;
#define KEYCODE_ARRAY_SIZE 20

    dispPtr->bindInfoStale = 0;
    modMapPtr = XGetModifierMapping(dispPtr->display);

    /*
     * Check the keycodes associated with the Lock modifier. If any of them is
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
 * When mapping from a keysym to a keycode, need information about the
 * modifier state that should be used so that when they call XkbKeycodeToKeysym
 * taking into account the xkey.state, they will get back the original keysym.
 */

void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    int i;
    SHORT result;
    int shift;
    (void)tkwin;

    eventPtr->xkey.keycode = 0;
    if (keySym == NoSymbol) {
	return;
    }

    /*







|






<







561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
 * When mapping from a keysym to a keycode, need information about the
 * modifier state that should be used so that when they call XkbKeycodeToKeysym
 * taking into account the xkey.state, they will get back the original keysym.
 */

void
TkpSetKeycodeAndState(
    TCL_UNUSED(Tk_Window),
    KeySym keySym,
    XEvent *eventPtr)
{
    int i;
    SHORT result;
    int shift;


    eventPtr->xkey.keycode = 0;
    if (keySym == NoSymbol) {
	return;
    }

    /*
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeyCode
XKeysymToKeycode(
    Display *display,
    KeySym keysym)
{
    int i;
    SHORT result;
    (void)display;

    /*
     * We check our private map first for a virtual keycode, as VkKeyScan will
     * return values that don't map to X for the "extended" Syms. This may be
     * due to just casting problems below, but this works.
     */








|




<







619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeyCode
XKeysymToKeycode(
    TCL_UNUSED(Display *),
    KeySym keysym)
{
    int i;
    SHORT result;


    /*
     * We check our private map first for a virtual keycode, as VkKeyScan will
     * return values that don't map to X for the "extended" Syms. This may be
     * due to just casting problems below, but this works.
     */

672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
 *	Allocates a new modifier map data structure.
 *
 *----------------------------------------------------------------------
 */

XModifierKeymap	*
XGetModifierMapping(
    Display *display)
{
    XModifierKeymap *map = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));
    (void)display;

    map->max_keypermod = 1;
    map->modifiermap = (KeyCode *)ckalloc(sizeof(KeyCode) * 8);
    map->modifiermap[ShiftMapIndex] = VK_SHIFT;
    map->modifiermap[LockMapIndex] = VK_CAPITAL;
    map->modifiermap[ControlMapIndex] = VK_CONTROL;
    map->modifiermap[Mod1MapIndex] = VK_NUMLOCK;







|


<







667
668
669
670
671
672
673
674
675
676

677
678
679
680
681
682
683
 *	Allocates a new modifier map data structure.
 *
 *----------------------------------------------------------------------
 */

XModifierKeymap	*
XGetModifierMapping(
    TCL_UNUSED(Display *))
{
    XModifierKeymap *map = (XModifierKeymap *)ckalloc(sizeof(XModifierKeymap));


    map->max_keypermod = 1;
    map->modifiermap = (KeyCode *)ckalloc(sizeof(KeyCode) * 8);
    map->modifiermap[ShiftMapIndex] = VK_SHIFT;
    map->modifiermap[LockMapIndex] = VK_CAPITAL;
    map->modifiermap[ControlMapIndex] = VK_CONTROL;
    map->modifiermap[Mod1MapIndex] = VK_NUMLOCK;
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XStringToKeysym(
    _Xconst char *string)
{
    (void)string;

    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString --







|

<
<







728
729
730
731
732
733
734
735
736


737
738
739
740
741
742
743
 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XStringToKeysym(
    TCL_UNUSED(_Xconst char *))
{


    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString --
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    KeySym keysym)
{
    (void)keysym;

    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|

<
<










751
752
753
754
755
756
757
758
759


760
761
762
763
764
765
766
767
768
769
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    TCL_UNUSED(KeySym))
{


    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinMenu.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * tkWinMenu.c --
 *
 *	This module implements the Windows platform-specific features of
 *	menus.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#define OEMRESOURCE
#include "tkWinInt.h"






|
|







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 © 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"
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
			    const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetTearoffEntryGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);
static int		GetNewID(TkMenuEntry *mePtr, WORD *menuIDPtr);
static int		TkWinMenuKeyObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		MenuSelectEvent(TkMenu *menuPtr);
static void		ReconfigureWindowsMenu(ClientData clientData);
static void		RecursivelyClearActiveMenu(TkMenu *menuPtr);
static void		SetDefaults(int firstTime);
static LRESULT CALLBACK	TkWinMenuProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK	TkWinEmbeddedMenuProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);








|
<
<

|







172
173
174
175
176
177
178
179


180
181
182
183
184
185
186
187
188
			    const Tk_FontMetrics *fmPtr,
			    int *widthPtr, int *heightPtr);
static void		GetTearoffEntryGeometry(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Tk_Font tkfont,
			    const Tk_FontMetrics *fmPtr, int *widthPtr,
			    int *heightPtr);
static int		GetNewID(TkMenuEntry *mePtr, WORD *menuIDPtr);
static Tcl_ObjCmdProc TkWinMenuKeyObjCmd;


static void		MenuSelectEvent(TkMenu *menuPtr);
static void		ReconfigureWindowsMenu(void *clientData);
static void		RecursivelyClearActiveMenu(TkMenu *menuPtr);
static void		SetDefaults(int firstTime);
static LRESULT CALLBACK	TkWinMenuProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static LRESULT CALLBACK	TkWinEmbeddedMenuProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
    int newEntry;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    winMenuHdl = CreatePopupMenu();
    if (winMenuHdl == NULL) {
    	Tcl_SetObjResult(menuPtr->interp, Tcl_NewStringObj(
		"No more menus can be allocated.", -1));
	Tcl_SetErrorCode(menuPtr->interp, "TK", "MENU", "SYSTEM_RESOURCES", NULL);
    	return TCL_ERROR;
    }

    /*
     * We hash all of the HMENU's so that we can get their menu ptrs back when
     * dispatch messages.







|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
    int newEntry;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    winMenuHdl = CreatePopupMenu();
    if (winMenuHdl == NULL) {
    	Tcl_SetObjResult(menuPtr->interp, Tcl_NewStringObj(
		"No more menus can be allocated.", TCL_INDEX_NONE));
	Tcl_SetErrorCode(menuPtr->interp, "TK", "MENU", "SYSTEM_RESOURCES", NULL);
    	return TCL_ERROR;
    }

    /*
     * We hash all of the HMENU's so that we can get their menu ptrs back when
     * dispatch messages.
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541
542
543
544
545
546
547
	int i;
	const char *label = (mePtr->labelPtr == NULL) ? ""
		: Tcl_GetString(mePtr->labelPtr);
	const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? ""
		: Tcl_GetString(mePtr->accelPtr);
	const char *p, *next;
	Tcl_DString itemString;
	int ch;

	/*
	 * We have to construct the string with an ampersand preceeding the
	 * underline character, and a tab seperating the text and the accel
	 * text. We have to be careful with ampersands in the string.
	 */

	Tcl_DStringInit(&itemString);

	for (p = label, i = 0; *p != '\0'; i++, p = next) {
	    if (i == mePtr->underline) {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    if (*p == '&') {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    next = p + TkUtfToUniChar(p, &ch);
	    Tcl_DStringAppend(&itemString, p, (int) (next - p));
	}

	if (mePtr->accelLength > 0) {
	    Tcl_DStringAppend(&itemString, "\t", 1);
	    for (p = accel, i = 0; *p != '\0'; i++, p = next) {
		if (*p == '&') {
		    Tcl_DStringAppend(&itemString, "&", 1);
		}
		next = p + TkUtfToUniChar(p, &ch);
		Tcl_DStringAppend(&itemString, p, (int) (next - p));
	    }
	}

	itemText = (char *)ckalloc(Tcl_DStringLength(&itemString) + 1);
	strcpy(itemText, Tcl_DStringValue(&itemString));
	Tcl_DStringFree(&itemString);







|
















|


>






|







505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
	int i;
	const char *label = (mePtr->labelPtr == NULL) ? ""
		: Tcl_GetString(mePtr->labelPtr);
	const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? ""
		: Tcl_GetString(mePtr->accelPtr);
	const char *p, *next;
	Tcl_DString itemString;
	Tcl_UniChar ch = 0;

	/*
	 * We have to construct the string with an ampersand preceeding the
	 * underline character, and a tab seperating the text and the accel
	 * text. We have to be careful with ampersands in the string.
	 */

	Tcl_DStringInit(&itemString);

	for (p = label, i = 0; *p != '\0'; i++, p = next) {
	    if (i == mePtr->underline) {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    if (*p == '&') {
		Tcl_DStringAppend(&itemString, "&", 1);
	    }
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    Tcl_DStringAppend(&itemString, p, (int) (next - p));
	}
	ch = 0;
	if (mePtr->accelLength > 0) {
	    Tcl_DStringAppend(&itemString, "\t", 1);
	    for (p = accel, i = 0; *p != '\0'; i++, p = next) {
		if (*p == '&') {
		    Tcl_DStringAppend(&itemString, "&", 1);
		}
		next = p + Tcl_UtfToUniChar(p, &ch);
		Tcl_DStringAppend(&itemString, p, (int) (next - p));
	    }
	}

	itemText = (char *)ckalloc(Tcl_DStringLength(&itemString) + 1);
	strcpy(itemText, Tcl_DStringValue(&itemString));
	Tcl_DStringFree(&itemString);
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
 *	if any need it.
 *
 *----------------------------------------------------------------------
 */

static void
ReconfigureWindowsMenu(
    ClientData clientData)	/* The menu we are rebuilding */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    char *itemText = NULL;
    LPCWSTR lpNewItem;
    UINT flags;







|







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
 *	if any need it.
 *
 *----------------------------------------------------------------------
 */

static void
ReconfigureWindowsMenu(
    void *clientData)	/* The menu we are rebuilding */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenuEntry *mePtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    char *itemText = NULL;
    LPCWSTR lpNewItem;
    UINT flags;
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
	    continue;
	}

	itemText = GetEntryText(menuPtr, mePtr);
	if ((menuPtr->menuType == MENUBAR)
		|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {
		Tcl_DStringInit(&translatedText);
		Tcl_UtfToWCharDString(itemText, -1, &translatedText);
	    lpNewItem = (LPCWSTR) Tcl_DStringValue(&translatedText);
	    flags |= MF_STRING;
	} else {
	    lpNewItem = (LPCWSTR) mePtr;
	    flags |= MF_OWNERDRAW;
	}








|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
	    continue;
	}

	itemText = GetEntryText(menuPtr, mePtr);
	if ((menuPtr->menuType == MENUBAR)
		|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {
		Tcl_DStringInit(&translatedText);
		Tcl_UtfToWCharDString(itemText, TCL_INDEX_NONE, &translatedText);
	    lpNewItem = (LPCWSTR) Tcl_DStringValue(&translatedText);
	    flags |= MF_STRING;
	} else {
	    lpNewItem = (LPCWSTR) mePtr;
	    flags |= MF_OWNERDRAW;
	}

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
			    & MENU_SYSTEM_MENU)) {
		Tcl_DString ds;
		TkMenuReferences *menuRefPtr;
		TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds,
			Tk_PathName(menuPtr->mainMenuPtr->tkwin), -1);
		Tcl_DStringAppend(&ds, ".system", 7);

		menuRefPtr = TkFindMenuReferences(menuPtr->interp,
			Tcl_DStringValue(&ds));

		Tcl_DStringFree(&ds);








|







680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
			    & MENU_SYSTEM_MENU)) {
		Tcl_DString ds;
		TkMenuReferences *menuRefPtr;
		TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds,
			Tk_PathName(menuPtr->mainMenuPtr->tkwin), TCL_INDEX_NONE);
		Tcl_DStringAppend(&ds, ".system", 7);

		menuRefPtr = TkFindMenuReferences(menuPtr->interp,
			Tcl_DStringValue(&ds));

		Tcl_DStringFree(&ds);

757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *dummy,
    TkMenu *menuPtr,
    int x, int y, int index)
{
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    int result, flags;
    RECT noGoawayRect;
    POINT point;
    Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
    int oldServiceMode = Tcl_GetServiceMode();
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    tsdPtr->inPostMenu++;
    CallPendingReconfigureImmediately(menuPtr);

    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
	tsdPtr->inPostMenu--;
	return result;
    }

    if (index >= (int)menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*







|

|









<










|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    TCL_UNUSED(Tcl_Interp *),
    TkMenu *menuPtr,
    int x, int y, Tcl_Size index)
{
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    int result, flags;
    RECT noGoawayRect;
    POINT point;
    Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
    int oldServiceMode = Tcl_GetServiceMode();
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    tsdPtr->inPostMenu++;
    CallPendingReconfigureImmediately(menuPtr);

    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
	tsdPtr->inPostMenu--;
	return result;
    }

    if (index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
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
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    Tcl_Interp *dummy,		/* The interpreter of the menu */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, int index)	/* The root X,Y coordinates where we are
				 * posting */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;
    (void)dummy;

    if (index >= (int)menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    TkActivateMenuEntry(menuPtr, -1);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    /*












     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 1. If a virtual root window manager is being used then the coordinates
     *    are in the virtual root window of menuPtr's parent; since the menu
     *    uses override-redirect mode it will be in the *real* root window for
     *    the screen, so we have to map the coordinates from the virtual root







|

|




<

<
<
<
<
<
<
<
|















|
>
>
>
>
>
>
>
>
>
>
>
>







866
867
868
869
870
871
872
873
874
875
876
877
878
879

880







881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter of the menu */
    TkMenu *menuPtr,		/* The menu we are posting */
    int x, int y, Tcl_Size index)	/* The root X,Y coordinates where we are
				 * posting */
{
    int vRootX, vRootY, vRootWidth, vRootHeight;
    int result;









    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
    TkRecomputeMenu(menuPtr);
    result = TkPostCommand(menuPtr);
    if (result != TCL_OK) {
    	return result;
    }

    /*
     * The post commands could have deleted the menu, which means we are dead
     * and should go away.
     */

    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

     /*
     * Adjust the menu y position so that the specified entry will be located
     * at the given coordinates.
     */

    if (index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

   /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 1. If a virtual root window manager is being used then the coordinates
     *    are in the virtual root window of menuPtr's parent; since the menu
     *    uses override-redirect mode it will be in the *real* root window for
     *    the screen, so we have to map the coordinates from the virtual root
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
 *	Redraw the embedded menu window.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateEmbeddedMenu(
    ClientData clientData)
{
    RECT rc;
    HWND hMenuWnd = (HWND)clientData;

    GetClientRect(hMenuWnd, &rc);
    InvalidateRect(hMenuWnd, &rc, FALSE);
    UpdateWindow(hMenuWnd);







|







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
 *	Redraw the embedded menu window.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateEmbeddedMenu(
    void *clientData)
{
    RECT rc;
    HWND hMenuWnd = (HWND)clientData;

    GetClientRect(hMenuWnd, &rc);
    InvalidateRect(hMenuWnd, &rc, FALSE);
    UpdateWindow(hMenuWnd);
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    switch(message) {
    case WM_ENTERIDLE:
	if ((wParam == MSGF_MENU) && (nIdles < 1)
		&& (hwnd == tsdPtr->embeddedMenuHWND)) {
	    Tcl_CreateTimerHandler(200, UpdateEmbeddedMenu,
		    (ClientData) lParam);
	    nIdles++;
	}
	break;

    case WM_INITMENUPOPUP:
	nIdles = 0;
	break;







|







1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    switch(message) {
    case WM_ENTERIDLE:
	if ((wParam == MSGF_MENU) && (nIdles < 1)
		&& (hwnd == tsdPtr->embeddedMenuHWND)) {
	    Tcl_CreateTimerHandler(200, UpdateEmbeddedMenu,
		    (void *) lParam);
	    nIdles++;
	}
	break;

    case WM_INITMENUPOPUP:
	nIdles = 0;
	break;
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
 *	should be returned to windows from this message.
 *
 *----------------------------------------------------------------------
 */

int
TkWinHandleMenuEvent(
    HWND *phwnd,
    UINT *pMessage,
    WPARAM *pwParam,
    LPARAM *plParam,
    LRESULT *plResult)
{
    Tcl_HashEntry *hashEntryPtr;
    int returnResult = 0;
    TkMenu *menuPtr;
    TkMenuEntry *mePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)phwnd;

    switch (*pMessage) {
    case WM_UNINITMENUPOPUP:
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*pwParam);
	if (hashEntryPtr != NULL) {
	    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);







|











<







1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150

1151
1152
1153
1154
1155
1156
1157
 *	should be returned to windows from this message.
 *
 *----------------------------------------------------------------------
 */

int
TkWinHandleMenuEvent(
    TCL_UNUSED(HWND *),
    UINT *pMessage,
    WPARAM *pwParam,
    LPARAM *plParam,
    LRESULT *plResult)
{
    Tcl_HashEntry *hashEntryPtr;
    int returnResult = 0;
    TkMenu *menuPtr;
    TkMenuEntry *mePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    switch (*pMessage) {
    case WM_UNINITMENUPOPUP:
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*pwParam);
	if (hashEntryPtr != NULL) {
	    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
		if ((code != TCL_OK) && (code != TCL_CONTINUE)
			&& (code != TCL_BREAK)) {
		    Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
		    Tcl_BackgroundException(interp, code);
		}
		Tcl_Release(interp);
	    }
	    TkActivateMenuEntry(menuPtr, -1);
	    *plResult = 0;
	    returnResult = 1;
	} else {
	    tsdPtr->modalMenuPtr = NULL;
	}
	break;








|







1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
		if ((code != TCL_OK) && (code != TCL_CONTINUE)
			&& (code != TCL_BREAK)) {
		    Tcl_AddErrorInfo(interp, "\n    (menu preprocess)");
		    Tcl_BackgroundException(interp, code);
		}
		Tcl_Release(interp);
	    }
	    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
	    *plResult = 0;
	    returnResult = 1;
	} else {
	    tsdPtr->modalMenuPtr = NULL;
	}
	break;

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
	}
	break;

    case WM_MENUCHAR: {
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*plParam);
	if (hashEntryPtr != NULL) {
	    TkSizeT i, len;
	    int underline;
	    Tcl_Obj *labelPtr;
	    WCHAR *wlabel;
	    int menuChar;
	    Tcl_DString ds;

	    *plResult = 0;







|







1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
	}
	break;

    case WM_MENUCHAR: {
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*plParam);
	if (hashEntryPtr != NULL) {
	    Tcl_Size i, len;
	    int underline;
	    Tcl_Obj *labelPtr;
	    WCHAR *wlabel;
	    int menuChar;
	    Tcl_DString ds;

	    *plResult = 0;
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
	    for (i = 0; i < menuPtr->numEntries; i++) {
		underline = menuPtr->entries[i]->underline;
		labelPtr = menuPtr->entries[i]->labelPtr;
		if ((underline >= 0) && (labelPtr != NULL)) {
		    /*
		     * Ensure we don't exceed the label length, then check
		     */
		    const char *src = TkGetStringFromObj(labelPtr, &len);

		    Tcl_DStringFree(&ds);
		    Tcl_DStringInit(&ds);
		    wlabel = Tcl_UtfToWCharDString(src, len, &ds);
		    if (((TkSizeT)underline + 1 < len + 1) && (menuChar ==
				Tcl_UniCharToUpper(wlabel[underline]))) {
			*plResult = (2 << 16) | i;
			returnResult = 1;
			break;
		    }
		}
	    }







|




|







1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
	    for (i = 0; i < menuPtr->numEntries; i++) {
		underline = menuPtr->entries[i]->underline;
		labelPtr = menuPtr->entries[i]->labelPtr;
		if ((underline >= 0) && (labelPtr != NULL)) {
		    /*
		     * Ensure we don't exceed the label length, then check
		     */
		    const char *src = Tcl_GetStringFromObj(labelPtr, &len);

		    Tcl_DStringFree(&ds);
		    Tcl_DStringInit(&ds);
		    wlabel = Tcl_UtfToWCharDString(src, len, &ds);
		    if ((underline < len) && (menuChar ==
				Tcl_UniCharToUpper(wlabel[underline]))) {
			*plResult = (2 << 16) | i;
			returnResult = 1;
			break;
		    }
		}
	    }
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
	    twdPtr->type = TWD_WINDC;
	    twdPtr->winDC.hdc = itemPtr->hDC;

	    if (mePtr->state != ENTRY_DISABLED) {
		if (itemPtr->itemState & ODS_SELECTED) {
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		} else {
		    TkActivateMenuEntry(menuPtr, -1);
		}
	    } else {
		/*
		 * On windows, menu entries should highlight even if they are
		 * disabled. (I know this seems dumb, but it is the way native
		 * windows menus works so we ought to mimic it.) The
		 * ENTRY_PLATFORM_FLAG1 flag will indicate that the entry







|







1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
	    twdPtr->type = TWD_WINDC;
	    twdPtr->winDC.hdc = itemPtr->hDC;

	    if (mePtr->state != ENTRY_DISABLED) {
		if (itemPtr->itemState & ODS_SELECTED) {
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		} else {
		    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
		}
	    } else {
		/*
		 * On windows, menu entries should highlight even if they are
		 * disabled. (I know this seems dumb, but it is the way native
		 * windows menus works so we ought to mimic it.) The
		 * ENTRY_PLATFORM_FLAG1 flag will indicate that the entry
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
			*plParam);
		if (hashEntryPtr != NULL) {
		    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
		}
	    }

	    if (menuPtr != NULL) {
		long entryIndex = LOWORD(*pwParam);

                if ((menuPtr->menuType == MENUBAR) && menuPtr->tearoff) {
                    /*
                     * Windows passes the entry index starting at 0 for
                     * the first menu entry. However this entry #0 is the
                     * tearoff entry for Tk (the menu has -tearoff 1),
                     * which is ignored for MENUBAR menues on Windows.
                     */

                    entryIndex++;
                }
                mePtr = NULL;
		if (flags != 0xFFFF) {
		    if ((flags&MF_POPUP) && (entryIndex < (int)menuPtr->numEntries)) {
			mePtr = menuPtr->entries[entryIndex];
		    } else {
			hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
				INT2PTR(entryIndex));
			if (hashEntryPtr != NULL) {
			    mePtr = (TkMenuEntry *)Tcl_GetHashValue(hashEntryPtr);
			}
		    }
		}

		if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) {
		    TkActivateMenuEntry(menuPtr, -1);
		} else {
		    if (mePtr->index >= (int)menuPtr->numEntries) {
			Tcl_Panic("Trying to activate an entry which doesn't exist");
		    }
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		}
		MenuSelectEvent(menuPtr);







|

|
|
|
|
|
|
|

|
|
|

|











|







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
			*plParam);
		if (hashEntryPtr != NULL) {
		    menuPtr = (TkMenu *)Tcl_GetHashValue(hashEntryPtr);
		}
	    }

	    if (menuPtr != NULL) {
		Tcl_Size entryIndex = LOWORD(*pwParam);

		if ((menuPtr->menuType == MENUBAR) && menuPtr->tearoff) {
		    /*
		     * Windows passes the entry index starting at 0 for
		     * the first menu entry. However this entry #0 is the
		     * tearoff entry for Tk (the menu has -tearoff 1),
		     * which is ignored for MENUBAR menues on Windows.
		     */

			entryIndex++;
		}
		mePtr = NULL;
		if (flags != 0xFFFF) {
		    if ((flags&MF_POPUP) && (entryIndex < menuPtr->numEntries)) {
			mePtr = menuPtr->entries[entryIndex];
		    } else {
			hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable,
				INT2PTR(entryIndex));
			if (hashEntryPtr != NULL) {
			    mePtr = (TkMenuEntry *)Tcl_GetHashValue(hashEntryPtr);
			}
		    }
		}

		if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) {
		    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
		} else {
		    if (mePtr->index >= (int)menuPtr->numEntries) {
			Tcl_Panic("Trying to activate an entry which doesn't exist");
		    }
		    TkActivateMenuEntry(menuPtr, mePtr->index);
		}
		MenuSelectEvent(menuPtr);
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    TkSizeT i;
    TkMenuEntry *mePtr;

    TkActivateMenuEntry(menuPtr, -1);
    MenuSelectEvent(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	mePtr = menuPtr->entries[i];
	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;







|


|







1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    Tcl_Size i;
    TkMenuEntry *mePtr;

    TkActivateMenuEntry(menuPtr, TCL_INDEX_NONE);
    MenuSelectEvent(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	mePtr = menuPtr->entries[i];
	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;
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
	TkWinSetMenu(tkwin, NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetMainMenubar --
 *
 *	Puts the menu associated with a window into the menubar. Should only
 *	be called when the window is in front.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menubar is changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpSetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    const char *menuName)	/* The name of the menu to put in front. If
    				 * NULL, use the default menu bar. */
{
    (void)interp;
    (void)tkwin;
    (void)menuName;

    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------







|














|
|
|
|


<
<
<
<







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
	TkWinSetMenu(tkwin, NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SetMainMenubar --
 *
 *	Puts the menu associated with a window into the menubar. Should only
 *	be called when the window is in front.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menubar is changed.
 *
 *----------------------------------------------------------------------
 */

void
Tk_SetMainMenubar(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter of the application */
    TCL_UNUSED(Tk_Window),		/* The frame we are setting up */
    TCL_UNUSED(const char *))	/* The name of the menu to put in front. If
    				 * NULL, use the default menu bar. */
{




    /*
     * Nothing to do.
     */
}

/*
 *----------------------------------------------------------------------
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
 *----------------------------------------------------------------------
 */

void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* Precalculated font */
    const Tk_FontMetrics *fmPtr,/* Precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)menuPtr;
    (void)tkfont;
    (void)fmPtr;

    *heightPtr = indicatorDimensions[0];
    if (mePtr->hideMargin) {
	*widthPtr = 0;
    } else {
	int borderWidth;

	Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,







|
|



<
<
<
<







1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593




1594
1595
1596
1597
1598
1599
1600
 *----------------------------------------------------------------------
 */

void
GetMenuIndicatorGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    TCL_UNUSED(Tk_Font),		/* Precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* Precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{




    *heightPtr = indicatorDimensions[0];
    if (mePtr->hideMargin) {
	*widthPtr = 0;
    } else {
	int borderWidth;

	Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
 *
 *----------------------------------------------------------------------
 */

void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)mePtr;
    (void)tkfont;

    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
    }
    *widthPtr = 0;
}







|
|




<
<
<







1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682



1683
1684
1685
1686
1687
1688
1689
 *
 *----------------------------------------------------------------------
 */

void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* 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 precalculated font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{



    if (menuPtr->menuType != MAIN_MENU) {
	*heightPtr = 0;
    } else {
	*heightPtr = fmPtr->linespace;
    }
    *widthPtr = 0;
}
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
GetMenuSeparatorGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{
    (void)menuPtr;
    (void)mePtr;
    (void)tkfont;

    *widthPtr = 0;
    *heightPtr = fmPtr->linespace - (2 * fmPtr->descent);
}

/*
 *----------------------------------------------------------------------
 *







|
|
|




<
<
<
<







1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715




1716
1717
1718
1719
1720
1721
1722
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
GetMenuSeparatorGeometry(
    TCL_UNUSED(TkMenu *),		/* The menu we are measuring */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */
    int *widthPtr,		/* The resulting width */
    int *heightPtr)		/* The resulting height */
{




    *widthPtr = 0;
    *heightPtr = fmPtr->linespace - (2 * fmPtr->descent);
}

/*
 *----------------------------------------------------------------------
 *
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
void
DrawMenuEntryIndicator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    GC indicatorGC,		/* The gc for indicator objects */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left edge */
    int y,			/* Top edge */
    int width,
    int height)
{
    (void)tkfont;
    (void)fmPtr;
    (void)width;
    (void)height;

    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
    	if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) {
	    RECT rect;
	    GC whichGC;
	    int borderWidth, activeBorderWidth;








|
|


|
|

<
<
<
<
<







1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828





1829
1830
1831
1832
1833
1834
1835
void
DrawMenuEntryIndicator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    GC indicatorGC,		/* The gc for indicator objects */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated font metrics */
    int x,			/* Left edge */
    int y,			/* Top edge */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{





    if ((mePtr->type == CHECK_BUTTON_ENTRY)
	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {
    	if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) {
	    RECT rect;
	    GC whichGC;
	    int borderWidth, activeBorderWidth;

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
DrawMenuEntryAccelerator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    Tk_3DBorder activeBorder,	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    int baseline;
    int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth;
    const char *accel;
    (void)activeBorder;
    (void)width;
    (void)height;

    if (menuPtr->menuType == MENUBAR) {
        return;
    }

    if (mePtr->accelPtr != NULL) {
	accel = Tcl_GetString(mePtr->accelPtr);







|


|





<
<
<







1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908



1909
1910
1911
1912
1913
1914
1915
DrawMenuEntryAccelerator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    TCL_UNUSED(Tk_3DBorder),	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    TCL_UNUSED(int),			/* Width of menu entry */
    int height)			/* Height of menu entry */
{
    int baseline;
    int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth;
    const char *accel;




    if (menuPtr->menuType == MENUBAR) {
        return;
    }

    if (mePtr->accelPtr != NULL) {
	accel = Tcl_GetString(mePtr->accelPtr);
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

void
DrawMenuEntryArrow(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_3DBorder activeBorder,	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height,			/* Height of menu entry */
    int drawArrow)		/* For cascade menus, whether of not to draw
				 * the arrow. I cannot figure out Windows'
				 * algorithm for where to draw this. */
{
    COLORREF oldFgColor;
    COLORREF oldBgColor;
    RECT rect;
    (void)gc;
    (void)activeBorder;

    if (!drawArrow || (mePtr->type != CASCADE_ENTRY)) {
	return;
    }

    /*
     * Don't draw the arrow if a submenu is not attached to this







|











<
<







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

void
DrawMenuEntryArrow(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    TCL_UNUSED(Tk_3DBorder),	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    int height,			/* Height of menu entry */
    int drawArrow)		/* For cascade menus, whether of not to draw
				 * the arrow. I cannot figure out Windows'
				 * algorithm for where to draw this. */
{
    COLORREF oldFgColor;
    COLORREF oldBgColor;
    RECT rect;



    if (!drawArrow || (mePtr->type != CASCADE_ENTRY)) {
	return;
    }

    /*
     * Don't draw the arrow if a submenu is not attached to this
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
 *
 *----------------------------------------------------------------------
 */

void
DrawMenuSeparator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* width of item */
    int height)			/* height of item */
{
    XPoint points[2];
    Tk_3DBorder border;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    points[0].x = x;
    points[0].y = y + height / 2;
    points[1].x = x + width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,







|

|
|
|







<
<
<
<







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
 *
 *----------------------------------------------------------------------
 */

void
DrawMenuSeparator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    TCL_UNUSED(GC),			/* The gc we are drawing with */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated font metrics */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* width of item */
    int height)			/* height of item */
{
    XPoint points[2];
    Tk_3DBorder border;





    points[0].x = x;
    points[0].y = y + height / 2;
    points[1].x = x + width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left Edge */
    int y,			/* Top Edge */
    int width,			/* Width of entry */
    int height)			/* Height of entry */
{
    (void)fmPtr;
    (void)width;

    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;

	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len) {
	    const char *label, *start, *end;
	    int ch;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = start + TkUtfToUniChar(start, &ch);
	    Tk_UnderlineChars(menuPtr->display, d,
		    gc, tkfont, label, x + mePtr->indicatorSpace,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    (int) (start - label), (int) (end - label));
	}
    }
}







|


<
<
<










|







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
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc to draw into */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    int x,			/* Left Edge */
    int y,			/* Top Edge */
    TCL_UNUSED(int),			/* Width of entry */
    int height)			/* Height of entry */
{



    if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) {
	int len;

	len = Tcl_GetCharLength(mePtr->labelPtr);
	if (mePtr->underline < len) {
	    const char *label, *start, *end;
	    int ch;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    end = start + Tcl_UtfToUniChar(start, &ch);
	    Tk_UnderlineChars(menuPtr->display, d,
		    gc, tkfont, label, x + mePtr->indicatorSpace,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    (int) (start - label), (int) (end - label));
	}
    }
}
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
 *	The menu system may take over and process user events for menu input.
 *
 *--------------------------------------------------------------
 */

static int
TkWinMenuKeyObjCmd(
    ClientData dummy,	/* Unused. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    UINT scanCode;
    UINT virtualKey;
    XEvent *eventPtr;
    Tk_Window tkwin;
    TkWindow *winPtr;
    KeySym keySym;
    int i;
    (void)dummy;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "window keySym");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]),







|











<







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
 *	The menu system may take over and process user events for menu input.
 *
 *--------------------------------------------------------------
 */

static int
TkWinMenuKeyObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    UINT scanCode;
    UINT virtualKey;
    XEvent *eventPtr;
    Tk_Window tkwin;
    TkWindow *winPtr;
    KeySym keySym;
    int i;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "window keySym");
	return TCL_ERROR;
    }

    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[1]),
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
     * create a C level binding directly since we may want to modify the
     * binding in Tcl code.
     */

    (void) Tcl_CreateObjCommand(interp, "tk::WinMenuKey",
	    TkWinMenuKeyObjCmd, Tk_MainWindow(interp), NULL);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt_L>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-Alt_L>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-Key>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<Key-F10>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuEntryLabel --







|


|


|


|


|


|


|


|







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
     * create a C level binding directly since we may want to modify the
     * binding in Tcl code.
     */

    (void) Tcl_CreateObjCommand(interp, "tk::WinMenuKey",
	    TkWinMenuKeyObjCmd, Tk_MainWindow(interp), NULL);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<Alt_L>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<KeyRelease-Alt_L>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<Alt-Key>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<Key-F10>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (void *)uid,
	    "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0);
}

/*
 *----------------------------------------------------------------------
 *
 * DrawMenuEntryLabel --
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
 *
 *----------------------------------------------------------------------
 */

void
DrawTearoffEntry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_Font tkfont,		/* The font we are drawing with */
    const Tk_FontMetrics *fmPtr,/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;







|

|
|
|






<
<
<
<







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
 *
 *----------------------------------------------------------------------
 */

void
DrawTearoffEntry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    TCL_UNUSED(GC),			/* The gc we are drawing with */
    TCL_UNUSED(Tk_Font),		/* The font we are drawing with */
    TCL_UNUSED(const Tk_FontMetrics *),/* The metrics we are drawing with */
    int x, int y,
    int width, int height)
{
    XPoint points[2];
    int segmentWidth, maxX;
    Tk_3DBorder border;





    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font menuFont, tkfont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int x, y, height, width, indicatorSpace, labelWidth, accelWidth;
    int windowWidth, windowHeight, accelSpace;
    int i, j, lastColumnBreak = 0;
    int activeBorderWidth, borderWidth;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,







|







2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    Tk_Font menuFont, tkfont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    int x, y, height, width, indicatorSpace, labelWidth, accelWidth;
    int windowWidth, windowHeight, accelSpace;
    Tcl_Size i, j, lastColumnBreak = 0;
    int activeBorderWidth, borderWidth;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin,
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    union {XEvent general; XVirtualEvent virt;} event;
    union {DWORD msgpos; POINTS point;} root;

    memset(&event, 0, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = menuPtr->display->request;
    event.virt.send_event = 0;
    event.virt.display = menuPtr->display;
    Tk_MakeWindowExist(menuPtr->tkwin);
    event.virt.event = Tk_WindowId(menuPtr->tkwin);
    event.virt.root = XRootWindow(menuPtr->display, 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();







|







3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    union {XEvent general; XVirtualEvent virt;} event;
    union {DWORD msgpos; POINTS point;} root;

    memset(&event, 0, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(menuPtr->display);
    event.virt.send_event = 0;
    event.virt.display = menuPtr->display;
    Tk_MakeWindowExist(menuPtr->tkwin);
    event.virt.event = Tk_WindowId(menuPtr->tkwin);
    event.virt.root = XRootWindow(menuPtr->display, 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetMenuHWND(
    Tk_Window tkwin)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)tkwin;

    TkMenuInit();
    return tsdPtr->embeddedMenuHWND;
}

/*
 *----------------------------------------------------------------------







|



<







3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231

3232
3233
3234
3235
3236
3237
3238
 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetMenuHWND(
    TCL_UNUSED(Tk_Window))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    TkMenuInit();
    return tsdPtr->embeddedMenuHWND;
}

/*
 *----------------------------------------------------------------------
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuExitHandler(
    ClientData dummy)	    /* Not used */
{
    (void)dummy;

    UnregisterClassW(MENU_CLASS_NAME, Tk_GetHINSTANCE());
    UnregisterClassW(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE());
}

/*
 *----------------------------------------------------------------------
 *







|

<
<







3248
3249
3250
3251
3252
3253
3254
3255
3256


3257
3258
3259
3260
3261
3262
3263
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuExitHandler(
    TCL_UNUSED(void *))	    /* Not used */
{


    UnregisterClassW(MENU_CLASS_NAME, Tk_GetHINSTANCE());
    UnregisterClassW(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE());
}

/*
 *----------------------------------------------------------------------
 *
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuThreadExitHandler(
    ClientData dummy)	    /* Not used */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    DestroyWindow(tsdPtr->menuHWND);
    DestroyWindow(tsdPtr->embeddedMenuHWND);
    tsdPtr->menuHWND = NULL;
    tsdPtr->embeddedMenuHWND = NULL;

    Tcl_DeleteHashTable(&tsdPtr->winMenuTable);







|



<







3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283

3284
3285
3286
3287
3288
3289
3290
 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuThreadExitHandler(
    TCL_UNUSED(void *))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    DestroyWindow(tsdPtr->menuHWND);
    DestroyWindow(tsdPtr->embeddedMenuHWND);
    tsdPtr->menuHWND = NULL;
    tsdPtr->embeddedMenuHWND = NULL;

    Tcl_DeleteHashTable(&tsdPtr->winMenuTable);
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
 *	Storage is allocated.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkWinGetMenuSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
{
    Tcl_Obj *valuePtr = NULL;
    (void)tkwin;
    (void)className;

    if ((strcmp(dbName, "activeBorderWidth") == 0) ||
	    (strcmp(dbName, "borderWidth") == 0)) {
	valuePtr = Tcl_NewWideIntObj(defaultBorderWidth);
    } else if (strcmp(dbName, "font") == 0) {
	valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1);
    }

    return valuePtr;
}

/*
 *----------------------------------------------------------------------







|

|


<
<





|







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
 *	Storage is allocated.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkWinGetMenuSystemDefault(
    TCL_UNUSED(Tk_Window),		/* A window to use. */
    const char *dbName,		/* The option database name. */
    TCL_UNUSED(const char *))	/* The name of the option class. */
{
    Tcl_Obj *valuePtr = NULL;



    if ((strcmp(dbName, "activeBorderWidth") == 0) ||
	    (strcmp(dbName, "borderWidth") == 0)) {
	valuePtr = Tcl_NewWideIntObj(defaultBorderWidth);
    } else if (strcmp(dbName, "font") == 0) {
	valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), TCL_INDEX_NONE);
    }

    return valuePtr;
}

/*
 *----------------------------------------------------------------------
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456

    SelectObject(scratchDC, GetStockObject(SYSTEM_FONT));
    DeleteDC(scratchDC);

    DeleteObject(menuFont);

    Tcl_DStringAppendElement(&menuFontDString, faceName);
    sprintf(sizeString, "%d", pointSize);
    Tcl_DStringAppendElement(&menuFontDString, sizeString);

    if (bold || italic) {
	Tcl_DString boldItalicDString;

	Tcl_DStringInit(&boldItalicDString);
	if (bold) {







|







3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414

    SelectObject(scratchDC, GetStockObject(SYSTEM_FONT));
    DeleteDC(scratchDC);

    DeleteObject(menuFont);

    Tcl_DStringAppendElement(&menuFontDString, faceName);
    snprintf(sizeString, sizeof(sizeString), "%d", pointSize);
    Tcl_DStringAppendElement(&menuFontDString, sizeString);

    if (bold || italic) {
	Tcl_DString boldItalicDString;

	Tcl_DStringInit(&boldItalicDString);
	if (bold) {

Changes to win/tkWinPixmap.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"







|







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 © 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"

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    int height,
    int depth)
{
    TkWinDrawable *newTwdPtr, *twdPtr;
    int planes;
    Screen *screen;

    display->request++;

    newTwdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));
    newTwdPtr->type = TWD_BITMAP;
    newTwdPtr->bitmap.depth = depth;
    twdPtr = (TkWinDrawable *) d;
    if (twdPtr->type != TWD_BITMAP) {
	if (twdPtr->window.winPtr == NULL) {
	    newTwdPtr->bitmap.colormap = DefaultColormap(display,
		    DefaultScreen(display));
	} else {
	    newTwdPtr->bitmap.colormap = twdPtr->window.winPtr->atts.colormap;
	}
    } else {
	newTwdPtr->bitmap.colormap = twdPtr->bitmap.colormap;
    }
    screen = &display->screens[0];
    planes = 1;
    if (depth == screen->root_depth) {
	planes = PTR2INT(screen->ext_data);
	depth /= planes;
    }
    newTwdPtr->bitmap.handle =
	    CreateBitmap(width, height, (DWORD) planes, (DWORD) depth, NULL);

    /*







|















|

|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    int height,
    int depth)
{
    TkWinDrawable *newTwdPtr, *twdPtr;
    int planes;
    Screen *screen;

    LastKnownRequestProcessed(display)++;

    newTwdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));
    newTwdPtr->type = TWD_BITMAP;
    newTwdPtr->bitmap.depth = depth;
    twdPtr = (TkWinDrawable *) d;
    if (twdPtr->type != TWD_BITMAP) {
	if (twdPtr->window.winPtr == NULL) {
	    newTwdPtr->bitmap.colormap = DefaultColormap(display,
		    DefaultScreen(display));
	} else {
	    newTwdPtr->bitmap.colormap = twdPtr->window.winPtr->atts.colormap;
	}
    } else {
	newTwdPtr->bitmap.colormap = twdPtr->bitmap.colormap;
    }
    screen = ScreenOfDisplay(display, 0);
    planes = 1;
    if (depth == DefaultDepthOfScreen(screen)) {
	planes = PTR2INT(screen->ext_data);
	depth /= planes;
    }
    newTwdPtr->bitmap.handle =
	    CreateBitmap(width, height, (DWORD) planes, (DWORD) depth, NULL);

    /*
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
void
Tk_FreePixmap(
    Display *display,
    Pixmap pixmap)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;

    display->request++;
    if (twdPtr != NULL) {
	DeleteObject(twdPtr->bitmap.handle);
	ckfree(twdPtr);
    }
}

/*







|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
void
Tk_FreePixmap(
    Display *display,
    Pixmap pixmap)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;

    LastKnownRequestProcessed(display)++;
    if (twdPtr != NULL) {
	DeleteObject(twdPtr->bitmap.handle);
	ckfree(twdPtr);
    }
}

/*
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XGetGeometry(
    Display *display,
    Drawable d,
    Window *root_return,
    int *x_return,
    int *y_return,
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    (void)display;
    (void)root_return;
    (void)x_return;
    (void)y_return;
    (void)border_width_return;
    (void)depth_return;

    if (twdPtr->type == TWD_BITMAP) {
	HDC dc;
	BITMAPINFO info;

	if (twdPtr->bitmap.handle == NULL) {
	    Tcl_Panic("XGetGeometry: invalid pixmap");







|

|
|
|


|
|


<
<
<
<
<
<







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210






211
212
213
214
215
216
217
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XGetGeometry(
    TCL_UNUSED(Display *),
    Drawable d,
    TCL_UNUSED(Window *),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    unsigned int *width_return,
    unsigned int *height_return,
    TCL_UNUSED(unsigned int *),
    TCL_UNUSED(unsigned int *))
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;







    if (twdPtr->type == TWD_BITMAP) {
	HDC dc;
	BITMAPINFO info;

	if (twdPtr->bitmap.handle == NULL) {
	    Tcl_Panic("XGetGeometry: invalid pixmap");

Changes to win/tkWinPointer.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"






|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkWinPointer.c --
 *
 *	Windows specific mouse tracking code.
 *
 * 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"

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
static Tcl_TimerToken mouseTimer;	/* Handle to the latest mouse timer. */
static int mouseTimerSet = 0;		/* 1 if the mouse timer is active. */

/*
 * Forward declarations of procedures used in this file.
 */

static void		MouseTimerProc(ClientData clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkWinGetModifierState --
 *
 *	Return the modifier state as of the last message.







|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
static Tcl_TimerToken mouseTimer;	/* Handle to the latest mouse timer. */
static int mouseTimerSet = 0;		/* 1 if the mouse timer is active. */

/*
 * Forward declarations of procedures used in this file.
 */

static void		MouseTimerProc(void *clientData);

/*
 *----------------------------------------------------------------------
 *
 * TkWinGetModifierState --
 *
 *	Return the modifier state as of the last message.
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
 *	May schedule a new timer and/or generate enter/leave events.
 *
 *----------------------------------------------------------------------
 */

void
MouseTimerProc(
    ClientData dummy)
{
    POINT pos;
    (void)dummy;

    mouseTimerSet = 0;

    /*
     * Get the current mouse position and window. Don't do anything if the
     * mouse hasn't moved since the last time we looked.
     */

    GetCursorPos(&pos);
    TkWinPointerEvent(NULL, pos.x, pos.y);
}

/*
 *----------------------------------------------------------------------
 *







|


<



<
<
<
<
<







231
232
233
234
235
236
237
238
239
240

241
242
243





244
245
246
247
248
249
250
 *	May schedule a new timer and/or generate enter/leave events.
 *
 *----------------------------------------------------------------------
 */

void
MouseTimerProc(
    TCL_UNUSED(void *))
{
    POINT pos;


    mouseTimerSet = 0;






    GetCursorPos(&pos);
    TkWinPointerEvent(NULL, pos.x, pos.y);
}

/*
 *----------------------------------------------------------------------
 *
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
 *
 *----------------------------------------------------------------------
 */

Bool
XQueryPointer(
    Display *display,
    Window w,
    Window *root_return,
    Window *child_return,
    int *root_x_return,
    int *root_y_return,
    int *win_x_return,
    int *win_y_return,
    unsigned int *mask_return)
{
    (void)w;
    (void)root_return;
    (void)child_return;
    (void)win_x_return;
    (void)win_y_return;

    display->request++;
    TkGetPointerCoords(NULL, root_x_return, root_y_return);
    *mask_return = TkWinGetModifierState();
    return True;
}

/*
 *----------------------------------------------------------------------







|
|
|


|
|


<
<
<
<
<
|
<







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334





335

336
337
338
339
340
341
342
 *
 *----------------------------------------------------------------------
 */

Bool
XQueryPointer(
    Display *display,
    TCL_UNUSED(Window),
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window *),
    int *root_x_return,
    int *root_y_return,
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    unsigned int *mask_return)
{





    LastKnownRequestProcessed(display)++;

    TkGetPointerCoords(NULL, root_x_return, root_y_return);
    *mask_return = TkWinGetModifierState();
    return True;
}

/*
 *----------------------------------------------------------------------
377
378
379
380
381
382
383











384
385
386
387
388
389
390
void TkSetCursorPos(
    int x,
    int y)
{
    INPUT input;
    int xscreen = (int)(GetSystemMetrics(SM_CXSCREEN) - 1);
    int yscreen = (int)(GetSystemMetrics(SM_CYSCREEN) - 1);












    input.type = INPUT_MOUSE;
    input.mi.dx = (x * 65535 + xscreen/2) / xscreen;
    input.mi.dy = (y * 65535 + yscreen/2) / yscreen;

    /*
     * Horrible workaround here. There is a bug on Win 10: when warping to







>
>
>
>
>
>
>
>
>
>
>







365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
void TkSetCursorPos(
    int x,
    int y)
{
    INPUT input;
    int xscreen = (int)(GetSystemMetrics(SM_CXSCREEN) - 1);
    int yscreen = (int)(GetSystemMetrics(SM_CYSCREEN) - 1);

    /*
     * A multi-screen system may have different logical pixels/inch, with
     * Windows applying behind-the-scenes scaling on secondary screens.
     * Don't try and emulate that, instead fall back to SetCursor if the
     * requested position is off the primary screen.
     */
    if ( x < 0 || x > xscreen || y < 0 || y > yscreen ) {
        SetCursorPos(x, y);
        return;
    }

    input.type = INPUT_MOUSE;
    input.mi.dx = (x * 65535 + xscreen/2) / xscreen;
    input.mi.dy = (y * 65535 + yscreen/2) / yscreen;

    /*
     * Horrible workaround here. There is a bug on Win 10: when warping to
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
    Window *focus_return,
    int *revert_to_return)
{
    Tk_Window tkwin = Tk_HWNDToWindow(GetFocus());

    *focus_return = tkwin ? Tk_WindowId(tkwin) : 0;
    *revert_to_return = RevertToParent;
    display->request++;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XSetInputFocus --







|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
    Window *focus_return,
    int *revert_to_return)
{
    Tk_Window tkwin = Tk_HWNDToWindow(GetFocus());

    *focus_return = tkwin ? Tk_WindowId(tkwin) : 0;
    *revert_to_return = RevertToParent;
    LastKnownRequestProcessed(display)++;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XSetInputFocus --
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
 *----------------------------------------------------------------------
 */

int
XSetInputFocus(
    Display *display,
    Window focus,
    int revert_to,
    Time time)
{
    (void)revert_to;
    (void)time;

    display->request++;
    if (focus != None) {
	SetFocus(Tk_GetHWND(focus));
    }
    return Success;
}

/*







|
|

<
<
|
<







490
491
492
493
494
495
496
497
498
499


500

501
502
503
504
505
506
507
 *----------------------------------------------------------------------
 */

int
XSetInputFocus(
    Display *display,
    Window focus,
    TCL_UNUSED(int),
    TCL_UNUSED(Time))
{


    LastKnownRequestProcessed(display)++;

    if (focus != None) {
	SetFocus(Tk_GetHWND(focus));
    }
    return Success;
}

/*

Changes to win/tkWinPort.h.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * compile under the windows compilers.
 *---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <wchar.h>
#include <io.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string.h>







<







20
21
22
23
24
25
26

27
28
29
30
31
32
33
 * compile under the windows compilers.
 *---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <wchar.h>
#include <io.h>

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
91
92
93
94
95
96
97

98
99
100
101
102
103
104

#define REDO_KEYSYM_LOOKUP

/*
 * See ticket [916c1095438eae56]: GetVersionExW triggers warnings
 */
#if defined(_MSC_VER)

#   pragma warning(disable:4146)
#   pragma warning(disable:4267)
#   pragma warning(disable:4244)
#   pragma warning(disable:4311)
#   pragma warning(disable:4312)
#   pragma warning(disable:4996)
#if !defined(_WIN64)







>







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

#define REDO_KEYSYM_LOOKUP

/*
 * See ticket [916c1095438eae56]: GetVersionExW triggers warnings
 */
#if defined(_MSC_VER)
#   pragma warning(disable:4090) /* see: https://developercommunity.visualstudio.com/t/c-compiler-incorrect-propagation-of-const-qualifie/390711 */
#   pragma warning(disable:4146)
#   pragma warning(disable:4267)
#   pragma warning(disable:4244)
#   pragma warning(disable:4311)
#   pragma warning(disable:4312)
#   pragma warning(disable:4996)
#if !defined(_WIN64)
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * The following Tk functions are implemented as macros under Windows.
 */

#define TkpGetPixel(p) (((((p)->red >> 8) & 0xff) \
	| ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000)

/*
 * Used by tkWindow.c
 */

#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)

/*
 * These calls implement native bitmaps which are not currently
 * supported under Windows.  The macros eliminate the calls.
 */

#define TkpDefineNativeBitmaps()
#define TkpCreateNativeBitmap(display, source) None
#define TkpGetNativeAppBitmap(display, name, w, h) None

#endif /* _WINPORT */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

120
121
122
123
124
125
126















127
/*
 * 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)
















#endif /* _WINPORT */

Changes to win/tkWinRegion.c.

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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * tkWinRegion.c --
 *
 *	Tk Region emulation code.
 *
 * 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"

272
273
274
275
276
277
278
























279
280
281
282
283
284
285
286
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF);
    return Success;
}

























/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCopyRegion --
 *
 *  Makes the destination region a copy of the source region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpCopyRegion(
    TkRegion dst,
    TkRegion src)
{
    CombineRgn((HRGN)dst, (HRGN)src, NULL, RGN_COPY);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinScrlbr.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkWinScrollbar.c --
 *
 *	This file implements the Windows specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"
#include "tkScrollbar.h"






|







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 © 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"
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
TCL_DECLARE_MUTEX(winScrlbrMutex)

/*
 * Declarations for functions defined in this file.
 */

static Window		CreateProc(Tk_Window tkwin, Window parent,
			    ClientData instanceData);
static void		ModalLoop(WinScrollbar *, XEvent *eventPtr);
static LRESULT CALLBACK	ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static void		UpdateScrollbar(WinScrollbar *scrollPtr);
static void		UpdateScrollbarMetrics(void);

/*
 * The class procedure table for the scrollbar widget.
 */

const Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,			/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL 			/* modalProc */
};

static void
WinScrollbarEventProc(ClientData clientData, XEvent *eventPtr)
{
    WinScrollbar *scrollPtr = (WinScrollbar *)clientData;

    if (eventPtr->type == ButtonPress) {
	ModalLoop(scrollPtr, eventPtr);
    } else {
	TkScrollbarEventProc(clientData, eventPtr);







|


















|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
TCL_DECLARE_MUTEX(winScrlbrMutex)

/*
 * Declarations for functions defined in this file.
 */

static Window		CreateProc(Tk_Window tkwin, Window parent,
			    void *instanceData);
static void		ModalLoop(WinScrollbar *, XEvent *eventPtr);
static LRESULT CALLBACK	ScrollbarProc(HWND hwnd, UINT message, WPARAM wParam,
			    LPARAM lParam);
static void		UpdateScrollbar(WinScrollbar *scrollPtr);
static void		UpdateScrollbarMetrics(void);

/*
 * The class procedure table for the scrollbar widget.
 */

const Tk_ClassProcs tkpScrollbarProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    NULL,			/* worldChangedProc */
    CreateProc,			/* createProc */
    NULL 			/* modalProc */
};

static void
WinScrollbarEventProc(void *clientData, XEvent *eventPtr)
{
    WinScrollbar *scrollPtr = (WinScrollbar *)clientData;

    if (eventPtr->type == ButtonPress) {
	ModalLoop(scrollPtr, eventPtr);
    } else {
	TkScrollbarEventProc(clientData, eventPtr);
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
 *----------------------------------------------------------------------
 */

static Window
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    ClientData instanceData)	/* Scrollbar instance data. */
{
    DWORD style;
    Window window;
    HWND parent;
    TkWindow *winPtr;
    WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;








|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
 *----------------------------------------------------------------------
 */

static Window
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    void *instanceData)	/* Scrollbar instance data. */
{
    DWORD style;
    Window window;
    HWND parent;
    TkWindow *winPtr;
    WinScrollbar *scrollPtr = (WinScrollbar *)instanceData;

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    WinScrollbar *scrollPtr = (WinScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->info.tkwin;

    scrollPtr->info.flags &= ~REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;







|







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
    void *clientData)	/* Information about window. */
{
    WinScrollbar *scrollPtr = (WinScrollbar *)clientData;
    Tk_Window tkwin = scrollPtr->info.tkwin;

    scrollPtr->info.flags &= ~REDRAW_PENDING;
    if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    int arrowWidth = GetSystemMetrics(SM_CXVSCROLL);

    hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
    hThumb = GetSystemMetrics(SM_CXHTHUMB);
    vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
    vThumb = GetSystemMetrics(SM_CYVTHUMB);

    sprintf(tkDefScrollbarWidth, "%d", arrowWidth);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --
 *







|







356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    int arrowWidth = GetSystemMetrics(SM_CXVSCROLL);

    hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
    hThumb = GetSystemMetrics(SM_CXHTHUMB);
    vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
    vThumb = GetSystemMetrics(SM_CYVTHUMB);

    snprintf(tkDefScrollbarWidth, sizeof(tkDefScrollbarWidth), "%d", arrowWidth);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --
 *
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

	    Tcl_PrintDouble(NULL, pos, valueString);
	    Tcl_DStringAppendElement(&cmdString, "moveto");
	    Tcl_DStringAppendElement(&cmdString, valueString);
	}

	interp = scrollPtr->info.interp;
	code = Tcl_EvalEx(interp, cmdString.string, -1, TCL_EVAL_GLOBAL);
	if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
	    Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
	    Tcl_BackgroundException(interp, code);
	}
	Tcl_DStringFree(&cmdString);

	Tcl_ServiceAll();







|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

	    Tcl_PrintDouble(NULL, pos, valueString);
	    Tcl_DStringAppendElement(&cmdString, "moveto");
	    Tcl_DStringAppendElement(&cmdString, valueString);
	}

	interp = scrollPtr->info.interp;
	code = Tcl_EvalEx(interp, cmdString.string, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) {
	    Tcl_AddErrorInfo(interp, "\n    (scrollbar command)");
	    Tcl_BackgroundException(interp, code);
	}
	Tcl_DStringFree(&cmdString);

	Tcl_ServiceAll();
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TkScrollbar *scrollPtr)
				/* Information about widget; may or may not
				 * already have values for some fields. */
{
    (void)scrollPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ModalLoop --
 *







|



<







587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TCL_UNUSED(TkScrollbar *))
				/* Information about widget; may or may not
				 * already have values for some fields. */
{

}

/*
 *----------------------------------------------------------------------
 *
 * ModalLoop --
 *

Changes to win/tkWinSend.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
/*
 * 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]>
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkWinSendCom.h"


/*
 * Should be defined in WTypes.h but mingw 1.0 is missing them.
 */

#ifndef _ROTFLAGS_DEFINED
#define _ROTFLAGS_DEFINED






|
|







>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * tkWinSend.c --
 *
 *	This file provides functions that implement the "send" command,
 *	allowing commands to be passed from interpreter to interpreter.
 *
 * Copyright © 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"
#include "tkWinInt.h"

/*
 * Should be defined in WTypes.h but mingw 1.0 is missing them.
 */

#ifndef _ROTFLAGS_DEFINED
#define _ROTFLAGS_DEFINED
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * Functions internal to this file.
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static void		CmdDeleteProc(ClientData clientData);
static void		InterpDeleteProc(ClientData clientData,
			    Tcl_Interp *interp);
static void		RevokeObjectRegistration(RegisteredInterp *riPtr);
#endif /* TK_SEND_ENABLED_ON_WINDOWS */
static HRESULT		BuildMoniker(const char *name, LPMONIKER *pmk);
#ifdef TK_SEND_ENABLED_ON_WINDOWS
static HRESULT		RegisterInterp(const char *name,
			    RegisteredInterp *riPtr);
#endif /* TK_SEND_ENABLED_ON_WINDOWS */
static int		FindInterpreterObject(Tcl_Interp *interp,
			    const char *name, LPDISPATCH *ppdisp);
static int		Send(LPDISPATCH pdispInterp, Tcl_Interp *interp,
			    int async, ClientData clientData, int objc,
			    Tcl_Obj *const objv[]);
static void		SendTrace(const char *format, ...);
static Tcl_EventProc	SendEventProc;

#if defined(DEBUG) || defined(_DEBUG)
#define TRACE SendTrace
#else







|
<
<










|







59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * Functions internal to this file.
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static Tcl_CmdDeleteProc CmdDeleteProc;


static void		RevokeObjectRegistration(RegisteredInterp *riPtr);
#endif /* TK_SEND_ENABLED_ON_WINDOWS */
static HRESULT		BuildMoniker(const char *name, LPMONIKER *pmk);
#ifdef TK_SEND_ENABLED_ON_WINDOWS
static HRESULT		RegisterInterp(const char *name,
			    RegisteredInterp *riPtr);
#endif /* TK_SEND_ENABLED_ON_WINDOWS */
static int		FindInterpreterObject(Tcl_Interp *interp,
			    const char *name, LPDISPATCH *ppdisp);
static int		Send(LPDISPATCH pdispInterp, Tcl_Interp *interp,
			    int async, void *clientData, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static void		SendTrace(const char *format, ...);
static Tcl_EventProc	SendEventProc;

#if defined(DEBUG) || defined(_DEBUG)
#define TRACE SendTrace
#else
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
     * Initialise the COM library for this interpreter just once.
     */

    if (tsdPtr->initialized == 0) {
	hr = CoInitialize(0);
	if (FAILED(hr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "failed to initialize the COM library", -1));
	    Tcl_SetErrorCode(interp, "TK", "SEND", "COM", NULL);
	    return "";
	}
	tsdPtr->initialized = 1;
	TRACE("Initialized COM library for interp 0x%" TCL_Z_MODIFIER "x\n", (size_t)interp);
    }








|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
     * Initialise the COM library for this interpreter just once.
     */

    if (tsdPtr->initialized == 0) {
	hr = CoInitialize(0);
	if (FAILED(hr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "failed to initialize the COM library", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "SEND", "COM", NULL);
	    return "";
	}
	tsdPtr->initialized = 1;
	TRACE("Initialized COM library for interp 0x%" TCL_Z_MODIFIER "x\n", (size_t)interp);
    }

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
 *
 *----------------------------------------------------------------------
 */

int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
				 * lookup. */
{
#ifndef TK_SEND_ENABLED_ON_WINDOWS
    (void)interp;
    (void)tkwin;
    /*
     * Temporarily disabled for bug #858822
     */

    return TCL_OK;
#else /* TK_SEND_ENABLED_ON_WINDOWS */








|




<







206
207
208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
 *
 *----------------------------------------------------------------------
 */

int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    TCL_UNUSED(Tk_Window))	/* Window whose display is to be used for the
				 * lookup. */
{
#ifndef TK_SEND_ENABLED_ON_WINDOWS
    (void)interp;

    /*
     * Temporarily disabled for bug #858822
     */

    return TCL_OK;
#else /* TK_SEND_ENABLED_ON_WINDOWS */

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345


346
347
348
349
350
351
352
353
354
355



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    ClientData clientData,	/* Information about sender (only dispPtr
				 * field is used). */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };

    int result = TCL_OK;
    int i, optind, async = 0;
    Tcl_Obj *displayPtr = NULL;

    /*
     * Process the command options.
     */

    for (i = 1; i < objc; i++) {


	if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		sizeof(char *), "option", 0, &optind) != TCL_OK) {
	    break;
	}
	if (optind == SEND_ASYNC) {
	    ++async;
	} else if (optind == SEND_DISPLAYOF) {
	    displayPtr = objv[++i];
	} else if (optind == SEND_LAST) {
	    i++;



	    break;
	}
    }

    /*
     * Ensure we still have a valid command.
     */

    if ((objc - i) < 2) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-async? ?-displayof? ?--? interpName arg ?arg ...?");
	result = TCL_ERROR;
    }

    /*
     * We don't support displayPtr. See TIP #150.
     */

    if (displayPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"option not implemented: \"displayof\" is not available"
		" for this platform.", -1));
	Tcl_SetErrorCode(interp, "TK", "SEND", "DISPLAYOF_WIN", NULL);
	result = TCL_ERROR;
    }

    /*
     * Send the arguments to the foreign interp.
     */
    /* FIX ME: we need to check for local interp */
    if (result == TCL_OK) {
	LPDISPATCH pdisp;








|











>

|
<





|
>
>
|
|
|
|
|
|
|
|
|
|
>
>
>








|





<
<
<
<
<
<
<
<
<
<
<
<







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372












373
374
375
376
377
378
379
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    void *clientData,	/* Information about sender (only dispPtr
				 * field is used). */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    enum {
	SEND_ASYNC, SEND_DISPLAYOF, SEND_LAST
    };
    static const char *const sendOptions[] = {
	"-async",   "-displayof",   "--",  NULL
    };
    const char *stringRep;
    int result = TCL_OK;
    int i, async = 0, index;


    /*
     * Process the command options.
     */

    for (i = 1; i < (objc - 1); i++) {
	stringRep = Tcl_GetString(objv[i]);
	if (stringRep[0] == '-') {
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		break;
	    }
	    if (index == SEND_ASYNC) {
		async = 1;
	    } else if (index == SEND_DISPLAYOF) {
		i++;
	    } else /* if (index == SEND_LAST) */ {
		i++;
		break;
	    }
	} else {
	    break;
	}
    }

    /*
     * Ensure we still have a valid command.
     */

    if (objc < (i + 2)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-async? ?-displayof? ?--? interpName arg ?arg ...?");
	result = TCL_ERROR;
    }













    /*
     * Send the arguments to the foreign interp.
     */
    /* FIX ME: we need to check for local interp */
    if (result == TCL_OK) {
	LPDISPATCH pdisp;

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
 *
 *--------------------------------------------------------------
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static void
CmdDeleteProc(
    ClientData clientData)
{
    RegisteredInterp *riPtr = (RegisteredInterp *)clientData;

    /*
     * Lock the package structure in memory.
     */








|







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
 *
 *--------------------------------------------------------------
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static void
CmdDeleteProc(
    void *clientData)
{
    RegisteredInterp *riPtr = (RegisteredInterp *)clientData;

    /*
     * Lock the package structure in memory.
     */

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
    }
}
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * ----------------------------------------------------------------------
 *
 * InterpDeleteProc --
 *
 *	This is called when the interpreter is deleted and used to unregister
 *	the COM libraries.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 * ----------------------------------------------------------------------
 */

#ifdef TK_SEND_ENABLED_ON_WINDOWS
static void
InterpDeleteProc(
    ClientData clientData,
    Tcl_Interp *interp)
{
    CoUninitialize();
}
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * ----------------------------------------------------------------------
 *
 * BuildMoniker --
 *
 *	Construct a moniker from the given name. This ensures that all our
 *	monikers have the same prefix.
 *
 * Results:
 *	S_OK. If the name cannot be turned into a moniker then a COM error







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







557
558
559
560
561
562
563



























564
565
566
567
568
569
570
    }
}
#endif /* TK_SEND_ENABLED_ON_WINDOWS */

/*
 * ----------------------------------------------------------------------
 *



























 * BuildMoniker --
 *
 *	Construct a moniker from the given name. This ensures that all our
 *	monikers have the same prefix.
 *
 * Results:
 *	S_OK. If the name cannot be turned into a moniker then a COM error
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    HRESULT hr = CreateFileMoniker(TKWINSEND_REGISTRATION_BASE, &pmkClass);

    if (SUCCEEDED(hr)) {
	LPMONIKER pmkItem = NULL;
	Tcl_DString dString;

	Tcl_DStringInit(&dString);
	Tcl_UtfToWCharDString(name, -1, &dString);
	hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem);
	Tcl_DStringFree(&dString);
	if (SUCCEEDED(hr)) {
	    hr = pmkClass->lpVtbl->ComposeWith(pmkClass, pmkItem, FALSE, ppmk);
	    pmkItem->lpVtbl->Release(pmkItem);
	}
	pmkClass->lpVtbl->Release(pmkClass);







|







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
    HRESULT hr = CreateFileMoniker(TKWINSEND_REGISTRATION_BASE, &pmkClass);

    if (SUCCEEDED(hr)) {
	LPMONIKER pmkItem = NULL;
	Tcl_DString dString;

	Tcl_DStringInit(&dString);
	Tcl_UtfToWCharDString(name, TCL_INDEX_NONE, &dString);
	hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem);
	Tcl_DStringFree(&dString);
	if (SUCCEEDED(hr)) {
	    hr = pmkClass->lpVtbl->ComposeWith(pmkClass, pmkItem, FALSE, ppmk);
	    pmkItem->lpVtbl->Release(pmkItem);
	}
	pmkClass->lpVtbl->Release(pmkClass);
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
    hr = GetRunningObjectTable(0, &pROT);
    if (SUCCEEDED(hr)) {
	offset = 0;
	for (i = 1; SUCCEEDED(hr); i++) {
	    if (i > 1) {
		if (i == 2) {
		    Tcl_DStringInit(&dString);
		    Tcl_DStringAppend(&dString, name, -1);
		    Tcl_DStringAppend(&dString, " #", 2);
		    offset = Tcl_DStringLength(&dString);
		    Tcl_DStringSetLength(&dString, offset+TCL_INTEGER_SPACE);
		    actualName = Tcl_DStringValue(&dString);
		}
		sprintf(Tcl_DStringValue(&dString) + offset, "%d", i);
	    }

	    hr = BuildMoniker(actualName, &pmk);
	    if (SUCCEEDED(hr)) {

		hr = pROT->lpVtbl->Register(pROT,
		    ROTFLAGS_REGISTRATIONKEEPSALIVE,







|


|


|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    hr = GetRunningObjectTable(0, &pROT);
    if (SUCCEEDED(hr)) {
	offset = 0;
	for (i = 1; SUCCEEDED(hr); i++) {
	    if (i > 1) {
		if (i == 2) {
		    Tcl_DStringInit(&dString);
		    Tcl_DStringAppend(&dString, name, TCL_INDEX_NONE);
		    Tcl_DStringAppend(&dString, " #", 2);
		    offset = Tcl_DStringLength(&dString);
		    Tcl_DStringSetLength(&dString, offset + TCL_INTEGER_SPACE);
		    actualName = Tcl_DStringValue(&dString);
		}
		snprintf(Tcl_DStringValue(&dString) + offset, TCL_INTEGER_SPACE, "%d", i);
	    }

	    hr = BuildMoniker(actualName, &pmk);
	    if (SUCCEEDED(hr)) {

		hr = pROT->lpVtbl->Register(pROT,
		    ROTFLAGS_REGISTRATIONKEEPSALIVE,
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

static int
Send(
    LPDISPATCH pdispInterp,	/* Pointer to the remote interp's COM
				 * object. */
    Tcl_Interp *interp,		/* The local interpreter. */
    int async,			/* Flag for the calling style. */
    ClientData dummy,	/* The RegisteredInterp structure for this
				 * interp. */
    int objc,			/* Number of arguments to be sent. */
    Tcl_Obj *const objv[])	/* The arguments to be sent. */
{
    VARIANT vCmd, vResult;
    DISPPARAMS dp;
    EXCEPINFO ei;
    UINT uiErr = 0;
    HRESULT hr = S_OK, ehr = S_OK;
    Tcl_Obj *cmd = NULL;
    DISPID dispid;
    Tcl_DString ds;
    const char *src;
    (void)dummy;

    cmd = Tcl_ConcatObj(objc, objv);

    /*
     * Setup the arguments for the COM method call.
     */








<
|
|











<







699
700
701
702
703
704
705

706
707
708
709
710
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725

static int
Send(
    LPDISPATCH pdispInterp,	/* Pointer to the remote interp's COM
				 * object. */
    Tcl_Interp *interp,		/* The local interpreter. */
    int async,			/* Flag for the calling style. */

    TCL_UNUSED(void *),
    Tcl_Size objc,			/* Number of arguments to be sent. */
    Tcl_Obj *const objv[])	/* The arguments to be sent. */
{
    VARIANT vCmd, vResult;
    DISPPARAMS dp;
    EXCEPINFO ei;
    UINT uiErr = 0;
    HRESULT hr = S_OK, ehr = S_OK;
    Tcl_Obj *cmd = NULL;
    DISPID dispid;
    Tcl_DString ds;
    const char *src;


    cmd = Tcl_ConcatObj(objc, objv);

    /*
     * Setup the arguments for the COM method call.
     */

966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
 *
 * ----------------------------------------------------------------------
 */

static int
SendEventProc(
    Tcl_Event *eventPtr,
    int flags)
{
    SendEvent *evPtr = (SendEvent *)eventPtr;
    (void)flags;

    TRACE("SendEventProc\n");

    Tcl_EvalObjEx(evPtr->interp, evPtr->cmdPtr,
	    TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);

    Tcl_DecrRefCount(evPtr->cmdPtr);







|


<







928
929
930
931
932
933
934
935
936
937

938
939
940
941
942
943
944
 *
 * ----------------------------------------------------------------------
 */

static int
SendEventProc(
    Tcl_Event *eventPtr,
    TCL_UNUSED(int))
{
    SendEvent *evPtr = (SendEvent *)eventPtr;


    TRACE("SendEventProc\n");

    Tcl_EvalObjEx(evPtr->interp, evPtr->cmdPtr,
	    TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);

    Tcl_DecrRefCount(evPtr->cmdPtr);

Changes to win/tkWinSendCom.c.

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]>
 *
 * 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"







|







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 © 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"
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
 *
 * ----------------------------------------------------------------------
 */
static void
TkWinSendCom_Destroy(
    LPDISPATCH pdisp)
{
    CoTaskMemFree((void *) pdisp);
}

/*
 * ----------------------------------------------------------------------
 *
 * IDispatch --
 *







|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
 *
 * ----------------------------------------------------------------------
 */
static void
TkWinSendCom_Destroy(
    LPDISPATCH pdisp)
{
    CoTaskMemFree(pdisp);
}

/*
 * ----------------------------------------------------------------------
 *
 * IDispatch --
 *
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    (void)puArgErr;

    VariantInit(&vCmd);

    hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR);
    if (FAILED(hr)) {
	Tcl_SetObjResult(obj->interp, Tcl_NewStringObj(
		"invalid args: Async(command)", -1));
	TkWinSend_SetExcepInfo(obj->interp, pExcepInfo);
	hr = DISP_E_EXCEPTION;
    }

    if (SUCCEEDED(hr) && obj->interp) {
	Tcl_Obj *scriptPtr;








|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    (void)puArgErr;

    VariantInit(&vCmd);

    hr = VariantChangeType(&vCmd, &Cmd, 0, VT_BSTR);
    if (FAILED(hr)) {
	Tcl_SetObjResult(obj->interp, Tcl_NewStringObj(
		"invalid args: Async(command)", TCL_INDEX_NONE));
	TkWinSend_SetExcepInfo(obj->interp, pExcepInfo);
	hr = DISP_E_EXCEPTION;
    }

    if (SUCCEEDED(hr) && obj->interp) {
	Tcl_Obj *scriptPtr;

Changes to win/tkWinSendCom.h.

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]>
 *
 * 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







|







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 © 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
/*
 * 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()

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(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), TCL_INDEX_NONE, &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", 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];
            snprintf(buffer, 100, "\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(
    void *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(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(
    void *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[] = {
        "-callback", "-image", "-text", NULL
    };
    enum { OPT_CALLBACK, OPT_IMAGE, OPT_TEXT };
    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\"", TCL_INDEX_NONE));
                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(
    void *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, TCL_INDEX_NONE, &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, TCL_INDEX_NONE, &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;

    mainWindow = Tk_MainWindow(interp);
    if (mainWindow == NULL) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj("main window has been destroyed", TCL_INDEX_NONE));
        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,
            icoInterpPtr, NULL);
    Tcl_CreateObjCommand(interp, "::tk::sysnotify::_sysnotify", WinSysNotifyCmd,
            icoInterpPtr, NULL);

    Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
            WinIcoDestroy, 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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#undef USE_TCL_STUBS
#define USE_TCL_STUBS
#undef USE_TK_STUBS
#define USE_TK_STUBS
#include "tkWinInt.h"

HWND tkWinCurrentDialog;

/*
 * Forward declarations of functions defined later in this file:
 */

static int		TestclipboardObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwineventObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestfindwindowObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestgetwindowinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwinlocaleObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static Tk_GetSelProc		SetSelectionResult;

/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for Windows






|
|
|

















|
<
<
|
<
<
|
<
<
|
<
<
|
<
<
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27


28


29


30


31


32
33
34
35
36
37
38
39
/*
 * tkWinTest.c --
 *
 *	Contains commands for platform specific tests for the Windows
 *	platform.
 *
 * 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
#undef USE_TK_STUBS
#define USE_TK_STUBS
#include "tkWinInt.h"

HWND tkWinCurrentDialog;

/*
 * Forward declarations of functions defined later in this file:
 */

static Tcl_ObjCmdProc TestclipboardObjCmd;


static Tcl_ObjCmdProc TestwineventObjCmd;


static Tcl_ObjCmdProc TestfindwindowObjCmd;


static Tcl_ObjCmdProc TestgetwindowinfoObjCmd;


static Tcl_ObjCmdProc TestwinlocaleObjCmd;


static Tk_GetSelProc SetSelectionResult;

/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for Windows
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
	    LocalFree(msgPtr);
	}
    }
    if (length == 0) {
	if (error == ERROR_CALL_NOT_IMPLEMENTED) {
	    strcpy(msgBuf, "function not supported under Win32s");
	} else {
	    sprintf(msgBuf, "unknown error: %ld", error);
	}
	msg = msgBuf;
    } else {
	char *msgPtr;

	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(wMsgPtr, wcslen(wMsgPtr), &ds);







|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
	    LocalFree(msgPtr);
	}
    }
    if (length == 0) {
	if (error == ERROR_CALL_NOT_IMPLEMENTED) {
	    strcpy(msgBuf, "function not supported under Win32s");
	} else {
	    snprintf(msgBuf, sizeof(msgBuf), "unknown error: %ld", error);
	}
	msg = msgBuf;
    } else {
	char *msgPtr;

	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(wMsgPtr, wcslen(wMsgPtr), &ds);
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
	if (msgPtr[length-1] == '\r') {
	    --length;
	}
	msgPtr[length] = 0;
	msg = msgPtr;
    }

    sprintf(id, "%ld", error);
    Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL);
    Tcl_AppendToObj(resultPtr, msg, length);
    Tcl_SetObjResult(interp, resultPtr);

    if (length != 0) {
	Tcl_DStringFree(&ds);
    }







|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
	if (msgPtr[length-1] == '\r') {
	    --length;
	}
	msgPtr[length] = 0;
	msg = msgPtr;
    }

    snprintf(id, sizeof(id), "%ld", error);
    Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL);
    Tcl_AppendToObj(resultPtr, msg, length);
    Tcl_SetObjResult(interp, resultPtr);

    if (length != 0) {
	Tcl_DStringFree(&ds);
    }
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SetSelectionResult(
    ClientData dummy,
    Tcl_Interp *interp,
    const char *selection)
{
    (void)dummy;

    Tcl_AppendResult(interp, selection, NULL);
    return TCL_OK;
}

static int
TestclipboardObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_Window tkwin = (Tk_Window)clientData;

    if (objc != 1) {







|



<
<






|







213
214
215
216
217
218
219
220
221
222
223


224
225
226
227
228
229
230
231
232
233
234
235
236
237
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SetSelectionResult(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    const char *selection)
{


    Tcl_AppendResult(interp, selection, NULL);
    return TCL_OK;
}

static int
TestclipboardObjCmd(
    void *clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_Window tkwin = (Tk_Window)clientData;

    if (objc != 1) {
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwineventObjCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    HWND hwnd = 0;
    HWND child = 0;
    HWND control;







|







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwineventObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    HWND hwnd = 0;
    HWND child = 0;
    HWND control;
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
	{WM_XBUTTONDBLCLK,		"WM_XBUTTONDBLCLK"},
	{WM_CHAR,		"WM_CHAR"},
	{WM_GETTEXT,		"WM_GETTEXT"},
	{WM_SETTEXT,		"WM_SETTEXT"},
	{WM_COMMAND,            "WM_COMMAND"},
	{-1,			NULL}
    };
    (void)dummy;

    if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]), "debug") == 0)) {
	int b;

	if (Tcl_GetBoolean(interp, Tcl_GetString(objv[2]), &b) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkWinDialogDebug(b);
	return TCL_OK;
    }

    if (objc < 4) {
	return TCL_ERROR;
    }

    hwnd = (HWND)INT2PTR(strtol(Tcl_GetString(objv[1]), &rest, 0));
    if (rest == Tcl_GetString(objv[1])) {
	hwnd = FindWindowA(NULL, Tcl_GetString(objv[1]));
	if (hwnd == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("no such window", -1));
	    return TCL_ERROR;
	}
    }
    UpdateWindow(hwnd);

    id = strtol(Tcl_GetString(objv[2]), &rest, 0);
    if (rest == Tcl_GetString(objv[2])) {







<




|














|







290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	{WM_XBUTTONDBLCLK,		"WM_XBUTTONDBLCLK"},
	{WM_CHAR,		"WM_CHAR"},
	{WM_GETTEXT,		"WM_GETTEXT"},
	{WM_SETTEXT,		"WM_SETTEXT"},
	{WM_COMMAND,            "WM_COMMAND"},
	{-1,			NULL}
    };


    if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]), "debug") == 0)) {
	int b;

	if (Tcl_GetBooleanFromObj(interp, objv[2], &b) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkWinDialogDebug(b);
	return TCL_OK;
    }

    if (objc < 4) {
	return TCL_ERROR;
    }

    hwnd = (HWND)INT2PTR(strtol(Tcl_GetString(objv[1]), &rest, 0));
    if (rest == Tcl_GetString(objv[1])) {
	hwnd = FindWindowA(NULL, Tcl_GetString(objv[1]));
	if (hwnd == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("no such window", TCL_INDEX_NONE));
	    return TCL_ERROR;
	}
    }
    UpdateWindow(hwnd);

    id = strtol(Tcl_GetString(objv[2]), &rest, 0);
    if (rest == Tcl_GetString(objv[2])) {
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
                             Tcl_ObjPrintf("Could not find control with id %d", id));
            return TCL_ERROR;
        }
        buf[0] = 0;
        SendMessageA(control, WM_GETTEXT, (WPARAM)sizeof(buf),
                     (LPARAM) buf);
#endif
	Tcl_ExternalToUtfDString(NULL, buf, -1, &ds);
	Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL);
	Tcl_DStringFree(&ds);
	break;
    }
    case WM_SETTEXT: {
	Tcl_DString ds;

	control = TestFindControl(hwnd, id);
	if (control == NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_ObjPrintf("Could not find control with id %d", id));
	    return TCL_ERROR;
	}
	Tcl_DStringInit(&ds);
	Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[4]), -1, &ds);
	result = SendMessageA(control, WM_SETTEXT, 0,
		(LPARAM) Tcl_DStringValue(&ds));
	Tcl_DStringFree(&ds);
	if (result == 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", -1));
	    AppendSystemError(interp, GetLastError());
	    return TCL_ERROR;
	}
	break;
    }
    case WM_COMMAND: {
	char buf[TCL_INTEGER_SPACE];
	if (objc < 5) {
	    wParam = MAKEWPARAM(id, 0);
	    lParam = (LPARAM)child;
	}
	sprintf(buf, "%d", (int) SendMessageA(hwnd, message, wParam, lParam));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
	break;
    }
    default: {
	char buf[TCL_INTEGER_SPACE];

	sprintf(buf, "%d",
		(int) SendDlgItemMessageA(hwnd, id, message, wParam, lParam));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
	break;
    }
    }
    return TCL_OK;
}

/*
 *  testfindwindow title ?class?
 *	Find a Windows window using the FindWindow API call. This takes the window
 *	title and optionally the window class and if found returns the HWND and
 *	raises an error if the window is not found.
 *	eg: testfindwindow Console TkTopLevel
 *	    Can find the console window if it is visible.
 *	eg: testfindwindow "TkTest #10201" "#32770"
 *	    Can find a messagebox window with this title.
 */

static int
TestfindwindowObjCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
	LPCWSTR title = NULL, windowClass = NULL;
    Tcl_DString titleString, classString;
    HWND hwnd = NULL;
    int r = TCL_OK;
    DWORD myPid;
    (void)dummy;

    Tcl_DStringInit(&classString);
    Tcl_DStringInit(&titleString);

    if (objc < 2 || objc > 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "title ?class?");
        return TCL_ERROR;
    }

    Tcl_DStringInit(&titleString);
    title = Tcl_UtfToWCharDString(Tcl_GetString(objv[1]), -1, &titleString);
    if (objc == 3) {
	Tcl_DStringInit(&classString);
	windowClass = Tcl_UtfToWCharDString(Tcl_GetString(objv[2]), -1, &classString);
    }
    if (title[0] == 0)
        title = NULL;
    /* We want find a window the belongs to us and not some other process */
    hwnd = NULL;
    myPid = GetCurrentProcessId();
    while (1) {







<
|













|
|
<


|











|
|





|

|



















|









<










|


|







364
365
366
367
368
369
370

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
                             Tcl_ObjPrintf("Could not find control with id %d", id));
            return TCL_ERROR;
        }
        buf[0] = 0;
        SendMessageA(control, WM_GETTEXT, (WPARAM)sizeof(buf),
                     (LPARAM) buf);
#endif

	Tcl_AppendResult(interp, Tcl_ExternalToUtfDString(NULL, buf, TCL_INDEX_NONE, &ds), NULL);
	Tcl_DStringFree(&ds);
	break;
    }
    case WM_SETTEXT: {
	Tcl_DString ds;

	control = TestFindControl(hwnd, id);
	if (control == NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_ObjPrintf("Could not find control with id %d", id));
	    return TCL_ERROR;
	}
	Tcl_DStringInit(&ds);
	LPARAM lparam = (LPARAM)Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[4]), TCL_INDEX_NONE, &ds);
	result = SendMessageA(control, WM_SETTEXT, 0, lparam);

	Tcl_DStringFree(&ds);
	if (result == 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to send text to dialog: ", TCL_INDEX_NONE));
	    AppendSystemError(interp, GetLastError());
	    return TCL_ERROR;
	}
	break;
    }
    case WM_COMMAND: {
	char buf[TCL_INTEGER_SPACE];
	if (objc < 5) {
	    wParam = MAKEWPARAM(id, 0);
	    lParam = (LPARAM)child;
	}
	snprintf(buf, sizeof(buf), "%d", (int) SendMessageA(hwnd, message, wParam, lParam));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
	break;
    }
    default: {
	char buf[TCL_INTEGER_SPACE];

	snprintf(buf, sizeof(buf), "%d",
		(int) SendDlgItemMessageA(hwnd, id, message, wParam, lParam));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
	break;
    }
    }
    return TCL_OK;
}

/*
 *  testfindwindow title ?class?
 *	Find a Windows window using the FindWindow API call. This takes the window
 *	title and optionally the window class and if found returns the HWND and
 *	raises an error if the window is not found.
 *	eg: testfindwindow Console TkTopLevel
 *	    Can find the console window if it is visible.
 *	eg: testfindwindow "TkTest #10201" "#32770"
 *	    Can find a messagebox window with this title.
 */

static int
TestfindwindowObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
	LPCWSTR title = NULL, windowClass = NULL;
    Tcl_DString titleString, classString;
    HWND hwnd = NULL;
    int r = TCL_OK;
    DWORD myPid;


    Tcl_DStringInit(&classString);
    Tcl_DStringInit(&titleString);

    if (objc < 2 || objc > 3) {
        Tcl_WrongNumArgs(interp, 1, objv, "title ?class?");
        return TCL_ERROR;
    }

    Tcl_DStringInit(&titleString);
    title = Tcl_UtfToWCharDString(Tcl_GetString(objv[1]), TCL_INDEX_NONE, &titleString);
    if (objc == 3) {
	Tcl_DStringInit(&classString);
	windowClass = Tcl_UtfToWCharDString(Tcl_GetString(objv[2]), TCL_INDEX_NONE, &classString);
    }
    if (title[0] == 0)
        title = NULL;
    /* We want find a window the belongs to us and not some other process */
    hwnd = NULL;
    myPid = GetCurrentProcessId();
    while (1) {
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
            break;
        }
        if (pid == myPid)
            break;              /* Found it */
    }

    if (hwnd == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to find window: ", -1));
	AppendSystemError(interp, GetLastError());
	r = TCL_ERROR;
    } else {
        Tcl_SetObjResult(interp, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    }

    Tcl_DStringFree(&titleString);







|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
            break;
        }
        if (pid == myPid)
            break;              /* Found it */
    }

    if (hwnd == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to find window: ", TCL_INDEX_NONE));
	AppendSystemError(interp, GetLastError());
	r = TCL_ERROR;
    } else {
        Tcl_SetObjResult(interp, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    }

    Tcl_DStringFree(&titleString);
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

    Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    return TRUE;
}

static int
TestgetwindowinfoObjCmd(
    ClientData dummy,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_WideInt hwnd;
    Tcl_Obj *dictObj = NULL, *classObj = NULL, *textObj = NULL;
    Tcl_Obj *childrenObj = NULL;
    WCHAR buf[512];
    int cch, cchBuf = 256;
    Tcl_DString ds;
    (void)dummy;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "hwnd");
	return TCL_ERROR;
    }

    if (Tcl_GetWideIntFromObj(interp, objv[1], &hwnd) != TCL_OK)
	return TCL_ERROR;

    cch = GetClassNameW((HWND)INT2PTR(hwnd), buf, cchBuf);
    if (cch == 0) {
    	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to get class name: ", -1));
    	AppendSystemError(interp, GetLastError());
    	return TCL_ERROR;
    } else {
	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(buf, wcslen(buf), &ds);
	classObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);







|










<











|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531

    Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    return TRUE;
}

static int
TestgetwindowinfoObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_WideInt hwnd;
    Tcl_Obj *dictObj = NULL, *classObj = NULL, *textObj = NULL;
    Tcl_Obj *childrenObj = NULL;
    WCHAR buf[512];
    int cch, cchBuf = 256;
    Tcl_DString ds;


    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "hwnd");
	return TCL_ERROR;
    }

    if (Tcl_GetWideIntFromObj(interp, objv[1], &hwnd) != TCL_OK)
	return TCL_ERROR;

    cch = GetClassNameW((HWND)INT2PTR(hwnd), buf, cchBuf);
    if (cch == 0) {
    	Tcl_SetObjResult(interp, Tcl_NewStringObj("failed to get class name: ", TCL_INDEX_NONE));
    	AppendSystemError(interp, GetLastError());
    	return TCL_ERROR;
    } else {
	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(buf, wcslen(buf), &ds);
	classObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589

    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6),
	Tcl_NewWideIntObj(PTR2INT(GetParent((HWND)(size_t)hwnd))));

    childrenObj = Tcl_NewListObj(0, NULL);
    EnumChildWindows((HWND)(size_t)hwnd, EnumChildrenProc, (LPARAM)childrenObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("children", -1), childrenObj);

    Tcl_SetObjResult(interp, dictObj);
    return TCL_OK;
}

static int
TestwinlocaleObjCmd(
    ClientData dummy,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    (void)dummy;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetThreadLocale()));
    return TCL_OK;
}







|







|




<
<







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563


564
565
566
567
568
569
570

    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6),
	Tcl_NewWideIntObj(PTR2INT(GetParent((HWND)(size_t)hwnd))));

    childrenObj = Tcl_NewListObj(0, NULL);
    EnumChildWindows((HWND)(size_t)hwnd, EnumChildrenProc, (LPARAM)childrenObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("children", TCL_INDEX_NONE), childrenObj);

    Tcl_SetObjResult(interp, dictObj);
    return TCL_OK;
}

static int
TestwinlocaleObjCmd(
    TCL_UNUSED(void *),	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{


    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetThreadLocale()));
    return TCL_OK;
}

Changes to win/tkWinWindow.c.

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.
 *
 * 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"






|







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 © 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"
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold the
				 * hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    HWND hwnd = (window) ? Tk_GetHWND(window) : 0;

    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *







|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
TkpPrintWindowId(
    char *buf,			/* Pointer to string large enough to hold the
				 * hex representation of a pointer. */
    Window window)		/* Window to be printed into buffer. */
{
    HWND hwnd = (window) ? Tk_GetHWND(window) : 0;

    snprintf(buf, TCL_INTEGER_SPACE, "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeWindow --
 *
 *	Creates a Windows window object based on the current attributes of the
 *	specified TkWindow.
 *
 * Results:
 *	Returns a pointer to a new TkWinDrawable cast to a Window.
 *
 * Side effects:
 *	Creates a new window.
 *
 *----------------------------------------------------------------------
 */

Window
TkpMakeWindow(
    TkWindow *winPtr,
    Window parent)
{
    HWND parentWin;
    int style;
    HWND hwnd;


    if (parent != None) {
	parentWin = Tk_GetHWND(parent);
	style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    } else {
	parentWin = NULL;
	style = WS_POPUP | WS_CLIPCHILDREN;







|














|
|





>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MakeWindow --
 *
 *	Creates a Windows window object based on the current attributes of the
 *	specified TkWindow.
 *
 * Results:
 *	Returns a pointer to a new TkWinDrawable cast to a Window.
 *
 * Side effects:
 *	Creates a new window.
 *
 *----------------------------------------------------------------------
 */

Window
Tk_MakeWindow(
    Tk_Window tkwin,
    Window parent)
{
    HWND parentWin;
    int style;
    HWND hwnd;
    TkWindow *winPtr = (TkWindow *)tkwin;

    if (parent != None) {
	parentWin = Tk_GetHWND(parent);
	style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    } else {
	parentWin = NULL;
	style = WS_POPUP | WS_CLIPCHILDREN;
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    Tcl_HashEntry *entryPtr;
    TkWinDrawable *twdPtr = (TkWinDrawable *)w;
    TkWindow *winPtr = TkWinGetWinPtr(w);
    HWND hwnd = Tk_GetHWND(w);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    display->request++;

    /*
     * Remove references to the window in the pointer module then release the
     * drawable.
     */

    TkPointerDeadWindow(winPtr);







|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    Tcl_HashEntry *entryPtr;
    TkWinDrawable *twdPtr = (TkWinDrawable *)w;
    TkWindow *winPtr = TkWinGetWinPtr(w);
    HWND hwnd = Tk_GetHWND(w);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    LastKnownRequestProcessed(display)++;

    /*
     * Remove references to the window in the pointer module then release the
     * drawable.
     */

    TkPointerDeadWindow(winPtr);
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359




360
361
362
363
364
365
366
367
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	Cause the given window to become visible.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Causes the window state to change, and generates a MapNotify event.
 *
 *----------------------------------------------------------------------
 */

int
XMapWindow(
    Display *display,
    Window w)
{
    XEvent event;
    TkWindow *parentPtr;
    TkWindow *winPtr = TkWinGetWinPtr(w);





    display->request++;

    ShowWindow(Tk_GetHWND(w), SW_SHOWNORMAL);
    winPtr->flags |= TK_MAPPED;

    /*
     * Check to see if this window is visible now. If all of the parent
     * windows up to the first toplevel are mapped, then this window and its







|














|

>
>
>
>
|







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	Cause the given window to become visible.
 *
 * Results:
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	Causes the window state to change, and generates a MapNotify event.
 *
 *----------------------------------------------------------------------
 */

int
XMapWindow(
    Display *display,
    Window w)
{
    XEvent event;
    TkWindow *parentPtr;
    TkWindow *winPtr;

    if (!w) {
	return BadWindow;
    }
    winPtr = TkWinGetWinPtr(w);
    LastKnownRequestProcessed(display)++;

    ShowWindow(Tk_GetHWND(w), SW_SHOWNORMAL);
    winPtr->flags |= TK_MAPPED;

    /*
     * Check to see if this window is visible now. If all of the parent
     * windows up to the first toplevel are mapped, then this window and its
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
	    }
	    if (parentPtr->flags & TK_TOP_HIERARCHY) {
		break;
	    }
	}
    } else {
	event.type = MapNotify;
	event.xmap.serial = display->request;
	event.xmap.send_event = False;
	event.xmap.display = display;
	event.xmap.event = winPtr->window;
	event.xmap.window = winPtr->window;
	event.xmap.override_redirect = winPtr->atts.override_redirect;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    }

    /*
     * Generate VisibilityNotify events for this window and its mapped
     * children.
     */

    event.type = VisibilityNotify;
    event.xvisibility.serial = display->request;
    event.xvisibility.send_event = False;
    event.xvisibility.display = display;
    event.xvisibility.window = winPtr->window;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(&event, winPtr);
    return Success;
}







|














|







381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
	    }
	    if (parentPtr->flags & TK_TOP_HIERARCHY) {
		break;
	    }
	}
    } else {
	event.type = MapNotify;
	event.xmap.serial = LastKnownRequestProcessed(display);
	event.xmap.send_event = False;
	event.xmap.display = display;
	event.xmap.event = winPtr->window;
	event.xmap.window = winPtr->window;
	event.xmap.override_redirect = winPtr->atts.override_redirect;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    }

    /*
     * Generate VisibilityNotify events for this window and its mapped
     * children.
     */

    event.type = VisibilityNotify;
    event.xvisibility.serial = LastKnownRequestProcessed(display);
    event.xvisibility.send_event = False;
    event.xvisibility.display = display;
    event.xvisibility.window = winPtr->window;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(&event, winPtr);
    return Success;
}
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467




468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
 *----------------------------------------------------------------------
 *
 * XUnmapWindow --
 *
 *	Cause the given window to become invisible.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Causes the window state to change, and generates an UnmapNotify event.
 *
 *----------------------------------------------------------------------
 */

int
XUnmapWindow(
    Display *display,
    Window w)
{
    XEvent event;
    TkWindow *winPtr = TkWinGetWinPtr(w);





    display->request++;

    /*
     * Bug fix: Don't short circuit this routine based on TK_MAPPED because it
     * will be cleared before XUnmapWindow is called.
     */

    ShowWindow(Tk_GetHWND(w), SW_HIDE);
    winPtr->flags &= ~TK_MAPPED;

    if (winPtr->flags & TK_WIN_MANAGED) {
	event.type = UnmapNotify;
	event.xunmap.serial = display->request;
	event.xunmap.send_event = False;
	event.xunmap.display = display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	Tk_HandleEvent(&event);
    }







|













|

>
>
>
>
|











|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 *----------------------------------------------------------------------
 *
 * XUnmapWindow --
 *
 *	Cause the given window to become invisible.
 *
 * Results:
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	Causes the window state to change, and generates an UnmapNotify event.
 *
 *----------------------------------------------------------------------
 */

int
XUnmapWindow(
    Display *display,
    Window w)
{
    XEvent event;
    TkWindow *winPtr;

    if (!w) {
	return BadWindow;
    }
    winPtr = TkWinGetWinPtr(w);
    LastKnownRequestProcessed(display)++;

    /*
     * Bug fix: Don't short circuit this routine based on TK_MAPPED because it
     * will be cleared before XUnmapWindow is called.
     */

    ShowWindow(Tk_GetHWND(w), SW_HIDE);
    winPtr->flags &= ~TK_MAPPED;

    if (winPtr->flags & TK_WIN_MANAGED) {
	event.type = UnmapNotify;
	event.xunmap.serial = LastKnownRequestProcessed(display);
	event.xunmap.send_event = False;
	event.xunmap.display = display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	Tk_HandleEvent(&event);
    }
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
int
XMoveResizeWindow(
    Display *display,
    Window w,
    int x, int y,		/* Position relative to parent. */
    unsigned int width, unsigned int height)
{
    display->request++;
    MoveWindow(Tk_GetHWND(w), x, y, (int) width, (int) height, TRUE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *







|







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
int
XMoveResizeWindow(
    Display *display,
    Window w,
    int x, int y,		/* Position relative to parent. */
    unsigned int width, unsigned int height)
{
    LastKnownRequestProcessed(display)++;
    MoveWindow(Tk_GetHWND(w), x, y, (int) width, (int) height, TRUE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
XMoveWindow(
    Display *display,
    Window w,
    int x, int y)		/* Position relative to parent */
{
    TkWindow *winPtr = TkWinGetWinPtr(w);

    display->request++;

    MoveWindow(Tk_GetHWND(w), x, y, winPtr->changes.width,
	    winPtr->changes.height, TRUE);
    return Success;
}

/*







|







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
XMoveWindow(
    Display *display,
    Window w,
    int x, int y)		/* Position relative to parent */
{
    TkWindow *winPtr = TkWinGetWinPtr(w);

    LastKnownRequestProcessed(display)++;

    MoveWindow(Tk_GetHWND(w), x, y, winPtr->changes.width,
	    winPtr->changes.height, TRUE);
    return Success;
}

/*
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
XResizeWindow(
    Display *display,
    Window w,
    unsigned int width, unsigned int height)
{
    TkWindow *winPtr = TkWinGetWinPtr(w);

    display->request++;

    MoveWindow(Tk_GetHWND(w), winPtr->changes.x, winPtr->changes.y, (int)width,
	    (int)height, TRUE);
    return Success;
}

/*







|







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
XResizeWindow(
    Display *display,
    Window w,
    unsigned int width, unsigned int height)
{
    TkWindow *winPtr = TkWinGetWinPtr(w);

    LastKnownRequestProcessed(display)++;

    MoveWindow(Tk_GetHWND(w), winPtr->changes.x, winPtr->changes.y, (int)width,
	    (int)height, TRUE);
    return Success;
}

/*
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
int
XRaiseWindow(
    Display *display,
    Window w)
{
    HWND window = Tk_GetHWND(w);

    display->request++;
    SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

int
XLowerWindow(
    Display *display,
    Window w)
{
    HWND window = Tk_GetHWND(w);

    display->request++;
    SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *







|











|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
int
XRaiseWindow(
    Display *display,
    Window w)
{
    HWND window = Tk_GetHWND(w);

    LastKnownRequestProcessed(display)++;
    SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

int
XLowerWindow(
    Display *display,
    Window w)
{
    HWND window = Tk_GetHWND(w);

    LastKnownRequestProcessed(display)++;
    SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    Window w,
    unsigned int valueMask,
    XWindowChanges *values)
{
    TkWindow *winPtr = TkWinGetWinPtr(w);
    HWND hwnd = Tk_GetHWND(w);

    display->request++;

    /*
     * Change the shape and/or position of the window.
     */

    if (valueMask & (CWX|CWY|CWWidth|CWHeight)) {
	MoveWindow(hwnd, winPtr->changes.x, winPtr->changes.y,







|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
    Window w,
    unsigned int valueMask,
    XWindowChanges *values)
{
    TkWindow *winPtr = TkWinGetWinPtr(w);
    HWND hwnd = Tk_GetHWND(w);

    LastKnownRequestProcessed(display)++;

    /*
     * Change the shape and/or position of the window.
     */

    if (valueMask & (CWX|CWY|CWWidth|CWHeight)) {
	MoveWindow(hwnd, winPtr->changes.x, winPtr->changes.y,
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
    RECT rc;
    HBRUSH brush;
    HPALETTE oldPalette, palette;
    TkWindow *winPtr;
    HWND hwnd = Tk_GetHWND(w);
    HDC dc = GetDC(hwnd);

    palette = TkWinGetPalette(display->screens[0].cmap);
    oldPalette = SelectPalette(dc, palette, FALSE);

    display->request++;

    winPtr = TkWinGetWinPtr(w);
    brush = CreateSolidBrush(winPtr->atts.background_pixel);
    GetWindowRect(hwnd, &rc);
    rc.right = rc.right - rc.left;
    rc.bottom = rc.bottom - rc.top;
    rc.left = rc.top = 0;







|


|







708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
    RECT rc;
    HBRUSH brush;
    HPALETTE oldPalette, palette;
    TkWindow *winPtr;
    HWND hwnd = Tk_GetHWND(w);
    HDC dc = GetDC(hwnd);

    palette = TkWinGetPalette(DefaultColormapOfScreen(ScreenOfDisplay(display, 0)));
    oldPalette = SelectPalette(dc, palette, FALSE);

    LastKnownRequestProcessed(display)++;

    winPtr = TkWinGetWinPtr(w);
    brush = CreateSolidBrush(winPtr->atts.background_pixel);
    GetWindowRect(hwnd, &rc);
    rc.right = rc.right - rc.left;
    rc.bottom = rc.bottom - rc.top;
    rc.left = rc.top = 0;
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
    Window window;

    if (busyPtr->tkBusy != NULL) {
	Tk_MapWindow(busyPtr->tkBusy);
	window = Tk_WindowId(busyPtr->tkBusy);
	display = Tk_Display(busyPtr->tkBusy);
	hWnd = Tk_GetHWND(window);
	display->request++;
	SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }

    /*
     * Under Win32, cursors aren't associated with windows. Tk fakes this by
     * watching Motion events on its windows. So Tk will automatically change
     * the cursor when the pointer enters the Busy window. But Windows does







|







836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
    Window window;

    if (busyPtr->tkBusy != NULL) {
	Tk_MapWindow(busyPtr->tkBusy);
	window = Tk_WindowId(busyPtr->tkBusy);
	display = Tk_Display(busyPtr->tkBusy);
	hWnd = Tk_GetHWND(window);
	LastKnownRequestProcessed(display)++;
	SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }

    /*
     * Under Win32, cursors aren't associated with windows. Tk fakes this by
     * watching Motion events on its windows. So Tk will automatically change
     * the cursor when the pointer enters the Busy window. But Windows does

Changes to win/tkWinWm.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16




17
18
19
20
21
22
23
24
25
/*
 * 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.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"




#include <shellapi.h>

/*
 * These next two defines are only valid on Win2K/XP+.
 */

#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED	0x00080000
#endif








|
|






>
>
>
>

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * 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 © 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 <windows.h>
#include <wtypes.h>
#include <shobjidl.h>
#include <shlguid.h>
#include <shellapi.h>
#include "tkWinIco.h"
/*
 * These next two defines are only valid on Win2K/XP+.
 */

#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED	0x00080000
#endif
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 */

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:
 *
 * (1) How many WmInfo structures point to this object
 * (2) Whether the ThreadSpecificData defined in this file contains a pointer
 *     to this object.







<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







77
78
79
80
81
82
83






84










85




































86
87
88
89
90
91
92
93
 */

typedef struct TkWmStackorderToplevelPair {
    Tcl_HashTable *table;
    TkWindow **windowPtr;
} TkWmStackorderToplevelPair;


















/*




































 * A pointer to one of these structures is associated with each toplevel.
 * This allows us to free up all memory associated with icon resources when a
 * window is deleted or if the window's icon is changed. They are simply
 * reference counted according to:
 *
 * (1) How many WmInfo structures point to this object
 * (2) Whether the ThreadSpecificData defined in this file contains a pointer
 *     to this object.
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
				 * transparent) .. 1.0 (opaque) */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    int cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    int cmdArgc;		/* Number of elements in cmdArgv below. */
    const char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
				 * property. NULL means nothing available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */
    int numTransients;		/* Number of transients on this window */
    WinIconPtr iconPtr;		/* Pointer to titlebar icon structure for this







|







|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
				 * transparent) .. 1.0 (opaque) */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    Tcl_Size cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
				 * window (NULL means none). */
    Tcl_Size cmdArgc;		/* Number of elements in cmdArgv below. */
    const char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
				 * property. NULL means nothing available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */
    int numTransients;		/* Number of transients on this window */
    WinIconPtr iconPtr;		/* Pointer to titlebar icon structure for this
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME)

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, HWND parentHWND);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};







|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME)

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void		TopLevelReqProc(void *dummy, Tk_Window tkwin);
static void		RemapWindows(TkWindow *winPtr, HWND parentHWND);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
};
393
394
395
396
397
398
399










400
401
402
403
404
405
406
 */

static int initialized;		/* Flag indicating whether module has been
				 * initialized. */

TCL_DECLARE_MUTEX(winWmMutex)











/*
 * Forward declarations for functions defined in this file:
 */

static int		ActivateWindow(Tcl_Event *evPtr, int flags);
static void		ConfigureTopLevel(WINDOWPOS *pos);
static void		GenerateConfigureNotify(TkWindow *winPtr);







>
>
>
>
>
>
>
>
>
>







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
 */

static int initialized;		/* Flag indicating whether module has been
				 * initialized. */

TCL_DECLARE_MUTEX(winWmMutex)

/*
 * The following records the "TaskbarButtonCreated" message ID
 * for overlay icons.
 */

static UINT TaskbarButtonCreatedMessageId = WM_NULL;

/* Reference to taskbarlist API for overlay icons. */
ITaskbarList3 *ptbl;

/*
 * Forward declarations for functions defined in this file:
 */

static int		ActivateWindow(Tcl_Event *evPtr, int flags);
static void		ConfigureTopLevel(WINDOWPOS *pos);
static void		GenerateConfigureNotify(TkWindow *winPtr);
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
			    TkWindow *winPtr);
static void		RefreshColormap(Colormap colormap, TkDisplay *dispPtr);
static void		SetLimits(HWND hwnd, MINMAXINFO *info);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *table);
static LRESULT CALLBACK	TopLevelProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static void		TopLevelEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		UpdateGeometryInfo(ClientData clientData);
static void		UpdateWrapper(TkWindow *winPtr);
static LRESULT CALLBACK	WmProc(HWND hwnd, UINT message,
			    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 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);

static int		WmAspectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);



static int		WmIconbitmapCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);

/*
 * 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







|

|
|



|





>


<









|


|


|


|


|


|


|


|


|


|


|


|

>
>
>

|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511





















































































































































































512
513
514
515
516
517
518
			    TkWindow *winPtr);
static void		RefreshColormap(Colormap colormap, TkDisplay *dispPtr);
static void		SetLimits(HWND hwnd, MINMAXINFO *info);
static void		TkWmStackorderToplevelWrapperMap(TkWindow *winPtr,
			    Display *display, Tcl_HashTable *table);
static LRESULT CALLBACK	TopLevelProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static void		TopLevelEventProc(void *clientData,
			    XEvent *eventPtr);
static void		TopLevelReqProc(void *dummy, Tk_Window tkwin);
static void		UpdateGeometryInfo(void *clientData);
static void		UpdateWrapper(TkWindow *winPtr);
static LRESULT CALLBACK	WmProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static void		WmWaitVisibilityOrMapProc(void *clientData,
			    XEvent *eventPtr);
static BlockOfIconImagesPtr ReadIconOrCursorFromFile(Tcl_Interp *interp,
			    Tcl_Obj* fileName, BOOL isIcon);
static WinIconPtr	ReadIconFromFile(Tcl_Interp *interp,
			    Tcl_Obj *fileName);
static BOOL		AdjustIconImagePointers(LPICONIMAGE lpImage);
static WinIconPtr	GetIconFromPixmap(Display *dsPtr, Pixmap pixmap);
static int		ReadICOHeader(Tcl_Channel channel);

static 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);

static int		WmAspectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmAttributesCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmClientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmColormapwindowsCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmCommandCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmDeiconifyCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmFocusmodelCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmForgetCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmFrameCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGeometryCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGridCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmGroupCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbadgeCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconbitmapCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconifyCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconmaskCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconnameCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconphotoCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconpositionCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmIconwindowCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmManageCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmMaxsizeCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmMinsizeCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmOverrideredirectCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmPositionfromCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmProtocolCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmResizableCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmSizefromCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmStackorderCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmStateCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmTitleCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmTransientCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static int		WmWithdrawCmd(Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, Tcl_Size objc,
			    Tcl_Obj *const objv[]);
static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);






















































































































































































/*
 *----------------------------------------------------------------------
 *
 * MakeIconOrCursorFromResource --
 *
 *	Construct an actual HICON structure from the information in a
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
    if (!initialized) {
	Tcl_MutexLock(&winWmMutex);
	if (!initialized) {
	    WNDCLASSW windowClass;

	    initialized = 1;

	    ZeroMemory(&windowClass, sizeof(WNDCLASSW));

	    windowClass.style = CS_HREDRAW | CS_VREDRAW;
	    windowClass.hInstance = Tk_GetHINSTANCE();
	    windowClass.lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME;
	    windowClass.lpfnWndProc = WmProc;
	    if (titlebaricon == NULL) {
		windowClass.hIcon = LoadIconW(Tk_GetHINSTANCE(), L"tk");







|







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    if (!initialized) {
	Tcl_MutexLock(&winWmMutex);
	if (!initialized) {
	    WNDCLASSW windowClass;

	    initialized = 1;

	    memset(&windowClass, 0, sizeof(WNDCLASSW));

	    windowClass.style = CS_HREDRAW | CS_VREDRAW;
	    windowClass.hInstance = Tk_GetHINSTANCE();
	    windowClass.lpszClassName = TK_WIN_TOPLEVEL_CLASS_NAME;
	    windowClass.lpfnWndProc = WmProc;
	    if (titlebaricon == NULL) {
		windowClass.hIcon = LoadIconW(Tk_GetHINSTANCE(), L"tk");
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
	 * icon. Otherwise our icon choice will be ignored moments later when
	 * Tk finishes initialising.
	 */

	if (!initialized) {
	    if (InitWindowClass(titlebaricon) != TCL_OK) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Unable to set icon", -1));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FAILED", NULL);
		return TCL_ERROR;
	    }
	} else {
	    ThreadSpecificData *tsdPtr;

	    /*







|







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
	 * icon. Otherwise our icon choice will be ignored moments later when
	 * Tk finishes initialising.
	 */

	if (!initialized) {
	    if (InitWindowClass(titlebaricon) != TCL_OK) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Unable to set icon", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FAILED", NULL);
		return TCL_ERROR;
	    }
	} else {
	    ThreadSpecificData *tsdPtr;

	    /*
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
	     */

	    UpdateWrapper(wmPtr->winPtr);
	    wmPtr = ((TkWindow *) tkw)->wmInfoPtr;
	    hwnd = wmPtr->wrapper;
	    if (hwnd == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Can't set icon; window has no wrapper.", -1));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "WRAPPER", NULL);
		return TCL_ERROR;
	    }
	}
	SendMessageW(hwnd, WM_SETICON, ICON_SMALL,
		(LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	SendMessageW(hwnd, WM_SETICON, ICON_BIG,







|







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
	     */

	    UpdateWrapper(wmPtr->winPtr);
	    wmPtr = ((TkWindow *) tkw)->wmInfoPtr;
	    hwnd = wmPtr->wrapper;
	    if (hwnd == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Can't set icon; window has no wrapper.", TCL_INDEX_NONE));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "WRAPPER", NULL);
		return TCL_ERROR;
	    }
	}
	SendMessageW(hwnd, WM_SETICON, ICON_SMALL,
		(LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	SendMessageW(hwnd, WM_SETICON, ICON_BIG,
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
	const char *file;

	file = Tcl_TranslateFileName(interp, Tcl_GetString(fileName), &ds);
	if (file == NULL) {
	    return NULL;
	}
	Tcl_DStringInit(&ds2);
	res = (DWORD *)SHGetFileInfoW(Tcl_UtfToWCharDString(file, -1, &ds2), 0, &sfiSM,
		sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
	Tcl_DStringFree(&ds);

	if (res != 0) {
	    SHFILEINFOW sfi;
	    unsigned size;








|







1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
	const char *file;

	file = Tcl_TranslateFileName(interp, Tcl_GetString(fileName), &ds);
	if (file == NULL) {
	    return NULL;
	}
	Tcl_DStringInit(&ds2);
	res = (DWORD *)SHGetFileInfoW(Tcl_UtfToWCharDString(file, TCL_INDEX_NONE, &ds2), 0, &sfiSM,
		sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
	Tcl_DStringFree(&ds);

	if (res != 0) {
	    SHFILEINFOW sfi;
	    unsigned size;

1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
		if (res != 0) {
		    DestroyIcon(sfi.hIcon);
		}
		DestroyIcon(sfiSM.hIcon);
		Tcl_DStringFree(&ds2);
		return NULL;
	    }
	    ZeroMemory(lpIR, size);

	    lpIR->nNumImages		= ((res != 0) ? 2 : 1);
	    lpIR->IconImages[0].Width	= 16;
	    lpIR->IconImages[0].Height	= 16;
	    lpIR->IconImages[0].Colors	= 4;
	    lpIR->IconImages[0].hIcon	= sfiSM.hIcon;








|







1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
		if (res != 0) {
		    DestroyIcon(sfi.hIcon);
		}
		DestroyIcon(sfiSM.hIcon);
		Tcl_DStringFree(&ds2);
		return NULL;
	    }
	    memset(lpIR, 0, size);

	    lpIR->nNumImages		= ((res != 0) ? 2 : 1);
	    lpIR->IconImages[0].Width	= 16;
	    lpIR->IconImages[0].Height	= 16;
	    lpIR->IconImages[0].Colors	= 4;
	    lpIR->IconImages[0].hIcon	= sfiSM.hIcon;

1294
1295
1296
1297
1298
1299
1300





































































1301
1302
1303
1304
1305
1306
1307
	titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
	titlebaricon->iconBlock = lpIR;
	titlebaricon->refCount = 1;
    }
    return titlebaricon;
}






































































/*
 *----------------------------------------------------------------------
 *
 * GetIconFromPixmap --
 *
 *	Turn a Tk Pixmap (i.e. a bitmap) into an icon resource, if possible,
 *	otherwise NULL is returned.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	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.
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611

    /*
     * Read in the header
     */

    lpIR->nNumImages = ReadICOHeader(channel);
    if (lpIR->nNumImages == -1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("Invalid file header", -1));
	Tcl_Close(NULL, channel);
	ckfree(lpIR);
	return NULL;
    }

    /*
     * Adjust the size of the struct to account for the images.







|







1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464

    /*
     * Read in the header
     */

    lpIR->nNumImages = ReadICOHeader(channel);
    if (lpIR->nNumImages == -1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("Invalid file header", TCL_INDEX_NONE));
	Tcl_Close(NULL, channel);
	ckfree(lpIR);
	return NULL;
    }

    /*
     * Adjust the size of the struct to account for the images.
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
	}

	/*
	 * Read it in.
	 */

	dwBytesRead = Tcl_Read(channel, (char *)lpIR->IconImages[i].lpBits,
		(int) lpIDE[i].dwBytesInRes);
	if (dwBytesRead != lpIDE[i].dwBytesInRes) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading file: %s", Tcl_PosixError(interp)));
	    goto readError;
	}

	/*
	 * Set the internal pointers appropriately.
	 */

	if (!AdjustIconImagePointers(&lpIR->IconImages[i])) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Error converting to internal format", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FORMAT", NULL);
	    goto readError;
	}
	lpIR->IconImages[i].hIcon =
		MakeIconOrCursorFromResource(&lpIR->IconImages[i], isIcon);
    }








|












|







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
	}

	/*
	 * Read it in.
	 */

	dwBytesRead = Tcl_Read(channel, (char *)lpIR->IconImages[i].lpBits,
		lpIDE[i].dwBytesInRes);
	if (dwBytesRead != lpIDE[i].dwBytesInRes) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading file: %s", Tcl_PosixError(interp)));
	    goto readError;
	}

	/*
	 * Set the internal pointers appropriately.
	 */

	if (!AdjustIconImagePointers(&lpIR->IconImages[i])) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Error converting to internal format", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FORMAT", NULL);
	    goto readError;
	}
	lpIR->IconImages[i].hIcon =
		MakeIconOrCursorFromResource(&lpIR->IconImages[i], isIcon);
    }

1877
1878
1879
1880
1881
1882
1883






1884
1885
1886
1887
1888
1889
1890
    tsdPtr = (ThreadSpecificData *)Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	return;
    }
    tsdPtr->initialized = 0;







    UnregisterClassW(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);
}

/*
 *--------------------------------------------------------------
 *
 * TkWmNewWindow --







>
>
>
>
>
>







1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
    tsdPtr = (ThreadSpecificData *)Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!tsdPtr->initialized) {
	return;
    }
    tsdPtr->initialized = 0;

    /*
     * COM library cleanup.
     */

    CoUninitialize();

    UnregisterClassW(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);
}

/*
 *--------------------------------------------------------------
 *
 * TkWmNewWindow --
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
{
    WmInfo *wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));

    /*
     * Initialize full structure, then set what isn't NULL
     */

    ZeroMemory(wmPtr, sizeof(WmInfo));
    winPtr->wmInfoPtr = wmPtr;
    wmPtr->winPtr = winPtr;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;







|







1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
{
    WmInfo *wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));

    /*
     * Initialize full structure, then set what isn't NULL
     */

    memset(wmPtr, 0, sizeof(WmInfo));
    winPtr->wmInfoPtr = wmPtr;
    wmPtr->winPtr = winPtr;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
1993
1994
1995
1996
1997
1998
1999

2000
2001
2002
2003
2004
2005
2006
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND parentHWND, oldWrapper = wmPtr->wrapper;
    HWND child, nextHWND, focusHWND;
    int x, y, width, height, state;
    WINDOWPLACEMENT place;
    HICON hSmallIcon = NULL;
    HICON hBigIcon = NULL;

    Tcl_DString titleString;
    int *childStateInfo = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window == None) {
	/*







>







1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND parentHWND, oldWrapper = wmPtr->wrapper;
    HWND child, nextHWND, focusHWND;
    int x, y, width, height, state;
    WINDOWPLACEMENT place;
    HICON hSmallIcon = NULL;
    HICON hBigIcon = NULL;
    HRESULT hr;
    Tcl_DString titleString;
    int *childStateInfo = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window == None) {
	/*
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
	 * Create the containing window, and set the user data to point to the
	 * TkWindow.
	 */

	tsdPtr->createWindow = winPtr;
	Tcl_DStringInit(&titleString);
	Tcl_UtfToWCharDString(((wmPtr->title != NULL) ?
		wmPtr->title : winPtr->nameUid), -1, &titleString);

	wmPtr->wrapper = CreateWindowExW(wmPtr->exStyle,
		TK_WIN_TOPLEVEL_CLASS_NAME,
		(LPCWSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
	Tcl_DStringFree(&titleString);







|







1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
	 * Create the containing window, and set the user data to point to the
	 * TkWindow.
	 */

	tsdPtr->createWindow = winPtr;
	Tcl_DStringInit(&titleString);
	Tcl_UtfToWCharDString(((wmPtr->title != NULL) ?
		wmPtr->title : winPtr->nameUid), TCL_INDEX_NONE, &titleString);

	wmPtr->wrapper = CreateWindowExW(wmPtr->exStyle,
		TK_WIN_TOPLEVEL_CLASS_NAME,
		(LPCWSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
	Tcl_DStringFree(&titleString);
2321
2322
2323
2324
2325
2326
2327





























2328
2329
2330
2331
2332
2333
2334

    if (tsdPtr->firstWindow) {
	tsdPtr->firstWindow = 0;
	SetActiveWindow(wmPtr->wrapper);
    } else if (focusHWND) {
	SetFocus(focusHWND);
    }





























}

/*
 *--------------------------------------------------------------
 *
 * TkWmMapWindow --
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

    if (tsdPtr->firstWindow) {
	tsdPtr->firstWindow = 0;
	SetActiveWindow(wmPtr->wrapper);
    } else if (focusHWND) {
	SetFocus(focusHWND);
    }

    /*
     * Initialize hooks for overlay icon.
     * Start with TaskbarButtonCreated message.
     */

    TaskbarButtonCreatedMessageId = RegisterWindowMessage(TEXT("TaskbarButtonCreated"));

    /*
     * In case the application is run elevated, allow the
     * TaskbarButtonCreated message through.
     */

    ChangeWindowMessageFilter(TaskbarButtonCreatedMessageId, MSGFLT_ADD);

    /*
     * Load COM library for icon overlay.
     */

    hr = CoInitialize(0);
    if (SUCCEEDED(hr)) {
	hr = CoCreateInstance(&CLSID_TaskbarList, NULL,
		CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, (void **) &ptbl);
	if (FAILED(hr)) {
	    printf("Unable to initialize ITaskbarList3 API");
	    ptbl->lpVtbl->Release(NULL);
	    ptbl = NULL;
	}
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkWmMapWindow --
 *
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
 *	A window property may get updated.
 *
 *--------------------------------------------------------------
 */

void
TkWmSetClass(
    TkWindow *winPtr)		/* Newly-created top-level window. */
{
    (void)winPtr;

    /* Do nothing */
    return;
}

/*
 *----------------------------------------------------------------------
 *







|

<
<







2625
2626
2627
2628
2629
2630
2631
2632
2633


2634
2635
2636
2637
2638
2639
2640
 *	A window property may get updated.
 *
 *--------------------------------------------------------------
 */

void
TkWmSetClass(
    TCL_UNUSED(TkWindow *))	/* Newly-created top-level window. */
{


    /* Do nothing */
    return;
}

/*
 *----------------------------------------------------------------------
 *
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL
    };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE,
	WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW
    };
    int index;
    TkSizeT length;
    const char *argv1;
    TkWindow *winPtr, **winPtrPtr = &winPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = TkGetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && !strncmp(argv1, "tracing", length)
	    && (length >= 3)) {
	int wmTracing;

	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
	    return TCL_ERROR;







|








|











|









|










|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    void *clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "forget", "frame",
	"geometry", "grid", "group", "iconbadge", "iconbitmap",
	"iconify", "iconmask", "iconname",
	"iconphoto", "iconposition",
	"iconwindow", "manage", "maxsize", "minsize", "overrideredirect",
	"positionfrom", "protocol", "resizable", "sizefrom",
	"stackorder", "state", "title", "transient",
	"withdraw", NULL
    };
    enum options {
	WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET,
	WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBADGE, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE,
	WMOPT_OVERRIDEREDIRECT,
	WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
	WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
	WMOPT_WITHDRAW
    };
    int index;
    Tcl_Size length;
    const char *argv1;
    TkWindow *winPtr, **winPtrPtr = &winPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objc < 2) {
    wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }

    argv1 = 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;
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }








|
|







2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
	    dispPtr->flags |= TK_DISPLAY_WM_TRACING;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_WM_TRACING;
	}
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings,
	    "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

2877
2878
2879
2880
2881
2882
2883


2884
2885
2886
2887
2888
2889
2890
	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GEOMETRY:
	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GRID:
	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GROUP:
	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);


    case WMOPT_ICONBITMAP:
	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONIFY:
	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONMASK:
	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONNAME:







>
>







2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GEOMETRY:
	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GRID:
	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_GROUP:
	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONBADGE:
	return WmIconbadgeCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONBITMAP:
	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONIFY:
	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONMASK:
	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
    case WMOPT_ICONNAME:
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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) {







|


|




<







2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845

2846
2847
2848
2849
2850
2851
2852
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int numer1, denom1, numer2, denom2;


    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?minNumer minDenom maxNumer maxDenom?");
	return TCL_ERROR;
    }
    if (objc == 3) {
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || (denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;







|







2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
		|| (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || (denom2 <= 0)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "aspect number can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "ASPECT", NULL);
	    return TCL_ERROR;
	}
	wmPtr->minAspect.x = numer1;
	wmPtr->minAspect.y = denom1;
	wmPtr->maxAspect.x = numer2;
	wmPtr->maxAspect.y = denom2;
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
 */

static int
WmAttributesCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr = NULL;
    const char *string;
    int i, boolean;
    TkSizeT length;
    int config_fullscreen = 0, updatewrapper = 0;
    int fullscreen_attr_changed = 0, fullscreen_attr = 0;

    if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
    configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"
		" ?-alpha ?double??"
		" ?-transparentcolor ?color??"
		" ?-disabled ?bool??"
		" ?-fullscreen ?bool??"
		" ?-toolwindow ?bool??"
		" ?-topmost ?bool??");
	return TCL_ERROR;
    }
    exStyle = wmPtr->exStyleConfig;
    style = wmPtr->styleConfig;
    if (objc == 3) {
	Tcl_Obj *objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-alpha", -1));
	Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewDoubleObj(wmPtr->alpha));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-transparentcolor", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj());
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-disabled", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((style & WS_DISABLED) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-fullscreen", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((wmPtr->flags & WM_FULLSCREEN) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-toolwindow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOOLWINDOW) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOPMOST) != 0));
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = TkGetStringFromObj(objv[i], &length);
	if ((length < 2) || (string[0] != '-')) {
	    goto configArgs;
	}
	if (strncmp(string, "-disabled", length) == 0) {
	    stylePtr = &style;
	    styleBit = WS_DISABLED;
	} else if ((strncmp(string, "-alpha", length) == 0)
		|| ((length > 2) && (strncmp(string, "-transparentcolor",
			length) == 0))) {
	    stylePtr = &exStyle;







|





|
|




















|


|



|



|



|



|






|
<
<
<







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
 */

static int
WmAttributesCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr = NULL;
    const char *string;
    int boolValue;
    Tcl_Size i, length;
    int config_fullscreen = 0, updatewrapper = 0;
    int fullscreen_attr_changed = 0, fullscreen_attr = 0;

    if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
    configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"
		" ?-alpha ?double??"
		" ?-transparentcolor ?color??"
		" ?-disabled ?bool??"
		" ?-fullscreen ?bool??"
		" ?-toolwindow ?bool??"
		" ?-topmost ?bool??");
	return TCL_ERROR;
    }
    exStyle = wmPtr->exStyleConfig;
    style = wmPtr->styleConfig;
    if (objc == 3) {
	Tcl_Obj *objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-alpha", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewDoubleObj(wmPtr->alpha));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-transparentcolor", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, objPtr,
		wmPtr->crefObj ? wmPtr->crefObj : Tcl_NewObj());
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-disabled", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((style & WS_DISABLED) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-fullscreen", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((wmPtr->flags & WM_FULLSCREEN) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-toolwindow", TCL_INDEX_NONE));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOOLWINDOW) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", TCL_INDEX_NONE));
	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 = Tcl_GetStringFromObj(objv[i], &length);



	if (strncmp(string, "-disabled", length) == 0) {
	    stylePtr = &style;
	    styleBit = WS_DISABLED;
	} else if ((strncmp(string, "-alpha", length) == 0)
		|| ((length > 2) && (strncmp(string, "-transparentcolor",
			length) == 0))) {
	    stylePtr = &exStyle;
3106
3107
3108
3109
3110
3111
3112






3113
3114
3115
3116
3117
3118
3119
	    if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set topmost flag on %s: it is an embedded window",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "TOPMOST", NULL);
		return TCL_ERROR;
	    }






	} else {
	    goto configArgs;
	}
	if (styleBit == WS_EX_LAYERED) {
	    if (objc == 4) {
		if (string[1] == 'a') {		/* -alpha */
		    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(wmPtr->alpha));







>
>
>
>
>
>







2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
	    if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set topmost flag on %s: it is an embedded window",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "TOPMOST", NULL);
		return TCL_ERROR;
	    }
	} else if (i == 3) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad attribute \"%s\": must be -alpha, -disabled, -fullscreen, -toolwindow, -topmost, or -transparentcolor",
		    string));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "UNRECOGNIZED", NULL);
	    return TCL_ERROR;
	} else {
	    goto configArgs;
	}
	if (styleBit == WS_EX_LAYERED) {
	    if (objc == 4) {
		if (string[1] == 'a') {		/* -alpha */
		    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(wmPtr->alpha));
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
		    if (dval < 0.0) {
			dval = 0;
		    } else if (dval > 1.0) {
			dval = 1;
		    }
		    wmPtr->alpha = dval;
		} else {			/* -transparentcolor */
		    const char *crefstr = TkGetStringFromObj(objv[i+1], &length);

		    if (length == 0) {
			/* reset to no transparent color */
			if (wmPtr->crefObj) {
			    Tcl_DecrRefCount(wmPtr->crefObj);
			    wmPtr->crefObj = NULL;
			}







|







3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
		    if (dval < 0.0) {
			dval = 0;
		    } else if (dval > 1.0) {
			dval = 1;
		    }
		    wmPtr->alpha = dval;
		} else {			/* -transparentcolor */
		    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;
			}
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
			    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
			    (unsigned) (LWA_ALPHA |
				    (wmPtr->crefObj ? LWA_COLORKEY : 0)));
		}
	    }
	} else {
	    if ((i < objc-1)
		    && Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean)
			    != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (config_fullscreen) {
		if (objc == 4) {
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
			    (wmPtr->flags & WM_FULLSCREEN) != 0));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolean;
		}
		config_fullscreen = 0;
	    } else if (objc == 4) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj((*stylePtr & styleBit) != 0));
	    } else if (boolean) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
	    }
	}
	if ((styleBit == WS_EX_TOPMOST) && (wmPtr->wrapper != NULL)) {
	    /*







|









|





|







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
			    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
			    (unsigned) (LWA_ALPHA |
				    (wmPtr->crefObj ? LWA_COLORKEY : 0)));
		}
	    }
	} else {
	    if ((i < objc-1)
		    && Tcl_GetBooleanFromObj(interp, objv[i+1], &boolValue)
			    != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (config_fullscreen) {
		if (objc == 4) {
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
			    (wmPtr->flags & WM_FULLSCREEN) != 0));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolValue;
		}
		config_fullscreen = 0;
	    } else if (objc == 4) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj((*stylePtr & styleBit) != 0));
	    } else if (boolValue) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
	    }
	}
	if ((styleBit == WS_EX_TOPMOST) && (wmPtr->wrapper != NULL)) {
	    /*
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    TkSizeT length;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, -1));
	}
	return TCL_OK;
    }
    argv3 = TkGetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, winPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,"WM_CLIENT_MACHINE"));







|


|




|
<








|



|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    Tcl_Size length;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->clientMachine != NULL) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(wmPtr->clientMachine, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree(wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XDeleteProperty(winPtr->display, winPtr->window,
			Tk_InternAtom((Tk_Window) winPtr,"WM_CLIENT_MACHINE"));
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;

	if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp)
		!= 0) {
	    XSetWMClientMachine(winPtr->display, winPtr->window,
		    &textProp);
	    XFree((char *) textProp.value);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|







3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;

	if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp)
		!= 0) {
	    XSetWMClientMachine(winPtr->display, winPtr->window,
		    &textProp);
	    XFree(textProp.value);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394

3395
3396
3397
3398
3399
3400
3401
3402
 */

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList, *winPtr2, **winPtr2Ptr = &winPtr2;

    int i, windowObjc, gotToplevel;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {







|




>
|







3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
 */

static int
WmColormapwindowsCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow **cmapList, *winPtr2, **winPtr2Ptr = &winPtr2;
    Tcl_Size i, windowObjc;
    int gotToplevel;
    Tcl_Obj **windowObjv, *resultObj;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    int cmdArgc;
    const char **cmdArgv;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
	    char *merged = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(merged, -1));
	    ckfree(merged);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {







|


|




|

<









|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    Tcl_Size cmdArgc;
    const char **cmdArgv;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
	    char *merged = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(merged, TCL_INDEX_NONE));
	    ckfree(merged);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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(







|


|



<







3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447

3448
3449
3450
3451
3452
3453
3454
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL
    };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE
    };
    int index;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", -1));
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
	    sizeof(char *), "argument", 0,&index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }







|


|










<







|



|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"active", "passive", NULL
    };
    enum options {
	OPT_ACTIVE, OPT_PASSIVE
    };
    int index;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		wmPtr->hints.input ? "passive" : "active", TCL_INDEX_NONE));
	return TCL_OK;
    }

    if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings,
	    "argument", 0,&index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (index == OPT_ACTIVE) {
	wmPtr->hints.input = False;
    } else { /* OPT_PASSIVE */
	wmPtr->hints.input = True;
    }
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmForgetCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *dummy,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    (void)tkwin;
    (void)dummy;
    (void)objc;
    (void)objv;

    if (Tk_IsTopLevel(frameWin)) {
	Tk_UnmapWindow(frameWin);
	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);
	RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window));

        /*
         * Make sure wm no longer manages this window
         */
        Tk_ManageGeometry(frameWin, NULL, NULL);

	TkWmDeadWindow(winPtr);
	/* flags (above) must be cleared before calling */
	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {
	/* Already not managed by wm - ignore it */







|

|
|
|


<
<
<
<







|
|
|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmForgetCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    TCL_UNUSED(Tcl_Interp *),		/* Current interpreter. */
    TCL_UNUSED(Tcl_Size),		/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *))	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;





    if (Tk_IsTopLevel(frameWin)) {
	Tk_UnmapWindow(frameWin);
	winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
	Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr);
	RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window));

	/*
	 * Make sure wm no longer manages this window
	 */
	Tk_ManageGeometry(frameWin, NULL, NULL);

	TkWmDeadWindow(winPtr);
	/* flags (above) must be cleared before calling */
	/* TkMapTopFrame (below) */
	TkMapTopFrame(frameWin);
    } else {
	/* Already not managed by wm - ignore it */
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND hwnd;
    char buf[TCL_INTEGER_SPACE];
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_WindowId((Tk_Window) winPtr) == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }
    hwnd = wmPtr->wrapper;
    if (hwnd == NULL) {
	hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr));
    }
    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --







|


|





<












|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND hwnd;
    char buf[TCL_INTEGER_SPACE];


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_WindowId((Tk_Window) winPtr) == None) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }
    hwnd = wmPtr->wrapper;
    if (hwnd == NULL) {
	hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr));
    }
    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, TCL_INDEX_NONE));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmGeometryCmd --
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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) {







|


|






<







3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651

3652
3653
3654
3655
3656
3657
3658
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    char xSign, ySign;
    int width, height;
    const char *argv3;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }

    if (objc == 3) {
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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) {







|


|




<







3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717

3718
3719
3720
3721
3722
3723
3724
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int reqWidth, reqHeight, widthInc, heightInc;


    if ((objc != 3) && (objc != 7)) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?baseWidth baseHeight widthInc heightInc?");
	return TCL_ERROR;
    }
    if (objc == 3) {
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
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
	 */

	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
	wmPtr->heightInc = 1;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseWidth can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseHeight can't be < 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "widthInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "heightInc can't be <= 0", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    WmUpdateGeom(wmPtr, winPtr);







|

















|





|





|





|







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
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	/*
	 * Turn off gridding and reset the width and height to make sense as
	 * ungridded numbers.
	 */

	wmPtr->sizeHintsFlags &= ~PBaseSize;
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
	wmPtr->heightInc = 1;
    } else {
	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if (reqWidth < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseWidth can't be < 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "baseHeight can't be < 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (widthInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "widthInc can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	if (heightInc <= 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "heightInc can't be <= 0", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID", NULL);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    WmUpdateGeom(wmPtr, winPtr);
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
 */

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    const char *argv3;
    TkSizeT length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1));
	}
	return TCL_OK;
    }
    argv3 = TkGetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {







|





|







|



|







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
 */

static int
WmGroupCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    const char *argv3;
    Tcl_Size length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & WindowGroupHint) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, TCL_INDEX_NONE));
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
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
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *















































































































 * WmIconbitmapCmd --
 *
 *	This function is invoked to process the "wm iconbitmap" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    const char *string;
    (void)tkwin;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-default? ?image?");
	return TCL_ERROR;
    } else if (objc == 5) {
	/*
	 * If we have 5 arguments, we must have a '-default' flag.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















|


|





<







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
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconbadgeCmd --
 *
 *	This function is invoked to process the "wm iconbadge" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbadgeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TCL_UNUSED(TkWindow *),	/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    HWND hwnd;
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int width, height;
    HICON overlayicon;
    int badgenumber;
    char *badgestring = NULL;
    char photoname[4096];
    LPCWSTR string;
    HRESULT hr;
    Tk_Window badgewindow;
    WmInfo *wmPtr;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window badge");
	return TCL_ERROR;
    }

    /*
     * Parse args, get native wrapper window, and determine image.
     */

    badgewindow = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
    wmPtr = ((TkWindow *) badgewindow)->wmInfoPtr;
    hwnd = wmPtr->wrapper;
    badgestring = Tcl_GetString(objv[3]);

    badgenumber = atoi(badgestring);
    if (badgenumber > 9) {
	strcpy(photoname, "::tk::icons::9plus-badge");
    } else {
	strcpy(photoname, "::tk::icons::");
	strcat(photoname, badgestring);
	strcat(photoname, "-badge");
    }

    /*
     * If badgestring is empty string, remove icon.
     */

    if (strcmp("", badgestring) == 0) {
	ptbl->lpVtbl->SetOverlayIcon(ptbl, hwnd, NULL, NULL);
	return TCL_OK;
    }

    /*
     * If photo does not exist, return error. This means we do not have
     * to test for decimal or negative values; no photo for such values
     * is present.
     */

    photo = Tk_FindPhoto(interp, photoname);
    if (photo == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use \"%s\" as icon badge", badgestring));
	return TCL_ERROR;
    }

    /*
     * We have found the image. Convert to icon.
     */

    Tk_PhotoGetSize(photo, &width, &height);
    Tk_PhotoGetImage(photo, &block);

    overlayicon = CreateIcoFromPhoto(width, height, block);
    if (overlayicon == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("Failed to create badge icon", TCL_INDEX_NONE));
	return TCL_ERROR;
    }

    /*
     * Place overlay icon on taskbar icon.
     */

    string = L"Alert";
    hr = ptbl->lpVtbl->SetOverlayIcon(ptbl, hwnd, overlayicon, string);
    if (hr != S_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("Failed to create badge icon", TCL_INDEX_NONE));
	return TCL_ERROR;
    }
    DestroyIcon(overlayicon);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconbitmapCmd --
 *
 *	This function is invoked to process the "wm iconbitmap" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    const char *string;


    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-default? ?image?");
	return TCL_ERROR;
    } else if (objc == 5) {
	/*
	 * If we have 5 arguments, we must have a '-default' flag.
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessageW(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {







|


|



<







4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124

4125
4126
4127
4128
4129
4130
4131
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessageW(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
 */

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {







|







4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
 */

static int
WmIconmaskCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    const char *argv3;

    if ((objc != 3) && (objc != 4)) {
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    TkSizeT length;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(wmPtr->iconName ? wmPtr->iconName : ""), -1));
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = TkGetStringFromObj(objv[3], &length);
	wmPtr->iconName = (char *)ckalloc(length + 1);
	memcpy(wmPtr->iconName, argv3, length + 1);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	}
    }
    return TCL_OK;







|


|




|
<













|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    Tcl_Size length;


    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		(wmPtr->iconName ? wmPtr->iconName : ""), -1));
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->iconName = (char *)ckalloc(length + 1);
	memcpy(wmPtr->iconName, argv3, length + 1);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	}
    }
    return TCL_OK;
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312

4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;

    int i, width, height, idx, bufferSize, startObj = 3;
    union {unsigned char *ptr; void *voidPtr;} bgraPixel;
    union {unsigned char *ptr; void *voidPtr;} bgraMask;
    BlockOfIconImagesPtr lpIR;
    WinIconPtr titlebaricon = NULL;
    HICON hIcon;
    unsigned size;
    BITMAPINFO bmInfo;
    ICONINFO iconInfo;
    (void)tkwin;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }








|


|





>
|
<
<




<
<
<







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconphotoCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size 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;
    Tcl_Size i;
    int width, height, startObj = 3;


    BlockOfIconImagesPtr lpIR;
    WinIconPtr titlebaricon = NULL;
    HICON hIcon;
    unsigned size;




    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"window ?-default? image1 ?image2 ...?");
	return TCL_ERROR;
    }

4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
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
     */

    size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
    lpIR = (BlockOfIconImagesPtr)attemptckalloc(size);
    if (lpIR == NULL) {
	return TCL_ERROR;
    }
    ZeroMemory(lpIR, size);

    lpIR->nNumImages = objc - startObj;

    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);

	/*
	 * Don't use CreateIcon to create the icon, as it requires color
	 * bitmap data in device-dependent format. Instead we use
	 * CreateIconIndirect which takes device-independent bitmaps and
	 * converts them as required. Initialise icon info structure.
	 */

	ZeroMemory(&iconInfo, sizeof(iconInfo));
	iconInfo.fIcon = TRUE;

	/*
	 * Create device-independent color bitmap.
	 */

	ZeroMemory(&bmInfo, sizeof bmInfo);
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmInfo.bmiHeader.biWidth = width;
	bmInfo.bmiHeader.biHeight = -height;
	bmInfo.bmiHeader.biPlanes = 1;
	bmInfo.bmiHeader.biBitCount = 32;
	bmInfo.bmiHeader.biCompression = BI_RGB;

	iconInfo.hbmColor = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
		&bgraPixel.voidPtr, NULL, 0);
	if (!iconInfo.hbmColor) {
	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create an iconphoto with image \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Convert the photo image data into BGRA format (RGBQUAD).
	 */

	bufferSize = height * width * 4;
	for (idx = 0 ; idx < bufferSize ; idx += 4) {
	    bgraPixel.ptr[idx] = block.pixelPtr[idx+2];
	    bgraPixel.ptr[idx+1] = block.pixelPtr[idx+1];
	    bgraPixel.ptr[idx+2] = block.pixelPtr[idx+0];
	    bgraPixel.ptr[idx+3] = block.pixelPtr[idx+3];
	}

	/*
	 * Create a dummy mask bitmap. The contents of this don't appear to
	 * matter, as CreateIconIndirect will setup the icon mask based on the
	 * alpha channel in our color bitmap.
	 */

	bmInfo.bmiHeader.biBitCount = 1;

	iconInfo.hbmMask = CreateDIBSection(NULL, &bmInfo, DIB_RGB_COLORS,
		&bgraMask.voidPtr, NULL, 0);
	if (!iconInfo.hbmMask) {
	    DeleteObject(iconInfo.hbmColor);
	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create mask bitmap for \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "MASK", NULL);
	    return TCL_ERROR;
	}

	ZeroMemory(bgraMask.ptr, width*height/8);

	/*
	 * Create an icon from the bitmaps.
	 */

	hIcon = CreateIconIndirect(&iconInfo);
	DeleteObject(iconInfo.hbmColor);
	DeleteObject(iconInfo.hbmMask);
	if (hIcon == NULL) {
	    /*
	     * XXX should free up created icons.
	     */

	    ckfree(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "failed to create icon for \"%s\"",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "ICON", NULL);
	    return TCL_ERROR;
	}
	lpIR->IconImages[i-startObj].Width = width;
	lpIR->IconImages[i-startObj].Height = height;
	lpIR->IconImages[i-startObj].Colors = 4;
	lpIR->IconImages[i-startObj].hIcon = hIcon;

    }

    titlebaricon = (WinIconPtr)ckalloc(sizeof(WinIconInstance));
    titlebaricon->iconBlock = lpIR;
    titlebaricon->refCount = 1;
    if (WinSetIcon(interp, titlebaricon, (Tk_Window) useWinPtr) != TCL_OK) {
	/*
	 * We didn't use the titlebaricon after all.
	 */

	DecrIconRefCount(titlebaricon);
	return TCL_ERROR;
    }
    return TCL_OK;
}



/*
 *----------------------------------------------------------------------
 *
 * WmIconpositionCmd --
 *
 *	This function is invoked to process the "wm iconposition" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {







<
|
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<

<
<
<
<
|

|








>
















>
>



















|


|




<







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
     */

    size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
    lpIR = (BlockOfIconImagesPtr)attemptckalloc(size);
    if (lpIR == NULL) {
	return TCL_ERROR;
    }

    memset(lpIR, 0, size);


    for (i = startObj; i < objc; i++) {
	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
	Tk_PhotoGetSize(photo, &width, &height);
	Tk_PhotoGetImage(photo, &block);








































































	hIcon = CreateIcoFromPhoto(width, height, block);


	if (hIcon == NULL) {




	    FreeIconBlock(lpIR);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "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) {
	/*
	 * We didn't use the titlebaricon after all.
	 */

	DecrIconRefCount(titlebaricon);
	return TCL_ERROR;
    }
    return TCL_OK;
}



/*
 *----------------------------------------------------------------------
 *
 * WmIconpositionCmd --
 *
 *	This function is invoked to process the "wm iconposition" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPositionHint) {
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
 */

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;








|







4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
 */

static int
WmIconwindowCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    XSetWindowAttributes atts;

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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel or Frame to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    (void)tkwin;
    (void)objc;
    (void)objv;

    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a frame,"
		    " labelframe or toplevel", Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);







|


|
|



<
<
<







4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580



4581
4582
4583
4584
4585
4586
4587
 *	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(Tcl_Size),		/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *)) /* Argument objects. */
{
    Tk_Window frameWin = (Tk_Window) winPtr;
    WmInfo *wmPtr = winPtr->wmInfoPtr;




    if (!Tk_IsTopLevel(frameWin)) {
	if (!Tk_IsManageable(frameWin)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" is not manageable: must be a frame,"
		    " labelframe or toplevel", Tk_PathName(frameWin)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL);
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}







|


|




<














|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
	    || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->maxWidth = width;
    wmPtr->maxHeight = height;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;
    (void)tkwin;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMinSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}







|


|




<














|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMinSize(wmPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	return TCL_OK;
    }
    if ((Tk_GetPixelsFromObj(interp, tkwin, objv[3], &width) != TCL_OK)
	    || (Tk_GetPixelsFromObj(interp, tkwin, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int boolean, curValue;
    XSetWindowAttributes atts;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	curValue = SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
	if (curValue < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Container does not support overrideredirect", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
	curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(curValue != 0));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	if (winPtr->flags & TK_EMBEDDED) {
	    SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0);
	} else {
	    /*
	     * Only do this if we are really changing value, because it causes
	     * some funky stuff to occur.
	     */

	    atts.override_redirect = (boolean) ? True : False;
	    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		    &atts);
	    if (!(wmPtr->flags & (WM_NEVER_MAPPED))
		    && !(winPtr->flags & TK_EMBEDDED)) {
		UpdateWrapper(winPtr);
	    }
	}







|


|



|

<









|










|


|

|






|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Bool boolValue, curValue;
    XSetWindowAttributes atts;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	curValue = SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
	if (curValue < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Container does not support overrideredirect", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
	curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(curValue != 0));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolValue) {
	if (winPtr->flags & TK_EMBEDDED) {
	    SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolValue, 0);
	} else {
	    /*
	     * Only do this if we are really changing value, because it causes
	     * some funky stuff to occur.
	     */

	    atts.override_redirect = boolValue;
	    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		    &atts);
	    if (!(wmPtr->flags & (WM_NEVER_MAPPED))
		    && !(winPtr->flags & TK_EMBEDDED)) {
		UpdateWrapper(winPtr);
	    }
	}
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USPosition) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;







|


|










<













|





|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USPosition) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, TCL_INDEX_NONE));
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings,
		"argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
	} else {
	    wmPtr->sizeHintsFlags &= ~USPosition;
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    const char *cmd;
    TkSizeT cmdLength;
    Tcl_Obj *resultObj;
    (void)tkwin;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */

	resultObj = Tcl_NewObj();
	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol), -1));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, -1));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*







|


|






|

<














|














|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    ProtocolHandler *protPtr, *prevPtr;
    Atom protocol;
    const char *cmd;
    Tcl_Size cmdLength;
    Tcl_Obj *resultObj;


    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
	 * Return a list of all defined protocols for the window.
	 */

	resultObj = Tcl_NewObj();
	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol), TCL_INDEX_NONE));
	}
	Tcl_SetObjResult(interp, resultObj);
	return TCL_OK;
    }
    protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
    if (objc == 4) {
	/*
	 * Return the command to handle a given protocol.
	 */

	for (protPtr = wmPtr->protPtr; protPtr != NULL;
		protPtr = protPtr->nextPtr) {
	    if (protPtr->protocol == protocol) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(protPtr->command, TCL_INDEX_NONE));
		return TCL_OK;
	    }
	}
	return TCL_OK;
    }

    /*
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = TkGetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *)ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);







|







4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *)ckalloc(HANDLER_SIZE(cmdLength));
	protPtr->protocol = protocol;
	protPtr->nextPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr;
	protPtr->interp = interp;
	memcpy(protPtr->command, cmd, cmdLength + 1);
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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];







|


|




<







4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972

4973
4974
4975
4976
4977
4978
4979
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;


    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_Obj *results[2];
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USSize) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, -1));
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;







|


|










<













|






|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"program", "user", NULL
    };
    enum options {
	OPT_PROGRAM, OPT_USER
    };
    int index;


    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	const char *sourceStr = "";

	if (wmPtr->sizeHintsFlags & USSize) {
	    sourceStr = "user";
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    sourceStr = "program";
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(sourceStr, TCL_INDEX_NONE));
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings,
		"argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
 */

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **windowPtr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {







|







5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
 */

static int
WmStackorderCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkWindow **windows, **windowPtr;
    static const char *const optionStrings[] = {
	"isabove", "isbelow", NULL
    };
    enum options {
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
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}

	for (windowPtr = windows; *windowPtr ; windowPtr++) {
	    if (*windowPtr == winPtr) {
		index1 = (windowPtr - windows);
	    }
	    if (*windowPtr == winPtr2) {
		index2 = (windowPtr - windows);
	    }
	}
	if (index1 == -1) {
	    Tcl_Panic("winPtr window not found");
	} else if (index2 == -1) {
	    Tcl_Panic("winPtr2 window not found");
	}

	ckfree(windows);

	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}







|




















|
|







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
	 * Lookup stacking order of all toplevels that are children of "." and
	 * find the position of winPtr and winPtr2 in the stacking order.
	 */

	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
	if (windows == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "TkWmStackorderToplevel failed", TCL_INDEX_NONE));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}

	for (windowPtr = windows; *windowPtr ; windowPtr++) {
	    if (*windowPtr == winPtr) {
		index1 = (windowPtr - windows);
	    }
	    if (*windowPtr == winPtr2) {
		index2 = (windowPtr - windows);
	    }
	}
	if (index1 == -1) {
	    Tcl_Panic("winPtr window not found");
	} else if (index2 == -1) {
	    Tcl_Panic("winPtr2 window not found");
	}

	ckfree(windows);

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings,
		"argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", NULL
    };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED
    };
    int index;
    (void)tkwin;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't change state of %s: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObjStruct(interp, objv[3], optionStrings,
		sizeof(char *), "argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (winPtr->flags & TK_EMBEDDED) {
	    int state = 0;

	    switch (index) {







|


|




|


|


<













|
|







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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    static const char *const optionStrings[] = {
	"iconic", "normal", "withdrawn", "zoomed", NULL
    };
    enum options {
	OPT_ICONIC, OPT_NORMAL, OPT_WITHDRAWN, OPT_ZOOMED
    };
    int index;


    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't change state of %s: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL);
	    return TCL_ERROR;
	}
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings,
		"argument", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (winPtr->flags & TK_EMBEDDED) {
	    int state = 0;

	    switch (index) {
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
	    switch (state) {
	    case NormalState:	stateStr = "normal";	break;
	    case IconicState:	stateStr = "iconic";	break;
	    case WithdrawnState: stateStr = "withdrawn"; break;
	    case ZoomState:	stateStr = "zoomed";	break;
	    }
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(stateStr, -1));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|







5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
	    switch (state) {
	    case NormalState:	stateStr = "normal";	break;
	    case IconicState:	stateStr = "iconic";	break;
	    case WithdrawnState: stateStr = "withdrawn"; break;
	    case ZoomState:	stateStr = "zoomed";	break;
	    }
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(stateStr, TCL_INDEX_NONE));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
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
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    TkSizeT length;
    HWND wrapper;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {







|


|




|

<







5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373

5374
5375
5376
5377
5378
5379
5380
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    const char *argv3;
    Tcl_Size length;
    HWND wrapper;


    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
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
	    Tcl_WCharToUtfDString(buf, wcslen(buf), &titleString);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tcl_DStringValue(&titleString),
		    Tcl_DStringLength(&titleString)));
	    Tcl_DStringFree(&titleString);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (wmPtr->title ? wmPtr->title : winPtr->nameUid), -1));
	}
    } else {
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	argv3 = TkGetStringFromObj(objv[3], &length);
	wmPtr->title = (char *)ckalloc(length + 1);
	memcpy(wmPtr->title, argv3, length + 1);

	if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) {
	    Tcl_DString titleString;

	    Tcl_DStringInit(&titleString);
	    Tcl_UtfToWCharDString(wmPtr->title, -1, &titleString);
	    SetWindowTextW(wrapper, (LPCWSTR) Tcl_DStringValue(&titleString));
	    Tcl_DStringFree(&titleString);
	}
    }
    return TCL_OK;
}








|





|







|







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
	    Tcl_WCharToUtfDString(buf, wcslen(buf), &titleString);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    Tcl_DStringValue(&titleString),
		    Tcl_DStringLength(&titleString)));
	    Tcl_DStringFree(&titleString);
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (wmPtr->title ? wmPtr->title : winPtr->nameUid), TCL_INDEX_NONE));
	}
    } else {
	if (wmPtr->title != NULL) {
	    ckfree(wmPtr->title);
	}
	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);
	    Tcl_UtfToWCharDString(wmPtr->title, TCL_INDEX_NONE, &titleString);
	    SetWindowTextW(wrapper, (LPCWSTR) Tcl_DStringValue(&titleString));
	    Tcl_DStringFree(&titleString);
	}
    }
    return TCL_OK;
}

5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
 */

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *containerPtr = wmPtr->containerPtr, **containerPtrPtr = &containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {







|







5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
 */

static int
WmTransientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    TkWindow *containerPtr = wmPtr->containerPtr, **containerPtrPtr = &containerPtr, *w;
    WmInfo *wmPtr2;

    if ((objc != 3) && (objc != 4)) {
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}
	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	     w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }







|







5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a container: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}
	for (w = containerPtr; w != NULL && w->wmInfoPtr != NULL;
	    w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    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(







|


|



<







5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575

5576
5577
5578
5579
5580
5581
5582
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    TCL_UNUSED(Tk_Window),	/* Main window of the application. */
    TkWindow *winPtr,		/* Toplevel to work with */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Size objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;


    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

static void
WmWaitVisibilityOrMapProc(
    ClientData clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL)
	return;







|







5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

static void
WmWaitVisibilityOrMapProc(
    void *clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL)
	return;
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
		    == (PBaseSize|PResizeInc))) {
	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel
     * units and there's no easy way to translate them to grid units since the







|
<







5713
5714
5715
5716
5717
5718
5719
5720

5721
5722
5723
5724
5725
5726
5727
	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & PBaseSize) == PBaseSize)) {

	return;
    }

    /*
     * If gridding was previously off, then forget about any window size
     * requests made by the user or via "wm geometry": these are in pixel
     * units and there's no easy way to translate them to grid units since the
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*







|







5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
    }

    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;







|







5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
    }

    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~PBaseSize;
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelEventProc(
    ClientData clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;








|







5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelEventProc(
    void *clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;
    (void)dummy;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr) {
	if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	    SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
		Tk_ReqHeight(tkwin));
	}







|




<







5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887

5888
5889
5890
5891
5892
5893
5894
 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelReqProc(
    TCL_UNUSED(void *),		/* Not used. */
    Tk_Window tkwin)		/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;


    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr) {
	if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	    SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
		Tk_ReqHeight(tkwin));
	}
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
 *	from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    int x, y;			/* Position of border on desktop. */
    int width, height;		/* Size of client area. */
    int min, max;
    RECT rect;
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;







|







5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
 *	from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    void *clientData)	/* Pointer to the window's record. */
{
    int x, y;			/* Position of border on desktop. */
    int width, height;		/* Size of client area. */
    int min, max;
    RECT rect;
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
 *	Vroot window information is refreshed if it is out of date.
 *
 *----------------------------------------------------------------------
 */

void
Tk_GetVRootGeometry(
    Tk_Window tkwin,		/* Window whose virtual root is to be
				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr, int *heightPtr)
				/* Store dimensions of virtual root here. */
{
    (void)tkwin;

    *xPtr = GetSystemMetrics(SM_XVIRTUALSCREEN);
    *yPtr = GetSystemMetrics(SM_YVIRTUALSCREEN);
    *widthPtr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    *heightPtr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}

/*







|






<
<







6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440


6441
6442
6443
6444
6445
6446
6447
 *	Vroot window information is refreshed if it is out of date.
 *
 *----------------------------------------------------------------------
 */

void
Tk_GetVRootGeometry(
    TCL_UNUSED(Tk_Window),/* Window whose virtual root is to be
				 * queried. */
    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
				 * here. */
    int *widthPtr, int *heightPtr)
				/* Store dimensions of virtual root here. */
{


    *xPtr = GetSystemMetrics(SM_XVIRTUALSCREEN);
    *yPtr = GetSystemMetrics(SM_YVIRTUALSCREEN);
    *widthPtr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    *heightPtr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}

/*
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
	     */

	    const char *name = Tk_GetAtomName((Tk_Window) winPtr, protocol);

	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			name));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);







|







6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
	     */

	    const char *name = Tk_GetAtomName((Tk_Window) winPtr, protocol);

	    Tcl_Preserve(protPtr);
	    interp = protPtr->interp;
	    Tcl_Preserve(interp);
	    result = Tcl_EvalEx(interp, protPtr->command, TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
	    if (result != TCL_OK) {
		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
			"\n    (command for \"%s\" window manager protocol)",
			name));
		Tcl_BackgroundException(interp, result);
	    }
	    Tcl_Release(interp);
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
    XEvent event;

    /*
     * Generate a ConfigureNotify event.
     */

    event.type = ConfigureNotify;
    event.xconfigure.serial = winPtr->display->request;
    event.xconfigure.send_event = False;
    event.xconfigure.display = winPtr->display;
    event.xconfigure.event = winPtr->window;
    event.xconfigure.window = winPtr->window;
    event.xconfigure.border_width = winPtr->changes.border_width;
    event.xconfigure.override_redirect = winPtr->atts.override_redirect;
    event.xconfigure.x = winPtr->changes.x;







|







7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
    XEvent event;

    /*
     * Generate a ConfigureNotify event.
     */

    event.type = ConfigureNotify;
    event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display);
    event.xconfigure.send_event = False;
    event.xconfigure.display = winPtr->display;
    event.xconfigure.event = winPtr->window;
    event.xconfigure.window = winPtr->window;
    event.xconfigure.border_width = winPtr->changes.border_width;
    event.xconfigure.override_redirect = winPtr->atts.override_redirect;
    event.xconfigure.x = winPtr->changes.x;
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
InstallColormaps(
    HWND hwnd,			/* Toplevel wrapper window whose colormaps
				 * should be installed. */
    int message,		/* Either WM_PALETTECHANGED or
				 * WM_QUERYNEWPALETTE */
    int isForemost)		/* 1 if window is foremost, else 0 */
{
    int i;
    HDC dc;
    HPALETTE oldPalette;
    TkWindow *winPtr = GetTopLevel(hwnd);
    WmInfo *wmPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));








|







7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
InstallColormaps(
    HWND hwnd,			/* Toplevel wrapper window whose colormaps
				 * should be installed. */
    int message,		/* Either WM_PALETTECHANGED or
				 * WM_QUERYNEWPALETTE */
    int isForemost)		/* 1 if window is foremost, else 0 */
{
    Tcl_Size i;
    HDC dc;
    HPALETTE oldPalette;
    TkWindow *winPtr = GetTopLevel(hwnd);
    WmInfo *wmPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525

static void
RefreshColormap(
    Colormap colormap,
    TkDisplay *dispPtr)
{
    WmInfo *wmPtr;
    int i;

    for (wmPtr = dispPtr->firstWmPtr; wmPtr != NULL; wmPtr = wmPtr->nextPtr) {
	if (wmPtr->cmapCount > 0) {
	    for (i = 0; i < wmPtr->cmapCount; i++) {
		if ((wmPtr->cmapList[i]->atts.colormap == colormap)
			&& Tk_IsMapped(wmPtr->cmapList[i])) {
		    InvalidateSubTree(wmPtr->cmapList[i], colormap);







|







7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416

static void
RefreshColormap(
    Colormap colormap,
    TkDisplay *dispPtr)
{
    WmInfo *wmPtr;
    Tcl_Size i;

    for (wmPtr = dispPtr->firstWmPtr; wmPtr != NULL; wmPtr = wmPtr->nextPtr) {
	if (wmPtr->cmapCount > 0) {
	    for (i = 0; i < wmPtr->cmapCount; i++) {
		if ((wmPtr->cmapList[i]->atts.colormap == colormap)
			&& Tk_IsMapped(wmPtr->cmapList[i])) {
		    InvalidateSubTree(wmPtr->cmapList[i], colormap);
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
	/*
	 * Display and/or color resolution changed.
	 */

	winPtr = GetTopLevel(hwnd);
	if (winPtr) {
	    Screen *screen = Tk_Screen(winPtr);
	    if (screen->root_depth != (int) wParam) {
		/*
		 * Color resolution changed, so do extensive rebuild of
		 * display parameters. This will affect the display for all Tk
		 * windows. We will receive this event for each toplevel, but
		 * this check makes us update only once, for the first
		 * toplevel that receives the message.
		 */

		TkWinDisplayChanged(Tk_Display(winPtr));
	    } else {
		HDC dc = GetDC(NULL);

		screen->width = LOWORD(lParam);		/* horizontal res */
		screen->height = HIWORD(lParam);	/* vertical res */
		screen->mwidth = MulDiv(screen->width, 254,
			GetDeviceCaps(dc, LOGPIXELSX) * 10);
		screen->mheight = MulDiv(screen->height, 254,
			GetDeviceCaps(dc, LOGPIXELSY) * 10);
		ReleaseDC(NULL, dc);
	    }
	    if (Tk_Depth(winPtr) != (int) wParam) {
		/*
		 * Defer the window depth check to here so that each toplevel
		 * will properly update depth info.







|












|
|
|

|







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
	/*
	 * Display and/or color resolution changed.
	 */

	winPtr = GetTopLevel(hwnd);
	if (winPtr) {
	    Screen *screen = Tk_Screen(winPtr);
	    if (DefaultDepthOfScreen(screen) != (int) wParam) {
		/*
		 * Color resolution changed, so do extensive rebuild of
		 * display parameters. This will affect the display for all Tk
		 * windows. We will receive this event for each toplevel, but
		 * this check makes us update only once, for the first
		 * toplevel that receives the message.
		 */

		TkWinDisplayChanged(Tk_Display(winPtr));
	    } else {
		HDC dc = GetDC(NULL);

		WidthOfScreen(screen) = LOWORD(lParam);		/* horizontal res */
		HeightOfScreen(screen) = HIWORD(lParam);	/* vertical res */
		WidthMMOfScreen(screen) = MulDiv(WidthOfScreen(screen), 254,
			GetDeviceCaps(dc, LOGPIXELSX) * 10);
		HeightMMOfScreen(screen) = MulDiv(HeightOfScreen(screen), 254,
			GetDeviceCaps(dc, LOGPIXELSY) * 10);
		ReleaseDC(NULL, dc);
	    }
	    if (Tk_Depth(winPtr) != (int) wParam) {
		/*
		 * Defer the window depth check to here so that each toplevel
		 * will properly update depth info.
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
	result = 0;
	goto done;

    case WM_NCHITTEST: {
	winPtr = GetTopLevel(hwnd);
	if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) {
	    /*
	     * This window is outside the grab heirarchy, so don't let any of
	     * the normal non-client processing occur. Note that this
	     * implementation is not strictly correct because the grab might
	     * change between now and when the event would have been processed
	     * by Tk, but it's close enough.
	     */

	    result = HTCLIENT;







|







7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
	result = 0;
	goto done;

    case WM_NCHITTEST: {
	winPtr = GetTopLevel(hwnd);
	if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) {
	    /*
	     * This window is outside the grab hierarchy, so don't let any of
	     * the normal non-client processing occur. Note that this
	     * implementation is not strictly correct because the grab might
	     * change between now and when the event would have been processed
	     * by Tk, but it's close enough.
	     */

	    result = HTCLIENT;
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
    if (!IsWindow(eventPtr->hwnd)) {
	return 1;
    }

    /*
     * If the toplevel is in the middle of a move or size operation then
     * we must delay handling of this event to avoid stealing the focus
     * while the window manage is in control.
     */

    if (eventPtr->flagPtr && *eventPtr->flagPtr) {
	return 0;
    }

    /*







|







8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
    if (!IsWindow(eventPtr->hwnd)) {
	return 1;
    }

    /*
     * If the toplevel is in the middle of a move or size operation then
     * we must delay handling of this event to avoid stealing the focus
     * while the window manager is in control.
     */

    if (eventPtr->flagPtr && *eventPtr->flagPtr) {
	return 0;
    }

    /*
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelWithdraw --
 *
 *	This function is to be used by a window manage to withdraw a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May withdraw the toplevel window.







|







8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelWithdraw --
 *
 *	This function is to be used by a window manager to withdraw a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May withdraw the toplevel window.
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelIconify --
 *
 *	This function is to be used by a window manage to iconify a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May iconify the toplevel window.







|







8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelIconify --
 *
 *	This function is to be used by a window manager to iconify a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May iconify the toplevel window.
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelDeiconify --
 *
 *	This function is to be used by a window manage to deiconify a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May deiconify the toplevel window.







|







8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelDeiconify --
 *
 *	This function is to be used by a window manager to deiconify a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May deiconify the toplevel window.
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinGeometryIsControlledByWm --
 *
 *	This function is to be used by a window manage to see if wm has
 *	canceled geometry control.
 *
 * Results:
 *	0 - if the window manager has canceled its control
 *	1 - if the window manager controls the geometry
 *
 * Side effects:







|







8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinGeometryIsControlledByWm --
 *
 *	This function is to be used by a window manager to see if wm has
 *	canceled geometry control.
 *
 * Results:
 *	0 - if the window manager has canceled its control
 *	1 - if the window manager controls the geometry
 *
 * Side effects:
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelDetachWindow --
 *
 *	This function is to be usd for changing a toplevel's wrapper or
 *	container.
 *
 * Results:
 *	The window's wrapper/container is removed.
 *
 * Side effects:
 *	None.







|







8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelDetachWindow --
 *
 *	This function is to be used for changing a toplevel's wrapper or
 *	container.
 *
 * Results:
 *	The window's wrapper/container is removed.
 *
 * Side effects:
 *	None.

Changes to win/tkWinX.c.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

























36
37
38
39
40
41
42
/*
 * tkWinX.c --
 *
 *	This file contains Windows emulation procedures for X routines.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright (c) 1994 Software Research Associates, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */


#include "tkWinInt.h"

#include <commctrl.h>
#ifdef _MSC_VER
#   pragma comment (lib, "comctl32.lib")
#   pragma comment (lib, "advapi32.lib")
#endif


/*
 * The zmouse.h file includes the definition for WM_MOUSEWHEEL.
 */

#include <zmouse.h>

/*
 * WM_MOUSEHWHEEL is normally defined by Winuser.h for Vista/2008 or later,
 * but is also usable on 2000/XP if IntelliPoint drivers are installed.
 */

#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif


























/*
 * imm.h is needed by HandleIMEComposition
 */

#include <imm.h>
#ifdef _MSC_VER





|
|
|





>







>















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
 * tkWinX.c --
 *
 *	This file contains Windows emulation procedures for X routines.
 *
 * 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.
 */

#define XLIB_ILLEGAL_ACCESS
#include "tkWinInt.h"

#include <commctrl.h>
#ifdef _MSC_VER
#   pragma comment (lib, "comctl32.lib")
#   pragma comment (lib, "advapi32.lib")
#endif


/*
 * The zmouse.h file includes the definition for WM_MOUSEWHEEL.
 */

#include <zmouse.h>

/*
 * WM_MOUSEHWHEEL is normally defined by Winuser.h for Vista/2008 or later,
 * but is also usable on 2000/XP if IntelliPoint drivers are installed.
 */

#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif

/* A WM_MOUSEWHEEL message sent by a trackpad contains the number of pixels as
 * the delta value, while low precision scrollwheels always send an integer
 * multiple of WHEELDELTA (= 120) as the delta value.
 */

#define WHEELDELTA 120

/*
 * Our heuristic for deciding whether a WM_MOUSEWHEEL message
 * comes from a high resolution scrolling device is that we
 * assume it is high resolution unless there are two consecutive
 * delta values that are both multiples of 120.  This is static,
 * rather than thread-specific, since input devices are shared
 * by all threads.
 */

static int lastMod = 0;

/*
 * The serial field of TouchpadScroll events is a counter for
 * events of this type only.
 */

static unsigned long scrollCounter = 0;

/*
 * imm.h is needed by HandleIMEComposition
 */

#include <imm.h>
#ifdef _MSC_VER
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
 */

typedef struct {
    TkDisplay *winDisplay;	/* TkDisplay structure that represents Windows
				 * screen. */
    int updatingClipboard;	/* If 1, we are updating the clipboard. */
    int surrogateBuffer;	/* Buffer for first of surrogate pair. */
    DWORD vWheelTickPrev;	/* For high resolution wheels (vertical). */
    DWORD hWheelTickPrev;	/* For high resolution wheels (horizontal). */
    short vWheelAcc;		/* For high resolution wheels (vertical). */
    short hWheelAcc;		/* For high resolution wheels (horizontal). */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of functions used in this file.
 */








<
<
<
<







103
104
105
106
107
108
109




110
111
112
113
114
115
116
 */

typedef struct {
    TkDisplay *winDisplay;	/* TkDisplay structure that represents Windows
				 * screen. */
    int updatingClipboard;	/* If 1, we are updating the clipboard. */
    int surrogateBuffer;	/* Buffer for first of surrogate pair. */




} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations of functions used in this file.
 */

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
 *----------------------------------------------------------------------
 */

void
TkGetServerInfo(
    Tcl_Interp *interp,		/* The server information is returned in this
				 * interpreter's result. */
    Tk_Window tkwin)		/* Token for window; this selects a particular
				 * display and server. */
{
    static char buffer[32]; /* Empty string means not initialized yet. */
    OSVERSIONINFOW os;
    (void)tkwin;

    if (!buffer[0]) {
	HMODULE handle = GetModuleHandleW(L"NTDLL");
	int(__stdcall *getversion)(void *) = (int(__stdcall *)(void *))
		(void *)GetProcAddress(handle, "RtlGetVersion");
	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	if (!getversion || getversion(&os)) {
	    GetVersionExW(&os);
	}
	/* Write the first character last, preventing multi-thread issues. */
	sprintf(buffer+1, "indows %d.%d %d %s", (int)os.dwMajorVersion,
		(int)os.dwMinorVersion, (int)os.dwBuildNumber,
#ifdef _WIN64
		"Win64"
#else
		"Win32"
#endif
	);







|




<


<
<
<
<
<
|
<

|







139
140
141
142
143
144
145
146
147
148
149
150

151
152





153

154
155
156
157
158
159
160
161
162
 *----------------------------------------------------------------------
 */

void
TkGetServerInfo(
    Tcl_Interp *interp,		/* The server information is returned in this
				 * interpreter's result. */
    TCL_UNUSED(Tk_Window))		/* Token for window; this selects a particular
				 * display and server. */
{
    static char buffer[32]; /* Empty string means not initialized yet. */
    OSVERSIONINFOW os;


    if (!buffer[0]) {





	GetVersionExW(&os);

	/* Write the first character last, preventing multi-thread issues. */
	snprintf(buffer+1, sizeof(buffer)-1, "indows %d.%d %d %s", (int)os.dwMajorVersion,
		(int)os.dwMinorVersion, (int)os.dwBuildNumber,
#ifdef _WIN64
		"Win64"
#else
		"Win32"
#endif
	);
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
 *	Removes window classes from the system.
 *
 *----------------------------------------------------------------------
 */

void
TkWinXCleanup(
    ClientData clientData)
{
    HINSTANCE hInstance = (HINSTANCE)clientData;

    /*
     * Clean up our own class.
     */








|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
 *	Removes window classes from the system.
 *
 *----------------------------------------------------------------------
 */

void
TkWinXCleanup(
    void *clientData)
{
    HINSTANCE hInstance = (HINSTANCE)clientData;

    /*
     * Clean up our own class.
     */

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkGetDefaultScreenName(
    Tcl_Interp *dummy,		/* Not used. */
    const char *screenName)	/* If NULL, use default string. */
{
    (void)dummy;

    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = winScreenName;
    }
    return screenName;
}

/*







|


<
<







409
410
411
412
413
414
415
416
417
418


419
420
421
422
423
424
425
 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkGetDefaultScreenName(
    TCL_UNUSED(Tcl_Interp *),
    const char *screenName)	/* If NULL, use default string. */
{


    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = winScreenName;
    }
    return screenName;
}

/*
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
void
TkWinDisplayChanged(
    Display *display)
{
    HDC dc;
    Screen *screen;

    if (display == NULL || display->screens == NULL) {
	return;
    }
    screen = display->screens;

    dc = GetDC(NULL);
    screen->width = GetDeviceCaps(dc, HORZRES);
    screen->height = GetDeviceCaps(dc, VERTRES);
    screen->mwidth = MulDiv(screen->width, 254,
	    GetDeviceCaps(dc, LOGPIXELSX) * 10);
    screen->mheight = MulDiv(screen->height, 254,
	    GetDeviceCaps(dc, LOGPIXELSY) * 10);

    /*
     * On windows, when creating a color bitmap, need two pieces of
     * information: the number of color planes and the number of pixels per
     * plane. Need to remember both quantities so that when constructing an
     * HBITMAP for offscreen rendering, we can specify the correct value for
     * the number of planes. Otherwise the HBITMAP won't be compatible with
     * the HWND and we'll just get blank spots copied onto the screen.
     */

    screen->ext_data = (XExtData *)INT2PTR(GetDeviceCaps(dc, PLANES));
    screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);

    if (screen->root_visual != NULL) {
	ckfree(screen->root_visual);
    }
    screen->root_visual = (Visual *)ckalloc(sizeof(Visual));
    screen->root_visual->visualid = 0;
    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
	screen->root_visual->c_class = PseudoColor;
	screen->root_visual->red_mask = 0x0;
	screen->root_visual->green_mask = 0x0;
	screen->root_visual->blue_mask = 0x0;
    } else if (screen->root_depth == 4) {
	screen->root_visual->c_class = StaticColor;
	screen->root_visual->map_entries = 16;
    } else if (screen->root_depth == 8) {
	screen->root_visual->c_class = StaticColor;
	screen->root_visual->map_entries = 256;
    } else if (screen->root_depth == 12) {
	screen->root_visual->c_class = TrueColor;
	screen->root_visual->map_entries = 32;
	screen->root_visual->red_mask = 0xf0;
	screen->root_visual->green_mask = 0xf000;
	screen->root_visual->blue_mask = 0xf00000;
    } else if (screen->root_depth == 16) {
	screen->root_visual->c_class = TrueColor;
	screen->root_visual->map_entries = 64;
	screen->root_visual->red_mask = 0xf8;
	screen->root_visual->green_mask = 0xfc00;
	screen->root_visual->blue_mask = 0xf80000;
    } else if (screen->root_depth >= 24) {
	screen->root_visual->c_class = TrueColor;
	screen->root_visual->map_entries = 256;
	screen->root_visual->red_mask = 0xff;
	screen->root_visual->green_mask = 0xff00;
	screen->root_visual->blue_mask = 0xff0000;
    }
    screen->root_visual->bits_per_rgb = screen->root_depth;
    ReleaseDC(NULL, dc);

    if (screen->cmap != None) {
	XFreeColormap(display, screen->cmap);
    }
    screen->cmap = XCreateColormap(display, None, screen->root_visual,
	    AllocNone);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay/XkbOpenDisplay --







|


|


|
|
|

|




















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|


|
|

|







442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
void
TkWinDisplayChanged(
    Display *display)
{
    HDC dc;
    Screen *screen;

    if (display == NULL || (((_XPrivDisplay)(display))->screens) == NULL) {
	return;
    }
    screen = (((_XPrivDisplay)(display))->screens);

    dc = GetDC(NULL);
    WidthOfScreen(screen) = GetDeviceCaps(dc, HORZRES);
    HeightOfScreen(screen) = GetDeviceCaps(dc, VERTRES);
    WidthMMOfScreen(screen) = MulDiv(WidthOfScreen(screen), 254,
	    GetDeviceCaps(dc, LOGPIXELSX) * 10);
    HeightMMOfScreen(screen) = MulDiv(HeightOfScreen(screen), 254,
	    GetDeviceCaps(dc, LOGPIXELSY) * 10);

    /*
     * On windows, when creating a color bitmap, need two pieces of
     * information: the number of color planes and the number of pixels per
     * plane. Need to remember both quantities so that when constructing an
     * HBITMAP for offscreen rendering, we can specify the correct value for
     * the number of planes. Otherwise the HBITMAP won't be compatible with
     * the HWND and we'll just get blank spots copied onto the screen.
     */

    screen->ext_data = (XExtData *)INT2PTR(GetDeviceCaps(dc, PLANES));
    screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);

    if (screen->root_visual != NULL) {
	ckfree(screen->root_visual);
    }
    screen->root_visual = (Visual *)ckalloc(sizeof(Visual));
    screen->root_visual->visualid = 0;
    if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
	DefaultVisualOfScreen(screen)->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
	DefaultVisualOfScreen(screen)->c_class = PseudoColor;
	DefaultVisualOfScreen(screen)->red_mask = 0x0;
	DefaultVisualOfScreen(screen)->green_mask = 0x0;
	DefaultVisualOfScreen(screen)->blue_mask = 0x0;
    } else if (DefaultDepthOfScreen(screen) == 4) {
	DefaultVisualOfScreen(screen)->c_class = StaticColor;
	DefaultVisualOfScreen(screen)->map_entries = 16;
    } else if (DefaultDepthOfScreen(screen) == 8) {
	DefaultVisualOfScreen(screen)->c_class = StaticColor;
	DefaultVisualOfScreen(screen)->map_entries = 256;
    } else if (DefaultDepthOfScreen(screen) == 12) {
	DefaultVisualOfScreen(screen)->c_class = TrueColor;
	DefaultVisualOfScreen(screen)->map_entries = 32;
	DefaultVisualOfScreen(screen)->red_mask = 0xf0;
	DefaultVisualOfScreen(screen)->green_mask = 0xf000;
	DefaultVisualOfScreen(screen)->blue_mask = 0xf00000;
    } else if (DefaultDepthOfScreen(screen) == 16) {
	DefaultVisualOfScreen(screen)->c_class = TrueColor;
	DefaultVisualOfScreen(screen)->map_entries = 64;
	DefaultVisualOfScreen(screen)->red_mask = 0xf8;
	DefaultVisualOfScreen(screen)->green_mask = 0xfc00;
	DefaultVisualOfScreen(screen)->blue_mask = 0xf80000;
    } else if (DefaultDepthOfScreen(screen) >= 24) {
	DefaultVisualOfScreen(screen)->c_class = TrueColor;
	DefaultVisualOfScreen(screen)->map_entries = 256;
	DefaultVisualOfScreen(screen)->red_mask = 0xff;
	DefaultVisualOfScreen(screen)->green_mask = 0xff00;
	DefaultVisualOfScreen(screen)->blue_mask = 0xff0000;
    }
    DefaultVisualOfScreen(screen)->bits_per_rgb = DefaultDepthOfScreen(screen);
    ReleaseDC(NULL, dc);

    if (DefaultColormapOfScreen(screen) != None) {
	XFreeColormap(display, DefaultColormapOfScreen(screen));
    }
    DefaultColormapOfScreen(screen) = XCreateColormap(display, None, DefaultVisualOfScreen(screen),
	    AllocNone);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay/XkbOpenDisplay --
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{
    Display *display;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    DWORD initialWheelTick;

    if (tsdPtr->winDisplay != NULL) {
	if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) {
	    return tsdPtr->winDisplay;
	} else {
	    return NULL;
	}
    }

    display = XkbOpenDisplay((char *)display_name, NULL, NULL, NULL, NULL, NULL);
    TkWinDisplayChanged(display);

    tsdPtr->winDisplay =(TkDisplay *) ckalloc(sizeof(TkDisplay));
    ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay));
    tsdPtr->winDisplay->display = display;
    tsdPtr->updatingClipboard = FALSE;
    initialWheelTick = GetTickCount();
    tsdPtr->vWheelTickPrev = initialWheelTick;
    tsdPtr->hWheelTickPrev = initialWheelTick;
    tsdPtr->vWheelAcc = 0;
    tsdPtr->hWheelAcc = 0;

    /*
     * Key map info must be available immediately, because of "send event".
     */
    TkpInitKeymapInfo(tsdPtr->winDisplay);

    /*







<


|






|



|


<
<
<
<
<







537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559





560
561
562
563
564
565
566
TkDisplay *
TkpOpenDisplay(
    const char *display_name)
{
    Display *display;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if (tsdPtr->winDisplay != NULL) {
	if (!strcmp(DisplayString(tsdPtr->winDisplay->display), display_name)) {
	    return tsdPtr->winDisplay;
	} else {
	    return NULL;
	}
    }

    display = XkbOpenDisplay(display_name, NULL, NULL, NULL, NULL, NULL);
    TkWinDisplayChanged(display);

    tsdPtr->winDisplay =(TkDisplay *) ckalloc(sizeof(TkDisplay));
    memset(tsdPtr->winDisplay, 0, sizeof(TkDisplay));
    tsdPtr->winDisplay->display = display;
    tsdPtr->updatingClipboard = FALSE;






    /*
     * Key map info must be available immediately, because of "send event".
     */
    TkpInitKeymapInfo(tsdPtr->winDisplay);

    /*
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
	const char *name,
	int *ev_rtrn,
	int *err_rtrn,
	int *major_rtrn,
	int *minor_rtrn,
	int *reason)
{
    Display *display = (Display *)ckalloc(sizeof(Display));
    Screen *screen = (Screen *)ckalloc(sizeof(Screen));
    TkWinDrawable *twdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));

    ZeroMemory(screen, sizeof(Screen));
    ZeroMemory(display, sizeof(Display));

    /*
     * Note that these pixel values are not palette relative.
     */

    screen->white_pixel = RGB(255, 255, 255);
    screen->black_pixel = RGB(0, 0, 0);
    screen->cmap = None;

    display->screens		= screen;
    display->nscreens		= 1;
    display->default_screen	= 0;

    twdPtr->type = TWD_WINDOW;
    twdPtr->window.winPtr = NULL;
    twdPtr->window.handle = NULL;
    screen->root = (Window)twdPtr;
    screen->display = display;

    display->display_name = (char  *)ckalloc(strlen(name) + 1);
    strcpy(display->display_name, name);

    display->cursor_font = 1;
    display->nscreens = 1;
    display->request = 1;
    display->qlen = 0;

    if (ev_rtrn) *ev_rtrn = 0;
    if (err_rtrn) *err_rtrn = 0;
    if (major_rtrn) *major_rtrn = 0;
    if (minor_rtrn) *minor_rtrn = 0;
    if (reason) *reason = 0;

    return display;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
 *







|



|
|





|
|
|









|




<










|







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
	const char *name,
	int *ev_rtrn,
	int *err_rtrn,
	int *major_rtrn,
	int *minor_rtrn,
	int *reason)
{
    _XPrivDisplay display = (_XPrivDisplay)ckalloc(sizeof(Display));
    Screen *screen = (Screen *)ckalloc(sizeof(Screen));
    TkWinDrawable *twdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable));

    memset(screen, 0, sizeof(Screen));
    memset(display, 0, sizeof(Display));

    /*
     * Note that these pixel values are not palette relative.
     */

    WhitePixelOfScreen(screen) = RGB(255, 255, 255);
    BlackPixelOfScreen(screen) = RGB(0, 0, 0);
    DefaultColormapOfScreen(screen) = None;

    display->screens		= screen;
    display->nscreens		= 1;
    display->default_screen	= 0;

    twdPtr->type = TWD_WINDOW;
    twdPtr->window.winPtr = NULL;
    twdPtr->window.handle = NULL;
    screen->root = (Window)twdPtr;
    screen->display = (Display *)display;

    display->display_name = (char  *)ckalloc(strlen(name) + 1);
    strcpy(display->display_name, name);


    display->nscreens = 1;
    display->request = 1;
    display->qlen = 0;

    if (ev_rtrn) *ev_rtrn = 0;
    if (err_rtrn) *err_rtrn = 0;
    if (major_rtrn) *major_rtrn = 0;
    if (minor_rtrn) *minor_rtrn = 0;
    if (reason) *reason = 0;

    return (Display *)display;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCloseDisplay --
 *
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
 *----------------------------------------------------------------------
 */

void
TkpCloseDisplay(
    TkDisplay *dispPtr)
{
    Display *display = dispPtr->display;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (dispPtr != tsdPtr->winDisplay) {
	Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on another display");
	return; /* not reached */
    }

    tsdPtr->winDisplay = NULL;

    if (display->display_name != NULL) {
	ckfree(display->display_name);
    }
    if (display->screens != NULL) {
	if (display->screens->root_visual != NULL) {
	    ckfree(display->screens->root_visual);
	}
	if (display->screens->root != None) {
	    ckfree((char *)display->screens->root);
	}
	if (display->screens->cmap != None) {
	    XFreeColormap(display, display->screens->cmap);
	}
	ckfree(display->screens);
    }
    ckfree(display);
}

/*
 *----------------------------------------------------------------------
 *







|













|
|
|

|
|

|
|

|







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
 *----------------------------------------------------------------------
 */

void
TkpCloseDisplay(
    TkDisplay *dispPtr)
{
    _XPrivDisplay display = (_XPrivDisplay)dispPtr->display;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (dispPtr != tsdPtr->winDisplay) {
	Tcl_Panic("TkpCloseDisplay: tried to call TkpCloseDisplay on another display");
	return; /* not reached */
    }

    tsdPtr->winDisplay = NULL;

    if (display->display_name != NULL) {
	ckfree(display->display_name);
    }
    if (ScreenOfDisplay(display, 0) != NULL) {
	if (DefaultVisualOfScreen(ScreenOfDisplay(display, 0)) != NULL) {
	    ckfree(DefaultVisualOfScreen(ScreenOfDisplay(display, 0)));
	}
	if (RootWindowOfScreen(ScreenOfDisplay(display, 0)) != None) {
	    ckfree((void *)RootWindowOfScreen(ScreenOfDisplay(display, 0)));
	}
	if (DefaultColormapOfScreen(ScreenOfDisplay(display, 0)) != None) {
	    XFreeColormap(display, DefaultColormapOfScreen(ScreenOfDisplay(display, 0)));
	}
	ckfree(ScreenOfDisplay(display, 0));
    }
    ckfree(display);
}

/*
 *----------------------------------------------------------------------
 *
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
 *	Plays a sounds out the system speakers.
 *
 *----------------------------------------------------------------------
 */

int
XBell(
    Display *display,
    int percent)
{
    (void)display;
    (void)percent;

    MessageBeep(MB_OK);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *







|
|

<
<
<







720
721
722
723
724
725
726
727
728
729



730
731
732
733
734
735
736
 *	Plays a sounds out the system speakers.
 *
 *----------------------------------------------------------------------
 */

int
XBell(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int))
{



    MessageBeep(MB_OK);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018

    winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
    if (!winPtr || winPtr->window == None) {
	return;
    }

    memset(&event.x, 0, sizeof(XEvent));
    event.x.xany.serial = winPtr->display->request++;
    event.x.xany.send_event = False;
    event.x.xany.display = winPtr->display;
    event.x.xany.window = winPtr->window;

    switch (message) {
    case WM_PAINT: {
	PAINTSTRUCT ps;







|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022

    winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
    if (!winPtr || winPtr->window == None) {
	return;
    }

    memset(&event.x, 0, sizeof(XEvent));
    event.x.xany.serial = LastKnownRequestProcessed(winPtr->display)++;
    event.x.xany.send_event = False;
    event.x.xany.display = winPtr->display;
    event.x.xany.window = winPtr->window;

    switch (message) {
    case WM_PAINT: {
	PAINTSTRUCT ps;
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

	/*
	 * Now set up event specific fields.
	 */

	switch (message) {
	case WM_MOUSEWHEEL: {
	    /*
	     * Support for high resolution wheels (vertical).
	     */

	    DWORD wheelTick = GetTickCount();

	    if (wheelTick - tsdPtr->vWheelTickPrev < 1500) {
		tsdPtr->vWheelAcc += (short) HIWORD(wParam);
	    } else {
		tsdPtr->vWheelAcc = (short) HIWORD(wParam);
	    }
	    tsdPtr->vWheelTickPrev = wheelTick;
	    if (abs(tsdPtr->vWheelAcc) < WHEEL_DELTA) {
		return;
	    }

	    /*
	     * We have invented a new X event type to handle this event. It
	     * still uses the KeyPress struct. However, the keycode field has


	     * been overloaded to hold the zDelta of the wheel. Set nbytes to
	     * 0 to prevent conversion of the keycode to a keysym in
	     * TkpGetString. [Bug 1118340].
	     */












	    event.x.type = MouseWheelEvent;
	    event.x.xany.send_event = -1;
	    event.key.nbytes = 0;
	    event.x.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
	    tsdPtr->vWheelAcc = tsdPtr->vWheelAcc % WHEEL_DELTA;


	    break;
	}
	case WM_MOUSEHWHEEL: {
	    /*
	     * Support for high resolution wheels (horizontal).
	     */

	    DWORD wheelTick = GetTickCount();

	    if (wheelTick - tsdPtr->hWheelTickPrev < 1500) {
		tsdPtr->hWheelAcc -= (short) HIWORD(wParam);
	    } else {
		tsdPtr->hWheelAcc = -((short) HIWORD(wParam));
	    }
	    tsdPtr->hWheelTickPrev = wheelTick;
	    if (abs(tsdPtr->hWheelAcc) < WHEEL_DELTA) {
		return;
	    }

	    /*
	     * We have invented a new X event type to handle this event. It



	     * still uses the KeyPress struct. However, the keycode field has
	     * been overloaded to hold the zDelta of the wheel. Set nbytes to

	     * 0 to prevent conversion of the keycode to a keysym in
	     * TkpGetString. [Bug 1118340].
	     */












	    event.x.type = MouseWheelEvent;
	    event.x.xany.send_event = -1;
	    event.key.nbytes = 0;
	    event.x.xkey.state |= ShiftMask;
	    event.x.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
	    tsdPtr->hWheelAcc = tsdPtr->hWheelAcc % WHEEL_DELTA;


	    break;
	}
	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	    /*
	     * Check for translated characters in the event queue. Setting
	     * xany.send_event to -1 indicates to the Windows implementation







<
<
<

<
<
<
<
<
<
<
<
<
<
<
<

<
|
>
>
|
|



>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
<
>
>



<
<
<

<
<
<
<
<
<
<
<
<
<
<
<

<
>
>
>
|
<
>
|
|


>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
<
>
>







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

	/*
	 * Now set up event specific fields.
	 */

	switch (message) {
	case WM_MOUSEWHEEL: {
















	    /*

	     * Send an Xevent using a KeyPress struct, but with the type field
	     * set to MouseWheelEvent for low resolution scrolls and to
	     * TouchpadScroll for high resolution scroll events. The Y delta
	     * is stored in the low order 16 bits of the keycode field.  Set
	     * nbytes to 0 to prevent conversion of the keycode to a keysym in
	     * TkpGetString. [Bug 1118340].
	     */

	    int delta = (short) HIWORD(wParam);
	    int mod = delta % WHEELDELTA;
	    if ( mod != 0 || lastMod != 0) {
		/* High resolution. */
		event.x.type = TouchpadScroll;
		event.x.xany.send_event = -1;
		event.key.nbytes = 0;
		event.x.xkey.state = state;
		event.x.xany.serial = scrollCounter++;
		event.x.xkey.keycode = (unsigned int) delta;
	    } else {
		event.x.type = MouseWheelEvent;
		event.x.xany.send_event = -1;
		event.key.nbytes = 0;
		event.x.xkey.keycode = (unsigned int) delta;

	    }
	    lastMod = mod;
	    break;
	}
	case WM_MOUSEHWHEEL: {
















	    /*

	     * Send an Xevent using a KeyPress struct, but with the type field
	     * set to MouseWheelEvent for low resolution scrolls and to
	     * TouchpadScroll for high resolution scroll events.  For low
	     * resolution scrolls the X delta is stored in the keycode field

	     * and For high resolution scrolls the X delta is in the high word
	     * of the keycode.  Set nbytes to 0 to prevent conversion of the
	     * keycode to a keysym in TkpGetString. [Bug 1118340].
	     */

	    int delta = (short) HIWORD(wParam);
	    int mod = delta % WHEELDELTA;
	    if ( mod != 0 || lastMod != 0) {
		/* High resolution. */
		event.x.type = TouchpadScroll;
		event.x.xany.send_event = -1;
		event.key.nbytes = 0;
		event.x.xkey.state = state;
		event.x.xany.serial = scrollCounter++;
		event.x.xkey.keycode = (unsigned int)(-(delta << 16));
	    } else {
		event.x.type = MouseWheelEvent;
		event.x.xany.send_event = -1;
		event.key.nbytes = 0;
		event.x.xkey.state |= ShiftMask;
		event.x.xkey.keycode = delta;

	    }
	    lastMod = mod;
	    break;
	}
	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	    /*
	     * Check for translated characters in the event queue. Setting
	     * xany.send_event to -1 indicates to the Windows implementation
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
    TkKeyEvent *xkey,
    UINT type)
{
    MSG msg;

    xkey->nbytes = 0;

    while ((xkey->nbytes < XMaxTransChars)
	    && (PeekMessageA(&msg, NULL, type, type, PM_NOREMOVE) != 0)) {
	if (msg.message != type) {
	    break;
	}

	GetMessageA(&msg, NULL, type, type);








|







1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
    TkKeyEvent *xkey,
    UINT type)
{
    MSG msg;

    xkey->nbytes = 0;

    while ((xkey->nbytes < sizeof(xkey->trans_chars))
	    && (PeekMessageA(&msg, NULL, type, type, PM_NOREMOVE) != 0)) {
	if (msg.message != type) {
	    break;
	}

	GetMessageA(&msg, NULL, type, type);

1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529

	return;
    }

    if (charsetInfo.ciACP == CP_UTF8) {
	strcpy(codepage, "utf-8");
    } else {
	sprintf(codepage, "cp%d", charsetInfo.ciACP);
    }

    if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
	/*
	 * The encoding is not supported by Tcl.
	 */








|







1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530

	return;
    }

    if (charsetInfo.ciACP == CP_UTF8) {
	strcpy(codepage, "utf-8");
    } else {
	snprintf(codepage, sizeof(codepage), "cp%d", charsetInfo.ciACP);
    }

    if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
	/*
	 * The encoding is not supported by Tcl.
	 */

1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
	 * Note that the event *must* be zeroed out first; Tk plays cunning
	 * games with the overalls structure. [Bug 2992129]
	 */

	winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

	memset(&event, 0, sizeof(XEvent));
	event.xkey.serial = winPtr->display->request++;
	event.xkey.send_event = -3;
	event.xkey.display = winPtr->display;
	event.xkey.window = winPtr->window;
	event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum);
	event.xkey.subwindow = None;
	event.xkey.state = TkWinGetModifierState();
	event.xkey.time = TkpGetMS();







|







1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
	 * Note that the event *must* be zeroed out first; Tk plays cunning
	 * games with the overalls structure. [Bug 2992129]
	 */

	winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);

	memset(&event, 0, sizeof(XEvent));
	event.xkey.serial = LastKnownRequestProcessed(winPtr->display)++;
	event.xkey.send_event = -3;
	event.xkey.display = winPtr->display;
	event.xkey.window = winPtr->window;
	event.xkey.root = RootWindow(winPtr->display, winPtr->screenNum);
	event.xkey.subwindow = None;
	event.xkey.state = TkWinGetModifierState();
	event.xkey.time = TkpGetMS();
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
 *	None.
 *
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
     Display *dpy)		/* Ignored on Windows */
{
    LASTINPUTINFO li;
    (void)dpy;

    li.cbSize = sizeof(li);
    if (!GetLastInputInfo(&li)) {
	return -1;
    }

    /*







|


<







1950
1951
1952
1953
1954
1955
1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
 *	None.
 *
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
     TCL_UNUSED(Display *))
{
    LASTINPUTINFO li;


    li.cbSize = sizeof(li);
    if (!GetLastInputInfo(&li)) {
	return -1;
    }

    /*
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
{
    INPUT inp;
    (void)dpy;

    inp.type = INPUT_MOUSE;
    inp.mi.dx = 0;
    inp.mi.dy = 0;
    inp.mi.mouseData = 0;
    inp.mi.dwFlags = MOUSEEVENTF_MOVE;
    inp.mi.time = 0;







|


<







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994

1995
1996
1997
1998
1999
2000
2001
 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    TCL_UNUSED(Display *))
{
    INPUT inp;


    inp.type = INPUT_MOUSE;
    inp.mi.dx = 0;
    inp.mi.dy = 0;
    inp.mi.mouseData = 0;
    inp.mi.dwFlags = MOUSEEVENTF_MOVE;
    inp.mi.time = 0;

Changes to win/ttkWinMonitor.c.

1
2
3
4
5
6
7
8
9
10
11
12
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include <tkWinInt.h>
#include "ttk/ttkTheme.h"

#if !defined(WM_THEMECHANGED)
#define WM_THEMECHANGED 0x031A
#endif

static LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);




|







1
2
3
4
5
6
7
8
9
10
11
12
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include "tkWinInt.h"
#include "ttk/ttkTheme.h"

#if !defined(WM_THEMECHANGED)
#define WM_THEMECHANGED 0x031A
#endif

static LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161

/*
 * Windows-specific platform initialization:
 */

MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);
MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd);


MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp)
{
    HWND hwnd;

    hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp);
    Ttk_RegisterCleanup(interp, hwnd, DestroyThemeMonitorWindow);

    TtkWinTheme_Init(interp, hwnd);
    TtkXPTheme_Init(interp, hwnd);

    return TCL_OK;
}







>













142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

/*
 * Windows-specific platform initialization:
 */

MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);
MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd);
MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp);

MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp)
{
    HWND hwnd;

    hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp);
    Ttk_RegisterCleanup(interp, hwnd, DestroyThemeMonitorWindow);

    TtkWinTheme_Init(interp, hwnd);
    TtkXPTheme_Init(interp, hwnd);

    return TCL_OK;
}

Changes to win/ttkWinTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* winTheme.c - Copyright (C) 2004 Pat Thoyts <[email protected]>
 */

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include <tkWinInt.h>

#ifndef DFCS_HOT	/* Windows 98/Me, Windows 2000/XP only */
#define DFCS_HOT 0
#endif

#include "ttk/ttkTheme.h"

|






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 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 2000/XP only */
#define DFCS_HOT 0
#endif

#include "ttk/ttkTheme.h"

92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 * +++ FrameControlElement --
 * 	General-purpose element for things drawn with DrawFrameControl
 */
typedef struct {
    const char *name;		/* element name */
    int classId;		/* class id for DrawFrameControl */
    int partId;			/* part id for DrawFrameControl  */
    unsigned cxId;			/* system metric ids for width/height... */
    unsigned cyId;			/* ... or size if FIXEDSIZE bit set */
    const Ttk_StateTable *stateMap;	/* map Tk states to Win32 flags */
    Ttk_Padding margins;	/* additional placement padding */
} FrameControlElementData;


#define _FIXEDSIZE  0x80000000UL
#define _HALFMETRIC 0x40000000UL
#define FIXEDSIZE(id) (id|_FIXEDSIZE)
#define HALFMETRIC(id) (id|_HALFMETRIC)
#define GETMETRIC(m) \
    ((m) & _FIXEDSIZE ? (int)((m) & ~_FIXEDSIZE) : GetSystemMetrics((m)&0xFFFFFFF))

static const FrameControlElementData FrameControlElements[] = {
    { "Checkbutton.indicator",
	DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(13), FIXEDSIZE(13),
	checkbutton_statemap, {0,0,4,0} },
    { "Radiobutton.indicator",
    	DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(13), FIXEDSIZE(13),
	checkbutton_statemap, {0,0,4,0} },
    { "uparrow",
    	DFC_SCROLL, DFCS_SCROLLUP, SM_CXVSCROLL, SM_CYVSCROLL,
	arrow_statemap, {0,0,0,0} },
    { "downarrow",
    	DFC_SCROLL, DFCS_SCROLLDOWN, SM_CXVSCROLL, SM_CYVSCROLL,
	arrow_statemap, {0,0,0,0} },







|
|




>







|

|


|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 * +++ FrameControlElement --
 * 	General-purpose element for things drawn with DrawFrameControl
 */
typedef struct {
    const char *name;		/* element name */
    int classId;		/* class id for DrawFrameControl */
    int partId;			/* part id for DrawFrameControl  */
    unsigned cxId;		/* system metric ids for width/height... */
    unsigned cyId;		/* ... or size if FIXEDSIZE bit set */
    const Ttk_StateTable *stateMap;	/* map Tk states to Win32 flags */
    Ttk_Padding margins;	/* additional placement padding */
} FrameControlElementData;

#define BASE_DIM    16
#define _FIXEDSIZE  0x80000000UL
#define _HALFMETRIC 0x40000000UL
#define FIXEDSIZE(id) (id|_FIXEDSIZE)
#define HALFMETRIC(id) (id|_HALFMETRIC)
#define GETMETRIC(m) \
    ((m) & _FIXEDSIZE ? (int)((m) & ~_FIXEDSIZE) : GetSystemMetrics((m)&0xFFFFFFF))

static FrameControlElementData FrameControlElements[] = {
    { "Checkbutton.indicator",
	DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(BASE_DIM), FIXEDSIZE(BASE_DIM),
	checkbutton_statemap, {0,0,4,0} },
    { "Radiobutton.indicator",
    	DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(BASE_DIM), FIXEDSIZE(BASE_DIM),
	checkbutton_statemap, {0,0,4,0} },
    { "uparrow",
    	DFC_SCROLL, DFCS_SCROLLUP, SM_CXVSCROLL, SM_CYVSCROLL,
	arrow_statemap, {0,0,0,0} },
    { "downarrow",
    	DFC_SCROLL, DFCS_SCROLLDOWN, SM_CXVSCROLL, SM_CYVSCROLL,
	arrow_statemap, {0,0,0,0} },
140
141
142
143
144
145
146
147


148


149
150
151
152
153

154


155






156
157
158

159
160
161
162
163
164


165


166
167
168
169
170
171
172
173
174
175
176
177
178

    { 0,0,0,0,0,0, {0,0,0,0} }
};

/* ---------------------------------------------------------------------- */

static void FrameControlElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    FrameControlElementData *p = (FrameControlElementData *)clientData;
    int cx = GETMETRIC(p->cxId);
    int cy = GETMETRIC(p->cyId);
    (void)elementRecord;

    (void)tkwin;


    (void)paddingPtr;







    if (p->cxId & _HALFMETRIC) cx /= 2;
    if (p->cyId & _HALFMETRIC) cy /= 2;

    *widthPtr = cx + Ttk_PaddingWidth(p->margins);
    *heightPtr = cy + Ttk_PaddingHeight(p->margins);
}

static void FrameControlElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)


{
    FrameControlElementData *elementData = (FrameControlElementData *)clientData;
    RECT rc = BoxToRect(Ttk_PadBox(b, elementData->margins));
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    (void)elementRecord;

    DrawFrameControl(hdc, &rc,
	elementData->classId,
	elementData->partId|Ttk_StateTableLookup(elementData->stateMap, state));
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}








|
>
>
|
>
>




|
>
|
>
>
|
>
>
>
>
>
>



>





|
>
>
|
>
>





<







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196

    { 0,0,0,0,0,0, {0,0,0,0} }
};

/* ---------------------------------------------------------------------- */

static void FrameControlElementSize(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    FrameControlElementData *p = (FrameControlElementData *)clientData;
    int cx = GETMETRIC(p->cxId);
    int cy = GETMETRIC(p->cyId);

    if ((p->cxId & _FIXEDSIZE) && cx == BASE_DIM) {
	double scalingLevel = TkScalingLevel(tkwin);
	cx *= scalingLevel;
	cy *= scalingLevel;

	/*
	 * Update the corresponding element of the array FrameControlElements
	 */
	p->cxId = FIXEDSIZE(cx);
	p->cyId = FIXEDSIZE(cy);
    }

    if (p->cxId & _HALFMETRIC) cx /= 2;
    if (p->cyId & _HALFMETRIC) cy /= 2;

    *widthPtr = cx + Ttk_PaddingWidth(p->margins);
    *heightPtr = cy + Ttk_PaddingHeight(p->margins);
}

static void FrameControlElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    FrameControlElementData *elementData = (FrameControlElementData *)clientData;
    RECT rc = BoxToRect(Ttk_PadBox(b, elementData->margins));
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);


    DrawFrameControl(hdc, &rc,
	elementData->classId,
	elementData->partId|Ttk_StateTableLookup(elementData->stateMap, state));
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214

215

216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

static const Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-relief",TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj), "flat" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void BorderElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;


    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void BorderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    BorderElement *border = (BorderElement *)elementRecord;
    RECT rc = BoxToRect(b);
    int relief = TK_RELIEF_FLAT;
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)state;

    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);

    if (relief != TK_RELIEF_FLAT) {
	UINT xFlags = (relief == TK_RELIEF_SOLID) ? BF_FLAT : 0;
	hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
	DrawEdge(hdc, &rc, ReliefToEdge(relief), BF_RECT | xFlags);







<
<
<
|
|
|
|
|
>
|





>
|
>
|
>
>






<
<







212
213
214
215
216
217
218



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242


243
244
245
246
247
248
249

static const Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-relief",TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj), "flat" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void BorderElementSize(



    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    BorderElement *border = (BorderElement *)elementRecord;
    RECT rc = BoxToRect(b);
    int relief = TK_RELIEF_FLAT;
    TkWinDCState dcState;
    HDC hdc;



    Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);

    if (relief != TK_RELIEF_FLAT) {
	UINT xFlags = (relief == TK_RELIEF_SOLID) ? BF_FLAT : 0;
	hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
	DrawEdge(hdc, &rc, ReliefToEdge(relief), BF_RECT | xFlags);
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273

274

275


276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
    	offsetof(FieldElement,backgroundObj), "white" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;


    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void FieldElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)state;

    Tk_Fill3DRectangle(
	tkwin, d, bg, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT);

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);







<
<
<
|
|
|
|
|
>
|





>
|
>
|
>
>






<
<







271
272
273
274
275
276
277



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301


302
303
304
305
306
307
308
static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
    	offsetof(FieldElement,backgroundObj), "white" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FieldElementSize(



    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;



    Tk_Fill3DRectangle(
	tkwin, d, bg, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT);

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
316
317
318
319
320
321
322

323



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
	offsetof(ButtonBorderElement,highlightColorObj), "black" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void ButtonBorderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_RAISED;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    short int cx, cy;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
    cx = GetSystemMetrics(SM_CXEDGE);
    cy = GetSystemMetrics(SM_CYEDGE);

    /* Space for default indicator:







>
|
>
>
>
|





<
<
<
<







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351




352
353
354
355
356
357
358
	offsetof(ButtonBorderElement,highlightColorObj), "black" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void ButtonBorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_RAISED;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    short int cx, cy;





    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
    cx = GetSystemMetrics(SM_CXEDGE);
    cy = GetSystemMetrics(SM_CYEDGE);

    /* Space for default indicator:
348
349
350
351
352
353
354

355

356


357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    cx += 2;
    cy += 2;

    *paddingPtr = Ttk_MakePadding(cx,cy,cx,cy);
}

static void ButtonBorderElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    TkWinDCState dcState;
    HDC hdc;
    RECT rc;
    (void)dummy;

    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
	XColor *highlightColor =
	    Tk_GetColorFromObj(tkwin, bd->highlightColorObj);







>
|
>
|
>
>







<







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
    cx += 2;
    cy += 2;

    *paddingPtr = Ttk_MakePadding(cx,cy,cx,cy);
}

static void ButtonBorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    TkWinDCState dcState;
    HDC hdc;
    RECT rc;


    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
	XColor *highlightColor =
	    Tk_GetColorFromObj(tkwin, bd->highlightColorObj);
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421
422


423
424
425
426
427

428
429
430
431
432
433
434
435

/*------------------------------------------------------------------------
 * +++ Focus element.
 * 	Draw dashed focus rectangle.
 */

static void FocusElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;


    *paddingPtr = Ttk_UniformPadding(1);
}

static void FocusElementDraw(


    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    (void)dummy;
    (void)elementRecord;


    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    	DrawFocusRect(hdc, &rc);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }







<
<
<
|
|
|
|
|
>
|




>
>
|
|
<
<
|
>
|







424
425
426
427
428
429
430



431
432
433
434
435
436
437
438
439
440
441
442
443
444
445


446
447
448
449
450
451
452
453
454
455

/*------------------------------------------------------------------------
 * +++ Focus element.
 * 	Draw dashed focus rectangle.
 */

static void FocusElementSize(



    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(1);
}

static void FocusElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,


    Ttk_Box b,
    Ttk_State state)
{
    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    	DrawFocusRect(hdc, &rc);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
455
456
457
458
459
460
461

462

463


464
465
466
467
468
469
470
471
472
473
    { "-focusfill", TK_OPTION_COLOR,
	offsetof(FillFocusElement,fillColorObj), "white" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

	/* @@@ FIX THIS */
static void FillFocusElementDraw(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    Drawable d, Ttk_Box b, unsigned int state)


{
    FillFocusElement *focus = (FillFocusElement *)elementRecord;
    (void)dummy;

    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	XColor *fillColor = Tk_GetColorFromObj(tkwin, focus->fillColorObj);
	GC gc = Tk_GCForColor(fillColor, d);
	HDC hdc;







>
|
>
|
>
>


<







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
    { "-focusfill", TK_OPTION_COLOR,
	offsetof(FillFocusElement,fillColorObj), "white" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

	/* @@@ FIX THIS */
static void FillFocusElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    FillFocusElement *focus = (FillFocusElement *)elementRecord;


    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	XColor *fillColor = Tk_GetColorFromObj(tkwin, focus->fillColorObj);
	GC gc = Tk_GCForColor(fillColor, d);
	HDC hdc;
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

/*
 * ComboboxFocusElement --
 * 	Read-only comboboxes have a filled focus ring, editable ones do not.
 */
static void ComboboxFocusElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    if (state & TTK_STATE_READONLY) {
    	FillFocusElementDraw(clientData, elementRecord, tkwin, d, b, state);
    }
}

static const Ttk_ElementSpec ComboboxFocusElementSpec = {







|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518

/*
 * ComboboxFocusElement --
 * 	Read-only comboboxes have a filled focus ring, editable ones do not.
 */
static void ComboboxFocusElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    if (state & TTK_STATE_READONLY) {
    	FillFocusElementDraw(clientData, elementRecord, tkwin, d, b, state);
    }
}

static const Ttk_ElementSpec ComboboxFocusElementSpec = {
531
532
533
534
535
536
537
538


539


540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
    cd->PatternBitmap = CreateBitmap(8, 8, 1, 1, Pattern);
    cd->PatternBrush  = CreatePatternBrush(cd->PatternBitmap);
    Ttk_RegisterCleanup(interp, cd, TroughClientDataDeleteProc);
    return cd;
}

static void TroughElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)


{
    TroughClientData *cd = (TroughClientData *)clientData;
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    HBRUSH hbr;
    COLORREF bk, oldbk, oldtxt;
    (void)elementRecord;
    (void)state;

    hbr = (HBRUSH)SelectObject(hdc, GetSysColorBrush(COLOR_SCROLLBAR));
    bk = GetSysColor(COLOR_3DHIGHLIGHT);
    oldtxt = SetTextColor(hdc, GetSysColor(COLOR_3DFACE));
    oldbk = SetBkColor(hdc, bk);

    /* WAS: if (bk (COLOR_3DHIGHLIGHT) == GetSysColor(COLOR_WINDOW)) ... */







|
>
>
|
>
>






<
<







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572


573
574
575
576
577
578
579
    cd->PatternBitmap = CreateBitmap(8, 8, 1, 1, Pattern);
    cd->PatternBrush  = CreatePatternBrush(cd->PatternBitmap);
    Ttk_RegisterCleanup(interp, cd, TroughClientDataDeleteProc);
    return cd;
}

static void TroughElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    TroughClientData *cd = (TroughClientData *)clientData;
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    HBRUSH hbr;
    COLORREF bk, oldbk, oldtxt;



    hbr = (HBRUSH)SelectObject(hdc, GetSysColorBrush(COLOR_SCROLLBAR));
    bk = GetSysColor(COLOR_3DHIGHLIGHT);
    oldtxt = SetTextColor(hdc, GetSysColor(COLOR_3DFACE));
    oldbk = SetBkColor(hdc, bk);

    /* WAS: if (bk (COLOR_3DHIGHLIGHT) == GetSysColor(COLOR_WINDOW)) ... */
582
583
584
585
586
587
588

589

590


591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608


609
610


611
612
613
614
615
616
617
618
619
620
621
622
623

static const Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ThumbElement *thumbPtr = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, thumbPtr->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = GetSystemMetrics(SM_CXHTHUMB);
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = GetSystemMetrics(SM_CYVTHUMB);
    }
}

static void ThumbElementDraw(


    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)


{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)elementRecord;

    /* Windows doesn't show a thumb when the scrollbar is disabled */
    if (state & TTK_STATE_DISABLED)
	return;

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);







>
|
>
|
>
>



<
<
<

|










>
>
|
|
>
>




<
<







607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622



623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644


645
646
647
648
649
650
651

static const Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ThumbElement *thumbPtr = (ThumbElement *)elementRecord;
    Ttk_Orient orient;




    Ttk_GetOrientFromObj(NULL, thumbPtr->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = GetSystemMetrics(SM_CXHTHUMB);
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = GetSystemMetrics(SM_CYVTHUMB);
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;



    /* Windows doesn't show a thumb when the scrollbar is disabled */
    if (state & TTK_STATE_DISABLED)
	return;

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
644
645
646
647
648
649
650

651

652


653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670


671
672


673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697













698

699



700
701




702


























703
704













705












706










707






















































































708
709
710
711
712


713
714


715
716
717
718
719
720
721
722
723
724
725
726
727
728
static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
      "horizontal" },
      { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,

    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = (GetSystemMetrics(SM_CXHTHUMB) / 2) | 1;
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = (GetSystemMetrics(SM_CYVTHUMB) / 2) | 1;
    }
}

static void SliderElementDraw(


    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)


{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;
    (void)dummy;
    (void)elementRecord;
    (void)state;

    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Notebook elements.
 */














static void ClientElementSize(

    void *dummy, void *elementRecord, Tk_Window tkwin,



    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{




    (void)dummy;


























    (void)elementRecord;
    (void)tkwin;













    (void)widthPtr;












    (void)heightPtr;

































































































    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void ClientElementDraw(


    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)


{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    (void)dummy;
    (void)elementRecord;
    (void)state;

    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_SOFT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,







>
|
>
|
>
>



<
<
<

|










>
>
|
|
>
>




<
<
<


















>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
|

>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
|
|
>
>




<
<
<







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687



688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709



710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
static const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
      "horizontal" },
      { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;




    Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = (GetSystemMetrics(SM_CXHTHUMB) / 2) | 1;
	*heightPtr = GetSystemMetrics(SM_CYHSCROLL);
    } else {
	*widthPtr = GetSystemMetrics(SM_CXVSCROLL);
	*heightPtr = (GetSystemMetrics(SM_CYVTHUMB) / 2) | 1;
    }
}

static void SliderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc;




    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Notebook elements.
 */

typedef struct {
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *backgroundObj;
} TabElement;

static const Ttk_ElementOptionSpec TabElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TabElement,borderWidthObj), "1" },
    { "-background", TK_OPTION_BORDER,
	offsetof(TabElement,backgroundObj), DEFAULT_BACKGROUND },
    {0,TK_OPTION_BOOLEAN,0,0}
};

static void TabElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    TabElement *tab = (TabElement *)elementRecord;
    int borderWidth = 1;
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;

    Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    TabElement *tab = (TabElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    XPoint pts[6];
    double scalingLevel = TkScalingLevel(tkwin);
    int cut = round(2 * scalingLevel);
    Display *disp = Tk_Display(tkwin);
    int borderWidth = 1;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    if (state & TTK_STATE_SELECTED) {
	/*
	 * Draw slightly outside of the allocated parcel,
	 * to overwrite the client area border.
	 */
	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		b.height += 2;
		break;
	    case TTK_STICK_N:
		b.height += 2; b.y -= 2;
		break;
	    case TTK_STICK_E:
		b.width += 2;
		break;
	    case TTK_STICK_W:
		b.width += 2; b.x -= 2;
		break;
	}
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    pts[0].x = b.x;  pts[0].y = b.y + b.height-1;
	    pts[1].x = b.x;  pts[1].y = b.y + cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y + b.height;
	    break;
	case TTK_STICK_N:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x;  pts[1].y = b.y + b.height-1 - cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y + b.height-1;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y + b.height-1;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + b.height-1 - cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y-1;
	    break;
	case TTK_STICK_E:
	    pts[0].x = b.x + b.width-1;  pts[0].y = b.y;
	    pts[1].x = b.x + cut;  pts[1].y = b.y;
	    pts[2].x = b.x;  pts[2].y = b.y + cut;
	    pts[3].x = b.x;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x + b.width;  pts[5].y = b.y + b.height-1;
	    break;
	case TTK_STICK_W:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x + b.width-1 - cut;  pts[1].y = b.y;
	    pts[2].x = b.x + b.width-1;  pts[2].y = b.y + cut;
	    pts[3].x = b.x + b.width-1;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + b.width-1 - cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x-1;  pts[5].y = b.y + b.height-1;
	    break;
    }

    XFillPolygon(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
	    pts, 6, Convex, CoordModeOrigin);

    Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);
    while (borderWidth--) {
	XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		pts, 4, CoordModeOrigin);
	XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		pts+3, 3, CoordModeOrigin);

	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		++pts[0].x;  ++pts[1].x;  ++pts[2].y;
		++pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_N:
		++pts[0].x;  ++pts[1].x;  --pts[2].y;
		--pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_E:
		++pts[0].y;  ++pts[1].y;  ++pts[2].x;
		++pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	    case TTK_STICK_W:
		++pts[0].y;  ++pts[1].y;  --pts[2].x;
		--pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	}
    }
}

static const Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TabElement),
    TabElementOptions,
    TabElementSize,
    TabElementDraw
};

static void ClientElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void ClientElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    RECT rc = BoxToRect(b);
    TkWinDCState dcState;
    HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);




    DrawEdge(hdc, &rc, EDGE_RAISED, BF_RECT | BF_SOFT);
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
751
752
753
754
755
756
757
758







759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
789
790
791
792
793
794
		TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))))

TTK_END_LAYOUT_TABLE

/* ---------------------------------------------------------------------- */

MODULE_SCOPE
int TtkWinTheme_Init(Tcl_Interp *interp, HWND hwnd)







{
    Ttk_Theme themePtr, parentPtr;
    const FrameControlElementData *fce = FrameControlElements;
    (void)hwnd;

    parentPtr = Ttk_GetTheme(interp, "alt");
    themePtr = Ttk_CreateTheme(interp, "winnative", parentPtr);
    if (!themePtr) {
        return TCL_ERROR;
    }

    Ttk_RegisterElementSpec(themePtr, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Button.border",
	&ButtonBorderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "focus", &FocusElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Combobox.focus",
    	&ComboboxFocusElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "slider", &SliderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec,
    	TroughClientDataInit(interp));


    Ttk_RegisterElementSpec(themePtr, "client", &ClientElementSpec, NULL);

    for (fce = FrameControlElements; fce->name != 0; ++fce) {
	Ttk_RegisterElementSpec(themePtr, fce->name,
		&FrameControlElementSpec, (void *)fce);
    }

    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::winnative", TTK_VERSION);
    return TCL_OK;
}








|
>
>
>
>
>
>
>



<



















>













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
		TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))))

TTK_END_LAYOUT_TABLE

/* ---------------------------------------------------------------------- */

MODULE_SCOPE
int TtkWinTheme_Init(
    Tcl_Interp *interp,
    TCL_UNUSED(HWND));

MODULE_SCOPE
int TtkWinTheme_Init(
    Tcl_Interp *interp,
    TCL_UNUSED(HWND))
{
    Ttk_Theme themePtr, parentPtr;
    const FrameControlElementData *fce = FrameControlElements;


    parentPtr = Ttk_GetTheme(interp, "alt");
    themePtr = Ttk_CreateTheme(interp, "winnative", parentPtr);
    if (!themePtr) {
        return TCL_ERROR;
    }

    Ttk_RegisterElementSpec(themePtr, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Button.border",
	&ButtonBorderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "focus", &FocusElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Combobox.focus",
    	&ComboboxFocusElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "slider", &SliderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec,
    	TroughClientDataInit(interp));

    Ttk_RegisterElementSpec(themePtr, "tab", &TabElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "client", &ClientElementSpec, NULL);

    for (fce = FrameControlElements; fce->name != 0; ++fce) {
	Ttk_RegisterElementSpec(themePtr, fce->name,
		&FrameControlElementSpec, (void *)fce);
    }

    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::winnative", TTK_VERSION);
    return TCL_OK;
}

Changes to win/ttkWinXPTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39




40
41
42
43
44
45
46
/*
 * 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
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * See also:
 *
 * <URL: http://msdn.microsoft.com/library/en-us/
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */

#include <tkWinInt.h>
#ifndef HAVE_UXTHEME_H
/* Stub for platforms that lack the XP theme API headers: */
int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) { return TCL_OK; }
#else

#include <windows.h>
#include <uxtheme.h>
#if defined(HAVE_VSSYM32_H) || _MSC_VER > 1500
#   include <vssym32.h>
#else
#   include <tmschema.h>
#endif

#include "ttk/ttkTheme.h"

typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,
                 HDC hdc, int iPartId, int iStateId, const RECT *pRect,
                 OPTIONAL const RECT *pClipRect);




typedef HRESULT	(STDAPICALLTYPE GetThemePartSizeProc)(HTHEME,HDC,
		 int iPartId, int iStateId,
		 RECT *prc, enum THEMESIZE eSize, SIZE *psz);
typedef int     (STDAPICALLTYPE GetThemeSysSizeProc)(HTHEME,int);
/* GetThemeTextExtent and DrawThemeText only used with BROKEN_TEXT_ELEMENT */
typedef HRESULT (STDAPICALLTYPE GetThemeTextExtentProc)(HTHEME hTheme, HDC hdc,
		 int iPartId, int iStateId, LPCWSTR pszText, int iCharCount,




|
|
|










|
<
<
<
<
<


<
|
<
<
<
<








>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18





19
20

21




22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
 * Tk theme engine which uses the Windows XP "Visual Styles" API
 * Adapted from Georgios Petasis' XP theme patch.
 *
 * 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/
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */

#include "tkWinInt.h"





#include <windows.h>
#include <uxtheme.h>

#include <vssym32.h>




#include "ttk/ttkTheme.h"

typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,
                 HDC hdc, int iPartId, int iStateId, const RECT *pRect,
                 OPTIONAL const RECT *pClipRect);
typedef HRESULT (STDAPICALLTYPE DrawThemeEdgeProc)(HTHEME hTheme,
		 HDC hdc, int iPartId, int iStateId, const RECT *pDestRect,
		 unsigned int uEdge, unsigned int uFlags,
		 OPTIONAL RECT *pContentRect);
typedef HRESULT	(STDAPICALLTYPE GetThemePartSizeProc)(HTHEME,HDC,
		 int iPartId, int iStateId,
		 RECT *prc, enum THEMESIZE eSize, SIZE *psz);
typedef int     (STDAPICALLTYPE GetThemeSysSizeProc)(HTHEME,int);
/* GetThemeTextExtent and DrawThemeText only used with BROKEN_TEXT_ELEMENT */
typedef HRESULT (STDAPICALLTYPE GetThemeTextExtentProc)(HTHEME hTheme, HDC hdc,
		 int iPartId, int iStateId, LPCWSTR pszText, int iCharCount,
54
55
56
57
58
59
60

61
62
63
64
65
66
67
typedef struct
{
    OpenThemeDataProc			*OpenThemeData;
    CloseThemeDataProc			*CloseThemeData;
    GetThemePartSizeProc		*GetThemePartSize;
    GetThemeSysSizeProc			*GetThemeSysSize;
    DrawThemeBackgroundProc		*DrawThemeBackground;

    DrawThemeTextProc		        *DrawThemeText;
    GetThemeTextExtentProc		*GetThemeTextExtent;
    IsThemeActiveProc			*IsThemeActive;
    IsAppThemedProc			*IsAppThemed;

    HWND                                stubWindow;
} XPThemeProcs;







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
typedef struct
{
    OpenThemeDataProc			*OpenThemeData;
    CloseThemeDataProc			*CloseThemeData;
    GetThemePartSizeProc		*GetThemePartSize;
    GetThemeSysSizeProc			*GetThemeSysSize;
    DrawThemeBackgroundProc		*DrawThemeBackground;
    DrawThemeEdgeProc			*DrawThemeEdge;
    DrawThemeTextProc		        *DrawThemeText;
    GetThemeTextExtentProc		*GetThemeTextExtent;
    IsThemeActiveProc			*IsThemeActive;
    IsAppThemedProc			*IsAppThemed;

    HWND                                stubWindow;
} XPThemeProcs;
107
108
109
110
111
112
113

114
115
116
117
118
119
120
	(0 != (procs->name = (name ## Proc *)(void *)GetProcAddress(handle, #name) ))

	if (   LOADPROC(OpenThemeData)
	    && LOADPROC(CloseThemeData)
	    && LOADPROC(GetThemePartSize)
	    && LOADPROC(GetThemeSysSize)
	    && LOADPROC(DrawThemeBackground)

	    && LOADPROC(GetThemeTextExtent)
	    && LOADPROC(DrawThemeText)
	    && LOADPROC(IsThemeActive)
	    && LOADPROC(IsAppThemed)
	)
	{
	    return procs;







>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
	(0 != (procs->name = (name ## Proc *)(void *)GetProcAddress(handle, #name) ))

	if (   LOADPROC(OpenThemeData)
	    && LOADPROC(CloseThemeData)
	    && LOADPROC(GetThemePartSize)
	    && LOADPROC(GetThemeSysSize)
	    && LOADPROC(DrawThemeBackground)
	    && LOADPROC(DrawThemeEdge)
	    && LOADPROC(GetThemeTextExtent)
	    && LOADPROC(DrawThemeText)
	    && LOADPROC(IsThemeActive)
	    && LOADPROC(IsAppThemed)
	)
	{
	    return procs;
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    FreeLibrary(themeData->hlibrary);
    ckfree(clientData);
}

static int
XPThemeEnabled(Ttk_Theme theme, void *clientData)


{
    XPThemeData *themeData = (XPThemeData *)clientData;
    int active = themeData->procs->IsThemeActive();
    int themed = themeData->procs->IsAppThemed();
    (void)theme;

    return (active && themed);
}

/*
 * BoxToRect --
 * 	Helper routine.  Returns a RECT data structure.







|
>
>




<







132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    FreeLibrary(themeData->hlibrary);
    ckfree(clientData);
}

static int
XPThemeEnabled(
    TCL_UNUSED(Ttk_Theme),
    void *clientData)
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    int active = themeData->procs->IsThemeActive();
    int themed = themeData->procs->IsAppThemed();


    return (active && themed);
}

/*
 * BoxToRect --
 * 	Helper routine.  Returns a RECT data structure.
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
 * then the info member is dynamically allocated. Otherwise it was
 * static data from the C object and only the ElementData needs freeing.
 */
static void DestroyElementData(void *clientData)
{
    ElementData *elementData = (ElementData *)clientData;
    if (elementData->info->flags & HEAP_ELEMENT) {
	ckfree((char *)elementData->info->statemap);
	ckfree((char *)elementData->info->className);
	ckfree((char *)elementData->info->elementName);
	ckfree((char *)elementData->info);
    }
    ckfree(clientData);
}

/*
 * InitElementData --
 * 	Looks up theme handle.  If Drawable argument is non-NULL,







|
|
|
|







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
 * then the info member is dynamically allocated. Otherwise it was
 * static data from the C object and only the ElementData needs freeing.
 */
static void DestroyElementData(void *clientData)
{
    ElementData *elementData = (ElementData *)clientData;
    if (elementData->info->flags & HEAP_ELEMENT) {
	ckfree((void *)elementData->info->statemap);
	ckfree((void *)elementData->info->className);
	ckfree((void *)elementData->info->elementName);
	ckfree((void *)elementData->info);
    }
    ckfree(clientData);
}

/*
 * InitElementData --
 * 	Looks up theme handle.  If Drawable argument is non-NULL,
488
489
490
491
492
493
494
495


496


497
498
499
500
501
502
503
504
505
506
507
508
 * +++ Generic element implementation.
 *
 * Used for elements which are handled entirely by the XP Theme API,
 * such as radiobutton and checkbutton indicators, scrollbar arrows, etc.
 */

static void GenericElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)


{
    ElementData *elementData = (ElementData *)clientData;
    HRESULT result;
    SIZE size;
    (void)elementRecord;

    if (!InitElementData(elementData, tkwin, 0))
	return;

    if (!(elementData->info->flags & IGNORE_THEMESIZE)) {
	result = elementData->procs->GetThemePartSize(
	    elementData->hTheme,







|
>
>
|
>
>




<







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

502
503
504
505
506
507
508
 * +++ Generic element implementation.
 *
 * Used for elements which are handled entirely by the XP Theme API,
 * such as radiobutton and checkbutton indicators, scrollbar arrows, etc.
 */

static void GenericElementSize(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    ElementData *elementData = (ElementData *)clientData;
    HRESULT result;
    SIZE size;


    if (!InitElementData(elementData, tkwin, 0))
	return;

    if (!(elementData->info->flags & IGNORE_THEMESIZE)) {
	result = elementData->procs->GetThemePartSize(
	    elementData->hTheme,
525
526
527
528
529
530
531
532


533


534
535
536
537
538
539
540
541
542
543
544
    if (elementData->info->flags & PAD_MARGINS) {
	*widthPtr += Ttk_PaddingWidth(elementData->info->padding);
	*heightPtr += Ttk_PaddingHeight(elementData->info->padding);
    }
}

static void GenericElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)


{
    ElementData *elementData = (ElementData *)clientData;
    RECT rc;
    (void)elementRecord;

    if (!InitElementData(elementData, tkwin, d)) {
	return;
    }

    if (elementData->info->flags & PAD_MARGINS) {
    	b = Ttk_PadBox(b, elementData->info->padding);







|
>
>
|
>
>



<







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
    if (elementData->info->flags & PAD_MARGINS) {
	*widthPtr += Ttk_PaddingWidth(elementData->info->padding);
	*heightPtr += Ttk_PaddingHeight(elementData->info->padding);
    }
}

static void GenericElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ElementData *elementData = (ElementData *)clientData;
    RECT rc;


    if (!InitElementData(elementData, tkwin, d)) {
	return;
    }

    if (elementData->info->flags & PAD_MARGINS) {
    	b = Ttk_PadBox(b, elementData->info->padding);
636
637
638
639
640
641
642
643


644


645
646
647
648
649
650
651
652
653
654
655
656

/*----------------------------------------------------------------------
 * +++ Scrollbar thumb element.
 *     Same as a GenericElement, but don't draw in the disabled state.
 */

static void ThumbElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)


{
    ElementData *elementData = (ElementData *)clientData;
    unsigned stateId = Ttk_StateTableLookup(elementData->info->statemap, state);
    RECT rc = BoxToRect(b);
    (void)elementRecord;

    /*
     * Don't draw the thumb if we are disabled.
     */
    if (state & TTK_STATE_DISABLED)
	return;








|
>
>
|
>
>




<







639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662

/*----------------------------------------------------------------------
 * +++ Scrollbar thumb element.
 *     Same as a GenericElement, but don't draw in the disabled state.
 */

static void ThumbElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ElementData *elementData = (ElementData *)clientData;
    unsigned stateId = Ttk_StateTableLookup(elementData->info->statemap, state);
    RECT rc = BoxToRect(b);


    /*
     * Don't draw the thumb if we are disabled.
     */
    if (state & TTK_STATE_DISABLED)
	return;

715
716
717
718
719
720
721





































722
723


724


725


726
727

























728
729
730
731
732


733
734





735
736









737
























738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
 *	tab is exactly at the right edge of the notebook, but
 *	not if it's simply the rightmost tab.  This information
 * 	is not available.
 *
 *	The TIS_* and TILES_* definitions are identical, so
 * 	we can use the same statemap no matter what the partId.
 */





































static void TabElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,


    Drawable d, Ttk_Box b, unsigned int state)


{


    ElementData *elementData = (ElementData *)clientData;
    int partId = elementData->info->partId;

























    RECT rc = BoxToRect(b);
    (void)elementRecord;

    if (!InitElementData(elementData, tkwin, d))
	return;


    if (state & TTK_STATE_USER1)
	partId = TABP_TABITEMLEFTEDGE;





    elementData->procs->DrawThemeBackground(
	elementData->hTheme, elementData->hDC, partId,









	Ttk_StateTableLookup(elementData->info->statemap, state), &rc, NULL);
























    FreeElementData(elementData);
}

static const Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TabElementDraw
};

/*----------------------------------------------------------------------
 * +++  Tree indicator element.
 *
 *	Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>
>
|
>
>

>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<



>
>
|
|
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
 *	tab is exactly at the right edge of the notebook, but
 *	not if it's simply the rightmost tab.  This information
 * 	is not available.
 *
 *	The TIS_* and TILES_* definitions are identical, so
 * 	we can use the same statemap no matter what the partId.
 */

static void TabElementSize(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    GenericElementSize(clientData, elementRecord, tkwin,
    	widthPtr, heightPtr, paddingPtr);

    *paddingPtr = Ttk_UniformPadding(3);
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    ElementData *elementData = (ElementData *)clientData;
    int partId = elementData->info->partId;
    int isSelected = (state & TTK_STATE_SELECTED);
    int stateId = Ttk_StateTableLookup(elementData->info->statemap, state);

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    /*
     * Correct the members of b if needed
     */
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    break;
	case TTK_STICK_N:
	    b.y -= isSelected ? 0 : 1; b.height -= isSelected ? 1 : 0;
	    break;
	case TTK_STICK_E:
	    b.width -= isSelected ? 1 : 0;
	    break;
	case TTK_STICK_W:
	    b.x -= isSelected ? 1 : 2; b.width -= isSelected ? 1 : 0;
	    break;
    }

    RECT rc = BoxToRect(b);


    if (!InitElementData(elementData, tkwin, d))
	return;

    if (nbTabsStickBit == TTK_STICK_S) {
	if (state & TTK_STATE_USER1) {
	    partId = TABP_TABITEMLEFTEDGE;
	}

	/*
	 * Draw the border and fill into rc
	 */
	elementData->procs->DrawThemeBackground(
	    elementData->hTheme, elementData->hDC, partId, stateId, &rc, NULL);
    } else {
	/*
	 * Draw the fill but no border into rc
	 */
	RECT rc2 = rc;
	--rc2.top; --rc2.left; ++rc2.bottom; ++rc2.right;
	elementData->procs->DrawThemeBackground(
	    elementData->hTheme, elementData->hDC, partId, stateId, &rc2, &rc);
    }

    /*
     * Draw a flat border at 3 edges
     */
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    break;
	case TTK_STICK_N:
	    elementData->procs->DrawThemeEdge(
		elementData->hTheme, elementData->hDC, partId, stateId, &rc,
		BDR_RAISEDINNER, BF_FLAT|BF_LEFT|BF_RIGHT|BF_BOTTOM, NULL);
	    break;
	case TTK_STICK_E:
	    elementData->procs->DrawThemeEdge(
		elementData->hTheme, elementData->hDC, partId, stateId, &rc,
		BDR_RAISEDINNER, BF_FLAT|BF_LEFT|BF_TOP|BF_BOTTOM, NULL);
	    break;
	case TTK_STICK_W:
	    elementData->procs->DrawThemeEdge(
		elementData->hTheme, elementData->hDC, partId, stateId, &rc,
		BDR_RAISEDINNER, BF_FLAT|BF_TOP|BF_RIGHT|BF_BOTTOM, NULL);
	    break;
    }

    FreeElementData(elementData);
}

static const Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    TabElementSize,
    TabElementDraw
};

/*----------------------------------------------------------------------
 * +++  Tree indicator element.
 *
 *	Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
{
    { GLPS_OPENED, 	TTK_STATE_OPEN, 0 },
    { GLPS_CLOSED, 	0,0 },
};

static void TreeIndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    if (!(state & TTK_STATE_LEAF)) {
        GenericElementDraw(clientData,elementRecord,tkwin,d,b,state);
    }
}

static const Ttk_ElementSpec TreeIndicatorElementSpec =







|







888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
{
    { GLPS_OPENED, 	TTK_STATE_OPEN, 0 },
    { GLPS_CLOSED, 	0,0 },
};

static void TreeIndicatorElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    if (!(state & TTK_STATE_LEAF)) {
        GenericElementDraw(clientData,elementRecord,tkwin,d,b,state);
    }
}

static const Ttk_ElementSpec TreeIndicatorElementSpec =
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
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
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = {0, 0};
    HRESULT hr = S_OK;
    const char *src;
    TkSizeT len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, 0))
	return;

    src = TkGetStringFromObj(element->textObj, &len);
    Tcl_DStringInit(&ds);
    hr = elementData->procs->GetThemeTextExtent(
	    elementData->hTheme,
	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, 0),
	    Tcl_UtfToWCharDString(src, len, &ds),
	    -1,
	    DT_LEFT,// | DT_BOTTOM | DT_NOPREFIX,
	    NULL,
	    &rc);

    if (SUCCEEDED(hr)) {
	*widthPtr = rc.right - rc.left;
	*heightPtr = rc.bottom - rc.top;
    }
    if (*widthPtr < 80) *widthPtr = 80;
    if (*heightPtr < 20) *heightPtr = 20;

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}

static void TextElementDraw(
    ClientData clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = BoxToRect(b);
    HRESULT hr = S_OK;
    const char *src;
    TkSizeT len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, d))
	return;

    src = TkGetStringFromObj(element->textObj, &len);
    Tcl_DStringInit(&ds);
    hr = elementData->procs->DrawThemeText(
	    elementData->hTheme,
	    elementData->hDC,
	    elementData->info->partId,
	    Ttk_StateTableLookup(elementData->info->statemap, state),
	    Tcl_UtfToWCharDString(src, len, &ds),
	    -1,
	    DT_LEFT,// | DT_BOTTOM | DT_NOPREFIX,
	    (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0,
	    &rc);

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}








|





|








|















|
|






|





|








|







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
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = {0, 0};
    HRESULT hr = S_OK;
    const char *src;
    Tcl_Size len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, 0))
	return;

    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 */,
	    NULL,
	    &rc);

    if (SUCCEEDED(hr)) {
	*widthPtr = rc.right - rc.left;
	*heightPtr = rc.bottom - rc.top;
    }
    if (*widthPtr < 80) *widthPtr = 80;
    if (*heightPtr < 20) *heightPtr = 20;

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}

static void TextElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = BoxToRect(b);
    HRESULT hr = S_OK;
    const char *src;
    Tcl_Size len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, d))
	return;

    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 */,
	    (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0,
	    &rc);

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}

1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
	SM_CXBORDER, SM_CYBORDER, SM_CXVSCROLL, SM_CYVSCROLL,
	SM_CXHSCROLL, SM_CYHSCROLL, SM_CXMENUCHECK, SM_CYMENUCHECK,
	SM_CXMENUSIZE, SM_CYMENUSIZE, SM_CXSIZE, SM_CYSIZE, SM_CXSMSIZE,
	SM_CYSMSIZE
    };

    Tcl_Obj **objv;
    int i, objc;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return TCL_ERROR;
    if (objc != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args", -1));
	Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	return TCL_ERROR;
    }
    for (i = 0; i < objc; ++i) {
	int option;
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], names,
		sizeof(char *), "system constant", 0, &option) != TCL_OK)







|




|







1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
	SM_CXBORDER, SM_CYBORDER, SM_CXVSCROLL, SM_CYVSCROLL,
	SM_CXHSCROLL, SM_CYHSCROLL, SM_CXMENUCHECK, SM_CYMENUCHECK,
	SM_CXMENUSIZE, SM_CYMENUSIZE, SM_CXSIZE, SM_CYSIZE, SM_CXSMSIZE,
	SM_CYSMSIZE
    };

    Tcl_Obj **objv;
    Tcl_Size i, objc;

    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
	return TCL_ERROR;
    if (objc != 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	return TCL_ERROR;
    }
    for (i = 0; i < objc; ++i) {
	int option;
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], names,
		sizeof(char *), "system constant", 0, &option) != TCL_OK)
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

static int
Ttk_CreateVsapiElement(
    Tcl_Interp *interp,
    void *clientData,
    Ttk_Theme theme,
    const char *elementName,
    int objc,
    Tcl_Obj *const objv[])
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    ElementInfo *elementPtr = NULL;
    ClientData elementData;
    LPCWSTR className;
    int partId = 0;
    Ttk_StateTable *stateTable;
    Ttk_Padding pad = {0, 0, 0, 0};
    int flags = 0;
    TkSizeT length = 0;
    char *name;
    LPWSTR wname;
    const Ttk_ElementSpec *elementSpec = &GenericElementSpec;
    Tcl_DString classBuf;

    static const char *const optionStrings[] =
	{ "-padding","-width","-height","-margins", "-syssize",
	  "-halfheight", "-halfwidth", NULL };
    enum { O_PADDING, O_WIDTH, O_HEIGHT, O_MARGINS, O_SYSSIZE,
	   O_HALFHEIGHT, O_HALFWIDTH };

    if (objc < 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "missing required arguments 'class' and/or 'partId'", -1));
	Tcl_SetErrorCode(interp, "TTK", "VSAPI", "REQUIRED", NULL);
	return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[1], &partId) != TCL_OK) {
	return TCL_ERROR;
    }
    name = TkGetStringFromObj(objv[0], &length);
    Tcl_DStringInit(&classBuf);
    className = Tcl_UtfToWCharDString(name, length, &classBuf);

    /* flags or padding */
    if (objc > 3) {

	int i = 3, option = 0;
	for (i = 3; i < objc; i += 2) {
	    int tmp = 0;
	    if (i == objc -1) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Missing value for \"%s\".",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TTK", "VSAPI", "MISSING", NULL);
		goto retErr;
	    }
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &option) != TCL_OK)
		goto retErr;
	    switch (option) {
	    case O_PADDING:
		if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) {
		    goto retErr;
		}
		break;







|




|





|






|
|
|
|



|







|





>
|









|
|







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

static int
Ttk_CreateVsapiElement(
    Tcl_Interp *interp,
    void *clientData,
    Ttk_Theme theme,
    const char *elementName,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    ElementInfo *elementPtr = NULL;
    void *elementData;
    LPCWSTR className;
    int partId = 0;
    Ttk_StateTable *stateTable;
    Ttk_Padding pad = {0, 0, 0, 0};
    int flags = 0;
    Tcl_Size length = 0;
    char *name;
    LPWSTR wname;
    const Ttk_ElementSpec *elementSpec = &GenericElementSpec;
    Tcl_DString classBuf;

    static const char *const optionStrings[] =
	{ "-halfheight", "-halfwidth", "-height", "-margins", "-padding",
	  "-syssize", "-width", NULL };
    enum { O_HALFHEIGHT, O_HALFWIDTH, O_HEIGHT, O_MARGINS, O_PADDING,
	   O_SYSSIZE, O_WIDTH };

    if (objc < 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "missing required arguments 'class' and/or 'partId'", TCL_INDEX_NONE));
	Tcl_SetErrorCode(interp, "TTK", "VSAPI", "REQUIRED", NULL);
	return TCL_ERROR;
    }

    if (Tcl_GetIntFromObj(interp, objv[1], &partId) != TCL_OK) {
	return TCL_ERROR;
    }
    name = Tcl_GetStringFromObj(objv[0], &length);
    Tcl_DStringInit(&classBuf);
    className = Tcl_UtfToWCharDString(name, length, &classBuf);

    /* flags or padding */
    if (objc > 3) {
	Tcl_Size i = 3;
	int option = 0;
	for (i = 3; i < objc; i += 2) {
	    int tmp = 0;
	    if (i == objc -1) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Missing value for \"%s\".",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TTK", "VSAPI", "MISSING", NULL);
		goto retErr;
	    }
	    if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		    "option", 0, &option) != TCL_OK)
		goto retErr;
	    switch (option) {
	    case O_PADDING:
		if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) {
		    goto retErr;
		}
		break;
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1225
	    }
	}
    }

    /* convert a statemap into a state table */
    if (objc > 2) {
	Tcl_Obj **specs;

	int n,j,count, status = TCL_OK;
	if (Tcl_ListObjGetElements(interp, objv[2], &count, &specs) != TCL_OK)
	    goto retErr;
	/* we over-allocate to ensure there is a terminating entry */
	stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable) * (count + 1));
	memset(stateTable, 0, sizeof(Ttk_StateTable) * (count + 1));
	for (n = 0, j = 0; status == TCL_OK && n < count; n += 2, ++j) {
	    Ttk_StateSpec spec = {0,0};







>
|







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
	    }
	}
    }

    /* convert a statemap into a state table */
    if (objc > 2) {
	Tcl_Obj **specs;
	Tcl_Size n, j, count;
	int status = TCL_OK;
	if (Tcl_ListObjGetElements(interp, objv[2], &count, &specs) != TCL_OK)
	    goto retErr;
	/* we over-allocate to ensure there is a terminating entry */
	stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable) * (count + 1));
	memset(stateTable, 0, sizeof(Ttk_StateTable) * (count + 1));
	for (n = 0, j = 0; status == TCL_OK && n < count; n += 2, ++j) {
	    Ttk_StateSpec spec = {0,0};
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
    elementPtr->className = wname;

    elementData = NewElementData(themeData->procs, elementPtr);
    Ttk_RegisterElementSpec(
	theme, elementName, elementPtr->elementSpec, elementData);

    Ttk_RegisterCleanup(interp, elementData, DestroyElementData);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
    Tcl_DStringFree(&classBuf);
    return TCL_OK;

retErr:
    Tcl_DStringFree(&classBuf);
    return TCL_ERROR;
}

/*----------------------------------------------------------------------
 * +++ Initialization routine:
 */



MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    XPThemeData *themeData;
    XPThemeProcs *procs;
    HINSTANCE hlibrary;
    Ttk_Theme themePtr, parentPtr, vistaPtr;







|











>
>







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
    elementPtr->className = wname;

    elementData = NewElementData(themeData->procs, elementPtr);
    Ttk_RegisterElementSpec(
	theme, elementName, elementPtr->elementSpec, elementData);

    Ttk_RegisterCleanup(interp, elementData, DestroyElementData);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, TCL_INDEX_NONE));
    Tcl_DStringFree(&classBuf);
    return TCL_OK;

retErr:
    Tcl_DStringFree(&classBuf);
    return TCL_ERROR;
}

/*----------------------------------------------------------------------
 * +++ Initialization routine:
 */

MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd);

MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    XPThemeData *themeData;
    XPThemeProcs *procs;
    HINSTANCE hlibrary;
    Ttk_Theme themePtr, parentPtr, vistaPtr;
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
	}
    }

    /*
     * New elements:
     */
    for (infoPtr = ElementInfoTable; infoPtr->elementName != 0; ++infoPtr) {
	ClientData clientData = NewElementData(procs, infoPtr);
	Ttk_RegisterElementSpec(
	    themePtr, infoPtr->elementName, infoPtr->elementSpec, clientData);
	Ttk_RegisterCleanup(interp, clientData, DestroyElementData);
    }

    Ttk_RegisterElementSpec(themePtr, "Scale.trough", &ttkNullElementSpec, 0);

    /*
     * Layouts:
     */
    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::xpnative", TTK_VERSION);

    return TCL_OK;
}

#endif /* HAVE_UXTHEME_H */







|
















<
<
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462


	}
    }

    /*
     * New elements:
     */
    for (infoPtr = ElementInfoTable; infoPtr->elementName != 0; ++infoPtr) {
	void *clientData = NewElementData(procs, infoPtr);
	Ttk_RegisterElementSpec(
	    themePtr, infoPtr->elementName, infoPtr->elementSpec, clientData);
	Ttk_RegisterCleanup(interp, clientData, DestroyElementData);
    }

    Ttk_RegisterElementSpec(themePtr, "Scale.trough", &ttkNullElementSpec, 0);

    /*
     * Layouts:
     */
    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::xpnative", TTK_VERSION);

    return TCL_OK;
}


Changes to win/winMain.c.

8
9
10
11
12
13
14



















15
16
17
18
19
20
21




22
23
24
25
26
27
28
29
30
31
32


33





34
35
36
37
38
39
40
41
42



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63

64
65
66
67
68
69
70
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */




















#include "tk.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <locale.h>
#include <stdlib.h>
#include <tchar.h>





#if defined(__GNUC__)
int _CRT_glob = 0;
#endif /* __GNUC__ */

#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
#ifdef __cplusplus


}





#endif
#endif /* TK_TEST */

#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
extern Tcl_PackageInitProc Registry_Init;
extern Tcl_PackageInitProc Dde_Init;
extern Tcl_PackageInitProc Dde_SafeInit;
#endif




#ifdef TCL_BROKEN_MAINARGS
static void setargv(int *argcPtr, TCHAR ***argvPtr);
#endif

/*
 * Forward declarations for procedures defined later in this file:
 */

static BOOL consoleRequired = TRUE;

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE



#   define MODULE_SCOPE extern

#endif
MODULE_SCOPE int TK_LOCAL_APPINIT(Tcl_Interp *interp);

/*
 * The following #if block allows you to change how Tcl finds the startup
 * script, prime the library or encoding paths, fiddle with the argv, etc.,
 * without needing to rewrite Tk_Main()







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>
>





<



|
|
>
>
|
>
>
>
>
>
|
|


|
|
|


>
>
>




















>
>
>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Explanation on following undef USE_TCL_STUBS by JN 2023-12-19 on the core list:
 * What's going on is related to TIP #596:
 *  Stubs support for Embedding Tcl in other applications
 *
 * If an application using Tcl_Main() is compiled with USE_TCL_STUBS,
 * Tcl_Main() will be replaced by a stub function, which loads
 * libtcl9.0.so/tcl90.dll and then calls its Tcl_MainEx(). If
 * libtcl9.0.so/tcl90.dll is not present (at runtime), a crash is what happens.
 *
 * So ... tkAppInit.c should not be compiled with USE_TCL_STUBS
 * (unless you want to use the TIP #596 functionality)
 *
 * The proper solution is to make sure that Makefile.in doesn't use
 * TCL_USE_STUBS when compiling tkAppInit.c. But that's a
 * quite big re-organization just before a b1 release. Simpler
 * is just to #undef'ine USE_TCL_STUBS, it has the same effect.
 */
#undef USE_TCL_STUBS
#include "tk.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <locale.h>
#include <stdlib.h>
#include <tchar.h>
#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
#   define Tcl_LibraryInitProc Tcl_PackageInitProc
#   define Tcl_StaticLibrary Tcl_StaticPackage
#endif

#if defined(__GNUC__)
int _CRT_glob = 0;
#endif /* __GNUC__ */


#ifdef __cplusplus
extern "C" {
#endif

#ifdef TK_TEST
extern Tcl_LibraryInitProc Tktest_Init;
#endif /* TK_TEST */

#if !defined(TCL_USE_STATIC_PACKAGES)
#   if TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 6
#	define TCL_USE_STATIC_PACKAGES 1
#   else
#	define TCL_USE_STATIC_PACKAGES 0
#   endif
#endif

#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
extern Tcl_LibraryInitProc Registry_Init;
extern Tcl_LibraryInitProc Dde_Init;
extern Tcl_LibraryInitProc Dde_SafeInit;
#endif

#ifdef __cplusplus
}
#endif
#ifdef TCL_BROKEN_MAINARGS
static void setargv(int *argcPtr, TCHAR ***argvPtr);
#endif

/*
 * Forward declarations for procedures defined later in this file:
 */

static BOOL consoleRequired = TRUE;

/*
 * The following #if block allows you to change the AppInit function by using
 * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
 * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
 */

#ifndef TK_LOCAL_APPINIT
#define TK_LOCAL_APPINIT Tcl_AppInit
#endif
#ifndef MODULE_SCOPE
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#	define MODULE_SCOPE extern
#   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()
186
187
188
189
190
191
192











193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }











    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);

    /*
     * Initialize the console only if we are running as an interactive
     * application.
     */

    if (consoleRequired) {
	if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }
#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
    if (Registry_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "registry", Registry_Init, 0);

    if (Dde_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit);
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {







>
>
>
>
>
>
>
>
>
>
>



|











<
<
<
<
<
<
<
<
<
<
<
<




|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254












255
256
257
258
259
260
261
262
263
264
265
266
int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
    if (Registry_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Registry", Registry_Init, 0);

    if (Dde_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Dde", Dde_Init, Dde_SafeInit);
#endif
    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Tk", Tk_Init, Tk_SafeInit);

    /*
     * Initialize the console only if we are running as an interactive
     * application.
     */

    if (consoleRequired) {
	if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
	    return TCL_ERROR;
	}
    }












#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Tktest", Tktest_Init, 0);
#endif /* TK_TEST */

    /*
     * Call the init procedures for included packages. Each call should look
     * like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {

Changes to win/wish.exe.manifest.in.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39




40
41
42
43
44
45
46
	    <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>




    </asmv3:application>
    <dependency>
	<dependentAssembly>
	    <assemblyIdentity
		    type="win32"
		    name="Microsoft.Windows.Common-Controls"
		    version="6.0.0.0"







<
<







>
>
>
>







24
25
26
27
28
29
30


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
	    <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}"/>


	</application>
    </compatibility>
    <asmv3:application>
	<asmv3:windowsSettings
		xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
	    <dpiAware>true</dpiAware>
	</asmv3:windowsSettings>
	<asmv3:windowsSettings
		xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">
	    <activeCodePage>UTF-8</activeCodePage>
	</asmv3:windowsSettings>
    </asmv3:application>
    <dependency>
	<dependentAssembly>
	    <assemblyIdentity
		    type="win32"
		    name="Microsoft.Windows.Common-Controls"
		    version="6.0.0.0"

Added win/x86_64-w64-mingw32-nmakehlp.exe.

cannot compute difference between binary files

Changes to xlib/X11/HPkeysym.h.

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  Hewlett-Packard shall not be liable for errors
contained herein or direct, indirect, special, incidental or
consequential damages in connection with the furnishing,
performance, or use of this material.

*/







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  Hewlett-Packard shall not be liable for errors
contained herein or direct, indirect, special, incidental or
consequential damages in connection with the furnishing,
performance, or use of this material.

*/

Changes to xlib/X11/Sunkeysym.h.

1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 1991, Oracle and/or its affiliates.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:

Changes to xlib/X11/X.h.

51
52
53
54
55
56
57








58
59
60
61




























62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
******************************************************************/

#define X_PROTOCOL	11		/* current protocol version */
#define X_PROTOCOL_REVISION 0		/* current minor version */

/* Resources */









#ifdef _WIN64
typedef unsigned __int64 XID;
#else
typedef unsigned long XID;




























#endif

typedef XID Window;
typedef XID Drawable;
#ifndef _XTYPEDEF_FONT
#  define _XTYPEDEF_FONT
typedef XID Font;
#endif
typedef XID Pixmap;
typedef XID Cursor;
typedef XID Colormap;
typedef XID GContext;
typedef XID KeySym;

typedef unsigned long Mask;

typedef unsigned long Atom;

typedef unsigned long VisualID;

typedef unsigned long Time;

typedef unsigned int KeyCode;	/* In order to use IME, the Macintosh needs
				 * to pack 3 bytes into the keyCode field in
				 * the XEvent.  In the real X.h, a KeyCode is
				 * defined as a short, which wouldn't be big
				 * enough. */

/*****************************************************************
 * RESERVED RESOURCE AND CONSTANT DEFINITIONS
 *****************************************************************/


/* #define None              0L      See bug [9e31fd9449] and below */

#define ParentRelative       1L	/* background pixmap in CreateWindow
				    and ChangeWindowAttributes */

#define CopyFromParent       0L	/* border pixmap in CreateWindow
				       and ChangeWindowAttributes
				   special VisualID and special window







>
>
>
>
>
>
>
>
|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














<
<
<
<
<
<
<
<










>
|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111








112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
******************************************************************/

#define X_PROTOCOL	11		/* current protocol version */
#define X_PROTOCOL_REVISION 0		/* current minor version */

/* Resources */

/*
 * _XSERVER64 must ONLY be defined when compiling X server sources on
 * systems where unsigned long is not 32 bits, must NOT be used in
 * client or library code.
 */
#ifndef _XSERVER64
#  ifndef _XTYPEDEF_XID
#    define _XTYPEDEF_XID
#    ifdef _WIN64
typedef unsigned __int64 XID;
#    else
typedef unsigned long XID;
#    endif
#  endif
#  ifndef _XTYPEDEF_MASK
#    define _XTYPEDEF_MASK
typedef unsigned long Mask;
#  endif
#  ifndef _XTYPEDEF_ATOM
#    define _XTYPEDEF_ATOM
typedef unsigned long Atom;		/* Also in Xdefs.h */
#  endif
typedef unsigned long VisualID;
typedef unsigned long Time;
#else
#  include <X11/Xmd.h>
#  ifndef _XTYPEDEF_XID
#    define _XTYPEDEF_XID
typedef CARD32 XID;
#  endif
#  ifndef _XTYPEDEF_MASK
#    define _XTYPEDEF_MASK
typedef CARD32 Mask;
#  endif
#  ifndef _XTYPEDEF_ATOM
#    define _XTYPEDEF_ATOM
typedef CARD32 Atom;
#  endif
typedef CARD32 VisualID;
typedef CARD32 Time;
#endif

typedef XID Window;
typedef XID Drawable;
#ifndef _XTYPEDEF_FONT
#  define _XTYPEDEF_FONT
typedef XID Font;
#endif
typedef XID Pixmap;
typedef XID Cursor;
typedef XID Colormap;
typedef XID GContext;
typedef XID KeySym;









typedef unsigned int KeyCode;	/* In order to use IME, the Macintosh needs
				 * to pack 3 bytes into the keyCode field in
				 * the XEvent.  In the real X.h, a KeyCode is
				 * defined as a short, which wouldn't be big
				 * enough. */

/*****************************************************************
 * RESERVED RESOURCE AND CONSTANT DEFINITIONS
 *****************************************************************/

/* Pert-Tk expects None to be a macro. See ticket [593eb0227c] */
#define None                 None /* See bug [9e31fd9449] and below */

#define ParentRelative       1L	/* background pixmap in CreateWindow
				    and ChangeWindowAttributes */

#define CopyFromParent       0L	/* border pixmap in CreateWindow
				       and ChangeWindowAttributes
				   special VisualID and special window
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216


/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
   state in various key-, mouse-, and button-related events. */

#define ShiftMask		(1<<0)
#define LockMask		(1<<1)

/* #define ControlMask		(1<<2) See bug [9e31fd9449] and below */
#define Mod1Mask		(1<<3)
#define Mod2Mask		(1<<4)
#define Mod3Mask		(1<<5)
#define Mod4Mask		(1<<6)
#define Mod5Mask		(1<<7)

/* See bug [9e31fd9449], this way prevents conflicts with Win32 headers */
enum _Bug9e31fd9449 { None = 0, ControlMask = (1<<2) };

/* modifier names.  Used to build a SetModifierMapping request or
   to read a GetModifierMapping request.  These correspond to the
   masks defined above. */
#define ShiftMapIndex		0
#define LockMapIndex		1
#define ControlMapIndex		2







>
|







|







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246


/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
   state in various key-, mouse-, and button-related events. */

#define ShiftMask		(1<<0)
#define LockMask		(1<<1)
/* Pert-Tk expects ControlMask to be a macro. See ticket [593eb0227c] */
#define ControlMask		ControlMask /* See bug [9e31fd9449] and below */
#define Mod1Mask		(1<<3)
#define Mod2Mask		(1<<4)
#define Mod3Mask		(1<<5)
#define Mod4Mask		(1<<6)
#define Mod5Mask		(1<<7)

/* See bug [9e31fd9449], this way prevents conflicts with Win32 headers */
enum { None = 0, ControlMask = (1<<2) };

/* modifier names.  Used to build a SetModifierMapping request or
   to read a GetModifierMapping request.  These correspond to the
   masks defined above. */
#define ShiftMapIndex		0
#define LockMapIndex		1
#define ControlMapIndex		2

Changes to xlib/X11/XF86keysym.h.

1
2
3
4
5
6

7

8
9
10
11
12
13
14
/*
 * XFree86 vendor specific keysyms.
 *
 * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
 *
 * X.Org will not be adding to the XF86 set of keysyms, though they have

 * been adopted and are considered a "standard" part of X keysym definitions.

 * XFree86 never properly commented these keysyms, so we have done our
 * best to explain the semantic meaning of these keys.
 *
 * XFree86 has removed their mail archives of the period, that might have
 * shed more light on some of these definitions. Until/unless we resurrect
 * these archives, these are from memory and usage.
 */





|
>
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * XFree86 vendor specific keysyms.
 *
 * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
 *
 * The XF86 set of keysyms is a catch-all set of defines for keysyms found
 * on various multimedia keyboards. Originally specific to XFree86 they have
 * been been adopted over time and are considered a "standard" part of X
 * keysym definitions.
 * XFree86 never properly commented these keysyms, so we have done our
 * best to explain the semantic meaning of these keys.
 *
 * XFree86 has removed their mail archives of the period, that might have
 * shed more light on some of these definitions. Until/unless we resurrect
 * these archives, these are from memory and usage.
 */
203
204
205
206
207
208
209


210
211
212
213
214
215
216
#define XF86XK_WWAN		0x1008FFB4   /* Toggle WWAN (LTE, UMTS, etc.) radio */
#define XF86XK_RFKill		0x1008FFB5   /* Toggle radios on/off */

#define XF86XK_AudioPreset	0x1008FFB6   /* Select equalizer preset, e.g. theatre-mode */

#define XF86XK_RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */



/* Keys for special action keys (hot keys) */
/* Virtual terminals on some operating systems */
#define XF86XK_Switch_VT_1	0x1008FE01
#define XF86XK_Switch_VT_2	0x1008FE02
#define XF86XK_Switch_VT_3	0x1008FE03
#define XF86XK_Switch_VT_4	0x1008FE04
#define XF86XK_Switch_VT_5	0x1008FE05







>
>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#define XF86XK_WWAN		0x1008FFB4   /* Toggle WWAN (LTE, UMTS, etc.) radio */
#define XF86XK_RFKill		0x1008FFB5   /* Toggle radios on/off */

#define XF86XK_AudioPreset	0x1008FFB6   /* Select equalizer preset, e.g. theatre-mode */

#define XF86XK_RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */

#define XF86XK_FullScreen	0x1008FFB8   /* Toggle fullscreen */

/* Keys for special action keys (hot keys) */
/* Virtual terminals on some operating systems */
#define XF86XK_Switch_VT_1	0x1008FE01
#define XF86XK_Switch_VT_2	0x1008FE02
#define XF86XK_Switch_VT_3	0x1008FE03
#define XF86XK_Switch_VT_4	0x1008FE04
#define XF86XK_Switch_VT_5	0x1008FE05
224
225
226
227
228
229
230












































































































































































































































#define XF86XK_Ungrab		0x1008FE20   /* force ungrab               */
#define XF86XK_ClearGrab	0x1008FE21   /* kill application with grab */
#define XF86XK_Next_VMode	0x1008FE22   /* next video mode available  */
#define XF86XK_Prev_VMode	0x1008FE23   /* prev. video mode available */
#define XF86XK_LogWindowTree	0x1008FE24   /* print window tree to log   */
#define XF86XK_LogGrabInfo	0x1008FE25   /* print all active grabs to log */


















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

#define XF86XK_Ungrab		0x1008FE20   /* force ungrab               */
#define XF86XK_ClearGrab	0x1008FE21   /* kill application with grab */
#define XF86XK_Next_VMode	0x1008FE22   /* next video mode available  */
#define XF86XK_Prev_VMode	0x1008FE23   /* prev. video mode available */
#define XF86XK_LogWindowTree	0x1008FE24   /* print window tree to log   */
#define XF86XK_LogGrabInfo	0x1008FE25   /* print all active grabs to log */


/*
 * Reserved range for evdev symbols: 0x10081000-0x10081FFF
 *
 * Key syms within this range must match the Linux kernel
 * input-event-codes.h file in the format:
 *     XF86XK_CamelCaseKernelName	_EVDEVK(kernel value)
 * For example, the kernel
 *   #define KEY_MACRO_RECORD_START	0x2b0
 * effectively ends up as:
 *   #define XF86XK_MacroRecordStart	0x100812b0
 *
 * For historical reasons, some keysyms within the reserved range will be
 * missing, most notably all "normal" keys that are mapped through default
 * XKB layouts (e.g. KEY_Q).
 *
 * CamelCasing is done with a human control as last authority, e.g. see VOD
 * instead of Vod for the Video on Demand key.
 *
 * The format for #defines is strict:
 *
 * #define XF86XK_FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *|
 *
 * Where
 * - alignment by tabs
 * - the _EVDEVK macro must be used
 * - the hex code must be in uppercase hex
 * - the kernel version (kver) is in the form v5.10
 * - kver and key name are within a slash-star comment (a pipe is used in
 *   this example for technical reasons)
 * These #defines are parsed by scripts. Do not stray from the given format.
 *
 * Where the evdev keycode is mapped to a different symbol, please add a
 * comment line starting with Use: but otherwise the same format, e.g.
 *  Use: XF86XK_RotationLockToggle	_EVDEVK(0x231)		   v4.16 KEY_ROTATE_LOCK_TOGGLE
 *
 */
#define _EVDEVK(_v) (0x10081000 + _v)
/* Use: XF86XK_Eject			_EVDEVK(0x0A2)		         KEY_EJECTCLOSECD */
/* Use: XF86XK_New			_EVDEVK(0x0B5)		   v2.6.14 KEY_NEW */
/* Use: XK_Redo				_EVDEVK(0x0B6)		   v2.6.14 KEY_REDO */
/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
/* Use: XF86XK_LaunchB			_EVDEVK(0x0CC)		   v2.6.28 KEY_DASHBOARD */
/* Use: XF86XK_Display			_EVDEVK(0x0E3)		   v2.6.12 KEY_SWITCHVIDEOMODE */
/* Use: XF86XK_KbdLightOnOff		_EVDEVK(0x0E4)		   v2.6.12 KEY_KBDILLUMTOGGLE */
/* Use: XF86XK_KbdBrightnessDown	_EVDEVK(0x0E5)		   v2.6.12 KEY_KBDILLUMDOWN */
/* Use: XF86XK_KbdBrightnessUp		_EVDEVK(0x0E6)		   v2.6.12 KEY_KBDILLUMUP */
/* Use: XF86XK_Send			_EVDEVK(0x0E7)		   v2.6.14 KEY_SEND */
/* Use: XF86XK_Reply			_EVDEVK(0x0E8)		   v2.6.14 KEY_REPLY */
/* Use: XF86XK_MailForward		_EVDEVK(0x0E9)		   v2.6.14 KEY_FORWARDMAIL */
/* Use: XF86XK_Save			_EVDEVK(0x0EA)		   v2.6.14 KEY_SAVE */
/* Use: XF86XK_Documents		_EVDEVK(0x0EB)		   v2.6.14 KEY_DOCUMENTS */
/* Use: XF86XK_Battery			_EVDEVK(0x0EC)		   v2.6.17 KEY_BATTERY */
/* Use: XF86XK_Bluetooth		_EVDEVK(0x0ED)		   v2.6.19 KEY_BLUETOOTH */
/* Use: XF86XK_WLAN			_EVDEVK(0x0EE)		   v2.6.19 KEY_WLAN */
/* Use: XF86XK_UWB			_EVDEVK(0x0EF)		   v2.6.24 KEY_UWB */
/* Use: XF86XK_Next_VMode		_EVDEVK(0x0F1)		   v2.6.23 KEY_VIDEO_NEXT */
/* Use: XF86XK_Prev_VMode		_EVDEVK(0x0F2)		   v2.6.23 KEY_VIDEO_PREV */
/* Use: XF86XK_MonBrightnessCycle	_EVDEVK(0x0F3)		   v2.6.23 KEY_BRIGHTNESS_CYCLE */
#define XF86XK_BrightnessAuto		_EVDEVK(0x0F4)		/* v3.16 KEY_BRIGHTNESS_AUTO */
#define XF86XK_DisplayOff		_EVDEVK(0x0F5)		/* v2.6.23 KEY_DISPLAY_OFF */
/* Use: XF86XK_WWAN			_EVDEVK(0x0F6)		   v3.13 KEY_WWAN */
/* Use: XF86XK_RFKill			_EVDEVK(0x0F7)		   v2.6.33 KEY_RFKILL */
/* Use: XF86XK_AudioMicMute		_EVDEVK(0x0F8)		   v3.1  KEY_MICMUTE */
#define XF86XK_Info			_EVDEVK(0x166)		/*       KEY_INFO */
/* Use: XF86XK_CycleAngle		_EVDEVK(0x173)		         KEY_ANGLE */
/* Use: XF86XK_FullScreen		_EVDEVK(0x174)		   v5.1  KEY_FULL_SCREEN */
#define XF86XK_AspectRatio		_EVDEVK(0x177)		/* v5.1  KEY_ASPECT_RATIO */
#define XF86XK_DVD			_EVDEVK(0x185)		/*       KEY_DVD */
#define XF86XK_Audio			_EVDEVK(0x188)		/*       KEY_AUDIO */
/* Use: XF86XK_Video			_EVDEVK(0x189)		         KEY_VIDEO */
/* Use: XF86XK_Calendar			_EVDEVK(0x18D)		         KEY_CALENDAR */
#define XF86XK_ChannelUp		_EVDEVK(0x192)		/*       KEY_CHANNELUP */
#define XF86XK_ChannelDown		_EVDEVK(0x193)		/*       KEY_CHANNELDOWN */
/* Use: XF86XK_AudioRandomPlay		_EVDEVK(0x19A)		         KEY_SHUFFLE */
#define XF86XK_Break			_EVDEVK(0x19B)		/*       KEY_BREAK */
#define XF86XK_VideoPhone		_EVDEVK(0x1A0)		/* v2.6.20 KEY_VIDEOPHONE */
/* Use: XF86XK_Game			_EVDEVK(0x1A1)		   v2.6.20 KEY_GAMES */
/* Use: XF86XK_ZoomIn			_EVDEVK(0x1A2)		   v2.6.20 KEY_ZOOMIN */
/* Use: XF86XK_ZoomOut			_EVDEVK(0x1A3)		   v2.6.20 KEY_ZOOMOUT */
#define XF86XK_ZoomReset		_EVDEVK(0x1A4)		/* v2.6.20 KEY_ZOOMRESET */
/* Use: XF86XK_Word			_EVDEVK(0x1A5)		   v2.6.20 KEY_WORDPROCESSOR */
#define XF86XK_Editor			_EVDEVK(0x1A6)		/* v2.6.20 KEY_EDITOR */
/* Use: XF86XK_Excel			_EVDEVK(0x1A7)		   v2.6.20 KEY_SPREADSHEET */
#define XF86XK_GraphicsEditor		_EVDEVK(0x1A8)		/* v2.6.20 KEY_GRAPHICSEDITOR */
#define XF86XK_Presentation		_EVDEVK(0x1A9)		/* v2.6.20 KEY_PRESENTATION */
#define XF86XK_Database			_EVDEVK(0x1AA)		/* v2.6.20 KEY_DATABASE */
/* Use: XF86XK_News			_EVDEVK(0x1AB)		   v2.6.20 KEY_NEWS */
#define XF86XK_Voicemail		_EVDEVK(0x1AC)		/* v2.6.20 KEY_VOICEMAIL */
#define XF86XK_Addressbook		_EVDEVK(0x1AD)		/* v2.6.20 KEY_ADDRESSBOOK */
/* Use: XF86XK_Messenger		_EVDEVK(0x1AE)		   v2.6.20 KEY_MESSENGER */
#define XF86XK_DisplayToggle		_EVDEVK(0x1AF)		/* v2.6.20 KEY_DISPLAYTOGGLE */
#define XF86XK_SpellCheck		_EVDEVK(0x1B0)		/* v2.6.24 KEY_SPELLCHECK */
/* Use: XF86XK_LogOff			_EVDEVK(0x1B1)		   v2.6.24 KEY_LOGOFF */
/* Use: XK_dollar			_EVDEVK(0x1B2)		   v2.6.24 KEY_DOLLAR */
/* Use: XK_EuroSign			_EVDEVK(0x1B3)		   v2.6.24 KEY_EURO */
/* Use: XF86XK_FrameBack		_EVDEVK(0x1B4)		   v2.6.24 KEY_FRAMEBACK */
/* Use: XF86XK_FrameForward		_EVDEVK(0x1B5)		   v2.6.24 KEY_FRAMEFORWARD */
#define XF86XK_ContextMenu		_EVDEVK(0x1B6)		/* v2.6.24 KEY_CONTEXT_MENU */
#define XF86XK_MediaRepeat		_EVDEVK(0x1B7)		/* v2.6.26 KEY_MEDIA_REPEAT */
#define XF86XK_10ChannelsUp		_EVDEVK(0x1B8)		/* v2.6.38 KEY_10CHANNELSUP */
#define XF86XK_10ChannelsDown		_EVDEVK(0x1B9)		/* v2.6.38 KEY_10CHANNELSDOWN */
#define XF86XK_Images			_EVDEVK(0x1BA)		/* v2.6.39 KEY_IMAGES */
#define XF86XK_NotificationCenter	_EVDEVK(0x1BC)		/* v5.10 KEY_NOTIFICATION_CENTER */
#define XF86XK_PickupPhone		_EVDEVK(0x1BD)		/* v5.10 KEY_PICKUP_PHONE */
#define XF86XK_HangupPhone		_EVDEVK(0x1BE)		/* v5.10 KEY_HANGUP_PHONE */
#define XF86XK_Fn			_EVDEVK(0x1D0)		/*       KEY_FN */
#define XF86XK_Fn_Esc			_EVDEVK(0x1D1)		/*       KEY_FN_ESC */
#define XF86XK_FnRightShift		_EVDEVK(0x1E5)		/* v5.10 KEY_FN_RIGHT_SHIFT */
/* Use: XK_braille_dot_1		_EVDEVK(0x1F1)		   v2.6.17 KEY_BRL_DOT1 */
/* Use: XK_braille_dot_2		_EVDEVK(0x1F2)		   v2.6.17 KEY_BRL_DOT2 */
/* Use: XK_braille_dot_3		_EVDEVK(0x1F3)		   v2.6.17 KEY_BRL_DOT3 */
/* Use: XK_braille_dot_4		_EVDEVK(0x1F4)		   v2.6.17 KEY_BRL_DOT4 */
/* Use: XK_braille_dot_5		_EVDEVK(0x1F5)		   v2.6.17 KEY_BRL_DOT5 */
/* Use: XK_braille_dot_6		_EVDEVK(0x1F6)		   v2.6.17 KEY_BRL_DOT6 */
/* Use: XK_braille_dot_7		_EVDEVK(0x1F7)		   v2.6.17 KEY_BRL_DOT7 */
/* Use: XK_braille_dot_8		_EVDEVK(0x1F8)		   v2.6.17 KEY_BRL_DOT8 */
/* Use: XK_braille_dot_9		_EVDEVK(0x1F9)		   v2.6.23 KEY_BRL_DOT9 */
/* Use: XK_braille_dot_1		_EVDEVK(0x1FA)		   v2.6.23 KEY_BRL_DOT10 */
#define XF86XK_Numeric0			_EVDEVK(0x200)		/* v2.6.28 KEY_NUMERIC_0 */
#define XF86XK_Numeric1			_EVDEVK(0x201)		/* v2.6.28 KEY_NUMERIC_1 */
#define XF86XK_Numeric2			_EVDEVK(0x202)		/* v2.6.28 KEY_NUMERIC_2 */
#define XF86XK_Numeric3			_EVDEVK(0x203)		/* v2.6.28 KEY_NUMERIC_3 */
#define XF86XK_Numeric4			_EVDEVK(0x204)		/* v2.6.28 KEY_NUMERIC_4 */
#define XF86XK_Numeric5			_EVDEVK(0x205)		/* v2.6.28 KEY_NUMERIC_5 */
#define XF86XK_Numeric6			_EVDEVK(0x206)		/* v2.6.28 KEY_NUMERIC_6 */
#define XF86XK_Numeric7			_EVDEVK(0x207)		/* v2.6.28 KEY_NUMERIC_7 */
#define XF86XK_Numeric8			_EVDEVK(0x208)		/* v2.6.28 KEY_NUMERIC_8 */
#define XF86XK_Numeric9			_EVDEVK(0x209)		/* v2.6.28 KEY_NUMERIC_9 */
#define XF86XK_NumericStar		_EVDEVK(0x20A)		/* v2.6.28 KEY_NUMERIC_STAR */
#define XF86XK_NumericPound		_EVDEVK(0x20B)		/* v2.6.28 KEY_NUMERIC_POUND */
#define XF86XK_NumericA			_EVDEVK(0x20C)		/* v4.1  KEY_NUMERIC_A */
#define XF86XK_NumericB			_EVDEVK(0x20D)		/* v4.1  KEY_NUMERIC_B */
#define XF86XK_NumericC			_EVDEVK(0x20E)		/* v4.1  KEY_NUMERIC_C */
#define XF86XK_NumericD			_EVDEVK(0x20F)		/* v4.1  KEY_NUMERIC_D */
#define XF86XK_CameraFocus		_EVDEVK(0x210)		/* v2.6.33 KEY_CAMERA_FOCUS */
#define XF86XK_WPSButton		_EVDEVK(0x211)		/* v2.6.34 KEY_WPS_BUTTON */
/* Use: XF86XK_TouchpadToggle		_EVDEVK(0x212)		   v2.6.37 KEY_TOUCHPAD_TOGGLE */
/* Use: XF86XK_TouchpadOn		_EVDEVK(0x213)		   v2.6.37 KEY_TOUCHPAD_ON */
/* Use: XF86XK_TouchpadOff		_EVDEVK(0x214)		   v2.6.37 KEY_TOUCHPAD_OFF */
#define XF86XK_CameraZoomIn		_EVDEVK(0x215)		/* v2.6.39 KEY_CAMERA_ZOOMIN */
#define XF86XK_CameraZoomOut		_EVDEVK(0x216)		/* v2.6.39 KEY_CAMERA_ZOOMOUT */
#define XF86XK_CameraUp			_EVDEVK(0x217)		/* v2.6.39 KEY_CAMERA_UP */
#define XF86XK_CameraDown		_EVDEVK(0x218)		/* v2.6.39 KEY_CAMERA_DOWN */
#define XF86XK_CameraLeft		_EVDEVK(0x219)		/* v2.6.39 KEY_CAMERA_LEFT */
#define XF86XK_CameraRight		_EVDEVK(0x21A)		/* v2.6.39 KEY_CAMERA_RIGHT */
#define XF86XK_AttendantOn		_EVDEVK(0x21B)		/* v3.10 KEY_ATTENDANT_ON */
#define XF86XK_AttendantOff		_EVDEVK(0x21C)		/* v3.10 KEY_ATTENDANT_OFF */
#define XF86XK_AttendantToggle		_EVDEVK(0x21D)		/* v3.10 KEY_ATTENDANT_TOGGLE */
#define XF86XK_LightsToggle		_EVDEVK(0x21E)		/* v3.10 KEY_LIGHTS_TOGGLE */
#define XF86XK_ALSToggle		_EVDEVK(0x230)		/* v3.13 KEY_ALS_TOGGLE */
/* Use: XF86XK_RotationLockToggle	_EVDEVK(0x231)		   v4.16 KEY_ROTATE_LOCK_TOGGLE */
#define XF86XK_Buttonconfig		_EVDEVK(0x240)		/* v3.16 KEY_BUTTONCONFIG */
#define XF86XK_Taskmanager		_EVDEVK(0x241)		/* v3.16 KEY_TASKMANAGER */
#define XF86XK_Journal			_EVDEVK(0x242)		/* v3.16 KEY_JOURNAL */
#define XF86XK_ControlPanel		_EVDEVK(0x243)		/* v3.16 KEY_CONTROLPANEL */
#define XF86XK_AppSelect		_EVDEVK(0x244)		/* v3.16 KEY_APPSELECT */
#define XF86XK_Screensaver		_EVDEVK(0x245)		/* v3.16 KEY_SCREENSAVER */
#define XF86XK_VoiceCommand		_EVDEVK(0x246)		/* v3.16 KEY_VOICECOMMAND */
#define XF86XK_Assistant		_EVDEVK(0x247)		/* v4.13 KEY_ASSISTANT */
/* Use: XK_ISO_Next_Group		_EVDEVK(0x248)		   v5.2  KEY_KBD_LAYOUT_NEXT */
#define XF86XK_EmojiPicker		_EVDEVK(0x249)		/* v5.13 KEY_EMOJI_PICKER */
#define XF86XK_Dictate			_EVDEVK(0x24A)		/* v5.17 KEY_DICTATE */
#define XF86XK_BrightnessMin		_EVDEVK(0x250)		/* v3.16 KEY_BRIGHTNESS_MIN */
#define XF86XK_BrightnessMax		_EVDEVK(0x251)		/* v3.16 KEY_BRIGHTNESS_MAX */
#define XF86XK_KbdInputAssistPrev	_EVDEVK(0x260)		/* v3.18 KEY_KBDINPUTASSIST_PREV */
#define XF86XK_KbdInputAssistNext	_EVDEVK(0x261)		/* v3.18 KEY_KBDINPUTASSIST_NEXT */
#define XF86XK_KbdInputAssistPrevgroup	_EVDEVK(0x262)		/* v3.18 KEY_KBDINPUTASSIST_PREVGROUP */
#define XF86XK_KbdInputAssistNextgroup	_EVDEVK(0x263)		/* v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */
#define XF86XK_KbdInputAssistAccept	_EVDEVK(0x264)		/* v3.18 KEY_KBDINPUTASSIST_ACCEPT */
#define XF86XK_KbdInputAssistCancel	_EVDEVK(0x265)		/* v3.18 KEY_KBDINPUTASSIST_CANCEL */
#define XF86XK_RightUp			_EVDEVK(0x266)		/* v4.7  KEY_RIGHT_UP */
#define XF86XK_RightDown		_EVDEVK(0x267)		/* v4.7  KEY_RIGHT_DOWN */
#define XF86XK_LeftUp			_EVDEVK(0x268)		/* v4.7  KEY_LEFT_UP */
#define XF86XK_LeftDown			_EVDEVK(0x269)		/* v4.7  KEY_LEFT_DOWN */
#define XF86XK_RootMenu			_EVDEVK(0x26A)		/* v4.7  KEY_ROOT_MENU */
#define XF86XK_MediaTopMenu		_EVDEVK(0x26B)		/* v4.7  KEY_MEDIA_TOP_MENU */
#define XF86XK_Numeric11		_EVDEVK(0x26C)		/* v4.7  KEY_NUMERIC_11 */
#define XF86XK_Numeric12		_EVDEVK(0x26D)		/* v4.7  KEY_NUMERIC_12 */
#define XF86XK_AudioDesc		_EVDEVK(0x26E)		/* v4.7  KEY_AUDIO_DESC */
#define XF86XK_3DMode			_EVDEVK(0x26F)		/* v4.7  KEY_3D_MODE */
#define XF86XK_NextFavorite		_EVDEVK(0x270)		/* v4.7  KEY_NEXT_FAVORITE */
#define XF86XK_StopRecord		_EVDEVK(0x271)		/* v4.7  KEY_STOP_RECORD */
#define XF86XK_PauseRecord		_EVDEVK(0x272)		/* v4.7  KEY_PAUSE_RECORD */
#define XF86XK_VOD			_EVDEVK(0x273)		/* v4.7  KEY_VOD */
#define XF86XK_Unmute			_EVDEVK(0x274)		/* v4.7  KEY_UNMUTE */
#define XF86XK_FastReverse		_EVDEVK(0x275)		/* v4.7  KEY_FASTREVERSE */
#define XF86XK_SlowReverse		_EVDEVK(0x276)		/* v4.7  KEY_SLOWREVERSE */
#define XF86XK_Data			_EVDEVK(0x277)		/* v4.7  KEY_DATA */
#define XF86XK_OnScreenKeyboard		_EVDEVK(0x278)		/* v4.12 KEY_ONSCREEN_KEYBOARD */
#define XF86XK_PrivacyScreenToggle	_EVDEVK(0x279)		/* v5.5  KEY_PRIVACY_SCREEN_TOGGLE */
#define XF86XK_SelectiveScreenshot	_EVDEVK(0x27A)		/* v5.6  KEY_SELECTIVE_SCREENSHOT */
#define XF86XK_Macro1			_EVDEVK(0x290)		/* v5.5  KEY_MACRO1 */
#define XF86XK_Macro2			_EVDEVK(0x291)		/* v5.5  KEY_MACRO2 */
#define XF86XK_Macro3			_EVDEVK(0x292)		/* v5.5  KEY_MACRO3 */
#define XF86XK_Macro4			_EVDEVK(0x293)		/* v5.5  KEY_MACRO4 */
#define XF86XK_Macro5			_EVDEVK(0x294)		/* v5.5  KEY_MACRO5 */
#define XF86XK_Macro6			_EVDEVK(0x295)		/* v5.5  KEY_MACRO6 */
#define XF86XK_Macro7			_EVDEVK(0x296)		/* v5.5  KEY_MACRO7 */
#define XF86XK_Macro8			_EVDEVK(0x297)		/* v5.5  KEY_MACRO8 */
#define XF86XK_Macro9			_EVDEVK(0x298)		/* v5.5  KEY_MACRO9 */
#define XF86XK_Macro10			_EVDEVK(0x299)		/* v5.5  KEY_MACRO10 */
#define XF86XK_Macro11			_EVDEVK(0x29A)		/* v5.5  KEY_MACRO11 */
#define XF86XK_Macro12			_EVDEVK(0x29B)		/* v5.5  KEY_MACRO12 */
#define XF86XK_Macro13			_EVDEVK(0x29C)		/* v5.5  KEY_MACRO13 */
#define XF86XK_Macro14			_EVDEVK(0x29D)		/* v5.5  KEY_MACRO14 */
#define XF86XK_Macro15			_EVDEVK(0x29E)		/* v5.5  KEY_MACRO15 */
#define XF86XK_Macro16			_EVDEVK(0x29F)		/* v5.5  KEY_MACRO16 */
#define XF86XK_Macro17			_EVDEVK(0x2A0)		/* v5.5  KEY_MACRO17 */
#define XF86XK_Macro18			_EVDEVK(0x2A1)		/* v5.5  KEY_MACRO18 */
#define XF86XK_Macro19			_EVDEVK(0x2A2)		/* v5.5  KEY_MACRO19 */
#define XF86XK_Macro20			_EVDEVK(0x2A3)		/* v5.5  KEY_MACRO20 */
#define XF86XK_Macro21			_EVDEVK(0x2A4)		/* v5.5  KEY_MACRO21 */
#define XF86XK_Macro22			_EVDEVK(0x2A5)		/* v5.5  KEY_MACRO22 */
#define XF86XK_Macro23			_EVDEVK(0x2A6)		/* v5.5  KEY_MACRO23 */
#define XF86XK_Macro24			_EVDEVK(0x2A7)		/* v5.5  KEY_MACRO24 */
#define XF86XK_Macro25			_EVDEVK(0x2A8)		/* v5.5  KEY_MACRO25 */
#define XF86XK_Macro26			_EVDEVK(0x2A9)		/* v5.5  KEY_MACRO26 */
#define XF86XK_Macro27			_EVDEVK(0x2AA)		/* v5.5  KEY_MACRO27 */
#define XF86XK_Macro28			_EVDEVK(0x2AB)		/* v5.5  KEY_MACRO28 */
#define XF86XK_Macro29			_EVDEVK(0x2AC)		/* v5.5  KEY_MACRO29 */
#define XF86XK_Macro30			_EVDEVK(0x2AD)		/* v5.5  KEY_MACRO30 */
#define XF86XK_MacroRecordStart		_EVDEVK(0x2B0)		/* v5.5  KEY_MACRO_RECORD_START */
#define XF86XK_MacroRecordStop		_EVDEVK(0x2B1)		/* v5.5  KEY_MACRO_RECORD_STOP */
#define XF86XK_MacroPresetCycle		_EVDEVK(0x2B2)		/* v5.5  KEY_MACRO_PRESET_CYCLE */
#define XF86XK_MacroPreset1		_EVDEVK(0x2B3)		/* v5.5  KEY_MACRO_PRESET1 */
#define XF86XK_MacroPreset2		_EVDEVK(0x2B4)		/* v5.5  KEY_MACRO_PRESET2 */
#define XF86XK_MacroPreset3		_EVDEVK(0x2B5)		/* v5.5  KEY_MACRO_PRESET3 */
#define XF86XK_KbdLcdMenu1		_EVDEVK(0x2B8)		/* v5.5  KEY_KBD_LCD_MENU1 */
#define XF86XK_KbdLcdMenu2		_EVDEVK(0x2B9)		/* v5.5  KEY_KBD_LCD_MENU2 */
#define XF86XK_KbdLcdMenu3		_EVDEVK(0x2BA)		/* v5.5  KEY_KBD_LCD_MENU3 */
#define XF86XK_KbdLcdMenu4		_EVDEVK(0x2BB)		/* v5.5  KEY_KBD_LCD_MENU4 */
#define XF86XK_KbdLcdMenu5		_EVDEVK(0x2BC)		/* v5.5  KEY_KBD_LCD_MENU5 */
#undef _EVDEVK

Changes to xlib/X11/Xfuncproto.h.

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#if __has_attribute(__format__) \
    || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
#else /* not gcc >= 2.3 */
# define _X_ATTRIBUTE_PRINTF(x,y)
#endif

/* requires xproto >= 7.0.22 - since this uses either gcc or C99 variable
   argument macros, must be only used inside #ifdef _X_NONNULL guards, as
   many legacy X clients are compiled in C89 mode still. */
#if __has_attribute(nonnull) \
    && defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
#define _X_NONNULL(...)  __attribute__((nonnull(__VA_ARGS__)))
#elif __has_attribute(nonnull) \
    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
#define _X_NONNULL(args...)  __attribute__((nonnull(args)))
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
#define _X_NONNULL(...)  /* */
#endif

/* requires xproto >= 7.0.22 */
#if __has_attribute(__unused__) \
    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)
#define _X_UNUSED  __attribute__((__unused__))
#else
#define _X_UNUSED  /* */
#endif







<
<
<
<
<
<
<
<
<
<
<
<
<







159
160
161
162
163
164
165













166
167
168
169
170
171
172
#if __has_attribute(__format__) \
    || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
#else /* not gcc >= 2.3 */
# define _X_ATTRIBUTE_PRINTF(x,y)
#endif














/* requires xproto >= 7.0.22 */
#if __has_attribute(__unused__) \
    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)
#define _X_UNUSED  __attribute__((__unused__))
#else
#define _X_UNUSED  /* */
#endif
213
214
215
216
217
218
219
220








221

/* requires xproto >= 7.0.30 */
#if __has_attribute(no_sanitize_thread)
# define _X_NOTSAN __attribute__((no_sanitize_thread))
#else
# define _X_NOTSAN
#endif









#endif /* _XFUNCPROTO_H_ */








>
>
>
>
>
>
>
>

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

/* requires xproto >= 7.0.30 */
#if __has_attribute(no_sanitize_thread)
# define _X_NOTSAN __attribute__((no_sanitize_thread))
#else
# define _X_NOTSAN
#endif

/* Mark a char array/pointer as not containing a NUL-terminated string */
/* requires xproto >= 7.0.33 */
#if __has_attribute(nonstring)
# define _X_NONSTRING __attribute__((nonstring))
#else
# define _X_NONSTRING
#endif

#endif /* _XFUNCPROTO_H_ */

Changes to xlib/X11/Xlib.h.

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#define True 1
#define False 0

#define QueuedAlready 0
#define QueuedAfterReading 1
#define QueuedAfterFlush 2

#define ConnectionNumber(dpy) 	((dpy)->fd)
#define RootWindow(dpy, scr) 	(((dpy)->screens[(scr)]).root)
#define DefaultScreen(dpy) 	((dpy)->default_screen)
#define DefaultRootWindow(dpy) 	(((dpy)->screens[(dpy)->default_screen]).root)
#define DefaultVisual(dpy, scr) (((dpy)->screens[(scr)]).root_visual)
#define DefaultGC(dpy, scr) 	(((dpy)->screens[(scr)]).default_gc)
#define BlackPixel(dpy, scr) 	(((dpy)->screens[(scr)]).black_pixel)
#define WhitePixel(dpy, scr) 	(((dpy)->screens[(scr)]).white_pixel)
#define AllPlanes 		((unsigned long)~0L)
#define QLength(dpy) 		((dpy)->qlen)
#define DisplayWidth(dpy, scr) 	(((dpy)->screens[(scr)]).width)
#define DisplayHeight(dpy, scr) (((dpy)->screens[(scr)]).height)
#define DisplayWidthMM(dpy, scr)(((dpy)->screens[(scr)]).mwidth)
#define DisplayHeightMM(dpy, scr)(((dpy)->screens[(scr)]).mheight)
#define DisplayPlanes(dpy, scr) (((dpy)->screens[(scr)]).root_depth)
#define DisplayCells(dpy, scr) 	(DefaultVisual((dpy), (scr))->map_entries)
#define ScreenCount(dpy) 	((dpy)->nscreens)
#define ServerVendor(dpy) 	((dpy)->vendor)
#define ProtocolVersion(dpy) 	((dpy)->proto_major_version)
#define ProtocolRevision(dpy) 	((dpy)->proto_minor_version)
#define VendorRelease(dpy) 	((dpy)->release)
#define DisplayString(dpy) 	((dpy)->display_name)
#define DefaultDepth(dpy, scr) 	(((dpy)->screens[(scr)]).root_depth)
#define DefaultColormap(dpy, scr)(((dpy)->screens[(scr)]).cmap)
#define BitmapUnit(dpy) 	((dpy)->bitmap_unit)
#define BitmapBitOrder(dpy) 	((dpy)->bitmap_bit_order)
#define BitmapPad(dpy) 		((dpy)->bitmap_pad)
#define ImageByteOrder(dpy) 	((dpy)->byte_order)
#define NextRequest(dpy)	((dpy)->request + 1)
#define LastKnownRequestProcessed(dpy)	((dpy)->request)

/* macros for screen oriented applications (toolkit) */
#define ScreenOfDisplay(dpy, scr)(&((dpy)->screens[(scr)]))
#define DefaultScreenOfDisplay(dpy) (&((dpy)->screens[(dpy)->default_screen]))
#define DisplayOfScreen(s)	((s)->display)
#define RootWindowOfScreen(s)	((s)->root)
#define BlackPixelOfScreen(s)	((s)->black_pixel)
#define WhitePixelOfScreen(s)	((s)->white_pixel)
#define DefaultColormapOfScreen(s)((s)->cmap)
#define DefaultDepthOfScreen(s)	((s)->root_depth)
#define DefaultGCOfScreen(s)	((s)->default_gc)







|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#define True 1
#define False 0

#define QueuedAlready 0
#define QueuedAfterReading 1
#define QueuedAfterFlush 2

#define ConnectionNumber(dpy) 	(((_XPrivDisplay)(dpy))->fd)
#define RootWindow(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->root)
#define DefaultScreen(dpy) 	(((_XPrivDisplay)(dpy))->default_screen)
#define DefaultRootWindow(dpy) 	(ScreenOfDisplay(dpy,DefaultScreen(dpy))->root)
#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual)
#define DefaultGC(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->default_gc)
#define BlackPixel(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->black_pixel)
#define WhitePixel(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->white_pixel)
#define AllPlanes 		((unsigned long)~0L)
#define QLength(dpy) 		(((_XPrivDisplay)(dpy))->qlen)
#define DisplayWidth(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->width)
#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height)
#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth)
#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight)
#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth)
#define DisplayCells(dpy, scr) 	(DefaultVisual(dpy,scr)->map_entries)
#define ScreenCount(dpy) 	(((_XPrivDisplay)(dpy))->nscreens)
#define ServerVendor(dpy) 	(((_XPrivDisplay)(dpy))->vendor)
#define ProtocolVersion(dpy) 	(((_XPrivDisplay)(dpy))->proto_major_version)
#define ProtocolRevision(dpy) 	(((_XPrivDisplay)(dpy))->proto_minor_version)
#define VendorRelease(dpy) 	(((_XPrivDisplay)(dpy))->release)
#define DisplayString(dpy) 	(((_XPrivDisplay)(dpy))->display_name)
#define DefaultDepth(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->root_depth)
#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap)
#define BitmapUnit(dpy) 	(((_XPrivDisplay)(dpy))->bitmap_unit)
#define BitmapBitOrder(dpy) 	(((_XPrivDisplay)(dpy))->bitmap_bit_order)
#define BitmapPad(dpy) 		(((_XPrivDisplay)(dpy))->bitmap_pad)
#define ImageByteOrder(dpy) 	(((_XPrivDisplay)(dpy))->byte_order)
#define NextRequest(dpy)	(((_XPrivDisplay)(dpy))->request + 1)
#define LastKnownRequestProcessed(dpy)	(((_XPrivDisplay)(dpy))->request)

/* macros for screen oriented applications (toolkit) */
#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)(dpy))->screens[scr])
#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy))
#define DisplayOfScreen(s)	((s)->display)
#define RootWindowOfScreen(s)	((s)->root)
#define BlackPixelOfScreen(s)	((s)->black_pixel)
#define WhitePixelOfScreen(s)	((s)->white_pixel)
#define DefaultColormapOfScreen(s)((s)->cmap)
#define DefaultDepthOfScreen(s)	((s)->root_depth)
#define DefaultGCOfScreen(s)	((s)->default_gc)
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	unsigned long background;/* background pixel */
	int line_width;		/* line width */
	int line_style;	 	/* LineSolid, LineOnOffDash, LineDoubleDash */
	int cap_style;	  	/* CapNotLast, CapButt,
				   CapRound, CapProjecting */
	int join_style;	 	/* JoinMiter, JoinRound, JoinBevel */
	int fill_style;	 	/* FillSolid, FillTiled,
				   FillStippled, FillOpaeueStippled */
	int fill_rule;	  	/* EvenOddRule, WindingRule */
	int arc_mode;		/* ArcChord, ArcPieSlice */
	Pixmap tile;		/* tile pixmap for tiling operations */
	Pixmap stipple;		/* stipple 1 plane pixmap for stipping */
	int ts_x_origin;	/* offset for tile or stipple operations */
	int ts_y_origin;
        Font font;	        /* default text font for text operations */
	int subwindow_mode;     /* ClipByChildren, IncludeInferiors */
	Bool graphics_exposures;/* boolean, should exposures be generated */
	int clip_x_origin;	/* origin for clipping */
	int clip_y_origin;







|



|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	unsigned long background;/* background pixel */
	int line_width;		/* line width */
	int line_style;	 	/* LineSolid, LineOnOffDash, LineDoubleDash */
	int cap_style;	  	/* CapNotLast, CapButt,
				   CapRound, CapProjecting */
	int join_style;	 	/* JoinMiter, JoinRound, JoinBevel */
	int fill_style;	 	/* FillSolid, FillTiled,
				   FillStippled, FillOpaqueStippled */
	int fill_rule;	  	/* EvenOddRule, WindingRule */
	int arc_mode;		/* ArcChord, ArcPieSlice */
	Pixmap tile;		/* tile pixmap for tiling operations */
	Pixmap stipple;		/* stipple 1 plane pixmap for stippling */
	int ts_x_origin;	/* offset for tile or stipple operations */
	int ts_y_origin;
        Font font;	        /* default text font for text operations */
	int subwindow_mode;     /* ClipByChildren, IncludeInferiors */
	Bool graphics_exposures;/* boolean, should exposures be generated */
	int clip_x_origin;	/* origin for clipping */
	int clip_y_origin;
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
    Pixmap background_pixmap;	/* background or None or ParentRelative */
    unsigned long background_pixel;	/* background pixel */
    Pixmap border_pixmap;	/* border of the window */
    unsigned long border_pixel;	/* border pixel value */
    int bit_gravity;		/* one of bit gravity values */
    int win_gravity;		/* one of the window gravity values */
    int backing_store;		/* NotUseful, WhenMapped, Always */
    unsigned long backing_planes;/* planes to be preseved if possible */
    unsigned long backing_pixel;/* value to use in restoring planes */
    Bool save_under;		/* should bits under be saved? (popups) */
    long event_mask;		/* set of events that should be saved */
    long do_not_propagate_mask;	/* set of events that should not propagate */
    Bool override_redirect;	/* boolean value for override-redirect */
    Colormap colormap;		/* color map to be associated with window */
    Cursor cursor;		/* cursor to be displayed (or None) */







|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
    Pixmap background_pixmap;	/* background or None or ParentRelative */
    unsigned long background_pixel;	/* background pixel */
    Pixmap border_pixmap;	/* border of the window */
    unsigned long border_pixel;	/* border pixel value */
    int bit_gravity;		/* one of bit gravity values */
    int win_gravity;		/* one of the window gravity values */
    int backing_store;		/* NotUseful, WhenMapped, Always */
    unsigned long backing_planes;/* planes to be preserved if possible */
    unsigned long backing_pixel;/* value to use in restoring planes */
    Bool save_under;		/* should bits under be saved? (popups) */
    long event_mask;		/* set of events that should be saved */
    long do_not_propagate_mask;	/* set of events that should not propagate */
    Bool override_redirect;	/* boolean value for override-redirect */
    Colormap colormap;		/* color map to be associated with window */
    Cursor cursor;		/* cursor to be displayed (or None) */
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    int format;			/* XYBitmap, XYPixmap, ZPixmap */
    char *data;			/* pointer to image data */
    int byte_order;		/* data byte order, LSBFirst, MSBFirst */
    int bitmap_unit;		/* quant. of scanline 8, 16, 32 */
    int bitmap_bit_order;	/* LSBFirst, MSBFirst */
    int bitmap_pad;		/* 8, 16, 32 either XY or ZPixmap */
    int depth;			/* depth of image */
    int bytes_per_line;		/* accelarator to next line */
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)(
		struct _XDisplay* /* display */,
		Visual*		/* visual */,







|

|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    int format;			/* XYBitmap, XYPixmap, ZPixmap */
    char *data;			/* pointer to image data */
    int byte_order;		/* data byte order, LSBFirst, MSBFirst */
    int bitmap_unit;		/* quant. of scanline 8, 16, 32 */
    int bitmap_bit_order;	/* LSBFirst, MSBFirst */
    int bitmap_pad;		/* 8, 16, 32 either XY or ZPixmap */
    int depth;			/* depth of image */
    int bytes_per_line;		/* accelerator to next line */
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangement */
    unsigned long green_mask;
    unsigned long blue_mask;
    XPointer obdata;		/* hook for the object routines to hang on */
    struct funcs {		/* image manipulation routines */
	struct _XImage *(*create_image)(
		struct _XDisplay* /* display */,
		Visual*		/* visual */,
488
489
490
491
492
493
494

495










496
497
498
499
500
501
502


/*
 * Display datatype maintaining display specific data.
 * The contents of this structure are implementation dependent.
 * A Display should be treated as opaque by application code.
 */

typedef struct _XDisplay {










	XExtData *ext_data;	/* hook for extension to hang data */
	struct _XPrivate *private1;
	int fd;			/* Network socket. */
	int private2;
	int proto_major_version;/* major version of server's X protocol */
	int proto_minor_version;/* minor version of servers X protocol */
	char *vendor;		/* vendor of the server hardware */







>
|
>
>
>
>
>
>
>
>
>
>







488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513


/*
 * Display datatype maintaining display specific data.
 * The contents of this structure are implementation dependent.
 * A Display should be treated as opaque by application code.
 */
#ifndef XLIB_ILLEGAL_ACCESS
typedef struct _XDisplay Display;
#endif

struct _XPrivate;		/* Forward declare before use for C++ */
struct _XrmHashBucketRec;

typedef struct
#ifdef XLIB_ILLEGAL_ACCESS
_XDisplay
#endif
{
	XExtData *ext_data;	/* hook for extension to hang data */
	struct _XPrivate *private1;
	int fd;			/* Network socket. */
	int private2;
	int proto_major_version;/* major version of server's X protocol */
	int proto_minor_version;/* minor version of servers X protocol */
	char *vendor;		/* vendor of the server hardware */
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564


565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
	unsigned long private16;
	int min_keycode;	/* minimum defined keycode */
	int max_keycode;	/* maximum defined keycode */
	XPointer private17;
	XPointer private18;
	int private19;
	char *xdefaults;	/* contents of defaults from server */
	char *scratch_buffer;	/* place to hang scratch buffer */
	unsigned long scratch_length;	/* length of scratch buffer */
	int ext_number;		/* extension number on this display */
	struct _XExten *ext_procs; /* extensions initialized on this display */
	/*
	 * the following can be fixed size, as the protocol defines how
	 * much address space is available.
	 * While this could be done using the extension vector, there
	 * may be MANY events processed, so a search through the extension
	 * list to find the right procedure for each event might be
	 * expensive if many extensions are being used.
	 */
	Bool (*event_vec[128])(void);  /* vector for wire to event */
	Status (*wire_vec[128])(void); /* vector for event to wire */
	KeySym lock_meaning;	   /* for XLookupString */
	struct _XLockInfo *lock;   /* multi-thread state, display lock */
	struct _XInternalAsync *async_handlers; /* for internal async */
	unsigned long bigreq_size; /* max size of big requests */
	struct _XLockPtrs *lock_fns; /* pointers to threads functions */
	/* things above this line should not move, for binary compatibility */
	struct _XKeytrans *key_bindings; /* for XLookupString */
	Font cursor_font;	   /* for XCreateFontCursor */


	struct _XDisplayAtoms *atoms; /* for XInternAtom */
	unsigned int mode_switch;  /* keyboard group modifiers */
	struct _XContextDB *context_db; /* context database */
	Bool (**error_vec)(void);      /* vector for wire to error */
	/*
	 * Xcms information
	 */
	struct {
	   XPointer defaultCCCs;  /* pointer to an array of default XcmsCCC */
	   XPointer clientCmaps;  /* pointer to linked list of XcmsCmapRec */
	   XPointer perVisualIntensityMaps;
				  /* linked list of XcmsIntensityMap */
	} cms;
	struct _XIMFilter *im_filters;
	struct _XSQEvent *qfree; /* unallocated event queue elements */
	unsigned long next_event_serial_num; /* inserted into next queue elt */
	int (*savedsynchandler)(void); /* user synchandler when Xlib usurps */
} Display;

#if NeedFunctionPrototypes	/* prototypes require event type definitions */
#undef _XEVENT_
#endif
#ifndef _XEVENT_

#define XMaxTransChars 7

/*
 * Definitions of specific events.
 */
typedef struct {
	int type;		/* of event */
	unsigned long serial;	/* # of last request processed by server */
	Bool send_event;	/* true if this came from a SendEvent request */







<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<

<

<
<
<







547
548
549
550
551
552
553







554














555
556
557
558















559
560

561

562



563
564
565
566
567
568
569
	unsigned long private16;
	int min_keycode;	/* minimum defined keycode */
	int max_keycode;	/* maximum defined keycode */
	XPointer private17;
	XPointer private18;
	int private19;
	char *xdefaults;	/* contents of defaults from server */







	/* there is more to this structure, but it is private to Xlib */














}
#ifdef XLIB_ILLEGAL_ACCESS
Display,
#endif















*_XPrivDisplay;


#undef _XEVENT_

#ifndef _XEVENT_



/*
 * Definitions of specific events.
 */
typedef struct {
	int type;		/* of event */
	unsigned long serial;	/* # of last request processed by server */
	Bool send_event;	/* true if this came from a SendEvent request */
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
	XKeymapEvent xkeymap;
	XGenericEvent xgeneric;
	XGenericEventCookie xcookie;
	XID pad[24];
} XEvent;
#endif

#define XAllocID(dpy) ((*(dpy)->resource_alloc)((dpy)))

/*
 * per character font metric information.
 */
typedef struct {
    short	lbearing;	/* origin to left edge of raster */
    short	rbearing;	/* origin to right edge of raster */







|







1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
	XKeymapEvent xkeymap;
	XGenericEvent xgeneric;
	XGenericEventCookie xcookie;
	XID pad[24];
} XEvent;
#endif

#define XAllocID(dpy) ((*((_XPrivDisplay)(dpy))->resource_alloc)((dpy)))

/*
 * per character font metric information.
 */
typedef struct {
    short	lbearing;	/* origin to left edge of raster */
    short	rbearing;	/* origin to right edge of raster */
1766
1767
1768
1769
1770
1771
1772




1773
1774
1775
1776
1777
1778
1779
);

/* multithread routines */

EXTERN Status XInitThreads(
    void
);





EXTERN void XLockDisplay(
    Display*		/* display */
);

EXTERN void XUnlockDisplay(
    Display*		/* display */







>
>
>
>







1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
);

/* multithread routines */

EXTERN Status XInitThreads(
    void
);

EXTERN Status XFreeThreads(
    void
);

EXTERN void XLockDisplay(
    Display*		/* display */
);

EXTERN void XUnlockDisplay(
    Display*		/* display */
1890
1891
1892
1893
1894
1895
1896










1897
1898
1899
1900
1901
1902
1903
    Display*		/* display */
);

EXTERN XIOErrorHandler XSetIOErrorHandler (
    XIOErrorHandler	/* handler */
);












EXTERN XPixmapFormatValues *XListPixmapFormats(
    Display*		/* display */,
    int*		/* count_return */
);
EXTERN int *XListDepths(
    Display*		/* display */,







>
>
>
>
>
>
>
>
>
>







1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
    Display*		/* display */
);

EXTERN XIOErrorHandler XSetIOErrorHandler (
    XIOErrorHandler	/* handler */
);

typedef void (*XIOErrorExitHandler) ( /* WARNING, this type not in Xlib spec */
    Display*,		/* display */
    void*		/* user_data */
);

EXTERN void XSetIOErrorExitHandler (
    Display*,			/* display */
    XIOErrorExitHandler,	/* handler */
    void*			/* user_data */
);

EXTERN XPixmapFormatValues *XListPixmapFormats(
    Display*		/* display */,
    int*		/* count_return */
);
EXTERN int *XListDepths(
    Display*		/* display */,

Changes to xlib/X11/Xutil.h.

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    XContext		/* context */
);

EXTERN int XDestroyRegion(
    Region		/* r */
);

EXTERN int XEmptyRegion(
    Region		/* r */
);

EXTERN int XEqualRegion(
    Region		/* r1 */,
    Region		/* r2 */
);

EXTERN int XFindContext(
    Display*		/* display */,
    XID			/* rid */,







|



|







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    XContext		/* context */
);

EXTERN int XDestroyRegion(
    Region		/* r */
);

EXTERN Bool XEmptyRegion(
    Region		/* r */
);

EXTERN Bool XEqualRegion(
    Region		/* r1 */,
    Region		/* r2 */
);

EXTERN int XFindContext(
    Display*		/* display */,
    XID			/* rid */,

Changes to xlib/X11/ap_keysym.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
that the above copyright notice appear in such copy and that this
copyright notice appear in all supporting documentation, and that the
names of Apollo Computer Inc., the Hewlett-Packard Company, or the X
Consortium not be used in advertising or publicity pertaining to
distribution of the software without written prior permission.

HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  Hewlett-Packard shall not be liable for errors
contained herein or direct, indirect, special, incidental or
consequential damages in connection with the furnishing,
performance, or use of this material.

This software is not subject to any license of the American







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
that the above copyright notice appear in such copy and that this
copyright notice appear in all supporting documentation, and that the
names of Apollo Computer Inc., the Hewlett-Packard Company, or the X
Consortium not be used in advertising or publicity pertaining to
distribution of the software without written prior permission.

HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  Hewlett-Packard shall not be liable for errors
contained herein or direct, indirect, special, incidental or
consequential damages in connection with the furnishing,
performance, or use of this material.

This software is not subject to any license of the American

Changes to xlib/X11/keysymdef.h.

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*(\/\*\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,







|
|







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*(\/\*\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
#define XK_Prior                         0xff55  /* Prior, previous */
#define XK_Page_Up                       0xff55
#define XK_Next                          0xff56  /* Next */
#define XK_Page_Down                     0xff56
#define XK_End                           0xff57  /* EOL */
#define XK_Begin                         0xff58  /* BOL */

/* Special Windows keyboard keys */

#define XK_Win_L		0xFF5B	/* Left-hand Windows */
#define XK_Win_R		0xFF5C	/* Right-hand Windows */
#define XK_App			0xFF5D	/* Menu key */

/* Misc functions */

#define XK_Select                        0xff60  /* Select, mark */
#define XK_Print                         0xff61
#define XK_Execute                       0xff62  /* Execute, run, do */
#define XK_Insert                        0xff63  /* Insert, insert here */







<
<
<
<
<







177
178
179
180
181
182
183





184
185
186
187
188
189
190
#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 */







/* 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 */
432
433
434
435
436
437
438


439
440
441
442
443
444
445
446
447
#define XK_dead_E                        0xfe83
#define XK_dead_i                        0xfe84
#define XK_dead_I                        0xfe85
#define XK_dead_o                        0xfe86
#define XK_dead_O                        0xfe87
#define XK_dead_u                        0xfe88
#define XK_dead_U                        0xfe89


#define XK_dead_small_schwa              0xfe8a
#define XK_dead_capital_schwa            0xfe8b

#define XK_dead_greek                    0xfe8c

#define XK_First_Virtual_Screen          0xfed0
#define XK_Prev_Virtual_Screen           0xfed1
#define XK_Next_Virtual_Screen           0xfed2
#define XK_Last_Virtual_Screen           0xfed4







>
>
|
|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#define XK_dead_E                        0xfe83
#define XK_dead_i                        0xfe84
#define XK_dead_I                        0xfe85
#define XK_dead_o                        0xfe86
#define XK_dead_O                        0xfe87
#define XK_dead_u                        0xfe88
#define XK_dead_U                        0xfe89
#define XK_dead_schwa                    0xfe8a
#define XK_dead_SCHWA                    0xfe8b
#define XK_dead_small_schwa              0xfe8a  /* deprecated, remove in 2025 */
#define XK_dead_capital_schwa            0xfe8b  /* deprecated, remove in 2025 */

#define XK_dead_greek                    0xfe8c

#define XK_First_Virtual_Screen          0xfed0
#define XK_Prev_Virtual_Screen           0xfed1
#define XK_Next_Virtual_Screen           0xfed2
#define XK_Last_Virtual_Screen           0xfed4
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672

673

674
675
676
677
678
679
680
681
#define XK_currency                      0x00a4  /* U+00A4 CURRENCY SIGN */
#define XK_yen                           0x00a5  /* U+00A5 YEN SIGN */
#define XK_brokenbar                     0x00a6  /* U+00A6 BROKEN BAR */
#define XK_section                       0x00a7  /* U+00A7 SECTION SIGN */
#define XK_diaeresis                     0x00a8  /* U+00A8 DIAERESIS */
#define XK_copyright                     0x00a9  /* U+00A9 COPYRIGHT SIGN */
#define XK_ordfeminine                   0x00aa  /* U+00AA FEMININE ORDINAL INDICATOR */

#define XK_guillemotleft                 0x00ab  /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_notsign                       0x00ac  /* U+00AC NOT SIGN */
#define XK_hyphen                        0x00ad  /* U+00AD SOFT HYPHEN */
#define XK_registered                    0x00ae  /* U+00AE REGISTERED SIGN */
#define XK_macron                        0x00af  /* U+00AF MACRON */
#define XK_degree                        0x00b0  /* U+00B0 DEGREE SIGN */
#define XK_plusminus                     0x00b1  /* U+00B1 PLUS-MINUS SIGN */
#define XK_twosuperior                   0x00b2  /* U+00B2 SUPERSCRIPT TWO */
#define XK_threesuperior                 0x00b3  /* U+00B3 SUPERSCRIPT THREE */
#define XK_acute                         0x00b4  /* U+00B4 ACUTE ACCENT */
#define XK_mu                            0x00b5  /* U+00B5 MICRO SIGN */
#define XK_paragraph                     0x00b6  /* U+00B6 PILCROW SIGN */
#define XK_periodcentered                0x00b7  /* U+00B7 MIDDLE DOT */
#define XK_cedilla                       0x00b8  /* U+00B8 CEDILLA */
#define XK_onesuperior                   0x00b9  /* U+00B9 SUPERSCRIPT ONE */

#define XK_masculine                     0x00ba  /* U+00BA MASCULINE ORDINAL INDICATOR */

#define XK_guillemotright                0x00bb  /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_onequarter                    0x00bc  /* U+00BC VULGAR FRACTION ONE QUARTER */
#define XK_onehalf                       0x00bd  /* U+00BD VULGAR FRACTION ONE HALF */
#define XK_threequarters                 0x00be  /* U+00BE VULGAR FRACTION THREE QUARTERS */
#define XK_questiondown                  0x00bf  /* U+00BF INVERTED QUESTION MARK */
#define XK_Agrave                        0x00c0  /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
#define XK_Aacute                        0x00c1  /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
#define XK_Acircumflex                   0x00c2  /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */







>
|














>
|
>
|







648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
#define XK_currency                      0x00a4  /* U+00A4 CURRENCY SIGN */
#define XK_yen                           0x00a5  /* U+00A5 YEN SIGN */
#define XK_brokenbar                     0x00a6  /* U+00A6 BROKEN BAR */
#define XK_section                       0x00a7  /* U+00A7 SECTION SIGN */
#define XK_diaeresis                     0x00a8  /* U+00A8 DIAERESIS */
#define XK_copyright                     0x00a9  /* U+00A9 COPYRIGHT SIGN */
#define XK_ordfeminine                   0x00aa  /* U+00AA FEMININE ORDINAL INDICATOR */
#define XK_guillemetleft                 0x00ab  /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_guillemotleft                 0x00ab  /* deprecated misspelling */
#define XK_notsign                       0x00ac  /* U+00AC NOT SIGN */
#define XK_hyphen                        0x00ad  /* U+00AD SOFT HYPHEN */
#define XK_registered                    0x00ae  /* U+00AE REGISTERED SIGN */
#define XK_macron                        0x00af  /* U+00AF MACRON */
#define XK_degree                        0x00b0  /* U+00B0 DEGREE SIGN */
#define XK_plusminus                     0x00b1  /* U+00B1 PLUS-MINUS SIGN */
#define XK_twosuperior                   0x00b2  /* U+00B2 SUPERSCRIPT TWO */
#define XK_threesuperior                 0x00b3  /* U+00B3 SUPERSCRIPT THREE */
#define XK_acute                         0x00b4  /* U+00B4 ACUTE ACCENT */
#define XK_mu                            0x00b5  /* U+00B5 MICRO SIGN */
#define XK_paragraph                     0x00b6  /* U+00B6 PILCROW SIGN */
#define XK_periodcentered                0x00b7  /* U+00B7 MIDDLE DOT */
#define XK_cedilla                       0x00b8  /* U+00B8 CEDILLA */
#define XK_onesuperior                   0x00b9  /* U+00B9 SUPERSCRIPT ONE */
#define XK_ordmasculine                  0x00ba  /* U+00BA MASCULINE ORDINAL INDICATOR */
#define XK_masculine                     0x00ba  /* deprecated inconsistent name */
#define XK_guillemetright                0x00bb  /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_guillemotright                0x00bb  /* deprecated misspelling */
#define XK_onequarter                    0x00bc  /* U+00BC VULGAR FRACTION ONE QUARTER */
#define XK_onehalf                       0x00bd  /* U+00BD VULGAR FRACTION ONE HALF */
#define XK_threequarters                 0x00be  /* U+00BE VULGAR FRACTION THREE QUARTERS */
#define XK_questiondown                  0x00bf  /* U+00BF INVERTED QUESTION MARK */
#define XK_Agrave                        0x00c0  /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
#define XK_Aacute                        0x00c1  /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
#define XK_Acircumflex                   0x00c2  /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
882
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
#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 */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







882
883
884
885
886
887
888
































889
890
891
892
893
894
895
#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 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

/*
 * 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 */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<







977
978
979
980
981
982
983

















984











985
986
987
988
989
990
991

/*
 * Arabic
 * Byte 3 = 5
 */

#ifdef XK_ARABIC

















#define XK_Arabic_comma                  0x05ac  /* U+060C ARABIC COMMA */











#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
#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 */







<
<
<
<
<
<
<
<
<
<
<
<
<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1026
1027
1028
1029
1030
1031
1032













1033
1034
1035
1036
1037
1038
1039
1040
































1041
1042
1043
1044
1045
1046
1047
#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_switch                 0xff7e  /* Alias for mode_switch */
#endif /* XK_ARABIC */

/*
 * Cyrillic
 * Byte 3 = 6
 */
#ifdef XK_CYRILLIC
































#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
#define XK_twofifths                     0x0ab3  /* U+2156 VULGAR FRACTION TWO FIFTHS */
#define XK_threefifths                   0x0ab4  /* U+2157 VULGAR FRACTION THREE FIFTHS */
#define XK_fourfifths                    0x0ab5  /* U+2158 VULGAR FRACTION FOUR FIFTHS */
#define XK_onesixth                      0x0ab6  /* U+2159 VULGAR FRACTION ONE SIXTH */
#define XK_fivesixths                    0x0ab7  /* U+215A VULGAR FRACTION FIVE SIXTHS */
#define XK_careof                        0x0ab8  /* U+2105 CARE OF */
#define XK_figdash                       0x0abb  /* U+2012 FIGURE DASH */
#define XK_leftanglebracket              0x0abc  /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/
#define XK_decimalpoint                  0x0abd  /*(U+002E FULL STOP)*/
#define XK_rightanglebracket             0x0abe  /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/
#define XK_marker                        0x0abf
#define XK_oneeighth                     0x0ac3  /* U+215B VULGAR FRACTION ONE EIGHTH */
#define XK_threeeighths                  0x0ac4  /* U+215C VULGAR FRACTION THREE EIGHTHS */
#define XK_fiveeighths                   0x0ac5  /* U+215D VULGAR FRACTION FIVE EIGHTHS */
#define XK_seveneighths                  0x0ac6  /* U+215E VULGAR FRACTION SEVEN EIGHTHS */
#define XK_trademark                     0x0ac9  /* U+2122 TRADE MARK SIGN */
#define XK_signaturemark                 0x0aca  /*(U+2613 SALTIRE)*/







|

|







1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
#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+2329 LEFT-POINTING ANGLE BRACKET)*/
#define XK_decimalpoint                  0x0abd  /*(U+002E FULL STOP)*/
#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
2511
2512
2513
2514
2515
2516
2517
#define XK_Hangul_SingleCandidate        0xff3c  /* Single candidate */
#define XK_Hangul_MultipleCandidate      0xff3d  /* Multiple candidate */
#define XK_Hangul_PreviousCandidate      0xff3e  /* Previous candidate */
#define XK_Hangul_Special                0xff3f  /* Special symbols */
#define XK_Hangul_switch                 0xff7e  /* Alias for mode_switch */

/* Hangul Consonant Characters */
#define XK_Hangul_Kiyeog                 0x0ea1
#define XK_Hangul_SsangKiyeog            0x0ea2
#define XK_Hangul_KiyeogSios             0x0ea3
#define XK_Hangul_Nieun                  0x0ea4
#define XK_Hangul_NieunJieuj             0x0ea5
#define XK_Hangul_NieunHieuh             0x0ea6
#define XK_Hangul_Dikeud                 0x0ea7
#define XK_Hangul_SsangDikeud            0x0ea8
#define XK_Hangul_Rieul                  0x0ea9
#define XK_Hangul_RieulKiyeog            0x0eaa
#define XK_Hangul_RieulMieum             0x0eab
#define XK_Hangul_RieulPieub             0x0eac
#define XK_Hangul_RieulSios              0x0ead
#define XK_Hangul_RieulTieut             0x0eae
#define XK_Hangul_RieulPhieuf            0x0eaf
#define XK_Hangul_RieulHieuh             0x0eb0
#define XK_Hangul_Mieum                  0x0eb1
#define XK_Hangul_Pieub                  0x0eb2
#define XK_Hangul_SsangPieub             0x0eb3
#define XK_Hangul_PieubSios              0x0eb4
#define XK_Hangul_Sios                   0x0eb5
#define XK_Hangul_SsangSios              0x0eb6
#define XK_Hangul_Ieung                  0x0eb7
#define XK_Hangul_Jieuj                  0x0eb8
#define XK_Hangul_SsangJieuj             0x0eb9
#define XK_Hangul_Cieuc                  0x0eba
#define XK_Hangul_Khieuq                 0x0ebb
#define XK_Hangul_Tieut                  0x0ebc
#define XK_Hangul_Phieuf                 0x0ebd
#define XK_Hangul_Hieuh                  0x0ebe

/* Hangul Vowel Characters */
#define XK_Hangul_A                      0x0ebf
#define XK_Hangul_AE                     0x0ec0
#define XK_Hangul_YA                     0x0ec1
#define XK_Hangul_YAE                    0x0ec2
#define XK_Hangul_EO                     0x0ec3
#define XK_Hangul_E                      0x0ec4
#define XK_Hangul_YEO                    0x0ec5
#define XK_Hangul_YE                     0x0ec6
#define XK_Hangul_O                      0x0ec7
#define XK_Hangul_WA                     0x0ec8
#define XK_Hangul_WAE                    0x0ec9
#define XK_Hangul_OE                     0x0eca
#define XK_Hangul_YO                     0x0ecb
#define XK_Hangul_U                      0x0ecc
#define XK_Hangul_WEO                    0x0ecd
#define XK_Hangul_WE                     0x0ece
#define XK_Hangul_WI                     0x0ecf
#define XK_Hangul_YU                     0x0ed0
#define XK_Hangul_EU                     0x0ed1
#define XK_Hangul_YI                     0x0ed2
#define XK_Hangul_I                      0x0ed3

/* Hangul syllable-final (JongSeong) Characters */
#define XK_Hangul_J_Kiyeog               0x0ed4
#define XK_Hangul_J_SsangKiyeog          0x0ed5
#define XK_Hangul_J_KiyeogSios           0x0ed6
#define XK_Hangul_J_Nieun                0x0ed7
#define XK_Hangul_J_NieunJieuj           0x0ed8
#define XK_Hangul_J_NieunHieuh           0x0ed9
#define XK_Hangul_J_Dikeud               0x0eda
#define XK_Hangul_J_Rieul                0x0edb
#define XK_Hangul_J_RieulKiyeog          0x0edc
#define XK_Hangul_J_RieulMieum           0x0edd
#define XK_Hangul_J_RieulPieub           0x0ede
#define XK_Hangul_J_RieulSios            0x0edf
#define XK_Hangul_J_RieulTieut           0x0ee0
#define XK_Hangul_J_RieulPhieuf          0x0ee1
#define XK_Hangul_J_RieulHieuh           0x0ee2
#define XK_Hangul_J_Mieum                0x0ee3
#define XK_Hangul_J_Pieub                0x0ee4
#define XK_Hangul_J_PieubSios            0x0ee5
#define XK_Hangul_J_Sios                 0x0ee6
#define XK_Hangul_J_SsangSios            0x0ee7
#define XK_Hangul_J_Ieung                0x0ee8
#define XK_Hangul_J_Jieuj                0x0ee9
#define XK_Hangul_J_Cieuc                0x0eea
#define XK_Hangul_J_Khieuq               0x0eeb
#define XK_Hangul_J_Tieut                0x0eec
#define XK_Hangul_J_Phieuf               0x0eed
#define XK_Hangul_J_Hieuh                0x0eee

/* Ancient Hangul Consonant Characters */
#define XK_Hangul_RieulYeorinHieuh       0x0eef
#define XK_Hangul_SunkyeongeumMieum      0x0ef0
#define XK_Hangul_SunkyeongeumPieub      0x0ef1
#define XK_Hangul_PanSios                0x0ef2
#define XK_Hangul_KkogjiDalrinIeung      0x0ef3
#define XK_Hangul_SunkyeongeumPhieuf     0x0ef4
#define XK_Hangul_YeorinHieuh            0x0ef5

/* Ancient Hangul Vowel Characters */
#define XK_Hangul_AraeA                  0x0ef6
#define XK_Hangul_AraeAE                 0x0ef7

/* Ancient Hangul syllable-final (JongSeong) Characters */
#define XK_Hangul_J_PanSios              0x0ef8
#define XK_Hangul_J_KkogjiDalrinIeung    0x0ef9
#define XK_Hangul_J_YeorinHieuh          0x0efa

/* Korean currency symbol */
#define XK_Korean_Won                    0x0eff  /*(U+20A9 WON SIGN)*/

#endif /* XK_KOREAN */

/*
 * Armenian
 */

#ifdef XK_ARMENIAN
#define XK_Armenian_ligature_ew       0x1000587  /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */
#define XK_Armenian_full_stop         0x1000589  /* U+0589 ARMENIAN FULL STOP */
#define XK_Armenian_verjaket          0x1000589  /* U+0589 ARMENIAN FULL STOP */
#define XK_Armenian_separation_mark   0x100055d  /* U+055D ARMENIAN COMMA */
#define XK_Armenian_but               0x100055d  /* U+055D ARMENIAN COMMA */
#define XK_Armenian_hyphen            0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_yentamna          0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_exclam            0x100055c  /* U+055C ARMENIAN EXCLAMATION MARK */
#define XK_Armenian_amanak            0x100055c  /* U+055C ARMENIAN EXCLAMATION MARK */
#define XK_Armenian_accent            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_shesht            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_question          0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_paruyk            0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_AYB               0x1000531  /* U+0531 ARMENIAN CAPITAL LETTER AYB */
#define XK_Armenian_ayb               0x1000561  /* U+0561 ARMENIAN SMALL LETTER AYB */
#define XK_Armenian_BEN               0x1000532  /* U+0532 ARMENIAN CAPITAL LETTER BEN */
#define XK_Armenian_ben               0x1000562  /* U+0562 ARMENIAN SMALL LETTER BEN */
#define XK_Armenian_GIM               0x1000533  /* U+0533 ARMENIAN CAPITAL LETTER GIM */
#define XK_Armenian_gim               0x1000563  /* U+0563 ARMENIAN SMALL LETTER GIM */
#define XK_Armenian_DA                0x1000534  /* U+0534 ARMENIAN CAPITAL LETTER DA */
#define XK_Armenian_da                0x1000564  /* U+0564 ARMENIAN SMALL LETTER DA */
#define XK_Armenian_YECH              0x1000535  /* U+0535 ARMENIAN CAPITAL LETTER ECH */
#define XK_Armenian_yech              0x1000565  /* U+0565 ARMENIAN SMALL LETTER ECH */
#define XK_Armenian_ZA                0x1000536  /* U+0536 ARMENIAN CAPITAL LETTER ZA */
#define XK_Armenian_za                0x1000566  /* U+0566 ARMENIAN SMALL LETTER ZA */
#define XK_Armenian_E                 0x1000537  /* U+0537 ARMENIAN CAPITAL LETTER EH */
#define XK_Armenian_e                 0x1000567  /* U+0567 ARMENIAN SMALL LETTER EH */
#define XK_Armenian_AT                0x1000538  /* U+0538 ARMENIAN CAPITAL LETTER ET */
#define XK_Armenian_at                0x1000568  /* U+0568 ARMENIAN SMALL LETTER ET */
#define XK_Armenian_TO                0x1000539  /* U+0539 ARMENIAN CAPITAL LETTER TO */
#define XK_Armenian_to                0x1000569  /* U+0569 ARMENIAN SMALL LETTER TO */
#define XK_Armenian_ZHE               0x100053a  /* U+053A ARMENIAN CAPITAL LETTER ZHE */
#define XK_Armenian_zhe               0x100056a  /* U+056A ARMENIAN SMALL LETTER ZHE */
#define XK_Armenian_INI               0x100053b  /* U+053B ARMENIAN CAPITAL LETTER INI */
#define XK_Armenian_ini               0x100056b  /* U+056B ARMENIAN SMALL LETTER INI */
#define XK_Armenian_LYUN              0x100053c  /* U+053C ARMENIAN CAPITAL LETTER LIWN */
#define XK_Armenian_lyun              0x100056c  /* U+056C ARMENIAN SMALL LETTER LIWN */
#define XK_Armenian_KHE               0x100053d  /* U+053D ARMENIAN CAPITAL LETTER XEH */
#define XK_Armenian_khe               0x100056d  /* U+056D ARMENIAN SMALL LETTER XEH */
#define XK_Armenian_TSA               0x100053e  /* U+053E ARMENIAN CAPITAL LETTER CA */
#define XK_Armenian_tsa               0x100056e  /* U+056E ARMENIAN SMALL LETTER CA */
#define XK_Armenian_KEN               0x100053f  /* U+053F ARMENIAN CAPITAL LETTER KEN */
#define XK_Armenian_ken               0x100056f  /* U+056F ARMENIAN SMALL LETTER KEN */
#define XK_Armenian_HO                0x1000540  /* U+0540 ARMENIAN CAPITAL LETTER HO */
#define XK_Armenian_ho                0x1000570  /* U+0570 ARMENIAN SMALL LETTER HO */
#define XK_Armenian_DZA               0x1000541  /* U+0541 ARMENIAN CAPITAL LETTER JA */
#define XK_Armenian_dza               0x1000571  /* U+0571 ARMENIAN SMALL LETTER JA */
#define XK_Armenian_GHAT              0x1000542  /* U+0542 ARMENIAN CAPITAL LETTER GHAD */
#define XK_Armenian_ghat              0x1000572  /* U+0572 ARMENIAN SMALL LETTER GHAD */
#define XK_Armenian_TCHE              0x1000543  /* U+0543 ARMENIAN CAPITAL LETTER CHEH */
#define XK_Armenian_tche              0x1000573  /* U+0573 ARMENIAN SMALL LETTER CHEH */
#define XK_Armenian_MEN               0x1000544  /* U+0544 ARMENIAN CAPITAL LETTER MEN */
#define XK_Armenian_men               0x1000574  /* U+0574 ARMENIAN SMALL LETTER MEN */
#define XK_Armenian_HI                0x1000545  /* U+0545 ARMENIAN CAPITAL LETTER YI */
#define XK_Armenian_hi                0x1000575  /* U+0575 ARMENIAN SMALL LETTER YI */
#define XK_Armenian_NU                0x1000546  /* U+0546 ARMENIAN CAPITAL LETTER NOW */
#define XK_Armenian_nu                0x1000576  /* U+0576 ARMENIAN SMALL LETTER NOW */
#define XK_Armenian_SHA               0x1000547  /* U+0547 ARMENIAN CAPITAL LETTER SHA */
#define XK_Armenian_sha               0x1000577  /* U+0577 ARMENIAN SMALL LETTER SHA */
#define XK_Armenian_VO                0x1000548  /* U+0548 ARMENIAN CAPITAL LETTER VO */
#define XK_Armenian_vo                0x1000578  /* U+0578 ARMENIAN SMALL LETTER VO */
#define XK_Armenian_CHA               0x1000549  /* U+0549 ARMENIAN CAPITAL LETTER CHA */
#define XK_Armenian_cha               0x1000579  /* U+0579 ARMENIAN SMALL LETTER CHA */
#define XK_Armenian_PE                0x100054a  /* U+054A ARMENIAN CAPITAL LETTER PEH */
#define XK_Armenian_pe                0x100057a  /* U+057A ARMENIAN SMALL LETTER PEH */
#define XK_Armenian_JE                0x100054b  /* U+054B ARMENIAN CAPITAL LETTER JHEH */
#define XK_Armenian_je                0x100057b  /* U+057B ARMENIAN SMALL LETTER JHEH */
#define XK_Armenian_RA                0x100054c  /* U+054C ARMENIAN CAPITAL LETTER RA */
#define XK_Armenian_ra                0x100057c  /* U+057C ARMENIAN SMALL LETTER RA */
#define XK_Armenian_SE                0x100054d  /* U+054D ARMENIAN CAPITAL LETTER SEH */
#define XK_Armenian_se                0x100057d  /* U+057D ARMENIAN SMALL LETTER SEH */
#define XK_Armenian_VEV               0x100054e  /* U+054E ARMENIAN CAPITAL LETTER VEW */
#define XK_Armenian_vev               0x100057e  /* U+057E ARMENIAN SMALL LETTER VEW */
#define XK_Armenian_TYUN              0x100054f  /* U+054F ARMENIAN CAPITAL LETTER TIWN */
#define XK_Armenian_tyun              0x100057f  /* U+057F ARMENIAN SMALL LETTER TIWN */
#define XK_Armenian_RE                0x1000550  /* U+0550 ARMENIAN CAPITAL LETTER REH */
#define XK_Armenian_re                0x1000580  /* U+0580 ARMENIAN SMALL LETTER REH */
#define XK_Armenian_TSO               0x1000551  /* U+0551 ARMENIAN CAPITAL LETTER CO */
#define XK_Armenian_tso               0x1000581  /* U+0581 ARMENIAN SMALL LETTER CO */
#define XK_Armenian_VYUN              0x1000552  /* U+0552 ARMENIAN CAPITAL LETTER YIWN */
#define XK_Armenian_vyun              0x1000582  /* U+0582 ARMENIAN SMALL LETTER YIWN */
#define XK_Armenian_PYUR              0x1000553  /* U+0553 ARMENIAN CAPITAL LETTER PIWR */
#define XK_Armenian_pyur              0x1000583  /* U+0583 ARMENIAN SMALL LETTER PIWR */
#define XK_Armenian_KE                0x1000554  /* U+0554 ARMENIAN CAPITAL LETTER KEH */
#define XK_Armenian_ke                0x1000584  /* U+0584 ARMENIAN SMALL LETTER KEH */
#define XK_Armenian_O                 0x1000555  /* U+0555 ARMENIAN CAPITAL LETTER OH */
#define XK_Armenian_o                 0x1000585  /* U+0585 ARMENIAN SMALL LETTER OH */
#define XK_Armenian_FE                0x1000556  /* U+0556 ARMENIAN CAPITAL LETTER FEH */
#define XK_Armenian_fe                0x1000586  /* U+0586 ARMENIAN SMALL LETTER FEH */
#define XK_Armenian_apostrophe        0x100055a  /* U+055A ARMENIAN APOSTROPHE */
#endif /* XK_ARMENIAN */

/*
 * Georgian
 */

#ifdef XK_GEORGIAN
#define XK_Georgian_an                0x10010d0  /* U+10D0 GEORGIAN LETTER AN */
#define XK_Georgian_ban               0x10010d1  /* U+10D1 GEORGIAN LETTER BAN */
#define XK_Georgian_gan               0x10010d2  /* U+10D2 GEORGIAN LETTER GAN */
#define XK_Georgian_don               0x10010d3  /* U+10D3 GEORGIAN LETTER DON */
#define XK_Georgian_en                0x10010d4  /* U+10D4 GEORGIAN LETTER EN */
#define XK_Georgian_vin               0x10010d5  /* U+10D5 GEORGIAN LETTER VIN */
#define XK_Georgian_zen               0x10010d6  /* U+10D6 GEORGIAN LETTER ZEN */
#define XK_Georgian_tan               0x10010d7  /* U+10D7 GEORGIAN LETTER TAN */
#define XK_Georgian_in                0x10010d8  /* U+10D8 GEORGIAN LETTER IN */
#define XK_Georgian_kan               0x10010d9  /* U+10D9 GEORGIAN LETTER KAN */
#define XK_Georgian_las               0x10010da  /* U+10DA GEORGIAN LETTER LAS */
#define XK_Georgian_man               0x10010db  /* U+10DB GEORGIAN LETTER MAN */
#define XK_Georgian_nar               0x10010dc  /* U+10DC GEORGIAN LETTER NAR */
#define XK_Georgian_on                0x10010dd  /* U+10DD GEORGIAN LETTER ON */
#define XK_Georgian_par               0x10010de  /* U+10DE GEORGIAN LETTER PAR */
#define XK_Georgian_zhar              0x10010df  /* U+10DF GEORGIAN LETTER ZHAR */
#define XK_Georgian_rae               0x10010e0  /* U+10E0 GEORGIAN LETTER RAE */
#define XK_Georgian_san               0x10010e1  /* U+10E1 GEORGIAN LETTER SAN */
#define XK_Georgian_tar               0x10010e2  /* U+10E2 GEORGIAN LETTER TAR */
#define XK_Georgian_un                0x10010e3  /* U+10E3 GEORGIAN LETTER UN */
#define XK_Georgian_phar              0x10010e4  /* U+10E4 GEORGIAN LETTER PHAR */
#define XK_Georgian_khar              0x10010e5  /* U+10E5 GEORGIAN LETTER KHAR */
#define XK_Georgian_ghan              0x10010e6  /* U+10E6 GEORGIAN LETTER GHAN */
#define XK_Georgian_qar               0x10010e7  /* U+10E7 GEORGIAN LETTER QAR */
#define XK_Georgian_shin              0x10010e8  /* U+10E8 GEORGIAN LETTER SHIN */
#define XK_Georgian_chin              0x10010e9  /* U+10E9 GEORGIAN LETTER CHIN */
#define XK_Georgian_can               0x10010ea  /* U+10EA GEORGIAN LETTER CAN */
#define XK_Georgian_jil               0x10010eb  /* U+10EB GEORGIAN LETTER JIL */
#define XK_Georgian_cil               0x10010ec  /* U+10EC GEORGIAN LETTER CIL */
#define XK_Georgian_char              0x10010ed  /* U+10ED GEORGIAN LETTER CHAR */
#define XK_Georgian_xan               0x10010ee  /* U+10EE GEORGIAN LETTER XAN */
#define XK_Georgian_jhan              0x10010ef  /* U+10EF GEORGIAN LETTER JHAN */
#define XK_Georgian_hae               0x10010f0  /* U+10F0 GEORGIAN LETTER HAE */
#define XK_Georgian_he                0x10010f1  /* U+10F1 GEORGIAN LETTER HE */
#define XK_Georgian_hie               0x10010f2  /* U+10F2 GEORGIAN LETTER HIE */
#define XK_Georgian_we                0x10010f3  /* U+10F3 GEORGIAN LETTER WE */
#define XK_Georgian_har               0x10010f4  /* U+10F4 GEORGIAN LETTER HAR */
#define XK_Georgian_hoe               0x10010f5  /* U+10F5 GEORGIAN LETTER HOE */
#define XK_Georgian_fi                0x10010f6  /* U+10F6 GEORGIAN LETTER FI */
#endif /* XK_GEORGIAN */

/*
 * Azeri (and other Turkic or Caucasian languages)
 */

#ifdef XK_CAUCASUS
/* latin */
#define XK_Xabovedot                  0x1001e8a  /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */
#define XK_Ibreve                     0x100012c  /* U+012C LATIN CAPITAL LETTER I WITH BREVE */
#define XK_Zstroke                    0x10001b5  /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */
#define XK_Gcaron                     0x10001e6  /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */
#define XK_Ocaron                     0x10001d1  /* U+01D1 LATIN CAPITAL LETTER O WITH CARON */
#define XK_Obarred                    0x100019f  /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
#define XK_xabovedot                  0x1001e8b  /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */
#define XK_ibreve                     0x100012d  /* U+012D LATIN SMALL LETTER I WITH BREVE */
#define XK_zstroke                    0x10001b6  /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */
#define XK_gcaron                     0x10001e7  /* U+01E7 LATIN SMALL LETTER G WITH CARON */
#define XK_ocaron                     0x10001d2  /* U+01D2 LATIN SMALL LETTER O WITH CARON */
#define XK_obarred                    0x1000275  /* U+0275 LATIN SMALL LETTER BARRED O */
#define XK_SCHWA                      0x100018f  /* U+018F LATIN CAPITAL LETTER SCHWA */
#define XK_schwa                      0x1000259  /* U+0259 LATIN SMALL LETTER SCHWA */
#define XK_EZH                        0x10001b7  /* U+01B7 LATIN CAPITAL LETTER EZH */
#define XK_ezh                        0x1000292  /* U+0292 LATIN SMALL LETTER EZH */
/* those are not really Caucasus */
/* For Inupiak */
#define XK_Lbelowdot                  0x1001e36  /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */
#define XK_lbelowdot                  0x1001e37  /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */
#endif /* XK_CAUCASUS */

/*
 * Vietnamese
 */

#ifdef XK_VIETNAMESE
#define XK_Abelowdot                  0x1001ea0  /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */
#define XK_abelowdot                  0x1001ea1  /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */
#define XK_Ahook                      0x1001ea2  /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */
#define XK_ahook                      0x1001ea3  /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */
#define XK_Acircumflexacute           0x1001ea4  /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
#define XK_acircumflexacute           0x1001ea5  /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
#define XK_Acircumflexgrave           0x1001ea6  /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
#define XK_acircumflexgrave           0x1001ea7  /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
#define XK_Acircumflexhook            0x1001ea8  /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_acircumflexhook            0x1001ea9  /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Acircumflextilde           0x1001eaa  /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
#define XK_acircumflextilde           0x1001eab  /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
#define XK_Acircumflexbelowdot        0x1001eac  /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
#define XK_acircumflexbelowdot        0x1001ead  /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Abreveacute                0x1001eae  /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
#define XK_abreveacute                0x1001eaf  /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */
#define XK_Abrevegrave                0x1001eb0  /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
#define XK_abrevegrave                0x1001eb1  /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */
#define XK_Abrevehook                 0x1001eb2  /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
#define XK_abrevehook                 0x1001eb3  /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
#define XK_Abrevetilde                0x1001eb4  /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
#define XK_abrevetilde                0x1001eb5  /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */
#define XK_Abrevebelowdot             0x1001eb6  /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
#define XK_abrevebelowdot             0x1001eb7  /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
#define XK_Ebelowdot                  0x1001eb8  /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */
#define XK_ebelowdot                  0x1001eb9  /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */
#define XK_Ehook                      0x1001eba  /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */
#define XK_ehook                      0x1001ebb  /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */
#define XK_Etilde                     0x1001ebc  /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */
#define XK_etilde                     0x1001ebd  /* U+1EBD LATIN SMALL LETTER E WITH TILDE */
#define XK_Ecircumflexacute           0x1001ebe  /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
#define XK_ecircumflexacute           0x1001ebf  /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
#define XK_Ecircumflexgrave           0x1001ec0  /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
#define XK_ecircumflexgrave           0x1001ec1  /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
#define XK_Ecircumflexhook            0x1001ec2  /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_ecircumflexhook            0x1001ec3  /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Ecircumflextilde           0x1001ec4  /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
#define XK_ecircumflextilde           0x1001ec5  /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
#define XK_Ecircumflexbelowdot        0x1001ec6  /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
#define XK_ecircumflexbelowdot        0x1001ec7  /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Ihook                      0x1001ec8  /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */
#define XK_ihook                      0x1001ec9  /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */
#define XK_Ibelowdot                  0x1001eca  /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */
#define XK_ibelowdot                  0x1001ecb  /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */
#define XK_Obelowdot                  0x1001ecc  /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */
#define XK_obelowdot                  0x1001ecd  /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */
#define XK_Ohook                      0x1001ece  /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */
#define XK_ohook                      0x1001ecf  /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */
#define XK_Ocircumflexacute           0x1001ed0  /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
#define XK_ocircumflexacute           0x1001ed1  /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
#define XK_Ocircumflexgrave           0x1001ed2  /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
#define XK_ocircumflexgrave           0x1001ed3  /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
#define XK_Ocircumflexhook            0x1001ed4  /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_ocircumflexhook            0x1001ed5  /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
#define XK_Ocircumflextilde           0x1001ed6  /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
#define XK_ocircumflextilde           0x1001ed7  /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
#define XK_Ocircumflexbelowdot        0x1001ed8  /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
#define XK_ocircumflexbelowdot        0x1001ed9  /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
#define XK_Ohornacute                 0x1001eda  /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
#define XK_ohornacute                 0x1001edb  /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */
#define XK_Ohorngrave                 0x1001edc  /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
#define XK_ohorngrave                 0x1001edd  /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */
#define XK_Ohornhook                  0x1001ede  /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
#define XK_ohornhook                  0x1001edf  /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
#define XK_Ohorntilde                 0x1001ee0  /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */
#define XK_ohorntilde                 0x1001ee1  /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */
#define XK_Ohornbelowdot              0x1001ee2  /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
#define XK_ohornbelowdot              0x1001ee3  /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
#define XK_Ubelowdot                  0x1001ee4  /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */
#define XK_ubelowdot                  0x1001ee5  /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */
#define XK_Uhook                      0x1001ee6  /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */
#define XK_uhook                      0x1001ee7  /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */
#define XK_Uhornacute                 0x1001ee8  /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
#define XK_uhornacute                 0x1001ee9  /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */
#define XK_Uhorngrave                 0x1001eea  /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
#define XK_uhorngrave                 0x1001eeb  /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */
#define XK_Uhornhook                  0x1001eec  /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
#define XK_uhornhook                  0x1001eed  /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
#define XK_Uhorntilde                 0x1001eee  /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */
#define XK_uhorntilde                 0x1001eef  /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */
#define XK_Uhornbelowdot              0x1001ef0  /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
#define XK_uhornbelowdot              0x1001ef1  /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
#define XK_Ybelowdot                  0x1001ef4  /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */
#define XK_ybelowdot                  0x1001ef5  /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */
#define XK_Yhook                      0x1001ef6  /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
#define XK_yhook                      0x1001ef7  /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */
#define XK_Ytilde                     0x1001ef8  /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */
#define XK_ytilde                     0x1001ef9  /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */
#define XK_Ohorn                      0x10001a0  /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */
#define XK_ohorn                      0x10001a1  /* U+01A1 LATIN SMALL LETTER O WITH HORN */
#define XK_Uhorn                      0x10001af  /* U+01AF LATIN CAPITAL LETTER U WITH HORN */
#define XK_uhorn                      0x10001b0  /* U+01B0 LATIN SMALL LETTER U WITH HORN */

#endif /* XK_VIETNAMESE */

#ifdef XK_CURRENCY
#define XK_EcuSign                    0x10020a0  /* U+20A0 EURO-CURRENCY SIGN */
#define XK_ColonSign                  0x10020a1  /* U+20A1 COLON SIGN */
#define XK_CruzeiroSign               0x10020a2  /* U+20A2 CRUZEIRO SIGN */
#define XK_FFrancSign                 0x10020a3  /* U+20A3 FRENCH FRANC SIGN */
#define XK_LiraSign                   0x10020a4  /* U+20A4 LIRA SIGN */
#define XK_MillSign                   0x10020a5  /* U+20A5 MILL SIGN */
#define XK_NairaSign                  0x10020a6  /* U+20A6 NAIRA SIGN */
#define XK_PesetaSign                 0x10020a7  /* U+20A7 PESETA SIGN */
#define XK_RupeeSign                  0x10020a8  /* U+20A8 RUPEE SIGN */
#define XK_WonSign                    0x10020a9  /* U+20A9 WON SIGN */
#define XK_NewSheqelSign              0x10020aa  /* U+20AA NEW SHEQEL SIGN */
#define XK_DongSign                   0x10020ab  /* U+20AB DONG SIGN */
#define XK_EuroSign                      0x20ac  /* U+20AC EURO SIGN */
#endif /* XK_CURRENCY */

#ifdef XK_MATHEMATICAL
/* one, two and three are defined above. */
#define XK_zerosuperior               0x1002070  /* U+2070 SUPERSCRIPT ZERO */
#define XK_foursuperior               0x1002074  /* U+2074 SUPERSCRIPT FOUR */
#define XK_fivesuperior               0x1002075  /* U+2075 SUPERSCRIPT FIVE */
#define XK_sixsuperior                0x1002076  /* U+2076 SUPERSCRIPT SIX */
#define XK_sevensuperior              0x1002077  /* U+2077 SUPERSCRIPT SEVEN */
#define XK_eightsuperior              0x1002078  /* U+2078 SUPERSCRIPT EIGHT */
#define XK_ninesuperior               0x1002079  /* U+2079 SUPERSCRIPT NINE */
#define XK_zerosubscript              0x1002080  /* U+2080 SUBSCRIPT ZERO */
#define XK_onesubscript               0x1002081  /* U+2081 SUBSCRIPT ONE */
#define XK_twosubscript               0x1002082  /* U+2082 SUBSCRIPT TWO */
#define XK_threesubscript             0x1002083  /* U+2083 SUBSCRIPT THREE */
#define XK_foursubscript              0x1002084  /* U+2084 SUBSCRIPT FOUR */
#define XK_fivesubscript              0x1002085  /* U+2085 SUBSCRIPT FIVE */
#define XK_sixsubscript               0x1002086  /* U+2086 SUBSCRIPT SIX */
#define XK_sevensubscript             0x1002087  /* U+2087 SUBSCRIPT SEVEN */
#define XK_eightsubscript             0x1002088  /* U+2088 SUBSCRIPT EIGHT */
#define XK_ninesubscript              0x1002089  /* U+2089 SUBSCRIPT NINE */
#define XK_partdifferential           0x1002202  /* U+2202 PARTIAL DIFFERENTIAL */
#define XK_emptyset                   0x1002205  /* U+2205 NULL SET */
#define XK_elementof                  0x1002208  /* U+2208 ELEMENT OF */
#define XK_notelementof               0x1002209  /* U+2209 NOT AN ELEMENT OF */
#define XK_containsas                 0x100220B  /* U+220B CONTAINS AS MEMBER */
#define XK_squareroot                 0x100221A  /* U+221A SQUARE ROOT */
#define XK_cuberoot                   0x100221B  /* U+221B CUBE ROOT */
#define XK_fourthroot                 0x100221C  /* U+221C FOURTH ROOT */
#define XK_dintegral                  0x100222C  /* U+222C DOUBLE INTEGRAL */
#define XK_tintegral                  0x100222D  /* U+222D TRIPLE INTEGRAL */
#define XK_because                    0x1002235  /* U+2235 BECAUSE */
#define XK_approxeq                   0x1002248  /* U+2245 ALMOST EQUAL TO */
#define XK_notapproxeq                0x1002247  /* U+2247 NOT ALMOST EQUAL TO */
#define XK_notidentical               0x1002262  /* U+2262 NOT IDENTICAL TO */
#define XK_stricteq                   0x1002263  /* U+2263 STRICTLY EQUIVALENT TO */
#endif /* XK_MATHEMATICAL */

#ifdef XK_BRAILLE
#define XK_braille_dot_1                 0xfff1
#define XK_braille_dot_2                 0xfff2
#define XK_braille_dot_3                 0xfff3
#define XK_braille_dot_4                 0xfff4
#define XK_braille_dot_5                 0xfff5
#define XK_braille_dot_6                 0xfff6
#define XK_braille_dot_7                 0xfff7
#define XK_braille_dot_8                 0xfff8
#define XK_braille_dot_9                 0xfff9
#define XK_braille_dot_10                0xfffa
#define XK_braille_blank              0x1002800  /* U+2800 BRAILLE PATTERN BLANK */
#define XK_braille_dots_1             0x1002801  /* U+2801 BRAILLE PATTERN DOTS-1 */
#define XK_braille_dots_2             0x1002802  /* U+2802 BRAILLE PATTERN DOTS-2 */
#define XK_braille_dots_12            0x1002803  /* U+2803 BRAILLE PATTERN DOTS-12 */
#define XK_braille_dots_3             0x1002804  /* U+2804 BRAILLE PATTERN DOTS-3 */
#define XK_braille_dots_13            0x1002805  /* U+2805 BRAILLE PATTERN DOTS-13 */
#define XK_braille_dots_23            0x1002806  /* U+2806 BRAILLE PATTERN DOTS-23 */
#define XK_braille_dots_123           0x1002807  /* U+2807 BRAILLE PATTERN DOTS-123 */
#define XK_braille_dots_4             0x1002808  /* U+2808 BRAILLE PATTERN DOTS-4 */
#define XK_braille_dots_14            0x1002809  /* U+2809 BRAILLE PATTERN DOTS-14 */
#define XK_braille_dots_24            0x100280a  /* U+280a BRAILLE PATTERN DOTS-24 */
#define XK_braille_dots_124           0x100280b  /* U+280b BRAILLE PATTERN DOTS-124 */
#define XK_braille_dots_34            0x100280c  /* U+280c BRAILLE PATTERN DOTS-34 */
#define XK_braille_dots_134           0x100280d  /* U+280d BRAILLE PATTERN DOTS-134 */
#define XK_braille_dots_234           0x100280e  /* U+280e BRAILLE PATTERN DOTS-234 */
#define XK_braille_dots_1234          0x100280f  /* U+280f BRAILLE PATTERN DOTS-1234 */
#define XK_braille_dots_5             0x1002810  /* U+2810 BRAILLE PATTERN DOTS-5 */
#define XK_braille_dots_15            0x1002811  /* U+2811 BRAILLE PATTERN DOTS-15 */
#define XK_braille_dots_25            0x1002812  /* U+2812 BRAILLE PATTERN DOTS-25 */
#define XK_braille_dots_125           0x1002813  /* U+2813 BRAILLE PATTERN DOTS-125 */
#define XK_braille_dots_35            0x1002814  /* U+2814 BRAILLE PATTERN DOTS-35 */
#define XK_braille_dots_135           0x1002815  /* U+2815 BRAILLE PATTERN DOTS-135 */
#define XK_braille_dots_235           0x1002816  /* U+2816 BRAILLE PATTERN DOTS-235 */
#define XK_braille_dots_1235          0x1002817  /* U+2817 BRAILLE PATTERN DOTS-1235 */
#define XK_braille_dots_45            0x1002818  /* U+2818 BRAILLE PATTERN DOTS-45 */
#define XK_braille_dots_145           0x1002819  /* U+2819 BRAILLE PATTERN DOTS-145 */
#define XK_braille_dots_245           0x100281a  /* U+281a BRAILLE PATTERN DOTS-245 */
#define XK_braille_dots_1245          0x100281b  /* U+281b BRAILLE PATTERN DOTS-1245 */
#define XK_braille_dots_345           0x100281c  /* U+281c BRAILLE PATTERN DOTS-345 */
#define XK_braille_dots_1345          0x100281d  /* U+281d BRAILLE PATTERN DOTS-1345 */
#define XK_braille_dots_2345          0x100281e  /* U+281e BRAILLE PATTERN DOTS-2345 */
#define XK_braille_dots_12345         0x100281f  /* U+281f BRAILLE PATTERN DOTS-12345 */
#define XK_braille_dots_6             0x1002820  /* U+2820 BRAILLE PATTERN DOTS-6 */
#define XK_braille_dots_16            0x1002821  /* U+2821 BRAILLE PATTERN DOTS-16 */
#define XK_braille_dots_26            0x1002822  /* U+2822 BRAILLE PATTERN DOTS-26 */
#define XK_braille_dots_126           0x1002823  /* U+2823 BRAILLE PATTERN DOTS-126 */
#define XK_braille_dots_36            0x1002824  /* U+2824 BRAILLE PATTERN DOTS-36 */
#define XK_braille_dots_136           0x1002825  /* U+2825 BRAILLE PATTERN DOTS-136 */
#define XK_braille_dots_236           0x1002826  /* U+2826 BRAILLE PATTERN DOTS-236 */
#define XK_braille_dots_1236          0x1002827  /* U+2827 BRAILLE PATTERN DOTS-1236 */
#define XK_braille_dots_46            0x1002828  /* U+2828 BRAILLE PATTERN DOTS-46 */
#define XK_braille_dots_146           0x1002829  /* U+2829 BRAILLE PATTERN DOTS-146 */
#define XK_braille_dots_246           0x100282a  /* U+282a BRAILLE PATTERN DOTS-246 */
#define XK_braille_dots_1246          0x100282b  /* U+282b BRAILLE PATTERN DOTS-1246 */
#define XK_braille_dots_346           0x100282c  /* U+282c BRAILLE PATTERN DOTS-346 */
#define XK_braille_dots_1346          0x100282d  /* U+282d BRAILLE PATTERN DOTS-1346 */
#define XK_braille_dots_2346          0x100282e  /* U+282e BRAILLE PATTERN DOTS-2346 */
#define XK_braille_dots_12346         0x100282f  /* U+282f BRAILLE PATTERN DOTS-12346 */
#define XK_braille_dots_56            0x1002830  /* U+2830 BRAILLE PATTERN DOTS-56 */
#define XK_braille_dots_156           0x1002831  /* U+2831 BRAILLE PATTERN DOTS-156 */
#define XK_braille_dots_256           0x1002832  /* U+2832 BRAILLE PATTERN DOTS-256 */
#define XK_braille_dots_1256          0x1002833  /* U+2833 BRAILLE PATTERN DOTS-1256 */
#define XK_braille_dots_356           0x1002834  /* U+2834 BRAILLE PATTERN DOTS-356 */
#define XK_braille_dots_1356          0x1002835  /* U+2835 BRAILLE PATTERN DOTS-1356 */
#define XK_braille_dots_2356          0x1002836  /* U+2836 BRAILLE PATTERN DOTS-2356 */
#define XK_braille_dots_12356         0x1002837  /* U+2837 BRAILLE PATTERN DOTS-12356 */
#define XK_braille_dots_456           0x1002838  /* U+2838 BRAILLE PATTERN DOTS-456 */
#define XK_braille_dots_1456          0x1002839  /* U+2839 BRAILLE PATTERN DOTS-1456 */
#define XK_braille_dots_2456          0x100283a  /* U+283a BRAILLE PATTERN DOTS-2456 */
#define XK_braille_dots_12456         0x100283b  /* U+283b BRAILLE PATTERN DOTS-12456 */
#define XK_braille_dots_3456          0x100283c  /* U+283c BRAILLE PATTERN DOTS-3456 */
#define XK_braille_dots_13456         0x100283d  /* U+283d BRAILLE PATTERN DOTS-13456 */
#define XK_braille_dots_23456         0x100283e  /* U+283e BRAILLE PATTERN DOTS-23456 */
#define XK_braille_dots_123456        0x100283f  /* U+283f BRAILLE PATTERN DOTS-123456 */
#define XK_braille_dots_7             0x1002840  /* U+2840 BRAILLE PATTERN DOTS-7 */
#define XK_braille_dots_17            0x1002841  /* U+2841 BRAILLE PATTERN DOTS-17 */
#define XK_braille_dots_27            0x1002842  /* U+2842 BRAILLE PATTERN DOTS-27 */
#define XK_braille_dots_127           0x1002843  /* U+2843 BRAILLE PATTERN DOTS-127 */
#define XK_braille_dots_37            0x1002844  /* U+2844 BRAILLE PATTERN DOTS-37 */
#define XK_braille_dots_137           0x1002845  /* U+2845 BRAILLE PATTERN DOTS-137 */
#define XK_braille_dots_237           0x1002846  /* U+2846 BRAILLE PATTERN DOTS-237 */
#define XK_braille_dots_1237          0x1002847  /* U+2847 BRAILLE PATTERN DOTS-1237 */
#define XK_braille_dots_47            0x1002848  /* U+2848 BRAILLE PATTERN DOTS-47 */
#define XK_braille_dots_147           0x1002849  /* U+2849 BRAILLE PATTERN DOTS-147 */
#define XK_braille_dots_247           0x100284a  /* U+284a BRAILLE PATTERN DOTS-247 */
#define XK_braille_dots_1247          0x100284b  /* U+284b BRAILLE PATTERN DOTS-1247 */
#define XK_braille_dots_347           0x100284c  /* U+284c BRAILLE PATTERN DOTS-347 */
#define XK_braille_dots_1347          0x100284d  /* U+284d BRAILLE PATTERN DOTS-1347 */
#define XK_braille_dots_2347          0x100284e  /* U+284e BRAILLE PATTERN DOTS-2347 */
#define XK_braille_dots_12347         0x100284f  /* U+284f BRAILLE PATTERN DOTS-12347 */
#define XK_braille_dots_57            0x1002850  /* U+2850 BRAILLE PATTERN DOTS-57 */
#define XK_braille_dots_157           0x1002851  /* U+2851 BRAILLE PATTERN DOTS-157 */
#define XK_braille_dots_257           0x1002852  /* U+2852 BRAILLE PATTERN DOTS-257 */
#define XK_braille_dots_1257          0x1002853  /* U+2853 BRAILLE PATTERN DOTS-1257 */
#define XK_braille_dots_357           0x1002854  /* U+2854 BRAILLE PATTERN DOTS-357 */
#define XK_braille_dots_1357          0x1002855  /* U+2855 BRAILLE PATTERN DOTS-1357 */
#define XK_braille_dots_2357          0x1002856  /* U+2856 BRAILLE PATTERN DOTS-2357 */
#define XK_braille_dots_12357         0x1002857  /* U+2857 BRAILLE PATTERN DOTS-12357 */
#define XK_braille_dots_457           0x1002858  /* U+2858 BRAILLE PATTERN DOTS-457 */
#define XK_braille_dots_1457          0x1002859  /* U+2859 BRAILLE PATTERN DOTS-1457 */
#define XK_braille_dots_2457          0x100285a  /* U+285a BRAILLE PATTERN DOTS-2457 */
#define XK_braille_dots_12457         0x100285b  /* U+285b BRAILLE PATTERN DOTS-12457 */
#define XK_braille_dots_3457          0x100285c  /* U+285c BRAILLE PATTERN DOTS-3457 */
#define XK_braille_dots_13457         0x100285d  /* U+285d BRAILLE PATTERN DOTS-13457 */
#define XK_braille_dots_23457         0x100285e  /* U+285e BRAILLE PATTERN DOTS-23457 */
#define XK_braille_dots_123457        0x100285f  /* U+285f BRAILLE PATTERN DOTS-123457 */
#define XK_braille_dots_67            0x1002860  /* U+2860 BRAILLE PATTERN DOTS-67 */
#define XK_braille_dots_167           0x1002861  /* U+2861 BRAILLE PATTERN DOTS-167 */
#define XK_braille_dots_267           0x1002862  /* U+2862 BRAILLE PATTERN DOTS-267 */
#define XK_braille_dots_1267          0x1002863  /* U+2863 BRAILLE PATTERN DOTS-1267 */
#define XK_braille_dots_367           0x1002864  /* U+2864 BRAILLE PATTERN DOTS-367 */
#define XK_braille_dots_1367          0x1002865  /* U+2865 BRAILLE PATTERN DOTS-1367 */
#define XK_braille_dots_2367          0x1002866  /* U+2866 BRAILLE PATTERN DOTS-2367 */
#define XK_braille_dots_12367         0x1002867  /* U+2867 BRAILLE PATTERN DOTS-12367 */
#define XK_braille_dots_467           0x1002868  /* U+2868 BRAILLE PATTERN DOTS-467 */
#define XK_braille_dots_1467          0x1002869  /* U+2869 BRAILLE PATTERN DOTS-1467 */
#define XK_braille_dots_2467          0x100286a  /* U+286a BRAILLE PATTERN DOTS-2467 */
#define XK_braille_dots_12467         0x100286b  /* U+286b BRAILLE PATTERN DOTS-12467 */
#define XK_braille_dots_3467          0x100286c  /* U+286c BRAILLE PATTERN DOTS-3467 */
#define XK_braille_dots_13467         0x100286d  /* U+286d BRAILLE PATTERN DOTS-13467 */
#define XK_braille_dots_23467         0x100286e  /* U+286e BRAILLE PATTERN DOTS-23467 */
#define XK_braille_dots_123467        0x100286f  /* U+286f BRAILLE PATTERN DOTS-123467 */
#define XK_braille_dots_567           0x1002870  /* U+2870 BRAILLE PATTERN DOTS-567 */
#define XK_braille_dots_1567          0x1002871  /* U+2871 BRAILLE PATTERN DOTS-1567 */
#define XK_braille_dots_2567          0x1002872  /* U+2872 BRAILLE PATTERN DOTS-2567 */
#define XK_braille_dots_12567         0x1002873  /* U+2873 BRAILLE PATTERN DOTS-12567 */
#define XK_braille_dots_3567          0x1002874  /* U+2874 BRAILLE PATTERN DOTS-3567 */
#define XK_braille_dots_13567         0x1002875  /* U+2875 BRAILLE PATTERN DOTS-13567 */
#define XK_braille_dots_23567         0x1002876  /* U+2876 BRAILLE PATTERN DOTS-23567 */
#define XK_braille_dots_123567        0x1002877  /* U+2877 BRAILLE PATTERN DOTS-123567 */
#define XK_braille_dots_4567          0x1002878  /* U+2878 BRAILLE PATTERN DOTS-4567 */
#define XK_braille_dots_14567         0x1002879  /* U+2879 BRAILLE PATTERN DOTS-14567 */
#define XK_braille_dots_24567         0x100287a  /* U+287a BRAILLE PATTERN DOTS-24567 */
#define XK_braille_dots_124567        0x100287b  /* U+287b BRAILLE PATTERN DOTS-124567 */
#define XK_braille_dots_34567         0x100287c  /* U+287c BRAILLE PATTERN DOTS-34567 */
#define XK_braille_dots_134567        0x100287d  /* U+287d BRAILLE PATTERN DOTS-134567 */
#define XK_braille_dots_234567        0x100287e  /* U+287e BRAILLE PATTERN DOTS-234567 */
#define XK_braille_dots_1234567       0x100287f  /* U+287f BRAILLE PATTERN DOTS-1234567 */
#define XK_braille_dots_8             0x1002880  /* U+2880 BRAILLE PATTERN DOTS-8 */
#define XK_braille_dots_18            0x1002881  /* U+2881 BRAILLE PATTERN DOTS-18 */
#define XK_braille_dots_28            0x1002882  /* U+2882 BRAILLE PATTERN DOTS-28 */
#define XK_braille_dots_128           0x1002883  /* U+2883 BRAILLE PATTERN DOTS-128 */
#define XK_braille_dots_38            0x1002884  /* U+2884 BRAILLE PATTERN DOTS-38 */
#define XK_braille_dots_138           0x1002885  /* U+2885 BRAILLE PATTERN DOTS-138 */
#define XK_braille_dots_238           0x1002886  /* U+2886 BRAILLE PATTERN DOTS-238 */
#define XK_braille_dots_1238          0x1002887  /* U+2887 BRAILLE PATTERN DOTS-1238 */
#define XK_braille_dots_48            0x1002888  /* U+2888 BRAILLE PATTERN DOTS-48 */
#define XK_braille_dots_148           0x1002889  /* U+2889 BRAILLE PATTERN DOTS-148 */
#define XK_braille_dots_248           0x100288a  /* U+288a BRAILLE PATTERN DOTS-248 */
#define XK_braille_dots_1248          0x100288b  /* U+288b BRAILLE PATTERN DOTS-1248 */
#define XK_braille_dots_348           0x100288c  /* U+288c BRAILLE PATTERN DOTS-348 */
#define XK_braille_dots_1348          0x100288d  /* U+288d BRAILLE PATTERN DOTS-1348 */
#define XK_braille_dots_2348          0x100288e  /* U+288e BRAILLE PATTERN DOTS-2348 */
#define XK_braille_dots_12348         0x100288f  /* U+288f BRAILLE PATTERN DOTS-12348 */
#define XK_braille_dots_58            0x1002890  /* U+2890 BRAILLE PATTERN DOTS-58 */
#define XK_braille_dots_158           0x1002891  /* U+2891 BRAILLE PATTERN DOTS-158 */
#define XK_braille_dots_258           0x1002892  /* U+2892 BRAILLE PATTERN DOTS-258 */
#define XK_braille_dots_1258          0x1002893  /* U+2893 BRAILLE PATTERN DOTS-1258 */
#define XK_braille_dots_358           0x1002894  /* U+2894 BRAILLE PATTERN DOTS-358 */
#define XK_braille_dots_1358          0x1002895  /* U+2895 BRAILLE PATTERN DOTS-1358 */
#define XK_braille_dots_2358          0x1002896  /* U+2896 BRAILLE PATTERN DOTS-2358 */
#define XK_braille_dots_12358         0x1002897  /* U+2897 BRAILLE PATTERN DOTS-12358 */
#define XK_braille_dots_458           0x1002898  /* U+2898 BRAILLE PATTERN DOTS-458 */
#define XK_braille_dots_1458          0x1002899  /* U+2899 BRAILLE PATTERN DOTS-1458 */
#define XK_braille_dots_2458          0x100289a  /* U+289a BRAILLE PATTERN DOTS-2458 */
#define XK_braille_dots_12458         0x100289b  /* U+289b BRAILLE PATTERN DOTS-12458 */
#define XK_braille_dots_3458          0x100289c  /* U+289c BRAILLE PATTERN DOTS-3458 */
#define XK_braille_dots_13458         0x100289d  /* U+289d BRAILLE PATTERN DOTS-13458 */
#define XK_braille_dots_23458         0x100289e  /* U+289e BRAILLE PATTERN DOTS-23458 */
#define XK_braille_dots_123458        0x100289f  /* U+289f BRAILLE PATTERN DOTS-123458 */
#define XK_braille_dots_68            0x10028a0  /* U+28a0 BRAILLE PATTERN DOTS-68 */
#define XK_braille_dots_168           0x10028a1  /* U+28a1 BRAILLE PATTERN DOTS-168 */
#define XK_braille_dots_268           0x10028a2  /* U+28a2 BRAILLE PATTERN DOTS-268 */
#define XK_braille_dots_1268          0x10028a3  /* U+28a3 BRAILLE PATTERN DOTS-1268 */
#define XK_braille_dots_368           0x10028a4  /* U+28a4 BRAILLE PATTERN DOTS-368 */
#define XK_braille_dots_1368          0x10028a5  /* U+28a5 BRAILLE PATTERN DOTS-1368 */
#define XK_braille_dots_2368          0x10028a6  /* U+28a6 BRAILLE PATTERN DOTS-2368 */
#define XK_braille_dots_12368         0x10028a7  /* U+28a7 BRAILLE PATTERN DOTS-12368 */
#define XK_braille_dots_468           0x10028a8  /* U+28a8 BRAILLE PATTERN DOTS-468 */
#define XK_braille_dots_1468          0x10028a9  /* U+28a9 BRAILLE PATTERN DOTS-1468 */
#define XK_braille_dots_2468          0x10028aa  /* U+28aa BRAILLE PATTERN DOTS-2468 */
#define XK_braille_dots_12468         0x10028ab  /* U+28ab BRAILLE PATTERN DOTS-12468 */
#define XK_braille_dots_3468          0x10028ac  /* U+28ac BRAILLE PATTERN DOTS-3468 */
#define XK_braille_dots_13468         0x10028ad  /* U+28ad BRAILLE PATTERN DOTS-13468 */
#define XK_braille_dots_23468         0x10028ae  /* U+28ae BRAILLE PATTERN DOTS-23468 */
#define XK_braille_dots_123468        0x10028af  /* U+28af BRAILLE PATTERN DOTS-123468 */
#define XK_braille_dots_568           0x10028b0  /* U+28b0 BRAILLE PATTERN DOTS-568 */
#define XK_braille_dots_1568          0x10028b1  /* U+28b1 BRAILLE PATTERN DOTS-1568 */
#define XK_braille_dots_2568          0x10028b2  /* U+28b2 BRAILLE PATTERN DOTS-2568 */
#define XK_braille_dots_12568         0x10028b3  /* U+28b3 BRAILLE PATTERN DOTS-12568 */
#define XK_braille_dots_3568          0x10028b4  /* U+28b4 BRAILLE PATTERN DOTS-3568 */
#define XK_braille_dots_13568         0x10028b5  /* U+28b5 BRAILLE PATTERN DOTS-13568 */
#define XK_braille_dots_23568         0x10028b6  /* U+28b6 BRAILLE PATTERN DOTS-23568 */
#define XK_braille_dots_123568        0x10028b7  /* U+28b7 BRAILLE PATTERN DOTS-123568 */
#define XK_braille_dots_4568          0x10028b8  /* U+28b8 BRAILLE PATTERN DOTS-4568 */
#define XK_braille_dots_14568         0x10028b9  /* U+28b9 BRAILLE PATTERN DOTS-14568 */
#define XK_braille_dots_24568         0x10028ba  /* U+28ba BRAILLE PATTERN DOTS-24568 */
#define XK_braille_dots_124568        0x10028bb  /* U+28bb BRAILLE PATTERN DOTS-124568 */
#define XK_braille_dots_34568         0x10028bc  /* U+28bc BRAILLE PATTERN DOTS-34568 */
#define XK_braille_dots_134568        0x10028bd  /* U+28bd BRAILLE PATTERN DOTS-134568 */
#define XK_braille_dots_234568        0x10028be  /* U+28be BRAILLE PATTERN DOTS-234568 */
#define XK_braille_dots_1234568       0x10028bf  /* U+28bf BRAILLE PATTERN DOTS-1234568 */
#define XK_braille_dots_78            0x10028c0  /* U+28c0 BRAILLE PATTERN DOTS-78 */
#define XK_braille_dots_178           0x10028c1  /* U+28c1 BRAILLE PATTERN DOTS-178 */
#define XK_braille_dots_278           0x10028c2  /* U+28c2 BRAILLE PATTERN DOTS-278 */
#define XK_braille_dots_1278          0x10028c3  /* U+28c3 BRAILLE PATTERN DOTS-1278 */
#define XK_braille_dots_378           0x10028c4  /* U+28c4 BRAILLE PATTERN DOTS-378 */
#define XK_braille_dots_1378          0x10028c5  /* U+28c5 BRAILLE PATTERN DOTS-1378 */
#define XK_braille_dots_2378          0x10028c6  /* U+28c6 BRAILLE PATTERN DOTS-2378 */
#define XK_braille_dots_12378         0x10028c7  /* U+28c7 BRAILLE PATTERN DOTS-12378 */
#define XK_braille_dots_478           0x10028c8  /* U+28c8 BRAILLE PATTERN DOTS-478 */
#define XK_braille_dots_1478          0x10028c9  /* U+28c9 BRAILLE PATTERN DOTS-1478 */
#define XK_braille_dots_2478          0x10028ca  /* U+28ca BRAILLE PATTERN DOTS-2478 */
#define XK_braille_dots_12478         0x10028cb  /* U+28cb BRAILLE PATTERN DOTS-12478 */
#define XK_braille_dots_3478          0x10028cc  /* U+28cc BRAILLE PATTERN DOTS-3478 */
#define XK_braille_dots_13478         0x10028cd  /* U+28cd BRAILLE PATTERN DOTS-13478 */
#define XK_braille_dots_23478         0x10028ce  /* U+28ce BRAILLE PATTERN DOTS-23478 */
#define XK_braille_dots_123478        0x10028cf  /* U+28cf BRAILLE PATTERN DOTS-123478 */
#define XK_braille_dots_578           0x10028d0  /* U+28d0 BRAILLE PATTERN DOTS-578 */
#define XK_braille_dots_1578          0x10028d1  /* U+28d1 BRAILLE PATTERN DOTS-1578 */
#define XK_braille_dots_2578          0x10028d2  /* U+28d2 BRAILLE PATTERN DOTS-2578 */
#define XK_braille_dots_12578         0x10028d3  /* U+28d3 BRAILLE PATTERN DOTS-12578 */
#define XK_braille_dots_3578          0x10028d4  /* U+28d4 BRAILLE PATTERN DOTS-3578 */
#define XK_braille_dots_13578         0x10028d5  /* U+28d5 BRAILLE PATTERN DOTS-13578 */
#define XK_braille_dots_23578         0x10028d6  /* U+28d6 BRAILLE PATTERN DOTS-23578 */
#define XK_braille_dots_123578        0x10028d7  /* U+28d7 BRAILLE PATTERN DOTS-123578 */
#define XK_braille_dots_4578          0x10028d8  /* U+28d8 BRAILLE PATTERN DOTS-4578 */
#define XK_braille_dots_14578         0x10028d9  /* U+28d9 BRAILLE PATTERN DOTS-14578 */
#define XK_braille_dots_24578         0x10028da  /* U+28da BRAILLE PATTERN DOTS-24578 */
#define XK_braille_dots_124578        0x10028db  /* U+28db BRAILLE PATTERN DOTS-124578 */
#define XK_braille_dots_34578         0x10028dc  /* U+28dc BRAILLE PATTERN DOTS-34578 */
#define XK_braille_dots_134578        0x10028dd  /* U+28dd BRAILLE PATTERN DOTS-134578 */
#define XK_braille_dots_234578        0x10028de  /* U+28de BRAILLE PATTERN DOTS-234578 */
#define XK_braille_dots_1234578       0x10028df  /* U+28df BRAILLE PATTERN DOTS-1234578 */
#define XK_braille_dots_678           0x10028e0  /* U+28e0 BRAILLE PATTERN DOTS-678 */
#define XK_braille_dots_1678          0x10028e1  /* U+28e1 BRAILLE PATTERN DOTS-1678 */
#define XK_braille_dots_2678          0x10028e2  /* U+28e2 BRAILLE PATTERN DOTS-2678 */
#define XK_braille_dots_12678         0x10028e3  /* U+28e3 BRAILLE PATTERN DOTS-12678 */
#define XK_braille_dots_3678          0x10028e4  /* U+28e4 BRAILLE PATTERN DOTS-3678 */
#define XK_braille_dots_13678         0x10028e5  /* U+28e5 BRAILLE PATTERN DOTS-13678 */
#define XK_braille_dots_23678         0x10028e6  /* U+28e6 BRAILLE PATTERN DOTS-23678 */
#define XK_braille_dots_123678        0x10028e7  /* U+28e7 BRAILLE PATTERN DOTS-123678 */
#define XK_braille_dots_4678          0x10028e8  /* U+28e8 BRAILLE PATTERN DOTS-4678 */
#define XK_braille_dots_14678         0x10028e9  /* U+28e9 BRAILLE PATTERN DOTS-14678 */
#define XK_braille_dots_24678         0x10028ea  /* U+28ea BRAILLE PATTERN DOTS-24678 */
#define XK_braille_dots_124678        0x10028eb  /* U+28eb BRAILLE PATTERN DOTS-124678 */
#define XK_braille_dots_34678         0x10028ec  /* U+28ec BRAILLE PATTERN DOTS-34678 */
#define XK_braille_dots_134678        0x10028ed  /* U+28ed BRAILLE PATTERN DOTS-134678 */
#define XK_braille_dots_234678        0x10028ee  /* U+28ee BRAILLE PATTERN DOTS-234678 */
#define XK_braille_dots_1234678       0x10028ef  /* U+28ef BRAILLE PATTERN DOTS-1234678 */
#define XK_braille_dots_5678          0x10028f0  /* U+28f0 BRAILLE PATTERN DOTS-5678 */
#define XK_braille_dots_15678         0x10028f1  /* U+28f1 BRAILLE PATTERN DOTS-15678 */
#define XK_braille_dots_25678         0x10028f2  /* U+28f2 BRAILLE PATTERN DOTS-25678 */
#define XK_braille_dots_125678        0x10028f3  /* U+28f3 BRAILLE PATTERN DOTS-125678 */
#define XK_braille_dots_35678         0x10028f4  /* U+28f4 BRAILLE PATTERN DOTS-35678 */
#define XK_braille_dots_135678        0x10028f5  /* U+28f5 BRAILLE PATTERN DOTS-135678 */
#define XK_braille_dots_235678        0x10028f6  /* U+28f6 BRAILLE PATTERN DOTS-235678 */
#define XK_braille_dots_1235678       0x10028f7  /* U+28f7 BRAILLE PATTERN DOTS-1235678 */
#define XK_braille_dots_45678         0x10028f8  /* U+28f8 BRAILLE PATTERN DOTS-45678 */
#define XK_braille_dots_145678        0x10028f9  /* U+28f9 BRAILLE PATTERN DOTS-145678 */
#define XK_braille_dots_245678        0x10028fa  /* U+28fa BRAILLE PATTERN DOTS-245678 */
#define XK_braille_dots_1245678       0x10028fb  /* U+28fb BRAILLE PATTERN DOTS-1245678 */
#define XK_braille_dots_345678        0x10028fc  /* U+28fc BRAILLE PATTERN DOTS-345678 */
#define XK_braille_dots_1345678       0x10028fd  /* U+28fd BRAILLE PATTERN DOTS-1345678 */
#define XK_braille_dots_2345678       0x10028fe  /* U+28fe BRAILLE PATTERN DOTS-2345678 */
#define XK_braille_dots_12345678      0x10028ff  /* U+28ff BRAILLE PATTERN DOTS-12345678 */
#endif /* XK_BRAILLE */

/*
 * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf)
 * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html
 */

#ifdef XK_SINHALA
#define XK_Sinh_ng            0x1000d82  /* U+0D82 SINHALA ANUSVARAYA */
#define XK_Sinh_h2            0x1000d83  /* U+0D83 SINHALA VISARGAYA */
#define XK_Sinh_a             0x1000d85  /* U+0D85 SINHALA AYANNA */
#define XK_Sinh_aa            0x1000d86  /* U+0D86 SINHALA AAYANNA */
#define XK_Sinh_ae            0x1000d87  /* U+0D87 SINHALA AEYANNA */
#define XK_Sinh_aee           0x1000d88  /* U+0D88 SINHALA AEEYANNA */
#define XK_Sinh_i             0x1000d89  /* U+0D89 SINHALA IYANNA */
#define XK_Sinh_ii            0x1000d8a  /* U+0D8A SINHALA IIYANNA */
#define XK_Sinh_u             0x1000d8b  /* U+0D8B SINHALA UYANNA */
#define XK_Sinh_uu            0x1000d8c  /* U+0D8C SINHALA UUYANNA */
#define XK_Sinh_ri            0x1000d8d  /* U+0D8D SINHALA IRUYANNA */
#define XK_Sinh_rii           0x1000d8e  /* U+0D8E SINHALA IRUUYANNA */
#define XK_Sinh_lu            0x1000d8f  /* U+0D8F SINHALA ILUYANNA */
#define XK_Sinh_luu           0x1000d90  /* U+0D90 SINHALA ILUUYANNA */
#define XK_Sinh_e             0x1000d91  /* U+0D91 SINHALA EYANNA */
#define XK_Sinh_ee            0x1000d92  /* U+0D92 SINHALA EEYANNA */
#define XK_Sinh_ai            0x1000d93  /* U+0D93 SINHALA AIYANNA */
#define XK_Sinh_o             0x1000d94  /* U+0D94 SINHALA OYANNA */
#define XK_Sinh_oo            0x1000d95  /* U+0D95 SINHALA OOYANNA */
#define XK_Sinh_au            0x1000d96  /* U+0D96 SINHALA AUYANNA */
#define XK_Sinh_ka            0x1000d9a  /* U+0D9A SINHALA KAYANNA */
#define XK_Sinh_kha           0x1000d9b  /* U+0D9B SINHALA MAHA. KAYANNA */
#define XK_Sinh_ga            0x1000d9c  /* U+0D9C SINHALA GAYANNA */
#define XK_Sinh_gha           0x1000d9d  /* U+0D9D SINHALA MAHA. GAYANNA */
#define XK_Sinh_ng2           0x1000d9e  /* U+0D9E SINHALA KANTAJA NAASIKYAYA */
#define XK_Sinh_nga           0x1000d9f  /* U+0D9F SINHALA SANYAKA GAYANNA */
#define XK_Sinh_ca            0x1000da0  /* U+0DA0 SINHALA CAYANNA */
#define XK_Sinh_cha           0x1000da1  /* U+0DA1 SINHALA MAHA. CAYANNA */
#define XK_Sinh_ja            0x1000da2  /* U+0DA2 SINHALA JAYANNA */
#define XK_Sinh_jha           0x1000da3  /* U+0DA3 SINHALA MAHA. JAYANNA */
#define XK_Sinh_nya           0x1000da4  /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */
#define XK_Sinh_jnya          0x1000da5  /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */
#define XK_Sinh_nja           0x1000da6  /* U+0DA6 SINHALA SANYAKA JAYANNA */
#define XK_Sinh_tta           0x1000da7  /* U+0DA7 SINHALA TTAYANNA */
#define XK_Sinh_ttha          0x1000da8  /* U+0DA8 SINHALA MAHA. TTAYANNA */
#define XK_Sinh_dda           0x1000da9  /* U+0DA9 SINHALA DDAYANNA */
#define XK_Sinh_ddha          0x1000daa  /* U+0DAA SINHALA MAHA. DDAYANNA */
#define XK_Sinh_nna           0x1000dab  /* U+0DAB SINHALA MUURDHAJA NAYANNA */
#define XK_Sinh_ndda          0x1000dac  /* U+0DAC SINHALA SANYAKA DDAYANNA */
#define XK_Sinh_tha           0x1000dad  /* U+0DAD SINHALA TAYANNA */
#define XK_Sinh_thha          0x1000dae  /* U+0DAE SINHALA MAHA. TAYANNA */
#define XK_Sinh_dha           0x1000daf  /* U+0DAF SINHALA DAYANNA */
#define XK_Sinh_dhha          0x1000db0  /* U+0DB0 SINHALA MAHA. DAYANNA */
#define XK_Sinh_na            0x1000db1  /* U+0DB1 SINHALA DANTAJA NAYANNA */
#define XK_Sinh_ndha          0x1000db3  /* U+0DB3 SINHALA SANYAKA DAYANNA */
#define XK_Sinh_pa            0x1000db4  /* U+0DB4 SINHALA PAYANNA */
#define XK_Sinh_pha           0x1000db5  /* U+0DB5 SINHALA MAHA. PAYANNA */
#define XK_Sinh_ba            0x1000db6  /* U+0DB6 SINHALA BAYANNA */
#define XK_Sinh_bha           0x1000db7  /* U+0DB7 SINHALA MAHA. BAYANNA */
#define XK_Sinh_ma            0x1000db8  /* U+0DB8 SINHALA MAYANNA */
#define XK_Sinh_mba           0x1000db9  /* U+0DB9 SINHALA AMBA BAYANNA */
#define XK_Sinh_ya            0x1000dba  /* U+0DBA SINHALA YAYANNA */
#define XK_Sinh_ra            0x1000dbb  /* U+0DBB SINHALA RAYANNA */
#define XK_Sinh_la            0x1000dbd  /* U+0DBD SINHALA DANTAJA LAYANNA */
#define XK_Sinh_va            0x1000dc0  /* U+0DC0 SINHALA VAYANNA */
#define XK_Sinh_sha           0x1000dc1  /* U+0DC1 SINHALA TAALUJA SAYANNA */
#define XK_Sinh_ssha          0x1000dc2  /* U+0DC2 SINHALA MUURDHAJA SAYANNA */
#define XK_Sinh_sa            0x1000dc3  /* U+0DC3 SINHALA DANTAJA SAYANNA */
#define XK_Sinh_ha            0x1000dc4  /* U+0DC4 SINHALA HAYANNA */
#define XK_Sinh_lla           0x1000dc5  /* U+0DC5 SINHALA MUURDHAJA LAYANNA */
#define XK_Sinh_fa            0x1000dc6  /* U+0DC6 SINHALA FAYANNA */
#define XK_Sinh_al            0x1000dca  /* U+0DCA SINHALA AL-LAKUNA */
#define XK_Sinh_aa2           0x1000dcf  /* U+0DCF SINHALA AELA-PILLA */
#define XK_Sinh_ae2           0x1000dd0  /* U+0DD0 SINHALA AEDA-PILLA */
#define XK_Sinh_aee2          0x1000dd1  /* U+0DD1 SINHALA DIGA AEDA-PILLA */
#define XK_Sinh_i2            0x1000dd2  /* U+0DD2 SINHALA IS-PILLA */
#define XK_Sinh_ii2           0x1000dd3  /* U+0DD3 SINHALA DIGA IS-PILLA */
#define XK_Sinh_u2            0x1000dd4  /* U+0DD4 SINHALA PAA-PILLA */
#define XK_Sinh_uu2           0x1000dd6  /* U+0DD6 SINHALA DIGA PAA-PILLA */
#define XK_Sinh_ru2           0x1000dd8  /* U+0DD8 SINHALA GAETTA-PILLA */
#define XK_Sinh_e2            0x1000dd9  /* U+0DD9 SINHALA KOMBUVA */
#define XK_Sinh_ee2           0x1000dda  /* U+0DDA SINHALA DIGA KOMBUVA */
#define XK_Sinh_ai2           0x1000ddb  /* U+0DDB SINHALA KOMBU DEKA */
#define XK_Sinh_o2            0x1000ddc  /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/
#define XK_Sinh_oo2           0x1000ddd  /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/
#define XK_Sinh_au2           0x1000dde  /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */
#define XK_Sinh_lu2           0x1000ddf  /* U+0DDF SINHALA GAYANUKITTA */
#define XK_Sinh_ruu2          0x1000df2  /* U+0DF2 SINHALA DIGA GAETTA-PILLA */
#define XK_Sinh_luu2          0x1000df3  /* U+0DF3 SINHALA DIGA GAYANUKITTA */
#define XK_Sinh_kunddaliya    0x1000df4  /* U+0DF4 SINHALA KUNDDALIYA */
#endif /* XK_SINHALA */

/* Multimedia keys, defined same as on Linux
 * /usr/include/pkg/libxkbcommon/xkbcommon/xkbcommon-keysyms.h
 */

#ifndef TK_NO_DEPRECATED
#define XK_XF86AudioLowerVolume	0x1008FF11   /* Volume control down        */
#define XK_XF86AudioMute	0x1008FF12   /* Mute sound from the system */
#define XK_XF86AudioRaiseVolume	0x1008FF13   /* Volume control up          */
#define XK_XF86AudioPlay	0x1008FF14   /* Start playing of audio >   */
#define XK_XF86AudioStop	0x1008FF15   /* Stop playing audio         */
#define XK_XF86AudioPrev	0x1008FF16   /* Previous track             */
#define XK_XF86AudioNext	0x1008FF17   /* Next track                 */
#endif /* !TK_NO_DEPRECATED */








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|


|
|


|
|
|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
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







































































































#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  /* 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  /* 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  /* 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  /* 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  /* 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  /* 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 */
















































































































































































































































































#ifdef XK_CURRENCY












#define XK_EuroSign                      0x20ac  /* U+20AC EURO SIGN */
#endif /* XK_CURRENCY */





































#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
































































































































































































































































#endif /* XK_BRAILLE */







































































































Changes to xlib/xcolors.c.

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
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"







|
|







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 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"

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#define RED(p)		((unsigned char) (p)[0])
#define GREEN(p)	((unsigned char) (p)[1])
#define BLUE(p)		((unsigned char) (p)[2])
#define US(expr)	((unsigned short) (expr))

Status
XParseColor(
    Display *display,
    Colormap map,
    const char *spec,
    XColor *colorPtr)
{
    (void)display;
    (void)map;

    if (spec[0] == '#') {
	char *p;
	Tcl_WideInt value = parseHex64bit(++spec, &p);

	/*
	 * If *p does not point to the end of the string, there were invalid
	 * digits in the spec. Ergo, it is not a valid color string.







|
|



<
<
<







332
333
334
335
336
337
338
339
340
341
342
343



344
345
346
347
348
349
350
#define RED(p)		((unsigned char) (p)[0])
#define GREEN(p)	((unsigned char) (p)[1])
#define BLUE(p)		((unsigned char) (p)[2])
#define US(expr)	((unsigned short) (expr))

Status
XParseColor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    const char *spec,
    XColor *colorPtr)
{



    if (spec[0] == '#') {
	char *p;
	Tcl_WideInt value = parseHex64bit(++spec, &p);

	/*
	 * If *p does not point to the end of the string, there were invalid
	 * digits in the spec. Ergo, it is not a valid color string.

Changes to xlib/xgc.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 * Copyright 2008-2009, Apple Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if !defined(MAC_OSX_TK)
#   include <X11/Xlib.h>
#   define TkpInitGCCache(gc)
#   define TkpFreeGCCache(gc)
#   define TkpGetGCCache(gc)
#else
#   include <tkMacOSXInt.h>
#   include <X11/Xlib.h>
#   include <X11/X.h>
#endif


#define MAX_DASH_LIST_SIZE 10
typedef struct {
    XGCValues gc;
    char dash[MAX_DASH_LIST_SIZE];
#ifdef MAC_OSX_TK
    TkpGCCache cache;
#endif
} XGCValuesWithCache;

/*
 *----------------------------------------------------------------------
 *
 * AllocClipMask --
 *
 *	Static helper proc to allocate new or clear existing TkpClipMask.







<
<
|
<
<
|
<
<
<
<







<
<
<
|







9
10
11
12
13
14
15


16


17




18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
 * Copyright 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"


#include <X11/Xlib.h>


#if defined(MAC_OSX_TK)




#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.
53
54
55
56
57
58
59


60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82


83

84


85
86
87
88
89
90
91

static TkpClipMask *AllocClipMask(GC gc) {
    TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;

    if (clip_mask == NULL) {
	clip_mask = (TkpClipMask *)ckalloc(sizeof(TkpClipMask));
	gc->clip_mask = (Pixmap) clip_mask;


    }


    return clip_mask;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeClipMask --
 *
 *	Static helper proc to free TkpClipMask.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void FreeClipMask(GC gc) {
    if (gc->clip_mask != None) {
	ckfree((char *)gc->clip_mask);


	gc->clip_mask = None;

    }


}

/*
 *----------------------------------------------------------------------
 *
 * XCreateGC --
 *







>
>

>
>




















|
|
>
>
|
>

>
>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

static TkpClipMask *AllocClipMask(GC gc) {
    TkpClipMask *clip_mask = (TkpClipMask*) gc->clip_mask;

    if (clip_mask == NULL) {
	clip_mask = (TkpClipMask *)ckalloc(sizeof(TkpClipMask));
	gc->clip_mask = (Pixmap) clip_mask;
    } else if (clip_mask->type == TKP_CLIP_REGION) {
	TkDestroyRegion(clip_mask->value.region);
    }
    clip_mask->type = TKP_CLIP_PIXMAP;
    clip_mask->value.pixmap = None;
    return clip_mask;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeClipMask --
 *
 *	Static helper proc to free TkpClipMask.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void FreeClipMask(GC gc) {
    TkpClipMask * clip_mask = (TkpClipMask*)gc->clip_mask;
    if (clip_mask == NULL) {
	return;
    }
    if (clip_mask->type == TKP_CLIP_REGION) {
	TkDestroyRegion(clip_mask->value.region);
    }
    ckfree(clip_mask);
    gc->clip_mask = None;
}

/*
 *----------------------------------------------------------------------
 *
 * XCreateGC --
 *
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
 *
 *----------------------------------------------------------------------
 */

GC
XCreateGC(
    Display *display,
    Drawable d,
    unsigned long mask,
    XGCValues *values)
{
    GC gp;
    (void)d;

    /*
     * In order to have room for a dash list, MAX_DASH_LIST_SIZE extra chars
     * are defined, which is invisible from the outside. The list is assumed
     * to end with a 0-char, so this must be set explicitly during
     * initialization.
     */

    gp = (GC)ckalloc(sizeof(XGCValuesWithCache));
    if (!gp) {
	return NULL;
    }

#define InitField(name,maskbit,default) \
	(gp->name = (mask & (maskbit)) ? values->name : (default))

    InitField(function,		  GCFunction,		GXcopy);
    InitField(plane_mask,	  GCPlaneMask,		(unsigned long)(~0));
    InitField(foreground,	  GCForeground,
	    BlackPixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(background,	  GCBackground,
	    WhitePixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(line_width,	  GCLineWidth,		1);
    InitField(line_style,	  GCLineStyle,		LineSolid);
    InitField(cap_style,	  GCCapStyle,		0);
    InitField(join_style,	  GCJoinStyle,		0);
    InitField(fill_style,	  GCFillStyle,		FillSolid);
    InitField(fill_rule,	  GCFillRule,		WindingRule);
    InitField(arc_mode,		  GCArcMode,		ArcPieSlice);
    InitField(tile,		  GCTile,		0);
    InitField(stipple,		  GCStipple,		0);
    InitField(ts_x_origin,	  GCTileStipXOrigin,	0);
    InitField(ts_y_origin,	  GCTileStipYOrigin,	0);
    InitField(font,		  GCFont,		0);
    InitField(subwindow_mode,	  GCSubwindowMode,	ClipByChildren);







|




<








|
<
<
<















|







97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 *
 *----------------------------------------------------------------------
 */

GC
XCreateGC(
    Display *display,
    TCL_UNUSED(Drawable),
    unsigned long mask,
    XGCValues *values)
{
    GC gp;


    /*
     * In order to have room for a dash list, MAX_DASH_LIST_SIZE extra chars
     * are defined, which is invisible from the outside. The list is assumed
     * to end with a 0-char, so this must be set explicitly during
     * initialization.
     */

    gp = (GC)ckalloc(sizeof(XGCValuesWithDash));




#define InitField(name,maskbit,default) \
	(gp->name = (mask & (maskbit)) ? values->name : (default))

    InitField(function,		  GCFunction,		GXcopy);
    InitField(plane_mask,	  GCPlaneMask,		(unsigned long)(~0));
    InitField(foreground,	  GCForeground,
	    BlackPixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(background,	  GCBackground,
	    WhitePixelOfScreen(DefaultScreenOfDisplay(display)));
    InitField(line_width,	  GCLineWidth,		1);
    InitField(line_style,	  GCLineStyle,		LineSolid);
    InitField(cap_style,	  GCCapStyle,		0);
    InitField(join_style,	  GCJoinStyle,		0);
    InitField(fill_style,	  GCFillStyle,		FillSolid);
    InitField(fill_rule,	  GCFillRule,		EvenOddRule);
    InitField(arc_mode,		  GCArcMode,		ArcPieSlice);
    InitField(tile,		  GCTile,		0);
    InitField(stipple,		  GCStipple,		0);
    InitField(ts_x_origin,	  GCTileStipXOrigin,	0);
    InitField(ts_y_origin,	  GCTileStipYOrigin,	0);
    InitField(font,		  GCFont,		0);
    InitField(subwindow_mode,	  GCSubwindowMode,	ClipByChildren);
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    gp->clip_mask = None;
    if (mask & GCClipMask) {
	TkpClipMask *clip_mask = AllocClipMask(gp);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = values->clip_mask;
    }
    TkpInitGCCache(gp);

    return gp;
}

#ifdef MAC_OSX_TK
/*
 *----------------------------------------------------------------------
 *
 * TkpGetGCCache --
 *
 * Results:
 *	Pointer to the TkpGCCache at the end of the GC.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkpGCCache*
TkpGetGCCache(GC gc) {
    return (gc ? &((XGCValuesWithCache *)gc)->cache : NULL);
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XChangeGC --
 *
 *	Changes the GC components specified by valuemask for the specified GC.
 *







<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







148
149
150
151
152
153
154


155
156
157





















158
159
160
161
162
163
164
    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;
    }


    return gp;
}






















/*
 *----------------------------------------------------------------------
 *
 * XChangeGC --
 *
 *	Changes the GC components specified by valuemask for the specified GC.
 *
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int XFreeGC(
    Display *d,
    GC gc)
{
    (void)d;

    if (gc != NULL) {
	FreeClipMask(gc);
	TkpFreeGCCache(gc);
	ckfree(gc);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------







|


<
<


<







225
226
227
228
229
230
231
232
233
234


235
236

237
238
239
240
241
242
243
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int XFreeGC(
    TCL_UNUSED(Display *),
    GC gc)
{


    if (gc != NULL) {
	FreeClipMask(gc);

	ckfree(gc);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493


494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515


























516
517
518
519
520
521
522
 *	Each function sets some slot in the GC.
 *
 *----------------------------------------------------------------------
 */

int
XSetForeground(
    Display *display,
    GC gc,
    unsigned long foreground)
{
    (void)display;

    gc->foreground = foreground;
    return Success;
}

int
XSetBackground(
    Display *display,
    GC gc,
    unsigned long background)
{
    (void)display;

    gc->background = background;
    return Success;
}

int
XSetDashes(
    Display *display,
    GC gc,
    int dash_offset,
    _Xconst char *dash_list,
    int n)
{
    char *p = &(gc->dashes);
    (void)display;

#ifdef TkWinDeleteBrush
    TkWinDeleteBrush(gc->fgBrush);
    TkWinDeletePen(gc->fgPen);
    TkWinDeleteBrush(gc->bgBrush);
    TkWinDeletePen(gc->fgExtPen);
#endif
    gc->dash_offset = dash_offset;
    if (n > MAX_DASH_LIST_SIZE) n = MAX_DASH_LIST_SIZE;
    while (n-- > 0) {
	*p++ = *dash_list++;
    }
    *p = 0;
    return Success;
}

int
XSetFunction(
    Display *display,
    GC gc,
    int function)
{
    (void)display;

    gc->function = function;
    return Success;
}

int
XSetFillRule(
    Display *display,
    GC gc,
    int fill_rule)
{
    (void)display;

    gc->fill_rule = fill_rule;
    return Success;
}

int
XSetFillStyle(
    Display *display,
    GC gc,
    int fill_style)
{
    (void)display;

    gc->fill_style = fill_style;
    return Success;
}

int
XSetTSOrigin(
    Display *display,
    GC gc,
    int x, int y)
{
    (void)display;

    gc->ts_x_origin = x;
    gc->ts_y_origin = y;
    return Success;
}

int
XSetFont(
    Display *display,
    GC gc,
    Font font)
{
    (void)display;

    gc->font = font;
    return Success;
}

int
XSetArcMode(
    Display *display,
    GC gc,
    int arc_mode)
{
    (void)display;

    gc->arc_mode = arc_mode;
    return Success;
}

int
XSetStipple(
    Display *display,
    GC gc,
    Pixmap stipple)
{
    (void)display;

    gc->stipple = stipple;
    return Success;
}

int
XSetLineAttributes(
    Display *display,
    GC gc,
    unsigned int line_width,
    int line_style,
    int cap_style,
    int join_style)
{
    (void)display;

    gc->line_width = line_width;
    gc->line_style = line_style;
    gc->cap_style = cap_style;
    gc->join_style = join_style;
    return Success;
}

int
XSetClipOrigin(
    Display *display,
    GC gc,
    int clip_x_origin,
    int clip_y_origin)
{
    (void)display;

    gc->clip_x_origin = clip_x_origin;
    gc->clip_y_origin = clip_y_origin;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetRegion, XSetClipMask --
 *
 *	Sets the clipping region/pixmap for a GC.
 *
 *	Note that unlike the Xlib equivalent, it is not safe to delete the
 *	region after setting it into the GC (except on Mac OS X). The only
 *	uses of TkSetRegion are currently in DisplayFrame and in
 *	ImgPhotoDisplay, which use the GC immediately.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates or deallocates a TkpClipMask.
 *
 *----------------------------------------------------------------------
 */

int
TkSetRegion(
    Display *display,
    GC gc,
    TkRegion r)
{
    (void)display;

    if (r == NULL) {
	Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_REGION;
	clip_mask->value.region = r;


    }
    return Success;
}

int
XSetClipMask(
    Display *display,
    GC gc,
    Pixmap pixmap)
{
    (void)display;

    if (pixmap == None) {
	FreeClipMask(gc);
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = pixmap;
    }
    return Success;
}



























/*
 * Some additional dummy functions (hopefully implemented soon).
 */

#if 0
Cursor







|



<
<






|



<
<






|






<


















|



<
<






|



<
<






|



<
<






|



<
<







|



<
<






|



<
<






|



<
<






|






<
<









|




<
<








|



|
|
<
<












|



<
<







>
>






|



<
<










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







254
255
256
257
258
259
260
261
262
263
264


265
266
267
268
269
270
271
272
273
274


275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309


310
311
312
313
314
315
316
317
318
319


320
321
322
323
324
325
326
327
328
329


330
331
332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
347
348
349
350


351
352
353
354
355
356
357
358
359
360


361
362
363
364
365
366
367
368
369
370


371
372
373
374
375
376
377
378
379
380
381
382
383


384
385
386
387
388
389
390
391
392
393
394
395
396
397


398
399
400
401
402
403
404
405
406
407
408
409
410
411


412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446


447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
 *	Each function sets some slot in the GC.
 *
 *----------------------------------------------------------------------
 */

int
XSetForeground(
    TCL_UNUSED(Display *),
    GC gc,
    unsigned long foreground)
{


    gc->foreground = foreground;
    return Success;
}

int
XSetBackground(
    TCL_UNUSED(Display *),
    GC gc,
    unsigned long background)
{


    gc->background = background;
    return Success;
}

int
XSetDashes(
    TCL_UNUSED(Display *),
    GC gc,
    int dash_offset,
    _Xconst char *dash_list,
    int n)
{
    char *p = &(gc->dashes);


#ifdef TkWinDeleteBrush
    TkWinDeleteBrush(gc->fgBrush);
    TkWinDeletePen(gc->fgPen);
    TkWinDeleteBrush(gc->bgBrush);
    TkWinDeletePen(gc->fgExtPen);
#endif
    gc->dash_offset = dash_offset;
    if (n > MAX_DASH_LIST_SIZE) n = MAX_DASH_LIST_SIZE;
    while (n-- > 0) {
	*p++ = *dash_list++;
    }
    *p = 0;
    return Success;
}

int
XSetFunction(
    TCL_UNUSED(Display *),
    GC gc,
    int function)
{


    gc->function = function;
    return Success;
}

int
XSetFillRule(
    TCL_UNUSED(Display *),
    GC gc,
    int fill_rule)
{


    gc->fill_rule = fill_rule;
    return Success;
}

int
XSetFillStyle(
    TCL_UNUSED(Display *),
    GC gc,
    int fill_style)
{


    gc->fill_style = fill_style;
    return Success;
}

int
XSetTSOrigin(
    TCL_UNUSED(Display *),
    GC gc,
    int x, int y)
{


    gc->ts_x_origin = x;
    gc->ts_y_origin = y;
    return Success;
}

int
XSetFont(
    TCL_UNUSED(Display *),
    GC gc,
    Font font)
{


    gc->font = font;
    return Success;
}

int
XSetArcMode(
    TCL_UNUSED(Display *),
    GC gc,
    int arc_mode)
{


    gc->arc_mode = arc_mode;
    return Success;
}

int
XSetStipple(
    TCL_UNUSED(Display *),
    GC gc,
    Pixmap stipple)
{


    gc->stipple = stipple;
    return Success;
}

int
XSetLineAttributes(
    TCL_UNUSED(Display *),
    GC gc,
    unsigned int line_width,
    int line_style,
    int cap_style,
    int join_style)
{


    gc->line_width = line_width;
    gc->line_style = line_style;
    gc->cap_style = cap_style;
    gc->join_style = join_style;
    return Success;
}

int
XSetClipOrigin(
    TCL_UNUSED(Display *),
    GC gc,
    int clip_x_origin,
    int clip_y_origin)
{


    gc->clip_x_origin = clip_x_origin;
    gc->clip_y_origin = clip_y_origin;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetRegion, XSetClipMask, XSetClipRectangles --
 *
 *	Sets the clipping region/pixmap for a GC.
 *
 *	Like the Xlib equivalent, it is safe to delete the
 *	region after setting it into the GC.


 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates or deallocates a TkpClipMask.
 *
 *----------------------------------------------------------------------
 */

int
TkSetRegion(
    TCL_UNUSED(Display *),
    GC gc,
    TkRegion r)
{


    if (r == NULL) {
	Tcl_Panic("must not pass NULL to TkSetRegion for compatibility with X11; use XSetClipMask instead");
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_REGION;
	clip_mask->value.region = r;
	clip_mask->value.region = TkCreateRegion();
	TkpCopyRegion(clip_mask->value.region, r);
    }
    return Success;
}

int
XSetClipMask(
    TCL_UNUSED(Display *),
    GC gc,
    Pixmap pixmap)
{


    if (pixmap == None) {
	FreeClipMask(gc);
    } else {
	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = pixmap;
    }
    return Success;
}

int
XSetClipRectangles(
    TCL_UNUSED(Display*),
    GC gc,
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    TCL_UNUSED(int))
{
    TkRegion clipRgn = TkCreateRegion();
    TkpClipMask * clip_mask = AllocClipMask(gc);
    clip_mask->type = TKP_CLIP_REGION;
    clip_mask->value.region = clipRgn;

    while (n--) {
	XRectangle rect = *rectangles;

	rect.x += clip_x_origin;
	rect.y += clip_y_origin;
	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
	rectangles++;
    }
    return 1;
}

/*
 * Some additional dummy functions (hopefully implemented soon).
 */

#if 0
Cursor
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
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
int
XDrawPoints(
    Display *display,
    Drawable d,
    GC gc,
    XPoint *points,
    int npoints,
    int mode)
{
    int res = Success;
    (void)mode;

    while (npoints-- > 0) {
	res = XDrawLine(display, d, gc,
		points[0].x, points[0].y, points[0].x, points[0].y);
	if (res != Success) break;
	++points;
    }
    return res;
}

#if !defined(MAC_OSX_TK)
int
XDrawSegments(
    Display *display,
    Drawable d,
    GC gc,
    XSegment *segments,
    int nsegments)
{
    (void)display;
    (void)d;
    (void)gc;
    (void)segments;
    (void)nsegments;

    return BadDrawable;
}
#endif

char *
XFetchBuffer(
    Display *display,
    int *nbytes_return,
    int buffer)
{
    (void)display;
    (void)nbytes_return;
    (void)buffer;

    return (char *) 0;
}

Status
XFetchName(
    Display *display,
    Window w,
    char **window_name_return)
{
    (void)display;
    (void)w;
    (void)window_name_return;

    return Success;
}

Atom *
XListProperties(
    Display* display,
    Window w,
    int *num_prop_return)
{
    (void)display;
    (void)w;
    (void)num_prop_return;

    return (Atom *) 0;
}

int
XMapRaised(
    Display *display,
    Window w)
{
    (void)display;
    (void)w;

    return Success;
}

int
XQueryTextExtents(
    Display *display,
    XID font_ID,
    _Xconst char *string,
    int nchars,
    int *direction_return,
    int *font_ascent_return,
    int *font_descent_return,
    XCharStruct *overall_return)
{
    (void)display;
    (void)font_ID;
    (void)string;
    (void)nchars;
    (void)direction_return;
    (void)font_ascent_return;
    (void)font_descent_return;
    (void)overall_return;

    return Success;
}

int
XReparentWindow(
    Display *display,
    Window w,
    Window parent,
    int x,
    int y)
{
    (void)display;
    (void)w;
    (void)parent;
    (void)x;
    (void)y;

    return BadWindow;
}

int
XUndefineCursor(
    Display *display,
    Window w)
{
    (void)display;
    (void)w;

    return Success;
}

XVaNestedList
XVaCreateNestedList(
    int unused, ...)
{
    (void)unused;
    return NULL;
}

char *
XSetICValues(
    XIC xic, ...)
{
    (void)xic;
    return NULL;
}

char *
XGetICValues(
    XIC xic, ...)
{
    (void)xic;
    return NULL;
}

void
XSetICFocus(
    XIC xic)
{
    (void)xic;
}

Window
XCreateWindow(
    Display *display,
	Window parent,
	int x,
	int y,
    unsigned int width,
	unsigned int height,
    unsigned int border_width,
	int depth,
	unsigned int clazz,
    Visual *visual,
	unsigned long value_mask,
    XSetWindowAttributes *attributes)
{
    (void)display;
    (void)parent;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)border_width;
    (void)depth;
    (void)clazz;
    (void)visual;
    (void)value_mask;
    (void)attributes;

	return 0;
}

int
XPointInRegion(
    Region rgn,
	int x,
	int y)
{
    (void)rgn;
    (void)x;
    (void)y;

	return 0;
}

int
XUnionRegion(
    Region srca,
	Region srcb,
	Region dr_return)
{
    (void)srca;
    (void)srcb;
    (void)dr_return;

	return 0;
}

Region
XPolygonRegion(
    XPoint *pts,
	int n,
	int rule)
{
    (void)pts;
    (void)n;
    (void)rule;

    return 0;
}

void
XDestroyIC(
    XIC ic)
{
    (void)ic;
}

Cursor
XCreatePixmapCursor(
    Display *display,
    Pixmap source,
    Pixmap mask,
    XColor *foreground_color,
    XColor *background_color,
    unsigned int x,
    unsigned int y)
{
    (void)display;
    (void)source;
    (void)mask;
    (void)foreground_color;
    (void)background_color;
    (void)x;
    (void)y;

    return (Cursor) NULL;
}

Cursor
XCreateGlyphCursor(
    Display *display,
    Font source_font,
    Font mask_font,
    unsigned int source_char,
    unsigned int mask_char,
    XColor _Xconst *foreground_color,
    XColor _Xconst *background_color)
{
    (void)display;
    (void)source_font;
    (void)mask_font;
    (void)source_char;
    (void)mask_char;
    (void)foreground_color;
    (void)background_color;

    return (Cursor) NULL;
}

XFontSet
XCreateFontSet(
    Display *display		/* display */,
    _Xconst char *base_font_name_list	/* base_font_name_list */,
    char ***missing_charset_list		/* missing_charset_list */,
    int *missing_charset_count		/* missing_charset_count */,
    char **def_string		/* def_string */
) {
    (void)display;
    (void)base_font_name_list;
    (void)missing_charset_list;
    (void)missing_charset_count;
    (void)def_string;

    return (XFontSet)0;
}

void
XFreeFontSet(
    Display *display,		/* display */
    XFontSet fontset		/* font_set */
) {
    (void)display;
    (void)fontset;
}

void
XFreeStringList(
    char **list		/* list */
) {
    (void)list;
}

Status
XCloseIM(
    XIM im /* im */
) {
    (void)im;

    return Success;
}

Bool
XRegisterIMInstantiateCallback(
    Display *dpy			/* dpy */,
    struct _XrmHashBucketRec *rdb	/* rdb */,
    char *res_name			/* res_name */,
    char *res_class			/* res_class */,
    XIDProc callback			/* callback */,
    XPointer client_data			/* client_data */
) {
    (void)dpy;
    (void)rdb;
    (void)res_name;
    (void)res_class;
    (void)callback;
    (void)client_data;

    return False;
}

Bool
XUnregisterIMInstantiateCallback(
    Display *dpy			/* dpy */,
    struct _XrmHashBucketRec *rdb	/* rdb */,
    char *res_name			/* res_name */,
    char *res_class			/* res_class */,
    XIDProc callback			/* callback */,
    XPointer client_data			/* client_data */
) {
    (void)dpy;
    (void)rdb;
    (void)res_name;
    (void)res_class;
    (void)callback;
    (void)client_data;

    return False;
}

char *
XSetLocaleModifiers(
    const char *modifier_list		/* modifier_list */
) {
    (void)modifier_list;

    return NULL;
}

XIM XOpenIM(
    Display *dpy			/* dpy */,
    struct _XrmHashBucketRec *rdb	/* rdb */,
    char *res_name			/* res_name */,
    char *res_class			/* res_class */
) {
    (void)dpy;
    (void)rdb;
    (void)res_name;
    (void)res_class;

    return NULL;
}

char *
XGetIMValues(
    XIM im /* im */, ...
) {
    (void)im;

    return NULL;
}

char *
XSetIMValues(
    XIM im /* im */, ...
) {
    (void)im;

    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|


<













|
|
|
|
|

<
<
<
<
<
<






|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|

<
<
<





|
|
|
|
|
|
|
|

<
<
<
<
<
<
<
<
<





|
|
|
|
|

<
<
<
<
<
<





|
|

<
<
<





|

<





|

<





|

<





|

<




|
|
|
|
|
|
|
|
|
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|
|
|

<
<
<
<





|

<




|
|
|
|
|
|
|

<
<
<
<
<
<
<
<





|
|
|
|
|
|
|

<
<
<
<
<
<
<
<





|
|
|
|
|

<
<
<
<
<
<





|
|

<
<




|

<




|

<
<





|
|
|
|
|
|

<
<
<
<
<
<
<





|
|
|
|
|
|

<
<
<
<
<
<
<





|

<
<




|
|
|
|

<
<
<
<
<





|

<
<





|

<
<










521
522
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549






550
551
552
553
554
555
556
557
558
559




560
561
562
563
564
565
566
567
568




569
570
571
572
573
574
575
576
577




578
579
580
581
582
583
584
585



586
587
588
589
590
591
592
593
594
595
596
597
598
599









600
601
602
603
604
605
606
607
608
609
610






611
612
613
614
615
616
617
618



619
620
621
622
623
624
625

626
627
628
629
630
631
632

633
634
635
636
637
638
639

640
641
642
643
644
645
646

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663













664
665
666
667
668
669
670
671
672




673
674
675
676
677
678
679
680
681




682
683
684
685
686
687
688
689
690




691
692
693
694
695
696
697

698
699
700
701
702
703
704
705
706
707
708
709








710
711
712
713
714
715
716
717
718
719
720
721
722








723
724
725
726
727
728
729
730
731
732
733






734
735
736
737
738
739
740
741


742
743
744
745
746
747

748
749
750
751
752
753


754
755
756
757
758
759
760
761
762
763
764
765







766
767
768
769
770
771
772
773
774
775
776
777







778
779
780
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
int
XDrawPoints(
    Display *display,
    Drawable d,
    GC gc,
    XPoint *points,
    int npoints,
    TCL_UNUSED(int))
{
    int res = Success;


    while (npoints-- > 0) {
	res = XDrawLine(display, d, gc,
		points[0].x, points[0].y, points[0].x, points[0].y);
	if (res != Success) break;
	++points;
    }
    return res;
}

#if !defined(MAC_OSX_TK)
int
XDrawSegments(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Drawable),
    TCL_UNUSED(GC),
    TCL_UNUSED(XSegment *),
    TCL_UNUSED(int))
{






    return BadDrawable;
}
#endif

char *
XFetchBuffer(
    TCL_UNUSED(Display *),
    TCL_UNUSED(int *),
    TCL_UNUSED(int))
{




    return (char *) 0;
}

Status
XFetchName(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(char **))
{




    return Success;
}

Atom *
XListProperties(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int *))
{




    return (Atom *) 0;
}

int
XMapRaised(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window))
{



    return Success;
}

int
XQueryTextExtents(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XID),
    TCL_UNUSED(_Xconst char *),
    TCL_UNUSED(int),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    TCL_UNUSED(XCharStruct *))
{









    return Success;
}

int
XReparentWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Window),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{






    return BadWindow;
}

int
XUndefineCursor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window))
{



    return Success;
}

XVaNestedList
XVaCreateNestedList(
    TCL_UNUSED(int), ...)
{

    return NULL;
}

char *
XSetICValues(
    TCL_UNUSED(XIC), ...)
{

    return NULL;
}

char *
XGetICValues(
    TCL_UNUSED(XIC), ...)
{

    return NULL;
}

void
XSetICFocus(
    TCL_UNUSED(XIC))
{

}

Window
XCreateWindow(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(Visual *),
    TCL_UNUSED(unsigned long),
    TCL_UNUSED(XSetWindowAttributes *))
{













	return 0;
}

int
XPointInRegion(
    TCL_UNUSED(Region),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{




	return 0;
}

int
XUnionRegion(
    TCL_UNUSED(Region),
    TCL_UNUSED(Region),
    TCL_UNUSED(Region))
{




	return 0;
}

Region
XPolygonRegion(
    TCL_UNUSED(XPoint *),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{




    return 0;
}

void
XDestroyIC(
    TCL_UNUSED(XIC))
{

}

Cursor
XCreatePixmapCursor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Pixmap),
    TCL_UNUSED(Pixmap),
    TCL_UNUSED(XColor *),
    TCL_UNUSED(XColor *),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(unsigned int))
{








    return (Cursor) NULL;
}

Cursor
XCreateGlyphCursor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Font),
    TCL_UNUSED(Font),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(XColor _Xconst *),
    TCL_UNUSED(XColor _Xconst *))
{








    return (Cursor) NULL;
}

XFontSet
XCreateFontSet(
    TCL_UNUSED(Display *)		/* display */,
    TCL_UNUSED(_Xconst char *)	/* base_font_name_list */,
    TCL_UNUSED(char ***)		/* missing_charset_list */,
    TCL_UNUSED(int *)		/* missing_charset_count */,
    TCL_UNUSED(char **)		/* def_string */
) {






    return (XFontSet)0;
}

void
XFreeFontSet(
    TCL_UNUSED(Display *),		/* display */
    TCL_UNUSED(XFontSet)		/* font_set */
) {


}

void
XFreeStringList(
    TCL_UNUSED(char **)		/* list */
) {

}

Status
XCloseIM(
    TCL_UNUSED(XIM) /* im */
) {


    return Success;
}

Bool
XRegisterIMInstantiateCallback(
    TCL_UNUSED(Display *)			/* dpy */,
    TCL_UNUSED(struct _XrmHashBucketRec *)	/* rdb */,
    TCL_UNUSED(char *)			/* res_name */,
    TCL_UNUSED(char *)			/* res_class */,
    TCL_UNUSED(XIDProc)			/* callback */,
    TCL_UNUSED(XPointer)			/* client_data */
) {







    return False;
}

Bool
XUnregisterIMInstantiateCallback(
    TCL_UNUSED(Display *) 		/* dpy */,
    TCL_UNUSED(struct _XrmHashBucketRec *)	/* rdb */,
    TCL_UNUSED(char *)			/* res_name */,
    TCL_UNUSED(char *)			/* res_class */,
    TCL_UNUSED(XIDProc)			/* callback */,
    TCL_UNUSED(XPointer)			/* client_data */
) {







    return False;
}

char *
XSetLocaleModifiers(
    TCL_UNUSED(const char *)		/* modifier_list */
) {


    return NULL;
}

XIM XOpenIM(
    TCL_UNUSED(Display *)			/* dpy */,
    TCL_UNUSED(struct _XrmHashBucketRec *)	/* rdb */,
    TCL_UNUSED(char *)			/* res_name */,
    TCL_UNUSED(char *)			/* res_class */
) {





    return NULL;
}

char *
XGetIMValues(
    TCL_UNUSED(XIM) /* im */, ...
) {


    return NULL;
}

char *
XSetIMValues(
    TCL_UNUSED(XIM) /* im */, ...
) {


    return NULL;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to xlib/ximage.c.

47
48
49
50
51
52
53

54
55
56
57
58

59
60
61
62
63
64
65
    pix = Tk_GetPixmap(display, d, (int) width, (int) height, 1);
    gc = XCreateGC(display, pix, 0, NULL);
    if (gc == NULL) {
	return None;
    }
    ximage = XCreateImage(display, NULL, 1, XYBitmap, 0, (char*) data, width,
	    height, 8, (width + 7) / 8);

    ximage->bitmap_bit_order = LSBFirst;
    _XInitImageFuncPtrs(ximage);
    TkPutImage(NULL, 0, display, pix, gc, ximage, 0, 0, 0, 0, width, height);
    ximage->data = NULL;
    XDestroyImage(ximage);

    XFreeGC(display, gc);
    return pix;
}

/*
 * Local Variables:
 * mode: c







>
|
|
|
|
|
>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    pix = Tk_GetPixmap(display, d, (int) width, (int) height, 1);
    gc = XCreateGC(display, pix, 0, NULL);
    if (gc == NULL) {
	return None;
    }
    ximage = XCreateImage(display, NULL, 1, XYBitmap, 0, (char*) data, width,
	    height, 8, (width + 7) / 8);
    if (ximage) {
	ximage->bitmap_bit_order = LSBFirst;
	_XInitImageFuncPtrs(ximage);
	TkPutImage(NULL, 0, display, pix, gc, ximage, 0, 0, 0, 0, width, height);
	ximage->data = NULL;
	XDestroyImage(ximage);
    }
    XFreeGC(display, gc);
    return pix;
}

/*
 * Local Variables:
 * mode: c

Changes to xlib/xutil.c.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 *
 *----------------------------------------------------------------------
 */

Atom
XInternAtom(
    Display *display,
    _Xconst char *atom_name,
    Bool only_if_exists)
{
    static Atom atom = XA_LAST_PREDEFINED;
    (void)atom_name;
    (void)only_if_exists;

    display->request++;
    return ++atom;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetVisualInfo --







|
|


<
<

|







28
29
30
31
32
33
34
35
36
37
38


39
40
41
42
43
44
45
46
47
 *
 *----------------------------------------------------------------------
 */

Atom
XInternAtom(
    Display *display,
    TCL_UNUSED(_Xconst char *),
    TCL_UNUSED(Bool))
{
    static Atom atom = XA_LAST_PREDEFINED;



    LastKnownRequestProcessed(display)++;
    return ++atom;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetVisualInfo --